From 8b83d7c9bbb8608ef9b7483a590c3db20a815d8b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 Nov 2023 10:48:03 +0500 Subject: [PATCH 001/497] Call ref_sound::play_at_pos instead of GEnv.Sound->play_at_pos --- src/xrGame/Actor.cpp | 2 +- src/xrGame/ai/crow/ai_crow.cpp | 2 +- src/xrGame/ai/monsters/burer/burer.cpp | 2 +- src/xrGame/ai/monsters/scanning_ability_inline.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 42eab16738a..389342beb54 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -889,7 +889,7 @@ void CActor::Die(IGameObject* who) if (!GEnv.isDedicatedServer) { - GEnv.Sound->play_at_pos(sndDie[Random.randI(SND_DIE_COUNT)], this, Position()); + sndDie[Random.randI(SND_DIE_COUNT)].play_at_pos(this, Position()); m_HeavyBreathSnd.stop(); m_BloodSnd.stop(); diff --git a/src/xrGame/ai/crow/ai_crow.cpp b/src/xrGame/ai/crow/ai_crow.cpp index 1ffae5e7e9d..ea51ad5f520 100644 --- a/src/xrGame/ai/crow/ai_crow.cpp +++ b/src/xrGame/ai/crow/ai_crow.cpp @@ -381,7 +381,7 @@ void CAI_Crow::shedule_Update(u32 DT) { fIdleSoundTime = fIdleSoundDelta + fIdleSoundDelta * Random.randF(-0.5f, 0.5f); // if (st_current==eFlyIdle) - GEnv.Sound->play_at_pos(m_Sounds.m_idle.GetRandom(), H_Root(), Position()); + m_Sounds.m_idle.GetRandom().play_at_pos(H_Root(), Position()); } fIdleSoundTime -= fDT; } diff --git a/src/xrGame/ai/monsters/burer/burer.cpp b/src/xrGame/ai/monsters/burer/burer.cpp index b206584f349..fca7823baa8 100644 --- a/src/xrGame/ai/monsters/burer/burer.cpp +++ b/src/xrGame/ai/monsters/burer/burer.cpp @@ -395,7 +395,7 @@ void CBurer::UpdateGraviObject() sound_gravi_wave.set_position(snd_pos); } else - GEnv.Sound->play_at_pos(sound_gravi_wave, 0, snd_pos); + sound_gravi_wave.play_at_pos(0, snd_pos); } void CBurer::UpdateCL() diff --git a/src/xrGame/ai/monsters/scanning_ability_inline.h b/src/xrGame/ai/monsters/scanning_ability_inline.h index 9b47f4b1c5b..059290ced6a 100644 --- a/src/xrGame/ai/monsters/scanning_ability_inline.h +++ b/src/xrGame/ai/monsters/scanning_ability_inline.h @@ -111,7 +111,7 @@ void CScanningAbilityAbstract::schedule_update() if (object->can_scan) { // играть звук - GEnv.Sound->play_at_pos(sound_scan, 0, scan_obj->Position()); + sound_scan.play_at_pos(0, scan_obj->Position()); // постпроцесс // TODO: make this postprocess with static check (only one for all scanners) From 0be18cc6c8a4c6d7d8def0abc8c6b00e9781cdc2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 Nov 2023 13:13:20 +0500 Subject: [PATCH 002/497] xrRender_RGL: removed FBO extension check This was made to fix #1528, but it doesn't work as intended and prevent normal usage of OpenGL for some users. --- src/Layers/xrRenderPC_GL/r2_test_hw.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp index d0d6a6d54c0..cf8e9b4b46b 100644 --- a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp +++ b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp @@ -52,8 +52,5 @@ BOOL xrRender_test_hw() return FALSE; } - if (!GLEW_ARB_framebuffer_object) - return FALSE; - return TRUE; } From 64778f161c02a95e3210153b22e069306922ee23 Mon Sep 17 00:00:00 2001 From: Mikhail Bogdanov Date: Sat, 2 Dec 2023 00:57:47 +0300 Subject: [PATCH 003/497] CMake refactoring (#1535) --- CMakeLists.txt | 292 +- Externals/CMakeLists.txt | 16 +- Externals/GameSpy | 2 +- Externals/LuaJIT-proj/CMakeLists.txt | 630 +- .../HostBuildTools/buildvm/CMakeLists.txt | 17 +- .../HostBuildTools/minilua/CMakeLists.txt | 6 +- Externals/LuaJIT-proj/luajit.cmake | 645 -- Externals/NVTT/CMakeLists.txt | 4 - Externals/NVTT/src/nvcore/CMakeLists.txt | 91 +- .../NVTT/src/nvcore/poshlib/CMakeLists.txt | 10 +- Externals/NVTT/src/nvimage/CMakeLists.txt | 105 +- Externals/NVTT/src/nvmath/CMakeLists.txt | 72 +- Externals/NVTT/src/nvtt/CMakeLists.txt | 192 +- Externals/NVTT/src/nvtt/squish/CMakeLists.txt | 47 +- .../NVTT/src/nvtt/squish/colourblock.cpp | 2 +- Externals/NVTT/src/nvtt/tools/configdialog.h | 2 +- Externals/NVTT/src/nvtt/tools/main.cpp | 2 +- Externals/OPCODE/CMakeLists.txt | 171 +- Externals/cximage/CMakeLists.txt | 78 +- Externals/imgui-proj/CMakeLists.txt | 40 +- Externals/imgui-proj/imgui.cmake | 41 - Externals/luabind | 2 +- Externals/ode/CMakeLists.txt | 199 +- Externals/xrLuaFix | 2 +- Externals/zlib | 2 +- cmake/FindLZO.cmake | 32 +- cmake/utils.cmake | 115 +- misc/CMakeLists.txt | 32 +- src/CMakeLists.txt | 2 - src/Common/Common.hpp | 2 + src/Layers/CMakeLists.txt | 12 +- src/Layers/xrAPI/CMakeLists.txt | 33 +- src/Layers/xrRenderPC_GL/CMakeLists.txt | 810 ++- src/Layers/xrRenderPC_R1/CMakeLists.txt | 77 +- src/Layers/xrRenderPC_R2/CMakeLists.txt | 56 + src/Layers/xrRenderPC_R4/CMakeLists.txt | 57 + src/utils/CMakeLists.txt | 7 +- src/utils/xrLCUtil/CMakeLists.txt | 50 +- src/utils/xrLC_Light/CMakeLists.txt | 379 +- src/utils/xrMiscMath/CMakeLists.txt | 34 +- src/utils/xrQSlim/CMakeLists.txt | 112 +- src/xrAICore/CMakeLists.txt | 576 +- src/xrCDB/CMakeLists.txt | 94 +- src/xrCore/CMakeLists.txt | 908 +-- src/xrEngine/CMakeLists.txt | 824 +-- src/xrGame/CMakeLists.txt | 5272 ++++++++--------- src/xrGameSpy/CMakeLists.txt | 120 +- src/xrNetServer/CMakeLists.txt | 81 +- src/xrParticles/CMakeLists.txt | 41 +- src/xrPhysics/CMakeLists.txt | 772 +-- src/xrScriptEngine/CMakeLists.txt | 240 +- src/xrScriptEngine/xrScriptEngine.hpp | 1 - src/xrSound/CMakeLists.txt | 255 +- src/xrUICore/CMakeLists.txt | 301 +- src/xr_3da/CMakeLists.txt | 39 +- 55 files changed, 7080 insertions(+), 6924 deletions(-) delete mode 100644 Externals/LuaJIT-proj/luajit.cmake create mode 100644 src/Layers/xrRenderPC_R2/CMakeLists.txt create mode 100644 src/Layers/xrRenderPC_R4/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 08e4f3ef94c..b24593b8b1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,16 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.22) + +message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") project(OpenXRay) set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +option(CMAKE_VERBOSE_MAKEFILE "Verbose build output" OFF) +message(STATUS "CMAKE_VERBOSE_MAKEFILE: ${CMAKE_VERBOSE_MAKEFILE}") if (CMAKE_VERBOSE_MAKEFILE) - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT) endif() @@ -18,22 +23,24 @@ if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/usr") endif() -# Installation paths include(GNUInstallDirs) -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -include(${PROJECT_SOURCE_DIR}/cmake/utils.cmake) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include(utils) + +set_git_info() # Output all libraries and executable to one folder -set(COMPILE_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/bin/${ARCH_TYPE}/${CMAKE_BUILD_TYPE}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${COMPILE_OUTPUT_FOLDER}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${COMPILE_OUTPUT_FOLDER}) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${COMPILE_OUTPUT_FOLDER}) -set(CMAKE_PDB_OUTPUT_DIRECTORY ${COMPILE_OUTPUT_FOLDER}) -set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${COMPILE_OUTPUT_FOLDER}) +set(COMPILE_OUTPUT_FOLDER "${CMAKE_SOURCE_DIR}/bin/${ARCH_TYPE}/${CMAKE_BUILD_TYPE}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") +set(CMAKE_PDB_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") +set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") if (DISABLE_PORTABLE_MODE) - add_definitions(-DDISABLE_PORTABLE_MODE) + add_compile_definitions(DISABLE_PORTABLE_MODE) endif() if (NOT DEFINED ALLOW_RPATH) @@ -42,18 +49,18 @@ endif() if (ALLOW_RPATH) # Set the shared object search path for the installation - set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") # Set the shared object search path for the build tree # On Linux/BSD we can use $ORIGIN to search for modules next to the executable if (NOT APPLE) set(CMAKE_BUILD_RPATH $ORIGIN) else() - set(CMAKE_BUILD_RPATH ${COMPILE_OUTPUT_FOLDER}) + set(CMAKE_BUILD_RPATH "${COMPILE_OUTPUT_FOLDER}") endif() endif() -message(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) +message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") set(PROJECT_PLATFORM_ARM64 TRUE) elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "armv*") @@ -64,77 +71,35 @@ elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL set(PROJECT_PLATFORM_PPC TRUE) endif() - if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") set(MASTER_GOLD_DEFAULT_VALUE ON) else() set(MASTER_GOLD_DEFAULT_VALUE OFF) endif() +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") option(MASTER_GOLD "Build with MASTER_GOLD" ${MASTER_GOLD_DEFAULT_VALUE}) -message(STATUS "MASTER_GOLD: ${MASTER_GOLD}") if (MASTER_GOLD) - add_definitions(-DMASTER_GOLD) + add_compile_definitions(MASTER_GOLD) endif() +message(STATUS "MASTER_GOLD: ${MASTER_GOLD}") option(STATIC_BUILD "Use static build" ${MASTER_GOLD}) -message(STATUS "STATIC_BUILD: ${STATIC_BUILD}") if (STATIC_BUILD) # XXX: Uncomment only after build with XRAY_STATIC_BUILD is fixed - #add_definitions(-DXRAY_STATIC_BUILD) + #add_compile_definitions(XRAY_STATIC_BUILD) endif() +message(STATUS "STATIC_BUILD: ${STATIC_BUILD}") -function(xr_install tgt) - if (NOT MSVC) - install(TARGETS ${tgt} DESTINATION "." - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 - ) - else() - install(TARGETS ${tgt} - CONFIGURATIONS Debug - RUNTIME DESTINATION Debug/ - LIBRARY DESTINATION Debug/ - ) - install(FILES $ - CONFIGURATIONS Debug - DESTINATION Debug/ - ) - install(TARGETS ${tgt} - CONFIGURATIONS Release - RUNTIME DESTINATION Release/ - LIBRARY DESTINATION Release/ - ) - endif() -endfunction() - -# Use only if install defined outside target directory(like luabind, for example) -function(xr_install_file tgt) - if (NOT MSVC) - install(FILES $ DESTINATION "." - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 - ) - else() - install($ - CONFIGURATIONS Debug - RUNTIME DESTINATION Debug/ - ) - install(FILES $ - CONFIGURATIONS Debug - DESTINATION Debug/ - ) - install($ - CONFIGURATIONS Release - RUNTIME DESTINATION Release/ - ) - endif() -endfunction() +option(CMAKE_UNITY_BUILD "Use unity build" OFF) +message(STATUS "CMAKE_UNITY_BUILD: ${CMAKE_UNITY_BUILD}") find_program(CCACHE_FOUND ccache) if (CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) set(ENV{CCACHE_SLOPPINESS} pch_defines,time_macros) -endif (CCACHE_FOUND) +endif () if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0 AND NOT PROJECT_PLATFORM_E2K) @@ -144,7 +109,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") endif() elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # XXX: Remove -fdelayed-template-parsing - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdelayed-template-parsing -Wno-unused-command-line-argument -Wno-inconsistent-missing-override") + add_compile_options( + -fdelayed-template-parsing + -Wno-unused-command-line-argument + -Wno-inconsistent-missing-override + ) endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT XRAY_USE_DEFAULT_CXX_LIB) @@ -163,44 +132,41 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT XRAY_USE_DEFAULT_CXX_LIB) endif() if (XRAY_CXX_LIB STREQUAL "libstdc++") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++") + add_compile_options(-stdlib=libstdc++) elseif (XRAY_CXX_LIB STREQUAL "libc++") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + add_compile_options(-stdlib=libc++) if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lcxxrt") + add_compile_options(-lcxxrt) else() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi") + add_compile_options(-lc++abi) endif() endif() endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") +add_compile_options(-Wno-attributes) if (APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-undefined,error") + add_compile_options(-Wl,-undefined,error) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined") + add_compile_options(-Wl,--no-undefined) endif() +# TODO test option(USE_ADDRESS_SANITIZER "Use AddressSanitizer" OFF) + if (USE_ADDRESS_SANITIZER) - set(SANITIZE_FLAGS - "-fsanitize=address" - "-fsanitize=leak" - "-fno-omit-frame-pointer" - "-fno-optimize-sibling-calls" - "-fsanitize=undefined" - "-fno-sanitize=vptr" + add_compile_options( + -fsanitize=address + -fsanitize=leak + -fsanitize=undefined + -fno-omit-frame-pointer + -fno-optimize-sibling-calls + -fno-sanitize=vptr ) - if (CMAKE_BUILD_TYPE STREQUAL "Debug") - list(APPEND SANITIZE_FLAGS "-g") - endif() - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_link_options("-shared-libasan") - endif() + add_link_options( + $<$:-shared-libasan> + ) endif() -string(REPLACE ";" " " SANITIZE_FLAGS "${SANITIZE_FLAGS}") message(STATUS "USE_ADDRESS_SANITIZER: ${USE_ADDRESS_SANITIZER}") @@ -212,7 +178,7 @@ if (USE_LTO) if (LTO_SUPPORTED) # With clang cmake only enables '-flto=thin' but we want full LTO if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(LTO_FLAGS "-flto=full") + add_compile_options(-flto=full) else() set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) endif() @@ -221,35 +187,31 @@ endif() message(STATUS "USE_LTO: ${USE_LTO}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS} ${LTO_FLAGS}") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_FLAGS} ${LTO_FLAGS}") -set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${SANITIZE_FLAGS} ${LTO_FLAGS}") - -set(LUA_LIBRARIES xrLuajit) - if (PROJECT_PLATFORM_ARM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon") + add_compile_options(-mfpu=neon) elseif (PROJECT_PLATFORM_ARM64) - set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) + #add_compile_options() elseif (PROJECT_PLATFORM_E2K) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") + add_compile_options(-Wno-unknown-pragmas) elseif (PROJECT_PLATFORM_PPC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_WARN_X86_INTRINSICS") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec -DNO_WARN_X86_INTRINSICS") + add_compile_options( + -maltivec + -mabi=altivec + ) + add_compile_definitions(NO_WARN_X86_INTRINSICS) else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse -msse3") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse3") + add_compile_options( + -mfpmath=sse + -msse3 + ) endif() option(XRAY_USE_DEFAULT_LINKER "Don't select linker, use system default." OFF) -if (NOT XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER AND NOT APPLE) # XXX: check if we can remove check for Apple +if (NOT XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER AND NOT APPLE) # XXX: check if we can remove this check for Apple include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-fuse-ld=gold" GOLD_LINKER_AVAILABLE) - CHECK_CXX_COMPILER_FLAG("-fuse-ld=lld" LLD_LINKER_AVAILABLE) + check_cxx_compiler_flag("-fuse-ld=gold" GOLD_LINKER_AVAILABLE) + check_cxx_compiler_flag("-fuse-ld=lld" LLD_LINKER_AVAILABLE) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND LLD_LINKER_AVAILABLE) set(XRAY_LINKER "lld" CACHE STRING "" FORCE) @@ -259,30 +221,21 @@ if (NOT XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER AND NOT APPLE) # XXX: check endif() if (XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=${XRAY_LINKER}") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=${XRAY_LINKER}") + add_link_options(-fuse-ld=${XRAY_LINKER}) endif() if (CMAKE_BUILD_TYPE STREQUAL "Debug") - add_definitions(-DDEBUG -DMIXED) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Og") - set(LUA_LIBRARIES xrLuajit-debug) -endif() - -set(LUA_FOUND true) - -message("CMake build ${CMAKE_BUILD_TYPE}, CFLAGS=${CMAKE_C_FLAGS}, CXXFLAGS=${CMAKE_CXX_FLAGS}") - -add_definitions(-D_MT -D_CPPUNWIND -DPURE_DYNAMIC_CAST -DDECLARE_SPECIALIZATION -DM_NOSTDCONTAINERS_EXT) -add_definitions(-DLUABIND_DYNAMIC_LINK) #self-explanatory -add_definitions(-DdSINGLE) # for ODE and xrPhysics -if (MASTER_GOLD) - add_definitions(-DLUABIND_NO_EXCEPTIONS) - add_definitions(-DLUABIND_NO_ERROR_CHECKING) - add_definitions(-DdNODEBUG) + add_compile_definitions( + DEBUG + MIXED + ) + add_compile_options(-Og) endif() -set(LUA_INCLUDE_DIR Externals/LuaJIT/src) +add_compile_definitions( + _MT + _CPPUNWIND +) if (NOT WIN32) find_package(SDL2 REQUIRED) @@ -308,75 +261,38 @@ else() endif() set_property(CACHE MEMORY_ALLOCATOR PROPERTY STRINGS "mimalloc" "standard") -if (MEMORY_ALLOCATOR STREQUAL "mimalloc") - add_definitions(-DUSE_MIMALLOC) - if (NOT mimalloc_FOUND) - message(FATAL_ERROR "mimalloc allocator requested but not found. Please, install mimalloc package or select standard allocator.") - endif() -else() - add_definitions(-DUSE_PURE_ALLOC) +if (MEMORY_ALLOCATOR STREQUAL "mimalloc" AND NOT mimalloc_FOUND) + message(FATAL_ERROR "mimalloc allocator requested but not found. Please, install mimalloc package or select standard allocator.") endif() message("Using ${MEMORY_ALLOCATOR} memory allocator") -# XXX: move to LuaJIT -include_directories(${LUA_INCLUDE_DIR}) - -execute_process(COMMAND git rev-parse --verify HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_VARIABLE GIT_SHA1 - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -message("git commit: " ${GIT_SHA1}) - -execute_process(COMMAND git rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_VARIABLE GIT_BRANCH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -message("git branch: " ${GIT_BRANCH}) - -include_directories( - ${CMAKE_SOURCE_DIR}/Externals - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/Externals/imgui -) +option(XRAY_USE_LUAJIT "Use LuaJIT" ON) add_subdirectory(Externals) -set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS}" - "-Wall" - #"-Werror" - "-Wextra" - #"-pedantic" - "-Wno-unknown-pragmas" - "-Wno-strict-aliasing" - "-Wno-parentheses" - "-Wno-unused-label" - "-Wno-unused-parameter" - "-Wno-switch" - #"-Wno-padded" - #"-Wno-c++98-compat" - #"-Wno-c++98-compat-pedantic" - #"-Wno-c++11-compat" - #"-Wno-c++11-compat-pedantic" - #"-Wno-c++14-compat" - #"-Wno-c++14-compat-pedantic" - #"-Wno-newline-eof" +add_compile_options( + -Wall + #-Werror + -Wextra + #-pedantic + -Wno-unknown-pragmas + -Wno-strict-aliasing + -Wno-parentheses + -Wno-unused-label + -Wno-unused-parameter + -Wno-switch + #-Wno-padded + #-Wno-c++98-compat + #-Wno-c++98-compat-pedantic + #-Wno-c++11-compat + #-Wno-c++11-compat-pedantic + #-Wno-c++14-compat + #-Wno-c++14-compat-pedantic + #-Wno-newline-eof + $<$:$<$:-Wno-class-memaccess>> + $<$:$<$:-Wno-interference-size>> ) -if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS}" - "-Wno-class-memaccess" - "-Wno-interference-size" - ) -endif() -string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") add_subdirectory(src) add_subdirectory(res) diff --git a/Externals/CMakeLists.txt b/Externals/CMakeLists.txt index d9772bd2753..6ee73375534 100644 --- a/Externals/CMakeLists.txt +++ b/Externals/CMakeLists.txt @@ -1,11 +1,25 @@ -add_subdirectory(LuaJIT-proj) +if (XRAY_USE_LUAJIT) + add_subdirectory(LuaJIT-proj) +else() + find_package(Lua51 REQUIRED) +endif() + add_subdirectory(xrLuaFix) add_subdirectory(luabind) + if (USE_CXIMAGE) add_subdirectory(cximage) endif() + add_subdirectory(GameSpy) add_subdirectory(OPCODE) add_subdirectory(ode) #add_subdirectory(NVTT) add_subdirectory(imgui-proj) + +if (NOT TARGET xrLuabind) + message(FATAL_ERROR + "You probably have downloaded OpenXRay sources as ZIP archive, you can't do that. Use git to clone the repository.\n" + "Read the build instructions: https://github.com/OpenXRay/xray-16/wiki" + ) +endif() diff --git a/Externals/GameSpy b/Externals/GameSpy index 1c9eb9af6be..c355b6e9b88 160000 --- a/Externals/GameSpy +++ b/Externals/GameSpy @@ -1 +1 @@ -Subproject commit 1c9eb9af6be4602bceb7b1913c7405f6bb76bea1 +Subproject commit c355b6e9b88b1d00912db902872c8bc7977f994e diff --git a/Externals/LuaJIT-proj/CMakeLists.txt b/Externals/LuaJIT-proj/CMakeLists.txt index 6143cc05e0d..36abe653fd1 100644 --- a/Externals/LuaJIT-proj/CMakeLists.txt +++ b/Externals/LuaJIT-proj/CMakeLists.txt @@ -1 +1,629 @@ -include(luajit.cmake) +# Copyright (C) 2007-2013 LuaDist. +# Created by Peter Drahoš +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Please note that the package source code is licensed under its own license. + +cmake_minimum_required(VERSION 3.13) + +project(xrLuaJIT C CXX ASM) + +# Version +set(MAJVER 2) +set(MINVER 0) +set(RELVER 5) +set(ABIVER 5.1) +set(NODOTABIVER 51) + +set(CMAKE_OSX_SYSROOT "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") +set(LUAJIT_DIR ${CMAKE_SOURCE_DIR}/Externals/LuaJIT/src CACHE PATH "Location of luajit sources") + +option(LUAJIT_BUILD_STATIC_LIB "Build as static library" OFF) +option(LUAJIT_BUILD_APP "Build application" OFF) + +# NOTE: Not working because there is no lib_package_rel.c file +option(LUA_USE_RELATIVE_LOADLIB "Use modified loadlib.c with support for relative paths on posix systems (Not working)" OFF) + +# Extra flags +option(LUAJIT_DISABLE_FFI "Disable the FFI extension to reduce the size of the LuaJIT executable. But please consider that the FFI library is compiled-in, but NOT loaded by default. It only allocates any memory, if you actually make use of it" OFF) +option(LUAJIT_ENABLE_LUA52COMPAT "Features from Lua 5.2 that are unlikely to break existing code are enabled by default. Some other features that *might* break some existing code (e.g. __pairs or os.execute() return values) can be enabled here. Note: this does not provide full compatibility with Lua 5.2 at this time" OFF) +option(LUAJIT_DISABLE_JIT "Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter" OFF) +option(LUAJIT_DISABLE_GC64 "Disable LJ_GC64 mode for x64" OFF) +option(LUAJIT_USE_SYSMALLOC "Use the system provided memory allocator (realloc) instead of the bundled memory allocator. This is slower, but sometimes helpful for debugging. It's helpful for Valgrind's memcheck tool, too. This option cannot be enabled on x64, since the built-in allocator is mandatory" OFF) +option(LUAJIT_USE_VALGRIND "This option is required to run LuaJIT under Valgrind. The Valgrind header files must be installed. You should enable debug information, too." OFF) +option(LUAJIT_USE_GDBJIT "This is the client for the GDB JIT API. GDB 7.0 or higher is required to make use of it. See lj_gdbjit.c for details. Enabling this causes a non-negligible overhead, even when not running under GDB" OFF) + +option(LUA_USE_APICHECK "Turn on assertions for the Lua/C API to debug problems with lua_* calls. This is rather slow, use only while developing C libraries/embeddings" OFF) +option(LUA_USE_ASSERT "Turn on assertions for the whole LuaJIT VM. This significantly slows down everything. Use only if you suspect a problem with LuaJIT itself" OFF) + +#option(LUAJIT_DEBUG "Generate debug information" OFF) + +if (WIN32) + option(LUA_BUILD_WLUA "Build wluajit interpreter for no-console applications." ON) +elseif (APPLE) + option(LUA_USE_POSIX "Use POSIX functionality." ON) + option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) +else() + option(LUA_USE_POSIX "Use POSIX functionality." ON) + option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) +endif() + +# TODO: check if we need luaconf.h +# TODO: add other variables from luaconf.h if we need them +# Configuration for luaconf.h +set(LUA_PATH "LUA_PATH" CACHE STRING "Environment variable to use as package.path") +set(LUA_CPATH "LUA_CPATH" CACHE STRING "Environment variable to use as package.cpath") +set(LUA_INIT "LUA_INIT" CACHE STRING "Environment variable for initial script") + +if (APPLE) + set(ENV{SDKROOT} ${CMAKE_OSX_SYSROOT}) +endif() + +# Clean unnecessary files in LuaJIT source directory +execute_process( + COMMAND make clean + WORKING_DIRECTORY ${LUAJIT_DIR} +) + +# TODO: check windows supports same target name for static and shared lib +if (LUAJIT_BUILD_STATIC_LIB) + add_library(xrLuaJIT STATIC) +else() + add_library(xrLuaJIT SHARED) +endif() + +# Compiler options +if (PROJECT_PLATFORM_E2K) # E2K: O3 on mcst-lcc approximately equal to O2 at gcc X86/ARM + set(CCOPT_OPT_LEVEL "-O3") +else() + set(CCOPT_OPT_LEVEL "-O2") +endif() + +set(CCOPT "${CMAKE_C_FLAGS} ${CCOPT_OPT_LEVEL}") + +if (USE_ADDRESS_SANITIZER) + set(CCOPT "${CCOPT} -fno-stack-protector") +else() + set(CCOPT "${CCOPT} -fomit-frame-pointer -fno-stack-protector") +endif() + +set(CCOPT "${CCOPT} -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE") + +string(REPLACE " " ";" CCOPT "${CCOPT}") + +add_compile_options( + #-Wdeclaration-after-statement + #-Wredundant-decls + #-Wshadow + #-Wpointer-arith +) + +if (LUAJIT_DISABLE_FFI) + list(APPEND XCFLAGS "-DLUAJIT_DISABLE_FFI") +endif() + +if (LUAJIT_ENABLE_LUA52COMPAT) + list(APPEND XCFLAGS "-DLUAJIT_ENABLE_LUA52COMPAT") +endif() + +if (LUAJIT_DISABLE_JIT) + list(APPEND XCFLAGS "-DLUAJIT_DISABLE_JIT") +endif() + +if (LUAJIT_DISABLE_GC64) + list(APPEND XCFLAGS "-DLUAJIT_DISABLE_GC64") +endif() + +if (LUAJIT_USE_SYSMALLOC) + list(APPEND XCFLAGS "-DLUAJIT_USE_SYSMALLOC") +endif() + +if (LUAJIT_USE_VALGRIND) + list(APPEND XCFLAGS "-DLUAJIT_USE_VALGRIND") +endif() + +if (LUAJIT_USE_GDBJIT) + list(APPEND XCFLAGS "-DLUAJIT_USE_GDBJIT") +endif() + +if (LUA_USE_APICHECK) + list(APPEND XCFLAGS "-DLUA_USE_APICHECK") +endif() + +if (LUA_USE_ASSERT) + list(APPEND XCFLAGS "-DLUA_USE_ASSERT") +endif() + +set(CCOPTIONS "${CCOPT};${XCFLAGS}") + +target_compile_options(xrLuaJIT PRIVATE ${CCOPTIONS}) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} ${CCOPTIONS} -E lj_arch.h -dM + WORKING_DIRECTORY "${LUAJIT_DIR}" + OUTPUT_VARIABLE TESTARCH_OUTPUT + ERROR_VARIABLE TESTARCH_ERROR +) + +if(NOT "${TESTARCH_ERROR}" STREQUAL "") + message("TESTARCH_ERROR=${TESTARCH_ERROR}") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_X64") + set(TARGET_LJARCH "x64") +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_X86") + set(TARGET_LJARCH "x86") + + string(APPEND TARGET_XCFLAGS " -march=i686 -msse -msse2 -mfpmath=sse") +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_ARM64") + set(TARGET_LJARCH "arm64") + if ("${TESTARCH_OUTPUT}" MATCHES "__AARCH64EB__") + set(TARGET_ARCH "-D__AARCH64EB__=1") + endif() +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_ARM") + set(TARGET_LJARCH "arm") +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_PPC") + set(TARGET_LJARCH "ppc") +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_MIPS") + if ("${TESTARCH_OUTPUT}" MATCHES "MIPSEL") + set(TARGET_ARCH "-D__MIPSEL__=1") + endif() + if ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_MIPS64") + set(TARGET_LJARCH "mips64") + else() + set(TARGET_LJARCH "mips") + endif() +elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "e2k") # MCST Elbrus 2000 + set(TARGET_LJARCH "e2k") +else() + message("${TESTARCH_OUTPUT}") + message(FATAL_ERROR "Unsupported luajit target architecture (see output above)") +endif() + +string(APPEND TARGET_ARCH "-DLUAJIT_TARGET=LUAJIT_ARCH_${TARGET_LJARCH}") + +# TODO: add PREFIX, TARGET_XCFLAGS, TARGET_DYNXLDOPTS, MULTILIB here (lines 289-302 in Makefile) +# TODO: use TARGET_STRIP flags? + +if (WIN32) + #string(APPEND TARGET_STRIP "--strip-unneeded") + + target_link_options(xrLuaJIT + PRIVATE + " -shared -Wl,--out-implib,libluajit-${ABIVER}.dll.a" + ) + + if (NOT LUAJIT_BUILD_STATIC_LIB) + string(APPEND HOST_XCFLAGS " -DLUA_BUILD_AS_DLL") + endif() + + set(LJVM_MODE peobj) +elseif (APPLE) + if (CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "") + message(FATAL_ERROR "Missing export MACOSX_DEPLOYMENT_TARGET=XX.YY") + endif() + + #string(APPEND TARGET_STRIP "-x") + # XXX: doesn't compile with Apple Clang + #string(APPEND TARGET_XSHLDFLAGS " -dynamiclib -single_module -undefined dynamic_lookup -fPIC") + #string(APPEND TARGET_XSHLDFLAGS " -install_name ${TARGET_DYLIBPATH} -compatibility_version ${MAJVER}.${MINVER} -current_version ${MAJVER}.${MINVER}.${RELVER}") + + if (${TARGET_LJARCH} STREQUAL "x64") + string(APPEND TARGET_XLDFLAGS " -pagezero_size 10000 -image_base 100000000 -image_base 7fff04c4a000") + elseif (${TARGET_LJARCH} STREQUAL "arm64") + string(APPEND TARGET_XCFLAGS " -fno-omit-frame-pointer") + endif() + + set(LJVM_MODE machasm) +else() + set(LJVM_MODE elfasm) +endif() + +# TODO: add HOST_SYS != TARGET_SYS code (lines 354-372 in Makefile) +#string(APPEND HOST_XCFLAGS "-DLUA_BUILD_AS_DLL -DLUAJIT_OS=LUAJIT_OS_WINDOWS") +# TODO: add "-DTARGET_OS_IPHONE=1" on iOS +#string(APPEND HOST_XCFLAGS "-DLUAJIT_OS=LUAJIT_OS_OSX") + +# NOTE: Defines in DASM_FLAGS should contain a space after -D for minilua to work + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_LE 1") + list(APPEND DASM_FLAGS "-D ENDIAN_LE") +else() + list(APPEND DASM_FLAGS "-D ENDIAN_BE") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_BITS 64") + list(APPEND DASM_FLAGS "-D P64") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_HASJIT 1") + list(APPEND DASM_FLAGS "-D JIT") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_HASFFI 1") + list(APPEND DASM_FLAGS "-D FFI") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_DUALNUM 1") + list(APPEND DASM_FLAGS "-D DUALNUM") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_HASFPU 1") + list(APPEND DASM_FLAGS "-D FPU") + list(APPEND TARGET_ARCH "-DLJ_ARCH_HASFPU=1") +else() + list(APPEND TARGET_ARCH "-DLJ_ARCH_HASFPU=0") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ABI_SOFTFP 1") + list(APPEND TARGET_ARCH "-DLJ_ABI_SOFTFP=1") +else() + list(APPEND DASM_FLAGS "-D HFABI") + list(APPEND TARGET_ARCH "-DLJ_ABI_SOFTFP=0") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_NO_UNWIND 1") + list(APPEND DASM_FLAGS "-D NO_UNWIND") + list(APPEND TARGET_ARCH "-DLUAJIT_NO_UNWIND") +endif() + +if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_VERSION") + list(REGEX MATCH "LJ_ARCH_VERSION ([0-9]+)$" _ "${TESTARCH_OUTPUT}") + list(APPEND DASM_FLAGS "-D VER=${CMAKE_MATCH_1}") +else() + list(APPEND DASM_FLAGS "-D VER=") +endif() + +set(DASM_ARCH ${TARGET_LJARCH}) + +if (WIN32) + list(APPEND DASM_FLAGS "-D WIN") +endif() + +if (TARGET_LJARCH STREQUAL "x64") + if (NOT "${TESTARCH_OUTPUT}" MATCHES "LJ_FR2 1") + set(DASM_ARCH "x86") + endif() +elseif (TARGET_LJARCH STREQUAL "arm") + if (APPLE) + list(APPEND DASM_FLAGS "-D IOS") + endif() +elseif ("${TESTARCH_OUTPUT}" MATCHES "LJ_TARGET_MIPSR6") + list(APPEND DASM_FLAGS "-D MIPSR6") +endif() + +if (TARGET_LJARCH STREQUAL "ppc") + if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_SQRT 1") + list(APPEND DASM_FLAGS "-D SQRT") + endif() + if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_ROUND 1") + list(APPEND DASM_FLAGS "-D ROUND") + endif() + if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_PPC32ON64 1") + list(APPEND DASM_FLAGS "-D GPR64") + endif() + if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_PPC64") + set(DASM_ARCH "ppc64") + endif() +endif() + +set(HOST_ACFLAGS "${CMAKE_C_FLAGS} ${CCOPTIONS} ${TARGET_ARCH}") +set(HOST_ALDFLAGS "${CMAKE_C_FLAGS}") + +string(APPEND TARGET_XCFLAGS " -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE") + +separate_arguments(HOST_ACFLAGS) +separate_arguments(HOST_ALDFLAGS) +separate_arguments(DASM_FLAGS) +separate_arguments(TARGET_XCFLAGS) + +target_compile_options(xrLuaJIT + PRIVATE + ${TARGET_XCFLAGS} +) + +set(DASM_DASC "${LUAJIT_DIR}/vm_${DASM_ARCH}.dasc") +set(DASM "${LUAJIT_DIR}/../dynasm/dynasm.lua") + +if (PROJECT_PLATFORM_E2K) + set(BUILDVM_ARCH "${LUAJIT_DIR}/host/buildvm_arch.h") +else() + set(BUILDVM_ARCH "${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h") +endif() + +# Generate buildvm arch header +if (NOT PROJECT_PLATFORM_E2K) + set(MINILUA_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/minilua") + set(MINILUA_FILE "${MINILUA_BINARY_DIR}/minilua") + + add_custom_command( + OUTPUT "${MINILUA_FILE}" + COMMAND ${CMAKE_COMMAND} + -B${MINILUA_BINARY_DIR} + -G${CMAKE_GENERATOR} + -S${CMAKE_CURRENT_SOURCE_DIR}/HostBuildTools/minilua + -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} + -DCMAKE_BUILD_TYPE=Release + -DLUAJIT_DIR=${LUAJIT_DIR} + -DLUA_USE_POSIX=${LUA_USE_POSIX} + -DHOST_ACFLAGS="${HOST_ACFLAGS}" + -DHOST_ALDFLAGS="${HOST_ALDFLAGS}" + COMMAND ${CMAKE_COMMAND} --build ${MINILUA_BINARY_DIR} --config Release --verbose + ) + + add_custom_command(OUTPUT ${BUILDVM_ARCH} + COMMAND "${MINILUA_FILE}" ${DASM} ${DASM_FLAGS} -o ${BUILDVM_ARCH} ${DASM_DASC} + DEPENDS "${MINILUA_FILE}" + ) + + add_custom_target(buildvm_arch + DEPENDS ${BUILDVM_ARCH} + ) + + set_target_properties(buildvm_arch PROPERTIES + ADDITIONAL_CLEAN_FILES "${MINILUA_BINARY_DIR}" + ) +endif() + +# Buildvm +set(BUILDVM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/buildvm") +set(BUILDVM_FILE "${BUILDVM_BINARY_DIR}/buildvm") + +add_custom_command( + OUTPUT "${BUILDVM_FILE}" + COMMAND ${CMAKE_COMMAND} + -B${BUILDVM_BINARY_DIR} + -G${CMAKE_GENERATOR} + -S${CMAKE_CURRENT_SOURCE_DIR}/HostBuildTools/buildvm + -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} + -DCMAKE_BUILD_TYPE=Release + -DLUAJIT_DIR=${LUAJIT_DIR} + -DBUILDVM_ARCH=${BUILDVM_ARCH} + -DHOST_ACFLAGS="${HOST_ACFLAGS}" + -DHOST_ALDFLAGS="${HOST_ALDFLAGS}" + COMMAND ${CMAKE_COMMAND} --build ${BUILDVM_BINARY_DIR} --config Release --verbose +) + +add_custom_target(buildvm + DEPENDS "${BUILDVM_FILE}" +) + +set_target_properties(buildvm PROPERTIES + ADDITIONAL_CLEAN_FILES "${BUILDVM_BINARY_DIR}" +) + +if (NOT PROJECT_PLATFORM_E2K) + add_dependencies(buildvm buildvm_arch) +endif() + +list(APPEND LJLIB_C + "${LUAJIT_DIR}/lib_base.c" + "${LUAJIT_DIR}/lib_bit.c" + "${LUAJIT_DIR}/lib_debug.c" + "${LUAJIT_DIR}/lib_ffi.c" + "${LUAJIT_DIR}/lib_io.c" + "${LUAJIT_DIR}/lib_jit.c" + "${LUAJIT_DIR}/lib_math.c" + "${LUAJIT_DIR}/lib_os.c" + "${LUAJIT_DIR}/lib_string.c" + "${LUAJIT_DIR}/lib_table.c" +) + +if (LUA_USE_RELATIVE_LOADLIB) + list(APPEND LJLIB_C "${LUAJIT_DIR}/lib_package_rel.c") +else() + list(APPEND LJLIB_C "${LUAJIT_DIR}/lib_package.c") +endif() + +macro(add_buildvm_target target mode) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${target}" + COMMAND "${BUILDVM_FILE}" ARGS -m ${mode} -o ${CMAKE_CURRENT_BINARY_DIR}/${target} ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + DEPENDS buildvm ${ARGN} + ) +endmacro() + +if (WIN32) + add_buildvm_target(lj_vm.obj peobj) + set(LJ_VM_SRC "${CMAKE_CURRENT_BINARY_DIR}/lj_vm.obj") +else() + add_buildvm_target(lj_vm.S ${LJVM_MODE}) + set(LJ_VM_SRC "${CMAKE_CURRENT_BINARY_DIR}/lj_vm.S") + set_source_files_properties("${LJ_VM_SRC}" PROPERTIES LANGUAGE CXX) +endif() + +add_buildvm_target("lj_bcdef.h" "bcdef" ${LJLIB_C}) +add_buildvm_target("lj_ffdef.h" "ffdef" ${LJLIB_C}) +add_buildvm_target("lj_libdef.h" "libdef" ${LJLIB_C}) +add_buildvm_target("lj_recdef.h" "recdef" ${LJLIB_C}) +add_buildvm_target("lj_folddef.h" "folddef" "${LUAJIT_DIR}/lj_opt_fold.c") +add_buildvm_target("jit/vmdef.lua" "libvm" ${LJLIB_C}) + +target_sources(xrLuaJIT PRIVATE + "${LJ_VM_SRC}" + "${CMAKE_CURRENT_BINARY_DIR}/lj_ffdef.h" + "${CMAKE_CURRENT_BINARY_DIR}/lj_bcdef.h" + "${CMAKE_CURRENT_BINARY_DIR}/lj_libdef.h" + "${CMAKE_CURRENT_BINARY_DIR}/lj_recdef.h" + "${CMAKE_CURRENT_BINARY_DIR}/lj_folddef.h" +) + +if (CMAKE_UNITY_BUILD) + target_sources(xrLuaJIT PRIVATE "${LUAJIT_DIR}/ljamalg.c") +else() + # TODO: use lj_asm_ lj_emit lj_target? + target_sources(xrLuaJIT PRIVATE + ${LJLIB_C} + "${LUAJIT_DIR}/lauxlib.h" + "${LUAJIT_DIR}/lib_aux.c" + "${LUAJIT_DIR}/lib_init.c" + "${LUAJIT_DIR}/lj_alloc.c" + "${LUAJIT_DIR}/lj_alloc.h" + "${LUAJIT_DIR}/lj_api.c" + "${LUAJIT_DIR}/lj_asm.c" + "${LUAJIT_DIR}/lj_asm.h" + "${LUAJIT_DIR}/lj_assert.c" + "${LUAJIT_DIR}/lj_bc.c" + "${LUAJIT_DIR}/lj_bc.h" + "${LUAJIT_DIR}/lj_bcdump.h" + "${LUAJIT_DIR}/lj_bcread.c" + "${LUAJIT_DIR}/lj_bcwrite.c" + "${LUAJIT_DIR}/lj_buf.c" + "${LUAJIT_DIR}/lj_buf.h" + "${LUAJIT_DIR}/lj_carith.c" + "${LUAJIT_DIR}/lj_carith.h" + "${LUAJIT_DIR}/lj_ccall.c" + "${LUAJIT_DIR}/lj_ccall.h" + "${LUAJIT_DIR}/lj_ccallback.c" + "${LUAJIT_DIR}/lj_ccallback.h" + "${LUAJIT_DIR}/lj_cconv.c" + "${LUAJIT_DIR}/lj_cconv.h" + "${LUAJIT_DIR}/lj_cdata.c" + "${LUAJIT_DIR}/lj_cdata.h" + "${LUAJIT_DIR}/lj_char.c" + "${LUAJIT_DIR}/lj_char.h" + "${LUAJIT_DIR}/lj_clib.c" + "${LUAJIT_DIR}/lj_clib.h" + "${LUAJIT_DIR}/lj_cparse.c" + "${LUAJIT_DIR}/lj_cparse.h" + "${LUAJIT_DIR}/lj_crecord.c" + "${LUAJIT_DIR}/lj_crecord.h" + "${LUAJIT_DIR}/lj_ctype.c" + "${LUAJIT_DIR}/lj_ctype.h" + "${LUAJIT_DIR}/lj_debug.c" + "${LUAJIT_DIR}/lj_debug.h" + "${LUAJIT_DIR}/lj_def.h" + "${LUAJIT_DIR}/lj_dispatch.c" + "${LUAJIT_DIR}/lj_dispatch.h" + "${LUAJIT_DIR}/lj_err.c" + "${LUAJIT_DIR}/lj_err.h" + "${LUAJIT_DIR}/lj_errmsg.h" + "${LUAJIT_DIR}/lj_ff.h" + "${LUAJIT_DIR}/lj_ffrecord.c" + "${LUAJIT_DIR}/lj_ffrecord.h" + "${LUAJIT_DIR}/lj_frame.h" + "${LUAJIT_DIR}/lj_func.c" + "${LUAJIT_DIR}/lj_func.h" + "${LUAJIT_DIR}/lj_gc.c" + "${LUAJIT_DIR}/lj_gc.h" + "${LUAJIT_DIR}/lj_gdbjit.c" + "${LUAJIT_DIR}/lj_gdbjit.h" + "${LUAJIT_DIR}/lj_ir.c" + "${LUAJIT_DIR}/lj_ircall.h" + "${LUAJIT_DIR}/lj_iropt.h" + "${LUAJIT_DIR}/lj_jit.h" + "${LUAJIT_DIR}/lj_lex.c" + "${LUAJIT_DIR}/lj_lex.h" + "${LUAJIT_DIR}/lj_lib.c" + "${LUAJIT_DIR}/lj_lib.h" + "${LUAJIT_DIR}/lj_load.c" + "${LUAJIT_DIR}/lj_mcode.c" + "${LUAJIT_DIR}/lj_mcode.h" + "${LUAJIT_DIR}/lj_meta.c" + "${LUAJIT_DIR}/lj_meta.h" + "${LUAJIT_DIR}/lj_obj.c" + "${LUAJIT_DIR}/lj_obj.h" + "${LUAJIT_DIR}/lj_opt_dce.c" + "${LUAJIT_DIR}/lj_opt_fold.c" + "${LUAJIT_DIR}/lj_opt_loop.c" + "${LUAJIT_DIR}/lj_opt_mem.c" + "${LUAJIT_DIR}/lj_opt_narrow.c" + "${LUAJIT_DIR}/lj_opt_sink.c" + "${LUAJIT_DIR}/lj_opt_split.c" + "${LUAJIT_DIR}/lj_parse.c" + "${LUAJIT_DIR}/lj_parse.h" + "${LUAJIT_DIR}/lj_prng.c" + "${LUAJIT_DIR}/lj_prng.h" + "${LUAJIT_DIR}/lj_profile.c" + "${LUAJIT_DIR}/lj_profile.h" + "${LUAJIT_DIR}/lj_record.c" + "${LUAJIT_DIR}/lj_record.h" + "${LUAJIT_DIR}/lj_snap.c" + "${LUAJIT_DIR}/lj_snap.h" + "${LUAJIT_DIR}/lj_state.c" + "${LUAJIT_DIR}/lj_state.h" + "${LUAJIT_DIR}/lj_str.c" + "${LUAJIT_DIR}/lj_str.h" + "${LUAJIT_DIR}/lj_strfmt.c" + "${LUAJIT_DIR}/lj_strfmt.h" + "${LUAJIT_DIR}/lj_strfmt_num.c" + "${LUAJIT_DIR}/lj_strscan.c" + "${LUAJIT_DIR}/lj_strscan.h" + "${LUAJIT_DIR}/lj_tab.c" + "${LUAJIT_DIR}/lj_tab.h" + "${LUAJIT_DIR}/lj_trace.c" + "${LUAJIT_DIR}/lj_trace.h" + "${LUAJIT_DIR}/lj_traceerr.h" + "${LUAJIT_DIR}/lj_udata.c" + "${LUAJIT_DIR}/lj_udata.h" + "${LUAJIT_DIR}/lj_vm.h" + "${LUAJIT_DIR}/lj_vmevent.c" + "${LUAJIT_DIR}/lj_vmevent.h" + "${LUAJIT_DIR}/lj_vmmath.c" + "${LUAJIT_DIR}/lua.h" + "${LUAJIT_DIR}/lua.hpp" + "${LUAJIT_DIR}/luaconf.h" + "${LUAJIT_DIR}/luajit.h" + "${LUAJIT_DIR}/lualib.h" + ) +endif() + +target_include_directories(xrLuaJIT + PUBLIC + "${CMAKE_SOURCE_DIR}/Externals/LuaJIT/src" + + PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}" +) + +target_link_libraries(xrLuaJIT + PRIVATE + $<$:m> + $<$:dl> +) + +target_compile_options(xrLuaJIT + PRIVATE + -Wno-comment +) + +set_target_properties(xrLuaJIT PROPERTIES + PREFIX "" + UNITY_BUILD OFF +) + +install( + TARGETS xrLuaJIT LIBRARY + DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +if (LUAJIT_BUILD_APP) + add_executable(luajit + "${LUAJIT_DIR}/luajit.c" + ) + + target_link_libraries(luajit + PRIVATE + xrLuaJIT + ) + + target_link_options(luajit + PRIVATE + ${TARGET_XLDFLAGS} + ) + + # On Windows build a no-console variant also + if (LUA_BUILD_WLUA) + # TODO: check if it works + add_executable(wluajit WIN32 + "${LUAJIT_DIR}/wmain.c" + "${LUAJIT_DIR}/luajit.c" + "${LUAJIT_DIR}/luajit.rc" + ) + target_link_libraries(wluajit + PRIVATE + xrLuaJIT + ) + endif() +endif() diff --git a/Externals/LuaJIT-proj/HostBuildTools/buildvm/CMakeLists.txt b/Externals/LuaJIT-proj/HostBuildTools/buildvm/CMakeLists.txt index 2bc4fd473c5..f0c2eaaded2 100644 --- a/Externals/LuaJIT-proj/HostBuildTools/buildvm/CMakeLists.txt +++ b/Externals/LuaJIT-proj/HostBuildTools/buildvm/CMakeLists.txt @@ -1,6 +1,8 @@ -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.22) -project(buildvm) +project(buildvm C) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (CMAKE_VERBOSE_MAKEFILE) set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT) @@ -8,13 +10,17 @@ endif() separate_arguments(HOST_ACFLAGS) separate_arguments(HOST_ALDFLAGS) -separate_arguments(BUILDVM_SRC NATIVE_COMMAND ${BUILDVM_SRC}) -separate_arguments(BUILDVM_ARCH) add_executable(buildvm) target_sources(buildvm PRIVATE - "${BUILDVM_SRC}" + "${LUAJIT_DIR}/host/buildvm_asm.c" + "${LUAJIT_DIR}/host/buildvm_fold.c" + "${LUAJIT_DIR}/host/buildvm_lib.c" + #"${LUAJIT_DIR}/host/buildvm_libbc.h" + "${LUAJIT_DIR}/host/buildvm_peobj.c" + "${LUAJIT_DIR}/host/buildvm.c" + "${LUAJIT_DIR}/host/buildvm.h" "${BUILDVM_ARCH}" ) @@ -27,6 +33,7 @@ target_include_directories(buildvm target_compile_options(buildvm PRIVATE ${HOST_ACFLAGS} + -Wno-discarded-qualifiers ) target_link_options(buildvm diff --git a/Externals/LuaJIT-proj/HostBuildTools/minilua/CMakeLists.txt b/Externals/LuaJIT-proj/HostBuildTools/minilua/CMakeLists.txt index 2c450dbf589..7f1d3e2b8ae 100644 --- a/Externals/LuaJIT-proj/HostBuildTools/minilua/CMakeLists.txt +++ b/Externals/LuaJIT-proj/HostBuildTools/minilua/CMakeLists.txt @@ -1,6 +1,8 @@ -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.22) -project(minilua) +project(minilua C) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (CMAKE_VERBOSE_MAKEFILE) set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT) diff --git a/Externals/LuaJIT-proj/luajit.cmake b/Externals/LuaJIT-proj/luajit.cmake deleted file mode 100644 index e71ba2946d2..00000000000 --- a/Externals/LuaJIT-proj/luajit.cmake +++ /dev/null @@ -1,645 +0,0 @@ -# Copyright (C) 2007-2013 LuaDist. -# Created by Peter Drahoš -# Redistribution and use of this file is allowed according to the terms of the MIT license. -# For details see the COPYRIGHT file distributed with LuaDist. -# Please note that the package source code is licensed under its own license. - -cmake_minimum_required(VERSION 3.13) - -project(xrLuajit C CXX ASM) - -# Version -set(MAJVER 2) -set(MINVER 0) -set(RELVER 5) -set(ABIVER 5.1) -set(NODOTABIVER 51) - -set(CMAKE_OSX_SYSROOT "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") -set(LUAJIT_DIR ${CMAKE_SOURCE_DIR}/Externals/LuaJIT/src CACHE PATH "Location of luajit sources") - -option(BUILD_STATIC_LIB "Build static library" OFF) -option(BUILD_DYNAMIC_LIB "Build dynamic library" ON) -option(BUILD_LIB_ONLY "Build library only" ON) - -# NOTE: Not working because there is no lib_package_rel.c file -option(LUA_USE_RELATIVE_LOADLIB "Use modified loadlib.c with support for relative paths on posix systems (Not working)" OFF) - -# Extra flags -option(LUAJIT_DISABLE_FFI "Disable the FFI extension to reduce the size of the LuaJIT executable. But please consider that the FFI library is compiled-in, but NOT loaded by default. It only allocates any memory, if you actually make use of it" OFF) -option(LUAJIT_ENABLE_LUA52COMPAT "Features from Lua 5.2 that are unlikely to break existing code are enabled by default. Some other features that *might* break some existing code (e.g. __pairs or os.execute() return values) can be enabled here. Note: this does not provide full compatibility with Lua 5.2 at this time" OFF) -option(LUAJIT_DISABLE_JIT "Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter" OFF) -option(LUAJIT_DISABLE_GC64 "Disable LJ_GC64 mode for x64" OFF) -option(LUAJIT_USE_SYSMALLOC "Use the system provided memory allocator (realloc) instead of the bundled memory allocator. This is slower, but sometimes helpful for debugging. It's helpful for Valgrind's memcheck tool, too. This option cannot be enabled on x64, since the built-in allocator is mandatory" OFF) -option(LUAJIT_USE_VALGRIND "This option is required to run LuaJIT under Valgrind. The Valgrind header files must be installed. You should enable debug information, too." OFF) -option(LUAJIT_USE_GDBJIT "This is the client for the GDB JIT API. GDB 7.0 or higher is required to make use of it. See lj_gdbjit.c for details. Enabling this causes a non-negligible overhead, even when not running under GDB" OFF) - -option(LUA_USE_APICHECK "Turn on assertions for the Lua/C API to debug problems with lua_* calls. This is rather slow, use only while developing C libraries/embeddings" OFF) -option(LUA_USE_ASSERT "Turn on assertions for the whole LuaJIT VM. This significantly slows down everything. Use only if you suspect a problem with LuaJIT itself" OFF) - -option(LUAJIT_DEBUG "Generate debug information" OFF) - -if (WIN32) - option(LUA_BUILD_WLUA "Build wluajit interpreter for no-console applications." ON) -elseif (APPLE) - option(LUA_USE_POSIX "Use POSIX functionality." ON) - option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) -else() - option(LUA_USE_POSIX "Use POSIX functionality." ON) - option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) -endif() - -# TODO: check if we need luaconf.h -# TODO: add other variables from luaconf.h if we need them -# Configuration for luaconf.h -set(LUA_PATH "LUA_PATH" CACHE STRING "Environment variable to use as package.path") -set(LUA_CPATH "LUA_CPATH" CACHE STRING "Environment variable to use as package.cpath") -set(LUA_INIT "LUA_INIT" CACHE STRING "Environment variable for initial script") - -# Clean unnecessary files in LuaJIT source directory -execute_process( - COMMAND ${CMAKE_MAKE_PROGRAM} clean - WORKING_DIRECTORY ${LUAJIT_DIR} -) - -# Compiler options -if (PROJECT_PLATFORM_E2K) # E2K: O3 on mcst-lcc approximately equal to O2 at gcc X86/ARM - set(CCOPT_OPT_LEVEL "-O3") -else() - set(CCOPT_OPT_LEVEL "-O2") -endif() - -# TODO Refactor all these options -if (USE_ADDRESS_SANITIZER) - set(CCOPT "${CCOPT_OPT_LEVEL} -fno-stack-protector") -else() - set(CCOPT "${CCOPT_OPT_LEVEL} -fomit-frame-pointer -fno-stack-protector") -endif() - -# Target-specific compiler options -set(CCOPT_x86 "-march=i686 -msse -msse2 -mfpmath=sse") -set(CCOPT_x64 "") -set(CCOPT_arm "") -set(CCOPT_arm64 "") -set(CCOPT_ppc "") -set(CCOPT_mips "") - -if (CCDEBUG) - set(LUAJIT_DEBUG "-g") -endif() - -set(CCWARN "-Wall") -#string(APPEND CCWARN "-Wextra -Wdeclaration-after-statement -Wredundant-decls -Wshadow -Wpointer-arith") - -if (LUAJIT_DISABLE_FFI) - string(APPEND XCFLAGS " -DLUAJIT_DISABLE_FFI") -endif() - -if (LUAJIT_ENABLE_LUA52COMPAT) - string(APPEND XCFLAGS " -DLUAJIT_ENABLE_LUA52COMPAT") -endif() - -if (LUAJIT_DISABLE_JIT) - string(APPEND XCFLAGS " -DLUAJIT_DISABLE_JIT") -endif() - -if (LUAJIT_DISABLE_GC64) - string(APPEND XCFLAGS " -DLUAJIT_DISABLE_GC64") -endif() - -if (LUAJIT_USE_SYSMALLOC) - string(APPEND XCFLAGS " -DLUAJIT_USE_SYSMALLOC") -endif() - -if (LUAJIT_USE_VALGRIND) - string(APPEND XCFLAGS " -DLUAJIT_USE_VALGRIND") -endif() - -if (LUAJIT_USE_GDBJIT) - string(APPEND XCFLAGS " -DLUAJIT_USE_GDBJIT") -endif() - -if (LUA_USE_APICHECK) - string(APPEND XCFLAGS " -DLUA_USE_APICHECK") -endif() - -if (LUA_USE_ASSERT) - string(APPEND XCFLAGS " -DLUA_USE_ASSERT") -endif() - -set(ASOPTIONS ${CCOPT} ${CCWARN}${XCFLAGS}) -set(CCOPTIONS ${CCDEBUG} ${ASOPTIONS}) - -set(TESTARCH_C_FLAGS ${CMAKE_C_FLAGS}) -string(REPLACE " " ";" TESTARCH_C_FLAGS "${TESTARCH_C_FLAGS}") - -set(TESTARCH_FLAGS "${TESTARCH_C_FLAGS} ${CCOPTIONS} -E lj_arch.h -dM") -string(REPLACE " " ";" TESTARCH_FLAGS "${TESTARCH_FLAGS}") - -if (APPLE) - set(ENV{SDKROOT} ${CMAKE_OSX_SYSROOT}) -endif() - -execute_process( - COMMAND ${CMAKE_C_COMPILER} ${TESTARCH_FLAGS} - WORKING_DIRECTORY ${LUAJIT_DIR} - OUTPUT_VARIABLE TARGET_TESTARCH -) - -if ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_X64") - set(TARGET_LJARCH "x64") -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_X86") - set(TARGET_LJARCH "x86") -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_ARM64") - set(TARGET_LJARCH "arm64") - if ("${TARGET_TESTARCH}" MATCHES "__AARCH64EB__") - set(TARGET_ARCH "-D__AARCH64EB__=1") - endif() -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_ARM") - set(TARGET_LJARCH "arm") -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_PPC") - set(TARGET_LJARCH "ppc") -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_MIPS") - if ("${TARGET_TESTARCH}" MATCHES "MIPSEL") - set(TARGET_ARCH "-D__MIPSEL__=1") - endif() - if ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_MIPS64") - set(TARGET_LJARCH "mips64") - else() - set(TARGET_LJARCH "mips") - endif() -elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "e2k") # MCST Elbrus 2000 - set(TARGET_LJARCH "e2k") -else() - message(FATAL_ERROR "Unsupported luajit target architecture") -endif() - -string(APPEND TARGET_ARCH "-DLUAJIT_TARGET=LUAJIT_ARCH_${TARGET_LJARCH}") -string(APPEND TARGET_XCFLAGS "${CCOPT_${TARGET_LJARCH}}") - -# TODO: add PREFIX, TARGET_XCFLAGS, TARGET_DYNXLDOPTS, MULTILIB here (lines 289-302 in Makefile) - -# TODO: use TARGET_STRIP flags? - -if (WIN32) - #string(APPEND TARGET_STRIP "--strip-unneeded") - - set(TARGET_DLLDOTANAME "libluajit-${ABIVER}.dll.a") - string(APPEND TARGET_XSHLDFLAGS " -shared -Wl,--out-implib,${TARGET_DLLDOTANAME}") - - if (BUILD_DYNAMIC_LIB) - string(APPEND HOST_XCFLAGS " -DLUA_BUILD_AS_DLL") - endif() - - set(LJVM_MODE peobj) -elseif (APPLE) - if (CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "") - message(FATAL_ERROR "Missing export MACOSX_DEPLOYMENT_TARGET=XX.YY") - endif() - - #string(APPEND TARGET_STRIP "-x") - # XXX: doesn't compile with Apple Clang - #string(APPEND TARGET_XSHLDFLAGS " -dynamiclib -single_module -undefined dynamic_lookup -fPIC") - #string(APPEND TARGET_XSHLDFLAGS " -install_name ${TARGET_DYLIBPATH} -compatibility_version ${MAJVER}.${MINVER} -current_version ${MAJVER}.${MINVER}.${RELVER}") - - if (${TARGET_LJARCH} STREQUAL "x64") - string(APPEND TARGET_XLDFLAGS " -pagezero_size 10000 -image_base 100000000 -image_base 7fff04c4a000") - elseif (${TARGET_LJARCH} STREQUAL "arm64") - string(APPEND TARGET_XCFLAGS " -fno-omit-frame-pointer") - endif() - - set(LJVM_MODE machasm) -else() - set(LJVM_MODE elfasm) -endif() - -# TODO: add HOST_SYS != TARGET_SYS code (lines 354-372 in Makefile) -#string(APPEND HOST_XCFLAGS "-DLUA_BUILD_AS_DLL -DLUAJIT_OS=LUAJIT_OS_WINDOWS") -# TODO: add "-DTARGET_OS_IPHONE=1" on iOS -#string(APPEND HOST_XCFLAGS "-DLUAJIT_OS=LUAJIT_OS_OSX") - -if ("${TARGET_TESTARCH}" MATCHES "LJ_LE 1") - string(APPEND DASM_FLAGS "-D ENDIAN_LE") -else() - string(APPEND DASM_FLAGS "-D ENDIAN_BE") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_BITS 64") - string(APPEND DASM_FLAGS " -D P64") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_HASJIT 1") - string(APPEND DASM_FLAGS " -D JIT") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_HASFFI 1") - string(APPEND DASM_FLAGS " -D FFI") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_DUALNUM 1") - string(APPEND DASM_FLAGS " -D DUALNUM") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_HASFPU 1") - string(APPEND DASM_FLAGS " -D FPU") - string(APPEND TARGET_ARCH " -DLJ_ARCH_HASFPU=1") -else() - string(APPEND TARGET_ARCH " -DLJ_ARCH_HASFPU=0") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_ABI_SOFTFP 1") - string(APPEND TARGET_ARCH " -DLJ_ABI_SOFTFP=1") -else() - string(APPEND DASM_FLAGS " -D HFABI") - string(APPEND TARGET_ARCH " -DLJ_ABI_SOFTFP=0") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_NO_UNWIND 1") - string(APPEND DASM_FLAGS " -D NO_UNWIND") - string(APPEND TARGET_ARCH " -DLUAJIT_NO_UNWIND") -endif() - -if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_VERSION") - string(REGEX MATCH "LJ_ARCH_VERSION ([0-9]+)$" _ "${TARGET_TESTARCH}") - string(APPEND DASM_FLAGS " -D VER=${CMAKE_MATCH_1}") -else() - string(APPEND DASM_FLAGS " -D VER=") -endif() - -set(DASM_ARCH ${TARGET_LJARCH}) - -if (WIN32) - string(APPEND DASM_FLAGS " -D WIN") -endif() - -if (TARGET_LJARCH STREQUAL "x64") - if (NOT "${TARGET_TESTARCH}" MATCHES "LJ_FR2 1") - set(DASM_ARCH "x86") - endif() -elseif (TARGET_LJARCH STREQUAL "arm") - if (APPLE) - string(APPEND DASM_FLAGS " -D IOS") - endif() -elseif ("${TARGET_TESTARCH}" MATCHES "LJ_TARGET_MIPSR6") - string(APPEND DASM_FLAGS " -D MIPSR6") -endif() - -if (TARGET_LJARCH STREQUAL "ppc") - if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_SQRT 1") - string(APPEND DASM_FLAGS " -D SQRT") - endif() - if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_ROUND 1") - string(APPEND DASM_FLAGS " -D ROUND") - endif() - if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_PPC32ON64 1") - string(APPEND DASM_FLAGS " -D GPR64") - endif() - if ("${TARGET_TESTARCH}" MATCHES "LJ_ARCH_PPC64") - set(DASM_ARCH "ppc64") - endif() -endif() - -set(HOST_ACFLAGS "${CMAKE_C_FLAGS} ${CCOPTIONS} ${TARGET_ARCH}") -set(HOST_ALDFLAGS "${CMAKE_C_FLAGS}") - -string(APPEND TARGET_XCFLAGS " -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE") - -string(REPLACE " " ";" CCOPTIONS "${CCOPTIONS}") -string(REPLACE " " ";" HOST_ACFLAGS "${HOST_ACFLAGS}") -string(REPLACE " " ";" HOST_ALDFLAGS "${HOST_ALDFLAGS}") -string(REPLACE " " ";" DASM_FLAGS "${DASM_FLAGS}") -string(REPLACE " " ";" TARGET_XCFLAGS "${TARGET_XCFLAGS}") - -set(DASM_DASC ${LUAJIT_DIR}/vm_${DASM_ARCH}.dasc) -set(DASM ${LUAJIT_DIR}/../dynasm/dynasm.lua) - -if (PROJECT_PLATFORM_E2K) - set(BUILDVM_ARCH "${LUAJIT_DIR}/host/buildvm_arch.h") -else() - set(BUILDVM_ARCH "${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h") -endif() - -# Generate buildvm arch header -if (NOT PROJECT_PLATFORM_E2K) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/minilua/minilua" - COMMAND ${CMAKE_COMMAND} - -B"HostBuildTools/minilua" - -G "${CMAKE_GENERATOR}" - -H${CMAKE_CURRENT_SOURCE_DIR}/HostBuildTools/minilua - -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} - -DCMAKE_BUILD_TYPE:STRING="Release" - -DLUAJIT_DIR=${LUAJIT_DIR} - -DLUA_USE_POSIX="${LUA_USE_POSIX}" - -DHOST_ACFLAGS="${HOST_ACFLAGS}" - -DHOST_ALDFLAGS="${HOST_ALDFLAGS}" - COMMAND ${CMAKE_COMMAND} --build "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/minilua" --config Release - ) - - add_custom_command(OUTPUT ${BUILDVM_ARCH} - COMMAND "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/minilua/minilua" ${DASM} ${DASM_FLAGS} -o ${BUILDVM_ARCH} ${DASM_DASC} - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/minilua/minilua" - ) - - add_custom_target(buildvm_arch - DEPENDS ${BUILDVM_ARCH} - ) -endif() - -# Buildvm -set(BUILDVM_SRC - "${LUAJIT_DIR}/host/buildvm_asm.c" - "${LUAJIT_DIR}/host/buildvm_fold.c" - "${LUAJIT_DIR}/host/buildvm_lib.c" - #"${LUAJIT_DIR}/host/buildvm_libbc.h" - "${LUAJIT_DIR}/host/buildvm_peobj.c" - "${LUAJIT_DIR}/host/buildvm.c" - "${LUAJIT_DIR}/host/buildvm.h" -) - -group_sources(BUILDVM_SRC) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/buildvm/buildvm" - COMMAND ${CMAKE_COMMAND} - -B"HostBuildTools/buildvm" - -G "${CMAKE_GENERATOR}" - -H${CMAKE_CURRENT_SOURCE_DIR}/HostBuildTools/buildvm - -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} - -DCMAKE_BUILD_TYPE:STRING="Release" - -DLUAJIT_DIR=${LUAJIT_DIR} - -DBUILDVM_SRC="${BUILDVM_SRC}" - -DBUILDVM_ARCH="${BUILDVM_ARCH}" - -DHOST_ACFLAGS="${HOST_ACFLAGS}" - -DHOST_ALDFLAGS="${HOST_ALDFLAGS}" - COMMAND ${CMAKE_COMMAND} --build HostBuildTools/buildvm --config Release -) - -add_custom_target(buildvm - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/buildvm/buildvm" -) - -if (NOT PROJECT_PLATFORM_E2K) - add_dependencies(buildvm buildvm_arch) -endif() - -set(LJLIB_C - "${LUAJIT_DIR}/lib_base.c" - "${LUAJIT_DIR}/lib_bit.c" - "${LUAJIT_DIR}/lib_debug.c" - "${LUAJIT_DIR}/lib_ffi.c" - "${LUAJIT_DIR}/lib_io.c" - "${LUAJIT_DIR}/lib_jit.c" - "${LUAJIT_DIR}/lib_math.c" - "${LUAJIT_DIR}/lib_os.c" - "${LUAJIT_DIR}/lib_string.c" - "${LUAJIT_DIR}/lib_table.c" -) - -if (LUA_USE_RELATIVE_LOADLIB) - list(APPEND LJLIB_C "${LUAJIT_DIR}/lib_package_rel.c") -else() - list(APPEND LJLIB_C "${LUAJIT_DIR}/lib_package.c") -endif() - -macro(add_buildvm_target target mode) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${target}" - COMMAND "${CMAKE_CURRENT_BINARY_DIR}/HostBuildTools/buildvm/buildvm" ARGS -m ${mode} -o ${CMAKE_CURRENT_BINARY_DIR}/${target} ${ARGN} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - DEPENDS buildvm ${ARGN} - ) -endmacro() - -if (WIN32) - add_buildvm_target(lj_vm.obj peobj) - set(LJ_VM_SRC "${CMAKE_CURRENT_BINARY_DIR}/lj_vm.obj") -else() - add_buildvm_target(lj_vm.S ${LJVM_MODE}) - set(LJ_VM_SRC "${CMAKE_CURRENT_BINARY_DIR}/lj_vm.S") - set_source_files_properties(${LJ_VM_SRC} PROPERTIES LANGUAGE CXX) -endif() - -add_buildvm_target("lj_bcdef.h" "bcdef" ${LJLIB_C}) -add_buildvm_target("lj_ffdef.h" "ffdef" ${LJLIB_C}) -add_buildvm_target("lj_libdef.h" "libdef" ${LJLIB_C}) -add_buildvm_target("lj_recdef.h" "recdef" ${LJLIB_C}) -add_buildvm_target("lj_folddef.h" "folddef" "${LUAJIT_DIR}/lj_opt_fold.c") -add_buildvm_target("jit/vmdef.lua" "libvm" ${LJLIB_C}) - -SET(DEPS - ${LJ_VM_SRC} - "${CMAKE_CURRENT_BINARY_DIR}/lj_ffdef.h" - "${CMAKE_CURRENT_BINARY_DIR}/lj_bcdef.h" - "${CMAKE_CURRENT_BINARY_DIR}/lj_libdef.h" - "${CMAKE_CURRENT_BINARY_DIR}/lj_recdef.h" - "${CMAKE_CURRENT_BINARY_DIR}/lj_folddef.h" -) - -group_sources(DEPS) - -if (CMAKE_UNITY_BUILD) - set(LJCORE_C "${LUAJIT_DIR}/ljamalg.c") -else() - # TODO: use lj_asm_ lj_emit lj_target? - set(LJCORE_C - ${LJLIB_C} - "${LUAJIT_DIR}/lauxlib.h" - "${LUAJIT_DIR}/lib_aux.c" - "${LUAJIT_DIR}/lib_init.c" - "${LUAJIT_DIR}/lj_alloc.c" - "${LUAJIT_DIR}/lj_alloc.h" - "${LUAJIT_DIR}/lj_api.c" - "${LUAJIT_DIR}/lj_asm.c" - "${LUAJIT_DIR}/lj_asm.h" - "${LUAJIT_DIR}/lj_assert.c" - "${LUAJIT_DIR}/lj_bc.c" - "${LUAJIT_DIR}/lj_bc.h" - "${LUAJIT_DIR}/lj_bcdump.h" - "${LUAJIT_DIR}/lj_bcread.c" - "${LUAJIT_DIR}/lj_bcwrite.c" - "${LUAJIT_DIR}/lj_buf.c" - "${LUAJIT_DIR}/lj_buf.h" - "${LUAJIT_DIR}/lj_carith.c" - "${LUAJIT_DIR}/lj_carith.h" - "${LUAJIT_DIR}/lj_ccall.c" - "${LUAJIT_DIR}/lj_ccall.h" - "${LUAJIT_DIR}/lj_ccallback.c" - "${LUAJIT_DIR}/lj_ccallback.h" - "${LUAJIT_DIR}/lj_cconv.c" - "${LUAJIT_DIR}/lj_cconv.h" - "${LUAJIT_DIR}/lj_cdata.c" - "${LUAJIT_DIR}/lj_cdata.h" - "${LUAJIT_DIR}/lj_char.c" - "${LUAJIT_DIR}/lj_char.h" - "${LUAJIT_DIR}/lj_clib.c" - "${LUAJIT_DIR}/lj_clib.h" - "${LUAJIT_DIR}/lj_cparse.c" - "${LUAJIT_DIR}/lj_cparse.h" - "${LUAJIT_DIR}/lj_crecord.c" - "${LUAJIT_DIR}/lj_crecord.h" - "${LUAJIT_DIR}/lj_ctype.c" - "${LUAJIT_DIR}/lj_ctype.h" - "${LUAJIT_DIR}/lj_debug.c" - "${LUAJIT_DIR}/lj_debug.h" - "${LUAJIT_DIR}/lj_def.h" - "${LUAJIT_DIR}/lj_dispatch.c" - "${LUAJIT_DIR}/lj_dispatch.h" - "${LUAJIT_DIR}/lj_err.c" - "${LUAJIT_DIR}/lj_err.h" - "${LUAJIT_DIR}/lj_errmsg.h" - "${LUAJIT_DIR}/lj_ff.h" - "${LUAJIT_DIR}/lj_ffrecord.c" - "${LUAJIT_DIR}/lj_ffrecord.h" - "${LUAJIT_DIR}/lj_frame.h" - "${LUAJIT_DIR}/lj_func.c" - "${LUAJIT_DIR}/lj_func.h" - "${LUAJIT_DIR}/lj_gc.c" - "${LUAJIT_DIR}/lj_gc.h" - "${LUAJIT_DIR}/lj_gdbjit.c" - "${LUAJIT_DIR}/lj_gdbjit.h" - "${LUAJIT_DIR}/lj_ir.c" - "${LUAJIT_DIR}/lj_ircall.h" - "${LUAJIT_DIR}/lj_iropt.h" - "${LUAJIT_DIR}/lj_jit.h" - "${LUAJIT_DIR}/lj_lex.c" - "${LUAJIT_DIR}/lj_lex.h" - "${LUAJIT_DIR}/lj_lib.c" - "${LUAJIT_DIR}/lj_lib.h" - "${LUAJIT_DIR}/lj_load.c" - "${LUAJIT_DIR}/lj_mcode.c" - "${LUAJIT_DIR}/lj_mcode.h" - "${LUAJIT_DIR}/lj_meta.c" - "${LUAJIT_DIR}/lj_meta.h" - "${LUAJIT_DIR}/lj_obj.c" - "${LUAJIT_DIR}/lj_obj.h" - "${LUAJIT_DIR}/lj_opt_dce.c" - "${LUAJIT_DIR}/lj_opt_fold.c" - "${LUAJIT_DIR}/lj_opt_loop.c" - "${LUAJIT_DIR}/lj_opt_mem.c" - "${LUAJIT_DIR}/lj_opt_narrow.c" - "${LUAJIT_DIR}/lj_opt_sink.c" - "${LUAJIT_DIR}/lj_opt_split.c" - "${LUAJIT_DIR}/lj_parse.c" - "${LUAJIT_DIR}/lj_parse.h" - "${LUAJIT_DIR}/lj_prng.c" - "${LUAJIT_DIR}/lj_prng.h" - "${LUAJIT_DIR}/lj_profile.c" - "${LUAJIT_DIR}/lj_profile.h" - "${LUAJIT_DIR}/lj_record.c" - "${LUAJIT_DIR}/lj_record.h" - "${LUAJIT_DIR}/lj_snap.c" - "${LUAJIT_DIR}/lj_snap.h" - "${LUAJIT_DIR}/lj_state.c" - "${LUAJIT_DIR}/lj_state.h" - "${LUAJIT_DIR}/lj_str.c" - "${LUAJIT_DIR}/lj_str.h" - "${LUAJIT_DIR}/lj_strfmt.c" - "${LUAJIT_DIR}/lj_strfmt.h" - "${LUAJIT_DIR}/lj_strfmt_num.c" - "${LUAJIT_DIR}/lj_strscan.c" - "${LUAJIT_DIR}/lj_strscan.h" - "${LUAJIT_DIR}/lj_tab.c" - "${LUAJIT_DIR}/lj_tab.h" - "${LUAJIT_DIR}/lj_trace.c" - "${LUAJIT_DIR}/lj_trace.h" - "${LUAJIT_DIR}/lj_traceerr.h" - "${LUAJIT_DIR}/lj_udata.c" - "${LUAJIT_DIR}/lj_udata.h" - "${LUAJIT_DIR}/lj_vm.h" - "${LUAJIT_DIR}/lj_vmevent.c" - "${LUAJIT_DIR}/lj_vmevent.h" - "${LUAJIT_DIR}/lj_vmmath.c" - "${LUAJIT_DIR}/lua.h" - "${LUAJIT_DIR}/lua.hpp" - "${LUAJIT_DIR}/luaconf.h" - "${LUAJIT_DIR}/luajit.h" - "${LUAJIT_DIR}/lualib.h" - ) -endif() - -group_sources(LJCORE_C) - -if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - set(LIB_NAME ${PROJECT_NAME}-debug) -else() - set(LIB_NAME ${PROJECT_NAME}) -endif() - -# TODO: check windows supports same target name for static and shared lib -if (BUILD_STATIC_LIB) - add_library(${LIB_NAME} STATIC - ${LJCORE_C} - ${DEPS} - ) - target_link_libraries(${LIB_NAME} ${LIBS}) -endif() - -if (BUILD_DYNAMIC_LIB) - add_library(${LIB_NAME} SHARED - ${LJCORE_C} - ${DEPS} - ) -endif() - -target_include_directories(${LIB_NAME} - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} -) - -target_link_libraries(${LIB_NAME} - PRIVATE - $<$:m> - $<$:dl> -) - -target_compile_options(${LIB_NAME} - PRIVATE - ${CCOPTIONS} - ${TARGET_XCFLAGS} -) - -target_link_options(${LIB_NAME} - PRIVATE - ${TARGET_XSHLDFLAGS} -) - -set_target_properties(${LIB_NAME} PROPERTIES - PREFIX "" - UNITY_BUILD OFF -) - -install(TARGETS ${LIB_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ -) - -if (NOT ${BUILD_LIB_ONLY}) - add_executable(luajit - "${LUAJIT_DIR}/luajit.c" - ) - - target_link_libraries(luajit - PRIVATE - ${LIB_NAME} - ) - - target_link_options(luajit - PRIVATE - ${TARGET_XLDFLAGS} - ) - - # On Windows build a no-console variant also - if (LUA_BUILD_WLUA) - # TODO: check if it works - add_executable(wluajit WIN32 - "${LUAJIT_DIR}/wmain.c" - "${LUAJIT_DIR}/luajit.c" - "${LUAJIT_DIR}/luajit.rc" - ) - target_link_libraries(wluajit - PRIVATE - ${LIB_NAME} - ) - endif() -endif() diff --git a/Externals/NVTT/CMakeLists.txt b/Externals/NVTT/CMakeLists.txt index 9ed004a39a4..b704148eae8 100644 --- a/Externals/NVTT/CMakeLists.txt +++ b/Externals/NVTT/CMakeLists.txt @@ -1,9 +1,5 @@ -cmake_minimum_required(VERSION 3.10) - project(nvtt) -add_definitions(-DHAVE_SIGNAL_H -DHAVE_EXECINFO_H) - add_subdirectory(src/nvcore) add_subdirectory(src/nvimage) add_subdirectory(src/nvmath) diff --git a/Externals/NVTT/src/nvcore/CMakeLists.txt b/Externals/NVTT/src/nvcore/CMakeLists.txt index 1502d8ce089..e54b6d10ef5 100644 --- a/Externals/NVTT/src/nvcore/CMakeLists.txt +++ b/Externals/NVTT/src/nvcore/CMakeLists.txt @@ -1,62 +1,59 @@ -project(nvcore) +option(NVCORE_SHARED "Build nvcore as shared library" OFF) -set(NVCORE_SHARED OFF) - -# XXX: check if poshlib is needed? add_subdirectory(poshlib) -set(SRC_FILES - "nvcore.h" - "Ptr.h" - "BitArray.h" - "Memory.h" - "Memory.cpp" - "Debug.h" - "Debug.cpp" - "Containers.h" - "StrLib.h" - "StrLib.cpp" - "Stream.h" - "StdStream.h" - "TextReader.h" - "TextReader.cpp" - "TextWriter.h" - "TextWriter.cpp" - "Radix.h" - "Radix.cpp" - "Library.h" - "Library.cpp" -) - -group_sources(SRC_FILES) - if (NVCORE_SHARED) - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(nvcore SHARED) + + target_compile_definitions(nvcore + PRIVATE + NVCORE_SHARED + ) else() - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(nvcore STATIC) endif() -target_include_directories(${PROJECT_NAME} +target_sources(nvcore PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/Externals/NVTT/src - ${CMAKE_SOURCE_DIR}/Externals/NVTT/include + nvcore.h + Ptr.h + BitArray.h + Memory.h + Memory.cpp + Debug.h + Debug.cpp + Containers.h + StrLib.h + StrLib.cpp + Stream.h + StdStream.h + TextReader.h + TextReader.cpp + TextWriter.h + TextWriter.cpp + Radix.h + Radix.cpp + Library.h + Library.cpp ) -target_compile_definitions(${PROJECT_NAME} +target_include_directories(nvcore + PUBLIC + "${CMAKE_SOURCE_DIR}/Externals/NVTT/src" + "${CMAKE_SOURCE_DIR}/Externals/NVTT/include" +) + +target_compile_definitions(nvcore PRIVATE - -DNVCORE_EXPORTS - $<$:-DNVCORE_SHARED=1> + NVCORE_EXPORTS + HAVE_EXECINFO_H + HAVE_SIGNAL_H ) -if (UNIX) - target_link_libraries(${PROJECT_NAME} - PRIVATE - ${CMAKE_DL_LIBS} # XXX: why? - ) -endif() +set_target_properties(nvcore PROPERTIES + POSITION_INDEPENDENT_CODE ON +) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS nvcore LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt b/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt index b0a52c9f641..1b8d4e37e2d 100644 --- a/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt +++ b/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt @@ -1,6 +1,6 @@ -set(SRC_FILES - "posh.c" - "posh.h" -) +add_library(posh STATIC) -add_library(posh STATIC ${SRC_FILES}) +target_sources(posh PRIVATE + posh.c + posh.h +) diff --git a/Externals/NVTT/src/nvimage/CMakeLists.txt b/Externals/NVTT/src/nvimage/CMakeLists.txt index 08e0c0b0a9a..830fd449ba7 100644 --- a/Externals/NVTT/src/nvimage/CMakeLists.txt +++ b/Externals/NVTT/src/nvimage/CMakeLists.txt @@ -1,72 +1,65 @@ -PROJECT(nvimage) - -set(NVIMAGE_SHARED OFF) - -set(SRC_FILES - "nvimage.h" - "FloatImage.h" - "FloatImage.cpp" - "Filter.h" - "Filter.cpp" - "Image.h" - "Image.cpp" - "ImageIO.h" - "ImageIO.cpp" - "ColorBlock.h" - "ColorBlock.cpp" - "BlockDXT.h" - "BlockDXT.cpp" - "HoleFilling.h" - "HoleFilling.cpp" - "DirectDrawSurface.h" - "DirectDrawSurface.cpp" - "Quantize.h" - "Quantize.cpp" - "NormalMap.h" - "NormalMap.cpp" - "NormalMipmap.h" - "NormalMipmap.cpp" - "PsdFile.h" - "TgaFile.h" -) - -group_sources(SRC_FILES) +option(NVIMAGE_SHARED "Build nvimage as shared library" OFF) if (NVIMAGE_SHARED) - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(nvimage SHARED) + + target_compile_definitions(nvimage + PRIVATE + NVIMAGE_SHARED=1 + ) else() - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(nvimage STATIC) endif() -target_include_directories(${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/Externals/NVTT/src - ${CMAKE_SOURCE_DIR}/Externals/NVTT/include - $<$:${PNG_INCLUDE_DIR}> - $<$:${JPEG_INCLUDE_DIR}> - $<$:${TIFF_INCLUDE_DIR}> - $<$:${OPENEXR_INCLUDE_PATHS}> +target_sources(nvimage PRIVATE + nvimage.h + FloatImage.h + FloatImage.cpp + Filter.h + Filter.cpp + Image.h + Image.cpp + ImageIO.h + ImageIO.cpp + ColorBlock.h + ColorBlock.cpp + BlockDXT.h + BlockDXT.cpp + HoleFilling.h + HoleFilling.cpp + DirectDrawSurface.h + DirectDrawSurface.cpp + Quantize.h + Quantize.cpp + NormalMap.h + NormalMap.cpp + NormalMipmap.h + NormalMipmap.cpp + PsdFile.h + TgaFile.h ) -target_link_libraries(${PROJECT_NAME} - PRIVATE +target_link_libraries(nvimage + PUBLIC nvcore nvmath + PRIVATE posh - $<$:${PNG_LIBRARIES}> - $<$:${JPEG_LIBRARIES}> - $<$:${TIFF_LIBRARIES}> - $<$:${OPENEXR_LIBRARIES}> + $<$:PNG::PNG> + $<$:JPEG::JPEG> + $<$:TIFF::TIFF> + $<$:OpenEXR::OpenEXR> ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(nvimage PRIVATE - -DNVIMAGE_EXPORTS - $<$:-DNVIMAGE_SHARED=1> + NVIMAGE_EXPORTS +) + +set_property(TARGET nvimage PROPERTY + POSITION_INDEPENDENT_CODE ON ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS nvimage LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/Externals/NVTT/src/nvmath/CMakeLists.txt b/Externals/NVTT/src/nvmath/CMakeLists.txt index 807e44d0f48..36f7341aa80 100644 --- a/Externals/NVTT/src/nvmath/CMakeLists.txt +++ b/Externals/NVTT/src/nvmath/CMakeLists.txt @@ -1,54 +1,46 @@ -PROJECT(nvmath) - -set(NVMATH_SHARED OFF) - -set(SRC_FILES - "nvmath.h" - "Vector.h" - "Matrix.h" - "Quaternion.h" - "Box.h" - "Color.h" - "Montecarlo.h" - "Montecarlo.cpp" - "Random.h" - "Random.cpp" - "SphericalHarmonic.h" - "SphericalHarmonic.cpp" - "Basis.h" - "Basis.cpp" - "Triangle.h" - "Triangle.cpp" - "TriBox.cpp" -) - -group_sources(SRC_FILES) +option(NVMATH_SHARED "Build nvmath as shared library" OFF) if (NVMATH_SHARED) - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(nvmath SHARED) + + target_compile_definitions(nvmath + PRIVATE + NVCORE_SHARED + ) else() - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(nvmath STATIC) endif() -target_include_directories(${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/Externals/NVTT/src - ${CMAKE_SOURCE_DIR}/Externals/NVTT/include +target_sources(nvmath PRIVATE + nvmath.h + Vector.h + Matrix.h + Quaternion.h + Box.h + Color.h + Montecarlo.h + Montecarlo.cpp + Random.h + Random.cpp + SphericalHarmonic.h + SphericalHarmonic.cpp + Basis.h + Basis.cpp + Triangle.h + Triangle.cpp + TriBox.cpp ) -target_link_libraries(${PROJECT_NAME} - PRIVATE +target_link_libraries(nvmath + PUBLIC nvcore ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(nvmath PRIVATE - -DNVCORE_EXPORTS - $<$:-DNVMATH_SHARED=1> + NVCORE_EXPORTS ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS nvmath LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/Externals/NVTT/src/nvtt/CMakeLists.txt b/Externals/NVTT/src/nvtt/CMakeLists.txt index 61e88df5b95..bfa58f4b834 100644 --- a/Externals/NVTT/src/nvtt/CMakeLists.txt +++ b/Externals/NVTT/src/nvtt/CMakeLists.txt @@ -1,143 +1,139 @@ -PROJECT(nvtt) - -ADD_SUBDIRECTORY(squish) - -set(NVTT_SHARED OFF) -set(NVTT_TEST_EXECUTABLES ON) - -set(SRC_FILES - "nvtt.h" - "nvtt.cpp" - "Compressor.h" - "Compressor.cpp" - "nvtt_wrapper.h" - "nvtt_wrapper.cpp" - "CompressDXT.h" - "CompressDXT.cpp" - "CompressRGB.h" - "CompressRGB.cpp" - "QuickCompressDXT.h" - "QuickCompressDXT.cpp" - "OptimalCompressDXT.h" - "OptimalCompressDXT.cpp" - "SingleColorLookup.h" - "CompressionOptions.h" - "CompressionOptions.cpp" - "InputOptions.h" - "InputOptions.cpp" - "OutputOptions.h" - "OutputOptions.cpp" - "cuda/CudaUtils.h" - "cuda/CudaUtils.cpp" - "cuda/CudaMath.h" - "cuda/Bitmaps.h" - "cuda/CudaCompressDXT.h" - "cuda/CudaCompressDXT.cpp" -) +add_subdirectory(squish) -# XXX: add "tests" and "tools" folders? +option(NVTT_SHARED "Build nvtt as shared library" OFF) +option(NVTT_BUILD_TEST_EXECUTABLES "Build nvtt test executables" OFF) +option(NVTT_BUILD_UI_TOOLS "Build nvtt UI tools" OFF) -if (CUDA_FOUND) - WRAP_CUDA(CUDA_SRCS cuda/CompressKernel.cu) - list(APPEND SRC_FILES ${CUDA_SRCS}) +if (NVTT_SHARED) + add_library(nvtt SHARED) + + target_compile_definitions(nvtt + PRIVATE + NVTT_SHARED + ) +else() + add_library(nvtt STATIC) endif() -group_sources(SRC_FILES) +target_sources(nvtt PRIVATE + nvtt.h + nvtt.cpp + Compressor.h + Compressor.cpp + nvtt_wrapper.h + nvtt_wrapper.cpp + CompressDXT.h + CompressDXT.cpp + CompressRGB.h + CompressRGB.cpp + QuickCompressDXT.h + QuickCompressDXT.cpp + OptimalCompressDXT.h + OptimalCompressDXT.cpp + SingleColorLookup.h + CompressionOptions.h + CompressionOptions.cpp + InputOptions.h + InputOptions.cpp + OutputOptions.h + OutputOptions.cpp + cuda/CudaUtils.h + cuda/CudaUtils.cpp + cuda/CudaMath.h + cuda/Bitmaps.h + cuda/CudaCompressDXT.h + cuda/CudaCompressDXT.cpp +) -if (NVTT_SHARED) - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) -else() - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) +if (CUDA_FOUND) + wrap_cuda(CUDA_SRCS cuda/CompressKernel.cu) + list(APPEND SRC_FILES ${CUDA_SRCS}) endif() -target_include_directories(${PROJECT_NAME} +target_include_directories(nvtt PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/Externals/NVTT/src - ${CMAKE_SOURCE_DIR}/Externals/NVTT/include $<$:${CUDA_INCLUDE_PATH}> ) -target_link_libraries(${PROJECT_NAME} - PRIVATE +target_link_libraries(nvtt + PUBLIC nvcore nvmath nvimage + PRIVATE squish $<$:${CUDA_LIBRARIES}> ) -target_compile_definitions(${PROJECT_NAME} +# TODO use configure_file for nvconfig.h + +target_compile_definitions(nvtt PRIVATE - -DNVTT_EXPORTS - $<$:-DNVTT_SHARED=1> - $<$:-DHAVE_CUDA> + NVTT_EXPORTS + HAVE_SIGNAL_H + HAVE_EXECINFO_H + $<$:HAVE_CUDA> +) + +set_target_properties(nvtt PROPERTIES + UNITY_BUILD OFF ) -install(TARGETS ${PROJECT_NAME} LIBRARY +install(TARGETS nvtt LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) -install(FILES "nvtt.h" DESTINATION "include/nvtt") +install(FILES nvtt.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nvtt") if (NVTT_TEST_EXECUTABLES) add_executable(nvcompress tools/compress.cpp tools/cmdline.h) - target_link_libraries(nvcompress nvcore nvmath nvimage nvtt) + target_link_libraries(nvcompress nvtt) add_executable(nvdecompress tools/decompress.cpp tools/cmdline.h) - target_link_libraries(nvdecompress nvcore nvmath nvimage) + target_link_libraries(nvdecompress nvmath nvimage) add_executable(nvddsinfo tools/ddsinfo.cpp tools/cmdline.h) - target_link_libraries(nvddsinfo nvcore nvmath nvimage) + target_link_libraries(nvddsinfo nvmath nvimage) add_executable(nvimgdiff tools/imgdiff.cpp tools/cmdline.h) - target_link_libraries(nvimgdiff nvcore nvmath nvimage) + target_link_libraries(nvimgdiff nvmath nvimage) add_executable(nvassemble tools/assemble.cpp tools/cmdline.h) - target_link_libraries(nvassemble nvcore nvmath nvimage) + target_link_libraries(nvassemble nvmath nvimage) add_executable(filtertest tests/filtertest.cpp tools/cmdline.h) - target_link_libraries(filtertest nvcore nvmath nvimage) + target_link_libraries(filtertest nvmath nvimage) add_executable(nvzoom tools/resize.cpp tools/cmdline.h) - target_link_libraries(nvzoom nvcore nvmath nvimage) + target_link_libraries(nvzoom nvmath nvimage) install(TARGETS nvcompress nvdecompress nvddsinfo nvimgdiff nvassemble nvzoom - DESTINATION ${CMAKE_INSTALL_LIBDIR} # XXX: change LIBDIR to BINDIR? + DESTINATION "${CMAKE_INSTALL_BINDIR}" ) endif() -# UI tools -# XXX: move to Qt5 -if (QT4_FOUND AND NOT MSVC) - set(QT_USE_QTOPENGL TRUE) - - set(SRC_FILES - "tools/main.cpp" - "tools/configdialog.h" - "tools/configdialog.cpp" - ) - - group_sources(SRC_FILES) - - add_executable(nvcompressui MACOSX_BUNDLE ${SRC_FILES} ${UICS} ${MOCS}) - - target_include_directories(${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} # XXX: why? - ${QT_INCLUDE_DIR} # XXX: check if variable is correct - ) - - target_link_libraries(nvcompressui - PRIVATE - nvtt - ${QT_QTCORE_LIBRARY} # XXX: check if variable is correct - ${QT_QTGUI_LIBRARY} # XXX: check if variable is correct - ${QT_QTOPENGL_LIBRARY} # XXX: check if variable is correct - ) - - QT4_WRAP_UI(UICS tools/configdialog.ui) - QT4_WRAP_CPP(MOCS tools/configdialog.h) - #QT4_ADD_RESOURCES(RCCS tools/configdialog.rc) +if (NVTT_BUILD_UI_TOOLS) + find_package(Qt5 COMPONENTS Core Widgets OpenGL) + + if (Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5OpenGL_FOUND) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTOUIC ON) + + add_executable(nvcompressui) + + target_sources(nvcompressui PRIVATE + tools/main.cpp + tools/configdialog.h + tools/configdialog.cpp + tools/configdialog.ui + ) + + target_link_libraries(nvcompressui + PRIVATE + nvtt + Qt5::Core + Qt5::Widgets + Qt5::OpenGL + ) + endif() endif() diff --git a/Externals/NVTT/src/nvtt/squish/CMakeLists.txt b/Externals/NVTT/src/nvtt/squish/CMakeLists.txt index 020fb49d88b..de8dc7194ce 100644 --- a/Externals/NVTT/src/nvtt/squish/CMakeLists.txt +++ b/Externals/NVTT/src/nvtt/squish/CMakeLists.txt @@ -1,34 +1,31 @@ PROJECT(squish) -set(SRC_FILES - "fastclusterfit.cpp" - "fastclusterfit.h" - "weightedclusterfit.cpp" - "weightedclusterfit.h" - "colourblock.cpp" - "colourblock.h" - "colourfit.cpp" - "colourfit.h" - "colourset.cpp" - "colourset.h" - "config.h" - "maths.cpp" - "maths.h" - "simd.h" - "simd_sse.h" - "simd_ve.h" -) - -group_sources(SRC_FILES) +add_library(squish STATIC) -add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) +target_sources(squish PRIVATE + fastclusterfit.cpp + fastclusterfit.h + weightedclusterfit.cpp + weightedclusterfit.h + colourblock.cpp + colourblock.h + colourfit.cpp + colourfit.h + colourset.cpp + colourset.h + config.h + maths.cpp + maths.h + simd.h + simd_sse.h + simd_ve.h +) -target_include_directories(${PROJECT_NAME} +target_include_directories(squish PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) -target_compile_definitions(${PROJECT_NAME} - PRIVATE - $<$:-fPIC> +set_property(TARGET squish PROPERTY + POSITION_INDEPENDENT_CODE ON ) diff --git a/Externals/NVTT/src/nvtt/squish/colourblock.cpp b/Externals/NVTT/src/nvtt/squish/colourblock.cpp index c0a022550a1..c2da6e82856 100644 --- a/Externals/NVTT/src/nvtt/squish/colourblock.cpp +++ b/Externals/NVTT/src/nvtt/squish/colourblock.cpp @@ -53,7 +53,7 @@ static int FloatTo565( Vec3::Arg colour ) return ( r << 11 ) | ( g << 5 ) | b; } -static void WriteColourBlock( int a, int b, u8* indices, void* block ) +void WriteColourBlock( int a, int b, u8* indices, void* block ) { // get the block as bytes u8* bytes = ( u8* )block; diff --git a/Externals/NVTT/src/nvtt/tools/configdialog.h b/Externals/NVTT/src/nvtt/tools/configdialog.h index 3c44073ca52..46264ca2172 100644 --- a/Externals/NVTT/src/nvtt/tools/configdialog.h +++ b/Externals/NVTT/src/nvtt/tools/configdialog.h @@ -24,7 +24,7 @@ #ifndef CONFIGDIALOG_H #define CONFIGDIALOG_H -#include +#include #include "ui_configdialog.h" diff --git a/Externals/NVTT/src/nvtt/tools/main.cpp b/Externals/NVTT/src/nvtt/tools/main.cpp index 48b95326fbe..4b5bc07e3b3 100644 --- a/Externals/NVTT/src/nvtt/tools/main.cpp +++ b/Externals/NVTT/src/nvtt/tools/main.cpp @@ -21,7 +21,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include +#include #include "configdialog.h" int main(int argc, char *argv[]) diff --git a/Externals/OPCODE/CMakeLists.txt b/Externals/OPCODE/CMakeLists.txt index 360996e4219..60656aa9f3c 100644 --- a/Externals/OPCODE/CMakeLists.txt +++ b/Externals/OPCODE/CMakeLists.txt @@ -1,111 +1,108 @@ -project(xrOPCODE) - -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) - -set(SRC_FILES - "OPC_AABBCollider.cpp" - "OPC_AABBCollider.h" - "OPC_AABB.cpp" - "OPC_AABB.h" - "OPC_AABBTree.cpp" - "OPC_AABBTree.h" - "OPC_BoundingSphere.h" - "OPC_BoxBoxOverlap.h" - "OPC_BVTCache.h" - "OPC_Collider.cpp" - "OPC_Collider.h" - "OPC_Common.cpp" - "OPC_Common.h" - "OPC_Container.cpp" - "OPC_Container.h" - "OPC_FPU.h" - "OPC_Matrix3x3.cpp" - "OPC_Matrix3x3.h" - "OPC_Matrix4x4.cpp" - "OPC_Matrix4x4.h" - "OPC_MemoryMacros.h" - "OPC_Model.cpp" - "OPC_Model.h" - "OPC_OBBCollider.cpp" - "OPC_OBBCollider.h" - "OPC_OBB.cpp" - "OPC_OBB.h" - "Opcode.cpp" - "Opcode.h" - "OPC_OptimizedTree.cpp" - "OPC_OptimizedTree.h" - "OPC_Plane.cpp" - "OPC_Plane.h" - "OPC_PlanesAABBOverlap.h" - "OPC_PlanesCollider.cpp" - "OPC_PlanesCollider.h" - "OPC_PlanesTriOverlap.h" - "OPC_Point.cpp" - "OPC_Point.h" - "OPC_Preprocessor.h" - "OPC_RayAABBOverlap.h" - "OPC_RayCollider.cpp" - "OPC_RayCollider.h" - "OPC_Ray.cpp" - "OPC_Ray.h" - "OPC_RayTriOverlap.h" - "OPC_Settings.h" - "OPC_SphereAABBOverlap.h" - "OPC_SphereCollider.cpp" - "OPC_SphereCollider.h" - "OPC_SphereTriOverlap.h" - "OPC_TreeBuilders.cpp" - "OPC_TreeBuilders.h" - "OPC_TreeCollider.cpp" - "OPC_TreeCollider.h" - "OPC_Triangle.cpp" - "OPC_Triangle.h" - "OPC_TriBoxOverlap.h" - "OPC_TriTriOverlap.h" - "OPC_Types.h" - "OPC_VolumeCollider.cpp" - "OPC_VolumeCollider.h" - "pch.cpp" - "pch.hpp" -) - -group_sources(SRC_FILES) - if (STATIC_BUILD) - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(xrOPCODE STATIC) + + target_compile_definitions(xrOPCODE + PRIVATE + OPCODE_STATIC + ) else() - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(xrOPCODE SHARED) endif() -target_include_directories(${PROJECT_NAME} +target_sources(xrOPCODE PRIVATE + OPC_AABBCollider.cpp + OPC_AABBCollider.h + OPC_AABB.cpp + OPC_AABB.h + OPC_AABBTree.cpp + OPC_AABBTree.h + OPC_BoundingSphere.h + OPC_BoxBoxOverlap.h + OPC_BVTCache.h + OPC_Collider.cpp + OPC_Collider.h + OPC_Common.cpp + OPC_Common.h + OPC_Container.cpp + OPC_Container.h + OPC_FPU.h + OPC_Matrix3x3.cpp + OPC_Matrix3x3.h + OPC_Matrix4x4.cpp + OPC_Matrix4x4.h + OPC_MemoryMacros.h + OPC_Model.cpp + OPC_Model.h + OPC_OBBCollider.cpp + OPC_OBBCollider.h + OPC_OBB.cpp + OPC_OBB.h + Opcode.cpp + Opcode.h + OPC_OptimizedTree.cpp + OPC_OptimizedTree.h + OPC_Plane.cpp + OPC_Plane.h + OPC_PlanesAABBOverlap.h + OPC_PlanesCollider.cpp + OPC_PlanesCollider.h + OPC_PlanesTriOverlap.h + OPC_Point.cpp + OPC_Point.h + OPC_Preprocessor.h + OPC_RayAABBOverlap.h + OPC_RayCollider.cpp + OPC_RayCollider.h + OPC_Ray.cpp + OPC_Ray.h + OPC_RayTriOverlap.h + OPC_Settings.h + OPC_SphereAABBOverlap.h + OPC_SphereCollider.cpp + OPC_SphereCollider.h + OPC_SphereTriOverlap.h + OPC_TreeBuilders.cpp + OPC_TreeBuilders.h + OPC_TreeCollider.cpp + OPC_TreeCollider.h + OPC_Triangle.cpp + OPC_Triangle.h + OPC_TriBoxOverlap.h + OPC_TriTriOverlap.h + OPC_Types.h + OPC_VolumeCollider.cpp + OPC_VolumeCollider.h + pch.cpp + pch.hpp +) + +target_include_directories(xrOPCODE PRIVATE - ${CMAKE_SOURCE_DIR}/src + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrOPCODE PRIVATE xrCore ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrOPCODE PRIVATE - -DOPCODE_EXPORTS - $<$:OPCODE_STATIC> + OPCODE_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrOPCODE PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrOPCODE PRIVATE - "pch.hpp" + pch.hpp ) if (NOT STATIC_BUILD) - install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + install(TARGETS xrOPCODE LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) endif() diff --git a/Externals/cximage/CMakeLists.txt b/Externals/cximage/CMakeLists.txt index 86b6ee56d51..5d60d8345bc 100644 --- a/Externals/cximage/CMakeLists.txt +++ b/Externals/cximage/CMakeLists.txt @@ -1,62 +1,52 @@ -cmake_minimum_required(VERSION 3.10) - -project(cximage) - -set(CMAKE_CXX_STANDARD 17) - -set(SRC_FILES - "xfile.h" - "ximacfg.cpp" - "ximacfg.h" - "ximadef.h" - "ximaenc.cpp" - "ximaexif.cpp" - "ximage.cpp" - "ximage.h" - "ximainfo.cpp" - "ximaint.cpp" - "ximaiter.h" - "ximajpg.cpp" - "ximajpg.h" - "ximalpha.cpp" - "ximalyr.cpp" - "ximapal.cpp" - "ximasel.cpp" - "ximath.cpp" - "ximath.h" - "xiofile.h" - "xiofile.cpp" - "xmemfile.cpp" - "xmemfile.h" +add_library(cximage STATIC) + +target_sources(cximage PRIVATE + xfile.h + ximacfg.cpp + ximacfg.h + ximadef.h + ximaenc.cpp + ximaexif.cpp + ximage.cpp + ximage.h + ximainfo.cpp + ximaint.cpp + ximaiter.h + ximajpg.cpp + ximajpg.h + ximalpha.cpp + ximalyr.cpp + ximapal.cpp + ximasel.cpp + ximath.cpp + ximath.h + xiofile.h + xiofile.cpp + xmemfile.cpp + xmemfile.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(cximage PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - $<$:${JPEG_INCLUDE_DIRS}> + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(cximage PRIVATE - $<$:${JPEG_LIBRARIES}> + $<$:JPEG::JPEG> ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(cximage PRIVATE - -DCXIMAGE_BUILD + CXIMAGE_BUILD ) # XXX: Clang-9 internal error in function GetPixelColorInterpolated during optimization if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION MATCHES "9.0.0" OR CMAKE_CXX_COMPILER_VERSION MATCHES "10.0.0")) - set_property(SOURCE "ximaint.cpp" PROPERTY SKIP_UNITY_BUILD_INCLUSION TRUE) + set_property(SOURCE ximaint.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION TRUE) endif() -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(cximage PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON ) diff --git a/Externals/imgui-proj/CMakeLists.txt b/Externals/imgui-proj/CMakeLists.txt index ee951d6a3f0..52c3c993ca0 100644 --- a/Externals/imgui-proj/CMakeLists.txt +++ b/Externals/imgui-proj/CMakeLists.txt @@ -1 +1,39 @@ -include(imgui.cmake) +add_library(xrImGui STATIC) + +set(IMGUI_DIR "${CMAKE_SOURCE_DIR}/Externals/imgui") + +target_sources(xrImGui PRIVATE + "${IMGUI_DIR}/imconfig.h" + "${IMGUI_DIR}/imgui.cpp" + "${IMGUI_DIR}/imgui.h" + "${IMGUI_DIR}/imgui_demo.cpp" + "${IMGUI_DIR}/imgui_draw.cpp" + "${IMGUI_DIR}/imgui_tables.cpp" + "${IMGUI_DIR}/imgui_widgets.cpp" + "${IMGUI_DIR}/imgui_internal.h" + "${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp" + "${IMGUI_DIR}/backends/imgui_impl_opengl3.h" + "${IMGUI_DIR}/imstb_rectpack.h" + "${IMGUI_DIR}/imstb_textedit.h" + "${IMGUI_DIR}/imstb_truetype.h" +) + +target_include_directories(xrImGui + PUBLIC + "${IMGUI_DIR}" +) + +target_link_libraries(xrImGui + PRIVATE + dl +) + +target_compile_definitions(xrImGui + PRIVATE + IMGUI_EXPORTS +) + +set_target_properties(xrImGui PROPERTIES + PREFIX "" + POSITION_INDEPENDENT_CODE ON +) diff --git a/Externals/imgui-proj/imgui.cmake b/Externals/imgui-proj/imgui.cmake index 4098a51e430..e69de29bb2d 100644 --- a/Externals/imgui-proj/imgui.cmake +++ b/Externals/imgui-proj/imgui.cmake @@ -1,41 +0,0 @@ -project(xrImGui) - -set(IMGUI_DIR ${CMAKE_SOURCE_DIR}/Externals/imgui) - -set(KERNEL_SRC - "${IMGUI_DIR}/imconfig.h" - "${IMGUI_DIR}/imgui.cpp" - "${IMGUI_DIR}/imgui.h" - "${IMGUI_DIR}/imgui_demo.cpp" - "${IMGUI_DIR}/imgui_draw.cpp" - "${IMGUI_DIR}/imgui_tables.cpp" - "${IMGUI_DIR}/imgui_widgets.cpp" - "${IMGUI_DIR}/imgui_internal.h" - "${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp" - "${IMGUI_DIR}/backends/imgui_impl_opengl3.h" - "${IMGUI_DIR}/imstb_rectpack.h" - "${IMGUI_DIR}/imstb_textedit.h" - "${IMGUI_DIR}/imstb_truetype.h" -) - -add_library(${PROJECT_NAME} STATIC ${KERNEL_SRC}) - -target_include_directories(${PROJECT_NAME} - PUBLIC - ${IMGUI_DIR} -) - -target_link_libraries(${PROJECT_NAME} - PRIVATE - dl -) - -target_compile_definitions(${PROJECT_NAME} - PRIVATE - -DIMGUI_EXPORTS -) - -set_target_properties(${PROJECT_NAME} PROPERTIES - PREFIX "" - POSITION_INDEPENDENT_CODE ON -) diff --git a/Externals/luabind b/Externals/luabind index f97166e3862..c90385df573 160000 --- a/Externals/luabind +++ b/Externals/luabind @@ -1 +1 @@ -Subproject commit f97166e38629b2d07de557d1dec7f0238510b775 +Subproject commit c90385df57349171506463cde3632c2f64991bd5 diff --git a/Externals/ode/CMakeLists.txt b/Externals/ode/CMakeLists.txt index fc4acfddc5a..f6fd21db86f 100644 --- a/Externals/ode/CMakeLists.txt +++ b/Externals/ode/CMakeLists.txt @@ -1,114 +1,121 @@ -project(xrODE) - -set(SRC_FILES - "ode/src/array.cpp" - "ode/src/array.h" - "ode/src/Bounder33.cpp" - "ode/src/Bounder33.h" - "ode/src/collision_kernel.cpp" - "ode/src/collision_kernel.h" - "ode/src/collision_quadtreespace.cpp" - "ode/src/collision_space.cpp" - "ode/src/collision_space_internal.h" - "ode/src/collision_std.cpp" - "ode/src/collision_std.h" - "ode/src/collision_transform.cpp" - "ode/src/collision_transform.h" - "ode/src/collision_trimesh_internal.h" - "ode/src/collision_util.cpp" - "ode/src/collision_util.h" - "ode/src/error.cpp" - "ode/src/export-dif.cpp" - "ode/src/fastdot.c" - "ode/src/fastldlt.c" - "ode/src/fastlsolve.c" - "ode/src/fastltsolve.c" - "ode/src/geom_internal.h" - "ode/src/joint.cpp" - "ode/src/joint.h" - "ode/src/Lcp33.h" - "ode/src/lcp.cpp" - "ode/src/lcp.h" - "ode/src/mass.cpp" - "ode/src/mat.cpp" - "ode/src/mat.h" - "ode/src/matrix.cpp" - "ode/src/memory.cpp" - "ode/src/misc.cpp" - "ode/src/objects.h" - "ode/src/obstack.cpp" - "ode/src/obstack.h" - "ode/src/ode.cpp" - "ode/src/odemath.cpp" - "ode/src/quickstep.cpp" - "ode/src/quickstep.h" - "ode/src/rotation.cpp" - "ode/src/stack.h" - "ode/src/step.cpp" - "ode/src/stepfast.cpp" - "ode/src/step.h" - "ode/src/StepJointInternal.cpp" - "ode/src/StepJointInternal.h" - "ode/src/testing.cpp" - "ode/src/testing.h" - "ode/src/timer.cpp" - "ode/src/util.cpp" - "ode/src/util.h" - "include/ode/collision.h" - "include/ode/collision_space.h" - "include/ode/collision_trimesh.h" - "include/ode/common.h" - "include/ode/compatibility.h" - "include/ode/config.h" - "include/ode/contact.h" - "include/ode/error.h" - "include/ode/export-dif.h" - "include/ode/geom.h" - "include/ode/mass.h" - "include/ode/matrix.h" - "include/ode/memory.h" - "include/ode/misc.h" - "include/ode/objects.h" - "include/ode/odecpp_collision.h" - "include/ode/odecpp.h" - "include/ode/ode.h" - "include/ode/odemath.h" - "include/ode/rotation.h" - "include/ode/space.h" - "include/ode/timer.h" - "contrib/msvc7/ode_default/de_padf_integration.cpp" - "contrib/msvc7/ode_default/de_padf_integration.h" -) - -group_sources(SRC_FILES) - if (STATIC_BUILD) - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(xrODE STATIC) else() - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(xrODE SHARED) endif() -target_include_directories(${PROJECT_NAME} +target_sources(xrODE PRIVATE + ode/src/array.cpp + ode/src/array.h + ode/src/Bounder33.cpp + ode/src/Bounder33.h + ode/src/collision_kernel.cpp + ode/src/collision_kernel.h + ode/src/collision_quadtreespace.cpp + ode/src/collision_space.cpp + ode/src/collision_space_internal.h + ode/src/collision_std.cpp + ode/src/collision_std.h + ode/src/collision_transform.cpp + ode/src/collision_transform.h + ode/src/collision_trimesh_internal.h + ode/src/collision_util.cpp + ode/src/collision_util.h + ode/src/error.cpp + ode/src/export-dif.cpp + ode/src/fastdot.c + ode/src/fastldlt.c + ode/src/fastlsolve.c + ode/src/fastltsolve.c + ode/src/geom_internal.h + ode/src/joint.cpp + ode/src/joint.h + ode/src/Lcp33.h + ode/src/lcp.cpp + ode/src/lcp.h + ode/src/mass.cpp + ode/src/mat.cpp + ode/src/mat.h + ode/src/matrix.cpp + ode/src/memory.cpp + ode/src/misc.cpp + ode/src/objects.h + ode/src/obstack.cpp + ode/src/obstack.h + ode/src/ode.cpp + ode/src/odemath.cpp + ode/src/quickstep.cpp + ode/src/quickstep.h + ode/src/rotation.cpp + ode/src/stack.h + ode/src/step.cpp + ode/src/stepfast.cpp + ode/src/step.h + ode/src/StepJointInternal.cpp + ode/src/StepJointInternal.h + ode/src/testing.cpp + ode/src/testing.h + ode/src/timer.cpp + ode/src/util.cpp + ode/src/util.h + include/ode/collision.h + include/ode/collision_space.h + include/ode/collision_trimesh.h + include/ode/common.h + include/ode/compatibility.h + include/ode/config.h + include/ode/contact.h + include/ode/error.h + include/ode/export-dif.h + include/ode/geom.h + include/ode/mass.h + include/ode/matrix.h + include/ode/memory.h + include/ode/misc.h + include/ode/objects.h + include/ode/odecpp_collision.h + include/ode/odecpp.h + include/ode/ode.h + include/ode/odemath.h + include/ode/rotation.h + include/ode/space.h + include/ode/timer.h + contrib/msvc7/ode_default/de_padf_integration.cpp + contrib/msvc7/ode_default/de_padf_integration.h +) + +target_include_directories(xrODE PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/include + "${CMAKE_CURRENT_SOURCE_DIR}/include" ) -target_compile_definitions(${PROJECT_NAME} +# TODO platform-specific defines +target_compile_definitions(xrODE + PUBLIC + dSINGLE + dNODEBUG + PRIVATE - -DLINUX - -D_cdecl= - -D__forceinline=inline + LINUX + __cdecl= + __forceinline=inline ) -set_target_properties(${PROJECT_NAME} PROPERTIES +if (MASTER_GOLD) + target_compile_definitions(xrODE + PUBLIC + dNODEBUG + ) +endif() + +set_target_properties(xrODE PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON UNITY_BUILD OFF ) if (NOT STATIC_BUILD) - install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + install(TARGETS xrODE LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) endif() diff --git a/Externals/xrLuaFix b/Externals/xrLuaFix index f4b37416713..67b77c92f49 160000 --- a/Externals/xrLuaFix +++ b/Externals/xrLuaFix @@ -1 +1 @@ -Subproject commit f4b374167139531f9120074f346effa282c53555 +Subproject commit 67b77c92f49c766c7c180cc39ffdb12799f395d7 diff --git a/Externals/zlib b/Externals/zlib index 643e17b7498..15c45adb76e 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 643e17b7498d12ab8d15565662880579692f769d +Subproject commit 15c45adb76e81a7e3a8a9e17b2a56eb90f668f44 diff --git a/cmake/FindLZO.cmake b/cmake/FindLZO.cmake index ed5d0ae8da8..c2659ffaa7b 100644 --- a/cmake/FindLZO.cmake +++ b/cmake/FindLZO.cmake @@ -24,25 +24,25 @@ #============================================================================= # If LZO_ROOT_DIR was defined in the environment, use it. -IF(NOT LZO_ROOT_DIR AND NOT $ENV{LZO_ROOT_DIR} STREQUAL "") - SET(LZO_ROOT_DIR $ENV{LZO_ROOT_DIR}) -ENDIF() +if(NOT LZO_ROOT_DIR AND NOT $ENV{LZO_ROOT_DIR} STREQUAL "") + set(LZO_ROOT_DIR $ENV{LZO_ROOT_DIR}) +endif() -SET(_lzo_SEARCH_DIRS +set(_lzo_SEARCH_DIRS ${LZO_ROOT_DIR} /usr/local /sw # Fink /opt/local # DarwinPorts ) -FIND_PATH(LZO_INCLUDE_DIR lzo/lzo1x.h +find_path(LZO_INCLUDE_DIR lzo/lzo1x.h HINTS ${_lzo_SEARCH_DIRS} PATH_SUFFIXES include ) -FIND_LIBRARY(LZO_LIBRARY +find_library(LZO_LIBRARY NAMES lzo2 HINTS @@ -53,16 +53,22 @@ FIND_LIBRARY(LZO_LIBRARY # handle the QUIETLY and REQUIRED arguments and set LZO_FOUND to TRUE if # all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO DEFAULT_MSG +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LZO DEFAULT_MSG LZO_LIBRARY LZO_INCLUDE_DIR) -IF(LZO_FOUND) - SET(LZO_LIBRARIES ${LZO_LIBRARY}) - SET(LZO_INCLUDE_DIRS ${LZO_INCLUDE_DIR}) -ENDIF(LZO_FOUND) +if(LZO_FOUND) + set(LZO_LIBRARIES ${LZO_LIBRARY}) + set(LZO_INCLUDE_DIRS ${LZO_INCLUDE_DIR}) -MARK_AS_ADVANCED( + add_library(LZO::LZO UNKNOWN IMPORTED) + set_target_properties(LZO::LZO PROPERTIES + IMPORTED_LOCATION "${LZO_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LZO_INCLUDE_DIR}" + ) +endif() + +mark_as_advanced( LZO_INCLUDE_DIR LZO_LIBRARY ) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 6dc938c01bc..e6f75c9057f 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -1,28 +1,30 @@ -# XXX: remove add_dir macro after Externals/GameSpy cmake refactoring -macro(add_dir DIRS) - foreach (dir ${DIRS}) - message("adding ${dir} to ${PROJECT_NAME}") - include_directories(${dir}) - file(GLOB ${dir}__INCLUDES_H ${dir} ${dir}/*.h) - file(GLOB ${dir}__INCLUDES_HPP ${dir} ${dir}/*.hpp) - list(APPEND ${PROJECT_NAME}__INCLUDES ${${dir}__INCLUDES_H} ${${dir}__INCLUDES_HPP}) - file(GLOB ${dir}__SOURCES_CPP ${dir} ${dir}/*.cpp ${dir}/*.cxx) - file(GLOB ${dir}__SOURCES_C ${dir} ${dir}/*.c) - list(APPEND ${PROJECT_NAME}__SOURCES ${${dir}__SOURCES_C} ${${dir}__SOURCES_CPP}) - endforeach() -endmacro() - -macro(group_sources SRC_FILES) - foreach(source IN LISTS SRC_FILES) - get_filename_component(source_path "${source}" PATH) - string(REPLACE "/" "\\" source_path_msvc "${source_path}") - source_group("${source_path_msvc}" FILES "${source}") - endforeach() -endmacro() - -# ------------------------------------------ +function(target_sources_grouped) + cmake_parse_arguments( + PARSED_ARGS + "" + "TARGET;NAME;SCOPE" + "FILES" + ${ARGN} + ) + + if(NOT PARSED_ARGS_TARGET) + message(FATAL_ERROR "You must provide a target name") + endif() + + if(NOT PARSED_ARGS_NAME) + message(FATAL_ERROR "You must provide a source group name") + endif() + + if(NOT PARSED_ARGS_SCOPE) + set(PARSED_ARGS_SCOPE PRIVATE) + endif() + + target_sources(${PARSED_ARGS_TARGET} ${PARSED_ARGS_SCOPE} ${PARSED_ARGS_FILES}) + + source_group(${PARSED_ARGS_NAME} FILES ${PARSED_ARGS_FILES}) +endfunction() + # Detect arch type ( x86 or x64 ) -# ------------------------------------------ if (CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH_TYPE x64) else (CMAKE_SIZEOF_VOID_P EQUAL 4) @@ -55,4 +57,67 @@ if (UNIX) endif() endif() -include(${PROJECT_SOURCE_DIR}/cmake/packaging.cmake) +function(set_git_info) + execute_process(COMMAND git rev-parse --verify HEAD + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_SHA1 + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "git commit: ${GIT_SHA1}") + + execute_process(COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_BRANCH + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "git branch: ${GIT_BRANCH}") +endfunction() + +include(packaging) + +function(xr_install tgt) + if (NOT MSVC) + install(TARGETS ${tgt} DESTINATION "." + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 + ) + else() + install(TARGETS ${tgt} + CONFIGURATIONS Debug + RUNTIME DESTINATION Debug/ + LIBRARY DESTINATION Debug/ + ) + install(FILES $ + CONFIGURATIONS Debug + DESTINATION Debug/ + ) + install(TARGETS ${tgt} + CONFIGURATIONS Release + RUNTIME DESTINATION Release/ + LIBRARY DESTINATION Release/ + ) + endif() +endfunction() + +# Use only if install defined outside target directory(like luabind, for example) +function(xr_install_file tgt) + if (NOT MSVC) + install(FILES $ DESTINATION "." + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 + ) + else() + install($ + CONFIGURATIONS Debug + RUNTIME DESTINATION Debug/ + ) + install(FILES $ + CONFIGURATIONS Debug + DESTINATION Debug/ + ) + install($ + CONFIGURATIONS Release + RUNTIME DESTINATION Release/ + ) + endif() +endfunction() diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index 982b9c53461..f15592488d4 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -1,25 +1,25 @@ project(xrResources) -install(DIRECTORY linux/bash-completion DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/) +install(DIRECTORY linux/bash-completion DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}) install(FILES linux/openxray_cop.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) install(FILES linux/openxray_cs.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) install(FILES linux/openxray_soc.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) -install(FILES media/icons/16x16/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps/) -install(FILES media/icons/32x32/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps/) -install(FILES media/icons/48x48/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps/) -install(FILES media/icons/64x64/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps/) -install(FILES media/icons/64x64/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/) +install(FILES media/icons/16x16/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps) +install(FILES media/icons/32x32/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps) +install(FILES media/icons/48x48/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps) +install(FILES media/icons/64x64/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps) +install(FILES media/icons/64x64/openxray_cop.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps) -install(FILES media/icons/16x16/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps/) -install(FILES media/icons/32x32/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps/) -install(FILES media/icons/48x48/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps/) -install(FILES media/icons/64x64/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps/) -install(FILES media/icons/64x64/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/) +install(FILES media/icons/16x16/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps) +install(FILES media/icons/32x32/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps) +install(FILES media/icons/48x48/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps) +install(FILES media/icons/64x64/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps) +install(FILES media/icons/64x64/openxray_cs.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps) -install(FILES media/icons/16x16/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps/) -install(FILES media/icons/32x32/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps/) -install(FILES media/icons/48x48/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps/) -install(FILES media/icons/64x64/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps/) -install(FILES media/icons/64x64/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/) +install(FILES media/icons/16x16/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps) +install(FILES media/icons/32x32/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps) +install(FILES media/icons/48x48/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps) +install(FILES media/icons/64x64/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps) +install(FILES media/icons/64x64/openxray_soc.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 576028099ad..ccece4ac50b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,5 +13,3 @@ add_subdirectory(xrParticles) add_subdirectory(xrPhysics) add_subdirectory(xrScriptEngine) add_subdirectory(xrSound) - -#add_subdirectory(xrMicroBenchmark) diff --git a/src/Common/Common.hpp b/src/Common/Common.hpp index 490fd574a6f..12f3cae38b0 100644 --- a/src/Common/Common.hpp +++ b/src/Common/Common.hpp @@ -1,6 +1,8 @@ #pragma once +#if _MSC_VER #include "submodule_check.hpp" +#endif #include "Common/Config.hpp" #include "Common/Platform.hpp" diff --git a/src/Layers/CMakeLists.txt b/src/Layers/CMakeLists.txt index 2ac726ff79a..b2a84b8aa36 100644 --- a/src/Layers/CMakeLists.txt +++ b/src/Layers/CMakeLists.txt @@ -1,6 +1,10 @@ add_subdirectory(xrAPI) -#add_subdirectory(xrRenderPC_R1) -#add_subdirectory(xrRenderPC_R2) -#add_subdirectory(xrRenderPC_R3) -#add_subdirectory(xrRenderPC_R4) + +# TODO test on Windows +if (WIN32) + add_subdirectory(xrRenderPC_R1) + add_subdirectory(xrRenderPC_R2) + add_subdirectory(xrRenderPC_R4) +endif() + add_subdirectory(xrRenderPC_GL) diff --git a/src/Layers/xrAPI/CMakeLists.txt b/src/Layers/xrAPI/CMakeLists.txt index 8b31e2ceac9..2d6408900a2 100644 --- a/src/Layers/xrAPI/CMakeLists.txt +++ b/src/Layers/xrAPI/CMakeLists.txt @@ -1,35 +1,30 @@ -project(xrAPI) +add_library(xrAPI SHARED) -set(KERNEL_SRC - "stdafx.h" - "stdafx.cpp" - "xrAPI.cpp" +target_sources(xrAPI PRIVATE + stdafx.h + stdafx.cpp + xrAPI.cpp ) -source_group("Kernel" FILES ${KERNEL_SRC}) - -add_library(${PROJECT_NAME} SHARED ${KERNEL_SRC}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrAPI PRIVATE - ${CMAKE_SOURCE_DIR}/src + "${CMAKE_SOURCE_DIR}/src" ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrAPI PRIVATE - -DXRAPI_EXPORTS + XRAPI_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrAPI PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrAPI PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrAPI LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/Layers/xrRenderPC_GL/CMakeLists.txt b/src/Layers/xrRenderPC_GL/CMakeLists.txt index 6475046b15a..7e6ca92ee11 100644 --- a/src/Layers/xrRenderPC_GL/CMakeLists.txt +++ b/src/Layers/xrRenderPC_GL/CMakeLists.txt @@ -1,409 +1,404 @@ -project(xrRender_GL) +add_library(xrRender_GL SHARED) -set(SRC_FILES - "gl_rendertarget_accum_direct.cpp" - "gl_rendertarget_build_textures.cpp" - "gl_rendertarget.h" - "gl_rendertarget_phase_combine.cpp" - "gl_rendertarget_phase_flip.cpp" - "gl_rendertarget_u_set_rt.cpp" - "r2_R_sun.cpp" - "r2_test_hw.cpp" - "rgl_shaders.cpp" - "stdafx.cpp" - "stdafx.h" - "xrRender_GL.cpp" - "../xrRender/Animation.cpp" - "../xrRender/Animation.h" - "../xrRender/AnimationKeyCalculate.h" - "../xrRender/Blender_CLSID.h" - "../xrRender/Blender.cpp" - "../xrRender/Blender.h" - "../xrRender/Blender_Recorder.cpp" - "../xrRender/Blender_Recorder.h" - "../xrRender/Blender_Recorder_R2.cpp" - "../xrRender/Blender_Recorder_StandartBinding.cpp" - "../xrRender/BufferUtils.h" - "../xrRender/ColorMapManager.cpp" - "../xrRender/ColorMapManager.h" - "../xrRender/D3DUtils.cpp" - "../xrRender/D3DUtils.h" - "../xrRender/D3DXRenderBase.cpp" - "../xrRender/D3DXRenderBase.h" - "../xrRender/DetailFormat.h" - "../xrRender/DetailManager_CACHE.cpp" - "../xrRender/DetailManager.cpp" - "../xrRender/DetailManager_Decompress.cpp" - "../xrRender/DetailManager_soft.cpp" - "../xrRender/DetailManager.h" - "../xrRender/DetailManager_VS.cpp" - "../xrRender/DetailModel.cpp" - "../xrRender/DetailModel.h" - "../xrRender/du_box.cpp" - "../xrRender/du_box.h" - "../xrRender/du_cone.cpp" - "../xrRender/du_cone.h" - "../xrRender/du_cylinder.cpp" - "../xrRender/du_cylinder.h" - "../xrRender/du_sphere.cpp" - "../xrRender/du_sphere.h" - "../xrRender/du_sphere_part.cpp" - "../xrRender/du_sphere_part.h" - "../xrRender/dxDebugRender.cpp" - "../xrRender/dxDebugRender.h" - "../xrRender/dxEnvironmentRender.cpp" - "../xrRender/dxEnvironmentRender.h" - "../xrRender/dxFontRender.cpp" - "../xrRender/dxFontRender.h" - "../xrRender/dxImGuiRender.cpp" - "../xrRender/dxImGuiRender.h" - "../xrRender/dxLensFlareRender.cpp" - "../xrRender/dxLensFlareRender.h" - "../xrRender/dxObjectSpaceRender.cpp" - "../xrRender/dxObjectSpaceRender.h" - "../xrRender/dxParticleCustom.cpp" - "../xrRender/dxParticleCustom.h" - "../xrRender/dxRainRender.cpp" - "../xrRender/dxRainRender.h" - "../xrRender/dxRenderFactory.cpp" - "../xrRender/dxRenderFactory.h" - "../xrRender/dxStatGraphRender.cpp" - "../xrRender/dxStatGraphRender.h" - "../xrRender/dxThunderboltDescRender.cpp" - "../xrRender/dxThunderboltDescRender.h" - "../xrRender/dxThunderboltRender.cpp" - "../xrRender/dxThunderboltRender.h" - "../xrRender/dxUIRender.cpp" - "../xrRender/dxUIRender.h" - "../xrRender/dxUISequenceVideoItem.cpp" - "../xrRender/dxUISequenceVideoItem.h" - "../xrRender/dxUIShader.cpp" - "../xrRender/dxUIShader.h" - "../xrRender/dxWallMarkArray.cpp" - "../xrRender/dxWallMarkArray.h" - "../xrRender/ETextureParams.cpp" - "../xrRender/ETextureParams.h" - "../xrRender/FBasicVisual.cpp" - "../xrRender/FBasicVisual.h" - "../xrRender/FHierrarhyVisual.cpp" - "../xrRender/FHierrarhyVisual.h" - "../xrRender/FLOD.cpp" - "../xrRender/FLOD.h" - "../xrRender/FProgressive.cpp" - "../xrRender/FProgressive.h" - "../xrRender/FSkinned.cpp" - "../xrRender/FSkinned.h" - "../xrRender/FSkinnedTypes.h" - "../xrRender/FTreeVisual.cpp" - "../xrRender/FTreeVisual.h" - "../xrRender/FVF.h" - "../xrRender/FVisual.cpp" - "../xrRender/FVisual.h" - "../xrRender/HOM.cpp" - "../xrRender/HOM.h" - "../xrRender/HWCaps.h" - "../xrRender/IRenderDetailModel.h" - "../xrRender/KinematicAnimatedDefs.h" - "../xrRender/KinematicsAddBoneTransform.hpp" - "../xrRender/light.cpp" - "../xrRender/Light_DB.cpp" - "../xrRender/Light_DB.h" - "../xrRender/light_gi.cpp" - "../xrRender/light_gi.h" - "../xrRender/light.h" - "../xrRender/Light_Package.cpp" - "../xrRender/Light_Package.h" - "../xrRender/Light_Render_Direct_ComputeXFS.cpp" - "../xrRender/Light_Render_Direct.cpp" - "../xrRender/Light_Render_Direct.h" - "../xrRender/light_smapvis.cpp" - "../xrRender/light_smapvis.h" - "../xrRender/LightTrack.cpp" - "../xrRender/LightTrack.h" - "../xrRender/light_vis.cpp" - "../xrRender/ModelPool.cpp" - "../xrRender/ModelPool.h" - "../xrRender/NvTriStrip.cpp" - "../xrRender/NvTriStrip.h" - "../xrRender/NvTriStripObjects.cpp" - "../xrRender/NvTriStripObjects.h" - "../xrRender/occRasterizer_core.cpp" - "../xrRender/occRasterizer.cpp" - "../xrRender/occRasterizer.h" - "../xrRender/ParticleEffect.cpp" - "../xrRender/ParticleEffectDef.cpp" - "../xrRender/ParticleEffectDef.h" - "../xrRender/ParticleEffect.h" - "../xrRender/ParticleGroup.cpp" - "../xrRender/ParticleGroup.h" - "../xrRender/PSLibrary.cpp" - "../xrRender/PSLibrary.h" - "../xrRender/QueryHelper.h" - "../xrRender/R_Backend.cpp" - "../xrRender/R_Backend_DBG.cpp" - "../xrRender/R_Backend.h" - "../xrRender/R_Backend_hemi.cpp" - "../xrRender/R_Backend_hemi.h" - "../xrRender/R_Backend_Runtime.cpp" - "../xrRender/R_Backend_Runtime.h" - "../xrRender/R_Backend_tree.cpp" - "../xrRender/R_Backend_tree.h" - "../xrRender/R_Backend_xform.cpp" - "../xrRender/R_Backend_xform.h" - "../xrRender/r_constants_cache.h" - "../xrRender/r_constants.cpp" - "../xrRender/r_constants.h" - "../xrRender/r__dsgraph_build.cpp" - "../xrRender/r__dsgraph_render.cpp" - "../xrRender/r__dsgraph_render_lods.cpp" - "../xrRender/r__dsgraph_types.h" - "../xrRender/R_DStreams.cpp" - "../xrRender/R_DStreams.h" - "../xrRender/ResourceManager.cpp" - "../xrRender/ResourceManager.h" - "../xrRender/ResourceManager_Loader.cpp" - "../xrRender/ResourceManager_Reset.cpp" - "../xrRender/ResourceManager_Resources.cpp" - #"../xrRender/ResourceManager_Scripting.cpp" - "../xrRender/r__occlusion.cpp" - "../xrRender/r__occlusion.h" - "../xrRender/r__pixel_calculator.cpp" - "../xrRender/r__pixel_calculator.h" - "../xrRender/r__screenshot.cpp" - "../xrRender/r__sector.cpp" - "../xrRender/r__sector.h" - "../xrRender/r__sector_detect.cpp" - "../xrRender/r__sector_traversal.cpp" - "../xrRender/r_sun_cascades.h" - "../xrRender/r__sync_point.cpp" - "../xrRender/r__sync_point.h" - "../xrRender/Shader.cpp" - "../xrRender/Shader.h" - "../xrRender/ShaderResourceTraits.h" - "../xrRender/SH_Atomic.cpp" - "../xrRender/SH_Atomic.h" - "../xrRender/SH_Constant.cpp" - "../xrRender/SH_Constant.h" - "../xrRender/SH_Matrix.cpp" - "../xrRender/SH_Matrix.h" - "../xrRender/SH_RT.h" - #"../xrRender/SH_Texture.cpp" - "../xrRender/SH_Texture.h" - "../xrRender/SkeletonAnimated.cpp" - "../xrRender/SkeletonAnimated.h" - "../xrRender/SkeletonCustom.cpp" - "../xrRender/SkeletonCustom.h" - "../xrRender/SkeletonRigid.cpp" - "../xrRender/SkeletonX.cpp" - "../xrRender/SkeletonX.h" - "../xrRender/SkeletonXSkinXW.h" - "../xrRender/SkeletonXSkinXW_CPP.cpp" - "../xrRender/SkeletonXSkinXW_SSE.cpp" - "../xrRender/SkeletonXVertRender.h" - #"../xrRender/stats_manager.cpp" - #"../xrRender/stats_manager.h" - #"../xrRender/Texture.cpp" - "../xrRender/TextureDescrManager.cpp" - "../xrRender/TextureDescrManager.h" - "../xrRender/tss_def.cpp" - "../xrRender/tss_def.h" - "../xrRender/tss.h" - "../xrRender/VertexCache.cpp" - "../xrRender/VertexCache.h" - "../xrRender/WallmarksEngine.cpp" - "../xrRender/WallmarksEngine.h" - "../xrRender/xr_effgamma.cpp" - "../xrRender/xr_effgamma.h" - "../xrRender/xrRender_console.cpp" - "../xrRender/xrRender_console.h" - "../xrRender/xrStripify.cpp" - "../xrRender/xrStripify.h" - "../xrRender/blenders/blender_bloom_build.cpp" - "../xrRender/blenders/blender_bloom_build.h" - #"../xrRender/blenders/Blender_Blur.cpp" - #"../xrRender/blenders/Blender_Blur.h" - #"../xrRender/blenders/Blender_BmmD.cpp" - "../xrRender/blenders/Blender_BmmD_deferred.cpp" - #"../xrRender/blenders/Blender_BmmD.h" - "../xrRender/blenders/blender_combine.cpp" - "../xrRender/blenders/blender_combine.h" - #"../xrRender/blenders/Blender_default_aref.cpp" - #"../xrRender/blenders/Blender_default_aref.h" - #"../xrRender/blenders/BlenderDefault.cpp" - #"../xrRender/blenders/BlenderDefault.h" - "../xrRender/blenders/blender_deffer_aref.cpp" - "../xrRender/blenders/blender_deffer_aref.h" - "../xrRender/blenders/blender_deffer_flat.cpp" - "../xrRender/blenders/blender_deffer_flat.h" - "../xrRender/blenders/blender_deffer_model.cpp" - "../xrRender/blenders/blender_deffer_model.h" - #"../xrRender/blenders/Blender_detail_still.cpp" - "../xrRender/blenders/Blender_detail_still_deferred.cpp" - #"../xrRender/blenders/Blender_detail_still.h" - "../xrRender/blenders/Blender_Editor_Selection.cpp" - "../xrRender/blenders/Blender_Editor_Selection.h" - "../xrRender/blenders/Blender_Editor_Wire.cpp" - "../xrRender/blenders/Blender_Editor_Wire.h" - #"../xrRender/blenders/Blender_LaEmB.cpp" - #"../xrRender/blenders/Blender_LaEmB.h" - "../xrRender/blenders/blender_light_direct_cascade.cpp" - "../xrRender/blenders/blender_light_direct_cascade.h" - "../xrRender/blenders/blender_light_direct.cpp" - "../xrRender/blenders/blender_light_direct.h" - "../xrRender/blenders/blender_light_mask.cpp" - "../xrRender/blenders/blender_light_mask.h" - "../xrRender/blenders/blender_light_occq.cpp" - "../xrRender/blenders/blender_light_occq.h" - "../xrRender/blenders/blender_light_point.cpp" - "../xrRender/blenders/blender_light_point.h" - "../xrRender/blenders/blender_light_reflected.cpp" - "../xrRender/blenders/blender_light_reflected.h" - "../xrRender/blenders/blender_light_spot.cpp" - "../xrRender/blenders/blender_light_spot.h" +target_sources(xrRender_GL PRIVATE + gl_rendertarget_accum_direct.cpp + gl_rendertarget_build_textures.cpp + gl_rendertarget.h + gl_rendertarget_phase_combine.cpp + gl_rendertarget_phase_flip.cpp + gl_rendertarget_u_set_rt.cpp + r2_R_sun.cpp + r2_test_hw.cpp + rgl_shaders.cpp + stdafx.cpp + stdafx.h + xrRender_GL.cpp + ../xrRender/Animation.cpp + ../xrRender/Animation.h + ../xrRender/AnimationKeyCalculate.h + ../xrRender/Blender_CLSID.h + ../xrRender/Blender.cpp + ../xrRender/Blender.h + ../xrRender/Blender_Recorder.cpp + ../xrRender/Blender_Recorder.h + ../xrRender/Blender_Recorder_R2.cpp + ../xrRender/Blender_Recorder_StandartBinding.cpp + ../xrRender/BufferUtils.h + ../xrRender/ColorMapManager.cpp + ../xrRender/ColorMapManager.h + ../xrRender/D3DUtils.cpp + ../xrRender/D3DUtils.h + ../xrRender/D3DXRenderBase.cpp + ../xrRender/D3DXRenderBase.h + ../xrRender/DetailFormat.h + ../xrRender/DetailManager_CACHE.cpp + ../xrRender/DetailManager.cpp + ../xrRender/DetailManager_Decompress.cpp + ../xrRender/DetailManager_soft.cpp + ../xrRender/DetailManager.h + ../xrRender/DetailManager_VS.cpp + ../xrRender/DetailModel.cpp + ../xrRender/DetailModel.h + ../xrRender/du_box.cpp + ../xrRender/du_box.h + ../xrRender/du_cone.cpp + ../xrRender/du_cone.h + ../xrRender/du_cylinder.cpp + ../xrRender/du_cylinder.h + ../xrRender/du_sphere.cpp + ../xrRender/du_sphere.h + ../xrRender/du_sphere_part.cpp + ../xrRender/du_sphere_part.h + ../xrRender/dxDebugRender.cpp + ../xrRender/dxDebugRender.h + ../xrRender/dxEnvironmentRender.cpp + ../xrRender/dxEnvironmentRender.h + ../xrRender/dxFontRender.cpp + ../xrRender/dxFontRender.h + ../xrRender/dxImGuiRender.cpp + ../xrRender/dxImGuiRender.h + ../xrRender/dxLensFlareRender.cpp + ../xrRender/dxLensFlareRender.h + ../xrRender/dxObjectSpaceRender.cpp + ../xrRender/dxObjectSpaceRender.h + ../xrRender/dxParticleCustom.cpp + ../xrRender/dxParticleCustom.h + ../xrRender/dxRainRender.cpp + ../xrRender/dxRainRender.h + ../xrRender/dxRenderFactory.cpp + ../xrRender/dxRenderFactory.h + ../xrRender/dxStatGraphRender.cpp + ../xrRender/dxStatGraphRender.h + ../xrRender/dxThunderboltDescRender.cpp + ../xrRender/dxThunderboltDescRender.h + ../xrRender/dxThunderboltRender.cpp + ../xrRender/dxThunderboltRender.h + ../xrRender/dxUIRender.cpp + ../xrRender/dxUIRender.h + ../xrRender/dxUISequenceVideoItem.cpp + ../xrRender/dxUISequenceVideoItem.h + ../xrRender/dxUIShader.cpp + ../xrRender/dxUIShader.h + ../xrRender/dxWallMarkArray.cpp + ../xrRender/dxWallMarkArray.h + ../xrRender/ETextureParams.cpp + ../xrRender/ETextureParams.h + ../xrRender/FBasicVisual.cpp + ../xrRender/FBasicVisual.h + ../xrRender/FHierrarhyVisual.cpp + ../xrRender/FHierrarhyVisual.h + ../xrRender/FLOD.cpp + ../xrRender/FLOD.h + ../xrRender/FProgressive.cpp + ../xrRender/FProgressive.h + ../xrRender/FSkinned.cpp + ../xrRender/FSkinned.h + ../xrRender/FSkinnedTypes.h + ../xrRender/FTreeVisual.cpp + ../xrRender/FTreeVisual.h + ../xrRender/FVF.h + ../xrRender/FVisual.cpp + ../xrRender/FVisual.h + ../xrRender/HOM.cpp + ../xrRender/HOM.h + ../xrRender/HWCaps.h + ../xrRender/IRenderDetailModel.h + ../xrRender/KinematicAnimatedDefs.h + ../xrRender/KinematicsAddBoneTransform.hpp + ../xrRender/light.cpp + ../xrRender/Light_DB.cpp + ../xrRender/Light_DB.h + ../xrRender/light_gi.cpp + ../xrRender/light_gi.h + ../xrRender/light.h + ../xrRender/Light_Package.cpp + ../xrRender/Light_Package.h + ../xrRender/Light_Render_Direct_ComputeXFS.cpp + ../xrRender/Light_Render_Direct.cpp + ../xrRender/Light_Render_Direct.h + ../xrRender/light_smapvis.cpp + ../xrRender/light_smapvis.h + ../xrRender/LightTrack.cpp + ../xrRender/LightTrack.h + ../xrRender/light_vis.cpp + ../xrRender/ModelPool.cpp + ../xrRender/ModelPool.h + ../xrRender/NvTriStrip.cpp + ../xrRender/NvTriStrip.h + ../xrRender/NvTriStripObjects.cpp + ../xrRender/NvTriStripObjects.h + ../xrRender/occRasterizer_core.cpp + ../xrRender/occRasterizer.cpp + ../xrRender/occRasterizer.h + ../xrRender/ParticleEffect.cpp + ../xrRender/ParticleEffectDef.cpp + ../xrRender/ParticleEffectDef.h + ../xrRender/ParticleEffect.h + ../xrRender/ParticleGroup.cpp + ../xrRender/ParticleGroup.h + ../xrRender/PSLibrary.cpp + ../xrRender/PSLibrary.h + ../xrRender/QueryHelper.h + ../xrRender/R_Backend.cpp + ../xrRender/R_Backend_DBG.cpp + ../xrRender/R_Backend.h + ../xrRender/R_Backend_hemi.cpp + ../xrRender/R_Backend_hemi.h + ../xrRender/R_Backend_Runtime.cpp + ../xrRender/R_Backend_Runtime.h + ../xrRender/R_Backend_tree.cpp + ../xrRender/R_Backend_tree.h + ../xrRender/R_Backend_xform.cpp + ../xrRender/R_Backend_xform.h + ../xrRender/r_constants_cache.h + ../xrRender/r_constants.cpp + ../xrRender/r_constants.h + ../xrRender/r__dsgraph_build.cpp + ../xrRender/r__dsgraph_render.cpp + ../xrRender/r__dsgraph_render_lods.cpp + ../xrRender/r__dsgraph_types.h + ../xrRender/R_DStreams.cpp + ../xrRender/R_DStreams.h + ../xrRender/ResourceManager.cpp + ../xrRender/ResourceManager.h + ../xrRender/ResourceManager_Loader.cpp + ../xrRender/ResourceManager_Reset.cpp + ../xrRender/ResourceManager_Resources.cpp + #../xrRender/ResourceManager_Scripting.cpp + ../xrRender/r__occlusion.cpp + ../xrRender/r__occlusion.h + ../xrRender/r__pixel_calculator.cpp + ../xrRender/r__pixel_calculator.h + ../xrRender/r__screenshot.cpp + ../xrRender/r__sector.cpp + ../xrRender/r__sector.h + ../xrRender/r__sector_detect.cpp + ../xrRender/r__sector_traversal.cpp + ../xrRender/r_sun_cascades.h + ../xrRender/r__sync_point.cpp + ../xrRender/r__sync_point.h + ../xrRender/Shader.cpp + ../xrRender/Shader.h + ../xrRender/ShaderResourceTraits.h + ../xrRender/SH_Atomic.cpp + ../xrRender/SH_Atomic.h + ../xrRender/SH_Constant.cpp + ../xrRender/SH_Constant.h + ../xrRender/SH_Matrix.cpp + ../xrRender/SH_Matrix.h + ../xrRender/SH_RT.h + #../xrRender/SH_Texture.cpp + ../xrRender/SH_Texture.h + ../xrRender/SkeletonAnimated.cpp + ../xrRender/SkeletonAnimated.h + ../xrRender/SkeletonCustom.cpp + ../xrRender/SkeletonCustom.h + ../xrRender/SkeletonRigid.cpp + ../xrRender/SkeletonX.cpp + ../xrRender/SkeletonX.h + ../xrRender/SkeletonXSkinXW.h + ../xrRender/SkeletonXSkinXW_CPP.cpp + ../xrRender/SkeletonXSkinXW_SSE.cpp + ../xrRender/SkeletonXVertRender.h + #../xrRender/stats_manager.cpp + #../xrRender/stats_manager.h + #../xrRender/Texture.cpp + ../xrRender/TextureDescrManager.cpp + ../xrRender/TextureDescrManager.h + ../xrRender/tss_def.cpp + ../xrRender/tss_def.h + ../xrRender/tss.h + ../xrRender/VertexCache.cpp + ../xrRender/VertexCache.h + ../xrRender/WallmarksEngine.cpp + ../xrRender/WallmarksEngine.h + ../xrRender/xr_effgamma.cpp + ../xrRender/xr_effgamma.h + ../xrRender/xrRender_console.cpp + ../xrRender/xrRender_console.h + ../xrRender/xrStripify.cpp + ../xrRender/xrStripify.h + ../xrRender/blenders/blender_bloom_build.cpp + ../xrRender/blenders/blender_bloom_build.h + #../xrRender/blenders/Blender_Blur.cpp + #../xrRender/blenders/Blender_Blur.h + #../xrRender/blenders/Blender_BmmD.cpp + ../xrRender/blenders/Blender_BmmD_deferred.cpp + #../xrRender/blenders/Blender_BmmD.h + ../xrRender/blenders/blender_combine.cpp + ../xrRender/blenders/blender_combine.h + #../xrRender/blenders/Blender_default_aref.cpp + #../xrRender/blenders/Blender_default_aref.h + #../xrRender/blenders/BlenderDefault.cpp + #../xrRender/blenders/BlenderDefault.h + ../xrRender/blenders/blender_deffer_aref.cpp + ../xrRender/blenders/blender_deffer_aref.h + ../xrRender/blenders/blender_deffer_flat.cpp + ../xrRender/blenders/blender_deffer_flat.h + ../xrRender/blenders/blender_deffer_model.cpp + ../xrRender/blenders/blender_deffer_model.h + #../xrRender/blenders/Blender_detail_still.cpp + ../xrRender/blenders/Blender_detail_still_deferred.cpp + #../xrRender/blenders/Blender_detail_still.h + ../xrRender/blenders/Blender_Editor_Selection.cpp + ../xrRender/blenders/Blender_Editor_Selection.h + ../xrRender/blenders/Blender_Editor_Wire.cpp + ../xrRender/blenders/Blender_Editor_Wire.h + #../xrRender/blenders/Blender_LaEmB.cpp + #../xrRender/blenders/Blender_LaEmB.h + ../xrRender/blenders/blender_light_direct_cascade.cpp + ../xrRender/blenders/blender_light_direct_cascade.h + ../xrRender/blenders/blender_light_direct.cpp + ../xrRender/blenders/blender_light_direct.h + ../xrRender/blenders/blender_light_mask.cpp + ../xrRender/blenders/blender_light_mask.h + ../xrRender/blenders/blender_light_occq.cpp + ../xrRender/blenders/blender_light_occq.h + ../xrRender/blenders/blender_light_point.cpp + ../xrRender/blenders/blender_light_point.h + ../xrRender/blenders/blender_light_reflected.cpp + ../xrRender/blenders/blender_light_reflected.h + ../xrRender/blenders/blender_light_spot.cpp + ../xrRender/blenders/blender_light_spot.h "../xrRender/blenders/Blender_Lm(EbB).cpp" "../xrRender/blenders/Blender_Lm(EbB).h" - "../xrRender/blenders/blender_luminance.cpp" - "../xrRender/blenders/blender_luminance.h" - #"../xrRender/blenders/Blender_Model.cpp" - #"../xrRender/blenders/Blender_Model_EbB.cpp" - "../xrRender/blenders/Blender_Model_EbB_deferred.cpp" - #"../xrRender/blenders/Blender_Model_EbB.h" - #"../xrRender/blenders/Blender_Model.h" - #"../xrRender/blenders/Blender_Particle.cpp" - "../xrRender/blenders/Blender_Particle_deferred.cpp" - #"../xrRender/blenders/Blender_Particle.h" - #"../xrRender/blenders/Blender_Screen_GRAY.cpp" - #"../xrRender/blenders/Blender_Screen_GRAY.h" - "../xrRender/blenders/Blender_Screen_SET.cpp" - "../xrRender/blenders/Blender_Screen_SET.h" - #"../xrRender/blenders/Blender_Shadow_World.cpp" - #"../xrRender/blenders/Blender_Shadow_World.h" - "../xrRender/blenders/blender_ssao.cpp" - "../xrRender/blenders/blender_ssao.h" - #"../xrRender/blenders/Blender_tree.cpp" - "../xrRender/blenders/Blender_tree_deferred.cpp" - #"../xrRender/blenders/Blender_tree.h" - #"../xrRender/blenders/Blender_Vertex_aref.cpp" - #"../xrRender/blenders/Blender_Vertex_aref.h" - #"../xrRender/blenders/Blender_Vertex.cpp" - #"../xrRender/blenders/Blender_Vertex.h" - #"../xrRender/blenders/dx11MinMaxSMBlender.cpp" - "../xrRender/blenders/dx11MinMaxSMBlender.h" - #"../xrRender/blenders/dx11MSAABlender.cpp" - "../xrRender/blenders/dx11MSAABlender.h" - #"../xrRender/blenders/dx11RainBlender.cpp" - "../xrRender/blenders/dx11RainBlender.h" - #"../xrRender/blenders/dx11HDAOCSBlender.cpp" - #"../xrRender/blenders/dx11HDAOCSBlender.h" - #"../xrRender/blenders/dx11MinMaxSMBlender.cpp" - #"../xrRender/blenders/dx11MinMaxSMBlender.h" - "../xrRender/blenders/glMinMaxSMBlender.cpp" - "../xrRender/blenders/glMSAABlender.cpp" - "../xrRender/blenders/glRainBlender.cpp" - "../xrRender/blenders/uber_deffer.cpp" - "../xrRender/blenders/uber_deffer.h" - "../xrRender_R2/r2.cpp" - "../xrRender_R2/r2.h" - "../xrRender_R2/r2_blenders.cpp" - "../xrRender_R2/r2_loader.cpp" - "../xrRender_R2/r2_R_calculate.cpp" - "../xrRender_R2/r2_R_lights.cpp" - "../xrRender_R2/r2_R_render.cpp" - "../xrRender_R2/r2_R_sun_support.h" - "../xrRender_R2/r2_rendertarget.cpp" - "../xrRender_R2/r2_rendertarget_accum_omnipart_geom.cpp" - "../xrRender_R2/r2_rendertarget_accum_point_geom.cpp" - "../xrRender_R2/r2_rendertarget_accum_reflected.cpp" - "../xrRender_R2/r2_rendertarget_accum_spot_geom.cpp" - "../xrRender_R2/r2_rendertarget_draw_volume.cpp" - "../xrRender_R2/r2_rendertarget_enable_scissor.cpp" - "../xrRender_R2/r2_rendertarget_phase_accumulator.cpp" - "../xrRender_R2/r2_rendertarget_phase_bloom.cpp" - "../xrRender_R2/r2_rendertarget_phase_luminance.cpp" - "../xrRender_R2/r2_rendertarget_phase_PP.cpp" - "../xrRender_R2/r2_rendertarget_phase_smap_S.cpp" - "../xrRender_R2/r2_rendertarget_wallmarks.h" - "../xrRender_R2/r2_types.h" - "../xrRender_R2/r3_R_rain.cpp" - "../xrRender_R2/r3_rendertarget_accum_point.cpp" - "../xrRender_R2/r3_rendertarget_accum_spot.cpp" - "../xrRender_R2/r3_rendertarget_create_minmaxSM.cpp" - "../xrRender_R2/r3_rendertarget_draw_rain.cpp" - "../xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp" - "../xrRender_R2/r3_rendertarget_phase_ssao.cpp" - "../xrRender_R2/r3_rendertarget_phase_smap_D.cpp" - "../xrRender_R2/r3_rendertarget_phase_occq.cpp" - "../xrRender_R2/r3_rendertarget_phase_scene.cpp" - "../xrRender_R2/render_phase_sun.cpp" - "../xrRender_R2/SMAP_Allocator.h" - "../xrRenderGL/Blender_Recorder_GL.cpp" - "../xrRenderGL/CommonTypes.h" - "../xrRenderGL/glBufferUtils.cpp" - "../xrRenderGL/glDetailManager_VS.cpp" - "../xrRenderGL/glHWCaps.cpp" - "../xrRenderGL/glHW.cpp" - "../xrRenderGL/glHW.h" - "../xrRenderGL/glR_Backend_Runtime.h" - "../xrRenderGL/glr_constants.cpp" - "../xrRenderGL/glr_constants_cache.h" - "../xrRenderGL/glr_screenshot.cpp" - "../xrRenderGL/glResourceManager_Resources.cpp" - "../xrRenderGL/glResourceManager_Scripting.cpp" - "../xrRenderGL/glSH_RT.cpp" - "../xrRenderGL/glSH_Texture.cpp" - "../xrRenderGL/glState.cpp" - "../xrRenderGL/glState.h" - "../xrRenderGL/glStateUtils.cpp" - "../xrRenderGL/glStateUtils.h" - "../xrRenderGL/glTexture.cpp" - "../xrRenderGL/glTextureUtils.cpp" - "../xrRenderGL/glTextureUtils.h" - "../../Include/xrRender/animation_blend.h" - "../../Include/xrRender/animation_motion.h" - "../../Include/xrRender/DebugRender.h" - "../../Include/xrRender/DebugShader.h" - "../../Include/xrRender/DrawUtils.h" - "../../Include/xrRender/EnvironmentRender.h" - "../../Include/xrRender/FactoryPtr.h" - "../../Include/xrRender/FontRender.h" - "../../Include/xrRender/KinematicsAnimated.h" - "../../Include/xrRender/Kinematics.h" - "../../Include/xrRender/LensFlareRender.h" - "../../Include/xrRender/ObjectSpaceRender.h" - "../../Include/xrRender/ParticleCustom.h" - "../../Include/xrRender/particles_systems_library_interface.hpp" - "../../Include/xrRender/RainRender.h" - "../../Include/xrRender/RenderDetailModel.h" - "../../Include/xrRender/RenderFactory.h" - "../../Include/xrRender/RenderVisual.h" - "../../Include/xrRender/StatGraphRender.h" - "../../Include/xrRender/ThunderboltDescRender.h" - "../../Include/xrRender/ThunderboltRender.h" - "../../Include/xrRender/UIRender.h" - "../../Include/xrRender/UISequenceVideoItem.h" - "../../Include/xrRender/UIShader.h" - "../../Include/xrRender/WallMarkArray.h" + ../xrRender/blenders/blender_luminance.cpp + ../xrRender/blenders/blender_luminance.h + #../xrRender/blenders/Blender_Model.cpp + #../xrRender/blenders/Blender_Model_EbB.cpp + ../xrRender/blenders/Blender_Model_EbB_deferred.cpp + #../xrRender/blenders/Blender_Model_EbB.h + #../xrRender/blenders/Blender_Model.h + #../xrRender/blenders/Blender_Particle.cpp + ../xrRender/blenders/Blender_Particle_deferred.cpp + #../xrRender/blenders/Blender_Particle.h + #../xrRender/blenders/Blender_Screen_GRAY.cpp + #../xrRender/blenders/Blender_Screen_GRAY.h + ../xrRender/blenders/Blender_Screen_SET.cpp + ../xrRender/blenders/Blender_Screen_SET.h + #../xrRender/blenders/Blender_Shadow_World.cpp + #../xrRender/blenders/Blender_Shadow_World.h + ../xrRender/blenders/blender_ssao.cpp + ../xrRender/blenders/blender_ssao.h + #../xrRender/blenders/Blender_tree.cpp + ../xrRender/blenders/Blender_tree_deferred.cpp + #../xrRender/blenders/Blender_tree.h + #../xrRender/blenders/Blender_Vertex_aref.cpp + #../xrRender/blenders/Blender_Vertex_aref.h + #../xrRender/blenders/Blender_Vertex.cpp + #../xrRender/blenders/Blender_Vertex.h + #../xrRender/blenders/dx11MinMaxSMBlender.cpp + ../xrRender/blenders/dx11MinMaxSMBlender.h + #../xrRender/blenders/dx11MSAABlender.cpp + ../xrRender/blenders/dx11MSAABlender.h + #../xrRender/blenders/dx11RainBlender.cpp + ../xrRender/blenders/dx11RainBlender.h + #../xrRender/blenders/dx11HDAOCSBlender.cpp + #../xrRender/blenders/dx11HDAOCSBlender.h + #../xrRender/blenders/dx11MinMaxSMBlender.cpp + #../xrRender/blenders/dx11MinMaxSMBlender.h + ../xrRender/blenders/glMinMaxSMBlender.cpp + ../xrRender/blenders/glMSAABlender.cpp + ../xrRender/blenders/glRainBlender.cpp + ../xrRender/blenders/uber_deffer.cpp + ../xrRender/blenders/uber_deffer.h + ../xrRender_R2/r2.cpp + ../xrRender_R2/r2.h + ../xrRender_R2/r2_blenders.cpp + ../xrRender_R2/r2_loader.cpp + ../xrRender_R2/r2_R_calculate.cpp + ../xrRender_R2/r2_R_lights.cpp + ../xrRender_R2/r2_R_render.cpp + ../xrRender_R2/r2_R_sun_support.h + ../xrRender_R2/r2_rendertarget.cpp + ../xrRender_R2/r2_rendertarget_accum_omnipart_geom.cpp + ../xrRender_R2/r2_rendertarget_accum_point_geom.cpp + ../xrRender_R2/r2_rendertarget_accum_reflected.cpp + ../xrRender_R2/r2_rendertarget_accum_spot_geom.cpp + ../xrRender_R2/r2_rendertarget_draw_volume.cpp + ../xrRender_R2/r2_rendertarget_enable_scissor.cpp + ../xrRender_R2/r2_rendertarget_phase_accumulator.cpp + ../xrRender_R2/r2_rendertarget_phase_bloom.cpp + ../xrRender_R2/r2_rendertarget_phase_luminance.cpp + ../xrRender_R2/r2_rendertarget_phase_PP.cpp + ../xrRender_R2/r2_rendertarget_phase_smap_S.cpp + ../xrRender_R2/r2_rendertarget_wallmarks.h + ../xrRender_R2/r2_types.h + ../xrRender_R2/r3_R_rain.cpp + ../xrRender_R2/r3_rendertarget_accum_point.cpp + ../xrRender_R2/r3_rendertarget_accum_spot.cpp + ../xrRender_R2/r3_rendertarget_create_minmaxSM.cpp + ../xrRender_R2/r3_rendertarget_draw_rain.cpp + ../xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp + ../xrRender_R2/r3_rendertarget_phase_ssao.cpp + ../xrRender_R2/r3_rendertarget_phase_smap_D.cpp + ../xrRender_R2/r3_rendertarget_phase_occq.cpp + ../xrRender_R2/r3_rendertarget_phase_scene.cpp + ../xrRender_R2/render_phase_sun.cpp + ../xrRender_R2/SMAP_Allocator.h + ../xrRenderGL/Blender_Recorder_GL.cpp + ../xrRenderGL/CommonTypes.h + ../xrRenderGL/glBufferUtils.cpp + ../xrRenderGL/glDetailManager_VS.cpp + ../xrRenderGL/glHWCaps.cpp + ../xrRenderGL/glHW.cpp + ../xrRenderGL/glHW.h + ../xrRenderGL/glR_Backend_Runtime.h + ../xrRenderGL/glr_constants.cpp + ../xrRenderGL/glr_constants_cache.h + ../xrRenderGL/glr_screenshot.cpp + ../xrRenderGL/glResourceManager_Resources.cpp + ../xrRenderGL/glResourceManager_Scripting.cpp + ../xrRenderGL/glSH_RT.cpp + ../xrRenderGL/glSH_Texture.cpp + ../xrRenderGL/glState.cpp + ../xrRenderGL/glState.h + ../xrRenderGL/glStateUtils.cpp + ../xrRenderGL/glStateUtils.h + ../xrRenderGL/glTexture.cpp + ../xrRenderGL/glTextureUtils.cpp + ../xrRenderGL/glTextureUtils.h + ../../Include/xrRender/animation_blend.h + ../../Include/xrRender/animation_motion.h + ../../Include/xrRender/DebugRender.h + ../../Include/xrRender/DebugShader.h + ../../Include/xrRender/DrawUtils.h + ../../Include/xrRender/EnvironmentRender.h + ../../Include/xrRender/FactoryPtr.h + ../../Include/xrRender/FontRender.h + ../../Include/xrRender/KinematicsAnimated.h + ../../Include/xrRender/Kinematics.h + ../../Include/xrRender/LensFlareRender.h + ../../Include/xrRender/ObjectSpaceRender.h + ../../Include/xrRender/ParticleCustom.h + ../../Include/xrRender/particles_systems_library_interface.hpp + ../../Include/xrRender/RainRender.h + ../../Include/xrRender/RenderDetailModel.h + ../../Include/xrRender/RenderFactory.h + ../../Include/xrRender/RenderVisual.h + ../../Include/xrRender/StatGraphRender.h + ../../Include/xrRender/ThunderboltDescRender.h + ../../Include/xrRender/ThunderboltRender.h + ../../Include/xrRender/UIRender.h + ../../Include/xrRender/UISequenceVideoItem.h + ../../Include/xrRender/UIShader.h + ../../Include/xrRender/WallMarkArray.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrRender_GL PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/src/Layers/xrRender - ${CMAKE_SOURCE_DIR}/src/Include/xrRender - ${CMAKE_SOURCE_DIR}/src/Layers/xrRender_R2 - ${CMAKE_SOURCE_DIR}/sdk/include/DirectXMesh - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/Externals/gli - ${CMAKE_SOURCE_DIR}/Externals/gli/external - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/src/Layers/xrRender" + "${CMAKE_SOURCE_DIR}/src/Include/xrRender" + "${CMAKE_SOURCE_DIR}/src/Layers/xrRender_R2" + "${CMAKE_SOURCE_DIR}/sdk/include/DirectXMesh" + "${CMAKE_SOURCE_DIR}/Externals" + "${CMAKE_SOURCE_DIR}/Externals/gli" + "${CMAKE_SOURCE_DIR}/Externals/gli/external" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrRender_GL PRIVATE xrAPI xrCDB @@ -411,28 +406,27 @@ target_link_libraries(${PROJECT_NAME} xrEngine xrParticles xrScriptEngine - xrLuabind xrImGui OpenGL::GL GLEW::GLEW ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrRender_GL PRIVATE - -DXRRENDER_GL_EXPORTS - -DUSE_OGL + XRRENDER_GL_EXPORTS + USE_OGL + PURE_DYNAMIC_CAST ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrRender_GL PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrRender_GL PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrRender_GL LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/Layers/xrRenderPC_R1/CMakeLists.txt b/src/Layers/xrRenderPC_R1/CMakeLists.txt index 28ceb224141..54800c07124 100644 --- a/src/Layers/xrRenderPC_R1/CMakeLists.txt +++ b/src/Layers/xrRenderPC_R1/CMakeLists.txt @@ -1,68 +1,59 @@ -project(xrRenderPC_R1) - -set(SRC_FILES - "FStaticRender_Blenders.cpp" - "FStaticRender.cpp" - "FStaticRender_DetectSector.cpp" - "FStaticRender.h" - "FStaticRender_Loader.cpp" - "FStaticRender_RenderTarget.cpp" - "FStaticRender_RenderTarget.h" - "FStaticRender_Shaders.cpp" - "FStaticRender_Types.h" - "GlowManager.cpp" - "GlowManager.h" - "LightPPA.cpp" - "LightPPA.h" - "LightProjector.cpp" - "LightProjector.h" - "LightShadows.cpp" - "LightShadows.h" - "stdafx.cpp" - "stdafx.h" - "xrRender_R1.cpp" +add_library(xrRenderPC_R1 SHARED) + +target_sources(xrRenderPC_R1 PRIVATE + FStaticRender_Blenders.cpp + FStaticRender.cpp + FStaticRender_DetectSector.cpp + FStaticRender.h + FStaticRender_Loader.cpp + FStaticRender_RenderTarget.cpp + FStaticRender_RenderTarget.h + FStaticRender_Shaders.cpp + FStaticRender_Types.h + GlowManager.cpp + GlowManager.h + LightPPA.cpp + LightPPA.h + LightProjector.cpp + LightProjector.h + LightShadows.cpp + LightShadows.h + stdafx.cpp + stdafx.h + xrRender_R1.cpp ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrRenderPC_R1 PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/sdk/include - ${SDL2_INCLUDE_DIRS} + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/sdk/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrRenderPC_R1 PRIVATE xrCore - xrLuabind xrCDB xrEngine xrParticles xrScriptEngine xrAPI xrMiscMath - ${SDL2_LIBRARIES} ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrRenderPC_R1 PRIVATE - -DXRRENDER_R1_EXPORTS + XRRENDER_R1_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrRenderPC_R1 PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrRenderPC_R1 PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrRenderPC_R1 LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/Layers/xrRenderPC_R2/CMakeLists.txt b/src/Layers/xrRenderPC_R2/CMakeLists.txt new file mode 100644 index 00000000000..b38400485b9 --- /dev/null +++ b/src/Layers/xrRenderPC_R2/CMakeLists.txt @@ -0,0 +1,56 @@ +add_library(xrRenderPC_R2 SHARED) + +target_sources(xrRenderPC_R2 PRIVATE + Light_Render_Direct_ComputeXFS.cpp + r2_rendertarget.h + r2_rendertarget_accum_direct.cpp + r2_rendertarget_accum_point.cpp + r2_rendertarget_accum_spot.cpp + r2_rendertarget_build_textures.cpp + r2_rendertarget_phase_combine.cpp + r2_rendertarget_phase_occq.cpp + r2_rendertarget_phase_scene.cpp + r2_rendertarget_phase_smap_D.cpp + r2_rendertarget_phase_ssao.cpp + r2_rendertarget_u_set_rt.cpp + r2_shaders.cpp + r2_test_hw.cpp + stdafx.cpp + stdafx.h + xrRender_R2.cpp +) + +target_include_directories(xrRenderPC_R2 + PRIVATE + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/sdk/include" +) + +target_link_libraries(xrRenderPC_R2 + PRIVATE + xrCore + xrCDB + xrEngine + xrParticles + xrScriptEngine + xrAPI + xrMiscMath +) + +target_compile_definitions(xrRenderPC_R2 + PRIVATE + XRRENDER_R2_EXPORTS +) + +set_target_properties(xrRenderPC_R2 PROPERTIES + PREFIX "" +) + +target_precompile_headers(xrRenderPC_R2 + PRIVATE + stdafx.h +) + +install(TARGETS xrRenderPC_R2 LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) diff --git a/src/Layers/xrRenderPC_R4/CMakeLists.txt b/src/Layers/xrRenderPC_R4/CMakeLists.txt new file mode 100644 index 00000000000..dfd3ab39daf --- /dev/null +++ b/src/Layers/xrRenderPC_R4/CMakeLists.txt @@ -0,0 +1,57 @@ +add_library(xrRenderPC_R4 SHARED) + +target_sources(xrRenderPC_R4 PRIVATE + ComputeShader.cpp + ComputeShader.h + CSCompiler.cpp + CSCompiler.h + packages.config + r2_test_hw.cpp + r4_rendertarget.h + r4_rendertarget_accum_direct.cpp + r4_rendertarget_build_textures.cpp + r4_rendertarget_phase_combine.cpp + r4_rendertarget_phase_hdao.cpp + r4_rendertarget_u_set_rt.cpp + r4_shaders.cpp + R_Backend_LOD.cpp + R_Backend_LOD.h + stdafx.cpp + stdafx.h + xrRender_R4.cpp +) + +target_include_directories(xrRenderPC_R4 + PRIVATE + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/sdk/include" +) + +target_link_libraries(xrRenderPC_R4 + PRIVATE + xrCore + xrCDB + xrEngine + xrParticles + xrScriptEngine + xrAPI + xrMiscMath +) + +target_compile_definitions(xrRenderPC_R4 + PRIVATE + XRRENDER_R4_EXPORTS +) + +set_target_properties(xrRenderPC_R4 PROPERTIES + PREFIX "" +) + +target_precompile_headers(xrRenderPC_R4 + PRIVATE + stdafx.h +) + +install(TARGETS xrRenderPC_R4 LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 569d71fc84f..b03646682fb 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -1,6 +1,11 @@ -#add_subdirectory(xrLC_Light) +if (WIN32) + add_subdirectory(xrLC_Light) +endif() + add_subdirectory(xrLCUtil) + if (NOT PROJECT_PLATFORM_E2K) # XXX: fix compilation on E2K add_subdirectory(xrQSlim) endif() + add_subdirectory(xrMiscMath) diff --git a/src/utils/xrLCUtil/CMakeLists.txt b/src/utils/xrLCUtil/CMakeLists.txt index 85a35eb5cc6..14f6f16ca2a 100644 --- a/src/utils/xrLCUtil/CMakeLists.txt +++ b/src/utils/xrLCUtil/CMakeLists.txt @@ -1,44 +1,40 @@ -project(xrLCUtil) - -set(SRC_FILES - #"ILevelCompilerLogger.hpp" - #"LevelCompilerLoggerWindow.hpp" - #"LevelCompilerLoggerWindow.cpp" - "pch.cpp" - "pch.cpp" - "resource.h" - "xrLCUtil.hpp" - "xrLCUtil.cpp" - "xrThread.hpp" - "xrThread.cpp" +add_library(xrLCUtil SHARED) + +target_sources(xrLCUtil PRIVATE + #ILevelCompilerLogger.hpp + #LevelCompilerLoggerWindow.hpp + #LevelCompilerLoggerWindow.cpp + pch.cpp + pch.cpp + resource.h + xrLCUtil.hpp + xrLCUtil.cpp + xrThread.hpp + xrThread.cpp ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrLCUtil PRIVATE - ${CMAKE_SOURCE_DIR}/src + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrLCUtil PRIVATE xrCore ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrLCUtil PRIVATE - -DLEVEL_COMPILER - -DXRLCUTIL_EXPORTS - -D_USE_MATH_DEFINES + LEVEL_COMPILER + XRLCUTIL_EXPORTS + _USE_MATH_DEFINES ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrLCUtil PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrLCUtil PRIVATE - "pch.hpp" + pch.hpp ) diff --git a/src/utils/xrLC_Light/CMakeLists.txt b/src/utils/xrLC_Light/CMakeLists.txt index 3d738db359f..ad262e58951 100644 --- a/src/utils/xrLC_Light/CMakeLists.txt +++ b/src/utils/xrLC_Light/CMakeLists.txt @@ -1,189 +1,185 @@ -project(xrLC_Light) +add_library(xrLC_Light SHARED) -set(SRC_FILES - "base_basis.cpp" - "base_basis.h" - "base_color.cpp" - "base_color.h" - "base_face.cpp" - "base_face.h" - "base_face_ptr_storage.h" - "base_lighting.cpp" - "base_lighting.h" - "b_build_texture.cpp" - "b_build_texture.h" - "calculate_normals.h" - "compiler.cpp" - "detail_net_global_data.cpp" - "detail_net_global_data.h" - "detail_slot_calculate.cpp" - "detail_slot_calculate.h" - "ETextureParams.cpp" - "ETextureParams.h" - "execute_statistics.cpp" - "execute_statistics.h" - "file_compress.cpp" - "file_compress.h" - "fitter.cpp" - "fitter.h" - "gl_base_cl_data.cpp" - "gl_base_cl_data.h" - "global_calculation_data.cpp" - "global_calculation_data.h" - "global_slots_data.cpp" - "global_slots_data.h" - "hash2D.h" - "implicit_net_global_data.cpp" - "implicit_net_global_data.h" - "itterate_adjacents.h" - "itterate_adjacents_static.h" - "lcnet_execution_tasks_add.h" - "lc_net_global_data.cpp" - "lc_net_global_data.h" - "lcnet_task_manager.cpp" - "lcnet_task_manager.h" - "lcnet_task_menager_run_task.cpp" - "light_execute.cpp" - "light_execute.h" - "Lightmap.cpp" - "Lightmap.h" - "light_point.h" - "lightstab_interface.h" - "LightThread.cpp" - "LightThread.h" - "lm_layer.cpp" - "lm_layer.h" - "lm_net_global_data.cpp" - "lm_net_global_data.h" - "MeshStaic.cpp" - "MeshStructure.h" - "mu_light_net.cpp" - "mu_light_net.h" - "mu_model_face.cpp" - "mu_model_face_defs.h" - "mu_model_face.h" - "mu_model_light.cpp" - "mu_model_light.h" - "mu_model_light_threads.cpp" - "mu_model_light_threads.h" - "net_all_executions.h" - "net_all_globals.h" - "net_cl_data_prepare.cpp" - "net_cl_data_prepare.h" - "net_exec_pool.cpp" - "net_exec_pool.h" - "net_execution.cpp" - "net_execution_detail_light.cpp" - "net_execution_detail_light.h" - "net_execution_factory.cpp" - "net_execution_factory.h" - "net_execution_factory_register.cpp" - "net_execution_globals.cpp" - "net_execution_globals.h" - "net_execution.h" - "net_execution_implicit_light.cpp" - "net_execution_implicit_light.h" - "net_execution_lightmaps.cpp" - "net_execution_lightmaps.h" - "net_execution_mu_base.cpp" - "net_execution_mu_base.h" - "net_execution_mu_ref.cpp" - "net_execution_mu_ref.h" - "net_execution_vertex_light.cpp" - "net_execution_vertex_light.h" - "net_global_data_cleanup.cpp" - "net_global_data_cleanup.h" - "net_global_data.cpp" - "net_global_data.h" - "net_light.cpp" - "net_light.h" - "net_lightmaps_add_task.cpp" - "net_light_task.cpp" - "net_light_task.h" - "net_stream.cpp" - "net_stream.h" - "net_task_callback.cpp" - "net_task_callback.h" - "net_task.cpp" - "net_task.h" - "net_task_manager.cpp" - "net_task_manager.h" - "net_task_menager.cpp" - "net_task_menager.h" - "recalculation.cpp" - "recalculation.h" - "ref_model_net_global_data.cpp" - "ref_model_net_global_data.h" - "R_light.h" - "serialize.cpp" - "serialize.h" - "stdafx.cpp" - "stdafx.h" - "tcf.cpp" - "tcf.h" - "uv_tri.cpp" - "uv_tri.h" - "vector_clear.h" - "xrDeflectoL_Direct.cpp" - "xrDeflector.cpp" - "xrDeflectorDefs.h" - "xrDeflector.h" - "xrDeflectorLight.cpp" - "xrDXTC.h" - "xrFace.cpp" - "xrFaceDefs.h" - "xrFace.h" - "xrFaceInline.h" - "xrImage_Filter.cpp" - "xrImage_Filter.h" - "xrImage_Resampler.cpp" - "xrImage_Resampler.h" - "xrIsect.h" - "xrLC_GlobalData.cpp" - "xrLC_GlobalData.h" - "xrLC_Light.cpp" - "xrLC_Light.h" - "xrLightDoNet.cpp" - "xrLightDoNet.h" - "xrLight_ImlicitNet.cpp" - "xrLight_ImplicitCalcGlobs.cpp" - "xrLight_ImplicitCalcGlobs.h" - "xrLight_Implicit.cpp" - "xrLight_ImplicitDeflector.cpp" - "xrLight_ImplicitDeflector.h" - "xrLight_Implicit.h" - "xrLight_ImplicitRun.h" - "xrLight_ImplicitThread.cpp" - "xrLightVertex.cpp" - "xrLightVertex.h" - "xrLightVertexNet.cpp" - "xrMU_Model_Calc_faceopacity.cpp" - "xrMU_Model_Calc_lighting.cpp" - "xrMU_Model_Calc_materials.cpp" - "xrMU_Model_Calc_normals.cpp" - "xrMU_Model.cpp" - "xrMU_Model_export_cform_rcast.cpp" - "xrMU_Model.h" - "xrMU_Model_Load.cpp" - "xrMU_Model_Reference_Calc_Lighting.cpp" - "xrMU_Model_Reference.cpp" - "xrMU_Model_Reference.h" - "xrUVpoint.h" - "../Shader_xrLC.h" - "../../xrEngine/xrLoadSurface.cpp" +target_sources(xrLC_Light PRIVATE + base_basis.cpp + base_basis.h + base_color.cpp + base_color.h + base_face.cpp + base_face.h + base_face_ptr_storage.h + base_lighting.cpp + base_lighting.h + b_build_texture.cpp + b_build_texture.h + calculate_normals.h + compiler.cpp + detail_net_global_data.cpp + detail_net_global_data.h + detail_slot_calculate.cpp + detail_slot_calculate.h + ETextureParams.cpp + ETextureParams.h + execute_statistics.cpp + execute_statistics.h + file_compress.cpp + file_compress.h + fitter.cpp + fitter.h + gl_base_cl_data.cpp + gl_base_cl_data.h + global_calculation_data.cpp + global_calculation_data.h + global_slots_data.cpp + global_slots_data.h + hash2D.h + implicit_net_global_data.cpp + implicit_net_global_data.h + itterate_adjacents.h + itterate_adjacents_static.h + lcnet_execution_tasks_add.h + lc_net_global_data.cpp + lc_net_global_data.h + lcnet_task_manager.cpp + lcnet_task_manager.h + lcnet_task_menager_run_task.cpp + light_execute.cpp + light_execute.h + Lightmap.cpp + Lightmap.h + light_point.h + lightstab_interface.h + LightThread.cpp + LightThread.h + lm_layer.cpp + lm_layer.h + lm_net_global_data.cpp + lm_net_global_data.h + MeshStaic.cpp + MeshStructure.h + mu_light_net.cpp + mu_light_net.h + mu_model_face.cpp + mu_model_face_defs.h + mu_model_face.h + mu_model_light.cpp + mu_model_light.h + mu_model_light_threads.cpp + mu_model_light_threads.h + net_all_executions.h + net_all_globals.h + net_cl_data_prepare.cpp + net_cl_data_prepare.h + net_exec_pool.cpp + net_exec_pool.h + net_execution.cpp + net_execution_detail_light.cpp + net_execution_detail_light.h + net_execution_factory.cpp + net_execution_factory.h + net_execution_factory_register.cpp + net_execution_globals.cpp + net_execution_globals.h + net_execution.h + net_execution_implicit_light.cpp + net_execution_implicit_light.h + net_execution_lightmaps.cpp + net_execution_lightmaps.h + net_execution_mu_base.cpp + net_execution_mu_base.h + net_execution_mu_ref.cpp + net_execution_mu_ref.h + net_execution_vertex_light.cpp + net_execution_vertex_light.h + net_global_data_cleanup.cpp + net_global_data_cleanup.h + net_global_data.cpp + net_global_data.h + net_light.cpp + net_light.h + net_lightmaps_add_task.cpp + net_light_task.cpp + net_light_task.h + net_stream.cpp + net_stream.h + net_task_callback.cpp + net_task_callback.h + net_task.cpp + net_task.h + net_task_manager.cpp + net_task_manager.h + net_task_menager.cpp + net_task_menager.h + recalculation.cpp + recalculation.h + ref_model_net_global_data.cpp + ref_model_net_global_data.h + R_light.h + serialize.cpp + serialize.h + stdafx.cpp + stdafx.h + tcf.cpp + tcf.h + uv_tri.cpp + uv_tri.h + vector_clear.h + xrDeflectoL_Direct.cpp + xrDeflector.cpp + xrDeflectorDefs.h + xrDeflector.h + xrDeflectorLight.cpp + xrDXTC.h + xrFace.cpp + xrFaceDefs.h + xrFace.h + xrFaceInline.h + xrImage_Filter.cpp + xrImage_Filter.h + xrImage_Resampler.cpp + xrImage_Resampler.h + xrIsect.h + xrLC_GlobalData.cpp + xrLC_GlobalData.h + xrLC_Light.cpp + xrLC_Light.h + xrLightDoNet.cpp + xrLightDoNet.h + xrLight_ImlicitNet.cpp + xrLight_ImplicitCalcGlobs.cpp + xrLight_ImplicitCalcGlobs.h + xrLight_Implicit.cpp + xrLight_ImplicitDeflector.cpp + xrLight_ImplicitDeflector.h + xrLight_Implicit.h + xrLight_ImplicitRun.h + xrLight_ImplicitThread.cpp + xrLightVertex.cpp + xrLightVertex.h + xrLightVertexNet.cpp + xrMU_Model_Calc_faceopacity.cpp + xrMU_Model_Calc_lighting.cpp + xrMU_Model_Calc_materials.cpp + xrMU_Model_Calc_normals.cpp + xrMU_Model.cpp + xrMU_Model_export_cform_rcast.cpp + xrMU_Model.h + xrMU_Model_Load.cpp + xrMU_Model_Reference_Calc_Lighting.cpp + xrMU_Model_Reference.cpp + xrMU_Model_Reference.h + xrUVpoint.h + ../Shader_xrLC.h + ../xrLoadSurface.cpp ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrLC_Light PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/sdk/include + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/sdk/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrLC_Light PRIVATE xrCore xrCDB @@ -191,25 +187,24 @@ target_link_libraries(${PROJECT_NAME} xrLCUtil ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrLC_Light PRIVATE - -D_USRDLL - -DLEVEL_COMPILER - -D_USE_MATH_DEFINES - -DXRLC_LIGHT_EXPORTS - -DFORCE_NO_EXCEPTIONS + _USRDLL + LEVEL_COMPILER + _USE_MATH_DEFINES + XRLC_LIGHT_EXPORTS + FORCE_NO_EXCEPTIONS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrLC_Light PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrLC_Light PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrLC_Light LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/utils/xrMiscMath/CMakeLists.txt b/src/utils/xrMiscMath/CMakeLists.txt index 86410fa1bbb..507c4072515 100644 --- a/src/utils/xrMiscMath/CMakeLists.txt +++ b/src/utils/xrMiscMath/CMakeLists.txt @@ -1,29 +1,25 @@ -project(xrMiscMath) +add_library(xrMiscMath STATIC) -set(SRC_FILES - "matrix.cpp" - "quaternion.cpp" - "vector.cpp" - "vector3d_ext.cpp" - "xrMiscMath.cpp" - "pch.hpp" - "pch.cpp" +target_sources(xrMiscMath PRIVATE + matrix.cpp + quaternion.cpp + vector.cpp + vector3d_ext.cpp + xrMiscMath.cpp + pch.hpp + pch.cpp ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} - PUBLIC - ${CMAKE_SOURCE_DIR}/src +target_include_directories(xrMiscMath + PRIVATE + "${CMAKE_SOURCE_DIR}/src" ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrMiscMath PROPERTIES POSITION_INDEPENDENT_CODE ON ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrMiscMath PRIVATE - "pch.hpp" + pch.hpp ) diff --git a/src/utils/xrQSlim/CMakeLists.txt b/src/utils/xrQSlim/CMakeLists.txt index d14960ca911..5569062f2a3 100644 --- a/src/utils/xrQSlim/CMakeLists.txt +++ b/src/utils/xrQSlim/CMakeLists.txt @@ -1,65 +1,61 @@ -project(xrQSlim) +add_library(xrQSlim STATIC) -set(SRC_FILES - "geom3d.h" - "mat2.h" - "mat2.cpp" - "mat3.h" - "mat3.cpp" - "mat4.h" - "mat4.cpp" - "mixmops.h" - "mixmops.cpp" - "mixvops.h" - "MxBlock2.h" - "MxBlock.h" - "MxBlockModel.h" - "MxBlockModel.cpp" - "MxDefines.h" - "MxDynBlock.h" - "MxGeom3D.h" - "MxGeom3D.cpp" - "MxGeoPrims.h" - "MxHeap.h" - "MxHeap.cpp" - "MxMat2.h" - "MxMat3.h" - "MxMat3-jacobi.cpp" - "MxMat4-jacobi.cpp" - "MxMat4.h" - "MxMatrix.h" - "MxMatrix.cpp" - "MxPropSlim.h" - "MxPropSlim.cpp" - "MxQMetric3.h" - "MxQMetric3.cpp" - "MxQMetric.h" - "MxQMetric.cpp" - "MxQSlim.h" - "MxQSlim.cpp" - "MxStdModel.h" - "MxStdModel.cpp" - "MxStdSlim.h" - "MxStdSlim.cpp" - "MxVec3.h" - "MxVec4.h" - "MxVector.h" - "stdafx.h" - "vec2.h" - "vec3.h" - "vec4.h" +target_sources(xrQSlim PRIVATE + geom3d.h + mat2.h + mat2.cpp + mat3.h + mat3.cpp + mat4.h + mat4.cpp + mixmops.h + mixmops.cpp + mixvops.h + MxBlock2.h + MxBlock.h + MxBlockModel.h + MxBlockModel.cpp + MxDefines.h + MxDynBlock.h + MxGeom3D.h + MxGeom3D.cpp + MxGeoPrims.h + MxHeap.h + MxHeap.cpp + MxMat2.h + MxMat3.h + MxMat3-jacobi.cpp + MxMat4-jacobi.cpp + MxMat4.h + MxMatrix.h + MxMatrix.cpp + MxPropSlim.h + MxPropSlim.cpp + MxQMetric3.h + MxQMetric3.cpp + MxQMetric.h + MxQMetric.cpp + MxQSlim.h + MxQSlim.cpp + MxStdModel.h + MxStdModel.cpp + MxStdSlim.h + MxStdSlim.cpp + MxVec3.h + MxVec4.h + MxVector.h + stdafx.h + vec2.h + vec3.h + vec4.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} - PUBLIC - ${CMAKE_SOURCE_DIR}/src +target_include_directories(xrQSlim + PRIVATE + "${CMAKE_SOURCE_DIR}/src" ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrQSlim PUBLIC - -DXR_QSLIM_EXPORTS + XR_QSLIM_EXPORTS ) diff --git a/src/xrAICore/CMakeLists.txt b/src/xrAICore/CMakeLists.txt index 9e96971b992..d6c9507dd16 100644 --- a/src/xrAICore/CMakeLists.txt +++ b/src/xrAICore/CMakeLists.txt @@ -1,297 +1,321 @@ -project(xrAICore) - -set(AI_SRC - "AISpaceBase.cpp" - "AISpaceBase.hpp" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_SRC - "Components/problem_solver.h" - "Components/problem_solver_inline.h" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SRC - "Components/condition_state.h" - "Components/condition_state_inline.h" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SCRIPT_WORLD_STATE_SRC - "Components/script_world_state.h" - "Components/script_world_state_script.cpp" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_ABSTRACT_SRC - "Components/operator_abstract.h" - "Components/operator_abstract_inline.h" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SRC - "Components/operator_condition.h" - "Components/operator_condition_inline.h" -) - -set(AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SCRIPT_WORLD_PROPERTY_SRC - "Components/script_world_property.h" - "Components/script_world_property_inline.h" - "Components/script_world_property_script.cpp" -) - -set(AI_NAVIGATION_GAME_GRAPH_SRC - "Navigation/game_graph.h" - "Navigation/game_graph_inline.h" - "Navigation/game_graph_script.cpp" - "Navigation/game_graph_space.h" -) - -set(AI_NAVIGATION_GAME_LEVEL_CROSS_TABLE_SRC - "Navigation/game_level_cross_table.h" - "Navigation/game_level_cross_table_inline.h" -) - -set(AI_NAVIGATION_GRAPH_ABSTRACT_SRC - "Navigation/graph_abstract.h" - "Navigation/graph_abstract_inline.h" - "Navigation/graph_edge.h" - "Navigation/graph_edge_inline.h" - "Navigation/graph_vertex.h" - "Navigation/graph_vertex_inline.h" -) - -set(AI_NAVIGATION_LEVEL_GRAPH - "Navigation/level_graph.cpp" - "Navigation/level_graph.h" - "Navigation/level_graph_inline.h" - "Navigation/level_graph_manager.h" - "Navigation/level_graph_space.h" - "Navigation/level_graph_vertex.cpp" - "Navigation/level_graph_vertex_inline.h" -) - -set(AI_NAVIGATION_OBJECT_LOCATION - "Navigation/ai_object_location.h" - "Navigation/ai_object_location_impl.h" - "Navigation/ai_object_location_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_ALGORITHMS_ASTAR - "Navigation/a_star.h" - "Navigation/a_star_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_ALGORITHMS_DIJKSTRA - "Navigation/dijkstra.h" - "Navigation/dijkstra_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_DATASTORAGES_CONSTRUCTORS - "Navigation/data_storage_constructor.h" -) - -set(AI_NAVIGATION_PATHFINDING_DATASTORAGES_PATH_BUILDERS - "Navigation/edge_path.h" - "Navigation/edge_path_inline.h" - "Navigation/vertex_path.h" - "Navigation/vertex_path_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_DATASTORAGES_PRIORITY_QUEUES - "Navigation/data_storage_binary_heap.h" - "Navigation/data_storage_binary_heap_inline.h" - "Navigation/data_storage_bucket_list.h" - "Navigation/data_storage_bucket_list_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_ALLOCATORS - "Navigation/vertex_allocator_fixed.h" - "Navigation/vertex_allocator_fixed_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_MANAGERS - "Navigation/vertex_manager_fixed.h" - "Navigation/vertex_manager_fixed_inline.h" - "Navigation/vertex_manager_hash_fixed.h" - "Navigation/vertex_manager_hash_fixed_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_GRAPH_ENGINE - "Navigation/graph_engine.h" - "Navigation/graph_engine_inline.h" - "Navigation/graph_engine_space.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS - "Navigation/PathManagers/path_manager.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GAME - "Navigation/PathManagers/path_manager_game.h" - "Navigation/PathManagers/path_manager_game_inline.h" - "Navigation/PathManagers/path_manager_game_level.h" - "Navigation/PathManagers/path_manager_game_level_inline.h" - "Navigation/PathManagers/path_manager_game_vertex.h" - "Navigation/PathManagers/path_manager_game_vertex_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GENERIC - "Navigation/PathManagers/path_manager_generic.h" - "Navigation/PathManagers/path_manager_generic_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_LEVEL - "Navigation/PathManagers/path_manager_level.h" - "Navigation/PathManagers/path_manager_level_inline.h" - "Navigation/PathManagers/path_manager_level_flooder.h" - "Navigation/PathManagers/path_manager_level_flooder_inline.h" - "Navigation/PathManagers/path_manager_level_nearest_vertex.h" - "Navigation/PathManagers/path_manager_level_nearest_vertex_inline.h" - "Navigation/PathManagers/path_manager_level_straight_line.h" - "Navigation/PathManagers/path_manager_level_straight_line_inline.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_PARAMS - "Navigation/PathManagers/path_manager_params.h" - "Navigation/PathManagers/path_manager_params_flooder.h" - "Navigation/PathManagers/path_manager_params_game_level.h" - "Navigation/PathManagers/path_manager_params_game_vertex.h" - "Navigation/PathManagers/path_manager_params_nearest_vertex.h" - "Navigation/PathManagers/path_manager_params_straight_line.h" -) - -set(AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_SOLVER - "Navigation/PathManagers/path_manager_solver.h" - "Navigation/PathManagers/path_manager_solver_inline.h" -) - -set(AI_NAVIGATION_PATROL_PATH - "Navigation/PatrolPath/patrol_path.cpp" - "Navigation/PatrolPath/patrol_path.h" - "Navigation/PatrolPath/patrol_path_inline.h" -) - -set(AI_NAVIGATION_PATROL_PATH_PARAMS - "Navigation/PatrolPath/patrol_path_params.cpp" - "Navigation/PatrolPath/patrol_path_params.h" - "Navigation/PatrolPath/patrol_path_params_inline.h" - "Navigation/PatrolPath/patrol_path_params_script.cpp" -) - -set(AI_NAVIGATION_PATROL_PATH_PATROL_POINT - "Navigation/PatrolPath/patrol_point.cpp" - "Navigation/PatrolPath/patrol_point.h" - "Navigation/PatrolPath/patrol_point_inline.h" -) - -set(AI_NAVIGATION_PATROL_PATH_STORAGE - "Navigation/PatrolPath/patrol_path_storage.cpp" - "Navigation/PatrolPath/patrol_path_storage.h" - "Navigation/PatrolPath/patrol_path_storage_inline.h" -) - -set(KERNEL_SRC - "pch.cpp" - "pch.hpp" -) - -source_group("AI" FILES ${AI_SRC}) -source_group("AI\\Component\\ProblemSolver" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_SRC}) -source_group("AI\\Component\\ProblemSolver\\ConditionState" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SRC}) -source_group("AI\\Component\\ProblemSolver\\ConditionState\\ScriptWorldState" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SCRIPT_WORLD_STATE_SRC}) -source_group("AI\\Component\\ProblemSolver\\OperatorAbstract" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_ABSTRACT_SRC}) -source_group("AI\\Component\\ProblemSolver\\OperatorCondition" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SRC}) -source_group("AI\\Component\\ProblemSolver\\OperatorCondition\\ScriptWorldProperty" FILES ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SCRIPT_WORLD_PROPERTY_SRC}) -source_group("AI\\Navigation\\GameGraph" FILES ${AI_NAVIGATION_GAME_GRAPH_SRC}) -source_group("AI\\Navigation\\GameLevelCrossTable" FILES ${AI_NAVIGATION_GAME_LEVEL_CROSS_TABLE_SRC}) -source_group("AI\\Navigation\\GraphAbstract" FILES ${AI_NAVIGATION_GRAPH_ABSTRACT_SRC}) -source_group("AI\\Navigation\\LevelGraph" FILES ${AI_NAVIGATION_LEVEL_GRAPH}) -source_group("AI\\Navigation\\ObjectLocation" FILES ${AI_NAVIGATION_OBJECT_LOCATION}) -source_group("AI\\Navigation\\Pathfinding\\Algorithms\\AStar" FILES ${AI_NAVIGATION_PATHFINDING_ALGORITHMS_ASTAR}) -source_group("AI\\Navigation\\Pathfinding\\Algorithms\\Dijkstra" FILES ${AI_NAVIGATION_PATHFINDING_ALGORITHMS_DIJKSTRA}) -source_group("AI\\Navigation\\Pathfinding\\DataStorages\\Constructors" FILES ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_CONSTRUCTORS}) -source_group("AI\\Navigation\\Pathfinding\\DataStorages\\PathBuilders" FILES ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_PATH_BUILDERS}) -source_group("AI\\Navigation\\Pathfinding\\DataStorages\\PriorityQueues" FILES ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_PRIORITY_QUEUES}) -source_group("AI\\Navigation\\Pathfinding\\DataStorages\\VertexAllocators" FILES ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_ALLOCATORS}) -source_group("AI\\Navigation\\Pathfinding\\DataStorages\\VertexManagers" FILES ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_MANAGERS}) -source_group("AI\\Navigation\\Pathfinding\\GraphEngine" FILES ${AI_NAVIGATION_PATHFINDING_GRAPH_ENGINE}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers\\Game" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GAME}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers\\Generic" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GENERIC}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers\\Level" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_LEVEL}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers\\Params" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_PARAMS}) -source_group("AI\\Navigation\\Pathfinding\\PathManagers\\Solver" FILES ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_SOLVER}) -source_group("AI\\Navigation\\PatrolPath" FILES ${AI_NAVIGATION_PATROL_PATH}) -source_group("AI\\Navigation\\PatrolPath\\Params" FILES ${AI_NAVIGATION_PATROL_PATH_PARAMS}) -source_group("AI\\Navigation\\PatrolPath\\PatrolPoint" FILES ${AI_NAVIGATION_PATROL_PATH_PATROL_POINT}) -source_group("AI\\Navigation\\PatrolPath\\Storage" FILES ${AI_NAVIGATION_PATROL_PATH_STORAGE}) -source_group("Kernel" FILES ${KERNEL_SRC}) - -add_library(${PROJECT_NAME} SHARED - ${AI_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_CONDITION_STATE_SCRIPT_WORLD_STATE_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_ABSTRACT_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SRC} - ${AI_COMPONENTS_PROBLEM_SOLVER_OPERATOR_CONDITION_SCRIPT_WORLD_PROPERTY_SRC} - ${AI_NAVIGATION_GAME_GRAPH_SRC} - ${AI_NAVIGATION_GAME_LEVEL_CROSS_TABLE_SRC} - ${AI_NAVIGATION_GRAPH_ABSTRACT_SRC} - ${AI_NAVIGATION_LEVEL_GRAPH} - ${AI_NAVIGATION_OBJECT_LOCATION} - ${AI_NAVIGATION_PATHFINDING_ALGORITHMS_ASTAR} - ${AI_NAVIGATION_PATHFINDING_ALGORITHMS_DIJKSTRA} - ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_CONSTRUCTORS} - ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_PATH_BUILDERS} - ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_PRIORITY_QUEUES} - ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_ALLOCATORS} - ${AI_NAVIGATION_PATHFINDING_DATASTORAGES_VERTEX_MANAGERS} - ${AI_NAVIGATION_PATHFINDING_GRAPH_ENGINE} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GAME} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_GENERIC} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_LEVEL} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_PARAMS} - ${AI_NAVIGATION_PATHFINDING_PATH_MANAGERS_SOLVER} - ${AI_NAVIGATION_PATROL_PATH} - ${AI_NAVIGATION_PATROL_PATH_PARAMS} - ${AI_NAVIGATION_PATROL_PATH_PATROL_POINT} - ${AI_NAVIGATION_PATROL_PATH_STORAGE} - ${KERNEL_SRC} -) - -target_include_directories(${PROJECT_NAME} +add_library(xrAICore SHARED) + +target_sources_grouped( + TARGET xrAICore + NAME "AI" + FILES + AISpaceBase.cpp + AISpaceBase.hpp +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver" + FILES + Components/problem_solver.h + Components/problem_solver_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver\\ConditionState" + FILES + Components/condition_state.h + Components/condition_state_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver\\ConditionState\\ScriptWorldState" + FILES + Components/script_world_state.h + Components/script_world_state_script.cpp +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver\\OperatorAbstract" + FILES + Components/operator_abstract.h + Components/operator_abstract_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver\\OperatorCondition" + FILES + Components/operator_condition.h + Components/operator_condition_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Component\\ProblemSolver\\OperatorCondition\\ScriptWorldProperty" + FILES + Components/script_world_property.h + Components/script_world_property_inline.h + Components/script_world_property_script.cpp +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\GameGraph" + FILES + Navigation/game_graph.h + Navigation/game_graph_inline.h + Navigation/game_graph_script.cpp + Navigation/game_graph_space.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\GameLevelCrossTable" + FILES + Navigation/game_level_cross_table.h + Navigation/game_level_cross_table_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\GraphAbstract" + FILES + Navigation/graph_abstract.h + Navigation/graph_abstract_inline.h + Navigation/graph_edge.h + Navigation/graph_edge_inline.h + Navigation/graph_vertex.h + Navigation/graph_vertex_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\LevelGraph" + FILES + Navigation/level_graph.cpp + Navigation/level_graph.h + Navigation/level_graph_inline.h + Navigation/level_graph_manager.h + Navigation/level_graph_space.h + Navigation/level_graph_vertex.cpp + Navigation/level_graph_vertex_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\ObjectLocation" + FILES + Navigation/ai_object_location.h + Navigation/ai_object_location_impl.h + Navigation/ai_object_location_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\Algorithms\\AStar" + FILES + Navigation/a_star.h + Navigation/a_star_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\Algorithms\\Dijkstra" + FILES + Navigation/dijkstra.h + Navigation/dijkstra_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\DataStorages\\Constructors" + FILES + Navigation/data_storage_constructor.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\DataStorages\\PathBuilders" + FILES + Navigation/edge_path.h + Navigation/edge_path_inline.h + Navigation/vertex_path.h + Navigation/vertex_path_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\DataStorages\\PriorityQueues" + FILES + Navigation/data_storage_binary_heap.h + Navigation/data_storage_binary_heap_inline.h + Navigation/data_storage_bucket_list.h + Navigation/data_storage_bucket_list_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\DataStorages\\VertexAllocators" + FILES + Navigation/vertex_allocator_fixed.h + Navigation/vertex_allocator_fixed_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\DataStorages\\VertexManagers" + FILES + Navigation/vertex_manager_fixed.h + Navigation/vertex_manager_fixed_inline.h + Navigation/vertex_manager_hash_fixed.h + Navigation/vertex_manager_hash_fixed_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\GraphEngine" + FILES + Navigation/graph_engine.h + Navigation/graph_engine_inline.h + Navigation/graph_engine_space.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers" + FILES + Navigation/PathManagers/path_manager.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers\\Game" + FILES + Navigation/PathManagers/path_manager_game.h + Navigation/PathManagers/path_manager_game_inline.h + Navigation/PathManagers/path_manager_game_level.h + Navigation/PathManagers/path_manager_game_level_inline.h + Navigation/PathManagers/path_manager_game_vertex.h + Navigation/PathManagers/path_manager_game_vertex_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers\\Generic" + FILES + Navigation/PathManagers/path_manager_generic.h + Navigation/PathManagers/path_manager_generic_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers\\Level" + FILES + Navigation/PathManagers/path_manager_level.h + Navigation/PathManagers/path_manager_level_inline.h + Navigation/PathManagers/path_manager_level_flooder.h + Navigation/PathManagers/path_manager_level_flooder_inline.h + Navigation/PathManagers/path_manager_level_nearest_vertex.h + Navigation/PathManagers/path_manager_level_nearest_vertex_inline.h + Navigation/PathManagers/path_manager_level_straight_line.h + Navigation/PathManagers/path_manager_level_straight_line_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers\\Params" + FILES + Navigation/PathManagers/path_manager_params.h + Navigation/PathManagers/path_manager_params_flooder.h + Navigation/PathManagers/path_manager_params_game_level.h + Navigation/PathManagers/path_manager_params_game_vertex.h + Navigation/PathManagers/path_manager_params_nearest_vertex.h + Navigation/PathManagers/path_manager_params_straight_line.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\Pathfinding\\PathManagers\\Solver" + FILES + Navigation/PathManagers/path_manager_solver.h + Navigation/PathManagers/path_manager_solver_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\PatrolPath" + FILES + Navigation/PatrolPath/patrol_path.cpp + Navigation/PatrolPath/patrol_path.h + Navigation/PatrolPath/patrol_path_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\PatrolPath\\Params" + FILES + Navigation/PatrolPath/patrol_path_params.cpp + Navigation/PatrolPath/patrol_path_params.h + Navigation/PatrolPath/patrol_path_params_inline.h + Navigation/PatrolPath/patrol_path_params_script.cpp +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\PatrolPath\\PatrolPoint" + FILES + Navigation/PatrolPath/patrol_point.cpp + Navigation/PatrolPath/patrol_point.h + Navigation/PatrolPath/patrol_point_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "AI\\Navigation\\PatrolPath\\Storage" + FILES + Navigation/PatrolPath/patrol_path_storage.cpp + Navigation/PatrolPath/patrol_path_storage.h + Navigation/PatrolPath/patrol_path_storage_inline.h +) + +target_sources_grouped( + TARGET xrAICore + NAME "Kernel" + FILES + pch.cpp + pch.hpp +) + + +target_include_directories(xrAICore PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/sdk/include + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/sdk/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrAICore PRIVATE xrCore xrEngine xrMiscMath xrAPI xrScriptEngine - xrLuabind - ${LUA_LIBRARIES} ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrAICore PRIVATE - -DXRAICORE_EXPORTS + XRAICORE_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrAICore PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrAICore PRIVATE - "pch.hpp" + pch.hpp ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrAICore LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrCDB/CMakeLists.txt b/src/xrCDB/CMakeLists.txt index 55227097472..2d4ff876ebe 100644 --- a/src/xrCDB/CMakeLists.txt +++ b/src/xrCDB/CMakeLists.txt @@ -1,52 +1,49 @@ -project(xrCDB) +add_library(xrCDB SHARED) -set(ENGINE_SRC - "ISpatial.cpp" - "ISpatial.h" - "ISpatial_q_box.cpp" - "ISpatial_q_frustum.cpp" - "ISpatial_q_ray.cpp" - "ISpatial_verify.cpp" - "xr_area.cpp" - "xr_area.h" - "xr_area_query.cpp" - "xr_area_raypick.cpp" - "xr_collide_defs.h" - "xrXRC.cpp" - "xrXRC.h" +target_sources_grouped( + TARGET xrCDB + NAME "engine" + FILES + ISpatial.cpp + ISpatial.h + ISpatial_q_box.cpp + ISpatial_q_frustum.cpp + ISpatial_q_ray.cpp + ISpatial_verify.cpp + xr_area.cpp + xr_area.h + xr_area_query.cpp + xr_area_raypick.cpp + xr_collide_defs.h + xrXRC.cpp + xrXRC.h ) -set(KERNEL_SRC - "Frustum.cpp" - "Frustum.h" - "Intersect.hpp" - "stdafx.h" - "StdAfx.cpp" - "xrCDB.cpp" - "xrCDB.h" - "xrCDB_box.cpp" - "xrCDB_Collector.cpp" - "xrCDB_frustum.cpp" - "xrCDB_ray.cpp" +target_sources_grouped( + TARGET xrCDB + NAME "Kernel" + FILES + Frustum.cpp + Frustum.h + Intersect.hpp + stdafx.h + StdAfx.cpp + xrCDB.cpp + xrCDB.h + xrCDB_box.cpp + xrCDB_Collector.cpp + xrCDB_frustum.cpp + xrCDB_ray.cpp ) -source_group("engine" FILES ${ENGINE_SRC}) -source_group("Kernel" FILES ${KERNEL_SRC}) - -set(SRC_FILES - ${ENGINE_SRC} - ${KERNEL_SRC} -) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrCDB PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${SDL2_INCLUDE_DIRS} + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals" + "${CMAKE_SOURCE_DIR}/Externals/imgui" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrCDB PRIVATE xrCore xrMiscMath @@ -54,22 +51,21 @@ target_link_libraries(${PROJECT_NAME} xrAPI ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrCDB PRIVATE - -DXRCDB_EXPORTS + XRCDB_EXPORTS $<$:OPCODE_STATIC> ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrCDB PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrCDB PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrCDB LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 40d7f4bbf58..4734307cec8 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -1,461 +1,491 @@ -project(xrCore) - -set(ANIMATION - "Animation/Bone.cpp" - "Animation/Bone.hpp" - "Animation/BoneEditor.cpp" - "Animation/Envelope.cpp" - "Animation/Envelope.hpp" - "Animation/interp.cpp" - "Animation/Motion.cpp" - "Animation/Motion.hpp" - "Animation/SkeletonMotionDefs.hpp" - "Animation/SkeletonMotions.cpp" - "Animation/SkeletonMotions.hpp" -) - -set(COMMON - "../Common/Common.hpp" - "../Common/Config.hpp" - "../Common/face_smoth_flags.h" - "../Common/FSMacros.hpp" - "../Common/LevelGameDef.h" - "../Common/Noncopyable.hpp" - "../Common/Platform.hpp" - "../Common/OGF_GContainer_Vertices.hpp" -) - -set(COMMON_OBJECT - "../Common/object_broker.h" - "../Common/object_cloner.h" - "../Common/object_comparer.h" - "../Common/object_destroyer.h" - "../Common/object_interfaces.h" - "../Common/object_loader.h" - "../Common/object_saver.h" - "../Common/object_type_traits.h" -) - -set(COMPRESSION_LZ - "LzHuf.cpp" - "lzhuf.h" -) - -set(COMPRESSION_LZO - "Compression/lzo_compressor.cpp" - "Compression/lzo_compressor.h" - "Compression/rt_compressor9.cpp" - "Compression/rt_compressor.cpp" - "Compression/rt_compressor.h" -) - -set(COMPRESSION_PPMD - "Compression/ppmd_compressor.cpp" - "Compression/ppmd_compressor.h" -) - -set(COMPRESSION_PPMD_COMMON - "Compression/PPMd.h" - "Compression/PPMdType.h" -) - -set(COMPRESSION_PPMD_CORE - "Compression/Coder.hpp" - "Compression/Model.cpp" -) - -set(COMPRESSION_PPMD_CORE_ALLOCATOR - "Compression/SubAlloc.hpp" -) - -set(COMPRESSION_PPMD_STREAM - "Compression/compression_ppmd_stream.h" - "Compression/compression_ppmd_stream_inline.h" -) - -set(CONTAINERS - "Containers/AssociativeVectorComparer.hpp" - "Containers/AssociativeVector.hpp" - "Containers/FixedMap.h" -) - -set(CRYPTO - "Crypto/trivial_encryptor.cpp" - "Crypto/trivial_encryptor.h" - "Crypto/xr_dsa.cpp" - "Crypto/xr_dsa.h" - "Crypto/xr_dsa_signer.cpp" - "Crypto/xr_dsa_signer.h" - "Crypto/xr_dsa_verifyer.cpp" - "Crypto/xr_dsa_verifyer.h" - "Crypto/xr_sha.h" -) - -set(DEBUG_CORE - #"Debug/MiniDump.cpp" - #"Debug/MiniDump.h" - "xrDebug.cpp" - "xrDebug.h" - "xrDebug_macros.h" -) - -#set(DEBUG_CORE_DXERR -# "Debug/dxerr.cpp" -# "Debug/dxerr.h" -# "Debug/DXGetErrorDescription.inl" -# "Debug/DXGetErrorString.inl" -# "Debug/DXTrace.inl" +add_library(xrCore SHARED) + +target_sources_grouped( + TARGET xrCore + NAME "Animation" + FILES + Animation/Bone.cpp + Animation/Bone.hpp + Animation/BoneEditor.cpp + Animation/Envelope.cpp + Animation/Envelope.hpp + Animation/interp.cpp + Animation/Motion.cpp + Animation/Motion.hpp + Animation/SkeletonMotionDefs.hpp + Animation/SkeletonMotions.cpp + Animation/SkeletonMotions.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Common" + FILES + ../Common/Common.hpp + ../Common/Config.hpp + ../Common/face_smoth_flags.h + ../Common/FSMacros.hpp + ../Common/LevelGameDef.h + ../Common/Noncopyable.hpp + ../Common/Platform.hpp + ../Common/OGF_GContainer_Vertices.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Common\\Object" + FILES + ../Common/object_broker.h + ../Common/object_cloner.h + ../Common/object_comparer.h + ../Common/object_destroyer.h + ../Common/object_interfaces.h + ../Common/object_loader.h + ../Common/object_saver.h + ../Common/object_type_traits.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\lz" + FILES + LzHuf.cpp + lzhuf.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\lzo" + FILES + Compression/lzo_compressor.cpp + Compression/lzo_compressor.h + Compression/rt_compressor9.cpp + Compression/rt_compressor.cpp + Compression/rt_compressor.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\ppmd" + FILES + Compression/ppmd_compressor.cpp + Compression/ppmd_compressor.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\ppmd\\common" + FILES + Compression/PPMd.h + Compression/PPMdType.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\ppmd\\core" + FILES + Compression/Coder.hpp + Compression/Model.cpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\ppmd\\core\\allocator" + FILES + Compression/SubAlloc.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Compression\\ppmd\\stream" + FILES + Compression/compression_ppmd_stream.h + Compression/compression_ppmd_stream_inline.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Containers" + FILES + Containers/AssociativeVectorComparer.hpp + Containers/AssociativeVector.hpp + Containers/FixedMap.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Crypto" + FILES + Crypto/trivial_encryptor.cpp + Crypto/trivial_encryptor.h + Crypto/xr_dsa.cpp + Crypto/xr_dsa.h + Crypto/xr_dsa_signer.cpp + Crypto/xr_dsa_signer.h + Crypto/xr_dsa_verifyer.cpp + Crypto/xr_dsa_verifyer.h + Crypto/xr_sha.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Debug core" + FILES + #Debug/MiniDump.cpp + #Debug/MiniDump.h + xrDebug.cpp + xrDebug.h + xrDebug_macros.h +) + +#target_sources_grouped( +# TARGET xrCore +# NAME "Debug core\\DxErr" +# FILES +# Debug/dxerr.cpp +# Debug/dxerr.h +# Debug/DXGetErrorDescription.inl +# Debug/DXGetErrorString.inl +# Debug/DXTrace.inl #) -set(EVENTS - "Events/Notifier.h" -) - -set(FMESH - "FMesh.cpp" - "FMesh.hpp" -) - -set(FS - "FileCRC32.cpp" - "FileCRC32.h" - "FileSystem.cpp" - "FileSystem.h" - "FileSystem_borland.cpp" - "FS.cpp" - "FS.h" - "FS_impl.h" - "FS_internal.h" - "LocatorAPI.cpp" - "LocatorAPI.h" - "LocatorAPI_auth.cpp" - "LocatorAPI_defs.cpp" - "LocatorAPI_defs.h" - "log.cpp" - "log.h" - "NET_utils.cpp" - "net_utils.h" - "xr_ini.cpp" - "xr_ini.h" -) - -set(FS_FILE_STREAM_READER - "file_stream_reader.cpp" - "file_stream_reader.h" -) - -set(FS_STREAM_READER - "stream_reader.cpp" - "stream_reader.h" - "stream_reader_inline.h" -) - -set(INTRUSIVE_PTR - "intrusive_ptr.h" -) - -set(KERNEL - "cdecl_cast.hpp" - "FTimer.cpp" - "FTimer.h" - "ModuleLookup.cpp" - "ModuleLookup.hpp" - "resource.h" - "xr_shortcut.h" - "xrCore.cpp" - "xrCore.h" -) - -set(KERNEL_COMMON - "../Common/_d3d_extensions.h" - "../Common/GUID.hpp" - "../Common/LevelStructure.hpp" - "../Common/Util.hpp" -) - -set(MATH - "_bitwise.h" - "_color.h" - "_compressed_normal.cpp" - "_compressed_normal.h" - "_cylinder.cpp" - "_cylinder.h" - "_fbox.h" - "_fbox2.h" - "_flags.h" - "_math.cpp" - "_math.h" - "_matrix.h" - "_matrix33.h" - "_obb.h" - "_plane.h" - "_plane2.h" - "_quaternion.h" - "_random.h" - "_rect.h" - "_sphere.cpp" - "_sphere.h" - "_vector2.h" - "_vector3d.h" - "_vector3d_ext.h" - "_vector4.h" - "dump_string.cpp" - "dump_string.h" - "math_constants.h" - "vector.h" - "xr_types.h" -) - -set(MATH_EXTENSIONS - #"ChooseTypes.H" - #"client_id.h" - "_std_extensions.cpp" - "_std_extensions.h" - "_stl_extensions.h" - "clsid.cpp" - "clsid.h" - "fastdelegate.h" - "xr_token.cpp" - "xr_token.h" - "xr_trims.cpp" - "xr_trims.h" -) - -set(MATH_EXTENSIONS_BUFFER_VECTOR - "buffer_vector.h" - "buffer_vector_inline.h" -) - -set(MATH_RNG - "Math/Random32.hpp" -) - -set(MATH_STLEXT - "FixedVector.h" - "xrPool.h" -) - -set(MEDIA - "Media/Image.cpp" - "Media/Image.hpp" - "Media/ImageJPEG.cpp" -) - -set(MEMORY - "Memory/xalloc.h" - "xrMemory.cpp" - "xrMemory.h" - #"Memory/xrMemory_align.cpp" - #"Memory/xrMemory_align.h" -) - -set(OS - "os_clipboard.cpp" - "os_clipboard.h" -) - -set(PCH - "stdafx.cpp" - "stdafx.h" -) - -set(POSTPROCESS - "PostProcess/PostProcess.cpp" - "PostProcess/PostProcess.hpp" - "PostProcess/PPInfo.cpp" - "PostProcess/PPInfo.hpp" -) - -set(SHARED_MEMORY_STRING_LIBRARY - "crc32.cpp" - "string_concatenations.cpp" - "string_concatenations.h" - "string_concatenations_inline.h" - "xr_resource.h" - "xr_shared.cpp" - "xr_shared.h" - "xrsharedmem.cpp" - "xrsharedmem.h" - "xrstring.cpp" - "xrstring.h" -) - -set(TEXT - "Text/StringConversion.cpp" - "Text/StringConversion.hpp" -) - -set(THREADING - "Threading/Event.cpp" - "Threading/Event.hpp" - "Threading/Lock.cpp" - "Threading/Lock.hpp" - "Threading/ParallelFor.hpp" - "Threading/ParallelForEach.hpp" - "Threading/ScopeLock.cpp" - "Threading/ScopeLock.hpp" - "Threading/Task.cpp" - "Threading/Task.hpp" - "Threading/TaskManager.cpp" - "Threading/TaskManager.hpp" -) - -set(THREADING_UTIL - "Threading/ThreadUtil.cpp" - "Threading/ThreadUtil.h" -) - -set(XML - "XML/XMLDocument.cpp" - "XML/XMLDocument.hpp" -) - -set(XML_TINY_XML - "XML/tinystr.cpp" - "XML/tinystr.h" - "XML/tinyxml.cpp" - "XML/tinyxmlerror.cpp" - "XML/tinyxml.h" - "XML/tinyxmlparser.cpp" -) - -source_group("Animation" FILES ${ANIMATION}) -source_group("Common" FILES ${COMMON}) -source_group("Common\\Object" FILES ${COMMON_OBJECT}) -source_group("Compression\\lz" FILES ${COMPRESSION_LZ}) -source_group("Compression\\lzo" FILES ${COMPRESSION_LZO}) -source_group("Compression\\ppmd" FILES ${COMPRESSION_PPMD}) -source_group("Compression\\ppmd\\common" FILES ${COMPRESSION_PPMD_COMMON}) -source_group("Compression\\ppmd\\core" FILES ${COMPRESSION_PPMD_CORE}) -source_group("Compression\\ppmd\\core\\allocator" FILES ${COMPRESSION_PPMD_CORE_ALLOCATOR}) -source_group("Compression\\ppmd\\stream" FILES ${COMPRESSION_PPMD_STREAM}) -source_group("Containers" FILES ${CONTAINERS}) -source_group("Crypto" FILES ${CRYPTO}) -source_group("Debug core" FILES ${DEBUG_CORE}) -#source_group("Debug core\\DxErr" FILES ${DEBUG_CORE_DXERR}) -source_group("Events" FILES ${EVENTS}) -source_group("FMesh" FILES ${FMESH}) -source_group("FS" FILES ${FS}) -source_group("FS\\file_stream_reader" FILES ${FS_FILE_STREAM_READER}) -source_group("FS\\stream_reader" FILES ${FS_STREAM_READER}) -source_group("intrusive_ptr" FILES ${INTRUSIVE_PTR}) -source_group("Kernel" FILES ${KERNEL}) -source_group("Kernel\\Common" FILES ${KERNEL_COMMON}) -source_group("Math" FILES ${MATH}) -source_group("Math\\Extensions" FILES ${MATH_EXTENSIONS}) -source_group("Math\\Extensions\\buffer_vector" FILES ${MATH_EXTENSIONS_BUFFER_VECTOR}) -source_group("Math\\RNG" FILES ${MATH_RNG}) -source_group("Math\\STLext" FILES ${MATH_STLEXT}) -source_group("Media" FILES ${MEDIA}) -source_group("Memory" FILES ${MEMORY}) -source_group("OS" FILES ${OS}) -source_group("PCH" FILES ${PCH}) -source_group("PostProcess" FILES ${POSTPROCESS}) -source_group("shared memory/string library" FILES ${SHARED_MEMORY_STRING_LIBRARY}) -source_group("Text" FILES ${TEXT}) -source_group("Threading" FILES ${THREADING}) -source_group("Threading\\Util" FILES ${THREADING_UTIL}) -source_group("XML" FILES ${XML}) -source_group("XML\\TinyXML" FILES ${XML_TINY_XML}) - -set(SRC_FILES - ${ANIMATION} - ${COMMON} - ${COMMON_OBJECT} - ${COMPRESSION_LZ} - ${COMPRESSION_LZO} - ${COMPRESSION_PPMD} - ${COMPRESSION_PPMD_COMMON} - ${COMPRESSION_PPMD_CORE} - ${COMPRESSION_PPMD_CORE_ALLOCATOR} - ${COMPRESSION_PPMD_STREAM} - ${CONTAINERS} - ${CRYPTO} - ${EVENTS} - ${DEBUG_CORE} - ${FMESH} - ${FS} - ${FS_FILE_STREAM_READER} - ${FS_STREAM_READER} - ${INTRUSIVE_PTR} - ${KERNEL} - ${KERNEL_COMMON} - ${MATH} - ${MATH_EXTENSIONS} - ${MATH_EXTENSIONS_BUFFER_VECTOR} - ${MATH_RNG} - ${MATH_STLEXT} - ${MEDIA} - ${MEMORY} - ${OS} - ${PCH} - ${POSTPROCESS} - ${SHARED_MEMORY_STRING_LIBRARY} - ${TEXT} - ${THREADING} - ${THREADING_UTIL} - ${XML} - ${XML_TINY_XML} -) - -if (PROJECT_PLATFORM_ARM OR PROJECT_PLATFORM_ARM64) - list(REMOVE_ITEM SRC_FILES "Math/PLC_SSE.cpp") - list(REMOVE_ITEM SRC_FILES "Math/PLC_SSE.hpp") -endif() - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} - PUBLIC - ${SDL2_INCLUDE_DIRS} +target_sources_grouped( + TARGET xrCore + NAME "Events" + FILES + Events/Notifier.h +) + +target_sources_grouped( + TARGET xrCore + NAME "FMesh" + FILES + FMesh.cpp + FMesh.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "FS" + FILES + FileCRC32.cpp + FileCRC32.h + FileSystem.cpp + FileSystem.h + FileSystem_borland.cpp + FS.cpp + FS.h + FS_impl.h + FS_internal.h + LocatorAPI.cpp + LocatorAPI.h + LocatorAPI_auth.cpp + LocatorAPI_defs.cpp + LocatorAPI_defs.h + log.cpp + log.h + NET_utils.cpp + net_utils.h + xr_ini.cpp + xr_ini.h +) + +target_sources_grouped( + TARGET xrCore + NAME "FS\\file_stream_reader" + FILES + file_stream_reader.cpp + file_stream_reader.h +) + +target_sources_grouped( + TARGET xrCore + NAME "FS\\stream_reader" + FILES + stream_reader.cpp + stream_reader.h + stream_reader_inline.h +) + +target_sources_grouped( + TARGET xrCore + NAME "intrusive_ptr" + FILES + intrusive_ptr.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Kernel" + FILES + cdecl_cast.hpp + FTimer.cpp + FTimer.h + ModuleLookup.cpp + ModuleLookup.hpp + resource.h + xr_shortcut.h + xrCore.cpp + xrCore.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Kernel\\Common" + FILES + ../Common/_d3d_extensions.h + ../Common/GUID.hpp + ../Common/LevelStructure.hpp + ../Common/Util.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Math" + FILES + _bitwise.h + _color.h + _compressed_normal.cpp + _compressed_normal.h + _cylinder.cpp + _cylinder.h + _fbox.h + _fbox2.h + _flags.h + _math.cpp + _math.h + _matrix.h + _matrix33.h + _obb.h + _plane.h + _plane2.h + _quaternion.h + _random.h + _rect.h + _sphere.cpp + _sphere.h + _vector2.h + _vector3d.h + _vector3d_ext.h + _vector4.h + dump_string.cpp + dump_string.h + math_constants.h + vector.h + xr_types.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Math\\Extensions" + FILES + #ChooseTypes.H + #client_id.h + _std_extensions.cpp + _std_extensions.h + _stl_extensions.h + clsid.cpp + clsid.h + fastdelegate.h + xr_token.cpp + xr_token.h + xr_trims.cpp + xr_trims.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Math\\Extensions\\buffer_vector" + FILES + buffer_vector.h + buffer_vector_inline.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Math\\RNG" + FILES + Math/Random32.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Math\\STLext" + FILES + FixedVector.h + xrPool.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Media" + FILES + Media/Image.cpp + Media/Image.hpp + Media/ImageJPEG.cpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Memory" + FILES + Memory/xalloc.h + xrMemory.cpp + xrMemory.h + #Memory/xrMemory_align.cpp + #Memory/xrMemory_align.h +) + +target_sources_grouped( + TARGET xrCore + NAME "OS" + FILES + os_clipboard.cpp + os_clipboard.h +) + +target_sources_grouped( + TARGET xrCore + NAME "PCH" + FILES + stdafx.cpp + stdafx.h +) + +target_sources_grouped( + TARGET xrCore + NAME "PostProcess" + FILES + PostProcess/PostProcess.cpp + PostProcess/PostProcess.hpp + PostProcess/PPInfo.cpp + PostProcess/PPInfo.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "shared memory/string library" + FILES + crc32.cpp + string_concatenations.cpp + string_concatenations.h + string_concatenations_inline.h + xr_resource.h + xr_shared.cpp + xr_shared.h + xrsharedmem.cpp + xrsharedmem.h + xrstring.cpp + xrstring.h +) + +target_sources_grouped( + TARGET xrCore + NAME "Text" + FILES + Text/StringConversion.cpp + Text/StringConversion.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Threading" + FILES + Threading/Event.cpp + Threading/Event.hpp + Threading/Lock.cpp + Threading/Lock.hpp + Threading/ParallelFor.hpp + Threading/ParallelForEach.hpp + Threading/ScopeLock.cpp + Threading/ScopeLock.hpp + Threading/Task.cpp + Threading/Task.hpp + Threading/TaskManager.cpp + Threading/TaskManager.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "Threading\\Util" + FILES + Threading/ThreadUtil.cpp + Threading/ThreadUtil.h +) + +target_sources_grouped( + TARGET xrCore + NAME "XML" + FILES + XML/XMLDocument.cpp + XML/XMLDocument.hpp +) + +target_sources_grouped( + TARGET xrCore + NAME "XML\\TinyXML" + FILES + XML/tinystr.cpp + XML/tinystr.h + XML/tinyxml.cpp + XML/tinyxmlerror.cpp + XML/tinyxml.h + XML/tinyxmlparser.cpp +) + +target_include_directories(xrCore PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/mimalloc/include - $<$:${JPEG_INCLUDE_DIRS}> - ${LZO_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals/mimalloc/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrCore PUBLIC pthread $<$:execinfo> - ${SDL2_LIBRARIES} + SDL2::SDL2 + PRIVATE xrMiscMath dl $<$:mimalloc> - $<$:${JPEG_LIBRARIES}> - ${LZO_LIBRARIES} + $<$:JPEG::JPEG> + LZO::LZO ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrCore PRIVATE - -DXRCORE_EXPORTS - -DCI=$ENV{CI} - -DTRAVIS=$ENV{TRAVIS} - -DTRAVIS_BUILD_ID=$ENV{TRAVIS_BUILD_ID} - -DTRAVIS_BUILD_NUMBER=$ENV{TRAVIS_BUILD_NUMBER} - -DTRAVIS_REPO_SLUG=$ENV{TRAVIS_REPO_SLUG} - -DGITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} - -DGITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} - -DGITHUB_RUN_NUMBER=$ENV{GITHUB_RUN_NUMBER} - -DGITHUB_REPOSITORY=$ENV{GITHUB_REPOSITORY} - -DGIT_INFO_CURRENT_COMMIT=${GIT_SHA1} - -DGIT_INFO_CURRENT_BRANCH=${GIT_BRANCH} - -DCMAKE_INSTALL_FULL_DATAROOTDIR=${CMAKE_INSTALL_FULL_DATAROOTDIR} -) - -set_target_properties(${PROJECT_NAME} PROPERTIES + XRCORE_EXPORTS + CI=$ENV{CI} + TRAVIS=$ENV{TRAVIS} + TRAVIS_BUILD_ID=$ENV{TRAVIS_BUILD_ID} + TRAVIS_BUILD_NUMBER=$ENV{TRAVIS_BUILD_NUMBER} + TRAVIS_REPO_SLUG=$ENV{TRAVIS_REPO_SLUG} + GITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} + GITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} + GITHUB_RUN_NUMBER=$ENV{GITHUB_RUN_NUMBER} + GITHUB_REPOSITORY=$ENV{GITHUB_REPOSITORY} + GIT_INFO_CURRENT_COMMIT=${GIT_SHA1} + GIT_INFO_CURRENT_BRANCH=${GIT_BRANCH} + CMAKE_INSTALL_FULL_DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}" +) + +if (MEMORY_ALLOCATOR STREQUAL "mimalloc") + target_compile_definitions(xrCore PRIVATE USE_MIMALLOC) +else() + target_compile_definitions(xrCore PRIVATE USE_PURE_ALLOC) +endif() + +set_target_properties(xrCore PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrCore PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrCore LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index 9d8f275e779..eca685c6821 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -1,436 +1,472 @@ -project(xrEngine) - -set(EDITOR_SRC - "editor_base.cpp" - "editor_base.h" - "editor_base_input.cpp" - "editor_helper.cpp" - "editor_helper.h" - "editor_weather.cpp" -) - -set(ENGINE_SRC - "Properties.h" - "pure.cpp" - "pure.h" - "std_classes.h" -) - -set(ENGINE_CONSOLE_SRC - "XR_IOConsole.cpp" - "XR_IOConsole.h" - "XR_IOConsole_callback.cpp" - "XR_IOConsole_control.cpp" - "XR_IOConsole_get.cpp" -) - -set(ENGINE_CONSOLE_COMMANDS_SRC - "xr_ioc_cmd.cpp" - "xr_ioc_cmd.h" -) - -set(ENGINE_CORE_SRC - "Engine.cpp" - "Engine.h" - "EngineAPI.cpp" - "EngineAPI.h" - "EventAPI.cpp" - "EventAPI.h" - "mailSlot.cpp" -) - -set(ENGINE_NOISE_SRC - "perlin.cpp" - "perlin.h" -) - -set(ENGINE_TEXT_EDITOR_EDIT_ACTIONS_SRC - "edit_actions.cpp" - "edit_actions.h" -) - -set(ENGINE_TEXT_EDITOR_LINE_EDITOR_SRC - "line_editor.cpp" - "line_editor.h" -) - -set(ENGINE_TEXT_EDITOR_LINE_EDITOR_CONTROL_SRC - "line_edit_control.cpp" - "line_edit_control.h" -) - -set(ENGINE_GAME_API_ANIMATOR_SRC - "ObjectAnimator.cpp" - "ObjectAnimator.h" -) - -set(ENGINE_GAME_API_CAMERAS_SRC - "CameraBase.cpp" - "CameraBase.h" - "CameraDefs.h" - "CameraManager.cpp" - "CameraManager.h" - "Effector.cpp" - "Effector.h" - "EffectorPP.cpp" - "EffectorPP.h" -) - -set(ENGINE_GAME_API_COLLISION_SRC - "cf_dynamic_mesh.cpp" - "cf_dynamic_mesh.h" - "xr_collide_form.cpp" - "xr_collide_form.h" -) - -set(ENGINE_GAME_API_DEBUG_SRC - "ObjectDump.cpp" - "ObjectDump.h" -) - -set(ENGINE_GAME_API_DEMO_SRC - "FDemoPlay.cpp" - "FDemoPlay.h" - "FDemoRecord.cpp" - "FDemoRecord.h" -) - -set(ENGINE_GAME_API_ENVIRONMENT_SRC - "Environment.cpp" - "Environment.h" - "Environment_misc.cpp" - "Environment_render.cpp" - "xrHemisphere.cpp" - "xrHemisphere.h" -) - -set(ENGINE_GAME_API_ENVIRONMENT_EFFECTS_SRC - "Rain.cpp" - "Rain.h" - "thunderbolt.cpp" - "thunderbolt.h" - "xr_efflensflare.cpp" - "xr_efflensflare.h" -) - -set(ENGINE_GAME_API_FEELERS_SRC - "Feel_Sound.h" - "Feel_Touch.cpp" - "Feel_Touch.h" - "Feel_Vision.cpp" - "Feel_Vision.h" -) - -set(ENGINE_GAME_API_HUD_SRC - "CustomHUD.cpp" - "CustomHUD.h" -) - -set(ENGINE_GAME_API_LEVEL_SRC - "IGame_Level.cpp" - "IGame_Level.h" - "IGame_Level_check_textures.cpp" -) - -set(ENGINE_GAME_API_LEVEL_CONTROLLER_SRC - "xr_level_controller.cpp" - "xr_level_controller.h" -) - -set(ENGINE_GAME_API_LEVEL_CONTROLLER_KEY_BINDINGS_SRC - "key_binding_registrator_script.cpp" -) - -set(ENGINE_GAME_API_MATERIALSYSTEM_SRC - "GameMtlLib.cpp" - "GameMtlLib.h" - "GameMtlLib_Engine.cpp" -) - -set(ENGINE_GAME_API_OBJECTS_SRC - "IGame_ObjectPool.cpp" - "IGame_ObjectPool.h" - "IGame_Persistent.cpp" - "IGame_Persistent.h" - "IGame_Persistent_Effects.cpp" - "pure_relcase.cpp" - "pure_relcase.h" - "xr_object.h" - "xr_object_list.cpp" - "xr_object_list.h" -) - -set(ENGINE_GAME_API_STRING_TABLE_SRC - "StringTable/StringTable.cpp" - "StringTable/StringTable.h" -) - -set(GENERAL_SRC - "defines.cpp" - "defines.h" - "embedded_resources_management.h" - "main.cpp" - "main.h" - "mp_logging.h" - "splash.cpp" - "splash.h" - "stdafx.cpp" - "stdafx.h" - "x_ray.cpp" - "x_ray.h" -) - -set(GENERAL_PROFILER_SRC - "profiler.cpp" - "profiler.h" - "profiler_inline.h" -) - -set(INTERFACES_COLLIDABLE_SRC - "ICollidable.cpp" - "ICollidable.h" -) - -set(INTERFACES_ILOADINGSCREEN_SRC - "ILoadingScreen.h" -) - -set(INTERFACES_INPUT_SRC - "IInputReceiver.cpp" - "IInputReceiver.h" - "xr_input.cpp" - "xr_input.h" -) - -set(INTERFACES_PHYSICS_SRC - "IObjectPhysicsCollision.h" - "IPHdebug.h" - "IPhysicsGeometry.h" - "IPhysicsShell.h" - "phdebug.cpp" -) - -set(INTERFACES_RENDER_SRC - "IRenderable.cpp" - "IRenderable.h" - "Render.cpp" - "Render.h" -) +add_library(xrEngine SHARED) + +target_sources_grouped( + TARGET xrEngine + NAME "editor" + FILES + editor_base.cpp + editor_base.h + editor_base_input.cpp + editor_helper.cpp + editor_helper.h + editor_weather.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine" + FILES + Properties.h + pure.cpp + pure.h + std_classes.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Console" + FILES + XR_IOConsole.cpp + XR_IOConsole.h + XR_IOConsole_callback.cpp + XR_IOConsole_control.cpp + XR_IOConsole_get.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Console\\commands" + FILES + xr_ioc_cmd.cpp + xr_ioc_cmd.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Core" + FILES + Engine.cpp + Engine.h + EngineAPI.cpp + EngineAPI.h + EventAPI.cpp + EventAPI.h + mailSlot.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Noise" + FILES + perlin.cpp + perlin.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\text_editor\\edit_actions" + FILES + edit_actions.cpp + edit_actions.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\text_editor\\line_editor" + FILES + line_editor.cpp + line_editor.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\text_editor\\line_editor_control" + FILES + line_edit_control.cpp + line_edit_control.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Animator" + FILES + ObjectAnimator.cpp + ObjectAnimator.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Cameras" + FILES + CameraBase.cpp + CameraBase.h + CameraDefs.h + CameraManager.cpp + CameraManager.h + Effector.cpp + Effector.h + EffectorPP.cpp + EffectorPP.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Collision" + FILES + cf_dynamic_mesh.cpp + cf_dynamic_mesh.h + xr_collide_form.cpp + xr_collide_form.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Debug" + FILES + ObjectDump.cpp + ObjectDump.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Demo" + FILES + FDemoPlay.cpp + FDemoPlay.h + FDemoRecord.cpp + FDemoRecord.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Environment" + FILES + Environment.cpp + Environment.h + Environment_misc.cpp + Environment_render.cpp + xrHemisphere.cpp + xrHemisphere.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Environment\\Effects" + FILES + Rain.cpp + Rain.h + thunderbolt.cpp + thunderbolt.h + xr_efflensflare.cpp + xr_efflensflare.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Feelers" + FILES + Feel_Sound.h + Feel_Touch.cpp + Feel_Touch.h + Feel_Vision.cpp + Feel_Vision.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\HUD" + FILES + CustomHUD.cpp + CustomHUD.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Level" + FILES + IGame_Level.cpp + IGame_Level.h + IGame_Level_check_textures.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Level Controller" + FILES + xr_level_controller.cpp + xr_level_controller.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Level Controller\\KeyBindings" + FILES + key_binding_registrator_script.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\MaterialSystem" + FILES + GameMtlLib.cpp + GameMtlLib.h + GameMtlLib_Engine.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\Objects" + FILES + IGame_ObjectPool.cpp + IGame_ObjectPool.h + IGame_Persistent.cpp + IGame_Persistent.h + IGame_Persistent_Effects.cpp + pure_relcase.cpp + pure_relcase.h + xr_object.h + xr_object_list.cpp + xr_object_list.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Engine\\Game API\\StringTable" + FILES + StringTable/StringTable.cpp + StringTable/StringTable.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "General" + FILES + defines.cpp + defines.h + embedded_resources_management.h + main.cpp + main.h + mp_logging.h + splash.cpp + splash.h + stdafx.cpp + stdafx.h + x_ray.cpp + x_ray.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "General\\Profiler" + FILES + profiler.cpp + profiler.h + profiler_inline.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\Collidable" + FILES + ICollidable.cpp + ICollidable.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\ILoadingScreen" + FILES + ILoadingScreen.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\Input" + FILES + IInputReceiver.cpp + IInputReceiver.h + xr_input.cpp + xr_input.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\Physics" + FILES + IObjectPhysicsCollision.h + IPHdebug.h + IPhysicsGeometry.h + IPhysicsShell.h + phdebug.cpp +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\Render" + FILES + IRenderable.cpp + IRenderable.h + Render.cpp + Render.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Interfaces\\Sheduler" + FILES + ISheduled.cpp + ISheduled.h + xrSheduler.cpp + xrSheduler.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "OpenAutomate" + FILES + xrSASH.cpp + xrSASH.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Device" + FILES + device.cpp + device.h + Device_create.cpp + Device_destroy.cpp + Device_Initialize.cpp + Device_mode.cpp + Device_overdraw.cpp + IPerformanceAlert.hpp + PerformanceAlert.cpp + PerformanceAlert.hpp + StatGraph.cpp + StatGraph.h + Stats.cpp + Stats.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Execution & 3D\\Shaders" + FILES + WaveForm.h +) + +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Execution & 3D\\Shaders\\Textures" + FILES + #tntQAVI.cpp + #tntQAVI.h + xrImage_Resampler.cpp + xrImage_Resampler.h + xrTheora_Stream.cpp + xrTheora_Stream.h + xrTheora_Surface.cpp + xrTheora_Surface.h +) + +#target_sources_grouped( +# TARGET xrEngine +# NAME "Render\\Execution & 3D\\TextConsole" +# FILES +# Text_Console.cpp +# Text_Console.h +# Text_Console_WndProc.cpp +#) -set(INTERFACES_SHEDULER_SRC - "ISheduled.cpp" - "ISheduled.h" - "xrSheduler.cpp" - "xrSheduler.h" +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Font output" + FILES + GameFont.cpp + GameFont.h + IGameFont.hpp ) -set(OPEN_AUTOMATE_SRC - "xrSASH.cpp" - "xrSASH.h" +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Lighting" + FILES + LightAnimLibrary.cpp + LightAnimLibrary.h ) -set(RENDER_DEVICE_SRC - "device.cpp" - "device.h" - "Device_create.cpp" - "Device_destroy.cpp" - "Device_Initialize.cpp" - "Device_mode.cpp" - "Device_overdraw.cpp" - "IPerformanceAlert.hpp" - "PerformanceAlert.cpp" - "PerformanceAlert.hpp" - "StatGraph.cpp" - "StatGraph.h" - "Stats.cpp" - "Stats.h" +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Particle system" + FILES + PS_instance.cpp + PS_instance.h ) -set(RENDER_EXECUTION_AND_3D_SHADERS_SRC - "WaveForm.h" -) - -set(RENDER_EXECUTION_AND_3D_SHADERS_TEXTURES_SRC - #"tntQAVI.cpp" - #"tntQAVI.h" - "xrImage_Resampler.cpp" - "xrImage_Resampler.h" - "xrTheora_Stream.cpp" - "xrTheora_Stream.h" - "xrTheora_Surface.cpp" - "xrTheora_Surface.h" +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Visibility" + FILES + ShadersExternalData.h + vis_common.h + vis_object_data.h ) -#set(RENDER_EXECUTION_AND_3D_TEXT_CONSOLE_SRC -# "Text_Console.cpp" -# "Text_Console.h" -# "Text_Console_WndProc.cpp" -#) - -set(RENDER_FONT_OUTPUT_SRC - "GameFont.cpp" - "GameFont.h" - "IGameFont.hpp" -) - -set(RENDER_LIGHTING_SRC - "LightAnimLibrary.cpp" - "LightAnimLibrary.h" -) - -set(RENDER_PARTICLE_SYSTEM_SRC - "PS_instance.cpp" - "PS_instance.h" -) - -set(RENDER_VISIBILITY_SRC - "ShadersExternalData.h" - "vis_common.h" - "vis_object_data.h" -) - -set(RENDER_VISUALS_SKELETON_SRC - "EnnumerateVertices.h" -) - -source_group("editor" FILES ${EDITOR_SRC}) -source_group("Engine" FILES ${ENGINE_SRC}) -source_group("Engine\\Console" FILES ${ENGINE_CONSOLE_SRC}) -source_group("Engine\\Console\\commands" FILES ${ENGINE_CONSOLE_COMMANDS_SRC}) -source_group("Engine\\Core" FILES ${ENGINE_CORE_SRC}) -source_group("Engine\\Noise" FILES ${ENGINE_NOISE_SRC}) -source_group("Engine\\text_editor\\edit_actions" FILES ${ENGINE_TEXT_EDITOR_EDIT_ACTIONS_SRC}) -source_group("Engine\\text_editor\\line_editor" FILES ${ENGINE_TEXT_EDITOR_LINE_EDITOR_SRC}) -source_group("Engine\\text_editor\\line_editor_control" FILES ${ENGINE_TEXT_EDITOR_LINE_EDITOR_CONTROL_SRC}) -source_group("Engine\\Game API\\Animator" FILES ${ENGINE_GAME_API_ANIMATOR_SRC}) -source_group("Engine\\Game API\\Cameras" FILES ${ENGINE_GAME_API_CAMERAS_SRC}) -source_group("Engine\\Game API\\Collision" FILES ${ENGINE_GAME_API_COLLISION_SRC}) -source_group("Engine\\Game API\\Debug" FILES ${ENGINE_GAME_API_DEBUG_SRC}) -source_group("Engine\\Game API\\Demo" FILES ${ENGINE_GAME_API_DEMO_SRC}) -source_group("Engine\\Game API\\Environment" FILES ${ENGINE_GAME_API_ENVIRONMENT_SRC}) -source_group("Engine\\Game API\\Environment\\Effects" FILES ${ENGINE_GAME_API_ENVIRONMENT_EFFECTS_SRC}) -source_group("Engine\\Game API\\Feelers" FILES ${ENGINE_GAME_API_FEELERS_SRC}) -source_group("Engine\\Game API\\HUD" FILES ${ENGINE_GAME_API_HUD_SRC}) -source_group("Engine\\Game API\\Level" FILES ${ENGINE_GAME_API_LEVEL_SRC}) -source_group("Engine\\Game API\\Level Controller" FILES ${ENGINE_GAME_API_LEVEL_CONTROLLER_SRC}) -source_group("Engine\\Game API\\Level Controller\\KeyBindings" FILES ${ENGINE_GAME_API_LEVEL_CONTROLLER_KEY_BINDINGS_SRC}) -source_group("Engine\\Game API\\MaterialSystem" FILES ${ENGINE_GAME_API_MATERIALSYSTEM_SRC}) -source_group("Engine\\Game API\\Objects" FILES ${ENGINE_GAME_API_OBJECTS_SRC}) -source_group("Engine\\Game API\\StringTable" FILES ${ENGINE_GAME_API_STRING_TABLE_SRC}) -source_group("General" FILES ${GENERAL_SRC}) -source_group("General\\Profiler" FILES ${GENERAL_PROFILER_SRC}) -source_group("Interfaces\\Collidable" FILES ${INTERFACES_COLLIDABLE_SRC}) -source_group("Interfaces\\ILoadingScreen" FILES ${INTERFACES_ILOADINGSCREEN_SRC}) -source_group("Interfaces\\Input" FILES ${INTERFACES_INPUT_SRC}) -source_group("Interfaces\\Physics" FILES ${INTERFACES_PHYSICS_SRC}) -source_group("Interfaces\\Render" FILES ${INTERFACES_RENDER_SRC}) -source_group("Interfaces\\Sheduler" FILES ${INTERFACES_SHEDULER_SRC}) -source_group("Interfaces\\Sound") -source_group("Interfaces\\SPATIAL") -source_group("OpenAutomate" FILES ${OPEN_AUTOMATE_SRC}) -source_group("Render\\Device" FILES ${RENDER_DEVICE_SRC}) -source_group("Render\\Execution & 3D\\Shaders" FILES ${RENDER_EXECUTION_AND_3D_SHADERS_SRC}) -source_group("Render\\Execution & 3D\\Shaders\\Textures" FILES ${RENDER_EXECUTION_AND_3D_SHADERS_TEXTURES_SRC}) -#source_group("Render\\Execution & 3D\\TextConsole" FILES ${RENDER_EXECUTION_AND_3D_TEXT_CONSOLE_SRC}) -source_group("Render\\Font output" FILES ${RENDER_FONT_OUTPUT_SRC}) -source_group("Render\\Lighting" FILES ${RENDER_LIGHTING_SRC}) -source_group("Render\\Particle system" FILES ${RENDER_PARTICLE_SYSTEM_SRC}) -source_group("Render\\Visibility" FILES ${RENDER_VISIBILITY_SRC}) -source_group("Render\\Visuals\\Skeleton" FILES ${RENDER_VISUALS_SKELETON_SRC}) - -add_library(${PROJECT_NAME} SHARED - ${EDITOR_SRC} - ${ENGINE_SRC} - ${ENGINE_CONSOLE_SRC} - ${ENGINE_CONSOLE_COMMANDS_SRC} - ${ENGINE_CORE_SRC} - ${ENGINE_NOISE_SRC} - ${ENGINE_TEXT_EDITOR_EDIT_ACTIONS_SRC} - ${ENGINE_TEXT_EDITOR_LINE_EDITOR_SRC} - ${ENGINE_TEXT_EDITOR_LINE_EDITOR_CONTROL_SRC} - ${ENGINE_GAME_API_ANIMATOR_SRC} - ${ENGINE_GAME_API_CAMERAS_SRC} - ${ENGINE_GAME_API_COLLISION_SRC} - ${ENGINE_GAME_API_DEBUG_SRC} - ${ENGINE_GAME_API_DEMO_SRC} - ${ENGINE_GAME_API_ENVIRONMENT_SRC} - ${ENGINE_GAME_API_ENVIRONMENT_EFFECTS_SRC} - ${ENGINE_GAME_API_FEELERS_SRC} - ${ENGINE_GAME_API_HUD_SRC} - ${ENGINE_GAME_API_LEVEL_SRC} - ${ENGINE_GAME_API_LEVEL_CONTROLLER_SRC} - ${ENGINE_GAME_API_LEVEL_CONTROLLER_KEY_BINDINGS_SRC} - ${ENGINE_GAME_API_MATERIALSYSTEM_SRC} - ${ENGINE_GAME_API_OBJECTS_SRC} - ${ENGINE_GAME_API_STRING_TABLE_SRC} - ${GENERAL_SRC} - ${GENERAL_PROFILER_SRC} - ${INTERFACES_COLLIDABLE_SRC} - ${INTERFACES_ILOADINGSCREEN_SRC} - ${INTERFACES_INPUT_SRC} - ${INTERFACES_PHYSICS_SRC} - ${INTERFACES_RENDER_SRC} - ${INTERFACES_SHEDULER_SRC} - ${OPEN_AUTOMATE_SRC} - ${RENDER_DEVICE_SRC} - ${RENDER_EXECUTION_AND_3D_SHADERS_SRC} - ${RENDER_EXECUTION_AND_3D_SHADERS_TEXTURES_SRC} - #${RENDER_EXECUTION_AND_3D_TEXT_CONSOLE_SRC} - ${RENDER_FONT_OUTPUT_SRC} - ${RENDER_LIGHTING_SRC} - ${RENDER_PARTICLE_SYSTEM_SRC} - ${RENDER_VISIBILITY_SRC} - ${RENDER_VISUALS_SKELETON_SRC} +target_sources_grouped( + TARGET xrEngine + NAME "Render\\Visuals\\Skeleton" + FILES + EnnumerateVertices.h ) # XXX: This is only used in utils, should be moved somewhere to utils -#set(SRC_FILES -# "xrLoadSurface.cpp" +#target_sources_grouped( +# TARGET xrEngine +# NAME "" +# FILES +# xrLoadSurface.cpp #) -target_include_directories(${PROJECT_NAME} +target_include_directories(xrEngine PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals/imgui" + "${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrEngine PUBLIC xrMiscMath + PRIVATE xrAPI xrCDB xrCore - xrLuabind xrSound xrScriptEngine xrNetServer xrImGui - ${LUA_LIBRARIES} - ${SDL2_LIBRARIES} ${OPENAL_LIBRARY} ${OGG_LIBRARIES} Theora::Theora ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrEngine PRIVATE - -DENGINE_BUILD + ENGINE_BUILD + PURE_DYNAMIC_CAST ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrEngine PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrEngine PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrEngine LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 5d3e2556a38..4119b41c997 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -1,2638 +1,2631 @@ -project(xrGame) +add_library(xrGame SHARED) -set(SRC_FILES - "abstract_location_selector.h" - "abstract_location_selector_inline.h" - "abstract_path_manager.h" - "abstract_path_manager_inline.h" - "account_manager_console.cpp" - "account_manager_console.h" - "account_manager.cpp" - "account_manager.h" - "account_manager_script.cpp" - "accumulative_states.h" - "action_base.h" - "action_base_inline.h" - "action_base_script.cpp" - "action_management_config.h" - "action_planner_action.h" - "action_planner_action_inline.h" - "action_planner_action_script.cpp" - "action_planner_action_script.h" - "action_planner_action_script_inline.h" - "action_planner.h" - "action_planner_inline.h" - "action_planner_script.cpp" - "action_planner_script.h" - "action_planner_script_inline.h" - "action_script_base.h" - "action_script_base_inline.h" - "ActivatingCharCollisionDelay.cpp" - "ActivatingCharCollisionDelay.h" - "ActorAnimation.cpp" - "ActorAnimation.h" - "actor_anim_defs.h" - "ActorCameras.cpp" - "actor_communication.cpp" - "ActorCondition.cpp" - "ActorCondition.h" - "Actor.cpp" - "actor_defs.h" - "ActorEffector.cpp" - "ActorEffector.h" - "ActorEffector_script.cpp" - "Actor_Events.cpp" - "Actor_Feel.cpp" - "Actor_Flags.h" - "ActorFollowers.cpp" - "ActorFollowers.h" - "Actor.h" - "ActorHelmet.cpp" - "ActorHelmet.h" - "ActorBackpack.cpp" - "ActorBackpack.h" - "ActorInput.cpp" - "actor_input_handler.cpp" - "actor_input_handler.h" - "actor_memory.cpp" - "actor_memory.h" - "ActorMountedWeapon.cpp" - "Actor_Movement.cpp" - "actor_mp_client.cpp" - "actor_mp_client_export.cpp" - "actor_mp_client.h" - "actor_mp_client_import.cpp" - "actor_mp_server.cpp" - "actor_mp_server_export.cpp" - "actor_mp_server.h" - "actor_mp_server_import.cpp" - "actor_mp_state.cpp" - "actor_mp_state.h" - "actor_mp_state_inline.h" - "Actor_Network.cpp" - "actor_script.cpp" - "Actor_Sleep.cpp" - "actor_statistic_defs.h" - "actor_statistic_mgr.cpp" - "actor_statistic_mgr.h" - "ActorVehicle.cpp" - "Actor_Weapon.cpp" - "AdvancedDetector.cpp" - "AdvancedDetector.h" - "agent_corpse_manager.cpp" - "agent_corpse_manager.h" - "agent_corpse_manager_inline.h" - "agent_enemy_manager.cpp" - "agent_enemy_manager.h" - "agent_enemy_manager_inline.h" - "agent_explosive_manager.cpp" - "agent_explosive_manager.h" - "agent_explosive_manager_inline.h" - "agent_location_manager.cpp" - "agent_location_manager.h" - "agent_location_manager_inline.h" - "agent_manager_actions.cpp" - "agent_manager_actions.h" - "agent_manager.cpp" - "agent_manager.h" - "agent_manager_inline.h" - "agent_manager_planner.cpp" - "agent_manager_planner.h" - "agent_manager_properties.cpp" - "agent_manager_properties.h" - "agent_manager_properties_inline.h" - "agent_manager_space.h" - "agent_member_manager.cpp" - "agent_member_manager.h" - "agent_member_manager_inline.h" - "agent_memory_manager.cpp" - "agent_memory_manager.h" - "agent_memory_manager_inline.h" - "ai_crow_script.cpp" - "ai_debug.h" - "ai_debug_variables.cpp" - "ai_debug_variables.h" - "aimers_base.cpp" - "aimers_base.h" - "aimers_base_inline.h" - "aimers_bone.h" - "aimers_bone_inline.h" - "aimers_weapon.cpp" - "aimers_weapon.h" - "aimers_weapon_inline.h" - "ai_monster_space.h" - "ai_obstacle.cpp" - "ai_obstacle.h" - "ai_obstacle_inline.h" - "AI_PhraseDialogManager.cpp" - "AI_PhraseDialogManager.h" - "ai_sounds.cpp" - "ai_space.cpp" - "ai_space.h" - "ai_space_inline.h" - "ai_stalker_alife.cpp" - "alife_abstract_registry.h" - "alife_abstract_registry_inline.h" - "alife_anomalous_zone.cpp" - "alife_combat_manager.cpp" - "alife_combat_manager.h" - "alife_combat_manager_inline.h" - "alife_communication_manager.cpp" - "alife_communication_manager.h" - "alife_communication_manager_inline.h" - "alife_communication_space.h" - "alife_creature_abstract.cpp" - "alife_dynamic_object.cpp" - "alife_graph_registry.cpp" - "alife_graph_registry.h" - "alife_graph_registry_inline.h" - "alife_group_abstract.cpp" - "alife_group_registry.cpp" - "alife_group_registry.h" - "alife_group_registry_inline.h" - "alife_human_abstract.cpp" - "alife_human_brain_save.h" - "alife_human_brain_script.cpp" - "alife_human_object_handler.cpp" - "alife_human_object_handler.h" - "alife_human_object_handler_inline.h" - "alife_human_object_handler_save.h" - "alife_interaction_manager.cpp" - "alife_interaction_manager.h" - "alife_interaction_manager_inline.h" - "alife_level_registry.h" - "alife_level_registry_inline.h" - "alife_monster_abstract.cpp" - "alife_monster_base.cpp" - "alife_monster_brain_script.cpp" - "alife_monster_detail_path_manager.cpp" - "alife_monster_detail_path_manager.h" - "alife_monster_detail_path_manager_inline.h" - "alife_monster_detail_path_manager_script.cpp" - "alife_monster_movement_manager.cpp" - "alife_monster_movement_manager.h" - "alife_monster_movement_manager_inline.h" - "alife_monster_movement_manager_script.cpp" - "alife_monster_patrol_path_manager.cpp" - "alife_monster_patrol_path_manager.h" - "alife_monster_patrol_path_manager_inline.h" - "alife_monster_patrol_path_manager_script.cpp" - "alife_object.cpp" - "alife_object_registry.cpp" - "alife_object_registry.h" - "alife_object_registry_inline.h" - "alife_online_offline_group_brain.cpp" - "alife_online_offline_group_brain.h" - "alife_online_offline_group_brain_inline.h" - "alife_online_offline_group.cpp" - "alife_registry_container_composition.h" - "alife_registry_container.cpp" - "alife_registry_container.h" - "alife_registry_container_inline.h" - "alife_registry_container_space.h" - "alife_registry_wrapper.h" - "alife_registry_wrappers.h" - "alife_schedule_registry.cpp" - "alife_schedule_registry.h" - "alife_schedule_registry_inline.h" - "alife_simulator_base2.cpp" - "alife_simulator_base.cpp" - "alife_simulator_base.h" - "alife_simulator_base_inline.h" - "alife_simulator.cpp" - "alife_simulator.h" - "alife_simulator_header.cpp" - "alife_simulator_header.h" - "alife_simulator_header_inline.h" - "alife_simulator_script.cpp" - "alife_smart_terrain_registry.cpp" - "alife_smart_terrain_registry.h" - "alife_smart_terrain_registry_inline.h" - "alife_smart_terrain_task.cpp" - "alife_smart_terrain_task.h" - "alife_smart_terrain_task_inline.h" - "alife_smart_terrain_task_script.cpp" - "alife_smart_zone.cpp" - "alife_spawn_registry.cpp" - "alife_spawn_registry.h" - "alife_spawn_registry_header.cpp" - "alife_spawn_registry_header.h" - "alife_spawn_registry_header_inline.h" - "alife_spawn_registry_inline.h" - "alife_spawn_registry_spawn.cpp" - "alife_storage_manager.cpp" - "alife_storage_manager.h" - "alife_storage_manager_inline.h" - "alife_story_registry.cpp" - "alife_story_registry.h" - "alife_story_registry_inline.h" - "alife_surge_manager.cpp" - "alife_surge_manager.h" - "alife_surge_manager_inline.h" - "alife_switch_manager.cpp" - "alife_switch_manager.h" - "alife_switch_manager_inline.h" - "alife_time_manager.cpp" - "alife_time_manager.h" - "alife_time_manager_inline.h" - "alife_trader_abstract.cpp" - "alife_trader.cpp" - "alife_update_manager.cpp" - "alife_update_manager.h" - "AmebaZone.cpp" - "AmebaZone.h" - "ammunition_groups.cpp" - "ammunition_groups.h" - "animation_movement_controller.cpp" - "animation_movement_controller.h" - "animation_script_callback.cpp" - "animation_script_callback.h" - "animation_utils.cpp" - "animation_utils.h" - #"AnselManager.cpp" - #"AnselManager.h" - "anticheat_dumpable_object.h" - "antirad.cpp" - "antirad.h" - "artefact_activation.cpp" - "artefact_activation.h" - "Artefact.cpp" - "Artefact.h" - "artefact_script.cpp" - "atlas_stalkercoppc_v1.c" - "atlas_stalkercoppc_v1.h" - #"atlas_stalkercs_v1.c" - #"atlas_stalkercs_v1.h" - "atlas_submit_queue.cpp" - "atlas_submit_queue.h" - "attachable_item.cpp" - "attachable_item.h" - "attachable_item_inline.h" - "attachment_owner.cpp" - "attachment_owner.h" - "autosave_manager.cpp" - "autosave_manager.h" - "autosave_manager_inline.h" - "awards_store.cpp" - "awards_store.h" - "base_client_classes_script.cpp" - "base_client_classes_wrappers.h" - "BastArtifact.cpp" - "BastArtifact.h" - "battleye.h" - #"battleye_system.cpp" - #"battleye_system.h" - "best_scores_helper.cpp" - "best_scores_helper.h" - "best_scores_store.cpp" - "best_scores_store.h" - "BlackDrops.cpp" - "BlackDrops.h" - "BlackGraviArtifact.cpp" - "BlackGraviArtifact.h" - "black_list.cpp" - "black_list.h" - "BlockAllocator.h" - "Bolt.cpp" - "Bolt.h" - "bone_groups.cpp" - "bone_groups.h" - "BoneProtections.cpp" - "BoneProtections.h" - "BottleItem.cpp" - "BottleItem.h" - "BreakableObject.cpp" - "BreakableObject.h" - "CameraEffector.cpp" - "CameraEffector.h" - "CameraFirstEye.cpp" - "CameraFirstEye.h" - "CameraLook.cpp" - "CameraLook.h" - "CameraRecoil.h" - "CaptureBoneCallback.h" - "CarCameras.cpp" - "Car.cpp" - "CarDamageParticles.cpp" - "CarDamageParticles.h" - "CarDoors.cpp" - "CarExhaust.cpp" - "Car.h" - "CarInput.cpp" - "CarLights.cpp" - "CarLights.h" - "car_memory.cpp" - "car_memory.h" - "CarScript.cpp" - "CarSound.cpp" - "CarWeapon.cpp" - "CarWeapon.h" - "CarWheels.cpp" - "cdkey_ban_list.cpp" - "cdkey_ban_list.h" - "character_community.cpp" - "character_community.h" - "character_hit_animations.cpp" - "character_hit_animations.h" - "character_hit_animations_params.h" - "CharacterPhysicsSupport.cpp" - "CharacterPhysicsSupport.h" - "character_rank.cpp" - "character_rank.h" - "character_reputation.cpp" - "character_reputation.h" - "character_shell_control.cpp" - "character_shell_control.h" - "client_spawn_manager.cpp" - "client_spawn_manager.h" - "client_spawn_manager_inline.h" - "client_spawn_manager_script.cpp" - "ClimableObject.cpp" - "ClimableObject.h" - "command_switch_counter.h" - "configs_common.cpp" - "configs_common.h" - "configs_dumper.cpp" - "configs_dumper.h" - "configs_dump_verifyer.cpp" - "configs_dump_verifyer.h" - "console_commands.cpp" - "console_commands_mp.cpp" - "console_registrator_script.cpp" - "ContextMenu.cpp" - "ContextMenu.h" - "control_action.h" - "control_action_inline.h" - "controller_state_panic_inline.h" - "cover_evaluators.cpp" - "cover_evaluators.h" - "cover_evaluators_inline.h" - "cover_manager.cpp" - "cover_manager.h" - "cover_manager_inline.h" - "cover_point.h" - "cover_point_inline.h" - "cover_point_script.cpp" - "cta_game_artefact_activation.cpp" - "cta_game_artefact_activation.h" - "cta_game_artefact.cpp" - "cta_game_artefact.h" - "CustomDetector.cpp" - "CustomDetector.h" - "CustomMonster.cpp" - "CustomMonster.h" - "CustomMonster_inline.h" - "CustomMonster_VCPU.cpp" - "CustomOutfit_script.cpp" - "CustomOutfit.cpp" - "CustomOutfit.h" - "CustomRocket.cpp" - "CustomRocket.h" - "CustomZone.cpp" - "CustomZone.h" - "CycleConstStorage.h" - "DamagableItem.cpp" - "DamagableItem.h" - "damage_manager.cpp" - "damage_manager.h" - "danger_cover_location.cpp" - "danger_cover_location.h" - "danger_cover_location_inline.h" - "danger_explosive.cpp" - "danger_explosive.h" - "danger_explosive_inline.h" - "danger_location.cpp" - "danger_location.h" - "danger_location_inline.h" - "danger_manager.cpp" - "danger_manager.h" - "danger_manager_inline.h" - "danger_object.cpp" - "danger_object.h" - "danger_object_inline.h" - "danger_object_location.cpp" - "danger_object_location.h" - "danger_object_location_inline.h" - "date_time.cpp" - "date_time.h" - "DBG_Car.cpp" - "dbg_draw_frustum.cpp" - "death_anims.cpp" - "death_anims.h" - "death_anims_predicates.cpp" - "debug_renderer.cpp" - "debug_renderer.h" - "debug_renderer_inline.h" - "debug_text_tree.cpp" - "debug_text_tree.h" - "debug_text_tree_inline.h" - "DelayedActionFuse.cpp" - "DelayedActionFuse.h" - "DemoInfo.cpp" - "DemoInfo.h" - "DemoInfo_Loader.cpp" - "DemoInfo_Loader.h" - "DemoPLay_Control.cpp" - "DemoPlay_Control.h" - "DestroyablePhysicsObject.cpp" - "DestroyablePhysicsObject.h" - "detail_path_builder.h" - "detail_path_manager.cpp" - "detail_path_manager.h" - "detail_path_manager_inline.h" - "detail_path_manager_smooth.cpp" - "detail_path_manager_space.h" - "doors_actor.cpp" - "doors_actor.h" - "doors_door.cpp" - "doors_door.h" - "doors.h" - "doors_manager.cpp" - "doors_manager.h" - "double_shot_double_kill.cpp" - "double_shot_double_kill.h" - "DummyArtifact.cpp" - "DummyArtifact.h" - #"DynamicHeightMap.cpp" - #"DynamicHeightMap.h" - "dynamic_obstacles_avoider.cpp" - "dynamic_obstacles_avoider.h" - "dynamic_obstacles_avoider_inline.h" - "eatable_item.cpp" - "eatable_item.h" - "eatable_item_object.cpp" - "eatable_item_object.h" - "ef_base.h" - "EffectorBobbing.cpp" - "EffectorBobbing.h" - "EffectorFall.cpp" - "EffectorFall.h" - "EffectorShot.cpp" - "EffectorShot.h" - "EffectorShotX.cpp" - "EffectorShotX.h" - "EffectorZoomInertion.cpp" - "EffectorZoomInertion.h" - "ef_pattern.cpp" - "ef_pattern.h" - "ef_primary.cpp" - "ef_primary.h" - "ef_storage.cpp" - "ef_storage.h" - "ef_storage_inline.h" - "ef_storage_script.cpp" - "ElectricBall.cpp" - "ElectricBall.h" - "EliteDetector.cpp" - "EliteDetector.h" - "encyclopedia_article.cpp" - "encyclopedia_article_defs.h" - "encyclopedia_article.h" - "enemy_manager.cpp" - "enemy_manager.h" - "enemy_manager_inline.h" - "entity_alive.cpp" - "entity_alive.h" - "entity_alive_inline.h" - "EntityCondition.cpp" - "EntityCondition.h" - "EntityCondition_script.cpp" - "Entity.cpp" - "Entity.h" - "event_conditions_collection.cpp" - "event_conditions_collection.h" - "ExoOutfit.cpp" - "ExoOutfit.h" - "Explosive.cpp" - "Explosive.h" - "ExplosiveItem.cpp" - "ExplosiveItem.h" - "ExplosiveRocket.cpp" - "ExplosiveRocket.h" - "ExplosiveScript.cpp" - "F1.h" - "FadedBall.cpp" - "FadedBall.h" - "faster_than_bullets_time.cpp" - "faster_than_bullets_time.h" - "filereceiver_node.cpp" - "filereceiver_node.h" - "filetransfer_common.h" - "file_transfer.cpp" - "file_transfer.h" - "filetransfer_node.cpp" - "filetransfer_node.h" - "firedeps.h" - "fire_disp_controller.cpp" - "fire_disp_controller.h" - "first_bullet_controller.cpp" - "first_bullet_controller.h" - "flare.cpp" - "flare.h" - "FoodItem.cpp" - "FoodItem.h" - "FryupZone.cpp" - "FryupZone.h" - "fs_registrator_script.cpp" - "GalantineArtifact.cpp" - "GalantineArtifact.h" - "game_base.cpp" - "game_base.h" - "game_base_kill_type.h" - "game_base_menu_events.h" - "game_base_script.cpp" - "game_cl_artefacthunt.cpp" - "game_cl_artefacthunt.h" - "game_cl_artefacthunt_snd_msg.h" - "game_cl_base.cpp" - "game_cl_base.h" - "game_cl_base_script.cpp" - "game_cl_base_weapon_usage_statistic.cpp" - "game_cl_base_weapon_usage_statistic.h" - "game_cl_base_weapon_usage_statistic_save.cpp" - "game_cl_capturetheartefact_buywnd.cpp" - "game_cl_capture_the_artefact_captions_manager.cpp" - "game_cl_capture_the_artefact_captions_manager.h" - "game_cl_capture_the_artefact.cpp" - "game_cl_capture_the_artefact.h" - "game_cl_capture_the_artefact_messages_menu.cpp" - "game_cl_capturetheartefact_snd_msg.h" - "game_cl_deathmatch_buywnd.cpp" - "game_cl_deathmatch.cpp" - "game_cl_deathmatch.h" - "game_cl_deathmatch_snd_messages.h" - "game_cl_mp.cpp" - "game_cl_mp.h" - "game_cl_mp_messages_menu.cpp" - "game_cl_mp_messages_menu.h" - "game_cl_mp_script.cpp" - "game_cl_mp_script.h" - "game_cl_mp_snd_messages.cpp" - "game_cl_mp_snd_messages.h" - "game_cl_single.cpp" - "game_cl_single.h" - "game_cl_teamdeathmatch.cpp" - "game_cl_teamdeathmatch.h" - "game_cl_teamdeathmatch_snd_messages.h" - "game_events_handler.h" - "game_location_selector.h" - "game_location_selector_inline.h" - "game_news.cpp" - "game_news.h" - "GameObject.cpp" - "GameObject.h" - "game_object_space.h" - "game_path_manager.h" - "game_path_manager_inline.h" - "GamePersistent.cpp" - "GamePersistent.h" - "game_state_accumulator.cpp" - "game_state_accumulator.h" - "game_state_accumulator_inline.h" - "game_state_accumulator_state_register.cpp" - "game_sv_artefacthunt.cpp" - "game_sv_artefacthunt.h" - "game_sv_artefacthunt_process_event.cpp" - "game_sv_base_console_vars.cpp" - "game_sv_base_console_vars.h" - "game_sv_base.cpp" - "game_sv_base.h" - "game_sv_base_script.cpp" - "game_sv_capture_the_artefact_buy_event.cpp" - "game_sv_capture_the_artefact.cpp" - "game_sv_capture_the_artefact.h" - "game_sv_capture_the_artefact_myteam_impl.cpp" - "game_sv_capture_the_artefact_process_event.cpp" - "game_sv_deathmatch.cpp" - "game_sv_deathmatch.h" - "game_sv_deathmatch_process_event.cpp" - "game_sv_deathmatch_script.cpp" - "game_sv_event_queue.cpp" - "game_sv_event_queue.h" - "game_sv_item_respawner.cpp" - "game_sv_item_respawner.h" - "game_sv_mp.cpp" - "game_sv_mp.h" - "game_sv_mp_script.cpp" - "game_sv_mp_script.h" - "game_sv_mp_team.h" - "game_sv_mp_vote_flags.h" - "game_sv_single.cpp" - "game_sv_single.h" - "game_sv_teamdeathmatch.cpp" - "game_sv_teamdeathmatch.h" - "game_sv_teamdeathmatch_process_event.cpp" - "GameTask.cpp" - "GameTaskDefs.h" - "GameTask.h" - "GametaskManager.cpp" - "GametaskManager.h" - "GameTask_script.cpp" - "game_type.cpp" - "game_type.h" - "GlobalFeelTouch.cpp" - "GlobalFeelTouch.hpp" - "GraviArtifact.cpp" - "GraviArtifact.h" - "GraviZone.cpp" - "GraviZone.h" - "Grenade.cpp" - "Grenade.h" - "GrenadeLauncher.cpp" - "GrenadeLauncher.h" - "group_hierarchy_holder.cpp" - "group_hierarchy_holder.h" - "group_hierarchy_holder_inline.h" - "gsc_dsigned_ltx.cpp" - "gsc_dsigned_ltx.h" - "HairsZone.cpp" - "HairsZone.h" - "HairsZone_script.cpp" - "HangingLamp.cpp" - "HangingLamp.h" - "harvest_time.cpp" - "harvest_time.h" - "Helicopter2.cpp" - "Helicopter.cpp" - "helicopter.h" - "HelicopterMovementManager.cpp" - "helicopter_script.cpp" - "HelicopterWeapon.cpp" - "Hit.cpp" - "Hit.h" - "hit_immunity.cpp" - "hit_immunity.h" - "hit_immunity_space.h" - "HitMarker.cpp" - "HitMarker.h" - "hit_memory_manager.cpp" - "hit_memory_manager.h" - "hit_memory_manager_inline.h" - "hits_store.cpp" - "hits_store.h" - "hits_store_inline.h" - "holder_custom.cpp" - "holder_custom.h" - "holder_custom_script.cpp" - "HUDCrosshair.cpp" - "HUDCrosshair.h" - "HudItem.cpp" - "HudItem.h" - "hud_item_object.cpp" - "hud_item_object.h" - "HUDManager.cpp" - "HUDManager.h" - "HudSound.cpp" - "HudSound.h" - "HUDTarget.cpp" - "HUDTarget.h" - "id_generator.h" - "ik_anim_state.cpp" - "ik_anim_state.h" - "ik_calculate_data.cpp" - "ik_calculate_data.h" - "ik_calculate_state.h" - "ik_collide_data.h" - "ik_dbg_matrix.cpp" - "ik_dbg_matrix.h" - "ik_foot_collider.cpp" - "ik_foot_collider.h" - "IKFoot.cpp" - "IKFoot.h" - "IKFoot_inl.h" - "IKLimbsController.cpp" - "IKLimbsController.h" - "ik_limb_state.cpp" - "ik_limb_state.h" - "ik_limb_state_predict.h" - "ik_object_shift.cpp" - "ik_object_shift.h" - "imotion_position.cpp" - "imotion_position.h" - "imotion_velocity.cpp" - "imotion_velocity.h" - "InfoDocument.cpp" - "InfoDocument.h" - "InfoPortion.cpp" - "InfoPortion.h" - "ini_id_loader.h" - "ini_table_loader.h" - "interactive_animation.cpp" - "interactive_animation.h" - "interactive_motion.cpp" - "interactive_motion.h" - "InventoryBox.cpp" - "InventoryBox.h" - "Inventory.cpp" - "Inventory.h" - "inventory_item.cpp" - "inventory_item.h" - "inventory_item_impl.h" - "inventory_item_inline.h" - "inventory_item_object.cpp" - "inventory_item_object.h" - "inventory_item_object_inline.h" - "inventory_item_upgrade.cpp" - "InventoryOwner.cpp" - "InventoryOwner.h" - "inventory_owner_info.cpp" - "inventory_owner_inline.h" - "inventory_quickswitch.cpp" - "inventory_upgrade_base.cpp" - "inventory_upgrade_base.h" - "inventory_upgrade_base_inline.h" - "inventory_upgrade.cpp" - "inventory_upgrade_group.cpp" - "inventory_upgrade_group.h" - "inventory_upgrade_group_inline.h" - "inventory_upgrade.h" - "inventory_upgrade_inline.h" - "inventory_upgrade_manager.cpp" - "inventory_upgrade_manager.h" - "inventory_upgrade_manager_inline.h" - "inventory_upgrade_property.cpp" - "inventory_upgrade_property.h" - "inventory_upgrade_property_inline.h" - "inventory_upgrade_root.cpp" - "inventory_upgrade_root.h" - "inventory_upgrade_root_inline.h" - "invincible_fury.cpp" - "invincible_fury.h" - "item_manager.cpp" - "item_manager.h" - "item_manager_inline.h" - "killer_victim_velocity_angle.cpp" - "killer_victim_velocity_angle.h" - "kills_store.cpp" - "kills_store.h" - "kills_store_inline.h" - "Level_Bullet_Manager.cpp" - "Level_bullet_manager_firetrace.cpp" - "Level_Bullet_Manager.h" - "level_changer.cpp" - "level_changer.h" - "Level.cpp" - "level_debug.cpp" - "level_debug.h" - #"LevelFogOfWar.cpp" - #"LevelFogOfWar.h" - "Level_GameSpy_Funcs.cpp" - "LevelGraphDebugRender.cpp" - "LevelGraphDebugRender.hpp" - "Level.h" - "Level_input.cpp" - "Level_load.cpp" - "level_location_selector.h" - "level_location_selector_inline.h" - "level_map_locations.cpp" - "Level_network_compressed_updates.cpp" - "Level_network.cpp" - "Level_network_Demo.cpp" - "Level_network_Demo.h" - "Level_network_digest_computer.cpp" - "Level_network_map_sync.cpp" - "Level_network_map_sync.h" - "Level_network_messages.cpp" - "Level_network_spawn.cpp" - "Level_network_start_client.cpp" - "level_path_builder.h" - "level_path_manager.h" - "level_path_manager_inline.h" - "level_script.cpp" - "Level_secure_messaging.cpp" - "Level_SLS_Default.cpp" - "Level_SLS_Load.cpp" - "Level_SLS_Save.cpp" - "level_sounds.cpp" - "level_sounds.h" - "Level_start.cpp" - "location_manager.cpp" - "location_manager.h" - "location_manager_inline.h" - "login_manager.cpp" - "login_manager.h" - "login_manager_script.cpp" - "magic_box3.cpp" - "magic_box3.h" - "magic_box3_inline.h" - "magic_minimize_1d.cpp" - "magic_minimize_1d.h" - "magic_minimize_1d_inline.h" - "magic_minimize_nd.h" - "magic_minimize_nd_inline.h" - "MainMenu.cpp" - "MainMenu.h" - "map_location.cpp" - "map_location_defs.h" - "map_location.h" - "map_manager.cpp" - "map_manager.h" - "map_script.cpp" - "map_spot.cpp" - "map_spot.h" - "material_manager.cpp" - "material_manager.h" - "material_manager_inline.h" - #"MathUtils.cpp" - #"MathUtils.h" - "matrix_utils.h" - "medkit.cpp" - "medkit.h" - "member_corpse.h" - "member_corpse_inline.h" - "member_enemy.h" - "member_enemy_inline.h" - "member_order.h" - "member_order_inline.h" - "memory_manager.cpp" - "memory_manager.h" - "memory_manager_inline.h" - "memory_space.h" - "memory_space_impl.h" - "memory_space_script.cpp" - "MercuryBall.cpp" - "MercuryBall.h" - "Message_Filter.cpp" - "Message_Filter.h" - "MilitaryOutfit.cpp" - "MilitaryOutfit.h" - "Mincer.cpp" - "Mincer.h" - "mincer_script.cpp" - "min_obb.cpp" - "Missile.cpp" - "Missile.h" - "mixed_delegate.h" - "mixed_delegate_unique_tags.h" - "monster_community.cpp" - "monster_community.h" - "MosquitoBald.cpp" - "MosquitoBald.h" - "MosquitoBald_script.cpp" - "movement_manager.cpp" - "movement_manager_game.cpp" - "movement_manager.h" - "movement_manager_impl.h" - "movement_manager_inline.h" - "movement_manager_level.cpp" - "movement_manager_patrol.cpp" - "movement_manager_physic.cpp" - "movement_manager_space.h" - "moving_bones_snd_player.cpp" - "moving_bones_snd_player.h" - "moving_object.cpp" - "moving_object.h" - "moving_object_inline.h" - "moving_objects.cpp" - "moving_objects_dynamic_collision.cpp" - "moving_objects_dynamic.cpp" - "moving_objects.h" - "moving_objects_impl.h" - "moving_objects_inline.h" - "moving_objects_static.cpp" - "mpactor_dump_impl.cpp" - "mp_config_sections.cpp" - "mp_config_sections.h" - "MPPlayersBag.cpp" - "MPPlayersBag.h" - "mt_config.h" - "Needles.cpp" - "Needles.h" - "NET_Queue.h" - "NoGravityZone.cpp" - "NoGravityZone.h" - "object_actions.cpp" - "object_actions.h" - "object_actions_inline.h" - #"ObjectDump.cpp" - #"ObjectDump.h" - "object_handler.cpp" - "object_handler.h" - "object_handler_inline.h" - "object_handler_planner.cpp" - "object_handler_planner.h" - "object_handler_planner_impl.h" - "object_handler_planner_inline.h" - "object_handler_planner_missile.cpp" - "object_handler_planner_weapon.cpp" - "object_handler_space.h" - "object_manager.h" - "object_manager_inline.h" - "object_property_evaluators.cpp" - "object_property_evaluators.h" - "object_property_evaluators_inline.h" - "obsolete_queue.h" - "obsolete_queue_inline.h" - "obstacles_query.cpp" - "obstacles_query.h" - "obstacles_query_inline.h" - "particle_params.h" - "particle_params_script.cpp" - "ParticlesObject.cpp" - "ParticlesObject.h" - "ParticlesPlayer.cpp" - "ParticlesPlayer.h" - "patrol_path_manager.cpp" - "patrol_path_manager.h" - "patrol_path_manager_inline.h" - "PDA.cpp" - "PDA.h" - "PdaMsg.h" - "pda_space.h" - "PHCollisionDamageReceiver.cpp" - "PHCollisionDamageReceiver.h" - "PHCommander.cpp" - "PHCommander.h" - "PHDebug.cpp" - "PHDebug.h" - "PHDestroyable.cpp" - "PHDestroyable.h" - "PHDestroyableNotificate.cpp" - "PHDestroyableNotificate.h" - "PHMovementControl.cpp" - "PHMovementControl.h" - "PHMovementDynamicActivate.cpp" - "Phrase.cpp" - "PhraseDialog.cpp" - "PhraseDialogDefs.h" - "PhraseDialog.h" - "PhraseDialogManager.cpp" - "PhraseDialogManager.h" - "PhraseDialog_script.cpp" - "Phrase.h" - "PhraseScript.cpp" - "PhraseScript.h" - "PHReqComparer.h" - "PHScriptCall.cpp" - "PHScriptCall.h" - "PHShellCreator.cpp" - "PHShellCreator.h" - "ph_shell_interface.h" - "PHSimpleCalls.cpp" - "PHSimpleCalls.h" - "PHSimpleCallsScript.cpp" - "PHSkeleton.cpp" - "PHSkeleton.h" - "PHSoundPlayer.cpp" - "PHSoundPlayer.h" - "physic_item.cpp" - "physic_item.h" - "physic_item_inline.h" - "PhysicObject.cpp" - "PhysicObject.h" - "PhysicObject_script.cpp" - "physics_element_scripted.cpp" - "physics_element_scripted.h" - "physics_game.cpp" - "physics_game.h" - "PhysicsGamePars.cpp" - "PhysicsGamePars.h" - "physics_joint_scripted.cpp" - "physics_joint_scripted.h" - "physics_shell_animated.cpp" - "physics_shell_animated.h" - "PhysicsShellHolder.cpp" - "PhysicsShellHolder.h" - #"PhysicsShellScript.cpp" - "physics_shell_scripted.cpp" - "physics_shell_scripted.h" - "PhysicsSkeletonObject.cpp" - "PhysicsSkeletonObject.h" - "physics_world_scripted.cpp" - "physics_world_scripted.h" - "player_account.cpp" - "player_account.h" - "player_hud.cpp" - "player_hud.h" - "player_hud_tune.cpp" - "player_name_modifyer.cpp" - "player_name_modifyer.h" - "player_spot_params.cpp" - "player_spot_params.h" - "player_state_achilles_heel.cpp" - "player_state_achilles_heel.h" - "player_state_ambassador.cpp" - "player_state_ambassador.h" - "player_state_ammo_elapsed.cpp" - "player_state_ammo_elapsed.h" - "player_state_avenger.cpp" - "player_state_avenger.h" - "player_state_blitzkrieg.cpp" - "player_state_blitzkrieg.h" - "player_state_cherub.cpp" - "player_state_cherub.h" - "player_state_climber.cpp" - "player_state_climber.h" - "player_state_mad.cpp" - "player_state_mad.h" - "player_state_marksman.cpp" - "player_state_marksman.h" - "player_state_multichampion.cpp" - "player_state_multichampion.h" - "player_state_opener.cpp" - "player_state_opener.h" - "player_state_param.h" - "player_state_params.cpp" - "player_state_params.h" - "player_state_remembrance.cpp" - "player_state_remembrance.h" - "player_state_skewer.cpp" - "player_state_skewer.h" - "player_state_toughy.cpp" - "player_state_toughy.h" - "player_team_win_score.cpp" - "player_team_win_score.h" - "pose_extrapolation.cpp" - "pose_extrapolation.h" - "poses_blending.cpp" - "poses_blending.h" - "PostprocessAnimator.cpp" - "PostprocessAnimator.h" - "pp_effector_custom.cpp" - "pp_effector_custom.h" - "pp_effector_distance.cpp" - "pp_effector_distance.h" - "profile_data_types.cpp" - "profile_data_types.h" - "profile_data_types_script.cpp" - "profile_data_types_script.h" - "profile_store.cpp" - "profile_store.h" - "profile_store_script.cpp" - "property_evaluator_const.h" - "property_evaluator.h" - "property_evaluator_inline.h" - "property_evaluator_member.h" - "property_evaluator_member_inline.h" - "property_evaluator_script.cpp" - "property_storage.h" - "property_storage_inline.h" - "property_storage_script.cpp" - "purchase_list.cpp" - "purchase_list.h" - "purchase_list_inline.h" - "quadtree.h" - "quadtree_inline.h" - "queued_async_method.h" - "RadioactiveZone.cpp" - "RadioactiveZone.h" - "Random.cpp" - "Random.hpp" - "rat_state_base.cpp" - "rat_state_base.h" - "rat_state_base_inline.h" - "rat_state_manager.cpp" - "rat_state_manager.h" - "rat_state_manager_inline.h" - "rat_states.cpp" - "rat_states.h" - "raypick.cpp" - "raypick.h" - "refreshable_obstacles_query.h" - "refreshable_obstacles_query_inline.h" - "RegistryFuncs.cpp" - "RegistryFuncs.h" - "relation_registry_actions.cpp" - "relation_registry.cpp" - "relation_registry_defs.h" - "relation_registry_fights.cpp" - "relation_registry.h" - "relation_registry_inline.h" - "restricted_object.cpp" - "restricted_object.h" - "restricted_object_inline.h" - "restricted_object_obstacle.cpp" - "restricted_object_obstacle.h" - "reward_event_generator.cpp" - "reward_event_generator.h" - "reward_event_handler.h" - "rewarding_events_handlers.cpp" - "rewarding_events_handlers.h" - "rewarding_state_events.cpp" - "rewarding_state_events.h" - "reward_manager.cpp" - "reward_manager.h" - "reward_snd_messages.h" - "RGD5.h" - "RocketLauncher.cpp" - "RocketLauncher.h" - "RustyHairArtifact.cpp" - "RustyHairArtifact.h" - "safe_map_iterator.h" - "safe_map_iterator_inline.h" - "saved_game_wrapper.cpp" - "saved_game_wrapper.h" - "saved_game_wrapper_inline.h" - "saved_game_wrapper_script.cpp" - "ScientificOutfit.cpp" - "ScientificOutfit.h" - "Scope.cpp" - "Scope.h" - "screenshot_manager.cpp" - "screenshot_manager.h" - "screenshots_common.cpp" - "screenshots_common.h" - "screenshot_server.cpp" - "screenshot_server.h" - "screenshots_writer.cpp" - "screenshots_writer.h" - "script_abstract_action.h" - "script_action_condition.h" - "script_action_condition_inline.h" - "script_action_condition_script.cpp" - "script_action_planner_action_wrapper.cpp" - "script_action_planner_action_wrapper.h" - "script_action_planner_action_wrapper_inline.h" - "script_action_planner_wrapper.cpp" - "script_action_planner_wrapper.h" - "script_action_planner_wrapper_inline.h" - "script_action_wrapper.cpp" - "script_action_wrapper.h" - "script_action_wrapper_inline.h" - "script_animation_action.h" - "script_animation_action_inline.h" - "script_animation_action_script.cpp" - "script_binder.cpp" - "script_binder.h" - "script_binder_inline.h" - "script_binder_object.cpp" - "script_binder_object.h" - "script_binder_object_script.cpp" - "script_binder_object_wrapper.cpp" - "script_binder_object_wrapper.h" - "script_bind_macroses.h" - "script_effector.cpp" - "script_effector.h" - "script_effector_inline.h" - "script_effector_script.cpp" - "script_effector_wrapper.cpp" - "script_effector_wrapper.h" - "script_effector_wrapper_inline.h" - "script_entity_action.cpp" - "script_entity_action.h" - "script_entity_action_inline.h" - "script_entity_action_script.cpp" - "script_entity.cpp" - "script_entity.h" - "script_entity_inline.h" - "script_entity_space.h" - "script_game_object2.cpp" - "script_game_object3.cpp" - "script_game_object4.cpp" - "script_game_object.cpp" - "script_game_object.h" - "script_game_object_impl.h" - "script_game_object_inventory_owner.cpp" - "script_game_object_script2.cpp" - "script_game_object_script3.cpp" - "script_game_object_script.cpp" - "script_game_object_script_trader.cpp" - "script_game_object_smart_covers.cpp" - "script_game_object_trader.cpp" - "script_game_object_use2.cpp" - "script_game_object_use.cpp" - "script_hit.cpp" - "script_hit.h" - "script_hit_inline.h" - "script_hit_script.cpp" - "script_lanim.cpp" - "script_monster_action.cpp" - "script_monster_action.h" - "script_monster_action_inline.h" - "script_monster_action_script.cpp" - "script_monster_hit_info.h" - "script_monster_hit_info_script.cpp" - "script_movement_action.cpp" - "script_movement_action.h" - "script_movement_action_inline.h" - "script_movement_action_script.cpp" - "script_object_action.cpp" - "script_object_action.h" - "script_object_action_inline.h" - "script_object_action_script.cpp" - "script_object.cpp" - "script_object.h" - "script_particle_action.cpp" - "script_particle_action.h" - "script_particle_action_inline.h" - "script_particle_action_script.cpp" - "script_particles.cpp" - "script_particles.h" - "script_particles_inline.h" - "script_particles_script.cpp" - "script_property_evaluator_wrapper.cpp" - "script_property_evaluator_wrapper.h" - "script_property_evaluator_wrapper_inline.h" - "script_render_device_script.cpp" - "script_sound_action.cpp" - "script_sound_action.h" - "script_sound_action_inline.h" - "script_sound_action_script.cpp" - "script_sound.cpp" - "script_sound.h" - "script_sound_info.h" - "script_sound_info_script.cpp" - "script_sound_inline.h" - "script_sound_script.cpp" - "script_watch_action.cpp" - "script_watch_action.h" - "script_watch_action_inline.h" - "script_watch_action_script.cpp" - "ScriptXMLInit.cpp" - "ScriptXMLInit.h" - "script_zone.cpp" - "script_zone.h" - "script_zone_script.cpp" - "searchlight.cpp" - "searchlight.h" - "secure_messaging.cpp" - "secure_messaging.h" - "seniority_hierarchy_holder.cpp" - "seniority_hierarchy_holder.h" - "seniority_hierarchy_holder_inline.h" - "seniority_hierarchy_space.h" - "server_entity_wrapper.cpp" - "server_entity_wrapper.h" - "server_entity_wrapper_inline.h" - "setup_manager.h" - "setup_manager_inline.h" - "ShootingObject.cpp" - "shootingObject_dump_impl.cpp" - "ShootingObject.h" - "sight_action.cpp" - "sight_action.h" - "sight_action_inline.h" - "sight_control_action.h" - "sight_control_action_inline.h" - "sight_manager.cpp" - "sight_manager.h" - "sight_manager_inline.h" - "sight_manager_space.h" - "sight_manager_target.cpp" - "Silencer.cpp" - "Silencer.h" - "silent_shots.cpp" - "silent_shots.h" - "SimpleDetector.cpp" - "SimpleDetector.h" - "SleepEffector.cpp" - "SleepEffector.h" - "smart_cover_action.cpp" - "smart_cover_action.h" - "smart_cover_action_inline.h" - "smart_cover_animation_planner.cpp" - "smart_cover_animation_planner.h" - "smart_cover_animation_planner_inline.h" - "smart_cover_animation_selector.cpp" - "smart_cover_animation_selector.h" - "smart_cover_animation_selector_inline.h" - "smart_cover.cpp" - "smart_cover_default_behaviour_planner.cpp" - "smart_cover_default_behaviour_planner.hpp" - "smart_cover_default_behaviour_planner_inline.hpp" - "smart_cover_description.cpp" - "smart_cover_description.h" - "smart_cover_description_inline.h" - "smart_cover_detail.cpp" - "smart_cover_detail.h" - "smart_cover_evaluators.cpp" - "smart_cover_evaluators.h" - "smart_cover.h" - "smart_cover_inline.h" - "smart_cover_loophole.cpp" - "smart_cover_loophole.h" - "smart_cover_loophole_inline.h" - "smart_cover_loophole_planner_actions.cpp" - "smart_cover_loophole_planner_actions.h" - "smart_cover_loophole_planner_actions_inline.h" - "smart_cover_object.cpp" - "smart_cover_object.h" - "smart_cover_object_inline.h" - "smart_cover_object_script.cpp" - "smart_cover_planner_actions.cpp" - "smart_cover_planner_actions.h" - "smart_cover_planner_actions_inline.h" - "smart_cover_planner_target_provider.cpp" - "smart_cover_planner_target_provider.h" - "smart_cover_planner_target_selector.cpp" - "smart_cover_planner_target_selector.h" - "smart_cover_planner_target_selector_inline.h" - "smart_cover_storage.cpp" - "smart_cover_storage.h" - "smart_cover_transition_animation.cpp" - "smart_cover_transition_animation.hpp" - "smart_cover_transition_animation_inline.hpp" - "smart_cover_transition.cpp" - "smart_cover_transition.hpp" - "smart_zone.h" - "sound_collection_storage.cpp" - "sound_collection_storage.h" - "sound_collection_storage_inline.h" - "sound_memory_manager.cpp" - "sound_memory_manager.h" - "sound_memory_manager_inline.h" - "sound_player.cpp" - "sound_player.h" - "sound_player_inline.h" - "sound_user_data_visitor.h" - "space_restriction_abstract.h" - "space_restriction_abstract_inline.h" - "space_restriction_base.cpp" - "space_restriction_base.h" - "space_restriction_base_inline.h" - "space_restriction_bridge.cpp" - "space_restriction_bridge.h" - "space_restriction_bridge_inline.h" - "space_restriction_composition.cpp" - "space_restriction_composition.h" - "space_restriction_composition_inline.h" - "space_restriction.cpp" - "space_restriction.h" - "space_restriction_holder.cpp" - "space_restriction_holder.h" - "space_restriction_holder_inline.h" - "space_restriction_inline.h" - "space_restriction_manager.cpp" - "space_restriction_manager.h" - "space_restriction_manager_inline.h" - "space_restriction_shape.cpp" - "space_restriction_shape.h" - "space_restriction_shape_inline.h" - "space_restrictor.cpp" - "space_restrictor.h" - "space_restrictor_inline.h" - "space_restrictor_script.cpp" - "SpaceUtils.h" - "spectator_camera_first_eye.cpp" - "spectator_camera_first_eye.h" - "Spectator.cpp" - "Spectator.h" - "sprinter_stopper.cpp" - "sprinter_stopper.h" - "squad_hierarchy_holder.cpp" - "squad_hierarchy_holder.h" - "squad_hierarchy_holder_inline.h" - "stalker_alife_actions.cpp" - "stalker_alife_actions.h" - "stalker_alife_planner.cpp" - "stalker_alife_planner.h" - "stalker_alife_task_actions.cpp" - "stalker_alife_task_actions.h" - "stalker_animation_callbacks.cpp" - "stalker_animation_data.cpp" - "stalker_animation_data.h" - "stalker_animation_data_storage.cpp" - "stalker_animation_data_storage.h" - "stalker_animation_data_storage_inline.h" - "stalker_animation_global.cpp" - "stalker_animation_head.cpp" - "stalker_animation_legs.cpp" - "stalker_animation_manager.cpp" - "stalker_animation_manager_debug.cpp" - "stalker_animation_manager.h" - "stalker_animation_manager_impl.h" - "stalker_animation_manager_inline.h" - "stalker_animation_manager_update.cpp" - "stalker_animation_names.cpp" - "stalker_animation_names.h" - #"stalker_animation_offsets.cpp" - #"stalker_animation_offsets.hpp" - "stalker_animation_pair.cpp" - "stalker_animation_pair.h" - "stalker_animation_pair_inline.h" - "stalker_animation_script.cpp" - "stalker_animation_script.h" - "stalker_animation_script_inline.h" - "stalker_animation_state.cpp" - "stalker_animation_state.h" - "stalker_animation_state_inline.h" - "stalker_animation_torso.cpp" - "stalker_anomaly_actions.cpp" - "stalker_anomaly_actions.h" - "stalker_anomaly_planner.cpp" - "stalker_anomaly_planner.h" - "stalker_base_action.cpp" - "stalker_base_action.h" - "stalker_combat_action_base.cpp" - "stalker_combat_action_base.h" - "stalker_combat_actions.cpp" - "stalker_combat_actions.h" - "stalker_combat_actions_inline.h" - "stalker_combat_planner.cpp" - "stalker_combat_planner.h" - "stalker_danger_by_sound_actions.cpp" - "stalker_danger_by_sound_actions.h" - "stalker_danger_by_sound_planner.cpp" - "stalker_danger_by_sound_planner.h" - "stalker_danger_grenade_actions.cpp" - "stalker_danger_grenade_actions.h" - "stalker_danger_grenade_planner.cpp" - "stalker_danger_grenade_planner.h" - "stalker_danger_in_direction_actions.cpp" - "stalker_danger_in_direction_actions.h" - "stalker_danger_in_direction_planner.cpp" - "stalker_danger_in_direction_planner.h" - "stalker_danger_planner.cpp" - "stalker_danger_planner.h" - "stalker_danger_planner_inline.h" - "stalker_danger_property_evaluators.cpp" - "stalker_danger_property_evaluators.h" - "stalker_danger_unknown_actions.cpp" - "stalker_danger_unknown_actions.h" - "stalker_danger_unknown_planner.cpp" - "stalker_danger_unknown_planner.h" - "stalker_death_actions.cpp" - "stalker_death_actions.h" - "stalker_death_planner.cpp" - "stalker_death_planner.h" - "stalker_decision_space.h" - "stalker_flair.cpp" - "stalker_flair.h" - "stalker_get_distance_actions.cpp" - "stalker_get_distance_actions.h" - "stalker_get_distance_planner.cpp" - "stalker_get_distance_planner.h" - "stalker_kill_wounded_actions.cpp" - "stalker_kill_wounded_actions.h" - "stalker_kill_wounded_planner.cpp" - "stalker_kill_wounded_planner.h" - "stalker_low_cover_actions.cpp" - "stalker_low_cover_actions.h" - "stalker_low_cover_planner.cpp" - "stalker_low_cover_planner.h" - "stalker_movement_manager_base.cpp" - "stalker_movement_manager_base.h" - "stalker_movement_manager_base_inline.h" - "stalker_movement_manager_obstacles.cpp" - "stalker_movement_manager_obstacles.h" - "stalker_movement_manager_obstacles_inline.h" - "stalker_movement_manager_obstacles_path.cpp" - "stalker_movement_manager_smart_cover.cpp" - "stalker_movement_manager_smart_cover_fov_range.cpp" - "stalker_movement_manager_smart_cover.h" - "stalker_movement_manager_smart_cover_inline.h" - "stalker_movement_manager_smart_cover_loopholes.cpp" - "stalker_movement_manager_space.h" - "stalker_movement_params.cpp" - "stalker_movement_params.h" - "stalker_movement_params_inline.h" - "stalker_movement_restriction.h" - "stalker_movement_restriction_inline.h" - "StalkerOutfit.cpp" - "StalkerOutfit.h" - "stalker_planner.cpp" - "stalker_planner.h" - "stalker_planner_inline.h" - "stalker_property_evaluators.cpp" - "stalker_property_evaluators.h" - "stalker_property_evaluators_inline.h" - "stalker_search_actions.cpp" - "stalker_search_actions.h" - "stalker_search_planner.cpp" - "stalker_search_planner.h" - "stalker_sound_data.cpp" - "stalker_sound_data.h" - "stalker_sound_data_inline.h" - "stalker_sound_data_visitor.cpp" - "stalker_sound_data_visitor.h" - "stalker_sound_data_visitor_inline.h" - "stalker_velocity_collection.cpp" - "stalker_velocity_collection.h" - "stalker_velocity_collection_inline.h" - "stalker_velocity_holder.cpp" - "stalker_velocity_holder.h" - "stalker_velocity_holder_inline.h" - "state_arguments_functions.cpp" - "state_arguments_functions.h" - "static_cast_checked.hpp" - #"static_cast_checked_test.cpp" - "static_obstacles_avoider.cpp" - "static_obstacles_avoider.h" - "static_obstacles_avoider_inline.h" - #"stats_submitter.cpp" - "stats_submitter_dsa_params.cpp" - "stats_submitter.h" - "StdAfx.cpp" - "StdAfx.h" - "steering_behaviour_alignment.h" - "steering_behaviour_base.h" - "steering_behaviour_base_inline.h" - "steering_behaviour_cohesion.h" - "steering_behaviour.cpp" - "steering_behaviour.h" - "steering_behaviour_separation.h" - "step_manager.cpp" - "step_manager_defs.h" - "step_manager.h" - "team_base_zone.cpp" - "team_base_zone.h" - "team_hierarchy_holder.cpp" - "team_hierarchy_holder.h" - "team_hierarchy_holder_inline.h" - "TeleWhirlwind.cpp" - "TeleWhirlwind.h" - "ThornArtifact.cpp" - "ThornArtifact.h" - "Torch.cpp" - "Torch.h" - "torch_script.cpp" - "TorridZone.cpp" - "TorridZone.h" - "Tracer.cpp" - "Tracer.h" - "trade2.cpp" - "trade_action_parameters.h" - "trade_action_parameters_inline.h" - "trade_bool_parameters.h" - "trade_bool_parameters_inline.h" - "trade.cpp" - "trade_factor_parameters.h" - "trade_factor_parameters_inline.h" - "trade_factors.h" - "trade_factors_inline.h" - "trade.h" - "trade_parameters.cpp" - "trade_parameters.h" - "trade_parameters_inline.h" - "traffic_optimization.cpp" - "traffic_optimization.h" - "trajectories.cpp" - "trajectories.h" - "UIAchivementsIndicator.cpp" - "UIAchivementsIndicator.h" - "UIDialogHolder.cpp" - "UIDialogHolder.h" - "ui_export_script.cpp" - #"UIFrameRect.cpp" - #"UIFrameRect.h" - "UIGameAHunt.cpp" - "UIGameAHunt.h" - "UIGameCTA.cpp" - "UIGameCTA.h" - "UIGameCustom.cpp" - "UIGameCustom.h" - #"UIGame_custom_script.cpp" - #"UIGame_custom_script.h" - "UIGameCustom_script.cpp" - "UIGameDM.cpp" - "UIGameDM.h" - "UIGameMP.cpp" - "UIGameMP.h" - "UIGameSP.cpp" - "UIGameSP.h" - "UIGameTDM.cpp" - "UIGameTDM.h" - "UIPanelsClassFactory.cpp" - "UIPanelsClassFactory.h" - "UIPlayerItem.cpp" - "UIPlayerItem.h" - "UITeamHeader.cpp" - "UITeamHeader.h" - "UITeamPanels.cpp" - "UITeamPanels.h" - "UITeamState.cpp" - "UITeamState.h" - "UITimeDilator.cpp" - "UITimeDilator.h" - "UIZoneMap.cpp" - "UIZoneMap.h" - "VersionSwitcher.cpp" - "VersionSwitcher.h" - "vision_client.cpp" - "vision_client.h" - "vision_client_inline.h" - "visual_memory_manager.cpp" - "visual_memory_manager.h" - "visual_memory_manager_inline.h" - "visual_memory_params.cpp" - "visual_memory_params.h" - "wallmark_manager.cpp" - "wallmark_manager.h" - "WeaponAK74.cpp" - "WeaponAK74.h" - "WeaponAmmo.cpp" - "weapon_ammo_dump_impl.cpp" - "WeaponAmmo.h" - "WeaponAutomaticShotgun.cpp" - "WeaponAutomaticShotgun.h" - "WeaponBinoculars.cpp" - "WeaponBinoculars.h" - "WeaponBinocularsVision.cpp" - "WeaponBinocularsVision.h" - "weaponBM16.cpp" - "weaponBM16.h" - "Weapon.cpp" - "WeaponCustomPistolAuto.cpp" - "WeaponCustomPistolAuto.h" - "WeaponCustomPistol.cpp" - "WeaponCustomPistol.h" - "WeaponDispersion.cpp" - "weapon_dump_impl.cpp" - "WeaponFire.cpp" - "WeaponFN2000.cpp" - "WeaponFN2000.h" - "WeaponFORT.h" - "WeaponGroza.cpp" - "WeaponGroza.h" - "Weapon.h" - "WeaponHPSA.cpp" - "WeaponHPSA.h" - "WeaponHUD.h" - "WeaponKnife.cpp" - "WeaponKnife.h" - "WeaponLR300.cpp" - "WeaponLR300.h" - "WeaponMagazined.cpp" - "WeaponMagazined.h" - "WeaponMagazinedWGrenade.cpp" - "WeaponMagazinedWGrenade.h" - "WeaponPistol.cpp" - "WeaponPistol.h" - "WeaponPM.cpp" - "WeaponPM.h" - "WeaponRevolver.cpp" - "WeaponRevolver.h" - "WeaponRG6.cpp" - "WeaponRG6.h" - "WeaponRPG7.cpp" - "WeaponRPG7.h" - "WeaponScript.cpp" - "WeaponShotgun.cpp" - "WeaponShotgun.h" - "WeaponStatMgun.cpp" - "WeaponStatMgunFire.cpp" - "WeaponStatMgun.h" - "WeaponStatMgunIR.cpp" - "WeaponSVD.cpp" - "WeaponSVD.h" - "WeaponSVU.h" - "WeaponUpgrade.cpp" - "WeaponUSP45.h" - "WeaponVal.cpp" - "WeaponVal.h" - "WeaponVintorez.cpp" - "WeaponVintorez.h" - "WeaponWalther.h" - "Wound.cpp" - "Wound.h" - "wrapper_abstract.h" - "wrapper_abstract_inline.h" - #"xr_Client_BattlEye.cpp" - #"xr_Client_BattlEye.h" - "xrClientsPool.cpp" - "xrClientsPool.h" - "xrGame.cpp" - "xrgame_dll_detach.cpp" - "xrGameSpy_GameSpyFuncs.cpp" - "xrGameSpyServer_callbacks.cpp" - "xrGameSpyServer_callbacks.h" - "xrGameSpyServer.cpp" - "xrGameSpyServer.h" - "xrServer_balance.cpp" - #"xr_Server_BattlEye.cpp" - #"xr_Server_BattlEye.h" - "xrServer_CL_connect.cpp" - "xrServer_CL_disconnect.cpp" - "xrServer_Connect.cpp" - "xrServer.cpp" - "xrServer_Disconnect.cpp" - "xrServer.h" - "xrServer_info.cpp" - "xrServer_info.h" - "xrServerMapSync.cpp" - "xrServerMapSync.h" - "xrServer_perform_GameExport.cpp" - "xrServer_perform_migration.cpp" - "xrServer_perform_RPgen.cpp" - "xrServer_perform_sls_default.cpp" - "xrServer_perform_sls_load.cpp" - "xrServer_perform_sls_save.cpp" - "xrServer_perform_transfer.cpp" - "xrServer_process_event_activate.cpp" - "xrServer_process_event.cpp" - "xrServer_process_event_destroy.cpp" - "xrServer_process_event_ownership.cpp" - "xrServer_process_event_reject.cpp" - "xrServer_process_spawn.cpp" - "xrServer_process_update.cpp" - "xrServer_secure_messaging.cpp" - "xrServer_sls_clear.cpp" - "xrServer_svclient_validation.cpp" - "xrServer_svclient_validation.h" - "xrServer_updates_compressor.cpp" - "xrServer_updates_compressor.h" - "xr_time.cpp" - "xr_time.h" - "ZoneCampfire.cpp" - "ZoneCampfire.h" - "zone_effector.cpp" - "zone_effector.h" - "ZoneVisual.cpp" - "ZoneVisual.h" - "ZudaArtifact.cpp" - "ZudaArtifact.h" - "ai/ai_monsters_anims.h" - "ai/ai_monsters_misc.cpp" - "ai/ai_monsters_misc.h" - "ai/position_prediction.h" - "ai/weighted_random.cpp" - "ai/weighted_random.h" - "ai/crow/ai_crow.cpp" - "ai/crow/ai_crow.h" - "ai/monsters/ai_monster_bones.cpp" - "ai/monsters/ai_monster_bones.h" - "ai/monsters/ai_monster_defs.h" - "ai/monsters/ai_monster_effector.cpp" - "ai/monsters/ai_monster_effector.h" - "ai/monsters/ai_monster_motion_stats.cpp" - "ai/monsters/ai_monster_motion_stats.h" - "ai/monsters/ai_monster_shared_data.h" - "ai/monsters/ai_monster_squad_attack.cpp" - "ai/monsters/ai_monster_squad.cpp" - "ai/monsters/ai_monster_squad.h" - "ai/monsters/ai_monster_squad_manager.cpp" - "ai/monsters/ai_monster_squad_manager.h" - "ai/monsters/ai_monster_squad_manager_inline.h" - "ai/monsters/ai_monster_squad_rest.cpp" - "ai/monsters/ai_monster_utils.cpp" - "ai/monsters/ai_monster_utils.h" - "ai/monsters/anim_triple.cpp" - "ai/monsters/anim_triple.h" - "ai/monsters/anomaly_detector.cpp" - "ai/monsters/anomaly_detector.h" - "ai/monsters/anti_aim_ability.cpp" - "ai/monsters/anti_aim_ability.h" - "ai/monsters/control_animation_base_accel.cpp" - "ai/monsters/control_animation_base.cpp" - "ai/monsters/control_animation_base.h" - "ai/monsters/control_animation_base_load.cpp" - "ai/monsters/control_animation_base_update.cpp" - "ai/monsters/control_animation.cpp" - "ai/monsters/control_animation.h" - "ai/monsters/control_combase.h" - "ai/monsters/control_com_defs.h" - "ai/monsters/control_critical_wound.cpp" - "ai/monsters/control_critical_wound.h" - "ai/monsters/control_direction_base.cpp" - "ai/monsters/control_direction_base.h" - "ai/monsters/control_direction.cpp" - "ai/monsters/control_direction.h" - "ai/monsters/control_jump.cpp" - "ai/monsters/control_jump.h" - "ai/monsters/controlled_actor.cpp" - "ai/monsters/controlled_actor.h" - "ai/monsters/controlled_entity.h" - "ai/monsters/controlled_entity_inline.h" - "ai/monsters/control_manager.cpp" - "ai/monsters/control_manager_custom.cpp" - "ai/monsters/control_manager_custom.h" - "ai/monsters/control_manager.h" - "ai/monsters/control_melee_jump.cpp" - "ai/monsters/control_melee_jump.h" - "ai/monsters/control_movement_base.cpp" - "ai/monsters/control_movement_base.h" - "ai/monsters/control_movement.cpp" - "ai/monsters/control_movement.h" - "ai/monsters/control_path_builder_base.cpp" - "ai/monsters/control_path_builder_base.h" - "ai/monsters/control_path_builder_base_inline.h" - "ai/monsters/control_path_builder_base_path.cpp" - "ai/monsters/control_path_builder_base_set.cpp" - "ai/monsters/control_path_builder_base_update.cpp" - "ai/monsters/control_path_builder.cpp" - "ai/monsters/control_path_builder.h" - "ai/monsters/control_rotation_jump.cpp" - "ai/monsters/control_rotation_jump.h" - "ai/monsters/control_run_attack.cpp" - "ai/monsters/control_run_attack.h" - "ai/monsters/control_sequencer.cpp" - "ai/monsters/control_sequencer.h" - "ai/monsters/control_threaten.cpp" - "ai/monsters/control_threaten.h" - "ai/monsters/corpse_cover.cpp" - "ai/monsters/corpse_cover.h" - "ai/monsters/custom_events.h" - "ai/monsters/energy_holder.cpp" - "ai/monsters/energy_holder.h" - "ai/monsters/invisibility.cpp" - "ai/monsters/invisibility.h" - "ai/monsters/melee_checker.cpp" - "ai/monsters/melee_checker.h" - "ai/monsters/melee_checker_inline.h" - "ai/monsters/monster_aura.cpp" - "ai/monsters/monster_aura.h" - "ai/monsters/monster_corpse_manager.cpp" - "ai/monsters/monster_corpse_manager.h" - "ai/monsters/monster_corpse_memory.cpp" - "ai/monsters/monster_corpse_memory.h" - "ai/monsters/monster_cover_manager.cpp" - "ai/monsters/monster_cover_manager.h" - "ai/monsters/monster_enemy_manager.cpp" - "ai/monsters/monster_enemy_manager.h" - "ai/monsters/monster_enemy_memory.cpp" - "ai/monsters/monster_enemy_memory.h" - "ai/monsters/monster_event_manager.cpp" - "ai/monsters/monster_event_manager_defs.h" - "ai/monsters/monster_event_manager.h" - "ai/monsters/monster_hit_memory.cpp" - "ai/monsters/monster_hit_memory.h" - "ai/monsters/monster_home.cpp" - "ai/monsters/monster_home.h" - "ai/monsters/monster_morale.cpp" - "ai/monsters/monster_morale.h" - "ai/monsters/monster_morale_inline.h" - "ai/monsters/monster_sound_defs.h" - "ai/monsters/monster_sound_memory.cpp" - "ai/monsters/monster_sound_memory.h" - "ai/monsters/monster_state_manager.h" - "ai/monsters/monster_state_manager_inline.h" - "ai/monsters/monster_velocity_space.h" - "ai/monsters/psy_aura.cpp" - "ai/monsters/psy_aura.h" - "ai/monsters/scanning_ability.h" - "ai/monsters/scanning_ability_inline.h" - "ai/monsters/state.cpp" - "ai/monsters/state_defs.h" - "ai/monsters/state.h" - "ai/monsters/state_inline.h" - "ai/monsters/state_manager.h" - "ai/monsters/telekinesis.cpp" - "ai/monsters/telekinesis.h" - "ai/monsters/telekinesis_inline.h" - "ai/monsters/telekinetic_object.cpp" - "ai/monsters/telekinetic_object.h" - "ai/monsters/basemonster/base_monster_anim.cpp" - "ai/monsters/basemonster/base_monster.cpp" - "ai/monsters/basemonster/base_monster_debug.cpp" - "ai/monsters/basemonster/base_monster_feel.cpp" - "ai/monsters/basemonster/base_monster.h" - "ai/monsters/basemonster/base_monster_inline.h" - "ai/monsters/basemonster/base_monster_misc.cpp" - "ai/monsters/basemonster/base_monster_net.cpp" - "ai/monsters/basemonster/base_monster_path.cpp" - "ai/monsters/basemonster/base_monster_script.cpp" - "ai/monsters/basemonster/base_monster_startup.cpp" - "ai/monsters/basemonster/base_monster_think.cpp" - "ai/monsters/bloodsucker/bloodsucker_alien.cpp" - "ai/monsters/bloodsucker/bloodsucker_alien.h" - "ai/monsters/bloodsucker/bloodsucker_attack_state.h" - "ai/monsters/bloodsucker/bloodsucker_attack_state_hide.h" - "ai/monsters/bloodsucker/bloodsucker_attack_state_hide_inline.h" - "ai/monsters/bloodsucker/bloodsucker_attack_state_inline.h" - "ai/monsters/bloodsucker/bloodsucker.cpp" - "ai/monsters/bloodsucker/bloodsucker.h" - "ai/monsters/bloodsucker/bloodsucker_predator.h" - "ai/monsters/bloodsucker/bloodsucker_predator_inline.h" - "ai/monsters/bloodsucker/bloodsucker_predator_lite.h" - "ai/monsters/bloodsucker/bloodsucker_predator_lite_inline.h" - "ai/monsters/bloodsucker/bloodsucker_script.cpp" - "ai/monsters/bloodsucker/bloodsucker_state_capture_jump.h" - "ai/monsters/bloodsucker/bloodsucker_state_capture_jump_inline.h" - "ai/monsters/bloodsucker/bloodsucker_state_manager.cpp" - "ai/monsters/bloodsucker/bloodsucker_state_manager.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_approach.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_approach_inline.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_effector.cpp" - "ai/monsters/bloodsucker/bloodsucker_vampire_effector.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_execute.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_execute_inline.h" - "ai/monsters/bloodsucker/bloodsucker_vampire.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_hide.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_hide_inline.h" - "ai/monsters/bloodsucker/bloodsucker_vampire_inline.h" - "ai/monsters/boar/boar.cpp" - "ai/monsters/boar/boar.h" - "ai/monsters/boar/boar_script.cpp" - "ai/monsters/boar/boar_state_manager.cpp" - "ai/monsters/boar/boar_state_manager.h" - "ai/monsters/burer/burer.cpp" - "ai/monsters/burer/burer_fast_gravi.cpp" - "ai/monsters/burer/burer_fast_gravi.h" - "ai/monsters/burer/burer.h" - "ai/monsters/burer/burer_script.cpp" - "ai/monsters/burer/burer_state_attack_antiaim.h" - "ai/monsters/burer/burer_state_attack_antiaim_inline.h" - "ai/monsters/burer/burer_state_attack_gravi.h" - "ai/monsters/burer/burer_state_attack_gravi_inline.h" - "ai/monsters/burer/burer_state_attack.h" - "ai/monsters/burer/burer_state_attack_inline.h" - "ai/monsters/burer/burer_state_attack_melee.h" - "ai/monsters/burer/burer_state_attack_melee_inline.h" - "ai/monsters/burer/burer_state_attack_run_around.h" - "ai/monsters/burer/burer_state_attack_run_around_inline.h" - "ai/monsters/burer/burer_state_attack_shield.h" - "ai/monsters/burer/burer_state_attack_shield_inline.h" - "ai/monsters/burer/burer_state_attack_tele.h" - "ai/monsters/burer/burer_state_attack_tele_inline.h" - "ai/monsters/burer/burer_state_manager.cpp" - "ai/monsters/burer/burer_state_manager.h" - "ai/monsters/cat/cat.cpp" - "ai/monsters/cat/cat.h" - "ai/monsters/cat/cat_script.cpp" - "ai/monsters/cat/cat_state_manager.cpp" - "ai/monsters/cat/cat_state_manager.h" - "ai/monsters/chimera/chimera_attack_state.h" - "ai/monsters/chimera/chimera_attack_state_inline.h" - "ai/monsters/chimera/chimera.cpp" - "ai/monsters/chimera/chimera.h" - "ai/monsters/chimera/chimera_script.cpp" - "ai/monsters/chimera/chimera_state_hunting_come_out.h" - "ai/monsters/chimera/chimera_state_hunting_come_out_inline.h" - "ai/monsters/chimera/chimera_state_hunting.h" - "ai/monsters/chimera/chimera_state_hunting_inline.h" - "ai/monsters/chimera/chimera_state_hunting_move_to_cover.h" - "ai/monsters/chimera/chimera_state_hunting_move_to_cover_inline.h" - "ai/monsters/chimera/chimera_state_manager.cpp" - "ai/monsters/chimera/chimera_state_manager.h" - "ai/monsters/chimera/chimera_state_threaten.h" - "ai/monsters/chimera/chimera_state_threaten_inline.h" - "ai/monsters/chimera/chimera_state_threaten_roar.h" - "ai/monsters/chimera/chimera_state_threaten_roar_inline.h" - "ai/monsters/chimera/chimera_state_threaten_steal.h" - "ai/monsters/chimera/chimera_state_threaten_steal_inline.h" - "ai/monsters/chimera/chimera_state_threaten_walk.h" - "ai/monsters/chimera/chimera_state_threaten_walk_inline.h" - "ai/monsters/controller/controller_animation.cpp" - "ai/monsters/controller/controller_animation.h" - "ai/monsters/controller/controller.cpp" - "ai/monsters/controller/controller_direction.cpp" - "ai/monsters/controller/controller_direction.h" - "ai/monsters/controller/controller.h" - "ai/monsters/controller/controller_psy_hit.cpp" - "ai/monsters/controller/controller_psy_hit_effector.cpp" - "ai/monsters/controller/controller_psy_hit_effector.h" - "ai/monsters/controller/controller_psy_hit.h" - "ai/monsters/controller/controller_script.cpp" - "ai/monsters/controller/controller_state_attack_camp.h" - "ai/monsters/controller/controller_state_attack_camp_inline.h" - "ai/monsters/controller/controller_state_attack_fast_move.h" - "ai/monsters/controller/controller_state_attack_fast_move_inline.h" - "ai/monsters/controller/controller_state_attack_fire.h" - "ai/monsters/controller/controller_state_attack_fire_inline.h" - "ai/monsters/controller/controller_state_attack.h" - "ai/monsters/controller/controller_state_attack_hide.h" - "ai/monsters/controller/controller_state_attack_hide_inline.h" - "ai/monsters/controller/controller_state_attack_hide_lite.h" - "ai/monsters/controller/controller_state_attack_hide_lite_inline.h" - "ai/monsters/controller/controller_state_attack_inline.h" - "ai/monsters/controller/controller_state_attack_moveout.h" - "ai/monsters/controller/controller_state_attack_moveout_inline.h" - "ai/monsters/controller/controller_state_control_hit.h" - "ai/monsters/controller/controller_state_control_hit_inline.h" - "ai/monsters/controller/controller_state_manager.cpp" - "ai/monsters/controller/controller_state_manager.h" - "ai/monsters/controller/controller_state_panic.h" - "ai/monsters/controller/controller_tube.h" - "ai/monsters/controller/controller_tube_inline.h" - "ai/monsters/dog/dog.cpp" - "ai/monsters/dog/dog.h" - "ai/monsters/dog/dog_script.cpp" - "ai/monsters/dog/dog_state_manager.cpp" - "ai/monsters/dog/dog_state_manager.h" - "ai/monsters/flesh/flesh.cpp" - "ai/monsters/flesh/flesh.h" - "ai/monsters/flesh/flesh_script.cpp" - "ai/monsters/flesh/flesh_state_manager.cpp" - "ai/monsters/flesh/flesh_state_manager.h" - "ai/monsters/fracture/fracture.cpp" - "ai/monsters/fracture/fracture.h" - "ai/monsters/fracture/fracture_script.cpp" - "ai/monsters/fracture/fracture_state_manager.cpp" - "ai/monsters/fracture/fracture_state_manager.h" - "ai/monsters/group_states/group_state_attack.h" - "ai/monsters/group_states/group_state_attack_inline.h" - "ai/monsters/group_states/group_state_attack_run.h" - "ai/monsters/group_states/group_state_attack_run_inline.h" - "ai/monsters/group_states/group_state_custom.h" - "ai/monsters/group_states/group_state_custom_inline.h" - "ai/monsters/group_states/group_state_eat_drag.h" - "ai/monsters/group_states/group_state_eat_drag_inline.h" - "ai/monsters/group_states/group_state_eat_eat.h" - "ai/monsters/group_states/group_state_eat_eat_inline.h" - "ai/monsters/group_states/group_state_eat.h" - "ai/monsters/group_states/group_state_eat_inline.h" - "ai/monsters/group_states/group_state_hear_danger_sound.h" - "ai/monsters/group_states/group_state_hear_danger_sound_inline.h" - "ai/monsters/group_states/group_state_home_point_attack.h" - "ai/monsters/group_states/group_state_home_point_attack_inline.h" - "ai/monsters/group_states/group_state_panic.h" - "ai/monsters/group_states/group_state_panic_inline.h" - "ai/monsters/group_states/group_state_panic_run.h" - "ai/monsters/group_states/group_state_panic_run_inline.h" - "ai/monsters/group_states/group_state_rest.h" - "ai/monsters/group_states/group_state_rest_idle.h" - "ai/monsters/group_states/group_state_rest_idle_inline.h" - "ai/monsters/group_states/group_state_rest_inline.h" - "ai/monsters/group_states/group_state_squad_move_to_radius.h" - "ai/monsters/group_states/group_state_squad_move_to_radius_inline.h" - "ai/monsters/group_states/state_adapter.h" - "ai/monsters/poltergeist/poltergeist_ability.cpp" - "ai/monsters/poltergeist/poltergeist.cpp" - "ai/monsters/poltergeist/poltergeist_flame_thrower.cpp" - "ai/monsters/poltergeist/poltergeist.h" - "ai/monsters/poltergeist/poltergeist_movement.cpp" - "ai/monsters/poltergeist/poltergeist_movement.h" - "ai/monsters/poltergeist/poltergeist_script.cpp" - "ai/monsters/poltergeist/poltergeist_state_attack_hidden.h" - "ai/monsters/poltergeist/poltergeist_state_attack_hidden_inline.h" - "ai/monsters/poltergeist/poltergeist_state_manager.cpp" - "ai/monsters/poltergeist/poltergeist_state_manager.h" - "ai/monsters/poltergeist/poltergeist_state_rest.h" - "ai/monsters/poltergeist/poltergeist_telekinesis.cpp" - "ai/monsters/pseudodog/pseudodog.cpp" - "ai/monsters/pseudodog/pseudodog.h" - "ai/monsters/pseudodog/pseudodog_psi_effector.cpp" - "ai/monsters/pseudodog/pseudodog_psi_effector.h" - "ai/monsters/pseudodog/pseudodog_script.cpp" - "ai/monsters/pseudodog/pseudodog_state_manager.cpp" - "ai/monsters/pseudodog/pseudodog_state_manager.h" - "ai/monsters/pseudodog/psy_dog_aura.cpp" - "ai/monsters/pseudodog/psy_dog_aura.h" - "ai/monsters/pseudodog/psy_dog.cpp" - "ai/monsters/pseudodog/psy_dog.h" - "ai/monsters/pseudodog/psy_dog_state_manager.cpp" - "ai/monsters/pseudodog/psy_dog_state_manager.h" - "ai/monsters/pseudodog/psy_dog_state_psy_attack.h" - "ai/monsters/pseudodog/psy_dog_state_psy_attack_hide.h" - "ai/monsters/pseudodog/psy_dog_state_psy_attack_hide_inline.h" - "ai/monsters/pseudodog/psy_dog_state_psy_attack_inline.h" - "ai/monsters/pseudogigant/pseudo_gigant.cpp" - "ai/monsters/pseudogigant/pseudo_gigant.h" - "ai/monsters/pseudogigant/pseudogigant_script.cpp" - "ai/monsters/pseudogigant/pseudogigant_state_manager.cpp" - "ai/monsters/pseudogigant/pseudogigant_state_manager.h" - "ai/monsters/pseudogigant/pseudo_gigant_step_effector.cpp" - "ai/monsters/pseudogigant/pseudo_gigant_step_effector.h" - "ai/monsters/rats/ai_rat_animations.cpp" - "ai/monsters/rats/ai_rat_behaviour.cpp" - "ai/monsters/rats/ai_rat.cpp" - "ai/monsters/rats/ai_rat_feel.cpp" - "ai/monsters/rats/ai_rat_fire.cpp" - #"ai/monsters/rats/ai_rat_fsm.cpp" - "ai/monsters/rats/ai_rat.h" - "ai/monsters/rats/ai_rat_impl.h" - "ai/monsters/rats/ai_rat_inline.h" - "ai/monsters/rats/ai_rat_space.h" - "ai/monsters/rats/ai_rat_templates.cpp" - "ai/monsters/rats/rat_state_activation.cpp" - "ai/monsters/rats/rat_state_initialize.cpp" - "ai/monsters/rats/rat_state_switch.cpp" - "ai/monsters/snork/snork.cpp" - "ai/monsters/snork/snork.h" - "ai/monsters/snork/snork_jump.cpp" - "ai/monsters/snork/snork_jump.h" - "ai/monsters/snork/snork_script.cpp" - "ai/monsters/snork/snork_state_manager.cpp" - "ai/monsters/snork/snork_state_manager.h" - "ai/monsters/states/monster_state_attack_camp.h" - "ai/monsters/states/monster_state_attack_camp_inline.h" - "ai/monsters/states/monster_state_attack_camp_stealout.h" - "ai/monsters/states/monster_state_attack_camp_stealout_inline.h" - "ai/monsters/states/monster_state_attack.h" - "ai/monsters/states/monster_state_attack_inline.h" - "ai/monsters/states/monster_state_attack_melee.h" - "ai/monsters/states/monster_state_attack_melee_inline.h" - "ai/monsters/states/monster_state_attack_on_run.h" - "ai/monsters/states/monster_state_attack_on_run_inline.h" - "ai/monsters/states/monster_state_attack_run_attack.h" - "ai/monsters/states/monster_state_attack_run_attack_inline.h" - "ai/monsters/states/monster_state_attack_run.h" - "ai/monsters/states/monster_state_attack_run_inline.h" - "ai/monsters/states/monster_state_controlled_attack.h" - "ai/monsters/states/monster_state_controlled_attack_inline.h" - "ai/monsters/states/monster_state_controlled_follow.h" - "ai/monsters/states/monster_state_controlled_follow_inline.h" - "ai/monsters/states/monster_state_controlled.h" - "ai/monsters/states/monster_state_controlled_inline.h" - "ai/monsters/states/monster_state_eat_drag.h" - "ai/monsters/states/monster_state_eat_drag_inline.h" - "ai/monsters/states/monster_state_eat_eat.h" - "ai/monsters/states/monster_state_eat_eat_inline.h" - "ai/monsters/states/monster_state_eat.h" - "ai/monsters/states/monster_state_eat_inline.h" - "ai/monsters/states/monster_state_find_enemy_angry.h" - "ai/monsters/states/monster_state_find_enemy_angry_inline.h" - "ai/monsters/states/monster_state_find_enemy.h" - "ai/monsters/states/monster_state_find_enemy_inline.h" - "ai/monsters/states/monster_state_find_enemy_look.h" - "ai/monsters/states/monster_state_find_enemy_look_inline.h" - "ai/monsters/states/monster_state_find_enemy_run.h" - "ai/monsters/states/monster_state_find_enemy_run_inline.h" - "ai/monsters/states/monster_state_find_enemy_walk.h" - "ai/monsters/states/monster_state_find_enemy_walk_inline.h" - "ai/monsters/states/monster_state_hear_danger_sound.h" - "ai/monsters/states/monster_state_hear_danger_sound_inline.h" - "ai/monsters/states/monster_state_hear_int_sound.h" - "ai/monsters/states/monster_state_hear_int_sound_inline.h" - "ai/monsters/states/monster_state_help_sound.h" - "ai/monsters/states/monster_state_help_sound_inline.h" - "ai/monsters/states/monster_state_hitted.h" - "ai/monsters/states/monster_state_hitted_hide.h" - "ai/monsters/states/monster_state_hitted_hide_inline.h" - "ai/monsters/states/monster_state_hitted_inline.h" - "ai/monsters/states/monster_state_hitted_moveout.h" - "ai/monsters/states/monster_state_hitted_moveout_inline.h" - "ai/monsters/states/monster_state_home_point_attack.h" - "ai/monsters/states/monster_state_home_point_attack_inline.h" - "ai/monsters/states/monster_state_home_point_danger.h" - "ai/monsters/states/monster_state_home_point_danger_inline.h" - "ai/monsters/states/monster_state_home_point_rest.h" - "ai/monsters/states/monster_state_home_point_rest_inline.h" - "ai/monsters/states/monster_state_panic.h" - "ai/monsters/states/monster_state_panic_inline.h" - "ai/monsters/states/monster_state_panic_run.h" - "ai/monsters/states/monster_state_panic_run_inline.h" - "ai/monsters/states/monster_state_rest_fun.h" - "ai/monsters/states/monster_state_rest_fun_inline.h" - "ai/monsters/states/monster_state_rest.h" - "ai/monsters/states/monster_state_rest_idle.h" - "ai/monsters/states/monster_state_rest_idle_inline.h" - "ai/monsters/states/monster_state_rest_inline.h" - "ai/monsters/states/monster_state_rest_sleep.h" - "ai/monsters/states/monster_state_rest_sleep_inline.h" - "ai/monsters/states/monster_state_rest_walk_graph.h" - "ai/monsters/states/monster_state_rest_walk_graph_inline.h" - "ai/monsters/states/monster_state_smart_terrain_task_graph_walk.h" - "ai/monsters/states/monster_state_smart_terrain_task_graph_walk_inline.h" - "ai/monsters/states/monster_state_smart_terrain_task.h" - "ai/monsters/states/monster_state_smart_terrain_task_inline.h" - "ai/monsters/states/monster_state_squad_rest_follow.h" - "ai/monsters/states/monster_state_squad_rest_follow_inline.h" - "ai/monsters/states/monster_state_squad_rest.h" - "ai/monsters/states/monster_state_squad_rest_inline.h" - "ai/monsters/states/monster_state_steal.h" - "ai/monsters/states/monster_state_steal_inline.h" - "ai/monsters/states/state_custom_action.h" - "ai/monsters/states/state_custom_action_inline.h" - "ai/monsters/states/state_custom_action_look.h" - "ai/monsters/states/state_custom_action_look_inline.h" - "ai/monsters/states/state_data.h" - "ai/monsters/states/state_hide_from_point.h" - "ai/monsters/states/state_hide_from_point_inline.h" - "ai/monsters/states/state_hit_object.h" - "ai/monsters/states/state_hit_object_inline.h" - "ai/monsters/states/state_look_point.h" - "ai/monsters/states/state_look_point_inline.h" - "ai/monsters/states/state_look_unprotected_area.h" - "ai/monsters/states/state_look_unprotected_area_inline.h" - "ai/monsters/states/state_move_around_point.h" - "ai/monsters/states/state_move_around_point_inline.h" - "ai/monsters/states/state_move_to_point.h" - "ai/monsters/states/state_move_to_point_inline.h" - "ai/monsters/states/state_move_to_restrictor.h" - "ai/monsters/states/state_move_to_restrictor_inline.h" - "ai/monsters/states/state_test_look_actor.h" - "ai/monsters/states/state_test_look_actor_inline.h" - "ai/monsters/states/state_test_state.h" - "ai/monsters/states/state_test_state_inline.h" - "ai/monsters/tushkano/tushkano.cpp" - "ai/monsters/tushkano/tushkano.h" - "ai/monsters/tushkano/tushkano_script.cpp" - "ai/monsters/tushkano/tushkano_state_manager.cpp" - "ai/monsters/tushkano/tushkano_state_manager.h" - "ai/monsters/zombie/zombie.cpp" - "ai/monsters/zombie/zombie.h" - "ai/monsters/zombie/zombie_script.cpp" - "ai/monsters/zombie/zombie_state_attack_run.h" - "ai/monsters/zombie/zombie_state_attack_run_inline.h" - "ai/monsters/zombie/zombie_state_manager.cpp" - "ai/monsters/zombie/zombie_state_manager.h" - "ai/phantom/phantom.cpp" - "ai/phantom/phantom.h" - "ai/stalker/ai_stalker_cover.cpp" - "ai/stalker/ai_stalker.cpp" - "ai/stalker/ai_stalker_debug.cpp" - "ai/stalker/ai_stalker_events.cpp" - "ai/stalker/ai_stalker_feel.cpp" - "ai/stalker/ai_stalker_fire.cpp" - "ai/stalker/ai_stalker.h" - "ai/stalker/ai_stalker_impl.h" - "ai/stalker/ai_stalker_inline.h" - "ai/stalker/ai_stalker_misc.cpp" - "ai/stalker/ai_stalker_script.cpp" - "ai/stalker/ai_stalker_script_entity.cpp" - "ai/stalker/ai_stalker_space.h" - "ai/trader/ai_trader.cpp" - "ai/trader/ai_trader.h" - "ai/trader/ai_trader_script.cpp" - "ai/trader/trader_animation.cpp" - "ai/trader/trader_animation.h" - "CdkeyDecode/base32.c" - "CdkeyDecode/base32.h" - "CdkeyDecode/cdkeydecode.c" - "CdkeyDecode/cdkeydecode.h" - "ik/aint.cxx" - "ik/aint.h" - "ik/Dof7control.cpp" - "ik/Dof7control.h" - "ik/eqn.cxx" - "ik/eqn.h" - "ik/eulersolver.cxx" - "ik/eulersolver.h" - "ik/IKLimb.cpp" - "ik/IKLimb.h" - "ik/jtlimits.cxx" - "ik/jtlimits.h" - "ik/limb.cxx" - "ik/limb.h" - "ik/math3d.cpp" - "ik/math3d.h" - "ik/mathTrig.cpp" - "ik/mathTrig.h" - "ui/ArtefactDetectorUI.cpp" - "ui/ArtefactDetectorUI.h" - #"ui/CExtraContentFilter.cpp" - #"ui/CExtraContentFilter.h" - "ui/ChangeWeatherDialog.cpp" - "ui/ChangeWeatherDialog.hpp" - "ui/FactionState.cpp" - "ui/FactionState.h" - "ui/FactionState_inline.h" - "ui/FractionState.cpp" - "ui/FractionState.h" - "ui/FractionState_inline.h" - "ui/KillMessageStruct.h" - "ui/map_hint.cpp" - "ui/map_hint.h" - "ui/MMSound.cpp" - "ui/MMSound.h" - "ui/Restrictions.cpp" - "ui/Restrictions.h" - "ui/ServerList.cpp" - "ui/ServerList_GameSpy_func.cpp" - "ui/ServerList.h" - "ui/TeamInfo.cpp" - "ui/TeamInfo.h" - "ui/UIAchievements.cpp" - "ui/UIAchievements.h" - "ui/UIActorInfo.cpp" - "ui/UIActorInfo.h" - "ui/UIActorMenu_action.cpp" - "ui/UIActorMenu.cpp" - "ui/UIActorMenuDeadBodySearch.cpp" - "ui/UIActorMenu.h" - "ui/UIActorMenuInitialize.cpp" - "ui/UIActorMenuInventory.cpp" - "ui/UIActorMenu_script.cpp" - "ui/UIActorMenuTrade.cpp" - "ui/UIActorMenuUpgrade.cpp" - "ui/UIActorStateInfo.cpp" - "ui/UIActorStateInfo.h" - "ui/ui_af_params.cpp" - "ui/ui_af_params.h" - "ui/UIArtefactPanel.cpp" - "ui/UIArtefactPanel.h" - "ui/UIBoosterInfo.cpp" - "ui/UIBoosterInfo.h" - "ui/UIBuyWeaponTab.cpp" - "ui/UIBuyWeaponTab.h" - "ui/UIBuyWndBase.h" - "ui/UIBuyWndShared.cpp" - "ui/UIBuyWndShared.h" - "ui/UICarPanel.cpp" - "ui/UICarPanel.h" - "ui/UICDkey.cpp" - "ui/UICDkey.h" - "ui/UICellCustomItems.cpp" - "ui/UICellCustomItems.h" - "ui/UICellItem.cpp" - "ui/UICellItemFactory.cpp" - "ui/UICellItemFactory.h" - "ui/UICellItem.h" - "ui/UIChangeMap.cpp" - "ui/UIChangeMap.h" - "ui/UICharacterInfo.cpp" - "ui/UICharacterInfo.h" - "ui/UIChatWnd.cpp" - "ui/UIChatWnd.h" - "ui/UIColorAnimatorWrapper.cpp" - "ui/UIColorAnimatorWrapper.h" - "ui/UIDebugFonts.cpp" - "ui/UIDebugFonts.h" - "ui/UIDemoPlayControl.cpp" - "ui/UIDemoPlayControl.h" - "ui/UIDialogWnd.cpp" - "ui/UIDialogWnd.h" - "ui/UIDiaryWnd.h" - "ui/UIDragDropListEx.cpp" - "ui/UIDragDropListEx.h" - "ui/UIDragDropReferenceList.cpp" - "ui/UIDragDropReferenceList.h" - "ui/UIEditKeyBind.cpp" - "ui/UIEditKeyBind.h" - "ui/UIFactionWarWnd.cpp" - "ui/UIFactionWarWnd.h" - #"ui/UIFrags2.cpp" - #"ui/UIFrags2.h" - #"ui/UIFrags.cpp" - #"ui/UIFrags.h" - #"ui/UIFrameLine.cpp" - #"ui/UIFrameLine.h" - "ui/UIGameLog.cpp" - "ui/UIGameLog.h" - "ui/UIGameTutorial.cpp" - "ui/UIGameTutorial.h" - "ui/UIGameTutorialSimpleItem.cpp" - "ui/UIGameTutorialVideoItem.cpp" - "ui/UIHelper.cpp" - "ui/UIHelper.h" - "ui/UIHudStatesWnd.cpp" - "ui/UIHudStatesWnd.h" - "ui/UIInventoryUpgradeWnd_add.cpp" - "ui/UIInventoryUpgradeWnd.cpp" - "ui/UIInventoryUpgradeWnd.h" - "ui/UIInventoryUtilities.cpp" - "ui/UIInventoryUtilities.h" - "ui/UIInvUpgrade.cpp" - "ui/UIInvUpgrade.h" - "ui/UIInvUpgradeInfo.cpp" - "ui/UIInvUpgradeInfo.h" - "ui/UIInvUpgradeProperty.cpp" - "ui/UIInvUpgradeProperty.h" - "ui/UIItemInfo.cpp" - "ui/UIItemInfo.h" - "ui/UIKeyBinding.cpp" - "ui/UIKeyBinding.h" - "ui/UIKickPlayer.cpp" - "ui/UIKickPlayer.h" - "ui/UILabel.cpp" - "ui/UILabel.h" - #"ui/UIListBox_script.cpp" - #"ui/UIListItemAdv.cpp" - #"ui/UIListItemAdv.h" - #"ui/UIListItemEx.cpp" - #"ui/UIListItemEx.h" - #"ui/UIListItem.cpp" - #"ui/UIListItem.h" - "ui/UIListItemServer.cpp" - "ui/UIListItemServer.h" - #"ui/UIListWnd.cpp" - #"ui/UIListWnd.h" - #"ui/UIListWnd_inline.h" - #"ui/UIListWnd_script.cpp" - "ui/UILoadingScreen.cpp" - "ui/UILoadingScreen.h" - "ui/UILoadingScreenHardcoded.h" - "ui/UILogsWnd.cpp" - "ui/UILogsWnd.h" - "ui/UIMainIngameWnd.cpp" - "ui/UIMainIngameWnd.h" - "ui/UIMap.cpp" - "ui/UIMapDesc.cpp" - "ui/UIMapDesc.h" - "ui/UIMapFilters.cpp" - "ui/UIMapFilters.h" - "ui/UIMap.h" - "ui/UIMapInfo.cpp" - "ui/UIMapInfo.h" - "ui/UIMapInfo_script.cpp" - "ui/UIMapLegend.cpp" - "ui/UIMapLegend.h" - "ui/UIMapList.cpp" - "ui/UIMapList.h" - "ui/UIMapWnd2.cpp" - "ui/UIMapWndActions.cpp" - "ui/UIMapWndActions.h" - "ui/UIMapWndActionsSpace.h" - "ui/UIMapWnd.cpp" - "ui/UIMapWnd.h" - "ui/UIMessageBoxEx.cpp" - "ui/UIMessageBoxEx.h" - "ui/UIMessagesWindow.cpp" - "ui/UIMessagesWindow.h" - "ui/UIMMShniaga.cpp" - "ui/UIMMShniaga.h" - "ui/UIMoneyIndicator.cpp" - "ui/UIMoneyIndicator.h" - "ui/UIMotionIcon.cpp" - "ui/UIMotionIcon.h" - "ui/UIMPAdminMenu.cpp" - "ui/UIMPAdminMenu.h" - "ui/UIMPChangeMapAdm.cpp" - "ui/UIMPChangeMapAdm.h" - "ui/UIMpItemsStoreWnd.cpp" - "ui/UIMpItemsStoreWnd.h" - "ui/UIMPPlayersAdm.cpp" - "ui/UIMPPlayersAdm.h" - "ui/UIMPServerAdm.cpp" - "ui/UIMPServerAdm.h" - "ui/UIMpTradeWnd.cpp" - "ui/UIMpTradeWnd.h" - "ui/UIMpTradeWnd_init.cpp" - "ui/UIMpTradeWnd_items.cpp" - "ui/UIMpTradeWnd_misc.cpp" - "ui/UIMpTradeWnd_trade.cpp" - "ui/UIMpTradeWnd_wpn.cpp" - "ui/UINewsItemWnd.cpp" - "ui/UINewsItemWnd.h" - "ui/UIOptConCom.cpp" - "ui/UIOptConCom.h" - "ui/UIOutfitInfo.cpp" - "ui/UIOutfitInfo.h" - "ui/UIOutfitSlot.cpp" - "ui/UIOutfitSlot.h" - "ui/UIPdaKillMessage.cpp" - "ui/UIPdaKillMessage.h" - "ui/UIPdaMsgListItem.cpp" - "ui/UIPdaMsgListItem.h" - "ui/UIPdaWnd.cpp" - "ui/UIPdaWnd.h" - "ui/UIRankFaction.cpp" - "ui/UIRankFaction.h" - "ui/UIRankIndicator.cpp" - "ui/UIRankIndicator.h" - "ui/UIRankingWnd.cpp" - "ui/UIRankingWnd.h" - "ui/UIScriptWnd.cpp" - "ui/UIScriptWnd.h" - "ui/UIScriptWnd_script.cpp" - "ui/UISecondTaskWnd.cpp" - "ui/UISecondTaskWnd.h" - "ui/UIServerInfo.cpp" - "ui/UIServerInfo.h" - "ui/UISkinSelector.cpp" - "ui/UISkinSelector.h" - "ui/UISleepStatic.cpp" - "ui/UISleepStatic.h" - "ui/UISpawnWnd.cpp" - "ui/UISpawnWnd.h" - "ui/UISpeechMenu.cpp" - "ui/UISpeechMenu.h" - "ui/UIStatix.cpp" - "ui/UIStatix.h" - "ui/UIStats.cpp" - "ui/UIStats.h" - "ui/UIStatsIcon.cpp" - "ui/UIStatsIcon.h" - "ui/UIStatsPlayerInfo.cpp" - "ui/UIStatsPlayerInfo.h" - "ui/UIStatsPlayerList.cpp" - "ui/UIStatsPlayerList.h" - "ui/UITabButtonMP.cpp" - "ui/UITabButtonMP.h" - "ui/UITalkDialogWnd.cpp" - "ui/UITalkDialogWnd.h" - "ui/UITalkWnd.cpp" - "ui/UITalkWnd.h" - "ui/UITaskWnd.cpp" - "ui/UITaskWnd.h" - #"ui/UITextBanner.cpp" - #"ui/UITextBanner.h" - "ui/UITextVote.cpp" - "ui/UITextVote.h" - "ui/UITradeBar.cpp" - "ui/UITradeBar.h" - "ui/UITradeWnd.cpp" - "ui/UITradeWnd.h" - "ui/UIVersionList.cpp" - "ui/UIVersionList.h" - "ui/UIVote.cpp" - "ui/UIVote.h" - "ui/UIVoteStatusWnd.cpp" - "ui/UIVoteStatusWnd.h" - "ui/UIVotingCategory.cpp" - "ui/UIVotingCategory.h" - "ui/UIWarState.cpp" - "ui/UIWarState.h" - "ui/UIWeightBar.cpp" - "ui/UIWeightBar.h" - "ui/UIWindow_script.cpp" - "ui/UIWpnParams.cpp" - "ui/UIWpnParams.h" - "ui/UIXmlInit.cpp" - "ui/UIXmlInit.h" - "gamespy/GameSpy_QR2_callbacks.cpp" - "gamespy/GameSpy_QR2_callbacks.h" - "../xrServerEntities/ai_sounds.h" - "../xrServerEntities/alife_human_brain.cpp" - "../xrServerEntities/alife_human_brain.h" - "../xrServerEntities/alife_human_brain_inline.h" - "../xrServerEntities/alife_monster_brain.cpp" - "../xrServerEntities/alife_monster_brain.h" - "../xrServerEntities/alife_monster_brain_inline.h" - "../xrServerEntities/alife_movement_manager_holder.h" - "../xrServerEntities/alife_space.cpp" - "../xrServerEntities/alife_space.h" - "../xrServerEntities/character_info.cpp" - "../xrServerEntities/character_info_defs.h" - "../xrServerEntities/character_info.h" - "../xrServerEntities/clsid_game.h" - "../xrServerEntities/game_base_space.h" - "../xrServerEntities/gametype_chooser.cpp" - "../xrServerEntities/gametype_chooser.h" - "../xrServerEntities/InfoPortionDefs.h" - "../xrServerEntities/inventory_space.h" - "../xrServerEntities/ItemListTypes.h" - "../xrServerEntities/object_factory.cpp" - "../xrServerEntities/object_factory.h" - "../xrServerEntities/object_factory_impl.h" - "../xrServerEntities/object_factory_inline.h" - "../xrServerEntities/object_factory_register.cpp" - "../xrServerEntities/object_factory_script.cpp" - "../xrServerEntities/object_factory_space.h" - "../xrServerEntities/object_item_abstract.h" - "../xrServerEntities/object_item_abstract_inline.h" - "../xrServerEntities/object_item_client_server.h" - "../xrServerEntities/object_item_client_server_inline.h" - "../xrServerEntities/object_item_script.cpp" - "../xrServerEntities/object_item_script.h" - "../xrServerEntities/object_item_single.h" - "../xrServerEntities/object_item_single_inline.h" - "../xrServerEntities/pch_script.cpp" - "../xrServerEntities/pch_script.h" - "../xrServerEntities/PHNetState.h" - "../xrServerEntities/PHSynchronize.h" - "../xrServerEntities/PropertiesListHelper.h" - "../xrServerEntities/PropertiesListTypes.h" - "../xrServerEntities/restriction_space.h" - "../xrServerEntities/script_fcolor_script.cpp" - "../xrServerEntities/script_flags_script.cpp" - "../xrServerEntities/script_fmatrix_script.cpp" - "../xrServerEntities/script_fvector_script.cpp" - "../xrServerEntities/script_ini_file.cpp" - "../xrServerEntities/script_ini_file.h" - "../xrServerEntities/script_ini_file_script.cpp" - "../xrServerEntities/script_net_packet_script.cpp" - "../xrServerEntities/script_reader_script.cpp" - "../xrServerEntities/script_rtoken_list.h" - "../xrServerEntities/script_rtoken_list_inline.h" - "../xrServerEntities/script_rtoken_list_script.cpp" - "../xrServerEntities/script_sound_type_script.cpp" - "../xrServerEntities/script_token_list.cpp" - "../xrServerEntities/script_token_list.h" - "../xrServerEntities/script_token_list_script.cpp" - "../xrServerEntities/script_value_container.h" - "../xrServerEntities/script_value_container_impl.h" - "../xrServerEntities/ShapeData.h" - "../xrServerEntities/shared_data.h" - "../xrServerEntities/smart_cast.cpp" - "../xrServerEntities/smart_cast.h" - "../xrServerEntities/smart_cast_impl0.h" - "../xrServerEntities/smart_cast_impl1.h" - "../xrServerEntities/smart_cast_impl2.h" - "../xrServerEntities/smart_cast_stats.cpp" - "../xrServerEntities/specific_character.cpp" - "../xrServerEntities/specific_character.h" - "../xrServerEntities/xml_str_id_loader.h" - "../xrServerEntities/xrEProps.h" - "../xrServerEntities/xrMessages.h" - "../xrServerEntities/xrServer_Factory.cpp" - "../xrServerEntities/xrServer_Object_Base.cpp" - "../xrServerEntities/xrServer_Object_Base.h" - "../xrServerEntities/xrServer_Objects_Abstract.cpp" - "../xrServerEntities/xrServer_Objects_Abstract.h" - "../xrServerEntities/xrServer_Objects_ALife_All.h" - "../xrServerEntities/xrServer_Objects_ALife.cpp" - "../xrServerEntities/xrServer_Objects_ALife.h" - "../xrServerEntities/xrServer_Objects_ALife_Items.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Items.h" - "../xrServerEntities/xrServer_Objects_ALife_Items_script2.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Items_script3.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Items_script.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Monsters.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Monsters.h" - "../xrServerEntities/xrServer_Objects_ALife_Monsters_script2.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Monsters_script3.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Monsters_script4.cpp" - "../xrServerEntities/xrServer_Objects_ALife_Monsters_script.cpp" - "../xrServerEntities/xrServer_Objects_ALife_script2.cpp" - "../xrServerEntities/xrServer_Objects_ALife_script3.cpp" - "../xrServerEntities/xrServer_Objects_ALife_script.cpp" - "../xrServerEntities/xrServer_Objects_Alife_Smartcovers.cpp" - "../xrServerEntities/xrServer_Objects_Alife_Smartcovers.h" - "../xrServerEntities/xrServer_Objects_Alife_Smartcovers_script.cpp" - "../xrServerEntities/xrServer_Objects.cpp" - "../xrServerEntities/xrServer_Objects.h" - "../xrServerEntities/xrServer_Objects_script2.cpp" - "../xrServerEntities/xrServer_Objects_script.cpp" - "../xrServerEntities/xrServer_script_macroses.h" - "../xrServerEntities/xrServer_Space.h" +target_sources(xrGame PRIVATE + abstract_location_selector.h + abstract_location_selector_inline.h + abstract_path_manager.h + abstract_path_manager_inline.h + account_manager_console.cpp + account_manager_console.h + account_manager.cpp + account_manager.h + account_manager_script.cpp + accumulative_states.h + action_base.h + action_base_inline.h + action_base_script.cpp + action_management_config.h + action_planner_action.h + action_planner_action_inline.h + action_planner_action_script.cpp + action_planner_action_script.h + action_planner_action_script_inline.h + action_planner.h + action_planner_inline.h + action_planner_script.cpp + action_planner_script.h + action_planner_script_inline.h + action_script_base.h + action_script_base_inline.h + ActivatingCharCollisionDelay.cpp + ActivatingCharCollisionDelay.h + ActorAnimation.cpp + ActorAnimation.h + actor_anim_defs.h + ActorCameras.cpp + actor_communication.cpp + ActorCondition.cpp + ActorCondition.h + Actor.cpp + actor_defs.h + ActorEffector.cpp + ActorEffector.h + ActorEffector_script.cpp + Actor_Events.cpp + Actor_Feel.cpp + Actor_Flags.h + ActorFollowers.cpp + ActorFollowers.h + Actor.h + ActorHelmet.cpp + ActorHelmet.h + ActorBackpack.cpp + ActorBackpack.h + ActorInput.cpp + actor_input_handler.cpp + actor_input_handler.h + actor_memory.cpp + actor_memory.h + ActorMountedWeapon.cpp + Actor_Movement.cpp + actor_mp_client.cpp + actor_mp_client_export.cpp + actor_mp_client.h + actor_mp_client_import.cpp + actor_mp_server.cpp + actor_mp_server_export.cpp + actor_mp_server.h + actor_mp_server_import.cpp + actor_mp_state.cpp + actor_mp_state.h + actor_mp_state_inline.h + Actor_Network.cpp + actor_script.cpp + Actor_Sleep.cpp + actor_statistic_defs.h + actor_statistic_mgr.cpp + actor_statistic_mgr.h + ActorVehicle.cpp + Actor_Weapon.cpp + AdvancedDetector.cpp + AdvancedDetector.h + agent_corpse_manager.cpp + agent_corpse_manager.h + agent_corpse_manager_inline.h + agent_enemy_manager.cpp + agent_enemy_manager.h + agent_enemy_manager_inline.h + agent_explosive_manager.cpp + agent_explosive_manager.h + agent_explosive_manager_inline.h + agent_location_manager.cpp + agent_location_manager.h + agent_location_manager_inline.h + agent_manager_actions.cpp + agent_manager_actions.h + agent_manager.cpp + agent_manager.h + agent_manager_inline.h + agent_manager_planner.cpp + agent_manager_planner.h + agent_manager_properties.cpp + agent_manager_properties.h + agent_manager_properties_inline.h + agent_manager_space.h + agent_member_manager.cpp + agent_member_manager.h + agent_member_manager_inline.h + agent_memory_manager.cpp + agent_memory_manager.h + agent_memory_manager_inline.h + ai_crow_script.cpp + ai_debug.h + ai_debug_variables.cpp + ai_debug_variables.h + aimers_base.cpp + aimers_base.h + aimers_base_inline.h + aimers_bone.h + aimers_bone_inline.h + aimers_weapon.cpp + aimers_weapon.h + aimers_weapon_inline.h + ai_monster_space.h + ai_obstacle.cpp + ai_obstacle.h + ai_obstacle_inline.h + AI_PhraseDialogManager.cpp + AI_PhraseDialogManager.h + ai_sounds.cpp + ai_space.cpp + ai_space.h + ai_space_inline.h + ai_stalker_alife.cpp + alife_abstract_registry.h + alife_abstract_registry_inline.h + alife_anomalous_zone.cpp + alife_combat_manager.cpp + alife_combat_manager.h + alife_combat_manager_inline.h + alife_communication_manager.cpp + alife_communication_manager.h + alife_communication_manager_inline.h + alife_communication_space.h + alife_creature_abstract.cpp + alife_dynamic_object.cpp + alife_graph_registry.cpp + alife_graph_registry.h + alife_graph_registry_inline.h + alife_group_abstract.cpp + alife_group_registry.cpp + alife_group_registry.h + alife_group_registry_inline.h + alife_human_abstract.cpp + alife_human_brain_save.h + alife_human_brain_script.cpp + alife_human_object_handler.cpp + alife_human_object_handler.h + alife_human_object_handler_inline.h + alife_human_object_handler_save.h + alife_interaction_manager.cpp + alife_interaction_manager.h + alife_interaction_manager_inline.h + alife_level_registry.h + alife_level_registry_inline.h + alife_monster_abstract.cpp + alife_monster_base.cpp + alife_monster_brain_script.cpp + alife_monster_detail_path_manager.cpp + alife_monster_detail_path_manager.h + alife_monster_detail_path_manager_inline.h + alife_monster_detail_path_manager_script.cpp + alife_monster_movement_manager.cpp + alife_monster_movement_manager.h + alife_monster_movement_manager_inline.h + alife_monster_movement_manager_script.cpp + alife_monster_patrol_path_manager.cpp + alife_monster_patrol_path_manager.h + alife_monster_patrol_path_manager_inline.h + alife_monster_patrol_path_manager_script.cpp + alife_object.cpp + alife_object_registry.cpp + alife_object_registry.h + alife_object_registry_inline.h + alife_online_offline_group_brain.cpp + alife_online_offline_group_brain.h + alife_online_offline_group_brain_inline.h + alife_online_offline_group.cpp + alife_registry_container_composition.h + alife_registry_container.cpp + alife_registry_container.h + alife_registry_container_inline.h + alife_registry_container_space.h + alife_registry_wrapper.h + alife_registry_wrappers.h + alife_schedule_registry.cpp + alife_schedule_registry.h + alife_schedule_registry_inline.h + alife_simulator_base2.cpp + alife_simulator_base.cpp + alife_simulator_base.h + alife_simulator_base_inline.h + alife_simulator.cpp + alife_simulator.h + alife_simulator_header.cpp + alife_simulator_header.h + alife_simulator_header_inline.h + alife_simulator_script.cpp + alife_smart_terrain_registry.cpp + alife_smart_terrain_registry.h + alife_smart_terrain_registry_inline.h + alife_smart_terrain_task.cpp + alife_smart_terrain_task.h + alife_smart_terrain_task_inline.h + alife_smart_terrain_task_script.cpp + alife_smart_zone.cpp + alife_spawn_registry.cpp + alife_spawn_registry.h + alife_spawn_registry_header.cpp + alife_spawn_registry_header.h + alife_spawn_registry_header_inline.h + alife_spawn_registry_inline.h + alife_spawn_registry_spawn.cpp + alife_storage_manager.cpp + alife_storage_manager.h + alife_storage_manager_inline.h + alife_story_registry.cpp + alife_story_registry.h + alife_story_registry_inline.h + alife_surge_manager.cpp + alife_surge_manager.h + alife_surge_manager_inline.h + alife_switch_manager.cpp + alife_switch_manager.h + alife_switch_manager_inline.h + alife_time_manager.cpp + alife_time_manager.h + alife_time_manager_inline.h + alife_trader_abstract.cpp + alife_trader.cpp + alife_update_manager.cpp + alife_update_manager.h + AmebaZone.cpp + AmebaZone.h + ammunition_groups.cpp + ammunition_groups.h + animation_movement_controller.cpp + animation_movement_controller.h + animation_script_callback.cpp + animation_script_callback.h + animation_utils.cpp + animation_utils.h + #AnselManager.cpp + #AnselManager.h + anticheat_dumpable_object.h + antirad.cpp + antirad.h + artefact_activation.cpp + artefact_activation.h + Artefact.cpp + Artefact.h + artefact_script.cpp + atlas_stalkercoppc_v1.c + atlas_stalkercoppc_v1.h + #atlas_stalkercs_v1.c + #atlas_stalkercs_v1.h + atlas_submit_queue.cpp + atlas_submit_queue.h + attachable_item.cpp + attachable_item.h + attachable_item_inline.h + attachment_owner.cpp + attachment_owner.h + autosave_manager.cpp + autosave_manager.h + autosave_manager_inline.h + awards_store.cpp + awards_store.h + base_client_classes_script.cpp + base_client_classes_wrappers.h + BastArtifact.cpp + BastArtifact.h + battleye.h + #battleye_system.cpp + #battleye_system.h + best_scores_helper.cpp + best_scores_helper.h + best_scores_store.cpp + best_scores_store.h + BlackDrops.cpp + BlackDrops.h + BlackGraviArtifact.cpp + BlackGraviArtifact.h + black_list.cpp + black_list.h + BlockAllocator.h + Bolt.cpp + Bolt.h + bone_groups.cpp + bone_groups.h + BoneProtections.cpp + BoneProtections.h + BottleItem.cpp + BottleItem.h + BreakableObject.cpp + BreakableObject.h + CameraEffector.cpp + CameraEffector.h + CameraFirstEye.cpp + CameraFirstEye.h + CameraLook.cpp + CameraLook.h + CameraRecoil.h + CaptureBoneCallback.h + CarCameras.cpp + Car.cpp + CarDamageParticles.cpp + CarDamageParticles.h + CarDoors.cpp + CarExhaust.cpp + Car.h + CarInput.cpp + CarLights.cpp + CarLights.h + car_memory.cpp + car_memory.h + CarScript.cpp + CarSound.cpp + CarWeapon.cpp + CarWeapon.h + CarWheels.cpp + cdkey_ban_list.cpp + cdkey_ban_list.h + character_community.cpp + character_community.h + character_hit_animations.cpp + character_hit_animations.h + character_hit_animations_params.h + CharacterPhysicsSupport.cpp + CharacterPhysicsSupport.h + character_rank.cpp + character_rank.h + character_reputation.cpp + character_reputation.h + character_shell_control.cpp + character_shell_control.h + client_spawn_manager.cpp + client_spawn_manager.h + client_spawn_manager_inline.h + client_spawn_manager_script.cpp + ClimableObject.cpp + ClimableObject.h + command_switch_counter.h + configs_common.cpp + configs_common.h + configs_dumper.cpp + configs_dumper.h + configs_dump_verifyer.cpp + configs_dump_verifyer.h + console_commands.cpp + console_commands_mp.cpp + console_registrator_script.cpp + ContextMenu.cpp + ContextMenu.h + control_action.h + control_action_inline.h + controller_state_panic_inline.h + cover_evaluators.cpp + cover_evaluators.h + cover_evaluators_inline.h + cover_manager.cpp + cover_manager.h + cover_manager_inline.h + cover_point.h + cover_point_inline.h + cover_point_script.cpp + cta_game_artefact_activation.cpp + cta_game_artefact_activation.h + cta_game_artefact.cpp + cta_game_artefact.h + CustomDetector.cpp + CustomDetector.h + CustomMonster.cpp + CustomMonster.h + CustomMonster_inline.h + CustomMonster_VCPU.cpp + CustomOutfit_script.cpp + CustomOutfit.cpp + CustomOutfit.h + CustomRocket.cpp + CustomRocket.h + CustomZone.cpp + CustomZone.h + CycleConstStorage.h + DamagableItem.cpp + DamagableItem.h + damage_manager.cpp + damage_manager.h + danger_cover_location.cpp + danger_cover_location.h + danger_cover_location_inline.h + danger_explosive.cpp + danger_explosive.h + danger_explosive_inline.h + danger_location.cpp + danger_location.h + danger_location_inline.h + danger_manager.cpp + danger_manager.h + danger_manager_inline.h + danger_object.cpp + danger_object.h + danger_object_inline.h + danger_object_location.cpp + danger_object_location.h + danger_object_location_inline.h + date_time.cpp + date_time.h + DBG_Car.cpp + dbg_draw_frustum.cpp + death_anims.cpp + death_anims.h + death_anims_predicates.cpp + debug_renderer.cpp + debug_renderer.h + debug_renderer_inline.h + debug_text_tree.cpp + debug_text_tree.h + debug_text_tree_inline.h + DelayedActionFuse.cpp + DelayedActionFuse.h + DemoInfo.cpp + DemoInfo.h + DemoInfo_Loader.cpp + DemoInfo_Loader.h + DemoPLay_Control.cpp + DemoPlay_Control.h + DestroyablePhysicsObject.cpp + DestroyablePhysicsObject.h + detail_path_builder.h + detail_path_manager.cpp + detail_path_manager.h + detail_path_manager_inline.h + detail_path_manager_smooth.cpp + detail_path_manager_space.h + doors_actor.cpp + doors_actor.h + doors_door.cpp + doors_door.h + doors.h + doors_manager.cpp + doors_manager.h + double_shot_double_kill.cpp + double_shot_double_kill.h + DummyArtifact.cpp + DummyArtifact.h + #DynamicHeightMap.cpp + #DynamicHeightMap.h + dynamic_obstacles_avoider.cpp + dynamic_obstacles_avoider.h + dynamic_obstacles_avoider_inline.h + eatable_item.cpp + eatable_item.h + eatable_item_object.cpp + eatable_item_object.h + ef_base.h + EffectorBobbing.cpp + EffectorBobbing.h + EffectorFall.cpp + EffectorFall.h + EffectorShot.cpp + EffectorShot.h + EffectorShotX.cpp + EffectorShotX.h + EffectorZoomInertion.cpp + EffectorZoomInertion.h + ef_pattern.cpp + ef_pattern.h + ef_primary.cpp + ef_primary.h + ef_storage.cpp + ef_storage.h + ef_storage_inline.h + ef_storage_script.cpp + ElectricBall.cpp + ElectricBall.h + EliteDetector.cpp + EliteDetector.h + encyclopedia_article.cpp + encyclopedia_article_defs.h + encyclopedia_article.h + enemy_manager.cpp + enemy_manager.h + enemy_manager_inline.h + entity_alive.cpp + entity_alive.h + entity_alive_inline.h + EntityCondition.cpp + EntityCondition.h + EntityCondition_script.cpp + Entity.cpp + Entity.h + event_conditions_collection.cpp + event_conditions_collection.h + ExoOutfit.cpp + ExoOutfit.h + Explosive.cpp + Explosive.h + ExplosiveItem.cpp + ExplosiveItem.h + ExplosiveRocket.cpp + ExplosiveRocket.h + ExplosiveScript.cpp + F1.h + FadedBall.cpp + FadedBall.h + faster_than_bullets_time.cpp + faster_than_bullets_time.h + filereceiver_node.cpp + filereceiver_node.h + filetransfer_common.h + file_transfer.cpp + file_transfer.h + filetransfer_node.cpp + filetransfer_node.h + firedeps.h + fire_disp_controller.cpp + fire_disp_controller.h + first_bullet_controller.cpp + first_bullet_controller.h + flare.cpp + flare.h + FoodItem.cpp + FoodItem.h + FryupZone.cpp + FryupZone.h + fs_registrator_script.cpp + GalantineArtifact.cpp + GalantineArtifact.h + game_base.cpp + game_base.h + game_base_kill_type.h + game_base_menu_events.h + game_base_script.cpp + game_cl_artefacthunt.cpp + game_cl_artefacthunt.h + game_cl_artefacthunt_snd_msg.h + game_cl_base.cpp + game_cl_base.h + game_cl_base_script.cpp + game_cl_base_weapon_usage_statistic.cpp + game_cl_base_weapon_usage_statistic.h + game_cl_base_weapon_usage_statistic_save.cpp + game_cl_capturetheartefact_buywnd.cpp + game_cl_capture_the_artefact_captions_manager.cpp + game_cl_capture_the_artefact_captions_manager.h + game_cl_capture_the_artefact.cpp + game_cl_capture_the_artefact.h + game_cl_capture_the_artefact_messages_menu.cpp + game_cl_capturetheartefact_snd_msg.h + game_cl_deathmatch_buywnd.cpp + game_cl_deathmatch.cpp + game_cl_deathmatch.h + game_cl_deathmatch_snd_messages.h + game_cl_mp.cpp + game_cl_mp.h + game_cl_mp_messages_menu.cpp + game_cl_mp_messages_menu.h + game_cl_mp_script.cpp + game_cl_mp_script.h + game_cl_mp_snd_messages.cpp + game_cl_mp_snd_messages.h + game_cl_single.cpp + game_cl_single.h + game_cl_teamdeathmatch.cpp + game_cl_teamdeathmatch.h + game_cl_teamdeathmatch_snd_messages.h + game_events_handler.h + game_location_selector.h + game_location_selector_inline.h + game_news.cpp + game_news.h + GameObject.cpp + GameObject.h + game_object_space.h + game_path_manager.h + game_path_manager_inline.h + GamePersistent.cpp + GamePersistent.h + game_state_accumulator.cpp + game_state_accumulator.h + game_state_accumulator_inline.h + game_state_accumulator_state_register.cpp + game_sv_artefacthunt.cpp + game_sv_artefacthunt.h + game_sv_artefacthunt_process_event.cpp + game_sv_base_console_vars.cpp + game_sv_base_console_vars.h + game_sv_base.cpp + game_sv_base.h + game_sv_base_script.cpp + game_sv_capture_the_artefact_buy_event.cpp + game_sv_capture_the_artefact.cpp + game_sv_capture_the_artefact.h + game_sv_capture_the_artefact_myteam_impl.cpp + game_sv_capture_the_artefact_process_event.cpp + game_sv_deathmatch.cpp + game_sv_deathmatch.h + game_sv_deathmatch_process_event.cpp + game_sv_deathmatch_script.cpp + game_sv_event_queue.cpp + game_sv_event_queue.h + game_sv_item_respawner.cpp + game_sv_item_respawner.h + game_sv_mp.cpp + game_sv_mp.h + game_sv_mp_script.cpp + game_sv_mp_script.h + game_sv_mp_team.h + game_sv_mp_vote_flags.h + game_sv_single.cpp + game_sv_single.h + game_sv_teamdeathmatch.cpp + game_sv_teamdeathmatch.h + game_sv_teamdeathmatch_process_event.cpp + GameTask.cpp + GameTaskDefs.h + GameTask.h + GametaskManager.cpp + GametaskManager.h + GameTask_script.cpp + game_type.cpp + game_type.h + GlobalFeelTouch.cpp + GlobalFeelTouch.hpp + GraviArtifact.cpp + GraviArtifact.h + GraviZone.cpp + GraviZone.h + Grenade.cpp + Grenade.h + GrenadeLauncher.cpp + GrenadeLauncher.h + group_hierarchy_holder.cpp + group_hierarchy_holder.h + group_hierarchy_holder_inline.h + gsc_dsigned_ltx.cpp + gsc_dsigned_ltx.h + HairsZone.cpp + HairsZone.h + HairsZone_script.cpp + HangingLamp.cpp + HangingLamp.h + harvest_time.cpp + harvest_time.h + Helicopter2.cpp + Helicopter.cpp + helicopter.h + HelicopterMovementManager.cpp + helicopter_script.cpp + HelicopterWeapon.cpp + Hit.cpp + Hit.h + hit_immunity.cpp + hit_immunity.h + hit_immunity_space.h + HitMarker.cpp + HitMarker.h + hit_memory_manager.cpp + hit_memory_manager.h + hit_memory_manager_inline.h + hits_store.cpp + hits_store.h + hits_store_inline.h + holder_custom.cpp + holder_custom.h + holder_custom_script.cpp + HUDCrosshair.cpp + HUDCrosshair.h + HudItem.cpp + HudItem.h + hud_item_object.cpp + hud_item_object.h + HUDManager.cpp + HUDManager.h + HudSound.cpp + HudSound.h + HUDTarget.cpp + HUDTarget.h + id_generator.h + ik_anim_state.cpp + ik_anim_state.h + ik_calculate_data.cpp + ik_calculate_data.h + ik_calculate_state.h + ik_collide_data.h + ik_dbg_matrix.cpp + ik_dbg_matrix.h + ik_foot_collider.cpp + ik_foot_collider.h + IKFoot.cpp + IKFoot.h + IKFoot_inl.h + IKLimbsController.cpp + IKLimbsController.h + ik_limb_state.cpp + ik_limb_state.h + ik_limb_state_predict.h + ik_object_shift.cpp + ik_object_shift.h + imotion_position.cpp + imotion_position.h + imotion_velocity.cpp + imotion_velocity.h + InfoDocument.cpp + InfoDocument.h + InfoPortion.cpp + InfoPortion.h + ini_id_loader.h + ini_table_loader.h + interactive_animation.cpp + interactive_animation.h + interactive_motion.cpp + interactive_motion.h + InventoryBox.cpp + InventoryBox.h + Inventory.cpp + Inventory.h + inventory_item.cpp + inventory_item.h + inventory_item_impl.h + inventory_item_inline.h + inventory_item_object.cpp + inventory_item_object.h + inventory_item_object_inline.h + inventory_item_upgrade.cpp + InventoryOwner.cpp + InventoryOwner.h + inventory_owner_info.cpp + inventory_owner_inline.h + inventory_quickswitch.cpp + inventory_upgrade_base.cpp + inventory_upgrade_base.h + inventory_upgrade_base_inline.h + inventory_upgrade.cpp + inventory_upgrade_group.cpp + inventory_upgrade_group.h + inventory_upgrade_group_inline.h + inventory_upgrade.h + inventory_upgrade_inline.h + inventory_upgrade_manager.cpp + inventory_upgrade_manager.h + inventory_upgrade_manager_inline.h + inventory_upgrade_property.cpp + inventory_upgrade_property.h + inventory_upgrade_property_inline.h + inventory_upgrade_root.cpp + inventory_upgrade_root.h + inventory_upgrade_root_inline.h + invincible_fury.cpp + invincible_fury.h + item_manager.cpp + item_manager.h + item_manager_inline.h + killer_victim_velocity_angle.cpp + killer_victim_velocity_angle.h + kills_store.cpp + kills_store.h + kills_store_inline.h + Level_Bullet_Manager.cpp + Level_bullet_manager_firetrace.cpp + Level_Bullet_Manager.h + level_changer.cpp + level_changer.h + Level.cpp + level_debug.cpp + level_debug.h + #LevelFogOfWar.cpp + #LevelFogOfWar.h + Level_GameSpy_Funcs.cpp + LevelGraphDebugRender.cpp + LevelGraphDebugRender.hpp + Level.h + Level_input.cpp + Level_load.cpp + level_location_selector.h + level_location_selector_inline.h + level_map_locations.cpp + Level_network_compressed_updates.cpp + Level_network.cpp + Level_network_Demo.cpp + Level_network_Demo.h + Level_network_digest_computer.cpp + Level_network_map_sync.cpp + Level_network_map_sync.h + Level_network_messages.cpp + Level_network_spawn.cpp + Level_network_start_client.cpp + level_path_builder.h + level_path_manager.h + level_path_manager_inline.h + level_script.cpp + Level_secure_messaging.cpp + Level_SLS_Default.cpp + Level_SLS_Load.cpp + Level_SLS_Save.cpp + level_sounds.cpp + level_sounds.h + Level_start.cpp + location_manager.cpp + location_manager.h + location_manager_inline.h + login_manager.cpp + login_manager.h + login_manager_script.cpp + magic_box3.cpp + magic_box3.h + magic_box3_inline.h + magic_minimize_1d.cpp + magic_minimize_1d.h + magic_minimize_1d_inline.h + magic_minimize_nd.h + magic_minimize_nd_inline.h + MainMenu.cpp + MainMenu.h + map_location.cpp + map_location_defs.h + map_location.h + map_manager.cpp + map_manager.h + map_script.cpp + map_spot.cpp + map_spot.h + material_manager.cpp + material_manager.h + material_manager_inline.h + #MathUtils.cpp + #MathUtils.h + matrix_utils.h + medkit.cpp + medkit.h + member_corpse.h + member_corpse_inline.h + member_enemy.h + member_enemy_inline.h + member_order.h + member_order_inline.h + memory_manager.cpp + memory_manager.h + memory_manager_inline.h + memory_space.h + memory_space_impl.h + memory_space_script.cpp + MercuryBall.cpp + MercuryBall.h + Message_Filter.cpp + Message_Filter.h + MilitaryOutfit.cpp + MilitaryOutfit.h + Mincer.cpp + Mincer.h + mincer_script.cpp + min_obb.cpp + Missile.cpp + Missile.h + mixed_delegate.h + mixed_delegate_unique_tags.h + monster_community.cpp + monster_community.h + MosquitoBald.cpp + MosquitoBald.h + MosquitoBald_script.cpp + movement_manager.cpp + movement_manager_game.cpp + movement_manager.h + movement_manager_impl.h + movement_manager_inline.h + movement_manager_level.cpp + movement_manager_patrol.cpp + movement_manager_physic.cpp + movement_manager_space.h + moving_bones_snd_player.cpp + moving_bones_snd_player.h + moving_object.cpp + moving_object.h + moving_object_inline.h + moving_objects.cpp + moving_objects_dynamic_collision.cpp + moving_objects_dynamic.cpp + moving_objects.h + moving_objects_impl.h + moving_objects_inline.h + moving_objects_static.cpp + mpactor_dump_impl.cpp + mp_config_sections.cpp + mp_config_sections.h + MPPlayersBag.cpp + MPPlayersBag.h + mt_config.h + Needles.cpp + Needles.h + NET_Queue.h + NoGravityZone.cpp + NoGravityZone.h + object_actions.cpp + object_actions.h + object_actions_inline.h + #ObjectDump.cpp + #ObjectDump.h + object_handler.cpp + object_handler.h + object_handler_inline.h + object_handler_planner.cpp + object_handler_planner.h + object_handler_planner_impl.h + object_handler_planner_inline.h + object_handler_planner_missile.cpp + object_handler_planner_weapon.cpp + object_handler_space.h + object_manager.h + object_manager_inline.h + object_property_evaluators.cpp + object_property_evaluators.h + object_property_evaluators_inline.h + obsolete_queue.h + obsolete_queue_inline.h + obstacles_query.cpp + obstacles_query.h + obstacles_query_inline.h + particle_params.h + particle_params_script.cpp + ParticlesObject.cpp + ParticlesObject.h + ParticlesPlayer.cpp + ParticlesPlayer.h + patrol_path_manager.cpp + patrol_path_manager.h + patrol_path_manager_inline.h + PDA.cpp + PDA.h + PdaMsg.h + pda_space.h + PHCollisionDamageReceiver.cpp + PHCollisionDamageReceiver.h + PHCommander.cpp + PHCommander.h + PHDebug.cpp + PHDebug.h + PHDestroyable.cpp + PHDestroyable.h + PHDestroyableNotificate.cpp + PHDestroyableNotificate.h + PHMovementControl.cpp + PHMovementControl.h + PHMovementDynamicActivate.cpp + Phrase.cpp + PhraseDialog.cpp + PhraseDialogDefs.h + PhraseDialog.h + PhraseDialogManager.cpp + PhraseDialogManager.h + PhraseDialog_script.cpp + Phrase.h + PhraseScript.cpp + PhraseScript.h + PHReqComparer.h + PHScriptCall.cpp + PHScriptCall.h + PHShellCreator.cpp + PHShellCreator.h + ph_shell_interface.h + PHSimpleCalls.cpp + PHSimpleCalls.h + PHSimpleCallsScript.cpp + PHSkeleton.cpp + PHSkeleton.h + PHSoundPlayer.cpp + PHSoundPlayer.h + physic_item.cpp + physic_item.h + physic_item_inline.h + PhysicObject.cpp + PhysicObject.h + PhysicObject_script.cpp + physics_element_scripted.cpp + physics_element_scripted.h + physics_game.cpp + physics_game.h + PhysicsGamePars.cpp + PhysicsGamePars.h + physics_joint_scripted.cpp + physics_joint_scripted.h + physics_shell_animated.cpp + physics_shell_animated.h + PhysicsShellHolder.cpp + PhysicsShellHolder.h + #PhysicsShellScript.cpp + physics_shell_scripted.cpp + physics_shell_scripted.h + PhysicsSkeletonObject.cpp + PhysicsSkeletonObject.h + physics_world_scripted.cpp + physics_world_scripted.h + player_account.cpp + player_account.h + player_hud.cpp + player_hud.h + player_hud_tune.cpp + player_name_modifyer.cpp + player_name_modifyer.h + player_spot_params.cpp + player_spot_params.h + player_state_achilles_heel.cpp + player_state_achilles_heel.h + player_state_ambassador.cpp + player_state_ambassador.h + player_state_ammo_elapsed.cpp + player_state_ammo_elapsed.h + player_state_avenger.cpp + player_state_avenger.h + player_state_blitzkrieg.cpp + player_state_blitzkrieg.h + player_state_cherub.cpp + player_state_cherub.h + player_state_climber.cpp + player_state_climber.h + player_state_mad.cpp + player_state_mad.h + player_state_marksman.cpp + player_state_marksman.h + player_state_multichampion.cpp + player_state_multichampion.h + player_state_opener.cpp + player_state_opener.h + player_state_param.h + player_state_params.cpp + player_state_params.h + player_state_remembrance.cpp + player_state_remembrance.h + player_state_skewer.cpp + player_state_skewer.h + player_state_toughy.cpp + player_state_toughy.h + player_team_win_score.cpp + player_team_win_score.h + pose_extrapolation.cpp + pose_extrapolation.h + poses_blending.cpp + poses_blending.h + PostprocessAnimator.cpp + PostprocessAnimator.h + pp_effector_custom.cpp + pp_effector_custom.h + pp_effector_distance.cpp + pp_effector_distance.h + profile_data_types.cpp + profile_data_types.h + profile_data_types_script.cpp + profile_data_types_script.h + profile_store.cpp + profile_store.h + profile_store_script.cpp + property_evaluator_const.h + property_evaluator.h + property_evaluator_inline.h + property_evaluator_member.h + property_evaluator_member_inline.h + property_evaluator_script.cpp + property_storage.h + property_storage_inline.h + property_storage_script.cpp + purchase_list.cpp + purchase_list.h + purchase_list_inline.h + quadtree.h + quadtree_inline.h + queued_async_method.h + RadioactiveZone.cpp + RadioactiveZone.h + Random.cpp + Random.hpp + rat_state_base.cpp + rat_state_base.h + rat_state_base_inline.h + rat_state_manager.cpp + rat_state_manager.h + rat_state_manager_inline.h + rat_states.cpp + rat_states.h + raypick.cpp + raypick.h + refreshable_obstacles_query.h + refreshable_obstacles_query_inline.h + RegistryFuncs.cpp + RegistryFuncs.h + relation_registry_actions.cpp + relation_registry.cpp + relation_registry_defs.h + relation_registry_fights.cpp + relation_registry.h + relation_registry_inline.h + restricted_object.cpp + restricted_object.h + restricted_object_inline.h + restricted_object_obstacle.cpp + restricted_object_obstacle.h + reward_event_generator.cpp + reward_event_generator.h + reward_event_handler.h + rewarding_events_handlers.cpp + rewarding_events_handlers.h + rewarding_state_events.cpp + rewarding_state_events.h + reward_manager.cpp + reward_manager.h + reward_snd_messages.h + RGD5.h + RocketLauncher.cpp + RocketLauncher.h + RustyHairArtifact.cpp + RustyHairArtifact.h + safe_map_iterator.h + safe_map_iterator_inline.h + saved_game_wrapper.cpp + saved_game_wrapper.h + saved_game_wrapper_inline.h + saved_game_wrapper_script.cpp + ScientificOutfit.cpp + ScientificOutfit.h + Scope.cpp + Scope.h + screenshot_manager.cpp + screenshot_manager.h + screenshots_common.cpp + screenshots_common.h + screenshot_server.cpp + screenshot_server.h + screenshots_writer.cpp + screenshots_writer.h + script_abstract_action.h + script_action_condition.h + script_action_condition_inline.h + script_action_condition_script.cpp + script_action_planner_action_wrapper.cpp + script_action_planner_action_wrapper.h + script_action_planner_action_wrapper_inline.h + script_action_planner_wrapper.cpp + script_action_planner_wrapper.h + script_action_planner_wrapper_inline.h + script_action_wrapper.cpp + script_action_wrapper.h + script_action_wrapper_inline.h + script_animation_action.h + script_animation_action_inline.h + script_animation_action_script.cpp + script_binder.cpp + script_binder.h + script_binder_inline.h + script_binder_object.cpp + script_binder_object.h + script_binder_object_script.cpp + script_binder_object_wrapper.cpp + script_binder_object_wrapper.h + script_bind_macroses.h + script_effector.cpp + script_effector.h + script_effector_inline.h + script_effector_script.cpp + script_effector_wrapper.cpp + script_effector_wrapper.h + script_effector_wrapper_inline.h + script_entity_action.cpp + script_entity_action.h + script_entity_action_inline.h + script_entity_action_script.cpp + script_entity.cpp + script_entity.h + script_entity_inline.h + script_entity_space.h + script_game_object2.cpp + script_game_object3.cpp + script_game_object4.cpp + script_game_object.cpp + script_game_object.h + script_game_object_impl.h + script_game_object_inventory_owner.cpp + script_game_object_script2.cpp + script_game_object_script3.cpp + script_game_object_script.cpp + script_game_object_script_trader.cpp + script_game_object_smart_covers.cpp + script_game_object_trader.cpp + script_game_object_use2.cpp + script_game_object_use.cpp + script_hit.cpp + script_hit.h + script_hit_inline.h + script_hit_script.cpp + script_lanim.cpp + script_monster_action.cpp + script_monster_action.h + script_monster_action_inline.h + script_monster_action_script.cpp + script_monster_hit_info.h + script_monster_hit_info_script.cpp + script_movement_action.cpp + script_movement_action.h + script_movement_action_inline.h + script_movement_action_script.cpp + script_object_action.cpp + script_object_action.h + script_object_action_inline.h + script_object_action_script.cpp + script_object.cpp + script_object.h + script_particle_action.cpp + script_particle_action.h + script_particle_action_inline.h + script_particle_action_script.cpp + script_particles.cpp + script_particles.h + script_particles_inline.h + script_particles_script.cpp + script_property_evaluator_wrapper.cpp + script_property_evaluator_wrapper.h + script_property_evaluator_wrapper_inline.h + script_render_device_script.cpp + script_sound_action.cpp + script_sound_action.h + script_sound_action_inline.h + script_sound_action_script.cpp + script_sound.cpp + script_sound.h + script_sound_info.h + script_sound_info_script.cpp + script_sound_inline.h + script_sound_script.cpp + script_watch_action.cpp + script_watch_action.h + script_watch_action_inline.h + script_watch_action_script.cpp + ScriptXMLInit.cpp + ScriptXMLInit.h + script_zone.cpp + script_zone.h + script_zone_script.cpp + searchlight.cpp + searchlight.h + secure_messaging.cpp + secure_messaging.h + seniority_hierarchy_holder.cpp + seniority_hierarchy_holder.h + seniority_hierarchy_holder_inline.h + seniority_hierarchy_space.h + server_entity_wrapper.cpp + server_entity_wrapper.h + server_entity_wrapper_inline.h + setup_manager.h + setup_manager_inline.h + ShootingObject.cpp + shootingObject_dump_impl.cpp + ShootingObject.h + sight_action.cpp + sight_action.h + sight_action_inline.h + sight_control_action.h + sight_control_action_inline.h + sight_manager.cpp + sight_manager.h + sight_manager_inline.h + sight_manager_space.h + sight_manager_target.cpp + Silencer.cpp + Silencer.h + silent_shots.cpp + silent_shots.h + SimpleDetector.cpp + SimpleDetector.h + SleepEffector.cpp + SleepEffector.h + smart_cover_action.cpp + smart_cover_action.h + smart_cover_action_inline.h + smart_cover_animation_planner.cpp + smart_cover_animation_planner.h + smart_cover_animation_planner_inline.h + smart_cover_animation_selector.cpp + smart_cover_animation_selector.h + smart_cover_animation_selector_inline.h + smart_cover.cpp + smart_cover_default_behaviour_planner.cpp + smart_cover_default_behaviour_planner.hpp + smart_cover_default_behaviour_planner_inline.hpp + smart_cover_description.cpp + smart_cover_description.h + smart_cover_description_inline.h + smart_cover_detail.cpp + smart_cover_detail.h + smart_cover_evaluators.cpp + smart_cover_evaluators.h + smart_cover.h + smart_cover_inline.h + smart_cover_loophole.cpp + smart_cover_loophole.h + smart_cover_loophole_inline.h + smart_cover_loophole_planner_actions.cpp + smart_cover_loophole_planner_actions.h + smart_cover_loophole_planner_actions_inline.h + smart_cover_object.cpp + smart_cover_object.h + smart_cover_object_inline.h + smart_cover_object_script.cpp + smart_cover_planner_actions.cpp + smart_cover_planner_actions.h + smart_cover_planner_actions_inline.h + smart_cover_planner_target_provider.cpp + smart_cover_planner_target_provider.h + smart_cover_planner_target_selector.cpp + smart_cover_planner_target_selector.h + smart_cover_planner_target_selector_inline.h + smart_cover_storage.cpp + smart_cover_storage.h + smart_cover_transition_animation.cpp + smart_cover_transition_animation.hpp + smart_cover_transition_animation_inline.hpp + smart_cover_transition.cpp + smart_cover_transition.hpp + smart_zone.h + sound_collection_storage.cpp + sound_collection_storage.h + sound_collection_storage_inline.h + sound_memory_manager.cpp + sound_memory_manager.h + sound_memory_manager_inline.h + sound_player.cpp + sound_player.h + sound_player_inline.h + sound_user_data_visitor.h + space_restriction_abstract.h + space_restriction_abstract_inline.h + space_restriction_base.cpp + space_restriction_base.h + space_restriction_base_inline.h + space_restriction_bridge.cpp + space_restriction_bridge.h + space_restriction_bridge_inline.h + space_restriction_composition.cpp + space_restriction_composition.h + space_restriction_composition_inline.h + space_restriction.cpp + space_restriction.h + space_restriction_holder.cpp + space_restriction_holder.h + space_restriction_holder_inline.h + space_restriction_inline.h + space_restriction_manager.cpp + space_restriction_manager.h + space_restriction_manager_inline.h + space_restriction_shape.cpp + space_restriction_shape.h + space_restriction_shape_inline.h + space_restrictor.cpp + space_restrictor.h + space_restrictor_inline.h + space_restrictor_script.cpp + SpaceUtils.h + spectator_camera_first_eye.cpp + spectator_camera_first_eye.h + Spectator.cpp + Spectator.h + sprinter_stopper.cpp + sprinter_stopper.h + squad_hierarchy_holder.cpp + squad_hierarchy_holder.h + squad_hierarchy_holder_inline.h + stalker_alife_actions.cpp + stalker_alife_actions.h + stalker_alife_planner.cpp + stalker_alife_planner.h + stalker_alife_task_actions.cpp + stalker_alife_task_actions.h + stalker_animation_callbacks.cpp + stalker_animation_data.cpp + stalker_animation_data.h + stalker_animation_data_storage.cpp + stalker_animation_data_storage.h + stalker_animation_data_storage_inline.h + stalker_animation_global.cpp + stalker_animation_head.cpp + stalker_animation_legs.cpp + stalker_animation_manager.cpp + stalker_animation_manager_debug.cpp + stalker_animation_manager.h + stalker_animation_manager_impl.h + stalker_animation_manager_inline.h + stalker_animation_manager_update.cpp + stalker_animation_names.cpp + stalker_animation_names.h + #stalker_animation_offsets.cpp + #stalker_animation_offsets.hpp + stalker_animation_pair.cpp + stalker_animation_pair.h + stalker_animation_pair_inline.h + stalker_animation_script.cpp + stalker_animation_script.h + stalker_animation_script_inline.h + stalker_animation_state.cpp + stalker_animation_state.h + stalker_animation_state_inline.h + stalker_animation_torso.cpp + stalker_anomaly_actions.cpp + stalker_anomaly_actions.h + stalker_anomaly_planner.cpp + stalker_anomaly_planner.h + stalker_base_action.cpp + stalker_base_action.h + stalker_combat_action_base.cpp + stalker_combat_action_base.h + stalker_combat_actions.cpp + stalker_combat_actions.h + stalker_combat_actions_inline.h + stalker_combat_planner.cpp + stalker_combat_planner.h + stalker_danger_by_sound_actions.cpp + stalker_danger_by_sound_actions.h + stalker_danger_by_sound_planner.cpp + stalker_danger_by_sound_planner.h + stalker_danger_grenade_actions.cpp + stalker_danger_grenade_actions.h + stalker_danger_grenade_planner.cpp + stalker_danger_grenade_planner.h + stalker_danger_in_direction_actions.cpp + stalker_danger_in_direction_actions.h + stalker_danger_in_direction_planner.cpp + stalker_danger_in_direction_planner.h + stalker_danger_planner.cpp + stalker_danger_planner.h + stalker_danger_planner_inline.h + stalker_danger_property_evaluators.cpp + stalker_danger_property_evaluators.h + stalker_danger_unknown_actions.cpp + stalker_danger_unknown_actions.h + stalker_danger_unknown_planner.cpp + stalker_danger_unknown_planner.h + stalker_death_actions.cpp + stalker_death_actions.h + stalker_death_planner.cpp + stalker_death_planner.h + stalker_decision_space.h + stalker_flair.cpp + stalker_flair.h + stalker_get_distance_actions.cpp + stalker_get_distance_actions.h + stalker_get_distance_planner.cpp + stalker_get_distance_planner.h + stalker_kill_wounded_actions.cpp + stalker_kill_wounded_actions.h + stalker_kill_wounded_planner.cpp + stalker_kill_wounded_planner.h + stalker_low_cover_actions.cpp + stalker_low_cover_actions.h + stalker_low_cover_planner.cpp + stalker_low_cover_planner.h + stalker_movement_manager_base.cpp + stalker_movement_manager_base.h + stalker_movement_manager_base_inline.h + stalker_movement_manager_obstacles.cpp + stalker_movement_manager_obstacles.h + stalker_movement_manager_obstacles_inline.h + stalker_movement_manager_obstacles_path.cpp + stalker_movement_manager_smart_cover.cpp + stalker_movement_manager_smart_cover_fov_range.cpp + stalker_movement_manager_smart_cover.h + stalker_movement_manager_smart_cover_inline.h + stalker_movement_manager_smart_cover_loopholes.cpp + stalker_movement_manager_space.h + stalker_movement_params.cpp + stalker_movement_params.h + stalker_movement_params_inline.h + stalker_movement_restriction.h + stalker_movement_restriction_inline.h + StalkerOutfit.cpp + StalkerOutfit.h + stalker_planner.cpp + stalker_planner.h + stalker_planner_inline.h + stalker_property_evaluators.cpp + stalker_property_evaluators.h + stalker_property_evaluators_inline.h + stalker_search_actions.cpp + stalker_search_actions.h + stalker_search_planner.cpp + stalker_search_planner.h + stalker_sound_data.cpp + stalker_sound_data.h + stalker_sound_data_inline.h + stalker_sound_data_visitor.cpp + stalker_sound_data_visitor.h + stalker_sound_data_visitor_inline.h + stalker_velocity_collection.cpp + stalker_velocity_collection.h + stalker_velocity_collection_inline.h + stalker_velocity_holder.cpp + stalker_velocity_holder.h + stalker_velocity_holder_inline.h + state_arguments_functions.cpp + state_arguments_functions.h + static_cast_checked.hpp + #static_cast_checked_test.cpp + static_obstacles_avoider.cpp + static_obstacles_avoider.h + static_obstacles_avoider_inline.h + #stats_submitter.cpp + stats_submitter_dsa_params.cpp + stats_submitter.h + StdAfx.cpp + StdAfx.h + steering_behaviour_alignment.h + steering_behaviour_base.h + steering_behaviour_base_inline.h + steering_behaviour_cohesion.h + steering_behaviour.cpp + steering_behaviour.h + steering_behaviour_separation.h + step_manager.cpp + step_manager_defs.h + step_manager.h + team_base_zone.cpp + team_base_zone.h + team_hierarchy_holder.cpp + team_hierarchy_holder.h + team_hierarchy_holder_inline.h + TeleWhirlwind.cpp + TeleWhirlwind.h + ThornArtifact.cpp + ThornArtifact.h + Torch.cpp + Torch.h + torch_script.cpp + TorridZone.cpp + TorridZone.h + Tracer.cpp + Tracer.h + trade2.cpp + trade_action_parameters.h + trade_action_parameters_inline.h + trade_bool_parameters.h + trade_bool_parameters_inline.h + trade.cpp + trade_factor_parameters.h + trade_factor_parameters_inline.h + trade_factors.h + trade_factors_inline.h + trade.h + trade_parameters.cpp + trade_parameters.h + trade_parameters_inline.h + traffic_optimization.cpp + traffic_optimization.h + trajectories.cpp + trajectories.h + UIAchivementsIndicator.cpp + UIAchivementsIndicator.h + UIDialogHolder.cpp + UIDialogHolder.h + ui_export_script.cpp + #UIFrameRect.cpp + #UIFrameRect.h + UIGameAHunt.cpp + UIGameAHunt.h + UIGameCTA.cpp + UIGameCTA.h + UIGameCustom.cpp + UIGameCustom.h + #UIGame_custom_script.cpp + #UIGame_custom_script.h + UIGameCustom_script.cpp + UIGameDM.cpp + UIGameDM.h + UIGameMP.cpp + UIGameMP.h + UIGameSP.cpp + UIGameSP.h + UIGameTDM.cpp + UIGameTDM.h + UIPanelsClassFactory.cpp + UIPanelsClassFactory.h + UIPlayerItem.cpp + UIPlayerItem.h + UITeamHeader.cpp + UITeamHeader.h + UITeamPanels.cpp + UITeamPanels.h + UITeamState.cpp + UITeamState.h + UITimeDilator.cpp + UITimeDilator.h + UIZoneMap.cpp + UIZoneMap.h + VersionSwitcher.cpp + VersionSwitcher.h + vision_client.cpp + vision_client.h + vision_client_inline.h + visual_memory_manager.cpp + visual_memory_manager.h + visual_memory_manager_inline.h + visual_memory_params.cpp + visual_memory_params.h + wallmark_manager.cpp + wallmark_manager.h + WeaponAK74.cpp + WeaponAK74.h + WeaponAmmo.cpp + weapon_ammo_dump_impl.cpp + WeaponAmmo.h + WeaponAutomaticShotgun.cpp + WeaponAutomaticShotgun.h + WeaponBinoculars.cpp + WeaponBinoculars.h + WeaponBinocularsVision.cpp + WeaponBinocularsVision.h + weaponBM16.cpp + weaponBM16.h + Weapon.cpp + WeaponCustomPistolAuto.cpp + WeaponCustomPistolAuto.h + WeaponCustomPistol.cpp + WeaponCustomPistol.h + WeaponDispersion.cpp + weapon_dump_impl.cpp + WeaponFire.cpp + WeaponFN2000.cpp + WeaponFN2000.h + WeaponFORT.h + WeaponGroza.cpp + WeaponGroza.h + Weapon.h + WeaponHPSA.cpp + WeaponHPSA.h + WeaponHUD.h + WeaponKnife.cpp + WeaponKnife.h + WeaponLR300.cpp + WeaponLR300.h + WeaponMagazined.cpp + WeaponMagazined.h + WeaponMagazinedWGrenade.cpp + WeaponMagazinedWGrenade.h + WeaponPistol.cpp + WeaponPistol.h + WeaponPM.cpp + WeaponPM.h + WeaponRevolver.cpp + WeaponRevolver.h + WeaponRG6.cpp + WeaponRG6.h + WeaponRPG7.cpp + WeaponRPG7.h + WeaponScript.cpp + WeaponShotgun.cpp + WeaponShotgun.h + WeaponStatMgun.cpp + WeaponStatMgunFire.cpp + WeaponStatMgun.h + WeaponStatMgunIR.cpp + WeaponSVD.cpp + WeaponSVD.h + WeaponSVU.h + WeaponUpgrade.cpp + WeaponUSP45.h + WeaponVal.cpp + WeaponVal.h + WeaponVintorez.cpp + WeaponVintorez.h + WeaponWalther.h + Wound.cpp + Wound.h + wrapper_abstract.h + wrapper_abstract_inline.h + #xr_Client_BattlEye.cpp + #xr_Client_BattlEye.h + xrClientsPool.cpp + xrClientsPool.h + xrGame.cpp + xrgame_dll_detach.cpp + xrGameSpy_GameSpyFuncs.cpp + xrGameSpyServer_callbacks.cpp + xrGameSpyServer_callbacks.h + xrGameSpyServer.cpp + xrGameSpyServer.h + xrServer_balance.cpp + #xr_Server_BattlEye.cpp + #xr_Server_BattlEye.h + xrServer_CL_connect.cpp + xrServer_CL_disconnect.cpp + xrServer_Connect.cpp + xrServer.cpp + xrServer_Disconnect.cpp + xrServer.h + xrServer_info.cpp + xrServer_info.h + xrServerMapSync.cpp + xrServerMapSync.h + xrServer_perform_GameExport.cpp + xrServer_perform_migration.cpp + xrServer_perform_RPgen.cpp + xrServer_perform_sls_default.cpp + xrServer_perform_sls_load.cpp + xrServer_perform_sls_save.cpp + xrServer_perform_transfer.cpp + xrServer_process_event_activate.cpp + xrServer_process_event.cpp + xrServer_process_event_destroy.cpp + xrServer_process_event_ownership.cpp + xrServer_process_event_reject.cpp + xrServer_process_spawn.cpp + xrServer_process_update.cpp + xrServer_secure_messaging.cpp + xrServer_sls_clear.cpp + xrServer_svclient_validation.cpp + xrServer_svclient_validation.h + xrServer_updates_compressor.cpp + xrServer_updates_compressor.h + xr_time.cpp + xr_time.h + ZoneCampfire.cpp + ZoneCampfire.h + zone_effector.cpp + zone_effector.h + ZoneVisual.cpp + ZoneVisual.h + ZudaArtifact.cpp + ZudaArtifact.h + ai/ai_monsters_anims.h + ai/ai_monsters_misc.cpp + ai/ai_monsters_misc.h + ai/position_prediction.h + ai/weighted_random.cpp + ai/weighted_random.h + ai/crow/ai_crow.cpp + ai/crow/ai_crow.h + ai/monsters/ai_monster_bones.cpp + ai/monsters/ai_monster_bones.h + ai/monsters/ai_monster_defs.h + ai/monsters/ai_monster_effector.cpp + ai/monsters/ai_monster_effector.h + ai/monsters/ai_monster_motion_stats.cpp + ai/monsters/ai_monster_motion_stats.h + ai/monsters/ai_monster_shared_data.h + ai/monsters/ai_monster_squad_attack.cpp + ai/monsters/ai_monster_squad.cpp + ai/monsters/ai_monster_squad.h + ai/monsters/ai_monster_squad_manager.cpp + ai/monsters/ai_monster_squad_manager.h + ai/monsters/ai_monster_squad_manager_inline.h + ai/monsters/ai_monster_squad_rest.cpp + ai/monsters/ai_monster_utils.cpp + ai/monsters/ai_monster_utils.h + ai/monsters/anim_triple.cpp + ai/monsters/anim_triple.h + ai/monsters/anomaly_detector.cpp + ai/monsters/anomaly_detector.h + ai/monsters/anti_aim_ability.cpp + ai/monsters/anti_aim_ability.h + ai/monsters/control_animation_base_accel.cpp + ai/monsters/control_animation_base.cpp + ai/monsters/control_animation_base.h + ai/monsters/control_animation_base_load.cpp + ai/monsters/control_animation_base_update.cpp + ai/monsters/control_animation.cpp + ai/monsters/control_animation.h + ai/monsters/control_combase.h + ai/monsters/control_com_defs.h + ai/monsters/control_critical_wound.cpp + ai/monsters/control_critical_wound.h + ai/monsters/control_direction_base.cpp + ai/monsters/control_direction_base.h + ai/monsters/control_direction.cpp + ai/monsters/control_direction.h + ai/monsters/control_jump.cpp + ai/monsters/control_jump.h + ai/monsters/controlled_actor.cpp + ai/monsters/controlled_actor.h + ai/monsters/controlled_entity.h + ai/monsters/controlled_entity_inline.h + ai/monsters/control_manager.cpp + ai/monsters/control_manager_custom.cpp + ai/monsters/control_manager_custom.h + ai/monsters/control_manager.h + ai/monsters/control_melee_jump.cpp + ai/monsters/control_melee_jump.h + ai/monsters/control_movement_base.cpp + ai/monsters/control_movement_base.h + ai/monsters/control_movement.cpp + ai/monsters/control_movement.h + ai/monsters/control_path_builder_base.cpp + ai/monsters/control_path_builder_base.h + ai/monsters/control_path_builder_base_inline.h + ai/monsters/control_path_builder_base_path.cpp + ai/monsters/control_path_builder_base_set.cpp + ai/monsters/control_path_builder_base_update.cpp + ai/monsters/control_path_builder.cpp + ai/monsters/control_path_builder.h + ai/monsters/control_rotation_jump.cpp + ai/monsters/control_rotation_jump.h + ai/monsters/control_run_attack.cpp + ai/monsters/control_run_attack.h + ai/monsters/control_sequencer.cpp + ai/monsters/control_sequencer.h + ai/monsters/control_threaten.cpp + ai/monsters/control_threaten.h + ai/monsters/corpse_cover.cpp + ai/monsters/corpse_cover.h + ai/monsters/custom_events.h + ai/monsters/energy_holder.cpp + ai/monsters/energy_holder.h + ai/monsters/invisibility.cpp + ai/monsters/invisibility.h + ai/monsters/melee_checker.cpp + ai/monsters/melee_checker.h + ai/monsters/melee_checker_inline.h + ai/monsters/monster_aura.cpp + ai/monsters/monster_aura.h + ai/monsters/monster_corpse_manager.cpp + ai/monsters/monster_corpse_manager.h + ai/monsters/monster_corpse_memory.cpp + ai/monsters/monster_corpse_memory.h + ai/monsters/monster_cover_manager.cpp + ai/monsters/monster_cover_manager.h + ai/monsters/monster_enemy_manager.cpp + ai/monsters/monster_enemy_manager.h + ai/monsters/monster_enemy_memory.cpp + ai/monsters/monster_enemy_memory.h + ai/monsters/monster_event_manager.cpp + ai/monsters/monster_event_manager_defs.h + ai/monsters/monster_event_manager.h + ai/monsters/monster_hit_memory.cpp + ai/monsters/monster_hit_memory.h + ai/monsters/monster_home.cpp + ai/monsters/monster_home.h + ai/monsters/monster_morale.cpp + ai/monsters/monster_morale.h + ai/monsters/monster_morale_inline.h + ai/monsters/monster_sound_defs.h + ai/monsters/monster_sound_memory.cpp + ai/monsters/monster_sound_memory.h + ai/monsters/monster_state_manager.h + ai/monsters/monster_state_manager_inline.h + ai/monsters/monster_velocity_space.h + ai/monsters/psy_aura.cpp + ai/monsters/psy_aura.h + ai/monsters/scanning_ability.h + ai/monsters/scanning_ability_inline.h + ai/monsters/state.cpp + ai/monsters/state_defs.h + ai/monsters/state.h + ai/monsters/state_inline.h + ai/monsters/state_manager.h + ai/monsters/telekinesis.cpp + ai/monsters/telekinesis.h + ai/monsters/telekinesis_inline.h + ai/monsters/telekinetic_object.cpp + ai/monsters/telekinetic_object.h + ai/monsters/basemonster/base_monster_anim.cpp + ai/monsters/basemonster/base_monster.cpp + ai/monsters/basemonster/base_monster_debug.cpp + ai/monsters/basemonster/base_monster_feel.cpp + ai/monsters/basemonster/base_monster.h + ai/monsters/basemonster/base_monster_inline.h + ai/monsters/basemonster/base_monster_misc.cpp + ai/monsters/basemonster/base_monster_net.cpp + ai/monsters/basemonster/base_monster_path.cpp + ai/monsters/basemonster/base_monster_script.cpp + ai/monsters/basemonster/base_monster_startup.cpp + ai/monsters/basemonster/base_monster_think.cpp + ai/monsters/bloodsucker/bloodsucker_alien.cpp + ai/monsters/bloodsucker/bloodsucker_alien.h + ai/monsters/bloodsucker/bloodsucker_attack_state.h + ai/monsters/bloodsucker/bloodsucker_attack_state_hide.h + ai/monsters/bloodsucker/bloodsucker_attack_state_hide_inline.h + ai/monsters/bloodsucker/bloodsucker_attack_state_inline.h + ai/monsters/bloodsucker/bloodsucker.cpp + ai/monsters/bloodsucker/bloodsucker.h + ai/monsters/bloodsucker/bloodsucker_predator.h + ai/monsters/bloodsucker/bloodsucker_predator_inline.h + ai/monsters/bloodsucker/bloodsucker_predator_lite.h + ai/monsters/bloodsucker/bloodsucker_predator_lite_inline.h + ai/monsters/bloodsucker/bloodsucker_script.cpp + ai/monsters/bloodsucker/bloodsucker_state_capture_jump.h + ai/monsters/bloodsucker/bloodsucker_state_capture_jump_inline.h + ai/monsters/bloodsucker/bloodsucker_state_manager.cpp + ai/monsters/bloodsucker/bloodsucker_state_manager.h + ai/monsters/bloodsucker/bloodsucker_vampire_approach.h + ai/monsters/bloodsucker/bloodsucker_vampire_approach_inline.h + ai/monsters/bloodsucker/bloodsucker_vampire_effector.cpp + ai/monsters/bloodsucker/bloodsucker_vampire_effector.h + ai/monsters/bloodsucker/bloodsucker_vampire_execute.h + ai/monsters/bloodsucker/bloodsucker_vampire_execute_inline.h + ai/monsters/bloodsucker/bloodsucker_vampire.h + ai/monsters/bloodsucker/bloodsucker_vampire_hide.h + ai/monsters/bloodsucker/bloodsucker_vampire_hide_inline.h + ai/monsters/bloodsucker/bloodsucker_vampire_inline.h + ai/monsters/boar/boar.cpp + ai/monsters/boar/boar.h + ai/monsters/boar/boar_script.cpp + ai/monsters/boar/boar_state_manager.cpp + ai/monsters/boar/boar_state_manager.h + ai/monsters/burer/burer.cpp + ai/monsters/burer/burer_fast_gravi.cpp + ai/monsters/burer/burer_fast_gravi.h + ai/monsters/burer/burer.h + ai/monsters/burer/burer_script.cpp + ai/monsters/burer/burer_state_attack_antiaim.h + ai/monsters/burer/burer_state_attack_antiaim_inline.h + ai/monsters/burer/burer_state_attack_gravi.h + ai/monsters/burer/burer_state_attack_gravi_inline.h + ai/monsters/burer/burer_state_attack.h + ai/monsters/burer/burer_state_attack_inline.h + ai/monsters/burer/burer_state_attack_melee.h + ai/monsters/burer/burer_state_attack_melee_inline.h + ai/monsters/burer/burer_state_attack_run_around.h + ai/monsters/burer/burer_state_attack_run_around_inline.h + ai/monsters/burer/burer_state_attack_shield.h + ai/monsters/burer/burer_state_attack_shield_inline.h + ai/monsters/burer/burer_state_attack_tele.h + ai/monsters/burer/burer_state_attack_tele_inline.h + ai/monsters/burer/burer_state_manager.cpp + ai/monsters/burer/burer_state_manager.h + ai/monsters/cat/cat.cpp + ai/monsters/cat/cat.h + ai/monsters/cat/cat_script.cpp + ai/monsters/cat/cat_state_manager.cpp + ai/monsters/cat/cat_state_manager.h + ai/monsters/chimera/chimera_attack_state.h + ai/monsters/chimera/chimera_attack_state_inline.h + ai/monsters/chimera/chimera.cpp + ai/monsters/chimera/chimera.h + ai/monsters/chimera/chimera_script.cpp + ai/monsters/chimera/chimera_state_hunting_come_out.h + ai/monsters/chimera/chimera_state_hunting_come_out_inline.h + ai/monsters/chimera/chimera_state_hunting.h + ai/monsters/chimera/chimera_state_hunting_inline.h + ai/monsters/chimera/chimera_state_hunting_move_to_cover.h + ai/monsters/chimera/chimera_state_hunting_move_to_cover_inline.h + ai/monsters/chimera/chimera_state_manager.cpp + ai/monsters/chimera/chimera_state_manager.h + ai/monsters/chimera/chimera_state_threaten.h + ai/monsters/chimera/chimera_state_threaten_inline.h + ai/monsters/chimera/chimera_state_threaten_roar.h + ai/monsters/chimera/chimera_state_threaten_roar_inline.h + ai/monsters/chimera/chimera_state_threaten_steal.h + ai/monsters/chimera/chimera_state_threaten_steal_inline.h + ai/monsters/chimera/chimera_state_threaten_walk.h + ai/monsters/chimera/chimera_state_threaten_walk_inline.h + ai/monsters/controller/controller_animation.cpp + ai/monsters/controller/controller_animation.h + ai/monsters/controller/controller.cpp + ai/monsters/controller/controller_direction.cpp + ai/monsters/controller/controller_direction.h + ai/monsters/controller/controller.h + ai/monsters/controller/controller_psy_hit.cpp + ai/monsters/controller/controller_psy_hit_effector.cpp + ai/monsters/controller/controller_psy_hit_effector.h + ai/monsters/controller/controller_psy_hit.h + ai/monsters/controller/controller_script.cpp + ai/monsters/controller/controller_state_attack_camp.h + ai/monsters/controller/controller_state_attack_camp_inline.h + ai/monsters/controller/controller_state_attack_fast_move.h + ai/monsters/controller/controller_state_attack_fast_move_inline.h + ai/monsters/controller/controller_state_attack_fire.h + ai/monsters/controller/controller_state_attack_fire_inline.h + ai/monsters/controller/controller_state_attack.h + ai/monsters/controller/controller_state_attack_hide.h + ai/monsters/controller/controller_state_attack_hide_inline.h + ai/monsters/controller/controller_state_attack_hide_lite.h + ai/monsters/controller/controller_state_attack_hide_lite_inline.h + ai/monsters/controller/controller_state_attack_inline.h + ai/monsters/controller/controller_state_attack_moveout.h + ai/monsters/controller/controller_state_attack_moveout_inline.h + ai/monsters/controller/controller_state_control_hit.h + ai/monsters/controller/controller_state_control_hit_inline.h + ai/monsters/controller/controller_state_manager.cpp + ai/monsters/controller/controller_state_manager.h + ai/monsters/controller/controller_state_panic.h + ai/monsters/controller/controller_tube.h + ai/monsters/controller/controller_tube_inline.h + ai/monsters/dog/dog.cpp + ai/monsters/dog/dog.h + ai/monsters/dog/dog_script.cpp + ai/monsters/dog/dog_state_manager.cpp + ai/monsters/dog/dog_state_manager.h + ai/monsters/flesh/flesh.cpp + ai/monsters/flesh/flesh.h + ai/monsters/flesh/flesh_script.cpp + ai/monsters/flesh/flesh_state_manager.cpp + ai/monsters/flesh/flesh_state_manager.h + ai/monsters/fracture/fracture.cpp + ai/monsters/fracture/fracture.h + ai/monsters/fracture/fracture_script.cpp + ai/monsters/fracture/fracture_state_manager.cpp + ai/monsters/fracture/fracture_state_manager.h + ai/monsters/group_states/group_state_attack.h + ai/monsters/group_states/group_state_attack_inline.h + ai/monsters/group_states/group_state_attack_run.h + ai/monsters/group_states/group_state_attack_run_inline.h + ai/monsters/group_states/group_state_custom.h + ai/monsters/group_states/group_state_custom_inline.h + ai/monsters/group_states/group_state_eat_drag.h + ai/monsters/group_states/group_state_eat_drag_inline.h + ai/monsters/group_states/group_state_eat_eat.h + ai/monsters/group_states/group_state_eat_eat_inline.h + ai/monsters/group_states/group_state_eat.h + ai/monsters/group_states/group_state_eat_inline.h + ai/monsters/group_states/group_state_hear_danger_sound.h + ai/monsters/group_states/group_state_hear_danger_sound_inline.h + ai/monsters/group_states/group_state_home_point_attack.h + ai/monsters/group_states/group_state_home_point_attack_inline.h + ai/monsters/group_states/group_state_panic.h + ai/monsters/group_states/group_state_panic_inline.h + ai/monsters/group_states/group_state_panic_run.h + ai/monsters/group_states/group_state_panic_run_inline.h + ai/monsters/group_states/group_state_rest.h + ai/monsters/group_states/group_state_rest_idle.h + ai/monsters/group_states/group_state_rest_idle_inline.h + ai/monsters/group_states/group_state_rest_inline.h + ai/monsters/group_states/group_state_squad_move_to_radius.h + ai/monsters/group_states/group_state_squad_move_to_radius_inline.h + ai/monsters/group_states/state_adapter.h + ai/monsters/poltergeist/poltergeist_ability.cpp + ai/monsters/poltergeist/poltergeist.cpp + ai/monsters/poltergeist/poltergeist_flame_thrower.cpp + ai/monsters/poltergeist/poltergeist.h + ai/monsters/poltergeist/poltergeist_movement.cpp + ai/monsters/poltergeist/poltergeist_movement.h + ai/monsters/poltergeist/poltergeist_script.cpp + ai/monsters/poltergeist/poltergeist_state_attack_hidden.h + ai/monsters/poltergeist/poltergeist_state_attack_hidden_inline.h + ai/monsters/poltergeist/poltergeist_state_manager.cpp + ai/monsters/poltergeist/poltergeist_state_manager.h + ai/monsters/poltergeist/poltergeist_state_rest.h + ai/monsters/poltergeist/poltergeist_telekinesis.cpp + ai/monsters/pseudodog/pseudodog.cpp + ai/monsters/pseudodog/pseudodog.h + ai/monsters/pseudodog/pseudodog_psi_effector.cpp + ai/monsters/pseudodog/pseudodog_psi_effector.h + ai/monsters/pseudodog/pseudodog_script.cpp + ai/monsters/pseudodog/pseudodog_state_manager.cpp + ai/monsters/pseudodog/pseudodog_state_manager.h + ai/monsters/pseudodog/psy_dog_aura.cpp + ai/monsters/pseudodog/psy_dog_aura.h + ai/monsters/pseudodog/psy_dog.cpp + ai/monsters/pseudodog/psy_dog.h + ai/monsters/pseudodog/psy_dog_state_manager.cpp + ai/monsters/pseudodog/psy_dog_state_manager.h + ai/monsters/pseudodog/psy_dog_state_psy_attack.h + ai/monsters/pseudodog/psy_dog_state_psy_attack_hide.h + ai/monsters/pseudodog/psy_dog_state_psy_attack_hide_inline.h + ai/monsters/pseudodog/psy_dog_state_psy_attack_inline.h + ai/monsters/pseudogigant/pseudo_gigant.cpp + ai/monsters/pseudogigant/pseudo_gigant.h + ai/monsters/pseudogigant/pseudogigant_script.cpp + ai/monsters/pseudogigant/pseudogigant_state_manager.cpp + ai/monsters/pseudogigant/pseudogigant_state_manager.h + ai/monsters/pseudogigant/pseudo_gigant_step_effector.cpp + ai/monsters/pseudogigant/pseudo_gigant_step_effector.h + ai/monsters/rats/ai_rat_animations.cpp + ai/monsters/rats/ai_rat_behaviour.cpp + ai/monsters/rats/ai_rat.cpp + ai/monsters/rats/ai_rat_feel.cpp + ai/monsters/rats/ai_rat_fire.cpp + #ai/monsters/rats/ai_rat_fsm.cpp + ai/monsters/rats/ai_rat.h + ai/monsters/rats/ai_rat_impl.h + ai/monsters/rats/ai_rat_inline.h + ai/monsters/rats/ai_rat_space.h + ai/monsters/rats/ai_rat_templates.cpp + ai/monsters/rats/rat_state_activation.cpp + ai/monsters/rats/rat_state_initialize.cpp + ai/monsters/rats/rat_state_switch.cpp + ai/monsters/snork/snork.cpp + ai/monsters/snork/snork.h + ai/monsters/snork/snork_jump.cpp + ai/monsters/snork/snork_jump.h + ai/monsters/snork/snork_script.cpp + ai/monsters/snork/snork_state_manager.cpp + ai/monsters/snork/snork_state_manager.h + ai/monsters/states/monster_state_attack_camp.h + ai/monsters/states/monster_state_attack_camp_inline.h + ai/monsters/states/monster_state_attack_camp_stealout.h + ai/monsters/states/monster_state_attack_camp_stealout_inline.h + ai/monsters/states/monster_state_attack.h + ai/monsters/states/monster_state_attack_inline.h + ai/monsters/states/monster_state_attack_melee.h + ai/monsters/states/monster_state_attack_melee_inline.h + ai/monsters/states/monster_state_attack_on_run.h + ai/monsters/states/monster_state_attack_on_run_inline.h + ai/monsters/states/monster_state_attack_run_attack.h + ai/monsters/states/monster_state_attack_run_attack_inline.h + ai/monsters/states/monster_state_attack_run.h + ai/monsters/states/monster_state_attack_run_inline.h + ai/monsters/states/monster_state_controlled_attack.h + ai/monsters/states/monster_state_controlled_attack_inline.h + ai/monsters/states/monster_state_controlled_follow.h + ai/monsters/states/monster_state_controlled_follow_inline.h + ai/monsters/states/monster_state_controlled.h + ai/monsters/states/monster_state_controlled_inline.h + ai/monsters/states/monster_state_eat_drag.h + ai/monsters/states/monster_state_eat_drag_inline.h + ai/monsters/states/monster_state_eat_eat.h + ai/monsters/states/monster_state_eat_eat_inline.h + ai/monsters/states/monster_state_eat.h + ai/monsters/states/monster_state_eat_inline.h + ai/monsters/states/monster_state_find_enemy_angry.h + ai/monsters/states/monster_state_find_enemy_angry_inline.h + ai/monsters/states/monster_state_find_enemy.h + ai/monsters/states/monster_state_find_enemy_inline.h + ai/monsters/states/monster_state_find_enemy_look.h + ai/monsters/states/monster_state_find_enemy_look_inline.h + ai/monsters/states/monster_state_find_enemy_run.h + ai/monsters/states/monster_state_find_enemy_run_inline.h + ai/monsters/states/monster_state_find_enemy_walk.h + ai/monsters/states/monster_state_find_enemy_walk_inline.h + ai/monsters/states/monster_state_hear_danger_sound.h + ai/monsters/states/monster_state_hear_danger_sound_inline.h + ai/monsters/states/monster_state_hear_int_sound.h + ai/monsters/states/monster_state_hear_int_sound_inline.h + ai/monsters/states/monster_state_help_sound.h + ai/monsters/states/monster_state_help_sound_inline.h + ai/monsters/states/monster_state_hitted.h + ai/monsters/states/monster_state_hitted_hide.h + ai/monsters/states/monster_state_hitted_hide_inline.h + ai/monsters/states/monster_state_hitted_inline.h + ai/monsters/states/monster_state_hitted_moveout.h + ai/monsters/states/monster_state_hitted_moveout_inline.h + ai/monsters/states/monster_state_home_point_attack.h + ai/monsters/states/monster_state_home_point_attack_inline.h + ai/monsters/states/monster_state_home_point_danger.h + ai/monsters/states/monster_state_home_point_danger_inline.h + ai/monsters/states/monster_state_home_point_rest.h + ai/monsters/states/monster_state_home_point_rest_inline.h + ai/monsters/states/monster_state_panic.h + ai/monsters/states/monster_state_panic_inline.h + ai/monsters/states/monster_state_panic_run.h + ai/monsters/states/monster_state_panic_run_inline.h + ai/monsters/states/monster_state_rest_fun.h + ai/monsters/states/monster_state_rest_fun_inline.h + ai/monsters/states/monster_state_rest.h + ai/monsters/states/monster_state_rest_idle.h + ai/monsters/states/monster_state_rest_idle_inline.h + ai/monsters/states/monster_state_rest_inline.h + ai/monsters/states/monster_state_rest_sleep.h + ai/monsters/states/monster_state_rest_sleep_inline.h + ai/monsters/states/monster_state_rest_walk_graph.h + ai/monsters/states/monster_state_rest_walk_graph_inline.h + ai/monsters/states/monster_state_smart_terrain_task_graph_walk.h + ai/monsters/states/monster_state_smart_terrain_task_graph_walk_inline.h + ai/monsters/states/monster_state_smart_terrain_task.h + ai/monsters/states/monster_state_smart_terrain_task_inline.h + ai/monsters/states/monster_state_squad_rest_follow.h + ai/monsters/states/monster_state_squad_rest_follow_inline.h + ai/monsters/states/monster_state_squad_rest.h + ai/monsters/states/monster_state_squad_rest_inline.h + ai/monsters/states/monster_state_steal.h + ai/monsters/states/monster_state_steal_inline.h + ai/monsters/states/state_custom_action.h + ai/monsters/states/state_custom_action_inline.h + ai/monsters/states/state_custom_action_look.h + ai/monsters/states/state_custom_action_look_inline.h + ai/monsters/states/state_data.h + ai/monsters/states/state_hide_from_point.h + ai/monsters/states/state_hide_from_point_inline.h + ai/monsters/states/state_hit_object.h + ai/monsters/states/state_hit_object_inline.h + ai/monsters/states/state_look_point.h + ai/monsters/states/state_look_point_inline.h + ai/monsters/states/state_look_unprotected_area.h + ai/monsters/states/state_look_unprotected_area_inline.h + ai/monsters/states/state_move_around_point.h + ai/monsters/states/state_move_around_point_inline.h + ai/monsters/states/state_move_to_point.h + ai/monsters/states/state_move_to_point_inline.h + ai/monsters/states/state_move_to_restrictor.h + ai/monsters/states/state_move_to_restrictor_inline.h + ai/monsters/states/state_test_look_actor.h + ai/monsters/states/state_test_look_actor_inline.h + ai/monsters/states/state_test_state.h + ai/monsters/states/state_test_state_inline.h + ai/monsters/tushkano/tushkano.cpp + ai/monsters/tushkano/tushkano.h + ai/monsters/tushkano/tushkano_script.cpp + ai/monsters/tushkano/tushkano_state_manager.cpp + ai/monsters/tushkano/tushkano_state_manager.h + ai/monsters/zombie/zombie.cpp + ai/monsters/zombie/zombie.h + ai/monsters/zombie/zombie_script.cpp + ai/monsters/zombie/zombie_state_attack_run.h + ai/monsters/zombie/zombie_state_attack_run_inline.h + ai/monsters/zombie/zombie_state_manager.cpp + ai/monsters/zombie/zombie_state_manager.h + ai/phantom/phantom.cpp + ai/phantom/phantom.h + ai/stalker/ai_stalker_cover.cpp + ai/stalker/ai_stalker.cpp + ai/stalker/ai_stalker_debug.cpp + ai/stalker/ai_stalker_events.cpp + ai/stalker/ai_stalker_feel.cpp + ai/stalker/ai_stalker_fire.cpp + ai/stalker/ai_stalker.h + ai/stalker/ai_stalker_impl.h + ai/stalker/ai_stalker_inline.h + ai/stalker/ai_stalker_misc.cpp + ai/stalker/ai_stalker_script.cpp + ai/stalker/ai_stalker_script_entity.cpp + ai/stalker/ai_stalker_space.h + ai/trader/ai_trader.cpp + ai/trader/ai_trader.h + ai/trader/ai_trader_script.cpp + ai/trader/trader_animation.cpp + ai/trader/trader_animation.h + CdkeyDecode/base32.c + CdkeyDecode/base32.h + CdkeyDecode/cdkeydecode.c + CdkeyDecode/cdkeydecode.h + ik/aint.cxx + ik/aint.h + ik/Dof7control.cpp + ik/Dof7control.h + ik/eqn.cxx + ik/eqn.h + ik/eulersolver.cxx + ik/eulersolver.h + ik/IKLimb.cpp + ik/IKLimb.h + ik/jtlimits.cxx + ik/jtlimits.h + ik/limb.cxx + ik/limb.h + ik/math3d.cpp + ik/math3d.h + ik/mathTrig.cpp + ik/mathTrig.h + ui/ArtefactDetectorUI.cpp + ui/ArtefactDetectorUI.h + #ui/CExtraContentFilter.cpp + #ui/CExtraContentFilter.h + ui/ChangeWeatherDialog.cpp + ui/ChangeWeatherDialog.hpp + ui/FactionState.cpp + ui/FactionState.h + ui/FactionState_inline.h + ui/FractionState.cpp + ui/FractionState.h + ui/FractionState_inline.h + ui/KillMessageStruct.h + ui/map_hint.cpp + ui/map_hint.h + ui/MMSound.cpp + ui/MMSound.h + ui/Restrictions.cpp + ui/Restrictions.h + ui/ServerList.cpp + ui/ServerList_GameSpy_func.cpp + ui/ServerList.h + ui/TeamInfo.cpp + ui/TeamInfo.h + ui/UIAchievements.cpp + ui/UIAchievements.h + ui/UIActorInfo.cpp + ui/UIActorInfo.h + ui/UIActorMenu_action.cpp + ui/UIActorMenu.cpp + ui/UIActorMenuDeadBodySearch.cpp + ui/UIActorMenu.h + ui/UIActorMenuInitialize.cpp + ui/UIActorMenuInventory.cpp + ui/UIActorMenu_script.cpp + ui/UIActorMenuTrade.cpp + ui/UIActorMenuUpgrade.cpp + ui/UIActorStateInfo.cpp + ui/UIActorStateInfo.h + ui/ui_af_params.cpp + ui/ui_af_params.h + ui/UIArtefactPanel.cpp + ui/UIArtefactPanel.h + ui/UIBoosterInfo.cpp + ui/UIBoosterInfo.h + ui/UIBuyWeaponTab.cpp + ui/UIBuyWeaponTab.h + ui/UIBuyWndBase.h + ui/UIBuyWndShared.cpp + ui/UIBuyWndShared.h + ui/UICarPanel.cpp + ui/UICarPanel.h + ui/UICDkey.cpp + ui/UICDkey.h + ui/UICellCustomItems.cpp + ui/UICellCustomItems.h + ui/UICellItem.cpp + ui/UICellItemFactory.cpp + ui/UICellItemFactory.h + ui/UICellItem.h + ui/UIChangeMap.cpp + ui/UIChangeMap.h + ui/UICharacterInfo.cpp + ui/UICharacterInfo.h + ui/UIChatWnd.cpp + ui/UIChatWnd.h + ui/UIColorAnimatorWrapper.cpp + ui/UIColorAnimatorWrapper.h + ui/UIDebugFonts.cpp + ui/UIDebugFonts.h + ui/UIDemoPlayControl.cpp + ui/UIDemoPlayControl.h + ui/UIDialogWnd.cpp + ui/UIDialogWnd.h + ui/UIDiaryWnd.h + ui/UIDragDropListEx.cpp + ui/UIDragDropListEx.h + ui/UIDragDropReferenceList.cpp + ui/UIDragDropReferenceList.h + ui/UIEditKeyBind.cpp + ui/UIEditKeyBind.h + ui/UIFactionWarWnd.cpp + ui/UIFactionWarWnd.h + #ui/UIFrags2.cpp + #ui/UIFrags2.h + #ui/UIFrags.cpp + #ui/UIFrags.h + #ui/UIFrameLine.cpp + #ui/UIFrameLine.h + ui/UIGameLog.cpp + ui/UIGameLog.h + ui/UIGameTutorial.cpp + ui/UIGameTutorial.h + ui/UIGameTutorialSimpleItem.cpp + ui/UIGameTutorialVideoItem.cpp + ui/UIHelper.cpp + ui/UIHelper.h + ui/UIHudStatesWnd.cpp + ui/UIHudStatesWnd.h + ui/UIInventoryUpgradeWnd_add.cpp + ui/UIInventoryUpgradeWnd.cpp + ui/UIInventoryUpgradeWnd.h + ui/UIInventoryUtilities.cpp + ui/UIInventoryUtilities.h + ui/UIInvUpgrade.cpp + ui/UIInvUpgrade.h + ui/UIInvUpgradeInfo.cpp + ui/UIInvUpgradeInfo.h + ui/UIInvUpgradeProperty.cpp + ui/UIInvUpgradeProperty.h + ui/UIItemInfo.cpp + ui/UIItemInfo.h + ui/UIKeyBinding.cpp + ui/UIKeyBinding.h + ui/UIKickPlayer.cpp + ui/UIKickPlayer.h + ui/UILabel.cpp + ui/UILabel.h + #ui/UIListBox_script.cpp + #ui/UIListItemAdv.cpp + #ui/UIListItemAdv.h + #ui/UIListItemEx.cpp + #ui/UIListItemEx.h + #ui/UIListItem.cpp + #ui/UIListItem.h + ui/UIListItemServer.cpp + ui/UIListItemServer.h + #ui/UIListWnd.cpp + #ui/UIListWnd.h + #ui/UIListWnd_inline.h + #ui/UIListWnd_script.cpp + ui/UILoadingScreen.cpp + ui/UILoadingScreen.h + ui/UILoadingScreenHardcoded.h + ui/UILogsWnd.cpp + ui/UILogsWnd.h + ui/UIMainIngameWnd.cpp + ui/UIMainIngameWnd.h + ui/UIMap.cpp + ui/UIMapDesc.cpp + ui/UIMapDesc.h + ui/UIMapFilters.cpp + ui/UIMapFilters.h + ui/UIMap.h + ui/UIMapInfo.cpp + ui/UIMapInfo.h + ui/UIMapInfo_script.cpp + ui/UIMapLegend.cpp + ui/UIMapLegend.h + ui/UIMapList.cpp + ui/UIMapList.h + ui/UIMapWnd2.cpp + ui/UIMapWndActions.cpp + ui/UIMapWndActions.h + ui/UIMapWndActionsSpace.h + ui/UIMapWnd.cpp + ui/UIMapWnd.h + ui/UIMessageBoxEx.cpp + ui/UIMessageBoxEx.h + ui/UIMessagesWindow.cpp + ui/UIMessagesWindow.h + ui/UIMMShniaga.cpp + ui/UIMMShniaga.h + ui/UIMoneyIndicator.cpp + ui/UIMoneyIndicator.h + ui/UIMotionIcon.cpp + ui/UIMotionIcon.h + ui/UIMPAdminMenu.cpp + ui/UIMPAdminMenu.h + ui/UIMPChangeMapAdm.cpp + ui/UIMPChangeMapAdm.h + ui/UIMpItemsStoreWnd.cpp + ui/UIMpItemsStoreWnd.h + ui/UIMPPlayersAdm.cpp + ui/UIMPPlayersAdm.h + ui/UIMPServerAdm.cpp + ui/UIMPServerAdm.h + ui/UIMpTradeWnd.cpp + ui/UIMpTradeWnd.h + ui/UIMpTradeWnd_init.cpp + ui/UIMpTradeWnd_items.cpp + ui/UIMpTradeWnd_misc.cpp + ui/UIMpTradeWnd_trade.cpp + ui/UIMpTradeWnd_wpn.cpp + ui/UINewsItemWnd.cpp + ui/UINewsItemWnd.h + ui/UIOptConCom.cpp + ui/UIOptConCom.h + ui/UIOutfitInfo.cpp + ui/UIOutfitInfo.h + ui/UIOutfitSlot.cpp + ui/UIOutfitSlot.h + ui/UIPdaKillMessage.cpp + ui/UIPdaKillMessage.h + ui/UIPdaMsgListItem.cpp + ui/UIPdaMsgListItem.h + ui/UIPdaWnd.cpp + ui/UIPdaWnd.h + ui/UIRankFaction.cpp + ui/UIRankFaction.h + ui/UIRankIndicator.cpp + ui/UIRankIndicator.h + ui/UIRankingWnd.cpp + ui/UIRankingWnd.h + ui/UIScriptWnd.cpp + ui/UIScriptWnd.h + ui/UIScriptWnd_script.cpp + ui/UISecondTaskWnd.cpp + ui/UISecondTaskWnd.h + ui/UIServerInfo.cpp + ui/UIServerInfo.h + ui/UISkinSelector.cpp + ui/UISkinSelector.h + ui/UISleepStatic.cpp + ui/UISleepStatic.h + ui/UISpawnWnd.cpp + ui/UISpawnWnd.h + ui/UISpeechMenu.cpp + ui/UISpeechMenu.h + ui/UIStatix.cpp + ui/UIStatix.h + ui/UIStats.cpp + ui/UIStats.h + ui/UIStatsIcon.cpp + ui/UIStatsIcon.h + ui/UIStatsPlayerInfo.cpp + ui/UIStatsPlayerInfo.h + ui/UIStatsPlayerList.cpp + ui/UIStatsPlayerList.h + ui/UITabButtonMP.cpp + ui/UITabButtonMP.h + ui/UITalkDialogWnd.cpp + ui/UITalkDialogWnd.h + ui/UITalkWnd.cpp + ui/UITalkWnd.h + ui/UITaskWnd.cpp + ui/UITaskWnd.h + #ui/UITextBanner.cpp + #ui/UITextBanner.h + ui/UITextVote.cpp + ui/UITextVote.h + ui/UITradeBar.cpp + ui/UITradeBar.h + ui/UITradeWnd.cpp + ui/UITradeWnd.h + ui/UIVersionList.cpp + ui/UIVersionList.h + ui/UIVote.cpp + ui/UIVote.h + ui/UIVoteStatusWnd.cpp + ui/UIVoteStatusWnd.h + ui/UIVotingCategory.cpp + ui/UIVotingCategory.h + ui/UIWarState.cpp + ui/UIWarState.h + ui/UIWeightBar.cpp + ui/UIWeightBar.h + ui/UIWindow_script.cpp + ui/UIWpnParams.cpp + ui/UIWpnParams.h + ui/UIXmlInit.cpp + ui/UIXmlInit.h + gamespy/GameSpy_QR2_callbacks.cpp + gamespy/GameSpy_QR2_callbacks.h + ../xrServerEntities/ai_sounds.h + ../xrServerEntities/alife_human_brain.cpp + ../xrServerEntities/alife_human_brain.h + ../xrServerEntities/alife_human_brain_inline.h + ../xrServerEntities/alife_monster_brain.cpp + ../xrServerEntities/alife_monster_brain.h + ../xrServerEntities/alife_monster_brain_inline.h + ../xrServerEntities/alife_movement_manager_holder.h + ../xrServerEntities/alife_space.cpp + ../xrServerEntities/alife_space.h + ../xrServerEntities/character_info.cpp + ../xrServerEntities/character_info_defs.h + ../xrServerEntities/character_info.h + ../xrServerEntities/clsid_game.h + ../xrServerEntities/game_base_space.h + ../xrServerEntities/gametype_chooser.cpp + ../xrServerEntities/gametype_chooser.h + ../xrServerEntities/InfoPortionDefs.h + ../xrServerEntities/inventory_space.h + ../xrServerEntities/ItemListTypes.h + ../xrServerEntities/object_factory.cpp + ../xrServerEntities/object_factory.h + ../xrServerEntities/object_factory_impl.h + ../xrServerEntities/object_factory_inline.h + ../xrServerEntities/object_factory_register.cpp + ../xrServerEntities/object_factory_script.cpp + ../xrServerEntities/object_factory_space.h + ../xrServerEntities/object_item_abstract.h + ../xrServerEntities/object_item_abstract_inline.h + ../xrServerEntities/object_item_client_server.h + ../xrServerEntities/object_item_client_server_inline.h + ../xrServerEntities/object_item_script.cpp + ../xrServerEntities/object_item_script.h + ../xrServerEntities/object_item_single.h + ../xrServerEntities/object_item_single_inline.h + ../xrServerEntities/pch_script.cpp + ../xrServerEntities/pch_script.h + ../xrServerEntities/PHNetState.h + ../xrServerEntities/PHSynchronize.h + ../xrServerEntities/PropertiesListHelper.h + ../xrServerEntities/PropertiesListTypes.h + ../xrServerEntities/restriction_space.h + ../xrServerEntities/script_fcolor_script.cpp + ../xrServerEntities/script_flags_script.cpp + ../xrServerEntities/script_fmatrix_script.cpp + ../xrServerEntities/script_fvector_script.cpp + ../xrServerEntities/script_ini_file.cpp + ../xrServerEntities/script_ini_file.h + ../xrServerEntities/script_ini_file_script.cpp + ../xrServerEntities/script_net_packet_script.cpp + ../xrServerEntities/script_reader_script.cpp + ../xrServerEntities/script_rtoken_list.h + ../xrServerEntities/script_rtoken_list_inline.h + ../xrServerEntities/script_rtoken_list_script.cpp + ../xrServerEntities/script_sound_type_script.cpp + ../xrServerEntities/script_token_list.cpp + ../xrServerEntities/script_token_list.h + ../xrServerEntities/script_token_list_script.cpp + ../xrServerEntities/script_value_container.h + ../xrServerEntities/script_value_container_impl.h + ../xrServerEntities/ShapeData.h + ../xrServerEntities/shared_data.h + ../xrServerEntities/smart_cast.cpp + ../xrServerEntities/smart_cast.h + ../xrServerEntities/smart_cast_impl0.h + ../xrServerEntities/smart_cast_impl1.h + ../xrServerEntities/smart_cast_impl2.h + ../xrServerEntities/smart_cast_stats.cpp + ../xrServerEntities/specific_character.cpp + ../xrServerEntities/specific_character.h + ../xrServerEntities/xml_str_id_loader.h + ../xrServerEntities/xrEProps.h + ../xrServerEntities/xrMessages.h + ../xrServerEntities/xrServer_Factory.cpp + ../xrServerEntities/xrServer_Object_Base.cpp + ../xrServerEntities/xrServer_Object_Base.h + ../xrServerEntities/xrServer_Objects_Abstract.cpp + ../xrServerEntities/xrServer_Objects_Abstract.h + ../xrServerEntities/xrServer_Objects_ALife_All.h + ../xrServerEntities/xrServer_Objects_ALife.cpp + ../xrServerEntities/xrServer_Objects_ALife.h + ../xrServerEntities/xrServer_Objects_ALife_Items.cpp + ../xrServerEntities/xrServer_Objects_ALife_Items.h + ../xrServerEntities/xrServer_Objects_ALife_Items_script2.cpp + ../xrServerEntities/xrServer_Objects_ALife_Items_script3.cpp + ../xrServerEntities/xrServer_Objects_ALife_Items_script.cpp + ../xrServerEntities/xrServer_Objects_ALife_Monsters.cpp + ../xrServerEntities/xrServer_Objects_ALife_Monsters.h + ../xrServerEntities/xrServer_Objects_ALife_Monsters_script2.cpp + ../xrServerEntities/xrServer_Objects_ALife_Monsters_script3.cpp + ../xrServerEntities/xrServer_Objects_ALife_Monsters_script4.cpp + ../xrServerEntities/xrServer_Objects_ALife_Monsters_script.cpp + ../xrServerEntities/xrServer_Objects_ALife_script2.cpp + ../xrServerEntities/xrServer_Objects_ALife_script3.cpp + ../xrServerEntities/xrServer_Objects_ALife_script.cpp + ../xrServerEntities/xrServer_Objects_Alife_Smartcovers.cpp + ../xrServerEntities/xrServer_Objects_Alife_Smartcovers.h + ../xrServerEntities/xrServer_Objects_Alife_Smartcovers_script.cpp + ../xrServerEntities/xrServer_Objects.cpp + ../xrServerEntities/xrServer_Objects.h + ../xrServerEntities/xrServer_Objects_script2.cpp + ../xrServerEntities/xrServer_Objects_script.cpp + ../xrServerEntities/xrServer_script_macroses.h + ../xrServerEntities/xrServer_Space.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrGame PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/src/xrServerEntities - $<$:${CMAKE_SOURCE_DIR}/Externals/cximage> - ${CMAKE_SOURCE_DIR}/Externals/GameSpy/src - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/Externals/ode/include - ${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc - ${CMAKE_SOURCE_DIR}/sdk/include - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/src/xrServerEntities" + "$<$:${CMAKE_SOURCE_DIR}/Externals/cximage>" + "${CMAKE_SOURCE_DIR}/Externals/GameSpy/src" + "${CMAKE_SOURCE_DIR}/Externals/ode/include" + "${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc" + "${CMAKE_SOURCE_DIR}/sdk/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrGame PRIVATE xrCore xrEngine xrMiscMath - xrLuabind xrImGui xrAPI xrAICore @@ -2641,42 +2634,45 @@ target_link_libraries(${PROJECT_NAME} xrScriptEngine $<$:cximage> xrGameSpy - ${LUA_LIBRARIES} xrCDB xrPhysics xrNetServer ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrGame + PUBLIC + DECLARE_SPECIALIZATION + PURE_DYNAMIC_CAST + PRIVATE - -DXRGAME_EXPORTS + XRGAME_EXPORTS ) -target_compile_options(${PROJECT_NAME} +target_compile_options(xrGame PRIVATE -Wno-trigraphs ) -if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") AND PROJECT_PLATFORM_E2K) # E2K: hack for debug compile (MCST lcc compiler does not support a file > 4Gb, this is a bug in EDG frontend) - target_compile_options(${PROJECT_NAME} +# E2K: hack for debug compile (MCST lcc compiler does not support a file > 4Gb, this is a bug in EDG frontend) +if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") AND PROJECT_PLATFORM_E2K) + target_compile_options(xrGame PRIVATE -g0 ) message(STATUS "Build type is ${CMAKE_BUILD_TYPE}, so disable generation of debug info for xrGame module, because MCST lcc compiler does not support a file > 4 GB (this is a bug in EDG frontend).") endif() -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrGame PROPERTIES PREFIX "" UNITY_BUILD_BATCH_SIZE 50 ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrGame PRIVATE - "$<$:StdAfx.h>" - "$<$:pch_script.h>" + $<$:StdAfx.h> + $<$:pch_script.h> ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrGame LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrGameSpy/CMakeLists.txt b/src/xrGameSpy/CMakeLists.txt index 86126958e21..6c024db1bb2 100644 --- a/src/xrGameSpy/CMakeLists.txt +++ b/src/xrGameSpy/CMakeLists.txt @@ -1,88 +1,86 @@ -project(xrGameSpy) +if (STATIC_BUILD) + add_library(xrGameSpy STATIC) +else() + add_library(xrGameSpy SHARED) +endif() -set(KERNEL_SRC - "stdafx.cpp" - "stdafx.h" - "xrGameSpy.cpp" - "xrGameSpy.h" - "xrGameSpy_MainDefs.h" -) -set(WRAPPER_SRC - "GameSpy_ATLAS.cpp" - "GameSpy_ATLAS.h" - "GameSpy_Available.cpp" - "GameSpy_Available.h" - "GameSpy_Browser.cpp" - "GameSpy_Browser.h" - "GameSpy_BrowsersWrapper.cpp" - "GameSpy_BrowsersWrapper.h" - "GameSpy_Full.cpp" - "GameSpy_Full.h" - "GameSpy_GCD_Client.cpp" - "GameSpy_GCD_Client.h" - "GameSpy_GCD_Server.cpp" - "GameSpy_GCD_Server.h" - "GameSpy_GP.cpp" - "GameSpy_GP.h" - "GameSpy_HTTP.cpp" - "GameSpy_HTTP.h" - "GameSpy_Keys.h" - "GameSpy_Patching.cpp" - "GameSpy_Patching.h" - "GameSpy_QR2.cpp" - "GameSpy_QR2.h" - "GameSpy_SAKE.cpp" - "GameSpy_SAKE.h" +target_sources_grouped( + TARGET xrGameSpy + NAME "Kernel" + FILES + stdafx.cpp + stdafx.h + xrGameSpy.cpp + xrGameSpy.h + xrGameSpy_MainDefs.h ) -source_group("Kernel" FILES ${KERNEL_SRC}) -source_group("Wrapper" FILES ${WRAPPER_SRC}) - -if (STATIC_BUILD) - add_library(${PROJECT_NAME} STATIC ${KERNEL_SRC} ${WRAPPER_SRC}) -else() - add_library(${PROJECT_NAME} SHARED ${KERNEL_SRC} ${WRAPPER_SRC}) -endif() +target_sources_grouped( + TARGET xrGameSpy + NAME "Wrapper" + FILES + GameSpy_ATLAS.cpp + GameSpy_ATLAS.h + GameSpy_Available.cpp + GameSpy_Available.h + GameSpy_Browser.cpp + GameSpy_Browser.h + GameSpy_BrowsersWrapper.cpp + GameSpy_BrowsersWrapper.h + GameSpy_Full.cpp + GameSpy_Full.h + GameSpy_GCD_Client.cpp + GameSpy_GCD_Client.h + GameSpy_GCD_Server.cpp + GameSpy_GCD_Server.h + GameSpy_GP.cpp + GameSpy_GP.h + GameSpy_HTTP.cpp + GameSpy_HTTP.h + GameSpy_Keys.h + GameSpy_Patching.cpp + GameSpy_Patching.h + GameSpy_QR2.cpp + GameSpy_QR2.h + GameSpy_SAKE.cpp + GameSpy_SAKE.h +) -target_include_directories(${PROJECT_NAME} +target_include_directories(xrGameSpy PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/src/xrServerEntities - ${CMAKE_SOURCE_DIR}/Externals/GameSpy/src - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${CMAKE_SOURCE_DIR}/Externals/ode/include - ${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc - ${SDL2_INCLUDE_DIRS} + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/src/xrServerEntities" + "${CMAKE_SOURCE_DIR}/Externals/GameSpy/src" + "${CMAKE_SOURCE_DIR}/Externals/ode/include" + "${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrGameSpy PRIVATE xrCore xrMiscMath GameSpy-oxr - ${SDL2_LIBRARIES} ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrGameSpy PRIVATE - -DXRGAMESPY_EXPORTS - -DXRAY_DISABLE_GAMESPY_WARNINGS + XRGAMESPY_EXPORTS + XRAY_DISABLE_GAMESPY_WARNINGS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrGameSpy PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrGameSpy PRIVATE - "stdafx.h" + stdafx.h ) if (NOT STATIC_BUILD) - install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + install(TARGETS xrGameSpy LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) endif() diff --git a/src/xrNetServer/CMakeLists.txt b/src/xrNetServer/CMakeLists.txt index d8b86e44e53..84012b9f117 100644 --- a/src/xrNetServer/CMakeLists.txt +++ b/src/xrNetServer/CMakeLists.txt @@ -1,62 +1,57 @@ -project(xrNetServer) - -set(SRC_FILES - "guids.cpp" - "ip_filter.cpp" - "ip_filter.h" - "NET_AuthCheck.cpp" - "NET_AuthCheck.h" - #"NET_Client.cpp" - #"NET_Client.h" - "NET_Common.cpp" - "NET_Common.h" - "NET_Compressor.cpp" - "NET_Compressor.h" - "NET_Log.cpp" - "NET_Log.h" - "NET_Messages.h" - "NET_PlayersMonitor.h" - #"NET_Server.cpp" - #"NET_Server.h" - "NET_Shared.h" - "stdafx.cpp" - "stdafx.h" - "empty/NET_Client.cpp" - "empty/NET_Client.h" - "empty/NET_Server.cpp" - "empty/NET_Server.h" +add_library(xrNetServer SHARED) + +target_sources(xrNetServer PRIVATE + guids.cpp + ip_filter.cpp + ip_filter.h + NET_AuthCheck.cpp + NET_AuthCheck.h + #NET_Client.cpp + #NET_Client.h + NET_Common.cpp + NET_Common.h + NET_Compressor.cpp + NET_Compressor.h + NET_Log.cpp + NET_Log.h + NET_Messages.h + NET_PlayersMonitor.h + #NET_Server.cpp + #NET_Server.h + NET_Shared.h + stdafx.cpp + stdafx.h + empty/NET_Client.cpp + empty/NET_Client.h + empty/NET_Server.cpp + empty/NET_Server.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrNetServer PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrNetServer PRIVATE xrCore ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrNetServer PRIVATE - -DXR_NETSERVER_EXPORTS + XR_NETSERVER_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrNetServer PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrNetServer PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrNetServer LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrParticles/CMakeLists.txt b/src/xrParticles/CMakeLists.txt index 711ef5f59cc..84177fd879f 100644 --- a/src/xrParticles/CMakeLists.txt +++ b/src/xrParticles/CMakeLists.txt @@ -1,12 +1,18 @@ -project(xrParticles) +add_library(xrParticles SHARED) -set(KERNEL_SRC +target_sources_grouped( + TARGET xrParticles + NAME "Kernel" + FILES "psystem.h" "stdafx.h" "stdafx.cpp" ) -set(PARTICLE_API_SRC +target_sources_grouped( + TARGET xrParticles + NAME "ParticleAPI" + FILES "noise.cpp" "noise.h" "particle_actions.cpp" @@ -22,41 +28,32 @@ set(PARTICLE_API_SRC "particle_manager.h" ) -source_group("Kernel" FILES ${KERNEL_SRC}) -source_group("ParticleAPI" FILES ${PARTICLE_API_SRC}) - -add_library(${PROJECT_NAME} SHARED - ${KERNEL_SRC} - ${PARTICLE_API_SRC} -) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrParticles PRIVATE - ${CMAKE_SOURCE_DIR}/src + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrParticles PRIVATE xrCore xrMiscMath xrEngine ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrParticles PRIVATE - -DXR_PARTICLES_EXPORTS + XR_PARTICLES_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrParticles PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrParticles PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrParticles LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrPhysics/CMakeLists.txt b/src/xrPhysics/CMakeLists.txt index 3367548a5dd..c46cc9ac55d 100644 --- a/src/xrPhysics/CMakeLists.txt +++ b/src/xrPhysics/CMakeLists.txt @@ -1,369 +1,407 @@ -project(xrPhysics) - -set(KERNEL - "stdafx.cpp" - "StdAfx.h" - "xrPhysics.cpp" - "xrPhysics.h" -) - -set(PHYSICS - "console_vars.cpp" - "console_vars.h" - "ShellHit.cpp" -) - -set(PHYSICS_ACTIVATION_BOX - "IActivationShape.cpp" - "IActivationShape.h" - "PHActivationShape.cpp" - "PHActivationShape.h" -) - -set(PHYSICS_BASE - "DamageSource.h" - "ode_include.h" - "ode_redefine.h" - "PhysicsCommon.h" - "PhysicsExternalCommon.cpp" - "PhysicsExternalCommon.h" -) - -set(PHYSICS_BASE_DEBUG - "debug_output.cpp" - "debug_output.h" -) - -set(PHYSICS_BASE_IMPACT - "PHImpact.h" -) - -set(PHYSICS_BASE_OBJECTS - "PHDefs.h" -) - -set(PHYSICS_BASE_OBJECTS_BASE_SHELL - "IPhysicsShellHolder.h" - "PhysicsShell.cpp" - "PhysicsShell.h" -) - -set(PHYSICS_BASE_OBJECTS_BASE_SHELL_ANIMATOR - "PhysicsShellAnimatorBoneData.h" - "PhysicsShellAnimator.cpp" - "PhysicsShellAnimator.h" -) - -set(PHYSICS_BASE_OBJECTS_BODY_EFFECTORS - "PHBaseBodyEffector.h" - "PHContactBodyEffector.cpp" - "PHContactBodyEffector.h" -) - -set(PHYSICS_BASE_OBJECTS_BREAKABLE - "PHFracture.cpp" - "PHFracture.h" - "PHJointDestroyInfo.cpp" - "PHJointDestroyInfo.h" - "PHShellSplitter.cpp" - "PHShellSplitter.h" -) - -set(PHYSICS_BASE_OBJECTS_COLLIDE_VALIDATOR - "ICollideValidator.h" - "PHCollideValidator.cpp" - "PHCollideValidator.h" -) - -set(PHYSICS_BASE_OBJECTS_DISABLING - "DisablingParams.cpp" - "DisablingParams.h" - "PHDisabling.cpp" - "PHDisabling.h" -) - -set(PHYSICS_BASE_OBJECTS_ELEMENT - "PHElement.cpp" - "PHElement.h" - "PHElementInline.h" - "PHElementNetState.cpp" -) - -set(PHYSICS_BASE_OBJECTS_ELEMENT_GEOM - "ExtendedGeom.cpp" - "ExtendedGeom.h" - "Geometry.cpp" - "Geometry.h" - "PHGeometryOwner.cpp" - "PHGeometryOwner.h" -) - -set(PHYSICS_BASE_OBJECTS_JOINT - "PHJoint.cpp" - "PHJoint.h" -) - -set(PHYSICS_BASE_OBJECTS_MOVE_STORAGE - "PHMoveStorage.cpp" - "PHMoveStorage.h" -) - -set(PHYSICS_BASE_OBJECTS_PH_ISLAND - "PHIsland.cpp" - "PHIsland.h" -) - -set(PHYSICS_BASE_OBJECTS_PH_NET - "../xrServerEntities/PHNetState.cpp" - "../xrServerEntities/PHNetState.h" -) - -set(PHYSICS_BASE_OBJECTS_PH_OBJECT - "PHObject.cpp" - "PHObject.h" - "PHUpdateObject.h" -) - -set(PHYSICS_BASE_OBJECTS_PHY_MOVE_ACTOR_CHARACTER - "PHActorCharacter.cpp" - "PHActorCharacter.h" - "PHActorCharacterInline.h" -) - -set(PHYSICS_BASE_OBJECTS_PHY_MOVE_AI_CHARACTER - "PHAICharacter.cpp" - "PHAICharacter.h" -) - -set(PHYSICS_BASE_OBJECTS_PHY_MOVE_BASE_CHARACTER - "IColisiondamageInfo.h" - "MovementBoxDynamicActivate.cpp" - "MovementBoxDynamicActivate.h" - "PHCharacter.cpp" - "PHCharacter.h" -) - -set(PHYSICS_BASE_OBJECTS_PHY_MOVE_CAPTURE - "IPHCapture.h" - "PHCapture.cpp" - "PHCapture.h" - "PHCaptureInit.cpp" -) - -set(PHYSICS_BASE_OBJECTS_PHY_MOVE_SIMPLE_CHARACTER - "ElevatorState.cpp" - "ElevatorState.h" - "IClimableObject.h" - "IElevatorState.h" - "PHSimpleCharacter.cpp" - "PHSimpleCharacter.h" - "PHSimpleCharacterInline.h" -) - -set(PHYSICS_BASE_OBJECTS_SCRIPT - "iphysics_scripted.h" - "physics_scripted.cpp" - "physics_scripted.h" -) - -set(PHYSICS_BASE_OBJECTS_SHELL - "PHShell.cpp" - "PHShell.h" - "PHShellActivate.cpp" - "PHShellBuildJoint.h" - "PHShellNetState.cpp" -) - -set(PHYSICS_BASE_OBJECTS_SPLITED_SHELL - "PHSplitedShell.cpp" - "PHSplitedShell.h" -) - -set(PHYSICS_BASE_OBJECTS_STATIC_SHELL - "IPHStaticGeomShell.h" - "PHStaticGeomShell.cpp" - "PHStaticGeomShell.h" -) - -set(PHYSICS_BASE_OBJECTS_UTILS - "ph_valid_ode.h" - "phvalide.cpp" - "phvalide.h" - "PHValideValues.h" -) -set(PHYSICS_BASE_OBJECTS_UTILS_INTERPOLATION - "PHInterpolation.cpp" - "PHInterpolation.h" -) - -set(PHYSICS_BASE_OBJECTS_UTILS_MATH - "CalculateTriangle.h" - "MathUtils.cpp" - "MathUtils.h" - "MathUtilsOde.h" - "matrix_utils.h" - "PHDynamicData.cpp" - "PHDynamicData.h" - "SpaceUtils.h" -) - -set(PHYSICS_BASE_OBJECTS_UTILS_STORAGE - "BlockAllocator.h" - "CycleConstStorage.h" -) - -set(PHYSICS_BASE_OBJECTS_WORLD - "GeometryBits.cpp" - "GeometryBits.h" - "IPHWorld.h" - "params.cpp" - "params.h" - "PHItemList.h" - "PHWorld.cpp" - "PHWorld.h" - "Physics.cpp" - "Physics.h" -) - -set(CAMERA_COLLISION - "ActorCameraCollision.cpp" - "ActorCameraCollision.h" -) - -set(COLLIDERS_CYL - "dcylinder/dCylinder.cpp" - "dcylinder/dCylinder.h" -) - -set(COLLIDERS_RAY_MOTIONS - "dRayMotions.cpp" - "dRayMotions.h" -) - -set(COLLIDERS_TRI - "tri-colliderknoopc/__aabb_tri.h" - "tri-colliderknoopc/dcTriangle.h" - #"tri-colliderknoopc/dcTriListCollider.cpp" - #"tri-colliderknoopc/dcTriListCollider.h" - "tri-colliderknoopc/dSortTriPrimitive.cpp" - "tri-colliderknoopc/dSortTriPrimitive.h" - "tri-colliderknoopc/dTriBox.cpp" - "tri-colliderknoopc/dTriBox.h" - "tri-colliderknoopc/dTriCallideK.cpp" - "tri-colliderknoopc/dTriCollideK.h" - "tri-colliderknoopc/dTriColliderCommon.h" - "tri-colliderknoopc/dTriColliderMath.h" - "tri-colliderknoopc/dTriCylinder.cpp" - "tri-colliderknoopc/dTriCylinder.h" - "tri-colliderknoopc/dTriList.cpp" - "tri-colliderknoopc/dTriList.h" - "tri-colliderknoopc/dTriSphere.cpp" - "tri-colliderknoopc/dTriSphere.h" - "tri-colliderknoopc/dxTriList.h" - "tri-colliderknoopc/TriPrimitiveCollideClassDef.h") - -set(DAMAGE_RECEIVER - "collisiondamagereceiver.cpp" - "icollisiondamagereceiver.h" -) - -source_group("kernel" FILES ${KERNEL}) -source_group("physics" FILES ${PHYSICS}) -source_group("physics\\ActivationBox" FILES ${PHYSICS_ACTIVATION_BOX}) -source_group("physics\\Base" FILES ${PHYSICS_BASE}) -source_group("physics\\Base\\Debug" FILES ${PHYSICS_BASE_DEBUG}) -source_group("physics\\Base\\Impact" FILES ${PHYSICS_BASE_IMPACT}) -source_group("physics\\Base\\Objects" FILES ${PHYSICS_BASE_OBJECTS}) -source_group("physics\\Base\\Objects\\BaseShell" FILES ${PHYSICS_BASE_OBJECTS_BASE_SHELL}) -source_group("physics\\Base\\Objects\\BaseShell\\PhysicsShellAnimator" FILES ${PHYSICS_BASE_OBJECTS_BASE_SHELL_ANIMATOR}) -source_group("physics\\Base\\Objects\\BodyEffectors" FILES ${PHYSICS_BASE_OBJECTS_BODY_EFFECTORS}) -source_group("physics\\Base\\Objects\\Breakable" FILES ${PHYSICS_BASE_OBJECTS_BREAKABLE}) -source_group("physics\\Base\\Objects\\CollideValidator" FILES ${PHYSICS_BASE_OBJECTS_COLLIDE_VALIDATOR}) -source_group("physics\\Base\\Objects\\Disabling" FILES ${PHYSICS_BASE_OBJECTS_DISABLING}) -source_group("physics\\Base\\Objects\\Element" FILES ${PHYSICS_BASE_OBJECTS_ELEMENT}) -source_group("physics\\Base\\Objects\\Element\\Geom" FILES ${PHYSICS_BASE_OBJECTS_ELEMENT_GEOM}) -source_group("physics\\Base\\Objects\\Joint" FILES ${PHYSICS_BASE_OBJECTS_JOINT}) -source_group("physics\\Base\\Objects\\MoveStorage" FILES ${PHYSICS_BASE_OBJECTS_MOVE_STORAGE}) -source_group("physics\\Base\\Objects\\PHIsland" FILES ${PHYSICS_BASE_OBJECTS_PH_ISLAND}) -source_group("physics\\Base\\Objects\\PHNet" FILES ${PHYSICS_BASE_OBJECTS_PH_NET}) -source_group("physics\\Base\\Objects\\PHObject" FILES ${PHYSICS_BASE_OBJECTS_PH_OBJECT}) -source_group("physics\\Base\\Objects\\PhyMove\\ActorCharacter" FILES ${PHYSICS_BASE_OBJECTS_PHY_MOVE_ACTOR_CHARACTER}) -source_group("physics\\Base\\Objects\\PhyMove\\AICharacter" FILES ${PHYSICS_BASE_OBJECTS_PHY_MOVE_AI_CHARACTER}) -source_group("physics\\Base\\Objects\\PhyMove\\BaseCharacter" FILES ${PHYSICS_BASE_OBJECTS_PHY_MOVE_BASE_CHARACTER}) -source_group("physics\\Base\\Objects\\PhyMove\\Capture" FILES ${PHYSICS_BASE_OBJECTS_PHY_MOVE_CAPTURE}) -source_group("physics\\Base\\Objects\\PhyMove\\SimpleCharacter" FILES ${PHYSICS_BASE_OBJECTS_PHY_MOVE_SIMPLE_CHARACTER}) -source_group("physics\\Base\\Objects\\script" FILES ${PHYSICS_BASE_OBJECTS_SCRIPT}) -source_group("physics\\Base\\Objects\\Shell" FILES ${PHYSICS_BASE_OBJECTS_SHELL}) -source_group("physics\\Base\\Objects\\SplitedShell" FILES ${PHYSICS_BASE_OBJECTS_SPLITED_SHELL}) -source_group("physics\\Base\\Objects\\StaticShell" FILES ${PHYSICS_BASE_OBJECTS_STATIC_SHELL}) -source_group("physics\\Base\\Objects\\utils" FILES ${PHYSICS_BASE_OBJECTS_UTILS}) -source_group("physics\\Base\\Objects\\utils\\Interpolation" FILES ${PHYSICS_BASE_OBJECTS_UTILS_INTERPOLATION}) -source_group("physics\\Base\\Objects\\utils\\Math" FILES ${PHYSICS_BASE_OBJECTS_UTILS_MATH}) -source_group("physics\\Base\\Objects\\utils\\Storage" FILES ${PHYSICS_BASE_OBJECTS_UTILS_STORAGE}) -source_group("physics\\Base\\Objects\\World" FILES ${PHYSICS_BASE_OBJECTS_WORLD}) -source_group("physics\\Camera collision" FILES ${CAMERA_COLLISION}) -source_group("physics\\colliders\\cyl" FILES ${COLLIDERS_CYL}) -source_group("physics\\colliders\\RayMotions" FILES ${COLLIDERS_RAY_MOTIONS}) -source_group("physics\\colliders\\tri" FILES ${COLLIDERS_TRI}) -source_group("physics\\Damage receiver" FILES ${DAMAGE_RECEIVER}) - -set(SRC_FILES - ${KERNEL} - ${PHYSICS} - ${PHYSICS_ACTIVATION_BOX} - ${PHYSICS_BASE} - ${PHYSICS_BASE_DEBUG} - ${PHYSICS_BASE_IMPACT} - ${PHYSICS_BASE_OBJECTS} - ${PHYSICS_BASE_OBJECTS_BASE_SHELL} - ${PHYSICS_BASE_OBJECTS_BASE_SHELL_ANIMATOR} - ${PHYSICS_BASE_OBJECTS_BODY_EFFECTORS} - ${PHYSICS_BASE_OBJECTS_BREAKABLE} - ${PHYSICS_BASE_OBJECTS_COLLIDE_VALIDATOR} - ${PHYSICS_BASE_OBJECTS_DISABLING} - ${PHYSICS_BASE_OBJECTS_ELEMENT} - ${PHYSICS_BASE_OBJECTS_ELEMENT_GEOM} - ${PHYSICS_BASE_OBJECTS_JOINT} - ${PHYSICS_BASE_OBJECTS_MOVE_STORAGE} - ${PHYSICS_BASE_OBJECTS_PH_ISLAND} - ${PHYSICS_BASE_OBJECTS_PH_NET} - ${PHYSICS_BASE_OBJECTS_PH_OBJECT} - ${PHYSICS_BASE_OBJECTS_PHY_MOVE_ACTOR_CHARACTER} - ${PHYSICS_BASE_OBJECTS_PHY_MOVE_AI_CHARACTER} - ${PHYSICS_BASE_OBJECTS_PHY_MOVE_BASE_CHARACTER} - ${PHYSICS_BASE_OBJECTS_PHY_MOVE_CAPTURE} - ${PHYSICS_BASE_OBJECTS_PHY_MOVE_SIMPLE_CHARACTER} - ${PHYSICS_BASE_OBJECTS_SCRIPT} - ${PHYSICS_BASE_OBJECTS_SHELL} - ${PHYSICS_BASE_OBJECTS_SPLITED_SHELL} - ${PHYSICS_BASE_OBJECTS_STATIC_SHELL} - ${PHYSICS_BASE_OBJECTS_UTILS} - ${PHYSICS_BASE_OBJECTS_UTILS_INTERPOLATION} - ${PHYSICS_BASE_OBJECTS_UTILS_MATH} - ${PHYSICS_BASE_OBJECTS_UTILS_STORAGE} - ${PHYSICS_BASE_OBJECTS_WORLD} - ${CAMERA_COLLISION} - ${COLLIDERS_CYL} - ${COLLIDERS_RAY_MOTIONS} - ${COLLIDERS_TRI} - ${DAMAGE_RECEIVER} -) - if (STATIC_BUILD) - add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) + add_library(xrPhysics STATIC) else() - add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) + add_library(xrPhysics SHARED) endif() -target_include_directories(${PROJECT_NAME} +target_sources_grouped( + TARGET xrPhysics + NAME "Kernel" + FILES + stdafx.cpp + StdAfx.h + xrPhysics.cpp + xrPhysics.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics" + FILES + console_vars.cpp + console_vars.h + ShellHit.cpp +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\ActivationBox" + FILES + IActivationShape.cpp + IActivationShape.h + PHActivationShape.cpp + PHActivationShape.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base" + FILES + DamageSource.h + ode_include.h + ode_redefine.h + PhysicsCommon.h + PhysicsExternalCommon.cpp + PhysicsExternalCommon.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Debug" + FILES + debug_output.cpp + debug_output.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Impact" + FILES + PHImpact.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects" + FILES + PHDefs.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\BaseShell" + FILES + IPhysicsShellHolder.h + PhysicsShell.cpp + PhysicsShell.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\BaseShell\\PhysicsShellAnimator" + FILES + PhysicsShellAnimatorBoneData.h + PhysicsShellAnimator.cpp + PhysicsShellAnimator.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\BodyEffectors" + FILES + PHBaseBodyEffector.h + PHContactBodyEffector.cpp + PHContactBodyEffector.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Breakable" + FILES + PHFracture.cpp + PHFracture.h + PHJointDestroyInfo.cpp + PHJointDestroyInfo.h + PHShellSplitter.cpp + PHShellSplitter.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\CollideValidator" + FILES + ICollideValidator.h + PHCollideValidator.cpp + PHCollideValidator.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Disabling" + FILES + DisablingParams.cpp + DisablingParams.h + PHDisabling.cpp + PHDisabling.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Element" + FILES + PHElement.cpp + PHElement.h + PHElementInline.h + PHElementNetState.cpp +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Element\\Geom" + FILES + ExtendedGeom.cpp + ExtendedGeom.h + Geometry.cpp + Geometry.h + PHGeometryOwner.cpp + PHGeometryOwner.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Joint" + FILES + PHJoint.cpp + PHJoint.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\MoveStorage" + FILES + PHMoveStorage.cpp + PHMoveStorage.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PHIsland" + FILES + PHIsland.cpp + PHIsland.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PHNet" + FILES + ../xrServerEntities/PHNetState.cpp + ../xrServerEntities/PHNetState.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PHObject" + FILES + PHObject.cpp + PHObject.h + PHUpdateObject.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PhyMove\\ActorCharacter" + FILES + PHActorCharacter.cpp + PHActorCharacter.h + PHActorCharacterInline.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PhyMove\\AICharacter" + FILES + PHAICharacter.cpp + PHAICharacter.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PhyMove\\BaseCharacter" + FILES + IColisiondamageInfo.h + MovementBoxDynamicActivate.cpp + MovementBoxDynamicActivate.h + PHCharacter.cpp + PHCharacter.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PhyMove\\Capture" + FILES + IPHCapture.h + PHCapture.cpp + PHCapture.h + PHCaptureInit.cpp +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\PhyMove\\SimpleCharacter" + FILES + ElevatorState.cpp + ElevatorState.h + IClimableObject.h + IElevatorState.h + PHSimpleCharacter.cpp + PHSimpleCharacter.h + PHSimpleCharacterInline.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\script" + FILES + iphysics_scripted.h + physics_scripted.cpp + physics_scripted.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\Shell" + FILES + PHShell.cpp + PHShell.h + PHShellActivate.cpp + PHShellBuildJoint.h + PHShellNetState.cpp +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\SplitedShell" + FILES + PHSplitedShell.cpp + PHSplitedShell.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\StaticShell" + FILES + IPHStaticGeomShell.h + PHStaticGeomShell.cpp + PHStaticGeomShell.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\utils" + FILES + ph_valid_ode.h + phvalide.cpp + phvalide.h + PHValideValues.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\utils\\Interpolation" + FILES + PHInterpolation.cpp + PHInterpolation.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\utils\\Math" + FILES + CalculateTriangle.h + MathUtils.cpp + MathUtils.h + MathUtilsOde.h + matrix_utils.h + PHDynamicData.cpp + PHDynamicData.h + SpaceUtils.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\utils\\Storage" + FILES + BlockAllocator.h + CycleConstStorage.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Base\\Objects\\World" + FILES + GeometryBits.cpp + GeometryBits.h + IPHWorld.h + params.cpp + params.h + PHItemList.h + PHWorld.cpp + PHWorld.h + Physics.cpp + Physics.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Camera collision" + FILES + ActorCameraCollision.cpp + ActorCameraCollision.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\colliders\\cyl" + FILES + dcylinder/dCylinder.cpp + dcylinder/dCylinder.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\colliders\\RayMotions" + FILES + dRayMotions.cpp + dRayMotions.h +) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\colliders\\tri" + FILES + tri-colliderknoopc/__aabb_tri.h + tri-colliderknoopc/dcTriangle.h + #tri-colliderknoopc/dcTriListCollider.cpp + #tri-colliderknoopc/dcTriListCollider.h + tri-colliderknoopc/dSortTriPrimitive.cpp + tri-colliderknoopc/dSortTriPrimitive.h + tri-colliderknoopc/dTriBox.cpp + tri-colliderknoopc/dTriBox.h + tri-colliderknoopc/dTriCallideK.cpp + tri-colliderknoopc/dTriCollideK.h + tri-colliderknoopc/dTriColliderCommon.h + tri-colliderknoopc/dTriColliderMath.h + tri-colliderknoopc/dTriCylinder.cpp + tri-colliderknoopc/dTriCylinder.h + tri-colliderknoopc/dTriList.cpp + tri-colliderknoopc/dTriList.h + tri-colliderknoopc/dTriSphere.cpp + tri-colliderknoopc/dTriSphere.h + tri-colliderknoopc/dxTriList.h + tri-colliderknoopc/TriPrimitiveCollideClassDef.h) + +target_sources_grouped( + TARGET xrPhysics + NAME "Physics\\Damage receiver" + FILES + collisiondamagereceiver.cpp + icollisiondamagereceiver.h +) + + +target_include_directories(xrPhysics + PUBLIC + "${CMAKE_SOURCE_DIR}/Externals" + PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/ode/include - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals/imgui" + "${CMAKE_SOURCE_DIR}/Externals/ode/include" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrPhysics PUBLIC xrODE PRIVATE @@ -376,24 +414,24 @@ target_link_libraries(${PROJECT_NAME} xrSound ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrPhysics PRIVATE - -DXRPHYSICS_EXPORTS + XRPHYSICS_EXPORTS + PURE_DYNAMIC_CAST ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrPhysics PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrPhysics PRIVATE - "StdAfx.h" + StdAfx.h ) if (NOT STATIC_BUILD) - install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + install(TARGETS xrPhysics LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) endif() diff --git a/src/xrScriptEngine/CMakeLists.txt b/src/xrScriptEngine/CMakeLists.txt index 7fb216717c0..ead48c5ce2b 100644 --- a/src/xrScriptEngine/CMakeLists.txt +++ b/src/xrScriptEngine/CMakeLists.txt @@ -1,138 +1,142 @@ -project(xrScriptEngine) - -set(DEBUG_SRC - "mslotutils.h" - "script_callStack.cpp" - "script_callStack.hpp" - "script_debugger.cpp" - "script_debugger.hpp" - "script_debugger_messages.hpp" - "script_debugger_threads.cpp" - "script_debugger_threads.hpp" - "script_lua_helper.cpp" - "script_lua_helper.hpp" -) - -set(ENGINE_SRC - "BindingsDumper.cpp" - "BindingsDumper.hpp" - "Functor.hpp" - "script_engine.cpp" - "script_engine.hpp" - "script_space_forward.hpp" - "ScriptEngineScript.cpp" - "ScriptEngineScript.hpp" -) - -set(EXPORT_SRC - "ScriptExporter.cpp" - "ScriptExporter.hpp" - "ScriptExportMacros.hpp" -) - -set(KERNEL_SRC - "DebugMacros.hpp" - "pch.cpp" - "pch.hpp" - "ScriptEngineConfig.hpp" - "xrScriptEngine.cpp" - "xrScriptEngine.hpp" -) - -set(LUA_STUDIO_SRC - "LuaStudio/Config.hpp" - "LuaStudio/Defines.hpp" - "LuaStudio/LuaStudio.cpp" - "LuaStudio/LuaStudio.hpp" -) - -set(LUA_STUDIO_BACKEND_SRC - "LuaStudio/Backend/Backend.hpp" - "LuaStudio/Backend/Engine.hpp" - "LuaStudio/Backend/Interfaces.hpp" - "LuaStudio/Backend/LibraryLinkage.hpp" - "LuaStudio/Backend/World.hpp" -) - -set(PROCESS_SRC - "script_process.cpp" - "script_process.hpp" -) - -set(SCRIPT_CALLBACK_EX_SRC - "script_callback_ex.h" -) - -set(THREAD_SRC - "script_thread.cpp" - "script_thread.hpp" -) - -set(THREAD_STACK_TRACKER_SRC - "script_stack_tracker.cpp" - "script_stack_tracker.hpp" -) - -source_group("Debug" FILES ${DEBUG_SRC}) -source_group("Engine" FILES ${ENGINE_SRC}) -source_group("Export" FILES ${EXPORT_SRC}) -source_group("Kernel" FILES ${KERNEL_SRC}) -source_group("LuaStudio" FILES ${LUA_STUDIO_SRC}) -source_group("LuaStudio\\Backend" FILES ${LUA_STUDIO_BACKEND_SRC}) -source_group("Process" FILES ${PROCESS_SRC}) -source_group("ScriptCallbackEx" FILES ${SCRIPT_CALLBACK_EX_SRC}) -source_group("Thread" FILES ${THREAD_SRC}) -source_group("Thread\\StackTracker" FILES ${THREAD_STACK_TRACKER_SRC}) - -add_library(${PROJECT_NAME} SHARED - ${DEBUG_SRC} - ${ENGINE_SRC} - ${EXPORT_SRC} - ${KERNEL_SRC} - ${LUA_STUDIO_SRC} - ${LUA_STUDIO_BACKEND_SRC} - ${PROCESS_SRC} - ${SCRIPT_CALLBACK_EX_SRC} - ${THREAD_SRC} - ${THREAD_STACK_TRACKER_SRC} -) - -target_include_directories(${PROJECT_NAME} +add_library(xrScriptEngine SHARED) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Debug" + FILES + mslotutils.h + script_callStack.cpp + script_callStack.hpp + script_debugger.cpp + script_debugger.hpp + script_debugger_messages.hpp + script_debugger_threads.cpp + script_debugger_threads.hpp + script_lua_helper.cpp + script_lua_helper.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Engine" + FILES + BindingsDumper.cpp + BindingsDumper.hpp + Functor.hpp + script_engine.cpp + script_engine.hpp + script_space_forward.hpp + ScriptEngineScript.cpp + ScriptEngineScript.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Export" + FILES + ScriptExporter.cpp + ScriptExporter.hpp + ScriptExportMacros.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Kernel" + FILES + DebugMacros.hpp + pch.cpp + pch.hpp + ScriptEngineConfig.hpp + xrScriptEngine.cpp + xrScriptEngine.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "LuaStudio" + FILES + LuaStudio/Config.hpp + LuaStudio/Defines.hpp + LuaStudio/LuaStudio.cpp + LuaStudio/LuaStudio.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "LuaStudio\\Backend" + FILES + LuaStudio/Backend/Backend.hpp + LuaStudio/Backend/Engine.hpp + LuaStudio/Backend/Interfaces.hpp + LuaStudio/Backend/LibraryLinkage.hpp + LuaStudio/Backend/World.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Process" + FILES + script_process.cpp + script_process.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "ScriptCallbackEx" + FILES + script_callback_ex.h +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Thread" + FILES + script_thread.cpp + script_thread.hpp +) + +target_sources_grouped( + TARGET xrScriptEngine + NAME "Thread\\StackTracker" + FILES + script_stack_tracker.cpp + script_stack_tracker.hpp +) + +target_include_directories(xrScriptEngine PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/xrLuaFix - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrScriptEngine + PUBLIC + xrLuabind + PRIVATE xrAPI xrCore xrLuaFix - xrLuabind - ${LUA_LIBRARIES} ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrScriptEngine PRIVATE - -DXRSCRIPTENGINE_EXPORTS + XRSCRIPTENGINE_EXPORTS # Uncomment next string for debug script engine - #-DCONFIG_SCRIPT_ENGINE_LOG_EXPORTS - #-DCONFIG_SCRIPT_ENGINE_LOG_SKIPPED_EXPORTS + #CONFIG_SCRIPT_ENGINE_LOG_EXPORTS + #CONFIG_SCRIPT_ENGINE_LOG_SKIPPED_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrScriptEngine PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrScriptEngine PRIVATE - "pch.hpp" + pch.hpp ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrScriptEngine LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrScriptEngine/xrScriptEngine.hpp b/src/xrScriptEngine/xrScriptEngine.hpp index 88750599fa9..a1bdf1f5ee3 100644 --- a/src/xrScriptEngine/xrScriptEngine.hpp +++ b/src/xrScriptEngine/xrScriptEngine.hpp @@ -18,7 +18,6 @@ extern "C" { #pragma warning(disable : 4459) // declaration of 'x' hides global declaration #pragma warning(disable : 4913) // user defined binary operator 'x' exists but no overload could convert all operands #pragma warning(disable : 4297) // function assumed not to throw exception but does -// XXX: define LUABIND_DYNAMIC_LINK in engine config header #include #include #include diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 79f994f76fc..4c00ee6f84a 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -1,124 +1,136 @@ -project(xrSound) - -set(CACHE_SRC - "SoundRender_Cache.cpp" - "SoundRender_Cache.h" -) - -set(CORE_SRC - "SoundRender_Core.cpp" - "SoundRender_Core.h" - "SoundRender_Core_Processor.cpp" - "SoundRender_Core_SourceManager.cpp" - "SoundRender_Core_StartStop.cpp" -) - -set(CORE_OPENAL_SRC - "OpenALDeviceList.cpp" - "OpenALDeviceList.h" - "SoundRender_CoreA.cpp" - "SoundRender_CoreA.h" -) - -set(EFFECTS_SRC - "SoundRender_Effects.h" -) - -set(EFFECTS_OPENAL_SRC - "SoundRender_EffectsA_EAX.cpp" - "SoundRender_EffectsA_EAX.h" - "SoundRender_EffectsA_EFX.cpp" - "SoundRender_EffectsA_EFX.h" -) - -set(EMITTER_SRC - "SoundRender_Emitter.cpp" - "SoundRender_Emitter.h" - "SoundRender_Emitter_FSM.cpp" - "SoundRender_Emitter_StartStop.cpp" - "SoundRender_Emitter_streamer.cpp" -) - -set(ENVIRONMENT_SRC - "SoundRender_Environment.cpp" - "SoundRender_Environment.h" -) - -set(KERNEL_SRC - "guids.cpp" - "Sound.cpp" - "Sound.h" - "SoundRender.h" - "stdafx.cpp" - "stdafx.h" -) - -set(SOURCE_SRC - "SoundRender_Source.cpp" - "SoundRender_Source.h" - "SoundRender_Source_loader.cpp" -) - -set(TARGET_SRC - "SoundRender_Target.cpp" - "SoundRender_Target.h" -) - -set(TARGET_OPENAL_SRC - "SoundRender_TargetA.cpp" - "SoundRender_TargetA.h" -) - -#set(STREAMING_SRC -# "MusicStream.cpp" -# "MusicStream.h" -# "xr_streamsnd.cpp" -# "xr_streamsnd.h" +add_library(xrSound SHARED) + +target_sources_grouped( + TARGET xrSound + NAME "Cache" + FILES + SoundRender_Cache.cpp + SoundRender_Cache.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Core" + FILES + SoundRender_Core.cpp + SoundRender_Core.h + SoundRender_Core_Processor.cpp + SoundRender_Core_SourceManager.cpp + SoundRender_Core_StartStop.cpp +) + +target_sources_grouped( + TARGET xrSound + NAME "Core\\OpenAL" + FILES + OpenALDeviceList.cpp + OpenALDeviceList.h + SoundRender_CoreA.cpp + SoundRender_CoreA.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Effects" + FILES + SoundRender_Effects.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Effects\\OpenAL" + FILES + SoundRender_EffectsA_EAX.cpp + SoundRender_EffectsA_EAX.h + SoundRender_EffectsA_EFX.cpp + SoundRender_EffectsA_EFX.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Emitter" + FILES + SoundRender_Emitter.cpp + SoundRender_Emitter.h + SoundRender_Emitter_FSM.cpp + SoundRender_Emitter_StartStop.cpp + SoundRender_Emitter_streamer.cpp +) + +target_sources_grouped( + TARGET xrSound + NAME "Environment" + FILES + SoundRender_Environment.cpp + SoundRender_Environment.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Kernel" + FILES + guids.cpp + Sound.cpp + Sound.h + SoundRender.h + stdafx.cpp + stdafx.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Source" + FILES + SoundRender_Source.cpp + SoundRender_Source.h + SoundRender_Source_loader.cpp +) + +target_sources_grouped( + TARGET xrSound + NAME "Target" + FILES + SoundRender_Target.cpp + SoundRender_Target.h +) + +target_sources_grouped( + TARGET xrSound + NAME "Target\\OpenAL" + FILES + SoundRender_TargetA.cpp + SoundRender_TargetA.h +) + +#target_sources_grouped( +# TARGET xrSound +# NAME "Stream" +# FILES +# MusicStream.cpp +# MusicStream.h +# xr_streamsnd.cpp +# xr_streamsnd.h #) -#set(CDAUDIO_SRC -# "xr_cda.cpp" -# "xr_cda.h" +#target_sources_grouped( +# TARGET xrSound +# NAME "CDA" +# FILES +# xr_cda.cpp +# xr_cda.h #) -source_group("Cache" FILES ${CACHE_SRC}) -source_group("Core" FILES ${CORE_SRC}) -source_group("Core\\OpenAL" FILES ${CORE_OPENAL_SRC}) -source_group("Effects" FILES ${EFFECTS_SRC}) -source_group("Effects\\OpenAL" FILES ${EFFECTS_OPENAL_SRC}) -source_group("Emitter" FILES ${EMITTER_SRC}) -source_group("Environment" FILES ${ENVIRONMENT_SRC}) -source_group("Kernel" FILES ${KERNEL_SRC}) -source_group("Source" FILES ${SOURCE_SRC}) -source_group("Target" FILES ${TARGET_SRC}) -source_group("Target\\OpenAL" FILES ${TARGET_OPENAL_SRC}) - -add_library(${PROJECT_NAME} SHARED - ${CACHE_SRC} - ${CORE_SRC} - ${CORE_OPENAL_SRC} - ${EFFECTS_SRC} - ${EFFECTS_OPENAL_SRC} - ${EMITTER_SRC} - ${ENVIRONMENT_SRC} - ${KERNEL_SRC} - ${SOURCE_SRC} - ${TARGET_SRC} - ${TARGET_OPENAL_SRC} -) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrSound PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/src/xrEngine - ${CMAKE_SOURCE_DIR}/Externals/libvorbis/include - ${CMAKE_SOURCE_DIR}/Externals/libogg/include - ${OPENAL_INCLUDE_DIR} - ${OGG_INCLUDE_DIRS} - ${SDL2_INCLUDE_DIRS} + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/src/xrEngine" + "${CMAKE_SOURCE_DIR}/Externals/libvorbis/include" + "${CMAKE_SOURCE_DIR}/Externals/libogg/include" + "${OPENAL_INCLUDE_DIR}" + "${OGG_INCLUDE_DIRS}" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xrSound PRIVATE xrCore xrMiscMath @@ -130,21 +142,20 @@ target_link_libraries(${PROJECT_NAME} Vorbis::VorbisFile ) -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrSound PRIVATE - -DXRSOUND_EXPORTS + XRSOUND_EXPORTS ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrSound PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrSound PRIVATE - "stdafx.h" + stdafx.h ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrSound LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xrUICore/CMakeLists.txt b/src/xrUICore/CMakeLists.txt index 2150e028e16..c3c63a5390d 100644 --- a/src/xrUICore/CMakeLists.txt +++ b/src/xrUICore/CMakeLists.txt @@ -1,151 +1,144 @@ -project(xrUICore) +add_library(xrUICore SHARED) -set(SRC_FILES - "pch.cpp" - "pch.hpp" - "ui_base.cpp" - "ui_base.h" - "ui_debug.cpp" - "ui_debug.h" - "ui_defs.h" - "ui_styles.cpp" - "ui_styles.h" - "uiabstract.h" - "UIMessages.h" - "arrow/ui_arrow.cpp" - "arrow/ui_arrow.h" - "Buttons/UI3tButton.cpp" - "Buttons/UI3tButton.h" - "Buttons/UIBtnHint.cpp" - "Buttons/UIBtnHint.h" - "Buttons/UIButton.cpp" - "Buttons/UIButton.h" - "Buttons/UIButton_script.cpp" - "Buttons/UICheckButton.cpp" - "Buttons/UICheckButton.h" - "Buttons/UIRadioButton.cpp" - "Buttons/UIRadioButton.h" - "Callbacks/UIWndCallback.cpp" - "Callbacks/UIWndCallback.h" - "Callbacks/callback_info.h" - "ComboBox/UIComboBox.cpp" - "ComboBox/UIComboBox.h" - "ComboBox/UIComboBox_script.cpp" - "Cursor/UICursor.cpp" - "Cursor/UICursor.h" - "EditBox/UICustomEdit.cpp" - "EditBox/UICustomEdit.h" - "EditBox/UIEditBox.cpp" - "EditBox/UIEditBox.h" - "EditBox/UIEditBoxEx.cpp" - "EditBox/UIEditBoxEx.h" - "EditBox/UIEditBox_script.cpp" - "FontManager/FontManager.cpp" - "FontManager/FontManager.h" - "Hint/UIHint.cpp" - "Hint/UIHint.h" - "InteractiveBackground/UIInteractiveBackground.h" - "InteractiveBackground/UI_IB_Static.cpp" - "InteractiveBackground/UI_IB_Static.h" - "Lines/UILine.cpp" - "Lines/UILine.h" - "Lines/UILines.cpp" - "Lines/UILines.h" - "Lines/UISubLine.cpp" - "Lines/UISubLine.h" - "Lines/uilinestd.h" - "ListBox/UIListBox.cpp" - "ListBox/UIListBox.h" - "ListBox/UIListBoxItem.cpp" - "ListBox/UIListBoxItem.h" - "ListBox/UIListBoxItemMsgChain.cpp" - "ListBox/UIListBoxItemMsgChain.h" - "ListBox/UIListBox_script.cpp" - "ListWnd/UIListItem.cpp" - "ListWnd/UIListItem.h" - "ListWnd/UIListItemEx.cpp" - "ListWnd/UIListItemEx.h" - "ListWnd/UIListWnd.cpp" - "ListWnd/UIListWnd.h" - "ListWnd/UIListWnd_inline.h" - "ListWnd/UIListWnd_script.cpp" - "MessageBox/UIMessageBox.cpp" - "MessageBox/UIMessageBox.h" - "MessageBox/UIMessageBox_script.cpp" - "Options/UIOptionsItem.cpp" - "Options/UIOptionsItem.h" - "Options/UIOptionsManager.cpp" - "Options/UIOptionsManager.h" - "Options/UIOptionsManagerScript.cpp" - "Options/UIOptionsManagerScript.h" - "ProgressBar/UIDoubleProgressBar.cpp" - "ProgressBar/UIDoubleProgressBar.h" - "ProgressBar/UIProgressBar.cpp" - "ProgressBar/UIProgressBar.h" - "ProgressBar/UIProgressBar_script.cpp" - "ProgressBar/UIProgressShape.cpp" - "ProgressBar/UIProgressShape.h" - "PropertiesBox/UIPropertiesBox.cpp" - "PropertiesBox/UIPropertiesBox.h" - "PropertiesBox/UIPropertiesBox_script.cpp" - "ScrollBar/UIFixedScrollBar.cpp" - "ScrollBar/UIFixedScrollBar.h" - "ScrollBar/UIScrollBar.cpp" - "ScrollBar/UIScrollBar.h" - "ScrollBar/UIScrollBox.cpp" - "ScrollBar/UIScrollBox.h" - "ScrollView/UIScrollView.cpp" - "ScrollView/UIScrollView.h" - "SpinBox/UICustomSpin.cpp" - "SpinBox/UICustomSpin.h" - "SpinBox/UISpinNum.cpp" - "SpinBox/UISpinNum.h" - "SpinBox/UISpinText.cpp" - "SpinBox/UISpinText.h" - "Static/UIAnimatedStatic.cpp" - "Static/UIAnimatedStatic.h" - "Static/UILanimController.cpp" - "Static/UILanimController.h" - "Static/UIStatic.cpp" - "Static/UIStatic.h" - "Static/UIStaticItem.cpp" - "Static/UIStaticItem.h" - "Static/UIStatic_script.cpp" - "TabControl/UITabButton.cpp" - "TabControl/UITabButton.h" - "TabControl/UITabControl.cpp" - "TabControl/UITabControl.h" - "TabControl/UITabControl_script.cpp" - "TrackBar/UITrackBar.cpp" - "TrackBar/UITrackBar.h" - "Windows/UIFrameLineWnd.cpp" - "Windows/UIFrameLineWnd.h" - "Windows/UIFrameWindow.cpp" - "Windows/UIFrameWindow.h" - "Windows/UITextFrameLineWnd.cpp" - "Windows/UITextFrameLineWnd.h" - "Windows/UIWindow.cpp" - "Windows/UIWindow.h" - "Windows/UIWindow_script.cpp" - "XML/UITextureMaster.cpp" - "XML/UITextureMaster.h" - "XML/UIXmlInitBase.cpp" - "XML/UIXmlInitBase.h" - "XML/xrUIXmlParser.cpp" - "XML/xrUIXmlParser.h" +target_sources(xrUICore PRIVATE + pch.cpp + pch.hpp + ui_base.cpp + ui_base.h + ui_debug.cpp + ui_debug.h + ui_defs.h + ui_styles.cpp + ui_styles.h + uiabstract.h + UIMessages.h + arrow/ui_arrow.cpp + arrow/ui_arrow.h + Buttons/UI3tButton.cpp + Buttons/UI3tButton.h + Buttons/UIBtnHint.cpp + Buttons/UIBtnHint.h + Buttons/UIButton.cpp + Buttons/UIButton.h + Buttons/UIButton_script.cpp + Buttons/UICheckButton.cpp + Buttons/UICheckButton.h + Buttons/UIRadioButton.cpp + Buttons/UIRadioButton.h + Callbacks/UIWndCallback.cpp + Callbacks/UIWndCallback.h + Callbacks/callback_info.h + ComboBox/UIComboBox.cpp + ComboBox/UIComboBox.h + ComboBox/UIComboBox_script.cpp + Cursor/UICursor.cpp + Cursor/UICursor.h + EditBox/UICustomEdit.cpp + EditBox/UICustomEdit.h + EditBox/UIEditBox.cpp + EditBox/UIEditBox.h + EditBox/UIEditBoxEx.cpp + EditBox/UIEditBoxEx.h + EditBox/UIEditBox_script.cpp + FontManager/FontManager.cpp + FontManager/FontManager.h + Hint/UIHint.cpp + Hint/UIHint.h + InteractiveBackground/UIInteractiveBackground.h + InteractiveBackground/UI_IB_Static.cpp + InteractiveBackground/UI_IB_Static.h + Lines/UILine.cpp + Lines/UILine.h + Lines/UILines.cpp + Lines/UILines.h + Lines/UISubLine.cpp + Lines/UISubLine.h + Lines/uilinestd.h + ListBox/UIListBox.cpp + ListBox/UIListBox.h + ListBox/UIListBoxItem.cpp + ListBox/UIListBoxItem.h + ListBox/UIListBoxItemMsgChain.cpp + ListBox/UIListBoxItemMsgChain.h + ListBox/UIListBox_script.cpp + ListWnd/UIListItem.cpp + ListWnd/UIListItem.h + ListWnd/UIListItemEx.cpp + ListWnd/UIListItemEx.h + ListWnd/UIListWnd.cpp + ListWnd/UIListWnd.h + ListWnd/UIListWnd_inline.h + ListWnd/UIListWnd_script.cpp + MessageBox/UIMessageBox.cpp + MessageBox/UIMessageBox.h + MessageBox/UIMessageBox_script.cpp + Options/UIOptionsItem.cpp + Options/UIOptionsItem.h + Options/UIOptionsManager.cpp + Options/UIOptionsManager.h + Options/UIOptionsManagerScript.cpp + Options/UIOptionsManagerScript.h + ProgressBar/UIDoubleProgressBar.cpp + ProgressBar/UIDoubleProgressBar.h + ProgressBar/UIProgressBar.cpp + ProgressBar/UIProgressBar.h + ProgressBar/UIProgressBar_script.cpp + ProgressBar/UIProgressShape.cpp + ProgressBar/UIProgressShape.h + PropertiesBox/UIPropertiesBox.cpp + PropertiesBox/UIPropertiesBox.h + PropertiesBox/UIPropertiesBox_script.cpp + ScrollBar/UIFixedScrollBar.cpp + ScrollBar/UIFixedScrollBar.h + ScrollBar/UIScrollBar.cpp + ScrollBar/UIScrollBar.h + ScrollBar/UIScrollBox.cpp + ScrollBar/UIScrollBox.h + ScrollView/UIScrollView.cpp + ScrollView/UIScrollView.h + SpinBox/UICustomSpin.cpp + SpinBox/UICustomSpin.h + SpinBox/UISpinNum.cpp + SpinBox/UISpinNum.h + SpinBox/UISpinText.cpp + SpinBox/UISpinText.h + Static/UIAnimatedStatic.cpp + Static/UIAnimatedStatic.h + Static/UILanimController.cpp + Static/UILanimController.h + Static/UIStatic.cpp + Static/UIStatic.h + Static/UIStaticItem.cpp + Static/UIStaticItem.h + Static/UIStatic_script.cpp + TabControl/UITabButton.cpp + TabControl/UITabButton.h + TabControl/UITabControl.cpp + TabControl/UITabControl.h + TabControl/UITabControl_script.cpp + TrackBar/UITrackBar.cpp + TrackBar/UITrackBar.h + Windows/UIFrameLineWnd.cpp + Windows/UIFrameLineWnd.h + Windows/UIFrameWindow.cpp + Windows/UIFrameWindow.h + Windows/UITextFrameLineWnd.cpp + Windows/UITextFrameLineWnd.h + Windows/UIWindow.cpp + Windows/UIWindow.h + Windows/UIWindow_script.cpp + XML/UITextureMaster.cpp + XML/UITextureMaster.h + XML/UIXmlInitBase.cpp + XML/UIXmlInitBase.h + XML/xrUIXmlParser.cpp + XML/xrUIXmlParser.h ) -group_sources(SRC_FILES) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) - -target_include_directories(${PROJECT_NAME} +target_include_directories(xrUICore PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/Externals/lzo/include - ${CMAKE_SOURCE_DIR}/Externals/luabind - ${SDL2_INCLUDE_DIRS} + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" ) target_link_libraries(xrUICore @@ -156,30 +149,28 @@ target_link_libraries(xrUICore xrMiscMath xrImGui xrCore - xrLuabind - ${SDL2_LIBRARIES} ) if (WIN32) add_compile_options(/fp:fast "/Yupch.hpp") - set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/pch.cpp PROPERTIES COMPILE_FLAGS /Yc) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/pch.cpp" PROPERTIES COMPILE_FLAGS /Yc) endif() -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(xrUICore PRIVATE - -DXRUICORE_EXPORTS + XRUICORE_EXPORTS + PURE_DYNAMIC_CAST ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(xrUICore PROPERTIES PREFIX "" ) -target_precompile_headers(${PROJECT_NAME} +target_precompile_headers(xrUICore PRIVATE - "pch.hpp" + pch.hpp ) -install(TARGETS ${PROJECT_NAME} LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +install(TARGETS xrUICore LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) diff --git a/src/xr_3da/CMakeLists.txt b/src/xr_3da/CMakeLists.txt index 9d49c464399..b253d1cb0fd 100644 --- a/src/xr_3da/CMakeLists.txt +++ b/src/xr_3da/CMakeLists.txt @@ -1,34 +1,35 @@ -project(xr_3da) +add_executable(xr_3da) -set(SRC_FILES - "AccessibilityShortcuts.hpp" - "entry_point.cpp" - "resource.h" - "stdafx.h" - "stdafx.cpp" +target_sources(xr_3da PRIVATE + AccessibilityShortcuts.hpp + entry_point.cpp + resource.h + stdafx.h + stdafx.cpp ) -group_sources(SRC_FILES) - -add_executable(${PROJECT_NAME} ${SRC_FILES}) -set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) +set_property( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + PROPERTY + VS_STARTUP_PROJECT xr_3da +) -target_include_directories(${PROJECT_NAME} +target_include_directories(xr_3da PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${SDL2_INCLUDE_DIRS} + "${CMAKE_SOURCE_DIR}/src" ) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(xr_3da PRIVATE xrCore xrAPI xrEngine ) -set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") +set_target_properties(xr_3da PROPERTIES + PREFIX "" +) -install(TARGETS ${PROJECT_NAME} RUNTIME - DESTINATION ${CMAKE_INSTALL_BINDIR} - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +install(TARGETS xr_3da RUNTIME + DESTINATION "${CMAKE_INSTALL_BINDIR}" ) From 00e9d4a1a4e91fc3eee7c33b55eae30e100bf646 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 29 Nov 2023 07:05:45 +0500 Subject: [PATCH 004/497] removed empty imgui.cmake --- Externals/imgui-proj/imgui.cmake | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Externals/imgui-proj/imgui.cmake diff --git a/Externals/imgui-proj/imgui.cmake b/Externals/imgui-proj/imgui.cmake deleted file mode 100644 index e69de29bb2d..00000000000 From 74fc4322a0197a1b36434089856145dc7dd8bdee Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 29 Nov 2023 07:49:30 +0500 Subject: [PATCH 005/497] Common/Common.hpp: move submodule check --- src/Common/Common.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Common/Common.hpp b/src/Common/Common.hpp index 12f3cae38b0..64132ae62e9 100644 --- a/src/Common/Common.hpp +++ b/src/Common/Common.hpp @@ -1,10 +1,10 @@ #pragma once -#if _MSC_VER -#include "submodule_check.hpp" -#endif - #include "Common/Config.hpp" #include "Common/Platform.hpp" #include "Common/FSMacros.hpp" #include "Include/xrAPI/xrAPI.h" + +#ifdef XR_COMPILER_MSVC +# include "submodule_check.hpp" +#endif From af1b18ca822cbd0fceec630c97942e6ccdf3b3dd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Dec 2023 02:27:30 +0500 Subject: [PATCH 006/497] Update zlib again --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 15c45adb76e..643e17b7498 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 15c45adb76e81a7e3a8a9e17b2a56eb90f668f44 +Subproject commit 643e17b7498d12ab8d15565662880579692f769d From a39037626113149e7323578d5e418b0bed9624c5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 03:42:37 +0500 Subject: [PATCH 007/497] xrSound: moved sound subsystem initialization to new CSoundManager class --- src/xrEngine/Engine.h | 2 ++ src/xrEngine/main.cpp | 6 +++--- src/xrSound/Sound.cpp | 19 ++++++++++--------- src/xrSound/Sound.h | 15 ++++++++------- src/xrSound/SoundRender_Core.h | 7 ++++--- src/xrSound/SoundRender_CoreA.cpp | 4 +--- src/xrSound/SoundRender_CoreA.h | 1 - src/xrSound/xrSound.vcxproj | 2 +- src/xrSound/xrSound.vcxproj.filters | 2 +- 9 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/xrEngine/Engine.h b/src/xrEngine/Engine.h index 2681a15b79f..392379efcf1 100644 --- a/src/xrEngine/Engine.h +++ b/src/xrEngine/Engine.h @@ -13,6 +13,7 @@ #include "EngineAPI.h" #include "EventAPI.h" #include "xrSheduler.h" +#include "xrSound/Sound.h" // TODO: this should be in render configuration #define R__NUM_SUN_CASCADES (3u) // csm/s.ligts @@ -27,6 +28,7 @@ class ENGINE_API CEngine CEngineAPI External; CEventAPI Event; CSheduler Sheduler; + CSoundManager Sound; void Initialize(); void Destroy(); diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp index 5558d4e265b..e927f7aa75f 100644 --- a/src/xrEngine/main.cpp +++ b/src/xrEngine/main.cpp @@ -173,9 +173,9 @@ ENGINE_API void InitInput() } ENGINE_API void destroyInput() { xr_delete(pInput); } -ENGINE_API void InitSoundDeviceList() { ISoundManager::_create_devices_list(); } -ENGINE_API void InitSound() { ISoundManager::_create(); } -ENGINE_API void destroySound() { ISoundManager::_destroy(); } +ENGINE_API void InitSoundDeviceList() { Engine.Sound.CreateDevicesList(); } +ENGINE_API void InitSound() { Engine.Sound.Create(); } +ENGINE_API void destroySound() { Engine.Sound.Destroy(); } ENGINE_API void destroySettings() { auto s = const_cast(&pSettings); diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index e18fb7f4047..ac00942f574 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -5,25 +5,26 @@ XRSOUND_API xr_token* snd_devices_token = nullptr; XRSOUND_API u32 snd_device_id = u32(-1); -void ISoundManager::_create_devices_list() +void CSoundManager::CreateDevicesList() { - SoundRenderA = xr_new(); - SoundRender = SoundRenderA; - GEnv.Sound = SoundRender; + SoundRender = xr_new(); SoundRender->bPresent = strstr(Core.Params, "-nosound") == nullptr; if (SoundRender->bPresent) - GEnv.Sound->_initialize_devices_list(); + SoundRender->_initialize_devices_list(); + + GEnv.Sound = SoundRender; } -void ISoundManager::_create() +void CSoundManager::Create() { if (SoundRender->bPresent) - GEnv.Sound->_initialize(); + SoundRender->_initialize(); } -void ISoundManager::_destroy() +void CSoundManager::Destroy() { - GEnv.Sound->_clear(); + SoundRender->_clear(); xr_delete(SoundRender); + GEnv.Sound = nullptr; } diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 7431823cb9e..a60f1d5fa4e 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -203,10 +203,6 @@ namespace CDB /// definition (Sound Manager Interface) class XRSOUND_API XR_NOVTABLE ISoundManager { - virtual void _initialize_devices_list() = 0; - virtual void _initialize() = 0; - virtual void _clear() = 0; - protected: friend class ref_sound_data; virtual bool _create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; @@ -214,9 +210,6 @@ class XRSOUND_API XR_NOVTABLE ISoundManager public: virtual ~ISoundManager() = default; - static void _create_devices_list(); - static void _create(); - static void _destroy(); virtual void _restart() = 0; virtual bool i_locked() = 0; @@ -260,6 +253,14 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) = 0; }; +class XRSOUND_API CSoundManager +{ +public: + void CreateDevicesList(); + void Create(); + void Destroy(); +}; + class CSound_UserDataVisitor; class CSound_UserData : public xr_resource diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index a743f4bcc47..6a514def384 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -78,11 +78,12 @@ class CSoundRender_Core : public ISoundManager public: CSoundRender_Core(); - virtual ~CSoundRender_Core(); + ~CSoundRender_Core() override; // General - void _initialize() override = 0; - void _clear() override = 0; + virtual void _initialize_devices_list() = 0; + virtual void _initialize() = 0; + virtual void _clear() = 0; void _restart() override; // Sound interface diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index ae37ab407b9..0df394adb96 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -7,9 +7,7 @@ #include "SoundRender_EffectsA_EAX.h" #include "SoundRender_EffectsA_EFX.h" -CSoundRender_CoreA* SoundRenderA = nullptr; - -CSoundRender_CoreA::CSoundRender_CoreA() : CSoundRender_Core() +CSoundRender_CoreA::CSoundRender_CoreA() { pDevice = nullptr; pDeviceList = nullptr; diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index 0b7a36ebedd..f4dd0514d68 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -75,4 +75,3 @@ class CSoundRender_CoreA : public CSoundRender_Core const Fvector& listener_position() override { return Listener.position; } }; -extern CSoundRender_CoreA* SoundRenderA; diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index b4d088a86a6..45e998ffeba 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -52,7 +52,7 @@ - + diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index 76307208f68..116d9294d06 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -86,7 +86,7 @@ Kernel - + Kernel From 4e04d276e6e83d4cc33a1b2f5055fe7af2319850 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 04:46:20 +0500 Subject: [PATCH 008/497] xrSound: Moved sound devices and environment lib to CSoundManager --- src/xrEngine/xr_ioc_cmd.cpp | 4 +-- src/xrSound/OpenALDeviceList.cpp | 30 +++++-------------- src/xrSound/OpenALDeviceList.h | 1 - src/xrSound/Sound.cpp | 41 +++++++++++++++++++++++-- src/xrSound/Sound.h | 15 ++++++++-- src/xrSound/SoundRender_Core.cpp | 50 ++++++++----------------------- src/xrSound/SoundRender_Core.h | 9 ++---- src/xrSound/SoundRender_CoreA.cpp | 3 +- src/xrSound/SoundRender_CoreA.h | 2 +- 9 files changed, 79 insertions(+), 76 deletions(-) diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index 9e9c186e60b..79387aa9aa9 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -702,8 +702,8 @@ class CCC_soundDevice : public CCC_Token const xr_token* GetToken() noexcept override { - tokens = snd_devices_token; - return inherited::GetToken(); + tokens = Engine.Sound.GetDevicesList().data(); + return tokens; } virtual void Save(IWriter* F) diff --git a/src/xrSound/OpenALDeviceList.cpp b/src/xrSound/OpenALDeviceList.cpp index 9a9dfba6a42..2f6c3e5a1bc 100644 --- a/src/xrSound/OpenALDeviceList.cpp +++ b/src/xrSound/OpenALDeviceList.cpp @@ -24,7 +24,7 @@ #include "stdafx.h" #include "OpenALDeviceList.h" -#include "xrCore/xr_token.h" +#include "SoundRender_Core.h" #include #include @@ -40,21 +40,6 @@ ALDeviceList::ALDeviceList() Enumerate(); } -/* - * Exit call - */ -ALDeviceList::~ALDeviceList() -{ - for (int i = 0; snd_devices_token[i].name; i++) - { - pstr tokenName = const_cast(snd_devices_token[i].name); - xr_free(tokenName); - } - - xr_free(snd_devices_token); - snd_devices_token = nullptr; -} - void ALDeviceList::IterateAndAddDevicesString(pcstr devices) { // go through device list (each device terminated with a single NULL, list terminated with double NULL) @@ -155,14 +140,15 @@ void ALDeviceList::Enumerate() // make token const auto _cnt = GetNumDevices(); - snd_devices_token = xr_alloc(_cnt + 1); - snd_devices_token[_cnt].id = -1; - snd_devices_token[_cnt].name = nullptr; + + auto& devices = SoundRender->Parent.GetDevicesList(); + devices.reserve(_cnt + 1); + for (u32 i = 0; i < _cnt; ++i) { - snd_devices_token[i].id = i; - snd_devices_token[i].name = xr_strdup(m_devices[i].name); + devices.emplace_back(xr_strdup(m_devices[i].name), i); } + devices.emplace_back(nullptr, -1); //-- if (0 == GetNumDevices()) @@ -188,7 +174,7 @@ void ALDeviceList::Enumerate() pcstr ALDeviceList::GetDeviceName(size_t index) const { - return snd_devices_token[index].name; + return m_devices[index].name; } void ALDeviceList::SelectBestDevice() diff --git a/src/xrSound/OpenALDeviceList.h b/src/xrSound/OpenALDeviceList.h index 148d521d1e2..9e76b1d8eaf 100644 --- a/src/xrSound/OpenALDeviceList.h +++ b/src/xrSound/OpenALDeviceList.h @@ -39,7 +39,6 @@ class ALDeviceList public: ALDeviceList(); - ~ALDeviceList(); [[nodiscard]] size_t GetNumDevices() const { return m_devices.size(); } diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index ac00942f574..e68945cbebb 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -2,15 +2,16 @@ #include "SoundRender_CoreA.h" -XRSOUND_API xr_token* snd_devices_token = nullptr; XRSOUND_API u32 snd_device_id = u32(-1); void CSoundManager::CreateDevicesList() { - SoundRender = xr_new(); + SoundRender = xr_new(*this); SoundRender->bPresent = strstr(Core.Params, "-nosound") == nullptr; if (SoundRender->bPresent) SoundRender->_initialize_devices_list(); + else + soundDevices.emplace_back("null", -1); GEnv.Sound = SoundRender; } @@ -18,13 +19,47 @@ void CSoundManager::CreateDevicesList() void CSoundManager::Create() { if (SoundRender->bPresent) + { + env_load(); SoundRender->_initialize(); + } } void CSoundManager::Destroy() { + GEnv.Sound = nullptr; + SoundRender->_clear(); xr_delete(SoundRender); - GEnv.Sound = nullptr; + env_unload(); + + for (auto& token : soundDevices) + { + pstr tokenName = const_cast(token.name); + xr_free(tokenName); + } + soundDevices.clear(); +} + +void CSoundManager::env_load() +{ + string_path fn; + if (FS.exist(fn, "$game_data$", SNDENV_FILENAME)) + { + soundEnvironment = xr_new(); + soundEnvironment->Load(fn); + } +} + +void CSoundManager::env_unload() +{ + if (soundEnvironment) + soundEnvironment->Unload(); + xr_delete(soundEnvironment); +} + +SoundEnvironment_LIB* CSoundManager::get_env_library() const +{ + return soundEnvironment; } diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index a60f1d5fa4e..c2af6984e70 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -4,6 +4,7 @@ #include "xrCore/_flags.h" #include "xrCore/xr_resource.h" #include "xrCore/_vector3d.h" +#include "xrCore/xr_token.h" #include "xrCommon/xr_vector.h" // DEFINE_VECTOR #ifdef XRAY_STATIC_BUILD @@ -49,7 +50,6 @@ XRSOUND_API extern Flags32 psSoundFlags; XRSOUND_API extern int psSoundTargets; XRSOUND_API extern int psSoundCacheSizeMB; XRSOUND_API extern u32 psSoundPrecacheAll; -XRSOUND_API extern xr_token* snd_devices_token; XRSOUND_API extern u32 snd_device_id; // Flags @@ -245,7 +245,6 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void object_relcase(IGameObject* obj) = 0; virtual const Fvector& listener_position() = 0; - virtual SoundEnvironment_LIB* get_env_library() = 0; virtual void refresh_env_library() = 0; virtual void set_user_env(CSound_environment* E) = 0; virtual void refresh_sources() = 0; @@ -255,10 +254,20 @@ class XRSOUND_API XR_NOVTABLE ISoundManager class XRSOUND_API CSoundManager { + xr_vector soundDevices; + + SoundEnvironment_LIB* soundEnvironment{}; + public: - void CreateDevicesList(); + void CreateDevicesList(); + auto& GetDevicesList() { return soundDevices; } + void Create(); void Destroy(); + + SoundEnvironment_LIB* get_env_library() const; + void env_load(); + void env_unload(); }; class CSound_UserDataVisitor; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index fcbb0db110c..b27564717fa 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -34,14 +34,14 @@ XRSOUND_API u32 psSoundPrecacheAll = 1; CSoundRender_Core* SoundRender = nullptr; -CSoundRender_Core::CSoundRender_Core() +CSoundRender_Core::CSoundRender_Core(CSoundManager& p) + : Parent(p) { bPresent = false; bUserEnvironment = false; geom_MODEL = nullptr; geom_ENV = nullptr; geom_SOM = nullptr; - s_environment = nullptr; Handler = nullptr; s_targets_pu = 0; s_emitters_u = 0; @@ -68,9 +68,6 @@ void CSoundRender_Core::_initialize() Timer.Start(); TimerPersistent.Start(); - // load environment - env_load(); - bPresent = true; // Cache @@ -86,7 +83,6 @@ void CSoundRender_Core::_clear() { bReady = false; cache.destroy(); - env_unload(); // remove sources for (auto& kv : s_sources) @@ -120,31 +116,6 @@ int CSoundRender_Core::pause_emitters(bool val) return m_iPauseCounter; } -void CSoundRender_Core::env_load() -{ - // Load environment - string_path fn; - if (FS.exist(fn, "$game_data$", SNDENV_FILENAME)) - { - s_environment = xr_new(); - s_environment->Load(fn); - } - - // Load geometry - - // Associate geometry -} - -void CSoundRender_Core::env_unload() -{ - // Unload - if (s_environment) - s_environment->Unload(); - xr_delete(s_environment); - - // Unload geometry -} - void CSoundRender_Core::_restart() { cache.destroy(); @@ -205,7 +176,8 @@ void CSoundRender_Core::set_geometry_env(IReader* I) xr_delete(geom_ENV); if (nullptr == I) return; - if (nullptr == s_environment) + const auto envLib = Parent.get_env_library(); + if (!envLib) return; // Associate names @@ -215,7 +187,7 @@ void CSoundRender_Core::set_geometry_env(IReader* I) { string256 n; names->r_stringZ(n, sizeof(n)); - int id = s_environment->GetID(n); + int id = envLib->GetID(n); R_ASSERT(id >= 0); ids.push_back((u16)id); } @@ -431,6 +403,8 @@ CSoundRender_Environment* CSoundRender_Core::get_environment(const Fvector& P) geom_DB.ray_query(CDB::OPT_ONLYNEAREST, geom_ENV, P, dir, 1000.f); if (geom_DB.r_count()) { + const auto envLib = Parent.get_env_library(); + CDB::RESULT* r = geom_DB.r_begin(); CDB::TRI* T = geom_ENV->get_tris() + r->id; Fvector* V = geom_ENV->get_verts(); @@ -440,10 +414,10 @@ CSoundRender_Environment* CSoundRender_Core::get_environment(const Fvector& P) if (dot < 0) { u16 id_front = (u16)((T->dummy & 0x0000ffff) >> 0); // front face - return s_environment->Get(id_front); + return envLib->Get(id_front); } u16 id_back = (u16)((T->dummy & 0xffff0000) >> 16); // back face - return s_environment->Get(id_back); + return envLib->Get(id_back); } identity.set_identity(); return &identity; @@ -502,10 +476,11 @@ void CSoundRender_Core::set_user_env(CSound_environment* E) void CSoundRender_Core::refresh_env_library() { - env_unload(); - env_load(); + Parent.env_unload(); + Parent.env_load(); env_apply(); } + void CSoundRender_Core::refresh_sources() { for (auto& emit : s_emitters) @@ -517,6 +492,7 @@ void CSoundRender_Core::refresh_sources() s->load(*s->fname); } } + void CSoundRender_Core::set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) { // XXX: old SDK functionality diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 6a514def384..b1a394514ce 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -32,6 +32,8 @@ class CSoundRender_Core : public ISoundManager SoundStatistics Stats; public: + CSoundManager& Parent; + using event = std::pair; xr_vector s_events; @@ -65,7 +67,6 @@ class CSoundRender_Core : public ISoundManager xr_vector s_targets; xr_vector s_targets_defer; u32 s_targets_pu; // parameters update - SoundEnvironment_LIB* s_environment; CSoundRender_Environment s_user_environment; CSoundRender_Effects* m_effects{}; @@ -77,7 +78,7 @@ class CSoundRender_Core : public ISoundManager u32 cache_bytes_per_line; public: - CSoundRender_Core(); + CSoundRender_Core(CSoundManager& p); ~CSoundRender_Core() override; // General @@ -123,7 +124,6 @@ class CSoundRender_Core : public ISoundManager // virtual const Fvector& listener_position ( )=0; virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) = 0; - virtual SoundEnvironment_LIB* get_env_library() { return s_environment; } virtual void refresh_env_library(); virtual void set_user_env(CSound_environment* E); virtual void refresh_sources(); @@ -148,9 +148,6 @@ class CSoundRender_Core : public ISoundManager float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) override; float get_occlusion(Fvector& P, float R, Fvector* occ) override; CSoundRender_Environment* get_environment(const Fvector& P); - - void env_load(); - void env_unload(); void env_apply(); }; diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 0df394adb96..ae8ee3fdedc 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -7,7 +7,8 @@ #include "SoundRender_EffectsA_EAX.h" #include "SoundRender_EffectsA_EFX.h" -CSoundRender_CoreA::CSoundRender_CoreA() +CSoundRender_CoreA::CSoundRender_CoreA(CSoundManager& p) + : CSoundRender_Core(p) { pDevice = nullptr; pDeviceList = nullptr; diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index f4dd0514d68..ee973ad128e 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -64,7 +64,7 @@ class CSoundRender_CoreA : public CSoundRender_Core void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) override; public: - CSoundRender_CoreA(); + CSoundRender_CoreA(CSoundManager& p); void _initialize_devices_list() override; void _initialize() override; From ad264365305b9ff24dae5b6874d4cb9779e67f9d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 04:49:27 +0500 Subject: [PATCH 009/497] xrSound/xrSound.vcxproj.filters: add missing filter --- src/xrSound/xrSound.vcxproj.filters | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index 116d9294d06..d888556773e 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -152,5 +152,6 @@ + \ No newline at end of file From 6f3ec5ccca04dfef7390f872f40fd8203db1426c Mon Sep 17 00:00:00 2001 From: AMS21 Date: Mon, 4 Dec 2023 01:37:36 +0100 Subject: [PATCH 010/497] Allow engine to run with no sound devices available (#1506) Co-authored-by: Xottab-DUTY --- src/xrGame/GamePersistent.cpp | 2 +- src/xrGame/script_sound.cpp | 2 +- src/xrGame/ui/UIGameTutorial.cpp | 2 +- src/xrGame/ui/UIGameTutorialSimpleItem.cpp | 2 +- src/xrGame/ui/UIGameTutorialVideoItem.cpp | 2 +- src/xrSound/Sound.cpp | 16 ++++++++++++---- src/xrSound/Sound.h | 2 ++ src/xrSound/SoundRender_CoreA.cpp | 21 ++++++++++++++------- 8 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 5eb2bb968fd..89afbb22d5d 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -300,7 +300,7 @@ void CGamePersistent::WeathersUpdate() snd.play_at_pos(nullptr, pos); #ifdef DEBUG - if (!snd._handle() && strstr(Core.Params, "-nosound")) + if (!snd._handle() && !Engine.Sound.IsSoundEnabled()) continue; #endif // DEBUG diff --git a/src/xrGame/script_sound.cpp b/src/xrGame/script_sound.cpp index e221e4be82f..39362cd0b76 100644 --- a/src/xrGame/script_sound.cpp +++ b/src/xrGame/script_sound.cpp @@ -16,7 +16,7 @@ CScriptSound::CScriptSound(LPCSTR caSoundName, ESoundTypes sound_type) { - m_bIsNoSound = strstr(Core.Params, "-nosound"); + m_bIsNoSound = !Engine.Sound.IsSoundEnabled(); m_caSoundToPlay = caSoundName; string_path l_caFileName; VERIFY(GEnv.Sound); diff --git a/src/xrGame/ui/UIGameTutorial.cpp b/src/xrGame/ui/UIGameTutorial.cpp index 509b67e1632..2e5fbbb8e49 100644 --- a/src/xrGame/ui/UIGameTutorial.cpp +++ b/src/xrGame/ui/UIGameTutorial.cpp @@ -150,7 +150,7 @@ bool CUISequencer::Start(LPCSTR tutor_name) if (snd_name && snd_name[0]) { m_global_sound.create(snd_name, st_Effect, sg_Undefined); - VERIFY(m_global_sound._handle() || strstr(Core.Params, "-nosound")); + VERIFY(m_global_sound._handle() || !Engine.Sound.IsSoundEnabled()); } m_start_lua_function = uiXml.Read("function_on_start", 0, ""); m_stop_lua_function = uiXml.Read("function_on_stop", 0, ""); diff --git a/src/xrGame/ui/UIGameTutorialSimpleItem.cpp b/src/xrGame/ui/UIGameTutorialSimpleItem.cpp index 4d9f6304d8b..83184d000d8 100644 --- a/src/xrGame/ui/UIGameTutorialSimpleItem.cpp +++ b/src/xrGame/ui/UIGameTutorialSimpleItem.cpp @@ -59,7 +59,7 @@ void CUISequenceSimpleItem::Load(CUIXml* xml, int idx) if (m_snd_name && m_snd_name[0]) { m_sound.create(m_snd_name, st_Effect, sg_Undefined); - VERIFY(m_sound._handle() || strstr(Core.Params, "-nosound")); + VERIFY(m_sound._handle() || !Engine.Sound.IsSoundEnabled()); } m_time_length = xml->ReadFlt("length_sec", 0, 0); m_desired_cursor_pos.x = xml->ReadAttribFlt("cursor_pos", 0, "x", 0); diff --git a/src/xrGame/ui/UIGameTutorialVideoItem.cpp b/src/xrGame/ui/UIGameTutorialVideoItem.cpp index b01c8b2b69d..e076ca6a02b 100644 --- a/src/xrGame/ui/UIGameTutorialVideoItem.cpp +++ b/src/xrGame/ui/UIGameTutorialVideoItem.cpp @@ -116,7 +116,7 @@ void CUISequenceVideoItem::Load(CUIXml* xml, int idx) m_sound[0] = one; } - VERIFY(m_sound[0]._handle() || strstr(Core.Params, "-nosound")); + VERIFY(m_sound[0]._handle() || !Engine.Sound.IsSoundEnabled()); } xml->SetLocalRoot(_stored_root); diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index e68945cbebb..3a1539eb0a9 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -6,12 +6,15 @@ XRSOUND_API u32 snd_device_id = u32(-1); void CSoundManager::CreateDevicesList() { + static bool noSound = strstr(Core.Params, "-nosound"); + SoundRender = xr_new(*this); - SoundRender->bPresent = strstr(Core.Params, "-nosound") == nullptr; - if (SoundRender->bPresent) + + if (!noSound) SoundRender->_initialize_devices_list(); - else - soundDevices.emplace_back("null", -1); + + if (!SoundRender->bPresent) + soundDevices.emplace_back(nullptr, -1); GEnv.Sound = SoundRender; } @@ -42,6 +45,11 @@ void CSoundManager::Destroy() soundDevices.clear(); } +bool CSoundManager::IsSoundEnabled() const +{ + return SoundRender && SoundRender->bPresent; +} + void CSoundManager::env_load() { string_path fn; diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index c2af6984e70..dd402e1f8da 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -265,6 +265,8 @@ class XRSOUND_API CSoundManager void Create(); void Destroy(); + bool IsSoundEnabled() const; + SoundEnvironment_LIB* get_env_library() const; void env_load(); void env_unload(); diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index ae8ee3fdedc..1f5696e915a 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -23,14 +23,21 @@ void CSoundRender_CoreA::_initialize_devices_list() if (0 == pDeviceList->GetNumDevices()) { - CHECK_OR_EXIT(0, "OpenAL: Can't create sound device."); + Log("! SOUND: OpenAL: No sound devices found."); + bPresent = false; xr_delete(pDeviceList); } + bPresent = true; } void CSoundRender_CoreA::_initialize() { - R_ASSERT2(pDeviceList, "Incorrect initialization order. Call _initialize_devices_list() first."); + if (!pDeviceList) + { + VERIFY2(pDeviceList, "Probably incorrect initialization order. Make sure to call _initialize_devices_list() first."); + bPresent = false; + return; + } pDeviceList->SelectBestDevice(); R_ASSERT(snd_device_id >= 0 && snd_device_id < pDeviceList->GetNumDevices()); @@ -38,10 +45,10 @@ void CSoundRender_CoreA::_initialize() // OpenAL device pDevice = alcOpenDevice(deviceDesc.name); - if (pDevice == nullptr) + if (!pDevice) { - CHECK_OR_EXIT(0, "SOUND: OpenAL: Failed to create device."); - bPresent = FALSE; + Log("! SOUND: OpenAL: Failed to create device."); + bPresent = false; return; } @@ -50,9 +57,9 @@ void CSoundRender_CoreA::_initialize() // Create context pContext = alcCreateContext(pDevice, nullptr); - if (nullptr == pContext) + if (!pContext) { - CHECK_OR_EXIT(0, "SOUND: OpenAL: Failed to create context."); + Log("! SOUND: OpenAL: Failed to create context."); bPresent = FALSE; alcCloseDevice(pDevice); pDevice = nullptr; From 746132a0bcd88835d8b6fe37070bb29e93407640 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 06:17:43 +0500 Subject: [PATCH 011/497] xrSound/SoundRender_Core.cpp: use this class instance directly instead of indirection through SoundRender --- src/xrSound/SoundRender_Core.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index b27564717fa..3226fb7e425 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -258,13 +258,13 @@ void CSoundRender_Core::attach_tail(ref_sound& S, pcstr fName) S._p->fn_attached[idx] = fn; - CSoundRender_Source* s = SoundRender->i_create_source(fn); + CSoundRender_Source* s = i_create_source(fn); S._p->dwBytesTotal += s->bytes_total(); S._p->fTimeTotal += s->length_sec(); if (S._feedback()) ((CSoundRender_Emitter*)S._feedback())->fTimeToStop += s->length_sec(); - SoundRender->i_destroy_source(s); + i_destroy_source(s); } void CSoundRender_Core::clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) @@ -362,7 +362,7 @@ bool CSoundRender_Core::_create_data(ref_sound_data& S, pcstr fName, esound_type xr_strcpy(fn, fName); if (strext(fn)) *strext(fn) = 0; - const bool found = SoundRender->i_create_source(S.handle, fn, replaceWithNoSound); + const bool found = i_create_source(S.handle, fn, replaceWithNoSound); const bool handleAvailable = found || replaceWithNoSound; S.g_type = game_type; if (game_type == sg_SourceType && handleAvailable) @@ -384,7 +384,7 @@ void CSoundRender_Core::_destroy_data(ref_sound_data& S) E->stop(false); } R_ASSERT(nullptr == S.feedback); - SoundRender->i_destroy_source((CSoundRender_Source*)S.handle); + i_destroy_source((CSoundRender_Source*)S.handle); S.handle = nullptr; } From 83b277d404732b01c21775a0141d8f1359378a05 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 07:27:55 +0500 Subject: [PATCH 012/497] Use ref_sound::create instead of GEnv.Sound->create --- src/xrGame/Actor.cpp | 8 ++++---- src/xrGame/Level_load.cpp | 2 +- src/xrGame/ai/crow/ai_crow.cpp | 6 +++--- src/xrGame/ai/monsters/burer/burer.cpp | 6 +++--- .../ai/monsters/controller/controller.cpp | 5 ++--- .../poltergeist/poltergeist_telekinesis.cpp | 4 ++-- .../monsters/pseudogigant/pseudo_gigant.cpp | 6 ++---- .../ai/monsters/scanning_ability_inline.h | 2 +- src/xrGame/ui/UIActorMenuInitialize.cpp | 20 +++++++++---------- src/xrUICore/Buttons/UI3tButton.cpp | 4 ++-- 10 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 389342beb54..985642a8e37 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -409,10 +409,10 @@ void CActor::Load(LPCSTR section) } } - GEnv.Sound->create(sndDie[0], strconcat(buf, *cName(), "\\die0"), st_Effect, SOUND_TYPE_MONSTER_DYING); - GEnv.Sound->create(sndDie[1], strconcat(buf, *cName(), "\\die1"), st_Effect, SOUND_TYPE_MONSTER_DYING); - GEnv.Sound->create(sndDie[2], strconcat(buf, *cName(), "\\die2"), st_Effect, SOUND_TYPE_MONSTER_DYING); - GEnv.Sound->create(sndDie[3], strconcat(buf, *cName(), "\\die3"), st_Effect, SOUND_TYPE_MONSTER_DYING); + sndDie[0].create(strconcat(buf, *cName(), "\\die0"), st_Effect, SOUND_TYPE_MONSTER_DYING); + sndDie[1].create(strconcat(buf, *cName(), "\\die1"), st_Effect, SOUND_TYPE_MONSTER_DYING); + sndDie[2].create(strconcat(buf, *cName(), "\\die2"), st_Effect, SOUND_TYPE_MONSTER_DYING); + sndDie[3].create(strconcat(buf, *cName(), "\\die3"), st_Effect, SOUND_TYPE_MONSTER_DYING); m_HeavyBreathSnd.create( pSettings->r_string(section, "heavy_breath_snd"), st_Effect, SOUND_TYPE_MONSTER_INJURING); diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index 5790e34fda1..b1c6776b38a 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -109,7 +109,7 @@ bool CLevel::Load_GameSpecific_After() for (auto I = S.Data.cbegin(); S.Data.cend() != I; ++I) { Sounds_Random.push_back(ref_sound()); - GEnv.Sound->create(Sounds_Random.back(), *I->first, st_Effect, sg_SourceType); + Sounds_Random.back().create(*I->first, st_Effect, sg_SourceType); } Sounds_Random_dwNextTime = Device.TimerAsync() + 50000; Sounds_Random_Enabled = FALSE; diff --git a/src/xrGame/ai/crow/ai_crow.cpp b/src/xrGame/ai/crow/ai_crow.cpp index ea51ad5f520..76b423b236c 100644 --- a/src/xrGame/ai/crow/ai_crow.cpp +++ b/src/xrGame/ai/crow/ai_crow.cpp @@ -59,7 +59,7 @@ void CAI_Crow::SSound::Load(LPCSTR prefix) if (FS.exist(fn, "$game_sounds$", prefix, ".ogg")) { m_Sounds.push_back(ref_sound()); - GEnv.Sound->create(m_Sounds.back(), prefix, st_Effect, sg_SourceType); + m_Sounds.back().create(prefix, st_Effect, sg_SourceType); } for (int i = 0; (i < MAX_SND_COUNT) && (m_Sounds.size() < MAX_SND_COUNT); ++i) { @@ -68,7 +68,7 @@ void CAI_Crow::SSound::Load(LPCSTR prefix) if (FS.exist(fn, "$game_sounds$", name, ".ogg")) { m_Sounds.push_back(ref_sound()); - GEnv.Sound->create(m_Sounds.back(), name, st_Effect, sg_SourceType); + m_Sounds.back().create(name, st_Effect, sg_SourceType); } } R_ASSERT(m_Sounds.size()); @@ -84,7 +84,7 @@ void CAI_Crow::SSound::SetPosition(const Fvector& pos) void CAI_Crow::SSound::Unload() { for (auto& sound : m_Sounds) - GEnv.Sound->destroy(sound); + sound.destroy(); } void cb_OnHitEndPlaying(CBlend* B) { ((CAI_Crow*)B->CallbackParam)->OnHitEndPlaying(B); } diff --git a/src/xrGame/ai/monsters/burer/burer.cpp b/src/xrGame/ai/monsters/burer/burer.cpp index fca7823baa8..bd309137829 100644 --- a/src/xrGame/ai/monsters/burer/burer.cpp +++ b/src/xrGame/ai/monsters/burer/burer.cpp @@ -88,9 +88,9 @@ void CBurer::Load(LPCSTR section) particle_gravi_prepare = pSettings->r_string(section, "Particle_Gravi_Prepare"); particle_tele_object = pSettings->r_string(section, "Particle_Tele_Object"); - GEnv.Sound->create(sound_gravi_wave, pSettings->r_string(section, "sound_gravi_wave"), st_Effect, SOUND_TYPE_WORLD); - GEnv.Sound->create(sound_tele_hold, pSettings->r_string(section, "sound_tele_hold"), st_Effect, SOUND_TYPE_WORLD); - GEnv.Sound->create(sound_tele_throw, pSettings->r_string(section, "sound_tele_throw"), st_Effect, SOUND_TYPE_WORLD); + sound_gravi_wave.create(pSettings->r_string(section, "sound_gravi_wave"), st_Effect, SOUND_TYPE_WORLD); + sound_tele_hold.create(pSettings->r_string(section, "sound_tele_hold"), st_Effect, SOUND_TYPE_WORLD); + sound_tele_throw.create(pSettings->r_string(section, "sound_tele_throw"), st_Effect, SOUND_TYPE_WORLD); m_gravi.cooldown = pSettings->r_u32(section, "Gravi_Cooldown"); m_gravi.min_dist = pSettings->r_float(section, "Gravi_MinDist"); diff --git a/src/xrGame/ai/monsters/controller/controller.cpp b/src/xrGame/ai/monsters/controller/controller.cpp index 8bf4c2d2050..8056787e296 100644 --- a/src/xrGame/ai/monsters/controller/controller.cpp +++ b/src/xrGame/ai/monsters/controller/controller.cpp @@ -82,9 +82,8 @@ void CController::Load(LPCSTR section) // anim().accel_chain_add (eAnimWalkFwd, eAnimRun); // anim().accel_chain_add (eAnimWalkDamaged, eAnimRunDamaged); - GEnv.Sound->create( - control_start_sound, pSettings->r_string(section, "sound_control_start"), st_Effect, SOUND_TYPE_WORLD); - GEnv.Sound->create(control_hit_sound, pSettings->r_string(section, "sound_control_hit"), st_Effect, SOUND_TYPE_WORLD); + control_start_sound.create(pSettings->r_string(section, "sound_control_start"), st_Effect, SOUND_TYPE_WORLD); + control_hit_sound.create(pSettings->r_string(section, "sound_control_hit"), st_Effect, SOUND_TYPE_WORLD); anim().AddReplacedAnim(&m_bDamaged, eAnimStandIdle, eAnimStandDamaged); anim().AddReplacedAnim(&m_bDamaged, eAnimRun, eAnimRunDamaged); diff --git a/src/xrGame/ai/monsters/poltergeist/poltergeist_telekinesis.cpp b/src/xrGame/ai/monsters/poltergeist/poltergeist_telekinesis.cpp index 41ea33f6b56..b5f86cdd79d 100644 --- a/src/xrGame/ai/monsters/poltergeist/poltergeist_telekinesis.cpp +++ b/src/xrGame/ai/monsters/poltergeist/poltergeist_telekinesis.cpp @@ -29,8 +29,8 @@ void CPolterTele::load(LPCSTR section) READ_IF_EXISTS(pSettings, r_u32, section, "Tele_Delay_Between_Objects_Raise_Time", 500); m_pmt_fly_velocity = READ_IF_EXISTS(pSettings, r_float, section, "Tele_Fly_Velocity", 30.f); m_pmt_object_collision_damage = READ_IF_EXISTS(pSettings, r_float, section, "Tele_Collision_Damage", 0.5f); - GEnv.Sound->create(m_sound_tele_hold, pSettings->r_string(section, "sound_tele_hold"), st_Effect, SOUND_TYPE_WORLD); - GEnv.Sound->create(m_sound_tele_throw, pSettings->r_string(section, "sound_tele_throw"), st_Effect, SOUND_TYPE_WORLD); + m_sound_tele_hold.create(pSettings->r_string(section, "sound_tele_hold"), st_Effect, SOUND_TYPE_WORLD); + m_sound_tele_throw.create(pSettings->r_string(section, "sound_tele_throw"), st_Effect, SOUND_TYPE_WORLD); m_state = eWait; m_time = 0; diff --git a/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp b/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp index 6e395abc856..8fd18d1dc3d 100644 --- a/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp +++ b/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp @@ -200,10 +200,8 @@ void CPseudoGigant::Load(LPCSTR section) // -------------------------------------------------------------------------------- - GEnv.Sound->create( - m_sound_threaten_hit, pSettings->r_string(section, "sound_threaten_hit"), st_Effect, SOUND_TYPE_WORLD); - GEnv.Sound->create(m_sound_start_threaten, pSettings->r_string(section, "sound_threaten_start"), st_Effect, - SOUND_TYPE_MONSTER_ATTACKING); + m_sound_threaten_hit.create(pSettings->r_string(section, "sound_threaten_hit"), st_Effect, SOUND_TYPE_WORLD); + m_sound_start_threaten.create(pSettings->r_string(section, "sound_threaten_start"), st_Effect, SOUND_TYPE_MONSTER_ATTACKING); m_kick_damage = pSettings->r_float(section, "HugeKick_Damage"); m_kick_particles = pSettings->r_string(section, "HugeKick_Particles"); diff --git a/src/xrGame/ai/monsters/scanning_ability_inline.h b/src/xrGame/ai/monsters/scanning_ability_inline.h index 059290ced6a..93acfda946b 100644 --- a/src/xrGame/ai/monsters/scanning_ability_inline.h +++ b/src/xrGame/ai/monsters/scanning_ability_inline.h @@ -18,7 +18,7 @@ void CScanningAbilityAbstract::on_destroy() TEMPLATE_SPECIALIZATION void CScanningAbilityAbstract::load(LPCSTR section) { - GEnv.Sound->create(sound_scan, pSettings->r_string(section, "scan_sound"), st_Effect, SOUND_TYPE_WORLD); + sound_scan.create(pSettings->r_string(section, "scan_sound"), st_Effect, SOUND_TYPE_WORLD); critical_value = pSettings->r_float(section, "scan_critical_value"); scan_radius = pSettings->r_float(section, "scan_radius"); diff --git a/src/xrGame/ui/UIActorMenuInitialize.cpp b/src/xrGame/ui/UIActorMenuInitialize.cpp index 26ee3547382..25c0617118a 100644 --- a/src/xrGame/ui/UIActorMenuInitialize.cpp +++ b/src/xrGame/ui/UIActorMenuInitialize.cpp @@ -459,16 +459,16 @@ void CUIActorMenu::InitSounds(CUIXml& uiXml) { XML_NODE stored_root = uiXml.GetLocalRoot(); uiXml.SetLocalRoot(uiXml.NavigateToNode("action_sounds", 0)); - GEnv.Sound->create(sounds[eSndOpen], uiXml.Read("snd_open", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eSndClose], uiXml.Read("snd_close", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eItemToSlot], uiXml.Read("snd_item_to_slot", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eItemToBelt], uiXml.Read("snd_item_to_belt", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eItemToRuck], uiXml.Read("snd_item_to_ruck", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eProperties], uiXml.Read("snd_properties", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eDropItem], uiXml.Read("snd_drop_item", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eAttachAddon], uiXml.Read("snd_attach_addon", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eDetachAddon], uiXml.Read("snd_detach_addon", 0, NULL), st_Effect, sg_SourceType); - GEnv.Sound->create(sounds[eItemUse], uiXml.Read("snd_item_use", 0, NULL), st_Effect, sg_SourceType); + sounds[eSndOpen].create(uiXml.Read("snd_open", 0, NULL), st_Effect, sg_SourceType); + sounds[eSndClose].create(uiXml.Read("snd_close", 0, NULL), st_Effect, sg_SourceType); + sounds[eItemToSlot].create(uiXml.Read("snd_item_to_slot", 0, NULL), st_Effect, sg_SourceType); + sounds[eItemToBelt].create(uiXml.Read("snd_item_to_belt", 0, NULL), st_Effect, sg_SourceType); + sounds[eItemToRuck].create(uiXml.Read("snd_item_to_ruck", 0, NULL), st_Effect, sg_SourceType); + sounds[eProperties].create(uiXml.Read("snd_properties", 0, NULL), st_Effect, sg_SourceType); + sounds[eDropItem].create(uiXml.Read("snd_drop_item", 0, NULL), st_Effect, sg_SourceType); + sounds[eAttachAddon].create(uiXml.Read("snd_attach_addon", 0, NULL), st_Effect, sg_SourceType); + sounds[eDetachAddon].create(uiXml.Read("snd_detach_addon", 0, NULL), st_Effect, sg_SourceType); + sounds[eItemUse].create(uiXml.Read("snd_item_use", 0, NULL), st_Effect, sg_SourceType); uiXml.SetLocalRoot(stored_root); } diff --git a/src/xrUICore/Buttons/UI3tButton.cpp b/src/xrUICore/Buttons/UI3tButton.cpp index 56474d97e5d..42f4ea6674d 100644 --- a/src/xrUICore/Buttons/UI3tButton.cpp +++ b/src/xrUICore/Buttons/UI3tButton.cpp @@ -34,8 +34,8 @@ void CUI3tButton::OnFocusReceive() PlaySoundH(); } -void CUI3tButton::InitSoundH(LPCSTR sound_file) { GEnv.Sound->create(m_sound_h, sound_file, st_Effect, sg_SourceType); } -void CUI3tButton::InitSoundT(LPCSTR sound_file) { GEnv.Sound->create(m_sound_t, sound_file, st_Effect, sg_SourceType); } +void CUI3tButton::InitSoundH(LPCSTR sound_file) { m_sound_h.create(sound_file, st_Effect, sg_SourceType); } +void CUI3tButton::InitSoundT(LPCSTR sound_file) { m_sound_t.create(sound_file, st_Effect, sg_SourceType); } void CUI3tButton::PlaySoundT() { if (m_sound_t._handle()) From 3fbf7f4500f19f07b01d7b3bcf6ff2ee89ef58d8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 07:58:04 +0500 Subject: [PATCH 013/497] Refactored ref_sound class --- src/xrEngine/IGame_Level.cpp | 13 +- src/xrEngine/IGame_Level.h | 4 +- src/xrGame/script_entity.h | 1 - src/xrGame/script_sound.cpp | 1 - src/xrGame/sound_player.cpp | 4 +- src/xrGame/sound_player_inline.h | 6 +- src/xrSound/Sound.h | 178 +++++++++++------- src/xrSound/SoundRender_Core.cpp | 146 ++++++-------- src/xrSound/SoundRender_Core.h | 15 +- src/xrSound/SoundRender_Core_Processor.cpp | 9 +- src/xrSound/SoundRender_Emitter.h | 4 +- src/xrSound/SoundRender_Emitter_StartStop.cpp | 4 +- 12 files changed, 193 insertions(+), 192 deletions(-) diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 53a81bbaf09..d075673ec2c 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -71,11 +71,6 @@ void IGame_Level::net_Stop() //------------------------------------------------------------------------------------------- // extern CStatTimer tscreate; -void _sound_event(const ref_sound_data_ptr& S, float range) -{ - if (g_pGameLevel && S && S->feedback) - g_pGameLevel->SoundEvent_Register(S, range); -} static void build_callback(Fvector* V, int Vcnt, CDB::TRI* T, int Tcnt, void* params) { @@ -121,7 +116,11 @@ bool IGame_Level::Load(u32 dwNum) g_pGamePersistent->SpatialSpacePhysic.initialize(ObjectSpace.GetBoundingVolume()); GEnv.Sound->set_geometry_occ(ObjectSpace.GetStaticModel()); - GEnv.Sound->set_handler(_sound_event); + GEnv.Sound->set_handler([](const ref_sound& S, float range) + { + if (g_pGameLevel && S && S->feedback) + g_pGameLevel->SoundEvent_Register(S, range); + }); pApp->LoadSwitch(); @@ -258,7 +257,7 @@ void IGame_Level::SetViewEntity(IGameObject* O) pCurrentViewEntity = O; } -void IGame_Level::SoundEvent_Register(ref_sound_data_ptr S, float range) +void IGame_Level::SoundEvent_Register(const ref_sound& S, float range) { if (!g_bLoaded) return; diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 00c565db531..66523e8d9ac 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -87,7 +87,7 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, struct _esound_delegate { Feel::Sound* dest; - ref_sound_data_ptr source; + ref_sound source; float power; }; xr_vector<_esound_delegate> snd_Events; @@ -129,7 +129,7 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, void SetEntity(IGameObject* O); // { pCurrentEntity=pCurrentViewEntity=O; } void SetViewEntity(IGameObject* O); // { pCurrentViewEntity=O; } - void SoundEvent_Register(ref_sound_data_ptr S, float range); + void SoundEvent_Register(const ref_sound& S, float range); void SoundEvent_Dispatch(); void SoundEvent_OnDestDestroy(Feel::Sound*); diff --git a/src/xrGame/script_entity.h b/src/xrGame/script_entity.h index ec26a703404..ee5ec299b60 100644 --- a/src/xrGame/script_entity.h +++ b/src/xrGame/script_entity.h @@ -17,7 +17,6 @@ class CScriptEntityAction; class CEntity; class CScriptGameObject; class CCustomMonster; -class ref_sound; using namespace ScriptEntity; diff --git a/src/xrGame/script_sound.cpp b/src/xrGame/script_sound.cpp index 39362cd0b76..37875e8e3f3 100644 --- a/src/xrGame/script_sound.cpp +++ b/src/xrGame/script_sound.cpp @@ -19,7 +19,6 @@ CScriptSound::CScriptSound(LPCSTR caSoundName, ESoundTypes sound_type) m_bIsNoSound = !Engine.Sound.IsSoundEnabled(); m_caSoundToPlay = caSoundName; string_path l_caFileName; - VERIFY(GEnv.Sound); if (FS.exist(l_caFileName, "$game_sounds$", caSoundName, ".ogg")) m_sound.create(caSoundName, st_Effect, sound_type); else diff --git a/src/xrGame/sound_player.cpp b/src/xrGame/sound_player.cpp index 4a745d5a325..ea6a228ec31 100644 --- a/src/xrGame/sound_player.cpp +++ b/src/xrGame/sound_player.cpp @@ -199,8 +199,8 @@ void CSoundPlayer::play( **/ sound_single.m_sound->clone((*I).second.second->random(id), st_Effect, sg_SourceType); - sound_single.m_sound->_p->g_object = m_object; - sound_single.m_sound->_p->g_userdata = (*I).second.first.m_data; + sound_single.m_sound->_get()->g_object = m_object; + sound_single.m_sound->_get()->g_userdata = (*I).second.first.m_data; VERIFY(sound_single.m_sound->_handle()); VERIFY(max_start_time >= min_start_time); diff --git a/src/xrGame/sound_player_inline.h b/src/xrGame/sound_player_inline.h index e10ac9f8f91..a61ded956ab 100644 --- a/src/xrGame/sound_player_inline.h +++ b/src/xrGame/sound_player_inline.h @@ -46,12 +46,12 @@ IC ref_sound* CSoundPlayer::CSoundCollection::add(ESoundTypes type, LPCSTR name) { ref_sound* temp = xr_new(); temp->create(name, st_Effect, type); - if (!temp->_p) + if (!temp) { xr_delete(temp); - return (0); + return nullptr; } - return (temp); + return temp; } IC const CSoundPlayer::SOUND_COLLECTIONS& CSoundPlayer::objects() const { return (m_sounds); } diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index dd402e1f8da..d12dce13361 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -22,8 +22,8 @@ constexpr pcstr SNDENV_FILENAME = "sEnvironment.xr"; // refs class IGameObject; -class ref_sound; -class ref_sound_data; +class CSound; +struct resptrcode_sound; class XRSOUND_API CSound_params; class XRSOUND_API CSound_source; class XRSOUND_API CSound_emitter; @@ -190,10 +190,10 @@ class XRSOUND_API CSound_stats u32 _events; }; -typedef resptr_core> ref_sound_data_ptr; +using ref_sound = resptr_core; /// definition (Sound Callback) -typedef void sound_event(const ref_sound_data_ptr& S, float range); +typedef void sound_event(const ref_sound& S, float range); namespace CDB { @@ -204,9 +204,18 @@ namespace CDB class XRSOUND_API XR_NOVTABLE ISoundManager { protected: - friend class ref_sound_data; - virtual bool _create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; - virtual void _destroy_data(ref_sound_data& S) = 0; + friend class CSound; + friend struct resptrcode_sound; + + virtual CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; + virtual void destroy(CSound& S) = 0; + + virtual void attach_tail(CSound& S, pcstr fName) = 0; + + virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, + float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; public: virtual ~ISoundManager() = default; @@ -214,21 +223,11 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void _restart() = 0; virtual bool i_locked() = 0; - virtual bool create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; - virtual void attach_tail(ref_sound& S, pcstr fName) = 0; - virtual void clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) = 0; - virtual void destroy(ref_sound& S) = 0; - virtual void prefetch() = 0; virtual void stop_emitters() = 0; virtual int pause_emitters(bool val) = 0; - virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, - float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; - virtual void set_master_volume(float f = 1.f) = 0; virtual void set_geometry_env(IReader* I) = 0; virtual void set_geometry_som(IReader* I) = 0; @@ -284,36 +283,27 @@ class CSound_UserData : public xr_resource using CSound_UserDataPtr = resptr_core>; -class ref_sound_data : public xr_resource +class CSound : public xr_resource { public: //shared_str nm; - CSound_source* handle; //!< Pointer to wave-source interface - CSound_emitter* feedback; //!< Pointer to emitter, automatically clears on emitter-stop - esound_type s_type; - int g_type; //!< Sound type, usually for AI - IGameObject* g_object; //!< Game object that emits ref_sound - CSound_UserDataPtr g_userdata; - shared_str fn_attached[2]; + CSound_source* handle{}; //!< Pointer to wave-source interface + CSound_emitter* feedback{}; //!< Pointer to emitter, automatically clears on emitter-stop - u32 dwBytesTotal; - float fTimeTotal; + esound_type s_type{ st_Effect }; + int g_type{}; //!< Sound type, usually for AI - ref_sound_data() noexcept - : handle(0), feedback(0), s_type(st_Effect), g_type(0), g_object(0), dwBytesTotal(0), fTimeTotal(0) - { - } + IGameObject* g_object{}; //!< Game object that emits ref_sound + CSound_UserDataPtr g_userdata{}; + shared_str fn_attached[2]; - ref_sound_data(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) - { - GEnv.Sound->_create_data(*this, fName, sound_type, game_type, replaceWithNoSound); - } + u32 dwBytesTotal{}; + float fTimeTotal{}; - virtual ~ref_sound_data() { GEnv.Sound->_destroy_data(*this); } + ~CSound() override { GEnv.Sound->destroy(*this); } float get_length_sec() const { return fTimeTotal; } }; -inline void VerSndUnlocked() { VERIFY(!GEnv.Sound->i_locked()); } /*! \class ref_sound \brief Sound source + control @@ -321,63 +311,101 @@ The main class representing source/emitter interface This class in fact just hides internals and redirect calls to specific sub-systems */ -class ref_sound +struct resptrcode_sound : public resptr_base { -public: - ref_sound_data_ptr _p; + [[nodiscard]] + ICF CSound_source* _handle() const { return p_ ? p_->handle : nullptr; } + + [[nodiscard]] + ICF CSound_emitter* _feedback() const { return p_ ? p_->feedback : nullptr; } + + [[nodiscard]] + ICF IGameObject* _g_object() const { VERIFY(p_); return p_ ? p_->g_object : nullptr; } - ref_sound() = default; - ~ref_sound() = default; + [[nodiscard]] + ICF int _g_type() const { VERIFY(p_); return p_ ? p_->g_type : 0; } + + [[nodiscard]] + ICF esound_type _sound_type() const { VERIFY(p_); return p_ ? p_->s_type : st_Effect; } + + [[nodiscard]] + ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; } - CSound_source* _handle() const { return _p ? _p->handle : nullptr; } - CSound_emitter* _feedback() const { return _p ? _p->feedback : nullptr; } - IGameObject* _g_object() { VERIFY(_p); return _p->g_object; } - int _g_type() { VERIFY(_p); return _p->g_type; } - esound_type _sound_type() { VERIFY(_p); return _p->s_type; } - CSound_UserDataPtr _g_userdata() { VERIFY(_p); return _p->g_userdata; } bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) - { VerSndUnlocked(); return GEnv.Sound->create(*this, name, sound_type, game_type, replaceWithNoSound); } + { + VerSndUnlocked(); + _set(GEnv.Sound->create(name, sound_type, game_type, replaceWithNoSound)); + return _get(); + } - void attach_tail(pcstr name) - { VerSndUnlocked(); GEnv.Sound->attach_tail(*this, name); } + ICF void destroy() + { + VerSndUnlocked(); + _set(nullptr); + } - void clone(const ref_sound& from, esound_type sound_type, int game_type) - { VerSndUnlocked(); GEnv.Sound->clone(*this, from, sound_type, game_type); } + void attach_tail(pcstr name) const + { + VerSndUnlocked(); + if (!p_) + return; + GEnv.Sound->attach_tail(*p_, name); + } - void destroy() - { VerSndUnlocked(); GEnv.Sound->destroy(*this); } + void clone(const ref_sound& from, esound_type sound_type, int game_type) + { + if (!from._get()) + return; + _set(xr_new()); + p_->handle = from->handle; + p_->dwBytesTotal = from->dwBytesTotal; + p_->fTimeTotal = from->fTimeTotal; + p_->fn_attached[0] = from->fn_attached[0]; + p_->fn_attached[1] = from->fn_attached[1]; + p_->g_type = (game_type == sg_SourceType) ? p_->handle->game_type() : game_type; + p_->s_type = sound_type; + } void play(IGameObject* O, u32 flags = 0, float delay = 0.f) - { VerSndUnlocked(); GEnv.Sound->play(*this, O, flags, delay); } + { + VerSndUnlocked(); + GEnv.Sound->play(static_cast(*this), O, flags, delay); + } void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) - { VerSndUnlocked(); GEnv.Sound->play_at_pos(*this, O, pos, flags, delay); } + { + VerSndUnlocked(); + GEnv.Sound->play_at_pos(static_cast(*this), O, pos, flags, delay); + } void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) - { VerSndUnlocked(); GEnv.Sound->play_no_feedback(*this, O, flags, delay, pos, vol, freq, range); } + { + VerSndUnlocked(); + GEnv.Sound->play_no_feedback(static_cast(*this), O, flags, delay, pos, vol, freq, range); + } - void stop() { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); } - void stop_deferred() { VerSndUnlocked(); if (_feedback()) _feedback()->stop(true ); } + ICF void stop() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); } + ICF void stop_deferred() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(true ); } - void set_position(const Fvector& pos) { VerSndUnlocked(); if (_feedback()) _feedback()->set_position(pos); } - void set_frequency(float freq) { VerSndUnlocked(); if (_feedback()) _feedback()->set_frequency(freq); } - void set_range(float min, float max) { VerSndUnlocked(); if (_feedback()) _feedback()->set_range(min, max); } - void set_volume(float vol) { VerSndUnlocked(); if (_feedback()) _feedback()->set_volume(vol); } - void set_priority(float p) { VerSndUnlocked(); if (_feedback()) _feedback()->set_priority(p); } - void set_time(float t) { VerSndUnlocked(); if (_feedback()) _feedback()->set_time(t); }; //--#SM+#-- + ICF void set_position(const Fvector& pos) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_position(pos); } + ICF void set_frequency(float freq) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_frequency(freq); } + ICF void set_range(float min, float max) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_range(min, max); } + ICF void set_volume(float vol) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_volume(vol); } + ICF void set_priority(float p) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_priority(p); } + ICF void set_time(float t) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_time(t); }; //--#SM+#-- - const CSound_params* get_params() + [[nodiscard]] + ICF const CSound_params* get_params() const { VerSndUnlocked(); - return _feedback() ? _feedback()->get_params() : 0; + return _feedback() ? _feedback()->get_params() : nullptr; } - void set_params(CSound_params* p) + void set_params(CSound_params* p) const { VerSndUnlocked(); - CSound_emitter* const feedback = _feedback(); - if (feedback) + if (CSound_emitter* const feedback = _feedback()) { feedback->set_position(p->position); feedback->set_frequency(p->freq); @@ -386,7 +414,13 @@ class ref_sound } } - float get_length_sec() const { return _p ? _p->get_length_sec() : 0.0f; } + [[nodiscard]] + ICF float get_length_sec() const { return p_ ? p_->get_length_sec() : 0.0f; } + + IC static void VerSndUnlocked() + { + VERIFY(!GEnv.Sound->i_locked()); + } }; class XRSOUND_API CSound_stats_ext diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 3226fb7e425..cf0a5771a99 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -225,20 +225,40 @@ void CSoundRender_Core::set_geometry_env(IReader* I) xr_free(_data); } -bool CSoundRender_Core::create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) +CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) { if (!bPresent) - return S._handle() != nullptr; + return nullptr; - S._p = xr_new(fName, sound_type, game_type, replaceWithNoSound); + CSound_source* handle{}; - if (S._handle() == nullptr && !replaceWithNoSound) - S._p = nullptr; // no reason to keep it + string_path fn; + xr_strcpy(fn, fName); + if (strext(fn)) + *strext(fn) = 0; + const bool found = i_create_source(handle, fn, replaceWithNoSound); + const bool handleAvailable = found || replaceWithNoSound; + + if (!handleAvailable) + return nullptr; + + auto* snd = xr_new(); + + snd->handle = handle; + + snd->g_type = game_type; + if (game_type == sg_SourceType && handleAvailable) + snd->g_type = snd->handle->game_type(); + + snd->s_type = sound_type; + + snd->dwBytesTotal = handleAvailable ? snd->handle->bytes_total() : 0; + snd->fTimeTotal = handleAvailable ? snd->handle->length_sec() : 0.f; - return S._handle() != nullptr; + return snd; } -void CSoundRender_Core::attach_tail(ref_sound& S, pcstr fName) +void CSoundRender_Core::attach_tail(CSound& snd, pcstr fName) { if (!bPresent) return; @@ -246,50 +266,36 @@ void CSoundRender_Core::attach_tail(ref_sound& S, pcstr fName) xr_strcpy(fn, fName); if (strext(fn)) *strext(fn) = 0; - if (S._p->fn_attached[0].size() && S._p->fn_attached[1].size()) + if (!snd.fn_attached[0].empty() && !snd.fn_attached[1].empty()) { -#ifdef DEBUG - Msg("! 2 file already in queue [%s][%s]", S._p->fn_attached[0].c_str(), S._p->fn_attached[1].c_str()); -#endif // #ifdef DEBUG +#ifndef MASTER_GOLD + Msg("! 2 file already in queue [%s][%s]", snd.fn_attached[0].c_str(), snd.fn_attached[1].c_str()); +#endif return; } - u32 idx = S._p->fn_attached[0].size() ? 1 : 0; + const u32 idx = snd.fn_attached[0].empty() ? 0 : 1; - S._p->fn_attached[idx] = fn; + snd.fn_attached[idx] = fn; CSoundRender_Source* s = i_create_source(fn); - S._p->dwBytesTotal += s->bytes_total(); - S._p->fTimeTotal += s->length_sec(); - if (S._feedback()) - ((CSoundRender_Emitter*)S._feedback())->fTimeToStop += s->length_sec(); + snd.dwBytesTotal += s->bytes_total(); + snd.fTimeTotal += s->length_sec(); + if (snd.feedback) + ((CSoundRender_Emitter*)snd.feedback)->fTimeToStop += s->length_sec(); i_destroy_source(s); } -void CSoundRender_Core::clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) -{ - if (!bPresent) - return; - S._p = xr_new(); - S._p->handle = from._p->handle; - S._p->dwBytesTotal = from._p->dwBytesTotal; - S._p->fTimeTotal = from._p->fTimeTotal; - S._p->fn_attached[0] = from._p->fn_attached[0]; - S._p->fn_attached[1] = from._p->fn_attached[1]; - S._p->g_type = (game_type == sg_SourceType) ? S._p->handle->game_type() : game_type; - S._p->s_type = sound_type; -} - void CSoundRender_Core::play(ref_sound& S, IGameObject* O, u32 flags, float delay) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - S._p->g_object = O; + S->g_object = O; if (S._feedback()) ((CSoundRender_Emitter*)S._feedback())->rewind(); else - i_play(&S, flags, delay); + i_play(S, flags, delay); if (flags & sm_2D || S._handle()->channels_num() == 2) S._feedback()->switch_to_2D(); @@ -300,19 +306,19 @@ void CSoundRender_Core::play(ref_sound& S, IGameObject* O, u32 flags, float dela void CSoundRender_Core::play_no_feedback( ref_sound& S, IGameObject* O, u32 flags, float delay, Fvector* pos, float* vol, float* freq, Fvector2* range) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - ref_sound_data_ptr orig = S._p; - S._p = xr_new(); - S._p->handle = orig->handle; - S._p->g_type = orig->g_type; - S._p->g_object = O; - S._p->dwBytesTotal = orig->dwBytesTotal; - S._p->fTimeTotal = orig->fTimeTotal; - S._p->fn_attached[0] = orig->fn_attached[0]; - S._p->fn_attached[1] = orig->fn_attached[1]; - - i_play(&S, flags, delay); + const ref_sound orig = S; + S._set(xr_new()); + S->handle = orig->handle; + S->g_type = orig->g_type; + S->g_object = O; + S->dwBytesTotal = orig->dwBytesTotal; + S->fTimeTotal = orig->fTimeTotal; + S->fn_attached[0] = orig->fn_attached[0]; + S->fn_attached[1] = orig->fn_attached[1]; + + i_play(S, flags, delay); if (flags & sm_2D || S._handle()->channels_num() == 2) S._feedback()->switch_to_2D(); @@ -325,18 +331,18 @@ void CSoundRender_Core::play_no_feedback( S._feedback()->set_range((*range)[0], (*range)[1]); if (vol) S._feedback()->set_volume(*vol); - S._p = orig; + S = orig; } void CSoundRender_Core::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags, float delay) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - S._p->g_object = O; + S->g_object = O; if (S._feedback()) ((CSoundRender_Emitter*)S._feedback())->rewind(); else - i_play(&S, flags, delay); + i_play(S, flags, delay); S._feedback()->set_position(pos); @@ -346,46 +352,14 @@ void CSoundRender_Core::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); } -void CSoundRender_Core::destroy(ref_sound& S) +void CSoundRender_Core::destroy(CSound& S) { - if (S._feedback()) + if (auto* emitter = (CSoundRender_Emitter*)S.feedback) { - CSoundRender_Emitter* E = (CSoundRender_Emitter*)S._feedback(); - E->stop(false); + emitter->stop(false); + VERIFY(S.feedback == nullptr); } - S._p = nullptr; -} - -bool CSoundRender_Core::_create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) -{ - string_path fn; - xr_strcpy(fn, fName); - if (strext(fn)) - *strext(fn) = 0; - const bool found = i_create_source(S.handle, fn, replaceWithNoSound); - const bool handleAvailable = found || replaceWithNoSound; - S.g_type = game_type; - if (game_type == sg_SourceType && handleAvailable) - S.g_type = S.handle->game_type(); - S.s_type = sound_type; - S.feedback = nullptr; - S.g_object = nullptr; - S.g_userdata = nullptr; - S.dwBytesTotal = handleAvailable ? S.handle->bytes_total() : 0; - S.fTimeTotal = handleAvailable ? S.handle->length_sec() : 0.f; - return found; -} - -void CSoundRender_Core::_destroy_data(ref_sound_data& S) -{ - if (S.feedback) - { - CSoundRender_Emitter* E = (CSoundRender_Emitter*)S.feedback; - E->stop(false); - } - R_ASSERT(nullptr == S.feedback); i_destroy_source((CSoundRender_Source*)S.handle); - S.handle = nullptr; } diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index b1a394514ce..2762b3290e6 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -22,9 +22,6 @@ class CSoundRender_Core : public ISoundManager volatile bool isLocked; protected: - bool _create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; - void _destroy_data(ref_sound_data& S) override; - bool bListenerMoved; CSoundRender_Environment e_current; @@ -34,7 +31,7 @@ class CSoundRender_Core : public ISoundManager public: CSoundManager& Parent; - using event = std::pair; + using event = std::pair; xr_vector s_events; bool bPresent; @@ -89,11 +86,10 @@ class CSoundRender_Core : public ISoundManager // Sound interface void verify_refsound(ref_sound& S); - bool create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; - void attach_tail(ref_sound& S, pcstr fName) override; + CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; + void attach_tail(CSound& S, pcstr fName) override; - void clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) override; - void destroy(ref_sound& S) override; + void destroy(CSound& S) override; void prefetch() override { @@ -109,6 +105,7 @@ class CSoundRender_Core : public ISoundManager void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) override; void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) override; + void set_master_volume(float f) override = 0; void set_geometry_env(IReader* I) override; void set_geometry_som(IReader* I) override; @@ -137,7 +134,7 @@ class CSoundRender_Core : public ISoundManager void i_create_all_sources(); void i_destroy_source(CSoundRender_Source* S); - CSoundRender_Emitter* i_play(ref_sound* S, u32 flags, float delay); + CSoundRender_Emitter* i_play(const ref_sound& S, u32 flags, float delay); void i_start(CSoundRender_Emitter* E); void i_stop(CSoundRender_Emitter* E); void i_rewind(CSoundRender_Emitter* E); diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 0dd688187a1..3f6f5eedea6 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -9,13 +9,12 @@ #include "SoundRender_Target.h" #include "SoundRender_Source.h" -CSoundRender_Emitter* CSoundRender_Core::i_play(ref_sound* S, u32 flags, float delay) +CSoundRender_Emitter* CSoundRender_Core::i_play(const ref_sound& S, u32 flags, float delay) { - VERIFY(S->_p->feedback == 0); - CSoundRender_Emitter* E = xr_new(); - S->_p->feedback = E; + VERIFY(S._get()->feedback == nullptr); + CSoundRender_Emitter* E = s_emitters.emplace_back(xr_new()); + S._get()->feedback = E; E->start(S, flags, delay); - s_emitters.push_back(E); return E; } diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 938066b9b57..001e2d19b20 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -34,7 +34,7 @@ class CSoundRender_Emitter final : public CSound_emitter static constexpr float TIME_TO_STOP_INFINITE = static_cast(0xffffffff); CSoundRender_Target* target; - ref_sound_data_ptr owner_data; + ref_sound owner_data; [[nodiscard]] CSoundRender_Source* source() const { return (CSoundRender_Source*)owner_data->handle; } @@ -108,7 +108,7 @@ class CSoundRender_Emitter final : public CSound_emitter void fill_data(u8* ptr, u32 offset, u32 size); float priority(); - void start(ref_sound* _owner, u32 flags, float delay); + void start(const ref_sound& _owner, u32 flags, float delay); void cancel(); // manager forces out of rendering void update(float time, float dt); bool update_culling(float dt); diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index a32f26c40ef..f61ed499831 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -5,14 +5,14 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -void CSoundRender_Emitter::start(ref_sound* _owner, u32 flags, float delay) +void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay) { const bool _loop = flags & sm_Looped; bIgnoringTimeFactor = flags & sm_IgnoreTimeFactor; starting_delay = delay; VERIFY(_owner); - owner_data = _owner->_p; + owner_data = _owner; VERIFY(owner_data); // source = (CSoundRender_Source*)owner_data->handle; p_source.position.set(0, 0, 0); From dfa50c2ba16e00878b3065d09bd82d483950efad Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 13:10:31 +0500 Subject: [PATCH 014/497] Introduce Sound Scene --- src/xrEngine/IGame_Level.cpp | 14 +- src/xrEngine/IGame_Level.h | 2 + src/xrEngine/IGame_Persistent.cpp | 6 + src/xrEngine/IGame_Persistent.h | 1 + src/xrEngine/xr_object_list.cpp | 2 +- src/xrGame/Level_load.cpp | 4 +- src/xrGame/level_sounds.cpp | 2 +- src/xrSound/Sound.cpp | 2 + src/xrSound/Sound.h | 71 +++- src/xrSound/SoundRender_Core.cpp | 323 ++-------------- src/xrSound/SoundRender_Core.h | 56 +-- src/xrSound/SoundRender_Core_Processor.cpp | 252 ++++-------- src/xrSound/SoundRender_Emitter.cpp | 32 +- src/xrSound/SoundRender_Emitter.h | 11 +- src/xrSound/SoundRender_Emitter_FSM.cpp | 39 +- src/xrSound/SoundRender_Scene.cpp | 421 +++++++++++++++++++++ src/xrSound/SoundRender_Scene.h | 66 ++++ src/xrSound/SoundRender_Target.h | 4 +- src/xrSound/xrSound.vcxproj | 2 + src/xrSound/xrSound.vcxproj.filters | 9 + src/xrUICore/CMakeLists.txt | 1 + src/xrUICore/xrUICore.vcxproj | 3 + 22 files changed, 733 insertions(+), 590 deletions(-) create mode 100644 src/xrSound/SoundRender_Scene.cpp create mode 100644 src/xrSound/SoundRender_Scene.h diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index d075673ec2c..b0f99fc3d3b 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -25,6 +25,8 @@ IGame_Level::IGame_Level() bReady = false; pCurrentEntity = NULL; pCurrentViewEntity = NULL; + Sound = GEnv.Sound->create_scene(); + DefaultSoundScene = Sound; #ifndef MASTER_GOLD GEnv.Render->ResourcesDumpMemoryUsage(); #endif @@ -44,8 +46,8 @@ IGame_Level::~IGame_Level() Device.seqFrame.Remove(this); CCameraManager::ResetPP(); /////////////////////////////////////////// - GEnv.Sound->set_geometry_occ(nullptr); - GEnv.Sound->set_handler(nullptr); + DefaultSoundScene = g_pGamePersistent->m_pSound; + GEnv.Sound->destroy_scene(Sound); #ifndef MASTER_GOLD GEnv.Render->ResourcesDumpMemoryUsage(); #endif @@ -115,8 +117,8 @@ bool IGame_Level::Load(u32 dwNum) g_pGamePersistent->SpatialSpace.initialize(ObjectSpace.GetBoundingVolume()); g_pGamePersistent->SpatialSpacePhysic.initialize(ObjectSpace.GetBoundingVolume()); - GEnv.Sound->set_geometry_occ(ObjectSpace.GetStaticModel()); - GEnv.Sound->set_handler([](const ref_sound& S, float range) + Sound->set_geometry_occ(ObjectSpace.GetStaticModel()); + Sound->set_handler([](const ref_sound& S, float range) { if (g_pGameLevel && S && S->feedback) g_pGameLevel->SoundEvent_Register(S, range); @@ -303,7 +305,7 @@ void IGame_Level::SoundEvent_Register(const ref_sound& S, float range) // Energy and signal VERIFY(_valid(it->GetSpatialData().sphere.P)); - float dist = snd_position.distance_to(it->GetSpatialData().sphere.P); + const float dist = snd_position.distance_to(it->GetSpatialData().sphere.P); if (dist > p->max_ai_distance) continue; VERIFY(_valid(dist)); @@ -312,7 +314,7 @@ void IGame_Level::SoundEvent_Register(const ref_sound& S, float range) VERIFY(_valid(Power)); if (Power > EPS_S) { - float occ = GEnv.Sound->get_occlusion_to(it->GetSpatialData().sphere.P, snd_position); + const float occ = Sound->get_occlusion_to(it->GetSpatialData().sphere.P, snd_position); VERIFY(_valid(occ)); Power *= occ; if (Power > EPS_S) diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 66523e8d9ac..6de9655221a 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -75,6 +75,8 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, xr_vector snd_ER; public: + ISoundScene* Sound{}; + CObjectList Objects; CObjectSpace ObjectSpace; CCameraManager& Cameras() { return *m_pCameras; }; diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 9ddb6937b9f..89f9f6e47da 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -44,10 +44,16 @@ IGame_Persistent::IGame_Persistent() pEnvironment = xr_new(); m_pGShaderConstants = xr_new(); //--#SM+#-- + + m_pSound = GEnv.Sound->create_scene(); + DefaultSoundScene = m_pSound; } IGame_Persistent::~IGame_Persistent() { + GEnv.Sound->destroy_scene(m_pSound); + DefaultSoundScene = nullptr; + xr_delete(PerlinNoise1D); Device.seqFrame.Remove(this); Device.seqAppStart.Remove(this); diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index d8a4fb97616..16977d95b7b 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -147,6 +147,7 @@ class ENGINE_API IGame_Persistent : CEnvironment& Environment() { return *pEnvironment; }; void Prefetch(); #endif + ISoundScene* m_pSound{}; IMainMenu* m_pMainMenu{}; static bool IsMainMenuActive(); static bool MainMenuActiveOrLevelNotExist(); diff --git a/src/xrEngine/xr_object_list.cpp b/src/xrEngine/xr_object_list.cpp index 4be4216e140..aacfa149cff 100644 --- a/src/xrEngine/xr_object_list.cpp +++ b/src/xrEngine/xr_object_list.cpp @@ -311,7 +311,7 @@ void CObjectList::Update(bool bForce) (*oit)->net_Relcase(destroy_queue[it]); for (int it = destroy_queue.size() - 1; it >= 0; it--) - GEnv.Sound->object_relcase(destroy_queue[it]); + g_pGameLevel->Sound->object_relcase(destroy_queue[it]); RELCASE_CALLBACK_VEC::iterator it = m_relcase_callbacks.begin(); const RELCASE_CALLBACK_VEC::iterator ite = m_relcase_callbacks.end(); diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index b1c6776b38a..b2b7c8cf44e 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -90,14 +90,14 @@ bool CLevel::Load_GameSpecific_After() if (FS.exist(fn_game, "$level$", "level.snd_env")) { IReader* F = FS.r_open(fn_game); - GEnv.Sound->set_geometry_env(F); + Sound->set_geometry_env(F); FS.r_close(F); } // loading SOM if (FS.exist(fn_game, "$level$", "level.som")) { IReader* F = FS.r_open(fn_game); - GEnv.Sound->set_geometry_som(F); + Sound->set_geometry_som(F); FS.r_close(F); } diff --git a/src/xrGame/level_sounds.cpp b/src/xrGame/level_sounds.cpp index 017dfcacfcb..68fcd0ebd78 100644 --- a/src/xrGame/level_sounds.cpp +++ b/src/xrGame/level_sounds.cpp @@ -34,7 +34,7 @@ void SStaticSound::Update(u32 game_time, u32 global_time) if (0 == m_Source._feedback()) { Fvector occ[3]; - const float occluder_volume = GEnv.Sound->get_occlusion(m_Position, .2f, occ); + const float occluder_volume = g_pGameLevel->Sound->get_occlusion(m_Position, .2f, occ); const float vol = m_Volume * occluder_volume; if ((0 == m_PauseTime.x) && (0 == m_PauseTime.y)) diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index 3a1539eb0a9..f26d697a69e 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -4,6 +4,8 @@ XRSOUND_API u32 snd_device_id = u32(-1); +ISoundScene* DefaultSoundScene{}; + void CSoundManager::CreateDevicesList() { static bool noSound = strstr(Core.Params, "-nosound"); diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index d12dce13361..2a7271246f1 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -24,6 +24,7 @@ constexpr pcstr SNDENV_FILENAME = "sEnvironment.xr"; class IGameObject; class CSound; struct resptrcode_sound; +class ISoundScene; class XRSOUND_API CSound_params; class XRSOUND_API CSound_source; class XRSOUND_API CSound_emitter; @@ -52,6 +53,8 @@ XRSOUND_API extern int psSoundCacheSizeMB; XRSOUND_API extern u32 psSoundPrecacheAll; XRSOUND_API extern u32 snd_device_id; +XRSOUND_API extern ISoundScene* DefaultSoundScene; + // Flags enum : u32 { @@ -200,6 +203,40 @@ namespace CDB class MODEL; } +class XRSOUND_API XR_NOVTABLE ISoundScene +{ +protected: + friend struct resptrcode_sound; + +public: + virtual ~ISoundScene() = 0; + + virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, + float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; + + virtual void stop_emitters() const = 0; + virtual int pause_emitters(bool pauseState) = 0; + + virtual void set_handler(sound_event* E) = 0; + virtual void set_geometry_env(IReader* I) = 0; + virtual void set_geometry_som(IReader* I) = 0; + virtual void set_geometry_occ(CDB::MODEL* M) = 0; + + virtual void set_user_env(CSound_environment* E) = 0; + virtual void set_environment(u32 id, CSound_environment** dst_env) = 0; + virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) = 0; + virtual CSound_environment* get_environment(const Fvector& P) = 0; + + virtual float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) = 0; + virtual float get_occlusion(Fvector& P, float R, Fvector* occ) = 0; + + virtual void object_relcase(IGameObject* obj) = 0; +}; + +inline ISoundScene::~ISoundScene() = default; + /// definition (Sound Manager Interface) class XRSOUND_API XR_NOVTABLE ISoundManager { @@ -212,43 +249,30 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void attach_tail(CSound& S, pcstr fName) = 0; - virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, - float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; - public: virtual ~ISoundManager() = default; + virtual ISoundScene* create_scene() = 0; + virtual void destroy_scene(ISoundScene*&) = 0; + virtual void _restart() = 0; virtual bool i_locked() = 0; virtual void prefetch() = 0; virtual void stop_emitters() = 0; - virtual int pause_emitters(bool val) = 0; + virtual int pause_emitters(bool pauseState) = 0; virtual void set_master_volume(float f = 1.f) = 0; - virtual void set_geometry_env(IReader* I) = 0; - virtual void set_geometry_som(IReader* I) = 0; - virtual void set_geometry_occ(CDB::MODEL* M) = 0; - virtual void set_handler(sound_event* E) = 0; virtual void update(const Fvector& P, const Fvector& D, const Fvector& N) = 0; virtual void statistic(CSound_stats* s0, CSound_stats_ext* s1) = 0; virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) = 0; - virtual float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) = 0; - virtual float get_occlusion(Fvector& P, float R, Fvector* occ) = 0; - - virtual void object_relcase(IGameObject* obj) = 0; virtual const Fvector& listener_position() = 0; virtual void refresh_env_library() = 0; - virtual void set_user_env(CSound_environment* E) = 0; virtual void refresh_sources() = 0; - virtual void set_environment(u32 id, CSound_environment** dst_env) = 0; - virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) = 0; }; class XRSOUND_API CSoundManager @@ -331,7 +355,6 @@ struct resptrcode_sound : public resptr_base [[nodiscard]] ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; } - bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) { VerSndUnlocked(); @@ -369,20 +392,26 @@ struct resptrcode_sound : public resptr_base void play(IGameObject* O, u32 flags = 0, float delay = 0.f) { + if (!p_ || !DefaultSoundScene) + return; VerSndUnlocked(); - GEnv.Sound->play(static_cast(*this), O, flags, delay); + DefaultSoundScene->play(static_cast(*this), O, flags, delay); } void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) { + if (!p_ || !DefaultSoundScene) + return; VerSndUnlocked(); - GEnv.Sound->play_at_pos(static_cast(*this), O, pos, flags, delay); + DefaultSoundScene->play_at_pos(static_cast(*this), O, pos, flags, delay); } void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) { + if (!p_ || !DefaultSoundScene) + return; VerSndUnlocked(); - GEnv.Sound->play_no_feedback(static_cast(*this), O, flags, delay, pos, vol, freq, range); + DefaultSoundScene->play_no_feedback(static_cast(*this), O, flags, delay, pos, vol, freq, range); } ICF void stop() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); } diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index cf0a5771a99..910363d4a78 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -38,11 +38,6 @@ CSoundRender_Core::CSoundRender_Core(CSoundManager& p) : Parent(p) { bPresent = false; - bUserEnvironment = false; - geom_MODEL = nullptr; - geom_ENV = nullptr; - geom_SOM = nullptr; - Handler = nullptr; s_targets_pu = 0; s_emitters_u = 0; e_current.set_identity(); @@ -54,13 +49,6 @@ CSoundRender_Core::CSoundRender_Core(CSoundManager& p) fTimer_Delta = 0.0f; fTimerPersistent_Value = TimerPersistent.GetElapsed_sec(); fTimerPersistent_Delta = 0.0f; - m_iPauseCounter = 1; -} - -CSoundRender_Core::~CSoundRender_Core() -{ - xr_delete(geom_ENV); - xr_delete(geom_SOM); } void CSoundRender_Core::_initialize() @@ -91,138 +79,39 @@ void CSoundRender_Core::_clear() } s_sources.clear(); - // remove emitters - for (auto& emit : s_emitters) - xr_delete(emit); - s_emitters.clear(); - g_target_temp_data.clear(); } -void CSoundRender_Core::stop_emitters() +ISoundScene* CSoundRender_Core::create_scene() { - for (auto& emit : s_emitters) - emit->stop(false); + return m_scenes.emplace_back(xr_new()); } -int CSoundRender_Core::pause_emitters(bool val) +void CSoundRender_Core::destroy_scene(ISoundScene*& sound_scene) { - m_iPauseCounter += val ? +1 : -1; - VERIFY(m_iPauseCounter >= 0); - - for (auto& emit : s_emitters) - static_cast(emit)->pause(val, val ? m_iPauseCounter : m_iPauseCounter + 1); - - return m_iPauseCounter; + m_scenes.erase(std::remove(m_scenes.begin(), m_scenes.end(), sound_scene), m_scenes.end()); + xr_delete(sound_scene); } -void CSoundRender_Core::_restart() +void CSoundRender_Core::stop_emitters() { - cache.destroy(); - cache.initialize(psSoundCacheSizeMB * 1024, cache_bytes_per_line); - env_apply(); + for (const auto& scene : m_scenes) + scene->stop_emitters(); } -void CSoundRender_Core::set_handler(sound_event* E) { Handler = E; } -void CSoundRender_Core::set_geometry_occ(CDB::MODEL* M) { geom_MODEL = M; } - -void CSoundRender_Core::set_geometry_som(IReader* I) +int CSoundRender_Core::pause_emitters(bool pauseState) { - xr_delete(geom_SOM); - if (nullptr == I) - return; - - // check version - R_ASSERT(I->find_chunk(0)); - [[maybe_unused]] u32 version = I->r_u32(); - VERIFY2(version == 0, "Invalid SOM version"); - - struct SOM_poly - { - Fvector3 v1; - Fvector3 v2; - Fvector3 v3; - u32 b2sided; - float occ; - }; - - CDB::Collector CL; - { - // load geometry - IReader* geom = I->open_chunk(1); - VERIFY2(geom, "Corrupted SOM file"); - if (!geom) - return; - - // Load tris and merge them - const auto begin = static_cast(geom->pointer()); - const auto end = static_cast(geom->end()); - for (SOM_poly* poly = begin; poly != end; ++poly) - { - CL.add_face_packed_D(poly->v1, poly->v2, poly->v3, *(u32*)&poly->occ, 0.01f); - if (poly->b2sided) - CL.add_face_packed_D(poly->v3, poly->v2, poly->v1, *(u32*)&poly->occ, 0.01f); - } - geom->close(); - } - - // Create AABB-tree - geom_SOM = xr_new(); - geom_SOM->build(CL.getV(), int(CL.getVS()), CL.getT(), int(CL.getTS())); + int cnt = 0; + for (const auto& scene : m_scenes) + cnt += scene->pause_emitters(pauseState); + return cnt; } -void CSoundRender_Core::set_geometry_env(IReader* I) +void CSoundRender_Core::_restart() { - xr_delete(geom_ENV); - if (nullptr == I) - return; - const auto envLib = Parent.get_env_library(); - if (!envLib) - return; - - // Associate names - xr_vector ids; - IReader* names = I->open_chunk(0); - while (!names->eof()) - { - string256 n; - names->r_stringZ(n, sizeof(n)); - int id = envLib->GetID(n); - R_ASSERT(id >= 0); - ids.push_back((u16)id); - } - names->close(); - - // Load geometry - IReader* geom_ch = I->open_chunk(1); - - u8* _data = (u8*)xr_malloc(geom_ch->length()); - - memcpy(_data, geom_ch->pointer(), geom_ch->length()); - - IReader* geom = xr_new(_data, geom_ch->length(), 0); - - hdrCFORM H; - geom->r(&H, sizeof(hdrCFORM)); - Fvector* verts = (Fvector*)geom->pointer(); - CDB::TRI* tris = (CDB::TRI*)(verts + H.vertcount); - for (u32 it = 0; it < H.facecount; it++) - { - CDB::TRI* T = tris + it; - u16 id_front = (u16)((T->dummy & 0x0000ffff) >> 0); // front face - u16 id_back = (u16)((T->dummy & 0xffff0000) >> 16); // back face - R_ASSERT(id_front < (u16)ids.size()); - R_ASSERT(id_back < (u16)ids.size()); - T->dummy = u32(ids[id_back] << 16) | u32(ids[id_front]); - } - geom_ENV = xr_new(); - geom_ENV->build(verts, H.vertcount, tris, H.facecount); -#ifdef _EDITOR // XXX: may be we are interested in applying env in the game build too? + cache.destroy(); + cache.initialize(psSoundCacheSizeMB * 1024, cache_bytes_per_line); env_apply(); -#endif - geom_ch->close(); - geom->close(); - xr_free(_data); } CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) @@ -287,71 +176,6 @@ void CSoundRender_Core::attach_tail(CSound& snd, pcstr fName) i_destroy_source(s); } -void CSoundRender_Core::play(ref_sound& S, IGameObject* O, u32 flags, float delay) -{ - if (!bPresent || !S._handle()) - return; - S->g_object = O; - if (S._feedback()) - ((CSoundRender_Emitter*)S._feedback())->rewind(); - else - i_play(S, flags, delay); - - if (flags & sm_2D || S._handle()->channels_num() == 2) - S._feedback()->switch_to_2D(); - - S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); -} - -void CSoundRender_Core::play_no_feedback( - ref_sound& S, IGameObject* O, u32 flags, float delay, Fvector* pos, float* vol, float* freq, Fvector2* range) -{ - if (!bPresent || !S._handle()) - return; - const ref_sound orig = S; - S._set(xr_new()); - S->handle = orig->handle; - S->g_type = orig->g_type; - S->g_object = O; - S->dwBytesTotal = orig->dwBytesTotal; - S->fTimeTotal = orig->fTimeTotal; - S->fn_attached[0] = orig->fn_attached[0]; - S->fn_attached[1] = orig->fn_attached[1]; - - i_play(S, flags, delay); - - if (flags & sm_2D || S._handle()->channels_num() == 2) - S._feedback()->switch_to_2D(); - - if (pos) - S._feedback()->set_position(*pos); - if (freq) - S._feedback()->set_frequency(*freq); - if (range) - S._feedback()->set_range((*range)[0], (*range)[1]); - if (vol) - S._feedback()->set_volume(*vol); - S = orig; -} - -void CSoundRender_Core::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags, float delay) -{ - if (!bPresent || !S._handle()) - return; - S->g_object = O; - if (S._feedback()) - ((CSoundRender_Emitter*)S._feedback())->rewind(); - else - i_play(S, flags, delay); - - S._feedback()->set_position(pos); - - if (flags & sm_2D || S._handle()->channels_num() == 2) - S._feedback()->switch_to_2D(); - - S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); -} - void CSoundRender_Core::destroy(CSound& S) { if (auto* emitter = (CSoundRender_Emitter*)S.feedback) @@ -363,43 +187,6 @@ void CSoundRender_Core::destroy(CSound& S) S.handle = nullptr; } -CSoundRender_Environment* CSoundRender_Core::get_environment(const Fvector& P) -{ - static CSoundRender_Environment identity; - - if (bUserEnvironment) - { - return &s_user_environment; - } - if (geom_ENV) - { - Fvector dir = {0, -1, 0}; - geom_DB.ray_query(CDB::OPT_ONLYNEAREST, geom_ENV, P, dir, 1000.f); - if (geom_DB.r_count()) - { - const auto envLib = Parent.get_env_library(); - - CDB::RESULT* r = geom_DB.r_begin(); - CDB::TRI* T = geom_ENV->get_tris() + r->id; - Fvector* V = geom_ENV->get_verts(); - Fvector tri_norm; - tri_norm.mknormal(V[T->verts[0]], V[T->verts[1]], V[T->verts[2]]); - float dot = dir.dotproduct(tri_norm); - if (dot < 0) - { - u16 id_front = (u16)((T->dummy & 0x0000ffff) >> 0); // front face - return envLib->Get(id_front); - } - u16 id_back = (u16)((T->dummy & 0xffff0000) >> 16); // back face - return envLib->Get(id_back); - } - identity.set_identity(); - return &identity; - } - identity.set_identity(); - return &identity; -} - void CSoundRender_Core::env_apply() { /* @@ -415,37 +202,22 @@ void CSoundRender_Core::env_apply() bListenerMoved = true; } -void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) {} - -void CSoundRender_Core::object_relcase(IGameObject* obj) +void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) { - if (obj) - { - for (auto& emit : s_emitters) - { - if (emit) - if (emit->owner_data) - if (obj == emit->owner_data->g_object) - emit->owner_data->g_object = 0; - } - } -} - -void CSoundRender_Core::set_user_env(CSound_environment* E) -{ - if (0 == E && !bUserEnvironment) + if (!psSoundFlags.test(ss_EFX) || !m_effects) return; - if (E) - { - s_user_environment = *((CSoundRender_Environment*)E); - bUserEnvironment = true; - } - else + // Update effects + if (bListenerMoved) { - bUserEnvironment = false; + bListenerMoved = false; + e_target = *(CSoundRender_Environment*)DefaultSoundScene->get_environment(P); } - env_apply(); + + e_current.lerp(e_current, e_target, fTimer_Delta); + + m_effects->set_listener(e_current); + m_effects->commit(); } void CSoundRender_Core::refresh_env_library() @@ -457,8 +229,8 @@ void CSoundRender_Core::refresh_env_library() void CSoundRender_Core::refresh_sources() { - for (auto& emit : s_emitters) - emit->stop(false); + stop_emitters(); + for (const auto& kv : s_sources) { CSoundRender_Source* s = kv.second; @@ -466,40 +238,3 @@ void CSoundRender_Core::refresh_sources() s->load(*s->fname); } } - -void CSoundRender_Core::set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) -{ - // XXX: old SDK functionality - /*if (bEAX) - { - CSoundRender_Environment* SE = static_cast(src_env); - CSoundRender_Environment* DE = static_cast(*dst_env); -#if defined(XR_PLATFORM_WINDOWS) - // set environment - i_eax_set(&DSPROPSETID_EAX_ListenerProperties, - DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &SE->EnvironmentSize, - sizeof(SE->EnvironmentSize)); - i_eax_listener_set(SE); - i_eax_commit_setting(); - i_eax_set(&DSPROPSETID_EAX_ListenerProperties, - DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &DE->EnvironmentSize, - sizeof(DE->EnvironmentSize)); - i_eax_listener_get(DE); -#endif - }*/ -} - -void CSoundRender_Core::set_environment(u32 id, CSound_environment** dst_env) -{ - // XXX: old SDK functionality - /*if (bEAX) - { - CSoundRender_Environment* DE = static_cast(*dst_env); -#if defined(XR_PLATFORM_WINDOWS) - // set environment - i_eax_set(&DSPROPSETID_EAX_ListenerProperties, - DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &id, sizeof(id)); - i_eax_listener_get(DE); -#endif - }*/ -} diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 2762b3290e6..a33df9e0e7d 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -1,10 +1,12 @@ #pragma once +#include "xrCommon/xr_unordered_map.h" + #include "SoundRender.h" #include "SoundRender_Cache.h" #include "SoundRender_Environment.h" #include "SoundRender_Effects.h" -#include "xrCommon/xr_unordered_map.h" +#include "SoundRender_Scene.h" class CSoundRender_Core : public ISoundManager { @@ -31,11 +33,7 @@ class CSoundRender_Core : public ISoundManager public: CSoundManager& Parent; - using event = std::pair; - xr_vector s_events; - bool bPresent; - bool bUserEnvironment; bool bReady; CTimer Timer; @@ -45,29 +43,19 @@ class CSoundRender_Core : public ISoundManager float fTimerPersistent_Value; float fTimerPersistent_Delta; - sound_event* Handler; - protected: - // Collider -#ifndef _EDITOR - CDB::COLLIDER geom_DB; -#endif - CDB::MODEL* geom_SOM; - CDB::MODEL* geom_MODEL; - CDB::MODEL* geom_ENV; - // Containers + xr_vector m_scenes; + Lock s_sources_lock; xr_unordered_map s_sources; - xr_vector s_emitters; + u32 s_emitters_u; // emitter update marker xr_vector s_targets; xr_vector s_targets_defer; u32 s_targets_pu; // parameters update - CSoundRender_Environment s_user_environment; - CSoundRender_Effects* m_effects{}; - int m_iPauseCounter; + CSoundRender_Effects* m_effects{}; public: // Cache @@ -76,16 +64,18 @@ class CSoundRender_Core : public ISoundManager public: CSoundRender_Core(CSoundManager& p); - ~CSoundRender_Core() override; // General virtual void _initialize_devices_list() = 0; virtual void _initialize() = 0; virtual void _clear() = 0; + + ISoundScene* create_scene() override; + void destroy_scene(ISoundScene*&) override; + void _restart() override; // Sound interface - void verify_refsound(ref_sound& S); CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; void attach_tail(CSound& S, pcstr fName) override; @@ -99,21 +89,11 @@ class CSoundRender_Core : public ISoundManager } void stop_emitters() override; - int pause_emitters(bool val) override; - - void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) override; - void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) override; - void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, - float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) override; + int pause_emitters(bool pauseState) override; void set_master_volume(float f) override = 0; - void set_geometry_env(IReader* I) override; - void set_geometry_som(IReader* I) override; - void set_geometry_occ(CDB::MODEL* M) override; - void set_handler(sound_event* E) override; void update(const Fvector& P, const Fvector& D, const Fvector& N) override; - virtual void update_events(); void statistic(CSound_stats* dest, CSound_stats_ext* ext) override; void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; @@ -121,11 +101,8 @@ class CSoundRender_Core : public ISoundManager // virtual const Fvector& listener_position ( )=0; virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) = 0; - virtual void refresh_env_library(); - virtual void set_user_env(CSound_environment* E); - virtual void refresh_sources(); - virtual void set_environment(u32 id, CSound_environment** dst_env); - virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env); + void refresh_env_library() override; + void refresh_sources() override; public: bool i_create_source(CSound_source*& result, pcstr name, bool replaceWithNoSound = true); @@ -134,17 +111,12 @@ class CSoundRender_Core : public ISoundManager void i_create_all_sources(); void i_destroy_source(CSoundRender_Source* S); - CSoundRender_Emitter* i_play(const ref_sound& S, u32 flags, float delay); void i_start(CSoundRender_Emitter* E); void i_stop(CSoundRender_Emitter* E); void i_rewind(CSoundRender_Emitter* E); bool i_allow_play(CSoundRender_Emitter* E); bool i_locked() override { return isLocked; } - void object_relcase(IGameObject* obj) override; - float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) override; - float get_occlusion(Fvector& P, float R, Fvector* occ) override; - CSoundRender_Environment* get_environment(const Fvector& P); void env_apply(); }; diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 3f6f5eedea6..8049639a936 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -9,18 +9,8 @@ #include "SoundRender_Target.h" #include "SoundRender_Source.h" -CSoundRender_Emitter* CSoundRender_Core::i_play(const ref_sound& S, u32 flags, float delay) -{ - VERIFY(S._get()->feedback == nullptr); - CSoundRender_Emitter* E = s_emitters.emplace_back(xr_new()); - S._get()->feedback = E; - E->start(S, flags, delay); - return E; -} - void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector& N) { - u32 it; if (0 == bReady) return; Stats.Update.Begin(); @@ -38,19 +28,22 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector } s_emitters_u++; + const auto update_emitter = [this](CSoundRender_Emitter* emitter) + { + const bool ignore = emitter->bIgnoringTimeFactor; + const float time = ignore ? fTimerPersistent_Value : fTimer_Value; + const float delta = ignore ? fTimerPersistent_Delta : fTimer_Delta; + emitter->update(time, delta); + emitter->marker = s_emitters_u; + }; + // Firstly update emitters, which are now being rendered - // Msg("! update: r-emitters"); - for (it = 0; it < s_targets.size(); it++) + for (CSoundRender_Target* T : s_targets) { - CSoundRender_Target* T = s_targets[it]; - CSoundRender_Emitter* E = T->get_emitter(); - if (E) + if (CSoundRender_Emitter* E = T->get_emitter()) { - const bool ignore = E->bIgnoringTimeFactor; - const float time = ignore ? fTimerPersistent_Value : fTimer_Value; - const float delta = ignore ? fTimerPersistent_Delta : fTimer_Delta; - E->update(time, delta); - E->marker = s_emitters_u; + update_emitter(E); + E = T->get_emitter(); // update can stop itself if (E) T->priority = E->priority(); @@ -64,41 +57,36 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector } // Update emitters - // Msg("! update: emitters"); - for (it = 0; it < s_emitters.size(); it++) + for (CSoundRender_Scene* scene : m_scenes) { - CSoundRender_Emitter* pEmitter = s_emitters[it]; - if (pEmitter->marker != s_emitters_u) - { - const bool ignore = pEmitter->bIgnoringTimeFactor; - const float time = ignore ? fTimerPersistent_Value : fTimer_Value; - const float delta = ignore ? fTimerPersistent_Delta : fTimer_Delta; - pEmitter->update(time, delta); - pEmitter->marker = s_emitters_u; - } - if (!pEmitter->isPlaying()) + auto& emitters = scene->get_emitters(); + for (u32 it = 0; it < emitters.size(); it++) { - // Stopped - xr_delete(pEmitter); - s_emitters.erase(s_emitters.begin() + it); - it--; + CSoundRender_Emitter* pEmitter = emitters[it]; + if (pEmitter->marker != s_emitters_u) + { + update_emitter(pEmitter); + } + if (!pEmitter->isPlaying()) + { + // Stopped + xr_delete(pEmitter); + emitters.erase(emitters.begin() + it); + it--; + } } } - // Get currently rendering emitters - // Msg("! update: targets"); s_targets_defer.clear(); s_targets_pu++; - // u32 PU = s_targets_pu%s_targets.size(); - for (it = 0; it < s_targets.size(); it++) + + for (CSoundRender_Target* T : s_targets) { - CSoundRender_Target* T = s_targets[it]; if (T->get_emitter()) { // Has emmitter, maybe just not started rendering if (T->get_Rendering()) { - /*if (PU == it)*/ T->fill_parameters(); T->update(); } else @@ -109,25 +97,9 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector // Commit parameters from pending targets if (!s_targets_defer.empty()) { - // Msg ("! update: start render - commit"); s_targets_defer.erase(std::unique(s_targets_defer.begin(), s_targets_defer.end()), s_targets_defer.end()); - for (it = 0; it < s_targets_defer.size(); it++) - s_targets_defer[it]->fill_parameters(); - } - - // Update effects - if (psSoundFlags.test(ss_EFX) && m_effects) - { - if (bListenerMoved) - { - bListenerMoved = false; - e_target = *get_environment(P); - } - - e_current.lerp(e_current, e_target, fTimer_Delta); - - m_effects->set_listener(e_current); - m_effects->commit(); + for (CSoundRender_Target* target : s_targets_defer) + target->fill_parameters(); } // update listener @@ -136,68 +108,68 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector // Start rendering of pending targets if (!s_targets_defer.empty()) { - // Msg ("! update: start render"); - for (it = 0; it < s_targets_defer.size(); it++) - s_targets_defer[it]->render(); + for (CSoundRender_Target* target : s_targets_defer) + target->render(); } // Events - update_events(); + for (CSoundRender_Scene* scene : m_scenes) + scene->update(); isLocked = false; Stats.Update.End(); } -static u32 g_saved_event_count = 0; - -void CSoundRender_Core::update_events() -{ - g_saved_event_count = static_cast(s_events.size()); - for (auto& E : s_events) - Handler(E.first, E.second); - - s_events.clear(); -} - void CSoundRender_Core::statistic(CSound_stats* dest, CSound_stats_ext* ext) { if (dest) { dest->_rendered = 0; + dest->_simulated = 0; + dest->_events = 0; + for (auto T : s_targets) { if (T->get_emitter() && T->get_Rendering()) dest->_rendered++; } - dest->_simulated = static_cast(s_emitters.size()); + + for (CSoundRender_Scene* scene : m_scenes) + { + dest->_simulated += scene->get_emitters().size(); + dest->_events += scene->get_prev_events_count(); + } dest->_cache_hits = cache._stat_hit; dest->_cache_misses = cache._stat_miss; - dest->_events = g_saved_event_count; cache.stats_clear(); } if (ext) { - for (auto _E : s_emitters) + for (CSoundRender_Scene* scene : m_scenes) { - CSound_stats_ext::SItem _I; - _I._3D = !_E->b2D; - _I._rendered = !!_E->target; - _I.params = _E->p_source; - _I.volume = _E->smooth_volume; - if (_E->owner_data) + auto& emitters = scene->get_emitters(); + for (const auto emitter : emitters) { - _I.name = _E->source()->fname; - _I.game_object = _E->owner_data->g_object; - _I.game_type = _E->owner_data->g_type; - _I.type = _E->owner_data->s_type; + CSound_stats_ext::SItem item; + item._3D = !emitter->b2D; + item._rendered = !!emitter->target; + item.params = emitter->p_source; + item.volume = emitter->smooth_volume; + if (emitter->owner_data) + { + item.name = emitter->source()->fname; + item.game_object = emitter->owner_data->g_object; + item.game_type = emitter->owner_data->g_type; + item.type = emitter->owner_data->s_type; + } + else + { + item.game_object = nullptr; + item.game_type = 0; + item.type = st_Effect; + } + ext->append(item); } - else - { - _I.game_object = nullptr; - _I.game_type = 0; - _I.type = st_Effect; - } - ext->append(_I); } } } @@ -214,93 +186,3 @@ void CSoundRender_Core::DumpStatistics(IGameFont& font, IPerformanceAlert* alert font.OutNext("Hits/misses: %d/%d", sndStat._cache_hits, sndStat._cache_misses); Stats.FrameStart(); } - -float CSoundRender_Core::get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion) -{ - float occ_value = 1.f; - - if (nullptr != geom_SOM) - { - // Calculate RAY params - Fvector pos, dir; - pos.random_dir(); - pos.mul(dispersion); - pos.add(snd_pt); - dir.sub(pos, hear_pt); - float range = dir.magnitude(); - dir.div(range); - - geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, hear_pt, dir, range); - const auto r_cnt = geom_DB.r_count(); - CDB::RESULT* _B = geom_DB.r_begin(); - if (0 != r_cnt) - { - for (size_t k = 0; k < r_cnt; k++) - { - CDB::RESULT* R = _B + k; - occ_value *= *reinterpret_cast(&R->dummy); - } - } - } - return occ_value; -} - -float CSoundRender_Core::get_occlusion(Fvector& P, float R, Fvector* occ) -{ - float occ_value = 1.f; - - // Calculate RAY params - Fvector base = listener_position(); - Fvector pos, dir; - float range; - pos.random_dir(); - pos.mul(R); - pos.add(P); - dir.sub(pos, base); - range = dir.magnitude(); - dir.div(range); - - if (nullptr != geom_MODEL) - { - bool bNeedFullTest = true; - // 1. Check cached polygon - float _u, _v, _range; - if (CDB::TestRayTri(base, dir, occ, _u, _v, _range, true)) - if (_range > 0 && _range < range) - { - occ_value = psSoundOcclusionScale; - bNeedFullTest = false; - } - // 2. Polygon doesn't picked up - real database query - if (bNeedFullTest) - { - geom_DB.ray_query(CDB::OPT_ONLYNEAREST, geom_MODEL, base, dir, range); - if (0 != geom_DB.r_count()) - { - // cache polygon - const CDB::RESULT* R2 = geom_DB.r_begin(); - const CDB::TRI& T = geom_MODEL->get_tris()[R2->id]; - const Fvector* V = geom_MODEL->get_verts(); - occ[0].set(V[T.verts[0]]); - occ[1].set(V[T.verts[1]]); - occ[2].set(V[T.verts[2]]); - occ_value = psSoundOcclusionScale; - } - } - } - if (nullptr != geom_SOM) - { - geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, base, dir, range); - const auto r_cnt = geom_DB.r_count(); - CDB::RESULT* _B = geom_DB.r_begin(); - if (0 != r_cnt) - { - for (size_t k = 0; k < r_cnt; k++) - { - CDB::RESULT* R2 = _B + k; - occ_value *= *reinterpret_cast(&R2->dummy); - } - } - } - return occ_value; -} diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 4735310397d..f805f6c34e8 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -2,6 +2,7 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Core.h" +#include "SoundRender_Scene.h" #include "SoundRender_Source.h" #include "SoundRender_TargetA.h" @@ -33,7 +34,8 @@ void CSoundRender_Emitter::set_time(float t) fTimeToRewind = t; } -CSoundRender_Emitter::CSoundRender_Emitter() +CSoundRender_Emitter::CSoundRender_Emitter(CSoundRender_Scene* s) + : scene(s) { #ifdef DEBUG static u32 incrementalID = 0; @@ -78,11 +80,13 @@ void CSoundRender_Emitter::Event_ReleaseOwner() if (!owner_data) return; - for (u32 it = 0; it < SoundRender->s_events.size(); it++) + auto& events = scene->get_events(); + + for (u32 it = 0; it < events.size(); it++) { - if (owner_data == SoundRender->s_events[it].first) + if (owner_data == events[it].first) { - SoundRender->s_events.erase(SoundRender->s_events.begin() + it); + events.erase(events.begin() + it); it--; } } @@ -91,24 +95,24 @@ void CSoundRender_Emitter::Event_ReleaseOwner() void CSoundRender_Emitter::Event_Propagade() { fTimeToPropagade += ::Random.randF(s_f_def_event_pulse - 0.030f, s_f_def_event_pulse + 0.030f); - if (!(owner_data)) + if (!owner_data) return; - if (0 == owner_data->g_type) + if (!owner_data->g_type) return; - if (0 == owner_data->g_object) + if (!owner_data->g_object) return; - if (0 == SoundRender->Handler) + if (!scene->get_events_handler()) return; VERIFY(_valid(p_source.volume)); // Calculate range - float clip = p_source.max_ai_distance * p_source.volume; - float range = std::min(p_source.max_ai_distance, clip); + const float clip = p_source.max_ai_distance * p_source.volume; + const float range = std::min(p_source.max_ai_distance, clip); if (range < 0.1f) return; // Inform objects - SoundRender->s_events.emplace_back(owner_data, range); + scene->get_events().emplace_back(owner_data, range); } void CSoundRender_Emitter::switch_to_2D() @@ -117,7 +121,11 @@ void CSoundRender_Emitter::switch_to_2D() set_priority(100.f); } -void CSoundRender_Emitter::switch_to_3D() { b2D = false; } +void CSoundRender_Emitter::switch_to_3D() +{ + b2D = false; +} + u32 CSoundRender_Emitter::play_time() { if (m_current_state == stPlaying || m_current_state == stPlayingLooped || m_current_state == stSimulating || diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 001e2d19b20..35c83ecbbf3 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -1,8 +1,10 @@ #pragma once +#include "xrCore/_std_extensions.h" + #include "SoundRender.h" #include "SoundRender_Environment.h" -#include "xrCore/_std_extensions.h" +#include "SoundRender_Scene.h" class CSoundRender_Emitter final : public CSound_emitter { @@ -33,7 +35,8 @@ class CSoundRender_Emitter final : public CSound_emitter static constexpr float TIME_TO_STOP_INFINITE = static_cast(0xffffffff); - CSoundRender_Target* target; + CSoundRender_Target* target{}; + CSoundRender_Scene* scene{}; ref_sound owner_data; [[nodiscard]] @@ -107,7 +110,7 @@ class CSoundRender_Emitter final : public CSound_emitter void fill_block(void* ptr, u32 size); void fill_data(u8* ptr, u32 offset, u32 size); - float priority(); + float priority() const; void start(const ref_sound& _owner, u32 flags, float delay); void cancel(); // manager forces out of rendering void update(float time, float dt); @@ -121,6 +124,6 @@ class CSoundRender_Emitter final : public CSound_emitter void set_ignore_time_factor(bool ignore) override { bIgnoringTimeFactor = ignore; }; - CSoundRender_Emitter(); + CSoundRender_Emitter(CSoundRender_Scene* s); ~CSoundRender_Emitter() override; }; diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 4ebf9e852b2..6f1c2c3304a 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -49,11 +49,11 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = fTime + (get_length_sec() / p_source.freq); //--#SM+#-- fTimeToPropagade = fTime; fade_volume = 1.f; - occluder_volume = SoundRender->get_occlusion(p_source.position, .2f, occluder); + occluder_volume = scene->get_occlusion(p_source.position, .2f, occluder); smooth_volume = p_source.base_volume * p_source.volume * (owner_data->s_type == st_Effect ? psSoundVEffects * psSoundVFactor : psSoundVMusic) * (b2D ? 1.f : occluder_volume); - e_current = e_target = *SoundRender->get_environment(p_source.position); + e_current = e_target = *(CSoundRender_Environment*)scene->get_environment(p_source.position); if (update_culling(dt)) { m_current_state = stPlaying; @@ -77,11 +77,11 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = TIME_TO_STOP_INFINITE; fTimeToPropagade = fTime; fade_volume = 1.f; - occluder_volume = SoundRender->get_occlusion(p_source.position, .2f, occluder); + occluder_volume = scene->get_occlusion(p_source.position, .2f, occluder); smooth_volume = p_source.base_volume * p_source.volume * (owner_data->s_type == st_Effect ? psSoundVEffects * psSoundVFactor : psSoundVMusic) * (b2D ? 1.f : occluder_volume); - e_current = e_target = *SoundRender->get_environment(p_source.position); + e_current = e_target = *(CSoundRender_Environment*)scene->get_environment(p_source.position); if (update_culling(dt)) { m_current_state = stPlayingLooped; @@ -140,7 +140,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) } else { - u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- set_cursor(ptr); if (update_culling(dt)) @@ -193,7 +193,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { // switch to: PLAY m_current_state = stPlayingLooped; // switch state - u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- set_cursor(ptr); SoundRender->i_start(this); @@ -213,13 +213,13 @@ void CSoundRender_Emitter::update(float fTime, float dt) case stSimulatingLooped: if (fTimeToRewind > 0.0f) { - float fLength = get_length_sec(); - bool bLooped = (fTimeToStop == 0xffffffff); + const float fLength = get_length_sec(); + const bool bLooped = (fTimeToStop == 0xffffffff); R_ASSERT2(fLength >= fTimeToRewind, "set_time: target time is bigger than length of sound"); - float fRemainingTime = (fLength - fTimeToRewind) / p_source.freq; - float fPastTime = fTimeToRewind / p_source.freq; + const float fRemainingTime = (fLength - fTimeToRewind) / p_source.freq; + const float fPastTime = fTimeToRewind / p_source.freq; fTimeStarted = fTime - fPastTime; fTimeToPropagade = fTimeStarted; //--> For AI events @@ -242,7 +242,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = fTime + fRemainingTime; } - u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_wformat); + const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_wformat); set_cursor(ptr); fTimeToRewind = 0.0f; @@ -275,8 +275,8 @@ void CSoundRender_Emitter::update(float fTime, float dt) IC void volume_lerp(float& c, float t, float s, float dt) { - float diff = t - c; - float diff_a = _abs(diff); + const float diff = t - c; + const float diff_a = _abs(diff); if (diff_a < EPS_S) return; float mot = s * dt; @@ -309,7 +309,7 @@ bool CSoundRender_Emitter::update_culling(float dt) // Calc attenuated volume float att = p_source.min_distance / (psSoundRolloff * dist); clamp(att, 0.f, 1.f); - float fade_scale = + const float fade_scale = bStopping || (att * p_source.base_volume * p_source.volume * (owner_data->s_type == st_Effect ? psSoundVEffects * psSoundVFactor : psSoundVMusic) < psSoundCull) ? @@ -318,9 +318,9 @@ bool CSoundRender_Emitter::update_culling(float dt) fade_volume += dt * 10.f * fade_scale; // Update occlusion - float occ = (owner_data->g_type == SOUND_TYPE_WORLD_AMBIENT) ? + const float occ = (owner_data->g_type == SOUND_TYPE_WORLD_AMBIENT) ? 1.0f : - SoundRender->get_occlusion(p_source.position, .2f, occluder); + scene->get_occlusion(p_source.position, .2f, occluder); volume_lerp(occluder_volume, occ, 1.f, dt); clamp(occluder_volume, 0.f, 1.f); @@ -352,11 +352,10 @@ bool CSoundRender_Emitter::update_culling(float dt) // --- else check availability of resources if (target) return TRUE; - else - return SoundRender->i_allow_play(this); + return SoundRender->i_allow_play(this); } -float CSoundRender_Emitter::priority() +float CSoundRender_Emitter::priority() const { float dist = SoundRender->listener_position().distance_to(p_source.position); float att = p_source.min_distance / (psSoundRolloff * dist); @@ -368,7 +367,7 @@ void CSoundRender_Emitter::update_environment(float dt) { if (bMoved) { - e_target = *SoundRender->get_environment(p_source.position); + e_target = *(CSoundRender_Environment*)scene->get_environment(p_source.position); // Cribbledirge: updates the velocity of the sound. p_source.update_velocity(dt); } diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp new file mode 100644 index 00000000000..bf5578cbdd8 --- /dev/null +++ b/src/xrSound/SoundRender_Scene.cpp @@ -0,0 +1,421 @@ +#include "stdafx.h" + +#include "Common/LevelStructure.hpp" +#include "xrCDB/Intersect.hpp" + +#include "SoundRender_Core.h" +#include "SoundRender_Scene.h" +#include "SoundRender_Emitter.h" + +CSoundRender_Scene::~CSoundRender_Scene() +{ + stop_emitters(); + + // remove emitters + for (auto& emit : s_emitters) + xr_delete(emit); + s_emitters.clear(); + + xr_delete(geom_ENV); + xr_delete(geom_SOM); +} + +void CSoundRender_Scene::stop_emitters() const +{ + for (const auto& emit : s_emitters) + emit->stop(false); +} + +int CSoundRender_Scene::pause_emitters(bool pauseState) +{ + m_iPauseCounter += pauseState ? +1 : -1; + VERIFY(m_iPauseCounter >= 0); + + for (const auto& emit : s_emitters) + emit->pause(pauseState, pauseState ? m_iPauseCounter : m_iPauseCounter + 1); + + return m_iPauseCounter; +} + +void CSoundRender_Scene::set_handler(sound_event* E) { sound_event_handler = E; } + +void CSoundRender_Scene::set_geometry_occ(CDB::MODEL* M) { geom_MODEL = M; } + +void CSoundRender_Scene::set_geometry_som(IReader* I) +{ + xr_delete(geom_SOM); + if (nullptr == I) + return; + + // check version + R_ASSERT(I->find_chunk(0)); + [[maybe_unused]] const u32 version = I->r_u32(); + VERIFY2(version == 0, "Invalid SOM version"); + + struct SOM_poly + { + Fvector3 v1; + Fvector3 v2; + Fvector3 v3; + u32 b2sided; + float occ; + }; + + CDB::Collector CL; + { + // load geometry + IReader* geom = I->open_chunk(1); + VERIFY2(geom, "Corrupted SOM file"); + if (!geom) + return; + + // Load tris and merge them + const auto begin = static_cast(geom->pointer()); + const auto end = static_cast(geom->end()); + for (SOM_poly* poly = begin; poly != end; ++poly) + { + CL.add_face_packed_D(poly->v1, poly->v2, poly->v3, *(u32*)&poly->occ, 0.01f); + if (poly->b2sided) + CL.add_face_packed_D(poly->v3, poly->v2, poly->v1, *(u32*)&poly->occ, 0.01f); + } + geom->close(); + } + + // Create AABB-tree + geom_SOM = xr_new(); + geom_SOM->build(CL.getV(), int(CL.getVS()), CL.getT(), int(CL.getTS())); +} + +void CSoundRender_Scene::set_geometry_env(IReader* I) +{ + xr_delete(geom_ENV); + if (nullptr == I) + return; + const auto envLib = SoundRender->Parent.get_env_library(); + if (!envLib) + return; + + // Associate names + xr_vector ids; + IReader* names = I->open_chunk(0); + while (!names->eof()) + { + string256 n; + names->r_stringZ(n, sizeof(n)); + const int id = envLib->GetID(n); + R_ASSERT(id >= 0); + ids.push_back((u16)id); + } + names->close(); + + // Load geometry + IReader* geom_ch = I->open_chunk(1); + + u8* _data = (u8*)xr_malloc(geom_ch->length()); + + memcpy(_data, geom_ch->pointer(), geom_ch->length()); + + IReader* geom = xr_new(_data, geom_ch->length(), 0); + + hdrCFORM H; + geom->r(&H, sizeof(hdrCFORM)); + Fvector* verts = (Fvector*)geom->pointer(); + CDB::TRI* tris = (CDB::TRI*)(verts + H.vertcount); + for (u32 it = 0; it < H.facecount; it++) + { + CDB::TRI* T = tris + it; + const u16 id_front = (u16)((T->dummy & 0x0000ffff) >> 0); // front face + const u16 id_back = (u16)((T->dummy & 0xffff0000) >> 16); // back face + R_ASSERT(id_front < (u16)ids.size()); + R_ASSERT(id_back < (u16)ids.size()); + T->dummy = u32(ids[id_back] << 16) | u32(ids[id_front]); + } + geom_ENV = xr_new(); + geom_ENV->build(verts, H.vertcount, tris, H.facecount); +#ifdef _EDITOR // XXX: may be we are interested in applying env in the game build too? + env_apply(); +#endif + geom_ch->close(); + geom->close(); + xr_free(_data); +} + +void CSoundRender_Scene::play(ref_sound& S, IGameObject* O, u32 flags, float delay) +{ + if (!SoundRender->bPresent || !S._handle()) + return; + S->g_object = O; + if (S._feedback()) + ((CSoundRender_Emitter*)S._feedback())->rewind(); + else + i_play(S, flags, delay); + + if (flags & sm_2D || S._handle()->channels_num() == 2) + S._feedback()->switch_to_2D(); + + S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); +} + +void CSoundRender_Scene::play_no_feedback( + ref_sound& S, IGameObject* O, u32 flags, float delay, Fvector* pos, float* vol, float* freq, Fvector2* range) +{ + if (!SoundRender->bPresent || !S._handle()) + return; + const ref_sound orig = S; + S._set(xr_new()); + S->handle = orig->handle; + S->g_type = orig->g_type; + S->g_object = O; + S->dwBytesTotal = orig->dwBytesTotal; + S->fTimeTotal = orig->fTimeTotal; + S->fn_attached[0] = orig->fn_attached[0]; + S->fn_attached[1] = orig->fn_attached[1]; + + i_play(S, flags, delay); + + if (flags & sm_2D || S._handle()->channels_num() == 2) + S._feedback()->switch_to_2D(); + + if (pos) + S._feedback()->set_position(*pos); + if (freq) + S._feedback()->set_frequency(*freq); + if (range) + S._feedback()->set_range((*range)[0], (*range)[1]); + if (vol) + S._feedback()->set_volume(*vol); + S = orig; +} + +void CSoundRender_Scene::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags, float delay) +{ + if (!SoundRender->bPresent || !S._handle()) + return; + S->g_object = O; + if (S._feedback()) + ((CSoundRender_Emitter*)S._feedback())->rewind(); + else + i_play(S, flags, delay); + + S._feedback()->set_position(pos); + + if (flags & sm_2D || S._handle()->channels_num() == 2) + S._feedback()->switch_to_2D(); + + S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); +} + +CSoundRender_Emitter* CSoundRender_Scene::i_play(ref_sound& S, u32 flags, float delay) +{ + VERIFY(!S->feedback); + CSoundRender_Emitter* E = s_emitters.emplace_back(xr_new(this)); + S->feedback = E; + E->start(S, flags, delay); + return E; +} + +void CSoundRender_Scene::update() +{ + s_events_prev_count = s_events.size(); + + for (auto& [sound, range] : s_events) + sound_event_handler(sound, range); + + s_events.clear(); +} + +void CSoundRender_Scene::object_relcase(IGameObject* obj) +{ + if (obj) + { + for (const auto& emit : s_emitters) + { + if (emit) + if (emit->owner_data) + if (obj == emit->owner_data->g_object) + emit->owner_data->g_object = 0; + } + } +} + +float CSoundRender_Scene::get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion) +{ + float occ_value = 1.f; + + if (nullptr != geom_SOM) + { + // Calculate RAY params + Fvector pos, dir; + pos.random_dir(); + pos.mul(dispersion); + pos.add(snd_pt); + dir.sub(pos, hear_pt); + const float range = dir.magnitude(); + dir.div(range); + + geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, hear_pt, dir, range); + const auto r_cnt = geom_DB.r_count(); + CDB::RESULT* _B = geom_DB.r_begin(); + if (0 != r_cnt) + { + for (size_t k = 0; k < r_cnt; k++) + { + CDB::RESULT* R = _B + k; + occ_value *= *reinterpret_cast(&R->dummy); + } + } + } + return occ_value; +} + +float CSoundRender_Scene::get_occlusion(Fvector& P, float R, Fvector* occ) +{ + float occ_value = 1.f; + + // Calculate RAY params + const Fvector base = SoundRender->listener_position(); + Fvector pos, dir; + float range; + pos.random_dir(); + pos.mul(R); + pos.add(P); + dir.sub(pos, base); + range = dir.magnitude(); + dir.div(range); + + if (nullptr != geom_MODEL) + { + bool bNeedFullTest = true; + // 1. Check cached polygon + float _u, _v, _range; + if (CDB::TestRayTri(base, dir, occ, _u, _v, _range, true)) + if (_range > 0 && _range < range) + { + occ_value = psSoundOcclusionScale; + bNeedFullTest = false; + } + // 2. Polygon doesn't picked up - real database query + if (bNeedFullTest) + { + geom_DB.ray_query(CDB::OPT_ONLYNEAREST, geom_MODEL, base, dir, range); + if (0 != geom_DB.r_count()) + { + // cache polygon + const CDB::RESULT* R2 = geom_DB.r_begin(); + const CDB::TRI& T = geom_MODEL->get_tris()[R2->id]; + const Fvector* V = geom_MODEL->get_verts(); + occ[0].set(V[T.verts[0]]); + occ[1].set(V[T.verts[1]]); + occ[2].set(V[T.verts[2]]); + occ_value = psSoundOcclusionScale; + } + } + } + if (nullptr != geom_SOM) + { + geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, base, dir, range); + const auto r_cnt = geom_DB.r_count(); + CDB::RESULT* _B = geom_DB.r_begin(); + if (0 != r_cnt) + { + for (size_t k = 0; k < r_cnt; k++) + { + CDB::RESULT* R2 = _B + k; + occ_value *= *reinterpret_cast(&R2->dummy); + } + } + } + return occ_value; +} + +void CSoundRender_Scene::set_user_env(CSound_environment* E) +{ + if (0 == E && !bUserEnvironment) + return; + + if (E) + { + s_user_environment = *((CSoundRender_Environment*)E); + bUserEnvironment = true; + } + else + { + bUserEnvironment = false; + } + SoundRender->env_apply(); +} + +CSound_environment* CSoundRender_Scene::get_environment(const Fvector& P) +{ + static CSoundRender_Environment identity; + + if (bUserEnvironment) + { + return &s_user_environment; + } + if (geom_ENV) + { + constexpr Fvector dir = { 0, -1, 0 }; + geom_DB.ray_query(CDB::OPT_ONLYNEAREST, geom_ENV, P, dir, 1000.f); + if (geom_DB.r_count()) + { + const auto envLib = SoundRender->Parent.get_env_library(); + + const CDB::RESULT* r = geom_DB.r_begin(); + const CDB::TRI* T = geom_ENV->get_tris() + r->id; + const Fvector* V = geom_ENV->get_verts(); + Fvector tri_norm; + tri_norm.mknormal(V[T->verts[0]], V[T->verts[1]], V[T->verts[2]]); + const float dot = dir.dotproduct(tri_norm); + if (dot < 0) + { + const u16 id_front = (u16)((T->dummy & 0x0000ffff) >> 0); // front face + return envLib->Get(id_front); + } + const u16 id_back = (u16)((T->dummy & 0xffff0000) >> 16); // back face + return envLib->Get(id_back); + } + identity.set_identity(); + return &identity; + } + identity.set_identity(); + return &identity; +} + +void CSoundRender_Scene::set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) +{ + // XXX: old SDK functionality + /*if (bEAX) + { + CSoundRender_Environment* SE = static_cast(src_env); + CSoundRender_Environment* DE = static_cast(*dst_env); +#if defined(XR_PLATFORM_WINDOWS) + // set environment + i_eax_set(&DSPROPSETID_EAX_ListenerProperties, + DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &SE->EnvironmentSize, + sizeof(SE->EnvironmentSize)); + i_eax_listener_set(SE); + i_eax_commit_setting(); + i_eax_set(&DSPROPSETID_EAX_ListenerProperties, + DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &DE->EnvironmentSize, + sizeof(DE->EnvironmentSize)); + i_eax_listener_get(DE); +#endif + }*/ +} + + +void CSoundRender_Scene::set_environment(u32 id, CSound_environment** dst_env) +{ + // XXX: old SDK functionality + /*if (bEAX) + { + CSoundRender_Environment* DE = static_cast(*dst_env); +#if defined(XR_PLATFORM_WINDOWS) + // set environment + i_eax_set(&DSPROPSETID_EAX_ListenerProperties, + DSPROPERTY_EAXLISTENER_IMMEDIATE | DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, &id, sizeof(id)); + i_eax_listener_get(DE); +#endif + }*/ +} diff --git a/src/xrSound/SoundRender_Scene.h b/src/xrSound/SoundRender_Scene.h new file mode 100644 index 00000000000..f832a1c32d1 --- /dev/null +++ b/src/xrSound/SoundRender_Scene.h @@ -0,0 +1,66 @@ +#pragma once + +#include "SoundRender_Environment.h" + +class CSoundRender_Emitter; + +class CSoundRender_Scene final : public ISoundScene +{ +public: + ~CSoundRender_Scene() override; + + void stop_emitters() const override; + int pause_emitters(bool pauseState) override; + + void set_handler(sound_event* E) override; + + void set_geometry_env(IReader* I) override; + void set_geometry_som(IReader* I) override; + void set_geometry_occ(CDB::MODEL* M) override; + + void set_user_env(CSound_environment* E) override; + void set_environment(u32 id, CSound_environment** dst_env) override; + void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) override; + CSound_environment* get_environment(const Fvector& P) override; + + void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) override; + void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) override; + void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, + float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) override; + + float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) override; + float get_occlusion(Fvector& P, float R, Fvector* occ) override; + + void object_relcase(IGameObject* obj) override; + +public: + CSoundRender_Emitter* i_play(ref_sound& S, u32 flags, float delay); + + void update(); + + auto get_events_handler() const { return sound_event_handler; } + auto& get_events() { return s_events; } + auto& get_prev_events_count() { return s_events_prev_count; } + + auto& get_emitters() { return s_emitters; } + +private: + xr_vector s_emitters; + + using event = std::pair; + xr_vector s_events; + size_t s_events_prev_count{}; + + sound_event* sound_event_handler{}; + + // Collider + CDB::COLLIDER geom_DB; + CDB::MODEL* geom_SOM{}; + CDB::MODEL* geom_MODEL{}; + CDB::MODEL* geom_ENV{}; + + bool bUserEnvironment{}; + CSoundRender_Environment s_user_environment; + + int m_iPauseCounter{ 1 }; +}; diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index 763f4d88db3..e17bb3bb7d2 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -28,8 +28,8 @@ class CSoundRender_Target CSoundRender_Target(); virtual ~CSoundRender_Target(); - CSoundRender_Emitter* get_emitter() { return m_pEmitter; } - bool get_Rendering() { return rendering; } + CSoundRender_Emitter* get_emitter() const { return m_pEmitter; } + bool get_Rendering() const { return rendering; } virtual bool _initialize() = 0; virtual void _destroy() = 0; virtual void _restart() = 0; diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index 45e998ffeba..dfaf3f000dd 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -41,6 +41,7 @@ + @@ -66,6 +67,7 @@ + diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index d888556773e..e10f7b3390a 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -34,6 +34,9 @@ {d66ed9a4-3e7a-471f-9b63-7596368b6f66} + + {764beefb-01ae-4d1b-9504-a66144a44420} + @@ -81,6 +84,9 @@ Effects\OpenAL + + Scene + @@ -146,6 +152,9 @@ Effects\OpenAL + + Scene + diff --git a/src/xrUICore/CMakeLists.txt b/src/xrUICore/CMakeLists.txt index c3c63a5390d..ae8df434075 100644 --- a/src/xrUICore/CMakeLists.txt +++ b/src/xrUICore/CMakeLists.txt @@ -149,6 +149,7 @@ target_link_libraries(xrUICore xrMiscMath xrImGui xrCore + xrSound ) if (WIN32) diff --git a/src/xrUICore/xrUICore.vcxproj b/src/xrUICore/xrUICore.vcxproj index 93fe0ce7037..94fc70434fe 100644 --- a/src/xrUICore/xrUICore.vcxproj +++ b/src/xrUICore/xrUICore.vcxproj @@ -51,6 +51,9 @@ {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} + + {ccca7859-eb86-493e-9b53-c4235f45b3c5} + From 16f742feb1fc01d452cc09ad00cdf822d36bfd2f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 23:26:18 +0500 Subject: [PATCH 015/497] xrSound: final polishing refactoring --- src/xrSound/Sound.cpp | 7 +++++ src/xrSound/Sound.h | 33 ++++++++++---------- src/xrSound/SoundRender_Core.cpp | 7 ----- src/xrSound/SoundRender_Core.h | 1 - src/xrSound/SoundRender_Emitter_streamer.cpp | 6 ++-- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index f26d697a69e..b4707943095 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -73,3 +73,10 @@ SoundEnvironment_LIB* CSoundManager::get_env_library() const { return soundEnvironment; } + +void CSoundManager::refresh_env_library() +{ + env_unload(); + env_load(); + SoundRender->env_apply(); +} diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 2a7271246f1..46792fd06f1 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -22,7 +22,7 @@ constexpr pcstr SNDENV_FILENAME = "sEnvironment.xr"; // refs class IGameObject; -class CSound; +struct CSound; struct resptrcode_sound; class ISoundScene; class XRSOUND_API CSound_params; @@ -241,7 +241,7 @@ inline ISoundScene::~ISoundScene() = default; class XRSOUND_API XR_NOVTABLE ISoundManager { protected: - friend class CSound; + friend struct CSound; friend struct resptrcode_sound; virtual CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; @@ -271,7 +271,6 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual const Fvector& listener_position() = 0; - virtual void refresh_env_library() = 0; virtual void refresh_sources() = 0; }; @@ -288,11 +287,13 @@ class XRSOUND_API CSoundManager void Create(); void Destroy(); + [[nodiscard]] bool IsSoundEnabled() const; - SoundEnvironment_LIB* get_env_library() const; void env_load(); void env_unload(); + void refresh_env_library(); + SoundEnvironment_LIB* get_env_library() const; }; class CSound_UserDataVisitor; @@ -307,7 +308,7 @@ class CSound_UserData : public xr_resource using CSound_UserDataPtr = resptr_core>; -class CSound : public xr_resource +struct CSound : public xr_resource { public: //shared_str nm; @@ -323,9 +324,6 @@ class CSound : public xr_resource u32 dwBytesTotal{}; float fTimeTotal{}; - - ~CSound() override { GEnv.Sound->destroy(*this); } - float get_length_sec() const { return fTimeTotal; } }; /*! \class ref_sound @@ -355,7 +353,7 @@ struct resptrcode_sound : public resptr_base [[nodiscard]] ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; } - bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) + ICF bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) { VerSndUnlocked(); _set(GEnv.Sound->create(name, sound_type, game_type, replaceWithNoSound)); @@ -364,11 +362,14 @@ struct resptrcode_sound : public resptr_base ICF void destroy() { + if (!p_) + return; VerSndUnlocked(); + GEnv.Sound->destroy(*p_); _set(nullptr); } - void attach_tail(pcstr name) const + ICF void attach_tail(pcstr name) const { VerSndUnlocked(); if (!p_) @@ -390,7 +391,7 @@ struct resptrcode_sound : public resptr_base p_->s_type = sound_type; } - void play(IGameObject* O, u32 flags = 0, float delay = 0.f) + ICF void play(IGameObject* O, u32 flags = 0, float delay = 0.f) { if (!p_ || !DefaultSoundScene) return; @@ -398,7 +399,7 @@ struct resptrcode_sound : public resptr_base DefaultSoundScene->play(static_cast(*this), O, flags, delay); } - void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) + ICF void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) { if (!p_ || !DefaultSoundScene) return; @@ -406,7 +407,7 @@ struct resptrcode_sound : public resptr_base DefaultSoundScene->play_at_pos(static_cast(*this), O, pos, flags, delay); } - void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) + ICF void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) { if (!p_ || !DefaultSoundScene) return; @@ -431,7 +432,7 @@ struct resptrcode_sound : public resptr_base return _feedback() ? _feedback()->get_params() : nullptr; } - void set_params(CSound_params* p) const + ICF void set_params(CSound_params* p) const { VerSndUnlocked(); if (CSound_emitter* const feedback = _feedback()) @@ -444,9 +445,9 @@ struct resptrcode_sound : public resptr_base } [[nodiscard]] - ICF float get_length_sec() const { return p_ ? p_->get_length_sec() : 0.0f; } + ICF float get_length_sec() const { return p_ ? p_->fTimeTotal : 0.0f; } - IC static void VerSndUnlocked() + static void VerSndUnlocked() { VERIFY(!GEnv.Sound->i_locked()); } diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 910363d4a78..5fd9127597c 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -220,13 +220,6 @@ void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, cons m_effects->commit(); } -void CSoundRender_Core::refresh_env_library() -{ - Parent.env_unload(); - Parent.env_load(); - env_apply(); -} - void CSoundRender_Core::refresh_sources() { stop_emitters(); diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index a33df9e0e7d..4b38eaa3281 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -101,7 +101,6 @@ class CSoundRender_Core : public ISoundManager // virtual const Fvector& listener_position ( )=0; virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) = 0; - void refresh_env_library() override; void refresh_sources() override; public: diff --git a/src/xrSound/SoundRender_Emitter_streamer.cpp b/src/xrSound/SoundRender_Emitter_streamer.cpp index 7f41274858d..59f55354898 100644 --- a/src/xrSound/SoundRender_Emitter_streamer.cpp +++ b/src/xrSound/SoundRender_Emitter_streamer.cpp @@ -153,12 +153,10 @@ void CSoundRender_Emitter::fill_block(void* ptr, u32 size) u32 CSoundRender_Emitter::get_bytes_total() const { - u32 res = owner_data->dwBytesTotal; - return res; + return owner_data->dwBytesTotal; } float CSoundRender_Emitter::get_length_sec() const { - float res = owner_data->get_length_sec(); - return res; + return owner_data->fTimeTotal; } From 466fe12f50ec973e662f4816aa4a953007899bdb Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Tue, 5 Dec 2023 03:24:27 +0500 Subject: [PATCH 016/497] Fixed non-Windows build --- src/xrSound/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 4c00ee6f84a..fd5b2fcd77e 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -65,6 +65,14 @@ target_sources_grouped( SoundRender_Environment.h ) +target_sources_grouped( + TARGET xrSound + NAME "Scene" + FILES + SoundRender_Scene.cpp + SoundRender_Scene.h +) + target_sources_grouped( TARGET xrSound NAME "Kernel" From 28b8adeb881bfa9ea0edf362af0e3a903a679bd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:32:54 +0000 Subject: [PATCH 017/497] build(deps): bump Externals/sse2neon from `243e90f` to `232c221` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `243e90f` to `232c221`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/243e90f654193c97a691b1a53213d091e02eb631...232c22135ce5b0a953c4e8d3d2325cd27745f830) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 243e90f6541..232c22135ce 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 243e90f654193c97a691b1a53213d091e02eb631 +Subproject commit 232c22135ce5b0a953c4e8d3d2325cd27745f830 From c12e6e99ab07063745f33466a621cbc2236f38c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 19:13:41 +0500 Subject: [PATCH 018/497] build(deps): bump actions/labeler from 4.3.0 to 5.0.0 (#1561) [skip ci] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/labeler.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 4c243d34bde..22a843a144d 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -15,28 +15,28 @@ jobs: steps: - name: on new pull request if: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.opened == true || github.event.pull_request.reopened == true }} - uses: actions/labeler@v4.3.0 + uses: actions/labeler@v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler_on_new_pr.yml - name: on any pull request if: ${{ github.event_name == 'pull_request_target' }} - uses: actions/labeler@v4.3.0 + uses: actions/labeler@v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler.yml - name: on pull request approval if: ${{ github.event_name == 'pull_request_review' && github.event.review.state == 'approved' }} - uses: actions/labeler@v4.3.0 + uses: actions/labeler@v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler_on_pr_approved.yml - name: on pull request merged if: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.merged == true }} - uses: actions/labeler@v4.3.0 + uses: actions/labeler@v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler_on_pr_merged.yml From 44e8a31fe23382e54896011a4a98791a0a68e04e Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Thu, 14 Dec 2023 19:16:48 +0500 Subject: [PATCH 019/497] GitHub: mark changes in .github folder with Infrastructure label --- .github/labeler.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index c2d62f763a9..eadb617af6c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -11,6 +11,9 @@ External (3rd party): Game assets: - res/**/* +Infrastructure: +- .github/**/* + Physics: - src/xrPhysics/**/* From 9ab3acad5ee9acdc7948b2f701a10e5fdca81ae6 Mon Sep 17 00:00:00 2001 From: yohjimane Date: Thu, 14 Dec 2023 08:37:06 -0800 Subject: [PATCH 020/497] Move GameMtlLib to it's own xrMaterialSystem library (#1563) Co-authored-by: Xottab-DUTY --- src/CMakeLists.txt | 1 + .../xrRender/DetailManager_Decompress.cpp | 4 +- src/Layers/xrRenderPC_GL/CMakeLists.txt | 1 + src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj | 3 ++ src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj | 3 ++ src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj | 3 ++ src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj | 3 ++ src/engine.sln | 34 ++++++++++++ src/xrEngine/CMakeLists.txt | 9 ---- src/xrEngine/xrEngine.vcxproj | 3 -- src/xrEngine/xrEngine.vcxproj.filters | 12 ----- src/xrGame/Actor_Feel.cpp | 2 +- src/xrGame/CMakeLists.txt | 1 + src/xrGame/Car.cpp | 2 +- src/xrGame/ClimableObject.cpp | 2 +- src/xrGame/CustomRocket.cpp | 2 +- src/xrGame/Explosive.cpp | 2 +- src/xrGame/GamePersistent.cpp | 2 +- src/xrGame/HUDTarget.cpp | 2 +- src/xrGame/Level_bullet_manager_firetrace.cpp | 2 +- src/xrGame/Level_load.cpp | 2 +- src/xrGame/PHMovementControl.cpp | 2 +- src/xrGame/PHSoundPlayer.h | 2 +- src/xrGame/WeaponAmmo.cpp | 2 +- src/xrGame/WeaponKnife.cpp | 2 +- src/xrGame/entity_alive.cpp | 2 +- src/xrGame/ik_foot_collider.cpp | 2 +- src/xrGame/material_manager.h | 2 +- src/xrGame/physics_game.cpp | 2 +- src/xrGame/visual_memory_manager.cpp | 2 +- src/xrGame/wallmark_manager.cpp | 2 +- src/xrGame/xrGame.vcxproj | 3 ++ src/xrMaterialSystem/CMakeLists.txt | 43 +++++++++++++++ .../GameMtlLib.cpp | 3 -- .../GameMtlLib.h | 54 +++++++------------ .../GameMtlLib_Engine.cpp | 53 +++++++----------- src/xrMaterialSystem/stdafx.cpp | 1 + src/xrMaterialSystem/stdafx.h | 7 +++ src/xrMaterialSystem/xrMaterialSystem.vcxproj | 54 +++++++++++++++++++ .../xrMaterialSystem.vcxproj.filters | 33 ++++++++++++ src/xrPhysics/ActorCameraCollision.cpp | 1 - src/xrPhysics/CMakeLists.txt | 1 + src/xrPhysics/MovementBoxDynamicActivate.cpp | 1 - src/xrPhysics/PHActivationShape.cpp | 1 - src/xrPhysics/PHActorCharacter.cpp | 1 - src/xrPhysics/PHCharacter.cpp | 1 - src/xrPhysics/PHContactBodyEffector.cpp | 2 +- src/xrPhysics/PHGeometryOwner.h | 1 - src/xrPhysics/PHShell.cpp | 1 - src/xrPhysics/PHSimpleCharacter.cpp | 2 - src/xrPhysics/PHSimpleCharacter.h | 1 - src/xrPhysics/PHWorld.cpp | 1 - src/xrPhysics/Physics.cpp | 1 - src/xrPhysics/StdAfx.h | 2 +- src/xrPhysics/collisiondamagereceiver.cpp | 2 - .../tri-colliderknoopc/dSortTriPrimitive.h | 2 +- src/xrPhysics/xrPhysics.vcxproj | 3 ++ 57 files changed, 255 insertions(+), 135 deletions(-) create mode 100644 src/xrMaterialSystem/CMakeLists.txt rename src/{xrEngine => xrMaterialSystem}/GameMtlLib.cpp (98%) rename src/{xrEngine => xrMaterialSystem}/GameMtlLib.h (93%) rename src/{xrEngine => xrMaterialSystem}/GameMtlLib_Engine.cpp (65%) create mode 100644 src/xrMaterialSystem/stdafx.cpp create mode 100644 src/xrMaterialSystem/stdafx.h create mode 100644 src/xrMaterialSystem/xrMaterialSystem.vcxproj create mode 100644 src/xrMaterialSystem/xrMaterialSystem.vcxproj.filters diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ccece4ac50b..26d661147a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(xrCore) add_subdirectory(xrEngine) add_subdirectory(xrGame) add_subdirectory(xrGameSpy) +add_subdirectory(xrMaterialSystem) add_subdirectory(xrNetServer) add_subdirectory(xrParticles) add_subdirectory(xrPhysics) diff --git a/src/Layers/xrRender/DetailManager_Decompress.cpp b/src/Layers/xrRender/DetailManager_Decompress.cpp index 97448a8ae96..acd663f16e1 100644 --- a/src/Layers/xrRender/DetailManager_Decompress.cpp +++ b/src/Layers/xrRender/DetailManager_Decompress.cpp @@ -2,6 +2,8 @@ #pragma hdrstop #include "DetailManager.h" #include "xrCDB/Intersect.hpp" +#include "xrMaterialSystem/GameMtlLib.h" + #ifdef _EDITOR #include "scene.h" #include "sceneobject.h" @@ -66,8 +68,6 @@ bool det_render_debug = false; #endif #endif -#include "xrEngine/GameMtlLib.h" - //#define DBG_SWITCHOFF_RANDOMIZE void CDetailManager::cache_Decompress(Slot* S) { diff --git a/src/Layers/xrRenderPC_GL/CMakeLists.txt b/src/Layers/xrRenderPC_GL/CMakeLists.txt index 7e6ca92ee11..b9dfc698731 100644 --- a/src/Layers/xrRenderPC_GL/CMakeLists.txt +++ b/src/Layers/xrRenderPC_GL/CMakeLists.txt @@ -404,6 +404,7 @@ target_link_libraries(xrRender_GL xrCDB xrCore xrEngine + xrMaterialSystem xrParticles xrScriptEngine xrImGui diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj index 7635b07080e..377b39983d3 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj @@ -403,6 +403,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj index 35856689ea1..bc8efde6f44 100644 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj +++ b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj @@ -368,6 +368,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj index e685455f12e..492bf05ef2a 100644 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj +++ b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj @@ -413,6 +413,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj index f4411ea5e51..882eddac91a 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj @@ -476,6 +476,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + diff --git a/src/engine.sln b/src/engine.sln index 4de2a723221..9838b0abab9 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -199,6 +199,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLuaFix", "..\Externals\xr EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiscordGameSDK", "..\Externals\DiscordGameSDK\DiscordGameSDK.vcxproj", "{CFF9F0DD-C2FC-424C-800B-BFBA35003932}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrMaterialSystem", "xrMaterialSystem\xrMaterialSystem.vcxproj", "{2C419512-6EEE-4707-BC51-2E834855552E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -2060,6 +2062,38 @@ Global {CFF9F0DD-C2FC-424C-800B-BFBA35003932}.Release|x64.Build.0 = Release|x64 {CFF9F0DD-C2FC-424C-800B-BFBA35003932}.Release|x86.ActiveCfg = Release|Win32 {CFF9F0DD-C2FC-424C-800B-BFBA35003932}.Release|x86.Build.0 = Release|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|ARM.ActiveCfg = Debug|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|ARM.Build.0 = Debug|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|ARM64.Build.0 = Debug|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|x64.ActiveCfg = Debug|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|x64.Build.0 = Debug|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|x86.ActiveCfg = Debug|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Debug|x86.Build.0 = Debug|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|ARM.ActiveCfg = Mixed|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|ARM.Build.0 = Mixed|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|ARM64.Build.0 = Mixed|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|x64.ActiveCfg = Mixed|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|x64.Build.0 = Mixed|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|x86.ActiveCfg = Mixed|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Mixed|x86.Build.0 = Mixed|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|ARM.ActiveCfg = Release|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|ARM.Build.0 = Release|ARM + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|ARM64.ActiveCfg = Release|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|ARM64.Build.0 = Release|ARM64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|x64.ActiveCfg = Release|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|x64.Build.0 = Release|x64 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|x86.ActiveCfg = Release|Win32 + {2C419512-6EEE-4707-BC51-2E834855552E}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index eca685c6821..d2d93f108d5 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -204,15 +204,6 @@ target_sources_grouped( key_binding_registrator_script.cpp ) -target_sources_grouped( - TARGET xrEngine - NAME "Engine\\Game API\\MaterialSystem" - FILES - GameMtlLib.cpp - GameMtlLib.h - GameMtlLib_Engine.cpp -) - target_sources_grouped( TARGET xrEngine NAME "Engine\\Game API\\Objects" diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index 514a7f4effd..a95149ed169 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -53,7 +53,6 @@ - @@ -144,8 +143,6 @@ - - diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 7234c8a0641..5823069915d 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -124,9 +124,6 @@ {fe56b488-34f8-4632-9f5e-7805f761b338} - - {59004dc1-5e77-4968-8321-6290b1ab9d3a} - {6e4e4f2d-02fc-4141-9ae3-ca29550fc16d} @@ -345,9 +342,6 @@ OpenAutomate - - Game API\MaterialSystem - Render\Font output @@ -584,12 +578,6 @@ OpenAutomate - - Game API\MaterialSystem - - - Game API\MaterialSystem - Game API\Level diff --git a/src/xrGame/Actor_Feel.cpp b/src/xrGame/Actor_Feel.cpp index 26763e8e2b3..ab010c720d6 100644 --- a/src/xrGame/Actor_Feel.cpp +++ b/src/xrGame/Actor_Feel.cpp @@ -6,7 +6,7 @@ #include "character_info.h" #include "xrEngine/xr_level_controller.h" #include "CustomZone.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "ui/UIMainIngameWnd.h" #include "UIGameCustom.h" #include "Grenade.h" diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 4119b41c997..1949afd085a 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -2625,6 +2625,7 @@ target_link_libraries(xrGame PRIVATE xrCore xrEngine + xrMaterialSystem xrMiscMath xrImGui xrAPI diff --git a/src/xrGame/Car.cpp b/src/xrGame/Car.cpp index 7c0c2405c37..23ffb85c1aa 100644 --- a/src/xrGame/Car.cpp +++ b/src/xrGame/Car.cpp @@ -24,7 +24,7 @@ #include "ui/UIMainIngameWnd.h" #include "CarWeapon.h" #include "game_object_space.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "CharacterPhysicsSupport.h" #include "car_memory.h" diff --git a/src/xrGame/ClimableObject.cpp b/src/xrGame/ClimableObject.cpp index 0bdc57bb6e9..a01fdcd3ffd 100644 --- a/src/xrGame/ClimableObject.cpp +++ b/src/xrGame/ClimableObject.cpp @@ -5,7 +5,7 @@ #include "xrPhysics/PHCharacter.h" #include "xrPhysics/MathUtils.h" #include "xrPhysics/ExtendedGeom.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #ifdef DEBUG #include "debug_renderer.h" #include "Level.h" diff --git a/src/xrGame/CustomRocket.cpp b/src/xrGame/CustomRocket.cpp index d199676f393..c04259cbecc 100644 --- a/src/xrGame/CustomRocket.cpp +++ b/src/xrGame/CustomRocket.cpp @@ -13,7 +13,7 @@ #include "Level.h" #include "xrMessages.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Include/xrRender/RenderVisual.h" diff --git a/src/xrGame/Explosive.cpp b/src/xrGame/Explosive.cpp index 29e366d5987..ff6a41591c1 100644 --- a/src/xrGame/Explosive.cpp +++ b/src/xrGame/Explosive.cpp @@ -19,7 +19,7 @@ #include "Level.h" #include "Level_Bullet_Manager.h" #include "xrMessages.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #ifdef DEBUG #include "xrEngine/StatGraph.h" diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 89afbb22d5d..f7c507fda0a 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -2,7 +2,7 @@ #include "GamePersistent.h" #include "xrCore/FMesh.hpp" #include "xrEngine/XR_IOConsole.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Include/xrRender/Kinematics.h" #include "xrEngine/profiler.h" #include "MainMenu.h" diff --git a/src/xrGame/HUDTarget.cpp b/src/xrGame/HUDTarget.cpp index 3a953e49955..a046025a6c4 100644 --- a/src/xrGame/HUDTarget.cpp +++ b/src/xrGame/HUDTarget.cpp @@ -1,6 +1,6 @@ #include "StdAfx.h" #include "HUDTarget.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrEngine/Environment.h" #include "xrEngine/CustomHUD.h" diff --git a/src/xrGame/Level_bullet_manager_firetrace.cpp b/src/xrGame/Level_bullet_manager_firetrace.cpp index 5b36c7c23fd..f5d79488e81 100644 --- a/src/xrGame/Level_bullet_manager_firetrace.cpp +++ b/src/xrGame/Level_bullet_manager_firetrace.cpp @@ -6,7 +6,7 @@ #include "StdAfx.h" #include "Level_Bullet_Manager.h" #include "Entity.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Level.h" #include "GamePersistent.h" #include "game_cl_base.h" diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index b2b7c8cf44e..0adfde3720a 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -7,7 +7,7 @@ #include "Level.h" #include "game_cl_base.h" #include "xrEngine/x_ray.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrPhysics/PhysicsCommon.h" #include "level_sounds.h" #include "GamePersistent.h" diff --git a/src/xrGame/PHMovementControl.cpp b/src/xrGame/PHMovementControl.cpp index c07ce222bd6..af825c255aa 100644 --- a/src/xrGame/PHMovementControl.cpp +++ b/src/xrGame/PHMovementControl.cpp @@ -15,7 +15,7 @@ #include "xrPhysics/IPHWorld.h" #include "detail_path_manager.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrEngine/xr_object.h" #include "CaptureBoneCallback.h" #include "Level.h" diff --git a/src/xrGame/PHSoundPlayer.h b/src/xrGame/PHSoundPlayer.h index 460c2d87709..2b16c8686f4 100644 --- a/src/xrGame/PHSoundPlayer.h +++ b/src/xrGame/PHSoundPlayer.h @@ -1,5 +1,5 @@ #pragma once -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" class CPhysicsShellHolder; diff --git a/src/xrGame/WeaponAmmo.cpp b/src/xrGame/WeaponAmmo.cpp index ec696d4ad4a..0a8b32bae46 100644 --- a/src/xrGame/WeaponAmmo.cpp +++ b/src/xrGame/WeaponAmmo.cpp @@ -7,7 +7,7 @@ #include "Weapon.h" #include "Level_Bullet_Manager.h" #include "ai_space.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Level.h" #define BULLET_MANAGER_SECTION "bullet_manager" diff --git a/src/xrGame/WeaponKnife.cpp b/src/xrGame/WeaponKnife.cpp index a19abd2cf54..df68d3058b9 100644 --- a/src/xrGame/WeaponKnife.cpp +++ b/src/xrGame/WeaponKnife.cpp @@ -7,7 +7,7 @@ #include "xrEngine/xr_level_controller.h" #include "game_cl_base.h" #include "Include/xrRender/Kinematics.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Level_Bullet_Manager.h" #include "ai_sounds.h" #include "game_cl_single.h" diff --git a/src/xrGame/entity_alive.cpp b/src/xrGame/entity_alive.cpp index 1bcf58e2853..d5f37cdcaf7 100644 --- a/src/xrGame/entity_alive.cpp +++ b/src/xrGame/entity_alive.cpp @@ -3,7 +3,7 @@ #include "InventoryOwner.h" #include "Inventory.h" #include "xrPhysics/PhysicsShell.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "PHMovementControl.h" #include "Wound.h" #include "xrMessages.h" diff --git a/src/xrGame/ik_foot_collider.cpp b/src/xrGame/ik_foot_collider.cpp index 3802bf656a7..01bf286ba0f 100644 --- a/src/xrGame/ik_foot_collider.cpp +++ b/src/xrGame/ik_foot_collider.cpp @@ -1,7 +1,7 @@ #include "StdAfx.h" #include "ik_foot_collider.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrCDB/Intersect.hpp" #include "Include/xrRender/Kinematics.h" diff --git a/src/xrGame/material_manager.h b/src/xrGame/material_manager.h index 43e8486c0f5..35914e6766b 100644 --- a/src/xrGame/material_manager.h +++ b/src/xrGame/material_manager.h @@ -8,7 +8,7 @@ #pragma once -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "PHMovementControl.h" class CPHMovementControl; diff --git a/src/xrGame/physics_game.cpp b/src/xrGame/physics_game.cpp index 1e1af2198ff..ca9ce08f101 100644 --- a/src/xrGame/physics_game.cpp +++ b/src/xrGame/physics_game.cpp @@ -1,6 +1,6 @@ #include "StdAfx.h" #include "ParticlesObject.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "Level.h" #include "GamePersistent.h" #include "xrPhysics/ExtendedGeom.h" diff --git a/src/xrGame/visual_memory_manager.cpp b/src/xrGame/visual_memory_manager.cpp index 5900e719e32..cc2cec36e83 100644 --- a/src/xrGame/visual_memory_manager.cpp +++ b/src/xrGame/visual_memory_manager.cpp @@ -15,7 +15,7 @@ #include "xrAICore/Navigation/ai_object_location.h" #include "xrAICore/Navigation/level_graph.h" #include "stalker_movement_manager_smart_cover.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "agent_manager.h" #include "agent_member_manager.h" #include "ai_space.h" diff --git a/src/xrGame/wallmark_manager.cpp b/src/xrGame/wallmark_manager.cpp index 7be8fd5d4dd..89985a6077b 100644 --- a/src/xrGame/wallmark_manager.cpp +++ b/src/xrGame/wallmark_manager.cpp @@ -1,7 +1,7 @@ #include "StdAfx.h" #include "wallmark_manager.h" #include "Level.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrPhysics/CalculateTriangle.h" #include "xrEngine/profiler.h" #ifdef DEBUG diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index ad49dfa564e..5b856169444 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -3531,6 +3531,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + diff --git a/src/xrMaterialSystem/CMakeLists.txt b/src/xrMaterialSystem/CMakeLists.txt new file mode 100644 index 00000000000..f0ee8cc20ce --- /dev/null +++ b/src/xrMaterialSystem/CMakeLists.txt @@ -0,0 +1,43 @@ +add_library(xrMaterialSystem SHARED) + +target_sources_grouped( + TARGET xrMaterialSystem + NAME "Kernel" + FILES + GameMtlLib.cpp + GameMtlLib.h + GameMtlLib_Engine.cpp +) + +target_include_directories(xrMaterialSystem + PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" +) + +target_link_libraries(xrMaterialSystem + PUBLIC + xrMiscMath + + PRIVATE + xrAPI + xrCore +) + +target_compile_definitions(xrMaterialSystem + PRIVATE + XRMTL_LIB_EXPORTS +) + +set_target_properties(xrMaterialSystem PROPERTIES + PREFIX "" +) + +target_precompile_headers(xrMaterialSystem + PRIVATE + stdafx.h +) + +install(TARGETS xrMaterialSystem LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) diff --git a/src/xrEngine/GameMtlLib.cpp b/src/xrMaterialSystem/GameMtlLib.cpp similarity index 98% rename from src/xrEngine/GameMtlLib.cpp rename to src/xrMaterialSystem/GameMtlLib.cpp index fdd6f6b61f9..9447e1e64fb 100644 --- a/src/xrEngine/GameMtlLib.cpp +++ b/src/xrMaterialSystem/GameMtlLib.cpp @@ -3,9 +3,6 @@ #include "Common/FSMacros.hpp" CGameMtlLibrary GMLib; -#ifdef _EDITOR -CGameMtlLibrary* PGMLib = nullptr; -#endif #ifdef DEBUG const char* SGameMtlPair::dbg_Name() diff --git a/src/xrEngine/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h similarity index 93% rename from src/xrEngine/GameMtlLib.h rename to src/xrMaterialSystem/GameMtlLib.h index 834d3219606..9fd9c01fa31 100644 --- a/src/xrEngine/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -1,15 +1,18 @@ #pragma once -#include - #include "xrCore/xrstring.h" #include "xrCore/_flags.h" #include "xrCommon/xr_vector.h" -#include "Common/Platform.hpp" -// fwd. decl. -class IReader; -class IWriter; +#include "xrSound/Sound.h" +#include "Include/xrRender/WallMarkArray.h" +#include "Include/xrRender/RenderFactory.h" + +#ifdef XRMTL_LIB_EXPORTS +#define MTL_EXPORT_API XR_EXPORT +#else +#define MTL_EXPORT_API XR_IMPORT +#endif #define GAMEMTL_CURRENT_VERSION 0x0001 @@ -39,30 +42,12 @@ class IWriter; #define GAMEMTL_NONE_ID u32(-1) #define GAMEMTL_NONE_IDX u16(-1) -#define GAMEMTL_FILENAME "gamemtl.xr" - -#ifndef GM_NON_GAME -#if defined(_EDITOR) || defined(_MAX_PLUGIN) || defined(_LW_SHADER) || defined(_MAYA_PLUGIN) -#define GM_NON_GAME -#endif -#endif - -#ifndef MTL_EXPORT_API -#ifdef _EDITOR -//#include "ElTree.hpp" -#define MTL_EXPORT_API ECORE_API -#else -#define MTL_EXPORT_API ENGINE_API -#endif -#endif -#ifndef GM_NON_GAME -#include "xrSound/Sound.h" -#include "Include/xrRender/WallMarkArray.h" -#include "Include/xrRender/RenderFactory.h" -#endif +constexpr pcstr GAMEMTL_FILENAME = "gamemtl.xr"; -// XXX: Place at least CGameMtlLibrary in a static lib or something? It currently gets instantiated a measurable amount of times. +// fwd. decl. +class IReader; +class IWriter; struct MTL_EXPORT_API SGameMtl { @@ -172,19 +157,12 @@ struct MTL_EXPORT_API SGameMtlPair Flags32 OwnProps; public: -#ifdef GM_NON_GAME - shared_str BreakingSounds; - shared_str StepSounds; - shared_str CollideSounds; - shared_str CollideParticles; - shared_str CollideMarks; -#else xr_vector BreakingSounds; xr_vector StepSounds; xr_vector CollideSounds; xr_vector CollideParticles; FactoryPtr CollideMarks; -#endif + public: SGameMtlPair(CGameMtlLibrary* owner) { @@ -196,6 +174,7 @@ struct MTL_EXPORT_API SGameMtlPair OwnProps.one(); } ~SGameMtlPair(); + int GetMtl0() const { return mtl0; } int GetMtl1() const { return mtl1; } int GetID() const { return ID; } @@ -214,6 +193,7 @@ struct MTL_EXPORT_API SGameMtlPair #ifdef DEBUG const char* dbg_Name(); #endif + #ifdef _EDITOR PropValue* propBreakingSounds; PropValue* propStepSounds; @@ -311,6 +291,7 @@ class MTL_EXPORT_API CGameMtlLibrary GameMtlIt FirstMaterial() { return materials.begin(); } GameMtlIt LastMaterial() { return materials.end(); } u32 CountMaterial() const { return materials.size(); } + #ifdef EDITOR SGameMtl* AppendMaterial(SGameMtl* parent); void RemoveMaterial(pcstr name); @@ -332,6 +313,7 @@ class MTL_EXPORT_API CGameMtlLibrary SGameMtlPair* GetMaterialPair(int mtl0, int mtl1); SGameMtlPair* GetMaterialPair(const char* name); #endif + // game SGameMtlPair* GetMaterialPairByIndices(u16 i0, u16 i1) const { diff --git a/src/xrEngine/GameMtlLib_Engine.cpp b/src/xrMaterialSystem/GameMtlLib_Engine.cpp similarity index 65% rename from src/xrEngine/GameMtlLib_Engine.cpp rename to src/xrMaterialSystem/GameMtlLib_Engine.cpp index e4302c9d733..66b9bb7c230 100644 --- a/src/xrEngine/GameMtlLib_Engine.cpp +++ b/src/xrMaterialSystem/GameMtlLib_Engine.cpp @@ -1,64 +1,64 @@ #include "stdafx.h" #include "GameMtlLib.h" -#ifndef GM_NON_GAME - -static void DestroySounds(xr_vector& lst) +namespace +{ +void DestroySounds(xr_vector& lst) { for (auto it : lst) it.destroy(); } -static void DestroyPSs(xr_vector& lst) {} -static void CreateSounds(xr_vector& lst, pcstr buf) +void DestroyPSs(xr_vector& lst) {} +void CreateSounds(xr_vector& lst, pcstr buf) { string128 tmp; - int cnt = _GetItemCount(buf); + const int cnt = _GetItemCount(buf); R_ASSERT(cnt <= GAMEMTL_SUBITEM_COUNT + 2); lst.resize(cnt); for (int k = 0; k < cnt; ++k) lst[k].create(_GetItem(buf, k, tmp), st_Effect, sg_SourceType); } -static void CreateMarks(IWallMarkArray* pMarks, pcstr buf) +void CreateMarks(IWallMarkArray* pMarks, pcstr buf) { string256 tmp; - int cnt = _GetItemCount(buf); + const int cnt = _GetItemCount(buf); R_ASSERT(cnt <= GAMEMTL_SUBITEM_COUNT); for (int k = 0; k < cnt; ++k) pMarks->AppendMark(_GetItem(buf, k, tmp)); } -static void CreatePSs(xr_vector& lst, pcstr buf) +void CreatePSs(xr_vector& lst, pcstr buf) { string256 tmp; - int cnt = _GetItemCount(buf); + const int cnt = _GetItemCount(buf); R_ASSERT(cnt <= GAMEMTL_SUBITEM_COUNT); for (int k = 0; k < cnt; ++k) - lst.push_back(_GetItem(buf, k, tmp)); + lst.emplace_back(_GetItem(buf, k, tmp)); +} } -#endif SGameMtlPair::~SGameMtlPair() { -#ifndef GM_NON_GAME // destroy all media DestroySounds(BreakingSounds); DestroySounds(StepSounds); DestroySounds(CollideSounds); DestroyPSs(CollideParticles); -#endif } void SGameMtlPair::Load(IReader& fs) { shared_str buf; + R_ASSERT(fs.find_chunk(GAMEMTLPAIR_CHUNK_PAIR)); mtl0 = fs.r_u32(); mtl1 = fs.r_u32(); ID = fs.r_u32(); ID_parent = fs.r_u32(); u32 own_mask = fs.r_u32(); + // XXX: recheck below when we will be integrating EDITOR #ifdef GM_NON_GAME if (GAMEMTL_NONE_ID == ID_parent) OwnProps.one(); @@ -67,37 +67,22 @@ void SGameMtlPair::Load(IReader& fs) #else OwnProps.assign(own_mask); #endif + R_ASSERT(fs.find_chunk(GAMEMTLPAIR_CHUNK_BREAKING)); fs.r_stringZ(buf); -#ifdef GM_NON_GAME - BreakingSounds = *buf ? *buf : ""; -#else CreateSounds(BreakingSounds, *buf); -#endif + R_ASSERT(fs.find_chunk(GAMEMTLPAIR_CHUNK_STEP)); fs.r_stringZ(buf); -#ifdef GM_NON_GAME - StepSounds = *buf ? *buf : ""; -#else CreateSounds(StepSounds, *buf); -#endif + R_ASSERT(fs.find_chunk(GAMEMTLPAIR_CHUNK_COLLIDE)); fs.r_stringZ(buf); -#ifdef GM_NON_GAME - CollideSounds = *buf ? *buf : ""; -#else CreateSounds(CollideSounds, *buf); -#endif + fs.r_stringZ(buf); -#ifdef GM_NON_GAME - CollideParticles = *buf ? *buf : ""; -#else CreatePSs(CollideParticles, *buf); -#endif + fs.r_stringZ(buf); -#ifdef GM_NON_GAME - CollideMarks = *buf ? *buf : ""; -#else CreateMarks(&*CollideMarks, *buf); -#endif } diff --git a/src/xrMaterialSystem/stdafx.cpp b/src/xrMaterialSystem/stdafx.cpp new file mode 100644 index 00000000000..fd4f341c7b2 --- /dev/null +++ b/src/xrMaterialSystem/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/src/xrMaterialSystem/stdafx.h b/src/xrMaterialSystem/stdafx.h new file mode 100644 index 00000000000..862b3958234 --- /dev/null +++ b/src/xrMaterialSystem/stdafx.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Common/Common.hpp" + +#include "xrCore/xrCore.h" + +#include "GameMtlLib.h" diff --git a/src/xrMaterialSystem/xrMaterialSystem.vcxproj b/src/xrMaterialSystem/xrMaterialSystem.vcxproj new file mode 100644 index 00000000000..be399e6c483 --- /dev/null +++ b/src/xrMaterialSystem/xrMaterialSystem.vcxproj @@ -0,0 +1,54 @@ + + + + + + + 16.0 + Win32Proj + {2c419512-6eee-4707-bc51-2e834855552e} + xrMaterialSystem + + + + + + + + + + + + + + + + XRMTL_LIB_EXPORTS;%(PreprocessorDefinitions) + + + + + + + + + + + Create + + + + + + + + {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} + + + {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} + + + + + + \ No newline at end of file diff --git a/src/xrMaterialSystem/xrMaterialSystem.vcxproj.filters b/src/xrMaterialSystem/xrMaterialSystem.vcxproj.filters new file mode 100644 index 00000000000..a78bfc32204 --- /dev/null +++ b/src/xrMaterialSystem/xrMaterialSystem.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {fd90ae41-f0eb-41be-bbc6-2b14a4fcc3f2} + + + {58571d13-01a3-494c-a79e-4a471d32201b} + + + + + Kernel + + + PCH + + + + + Kernel + + + Kernel + + + PCH + + + + + + \ No newline at end of file diff --git a/src/xrPhysics/ActorCameraCollision.cpp b/src/xrPhysics/ActorCameraCollision.cpp index 94bc63718eb..04b3696e311 100644 --- a/src/xrPhysics/ActorCameraCollision.cpp +++ b/src/xrPhysics/ActorCameraCollision.cpp @@ -3,7 +3,6 @@ #include "ActorCameraCollision.h" #include "xrEngine/CameraBase.h" -#include "xrEngine/GameMtlLib.h" #include "PHShell.h" #include "matrix_utils.h" diff --git a/src/xrPhysics/CMakeLists.txt b/src/xrPhysics/CMakeLists.txt index c46cc9ac55d..b072f9150ea 100644 --- a/src/xrPhysics/CMakeLists.txt +++ b/src/xrPhysics/CMakeLists.txt @@ -407,6 +407,7 @@ target_link_libraries(xrPhysics PRIVATE xrCore xrEngine + xrMaterialSystem xrMiscMath xrScriptEngine xrAPI diff --git a/src/xrPhysics/MovementBoxDynamicActivate.cpp b/src/xrPhysics/MovementBoxDynamicActivate.cpp index 4119a8b3e71..79d2842e704 100644 --- a/src/xrPhysics/MovementBoxDynamicActivate.cpp +++ b/src/xrPhysics/MovementBoxDynamicActivate.cpp @@ -9,7 +9,6 @@ #include "MathUtilsOde.h" #include "IPhysicsShellHolder.h" #include "PHCharacter.h" -#include "xrEngine/GameMtlLib.h" namespace detail::movement_box { diff --git a/src/xrPhysics/PHActivationShape.cpp b/src/xrPhysics/PHActivationShape.cpp index ab206dd21cf..8f6d4f79413 100644 --- a/src/xrPhysics/PHActivationShape.cpp +++ b/src/xrPhysics/PHActivationShape.cpp @@ -8,7 +8,6 @@ #include "ExtendedGeom.h" #include "SpaceUtils.h" #include "MathUtils.h" -#include "xrEngine/GameMtlLib.h" #include "PHWorld.h" #include "ode/ode/src/util.h" diff --git a/src/xrPhysics/PHActorCharacter.cpp b/src/xrPhysics/PHActorCharacter.cpp index 4327c860854..3610155de9f 100644 --- a/src/xrPhysics/PHActorCharacter.cpp +++ b/src/xrPhysics/PHActorCharacter.cpp @@ -5,7 +5,6 @@ #include "IPhysicsShellHolder.h" -#include "xrEngine/GameMtlLib.h" // const float JUMP_HIGHT=0.5; const float JUMP_UP_VELOCITY = 6.0f; // 5.6f; diff --git a/src/xrPhysics/PHCharacter.cpp b/src/xrPhysics/PHCharacter.cpp index c9336ee6c20..13de41315ff 100644 --- a/src/xrPhysics/PHCharacter.cpp +++ b/src/xrPhysics/PHCharacter.cpp @@ -7,7 +7,6 @@ #include "IPhysicsShellHolder.h" #include "xrCDB/Intersect.hpp" -#include "xrEngine/GameMtlLib.h" #include "tri-colliderknoopc/__aabb_tri.h" #include "ode/ode/src/util.h" diff --git a/src/xrPhysics/PHContactBodyEffector.cpp b/src/xrPhysics/PHContactBodyEffector.cpp index d4c1516f2b4..c6013947df5 100644 --- a/src/xrPhysics/PHContactBodyEffector.cpp +++ b/src/xrPhysics/PHContactBodyEffector.cpp @@ -3,8 +3,8 @@ #include "ExtendedGeom.h" #include "tri-colliderknoopc/dTriList.h" #include "PhysicsCommon.h" -#include "xrEngine/GameMtlLib.h" #include "MathUtilsOde.h" + void CPHContactBodyEffector::Init(dBodyID body, const dContact& contact, SGameMtl* material) { CPHBaseBodyEffector::Init(body); diff --git a/src/xrPhysics/PHGeometryOwner.h b/src/xrPhysics/PHGeometryOwner.h index 60ca1f9dad7..3e2a0f2d0f5 100644 --- a/src/xrPhysics/PHGeometryOwner.h +++ b/src/xrPhysics/PHGeometryOwner.h @@ -1,7 +1,6 @@ #pragma once #include "Geometry.h" -#include "xrEngine/GameMtlLib.h" using GEOM_STORAGE = xr_vector; using GEOM_I = GEOM_STORAGE::iterator; diff --git a/src/xrPhysics/PHShell.cpp b/src/xrPhysics/PHShell.cpp index cb08592b6bd..e3ed8eafb44 100644 --- a/src/xrPhysics/PHShell.cpp +++ b/src/xrPhysics/PHShell.cpp @@ -13,7 +13,6 @@ #include "Include/xrRender/Kinematics.h" #include "PHCollideValidator.h" #include "xrCore/Animation/Bone.hpp" -#include "xrEngine/GameMtlLib.h" #include "ExtendedGeom.h" #include "PHElement.h" diff --git a/src/xrPhysics/PHSimpleCharacter.cpp b/src/xrPhysics/PHSimpleCharacter.cpp index 78c0979b2c8..7bf50d2da5c 100644 --- a/src/xrPhysics/PHSimpleCharacter.cpp +++ b/src/xrPhysics/PHSimpleCharacter.cpp @@ -13,8 +13,6 @@ #include "params.h" #include "MathUtils.h" -#include "xrEngine/GameMtlLib.h" - #include "IPhysicsShellHolder.h" #include "Include/xrRender/Kinematics.h" #include "PHSimpleCharacterInline.h" diff --git a/src/xrPhysics/PHSimpleCharacter.h b/src/xrPhysics/PHSimpleCharacter.h index df93a613bc8..7cecfb274b6 100644 --- a/src/xrPhysics/PHSimpleCharacter.h +++ b/src/xrPhysics/PHSimpleCharacter.h @@ -4,7 +4,6 @@ #include "MathUtils.h" #include "ElevatorState.h" #include "IColisiondamageInfo.h" -#include "xrEngine/GameMtlLib.h" #include "xrCDB/xr_collide_defs.h" namespace ALife diff --git a/src/xrPhysics/PHWorld.cpp b/src/xrPhysics/PHWorld.cpp index d53b4b791e1..50199c5eb10 100644 --- a/src/xrPhysics/PHWorld.cpp +++ b/src/xrPhysics/PHWorld.cpp @@ -7,7 +7,6 @@ #include "ExtendedGeom.h" #include "dRayMotions.h" #include "PHCollideValidator.h" -#include "xrEngine/GameMtlLib.h" #include "xrEngine/device.h" #include "xrEngine/GameFont.h" #include "xrEngine/PerformanceAlert.hpp" diff --git a/src/xrPhysics/Physics.cpp b/src/xrPhysics/Physics.cpp index 4606f24c610..b5fa1a1f3f6 100644 --- a/src/xrPhysics/Physics.cpp +++ b/src/xrPhysics/Physics.cpp @@ -6,7 +6,6 @@ #include "Physics.h" #include "tri-colliderknoopc/dTriList.h" #include "PHContactBodyEffector.h" -#include "xrEngine/GameMtlLib.h" #include "PHCollideValidator.h" #ifdef DEBUG diff --git a/src/xrPhysics/StdAfx.h b/src/xrPhysics/StdAfx.h index 998f9639e03..b0a3628a7f5 100644 --- a/src/xrPhysics/StdAfx.h +++ b/src/xrPhysics/StdAfx.h @@ -12,7 +12,7 @@ #include "xrCDB/xrCDB.h" #include "xrSound/Sound.h" -#include "xrEngine/GameMtlLib.h" +#include "xrMaterialSystem/GameMtlLib.h" #include "xrCore/_std_extensions.h" #include "xrPhysics.h" diff --git a/src/xrPhysics/collisiondamagereceiver.cpp b/src/xrPhysics/collisiondamagereceiver.cpp index 1726918f7f2..1344c01584d 100644 --- a/src/xrPhysics/collisiondamagereceiver.cpp +++ b/src/xrPhysics/collisiondamagereceiver.cpp @@ -6,8 +6,6 @@ #include "ExtendedGeom.h" #include "MathUtilsOde.h" -#include "xrEngine/GameMtlLib.h" - void DamageReceiverCollisionCallback(bool& do_colide, bool bo1, dContact& c, SGameMtl* material_1, SGameMtl* material_2) { if (material_1->Flags.test(SGameMtl::flPassable) || material_2->Flags.test(SGameMtl::flPassable)) diff --git a/src/xrPhysics/tri-colliderknoopc/dSortTriPrimitive.h b/src/xrPhysics/tri-colliderknoopc/dSortTriPrimitive.h index 00fa2a0bf09..6d64905c8f1 100644 --- a/src/xrPhysics/tri-colliderknoopc/dSortTriPrimitive.h +++ b/src/xrPhysics/tri-colliderknoopc/dSortTriPrimitive.h @@ -8,7 +8,7 @@ #include "xrPhysics/console_vars.h" #include "xrPhysics/PHWorld.h" #include "xrCDB/xr_area.h" -#include "xrEngine/GameMtlLib.h" + #ifdef DEBUG #include "xrPhysics/debug_output.h" #endif diff --git a/src/xrPhysics/xrPhysics.vcxproj b/src/xrPhysics/xrPhysics.vcxproj index e895a62d749..9d8cefd2118 100644 --- a/src/xrPhysics/xrPhysics.vcxproj +++ b/src/xrPhysics/xrPhysics.vcxproj @@ -216,6 +216,9 @@ {2578c6d8-660d-48ae-9322-7422f8664f06} + + {2c419512-6eee-4707-bc51-2e834855552e} + From 71d2527dbc5f80383045edd56315e32f95a61fd4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 14 Dec 2023 21:45:07 +0500 Subject: [PATCH 021/497] engine.sln: clean up build dependencies These dependencies are formed automatically via MSBuild projects references --- src/engine.sln | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/src/engine.sln b/src/engine.sln index 9838b0abab9..8e4578d7cf3 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -9,7 +9,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XR_3DA", "xr_3da\xr_3da.vcx {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} = {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} {963BA4E5-499A-454D-B002-1D5ECE0527A6} = {963BA4E5-499A-454D-B002-1D5ECE0527A6} {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} = {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} - {492D3DFE-9068-4E7E-A008-7C2420A651C0} = {492D3DFE-9068-4E7E-A008-7C2420A651C0} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B}" @@ -27,45 +26,22 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctool", "utils\ctool\ctool.vcxproj", "{2FAAC8BA-369F-465E-B465-2235963FD377}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ETools", "utils\ETools\ETools.vcxproj", "{65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}" - ProjectSection(ProjectDependencies) = postProject - {3A214E06-B95E-4D61-A291-1F8DF2EC10FD} = {3A214E06-B95E-4D61-A291-1F8DF2EC10FD} - {CEBDE98B-A6AA-46E6-BC79-FAAF823DB9EC} = {CEBDE98B-A6AA-46E6-BC79-FAAF823DB9EC} - {15CBFEFF-7965-41F5-B4E2-21E8795C9159} = {15CBFEFF-7965-41F5-B4E2-21E8795C9159} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrAI", "utils\xrAI\xrAI.vcxproj", "{EA5932F3-02FE-4AD3-89E8-7072DC465D25}" - ProjectSection(ProjectDependencies) = postProject - {B90BDC22-A891-4B33-B562-29D701F65DBD} = {B90BDC22-A891-4B33-B562-29D701F65DBD} - {2578C6D8-660D-48AE-9322-7422F8664F06} = {2578C6D8-660D-48AE-9322-7422F8664F06} - {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} = {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} - {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} = {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCompress", "utils\xrCompress\xrCompress.vcxproj", "{EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrDO_Light", "utils\xrDO_Light\xrDO_Light.vcxproj", "{B730F54D-1199-481A-AAD0-5DB684E067C0}" - ProjectSection(ProjectDependencies) = postProject - {EFB76D6F-0092-439C-A783-C0BE10BD17C9} = {EFB76D6F-0092-439C-A783-C0BE10BD17C9} - {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} = {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} - {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} = {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXT", "utils\xrDXT\DXT.vcxproj", "{EBF9B543-0830-4866-9B48-DC0740E87E8A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC", "utils\xrLC\xrLC.vcxproj", "{A4ABD75E-825B-4D09-B3B2-2709682E40C8}" - ProjectSection(ProjectDependencies) = postProject - {EFB76D6F-0092-439C-A783-C0BE10BD17C9} = {EFB76D6F-0092-439C-A783-C0BE10BD17C9} - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33} = {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrQSlim", "utils\xrQSlim\xrQSlim.vcxproj", "{F1836CE2-59EF-4189-8B9C-D103A511CB27}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrSE_Factory", "utils\xrSE_Factory\xrSE_Factory.vcxproj", "{3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCDB", "xrCDB\xrCDB.vcxproj", "{A19B1DF2-82EC-4364-8BDF-85D13A1C89B5}" - ProjectSection(ProjectDependencies) = postProject - {DAFD6D98-3DCD-40AD-BC85-EC71797B6767} = {DAFD6D98-3DCD-40AD-BC85-EC71797B6767} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCore", "xrCore\xrCore.vcxproj", "{A0F7D1FB-59A7-4717-A7E4-96F37E91998E}" EndProject @@ -91,10 +67,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrEngine", "xrEngine\xrEngine.vcxproj", "{2578C6D8-660D-48AE-9322-7422F8664F06}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC_Light", "utils\xrLC_Light\xrLC_Light.vcxproj", "{EFB76D6F-0092-439C-A783-C0BE10BD17C9}" - ProjectSection(ProjectDependencies) = postProject - {B90BDC22-A891-4B33-B562-29D701F65DBD} = {B90BDC22-A891-4B33-B562-29D701F65DBD} - {EBF9B543-0830-4866-9B48-DC0740E87E8A} = {EBF9B543-0830-4866-9B48-DC0740E87E8A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC_LightStab", "utils\xrLC_LightStab\xrLC_LightStab.vcxproj", "{EC924B9B-4991-4931-8623-E1DB9AE005CA}" EndProject @@ -123,25 +95,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luabind", "..\Externals\luabind.vcxproj", "{CCD4AFAE-AA10-42C6-A452-FDEE497CCDF1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Common\Common.vcxproj", "{EDB0DFAF-5D6F-4D74-AE66-0DDADE12A7F6}" - ProjectSection(ProjectDependencies) = postProject - {1DAEC516-E52C-4A3C-A4DA-AE3553E6E0F8} = {1DAEC516-E52C-4A3C-A4DA-AE3553E6E0F8} - {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {0899B131-F1D4-4876-9BA1-67AC821DB9E1} - {7885CF3C-EE04-4C67-9467-1FBF9A36B037} = {7885CF3C-EE04-4C67-9467-1FBF9A36B037} - {98D24A3D-7666-4C11-9D6E-B10393CE8CBA} = {98D24A3D-7666-4C11-9D6E-B10393CE8CBA} - {CCCA7859-EB86-493E-9B53-C4235F45B3C5} = {CCCA7859-EB86-493E-9B53-C4235F45B3C5} - {94A1C366-3D19-48E6-8170-4ADC2E70DF97} = {94A1C366-3D19-48E6-8170-4ADC2E70DF97} - {435BAC9A-B225-457D-AB40-C9BD0CC8838C} = {435BAC9A-B225-457D-AB40-C9BD0CC8838C} - {200652A6-043E-4634-8837-87983B3BD5E0} = {200652A6-043E-4634-8837-87983B3BD5E0} - {5535F6B4-7AE6-4B66-8AEA-CC31C14D7AB7} = {5535F6B4-7AE6-4B66-8AEA-CC31C14D7AB7} - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} = {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} - {5CB057D8-4464-40A6-AF10-C26B826D1D90} = {5CB057D8-4464-40A6-AF10-C26B826D1D90} - {2578C6D8-660D-48AE-9322-7422F8664F06} = {2578C6D8-660D-48AE-9322-7422F8664F06} - {132C62DE-DE85-4978-9675-C78ED4DA46F0} = {132C62DE-DE85-4978-9675-C78ED4DA46F0} - {963BA4E5-499A-454D-B002-1D5ECE0527A6} = {963BA4E5-499A-454D-B002-1D5ECE0527A6} - {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} = {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} - {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} = {A19B1DF2-82EC-4364-8BDF-85D13A1C89B5} - {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} = {A0F7D1FB-59A7-4717-A7E4-96F37E91998E} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GameSpy", "..\Externals\GameSpy.vcxproj", "{67FF193E-2C20-402A-9026-9F5F6327503C}" EndProject From 09156fbf58b0af91f1cccb1d3560bdd75ca59c05 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 5 Dec 2023 00:19:15 +0500 Subject: [PATCH 022/497] xrCore: detect more CPU intrinsics --- src/xrCore/_math.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- src/xrCore/_math.h | 4 ++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 4414234e0a5..3c3abf95773 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -184,7 +184,26 @@ void initialize() namespace CPU { -XRCORE_API bool HasSSE = SDL_HasSSE(); +XRCORE_API bool HasSSE = SDL_HasSSE(); +XRCORE_API bool HasSSE41 = SDL_HasSSE41(); + +#if SDL_VERSION_ATLEAST(2, 0, 6) +XRCORE_API bool HasAVX = SDL_HasAVX(); +#else +XRCORE_API bool HasAVX = false(); +#endif + +#if SDL_VERSION_ATLEAST(2, 0, 9) +XRCORE_API bool HasAVX2 = SDL_HasAVX2(); +#else +XRCORE_API bool HasAVX2 = false; +#endif + +#if SDL_VERSION_ATLEAST(2, 0, 9) +XRCORE_API bool HasAVX512F = SDL_HasAVX512F(); +#else +XRCORE_API bool HasAVX512F = false; +#endif XRCORE_API u64 qpc_freq = SDL_GetPerformanceFrequency(); @@ -224,16 +243,32 @@ void _initialize_cpu() } } }; + + // x86 listFeature("RDTSC", SDL_HasRDTSC()); listFeature("MMX", SDL_HasMMX()); listFeature("3DNow!", SDL_Has3DNow()); listFeature("SSE", SDL_HasSSE()); - listFeature("AVX", SDL_HasAVX()); + listFeature("SSE2", SDL_HasSSE2()); + listFeature("SSE3", SDL_HasSSE3()); + listFeature("SSE41", SDL_HasSSE41()); + listFeature("SSE42", SDL_HasSSE42()); + listFeature("AVX", CPU::HasAVX); + listFeature("AVX2", CPU::HasAVX2); + listFeature("AVX512F", CPU::HasAVX512F); + + // Other architectures + listFeature("AltiVec", SDL_HasAltiVec()); #if SDL_VERSION_ATLEAST(2, 0, 12) listFeature("ARMSIMD", SDL_HasARMSIMD()); #endif +#if SDL_VERSION_ATLEAST(2, 0, 6) listFeature("NEON", SDL_HasNEON()); - listFeature("AltiVec", SDL_HasAltiVec()); +#endif +#if SDL_VERSION_ATLEAST(2, 24, 0) + listFeature("LSX", SDL_HasLSX()); + listFeature("LASX", SDL_HasLASX()); +#endif Msg("* CPU features: %s", features); Msg("* CPU threads: %d", std::thread::hardware_concurrency()); diff --git a/src/xrCore/_math.h b/src/xrCore/_math.h index 6705ef4dc36..6aca8395bec 100644 --- a/src/xrCore/_math.h +++ b/src/xrCore/_math.h @@ -15,6 +15,10 @@ XRCORE_API void m64r(); namespace CPU { XRCORE_API extern bool HasSSE; +XRCORE_API extern bool HasSSE41; +XRCORE_API extern bool HasAVX; +XRCORE_API extern bool HasAVX2; +XRCORE_API extern bool HasAVX512F; XRCORE_API extern u64 qpc_freq; XRCORE_API extern u32 qpc_counter; From 3a6ae30b034e1ab3c436aa380672c88bc79fa7f8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 5 Dec 2023 02:59:01 +0500 Subject: [PATCH 023/497] xrSound/Sound.h: constify position vector in get_occlusion --- src/xrSound/Sound.h | 2 +- src/xrSound/SoundRender_Scene.cpp | 5 ++--- src/xrSound/SoundRender_Scene.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 46792fd06f1..2cc77caaf9c 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -230,7 +230,7 @@ class XRSOUND_API XR_NOVTABLE ISoundScene virtual CSound_environment* get_environment(const Fvector& P) = 0; virtual float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) = 0; - virtual float get_occlusion(Fvector& P, float R, Fvector* occ) = 0; + virtual float get_occlusion(const Fvector& P, float R, Fvector* occ) = 0; virtual void object_relcase(IGameObject* obj) = 0; }; diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index bf5578cbdd8..9048eab97b1 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -268,19 +268,18 @@ float CSoundRender_Scene::get_occlusion_to(const Fvector& hear_pt, const Fvector return occ_value; } -float CSoundRender_Scene::get_occlusion(Fvector& P, float R, Fvector* occ) +float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) { float occ_value = 1.f; // Calculate RAY params const Fvector base = SoundRender->listener_position(); Fvector pos, dir; - float range; pos.random_dir(); pos.mul(R); pos.add(P); dir.sub(pos, base); - range = dir.magnitude(); + const float range = dir.magnitude(); dir.div(range); if (nullptr != geom_MODEL) diff --git a/src/xrSound/SoundRender_Scene.h b/src/xrSound/SoundRender_Scene.h index f832a1c32d1..16bced6d71e 100644 --- a/src/xrSound/SoundRender_Scene.h +++ b/src/xrSound/SoundRender_Scene.h @@ -29,7 +29,7 @@ class CSoundRender_Scene final : public ISoundScene float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) override; float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) override; - float get_occlusion(Fvector& P, float R, Fvector* occ) override; + float get_occlusion(const Fvector& P, float R, Fvector* occ) override; void object_relcase(IGameObject* obj) override; From bd675dd1e2aef20b4657d9c6cd544200132a3fa2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 6 Dec 2023 01:31:28 +0500 Subject: [PATCH 024/497] xrSound/SoundRender_Source.cpp: removed dead code --- src/xrSound/SoundRender_Source.cpp | 54 +----------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 149aafdbfc2..77d6ae1102f 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -50,18 +50,13 @@ bool ov_error(int res) void CSoundRender_Source::i_decompress_fr(OggVorbis_File* ovf, char* _dest, u32 left) { - // vars - // char eof = 0; int current_section; long TotalRet = 0, ret; - //. char *PCM; - //. PCM = new char[left]; - // Read loop while (TotalRet < (long)left) { - ret = ov_read(ovf, /*PCM*/ _dest + TotalRet, left - TotalRet, 0, 2, 1, ¤t_section); + ret = ov_read(ovf, _dest + TotalRet, left - TotalRet, 0, 2, 1, ¤t_section); // BUG: ov_read can return negative value indicating an error, making this loop infinite // if end of file or read limit exceeded if (ret == 0) @@ -75,51 +70,4 @@ void CSoundRender_Source::i_decompress_fr(OggVorbis_File* ovf, char* _dest, u32 TotalRet += ret; } } - //. memcpy(_dest, PCM,TotalRet); - //. delete [] PCM; -} - -/* -void CSoundRender_Source::i_decompress_fr(OggVorbis_File* ovf, char* _dest, u32 left) -{ - float** pcm; - int val; - long channels = ov_info(ovf, -1)->channels; - long bytespersample = 2 / channels; - int dummy; - left /= bytespersample; - short* buffer = (short*)_dest; - while (left) - { - int samples = ov_read_float(ovf, &pcm, left, &dummy); - if (samples > 0) - { - for (int i = 0; i < channels; i++) - { - float* src = pcm[i]; - short* dest = (short *)buffer + i; - - for (int j = 0; j < samples; j++) - { - val = iFloor(src[j] * 32768.f); - if (val > 32767) - val = 32767; - else if (val < -32768) - val = -32768; - - *dest = short(val); - dest += channels; - } - } - left -= samples; - buffer += samples; - } - else - { - if (ov_error(samples)) continue; - break; - } - } } -*/ - From d83402322452df087e59c0624d317da2a0d9ffe7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 6 Dec 2023 01:34:28 +0500 Subject: [PATCH 025/497] xrSound/SoundRender_Source.cpp: improved robustness of ogg reader It now prints errors as it did in X-Ray 1.0 and can still continue correctly handle errors --- src/xrSound/SoundRender_Source.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 77d6ae1102f..c094166ecf0 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -16,7 +16,10 @@ CSoundRender_Source::CSoundRender_Source() } CSoundRender_Source::~CSoundRender_Source() { unload(); } -bool ov_error(int res) + +namespace +{ +bool ov_can_continue_read(long res) { switch (res) { @@ -47,27 +50,19 @@ bool ov_error(int res) } return false; } +} void CSoundRender_Source::i_decompress_fr(OggVorbis_File* ovf, char* _dest, u32 left) { int current_section; - long TotalRet = 0, ret; + long TotalRet = 0; // Read loop - while (TotalRet < (long)left) + while (TotalRet < static_cast(left)) { - ret = ov_read(ovf, _dest + TotalRet, left - TotalRet, 0, 2, 1, ¤t_section); - // BUG: ov_read can return negative value indicating an error, making this loop infinite - // if end of file or read limit exceeded - if (ret == 0) + const auto ret = ov_read(ovf, _dest + TotalRet, left - TotalRet, 0, 2, 1, ¤t_section); + if (ret <= 0 && !ov_can_continue_read(ret)) break; - else if (ret < 0) // Error in bitstream - { - // - } - else - { - TotalRet += ret; - } + TotalRet += ret; } } From 7ac9432c343894a2b496da85e444300cd1c5e97e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 7 Dec 2023 07:43:02 +0500 Subject: [PATCH 026/497] xrSound: add support for 32-bit float output in sound targets The sound quality has become much better! You can notice that even in vanilla game. --- src/Common/PlatformApple.inl | 3 ++- src/Common/PlatformBSD.inl | 3 ++- src/Common/PlatformLinux.inl | 3 ++- src/xrSound/SoundRender_Core.cpp | 2 +- src/xrSound/SoundRender_Core.h | 2 ++ src/xrSound/SoundRender_CoreA.cpp | 5 ++++ src/xrSound/SoundRender_CoreA.h | 1 + src/xrSound/SoundRender_Source.cpp | 29 +++++++++++++++++++---- src/xrSound/SoundRender_Source.h | 4 +++- src/xrSound/SoundRender_Source_loader.cpp | 22 +++++++++++++---- src/xrSound/SoundRender_TargetA.cpp | 15 +++++++++++- 11 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 50bbb3cf69f..348ee3d6a21 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -163,7 +163,8 @@ typedef long long int* PLARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 typedef struct { WORD wFormatTag; diff --git a/src/Common/PlatformBSD.inl b/src/Common/PlatformBSD.inl index 896dd8942a8..e955262bc36 100644 --- a/src/Common/PlatformBSD.inl +++ b/src/Common/PlatformBSD.inl @@ -161,7 +161,8 @@ typedef long long int* PLARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 typedef struct { WORD wFormatTag; diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index 4693ea525d1..e094b66ed84 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -154,7 +154,8 @@ typedef unsigned long long int ULARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 typedef struct { WORD wFormatTag; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 5fd9127597c..6fd1d707e8c 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -59,7 +59,7 @@ void CSoundRender_Core::_initialize() bPresent = true; // Cache - cache_bytes_per_line = (sdef_target_block / 8) * 276400 / 1000; + cache_bytes_per_line = (sdef_target_block / 8) * 352800 / 1000; cache.initialize(psSoundCacheSizeMB * 1024, cache_bytes_per_line); bReady = true; diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 4b38eaa3281..53bc3a2a4e9 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -58,6 +58,8 @@ class CSoundRender_Core : public ISoundManager CSoundRender_Effects* m_effects{}; public: + bool supports_float_pcm{}; + // Cache CSoundRender_Cache cache; u32 cache_bytes_per_line; diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 1f5696e915a..5366ddc9bb8 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -80,6 +80,11 @@ void CSoundRender_CoreA::_initialize() A_CHK(alListenerfv(AL_ORIENTATION, (const ALfloat*)&orient[0].x)); A_CHK(alListenerf(AL_GAIN, 1.f)); +#if AL_EXT_float32 + supports_float_pcm = alIsExtensionPresent("AL_EXT_FLOAT32") // first is OpenAL Soft, + || alIsExtensionPresent("AL_EXT_float32"); // second is macOS +#endif + auto auxSlot = ALuint(-1); #if defined(XR_HAS_EAX) // Check for EAX extension diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index ee973ad128e..1aaf6b8b508 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -4,6 +4,7 @@ #include #include +#include #ifdef DEBUG #define A_CHK(expr) \ diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index c094166ecf0..712fbd5fea1 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -52,17 +52,38 @@ bool ov_can_continue_read(long res) } } -void CSoundRender_Source::i_decompress_fr(OggVorbis_File* ovf, char* _dest, u32 left) +void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, char* _dest, u32 size) const { - int current_section; long TotalRet = 0; // Read loop - while (TotalRet < static_cast(left)) + while (TotalRet < static_cast(size)) { - const auto ret = ov_read(ovf, _dest + TotalRet, left - TotalRet, 0, 2, 1, ¤t_section); + const auto ret = ov_read(ovf, _dest + TotalRet, size - TotalRet, 0, 2, 1, nullptr); if (ret <= 0 && !ov_can_continue_read(ret)) break; TotalRet += ret; } } + +void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, float* _dest, u32 size) const +{ + s32 left = s32(size / m_wformat.nBlockAlign); + while (left) + { + float** pcm; + long samples = ov_read_float(ovf, &pcm, left, nullptr); + + if (samples <= 0 && !ov_can_continue_read(samples)) + break; + + if (samples > left) + samples = left; + + for (long j = 0; j < samples; j++) + for (long i = 0; i < m_wformat.nChannels; i++) + *_dest++ = pcm[i][j]; + + left -= samples; + } +} diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 6bd4857cb41..eb6e74554a7 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -24,7 +24,9 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source u32 m_uGameType; private: - void i_decompress_fr(OggVorbis_File* ovf, char* dest, u32 size); + void i_decompress(OggVorbis_File* ovf, char* dest, u32 size) const; + void i_decompress(OggVorbis_File* ovf, float* dest, u32 size) const; + bool LoadWave(pcstr name, bool crashOnError); public: diff --git a/src/xrSound/SoundRender_Source_loader.cpp b/src/xrSound/SoundRender_Source_loader.cpp index a76c3dfa3c5..4415c87388e 100644 --- a/src/xrSound/SoundRender_Source_loader.cpp +++ b/src/xrSound/SoundRender_Source_loader.cpp @@ -36,8 +36,7 @@ void CSoundRender_Source::decompress(u32 line, OggVorbis_File* ovf) VERIFY(ovf); // decompression of one cache-line u32 line_size = SoundRender->cache.get_linesize(); - auto dest = (pstr)SoundRender->cache.get_dataptr(CAT, line); - u32 buf_offs = (line * line_size) / 2 / m_wformat.nChannels; + u32 buf_offs = (line * line_size) / (m_wformat.wBitsPerSample / 8) / m_wformat.nChannels; u32 left_file = dwBytesTotal - buf_offs; u32 left = (u32)std::min(left_file, line_size); @@ -47,7 +46,11 @@ void CSoundRender_Source::decompress(u32 line, OggVorbis_File* ovf) ov_pcm_seek(ovf, buf_offs); // decompress - i_decompress_fr(ovf, dest, left); + const auto dest = SoundRender->cache.get_dataptr(CAT, line); + if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + i_decompress(ovf, static_cast(dest), left); + else + i_decompress(ovf, static_cast(dest), left); } bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) @@ -84,9 +87,18 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); m_wformat.nSamplesPerSec = (ovi->rate); // 44100; - m_wformat.wFormatTag = WAVE_FORMAT_PCM; m_wformat.nChannels = u16(ovi->channels); - m_wformat.wBitsPerSample = 16; + + if (SoundRender->supports_float_pcm) + { + m_wformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + m_wformat.wBitsPerSample = 32; + } + else + { + m_wformat.wFormatTag = WAVE_FORMAT_PCM; + m_wformat.wBitsPerSample = 16; + } m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 416576ea89a..5c4d689b954 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -207,7 +207,20 @@ void CSoundRender_TargetA::fill_block(ALuint BufferID) R_ASSERT(m_pEmitter); m_pEmitter->fill_block(&g_target_temp_data.front(), buf_block); - ALuint format = m_pEmitter->source()->m_wformat.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + + const auto& wvf = m_pEmitter->source()->m_wformat; + const bool mono = wvf.nChannels == 1; + + ALuint format; +#if AL_EXT_float32 + if (wvf.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + format = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; + else +#endif + { + format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + } + A_CHK(alBufferData( BufferID, format, &g_target_temp_data.front(), buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); } From 08c01f82d7dd2a0d7f5267f8377a1994d3653b4f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 00:05:21 +0500 Subject: [PATCH 027/497] Fixed macOS build --- src/xrSound/SoundRender_CoreA.cpp | 2 -- src/xrSound/SoundRender_CoreA.h | 9 +++++++++ src/xrSound/SoundRender_TargetA.cpp | 2 -- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 5366ddc9bb8..44ba672f947 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -80,10 +80,8 @@ void CSoundRender_CoreA::_initialize() A_CHK(alListenerfv(AL_ORIENTATION, (const ALfloat*)&orient[0].x)); A_CHK(alListenerf(AL_GAIN, 1.f)); -#if AL_EXT_float32 supports_float_pcm = alIsExtensionPresent("AL_EXT_FLOAT32") // first is OpenAL Soft, || alIsExtensionPresent("AL_EXT_float32"); // second is macOS -#endif auto auxSlot = ALuint(-1); #if defined(XR_HAS_EAX) diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index 1aaf6b8b508..6751e633a2c 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -4,7 +4,16 @@ #include #include + +#if __has_include() #include +#endif + +#ifndef AL_EXT_float32 +#define AL_EXT_float32 1 +#define AL_FORMAT_MONO_FLOAT32 0x10010 +#define AL_FORMAT_STEREO_FLOAT32 0x10011 +#endif #ifdef DEBUG #define A_CHK(expr) \ diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 5c4d689b954..9dc973dc514 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -212,11 +212,9 @@ void CSoundRender_TargetA::fill_block(ALuint BufferID) const bool mono = wvf.nChannels == 1; ALuint format; -#if AL_EXT_float32 if (wvf.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) format = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; else -#endif { format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; } From 5c3b8dd36d7e6c566673efd64230137987628e86 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 01:38:09 +0500 Subject: [PATCH 028/497] Fixed some sound not working This reverts change made in 16f742feb1fc01d452cc09ad00cdf822d36bfd2f --- src/xrSound/Sound.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 2cc77caaf9c..a1634a765f4 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -324,6 +324,8 @@ struct CSound : public xr_resource u32 dwBytesTotal{}; float fTimeTotal{}; + + ~CSound() override { GEnv.Sound->destroy(*this); } }; /*! \class ref_sound @@ -362,10 +364,6 @@ struct resptrcode_sound : public resptr_base ICF void destroy() { - if (!p_) - return; - VerSndUnlocked(); - GEnv.Sound->destroy(*p_); _set(nullptr); } From d5fb5764c5158658237b77fd3d4436565dbbf9de Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 20:04:07 +0500 Subject: [PATCH 029/497] xrMaterialSystem/GameMtlLib.h: fix encoding --- src/xrMaterialSystem/GameMtlLib.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 9fd9c01fa31..a0491abd2ff 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -89,13 +89,13 @@ struct MTL_EXPORT_API SGameMtl float fPHBounceStartVelocity; // ? float fPHBouncing; // ? // shoot&bounce&visibility&flotation - float fFlotationFactor; // 0.f - 1.f (1.f-?????????????????? ????????????????????) - float fShootFactor; // 0.f - 1.f (1.f-?????????????????? ??????????????????????????????) - float fShootFactorMP; // 0.f - 1.f (1.f-?????????????????? ??????????????????????????????) + float fFlotationFactor; // 0.f - 1.f (1.f-полностью проходимый) + float fShootFactor; // 0.f - 1.f (1.f-полностью простреливаемый) + float fShootFactorMP; // 0.f - 1.f (1.f-полностью простреливаемый) float fBounceDamageFactor; // 0.f - 100.f - float fInjuriousSpeed; // 0.f - ... (0.f-???? ???????????????? ???????????????? (???????????????? ???????????????????? ????????????????)) - float fVisTransparencyFactor; // 0.f - 1.f (1.f-?????????????????? ????????????????????) - float fSndOcclusionFactor; // 0.f - 1.f (1.f-?????????????????? ????????????) + float fInjuriousSpeed; // 0.f - ... (0.f-не отбирает здоровье (скорость уменьшения здоровья)) + float fVisTransparencyFactor; // 0.f - 1.f (1.f-полностью прозрачный) + float fSndOcclusionFactor; // 0.f - 1.f (1.f-полностью слышен) float fDensityFactor; public: From efe60860796072cc6e2cf6403563e6d70b8c4648 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 20:06:58 +0500 Subject: [PATCH 030/497] Use game materials system for a bit better sound occlusion --- src/xrSound/CMakeLists.txt | 1 + src/xrSound/SoundRender_Scene.cpp | 6 +++++- src/xrSound/xrSound.vcxproj | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index fd5b2fcd77e..53cb179226e 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -144,6 +144,7 @@ target_link_libraries(xrSound xrMiscMath xrAPI xrCDB + xrMaterialSystem ${OPENAL_LIBRARY} ${OGG_LIBRARIES} Vorbis::Vorbis diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 9048eab97b1..f24fdc1ad9f 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -2,6 +2,7 @@ #include "Common/LevelStructure.hpp" #include "xrCDB/Intersect.hpp" +#include "xrMaterialSystem/GameMtlLib.h" #include "SoundRender_Core.h" #include "SoundRender_Scene.h" @@ -306,7 +307,10 @@ float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) occ[0].set(V[T.verts[0]]); occ[1].set(V[T.verts[1]]); occ[2].set(V[T.verts[2]]); - occ_value = psSoundOcclusionScale; + + const SGameMtl* mtl = GMLib.GetMaterialByIdx(T.material); + const float occlusion = fis_zero(mtl->fSndOcclusionFactor) ? 0.1f : mtl->fSndOcclusionFactor; + occ_value = psSoundOcclusionScale * occlusion; } } } diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index dfaf3f000dd..2763301039d 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -95,6 +95,9 @@ {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} + + {2c419512-6eee-4707-bc51-2e834855552e} + From e62423021bfb6ed28db49fdd1e6d82a7f3a64740 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 21:48:40 +0500 Subject: [PATCH 031/497] xrSound/SoundRender_Scene.cpp: fixed potential memory leak when changing levels with SOM or SENV available SOM - sound occlusion model SENV - sound environment --- src/xrSound/SoundRender_Scene.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index f24fdc1ad9f..28aa270c43c 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -12,6 +12,10 @@ CSoundRender_Scene::~CSoundRender_Scene() { stop_emitters(); + set_geometry_occ(nullptr); + set_geometry_som(nullptr); + set_geometry_env(nullptr); + // remove emitters for (auto& emit : s_emitters) xr_delete(emit); From 128996a2258da67deb2fefb3e1fb7a7bc8daf96b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 22:01:00 +0500 Subject: [PATCH 032/497] xrEngine: use xrMaterialSystem directly instead of indirection through IGame_Persistent --- src/xrEngine/CMakeLists.txt | 1 + src/xrEngine/IGame_Persistent.h | 8 -------- src/xrEngine/xrEngine.vcxproj | 3 +++ src/xrEngine/xr_efflensflare.cpp | 8 ++++++-- src/xrGame/GamePersistent.cpp | 4 ---- src/xrGame/GamePersistent.h | 1 - 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index d2d93f108d5..592bd5e41b8 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -433,6 +433,7 @@ target_link_libraries(xrEngine PRIVATE xrAPI xrCDB + xrMaterialSystem xrCore xrSound xrScriptEngine diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 16977d95b7b..73644813e00 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -184,14 +184,6 @@ class ENGINE_API IGame_Persistent : { } #endif - virtual float MtlTransparent(u32 mtl_idx) -#ifndef _EDITOR - = 0; -#else - { - return 1.f; - } -#endif IGame_Persistent(); virtual ~IGame_Persistent(); diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index a95149ed169..4d971be9f86 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -244,6 +244,9 @@ {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} + + {2c419512-6eee-4707-bc51-2e834855552e} + diff --git a/src/xrEngine/xr_efflensflare.cpp b/src/xrEngine/xr_efflensflare.cpp index 46f9b8b4cc4..7819cbc4214 100644 --- a/src/xrEngine/xr_efflensflare.cpp +++ b/src/xrEngine/xr_efflensflare.cpp @@ -11,6 +11,7 @@ #include "Include/xrRender/Kinematics.h" #include "xrCDB/Intersect.hpp" #include "Common/object_broker.h" +#include "xrMaterialSystem/GameMtlLib.h" #ifdef _EDITOR #include "ui_toolscustom.h" @@ -223,12 +224,15 @@ IC bool material_callback(collide::rq_result& result, LPVOID params) vis = 0.f; IKinematics* K = PKinematics(result.O->GetRenderData().visual); if (K && (result.element > 0)) - vis = g_pGamePersistent->MtlTransparent(K->LL_GetData(u16(result.element)).game_mtl_idx); + { + const auto& bone_data = K->LL_GetData(u16(result.element)); + vis = GMLib.GetMaterialByIdx(bone_data.game_mtl_idx)->fVisTransparencyFactor; + } } else { CDB::TRI* T = g_pGameLevel->ObjectSpace.GetStaticTris() + result.element; - vis = g_pGamePersistent->MtlTransparent(T->material); + vis = GMLib.GetMaterialByIdx(T->material)->fVisTransparencyFactor; if (fis_zero(vis)) { Fvector* V = g_pGameLevel->ObjectSpace.GetStaticVerts(); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index f7c507fda0a..9585afaca5a 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -749,10 +749,6 @@ void CGamePersistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) #endif } -float CGamePersistent::MtlTransparent(u32 mtl_idx) -{ - return GMLib.GetMaterialByIdx((u16)mtl_idx)->fVisTransparencyFactor; -} static BOOL bRestorePause = FALSE; static BOOL bEntryFlag = TRUE; diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 4e43becfcd8..2dd1c89973d 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -83,7 +83,6 @@ class CGamePersistent : public IGame_Persistent, public IEventReceiver virtual void UpdateGameType(); virtual void RegisterModel(IRenderVisual* V); - virtual float MtlTransparent(u32 mtl_idx); virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; virtual bool OnRenderPPUI_query(); From 9cf5c0910db841df1b77c0a28e3782a251a18f59 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 22:12:36 +0500 Subject: [PATCH 033/497] xrRender: use xrMaterialSystem directly instead of indirection through IGame_Persistent --- src/Layers/xrRender/ModelPool.cpp | 35 ++++++++++++++++++++++++++++--- src/xrEngine/IGame_Persistent.h | 8 ------- src/xrGame/GamePersistent.cpp | 32 ---------------------------- src/xrGame/GamePersistent.h | 1 - 4 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/Layers/xrRender/ModelPool.cpp b/src/Layers/xrRender/ModelPool.cpp index 6bdbb7cc2b3..07c8990eb4d 100644 --- a/src/Layers/xrRender/ModelPool.cpp +++ b/src/Layers/xrRender/ModelPool.cpp @@ -2,6 +2,8 @@ #include "ModelPool.h" +#include "xrMaterialSystem/GameMtlLib.h" + #ifndef _EDITOR #include "xrEngine/IGame_Persistent.h" #include "xrCore/FMesh.hpp" @@ -76,7 +78,6 @@ dxRender_Visual* CModelPool::Instance_Duplicate(dxRender_Visual* V) dxRender_Visual* CModelPool::Instance_Load(const char* N, BOOL allow_register) { - dxRender_Visual* V; string_path fn; string_path name; @@ -114,10 +115,38 @@ dxRender_Visual* CModelPool::Instance_Load(const char* N, BOOL allow_register) IReader* data = FS.r_open(fn); ogf_header H; data->r_chunk_safe(OGF_HEADER, &H, sizeof(H)); - V = Instance_Create(H.type); + dxRender_Visual* V = Instance_Create(H.type); V->Load(N, data, 0); FS.r_close(data); - g_pGamePersistent->RegisterModel(V); + + // Register material + switch (H.type) + { + case MT_SKELETON_ANIM: + case MT_SKELETON_RIGID: + { + const u16 def_idx = GMLib.GetMaterialIdx("default_object"); + R_ASSERT2(GMLib.GetMaterialByIdx(def_idx)->Flags.is(SGameMtl::flDynamic), "'default_object' - must be dynamic"); + auto* K = static_cast(V); + VERIFY(K); + const u16 cnt = K->LL_BoneCount(); + for (u16 k = 0; k < cnt; k++) + { + CBoneData& bd = K->LL_GetData(k); + if (*(bd.game_mtl_name)) + { + bd.game_mtl_idx = GMLib.GetMaterialIdx(*bd.game_mtl_name); + R_ASSERT2(GMLib.GetMaterialByIdx(bd.game_mtl_idx)->Flags.is(SGameMtl::flDynamic), + "Required dynamic game material"); + } + else + { + bd.game_mtl_idx = def_idx; + } + } + } + break; + } // switch (V->getType()) // Registration if (allow_register) diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 73644813e00..4f712e2b73e 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -177,14 +177,6 @@ class ENGINE_API IGame_Persistent : virtual void OnSectorChanged(IRender_Sector::sector_id_t /*sector*/) {}; virtual void OnAssetsChanged(); - virtual void RegisterModel(IRenderVisual* V) -#ifndef _EDITOR - = 0; -#else - { - } -#endif - IGame_Persistent(); virtual ~IGame_Persistent(); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 9585afaca5a..1795e116bdb 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -110,38 +110,6 @@ void CGamePersistent::PreStart(LPCSTR op) inherited::PreStart(op); } -void CGamePersistent::RegisterModel(IRenderVisual* V) -{ - // Check types - switch (V->getType()) - { - case MT_SKELETON_ANIM: - case MT_SKELETON_RIGID: - { - u16 def_idx = GMLib.GetMaterialIdx("default_object"); - R_ASSERT2(GMLib.GetMaterialByIdx(def_idx)->Flags.is(SGameMtl::flDynamic), "'default_object' - must be dynamic"); - IKinematics* K = smart_cast(V); - VERIFY(K); - const u16 cnt = K->LL_BoneCount(); - for (u16 k = 0; k < cnt; k++) - { - CBoneData& bd = K->LL_GetData(k); - if (*(bd.game_mtl_name)) - { - bd.game_mtl_idx = GMLib.GetMaterialIdx(*bd.game_mtl_name); - R_ASSERT2(GMLib.GetMaterialByIdx(bd.game_mtl_idx)->Flags.is(SGameMtl::flDynamic), - "Required dynamic game material"); - } - else - { - bd.game_mtl_idx = def_idx; - } - } - } - break; - } -} - extern void clean_game_globals(); extern void init_game_globals(); diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 2dd1c89973d..9c771569c18 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -82,7 +82,6 @@ class CGamePersistent : public IGame_Persistent, public IEventReceiver virtual void UpdateGameType(); - virtual void RegisterModel(IRenderVisual* V); virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; virtual bool OnRenderPPUI_query(); From b956e6a7fa0bb9e53512333693a1346a9cc2c1e1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 22:23:04 +0500 Subject: [PATCH 034/497] Rename last occurences of EDITOR macro to _EDITOR _EDITOR is used everywhere --- src/xrCore/FS.cpp | 4 ++-- src/xrMaterialSystem/GameMtlLib.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xrCore/FS.cpp b/src/xrCore/FS.cpp index f9fc17e07c0..fa623aa906a 100644 --- a/src/xrCore/FS.cpp +++ b/src/xrCore/FS.cpp @@ -98,7 +98,7 @@ bool file_handle_internal(pcstr file_name, size_t& size, int& hFile) size = filelength(hFile); return (true); } -#else // EDITOR +#else // _EDITOR static int open_internal(pcstr fn, int& handle) { #if defined(XR_PLATFORM_WINDOWS) @@ -127,7 +127,7 @@ bool file_handle_internal(pcstr file_name, size_t& size, int& file_handle) size = _filelength(file_handle); return (true); } -#endif // EDITOR +#endif // _EDITOR void* FileDownload(pcstr file_name, const int& file_handle, size_t& file_size) { diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index a0491abd2ff..e14e44e308e 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -292,7 +292,7 @@ class MTL_EXPORT_API CGameMtlLibrary GameMtlIt LastMaterial() { return materials.end(); } u32 CountMaterial() const { return materials.size(); } -#ifdef EDITOR +#ifdef _EDITOR SGameMtl* AppendMaterial(SGameMtl* parent); void RemoveMaterial(pcstr name); void CopyMtlPairs(SGameMtl* src, SGameMtl* dst); @@ -312,7 +312,7 @@ class MTL_EXPORT_API CGameMtlLibrary SGameMtlPair* GetMaterialPair(int id); SGameMtlPair* GetMaterialPair(int mtl0, int mtl1); SGameMtlPair* GetMaterialPair(const char* name); -#endif +#endif // _EDITOR // game SGameMtlPair* GetMaterialPairByIndices(u16 i0, u16 i1) const From e390e3d2cb290f8c45ce5e40a9c00e6b7d5eb740 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 22:29:34 +0500 Subject: [PATCH 035/497] Removed BREAK_AT_STRCMP --- src/xrCore/_std_extensions.cpp | 8 -------- src/xrCore/xrstring.h | 26 +++++++------------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/xrCore/_std_extensions.cpp b/src/xrCore/_std_extensions.cpp index 0d8b8261347..dafc5ed5d62 100644 --- a/src/xrCore/_std_extensions.cpp +++ b/src/xrCore/_std_extensions.cpp @@ -3,14 +3,6 @@ #include -#ifdef BREAK_AT_STRCMP -int xr_strcmp(const char* S1, const char* S2) -{ - int res = (int)strcmp(S1, S2); - return res; -} -#endif - char* timestamp(string64& dest) { time_t now = time(nullptr); diff --git a/src/xrCore/xrstring.h b/src/xrCore/xrstring.h index ddc4a8dbe2a..7810b1c7893 100644 --- a/src/xrCore/xrstring.h +++ b/src/xrCore/xrstring.h @@ -5,17 +5,7 @@ #include "xr_types.h" #include "xrMemory.h" -#define BREAK_AT_STRCMP -#ifndef DEBUG -#undef BREAK_AT_STRCMP -#endif -#ifdef _EDITOR -#undef BREAK_AT_STRCMP -#endif - -#ifndef BREAK_AT_STRCMP -#include -#endif +#include #pragma pack(push, 4) #pragma warning(push) @@ -184,14 +174,6 @@ class shared_str } }; -#ifdef BREAK_AT_STRCMP -XRCORE_API int xr_strcmp(const char* S1, const char* S2); -#else -inline int xr_strcmp(const char* S1, const char* S2) -{ - return (int)strcmp(S1, S2); -} -#endif template<> struct std::hash @@ -218,6 +200,12 @@ IC bool operator>(shared_str const& a, shared_str const& b) { return a._get() > // externally visible standard functionality IC void swap(shared_str& lhs, shared_str& rhs) noexcept { lhs.swap(rhs); } IC size_t xr_strlen(const shared_str& a) noexcept { return a.size(); } + +ICF int xr_strcmp(const char* S1, const char* S2) +{ + return strcmp(S1, S2); +} + IC int xr_strcmp(const shared_str& a, const char* b) noexcept { return xr_strcmp(*a, b); } IC int xr_strcmp(const char* a, const shared_str& b) noexcept { return xr_strcmp(a, *b); } IC int xr_strcmp(const shared_str& a, const shared_str& b) noexcept From 48ed4d7aa0da741745a92808ee6a13f82a68d1ce Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 22:42:51 +0500 Subject: [PATCH 036/497] xrParticles/particle_actions_collection.cpp: removed _EDITOR code path --- .../particle_actions_collection.cpp | 35 ++----------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/src/xrParticles/particle_actions_collection.cpp b/src/xrParticles/particle_actions_collection.cpp index 179eaad8968..3150dcfbdf7 100644 --- a/src/xrParticles/particle_actions_collection.cpp +++ b/src/xrParticles/particle_actions_collection.cpp @@ -1616,8 +1616,6 @@ void PAVortex::Transform(const Fmatrix& m) static int noise_start = 1; extern void noise3Init(); -#ifndef _EDITOR - #if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) || defined(XR_ARCHITECTURE_PPC64) #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) @@ -1693,10 +1691,11 @@ void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max vY.set(pV.x, pV.y + epsilon, pV.z); vZ.set(pV.x, pV.y, pV.z + epsilon); - float d = fractalsum3(pV, frequency, octaves); + const float d = fractalsum3(pV, frequency, octaves); pVector D; +#if 1 D.x = fractalsum3(vX, frequency, octaves); D.y = fractalsum3(vY, frequency, octaves); D.z = fractalsum3(vZ, frequency, octaves); @@ -1732,35 +1731,7 @@ void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max _mvel = _mm_mul_ps(_mvel, _vmo); _mm_store_fvector(m.vel, _mvel); - } -} - #else - -void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max) -{ - if (noise_start) - { - noise_start = 0; - noise3Init(); - }; - - pVector pV; - pVector vX; - pVector vY; - pVector vZ; - age += dt; - for (u32 i = 0; i < effect->p_count; i++) - { - Particle& m = effect->particles[i]; - - pV.mad(m.pos, offset, age); - vX.set(pV.x + epsilon, pV.y, pV.z); - vY.set(pV.x, pV.y + epsilon, pV.z); - vZ.set(pV.x, pV.y, pV.z + epsilon); - - pVector D; - float d = fractalsum3(pV, frequency, octaves); D.x = (fractalsum3(vX, frequency, octaves) - d) * (float)magnitude; D.y = (fractalsum3(vY, frequency, octaves) - d) * (float)magnitude; D.z = (fractalsum3(vZ, frequency, octaves) - d) * (float)magnitude; @@ -1770,9 +1741,9 @@ void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max float velMagNow = m.vel.magnitude(); float valMagScale = velMagOrig / velMagNow; m.vel.mul(valMagScale); +#endif } } -#endif void PATurbulence::Transform(const Fmatrix& m) {} //------------------------------------------------------------------------------------------------- From bf724895729891ced1348dd9ad4ad7f0d31fbf08 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 23:00:39 +0500 Subject: [PATCH 037/497] Removed some occurences of _EDITOR macro --- src/xrCDB/xrCDB.cpp | 5 +--- src/xrCore/FS.cpp | 25 ------------------ src/xrCore/FS_internal.h | 2 +- src/xrCore/LocatorAPI_defs.h | 8 ------ src/xrCore/_std_extensions.h | 32 ----------------------- src/xrEngine/GameFont.cpp | 2 -- src/xrEngine/IGame_Persistent_Effects.cpp | 2 -- src/xrEngine/xrTheora_Stream.cpp | 5 ---- src/xrEngine/xrTheora_Stream.h | 4 --- src/xrParticles/noise.cpp | 13 --------- src/xrSound/stdafx.h | 4 --- 11 files changed, 2 insertions(+), 100 deletions(-) diff --git a/src/xrCDB/xrCDB.cpp b/src/xrCDB/xrCDB.cpp index 5ab5cdf8e18..ca73b1f93b2 100644 --- a/src/xrCDB/xrCDB.cpp +++ b/src/xrCDB/xrCDB.cpp @@ -78,9 +78,7 @@ void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, vo R_ASSERT((Vcnt >= 4) && (Tcnt >= 2)); _initialize_cpu_thread(); -#ifdef _EDITOR - build_internal(V, Vcnt, T, Tcnt, bc, bcp); -#else + if (!strstr(Core.Params, "-mt_cdb")) { build_internal(V, Vcnt, T, Tcnt, bc, bcp); @@ -97,7 +95,6 @@ void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, vo Sleep(5); } } -#endif } void MODEL::build_internal(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, void* bcp) diff --git a/src/xrCore/FS.cpp b/src/xrCore/FS.cpp index fa623aa906a..6e9adcebe52 100644 --- a/src/xrCore/FS.cpp +++ b/src/xrCore/FS.cpp @@ -83,22 +83,6 @@ void VerifyPath(pcstr path) } } -#ifdef _EDITOR -bool file_handle_internal(pcstr file_name, size_t& size, int& hFile) -{ - hFile = _open(file_name, O_RDONLY | O_BINARY | O_SEQUENTIAL); - if (hFile <= 0) - { - Sleep(1); - hFile = _open(file_name, O_RDONLY | O_BINARY | O_SEQUENTIAL); - if (hFile <= 0) - return (false); - } - - size = filelength(hFile); - return (true); -} -#else // _EDITOR static int open_internal(pcstr fn, int& handle) { #if defined(XR_PLATFORM_WINDOWS) @@ -127,7 +111,6 @@ bool file_handle_internal(pcstr file_name, size_t& size, int& file_handle) size = _filelength(file_handle); return (true); } -#endif // _EDITOR void* FileDownload(pcstr file_name, const int& file_handle, size_t& file_size) { @@ -426,11 +409,7 @@ void IReader::r_string(char* dest, size_t tgt_sz) R_ASSERT(!IsBadReadPtr((void*)src, sz)); #endif -#ifdef _EDITOR - CopyMemory(dest, src, sz); -#else strncpy_s(dest, tgt_sz, src, sz); -#endif dest[sz] = 0; } void IReader::r_string(xr_string& dest) @@ -479,11 +458,7 @@ bool IReader::try_r_string(char* dest, size_t tgt_sz) R_ASSERT(!IsBadReadPtr((void*)src, sz)); #endif -#ifdef _EDITOR - CopyMemory(dest, src, sz); -#else strncpy_s(dest, tgt_sz, src, sz); -#endif dest[sz] = 0; return true; diff --git a/src/xrCore/FS_internal.h b/src/xrCore/FS_internal.h index ce7cafe3976..8a7468f1ea2 100644 --- a/src/xrCore/FS_internal.h +++ b/src/xrCore/FS_internal.h @@ -36,7 +36,7 @@ class CFileWriter final : public IWriter if (exclusive) { const int handle = _sopen(conv_fn, _O_WRONLY | _O_TRUNC | _O_CREAT | _O_BINARY, SH_DENYWR); -#ifdef _EDITOR +#ifndef MASTER_GOLD if (handle == -1) Msg("! Can't create file: '%s'. Error: '%s'.", conv_fn, _sys_errlist[errno]); #endif diff --git a/src/xrCore/LocatorAPI_defs.h b/src/xrCore/LocatorAPI_defs.h index c17b7aadae4..d514cb1264a 100644 --- a/src/xrCore/LocatorAPI_defs.h +++ b/src/xrCore/LocatorAPI_defs.h @@ -39,16 +39,8 @@ class XRCORE_API FS_Path void rescan_path_cb(); }; -#ifdef _EDITOR -namespace std -{ -struct _finddata_t; -}; -#define _FINDDATA_T std::_finddata_t -#else struct _finddata64i32_t; #define _FINDDATA_T _finddata64i32_t -#endif struct XRCORE_API FS_File { diff --git a/src/xrCore/_std_extensions.h b/src/xrCore/_std_extensions.h index 882e4805aa5..89010b7129c 100644 --- a/src/xrCore/_std_extensions.h +++ b/src/xrCore/_std_extensions.h @@ -28,36 +28,6 @@ #undef max #endif -#if 0//def _EDITOR -IC char* strncpy_s(char* strDestination, size_t sizeInBytes, const char* strSource, size_t count) -{ - return strncpy(strDestination, strSource, count); -} - -IC char* xr_strcpy(char* strDestination, size_t sizeInBytes, const char* strSource) -{ - return strcpy(strDestination, strSource); -} - -IC char* xr_strcpy(char* strDestination, const char* strSource) { return strcpy(strDestination, strSource); } -IC char* _strlwr_s(char* strDestination, size_t sizeInBytes) { return xr_strlwr(strDestination); } -IC char* xr_strcat(char* strDestination, size_t sizeInBytes, const char* strSource) -{ - return strncat(strDestination, strSource, sizeInBytes); -} - -IC char* xr_strcat(char* strDestination, const char* strSource) { return strcat(strDestination, strSource); } -IC int xr_sprintf(char* dest, size_t sizeOfBuffer, const char* format, ...) -{ - va_list mark; - va_start(mark, format); - int sz = _vsnprintf(dest, sizeOfBuffer, format, mark); - dest[sizeOfBuffer - 1] = 0; - va_end(mark); - return sz; -} -#endif // _EDITOR - // generic template IC T _min(T a, T b) @@ -167,7 +137,6 @@ IC s64 _max(s64 x, s64 y) { return x - ((x - y) & ((x - y) >> (sizeof(s64) * 8 - IC char* strext(const char* S) { return (char*)strrchr(S, '.'); } IC size_t xr_strlen(const char* S) { return strlen(S); } -//#ifndef _EDITOR #ifndef MASTER_GOLD inline int xr_strcpy(pstr destination, size_t const destination_size, LPCSTR source) @@ -251,7 +220,6 @@ inline int xr_strcat(char(&destination)[count], LPCSTR source) { return xr_strcat(destination, count, source); } -//#endif // #ifndef _EDITOR inline void MemFill32(void* dst, u32 value, size_t dstSize) { diff --git a/src/xrEngine/GameFont.cpp b/src/xrEngine/GameFont.cpp index baa5f749c04..aa6b85da657 100644 --- a/src/xrEngine/GameFont.cpp +++ b/src/xrEngine/GameFont.cpp @@ -4,9 +4,7 @@ #include "GameFont.h" #include "xr_level_controller.h" #include "xrCore/Text/StringConversion.hpp" -#ifndef _EDITOR #include "Render.h" -#endif extern ENGINE_API bool g_bRendering; ENGINE_API Fvector2 g_current_font_scale = {1.0f, 1.0f}; diff --git a/src/xrEngine/IGame_Persistent_Effects.cpp b/src/xrEngine/IGame_Persistent_Effects.cpp index 292608eb7eb..941b0708f63 100644 --- a/src/xrEngine/IGame_Persistent_Effects.cpp +++ b/src/xrEngine/IGame_Persistent_Effects.cpp @@ -2,12 +2,10 @@ #include "IGame_Persistent.h" -#ifndef _EDITOR #include "Environment.h" #include "IGame_Level.h" #include "Render.h" #include "perlin.h" -#endif void IGame_Persistent::GrassBendersUpdate(u16 id, u8& data_idx, u32& data_frame, Fvector& position, float init_radius, float init_str, bool CheckDistance) { diff --git a/src/xrEngine/xrTheora_Stream.cpp b/src/xrEngine/xrTheora_Stream.cpp index 0a83cd25801..ad0213ce97f 100644 --- a/src/xrEngine/xrTheora_Stream.cpp +++ b/src/xrEngine/xrTheora_Stream.cpp @@ -241,12 +241,7 @@ bool CTheoraStream::Decode(u32 in_tm_play) bool CTheoraStream::Load(const char* fname) { VERIFY(0 == source); -// open source -#ifdef _EDITOR - source = FS.r_open(0, fname); -#else source = FS.rs_open(0, fname); -#endif VERIFY(source); // parse headers diff --git a/src/xrEngine/xrTheora_Stream.h b/src/xrEngine/xrTheora_Stream.h index 3966155806b..b5389c8b65c 100644 --- a/src/xrEngine/xrTheora_Stream.h +++ b/src/xrEngine/xrTheora_Stream.h @@ -16,11 +16,7 @@ class ENGINE_API CTheoraStream theora_comment t_comment; theora_state t_state; -#ifdef _EDITOR - IReader* source; -#else CStreamReader* source; -#endif yuv_buffer t_yuv_buffer; ogg_int64_t d_frame; diff --git a/src/xrParticles/noise.cpp b/src/xrParticles/noise.cpp index 2672b30b9d1..582d79c4cd1 100644 --- a/src/xrParticles/noise.cpp +++ b/src/xrParticles/noise.cpp @@ -2,7 +2,6 @@ #include "noise.h" -#ifndef _EDITOR #if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) || defined(XR_ARCHITECTURE_PPC64) #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) @@ -16,7 +15,6 @@ ICF int iFloor_SSE(float const x) { return floor(x); } #else ICF int iFloor_SSE(float const x) { return _mm_cvtt_ss2si(_mm_set_ss(x)); } #endif -#endif //============================================================================== // Perlin's noise from Texturing and Modeling... @@ -27,7 +25,6 @@ ICF int iFloor_SSE(float const x) { return _mm_cvtt_ss2si(_mm_set_ss(x)); } #define S_CURVE(t) (t * t * (3.f - 2.f * t)) #define LERP(t, a, b) (a + t * (b - a)) -#ifndef _EDITOR #define PN_SETUP(i, b0, b1, r0, r1) \ t = vec[i] + 10000.f; \ tt = iFloor_SSE(t); \ @@ -35,16 +32,6 @@ ICF int iFloor_SSE(float const x) { return _mm_cvtt_ss2si(_mm_set_ss(x)); } b1 = (b0 + 1) & (B - 1); \ r0 = t - float(tt); \ r1 = r0 - 1.f; -#else - -#define PN_SETUP(i, b0, b1, r0, r1) \ - t = vec[i] + 10000.f; \ - b0 = iFloor(t) & (B - 1); \ - b1 = (b0 + 1) & (B - 1); \ - r0 = t - iFloor(t); \ - r1 = r0 - 1.f; - -#endif static int p[B + B + 2]; static float g[B + B + 2][3]; diff --git a/src/xrSound/stdafx.h b/src/xrSound/stdafx.h index 9b85a575276..e6d74f5785a 100644 --- a/src/xrSound/stdafx.h +++ b/src/xrSound/stdafx.h @@ -29,7 +29,3 @@ #include "Sound.h" #include "xrCore/xr_resource.h" - -#ifdef _EDITOR -#include "utils/ETools/ETools.h" -#endif From 0b5efe46eb5aa3d53d75845ebeab2f96af9f5621 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Dec 2023 23:31:29 +0500 Subject: [PATCH 038/497] Unify SetLoadStageTitle and LoadTitle into one function Like it was in SOC/CS. This simplifies ongoing refactoring for us. --- .../xrRenderPC_R1/FStaticRender_Loader.cpp | 18 +++++-------- src/Layers/xrRender_R2/r2_loader.cpp | 18 +++++-------- src/xrEngine/IGame_Level.cpp | 6 ++--- src/xrEngine/IGame_Persistent.cpp | 3 +-- src/xrEngine/IGame_Persistent.h | 3 +-- src/xrEngine/x_ray.cpp | 2 +- src/xrEngine/x_ray.h | 3 +-- src/xrGame/GamePersistent.cpp | 26 +++++++++---------- src/xrGame/GamePersistent.h | 3 +-- src/xrGame/Level_GameSpy_Funcs.cpp | 3 +-- src/xrGame/Level_load.cpp | 3 +-- src/xrGame/Level_network_start_client.cpp | 13 +++------- src/xrGame/Level_start.cpp | 7 +++-- src/xrGame/alife_storage_manager.cpp | 5 ++-- src/xrGame/alife_update_manager.cpp | 9 +++---- src/xrGame/game_sv_single.cpp | 3 +-- 16 files changed, 46 insertions(+), 79 deletions(-) diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp index 981fdaf4f04..ae5d26221c9 100644 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp +++ b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp @@ -18,8 +18,7 @@ void CRender::level_Load(IReader* fs) IReader* chunk; // Shaders - g_pGamePersistent->SetLoadStageTitle("st_loading_shaders"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_shaders"); { chunk = fs->open_chunk(fsL_SHADERS); R_ASSERT2(chunk, "Level doesn't builded correctly."); @@ -54,8 +53,7 @@ void CRender::level_Load(IReader* fs) if (!GEnv.isDedicatedServer) { // VB,IB,SWI - g_pGamePersistent->SetLoadStageTitle("st_loading_geometry"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_geometry"); { CStreamReader* geom = FS.rs_open("$level$", "level.geom"); R_ASSERT2(geom, "level.geom"); @@ -74,29 +72,25 @@ void CRender::level_Load(IReader* fs) } // Visuals - g_pGamePersistent->SetLoadStageTitle("st_loading_spatial_db"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_spatial_db"); chunk = fs->open_chunk(fsL_VISUALS); LoadVisuals(chunk); chunk->close(); // Details - g_pGamePersistent->SetLoadStageTitle("st_loading_details"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_details"); Details->Load(); } // Sectors - g_pGamePersistent->SetLoadStageTitle("st_loading_sectors_portals"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_sectors_portals"); LoadSectors(fs); // HOM HOM.Load(); // Lights - g_pGamePersistent->SetLoadStageTitle("st_loading_lights"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_lights"); LoadLights(fs); // End diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index 4be97a4b6a1..16ea4cdc311 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -24,8 +24,7 @@ void CRender::level_Load(IReader* fs) IReader* chunk; // Shaders - g_pGamePersistent->SetLoadStageTitle("st_loading_shaders"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_shaders"); { chunk = fs->open_chunk(fsL_SHADERS); R_ASSERT2(chunk, "Level doesn't builded correctly."); @@ -54,8 +53,7 @@ void CRender::level_Load(IReader* fs) if (!GEnv.isDedicatedServer) { // VB,IB,SWI - g_pGamePersistent->SetLoadStageTitle("st_loading_geometry"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_geometry"); { CStreamReader* geom = FS.rs_open("$level$", "level.geom"); R_ASSERT2(geom, "level.geom"); @@ -73,21 +71,18 @@ void CRender::level_Load(IReader* fs) } // Visuals - g_pGamePersistent->SetLoadStageTitle("st_loading_spatial_db"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_spatial_db"); chunk = fs->open_chunk(fsL_VISUALS); LoadVisuals(chunk); chunk->close(); // Details - g_pGamePersistent->SetLoadStageTitle("st_loading_details"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_details"); Details->Load(); } // Sectors - g_pGamePersistent->SetLoadStageTitle("st_loading_sectors_portals"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_sectors_portals"); LoadSectors(fs); #if defined(USE_DX11) @@ -99,8 +94,7 @@ void CRender::level_Load(IReader* fs) HOM.Load(); // Lights - g_pGamePersistent->SetLoadStageTitle("st_loading_lights"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_lights"); LoadLights(fs); // End diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index b0f99fc3d3b..10ee97ccd3e 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -99,8 +99,7 @@ bool IGame_Level::Load(u32 dwNum) pLevel = xr_new(temp); // Open - g_pGamePersistent->SetLoadStageTitle("st_opening_stream"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_opening_stream"); IReader* LL_Stream = FS.r_open("$level$", "level"); IReader& fs = *LL_Stream; @@ -110,8 +109,7 @@ bool IGame_Level::Load(u32 dwNum) R_ASSERT2(XRCL_PRODUCTION_VERSION == H.XRLC_version, "Incompatible level version."); // CForms - g_pGamePersistent->SetLoadStageTitle("st_loading_cform"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_cform"); ObjectSpace.Load(build_callback, serialize_callback, deserialize_callback); g_pGamePersistent->SpatialSpace.initialize(ObjectSpace.GetBoundingVolume()); diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 89f9f6e47da..e309a76ea80 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -125,8 +125,7 @@ void IGame_Persistent::Disconnect() void IGame_Persistent::OnGameStart() { #ifndef _EDITOR - SetLoadStageTitle("st_prefetching_objects"); - LoadTitle(); + LoadTitle("st_prefetching_objects"); if (!strstr(Core.Params, "-noprefetch")) Prefetch(); #endif diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 4f712e2b73e..7c35716450f 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -182,8 +182,7 @@ class ENGINE_API IGame_Persistent : ICF u32 GameType() { return m_game_params.m_e_game_type; }; virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert); - virtual void LoadTitle(bool /*change_tip*/ = false, shared_str /*map_name*/ = "") {} - virtual void SetLoadStageTitle(pcstr /*ls_title*/) {} + virtual void LoadTitle(pcstr /*ls_title*/ = nullptr, bool /*change_tip*/ = false, shared_str /*map_name*/ = "") {} virtual bool CanBePaused() { return true; } }; diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 47619e69a67..0151e8b765d 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -249,7 +249,7 @@ void CApplication::LoadDraw() Device.RenderEnd(); } -void CApplication::SetLoadStageTitle(pcstr _ls_title) +void CApplication::LoadTitle(pcstr _ls_title) { loadingScreen->SetStageTitle(_ls_title); } diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 1de66a15cdd..a676a96f50e 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -48,13 +48,12 @@ class ENGINE_API CApplication : public pureFrame, public IEventReceiver // Loading void LoadBegin(); void LoadEnd(); + void LoadTitle(pcstr ls_title); void LoadTitleInt(pcstr str1, pcstr str2, pcstr str3); void LoadStage(bool draw = true); void LoadSwitch(); void LoadDraw(); - void SetLoadStageTitle(pcstr ls_title); - virtual void OnEvent(EVENT E, u64 P1, u64 P2); // Other diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 1795e116bdb..143deb0f3a6 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -486,7 +486,7 @@ void CGamePersistent::OnFrame() { if (Device.dwPrecacheFrame == 5 && m_intro_event.empty()) { - SetLoadStageTitle(); + LoadTitle(); m_intro_event.bind(this, &CGamePersistent::game_loaded); } @@ -772,9 +772,17 @@ void CGamePersistent::OnRenderPPUI_main() void CGamePersistent::OnRenderPPUI_PP() { MainMenu()->OnRenderPPUI_PP(); } #include "xrEngine/x_ray.h" -void CGamePersistent::LoadTitle(bool change_tip, shared_str map_name) +void CGamePersistent::LoadTitle(pcstr ls_title, bool change_tip, shared_str map_name) { - pApp->LoadStage(); + if (ls_title) + { + string256 buff; + xr_sprintf(buff, "%s%s", StringTable().translate(ls_title).c_str(), "..."); + pApp->LoadTitle(buff); + } + else if (!change_tip) + pApp->LoadTitle(""); + if (change_tip) { bool noTips = false; @@ -810,18 +818,8 @@ void CGamePersistent::LoadTitle(bool change_tip, shared_str map_name) pApp->LoadTitleInt( StringTable().translate("ls_header").c_str(), tmp.c_str(), StringTable().translate(buff).c_str()); } -} -void CGamePersistent::SetLoadStageTitle(pcstr ls_title) -{ - string256 buff; - if (ls_title) - { - xr_sprintf(buff, "%s%s", StringTable().translate(ls_title).c_str(), "..."); - pApp->SetLoadStageTitle(buff); - } - else - pApp->SetLoadStageTitle(""); + pApp->LoadStage(); } bool CGamePersistent::CanBePaused() { return IsGameTypeSingle() || (g_pGameLevel && Level().IsDemoPlay()); } diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 9c771569c18..5cd5082c075 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -87,8 +87,7 @@ class CGamePersistent : public IGame_Persistent, public IEventReceiver virtual bool OnRenderPPUI_query(); virtual void OnRenderPPUI_main(); virtual void OnRenderPPUI_PP(); - virtual void LoadTitle(bool change_tip = false, shared_str map_name = ""); - void SetLoadStageTitle(pcstr ls_title = nullptr) override; + virtual void LoadTitle(pcstr ls_title = nullptr, bool change_tip = false, shared_str map_name = ""); virtual bool CanBePaused(); diff --git a/src/xrGame/Level_GameSpy_Funcs.cpp b/src/xrGame/Level_GameSpy_Funcs.cpp index a179bdb35fd..9ec86f542fb 100644 --- a/src/xrGame/Level_GameSpy_Funcs.cpp +++ b/src/xrGame/Level_GameSpy_Funcs.cpp @@ -30,6 +30,5 @@ void CLevel::OnGameSpyChallenge(NET_Packet* P) newP.w_stringZ(ResponseStr); Send(newP, net_flags(TRUE, TRUE, TRUE, TRUE)); - g_pGamePersistent->SetLoadStageTitle("st_validating_cdkey"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_validating_cdkey"); }; diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index 0adfde3720a..46464bbfdbe 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -15,8 +15,7 @@ bool CLevel::Load_GameSpecific_Before() { // AI space - g_pGamePersistent->SetLoadStageTitle("st_loading_ai_objects"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_ai_objects"); string_path fn_game; if (GamePersistent().GameType() == eGameIDSingle && !ai().get_alife() && FS.exist(fn_game, "$level$", "level.ai") && diff --git a/src/xrGame/Level_network_start_client.cpp b/src/xrGame/Level_network_start_client.cpp index 8975ac09740..e3795d50f16 100644 --- a/src/xrGame/Level_network_start_client.cpp +++ b/src/xrGame/Level_network_start_client.cpp @@ -32,14 +32,12 @@ bool CLevel::net_start_client1() *strchr(name_of_server, '/') = 0; // Startup client - string256 temp; xr_sprintf(temp, "%s %s", StringTable().translate("st_client_connecting_to").c_str(), name_of_server); - pApp->SetLoadStageTitle(temp); - pApp->LoadStage(); + g_pGamePersistent->LoadTitle(temp); return true; } @@ -128,8 +126,7 @@ bool CLevel::net_start_client4() if (connected_to_server) { // Begin spawn - g_pGamePersistent->SetLoadStageTitle("st_client_spawning"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_client_spawning"); // Send physics to single or multithreaded mode @@ -211,8 +208,7 @@ bool CLevel::net_start_client5() // Textures if (!GEnv.isDedicatedServer) { - g_pGamePersistent->SetLoadStageTitle("st_loading_textures"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_textures"); GEnv.Render->DeferredLoad(FALSE); GEnv.Render->ResourcesDeferredUpload(); LL_CheckTextures(); @@ -255,8 +251,7 @@ bool CLevel::net_start_client6() } } - g_pGamePersistent->SetLoadStageTitle("st_client_synchronising"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_client_synchronising"); Device.PreCache(60, true, true); net_start_result_total = TRUE; } diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index 1de5fbbafe1..e2b4c88477a 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -102,8 +102,7 @@ bool CLevel::net_start1() // Start client and server if need it if (m_caServerOptions.size()) { - g_pGamePersistent->SetLoadStageTitle("st_server_starting"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_server_starting"); typedef IGame_Persistent::params params; params& p = g_pGamePersistent->m_game_params; @@ -124,7 +123,7 @@ bool CLevel::net_start1() map_data.m_name = game_sv_GameState::parse_level_name(m_caServerOptions); if (!GEnv.isDedicatedServer) - g_pGamePersistent->LoadTitle(true, map_data.m_name); + g_pGamePersistent->LoadTitle(nullptr, true, map_data.m_name); int id = pApp->Level_ID(map_data.m_name.c_str(), l_ver.c_str(), true); @@ -154,7 +153,7 @@ bool CLevel::net_start2() Server->SLS_Default(); map_data.m_name = Server->level_name(m_caServerOptions); if (!GEnv.isDedicatedServer) - g_pGamePersistent->LoadTitle(true, map_data.m_name); + g_pGamePersistent->LoadTitle(nullptr, true, map_data.m_name); } return true; } diff --git a/src/xrGame/alife_storage_manager.cpp b/src/xrGame/alife_storage_manager.cpp index bbcbc741c78..1f977492db7 100644 --- a/src/xrGame/alife_storage_manager.cpp +++ b/src/xrGame/alife_storage_manager.cpp @@ -185,11 +185,10 @@ bool CALifeStorageManager::load(LPCSTR save_name_no_check) } string512 temp; - strconcat(sizeof(temp), temp, StringTable().translate("st_loading_saved_game").c_str(), + strconcat(temp, StringTable().translate("st_loading_saved_game").c_str(), " \"", save_name, gameSaveExtension, "\""); - g_pGamePersistent->SetLoadStageTitle(temp); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle(temp); unload(); reload(m_section); diff --git a/src/xrGame/alife_update_manager.cpp b/src/xrGame/alife_update_manager.cpp index f8ec609ddfd..2d10fda3634 100644 --- a/src/xrGame/alife_update_manager.cpp +++ b/src/xrGame/alife_update_manager.cpp @@ -215,8 +215,7 @@ bool CALifeUpdateManager::change_level(NET_Packet& net_packet) #include "xrEngine/IGame_Persistent.h" void CALifeUpdateManager::new_game(LPCSTR save_name) { - g_pGamePersistent->SetLoadStageTitle("st_creating_new_game"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_creating_new_game"); Msg("* Creating new game..."); unload(); @@ -245,8 +244,7 @@ void CALifeUpdateManager::new_game(LPCSTR save_name) void CALifeUpdateManager::load(LPCSTR game_name, bool no_assert, bool new_only) { - g_pGamePersistent->SetLoadStageTitle("st_loading_alife_simulator"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_loading_alife_simulator"); #ifdef DEBUG Memory.mem_compact(); @@ -268,8 +266,7 @@ void CALifeUpdateManager::load(LPCSTR game_name, bool no_assert, bool new_only) Msg("* Loading alife simulator is successfully completed (%7.3f Mb)", float(Memory.mem_usage() - memory_usage) / 1048576.0); #endif - g_pGamePersistent->SetLoadStageTitle("st_server_connecting"); - g_pGamePersistent->LoadTitle(true, g_pGameLevel->name()); + g_pGamePersistent->LoadTitle("st_server_connecting", true, g_pGameLevel->name()); } void CALifeUpdateManager::reload(LPCSTR section) diff --git a/src/xrGame/game_sv_single.cpp b/src/xrGame/game_sv_single.cpp index 38b6fa79b81..46d37c8a89b 100644 --- a/src/xrGame/game_sv_single.cpp +++ b/src/xrGame/game_sv_single.cpp @@ -341,8 +341,7 @@ void game_sv_Single::restart_simulator(LPCSTR saved_game_name) pApp->LoadBegin(); m_alife_simulator = xr_new(&server(), &options); - g_pGamePersistent->SetLoadStageTitle("st_client_synchronising"); - g_pGamePersistent->LoadTitle(); + g_pGamePersistent->LoadTitle("st_client_synchronising"); Device.PreCache(60, true, true); pApp->LoadEnd(); } From 373f67c7944a423dd7c34acf89944466c59387f6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 00:35:22 +0500 Subject: [PATCH 039/497] xrEngine/CustomHUD.h: removed inheritance from FactoryObjectBase It's not needed since 19c51a34fb142bb63db8e4d364ab34f9c113166d, this commit is a minor addition and finalization. --- src/xrEngine/CustomHUD.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/xrEngine/CustomHUD.h b/src/xrEngine/CustomHUD.h index b2c33fe22c4..fe62189ae52 100644 --- a/src/xrEngine/CustomHUD.h +++ b/src/xrEngine/CustomHUD.h @@ -21,8 +21,7 @@ ENGINE_API extern Flags32 psHUD_Flags; class IGameObject; class ENGINE_API XR_NOVTABLE CCustomHUD - : public FactoryObjectBase, - public IEventReceiver, + : public IEventReceiver, public CUIResetNotifier { public: From 5bee9eceb5a8305df6dea0e140bcedf67b8c0e03 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 01:25:51 +0500 Subject: [PATCH 040/497] Moved loading screen and level scan functionality to IGame_Persistent --- .../xrRenderPC_R1/FStaticRender_Loader.cpp | 4 +- src/Layers/xrRender_R2/r2_loader.cpp | 4 +- src/xrEngine/IGame_Level.cpp | 4 +- src/xrEngine/IGame_Persistent.cpp | 381 +++++++++++++++++- src/xrEngine/IGame_Persistent.h | 50 ++- src/xrEngine/Text_Console.cpp | 40 -- src/xrEngine/Text_Console.h | 18 - src/xrEngine/device.cpp | 14 +- src/xrEngine/main.cpp | 10 +- src/xrEngine/x_ray.cpp | 375 +---------------- src/xrEngine/x_ray.h | 49 +-- src/xrGame/GamePersistent.cpp | 66 +-- src/xrGame/GamePersistent.h | 3 +- src/xrGame/Level_network_start_client.cpp | 8 +- src/xrGame/Level_start.cpp | 6 +- src/xrGame/alife_graph_registry.cpp | 2 +- src/xrGame/game_sv_single.cpp | 4 +- src/xrGame/script_render_device_script.cpp | 2 +- src/xrGame/ui/UILoadingScreen.h | 17 + src/xrGame/xrServer_Connect.cpp | 2 +- 20 files changed, 480 insertions(+), 579 deletions(-) diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp index ae5d26221c9..6d2770a126e 100644 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp +++ b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp @@ -13,7 +13,7 @@ void CRender::level_Load(IReader* fs) R_ASSERT(!b_loaded); // Begin - pApp->LoadBegin(); + g_pGamePersistent->LoadBegin(); Resources->DeferredLoad(TRUE); IReader* chunk; @@ -94,7 +94,7 @@ void CRender::level_Load(IReader* fs) LoadLights(fs); // End - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); b_loaded = TRUE; } diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index 16ea4cdc311..c63da2c5039 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -19,7 +19,7 @@ void CRender::level_Load(IReader* fs) R_ASSERT(!b_loaded); // Begin - pApp->LoadBegin(); + g_pGamePersistent->LoadBegin(); Resources->DeferredLoad(TRUE); IReader* chunk; @@ -98,7 +98,7 @@ void CRender::level_Load(IReader* fs) LoadLights(fs); // End - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); // signal loaded b_loaded = TRUE; diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 10ee97ccd3e..72877c76f79 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -92,7 +92,7 @@ static bool deserialize_callback(IReader& reader) bool IGame_Level::Load(u32 dwNum) { // Initialize level data - pApp->Level_Set(dwNum); + g_pGamePersistent->Level_Set(dwNum); string_path temp; if (!FS.exist(temp, "$level$", "level.ltx")) xrDebug::Fatal(DEBUG_INFO, "Can't find level configuration file '%s'.", temp); @@ -122,8 +122,6 @@ bool IGame_Level::Load(u32 dwNum) g_pGameLevel->SoundEvent_Register(S, range); }); - pApp->LoadSwitch(); - // Render-level Load GEnv.Render->level_Load(LL_Stream); // tscreate.FrameEnd (); diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index e309a76ea80..9a5c5c21dd9 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -3,7 +3,11 @@ #include "IGame_Persistent.h" #include "GameFont.h" +#include "ILoadingScreen.h" #include "PerformanceAlert.hpp" +#include "std_classes.h" +#include "StringTable/StringTable.h" +#include "xrScriptEngine/script_engine.hpp" #ifndef _EDITOR #include "Environment.h" @@ -31,6 +35,11 @@ bool IGame_Persistent::MainMenuActiveOrLevelNotExist() IGame_Persistent::IGame_Persistent() { + eStart = Engine.Event.Handler_Attach("KERNEL:start", this); + eStartLoad = Engine.Event.Handler_Attach("KERNEL:load", this); + eDisconnect = Engine.Event.Handler_Attach("KERNEL:disconnect", this); + eStartMPDemo = Engine.Event.Handler_Attach("KERNEL:start_mp_demo", this); + Device.seqAppStart.Add(this); Device.seqAppEnd.Add(this); Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1); @@ -54,26 +63,34 @@ IGame_Persistent::~IGame_Persistent() GEnv.Sound->destroy_scene(m_pSound); DefaultSoundScene = nullptr; - xr_delete(PerlinNoise1D); Device.seqFrame.Remove(this); Device.seqAppStart.Remove(this); Device.seqAppEnd.Remove(this); Device.seqAppActivate.Remove(this); Device.seqAppDeactivate.Remove(this); + + Engine.Event.Handler_Detach(eDisconnect, this); + Engine.Event.Handler_Detach(eStartLoad, this); + Engine.Event.Handler_Detach(eStart, this); + Engine.Event.Handler_Detach(eStartMPDemo, this); + + xr_delete(PerlinNoise1D); #ifndef _EDITOR xr_delete(pEnvironment); #endif - xr_delete(m_pGShaderConstants); //--#SM+#-- } void IGame_Persistent::OnAppActivate() {} void IGame_Persistent::OnAppDeactivate() {} + void IGame_Persistent::OnAppStart() { #ifndef _EDITOR Environment().load(); #endif + + Level_Scan(); } void IGame_Persistent::OnAppEnd() @@ -82,6 +99,241 @@ void IGame_Persistent::OnAppEnd() Environment().unload(); #endif OnGameEnd(); + + for (auto& level : Levels) + { + xr_free(level.folder); + xr_free(level.name); + } + Levels.clear(); +} + +void IGame_Persistent::Level_Append(pcstr folder) +{ + string_path N1, N2, N3, N4; + + strconcat(N1, folder, "level"); + strconcat(N2, folder, "level.ltx"); + strconcat(N3, folder, "level.geom"); + strconcat(N4, folder, "level.cform"); + + if (FS.exist("$game_levels$", N1) && + FS.exist("$game_levels$", N2) && + FS.exist("$game_levels$", N3) && + FS.exist("$game_levels$", N4)) + { + Levels.emplace_back(sLevelInfo{ xr_strdup(folder), nullptr }); + } +} + +void IGame_Persistent::Level_Scan() +{ + for (auto& level : Levels) + { + xr_free(level.folder); + xr_free(level.name); + } + Levels.clear(); + + xr_vector* folder = FS.file_list_open("$game_levels$", FS_ListFolders | FS_RootOnly); + if (!folder) + { + Log("! No levels found in game data"); + return; + } + + for (cpcstr i : *folder) + Level_Append(i); + + FS.file_list_close(folder); +} + +void gen_logo_name(string_path& dest, pcstr level_name, int num = -1) +{ + strconcat(sizeof(dest), dest, "intro" DELIMITER "intro_", level_name); + + const auto len = xr_strlen(dest); + if (dest[len - 1] == _DELIMITER) + dest[len - 1] = 0; + + if (num < 0) + return; + + string16 buff; + xr_strcat(dest, sizeof(dest), "_"); + xr_strcat(dest, sizeof(dest), xr_itoa(num + 1, buff, 10)); +} + +// Return true if logo exists +// Always sets the path even if logo doesn't exist +bool set_logo_path(string_path& path, pcstr levelName, int count = -1) +{ + gen_logo_name(path, levelName, count); + string_path temp2; + return FS.exist(temp2, "$game_textures$", path, ".dds") || FS.exist(temp2, "$level$", path, ".dds"); +} + +void IGame_Persistent::Level_Set(u32 id) +{ + if (id >= Levels.size()) + return; + FS.get_path("$level$")->_set(Levels[id].folder); + Level_Current = id; + + static string_path path; + path[0] = 0; + + int count = 0; + while (true) + { + if (set_logo_path(path, Levels[id].folder, count)) + count++; + else + break; + } + + if (count) + { + const int num = ::Random.randI(count); + gen_logo_name(path, Levels[id].folder, num); + } + else if (!set_logo_path(path, Levels[id].folder)) + { + if (!set_logo_path(path, "no_start_picture")) + path[0] = 0; + } + + if (path[0]) + m_pLoadingScreen->SetLevelLogo(path); +} + +int IGame_Persistent::Level_ID(pcstr name, pcstr ver, bool bSet) +{ + int result = -1; + bool arch_res = false; + + for (CLocatorAPI::archive& A : FS.m_archives) + { + if (!A.hSrcFile) + { + cpcstr ln = A.header->r_string("header", "level_name"); + cpcstr lv = A.header->r_string("header", "level_ver"); + if (0 == xr_stricmp(ln, name) && 0 == xr_stricmp(lv, ver)) + { + FS.LoadArchive(A); + arch_res = true; + } + } + } + + if (arch_res) + Level_Scan(); + + string256 buffer; + strconcat(sizeof(buffer), buffer, name, DELIMITER); + for (u32 I = 0; I < Levels.size(); ++I) + { + if (0 == xr_stricmp(buffer, Levels[I].folder)) + { + result = int(I); + break; + } + } + + if (bSet && result != -1) + Level_Set(result); + + if (arch_res) + g_pGamePersistent->OnAssetsChanged(); + return result; +} + +CInifile* IGame_Persistent::GetArchiveHeader(pcstr name, pcstr ver) +{ + for (const CLocatorAPI::archive& A : FS.m_archives) + { + if (!A.header) + continue; + + cpcstr ln = A.header->r_string("header", "level_name"); + cpcstr lv = A.header->r_string("header", "level_ver"); + if (0 == xr_stricmp(ln, name) && 0 == xr_stricmp(lv, ver)) + { + return A.header; + } + } + return nullptr; +} + +void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) +{ + if (E == eStart) + { + pstr op_server = pstr(P1); + pstr op_client = pstr(P2); + Level_Current = u32(-1); + R_ASSERT(nullptr == g_pGameLevel); + Console->Execute("main_menu off"); + Console->Hide(); + //----------------------------------------------------------- + PreStart(op_server); + //----------------------------------------------------------- + g_pGameLevel = dynamic_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); + R_ASSERT(g_pGameLevel); + LoadBegin(); + Start(op_server); + g_pGameLevel->net_Start(op_server, op_client); + LoadEnd(); + xr_free(op_server); + xr_free(op_client); + } + else if (E == eDisconnect) + { + if (pInput != nullptr && true == Engine.Event.Peek("KERNEL:quit")) + pInput->GrabInput(false); + + if (g_pGameLevel) + { + const bool show = Console->bVisible; + Console->Hide(); + g_pGameLevel->net_Stop(); + DEL_INSTANCE(g_pGameLevel); + if (show) + Console->Show(); + + if ((false == Engine.Event.Peek("KERNEL:quit")) && (false == Engine.Event.Peek("KERNEL:start"))) + { + Console->Execute("main_menu off"); + Console->Execute("main_menu on"); + } + } + Disconnect(); + } + else if (E == eStartMPDemo) + { + pstr demo_file = pstr(P1); + + R_ASSERT(nullptr == g_pGameLevel); + + Console->Execute("main_menu off"); + Console->Hide(); + Device.Reset(false); + + g_pGameLevel = dynamic_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); + VERIFY(g_pGameLevel); + const shared_str server_options = g_pGameLevel->OpenDemoFile(demo_file); + + //----------------------------------------------------------- + PreStart(server_options.c_str()); + //----------------------------------------------------------- + + LoadBegin(); + Start(""); // server_options.c_str()); - no prefetch ! + g_pGameLevel->net_StartPlayDemo(); + LoadEnd(); + + xr_free(demo_file); + } } void IGame_Persistent::PreStart(pcstr op) @@ -169,6 +421,131 @@ void IGame_Persistent::OnGameEnd() #endif } +void IGame_Persistent::LoadBegin() +{ + ll_dwReference++; + if (1 == ll_dwReference) + { + loaded = false; + phase_timer.Start(); + load_stage = 0; + } +} + +void IGame_Persistent::LoadEnd() +{ + ll_dwReference--; + if (0 == ll_dwReference) + { + Msg("* phase time: %d ms", phase_timer.GetElapsed_ms()); + Msg("* phase cmem: %d K", Memory.mem_usage() / 1024); + Console->Execute("stat_memory"); + loaded = true; + } +} + +void IGame_Persistent::LoadTitle(pcstr ls_title, bool change_tip, shared_str map_name) +{ + if (ls_title) + { + string256 buff; + xr_sprintf(buff, "%s%s", StringTable().translate(ls_title).c_str(), "..."); + m_pLoadingScreen->SetStageTitle(buff); + } + else if (!change_tip) + m_pLoadingScreen->SetStageTitle(""); + + if (change_tip) + { + bool noTips = false; + string512 buff; + u8 tip_num; + luabind::functor m_functor; + const bool is_single = !xr_strcmp(m_game_params.m_game_type, "single"); + if (is_single) + { + if (GEnv.ScriptEngine->functor("loadscreen.get_tip_number", m_functor)) + tip_num = m_functor(map_name.c_str()); + else + noTips = true; + } + else + { + if (GEnv.ScriptEngine->functor("loadscreen.get_mp_tip_number", m_functor)) + tip_num = m_functor(map_name.c_str()); + else + noTips = true; + } + if (noTips) + return; + + xr_sprintf(buff, "%s%d:", StringTable().translate("ls_tip_number").c_str(), tip_num); + const shared_str tmp = buff; + + if (is_single) + xr_sprintf(buff, "ls_tip_%d", tip_num); + else + xr_sprintf(buff, "ls_mp_tip_%d", tip_num); + + m_pLoadingScreen->SetStageTip(StringTable().translate("ls_header").c_str(), + tmp.c_str(), + StringTable().translate(buff).c_str()); + } + + LoadStage(); +} + +void IGame_Persistent::LoadStage(bool draw /*= true*/) +{ + VERIFY(ll_dwReference); + if (!load_screen_renderer.IsActive()) + { + Msg("* phase time: %d ms", phase_timer.GetElapsed_ms()); + Msg("* phase cmem: %d K", Memory.mem_usage() / 1024); + phase_timer.Start(); + } + + if (GameType() == 1 && !xr_strcmp(m_game_params.m_alife, "alife")) + max_load_stage = 18; + else + max_load_stage = 14; + + m_pLoadingScreen->Show(true); + m_pLoadingScreen->Update(load_stage, max_load_stage); + + if (draw) + LoadDraw(); + ++load_stage; +} + +void IGame_Persistent::LoadDraw() const +{ + if (loaded) + return; + + Device.dwFrame += 1; + + if (!Device.RenderBegin()) + return; + + if (GEnv.isDedicatedServer) + Console->OnRender(); + else + load_draw_internal(); + + Device.RenderEnd(); +} + +void IGame_Persistent::load_draw_internal() const +{ + m_pLoadingScreen->Draw(); +} + +void IGame_Persistent::ShowLoadingScreen(bool show) const +{ + m_pLoadingScreen->Show(show); +} + void IGame_Persistent::OnFrame() { SpatialSpace.update(); diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 7c35716450f..6ea03c7681f 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -20,6 +20,7 @@ #include "ShadersExternalData.h" //--#SM+#-- class IRenderVisual; +class ILoadingScreen; class IMainMenu; class ENGINE_API CPS_Instance; //----------------------------------------------------------------------------------------------------------- @@ -31,7 +32,8 @@ class ENGINE_API IGame_Persistent : public pureAppEnd, public pureAppActivate, public pureAppDeactivate, - public pureFrame + public pureFrame, + public IEventReceiver { public: struct ParticleStatistics @@ -133,6 +135,38 @@ class ENGINE_API IGame_Persistent : public: void destroy_particles(const bool& all_particles); +private: + EVENT eStart; + EVENT eStartLoad; + EVENT eDisconnect; + EVENT eStartMPDemo; + + u32 ll_dwReference{}; + int load_stage{}; + int max_load_stage{}; + CTimer phase_timer; + + bool loaded{}; + + // Levels + struct sLevelInfo + { + char* folder; + char* name; + }; + + xr_vector Levels; + u32 Level_Current{ u32(-1) }; + + void Level_Append(pcstr lname); + +public: + bool IsLoaded() const { return loaded; } + void Level_Scan(); + int Level_ID(pcstr name, pcstr ver, bool bSet); + void Level_Set(u32 id); + static CInifile* GetArchiveHeader(pcstr name, pcstr ver); + public: virtual void PreStart(pcstr op); virtual void Start(pcstr op); @@ -147,6 +181,7 @@ class ENGINE_API IGame_Persistent : CEnvironment& Environment() { return *pEnvironment; }; void Prefetch(); #endif + ILoadingScreen* m_pLoadingScreen{}; ISoundScene* m_pSound{}; IMainMenu* m_pMainMenu{}; static bool IsMainMenuActive(); @@ -161,6 +196,8 @@ class ENGINE_API IGame_Persistent : virtual void OnRenderPPUI_main(){}; virtual void OnRenderPPUI_PP(){}; + void OnEvent(EVENT E, u64 P1, u64 P2) override; + virtual void OnAppStart(); virtual void OnAppEnd(); virtual void OnAppActivate(); @@ -180,9 +217,18 @@ class ENGINE_API IGame_Persistent : IGame_Persistent(); virtual ~IGame_Persistent(); + // Loading + void LoadBegin(); + void LoadEnd(); + void LoadTitle(pcstr ls_title = nullptr, bool change_tip = false, shared_str map_name = nullptr); + void LoadStage(bool draw = true); + void LoadDraw() const; + + void load_draw_internal() const; + void ShowLoadingScreen(bool show) const; + ICF u32 GameType() { return m_game_params.m_e_game_type; }; virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert); - virtual void LoadTitle(pcstr /*ls_title*/ = nullptr, bool /*change_tip*/ = false, shared_str /*map_name*/ = "") {} virtual bool CanBePaused() { return true; } }; diff --git a/src/xrEngine/Text_Console.cpp b/src/xrEngine/Text_Console.cpp index 238396e6588..afcf28d8d81 100644 --- a/src/xrEngine/Text_Console.cpp +++ b/src/xrEngine/Text_Console.cpp @@ -330,43 +330,3 @@ void CTextConsole::OnFrame() SetCursor(LoadCursor(NULL, IDC_ARROW)); // m_bNeedUpdate = true; } - -void TextLoadingScreen::Initialize() -{ - -} - -bool TextLoadingScreen::IsShown() const -{ - return false; -} - -void TextLoadingScreen::Show(bool status) -{ - -} - -void TextLoadingScreen::Update(int stagesCompleted, int stagesTotal) -{ - -} - -void TextLoadingScreen::Draw() -{ - -} - -void TextLoadingScreen::SetLevelLogo(cpcstr name) -{ - -} - -void TextLoadingScreen::SetStageTitle(cpcstr title) -{ - -} - -void TextLoadingScreen::SetStageTip(cpcstr header, cpcstr tipNumber, cpcstr tip) -{ - -} diff --git a/src/xrEngine/Text_Console.h b/src/xrEngine/Text_Console.h index 3b80155702e..623dad24e6b 100644 --- a/src/xrEngine/Text_Console.h +++ b/src/xrEngine/Text_Console.h @@ -1,24 +1,6 @@ #pragma once #include "XR_IOConsole.h" #include "IGame_Level.h" -#include "xrEngine/ILoadingScreen.h" - -class TextLoadingScreen : public ILoadingScreen -{ -public: - void Initialize() override; - - [[nodiscard]] - bool IsShown() const override; - void Show(bool status) override; - - void Update(int stagesCompleted, int stagesTotal) override; - void Draw() override; - - void SetLevelLogo(cpcstr name) override; - void SetStageTitle(cpcstr title) override; - void SetStageTip(cpcstr header, cpcstr tipNumber, cpcstr tip) override; -}; class ENGINE_API CTextConsole : public CConsole { diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 0f654e447a3..59296d4ca42 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -189,7 +189,7 @@ bool CRenderDevice::BeforeFrame() { if (g_loading_events.front()()) g_loading_events.pop_front(); - pApp->LoadDraw(); + g_pGamePersistent->LoadDraw(); return false; } @@ -627,8 +627,8 @@ void CLoadScreenRenderer::Start(bool b_user_input) m_registered = true; m_need_user_input = b_user_input; - pApp->ShowLoadingScreen(true); - pApp->LoadBegin(); + g_pGamePersistent->ShowLoadingScreen(true); + g_pGamePersistent->LoadBegin(); } void CLoadScreenRenderer::Stop() @@ -641,16 +641,16 @@ void CLoadScreenRenderer::Stop() m_registered = false; m_need_user_input = false; - pApp->ShowLoadingScreen(false); - pApp->LoadEnd(); + g_pGamePersistent->ShowLoadingScreen(false); + g_pGamePersistent->LoadEnd(); } void CLoadScreenRenderer::OnFrame() { - pApp->LoadStage(false); + g_pGamePersistent->LoadStage(false); } void CLoadScreenRenderer::OnRender() { - pApp->load_draw_internal(); + g_pGamePersistent->load_draw_internal(); } diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp index e927f7aa75f..0306e3a555d 100644 --- a/src/xrEngine/main.cpp +++ b/src/xrEngine/main.cpp @@ -282,18 +282,10 @@ ENGINE_API void Startup() LALib.OnCreate(); }); - const auto& createApplication = TaskScheduler->AddTask("CreateApplication()", [](Task&, void*) - { - pApp = xr_new(); -#ifdef XR_PLATFORM_WINDOWS // XXX: Remove this macro check - if (GEnv.isDedicatedServer) - pApp->SetLoadingScreen(xr_new()); -#endif - }); + pApp = xr_new(); Device.Create(); TaskScheduler->Wait(createLightAnim); - TaskScheduler->Wait(createApplication); g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 0151e8b765d..60631fbb44f 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -9,24 +9,17 @@ #include "IGame_Level.h" #include "IGame_Persistent.h" -#include "ILoadingScreen.h" #include "XR_IOConsole.h" #include "x_ray.h" #include "std_classes.h" #include "GameFont.h" #include "xrCDB/ISpatial.h" #include "xrSASH.h" -#include "xrServerEntities/smart_cast.h" #include "xr_input.h" //--------------------------------------------------------------------- ENGINE_API CApplication* pApp = nullptr; -extern CRenderDevice Device; - -#ifdef MASTER_GOLD -#define NO_MULTI_INSTANCES -#endif // #ifdef MASTER_GOLD ////////////////////////////////////////////////////////////////////////// struct _SoundProcessor : public pureFrame @@ -40,22 +33,9 @@ struct _SoundProcessor : public pureFrame CApplication::CApplication() { - loaded = false; - ll_dwReference = 0; - - max_load_stage = 0; - // events eQuit = Engine.Event.Handler_Attach("KERNEL:quit", this); - eStart = Engine.Event.Handler_Attach("KERNEL:start", this); - eStartLoad = Engine.Event.Handler_Attach("KERNEL:load", this); - eDisconnect = Engine.Event.Handler_Attach("KERNEL:disconnect", this); eConsole = Engine.Event.Handler_Attach("KERNEL:console", this); - eStartMPDemo = Engine.Event.Handler_Attach("KERNEL:start_mp_demo", this); - - // levels - Level_Current = u32(-1); - Level_Scan(); // Register us Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000); @@ -64,13 +44,8 @@ CApplication::CApplication() Device.seqFrameMT.Add(&SoundProcessor); else Device.seqFrame.Add(&SoundProcessor); - - // App Title - loadingScreen = nullptr; } -extern CInput* pInput; - CApplication::~CApplication() { Console->Hide(); @@ -80,12 +55,8 @@ CApplication::~CApplication() Device.seqFrame.Remove(this); // events - Engine.Event.Handler_Detach(eConsole, this); - Engine.Event.Handler_Detach(eDisconnect, this); - Engine.Event.Handler_Detach(eStartLoad, this); - Engine.Event.Handler_Detach(eStart, this); Engine.Event.Handler_Detach(eQuit, this); - Engine.Event.Handler_Detach(eStartMPDemo, this); + Engine.Event.Handler_Detach(eConsole, this); } void CApplication::OnEvent(EVENT E, u64 P1, u64 P2) @@ -99,62 +70,6 @@ void CApplication::OnEvent(EVENT E, u64 P1, u64 P2) SDL_Event quit = { SDL_QUIT }; SDL_PushEvent(&quit); - - for (auto& level : Levels) - { - xr_free(level.folder); - xr_free(level.name); - } - Levels.clear(); - } - else if (E == eStart) - { - pstr op_server = pstr(P1); - pstr op_client = pstr(P2); - Level_Current = u32(-1); - R_ASSERT(nullptr == g_pGameLevel); - R_ASSERT(nullptr != g_pGamePersistent); - Console->Execute("main_menu off"); - Console->Hide(); - //! this line is commented by Dima - //! because I don't see any reason to reset device here - //! Device.Reset (false); - //----------------------------------------------------------- - g_pGamePersistent->PreStart(op_server); - //----------------------------------------------------------- - g_pGameLevel = dynamic_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); - R_ASSERT(g_pGameLevel); - LoadBegin(); - g_pGamePersistent->Start(op_server); - g_pGameLevel->net_Start(op_server, op_client); - LoadEnd(); - xr_free(op_server); - xr_free(op_client); - } - else if (E == eDisconnect) - { - if (pInput != nullptr && true == Engine.Event.Peek("KERNEL:quit")) - pInput->GrabInput(false); - - if (g_pGameLevel) - { - const bool show = Console->bVisible; - Console->Hide(); - g_pGameLevel->net_Stop(); - DEL_INSTANCE(g_pGameLevel); - if (show) - Console->Show(); - - if ((false == Engine.Event.Peek("KERNEL:quit")) && (false == Engine.Event.Peek("KERNEL:start"))) - { - Console->Execute("main_menu off"); - Console->Execute("main_menu on"); - } - } - if (g_pGamePersistent) - { - g_pGamePersistent->Disconnect(); - } } else if (E == eConsole) { @@ -162,298 +77,10 @@ void CApplication::OnEvent(EVENT E, u64 P1, u64 P2) Console->ExecuteCommand(command, false); xr_free(command); } - else if (E == eStartMPDemo) - { - pstr demo_file = pstr(P1); - - R_ASSERT(nullptr == g_pGameLevel); - R_ASSERT(nullptr != g_pGamePersistent); - - Console->Execute("main_menu off"); - Console->Hide(); - Device.Reset(false); - - g_pGameLevel = smart_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); - VERIFY(g_pGameLevel); - shared_str server_options = g_pGameLevel->OpenDemoFile(demo_file); - - //----------------------------------------------------------- - g_pGamePersistent->PreStart(server_options.c_str()); - //----------------------------------------------------------- - - LoadBegin(); - g_pGamePersistent->Start(""); // server_options.c_str()); - no prefetch ! - g_pGameLevel->net_StartPlayDemo(); - LoadEnd(); - - xr_free(demo_file); - } -} - -static CTimer phase_timer; - -void CApplication::LoadBegin() -{ - ll_dwReference++; - if (1 == ll_dwReference) - { - loaded = false; - phase_timer.Start(); - load_stage = 0; - } -} - -void CApplication::LoadEnd() -{ - ll_dwReference--; - if (0 == ll_dwReference) - { - Msg("* phase time: %d ms", phase_timer.GetElapsed_ms()); - Msg("* phase cmem: %d K", Memory.mem_usage() / 1024); - Console->Execute("stat_memory"); - loaded = true; - } -} - -void CApplication::SetLoadingScreen(ILoadingScreen* newScreen) -{ - R_ASSERT(!loadingScreen); - loadingScreen = newScreen; -} - -void CApplication::DestroyLoadingScreen() -{ - xr_delete(loadingScreen); -} - -void CApplication::ShowLoadingScreen(bool show) -{ - loadingScreen->Show(show); -} - -void CApplication::LoadDraw() -{ - if (loaded) - return; - - Device.dwFrame += 1; - - if (!Device.RenderBegin()) - return; - - if (GEnv.isDedicatedServer) - Console->OnRender(); - else - load_draw_internal(); - - Device.RenderEnd(); -} - -void CApplication::LoadTitle(pcstr _ls_title) -{ - loadingScreen->SetStageTitle(_ls_title); -} - -void CApplication::LoadTitleInt(pcstr str1, pcstr str2, pcstr str3) -{ - loadingScreen->SetStageTip(str1, str2, str3); } -void CApplication::LoadStage(bool draw /*= true*/) -{ - VERIFY(ll_dwReference); - if (!load_screen_renderer.IsActive()) - { - Msg("* phase time: %d ms", phase_timer.GetElapsed_ms()); - Msg("* phase cmem: %d K", Memory.mem_usage() / 1024); - phase_timer.Start(); - } - - if (g_pGamePersistent->GameType() == 1 && !xr_strcmp(g_pGamePersistent->m_game_params.m_alife, "alife")) - max_load_stage = 18; - else - max_load_stage = 14; - - loadingScreen->Show(true); - loadingScreen->Update(load_stage, max_load_stage); - - if (draw) - LoadDraw(); - ++load_stage; -} - -void CApplication::LoadSwitch() {} - // Sequential void CApplication::OnFrame() { Engine.Event.OnFrame(); } - -void CApplication::Level_Append(pcstr folder) -{ - string_path N1, N2, N3, N4; - strconcat(sizeof(N1), N1, folder, "level"); - strconcat(sizeof(N2), N2, folder, "level.ltx"); - strconcat(sizeof(N3), N3, folder, "level.geom"); - strconcat(sizeof(N4), N4, folder, "level.cform"); - if (FS.exist("$game_levels$", N1) && FS.exist("$game_levels$", N2) && FS.exist("$game_levels$", N3) && - FS.exist("$game_levels$", N4)) - { - sLevelInfo LI; - LI.folder = xr_strdup(folder); - LI.name = nullptr; - Levels.push_back(LI); - } -} - -void CApplication::Level_Scan() -{ - for (auto& level : Levels) - { - xr_free(level.folder); - xr_free(level.name); - } - Levels.clear(); - - xr_vector* folder = FS.file_list_open("$game_levels$", FS_ListFolders | FS_RootOnly); - if (!folder) - { - Log("! No levels found in game data"); - return; - } - - for (u32 i = 0; i < folder->size(); ++i) - Level_Append((*folder)[i]); - - FS.file_list_close(folder); -} - -void gen_logo_name(string_path& dest, pcstr level_name, int num = -1) -{ - strconcat(sizeof(dest), dest, "intro" DELIMITER "intro_", level_name); - - const auto len = xr_strlen(dest); - if (dest[len - 1] == _DELIMITER) - dest[len - 1] = 0; - - if (num < 0) - return; - - string16 buff; - xr_strcat(dest, sizeof(dest), "_"); - xr_strcat(dest, sizeof(dest), xr_itoa(num + 1, buff, 10)); -} - -// Return true if logo exists -// Always sets the path even if logo doesn't exist -bool set_logo_path(string_path& path, pcstr levelName, int count = -1) -{ - gen_logo_name(path, levelName, count); - string_path temp2; - return FS.exist(temp2, "$game_textures$", path, ".dds") || FS.exist(temp2, "$level$", path, ".dds"); -} - -void CApplication::Level_Set(u32 L) -{ - if (L >= Levels.size()) - return; - FS.get_path("$level$")->_set(Levels[L].folder); - Level_Current = L; - - static string_path path; - path[0] = 0; - - int count = 0; - while (true) - { - if (set_logo_path(path, Levels[L].folder, count)) - count++; - else - break; - } - - if (count) - { - const int num = ::Random.randI(count); - gen_logo_name(path, Levels[L].folder, num); - } - else if (!set_logo_path(path, Levels[L].folder)) - { - if (!set_logo_path(path, "no_start_picture")) - path[0] = 0; - } - - if (path[0]) - loadingScreen->SetLevelLogo(path); -} - -int CApplication::Level_ID(pcstr name, pcstr ver, bool bSet) -{ - int result = -1; - auto it = FS.m_archives.begin(); - auto it_e = FS.m_archives.end(); - bool arch_res = false; - - for (; it != it_e; ++it) - { - CLocatorAPI::archive& A = *it; - if (!A.hSrcFile) - { - pcstr ln = A.header->r_string("header", "level_name"); - pcstr lv = A.header->r_string("header", "level_ver"); - if (0 == xr_stricmp(ln, name) && 0 == xr_stricmp(lv, ver)) - { - FS.LoadArchive(A); - arch_res = true; - } - } - } - - if (arch_res) - Level_Scan(); - - string256 buffer; - strconcat(sizeof(buffer), buffer, name, DELIMITER); - for (u32 I = 0; I < Levels.size(); ++I) - { - if (0 == xr_stricmp(buffer, Levels[I].folder)) - { - result = int(I); - break; - } - } - - if (bSet && result != -1) - Level_Set(result); - - if (arch_res) - g_pGamePersistent->OnAssetsChanged(); - return result; -} - -CInifile* CApplication::GetArchiveHeader(pcstr name, pcstr ver) -{ - auto it = FS.m_archives.begin(); - auto it_e = FS.m_archives.end(); - - for (; it != it_e; ++it) - { - CLocatorAPI::archive& A = *it; - if (!A.header) - continue; - - pcstr ln = A.header->r_string("header", "level_name"); - pcstr lv = A.header->r_string("header", "level_ver"); - if (0 == xr_stricmp(ln, name) && 0 == xr_stricmp(lv, ver)) - { - return A.header; - } - } - return nullptr; -} - -void CApplication::load_draw_internal() -{ - loadingScreen->Draw(); -} diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index a676a96f50e..f830c74ce81 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -8,64 +8,17 @@ class ILoadingScreen; // definition class ENGINE_API CApplication : public pureFrame, public IEventReceiver { - // levels - struct sLevelInfo - { - char* folder; - char* name; - }; - -private: - ILoadingScreen* loadingScreen; - - int max_load_stage; - - int load_stage; - - u32 ll_dwReference; - bool loaded; - -private: EVENT eQuit; - EVENT eStart; - EVENT eStartLoad; - EVENT eDisconnect; EVENT eConsole; - EVENT eStartMPDemo; - - void Level_Append(pcstr lname); public: - bool IsLoaded() { return loaded; } - // Levels - xr_vector Levels; - u32 Level_Current; - void Level_Scan(); - int Level_ID(pcstr name, pcstr ver, bool bSet); - void Level_Set(u32 ID); - static CInifile* GetArchiveHeader(pcstr name, pcstr ver); - - // Loading - void LoadBegin(); - void LoadEnd(); - void LoadTitle(pcstr ls_title); - void LoadTitleInt(pcstr str1, pcstr str2, pcstr str3); - void LoadStage(bool draw = true); - void LoadSwitch(); - void LoadDraw(); - - virtual void OnEvent(EVENT E, u64 P1, u64 P2); + void OnEvent(EVENT E, u64 P1, u64 P2) override; // Other CApplication(); virtual ~CApplication(); virtual void OnFrame(); - void load_draw_internal(); - - void SetLoadingScreen(ILoadingScreen* newScreen); - void DestroyLoadingScreen(); - void ShowLoadingScreen(bool show); }; extern ENGINE_API CApplication* pApp; diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 143deb0f3a6..b2300208b29 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -22,7 +22,6 @@ #include "xrEngine/xrSASH.h" #include "ai_space.h" -#include "xrScriptEngine/script_engine.hpp" #include "holder_custom.h" #include "game_cl_base.h" @@ -32,7 +31,6 @@ #include "xrEngine/GameFont.h" #include "xrEngine/PerformanceAlert.hpp" #include "xrEngine/xr_input.h" -#include "xrEngine/x_ray.h" #include "ui/UILoadingScreen.h" #include "AnselManager.h" #include "xrCore/Threading/TaskManager.hpp" @@ -130,12 +128,13 @@ void CGamePersistent::OnAppStart() GEnv.UI = xr_new(); m_pMainMenu = xr_new(); + if (GEnv.isDedicatedServer) + m_pLoadingScreen = xr_new(); + else + m_pLoadingScreen = xr_new(); inherited::OnAppStart(); - if (!GEnv.isDedicatedServer) - pApp->SetLoadingScreen(xr_new()); - #ifdef XR_PLATFORM_WINDOWS ansel = xr_new(); ansel->Load(); @@ -152,7 +151,7 @@ void CGamePersistent::OnAppEnd() if (m_pMainMenu->IsActive()) m_pMainMenu->Activate(false); - pApp->DestroyLoadingScreen(); + xr_delete(m_pLoadingScreen); xr_delete(m_pMainMenu); xr_delete(GEnv.UI); @@ -689,7 +688,7 @@ void CGamePersistent::OnEvent(EVENT E, u64 P1, u64 P2) xr_free(saved_name); return; } - else if (E == eDemoStart) + if (E == eDemoStart) { string256 cmd; pstr demo = pstr(P1); @@ -697,7 +696,9 @@ void CGamePersistent::OnEvent(EVENT E, u64 P1, u64 P2) Console->Execute(cmd); xr_free(demo); uTime2Change = Device.TimerAsync() + u32(P2) * 1000; + return; } + inherited::OnEvent(E, P1, P2); } void CGamePersistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) @@ -771,57 +772,6 @@ void CGamePersistent::OnRenderPPUI_main() void CGamePersistent::OnRenderPPUI_PP() { MainMenu()->OnRenderPPUI_PP(); } -#include "xrEngine/x_ray.h" -void CGamePersistent::LoadTitle(pcstr ls_title, bool change_tip, shared_str map_name) -{ - if (ls_title) - { - string256 buff; - xr_sprintf(buff, "%s%s", StringTable().translate(ls_title).c_str(), "..."); - pApp->LoadTitle(buff); - } - else if (!change_tip) - pApp->LoadTitle(""); - - if (change_tip) - { - bool noTips = false; - string512 buff; - u8 tip_num; - luabind::functor m_functor; - const bool is_single = !xr_strcmp(m_game_params.m_game_type, "single"); - if (is_single) - { - if (GEnv.ScriptEngine->functor("loadscreen.get_tip_number", m_functor)) - tip_num = m_functor(map_name.c_str()); - else - noTips = true; - } - else - { - if (GEnv.ScriptEngine->functor("loadscreen.get_mp_tip_number", m_functor)) - tip_num = m_functor(map_name.c_str()); - else - noTips = true; - } - if (noTips) - return; - - xr_sprintf(buff, "%s%d:", StringTable().translate("ls_tip_number").c_str(), tip_num); - shared_str tmp = buff; - - if (is_single) - xr_sprintf(buff, "ls_tip_%d", tip_num); - else - xr_sprintf(buff, "ls_mp_tip_%d", tip_num); - - pApp->LoadTitleInt( - StringTable().translate("ls_header").c_str(), tmp.c_str(), StringTable().translate(buff).c_str()); - } - - pApp->LoadStage(); -} - bool CGamePersistent::CanBePaused() { return IsGameTypeSingle() || (g_pGameLevel && Level().IsDemoPlay()); } void CGamePersistent::SetPickableEffectorDOF(bool bSet) { diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 5cd5082c075..3e4f3d6aeb1 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -12,7 +12,7 @@ class CUISequencer; class UICore; class AnselManager; -class CGamePersistent : public IGame_Persistent, public IEventReceiver +class CGamePersistent : public IGame_Persistent { protected: using inherited = IGame_Persistent; @@ -87,7 +87,6 @@ class CGamePersistent : public IGame_Persistent, public IEventReceiver virtual bool OnRenderPPUI_query(); virtual void OnRenderPPUI_main(); virtual void OnRenderPPUI_PP(); - virtual void LoadTitle(pcstr ls_title = nullptr, bool change_tip = false, shared_str map_name = ""); virtual bool CanBePaused(); diff --git a/src/xrGame/Level_network_start_client.cpp b/src/xrGame/Level_network_start_client.cpp index e3795d50f16..b8923665b0c 100644 --- a/src/xrGame/Level_network_start_client.cpp +++ b/src/xrGame/Level_network_start_client.cpp @@ -21,7 +21,7 @@ bool CLevel::net_Start_client(const char* options) { return false; } bool CLevel::net_start_client1() { - pApp->LoadBegin(); + g_pGamePersistent->LoadBegin(); // name_of_server string64 name_of_server = ""; // xr_strcpy (name_of_server,*m_caClientOptions); @@ -89,7 +89,7 @@ bool CLevel::net_start_client3() rescan_mp_archives(); // because if we are using psNET_direct_connect, we not download map... } // Determine internal level-ID - int level_id = pApp->Level_ID(level_name, level_ver, true); + const int level_id = g_pGamePersistent->Level_ID(level_name, level_ver, true); if (level_id == -1) { Disconnect(); @@ -229,7 +229,7 @@ bool CLevel::net_start_client6() if (!game_configured) { - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); return true; } if (!GEnv.isDedicatedServer) @@ -260,6 +260,6 @@ bool CLevel::net_start_client6() net_start_result_total = FALSE; } - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); return true; } diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index e2b4c88477a..21026f3194e 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -26,7 +26,7 @@ bool CLevel::net_Start(const char* op_server, const char* op_client) { net_start_result_total = TRUE; - pApp->LoadBegin(); + g_pGamePersistent->LoadBegin(); string64 player_name; GetPlayerName_FromRegistry(player_name, sizeof(player_name)); @@ -125,7 +125,7 @@ bool CLevel::net_start1() if (!GEnv.isDedicatedServer) g_pGamePersistent->LoadTitle(nullptr, true, map_data.m_name); - int id = pApp->Level_ID(map_data.m_name.c_str(), l_ver.c_str(), true); + const int id = g_pGamePersistent->Level_ID(map_data.m_name.c_str(), l_ver.c_str(), true); if (id < 0) { @@ -243,7 +243,7 @@ bool CLevel::net_start6() BulletManager().Clear(); BulletManager().Load(); - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); if (net_start_result_total) { diff --git a/src/xrGame/alife_graph_registry.cpp b/src/xrGame/alife_graph_registry.cpp index 12600613b23..2e1dc371bef 100644 --- a/src/xrGame/alife_graph_registry.cpp +++ b/src/xrGame/alife_graph_registry.cpp @@ -93,7 +93,7 @@ void CALifeGraphRegistry::setup_current_level() ai().game_graph().header().levels().find(ai().game_graph().vertex(actor()->m_tGraphID)->level_id()); R_ASSERT2(ai().game_graph().header().levels().end() != I, "Graph point level ID not found!"); - [[maybe_unused]] int id = pApp->Level_ID(*(*I).second.name(), "1.0", true); + [[maybe_unused]] const int id = g_pGamePersistent->Level_ID(*(*I).second.name(), "1.0", true); VERIFY3(id >= 0, "Level is corrupted or doesn't exist", *(*I).second.name()); ai().load(*(*I).second.name()); diff --git a/src/xrGame/game_sv_single.cpp b/src/xrGame/game_sv_single.cpp index 46d37c8a89b..3d102a33edc 100644 --- a/src/xrGame/game_sv_single.cpp +++ b/src/xrGame/game_sv_single.cpp @@ -339,9 +339,9 @@ void game_sv_Single::restart_simulator(LPCSTR saved_game_name) xr_strcpy(g_pGamePersistent->m_game_params.m_game_or_spawn, saved_game_name); xr_strcpy(g_pGamePersistent->m_game_params.m_new_or_load, "load"); - pApp->LoadBegin(); + g_pGamePersistent->LoadBegin(); m_alife_simulator = xr_new(&server(), &options); g_pGamePersistent->LoadTitle("st_client_synchronising"); Device.PreCache(60, true, true); - pApp->LoadEnd(); + g_pGamePersistent->LoadEnd(); } diff --git a/src/xrGame/script_render_device_script.cpp b/src/xrGame/script_render_device_script.cpp index 18e7dbf6baf..409b802457f 100644 --- a/src/xrGame/script_render_device_script.cpp +++ b/src/xrGame/script_render_device_script.cpp @@ -12,7 +12,7 @@ bool is_device_paused(CRenderDevice* d) { return !!Device.Paused(); } void set_device_paused(CRenderDevice* d, bool b) { Device.Pause(b, TRUE, FALSE, "set_device_paused_script"); } -bool is_app_ready() { return pApp->IsLoaded(); } +bool is_app_ready() { return g_pGamePersistent->IsLoaded(); } u32 time_global(const CRenderDevice* self) { THROW(self); diff --git a/src/xrGame/ui/UILoadingScreen.h b/src/xrGame/ui/UILoadingScreen.h index 6ca0c28c936..ccff330c4a9 100644 --- a/src/xrGame/ui/UILoadingScreen.h +++ b/src/xrGame/ui/UILoadingScreen.h @@ -47,3 +47,20 @@ class UILoadingScreen final : public ILoadingScreen, public CUIWindow pcstr GetDebugType() override { return "UILoadingScreen"; } }; + +class NullLoadingScreen : public ILoadingScreen +{ +public: + void Initialize() override {} + + [[nodiscard]] + bool IsShown() const override { return false; } + void Show(bool /*status*/) override {} + + void Update(int /*stagesCompleted*/, int /*stagesTotal*/) override {} + void Draw() override {} + + void SetLevelLogo(cpcstr /*name*/) override {} + void SetStageTitle(cpcstr /*title*/) override {} + void SetStageTip(cpcstr /*header*/, cpcstr /*tipNumber*/, cpcstr /*tip*/) override {} +}; diff --git a/src/xrGame/xrServer_Connect.cpp b/src/xrGame/xrServer_Connect.cpp index 5baed59d67f..f9cf35b3725 100644 --- a/src/xrGame/xrServer_Connect.cpp +++ b/src/xrGame/xrServer_Connect.cpp @@ -18,7 +18,7 @@ LPCSTR xrServer::get_map_download_url(LPCSTR level_name, LPCSTR level_version) { R_ASSERT(level_name && level_version); LPCSTR ret_url = ""; - CInifile* level_ini = pApp->GetArchiveHeader(level_name, level_version); + CInifile* level_ini = g_pGamePersistent->GetArchiveHeader(level_name, level_version); if (!level_ini) { if (!IsGameTypeSingle()) From f14a3a3d8584284c482ea62848b62b76c6e29d48 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 01:26:51 +0500 Subject: [PATCH 041/497] Fixed dedicated server crash on start --- src/xrGame/UIDialogHolder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/UIDialogHolder.cpp b/src/xrGame/UIDialogHolder.cpp index 2faf3938ebd..2db02981009 100644 --- a/src/xrGame/UIDialogHolder.cpp +++ b/src/xrGame/UIDialogHolder.cpp @@ -225,7 +225,7 @@ void CDialogHolder::OnFrame() { m_b_in_update = true; - if (GetUICursor().IsVisible() && pInput->IsCurrentInputTypeController()) + if (!GEnv.isDedicatedServer && GetUICursor().IsVisible() && pInput->IsCurrentInputTypeController()) GetUICursor().UpdateAutohideTiming(); CUIDialogWnd* wnd = TopInputReceiver(); From eddd3d03e76f04b09b4a952267b03ef6daaf46ec Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 01:29:28 +0500 Subject: [PATCH 042/497] Fixed Linux/macOS build --- src/xrCore/FS_internal.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/xrCore/FS_internal.h b/src/xrCore/FS_internal.h index 8a7468f1ea2..3ad13a8638a 100644 --- a/src/xrCore/FS_internal.h +++ b/src/xrCore/FS_internal.h @@ -38,7 +38,11 @@ class CFileWriter final : public IWriter const int handle = _sopen(conv_fn, _O_WRONLY | _O_TRUNC | _O_CREAT | _O_BINARY, SH_DENYWR); #ifndef MASTER_GOLD if (handle == -1) - Msg("! Can't create file: '%s'. Error: '%s'.", conv_fn, _sys_errlist[errno]); + { + string1024 error; + xr_strerror(errno, error, sizeof(error)); + Msg("! Can't create file: '%s'. Error: '%s'.", conv_fn, error); + } #endif hf = _fdopen(handle, "wb"); } From be13bcffaeb8f1be30985e523b9c8d830733a2e9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 01:37:50 +0500 Subject: [PATCH 043/497] xrMaterialSystem/GameMtlLib.h|cpp: constify, modernize --- src/xrMaterialSystem/GameMtlLib.cpp | 22 ++++++++++------------ src/xrMaterialSystem/GameMtlLib.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/xrMaterialSystem/GameMtlLib.cpp b/src/xrMaterialSystem/GameMtlLib.cpp index 9447e1e64fb..2c66f9b1572 100644 --- a/src/xrMaterialSystem/GameMtlLib.cpp +++ b/src/xrMaterialSystem/GameMtlLib.cpp @@ -5,11 +5,11 @@ CGameMtlLibrary GMLib; #ifdef DEBUG -const char* SGameMtlPair::dbg_Name() +const char* SGameMtlPair::dbg_Name() const { static string256 nm; - SGameMtl* M0 = GMLib.GetMaterialByID(GetMtl0()); - SGameMtl* M1 = GMLib.GetMaterialByID(GetMtl1()); + const SGameMtl* M0 = GMLib.GetMaterialByID(GetMtl0()); + const SGameMtl* M1 = GMLib.GetMaterialByID(GetMtl1()); xr_sprintf(nm, sizeof(nm), "Pair: %s - %s", *M0->m_Name, *M1->m_Name); return nm; } @@ -79,7 +79,7 @@ void CGameMtlLibrary::Load() IReader& fs = *F; R_ASSERT(fs.find_chunk(GAMEMTLS_CHUNK_VERSION)); - u16 version = fs.r_u16(); + const u16 version = fs.r_u16(); if (GAMEMTL_CURRENT_VERSION != version) { Log("CGameMtlLibrary: invalid version. Library can't load."); @@ -102,9 +102,8 @@ void CGameMtlLibrary::Load() u32 count; for (IReader* O = OBJ->open_chunk_iterator(count); O; O = OBJ->open_chunk_iterator(count, O)) { - SGameMtl* M = xr_new(); + SGameMtl* M = materials.emplace_back(xr_new()); M->Load(*O); - materials.push_back(M); } OBJ->close(); } @@ -115,18 +114,17 @@ void CGameMtlLibrary::Load() u32 count; for (IReader* O = OBJ->open_chunk_iterator(count); O; O = OBJ->open_chunk_iterator(count, O)) { - SGameMtlPair* M = xr_new(this); + SGameMtlPair* M = material_pairs.emplace_back(xr_new(this)); M->Load(*O); - material_pairs.push_back(M); } OBJ->close(); } - u32 mtlCount = materials.size(); + const u32 mtlCount = materials.size(); material_pairs_rt.resize(mtlCount * mtlCount, 0); - for (auto& mtlPair : material_pairs) + for (const auto& mtlPair : material_pairs) { - int idx0 = GetMaterialIdx(mtlPair->mtl0) * mtlCount + GetMaterialIdx(mtlPair->mtl1); - int idx1 = GetMaterialIdx(mtlPair->mtl1) * mtlCount + GetMaterialIdx(mtlPair->mtl0); + const int idx0 = GetMaterialIdx(mtlPair->mtl0) * mtlCount + GetMaterialIdx(mtlPair->mtl1); + const int idx1 = GetMaterialIdx(mtlPair->mtl1) * mtlCount + GetMaterialIdx(mtlPair->mtl0); material_pairs_rt[idx0] = mtlPair; material_pairs_rt[idx1] = mtlPair; } diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index e14e44e308e..16eac3d9010 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -191,7 +191,7 @@ struct MTL_EXPORT_API SGameMtlPair void Save(IWriter& fs); void Load(IReader& fs); #ifdef DEBUG - const char* dbg_Name(); + const char* dbg_Name() const; #endif #ifdef _EDITOR From 396bcce1222c162d208cb3a2bc9ce14ed2213bbd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 02:25:19 +0500 Subject: [PATCH 044/497] xrEngine/device.h: removed draw_loadscreen param from PreCache It's always true anyway. That call in Device_create was there to just initialize the variables, but they already initialized in the constructor. --- src/xrEngine/Device_create.cpp | 1 - src/xrEngine/Device_destroy.cpp | 2 +- src/xrEngine/FDemoPlay.cpp | 2 +- src/xrEngine/device.cpp | 4 ++-- src/xrEngine/device.h | 2 +- src/xrGame/Level_network_start_client.cpp | 2 +- src/xrGame/MainMenu.cpp | 2 +- src/xrGame/game_sv_single.cpp | 2 +- 8 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index 0f5e577414d..1bf765e5631 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -47,5 +47,4 @@ void CRenderDevice::Create() m_editor.OnDeviceCreate(); Statistic->OnDeviceCreate(); dwFrame = 0; - PreCache(0, false, false); } diff --git a/src/xrEngine/Device_destroy.cpp b/src/xrEngine/Device_destroy.cpp index f7a4ab85cd2..53273bb5cbe 100644 --- a/src/xrEngine/Device_destroy.cpp +++ b/src/xrEngine/Device_destroy.cpp @@ -53,7 +53,7 @@ void CRenderDevice::Reset(bool precache /*= true*/) SetupStates(); if (precache) - PreCache(20, true, false); + PreCache(20, false); const auto tm_end = TimerAsync(); Msg("*** RESET [%d ms]", tm_end - tm_start); diff --git a/src/xrEngine/FDemoPlay.cpp b/src/xrEngine/FDemoPlay.cpp index abd0bcf7fd1..13639fc51d4 100644 --- a/src/xrEngine/FDemoPlay.cpp +++ b/src/xrEngine/FDemoPlay.cpp @@ -67,7 +67,7 @@ CDemoPlay::CDemoPlay(const char* name, float ms, u32 cycles, float life_time) Log("~ Total key-frames: ", m_count); } stat_started = false; - Device.PreCache(50, true, false); + Device.PreCache(50, false); } CDemoPlay::~CDemoPlay() diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 59296d4ca42..e6bcdb58be2 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -122,7 +122,7 @@ void CRenderDevice::RenderEnd(void) } #include "IGame_Level.h" -void CRenderDevice::PreCache(u32 amount, bool draw_loadscreen, bool wait_user_input) +void CRenderDevice::PreCache(u32 amount, bool wait_user_input) { if (GEnv.isDedicatedServer) amount = 0; @@ -139,7 +139,7 @@ void CRenderDevice::PreCache(u32 amount, bool draw_loadscreen, bool wait_user_in precache_light->set_range(5.0f); precache_light->set_active(true); } - if (amount && draw_loadscreen && !load_screen_renderer.IsActive()) + if (amount && !load_screen_renderer.IsActive()) { load_screen_renderer.Start(wait_user_input); } diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 83038190fa6..09cc982b13b 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -169,7 +169,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler // Scene control void ProcessFrame(); - void PreCache(u32 amount, bool draw_loadscreen, bool wait_user_input); + void PreCache(u32 amount, bool wait_user_input); bool BeforeFrame(); void FrameMove(); diff --git a/src/xrGame/Level_network_start_client.cpp b/src/xrGame/Level_network_start_client.cpp index b8923665b0c..566c3af90ec 100644 --- a/src/xrGame/Level_network_start_client.cpp +++ b/src/xrGame/Level_network_start_client.cpp @@ -252,7 +252,7 @@ bool CLevel::net_start_client6() } g_pGamePersistent->LoadTitle("st_client_synchronising"); - Device.PreCache(60, true, true); + Device.PreCache(60, true); net_start_result_total = TRUE; } else diff --git a/src/xrGame/MainMenu.cpp b/src/xrGame/MainMenu.cpp index 7b59e08255f..c44a2531aeb 100644 --- a/src/xrGame/MainMenu.cpp +++ b/src/xrGame/MainMenu.cpp @@ -316,7 +316,7 @@ void CMainMenu::Activate(bool bActivate) Device.Reset(); #else // Do only a precache for Debug and Mixed - Device.PreCache(20, true, false); + Device.PreCache(20, false); #endif } } diff --git a/src/xrGame/game_sv_single.cpp b/src/xrGame/game_sv_single.cpp index 3d102a33edc..d4a3b05a27a 100644 --- a/src/xrGame/game_sv_single.cpp +++ b/src/xrGame/game_sv_single.cpp @@ -342,6 +342,6 @@ void game_sv_Single::restart_simulator(LPCSTR saved_game_name) g_pGamePersistent->LoadBegin(); m_alife_simulator = xr_new(&server(), &options); g_pGamePersistent->LoadTitle("st_client_synchronising"); - Device.PreCache(60, true, true); + Device.PreCache(60, true); g_pGamePersistent->LoadEnd(); } From d72e982201b9f8bf8f303b16bd42218367478850 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 10:01:22 +0500 Subject: [PATCH 045/497] xrEngine/IGame_Persistent.h: made IsMainMenuActive and MainMenuActiveOrLevelNotExist not static It's completely nonsense to have them static. --- src/Layers/xrRenderPC_R1/FStaticRender.cpp | 4 ++-- src/Layers/xrRender_R2/r2.cpp | 4 ++-- src/xrEngine/IGame_Persistent.cpp | 22 +++++++++++----------- src/xrEngine/IGame_Persistent.h | 5 +++-- src/xrGame/ai/stalker/ai_stalker.cpp | 2 +- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Layers/xrRenderPC_R1/FStaticRender.cpp b/src/Layers/xrRenderPC_R1/FStaticRender.cpp index 4bb1f1269c9..0e83e26464f 100644 --- a/src/Layers/xrRenderPC_R1/FStaticRender.cpp +++ b/src/Layers/xrRenderPC_R1/FStaticRender.cpp @@ -166,7 +166,7 @@ void CRender::reset_end() void CRender::BeforeRender() { - if (IGame_Persistent::MainMenuActiveOrLevelNotExist()) + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; ProcessHOMTask = &TaskScheduler->AddTask("MT-HOM", { &HOM, &CHOM::MT_RENDER }); @@ -175,7 +175,7 @@ void CRender::BeforeRender() void CRender::OnFrame() { Models->DeleteQueue(); - if (IGame_Persistent::MainMenuActiveOrLevelNotExist()) + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; if (ps_r2_ls_flags.test(R2FLAG_EXP_MT_CALC)) { diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index bcce145c8ec..d1433aecefc 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -719,7 +719,7 @@ void CRender::reset_end() void CRender::BeforeRender() { - if (IGame_Persistent::MainMenuActiveOrLevelNotExist()) + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; ProcessHOMTask = &TaskScheduler->AddTask("MT-HOM", { &HOM, &CHOM::MT_RENDER }); @@ -728,7 +728,7 @@ void CRender::BeforeRender() void CRender::OnFrame() { Models->DeleteQueue(); - if (IGame_Persistent::MainMenuActiveOrLevelNotExist()) + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; if (ps_r2_ls_flags.test(R2FLAG_EXP_MT_CALC)) { diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 9a5c5c21dd9..ca78fa418b1 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -22,17 +22,6 @@ ENGINE_API IGame_Persistent* g_pGamePersistent = nullptr; -//ECO_RENDER add -bool IGame_Persistent::IsMainMenuActive() -{ - return g_pGamePersistent && g_pGamePersistent->m_pMainMenu && g_pGamePersistent->m_pMainMenu->IsActive(); -} - -bool IGame_Persistent::MainMenuActiveOrLevelNotExist() -{ - return !g_pGameLevel || g_pGamePersistent->m_pMainMenu && g_pGamePersistent->m_pMainMenu->IsActive(); -} - IGame_Persistent::IGame_Persistent() { eStart = Engine.Event.Handler_Attach("KERNEL:start", this); @@ -624,6 +613,17 @@ void IGame_Persistent::destroy_particles(const bool& all_particles) #endif } +//ECO_RENDER add +bool IGame_Persistent::IsMainMenuActive() const +{ + return m_pMainMenu && m_pMainMenu->IsActive(); +} + +bool IGame_Persistent::MainMenuActiveOrLevelNotExist() const +{ + return !g_pGameLevel || IsMainMenuActive(); +} + void IGame_Persistent::OnAssetsChanged() { #ifndef _EDITOR diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 6ea03c7681f..befccdef1c7 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -184,8 +184,9 @@ class ENGINE_API IGame_Persistent : ILoadingScreen* m_pLoadingScreen{}; ISoundScene* m_pSound{}; IMainMenu* m_pMainMenu{}; - static bool IsMainMenuActive(); - static bool MainMenuActiveOrLevelNotExist(); + + bool IsMainMenuActive() const; + bool MainMenuActiveOrLevelNotExist() const; ParticleStatistics stats; diff --git a/src/xrGame/ai/stalker/ai_stalker.cpp b/src/xrGame/ai/stalker/ai_stalker.cpp index c1cf7cc2d5a..128a4d733c3 100644 --- a/src/xrGame/ai/stalker/ai_stalker.cpp +++ b/src/xrGame/ai/stalker/ai_stalker.cpp @@ -790,7 +790,7 @@ void CAI_Stalker::update_object_handler() bool CAI_Stalker::mt_object_handler_update_allowed() const { return m_client_updated && - (g_pGameLevel->WorldRendered() || IGame_Persistent::IsMainMenuActive()) + (g_pGameLevel->WorldRendered() || g_pGamePersistent->IsMainMenuActive()) #ifdef DEBUG && !ShouldProcessOnRender() #endif From 46b1caeedf995ae4750219c49afdb5c4a71ea7ce Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 10:37:15 +0500 Subject: [PATCH 046/497] xrEngine/Device_initialize.cpp: don't call Device indirectly We are already Device --- src/xrEngine/Device_Initialize.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index 0f00bf0acb6..9490aeb53c1 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -63,8 +63,8 @@ void CRenderDevice::Initialize() if (!GEnv.isDedicatedServer) { - Device.seqAppStart.Add(&m_editor); - Device.seqAppEnd.Add(&m_editor); + seqAppStart.Add(&m_editor); + seqAppEnd.Add(&m_editor); } } From c161b9eaa742989c4ae6c57061dcca4d192e54c0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 10:53:09 +0500 Subject: [PATCH 047/497] Moved CApplication functionality into CEngine --- src/xrEngine/Engine.cpp | 105 ++++++++++++++++++++++++++++++++++--- src/xrEngine/Engine.h | 9 +++- src/xrEngine/EngineAPI.cpp | 1 - src/xrEngine/main.cpp | 69 +++++------------------- src/xrEngine/main.h | 3 -- src/xrEngine/x_ray.cpp | 54 +------------------ src/xrEngine/x_ray.h | 12 ++--- src/xrEngine/xrSASH.cpp | 4 +- 8 files changed, 124 insertions(+), 133 deletions(-) diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 63458cb3bd7..767969ee0d4 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -5,26 +5,117 @@ #include "stdafx.h" #include "Engine.h" -CEngine Engine; +#include "xrSASH.h" +#include "XR_IOConsole.h" +#include "xr_ioc_cmd.h" -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// +struct _SoundProcessor final : public pureFrame +{ + void OnFrame() override + { + // Msg ("------------- sound: %d [%3.2f,%3.2f,%3.2f]",u32(Device.dwFrame),VPUSH(Device.vCameraPosition)); + GEnv.Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop); + } +} SoundProcessor; + +CEngine Engine; CEngine::CEngine() {} CEngine::~CEngine() {} + +void CheckAndSetupRenderer() +{ + if (GEnv.isDedicatedServer) + { + Console->Execute("renderer renderer_r1"); + return; + } + + if (strstr(Core.Params, "-rgl")) + Console->Execute("renderer renderer_rgl"); + else if (strstr(Core.Params, "-r4")) + Console->Execute("renderer renderer_r4"); + else if (strstr(Core.Params, "-r3")) + Console->Execute("renderer renderer_r3"); + else if (strstr(Core.Params, "-r2.5")) + Console->Execute("renderer renderer_r2.5"); + else if (strstr(Core.Params, "-r2a")) + Console->Execute("renderer renderer_r2a"); + else if (strstr(Core.Params, "-r2")) + Console->Execute("renderer renderer_r2"); + else if (strstr(Core.Params, "-r1")) + Console->Execute("renderer renderer_r1"); + else + { + CCC_LoadCFG_custom cmd("renderer "); + cmd.Execute(Console->ConfigFile); + renderer_allow_override = true; + } +} + extern void msCreate(pcstr name); void CEngine::Initialize(void) { - Engine.Sheduler.Initialize(); #ifdef DEBUG msCreate("game"); #endif + + // events + eQuit = Event.Handler_Attach("KERNEL:quit", this); + eConsole = Event.Handler_Attach("KERNEL:console", this); + + // Register us + Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000); + + if (psDeviceFlags.test(mtSound)) + Device.seqFrameMT.Add(&SoundProcessor); + else + Device.seqFrame.Add(&SoundProcessor); + + External.CreateRendererList(); + CheckAndSetupRenderer(); + + External.Initialize(); + Sheduler.Initialize(); } void CEngine::Destroy() { - Engine.Sheduler.Destroy(); - Engine.External.Destroy(); + Sheduler.Destroy(); + External.Destroy(); + Event._destroy(); + + // events + Event.Handler_Detach(eQuit, this); + Event.Handler_Detach(eConsole, this); + + Device.seqFrameMT.Remove(&SoundProcessor); + Device.seqFrame.Remove(&SoundProcessor); + Device.seqFrame.Remove(this); +} + +void CEngine::OnEvent(EVENT E, u64 P1, u64 P2) +{ + if (E == eQuit) + { + if (pInput != nullptr) + pInput->GrabInput(false); + + g_SASH.EndBenchmark(); + + SDL_Event quit = { SDL_QUIT }; + SDL_PushEvent(&quit); + } + else if (E == eConsole) + { + pstr command = (pstr)P1; + Console->ExecuteCommand(command, false); + xr_free(command); + } +} + +void CEngine::OnFrame() +{ + Event.OnFrame(); } diff --git a/src/xrEngine/Engine.h b/src/xrEngine/Engine.h index 392379efcf1..57d06f787d6 100644 --- a/src/xrEngine/Engine.h +++ b/src/xrEngine/Engine.h @@ -10,6 +10,7 @@ # endif #endif +#include "pure.h" #include "EngineAPI.h" #include "EventAPI.h" #include "xrSheduler.h" @@ -21,8 +22,11 @@ #define R__NUM_PARALLEL_CONTEXTS (R__NUM_SUN_CASCADES + R__NUM_AUX_CONTEXTS) #define R__NUM_CONTEXTS (R__NUM_PARALLEL_CONTEXTS + 1/* imm */) -class ENGINE_API CEngine +class ENGINE_API CEngine final : public pureFrame, public IEventReceiver { + EVENT eQuit; + EVENT eConsole; + public: // DLL api stuff CEngineAPI External; @@ -33,6 +37,9 @@ class ENGINE_API CEngine void Initialize(); void Destroy(); + void OnEvent(EVENT E, u64 P1, u64 P2) override; + void OnFrame() override; + CEngine(); ~CEngine(); }; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 60ac73d6207..4fd06c75ace 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -140,7 +140,6 @@ void CEngineAPI::Destroy(void) hGame = nullptr; renderers.clear(); - Engine.Event._destroy(); XRC.r_clear_compact(); } diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp index 0306e3a555d..ba7712b008d 100644 --- a/src/xrEngine/main.cpp +++ b/src/xrEngine/main.cpp @@ -44,14 +44,6 @@ bool CheckBenchmark(); void RunBenchmark(pcstr name); } -ENGINE_API void InitEngine() -{ - Engine.Initialize(); - Device.Initialize(); - - Console->OnDeviceInitialize(); -} - namespace { struct PathIncludePred @@ -197,55 +189,19 @@ ENGINE_API void destroyConsole() xr_delete(Console); } -ENGINE_API void destroyEngine() -{ - Device.Destroy(); - Engine.Destroy(); -} - void execUserScript() { Console->Execute("default_controls"); Console->ExecuteScript(Console->ConfigFile); } -void CheckAndSetupRenderer() -{ - if (GEnv.isDedicatedServer) - { - Console->Execute("renderer renderer_r1"); - return; - } - - if (strstr(Core.Params, "-rgl")) - Console->Execute("renderer renderer_rgl"); - else if (strstr(Core.Params, "-r4")) - Console->Execute("renderer renderer_r4"); - else if (strstr(Core.Params, "-r3")) - Console->Execute("renderer renderer_r3"); - else if (strstr(Core.Params, "-r2.5")) - Console->Execute("renderer renderer_r2.5"); - else if (strstr(Core.Params, "-r2a")) - Console->Execute("renderer renderer_r2a"); - else if (strstr(Core.Params, "-r2")) - Console->Execute("renderer renderer_r2"); - else if (strstr(Core.Params, "-r1")) - Console->Execute("renderer renderer_r1"); - else - { - CCC_LoadCFG_custom cmd("renderer "); - cmd.Execute(Console->ConfigFile); - renderer_allow_override = true; - } -} - void slowdownthread(void*) { for (;;) { if (Device.GetStats().fFPS < 30) Sleep(1); - if (Device.mt_bMustExit || !pSettings || !Console || !pInput || !pApp) + if (Device.mt_bMustExit || !pSettings || !Console || !pInput) return; } } @@ -282,8 +238,6 @@ ENGINE_API void Startup() LALib.OnCreate(); }); - pApp = xr_new(); - Device.Create(); TaskScheduler->Wait(createLightAnim); @@ -297,7 +251,6 @@ ENGINE_API void Startup() // Destroy APP DEL_INSTANCE(g_pGamePersistent); - xr_delete(pApp); Engine.Event.Dump(); // Destroying @@ -313,7 +266,6 @@ ENGINE_API void Startup() Console->Destroy(); Device.CleanupVideoModes(); - destroyEngine(); destroySound(); } @@ -338,16 +290,19 @@ ENGINE_API int RunApplication() InitInput(); InitConsole(); - Engine.External.CreateRendererList(); - CheckAndSetupRenderer(); + Engine.Initialize(); + Device.Initialize(); - Engine.External.Initialize(); - InitEngine(); + Console->OnDeviceInitialize(); - if (CheckBenchmark()) - return 0; + //if (CheckBenchmark()) + // return 0; Startup(); + + Device.Destroy(); + Engine.Destroy(); + // check for need to execute something external if (/*xr_strlen(g_sLaunchOnExit_params) && */ xr_strlen(g_sLaunchOnExit_app)) { @@ -413,8 +368,8 @@ void RunBenchmark(pcstr name) xr_strlwr(Core.Params); InitInput(); Engine.External.Initialize(); - if (i) - InitEngine(); + //if (i) + // InitEngine(); xr_strcpy(Console->ConfigFile, "user.ltx"); if (strstr(Core.Params, "-ltx ")) { diff --git a/src/xrEngine/main.h b/src/xrEngine/main.h index c9b8ccf9e15..952c1b67c61 100644 --- a/src/xrEngine/main.h +++ b/src/xrEngine/main.h @@ -1,8 +1,5 @@ #pragma once -ENGINE_API void InitEngine(); -ENGINE_API void destroyEngine(); - ENGINE_API void InitSettings(); ENGINE_API void destroySettings(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 60631fbb44f..06a6f0a2f2f 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -19,68 +19,16 @@ //--------------------------------------------------------------------- -ENGINE_API CApplication* pApp = nullptr; +ENGINE_API CApplication Application; ////////////////////////////////////////////////////////////////////////// -struct _SoundProcessor : public pureFrame -{ - virtual void OnFrame() - { - // Msg ("------------- sound: %d [%3.2f,%3.2f,%3.2f]",u32(Device.dwFrame),VPUSH(Device.vCameraPosition)); - GEnv.Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop); - } -} SoundProcessor; CApplication::CApplication() { - // events - eQuit = Engine.Event.Handler_Attach("KERNEL:quit", this); - eConsole = Engine.Event.Handler_Attach("KERNEL:console", this); - - // Register us - Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000); - if (psDeviceFlags.test(mtSound)) - Device.seqFrameMT.Add(&SoundProcessor); - else - Device.seqFrame.Add(&SoundProcessor); } CApplication::~CApplication() { - Console->Hide(); - - Device.seqFrameMT.Remove(&SoundProcessor); - Device.seqFrame.Remove(&SoundProcessor); - Device.seqFrame.Remove(this); - // events - Engine.Event.Handler_Detach(eQuit, this); - Engine.Event.Handler_Detach(eConsole, this); -} - -void CApplication::OnEvent(EVENT E, u64 P1, u64 P2) -{ - if (E == eQuit) - { - if (pInput != nullptr) - pInput->GrabInput(false); - - g_SASH.EndBenchmark(); - - SDL_Event quit = { SDL_QUIT }; - SDL_PushEvent(&quit); - } - else if (E == eConsole) - { - pstr command = (pstr)P1; - Console->ExecuteCommand(command, false); - xr_free(command); - } -} - -// Sequential -void CApplication::OnFrame() -{ - Engine.Event.OnFrame(); } diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index f830c74ce81..45a6efde65f 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -6,21 +6,15 @@ class ENGINE_API CGameFont; class ILoadingScreen; // definition -class ENGINE_API CApplication : public pureFrame, public IEventReceiver +class ENGINE_API CApplication final { - EVENT eQuit; - EVENT eConsole; public: - void OnEvent(EVENT E, u64 P1, u64 P2) override; - // Other CApplication(); - virtual ~CApplication(); - - virtual void OnFrame(); + ~CApplication(); }; -extern ENGINE_API CApplication* pApp; +extern ENGINE_API CApplication Application; #endif //__XR_BASE_H__ diff --git a/src/xrEngine/xrSASH.cpp b/src/xrEngine/xrSASH.cpp index 12be558ae83..802ecf7c4af 100644 --- a/src/xrEngine/xrSASH.cpp +++ b/src/xrEngine/xrSASH.cpp @@ -453,7 +453,7 @@ void xrSASH::TryInitEngine(bool bNoRun) { if (m_bReinitEngine) { - InitEngine(); + //InitEngine(); // It was destroyed on previous exit Console->Initialize(); } @@ -520,7 +520,7 @@ void xrSASH::ReleaseEngine() Console->Destroy(); Device.CleanupVideoModes(); destroySound(); - destroyEngine(); + //destroyEngine(); } #ifdef XR_PLATFORM_WINDOWS From bd0887cfb00a90d2fe0b80a07cb040a3699ea85e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 10:56:54 +0500 Subject: [PATCH 048/497] Moved KERNEL:console event to CConsole class --- src/xrEngine/Engine.cpp | 11 ----------- src/xrEngine/Engine.h | 1 - src/xrEngine/XR_IOConsole.cpp | 10 ++++++++++ src/xrEngine/XR_IOConsole.h | 11 +++++++++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 767969ee0d4..15353fb6a36 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -61,11 +61,8 @@ void CEngine::Initialize(void) msCreate("game"); #endif - // events eQuit = Event.Handler_Attach("KERNEL:quit", this); - eConsole = Event.Handler_Attach("KERNEL:console", this); - // Register us Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000); if (psDeviceFlags.test(mtSound)) @@ -86,9 +83,7 @@ void CEngine::Destroy() External.Destroy(); Event._destroy(); - // events Event.Handler_Detach(eQuit, this); - Event.Handler_Detach(eConsole, this); Device.seqFrameMT.Remove(&SoundProcessor); Device.seqFrame.Remove(&SoundProcessor); @@ -107,12 +102,6 @@ void CEngine::OnEvent(EVENT E, u64 P1, u64 P2) SDL_Event quit = { SDL_QUIT }; SDL_PushEvent(&quit); } - else if (E == eConsole) - { - pstr command = (pstr)P1; - Console->ExecuteCommand(command, false); - xr_free(command); - } } void CEngine::OnFrame() diff --git a/src/xrEngine/Engine.h b/src/xrEngine/Engine.h index 57d06f787d6..fd67507acb5 100644 --- a/src/xrEngine/Engine.h +++ b/src/xrEngine/Engine.h @@ -25,7 +25,6 @@ class ENGINE_API CEngine final : public pureFrame, public IEventReceiver { EVENT eQuit; - EVENT eConsole; public: // DLL api stuff diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index eb39bc471b7..b9d5e2b80a9 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -124,6 +124,8 @@ void CConsole::Initialize() m_cur_cmd = NULL; reset_selected_tip(); + eConsole = Engine.Event.Handler_Attach("KERNEL:console", this); + // Commands extern void CCC_Register(); CCC_Register(); @@ -142,6 +144,7 @@ void CConsole::Destroy() xr_delete(pFont); xr_delete(pFont2); Commands.clear(); + Engine.Event.Handler_Detach(eConsole, this); } void CConsole::AddCommand(IConsole_Command* cc) { Commands[cc->Name()] = cc; } @@ -164,6 +167,13 @@ void CConsole::OnFrame() } } +void CConsole::OnEvent(EVENT E, u64 P1, u64 P2) +{ + pstr command = (pstr)P1; + ExecuteCommand(command, false); + xr_free(command); +} + void CConsole::OutFont(pcstr text, float& pos_y) { float str_length = pFont->SizeOf_(text); diff --git a/src/xrEngine/XR_IOConsole.h b/src/xrEngine/XR_IOConsole.h index 1dd0597f3ed..58ed76ef1bb 100644 --- a/src/xrEngine/XR_IOConsole.h +++ b/src/xrEngine/XR_IOConsole.h @@ -51,8 +51,12 @@ struct TipString IC bool operator==(shared_str const& tips_text) { return (text == tips_text); } }; -class ENGINE_API CConsole : public pureRender, public pureFrame, - public CUIResetNotifier, public IUserConfigHandler +class ENGINE_API CConsole : + public pureRender, + public pureFrame, + public IEventReceiver, + public CUIResetNotifier, + public IUserConfigHandler { public: struct str_pred @@ -89,6 +93,8 @@ class ENGINE_API CConsole : public pureRender, public pureFrame, bool m_disable_tips; private: + EVENT eConsole; + int lastBindedKeys[bindtypes_count]{}; vecHistory m_cmd_history; @@ -114,6 +120,7 @@ class ENGINE_API CConsole : public pureRender, public pureFrame, virtual void OnRender(); virtual void OnFrame(); + virtual void OnEvent(EVENT E, u64 P1, u64 P2) override; void OnUIReset() override; From c76ddddcf1c22d446c79b16a327e61341ee3274f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 11:43:18 +0500 Subject: [PATCH 049/497] Moved basic application functionality to CApplication --- .../AccessibilityShortcuts.hpp | 0 src/xrEngine/device.cpp | 2 - src/xrEngine/embedded_resources_management.h | 1 - src/xrEngine/splash.cpp | 110 ------------ src/xrEngine/splash.h | 7 - src/xrEngine/x_ray.cpp | 164 ++++++++++++++++-- src/xrEngine/x_ray.h | 21 ++- src/xrEngine/xrEngine.vcxproj | 3 +- src/xrEngine/xrEngine.vcxproj.filters | 9 +- src/xr_3da/entry_point.cpp | 80 +-------- src/xr_3da/packages.config | 5 - src/xr_3da/xr_3da.vcxproj | 16 +- src/xr_3da/xr_3da.vcxproj.filters | 4 - 13 files changed, 176 insertions(+), 246 deletions(-) rename src/{xr_3da => xrEngine}/AccessibilityShortcuts.hpp (100%) delete mode 100644 src/xrEngine/splash.cpp delete mode 100644 src/xrEngine/splash.h delete mode 100644 src/xr_3da/packages.config diff --git a/src/xr_3da/AccessibilityShortcuts.hpp b/src/xrEngine/AccessibilityShortcuts.hpp similarity index 100% rename from src/xr_3da/AccessibilityShortcuts.hpp rename to src/xrEngine/AccessibilityShortcuts.hpp diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index e6bcdb58be2..1f7622df24e 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -12,7 +12,6 @@ #include "xrScriptEngine/ScriptExporter.hpp" #include "XR_IOConsole.h" #include "xr_input.h" -#include "splash.h" #include @@ -430,7 +429,6 @@ void CRenderDevice::Run() // Pre start seqAppStart.Process(); - splash::hide(); SDL_HideWindow(m_sdlWnd); // workaround for SDL bug UpdateWindowProps(); SDL_ShowWindow(m_sdlWnd); diff --git a/src/xrEngine/embedded_resources_management.h b/src/xrEngine/embedded_resources_management.h index 8c62709cd66..0e4cb1076ad 100644 --- a/src/xrEngine/embedded_resources_management.h +++ b/src/xrEngine/embedded_resources_management.h @@ -37,7 +37,6 @@ inline HANDLE ExtractImage(int idx, UINT type) type, 0, 0, LR_CREATEDIBSECTION); } - inline SDL_Surface* CreateSurfaceFromBitmap(HBITMAP bitmapHandle) { BITMAP bitmap; diff --git a/src/xrEngine/splash.cpp b/src/xrEngine/splash.cpp deleted file mode 100644 index 25d39cff79a..00000000000 --- a/src/xrEngine/splash.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "stdafx.h" -#include "splash.h" -#include "embedded_resources_management.h" - -#include - -constexpr u32 SPLASH_FRAMERATE = 30; - -class splash_screen -{ - SDL_Window* m_window; - Event m_should_exit; - bool m_thread_operational; - - size_t m_current_surface_idx; - xr_vector m_surfaces; - -public: - splash_screen() : m_window(nullptr), m_current_surface_idx(0) {} - - static void splash_proc(void* self_ptr) - { - auto& self = *static_cast(self_ptr); - self.m_thread_operational = true; - - while (true) - { - if (self.m_should_exit.Wait(SPLASH_FRAMERATE)) - break; - - if (self.m_surfaces.size() > 1) - { - if (self.m_current_surface_idx >= self.m_surfaces.size()) - self.m_current_surface_idx = 0; - - const auto current = SDL_GetWindowSurface(self.m_window); - const auto next = self.m_surfaces[self.m_current_surface_idx++]; // It's important to have postfix increment! - SDL_BlitSurface(next, nullptr, current, nullptr); - SDL_UpdateWindowSurface(self.m_window); - } - } - - for (SDL_Surface* surface : self.m_surfaces) - SDL_FreeSurface(surface); - self.m_surfaces.clear(); - - SDL_DestroyWindow(self.m_window); - self.m_window = nullptr; - - self.m_thread_operational = false; - } - - void show(bool topmost) - { - if (m_window) - return; - - m_surfaces = std::move(ExtractSplashScreen()); - - if (m_surfaces.empty()) - { - Log("! Couldn't create surface from image:", SDL_GetError()); - return; - } - - Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN; - -#if SDL_VERSION_ATLEAST(2,0,5) - if (topmost) - flags |= SDL_WINDOW_ALWAYS_ON_TOP; -#endif - - SDL_Surface* surface = m_surfaces.front(); - m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, surface->w, surface->h, flags); - - const auto current = SDL_GetWindowSurface(m_window); - SDL_BlitSurface(surface, nullptr, current, nullptr); - SDL_ShowWindow(m_window); - SDL_UpdateWindowSurface(m_window); - - Threading::SpawnThread(splash_proc, "X-Ray Splash Thread", 0, this); - - while (!m_thread_operational) - SDL_PumpEvents(); - SDL_PumpEvents(); - } - - void hide() - { - m_should_exit.Set(); - while (m_thread_operational) - { - SDL_PumpEvents(); - std::this_thread::yield(); - } - } -} g_splash_screen; - -namespace splash -{ -void show(const bool topmost) -{ - g_splash_screen.show(topmost); -} - -void hide() -{ - g_splash_screen.hide(); -} -} // namespace splash diff --git a/src/xrEngine/splash.h b/src/xrEngine/splash.h deleted file mode 100644 index 024108dea21..00000000000 --- a/src/xrEngine/splash.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace splash -{ -void ENGINE_API show(const bool topmost); -void ENGINE_API hide(); -} diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 06a6f0a2f2f..616b1ac5d86 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -6,29 +6,169 @@ // AlexMX - Alexander Maksimchuk //----------------------------------------------------------------------------- #include "stdafx.h" -#include "IGame_Level.h" -#include "IGame_Persistent.h" -#include "XR_IOConsole.h" #include "x_ray.h" -#include "std_classes.h" -#include "GameFont.h" -#include "xrCDB/ISpatial.h" -#include "xrSASH.h" -#include "xr_input.h" -//--------------------------------------------------------------------- +#include "main.h" +#include "AccessibilityShortcuts.hpp" +#include "embedded_resources_management.h" -ENGINE_API CApplication Application; +//#define PROFILE_TASK_SYSTEM -////////////////////////////////////////////////////////////////////////// +#ifdef PROFILE_TASK_SYSTEM +#include "xrCore/Threading/ParallelForEach.hpp" +#endif -CApplication::CApplication() +constexpr u32 SPLASH_FRAMERATE = 30; + +CApplication::CApplication(pcstr commandLine) { + xrDebug::Initialize(commandLine); + R_ASSERT3(SDL_Init(SDL_INIT_VIDEO) == 0, "Unable to initialize SDL", SDL_GetError()); + +#ifdef XR_PLATFORM_WINDOWS + AccessibilityShortcuts shortcuts; + if (!GEnv.isDedicatedServer) + shortcuts.Disable(); +#endif + + if (!strstr(commandLine, "-nosplash")) + { + const bool topmost = !strstr(commandLine, "-splashnotop"); +#ifndef PROFILE_TASK_SYSTEM + ShowSplash(topmost); +#endif + } + + pcstr fsltx = "-fsltx "; + string_path fsgame = ""; + if (strstr(commandLine, fsltx)) + { + const size_t sz = xr_strlen(fsltx); + sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); + } + + Core.Initialize("OpenXRay", commandLine, nullptr, true, *fsgame ? fsgame : nullptr); +#ifdef PROFILE_TASK_SYSTEM + const auto task = [](const TaskRange&){}; + + constexpr int task_count = 1048576; + constexpr int iterations = 250; + u64 results[iterations]; + + CTimer timer; + for (int i = 0; i < iterations; ++i) + { + timer.Start(); + xr_parallel_for(TaskRange(0, task_count, 1), task); + results[i] = timer.GetElapsed_ns(); + } + + u64 min = std::numeric_limits::max(); + u64 average{}; + for (int i = 0; i < iterations; ++i) + { + min = std::min(min, results[i]); + average += results[i] / 1000; + Log("Time:", results[i]); + } + Msg("Time min: %f microseconds", float(min) / 1000.f); + Msg("Time average: %f microseconds", float(average) / float(iterations)); +#endif } CApplication::~CApplication() { + Core._destroy(); + SDL_Quit(); +} + +int CApplication::Run() +{ +#ifdef PROFILE_TASK_SYSTEM + return 0; +#endif + HideSplash(); + return RunApplication(); +} + +void CApplication::ShowSplash(bool topmost) +{ + if (m_window) + return; + + m_surfaces = std::move(ExtractSplashScreen()); + + if (m_surfaces.empty()) + { + Log("! Couldn't create surface from image:", SDL_GetError()); + return; + } + + Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN; + +#if SDL_VERSION_ATLEAST(2,0,5) + if (topmost) + flags |= SDL_WINDOW_ALWAYS_ON_TOP; +#endif + + SDL_Surface* surface = m_surfaces.front(); + m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, surface->w, surface->h, flags); + + const auto current = SDL_GetWindowSurface(m_window); + SDL_BlitSurface(surface, nullptr, current, nullptr); + SDL_ShowWindow(m_window); + SDL_UpdateWindowSurface(m_window); + + Threading::SpawnThread(SplashProc, "X-Ray Splash Thread", 0, this); + + while (!m_thread_operational) + SDL_PumpEvents(); + SDL_PumpEvents(); +} + +void CApplication::SplashProc(void* self_ptr) +{ + auto& self = *static_cast(self_ptr); + self.m_thread_operational = true; + + while (true) + { + if (self.m_should_exit.Wait(SPLASH_FRAMERATE)) + break; + + if (self.m_surfaces.size() > 1) + { + if (self.m_current_surface_idx >= self.m_surfaces.size()) + self.m_current_surface_idx = 0; + + const auto current = SDL_GetWindowSurface(self.m_window); + const auto next = self.m_surfaces[self.m_current_surface_idx++]; // It's important to have postfix increment! + SDL_BlitSurface(next, nullptr, current, nullptr); + SDL_UpdateWindowSurface(self.m_window); + } + } + + for (SDL_Surface* surface : self.m_surfaces) + SDL_FreeSurface(surface); + self.m_surfaces.clear(); + + SDL_DestroyWindow(self.m_window); + self.m_window = nullptr; + + self.m_thread_operational = false; +} + +void CApplication::HideSplash() +{ + if (!m_window) + return; + m_should_exit.Set(); + while (m_thread_operational) + { + SDL_PumpEvents(); + SwitchToThread(); + } } diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 45a6efde65f..9612d162a19 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -1,20 +1,29 @@ #ifndef __X_RAY_H__ #define __X_RAY_H__ -// refs -class ENGINE_API CGameFont; -class ILoadingScreen; - // definition class ENGINE_API CApplication final { + SDL_Window* m_window{}; + Event m_should_exit; + bool m_thread_operational{}; + + size_t m_current_surface_idx{}; + xr_vector m_surfaces; + +private: + static void SplashProc(void* self_ptr); + + void ShowSplash(bool topmost); + void HideSplash(); public: // Other - CApplication(); + CApplication(pcstr commandLine); ~CApplication(); + + int Run(); }; -extern ENGINE_API CApplication Application; #endif //__XR_BASE_H__ diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index 4d971be9f86..8d9047eed80 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -29,6 +29,7 @@ + @@ -84,7 +85,6 @@ - @@ -168,7 +168,6 @@ - diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 5823069915d..03c7eab12f7 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -354,9 +354,6 @@ General\Profiler - - General - Render\Visibility @@ -399,6 +396,9 @@ editor + + General + @@ -590,9 +590,6 @@ General\Profiler - - General - Render\Device diff --git a/src/xr_3da/entry_point.cpp b/src/xr_3da/entry_point.cpp index cc66a82a744..0d5f7e0240a 100644 --- a/src/xr_3da/entry_point.cpp +++ b/src/xr_3da/entry_point.cpp @@ -1,26 +1,14 @@ #include "stdafx.h" -#include "resource.h" -#include "xrEngine/main.h" -#include "xrEngine/splash.h" +#include "xrEngine/x_ray.h" -#if defined(XR_PLATFORM_WINDOWS) -#include "AccessibilityShortcuts.hpp" -#elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) +#if defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) #include #include #include #include #endif -#include - -//#define PROFILE_TASK_SYSTEM - -#ifdef PROFILE_TASK_SYSTEM -#include "xrCore/Threading/ParallelForEach.hpp" -#endif - // Always request high performance GPU extern "C" { @@ -33,72 +21,12 @@ XR_EXPORT u32 AmdPowerXpressRequestHighPerformance = 0x00000001; // PowerXpress int entry_point(pcstr commandLine) { - xrDebug::Initialize(commandLine); - R_ASSERT3(SDL_Init(SDL_INIT_VIDEO) == 0, "Unable to initialize SDL", SDL_GetError()); - - if (!strstr(commandLine, "-nosplash")) - { - const bool topmost = !strstr(commandLine, "-splashnotop"); -#ifndef PROFILE_TASK_SYSTEM - splash::show(topmost); -#endif - } - if (strstr(commandLine, "-dedicated")) GEnv.isDedicatedServer = true; -#ifdef XR_PLATFORM_WINDOWS - AccessibilityShortcuts shortcuts; - if (!GEnv.isDedicatedServer) - shortcuts.Disable(); -#endif - - pcstr fsltx = "-fsltx "; - string_path fsgame = ""; - if (strstr(commandLine, fsltx)) - { - const size_t sz = xr_strlen(fsltx); - sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); - } -#ifdef PROFILE_TASK_SYSTEM - Core.Initialize("OpenXRay", commandLine, nullptr, false, *fsgame ? fsgame : nullptr); - - const auto task = [](const TaskRange&){}; - - constexpr int task_count = 1048576; - constexpr int iterations = 250; - u64 results[iterations]; - - CTimer timer; - for (int i = 0; i < iterations; ++i) - { - timer.Start(); - xr_parallel_for(TaskRange(0, task_count, 1), task); - results[i] = timer.GetElapsed_ns(); - } - - u64 min = std::numeric_limits::max(); - u64 average{}; - for (int i = 0; i < iterations; ++i) - { - min = std::min(min, results[i]); - average += results[i] / 1000; - Log("Time:", results[i]); - } - Msg("Time min: %f microseconds", float(min) / 1000.f); - Msg("Time average: %f microseconds", float(average) / float(iterations)); - - const auto result = 0; -#else - Core.Initialize("OpenXRay", commandLine, nullptr, true, *fsgame ? fsgame : nullptr); + CApplication app{ commandLine }; - const auto result = RunApplication(); -#endif // PROFILE_TASK_SYSTEM - - Core._destroy(); - - SDL_Quit(); - return result; + return app.Run(); } #if defined(XR_PLATFORM_WINDOWS) diff --git a/src/xr_3da/packages.config b/src/xr_3da/packages.config deleted file mode 100644 index 7539664cbfc..00000000000 --- a/src/xr_3da/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/xr_3da/xr_3da.vcxproj b/src/xr_3da/xr_3da.vcxproj index 13779fcc7a4..fccddc4fccb 100644 --- a/src/xr_3da/xr_3da.vcxproj +++ b/src/xr_3da/xr_3da.vcxproj @@ -63,7 +63,6 @@ - @@ -87,19 +86,6 @@ - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + \ No newline at end of file diff --git a/src/xr_3da/xr_3da.vcxproj.filters b/src/xr_3da/xr_3da.vcxproj.filters index d27d4292d33..eb136a002cf 100644 --- a/src/xr_3da/xr_3da.vcxproj.filters +++ b/src/xr_3da/xr_3da.vcxproj.filters @@ -9,7 +9,6 @@ resources - @@ -55,7 +54,4 @@ Dependecies - - - \ No newline at end of file From 71eb6b27e4bea5c373627599b9e7d1f07b579b4a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 12:39:56 +0500 Subject: [PATCH 050/497] xrEngine: moved CheckPrivilegySlowdown to device.cpp --- src/xrEngine/device.cpp | 28 +++++++++++++++++++++++++++- src/xrEngine/main.cpp | 23 ----------------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 1f7622df24e..63f2c218874 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -68,7 +68,33 @@ bool CRenderDevice::RenderBegin() } void CRenderDevice::Clear() { GEnv.Render->Clear(); } -extern void CheckPrivilegySlowdown(); + +namespace +{ +void CheckPrivilegySlowdown() +{ +#ifndef MASTER_GOLD + const auto slowdownthread = +[](void*) + { + for (;;) + { + if (Device.GetStats().fFPS < 30) + Sleep(1); + if (Device.mt_bMustExit || !pSettings || !Console || !pInput) + return; + } + }; + + if (strstr(Core.Params, "-slowdown")) + Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); + if (strstr(Core.Params, "-slowdown2x")) + { + Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); + Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); + } +#endif +} +} void CRenderDevice::RenderEnd(void) { diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp index ba7712b008d..9ead4c77a0c 100644 --- a/src/xrEngine/main.cpp +++ b/src/xrEngine/main.cpp @@ -195,29 +195,6 @@ void execUserScript() Console->ExecuteScript(Console->ConfigFile); } -void slowdownthread(void*) -{ - for (;;) - { - if (Device.GetStats().fFPS < 30) - Sleep(1); - if (Device.mt_bMustExit || !pSettings || !Console || !pInput) - return; - } -} -void CheckPrivilegySlowdown() -{ -#ifdef DEBUG - if (strstr(Core.Params, "-slowdown")) - Threading::SpawnThread(slowdownthread, "slowdown", 0, 0); - if (strstr(Core.Params, "-slowdown2x")) - { - Threading::SpawnThread(slowdownthread, "slowdown", 0, 0); - Threading::SpawnThread(slowdownthread, "slowdown", 0, 0); - } -#endif -} - ENGINE_API void Startup() { InitSoundDeviceList(); From 3081a853488b41a181bf9619b9c1ab15b9890784 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 12:45:25 +0500 Subject: [PATCH 051/497] xrEngine/device.cpp: clean up includes --- src/xrEngine/device.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 63f2c218874..321ec8dda78 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -1,32 +1,20 @@ #include "stdafx.h" -#include "xrCDB/Frustum.h" -#include "x_ray.h" #include "Render.h" #include "xrCore/FS_impl.h" #include "xrCore/Threading/TaskManager.hpp" +#include "xrScriptEngine/ScriptExporter.hpp" #include "xrSASH.h" -#include "IGame_Persistent.h" -#include "xrScriptEngine/ScriptExporter.hpp" #include "XR_IOConsole.h" #include "xr_input.h" -#include +#include "IGame_Level.h" +#include "IGame_Persistent.h" #include -// mmsystem.h -#if defined(XR_PLATFORM_WINDOWS) -#define MMNOSOUND -#define MMNOMIDI -#define MMNOAUX -#define MMNOMIXER -#define MMNOJOY -#include -#endif - ENGINE_API CRenderDevice Device; ENGINE_API CLoadScreenRenderer load_screen_renderer; @@ -146,7 +134,6 @@ void CRenderDevice::RenderEnd(void) mProjectSaved = mProject; } -#include "IGame_Level.h" void CRenderDevice::PreCache(u32 amount, bool wait_user_input) { if (GEnv.isDedicatedServer) @@ -526,7 +513,6 @@ void CRenderDevice::FrameMove() } ENGINE_API bool bShowPauseString = true; -#include "IGame_Persistent.h" void CRenderDevice::Pause(bool bOn, bool bTimer, bool bSound, [[maybe_unused]] pcstr reason) { From d4707ef8b678c1b7b33deea943e95ab5d5387840 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 13:18:34 +0500 Subject: [PATCH 052/497] Moved application initialization functionality back to x_ray.cpp --- src/Layers/xrRender/WallmarksEngine.cpp | 1 - .../xrRenderPC_R1/FStaticRender_Loader.cpp | 1 - src/Layers/xrRenderPC_R1/GlowManager.cpp | 1 - src/Layers/xrRender_R2/r2_loader.cpp | 1 - src/xrEngine/CameraManager.cpp | 1 - src/xrEngine/IGame_Level.cpp | 2 - src/xrEngine/IGame_Persistent.cpp | 1 - src/xrEngine/Text_Console.cpp | 1 - src/xrEngine/XR_IOConsole.cpp | 1 - src/xrEngine/main.cpp | 344 ++---------------- src/xrEngine/main.h | 17 - src/xrEngine/x_ray.cpp | 274 +++++++++++++- src/xrEngine/x_ray.h | 6 +- src/xrEngine/xrEngine.vcxproj | 1 - src/xrEngine/xrEngine.vcxproj.filters | 3 - src/xrEngine/xrSASH.cpp | 18 +- src/xrEngine/xr_collide_form.cpp | 1 - src/xrEngine/xr_ioc_cmd.cpp | 1 - src/xrGame/Level_GameSpy_Funcs.cpp | 1 - src/xrGame/Level_load.cpp | 1 - src/xrGame/Level_network_start_client.cpp | 1 - src/xrGame/Level_start.cpp | 1 - src/xrGame/UIGameCustom.cpp | 2 - src/xrGame/alife_graph_registry.cpp | 1 - src/xrGame/alife_storage_manager.cpp | 1 - src/xrGame/alife_update_manager.cpp | 1 - src/xrGame/game_sv_single.cpp | 1 - src/xrGame/script_render_device_script.cpp | 1 - src/xrGame/ui/UILoadingScreen.cpp | 2 - src/xrGame/xrServer_Connect.cpp | 1 - src/xrSound/MusicStream.cpp | 3 - 31 files changed, 312 insertions(+), 380 deletions(-) delete mode 100644 src/xrEngine/main.h diff --git a/src/Layers/xrRender/WallmarksEngine.cpp b/src/Layers/xrRender/WallmarksEngine.cpp index 80da1ba2811..a2b9ca9c1fb 100644 --- a/src/Layers/xrRender/WallmarksEngine.cpp +++ b/src/Layers/xrRender/WallmarksEngine.cpp @@ -5,7 +5,6 @@ #include "stdafx.h" #include "WallmarksEngine.h" #include "xrEngine/xr_object.h" -#include "xrEngine/x_ray.h" #include "xrEngine/GameFont.h" #include "SkeletonCustom.h" diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp index 6d2770a126e..b1a7d3f5c55 100644 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp +++ b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp @@ -3,7 +3,6 @@ #include "xrCore/FMesh.hpp" #include "Common/LevelStructure.hpp" #include "Common/OGF_GContainer_Vertices.hpp" -#include "xrEngine/x_ray.h" #include "xrEngine/IGame_Persistent.h" #include "xrCore/stream_reader.h" diff --git a/src/Layers/xrRenderPC_R1/GlowManager.cpp b/src/Layers/xrRenderPC_R1/GlowManager.cpp index 022f6c05fcf..9908d7dfe3f 100644 --- a/src/Layers/xrRenderPC_R1/GlowManager.cpp +++ b/src/Layers/xrRenderPC_R1/GlowManager.cpp @@ -5,7 +5,6 @@ #include "stdafx.h" #include "xrEngine/IGame_Persistent.h" #include "xrEngine/Environment.h" -#include "xrEngine/x_ray.h" #include "xrEngine/GameFont.h" #include "GlowManager.h" #include "xrEngine/xr_object.h" diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index c63da2c5039..7a894fbfa7e 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -4,7 +4,6 @@ #include "Layers/xrRender/FBasicVisual.h" #include "xrCore/FMesh.hpp" #include "Common/LevelStructure.hpp" -#include "xrEngine/x_ray.h" #include "xrEngine/IGame_Persistent.h" #include "xrCore/stream_reader.h" diff --git a/src/xrEngine/CameraManager.cpp b/src/xrEngine/CameraManager.cpp index 113ae67ff87..6bb1cf01cd4 100644 --- a/src/xrEngine/CameraManager.cpp +++ b/src/xrEngine/CameraManager.cpp @@ -12,7 +12,6 @@ #include "Effector.h" #include "EffectorPP.h" -#include "x_ray.h" #include "GameFont.h" #include "Render.h" diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 72877c76f79..de72bb7438c 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -2,8 +2,6 @@ #include "IGame_Level.h" #include "IGame_Persistent.h" -#include "x_ray.h" -#include "std_classes.h" #include "CustomHUD.h" #include "Render.h" #include "GameFont.h" diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index ca78fa418b1..8d3359295a9 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -11,7 +11,6 @@ #ifndef _EDITOR #include "Environment.h" -#include "x_ray.h" #include "IGame_Level.h" #include "XR_IOConsole.h" #include "Render.h" diff --git a/src/xrEngine/Text_Console.cpp b/src/xrEngine/Text_Console.cpp index afcf28d8d81..0784f1e91a7 100644 --- a/src/xrEngine/Text_Console.cpp +++ b/src/xrEngine/Text_Console.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Text_Console.h" #include "line_editor.h" -#include "x_ray.h" #include diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index b9d5e2b80a9..72d24c10991 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -8,7 +8,6 @@ #include "IGame_Level.h" #include "IGame_Persistent.h" -#include "x_ray.h" #include "xr_input.h" #include "xr_ioc_cmd.h" #include "GameFont.h" diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp index 9ead4c77a0c..513f339a7be 100644 --- a/src/xrEngine/main.cpp +++ b/src/xrEngine/main.cpp @@ -1,303 +1,47 @@ -// Entry point is in xr_3da/entry_point.cpp #include "stdafx.h" -#include "main.h" -#if defined(XR_PLATFORM_WINDOWS) -#include -#endif - -#include "IGame_Persistent.h" -#include "xrNetServer/NET_AuthCheck.h" -#include "xr_input.h" #include "XR_IOConsole.h" -#include "x_ray.h" -#include "std_classes.h" - -#include "LightAnimLibrary.h" -#include "xrCDB/ISpatial.h" -#if defined(XR_PLATFORM_WINDOWS) -#include "Text_Console.h" -#elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) -#define CTextConsole CConsole -#pragma todo("Implement text console or it's alternative") -#endif #include "xrSASH.h" -#include "xr_ioc_cmd.h" - -#include "xrCore/Threading/TaskManager.hpp" // global variables -ENGINE_API CInifile* pGameIni = nullptr; ENGINE_API bool g_bBenchmark = false; string512 g_sBenchmarkName; -ENGINE_API string512 g_sLaunchOnExit_params; -ENGINE_API string512 g_sLaunchOnExit_app; -ENGINE_API string_path g_sLaunchWorkingFolder; - -ENGINE_API bool CallOfPripyatMode = false; -ENGINE_API bool ClearSkyMode = false; -ENGINE_API bool ShadowOfChernobylMode = false; namespace { -bool CheckBenchmark(); -void RunBenchmark(pcstr name); -} - -namespace -{ -struct PathIncludePred -{ -private: - const xr_auth_strings_t* ignored; - -public: - explicit PathIncludePred(const xr_auth_strings_t* ignoredPaths) : ignored(ignoredPaths) {} - bool IsIncluded(pcstr path) - { - if (!ignored) - return true; - - return allow_to_include_path(*ignored, path); - } -}; -} - -template -void InitConfig(T& config, pcstr name, bool fatal = true, - bool readOnly = true, bool loadAtStart = true, bool saveAtEnd = true, - u32 sectCount = 0, const CInifile::allow_include_func_t& allowIncludeFunc = nullptr) -{ - string_path fname; - FS.update_path(fname, "$game_config$", name); - config = xr_new(fname, readOnly, loadAtStart, saveAtEnd, sectCount, allowIncludeFunc); - - CHECK_OR_EXIT(config->section_count() || !fatal, - make_string("Cannot find file %s.\nReinstalling application may fix this problem.", fname)); -} - -// XXX: make it more fancy -// некрасиво слишком -void set_shoc_mode() -{ - CallOfPripyatMode = false; - ShadowOfChernobylMode = true; - ClearSkyMode = false; -} - -void set_cs_mode() -{ - CallOfPripyatMode = false; - ShadowOfChernobylMode = false; - ClearSkyMode = true; -} - -void set_cop_mode() -{ - CallOfPripyatMode = true; - ShadowOfChernobylMode = false; - ClearSkyMode = false; -} - -void set_free_mode() -{ - CallOfPripyatMode = false; - ShadowOfChernobylMode = false; - ClearSkyMode = false; -} - -ENGINE_API void InitSettings() -{ - xr_auth_strings_t ignoredPaths, checkedPaths; - fill_auth_check_params(ignoredPaths, checkedPaths); //TODO port xrNetServer to Linux - PathIncludePred includePred(&ignoredPaths); - CInifile::allow_include_func_t includeFilter; - includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); - - InitConfig(pSettings, "system.ltx"); - InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); - InitConfig(pSettingsOpenXRay, "openxray.ltx", false, true, true, false); - InitConfig(pGameIni, "game.ltx"); - - if (strstr(Core.Params, "-shoc") || strstr(Core.Params, "-soc")) - set_shoc_mode(); - else if (strstr(Core.Params, "-cs")) - set_cs_mode(); - else if (strstr(Core.Params, "-cop")) - set_cop_mode(); - else if (strstr(Core.Params, "-unlock_game_mode")) - set_free_mode(); - else - { - pcstr gameMode = READ_IF_EXISTS(pSettingsOpenXRay, r_string, "compatibility", "game_mode", "cop"); - if (xr_strcmpi("cop", gameMode) == 0) - set_cop_mode(); - else if (xr_strcmpi("cs", gameMode) == 0) - set_cs_mode(); - else if (xr_strcmpi("shoc", gameMode) == 0 || xr_strcmpi("soc", gameMode) == 0) - set_shoc_mode(); - else if (xr_strcmpi("unlock", gameMode) == 0) - set_free_mode(); - } -} - -ENGINE_API void InitConsole() -{ - if (GEnv.isDedicatedServer) - Console = xr_new(); - else - Console = xr_new(); - - Console->Initialize(); - xr_strcpy(Console->ConfigFile, "user.ltx"); - if (strstr(Core.Params, "-ltx ")) - { - string64 c_name; - sscanf(strstr(Core.Params, "-ltx ") + strlen("-ltx "), "%[^ ] ", c_name); - xr_strcpy(Console->ConfigFile, c_name); - } -} - -ENGINE_API void InitInput() -{ - bool captureInput = !strstr(Core.Params, "-i"); - pInput = xr_new(captureInput); -} - -ENGINE_API void destroyInput() { xr_delete(pInput); } -ENGINE_API void InitSoundDeviceList() { Engine.Sound.CreateDevicesList(); } -ENGINE_API void InitSound() { Engine.Sound.Create(); } -ENGINE_API void destroySound() { Engine.Sound.Destroy(); } -ENGINE_API void destroySettings() -{ - auto s = const_cast(&pSettings); - xr_delete(*s); - - auto sa = const_cast(&pSettingsAuth); - xr_delete(*sa); - - auto so = const_cast(&pSettingsOpenXRay); - xr_delete(*so); - - xr_delete(pGameIni); -} - -ENGINE_API void destroyConsole() -{ - Console->Execute("cfg_save"); - Console->Destroy(); - xr_delete(Console); -} - -void execUserScript() -{ - Console->Execute("default_controls"); - Console->ExecuteScript(Console->ConfigFile); -} - -ENGINE_API void Startup() -{ - InitSoundDeviceList(); - execUserScript(); - InitSound(); - - // ...command line for auto start - pcstr startArgs = strstr(Core.Params, "-start "); - if (startArgs) - Console->Execute(startArgs + 1); - pcstr loadArgs = strstr(Core.Params, "-load "); - if (loadArgs) - Console->Execute(loadArgs + 1); - - // Initialize APP - const auto& createLightAnim = TaskScheduler->AddTask("LALib.OnCreate()", [](Task&, void*) - { - LALib.OnCreate(); - }); - - Device.Create(); - TaskScheduler->Wait(createLightAnim); - - g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); - R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); - if (!g_pGamePersistent) - Console->Show(); - - // Main cycle - Device.Run(); - - // Destroy APP - DEL_INSTANCE(g_pGamePersistent); - Engine.Event.Dump(); - - // Destroying - destroyInput(); - if (!g_bBenchmark && !g_SASH.IsRunning()) - destroySettings(); - - LALib.OnDestroy(); - - if (!g_bBenchmark && !g_SASH.IsRunning()) - destroyConsole(); - else - Console->Destroy(); - - Device.CleanupVideoModes(); - destroySound(); -} - -ENGINE_API int RunApplication() +void RunBenchmark(pcstr name) { - R_ASSERT2(Core.Params, "Core must be initialized"); - - *g_sLaunchOnExit_app = 0; - *g_sLaunchOnExit_params = 0; - - InitSettings(); - // Adjust player & computer name for Asian - if (pSettings->line_exist("string_table", "no_native_input")) - { - xr_strcpy(Core.UserName, sizeof(Core.UserName), "Player"); - xr_strcpy(Core.CompName, sizeof(Core.CompName), "Computer"); - } - - FPU::m24r(); - - Device.FillVideoModes(); - InitInput(); - InitConsole(); - - Engine.Initialize(); - Device.Initialize(); - - Console->OnDeviceInitialize(); - - //if (CheckBenchmark()) - // return 0; - - Startup(); - - Device.Destroy(); - Engine.Destroy(); - - // check for need to execute something external - if (/*xr_strlen(g_sLaunchOnExit_params) && */ xr_strlen(g_sLaunchOnExit_app)) + g_bBenchmark = true; + string_path cfgPath; + FS.update_path(cfgPath, "$app_data_root$", name); + CInifile ini(cfgPath); + const u32 benchmarkCount = ini.line_count("benchmark"); + const size_t hyphenLtxLen = xr_strlen("-ltx "); + for (u32 i = 0; i < benchmarkCount; i++) { -#if defined(XR_PLATFORM_WINDOWS) - // CreateProcess need to return results to next two structures - STARTUPINFO si = {}; - si.cb = sizeof(si); - PROCESS_INFORMATION pi = {}; - // We use CreateProcess to setup working folder - pcstr tempDir = xr_strlen(g_sLaunchWorkingFolder) ? g_sLaunchWorkingFolder : nullptr; - CreateProcess(g_sLaunchOnExit_app, g_sLaunchOnExit_params, nullptr, nullptr, FALSE, 0, nullptr, tempDir, &si, &pi); -#endif + pcstr benchmarkName, t; + ini.r_line("benchmark", i, &benchmarkName, &t); + xr_strcpy(g_sBenchmarkName, benchmarkName); + shared_str benchmarkCommand = ini.r_string_wb("benchmark", benchmarkName); + const auto cmdSize = benchmarkCommand.size() + 1; + Core.Params = (char*)xr_realloc(Core.Params, cmdSize); + xr_strcpy(Core.Params, cmdSize, benchmarkCommand.c_str()); + xr_strlwr(Core.Params); + //InitInput(); + Engine.External.Initialize(); + //if (i) + // InitEngine(); + xr_strcpy(Console->ConfigFile, "user.ltx"); + if (strstr(Core.Params, "-ltx ")) + { + string64 cfgName; + sscanf(strstr(Core.Params, "-ltx ") + hyphenLtxLen, "%[^ ] ", cfgName); + xr_strcpy(Console->ConfigFile, cfgName); + } + //Startup(); } - return 0; } -namespace -{ bool CheckBenchmark() { pcstr benchName = "-batch_benchmark "; @@ -325,36 +69,4 @@ bool CheckBenchmark() return false; } -void RunBenchmark(pcstr name) -{ - g_bBenchmark = true; - string_path cfgPath; - FS.update_path(cfgPath, "$app_data_root$", name); - CInifile ini(cfgPath); - const u32 benchmarkCount = ini.line_count("benchmark"); - const size_t hyphenLtxLen = xr_strlen("-ltx "); - for (u32 i = 0; i < benchmarkCount; i++) - { - pcstr benchmarkName, t; - ini.r_line("benchmark", i, &benchmarkName, &t); - xr_strcpy(g_sBenchmarkName, benchmarkName); - shared_str benchmarkCommand = ini.r_string_wb("benchmark", benchmarkName); - const auto cmdSize = benchmarkCommand.size() + 1; - Core.Params = (char*)xr_realloc(Core.Params, cmdSize); - xr_strcpy(Core.Params, cmdSize, benchmarkCommand.c_str()); - xr_strlwr(Core.Params); - InitInput(); - Engine.External.Initialize(); - //if (i) - // InitEngine(); - xr_strcpy(Console->ConfigFile, "user.ltx"); - if (strstr(Core.Params, "-ltx ")) - { - string64 cfgName; - sscanf(strstr(Core.Params, "-ltx ") + hyphenLtxLen, "%[^ ] ", cfgName); - xr_strcpy(Console->ConfigFile, cfgName); - } - Startup(); - } -} } diff --git a/src/xrEngine/main.h b/src/xrEngine/main.h deleted file mode 100644 index 952c1b67c61..00000000000 --- a/src/xrEngine/main.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -ENGINE_API void InitSettings(); -ENGINE_API void destroySettings(); - -ENGINE_API void InitConsole(); -ENGINE_API void destroyConsole(); - -ENGINE_API void InitInput(); -ENGINE_API void destroyInput(); - -ENGINE_API void InitSoundDeviceList(); -ENGINE_API void InitSound(); -ENGINE_API void destroySound(); - -ENGINE_API void Startup(); -ENGINE_API int RunApplication(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 616b1ac5d86..9e3d284a9a0 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -9,18 +9,194 @@ #include "x_ray.h" -#include "main.h" #include "AccessibilityShortcuts.hpp" #include "embedded_resources_management.h" +#include "xrCore/Threading/TaskManager.hpp" +#include "xrNetServer/NET_AuthCheck.h" + +#include "std_classes.h" +#include "IGame_Persistent.h" +#include "LightAnimLibrary.h" +#include "XR_IOConsole.h" +#include "xrSASH.h" + +#if defined(XR_PLATFORM_WINDOWS) +#include "Text_Console.h" +#elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) +#define CTextConsole CConsole +#pragma todo("Implement text console or it's alternative") +#endif + //#define PROFILE_TASK_SYSTEM #ifdef PROFILE_TASK_SYSTEM #include "xrCore/Threading/ParallelForEach.hpp" #endif +// global variables constexpr u32 SPLASH_FRAMERATE = 30; +ENGINE_API CInifile* pGameIni = nullptr; +ENGINE_API bool CallOfPripyatMode = false; +ENGINE_API bool ClearSkyMode = false; +ENGINE_API bool ShadowOfChernobylMode = false; + +ENGINE_API string512 g_sLaunchOnExit_params; +ENGINE_API string512 g_sLaunchOnExit_app; +ENGINE_API string_path g_sLaunchWorkingFolder; + +namespace +{ +struct PathIncludePred +{ +private: + const xr_auth_strings_t* ignored; + +public: + explicit PathIncludePred(const xr_auth_strings_t* ignoredPaths) : ignored(ignoredPaths) {} + bool IsIncluded(pcstr path) + { + if (!ignored) + return true; + + return allow_to_include_path(*ignored, path); + } +}; +} + +template +void InitConfig(T& config, pcstr name, bool fatal = true, + bool readOnly = true, bool loadAtStart = true, bool saveAtEnd = true, + u32 sectCount = 0, const CInifile::allow_include_func_t& allowIncludeFunc = nullptr) +{ + string_path fname; + FS.update_path(fname, "$game_config$", name); + config = xr_new(fname, readOnly, loadAtStart, saveAtEnd, sectCount, allowIncludeFunc); + + CHECK_OR_EXIT(config->section_count() || !fatal, + make_string("Cannot find file %s.\nReinstalling application may fix this problem.", fname)); +} + +// XXX: make it more fancy +// некрасиво слишком +void set_shoc_mode() +{ + CallOfPripyatMode = false; + ShadowOfChernobylMode = true; + ClearSkyMode = false; +} + +void set_cs_mode() +{ + CallOfPripyatMode = false; + ShadowOfChernobylMode = false; + ClearSkyMode = true; +} + +void set_cop_mode() +{ + CallOfPripyatMode = true; + ShadowOfChernobylMode = false; + ClearSkyMode = false; +} + +void set_free_mode() +{ + CallOfPripyatMode = false; + ShadowOfChernobylMode = false; + ClearSkyMode = false; +} + +void InitSettings() +{ + xr_auth_strings_t ignoredPaths, checkedPaths; + fill_auth_check_params(ignoredPaths, checkedPaths); //TODO port xrNetServer to Linux + PathIncludePred includePred(&ignoredPaths); + CInifile::allow_include_func_t includeFilter; + includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); + + InitConfig(pSettings, "system.ltx"); + InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); + InitConfig(pSettingsOpenXRay, "openxray.ltx", false, true, true, false); + InitConfig(pGameIni, "game.ltx"); + + if (strstr(Core.Params, "-shoc") || strstr(Core.Params, "-soc")) + set_shoc_mode(); + else if (strstr(Core.Params, "-cs")) + set_cs_mode(); + else if (strstr(Core.Params, "-cop")) + set_cop_mode(); + else if (strstr(Core.Params, "-unlock_game_mode")) + set_free_mode(); + else + { + pcstr gameMode = READ_IF_EXISTS(pSettingsOpenXRay, r_string, "compatibility", "game_mode", "cop"); + if (xr_strcmpi("cop", gameMode) == 0) + set_cop_mode(); + else if (xr_strcmpi("cs", gameMode) == 0) + set_cs_mode(); + else if (xr_strcmpi("shoc", gameMode) == 0 || xr_strcmpi("soc", gameMode) == 0) + set_shoc_mode(); + else if (xr_strcmpi("unlock", gameMode) == 0) + set_free_mode(); + } +} + +void InitConsole() +{ + if (GEnv.isDedicatedServer) + Console = xr_new(); + else + Console = xr_new(); + + Console->Initialize(); + xr_strcpy(Console->ConfigFile, "user.ltx"); + if (strstr(Core.Params, "-ltx ")) + { + string64 c_name; + sscanf(strstr(Core.Params, "-ltx ") + strlen("-ltx "), "%[^ ] ", c_name); + xr_strcpy(Console->ConfigFile, c_name); + } +} + +void InitInput() +{ + bool captureInput = !strstr(Core.Params, "-i"); + pInput = xr_new(captureInput); +} + +void destroyInput() { xr_delete(pInput); } +void InitSoundDeviceList() { Engine.Sound.CreateDevicesList(); } +void InitSound() { Engine.Sound.Create(); } +void destroySound() { Engine.Sound.Destroy(); } +void destroySettings() +{ + auto s = const_cast(&pSettings); + xr_delete(*s); + + auto sa = const_cast(&pSettingsAuth); + xr_delete(*sa); + + auto so = const_cast(&pSettingsOpenXRay); + xr_delete(*so); + + xr_delete(pGameIni); +} + +void destroyConsole() +{ + Console->Execute("cfg_save"); + Console->Destroy(); + xr_delete(Console); +} + +void execUserScript() +{ + Console->Execute("default_controls"); + Console->ExecuteScript(Console->ConfigFile); +} + CApplication::CApplication(pcstr commandLine) { xrDebug::Initialize(commandLine); @@ -75,11 +251,101 @@ CApplication::CApplication(pcstr commandLine) } Msg("Time min: %f microseconds", float(min) / 1000.f); Msg("Time average: %f microseconds", float(average) / float(iterations)); + + return; #endif + *g_sLaunchOnExit_app = 0; + *g_sLaunchOnExit_params = 0; + + InitSettings(); + // Adjust player & computer name for Asian + if (pSettings->line_exist("string_table", "no_native_input")) + { + xr_strcpy(Core.UserName, sizeof(Core.UserName), "Player"); + xr_strcpy(Core.CompName, sizeof(Core.CompName), "Computer"); + } + + FPU::m24r(); + + Device.FillVideoModes(); + InitInput(); + InitConsole(); + + Engine.Initialize(); + Device.Initialize(); + + Console->OnDeviceInitialize(); + + //if (CheckBenchmark()) + // return 0; + + InitSoundDeviceList(); + execUserScript(); + InitSound(); + + // ...command line for auto start + pcstr startArgs = strstr(Core.Params, "-start "); + if (startArgs) + Console->Execute(startArgs + 1); + pcstr loadArgs = strstr(Core.Params, "-load "); + if (loadArgs) + Console->Execute(loadArgs + 1); + + // Initialize APP + const auto& createLightAnim = TaskScheduler->AddTask("LALib.OnCreate()", [](Task&, void*) + { + LALib.OnCreate(); + }); + + Device.Create(); + TaskScheduler->Wait(createLightAnim); + + g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); + R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); + if (!g_pGamePersistent) + Console->Show(); } CApplication::~CApplication() { +#ifndef PROFILE_TASK_SYSTEM + // Destroy APP + DEL_INSTANCE(g_pGamePersistent); + Engine.Event.Dump(); + + // Destroying + destroyInput(); + if (!g_bBenchmark && !g_SASH.IsRunning()) + destroySettings(); + + LALib.OnDestroy(); + + if (!g_bBenchmark && !g_SASH.IsRunning()) + destroyConsole(); + else + Console->Destroy(); + + Device.CleanupVideoModes(); + destroySound(); + + Device.Destroy(); + Engine.Destroy(); + + // check for need to execute something external + if (/*xr_strlen(g_sLaunchOnExit_params) && */ xr_strlen(g_sLaunchOnExit_app)) + { +#if defined(XR_PLATFORM_WINDOWS) + // CreateProcess need to return results to next two structures + STARTUPINFO si = {}; + si.cb = sizeof(si); + PROCESS_INFORMATION pi = {}; + // We use CreateProcess to setup working folder + pcstr tempDir = xr_strlen(g_sLaunchWorkingFolder) ? g_sLaunchWorkingFolder : nullptr; + CreateProcess(g_sLaunchOnExit_app, g_sLaunchOnExit_params, nullptr, nullptr, FALSE, 0, nullptr, tempDir, &si, &pi); +#endif + } +#endif // PROFILE_TASK_SYSTEM + Core._destroy(); SDL_Quit(); } @@ -89,8 +355,12 @@ int CApplication::Run() #ifdef PROFILE_TASK_SYSTEM return 0; #endif + + // Main cycle HideSplash(); - return RunApplication(); + Device.Run(); + + return 0; } void CApplication::ShowSplash(bool topmost) diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 9612d162a19..076ca6f9ae0 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -1,6 +1,11 @@ #ifndef __X_RAY_H__ #define __X_RAY_H__ +#include "xrCore/Threading/Event.hpp" + +struct SDL_Window; +struct SDL_Surface; + // definition class ENGINE_API CApplication final { @@ -25,5 +30,4 @@ class ENGINE_API CApplication final int Run(); }; - #endif //__XR_BASE_H__ diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index 8d9047eed80..73ce634812f 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -71,7 +71,6 @@ - diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 03c7eab12f7..d785264fba7 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -360,9 +360,6 @@ Render\Visibility - - General - Interfaces\ILoadingScreen diff --git a/src/xrEngine/xrSASH.cpp b/src/xrEngine/xrSASH.cpp index 802ecf7c4af..d1dd322a35f 100644 --- a/src/xrEngine/xrSASH.cpp +++ b/src/xrEngine/xrSASH.cpp @@ -4,8 +4,6 @@ #include "XR_IOConsole.h" #include "xr_ioc_cmd.h" -#include "main.h" - xrSASH ENGINE_API g_SASH; xrSASH::~xrSASH() @@ -434,15 +432,13 @@ void xrSASH::GetBenchmarks() } #endif -void Startup(); - void xrSASH::RunBenchmark(pcstr pszName) { Msg("SASH:: RunBenchmark."); TryInitEngine(false); - Startup(); + //Startup(); m_bReinitEngine = true; @@ -489,12 +485,12 @@ void xrSASH::TryInitEngine(bool bNoRun) xr_delete(pTmp); } - InitInput(); + //InitInput(); Engine.External.Initialize(); - if (bNoRun) - InitSoundDeviceList(); + //if (bNoRun) + // InitSoundDeviceList(); Console->Execute("unbindall"); Console->ExecuteScript(Console->ConfigFile); @@ -507,7 +503,7 @@ void xrSASH::TryInitEngine(bool bNoRun) if (bNoRun) { - InitSound(); + //InitSound(); Device.Create(); } } @@ -516,10 +512,10 @@ void xrSASH::ReleaseEngine() { m_bReinitEngine = true; - destroyInput(); + //destroyInput(); Console->Destroy(); Device.CleanupVideoModes(); - destroySound(); + //destroySound(); //destroyEngine(); } diff --git a/src/xrEngine/xr_collide_form.cpp b/src/xrEngine/xr_collide_form.cpp index 4cc385296f7..97f901b5392 100644 --- a/src/xrEngine/xr_collide_form.cpp +++ b/src/xrEngine/xr_collide_form.cpp @@ -3,7 +3,6 @@ #include "xr_collide_form.h" #include "xr_object.h" #include "xrCDB/xr_area.h" -#include "x_ray.h" #include "Common/LevelStructure.hpp" #include "xrCore/FMesh.hpp" #include "xrCDB/Frustum.h" diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index 79387aa9aa9..5ba8e794ec9 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "IGame_Level.h" -#include "x_ray.h" #include "XR_IOConsole.h" #include "xr_ioc_cmd.h" #include "xrSASH.h" diff --git a/src/xrGame/Level_GameSpy_Funcs.cpp b/src/xrGame/Level_GameSpy_Funcs.cpp index 9ec86f542fb..a9090de36ab 100644 --- a/src/xrGame/Level_GameSpy_Funcs.cpp +++ b/src/xrGame/Level_GameSpy_Funcs.cpp @@ -1,7 +1,6 @@ #include "StdAfx.h" #include "Level.h" #include "xrMessages.h" -#include "xrEngine/x_ray.h" #include "xrGameSpy/GameSpy_GCD_Client.h" #include "xrEngine/IGame_Persistent.h" #include "ui/UICDkey.h" diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index 46464bbfdbe..4ee77204890 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -6,7 +6,6 @@ #include "xrScriptEngine/script_engine.hpp" #include "Level.h" #include "game_cl_base.h" -#include "xrEngine/x_ray.h" #include "xrMaterialSystem/GameMtlLib.h" #include "xrPhysics/PhysicsCommon.h" #include "level_sounds.h" diff --git a/src/xrGame/Level_network_start_client.cpp b/src/xrGame/Level_network_start_client.cpp index 566c3af90ec..76252367f92 100644 --- a/src/xrGame/Level_network_start_client.cpp +++ b/src/xrGame/Level_network_start_client.cpp @@ -1,7 +1,6 @@ #include "StdAfx.h" #include "Level.h" -#include "xrEngine/x_ray.h" #include "xrEngine/IGame_Persistent.h" #include "ai_space.h" diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index 21026f3194e..4336437b26e 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -5,7 +5,6 @@ #include "game_cl_base.h" #include "xrMessages.h" #include "xrGameSpyServer.h" -#include "xrEngine/x_ray.h" #include "xrEngine/device.h" #include "xrEngine/IGame_Persistent.h" #include "xrEngine/XR_IOConsole.h" diff --git a/src/xrGame/UIGameCustom.cpp b/src/xrGame/UIGameCustom.cpp index 02c2035a755..619f532468b 100644 --- a/src/xrGame/UIGameCustom.cpp +++ b/src/xrGame/UIGameCustom.cpp @@ -15,8 +15,6 @@ #include "Inventory.h" #include "game_cl_base.h" -#include "xrEngine/x_ray.h" - #include "ui/UICellItem.h" //Alundaio //#include "script_game_object.h" //Alundaio diff --git a/src/xrGame/alife_graph_registry.cpp b/src/xrGame/alife_graph_registry.cpp index 2e1dc371bef..c16986cdc4b 100644 --- a/src/xrGame/alife_graph_registry.cpp +++ b/src/xrGame/alife_graph_registry.cpp @@ -8,7 +8,6 @@ #include "StdAfx.h" #include "alife_graph_registry.h" -#include "xrEngine/x_ray.h" #include "xrServerEntities/xrMessages.h" using namespace ALife; diff --git a/src/xrGame/alife_storage_manager.cpp b/src/xrGame/alife_storage_manager.cpp index 1f977492db7..611d898f161 100644 --- a/src/xrGame/alife_storage_manager.cpp +++ b/src/xrGame/alife_storage_manager.cpp @@ -17,7 +17,6 @@ #include "alife_registry_container.h" #include "xrServer.h" #include "Level.h" -#include "xrEngine/x_ray.h" #include "saved_game_wrapper.h" #include "xrEngine/IGame_Persistent.h" #include "autosave_manager.h" diff --git a/src/xrGame/alife_update_manager.cpp b/src/xrGame/alife_update_manager.cpp index 2d10fda3634..339bbfeb8f8 100644 --- a/src/xrGame/alife_update_manager.cpp +++ b/src/xrGame/alife_update_manager.cpp @@ -18,7 +18,6 @@ #include "xrServer.h" #include "Level.h" #include "xrAICore/Navigation/graph_engine.h" -#include "xrEngine/x_ray.h" #include "restriction_space.h" #include "xrEngine/profiler.h" #include "mt_config.h" diff --git a/src/xrGame/game_sv_single.cpp b/src/xrGame/game_sv_single.cpp index d4a3b05a27a..c7be6bc8d7b 100644 --- a/src/xrGame/game_sv_single.cpp +++ b/src/xrGame/game_sv_single.cpp @@ -8,7 +8,6 @@ #include "Common/object_broker.h" #include "GamePersistent.h" #include "xrServer.h" -#include "xrEngine/x_ray.h" game_sv_Single::game_sv_Single() { diff --git a/src/xrGame/script_render_device_script.cpp b/src/xrGame/script_render_device_script.cpp index 409b802457f..21e342223dc 100644 --- a/src/xrGame/script_render_device_script.cpp +++ b/src/xrGame/script_render_device_script.cpp @@ -8,7 +8,6 @@ #include "pch_script.h" #include "xrScriptEngine/ScriptExporter.hpp" -#include "xrEngine/x_ray.h" bool is_device_paused(CRenderDevice* d) { return !!Device.Paused(); } void set_device_paused(CRenderDevice* d, bool b) { Device.Pause(b, TRUE, FALSE, "set_device_paused_script"); } diff --git a/src/xrGame/ui/UILoadingScreen.cpp b/src/xrGame/ui/UILoadingScreen.cpp index 32db07cd000..6caea14ed93 100644 --- a/src/xrGame/ui/UILoadingScreen.cpp +++ b/src/xrGame/ui/UILoadingScreen.cpp @@ -11,8 +11,6 @@ #include "UILoadingScreen.h" #include "UILoadingScreenHardcoded.h" -#include "xrEngine/x_ray.h" -#include "xrEngine/GameFont.h" #include "UIHelper.h" #include "xrUICore/XML/UITextureMaster.h" diff --git a/src/xrGame/xrServer_Connect.cpp b/src/xrGame/xrServer_Connect.cpp index f9cf35b3725..e94ad899980 100644 --- a/src/xrGame/xrServer_Connect.cpp +++ b/src/xrGame/xrServer_Connect.cpp @@ -8,7 +8,6 @@ #include "game_cl_artefacthunt.h" #include "game_cl_single.h" #include "MainMenu.h" -#include "xrEngine/x_ray.h" #include "file_transfer.h" #include "screenshot_server.h" #include "xrNetServer/NET_AuthCheck.h" diff --git a/src/xrSound/MusicStream.cpp b/src/xrSound/MusicStream.cpp index 9ddbfb2c6b0..1bc1e98474d 100644 --- a/src/xrSound/MusicStream.cpp +++ b/src/xrSound/MusicStream.cpp @@ -6,9 +6,6 @@ #include "MusicStream.h" #include "xr_streamsnd.h" -#if defined(WINDOWS) -#include "x_ray.h" -#endif #include "GameFont.h" ////////////////////////////////////////////////////////////////////// From b13bbdaef969633735c659ad412068e493357c28 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 13:49:34 +0500 Subject: [PATCH 053/497] Moved application cycle processing to CApplication --- src/xrEngine/device.cpp | 155 +++++++++++++--------------------------- src/xrEngine/device.h | 12 ++-- src/xrEngine/x_ray.cpp | 70 +++++++++++++++++- 3 files changed, 127 insertions(+), 110 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 321ec8dda78..8261cb97ee0 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -23,8 +23,6 @@ ENGINE_API bool g_bRendering = false; int ps_fps_limit = 501; int ps_fps_limit_in_menu = 60; -constexpr size_t MAX_WINDOW_EVENTS = 32; - bool g_bLoaded = false; ref_light precache_light = 0; @@ -298,128 +296,77 @@ void CRenderDevice::ProcessFrame() Sleep(1); } -void CRenderDevice::message_loop() +void CRenderDevice::ProcessEvent(const SDL_Event& event) { - while (!SDL_QuitRequested()) // SDL_PumpEvents is here + switch (event.type) { - bool canCallActivate = false; - bool shouldActivate = false; - - SDL_Event events[MAX_WINDOW_EVENTS]; - const int count = SDL_PeepEvents(events, MAX_WINDOW_EVENTS, - SDL_GETEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); - - for (int i = 0; i < count; ++i) - { - const SDL_Event event = events[i]; - - switch (event.type) - { #if SDL_VERSION_ATLEAST(2, 0, 9) - case SDL_DISPLAYEVENT: - { - switch (event.display.type) - { - case SDL_DISPLAYEVENT_ORIENTATION: + case SDL_DISPLAYEVENT: + { + switch (event.display.type) + { + case SDL_DISPLAYEVENT_ORIENTATION: #if SDL_VERSION_ATLEAST(2, 0, 14) - case SDL_DISPLAYEVENT_CONNECTED: - case SDL_DISPLAYEVENT_DISCONNECTED: + case SDL_DISPLAYEVENT_CONNECTED: + case SDL_DISPLAYEVENT_DISCONNECTED: #endif - CleanupVideoModes(); - FillVideoModes(); + CleanupVideoModes(); + FillVideoModes(); #if SDL_VERSION_ATLEAST(2, 0, 14) - if (event.display.display == psDeviceMode.Monitor && event.display.type != SDL_DISPLAYEVENT_CONNECTED) + if (event.display.display == psDeviceMode.Monitor && event.display.type != SDL_DISPLAYEVENT_CONNECTED) #else if (event.display.display == psDeviceMode.Monitor) #endif - Reset(); - else - UpdateWindowProps(); - break; - } // switch (event.display.type) - break; - } + Reset(); + else + UpdateWindowProps(); + break; + } // switch (event.display.type) + break; + } #endif - case SDL_WINDOWEVENT: - { - switch (event.window.event) - { - case SDL_WINDOWEVENT_MOVED: - { - UpdateWindowRects(); + case SDL_WINDOWEVENT: + { + switch (event.window.event) + { + case SDL_WINDOWEVENT_MOVED: + { + UpdateWindowRects(); #if !SDL_VERSION_ATLEAST(2, 0, 18) // without SDL_WINDOWEVENT_DISPLAY_CHANGED, let's detect monitor change ourselves const int display = SDL_GetWindowDisplayIndex(m_sdlWnd); if (display != -1) psDeviceMode.Monitor = display; #endif - break; - } + break; + } #if SDL_VERSION_ATLEAST(2, 0, 18) - case SDL_WINDOWEVENT_DISPLAY_CHANGED: - psDeviceMode.Monitor = event.window.data1; - break; + case SDL_WINDOWEVENT_DISPLAY_CHANGED: + psDeviceMode.Monitor = event.window.data1; + break; #endif - case SDL_WINDOWEVENT_SIZE_CHANGED: - { - if (psDeviceMode.WindowStyle != rsFullscreen) - { - if (static_cast(psDeviceMode.Width) == event.window.data1 && - static_cast(psDeviceMode.Height) == event.window.data2) - break; // we don't need to reset device if resolution wasn't really changed - - psDeviceMode.Width = event.window.data1; - psDeviceMode.Height = event.window.data2; - - Reset(); - } - else - UpdateWindowRects(); - - break; - } - - case SDL_WINDOWEVENT_SHOWN: - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_RESTORED: - case SDL_WINDOWEVENT_MAXIMIZED: - canCallActivate = true; - shouldActivate = true; - break; - - case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_FOCUS_LOST: - case SDL_WINDOWEVENT_MINIMIZED: - canCallActivate = true; - shouldActivate = false; - break; - - case SDL_WINDOWEVENT_ENTER: - SDL_ShowCursor(SDL_FALSE); - break; - - case SDL_WINDOWEVENT_LEAVE: - SDL_ShowCursor(SDL_TRUE); - break; - - case SDL_WINDOWEVENT_CLOSE: - Engine.Event.Defer("KERNEL:disconnect"); - Engine.Event.Defer("KERNEL:quit"); - break; - } // switch (event.window.event) + case SDL_WINDOWEVENT_SIZE_CHANGED: + { + if (psDeviceMode.WindowStyle != rsFullscreen) + { + if (static_cast(psDeviceMode.Width) == event.window.data1 && + static_cast(psDeviceMode.Height) == event.window.data2) + break; // we don't need to reset device if resolution wasn't really changed + + psDeviceMode.Width = event.window.data1; + psDeviceMode.Height = event.window.data2; + + Reset(); } - } // switch (event.type) - } // for (int i = 0; i < count; ++i) + else + UpdateWindowRects(); - // Workaround for screen blinking when there's too much timeouts - if (canCallActivate) - { - OnWindowActivate(shouldActivate); + break; } - - ProcessFrame(); + } // switch (event.window.event) } + } // switch (event.type) } void CRenderDevice::Run() @@ -448,10 +395,10 @@ void CRenderDevice::Run() SDL_RaiseWindow(m_sdlWnd); if (GEnv.isDedicatedServer || strstr(Core.Params, "-center_screen")) SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); +} - // Message cycle - message_loop(); - +void CRenderDevice::Shutdown() +{ // Stop Balance-Thread mt_bMustExit = true; diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 09cc982b13b..76433627257 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -191,10 +191,16 @@ class ENGINE_API CRenderDevice : public IWindowHandler public: // Creation & Destroying void Create(); - void Run(); void Destroy(); + void Reset(bool precache = true); + void Run(); + void Shutdown(); + + void ProcessEvent(const SDL_Event& event); + void OnWindowActivate(bool activated); + void UpdateWindowProps(); void UpdateWindowRects(); void SelectResolution(bool windowed); @@ -258,10 +264,6 @@ class ENGINE_API CRenderDevice : public IWindowHandler private: void CalcFrameStats(); - void OnWindowActivate(bool activated); - - void message_loop(); - public: [[nodiscard]] auto& editor() { return m_editor; } diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 9e3d284a9a0..b66f03311e2 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -37,6 +37,8 @@ // global variables constexpr u32 SPLASH_FRAMERATE = 30; +constexpr size_t MAX_WINDOW_EVENTS = 32; + ENGINE_API CInifile* pGameIni = nullptr; ENGINE_API bool CallOfPripyatMode = false; ENGINE_API bool ClearSkyMode = false; @@ -357,8 +359,74 @@ int CApplication::Run() #endif // Main cycle - HideSplash(); Device.Run(); + HideSplash(); + + while (!SDL_QuitRequested()) // SDL_PumpEvents is here + { + bool canCallActivate = false; + bool shouldActivate = false; + + SDL_Event events[MAX_WINDOW_EVENTS]; + const int count = SDL_PeepEvents(events, MAX_WINDOW_EVENTS, + SDL_GETEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); + + for (int i = 0; i < count; ++i) + { + const SDL_Event event = events[i]; + + switch (event.type) + { + case SDL_WINDOWEVENT: + { + switch (event.window.event) + { + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_RESTORED: + case SDL_WINDOWEVENT_MAXIMIZED: + canCallActivate = true; + shouldActivate = true; + continue; + + case SDL_WINDOWEVENT_HIDDEN: + case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_WINDOWEVENT_MINIMIZED: + canCallActivate = true; + shouldActivate = false; + continue; + + case SDL_WINDOWEVENT_ENTER: + SDL_ShowCursor(SDL_FALSE); + continue; + + case SDL_WINDOWEVENT_LEAVE: + SDL_ShowCursor(SDL_TRUE); + continue; + + case SDL_WINDOWEVENT_CLOSE: + Engine.Event.Defer("KERNEL:disconnect"); + Engine.Event.Defer("KERNEL:quit"); + continue; + } // switch (event.window.event) + } + } // switch (event.type) + + // Only process event in Device + // if it wasn't processed in the switch above + Device.ProcessEvent(event); + } // for (int i = 0; i < count; ++i) + + // Workaround for screen blinking when there's too much timeouts + if (canCallActivate) + { + Device.OnWindowActivate(shouldActivate); + } + + Device.ProcessFrame(); + } // while (!SDL_QuitRequested()) + + Device.Shutdown(); return 0; } From 118d39d55e343586fce5fa048b09b94b5c18adaa Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 14:50:41 +0500 Subject: [PATCH 054/497] Fixed non-Windows build --- src/xrEngine/CMakeLists.txt | 4 +--- src/xrEngine/x_ray.cpp | 2 +- src/xr_3da/CMakeLists.txt | 3 --- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index 592bd5e41b8..ac06fe221cb 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -232,14 +232,12 @@ target_sources_grouped( TARGET xrEngine NAME "General" FILES + AccessibilityShortcuts.hpp defines.cpp defines.h embedded_resources_management.h main.cpp - main.h mp_logging.h - splash.cpp - splash.h stdafx.cpp stdafx.h x_ray.cpp diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index b66f03311e2..5d2660eaffe 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -9,7 +9,6 @@ #include "x_ray.h" -#include "AccessibilityShortcuts.hpp" #include "embedded_resources_management.h" #include "xrCore/Threading/TaskManager.hpp" @@ -22,6 +21,7 @@ #include "xrSASH.h" #if defined(XR_PLATFORM_WINDOWS) +#include "AccessibilityShortcuts.hpp" #include "Text_Console.h" #elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) #define CTextConsole CConsole diff --git a/src/xr_3da/CMakeLists.txt b/src/xr_3da/CMakeLists.txt index b253d1cb0fd..7fbdf10f7c1 100644 --- a/src/xr_3da/CMakeLists.txt +++ b/src/xr_3da/CMakeLists.txt @@ -1,11 +1,8 @@ add_executable(xr_3da) target_sources(xr_3da PRIVATE - AccessibilityShortcuts.hpp entry_point.cpp - resource.h stdafx.h - stdafx.cpp ) set_property( From 39b40de7cdae868e5829d67e560c540325089bc6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 16:20:11 +0500 Subject: [PATCH 055/497] xrEngine/x_ray.h|cpp: simplify splash thread proc --- src/xrEngine/x_ray.cpp | 35 +++++++++++++++++++---------------- src/xrEngine/x_ray.h | 2 +- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 5d2660eaffe..650d2e7f899 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -459,43 +459,46 @@ void CApplication::ShowSplash(bool topmost) SDL_ShowWindow(m_window); SDL_UpdateWindowSurface(m_window); - Threading::SpawnThread(SplashProc, "X-Ray Splash Thread", 0, this); + Threading::SpawnThread(+[](void* self_ptr) + { + auto& self = *static_cast(self_ptr); + self.SplashProc(); + }, "X-Ray Splash Thread", 0, this); while (!m_thread_operational) SDL_PumpEvents(); SDL_PumpEvents(); } -void CApplication::SplashProc(void* self_ptr) +void CApplication::SplashProc() { - auto& self = *static_cast(self_ptr); - self.m_thread_operational = true; + m_thread_operational = true; while (true) { - if (self.m_should_exit.Wait(SPLASH_FRAMERATE)) + if (m_should_exit.Wait(SPLASH_FRAMERATE)) break; - if (self.m_surfaces.size() > 1) + if (m_surfaces.size() > 1) { - if (self.m_current_surface_idx >= self.m_surfaces.size()) - self.m_current_surface_idx = 0; + if (m_current_surface_idx >= m_surfaces.size()) + m_current_surface_idx = 0; - const auto current = SDL_GetWindowSurface(self.m_window); - const auto next = self.m_surfaces[self.m_current_surface_idx++]; // It's important to have postfix increment! + const auto current = SDL_GetWindowSurface(m_window); + const auto next = m_surfaces[m_current_surface_idx++]; // It's important to have postfix increment! SDL_BlitSurface(next, nullptr, current, nullptr); - SDL_UpdateWindowSurface(self.m_window); + SDL_UpdateWindowSurface(m_window); } } - for (SDL_Surface* surface : self.m_surfaces) + for (SDL_Surface* surface : m_surfaces) SDL_FreeSurface(surface); - self.m_surfaces.clear(); + m_surfaces.clear(); - SDL_DestroyWindow(self.m_window); - self.m_window = nullptr; + SDL_DestroyWindow(m_window); + m_window = nullptr; - self.m_thread_operational = false; + m_thread_operational = false; } void CApplication::HideSplash() diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 076ca6f9ae0..0073fceb9dc 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -17,7 +17,7 @@ class ENGINE_API CApplication final xr_vector m_surfaces; private: - static void SplashProc(void* self_ptr); + void SplashProc(); void ShowSplash(bool topmost); void HideSplash(); From d19b10d52c69da8a6f75ec211460d71d53d2b2bb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 16:33:43 +0500 Subject: [PATCH 056/497] Add basic Discord integration --- src/xrEngine/x_ray.cpp | 62 +++++++++++++++++++++++++++++++++++ src/xrEngine/x_ray.h | 11 +++++++ src/xrEngine/xrEngine.vcxproj | 3 ++ 3 files changed, 76 insertions(+) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 650d2e7f899..99efaa4cd86 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -28,6 +28,15 @@ #pragma todo("Implement text console or it's alternative") #endif +#ifdef XR_PLATFORM_WINDOWS +#include + +#include "DiscordGameSDK/discord.h" +#define USE_DISCORD_INTEGRATION + +#include "xrCore/Text/StringConversion.hpp" +#endif + //#define PROFILE_TASK_SYSTEM #ifdef PROFILE_TASK_SYSTEM @@ -39,6 +48,10 @@ constexpr u32 SPLASH_FRAMERATE = 30; constexpr size_t MAX_WINDOW_EVENTS = 32; +#ifdef USE_DISCORD_INTEGRATION +constexpr discord::ClientId DISCORD_APP_ID = 421286728695939072; +#endif + ENGINE_API CInifile* pGameIni = nullptr; ENGINE_API bool CallOfPripyatMode = false; ENGINE_API bool ClearSkyMode = false; @@ -210,6 +223,32 @@ CApplication::CApplication(pcstr commandLine) shortcuts.Disable(); #endif +#ifdef USE_DISCORD_INTEGRATION + discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &m_discord_core); + +# ifndef MASTER_GOLD + const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; + m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) + { + switch (level) + { + case discord::LogLevel::Error: Log("!", message); break; + case discord::LogLevel::Warn: Log("~", message); break; + case discord::LogLevel::Info: Log("*", message); break; + case discord::LogLevel::Debug: Log("#", message); break; + } + }); +# endif + + discord::Activity activity{}; + activity.SetType(discord::ActivityType::Playing); + activity.SetApplicationId(DISCORD_APP_ID); + { + std::lock_guard guard{ m_discord_lock }; + m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); + } +#endif + if (!strstr(commandLine, "-nosplash")) { const bool topmost = !strstr(commandLine, "-splashnotop"); @@ -277,6 +316,14 @@ CApplication::CApplication(pcstr commandLine) Device.Initialize(); Console->OnDeviceInitialize(); +#ifdef USE_DISCORD_INTEGRATION + const std::locale locale(""); + activity.SetDetails(StringToUTF8(Core.ApplicationTitle, locale).c_str()); + { + std::lock_guard guard{ m_discord_lock }; + m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); + } +#endif //if (CheckBenchmark()) // return 0; @@ -333,6 +380,10 @@ CApplication::~CApplication() Device.Destroy(); Engine.Destroy(); +#ifdef USE_DISCORD_INTEGRATION + discord::Core::Destroy(&m_discord_core); +#endif + // check for need to execute something external if (/*xr_strlen(g_sLaunchOnExit_params) && */ xr_strlen(g_sLaunchOnExit_app)) { @@ -424,6 +475,10 @@ int CApplication::Run() } Device.ProcessFrame(); + +#ifdef USE_DISCORD_INTEGRATION + m_discord_core->RunCallbacks(); +#endif } // while (!SDL_QuitRequested()) Device.Shutdown(); @@ -488,6 +543,13 @@ void CApplication::SplashProc() const auto next = m_surfaces[m_current_surface_idx++]; // It's important to have postfix increment! SDL_BlitSurface(next, nullptr, current, nullptr); SDL_UpdateWindowSurface(m_window); + +#ifdef USE_DISCORD_INTEGRATION + { + std::lock_guard guard{ m_discord_lock }; + m_discord_core->RunCallbacks(); + } +#endif } } diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 0073fceb9dc..4a4012d2f7f 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -1,11 +1,18 @@ #ifndef __X_RAY_H__ #define __X_RAY_H__ +#include + #include "xrCore/Threading/Event.hpp" struct SDL_Window; struct SDL_Surface; +namespace discord +{ +class Core; +} + // definition class ENGINE_API CApplication final { @@ -16,6 +23,10 @@ class ENGINE_API CApplication final size_t m_current_surface_idx{}; xr_vector m_surfaces; +private: + std::mutex m_discord_lock; + discord::Core* m_discord_core{}; + private: void SplashProc(); diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index 73ce634812f..075b0baab11 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -245,6 +245,9 @@ {2c419512-6eee-4707-bc51-2e834855552e} + + {cff9f0dd-c2fc-424c-800b-bfba35003932} + From 7efd1bc45c65f7423f50478e0db2347a349d296b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 16:41:58 +0500 Subject: [PATCH 057/497] xrEngine/embedded_resources_management.h: fix stack overflow woth splashes greater than 1 MB is size --- src/xrEngine/embedded_resources_management.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/xrEngine/embedded_resources_management.h b/src/xrEngine/embedded_resources_management.h index 0e4cb1076ad..cdb52781877 100644 --- a/src/xrEngine/embedded_resources_management.h +++ b/src/xrEngine/embedded_resources_management.h @@ -11,10 +11,9 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) const size_t pitch = source->pitch; const size_t size = pitch * source->h; - // XXX: get rid of xr_alloca usage, possible stack overflow - //auto original = new u8(size); + // XXX: don't alloc at all, flip surface in-place + auto original = static_cast(xr_malloc(size)); - auto original = static_cast(xr_alloca(size)); CopyMemory(original, source->pixels, size); auto flipped = static_cast(source->pixels) + size; @@ -26,7 +25,7 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) flipped -= pitch; } - //xr_delete(original); + xr_free(original); return source; } From 8e96155d104f9127d6c2622d6cae32736963a72f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 16:55:48 +0500 Subject: [PATCH 058/497] Fixed crash on start with -nogame key specified --- src/xrEngine/Stats.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrEngine/Stats.cpp b/src/xrEngine/Stats.cpp index e0d7bf4bd8f..564655555d3 100644 --- a/src/xrEngine/Stats.cpp +++ b/src/xrEngine/Stats.cpp @@ -129,9 +129,9 @@ void CStats::Show() if (g_pGamePersistent) { g_pGamePersistent->DumpStatistics(font, alertPtr); + DumpSpatialStatistics(font, alertPtr, g_pGamePersistent->SpatialSpace, engineTotal); + DumpSpatialStatistics(font, alertPtr, g_pGamePersistent->SpatialSpacePhysic, engineTotal); } - DumpSpatialStatistics(font, alertPtr, g_pGamePersistent->SpatialSpace, engineTotal); - DumpSpatialStatistics(font, alertPtr, g_pGamePersistent->SpatialSpacePhysic, engineTotal); font.OutSet(200, 0); GEnv.Render->DumpStatistics(font, alertPtr); font.OutSkip(); From 6515c3a18aa11d04508bc64be8332b0f49a04244 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 16:58:38 +0500 Subject: [PATCH 059/497] xrEngine/x_ray.cpp: don't crash if Discord is not available --- src/xrEngine/x_ray.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 99efaa4cd86..bbc8d83bd62 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -227,22 +227,26 @@ CApplication::CApplication(pcstr commandLine) discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &m_discord_core); # ifndef MASTER_GOLD - const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; - m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) + if (m_discord_core) { - switch (level) + const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; + m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) { - case discord::LogLevel::Error: Log("!", message); break; - case discord::LogLevel::Warn: Log("~", message); break; - case discord::LogLevel::Info: Log("*", message); break; - case discord::LogLevel::Debug: Log("#", message); break; - } - }); + switch (level) + { + case discord::LogLevel::Error: Log("!", message); break; + case discord::LogLevel::Warn: Log("~", message); break; + case discord::LogLevel::Info: Log("*", message); break; + case discord::LogLevel::Debug: Log("#", message); break; + } + }); + } # endif discord::Activity activity{}; activity.SetType(discord::ActivityType::Playing); activity.SetApplicationId(DISCORD_APP_ID); + if (m_discord_core) { std::lock_guard guard{ m_discord_lock }; m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); @@ -319,6 +323,7 @@ CApplication::CApplication(pcstr commandLine) #ifdef USE_DISCORD_INTEGRATION const std::locale locale(""); activity.SetDetails(StringToUTF8(Core.ApplicationTitle, locale).c_str()); + if (m_discord_core) { std::lock_guard guard{ m_discord_lock }; m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); @@ -477,7 +482,8 @@ int CApplication::Run() Device.ProcessFrame(); #ifdef USE_DISCORD_INTEGRATION - m_discord_core->RunCallbacks(); + if (m_discord_core) + m_discord_core->RunCallbacks(); #endif } // while (!SDL_QuitRequested()) @@ -545,6 +551,7 @@ void CApplication::SplashProc() SDL_UpdateWindowSurface(m_window); #ifdef USE_DISCORD_INTEGRATION + if (m_discord_core) { std::lock_guard guard{ m_discord_lock }; m_discord_core->RunCallbacks(); From 8add9a28913df6e374b9a8c87afb0e300a55cf86 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 16 Dec 2023 17:51:33 +0500 Subject: [PATCH 060/497] xrEngine/embedded_resources_management.h: fixed incorrect pointer free --- src/xrEngine/embedded_resources_management.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/xrEngine/embedded_resources_management.h b/src/xrEngine/embedded_resources_management.h index cdb52781877..7aa74e00a04 100644 --- a/src/xrEngine/embedded_resources_management.h +++ b/src/xrEngine/embedded_resources_management.h @@ -12,7 +12,8 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) const size_t size = pitch * source->h; // XXX: don't alloc at all, flip surface in-place - auto original = static_cast(xr_malloc(size)); + auto ptr = static_cast(xr_malloc(size)); + auto original = ptr; CopyMemory(original, source->pixels, size); @@ -25,7 +26,7 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) flipped -= pitch; } - xr_free(original); + xr_free(ptr); return source; } From a1331881a888f974a969b2d4ae3a2df31791fbd4 Mon Sep 17 00:00:00 2001 From: Masterkatze Date: Sun, 17 Dec 2023 06:56:17 +0300 Subject: [PATCH 061/497] Fix list/string REGEX issue in LuaJIT CMake file --- Externals/LuaJIT-proj/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/LuaJIT-proj/CMakeLists.txt b/Externals/LuaJIT-proj/CMakeLists.txt index 36abe653fd1..87cfbc9d2ab 100644 --- a/Externals/LuaJIT-proj/CMakeLists.txt +++ b/Externals/LuaJIT-proj/CMakeLists.txt @@ -268,7 +268,7 @@ if ("${TESTARCH_OUTPUT}" MATCHES "LJ_NO_UNWIND 1") endif() if ("${TESTARCH_OUTPUT}" MATCHES "LJ_ARCH_VERSION") - list(REGEX MATCH "LJ_ARCH_VERSION ([0-9]+)$" _ "${TESTARCH_OUTPUT}") + string(REGEX MATCH "LJ_ARCH_VERSION ([0-9]+)$" _ "${TESTARCH_OUTPUT}") list(APPEND DASM_FLAGS "-D VER=${CMAKE_MATCH_1}") else() list(APPEND DASM_FLAGS "-D VER=") From 2b6a1168aa29eea68bee075a78f77e9561ee8a96 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 12:37:05 +0500 Subject: [PATCH 062/497] Place structures needed by xrSound into xrSound Plus, small includes cleanup: sorted them, and removed mmsystem.h (not needed) --- src/Common/PlatformApple.inl | 13 ------------- src/Common/PlatformBSD.inl | 13 ------------- src/Common/PlatformLinux.inl | 13 ------------- src/xrSound/stdafx.h | 37 ++++++++++++++++++++---------------- 4 files changed, 21 insertions(+), 55 deletions(-) diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 348ee3d6a21..1cc460b9321 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -163,19 +163,6 @@ typedef long long int* PLARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 - -typedef struct { - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *LPWAVEFORMATEX; - typedef struct tagSTICKYKEYS { DWORD cbSize; diff --git a/src/Common/PlatformBSD.inl b/src/Common/PlatformBSD.inl index e955262bc36..7bd021f9994 100644 --- a/src/Common/PlatformBSD.inl +++ b/src/Common/PlatformBSD.inl @@ -161,19 +161,6 @@ typedef long long int* PLARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 - -typedef struct { - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *LPWAVEFORMATEX; - typedef struct tagSTICKYKEYS { DWORD cbSize; diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index e094b66ed84..d21722d9e45 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -154,19 +154,6 @@ typedef unsigned long long int ULARGE_INTEGER; typedef wchar_t WCHAR; -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 - -typedef struct { - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *LPWAVEFORMATEX; - typedef struct tagSTICKYKEYS { DWORD cbSize; diff --git a/src/xrSound/stdafx.h b/src/xrSound/stdafx.h index e6d74f5785a..b8e0fde3f02 100644 --- a/src/xrSound/stdafx.h +++ b/src/xrSound/stdafx.h @@ -3,16 +3,16 @@ #include "Common/Common.hpp" #include "xrCore/xrCore.h" #include "xrCore/_std_extensions.h" +#include "xrCore/xr_resource.h" -#if defined(XR_PLATFORM_WINDOWS) -// mmsystem.h -#define MMNOSOUND -#define MMNOMIDI -#define MMNOAUX -#define MMNOMIXER -#define MMNOJOY -#include +#include "xrCDB/xrCDB.h" + +#include "Sound.h" +#include +#include + +#if defined(XR_PLATFORM_WINDOWS) // mmreg.h #define NOMMIDS #define NONEWRIFF @@ -20,12 +20,17 @@ #define NONEWIC #define NOBITMAP #include -#endif +#else +#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 -#include -#include - -#include "xrCDB/xrCDB.h" -#include "Sound.h" - -#include "xrCore/xr_resource.h" +typedef struct { + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +} WAVEFORMATEX, *LPWAVEFORMATEX; +#endif From 131a2ad41af7af8d3394b23ce8aa9a4802694587 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 16:51:15 +0500 Subject: [PATCH 063/497] ini_id_loader.h and xml_str_id_loader.h: default constructors and destructors --- src/xrGame/ini_id_loader.h | 8 ++------ src/xrServerEntities/xml_str_id_loader.h | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/xrGame/ini_id_loader.h b/src/xrGame/ini_id_loader.h index 27ed847aee3..abded7370cf 100644 --- a/src/xrGame/ini_id_loader.h +++ b/src/xrGame/ini_id_loader.h @@ -62,8 +62,8 @@ class CIni_IdToIndex static LPCSTR line_name; public: - CIni_IdToIndex(); - virtual ~CIni_IdToIndex(); + CIni_IdToIndex() = default; + virtual ~CIni_IdToIndex() = default; static void InitInternal(); static const ITEM_DATA* GetById(const T_ID& str_id, bool no_assert = false); @@ -93,10 +93,6 @@ LPCSTR CSINI_IdToIndex::section_name = NULL; TEMPLATE_SPECIALIZATION LPCSTR CSINI_IdToIndex::line_name = NULL; -TEMPLATE_SPECIALIZATION -CSINI_IdToIndex::CIni_IdToIndex() {} -TEMPLATE_SPECIALIZATION -CSINI_IdToIndex::~CIni_IdToIndex() {} TEMPLATE_SPECIALIZATION const ITEM_DATA* CSINI_IdToIndex::GetById(const T_ID& str_id, bool no_assert) { diff --git a/src/xrServerEntities/xml_str_id_loader.h b/src/xrServerEntities/xml_str_id_loader.h index eef3ca2561a..c0e576f6284 100644 --- a/src/xrServerEntities/xml_str_id_loader.h +++ b/src/xrServerEntities/xml_str_id_loader.h @@ -41,8 +41,8 @@ class CXML_IdToIndex static LPCSTR tag_name; public: - CXML_IdToIndex(); - virtual ~CXML_IdToIndex(); + CXML_IdToIndex() = default; + virtual ~CXML_IdToIndex() = default; static void InitInternal(bool crashOnFail = true, bool ignoreMissingEndTagError = false); @@ -73,10 +73,6 @@ LPCSTR CSXML_IdToIndex::file_str = NULL; TEMPLATE_SPECIALIZATION LPCSTR CSXML_IdToIndex::tag_name = NULL; -TEMPLATE_SPECIALIZATION -CSXML_IdToIndex::CXML_IdToIndex() {} -TEMPLATE_SPECIALIZATION -CSXML_IdToIndex::~CXML_IdToIndex() {} TEMPLATE_SPECIALIZATION const ITEM_DATA* CSXML_IdToIndex::GetById(const shared_str& str_id, bool no_assert) { From fedce64a49a7fd1986df89e8fb4f82601b49ed46 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 18:56:54 +0500 Subject: [PATCH 064/497] xrEngine/IGame_Level.cpp: removed smart_cast.h include Because it shouldn't be there --- src/xrEngine/IGame_Level.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index de72bb7438c..e3ca7426fca 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -9,7 +9,6 @@ #include "CameraManager.h" #include "xr_object.h" #include "Feel_Sound.h" -#include "xrServerEntities/smart_cast.h" ENGINE_API IGame_Level* g_pGameLevel = NULL; extern bool g_bLoaded; From 2a62b20c04b2d827069cca7bd95c46877a86e398 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 19:51:51 +0500 Subject: [PATCH 065/497] Moved particles from IGame_Persistent to IGame_Level These belong to the level --- src/xrEngine/IGame_Level.cpp | 80 ++++++++++++++++- src/xrEngine/IGame_Level.h | 27 ++++++ src/xrEngine/IGame_Persistent.cpp | 85 +------------------ src/xrEngine/IGame_Persistent.h | 28 ------ src/xrEngine/PS_instance.cpp | 16 ++-- src/xrEngine/PS_instance.h | 2 +- src/xrGame/Actor.cpp | 2 +- src/xrGame/Actor_Network.cpp | 2 +- src/xrGame/Level_Bullet_Manager.cpp | 2 +- src/xrGame/Level_bullet_manager_firetrace.cpp | 2 +- src/xrGame/Level_network.cpp | 2 +- src/xrGame/ai/monsters/burer/burer.cpp | 2 +- src/xrGame/game_cl_deathmatch.cpp | 2 +- src/xrGame/physics_game.cpp | 2 +- src/xrGame/step_manager.cpp | 2 +- 15 files changed, 127 insertions(+), 129 deletions(-) diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index e3ca7426fca..3b5fd7d09c3 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -9,6 +9,7 @@ #include "CameraManager.h" #include "xr_object.h" #include "Feel_Sound.h" +#include "PS_instance.h" ENGINE_API IGame_Level* g_pGameLevel = NULL; extern bool g_bLoaded; @@ -54,6 +55,9 @@ IGame_Level::~IGame_Level() GEnv.Render->ResourcesGetMemoryUsage(m_base, c_base, m_lmaps, c_lmaps); Msg("* [ D3D ]: textures[%d K]", (m_base + m_lmaps) / 1024); + + // clear "need to play" particles + DestroyParticles(true); } void IGame_Level::net_Stop() @@ -202,9 +206,83 @@ void IGame_Level::OnFrame() Sounds_Random[id].set_range(10, 200); } } + + particles_stats.Starting = ps_needtoplay.size(); + particles_stats.Active = ps_active.size(); + particles_stats.Destroying = ps_destroy.size(); + + // Play req particle systems + while (!ps_needtoplay.empty()) + { + CPS_Instance* psi = ps_needtoplay.back(); + ps_needtoplay.pop_back(); + psi->Play(false); + } + + // Destroy inactive particle systems + while (!ps_destroy.empty()) + { + CPS_Instance* psi = ps_destroy.back(); + VERIFY(psi); + if (psi->Locked()) + { + VERIFY2(false, "Try to delete particle system instance, but it's locked!"); + break; + } + ps_destroy.pop_back(); + psi->PSI_internal_delete(); + } } -void IGame_Level::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) { Objects.DumpStatistics(font, alert); } +void IGame_Level::DestroyParticles(bool all_particles) +{ +#ifndef _EDITOR + ps_needtoplay.clear(); + + while (ps_destroy.size()) + { + CPS_Instance* psi = ps_destroy.back(); + VERIFY(psi); + VERIFY(!psi->Locked()); + ps_destroy.pop_back(); + psi->PSI_internal_delete(); + } + + // delete active particles + if (all_particles) + { + for (; !ps_active.empty();) + (*ps_active.begin())->PSI_internal_delete(); + } + else + { + u32 active_size = ps_active.size(); + CPS_Instance** I = (CPS_Instance**)xr_alloca(active_size * sizeof(CPS_Instance*)); + std::copy(ps_active.begin(), ps_active.end(), I); + + CPS_Instance** E = std::remove_if(I, I + active_size, [](CPS_Instance* const& object) + { + return (!object->destroy_on_game_load()); + }); + for (; I != E; ++I) + (*I)->PSI_internal_delete(); + } + + VERIFY(ps_needtoplay.empty() && ps_destroy.empty() && (!all_particles || ps_active.empty())); +#endif +} + +void IGame_Level::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) +{ + particles_stats.FrameEnd(); + font.OutNext("Particles:"); + font.OutNext("- starting: %u", particles_stats.Starting); + font.OutNext("- active: %u", particles_stats.Active); + font.OutNext("- destroying: %u", particles_stats.Destroying); + particles_stats.FrameStart(); + + Objects.DumpStatistics(font, alert); +} // ================================================================================================== void CServerInfo::AddItem(pcstr name_, pcstr value_, u32 color_) diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 6de9655221a..5606ebed224 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -16,6 +16,7 @@ class ENGINE_API CCameraManager; class ENGINE_API CCursor; class ENGINE_API CCustomHUD; class ENGINE_API ISpatial; +class ENGINE_API CPS_Instance; namespace Feel { class ENGINE_API Sound; @@ -74,6 +75,30 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, // temporary xr_vector snd_ER; + struct ParticleStatistics + { + u32 Starting; + u32 Active; + u32 Destroying; + + ParticleStatistics() { FrameStart(); } + void FrameStart() + { + Starting = 0; + Active = 0; + Destroying = 0; + } + + void FrameEnd() {} + }; + + ParticleStatistics particles_stats; + +public: + xr_set ps_active; + xr_vector ps_destroy; + xr_vector ps_needtoplay; + public: ISoundScene* Sound{}; @@ -122,6 +147,8 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, [[nodiscard]] bool WorldRendered() const { return m_world_rendered; } void WorldRendered(bool rendered) { m_world_rendered = rendered; } + void DestroyParticles(bool all_particles); + virtual shared_str OpenDemoFile(const char* demo_file_name) = 0; virtual void net_StartPlayDemo() = 0; diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 8d3359295a9..2f7d0a021cc 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -14,7 +14,6 @@ #include "IGame_Level.h" #include "XR_IOConsole.h" #include "Render.h" -#include "PS_instance.h" #include "CustomHUD.h" #include "perlin.h" #endif @@ -350,17 +349,9 @@ void IGame_Persistent::Start(pcstr op) } else UpdateGameType(); - - VERIFY(ps_destroy.empty()); } -void IGame_Persistent::Disconnect() -{ -#ifndef _EDITOR - // clear "need to play" particles - destroy_particles(true); -#endif -} +void IGame_Persistent::Disconnect() {} void IGame_Persistent::OnGameStart() { @@ -546,69 +537,6 @@ void IGame_Persistent::OnFrame() UpdateHudRaindrops(); UpdateRainGloss(); } - - stats.Starting = ps_needtoplay.size(); - stats.Active = ps_active.size(); - stats.Destroying = ps_destroy.size(); - // Play req particle systems - while (ps_needtoplay.size()) - { - CPS_Instance* psi = ps_needtoplay.back(); - ps_needtoplay.pop_back(); - psi->Play(false); - } - // Destroy inactive particle systems - while (ps_destroy.size()) - { - // u32 cnt = ps_destroy.size(); - CPS_Instance* psi = ps_destroy.back(); - VERIFY(psi); - if (psi->Locked()) - { - Log("--locked"); - break; - } - ps_destroy.pop_back(); - psi->PSI_internal_delete(); - } -#endif -} - -void IGame_Persistent::destroy_particles(const bool& all_particles) -{ -#ifndef _EDITOR - ps_needtoplay.clear(); - - while (ps_destroy.size()) - { - CPS_Instance* psi = ps_destroy.back(); - VERIFY(psi); - VERIFY(!psi->Locked()); - ps_destroy.pop_back(); - psi->PSI_internal_delete(); - } - - // delete active particles - if (all_particles) - { - for (; !ps_active.empty();) - (*ps_active.begin())->PSI_internal_delete(); - } - else - { - u32 active_size = ps_active.size(); - CPS_Instance** I = (CPS_Instance**)xr_alloca(active_size * sizeof(CPS_Instance*)); - std::copy(ps_active.begin(), ps_active.end(), I); - - CPS_Instance** E = std::remove_if(I, I + active_size, [](CPS_Instance* const& object) - { - return (!object->destroy_on_game_load()); - }); - for (; I != E; ++I) - (*I)->PSI_internal_delete(); - } - - VERIFY(ps_needtoplay.empty() && ps_destroy.empty() && (!all_particles || ps_active.empty())); #endif } @@ -630,13 +558,4 @@ void IGame_Persistent::OnAssetsChanged() #endif } -void IGame_Persistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) -{ - // XXX: move to particle engine - stats.FrameEnd(); - font.OutNext("Particles:"); - font.OutNext("- starting: %u", stats.Starting); - font.OutNext("- active: %u", stats.Active); - font.OutNext("- destroying: %u", stats.Destroying); - stats.FrameStart(); -} +void IGame_Persistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) {} diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index befccdef1c7..872e56fb5b6 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -22,7 +22,6 @@ class IRenderVisual; class ILoadingScreen; class IMainMenu; -class ENGINE_API CPS_Instance; //----------------------------------------------------------------------------------------------------------- class ENGINE_API IGame_Persistent : #ifndef _EDITOR @@ -36,22 +35,6 @@ class ENGINE_API IGame_Persistent : public IEventReceiver { public: - struct ParticleStatistics - { - u32 Starting; - u32 Active; - u32 Destroying; - - ParticleStatistics() { FrameStart(); } - void FrameStart() - { - Starting = 0; - Active = 0; - Destroying = 0; - } - - void FrameEnd() {} - }; union params { struct @@ -82,11 +65,6 @@ class ENGINE_API IGame_Persistent : }; params m_game_params; -public: - xr_set ps_active; - xr_vector ps_destroy; - xr_vector ps_needtoplay; - public: enum GrassBenders_Anim { @@ -132,9 +110,6 @@ class ENGINE_API IGame_Persistent : void UpdateHudRaindrops() const; void UpdateRainGloss() const; -public: - void destroy_particles(const bool& all_particles); - private: EVENT eStart; EVENT eStartLoad; @@ -188,11 +163,8 @@ class ENGINE_API IGame_Persistent : bool IsMainMenuActive() const; bool MainMenuActiveOrLevelNotExist() const; - ParticleStatistics stats; - ShadersExternalData* m_pGShaderConstants; //--#SM+#-- - const ParticleStatistics& GetStats() { return stats; } virtual bool OnRenderPPUI_query() { return false; }; // should return true if we want to have second function called virtual void OnRenderPPUI_main(){}; virtual void OnRenderPPUI_PP(){}; diff --git a/src/xrEngine/PS_instance.cpp b/src/xrEngine/PS_instance.cpp index d4fb8a472cd..a344f98250c 100644 --- a/src/xrEngine/PS_instance.cpp +++ b/src/xrEngine/PS_instance.cpp @@ -5,12 +5,14 @@ #pragma hdrstop #include "PS_instance.h" + +#include "IGame_Level.h" #include "IGame_Persistent.h" CPS_Instance::CPS_Instance(bool destroy_on_game_load) : SpatialBase(g_pGamePersistent->SpatialSpace), m_destroy_on_game_load(destroy_on_game_load) { - g_pGamePersistent->ps_active.insert(this); + g_pGameLevel->ps_active.insert(this); renderable.pROS_Allowed = false; m_iLifeTime = int_max; @@ -23,12 +25,12 @@ extern ENGINE_API bool g_bRendering; CPS_Instance::~CPS_Instance() { VERIFY(!g_bRendering); - auto it = g_pGamePersistent->ps_active.find(this); - VERIFY(it != g_pGamePersistent->ps_active.end()); - g_pGamePersistent->ps_active.erase(it); + auto it = g_pGameLevel->ps_active.find(this); + VERIFY(it != g_pGameLevel->ps_active.end()); + g_pGameLevel->ps_active.erase(it); - [[maybe_unused]] auto it2 = std::find(g_pGamePersistent->ps_destroy.begin(), g_pGamePersistent->ps_destroy.end(), this); - VERIFY(it2 == g_pGamePersistent->ps_destroy.end()); + [[maybe_unused]] auto it2 = std::find(g_pGameLevel->ps_destroy.begin(), g_pGameLevel->ps_destroy.end(), this); + VERIFY(it2 == g_pGameLevel->ps_destroy.end()); spatial_unregister(); shedule_unregister(); @@ -53,7 +55,7 @@ void CPS_Instance::PSI_destroy() { m_bDead = true; m_iLifeTime = 0; - g_pGamePersistent->ps_destroy.push_back(this); + g_pGameLevel->ps_destroy.push_back(this); } //---------------------------------------------------- void CPS_Instance::PSI_internal_delete() diff --git a/src/xrEngine/PS_instance.h b/src/xrEngine/PS_instance.h index 5a44e27ee6d..c301e78fa64 100644 --- a/src/xrEngine/PS_instance.h +++ b/src/xrEngine/PS_instance.h @@ -9,7 +9,7 @@ class ENGINE_API CPS_Instance : public SpatialBase, public ScheduledBase, public RenderableBase { - friend class IGame_Persistent; + friend class IGame_Level; private: bool m_destroy_on_game_load; diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 985642a8e37..9053f649c83 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -524,7 +524,7 @@ void CActor::Hit(SHit* pHDS) ps = CParticlesObject::Create(invincibility_fire_shield_3rd, TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); }; }; diff --git a/src/xrGame/Actor_Network.cpp b/src/xrGame/Actor_Network.cpp index 140ba839fbc..8cf36b14d31 100644 --- a/src/xrGame/Actor_Network.cpp +++ b/src/xrGame/Actor_Network.cpp @@ -2019,7 +2019,7 @@ void CActor::OnPlayHeadShotParticle(NET_Packet P) ps = CParticlesObject::Create(m_sHeadShotParticle.c_str(), TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); }; void CActor::OnCriticalWoundHealthLoss() diff --git a/src/xrGame/Level_Bullet_Manager.cpp b/src/xrGame/Level_Bullet_Manager.cpp index 05ff474bdd8..d9aebbb6dda 100644 --- a/src/xrGame/Level_Bullet_Manager.cpp +++ b/src/xrGame/Level_Bullet_Manager.cpp @@ -149,7 +149,7 @@ void CBulletManager::PlayExplodePS(const Fmatrix& xf) shared_str const& ps_name = m_ExplodeParticles[Random.randI(0, m_ExplodeParticles.size())]; CParticlesObject* const ps = CParticlesObject::Create(*ps_name, TRUE); ps->UpdateParent(xf, zero_vel); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); } void CBulletManager::PlayWhineSound(SBullet* bullet, IGameObject* object, const Fvector& pos) diff --git a/src/xrGame/Level_bullet_manager_firetrace.cpp b/src/xrGame/Level_bullet_manager_firetrace.cpp index f5d79488e81..a3a059c80bd 100644 --- a/src/xrGame/Level_bullet_manager_firetrace.cpp +++ b/src/xrGame/Level_bullet_manager_firetrace.cpp @@ -249,7 +249,7 @@ void CBulletManager::FireShotmark(SBullet* bullet, const Fvector& vDir, const Fv CParticlesObject* ps = CParticlesObject::Create(ps_name, TRUE); ps->UpdateParent(pos, zero_vel); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); } if (bullet->flags.explosive && bStatic) diff --git a/src/xrGame/Level_network.cpp b/src/xrGame/Level_network.cpp index 0b336643478..d75ab8511f9 100644 --- a/src/xrGame/Level_network.cpp +++ b/src/xrGame/Level_network.cpp @@ -104,7 +104,7 @@ void CLevel::remove_objects() client_spawn_manager().clear(); } - g_pGamePersistent->destroy_particles(false); + DestroyParticles(false); //. xr_delete (m_seniority_hierarchy_holder); //. m_seniority_hierarchy_holder = new CSeniorityHierarchyHolder(); diff --git a/src/xrGame/ai/monsters/burer/burer.cpp b/src/xrGame/ai/monsters/burer/burer.cpp index bd309137829..20b635cf3f1 100644 --- a/src/xrGame/ai/monsters/burer/burer.cpp +++ b/src/xrGame/ai/monsters/burer/burer.cpp @@ -455,7 +455,7 @@ void CBurer::Hit(SHit* pHDS) CParticlesObject* ps = CParticlesObject::Create(particle_fire_shield, TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); } else if (!m_shield_active) { diff --git a/src/xrGame/game_cl_deathmatch.cpp b/src/xrGame/game_cl_deathmatch.cpp index f58809216b1..77a2d68f219 100644 --- a/src/xrGame/game_cl_deathmatch.cpp +++ b/src/xrGame/game_cl_deathmatch.cpp @@ -983,7 +983,7 @@ void game_cl_Deathmatch::PlayParticleEffect(LPCSTR EffName, Fvector& pos) ps = CParticlesObject::Create(EffName, TRUE); ps->UpdateParent(M, Fvector().set(0.f, 0.f, 0.f)); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); } void game_cl_Deathmatch::OnSpawn(IGameObject* pObj) diff --git a/src/xrGame/physics_game.cpp b/src/xrGame/physics_game.cpp index ca9ce08f101..914285ca237 100644 --- a/src/xrGame/physics_game.cpp +++ b/src/xrGame/physics_game.cpp @@ -59,7 +59,7 @@ class CPHParticlesPlayCall : public CPHAction pos.c.set(*((Fvector*)c.pos)); ps->UpdateParent(pos, zero_vel); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); }; virtual bool obsolete() const { return false; } }; diff --git a/src/xrGame/step_manager.cpp b/src/xrGame/step_manager.cpp index 3dcc3b7aeaf..d5c04235386 100644 --- a/src/xrGame/step_manager.cpp +++ b/src/xrGame/step_manager.cpp @@ -219,7 +219,7 @@ void CStepManager::update(bool b_hud_view) pos.c.set(get_foot_position(ELegType(i))); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - GamePersistent().ps_needtoplay.push_back(ps); + Level().ps_needtoplay.push_back(ps); } // Play Camera FXs From 77253ea64237716107bf1ac582f4e0787b57d6b8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 21:40:35 +0500 Subject: [PATCH 066/497] Revert "Moved particles from IGame_Persistent to IGame_Level" This reverts commit 2a62b20c04b2d827069cca7bd95c46877a86e398. --- src/xrEngine/IGame_Level.cpp | 80 +---------------- src/xrEngine/IGame_Level.h | 27 ------ src/xrEngine/IGame_Persistent.cpp | 85 ++++++++++++++++++- src/xrEngine/IGame_Persistent.h | 28 ++++++ src/xrEngine/PS_instance.cpp | 16 ++-- src/xrEngine/PS_instance.h | 2 +- src/xrGame/Actor.cpp | 2 +- src/xrGame/Actor_Network.cpp | 2 +- src/xrGame/Level_Bullet_Manager.cpp | 2 +- src/xrGame/Level_bullet_manager_firetrace.cpp | 2 +- src/xrGame/Level_network.cpp | 2 +- src/xrGame/ai/monsters/burer/burer.cpp | 2 +- src/xrGame/game_cl_deathmatch.cpp | 2 +- src/xrGame/physics_game.cpp | 2 +- src/xrGame/step_manager.cpp | 2 +- 15 files changed, 129 insertions(+), 127 deletions(-) diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 3b5fd7d09c3..e3ca7426fca 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -9,7 +9,6 @@ #include "CameraManager.h" #include "xr_object.h" #include "Feel_Sound.h" -#include "PS_instance.h" ENGINE_API IGame_Level* g_pGameLevel = NULL; extern bool g_bLoaded; @@ -55,9 +54,6 @@ IGame_Level::~IGame_Level() GEnv.Render->ResourcesGetMemoryUsage(m_base, c_base, m_lmaps, c_lmaps); Msg("* [ D3D ]: textures[%d K]", (m_base + m_lmaps) / 1024); - - // clear "need to play" particles - DestroyParticles(true); } void IGame_Level::net_Stop() @@ -206,83 +202,9 @@ void IGame_Level::OnFrame() Sounds_Random[id].set_range(10, 200); } } - - particles_stats.Starting = ps_needtoplay.size(); - particles_stats.Active = ps_active.size(); - particles_stats.Destroying = ps_destroy.size(); - - // Play req particle systems - while (!ps_needtoplay.empty()) - { - CPS_Instance* psi = ps_needtoplay.back(); - ps_needtoplay.pop_back(); - psi->Play(false); - } - - // Destroy inactive particle systems - while (!ps_destroy.empty()) - { - CPS_Instance* psi = ps_destroy.back(); - VERIFY(psi); - if (psi->Locked()) - { - VERIFY2(false, "Try to delete particle system instance, but it's locked!"); - break; - } - ps_destroy.pop_back(); - psi->PSI_internal_delete(); - } } -void IGame_Level::DestroyParticles(bool all_particles) -{ -#ifndef _EDITOR - ps_needtoplay.clear(); - - while (ps_destroy.size()) - { - CPS_Instance* psi = ps_destroy.back(); - VERIFY(psi); - VERIFY(!psi->Locked()); - ps_destroy.pop_back(); - psi->PSI_internal_delete(); - } - - // delete active particles - if (all_particles) - { - for (; !ps_active.empty();) - (*ps_active.begin())->PSI_internal_delete(); - } - else - { - u32 active_size = ps_active.size(); - CPS_Instance** I = (CPS_Instance**)xr_alloca(active_size * sizeof(CPS_Instance*)); - std::copy(ps_active.begin(), ps_active.end(), I); - - CPS_Instance** E = std::remove_if(I, I + active_size, [](CPS_Instance* const& object) - { - return (!object->destroy_on_game_load()); - }); - for (; I != E; ++I) - (*I)->PSI_internal_delete(); - } - - VERIFY(ps_needtoplay.empty() && ps_destroy.empty() && (!all_particles || ps_active.empty())); -#endif -} - -void IGame_Level::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) -{ - particles_stats.FrameEnd(); - font.OutNext("Particles:"); - font.OutNext("- starting: %u", particles_stats.Starting); - font.OutNext("- active: %u", particles_stats.Active); - font.OutNext("- destroying: %u", particles_stats.Destroying); - particles_stats.FrameStart(); - - Objects.DumpStatistics(font, alert); -} +void IGame_Level::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) { Objects.DumpStatistics(font, alert); } // ================================================================================================== void CServerInfo::AddItem(pcstr name_, pcstr value_, u32 color_) diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 5606ebed224..6de9655221a 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -16,7 +16,6 @@ class ENGINE_API CCameraManager; class ENGINE_API CCursor; class ENGINE_API CCustomHUD; class ENGINE_API ISpatial; -class ENGINE_API CPS_Instance; namespace Feel { class ENGINE_API Sound; @@ -75,30 +74,6 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, // temporary xr_vector snd_ER; - struct ParticleStatistics - { - u32 Starting; - u32 Active; - u32 Destroying; - - ParticleStatistics() { FrameStart(); } - void FrameStart() - { - Starting = 0; - Active = 0; - Destroying = 0; - } - - void FrameEnd() {} - }; - - ParticleStatistics particles_stats; - -public: - xr_set ps_active; - xr_vector ps_destroy; - xr_vector ps_needtoplay; - public: ISoundScene* Sound{}; @@ -147,8 +122,6 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, [[nodiscard]] bool WorldRendered() const { return m_world_rendered; } void WorldRendered(bool rendered) { m_world_rendered = rendered; } - void DestroyParticles(bool all_particles); - virtual shared_str OpenDemoFile(const char* demo_file_name) = 0; virtual void net_StartPlayDemo() = 0; diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 2f7d0a021cc..8d3359295a9 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -14,6 +14,7 @@ #include "IGame_Level.h" #include "XR_IOConsole.h" #include "Render.h" +#include "PS_instance.h" #include "CustomHUD.h" #include "perlin.h" #endif @@ -349,9 +350,17 @@ void IGame_Persistent::Start(pcstr op) } else UpdateGameType(); + + VERIFY(ps_destroy.empty()); } -void IGame_Persistent::Disconnect() {} +void IGame_Persistent::Disconnect() +{ +#ifndef _EDITOR + // clear "need to play" particles + destroy_particles(true); +#endif +} void IGame_Persistent::OnGameStart() { @@ -537,6 +546,69 @@ void IGame_Persistent::OnFrame() UpdateHudRaindrops(); UpdateRainGloss(); } + + stats.Starting = ps_needtoplay.size(); + stats.Active = ps_active.size(); + stats.Destroying = ps_destroy.size(); + // Play req particle systems + while (ps_needtoplay.size()) + { + CPS_Instance* psi = ps_needtoplay.back(); + ps_needtoplay.pop_back(); + psi->Play(false); + } + // Destroy inactive particle systems + while (ps_destroy.size()) + { + // u32 cnt = ps_destroy.size(); + CPS_Instance* psi = ps_destroy.back(); + VERIFY(psi); + if (psi->Locked()) + { + Log("--locked"); + break; + } + ps_destroy.pop_back(); + psi->PSI_internal_delete(); + } +#endif +} + +void IGame_Persistent::destroy_particles(const bool& all_particles) +{ +#ifndef _EDITOR + ps_needtoplay.clear(); + + while (ps_destroy.size()) + { + CPS_Instance* psi = ps_destroy.back(); + VERIFY(psi); + VERIFY(!psi->Locked()); + ps_destroy.pop_back(); + psi->PSI_internal_delete(); + } + + // delete active particles + if (all_particles) + { + for (; !ps_active.empty();) + (*ps_active.begin())->PSI_internal_delete(); + } + else + { + u32 active_size = ps_active.size(); + CPS_Instance** I = (CPS_Instance**)xr_alloca(active_size * sizeof(CPS_Instance*)); + std::copy(ps_active.begin(), ps_active.end(), I); + + CPS_Instance** E = std::remove_if(I, I + active_size, [](CPS_Instance* const& object) + { + return (!object->destroy_on_game_load()); + }); + for (; I != E; ++I) + (*I)->PSI_internal_delete(); + } + + VERIFY(ps_needtoplay.empty() && ps_destroy.empty() && (!all_particles || ps_active.empty())); #endif } @@ -558,4 +630,13 @@ void IGame_Persistent::OnAssetsChanged() #endif } -void IGame_Persistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) {} +void IGame_Persistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) +{ + // XXX: move to particle engine + stats.FrameEnd(); + font.OutNext("Particles:"); + font.OutNext("- starting: %u", stats.Starting); + font.OutNext("- active: %u", stats.Active); + font.OutNext("- destroying: %u", stats.Destroying); + stats.FrameStart(); +} diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 872e56fb5b6..befccdef1c7 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -22,6 +22,7 @@ class IRenderVisual; class ILoadingScreen; class IMainMenu; +class ENGINE_API CPS_Instance; //----------------------------------------------------------------------------------------------------------- class ENGINE_API IGame_Persistent : #ifndef _EDITOR @@ -35,6 +36,22 @@ class ENGINE_API IGame_Persistent : public IEventReceiver { public: + struct ParticleStatistics + { + u32 Starting; + u32 Active; + u32 Destroying; + + ParticleStatistics() { FrameStart(); } + void FrameStart() + { + Starting = 0; + Active = 0; + Destroying = 0; + } + + void FrameEnd() {} + }; union params { struct @@ -65,6 +82,11 @@ class ENGINE_API IGame_Persistent : }; params m_game_params; +public: + xr_set ps_active; + xr_vector ps_destroy; + xr_vector ps_needtoplay; + public: enum GrassBenders_Anim { @@ -110,6 +132,9 @@ class ENGINE_API IGame_Persistent : void UpdateHudRaindrops() const; void UpdateRainGloss() const; +public: + void destroy_particles(const bool& all_particles); + private: EVENT eStart; EVENT eStartLoad; @@ -163,8 +188,11 @@ class ENGINE_API IGame_Persistent : bool IsMainMenuActive() const; bool MainMenuActiveOrLevelNotExist() const; + ParticleStatistics stats; + ShadersExternalData* m_pGShaderConstants; //--#SM+#-- + const ParticleStatistics& GetStats() { return stats; } virtual bool OnRenderPPUI_query() { return false; }; // should return true if we want to have second function called virtual void OnRenderPPUI_main(){}; virtual void OnRenderPPUI_PP(){}; diff --git a/src/xrEngine/PS_instance.cpp b/src/xrEngine/PS_instance.cpp index a344f98250c..d4fb8a472cd 100644 --- a/src/xrEngine/PS_instance.cpp +++ b/src/xrEngine/PS_instance.cpp @@ -5,14 +5,12 @@ #pragma hdrstop #include "PS_instance.h" - -#include "IGame_Level.h" #include "IGame_Persistent.h" CPS_Instance::CPS_Instance(bool destroy_on_game_load) : SpatialBase(g_pGamePersistent->SpatialSpace), m_destroy_on_game_load(destroy_on_game_load) { - g_pGameLevel->ps_active.insert(this); + g_pGamePersistent->ps_active.insert(this); renderable.pROS_Allowed = false; m_iLifeTime = int_max; @@ -25,12 +23,12 @@ extern ENGINE_API bool g_bRendering; CPS_Instance::~CPS_Instance() { VERIFY(!g_bRendering); - auto it = g_pGameLevel->ps_active.find(this); - VERIFY(it != g_pGameLevel->ps_active.end()); - g_pGameLevel->ps_active.erase(it); + auto it = g_pGamePersistent->ps_active.find(this); + VERIFY(it != g_pGamePersistent->ps_active.end()); + g_pGamePersistent->ps_active.erase(it); - [[maybe_unused]] auto it2 = std::find(g_pGameLevel->ps_destroy.begin(), g_pGameLevel->ps_destroy.end(), this); - VERIFY(it2 == g_pGameLevel->ps_destroy.end()); + [[maybe_unused]] auto it2 = std::find(g_pGamePersistent->ps_destroy.begin(), g_pGamePersistent->ps_destroy.end(), this); + VERIFY(it2 == g_pGamePersistent->ps_destroy.end()); spatial_unregister(); shedule_unregister(); @@ -55,7 +53,7 @@ void CPS_Instance::PSI_destroy() { m_bDead = true; m_iLifeTime = 0; - g_pGameLevel->ps_destroy.push_back(this); + g_pGamePersistent->ps_destroy.push_back(this); } //---------------------------------------------------- void CPS_Instance::PSI_internal_delete() diff --git a/src/xrEngine/PS_instance.h b/src/xrEngine/PS_instance.h index c301e78fa64..5a44e27ee6d 100644 --- a/src/xrEngine/PS_instance.h +++ b/src/xrEngine/PS_instance.h @@ -9,7 +9,7 @@ class ENGINE_API CPS_Instance : public SpatialBase, public ScheduledBase, public RenderableBase { - friend class IGame_Level; + friend class IGame_Persistent; private: bool m_destroy_on_game_load; diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 9053f649c83..985642a8e37 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -524,7 +524,7 @@ void CActor::Hit(SHit* pHDS) ps = CParticlesObject::Create(invincibility_fire_shield_3rd, TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); }; }; diff --git a/src/xrGame/Actor_Network.cpp b/src/xrGame/Actor_Network.cpp index 8cf36b14d31..140ba839fbc 100644 --- a/src/xrGame/Actor_Network.cpp +++ b/src/xrGame/Actor_Network.cpp @@ -2019,7 +2019,7 @@ void CActor::OnPlayHeadShotParticle(NET_Packet P) ps = CParticlesObject::Create(m_sHeadShotParticle.c_str(), TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); }; void CActor::OnCriticalWoundHealthLoss() diff --git a/src/xrGame/Level_Bullet_Manager.cpp b/src/xrGame/Level_Bullet_Manager.cpp index d9aebbb6dda..05ff474bdd8 100644 --- a/src/xrGame/Level_Bullet_Manager.cpp +++ b/src/xrGame/Level_Bullet_Manager.cpp @@ -149,7 +149,7 @@ void CBulletManager::PlayExplodePS(const Fmatrix& xf) shared_str const& ps_name = m_ExplodeParticles[Random.randI(0, m_ExplodeParticles.size())]; CParticlesObject* const ps = CParticlesObject::Create(*ps_name, TRUE); ps->UpdateParent(xf, zero_vel); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); } void CBulletManager::PlayWhineSound(SBullet* bullet, IGameObject* object, const Fvector& pos) diff --git a/src/xrGame/Level_bullet_manager_firetrace.cpp b/src/xrGame/Level_bullet_manager_firetrace.cpp index a3a059c80bd..f5d79488e81 100644 --- a/src/xrGame/Level_bullet_manager_firetrace.cpp +++ b/src/xrGame/Level_bullet_manager_firetrace.cpp @@ -249,7 +249,7 @@ void CBulletManager::FireShotmark(SBullet* bullet, const Fvector& vDir, const Fv CParticlesObject* ps = CParticlesObject::Create(ps_name, TRUE); ps->UpdateParent(pos, zero_vel); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); } if (bullet->flags.explosive && bStatic) diff --git a/src/xrGame/Level_network.cpp b/src/xrGame/Level_network.cpp index d75ab8511f9..0b336643478 100644 --- a/src/xrGame/Level_network.cpp +++ b/src/xrGame/Level_network.cpp @@ -104,7 +104,7 @@ void CLevel::remove_objects() client_spawn_manager().clear(); } - DestroyParticles(false); + g_pGamePersistent->destroy_particles(false); //. xr_delete (m_seniority_hierarchy_holder); //. m_seniority_hierarchy_holder = new CSeniorityHierarchyHolder(); diff --git a/src/xrGame/ai/monsters/burer/burer.cpp b/src/xrGame/ai/monsters/burer/burer.cpp index 20b635cf3f1..bd309137829 100644 --- a/src/xrGame/ai/monsters/burer/burer.cpp +++ b/src/xrGame/ai/monsters/burer/burer.cpp @@ -455,7 +455,7 @@ void CBurer::Hit(SHit* pHDS) CParticlesObject* ps = CParticlesObject::Create(particle_fire_shield, TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); } else if (!m_shield_active) { diff --git a/src/xrGame/game_cl_deathmatch.cpp b/src/xrGame/game_cl_deathmatch.cpp index 77a2d68f219..f58809216b1 100644 --- a/src/xrGame/game_cl_deathmatch.cpp +++ b/src/xrGame/game_cl_deathmatch.cpp @@ -983,7 +983,7 @@ void game_cl_Deathmatch::PlayParticleEffect(LPCSTR EffName, Fvector& pos) ps = CParticlesObject::Create(EffName, TRUE); ps->UpdateParent(M, Fvector().set(0.f, 0.f, 0.f)); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); } void game_cl_Deathmatch::OnSpawn(IGameObject* pObj) diff --git a/src/xrGame/physics_game.cpp b/src/xrGame/physics_game.cpp index 914285ca237..ca9ce08f101 100644 --- a/src/xrGame/physics_game.cpp +++ b/src/xrGame/physics_game.cpp @@ -59,7 +59,7 @@ class CPHParticlesPlayCall : public CPHAction pos.c.set(*((Fvector*)c.pos)); ps->UpdateParent(pos, zero_vel); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); }; virtual bool obsolete() const { return false; } }; diff --git a/src/xrGame/step_manager.cpp b/src/xrGame/step_manager.cpp index d5c04235386..3dcc3b7aeaf 100644 --- a/src/xrGame/step_manager.cpp +++ b/src/xrGame/step_manager.cpp @@ -219,7 +219,7 @@ void CStepManager::update(bool b_hud_view) pos.c.set(get_foot_position(ELegType(i))); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); - Level().ps_needtoplay.push_back(ps); + GamePersistent().ps_needtoplay.push_back(ps); } // Play Camera FXs From c3f6e83f6bc8c23e9463cd7c07a9ab5bf64843d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:40:58 +0000 Subject: [PATCH 067/497] build(deps): bump Externals/sse2neon from `232c221` to `1d79067` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `232c221` to `1d79067`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/232c22135ce5b0a953c4e8d3d2325cd27745f830...1d790675d58053e7eb8b83e7a579d2775e165bd7) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 232c22135ce..1d790675d58 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 232c22135ce5b0a953c4e8d3d2325cd27745f830 +Subproject commit 1d790675d58053e7eb8b83e7a579d2775e165bd7 From c0b50d3213fa1e893313b5e86bfb207fb79cbd93 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 23:47:36 +0500 Subject: [PATCH 068/497] xrEngine/pure.h: free memory when all objects are removed from registry This reproduces vanilla behaviour where .clear() was releasing the memory also --- src/xrEngine/pure.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/pure.h b/src/xrEngine/pure.h index 01adba69d05..a036ceb5634 100644 --- a/src/xrEngine/pure.h +++ b/src/xrEngine/pure.h @@ -119,7 +119,7 @@ class MessageRegistry messages.pop_back(); if (messages.empty()) - messages.clear(); + messages.shrink_to_fit(); changed = false; } From 3af174026bb9c22574daa3a89216e6df44386044 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Dec 2023 23:49:16 +0500 Subject: [PATCH 069/497] xrGame/GamePersistent.h|cpp: default-initialize variables and lighten the constructor --- src/xrGame/GamePersistent.cpp | 33 +++++---------------------------- src/xrGame/GamePersistent.h | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index b2300208b29..5d713e59e57 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -47,55 +47,32 @@ #include "xrEngine/xr_level_controller.h" -CGamePersistent::CGamePersistent(void) +CGamePersistent::CGamePersistent() { - m_bPickableDOF = false; m_game_params.m_e_game_type = eGameIDNoGame; - ambient_effect_next_time = 0; - ambient_effect_stop_time = 0; - ambient_particles = nullptr; - - ambient_effect_wind_start = 0.f; - ambient_effect_wind_in_time = 0.f; - ambient_effect_wind_end = 0.f; - ambient_effect_wind_out_time = 0.f; - ambient_effect_wind_on = false; ambient_sound_next_time.reserve(32); - m_pMainMenu = nullptr; - m_intro = nullptr; m_intro_event.bind(this, &CGamePersistent::start_logo_intro); -#ifdef DEBUG - m_frame_counter = 0; - m_last_stats_frame = u32(-2); -#endif - const bool bDemoMode = (0 != strstr(Core.Params, "-demomode ")); - if (bDemoMode) + if ((0 != strstr(Core.Params, "-demomode "))) { string256 fname; - LPCSTR name = strstr(Core.Params, "-demomode ") + 10; + cpcstr name = strstr(Core.Params, "-demomode ") + 10; sscanf(name, "%s", fname); R_ASSERT2(fname[0], "Missing filename for 'demomode'"); Msg("- playing in demo mode '%s'", fname); pDemoFile = FS.r_open(fname); Device.seqFrame.Add(this); eDemoStart = Engine.Event.Handler_Attach("GAME:demo", this); - uTime2Change = 0; - } - else - { - pDemoFile = NULL; - eDemoStart = NULL; } eQuickLoad = Engine.Event.Handler_Attach("Game:QuickLoad", this); - Fvector3* DofValue = Console->GetFVectorPtr("r2_dof"); + const Fvector3* DofValue = Console->GetFVectorPtr("r2_dof"); SetBaseDof(*DofValue); } -CGamePersistent::~CGamePersistent(void) +CGamePersistent::~CGamePersistent() { FS.r_close(pDemoFile); Device.seqFrame.Remove(this); diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 3e4f3d6aeb1..b2f3a8caed7 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -19,22 +19,22 @@ class CGamePersistent : public IGame_Persistent private: // ambient particles - CParticlesObject* ambient_particles; + CParticlesObject* ambient_particles{}; AssociativeVector ambient_sound_next_time; // max snd channels - u32 ambient_effect_next_time; - u32 ambient_effect_stop_time; + u32 ambient_effect_next_time{}; + u32 ambient_effect_stop_time{}; - float ambient_effect_wind_start; - float ambient_effect_wind_in_time; - float ambient_effect_wind_end; - float ambient_effect_wind_out_time; - bool ambient_effect_wind_on; + float ambient_effect_wind_start{}; + float ambient_effect_wind_in_time{}; + float ambient_effect_wind_end{}; + float ambient_effect_wind_out_time{}; + bool ambient_effect_wind_on{}; - bool m_bPickableDOF; + bool m_bPickableDOF{}; - AnselManager* ansel; + AnselManager* ansel{}; - CUISequencer* m_intro; + CUISequencer* m_intro{}; EVENT eQuickLoad; Fvector m_dof[4]; // 0-dest 1-current 2-from 3-original @@ -50,17 +50,17 @@ class CGamePersistent : public IGame_Persistent void update_game_intro(); #ifdef DEBUG - u32 m_frame_counter; - u32 m_last_stats_frame; + u32 m_frame_counter{}; + u32 m_last_stats_frame{ u32(-2) }; #endif void WeathersUpdate(); void UpdateDof(); public: - IReader* pDemoFile; - u32 uTime2Change; - EVENT eDemoStart; + IReader* pDemoFile{}; + u32 uTime2Change{}; + EVENT eDemoStart{}; CGamePersistent(); virtual ~CGamePersistent(); From 0e4f0bf5361c2b9ffd32fcda1d75591ea3b32b34 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 19 Dec 2023 22:35:03 +0500 Subject: [PATCH 070/497] xrEngine/x_ray.h|cpp: moved Discord update procedure to a dedicated function --- src/xrEngine/x_ray.cpp | 25 +++++++++++++------------ src/xrEngine/x_ray.h | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index bbc8d83bd62..fe9e44ed9a5 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -481,10 +481,7 @@ int CApplication::Run() Device.ProcessFrame(); -#ifdef USE_DISCORD_INTEGRATION - if (m_discord_core) - m_discord_core->RunCallbacks(); -#endif + UpdateDiscordStatus(); } // while (!SDL_QuitRequested()) Device.Shutdown(); @@ -549,15 +546,8 @@ void CApplication::SplashProc() const auto next = m_surfaces[m_current_surface_idx++]; // It's important to have postfix increment! SDL_BlitSurface(next, nullptr, current, nullptr); SDL_UpdateWindowSurface(m_window); - -#ifdef USE_DISCORD_INTEGRATION - if (m_discord_core) - { - std::lock_guard guard{ m_discord_lock }; - m_discord_core->RunCallbacks(); - } -#endif } + UpdateDiscordStatus(); } for (SDL_Surface* surface : m_surfaces) @@ -582,3 +572,14 @@ void CApplication::HideSplash() SwitchToThread(); } } + +void CApplication::UpdateDiscordStatus() +{ +#ifdef USE_DISCORD_INTEGRATION + if (!m_discord_core) + return; + + std::lock_guard guard{ m_discord_lock }; + m_discord_core->RunCallbacks(); +#endif +} diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 4a4012d2f7f..cac96af80b0 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -33,6 +33,8 @@ class ENGINE_API CApplication final void ShowSplash(bool topmost); void HideSplash(); + void UpdateDiscordStatus(); + public: // Other CApplication(pcstr commandLine); From 0c99936a6976e6517dd66adceea15867cb4bf90f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Dec 2023 00:31:54 +0500 Subject: [PATCH 071/497] Discord: set logo during engine start --- src/xrEngine/x_ray.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index fe9e44ed9a5..85f5e3e77b9 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -246,6 +246,8 @@ CApplication::CApplication(pcstr commandLine) discord::Activity activity{}; activity.SetType(discord::ActivityType::Playing); activity.SetApplicationId(DISCORD_APP_ID); + activity.SetState("Starting engine..."); + activity.GetAssets().SetLargeImage("logo"); if (m_discord_core) { std::lock_guard guard{ m_discord_lock }; @@ -322,7 +324,7 @@ CApplication::CApplication(pcstr commandLine) Console->OnDeviceInitialize(); #ifdef USE_DISCORD_INTEGRATION const std::locale locale(""); - activity.SetDetails(StringToUTF8(Core.ApplicationTitle, locale).c_str()); + activity.SetState(StringToUTF8(Core.ApplicationTitle, locale).c_str()); if (m_discord_core) { std::lock_guard guard{ m_discord_lock }; From 386735111399447c0ef898df0bb661a7dc01fa50 Mon Sep 17 00:00:00 2001 From: Masterkatze Date: Sat, 23 Dec 2023 05:28:25 +0300 Subject: [PATCH 072/497] Fix aarch64 build --- src/xrCore/CMakeLists.txt | 1 + src/xrParticles/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 4734307cec8..8c34504a9bd 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -437,6 +437,7 @@ target_include_directories(xrCore PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals" "${CMAKE_SOURCE_DIR}/Externals/mimalloc/include" ) diff --git a/src/xrParticles/CMakeLists.txt b/src/xrParticles/CMakeLists.txt index 84177fd879f..4863ded0863 100644 --- a/src/xrParticles/CMakeLists.txt +++ b/src/xrParticles/CMakeLists.txt @@ -31,6 +31,7 @@ target_sources_grouped( target_include_directories(xrParticles PRIVATE "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/Externals" ) target_link_libraries(xrParticles From 27da7a11516962b98d5b4d3412ff2e8baa27f15e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:23:27 +0000 Subject: [PATCH 073/497] build(deps): bump Externals/sse2neon from `1d79067` to `01cba29` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `1d79067` to `01cba29`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/1d790675d58053e7eb8b83e7a579d2775e165bd7...01cba29951cdbd681102f33dab0767168eed73fd) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 1d790675d58..01cba29951c 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 1d790675d58053e7eb8b83e7a579d2775e165bd7 +Subproject commit 01cba29951cdbd681102f33dab0767168eed73fd From 1cd834d352c0ae41254d0b5d7ab99c79d7c31a76 Mon Sep 17 00:00:00 2001 From: Roman Zavalov Date: Thu, 28 Dec 2023 17:44:20 +0300 Subject: [PATCH 074/497] Fixed PIX_EVENT on non-msvc compilers. (#1574) --- src/Layers/xrRender/Debug/dxPixEventWrapper.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Layers/xrRender/Debug/dxPixEventWrapper.h b/src/Layers/xrRender/Debug/dxPixEventWrapper.h index dc1e4974e83..87d21c8693c 100644 --- a/src/Layers/xrRender/Debug/dxPixEventWrapper.h +++ b/src/Layers/xrRender/Debug/dxPixEventWrapper.h @@ -5,8 +5,8 @@ # define PIX_EVENT_CTX(C,Name) do { } while (false) #else #if defined(USE_DX9) || defined(USE_DX11) -# define PIX_EVENT(Name) dxPixEventWrapper pixEvent##Name(RCache,L#Name) -# define PIX_EVENT_CTX(C,Name) dxPixEventWrapper pixEvent##Name(C,L#Name) +# define PIX_EVENT(Name) dxPixEventWrapper pixEvent##Name(RCache,L ## #Name) +# define PIX_EVENT_CTX(C,Name) dxPixEventWrapper pixEvent##Name(C,L ## #Name) class dxPixEventWrapper { From 602c38043162db7dac8e3fa7ef2fd4dbacd32bfe Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 28 Dec 2023 17:45:35 +0300 Subject: [PATCH 075/497] Update read window title from configs/openxray.ltx (#1559) --- src/xrEngine/Device_Initialize.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index 9490aeb53c1..7fbbb007c73 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -40,8 +40,8 @@ void CRenderDevice::Initialize() title = "S.T.A.L.K.E.R.: Clear Sky"; } - title = READ_IF_EXISTS(pSettingsOpenXRay, r_string, - "window", "title", title); + title = READ_IF_EXISTS(pSettingsOpenXRay, r_string_wb, + "window", "title", title).c_str(); xr_strcpy(Core.ApplicationTitle, title); From 77f92ae537ee3b81073d0eb828e494d2d065f3e9 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Thu, 28 Dec 2023 16:04:16 +0100 Subject: [PATCH 076/497] xrGame: Fix buffer overflow in `ParseControlString` (#1556) Co-authored-by: Xottab_DUTY --- src/xrGame/console_commands_mp.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/xrGame/console_commands_mp.cpp b/src/xrGame/console_commands_mp.cpp index 4114ff7e78b..66ec198f0bc 100644 --- a/src/xrGame/console_commands_mp.cpp +++ b/src/xrGame/console_commands_mp.cpp @@ -598,12 +598,10 @@ class DemoPlayControlArgParser shared_str m_action_param; bool ParseControlString(LPCSTR args_string) { - string16 action_name; - action_name[0] = 0; - string32 param_name; - param_name[0] = 0; + string32 action_name{}; + string64 param_name{}; - sscanf(args_string, "%16s %32s", action_name, param_name); + sscanf(args_string, "%31s %63s", action_name, param_name); // 31/63 instead of 32/64 because we reserve space for null character m_action_param = param_name; if (!xr_strcmp(action_name, "roundstart")) From 46b11b5ff80b23106448902b8948fcb5c4652525 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 28 Dec 2023 20:15:14 +0500 Subject: [PATCH 077/497] GitHub: removed Travis CI integration It doesn't work for a while, and it's really buggy, so not worth the efforts. --- .travis.yml | 54 ----------------------------------------------------- README.md | 1 - 2 files changed, 55 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b3e98241e30..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -language: cpp -cache: ccache - -branches: - except: - - /^dependabot\/.*$/ - -os: linux -dist: focal -virt: lxd -group: edge - -arch: - - arm64 - # XXX: ppc64le and s390x are not supported by LuaJIT - #- ppc64le - #- s390x - -compiler: - - gcc - #- clang - -addons: - apt: - update: true - packages: - - [libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev libopenal-dev libogg-dev libtheora-dev libvorbis-dev] - -env: - - CONFIGURATION: Debug - - CONFIGURATION: Release - -before_script: - - if [ $TRAVIS_CPU_ARCH == arm64 ]; then - export core_count=2 && echo core_count = $core_count; - else - export core_count=$(nproc || echo 4) && echo core_count = $core_count; - fi - - git submodule deinit Externals/cryptopp - - CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=$CONFIGURATION - -script: -- if [ $TRAVIS_OS_NAME == linux ]; then - cd build; - make -j $core_count package; - file openxray_1.6.02_*.deb; - fi - -deploy: - provider: releases - token: - secure: kGVniXDR926BfVcA97y25BzALbijvgboBsozZzY9yc8RPz15Q4YG474h7vl14/J1 - file: ./*.deb - draft: true diff --git a/README.md b/README.md index 617938eae2e..c4eaf564f4f 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ Make sure to visit our [wiki](https://github.com/OpenXRay/xray-16/wiki). |---|---|---|---|---|---| |AppVeyor|Windows, Ubuntu|MSVC, GCC|Debug, Mixed, Release, Release Master Gold|x64, x86|[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/16mp39v0d7fts6yf?svg=true)](https://ci.appveyor.com/project/OpenXRay/xray-16)| |GitHub Actions|Windows, Ubuntu, Alpine Linux, macOS|MSVC, GCC, Clang|Debug, Mixed, Release, Release Master Gold|x64, x86|[![GitHub Actions Build Status](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml/badge.svg)](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml) -|Travis|Ubuntu|GCC|Debug, Release|ARM64|[![Travis Build Status](https://api.travis-ci.com/OpenXRay/xray-16.svg?branch=dev)](https://app.travis-ci.com/github/OpenXRay/xray-16)| ## Contributing All contributions are more than welcomed. There are several ways how you can contribute: From 094d960a88f65a145f287728339d5420f5049b95 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 30 Dec 2023 04:43:30 +0500 Subject: [PATCH 078/497] Fix mouse doesn't hide on engine start --- src/xrEngine/x_ray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 85f5e3e77b9..be3222cb41d 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -417,8 +417,8 @@ int CApplication::Run() #endif // Main cycle - Device.Run(); HideSplash(); + Device.Run(); while (!SDL_QuitRequested()) // SDL_PumpEvents is here { From ccef7d2a4a91703dc8e27a044fbb3867509b994b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 12:22:20 +0000 Subject: [PATCH 079/497] build(deps): bump Externals/sse2neon from `01cba29` to `25e2a60` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `01cba29` to `25e2a60`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/01cba29951cdbd681102f33dab0767168eed73fd...25e2a601a06cbd97538bbe422a46bba3655763b9) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 01cba29951c..25e2a601a06 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 01cba29951cdbd681102f33dab0767168eed73fd +Subproject commit 25e2a601a06cbd97538bbe422a46bba3655763b9 From 2872d68cb1cdf077af023ad9c5462cda7eeb60c3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 1 Jan 2024 10:27:44 +0500 Subject: [PATCH 080/497] CMake: link to Ogg target instead of using OGG_* variables directly Fix find modules like #1206 --- cmake/FindOgg.cmake | 3 +-- cmake/FindVorbis.cmake | 2 +- src/xrEngine/CMakeLists.txt | 2 +- src/xrSound/CMakeLists.txt | 5 +---- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cmake/FindOgg.cmake b/cmake/FindOgg.cmake index eab7f6c1c82..804021ffd05 100644 --- a/cmake/FindOgg.cmake +++ b/cmake/FindOgg.cmake @@ -28,7 +28,6 @@ # A user may set ``OGGDIR`` environment to a ogg installation root # to tell this module where to look. - set(_OGG_SEARCHES) # Search OGGDIR first when is set. @@ -47,7 +46,7 @@ set(OGG_NAMES ogg libogg) set(OGG_NAMES_DEBUG oggd ogg_D oggD ogg_D) foreach(search ${_OGG_SEARCHES}) - find_path(OGG_INCLUDE_DIR NAMES ogg.h ${${search}} PATH_SUFFIXES ogg) + find_path(OGG_INCLUDE_DIR NAMES ogg/ogg.h ${${search}} PATH_SUFFIXES include) endforeach() # Allow OGG_LIBRARY to be set manually, as the location of the diff --git a/cmake/FindVorbis.cmake b/cmake/FindVorbis.cmake index 7b047f22171..a7b974d9729 100644 --- a/cmake/FindVorbis.cmake +++ b/cmake/FindVorbis.cmake @@ -65,7 +65,7 @@ set(VORBISFILE_NAMES vorbisfile libvorbisfile) set(VORBISFILE_NAMES_DEBUG vorbisfiled vorbisfile_d vorbisfileD vorbisfile_D) foreach(search ${_VORBIS_SEARCHES}) - find_path(VORBIS_INCLUDE_DIR NAMES codec.h ${${search}} PATH_SUFFIXES vorbis) + find_path(VORBIS_INCLUDE_DIR NAMES vorbis/codec.h ${${search}} PATH_SUFFIXES include) endforeach() if(${VORBIS_INCLUDE_DIR} MATCHES ".framework") diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index ac06fe221cb..7625340959c 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -438,7 +438,7 @@ target_link_libraries(xrEngine xrNetServer xrImGui ${OPENAL_LIBRARY} - ${OGG_LIBRARIES} + Ogg::Ogg Theora::Theora ) diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 53cb179226e..2250de18246 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -132,10 +132,7 @@ target_include_directories(xrSound PRIVATE "${CMAKE_SOURCE_DIR}/src" "${CMAKE_SOURCE_DIR}/src/xrEngine" - "${CMAKE_SOURCE_DIR}/Externals/libvorbis/include" - "${CMAKE_SOURCE_DIR}/Externals/libogg/include" "${OPENAL_INCLUDE_DIR}" - "${OGG_INCLUDE_DIRS}" ) target_link_libraries(xrSound @@ -146,7 +143,7 @@ target_link_libraries(xrSound xrCDB xrMaterialSystem ${OPENAL_LIBRARY} - ${OGG_LIBRARIES} + Ogg::Ogg Vorbis::Vorbis Vorbis::VorbisFile ) From 466967061bb501249306ec7fa9912a21c31fb78a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 03:23:08 +0500 Subject: [PATCH 081/497] cmake/FindLZO.cmake: removed /sw and /opt/local search paths According to https://github.com/Kitware/CMake/commit/eea9eda834466272b42f694a14d5d5f3d1975ec2 --- cmake/FindLZO.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/FindLZO.cmake b/cmake/FindLZO.cmake index c2659ffaa7b..badf5c0e81c 100644 --- a/cmake/FindLZO.cmake +++ b/cmake/FindLZO.cmake @@ -31,8 +31,6 @@ endif() set(_lzo_SEARCH_DIRS ${LZO_ROOT_DIR} /usr/local - /sw # Fink - /opt/local # DarwinPorts ) find_path(LZO_INCLUDE_DIR lzo/lzo1x.h From 1687006ab2f7aba92a5d1c695ae221b49b0f819e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 1 Jan 2024 03:18:24 +0500 Subject: [PATCH 082/497] GitHub Actions: removed 'build-' prefix from Build workflow jobs ids --- .github/workflows/cibuild.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index a03b5a26420..0df4c18f9ae 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - build-windows: + windows: name: Windows ${{ matrix.Configuration }} ${{ matrix.Platform }} (msvc) runs-on: windows-latest strategy: @@ -67,7 +67,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload --clobber latest-nightly (get-item res/*.*.7z) - build-ubuntu: + ubuntu: name: Ubuntu ${{ matrix.Configuration }} ${{ matrix.Platform }} (${{ matrix.CC }}) runs-on: ubuntu-latest strategy: @@ -132,7 +132,7 @@ jobs: name: openxray_1.6.02_${{ matrix.Configuration }}_${{ matrix.Platform }}_(github-${{ matrix.CC }}-${{ github.run_number }}).deb path: build/openxray_1.6.02_*.deb - build-alpine: + alpine: name: Alpine ${{ matrix.Configuration }} ${{ matrix.Platform }} (gcc) runs-on: ubuntu-latest strategy: @@ -171,7 +171,7 @@ jobs: shell: alpine.sh {0} run: cmake --build build --config ${{ matrix.Configuration }} --parallel $(nproc || echo 4) - build-macos: + macos: name: macOS ${{ matrix.Configuration }} ${{ matrix.Platform }} runs-on: macos-latest strategy: From 95276cd01f03e162c078da6ead6f5cddad3cc3d4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 1 Jan 2024 08:07:12 +0500 Subject: [PATCH 083/497] GitHub Actions: removed Crypto++ deinitialization step Crypto++ is disabled on Linux anyway --- .github/workflows/cibuild.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 0df4c18f9ae..6af14448d71 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -87,9 +87,6 @@ jobs: with: submodules: recursive - - name: Deinit Crypto++ - run: git submodule deinit Externals/cryptopp - - name: Install packages run: | sudo apt-get update -qq @@ -146,10 +143,6 @@ jobs: with: submodules: recursive - - name: Deinit Crypto++ - run: | - git submodule deinit Externals/cryptopp - - name: Install latest stable Alpine Linux uses: jirutka/setup-alpine@master with: @@ -184,9 +177,6 @@ jobs: with: submodules: recursive - - name: Deinit Crypto++ - run: git submodule deinit Externals/cryptopp - - name: Install packages run: | brew update From 9c1cb130a025db21d5472973edc956d55db3434a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 1 Jan 2024 03:20:39 +0500 Subject: [PATCH 084/497] GitHub Actions: use one job for both Ubuntu and Linux builds --- .github/workflows/cibuild.yml | 102 ++++++++++++---------------------- 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 6af14448d71..9e6da510065 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -67,57 +67,62 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload --clobber latest-nightly (get-item res/*.*.7z) - ubuntu: - name: Ubuntu ${{ matrix.Configuration }} ${{ matrix.Platform }} (${{ matrix.CC }}) + linux: + name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc || 'gcc' }}) runs-on: ubuntu-latest + + defaults: + run: + shell: ${{ matrix.platform.shell || 'bash -e {0}' }} + + env: + CC: ${{ matrix.platform.cc || 'gcc' }} + CXX: ${{ matrix.platform.cxx || 'g++' }} + CFLAGS: "-w" + CXXFLAGS: "-w" + strategy: fail-fast: false matrix: - Configuration: [Debug, Release] - Platform: [x64] - CC: [gcc, clang] - include: - - CC: gcc - CXX: g++ - - CC: clang - CXX: clang++ + platform: + - { name: Ubuntu, arch: x86_64, cc: gcc, cxx: g++, } + - { name: Ubuntu, arch: x86_64, cc: clang, cxx: clang++, } + - { name: Alpine, arch: x86_64, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + - { name: Alpine, arch: x86, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + + configuration: [Debug, Release] steps: - - uses: actions/checkout@main + - name: Install latest stable Alpine Linux + if: ${{ matrix.platform.name == 'Alpine' }} + uses: jirutka/setup-alpine@master with: - submodules: recursive + arch: ${{ matrix.platform.arch }} + branch: 'latest-stable' + packages: build-base cmake git mold sdl2-dev glew-dev lzo-dev libjpeg-turbo-dev openal-soft-dev libogg-dev libtheora-dev libvorbis-dev - - name: Install packages + - name: Install Ubuntu packages + if: ${{ matrix.platform.name == 'Ubuntu' }} run: | sudo apt-get update -qq - sudo apt-get install -qq -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev && - sudo apt-get install -qq -y libopenal-dev libogg-dev libtheora-dev libvorbis-dev + sudo apt-get install -qq -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev libopenal-dev libogg-dev libtheora-dev libvorbis-dev - - name: Install Clang - if: ${{ matrix.CC == 'clang' }} - uses: egor-tensin/setup-clang@master + - uses: actions/checkout@main + with: + submodules: recursive - name: Run CMake - env: - CC: ${{ matrix.CC }} - CXX: ${{ matrix.CXX }} - run: CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} -DCMAKE_UNITY_BUILD=ON ${{ matrix.platform.flags }} - name: Run CMake Build id: cmake-build - env: - CC: ${{ matrix.CC }} - CXX: ${{ matrix.CXX }} - run: cmake --build build --config ${{ matrix.Configuration }} --parallel $(nproc || echo 4) + run: cmake --build build --config ${{ matrix.configuration }} --parallel $(nproc || echo 4) - name: Make package - if: ${{ steps.cmake-build.outcome == 'success' }} + if: ${{ steps.cmake-build.outcome == 'success' && matrix.platform.name == 'Ubuntu' }} id: make-package working-directory: build #continue-on-error: true - env: - CC: ${{ matrix.CC }} - CXX: ${{ matrix.CXX }} run: | make -j $(nproc || echo 4) package file openxray_1.6.02_*.deb @@ -126,44 +131,9 @@ jobs: if: ${{ steps.make-package.outcome == 'success' }} uses: actions/upload-artifact@main with: - name: openxray_1.6.02_${{ matrix.Configuration }}_${{ matrix.Platform }}_(github-${{ matrix.CC }}-${{ github.run_number }}).deb + name: openxray_1.6.02_${{ matrix.configuration }}_${{ matrix.platform.arch }}_(github-${{ env.CC }}-${{ github.run_number }}).deb path: build/openxray_1.6.02_*.deb - alpine: - name: Alpine ${{ matrix.Configuration }} ${{ matrix.Platform }} (gcc) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - Configuration: [Debug, Release] - Platform: [x86_64, x86] - - steps: - - uses: actions/checkout@main - with: - submodules: recursive - - - name: Install latest stable Alpine Linux - uses: jirutka/setup-alpine@master - with: - arch: ${{ matrix.Platform }} - branch: 'latest-stable' - packages: build-base cmake mold sdl2-dev glew-dev lzo-dev libjpeg-turbo-dev openal-soft-dev libogg-dev libtheora-dev libvorbis-dev - - - name: Run CMake x64 - if: ${{ matrix.Platform == 'x86_64' }} - shell: alpine.sh {0} - run: CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON -DXRAY_LINKER=mold - - - name: Run CMake x86 - if: ${{ matrix.Platform == 'x86' }} - shell: alpine.sh {0} - run: CFLAGS="-m32 -w" CXXFLAGS="-m32 -w" cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_ASM_FLAGS=-m32 -DCMAKE_UNITY_BUILD=ON -DXRAY_LINKER=mold - - - name: Run CMake Build - shell: alpine.sh {0} - run: cmake --build build --config ${{ matrix.Configuration }} --parallel $(nproc || echo 4) - macos: name: macOS ${{ matrix.Configuration }} ${{ matrix.Platform }} runs-on: macos-latest From 281980ccf26cd2ccada949dd0dc031351f42dab3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 09:32:02 +0500 Subject: [PATCH 085/497] xrRender: use RenderDoc API on non Master Gold builds and only on Windows/Linux/macOS --- src/Layers/xrRender/D3DXRenderBase.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Layers/xrRender/D3DXRenderBase.cpp b/src/Layers/xrRender/D3DXRenderBase.cpp index 0680f4cc8c8..59627d0da57 100644 --- a/src/Layers/xrRender/D3DXRenderBase.cpp +++ b/src/Layers/xrRender/D3DXRenderBase.cpp @@ -6,7 +6,13 @@ #include "xrEngine/GameFont.h" #include "xrEngine/PerformanceAlert.hpp" -#if DEBUG +#if defined(XR_PLATFORM_WINDOWS) || defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_APPLE) +# ifndef MASTER_GOLD +# define USE_RENDERDOC +# endif +#endif + +#ifdef USE_RENDERDOC #include RENDERDOC_API_1_0_0* g_renderdoc_api; #endif @@ -151,7 +157,7 @@ void D3DXRenderBase::OnDeviceCreate(const char* shName) void D3DXRenderBase::Create(SDL_Window* hWnd, u32& dwWidth, u32& dwHeight, float& fWidth_2, float& fHeight_2) { -#if defined(DEBUG) && defined(USE_DX11) +#if defined(USE_RENDERDOC) && defined(USE_DX11) if (!g_renderdoc_api) { HMODULE hModule = GetModuleHandleA("renderdoc.dll"); From 8803cb977fc19fbeba724a130609202c925e1b2a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 11:37:59 +0500 Subject: [PATCH 086/497] Common/Platform.hpp: expand XR_PLATFORM_BSD to detect OpenBSD/NetBSD/DragonFlyBSD --- src/Common/Platform.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common/Platform.hpp b/src/Common/Platform.hpp index 8caddcab7c9..dde3a96b556 100644 --- a/src/Common/Platform.hpp +++ b/src/Common/Platform.hpp @@ -6,7 +6,7 @@ #elif defined(__linux__) # define XR_PLATFORM_LINUX # define _XRAY_PLATFORM_MARKER "Linux" -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) # define XR_PLATFORM_BSD # define _XRAY_PLATFORM_MARKER "BSD" #elif defined(__APPLE__) From 2fb0bfdf28cd4dd04f3fe0518ac638ccb1934445 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 1 Jan 2024 05:45:09 +0500 Subject: [PATCH 087/497] GitHub Actions: add FreeBSD build Added OpenBSD and NetBSD build stubs --- .github/workflows/cibuild.yml | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 9e6da510065..3d024b02290 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -157,3 +157,58 @@ jobs: - name: Run CMake Build run: cmake --build build --config ${{ matrix.Configuration }} --parallel $(sysctl -n hw.ncpu || echo 4) + + bsd: + name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} + runs-on: macos-latest + env: + CFLAGS: "-w" + CXXFLAGS: "-w" + strategy: + fail-fast: false + matrix: + platform: + - { name: FreeBSD, os: freebsd, os-version: 13.2, arch: x86_64, + install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" + } + #- { name: OpenBSD, os: openbsd, os-version: 7.4, arch: x86_64, + # install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", + # } + #- { name: NetBSD, os: netbsd, os-version: 9.3, arch: x86_64, + # install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis && export CC=gcc-13 && export CXX=g++-13", + # } + configuration: [Debug, Release] + + steps: + - uses: actions/checkout@main + with: + submodules: recursive + + - name: Setup ${{ matrix.platform.name }} and packages + uses: cross-platform-actions/action@v0.22.0 + with: + operating_system: ${{ matrix.platform.os }} + architecture: ${{ matrix.platform.arch }} + version: ${{ matrix.platform.os-version }} + shutdown_vm: false + sync_files: runner-to-vm + run: ${{ matrix.platform.install-cmd }} + + - name: Run CMake + uses: cross-platform-actions/action@v0.22.0 + with: + operating_system: ${{ matrix.platform.os }} + architecture: ${{ matrix.platform.arch }} + version: ${{ matrix.platform.os-version }} + shutdown_vm: false + sync_files: false + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON + + - name: Run CMake Build + uses: cross-platform-actions/action@v0.22.0 + with: + operating_system: ${{ matrix.platform.os }} + architecture: ${{ matrix.platform.arch }} + version: ${{ matrix.platform.os-version }} + sync_files: vm-to-runner + run: cmake --build build --config ${{ matrix.Configuration }} --parallel 3 From d6d814cd2b3f7e17407a42834addf76cd24f37d4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 09:36:26 +0500 Subject: [PATCH 088/497] GitHub Actions: added Haiku and ARM64/PPC64LE Ubuntu builds stubs --- .github/workflows/cibuild.yml | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 3d024b02290..67cdd381fb1 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -71,13 +71,13 @@ jobs: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc || 'gcc' }}) runs-on: ubuntu-latest + container: ${{ matrix.platform.container || '' }} + defaults: run: shell: ${{ matrix.platform.shell || 'bash -e {0}' }} env: - CC: ${{ matrix.platform.cc || 'gcc' }} - CXX: ${{ matrix.platform.cxx || 'g++' }} CFLAGS: "-w" CXXFLAGS: "-w" @@ -85,10 +85,13 @@ jobs: fail-fast: false matrix: platform: - - { name: Ubuntu, arch: x86_64, cc: gcc, cxx: g++, } - - { name: Ubuntu, arch: x86_64, cc: clang, cxx: clang++, } + - { name: Ubuntu, arch: amd64, cc: gcc, cxx: g++, } + - { name: Ubuntu, arch: amd64, cc: clang, cxx: clang++, } + #- { name: Ubuntu, arch: arm64, container: 'dockcross/linux-arm64', } + #- { name: Ubuntu, arch: ppc64el, container: 'dockcross/linux-ppc64le:latest', } - { name: Alpine, arch: x86_64, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } - { name: Alpine, arch: x86, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + #- { name: Haiku, arch: x86_64, container: 'haiku/cross-compiler:x86_64-r1beta4', cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, } configuration: [Debug, Release] @@ -104,8 +107,23 @@ jobs: - name: Install Ubuntu packages if: ${{ matrix.platform.name == 'Ubuntu' }} run: | + sudo dpkg --add-architecture ${{ matrix.platform.arch }} sudo apt-get update -qq - sudo apt-get install -qq -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev libopenal-dev libogg-dev libtheora-dev libvorbis-dev + sudo apt-get install -qq -y \ + libsdl2-dev:${{ matrix.platform.arch }} \ + libglew-dev:${{ matrix.platform.arch }} \ + liblzo2-dev:${{ matrix.platform.arch }} \ + libjpeg-dev:${{ matrix.platform.arch }} \ + libopenal-dev:${{ matrix.platform.arch }} \ + libogg-dev:${{ matrix.platform.arch }} \ + libtheora-dev:${{ matrix.platform.arch }} \ + libvorbis-dev:${{ matrix.platform.arch }} + + - name: Set environment variables + if: ${{ matrix.platform.cc != '' }} + run: | + echo "CC=${{ matrix.platform.cc }}" >> $GITHUB_ENV + echo "CXX=${{ matrix.platform.cxx }}" >> $GITHUB_ENV - uses: actions/checkout@main with: @@ -131,7 +149,7 @@ jobs: if: ${{ steps.make-package.outcome == 'success' }} uses: actions/upload-artifact@main with: - name: openxray_1.6.02_${{ matrix.configuration }}_${{ matrix.platform.arch }}_(github-${{ env.CC }}-${{ github.run_number }}).deb + name: openxray_1.6.02_${{ matrix.configuration }}_${{ matrix.platform.arch }}_(github-${{ matrix.platform.cc }}-${{ github.run_number }}).deb path: build/openxray_1.6.02_*.deb macos: From e324b1d6e0673263a1127df532e7d6d69d6eb8da Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 12:44:38 +0500 Subject: [PATCH 089/497] Removed Travis CI leftovers --- src/xrCore/CMakeLists.txt | 4 ---- src/xrCore/xrCore.cpp | 5 ----- 2 files changed, 9 deletions(-) diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 8c34504a9bd..f6df1070603 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -459,10 +459,6 @@ target_compile_definitions(xrCore PRIVATE XRCORE_EXPORTS CI=$ENV{CI} - TRAVIS=$ENV{TRAVIS} - TRAVIS_BUILD_ID=$ENV{TRAVIS_BUILD_ID} - TRAVIS_BUILD_NUMBER=$ENV{TRAVIS_BUILD_NUMBER} - TRAVIS_REPO_SLUG=$ENV{TRAVIS_REPO_SLUG} GITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} GITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} GITHUB_RUN_NUMBER=$ENV{GITHUB_RUN_NUMBER} diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index bf038912790..2f8161c289d 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -120,11 +120,6 @@ void xrCore::PrintBuildInfo() buildUniqueId = MACRO_TO_STRING(APPVEYOR_BUILD_ID); buildId = MACRO_TO_STRING(APPVEYOR_BUILD_VERSION); builder = MACRO_TO_STRING(APPVEYOR_ACCOUNT_NAME); -# elif defined(TRAVIS) - name = "Travis"; - buildUniqueId = MACRO_TO_STRING(TRAVIS_BUILD_ID); - buildId = MACRO_TO_STRING(TRAVIS_BUILD_NUMBER); - builder = MACRO_TO_STRING(TRAVIS_REPO_SLUG); # elif defined(GITHUB_ACTIONS) name = "GitHub Actions"; buildUniqueId = MACRO_TO_STRING(GITHUB_RUN_ID); From 00b865aac173827b8ed35249e1b0786215656ca7 Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Wed, 3 Jan 2024 13:52:51 +0500 Subject: [PATCH 090/497] GitHub Actions: stop *BSD builds after 30 minutes It usually takes 10-20 minutes to build, anything longer that that is a VM stall. --- .github/workflows/cibuild.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 67cdd381fb1..399c21eed7d 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -179,6 +179,7 @@ jobs: bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} runs-on: macos-latest + timeout-minutes: 30 env: CFLAGS: "-w" CXXFLAGS: "-w" From f09e27addadc397f992a55113b61b75ce6ea691d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:31:46 +0500 Subject: [PATCH 091/497] Use C++ types in log functions to make it more portable uint64_t and size_t are using different underlying types on different platforms, and compiler even fails to determine which overload to call on Apple, *BSD platforms. --- src/xrCore/log.cpp | 41 ++++++++++++++++++++++++++++++------ src/xrCore/log.h | 20 ++++++------------ src/xrGame/debug_text_tree.h | 22 ++++++++----------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/xrCore/log.cpp b/src/xrCore/log.cpp index 4482ba9617c..9d515ccedbd 100644 --- a/src/xrCore/log.cpp +++ b/src/xrCore/log.cpp @@ -131,30 +131,57 @@ void Log(const char* msg, const char* dop) Log(buf); } -void Log(const char* msg, u32 dop) +void Log(const char* msg, int dop) +{ + const u32 buffer_size = (xr_strlen(msg) + 1 + 11 + 1) * sizeof(char); + pstr buf = static_cast(xr_alloca(buffer_size)); + + xr_sprintf(buf, buffer_size, "%s %i", msg, dop); + Log(buf); +} + +void Log(const char* msg, unsigned int dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 10 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); - xr_sprintf(buf, buffer_size, "%s %d", msg, dop); + xr_sprintf(buf, buffer_size, "%s %u", msg, dop); Log(buf); } -void Log(const char* msg, u64 dop) +void Log(const char* msg, long dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); - xr_sprintf(buf, buffer_size, "%s %d", msg, dop); + xr_sprintf(buf, buffer_size, "%s %li", msg, dop); Log(buf); } -void Log(const char* msg, int dop) +void Log(const char* msg, unsigned long dop) { - const u32 buffer_size = (xr_strlen(msg) + 1 + 11 + 1) * sizeof(char); + const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); - xr_sprintf(buf, buffer_size, "%s %i", msg, dop); + xr_sprintf(buf, buffer_size, "%s %lu", msg, dop); + Log(buf); +} + +void Log(const char* msg, long long dop) +{ + const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); + pstr buf = static_cast(xr_alloca(buffer_size)); + + xr_sprintf(buf, buffer_size, "%s %lli", msg, dop); + Log(buf); +} + +void Log(const char* msg, unsigned long long dop) +{ + const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); + pstr buf = static_cast(xr_alloca(buffer_size)); + + xr_sprintf(buf, buffer_size, "%s %llu", msg, dop); Log(buf); } diff --git a/src/xrCore/log.h b/src/xrCore/log.h index c378bcd9ea7..5465854af93 100644 --- a/src/xrCore/log.h +++ b/src/xrCore/log.h @@ -11,26 +11,20 @@ template struct _matrix; typedef _matrix Fmatrix; #define VPUSH(a) ((a).x), ((a).y), ((a).z) void XRCORE_API __cdecl Msg(LPCSTR format, ...); -void XRCORE_API Log(LPCSTR msg); + void XRCORE_API Log(LPCSTR msg); void XRCORE_API Log(LPCSTR msg, LPCSTR dop); -void XRCORE_API Log(LPCSTR msg, u32 dop); -void XRCORE_API Log(LPCSTR msg, u64 dop); void XRCORE_API Log(LPCSTR msg, int dop); +void XRCORE_API Log(LPCSTR msg, unsigned int dop); +void XRCORE_API Log(LPCSTR msg, long dop); +void XRCORE_API Log(LPCSTR msg, unsigned long dop); +void XRCORE_API Log(LPCSTR msg, long long dop); +void XRCORE_API Log(LPCSTR msg, unsigned long long dop); void XRCORE_API Log(LPCSTR msg, float dop); void XRCORE_API Log(LPCSTR msg, const Fvector& dop); void XRCORE_API Log(LPCSTR msg, const Fmatrix& dop); -void XRCORE_API LogWinErr(LPCSTR msg, long err_code); -#ifdef XR_PLATFORM_APPLE -ICF void Log(pcstr msg, size_t dop) -{ - if constexpr (sizeof(size_t) == sizeof(u32)) - return Log(msg, static_cast(dop)); - else - return Log(msg, static_cast(dop)); -} -#endif +void XRCORE_API LogWinErr(LPCSTR msg, long err_code); struct LogCallback { diff --git a/src/xrGame/debug_text_tree.h b/src/xrGame/debug_text_tree.h index 6debe33efc1..57d3970284f 100644 --- a/src/xrGame/debug_text_tree.h +++ b/src/xrGame/debug_text_tree.h @@ -23,19 +23,15 @@ IC xr_string __cdecl make_xrstr(pcstr format, ...) IC xr_string __cdecl make_xrstr(bool b) { return b ? "+" : "-"; } IC xr_string __cdecl make_xrstr(float f) { return make_xrstr("%f", f); } -IC xr_string __cdecl make_xrstr(s32 d) { return make_xrstr("%i", d); } -IC xr_string __cdecl make_xrstr(u32 d) { return make_xrstr("%u", d); } -IC xr_string __cdecl make_xrstr(s64 d) { return make_xrstr("%i", d); } -IC xr_string __cdecl make_xrstr(u64 d) { return make_xrstr("%u", d); } -#ifdef XR_PLATFORM_APPLE -ICF xr_string __cdecl make_xrstr(size_t d) -{ - if constexpr (sizeof(size_t) == sizeof(u32)) - return make_xrstr(static_cast(d)); - else - return make_xrstr(static_cast(d)); -} -#endif + +IC xr_string __cdecl make_xrstr(int d) { return make_xrstr("%i", d); } +IC xr_string __cdecl make_xrstr(unsigned int d) { return make_xrstr("%u", d); } + +IC xr_string __cdecl make_xrstr(long d) { return make_xrstr("%li", d); } +IC xr_string __cdecl make_xrstr(unsigned long d) { return make_xrstr("%lu", d); } + +IC xr_string __cdecl make_xrstr(long long d) { return make_xrstr("%lli", d); } +IC xr_string __cdecl make_xrstr(unsigned long long d) { return make_xrstr("%llu", d); } IC xr_string __cdecl make_xrstr(Fvector3 v) { return make_xrstr("[%f][%f][%f]", v.x, v.y, v.z); } IC xr_string __cdecl make_xrstr(const xr_string& s) { return s; } From 0121b93367850a3873d6edf6008261e13b660cad Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:33:23 +0500 Subject: [PATCH 092/497] xrCore/_math.cpp: improved code path selection for Linux/BSD/etc. --- src/xrCore/_math.cpp | 89 ++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 3c3abf95773..9305dc3e583 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -13,36 +13,29 @@ #include #include -# if __has_include() +// It's reasonable to use special functions only if we have precision control. + +# if __has_include() && defined(XR_ARCHITECTURE_X86) +// Check for _FPU_EXTENDED, _FPU_DOUBLE, _FPU_SINGLE macros availability here: +// https://elixir.bootlin.com/glibc/glibc-2.38.9000/A/ident/_FPU_SETCW # include -# define USE_FPU_CONTROL_H -# else -# include -# pragma STDC FENV_ACCESS on -# if defined(XR_PLATFORM_BSD) -# define USE_FPU_CONTROL_H - typedef unsigned int fpu_control_t __attribute__((__mode__(__HI__))); // XXX: replace with type alias -# define _FPU_GETCW(x) asm volatile ("fnstcw %0" : "=m" ((*&x))) -# define _FPU_SETCW(x) asm volatile ("fldcw %0" : : "m" ((*&x))) -# define _FPU_EXTENDED FP_PRC_FLD -# define _FPU_DOUBLE 0x200 -# define _FPU_SINGLE 0x0 -# define _FPU_RC_NEAREST FP_PS -# define _FPU_DEFAULT FP_PD -# endif +# define USE_GLIBC_FPU_CONTROL + +# elif defined(XR_PLATFORM_FREEBSD) +// Check for fpsetprec availability +# include +# define USE_BSD_FP # endif #endif +#if !defined(XR_PLATFORM_WINDOWS) && !defined(USE_GLIBC_FPU_CONTROL) && !defined(USE_BSD_FP) +# include +# pragma STDC FENV_ACCESS on +#endif + #include #include -#if (defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) || defined(XR_ARCHITECTURE_E2K) || defined(XR_ARCHITECTURE_PPC64)) && !defined(XR_COMPILER_MSVC) -#define _FPU_EXTENDED 0 -#define _FPU_DOUBLE 0 -#define _FPU_SINGLE 0 -#define _FPU_RC_NEAREST 0 -#endif // defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) || defined(XR_ARCHITECTURE_E2K) - // Initialized on startup XRCORE_API Fmatrix Fidentity; XRCORE_API Dmatrix Didentity; @@ -61,15 +54,18 @@ namespace FPU XRCORE_API void m24() { #if defined(XR_PLATFORM_WINDOWS) -# ifndef XR_ARCHITECTURE_X64 +# ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_24, MCW_PC); # endif _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RZ); + fpsetprec(FP_PS); #else std::fesetround(FE_TOWARDZERO); #endif @@ -78,15 +74,18 @@ XRCORE_API void m24() XRCORE_API void m24r() { #if defined(XR_PLATFORM_WINDOWS) -# ifndef XR_ARCHITECTURE_X64 +# ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_24, MCW_PC); # endif _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE | _FPU_RC_NEAREST; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RN); + fpsetprec(FP_PS); #else std::fesetround(FE_TONEAREST); #endif @@ -95,15 +94,18 @@ XRCORE_API void m24r() XRCORE_API void m53() { #if defined(XR_PLATFORM_WINDOWS) -# ifndef XR_ARCHITECTURE_X64 +# ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_53, MCW_PC); # endif _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RZ); + fpsetprec(FP_PD); #else std::fesetround(FE_TOWARDZERO); #endif @@ -112,15 +114,18 @@ XRCORE_API void m53() XRCORE_API void m53r() { #if defined(XR_PLATFORM_WINDOWS) -# ifndef XR_ARCHITECTURE_X64 +# ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_53, MCW_PC); # endif _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE | _FPU_RC_NEAREST; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RN); + fpsetprec(FP_PD); #else std::fesetround(FE_TONEAREST); #endif @@ -129,15 +134,18 @@ XRCORE_API void m53r() XRCORE_API void m64() { #if defined(XR_PLATFORM_WINDOWS) -# ifndef XR_ARCHITECTURE_X64 +# ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_64, MCW_PC); # endif _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_DOUBLE & ~_FPU_SINGLE) | _FPU_EXTENDED; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RZ); + fpsetprec(FP_PE); #else std::fesetround(FE_TOWARDZERO); #endif @@ -146,15 +154,18 @@ XRCORE_API void m64() XRCORE_API void m64r() { #if defined(XR_PLATFORM_WINDOWS) -#ifndef XR_ARCHITECTURE_X64 +#ifdef XR_ARCHITECTURE_X86 _controlfp(_PC_64, MCW_PC); #endif _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_FPU_CONTROL_H) +#elif defined(USE_GLIBC_FPU_CONTROL) fpu_control_t fpu_cw; _FPU_GETCW(fpu_cw); fpu_cw = (fpu_cw & ~_FPU_DOUBLE & ~_FPU_SINGLE) | _FPU_EXTENDED | _FPU_RC_NEAREST; _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + fpsetround(FP_RN); + fpsetprec(FP_PE); #else std::fesetround(FE_TONEAREST); #endif @@ -164,12 +175,10 @@ void initialize() { #if defined(XR_PLATFORM_WINDOWS) _clearfp(); -#elif defined(USE_FPU_CONTROL_H) - fpu_control_t fpu_cw; - fpu_cw = _FPU_DEFAULT; - _FPU_SETCW(fpu_cw); +#elif defined(USE_BSD_FP) + std::ignore = fpresetsticky(FP_X_INV | |FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP | FP_X_STK); #else - std::feclearexcept(FE_ALL_EXCEPT); + std::ignore = std::feclearexcept(FE_ALL_EXCEPT); #endif // По-умолчанию для плагинов экспорта из 3D-редакторов включена высокая точность вычислений с плавающей точкой From 585b6701580e2b829e021aa9de434d5efe3fcdc1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:34:45 +0500 Subject: [PATCH 093/497] Don't link dl on OpenBSD It's a part of libc in OpenBSD, there's no ld.so/ld.a. --- Externals/LuaJIT-proj/CMakeLists.txt | 5 ++++- Externals/imgui-proj/CMakeLists.txt | 10 ++++++---- src/xrCore/CMakeLists.txt | 8 +++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Externals/LuaJIT-proj/CMakeLists.txt b/Externals/LuaJIT-proj/CMakeLists.txt index 87cfbc9d2ab..9ec04fd9894 100644 --- a/Externals/LuaJIT-proj/CMakeLists.txt +++ b/Externals/LuaJIT-proj/CMakeLists.txt @@ -45,7 +45,10 @@ elseif (APPLE) option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) else() option(LUA_USE_POSIX "Use POSIX functionality." ON) - option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) + + if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD has dlopen as a part of libc + option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) + endif() endif() # TODO: check if we need luaconf.h diff --git a/Externals/imgui-proj/CMakeLists.txt b/Externals/imgui-proj/CMakeLists.txt index 52c3c993ca0..0e8771536ee 100644 --- a/Externals/imgui-proj/CMakeLists.txt +++ b/Externals/imgui-proj/CMakeLists.txt @@ -23,10 +23,12 @@ target_include_directories(xrImGui "${IMGUI_DIR}" ) -target_link_libraries(xrImGui - PRIVATE - dl -) +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT WIN32) + target_link_libraries(xrImGui + PRIVATE + $<$>:dl> + ) +endif() target_compile_definitions(xrImGui PRIVATE diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 8c34504a9bd..a8561001263 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -449,12 +449,18 @@ target_link_libraries(xrCore PRIVATE xrMiscMath - dl $<$:mimalloc> $<$:JPEG::JPEG> LZO::LZO ) +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT WIN32) + target_link_libraries(xrCore + PRIVATE + dl + ) +endif() + target_compile_definitions(xrCore PRIVATE XRCORE_EXPORTS From b16894d7de09934e50c24053617ba2f02eba0b62 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:40:32 +0500 Subject: [PATCH 094/497] Common/Platform.hpp: expand *BSD macros to allow to determine exact platform --- src/Common/Platform.hpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Common/Platform.hpp b/src/Common/Platform.hpp index dde3a96b556..6bb391d3ac5 100644 --- a/src/Common/Platform.hpp +++ b/src/Common/Platform.hpp @@ -6,9 +6,23 @@ #elif defined(__linux__) # define XR_PLATFORM_LINUX # define _XRAY_PLATFORM_MARKER "Linux" -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(BSD) # define XR_PLATFORM_BSD -# define _XRAY_PLATFORM_MARKER "BSD" +# if defined(__FreeBSD__) +# define XR_PLATFORM_FREEBSD +# define _XRAY_PLATFORM_MARKER "FreeBSD" +# elif defined(__OpenBSD__) +# define XR_PLATFORM_OPENBSD +# define _XRAY_PLATFORM_MARKER "OpenBSD" +# elif defined(__NetBSD__) +# define XR_PLATFORM_NETBSD +# define _XRAY_PLATFORM_MARKER "NetBSD" +# elif defined(__DragonFly__) +# define XR_PLATFORM_DRAGONFLYBSD +# define _XRAY_PLATFORM_MARKER "DragonFlyBSD" +# else +# define _XRAY_PLATFORM_MARKER "*BSD" +# endif #elif defined(__APPLE__) # define XR_PLATFORM_APPLE # define _XRAY_PLATFORM_MARKER "Apple" From 8f799be74b7f987f17c355788e0e2159fda8dfa1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:41:42 +0500 Subject: [PATCH 095/497] xrCore/Threading/ThreadUtil.cpp: fix compilation on OpenBSD/NetBSD Moved Apple's function fix to this file too. --- src/Common/PlatformApple.inl | 1 - src/xrCore/Threading/ThreadUtil.cpp | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 1cc460b9321..140dfcb8d74 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -62,7 +62,6 @@ #define GetCurrentProcessId getpid #define GetCurrentThreadId pthread_self -static int pthread_setname_np(pthread_t /*threadId*/, const char* name) { return pthread_setname_np(name); } inline void Sleep(int ms) { diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index e5bbd40a943..a3ca491d3b0 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -2,7 +2,27 @@ #include "ThreadUtil.h" #if defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) -#include +# include + +# if defined(XR_PLATFORM_OPENBSD) || (defined(XR_PLATFORM_FREEBSD) && __FreeBSD_version < 1201519) +# include + +static int pthread_setname_np(pthread_t threadId, const char* name) +{ + pthread_set_name_np(threadId, name); + return 0; +} +# elif defined(XR_PLATFORM_NETBSD) +static int pthread_setname_np(pthread_t threadId, const char* name) +{ + return pthread_setname_np(threadId, "%s", name); +} +# elif defined(XR_PLATFORM_APPLE) +static int pthread_setname_np(pthread_t /*threadId*/, const char* name) +{ + return pthread_setname_np(name); +} +# endif #endif namespace Threading From 5ab0ed3b7182edc778bc7fb242f92000e01e876e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 11:42:42 +0500 Subject: [PATCH 096/497] Externals/GameSpy: include pthread.h to make sure it's compilable --- Externals/GameSpy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/GameSpy b/Externals/GameSpy index c355b6e9b88..61d061b4b3f 160000 --- a/Externals/GameSpy +++ b/Externals/GameSpy @@ -1 +1 @@ -Subproject commit c355b6e9b88b1d00912db902872c8bc7977f994e +Subproject commit 61d061b4b3f860865f97e659e496e11704f61eb3 From d0a2145db6f792134e65b6f9352849420de49e31 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 12:52:30 +0500 Subject: [PATCH 097/497] Don't use variable names starting with _ or __ Such names are reserved by the C++ standard. This fixes compilation errors due to conflicts on OpenBSD. --- Externals/OPCODE/OPC_AABBTree.cpp | 4 +- Externals/OPCODE/OPC_Point.h | 61 +++-- src/Common/OGF_GContainer_Vertices.hpp | 36 +-- src/Common/object_loader.h | 6 +- src/Layers/xrRender/FSkinnedTypes.h | 208 +++++++++--------- src/Layers/xrRender/ParticleEffect.cpp | 14 +- src/Layers/xrRender/R_Backend_Runtime.cpp | 16 +- src/Layers/xrRender/R_Backend_Runtime.h | 6 +- src/Layers/xrRender/ResourceManager_Reset.cpp | 14 +- .../xrRender/ResourceManager_Scripting.cpp | 12 +- src/Layers/xrRender/SH_Constant.cpp | 18 +- src/Layers/xrRender/SH_Constant.h | 16 +- src/Layers/xrRender/SkeletonCustom.cpp | 7 +- src/Layers/xrRender/SkeletonX.cpp | 10 +- src/Layers/xrRender/dxFontRender.cpp | 15 +- src/Layers/xrRender/light.h | 6 +- src/Layers/xrRender/r__occlusion.cpp | 4 +- src/Layers/xrRender/r__occlusion.h | 6 +- src/Layers/xrRender/r__sector_traversal.cpp | 10 +- src/Layers/xrRender/r_sun_cascades.h | 2 +- .../dx11ResourceManager_Scripting.cpp | 16 +- .../glResourceManager_Scripting.cpp | 12 +- src/Layers/xrRenderPC_R1/LightPPA.cpp | 8 +- src/Layers/xrRenderPC_R1/LightShadows.cpp | 8 +- src/Layers/xrRender_R2/r2_loader.cpp | 28 +-- src/utils/xrAI/xr_graph_merge.cpp | 10 +- src/utils/xrDXT/dds/tPixel.h | 8 +- src/utils/xrLC/OGF_Face.h | 8 +- src/utils/xrLC/xrMU_Model_export_OGF.cpp | 16 +- src/utils/xrLC/xrPhase_MergeLM_Surface.cpp | 50 ++--- src/utils/xrLCUtil/xrThread.hpp | 4 +- src/utils/xrLC_Light/xrDeflector.h | 4 +- src/utils/xrLC_Light/xrMU_Model_Load.cpp | 34 +-- .../xrMU_Model_Reference_Calc_Lighting.cpp | 12 +- src/utils/xrSE_Factory/script_value_wrapper.h | 12 +- .../script_value_wrapper_inline.h | 18 +- src/xrCDB/ISpatial.h | 4 +- src/xrCore/LocatorAPI_defs.h | 2 +- src/xrCore/_sphere.h | 6 +- src/xrEngine/CameraManager.cpp | 20 +- src/xrEngine/xr_efflensflare.cpp | 4 +- src/xrEngine/xr_ioc_cmd.cpp | 10 +- src/xrGame/Level_network.cpp | 4 +- src/xrSound/SoundRender_Scene.cpp | 14 +- src/xrUICore/Lines/UILines.cpp | 4 +- src/xrUICore/ProgressBar/UIProgressBar.cpp | 4 +- src/xrUICore/ProgressBar/UIProgressBar.h | 8 +- src/xrUICore/ProgressBar/UIProgressShape.cpp | 12 +- src/xrUICore/TrackBar/UITrackBar.cpp | 37 ++-- 49 files changed, 421 insertions(+), 427 deletions(-) diff --git a/Externals/OPCODE/OPC_AABBTree.cpp b/Externals/OPCODE/OPC_AABBTree.cpp index 328d09c5a6b..81da7e2ce22 100644 --- a/Externals/OPCODE/OPC_AABBTree.cpp +++ b/Externals/OPCODE/OPC_AABBTree.cpp @@ -164,7 +164,7 @@ bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder) // Find the largest axis to split along Point Extents; mBV.GetExtents(Extents); // Box extents - udword Axis = Extents.LargestAxis(); // Index of largest axis + const udword Axis = (udword)Extents.LargestAxis(); // Index of largest axis // Split along the axis NbPos = Split(Axis, builder); @@ -201,7 +201,7 @@ bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder) Vars /= float(mNbPrimitives - 1); // Choose axis with greatest variance - udword Axis = Vars.LargestAxis(); + const udword Axis = (udword)Vars.LargestAxis(); // Split along the axis NbPos = Split(Axis, builder); diff --git a/Externals/OPCODE/OPC_Point.h b/Externals/OPCODE/OPC_Point.h index 6a96192e4c0..b2df252be52 100644 --- a/Externals/OPCODE/OPC_Point.h +++ b/Externals/OPCODE/OPC_Point.h @@ -12,13 +12,12 @@ #ifndef __ICEPOINT_H__ #define __ICEPOINT_H__ -enum PointComponent +enum class PointComponent : u32 { - _X = 0, - _Y = 1, - _Z = 2, - _W = 3, - _FORCE_DWORD = 0x7fffffff + X = 0, + Y = 1, + Z = 2, + W = 3, }; // Forward declarations @@ -44,7 +43,7 @@ class ICEMATHS_API icePoint //! Constructor from floats inline_ Point(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} //! Constructor from array - inline_ Point(float f[3]) : x(f[_X]), y(f[_Y]), z(f[_Z]) {} + inline_ Point(float f[3]) : x(f[(u32)PointComponent::X]), y(f[(u32)PointComponent::Y]), z(f[(u32)PointComponent::Z]) {} //! Copy constructor inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {} //! Destructor @@ -85,9 +84,9 @@ class ICEMATHS_API icePoint //! Assignment from array inline_ Point& Set(float f[3]) { - x = f[_X]; - y = f[_Y]; - z = f[_Z]; + x = f[(u32)PointComponent::X]; + y = f[(u32)PointComponent::Y]; + z = f[(u32)PointComponent::Z]; return *this; } //! Assignment from another point @@ -118,9 +117,9 @@ class ICEMATHS_API icePoint //! Adds a vector3 inline_ Point& Add(float f[3]) { - x += f[_X]; - y += f[_Y]; - z += f[_Z]; + x += f[(u32)PointComponent::X]; + y += f[(u32)PointComponent::Y]; + z += f[(u32)PointComponent::Z]; return *this; } //! Adds vectors @@ -151,9 +150,9 @@ class ICEMATHS_API icePoint //! Subtracts a vector3 inline_ Point& Sub(float f[3]) { - x -= f[_X]; - y -= f[_Y]; - z -= f[_Z]; + x -= f[(u32)PointComponent::X]; + y -= f[(u32)PointComponent::Y]; + z -= f[(u32)PointComponent::Z]; return *this; } //! Subtracts vectors @@ -463,11 +462,11 @@ class ICEMATHS_API icePoint inline_ PointComponent LargestAxis() const { const float* Vals = &x; - PointComponent m = _X; - if (Vals[_Y] > Vals[m]) - m = _Y; - if (Vals[_Z] > Vals[m]) - m = _Z; + PointComponent m = PointComponent::X; + if (Vals[(u32)PointComponent::Y] > Vals[(u32)m]) + m = PointComponent::Y; + if (Vals[(u32)PointComponent::Z] > Vals[(u32)m]) + m = PointComponent::Z; return m; } @@ -475,11 +474,11 @@ class ICEMATHS_API icePoint inline_ PointComponent ClosestAxis() const { const float* Vals = &x; - PointComponent m = _X; - if (AIR(Vals[_Y]) > AIR(Vals[m])) - m = _Y; - if (AIR(Vals[_Z]) > AIR(Vals[m])) - m = _Z; + PointComponent m = PointComponent::X; + if (AIR(Vals[(u32)PointComponent::Y]) > AIR(Vals[(u32)m])) + m = PointComponent::Y; + if (AIR(Vals[(u32)PointComponent::Z]) > AIR(Vals[(u32)m])) + m = PointComponent::Z; return m; } @@ -487,11 +486,11 @@ class ICEMATHS_API icePoint inline_ PointComponent SmallestAxis() const { const float* Vals = &x; - PointComponent m = _X; - if (Vals[_Y] < Vals[m]) - m = _Y; - if (Vals[_Z] < Vals[m]) - m = _Z; + PointComponent m = PointComponent::X; + if (Vals[(u32)PointComponent::Y] < Vals[(u32)m]) + m = PointComponent::Y; + if (Vals[(u32)PointComponent::Z] < Vals[(u32)m]) + m = PointComponent::Z; return m; } diff --git a/src/Common/OGF_GContainer_Vertices.hpp b/src/Common/OGF_GContainer_Vertices.hpp index 0c5a0abc4ce..8e2490df118 100644 --- a/src/Common/OGF_GContainer_Vertices.hpp +++ b/src/Common/OGF_GContainer_Vertices.hpp @@ -111,7 +111,7 @@ constexpr D3DVERTEXELEMENT9 mu_model_decl_unpacked[] = // 12+4+4+8 = 28 struct x_vert { Fvector3 P; - x_vert(Fvector3 _P) { P = _P; } + x_vert(Fvector3 p) { P = p; } }; struct r1v_lmap @@ -124,17 +124,17 @@ struct r1v_lmap _vector2 tc1; #ifdef LEVEL_COMPILER - r1v_lmap(Fvector3 _P, Fvector _N, base_basis _T, base_basis _B, base_color _CC, Fvector2 tc_base, Fvector2 tc_lmap) + r1v_lmap(Fvector3 position, Fvector normal, base_basis tangent, base_basis binormal, base_color CC_, Fvector2 tc_base, Fvector2 tc_lmap) { - base_color_c _C; - _CC._get(_C); - _N.normalize(); + base_color_c C_; + CC_._get(C_); + normal.normalize(); std::pair tc_u = s24_tc_base(tc_base.x); std::pair tc_v = s24_tc_base(tc_base.y); - P = _P; - N = u8_vec4(_N, u8_clr(_C.hemi)); - T = u8_vec4(_T, tc_u.second); - B = u8_vec4(_B, tc_v.second); + P = position; + N = u8_vec4(normal, u8_clr(C_.hemi)); + T = u8_vec4(tangent, tc_u.second); + B = u8_vec4(binormal, tc_v.second); tc0.x = tc_u.first; tc0.y = tc_v.first; tc1.x = s16_tc_lmap(tc_lmap.x); @@ -182,18 +182,18 @@ struct r1v_vert _vector2 tc; #ifdef LEVEL_COMPILER - r1v_vert(Fvector3 _P, Fvector _N, base_basis _T, base_basis _B, base_color _CC, Fvector2 tc_base) + r1v_vert(Fvector3 position, Fvector normal, base_basis tangent, base_basis binormal, base_color CC_, Fvector2 tc_base) { - base_color_c _C; - _CC._get(_C); - _N.normalize(); + base_color_c C_; + CC_._get(C_); + normal.normalize(); std::pair tc_u = s24_tc_base(tc_base.x); std::pair tc_v = s24_tc_base(tc_base.y); - P = _P; - N = u8_vec4(_N, u8_clr(_C.hemi)); - T = u8_vec4(_T, tc_u.second); - B = u8_vec4(_B, tc_v.second); - C = color_rgba(u8_clr(_C.rgb.x), u8_clr(_C.rgb.y), u8_clr(_C.rgb.z), u8_clr(_C.sun)); + P = position; + N = u8_vec4(normal, u8_clr(C_.hemi)); + T = u8_vec4(tangent, tc_u.second); + B = u8_vec4(binormal, tc_v.second); + C = color_rgba(u8_clr(C_.rgb.x), u8_clr(C_.rgb.y), u8_clr(C_.rgb.z), u8_clr(C_.sun)); tc.x = tc_u.first; tc.y = tc_v.first; } diff --git a/src/Common/object_loader.h b/src/Common/object_loader.h index 8653c130795..76ebbcb6df6 100644 --- a/src/Common/object_loader.h +++ b/src/Common/object_loader.h @@ -55,10 +55,10 @@ struct CLoader template struct has_value_compare { - template + template static object_type_traits::detail::yes select( - object_type_traits::detail::other*); - template + object_type_traits::detail::other*); + template static object_type_traits::detail::no select(...); enum { diff --git a/src/Layers/xrRender/FSkinnedTypes.h b/src/Layers/xrRender/FSkinnedTypes.h index df9acfb97bb..8552004d35a 100644 --- a/src/Layers/xrRender/FSkinnedTypes.h +++ b/src/Layers/xrRender/FSkinnedTypes.h @@ -171,31 +171,31 @@ struct vertHW_1W { static_assert(std::is_same_v || std::is_same_v, "Only float and s16 are supported"); - TVal _P[4]; - u32 _N_I; - u32 _T; - u32 _B; - TVal _tc[2]; + TVal Position[4]; + u32 Normal_and_index; + u32 Tangent; + u32 Binormal; + TVal TexCoord[2]; - void set(const Fvector3& P, Fvector3 N, Fvector3 T, Fvector3 B, const Fvector2& tc, int index) + void set(const Fvector3& position, Fvector3 normal, Fvector3 tangent, Fvector3 binormal, const Fvector2& texcoord, int index) { - N.normalize_safe(); - T.normalize_safe(); - B.normalize_safe(); - q_P(_P[0], P.x); - q_P(_P[1], P.y); - q_P(_P[2], P.z); - _P[3] = TVal(1); - _N_I = color_rgba(q_N(N.x), q_N(N.y), q_N(N.z), u8(index)); - _T = color_rgba(q_N(T.x), q_N(T.y), q_N(T.z), 0); - _B = color_rgba(q_N(B.x), q_N(B.y), q_N(B.z), 0); - q_tc(_tc[0], tc.x); - q_tc(_tc[1], tc.y); + normal.normalize_safe(); + tangent.normalize_safe(); + binormal.normalize_safe(); + q_P(Position[0], position.x); + q_P(Position[1], position.y); + q_P(Position[2], position.z); + Position[3] = TVal(1); + Normal_and_index = color_rgba(q_N(normal.x), q_N(normal.y), q_N(normal.z), u8(index)); + Tangent = color_rgba(q_N(tangent.x), q_N(tangent.y), q_N(tangent.z), 0); + Binormal = color_rgba(q_N(binormal.x), q_N(binormal.y), q_N(binormal.z), 0); + q_tc(TexCoord[0], texcoord.x); + q_tc(TexCoord[1], texcoord.y); } u16 get_bone() const { - return (u16)color_get_A(_N_I) / 3; + return (u16)color_get_A(Normal_and_index) / 3; } void get_pos_bones(Fvector& p, CKinematics* Parent) const @@ -207,9 +207,9 @@ struct vertHW_1W void get_pos(Fvector& p) const { - p.x = u_P(_P[0]); - p.y = u_P(_P[1]); - p.z = u_P(_P[2]); + p.x = u_P(Position[0]); + p.y = u_P(Position[1]); + p.z = u_P(Position[2]); } }; @@ -218,46 +218,46 @@ struct vertHW_2W { static_assert(std::is_same_v || std::is_same_v, "Only float and s16 are supported"); - TVal _P[4]; - u32 _N_w; - u32 _T; - u32 _B; - TVal _tc_i[4]; + TVal Position[4]; + u32 Normal_and_w; + u32 Tangent; + u32 Binormal; + TVal TexCoord_and_index[4]; - void set(const Fvector3& P, Fvector3 N, Fvector3 T, Fvector3 B, const Fvector2& tc, + void set(const Fvector3& position, Fvector3 normal, Fvector3 tangent, Fvector3 binormal, const Fvector2& texcoord, int index0, int index1, float w) { - N.normalize_safe(); - T.normalize_safe(); - B.normalize_safe(); - q_P(_P[0], P.x); - q_P(_P[1], P.y); - q_P(_P[2], P.z); - _P[3] = TVal(1); - _N_w = color_rgba(q_N(N.x), q_N(N.y), q_N(N.z), u8(clampr(iFloor(w * 255.f + .5f), 0, 255))); - _T = color_rgba(q_N(T.x), q_N(T.y), q_N(T.z), 0); - _B = color_rgba(q_N(B.x), q_N(B.y), q_N(B.z), 0); - q_tc(_tc_i[0], tc.x); - q_tc(_tc_i[1], tc.y); - _tc_i[2] = s16(index0); - _tc_i[3] = s16(index1); + normal.normalize_safe(); + tangent.normalize_safe(); + binormal.normalize_safe(); + q_P(Position[0], position.x); + q_P(Position[1], position.y); + q_P(Position[2], position.z); + Position[3] = TVal(1); + Normal_and_w = color_rgba(q_N(normal.x), q_N(normal.y), q_N(normal.z), u8(clampr(iFloor(w * 255.f + .5f), 0, 255))); + Tangent = color_rgba(q_N(tangent.x), q_N(tangent.y), q_N(tangent.z), 0); + Binormal = color_rgba(q_N(binormal.x), q_N(binormal.y), q_N(binormal.z), 0); + q_tc(TexCoord_and_index[0], texcoord.x); + q_tc(TexCoord_and_index[1], texcoord.y); + TexCoord_and_index[2] = s16(index0); + TexCoord_and_index[3] = s16(index1); } float get_weight() const { - return float(color_get_A(_N_w)) / 255.f; + return float(color_get_A(Normal_and_w)) / 255.f; } u16 get_bone(u16 w) const { - return (u16)_tc_i[w + 2] / 3; + return (u16)TexCoord_and_index[w + 2] / 3; } void get_pos(Fvector& p) const { - p.x = u_P(_P[0]); - p.y = u_P(_P[1]); - p.z = u_P(_P[2]); + p.x = u_P(Position[0]); + p.y = u_P(Position[1]); + p.z = u_P(Position[2]); } void get_pos_bones(Fvector& p, CKinematics* Parent) const @@ -278,40 +278,40 @@ struct vertHW_3W { static_assert(std::is_same_v || std::is_same_v, "Only float and s16 are supported"); - TVal _P[4]; - u32 _N_w; - u32 _T_w; - u32 _B_i; - TVal _tc_i[4]; + TVal Position[4]; + u32 Normal_and_w; + u32 Tangent_and_w; + u32 Binormal_and_index; + TVal TexCoord_and_index[4]; - void set(const Fvector3& P, Fvector3 N, Fvector3 T, Fvector3 B, const Fvector2& tc, + void set(const Fvector3& position, Fvector3 normal, Fvector3 tangent, Fvector3 binormal, const Fvector2& texcoord, int index0, int index1, int index2, float w0, float w1) { - N.normalize_safe(); - T.normalize_safe(); - B.normalize_safe(); - q_P(_P[0], P.x); - q_P(_P[1], P.y); - q_P(_P[2], P.z); - _P[3] = TVal(1); - _N_w = color_rgba(q_N(N.x), q_N(N.y), q_N(N.z), u8(clampr(iFloor(w0 * 255.f + .5f), 0, 255))); - _T_w = color_rgba(q_N(T.x), q_N(T.y), q_N(T.z), u8(clampr(iFloor(w1 * 255.f + .5f), 0, 255))); - _B_i = color_rgba(q_N(B.x), q_N(B.y), q_N(B.z), u8(index2)); - q_tc(_tc_i[0], tc.x);; - q_tc(_tc_i[1], tc.y);; - _tc_i[2] = s16(index0); - _tc_i[3] = s16(index1); + normal.normalize_safe(); + tangent.normalize_safe(); + binormal.normalize_safe(); + q_P(Position[0], position.x); + q_P(Position[1], position.y); + q_P(Position[2], position.z); + Position[3] = TVal(1); + Normal_and_w = color_rgba(q_N(normal.x), q_N(normal.y), q_N(normal.z), u8(clampr(iFloor(w0 * 255.f + .5f), 0, 255))); + Tangent_and_w = color_rgba(q_N(tangent.x), q_N(tangent.y), q_N(tangent.z), u8(clampr(iFloor(w1 * 255.f + .5f), 0, 255))); + Binormal_and_index = color_rgba(q_N(binormal.x), q_N(binormal.y), q_N(binormal.z), u8(index2)); + q_tc(TexCoord_and_index[0], texcoord.x);; + q_tc(TexCoord_and_index[1], texcoord.y);; + TexCoord_and_index[2] = s16(index0); + TexCoord_and_index[3] = s16(index1); } float get_weight0() const { - return float(color_get_A(_N_w)) / 255.f; + return float(color_get_A(Normal_and_w)) / 255.f; } float get_weight1() const { - return float(color_get_A(_T_w)) / 255.f; + return float(color_get_A(Tangent_and_w)) / 255.f; } u16 get_bone(u16 w) const @@ -319,8 +319,8 @@ struct vertHW_3W switch (w) { case 0: - case 1: return (u16)_tc_i[w + 2] / 3; - case 2: return (u16)color_get_A(_B_i) / 3; + case 1: return (u16)TexCoord_and_index[w + 2] / 3; + case 2: return (u16)color_get_A(Binormal_and_index) / 3; } R_ASSERT(0); return 0; @@ -328,9 +328,9 @@ struct vertHW_3W void get_pos(Fvector& p) const { - p.x = u_P(_P[0]); - p.y = u_P(_P[1]); - p.z = u_P(_P[2]); + p.x = u_P(Position[0]); + p.y = u_P(Position[1]); + p.z = u_P(Position[2]); } void get_pos_bones(Fvector& p, CKinematics* Parent) const @@ -361,55 +361,55 @@ struct vertHW_4W { static_assert(std::is_same_v || std::is_same_v, "Only float and s16 are supported"); - TVal _P[4]; - u32 _N_w; - u32 _T_w; - u32 _B_w; - TVal _tc[2]; - u32 _i; + TVal Position[4]; + u32 Normal_and_w; + u32 Tangent_and_w; + u32 Binormal_and_w; + TVal TexCoord[2]; + u32 Index; - void set(const Fvector3& P, Fvector3 N, Fvector3 T, Fvector3 B, const Fvector2& tc, + void set(const Fvector3& position, Fvector3 normal, Fvector3 tangent, Fvector3 binormal, const Fvector2& texcoord, int index0, int index1, int index2, int index3, float w0, float w1, float w2) { - N.normalize_safe(); - T.normalize_safe(); - B.normalize_safe(); - q_P(_P[0], P.x); - q_P(_P[1], P.y); - q_P(_P[2], P.z); - _P[3] = TVal(1); - _N_w = color_rgba(q_N(N.x), q_N(N.y), q_N(N.z), u8(clampr(iFloor(w0 * 255.f + .5f), 0, 255))); - _T_w = color_rgba(q_N(T.x), q_N(T.y), q_N(T.z), u8(clampr(iFloor(w1 * 255.f + .5f), 0, 255))); - _B_w = color_rgba(q_N(B.x), q_N(B.y), q_N(B.z), u8(clampr(iFloor(w2 * 255.f + .5f), 0, 255))); - q_tc(_tc[0], tc.x); - q_tc(_tc[1], tc.y); - _i = color_rgba(u8(index0), u8(index1), u8(index2), u8(index3)); + normal.normalize_safe(); + tangent.normalize_safe(); + binormal.normalize_safe(); + q_P(Position[0], position.x); + q_P(Position[1], position.y); + q_P(Position[2], position.z); + Position[3] = TVal(1); + Normal_and_w = color_rgba(q_N(normal.x), q_N(normal.y), q_N(normal.z), u8(clampr(iFloor(w0 * 255.f + .5f), 0, 255))); + Tangent_and_w = color_rgba(q_N(tangent.x), q_N(tangent.y), q_N(tangent.z), u8(clampr(iFloor(w1 * 255.f + .5f), 0, 255))); + Binormal_and_w = color_rgba(q_N(binormal.x), q_N(binormal.y), q_N(binormal.z), u8(clampr(iFloor(w2 * 255.f + .5f), 0, 255))); + q_tc(TexCoord[0], texcoord.x); + q_tc(TexCoord[1], texcoord.y); + Index = color_rgba(u8(index0), u8(index1), u8(index2), u8(index3)); } float get_weight0() const { - return float(color_get_A(_N_w)) / 255.f; + return float(color_get_A(Normal_and_w)) / 255.f; } float get_weight1() const { - return float(color_get_A(_T_w)) / 255.f; + return float(color_get_A(Tangent_and_w)) / 255.f; } float get_weight2() const { - return float(color_get_A(_B_w)) / 255.f; + return float(color_get_A(Binormal_and_w)) / 255.f; } u16 get_bone(u16 w) const { switch (w) { - case 0: return (u16)color_get_R(_i) / 3; - case 1: return (u16)color_get_G(_i) / 3; - case 2: return (u16)color_get_B(_i) / 3; - case 3: return (u16)color_get_A(_i) / 3; + case 0: return (u16)color_get_R(Index) / 3; + case 1: return (u16)color_get_G(Index) / 3; + case 2: return (u16)color_get_B(Index) / 3; + case 3: return (u16)color_get_A(Index) / 3; } R_ASSERT(0); return 0; @@ -417,9 +417,9 @@ struct vertHW_4W void get_pos(Fvector& p) const { - p.x = u_P(_P[0]); - p.y = u_P(_P[1]); - p.z = u_P(_P[2]); + p.x = u_P(Position[0]); + p.y = u_P(Position[1]); + p.z = u_P(Position[2]); } void get_pos_bones(Fvector& p, CKinematics* Parent) const diff --git a/src/Layers/xrRender/ParticleEffect.cpp b/src/Layers/xrRender/ParticleEffect.cpp index a42a89c8b21..d51708ef885 100644 --- a/src/Layers/xrRender/ParticleEffect.cpp +++ b/src/Layers/xrRender/ParticleEffect.cpp @@ -358,24 +358,24 @@ IC void FillSprite(FVF::LIT*& pv, const Fvector& T, const Fvector& R, const Fvec { m_sprite_section.Enter(); - __m128 Vr, Vt, _T, _R, _pos, _zz, _sa, _ca, a, b, c, d; + __m128 Vr, Vt, T_, R_, _pos, _zz, _sa, _ca, a, b, c, d; _sa = _mm_set1_ps(sina); _ca = _mm_set1_ps(cosa); - _T = _mm_load_ss((float*)&T.x); - _T = _mm_loadh_pi(_T, (__m64*)&T.y); + T_ = _mm_load_ss((float*)&T.x); + T_ = _mm_loadh_pi(T_, (__m64*)&T.y); - _R = _mm_load_ss((float*)&R.x); - _R = _mm_loadh_pi(_R, (__m64*)&R.y); + R_ = _mm_load_ss((float*)&R.x); + R_ = _mm_loadh_pi(R_, (__m64*)&R.y); _pos = _mm_load_ss((float*)&pos.x); _pos = _mm_loadh_pi(_pos, (__m64*)&pos.y); _zz = _mm_setzero_ps(); - Vr = _mm_mul_ps(_mm_set1_ps(r1), _mm_add_ps(_mm_mul_ps(_T, _sa), _mm_mul_ps(_R, _ca))); - Vt = _mm_mul_ps(_mm_set1_ps(r2), _mm_sub_ps(_mm_mul_ps(_T, _ca), _mm_mul_ps(_R, _sa))); + Vr = _mm_mul_ps(_mm_set1_ps(r1), _mm_add_ps(_mm_mul_ps(T_, _sa), _mm_mul_ps(R_, _ca))); + Vt = _mm_mul_ps(_mm_set1_ps(r2), _mm_sub_ps(_mm_mul_ps(T_, _ca), _mm_mul_ps(R_, _sa))); a = _mm_sub_ps(Vt, Vr); b = _mm_add_ps(Vt, Vr); diff --git a/src/Layers/xrRender/R_Backend_Runtime.cpp b/src/Layers/xrRender/R_Backend_Runtime.cpp index 4b866d38e58..439699a6789 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.cpp +++ b/src/Layers/xrRender/R_Backend_Runtime.cpp @@ -209,12 +209,12 @@ void CBackend::set_ClipPlanes(u32 _enable, Fmatrix* _xform /*=NULL */, u32 fmask set_ClipPlanes(_enable, F.planes, F.p_count); } -void CBackend::set_Textures(STextureList* _T) +void CBackend::set_Textures(STextureList* textures_list) { // TODO: expose T invalidation method - //if (T == _T) // disabled due to cases when the set of resources the same, but different srv is need to be bind + //if (T == textures_list) // disabled due to cases when the set of resources the same, but different srv is need to be bind // return; - T = _T; + T = textures_list; // If resources weren't set at all we should clear from resource #0. int _last_ps = -1; int _last_vs = -1; @@ -224,12 +224,12 @@ void CBackend::set_Textures(STextureList* _T) int _last_ds = -1; int _last_cs = -1; #endif - STextureList::iterator _it = _T->begin(); - STextureList::iterator _end = _T->end(); + auto it = textures_list->begin(); + const auto end = textures_list->end(); - for (; _it != _end; ++_it) + for (; it != end; ++it) { - std::pair& loader = *_it; + std::pair& loader = *it; u32 load_id = loader.first; CTexture* load_surf = loader.second._get(); //if (load_id < 256) { @@ -478,7 +478,7 @@ void CBackend::set_Textures(STextureList* _T) #else void CBackend::set_ClipPlanes(u32 _enable, Fmatrix* _xform /*=NULL */, u32 fmask /* =0xff */) {} -void CBackend::set_Textures(STextureList* _T) {} +void CBackend::set_Textures(STextureList* textures_list) {} #endif // DEDICATED SERVER diff --git a/src/Layers/xrRender/R_Backend_Runtime.h b/src/Layers/xrRender/R_Backend_Runtime.h index 181fccfe7c6..6bb1500cb4c 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.h +++ b/src/Layers/xrRender/R_Backend_Runtime.h @@ -101,11 +101,11 @@ ICF void CBackend::set_States(SState* _state) } } -IC void CBackend::set_Matrices(SMatrixList* _M) +IC void CBackend::set_Matrices(SMatrixList* matrix_list) { - if (M != _M) + if (M != matrix_list) { - M = _M; + M = matrix_list; if (M) { for (u32 it = 0; it < M->size(); it++) diff --git a/src/Layers/xrRender/ResourceManager_Reset.cpp b/src/Layers/xrRender/ResourceManager_Reset.cpp index c73a26e8569..b99b7733b87 100644 --- a/src/Layers/xrRender/ResourceManager_Reset.cpp +++ b/src/Layers/xrRender/ResourceManager_Reset.cpp @@ -47,20 +47,20 @@ void CResourceManager::reset_end() { for (u32 _it = 0; _it < v_geoms.size(); _it++) { - SGeometry* _G = v_geoms[_it]; - if (_G->vb == RImplementation.Vertex.old_pVB) - _G->vb = RImplementation.Vertex.Buffer(); + SGeometry* geom = v_geoms[_it]; + if (geom->vb == RImplementation.Vertex.old_pVB) + geom->vb = RImplementation.Vertex.Buffer(); // Here we may recover the buffer using one of // RCache's index buffers. // Do not remove else. - if (_G->ib == RImplementation.Index.old_pIB) + if (geom->ib == RImplementation.Index.old_pIB) { - _G->ib = RImplementation.Index.Buffer(); + geom->ib = RImplementation.Index.Buffer(); } - else if (_G->ib == RImplementation.old_QuadIB) + else if (geom->ib == RImplementation.old_QuadIB) { - _G->ib = RImplementation.QuadIB; + geom->ib = RImplementation.QuadIB; } } } diff --git a/src/Layers/xrRender/ResourceManager_Scripting.cpp b/src/Layers/xrRender/ResourceManager_Scripting.cpp index 1a201ef4e21..def93e69161 100644 --- a/src/Layers/xrRender/ResourceManager_Scripting.cpp +++ b/src/Layers/xrRender/ResourceManager_Scripting.cpp @@ -22,12 +22,12 @@ class adopt_sampler u32 stage; public: - adopt_sampler(CBlender_Compile* _C, u32 _stage) : C(_C), stage(_stage) + adopt_sampler(CBlender_Compile* compiler, u32 _stage) : C(compiler), stage(_stage) { if (u32(-1) == stage) C = nullptr; } - adopt_sampler(const adopt_sampler& _C) : C(_C.C), stage(_C.stage) + adopt_sampler(const adopt_sampler& other) : C(other.C), stage(other.stage) { if (u32(-1) == stage) C = nullptr; @@ -161,8 +161,8 @@ class adopt_compiler CBlender_Compile* C; public: - adopt_compiler(CBlender_Compile* _C) : C(_C) {} - adopt_compiler(const adopt_compiler& _C) : C(_C.C) {} + adopt_compiler(CBlender_Compile* compiler) : C(compiler) {} + adopt_compiler(const adopt_compiler& other) : C(other.C) {} adopt_compiler& _options(int P, bool S) { C->SetParams(P, S); @@ -193,7 +193,7 @@ class adopt_compiler C->PassSET_LightFog(FALSE, _fog); return *this; } - adopt_compiler& _ZB(bool _test, bool _write) + adopt_compiler& _zbuffer(bool _test, bool _write) { C->PassSET_ZB(_test, _write); return *this; @@ -267,7 +267,7 @@ void CResourceManager::LS_Load() .def("distort", &adopt_compiler::_o_distort, return_reference_to<1>()) .def("wmark", &adopt_compiler::_o_wmark, return_reference_to<1>()) .def("fog", &adopt_compiler::_fog, return_reference_to<1>()) - .def("zb", &adopt_compiler::_ZB, return_reference_to<1>()) + .def("zb", &adopt_compiler::_zbuffer, return_reference_to<1>()) .def("blend", &adopt_compiler::_blend, return_reference_to<1>()) .def("aref", &adopt_compiler::_aref, return_reference_to<1>()) .def("color_write_enable", &adopt_compiler::_color_write_enable, return_reference_to<1>()) diff --git a/src/Layers/xrRender/SH_Constant.cpp b/src/Layers/xrRender/SH_Constant.cpp index aa97b39949a..27399f38526 100644 --- a/src/Layers/xrRender/SH_Constant.cpp +++ b/src/Layers/xrRender/SH_Constant.cpp @@ -33,22 +33,22 @@ void CConstant::Calculate() return; float t = Device.fTimeGlobal; - set_float(_R.Calculate(t), _G.Calculate(t), _B.Calculate(t), _A.Calculate(t)); + set_float(R.Calculate(t), G.Calculate(t), B.Calculate(t), A.Calculate(t)); } void CConstant::Load(IReader* fs) { dwMode = modeWaveForm; - fs->r(&_R, sizeof(WaveForm)); - fs->r(&_G, sizeof(WaveForm)); - fs->r(&_B, sizeof(WaveForm)); - fs->r(&_A, sizeof(WaveForm)); + fs->r(&R, sizeof(WaveForm)); + fs->r(&G, sizeof(WaveForm)); + fs->r(&B, sizeof(WaveForm)); + fs->r(&A, sizeof(WaveForm)); } void CConstant::Save(IWriter* fs) { - fs->w(&_R, sizeof(WaveForm)); - fs->w(&_G, sizeof(WaveForm)); - fs->w(&_B, sizeof(WaveForm)); - fs->w(&_A, sizeof(WaveForm)); + fs->w(&R, sizeof(WaveForm)); + fs->w(&G, sizeof(WaveForm)); + fs->w(&B, sizeof(WaveForm)); + fs->w(&A, sizeof(WaveForm)); } diff --git a/src/Layers/xrRender/SH_Constant.h b/src/Layers/xrRender/SH_Constant.h index df493232165..c824a48e76f 100644 --- a/src/Layers/xrRender/SH_Constant.h +++ b/src/Layers/xrRender/SH_Constant.h @@ -22,10 +22,10 @@ class ECORE_API CConstant : public xr_resource_named u32 dwFrame{ 0 }; u32 dwMode{ 0 }; - WaveForm _R; - WaveForm _G; - WaveForm _B; - WaveForm _A; + WaveForm R; + WaveForm G; + WaveForm B; + WaveForm A; void set_float(float r, float g, float b, float a) { @@ -50,13 +50,13 @@ class ECORE_API CConstant : public xr_resource_named { if (dwMode != C.dwMode) return FALSE; - if (!_R.Similar(C._R)) + if (!R.Similar(C.R)) return FALSE; - if (!_G.Similar(C._G)) + if (!G.Similar(C.G)) return FALSE; - if (!_B.Similar(C._B)) + if (!B.Similar(C.B)) return FALSE; - if (!_A.Similar(C._A)) + if (!A.Similar(C.A)) return FALSE; return TRUE; } diff --git a/src/Layers/xrRender/SkeletonCustom.cpp b/src/Layers/xrRender/SkeletonCustom.cpp index 88001c58209..59492892ab8 100644 --- a/src/Layers/xrRender/SkeletonCustom.cpp +++ b/src/Layers/xrRender/SkeletonCustom.cpp @@ -50,10 +50,9 @@ u16 CKinematics::LL_BoneID(const shared_str& B) // LPCSTR CKinematics::LL_BoneName_dbg(u16 ID) { - CKinematics::accel::iterator _I, _E = bone_map_N->end(); - for (_I = bone_map_N->begin(); _I != _E; ++_I) - if (_I->second == ID) - return *_I->first; + for (const auto& [bone_name, bone_id] : *bone_map_N) + if (bone_id == ID) + return bone_name.c_str(); return nullptr; } diff --git a/src/Layers/xrRender/SkeletonX.cpp b/src/Layers/xrRender/SkeletonX.cpp index 12cc9b3ac49..d6f95c87245 100644 --- a/src/Layers/xrRender/SkeletonX.cpp +++ b/src/Layers/xrRender/SkeletonX.cpp @@ -98,11 +98,11 @@ void CSkeletonX::_Render_soft(CBackend& cmd_list, ref_geom& hGeom, u32 vCount, u { u32 vOffset = cache_vOffset; - _VertexStream& _VS = RImplementation.Vertex; - if (cache_DiscardID != _VS.DiscardID() || vCount != cache_vCount) + _VertexStream& vstream = RImplementation.Vertex; + if (cache_DiscardID != vstream.DiscardID() || vCount != cache_vCount) { - vertRender* Dest = (vertRender*)_VS.Lock(vCount, hGeom->vb_stride, vOffset); - cache_DiscardID = _VS.DiscardID(); + vertRender* Dest = (vertRender*)vstream.Lock(vCount, hGeom->vb_stride, vOffset); + cache_DiscardID = vstream.DiscardID(); cache_vCount = vCount; cache_vOffset = vOffset; @@ -143,7 +143,7 @@ void CSkeletonX::_Render_soft(CBackend& cmd_list, ref_geom& hGeom, u32 vCount, u R_ASSERT2(0, "unsupported soft rendering"); RImplementation.BasicStats.Skinning.End(); - _VS.Unlock(vCount, hGeom->vb_stride); + vstream.Unlock(vCount, hGeom->vb_stride); } cmd_list.set_Geometry(hGeom); diff --git a/src/Layers/xrRender/dxFontRender.cpp b/src/Layers/xrRender/dxFontRender.cpp index 63b2ca3df91..49081a7bdc8 100644 --- a/src/Layers/xrRender/dxFontRender.cpp +++ b/src/Layers/xrRender/dxFontRender.cpp @@ -92,15 +92,16 @@ void dxFontRender::OnRender(CGameFont& owner) case CGameFont::alRight: X -= iFloor(fSize); break; } - u32 clr, clr2; - clr2 = clr = PS.c; + const u32 clr = PS.c; + u32 clr2 = PS.c; + if (owner.uFlags & CGameFont::fsGradient) { - u32 _R = color_get_R(clr) / 2; - u32 _G = color_get_G(clr) / 2; - u32 _B = color_get_B(clr) / 2; - u32 _A = color_get_A(clr); - clr2 = color_rgba(_R, _G, _B, _A); + const u32 r = color_get_R(clr) / 2; + const u32 g = color_get_G(clr) / 2; + const u32 b = color_get_B(clr) / 2; + const u32 a = color_get_A(clr); + clr2 = color_rgba(r, g, b, a); } #ifndef USE_DX9 // Vertex shader will cancel a DX9 correction, so make fake offset diff --git a/src/Layers/xrRender/light.h b/src/Layers/xrRender/light.h index 84c0917358e..85cb5e7ea74 100644 --- a/src/Layers/xrRender/light.h +++ b/src/Layers/xrRender/light.h @@ -77,21 +77,21 @@ class light : public IRender_Light, public SpatialBase union _xform { - struct _D + struct Directional { Fmatrix combine; s32 minX, maxX; s32 minY, maxY; BOOL transluent; } D[R__NUM_SUN_CASCADES]; - struct _P + struct Point { Fmatrix world; Fmatrix view; Fmatrix project; Fmatrix combine; } P; - struct _S + struct Spot { Fmatrix view; Fmatrix project; diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 7f6133571be..c6e59e01ecc 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -12,7 +12,7 @@ void R_occlusion::occq_create(u32 limit) fids.reserve(limit); for (u32 it = 0; it < limit; it++) { - _Q q; + Query q; q.order = it; if (FAILED(CreateQuery(&q.Q, D3D_QUERY_OCCLUSION))) break; @@ -131,7 +131,7 @@ R_occlusion::occq_result R_occlusion::occq_get(u32& ID) RImplementation.BasicStats.OcclusionCulled++; // insert into pool (sorting in decreasing order) - _Q& Q = used[ID]; + Query& Q = used[ID]; if (pool.empty()) pool.push_back(Q); else diff --git a/src/Layers/xrRender/r__occlusion.h b/src/Layers/xrRender/r__occlusion.h index 6e0a2ac6a26..ceb6039b8f1 100644 --- a/src/Layers/xrRender/r__occlusion.h +++ b/src/Layers/xrRender/r__occlusion.h @@ -15,7 +15,7 @@ constexpr u32 occq_size = 2 * 768 * R__NUM_PARALLEL_CONTEXTS; // // queue for oc class R_occlusion { private: - struct _Q + struct Query { u32 order; #if defined(USE_DX9) || defined(USE_DX11) @@ -30,8 +30,8 @@ class R_occlusion static const u32 iInvalidHandle = 0xFFFFFFFF; BOOL enabled; // - xr_vector<_Q> pool; // sorted (max ... min), insertions are usually at the end - xr_vector<_Q> used; // id's are generated from this and it is cleared from back only + xr_vector pool; // sorted (max ... min), insertions are usually at the end + xr_vector used; // id's are generated from this and it is cleared from back only xr_vector fids; // free id's Lock render_lock{}; diff --git a/src/Layers/xrRender/r__sector_traversal.cpp b/src/Layers/xrRender/r__sector_traversal.cpp index 67ee6a890a6..1130299f619 100644 --- a/src/Layers/xrRender/r__sector_traversal.cpp +++ b/src/Layers/xrRender/r__sector_traversal.cpp @@ -81,7 +81,7 @@ void CPortalTraverser::fade_render() for (u32 _it = 0; _it < f_portals.size(); _it++) { std::pair& fp = f_portals[_it]; - CPortal* _P = fp.first; + CPortal* portal = fp.first; float _ssa = fp.second; float ssaDiff = _ssa - r_ssaLOD_B; float ssaScale = ssaDiff / ssaRange; @@ -90,14 +90,14 @@ void CPortalTraverser::fade_render() u32 _clr = subst_alpha(_ambient, u32(iA)); // fill polys - u32 _polys = _P->getPoly().size() - 2; + u32 _polys = portal->getPoly().size() - 2; for (u32 _pit = 0; _pit < _polys; _pit++) { - _v->set(_P->getPoly()[0], _clr); + _v->set(portal->getPoly()[0], _clr); _v++; - _v->set(_P->getPoly()[_pit + 1], _clr); + _v->set(portal->getPoly()[_pit + 1], _clr); _v++; - _v->set(_P->getPoly()[_pit + 2], _clr); + _v->set(portal->getPoly()[_pit + 2], _clr); _v++; } } diff --git a/src/Layers/xrRender/r_sun_cascades.h b/src/Layers/xrRender/r_sun_cascades.h index e2542f5495c..6daf950d341 100644 --- a/src/Layers/xrRender/r_sun_cascades.h +++ b/src/Layers/xrRender/r_sun_cascades.h @@ -5,7 +5,7 @@ namespace sun struct ray { ray() {} - ray(Fvector3 const& _P, Fvector3 const& _D) : D(_D), P(_P) {} + ray(Fvector3 const& pos, Fvector3 const& dir) : D(dir), P(pos) {} Fvector3 D; Fvector3 P; }; diff --git a/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp b/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp index 1820a0bfd8d..469bccbd98c 100644 --- a/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp +++ b/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp @@ -37,13 +37,13 @@ class adopt_dx10sampler u32 m_SI; // Sampler index public: - adopt_dx10sampler(CBlender_Compile* C, u32 SamplerIndex) : m_pC(C), m_SI(SamplerIndex) + adopt_dx10sampler(CBlender_Compile* compiler, u32 SamplerIndex) : m_pC(compiler), m_SI(SamplerIndex) { if (u32(-1) == m_SI) m_pC = nullptr; } - adopt_dx10sampler(const adopt_dx10sampler& _C) : m_pC(_C.m_pC), m_SI(_C.m_SI) + adopt_dx10sampler(const adopt_dx10sampler& other) : m_pC(other.m_pC), m_SI(other.m_SI) { if (u32(-1) == m_SI) m_pC = nullptr; @@ -56,13 +56,13 @@ class adopt_sampler u32 stage; // Sampler index public: - adopt_sampler(CBlender_Compile* _C, u32 _stage) : C(_C), stage(_stage) + adopt_sampler(CBlender_Compile* compiler, u32 _stage) : C(compiler), stage(_stage) { if (u32(-1) == stage) C = nullptr; } - adopt_sampler(const adopt_sampler& _C) : C(_C.C), stage(_C.stage) + adopt_sampler(const adopt_sampler& other) : C(other.C), stage(other.stage) { if (u32(-1) == stage) C = nullptr; @@ -206,8 +206,8 @@ class adopt_compiler } public: - adopt_compiler(CBlender_Compile* _C, bool& bFirstPass) : C(_C), m_bFirstPass(bFirstPass) { m_bFirstPass = true; } - adopt_compiler(const adopt_compiler& _C) : C(_C.C), m_bFirstPass(_C.m_bFirstPass) {} + adopt_compiler(CBlender_Compile* compiler, bool& bFirstPass) : C(compiler), m_bFirstPass(bFirstPass) { m_bFirstPass = true; } + adopt_compiler(const adopt_compiler& other) : C(other.C), m_bFirstPass(other.m_bFirstPass) {} adopt_compiler& _options(int P, bool S) { C->SetParams(P, S); @@ -245,7 +245,7 @@ class adopt_compiler C->PassSET_LightFog(FALSE, _fog); return *this; } - adopt_compiler& _ZB(bool _test, bool _write) + adopt_compiler& _zbuffer(bool _test, bool _write) { C->PassSET_ZB(_test, _write); return *this; @@ -377,7 +377,7 @@ void CResourceManager::LS_Load() .def("distort", &adopt_compiler::_o_distort, return_reference_to<1>()) .def("wmark", &adopt_compiler::_o_wmark, return_reference_to<1>()) .def("fog", &adopt_compiler::_fog, return_reference_to<1>()) - .def("zb", &adopt_compiler::_ZB, return_reference_to<1>()) + .def("zb", &adopt_compiler::_zbuffer, return_reference_to<1>()) .def("blend", &adopt_compiler::_blend, return_reference_to<1>()) .def("aref", &adopt_compiler::_aref, return_reference_to<1>()) // For compatibility only diff --git a/src/Layers/xrRenderGL/glResourceManager_Scripting.cpp b/src/Layers/xrRenderGL/glResourceManager_Scripting.cpp index 3bd91d9cf5f..5f0646fdd5c 100644 --- a/src/Layers/xrRenderGL/glResourceManager_Scripting.cpp +++ b/src/Layers/xrRenderGL/glResourceManager_Scripting.cpp @@ -31,8 +31,8 @@ class adopt_sampler CBlender_Compile* C; u32 stage; public: - adopt_sampler(CBlender_Compile* _C, u32 _stage) : C(_C), stage(_stage) { if (u32(-1) == stage) C = nullptr; } - adopt_sampler(const adopt_sampler& _C) : C(_C.C), stage(_C.stage) { if (u32(-1) == stage) C = nullptr; } + adopt_sampler(CBlender_Compile* c, u32 st) : C(c), stage(st) { if (u32(-1) == stage) C = nullptr; } + adopt_sampler(const adopt_sampler& other) : C(other.C), stage(other.stage) { if (u32(-1) == stage) C = nullptr; } adopt_sampler& _texture(LPCSTR texture) { @@ -176,8 +176,8 @@ class adopt_compiler } public: - adopt_compiler(CBlender_Compile* _C, bool& bFirstPass) : C(_C), m_bFirstPass(bFirstPass) { m_bFirstPass = true; } - adopt_compiler(const adopt_compiler& _C) : C(_C.C), m_bFirstPass(_C.m_bFirstPass) { } + adopt_compiler(CBlender_Compile* compiler, bool& bFirstPass) : C(compiler), m_bFirstPass(bFirstPass) { m_bFirstPass = true; } + adopt_compiler(const adopt_compiler& other) : C(other.C), m_bFirstPass(other.m_bFirstPass) { } adopt_compiler& _options(int P, bool S) { @@ -223,7 +223,7 @@ class adopt_compiler return *this; } - adopt_compiler& _ZB(bool _test, bool _write) + adopt_compiler& _zbuffer(bool _test, bool _write) { C->PassSET_ZB(_test, _write); return *this; @@ -351,7 +351,7 @@ void CResourceManager::LS_Load() .def("distort", &adopt_compiler::_o_distort, return_reference_to<1>()) .def("wmark", &adopt_compiler::_o_wmark, return_reference_to<1>()) .def("fog", &adopt_compiler::_fog, return_reference_to<1>()) - .def("zb", &adopt_compiler::_ZB, return_reference_to<1>()) + .def("zb", &adopt_compiler::_zbuffer, return_reference_to<1>()) .def("blend", &adopt_compiler::_blend, return_reference_to<1>()) .def("aref", &adopt_compiler::_aref, return_reference_to<1>()) // For compatibility only diff --git a/src/Layers/xrRenderPC_R1/LightPPA.cpp b/src/Layers/xrRenderPC_R1/LightPPA.cpp index 349494cd0e8..9764b248cc5 100644 --- a/src/Layers/xrRenderPC_R1/LightPPA.cpp +++ b/src/Layers/xrRenderPC_R1/LightPPA.cpp @@ -31,11 +31,11 @@ void cl_light_PR::setup(CBackend& cmd_list, R_constant* C) else RCache.set_c(C, P.x, P.y, P.z, 1.f / R); } -void cl_light_C::setup(CBackend& cmd_list, R_constant* C) +void cl_light_C::setup(CBackend& cmd_list, R_constant* constant) { - Fcolor _C = RImplementation.r1_dlight_light->color; - _C.mul_rgb(RImplementation.r1_dlight_scale); - RCache.set_c(C, _C.r, _C.g, _C.b, 1.f); + Fcolor color = RImplementation.r1_dlight_light->color; + color.mul_rgb(RImplementation.r1_dlight_scale); + RCache.set_c(constant, color.r, color.g, color.b, 1.f); } void cl_light_XFORM::setup(CBackend& cmd_list, R_constant* C) { RCache.set_c(C, RImplementation.r1_dlight_tcgen); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Layers/xrRenderPC_R1/LightShadows.cpp b/src/Layers/xrRenderPC_R1/LightShadows.cpp index b9b726deb5c..c584f5521b3 100644 --- a/src/Layers/xrRenderPC_R1/LightShadows.cpp +++ b/src/Layers/xrRenderPC_R1/LightShadows.cpp @@ -256,14 +256,14 @@ void CLightShadows::calculate() break; Lpos.y += .01f; //. hack to avoid light-in-the-center-of-object } - float _R = C.O->GetRenderData().visual->getVisData().sphere.R + 0.1f; - // Msg ("* o-r: %f",_R); - if (_dist < _R) + const float radius = C.O->GetRenderData().visual->getVisData().sphere.R + 0.1f; + // Msg ("* o-r: %f", radius); + if (_dist < radius) { Fvector Ldir; Ldir.sub(C.C, Lpos); Ldir.normalize(); - Lpos.mad(Lpos, Ldir, _dist - _R); + Lpos.mad(Lpos, Ldir, _dist - radius); // Msg ("* moving lpos"); } } diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index 7a894fbfa7e..e9fadbb20f7 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -192,16 +192,16 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) Resources->Evict(); // Vertex buffers { - xr_vector& _DC = alternative ? xDC : nDC; - xr_vector& _VB = alternative ? xVB : nVB; + xr_vector& decls = alternative ? xDC : nDC; + xr_vector& vbuffers = alternative ? xVB : nVB; // Use DX9-style declarators CStreamReader* fs = base_fs->open_chunk(fsL_VB); R_ASSERT2(fs, "Could not load geometry. File 'level.geom?' corrupted."); const u32 count = fs->r_u32(); - _DC.resize(count); - _VB.resize(count); + decls.resize(count); + vbuffers.resize(count); constexpr size_t buffer_size = (MAXD3DDECLLENGTH + 1) * sizeof(VertexElement); for (u32 i = 0; i < count; i++) @@ -212,8 +212,8 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) fs->advance(-(int)buffer_size); const u32 dcl_len = GetDeclLength(dcl) + 1; - _DC[i].resize(dcl_len); - fs->r(_DC[i].begin(), dcl_len * sizeof(VertexElement)); + decls[i].resize(dcl_len); + fs->r(decls[i].begin(), dcl_len * sizeof(VertexElement)); // count, size const u32 vCount = fs->r_u32(); @@ -225,10 +225,10 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) // Create and fill // TODO: DX11: Check fragmentation. // Check if buffer is less then 2048 kb - _VB[i].Create(vCount * vSize); - u8* pData = static_cast(_VB[i].Map()); + vbuffers[i].Create(vCount * vSize); + u8* pData = static_cast(vbuffers[i].Map()); fs->r(pData, vCount * vSize); - _VB[i].Unmap(true); // upload vertex data + vbuffers[i].Unmap(true); // upload vertex data // fs->advance (vCount*vSize); } @@ -237,11 +237,11 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) // Index buffers { - xr_vector& _IB = alternative ? xIB : nIB; + xr_vector& ibuffers = alternative ? xIB : nIB; CStreamReader* fs = base_fs->open_chunk(fsL_IB); const u32 count = fs->r_u32(); - _IB.resize(count); + ibuffers.resize(count); for (u32 i = 0; i < count; i++) { const u32 iCount = fs->r_u32(); @@ -252,10 +252,10 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) // Create and fill // TODO: DX11: Check fragmentation. // Check if buffer is less then 2048 kb - _IB[i].Create(iCount * 2); - u8* pData = static_cast(_IB[i].Map()); + ibuffers[i].Create(iCount * 2); + u8* pData = static_cast(ibuffers[i].Map()); fs->r(pData, iCount * 2); - _IB[i].Unmap(true); // upload index data + ibuffers[i].Unmap(true); // upload index data // fs().advance (iCount*2); } diff --git a/src/utils/xrAI/xr_graph_merge.cpp b/src/utils/xrAI/xr_graph_merge.cpp index 94283f8c51c..f7729e9315c 100644 --- a/src/utils/xrAI/xr_graph_merge.cpp +++ b/src/utils/xrAI/xr_graph_merge.cpp @@ -388,12 +388,12 @@ class CGraphMerger void read_levels(CInifile* Ini, xr_set& levels, bool rebuild_graph, xr_vector* needed_levels) { - LPCSTR _N, V; + pcstr field_name, field_value; string_path caFileName, file_name; - for (u32 k = 0; Ini->r_line("levels", k, &_N, &V); k++) + for (u32 k = 0; Ini->r_line("levels", k, &field_name, &field_value); k++) { string256 N; - xr_strcpy(N, _N); + xr_strcpy(N, field_name); xr_strlwr(N); if (!Ini->section_exist(N)) @@ -421,9 +421,9 @@ void read_levels(CInifile* Ini, xr_set& levels, bool rebuild_graph, } u8 id = Ini->r_u8(N, "id"); - auto _S = Ini->r_string(N, "name"); + cpcstr level_name = Ini->r_string(N, "name"); string256 S; - xr_strcpy(S, _S); + xr_strcpy(S, level_name); xr_strlwr(S); if (needed_levels) diff --git a/src/utils/xrDXT/dds/tPixel.h b/src/utils/xrDXT/dds/tPixel.h index 274cf6db43c..656a4bf8f47 100644 --- a/src/utils/xrDXT/dds/tPixel.h +++ b/src/utils/xrDXT/dds/tPixel.h @@ -41,7 +41,8 @@ inline float fClamp(float x, float lo, float hi) inline int fmod(int x, int size) { return x % size; } inline __int64 fmod(__int64 x, __int64 size) { return x % size; } inline unsigned __int64 fmod(unsigned __int64 x, unsigned __int64 size) { return x % size; } -inline float __cdecl fmod(float _X, float _Y) { return fmodf(_X, _Y); } +inline float __cdecl fmod(float x, float y) { return fmodf(x, y); } + // calcMaxMipmap // calculates max # of mipmap levels for given texture size inline size_t calcMaxMipmap(size_t w, size_t h) @@ -382,11 +383,6 @@ class q8w8v8u8_t } }; -#define _R 0 -#define _G 1 -#define _B 2 -#define _A 3 - class fpPixel { public: diff --git a/src/utils/xrLC/OGF_Face.h b/src/utils/xrLC/OGF_Face.h index ead186d455e..b5fadb8d892 100644 --- a/src/utils/xrLC/OGF_Face.h +++ b/src/utils/xrLC/OGF_Face.h @@ -95,10 +95,10 @@ struct OGF_Base Fvector C; float R; - OGF_Base(int _Level) + OGF_Base(int level) { bbox.invalidate(); - iLevel = _Level; + iLevel = level; bConnected = FALSE; Sector = 0xffff; } @@ -242,7 +242,7 @@ struct OGF_Node : public OGF_Base { xr_vector chields; - OGF_Node(int _L, u16 _Sector) : OGF_Base(_L) { Sector = _Sector; } + OGF_Node(int level, u16 _Sector) : OGF_Base(level) { Sector = _Sector; } void AddChield(u32 ID) { chields.push_back(ID); @@ -261,7 +261,7 @@ struct OGF_Node : public OGF_Base struct OGF_LOD : public OGF_Node { - OGF_LOD(int _L, u16 _Sector) : OGF_Node(_L, _Sector){}; + OGF_LOD(int level, u16 _Sector) : OGF_Node(level, _Sector){}; struct _vertex { diff --git a/src/utils/xrLC/xrMU_Model_export_OGF.cpp b/src/utils/xrLC/xrMU_Model_export_OGF.cpp index 81e9f3e024b..7b10bf36a10 100644 --- a/src/utils/xrLC/xrMU_Model_export_OGF.cpp +++ b/src/utils/xrLC/xrMU_Model_export_OGF.cpp @@ -94,8 +94,8 @@ void export_ogf(xrMU_Reference& mu_reference) { Fvector ptPos = F.v[lv].v; - base_color_c _C; - float _N = 0; + base_color_c color; + float n = 0; for (u32 v_it = 0; v_it < model->m_vertices.size(); v_it++) { @@ -110,14 +110,14 @@ void export_ogf(xrMU_Reference& mu_reference) float oA = 1 / (1 + 100 * oD * oD); vC = (baseC); vC.mul(oA); - _C.add(vC); - _N += oA; + color.add(vC); + n += oA; } - float s = 1 / (_N + EPS); - _C.mul(s); - F.v[lv].c_rgb_hemi = color_rgba(u8_clr(_C.rgb.x), u8_clr(_C.rgb.y), u8_clr(_C.rgb.z), u8_clr(_C.hemi)); - F.v[lv].c_sun = u8_clr(_C.sun); + float s = 1 / (n + EPS); + color.mul(s); + F.v[lv].c_rgb_hemi = color_rgba(u8_clr(color.rgb.x), u8_clr(color.rgb.y), u8_clr(color.rgb.z), u8_clr(color.hemi)); + F.v[lv].c_sun = u8_clr(color.sun); } } } diff --git a/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp b/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp index 79efffb5449..a6ad9def3ed 100644 --- a/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp +++ b/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp @@ -135,7 +135,7 @@ bool Place_Perpixel(L_rect& R, lm_layer* D, BOOL bRotate) BOOL _rect_place(L_rect& r, lm_layer* D) { L_rect R; - int _X; + int X_; u8* temp_surf; // Normal @@ -146,37 +146,37 @@ BOOL _rect_place(L_rect& r, lm_layer* D) { temp_surf = surface + _Y * c_LMAP_size; // accelerated part - for (_X = 0; _X < x_max - 8;) + for (X_ = 0; X_ < x_max - 8;) { #ifdef _M_X64 - __m128i init = _mm_set1_epi64x(*(temp_surf + _X)); + __m128i init = _mm_set1_epi64x(*(temp_surf + X_)); __m128i m64_cmp = _mm_cmpeq_epi8(init, _mm_setzero_si128()); __m128i m64_cmp_low = _mm_move_epi64(m64_cmp); __m128i m64_work = _mm_sad_epu8(m64_cmp_low, _mm_setzero_si128()); if (!_mm_cvtsi128_si32(m64_work)) { - _X += 8; + X_ += 8; continue; } #else - __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + _X), _mm_setzero_si64()); + __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + X_), _mm_setzero_si64()); __m64 m64_work = _mm_sad_pu8(m64_cmp, _mm_setzero_si64()); if (!_mm_cvtsi64_si32(m64_work)) { - _X += 8; + X_ += 8; continue; } #endif - if (temp_surf[_X]) + if (temp_surf[X_]) { - _X++; + X_++; continue; } - R.init(_X, _Y, _X + r.b.x, _Y + r.b.y); + R.init(X_, _Y, X_ + r.b.x, _Y + r.b.y); - _X++; + X_++; if (Place_Perpixel(R, D, FALSE)) { @@ -189,11 +189,11 @@ BOOL _rect_place(L_rect& r, lm_layer* D) } } // remainder part - for (; _X < x_max; _X++) + for (; X_ < x_max; X_++) { - if (temp_surf[_X]) + if (temp_surf[X_]) continue; - R.init(_X, _Y, _X + r.b.x, _Y + r.b.y); + R.init(X_, _Y, X_ + r.b.x, _Y + r.b.y); if (Place_Perpixel(R, D, FALSE)) { _rect_register(R, D, FALSE); @@ -215,37 +215,37 @@ BOOL _rect_place(L_rect& r, lm_layer* D) { temp_surf = surface + _Y * c_LMAP_size; // accelerated part - for (_X = 0; _X < x_max - 8;) + for (X_ = 0; X_ < x_max - 8;) { #ifdef _M_X64 - __m128i init = _mm_set1_epi64x(*(temp_surf + _X)); + __m128i init = _mm_set1_epi64x(*(temp_surf + X_)); __m128i m64_cmp = _mm_cmpeq_epi8(init, _mm_setzero_si128()); __m128i m64_cmp_low = _mm_move_epi64(m64_cmp); __m128i m64_work = _mm_sad_epu8(m64_cmp_low, _mm_setzero_si128()); if (!_mm_cvtsi128_si32(m64_work)) { - _X += 8; + X_ += 8; continue; } #else - __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + _X), _mm_setzero_si64()); + __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + X_), _mm_setzero_si64()); __m64 m64_work = _mm_sad_pu8(m64_cmp, _mm_setzero_si64()); if (!_mm_cvtsi64_si32(m64_work)) { - _X += 8; + X_ += 8; continue; } #endif - if (temp_surf[_X]) + if (temp_surf[X_]) { - _X++; + X_++; continue; } - R.init(_X, _Y, _X + r.b.y, _Y + r.b.x); + R.init(X_, _Y, X_ + r.b.y, _Y + r.b.x); - _X++; + X_++; if (Place_Perpixel(R, D, TRUE)) { @@ -258,11 +258,11 @@ BOOL _rect_place(L_rect& r, lm_layer* D) } } // remainder part - for (; _X < x_max; _X++) + for (; X_ < x_max; X_++) { - if (temp_surf[_X]) + if (temp_surf[X_]) continue; - R.init(_X, _Y, _X + r.b.y, _Y + r.b.x); + R.init(X_, _Y, X_ + r.b.y, _Y + r.b.x); if (Place_Perpixel(R, D, TRUE)) { _rect_register(R, D, TRUE); diff --git a/src/utils/xrLCUtil/xrThread.hpp b/src/utils/xrLCUtil/xrThread.hpp index 91b0ca5c6f5..d224e827b37 100644 --- a/src/utils/xrLCUtil/xrThread.hpp +++ b/src/utils/xrLCUtil/xrThread.hpp @@ -20,10 +20,10 @@ class XRLCUTIL_API CThread volatile float thPerformance; volatile BOOL thDestroyOnComplete; - CThread(u32 _ID, LogFunc log) + CThread(u32 id, LogFunc log) { this->log = log ? log : StubLog; - thID = _ID; + thID = id; thProgress = 0; thCompleted = FALSE; thMessages = TRUE; diff --git a/src/utils/xrLC_Light/xrDeflector.h b/src/utils/xrLC_Light/xrDeflector.h index d6ea05aadbf..9911403efc5 100644 --- a/src/utils/xrLC_Light/xrDeflector.h +++ b/src/utils/xrLC_Light/xrDeflector.h @@ -31,9 +31,9 @@ class XRLC_LIGHT_API CDeflector ~CDeflector(); static CDeflector* read_create(); - void OA_SetNormal(Fvector& _N) + void OA_SetNormal(const Fvector& n) { - normal.set(_N); + normal.set(n); normal.normalize(); VERIFY(_valid(normal)); } diff --git a/src/utils/xrLC_Light/xrMU_Model_Load.cpp b/src/utils/xrLC_Light/xrMU_Model_Load.cpp index 6ef3b964b55..fe12b117947 100644 --- a/src/utils/xrLC_Light/xrMU_Model_Load.cpp +++ b/src/utils/xrLC_Light/xrMU_Model_Load.cpp @@ -56,25 +56,25 @@ void xrMU_Model::Load(IReader& F, u32 version) _face* xrMU_Model::create_face(_vertex* v0, _vertex* v1, _vertex* v2, b_face& B) { - _face* _F = mu_faces_pool().create(); - _F->dwMaterial = u16(B.dwMaterial); - _F->dwMaterialGame = B.dwMaterialGame; + _face* face = mu_faces_pool().create(); + face->dwMaterial = u16(B.dwMaterial); + face->dwMaterialGame = B.dwMaterialGame; R_ASSERT(B.dwMaterialGame < 65536); // Vertices and adjacement info - _F->SetVertex(0, v0); - _F->SetVertex(1, v1); - _F->SetVertex(2, v2); + face->SetVertex(0, v0); + face->SetVertex(1, v1); + face->SetVertex(2, v2); // tc - _F->tc[0] = B.t[0]; - _F->tc[1] = B.t[1]; - _F->tc[2] = B.t[2]; - _F->CalcNormal(); + face->tc[0] = B.t[0]; + face->tc[1] = B.t[1]; + face->tc[2] = B.t[2]; + face->CalcNormal(); // register - m_faces.push_back(_F); - return _F; + m_faces.push_back(face); + return face; } _face* xrMU_Model::load_create_face(Fvector& P1, Fvector& P2, Fvector& P3, b_face& B) @@ -84,11 +84,11 @@ _face* xrMU_Model::load_create_face(Fvector& P1, Fvector& P2, Fvector& P3, b_fac _vertex* xrMU_Model::create_vertex(Fvector& P) { - _vertex* _V = mu_vertices_pool().create(); - _V->P = P; - _V->N.set(0, 0, 0); - m_vertices.push_back(_V); - return _V; + _vertex* vertex = mu_vertices_pool().create(); + vertex->P = P; + vertex->N.set(0, 0, 0); + m_vertices.push_back(vertex); + return vertex; } _vertex* xrMU_Model::load_create_vertex(Fvector& P) diff --git a/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp b/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp index 4fc389bdd6e..67f55a642f8 100644 --- a/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp +++ b/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp @@ -83,9 +83,9 @@ T simple_optimize(xr_vector& A, xr_vector& B, T2& _scale, T2& _bias) void o_test(int iA, int iB, int count, base_color* A, base_color* B, float& C, float& D) { - xr_vector _A, _B; - _A.resize(count); - _B.resize(count); + xr_vector A_, B_; + A_.resize(count); + B_.resize(count); for (int it = 0; it < count; it++) { base_color_c _a; @@ -94,11 +94,11 @@ void o_test(int iA, int iB, int count, base_color* A, base_color* B, float& C, f base_color_c _b; B[it]._get(_b); float* f_b = (float*)&_b; - _A[it] = f_a[iA]; - _B[it] = f_b[iB]; + A_[it] = f_a[iA]; + B_[it] = f_b[iB]; } // C=1, D=0; - simple_optimize(_A, _B, C, D); + simple_optimize(A_, B_, C, D); } void xrMU_Reference::calc_lighting() diff --git a/src/utils/xrSE_Factory/script_value_wrapper.h b/src/utils/xrSE_Factory/script_value_wrapper.h index e69ee5922f4..093e6836fde 100644 --- a/src/utils/xrSE_Factory/script_value_wrapper.h +++ b/src/utils/xrSE_Factory/script_value_wrapper.h @@ -10,26 +10,26 @@ #include "script_value.h" -template +template class CScriptValueWrapperImpl : public CScriptValue { private: typedef CScriptValue inherited; protected: - _type m_value; + T m_value; public: IC CScriptValueWrapperImpl(luabind::object object, LPCSTR name); virtual void assign(); - virtual _type* value(); + virtual T* value(); }; -template -class CScriptValueWrapper : public CScriptValueWrapperImpl<_type> +template +class CScriptValueWrapper : public CScriptValueWrapperImpl { private: - typedef CScriptValueWrapperImpl<_type> inherited; + typedef CScriptValueWrapperImpl inherited; public: IC CScriptValueWrapper(luabind::object object, LPCSTR name); diff --git a/src/utils/xrSE_Factory/script_value_wrapper_inline.h b/src/utils/xrSE_Factory/script_value_wrapper_inline.h index cb67bd2c370..c9600211d76 100644 --- a/src/utils/xrSE_Factory/script_value_wrapper_inline.h +++ b/src/utils/xrSE_Factory/script_value_wrapper_inline.h @@ -8,26 +8,26 @@ #pragma once -template -IC CScriptValueWrapperImpl<_type>::CScriptValueWrapperImpl(luabind::object object, LPCSTR name) +template +IC CScriptValueWrapperImpl::CScriptValueWrapperImpl(luabind::object object, LPCSTR name) : inherited(object, name) { - m_value = luabind::object_cast<_type>(object[name]); + m_value = luabind::object_cast(object[name]); } -template -IC void CScriptValueWrapperImpl<_type>::assign() +template +IC void CScriptValueWrapperImpl::assign() { m_object[*m_name] = m_value; } -template -IC _type* CScriptValueWrapperImpl<_type>::value() +template +IC T* CScriptValueWrapperImpl::value() { return (&m_value); } -template -IC CScriptValueWrapper<_type>::CScriptValueWrapper(luabind::object object, LPCSTR name) : inherited(object, name) +template +IC CScriptValueWrapper::CScriptValueWrapper(luabind::object object, LPCSTR name) : inherited(object, name) { } diff --git a/src/xrCDB/ISpatial.h b/src/xrCDB/ISpatial.h index 65338645bda..30ee17a46bf 100644 --- a/src/xrCDB/ISpatial.h +++ b/src/xrCDB/ISpatial.h @@ -171,8 +171,8 @@ class ISpatial_NODE xr_vector items; // own items void _init(ISpatial_NODE* _parent); - void _remove(ISpatial* _S); - void _insert(ISpatial* _S); + void _remove(ISpatial* S); + void _insert(ISpatial* S); bool _empty() { return items.empty() && diff --git a/src/xrCore/LocatorAPI_defs.h b/src/xrCore/LocatorAPI_defs.h index d514cb1264a..671d32d3130 100644 --- a/src/xrCore/LocatorAPI_defs.h +++ b/src/xrCore/LocatorAPI_defs.h @@ -61,7 +61,7 @@ struct XRCORE_API FS_File FS_File(const _FINDDATA_T& f); FS_File(const xr_string& nm, const _FINDDATA_T& f); FS_File(const xr_string& nm, long sz, time_t modif, unsigned attr); - bool operator<(const FS_File& _X) const { return xr_strcmp(name.c_str(), _X.name.c_str()) < 0; } + bool operator<(const FS_File& other) const { return xr_strcmp(name.c_str(), other.name.c_str()) < 0; } }; using FS_FileSet = xr_set; diff --git a/src/xrCore/_sphere.h b/src/xrCore/_sphere.h index fb619c2d847..40fc57020fc 100644 --- a/src/xrCore/_sphere.h +++ b/src/xrCore/_sphere.h @@ -8,10 +8,10 @@ struct Fsphere float R; public: - void set(const Fvector3& _P, float _R) + void set(const Fvector3& p, float r) { - P.set(_P); - R = _R; + P.set(p); + R = r; } void set(const Fsphere& S) diff --git a/src/xrEngine/CameraManager.cpp b/src/xrEngine/CameraManager.cpp index 6bb1cf01cd4..3794bd691ec 100644 --- a/src/xrEngine/CameraManager.cpp +++ b/src/xrEngine/CameraManager.cpp @@ -379,15 +379,15 @@ void CCameraManager::ResetPP() void CCameraManager::Dump() { Fmatrix mInvCamera; - Fvector _R, _U, _T, _P; - mInvCamera.invert(Device.mView); - _R.set(mInvCamera._11, mInvCamera._12, mInvCamera._13); - _U.set(mInvCamera._21, mInvCamera._22, mInvCamera._23); - _T.set(mInvCamera._31, mInvCamera._32, mInvCamera._33); - _P.set(mInvCamera._41, mInvCamera._42, mInvCamera._43); - Log("CCameraManager::Dump::vPosition = ", _P); - Log("CCameraManager::Dump::vDirection = ", _T); - Log("CCameraManager::Dump::vNormal = ", _U); - Log("CCameraManager::Dump::vRight = ", _R); + + const Fvector right{ mInvCamera._11, mInvCamera._12, mInvCamera._13 }; + const Fvector normal{ mInvCamera._21, mInvCamera._22, mInvCamera._23 }; + const Fvector direction{ mInvCamera._31, mInvCamera._32, mInvCamera._33 }; + const Fvector position{ mInvCamera._41, mInvCamera._42, mInvCamera._43 }; + + Log("CCameraManager::Dump::vPosition = ", position); + Log("CCameraManager::Dump::vDirection = ", direction); + Log("CCameraManager::Dump::vNormal = ", normal); + Log("CCameraManager::Dump::vRight = ", right); } diff --git a/src/xrEngine/xr_efflensflare.cpp b/src/xrEngine/xr_efflensflare.cpp index 7819cbc4214..ea41ed8f24d 100644 --- a/src/xrEngine/xr_efflensflare.cpp +++ b/src/xrEngine/xr_efflensflare.cpp @@ -210,8 +210,8 @@ struct STranspParam collide::ray_cache* pray_cache; float vis; float vis_threshold; - STranspParam(collide::ray_cache* p, const Fvector& _P, const Fvector& _D, float _f, float _vis_threshold) - : P(_P), D(_D), f(_f), pray_cache(p), vis(1.f), vis_threshold(_vis_threshold) + STranspParam(collide::ray_cache* cache, const Fvector& p, const Fvector& d, float fval, float _vis_threshold) + : P(p), D(d), f(fval), pray_cache(cache), vis(1.f), vis_threshold(_vis_threshold) { } }; diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index 5ba8e794ec9..ded0c276b92 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -124,12 +124,12 @@ class CCC_Help : public IConsole_Command for (it = Console->Commands.begin(); it != Console->Commands.end(); ++it) { IConsole_Command& C = *(it->second); - TStatus _S; - C.GetStatus(_S); - TInfo _I; - C.Info(_I); + TStatus status; + C.GetStatus(status); + TInfo info; + C.Info(info); - Msg("%-20s (%-10s) --- %s", C.Name(), _S, _I); + Msg("%-20s (%-10s) --- %s", C.Name(), status, info); } Log("Key: Ctrl + A === Select all "); Log("Key: Ctrl + C === Copy to clipboard "); diff --git a/src/xrGame/Level_network.cpp b/src/xrGame/Level_network.cpp index 0b336643478..d42b07475da 100644 --- a/src/xrGame/Level_network.cpp +++ b/src/xrGame/Level_network.cpp @@ -239,8 +239,8 @@ u32 CLevel::Objects_net_Save(NET_Packet* _Packet, u32 start, u32 max_object_size u32 position; for (; start < Objects.o_count(); start++) { - IGameObject* _P = Objects.o_get_by_iterator(start); - CGameObject* P = smart_cast(_P); + IGameObject* object = Objects.o_get_by_iterator(start); + CGameObject* P = smart_cast(object); // Msg ("save:iterating:%d:%s, size[%d]",P->ID(),*P->cName(), Packet.w_tell() ); if (P && !P->getDestroy() && P->net_SaveRelevant()) { diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 28aa270c43c..50392e35aec 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -260,12 +260,12 @@ float CSoundRender_Scene::get_occlusion_to(const Fvector& hear_pt, const Fvector geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, hear_pt, dir, range); const auto r_cnt = geom_DB.r_count(); - CDB::RESULT* _B = geom_DB.r_begin(); + CDB::RESULT* begin = geom_DB.r_begin(); if (0 != r_cnt) { for (size_t k = 0; k < r_cnt; k++) { - CDB::RESULT* R = _B + k; + CDB::RESULT* R = begin + k; occ_value *= *reinterpret_cast(&R->dummy); } } @@ -291,9 +291,9 @@ float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) { bool bNeedFullTest = true; // 1. Check cached polygon - float _u, _v, _range; - if (CDB::TestRayTri(base, dir, occ, _u, _v, _range, true)) - if (_range > 0 && _range < range) + float u, v, test_range; + if (CDB::TestRayTri(base, dir, occ, u, v, test_range, true)) + if (test_range > 0 && test_range < range) { occ_value = psSoundOcclusionScale; bNeedFullTest = false; @@ -322,12 +322,12 @@ float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) { geom_DB.ray_query(CDB::OPT_CULL, geom_SOM, base, dir, range); const auto r_cnt = geom_DB.r_count(); - CDB::RESULT* _B = geom_DB.r_begin(); + CDB::RESULT* begin = geom_DB.r_begin(); if (0 != r_cnt) { for (size_t k = 0; k < r_cnt; k++) { - CDB::RESULT* R2 = _B + k; + CDB::RESULT* R2 = begin + k; occ_value *= *reinterpret_cast(&R2->dummy); } } diff --git a/src/xrUICore/Lines/UILines.cpp b/src/xrUICore/Lines/UILines.cpp index bc771902cad..d445e7a6f79 100644 --- a/src/xrUICore/Lines/UILines.cpp +++ b/src/xrUICore/Lines/UILines.cpp @@ -209,7 +209,7 @@ void CUILines::ParseText(bool force) float curr_width = 0.0f; // XXX: use 'bnew_line' or remove it [[maybe_unused]] bool bnew_line = false; - float __eps = get_str_width(m_pFont, 'o'); // hack -( + float eps = get_str_width(m_pFont, 'o'); // hack -( for (u32 sbl_idx = 0; sbl_idx < sbl_cnt; ++sbl_idx) { bool b_last_subl = (sbl_idx == sbl_cnt - 1); @@ -226,7 +226,7 @@ void CUILines::ParseText(bool force) last_space_idx = idx; float w1 = get_str_width(m_pFont, sbl.m_text[idx]); - bool bOver = (curr_width + w1 + __eps > max_width); + bool bOver = (curr_width + w1 + eps > max_width); if (bOver || b_last_ch) { diff --git a/src/xrUICore/ProgressBar/UIProgressBar.cpp b/src/xrUICore/ProgressBar/UIProgressBar.cpp index af5077c78b6..3db384df4ba 100644 --- a/src/xrUICore/ProgressBar/UIProgressBar.cpp +++ b/src/xrUICore/ProgressBar/UIProgressBar.cpp @@ -73,9 +73,9 @@ void CUIProgressBar::UpdateProgressBar() } } -void CUIProgressBar::SetProgressPos(float _Pos) +void CUIProgressBar::SetProgressPos(float pos) { - m_ProgressPos.y = _Pos; + m_ProgressPos.y = pos; clamp(m_ProgressPos.y, m_MinPos, m_MaxPos); UpdateProgressBar(); } diff --git a/src/xrUICore/ProgressBar/UIProgressBar.h b/src/xrUICore/ProgressBar/UIProgressBar.h index 434ca75d256..b189d6b3e06 100644 --- a/src/xrUICore/ProgressBar/UIProgressBar.h +++ b/src/xrUICore/ProgressBar/UIProgressBar.h @@ -49,16 +49,16 @@ class XRUICORE_API CUIProgressBar final : public CUIWindow void InitProgressBar(Fvector2 pos, Fvector2 size, EOrientMode mode); - void SetRange(float _Min, float _Max) + void SetRange(float min, float max) { - m_MinPos = _Min; - m_MaxPos = _Max; + m_MinPos = min; + m_MaxPos = max; UpdateProgressBar(); } float GetRange_min() { return m_MinPos; } float GetRange_max() { return m_MaxPos; } - void SetProgressPos(float _Pos); + void SetProgressPos(float pos); void ForceSetProgressPos(float pos); float GetProgressPos() { return m_ProgressPos.y; } diff --git a/src/xrUICore/ProgressBar/UIProgressShape.cpp b/src/xrUICore/ProgressBar/UIProgressShape.cpp index 83f5ab033dd..b586d8716f1 100644 --- a/src/xrUICore/ProgressBar/UIProgressShape.cpp +++ b/src/xrUICore/ProgressBar/UIProgressShape.cpp @@ -29,13 +29,13 @@ void CUIProgressShape::SetPos(int pos, int max) } void CUIProgressShape::SetTextVisible(bool b) { m_bText = b; } -void _make_rot_pos(Fvector2& pt, float sin_a, float cos_a, float R1, float R2) +void make_rot_pos(Fvector2& pt, float sin_a, float cos_a, float R1, float R2) { pt.x = -R1 * sin_a; pt.y = -R2 * cos_a; } -void _make_rot_tex(Fvector2& pt, float src, float sin_a, float cos_a) +void make_rot_tex(Fvector2& pt, float src, float sin_a, float cos_a) { pt.x = src * sin_a; pt.y = src * cos_a; @@ -120,8 +120,8 @@ void CUIProgressShape::Draw() start_tex_pt.set(0.0f, -radius_tex); prev_tex_pt = start_tex_pt; - _make_rot_tex(prev_pos_pt, start_pos_pt.y, sin_a, cos_a); - _make_rot_tex(prev_tex_pt, start_tex_pt.y, sin_a, cos_a); + make_rot_tex(prev_pos_pt, start_pos_pt.y, sin_a, cos_a); + make_rot_tex(prev_tex_pt, start_tex_pt.y, sin_a, cos_a); float angle_range = PI_MUL_2; if (m_bClockwise) @@ -158,8 +158,8 @@ void CUIProgressShape::Draw() sin_a = _sin(curr_angle); cos_a = _cos(curr_angle); - _make_rot_tex(prev_pos_pt, start_pos_pt.y, sin_a, cos_a); - _make_rot_tex(prev_tex_pt, start_tex_pt.y, sin_a, cos_a); + make_rot_tex(prev_pos_pt, start_pos_pt.y, sin_a, cos_a); + make_rot_tex(prev_tex_pt, start_tex_pt.y, sin_a, cos_a); tp.set(prev_pos_pt); tp.add(center_pos); diff --git a/src/xrUICore/TrackBar/UITrackBar.cpp b/src/xrUICore/TrackBar/UITrackBar.cpp index acdedf35624..e131f5311e8 100644 --- a/src/xrUICore/TrackBar/UITrackBar.cpp +++ b/src/xrUICore/TrackBar/UITrackBar.cpp @@ -260,30 +260,29 @@ void CUITrackBar::UpdatePosRelativeToMouse() else if (fpos > window_width - btn_width / 2) fpos = window_width - btn_width / 2; - float __fval; - float __fmax = (m_b_is_float) ? m_f_max : (float)m_i_max; - float __fmin = (m_b_is_float) ? m_f_min : (float)m_i_min; - float __fstep = (m_b_is_float) ? m_f_step : (float)m_i_step; + const float fmax = (m_b_is_float) ? m_f_max : (float)m_i_max; + const float fmin = (m_b_is_float) ? m_f_min : (float)m_i_min; + const float fstep = (m_b_is_float) ? m_f_step : (float)m_i_step; - __fval = (__fmax - __fmin) * (fpos - btn_width / 2) / (window_width - btn_width) + __fmin; + float fval = (fmax - fmin) * (fpos - btn_width / 2) / (window_width - btn_width) + fmin; - float _d = (__fval - __fmin); + const float d = (fval - fmin); - float _v = _d / __fstep; - int _vi = iFloor(_v); - float _vf = __fstep * _vi; + const float val = d / fstep; + const int vi = iFloor(val); + float vf = fstep * vi; - if (_d - _vf > __fstep / 2.0f) - _vf += __fstep; + if (d - vf > fstep / 2.0f) + vf += fstep; - __fval = __fmin + _vf; + fval = fmin + vf; - clamp(__fval, __fmin, __fmax); + clamp(fval, fmin, fmax); if (m_b_is_float) - m_f_val = __fval; + m_f_val = fval; else - m_i_val = iFloor(__fval); + m_i_val = iFloor(fval); bool b_ch = false; if (m_b_is_float) @@ -320,11 +319,11 @@ void CUITrackBar::UpdatePos() float free_space = window_width - btn_width; Fvector2 pos = m_pSlider->GetWndPos(); - float __fval = (m_b_is_float) ? m_f_val : (float)m_i_val; - float __fmax = (m_b_is_float) ? m_f_max : (float)m_i_max; - float __fmin = (m_b_is_float) ? m_f_min : (float)m_i_min; + const float fval = (m_b_is_float) ? m_f_val : (float)m_i_val; + const float fmax = (m_b_is_float) ? m_f_max : (float)m_i_max; + const float fmin = (m_b_is_float) ? m_f_min : (float)m_i_min; - pos.x = (__fval - __fmin) * free_space / (__fmax - __fmin); + pos.x = (fval - fmin) * free_space / (fmax - fmin); if (GetInvert()) pos.x = free_space - pos.x; From 92b9d498d848ef149fee5d16e80fa63b098c6bc4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 13:23:23 +0500 Subject: [PATCH 098/497] GitHub Actions: disabled syncing files back from *BSD VMs due to VM stalls --- .github/workflows/cibuild.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 67cdd381fb1..073b58944cf 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -228,5 +228,18 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} - sync_files: vm-to-runner + shutdown_vm: false + sync_files: false run: cmake --build build --config ${{ matrix.Configuration }} --parallel 3 + + - name: Finalize + uses: cross-platform-actions/action@v0.22.0 + with: + operating_system: ${{ matrix.platform.os }} + architecture: ${{ matrix.platform.arch }} + version: ${{ matrix.platform.os-version }} + # sync back is disabled due to: + # 1) VM stalls during the process + # 2) we don't output artifacts anyway + sync_files: false #vm-to-runner + run: rm -rf build # reduce amount of files to copy back from VM From 89e8f61198a87cc232f943c330cd98f1cf28ce44 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 3 Jan 2024 13:21:14 +0500 Subject: [PATCH 099/497] GitHub Actions: build for OpenBSD --- .github/workflows/cibuild.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 073b58944cf..14fd5d47964 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -189,11 +189,11 @@ jobs: - { name: FreeBSD, os: freebsd, os-version: 13.2, arch: x86_64, install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" } - #- { name: OpenBSD, os: openbsd, os-version: 7.4, arch: x86_64, - # install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", - # } + - { name: OpenBSD, os: openbsd, os-version: 7.4, arch: x86_64, + install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", + } #- { name: NetBSD, os: netbsd, os-version: 9.3, arch: x86_64, - # install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis && export CC=gcc-13 && export CXX=g++-13", + # install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis", # } configuration: [Debug, Release] @@ -208,6 +208,7 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: runner-to-vm run: ${{ matrix.platform.install-cmd }} @@ -218,6 +219,7 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON @@ -228,6 +230,7 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false run: cmake --build build --config ${{ matrix.Configuration }} --parallel 3 From c7e225008e9eda53ab5d141bfc5f9530579994b2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 18:42:43 +0500 Subject: [PATCH 100/497] Fix FreeBSD build Oops, I broke it in 0121b93367850a3873d6edf6008261e13b660cad --- src/xrCore/_math.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 9305dc3e583..604c49422a9 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -176,7 +176,7 @@ void initialize() #if defined(XR_PLATFORM_WINDOWS) _clearfp(); #elif defined(USE_BSD_FP) - std::ignore = fpresetsticky(FP_X_INV | |FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP | FP_X_STK); + std::ignore = fpresetsticky(FP_X_INV | FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP | FP_X_STK); #else std::ignore = std::feclearexcept(FE_ALL_EXCEPT); #endif From 57423fa20552d9c044eb4e9ba7c9688d4baddc17 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 4 Jan 2024 19:02:33 +0500 Subject: [PATCH 101/497] Fix FreeBSD build --- src/xrCore/_math.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 604c49422a9..01cbe55f581 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -26,9 +26,7 @@ # include # define USE_BSD_FP # endif -#endif -#if !defined(XR_PLATFORM_WINDOWS) && !defined(USE_GLIBC_FPU_CONTROL) && !defined(USE_BSD_FP) # include # pragma STDC FENV_ACCESS on #endif @@ -175,8 +173,6 @@ void initialize() { #if defined(XR_PLATFORM_WINDOWS) _clearfp(); -#elif defined(USE_BSD_FP) - std::ignore = fpresetsticky(FP_X_INV | FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP | FP_X_STK); #else std::ignore = std::feclearexcept(FE_ALL_EXCEPT); #endif From b872f29ab9c2b1aa14d63e688645bf8daefcb6ac Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 5 Jan 2024 02:07:21 +0500 Subject: [PATCH 102/497] GitHub Actions: fix BSD finalization failure --- .github/workflows/cibuild.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index dc9effcd9f2..534417efe45 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -242,6 +242,7 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + environment_variables: CFLAGS CXXFLAGS # sync back is disabled due to: # 1) VM stalls during the process # 2) we don't output artifacts anyway From b2da973f2521c6df80bd1f03c149e90e4ff92cd6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 5 Jan 2024 02:07:46 +0500 Subject: [PATCH 103/497] GitHub Actions: increase timeout to 45 minutes for *BSD builds --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 534417efe45..d84f10a1890 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -179,7 +179,7 @@ jobs: bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} runs-on: macos-latest - timeout-minutes: 30 + timeout-minutes: 45 env: CFLAGS: "-w" CXXFLAGS: "-w" From 9ae70f8fdbc40e4d9c42a6ca84243660e70779a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:38:52 +0000 Subject: [PATCH 104/497] build(deps): bump Externals/sse2neon from `25e2a60` to `60ecccb` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `25e2a60` to `60ecccb`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/25e2a601a06cbd97538bbe422a46bba3655763b9...60ecccbc219fed1aabf10b41d9762972a01e2914) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 25e2a601a06..60ecccbc219 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 25e2a601a06cbd97538bbe422a46bba3655763b9 +Subproject commit 60ecccbc219fed1aabf10b41d9762972a01e2914 From 44ca014e8dce568ac027298592b649a3e1d6fa0e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Jan 2024 10:19:16 +0500 Subject: [PATCH 105/497] Update imgui submodule --- Externals/imgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/imgui b/Externals/imgui index f8704cd085c..e3d7cd665d9 160000 --- a/Externals/imgui +++ b/Externals/imgui @@ -1 +1 @@ -Subproject commit f8704cd085c4347f835c21dc12a3951924143872 +Subproject commit e3d7cd665d9b8cf7c78166ed774bf47e502dd6be From 692666fbab83bb0847bd6b16a43b6ceb8ebeb3d1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Jan 2024 12:58:37 +0500 Subject: [PATCH 106/497] Common/PlatformWindows.inl: disable more Windows.h features --- src/Common/PlatformWindows.inl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Common/PlatformWindows.inl b/src/Common/PlatformWindows.inl index fdebbd48f95..60bee05ca7d 100644 --- a/src/Common/PlatformWindows.inl +++ b/src/Common/PlatformWindows.inl @@ -46,6 +46,17 @@ #define NODEFERWINDOWPOS #define NOMCX #define NOIME +#define NODESKTOP +#define NOWINDOWSTATION +#define NOSECURITY +#define NONCMESSAGES +#define NOTRACKMOUSEEVENT +#define NOKEYSTATES +#define NOTRACKMOUSEEVENT +#define NODEFERWINDOWPOS +#define NOMDI +#define NOWINABLE +#define NO_STATE_FLAGS #define DOSWIN32 #define _WIN32_DCOM From 7ce51b5af21260b3072f2a97c54ce93da114374a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:54:58 +0000 Subject: [PATCH 107/497] build(deps): bump Externals/sse2neon from `60ecccb` to `cfaa59f` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `60ecccb` to `cfaa59f`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/60ecccbc219fed1aabf10b41d9762972a01e2914...cfaa59fc04fecb117c0a0f3fe9c82dece6f359ad) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 60ecccbc219..cfaa59fc04f 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 60ecccbc219fed1aabf10b41d9762972a01e2914 +Subproject commit cfaa59fc04fecb117c0a0f3fe9c82dece6f359ad From a86012a213f51d6873d2227c4175263158cca005 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:30:16 +0000 Subject: [PATCH 108/497] build(deps): bump Externals/zlib from `643e17b` to `c06dfec` Bumps [Externals/zlib](https://github.com/madler/zlib) from `643e17b` to `c06dfec`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/643e17b7498d12ab8d15565662880579692f769d...c06dfecb8a0c996dce87148b9086f0fe79734f32) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 643e17b7498..c06dfecb8a0 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 643e17b7498d12ab8d15565662880579692f769d +Subproject commit c06dfecb8a0c996dce87148b9086f0fe79734f32 From 7488027e669276bb7c29bb45e2382157f5186fce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:25:55 +0000 Subject: [PATCH 109/497] build(deps): bump Externals/zlib from `c06dfec` to `f1f503d` Bumps [Externals/zlib](https://github.com/madler/zlib) from `c06dfec` to `f1f503d`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/c06dfecb8a0c996dce87148b9086f0fe79734f32...f1f503da85d52e56aae11557b4d79a42bcaa2b86) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index c06dfecb8a0..f1f503da85d 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit c06dfecb8a0c996dce87148b9086f0fe79734f32 +Subproject commit f1f503da85d52e56aae11557b4d79a42bcaa2b86 From 4f05eeee3238daba12083b8604387ce9577ac74f Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Thu, 1 Feb 2024 14:34:01 +0500 Subject: [PATCH 110/497] Fixed build under macOS 13 and higher (#1598) Added macOS M1 build using GitHub Actions Unified Linux and macOS build steps in cibuild.yml --- .github/workflows/cibuild.yml | 56 ++++++++++------------------ Externals/LuaJIT-proj/CMakeLists.txt | 2 + 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index d84f10a1890..540d14f0233 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -67,9 +67,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload --clobber latest-nightly (get-item res/*.*.7z) - linux: - name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc || 'gcc' }}) - runs-on: ubuntu-latest + cmake: + name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc || 'unknown compiler' }}) + runs-on: ${{ matrix.platform.os }} container: ${{ matrix.platform.container || '' }} @@ -85,18 +85,20 @@ jobs: fail-fast: false matrix: platform: - - { name: Ubuntu, arch: amd64, cc: gcc, cxx: g++, } - - { name: Ubuntu, arch: amd64, cc: clang, cxx: clang++, } - #- { name: Ubuntu, arch: arm64, container: 'dockcross/linux-arm64', } - #- { name: Ubuntu, arch: ppc64el, container: 'dockcross/linux-ppc64le:latest', } - - { name: Alpine, arch: x86_64, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } - - { name: Alpine, arch: x86, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } - #- { name: Haiku, arch: x86_64, container: 'haiku/cross-compiler:x86_64-r1beta4', cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, } + - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: gcc, cxx: g++, } + - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: clang, cxx: clang++, } + #- { name: Ubuntu, os: ubuntu-latest, arch: arm64, cc: gcc, cxx: g++, container: 'dockcross/linux-arm64', } + #- { name: Ubuntu, os: ubuntu-latest, arch: ppc64el, cc: gcc, cxx: g++, container: 'dockcross/linux-ppc64le:latest', } + - { name: Alpine, os: ubuntu-latest, arch: x86_64, cc: gcc, cxx: g++, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + - { name: Alpine, os: ubuntu-latest, arch: x86, cc: gcc, cxx: g++, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + #- { name: Haiku, os: ubuntu-latest, arch: x86_64, cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, container: 'haiku/cross-compiler:x86_64-r1beta4', } + - { name: macOS, os: macos-13, arch: x86_64, cc: clang, cxx: clang++, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=13.6" } + - { name: macOS, os: macos-14, arch: arm64, cc: clang, cxx: clang++, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0" } configuration: [Debug, Release] steps: - - name: Install latest stable Alpine Linux + - name: Install latest stable Alpine Linux and packages if: ${{ matrix.platform.name == 'Alpine' }} uses: jirutka/setup-alpine@master with: @@ -119,6 +121,12 @@ jobs: libtheora-dev:${{ matrix.platform.arch }} \ libvorbis-dev:${{ matrix.platform.arch }} + - name: Install macOS packages + if: ${{ matrix.platform.name == 'macOS' }} + run: | + brew update + brew install sdl2 glew lzo libogg libvorbis theora + - name: Set environment variables if: ${{ matrix.platform.cc != '' }} run: | @@ -134,7 +142,7 @@ jobs: - name: Run CMake Build id: cmake-build - run: cmake --build build --config ${{ matrix.configuration }} --parallel $(nproc || echo 4) + run: cmake --build build --config ${{ matrix.configuration }} --parallel $(nproc || sysctl -n hw.ncpu || echo 4) - name: Make package if: ${{ steps.cmake-build.outcome == 'success' && matrix.platform.name == 'Ubuntu' }} @@ -152,30 +160,6 @@ jobs: name: openxray_1.6.02_${{ matrix.configuration }}_${{ matrix.platform.arch }}_(github-${{ matrix.platform.cc }}-${{ github.run_number }}).deb path: build/openxray_1.6.02_*.deb - macos: - name: macOS ${{ matrix.Configuration }} ${{ matrix.Platform }} - runs-on: macos-latest - strategy: - fail-fast: false - matrix: - Configuration: [Debug, Release] - - steps: - - uses: actions/checkout@main - with: - submodules: recursive - - - name: Install packages - run: | - brew update - brew install sdl2 glew lzo libogg libvorbis theora - - - name: Run CMake - run: CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON - - - name: Run CMake Build - run: cmake --build build --config ${{ matrix.Configuration }} --parallel $(sysctl -n hw.ncpu || echo 4) - bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} runs-on: macos-latest diff --git a/Externals/LuaJIT-proj/CMakeLists.txt b/Externals/LuaJIT-proj/CMakeLists.txt index 9ec04fd9894..58eae7997bb 100644 --- a/Externals/LuaJIT-proj/CMakeLists.txt +++ b/Externals/LuaJIT-proj/CMakeLists.txt @@ -60,6 +60,7 @@ set(LUA_INIT "LUA_INIT" CACHE STRING "Environment variable for initial script") if (APPLE) set(ENV{SDKROOT} ${CMAKE_OSX_SYSROOT}) + set(ENV{MACOSX_DEPLOYMENT_TARGET} ${CMAKE_OSX_DEPLOYMENT_TARGET}) endif() # Clean unnecessary files in LuaJIT source directory @@ -345,6 +346,7 @@ if (NOT PROJECT_PLATFORM_E2K) -B${MINILUA_BINARY_DIR} -G${CMAKE_GENERATOR} -S${CMAKE_CURRENT_SOURCE_DIR}/HostBuildTools/minilua + -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} -DCMAKE_BUILD_TYPE=Release -DLUAJIT_DIR=${LUAJIT_DIR} From b6bfab7a0337b8d5841bdc9554ab8a1e1b68f047 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 17:48:24 +0500 Subject: [PATCH 111/497] Common: Moved d3d9 specific types to d3d9compat.hpp --- src/Common/Common.vcxproj | 1 + src/Common/Common.vcxproj.filters | 1 + src/Common/PlatformApple.inl | 601 --------------------------- src/Common/PlatformBSD.inl | 601 --------------------------- src/Common/PlatformLinux.inl | 601 --------------------------- src/Common/d3d9compat.hpp | 602 ++++++++++++++++++++++++++++ src/Layers/xrRenderGL/CommonTypes.h | 2 + 7 files changed, 606 insertions(+), 1803 deletions(-) create mode 100644 src/Common/d3d9compat.hpp diff --git a/src/Common/Common.vcxproj b/src/Common/Common.vcxproj index a36b85aa06a..bfa5fe31330 100644 --- a/src/Common/Common.vcxproj +++ b/src/Common/Common.vcxproj @@ -54,6 +54,7 @@ + diff --git a/src/Common/Common.vcxproj.filters b/src/Common/Common.vcxproj.filters index 96a3b808832..6269d792325 100644 --- a/src/Common/Common.vcxproj.filters +++ b/src/Common/Common.vcxproj.filters @@ -92,6 +92,7 @@ Externals + diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 140dfcb8d74..5300dfacd93 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -452,590 +452,6 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define SEM_FAILCRITICALERRORS 1 #define SetErrorMode(x) {} -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ - ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) -#endif - -typedef enum _D3DFORMAT { - D3DFMT_UNKNOWN = 0, - - D3DFMT_R8G8B8 = 20, - D3DFMT_A8R8G8B8 = 21, - D3DFMT_X8R8G8B8 = 22, - D3DFMT_R5G6B5 = 23, - D3DFMT_X1R5G5B5 = 24, - D3DFMT_A1R5G5B5 = 25, - D3DFMT_A4R4G4B4 = 26, - D3DFMT_R3G3B2 = 27, - D3DFMT_A8 = 28, - D3DFMT_A8R3G3B2 = 29, - D3DFMT_X4R4G4B4 = 30, - D3DFMT_A2B10G10R10 = 31, - D3DFMT_A8B8G8R8 = 32, - D3DFMT_X8B8G8R8 = 33, - D3DFMT_G16R16 = 34, - D3DFMT_A2R10G10B10 = 35, - D3DFMT_A16B16G16R16 = 36, - - - D3DFMT_A8P8 = 40, - D3DFMT_P8 = 41, - - D3DFMT_L8 = 50, - D3DFMT_A8L8 = 51, - D3DFMT_A4L4 = 52, - - D3DFMT_V8U8 = 60, - D3DFMT_L6V5U5 = 61, - D3DFMT_X8L8V8U8 = 62, - D3DFMT_Q8W8V8U8 = 63, - D3DFMT_V16U16 = 64, - D3DFMT_A2W10V10U10 = 67, - - D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), - D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), - D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), - D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), - D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), - D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), - D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), - D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M', 'E', 'T', '1'), - D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), - D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), - - D3DFMT_D16_LOCKABLE = 70, - D3DFMT_D32 = 71, - D3DFMT_D15S1 = 73, - D3DFMT_D24S8 = 75, - D3DFMT_D24X8 = 77, - D3DFMT_D24X4S4 = 79, - D3DFMT_D16 = 80, - D3DFMT_L16 = 81, - D3DFMT_D32F_LOCKABLE = 82, - D3DFMT_D24FS8 = 83, - - D3DFMT_VERTEXDATA = 100, - D3DFMT_INDEX16 = 101, - D3DFMT_INDEX32 = 102, - D3DFMT_Q16W16V16U16 = 110, - /* Floating point formats */ - D3DFMT_R16F = 111, - D3DFMT_G16R16F = 112, - D3DFMT_A16B16G16R16F = 113, - - /* IEEE formats */ - D3DFMT_R32F = 114, - D3DFMT_G32R32F = 115, - D3DFMT_A32B32G32R32F = 116, - - D3DFMT_CxV8U8 = 117, - - - D3DFMT_FORCE_DWORD = 0xFFFFFFFF -} D3DFORMAT; - -typedef enum _D3DCULL { - D3DCULL_NONE = 1, - D3DCULL_CW = 2, - D3DCULL_CCW = 3, - - D3DCULL_FORCE_DWORD = 0x7fffffff -} D3DCULL; - -typedef enum _D3DCMPFUNC { - D3DCMP_NEVER = 1, - D3DCMP_LESS = 2, - D3DCMP_EQUAL = 3, - D3DCMP_LESSEQUAL = 4, - D3DCMP_GREATER = 5, - D3DCMP_NOTEQUAL = 6, - D3DCMP_GREATEREQUAL = 7, - D3DCMP_ALWAYS = 8, - - D3DCMP_FORCE_DWORD = 0x7fffffff -} D3DCMPFUNC; - -typedef enum _D3DSTENCILOP { - D3DSTENCILOP_KEEP = 1, - D3DSTENCILOP_ZERO = 2, - D3DSTENCILOP_REPLACE = 3, - D3DSTENCILOP_INCRSAT = 4, - D3DSTENCILOP_DECRSAT = 5, - D3DSTENCILOP_INVERT = 6, - D3DSTENCILOP_INCR = 7, - D3DSTENCILOP_DECR = 8, - - D3DSTENCILOP_FORCE_DWORD = 0x7fffffff -} D3DSTENCILOP; - -typedef enum _D3DBLEND { - D3DBLEND_ZERO = 1, - D3DBLEND_ONE = 2, - D3DBLEND_SRCCOLOR = 3, - D3DBLEND_INVSRCCOLOR = 4, - D3DBLEND_SRCALPHA = 5, - D3DBLEND_INVSRCALPHA = 6, - D3DBLEND_DESTALPHA = 7, - D3DBLEND_INVDESTALPHA = 8, - D3DBLEND_DESTCOLOR = 9, - D3DBLEND_INVDESTCOLOR = 10, - D3DBLEND_SRCALPHASAT = 11, - D3DBLEND_BOTHSRCALPHA = 12, - D3DBLEND_BOTHINVSRCALPHA = 13, - D3DBLEND_BLENDFACTOR = 14, - D3DBLEND_INVBLENDFACTOR = 15, - D3DBLEND_FORCE_DWORD = 0x7fffffff -} D3DBLEND; - -typedef enum _D3DBLENDOP { - D3DBLENDOP_ADD = 1, - D3DBLENDOP_SUBTRACT = 2, - D3DBLENDOP_REVSUBTRACT = 3, - D3DBLENDOP_MIN = 4, - D3DBLENDOP_MAX = 5, - - D3DBLENDOP_FORCE_DWORD = 0x7fffffff -} D3DBLENDOP; - -typedef struct _D3DVERTEXELEMENT9 { - WORD Stream; - WORD Offset; - BYTE Type; - BYTE Method; - BYTE Usage; - BYTE UsageIndex; -} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; - -#define MAXD3DDECLLENGTH 64 /* +end marker */ - -#define D3DFVF_RESERVED0 0x0001 -#define D3DFVF_POSITION_MASK 0x400E -#define D3DFVF_XYZ 0x0002 -#define D3DFVF_XYZRHW 0x0004 -#define D3DFVF_XYZB1 0x0006 -#define D3DFVF_XYZB2 0x0008 -#define D3DFVF_XYZB3 0x000a -#define D3DFVF_XYZB4 0x000c -#define D3DFVF_XYZB5 0x000e -#define D3DFVF_XYZW 0x4002 -#define D3DFVF_NORMAL 0x0010 -#define D3DFVF_PSIZE 0x0020 -#define D3DFVF_DIFFUSE 0x0040 -#define D3DFVF_SPECULAR 0x0080 -#define D3DFVF_TEXCOUNT_MASK 0x0f00 -#define D3DFVF_TEXCOUNT_SHIFT 8 -#define D3DFVF_TEX0 0x0000 -#define D3DFVF_TEX1 0x0100 -#define D3DFVF_TEX2 0x0200 -#define D3DFVF_TEX3 0x0300 -#define D3DFVF_TEX4 0x0400 -#define D3DFVF_TEX5 0x0500 -#define D3DFVF_TEX6 0x0600 -#define D3DFVF_TEX7 0x0700 -#define D3DFVF_TEX8 0x0800 -#define D3DFVF_LASTBETA_UBYTE4 0x1000 -#define D3DFVF_LASTBETA_D3DCOLOR 0x8000 -#define D3DFVF_RESERVED2 0x6000 - -typedef enum _D3DPRIMITIVETYPE { - D3DPT_POINTLIST = 1, - D3DPT_LINELIST = 2, - D3DPT_LINESTRIP = 3, - D3DPT_TRIANGLELIST = 4, - D3DPT_TRIANGLESTRIP = 5, - D3DPT_TRIANGLEFAN = 6, - - D3DPT_FORCE_DWORD = 0x7fffffff -} D3DPRIMITIVETYPE; - -typedef enum _D3DRENDERSTATETYPE { - D3DRS_ZENABLE = 7, - D3DRS_FILLMODE = 8, - D3DRS_SHADEMODE = 9, - D3DRS_ZWRITEENABLE = 14, - D3DRS_ALPHATESTENABLE = 15, - D3DRS_LASTPIXEL = 16, - D3DRS_SRCBLEND = 19, - D3DRS_DESTBLEND = 20, - D3DRS_CULLMODE = 22, - D3DRS_ZFUNC = 23, - D3DRS_ALPHAREF = 24, - D3DRS_ALPHAFUNC = 25, - D3DRS_DITHERENABLE = 26, - D3DRS_ALPHABLENDENABLE = 27, - D3DRS_FOGENABLE = 28, - D3DRS_SPECULARENABLE = 29, - D3DRS_FOGCOLOR = 34, - D3DRS_FOGTABLEMODE = 35, - D3DRS_FOGSTART = 36, - D3DRS_FOGEND = 37, - D3DRS_FOGDENSITY = 38, - D3DRS_RANGEFOGENABLE = 48, - D3DRS_STENCILENABLE = 52, - D3DRS_STENCILFAIL = 53, - D3DRS_STENCILZFAIL = 54, - D3DRS_STENCILPASS = 55, - D3DRS_STENCILFUNC = 56, - D3DRS_STENCILREF = 57, - D3DRS_STENCILMASK = 58, - D3DRS_STENCILWRITEMASK = 59, - D3DRS_TEXTUREFACTOR = 60, - D3DRS_WRAP0 = 128, - D3DRS_WRAP1 = 129, - D3DRS_WRAP2 = 130, - D3DRS_WRAP3 = 131, - D3DRS_WRAP4 = 132, - D3DRS_WRAP5 = 133, - D3DRS_WRAP6 = 134, - D3DRS_WRAP7 = 135, - D3DRS_CLIPPING = 136, - D3DRS_LIGHTING = 137, - D3DRS_AMBIENT = 139, - D3DRS_FOGVERTEXMODE = 140, - D3DRS_COLORVERTEX = 141, - D3DRS_LOCALVIEWER = 142, - D3DRS_NORMALIZENORMALS = 143, - D3DRS_DIFFUSEMATERIALSOURCE = 145, - D3DRS_SPECULARMATERIALSOURCE = 146, - D3DRS_AMBIENTMATERIALSOURCE = 147, - D3DRS_EMISSIVEMATERIALSOURCE = 148, - D3DRS_VERTEXBLEND = 151, - D3DRS_CLIPPLANEENABLE = 152, - D3DRS_POINTSIZE = 154, - D3DRS_POINTSIZE_MIN = 155, - D3DRS_POINTSPRITEENABLE = 156, - D3DRS_POINTSCALEENABLE = 157, - D3DRS_POINTSCALE_A = 158, - D3DRS_POINTSCALE_B = 159, - D3DRS_POINTSCALE_C = 160, - D3DRS_MULTISAMPLEANTIALIAS = 161, - D3DRS_MULTISAMPLEMASK = 162, - D3DRS_PATCHEDGESTYLE = 163, - D3DRS_DEBUGMONITORTOKEN = 165, - D3DRS_POINTSIZE_MAX = 166, - D3DRS_INDEXEDVERTEXBLENDENABLE = 167, - D3DRS_COLORWRITEENABLE = 168, - D3DRS_TWEENFACTOR = 170, - D3DRS_BLENDOP = 171, - D3DRS_POSITIONDEGREE = 172, - D3DRS_NORMALDEGREE = 173, - D3DRS_SCISSORTESTENABLE = 174, - D3DRS_SLOPESCALEDEPTHBIAS = 175, - D3DRS_ANTIALIASEDLINEENABLE = 176, - D3DRS_MINTESSELLATIONLEVEL = 178, - D3DRS_MAXTESSELLATIONLEVEL = 179, - D3DRS_ADAPTIVETESS_X = 180, - D3DRS_ADAPTIVETESS_Y = 181, - D3DRS_ADAPTIVETESS_Z = 182, - D3DRS_ADAPTIVETESS_W = 183, - D3DRS_ENABLEADAPTIVETESSELLATION= 184, - D3DRS_TWOSIDEDSTENCILMODE = 185, - D3DRS_CCW_STENCILFAIL = 186, - D3DRS_CCW_STENCILZFAIL = 187, - D3DRS_CCW_STENCILPASS = 188, - D3DRS_CCW_STENCILFUNC = 189, - D3DRS_COLORWRITEENABLE1 = 190, - D3DRS_COLORWRITEENABLE2 = 191, - D3DRS_COLORWRITEENABLE3 = 192, - D3DRS_BLENDFACTOR = 193, - D3DRS_SRGBWRITEENABLE = 194, - D3DRS_DEPTHBIAS = 195, - D3DRS_WRAP8 = 198, - D3DRS_WRAP9 = 199, - D3DRS_WRAP10 = 200, - D3DRS_WRAP11 = 201, - D3DRS_WRAP12 = 202, - D3DRS_WRAP13 = 203, - D3DRS_WRAP14 = 204, - D3DRS_WRAP15 = 205, - D3DRS_SEPARATEALPHABLENDENABLE = 206, - D3DRS_SRCBLENDALPHA = 207, - D3DRS_DESTBLENDALPHA = 208, - D3DRS_BLENDOPALPHA = 209, - - D3DRS_FORCE_DWORD = 0x7fffffff -} D3DRENDERSTATETYPE; - -/* Macro to deal with LP64 <=> LLP64 differences in numeric constants with 'l' modifier */ -#ifndef __MSABI_LONG -# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) -# define __MSABI_LONG(x) x ## l -# else -# define __MSABI_LONG(x) x -# endif -#endif - -#define D3DCOLORWRITEENABLE_RED (__MSABI_LONG(1)<<0) -#define D3DCOLORWRITEENABLE_GREEN (__MSABI_LONG(1)<<1) -#define D3DCOLORWRITEENABLE_BLUE (__MSABI_LONG(1)<<2) -#define D3DCOLORWRITEENABLE_ALPHA (__MSABI_LONG(1)<<3) - -typedef enum _D3DTEXTURESTAGESTATETYPE { - D3DTSS_COLOROP = 1, - D3DTSS_COLORARG1 = 2, - D3DTSS_COLORARG2 = 3, - D3DTSS_ALPHAOP = 4, - D3DTSS_ALPHAARG1 = 5, - D3DTSS_ALPHAARG2 = 6, - D3DTSS_BUMPENVMAT00 = 7, - D3DTSS_BUMPENVMAT01 = 8, - D3DTSS_BUMPENVMAT10 = 9, - D3DTSS_BUMPENVMAT11 = 10, - D3DTSS_TEXCOORDINDEX = 11, - D3DTSS_BUMPENVLSCALE = 22, - D3DTSS_BUMPENVLOFFSET = 23, - D3DTSS_TEXTURETRANSFORMFLAGS = 24, - D3DTSS_COLORARG0 = 26, - D3DTSS_ALPHAARG0 = 27, - D3DTSS_RESULTARG = 28, - D3DTSS_CONSTANT = 32, - - D3DTSS_FORCE_DWORD = 0x7fffffff -} D3DTEXTURESTAGESTATETYPE; - -typedef enum _D3DTEXTUREOP { - D3DTOP_DISABLE = 1, - D3DTOP_SELECTARG1 = 2, - D3DTOP_SELECTARG2 = 3, - D3DTOP_MODULATE = 4, - D3DTOP_MODULATE2X = 5, - D3DTOP_MODULATE4X = 6, - D3DTOP_ADD = 7, - D3DTOP_ADDSIGNED = 8, - D3DTOP_ADDSIGNED2X = 9, - D3DTOP_SUBTRACT = 10, - D3DTOP_ADDSMOOTH = 11, - D3DTOP_BLENDDIFFUSEALPHA = 12, - D3DTOP_BLENDTEXTUREALPHA = 13, - D3DTOP_BLENDFACTORALPHA = 14, - D3DTOP_BLENDTEXTUREALPHAPM = 15, - D3DTOP_BLENDCURRENTALPHA = 16, - D3DTOP_PREMODULATE = 17, - D3DTOP_MODULATEALPHA_ADDCOLOR = 18, - D3DTOP_MODULATECOLOR_ADDALPHA = 19, - D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, - D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, - D3DTOP_BUMPENVMAP = 22, - D3DTOP_BUMPENVMAPLUMINANCE = 23, - D3DTOP_DOTPRODUCT3 = 24, - D3DTOP_MULTIPLYADD = 25, - D3DTOP_LERP = 26, - - D3DTOP_FORCE_DWORD = 0x7fffffff, -} D3DTEXTUREOP; - -typedef enum _D3DTEXTUREADDRESS { - D3DTADDRESS_WRAP = 1, - D3DTADDRESS_MIRROR = 2, - D3DTADDRESS_CLAMP = 3, - D3DTADDRESS_BORDER = 4, - D3DTADDRESS_MIRRORONCE = 5, - - D3DTADDRESS_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREADDRESS; - -typedef enum _D3DTEXTUREFILTERTYPE { - D3DTEXF_NONE = 0, - D3DTEXF_POINT = 1, - D3DTEXF_LINEAR = 2, - D3DTEXF_ANISOTROPIC = 3, - D3DTEXF_FLATCUBIC = 4, - D3DTEXF_GAUSSIANCUBIC = 5, - D3DTEXF_PYRAMIDALQUAD = 6, - D3DTEXF_GAUSSIANQUAD = 7, - D3DTEXF_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREFILTERTYPE; - -typedef struct _D3DGAMMARAMP { - WORD red [256]; - WORD green[256]; - WORD blue [256]; -} D3DGAMMARAMP; - -typedef enum _D3DSAMPLERSTATETYPE { - D3DSAMP_ADDRESSU = 1, - D3DSAMP_ADDRESSV = 2, - D3DSAMP_ADDRESSW = 3, - D3DSAMP_BORDERCOLOR = 4, - D3DSAMP_MAGFILTER = 5, - D3DSAMP_MINFILTER = 6, - D3DSAMP_MIPFILTER = 7, - D3DSAMP_MIPMAPLODBIAS = 8, - D3DSAMP_MAXMIPLEVEL = 9, - D3DSAMP_MAXANISOTROPY = 10, - D3DSAMP_SRGBTEXTURE = 11, - D3DSAMP_ELEMENTINDEX = 12, - D3DSAMP_DMAPOFFSET = 13, - - D3DSAMP_FORCE_DWORD = 0x7fffffff, -} D3DSAMPLERSTATETYPE; - -#define D3DFVF_TEXTUREFORMAT1 3 -#define D3DFVF_TEXTUREFORMAT2 0 -#define D3DFVF_TEXTUREFORMAT3 1 -#define D3DFVF_TEXTUREFORMAT4 2 -#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2) -#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16)) - -typedef enum _D3DDECLMETHOD { - D3DDECLMETHOD_DEFAULT = 0, - D3DDECLMETHOD_PARTIALU = 1, - D3DDECLMETHOD_PARTIALV = 2, - D3DDECLMETHOD_CROSSUV = 3, - D3DDECLMETHOD_UV = 4, - D3DDECLMETHOD_LOOKUP = 5, - D3DDECLMETHOD_LOOKUPPRESAMPLED = 6 -} D3DDECLMETHOD; - - -#define D3DMAXDECLMETHOD D3DDECLMETHOD_LOOKUPPRESAMPLED - -typedef enum _D3DDECLTYPE { - D3DDECLTYPE_FLOAT1 = 0, - D3DDECLTYPE_FLOAT2 = 1, - D3DDECLTYPE_FLOAT3 = 2, - D3DDECLTYPE_FLOAT4 = 3, - D3DDECLTYPE_D3DCOLOR = 4, - D3DDECLTYPE_UBYTE4 = 5, - D3DDECLTYPE_SHORT2 = 6, - D3DDECLTYPE_SHORT4 = 7, - /* VS 2.0 */ - D3DDECLTYPE_UBYTE4N = 8, - D3DDECLTYPE_SHORT2N = 9, - D3DDECLTYPE_SHORT4N = 10, - D3DDECLTYPE_USHORT2N = 11, - D3DDECLTYPE_USHORT4N = 12, - D3DDECLTYPE_UDEC3 = 13, - D3DDECLTYPE_DEC3N = 14, - D3DDECLTYPE_FLOAT16_2 = 15, - D3DDECLTYPE_FLOAT16_4 = 16, - D3DDECLTYPE_UNUSED = 17, -} D3DDECLTYPE; - -#define D3DMAXDECLTYPE D3DDECLTYPE_UNUSED - -typedef enum _D3DDECLUSAGE { - D3DDECLUSAGE_POSITION = 0, - D3DDECLUSAGE_BLENDWEIGHT = 1, - D3DDECLUSAGE_BLENDINDICES = 2, - D3DDECLUSAGE_NORMAL = 3, - D3DDECLUSAGE_PSIZE = 4, - D3DDECLUSAGE_TEXCOORD = 5, - D3DDECLUSAGE_TANGENT = 6, - D3DDECLUSAGE_BINORMAL = 7, - D3DDECLUSAGE_TESSFACTOR = 8, - D3DDECLUSAGE_POSITIONT = 9, - D3DDECLUSAGE_COLOR = 10, - D3DDECLUSAGE_FOG = 11, - D3DDECLUSAGE_DEPTH = 12, - D3DDECLUSAGE_SAMPLE = 13 -} D3DDECLUSAGE; - -typedef enum _D3DFILLMODE { - D3DFILL_POINT = 1, - D3DFILL_WIREFRAME = 2, - D3DFILL_SOLID = 3, - - D3DFILL_FORCE_DWORD = 0x7fffffff -} D3DFILLMODE; - -typedef enum _D3DLIGHTTYPE { - D3DLIGHT_POINT = 1, - D3DLIGHT_SPOT = 2, - D3DLIGHT_DIRECTIONAL = 3, - - D3DLIGHT_FORCE_DWORD = 0x7fffffff -} D3DLIGHTTYPE; - -#ifndef D3DCOLOR_DEFINED -typedef DWORD D3DCOLOR; -#define D3DCOLOR_DEFINED -#endif - -typedef enum _D3DSHADEMODE { - D3DSHADE_FLAT = 1, - D3DSHADE_GOURAUD = 2, - D3DSHADE_PHONG = 3, - - D3DSHADE_FORCE_DWORD = 0x7fffffff -} D3DSHADEMODE; - -typedef enum _D3DSWAPEFFECT { - D3DSWAPEFFECT_DISCARD = 1, - D3DSWAPEFFECT_FLIP = 2, - D3DSWAPEFFECT_COPY = 3, - D3DSWAPEFFECT_OVERLAY = 4, - D3DSWAPEFFECT_FLIPEX = 5, - D3DSWAPEFFECT_FORCE_DWORD = 0xFFFFFFFF -} D3DSWAPEFFECT; - -typedef enum _D3DTRANSFORMSTATETYPE { - D3DTS_VIEW = 2, - D3DTS_PROJECTION = 3, - D3DTS_TEXTURE0 = 16, - D3DTS_TEXTURE1 = 17, - D3DTS_TEXTURE2 = 18, - D3DTS_TEXTURE3 = 19, - D3DTS_TEXTURE4 = 20, - D3DTS_TEXTURE5 = 21, - D3DTS_TEXTURE6 = 22, - D3DTS_TEXTURE7 = 23, - - D3DTS_FORCE_DWORD = 0x7fffffff -} D3DTRANSFORMSTATETYPE; - -typedef enum _D3DTEXTURETRANSFORMFLAGS { - D3DTTFF_DISABLE = 0, - D3DTTFF_COUNT1 = 1, - D3DTTFF_COUNT2 = 2, - D3DTTFF_COUNT3 = 3, - D3DTTFF_COUNT4 = 4, - D3DTTFF_PROJECTED = 256, - - D3DTTFF_FORCE_DWORD = 0x7fffffff -} D3DTEXTURETRANSFORMFLAGS; - -#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) -#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) -#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) -#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) -#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) - -#define D3DUSAGE_RENDERTARGET __MSABI_LONG(0x00000001) -#define D3DUSAGE_DEPTHSTENCIL __MSABI_LONG(0x00000002) -#define D3DUSAGE_WRITEONLY __MSABI_LONG(0x00000008) -#define D3DUSAGE_SOFTWAREPROCESSING __MSABI_LONG(0x00000010) -#define D3DUSAGE_DONOTCLIP __MSABI_LONG(0x00000020) -#define D3DUSAGE_POINTS __MSABI_LONG(0x00000040) -#define D3DUSAGE_RTPATCHES __MSABI_LONG(0x00000080) -#define D3DUSAGE_NPATCHES __MSABI_LONG(0x00000100) -#define D3DUSAGE_DYNAMIC __MSABI_LONG(0x00000200) -#define D3DUSAGE_AUTOGENMIPMAP __MSABI_LONG(0x00000400) -#define D3DUSAGE_DMAP __MSABI_LONG(0x00004000) - -#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) -#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) -#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) -#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) -#define D3DCOLOR_XYUV(y,u,v) D3DCOLOR_ARGB(0xFF,y,u,v) -#define D3DCOLOR_AYUV(a,y,u,v) D3DCOLOR_ARGB(a,y,u,v) - -#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} - -#ifndef D3DRECT_DEFINED -typedef struct _D3DRECT { - LONG x1; - LONG y1; - LONG x2; - LONG y2; -} D3DRECT; -#define D3DRECT_DEFINED -#endif - typedef DWORD FOURCC; typedef struct _AVIINDEXENTRY { @@ -1047,23 +463,6 @@ typedef struct _AVIINDEXENTRY { typedef void *HIC; -#define D3DTA_SELECTMASK 0x0000000f -#define D3DTA_DIFFUSE 0x00000000 -#define D3DTA_CURRENT 0x00000001 -#define D3DTA_TEXTURE 0x00000002 -#define D3DTA_TFACTOR 0x00000003 -#define D3DTA_SPECULAR 0x00000004 -#define D3DTA_TEMP 0x00000005 -#define D3DTA_CONSTANT 0x00000006 -#define D3DTA_COMPLEMENT 0x00000010 -#define D3DTA_ALPHAREPLICATE 0x00000020 - -#define D3DTSS_TCI_PASSTHRU 0x00000 -#define D3DTSS_TCI_CAMERASPACENORMAL 0x10000 -#define D3DTSS_TCI_CAMERASPACEPOSITION 0x20000 -#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x30000 -#define D3DTSS_TCI_SPHEREMAP 0x40000 - inline BOOL SwitchToThread() { return (0 == sched_yield()); } #define xr_fs_strlwr(str) str diff --git a/src/Common/PlatformBSD.inl b/src/Common/PlatformBSD.inl index 7bd021f9994..26ca30cff08 100644 --- a/src/Common/PlatformBSD.inl +++ b/src/Common/PlatformBSD.inl @@ -455,590 +455,6 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define SEM_FAILCRITICALERRORS 1 #define SetErrorMode(x) {} -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ - ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) -#endif - -typedef enum _D3DFORMAT { - D3DFMT_UNKNOWN = 0, - - D3DFMT_R8G8B8 = 20, - D3DFMT_A8R8G8B8 = 21, - D3DFMT_X8R8G8B8 = 22, - D3DFMT_R5G6B5 = 23, - D3DFMT_X1R5G5B5 = 24, - D3DFMT_A1R5G5B5 = 25, - D3DFMT_A4R4G4B4 = 26, - D3DFMT_R3G3B2 = 27, - D3DFMT_A8 = 28, - D3DFMT_A8R3G3B2 = 29, - D3DFMT_X4R4G4B4 = 30, - D3DFMT_A2B10G10R10 = 31, - D3DFMT_A8B8G8R8 = 32, - D3DFMT_X8B8G8R8 = 33, - D3DFMT_G16R16 = 34, - D3DFMT_A2R10G10B10 = 35, - D3DFMT_A16B16G16R16 = 36, - - - D3DFMT_A8P8 = 40, - D3DFMT_P8 = 41, - - D3DFMT_L8 = 50, - D3DFMT_A8L8 = 51, - D3DFMT_A4L4 = 52, - - D3DFMT_V8U8 = 60, - D3DFMT_L6V5U5 = 61, - D3DFMT_X8L8V8U8 = 62, - D3DFMT_Q8W8V8U8 = 63, - D3DFMT_V16U16 = 64, - D3DFMT_A2W10V10U10 = 67, - - D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), - D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), - D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), - D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), - D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), - D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), - D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), - D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M', 'E', 'T', '1'), - D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), - D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), - - D3DFMT_D16_LOCKABLE = 70, - D3DFMT_D32 = 71, - D3DFMT_D15S1 = 73, - D3DFMT_D24S8 = 75, - D3DFMT_D24X8 = 77, - D3DFMT_D24X4S4 = 79, - D3DFMT_D16 = 80, - D3DFMT_L16 = 81, - D3DFMT_D32F_LOCKABLE = 82, - D3DFMT_D24FS8 = 83, - - D3DFMT_VERTEXDATA = 100, - D3DFMT_INDEX16 = 101, - D3DFMT_INDEX32 = 102, - D3DFMT_Q16W16V16U16 = 110, - /* Floating point formats */ - D3DFMT_R16F = 111, - D3DFMT_G16R16F = 112, - D3DFMT_A16B16G16R16F = 113, - - /* IEEE formats */ - D3DFMT_R32F = 114, - D3DFMT_G32R32F = 115, - D3DFMT_A32B32G32R32F = 116, - - D3DFMT_CxV8U8 = 117, - - - D3DFMT_FORCE_DWORD = 0xFFFFFFFF -} D3DFORMAT; - -typedef enum _D3DCULL { - D3DCULL_NONE = 1, - D3DCULL_CW = 2, - D3DCULL_CCW = 3, - - D3DCULL_FORCE_DWORD = 0x7fffffff -} D3DCULL; - -typedef enum _D3DCMPFUNC { - D3DCMP_NEVER = 1, - D3DCMP_LESS = 2, - D3DCMP_EQUAL = 3, - D3DCMP_LESSEQUAL = 4, - D3DCMP_GREATER = 5, - D3DCMP_NOTEQUAL = 6, - D3DCMP_GREATEREQUAL = 7, - D3DCMP_ALWAYS = 8, - - D3DCMP_FORCE_DWORD = 0x7fffffff -} D3DCMPFUNC; - -typedef enum _D3DSTENCILOP { - D3DSTENCILOP_KEEP = 1, - D3DSTENCILOP_ZERO = 2, - D3DSTENCILOP_REPLACE = 3, - D3DSTENCILOP_INCRSAT = 4, - D3DSTENCILOP_DECRSAT = 5, - D3DSTENCILOP_INVERT = 6, - D3DSTENCILOP_INCR = 7, - D3DSTENCILOP_DECR = 8, - - D3DSTENCILOP_FORCE_DWORD = 0x7fffffff -} D3DSTENCILOP; - -typedef enum _D3DBLEND { - D3DBLEND_ZERO = 1, - D3DBLEND_ONE = 2, - D3DBLEND_SRCCOLOR = 3, - D3DBLEND_INVSRCCOLOR = 4, - D3DBLEND_SRCALPHA = 5, - D3DBLEND_INVSRCALPHA = 6, - D3DBLEND_DESTALPHA = 7, - D3DBLEND_INVDESTALPHA = 8, - D3DBLEND_DESTCOLOR = 9, - D3DBLEND_INVDESTCOLOR = 10, - D3DBLEND_SRCALPHASAT = 11, - D3DBLEND_BOTHSRCALPHA = 12, - D3DBLEND_BOTHINVSRCALPHA = 13, - D3DBLEND_BLENDFACTOR = 14, - D3DBLEND_INVBLENDFACTOR = 15, - D3DBLEND_FORCE_DWORD = 0x7fffffff -} D3DBLEND; - -typedef enum _D3DBLENDOP { - D3DBLENDOP_ADD = 1, - D3DBLENDOP_SUBTRACT = 2, - D3DBLENDOP_REVSUBTRACT = 3, - D3DBLENDOP_MIN = 4, - D3DBLENDOP_MAX = 5, - - D3DBLENDOP_FORCE_DWORD = 0x7fffffff -} D3DBLENDOP; - -typedef struct _D3DVERTEXELEMENT9 { - WORD Stream; - WORD Offset; - BYTE Type; - BYTE Method; - BYTE Usage; - BYTE UsageIndex; -} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; - -#define MAXD3DDECLLENGTH 64 /* +end marker */ - -#define D3DFVF_RESERVED0 0x0001 -#define D3DFVF_POSITION_MASK 0x400E -#define D3DFVF_XYZ 0x0002 -#define D3DFVF_XYZRHW 0x0004 -#define D3DFVF_XYZB1 0x0006 -#define D3DFVF_XYZB2 0x0008 -#define D3DFVF_XYZB3 0x000a -#define D3DFVF_XYZB4 0x000c -#define D3DFVF_XYZB5 0x000e -#define D3DFVF_XYZW 0x4002 -#define D3DFVF_NORMAL 0x0010 -#define D3DFVF_PSIZE 0x0020 -#define D3DFVF_DIFFUSE 0x0040 -#define D3DFVF_SPECULAR 0x0080 -#define D3DFVF_TEXCOUNT_MASK 0x0f00 -#define D3DFVF_TEXCOUNT_SHIFT 8 -#define D3DFVF_TEX0 0x0000 -#define D3DFVF_TEX1 0x0100 -#define D3DFVF_TEX2 0x0200 -#define D3DFVF_TEX3 0x0300 -#define D3DFVF_TEX4 0x0400 -#define D3DFVF_TEX5 0x0500 -#define D3DFVF_TEX6 0x0600 -#define D3DFVF_TEX7 0x0700 -#define D3DFVF_TEX8 0x0800 -#define D3DFVF_LASTBETA_UBYTE4 0x1000 -#define D3DFVF_LASTBETA_D3DCOLOR 0x8000 -#define D3DFVF_RESERVED2 0x6000 - -typedef enum _D3DPRIMITIVETYPE { - D3DPT_POINTLIST = 1, - D3DPT_LINELIST = 2, - D3DPT_LINESTRIP = 3, - D3DPT_TRIANGLELIST = 4, - D3DPT_TRIANGLESTRIP = 5, - D3DPT_TRIANGLEFAN = 6, - - D3DPT_FORCE_DWORD = 0x7fffffff -} D3DPRIMITIVETYPE; - -typedef enum _D3DRENDERSTATETYPE { - D3DRS_ZENABLE = 7, - D3DRS_FILLMODE = 8, - D3DRS_SHADEMODE = 9, - D3DRS_ZWRITEENABLE = 14, - D3DRS_ALPHATESTENABLE = 15, - D3DRS_LASTPIXEL = 16, - D3DRS_SRCBLEND = 19, - D3DRS_DESTBLEND = 20, - D3DRS_CULLMODE = 22, - D3DRS_ZFUNC = 23, - D3DRS_ALPHAREF = 24, - D3DRS_ALPHAFUNC = 25, - D3DRS_DITHERENABLE = 26, - D3DRS_ALPHABLENDENABLE = 27, - D3DRS_FOGENABLE = 28, - D3DRS_SPECULARENABLE = 29, - D3DRS_FOGCOLOR = 34, - D3DRS_FOGTABLEMODE = 35, - D3DRS_FOGSTART = 36, - D3DRS_FOGEND = 37, - D3DRS_FOGDENSITY = 38, - D3DRS_RANGEFOGENABLE = 48, - D3DRS_STENCILENABLE = 52, - D3DRS_STENCILFAIL = 53, - D3DRS_STENCILZFAIL = 54, - D3DRS_STENCILPASS = 55, - D3DRS_STENCILFUNC = 56, - D3DRS_STENCILREF = 57, - D3DRS_STENCILMASK = 58, - D3DRS_STENCILWRITEMASK = 59, - D3DRS_TEXTUREFACTOR = 60, - D3DRS_WRAP0 = 128, - D3DRS_WRAP1 = 129, - D3DRS_WRAP2 = 130, - D3DRS_WRAP3 = 131, - D3DRS_WRAP4 = 132, - D3DRS_WRAP5 = 133, - D3DRS_WRAP6 = 134, - D3DRS_WRAP7 = 135, - D3DRS_CLIPPING = 136, - D3DRS_LIGHTING = 137, - D3DRS_AMBIENT = 139, - D3DRS_FOGVERTEXMODE = 140, - D3DRS_COLORVERTEX = 141, - D3DRS_LOCALVIEWER = 142, - D3DRS_NORMALIZENORMALS = 143, - D3DRS_DIFFUSEMATERIALSOURCE = 145, - D3DRS_SPECULARMATERIALSOURCE = 146, - D3DRS_AMBIENTMATERIALSOURCE = 147, - D3DRS_EMISSIVEMATERIALSOURCE = 148, - D3DRS_VERTEXBLEND = 151, - D3DRS_CLIPPLANEENABLE = 152, - D3DRS_POINTSIZE = 154, - D3DRS_POINTSIZE_MIN = 155, - D3DRS_POINTSPRITEENABLE = 156, - D3DRS_POINTSCALEENABLE = 157, - D3DRS_POINTSCALE_A = 158, - D3DRS_POINTSCALE_B = 159, - D3DRS_POINTSCALE_C = 160, - D3DRS_MULTISAMPLEANTIALIAS = 161, - D3DRS_MULTISAMPLEMASK = 162, - D3DRS_PATCHEDGESTYLE = 163, - D3DRS_DEBUGMONITORTOKEN = 165, - D3DRS_POINTSIZE_MAX = 166, - D3DRS_INDEXEDVERTEXBLENDENABLE = 167, - D3DRS_COLORWRITEENABLE = 168, - D3DRS_TWEENFACTOR = 170, - D3DRS_BLENDOP = 171, - D3DRS_POSITIONDEGREE = 172, - D3DRS_NORMALDEGREE = 173, - D3DRS_SCISSORTESTENABLE = 174, - D3DRS_SLOPESCALEDEPTHBIAS = 175, - D3DRS_ANTIALIASEDLINEENABLE = 176, - D3DRS_MINTESSELLATIONLEVEL = 178, - D3DRS_MAXTESSELLATIONLEVEL = 179, - D3DRS_ADAPTIVETESS_X = 180, - D3DRS_ADAPTIVETESS_Y = 181, - D3DRS_ADAPTIVETESS_Z = 182, - D3DRS_ADAPTIVETESS_W = 183, - D3DRS_ENABLEADAPTIVETESSELLATION= 184, - D3DRS_TWOSIDEDSTENCILMODE = 185, - D3DRS_CCW_STENCILFAIL = 186, - D3DRS_CCW_STENCILZFAIL = 187, - D3DRS_CCW_STENCILPASS = 188, - D3DRS_CCW_STENCILFUNC = 189, - D3DRS_COLORWRITEENABLE1 = 190, - D3DRS_COLORWRITEENABLE2 = 191, - D3DRS_COLORWRITEENABLE3 = 192, - D3DRS_BLENDFACTOR = 193, - D3DRS_SRGBWRITEENABLE = 194, - D3DRS_DEPTHBIAS = 195, - D3DRS_WRAP8 = 198, - D3DRS_WRAP9 = 199, - D3DRS_WRAP10 = 200, - D3DRS_WRAP11 = 201, - D3DRS_WRAP12 = 202, - D3DRS_WRAP13 = 203, - D3DRS_WRAP14 = 204, - D3DRS_WRAP15 = 205, - D3DRS_SEPARATEALPHABLENDENABLE = 206, - D3DRS_SRCBLENDALPHA = 207, - D3DRS_DESTBLENDALPHA = 208, - D3DRS_BLENDOPALPHA = 209, - - D3DRS_FORCE_DWORD = 0x7fffffff -} D3DRENDERSTATETYPE; - -/* Macro to deal with LP64 <=> LLP64 differences in numeric constants with 'l' modifier */ -#ifndef __MSABI_LONG -# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) -# define __MSABI_LONG(x) x ## l -# else -# define __MSABI_LONG(x) x -# endif -#endif - -#define D3DCOLORWRITEENABLE_RED (__MSABI_LONG(1)<<0) -#define D3DCOLORWRITEENABLE_GREEN (__MSABI_LONG(1)<<1) -#define D3DCOLORWRITEENABLE_BLUE (__MSABI_LONG(1)<<2) -#define D3DCOLORWRITEENABLE_ALPHA (__MSABI_LONG(1)<<3) - -typedef enum _D3DTEXTURESTAGESTATETYPE { - D3DTSS_COLOROP = 1, - D3DTSS_COLORARG1 = 2, - D3DTSS_COLORARG2 = 3, - D3DTSS_ALPHAOP = 4, - D3DTSS_ALPHAARG1 = 5, - D3DTSS_ALPHAARG2 = 6, - D3DTSS_BUMPENVMAT00 = 7, - D3DTSS_BUMPENVMAT01 = 8, - D3DTSS_BUMPENVMAT10 = 9, - D3DTSS_BUMPENVMAT11 = 10, - D3DTSS_TEXCOORDINDEX = 11, - D3DTSS_BUMPENVLSCALE = 22, - D3DTSS_BUMPENVLOFFSET = 23, - D3DTSS_TEXTURETRANSFORMFLAGS = 24, - D3DTSS_COLORARG0 = 26, - D3DTSS_ALPHAARG0 = 27, - D3DTSS_RESULTARG = 28, - D3DTSS_CONSTANT = 32, - - D3DTSS_FORCE_DWORD = 0x7fffffff -} D3DTEXTURESTAGESTATETYPE; - -typedef enum _D3DTEXTUREOP { - D3DTOP_DISABLE = 1, - D3DTOP_SELECTARG1 = 2, - D3DTOP_SELECTARG2 = 3, - D3DTOP_MODULATE = 4, - D3DTOP_MODULATE2X = 5, - D3DTOP_MODULATE4X = 6, - D3DTOP_ADD = 7, - D3DTOP_ADDSIGNED = 8, - D3DTOP_ADDSIGNED2X = 9, - D3DTOP_SUBTRACT = 10, - D3DTOP_ADDSMOOTH = 11, - D3DTOP_BLENDDIFFUSEALPHA = 12, - D3DTOP_BLENDTEXTUREALPHA = 13, - D3DTOP_BLENDFACTORALPHA = 14, - D3DTOP_BLENDTEXTUREALPHAPM = 15, - D3DTOP_BLENDCURRENTALPHA = 16, - D3DTOP_PREMODULATE = 17, - D3DTOP_MODULATEALPHA_ADDCOLOR = 18, - D3DTOP_MODULATECOLOR_ADDALPHA = 19, - D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, - D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, - D3DTOP_BUMPENVMAP = 22, - D3DTOP_BUMPENVMAPLUMINANCE = 23, - D3DTOP_DOTPRODUCT3 = 24, - D3DTOP_MULTIPLYADD = 25, - D3DTOP_LERP = 26, - - D3DTOP_FORCE_DWORD = 0x7fffffff, -} D3DTEXTUREOP; - -typedef enum _D3DTEXTUREADDRESS { - D3DTADDRESS_WRAP = 1, - D3DTADDRESS_MIRROR = 2, - D3DTADDRESS_CLAMP = 3, - D3DTADDRESS_BORDER = 4, - D3DTADDRESS_MIRRORONCE = 5, - - D3DTADDRESS_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREADDRESS; - -typedef enum _D3DTEXTUREFILTERTYPE { - D3DTEXF_NONE = 0, - D3DTEXF_POINT = 1, - D3DTEXF_LINEAR = 2, - D3DTEXF_ANISOTROPIC = 3, - D3DTEXF_FLATCUBIC = 4, - D3DTEXF_GAUSSIANCUBIC = 5, - D3DTEXF_PYRAMIDALQUAD = 6, - D3DTEXF_GAUSSIANQUAD = 7, - D3DTEXF_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREFILTERTYPE; - -typedef struct _D3DGAMMARAMP { - WORD red [256]; - WORD green[256]; - WORD blue [256]; -} D3DGAMMARAMP; - -typedef enum _D3DSAMPLERSTATETYPE { - D3DSAMP_ADDRESSU = 1, - D3DSAMP_ADDRESSV = 2, - D3DSAMP_ADDRESSW = 3, - D3DSAMP_BORDERCOLOR = 4, - D3DSAMP_MAGFILTER = 5, - D3DSAMP_MINFILTER = 6, - D3DSAMP_MIPFILTER = 7, - D3DSAMP_MIPMAPLODBIAS = 8, - D3DSAMP_MAXMIPLEVEL = 9, - D3DSAMP_MAXANISOTROPY = 10, - D3DSAMP_SRGBTEXTURE = 11, - D3DSAMP_ELEMENTINDEX = 12, - D3DSAMP_DMAPOFFSET = 13, - - D3DSAMP_FORCE_DWORD = 0x7fffffff, -} D3DSAMPLERSTATETYPE; - -#define D3DFVF_TEXTUREFORMAT1 3 -#define D3DFVF_TEXTUREFORMAT2 0 -#define D3DFVF_TEXTUREFORMAT3 1 -#define D3DFVF_TEXTUREFORMAT4 2 -#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2) -#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16)) - -typedef enum _D3DDECLMETHOD { - D3DDECLMETHOD_DEFAULT = 0, - D3DDECLMETHOD_PARTIALU = 1, - D3DDECLMETHOD_PARTIALV = 2, - D3DDECLMETHOD_CROSSUV = 3, - D3DDECLMETHOD_UV = 4, - D3DDECLMETHOD_LOOKUP = 5, - D3DDECLMETHOD_LOOKUPPRESAMPLED = 6 -} D3DDECLMETHOD; - - -#define D3DMAXDECLMETHOD D3DDECLMETHOD_LOOKUPPRESAMPLED - -typedef enum _D3DDECLTYPE { - D3DDECLTYPE_FLOAT1 = 0, - D3DDECLTYPE_FLOAT2 = 1, - D3DDECLTYPE_FLOAT3 = 2, - D3DDECLTYPE_FLOAT4 = 3, - D3DDECLTYPE_D3DCOLOR = 4, - D3DDECLTYPE_UBYTE4 = 5, - D3DDECLTYPE_SHORT2 = 6, - D3DDECLTYPE_SHORT4 = 7, - /* VS 2.0 */ - D3DDECLTYPE_UBYTE4N = 8, - D3DDECLTYPE_SHORT2N = 9, - D3DDECLTYPE_SHORT4N = 10, - D3DDECLTYPE_USHORT2N = 11, - D3DDECLTYPE_USHORT4N = 12, - D3DDECLTYPE_UDEC3 = 13, - D3DDECLTYPE_DEC3N = 14, - D3DDECLTYPE_FLOAT16_2 = 15, - D3DDECLTYPE_FLOAT16_4 = 16, - D3DDECLTYPE_UNUSED = 17, -} D3DDECLTYPE; - -#define D3DMAXDECLTYPE D3DDECLTYPE_UNUSED - -typedef enum _D3DDECLUSAGE { - D3DDECLUSAGE_POSITION = 0, - D3DDECLUSAGE_BLENDWEIGHT = 1, - D3DDECLUSAGE_BLENDINDICES = 2, - D3DDECLUSAGE_NORMAL = 3, - D3DDECLUSAGE_PSIZE = 4, - D3DDECLUSAGE_TEXCOORD = 5, - D3DDECLUSAGE_TANGENT = 6, - D3DDECLUSAGE_BINORMAL = 7, - D3DDECLUSAGE_TESSFACTOR = 8, - D3DDECLUSAGE_POSITIONT = 9, - D3DDECLUSAGE_COLOR = 10, - D3DDECLUSAGE_FOG = 11, - D3DDECLUSAGE_DEPTH = 12, - D3DDECLUSAGE_SAMPLE = 13 -} D3DDECLUSAGE; - -typedef enum _D3DFILLMODE { - D3DFILL_POINT = 1, - D3DFILL_WIREFRAME = 2, - D3DFILL_SOLID = 3, - - D3DFILL_FORCE_DWORD = 0x7fffffff -} D3DFILLMODE; - -typedef enum _D3DLIGHTTYPE { - D3DLIGHT_POINT = 1, - D3DLIGHT_SPOT = 2, - D3DLIGHT_DIRECTIONAL = 3, - - D3DLIGHT_FORCE_DWORD = 0x7fffffff -} D3DLIGHTTYPE; - -#ifndef D3DCOLOR_DEFINED -typedef DWORD D3DCOLOR; -#define D3DCOLOR_DEFINED -#endif - -typedef enum _D3DSHADEMODE { - D3DSHADE_FLAT = 1, - D3DSHADE_GOURAUD = 2, - D3DSHADE_PHONG = 3, - - D3DSHADE_FORCE_DWORD = 0x7fffffff -} D3DSHADEMODE; - -typedef enum _D3DSWAPEFFECT { - D3DSWAPEFFECT_DISCARD = 1, - D3DSWAPEFFECT_FLIP = 2, - D3DSWAPEFFECT_COPY = 3, - D3DSWAPEFFECT_OVERLAY = 4, - D3DSWAPEFFECT_FLIPEX = 5, - D3DSWAPEFFECT_FORCE_DWORD = 0xFFFFFFFF -} D3DSWAPEFFECT; - -typedef enum _D3DTRANSFORMSTATETYPE { - D3DTS_VIEW = 2, - D3DTS_PROJECTION = 3, - D3DTS_TEXTURE0 = 16, - D3DTS_TEXTURE1 = 17, - D3DTS_TEXTURE2 = 18, - D3DTS_TEXTURE3 = 19, - D3DTS_TEXTURE4 = 20, - D3DTS_TEXTURE5 = 21, - D3DTS_TEXTURE6 = 22, - D3DTS_TEXTURE7 = 23, - - D3DTS_FORCE_DWORD = 0x7fffffff -} D3DTRANSFORMSTATETYPE; - -typedef enum _D3DTEXTURETRANSFORMFLAGS { - D3DTTFF_DISABLE = 0, - D3DTTFF_COUNT1 = 1, - D3DTTFF_COUNT2 = 2, - D3DTTFF_COUNT3 = 3, - D3DTTFF_COUNT4 = 4, - D3DTTFF_PROJECTED = 256, - - D3DTTFF_FORCE_DWORD = 0x7fffffff -} D3DTEXTURETRANSFORMFLAGS; - -#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) -#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) -#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) -#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) -#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) - -#define D3DUSAGE_RENDERTARGET __MSABI_LONG(0x00000001) -#define D3DUSAGE_DEPTHSTENCIL __MSABI_LONG(0x00000002) -#define D3DUSAGE_WRITEONLY __MSABI_LONG(0x00000008) -#define D3DUSAGE_SOFTWAREPROCESSING __MSABI_LONG(0x00000010) -#define D3DUSAGE_DONOTCLIP __MSABI_LONG(0x00000020) -#define D3DUSAGE_POINTS __MSABI_LONG(0x00000040) -#define D3DUSAGE_RTPATCHES __MSABI_LONG(0x00000080) -#define D3DUSAGE_NPATCHES __MSABI_LONG(0x00000100) -#define D3DUSAGE_DYNAMIC __MSABI_LONG(0x00000200) -#define D3DUSAGE_AUTOGENMIPMAP __MSABI_LONG(0x00000400) -#define D3DUSAGE_DMAP __MSABI_LONG(0x00004000) - -#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) -#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) -#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) -#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) -#define D3DCOLOR_XYUV(y,u,v) D3DCOLOR_ARGB(0xFF,y,u,v) -#define D3DCOLOR_AYUV(a,y,u,v) D3DCOLOR_ARGB(a,y,u,v) - -#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} - -#ifndef D3DRECT_DEFINED -typedef struct _D3DRECT { - LONG x1; - LONG y1; - LONG x2; - LONG y2; -} D3DRECT; -#define D3DRECT_DEFINED -#endif - typedef DWORD FOURCC; typedef struct _AVIINDEXENTRY { @@ -1050,23 +466,6 @@ typedef struct _AVIINDEXENTRY { typedef void *HIC; -#define D3DTA_SELECTMASK 0x0000000f -#define D3DTA_DIFFUSE 0x00000000 -#define D3DTA_CURRENT 0x00000001 -#define D3DTA_TEXTURE 0x00000002 -#define D3DTA_TFACTOR 0x00000003 -#define D3DTA_SPECULAR 0x00000004 -#define D3DTA_TEMP 0x00000005 -#define D3DTA_CONSTANT 0x00000006 -#define D3DTA_COMPLEMENT 0x00000010 -#define D3DTA_ALPHAREPLICATE 0x00000020 - -#define D3DTSS_TCI_PASSTHRU 0x00000 -#define D3DTSS_TCI_CAMERASPACENORMAL 0x10000 -#define D3DTSS_TCI_CAMERASPACEPOSITION 0x20000 -#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x30000 -#define D3DTSS_TCI_SPHEREMAP 0x40000 - inline BOOL SwitchToThread() { return (0 == sched_yield()); } #define xr_fs_strlwr(str) str diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index d21722d9e45..d52b08c499a 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -448,590 +448,6 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define _MAX_FNAME 256 #define _MAX_EXT 256 -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((DWORD)(uint8_t)(ch0) | ((DWORD)(uint8_t)(ch1) << 8) | \ - ((DWORD)(uint8_t)(ch2) << 16) | ((DWORD)(uint8_t)(ch3) << 24 )) -#endif - -typedef enum _D3DFORMAT { - D3DFMT_UNKNOWN = 0, - - D3DFMT_R8G8B8 = 20, - D3DFMT_A8R8G8B8 = 21, - D3DFMT_X8R8G8B8 = 22, - D3DFMT_R5G6B5 = 23, - D3DFMT_X1R5G5B5 = 24, - D3DFMT_A1R5G5B5 = 25, - D3DFMT_A4R4G4B4 = 26, - D3DFMT_R3G3B2 = 27, - D3DFMT_A8 = 28, - D3DFMT_A8R3G3B2 = 29, - D3DFMT_X4R4G4B4 = 30, - D3DFMT_A2B10G10R10 = 31, - D3DFMT_A8B8G8R8 = 32, - D3DFMT_X8B8G8R8 = 33, - D3DFMT_G16R16 = 34, - D3DFMT_A2R10G10B10 = 35, - D3DFMT_A16B16G16R16 = 36, - - - D3DFMT_A8P8 = 40, - D3DFMT_P8 = 41, - - D3DFMT_L8 = 50, - D3DFMT_A8L8 = 51, - D3DFMT_A4L4 = 52, - - D3DFMT_V8U8 = 60, - D3DFMT_L6V5U5 = 61, - D3DFMT_X8L8V8U8 = 62, - D3DFMT_Q8W8V8U8 = 63, - D3DFMT_V16U16 = 64, - D3DFMT_A2W10V10U10 = 67, - - D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), - D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), - D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), - D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), - D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), - D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), - D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), - D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M', 'E', 'T', '1'), - D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), - D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), - - D3DFMT_D16_LOCKABLE = 70, - D3DFMT_D32 = 71, - D3DFMT_D15S1 = 73, - D3DFMT_D24S8 = 75, - D3DFMT_D24X8 = 77, - D3DFMT_D24X4S4 = 79, - D3DFMT_D16 = 80, - D3DFMT_L16 = 81, - D3DFMT_D32F_LOCKABLE = 82, - D3DFMT_D24FS8 = 83, - - D3DFMT_VERTEXDATA = 100, - D3DFMT_INDEX16 = 101, - D3DFMT_INDEX32 = 102, - D3DFMT_Q16W16V16U16 = 110, - /* Floating point formats */ - D3DFMT_R16F = 111, - D3DFMT_G16R16F = 112, - D3DFMT_A16B16G16R16F = 113, - - /* IEEE formats */ - D3DFMT_R32F = 114, - D3DFMT_G32R32F = 115, - D3DFMT_A32B32G32R32F = 116, - - D3DFMT_CxV8U8 = 117, - - - D3DFMT_FORCE_DWORD = 0xFFFFFFFF -} D3DFORMAT; - -typedef enum _D3DCULL { - D3DCULL_NONE = 1, - D3DCULL_CW = 2, - D3DCULL_CCW = 3, - - D3DCULL_FORCE_DWORD = 0x7fffffff -} D3DCULL; - -typedef enum _D3DCMPFUNC { - D3DCMP_NEVER = 1, - D3DCMP_LESS = 2, - D3DCMP_EQUAL = 3, - D3DCMP_LESSEQUAL = 4, - D3DCMP_GREATER = 5, - D3DCMP_NOTEQUAL = 6, - D3DCMP_GREATEREQUAL = 7, - D3DCMP_ALWAYS = 8, - - D3DCMP_FORCE_DWORD = 0x7fffffff -} D3DCMPFUNC; - -typedef enum _D3DSTENCILOP { - D3DSTENCILOP_KEEP = 1, - D3DSTENCILOP_ZERO = 2, - D3DSTENCILOP_REPLACE = 3, - D3DSTENCILOP_INCRSAT = 4, - D3DSTENCILOP_DECRSAT = 5, - D3DSTENCILOP_INVERT = 6, - D3DSTENCILOP_INCR = 7, - D3DSTENCILOP_DECR = 8, - - D3DSTENCILOP_FORCE_DWORD = 0x7fffffff -} D3DSTENCILOP; - -typedef enum _D3DBLEND { - D3DBLEND_ZERO = 1, - D3DBLEND_ONE = 2, - D3DBLEND_SRCCOLOR = 3, - D3DBLEND_INVSRCCOLOR = 4, - D3DBLEND_SRCALPHA = 5, - D3DBLEND_INVSRCALPHA = 6, - D3DBLEND_DESTALPHA = 7, - D3DBLEND_INVDESTALPHA = 8, - D3DBLEND_DESTCOLOR = 9, - D3DBLEND_INVDESTCOLOR = 10, - D3DBLEND_SRCALPHASAT = 11, - D3DBLEND_BOTHSRCALPHA = 12, - D3DBLEND_BOTHINVSRCALPHA = 13, - D3DBLEND_BLENDFACTOR = 14, - D3DBLEND_INVBLENDFACTOR = 15, - D3DBLEND_FORCE_DWORD = 0x7fffffff -} D3DBLEND; - -typedef enum _D3DBLENDOP { - D3DBLENDOP_ADD = 1, - D3DBLENDOP_SUBTRACT = 2, - D3DBLENDOP_REVSUBTRACT = 3, - D3DBLENDOP_MIN = 4, - D3DBLENDOP_MAX = 5, - - D3DBLENDOP_FORCE_DWORD = 0x7fffffff -} D3DBLENDOP; - -typedef struct _D3DVERTEXELEMENT9 { - WORD Stream; - WORD Offset; - uint8_t Type; - uint8_t Method; - uint8_t Usage; - uint8_t UsageIndex; -} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; - -#define MAXD3DDECLLENGTH 64 /* +end marker */ - -#define D3DFVF_RESERVED0 0x0001 -#define D3DFVF_POSITION_MASK 0x400E -#define D3DFVF_XYZ 0x0002 -#define D3DFVF_XYZRHW 0x0004 -#define D3DFVF_XYZB1 0x0006 -#define D3DFVF_XYZB2 0x0008 -#define D3DFVF_XYZB3 0x000a -#define D3DFVF_XYZB4 0x000c -#define D3DFVF_XYZB5 0x000e -#define D3DFVF_XYZW 0x4002 -#define D3DFVF_NORMAL 0x0010 -#define D3DFVF_PSIZE 0x0020 -#define D3DFVF_DIFFUSE 0x0040 -#define D3DFVF_SPECULAR 0x0080 -#define D3DFVF_TEXCOUNT_MASK 0x0f00 -#define D3DFVF_TEXCOUNT_SHIFT 8 -#define D3DFVF_TEX0 0x0000 -#define D3DFVF_TEX1 0x0100 -#define D3DFVF_TEX2 0x0200 -#define D3DFVF_TEX3 0x0300 -#define D3DFVF_TEX4 0x0400 -#define D3DFVF_TEX5 0x0500 -#define D3DFVF_TEX6 0x0600 -#define D3DFVF_TEX7 0x0700 -#define D3DFVF_TEX8 0x0800 -#define D3DFVF_LASTBETA_UBYTE4 0x1000 -#define D3DFVF_LASTBETA_D3DCOLOR 0x8000 -#define D3DFVF_RESERVED2 0x6000 - -typedef enum _D3DPRIMITIVETYPE { - D3DPT_POINTLIST = 1, - D3DPT_LINELIST = 2, - D3DPT_LINESTRIP = 3, - D3DPT_TRIANGLELIST = 4, - D3DPT_TRIANGLESTRIP = 5, - D3DPT_TRIANGLEFAN = 6, - - D3DPT_FORCE_DWORD = 0x7fffffff -} D3DPRIMITIVETYPE; - -typedef enum _D3DRENDERSTATETYPE { - D3DRS_ZENABLE = 7, - D3DRS_FILLMODE = 8, - D3DRS_SHADEMODE = 9, - D3DRS_ZWRITEENABLE = 14, - D3DRS_ALPHATESTENABLE = 15, - D3DRS_LASTPIXEL = 16, - D3DRS_SRCBLEND = 19, - D3DRS_DESTBLEND = 20, - D3DRS_CULLMODE = 22, - D3DRS_ZFUNC = 23, - D3DRS_ALPHAREF = 24, - D3DRS_ALPHAFUNC = 25, - D3DRS_DITHERENABLE = 26, - D3DRS_ALPHABLENDENABLE = 27, - D3DRS_FOGENABLE = 28, - D3DRS_SPECULARENABLE = 29, - D3DRS_FOGCOLOR = 34, - D3DRS_FOGTABLEMODE = 35, - D3DRS_FOGSTART = 36, - D3DRS_FOGEND = 37, - D3DRS_FOGDENSITY = 38, - D3DRS_RANGEFOGENABLE = 48, - D3DRS_STENCILENABLE = 52, - D3DRS_STENCILFAIL = 53, - D3DRS_STENCILZFAIL = 54, - D3DRS_STENCILPASS = 55, - D3DRS_STENCILFUNC = 56, - D3DRS_STENCILREF = 57, - D3DRS_STENCILMASK = 58, - D3DRS_STENCILWRITEMASK = 59, - D3DRS_TEXTUREFACTOR = 60, - D3DRS_WRAP0 = 128, - D3DRS_WRAP1 = 129, - D3DRS_WRAP2 = 130, - D3DRS_WRAP3 = 131, - D3DRS_WRAP4 = 132, - D3DRS_WRAP5 = 133, - D3DRS_WRAP6 = 134, - D3DRS_WRAP7 = 135, - D3DRS_CLIPPING = 136, - D3DRS_LIGHTING = 137, - D3DRS_AMBIENT = 139, - D3DRS_FOGVERTEXMODE = 140, - D3DRS_COLORVERTEX = 141, - D3DRS_LOCALVIEWER = 142, - D3DRS_NORMALIZENORMALS = 143, - D3DRS_DIFFUSEMATERIALSOURCE = 145, - D3DRS_SPECULARMATERIALSOURCE = 146, - D3DRS_AMBIENTMATERIALSOURCE = 147, - D3DRS_EMISSIVEMATERIALSOURCE = 148, - D3DRS_VERTEXBLEND = 151, - D3DRS_CLIPPLANEENABLE = 152, - D3DRS_POINTSIZE = 154, - D3DRS_POINTSIZE_MIN = 155, - D3DRS_POINTSPRITEENABLE = 156, - D3DRS_POINTSCALEENABLE = 157, - D3DRS_POINTSCALE_A = 158, - D3DRS_POINTSCALE_B = 159, - D3DRS_POINTSCALE_C = 160, - D3DRS_MULTISAMPLEANTIALIAS = 161, - D3DRS_MULTISAMPLEMASK = 162, - D3DRS_PATCHEDGESTYLE = 163, - D3DRS_DEBUGMONITORTOKEN = 165, - D3DRS_POINTSIZE_MAX = 166, - D3DRS_INDEXEDVERTEXBLENDENABLE = 167, - D3DRS_COLORWRITEENABLE = 168, - D3DRS_TWEENFACTOR = 170, - D3DRS_BLENDOP = 171, - D3DRS_POSITIONDEGREE = 172, - D3DRS_NORMALDEGREE = 173, - D3DRS_SCISSORTESTENABLE = 174, - D3DRS_SLOPESCALEDEPTHBIAS = 175, - D3DRS_ANTIALIASEDLINEENABLE = 176, - D3DRS_MINTESSELLATIONLEVEL = 178, - D3DRS_MAXTESSELLATIONLEVEL = 179, - D3DRS_ADAPTIVETESS_X = 180, - D3DRS_ADAPTIVETESS_Y = 181, - D3DRS_ADAPTIVETESS_Z = 182, - D3DRS_ADAPTIVETESS_W = 183, - D3DRS_ENABLEADAPTIVETESSELLATION= 184, - D3DRS_TWOSIDEDSTENCILMODE = 185, - D3DRS_CCW_STENCILFAIL = 186, - D3DRS_CCW_STENCILZFAIL = 187, - D3DRS_CCW_STENCILPASS = 188, - D3DRS_CCW_STENCILFUNC = 189, - D3DRS_COLORWRITEENABLE1 = 190, - D3DRS_COLORWRITEENABLE2 = 191, - D3DRS_COLORWRITEENABLE3 = 192, - D3DRS_BLENDFACTOR = 193, - D3DRS_SRGBWRITEENABLE = 194, - D3DRS_DEPTHBIAS = 195, - D3DRS_WRAP8 = 198, - D3DRS_WRAP9 = 199, - D3DRS_WRAP10 = 200, - D3DRS_WRAP11 = 201, - D3DRS_WRAP12 = 202, - D3DRS_WRAP13 = 203, - D3DRS_WRAP14 = 204, - D3DRS_WRAP15 = 205, - D3DRS_SEPARATEALPHABLENDENABLE = 206, - D3DRS_SRCBLENDALPHA = 207, - D3DRS_DESTBLENDALPHA = 208, - D3DRS_BLENDOPALPHA = 209, - - D3DRS_FORCE_DWORD = 0x7fffffff -} D3DRENDERSTATETYPE; - -/* Macro to deal with LP64 <=> LLP64 differences in numeric constants with 'l' modifier */ -#ifndef __MSABI_LONG -# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) -# define __MSABI_LONG(x) x ## l -# else -# define __MSABI_LONG(x) x -# endif -#endif - -#define D3DCOLORWRITEENABLE_RED (__MSABI_LONG(1)<<0) -#define D3DCOLORWRITEENABLE_GREEN (__MSABI_LONG(1)<<1) -#define D3DCOLORWRITEENABLE_BLUE (__MSABI_LONG(1)<<2) -#define D3DCOLORWRITEENABLE_ALPHA (__MSABI_LONG(1)<<3) - -typedef enum _D3DTEXTURESTAGESTATETYPE { - D3DTSS_COLOROP = 1, - D3DTSS_COLORARG1 = 2, - D3DTSS_COLORARG2 = 3, - D3DTSS_ALPHAOP = 4, - D3DTSS_ALPHAARG1 = 5, - D3DTSS_ALPHAARG2 = 6, - D3DTSS_BUMPENVMAT00 = 7, - D3DTSS_BUMPENVMAT01 = 8, - D3DTSS_BUMPENVMAT10 = 9, - D3DTSS_BUMPENVMAT11 = 10, - D3DTSS_TEXCOORDINDEX = 11, - D3DTSS_BUMPENVLSCALE = 22, - D3DTSS_BUMPENVLOFFSET = 23, - D3DTSS_TEXTURETRANSFORMFLAGS = 24, - D3DTSS_COLORARG0 = 26, - D3DTSS_ALPHAARG0 = 27, - D3DTSS_RESULTARG = 28, - D3DTSS_CONSTANT = 32, - - D3DTSS_FORCE_DWORD = 0x7fffffff -} D3DTEXTURESTAGESTATETYPE; - -typedef enum _D3DTEXTUREOP { - D3DTOP_DISABLE = 1, - D3DTOP_SELECTARG1 = 2, - D3DTOP_SELECTARG2 = 3, - D3DTOP_MODULATE = 4, - D3DTOP_MODULATE2X = 5, - D3DTOP_MODULATE4X = 6, - D3DTOP_ADD = 7, - D3DTOP_ADDSIGNED = 8, - D3DTOP_ADDSIGNED2X = 9, - D3DTOP_SUBTRACT = 10, - D3DTOP_ADDSMOOTH = 11, - D3DTOP_BLENDDIFFUSEALPHA = 12, - D3DTOP_BLENDTEXTUREALPHA = 13, - D3DTOP_BLENDFACTORALPHA = 14, - D3DTOP_BLENDTEXTUREALPHAPM = 15, - D3DTOP_BLENDCURRENTALPHA = 16, - D3DTOP_PREMODULATE = 17, - D3DTOP_MODULATEALPHA_ADDCOLOR = 18, - D3DTOP_MODULATECOLOR_ADDALPHA = 19, - D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, - D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, - D3DTOP_BUMPENVMAP = 22, - D3DTOP_BUMPENVMAPLUMINANCE = 23, - D3DTOP_DOTPRODUCT3 = 24, - D3DTOP_MULTIPLYADD = 25, - D3DTOP_LERP = 26, - - D3DTOP_FORCE_DWORD = 0x7fffffff, -} D3DTEXTUREOP; - -typedef enum _D3DTEXTUREADDRESS { - D3DTADDRESS_WRAP = 1, - D3DTADDRESS_MIRROR = 2, - D3DTADDRESS_CLAMP = 3, - D3DTADDRESS_BORDER = 4, - D3DTADDRESS_MIRRORONCE = 5, - - D3DTADDRESS_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREADDRESS; - -typedef enum _D3DTEXTUREFILTERTYPE { - D3DTEXF_NONE = 0, - D3DTEXF_POINT = 1, - D3DTEXF_LINEAR = 2, - D3DTEXF_ANISOTROPIC = 3, - D3DTEXF_FLATCUBIC = 4, - D3DTEXF_GAUSSIANCUBIC = 5, - D3DTEXF_PYRAMIDALQUAD = 6, - D3DTEXF_GAUSSIANQUAD = 7, - D3DTEXF_FORCE_DWORD = 0x7fffffff -} D3DTEXTUREFILTERTYPE; - -typedef struct _D3DGAMMARAMP { - WORD red [256]; - WORD green[256]; - WORD blue [256]; -} D3DGAMMARAMP; - -typedef enum _D3DSAMPLERSTATETYPE { - D3DSAMP_ADDRESSU = 1, - D3DSAMP_ADDRESSV = 2, - D3DSAMP_ADDRESSW = 3, - D3DSAMP_BORDERCOLOR = 4, - D3DSAMP_MAGFILTER = 5, - D3DSAMP_MINFILTER = 6, - D3DSAMP_MIPFILTER = 7, - D3DSAMP_MIPMAPLODBIAS = 8, - D3DSAMP_MAXMIPLEVEL = 9, - D3DSAMP_MAXANISOTROPY = 10, - D3DSAMP_SRGBTEXTURE = 11, - D3DSAMP_ELEMENTINDEX = 12, - D3DSAMP_DMAPOFFSET = 13, - - D3DSAMP_FORCE_DWORD = 0x7fffffff, -} D3DSAMPLERSTATETYPE; - -#define D3DFVF_TEXTUREFORMAT1 3 -#define D3DFVF_TEXTUREFORMAT2 0 -#define D3DFVF_TEXTUREFORMAT3 1 -#define D3DFVF_TEXTUREFORMAT4 2 -#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2) -#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16)) -#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16)) - -typedef enum _D3DDECLMETHOD { - D3DDECLMETHOD_DEFAULT = 0, - D3DDECLMETHOD_PARTIALU = 1, - D3DDECLMETHOD_PARTIALV = 2, - D3DDECLMETHOD_CROSSUV = 3, - D3DDECLMETHOD_UV = 4, - D3DDECLMETHOD_LOOKUP = 5, - D3DDECLMETHOD_LOOKUPPRESAMPLED = 6 -} D3DDECLMETHOD; - - -#define D3DMAXDECLMETHOD D3DDECLMETHOD_LOOKUPPRESAMPLED - -typedef enum _D3DDECLTYPE { - D3DDECLTYPE_FLOAT1 = 0, - D3DDECLTYPE_FLOAT2 = 1, - D3DDECLTYPE_FLOAT3 = 2, - D3DDECLTYPE_FLOAT4 = 3, - D3DDECLTYPE_D3DCOLOR = 4, - D3DDECLTYPE_UBYTE4 = 5, - D3DDECLTYPE_SHORT2 = 6, - D3DDECLTYPE_SHORT4 = 7, - /* VS 2.0 */ - D3DDECLTYPE_UBYTE4N = 8, - D3DDECLTYPE_SHORT2N = 9, - D3DDECLTYPE_SHORT4N = 10, - D3DDECLTYPE_USHORT2N = 11, - D3DDECLTYPE_USHORT4N = 12, - D3DDECLTYPE_UDEC3 = 13, - D3DDECLTYPE_DEC3N = 14, - D3DDECLTYPE_FLOAT16_2 = 15, - D3DDECLTYPE_FLOAT16_4 = 16, - D3DDECLTYPE_UNUSED = 17, -} D3DDECLTYPE; - -#define D3DMAXDECLTYPE D3DDECLTYPE_UNUSED - -typedef enum _D3DDECLUSAGE { - D3DDECLUSAGE_POSITION = 0, - D3DDECLUSAGE_BLENDWEIGHT = 1, - D3DDECLUSAGE_BLENDINDICES = 2, - D3DDECLUSAGE_NORMAL = 3, - D3DDECLUSAGE_PSIZE = 4, - D3DDECLUSAGE_TEXCOORD = 5, - D3DDECLUSAGE_TANGENT = 6, - D3DDECLUSAGE_BINORMAL = 7, - D3DDECLUSAGE_TESSFACTOR = 8, - D3DDECLUSAGE_POSITIONT = 9, - D3DDECLUSAGE_COLOR = 10, - D3DDECLUSAGE_FOG = 11, - D3DDECLUSAGE_DEPTH = 12, - D3DDECLUSAGE_SAMPLE = 13 -} D3DDECLUSAGE; - -typedef enum _D3DFILLMODE { - D3DFILL_POINT = 1, - D3DFILL_WIREFRAME = 2, - D3DFILL_SOLID = 3, - - D3DFILL_FORCE_DWORD = 0x7fffffff -} D3DFILLMODE; - -typedef enum _D3DLIGHTTYPE { - D3DLIGHT_POINT = 1, - D3DLIGHT_SPOT = 2, - D3DLIGHT_DIRECTIONAL = 3, - - D3DLIGHT_FORCE_DWORD = 0x7fffffff -} D3DLIGHTTYPE; - -#ifndef D3DCOLOR_DEFINED -typedef DWORD D3DCOLOR; -#define D3DCOLOR_DEFINED -#endif - -typedef enum _D3DSHADEMODE { - D3DSHADE_FLAT = 1, - D3DSHADE_GOURAUD = 2, - D3DSHADE_PHONG = 3, - - D3DSHADE_FORCE_DWORD = 0x7fffffff -} D3DSHADEMODE; - -typedef enum _D3DSWAPEFFECT { - D3DSWAPEFFECT_DISCARD = 1, - D3DSWAPEFFECT_FLIP = 2, - D3DSWAPEFFECT_COPY = 3, - D3DSWAPEFFECT_OVERLAY = 4, - D3DSWAPEFFECT_FLIPEX = 5, - D3DSWAPEFFECT_FORCE_DWORD = 0xFFFFFFFF -} D3DSWAPEFFECT; - -typedef enum _D3DTRANSFORMSTATETYPE { - D3DTS_VIEW = 2, - D3DTS_PROJECTION = 3, - D3DTS_TEXTURE0 = 16, - D3DTS_TEXTURE1 = 17, - D3DTS_TEXTURE2 = 18, - D3DTS_TEXTURE3 = 19, - D3DTS_TEXTURE4 = 20, - D3DTS_TEXTURE5 = 21, - D3DTS_TEXTURE6 = 22, - D3DTS_TEXTURE7 = 23, - - D3DTS_FORCE_DWORD = 0x7fffffff -} D3DTRANSFORMSTATETYPE; - -typedef enum _D3DTEXTURETRANSFORMFLAGS { - D3DTTFF_DISABLE = 0, - D3DTTFF_COUNT1 = 1, - D3DTTFF_COUNT2 = 2, - D3DTTFF_COUNT3 = 3, - D3DTTFF_COUNT4 = 4, - D3DTTFF_PROJECTED = 256, - - D3DTTFF_FORCE_DWORD = 0x7fffffff -} D3DTEXTURETRANSFORMFLAGS; - -#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) -#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) -#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) -#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) -#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) - -#define D3DUSAGE_RENDERTARGET __MSABI_LONG(0x00000001) -#define D3DUSAGE_DEPTHSTENCIL __MSABI_LONG(0x00000002) -#define D3DUSAGE_WRITEONLY __MSABI_LONG(0x00000008) -#define D3DUSAGE_SOFTWAREPROCESSING __MSABI_LONG(0x00000010) -#define D3DUSAGE_DONOTCLIP __MSABI_LONG(0x00000020) -#define D3DUSAGE_POINTS __MSABI_LONG(0x00000040) -#define D3DUSAGE_RTPATCHES __MSABI_LONG(0x00000080) -#define D3DUSAGE_NPATCHES __MSABI_LONG(0x00000100) -#define D3DUSAGE_DYNAMIC __MSABI_LONG(0x00000200) -#define D3DUSAGE_AUTOGENMIPMAP __MSABI_LONG(0x00000400) -#define D3DUSAGE_DMAP __MSABI_LONG(0x00004000) - -#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) -#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) -#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) -#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) -#define D3DCOLOR_XYUV(y,u,v) D3DCOLOR_ARGB(0xFF,y,u,v) -#define D3DCOLOR_AYUV(a,y,u,v) D3DCOLOR_ARGB(a,y,u,v) - -#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} - -#ifndef D3DRECT_DEFINED -typedef struct _D3DRECT { - LONG x1; - LONG y1; - LONG x2; - LONG y2; -} D3DRECT; -#define D3DRECT_DEFINED -#endif - typedef DWORD FOURCC; typedef struct _AVIINDEXENTRY { @@ -1043,23 +459,6 @@ typedef struct _AVIINDEXENTRY { typedef void *HIC; -#define D3DTA_SELECTMASK 0x0000000f -#define D3DTA_DIFFUSE 0x00000000 -#define D3DTA_CURRENT 0x00000001 -#define D3DTA_TEXTURE 0x00000002 -#define D3DTA_TFACTOR 0x00000003 -#define D3DTA_SPECULAR 0x00000004 -#define D3DTA_TEMP 0x00000005 -#define D3DTA_CONSTANT 0x00000006 -#define D3DTA_COMPLEMENT 0x00000010 -#define D3DTA_ALPHAREPLICATE 0x00000020 - -#define D3DTSS_TCI_PASSTHRU 0x00000 -#define D3DTSS_TCI_CAMERASPACENORMAL 0x10000 -#define D3DTSS_TCI_CAMERASPACEPOSITION 0x20000 -#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x30000 -#define D3DTSS_TCI_SPHEREMAP 0x40000 - inline BOOL SwitchToThread() { return (0 == sched_yield()); } template diff --git a/src/Common/d3d9compat.hpp b/src/Common/d3d9compat.hpp new file mode 100644 index 00000000000..d51329bde18 --- /dev/null +++ b/src/Common/d3d9compat.hpp @@ -0,0 +1,602 @@ +#pragma once + +/* Macro to deal with LP64 <=> LLP64 differences in numeric constants with 'l' modifier */ +#ifndef __MSABI_LONG +# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) +# define __MSABI_LONG(x) x ## l +# else +# define __MSABI_LONG(x) x +# endif +#endif + +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(uint8_t)(ch0) | ((DWORD)(uint8_t)(ch1) << 8) | \ + ((DWORD)(uint8_t)(ch2) << 16) | ((DWORD)(uint8_t)(ch3) << 24 )) +#endif + +typedef enum _D3DFORMAT { + D3DFMT_UNKNOWN = 0, + + D3DFMT_R8G8B8 = 20, + D3DFMT_A8R8G8B8 = 21, + D3DFMT_X8R8G8B8 = 22, + D3DFMT_R5G6B5 = 23, + D3DFMT_X1R5G5B5 = 24, + D3DFMT_A1R5G5B5 = 25, + D3DFMT_A4R4G4B4 = 26, + D3DFMT_R3G3B2 = 27, + D3DFMT_A8 = 28, + D3DFMT_A8R3G3B2 = 29, + D3DFMT_X4R4G4B4 = 30, + D3DFMT_A2B10G10R10 = 31, + D3DFMT_A8B8G8R8 = 32, + D3DFMT_X8B8G8R8 = 33, + D3DFMT_G16R16 = 34, + D3DFMT_A2R10G10B10 = 35, + D3DFMT_A16B16G16R16 = 36, + + + D3DFMT_A8P8 = 40, + D3DFMT_P8 = 41, + + D3DFMT_L8 = 50, + D3DFMT_A8L8 = 51, + D3DFMT_A4L4 = 52, + + D3DFMT_V8U8 = 60, + D3DFMT_L6V5U5 = 61, + D3DFMT_X8L8V8U8 = 62, + D3DFMT_Q8W8V8U8 = 63, + D3DFMT_V16U16 = 64, + D3DFMT_A2W10V10U10 = 67, + + D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), + D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), + D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), + D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), + D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), + D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), + D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), + D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M', 'E', 'T', '1'), + D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), + D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), + + D3DFMT_D16_LOCKABLE = 70, + D3DFMT_D32 = 71, + D3DFMT_D15S1 = 73, + D3DFMT_D24S8 = 75, + D3DFMT_D24X8 = 77, + D3DFMT_D24X4S4 = 79, + D3DFMT_D16 = 80, + D3DFMT_L16 = 81, + D3DFMT_D32F_LOCKABLE = 82, + D3DFMT_D24FS8 = 83, + + D3DFMT_VERTEXDATA = 100, + D3DFMT_INDEX16 = 101, + D3DFMT_INDEX32 = 102, + D3DFMT_Q16W16V16U16 = 110, + /* Floating point formats */ + D3DFMT_R16F = 111, + D3DFMT_G16R16F = 112, + D3DFMT_A16B16G16R16F = 113, + + /* IEEE formats */ + D3DFMT_R32F = 114, + D3DFMT_G32R32F = 115, + D3DFMT_A32B32G32R32F = 116, + + D3DFMT_CxV8U8 = 117, + + + D3DFMT_FORCE_DWORD = 0xFFFFFFFF +} D3DFORMAT; + +typedef enum _D3DCULL { + D3DCULL_NONE = 1, + D3DCULL_CW = 2, + D3DCULL_CCW = 3, + + D3DCULL_FORCE_DWORD = 0x7fffffff +} D3DCULL; + +typedef enum _D3DCMPFUNC { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, + + D3DCMP_FORCE_DWORD = 0x7fffffff +} D3DCMPFUNC; + +typedef enum _D3DSTENCILOP { + D3DSTENCILOP_KEEP = 1, + D3DSTENCILOP_ZERO = 2, + D3DSTENCILOP_REPLACE = 3, + D3DSTENCILOP_INCRSAT = 4, + D3DSTENCILOP_DECRSAT = 5, + D3DSTENCILOP_INVERT = 6, + D3DSTENCILOP_INCR = 7, + D3DSTENCILOP_DECR = 8, + + D3DSTENCILOP_FORCE_DWORD = 0x7fffffff +} D3DSTENCILOP; + +typedef enum _D3DBLEND { + D3DBLEND_ZERO = 1, + D3DBLEND_ONE = 2, + D3DBLEND_SRCCOLOR = 3, + D3DBLEND_INVSRCCOLOR = 4, + D3DBLEND_SRCALPHA = 5, + D3DBLEND_INVSRCALPHA = 6, + D3DBLEND_DESTALPHA = 7, + D3DBLEND_INVDESTALPHA = 8, + D3DBLEND_DESTCOLOR = 9, + D3DBLEND_INVDESTCOLOR = 10, + D3DBLEND_SRCALPHASAT = 11, + D3DBLEND_BOTHSRCALPHA = 12, + D3DBLEND_BOTHINVSRCALPHA = 13, + D3DBLEND_BLENDFACTOR = 14, + D3DBLEND_INVBLENDFACTOR = 15, + D3DBLEND_FORCE_DWORD = 0x7fffffff +} D3DBLEND; + +typedef enum _D3DBLENDOP { + D3DBLENDOP_ADD = 1, + D3DBLENDOP_SUBTRACT = 2, + D3DBLENDOP_REVSUBTRACT = 3, + D3DBLENDOP_MIN = 4, + D3DBLENDOP_MAX = 5, + + D3DBLENDOP_FORCE_DWORD = 0x7fffffff +} D3DBLENDOP; + +typedef struct _D3DVERTEXELEMENT9 { + WORD Stream; + WORD Offset; + uint8_t Type; + uint8_t Method; + uint8_t Usage; + uint8_t UsageIndex; +} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; + +#define MAXD3DDECLLENGTH 64 /* +end marker */ + +#define D3DFVF_RESERVED0 0x0001 +#define D3DFVF_POSITION_MASK 0x400E +#define D3DFVF_XYZ 0x0002 +#define D3DFVF_XYZRHW 0x0004 +#define D3DFVF_XYZB1 0x0006 +#define D3DFVF_XYZB2 0x0008 +#define D3DFVF_XYZB3 0x000a +#define D3DFVF_XYZB4 0x000c +#define D3DFVF_XYZB5 0x000e +#define D3DFVF_XYZW 0x4002 +#define D3DFVF_NORMAL 0x0010 +#define D3DFVF_PSIZE 0x0020 +#define D3DFVF_DIFFUSE 0x0040 +#define D3DFVF_SPECULAR 0x0080 +#define D3DFVF_TEXCOUNT_MASK 0x0f00 +#define D3DFVF_TEXCOUNT_SHIFT 8 +#define D3DFVF_TEX0 0x0000 +#define D3DFVF_TEX1 0x0100 +#define D3DFVF_TEX2 0x0200 +#define D3DFVF_TEX3 0x0300 +#define D3DFVF_TEX4 0x0400 +#define D3DFVF_TEX5 0x0500 +#define D3DFVF_TEX6 0x0600 +#define D3DFVF_TEX7 0x0700 +#define D3DFVF_TEX8 0x0800 +#define D3DFVF_LASTBETA_UBYTE4 0x1000 +#define D3DFVF_LASTBETA_D3DCOLOR 0x8000 +#define D3DFVF_RESERVED2 0x6000 + +typedef enum _D3DPRIMITIVETYPE { + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_LINESTRIP = 3, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_TRIANGLEFAN = 6, + + D3DPT_FORCE_DWORD = 0x7fffffff +} D3DPRIMITIVETYPE; + +typedef enum _D3DRENDERSTATETYPE { + D3DRS_ZENABLE = 7, + D3DRS_FILLMODE = 8, + D3DRS_SHADEMODE = 9, + D3DRS_ZWRITEENABLE = 14, + D3DRS_ALPHATESTENABLE = 15, + D3DRS_LASTPIXEL = 16, + D3DRS_SRCBLEND = 19, + D3DRS_DESTBLEND = 20, + D3DRS_CULLMODE = 22, + D3DRS_ZFUNC = 23, + D3DRS_ALPHAREF = 24, + D3DRS_ALPHAFUNC = 25, + D3DRS_DITHERENABLE = 26, + D3DRS_ALPHABLENDENABLE = 27, + D3DRS_FOGENABLE = 28, + D3DRS_SPECULARENABLE = 29, + D3DRS_FOGCOLOR = 34, + D3DRS_FOGTABLEMODE = 35, + D3DRS_FOGSTART = 36, + D3DRS_FOGEND = 37, + D3DRS_FOGDENSITY = 38, + D3DRS_RANGEFOGENABLE = 48, + D3DRS_STENCILENABLE = 52, + D3DRS_STENCILFAIL = 53, + D3DRS_STENCILZFAIL = 54, + D3DRS_STENCILPASS = 55, + D3DRS_STENCILFUNC = 56, + D3DRS_STENCILREF = 57, + D3DRS_STENCILMASK = 58, + D3DRS_STENCILWRITEMASK = 59, + D3DRS_TEXTUREFACTOR = 60, + D3DRS_WRAP0 = 128, + D3DRS_WRAP1 = 129, + D3DRS_WRAP2 = 130, + D3DRS_WRAP3 = 131, + D3DRS_WRAP4 = 132, + D3DRS_WRAP5 = 133, + D3DRS_WRAP6 = 134, + D3DRS_WRAP7 = 135, + D3DRS_CLIPPING = 136, + D3DRS_LIGHTING = 137, + D3DRS_AMBIENT = 139, + D3DRS_FOGVERTEXMODE = 140, + D3DRS_COLORVERTEX = 141, + D3DRS_LOCALVIEWER = 142, + D3DRS_NORMALIZENORMALS = 143, + D3DRS_DIFFUSEMATERIALSOURCE = 145, + D3DRS_SPECULARMATERIALSOURCE = 146, + D3DRS_AMBIENTMATERIALSOURCE = 147, + D3DRS_EMISSIVEMATERIALSOURCE = 148, + D3DRS_VERTEXBLEND = 151, + D3DRS_CLIPPLANEENABLE = 152, + D3DRS_POINTSIZE = 154, + D3DRS_POINTSIZE_MIN = 155, + D3DRS_POINTSPRITEENABLE = 156, + D3DRS_POINTSCALEENABLE = 157, + D3DRS_POINTSCALE_A = 158, + D3DRS_POINTSCALE_B = 159, + D3DRS_POINTSCALE_C = 160, + D3DRS_MULTISAMPLEANTIALIAS = 161, + D3DRS_MULTISAMPLEMASK = 162, + D3DRS_PATCHEDGESTYLE = 163, + D3DRS_DEBUGMONITORTOKEN = 165, + D3DRS_POINTSIZE_MAX = 166, + D3DRS_INDEXEDVERTEXBLENDENABLE = 167, + D3DRS_COLORWRITEENABLE = 168, + D3DRS_TWEENFACTOR = 170, + D3DRS_BLENDOP = 171, + D3DRS_POSITIONDEGREE = 172, + D3DRS_NORMALDEGREE = 173, + D3DRS_SCISSORTESTENABLE = 174, + D3DRS_SLOPESCALEDEPTHBIAS = 175, + D3DRS_ANTIALIASEDLINEENABLE = 176, + D3DRS_MINTESSELLATIONLEVEL = 178, + D3DRS_MAXTESSELLATIONLEVEL = 179, + D3DRS_ADAPTIVETESS_X = 180, + D3DRS_ADAPTIVETESS_Y = 181, + D3DRS_ADAPTIVETESS_Z = 182, + D3DRS_ADAPTIVETESS_W = 183, + D3DRS_ENABLEADAPTIVETESSELLATION= 184, + D3DRS_TWOSIDEDSTENCILMODE = 185, + D3DRS_CCW_STENCILFAIL = 186, + D3DRS_CCW_STENCILZFAIL = 187, + D3DRS_CCW_STENCILPASS = 188, + D3DRS_CCW_STENCILFUNC = 189, + D3DRS_COLORWRITEENABLE1 = 190, + D3DRS_COLORWRITEENABLE2 = 191, + D3DRS_COLORWRITEENABLE3 = 192, + D3DRS_BLENDFACTOR = 193, + D3DRS_SRGBWRITEENABLE = 194, + D3DRS_DEPTHBIAS = 195, + D3DRS_WRAP8 = 198, + D3DRS_WRAP9 = 199, + D3DRS_WRAP10 = 200, + D3DRS_WRAP11 = 201, + D3DRS_WRAP12 = 202, + D3DRS_WRAP13 = 203, + D3DRS_WRAP14 = 204, + D3DRS_WRAP15 = 205, + D3DRS_SEPARATEALPHABLENDENABLE = 206, + D3DRS_SRCBLENDALPHA = 207, + D3DRS_DESTBLENDALPHA = 208, + D3DRS_BLENDOPALPHA = 209, + + D3DRS_FORCE_DWORD = 0x7fffffff +} D3DRENDERSTATETYPE; + +#define D3DCOLORWRITEENABLE_RED (__MSABI_LONG(1)<<0) +#define D3DCOLORWRITEENABLE_GREEN (__MSABI_LONG(1)<<1) +#define D3DCOLORWRITEENABLE_BLUE (__MSABI_LONG(1)<<2) +#define D3DCOLORWRITEENABLE_ALPHA (__MSABI_LONG(1)<<3) + +typedef enum _D3DTEXTURESTAGESTATETYPE { + D3DTSS_COLOROP = 1, + D3DTSS_COLORARG1 = 2, + D3DTSS_COLORARG2 = 3, + D3DTSS_ALPHAOP = 4, + D3DTSS_ALPHAARG1 = 5, + D3DTSS_ALPHAARG2 = 6, + D3DTSS_BUMPENVMAT00 = 7, + D3DTSS_BUMPENVMAT01 = 8, + D3DTSS_BUMPENVMAT10 = 9, + D3DTSS_BUMPENVMAT11 = 10, + D3DTSS_TEXCOORDINDEX = 11, + D3DTSS_BUMPENVLSCALE = 22, + D3DTSS_BUMPENVLOFFSET = 23, + D3DTSS_TEXTURETRANSFORMFLAGS = 24, + D3DTSS_COLORARG0 = 26, + D3DTSS_ALPHAARG0 = 27, + D3DTSS_RESULTARG = 28, + D3DTSS_CONSTANT = 32, + + D3DTSS_FORCE_DWORD = 0x7fffffff +} D3DTEXTURESTAGESTATETYPE; + +typedef enum _D3DTEXTUREOP { + D3DTOP_DISABLE = 1, + D3DTOP_SELECTARG1 = 2, + D3DTOP_SELECTARG2 = 3, + D3DTOP_MODULATE = 4, + D3DTOP_MODULATE2X = 5, + D3DTOP_MODULATE4X = 6, + D3DTOP_ADD = 7, + D3DTOP_ADDSIGNED = 8, + D3DTOP_ADDSIGNED2X = 9, + D3DTOP_SUBTRACT = 10, + D3DTOP_ADDSMOOTH = 11, + D3DTOP_BLENDDIFFUSEALPHA = 12, + D3DTOP_BLENDTEXTUREALPHA = 13, + D3DTOP_BLENDFACTORALPHA = 14, + D3DTOP_BLENDTEXTUREALPHAPM = 15, + D3DTOP_BLENDCURRENTALPHA = 16, + D3DTOP_PREMODULATE = 17, + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, + D3DTOP_MODULATECOLOR_ADDALPHA = 19, + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, + D3DTOP_BUMPENVMAP = 22, + D3DTOP_BUMPENVMAPLUMINANCE = 23, + D3DTOP_DOTPRODUCT3 = 24, + D3DTOP_MULTIPLYADD = 25, + D3DTOP_LERP = 26, + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +typedef enum _D3DTEXTUREADDRESS { + D3DTADDRESS_WRAP = 1, + D3DTADDRESS_MIRROR = 2, + D3DTADDRESS_CLAMP = 3, + D3DTADDRESS_BORDER = 4, + D3DTADDRESS_MIRRORONCE = 5, + + D3DTADDRESS_FORCE_DWORD = 0x7fffffff +} D3DTEXTUREADDRESS; + +typedef enum _D3DTEXTUREFILTERTYPE { + D3DTEXF_NONE = 0, + D3DTEXF_POINT = 1, + D3DTEXF_LINEAR = 2, + D3DTEXF_ANISOTROPIC = 3, + D3DTEXF_FLATCUBIC = 4, + D3DTEXF_GAUSSIANCUBIC = 5, + D3DTEXF_PYRAMIDALQUAD = 6, + D3DTEXF_GAUSSIANQUAD = 7, + D3DTEXF_FORCE_DWORD = 0x7fffffff +} D3DTEXTUREFILTERTYPE; + +typedef struct _D3DGAMMARAMP { + WORD red [256]; + WORD green[256]; + WORD blue [256]; +} D3DGAMMARAMP; + +typedef enum _D3DSAMPLERSTATETYPE { + D3DSAMP_ADDRESSU = 1, + D3DSAMP_ADDRESSV = 2, + D3DSAMP_ADDRESSW = 3, + D3DSAMP_BORDERCOLOR = 4, + D3DSAMP_MAGFILTER = 5, + D3DSAMP_MINFILTER = 6, + D3DSAMP_MIPFILTER = 7, + D3DSAMP_MIPMAPLODBIAS = 8, + D3DSAMP_MAXMIPLEVEL = 9, + D3DSAMP_MAXANISOTROPY = 10, + D3DSAMP_SRGBTEXTURE = 11, + D3DSAMP_ELEMENTINDEX = 12, + D3DSAMP_DMAPOFFSET = 13, + + D3DSAMP_FORCE_DWORD = 0x7fffffff, +} D3DSAMPLERSTATETYPE; + +#define D3DFVF_TEXTUREFORMAT1 3 +#define D3DFVF_TEXTUREFORMAT2 0 +#define D3DFVF_TEXTUREFORMAT3 1 +#define D3DFVF_TEXTUREFORMAT4 2 +#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16)) +#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2) +#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16)) +#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16)) + +typedef enum _D3DDECLMETHOD { + D3DDECLMETHOD_DEFAULT = 0, + D3DDECLMETHOD_PARTIALU = 1, + D3DDECLMETHOD_PARTIALV = 2, + D3DDECLMETHOD_CROSSUV = 3, + D3DDECLMETHOD_UV = 4, + D3DDECLMETHOD_LOOKUP = 5, + D3DDECLMETHOD_LOOKUPPRESAMPLED = 6 +} D3DDECLMETHOD; + + +#define D3DMAXDECLMETHOD D3DDECLMETHOD_LOOKUPPRESAMPLED + +typedef enum _D3DDECLTYPE { + D3DDECLTYPE_FLOAT1 = 0, + D3DDECLTYPE_FLOAT2 = 1, + D3DDECLTYPE_FLOAT3 = 2, + D3DDECLTYPE_FLOAT4 = 3, + D3DDECLTYPE_D3DCOLOR = 4, + D3DDECLTYPE_UBYTE4 = 5, + D3DDECLTYPE_SHORT2 = 6, + D3DDECLTYPE_SHORT4 = 7, + /* VS 2.0 */ + D3DDECLTYPE_UBYTE4N = 8, + D3DDECLTYPE_SHORT2N = 9, + D3DDECLTYPE_SHORT4N = 10, + D3DDECLTYPE_USHORT2N = 11, + D3DDECLTYPE_USHORT4N = 12, + D3DDECLTYPE_UDEC3 = 13, + D3DDECLTYPE_DEC3N = 14, + D3DDECLTYPE_FLOAT16_2 = 15, + D3DDECLTYPE_FLOAT16_4 = 16, + D3DDECLTYPE_UNUSED = 17, +} D3DDECLTYPE; + +#define D3DMAXDECLTYPE D3DDECLTYPE_UNUSED + +typedef enum _D3DDECLUSAGE { + D3DDECLUSAGE_POSITION = 0, + D3DDECLUSAGE_BLENDWEIGHT = 1, + D3DDECLUSAGE_BLENDINDICES = 2, + D3DDECLUSAGE_NORMAL = 3, + D3DDECLUSAGE_PSIZE = 4, + D3DDECLUSAGE_TEXCOORD = 5, + D3DDECLUSAGE_TANGENT = 6, + D3DDECLUSAGE_BINORMAL = 7, + D3DDECLUSAGE_TESSFACTOR = 8, + D3DDECLUSAGE_POSITIONT = 9, + D3DDECLUSAGE_COLOR = 10, + D3DDECLUSAGE_FOG = 11, + D3DDECLUSAGE_DEPTH = 12, + D3DDECLUSAGE_SAMPLE = 13 +} D3DDECLUSAGE; + +typedef enum _D3DFILLMODE { + D3DFILL_POINT = 1, + D3DFILL_WIREFRAME = 2, + D3DFILL_SOLID = 3, + + D3DFILL_FORCE_DWORD = 0x7fffffff +} D3DFILLMODE; + +typedef enum _D3DLIGHTTYPE { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + + D3DLIGHT_FORCE_DWORD = 0x7fffffff +} D3DLIGHTTYPE; + +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +typedef enum _D3DSHADEMODE { + D3DSHADE_FLAT = 1, + D3DSHADE_GOURAUD = 2, + D3DSHADE_PHONG = 3, + + D3DSHADE_FORCE_DWORD = 0x7fffffff +} D3DSHADEMODE; + +typedef enum _D3DSWAPEFFECT { + D3DSWAPEFFECT_DISCARD = 1, + D3DSWAPEFFECT_FLIP = 2, + D3DSWAPEFFECT_COPY = 3, + D3DSWAPEFFECT_OVERLAY = 4, + D3DSWAPEFFECT_FLIPEX = 5, + D3DSWAPEFFECT_FORCE_DWORD = 0xFFFFFFFF +} D3DSWAPEFFECT; + +typedef enum _D3DTRANSFORMSTATETYPE { + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_TEXTURE1 = 17, + D3DTS_TEXTURE2 = 18, + D3DTS_TEXTURE3 = 19, + D3DTS_TEXTURE4 = 20, + D3DTS_TEXTURE5 = 21, + D3DTS_TEXTURE6 = 22, + D3DTS_TEXTURE7 = 23, + + D3DTS_FORCE_DWORD = 0x7fffffff +} D3DTRANSFORMSTATETYPE; + +typedef enum _D3DTEXTURETRANSFORMFLAGS { + D3DTTFF_DISABLE = 0, + D3DTTFF_COUNT1 = 1, + D3DTTFF_COUNT2 = 2, + D3DTTFF_COUNT3 = 3, + D3DTTFF_COUNT4 = 4, + D3DTTFF_PROJECTED = 256, + + D3DTTFF_FORCE_DWORD = 0x7fffffff +} D3DTEXTURETRANSFORMFLAGS; + +#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) +#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) +#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) +#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) +#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) + +#define D3DUSAGE_RENDERTARGET __MSABI_LONG(0x00000001) +#define D3DUSAGE_DEPTHSTENCIL __MSABI_LONG(0x00000002) +#define D3DUSAGE_WRITEONLY __MSABI_LONG(0x00000008) +#define D3DUSAGE_SOFTWAREPROCESSING __MSABI_LONG(0x00000010) +#define D3DUSAGE_DONOTCLIP __MSABI_LONG(0x00000020) +#define D3DUSAGE_POINTS __MSABI_LONG(0x00000040) +#define D3DUSAGE_RTPATCHES __MSABI_LONG(0x00000080) +#define D3DUSAGE_NPATCHES __MSABI_LONG(0x00000100) +#define D3DUSAGE_DYNAMIC __MSABI_LONG(0x00000200) +#define D3DUSAGE_AUTOGENMIPMAP __MSABI_LONG(0x00000400) +#define D3DUSAGE_DMAP __MSABI_LONG(0x00004000) + +#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) +#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) +#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) +#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) +#define D3DCOLOR_XYUV(y,u,v) D3DCOLOR_ARGB(0xFF,y,u,v) +#define D3DCOLOR_AYUV(a,y,u,v) D3DCOLOR_ARGB(a,y,u,v) + +#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} + +#ifndef D3DRECT_DEFINED +typedef struct _D3DRECT { + LONG x1; + LONG y1; + LONG x2; + LONG y2; +} D3DRECT; +#define D3DRECT_DEFINED +#endif + +#define D3DTA_SELECTMASK 0x0000000f +#define D3DTA_DIFFUSE 0x00000000 +#define D3DTA_CURRENT 0x00000001 +#define D3DTA_TEXTURE 0x00000002 +#define D3DTA_TFACTOR 0x00000003 +#define D3DTA_SPECULAR 0x00000004 +#define D3DTA_TEMP 0x00000005 +#define D3DTA_CONSTANT 0x00000006 +#define D3DTA_COMPLEMENT 0x00000010 +#define D3DTA_ALPHAREPLICATE 0x00000020 + +#define D3DTSS_TCI_PASSTHRU 0x00000 +#define D3DTSS_TCI_CAMERASPACENORMAL 0x10000 +#define D3DTSS_TCI_CAMERASPACEPOSITION 0x20000 +#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x30000 +#define D3DTSS_TCI_SPHEREMAP 0x40000 diff --git a/src/Layers/xrRenderGL/CommonTypes.h b/src/Layers/xrRenderGL/CommonTypes.h index cd6968c381c..c61fd9f3984 100644 --- a/src/Layers/xrRenderGL/CommonTypes.h +++ b/src/Layers/xrRenderGL/CommonTypes.h @@ -3,6 +3,8 @@ // TODO: Get rid of D3D types. #if defined(XR_PLATFORM_WINDOWS) #include +#else +#include "Common/d3d9compat.hpp" #endif class glState; From 83cdf626fcc4a0bc75c9121ed1d112809bedfa0a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 17:48:52 +0500 Subject: [PATCH 112/497] Cleaned up Platform*.inl files And reduced diff between them --- Externals/ode/CMakeLists.txt | 1 - Externals/ode/include/ode/odemath.h | 2 +- src/Common/PlatformApple.inl | 128 +++++++++--------- src/Common/PlatformBSD.inl | 125 ++++++++--------- src/Common/PlatformLinux.inl | 44 +----- src/Layers/xrRenderGL/glHW.cpp | 2 + .../gl_rendertarget_build_textures.cpp | 4 + src/utils/ETools/ETools.h | 4 +- src/utils/xrLC_Light/xrIsect.h | 2 +- src/xrCDB/xrCDB.h | 2 +- src/xrCore/Compression/rt_compressor.cpp | 2 +- src/xrCore/Compression/rt_compressor9.cpp | 2 +- src/xrCore/FileSystem_borland.cpp | 2 +- src/xrEngine/XR_IOConsole.cpp | 4 +- src/xrEngine/XR_IOConsole.h | 2 +- src/xrGame/console_commands.cpp | 6 +- .../LuaStudio/Backend/Backend.hpp | 4 +- .../LuaStudio/Backend/Engine.hpp | 2 +- .../LuaStudio/Backend/World.hpp | 2 +- src/xrScriptEngine/LuaStudio/Config.hpp | 2 +- src/xrScriptEngine/LuaStudio/Defines.hpp | 9 -- 21 files changed, 144 insertions(+), 207 deletions(-) diff --git a/Externals/ode/CMakeLists.txt b/Externals/ode/CMakeLists.txt index f6fd21db86f..bd6cc37e5ed 100644 --- a/Externals/ode/CMakeLists.txt +++ b/Externals/ode/CMakeLists.txt @@ -98,7 +98,6 @@ target_compile_definitions(xrODE PRIVATE LINUX __cdecl= - __forceinline=inline ) if (MASTER_GOLD) diff --git a/Externals/ode/include/ode/odemath.h b/Externals/ode/include/ode/odemath.h index a32da0a2b87..d429f725fe7 100644 --- a/Externals/ode/include/ode/odemath.h +++ b/Externals/ode/include/ode/odemath.h @@ -222,7 +222,7 @@ extern "C" { ODE_API void dNormalize3_slow (dVector3 a); // XXX: original ODE_API void dNormalize4 (dVector4 a); -__forceinline void dNormalize3 (dVector3 a) // XXX: GSC custom +inline void dNormalize3 (dVector3 a) // XXX: GSC custom { dReal sqr_magnitude = a[0]*a[0] + a[1]*a[1] + a[2]*a[2]; dReal epsilon = 1.192092896e-05F; diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 5300dfacd93..7e11485181d 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -29,39 +29,25 @@ #define _LINUX // for GameSpy -#define _MAX_PATH 4096 + 1 -#define MAX_PATH 4096 + 1 +#define MAX_PATH PATH_MAX + 1 #define WINAPI #define _copysign copysign #define _cdecl //__attribute__((cdecl)) -#define _stdcall //__attribute__((stdcall)) #define _fastcall //__attribute__((fastcall)) #define __cdecl #define __stdcall #define __fastcall -//#define __declspec -#define __forceinline FORCE_INLINE #define __pragma(...) _Pragma(#__VA_ARGS__) -#define __declspec(x) #define CALLBACK -#define TEXT(x) strdup(x) - - - -#define VOID void -#define HKL void* -#define ActivateKeyboardLayout(x, y) {} -#define ScreenToClient(hwnd, p) {} #define __except(X) catch(X) #define GetCurrentProcessId getpid -#define GetCurrentThreadId pthread_self inline void Sleep(int ms) { @@ -131,9 +117,10 @@ inline int GetExceptionCode() return 0; } +inline void convert_path_separators(char * path); + #include typedef int32_t BOOL; -typedef uint8_t BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; typedef int32_t LONG; @@ -147,47 +134,14 @@ typedef char* PSTR; typedef char* LPTSTR; typedef const char* LPCSTR; typedef const char* LPCTSTR; -typedef unsigned char* LPBYTE; typedef unsigned int UINT; -typedef int INT; -typedef unsigned long ULONG; -typedef unsigned long* ULONG_PTR; typedef long long int LARGE_INTEGER; typedef unsigned long long int ULARGE_INTEGER; -typedef unsigned short* LPWORD; -typedef unsigned long* LPDWORD; -typedef const void* LPCVOID; -typedef long long int* PLARGE_INTEGER; - -typedef wchar_t WCHAR; - -typedef struct tagSTICKYKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} STICKYKEYS, *LPSTICKYKEYS; - -typedef struct tagFILTERKEYS -{ - UINT cbSize; - DWORD dwFlags; - DWORD iWaitMSec; - DWORD iDelayMSec; - DWORD iRepeatMSec; - DWORD iBounceMSec; -} FILTERKEYS, *LPFILTERKEYS; - -typedef struct tagTOGGLEKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} TOGGLEKEYS, *LPTOGGLEKEYS; - typedef struct _EXCEPTION_POINTERS { } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; -#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_ARM64) +#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_ARM64) || defined(XR_ARCHITECTURE_E2K) typedef int64_t INT_PTR; typedef uint64_t UINT_PTR; typedef int64_t LONG_PTR; @@ -195,21 +149,22 @@ typedef int64_t LONG_PTR; typedef int INT_PTR; typedef unsigned int UINT_PTR; typedef long LONG_PTR; -#endif // XR_ARCHITECTURE_X64 +#endif typedef void* HANDLE; typedef void* HMODULE; typedef void* PVOID; typedef void* LPVOID; +#if defined(XR_ARCHITECTURE_PPC64) +typedef LONG_PTR WPARAM; +#else typedef UINT_PTR WPARAM; +#endif typedef LONG_PTR LPARAM; typedef long HRESULT; typedef long LRESULT; -typedef long _W64; typedef void* HWND; typedef void* HDC; -typedef float FLOAT; -typedef unsigned char UINT8; typedef struct _RECT { long left; @@ -223,7 +178,6 @@ typedef struct tagPOINT { long y; } POINT, *PPOINT, *LPPOINT; -#define DWORD_PTR UINT_PTR #define WM_USER 0x0400 #define TRUE true @@ -286,7 +240,7 @@ inline int strcpy_s(char *dest, size_t num, const char *source) return ERANGE; } -template +template inline int strcpy_s(char (&dest)[num], const char *source) { return strcpy_s(dest, num, source); } inline int strncpy_s(char * dest, size_t dst_size, const char * source, size_t num) @@ -326,7 +280,7 @@ inline int strncpy_s(char * dest, size_t dst_size, const char * source, size_t n return EINVAL; } -template +template inline int strncpy_s(char (&dest)[dst_sz], const char * source, size_t num) { return strncpy_s(dest, dst_sz, source, num); } inline int strcat_s(char * dest, size_t num, const char * source) @@ -400,7 +354,6 @@ inline int vsnprintf_s(char* buffer, size_t size, size_t, const char* format, va #define wcsicmp _wcsicmp #define _wcsicmp wcscmp #define _tempnam tempnam -#define _unlink unlink #define _access access #define _open open #define _close close @@ -415,10 +368,17 @@ inline int _filelength(int fd) return file_info.st_size; } #define _fdopen fdopen -#define _rmdir rmdir +inline int _rmdir(const char *path) +{ + char* conv_fn = strdup(path); + convert_path_separators(conv_fn); + int result = rmdir(conv_fn); + free(conv_fn); + return result; +} #define _write write #define _strupr strupr -#define _read read +#define _read xr_read #define _set_new_handler std::set_new_handler #define _finite isfinite inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } @@ -437,7 +397,7 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define ZeroMemory(p, sz) memset((p), 0, (sz)) #define CopyMemory(d, s, n) memcpy(d, s, n) -#define RGB(r,g,b) ( ((DWORD)(BYTE)r)|((DWORD)((BYTE)g)<<8)|((DWORD)((BYTE)b)<<16) ) +#define RGB(r,g,b) ( ((DWORD)(uint8_t)r)|((DWORD)((uint8_t)g)<<8)|((DWORD)((uint8_t)b)<<16) ) #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #define FAILED(hr) (((HRESULT)(hr)) < 0) #define S_OK 0x00000000 @@ -449,9 +409,6 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define _MAX_FNAME 256 #define _MAX_EXT 256 -#define SEM_FAILCRITICALERRORS 1 -#define SetErrorMode(x) {} - typedef DWORD FOURCC; typedef struct _AVIINDEXENTRY { @@ -465,7 +422,13 @@ typedef void *HIC; inline BOOL SwitchToThread() { return (0 == sched_yield()); } -#define xr_fs_strlwr(str) str +template +decltype(auto) do_nothing(const T& obj) +{ + return obj; +} + +#define xr_fs_strlwr(str) do_nothing(str) #define xr_fs_nostrlwr(str) xr_strlwr(str) /// For backward compability of FS, for real filesystem delimiter set to back @@ -479,10 +442,43 @@ inline void convert_path_separators(char * path) while (char* sep = strchr(path, '\\')) *sep = '/'; } -#define xr_unlink unlink +inline int xr_unlink(const char *path) +{ + char* conv_fn = strdup(path); + convert_path_separators(conv_fn); + int result = unlink(conv_fn); + free(conv_fn); + return result; +} inline tm* localtime_safe(const time_t *time, struct tm* result){ return localtime_r(time, result); } #define xr_strerror(errno, buffer, bufferSize) strerror_r(errno, buffer, sizeof(buffer)) using xrpid_t = pid_t; + +// This is a drop-in replacement for calls to linux 'read' function. We use this because unlike other OSes +// Linux 'read' function can return less then the requested number of bytes and might need to be called multiple times. +// Apart from this, it behaves exactly as you would expect and matches the other OSes implementation. +// See also: https://www.man7.org/linux/man-pages/man2/read.2.html +inline ssize_t xr_read(int file_handle, void *buffer, size_t count) +{ + ssize_t total_r_bytes = 0; + do + { + const ssize_t r_bytes = + read(file_handle, reinterpret_cast(buffer) + total_r_bytes, count - total_r_bytes); + + // Check for error + if (r_bytes == -1) + return -1; + + // Check for EOF otherwise we would loop indefinitely + if (r_bytes == 0) + return total_r_bytes; + + total_r_bytes += r_bytes; + } while (static_cast(total_r_bytes) < count); + + return total_r_bytes; +} diff --git a/src/Common/PlatformBSD.inl b/src/Common/PlatformBSD.inl index 26ca30cff08..56a8981345d 100644 --- a/src/Common/PlatformBSD.inl +++ b/src/Common/PlatformBSD.inl @@ -23,13 +23,9 @@ #include #include #include -#include - -#pragma STDC FENV_ACCESS ON #define _LINUX // for GameSpy -#define _MAX_PATH PATH_MAX + 1 #define MAX_PATH PATH_MAX + 1 #define WINAPI @@ -37,30 +33,17 @@ #define _copysign copysign #define _cdecl //__attribute__((cdecl)) -#define _stdcall //__attribute__((stdcall)) #define _fastcall //__attribute__((fastcall)) #define __cdecl #define __stdcall -//#define __declspec -#define __forceinline FORCE_INLINE #define __pragma(...) _Pragma(#__VA_ARGS__) -#define __declspec(x) #define CALLBACK -#define TEXT(x) strdup(x) - - - -#define VOID void -#define HKL void* -#define ActivateKeyboardLayout(x, y) {} -#define ScreenToClient(hwnd, p) {} #define __except(X) catch(X) #define GetCurrentProcessId getpid -#define GetCurrentThreadId pthread_self inline void Sleep(int ms) { @@ -130,9 +113,10 @@ inline int GetExceptionCode() return 0; } +inline void convert_path_separators(char * path); + #include typedef int32_t BOOL; -typedef uint8_t BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; typedef int32_t LONG; @@ -146,47 +130,14 @@ typedef char* PSTR; typedef char* LPTSTR; typedef const char* LPCSTR; typedef const char* LPCTSTR; -typedef unsigned char* LPBYTE; typedef unsigned int UINT; -typedef int INT; -typedef unsigned long ULONG; -typedef unsigned long* ULONG_PTR; typedef long long int LARGE_INTEGER; typedef unsigned long long int ULARGE_INTEGER; -typedef unsigned short* LPWORD; -typedef unsigned long* LPDWORD; -typedef const void* LPCVOID; -typedef long long int* PLARGE_INTEGER; - -typedef wchar_t WCHAR; - -typedef struct tagSTICKYKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} STICKYKEYS, *LPSTICKYKEYS; - -typedef struct tagFILTERKEYS -{ - UINT cbSize; - DWORD dwFlags; - DWORD iWaitMSec; - DWORD iDelayMSec; - DWORD iRepeatMSec; - DWORD iBounceMSec; -} FILTERKEYS, *LPFILTERKEYS; - -typedef struct tagTOGGLEKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} TOGGLEKEYS, *LPTOGGLEKEYS; - typedef struct _EXCEPTION_POINTERS { } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; -#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_ARM64) +#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_ARM64) || defined(XR_ARCHITECTURE_E2K) typedef int64_t INT_PTR; typedef uint64_t UINT_PTR; typedef int64_t LONG_PTR; @@ -194,7 +145,7 @@ typedef int64_t LONG_PTR; typedef int INT_PTR; typedef unsigned int UINT_PTR; typedef long LONG_PTR; -#endif // XR_ARCHITECTURE_X64 +#endif typedef void* HANDLE; typedef void* HMODULE; @@ -208,11 +159,8 @@ typedef UINT_PTR WPARAM; typedef LONG_PTR LPARAM; typedef long HRESULT; typedef long LRESULT; -typedef long _W64; typedef void* HWND; typedef void* HDC; -typedef float FLOAT; -typedef unsigned char UINT8; typedef struct _RECT { long left; @@ -226,7 +174,6 @@ typedef struct tagPOINT { long y; } POINT, *PPOINT, *LPPOINT; -#define DWORD_PTR UINT_PTR #define WM_USER 0x0400 #define TRUE true @@ -289,7 +236,7 @@ inline int strcpy_s(char *dest, size_t num, const char *source) return ERANGE; } -template +template inline int strcpy_s(char (&dest)[num], const char *source) { return strcpy_s(dest, num, source); } inline int strncpy_s(char * dest, size_t dst_size, const char * source, size_t num) @@ -329,7 +276,7 @@ inline int strncpy_s(char * dest, size_t dst_size, const char * source, size_t n return EINVAL; } -template +template inline int strncpy_s(char (&dest)[dst_sz], const char * source, size_t num) { return strncpy_s(dest, dst_sz, source, num); } inline int strcat_s(char * dest, size_t num, const char * source) @@ -403,7 +350,6 @@ inline int vsnprintf_s(char* buffer, size_t size, size_t, const char* format, va #define wcsicmp _wcsicmp #define _wcsicmp wcscmp #define _tempnam tempnam -#define _unlink unlink #define _access access #define _open open #define _close close @@ -418,10 +364,17 @@ inline int _filelength(int fd) return file_info.st_size; } #define _fdopen fdopen -#define _rmdir rmdir +inline int _rmdir(const char *path) +{ + char* conv_fn = strdup(path); + convert_path_separators(conv_fn); + int result = rmdir(conv_fn); + free(conv_fn); + return result; +} #define _write write #define _strupr strupr -#define _read read +#define _read xr_read #define _set_new_handler std::set_new_handler #define _finite isfinite inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } @@ -440,7 +393,7 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define ZeroMemory(p, sz) memset((p), 0, (sz)) #define CopyMemory(d, s, n) memcpy(d, s, n) -#define RGB(r,g,b) ( ((DWORD)(BYTE)r)|((DWORD)((BYTE)g)<<8)|((DWORD)((BYTE)b)<<16) ) +#define RGB(r,g,b) ( ((DWORD)(uint8_t)r)|((DWORD)((uint8_t)g)<<8)|((DWORD)((uint8_t)b)<<16) ) #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #define FAILED(hr) (((HRESULT)(hr)) < 0) #define S_OK 0x00000000 @@ -452,9 +405,6 @@ inline int _mkdir(const char *dir) { return mkdir(dir, S_IRWXU); } #define _MAX_FNAME 256 #define _MAX_EXT 256 -#define SEM_FAILCRITICALERRORS 1 -#define SetErrorMode(x) {} - typedef DWORD FOURCC; typedef struct _AVIINDEXENTRY { @@ -468,7 +418,13 @@ typedef void *HIC; inline BOOL SwitchToThread() { return (0 == sched_yield()); } -#define xr_fs_strlwr(str) str +template +decltype(auto) do_nothing(const T& obj) +{ + return obj; +} + +#define xr_fs_strlwr(str) do_nothing(str) #define xr_fs_nostrlwr(str) xr_strlwr(str) /// For backward compability of FS, for real filesystem delimiter set to back @@ -482,10 +438,43 @@ inline void convert_path_separators(char * path) while (char* sep = strchr(path, '\\')) *sep = '/'; } -#define xr_unlink unlink +inline int xr_unlink(const char *path) +{ + char* conv_fn = strdup(path); + convert_path_separators(conv_fn); + int result = unlink(conv_fn); + free(conv_fn); + return result; +} inline tm* localtime_safe(const time_t *time, struct tm* result){ return localtime_r(time, result); } #define xr_strerror(errno, buffer, bufferSize) strerror_r(errno, buffer, sizeof(buffer)) using xrpid_t = pid_t; + +// This is a drop-in replacement for calls to linux 'read' function. We use this because unlike other OSes +// Linux 'read' function can return less then the requested number of bytes and might need to be called multiple times. +// Apart from this, it behaves exactly as you would expect and matches the other OSes implementation. +// See also: https://www.man7.org/linux/man-pages/man2/read.2.html +inline ssize_t xr_read(int file_handle, void *buffer, size_t count) +{ + ssize_t total_r_bytes = 0; + do + { + const ssize_t r_bytes = + read(file_handle, reinterpret_cast(buffer) + total_r_bytes, count - total_r_bytes); + + // Check for error + if (r_bytes == -1) + return -1; + + // Check for EOF otherwise we would loop indefinitely + if (r_bytes == 0) + return total_r_bytes; + + total_r_bytes += r_bytes; + } while (static_cast(total_r_bytes) < count); + + return total_r_bytes; +} diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index d52b08c499a..fc342ebb881 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -26,7 +26,6 @@ #define _LINUX // for GameSpy -#define _MAX_PATH PATH_MAX + 1 #define MAX_PATH PATH_MAX + 1 #define WINAPI @@ -40,24 +39,8 @@ #define __stdcall #define __fastcall -//#define __declspec -#define __forceinline FORCE_INLINE #define __pragma(...) _Pragma(#__VA_ARGS__) -#define __declspec(x) #define CALLBACK -#define TEXT(x) strdup(x) - -/* -inline char* _strlwr_l(char* str, locale_t loc) -{ -//TODO -} - -inline char* _strupr_l(char* str, locale_t loc) -{ -//TODO -} -*/ #define __except(X) catch(X) @@ -152,30 +135,6 @@ typedef unsigned int UINT; typedef long long int LARGE_INTEGER; typedef unsigned long long int ULARGE_INTEGER; -typedef wchar_t WCHAR; - -typedef struct tagSTICKYKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} STICKYKEYS, *LPSTICKYKEYS; - -typedef struct tagFILTERKEYS -{ - UINT cbSize; - DWORD dwFlags; - DWORD iWaitMSec; - DWORD iDelayMSec; - DWORD iRepeatMSec; - DWORD iBounceMSec; -} FILTERKEYS, *LPFILTERKEYS; - -typedef struct tagTOGGLEKEYS -{ - DWORD cbSize; - DWORD dwFlags; -} TOGGLEKEYS, *LPTOGGLEKEYS; - typedef struct _EXCEPTION_POINTERS { } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; @@ -187,7 +146,7 @@ typedef int64_t LONG_PTR; typedef int INT_PTR; typedef unsigned int UINT_PTR; typedef long LONG_PTR; -#endif // defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_ARM64) || defined(XR_ARCHITECTURE_E2K) +#endif typedef void* HANDLE; typedef void* HMODULE; @@ -216,7 +175,6 @@ typedef struct tagPOINT { long y; } POINT, *PPOINT, *LPPOINT; -#define DWORD_PTR UINT_PTR #define WM_USER 0x0400 #define TRUE true diff --git a/src/Layers/xrRenderGL/glHW.cpp b/src/Layers/xrRenderGL/glHW.cpp index 0a2f640e216..4d1f53c057f 100644 --- a/src/Layers/xrRenderGL/glHW.cpp +++ b/src/Layers/xrRenderGL/glHW.cpp @@ -16,6 +16,8 @@ void CALLBACK OnDebugCallback(GLenum /*source*/, GLenum /*type*/, GLuint id, GLe Log(message, id); } +static_assert(std::is_same_v); + void UpdateVSync() { if (psDeviceFlags.test(rsVSync)) diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp index a74b29460f4..1ed576c977e 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp @@ -1,5 +1,9 @@ #include "stdafx.h" +#ifdef XR_PLATFORM_BSD +#include // XXX: needed for workaround below +#endif + static void generate_jitter(u32* dest, u32 elem_count) { const int cmax = 8; diff --git a/src/utils/ETools/ETools.h b/src/utils/ETools/ETools.h index 56cf017dc52..a3643015fac 100644 --- a/src/utils/ETools/ETools.h +++ b/src/utils/ETools/ETools.h @@ -1,7 +1,7 @@ #pragma once #ifdef ETOOLS_EXPORTS -#define ETOOLS_API __declspec(dllexport) +#define ETOOLS_API XR_EXPORT #else -#define ETOOLS_API __declspec(dllimport) +#define ETOOLS_API XR_IMPORT #endif diff --git a/src/utils/xrLC_Light/xrIsect.h b/src/utils/xrLC_Light/xrIsect.h index 379d708cda4..32d2de75703 100644 --- a/src/utils/xrLC_Light/xrIsect.h +++ b/src/utils/xrLC_Light/xrIsect.h @@ -43,7 +43,7 @@ #define LI_INTERSECT 1 #define LI_EQUAL 2 -__forceinline int lines_intersect(float x1, float y1, /* First line segment */ +ICF int lines_intersect(float x1, float y1, /* First line segment */ float x2, float y2, float x3, float y3, /* Second line segment */ diff --git a/src/xrCDB/xrCDB.h b/src/xrCDB/xrCDB.h index 094ac895624..89ae6d7778a 100644 --- a/src/xrCDB/xrCDB.h +++ b/src/xrCDB/xrCDB.h @@ -215,7 +215,7 @@ class XRCDB_API CollectorPacked : public Noncopyable public: CollectorPacked(const Fbox& bb, int apx_vertices = 5000, int apx_faces = 5000); - // __declspec(noinline) CollectorPacked &operator= (const CollectorPacked &object) + // ICN CollectorPacked &operator= (const CollectorPacked &object) // { // verts // } diff --git a/src/xrCore/Compression/rt_compressor.cpp b/src/xrCore/Compression/rt_compressor.cpp index ae18763d9cb..464b2e57542 100644 --- a/src/xrCore/Compression/rt_compressor.cpp +++ b/src/xrCore/Compression/rt_compressor.cpp @@ -5,7 +5,7 @@ #define HEAP_ALLOC(var, size) lzo_align_t __LZO_MMODEL var[((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)] -__declspec(thread) HEAP_ALLOC(rtc_wrkmem, LZO1X_1_MEM_COMPRESS); +thread_local HEAP_ALLOC(rtc_wrkmem, LZO1X_1_MEM_COMPRESS); void rtc_initialize() { VERIFY(lzo_init() == LZO_E_OK); } u32 rtc_csize(u32 in) diff --git a/src/xrCore/Compression/rt_compressor9.cpp b/src/xrCore/Compression/rt_compressor9.cpp index e2736948980..8f4f7f99a31 100644 --- a/src/xrCore/Compression/rt_compressor9.cpp +++ b/src/xrCore/Compression/rt_compressor9.cpp @@ -7,7 +7,7 @@ #define HEAP_ALLOC(var, size) lzo_align_t __LZO_MMODEL var[((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)] -__declspec(thread) HEAP_ALLOC(rtc9_wrkmem, LZO1X_999_MEM_COMPRESS); +thread_local HEAP_ALLOC(rtc9_wrkmem, LZO1X_999_MEM_COMPRESS); static u8* _LZO_Dictionary = nullptr; static u32 _LZO_DictionarySize = 0; diff --git a/src/xrCore/FileSystem_borland.cpp b/src/xrCore/FileSystem_borland.cpp index 7ef7fe9d8a0..b22bb28fff8 100644 --- a/src/xrCore/FileSystem_borland.cpp +++ b/src/xrCore/FileSystem_borland.cpp @@ -26,7 +26,7 @@ bool EFS_Utils::GetOpenName(LPCSTR initial, xr_string& buffer, bool bMulti, LPCS /* char* g_SHBF_Folder =("C:\\Program Files"); - TCHAR path[_MAX_PATH]; + TCHAR path[MAX_PATH]; BROWSEINFO info={NULL,NULL,path,"title",BIF_USENEWUI,BrowseCallbackProc, (LPARAM)g_SHBF_Folder }; SHBrowseForFolder (&info); */ diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index 72d24c10991..93a0c553f35 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -105,8 +105,6 @@ void CConsole::Initialize() pFont = NULL; pFont2 = NULL; - m_mouse_pos.x = 0; - m_mouse_pos.y = 0; m_last_cmd = NULL; m_cmd_history.reserve(m_cmd_history_max + 2); @@ -615,7 +613,7 @@ void CConsole::Show() } bVisible = true; - SDL_GetGlobalMouseState((int *) &m_mouse_pos.x, (int *) &m_mouse_pos.y); // Replace with SDL_GetMouseState in case retrieve window-relative coordinates + SDL_GetGlobalMouseState(&m_mouse_pos.x, &m_mouse_pos.y); // Replace with SDL_GetMouseState in case retrieve window-relative coordinates ec().clear_states(); scroll_delta = 0; diff --git a/src/xrEngine/XR_IOConsole.h b/src/xrEngine/XR_IOConsole.h index 58ed76ef1bb..7ad9dc49305 100644 --- a/src/xrEngine/XR_IOConsole.h +++ b/src/xrEngine/XR_IOConsole.h @@ -89,7 +89,7 @@ class ENGINE_API CConsole : FactoryPtr* m_hShader_back{}; - POINT m_mouse_pos; + Ivector2 m_mouse_pos{}; bool m_disable_tips; private: diff --git a/src/xrGame/console_commands.cpp b/src/xrGame/console_commands.cpp index 7fe007502fb..3420ed8c36a 100644 --- a/src/xrGame/console_commands.cpp +++ b/src/xrGame/console_commands.cpp @@ -642,7 +642,7 @@ class CCC_ALifeSave : public IConsole_Command string_path S, S1; S[0] = 0; - strncpy_s(S, sizeof(S), args, _MAX_PATH - 1); + strncpy_s(S, sizeof(S), args, MAX_PATH - 1); #ifdef DEBUG CTimer timer; @@ -710,7 +710,7 @@ class CCC_ALifeLoadFrom : public IConsole_Command virtual void Execute(LPCSTR args) { string_path saved_game; - strncpy_s(saved_game, sizeof(saved_game), args, _MAX_PATH - 1); + strncpy_s(saved_game, sizeof(saved_game), args, MAX_PATH - 1); if (!ai().get_alife()) { @@ -790,7 +790,7 @@ class CCC_LoadLastSave : public IConsole_Command string_path saved_game = ""; if (args) { - strncpy_s(saved_game, sizeof(saved_game), args, _MAX_PATH - 1); + strncpy_s(saved_game, sizeof(saved_game), args, MAX_PATH - 1); } if (*saved_game) diff --git a/src/xrScriptEngine/LuaStudio/Backend/Backend.hpp b/src/xrScriptEngine/LuaStudio/Backend/Backend.hpp index 917c71cbc94..aad795e7737 100644 --- a/src/xrScriptEngine/LuaStudio/Backend/Backend.hpp +++ b/src/xrScriptEngine/LuaStudio/Backend/Backend.hpp @@ -44,7 +44,7 @@ enum icon_type #endif }; -struct DECLSPEC_NOVTABLE backend +struct XR_NOVTABLE backend { public: virtual void CS_LUA_STUDIO_BACKEND_CALL type_to_string( @@ -53,7 +53,7 @@ struct DECLSPEC_NOVTABLE backend char* buffer, unsigned int size, lua_State* state, int index, icon_type& icon_type, bool full_description) = 0; }; -struct DECLSPEC_NOVTABLE value_to_expand +struct XR_NOVTABLE value_to_expand { virtual void CS_LUA_STUDIO_BACKEND_CALL add_value( char const* id, char const* type, char const* value, icon_type icon_type) = 0; diff --git a/src/xrScriptEngine/LuaStudio/Backend/Engine.hpp b/src/xrScriptEngine/LuaStudio/Backend/Engine.hpp index d086bfa2cc2..3fb29a75359 100644 --- a/src/xrScriptEngine/LuaStudio/Backend/Engine.hpp +++ b/src/xrScriptEngine/LuaStudio/Backend/Engine.hpp @@ -19,7 +19,7 @@ namespace lua_studio { struct backend; -struct DECLSPEC_NOVTABLE XRSCRIPTENGINE_API engine +struct XR_NOVTABLE XRSCRIPTENGINE_API engine { public: enum lua_hook_type diff --git a/src/xrScriptEngine/LuaStudio/Backend/World.hpp b/src/xrScriptEngine/LuaStudio/Backend/World.hpp index 93bf1a1b48a..e7ea4448b5c 100644 --- a/src/xrScriptEngine/LuaStudio/Backend/World.hpp +++ b/src/xrScriptEngine/LuaStudio/Backend/World.hpp @@ -16,7 +16,7 @@ namespace lua_studio { struct engine; -struct DECLSPEC_NOVTABLE world +struct XR_NOVTABLE world { virtual void CS_LUA_STUDIO_BACKEND_CALL add(lua_State* state) = 0; virtual void CS_LUA_STUDIO_BACKEND_CALL remove(lua_State* state) = 0; diff --git a/src/xrScriptEngine/LuaStudio/Config.hpp b/src/xrScriptEngine/LuaStudio/Config.hpp index eddd2a0e165..54f8c2bbbb0 100644 --- a/src/xrScriptEngine/LuaStudio/Config.hpp +++ b/src/xrScriptEngine/LuaStudio/Config.hpp @@ -38,7 +38,7 @@ STATIC_CHECK(false, Unknown_Platform); #ifdef CS_STATIC_LIBRARIES #define CS_API #else // #ifdef CS_STATIC_LIBRARIES -#define CS_API __declspec(dllimport) +#define CS_API XR_IMPORT #endif // #ifdef CS_STATIC_LIBRARIES #endif // #ifndef CS_API diff --git a/src/xrScriptEngine/LuaStudio/Defines.hpp b/src/xrScriptEngine/LuaStudio/Defines.hpp index ba8a9e56cc5..62c7984de53 100644 --- a/src/xrScriptEngine/LuaStudio/Defines.hpp +++ b/src/xrScriptEngine/LuaStudio/Defines.hpp @@ -8,15 +8,6 @@ #pragma once -// DECLSPEC_NOVTABLE macro -#ifndef DECLSPEC_NOVTABLE -#if (XR_COMPILER_MSVC >= 1100) && defined(__cplusplus) -#define DECLSPEC_NOVTABLE __declspec(novtable) -#else // #if (XR_COMPILER_MSVC >= 1100) && defined(__cplusplus) -#define DECLSPEC_NOVTABLE -#endif // #if (XR_COMPILER_MSVC >= 1100) && defined(__cplusplus) -#endif // #ifndef DECLSPEC_NOVTABLE - // CS_STRING_CONCAT macro #if defined(CS_STRING_CONCAT) || defined(CS_STRING_CONCAT_HELPER) STATIC_CHECK(false, CS_STRING_CONCAT_or_CS_STRING_CONCAT_HELPER_or_CS_STRING_CONCAT4_macro_already_defined); From 9875f60459ab2165ee6742ad933ac74c7536248e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 19:06:07 +0500 Subject: [PATCH 113/497] CMake: Always use system default linker Mainly because ld.gold is outdated and check_cxx_compiler_flag returns true even if ld.gold is unavailable, which leads to linking failure. You can still submit XRAY_LINKER define to CMake to specify you other linker (e.g. mold) --- CMakeLists.txt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b24593b8b1e..8b8e62e64ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,21 +206,7 @@ else() ) endif() -option(XRAY_USE_DEFAULT_LINKER "Don't select linker, use system default." OFF) - -if (NOT XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER AND NOT APPLE) # XXX: check if we can remove this check for Apple - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-fuse-ld=gold" GOLD_LINKER_AVAILABLE) - check_cxx_compiler_flag("-fuse-ld=lld" LLD_LINKER_AVAILABLE) - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND LLD_LINKER_AVAILABLE) - set(XRAY_LINKER "lld" CACHE STRING "" FORCE) - elseif (GOLD_LINKER_AVAILABLE) - set(XRAY_LINKER "gold" CACHE STRING "" FORCE) - endif() -endif() - -if (XRAY_LINKER AND NOT XRAY_USE_DEFAULT_LINKER) +if (XRAY_LINKER) add_link_options(-fuse-ld=${XRAY_LINKER}) endif() From 5b6fd8dc866b3620baef4f12ba57dc14ac9f2d42 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 20:16:18 +0500 Subject: [PATCH 114/497] GitHub Actions: Fixed Ubuntu Clang build --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 540d14f0233..efe53d5c562 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -86,7 +86,7 @@ jobs: matrix: platform: - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: gcc, cxx: g++, } - - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: clang, cxx: clang++, } + - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: clang, cxx: clang++, flags: "-DXRAY_LINKER=lld", } #- { name: Ubuntu, os: ubuntu-latest, arch: arm64, cc: gcc, cxx: g++, container: 'dockcross/linux-arm64', } #- { name: Ubuntu, os: ubuntu-latest, arch: ppc64el, cc: gcc, cxx: g++, container: 'dockcross/linux-ppc64le:latest', } - { name: Alpine, os: ubuntu-latest, arch: x86_64, cc: gcc, cxx: g++, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } From ed15ebe36aaa1a9f77078f37440da67aad6aa755 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 20:22:51 +0500 Subject: [PATCH 115/497] GitHub Actions: don't set CC and CXX if we don't need to --- .github/workflows/cibuild.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index efe53d5c562..5474968b26f 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -85,15 +85,18 @@ jobs: fail-fast: false matrix: platform: - - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: gcc, cxx: g++, } + # cc is always set for the correct naming of the job. + # Both cc and cxx should be set if we want to change the compiler. + # You may also want to set XRAY_LINKER when changing the compiler. + - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: gcc, } - { name: Ubuntu, os: ubuntu-latest, arch: amd64, cc: clang, cxx: clang++, flags: "-DXRAY_LINKER=lld", } - #- { name: Ubuntu, os: ubuntu-latest, arch: arm64, cc: gcc, cxx: g++, container: 'dockcross/linux-arm64', } - #- { name: Ubuntu, os: ubuntu-latest, arch: ppc64el, cc: gcc, cxx: g++, container: 'dockcross/linux-ppc64le:latest', } - - { name: Alpine, os: ubuntu-latest, arch: x86_64, cc: gcc, cxx: g++, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } - - { name: Alpine, os: ubuntu-latest, arch: x86, cc: gcc, cxx: g++, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + #- { name: Ubuntu, os: ubuntu-latest, arch: arm64, cc: gcc, container: 'dockcross/linux-arm64', } + #- { name: Ubuntu, os: ubuntu-latest, arch: ppc64el, cc: gcc, container: 'dockcross/linux-ppc64le:latest', } + - { name: Alpine, os: ubuntu-latest, arch: x86_64, cc: gcc, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + - { name: Alpine, os: ubuntu-latest, arch: x86, cc: gcc, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } #- { name: Haiku, os: ubuntu-latest, arch: x86_64, cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, container: 'haiku/cross-compiler:x86_64-r1beta4', } - - { name: macOS, os: macos-13, arch: x86_64, cc: clang, cxx: clang++, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=13.6" } - - { name: macOS, os: macos-14, arch: arm64, cc: clang, cxx: clang++, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0" } + - { name: macOS, os: macos-13, arch: x86_64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=13.6" } + - { name: macOS, os: macos-14, arch: arm64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0" } configuration: [Debug, Release] @@ -128,7 +131,7 @@ jobs: brew install sdl2 glew lzo libogg libvorbis theora - name: Set environment variables - if: ${{ matrix.platform.cc != '' }} + if: ${{ matrix.platform.cc != '' && matrix.platform.cxx != '' }} run: | echo "CC=${{ matrix.platform.cc }}" >> $GITHUB_ENV echo "CXX=${{ matrix.platform.cxx }}" >> $GITHUB_ENV From 22b8736d659060756e60e27924aeae9e77b33f22 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 20:35:37 +0500 Subject: [PATCH 116/497] Fixed missing discord_game_sdk.dll error in Windows builds --- src/xrEngine/xrEngine.vcxproj | 3 +++ src/xrEngine/xrEngine.vcxproj.filters | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index 075b0baab11..baaa4f94e21 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -253,6 +253,9 @@ + + Document + diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index d785264fba7..4930fdadfaa 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -651,4 +651,7 @@ + + + \ No newline at end of file From b5933d51516dd111aa8f32e9183b690b6767169f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 1 Feb 2024 21:33:31 +0500 Subject: [PATCH 117/497] GitHub Actions: Added Fedora build --- .github/workflows/cibuild.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 5474968b26f..aeca23cf4ef 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -94,6 +94,7 @@ jobs: #- { name: Ubuntu, os: ubuntu-latest, arch: ppc64el, cc: gcc, container: 'dockcross/linux-ppc64le:latest', } - { name: Alpine, os: ubuntu-latest, arch: x86_64, cc: gcc, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } - { name: Alpine, os: ubuntu-latest, arch: x86, cc: gcc, shell: 'alpine.sh {0}', flags: "-DXRAY_LINKER=mold", } + - { name: Fedora, os: ubuntu-latest, arch: x86_64, cc: gcc, container: 'fedora:latest', } #- { name: Haiku, os: ubuntu-latest, arch: x86_64, cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, container: 'haiku/cross-compiler:x86_64-r1beta4', } - { name: macOS, os: macos-13, arch: x86_64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=13.6" } - { name: macOS, os: macos-14, arch: arm64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0" } @@ -130,6 +131,10 @@ jobs: brew update brew install sdl2 glew lzo libogg libvorbis theora + - name: Install Fedora packages + if: ${{ matrix.platform.name == 'Fedora' }} + run: dnf install -y git gcc gcc-c++ cmake SDL2-devel glew-devel lzo-devel libjpeg-turbo-devel openal-devel libogg-devel libtheora-devel libvorbis-devel + - name: Set environment variables if: ${{ matrix.platform.cc != '' && matrix.platform.cxx != '' }} run: | From fa82b6ce108a1b94d91961d446768f1d49daa71c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 2 Feb 2024 01:15:32 +0500 Subject: [PATCH 118/497] cmake/utils.cmake: removed xr_install functions --- cmake/utils.cmake | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index e6f75c9057f..492f4da251a 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -76,48 +76,3 @@ function(set_git_info) endfunction() include(packaging) - -function(xr_install tgt) - if (NOT MSVC) - install(TARGETS ${tgt} DESTINATION "." - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 - ) - else() - install(TARGETS ${tgt} - CONFIGURATIONS Debug - RUNTIME DESTINATION Debug/ - LIBRARY DESTINATION Debug/ - ) - install(FILES $ - CONFIGURATIONS Debug - DESTINATION Debug/ - ) - install(TARGETS ${tgt} - CONFIGURATIONS Release - RUNTIME DESTINATION Release/ - LIBRARY DESTINATION Release/ - ) - endif() -endfunction() - -# Use only if install defined outside target directory(like luabind, for example) -function(xr_install_file tgt) - if (NOT MSVC) - install(FILES $ DESTINATION "." - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # chmod 755 - ) - else() - install($ - CONFIGURATIONS Debug - RUNTIME DESTINATION Debug/ - ) - install(FILES $ - CONFIGURATIONS Debug - DESTINATION Debug/ - ) - install($ - CONFIGURATIONS Release - RUNTIME DESTINATION Release/ - ) - endif() -endfunction() From cad6d4a71bf29a88710deb98fd197df9d519ba24 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 4 Feb 2024 17:50:02 +0500 Subject: [PATCH 119/497] xrSound: 32-bit float sound should used only if console command is on Console command is snd_use_float32 --- src/xrEngine/xr_ioc_cmd.cpp | 1 + src/xrSound/Sound.h | 1 + src/xrSound/SoundRender_CoreA.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index ded0c276b92..c9cd8e69918 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -901,6 +901,7 @@ void CCC_Register() CMD1(CCC_SND_Restart, "snd_restart"); CMD3(CCC_Mask, "snd_acceleration", &psSoundFlags, ss_Hardware); CMD3(CCC_Mask, "snd_efx", &psSoundFlags, ss_EFX); + CMD3(CCC_Mask, "snd_use_float32", &psSoundFlags, ss_UseFloat32); CMD4(CCC_Integer, "snd_targets", &psSoundTargets, 4, 256); CMD4(CCC_Integer, "snd_cache_size", &psSoundCacheSizeMB, 4, 64); CMD3(CCC_Token, "snd_precache_all", &psSoundPrecacheAll, snd_precache_all_token); diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index a1634a765f4..2b1e7ad51ff 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -60,6 +60,7 @@ enum : u32 { ss_Hardware = 1ul << 1ul, //!< Use hardware mixing only ss_EFX = 1ul << 2ul, //!< Use efx + ss_UseFloat32 = 1ul << 3ul, //!< Use 32-bit float sound instead of 16-bit }; enum : u32 diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 44ba672f947..314ab15c3ff 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -83,6 +83,8 @@ void CSoundRender_CoreA::_initialize() supports_float_pcm = alIsExtensionPresent("AL_EXT_FLOAT32") // first is OpenAL Soft, || alIsExtensionPresent("AL_EXT_float32"); // second is macOS + supports_float_pcm &= psSoundFlags.test(ss_UseFloat32); + auto auxSlot = ALuint(-1); #if defined(XR_HAS_EAX) // Check for EAX extension From 1251d10d8c642500ee4d73164b694bc9a37a098e Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Sun, 4 Feb 2024 19:20:31 +0500 Subject: [PATCH 120/497] GitHub Actions: use macos-13 runner for *BSD It has one additional CPU core, compared to macos-latest which is macos-12 at the time of creating this commit. So, by default, cross-platform-actions/action uses 3 CPU cores and 13 GiB of memory. Changing it to 4 cores and 14 GiB makes compilation almost identical to native x86_64 Linux/macOS builds. --- .github/workflows/cibuild.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index aeca23cf4ef..9d5304e5146 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -170,8 +170,8 @@ jobs: bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} - runs-on: macos-latest - timeout-minutes: 45 + runs-on: macos-13 # macOS 13 runner has 4 CPUs + timeout-minutes: 30 env: CFLAGS: "-w" CXXFLAGS: "-w" @@ -201,6 +201,8 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + cpu_count: 4 + memory: 14G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: runner-to-vm @@ -212,6 +214,8 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + cpu_count: 4 + memory: 14G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false @@ -223,6 +227,8 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + cpu_count: 4 + memory: 14G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false @@ -234,6 +240,8 @@ jobs: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} + cpu_count: 4 + memory: 14G environment_variables: CFLAGS CXXFLAGS # sync back is disabled due to: # 1) VM stalls during the process From 72a322aa9996254ee4a87501dac3e40227fbd1c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:15:34 +0000 Subject: [PATCH 121/497] build(deps): bump Externals/zlib from `f1f503d` to `abd3d1a` Bumps [Externals/zlib](https://github.com/madler/zlib) from `f1f503d` to `abd3d1a`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/f1f503da85d52e56aae11557b4d79a42bcaa2b86...abd3d1a28930f89375d4b41408b39f6c1be157b2) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index f1f503da85d..abd3d1a2893 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit f1f503da85d52e56aae11557b4d79a42bcaa2b86 +Subproject commit abd3d1a28930f89375d4b41408b39f6c1be157b2 From f8e8e990a600303af3ae5870e984599c618a94a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:15:36 +0000 Subject: [PATCH 122/497] build(deps): bump Externals/sse2neon from `cfaa59f` to `4a036e6` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `cfaa59f` to `4a036e6`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/cfaa59fc04fecb117c0a0f3fe9c82dece6f359ad...4a036e60472af7dd60a31421fa01557000b5c96b) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index cfaa59fc04f..4a036e60472 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit cfaa59fc04fecb117c0a0f3fe9c82dece6f359ad +Subproject commit 4a036e60472af7dd60a31421fa01557000b5c96b From ed0da712d6cc2f3abeccffcf036430b03897645a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 4 Feb 2024 21:51:01 +0500 Subject: [PATCH 123/497] CMake: refactored packaging This removes setting CMAKE_INSTALL_RPATH to ${CMAKE_INSTALL_FULL_LIBDIR} (as was introduced in #739, #1312) due to Fedora complaining about RPATH containing standard path /usr/lib64. It can be properly reintroduced later. (by saying 'properly' I mean that Fedora complain is valid, we should not have standard system paths in our RPATH) We also now reuse CMAKE_BUILD_RPATH_USE_ORIGIN appeared in CMake 3.14 instead of directly adding $ORIGIN to RPATH. Not sure about macOS, but using CMAKE_MACOSX_RPATH looks correct too. Needs testing. This also reimplements fix from #1423 in a more flexible way. Not tested. GitHub Actions CI now outputs artifacts in tar.gz, tar.Z or .sh form for Alpine and macOS (and for all possible future configurations that don't use deb or rpm. I know that for macOS has it's own packages, but they are not supported for now. --- .github/workflows/cibuild.yml | 14 ++++++------- CMakeLists.txt | 29 ++++++++++++--------------- cmake/packaging.cmake | 37 ++++++++++++----------------------- src/xrCore/CMakeLists.txt | 3 ++- src/xrCore/xrCore.cpp | 7 ++++--- 5 files changed, 38 insertions(+), 52 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 9d5304e5146..61a0ed8dfe7 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -133,7 +133,7 @@ jobs: - name: Install Fedora packages if: ${{ matrix.platform.name == 'Fedora' }} - run: dnf install -y git gcc gcc-c++ cmake SDL2-devel glew-devel lzo-devel libjpeg-turbo-devel openal-devel libogg-devel libtheora-devel libvorbis-devel + run: dnf install -y git gcc gcc-c++ rpmdevtools cmake SDL2-devel glew-devel lzo-devel libjpeg-turbo-devel openal-devel libogg-devel libtheora-devel libvorbis-devel - name: Set environment variables if: ${{ matrix.platform.cc != '' && matrix.platform.cxx != '' }} @@ -153,20 +153,20 @@ jobs: run: cmake --build build --config ${{ matrix.configuration }} --parallel $(nproc || sysctl -n hw.ncpu || echo 4) - name: Make package - if: ${{ steps.cmake-build.outcome == 'success' && matrix.platform.name == 'Ubuntu' }} + if: ${{ steps.cmake-build.outcome == 'success' }} id: make-package - working-directory: build #continue-on-error: true + working-directory: build run: | - make -j $(nproc || echo 4) package - file openxray_1.6.02_*.deb + cpack -B artifacts -C ${{ matrix.configuration }} -DCPACK_THREADS=$(nproc || sysctl -n hw.ncpu || echo 4) + file artifacts/openxray*.* - name: Upload OpenXRay artifact if: ${{ steps.make-package.outcome == 'success' }} uses: actions/upload-artifact@main with: - name: openxray_1.6.02_${{ matrix.configuration }}_${{ matrix.platform.arch }}_(github-${{ matrix.platform.cc }}-${{ github.run_number }}).deb - path: build/openxray_1.6.02_*.deb + name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc }}) + path: build/artifacts/openxray*.* bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b8e62e64ba..df403f20414 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,16 @@ cmake_minimum_required(VERSION 3.22) message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") -project(OpenXRay) +cmake_policy(SET CMP0048 NEW) +cmake_policy(SET CMP0095 NEW) + +project(OpenXRay + DESCRIPTION "OpenXRay is an improved version of the X-Ray Engine, \ + the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World." + VERSION 1.6.02 + HOMEPAGE_URL "https://github.com/OpenXRay/xray-16" + LANGUAGES CXX C +) set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -43,22 +52,8 @@ if (DISABLE_PORTABLE_MODE) add_compile_definitions(DISABLE_PORTABLE_MODE) endif() -if (NOT DEFINED ALLOW_RPATH) - set(ALLOW_RPATH TRUE) -endif() - -if (ALLOW_RPATH) - # Set the shared object search path for the installation - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") - - # Set the shared object search path for the build tree - # On Linux/BSD we can use $ORIGIN to search for modules next to the executable - if (NOT APPLE) - set(CMAKE_BUILD_RPATH $ORIGIN) - else() - set(CMAKE_BUILD_RPATH "${COMPILE_OUTPUT_FOLDER}") - endif() -endif() +set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE) +set(CMAKE_MACOSX_RPATH TRUE) message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") diff --git a/cmake/packaging.cmake b/cmake/packaging.cmake index 36a9535ec5f..9a59066fc47 100644 --- a/cmake/packaging.cmake +++ b/cmake/packaging.cmake @@ -1,17 +1,11 @@ -set(PACKAGE_PROJECT_NAME "OpenXRay") -set(PACKAGE_PROJECT_DESCRIPTION "OpenXRay is an improved version of the X-Ray Engine, the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World.") -set(PACKAGE_PROJECT_CONTACT "OpenXRay ") -set(PACKAGE_PROJECT_VERSION "1.6.02") -set(PACKAGE_PROJECT_HOME_URL "https://github.com/OpenXRay/xray-16") - if (UNIX) if (EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") - set(CPACK_PACKAGE_NAME ${PACKAGE_PROJECT_NAME}) - set(CPACK_FILE_NAME "openxray") - set(CPACK_PACKAGE_VERSION ${PACKAGE_PROJECT_VERSION}) - set(CPACK_PACKAGE_CONTACT ${PACKAGE_PROJECT_CONTACT}) - set(CPACK_PACKAGE_DESCRIPTION ${PACKAGE_PROJECT_DESCRIPTION}) - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CPACK_PACKAGE_DESCRIPTION}) + set(CPACK_PACKAGE_VENDOR "OpenXRay Team") + set(CPACK_PACKAGE_CONTACT "OpenXRay ") + set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) + + set(CPACK_PACKAGE_FILE_NAME "openxray-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") + set(CPACK_STRIP_FILES TRUE) set(CPACK_SOURCE_IGNORE_FILES "/.gitattributes") set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) @@ -22,30 +16,25 @@ if (UNIX) set(CPACK_GENERATOR DEB) set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") - set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) - set(CPACK_DEBIAN_REVISON "ubuntu-bionic-a1") # TODO: This one need to be detected dynamically - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_REVISON}_${_OS_ARCH}") - set(CPACK_DEBIAN_PACKAGE_SOURCE "OpenXRay") + set(CPACK_DEBIAN_PACKAGE_SECTION "games") - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${PACKAGE_PROJECT_HOME_URL}) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) endif() if (FEDORA_FOUND OR REDHAT_FOUND OR CENTOS_FOUND) set(CPACK_GENERATOR RPM) + set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") + + set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games") # -- set(CPACK_RPM_PACKAGE_AUTOREQPROV ON) set(CPACK_RPM_PACKAGE_AUTOREQ ON) set(CPACK_RPM_PACKAGE_AUTOPROV YES) - set(CPACK_RPM_PACKAGE_NAME ${PACKAGE_PROJECT_NAME}) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${PACKAGE_PROJECT_DESCRIPTION}) - set(CPACK_RPM_PACKAGE_VERSION ${PACKAGE_PROJECT_VERSION}) - set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games") - set(CPACK_RPM_PACKAGE_VENDOR ${PACKAGE_PROJECT_NAME}) - set(CPACK_RPM_PACKAGE_URL ${PACKAGE_PROJECT_HOME_URL}) + set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) endif() - INCLUDE(CPack) + include(CPack) endif() endif() diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index ccbbaacb2cb..4588ed2c130 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -464,6 +464,8 @@ endif() target_compile_definitions(xrCore PRIVATE XRCORE_EXPORTS + CMAKE_INSTALL_FULL_LIBDIR="${CMAKE_INSTALL_FULL_LIBDIR}" + CMAKE_INSTALL_FULL_DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}" CI=$ENV{CI} GITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} GITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} @@ -471,7 +473,6 @@ target_compile_definitions(xrCore GITHUB_REPOSITORY=$ENV{GITHUB_REPOSITORY} GIT_INFO_CURRENT_COMMIT=${GIT_SHA1} GIT_INFO_CURRENT_BRANCH=${GIT_BRANCH} - CMAKE_INSTALL_FULL_DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}" ) if (MEMORY_ALLOCATOR STREQUAL "mimalloc") diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 2f8161c289d..42bdb0bf71f 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -270,9 +270,10 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback c #ifdef _EDITOR // for EDITORS - no cache flags &= ~CLocatorAPI::flCacheFiles; #endif // _EDITOR -#ifndef DISABLE_PORTABLE_MODE - flags |= CLocatorAPI::flScanAppRoot; -#endif + + if (xr_stricmp(ApplicationPath, MACRO_TO_STRING(CMAKE_INSTALL_FULL_DATAROOTDIR)) != 0) + flags |= CLocatorAPI::flScanAppRoot; + #ifndef _EDITOR #ifndef ELocatorAPIH if (strstr(Params, "-file_activity") != nullptr) From 37c89842faebf9bda054f8dd05814bce4bf6fd4a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 5 Feb 2024 21:39:16 +0500 Subject: [PATCH 124/497] GitHub Actions: return run id number to the build artifacts [skip ci] --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 61a0ed8dfe7..87fd27d2163 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -165,7 +165,7 @@ jobs: if: ${{ steps.make-package.outcome == 'success' }} uses: actions/upload-artifact@main with: - name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc }}) + name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} (${{ matrix.platform.cc }} github-${{ github.run_number }}) path: build/artifacts/openxray*.* bsd: From f11c6a3ddcfbd3eed7f02ec3e3f204b7caafd99b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 5 Feb 2024 21:43:16 +0500 Subject: [PATCH 125/497] GitHub Actions: use 4 CPU threads for BSD builds --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 87fd27d2163..ee2aab62fc8 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -232,7 +232,7 @@ jobs: environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false - run: cmake --build build --config ${{ matrix.Configuration }} --parallel 3 + run: cmake --build build --config ${{ matrix.Configuration }} --parallel 4 - name: Finalize uses: cross-platform-actions/action@v0.22.0 From e57ff1102e1633cd626e3d37ce8d6076e8afa04b Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Tue, 6 Feb 2024 00:35:37 +0500 Subject: [PATCH 126/497] GitHub Actions: fixed labeler --- .github/labeler.yml | 56 +++++++++++++++++++++--------- .github/labeler_on_new_pr.yml | 4 ++- .github/labeler_on_pr_approved.yml | 8 +++-- .github/labeler_on_pr_merged.yml | 4 ++- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index eadb617af6c..944ae2da63e 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,40 +1,62 @@ AI: -- src/xrAICore/**/* -- src/xrGame/ai/**/* +- changed-files: + - any-glob-to-any-file: + - src/xrAICore/**/* + - src/xrGame/ai/**/* Documentation: -- docs/**/* +- changed-files: + - any-glob-to-any-file: + - docs/**/* External (3rd party): -- Externals/**/* +- changed-files: + - any-glob-to-any-file: + - Externals/**/* Game assets: -- res/**/* +- changed-files: + - any-glob-to-any-file: + - res/**/* Infrastructure: -- .github/**/* +- changed-files: + - any-glob-to-any-file: + - .github/**/* Physics: -- src/xrPhysics/**/* +- changed-files: + - any-glob-to-any-file: + - src/xrPhysics/**/* Renderer: -- src/Layers/**/* +- changed-files: + - any-glob-to-any-file: + - src/Layers/**/* DirectX: -- src/Layers/xrRenderDX* -- src/Layers/xrRenderPC_R1 -- src/Layers/xrRenderPC_R2 -- src/Layers/xrRenderPC_R4 +- changed-files: + - any-glob-to-any-file: + - src/Layers/xrRenderDX* + - src/Layers/xrRenderPC_R1 + - src/Layers/xrRenderPC_R2 + - src/Layers/xrRenderPC_R4 OpenGL: -- src/Layers/xrRenderGL -- src/Layers/xrRenderPC_GL +- changed-files: + - any-glob-to-any-file: + - src/Layers/xrRenderGL + - src/Layers/xrRenderPC_GL Sound: -- src/xrSound/**/* +- changed-files: + - any-glob-to-any-file: + - src/xrSound/**/* UI: -- src/xrUICore/**/* -- src/xrGame/ui/**/* +- changed-files: + - any-glob-to-any-file: + - src/xrUICore/**/* + - src/xrGame/ui/**/* diff --git a/.github/labeler_on_new_pr.yml b/.github/labeler_on_new_pr.yml index cbfe80da528..32dfeb06dd6 100644 --- a/.github/labeler_on_new_pr.yml +++ b/.github/labeler_on_new_pr.yml @@ -1,2 +1,4 @@ pending review: -- '**/*' +- changed-files: + - any-glob-to-any-file: + - '**/*' diff --git a/.github/labeler_on_pr_approved.yml b/.github/labeler_on_pr_approved.yml index e6ca8ee3c14..7c22ae58769 100644 --- a/.github/labeler_on_pr_approved.yml +++ b/.github/labeler_on_pr_approved.yml @@ -1,5 +1,9 @@ pending review: -- '!**/*' +- changed-files: + - any-glob-to-any-file: + - '!**/*' ready to merge: -- '**/*' +- changed-files: + - any-glob-to-any-file: + - '**/*' diff --git a/.github/labeler_on_pr_merged.yml b/.github/labeler_on_pr_merged.yml index 23f7153853a..aaa6fd4b6bb 100644 --- a/.github/labeler_on_pr_merged.yml +++ b/.github/labeler_on_pr_merged.yml @@ -1,2 +1,4 @@ ready to merge: -- '!**/*' +- changed-files: + - any-glob-to-any-file: + - '!**/*' From ecfc127acc4ae120db9d0805d6d710b92a5b0dfc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 6 Feb 2024 01:15:34 +0500 Subject: [PATCH 127/497] GitHub Actions: use hardcoded number of threads when building --- .github/workflows/cibuild.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index ee2aab62fc8..3c88a91a5bc 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -97,7 +97,7 @@ jobs: - { name: Fedora, os: ubuntu-latest, arch: x86_64, cc: gcc, container: 'fedora:latest', } #- { name: Haiku, os: ubuntu-latest, arch: x86_64, cc: x86_64-unknown-haiku-gcc, cxx: x86_64-unknown-haiku-g++, container: 'haiku/cross-compiler:x86_64-r1beta4', } - { name: macOS, os: macos-13, arch: x86_64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=13.6" } - - { name: macOS, os: macos-14, arch: arm64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0" } + - { name: macOS, os: macos-14, arch: arm64, cc: clang, flags: "-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0", threads: 3 } configuration: [Debug, Release] @@ -150,7 +150,7 @@ jobs: - name: Run CMake Build id: cmake-build - run: cmake --build build --config ${{ matrix.configuration }} --parallel $(nproc || sysctl -n hw.ncpu || echo 4) + run: cmake --build build --config ${{ matrix.configuration }} --parallel ${{ matrix.platform.threads || 4 }} - name: Make package if: ${{ steps.cmake-build.outcome == 'success' }} @@ -158,7 +158,7 @@ jobs: #continue-on-error: true working-directory: build run: | - cpack -B artifacts -C ${{ matrix.configuration }} -DCPACK_THREADS=$(nproc || sysctl -n hw.ncpu || echo 4) + cpack -B artifacts -C ${{ matrix.configuration }} -DCPACK_THREADS=${{ matrix.platform.threads || 4 }} file artifacts/openxray*.* - name: Upload OpenXRay artifact From 41f311361ec509868c644a78f9ef9e9a50fa8c01 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Tue, 6 Feb 2024 11:47:47 +0100 Subject: [PATCH 128/497] Fix incorrect format specifiers (#173) (#1557) --- src/xrCore/Animation/SkeletonMotions.cpp | 2 +- src/xrCore/LocatorAPI.cpp | 2 +- src/xrCore/xrMemory.cpp | 2 +- src/xrGame/configs_dumper.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xrCore/Animation/SkeletonMotions.cpp b/src/xrCore/Animation/SkeletonMotions.cpp index 4336edda9ef..41cedbea6a9 100644 --- a/src/xrCore/Animation/SkeletonMotions.cpp +++ b/src/xrCore/Animation/SkeletonMotions.cpp @@ -332,7 +332,7 @@ void motions_container::dump() sz += it->second->mem_usage(); Msg("#%3d: [%3d/%5d Kb] - %s", k, it->second->m_dwReference, it->second->mem_usage() / 1024, it->first.c_str()); } - Msg("--- items: %d, mem usage: %d Kb ", container.size(), sz / 1024); + Msg("--- items: %zu, mem usage: %zu Kb ", container.size(), sz / 1024); Log("--- motion container --- end."); } diff --git a/src/xrCore/LocatorAPI.cpp b/src/xrCore/LocatorAPI.cpp index 73a08a99367..b14f56bb490 100644 --- a/src/xrCore/LocatorAPI.cpp +++ b/src/xrCore/LocatorAPI.cpp @@ -1021,7 +1021,7 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) }; const size_t M2 = Memory.mem_usage(); - Msg("FS: %d files cached %d archives, %dKb memory used.", m_files.size(), m_archives.size(), (M2 - M1) / 1024); + Msg("FS: %zu files cached %zu archives, %zuKb memory used.", m_files.size(), m_archives.size(), (M2 - M1) / 1024); m_Flags.set(flReady, true); diff --git a/src/xrCore/xrMemory.cpp b/src/xrCore/xrMemory.cpp index df3e00842e4..efe68a972f0 100644 --- a/src/xrCore/xrMemory.cpp +++ b/src/xrCore/xrMemory.cpp @@ -133,7 +133,7 @@ XRCORE_API void log_vminfo() { size_t w_free, w_reserved, w_committed; vminfo(&w_free, &w_reserved, &w_committed); - Msg("* [ %s ]: free[%d K], reserved[%d K], committed[%d K]", SDL_GetPlatform(), w_free / 1024, w_reserved / 1024, w_committed / 1024); + Msg("* [ %s ]: free[%zu K], reserved[%zu K], committed[%zu K]", SDL_GetPlatform(), w_free / 1024, w_reserved / 1024, w_committed / 1024); } size_t xrMemory::mem_usage() diff --git a/src/xrGame/configs_dumper.cpp b/src/xrGame/configs_dumper.cpp index 1ec934800ea..ea914df358c 100644 --- a/src/xrGame/configs_dumper.cpp +++ b/src/xrGame/configs_dumper.cpp @@ -146,7 +146,7 @@ void configs_dumper::write_configs() string16 tmp_strbuff; for (active_objects_t::size_type i = 0; i < aobjs_count; ++i) { - xr_sprintf(tmp_strbuff, "%d", i + 1); + xr_sprintf(tmp_strbuff, "%zu", i + 1); m_active_params.dump(active_objects[i], tmp_strbuff, active_params_dumper); } active_params_dumper.save_as(m_dump_result); From fa4f48588985b4452497afd8a10e1499ad27cdb8 Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Tue, 6 Feb 2024 17:07:57 +0500 Subject: [PATCH 129/497] GitHub Actions: mirror to gitflic.ru and abf.io --- .github/workflows/mirror.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 58fc61b3676..828a76badc6 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -3,15 +3,28 @@ name: Mirror on: [push, delete, workflow_dispatch] jobs: - to_bitbucket: + mirror: if: github.repository == 'OpenXRay/xray-16' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pixta-dev/repository-mirroring-action@v1.1.1 + + - name: Bitbucket.org + uses: pixta-dev/repository-mirroring-action@v1.1.1 with: target_repo_url: git@bitbucket.org:OpenXRay/xray-16.git ssh_private_key: ${{ secrets.RABOTYAGA_BITBUCKET_PRIVATE_SSH_KEY }} + - name: gitflic.ru + uses: pixta-dev/repository-mirroring-action@v1.1.1 + with: + target_repo_url: git@gitflic.ru:openxray/xray-16.git + ssh_private_key: ${{ secrets.GITFLIC_PRIVATE_SSH_KEY }} + + - name: abf.io + uses: pixta-dev/repository-mirroring-action@v1.1.1 + with: + target_repo_url: git@abf.io:openxray/xray-16.git + ssh_private_key: ${{ secrets.ABF_IO_PRIVATE_SSH_KEY }} From c4f1191ea6e7ddc00724db762c3123580e195d71 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 6 Feb 2024 04:18:53 +0500 Subject: [PATCH 130/497] GitHub Actions: increase timeout for *BSD builds to 35 minutes [skip ci] --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 3c88a91a5bc..4697121fe73 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -171,7 +171,7 @@ jobs: bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} runs-on: macos-13 # macOS 13 runner has 4 CPUs - timeout-minutes: 30 + timeout-minutes: 35 env: CFLAGS: "-w" CXXFLAGS: "-w" From 046c2871cba00f4c92ae1c73f364ae00b770f8c5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 7 Feb 2024 00:41:36 +0500 Subject: [PATCH 131/497] Revert "Use game materials system for a bit better sound occlusion" This reverts commit efe60860796072cc6e2cf6403563e6d70b8c4648. --- src/xrSound/CMakeLists.txt | 1 - src/xrSound/SoundRender_Scene.cpp | 6 +----- src/xrSound/xrSound.vcxproj | 3 --- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 2250de18246..a626f73fb96 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -141,7 +141,6 @@ target_link_libraries(xrSound xrMiscMath xrAPI xrCDB - xrMaterialSystem ${OPENAL_LIBRARY} Ogg::Ogg Vorbis::Vorbis diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 50392e35aec..72d739e854e 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -2,7 +2,6 @@ #include "Common/LevelStructure.hpp" #include "xrCDB/Intersect.hpp" -#include "xrMaterialSystem/GameMtlLib.h" #include "SoundRender_Core.h" #include "SoundRender_Scene.h" @@ -311,10 +310,7 @@ float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) occ[0].set(V[T.verts[0]]); occ[1].set(V[T.verts[1]]); occ[2].set(V[T.verts[2]]); - - const SGameMtl* mtl = GMLib.GetMaterialByIdx(T.material); - const float occlusion = fis_zero(mtl->fSndOcclusionFactor) ? 0.1f : mtl->fSndOcclusionFactor; - occ_value = psSoundOcclusionScale * occlusion; + occ_value = psSoundOcclusionScale; } } } diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index 2763301039d..dfaf3f000dd 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -95,9 +95,6 @@ {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - {2c419512-6eee-4707-bc51-2e834855552e} - From a2e6f064c5c2a5895e449082520b76b55d809a69 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 7 Feb 2024 21:33:13 +0500 Subject: [PATCH 132/497] CMake: added XRAY build ID calculation This was ported to CMake from C++ --- CMakeLists.txt | 3 +++ cmake/utils.cmake | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index df403f20414..7ba9d35bff7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(utils) +calculate_xray_build_id(XRAY_BUILD_ID) +message(STATUS "XRAY_BUILD_ID: ${XRAY_BUILD_ID}") + set_git_info() # Output all libraries and executable to one folder diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 492f4da251a..822ae6b09e3 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -75,4 +75,43 @@ function(set_git_info) message(STATUS "git branch: ${GIT_BRANCH}") endfunction() +function(calculate_xray_build_id output) + set(XRAY_START_DAY 31) + set(XRAY_START_MONTH 1) + set(XRAY_START_YEAR 1999) + + set(DAYS_IN_MONTH 0 31 28 31 30 31 30 31 31 30 31 30 31) # first is dummy + + # Acquire timestamp in "date month year" format + string(TIMESTAMP current_date "%d %m %Y") + + # Transform string into a list, then extract 3 separate variables + string(REPLACE " " ";" current_date_list ${current_date}) + list(GET current_date_list 0 CURRENT_DATE_DAY) + list(GET current_date_list 1 CURRENT_DATE_MONTH) + list(GET current_date_list 2 CURRENT_DATE_YEAR) + + # Calculate XRAY build ID + math(EXPR build_id "(${CURRENT_DATE_YEAR} - ${XRAY_START_YEAR}) * 365 + ${CURRENT_DATE_DAY} - ${XRAY_START_DAY}") + + set(it 1) + while(it LESS CURRENT_DATE_MONTH) + list(GET DAYS_IN_MONTH ${it} days) + math(EXPR build_id "${build_id} + ${days}") + + math(EXPR it "${it} + 1") + endwhile() + + set(it 1) + while(it LESS XRAY_START_MONTH) + list(GET DAYS_IN_MONTH ${it} days) + math(EXPR build_id "${build_id} - ${days}") + + math(EXPR it "${it} + 1") + endwhile() + + # Set requested variable + set(${output} ${build_id} PARENT_SCOPE) +endfunction() + include(packaging) From 52c3e2e3f15a9bfeecc85f1283230bec63e588ce Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 7 Feb 2024 21:59:12 +0500 Subject: [PATCH 133/497] CMake: use XRAY build ID as CMAKE_PROJECT_VERSION_TWEAK --- CMakeLists.txt | 18 +++++++++--------- cmake/utils.cmake | 2 -- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba9d35bff7..8a669a43019 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,13 +5,19 @@ message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0095 NEW) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include(utils) +calculate_xray_build_id(XRAY_BUILD_ID) + project(OpenXRay DESCRIPTION "OpenXRay is an improved version of the X-Ray Engine, \ - the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World." - VERSION 1.6.02 + the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World." + VERSION 1.6.02.${XRAY_BUILD_ID} HOMEPAGE_URL "https://github.com/OpenXRay/xray-16" LANGUAGES CXX C ) +message(STATUS "CMAKE_PROJECT_VERSION: ${}") set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -33,13 +39,7 @@ if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) endif() include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -include(utils) - -calculate_xray_build_id(XRAY_BUILD_ID) -message(STATUS "XRAY_BUILD_ID: ${XRAY_BUILD_ID}") +include(packaging) set_git_info() diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 822ae6b09e3..2a052b011f6 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -113,5 +113,3 @@ function(calculate_xray_build_id output) # Set requested variable set(${output} ${build_id} PARENT_SCOPE) endfunction() - -include(packaging) From 289f78b5280c1ca8ad7becd1a5c428647fb18c14 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 7 Feb 2024 22:10:27 +0500 Subject: [PATCH 134/497] CMake: move packaging related stuff from utils.cmake to packaging.cmake --- cmake/packaging.cmake | 84 ++++++++++++++++++++++++------------------- cmake/utils.cmake | 26 -------------- 2 files changed, 48 insertions(+), 62 deletions(-) diff --git a/cmake/packaging.cmake b/cmake/packaging.cmake index 9a59066fc47..cb188e7aa70 100644 --- a/cmake/packaging.cmake +++ b/cmake/packaging.cmake @@ -1,48 +1,60 @@ -if (UNIX) - if (EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") - set(CPACK_PACKAGE_VENDOR "OpenXRay Team") - set(CPACK_PACKAGE_CONTACT "OpenXRay ") - set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) +set(CPACK_PACKAGE_VENDOR "OpenXRay Team") +set(CPACK_PACKAGE_CONTACT "OpenXRay ") +set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) - set(CPACK_PACKAGE_FILE_NAME "openxray-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_PACKAGE_FILE_NAME "openxray-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") - set(CPACK_STRIP_FILES TRUE) - set(CPACK_SOURCE_IGNORE_FILES "/.gitattributes") - set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) - set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/License.txt) +set(CPACK_STRIP_FILES TRUE) +set(CPACK_SOURCE_IGNORE_FILES "/.gitattributes") +set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) +set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/License.txt) - # --- SELECT PROPER CPACK GENERATOR --- - if (DEBIAN_FOUND) - set(CPACK_GENERATOR DEB) +if (UNIX) + # Try to find specific OS files to determine type of linux distribution + find_file(FEDORA_FOUND fedora-release PATHS /etc) + find_file(REDHAT_FOUND redhat-release inittab.RH PATHS /etc) + find_file(CENTOS_FOUND centos-release PATHS /etc) + # If we found debian then we don't need to check further for ubuntu + # as it uses debian core. + find_file(DEBIAN_FOUND debian_version debconf.conf PATHS /etc) + + # -------------------------------------------------- + # Uninstall target + # -------------------------------------------------- + # To clean system folder from libraries and binaries + # that was installed with `sudo make install` + # just run `sudo make uninstall` + if (NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + + add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + endif() - set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") + # --- SELECT PROPER CPACK GENERATOR --- + if (DEBIAN_FOUND) + set(CPACK_GENERATOR DEB) - set(CPACK_DEBIAN_PACKAGE_SECTION "games") - set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) - set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) - endif() + set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") - if (FEDORA_FOUND OR REDHAT_FOUND OR CENTOS_FOUND) - set(CPACK_GENERATOR RPM) + set(CPACK_DEBIAN_PACKAGE_SECTION "games") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) + endif() - set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") + if (FEDORA_FOUND OR REDHAT_FOUND OR CENTOS_FOUND) + set(CPACK_GENERATOR RPM) - set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games") - # -- set(CPACK_RPM_PACKAGE_AUTOREQPROV ON) - set(CPACK_RPM_PACKAGE_AUTOREQ ON) - set(CPACK_RPM_PACKAGE_AUTOPROV YES) - set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) - endif() + set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") - include(CPack) + set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games") + # -- set(CPACK_RPM_PACKAGE_AUTOREQPROV ON) + set(CPACK_RPM_PACKAGE_AUTOREQ ON) + set(CPACK_RPM_PACKAGE_AUTOPROV YES) + set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) endif() -endif() - -# TODO: Need to be implemented in future -if (WIN32) - #set(CPACK_GENERATOR NSIS) -endif() -if (APPLE) - #set(CPACK_GENERATOR "DRAGNDROP") + include(CPack) endif() diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 2a052b011f6..9262a7993bf 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -31,32 +31,6 @@ else (CMAKE_SIZEOF_VOID_P EQUAL 4) set(ARCH_TYPE x86) endif() -# Unix system configuration -if (UNIX) - # Try to find specific OS files to determine type of linux distribution - find_file(FEDORA_FOUND fedora-release PATHS /etc) - find_file(REDHAT_FOUND redhat-release inittab.RH PATHS /etc) - find_file(CENTOS_FOUND centos-release PATHS /etc) - # If we found debian then we don't need to check further for ubuntu - # as it uses debian core. - find_file(DEBIAN_FOUND debian_version debconf.conf PATHS /etc) - - # -------------------------------------------------- - # Uninstall target - # -------------------------------------------------- - # To clean system folder from libraries and binaries - # that was installed with `sudo make install` - # just run `sudo make uninstall` - if (NOT TARGET uninstall) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - - add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) - endif() -endif() - function(set_git_info) execute_process(COMMAND git rev-parse --verify HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" From a66a0de988649a6df2c0a510d856f9d7be1f27d8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 9 Feb 2024 16:29:53 +0500 Subject: [PATCH 135/497] xrGame/action_base_script.cpp: return "weight" script property (#382) --- src/xrGame/action_base_script.cpp | 3 +-- src/xrGame/script_action_wrapper.cpp | 36 +++++++++++++--------------- src/xrGame/script_action_wrapper.h | 8 ++----- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/xrGame/action_base_script.cpp b/src/xrGame/action_base_script.cpp index 9c956eaf3dd..6bc1e2f0a20 100644 --- a/src/xrGame/action_base_script.cpp +++ b/src/xrGame/action_base_script.cpp @@ -38,8 +38,7 @@ IC static void CScriptActionBase_Export(lua_State* luaState) .def("initialize", &CScriptActionBase::initialize, &CScriptActionWrapper::initialize_static) .def("execute", &CScriptActionBase::execute, &CScriptActionWrapper::execute_static) .def("finalize", &CScriptActionBase::finalize, &CScriptActionWrapper::finalize_static) - // .def("weight", &CScriptActionBase::weight, - //&CScriptActionWrapper::weight_static) + .def("weight", &CScriptActionBase::weight, &CScriptActionWrapper::weight_static) .def("set_weight", &CScriptActionBase::set_weight) #ifdef LOG_ACTION .def("show", &CScriptActionBase::show) diff --git a/src/xrGame/script_action_wrapper.cpp b/src/xrGame/script_action_wrapper.cpp index 8fe76c61d7e..cde7923b50e 100644 --- a/src/xrGame/script_action_wrapper.cpp +++ b/src/xrGame/script_action_wrapper.cpp @@ -28,23 +28,19 @@ void CScriptActionWrapper::execute() { luabind::call_member(this, "execute void CScriptActionWrapper::execute_static(CScriptActionBase* action) { action->CScriptActionBase::execute(); } void CScriptActionWrapper::finalize() { luabind::call_member(this, "finalize"); } void CScriptActionWrapper::finalize_static(CScriptActionBase* action) { action->CScriptActionBase::finalize(); } -// CScriptActionWrapper::_edge_value_type CScriptActionWrapper::weight (const CSConditionState &condition0, const -// CSConditionState &condition1) const -//{ -// _edge_value_type _weight = -// luabind::call_member<_edge_value_type>(const_cast(this),"weight",condition0,condition1); -// if (_weight < min_weight()) { -// GEnv.ScriptEngine->script_log (LuaMessageType::Error,"Weight is less than effect count! It is corrected from -//%d -// to %d",_weight,min_weight()); -// _weight = min_weight(); -// } -// return (_weight); -//} -// -// CScriptActionWrapper::_edge_value_type CScriptActionWrapper::weight_static (CScriptActionBase *action, const -// CSConditionState &condition0, const CSConditionState &condition1) -//{ -// return (((const -// CScriptActionWrapper*)action)->CScriptActionBase::weight(condition0,condition1)); -//} + +CScriptActionWrapper::edge_value_type CScriptActionWrapper::weight(const CSConditionState& condition0, const CSConditionState& condition1) const +{ + auto _weight = luabind::call_member(const_cast(this), "weight", condition0, condition1); + if (_weight < min_weight()) + { + GEnv.ScriptEngine->script_log(LuaMessageType::Error, "Weight is less than effect count! It is corrected from %d to %d", _weight, min_weight()); + _weight = min_weight(); + } + return _weight; +} + +CScriptActionWrapper::edge_value_type CScriptActionWrapper::weight_static(CScriptActionBase* action, const CSConditionState& condition0, const CSConditionState& condition1) +{ + return ((const CScriptActionWrapper*)action)->CScriptActionBase::weight(condition0, condition1); +} diff --git a/src/xrGame/script_action_wrapper.h b/src/xrGame/script_action_wrapper.h index a31dc9d11a9..46a5e9eef13 100644 --- a/src/xrGame/script_action_wrapper.h +++ b/src/xrGame/script_action_wrapper.h @@ -22,12 +22,8 @@ class CScriptActionWrapper : public CScriptActionBase, public luabind::wrap_base static void execute_static(CScriptActionBase* action); virtual void finalize(); static void finalize_static(CScriptActionBase* action); - // virtual _edge_value_type weight (const CSConditionState &condition0, const CSConditionState - //&condition1) - // const; - // static _edge_value_type weight_static (CScriptActionBase *action, const CSConditionState &condition0, - //const - // CSConditionState &condition1); + virtual edge_value_type weight(const CSConditionState& condition0, const CSConditionState& condition1) const; + static edge_value_type weight_static(CScriptActionBase* action, const CSConditionState& condition0, const CSConditionState& condition1); }; #include "script_action_wrapper_inline.h" From 62b347d856d480dbec8e4ecda0512fb720abdb3a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 9 Feb 2024 16:30:40 +0500 Subject: [PATCH 136/497] xrUICore/Static/UIStatic.cpp: constify variables Removed excess scope --- src/xrUICore/Static/UIStatic.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/xrUICore/Static/UIStatic.cpp b/src/xrUICore/Static/UIStatic.cpp index 61aae6c0148..1cb3e2ee3ab 100644 --- a/src/xrUICore/Static/UIStatic.cpp +++ b/src/xrUICore/Static/UIStatic.cpp @@ -106,9 +106,8 @@ void CUIStatic::DrawTexture() { if (m_UIStaticItem.GetFixedLTWhileHeading()) { - float t1, t2; - t1 = rect.width(); - t2 = rect.height(); + const float t1 = rect.width(); + const float t2 = rect.height(); rect.y2 = rect.y1 + t1; rect.x2 = rect.x1 + t2; } @@ -117,20 +116,17 @@ void CUIStatic::DrawTexture() } else { - Frect r = {0.0f, 0.0f, m_UIStaticItem.GetTextureRect().width(), m_UIStaticItem.GetTextureRect().height()}; + const Frect r = { 0.0f, 0.0f, m_UIStaticItem.GetTextureRect().width(), m_UIStaticItem.GetTextureRect().height() }; + if (Heading()) { - if (Heading()) - { - float t1, t2; - t1 = rect.width(); - t2 = rect.height(); - rect.y2 = rect.y1 + t1; - rect.x2 = rect.x1 + t2; - } - - m_UIStaticItem.SetSize(Fvector2().set(r.width(), r.height())); + const float t1 = rect.width(); + const float t2 = rect.height(); + rect.y2 = rect.y1 + t1; + rect.x2 = rect.x1 + t2; } + + m_UIStaticItem.SetSize(Fvector2().set(r.width(), r.height())); } if (Heading()) From 5aec8e6a4fd247b39303a980132181176cbddf5d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 9 Feb 2024 16:40:18 +0500 Subject: [PATCH 137/497] xrUICore/Static/UIStatic.h: moved some script specific functions to _script.cpp --- src/xrUICore/Static/UIStatic.h | 16 ---------------- src/xrUICore/Static/UIStatic_script.cpp | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/xrUICore/Static/UIStatic.h b/src/xrUICore/Static/UIStatic.h index 22f40ca4c4c..16e235724ee 100644 --- a/src/xrUICore/Static/UIStatic.h +++ b/src/xrUICore/Static/UIStatic.h @@ -54,22 +54,6 @@ class XRUICORE_API CUIStatic : public CUIWindow, public ITextureOwner, public CU TextItemControl()->SetTextColor(color); } - void SetTextColor_script(int a, int r, int g, int b) - { - TextItemControl()->SetTextColor(color_argb(a, r, g, b)); - } - - u32 GetTextAlign_script() - { - return static_cast(TextItemControl()->GetTextAlignment()); - } - - void SetTextAlign_script(u32 align) - { - TextItemControl()->SetTextAlignment((CGameFont::EAligment)align); - TextItemControl()->GetFont()->SetAligment((CGameFont::EAligment)align); - } - virtual void SetTextX(float text_x) { TextItemControl()->m_TextOffset.x = text_x; } virtual void SetTextY(float text_y) { TextItemControl()->m_TextOffset.y = text_y; } virtual float GetTextX() { return TextItemControl()->m_TextOffset.x; } diff --git a/src/xrUICore/Static/UIStatic_script.cpp b/src/xrUICore/Static/UIStatic_script.cpp index 91982564bbf..4e41ea6e238 100644 --- a/src/xrUICore/Static/UIStatic_script.cpp +++ b/src/xrUICore/Static/UIStatic_script.cpp @@ -52,7 +52,10 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("SetColor", &CUIStatic::SetColor) .def("GetColor", &CUIStatic::GetColor) - .def("SetTextColor", &CUIStatic::SetTextColor_script) + .def("SetTextColor", +[](CUIStatic* self, int a, int r, int g, int b) + { + self->SetTextColor(color_argb(a, r, g, b)); + }) .def("Init", +[](CUIStatic* self, float x, float y, float width, float height) { @@ -82,8 +85,15 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("SetStretchTexture", &CUIStatic::SetStretchTexture) .def("GetStretchTexture", &CUIStatic::GetStretchTexture) - .def("SetTextAlign", &CUIStatic::SetTextAlign_script) - .def("GetTextAlign", &CUIStatic::GetTextAlign_script) + .def("SetTextAlign", +[](CUIStatic* self, u32 align) + { + self->TextItemControl()->SetTextAlignment(static_cast(align)); + self->TextItemControl()->GetFont()->SetAligment(static_cast(align)); + }) + .def("GetTextAlign", +[](CUIStatic* self) -> u32 + { + return static_cast(self->TextItemControl()->GetTextAlignment()); + }) .def("SetHeading", &CUIStatic::SetHeading) .def("GetHeading", &CUIStatic::GetHeading) From 56832f1dab59e4f0b25e86235f7b21bb8b540e08 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 10 Feb 2024 02:27:00 +0500 Subject: [PATCH 138/497] Replaced CUITextWnd with CUIStatic in the engine (#382) --- src/xrGame/UIGameAHunt.cpp | 12 +++---- src/xrGame/UIGameAHunt.h | 5 ++- src/xrGame/UIGameCTA.cpp | 32 ++++++++--------- src/xrGame/UIGameCTA.h | 27 +++++++-------- src/xrGame/UIGameDM.cpp | 22 ++++++------ src/xrGame/UIGameDM.h | 21 ++++++------ src/xrGame/UIGameTDM.cpp | 14 ++++---- src/xrGame/UIGameTDM.h | 7 ++-- src/xrGame/UIPlayerItem.cpp | 12 +++---- src/xrGame/UIPlayerItem.h | 6 ++-- src/xrGame/UIZoneMap.cpp | 2 +- src/xrGame/UIZoneMap.h | 2 +- src/xrGame/ui/ChangeWeatherDialog.cpp | 12 +++---- src/xrGame/ui/ChangeWeatherDialog.hpp | 5 ++- src/xrGame/ui/UIAchievements.cpp | 4 +-- src/xrGame/ui/UIAchievements.h | 5 ++- src/xrGame/ui/UIActorMenu.h | 1 - src/xrGame/ui/UIBoosterInfo.cpp | 2 +- src/xrGame/ui/UIBoosterInfo.h | 3 +- src/xrGame/ui/UIChangeMap.cpp | 8 ++--- src/xrGame/ui/UIChangeMap.h | 5 ++- src/xrGame/ui/UICharacterInfo.cpp | 2 +- src/xrGame/ui/UIChatWnd.cpp | 42 ++++++++++++----------- src/xrGame/ui/UIChatWnd.h | 5 ++- src/xrGame/ui/UIDebugFonts.cpp | 2 +- src/xrGame/ui/UIDemoPlayControl.cpp | 4 +-- src/xrGame/ui/UIDemoPlayControl.h | 3 +- src/xrGame/ui/UIDragDropReferenceList.cpp | 2 +- src/xrGame/ui/UIDragDropReferenceList.h | 2 +- src/xrGame/ui/UIGameLog.cpp | 6 ++-- src/xrGame/ui/UIGameLog.h | 3 +- src/xrGame/ui/UIHelper.cpp | 19 ---------- src/xrGame/ui/UIHelper.h | 2 -- src/xrGame/ui/UIHudStatesWnd.cpp | 12 +++---- src/xrGame/ui/UIHudStatesWnd.h | 13 ++++--- src/xrGame/ui/UIInventoryUtilities.cpp | 2 +- src/xrGame/ui/UIInventoryUtilities.h | 4 +-- src/xrGame/ui/UIItemInfo.cpp | 10 +++--- src/xrGame/ui/UIItemInfo.h | 9 +++-- src/xrGame/ui/UIKeyBinding.cpp | 9 +++-- src/xrGame/ui/UIListItemServer.h | 13 +++---- src/xrGame/ui/UILogsWnd.cpp | 8 ++--- src/xrGame/ui/UILogsWnd.h | 9 +++-- src/xrGame/ui/UIMMShniaga.cpp | 8 ++--- src/xrGame/ui/UIMMShniaga.h | 9 +++-- src/xrGame/ui/UIMPChangeMapAdm.cpp | 4 +-- src/xrGame/ui/UIMPChangeMapAdm.h | 3 +- src/xrGame/ui/UIMPPlayersAdm.cpp | 10 +++--- src/xrGame/ui/UIMPPlayersAdm.h | 5 ++- src/xrGame/ui/UIMainIngameWnd.cpp | 5 ++- src/xrGame/ui/UIMainIngameWnd.h | 4 +-- src/xrGame/ui/UIMapInfo.cpp | 13 ++++--- src/xrGame/ui/UIMoneyIndicator.cpp | 4 +-- src/xrGame/ui/UIMoneyIndicator.h | 6 ++-- src/xrGame/ui/UIMpTradeWnd.h | 11 +++--- src/xrGame/ui/UIMpTradeWnd_init.cpp | 18 +++++----- src/xrGame/ui/UIMpTradeWnd_misc.cpp | 2 +- src/xrGame/ui/UINewsItemWnd.cpp | 10 +++--- src/xrGame/ui/UINewsItemWnd.h | 7 ++-- src/xrGame/ui/UIOutfitInfo.cpp | 4 +-- src/xrGame/ui/UIOutfitInfo.h | 2 +- src/xrGame/ui/UIPdaKillMessage.cpp | 2 +- src/xrGame/ui/UIPdaKillMessage.h | 10 +++--- src/xrGame/ui/UIPdaMsgListItem.cpp | 8 ++--- src/xrGame/ui/UIPdaMsgListItem.h | 8 ++--- src/xrGame/ui/UIPdaWnd.cpp | 5 ++- src/xrGame/ui/UIPdaWnd.h | 3 +- src/xrGame/ui/UIRankFaction.cpp | 16 ++++----- src/xrGame/ui/UIRankFaction.h | 17 +++++---- src/xrGame/ui/UIRankingWnd.cpp | 14 ++++---- src/xrGame/ui/UIRankingWnd.h | 10 +++--- src/xrGame/ui/UIServerInfo.cpp | 4 +-- src/xrGame/ui/UIServerInfo.h | 4 +-- src/xrGame/ui/UISpeechMenu.cpp | 2 +- src/xrGame/ui/UIStatsPlayerList.cpp | 8 ++--- src/xrGame/ui/UIStatsPlayerList.h | 4 +-- src/xrGame/ui/UITalkDialogWnd.cpp | 7 ++-- src/xrGame/ui/UITalkDialogWnd.h | 6 ++-- src/xrGame/ui/UITradeBar.cpp | 6 ++-- src/xrGame/ui/UITradeBar.h | 6 ++-- src/xrGame/ui/UIVote.cpp | 8 ++--- src/xrGame/ui/UIVote.h | 5 ++- src/xrGame/ui/UIVoteStatusWnd.cpp | 12 +++---- src/xrGame/ui/UIVoteStatusWnd.h | 8 ++--- src/xrGame/ui/UIWeightBar.cpp | 6 ++-- src/xrGame/ui/UIWeightBar.h | 4 +-- src/xrGame/ui/UIWpnParams.cpp | 16 ++++----- src/xrGame/ui/UIWpnParams.h | 16 ++++----- src/xrGame/ui/map_hint.h | 1 - src/xrGame/ui/ui_af_params.cpp | 4 +-- src/xrGame/ui/ui_af_params.h | 3 +- src/xrUICore/Buttons/UIBtnHint.cpp | 5 ++- src/xrUICore/Buttons/UIBtnHint.h | 4 +-- src/xrUICore/ComboBox/UIComboBox.h | 2 +- src/xrUICore/Hint/UIHint.cpp | 4 +-- src/xrUICore/Hint/UIHint.h | 3 +- src/xrUICore/ListBox/UIListBoxItem.cpp | 4 +-- src/xrUICore/ListBox/UIListBoxItem.h | 7 ++-- src/xrUICore/MessageBox/UIMessageBox.cpp | 28 +++++++-------- src/xrUICore/MessageBox/UIMessageBox.h | 8 ++--- src/xrUICore/ScrollView/UIScrollView.h | 4 +-- 101 files changed, 375 insertions(+), 430 deletions(-) diff --git a/src/xrGame/UIGameAHunt.cpp b/src/xrGame/UIGameAHunt.cpp index 848c12b3881..b2297f08313 100644 --- a/src/xrGame/UIGameAHunt.cpp +++ b/src/xrGame/UIGameAHunt.cpp @@ -21,7 +21,7 @@ void CUIGameAHunt::Init(int stage) if (stage == 0) { // shared inherited::Init(stage); - m_buy_msg_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_ah_buy", Window); + m_buy_msg_caption = UIHelper::CreateStatic(*MsgConfig, "mp_ah_buy", Window); } if (stage == 1) { // unique @@ -31,16 +31,16 @@ void CUIGameAHunt::Init(int stage) uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "ui_game_ahunt.xml"); CUIXmlInit::InitWindow(uiXml, "global", 0, Window); - CUIXmlInit::InitTextWnd(uiXml, "fraglimit", 0, m_pFragLimitIndicator); + CUIXmlInit::InitStatic(uiXml, "fraglimit", 0, m_pFragLimitIndicator); - m_pReinforcementInidcator = xr_new(); + m_pReinforcementInidcator = xr_new("Reinforcement indicator"); m_pReinforcementInidcator->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(uiXml, "reinforcement", 0, m_pReinforcementInidcator); + CUIXmlInit::InitStatic(uiXml, "reinforcement", 0, m_pReinforcementInidcator); CUIXmlInit::InitStatic(uiXml, "team1_icon", 0, m_team1_icon); CUIXmlInit::InitStatic(uiXml, "team2_icon", 0, m_team2_icon); - CUIXmlInit::InitTextWnd(uiXml, "team1_score", 0, m_team1_score); - CUIXmlInit::InitTextWnd(uiXml, "team2_score", 0, m_team2_score); + CUIXmlInit::InitStatic(uiXml, "team1_score", 0, m_team1_score); + CUIXmlInit::InitStatic(uiXml, "team2_score", 0, m_team2_score); m_pMoneyIndicator->InitFromXML(uiXml); m_pRankIndicator->InitFromXml(uiXml); diff --git a/src/xrGame/UIGameAHunt.h b/src/xrGame/UIGameAHunt.h index bbcb37663e0..11bc150be3e 100644 --- a/src/xrGame/UIGameAHunt.h +++ b/src/xrGame/UIGameAHunt.h @@ -10,7 +10,6 @@ class CUIAHuntFragList; class CUIAHuntPlayerList; class game_cl_ArtefactHunt; -class CUITextWnd; class CUIMessageBoxEx; class CUIGameAHunt : public CUIGameTDM @@ -20,7 +19,7 @@ class CUIGameAHunt : public CUIGameTDM typedef CUIGameTDM inherited; public: - CUITextWnd* m_pReinforcementInidcator; + CUIStatic* m_pReinforcementInidcator; CUIMessageBoxEx* m_pBuySpawnMsgBox; public: @@ -33,5 +32,5 @@ class CUIGameAHunt : public CUIGameTDM void SetBuyMsgCaption(LPCSTR str); protected: - CUITextWnd* m_buy_msg_caption; + CUIStatic* m_buy_msg_caption; }; diff --git a/src/xrGame/UIGameCTA.cpp b/src/xrGame/UIGameCTA.cpp index 136959e94f3..97c3cca6edc 100644 --- a/src/xrGame/UIGameCTA.cpp +++ b/src/xrGame/UIGameCTA.cpp @@ -50,14 +50,14 @@ void CUIGameCTA::Init(int stage) { if (stage == 0) { - m_round_result_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_round_result", Window); - m_pressbuy_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_pressbuy", Window); - m_pressjump_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_pressjump", Window); - m_spectator_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_spectator", Window); - m_spectrmode_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_spetatormode", Window); - m_warm_up_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_warm_up", Window); - m_time_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_timelimit", Window); - m_demo_play_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_demo_play", Window); + m_round_result_caption = UIHelper::CreateStatic(*MsgConfig, "mp_round_result", Window); + m_pressbuy_caption = UIHelper::CreateStatic(*MsgConfig, "mp_pressbuy", Window); + m_pressjump_caption = UIHelper::CreateStatic(*MsgConfig, "mp_pressjump", Window); + m_spectator_caption = UIHelper::CreateStatic(*MsgConfig, "mp_spectator", Window); + m_spectrmode_caption = UIHelper::CreateStatic(*MsgConfig, "mp_spetatormode", Window); + m_warm_up_caption = UIHelper::CreateStatic(*MsgConfig, "mp_warm_up", Window); + m_time_caption = UIHelper::CreateStatic(*MsgConfig, "mp_timelimit", Window); + m_demo_play_caption = UIHelper::CreateStatic(*MsgConfig, "mp_demo_play", Window); teamPanels = xr_new(); teamPanels->Init(TEAM_PANELS_XML_NAME, "team_panels_wnd"); @@ -75,25 +75,25 @@ void CUIGameCTA::Init(int stage) m_pRankIndicator->SetAutoDelete(true); m_pRankIndicator->InitFromXml(uiXml); - m_pReinforcementInidcator = xr_new(); + m_pReinforcementInidcator = xr_new("Reinforcement indicator"); m_pReinforcementInidcator->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(uiXml, "reinforcement", 0, m_pReinforcementInidcator); + CUIXmlInit::InitStatic(uiXml, "reinforcement", 0, m_pReinforcementInidcator); m_team1_icon = xr_new("Team 1 icon"); m_team2_icon = xr_new("Team 2 icon"); CUIXmlInit::InitStatic(uiXml, "team1_icon", 0, m_team1_icon); CUIXmlInit::InitStatic(uiXml, "team2_icon", 0, m_team2_icon); - m_team1_score = xr_new(); - m_team2_score = xr_new(); + m_team1_score = xr_new("Team 1 score"); + m_team2_score = xr_new("Team 2 score"); m_team1_score->SetAutoDelete(true); m_team2_score->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(uiXml, "team1_score", 0, m_team1_score); - CUIXmlInit::InitTextWnd(uiXml, "team2_score", 0, m_team2_score); + CUIXmlInit::InitStatic(uiXml, "team1_score", 0, m_team1_score); + CUIXmlInit::InitStatic(uiXml, "team2_score", 0, m_team2_score); - m_pFragLimitIndicator = xr_new(); + m_pFragLimitIndicator = xr_new("Frag limit indicator"); m_pFragLimitIndicator->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(uiXml, "fraglimit", 0, m_pFragLimitIndicator); + CUIXmlInit::InitStatic(uiXml, "fraglimit", 0, m_pFragLimitIndicator); } if (stage == 2) diff --git a/src/xrGame/UIGameCTA.h b/src/xrGame/UIGameCTA.h index 71ee1e51385..674b875895e 100644 --- a/src/xrGame/UIGameCTA.h +++ b/src/xrGame/UIGameCTA.h @@ -23,7 +23,6 @@ class CUIProgressShape; class CUIMessageBoxEx; class UIVoteStatusWnd; class game_cl_CaptureTheArtefact; -class CUITextWnd; /// This class used to control UI part of client for Capture the Artefact mp game mode. class CUIGameCTA : public UIGameMP @@ -31,14 +30,14 @@ class CUIGameCTA : public UIGameMP CUISpawnWnd* m_pUITeamSelectWnd; CUIStatic* m_team1_icon; CUIStatic* m_team2_icon; - CUITextWnd* m_team1_score{}; - CUITextWnd* m_team2_score{}; - CUITextWnd* m_pFragLimitIndicator{}; + CUIStatic* m_team1_score{}; + CUIStatic* m_team2_score{}; + CUIStatic* m_pFragLimitIndicator{}; game_cl_CaptureTheArtefact* m_game{}; CUIMoneyIndicator* m_pMoneyIndicator; CUIRankIndicator* m_pRankIndicator; - CUITextWnd* m_pReinforcementInidcator; + CUIStatic* m_pReinforcementInidcator; CUIMessageBoxEx* m_pBuySpawnMsgBox{}; UIVoteStatusWnd* m_voteStatusWnd{}; @@ -52,15 +51,15 @@ class CUIGameCTA : public UIGameMP UITeamPanels* teamPanels{}; bool m_team_panels_shown{}; - CUITextWnd* m_spectator_caption; - CUITextWnd* m_pressjump_caption; - CUITextWnd* m_pressbuy_caption; - CUITextWnd* m_round_result_caption; - CUITextWnd* m_force_respawn_time_caption; - CUITextWnd* m_spectrmode_caption; - CUITextWnd* m_warm_up_caption; - CUITextWnd* m_time_caption; - CUITextWnd* m_demo_play_caption; + CUIStatic* m_spectator_caption; + CUIStatic* m_pressjump_caption; + CUIStatic* m_pressbuy_caption; + CUIStatic* m_round_result_caption; + CUIStatic* m_force_respawn_time_caption; + CUIStatic* m_spectrmode_caption; + CUIStatic* m_warm_up_caption; + CUIStatic* m_time_caption; + CUIStatic* m_demo_play_caption; struct PresetItem { diff --git a/src/xrGame/UIGameDM.cpp b/src/xrGame/UIGameDM.cpp index 056fb063d27..60a62096406 100644 --- a/src/xrGame/UIGameDM.cpp +++ b/src/xrGame/UIGameDM.cpp @@ -51,19 +51,19 @@ void CUIGameDM::Init(int stage) m_pMoneyIndicator->SetAutoDelete(true); m_pRankIndicator = xr_new(); m_pRankIndicator->SetAutoDelete(true); - m_pFragLimitIndicator = xr_new(); + m_pFragLimitIndicator = xr_new("Frag limit indicator"); m_pFragLimitIndicator->SetAutoDelete(true); inherited::Init(stage); - m_time_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_timelimit", Window); - m_spectrmode_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_spetatormode", Window); - m_spectator_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_spectator", Window); - m_pressjump_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_pressjump", Window); - m_pressbuy_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_pressbuy", Window); - m_round_result_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_round_result", Window); - m_force_respawn_time_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_force_respawn_time", Window); - m_demo_play_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_demo_play", Window); - m_warm_up_caption = UIHelper::CreateTextWnd(*MsgConfig, "mp_warm_up", Window); + m_time_caption = UIHelper::CreateStatic(*MsgConfig, "mp_timelimit", Window); + m_spectrmode_caption = UIHelper::CreateStatic(*MsgConfig, "mp_spetatormode", Window); + m_spectator_caption = UIHelper::CreateStatic(*MsgConfig, "mp_spectator", Window); + m_pressjump_caption = UIHelper::CreateStatic(*MsgConfig, "mp_pressjump", Window); + m_pressbuy_caption = UIHelper::CreateStatic(*MsgConfig, "mp_pressbuy", Window); + m_round_result_caption = UIHelper::CreateStatic(*MsgConfig, "mp_round_result", Window); + m_force_respawn_time_caption = UIHelper::CreateStatic(*MsgConfig, "mp_force_respawn_time", Window); + m_demo_play_caption = UIHelper::CreateStatic(*MsgConfig, "mp_demo_play", Window); + m_warm_up_caption = UIHelper::CreateStatic(*MsgConfig, "mp_warm_up", Window); } if (stage == 1) { // unique @@ -73,7 +73,7 @@ void CUIGameDM::Init(int stage) CUIXmlInit::InitWindow(uiXml, "global", 0, Window); m_pMoneyIndicator->InitFromXML(uiXml); m_pRankIndicator->InitFromXml(uiXml); - CUIXmlInit::InitTextWnd(uiXml, "fraglimit", 0, m_pFragLimitIndicator); + CUIXmlInit::InitStatic(uiXml, "fraglimit", 0, m_pFragLimitIndicator); } if (stage == 2) { // after diff --git a/src/xrGame/UIGameDM.h b/src/xrGame/UIGameDM.h index c45d9a93a6a..d7e400c22ae 100644 --- a/src/xrGame/UIGameDM.h +++ b/src/xrGame/UIGameDM.h @@ -11,7 +11,6 @@ class CUIRankIndicator; class UIVoteStatusWnd; class CUIMapDesc; class UITeamPanels; -class CUITextWnd; class CUIGameDM : public UIGameMP { @@ -27,19 +26,19 @@ class CUIGameDM : public UIGameMP UITeamPanels* m_pTeamPanels; - CUITextWnd* m_time_caption; - CUITextWnd* m_spectrmode_caption; - CUITextWnd* m_spectator_caption; - CUITextWnd* m_pressjump_caption; - CUITextWnd* m_pressbuy_caption; - CUITextWnd* m_round_result_caption; - CUITextWnd* m_force_respawn_time_caption; - CUITextWnd* m_demo_play_caption; - CUITextWnd* m_warm_up_caption; + CUIStatic* m_time_caption; + CUIStatic* m_spectrmode_caption; + CUIStatic* m_spectator_caption; + CUIStatic* m_pressjump_caption; + CUIStatic* m_pressbuy_caption; + CUIStatic* m_round_result_caption; + CUIStatic* m_force_respawn_time_caption; + CUIStatic* m_demo_play_caption; + CUIStatic* m_warm_up_caption; CUIMoneyIndicator* m_pMoneyIndicator; CUIRankIndicator* m_pRankIndicator; - CUITextWnd* m_pFragLimitIndicator; + CUIStatic* m_pFragLimitIndicator; UIVoteStatusWnd* m_voteStatusWnd; public: diff --git a/src/xrGame/UIGameTDM.cpp b/src/xrGame/UIGameTDM.cpp index 693e7e04b7d..a369762a6a7 100644 --- a/src/xrGame/UIGameTDM.cpp +++ b/src/xrGame/UIGameTDM.cpp @@ -32,15 +32,15 @@ void CUIGameTDM::Init(int stage) m_pUITeamSelectWnd = xr_new(); m_team1_icon = xr_new("Team 1 icon"); m_team2_icon = xr_new("Team 2 icon"); - m_team1_score = xr_new(); + m_team1_score = xr_new("Team 1 score"); m_team1_score->SetAutoDelete(true); - m_team2_score = xr_new(); + m_team2_score = xr_new("Team 2 score"); m_team2_score->SetAutoDelete(true); - m_buy_msg_caption = xr_new(); + m_buy_msg_caption = xr_new("Buy message caption"); m_buy_msg_caption->SetAutoDelete(true); inherited::Init(stage); - CUIXmlInit::InitTextWnd(*MsgConfig, "mp_tdm_buy", 0, m_buy_msg_caption); + CUIXmlInit::InitStatic(*MsgConfig, "mp_tdm_buy", 0, m_buy_msg_caption); } if (stage == 1) { // unique @@ -52,9 +52,9 @@ void CUIGameTDM::Init(int stage) CUIXmlInit::InitWindow(uiXml, "global", 0, Window); CUIXmlInit::InitStatic(uiXml, "team1_icon", 0, m_team1_icon); CUIXmlInit::InitStatic(uiXml, "team2_icon", 0, m_team2_icon); - CUIXmlInit::InitTextWnd(uiXml, "team1_score", 0, m_team1_score); - CUIXmlInit::InitTextWnd(uiXml, "team2_score", 0, m_team2_score); - CUIXmlInit::InitTextWnd(uiXml, "fraglimit", 0, m_pFragLimitIndicator); + CUIXmlInit::InitStatic(uiXml, "team1_score", 0, m_team1_score); + CUIXmlInit::InitStatic(uiXml, "team2_score", 0, m_team2_score); + CUIXmlInit::InitStatic(uiXml, "fraglimit", 0, m_pFragLimitIndicator); m_pMoneyIndicator->InitFromXML(uiXml); m_pRankIndicator->InitFromXml(uiXml); diff --git a/src/xrGame/UIGameTDM.h b/src/xrGame/UIGameTDM.h index 69f087aac39..7296fa0c079 100644 --- a/src/xrGame/UIGameTDM.h +++ b/src/xrGame/UIGameTDM.h @@ -13,7 +13,6 @@ class CUITDMPlayerList; class CUISkinSelectorWnd; class game_cl_TeamDeathmatch; class CUIStatic; -class CUITextWnd; class CUISpawnWnd; class CUIGameTDM : public CUIGameDM @@ -28,9 +27,9 @@ class CUIGameTDM : public CUIGameDM protected: CUIStatic* m_team1_icon; CUIStatic* m_team2_icon; - CUITextWnd* m_team1_score; - CUITextWnd* m_team2_score; - CUITextWnd* m_buy_msg_caption; + CUIStatic* m_team1_score; + CUIStatic* m_team2_score; + CUIStatic* m_buy_msg_caption; public: CUIGameTDM(); diff --git a/src/xrGame/UIPlayerItem.cpp b/src/xrGame/UIPlayerItem.cpp index 1ec0a80553d..91bc9cb2cff 100644 --- a/src/xrGame/UIPlayerItem.cpp +++ b/src/xrGame/UIPlayerItem.cpp @@ -53,11 +53,11 @@ void UIPlayerItem::InitTextParams(CUIXml& uiXml) if (!text_param_node) break; LPCSTR param_name = uiXml.ReadAttrib(text_param_node, "name", "param_name_not_set_in_name_attribute"); - CUITextWnd* temp_static = xr_new(); + auto* temp_static = xr_new("Text param"); VERIFY(temp_static); this->AttachChild(temp_static); temp_static->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(uiXml, TEXTPARAM_NODE_NAME, i, temp_static); + CUIXmlInit::InitStatic(uiXml, TEXTPARAM_NODE_NAME, i, temp_static); m_text_params.emplace(shared_str(param_name), temp_static); } } @@ -85,8 +85,8 @@ void UIPlayerItem::InitIconParams(CUIXml& uiXml) void UIPlayerItem::UpdateTextParams(game_PlayerState const* ps) { buffer_vector value_store(xr_alloca(512), 512, 512, char(0)); - TMapStrToUIText::iterator ie = m_text_params.end(); - for (TMapStrToUIText::iterator i = m_text_params.begin(); i != ie; ++i) + const auto ie = m_text_params.end(); + for (auto i = m_text_params.begin(); i != ie; ++i) { VERIFY(i->second); GetTextParamValue(ps, i->first, value_store); @@ -98,8 +98,8 @@ void UIPlayerItem::UpdateTextParams(game_PlayerState const* ps) void UIPlayerItem::UpdateIconParams(game_PlayerState const* ps) { buffer_vector value_store(xr_alloca(512), 512, 512, char(0)); - TMapStrToUIStatic::iterator ie = m_icon_params.end(); - for (TMapStrToUIStatic::iterator i = m_icon_params.begin(); i != ie; ++i) + const auto ie = m_icon_params.end(); + for (auto i = m_icon_params.begin(); i != ie; ++i) { VERIFY(i->second); GetIconParamValue(ps, i->first, value_store); diff --git a/src/xrGame/UIPlayerItem.h b/src/xrGame/UIPlayerItem.h index fb929b47d9f..b38168a1391 100644 --- a/src/xrGame/UIPlayerItem.h +++ b/src/xrGame/UIPlayerItem.h @@ -19,8 +19,8 @@ class UIPlayerItem final : public CUIWindow { private: typedef CUIWindow inherited; - typedef AssociativeVector TMapStrToUIText; - typedef AssociativeVector TMapStrToUIStatic; + typedef AssociativeVector TMapStrToUIText; + typedef AssociativeVector TMapStrToUIStats; // this is for the case when user disconnects. // we just call method RemovePlayer UITeamState* m_teamState; @@ -30,7 +30,7 @@ class UIPlayerItem final : public CUIWindow s32 m_checkPoints; TMapStrToUIText m_text_params; - TMapStrToUIStatic m_icon_params; + TMapStrToUIStats m_icon_params; ClientID myClientId; UIPlayerItem(); diff --git a/src/xrGame/UIZoneMap.cpp b/src/xrGame/UIZoneMap.cpp index f7043a887da..777e17ff01d 100644 --- a/src/xrGame/UIZoneMap.cpp +++ b/src/xrGame/UIZoneMap.cpp @@ -93,7 +93,7 @@ void CUIZoneMap::Init(bool motionIconAttached) { CUIXmlInit::InitStatic(uiXml, "minimap:static_counter", 0, &m_Counter); m_background.AttachChild(&m_Counter); - CUIXmlInit::InitTextWnd(uiXml, "minimap:static_counter:text_static", 0, &m_Counter_text); + CUIXmlInit::InitStatic(uiXml, "minimap:static_counter:text_static", 0, &m_Counter_text); m_Counter.AttachChild(&m_Counter_text); if (motionIconAttached) diff --git a/src/xrGame/UIZoneMap.h b/src/xrGame/UIZoneMap.h index 7b64fcd6cff..fcbe6f79c56 100644 --- a/src/xrGame/UIZoneMap.h +++ b/src/xrGame/UIZoneMap.h @@ -18,7 +18,7 @@ class CUIZoneMap CUIStatic m_compass{ "Compass" }; CUIWindow m_clipFrame{ "Clip frame" }; CUIStatic m_Counter{ "Counter" }; - CUITextWnd m_Counter_text{}; + CUIStatic m_Counter_text{ "Counter text" }; CUIStatic* m_clock_wnd{}; CUIStatic* m_pointerDistanceText{}; diff --git a/src/xrGame/ui/ChangeWeatherDialog.cpp b/src/xrGame/ui/ChangeWeatherDialog.cpp index e065c276816..a3da7be7e3f 100644 --- a/src/xrGame/ui/ChangeWeatherDialog.cpp +++ b/src/xrGame/ui/ChangeWeatherDialog.cpp @@ -15,7 +15,7 @@ ButtonListDialog::ButtonListDialog(pcstr window_name) Background = xr_new("Background"); Background->SetAutoDelete(true); AttachChild(Background); - Header = xr_new(); + Header = xr_new("Header"); Header->SetAutoDelete(true); AttachChild(Header); CancelButton = xr_new(); @@ -32,7 +32,7 @@ void ButtonListDialog::Initialize(int buttonCount) btn.Button = xr_new(); btn.Button->SetAutoDelete(true); AttachChild(btn.Button); - btn.Text = xr_new(); + btn.Text = xr_new("Text"); btn.Text->SetAutoDelete(true); AttachChild(btn.Text); buttons.push_back(btn); @@ -81,7 +81,7 @@ void ButtonListDialog::SendMessage(CUIWindow* wnd, s16 msg, void* data /*= nullp void ChangeWeatherDialog::InitChangeWeather(CUIXml& xmlDoc) { CUIXmlInit::InitWindow(xmlDoc, "change_weather", 0, this); - CUIXmlInit::InitTextWnd(xmlDoc, "change_weather:header", 0, Header); + CUIXmlInit::InitStatic(xmlDoc, "change_weather:header", 0, Header); CUIXmlInit::InitStatic(xmlDoc, "change_weather:background", 0, Background); CUIXmlInit::Init3tButton(xmlDoc, "change_weather:btn_cancel", 0, CancelButton); auto& gameWeathers = gMapListHelper.GetGameWeathers(); @@ -96,7 +96,7 @@ void ChangeWeatherDialog::InitChangeWeather(CUIXml& xmlDoc) xr_sprintf(path, "change_weather:btn_%d", i+1); CUIXmlInit::Init3tButton(xmlDoc, path, 0, GetButton(i).Button); xr_sprintf(path, "change_weather:txt_%d", i+1); - CUIXmlInit::InitTextWnd(xmlDoc, path, 0, GetButton(i).Text); + CUIXmlInit::InitStatic(xmlDoc, path, 0, GetButton(i).Text); } Log("! Weathers name sorted by alphabet !"); weathers[0].Name = gameWeathers[0].Name; @@ -120,7 +120,7 @@ void ChangeWeatherDialog::OnButtonClick(int i) void ChangeGameTypeDialog::InitChangeGameType(CUIXml& xmlDoc) { CUIXmlInit::InitWindow(xmlDoc, "change_gametype", 0, this); - CUIXmlInit::InitTextWnd(xmlDoc, "change_gametype:header", 0, Header); + CUIXmlInit::InitStatic(xmlDoc, "change_gametype:header", 0, Header); CUIXmlInit::InitStatic(xmlDoc, "change_gametype:background", 0, Background); CUIXmlInit::Init3tButton(xmlDoc, "change_gametype:btn_cancel", 0, CancelButton); // XXX nitrocaster: get it from somewhere @@ -133,7 +133,7 @@ void ChangeGameTypeDialog::InitChangeGameType(CUIXml& xmlDoc) xr_sprintf(path, "change_gametype:btn_%d", i + 1); CUIXmlInit::Init3tButton(xmlDoc, path, 0, GetButton(i).Button); xr_sprintf(path, "change_gametype:txt_%d", i + 1); - CUIXmlInit::InitTextWnd(xmlDoc, path, 0, GetButton(i).Text); + CUIXmlInit::InitStatic(xmlDoc, path, 0, GetButton(i).Text); gameTypes[i] = xmlDoc.ReadAttrib(path, 0, "id"); } } diff --git a/src/xrGame/ui/ChangeWeatherDialog.hpp b/src/xrGame/ui/ChangeWeatherDialog.hpp index ce7e0b704fd..5d9b8a291c5 100644 --- a/src/xrGame/ui/ChangeWeatherDialog.hpp +++ b/src/xrGame/ui/ChangeWeatherDialog.hpp @@ -3,7 +3,6 @@ #include "UIDialogWnd.h" class CUIStatic; -class CUITextWnd; class CUI3tButton; class CUIKickPlayer; class CUIChangeMap; @@ -15,10 +14,10 @@ class ButtonListDialog : public CUIDialogWnd struct NamedButton { CUI3tButton* Button; - CUITextWnd* Text; + CUIStatic* Text; }; - CUITextWnd* Header; + CUIStatic* Header; CUIStatic* Background; CUI3tButton* CancelButton; diff --git a/src/xrGame/ui/UIAchievements.cpp b/src/xrGame/ui/UIAchievements.cpp index 489a9a6c551..39849187bdf 100644 --- a/src/xrGame/ui/UIAchievements.cpp +++ b/src/xrGame/ui/UIAchievements.cpp @@ -22,8 +22,8 @@ void CUIAchievements::init_from_xml(CUIXml& xml) XML_NODE node = xml.NavigateToNode("achievements_itm", 0); xml.SetLocalRoot(node); - m_name = UIHelper::CreateTextWnd(xml, "name", this); - m_descr = UIHelper::CreateTextWnd(xml, "descr", this); + m_name = UIHelper::CreateStatic(xml, "name", this); + m_descr = UIHelper::CreateStatic(xml, "descr", this); m_icon = UIHelper::CreateStatic(xml, "icon", this); m_hint = UIHelper::CreateHint(xml, "hint_wnd"); diff --git a/src/xrGame/ui/UIAchievements.h b/src/xrGame/ui/UIAchievements.h index 5d23ac2fb21..e18e7a453f9 100644 --- a/src/xrGame/ui/UIAchievements.h +++ b/src/xrGame/ui/UIAchievements.h @@ -3,7 +3,6 @@ class CUIXml; class CUIStatic; -class CUITextWnd; class UIHint; class CUIScrollView; @@ -13,8 +12,8 @@ class CUIAchievements final : public CUIWindow private: CUIScrollView* m_parent{}; - CUITextWnd* m_name{}; - CUITextWnd* m_descr{}; + CUIStatic* m_name{}; + CUIStatic* m_descr{}; CUIStatic* m_icon{}; UIHint* m_hint{}; string128 m_functor_str; diff --git a/src/xrGame/ui/UIActorMenu.h b/src/xrGame/ui/UIActorMenu.h index cc54826dfec..ecf76bcd22f 100644 --- a/src/xrGame/ui/UIActorMenu.h +++ b/src/xrGame/ui/UIActorMenu.h @@ -14,7 +14,6 @@ class ui_actor_state_wnd; class CUIItemInfo; class CUIFrameLineWnd; class CUIStatic; -class CUITextWnd; class CUI3tButton; class CInventoryOwner; class CInventoryBox; diff --git a/src/xrGame/ui/UIBoosterInfo.cpp b/src/xrGame/ui/UIBoosterInfo.cpp index 9f69c24270a..91fbe37a579 100644 --- a/src/xrGame/ui/UIBoosterInfo.cpp +++ b/src/xrGame/ui/UIBoosterInfo.cpp @@ -208,7 +208,7 @@ void UIBoosterInfoItem::Init(CUIXml& xml, LPCSTR section) xml.SetLocalRoot(xml.NavigateToNode(section)); m_caption = UIHelper::CreateStatic(xml, "caption", this); - m_value = UIHelper::CreateTextWnd(xml, "value", this); + m_value = UIHelper::CreateStatic(xml, "value", this); m_magnitude = xml.ReadAttribFlt("value", 0, "magnitude", 1.0f); m_show_sign = (xml.ReadAttribInt("value", 0, "show_sign", 1) == 1); diff --git a/src/xrGame/ui/UIBoosterInfo.h b/src/xrGame/ui/UIBoosterInfo.h index 68f2198f5d1..246c1a32b9b 100644 --- a/src/xrGame/ui/UIBoosterInfo.h +++ b/src/xrGame/ui/UIBoosterInfo.h @@ -4,7 +4,6 @@ class CUIXml; class CUIStatic; -class CUITextWnd; class UIBoosterInfoItem; class CUIBoosterInfo final : public CUIWindow @@ -42,7 +41,7 @@ class UIBoosterInfoItem final : public CUIWindow private: CUIStatic* m_caption{}; - CUITextWnd* m_value{}; + CUIStatic* m_value{}; float m_magnitude; bool m_show_sign; shared_str m_unit_str; diff --git a/src/xrGame/ui/UIChangeMap.cpp b/src/xrGame/ui/UIChangeMap.cpp index 7ff549107cd..3a7ec32764e 100644 --- a/src/xrGame/ui/UIChangeMap.cpp +++ b/src/xrGame/ui/UIChangeMap.cpp @@ -22,7 +22,7 @@ CUIChangeMap::CUIChangeMap() : CUIDialogWnd(CUIChangeMap::GetDebugType()) bkgrnd->SetAutoDelete(true); AttachChild(bkgrnd); - header = xr_new(); + header = xr_new("Header"); header->SetAutoDelete(true); AttachChild(header); @@ -34,7 +34,7 @@ CUIChangeMap::CUIChangeMap() : CUIDialogWnd(CUIChangeMap::GetDebugType()) map_frame->SetAutoDelete(true); AttachChild(map_frame); - map_version = xr_new(); + map_version = xr_new("Map version"); map_version->SetAutoDelete(true); AttachChild(map_version); @@ -62,10 +62,10 @@ CUIChangeMap::CUIChangeMap() : CUIDialogWnd(CUIChangeMap::GetDebugType()) void CUIChangeMap::InitChangeMap(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "change_map", 0, this); - CUIXmlInit::InitTextWnd(xml_doc, "change_map:header", 0, header); + CUIXmlInit::InitStatic(xml_doc, "change_map:header", 0, header); CUIXmlInit::InitStatic(xml_doc, "change_map:background", 0, bkgrnd); CUIXmlInit::InitStatic(xml_doc, "change_map:map_frame", 0, map_frame); - CUIXmlInit::InitTextWnd(xml_doc, "change_map:map_ver_txt", 0, map_version); + CUIXmlInit::InitStatic(xml_doc, "change_map:map_ver_txt", 0, map_version); CUIXmlInit::InitStatic(xml_doc, "change_map:map_pic", 0, map_pic); // CUIXmlInit::InitFrameWindow (xml_doc, "change_map:list_back", 0, lst_back); // CUIXmlInit::InitFrameWindow (xml_doc, "change_map:frame", 0, frame); diff --git a/src/xrGame/ui/UIChangeMap.h b/src/xrGame/ui/UIChangeMap.h index 6c668006054..546c2fc73f4 100644 --- a/src/xrGame/ui/UIChangeMap.h +++ b/src/xrGame/ui/UIChangeMap.h @@ -3,7 +3,6 @@ #include "UIDialogWnd.h" class CUIStatic; -class CUITextWnd; class CUI3tButton; class CUIFrameWindow; class CUIListBox; @@ -28,10 +27,10 @@ class CUIChangeMap final : public CUIDialogWnd void FillUpList(); CUIStatic* bkgrnd; - CUITextWnd* header; + CUIStatic* header; CUIStatic* map_pic; CUIStatic* map_frame; - CUITextWnd* map_version; + CUIStatic* map_version; CUIFrameWindow* frame; CUIFrameWindow* lst_back; CUIListBox* lst; diff --git a/src/xrGame/ui/UICharacterInfo.cpp b/src/xrGame/ui/UICharacterInfo.cpp index e3367896ab5..e4e08f91eea 100644 --- a/src/xrGame/ui/UICharacterInfo.cpp +++ b/src/xrGame/ui/UICharacterInfo.cpp @@ -157,7 +157,7 @@ void CUICharacterInfo::InitCharacter(u16 id) pUIBio->Clear(); if (chInfo.Bio().size()) { - CUITextWnd* pItem = xr_new(); + auto* pItem = xr_new("Biography"); pItem->SetWidth(pUIBio->GetDesiredChildWidth()); pItem->SetText(chInfo.Bio().c_str()); pItem->AdjustHeightToText(); diff --git a/src/xrGame/ui/UIChatWnd.cpp b/src/xrGame/ui/UIChatWnd.cpp index e8fff98a62e..259b45ec6cc 100644 --- a/src/xrGame/ui/UIChatWnd.cpp +++ b/src/xrGame/ui/UIChatWnd.cpp @@ -19,16 +19,16 @@ void CUIChatWnd::PendingMode(bool const is_pending_mode) if (pendingGameMode) return; - UIPrefix->SetWndRect(pending_prefix_rect); - UIEditBox->SetWndRect(pending_edit_rect); + UIPrefix.SetWndRect(pending_prefix_rect); + UIEditBox.SetWndRect(pending_edit_rect); pendingGameMode = true; return; } if (!pendingGameMode) return; - UIPrefix->SetWndRect(inprogress_prefix_rect); - UIEditBox->SetWndRect(inprogress_edit_rect); + UIPrefix.SetWndRect(inprogress_prefix_rect); + UIEditBox.SetWndRect(inprogress_edit_rect); pendingGameMode = false; } @@ -37,12 +37,14 @@ const pcstr CHAT_EDITBOX_PENDING = "chat_editbox_pending"; void CUIChatWnd::Init(CUIXml& uiXml) { - UIPrefix = UIHelper::CreateTextWnd(uiXml, "chat_prefix", this); - inprogress_prefix_rect = UIPrefix->GetWndRect(); + AttachChild(&UIPrefix); + CUIXmlInit::InitStatic(uiXml, "chat_prefix", 0, &UIPrefix); + inprogress_prefix_rect = UIPrefix.GetWndRect(); - UIEditBox = UIHelper::CreateEditBox(uiXml, "chat_edit_box", this); - inprogress_edit_rect = UIEditBox->GetWndRect(); - UIEditBox->SetWindowName("chat_edit_box"); + AttachChild(&UIEditBox); + CUIXmlInit::InitEditBox(uiXml, "chat_edit_box", 0, &UIEditBox); + inprogress_edit_rect = UIEditBox.GetWndRect(); + UIEditBox.SetWindowName("chat_edit_box"); pendingGameMode = false; @@ -61,32 +63,32 @@ void CUIChatWnd::Init(CUIXml& uiXml) pending_edit_rect.y2 = uiXml.ReadAttribFlt(CHAT_EDITBOX_PENDING, 0, "height"); pending_edit_rect.rb.add(pending_edit_rect.lt); - Register(UIEditBox); - AddCallback(UIEditBox, EDIT_TEXT_COMMIT, CUIWndCallback::void_function(this, &CUIChatWnd::OnChatCommit)); - AddCallback(UIEditBox, EDIT_TEXT_CANCEL, CUIWndCallback::void_function(this, &CUIChatWnd::OnChatCancel)); + Register(&UIEditBox); + AddCallback(&UIEditBox, EDIT_TEXT_COMMIT, CUIWndCallback::void_function(this, &CUIChatWnd::OnChatCommit)); + AddCallback(&UIEditBox, EDIT_TEXT_CANCEL, CUIWndCallback::void_function(this, &CUIChatWnd::OnChatCancel)); } void CUIChatWnd::SetEditBoxPrefix(LPCSTR prefix) { - UIPrefix->SetText(prefix); - UIPrefix->AdjustWidthToText(); + UIPrefix.SetText(prefix); + UIPrefix.AdjustWidthToText(); Fvector2 _pos; - _pos.x = UIPrefix->GetWndPos().x + UIPrefix->GetWidth() + 5.0f; - _pos.y = UIEditBox->GetWndPos().y; - UIEditBox->SetWndPos(_pos); - UIEditBox->ClearText(); + _pos.x = UIPrefix.GetWndPos().x + UIPrefix.GetWidth() + 5.0f; + _pos.y = UIEditBox.GetWndPos().y; + UIEditBox.SetWndPos(_pos); + UIEditBox.ClearText(); } void CUIChatWnd::Show(bool status) { - UIEditBox->CaptureFocus(status); + UIEditBox.CaptureFocus(status); inherited::Show(status); } void CUIChatWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { CUIWndCallback::OnEvent(pWnd, msg, pData); } void CUIChatWnd::OnChatCommit(CUIWindow* w, void* d) { - Game().ChatSay(UIEditBox->GetText(), sendNextMessageToAll); + Game().ChatSay(UIEditBox.GetText(), sendNextMessageToAll); HideDialog(); } diff --git a/src/xrGame/ui/UIChatWnd.h b/src/xrGame/ui/UIChatWnd.h index e3fa905a570..a89a025c262 100644 --- a/src/xrGame/ui/UIChatWnd.h +++ b/src/xrGame/ui/UIChatWnd.h @@ -5,7 +5,6 @@ class CUIXml; class CUIGameLog; class CUIEditBox; -class CUITextWnd; class CUIChatWnd final : public CUIDialogWnd, public CUIWndCallback { @@ -25,8 +24,8 @@ class CUIChatWnd final : public CUIDialogWnd, public CUIWndCallback pcstr GetDebugType() override { return "CUIChatWnd"; } protected: - CUIEditBox* UIEditBox; - CUITextWnd* UIPrefix; + CUIEditBox UIEditBox; + CUIStatic UIPrefix{ "Chat prefix" }; bool sendNextMessageToAll; bool pendingGameMode; diff --git a/src/xrGame/ui/UIDebugFonts.cpp b/src/xrGame/ui/UIDebugFonts.cpp index dcb52122461..b46007ae02b 100644 --- a/src/xrGame/ui/UIDebugFonts.cpp +++ b/src/xrGame/ui/UIDebugFonts.cpp @@ -47,7 +47,7 @@ void CUIDebugFonts::FillUpList() for (; it != it_e; ++it) { CGameFont* F = *(*it); - CUITextWnd* pItem = xr_new(); + auto* pItem = xr_new("Item"); pItem->SetWndPos(pos); pItem->SetWndSize(sz); #ifdef DEBUG diff --git a/src/xrGame/ui/UIDemoPlayControl.cpp b/src/xrGame/ui/UIDemoPlayControl.cpp index db0b6983ffb..20d30ddff52 100644 --- a/src/xrGame/ui/UIDemoPlayControl.cpp +++ b/src/xrGame/ui/UIDemoPlayControl.cpp @@ -31,7 +31,7 @@ CUIDemoPlayControl::CUIDemoPlayControl() AttachChild(m_rewind_until_btn); m_repeat_rewind_btn = xr_new(); AttachChild(m_repeat_rewind_btn); - m_static_demo_status = xr_new(); + m_static_demo_status = xr_new("Demo status"); AttachChild(m_static_demo_status); m_all_players = xr_new(); @@ -81,7 +81,7 @@ void CUIDemoPlayControl::Init() CUIXmlInit::Init3tButton(xml_doc, "demo_play_control:btn_rewind_until", 0, m_rewind_until_btn); CUIXmlInit::Init3tButton(xml_doc, "demo_play_control:btn_repeat_rewind", 0, m_repeat_rewind_btn); CUIXmlInit::InitProgressBar(xml_doc, "demo_play_control:progress", 0, m_progress_bar); - CUIXmlInit::InitTextWnd(xml_doc, "demo_play_control:static_demo_status", 0, m_static_demo_status); + CUIXmlInit::InitStatic(xml_doc, "demo_play_control:static_demo_status", 0, m_static_demo_status); CUIWindow tmp_prop_boxes_wnd("tmp_prop_boxes_wnd"); CUIXmlInit::InitWindow(xml_doc, "demo_play_control:rewind_property_boxes", 0, &tmp_prop_boxes_wnd); diff --git a/src/xrGame/ui/UIDemoPlayControl.h b/src/xrGame/ui/UIDemoPlayControl.h index 09fbeadb3df..f3127bc0e18 100644 --- a/src/xrGame/ui/UIDemoPlayControl.h +++ b/src/xrGame/ui/UIDemoPlayControl.h @@ -9,7 +9,6 @@ class CUI3tButton; class CUIProgressBar; class CUIPropertiesBox; -class CUITextWnd; class CUIStatic; class demoplay_control; @@ -80,7 +79,7 @@ class CUIDemoPlayControl final : public CUIDialogWnd, public CUIWndCallback CUI3tButton* m_rewind_until_btn; CUI3tButton* m_repeat_rewind_btn; CUIProgressBar* m_progress_bar; - CUITextWnd* m_static_demo_status; + CUIStatic* m_static_demo_status; Fvector2 m_last_curr_pos; demoplay_control* m_demo_play_control; diff --git a/src/xrGame/ui/UIDragDropReferenceList.cpp b/src/xrGame/ui/UIDragDropReferenceList.cpp index a6df3b8bfdf..a01eb883ff4 100644 --- a/src/xrGame/ui/UIDragDropReferenceList.cpp +++ b/src/xrGame/ui/UIDragDropReferenceList.cpp @@ -51,7 +51,7 @@ void CUIDragDropReferenceList::Initialize(pcstr labelSection /*= nullptr*/, pcst { string32 temp; xr_sprintf(temp, labelSection, i + j + 1); - CUITextWnd* label = UIHelper::CreateTextWnd(*uiXml, temp, this, false); + auto* label = UIHelper::CreateStatic(*uiXml, temp, this, false); if (label) { if (true /*!label->WndPosIsProbablyRelative()*/) // Without this, UI Frustum will cull our label diff --git a/src/xrGame/ui/UIDragDropReferenceList.h b/src/xrGame/ui/UIDragDropReferenceList.h index 6b6aa2102ce..0b9f802ab96 100644 --- a/src/xrGame/ui/UIDragDropReferenceList.h +++ b/src/xrGame/ui/UIDragDropReferenceList.h @@ -10,7 +10,7 @@ class CUIDragDropReferenceList final : public CUIDragDropListEx typedef xr_vector ITEMS_REFERENCES_VEC; typedef ITEMS_REFERENCES_VEC::iterator ITEMS_REFERENCES_VEC_IT; ITEMS_REFERENCES_VEC m_references; - xr_vector m_labels; + xr_vector m_labels; pcstr m_translation_id; public: diff --git a/src/xrGame/ui/UIGameLog.cpp b/src/xrGame/ui/UIGameLog.cpp index 84e40e406ca..c7eb97885cc 100644 --- a/src/xrGame/ui/UIGameLog.cpp +++ b/src/xrGame/ui/UIGameLog.cpp @@ -19,9 +19,9 @@ CUIGameLog::CUIGameLog() m_pFont = NULL; } -CUITextWnd* CUIGameLog::AddLogMessage(LPCSTR msg) +CUIStatic* CUIGameLog::AddLogMessage(LPCSTR msg) { - CUITextWnd* pItem = NULL; + CUIStatic* pItem{}; ADD_TEXT_TO_VIEW3(msg, pItem, this); pItem->SetFont(m_pFont); pItem->SetTextColor(txt_color); @@ -57,7 +57,7 @@ void CUIGameLog::AddChatMessage(LPCSTR msg, LPCSTR author) _TrimRight(fullLine); - CUITextWnd* pItem = xr_new(); + auto* pItem = xr_new("Chat message"); pItem->SetTextComplexMode(true); pItem->SetText(fullLine); pItem->SetCutWordsMode(true); diff --git a/src/xrGame/ui/UIGameLog.h b/src/xrGame/ui/UIGameLog.h index bffbfe7ee89..f51900d4b52 100644 --- a/src/xrGame/ui/UIGameLog.h +++ b/src/xrGame/ui/UIGameLog.h @@ -14,14 +14,13 @@ class CUIXml; class CUIPdaKillMessage; class CUIPdaMsgListItem; class CUIStatic; -class CUITextWnd; struct KillMessageStruct; class CUIGameLog final : public CUIScrollView { public: CUIGameLog(); - CUITextWnd* AddLogMessage(LPCSTR msg); + CUIStatic* AddLogMessage(LPCSTR msg); CUIPdaKillMessage* AddLogMessage(KillMessageStruct& msg); CUIPdaMsgListItem* AddPdaMessage(); void AddChatMessage(LPCSTR msg, LPCSTR author); diff --git a/src/xrGame/ui/UIHelper.cpp b/src/xrGame/ui/UIHelper.cpp index 9cd05ed06f9..dde3e06f51c 100644 --- a/src/xrGame/ui/UIHelper.cpp +++ b/src/xrGame/ui/UIHelper.cpp @@ -84,25 +84,6 @@ CUIScrollView* UIHelper::CreateScrollView(CUIXml& xml, LPCSTR ui_path, CUIWindow return ui; } -CUITextWnd* UIHelper::CreateTextWnd(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical) -{ - // If it's not critical element, then don't crash if it doesn't exist - if (!critical && !xml.NavigateToNode(ui_path, 0)) - return nullptr; - - auto ui = xr_new(); - if (!CUIXmlInit::InitTextWnd(xml, ui_path, 0, ui, critical) && !critical) - { - xr_delete(ui); - } - if (ui && parent) - { - parent->AttachChild(ui); - ui->SetAutoDelete(true); - } - return ui; -} - CUIEditBox* UIHelper::CreateEditBox(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical) { // If it's not critical element, then don't crash if it doesn't exist diff --git a/src/xrGame/ui/UIHelper.h b/src/xrGame/ui/UIHelper.h index d78d782cb3d..41e40c8562f 100644 --- a/src/xrGame/ui/UIHelper.h +++ b/src/xrGame/ui/UIHelper.h @@ -12,7 +12,6 @@ class CUIXml; class CUIWindow; class CUIStatic; class CUIScrollView; -class CUITextWnd; class CUIProgressBar; class CUIProgressShape; class CUIFrameLineWnd; @@ -34,7 +33,6 @@ class UIHelper static CUIStatic* CreateStatic(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static CUIStatic* CreateStatic(CUIXml& xml, LPCSTR ui_path, int index, CUIWindow* parent, bool critical = true); static CUIScrollView* CreateScrollView(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); - static CUITextWnd* CreateTextWnd(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static CUIProgressBar* CreateProgressBar(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static CUIProgressShape* CreateProgressShape(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static CUIFrameLineWnd* CreateFrameLine(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); diff --git a/src/xrGame/ui/UIHudStatesWnd.cpp b/src/xrGame/ui/UIHudStatesWnd.cpp index 1e62e5fa31a..8376d301380 100644 --- a/src/xrGame/ui/UIHudStatesWnd.cpp +++ b/src/xrGame/ui/UIHudStatesWnd.cpp @@ -144,12 +144,12 @@ void CUIHudStatesWnd::InitFromXml(CUIXml& xml, LPCSTR path) m_ui_weapon_sign_ammo = UIHelper::CreateStatic(xml, "static_ammo", weaponsParent, false); //m_ui_weapon_sign_ammo->SetEllipsis( CUIStatic::eepEnd, 2 ); - m_ui_weapon_cur_ammo = UIHelper::CreateTextWnd(xml, "static_cur_ammo", this, false); - m_ui_weapon_fmj_ammo = UIHelper::CreateTextWnd(xml, "static_fmj_ammo", this, false); - m_ui_weapon_ap_ammo = UIHelper::CreateTextWnd(xml, "static_ap_ammo", this, false); - m_ui_weapon_third_ammo = UIHelper::CreateTextWnd(xml, "static_third_ammo", this, false); //Alundaio: Option to display a third ammo type - m_fire_mode = UIHelper::CreateTextWnd(xml, "static_fire_mode", this); - m_ui_grenade = UIHelper::CreateTextWnd(xml, "static_grenade", this, false); + m_ui_weapon_cur_ammo = UIHelper::CreateStatic(xml, "static_cur_ammo", this, false); + m_ui_weapon_fmj_ammo = UIHelper::CreateStatic(xml, "static_fmj_ammo", this, false); + m_ui_weapon_ap_ammo = UIHelper::CreateStatic(xml, "static_ap_ammo", this, false); + m_ui_weapon_third_ammo = UIHelper::CreateStatic(xml, "static_third_ammo", this, false); //Alundaio: Option to display a third ammo type + m_fire_mode = UIHelper::CreateStatic(xml, "static_fire_mode", this); + m_ui_grenade = UIHelper::CreateStatic(xml, "static_grenade", this, false); m_ui_weapon_icon = UIHelper::CreateStatic(xml, "static_wpn_icon", weaponsParent); m_ui_weapon_icon->SetShader(InventoryUtilities::GetEquipmentIconsShader()); diff --git a/src/xrGame/ui/UIHudStatesWnd.h b/src/xrGame/ui/UIHudStatesWnd.h index 21acc2a5593..4f4c7358ab9 100644 --- a/src/xrGame/ui/UIHudStatesWnd.h +++ b/src/xrGame/ui/UIHudStatesWnd.h @@ -5,7 +5,6 @@ #include "actor_defs.h" class CUIStatic; -class CUITextWnd; class CUIProgressBar; class CUIProgressShape; class CUIXml; @@ -30,12 +29,12 @@ class CUIHudStatesWnd final : public CUIWindow xr_map m_resist_back; xr_map m_indik; - CUITextWnd* m_ui_weapon_cur_ammo; - CUITextWnd* m_ui_weapon_fmj_ammo; - CUITextWnd* m_ui_weapon_ap_ammo; - CUITextWnd* m_ui_weapon_third_ammo; //Alundaio - CUITextWnd* m_fire_mode; - CUITextWnd* m_ui_grenade; + CUIStatic* m_ui_weapon_cur_ammo; + CUIStatic* m_ui_weapon_fmj_ammo; + CUIStatic* m_ui_weapon_ap_ammo; + CUIStatic* m_ui_weapon_third_ammo; //Alundaio + CUIStatic* m_fire_mode; + CUIStatic* m_ui_grenade; II_BriefInfo m_item_info; CUIStatic* m_ui_weapon_sign_ammo; diff --git a/src/xrGame/ui/UIInventoryUtilities.cpp b/src/xrGame/ui/UIInventoryUtilities.cpp index ef657774699..17b818c0a20 100644 --- a/src/xrGame/ui/UIInventoryUtilities.cpp +++ b/src/xrGame/ui/UIInventoryUtilities.cpp @@ -379,7 +379,7 @@ void InventoryUtilities::UpdateWeight(CUIStatic& wnd, CInventoryOwner* pInvOwner ////////////////////////////////////////////////////////////////////////// -void InventoryUtilities::UpdateWeightStr(CUITextWnd& wnd, CUITextWnd& wnd_max, CInventoryOwner* pInvOwner) +void InventoryUtilities::UpdateWeightStr(CUIStatic& wnd, CUIStatic& wnd_max, CInventoryOwner* pInvOwner) { R_ASSERT(pInvOwner); string128 buf; diff --git a/src/xrGame/ui/UIInventoryUtilities.h b/src/xrGame/ui/UIInventoryUtilities.h index 3be52cfcd76..aec3cc63893 100644 --- a/src/xrGame/ui/UIInventoryUtilities.h +++ b/src/xrGame/ui/UIInventoryUtilities.h @@ -3,7 +3,7 @@ #include "character_info_defs.h" #include "xrUICore/ui_defs.h" -class CUITextWnd; +class CUIStatic; //размеры сетки в текстуре инвентаря #define INV_GRID_WIDTH 50.0f @@ -75,7 +75,7 @@ const shared_str Get_GameTimeAndDate_AsString(); LPCSTR GetTimePeriodAsString(pstr _buff, u32 buff_sz, ALife::_TIME_ID _from, ALife::_TIME_ID _to); // Отобразить вес, который несет (*pInvOwner) void UpdateWeight(CUIStatic& wnd, CInventoryOwner* pInvOwner, bool withPrefix = false); -void UpdateWeightStr(CUITextWnd& wnd, CUITextWnd& wnd_max, CInventoryOwner* pInvOwner); +void UpdateWeightStr(CUIStatic& wnd, CUIStatic& wnd_max, CInventoryOwner* pInvOwner); // Функции получения строки-идентификатора ранга и отношения по их числовому идентификатору LPCSTR GetRankAsText(CHARACTER_RANK_VALUE rankID); diff --git a/src/xrGame/ui/UIItemInfo.cpp b/src/xrGame/ui/UIItemInfo.cpp index 24004dd475c..eb93af24b81 100644 --- a/src/xrGame/ui/UIItemInfo.cpp +++ b/src/xrGame/ui/UIItemInfo.cpp @@ -84,13 +84,13 @@ bool CUIItemInfo::InitItemInfo(cpcstr xml_name) } UIBackground = UIHelper::CreateFrameWindow(uiXml, "background_frame", this, false); - UIName = UIHelper::CreateTextWnd(uiXml, "static_name", this, false); + UIName = UIHelper::CreateStatic(uiXml, "static_name", this, false); if (UIName) m_complex_desc = (uiXml.ReadAttribInt("static_name", 0, "complex_desc", 0) == 1); - UIWeight = UIHelper::CreateTextWnd(uiXml, "static_weight", this, false); - UICost = UIHelper::CreateTextWnd(uiXml, "static_cost", this, false); - UITradeTip = UIHelper::CreateTextWnd(uiXml, "static_no_trade", this, false); + UIWeight = UIHelper::CreateStatic(uiXml, "static_weight", this, false); + UICost = UIHelper::CreateStatic(uiXml, "static_cost", this, false); + UITradeTip = UIHelper::CreateStatic(uiXml, "static_no_trade", this, false); if (uiXml.NavigateToNode("descr_list", 0)) { @@ -269,7 +269,7 @@ void CUIItemInfo::InitItem(CUICellItem* pCellItem, CInventoryItem* pCompareItem, VERIFY(0 == UIDesc->GetSize()); if (m_desc_info.bShowDescrText) { - CUITextWnd* pItem = xr_new(); + auto* pItem = xr_new("Description"); pItem->SetTextColor(m_desc_info.uDescClr); pItem->SetFont(m_desc_info.pDescFont); pItem->SetWidth(UIDesc->GetDesiredChildWidth()); diff --git a/src/xrGame/ui/UIItemInfo.h b/src/xrGame/ui/UIItemInfo.h index 2da03e2d239..2335b6e70dc 100644 --- a/src/xrGame/ui/UIItemInfo.h +++ b/src/xrGame/ui/UIItemInfo.h @@ -3,7 +3,6 @@ class CInventoryItem; class CUIStatic; -class CUITextWnd; class CUIScrollView; class CUIProgressBar; class CUIConditionParams; @@ -54,10 +53,10 @@ class CUIItemInfo final : public CUIWindow u32 delay; CUIFrameWindow* UIBackground; - CUITextWnd* UIName; - CUITextWnd* UIWeight; - CUITextWnd* UICost; - CUITextWnd* UITradeTip; + CUIStatic* UIName; + CUIStatic* UIWeight; + CUIStatic* UICost; + CUIStatic* UITradeTip; // CUIStatic* UIDesc_line; CUIScrollView* UIDesc; bool m_complex_desc; diff --git a/src/xrGame/ui/UIKeyBinding.cpp b/src/xrGame/ui/UIKeyBinding.cpp index 94f02a33907..f79c9e16266 100644 --- a/src/xrGame/ui/UIKeyBinding.cpp +++ b/src/xrGame/ui/UIKeyBinding.cpp @@ -139,18 +139,17 @@ void CUIKeyBinding::OnKeyMapChanged() void CUIKeyBinding::CheckStructure(CUIXml& xml_doc) { bool first = true; - CUITextWnd* item = nullptr; for (int i = 0; true; ++i) { - LPCSTR action_name = actions[i].action_name; - if (action_name) + if (cpcstr action_name = actions[i].action_name) { if (!IsActionExist(action_name, xml_doc)) { + CUIStatic* item = nullptr; if (first) { - item = xr_new(); + item = xr_new("First action"); item->SetWndPos(Fvector2().set(0, 0)); item->SetWndSize(Fvector2().set(m_scroll_wnd->GetWndSize().x, 20.0f)); item->SetText("NEXT ITEMS NOT DESCRIBED IN COMMAND DESC LIST"); @@ -159,7 +158,7 @@ void CUIKeyBinding::CheckStructure(CUIXml& xml_doc) m_scroll_wnd->AddWindow(item, true); } - item = xr_new(); + item = xr_new(action_name); item->SetWndPos(Fvector2().set(0, 0)); item->SetWndSize(Fvector2().set(m_scroll_wnd->GetWndSize().x, 20.0f)); item->SetText(action_name); diff --git a/src/xrGame/ui/UIListItemServer.h b/src/xrGame/ui/UIListItemServer.h index b82b5cec756..897a009f819 100644 --- a/src/xrGame/ui/UIListItemServer.h +++ b/src/xrGame/ui/UIListItemServer.h @@ -64,14 +64,15 @@ class CUIListItemServer final : public CUIListBoxItem LIST_SRV_SIZES m_sizes; LIST_SRV_ITEM m_srv_info; + CUIStatic* m_iconPass; CUIStatic* m_iconDedicated; // CUIStatic* m_iconPunkBuster; CUIStatic* m_iconUserPass; - CUITextWnd* m_server; - CUITextWnd* m_map; - CUITextWnd* m_game; - CUITextWnd* m_players; - CUITextWnd* m_ping; - CUITextWnd* m_version; + CUIStatic* m_server; + CUIStatic* m_map; + CUIStatic* m_game; + CUIStatic* m_players; + CUIStatic* m_ping; + CUIStatic* m_version; }; diff --git a/src/xrGame/ui/UILogsWnd.cpp b/src/xrGame/ui/UILogsWnd.cpp index c17287f3f0b..bdfc5d5195b 100644 --- a/src/xrGame/ui/UILogsWnd.cpp +++ b/src/xrGame/ui/UILogsWnd.cpp @@ -119,7 +119,7 @@ bool CUILogsWnd::Init() if (!m_center_background) m_center_background2 = UIHelper::CreateStatic(m_uiXml, "center_background", this, false); - m_center_caption = UIHelper::CreateTextWnd(m_uiXml, "center_caption", this); + m_center_caption = UIHelper::CreateStatic(m_uiXml, "center_caption", this); string256 buf; xr_strcpy(buf, sizeof(buf), m_center_caption->GetText()); @@ -139,8 +139,8 @@ bool CUILogsWnd::Init() m_filter_news->SetCheck(true); m_filter_talk->SetCheck(true); - m_date_caption = UIHelper::CreateTextWnd(m_uiXml, "date_caption", this, false); - m_date = UIHelper::CreateTextWnd(m_uiXml, "date", this, false); + m_date_caption = UIHelper::CreateStatic(m_uiXml, "date_caption", this, false); + m_date = UIHelper::CreateStatic(m_uiXml, "date", this, false); if (m_date || m_date_caption) { @@ -148,7 +148,7 @@ bool CUILogsWnd::Init() "Please, provide both [date] and [date_caption] tags in xml file", m_uiXml.m_xml_file_name); } - m_period_caption = UIHelper::CreateTextWnd(m_uiXml, "period_caption", this); + m_period_caption = UIHelper::CreateStatic(m_uiXml, "period_caption", this); m_period = UIHelper::CreateStatic(m_uiXml, "period", this); m_prev_period = UIHelper::Create3tButton(m_uiXml, "btn_prev_period", this); diff --git a/src/xrGame/ui/UILogsWnd.h b/src/xrGame/ui/UILogsWnd.h index fd5e1dd9144..a3d0f589509 100644 --- a/src/xrGame/ui/UILogsWnd.h +++ b/src/xrGame/ui/UILogsWnd.h @@ -16,7 +16,6 @@ #include "xrUICore/XML/xrUIXmlParser.h" class CUIStatic; -class CUITextWnd; class CUIXml; class CUIProgressBar; class CUIFrameLineWnd; @@ -38,16 +37,16 @@ class CUILogsWnd final : public CUIWindow, public CUIWndCallback CUIFrameWindow* m_center_background; CUIStatic* m_center_background2; - CUITextWnd* m_center_caption; + CUIStatic* m_center_caption; CUICharacterInfo* m_actor_ch_info; CUICheckButton* m_filter_news; CUICheckButton* m_filter_talk; - CUITextWnd* m_date_caption; - CUITextWnd* m_date; + CUIStatic* m_date_caption; + CUIStatic* m_date; - CUITextWnd* m_period_caption; + CUIStatic* m_period_caption; CUIStatic* m_period; ALife::_TIME_ID m_start_game_time; diff --git a/src/xrGame/ui/UIMMShniaga.cpp b/src/xrGame/ui/UIMMShniaga.cpp index 46a3b87f133..00065088d96 100644 --- a/src/xrGame/ui/UIMMShniaga.cpp +++ b/src/xrGame/ui/UIMMShniaga.cpp @@ -142,7 +142,7 @@ void CUIMMShniaga::InitShniaga(CUIXml& xml_doc, LPCSTR path) void CUIMMShniaga::OnDeviceReset() {} -void CUIMMShniaga::CreateList(xr_vector& lst, CUIXml& xml_doc, LPCSTR path, bool required /*= true*/) +void CUIMMShniaga::CreateList(xr_vector& lst, CUIXml& xml_doc, LPCSTR path, bool required /*= true*/) { u32 color; CGameFont* pF; @@ -167,11 +167,9 @@ void CUIMMShniaga::CreateList(xr_vector& lst, CUIXml& xml_doc, LPCS XML_NODE tab_node = xml_doc.NavigateToNode(path, 0); xml_doc.SetLocalRoot(tab_node); - CUITextWnd* st; - for (int i = 0; i < nodes_num; ++i) { - st = xr_new(); + auto* st = xr_new("Button"); st->SetWndPos(Fvector2().set(0, 0)); st->SetWndSize(Fvector2().set(m_view->GetDesiredChildWidth(), button_height)); st->SetFont(pF); @@ -196,7 +194,7 @@ void CUIMMShniaga::CreateList(xr_vector& lst, CUIXml& xml_doc, LPCS void CUIMMShniaga::SetPage(enum_page_id page_id, LPCSTR xml_file, LPCSTR xml_path) { VERIFY(m_page != page_id); - xr_vector* lst = NULL; + xr_vector* lst = nullptr; switch (page_id) { case epi_main: lst = &m_buttons; break; diff --git a/src/xrGame/ui/UIMMShniaga.h b/src/xrGame/ui/UIMMShniaga.h index a806cabd846..a66a609289d 100644 --- a/src/xrGame/ui/UIMMShniaga.h +++ b/src/xrGame/ui/UIMMShniaga.h @@ -2,7 +2,6 @@ #include "xrUICore/Windows/UIWindow.h" class CUIStatic; -class CUITextWnd; class CUIXml; class CUIScrollView; class CMMSound; @@ -59,7 +58,7 @@ class CUIMMShniaga final : public CUIWindow, public CDeviceResetNotifier void ProcessEvent(EVENT ev); bool IsButton(CUIWindow* st); - void CreateList(xr_vector& lst, CUIXml& xml_doc, LPCSTR path, bool required = true); + void CreateList(xr_vector& lst, CUIXml& xml_doc, LPCSTR path, bool required = true); void ShowMain(); void ShowNewGame(); void ShowNetworkGame(); @@ -80,9 +79,9 @@ class CUIMMShniaga final : public CUIWindow, public CDeviceResetNotifier float m_mag_pos; float m_offset; - xr_vector m_buttons; - xr_vector m_buttons_new; - xr_vector m_buttons_new_network; + xr_vector m_buttons; + xr_vector m_buttons_new; + xr_vector m_buttons_new_network; int m_selected_btn; enum_page_id m_page; diff --git a/src/xrGame/ui/UIMPChangeMapAdm.cpp b/src/xrGame/ui/UIMPChangeMapAdm.cpp index c9d941d9139..37bb87c73a2 100644 --- a/src/xrGame/ui/UIMPChangeMapAdm.cpp +++ b/src/xrGame/ui/UIMPChangeMapAdm.cpp @@ -20,7 +20,7 @@ CUIMpChangeMapAdm::CUIMpChangeMapAdm() : CUIWindow("CUIMpChangeMapAdm") map_frame->SetAutoDelete(true); AttachChild(map_frame); - map_version = xr_new(); + map_version = xr_new("Map version"); map_version->SetAutoDelete(true); AttachChild(map_version); @@ -37,7 +37,7 @@ void CUIMpChangeMapAdm::Init(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "change_map_adm", 0, this); CUIXmlInit::InitStatic(xml_doc, "change_map_adm:map_frame", 0, map_frame); - CUIXmlInit::InitTextWnd(xml_doc, "change_map_adm:map_ver_txt", 0, map_version); + CUIXmlInit::InitStatic(xml_doc, "change_map_adm:map_ver_txt", 0, map_version); CUIXmlInit::InitStatic(xml_doc, "change_map_adm:map_pic", 0, map_pic); CUIXmlInit::InitListBox(xml_doc, "change_map_adm:list", 0, lst); CUIXmlInit::Init3tButton(xml_doc, "change_map_adm:btn_ok", 0, btn_ok); diff --git a/src/xrGame/ui/UIMPChangeMapAdm.h b/src/xrGame/ui/UIMPChangeMapAdm.h index 2c5654ab9a7..8510743ca3b 100644 --- a/src/xrGame/ui/UIMPChangeMapAdm.h +++ b/src/xrGame/ui/UIMPChangeMapAdm.h @@ -5,7 +5,6 @@ class CUIXml; class CUIStatic; -class CUITextWnd; class CUIListBox; class CUI3tButton; @@ -14,7 +13,7 @@ class CUIMpChangeMapAdm final : public CUIWindow, public CUIWndCallback typedef CUIWindow inherited; CUIStatic* map_pic; CUIStatic* map_frame; - CUITextWnd* map_version; + CUIStatic* map_version; CUIListBox* lst; CUI3tButton* btn_ok; diff --git a/src/xrGame/ui/UIMPPlayersAdm.cpp b/src/xrGame/ui/UIMPPlayersAdm.cpp index 1c594216482..59140601247 100644 --- a/src/xrGame/ui/UIMPPlayersAdm.cpp +++ b/src/xrGame/ui/UIMPPlayersAdm.cpp @@ -45,7 +45,7 @@ CUIMpPlayersAdm::CUIMpPlayersAdm() : CUIWindow("CUIMpPlayersAdm") m_pPingLimitTrack->SetAutoDelete(true); AttachChild(m_pPingLimitTrack); - m_pPingLimitText = xr_new(); + m_pPingLimitText = xr_new("Ping limit"); m_pPingLimitText->SetAutoDelete(true); AttachChild(m_pPingLimitText); @@ -69,11 +69,11 @@ CUIMpPlayersAdm::CUIMpPlayersAdm() : CUIWindow("CUIMpPlayersAdm") m_pBanPlayerCombo->SetAutoDelete(true); AttachChild(m_pBanPlayerCombo); - // m_pBanTimeTrack = new CUITrackBar(); + // m_pBanTimeTrack = xr_new(); // m_pBanTimeTrack->SetAutoDelete(true); // AttachChild(m_pBanTimeTrack); - // m_pBanTimeText = new CUITextWnd(); + // m_pBanTimeText = xr_new("Ban time"); // m_pBanTimeText->SetAutoDelete(true); // AttachChild(m_pBanTimeText); } @@ -88,14 +88,14 @@ void CUIMpPlayersAdm::Init(CUIXml& xml_doc) CUIXmlInit::Init3tButton(xml_doc, "players_adm:config_all_button", 0, m_pConfigAllBtn); CUIXmlInit::Init3tButton(xml_doc, "players_adm:max_ping_limit_button", 0, m_pPingLimitBtn); CUIXmlInit::InitTrackBar(xml_doc, "players_adm:max_ping_limit_track", 0, m_pPingLimitTrack); - CUIXmlInit::InitTextWnd(xml_doc, "players_adm:max_ping_limit_text", 0, m_pPingLimitText); + CUIXmlInit::InitStatic(xml_doc, "players_adm:max_ping_limit_text", 0, m_pPingLimitText); CUIXmlInit::Init3tButton(xml_doc, "players_adm:screen_player_button", 0, m_pScreenPlayerBtn); CUIXmlInit::Init3tButton(xml_doc, "players_adm:config_player_button", 0, m_pConfigPlayerBtn); CUIXmlInit::Init3tButton(xml_doc, "players_adm:kick_player_button", 0, m_pKickPlayerBtn); CUIXmlInit::Init3tButton(xml_doc, "players_adm:ban_player_button", 0, m_pBanPlayerBtn); CUIXmlInit::InitComboBox(xml_doc, "players_adm:ban_player_combo", 0, m_pBanPlayerCombo); // CUIXmlInit::InitTrackBar(xml_doc, "players_adm:ban_time_track", 0, m_pBanTimeTrack); - // CUIXmlInit::InitTextWnd(xml_doc, "players_adm:ban_time_text", 0, m_pBanTimeText); + // CUIXmlInit::InitStatic(xml_doc, "players_adm:ban_time_text", 0, m_pBanTimeText); RefreshPlayersList(); int min, max; g_sv_adm_menu_ping_limit = iCeil(Console->GetInteger("sv_max_ping_limit", min, max) / 10.0f); diff --git a/src/xrGame/ui/UIMPPlayersAdm.h b/src/xrGame/ui/UIMPPlayersAdm.h index 51f7e30a5a0..b82043501db 100644 --- a/src/xrGame/ui/UIMPPlayersAdm.h +++ b/src/xrGame/ui/UIMPPlayersAdm.h @@ -7,7 +7,6 @@ class CUIXml; class CUIListBox; class CUI3tButton; class CUITrackBar; -class CUITextWnd; class CUIComboBox; class CUIMpPlayersAdm final : public CUIWindow, public CUIWndCallback @@ -19,14 +18,14 @@ class CUIMpPlayersAdm final : public CUIWindow, public CUIWndCallback CUI3tButton* m_pConfigAllBtn; CUI3tButton* m_pPingLimitBtn; CUITrackBar* m_pPingLimitTrack; - CUITextWnd* m_pPingLimitText; + CUIStatic* m_pPingLimitText; CUI3tButton* m_pScreenPlayerBtn; CUI3tButton* m_pConfigPlayerBtn; CUI3tButton* m_pKickPlayerBtn; CUI3tButton* m_pBanPlayerBtn; CUIComboBox* m_pBanPlayerCombo; // CUITrackBar* m_pBanTimeTrack; - // CUITextWnd* m_pBanTimeText; + // CUIStatic* m_pBanTimeText; public: CUIMpPlayersAdm(); ~CUIMpPlayersAdm() override; diff --git a/src/xrGame/ui/UIMainIngameWnd.cpp b/src/xrGame/ui/UIMainIngameWnd.cpp index a9cd904b7be..7eb7074cf35 100644 --- a/src/xrGame/ui/UIMainIngameWnd.cpp +++ b/src/xrGame/ui/UIMainIngameWnd.cpp @@ -104,7 +104,7 @@ void CUIMainIngameWnd::Init() //--------------------------------------------------------- // Подсказки, которые возникают при наведении прицела на объект - UIStaticQuickHelp = UIHelper::CreateTextWnd(uiXml, "quick_info", this); + UIStaticQuickHelp = UIHelper::CreateStatic(uiXml, "quick_info", this); uiXml.SetLocalRoot(uiXml.GetRoot()); @@ -248,8 +248,7 @@ void CUIMainIngameWnd::Init() m_quick_slots_icons.push_back(slot); xr_sprintf(path, "quick_slot%d_text", i); - CUITextWnd* text = UIHelper::CreateTextWnd(uiXml, path, this); - m_quick_slots_texts.push_back(text); + m_quick_slots_texts.emplace_back(UIHelper::CreateStatic(uiXml, path, this)); i++; } diff --git a/src/xrGame/ui/UIMainIngameWnd.h b/src/xrGame/ui/UIMainIngameWnd.h index cbc4fed938e..ee25106e5c9 100644 --- a/src/xrGame/ui/UIMainIngameWnd.h +++ b/src/xrGame/ui/UIMainIngameWnd.h @@ -29,7 +29,7 @@ class CUIMainIngameWnd final : public CUIWindow protected: CUIStatic* UIStaticDiskIO{}; - CUITextWnd* UIStaticQuickHelp{}; + CUIStatic* UIStaticQuickHelp{}; CUIMotionIcon* UIMotionIcon{}; CUIZoneMap* UIZoneMap{}; @@ -65,7 +65,7 @@ class CUIMainIngameWnd final : public CUIWindow void OnSectorChanged(IRender_Sector::sector_id_t sector); xr_vector m_quick_slots_icons; - xr_vector m_quick_slots_texts; + xr_vector m_quick_slots_texts; protected: // 5 статиков для отображения иконок: diff --git a/src/xrGame/ui/UIMapInfo.cpp b/src/xrGame/ui/UIMapInfo.cpp index 3a5eb3ca50e..efd43d0c094 100644 --- a/src/xrGame/ui/UIMapInfo.cpp +++ b/src/xrGame/ui/UIMapInfo.cpp @@ -31,7 +31,7 @@ void CUIMapInfo::InitMapInfo(Fvector2 pos, Fvector2 size) else \ text += *StringTable().translate(z); \ text += "%c[default]\\n"; \ - st = new CUITextWnd(); \ + st = xr_new("Text"); \ st->SetTextComplexMode(true); \ st->SetFont(txt_font); \ st->SetTextColor(header_color); \ @@ -49,7 +49,6 @@ void CUIMapInfo::InitMap(LPCSTR map_name, LPCSTR map_ver) CUIXml xml_doc; xml_doc.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "ui_mapinfo.xml"); - CUITextWnd* st; // try to find file with info xr_string info_path = "text" DELIMITER "map_desc" DELIMITER; info_path += map_name; @@ -63,8 +62,8 @@ void CUIMapInfo::InitMap(LPCSTR map_name, LPCSTR map_ver) xr_string text; // map name - st = xr_new(); - CUIXmlInit::InitTextWnd(xml_doc, "map_name", 0, st); + auto* st = xr_new("Map name"); + CUIXmlInit::InitStatic(xml_doc, "map_name", 0, st); xr_string S = StringTable().translate(map_name).c_str(); if (map_ver) @@ -116,7 +115,7 @@ void CUIMapInfo::InitMap(LPCSTR map_name, LPCSTR map_ver) text += "%c[default]\\n"; - st = xr_new(); + st = xr_new("Game modes"); st->SetTextComplexMode(true); st->SetFont(txt_font); st->SetTextColor(header_color); @@ -132,8 +131,8 @@ void CUIMapInfo::InitMap(LPCSTR map_name, LPCSTR map_ver) } else { - st = xr_new(); - CUIXmlInit::InitTextWnd(xml_doc, "map_name", 0, st); + auto* st = xr_new("Map name"); + CUIXmlInit::InitStatic(xml_doc, "map_name", 0, st); st->SetTextST(map_name); st->SetWidth(m_view->GetDesiredChildWidth()); st->AdjustHeightToText(); diff --git a/src/xrGame/ui/UIMoneyIndicator.cpp b/src/xrGame/ui/UIMoneyIndicator.cpp index 6c920fac01d..9d12cd1b9ea 100644 --- a/src/xrGame/ui/UIMoneyIndicator.cpp +++ b/src/xrGame/ui/UIMoneyIndicator.cpp @@ -22,8 +22,8 @@ void CUIMoneyIndicator::InitFromXML(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "money_wnd", 0, this); CUIXmlInit::InitStatic(xml_doc, "money_wnd:money_indicator", 0, &m_back); - CUIXmlInit::InitTextWnd(xml_doc, "money_wnd:money_indicator:total_money", 0, &m_money_amount); - CUIXmlInit::InitTextWnd(xml_doc, "money_wnd:money_change", 0, &m_money_change); + CUIXmlInit::InitStatic(xml_doc, "money_wnd:money_indicator:total_money", 0, &m_money_amount); + CUIXmlInit::InitStatic(xml_doc, "money_wnd:money_change", 0, &m_money_change); CUIXmlInit::InitScrollView(xml_doc, "money_wnd:money_bonus_list", 0, m_pBonusMoney); CGameFont* pF; u32 color; diff --git a/src/xrGame/ui/UIMoneyIndicator.h b/src/xrGame/ui/UIMoneyIndicator.h index 458d2779186..29fc77529e4 100644 --- a/src/xrGame/ui/UIMoneyIndicator.h +++ b/src/xrGame/ui/UIMoneyIndicator.h @@ -19,8 +19,8 @@ class CUIMoneyIndicator final : public CUIWindow pcstr GetDebugType() override { return "CUIMoneyIndicator"; } protected: - CUIStatic m_back; - CUITextWnd m_money_amount; - CUITextWnd m_money_change; + CUIStatic m_back{ "Background" }; + CUIStatic m_money_amount{ "Money amount" }; + CUIStatic m_money_change{ "Money change" }; CUIGameLog* m_pBonusMoney; }; diff --git a/src/xrGame/ui/UIMpTradeWnd.h b/src/xrGame/ui/UIMpTradeWnd.h index 4aedf73a918..4003d786551 100644 --- a/src/xrGame/ui/UIMpTradeWnd.h +++ b/src/xrGame/ui/UIMpTradeWnd.h @@ -9,7 +9,6 @@ class CUIDragDropListEx; class CUI3tButton; class CUIStatic; -class CUITextWnd; class CUIMpItemsStoreWnd; class CUITabControl; class CUICellItem; @@ -148,12 +147,12 @@ class CUIMpTradeWnd final : public IBuyWnd, public CUIWndCallback bool m_bIgnoreMoneyAndRank; // controls CUIWindow* m_shop_wnd; - CUITextWnd* m_static_curr_items_money; - CUITextWnd* m_static_player_money; - CUITextWnd* m_static_preset_money[5]; + CUIStatic* m_static_curr_items_money; + CUIStatic* m_static_player_money; + CUIStatic* m_static_preset_money[5]; CUIStatic* m_static_player_rank; - CUITextWnd* m_static_information; - CUITextWnd* m_static_money_change; + CUIStatic* m_static_information; + CUIStatic* m_static_money_change; CUI3tButton* m_btn_shop_back; CUI3tButton* m_btn_ok; CUI3tButton* m_btn_cancel; diff --git a/src/xrGame/ui/UIMpTradeWnd_init.cpp b/src/xrGame/ui/UIMpTradeWnd_init.cpp index 2405fbf93d7..d0e4edeec0d 100644 --- a/src/xrGame/ui/UIMpTradeWnd_init.cpp +++ b/src/xrGame/ui/UIMpTradeWnd_init.cpp @@ -179,14 +179,14 @@ void CUIMpTradeWnd::Init(const shared_str& sectionName, const shared_str& sectio //(this, //&CUIMpTradeWnd::OnBtnRifleAmmo2Clicked )); - m_static_player_money = UIHelper::CreateTextWnd(xml_doc, "static_player_money", this); - m_static_curr_items_money = UIHelper::CreateTextWnd(xml_doc, "static_curr_items_money", this); + m_static_player_money = UIHelper::CreateStatic(xml_doc, "static_player_money", this); + m_static_curr_items_money = UIHelper::CreateStatic(xml_doc, "static_curr_items_money", this); - m_static_preset_money[0] = UIHelper::CreateTextWnd(xml_doc, "static_preset_money_last", this); - m_static_preset_money[1] = UIHelper::CreateTextWnd(xml_doc, "static_preset_money_1", this); - m_static_preset_money[2] = UIHelper::CreateTextWnd(xml_doc, "static_preset_money_2", this); - m_static_preset_money[3] = UIHelper::CreateTextWnd(xml_doc, "static_preset_money_3", this); - m_static_preset_money[4] = UIHelper::CreateTextWnd(xml_doc, "static_preset_money_def", this); + m_static_preset_money[0] = UIHelper::CreateStatic(xml_doc, "static_preset_money_last", this); + m_static_preset_money[1] = UIHelper::CreateStatic(xml_doc, "static_preset_money_1", this); + m_static_preset_money[2] = UIHelper::CreateStatic(xml_doc, "static_preset_money_2", this); + m_static_preset_money[3] = UIHelper::CreateStatic(xml_doc, "static_preset_money_3", this); + m_static_preset_money[4] = UIHelper::CreateStatic(xml_doc, "static_preset_money_def", this); // preset money indicators m_item_color_restr_rank = CUIXmlInit::GetColor(xml_doc, "item_color_restr_rank", 0, color_rgba(255, 255, 255, 255)); @@ -201,8 +201,8 @@ void CUIMpTradeWnd::Init(const shared_str& sectionName, const shared_str& sectio m_static_player_rank = UIHelper::CreateStatic(xml_doc, "static_player_rank", this); m_static_item_rank = UIHelper::CreateStatic(xml_doc, "static_item_rank", this); - m_static_information = UIHelper::CreateTextWnd(xml_doc, "static_info", this); - m_static_money_change = UIHelper::CreateTextWnd(xml_doc, "static_money_change", this); + m_static_information = UIHelper::CreateStatic(xml_doc, "static_info", this); + m_static_money_change = UIHelper::CreateStatic(xml_doc, "static_money_change", this); m_item_info = xr_new(); AttachChild(m_item_info); diff --git a/src/xrGame/ui/UIMpTradeWnd_misc.cpp b/src/xrGame/ui/UIMpTradeWnd_misc.cpp index 021727a4de3..1d27d28bb40 100644 --- a/src/xrGame/ui/UIMpTradeWnd_misc.cpp +++ b/src/xrGame/ui/UIMpTradeWnd_misc.cpp @@ -83,7 +83,7 @@ void CUIMpTradeWnd::UpdateMoneyIndicator() // update preset money for (u32 i = _preset_idx_last; i <= _preset_idx_3; ++i) { - CUITextWnd* st = m_static_preset_money[i]; + auto* st = m_static_preset_money[i]; _cost = GetPresetCost((ETradePreset)i); xr_sprintf(buff, "%d", _cost); st->SetText(buff); diff --git a/src/xrGame/ui/UINewsItemWnd.cpp b/src/xrGame/ui/UINewsItemWnd.cpp index 8b346ceb0e3..18406af4f45 100644 --- a/src/xrGame/ui/UINewsItemWnd.cpp +++ b/src/xrGame/ui/UINewsItemWnd.cpp @@ -18,16 +18,16 @@ void CUINewsItemWnd::Init(CUIXml& uiXml, LPCSTR start_from) uiXml.SetLocalRoot(node); m_UIImage = UIHelper::CreateStatic(uiXml, "image", this); - m_UICaption = UIHelper::CreateTextWnd(uiXml, "caption_static", this, false); // no caption tag in SOC + m_UICaption = UIHelper::CreateStatic(uiXml, "caption_static", this, false); // no caption tag in SOC - m_UIText = UIHelper::CreateTextWnd(uiXml, "text_static", this, false); - m_UIDate = UIHelper::CreateTextWnd(uiXml, "date_static", this, false); + m_UIText = UIHelper::CreateStatic(uiXml, "text_static", this, false); + m_UIDate = UIHelper::CreateStatic(uiXml, "date_static", this, false); // SOC if (!m_UIText) - m_UIText = UIHelper::CreateTextWnd(uiXml, "text_cont", this, false); + m_UIText = UIHelper::CreateStatic(uiXml, "text_cont", this, false); if (!m_UIDate) - m_UIDate = UIHelper::CreateTextWnd(uiXml, "date_text_cont", this, false); + m_UIDate = UIHelper::CreateStatic(uiXml, "date_text_cont", this, false); uiXml.SetLocalRoot(stored_root); } diff --git a/src/xrGame/ui/UINewsItemWnd.h b/src/xrGame/ui/UINewsItemWnd.h index 0b1434b5053..e4a20f8fa00 100644 --- a/src/xrGame/ui/UINewsItemWnd.h +++ b/src/xrGame/ui/UINewsItemWnd.h @@ -3,16 +3,15 @@ #include "xrUICore/XML/xrUIXmlParser.h" class CUIStatic; -class CUITextWnd; struct GAME_NEWS_DATA; class CUINewsItemWnd final : public CUIWindow { typedef CUIWindow inherited; - CUITextWnd* m_UIDate; - CUITextWnd* m_UICaption; - CUITextWnd* m_UIText; + CUIStatic* m_UIDate; + CUIStatic* m_UICaption; + CUIStatic* m_UIText; CUIStatic* m_UIImage; public: diff --git a/src/xrGame/ui/UIOutfitInfo.cpp b/src/xrGame/ui/UIOutfitInfo.cpp index 591d9ce0a47..56e77d070aa 100644 --- a/src/xrGame/ui/UIOutfitInfo.cpp +++ b/src/xrGame/ui/UIOutfitInfo.cpp @@ -39,7 +39,7 @@ constexpr cpcstr immunity_st_names[] = }; CUIOutfitImmunity::CUIOutfitImmunity() - : CUIWindow("CUIOutfitImmunity"), m_name("Name") + : CUIWindow("CUIOutfitImmunity"), m_name("Name"), m_value("Value") { AttachChild(&m_name); AttachChild(&m_progress); @@ -66,7 +66,7 @@ bool CUIOutfitImmunity::InitFromXml(CUIXml& xml_doc, LPCSTR base_str, u32 hit_ty strconcat(sizeof(buf), buf, base_str, ":", immunity_names[hit_type], ":static_value"); if (xml_doc.NavigateToNode(buf, 0) && !CallOfPripyatMode) { - CUIXmlInit::InitTextWnd(xml_doc, buf, 0, &m_value); + CUIXmlInit::InitStatic(xml_doc, buf, 0, &m_value); m_value.Show(true); } else diff --git a/src/xrGame/ui/UIOutfitInfo.h b/src/xrGame/ui/UIOutfitInfo.h index e7f162ebfb0..a36743a8684 100644 --- a/src/xrGame/ui/UIOutfitInfo.h +++ b/src/xrGame/ui/UIOutfitInfo.h @@ -22,7 +22,7 @@ class CUIOutfitImmunity final : public CUIWindow protected: CUIStatic m_name; // texture + name CUIDoubleProgressBar m_progress; - CUITextWnd m_value; // 100% + CUIStatic m_value; // 100% float m_magnitude; }; // class CUIOutfitImmunity diff --git a/src/xrGame/ui/UIPdaKillMessage.cpp b/src/xrGame/ui/UIPdaKillMessage.cpp index 80368801494..6b7e4153749 100644 --- a/src/xrGame/ui/UIPdaKillMessage.cpp +++ b/src/xrGame/ui/UIPdaKillMessage.cpp @@ -37,7 +37,7 @@ void CUIPdaKillMessage::Init(KillMessageStruct& msg, CGameFont* F) SetColorAnimation("ui_main_msgs_short", LA_ONLYALPHA | LA_TEXTCOLOR | LA_TEXTURECOLOR, 5000.0f); } -float CUIPdaKillMessage::InitText(CUITextWnd& refStatic, float x, ColoredName& info) +float CUIPdaKillMessage::InitText(CUIStatic& refStatic, float x, ColoredName& info) { if (0 == xr_strlen(info.m_name)) return 0.0f; diff --git a/src/xrGame/ui/UIPdaKillMessage.h b/src/xrGame/ui/UIPdaKillMessage.h index 8022157171d..ae37aa7e463 100644 --- a/src/xrGame/ui/UIPdaKillMessage.h +++ b/src/xrGame/ui/UIPdaKillMessage.h @@ -15,11 +15,11 @@ class CUIPdaKillMessage final : public CUIColorAnimConrollerContainer pcstr GetDebugType() override { return "CUIPdaKillMessage"; } protected: - float InitText(CUITextWnd& refStatic, float x, ColoredName& info); + float InitText(CUIStatic& refStatic, float x, ColoredName& info); float InitIcon(CUIStatic& refStatic, float x, IconInfo& info); - CUITextWnd m_victim_name; - CUIStatic m_initiator{ "Initiator" }; - CUITextWnd m_killer_name; - CUIStatic m_ext_info{ "Ext. info" }; + CUIStatic m_victim_name{ "Victim name" }; + CUIStatic m_initiator { "Initiator" }; + CUIStatic m_killer_name{ "Killer name" }; + CUIStatic m_ext_info { "Ext. info" }; }; diff --git a/src/xrGame/ui/UIPdaMsgListItem.cpp b/src/xrGame/ui/UIPdaMsgListItem.cpp index f3b36f685d7..d924b709c0c 100644 --- a/src/xrGame/ui/UIPdaMsgListItem.cpp +++ b/src/xrGame/ui/UIPdaMsgListItem.cpp @@ -21,14 +21,14 @@ void CUIPdaMsgListItem::InitPdaMsgListItem(const Fvector2& size) AttachChild(&UIIcon); CUIXmlInit::InitStatic(uiXml, "icon_static", 0, &UIIcon); - if (CUIXmlInit::InitTextWnd(uiXml, "time_static", 0, &UITimeText, false)) + if (CUIXmlInit::InitStatic(uiXml, "time_static", 0, &UITimeText, false)) AttachChild(&UITimeText); - if (CUIXmlInit::InitTextWnd(uiXml, "caption_static", 0, &UICaptionText, false)) + if (CUIXmlInit::InitStatic(uiXml, "caption_static", 0, &UICaptionText, false)) AttachChild(&UICaptionText); - if (CUIXmlInit::InitTextWnd(uiXml, "msg_static", 0, &UIMsgText, false) || - CUIXmlInit::InitTextWnd(uiXml, "text_static", 0, &UIMsgText, false)) + if (CUIXmlInit::InitStatic(uiXml, "msg_static", 0, &UIMsgText, false) || + CUIXmlInit::InitStatic(uiXml, "text_static", 0, &UIMsgText, false)) { AttachChild(&UIMsgText); } diff --git a/src/xrGame/ui/UIPdaMsgListItem.h b/src/xrGame/ui/UIPdaMsgListItem.h index 63ca09ea26e..e15ac85a622 100644 --- a/src/xrGame/ui/UIPdaMsgListItem.h +++ b/src/xrGame/ui/UIPdaMsgListItem.h @@ -18,8 +18,8 @@ class CUIPdaMsgListItem final : public CUIColorAnimConrollerContainer pcstr GetDebugType() override { return "CUIPdaMsgListItem"; } - CUIStatic UIIcon{ "Icon" }; - CUITextWnd UITimeText; - CUITextWnd UICaptionText; - CUITextWnd UIMsgText; + CUIStatic UIIcon { "Icon" }; + CUIStatic UITimeText { "Time text" }; + CUIStatic UICaptionText{ "Caption text" }; + CUIStatic UIMsgText { "Message text" }; }; diff --git a/src/xrGame/ui/UIPdaWnd.cpp b/src/xrGame/ui/UIPdaWnd.cpp index 2cd90634e02..95ea764824b 100644 --- a/src/xrGame/ui/UIPdaWnd.cpp +++ b/src/xrGame/ui/UIPdaWnd.cpp @@ -81,7 +81,7 @@ void CUIPdaWnd::Init() UIMainPdaFrame = UIHelper::CreateStatic(uiXml, "background_static", this); m_caption = UIHelper::CreateStatic(uiXml, "caption_static", this); m_caption_const = (m_caption->GetText()); - m_clock = UIHelper::CreateTextWnd(uiXml, "clock_wnd", this, false); + m_clock = UIHelper::CreateStatic(uiXml, "clock_wnd", this, false); if (uiXml.NavigateToNode("anim_static")) // XXX: Replace with UIHelper { @@ -201,8 +201,7 @@ void CUIPdaWnd::Update() if (m_clock) { - m_clock->TextItemControl().SetText( - GetGameTimeAsString(InventoryUtilities::etpTimeToMinutes).c_str()); + m_clock->SetText(GetGameTimeAsString(InventoryUtilities::etpTimeToMinutes).c_str()); } if (pUILogsWnd) diff --git a/src/xrGame/ui/UIPdaWnd.h b/src/xrGame/ui/UIPdaWnd.h index c77760ecec1..97df348816f 100644 --- a/src/xrGame/ui/UIPdaWnd.h +++ b/src/xrGame/ui/UIPdaWnd.h @@ -7,7 +7,6 @@ class CUIFrameLineWnd; class CUI3tButton; class CUITabControl; class CUIStatic; -class CUITextWnd; class CUIXml; class CUIFrameWindow; class UIHint; @@ -35,7 +34,7 @@ class CUIPdaWnd final : public CUIDialogWnd CUIStatic* m_caption; shared_str m_caption_const; CUIAnimatedStatic* m_anim_static; - CUITextWnd* m_clock; + CUIStatic* m_clock; // Текущий активный диалог CUIWindow* m_pActiveDialog; diff --git a/src/xrGame/ui/UIRankFaction.cpp b/src/xrGame/ui/UIRankFaction.cpp index 37583b954c3..e90767bdc41 100644 --- a/src/xrGame/ui/UIRankFaction.cpp +++ b/src/xrGame/ui/UIRankFaction.cpp @@ -85,14 +85,14 @@ void CUIRankFaction::init_from_xml(CUIXml& xml) { CUIXmlInit::InitWindow(xml, "fraction_stand_wnd", 0, this); - m_sn = UIHelper::CreateTextWnd(xml, "serial_number", this); - m_name = UIHelper::CreateTextWnd(xml, "name", this); + m_sn = UIHelper::CreateStatic(xml, "serial_number", this); + m_name = UIHelper::CreateStatic(xml, "name", this); m_icon = UIHelper::CreateStatic(xml, "icon", this); m_icon_over = UIHelper::CreateStatic(xml, "icon_over", this); - m_location_static = UIHelper::CreateTextWnd(xml, "location_static", this); - m_location_value = UIHelper::CreateTextWnd(xml, "location_value", this); - m_power_static = UIHelper::CreateTextWnd(xml, "power_static", this); - m_power_value = UIHelper::CreateTextWnd(xml, "power_value", this); + m_location_static = UIHelper::CreateStatic(xml, "location_static", this); + m_location_value = UIHelper::CreateStatic(xml, "location_value", this); + m_power_static = UIHelper::CreateStatic(xml, "power_static", this); + m_power_value = UIHelper::CreateStatic(xml, "power_value", this); m_relation_minus = UIHelper::CreateProgressBar(xml, "relation_minus", this); m_relation_center_minus = UIHelper::CreateProgressBar(xml, "relation_center_minus", this); @@ -102,8 +102,8 @@ void CUIRankFaction::init_from_xml(CUIXml& xml) m_origin_static = UIHelper::CreateStatic(xml, "origin_static", this); m_border_minus = UIHelper::CreateStatic(xml, "border_minus", this); m_border_plus = UIHelper::CreateStatic(xml, "border_plus", this); - m_enemy_static = UIHelper::CreateTextWnd(xml, "enemy_static", this); - m_frined_static = UIHelper::CreateTextWnd(xml, "frined_static", this); + m_enemy_static = UIHelper::CreateStatic(xml, "enemy_static", this); + m_frined_static = UIHelper::CreateStatic(xml, "frined_static", this); m_rating_up = UIHelper::CreateStatic(xml, "rating_up", this); m_rating_down = UIHelper::CreateStatic(xml, "rating_down", this); diff --git a/src/xrGame/ui/UIRankFaction.h b/src/xrGame/ui/UIRankFaction.h index c4dfc4d7cba..1997c591aa5 100644 --- a/src/xrGame/ui/UIRankFaction.h +++ b/src/xrGame/ui/UIRankFaction.h @@ -11,7 +11,6 @@ class CUIXml; class CUIStatic; -class CUITextWnd; class CUIProgressBar; class CActor; @@ -19,14 +18,14 @@ class CUIRankFaction final : public CUIWindow { FactionState m_faction_state; - CUITextWnd* m_sn; - CUITextWnd* m_name; + CUIStatic* m_sn; + CUIStatic* m_name; CUIStatic* m_icon; CUIStatic* m_icon_over; - CUITextWnd* m_location_static; - CUITextWnd* m_location_value; - CUITextWnd* m_power_static; - CUITextWnd* m_power_value; + CUIStatic* m_location_static; + CUIStatic* m_location_value; + CUIStatic* m_power_static; + CUIStatic* m_power_value; CUIProgressBar* m_relation_minus; CUIProgressBar* m_relation_center_minus; @@ -36,8 +35,8 @@ class CUIRankFaction final : public CUIWindow CUIStatic* m_origin_static; CUIStatic* m_border_minus; CUIStatic* m_border_plus; - CUITextWnd* m_enemy_static; - CUITextWnd* m_frined_static; + CUIStatic* m_enemy_static; + CUIStatic* m_frined_static; CUIStatic* m_rating_up; CUIStatic* m_rating_down; diff --git a/src/xrGame/ui/UIRankingWnd.cpp b/src/xrGame/ui/UIRankingWnd.cpp index 80a3df7154f..888cee11a17 100644 --- a/src/xrGame/ui/UIRankingWnd.cpp +++ b/src/xrGame/ui/UIRankingWnd.cpp @@ -105,15 +105,15 @@ bool CUIRankingWnd::Init() m_actor_ch_info->InitCharacterInfo(&xml, "actor_ch_info"); m_icon_overlay = UIHelper::CreateFrameWindow(xml, "actor_icon_over", this, false); - m_money_caption = UIHelper::CreateTextWnd(xml, "money_caption", this); - m_money_value = UIHelper::CreateTextWnd(xml, "money_value", this); + m_money_caption = UIHelper::CreateStatic(xml, "money_caption", this); + m_money_value = UIHelper::CreateStatic(xml, "money_value", this); m_money_caption->AdjustWidthToText(); pos = m_money_caption->GetWndPos(); pos.x += m_money_caption->GetWndSize().x + 10.0f; m_money_value->SetWndPos(pos); - m_center_caption = UIHelper::CreateTextWnd(xml, "center_caption", this); + m_center_caption = UIHelper::CreateStatic(xml, "center_caption", this); m_faction_static = UIHelper::CreateStatic(xml, "fraction_static", this, false); m_faction_line1 = UIHelper::CreateFrameLine(xml, "fraction_line1", this, false); m_faction_line2 = UIHelper::CreateFrameLine(xml, "fraction_line2", this, false); @@ -127,16 +127,16 @@ bool CUIRankingWnd::Init() for (u8 i = 0; i < m_stat_count; ++i) { - m_stat_caption[i] = xr_new(); + m_stat_caption[i] = xr_new("Caption"); AttachChild(m_stat_caption[i]); m_stat_caption[i]->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(xml, "stat", i, m_stat_caption[i]); + CUIXmlInit::InitStatic(xml, "stat", i, m_stat_caption[i]); m_stat_caption[i]->AdjustWidthToText(); - m_stat_info[i] = xr_new(); + m_stat_info[i] = xr_new("Info"); AttachChild(m_stat_info[i]); m_stat_info[i]->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(xml, "stat", i, m_stat_info[i]); + CUIXmlInit::InitStatic(xml, "stat", i, m_stat_info[i]); m_stat_info[i]->SetTextColor(value_color); diff --git a/src/xrGame/ui/UIRankingWnd.h b/src/xrGame/ui/UIRankingWnd.h index 32749d43b83..7774761c820 100644 --- a/src/xrGame/ui/UIRankingWnd.h +++ b/src/xrGame/ui/UIRankingWnd.h @@ -31,10 +31,10 @@ class CUIRankingWnd final : public CUIWindow, public CUIWndCallback CUICharacterInfo* m_actor_ch_info; - CUITextWnd* m_money_caption; - CUITextWnd* m_money_value; + CUIStatic* m_money_caption; + CUIStatic* m_money_value; - CUITextWnd* m_center_caption; + CUIStatic* m_center_caption; CUIStatic* m_faction_static; CUIFrameLineWnd* m_faction_line1; CUIFrameLineWnd* m_faction_line2; @@ -59,8 +59,8 @@ class CUIRankingWnd final : public CUIWindow, public CUIWndCallback { max_stat_info = 15 }; - CUITextWnd* m_stat_caption[max_stat_info]; - CUITextWnd* m_stat_info[max_stat_info]; + CUIStatic* m_stat_caption[max_stat_info]; + CUIStatic* m_stat_info[max_stat_info]; u32 m_delay; u32 m_previous_time; diff --git a/src/xrGame/ui/UIServerInfo.cpp b/src/xrGame/ui/UIServerInfo.cpp index eec10d10ef0..bd755bf5f05 100644 --- a/src/xrGame/ui/UIServerInfo.cpp +++ b/src/xrGame/ui/UIServerInfo.cpp @@ -35,7 +35,7 @@ CUIServerInfo::CUIServerInfo() AttachChild(m_text_desc); m_text_desc->SetAutoDelete(true); - m_text_body = xr_new(); + m_text_body = xr_new("Text body"); // m_text_desc->AttachChild (m_text_body); // m_text_body->SetAutoDelete (true); @@ -63,7 +63,7 @@ void CUIServerInfo::Init() CUIXmlInit::InitScrollView(xml_doc, "server_info:text_desc", 0, m_text_desc); CUIXmlInit::InitStatic(xml_doc, "server_info:image", 0, m_image); - CUIXmlInit::InitTextWnd(xml_doc, "server_info:text_body", 0, m_text_body); + CUIXmlInit::InitStatic(xml_doc, "server_info:text_body", 0, m_text_body); m_text_body->SetTextComplexMode(true); m_text_body->SetWidth(m_text_desc->GetDesiredChildWidth()); m_text_desc->AddWindow(m_text_body, true); diff --git a/src/xrGame/ui/UIServerInfo.h b/src/xrGame/ui/UIServerInfo.h index 606342d214c..3c25bc8ef6b 100644 --- a/src/xrGame/ui/UIServerInfo.h +++ b/src/xrGame/ui/UIServerInfo.h @@ -7,8 +7,6 @@ class CUIStatic; class CUIScrollView; class CUI3tButton; -class CUI3tButton; -class CUITextWnd; class CUIServerInfo final : public CUIDialogWnd, public CUIWndCallback { @@ -37,7 +35,7 @@ class CUIServerInfo final : public CUIDialogWnd, public CUIWndCallback CUIStatic* m_caption; CUIStatic* m_background; CUIScrollView* m_text_desc; - CUITextWnd* m_text_body; + CUIStatic* m_text_body; CUIStatic* m_image; CUI3tButton* m_btn_spectator; CUI3tButton* m_btn_next; diff --git a/src/xrGame/ui/UISpeechMenu.cpp b/src/xrGame/ui/UISpeechMenu.cpp index 376f5de83b9..8c4cb8db0a5 100644 --- a/src/xrGame/ui/UISpeechMenu.cpp +++ b/src/xrGame/ui/UISpeechMenu.cpp @@ -26,7 +26,6 @@ CUISpeechMenu::CUISpeechMenu(LPCSTR section_name) void CUISpeechMenu::InitList(LPCSTR section_name) { R_ASSERT2(pSettings->section_exist(section_name), section_name); - CUITextWnd* pItem = NULL; string64 phrase; string256 str; @@ -39,6 +38,7 @@ void CUISpeechMenu::InitList(LPCSTR section_name) _GetItem(s, 0, phrase); xr_sprintf(str, "%d. %s", i + 1, StringTable().translate(phrase).c_str()); + CUIStatic* pItem{}; ADD_TEXT_TO_VIEW3(str, pItem, m_pList); pItem->SetFont(m_pFont); pItem->SetTextColor(m_text_color); diff --git a/src/xrGame/ui/UIStatsPlayerList.cpp b/src/xrGame/ui/UIStatsPlayerList.cpp index 0a76b2d766a..06d72e00391 100644 --- a/src/xrGame/ui/UIStatsPlayerList.cpp +++ b/src/xrGame/ui/UIStatsPlayerList.cpp @@ -122,7 +122,7 @@ void CUIStatsPlayerList::InitHeader(CUIXml& xml_doc, LPCSTR path) { for (u32 i = 0; i < m_field_info.size(); ++i) { - CUITextWnd* st = xr_new(); + auto* st = xr_new("Field"); st->SetAutoDelete(true); st->SetWndPos(Fvector2().set(indent, 10.0f)); st->SetWndSize(Fvector2().set(m_field_info[i].width, m_header->GetHeight())); @@ -148,7 +148,7 @@ void CUIStatsPlayerList::InitHeader(CUIXml& xml_doc, LPCSTR path) } else { - CUITextWnd* st = xr_new(); + auto* st = xr_new("Field"); st->SetAutoDelete(true); st->SetWndPos(Fvector2().set(10, 0)); st->SetWndSize(Fvector2().set(this->GetDesiredChildWidth(), m_h.h)); @@ -187,9 +187,9 @@ void CUIStatsPlayerList::InitTeamHeader(CUIXml& xml_doc, LPCSTR path) CUIXmlInit::InitFont(xml_doc, strconcat(sizeof(_path), _path, path, ":team_header:text_format"), 0, t.c, t.f); t.h = m_header_team->GetHeight(); - m_header_text = xr_new(); + m_header_text = xr_new("Header"); m_header_text->SetAutoDelete(true); - CUIXmlInit::InitTextWnd(xml_doc, strconcat(sizeof(_path), _path, path, ":team_header:header"), 0, m_header_text); + CUIXmlInit::InitStatic(xml_doc, strconcat(sizeof(_path), _path, path, ":team_header:header"), 0, m_header_text); m_header_text->SetWidth(GetDesiredChildWidth()); m_header_text->SetVTextAlignment(valCenter); m_header_team->AttachChild(m_header_text); diff --git a/src/xrGame/ui/UIStatsPlayerList.h b/src/xrGame/ui/UIStatsPlayerList.h index 94fe5c0ffa1..ba2fd3fee33 100644 --- a/src/xrGame/ui/UIStatsPlayerList.h +++ b/src/xrGame/ui/UIStatsPlayerList.h @@ -4,7 +4,7 @@ #include "UIStatsPlayerInfo.h" class CUIXml; -class CUITextWnd; +class CUIStatic; typedef bool (*player_cmp_func)(LPVOID v1, LPVOID v2); @@ -42,7 +42,7 @@ class CUIStatsPlayerList final : public CUIScrollView CUIStatic* m_header; CUIWindow* m_header_team; - CUITextWnd* m_header_text; + CUIStatic* m_header_text; u32 m_prev_upd_time; typedef struct diff --git a/src/xrGame/ui/UITalkDialogWnd.cpp b/src/xrGame/ui/UITalkDialogWnd.cpp index ecc535c22f5..aaf15cc5c06 100644 --- a/src/xrGame/ui/UITalkDialogWnd.cpp +++ b/src/xrGame/ui/UITalkDialogWnd.cpp @@ -15,7 +15,6 @@ #include "alife_registry_wrappers.h" #include "UIHelper.h" - CUITalkDialogWnd::CUITalkDialogWnd() : CUIWindow("CUITalkDialogWnd"), m_uiXml(nullptr), @@ -363,7 +362,7 @@ CUIQuestionItem::CUIQuestionItem(CUIXml* xml_doc, LPCSTR path) AddCallback(m_text, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUIQuestionItem::OnTextClicked)); strconcat(sizeof(str), str, path, ":num_text"); - m_num_text = UIHelper::CreateTextWnd(*xml_doc, str, this, false); + m_num_text = UIHelper::CreateStatic(*xml_doc, str, this, false); } void CUIQuestionItem::Init(LPCSTR val, LPCSTR text) @@ -391,10 +390,10 @@ CUIAnswerItem::CUIAnswerItem(CUIXml* xml_doc, LPCSTR path) string512 str; strconcat(sizeof(str), str, path, ":content_text"); - m_text = UIHelper::CreateTextWnd(*xml_doc, str, this); + m_text = UIHelper::CreateStatic(*xml_doc, str, this); strconcat(sizeof(str), str, path, ":name_caption"); - m_name = UIHelper::CreateTextWnd(*xml_doc, str, this); + m_name = UIHelper::CreateStatic(*xml_doc, str, this); SetAutoDelete(true); } diff --git a/src/xrGame/ui/UITalkDialogWnd.h b/src/xrGame/ui/UITalkDialogWnd.h index 93c2ddaa1e6..32111499ef4 100644 --- a/src/xrGame/ui/UITalkDialogWnd.h +++ b/src/xrGame/ui/UITalkDialogWnd.h @@ -94,7 +94,7 @@ class CUIQuestionItem final : public CUIWindow, public CUIWndCallback float m_min_height; public: - CUITextWnd* m_num_text; + CUIStatic* m_num_text; CUI3tButton* m_text; shared_str m_s_value; CUIQuestionItem(CUIXml* xml_doc, LPCSTR path); @@ -112,8 +112,8 @@ class CUIAnswerItem: public CUIWindow float m_min_height; float m_bottom_footer; - CUITextWnd* m_text; - CUITextWnd* m_name; + CUIStatic* m_text; + CUIStatic* m_name; public: CUIAnswerItem(CUIXml* xml_doc, LPCSTR path); diff --git a/src/xrGame/ui/UITradeBar.cpp b/src/xrGame/ui/UITradeBar.cpp index 9e973619f40..ad05147db65 100644 --- a/src/xrGame/ui/UITradeBar.cpp +++ b/src/xrGame/ui/UITradeBar.cpp @@ -12,12 +12,12 @@ void CUITradeBar::init_from_xml(CUIXml& uiXml, pcstr path) if (!CallOfPripyatMode) { - CUITextWnd* m_TradeCaption = UIHelper::CreateTextWnd(uiXml, "trade_caption", this, false); + m_TradeCaption = UIHelper::CreateStatic(uiXml, "trade_caption", this, false); if (m_TradeCaption) m_TradeCaption->AdjustWidthToText(); } - m_TradePrice = UIHelper::CreateTextWnd(uiXml, "trade_price", this); - m_TradeWeightMax = UIHelper::CreateTextWnd(uiXml, "trade_weight_max", this); + m_TradePrice = UIHelper::CreateStatic(uiXml, "trade_price", this); + m_TradeWeightMax = UIHelper::CreateStatic(uiXml, "trade_weight_max", this); uiXml.SetLocalRoot(stored_root); } diff --git a/src/xrGame/ui/UITradeBar.h b/src/xrGame/ui/UITradeBar.h index 554a293ab5d..952827e7651 100644 --- a/src/xrGame/ui/UITradeBar.h +++ b/src/xrGame/ui/UITradeBar.h @@ -2,9 +2,9 @@ class CUITradeBar final : public CUIStatic { - CUITextWnd* m_TradeCaption{}; - CUITextWnd* m_TradePrice{}; - CUITextWnd* m_TradeWeightMax{}; + CUIStatic* m_TradeCaption{}; + CUIStatic* m_TradePrice{}; + CUIStatic* m_TradeWeightMax{}; public: CUITradeBar() : CUIStatic("Trade Bar") {} diff --git a/src/xrGame/ui/UIVote.cpp b/src/xrGame/ui/UIVote.cpp index e30f88c8a06..fbe80d1e463 100644 --- a/src/xrGame/ui/UIVote.cpp +++ b/src/xrGame/ui/UIVote.cpp @@ -16,13 +16,13 @@ CUIVote::CUIVote() : CUIDialogWnd(CUIVote::GetDebugType()) bkgrnd = xr_new("Background"); bkgrnd->SetAutoDelete(true); AttachChild(bkgrnd); - msg = xr_new(); + msg = xr_new("Message"); msg->SetAutoDelete(true); AttachChild(msg); for (int i = 0; i < 3; i++) { - cap[i] = xr_new(); + cap[i] = xr_new("Caption"); cap[i]->SetAutoDelete(true); AttachChild(cap[i]); // frame[i] = new CUIFrameWindow(); frame[i]->SetAutoDelete(true); AttachChild(frame[i]); @@ -50,14 +50,14 @@ void CUIVote::Init() xml_doc.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "voting_category.xml"); CUIXmlInit::InitWindow(xml_doc, "vote", 0, this); CUIXmlInit::InitStatic(xml_doc, "vote:background", 0, bkgrnd); - CUIXmlInit::InitTextWnd(xml_doc, "vote:msg", 0, msg); + CUIXmlInit::InitStatic(xml_doc, "vote:msg", 0, msg); string256 path; for (int i = 0; i < 3; i++) { xr_sprintf(path, "vote:list_cap_%d", i + 1); - CUIXmlInit::InitTextWnd(xml_doc, path, 0, cap[i]); + CUIXmlInit::InitStatic(xml_doc, path, 0, cap[i]); // xr_sprintf (path, "vote:list_back_%d", i+1); // CUIXmlInit::InitFrameWindow (xml_doc, path, 0, frame[i]); xr_sprintf(path, "vote:list_%d", i + 1); diff --git a/src/xrGame/ui/UIVote.h b/src/xrGame/ui/UIVote.h index a2651968fdf..50bd633b694 100644 --- a/src/xrGame/ui/UIVote.h +++ b/src/xrGame/ui/UIVote.h @@ -3,7 +3,6 @@ #include "UIDialogWnd.h" class CUIStatic; -class CUITextWnd; class CUI3tButton; class CUIListBox; class CUIFrameWindow; @@ -24,8 +23,8 @@ class CUIVote final : public CUIDialogWnd pcstr GetDebugType() override { return "CUIVote"; } protected: - CUITextWnd* msg; - CUITextWnd* cap[3]; + CUIStatic* msg; + CUIStatic* cap[3]; CUIFrameWindow* frame[3]; CUIListBox* list[3]; diff --git a/src/xrGame/ui/UIVoteStatusWnd.cpp b/src/xrGame/ui/UIVoteStatusWnd.cpp index be6f33cc020..d7c9cc8b1cd 100644 --- a/src/xrGame/ui/UIVoteStatusWnd.cpp +++ b/src/xrGame/ui/UIVoteStatusWnd.cpp @@ -5,20 +5,20 @@ void UIVoteStatusWnd::InitFromXML(CUIXml& xml_doc) { - m_str_message = xr_new(); + m_str_message = xr_new("Message"); m_str_message->SetAutoDelete(true); AttachChild(m_str_message); - m_hint = xr_new(); + m_hint = xr_new("Hint"); m_hint->SetAutoDelete(true); AttachChild(m_hint); - m_time_message = xr_new(); + m_time_message = xr_new("Time message"); m_time_message->SetAutoDelete(true); AttachChild(m_time_message); CUIXmlInit::InitFrameWindow(xml_doc, "vote_wnd", 0, this); - CUIXmlInit::InitTextWnd(xml_doc, "vote_wnd:static_str_message", 0, m_str_message); - CUIXmlInit::InitTextWnd(xml_doc, "vote_wnd:static_hint", 0, m_hint); - CUIXmlInit::InitTextWnd(xml_doc, "vote_wnd:static_time_message", 0, m_time_message); + CUIXmlInit::InitStatic(xml_doc, "vote_wnd:static_str_message", 0, m_str_message); + CUIXmlInit::InitStatic(xml_doc, "vote_wnd:static_hint", 0, m_hint); + CUIXmlInit::InitStatic(xml_doc, "vote_wnd:static_time_message", 0, m_time_message); } void UIVoteStatusWnd::SetVoteTimeResultMsg(LPCSTR s) { m_time_message->SetText(s); } diff --git a/src/xrGame/ui/UIVoteStatusWnd.h b/src/xrGame/ui/UIVoteStatusWnd.h index 615da051b4a..409cf6aaabb 100644 --- a/src/xrGame/ui/UIVoteStatusWnd.h +++ b/src/xrGame/ui/UIVoteStatusWnd.h @@ -2,13 +2,13 @@ #include "xrUICore/Windows/UIFrameWindow.h" class CUIXml; -class CUITextWnd; +class CUIStatic; class UIVoteStatusWnd final : public CUIFrameWindow { - CUITextWnd* m_str_message{}; - CUITextWnd* m_hint{}; - CUITextWnd* m_time_message{}; + CUIStatic* m_str_message{}; + CUIStatic* m_hint{}; + CUIStatic* m_time_message{}; public: UIVoteStatusWnd() : CUIFrameWindow(UIVoteStatusWnd::GetDebugType()) {} diff --git a/src/xrGame/ui/UIWeightBar.cpp b/src/xrGame/ui/UIWeightBar.cpp index 691929b8258..89eb6a4414f 100644 --- a/src/xrGame/ui/UIWeightBar.cpp +++ b/src/xrGame/ui/UIWeightBar.cpp @@ -11,12 +11,12 @@ void CUIWeightBar::init_from_xml(CUIXml& uiXml, pcstr path) m_BottomInfo = UIHelper::CreateStatic(uiXml, buf, this); xr_sprintf(buf, "%s_weight", path); - m_Weight = UIHelper::CreateTextWnd(uiXml, buf, this); + m_Weight = UIHelper::CreateStatic(uiXml, buf, this); xr_sprintf(buf, "%s_weight_max", path); - m_WeightMax = UIHelper::CreateTextWnd(uiXml, buf, this, false); + m_WeightMax = UIHelper::CreateStatic(uiXml, buf, this, false); { - CUITextWnd* weightLabel = m_WeightMax ? m_WeightMax : m_Weight; + const auto* weightLabel = m_WeightMax ? m_WeightMax : m_Weight; m_Weight_end_x = weightLabel->GetWndPos().x; } m_BottomInfo->AdjustWidthToText(); diff --git a/src/xrGame/ui/UIWeightBar.h b/src/xrGame/ui/UIWeightBar.h index 837692a5ad9..f764eda502f 100644 --- a/src/xrGame/ui/UIWeightBar.h +++ b/src/xrGame/ui/UIWeightBar.h @@ -3,8 +3,8 @@ class CUIWeightBar final : public CUIWindow { CUIStatic* m_BottomInfo{}; - CUITextWnd* m_Weight{}; - CUITextWnd* m_WeightMax{}; + CUIStatic* m_Weight{}; + CUIStatic* m_WeightMax{}; float m_Weight_end_x{}; public: diff --git a/src/xrGame/ui/UIWpnParams.cpp b/src/xrGame/ui/UIWpnParams.cpp index 8e7e763fb8b..82ea67046f5 100644 --- a/src/xrGame/ui/UIWpnParams.cpp +++ b/src/xrGame/ui/UIWpnParams.cpp @@ -69,10 +69,10 @@ bool CUIWpnParams::InitFromXml(CUIXml& xml_doc) m_icon_han = UIHelper::CreateStatic(xml_doc, "wpn_params:static_handling", this, false); m_icon_rpm = UIHelper::CreateStatic(xml_doc, "wpn_params:static_rpm", this, false); - CUIXmlInit::InitTextWnd(xml_doc, "wpn_params:cap_accuracy", 0, &m_textAccuracy); - CUIXmlInit::InitTextWnd(xml_doc, "wpn_params:cap_damage", 0, &m_textDamage); - CUIXmlInit::InitTextWnd(xml_doc, "wpn_params:cap_handling", 0, &m_textHandling); - CUIXmlInit::InitTextWnd(xml_doc, "wpn_params:cap_rpm", 0, &m_textRPM); + CUIXmlInit::InitStatic(xml_doc, "wpn_params:cap_accuracy", 0, &m_textAccuracy); + CUIXmlInit::InitStatic(xml_doc, "wpn_params:cap_damage", 0, &m_textDamage); + CUIXmlInit::InitStatic(xml_doc, "wpn_params:cap_handling", 0, &m_textHandling); + CUIXmlInit::InitStatic(xml_doc, "wpn_params:cap_rpm", 0, &m_textRPM); m_progressAccuracy.InitFromXml(xml_doc, "wpn_params:progress_accuracy"); m_progressDamage.InitFromXml(xml_doc, "wpn_params:progress_damage"); @@ -82,10 +82,10 @@ bool CUIWpnParams::InitFromXml(CUIXml& xml_doc) if (IsGameTypeSingle()) { m_stAmmo = UIHelper::CreateStatic(xml_doc, "wpn_params:static_ammo", this, false); - m_textAmmoCount = UIHelper::CreateTextWnd(xml_doc, "wpn_params:cap_ammo_count", this, false); - m_textAmmoCount2 = UIHelper::CreateTextWnd(xml_doc, "wpn_params:cap_ammo_count2", this, false); - m_textAmmoTypes = UIHelper::CreateTextWnd(xml_doc, "wpn_params:cap_ammo_types", this, false); - m_textAmmoUsedType = UIHelper::CreateTextWnd(xml_doc, "wpn_params:cap_ammo_used_type", this, false); + m_textAmmoCount = UIHelper::CreateStatic(xml_doc, "wpn_params:cap_ammo_count", this, false); + m_textAmmoCount2 = UIHelper::CreateStatic(xml_doc, "wpn_params:cap_ammo_count2", this, false); + m_textAmmoTypes = UIHelper::CreateStatic(xml_doc, "wpn_params:cap_ammo_types", this, false); + m_textAmmoUsedType = UIHelper::CreateStatic(xml_doc, "wpn_params:cap_ammo_used_type", this, false); m_stAmmoType1 = UIHelper::CreateStatic(xml_doc, "wpn_params:static_ammo_type1", this, false); m_stAmmoType2 = UIHelper::CreateStatic(xml_doc, "wpn_params:static_ammo_type2", this, false); } diff --git a/src/xrGame/ui/UIWpnParams.h b/src/xrGame/ui/UIWpnParams.h index 020d398fa53..a97bc67a829 100644 --- a/src/xrGame/ui/UIWpnParams.h +++ b/src/xrGame/ui/UIWpnParams.h @@ -30,14 +30,14 @@ class CUIWpnParams final : public CUIWindow CUIStatic* m_icon_rpm; CUIStatic* m_stAmmo; - CUITextWnd m_textAccuracy; - CUITextWnd m_textHandling; - CUITextWnd m_textDamage; - CUITextWnd m_textRPM; - CUITextWnd* m_textAmmoTypes; - CUITextWnd* m_textAmmoUsedType; - CUITextWnd* m_textAmmoCount; - CUITextWnd* m_textAmmoCount2; + CUIStatic m_textAccuracy{ "Accuracy" }; + CUIStatic m_textHandling{ "Handling" }; + CUIStatic m_textDamage{ "Damage" }; + CUIStatic m_textRPM{ "RPM" }; + CUIStatic* m_textAmmoTypes; + CUIStatic* m_textAmmoUsedType; + CUIStatic* m_textAmmoCount; + CUIStatic* m_textAmmoCount2; CUIStatic* m_stAmmoType1; CUIStatic* m_stAmmoType2; CUIStatic* m_Prop_line; diff --git a/src/xrGame/ui/map_hint.h b/src/xrGame/ui/map_hint.h index b38507a4154..b4ccc11fe4c 100644 --- a/src/xrGame/ui/map_hint.h +++ b/src/xrGame/ui/map_hint.h @@ -3,7 +3,6 @@ #include "xrCore/Containers/AssociativeVector.hpp" class CUIStatic; -class CUITextWnd; class CUIXml; class CGameTask; class CMapSpot; diff --git a/src/xrGame/ui/ui_af_params.cpp b/src/xrGame/ui/ui_af_params.cpp index 87640371df4..57593b770aa 100644 --- a/src/xrGame/ui/ui_af_params.cpp +++ b/src/xrGame/ui/ui_af_params.cpp @@ -212,7 +212,7 @@ UIArtefactParamItem::InitResult UIArtefactParamItem::Init(CUIXml& xml, pcstr sec xml.SetLocalRoot(xml.NavigateToNode(section)); m_caption = UIHelper::CreateStatic(xml, "caption", this); - m_value = UIHelper::CreateTextWnd(xml, "value", this); + m_value = UIHelper::CreateStatic(xml, "value", this); m_magnitude = xml.ReadAttribFlt("value", 0, "magnitude", 1.0f); m_sign_inverse = (xml.ReadAttribInt("value", 0, "sign_inverse", 0) == 1); @@ -244,7 +244,7 @@ UIArtefactParamItem::InitResult UIArtefactParamItem::InitPlain(CUIXml& xml, pcst AttachChild(m_caption); m_caption->Show(false); // hack - m_value = xr_new(); + m_value = xr_new("Value"); m_value->SetAutoDelete(true); AttachChild(m_value); m_value->Show(false); // hack diff --git a/src/xrGame/ui/ui_af_params.h b/src/xrGame/ui/ui_af_params.h index cfa714d3b4c..9b7c9fe1c38 100644 --- a/src/xrGame/ui/ui_af_params.h +++ b/src/xrGame/ui/ui_af_params.h @@ -4,7 +4,6 @@ class CUIXml; class CUIStatic; -class CUITextWnd; class UIArtefactParamItem; class CUIArtefactParams final : public CUIWindow @@ -61,7 +60,7 @@ class UIArtefactParamItem final : public CUIStatic private: CUIStatic* m_caption{}; - CUITextWnd* m_value{}; + CUIStatic* m_value{}; float m_magnitude; bool m_sign_inverse; shared_str m_unit_str; diff --git a/src/xrUICore/Buttons/UIBtnHint.cpp b/src/xrUICore/Buttons/UIBtnHint.cpp index 14c07a5dfec..f4a02a9001f 100644 --- a/src/xrUICore/Buttons/UIBtnHint.cpp +++ b/src/xrUICore/Buttons/UIBtnHint.cpp @@ -15,13 +15,12 @@ CUIButtonHint::CUIButtonHint() uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "hint_item.xml"); CUIXmlInitBase::InitFrameWindow(uiXml, "button_hint", 0, this); - m_text = xr_new(); + m_text = xr_new("Text"); m_text->SetAutoDelete(true); CUIWindow::AttachChild(m_text); - CUIXmlInitBase::InitTextWnd(uiXml, "button_hint:description", 0, m_text); + CUIXmlInitBase::InitStatic(uiXml, "button_hint:description", 0, m_text); } - void CUIButtonHint::OnRender() { if (m_enabledOnFrame) diff --git a/src/xrUICore/Buttons/UIBtnHint.h b/src/xrUICore/Buttons/UIBtnHint.h index d5aee5350ba..8e1b8f0a52f 100644 --- a/src/xrUICore/Buttons/UIBtnHint.h +++ b/src/xrUICore/Buttons/UIBtnHint.h @@ -1,13 +1,13 @@ #pragma once #include "xrUICore/Windows/UIFrameWindow.h" -class CUITextWnd; +class CUIStatic; class XRUICORE_API CUIButtonHint final : public CUIFrameWindow { CUIWindow* m_ownerWnd; - CUITextWnd* m_text; + CUIStatic* m_text; bool m_enabledOnFrame; public: diff --git a/src/xrUICore/ComboBox/UIComboBox.h b/src/xrUICore/ComboBox/UIComboBox.h index a4cabb4cf99..8d5524d65d7 100644 --- a/src/xrUICore/ComboBox/UIComboBox.h +++ b/src/xrUICore/ComboBox/UIComboBox.h @@ -68,7 +68,7 @@ class XRUICORE_API CUIComboBox final : public CUIWindow, public CUIOptionsItem, int m_opt_backup_value; CUI_IB_FrameLineWnd m_frameLine; - CUITextWnd m_text; + CUIStatic m_text{ "Text" }; CUIFrameWindow m_list_frame{ "List frame" }; u32 m_textColor[2]; diff --git a/src/xrUICore/Hint/UIHint.cpp b/src/xrUICore/Hint/UIHint.cpp index cad40ef8651..f2b83134269 100644 --- a/src/xrUICore/Hint/UIHint.cpp +++ b/src/xrUICore/Hint/UIHint.cpp @@ -31,10 +31,10 @@ void UIHint::init_from_xml(CUIXml& xml, LPCSTR path) m_background->SetAutoDelete(true); CUIXmlInitBase::InitFrameWindow(xml, "background", 0, m_background); - m_text = xr_new(); + m_text = xr_new("Text"); AttachChild(m_text); m_text->SetAutoDelete(true); - CUIXmlInitBase::InitTextWnd(xml, "text", 0, m_text); + CUIXmlInitBase::InitStatic(xml, "text", 0, m_text); m_border = xml.ReadAttribFlt("background", 0, "border", 0.0f); diff --git a/src/xrUICore/Hint/UIHint.h b/src/xrUICore/Hint/UIHint.h index 44fb62166c3..9fc234c154e 100644 --- a/src/xrUICore/Hint/UIHint.h +++ b/src/xrUICore/Hint/UIHint.h @@ -11,7 +11,6 @@ #include "xrUICore/Windows/UIWindow.h" class CUIStatic; -class CUITextWnd; class CUIFrameWindow; class CUIXml; @@ -39,7 +38,7 @@ class XRUICORE_API UIHint final : public CUIWindow protected: CUIFrameWindow* m_background; - CUITextWnd* m_text; + CUIStatic* m_text; bool m_visible; float m_border; diff --git a/src/xrUICore/ListBox/UIListBoxItem.cpp b/src/xrUICore/ListBox/UIListBoxItem.cpp index 45a485a4cc7..e18d5a81e28 100644 --- a/src/xrUICore/ListBox/UIListBoxItem.cpp +++ b/src/xrUICore/ListBox/UIListBoxItem.cpp @@ -76,9 +76,9 @@ CUIStatic* CUIListBoxItem::AddIconField(float width) return st; } -CUITextWnd* CUIListBoxItem::AddTextField(LPCSTR txt, float width) +CUIStatic* CUIListBoxItem::AddTextField(LPCSTR txt, float width) { - CUITextWnd* st = xr_new(); + auto* st = xr_new("Text field"); st->SetAutoDelete(true); st->SetWndPos(Fvector2().set(FieldsLength(), 0.0f)); st->SetWndSize(Fvector2().set(width, GetHeight())); diff --git a/src/xrUICore/ListBox/UIListBoxItem.h b/src/xrUICore/ListBox/UIListBoxItem.h index bf38867260b..9cd36abb7dd 100644 --- a/src/xrUICore/ListBox/UIListBoxItem.h +++ b/src/xrUICore/ListBox/UIListBoxItem.h @@ -1,7 +1,6 @@ #pragma once #include "xrUICore/Windows/UIFrameLineWnd.h" -class CUITextWnd; class CUIStatic; class XRUICORE_API CUIListBoxItem : public CUIFrameLineWnd, public CUISelectable @@ -21,10 +20,10 @@ class XRUICORE_API CUIListBoxItem : public CUIFrameLineWnd, public CUISelectable void SetData(void* data); void* GetData(); - CUITextWnd* AddTextField(LPCSTR txt, float width); + CUIStatic* AddTextField(LPCSTR txt, float width); CUIStatic* AddIconField(float width); - CUITextWnd* GetTextItem() { return m_text; } + CUIStatic* GetTextItem() const { return m_text; } // TextControl void SetText(LPCSTR txt); LPCSTR GetText(); @@ -36,7 +35,7 @@ class XRUICORE_API CUIListBoxItem : public CUIFrameLineWnd, public CUISelectable pcstr GetDebugType() override { return "CUIListBoxItem"; } protected: - CUITextWnd* m_text; + CUIStatic* m_text; u32 tag; void* pData; float FieldsLength() const; diff --git a/src/xrUICore/MessageBox/UIMessageBox.cpp b/src/xrUICore/MessageBox/UIMessageBox.cpp index 196331f22c9..f9a76a5a24f 100644 --- a/src/xrUICore/MessageBox/UIMessageBox.cpp +++ b/src/xrUICore/MessageBox/UIMessageBox.cpp @@ -149,9 +149,9 @@ bool CUIMessageBox::InitMessageBox(LPCSTR box_template) strconcat(sizeof(str), str, box_template, ":message_text"); if (uiXml.NavigateToNode(str, 0)) { - m_UIStaticText = xr_new(); + m_UIStaticText = xr_new("Text"); AttachChild(m_UIStaticText); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticText); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticText); } xr_strcpy(str, box_template); @@ -221,9 +221,9 @@ bool CUIMessageBox::InitMessageBox(LPCSTR box_template) case MESSAGEBOX_DIRECT_IP: strconcat(sizeof(str), str, box_template, ":cap_host"); - m_UIStaticHost = xr_new(); + m_UIStaticHost = xr_new("Host"); AttachChild(m_UIStaticHost); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticHost); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticHost); strconcat(sizeof(str), str, box_template, ":edit_host"); m_UIEditHost = xr_new(); @@ -231,9 +231,9 @@ bool CUIMessageBox::InitMessageBox(LPCSTR box_template) CUIXmlInitBase::InitEditBox(uiXml, str, 0, m_UIEditHost); strconcat(sizeof(str), str, box_template, ":cap_password"); - m_UIStaticPass = xr_new(); + m_UIStaticPass = xr_new("Password"); AttachChild(m_UIStaticPass); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticPass); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticPass); strconcat(sizeof(str), str, box_template, ":edit_password"); m_UIEditPass = xr_new(); @@ -255,14 +255,14 @@ bool CUIMessageBox::InitMessageBox(LPCSTR box_template) case MESSAGEBOX_PASSWORD: { strconcat(sizeof(str), str, box_template, ":cap_user_password"); - m_UIStaticUserPass = xr_new(); + m_UIStaticUserPass = xr_new("User password"); AttachChild(m_UIStaticUserPass); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticUserPass); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticUserPass); strconcat(sizeof(str), str, box_template, ":cap_password"); - m_UIStaticPass = xr_new(); + m_UIStaticPass = xr_new("Password"); AttachChild(m_UIStaticPass); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticPass); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticPass); strconcat(sizeof(str), str, box_template, ":edit_user_password"); m_UIEditUserPass = xr_new(); @@ -288,14 +288,14 @@ bool CUIMessageBox::InitMessageBox(LPCSTR box_template) case MESSAGEBOX_RA_LOGIN: strconcat(sizeof(str), str, box_template, ":cap_login"); - m_UIStaticUserPass = xr_new(); + m_UIStaticUserPass = xr_new("Login"); AttachChild(m_UIStaticUserPass); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticUserPass); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticUserPass); strconcat(sizeof(str), str, box_template, ":cap_password"); - m_UIStaticPass = xr_new(); + m_UIStaticPass = xr_new("Password"); AttachChild(m_UIStaticPass); - CUIXmlInitBase::InitTextWnd(uiXml, str, 0, m_UIStaticPass); + CUIXmlInitBase::InitStatic(uiXml, str, 0, m_UIStaticPass); strconcat(sizeof(str), str, box_template, ":edit_login"); m_UIEditUserPass = xr_new(); diff --git a/src/xrUICore/MessageBox/UIMessageBox.h b/src/xrUICore/MessageBox/UIMessageBox.h index a8903356a94..95f72c77417 100644 --- a/src/xrUICore/MessageBox/UIMessageBox.h +++ b/src/xrUICore/MessageBox/UIMessageBox.h @@ -60,10 +60,10 @@ class XRUICORE_API CUIMessageBox final : public CUIStatic CUI3tButton* m_UIButtonCopy; CUIStatic* m_UIStaticPicture; - CUITextWnd* m_UIStaticText; - CUITextWnd* m_UIStaticHost; - CUITextWnd* m_UIStaticPass; - CUITextWnd* m_UIStaticUserPass; + CUIStatic* m_UIStaticText; + CUIStatic* m_UIStaticHost; + CUIStatic* m_UIStaticPass; + CUIStatic* m_UIStaticUserPass; CUIEditBox* m_UIEditHost; CUIEditBox* m_UIEditPass; CUIEditBox* m_UIEditUserPass; diff --git a/src/xrUICore/ScrollView/UIScrollView.h b/src/xrUICore/ScrollView/UIScrollView.h index 6b92f8a28df..0c02a6754c6 100644 --- a/src/xrUICore/ScrollView/UIScrollView.h +++ b/src/xrUICore/ScrollView/UIScrollView.h @@ -89,7 +89,7 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback }; #define ADD_TEXT_TO_VIEW3(txt, st, view) \ - st = xr_new(); \ + st = xr_new("Text"); \ st->SetFont(UI().Font().pFontLetterica16Russian); \ st->SetText(txt); \ st->SetTextComplexMode(true); \ @@ -98,5 +98,5 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback view->AddWindow(st, true) #define ADD_TEXT_TO_VIEW2(txt, view) \ - CUITextWnd* pSt; \ + CUIStatic* pSt; \ ADD_TEXT_TO_VIEW3(txt, pSt, view) From 6ce635b81c025a0d07b3b59e7b5ba59affd96989 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 10 Feb 2024 02:27:34 +0500 Subject: [PATCH 139/497] Removed CUITextWnd (#382) Lua scripts will now use CUIStatic too --- src/xrGame/ScriptXMLInit.cpp | 6 +-- src/xrGame/ScriptXMLInit.h | 3 +- src/xrUICore/Static/UIStatic.cpp | 54 +--------------------- src/xrUICore/Static/UIStatic.h | 59 +++++-------------------- src/xrUICore/Static/UIStatic_script.cpp | 50 +++++++++------------ src/xrUICore/Windows/UIWindow.h | 5 +-- src/xrUICore/XML/UIXmlInitBase.cpp | 58 ++++++------------------ src/xrUICore/XML/UIXmlInitBase.h | 5 +-- 8 files changed, 55 insertions(+), 185 deletions(-) diff --git a/src/xrGame/ScriptXMLInit.cpp b/src/xrGame/ScriptXMLInit.cpp index a665d5269f2..b4ef8c71623 100644 --- a/src/xrGame/ScriptXMLInit.cpp +++ b/src/xrGame/ScriptXMLInit.cpp @@ -82,10 +82,10 @@ CUIStatic* CScriptXmlInit::InitStatic(LPCSTR path, CUIWindow* parent) return pWnd; } -CUITextWnd* CScriptXmlInit::InitTextWnd(LPCSTR path, CUIWindow* parent) +CUIStatic* CScriptXmlInit::InitTextWnd(LPCSTR path, CUIWindow* parent) { - CUITextWnd* pWnd = xr_new(); - CUIXmlInit::InitTextWnd(m_xml, path, 0, pWnd); + auto* pWnd = xr_new(path); + CUIXmlInit::InitStatic(m_xml, path, 0, pWnd, true, true); _attach_child(pWnd, parent); return pWnd; } diff --git a/src/xrGame/ScriptXMLInit.h b/src/xrGame/ScriptXMLInit.h index 93f7217e8bd..1d338c8e19f 100644 --- a/src/xrGame/ScriptXMLInit.h +++ b/src/xrGame/ScriptXMLInit.h @@ -5,7 +5,6 @@ class CUIWindow; class CUIFrameWindow; class CUIStatic; -class CUITextWnd; class CUICheckButton; class CUISpinNum; class CUISpinText; @@ -43,7 +42,7 @@ class CScriptXmlInit CUIStatic* InitStatic(LPCSTR path, CUIWindow* parent); CUIStatic* InitAnimStatic(LPCSTR path, CUIWindow* parent); CUIStatic* InitSleepStatic(LPCSTR path, CUIWindow* parent); - CUITextWnd* InitTextWnd(LPCSTR path, CUIWindow* parent); + CUIStatic* InitTextWnd(LPCSTR path, CUIWindow* parent); CUICheckButton* InitCheck(LPCSTR path, CUIWindow* parent); CUISpinNum* InitSpinNum(LPCSTR path, CUIWindow* parent); CUISpinFlt* InitSpinFlt(LPCSTR path, CUIWindow* parent); diff --git a/src/xrUICore/Static/UIStatic.cpp b/src/xrUICore/Static/UIStatic.cpp index 1cb3e2ee3ab..4620df7e2c9 100644 --- a/src/xrUICore/Static/UIStatic.cpp +++ b/src/xrUICore/Static/UIStatic.cpp @@ -241,7 +241,7 @@ void CUIStatic::ColorAnimationSetTextureColor(u32 color, bool only_alpha) void CUIStatic::ColorAnimationSetTextColor(u32 color, bool only_alpha) { - TextItemControl()->SetTextColor((only_alpha) ? subst_alpha(TextItemControl()->GetTextColor(), color) : color); + SetTextColor((only_alpha) ? subst_alpha(GetTextColor(), color) : color); } void CUIStatic::FillDebugInfo() @@ -271,55 +271,3 @@ void CUIStatic::OnFocusLost() if (g_statHint->Owner() == this) g_statHint->Discard(); } - -//------------------------------------- -CUITextWnd::CUITextWnd() : CUIWindow("CUITextWnd") {} - -void CUITextWnd::AdjustHeightToText() -{ - if (!fsimilar(TextItemControl().m_wndSize.x, GetWidth())) - { - TextItemControl().m_wndSize.x = GetWidth(); - TextItemControl().ParseText(true); - } - SetHeight(TextItemControl().GetVisibleHeight()); -} - -void CUITextWnd::AdjustWidthToText() -{ - float _len = TextItemControl().GetFont()->SizeOf_(TextItemControl().GetText()); - UI().ClientToScreenScaledWidth(_len); - SetWidth(_len); -} - -void CUITextWnd::Draw() -{ - if (!fsimilar(TextItemControl().m_wndSize.x, m_wndSize.x) || !fsimilar(TextItemControl().m_wndSize.y, m_wndSize.y)) - { - TextItemControl().m_wndSize = m_wndSize; - TextItemControl().ParseText(true); - } - - Fvector2 p; - GetAbsolutePos(p); - TextItemControl().Draw(p.x, p.y); -} - -void CUITextWnd::Update() -{ - R_ASSERT(GetChildWndList().size() == 0); - UpdateColorAnimation(); - inherited::Update(); -} - -void CUITextWnd::ColorAnimationSetTextColor(u32 color, bool only_alpha) -{ - SetTextColor((only_alpha) ? subst_alpha(GetTextColor(), color) : color); -} - -void CUITextWnd::FillDebugInfo() -{ -#ifndef MASTER_GOLD - -#endif -} diff --git a/src/xrUICore/Static/UIStatic.h b/src/xrUICore/Static/UIStatic.h index 16e235724ee..ce29f2f2a57 100644 --- a/src/xrUICore/Static/UIStatic.h +++ b/src/xrUICore/Static/UIStatic.h @@ -43,15 +43,21 @@ class XRUICORE_API CUIStatic : public CUIWindow, public ITextureOwner, public CU virtual pcstr GetText() const { return const_cast(this)->TextItemControl()->GetText(); } virtual void SetText(pcstr txt) { TextItemControl()->SetText(txt); } virtual void SetTextST(pcstr txt) { TextItemControl()->SetTextST(txt); } + void SetFont(CGameFont* F) override { TextItemControl()->SetFont(F); } + CGameFont* GetFont() override { return TextItemControl()->GetFont(); } - u32 GetTextColor() - { - return TextItemControl()->GetTextColor(); - } + u32 GetTextColor() { return TextItemControl()->GetTextColor(); } + void SetTextColor(u32 color) { TextItemControl()->SetTextColor(color); } - void SetTextColor(u32 color) + void SetTextComplexMode(bool mode = true) { TextItemControl()->SetTextComplexMode(mode); } + void SetTextAlignment(ETextAlignment al) { TextItemControl()->SetTextAlignment(al); } + void SetVTextAlignment(EVTextAlignment al) { TextItemControl()->SetVTextAlignment(al); } + void SetEllipsis(bool mode) { TextItemControl()->SetEllipsis(mode); } + void SetCutWordsMode(bool mode) { TextItemControl()->SetCutWordsMode(mode); } + void SetTextOffset(float x, float y) { - TextItemControl()->SetTextColor(color); + TextItemControl()->m_TextOffset.x = x; + TextItemControl()->m_TextOffset.y = y; } virtual void SetTextX(float text_x) { TextItemControl()->m_TextOffset.x = text_x; } @@ -96,7 +102,6 @@ class XRUICORE_API CUIStatic : public CUIWindow, public ITextureOwner, public CU CUIStaticItem& GetUIStaticItem() { return m_UIStaticItem; } void SetStretchTexture(bool stretch_texture) { m_bStretchTexture = stretch_texture; } bool GetStretchTexture() { return m_bStretchTexture; } - void SetEllipsis(int pos, int indent) { TextItemControl()->SetEllipsis(pos != 0); } void SetHeading(float f) { m_fHeading = f; }; float GetHeading() { return m_fHeading; } bool Heading() { return m_bHeading; } @@ -126,43 +131,3 @@ class XRUICORE_API CUIStatic : public CUIWindow, public ITextureOwner, public CU CUILines* TextItemControl(); shared_str m_stat_hint_text; }; - -class XRUICORE_API CUITextWnd final : public CUIWindow, public CUILightAnimColorConrollerImpl -{ - typedef CUIWindow inherited; - CUILines m_lines; - -public: - CUITextWnd(); - - virtual void Draw(); - virtual void Update(); - - void AdjustHeightToText(); - void AdjustWidthToText(); - - void SetText(LPCSTR txt) { TextItemControl().SetText(txt); } - void SetTextST(LPCSTR txt) { TextItemControl().SetTextST(txt); } - LPCSTR GetText() { return TextItemControl().GetText(); } - void SetFont(CGameFont* F) { TextItemControl().SetFont(F); } - CGameFont* GetFont() { return TextItemControl().GetFont(); } - void SetTextColor(u32 color) { TextItemControl().SetTextColor(color); } - u32 GetTextColor() { return TextItemControl().GetTextColor(); } - void SetTextComplexMode(bool mode = true) { TextItemControl().SetTextComplexMode(mode); } - void SetTextAlignment(ETextAlignment al) { TextItemControl().SetTextAlignment(al); } - void SetVTextAlignment(EVTextAlignment al) { TextItemControl().SetVTextAlignment(al); } - void SetEllipsis(bool mode) { TextItemControl().SetEllipsis(mode); } - void SetCutWordsMode(bool mode) { TextItemControl().SetCutWordsMode(mode); } - void SetTextOffset(float x, float y) - { - TextItemControl().m_TextOffset.x = x; - TextItemControl().m_TextOffset.y = y; - } - - virtual void ColorAnimationSetTextColor(u32 color, bool only_alpha); - - CUILines& TextItemControl() { return m_lines; } - - pcstr GetDebugType() override { return "CUITextWnd"; } - void FillDebugInfo() override; -}; diff --git a/src/xrUICore/Static/UIStatic_script.cpp b/src/xrUICore/Static/UIStatic_script.cpp index 4e41ea6e238..058296eb800 100644 --- a/src/xrUICore/Static/UIStatic_script.cpp +++ b/src/xrUICore/Static/UIStatic_script.cpp @@ -39,8 +39,8 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("TextControl", &CUIStatic::TextItemControl) - .def("SetText", (void (CUIStatic::*)(LPCSTR)) (&CUIStatic::SetText)) - .def("SetTextST", (void (CUIStatic::*)(LPCSTR)) (&CUIStatic::SetTextST)) + .def("SetText", &CUIStatic::SetText) + .def("SetTextST", &CUIStatic::SetTextST) .def("GetText", &CUIStatic::GetText) @@ -52,10 +52,21 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("SetColor", &CUIStatic::SetColor) .def("GetColor", &CUIStatic::GetColor) + .def("SetFont", &CUIStatic::SetFont) + .def("GetFont", &CUIStatic::GetFont) + .def("SetTextColor", +[](CUIStatic* self, int a, int r, int g, int b) { self->SetTextColor(color_argb(a, r, g, b)); }) + .def("GetTextColor", &CUIStatic::GetTextColor) + .def("SetTextComplexMode", &CUIStatic::SetTextComplexMode) + .def("SetTextAlignment", &CUIStatic::SetTextAlignment) + .def("SetVTextAlignment", &CUIStatic::SetVTextAlignment) + + .def("AdjustHeightToText", &CUIStatic::AdjustHeightToText) + .def("AdjustWidthToText", &CUIStatic::AdjustWidthToText) + .def("SetTextOffset", &CUIStatic::SetTextOffset) .def("Init", +[](CUIStatic* self, float x, float y, float width, float height) { @@ -74,6 +85,9 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("InitTextureEx", &CUIStatic::InitTextureEx) .def("InitTextureEx", +[](CUIStatic* self, pcstr texture, pcstr shader) { self->InitTextureEx(texture, shader); }) + .def("SetTextureColor", &CUIStatic::SetTextureColor) + .def("GetTextureColor", &CUIStatic::GetTextureColor) + .def("SetTextureOffset", &CUIStatic::SetTextureOffset) .def("SetTextureRect", &CUIStatic::SetTextureRect_script) @@ -103,34 +117,14 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), //.def("GetClipperState", &CUIStatic::GetClipperState) - .def("SetElipsis", &CUIStatic::SetEllipsis), + .def("SetEllipsis", &CUIStatic::SetEllipsis) + .def("SetElipsis", &CUIStatic::SetEllipsis) + .def("SetElipsis", +[](CUIStatic* self, int mode, int indent) + { + self->SetEllipsis(mode != 0); + }), class_("CUIStatic") .def(constructor<>()) ]; }); - -SCRIPT_EXPORT(CUITextWnd, (CUIWindow), -{ - using namespace luabind; - - module(luaState) - [ - class_("CUITextWnd") - .def(constructor<>()) - .def("AdjustHeightToText", &CUITextWnd::AdjustHeightToText) - .def("AdjustWidthToText", &CUITextWnd::AdjustWidthToText) - .def("SetText", &CUITextWnd::SetText) - .def("SetTextST", &CUITextWnd::SetTextST) - .def("GetText", &CUITextWnd::GetText) - .def("SetFont", &CUITextWnd::SetFont) - .def("GetFont", &CUITextWnd::GetFont) - .def("SetTextColor", &CUITextWnd::SetTextColor) - .def("GetTextColor", &CUITextWnd::GetTextColor) - .def("SetTextComplexMode", &CUITextWnd::SetTextComplexMode) - .def("SetTextAlignment", &CUITextWnd::SetTextAlignment) - .def("SetVTextAlignment", &CUITextWnd::SetVTextAlignment) - .def("SetEllipsis", &CUITextWnd::SetEllipsis) - .def("SetTextOffset", &CUITextWnd::SetTextOffset) - ]; -}); diff --git a/src/xrUICore/Windows/UIWindow.h b/src/xrUICore/Windows/UIWindow.h index 191f45d2de6..2f4ceadf417 100644 --- a/src/xrUICore/Windows/UIWindow.h +++ b/src/xrUICore/Windows/UIWindow.h @@ -118,10 +118,7 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable virtual void Reset(); void ResetAll(); - virtual void SetFont(CGameFont* pFont) - { - UNUSED(pFont); - } + virtual void SetFont(CGameFont* /*pFont*/) {} virtual CGameFont* GetFont() { diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 2e0275edb4e..2b81e013bd6 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -135,13 +135,13 @@ bool CUIXmlInitBase::InitOptionsItem(CUIXml& xml_doc, LPCSTR path, int index, CU return false; } -bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal /*= true*/, bool textWnd /*= false*/) { if (!InitWindow(xml_doc, path, index, pWnd, fatal)) return false; string256 buf; - InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd); + InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd->TextItemControl()); InitTexture(xml_doc, path, index, pWnd); InitTextureOffset(xml_doc, path, index, pWnd); @@ -167,7 +167,7 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStat flags |= LA_CYCLIC; if (flag_alpha) flags |= LA_ONLYALPHA; - if (flag_text) + if (flag_text || textWnd) flags |= LA_TEXTCOLOR; if (flag_texture) flags |= LA_TEXTURECOLOR; @@ -185,38 +185,16 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStat pWnd->m_stat_hint_text = xml_doc.ReadAttrib(path, index, "hint", ""); - return true; -} - -bool CUIXmlInitBase::InitTextWnd(CUIXml& xml_doc, LPCSTR path, int index, CUITextWnd* pWnd, bool fatal /*= true*/) -{ - if (!InitWindow(xml_doc, path, index, pWnd, fatal)) - return false; - - string256 buf; - InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, &pWnd->TextItemControl()); - - LPCSTR str_flag = xml_doc.ReadAttrib(path, index, "light_anim", ""); - int flag_cyclic = xml_doc.ReadAttribInt(path, index, "la_cyclic", 1); - int flag_alpha = xml_doc.ReadAttribInt(path, index, "la_alpha", 0); - - u8 flags = LA_TEXTCOLOR; - if (flag_cyclic) - flags |= LA_CYCLIC; - if (flag_alpha) - flags |= LA_ONLYALPHA; - pWnd->SetColorAnimation(str_flag, flags); - - bool bComplexMode = xml_doc.ReadAttribInt(path, index, "complex_mode", 0) ? true : false; - if (bComplexMode) - pWnd->SetTextComplexMode(bComplexMode); - - strconcat(sizeof(buf), buf, path, ":texture"); - R_ASSERT3(NULL == xml_doc.NavigateToNode(buf, index), xml_doc.m_xml_file_name, buf); + if (textWnd) + { + strconcat(sizeof(buf), buf, path, ":texture"); + R_ASSERT3(nullptr == xml_doc.NavigateToNode(buf, index), xml_doc.m_xml_file_name, buf); - R_ASSERT(pWnd->GetChildWndList().size() == 0); + R_ASSERT2(pWnd->GetChildWndList().empty(), + "CUITextWnd should have no children. " + "Use InitStatic from Lua, if you want your UI element to have children."); + } return true; - } bool CUIXmlInitBase::InitCheck(CUIXml& xml_doc, LPCSTR path, int index, CUICheckButton* pWnd, bool fatal /*= true*/) @@ -290,14 +268,6 @@ bool CUIXmlInitBase::InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustom return true; } -bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd) -{ - if (!xml_doc.NavigateToNode(path, index)) - return false; - - return InitText(xml_doc, path, index, pWnd->TextItemControl()); -} - bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines) { if (!xml_doc.NavigateToNode(path, index)) @@ -366,7 +336,7 @@ bool CUIXmlInitBase::Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3t pWnd->InitButton(pWnd->GetWndPos(), pWnd->GetWndSize()); string256 buf; - InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd); + InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd->TextItemControl()); u32 color; strconcat(sizeof(buf), buf, path, ":text_color:e"); @@ -1200,8 +1170,8 @@ bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUI for (int i = 0; i < tabsCount; ++i) { - CUITextWnd* newText = xr_new(); - InitText(xml_doc, "text", i, &newText->TextItemControl()); + auto* newText = xr_new("Text"); + InitText(xml_doc, "text", i, newText->TextItemControl()); newText->SetTextComplexMode(true); newText->SetWidth(pWnd->GetDesiredChildWidth()); newText->AdjustHeightToText(); diff --git a/src/xrUICore/XML/UIXmlInitBase.h b/src/xrUICore/XML/UIXmlInitBase.h index de88b6dbf5d..e0eda3f35bb 100644 --- a/src/xrUICore/XML/UIXmlInitBase.h +++ b/src/xrUICore/XML/UIXmlInitBase.h @@ -31,7 +31,6 @@ class CUIDragDropListEx; class CUIComboBox; class CUITrackBar; class CUILines; -class CUITextWnd; class CGameFont; class XRUICORE_API CUIXmlInitBase @@ -46,11 +45,9 @@ class XRUICORE_API CUIXmlInitBase static bool InitTextFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUITextFrameLineWnd* pWnd, bool fatal = true); static bool InitCustomEdit(CUIXml& xml_doc, LPCSTR paht, int index, CUICustomEdit* pWnd, bool fatal = true); static bool InitEditBox(CUIXml& xml_doc, LPCSTR paht, int index, CUIEditBox* pWnd, bool fatal = true); - static bool InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal = true); - static bool InitTextWnd(CUIXml& xml_doc, LPCSTR path, int index, CUITextWnd* pWnd, bool fatal = true); + static bool InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal = true, bool textWnd = false); static bool InitCheck(CUIXml& xml_doc, LPCSTR path, int index, CUICheckButton* pWnd, bool fatal = true); static bool InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustomSpin* pWnd, bool fatal = true); - static bool InitText(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd); static bool InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines); static bool Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd, bool fatal = true); static bool InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CUIProgressBar* pWnd, bool fatal = true); From d58bf5b29b3713d7f02a8690eb6c422e25c1225b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 10 Feb 2024 15:58:12 +0500 Subject: [PATCH 140/497] Fixed misplaced text on radio buttons in UI in CS (#382) --- src/xrUICore/Buttons/UIRadioButton.cpp | 8 +++----- src/xrUICore/Buttons/UIRadioButton.h | 1 - src/xrUICore/ListWnd/UIListItem.cpp | 2 +- src/xrUICore/Static/UIStatic.h | 5 ----- src/xrUICore/Static/UIStatic_script.cpp | 10 +++++----- src/xrUICore/XML/UIXmlInitBase.cpp | 6 +++--- 6 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/xrUICore/Buttons/UIRadioButton.cpp b/src/xrUICore/Buttons/UIRadioButton.cpp index 9a3fbce5a0e..3811a4842a3 100644 --- a/src/xrUICore/Buttons/UIRadioButton.cpp +++ b/src/xrUICore/Buttons/UIRadioButton.cpp @@ -6,17 +6,15 @@ void CUIRadioButton::InitButton(Fvector2 pos, Fvector2 size) { inherited::InitButton(pos, size); - TextItemControl(); CUI3tButton::InitTexture("ui_radio"); - Fvector2 sz = m_background->Get(S_Enabled)->GetStaticItem()->GetSize(); + const Fvector2 sz = m_background->Get(S_Enabled)->GetStaticItem()->GetSize(); TextItemControl()->m_TextOffset.x = sz.x; - CUI3tButton::InitButton(pos, Fvector2().set(size.x, sz.y - 5.0f)); + CUI3tButton::InitButton(pos, { size.x, sz.y - 5.0f }); TextItemControl()->m_wndPos.set(pos); - TextItemControl()->m_wndSize.set( - Fvector2().set(size.x, m_background->Get(S_Enabled)->GetStaticItem()->GetSize().y)); + TextItemControl()->m_wndSize.set({ size.x, m_background->Get(S_Enabled)->GetStaticItem()->GetSize().y }); } bool CUIRadioButton::InitTexture(pcstr /*texture*/, bool /*fatal = true*/) diff --git a/src/xrUICore/Buttons/UIRadioButton.h b/src/xrUICore/Buttons/UIRadioButton.h index 32d59003672..319209830d0 100644 --- a/src/xrUICore/Buttons/UIRadioButton.h +++ b/src/xrUICore/Buttons/UIRadioButton.h @@ -8,7 +8,6 @@ class CUIRadioButton final : public CUITabButton public: virtual void InitButton(Fvector2 pos, Fvector2 size); virtual bool InitTexture(pcstr texture, bool fatal = true); - virtual void SetTextX(float x) { /*do nothing*/} bool OnMouseDown(int mouse_btn) override; pcstr GetDebugType() override { return "CUIRadioButton"; } }; diff --git a/src/xrUICore/ListWnd/UIListItem.cpp b/src/xrUICore/ListWnd/UIListItem.cpp index 210ceb29d31..ee95a87fe79 100644 --- a/src/xrUICore/ListWnd/UIListItem.cpp +++ b/src/xrUICore/ListWnd/UIListItem.cpp @@ -28,7 +28,7 @@ void CUIListItem::InitListItem(Fvector2 pos, Fvector2 size) void CUIListItem::InitTexture(pcstr tex_name) { CUIButton::InitTexture(tex_name); - SetTextX(m_UIStaticItem.GetTextureRect().width()); + TextItemControl()->m_TextOffset.x = m_UIStaticItem.GetTextureRect().width(); } /* diff --git a/src/xrUICore/Static/UIStatic.h b/src/xrUICore/Static/UIStatic.h index ce29f2f2a57..b5e9817059e 100644 --- a/src/xrUICore/Static/UIStatic.h +++ b/src/xrUICore/Static/UIStatic.h @@ -60,11 +60,6 @@ class XRUICORE_API CUIStatic : public CUIWindow, public ITextureOwner, public CU TextItemControl()->m_TextOffset.y = y; } - virtual void SetTextX(float text_x) { TextItemControl()->m_TextOffset.x = text_x; } - virtual void SetTextY(float text_y) { TextItemControl()->m_TextOffset.y = text_y; } - virtual float GetTextX() { return TextItemControl()->m_TextOffset.x; } - virtual float GetTextY() { return TextItemControl()->m_TextOffset.y; } - virtual void SetColor(u32 color) { m_UIStaticItem.SetColor(color); } virtual u32 GetColor() const { return m_UIStaticItem.GetColor(); } diff --git a/src/xrUICore/Static/UIStatic_script.cpp b/src/xrUICore/Static/UIStatic_script.cpp index 058296eb800..a508b3de923 100644 --- a/src/xrUICore/Static/UIStatic_script.cpp +++ b/src/xrUICore/Static/UIStatic_script.cpp @@ -44,10 +44,11 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("GetText", &CUIStatic::GetText) - .def("SetTextX", &CUIStatic::SetTextX) - .def("SetTextY", &CUIStatic::SetTextY) - .def("GetTextX", &CUIStatic::GetTextX) - .def("GetTextY", &CUIStatic::GetTextY) + .def("SetTextOffset", &CUIStatic::SetTextOffset) + .def("SetTextX", +[](CUIStatic* self, float x) { self->TextItemControl()->m_TextOffset.x = x; }) + .def("SetTextY", +[](CUIStatic* self, float y) { self->TextItemControl()->m_TextOffset.y = y; }) + .def("GetTextX", +[](CUIStatic* self) { return self->TextItemControl()->m_TextOffset.x; }) + .def("GetTextY", +[](CUIStatic* self) { return self->TextItemControl()->m_TextOffset.y; }) .def("SetColor", &CUIStatic::SetColor) .def("GetColor", &CUIStatic::GetColor) @@ -66,7 +67,6 @@ SCRIPT_EXPORT(CUIStatic, (CUIWindow), .def("AdjustHeightToText", &CUIStatic::AdjustHeightToText) .def("AdjustWidthToText", &CUIStatic::AdjustWidthToText) - .def("SetTextOffset", &CUIStatic::SetTextOffset) .def("Init", +[](CUIStatic* self, float x, float y, float width, float height) { diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 2b81e013bd6..696cefe03d8 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -307,10 +307,10 @@ bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines->SetTextComplexMode(xml_doc.ReadAttribInt(path, index, "complex_mode", 0) ? true : false); // Text coordinates - float text_x = xml_doc.ReadAttribFlt(path, index, "x", 0); - float text_y = xml_doc.ReadAttribFlt(path, index, "y", 0); + const float text_x = xml_doc.ReadAttribFlt(path, index, "x", 0.0f); + const float text_y = xml_doc.ReadAttribFlt(path, index, "y", 0.0f); - pLines->m_TextOffset.set(text_x, text_y); + pLines->m_TextOffset.add({ text_x, text_y }); shared_str text = xml_doc.Read(path, index, NULL); if (text.size()) From c1b2973561ccedca0da16722dca2435b1d71082f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 10 Feb 2024 16:23:04 +0500 Subject: [PATCH 141/497] Fixed yellow NPC icons in talk/trade/upgrade (fixes #1490) --- src/xrGame/ui/UICharacterInfo.cpp | 24 ++++++++++++------------ src/xrGame/ui/UICharacterInfo.h | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/xrGame/ui/UICharacterInfo.cpp b/src/xrGame/ui/UICharacterInfo.cpp index e4e08f91eea..41749859342 100644 --- a/src/xrGame/ui/UICharacterInfo.cpp +++ b/src/xrGame/ui/UICharacterInfo.cpp @@ -44,6 +44,14 @@ void CUICharacterInfo::InitCharacterInfo(Fvector2 pos, Fvector2 size, CUIXml* xm if (!m_icons[eIcon]) Init_IconInfoItem(*xml_doc, "icon_static", eIcon); + m_original_color = m_icons[eIcon] ? m_icons[eIcon]->GetTextureColor() : color_xrgb(255, 255, 255); + + m_deadbody_color = color_argb(160, 160, 160, 160); + if (xml_doc->NavigateToNode("icon:deadbody", 0)) + { + m_deadbody_color = CUIXmlInit::GetColor(*xml_doc, "icon:deadbody", 0, m_deadbody_color); + } + Init_IconInfoItem(*xml_doc, "icon_over", eIconOver); Init_IconInfoItem(*xml_doc, "rank_icon", eRankIcon); @@ -55,13 +63,6 @@ void CUICharacterInfo::InitCharacterInfo(Fvector2 pos, Fvector2 size, CUIXml* xm Init_IconInfoItem(*xml_doc, "commumity_big_icon", eCommunityBigIcon); Init_IconInfoItem(*xml_doc, "commumity_big_icon_over", eCommunityBigIconOver); - VERIFY(m_icons[eIcon]); - m_deadbody_color = color_argb(160, 160, 160, 160); - if (xml_doc->NavigateToNode("icon:deadbody", 0)) - { - m_deadbody_color = CUIXmlInit::GetColor(*xml_doc, "icon:deadbody", 0, m_deadbody_color); - } - // ---------------------------- Init_StrInfoItem(*xml_doc, "name_caption", eNameCaption); Init_StrInfoItem(*xml_doc, "name_static", eName); @@ -328,13 +329,12 @@ void CUICharacterInfo::Update() if (m_icons[eIcon]) { - CSE_ALifeCreatureAbstract* pCreature = smart_cast(T); - if (pCreature) + if (const auto* creature = smart_cast(T)) { - if (pCreature->g_Alive()) - m_icons[eIcon]->SetTextureColor(color_argb(255, 255, 255, 160)); + if (creature->g_Alive()) + m_icons[eIcon]->SetTextureColor(m_original_color); else - m_icons[eIcon]->SetTextureColor(color_argb(255, 255, 160, 160)); + m_icons[eIcon]->SetTextureColor(m_deadbody_color); } } } diff --git a/src/xrGame/ui/UICharacterInfo.h b/src/xrGame/ui/UICharacterInfo.h index 9ed76c888b4..ff09b7fc398 100644 --- a/src/xrGame/ui/UICharacterInfo.h +++ b/src/xrGame/ui/UICharacterInfo.h @@ -54,6 +54,7 @@ class CUICharacterInfo final : public CUIWindow }; CUIStatic* m_icons[eMaxCaption]{}; shared_str m_texture_name; + u32 m_original_color; u32 m_deadbody_color; public: From ba154b88bba43fedbe9b8ca5b7cea6e899dac30b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 00:36:17 +0500 Subject: [PATCH 142/497] Fixed misplaced text on radio buttons in COP (#382) This commit reimplements fix from d58bf5b29b3713d7f02a8690eb6c422e25c1225b --- src/xrUICore/XML/UIXmlInitBase.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 696cefe03d8..dc72f4c86ac 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -307,10 +307,12 @@ bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines->SetTextComplexMode(xml_doc.ReadAttribInt(path, index, "complex_mode", 0) ? true : false); // Text coordinates - const float text_x = xml_doc.ReadAttribFlt(path, index, "x", 0.0f); - const float text_y = xml_doc.ReadAttribFlt(path, index, "y", 0.0f); + // m_TextOffset can be already set during parent element creation (e.g. 3tButton) + // so reuse it as default. + const float text_x = xml_doc.ReadAttribFlt(path, index, "x", pLines->m_TextOffset.x); + const float text_y = xml_doc.ReadAttribFlt(path, index, "y", pLines->m_TextOffset.y); - pLines->m_TextOffset.add({ text_x, text_y }); + pLines->m_TextOffset = { text_x, text_y }; shared_str text = xml_doc.Read(path, index, NULL); if (text.size()) From 9e11f227a5c9be1ac9ae43266c69a486ebf6543b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 00:53:58 +0500 Subject: [PATCH 143/497] Fixed misplaced text on 3tButtons (both COP and CS, #382) I just returned Clear Sky code and it fixed some text misplacements even in COP. Why GSC changed this in COP? --- src/xrUICore/Lines/UILines.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/xrUICore/Lines/UILines.cpp b/src/xrUICore/Lines/UILines.cpp index d445e7a6f79..38f6d04013b 100644 --- a/src/xrUICore/Lines/UILines.cpp +++ b/src/xrUICore/Lines/UILines.cpp @@ -354,10 +354,8 @@ void CUILines::Draw(float x, float y) text_pos.set(0, 0); text_pos.x = x + GetIndentByAlign(); - // text_pos.y = y + GetVIndentByAlign(); - text_pos.y = y; + text_pos.y = y + GetVIndentByAlign(); UI().ClientToScreenScaled(text_pos); - text_pos.y += GetVIndentByAlign(); if (uFlags.test(flPasswordMode)) { From 393eaf859e5c764e83aa96a2df35d467105a5f7d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 02:50:51 +0500 Subject: [PATCH 144/497] xrUICore/Buttons/UICheckButton: reuse CUIButton functionality instead of code duplication --- src/xrUICore/Buttons/UICheckButton.cpp | 9 +-------- src/xrUICore/Buttons/UICheckButton.h | 1 - 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/xrUICore/Buttons/UICheckButton.cpp b/src/xrUICore/Buttons/UICheckButton.cpp index 16a8cbaa702..5e3babff753 100644 --- a/src/xrUICore/Buttons/UICheckButton.cpp +++ b/src/xrUICore/Buttons/UICheckButton.cpp @@ -10,6 +10,7 @@ CUICheckButton::CUICheckButton() { TextItemControl()->SetTextAlignment(CGameFont::alLeft); + SetButtonAsSwitch(true); m_pDependControl = NULL; } @@ -61,14 +62,6 @@ void CUICheckButton::InitTexture2(LPCSTR texture_name) TextItemControl()->m_TextOffset.x = TextItemControl()->m_TextOffset.x + r.width(); } -void CUICheckButton::OnFocusLost() -{ - if (m_eButtonState == BUTTON_PUSHED && pInput->iGetAsyncKeyState(MOUSE_1)) - return; - - inherited::OnFocusLost(); -} - void CUICheckButton::OnFocusReceive() { inherited::OnFocusReceive(); } void CUICheckButton::Show(bool status) { inherited::Show(status); } bool CUICheckButton::OnMouseDown(int mouse_btn) diff --git a/src/xrUICore/Buttons/UICheckButton.h b/src/xrUICore/Buttons/UICheckButton.h index bc1e2a3d061..b80afa47ca2 100644 --- a/src/xrUICore/Buttons/UICheckButton.h +++ b/src/xrUICore/Buttons/UICheckButton.h @@ -23,7 +23,6 @@ class XRUICORE_API CUICheckButton final : public CUI3tButton, public CUIOptionsI virtual bool IsChangedOptValue() const; // backup!=current virtual void OnFocusReceive(); - virtual void OnFocusLost(); virtual void Show(bool status); virtual bool OnMouseAction(float x, float y, EUIMessages mouse_action); virtual bool OnMouseDown(int mouse_btn); From 5223cf89c2ef26145fc77bcbdd3f91deb51627ca Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 02:55:07 +0500 Subject: [PATCH 145/497] CUI3tButton and CUICheckButton: removed excess virtual function overloads --- src/xrUICore/Buttons/UI3tButton.cpp | 3 --- src/xrUICore/Buttons/UI3tButton.h | 4 ---- src/xrUICore/Buttons/UICheckButton.cpp | 3 --- src/xrUICore/Buttons/UICheckButton.h | 3 --- 4 files changed, 13 deletions(-) diff --git a/src/xrUICore/Buttons/UI3tButton.cpp b/src/xrUICore/Buttons/UI3tButton.cpp index 42f4ea6674d..94c913c8310 100644 --- a/src/xrUICore/Buttons/UI3tButton.cpp +++ b/src/xrUICore/Buttons/UI3tButton.cpp @@ -19,15 +19,12 @@ CUI3tButton::CUI3tButton() m_frameline_mode = false; } -CUI3tButton::~CUI3tButton() {} void CUI3tButton::OnClick() { CUIButton::OnClick(); PlaySoundT(); } -bool CUI3tButton::OnMouseDown(int mouse_btn) { return CUIButton::OnMouseDown(mouse_btn); } -void CUI3tButton::OnFocusLost() { inherited::OnFocusLost(); } void CUI3tButton::OnFocusReceive() { inherited::OnFocusReceive(); diff --git a/src/xrUICore/Buttons/UI3tButton.h b/src/xrUICore/Buttons/UI3tButton.h index 9bbcab8408b..169ed822a76 100644 --- a/src/xrUICore/Buttons/UI3tButton.h +++ b/src/xrUICore/Buttons/UI3tButton.h @@ -10,7 +10,6 @@ class XRUICORE_API CUI3tButton : public CUIButton //. using CUIButton::SetTextColor; public: CUI3tButton(); - virtual ~CUI3tButton(); // appearance virtual void InitButton(Fvector2 pos, Fvector2 size); @@ -26,14 +25,11 @@ class XRUICORE_API CUI3tButton : public CUIButton virtual void OnClick(); virtual void OnFocusReceive(); - virtual void OnFocusLost(); virtual void DrawTexture(); virtual void Update(); virtual void Draw(); - virtual bool OnMouseDown(int mouse_btn); - pcstr GetDebugType() override { return "CUI3tButton"; } void SetStateTextColor(u32 color, IBState state) diff --git a/src/xrUICore/Buttons/UICheckButton.cpp b/src/xrUICore/Buttons/UICheckButton.cpp index 5e3babff753..8b52334eb1e 100644 --- a/src/xrUICore/Buttons/UICheckButton.cpp +++ b/src/xrUICore/Buttons/UICheckButton.cpp @@ -14,7 +14,6 @@ CUICheckButton::CUICheckButton() m_pDependControl = NULL; } -CUICheckButton::~CUICheckButton() {} void CUICheckButton::SetDependControl(CUIWindow* pWnd) { m_pDependControl = pWnd; } void CUICheckButton::Update() { @@ -62,8 +61,6 @@ void CUICheckButton::InitTexture2(LPCSTR texture_name) TextItemControl()->m_TextOffset.x = TextItemControl()->m_TextOffset.x + r.width(); } -void CUICheckButton::OnFocusReceive() { inherited::OnFocusReceive(); } -void CUICheckButton::Show(bool status) { inherited::Show(status); } bool CUICheckButton::OnMouseDown(int mouse_btn) { if (mouse_btn == MOUSE_1) diff --git a/src/xrUICore/Buttons/UICheckButton.h b/src/xrUICore/Buttons/UICheckButton.h index b80afa47ca2..b1703b63c55 100644 --- a/src/xrUICore/Buttons/UICheckButton.h +++ b/src/xrUICore/Buttons/UICheckButton.h @@ -11,7 +11,6 @@ class XRUICORE_API CUICheckButton final : public CUI3tButton, public CUIOptionsI public: CUICheckButton(); - virtual ~CUICheckButton(); virtual void Update(); @@ -22,8 +21,6 @@ class XRUICORE_API CUICheckButton final : public CUI3tButton, public CUIOptionsI virtual void UndoOptValue(); // backup->current virtual bool IsChangedOptValue() const; // backup!=current - virtual void OnFocusReceive(); - virtual void Show(bool status); virtual bool OnMouseAction(float x, float y, EUIMessages mouse_action); virtual bool OnMouseDown(int mouse_btn); From 217ee7187a052d13befb7693b433fa6600c66a39 Mon Sep 17 00:00:00 2001 From: threedeyes <3dEyes@gmail.com> Date: Sun, 11 Feb 2024 08:30:33 +0500 Subject: [PATCH 146/497] xrSound: use correct function paramer type in ogg vorbis seek --- src/xrSound/SoundRender_Source_loader.cpp | 2 +- src/xrSound/SoundRender_Target.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrSound/SoundRender_Source_loader.cpp b/src/xrSound/SoundRender_Source_loader.cpp index 4415c87388e..be993c850e3 100644 --- a/src/xrSound/SoundRender_Source_loader.cpp +++ b/src/xrSound/SoundRender_Source_loader.cpp @@ -6,7 +6,7 @@ //SEEK_SET 0 File beginning //SEEK_CUR 1 Current file pointer position //SEEK_END 2 End-of-file -int ov_seek_func(void* datasource, s64 offset, int whence) +int ov_seek_func(void* datasource, ogg_int64_t offset, int whence) { switch (whence) { diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index faab1adb39d..10940946f47 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -68,7 +68,7 @@ void CSoundRender_Target::fill_parameters() // pEmitter->set_position(SoundRender->listener_position()); } -extern int ov_seek_func(void* datasource, s64 offset, int whence); +extern int ov_seek_func(void* datasource, ogg_int64_t offset, int whence); extern size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource); extern int ov_close_func(void* datasource); extern long ov_tell_func(void* datasource); From 1bb2769a569e3f145967627862064d4e082059b2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 08:55:12 +0500 Subject: [PATCH 147/497] xrGame/ui/UIPdaWnd.h|cpp: additional pointer to animated static is not needed --- src/xrGame/ui/UIPdaWnd.cpp | 8 ++++---- src/xrGame/ui/UIPdaWnd.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/xrGame/ui/UIPdaWnd.cpp b/src/xrGame/ui/UIPdaWnd.cpp index 95ea764824b..2f069eb67b8 100644 --- a/src/xrGame/ui/UIPdaWnd.cpp +++ b/src/xrGame/ui/UIPdaWnd.cpp @@ -85,10 +85,10 @@ void CUIPdaWnd::Init() if (uiXml.NavigateToNode("anim_static")) // XXX: Replace with UIHelper { - m_anim_static = xr_new(); - AttachChild(m_anim_static); - m_anim_static->SetAutoDelete(true); - CUIXmlInit::InitAnimatedStatic(uiXml, "anim_static", 0, m_anim_static); + auto* anim_static = xr_new(); + AttachChild(anim_static); + anim_static->SetAutoDelete(true); + CUIXmlInit::InitAnimatedStatic(uiXml, "anim_static", 0, anim_static); } m_btn_close = UIHelper::Create3tButton(uiXml, "close_button", this); diff --git a/src/xrGame/ui/UIPdaWnd.h b/src/xrGame/ui/UIPdaWnd.h index 97df348816f..a6d71836231 100644 --- a/src/xrGame/ui/UIPdaWnd.h +++ b/src/xrGame/ui/UIPdaWnd.h @@ -33,7 +33,6 @@ class CUIPdaWnd final : public CUIDialogWnd CUIStatic* m_caption; shared_str m_caption_const; - CUIAnimatedStatic* m_anim_static; CUIStatic* m_clock; // Текущий активный диалог From 212caccb683cad44331c0f5f8d7146144420d53c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 08:58:06 +0500 Subject: [PATCH 148/497] xrGame/ui/UIVote.h|cpp: simplify CUIVote class creation --- src/xrGame/ui/UIHelper.cpp | 19 +++++++++++++ src/xrGame/ui/UIHelper.h | 1 + src/xrGame/ui/UIVote.cpp | 56 +++++++++----------------------------- src/xrGame/ui/UIVote.h | 7 ++--- 4 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/xrGame/ui/UIHelper.cpp b/src/xrGame/ui/UIHelper.cpp index dde3e06f51c..adf072de75c 100644 --- a/src/xrGame/ui/UIHelper.cpp +++ b/src/xrGame/ui/UIHelper.cpp @@ -241,6 +241,25 @@ CUICheckButton* UIHelper::CreateCheck(CUIXml& xml, LPCSTR ui_path, CUIWindow* pa return ui; } +CUIListBox* UIHelper::CreateListBox(CUIXml& xml, pcstr ui_path, CUIWindow* parent, bool critical) +{ + // If it's not critical element, then don't crash if it doesn't exist + if (!critical && !xml.NavigateToNode(ui_path, 0)) + return nullptr; + + auto ui = xr_new(); + if (!CUIXmlInit::InitListBox(xml, ui_path, 0, ui, critical) && !critical) + { + xr_delete(ui); + } + if (ui && parent) + { + parent->AttachChild(ui); + ui->SetAutoDelete(true); + } + return ui; +} + UIHint* UIHelper::CreateHint(CUIXml& xml, LPCSTR ui_path /*, CUIWindow* parent*/, bool critical) { // If it's not critical element, then don't crash if it doesn't exist diff --git a/src/xrGame/ui/UIHelper.h b/src/xrGame/ui/UIHelper.h index 41e40c8562f..b450df3b91d 100644 --- a/src/xrGame/ui/UIHelper.h +++ b/src/xrGame/ui/UIHelper.h @@ -41,6 +41,7 @@ class UIHelper static CUI3tButton* Create3tButton(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static CUI3tButton* Create3tButton(CUIXml& xml, LPCSTR ui_path, int index, CUIWindow* parent, bool critical = true); static CUICheckButton* CreateCheck(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); + static CUIListBox* CreateListBox(CUIXml& xml, pcstr ui_path, CUIWindow* parent, bool critical = true); static CUIEditBox* CreateEditBox(CUIXml& xml, LPCSTR ui_path, CUIWindow* parent, bool critical = true); static UIHint* CreateHint(CUIXml& xml, LPCSTR ui_path /*, CUIWindow* parent*/, bool critical = true); diff --git a/src/xrGame/ui/UIVote.cpp b/src/xrGame/ui/UIVote.cpp index fbe80d1e463..94049dae2d6 100644 --- a/src/xrGame/ui/UIVote.cpp +++ b/src/xrGame/ui/UIVote.cpp @@ -5,68 +5,38 @@ #include "xrUICore/ListBox/UIListBox.h" #include "xrUICore/Windows/UIFrameWindow.h" #include "UIXmlInit.h" +#include "UIHelper.h" #include "Level.h" #include "game_cl_base.h" #include "game_cl_teamdeathmatch.h" #include "xrEngine/XR_IOConsole.h" CUIVote::CUIVote() : CUIDialogWnd(CUIVote::GetDebugType()) -{ - m_prev_upd_time = 0; - bkgrnd = xr_new("Background"); - bkgrnd->SetAutoDelete(true); - AttachChild(bkgrnd); - msg = xr_new("Message"); - msg->SetAutoDelete(true); - AttachChild(msg); - - for (int i = 0; i < 3; i++) - { - cap[i] = xr_new("Caption"); - cap[i]->SetAutoDelete(true); - AttachChild(cap[i]); - // frame[i] = new CUIFrameWindow(); frame[i]->SetAutoDelete(true); AttachChild(frame[i]); - list[i] = xr_new(); - list[i]->SetAutoDelete(true); - AttachChild(list[i]); - } - - btn_yes = xr_new(); - btn_yes->SetAutoDelete(true); - AttachChild(btn_yes); - btn_no = xr_new(); - btn_no->SetAutoDelete(true); - AttachChild(btn_no); - btn_cancel = xr_new(); - btn_cancel->SetAutoDelete(true); - AttachChild(btn_cancel); - - Init(); -} - -void CUIVote::Init() { CUIXml xml_doc; xml_doc.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "voting_category.xml"); + CUIXmlInit::InitWindow(xml_doc, "vote", 0, this); - CUIXmlInit::InitStatic(xml_doc, "vote:background", 0, bkgrnd); - CUIXmlInit::InitStatic(xml_doc, "vote:msg", 0, msg); + std::ignore = UIHelper::CreateStatic(xml_doc, "vote:background", this); + msg = UIHelper::CreateStatic(xml_doc, "vote:msg", this); string256 path; for (int i = 0; i < 3; i++) { xr_sprintf(path, "vote:list_cap_%d", i + 1); - CUIXmlInit::InitStatic(xml_doc, path, 0, cap[i]); - // xr_sprintf (path, "vote:list_back_%d", i+1); - // CUIXmlInit::InitFrameWindow (xml_doc, path, 0, frame[i]); + std::ignore = UIHelper::CreateStatic(xml_doc, path, this); + + //xr_sprintf(path, "vote:list_back_%d", i + 1); + //std::ignore = UIHelper::CreateFrameWindow(xml_doc, path, this); + xr_sprintf(path, "vote:list_%d", i + 1); - CUIXmlInit::InitListBox(xml_doc, path, 0, list[i]); + list[i] = UIHelper::CreateListBox(xml_doc, path, this); } - CUIXmlInit::Init3tButton(xml_doc, "vote:btn_yes", 0, btn_yes); - CUIXmlInit::Init3tButton(xml_doc, "vote:btn_no", 0, btn_no); - CUIXmlInit::Init3tButton(xml_doc, "vote:btn_cancel", 0, btn_cancel); + btn_yes = UIHelper::Create3tButton(xml_doc, "vote:btn_yes", this); + btn_no = UIHelper::Create3tButton(xml_doc, "vote:btn_no", this); + btn_cancel = UIHelper::Create3tButton(xml_doc, "vote:btn_cancel", this); } void CUIVote::SetVoting(LPCSTR txt) { msg->SetText(txt); } diff --git a/src/xrGame/ui/UIVote.h b/src/xrGame/ui/UIVote.h index 50bd633b694..744e5209afa 100644 --- a/src/xrGame/ui/UIVote.h +++ b/src/xrGame/ui/UIVote.h @@ -12,7 +12,6 @@ class CUIVote final : public CUIDialogWnd public: CUIVote(); - void Init(); void Update() override; void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = 0) override; void OnBtnYes(); @@ -24,13 +23,11 @@ class CUIVote final : public CUIDialogWnd protected: CUIStatic* msg; - CUIStatic* cap[3]; - CUIFrameWindow* frame[3]; CUIListBox* list[3]; CUI3tButton* btn_yes; CUI3tButton* btn_no; CUI3tButton* btn_cancel; - CUIStatic* bkgrnd; - u32 m_prev_upd_time; + + u32 m_prev_upd_time{}; }; From 5007c375a7e741b2fd17569259865e0a72bb7603 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 11 Feb 2024 09:03:21 +0500 Subject: [PATCH 149/497] CUIVote: return UI elements from CS (#382) --- src/xrGame/ui/UIVote.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/xrGame/ui/UIVote.cpp b/src/xrGame/ui/UIVote.cpp index 94049dae2d6..6803a05584d 100644 --- a/src/xrGame/ui/UIVote.cpp +++ b/src/xrGame/ui/UIVote.cpp @@ -18,6 +18,7 @@ CUIVote::CUIVote() : CUIDialogWnd(CUIVote::GetDebugType()) CUIXmlInit::InitWindow(xml_doc, "vote", 0, this); std::ignore = UIHelper::CreateStatic(xml_doc, "vote:background", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "vote:msg_back", this, false); msg = UIHelper::CreateStatic(xml_doc, "vote:msg", this); string256 path; @@ -27,8 +28,8 @@ CUIVote::CUIVote() : CUIDialogWnd(CUIVote::GetDebugType()) xr_sprintf(path, "vote:list_cap_%d", i + 1); std::ignore = UIHelper::CreateStatic(xml_doc, path, this); - //xr_sprintf(path, "vote:list_back_%d", i + 1); - //std::ignore = UIHelper::CreateFrameWindow(xml_doc, path, this); + xr_sprintf(path, "vote:list_back_%d", i + 1); + std::ignore = UIHelper::CreateFrameWindow(xml_doc, path, this, false); xr_sprintf(path, "vote:list_%d", i + 1); list[i] = UIHelper::CreateListBox(xml_doc, path, this); From 3b6821c044a7d073341f8cc575d8e057da90d5a7 Mon Sep 17 00:00:00 2001 From: Xottab_DUTY Date: Sun, 11 Feb 2024 18:42:58 +0500 Subject: [PATCH 150/497] GitHub Actions: fix spurious failures on *BSD (#1604) --- .github/workflows/cibuild.yml | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 4697121fe73..3aa4fe4b531 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -202,7 +202,7 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 14G + memory: 8G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: runner-to-vm @@ -215,7 +215,7 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 14G + memory: 8G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false @@ -228,23 +228,8 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 14G + memory: 8G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false run: cmake --build build --config ${{ matrix.Configuration }} --parallel 4 - - - name: Finalize - uses: cross-platform-actions/action@v0.22.0 - with: - operating_system: ${{ matrix.platform.os }} - architecture: ${{ matrix.platform.arch }} - version: ${{ matrix.platform.os-version }} - cpu_count: 4 - memory: 14G - environment_variables: CFLAGS CXXFLAGS - # sync back is disabled due to: - # 1) VM stalls during the process - # 2) we don't output artifacts anyway - sync_files: false #vm-to-runner - run: rm -rf build # reduce amount of files to copy back from VM From f5e4fd181680134d0d932ddbda4cad34f9e08ae1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:52:03 +0000 Subject: [PATCH 151/497] build(deps): bump Externals/zlib from `abd3d1a` to `5c42a23` Bumps [Externals/zlib](https://github.com/madler/zlib) from `abd3d1a` to `5c42a23`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/abd3d1a28930f89375d4b41408b39f6c1be157b2...5c42a230b7b468dff011f444161c0145b5efae59) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index abd3d1a2893..5c42a230b7b 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit abd3d1a28930f89375d4b41408b39f6c1be157b2 +Subproject commit 5c42a230b7b468dff011f444161c0145b5efae59 From 3e357161a5a42dc841d295f7d65f99132fb9aade Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 12 Feb 2024 03:24:04 +0500 Subject: [PATCH 152/497] xrCore/xrDebug.cpp: dump locals and stack memory when detailed minidump is enabled MiniDumpFilterMemory won't be used now. Hopefully, this will increase useful data to determine the crash reason during debugging. --- src/xrCore/xrDebug.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index d3c3aad0472..197e1ae300f 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -699,10 +699,8 @@ void xrDebug::SetupExceptionHandler() if (strstr(commandLine, "-full_memory_dump")) minidumpFlags |= MiniDumpWithFullMemory | MiniDumpIgnoreInaccessibleMemory; -#ifdef MASTER_GOLD - else if (!strstr(commandLine, "-detailed_minidump")) - minidumpFlags |= MiniDumpFilterMemory; -#endif + else if (strstr(commandLine, "-detailed_minidump")) + minidumpFlags |= MiniDumpWithIndirectlyReferencedMemory; BT_SetDumpType(minidumpFlags); //BT_SetSupportEMail("cop-crash-report@stalker-game.com"); From e438e063cddf31337281f3f68c3b53f649399949 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 12 Feb 2024 20:04:37 +0500 Subject: [PATCH 153/497] xrUICore/Windows/UIWindow_script.cpp: export missing CS UI events (#382) Still not all of them yet --- src/xrUICore/Windows/UIWindow_script.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/xrUICore/Windows/UIWindow_script.cpp b/src/xrUICore/Windows/UIWindow_script.cpp index 336da9072d3..872e8ce0bb9 100644 --- a/src/xrUICore/Windows/UIWindow_script.cpp +++ b/src/xrUICore/Windows/UIWindow_script.cpp @@ -316,8 +316,13 @@ SCRIPT_EXPORT(EnumUIMessages, (), value("WINDOW_LBUTTON_DB_CLICK", int(WINDOW_LBUTTON_DB_CLICK)), value("WINDOW_KEY_PRESSED", int(WINDOW_KEY_PRESSED)), value("WINDOW_KEY_RELEASED", int(WINDOW_KEY_RELEASED)), + value("WINDOW_MOUSE_CAPTURE_LOST", int(WINDOW_MOUSE_CAPTURE_LOST)), value("WINDOW_KEYBOARD_CAPTURE_LOST", int(WINDOW_KEYBOARD_CAPTURE_LOST)), + // Legacy SOC/CS events + value("STATIC_FOCUS_RECEIVED", int(WINDOW_FOCUS_RECEIVED)), + value("STATIC_FOCUS_LOST", int(WINDOW_FOCUS_LOST)), + // CUIButton value("BUTTON_CLICKED", int(BUTTON_CLICKED)), value("BUTTON_DOWN", int(BUTTON_DOWN)), From e66e812f544652bb0e8b5e0ad153d43eba29cb9e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 12 Feb 2024 21:34:51 +0500 Subject: [PATCH 154/497] Take font prefix into account when changing game language (fixes #865) --- src/xrEngine/GameFont.cpp | 5 +-- src/xrEngine/StringTable/StringTable.cpp | 41 ++++++++++++++++++++++-- src/xrEngine/StringTable/StringTable.h | 2 ++ src/xrGame/console_commands.cpp | 3 +- src/xrUICore/FontManager/FontManager.cpp | 10 +++--- src/xrUICore/FontManager/FontManager.h | 4 +-- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/xrEngine/GameFont.cpp b/src/xrEngine/GameFont.cpp index aa6b85da657..255829fa1cd 100644 --- a/src/xrEngine/GameFont.cpp +++ b/src/xrEngine/GameFont.cpp @@ -5,6 +5,7 @@ #include "xr_level_controller.h" #include "xrCore/Text/StringConversion.hpp" #include "Render.h" +#include "StringTable/StringTable.h" extern ENGINE_API bool g_bRendering; ENGINE_API Fvector2 g_current_font_scale = {1.0f, 1.0f}; @@ -50,11 +51,11 @@ void CGameFont::Initialize(pcstr cShader, pcstr cTextureName) { string_path cTexture; - pcstr _lang = pSettings->r_string("string_table", "font_prefix"); + pcstr _lang = StringTable().GetCurrentFontPrefix().c_str(); bool is_di = strstr(cTextureName, "ui_font_hud_01") || strstr(cTextureName, "ui_font_hud_02") || strstr(cTextureName, "ui_font_console_02"); if (_lang && !is_di) - strconcat(sizeof(cTexture), cTexture, cTextureName, _lang); + strconcat(cTexture, cTextureName, _lang); else xr_strcpy(cTexture, sizeof(cTexture), cTextureName); diff --git a/src/xrEngine/StringTable/StringTable.cpp b/src/xrEngine/StringTable/StringTable.cpp index 7187ac4b91c..d709c17c2a0 100644 --- a/src/xrEngine/StringTable/StringTable.cpp +++ b/src/xrEngine/StringTable/StringTable.cpp @@ -128,18 +128,48 @@ void CStringTable::FillLanguageToken() void CStringTable::SetLanguage() { + cpcstr defined_language = pSettings->r_string("string_table", "language"); + cpcstr defined_prefix = pSettings->r_string("string_table", "font_prefix"); + if (LanguageID != std::numeric_limits::max()) + { pData->m_sLanguage = languagesToken.at(LanguageID).name; + + if (0 == xr_strcmp(pData->m_sLanguage, defined_language)) + pData->m_fontPrefix = defined_prefix; + else + { + pData->m_fontPrefix = nullptr; + + constexpr std::tuple known_prefixes[] = + { + { "fra", "_west" }, + { "ger", "_west" }, + { "ita", "_west" }, + { "spa", "_west" }, + { "pol", "_cent" }, + { "cze", "_cent" }, + }; + for (const auto [language, prefix] : known_prefixes) + { + if (0 == xr_strcmp(pData->m_sLanguage, language)) + pData->m_fontPrefix = prefix; + } + } + } else { - pData->m_sLanguage = pSettings->r_string("string_table", "language"); - auto it = std::find_if(languagesToken.begin(), languagesToken.end(), [](const xr_token& token) { + pData->m_sLanguage = defined_language; + pData->m_fontPrefix = defined_prefix; + + const auto it = std::find_if(languagesToken.begin(), languagesToken.end(), [](const xr_token& token) + { return token.name && token.name == pData->m_sLanguage; }); R_ASSERT3(it != languagesToken.end(), "Check localization.ltx! Current language: ", pData->m_sLanguage.c_str()); if (it != languagesToken.end()) - LanguageID = (*it).id; + LanguageID = it->id; } } @@ -148,6 +178,11 @@ shared_str CStringTable::GetCurrentLanguage() const return pData ? pData->m_sLanguage : nullptr; } +shared_str CStringTable::GetCurrentFontPrefix() const +{ + return pData ? pData->m_fontPrefix : nullptr; +} + xr_token* CStringTable::GetLanguagesToken() const { return languagesToken.data(); } void CStringTable::Load(LPCSTR xml_file_full) diff --git a/src/xrEngine/StringTable/StringTable.h b/src/xrEngine/StringTable/StringTable.h index 09e1dbed519..c687f91fe70 100644 --- a/src/xrEngine/StringTable/StringTable.h +++ b/src/xrEngine/StringTable/StringTable.h @@ -15,6 +15,7 @@ using STRING_TABLE_MAP = xr_map; struct STRING_TABLE_DATA { + shared_str m_fontPrefix; shared_str m_sLanguage; STRING_TABLE_MAP m_StringTable; }; @@ -35,6 +36,7 @@ class ENGINE_API CStringTable final static BOOL m_bWriteErrorsToLog; shared_str GetCurrentLanguage() const; + shared_str GetCurrentFontPrefix() const; xr_token* GetLanguagesToken() const; static u32 LanguageID; diff --git a/src/xrGame/console_commands.cpp b/src/xrGame/console_commands.cpp index 3420ed8c36a..1589788fcd4 100644 --- a/src/xrGame/console_commands.cpp +++ b/src/xrGame/console_commands.cpp @@ -214,8 +214,7 @@ class CCC_GameLanguage : public CCC_Token CCC_Token::Execute(args); StringTable().ReloadLanguage(); - if (g_pGamePersistent && g_pGamePersistent->IsMainMenuActive()) - MainMenu()->OnUIReset(); + Device.seqUIReset.Process(); if (!g_pGameLevel) return; diff --git a/src/xrUICore/FontManager/FontManager.cpp b/src/xrUICore/FontManager/FontManager.cpp index 516eac0ad68..e9b8dbeeb04 100644 --- a/src/xrUICore/FontManager/FontManager.cpp +++ b/src/xrUICore/FontManager/FontManager.cpp @@ -4,8 +4,6 @@ CFontManager::CFontManager() { - Device.seqDeviceReset.Add(this, REG_PRIORITY_HIGH); - m_all_fonts.push_back(&pFontMedium); // used cpp m_all_fonts.push_back(&pFontDI); // used cpp m_all_fonts.push_back(&pFontArial14); // used xml @@ -84,7 +82,6 @@ void CFontManager::InitializeFont(CGameFont*& F, LPCSTR section, u32 flags) CFontManager::~CFontManager() { - Device.seqDeviceReset.Remove(this); FONTS_VEC_IT it = m_all_fonts.begin(); FONTS_VEC_IT it_e = m_all_fonts.end(); for (; it != it_e; ++it) @@ -98,4 +95,9 @@ void CFontManager::Render() for (; it != it_e; ++it) (**it)->OnRender(); } -void CFontManager::OnDeviceReset() { InitializeFonts(); } + +void CFontManager::OnUIReset() +{ + // XXX: memory leak, font aren't being deallocated + InitializeFonts(); +} diff --git a/src/xrUICore/FontManager/FontManager.h b/src/xrUICore/FontManager/FontManager.h index ca385bf1b3d..505ce49b73c 100644 --- a/src/xrUICore/FontManager/FontManager.h +++ b/src/xrUICore/FontManager/FontManager.h @@ -1,6 +1,6 @@ #pragma once -struct XRUICORE_API CFontManager : public pureDeviceReset +struct XRUICORE_API CFontManager : public CUIResetNotifier { CFontManager(); ~CFontManager(); @@ -28,5 +28,5 @@ struct XRUICORE_API CFontManager : public pureDeviceReset void InitializeFont(CGameFont*& F, LPCSTR section, u32 flags = 0); LPCSTR GetFontTexName(LPCSTR section); - virtual void OnDeviceReset(); + void OnUIReset() override; }; From 5e8c1669febf9b5d6a501d8982fb48e3d4b8946f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 12 Feb 2024 22:54:55 +0500 Subject: [PATCH 155/497] Improve robustness of "-$" command line key when it's used incorrectly (#1582) --- src/xrGame/Level_start.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index 4336437b26e..986554d4755 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -248,10 +248,17 @@ bool CLevel::net_start6() { if (strstr(Core.Params, "-$")) { - string256 buf, cmd, param; - sscanf(strstr(Core.Params, "-$") + 2, "%[^ ] %[^ ] ", cmd, param); - strconcat(sizeof(buf), buf, cmd, " ", param); - Console->Execute(buf); + string256 buf{}, cmd{}, param{}; + const int result = sscanf(strstr(Core.Params, "-$") + 2, "%[^ ] %[^ ] ", cmd, param); + if (result == 2) + { + strconcat(buf, cmd, " ", param); + Console->Execute(buf); + } + else + { + Log("! The key '-$' is not being used correctly. Correct format: -$ "); + } } } else From dc51ba9931783b943573aa039cf6fc8d3b4814ac Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 13 Feb 2024 02:46:15 +0500 Subject: [PATCH 156/497] Restored old comments from original devs that were deleted in COP (#382) Cosmetic commit --- src/xrGame/ui/UIDebugFonts.cpp | 8 ++++++++ src/xrGame/ui/UIPdaKillMessage.cpp | 8 ++++++++ src/xrGame/ui/UIPdaKillMessage.h | 8 ++++++++ src/xrGame/ui/UISkinSelector.h | 9 +++++---- src/xrUICore/Buttons/UI3tButton.h | 10 ++++++++++ src/xrUICore/Lines/UILines.h | 9 +++++++++ src/xrUICore/SpinBox/UISpinText.h | 6 ++++++ 7 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/xrGame/ui/UIDebugFonts.cpp b/src/xrGame/ui/UIDebugFonts.cpp index b46007ae02b..864538a62b1 100644 --- a/src/xrGame/ui/UIDebugFonts.cpp +++ b/src/xrGame/ui/UIDebugFonts.cpp @@ -1,3 +1,11 @@ +// File: UIDebugFonts.cpp +// Description: Output list of all fonts +// Created: 22.03.2005 +// Author: Serge Vynnychenko +// Mail: narrator@gsc-game.kiev.ua +// +// Copyright 2005 GSC Game World + #include "StdAfx.h" #include "UIDebugFonts.h" diff --git a/src/xrGame/ui/UIPdaKillMessage.cpp b/src/xrGame/ui/UIPdaKillMessage.cpp index 6b7e4153749..125a6533651 100644 --- a/src/xrGame/ui/UIPdaKillMessage.cpp +++ b/src/xrGame/ui/UIPdaKillMessage.cpp @@ -1,3 +1,11 @@ +// File: UIPdaKillMessage.cpp +// Description: HUD message about player death. Implementation of visual behavior +// Created: 10.03.2005 +// Author: Serge Vynnychenko +// Mail: narrator@gsc-game.kiev.ua +// +// Copyright 2005 GSC GameWorld + #include "StdAfx.h" #include "UIPdaKillMessage.h" #include "UIInventoryUtilities.h" diff --git a/src/xrGame/ui/UIPdaKillMessage.h b/src/xrGame/ui/UIPdaKillMessage.h index ae37aa7e463..c8df84bb6e1 100644 --- a/src/xrGame/ui/UIPdaKillMessage.h +++ b/src/xrGame/ui/UIPdaKillMessage.h @@ -1,3 +1,11 @@ +// File: UIPdaKillMessage.h +// Description: HUD message about player death. Implementation of visual behavior +// Created: 10.03.2005 +// Author: Serge Vynnychenko +// Mail: narrator@gsc-game.kiev.ua +// +// Copyright 2005 GSC GameWorld + #pragma once #include "KillMessageStruct.h" diff --git a/src/xrGame/ui/UISkinSelector.h b/src/xrGame/ui/UISkinSelector.h index b9b18e92829..fe3a7da0e7c 100644 --- a/src/xrGame/ui/UISkinSelector.h +++ b/src/xrGame/ui/UISkinSelector.h @@ -1,5 +1,8 @@ -#ifndef UI_SKIN_SELECTOR_H_ -#define UI_SKIN_SELECTOR_H_ +//-----------------------------------------------------------------------------/ +// Окно выбора скина в сетевой игре +//-----------------------------------------------------------------------------/ + +#pragma once #include "UIDialogWnd.h" @@ -61,5 +64,3 @@ class CUISkinSelectorWnd final : public CUIDialogWnd int m_firstSkin; s16 m_team; }; - -#endif diff --git a/src/xrUICore/Buttons/UI3tButton.h b/src/xrUICore/Buttons/UI3tButton.h index 169ed822a76..25176961eb6 100644 --- a/src/xrUICore/Buttons/UI3tButton.h +++ b/src/xrUICore/Buttons/UI3tButton.h @@ -1,4 +1,14 @@ +// File: UI3tButton.cpp +// Description: Button with 3 texutres (for , and states) +// Created: 07.12.2004 +// Author: Serhiy 0. Vynnychenk0 +// Mail: narrator@gsc-game.kiev.ua +// +// copyright 2004 GSC Game World +// + #pragma once + #include "xrUICore/Buttons/UIButton.h" #include "xrUICore/InteractiveBackground/UI_IB_Static.h" #include "xrSound/Sound.h" diff --git a/src/xrUICore/Lines/UILines.h b/src/xrUICore/Lines/UILines.h index 4ad0634eb34..a01c90a48ba 100644 --- a/src/xrUICore/Lines/UILines.h +++ b/src/xrUICore/Lines/UILines.h @@ -1,4 +1,13 @@ +// File: UILines.h +// Description: Multilines Text Control +// Created: 11.03.2005 +// Author: Serge Vynnycheko +// Mail: narrator@gsc-game.kiev.ua +// +// Copyright 2005 GSC Game World + #pragma once + #include "xrUICore/Lines/UILine.h" #include "xrUICore/uiabstract.h" diff --git a/src/xrUICore/SpinBox/UISpinText.h b/src/xrUICore/SpinBox/UISpinText.h index 9921a7c004a..5c19cb05545 100644 --- a/src/xrUICore/SpinBox/UISpinText.h +++ b/src/xrUICore/SpinBox/UISpinText.h @@ -1,3 +1,9 @@ +// file: UISpinNum.h +// description: Spin Button with text data (unlike numerical data) +// created: 15.06.2005 +// author: Serge Vynnychenko +// + #pragma once #include "xrUICore/SpinBox/UICustomSpin.h" From ad6d9bcc5dcd01ae54b9efe4eed9e5b5abc23d13 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 13 Feb 2024 03:56:13 +0500 Subject: [PATCH 157/497] xrGame/ui/UIMMShniaga.cpp: removed old commented CS code (#382) It's not needed because we have SetVTextAlignment --- src/xrGame/ui/UIMMShniaga.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/xrGame/ui/UIMMShniaga.cpp b/src/xrGame/ui/UIMMShniaga.cpp index 00065088d96..a166ae1b612 100644 --- a/src/xrGame/ui/UIMMShniaga.cpp +++ b/src/xrGame/ui/UIMMShniaga.cpp @@ -175,11 +175,6 @@ void CUIMMShniaga::CreateList(xr_vector& lst, CUIXml& xml_doc, LPCST st->SetFont(pF); st->SetTextComplexMode(false); st->SetTextST(xml_doc.ReadAttrib("btn", i, "caption")); - - // float font_height = st->GetFont()->GetHeight(); - // UI().ClientToScreenScaledHeight(font_height); - - //. st->SetTextOffset (0, (button_height-font_height)/2.0f); st->SetTextColor(color); st->SetTextAlignment(CGameFont::alCenter); st->SetVTextAlignment(valCenter); From e3767dd1b47c055b4327ed49c896d7c3bb0fc4b9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 13 Feb 2024 06:16:38 +0500 Subject: [PATCH 158/497] xrGame/ui/UISpawnWnd.h|cpp: simplify CUISpawnWnd creation --- src/xrGame/ui/UISpawnWnd.cpp | 75 ++++++++++-------------------------- src/xrGame/ui/UISpawnWnd.h | 8 +--- 2 files changed, 21 insertions(+), 62 deletions(-) diff --git a/src/xrGame/ui/UISpawnWnd.cpp b/src/xrGame/ui/UISpawnWnd.cpp index dfe9c9fefc6..1717687fb52 100644 --- a/src/xrGame/ui/UISpawnWnd.cpp +++ b/src/xrGame/ui/UISpawnWnd.cpp @@ -9,65 +9,25 @@ #include "xrEngine/xr_level_controller.h" #include "xrUICore/Cursor/UICursor.h" #include "UIGameCustom.h" +#include "UIHelper.h" CUISpawnWnd::CUISpawnWnd() - : CUIDialogWnd(CUISpawnWnd::GetDebugType()), m_iCurTeam(0) -{ - m_pBackground = xr_new("Background"); - AttachChild(m_pBackground); - m_pCaption = xr_new("Caption"); - AttachChild(m_pCaption); - m_pImage1 = xr_new(); - AttachChild(m_pImage1); - m_pImage2 = xr_new(); - AttachChild(m_pImage2); - - m_pFrames[0] = xr_new("Frame 0"); - AttachChild(m_pFrames[0]); - m_pFrames[1] = xr_new("Frame 1"); - AttachChild(m_pFrames[1]); - // m_pFrames[2] = new CUIStatic("Frame 2"); AttachChild(m_pFrames[2]); - - m_pTextDesc = xr_new(); - AttachChild(m_pTextDesc); - - m_pBtnAutoSelect = xr_new(); - AttachChild(m_pBtnAutoSelect); - m_pBtnSpectator = xr_new(); - AttachChild(m_pBtnSpectator); - m_pBtnBack = xr_new(); - AttachChild(m_pBtnBack); - - Init(); -} - -CUISpawnWnd::~CUISpawnWnd() -{ - xr_delete(m_pCaption); - xr_delete(m_pBackground); - xr_delete(m_pFrames[0]); - xr_delete(m_pFrames[1]); - // xr_delete(m_pFrames[2]); - xr_delete(m_pImage1); - xr_delete(m_pImage2); - xr_delete(m_pTextDesc); - xr_delete(m_pBtnAutoSelect); - xr_delete(m_pBtnSpectator); - xr_delete(m_pBtnBack); -} - -void CUISpawnWnd::Init() + : CUIDialogWnd(CUISpawnWnd::GetDebugType()), + m_pImage1{ xr_new() }, + m_pImage2{ xr_new() } { CUIXml xml_doc; xml_doc.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "spawn.xml"); CUIXmlInit::InitWindow(xml_doc, "team_selector", 0, this); - CUIXmlInit::InitStatic(xml_doc, "team_selector:caption", 0, m_pCaption); - CUIXmlInit::InitStatic(xml_doc, "team_selector:background", 0, m_pBackground); - CUIXmlInit::InitStatic(xml_doc, "team_selector:image_frames_tl", 0, m_pFrames[0]); - CUIXmlInit::InitStatic(xml_doc, "team_selector:image_frames_tr", 0, m_pFrames[1]); - // CUIXmlInit::InitStatic(xml_doc,"team_selector:image_frames_bottom", 0, m_pFrames[2]); - CUIXmlInit::InitScrollView(xml_doc, "team_selector:text_desc", 0, m_pTextDesc); + + std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:background", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:caption", this); + + AttachChild(m_pImage1); + AttachChild(m_pImage2); + m_pImage1->SetAutoDelete(true); + m_pImage2->SetAutoDelete(true); CUIXmlInit::InitStatic(xml_doc, "team_selector:image_0", 0, m_pImage1); // m_pImage1->SetStretchTexture(true); @@ -75,9 +35,14 @@ void CUISpawnWnd::Init() // m_pImage2->SetStretchTexture(true); // InitTeamLogo(); - CUIXmlInit::Init3tButton(xml_doc, "team_selector:btn_spectator", 0, m_pBtnSpectator); - CUIXmlInit::Init3tButton(xml_doc, "team_selector:btn_autoselect", 0, m_pBtnAutoSelect); - CUIXmlInit::Init3tButton(xml_doc, "team_selector:btn_back", 0, m_pBtnBack); + std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_tl", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_tr", this); + // std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_bottom", this); + std::ignore = UIHelper::CreateScrollView(xml_doc, "team_selector:text_desc", this); + + m_pBtnAutoSelect = UIHelper::Create3tButton(xml_doc, "team_selector:btn_autoselect", this); + m_pBtnSpectator = UIHelper::Create3tButton(xml_doc, "team_selector:btn_spectator", this); + m_pBtnBack = UIHelper::Create3tButton(xml_doc, "team_selector:btn_back", this); } void CUISpawnWnd::InitTeamLogo() diff --git a/src/xrGame/ui/UISpawnWnd.h b/src/xrGame/ui/UISpawnWnd.h index b6c2a6e3817..32299eb0837 100644 --- a/src/xrGame/ui/UISpawnWnd.h +++ b/src/xrGame/ui/UISpawnWnd.h @@ -16,9 +16,7 @@ class CUISpawnWnd final : public CUIDialogWnd public: CUISpawnWnd(); - ~CUISpawnWnd() override; - virtual void Init(); void SendMessage(CUIWindow* pWnd, s16 msg, void* pData) override; bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; void SetVisibleForBtn(ETEAMMENU_BTN btn, bool state); @@ -38,15 +36,11 @@ class CUISpawnWnd final : public CUIDialogWnd // void SetCallbackFunc (ButtonClickCallback pFunc); protected: - CUIStatic* m_pCaption; - CUIStatic* m_pBackground; - CUIStatic* m_pFrames[2]; - CUIScrollView* m_pTextDesc; CUIStatix* m_pImage1; CUIStatix* m_pImage2; CUI3tButton* m_pBtnAutoSelect; CUI3tButton* m_pBtnSpectator; CUI3tButton* m_pBtnBack; - int m_iCurTeam; + int m_iCurTeam{}; }; From d2f20027d62a03ffb77e0c192da25a442fa300d1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 13 Feb 2024 06:19:28 +0500 Subject: [PATCH 159/497] xrGame/ui/UISpawnWnd.cpp: returned bottom image from CS (#382) --- src/xrGame/ui/UISpawnWnd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/ui/UISpawnWnd.cpp b/src/xrGame/ui/UISpawnWnd.cpp index 1717687fb52..f8f26f0fa77 100644 --- a/src/xrGame/ui/UISpawnWnd.cpp +++ b/src/xrGame/ui/UISpawnWnd.cpp @@ -37,7 +37,7 @@ CUISpawnWnd::CUISpawnWnd() std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_tl", this); std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_tr", this); - // std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_bottom", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "team_selector:image_frames_bottom", this, false); std::ignore = UIHelper::CreateScrollView(xml_doc, "team_selector:text_desc", this); m_pBtnAutoSelect = UIHelper::Create3tButton(xml_doc, "team_selector:btn_autoselect", this); From c382f715ce5585c493712cff04a76dd3240a3680 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 13 Feb 2024 08:42:44 +0500 Subject: [PATCH 160/497] Optimized code in CUIProgressShape --- src/xrUICore/ProgressBar/UIProgressShape.cpp | 42 +++++--------------- src/xrUICore/ProgressBar/UIProgressShape.h | 20 +++++----- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/src/xrUICore/ProgressBar/UIProgressShape.cpp b/src/xrUICore/ProgressBar/UIProgressShape.cpp index b586d8716f1..adb66d64960 100644 --- a/src/xrUICore/ProgressBar/UIProgressShape.cpp +++ b/src/xrUICore/ProgressBar/UIProgressShape.cpp @@ -3,16 +3,7 @@ #include "Include/xrRender/UIShader.h" #include "Include/xrRender/UIRender.h" -CUIProgressShape::CUIProgressShape() : CUIStatic("CUIProgressShape") -{ - m_pBackground = nullptr; - m_pTexture = nullptr; - m_bText = false; - m_blend = true; - m_angle_begin = 0.0f; - m_angle_end = PI_MUL_2; - m_stage = 0.f; -}; +CUIProgressShape::CUIProgressShape() : CUIStatic("CUIProgressShape") {} void CUIProgressShape::SetPos(float pos) { m_stage = pos; } void CUIProgressShape::SetPos(int pos, int max) @@ -20,11 +11,9 @@ void CUIProgressShape::SetPos(int pos, int max) m_stage = float(pos) / float(max); if (m_bText) { - string256 _buff; - if (m_pTexture) - m_pTexture->SetText(xr_itoa(pos, _buff, 10)); - else - TextItemControl()->SetText(xr_itoa(pos, _buff, 10)); + CUIStatic* origin = m_pTexture ? m_pTexture : this; + string256 buff; + origin->SetText(xr_itoa(pos, buff, 10)); } } @@ -61,18 +50,14 @@ void CUIProgressShape::Draw() if (m_pBackground) m_pBackground->Draw(); + CUIStatic* origin = m_pTexture ? m_pTexture : this; + if (m_bText) { - if (m_pTexture) - m_pTexture->DrawText(); - else - DrawText(); + origin->DrawText(); } - if (m_pTexture) - GEnv.UIRender->SetShader(*m_pTexture->GetShader()); - else - GEnv.UIRender->SetShader(*GetShader()); + GEnv.UIRender->SetShader(*origin->GetShader()); Fvector2 tsize; GEnv.UIRender->GetActiveTextureResolution(tsize); @@ -80,21 +65,14 @@ void CUIProgressShape::Draw() GEnv.UIRender->StartPrimitive(m_sectorCount * 3, IUIRender::ptTriList, UI().m_currentPointType); Frect pos_rect; - if (m_pTexture) - m_pTexture->GetAbsoluteRect(pos_rect); - else - GetAbsoluteRect(pos_rect); + origin->GetAbsoluteRect(pos_rect); UI().ClientToScreenScaled(pos_rect.lt, pos_rect.x1, pos_rect.y1); UI().ClientToScreenScaled(pos_rect.rb, pos_rect.x2, pos_rect.y2); Fvector2 center_pos; pos_rect.getcenter(center_pos); - Frect tex_rect; - if (m_pTexture) - tex_rect = m_pTexture->GetUIStaticItem().GetTextureRect(); - else - tex_rect = GetUIStaticItem().GetTextureRect(); + Frect tex_rect = origin->GetUIStaticItem().GetTextureRect(); tex_rect.lt.x /= tsize.x; tex_rect.lt.y /= tsize.y; diff --git a/src/xrUICore/ProgressBar/UIProgressShape.h b/src/xrUICore/ProgressBar/UIProgressShape.h index 6659f1e9616..f7854f2b3bf 100644 --- a/src/xrUICore/ProgressBar/UIProgressShape.h +++ b/src/xrUICore/ProgressBar/UIProgressShape.h @@ -29,14 +29,14 @@ class XRUICORE_API CUIProgressShape final : public CUIStatic pcstr GetDebugType() override { return "CUIProgressShape"; } protected: - bool m_bClockwise; - u32 m_sectorCount; - float m_stage; - CUIStatic* m_pTexture; - CUIStatic* m_pBackground; - bool m_bText; - bool m_blend; - - float m_angle_begin; - float m_angle_end; + bool m_bClockwise{ true }; + u32 m_sectorCount{ 8 }; + float m_stage{}; + CUIStatic* m_pTexture{}; + CUIStatic* m_pBackground{}; + bool m_bText{}; + bool m_blend{ true }; + + float m_angle_begin{}; + float m_angle_end{ PI_MUL_2 }; }; From f3ce61e5b52321f7a9fbcfa9e725cb9e8a88bec9 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Tue, 13 Feb 2024 15:35:32 +0000 Subject: [PATCH 161/497] CMake: Use CMAKE_SYSTEM_PROCESSOR instead of ARCH_TYPE variable (#1608) Co-authored-by: Sultan Uramaev --- CMakeLists.txt | 5 +++-- cmake/utils.cmake | 7 ------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a669a43019..584e937f9e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,8 @@ project(OpenXRay HOMEPAGE_URL "https://github.com/OpenXRay/xray-16" LANGUAGES CXX C ) -message(STATUS "CMAKE_PROJECT_VERSION: ${}") + +message(STATUS "CMAKE_PROJECT_VERSION: ${CMAKE_PROJECT_VERSION}") set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -44,7 +45,7 @@ include(packaging) set_git_info() # Output all libraries and executable to one folder -set(COMPILE_OUTPUT_FOLDER "${CMAKE_SOURCE_DIR}/bin/${ARCH_TYPE}/${CMAKE_BUILD_TYPE}") +set(COMPILE_OUTPUT_FOLDER "${CMAKE_SOURCE_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}/${CMAKE_BUILD_TYPE}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${COMPILE_OUTPUT_FOLDER}") diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 9262a7993bf..b85beb3b043 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -24,13 +24,6 @@ function(target_sources_grouped) source_group(${PARSED_ARGS_NAME} FILES ${PARSED_ARGS_FILES}) endfunction() -# Detect arch type ( x86 or x64 ) -if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH_TYPE x64) -else (CMAKE_SIZEOF_VOID_P EQUAL 4) - set(ARCH_TYPE x86) -endif() - function(set_git_info) execute_process(COMMAND git rev-parse --verify HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" From 5cfbd42cbfb4d6139337156146e18d7a808ea0a7 Mon Sep 17 00:00:00 2001 From: Neloreck Date: Wed, 14 Feb 2024 01:39:11 +0200 Subject: [PATCH 162/497] Fix r5 hbao variable re-declaration. --- res/gamedata/shaders/r5/ssao_hbao.ps | Bin 15142 -> 15151 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/res/gamedata/shaders/r5/ssao_hbao.ps b/res/gamedata/shaders/r5/ssao_hbao.ps index b67f64acad9241987e28618d2d63914191922d73..b5788ee8797224d190ca5beefa55c39bd3a61bff 100644 GIT binary patch delta 37 ocmZ2hw!Un_S?2g6(}`!5z|?y+b|6o$s+?=`Lq@U9`i$Q#0V$Ubs{jB1 delta 17 ZcmZ2qwybQz*@+jFCVo}hEXOEl1prhm2kQU; From 76c251bd28b704df464fe415417f63ad5117c42c Mon Sep 17 00:00:00 2001 From: Neloreck Date: Wed, 14 Feb 2024 02:49:48 +0200 Subject: [PATCH 163/497] Reuse global hbao `screen_res` variable. --- res/gamedata/shaders/r5/ssao_hbao.ps | Bin 15151 -> 15113 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/res/gamedata/shaders/r5/ssao_hbao.ps b/res/gamedata/shaders/r5/ssao_hbao.ps index b5788ee8797224d190ca5beefa55c39bd3a61bff..675cb8e105c0ccc0e4550e801e2d2b6f82359590 100644 GIT binary patch delta 17 ZcmZ2q)>$@T^Tf;Y6Thl$mSYsO0sv7&2ebeH delta 64 zcmeAyTVFO|vs`IjW?FtxE@xU!eqxCUCuebTQEF;ld{Js~e37a3#Epu~KziaOHFhAS RS5?k6c>$x?W+BG!mH;jp7r+1j From 5efa5fb061a68a89c65dd5e5e7ad4b71f15d0389 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 15 Feb 2024 05:36:46 +0500 Subject: [PATCH 164/497] Revert "Revert "Use game materials system for a bit better sound occlusion"" This reverts commit 046c2871cba00f4c92ae1c73f364ae00b770f8c5. --- src/xrSound/CMakeLists.txt | 1 + src/xrSound/SoundRender_Scene.cpp | 6 +++++- src/xrSound/xrSound.vcxproj | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index a626f73fb96..2250de18246 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -141,6 +141,7 @@ target_link_libraries(xrSound xrMiscMath xrAPI xrCDB + xrMaterialSystem ${OPENAL_LIBRARY} Ogg::Ogg Vorbis::Vorbis diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 72d739e854e..50392e35aec 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -2,6 +2,7 @@ #include "Common/LevelStructure.hpp" #include "xrCDB/Intersect.hpp" +#include "xrMaterialSystem/GameMtlLib.h" #include "SoundRender_Core.h" #include "SoundRender_Scene.h" @@ -310,7 +311,10 @@ float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) occ[0].set(V[T.verts[0]]); occ[1].set(V[T.verts[1]]); occ[2].set(V[T.verts[2]]); - occ_value = psSoundOcclusionScale; + + const SGameMtl* mtl = GMLib.GetMaterialByIdx(T.material); + const float occlusion = fis_zero(mtl->fSndOcclusionFactor) ? 0.1f : mtl->fSndOcclusionFactor; + occ_value = psSoundOcclusionScale * occlusion; } } } diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index dfaf3f000dd..2763301039d 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -95,6 +95,9 @@ {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} + + {2c419512-6eee-4707-bc51-2e834855552e} + From 63b559eb43b240cd050ab914451ed917d7120221 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 15 Feb 2024 08:02:50 +0500 Subject: [PATCH 165/497] xrCore/FS.cpp: r_bytes can be 0 if the file_size is 0 (fixes #1572) Mandatory condition for r_bytes to be greater than 0 was introduced in #1512 and #1523, this commit reverts the check to original one. --- src/xrCore/FS.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrCore/FS.cpp b/src/xrCore/FS.cpp index 6e9adcebe52..b547650786b 100644 --- a/src/xrCore/FS.cpp +++ b/src/xrCore/FS.cpp @@ -117,8 +117,8 @@ void* FileDownload(pcstr file_name, const int& file_handle, size_t& file_size) VERIFY(file_size != 0); void* buffer = xr_malloc(file_size); - const ssize_t r_bytes = _read(file_handle, buffer, file_size); - R_ASSERT3(r_bytes > 0 && static_cast(r_bytes) == file_size, "Can't read from file : ", file_name); + const auto r_bytes = _read(file_handle, buffer, file_size); + R_ASSERT3(file_size == static_cast(r_bytes), "Can't read from file : ", file_name); // file_size = r_bytes; From d0e7002f377b5963a1540a359797b653e5bb492e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 15 Feb 2024 08:21:52 +0500 Subject: [PATCH 166/497] xrAICore: don't throw exceptions in some functions, that are being exported to script That breaks the game in Debug/Mixed builds. --- src/xrAICore/Components/condition_state_inline.h | 4 ++-- src/xrAICore/Components/problem_solver_inline.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrAICore/Components/condition_state_inline.h b/src/xrAICore/Components/condition_state_inline.h index 41ff7c3a233..d405dfd4382 100644 --- a/src/xrAICore/Components/condition_state_inline.h +++ b/src/xrAICore/Components/condition_state_inline.h @@ -39,7 +39,7 @@ TEMPLATE_SPECIALIZATION IC void CConditionStateAbstract::add_condition(const _world_property& condition) { typename xr_vector<_world_property>::iterator I = std::lower_bound(m_conditions.begin(), m_conditions.end(), condition); - THROW((I == m_conditions.end()) || ((*I).condition() != condition.condition())); + VERIFY((I == m_conditions.end()) || ((*I).condition() != condition.condition())); m_conditions.insert(I, condition); m_hash ^= condition.hash_value(); } @@ -49,7 +49,7 @@ IC void CConditionStateAbstract::remove_condition(const typename _world_property { typename xr_vector<_world_property>::iterator I = std::lower_bound( m_conditions.begin(), m_conditions.end(), _world_property(condition, typename _world_property::value_type(0))); - THROW((I != m_conditions.end()) && ((*I).condition() == condition)); + VERIFY((I != m_conditions.end()) && ((*I).condition() == condition)); m_hash ^= (*I).hash_value(); m_conditions.erase(I); } diff --git a/src/xrAICore/Components/problem_solver_inline.h b/src/xrAICore/Components/problem_solver_inline.h index 05a2ef23a6a..33771ac63aa 100644 --- a/src/xrAICore/Components/problem_solver_inline.h +++ b/src/xrAICore/Components/problem_solver_inline.h @@ -96,7 +96,7 @@ IC void CProblemSolverAbstract::validate_properties(const CState& conditions) co if (evaluators().find(cond.condition()) == evaluators().end()) { Msg("! cannot find corresponding evaluator to the property with id %d", cond.condition()); - THROW(evaluators().find(cond.condition()) != evaluators().end()); + VERIFY(evaluators().find(cond.condition()) != evaluators().end()); } } } From ebe29b79655417fc22a9bb8035777ae961655d9c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 16 Feb 2024 00:42:23 +0500 Subject: [PATCH 167/497] xrGame/ui/ServerList.h: use std::array instead of plain C array --- src/xrGame/ui/ServerList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/ui/ServerList.h b/src/xrGame/ui/ServerList.h index 05343d49333..543598805c6 100644 --- a/src/xrGame/ui/ServerList.h +++ b/src/xrGame/ui/ServerList.h @@ -121,7 +121,7 @@ class CServerList final : public CUIWindow SServerFilters m_sf; // CUIListWnd m_list[3]; CUIListBox m_list[3]; - CUIFrameWindow m_frame[3]; + std::array m_frame; CUI3tButton m_header[LST_COLUMN_COUNT]; std::array m_header2; std::array m_header_frames; From 92c550c591a57491371e7b8d3d3494d4224a9c38 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 16 Feb 2024 00:53:52 +0500 Subject: [PATCH 168/497] Modernize AppVeyor configuration - Update to Visual Studio 2022 - Deprecate Ubuntu x86 --- appveyor.yml | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 45b16e5f84e..1a9c1f004b7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ skip_tags: true skip_branch_with_pr: true image: -- Visual Studio 2019 +- Visual Studio 2022 - Ubuntu configuration: @@ -26,6 +26,8 @@ branches: matrix: exclude: + - image: Ubuntu + platform: x86 - image: Ubuntu configuration: Mixed - image: Ubuntu @@ -38,16 +40,20 @@ for: - matrix: only: - - image: Visual Studio 2019 + - image: Visual Studio 2022 + before_build: - git submodule update --init --recursive - nuget restore src\engine.sln + build: project: src/engine.sln parallel: true verbosity: minimal + after_build: - cmd: misc/windows/xr_pack_build.cmd "%CONFIGURATION%" "%PLATFORM%" + artifacts: - path: res/OpenXRay.*.7z name: OpenXRay.*.7z @@ -59,33 +65,21 @@ for: matrix: only: - image: Ubuntu + before_build: + - sudo apt-get update + - sudo apt-get install -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev libopenal-dev libogg-dev libtheora-dev libvorbis-dev - git submodule update --init --recursive - - git submodule deinit Externals/cryptopp + build_script: - - export CC=gcc-8 - - export CXX=g++-8 - ${CXX} --version - cmake --version - export core_count=$(nproc || echo 4) && echo core_count = $core_count - - mkdir bin - - cd bin - - sh: | - if [ "$PLATFORM" = "x64" ]; then - sudo apt-get update && - sudo apt-get install -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev && - sudo apt-get install -y libopenal-dev libogg-dev libtheora-dev libvorbis-dev && - CFLAGS="-w" CXXFLAGS="-w" cmake .. -DCMAKE_BUILD_TYPE=$BUILD_CONFIGURATION - fi - - sh: | - if [ "$PLATFORM" = "x86" ]; then - sudo dpkg --add-architecture i386 && sudo apt-get -qq update && sudo apt-get remove -y libllvm10 libgl1 libgl1-mesa-dri && sudo apt-get install -y gcc-multilib g++-8-multilib && - sudo apt-get install -y libsdl2-dev:i386 libglew-dev:i386 liblzo2-dev:i386 libjpeg-dev:i386 && - sudo apt-get install -y libopenal-dev:i386 libogg-dev:i386 libtheora-dev:i386 libvorbis-dev:i386 && - CFLAGS="-m32 -w" CXXFLAGS="-m32 -w" cmake .. -DCMAKE_BUILD_TYPE=$BUILD_CONFIGURATION -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -DCMAKE_ASM_FLAGS=-m32 - fi - - make -j $core_count package + - CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=$BUILD_CONFIGURATION + - cmake --build build --config $BUILD_CONFIGURATION --parallel $core_count + - cpack -B artifacts -C $BUILD_CONFIGURATION -DCPACK_THREADS=$core_count - file openxray_1.6.02_*.deb + artifacts: - path: bin/openxray_1.6.02_*.deb name: openxray_1.6.02_*.deb From 779ff9f50cfd0dd41d32bdf11c74c60e19183b1d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 18 Feb 2024 00:22:13 +0500 Subject: [PATCH 169/497] DirectX 11: don't do DXGI_PRESENT_TEST every frame According to Microsoft, we should not do that. --- src/Layers/xrRenderDX11/dx11HW.cpp | 37 +++++++++++++++++++++++------- src/Layers/xrRenderDX11/dx11HW.h | 3 ++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index 00c16c2e639..7dfe138fc62 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -496,7 +496,15 @@ void CHW::Present() { const bool bUseVSync = psDeviceMode.WindowStyle == rsFullscreen && psDeviceFlags.test(rsVSync); // xxx: weird tearing glitches when VSync turned on for windowed mode in DX11 - m_pSwapChain->Present(bUseVSync ? 1 : 0, 0); + + switch (m_pSwapChain->Present(bUseVSync ? 1 : 0, 0)) + { + case DXGI_STATUS_OCCLUDED: + case DXGI_ERROR_DEVICE_REMOVED: + doPresentTest = true; + break; + } + #ifdef HAS_DX11_2 if (m_pSwapChain2 && UsingFlipPresentationModel()) { @@ -510,15 +518,28 @@ void CHW::Present() CurrentBackBuffer = (CurrentBackBuffer + 1) % BackBufferCount; } -DeviceState CHW::GetDeviceState() const +DeviceState CHW::GetDeviceState() { - const auto result = m_pSwapChain->Present(0, DXGI_PRESENT_TEST); - - switch (result) + if (doPresentTest) { - // Check if the device is ready to be reset - case DXGI_ERROR_DEVICE_RESET: - return DeviceState::NeedReset; + switch (m_pSwapChain->Present(0, DXGI_PRESENT_TEST)) + { + case S_OK: + doPresentTest = false; + break; + + case DXGI_STATUS_OCCLUDED: + // Do not render until we become visible again + return DeviceState::Lost; + + case DXGI_ERROR_DEVICE_RESET: + return DeviceState::NeedReset; + + case DXGI_ERROR_DEVICE_REMOVED: + FATAL("Graphics driver was updated or GPU was physically removed from computer.\n" + "Please, restart the game."); + break; + } } return DeviceState::Normal; diff --git a/src/Layers/xrRenderDX11/dx11HW.h b/src/Layers/xrRenderDX11/dx11HW.h index 116149d492b..9faac490c2d 100644 --- a/src/Layers/xrRenderDX11/dx11HW.h +++ b/src/Layers/xrRenderDX11/dx11HW.h @@ -35,7 +35,7 @@ class CHW return SelectFormat(feature, formats, count); } bool UsingFlipPresentationModel() const; - DeviceState GetDeviceState() const; + DeviceState GetDeviceState(); public: void BeginScene(); @@ -100,6 +100,7 @@ class CHW #endif private: DXGI_SWAP_CHAIN_DESC m_ChainDesc; // DevPP equivalent + bool doPresentTest{}; XRay::Module hD3DCompiler; XRay::Module hDXGI; XRay::Module hD3D; From f8de69580f69e4909b1c836b21b2cb6d5aa06ae0 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Sun, 18 Feb 2024 21:01:10 +0500 Subject: [PATCH 170/497] AppVeyor: removed Ubuntu configuration I couldn't get it to work --- appveyor.yml | 58 ---------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1a9c1f004b7..621b7c74a1c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,6 @@ skip_branch_with_pr: true image: - Visual Studio 2022 -- Ubuntu configuration: - Debug @@ -24,66 +23,9 @@ branches: except: - dependabot/* -matrix: - exclude: - - image: Ubuntu - platform: x86 - - image: Ubuntu - configuration: Mixed - - image: Ubuntu - configuration: Release Master Gold - cache: - src/packages -> **/packages.config -for: -- - matrix: - only: - - image: Visual Studio 2022 - - before_build: - - git submodule update --init --recursive - - nuget restore src\engine.sln - - build: - project: src/engine.sln - parallel: true - verbosity: minimal - - after_build: - - cmd: misc/windows/xr_pack_build.cmd "%CONFIGURATION%" "%PLATFORM%" - - artifacts: - - path: res/OpenXRay.*.7z - name: OpenXRay.*.7z - - path: res/Symbols.*.7z - name: Symbols.*.7z - - path: res/Utils.*.7z - name: Utils.*.7z -- - matrix: - only: - - image: Ubuntu - - before_build: - - sudo apt-get update - - sudo apt-get install -y libsdl2-dev libglew-dev liblzo2-dev libjpeg-dev libopenal-dev libogg-dev libtheora-dev libvorbis-dev - - git submodule update --init --recursive - - build_script: - - ${CXX} --version - - cmake --version - - export core_count=$(nproc || echo 4) && echo core_count = $core_count - - CFLAGS="-w" CXXFLAGS="-w" cmake -B build -DCMAKE_BUILD_TYPE=$BUILD_CONFIGURATION - - cmake --build build --config $BUILD_CONFIGURATION --parallel $core_count - - cpack -B artifacts -C $BUILD_CONFIGURATION -DCPACK_THREADS=$core_count - - file openxray_1.6.02_*.deb - - artifacts: - - path: bin/openxray_1.6.02_*.deb - name: openxray_1.6.02_*.deb - test: off deploy: From 568e64656dfd2f811322d9d92753fee4b7b12241 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 18 Feb 2024 21:42:29 +0500 Subject: [PATCH 171/497] xrEngine/device.cpp: constify variables --- src/xrEngine/device.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 8261cb97ee0..6c1d3ac2a5c 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -108,7 +108,7 @@ void CRenderDevice::RenderEnd(void) CheckPrivilegySlowdown(); if (g_pGamePersistent->GameType() == 1 && !psDeviceFlags.test(rsAlwaysActive)) // haCk { - Uint32 flags = SDL_GetWindowFlags(m_sdlWnd); + const Uint32 flags = SDL_GetWindowFlags(m_sdlWnd); if ((flags & SDL_WINDOW_INPUT_FOCUS) == 0) Pause(true, true, true, "application start"); } @@ -163,14 +163,14 @@ void CRenderDevice::CalcFrameStats() // calc FPS & TPS if (fTimeDelta <= EPS_S) break; - float fps = 1.f / fTimeDelta; + const float fps = 1.f / fTimeDelta; // if (Engine.External.tune_enabled) vtune.update (fps); - float fOne = 0.3f; - float fInv = 1.0f - fOne; + constexpr float fOne = 0.3f; + constexpr float fInv = 1.0f - fOne; stats.fFPS = fInv * stats.fFPS + fOne * fps; if (stats.RenderTotal.result > EPS_S) { - u32 renderedPolys = GEnv.Render->GetCacheStatPolys(); + const u32 renderedPolys = GEnv.Render->GetCacheStatPolys(); stats.fTPS = fInv * stats.fTPS + fOne * float(renderedPolys) / (stats.RenderTotal.result * 1000.f); stats.fRFPS = fInv * stats.fRFPS + fOne * 1000.f / stats.RenderTotal.result; } @@ -214,8 +214,8 @@ void CRenderDevice::BeforeRender() // Precache if (dwPrecacheFrame) { - float factor = float(dwPrecacheFrame) / float(dwPrecacheTotal); - float angle = PI_MUL_2 * factor; + const float factor = float(dwPrecacheFrame) / float(dwPrecacheTotal); + const float angle = PI_MUL_2 * factor; vCameraDirection.set(_sin(angle), 0, _cos(angle)); vCameraDirection.normalize(); vCameraTop.set(0, 1, 0); @@ -378,11 +378,11 @@ void CRenderDevice::Run() dwTimeGlobal = 0; Timer_MM_Delta = 0; { - u32 time_mm = CPU::GetTicks(); + const u32 time_mm = CPU::GetTicks(); while (CPU::GetTicks() == time_mm) ; // wait for next tick - u32 time_system = CPU::GetTicks(); - u32 time_local = TimerAsync(); + const u32 time_system = CPU::GetTicks(); + const u32 time_local = TimerAsync(); Timer_MM_Delta = time_system - time_local; } @@ -429,7 +429,7 @@ void CRenderDevice::FrameMove() else { // Timer - float fPreviousFrameTime = Timer.GetElapsed_sec(); + const float fPreviousFrameTime = Timer.GetElapsed_sec(); Timer.Start(); // previous frame fTimeDelta = 0.1f * fTimeDelta + 0.9f * fPreviousFrameTime; // smooth random system activity - worst case ~7% error @@ -442,7 +442,7 @@ void CRenderDevice::FrameMove() fTimeDelta = 0.0f; // u64 qTime = TimerGlobal.GetElapsed_clk(); fTimeGlobal = TimerGlobal.GetElapsed_sec(); // float(qTime)*CPU::cycles2seconds; - u32 _old_global = dwTimeGlobal; + const u32 _old_global = dwTimeGlobal; dwTimeGlobal = TimerGlobal.GetElapsed_ms(); dwTimeDelta = dwTimeGlobal - _old_global; } From 524b616dda6b8a853b11e36180283bedb8407a0f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 18 Feb 2024 22:18:16 +0500 Subject: [PATCH 172/497] Added real time delta value to CRenderDevice We can now normally calculate real FPS. This could be useful in other scenarios also. --- src/xrEngine/device.cpp | 28 ++++++++++++++-------------- src/xrEngine/device.h | 1 + 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 6c1d3ac2a5c..e6a79f64c09 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -161,9 +161,9 @@ void CRenderDevice::CalcFrameStats() do { // calc FPS & TPS - if (fTimeDelta <= EPS_S) + if (fTimeDeltaReal <= EPS_S) break; - const float fps = 1.f / fTimeDelta; + const float fps = 1.f / fTimeDeltaReal; // if (Engine.External.tune_enabled) vtune.update (fps); constexpr float fOne = 0.3f; constexpr float fInv = 1.0f - fOne; @@ -413,6 +413,12 @@ void CRenderDevice::FrameMove() dwFrame++; Core.dwFrame = dwFrame; dwTimeContinual = TimerMM.GetElapsed_ms() - app_inactive_time; + + fTimeDeltaReal = Timer.GetElapsed_sec(); + if (!_valid(fTimeDeltaReal)) + fTimeDeltaReal = EPS_S + EPS_S; + Timer.Start(); // previous frame + if (psDeviceFlags.test(rsConstantFPS)) { // 20ms = 50fps @@ -428,20 +434,14 @@ void CRenderDevice::FrameMove() } else { - // Timer - const float fPreviousFrameTime = Timer.GetElapsed_sec(); - Timer.Start(); // previous frame - fTimeDelta = - 0.1f * fTimeDelta + 0.9f * fPreviousFrameTime; // smooth random system activity - worst case ~7% error - // fTimeDelta = 0.7f * fTimeDelta + 0.3f*fPreviousFrameTime; // smooth random system activity - if (fTimeDelta > .1f) - fTimeDelta = .1f; // limit to 15fps minimum - if (fTimeDelta <= 0.f) - fTimeDelta = EPS_S + EPS_S; // limit to 15fps minimum if (Paused()) fTimeDelta = 0.0f; - // u64 qTime = TimerGlobal.GetElapsed_clk(); - fTimeGlobal = TimerGlobal.GetElapsed_sec(); // float(qTime)*CPU::cycles2seconds; + else + { + fTimeDelta = 0.1f * fTimeDelta + 0.9f * fTimeDeltaReal; // smooth random system activity - worst case ~7% error + clamp(fTimeDelta, EPS_S + EPS_S, .1f); // limit to 10fps minimum + } + fTimeGlobal = TimerGlobal.GetElapsed_sec(); const u32 _old_global = dwTimeGlobal; dwTimeGlobal = TimerGlobal.GetElapsed_ms(); dwTimeDelta = dwTimeGlobal - _old_global; diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 76433627257..85ef7373a35 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -121,6 +121,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler public: // Engine flow-control float fTimeDelta{}; + float fTimeDeltaReal{}; float fTimeGlobal{}; u32 dwTimeDelta{}; u32 dwTimeGlobal{}; From e56a54456baa8f902b632b7f1ee931631659c99d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 18 Feb 2024 22:32:04 +0500 Subject: [PATCH 173/497] xrEngine/xr_input.cpp: improve robustness of KbdKeyToButtonName --- src/xrEngine/xr_input.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index be932c6e2ac..645ef16312a 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -434,25 +434,29 @@ void CInput::ControllerUpdate() checkAxis(XR_CONTROLLER_AXIS_TRIGGER_RIGHT, controllerAxisState[5], 0, controllerAxisStatePrev[5], 0); } -bool KbdKeyToButtonName(const int dik, xr_string& name) +bool KbdKeyToButtonName(const int dik, xr_string& result) { static std::locale locale(""); if (dik >= 0) { - name = StringFromUTF8(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)dik)), locale); - return true; + cpcstr name = SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)dik)); + if (name && name[0]) + { + result = StringFromUTF8(name, locale); + return true; + } } return false; } -bool OtherDevicesKeyToButtonName(const int btn, xr_string& name) +bool OtherDevicesKeyToButtonName(const int btn, xr_string& /*result*/) { if (btn > CInput::COUNT_KB_BUTTONS) { // XXX: Not implemented - return false; // true; + return false; } return false; From 4c0c1b1b0064352ecc228722c08eb58e3fb78de2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 18 Feb 2024 22:50:16 +0500 Subject: [PATCH 174/497] xrCore/xrDebug.cpp cleaned up defines --- src/xrCore/xrDebug.cpp | 96 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 197e1ae300f..be35a07dcc2 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -6,58 +6,15 @@ #include "log.h" #include "Threading/ScopeLock.hpp" -#if defined(XR_PLATFORM_WINDOWS) -#include "Debug/dxerr.h" -#include "Debug/MiniDump.h" -#endif - #include -#ifdef XR_PLATFORM_WINDOWS -# define USE_BUG_TRAP -static BOOL bException = FALSE; -#endif - -#ifdef USE_BUG_TRAP -# include -#else -# include -#endif - #include #if defined(XR_PLATFORM_WINDOWS) # include # include // for _set_new_mode # include // ReportFault -#elif defined(XR_PLATFORM_LINUX) -# include -# include -# include -# include -# if __has_include() -# include -# endif -#elif defined(XR_PLATFORM_APPLE) -# include -# include -# define PTRACE_TRACEME PT_TRACE_ME -# define PTRACE_DETACH PT_DETACH -#elif defined(XR_PLATFORM_BSD) -# include -# include -# include -# include -# include -# define PTRACE_TRACEME PT_TRACE_ME -# define PTRACE_DETACH PT_DETACH -#endif - -#ifdef DEBUG -#define USE_OWN_ERROR_MESSAGE_WINDOW -#endif -#if defined(XR_PLATFORM_WINDOWS) # if defined(XR_ARCHITECTURE_X86) # define MACHINE_TYPE IMAGE_FILE_MACHINE_I386 # elif defined(XR_ARCHITECTURE_X64) @@ -71,7 +28,44 @@ static BOOL bException = FALSE; # else # error CPU architecture is not supported. # endif -#endif // XR_PLATFORM_WINDOWS + +# define USE_BUG_TRAP +# ifdef USE_BUG_TRAP +# include +# else +# include +# endif + +# include "Debug/dxerr.h" +# include "Debug/MiniDump.h" +#endif + +#if defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_APPLE) || defined(XR_PLATFORM_BSD) +# if __has_include() +# include +# define BACKTRACE_AVAILABLE + +# if __has_include() +# include +# include +# define CXXABI_AVAILABLE +# endif +# endif + +# if __has_include() +# include +# define PTRACE_AVAILABLE + +# ifdef defined(XR_PLATFORM_APPLE) || defined(XR_PLATFORM_BSD) +# define PTRACE_TRACEME PT_TRACE_ME +# define PTRACE_DETACH PT_DETACH +# endif +# endif +#endif + +#ifdef DEBUG +# define USE_OWN_ERROR_MESSAGE_WINDOW +#endif constexpr SDL_MessageBoxButtonData buttons[] = { @@ -434,10 +428,10 @@ void xrDebug::GatherInfo(char* assertionInfo, size_t bufferSize, const ErrorLoca buffer += xr_sprintf(buffer, oneAboveBuffer - buffer, "%s\n", stackTrace[i].c_str()); #endif // USE_OWN_ERROR_MESSAGE_WINDOW } -#elif defined(XR_PLATFORM_LINUX) && __has_include() || defined(XR_PLATFORM_BSD) - void *array[20]; - int nptrs = backtrace(array, 20); // get void*'s for all entries on the stack - char **strings = backtrace_symbols(array, nptrs); +#elif BACKTRACE_AVAILABLE + void* array[20]; + int nptrs = backtrace(array, 20); // get void*'s for all entries on the stack + char** strings = backtrace_symbols(array, nptrs); if (strings) { @@ -447,6 +441,7 @@ void xrDebug::GatherInfo(char* assertionInfo, size_t bufferSize, const ErrorLoca { char* functionName = strings[i]; +# ifdef CXXABI_AVAILABLE Dl_info info; if (dladdr(array[i], &info)) @@ -461,6 +456,7 @@ void xrDebug::GatherInfo(char* assertionInfo, size_t bufferSize, const ErrorLoca } } } +# endif Log(functionName); # ifdef USE_OWN_ERROR_MESSAGE_WINDOW buffer += xr_sprintf(buffer, bufferSize, "%s\n", functionName); @@ -736,11 +732,13 @@ bool xrDebug::DebuggerIsPresent() { #ifdef XR_PLATFORM_WINDOWS return IsDebuggerPresent(); -#else +#elif defined(PTRACE_AVAILABLE) if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) return true; ptrace(PTRACE_DETACH, 0, 0, 0); return false; +#else + return false; #endif } From 8d87872127cad006c15fa80dacebafb7ce77b3e6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 19 Feb 2024 01:44:56 +0500 Subject: [PATCH 175/497] Wrap thread priority manipulations --- src/xrCore/Threading/TaskManager.cpp | 14 ++--- src/xrCore/Threading/ThreadUtil.cpp | 87 ++++++++++++++++++++++++++-- src/xrCore/Threading/ThreadUtil.h | 28 ++++++++- src/xrNetServer/NET_Client.cpp | 2 +- 4 files changed, 115 insertions(+), 16 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 54859dcc900..9a53aa845fa 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -172,25 +172,19 @@ static TaskWorker* s_main_thread_worker = nullptr; class ThreadPriorityHelper { -#ifdef XR_PLATFORM_WINDOWS - DWORD m_priority; + Threading::priority_class m_priority; public: ThreadPriorityHelper() - : m_priority(GetPriorityClass(GetCurrentProcess())) + : m_priority(Threading::GetCurrentProcessPriorityClass()) { - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + Threading::SetCurrentProcessPriorityClass(Threading::priority_class::realtime); } ~ThreadPriorityHelper() { - SetPriorityClass(GetCurrentProcess(), m_priority); + Threading::SetCurrentProcessPriorityClass(m_priority); } -#else - // XXX: add other platforms -public: - ThreadPriorityHelper() = default; -#endif }; // Get fast spin-loop timings diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index a3ca491d3b0..1268f42618e 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -30,8 +30,6 @@ namespace Threading #if defined(XR_PLATFORM_WINDOWS) ThreadId GetCurrThreadId() { return GetCurrentThreadId(); } -ThreadHandle GetCurrentThreadHandle() { return GetCurrentThread(); } - bool ThreadIdsAreEqual(ThreadId left, ThreadId right) { return left == right; } void SetThreadNameImpl(DWORD threadId, pcstr name) @@ -72,6 +70,69 @@ void SetCurrentThreadName(pcstr name) SetThreadNameImpl(-1, name); } +priority_level GetCurrentThreadPriorityLevel() +{ + switch (GetThreadPriority(GetCurrentThread())) + { + case THREAD_PRIORITY_IDLE: return priority_level::idle; + case THREAD_PRIORITY_LOWEST: return priority_level::lowest; + case THREAD_PRIORITY_BELOW_NORMAL: return priority_level::below_normal; + default: [[fallthrough]] + case THREAD_PRIORITY_NORMAL: return priority_level::normal; + case THREAD_PRIORITY_ABOVE_NORMAL: return priority_level::above_normal; + case THREAD_PRIORITY_HIGHEST: return priority_level::highest; + case THREAD_PRIORITY_TIME_CRITICAL: return priority_level::time_critical; + + } +} + +priority_class GetCurrentProcessPriorityClass() +{ + switch (GetPriorityClass(GetCurrentProcess())) + { + case IDLE_PRIORITY_CLASS: return priority_class::idle; + case BELOW_NORMAL_PRIORITY_CLASS: return priority_class::below_normal; + default: [[fallthrough]] + case NORMAL_PRIORITY_CLASS: return priority_class::normal; + case ABOVE_NORMAL_PRIORITY_CLASS: return priority_class::above_normal; + case HIGH_PRIORITY_CLASS: return priority_class::high; + case REALTIME_PRIORITY_CLASS: return priority_class::realtime; + } +} + +void SetCurrentThreadPriorityLevel(priority_level prio) +{ + int nPriority; + switch (prio) + { + case priority_level::idle: nPriority = THREAD_PRIORITY_IDLE; break; + case priority_level::lowest: nPriority = THREAD_PRIORITY_LOWEST; break; + case priority_level::below_normal: nPriority = THREAD_PRIORITY_BELOW_NORMAL; break; + default: [[fallthrough]] + case priority_level::normal: nPriority = THREAD_PRIORITY_NORMAL; break; + case priority_level::above_normal: nPriority = THREAD_PRIORITY_ABOVE_NORMAL; break; + case priority_level::highest: nPriority = THREAD_PRIORITY_HIGHEST; break; + case priority_level::time_critical: nPriority = THREAD_PRIORITY_TIME_CRITICAL; break; + } + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); +} + +void SetCurrentProcessPriorityClass(priority_class cls) +{ + DWORD dwPriorityClass; + switch (cls) + { + case priority_class::idle: dwPriorityClass = IDLE_PRIORITY_CLASS; break; + case priority_class::below_normal: dwPriorityClass = BELOW_NORMAL_PRIORITY_CLASS; break; + default: [[fallthrough]] + case priority_class::normal: dwPriorityClass = NORMAL_PRIORITY_CLASS; break; + case priority_class::above_normal: dwPriorityClass = ABOVE_NORMAL_PRIORITY_CLASS; break; + case priority_class::high: dwPriorityClass = HIGH_PRIORITY_CLASS; break; + case priority_class::realtime: dwPriorityClass = REALTIME_PRIORITY_CLASS; break; + } + SetPriorityClass(GetCurrentProcess(), dwPriorityClass); +} + u32 __stdcall ThreadEntry(void* params) { SThreadStartupInfo* args = (SThreadStartupInfo*)params; @@ -121,8 +182,6 @@ void CloseThreadHandle(ThreadHandle& threadHandle) #elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) ThreadId GetCurrThreadId() { return pthread_self(); } -ThreadHandle GetCurrentThreadHandle() { return pthread_self(); } - bool ThreadIdsAreEqual(ThreadId left, ThreadId right) { return !!pthread_equal(left, right); } void SetCurrentThreadName(pcstr name) @@ -133,6 +192,26 @@ void SetCurrentThreadName(pcstr name) } } +priority_level GetCurrentThreadPriorityLevel() +{ + return priority_level::normal; +} + +priority_class GetCurrentProcessPriorityClass() +{ + return priority_class::normal; +} + +void SetCurrentThreadPriorityLevel(priority_level prio) +{ + +} + +void SetCurrentProcessPriorityClass(priority_class cls) +{ + +} + void* __cdecl ThreadEntry(void* params) { SThreadStartupInfo* args = (SThreadStartupInfo*)params; diff --git a/src/xrCore/Threading/ThreadUtil.h b/src/xrCore/Threading/ThreadUtil.h index ba830574bda..5ee3fa60c54 100644 --- a/src/xrCore/Threading/ThreadUtil.h +++ b/src/xrCore/Threading/ThreadUtil.h @@ -5,6 +5,27 @@ namespace Threading { +enum class priority_class +{ + idle, + below_normal, + normal, + above_normal, + high, + realtime, +}; + +enum class priority_level +{ + idle, + lowest, + below_normal, + normal, + above_normal, + highest, + time_critical, +}; + #ifdef XR_PLATFORM_WINDOWS using ThreadHandle = HANDLE; using ThreadId = u32; @@ -24,12 +45,17 @@ struct SThreadStartupInfo ////////////////////////////////////////////////////////////// XRCORE_API ThreadId GetCurrThreadId(); -XRCORE_API ThreadHandle GetCurrentThreadHandle(); XRCORE_API bool ThreadIdsAreEqual(ThreadId left, ThreadId right); XRCORE_API void SetCurrentThreadName(pcstr name); +XRCORE_API priority_level GetCurrentThreadPriorityLevel(); +XRCORE_API priority_class GetCurrentProcessPriorityClass(); + +XRCORE_API void SetCurrentThreadPriorityLevel(priority_level prio); +XRCORE_API void SetCurrentProcessPriorityClass(priority_class cls); + XRCORE_API bool SpawnThread(EntryFuncType entry, pcstr name, u32 stack, void* arglist); XRCORE_API void WaitThread(ThreadHandle& threadHandle); diff --git a/src/xrNetServer/NET_Client.cpp b/src/xrNetServer/NET_Client.cpp index 600433e2288..bb4808d35a8 100644 --- a/src/xrNetServer/NET_Client.cpp +++ b/src/xrNetServer/NET_Client.cpp @@ -1076,7 +1076,7 @@ void IPureClient::net_Syncronize() net_DeltaArray.clear(); Threading::SpawnThread([](void* P) { - SetThreadPriority(Threading::GetCurrentThreadHandle(), THREAD_PRIORITY_TIME_CRITICAL); + Threading::SetCurrentThreadPriorityLevel(Threading::priority_level::time_critical); IPureClient* C = static_cast(P); C->Sync_Thread(); }, "network-time-sync", 0, this); From d6edf634e16233b77f9d2a14b61b2696171f08ef Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 19 Feb 2024 03:09:00 +0500 Subject: [PATCH 176/497] Fix compilation --- src/xrCore/Threading/ThreadUtil.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 1268f42618e..4be4c8006cb 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -77,12 +77,11 @@ priority_level GetCurrentThreadPriorityLevel() case THREAD_PRIORITY_IDLE: return priority_level::idle; case THREAD_PRIORITY_LOWEST: return priority_level::lowest; case THREAD_PRIORITY_BELOW_NORMAL: return priority_level::below_normal; - default: [[fallthrough]] + default: [[fallthrough]]; case THREAD_PRIORITY_NORMAL: return priority_level::normal; case THREAD_PRIORITY_ABOVE_NORMAL: return priority_level::above_normal; case THREAD_PRIORITY_HIGHEST: return priority_level::highest; case THREAD_PRIORITY_TIME_CRITICAL: return priority_level::time_critical; - } } @@ -92,7 +91,7 @@ priority_class GetCurrentProcessPriorityClass() { case IDLE_PRIORITY_CLASS: return priority_class::idle; case BELOW_NORMAL_PRIORITY_CLASS: return priority_class::below_normal; - default: [[fallthrough]] + default: [[fallthrough]]; case NORMAL_PRIORITY_CLASS: return priority_class::normal; case ABOVE_NORMAL_PRIORITY_CLASS: return priority_class::above_normal; case HIGH_PRIORITY_CLASS: return priority_class::high; @@ -108,7 +107,7 @@ void SetCurrentThreadPriorityLevel(priority_level prio) case priority_level::idle: nPriority = THREAD_PRIORITY_IDLE; break; case priority_level::lowest: nPriority = THREAD_PRIORITY_LOWEST; break; case priority_level::below_normal: nPriority = THREAD_PRIORITY_BELOW_NORMAL; break; - default: [[fallthrough]] + default: [[fallthrough]]; case priority_level::normal: nPriority = THREAD_PRIORITY_NORMAL; break; case priority_level::above_normal: nPriority = THREAD_PRIORITY_ABOVE_NORMAL; break; case priority_level::highest: nPriority = THREAD_PRIORITY_HIGHEST; break; @@ -124,7 +123,7 @@ void SetCurrentProcessPriorityClass(priority_class cls) { case priority_class::idle: dwPriorityClass = IDLE_PRIORITY_CLASS; break; case priority_class::below_normal: dwPriorityClass = BELOW_NORMAL_PRIORITY_CLASS; break; - default: [[fallthrough]] + default: [[fallthrough]]; case priority_class::normal: dwPriorityClass = NORMAL_PRIORITY_CLASS; break; case priority_class::above_normal: dwPriorityClass = ABOVE_NORMAL_PRIORITY_CLASS; break; case priority_class::high: dwPriorityClass = HIGH_PRIORITY_CLASS; break; From 344aa8a54739892b4e4ae5e3fcdc24512f7bd05b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 19 Feb 2024 03:24:34 +0500 Subject: [PATCH 177/497] Fix Linux compilation --- src/xrCore/xrDebug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index be35a07dcc2..235b4387768 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -428,7 +428,7 @@ void xrDebug::GatherInfo(char* assertionInfo, size_t bufferSize, const ErrorLoca buffer += xr_sprintf(buffer, oneAboveBuffer - buffer, "%s\n", stackTrace[i].c_str()); #endif // USE_OWN_ERROR_MESSAGE_WINDOW } -#elif BACKTRACE_AVAILABLE +#elif defined(BACKTRACE_AVAILABLE) void* array[20]; int nptrs = backtrace(array, 20); // get void*'s for all entries on the stack char** strings = backtrace_symbols(array, nptrs); From 95c28860694d95ffb22ff38f3b92baecc5864572 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 19 Feb 2024 03:25:04 +0500 Subject: [PATCH 178/497] xrCore/xrDebug.cpp: removed excess ifdef --- src/xrCore/xrDebug.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 235b4387768..19bf97173c9 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -169,13 +169,7 @@ Lock xrDebug::failLock(MUTEX_PROFILE_ID(xrDebug::Backend)); Lock xrDebug::failLock; #endif -#if defined(XR_PLATFORM_WINDOWS) void xrDebug::SetBugReportFile(const char* fileName) { xr_strcpy(BugReportFile, fileName); } -#elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) -void xrDebug::SetBugReportFile(const char* fileName) { xr_strcpy(BugReportFile, 0, fileName); } -#else -# error Select or add implementation for your platform -#endif #if defined(XR_PLATFORM_WINDOWS) bool xrDebug::GetNextStackFrameString(LPSTACKFRAME stackFrame, PCONTEXT threadCtx, xr_string& frameStr) From fc8076580d8bd96076078c8fa4601b495a245306 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 19 Feb 2024 03:33:55 +0500 Subject: [PATCH 179/497] Fix *BSD and macOS compilation --- src/xrCore/xrDebug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 19bf97173c9..5799aeac99b 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -56,7 +56,7 @@ # include # define PTRACE_AVAILABLE -# ifdef defined(XR_PLATFORM_APPLE) || defined(XR_PLATFORM_BSD) +# if defined(XR_PLATFORM_APPLE) || defined(XR_PLATFORM_BSD) # define PTRACE_TRACEME PT_TRACE_ME # define PTRACE_DETACH PT_DETACH # endif From 363e0889431a60e7a83c2ab5c7d225c67576e2f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:06:04 +0000 Subject: [PATCH 180/497] build(deps): bump cross-platform-actions/action from 0.22.0 to 0.23.0 Bumps [cross-platform-actions/action](https://github.com/cross-platform-actions/action) from 0.22.0 to 0.23.0. - [Release notes](https://github.com/cross-platform-actions/action/releases) - [Changelog](https://github.com/cross-platform-actions/action/blob/master/changelog.md) - [Commits](https://github.com/cross-platform-actions/action/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: cross-platform-actions/action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/cibuild.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 3aa4fe4b531..d6f5036478e 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -196,7 +196,7 @@ jobs: submodules: recursive - name: Setup ${{ matrix.platform.name }} and packages - uses: cross-platform-actions/action@v0.22.0 + uses: cross-platform-actions/action@v0.23.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -209,7 +209,7 @@ jobs: run: ${{ matrix.platform.install-cmd }} - name: Run CMake - uses: cross-platform-actions/action@v0.22.0 + uses: cross-platform-actions/action@v0.23.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -222,7 +222,7 @@ jobs: run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON - name: Run CMake Build - uses: cross-platform-actions/action@v0.22.0 + uses: cross-platform-actions/action@v0.23.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} From fc0eeb840ac86639fed97c72e5148cc715630989 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 19 Feb 2024 17:58:45 +0500 Subject: [PATCH 181/497] GitHub Actions: Upgrade to the latest CPA with Linux hardware acceleration and FreeBSD 14.0 (#1617) --- .github/workflows/cibuild.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index d6f5036478e..3d751c56528 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -170,7 +170,7 @@ jobs: bsd: name: ${{ matrix.platform.name }} ${{ matrix.configuration }} ${{ matrix.platform.arch }} - runs-on: macos-13 # macOS 13 runner has 4 CPUs + runs-on: ubuntu-latest timeout-minutes: 35 env: CFLAGS: "-w" @@ -179,7 +179,7 @@ jobs: fail-fast: false matrix: platform: - - { name: FreeBSD, os: freebsd, os-version: 13.2, arch: x86_64, + - { name: FreeBSD, os: freebsd, os-version: '14.0', arch: x86_64, install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" } - { name: OpenBSD, os: openbsd, os-version: 7.4, arch: x86_64, @@ -202,7 +202,7 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 8G + memory: 13G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: runner-to-vm @@ -215,7 +215,7 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 8G + memory: 13G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false @@ -228,7 +228,7 @@ jobs: architecture: ${{ matrix.platform.arch }} version: ${{ matrix.platform.os-version }} cpu_count: 4 - memory: 8G + memory: 13G environment_variables: CFLAGS CXXFLAGS shutdown_vm: false sync_files: false From 0632d47ddf5a49b2a79da2e77c8a7bb66fbf0d98 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 19 Feb 2024 18:41:03 +0500 Subject: [PATCH 182/497] Disable CMake precompiled headers when Unity build is ON in CMake 3.28.2 --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 584e937f9e1..ae645c055fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,12 @@ if (CMAKE_VERBOSE_MAKEFILE) set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT) endif() +if (CMAKE_VERSION VERSION_EQUAL "3.28.2" AND CMAKE_UNITY_BUILD) + # https://gitlab.kitware.com/cmake/cmake/-/issues/25650 + message(WARNING "Precompiled headers are broken when Unity build is enabled in CMake 3.28.2. Please, update to CMake 3.28.3 or downgrade to 3.28.1.") + set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON) +endif() + if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) endif() From aed2394dbaab6dd36f7c8346a386a7fb4dcb55aa Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 19 Feb 2024 18:58:00 +0500 Subject: [PATCH 183/497] Disable CMake Unity build in CMake 3.28.2 This commit reimplements compilation fix from 0632d47ddf5a49b2a79da2e77c8a7bb66fbf0d98. --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae645c055fd..cfa8d64409b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,9 @@ endif() if (CMAKE_VERSION VERSION_EQUAL "3.28.2" AND CMAKE_UNITY_BUILD) # https://gitlab.kitware.com/cmake/cmake/-/issues/25650 - message(WARNING "Precompiled headers are broken when Unity build is enabled in CMake 3.28.2. Please, update to CMake 3.28.3 or downgrade to 3.28.1.") - set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON) + message(WARNING "In CMake 3.28.2, precompiled headers are broken when Unity build is enabled. This breaks project from compiling. \ + Please, update to CMake 3.28.3 or downgrade to 3.28.1.") + set(CMAKE_UNITY_BUILD OFF) endif() if (NOT CMAKE_BUILD_TYPE) From a78e8ed08c8dd2bc5f373b3736774d2255cdf4af Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 20 Feb 2024 07:09:21 +0500 Subject: [PATCH 184/497] Fix missing background in messages history window in CS (#382) --- src/xrGame/ui/UILogsWnd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/ui/UILogsWnd.cpp b/src/xrGame/ui/UILogsWnd.cpp index bdfc5d5195b..b0bf495af29 100644 --- a/src/xrGame/ui/UILogsWnd.cpp +++ b/src/xrGame/ui/UILogsWnd.cpp @@ -105,7 +105,7 @@ bool CUILogsWnd::Init() CUIXmlInit::InitWindow(m_uiXml, "main_wnd", 0, this); m_background = UIHelper::CreateFrameWindow(m_uiXml, "background", this, false); - if (m_background) + if (!m_background) m_background2 = UIHelper::CreateFrameLine(m_uiXml, "background", this, false); m_center_background = UIHelper::CreateFrameWindow(m_uiXml, "center_background", this, false); From d347c47f45b0ba9511af37bc62e91f090dcc57ff Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 20 Feb 2024 07:51:27 +0500 Subject: [PATCH 185/497] xrGame: simplify and modernize the code, remove unneeded variables in UI elements --- src/xrGame/UIZoneMap.cpp | 13 ++- src/xrGame/UIZoneMap.h | 6 +- src/xrGame/game_cl_mp_messages_menu.cpp | 11 +- src/xrGame/hit_immunity.cpp | 1 - src/xrGame/hit_immunity.h | 2 +- src/xrGame/ui/UICharacterInfo.cpp | 15 ++- src/xrGame/ui/UIEditKeyBind.h | 2 - src/xrGame/ui/UIKickPlayer.cpp | 28 ++--- src/xrGame/ui/UIKickPlayer.h | 4 +- src/xrGame/ui/UILogsWnd.cpp | 29 ++--- src/xrGame/ui/UILogsWnd.h | 34 +++--- src/xrGame/ui/UIMessagesWindow.cpp | 25 ++--- src/xrGame/ui/UIMessagesWindow.h | 19 ++-- src/xrGame/ui/UIMoneyIndicator.cpp | 13 +-- src/xrGame/ui/UIMoneyIndicator.h | 8 +- src/xrGame/ui/UIRankingWnd.cpp | 90 ++++++---------- src/xrGame/ui/UIRankingWnd.h | 42 +++----- src/xrGame/ui/UIScriptWnd.cpp | 22 ++-- src/xrGame/ui/UIScriptWnd.h | 16 ++- src/xrGame/ui/UIScriptWnd_script.cpp | 32 +++--- src/xrGame/ui/UISecondTaskWnd.cpp | 78 ++++++-------- src/xrGame/ui/UISecondTaskWnd.h | 37 +++---- src/xrGame/ui/UITaskWnd.cpp | 40 +++---- src/xrGame/ui/UITaskWnd.h | 42 +++----- src/xrUICore/ComboBox/UIComboBox.cpp | 25 ++--- src/xrUICore/ComboBox/UIComboBox.h | 5 +- src/xrUICore/ScrollBar/UIFixedScrollBar.cpp | 33 +++--- src/xrUICore/ScrollBar/UIFixedScrollBar.h | 7 +- src/xrUICore/ScrollBar/UIScrollBar.cpp | 81 +++++++------- src/xrUICore/ScrollBar/UIScrollBar.h | 38 +++---- src/xrUICore/ScrollView/UIScrollView.cpp | 114 +++++++++----------- src/xrUICore/ScrollView/UIScrollView.h | 38 +++---- src/xrUICore/Windows/UIWindow.h | 2 +- 33 files changed, 398 insertions(+), 554 deletions(-) diff --git a/src/xrGame/UIZoneMap.cpp b/src/xrGame/UIZoneMap.cpp index 777e17ff01d..a7dff759555 100644 --- a/src/xrGame/UIZoneMap.cpp +++ b/src/xrGame/UIZoneMap.cpp @@ -116,7 +116,7 @@ void CUIZoneMap::Render() void CUIZoneMap::Update() { - CActor* pActor = smart_cast(Level().CurrentViewEntity()); + const auto* pActor = smart_cast(Level().CurrentViewEntity()); if (!pActor) return; @@ -125,10 +125,9 @@ void CUIZoneMap::Update() string16 text_str; xr_strcpy(text_str, sizeof(text_str), ""); - CPda* pda = pActor->GetPDA(); - if (pda) + if (CPda* pda = pActor->GetPDA()) { - u32 cn = pda->ActiveContactsNum(); + const u32 cn = pda->ActiveContactsNum(); if (cn > 0) { xr_sprintf(text_str, sizeof(text_str), "%d", cn); @@ -144,8 +143,7 @@ void CUIZoneMap::Update() if (m_clock_wnd) { - m_clock_wnd->TextItemControl()->SetText( - InventoryUtilities::GetGameTimeAsString(InventoryUtilities::etpTimeToMinutes).c_str()); + m_clock_wnd->SetText(GetGameTimeAsString(InventoryUtilities::etpTimeToMinutes).c_str()); } } @@ -178,6 +176,7 @@ void CUIZoneMap::UpdateRadar(Fvector pos) bool CUIZoneMap::ZoomIn() { return true; } bool CUIZoneMap::ZoomOut() { return true; } + void CUIZoneMap::SetupCurrentMap() { m_activeMap->Initialize(Level().name(), "hud" DELIMITER "default"); @@ -189,7 +188,7 @@ void CUIZoneMap::SetupCurrentMap() Fvector2 wnd_size; float zoom_factor = float(m_clipFrame.GetWidth()) / 100.0f; - LPCSTR ln = Level().name().c_str(); + cpcstr ln = Level().name().c_str(); if (pGameIni->section_exist(ln)) { if (pGameIni->line_exist(ln, "minimap_zoom")) diff --git a/src/xrGame/UIZoneMap.h b/src/xrGame/UIZoneMap.h index fcbe6f79c56..43492b60941 100644 --- a/src/xrGame/UIZoneMap.h +++ b/src/xrGame/UIZoneMap.h @@ -25,8 +25,6 @@ class CUIZoneMap u8 m_current_map_idx{ u8(-1) }; public: - virtual ~CUIZoneMap() = default; - void Init(bool motionIconAttached); void Render(); @@ -35,8 +33,8 @@ class CUIZoneMap bool ZoomIn(); bool ZoomOut(); - CUIStatic& Background() { return m_background; }; - CUIWindow& MapFrame() { return m_clipFrame; }; + CUIStatic& Background() { return m_background; } + CUIWindow& MapFrame() { return m_clipFrame; } void SetupCurrentMap(); void OnSectorChanged(IRender_Sector::sector_id_t sector); void Counter_ResetClrAnimation(); diff --git a/src/xrGame/game_cl_mp_messages_menu.cpp b/src/xrGame/game_cl_mp_messages_menu.cpp index 894ea9934c7..095c76b7fc2 100644 --- a/src/xrGame/game_cl_mp_messages_menu.cpp +++ b/src/xrGame/game_cl_mp_messages_menu.cpp @@ -174,16 +174,17 @@ void game_cl_mp::OnSpeechMessage(NET_Packet& P) if (ps->team == local_player->team) { if (CurrentGameUI()) + { CurrentGameUI()->m_pMessagesWnd->AddChatMessage( - StringTable().translate(pMMessage->pMessage.c_str()).c_str(), ps->getName()); - + StringTable().translate(pMMessage->pMessage), ps->getName()); + } if (!Level().MapManager().HasMapLocation(FRIEND_RADION_LOCATION, ps->GameID)) { (Level().MapManager().AddMapLocation(FRIEND_RADION_LOCATION, ps->GameID))->EnablePointer(); } } - u8 VariantID = P.r_u8(); + const u8 VariantID = P.r_u8(); if (pMMessage->aVariants.empty()) return; if (VariantID && VariantID >= pMMessage->aVariants.size()) @@ -195,11 +196,11 @@ void game_cl_mp::OnSpeechMessage(NET_Packet& P) { if (ps == local_player) { - pMSound->mSound_Voice.play_at_pos(NULL, Fvector().set(0, 0, 0), sm_2D, 0); + pMSound->mSound_Voice.play_at_pos(nullptr, Fvector().set(0, 0, 0), sm_2D, 0); } else { - pMSound->mSound_Radio.play_at_pos(NULL, Fvector().set(0, 0, 0), sm_2D, 0); + pMSound->mSound_Radio.play_at_pos(nullptr, Fvector().set(0, 0, 0), sm_2D, 0); } Msg("%s said: %s", ps->getName(), *StringTable().translate(pMMessage->pMessage)); } diff --git a/src/xrGame/hit_immunity.cpp b/src/xrGame/hit_immunity.cpp index c58abaa1f12..efaf0e5cb89 100644 --- a/src/xrGame/hit_immunity.cpp +++ b/src/xrGame/hit_immunity.cpp @@ -12,7 +12,6 @@ CHitImmunity::CHitImmunity() m_HitImmunityKoefs[i] = 1.0f; } -CHitImmunity::~CHitImmunity() {} void CHitImmunity::LoadImmunities(const char* imm_sect, const CInifile* ini) { R_ASSERT2(ini->section_exist(imm_sect), imm_sect); diff --git a/src/xrGame/hit_immunity.h b/src/xrGame/hit_immunity.h index 6ce1a2b6d26..7c8c7211bd6 100644 --- a/src/xrGame/hit_immunity.h +++ b/src/xrGame/hit_immunity.h @@ -19,7 +19,7 @@ class CHitImmunity public: CHitImmunity(); - virtual ~CHitImmunity(); + virtual ~CHitImmunity() = default; void LoadImmunities(const char* section, const CInifile* ini); void AddImmunities(const char* section, const CInifile* ini); diff --git a/src/xrGame/ui/UICharacterInfo.cpp b/src/xrGame/ui/UICharacterInfo.cpp index 41749859342..5c242e8e1a8 100644 --- a/src/xrGame/ui/UICharacterInfo.cpp +++ b/src/xrGame/ui/UICharacterInfo.cpp @@ -84,8 +84,7 @@ void CUICharacterInfo::InitCharacterInfo(Fvector2 pos, Fvector2 size, CUIXml* xm void CUICharacterInfo::Init_StrInfoItem(CUIXml& xml_doc, LPCSTR item_str, UIItemType type) { - CUIStatic* item = UIHelper::CreateStatic(xml_doc, item_str, this, false); - if (item) + if (CUIStatic* item = UIHelper::CreateStatic(xml_doc, item_str, this, false)) { m_icons[type] = item; } @@ -93,10 +92,8 @@ void CUICharacterInfo::Init_StrInfoItem(CUIXml& xml_doc, LPCSTR item_str, UIItem void CUICharacterInfo::Init_IconInfoItem(CUIXml& xml_doc, LPCSTR item_str, UIItemType type) { - CUIStatic* item = UIHelper::CreateStatic(xml_doc, item_str, this, false); - if (item) + if (CUIStatic* item = UIHelper::CreateStatic(xml_doc, item_str, this, false)) { - //. item->ClipperOn(); item->Show(true); m_icons[type] = item; } @@ -115,8 +112,8 @@ void CUICharacterInfo::InitCharacterInfo(Fvector2 pos, Fvector2 size, cpcstr xml void CUICharacterInfo::InitCharacterInfo(CUIXml* xml_doc, LPCSTR node_str) { Fvector2 pos, size; - XML_NODE stored_root = xml_doc->GetLocalRoot(); - XML_NODE ch_node = xml_doc->NavigateToNode(node_str, 0); + const XML_NODE stored_root = xml_doc->GetLocalRoot(); + const XML_NODE ch_node = xml_doc->NavigateToNode(node_str, 0); xml_doc->SetLocalRoot(ch_node); pos.x = xml_doc->ReadAttribFlt(ch_node, "x"); pos.y = xml_doc->ReadAttribFlt(ch_node, "y"); @@ -156,7 +153,7 @@ void CUICharacterInfo::InitCharacter(u16 id) if (pUIBio && pUIBio->IsEnabled()) { pUIBio->Clear(); - if (chInfo.Bio().size()) + if (!chInfo.Bio().empty()) { auto* pItem = xr_new("Biography"); pItem->SetWidth(pUIBio->GetDesiredChildWidth()); @@ -167,7 +164,7 @@ void CUICharacterInfo::InitCharacter(u16 id) } shared_str const& comm_id = chInfo.Community().id(); - LPCSTR community0 = comm_id.c_str(); + cpcstr community0 = comm_id.c_str(); string64 community1; xr_strcpy(community1, sizeof(community1), community0); xr_strcat(community1, sizeof(community1), "_icon"); diff --git a/src/xrGame/ui/UIEditKeyBind.h b/src/xrGame/ui/UIEditKeyBind.h index 92ef4bfb11f..8aec62f093c 100644 --- a/src/xrGame/ui/UIEditKeyBind.h +++ b/src/xrGame/ui/UIEditKeyBind.h @@ -47,6 +47,4 @@ class CUIEditKeyBind final : public CUIStatic, public CUIOptionsItem void BindAction2Key(); bool m_isEditMode; - - //. CUIColorAnimatorWrapper* m_pAnimation; }; diff --git a/src/xrGame/ui/UIKickPlayer.cpp b/src/xrGame/ui/UIKickPlayer.cpp index dc08e6ad4a9..b6133addc22 100644 --- a/src/xrGame/ui/UIKickPlayer.cpp +++ b/src/xrGame/ui/UIKickPlayer.cpp @@ -16,7 +16,6 @@ CUIKickPlayer::CUIKickPlayer() : CUIDialogWnd(CUIKickPlayer::GetDebugType()) { - m_prev_upd_time = 0; bkgrnd = xr_new("Background"); bkgrnd->SetAutoDelete(true); AttachChild(bkgrnd); @@ -50,8 +49,6 @@ CUIKickPlayer::CUIKickPlayer() m_ban_sec_label = xr_new("Ban time label"); m_ban_sec_label->SetAutoDelete(true); AttachChild(m_ban_sec_label); - - mode = MODE_KICK; } void CUIKickPlayer::Init_internal(CUIXml& xml_doc) @@ -98,7 +95,7 @@ void CUIKickPlayer::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { if (LIST_ITEM_SELECT == msg && pWnd == m_ui_players_list) { - CUIListBoxItem* itm = smart_cast(m_ui_players_list->GetSelected()); + auto* itm = smart_cast(m_ui_players_list->GetSelected()); m_selected_item_text = itm->GetText(); } else if (BUTTON_CLICKED == msg) @@ -112,8 +109,7 @@ void CUIKickPlayer::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) void CUIKickPlayer::OnBtnOk() { - CUIListBoxItem* item = smart_cast(m_ui_players_list->GetSelected()); - if (item) + if (auto* item = smart_cast(m_ui_players_list->GetSelected())) { string512 command; switch (mode) @@ -126,15 +122,11 @@ void CUIKickPlayer::OnBtnOk() Console->Execute(command); HideDialog(); } - else - return; } void CUIKickPlayer::OnBtnCancel() { HideDialog(); } IC bool DM_Compare_Players(game_PlayerState* v1, game_PlayerState* v2); -using ItemVec = xr_vector; - void CUIKickPlayer::Update() { CUIDialogWnd::Update(); @@ -146,20 +138,16 @@ void CUIKickPlayer::Update() const game_cl_GameState::PLAYERS_MAP& items = Game().players; - game_cl_GameState::PLAYERS_MAP_CIT I = items.begin(); - game_cl_GameState::PLAYERS_MAP_CIT E = items.end(); - bool bNeedRefresh = false; bool bHasSelected = false; - xr_vector::iterator fit; //, fite; - for (; I != E; ++I) + //, fite; + for (auto [cliend_id, pI] : items) { - game_PlayerState* pI = I->second; - if (m_selected_item_text.size() && !xr_stricmp(pI->getName(), m_selected_item_text.c_str())) + if (!m_selected_item_text.empty() && !xr_stricmp(pI->getName(), m_selected_item_text.c_str())) bHasSelected = true; - fit = std::find(m_current_set.begin(), m_current_set.end(), pI); + const auto fit = std::find(m_current_set.begin(), m_current_set.end(), pI); if (fit == m_current_set.end()) bNeedRefresh = true; else if (xr_stricmp((*fit)->getName(), pI->getName())) @@ -170,13 +158,11 @@ void CUIKickPlayer::Update() if (bNeedRefresh) { - I = items.begin(); m_ui_players_list->Clear(); m_current_set.clear(); - for (; I != E; ++I) + for (auto [cliend_id, p] : items) { - game_PlayerState* p = I->second; m_current_set.push_back(p); m_ui_players_list->AddTextItem(p->getName()); } diff --git a/src/xrGame/ui/UIKickPlayer.h b/src/xrGame/ui/UIKickPlayer.h index 03060b282db..e35e09a27be 100644 --- a/src/xrGame/ui/UIKickPlayer.h +++ b/src/xrGame/ui/UIKickPlayer.h @@ -32,7 +32,7 @@ class CUIKickPlayer final : public CUIDialogWnd void Init_internal(CUIXml& xml_doc); - E_MODE mode; + E_MODE mode{ MODE_KICK }; CUIStatic* bkgrnd; CUIStatic* header; @@ -44,7 +44,7 @@ class CUIKickPlayer final : public CUIDialogWnd CUI3tButton* btn_ok; CUI3tButton* btn_cancel; - u32 m_prev_upd_time; + u32 m_prev_upd_time{}; shared_str m_selected_item_text; xr_vector m_current_set; diff --git a/src/xrGame/ui/UILogsWnd.cpp b/src/xrGame/ui/UILogsWnd.cpp index b0bf495af29..cc1125e5794 100644 --- a/src/xrGame/ui/UILogsWnd.cpp +++ b/src/xrGame/ui/UILogsWnd.cpp @@ -26,17 +26,11 @@ #include "xrEngine/xr_input.h" #include "date_time.h" -#define PDA_LOGS_XML "pda_logs.xml" +constexpr pcstr PDA_LOGS_XML = "pda_logs.xml"; u64 constexpr day2ms = u64(24 * 60 * 60 * 1000); -CUILogsWnd::CUILogsWnd() : CUIWindow(CUILogsWnd::GetDebugType()) -{ - m_list = nullptr; - m_actor_ch_info = nullptr; - m_previous_time = Device.dwTimeGlobal; - m_selected_period = 0; -} +CUILogsWnd::CUILogsWnd() : CUIWindow(CUILogsWnd::GetDebugType()), m_previous_time(Device.dwTimeGlobal) {} CUILogsWnd::~CUILogsWnd() { @@ -104,10 +98,11 @@ bool CUILogsWnd::Init() CUIXmlInit::InitWindow(m_uiXml, "main_wnd", 0, this); - m_background = UIHelper::CreateFrameWindow(m_uiXml, "background", this, false); - if (!m_background) - m_background2 = UIHelper::CreateFrameLine(m_uiXml, "background", this, false); - m_center_background = UIHelper::CreateFrameWindow(m_uiXml, "center_background", this, false); + if (!UIHelper::CreateFrameWindow(m_uiXml, "background", this, false)) + std::ignore = UIHelper::CreateFrameLine(m_uiXml, "background", this, false); + + if (!UIHelper::CreateFrameWindow(m_uiXml, "center_background", this, false)) + std::ignore = UIHelper::CreateStatic(m_uiXml, "center_background", this, false); if (m_uiXml.NavigateToNode("actor_ch_info")) { @@ -117,14 +112,12 @@ bool CUILogsWnd::Init() m_actor_ch_info->InitCharacterInfo(&m_uiXml, "actor_ch_info"); } - if (!m_center_background) - m_center_background2 = UIHelper::CreateStatic(m_uiXml, "center_background", this, false); - m_center_caption = UIHelper::CreateStatic(m_uiXml, "center_caption", this); + auto* center_caption = UIHelper::CreateStatic(m_uiXml, "center_caption", this); string256 buf; - xr_strcpy(buf, sizeof(buf), m_center_caption->GetText()); - xr_strcat(buf, sizeof(buf), StringTable().translate("ui_logs_center_caption").c_str()); - m_center_caption->SetText(buf); + xr_strcpy(buf, center_caption->GetText()); + xr_strcat(buf, StringTable().translate("ui_logs_center_caption").c_str()); + center_caption->SetText(buf); CUIFixedScrollBar* tmp_scroll = xr_new(); m_list = xr_new(tmp_scroll); diff --git a/src/xrGame/ui/UILogsWnd.h b/src/xrGame/ui/UILogsWnd.h index a3d0f589509..87ab366ba33 100644 --- a/src/xrGame/ui/UILogsWnd.h +++ b/src/xrGame/ui/UILogsWnd.h @@ -32,33 +32,27 @@ class CUILogsWnd final : public CUIWindow, public CUIWndCallback private: typedef CUIWindow inherited; - CUIFrameWindow* m_background; - CUIFrameLineWnd* m_background2; - CUIFrameWindow* m_center_background; - CUIStatic* m_center_background2; + CUICharacterInfo* m_actor_ch_info{}; - CUIStatic* m_center_caption; - CUICharacterInfo* m_actor_ch_info; + CUICheckButton* m_filter_news{}; + CUICheckButton* m_filter_talk{}; - CUICheckButton* m_filter_news; - CUICheckButton* m_filter_talk; + CUIStatic* m_date_caption{}; + CUIStatic* m_date{}; - CUIStatic* m_date_caption; - CUIStatic* m_date; + CUIStatic* m_period_caption{}; + CUIStatic* m_period{}; - CUIStatic* m_period_caption; - CUIStatic* m_period; + ALife::_TIME_ID m_start_game_time{}; + ALife::_TIME_ID m_selected_period{}; - ALife::_TIME_ID m_start_game_time; - ALife::_TIME_ID m_selected_period; + CUI3tButton* m_prev_period{}; + CUI3tButton* m_next_period{}; + bool m_ctrl_press{}; - CUI3tButton* m_prev_period; - CUI3tButton* m_next_period; - bool m_ctrl_press; - - CUIScrollView* m_list; + CUIScrollView* m_list{}; u32 m_previous_time; - bool m_need_reload; + bool m_need_reload{}; WINDOW_LIST m_items_cache; WINDOW_LIST m_items_ready; xr_vector m_news_in_queue; diff --git a/src/xrGame/ui/UIMessagesWindow.cpp b/src/xrGame/ui/UIMessagesWindow.cpp index c05b0ff2924..a855a2c50a5 100644 --- a/src/xrGame/ui/UIMessagesWindow.cpp +++ b/src/xrGame/ui/UIMessagesWindow.cpp @@ -17,14 +17,16 @@ #include "UIPdaMsgListItem.h" #include "xrGame/game_type.h" -CUIMessagesWindow::CUIMessagesWindow() - : CUIWindow("CUIMessagesWindow"), m_pChatLog(nullptr), m_pChatWnd(nullptr), m_pGameLog(nullptr) +constexpr cpcstr CHAT_LOG_LIST_PENDING = "chat_log_list_pending"; + +CUIMessagesWindow::CUIMessagesWindow() : CUIWindow("CUIMessagesWindow") { Init(0, 0, UI_BASE_WIDTH, UI_BASE_HEIGHT); } -void CUIMessagesWindow::AddLogMessage(KillMessageStruct& msg) { m_pGameLog->AddLogMessage(msg); } -void CUIMessagesWindow::AddLogMessage(const shared_str& msg) { m_pGameLog->AddLogMessage(*msg); } +void CUIMessagesWindow::AddLogMessage(KillMessageStruct& msg) const { m_pGameLog->AddLogMessage(msg); } +void CUIMessagesWindow::AddLogMessage(const shared_str& msg) const { m_pGameLog->AddLogMessage(msg.c_str()); } + void CUIMessagesWindow::PendingMode(bool const is_pending_mode) { if (is_pending_mode) @@ -45,7 +47,6 @@ void CUIMessagesWindow::PendingMode(bool const is_pending_mode) m_in_pending_mode = false; } -#define CHAT_LOG_LIST_PENDING "chat_log_list_pending" void CUIMessagesWindow::Init(float x, float y, float width, float height) { CUIXml xml; @@ -104,8 +105,7 @@ void CUIMessagesWindow::AddIconedPdaMessage(GAME_NEWS_DATA* news) { CUIPdaMsgListItem* pItem = m_pGameLog->AddPdaMessage(); - LPCSTR time_str = - InventoryUtilities::GetTimeAsString(news->receive_time, InventoryUtilities::etpTimeToMinutes).c_str(); + cpcstr time_str = GetTimeAsString(news->receive_time, InventoryUtilities::etpTimeToMinutes).c_str(); pItem->UITimeText.SetText(time_str); pItem->UITimeText.AdjustWidthToText(); Fvector2 p = pItem->UICaptionText.GetWndPos(); @@ -119,20 +119,17 @@ void CUIMessagesWindow::AddIconedPdaMessage(GAME_NEWS_DATA* news) "ui_main_msgs_short", LA_ONLYALPHA | LA_TEXTCOLOR | LA_TEXTURECOLOR, float(news->show_time)); pItem->UIIcon.InitTexture(news->texture_name.c_str()); - float h1 = _max(pItem->UIIcon.GetHeight(), pItem->UIMsgText.GetWndPos().y + pItem->UIMsgText.GetHeight()); + const float h1 = _max(pItem->UIIcon.GetHeight(), pItem->UIMsgText.GetWndPos().y + pItem->UIMsgText.GetHeight()); pItem->SetHeight(h1 + 3.0f); m_pGameLog->SendMessage(pItem, CHILD_CHANGED_SIZE); } -void CUIMessagesWindow::AddChatMessage(shared_str msg, shared_str author) { m_pChatLog->AddChatMessage(*msg, *author); } -/* -void CUIMessagesWindow::SetChatOwner(game_cl_GameState* owner) +void CUIMessagesWindow::AddChatMessage(const shared_str& msg, const shared_str& author) const { - if (m_pChatWnd) - m_pChatWnd->SetOwner(owner); + m_pChatLog->AddChatMessage(msg.c_str(), author.c_str()); } -*/ + void CUIMessagesWindow::Show(bool show) { if (m_pChatWnd) diff --git a/src/xrGame/ui/UIMessagesWindow.h b/src/xrGame/ui/UIMessagesWindow.h index ffc6ce7dabc..aa86f7aca71 100644 --- a/src/xrGame/ui/UIMessagesWindow.h +++ b/src/xrGame/ui/UIMessagesWindow.h @@ -22,23 +22,22 @@ class CUIMessagesWindow final : public CUIWindow void AddIconedPdaMessage(GAME_NEWS_DATA* news); - void AddLogMessage(const shared_str& msg); - void AddLogMessage(KillMessageStruct& msg); - void AddChatMessage(shared_str msg, shared_str author); - //. void SetChatOwner (game_cl_GameState* owner); + void AddLogMessage(const shared_str& msg) const; + void AddLogMessage(KillMessageStruct& msg) const; + void AddChatMessage(const shared_str& msg, const shared_str& author) const; void PendingMode(bool const is_in_pending_mode); - CUIChatWnd* GetChatWnd() { return m_pChatWnd; } - virtual void Show(bool show); + CUIChatWnd* GetChatWnd() const { return m_pChatWnd; } + void Show(bool show) override; pcstr GetDebugType() override { return "CUIMessagesWindow"; } protected: virtual void Init(float x, float y, float width, float height); - CUIGameLog* m_pChatLog; - CUIChatWnd* m_pChatWnd; - CUIGameLog* m_pGameLog; - bool m_in_pending_mode; + CUIGameLog* m_pChatLog{}; + CUIChatWnd* m_pChatWnd{}; + CUIGameLog* m_pGameLog{}; + bool m_in_pending_mode{}; Frect m_pending_chat_log_rect; Frect m_inprogress_chat_log_rect; diff --git a/src/xrGame/ui/UIMoneyIndicator.cpp b/src/xrGame/ui/UIMoneyIndicator.cpp index 9d12cd1b9ea..746e01caf70 100644 --- a/src/xrGame/ui/UIMoneyIndicator.cpp +++ b/src/xrGame/ui/UIMoneyIndicator.cpp @@ -5,19 +5,15 @@ #include "UIGameLog.h" CUIMoneyIndicator::CUIMoneyIndicator() - : CUIWindow("CUIMoneyIndicator"), m_back("Background") + : CUIWindow("CUIMoneyIndicator"), m_pBonusMoney(xr_new()) { AttachChild(&m_back); AttachChild(&m_money_amount); AttachChild(&m_money_change); - m_pBonusMoney = xr_new(); AttachChild(m_pBonusMoney); - // m_pAnimChange = new CUIColorAnimatorWrapper("ui_mp_chat"); - // m_pAnimChange->Cyclic(false); - // m_pAnimChange->SetDone(true); + m_pBonusMoney->SetAutoDelete(true); } -CUIMoneyIndicator::~CUIMoneyIndicator() { xr_delete(m_pBonusMoney); } void CUIMoneyIndicator::InitFromXML(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "money_wnd", 0, this); @@ -34,12 +30,11 @@ void CUIMoneyIndicator::InitFromXML(CUIXml& xml_doc) m_money_change.SetColorAnimation("ui_mp_chat", LA_ONLYALPHA | LA_TEXTCOLOR); } -void CUIMoneyIndicator::SetMoneyAmount(LPCSTR money) { m_money_amount.SetText(money); } -void CUIMoneyIndicator::SetMoneyChange(LPCSTR money) +void CUIMoneyIndicator::SetMoneyAmount(pcstr money) { m_money_amount.SetText(money); } +void CUIMoneyIndicator::SetMoneyChange(pcstr money) { m_money_change.SetText(money); m_money_change.ResetColorAnimation(); } void CUIMoneyIndicator::AddBonusMoney(KillMessageStruct& msg) { m_pBonusMoney->AddLogMessage(msg); } -void CUIMoneyIndicator::Update() { CUIWindow::Update(); } diff --git a/src/xrGame/ui/UIMoneyIndicator.h b/src/xrGame/ui/UIMoneyIndicator.h index 29fc77529e4..1b33a5837c3 100644 --- a/src/xrGame/ui/UIMoneyIndicator.h +++ b/src/xrGame/ui/UIMoneyIndicator.h @@ -1,20 +1,18 @@ #pragma once #include "xrUICore/Static/UIStatic.h" -#include "KillMessageStruct.h" class CUIXml; class CUIGameLog; +struct KillMessageStruct; class CUIMoneyIndicator final : public CUIWindow { public: CUIMoneyIndicator(); - virtual ~CUIMoneyIndicator(); - virtual void Update(); void InitFromXML(CUIXml& xml_doc); - void SetMoneyAmount(LPCSTR money); - void SetMoneyChange(LPCSTR money); + void SetMoneyAmount(pcstr money); + void SetMoneyChange(pcstr money); void AddBonusMoney(KillMessageStruct& msg); pcstr GetDebugType() override { return "CUIMoneyIndicator"; } diff --git a/src/xrGame/ui/UIRankingWnd.cpp b/src/xrGame/ui/UIRankingWnd.cpp index 888cee11a17..fa48f8301bd 100644 --- a/src/xrGame/ui/UIRankingWnd.cpp +++ b/src/xrGame/ui/UIRankingWnd.cpp @@ -7,7 +7,6 @@ #include "pch_script.h" #include "UIRankingWnd.h" -#include "xrUICore/ScrollBar/UIFixedScrollBar.h" #include "UIXmlInit.h" #include "xrUICore/ProgressBar/UIProgressBar.h" #include "xrUICore/Windows/UIFrameLineWnd.h" @@ -28,26 +27,8 @@ CUIRankingWnd::CUIRankingWnd() : CUIWindow("CUIRankingWnd"), - m_background(nullptr), m_background2(nullptr), - m_center_background(nullptr), m_down_background(nullptr), - m_icon_overlay(nullptr), m_money_caption(nullptr), - m_money_value(nullptr), m_center_caption(nullptr), - m_faction_static(nullptr), m_faction_line1(nullptr), - m_faction_line2(nullptr), m_factions_list(nullptr), - m_achievements(nullptr), m_achievements_background(nullptr), - m_monster_background(nullptr), m_monster_over(nullptr), - m_favorite_weapon_ramka(nullptr), m_favorite_weapon_over(nullptr), - m_monster_icon_back(nullptr), m_monster_icon(nullptr), - m_favorite_weapon_bckgrnd(nullptr), m_favorite_weapon_icon(nullptr), - m_stat_caption{}, m_stat_info{}, m_stat_count(0) -{ - m_actor_ch_info = nullptr; - m_previous_time = Device.dwTimeGlobal; - m_delay = 3000; - m_last_monster_icon_back = ""; - m_last_monster_icon = ""; - m_last_weapon_icon = ""; -} + m_delay(3000), m_previous_time(Device.dwTimeGlobal), m_stat_count(0), + m_last_monster_icon_back(""), m_last_monster_icon(""), m_last_weapon_icon("") {} CUIRankingWnd::~CUIRankingWnd() { @@ -93,37 +74,38 @@ bool CUIRankingWnd::Init() CUIXmlInit::InitWindow(xml, "main_wnd", 0, this); m_delay = (u32)xml.ReadAttribInt("main_wnd", 0, "delay", 3000); - m_background = UIHelper::CreateFrameWindow(xml, "background", this, false); - if (!m_background) - m_background2 = UIHelper::CreateFrameLine(xml, "background", this, false); - m_center_background = UIHelper::CreateStatic(xml, "center_background", this, false); - m_down_background = UIHelper::CreateFrameWindow(xml, "down_background", this, false); + if (!UIHelper::CreateFrameWindow(xml, "background", this, false)) + std::ignore = UIHelper::CreateFrameLine(xml, "background", this, false); + + std::ignore = UIHelper::CreateStatic(xml, "center_background", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "down_background", this, false); m_actor_ch_info = xr_new(); m_actor_ch_info->SetAutoDelete(true); AttachChild(m_actor_ch_info); m_actor_ch_info->InitCharacterInfo(&xml, "actor_ch_info"); - m_icon_overlay = UIHelper::CreateFrameWindow(xml, "actor_icon_over", this, false); - m_money_caption = UIHelper::CreateStatic(xml, "money_caption", this); + std::ignore = UIHelper::CreateFrameWindow(xml, "actor_icon_over", this, false); + auto* money_caption = UIHelper::CreateStatic(xml, "money_caption", this); m_money_value = UIHelper::CreateStatic(xml, "money_value", this); - m_money_caption->AdjustWidthToText(); - pos = m_money_caption->GetWndPos(); - pos.x += m_money_caption->GetWndSize().x + 10.0f; + money_caption->AdjustWidthToText(); + pos = money_caption->GetWndPos(); + pos.x += money_caption->GetWndSize().x + 10.0f; m_money_value->SetWndPos(pos); - m_center_caption = UIHelper::CreateStatic(xml, "center_caption", this); - m_faction_static = UIHelper::CreateStatic(xml, "fraction_static", this, false); - m_faction_line1 = UIHelper::CreateFrameLine(xml, "fraction_line1", this, false); - m_faction_line2 = UIHelper::CreateFrameLine(xml, "fraction_line2", this, false); + auto* center_caption = UIHelper::CreateStatic(xml, "center_caption", this); + + std::ignore = UIHelper::CreateStatic (xml, "fraction_static", this, false); + std::ignore = UIHelper::CreateFrameLine(xml, "fraction_line1", this, false); + std::ignore = UIHelper::CreateFrameLine(xml, "fraction_line2", this, false); XML_NODE stored_root = xml.GetLocalRoot(); XML_NODE node = xml.NavigateToNode("stat_info", 0); xml.SetLocalRoot(node); m_stat_count = (u32)xml.GetNodesNum(node, "stat"); - u32 value_color = CUIXmlInit::GetColor(xml, "value", 0, 0xFFffffff); + const u32 value_color = CUIXmlInit::GetColor(xml, "value", 0, 0xFFffffff); for (u8 i = 0; i < m_stat_count; ++i) { @@ -147,9 +129,9 @@ bool CUIRankingWnd::Init() xml.SetLocalRoot(stored_root); string256 buf; - xr_strcpy(buf, sizeof(buf), m_center_caption->GetText()); - xr_strcat(buf, sizeof(buf), StringTable().translate("ui_ranking_center_caption").c_str()); - m_center_caption->SetText(buf); + xr_strcpy(buf, center_caption->GetText()); + xr_strcat(buf, StringTable().translate("ui_ranking_center_caption").c_str()); + center_caption->SetText(buf); m_factions_list = UIHelper::CreateScrollView(xml, "fraction_list", this, false); if (m_factions_list) @@ -157,7 +139,7 @@ bool CUIRankingWnd::Init() m_factions_list->SetWindowName("---fraction_list"); m_factions_list->m_sort_function = fastdelegate::MakeDelegate(this, &CUIRankingWnd::SortingLessFunction); - pcstr fract_section = "pda_rank_communities"; + cpcstr fract_section = "pda_rank_communities"; if (pSettings->section_exist(fract_section)) { @@ -175,25 +157,25 @@ bool CUIRankingWnd::Init() m_monster_icon_back = UIHelper::CreateStatic(xml, "monster_icon_back", this, false); m_monster_icon = UIHelper::CreateStatic(xml, "monster_icon", this, false); - m_monster_background = UIHelper::CreateFrameWindow(xml, "monster_background", this, false); - m_monster_over = UIHelper::CreateFrameWindow(xml, "monster_over", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "monster_background", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "monster_over", this, false); - m_favorite_weapon_bckgrnd = UIHelper::CreateStatic(xml, "favorite_weapon_back", this, false); + std::ignore = UIHelper::CreateStatic(xml, "favorite_weapon_back", this, false); m_favorite_weapon_icon = UIHelper::CreateStatic(xml, "favorite_weapon_icon", this, false); - m_favorite_weapon_ramka = UIHelper::CreateFrameWindow(xml, "favorite_weapon_ramka", this, false); - m_favorite_weapon_over = UIHelper::CreateFrameWindow(xml, "favorite_weapon_over", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "favorite_weapon_ramka", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "favorite_weapon_over", this, false); - m_achievements_background = UIHelper::CreateFrameWindow(xml, "achievements_background", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "achievements_background", this, false); m_achievements = UIHelper::CreateScrollView(xml, "achievements_wnd", this, false); if (m_achievements) { m_achievements->SetWindowName("achievements_list"); - pcstr section = "achievements"; + cpcstr section = "achievements"; if (pSettings->section_exist(section)) { - CInifile::Sect& achievs_section = pSettings->r_section(section); + const auto& achievs_section = pSettings->r_section(section); for (const auto& item : achievs_section.Data) add_achievement(xml, item.first); } @@ -252,8 +234,7 @@ void CUIRankingWnd::update_info() bool force_rating = false; for (u8 i = 0; i < m_factions_list->GetSize(); ++i) { - CUIRankFaction* ui_faction = smart_cast(m_factions_list->GetItem(i)); - if (ui_faction) + if (const auto* ui_faction = smart_cast(m_factions_list->GetItem(i))) { if (ui_faction->get_cur_sn() != i + 1) { @@ -265,8 +246,7 @@ void CUIRankingWnd::update_info() for (u8 i = 0; i < m_factions_list->GetSize(); ++i) { - CUIRankFaction* ui_faction = smart_cast(m_factions_list->GetItem(i)); - if (ui_faction) + if (auto* ui_faction = smart_cast(m_factions_list->GetItem(i))) { ui_faction->update_info(i + 1); ui_faction->rating(i + 1, force_rating); @@ -295,13 +275,13 @@ void CUIRankingWnd::get_statistic() m_stat_info[0]->SetTextColor(color_rgba(170, 170, 170, 255)); m_stat_info[0]->SetText(buf); - luabind::functor funct; + luabind::functor funct; if (!GEnv.ScriptEngine->functor("pda.get_stat", funct)) return; for (u8 i = 1; i < m_stat_count; ++i) { - LPCSTR str = funct(i); + cpcstr str = funct(i); m_stat_info[i]->SetTextColor(color_rgba(170, 170, 170, 255)); m_stat_info[i]->SetTextST(str); } @@ -350,7 +330,7 @@ void CUIRankingWnd::get_favorite_weapon() luabind::functor functor; if(!GEnv.ScriptEngine->functor("pda.get_favorite_weapon", functor)) return; - pcstr str = functor(); + cpcstr str = functor(); if (!xr_strcmp(str, "")) return; diff --git a/src/xrGame/ui/UIRankingWnd.h b/src/xrGame/ui/UIRankingWnd.h index 7774761c820..51bade49ae3 100644 --- a/src/xrGame/ui/UIRankingWnd.h +++ b/src/xrGame/ui/UIRankingWnd.h @@ -23,34 +23,16 @@ class CUIRankingWnd final : public CUIWindow, public CUIWndCallback { using inherited = CUIWindow; - CUIFrameWindow* m_background; - CUIFrameLineWnd* m_background2; - CUIStatic* m_center_background; - CUIFrameWindow* m_down_background; - CUIFrameWindow* m_icon_overlay; - - CUICharacterInfo* m_actor_ch_info; - - CUIStatic* m_money_caption; - CUIStatic* m_money_value; - - CUIStatic* m_center_caption; - CUIStatic* m_faction_static; - CUIFrameLineWnd* m_faction_line1; - CUIFrameLineWnd* m_faction_line2; - - CUIScrollView* m_factions_list; - - CUIScrollView* m_achievements; - CUIFrameWindow* m_achievements_background; - CUIFrameWindow* m_monster_background; - CUIFrameWindow* m_monster_over; - CUIFrameWindow* m_favorite_weapon_ramka; - CUIFrameWindow* m_favorite_weapon_over; - CUIStatic* m_monster_icon_back; - CUIStatic* m_monster_icon; - CUIStatic* m_favorite_weapon_bckgrnd; - CUIStatic* m_favorite_weapon_icon; + CUICharacterInfo* m_actor_ch_info{}; + + CUIStatic* m_money_value{}; + + CUIScrollView* m_factions_list{}; + + CUIScrollView* m_achievements{}; + CUIStatic* m_monster_icon_back{}; + CUIStatic* m_monster_icon{}; + CUIStatic* m_favorite_weapon_icon{}; using ACHIEVES_VEC = xr_vector; ACHIEVES_VEC m_achieves_vec; @@ -59,8 +41,8 @@ class CUIRankingWnd final : public CUIWindow, public CUIWndCallback { max_stat_info = 15 }; - CUIStatic* m_stat_caption[max_stat_info]; - CUIStatic* m_stat_info[max_stat_info]; + CUIStatic* m_stat_caption[max_stat_info]{}; + CUIStatic* m_stat_info[max_stat_info]{}; u32 m_delay; u32 m_previous_time; diff --git a/src/xrGame/ui/UIScriptWnd.cpp b/src/xrGame/ui/UIScriptWnd.cpp index b039851689a..997d6453bcf 100644 --- a/src/xrGame/ui/UIScriptWnd.cpp +++ b/src/xrGame/ui/UIScriptWnd.cpp @@ -5,8 +5,9 @@ CUIDialogWndEx::CUIDialogWndEx() : CUIDialogWnd("CUIDialogWndEx") {} CUIDialogWndEx::~CUIDialogWndEx() { delete_data(m_callbacks); } + void CUIDialogWndEx::Register(CUIWindow* pChild) { pChild->SetMessageTarget(this); } -void CUIDialogWndEx::Register(CUIWindow* pChild, LPCSTR name) +void CUIDialogWndEx::Register(CUIWindow* pChild, pcstr name) { pChild->SetWindowName(name); pChild->SetMessageTarget(this); @@ -14,37 +15,28 @@ void CUIDialogWndEx::Register(CUIWindow* pChild, LPCSTR name) void CUIDialogWndEx::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { - event_comparer ec(pWnd, msg); - - CALLBACK_IT it = std::find_if(m_callbacks.begin(), m_callbacks.end(), ec); + const auto it = std::find_if(m_callbacks.begin(), m_callbacks.end(), event_comparer{ pWnd, msg }); if (it == m_callbacks.end()) return inherited::SendMessage(pWnd, msg, pData); - ((*it)->m_callback)(); + (*it)->m_callback(); // if ( (*it)->m_cpp_callback ) // (*it)->m_cpp_callback(pData); } -bool CUIDialogWndEx::Load(LPCSTR xml_name) { return true; } +bool CUIDialogWndEx::Load(pcstr /*xml_name*/) { return true; } + SCallbackInfo* CUIDialogWndEx::NewCallback() { m_callbacks.push_back(xr_new()); return m_callbacks.back(); } -void CUIDialogWndEx::AddCallback( - LPCSTR control_id, s16 evt, const luabind::functor& functor, const luabind::object& object) +void CUIDialogWndEx::AddCallback(pcstr control_id, s16 evt, const luabind::functor& functor, const luabind::object& object) { SCallbackInfo* c = NewCallback(); c->m_callback.set(functor, object); c->m_control_name = control_id; c->m_event = evt; } - -bool CUIDialogWndEx::OnKeyboardAction(int dik, EUIMessages keyboard_action) -{ - return inherited::OnKeyboardAction(dik, keyboard_action); -} - -void CUIDialogWndEx::Update() { inherited::Update(); } diff --git a/src/xrGame/ui/UIScriptWnd.h b/src/xrGame/ui/UIScriptWnd.h index 2df770a93f1..bff00978157 100644 --- a/src/xrGame/ui/UIScriptWnd.h +++ b/src/xrGame/ui/UIScriptWnd.h @@ -13,20 +13,18 @@ class CUIDialogWndEx : public CUIDialogWnd, public FactoryObjectBase private: CALLBACKS m_callbacks; - virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = NULL); + void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = nullptr) override; SCallbackInfo* NewCallback(); public: - bool Load(LPCSTR xml_name); + bool Load(pcstr xml_name); void Register(CUIWindow* pChild); - void Register(CUIWindow* pChild, LPCSTR name); + void Register(CUIWindow* pChild, pcstr name); + CUIDialogWndEx(); - virtual ~CUIDialogWndEx(); - void AddCallback( - LPCSTR control_id, s16 event, const luabind::functor& functor, const luabind::object& object); - virtual void Update(); - virtual bool OnKeyboardAction(int dik, EUIMessages keyboard_action); - virtual bool Dispatch(int cmd, int param) { return true; } + ~CUIDialogWndEx() override; + + void AddCallback(pcstr control_id, s16 event, const luabind::functor& functor, const luabind::object& object); template T* GetControl(pcstr name); diff --git a/src/xrGame/ui/UIScriptWnd_script.cpp b/src/xrGame/ui/UIScriptWnd_script.cpp index f0c66fc1283..ebd727568a1 100644 --- a/src/xrGame/ui/UIScriptWnd_script.cpp +++ b/src/xrGame/ui/UIScriptWnd_script.cpp @@ -206,22 +206,22 @@ SCRIPT_EXPORT(CUIDialogWndEx, (CUIDialogWnd, IFactoryObject), [ class_, luabind::default_holder, WrapType>("CUIScriptWnd") .def(constructor<>()) - .def("AddCallback", &BaseType::AddCallback) - .def("Register", (void (BaseType::*)(CUIWindow*, pcstr)) & BaseType::Register) - .def("OnKeyboard", &BaseType::OnKeyboardAction, &WrapType::OnKeyboard_static) - .def("Update", &BaseType::Update, &WrapType::Update_static) - .def("Dispatch", &BaseType::Dispatch, &WrapType::Dispatch_static) - .def("Load", &BaseType::Load) - - .def("GetStatic", (CUIStatic* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetEditBox", (CUIEditBox* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetDialogWnd", (CUIDialogWnd* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetFrameWindow", (CUIFrameWindow* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetFrameLineWnd", (CUIFrameLineWnd* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetProgressBar", (CUIProgressBar* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetTabControl", (CUITabControl* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetListBox", (CUIListBox* (BaseType::*)(pcstr)) &BaseType::GetControl) - .def("GetListWnd", (CUIListWnd* (BaseType::*)(pcstr)) &BaseType::GetControl) + .def("AddCallback", &BaseType::AddCallback) + .def("Register", (void (BaseType::*)(CUIWindow*, pcstr)) & BaseType::Register) + .def("OnKeyboard", &BaseType::OnKeyboardAction, &WrapType::OnKeyboard_static) + .def("Update", &BaseType::Update, &WrapType::Update_static) + .def("Dispatch", &BaseType::Dispatch, &WrapType::Dispatch_static) + .def("Load", &BaseType::Load) + + .def("GetStatic", &BaseType::GetControl) + .def("GetEditBox", &BaseType::GetControl) + .def("GetDialogWnd", &BaseType::GetControl) + .def("GetFrameWindow", &BaseType::GetControl) + .def("GetFrameLineWnd", &BaseType::GetControl) + .def("GetProgressBar", &BaseType::GetControl) + .def("GetTabControl", &BaseType::GetControl) + .def("GetListBox", &BaseType::GetControl) + .def("GetListWnd", &BaseType::GetControl) ]; }); // clang-format on diff --git a/src/xrGame/ui/UISecondTaskWnd.cpp b/src/xrGame/ui/UISecondTaskWnd.cpp index 1e305ec94f2..a66a79b4437 100644 --- a/src/xrGame/ui/UISecondTaskWnd.cpp +++ b/src/xrGame/ui/UISecondTaskWnd.cpp @@ -27,19 +27,15 @@ #include "GametaskManager.h" #include "Actor.h" -UITaskListWnd::UITaskListWnd() - : CUIWindow("UITaskListWnd"), - hint_wnd(nullptr), m_background(nullptr), m_list(nullptr), - m_caption(nullptr), m_bt_close(nullptr), m_orig_h(0) {} +UITaskListWnd::UITaskListWnd() : CUIWindow("UITaskListWnd") {} -UITaskListWnd::~UITaskListWnd() {} void UITaskListWnd::init_from_xml(CUIXml& xml, LPCSTR path) { VERIFY(hint_wnd); CUIXmlInit::InitWindow(xml, path, 0, this); - XML_NODE stored_root = xml.GetLocalRoot(); - XML_NODE tmpl_root = xml.NavigateToNode(path, 0); + const XML_NODE stored_root = xml.GetLocalRoot(); + const XML_NODE tmpl_root = xml.NavigateToNode(path, 0); xml.SetLocalRoot(tmpl_root); m_background = UIHelper::CreateFrameWindow(xml, "background_frame", this); @@ -57,7 +53,13 @@ void UITaskListWnd::init_from_xml(CUIXml& xml, LPCSTR path) m_orig_h = GetHeight(); m_list->SetWindowName("---second_task_list"); - m_list->m_sort_function = fastdelegate::MakeDelegate(this, &UITaskListWnd::SortingLessFunction); + m_list->m_sort_function = +[](CUIWindow* left, CUIWindow* right) -> bool + { + const auto* lpi = smart_cast(left); + const auto* rpi = smart_cast(right); + VERIFY(lpi && rpi); + return lpi->get_priority_task() > rpi->get_priority_task(); + }; xml.SetLocalRoot(stored_root); } @@ -92,7 +94,7 @@ bool UITaskListWnd::OnControllerAction(int axis, float x, float y, EUIMessages c void UITaskListWnd::Show(bool status) { inherited::Show(status); - GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, NULL); + GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); if (status) UpdateList(); } @@ -100,13 +102,13 @@ void UITaskListWnd::Show(bool status) void UITaskListWnd::OnFocusReceive() { inherited::OnFocusReceive(); - GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, NULL); + GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); } void UITaskListWnd::OnFocusLost() { inherited::OnFocusLost(); - GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, NULL); + GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); } void UITaskListWnd::Update() @@ -124,8 +126,7 @@ void UITaskListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) void UITaskListWnd::OnBtnClose(CUIWindow* w, void* d) { - CUITaskWnd* wnd = smart_cast(GetParent()->GetParent()); - if (wnd) + if (auto* wnd = smart_cast(GetParent()->GetParent())) wnd->Show_TaskListWnd(false); // Show( false ); m_bt_close->SetButtonState(CUIButton::BUTTON_NORMAL); @@ -133,38 +134,30 @@ void UITaskListWnd::OnBtnClose(CUIWindow* w, void* d) void UITaskListWnd::UpdateList() { - int prev_scroll_pos = m_list->GetCurrentScrollPos(); + const int prev_scroll_pos = m_list->GetCurrentScrollPos(); m_list->Clear(); u32 count_for_check = 0; - vGameTasks& tasks = Level().GameTaskManager().GetGameTasks(); - vGameTasks::iterator itb = tasks.begin(); - vGameTasks::iterator ite = tasks.end(); - for (; itb != ite; ++itb) + const vGameTasks& tasks = Level().GameTaskManager().GetGameTasks(); + + for (const auto& key : tasks) { - CGameTask* task = (*itb).game_task; - if (task && task->GetTaskState() == eTaskStateInProgress) + CGameTask* task = key.game_task; + + if (!task || task->GetTaskState() != eTaskStateInProgress) + continue; + + auto* item = xr_new(); + if (item->init_task(task, this)) { - UITaskListWndItem* item = xr_new(); - if (item->init_task(task, this)) - { - m_list->AddWindow(item, true); - ++count_for_check; - } + m_list->AddWindow(item, true); + ++count_for_check; } } // for m_list->SetScrollPos(prev_scroll_pos); } -bool UITaskListWnd::SortingLessFunction(CUIWindow* left, CUIWindow* right) -{ - UITaskListWndItem* lpi = smart_cast(left); - UITaskListWndItem* rpi = smart_cast(right); - VERIFY(lpi && rpi); - return (lpi->get_priority_task() > rpi->get_priority_task()); -} - /* void UITaskListWnd::UpdateCounter() { @@ -179,12 +172,7 @@ void UITaskListWnd::UpdateCounter() */ // - ----------------------------------------------------------------------------------------------- -UITaskListWndItem::UITaskListWndItem() - : CUIWindow("UITaskListWndItem"), - show_hint_can(false), show_hint(false), - m_task(nullptr), m_name(nullptr), - m_bt_view(nullptr), m_st_story(nullptr), - m_bt_focus(nullptr) +UITaskListWndItem::UITaskListWndItem() : CUIWindow("UITaskListWndItem") { m_color_states[0] = u32(-1); m_color_states[1] = u32(-1); @@ -217,9 +205,9 @@ bool UITaskListWndItem::init_task(CGameTask* task, UITaskListWnd* parent) m_st_story = UIHelper::CreateStatic(xml, "second_task_wnd:task_item:st_story", this, false); m_bt_focus = UIHelper::Create3tButton(xml, "second_task_wnd:task_item:btn_focus", this); - m_color_states[stt_activ] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:activ", 0, (u32)(-1)); - m_color_states[stt_unread] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:unread", 0, (u32)(-1)); - m_color_states[stt_read] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:read", 0, (u32)(-1)); + m_color_states[stt_activ] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:activ", 0, u32(-1)); + m_color_states[stt_unread] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:unread", 0, u32(-1)); + m_color_states[stt_read] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:read", 0, u32(-1)); update_view(); return true; } @@ -228,7 +216,7 @@ void UITaskListWndItem::hide_hint() { show_hint_can = false; show_hint = false; - GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, NULL); + GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); } void UITaskListWndItem::Update() @@ -307,7 +295,7 @@ void UITaskListWndItem::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) GetMessageTarget()->SendMessage(this, PDA_TASK_SET_TARGET_MAP, (void*)m_task); } } - if (pWnd == m_bt_view) + if (pWnd == m_bt_view && m_bt_view) { if (m_bt_view->GetCheck() && msg == BUTTON_CLICKED) { diff --git a/src/xrGame/ui/UISecondTaskWnd.h b/src/xrGame/ui/UISecondTaskWnd.h index c738166e184..9d5c3455d27 100644 --- a/src/xrGame/ui/UISecondTaskWnd.h +++ b/src/xrGame/ui/UISecondTaskWnd.h @@ -30,7 +30,6 @@ class UITaskListWnd final : public CUIWindow, public CUIWndCallback public: UITaskListWnd(); - ~UITaskListWnd() override; void init_from_xml(CUIXml& xml, LPCSTR path); @@ -50,22 +49,20 @@ class UITaskListWnd final : public CUIWindow, public CUIWndCallback protected: void OnBtnClose(CUIWindow* w, void* d); - bool SortingLessFunction(CUIWindow* left, CUIWindow* right); - // void UpdateCounter (); + public: - UIHint* hint_wnd; + UIHint* hint_wnd{}; private: // m_ - CUIFrameWindow* m_background; - CUIScrollView* m_list; + CUIFrameWindow* m_background{}; + CUIScrollView* m_list{}; - CUIStatic* m_caption; - // CUIStatic* m_counter; - CUI3tButton* m_bt_close; + CUIStatic* m_caption{}; + // CUIStatic* m_counter{}; + CUI3tButton* m_bt_close{}; - // u32 m_activ_task_count; - float m_orig_h; + float m_orig_h{}; }; // class UITaskListWnd @@ -78,7 +75,6 @@ class UITaskListWndItem final : public CUIWindow public: UITaskListWndItem(); - virtual ~UITaskListWndItem() = default; bool init_task(CGameTask* task, UITaskListWnd* parent); IC u32 get_priority_task() const; @@ -95,15 +91,15 @@ class UITaskListWndItem final : public CUIWindow void update_visible_map_spot(); public: - bool show_hint_can; - bool show_hint; + bool show_hint_can{}; + bool show_hint{}; -private: // m_ - CGameTask* m_task; - CUI3tButton* m_name; - CUICheckButton* m_bt_view; - CUIStatic* m_st_story; - CUI3tButton* m_bt_focus; +private: + CGameTask* m_task{}; + CUI3tButton* m_name{}; + CUICheckButton* m_bt_view{}; + CUIStatic* m_st_story{}; + CUI3tButton* m_bt_focus{}; enum { @@ -113,7 +109,6 @@ class UITaskListWndItem final : public CUIWindow stt_count }; u32 m_color_states[stt_count]; - }; // class UITaskListWndItem #endif // UI_SECOND_TASK_WND_H_INCLUDED diff --git a/src/xrGame/ui/UITaskWnd.cpp b/src/xrGame/ui/UITaskWnd.cpp index 7cbfeefb020..945c66ef026 100644 --- a/src/xrGame/ui/UITaskWnd.cpp +++ b/src/xrGame/ui/UITaskWnd.cpp @@ -20,19 +20,7 @@ #include "Actor.h" #include "xrUICore/Buttons/UICheckButton.h" -CUITaskWnd::CUITaskWnd(UIHint* hint) - : CUIWindow("CUITaskWnd"), - m_background(nullptr), m_background2(nullptr), - m_center_background(nullptr), m_right_bottom_background(nullptr), - m_task_split(nullptr), m_pMapWnd(nullptr), - m_pStoryLineTaskItem(nullptr), m_pSecondaryTaskItem(nullptr), - m_BtnTaskListWnd(nullptr), m_second_task_index(nullptr), - m_devider(nullptr), m_actual_frame(0), - m_btn_focus(nullptr), m_btn_focus2(nullptr), - m_task_wnd(nullptr), m_task_wnd_show(false), - m_map_legend_wnd(nullptr), hint_wnd(hint) -{ -} +CUITaskWnd::CUITaskWnd(UIHint* hint) : CUIWindow("CUITaskWnd"), hint_wnd(hint) {} CUITaskWnd::~CUITaskWnd() { delete_data(m_pMapWnd); } @@ -46,10 +34,10 @@ bool CUITaskWnd::Init() CUIXmlInit::InitWindow(xml, "main_wnd", 0, this); - m_background = UIHelper::CreateFrameWindow(xml, "background", this, false); - m_background2 = UIHelper::CreateFrameLine(xml, "background", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml, "background", this, false); + std::ignore = UIHelper::CreateFrameLine(xml, "background", this, false); - m_task_split = UIHelper::CreateFrameLine(xml, "task_split", this, false); + std::ignore = UIHelper::CreateFrameLine(xml, "task_split", this, false); AttachChild(&m_filters); m_filters.SetMessageTarget(this); @@ -61,7 +49,7 @@ bool CUITaskWnd::Init() AttachChild(m_pMapWnd); m_center_background = UIHelper::CreateStatic(xml, "center_background", this); - m_devider = UIHelper::CreateStatic(xml, "line_devider", this, false); + std::ignore = UIHelper::CreateStatic(xml, "line_devider", this, false); m_pStoryLineTaskItem = xr_new(); m_pStoryLineTaskItem->Init(xml, "storyline_task_item"); @@ -94,8 +82,8 @@ bool CUITaskWnd::Init() //m_btn_focus2->set_hint_wnd(hint_wnd); } - m_BtnTaskListWnd = UIHelper::Create3tButton(xml, "btn_second_task", this); - AddCallback(m_BtnTaskListWnd, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUITaskWnd::OnShowTaskListWnd)); + auto* btnTaskListWnd = UIHelper::Create3tButton(xml, "btn_second_task", this); + AddCallback(btnTaskListWnd, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUITaskWnd::OnShowTaskListWnd)); m_second_task_index = UIHelper::CreateStatic(xml, "second_task_index", this, false); @@ -229,14 +217,14 @@ void CUITaskWnd::ReloadTaskInfo() m_pSecondaryTaskItem->InitTask(additionalTask); } - if (!storyTask || (storyTask->m_map_object_id == u16(-1) || storyTask->m_map_location.size() == 0)) + if (!storyTask || (storyTask->m_map_object_id == u16(-1) || storyTask->m_map_location.empty())) m_btn_focus->Show(false); else m_btn_focus->Show(true); if (m_btn_focus2) { - if (!additionalTask || (additionalTask->m_map_object_id == u16(-1) || additionalTask->m_map_location.size() == 0)) + if (!additionalTask || (additionalTask->m_map_object_id == u16(-1) || additionalTask->m_map_location.empty())) m_btn_focus2->Show(false); else m_btn_focus2->Show(true); @@ -329,8 +317,6 @@ void CUITaskWnd::Show(bool status) } } -void CUITaskWnd::OnNextTaskClicked() {} -void CUITaskWnd::OnPrevTaskClicked() {} void CUITaskWnd::OnShowTaskListWnd(CUIWindow* w, void* d) { m_task_wnd_show = !m_task_wnd_show; @@ -343,7 +329,7 @@ void CUITaskWnd::Show_TaskListWnd(bool status) m_task_wnd_show = status; } -void CUITaskWnd::TaskSetTargetMap(CGameTask* task) +void CUITaskWnd::TaskSetTargetMap(CGameTask* task) const { if (!task || !IsSecondaryTasksEnabled()) { @@ -398,9 +384,7 @@ void CUITaskWnd::ShowMapLegend(bool status) const { m_map_legend_wnd->Show(statu void CUITaskWnd::Switch_ShowMapLegend() const { m_map_legend_wnd->Show(!m_map_legend_wnd->IsShown()); } // -------------------------------------------------------------------------------------------------- -CUITaskItem::CUITaskItem() - : CUIWindow("CUITaskItem"), - m_owner(nullptr), show_hint_can(false), show_hint(false), m_hint_wt(500) {} +CUITaskItem::CUITaskItem() : CUIWindow("CUITaskItem"), m_hint_wt(500) {} void CUITaskItem::Init(CUIXml& uiXml, LPCSTR path) { @@ -410,7 +394,7 @@ void CUITaskItem::Init(CUIXml& uiXml, LPCSTR path) const auto init = [&](pcstr name, bool critical = true) { string256 buff; - strconcat(sizeof(buff), buff, path, ":", name); + strconcat(buff, path, ":", name); m_info[name] = UIHelper::CreateStatic(uiXml, buff, this, critical); }; diff --git a/src/xrGame/ui/UITaskWnd.h b/src/xrGame/ui/UITaskWnd.h index 82e51af268e..d2999e3d741 100644 --- a/src/xrGame/ui/UITaskWnd.h +++ b/src/xrGame/ui/UITaskWnd.h @@ -23,30 +23,24 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback private: typedef CUIWindow inherited; - CUIFrameWindow* m_background; - CUIFrameLineWnd* m_background2; + CUIStatic* m_center_background{}; + CUIStatic* m_right_bottom_background{}; - CUIStatic* m_center_background; - CUIStatic* m_right_bottom_background; - CUIFrameLineWnd* m_task_split; + CUIMapWnd* m_pMapWnd{}; + CUITaskItem* m_pStoryLineTaskItem{}; + CUITaskItem* m_pSecondaryTaskItem{}; - CUIMapWnd* m_pMapWnd; - CUITaskItem* m_pStoryLineTaskItem; - CUITaskItem* m_pSecondaryTaskItem; + CUIStatic* m_second_task_index{}; + u32 m_actual_frame{}; - CUI3tButton* m_BtnTaskListWnd; - CUIStatic* m_second_task_index; - CUIStatic* m_devider; - u32 m_actual_frame; - - CUI3tButton* m_btn_focus; - CUI3tButton* m_btn_focus2; + CUI3tButton* m_btn_focus{}; + CUI3tButton* m_btn_focus2{}; CUIMapFilters m_filters; - UITaskListWnd* m_task_wnd; - bool m_task_wnd_show; - UIMapLegend* m_map_legend_wnd; + UITaskListWnd* m_task_wnd{}; + bool m_task_wnd_show{}; + UIMapLegend* m_map_legend_wnd{}; public: UIHint* hint_wnd; @@ -85,11 +79,9 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback void PrimaryObjectsEnabled(bool enable) { m_filters.SetFilterEnabled(CUIMapFilters::PrimaryObjects, enable); } private: - void TaskSetTargetMap(CGameTask* task); + void TaskSetTargetMap(CGameTask* task) const; void TaskShowMapSpot(CGameTask* task, bool show) const; - void OnNextTaskClicked(); - void OnPrevTaskClicked(); void OnShowTaskListWnd(CUIWindow* w, void* d); void OnTask1DbClicked(CUIWindow*, void*); void OnTask2DbClicked(CUIWindow*, void*); @@ -101,7 +93,7 @@ class CUITaskItem final : public CUIWindow typedef CUIWindow inherited; AssociativeVector m_info; - CGameTask* m_owner; + CGameTask* m_owner{}; public: CUITaskItem(); @@ -115,13 +107,13 @@ class CUITaskItem final : public CUIWindow void Init(CUIXml& uiXml, LPCSTR path); void InitTask(CGameTask* task); - CGameTask* OwnerTask() { return m_owner; } + CGameTask* OwnerTask() const { return m_owner; } pcstr GetDebugType() override { return "CUITaskItem"; } public: - bool show_hint_can; - bool show_hint; + bool show_hint_can{}; + bool show_hint{}; protected: u32 m_hint_wt; diff --git a/src/xrUICore/ComboBox/UIComboBox.cpp b/src/xrUICore/ComboBox/UIComboBox.cpp index f7793957d8d..245e279f00f 100644 --- a/src/xrUICore/ComboBox/UIComboBox.cpp +++ b/src/xrUICore/ComboBox/UIComboBox.cpp @@ -21,7 +21,6 @@ CUIComboBox::CUIComboBox() : CUIWindow("CUIComboBox") m_textColor[0] = 0xff00ff00; } -CUIComboBox::~CUIComboBox() {} void CUIComboBox::SetListLength(int length) { R_ASSERT(0 == m_iListHeight); @@ -30,7 +29,7 @@ void CUIComboBox::SetListLength(int length) void CUIComboBox::InitComboBox(Fvector2 pos, float width) { - float lb_text_offset = 5.0f; + const float lb_text_offset = 5.0f; m_bInited = true; if (0 == m_iListHeight) @@ -103,13 +102,13 @@ void CUIComboBox::OnListItemSelect() m_text.SetText(m_list_box.GetSelectedText()); CUIListBoxItem* itm = m_list_box.GetSelectedItem(); - int bk_itoken_id = m_itoken_id; + const int bk_itoken_id = m_itoken_id; m_itoken_id = (int)(__int64)itm->GetData(); ShowList(false); if (bk_itoken_id != m_itoken_id) - GetMessageTarget()->SendMessage(this, LIST_ITEM_SELECT, NULL); + GetMessageTarget()->SendMessage(this, LIST_ITEM_SELECT, nullptr); } void CUIComboBox::SetText(LPCSTR text) @@ -150,12 +149,11 @@ void CUIComboBox::SetCurrentOptValue() tok++; } - LPCSTR cur_val = *StringTable().translate(GetOptTokenValue()); + cpcstr cur_val = *StringTable().translate(GetOptTokenValue()); m_text.SetText(cur_val); m_list_box.SetSelectedText(cur_val); - CUIListBoxItem* itm = m_list_box.GetSelectedItem(); - if (itm) + if (CUIListBoxItem* itm = m_list_box.GetSelectedItem()) m_itoken_id = (int)(__int64)itm->GetData(); else m_itoken_id = 1; // first @@ -178,17 +176,16 @@ void CUIComboBox::SaveOptValue() { CUIOptionsItem::SaveOptValue(); - const xr_token* tok = GetOptToken(); - if (tok) + if (const xr_token* tok = GetOptToken()) { - LPCSTR cur_val = get_token_name(tok, m_itoken_id); + cpcstr cur_val = get_token_name(tok, m_itoken_id); SaveOptStringValue(cur_val); } } -bool CUIComboBox::IsChangedOptValue() const { return (m_opt_backup_value != m_itoken_id); } -LPCSTR CUIComboBox::GetText() { return m_text.GetText(); } -u32 CUIComboBox::GetSize() { return m_list_box.GetSize(); } +bool CUIComboBox::IsChangedOptValue() const { return m_opt_backup_value != m_itoken_id; } +LPCSTR CUIComboBox::GetText() const { return m_text.GetText(); } +u32 CUIComboBox::GetSize() const { return m_list_box.GetSize(); } LPCSTR CUIComboBox::GetTextOf(int index) { if (u32(index) >= GetSize()) @@ -210,7 +207,7 @@ void CUIComboBox::SetItemIDX(int idx) void CUIComboBox::SetItemToken(int tok_id) { - int idx = m_list_box.GetIdxByTAG(tok_id); + const int idx = m_list_box.GetIdxByTAG(tok_id); SetItemIDX(idx); } diff --git a/src/xrUICore/ComboBox/UIComboBox.h b/src/xrUICore/ComboBox/UIComboBox.h index 8d5524d65d7..e48154dc70c 100644 --- a/src/xrUICore/ComboBox/UIComboBox.h +++ b/src/xrUICore/ComboBox/UIComboBox.h @@ -16,7 +16,6 @@ class XRUICORE_API CUIComboBox final : public CUIWindow, public CUIOptionsItem, public: CUIComboBox(); - virtual ~CUIComboBox(); // CUIOptionsItem virtual void SetCurrentOptValue(); // opt->current @@ -27,7 +26,7 @@ class XRUICORE_API CUIComboBox final : public CUIWindow, public CUIOptionsItem, virtual void OnRender(); // only for list-box - LPCSTR GetText(); + LPCSTR GetText() const; LPCSTR GetTextOf(int index); void SetText(LPCSTR text); @@ -58,7 +57,7 @@ class XRUICORE_API CUIComboBox final : public CUIWindow, public CUIOptionsItem, public: void ClearList(); - u32 GetSize(); + u32 GetSize() const; protected: bool m_bInited; diff --git a/src/xrUICore/ScrollBar/UIFixedScrollBar.cpp b/src/xrUICore/ScrollBar/UIFixedScrollBar.cpp index 10adf2e2d15..91c13ca63ec 100644 --- a/src/xrUICore/ScrollBar/UIFixedScrollBar.cpp +++ b/src/xrUICore/ScrollBar/UIFixedScrollBar.cpp @@ -7,13 +7,12 @@ #include "Cursor/UICursor.h" CUIFixedScrollBar::CUIFixedScrollBar() + : m_ScrollBox(xr_new()) { - m_ScrollBox = xr_new(); m_ScrollBox->SetAutoDelete(true); AttachChild(m_ScrollBox); } -CUIFixedScrollBar::~CUIFixedScrollBar(void) {} bool CUIFixedScrollBar::InitScrollBar(Fvector2 pos, bool horizontal, cpcstr profile) { string256 _path; @@ -35,16 +34,16 @@ bool CUIFixedScrollBar::InitScrollBar(Fvector2 pos, bool horizontal, cpcstr prof { inherited::SetWndSize(Fvector2().set(width, height)); - strconcat(sizeof(_path), _path, profile, ":left_arrow"); + strconcat(_path, profile, ":left_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_DecButton); - strconcat(sizeof(_path), _path, profile, ":right_arrow"); + strconcat(_path, profile, ":right_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_IncButton); - strconcat(sizeof(_path), _path, profile, ":box"); + strconcat(_path, profile, ":box"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_ScrollBox); - strconcat(sizeof(_path), _path, profile, ":back"); + strconcat(_path, profile, ":back"); if (!CUIXmlInitBase::InitFrameLine(xml_doc, _path, 0, m_FrameBackground, false)) return false; @@ -54,16 +53,16 @@ bool CUIFixedScrollBar::InitScrollBar(Fvector2 pos, bool horizontal, cpcstr prof { inherited::SetWndSize(Fvector2().set(width_v, height_v)); - strconcat(sizeof(_path), _path, profile, ":up_arrow"); + strconcat(_path, profile, ":up_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_DecButton); - strconcat(sizeof(_path), _path, profile, ":down_arrow"); + strconcat(_path, profile, ":down_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_IncButton); - strconcat(sizeof(_path), _path, profile, ":box_v"); + strconcat(_path, profile, ":box_v"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_ScrollBox); - strconcat(sizeof(_path), _path, profile, ":back_v"); + strconcat(_path, profile, ":back_v"); if (!CUIXmlInitBase::InitFrameLine(xml_doc, _path, 0, m_FrameBackground, false)) return false; @@ -90,7 +89,7 @@ void CUIFixedScrollBar::UpdateScrollBar() GetWidth() - m_IncButton->GetWidth() - m_DecButton->GetWidth() - 2 * m_ScrollBoxOffset.x); m_ScrollBox->SetWidth(box_sz); // set pos - int pos = PosViewFromScroll(iFloor(box_sz), iFloor(GetHeight())); + const int pos = PosViewFromScroll(iFloor(box_sz), iFloor(GetHeight())); m_ScrollBox->SetWndPos(Fvector2().set(float(pos), m_ScrollBox->GetWndRect().top)); m_IncButton->SetWndPos(Fvector2().set(GetWidth() - m_IncButton->GetWidth(), 0.0f)); } @@ -101,7 +100,7 @@ void CUIFixedScrollBar::UpdateScrollBar() GetHeight() - m_IncButton->GetHeight() - m_DecButton->GetHeight() - 2 * m_ScrollBoxOffset.y); m_ScrollBox->SetHeight(box_sz); // set pos - int pos = PosViewFromScroll(iFloor(box_sz), iFloor(GetWidth())); + const int pos = PosViewFromScroll(iFloor(box_sz), iFloor(GetWidth())); m_ScrollBox->SetWndPos(Fvector2().set(m_ScrollBox->GetWndRect().left, float(pos))); m_IncButton->SetWndPos(Fvector2().set(0.0f, GetHeight() - m_IncButton->GetHeight())); } @@ -186,7 +185,7 @@ bool CUIFixedScrollBar::OnMouseAction(float x, float y, EUIMessages mouse_action } case WINDOW_MOUSE_MOVE: { - bool im_capturer = (GetMouseCapturer() == m_ScrollBox); + const bool im_capturer = (GetMouseCapturer() == m_ScrollBox); bool cursor_over = false; Fvector2 cursor_pos = GetUICursor().GetCursorPosition(); Frect box_rect; @@ -202,7 +201,7 @@ bool CUIFixedScrollBar::OnMouseAction(float x, float y, EUIMessages mouse_action if (im_capturer && cursor_over) { Fvector2 pos = m_ScrollBox->GetWndPos(); - Fvector2 delta = GetUICursor().GetCursorPositionDelta(); + const Fvector2 delta = GetUICursor().GetCursorPositionDelta(); if (m_bIsHorizontal) pos.x += delta.x; else @@ -312,9 +311,9 @@ void CUIFixedScrollBar::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) void CUIFixedScrollBar::SetPosScrollFromView(float view_pos, float view_size, float view_offs) { - int scroll_size = ScrollSize(); - float pos = view_pos - view_offs; - float work_size = m_ScrollWorkArea - view_size; + const int scroll_size = ScrollSize(); + const float pos = view_pos - view_offs; + const float work_size = m_ScrollWorkArea - view_size; m_iScrollPos = work_size ? iFloor(((pos / work_size) * (scroll_size) + m_iMinPos)) : 0; clamp(m_iScrollPos, m_iMinPos, m_iMaxPos - m_iPageSize + 1); UpdateScrollBar(); diff --git a/src/xrUICore/ScrollBar/UIFixedScrollBar.h b/src/xrUICore/ScrollBar/UIFixedScrollBar.h index 5237488261e..6b48c7d97e3 100644 --- a/src/xrUICore/ScrollBar/UIFixedScrollBar.h +++ b/src/xrUICore/ScrollBar/UIFixedScrollBar.h @@ -12,16 +12,17 @@ class XRUICORE_API CUIFixedScrollBar final : public CUIScrollBar protected: CUI3tButton* m_ScrollBox; - Ivector2 m_ScrollBoxOffset; + Ivector2 m_ScrollBoxOffset{}; void UpdateScrollBar() override; void ClampByViewRect() override; - void SetPosScrollFromView(float view_pos, float view_width, float view_offs) override; + void SetPosScrollFromView(float view_pos, float view_size, float view_offs) override; public: CUIFixedScrollBar(); - ~CUIFixedScrollBar() override; + virtual bool InitScrollBar(Fvector2 pos, bool horizontal, cpcstr profile = "pda"); + void SetWidth(float /*width*/) override {} void SetHeight(float /*height*/) override {} void Draw() override { inherited::Draw(); } diff --git a/src/xrUICore/ScrollBar/UIScrollBar.cpp b/src/xrUICore/ScrollBar/UIScrollBar.cpp index def2944bb10..73ccddd3b2e 100644 --- a/src/xrUICore/ScrollBar/UIScrollBar.cpp +++ b/src/xrUICore/ScrollBar/UIScrollBar.cpp @@ -6,30 +6,22 @@ #include "XML/UITextureMaster.h" #include "Cursor/UICursor.h" -CUIScrollBar::CUIScrollBar() : CUIWindow("CUIScrollBar") +CUIScrollBar::CUIScrollBar() + : CUIWindow("CUIScrollBar"), + m_DecButton(xr_new()), + m_IncButton(xr_new()), + m_ScrollBox(xr_new()), + m_FrameBackground(xr_new("Frame background")) { - m_iMinPos = 1; - m_iMaxPos = 1; - m_iPageSize = 1; - m_iStepSize = 1; - m_iScrollPos = 0; - m_hold_delay = 50.0f; - m_b_enabled = true; - m_mouse_state = 0; - - m_DecButton = xr_new(); m_DecButton->SetAutoDelete(true); AttachChild(m_DecButton); - m_IncButton = xr_new(); m_IncButton->SetAutoDelete(true); AttachChild(m_IncButton); - m_ScrollBox = xr_new(); m_ScrollBox->SetAutoDelete(true); AttachChild(m_ScrollBox); - m_FrameBackground = xr_new("Frame background"); m_FrameBackground->SetAutoDelete(true); AttachChild(m_FrameBackground); } @@ -63,17 +55,17 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, { inherited::SetWndSize(Fvector2().set(length, height)); - strconcat(sizeof(_path), _path, profile, ":left_arrow"); + strconcat(_path, profile, ":left_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_DecButton); m_DecButton->SetWndPos(Fvector2().set(0, 0)); - strconcat(sizeof(_path), _path, profile, ":right_arrow"); + strconcat(_path, profile, ":right_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_IncButton); m_IncButton->SetWndPos(Fvector2().set(length - m_IncButton->GetWidth(), 0.0f)); m_ScrollBox->SetHorizontal(true); - strconcat(sizeof(_path), _path, profile, ":box"); + strconcat(_path, profile, ":box"); if (!CUIXmlInitBase::InitFrameLine(xml_doc, _path, 0, m_ScrollBox, false)) { tempScroll = xr_new("temporary scroll"); @@ -81,15 +73,15 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, tempScroll->Show(true); } - strconcat(sizeof(_path), _path, profile, ":back:texture"); - LPCSTR texture = xml_doc.Read(_path, 0, nullptr); + strconcat(_path, profile, ":back:texture"); + cpcstr texture = xml_doc.Read(_path, 0, nullptr); R_ASSERT(texture); if (!m_FrameBackground->InitTexture(texture, "hud" DELIMITER "default", false)) { tempBackground = xr_new("temporary background"); tempBackground->SetWndRect(GetWndRect()); - strconcat(sizeof(_path), _path, profile, ":back"); + strconcat(_path, profile, ":back"); if (CUIXmlInitBase::InitStatic(xml_doc, _path, 0, tempBackground, false)) tempBackground->Show(true); } @@ -100,17 +92,17 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, { inherited::SetWndSize(Fvector2().set(height, length)); - strconcat(sizeof(_path), _path, profile, ":up_arrow"); + strconcat(_path, profile, ":up_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_DecButton); m_DecButton->SetWndPos(Fvector2().set(0, 0)); - strconcat(sizeof(_path), _path, profile, ":down_arrow"); + strconcat(_path, profile, ":down_arrow"); CUIXmlInitBase::Init3tButton(xml_doc, _path, 0, m_IncButton); m_IncButton->SetWndPos(Fvector2().set(0.0f, length - m_IncButton->GetHeight())); m_ScrollBox->SetHorizontal(false); - strconcat(sizeof(_path), _path, profile, ":box_v"); + strconcat(_path, profile, ":box_v"); if (!CUIXmlInitBase::InitFrameLine(xml_doc, _path, 0, m_ScrollBox, false)) { tempScroll = xr_new("temporary scroll"); @@ -118,15 +110,15 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, tempScroll->Show(true); } - strconcat(sizeof(_path), _path, profile, ":back_v:texture"); - LPCSTR texture = xml_doc.Read(_path, 0, nullptr); + strconcat(_path, profile, ":back_v:texture"); + cpcstr texture = xml_doc.Read(_path, 0, nullptr); R_ASSERT(texture); if (!m_FrameBackground->InitTexture(texture, "hud" DELIMITER "default", false)) { tempBackground = xr_new("temporary background"); tempBackground->SetWndRect(GetWndRect()); - strconcat(sizeof(_path), _path, profile, ":back_v"); + strconcat(_path, profile, ":back_v"); if (CUIXmlInitBase::InitStatic(xml_doc, _path, 0, tempBackground, false)) tempBackground->Show(true); } @@ -185,7 +177,7 @@ void CUIScrollBar::SetWidth(float width) inherited::SetWidth(width); if (m_bIsHorizontal) { - float work_area = float(width) - m_DecButton->GetWidth() - m_IncButton->GetWidth(); + const float work_area = float(width) - m_DecButton->GetWidth() - m_IncButton->GetWidth(); m_ScrollWorkArea = work_area < 0.f ? 0 : int(work_area); } UpdateScrollBar(); @@ -198,7 +190,7 @@ void CUIScrollBar::SetHeight(float height) inherited::SetHeight(height); if (!m_bIsHorizontal) { - float work_area = float(height) - m_DecButton->GetHeight() - m_IncButton->GetHeight(); + const float work_area = float(height) - m_DecButton->GetHeight() - m_IncButton->GetHeight(); m_ScrollWorkArea = work_area < 0.f ? 0 : int(work_area); } UpdateScrollBar(); @@ -252,7 +244,7 @@ void CUIScrollBar::UpdateScrollBar() m_ScrollBox->SetHeight(GetHeight()); // set pos - int pos = PosViewFromScroll(iFloor(m_ScrollBox->GetWidth()), iFloor(GetHeight())); + const int pos = PosViewFromScroll(iFloor(m_ScrollBox->GetWidth()), iFloor(GetHeight())); m_ScrollBox->SetWndPos(Fvector2().set(float(pos), m_ScrollBox->GetWndRect().top)); m_IncButton->SetWndPos(Fvector2().set(GetWidth() - m_IncButton->GetWidth(), 0.0f)); } @@ -265,7 +257,7 @@ void CUIScrollBar::UpdateScrollBar() m_ScrollBox->SetWidth(GetWidth()); // set pos - int pos = PosViewFromScroll(iFloor(m_ScrollBox->GetHeight()), iFloor(GetWidth())); + const int pos = PosViewFromScroll(iFloor(m_ScrollBox->GetHeight()), iFloor(GetWidth())); m_ScrollBox->SetWndPos(Fvector2().set(m_ScrollBox->GetWndRect().left, float(pos))); m_IncButton->SetWndPos(Fvector2().set(0.0f, GetHeight() - m_IncButton->GetHeight())); } @@ -320,7 +312,7 @@ bool CUIScrollBar::OnMouseAction(float x, float y, EUIMessages mouse_action) m_mouse_state = 0; break; } - }; + } // switch (mouse_action) return inherited::OnMouseAction(x, y, mouse_action); } @@ -336,6 +328,7 @@ bool CUIScrollBar::OnMouseDown(int mouse_btn) } return inherited::OnMouseDown(mouse_btn); } + bool CUIScrollBar::OnMouseDownEx() { Fvector2 cursor_pos = GetUICursor().GetCursorPosition(); @@ -411,16 +404,16 @@ void CUIScrollBar::ClampByViewRect() void CUIScrollBar::SetPosScrollFromView(float view_pos, float view_size, float view_offs) { - int scroll_size = ScrollSize(); - float pos = view_pos - view_offs; - float work_size = m_ScrollWorkArea - view_size; + const int scroll_size = ScrollSize(); + const float pos = view_pos - view_offs; + const float work_size = m_ScrollWorkArea - view_size; SetScrollPosClamped(work_size ? iFloor(((pos / work_size) * (scroll_size) + m_iMinPos)) : 0); } -int CUIScrollBar::PosViewFromScroll(int view_size, int view_offs) +int CUIScrollBar::PosViewFromScroll(int view_size, int view_offs) const { - int work_size = m_ScrollWorkArea - view_size; - int scroll_size = ScrollSize(); + const int work_size = m_ScrollWorkArea - view_size; + const int scroll_size = ScrollSize(); return scroll_size ? (m_iScrollPos * work_size + scroll_size * view_offs - m_iMinPos * work_size) / scroll_size : 0; } @@ -523,25 +516,25 @@ void CUIScrollBar::Reset() inherited::Reset(); } -bool CUIScrollBar::IsRelevant() +bool CUIScrollBar::IsRelevant() const { - bool b_can_inc = (m_iScrollPos <= (m_iMaxPos - m_iPageSize)); - bool b_can_dec = (m_iScrollPos > m_iMinPos); - return b_can_inc || b_can_dec; + const bool can_inc = m_iScrollPos <= (m_iMaxPos - m_iPageSize); + const bool can_dec = m_iScrollPos > m_iMinPos; + return can_inc || can_dec; } void CUIScrollBar::Draw() { if (m_bIsHorizontal) { - float size = GetWidth() - m_DecButton->GetWidth() - m_IncButton->GetWidth(); + const float size = GetWidth() - m_DecButton->GetWidth() - m_IncButton->GetWidth(); m_FrameBackground->SetWndSize(Fvector2().set(size, GetHeight())); m_FrameBackground->SetWndPos(Fvector2().set(m_DecButton->GetWidth(), 0.0f)); } else { - float size = GetHeight() - m_IncButton->GetHeight() - m_DecButton->GetHeight(); + const float size = GetHeight() - m_IncButton->GetHeight() - m_DecButton->GetHeight(); m_FrameBackground->SetWndSize(Fvector2().set(GetWidth(), size)); m_FrameBackground->SetWndPos(Fvector2().set(0.0f, m_DecButton->GetHeight())); @@ -549,4 +542,4 @@ void CUIScrollBar::Draw() inherited::Draw(); } -void CUIScrollBar::Refresh() { SendMessage(m_ScrollBox, SCROLLBOX_MOVE, NULL); } +void CUIScrollBar::Refresh() { SendMessage(m_ScrollBox, SCROLLBOX_MOVE, nullptr); } diff --git a/src/xrUICore/ScrollBar/UIScrollBar.h b/src/xrUICore/ScrollBar/UIScrollBar.h index 8edbc2f6f7f..e487c86f83a 100644 --- a/src/xrUICore/ScrollBar/UIScrollBar.h +++ b/src/xrUICore/ScrollBar/UIScrollBar.h @@ -16,33 +16,33 @@ class XRUICORE_API CUIScrollBar : public CUIWindow CUIScrollBox* m_ScrollBox; CUIFrameLineWnd* m_FrameBackground; - float m_hold_delay; - int m_iScrollPos; + float m_hold_delay{ 50.0f }; + int m_iScrollPos{}; - int m_iStepSize; + int m_iStepSize{ 1 }; - int m_iMinPos; - int m_iMaxPos; + int m_iMinPos{ 1 }; + int m_iMaxPos{ 1 }; - int m_iPageSize; + int m_iPageSize{ 1 }; int m_ScrollWorkArea; - bool m_b_enabled; + bool m_b_enabled{ true }; bool m_bIsHorizontal; - int m_mouse_state; + int m_mouse_state{}; bool ScrollInc(bool by_scrollbox = false); bool ScrollDec(bool by_scrollbox = false); virtual void UpdateScrollBar(); - u32 ScrollSize() { return _max(1, m_iMaxPos - m_iMinPos - m_iPageSize + 1); } + u32 ScrollSize() const { return _max(1, m_iMaxPos - m_iMinPos - m_iPageSize + 1); } virtual void ClampByViewRect(); - virtual void SetPosScrollFromView(float view_pos, float view_width, float view_offs); - int PosViewFromScroll(int view_size, int view_offs); + virtual void SetPosScrollFromView(float view_pos, float view_size, float view_offs); + int PosViewFromScroll(int view_size, int view_offs) const; void SetScrollPosClamped(int iPos); - bool IsRelevant(); + bool IsRelevant() const; public: CUIScrollBar(); @@ -53,7 +53,7 @@ class XRUICORE_API CUIScrollBar : public CUIWindow if (!m_b_enabled) Show(m_b_enabled); } - bool GetEnabled() { return m_b_enabled; } + bool GetEnabled() const { return m_b_enabled; } virtual void Show(bool b); virtual void Enable(bool b); virtual bool InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, cpcstr profile = "default"); @@ -73,27 +73,27 @@ class XRUICORE_API CUIScrollBar : public CUIWindow virtual void Reset(); void Refresh(); void SetStepSize(int step); - IC int GetStepSize() { return m_iStepSize; } + IC int GetStepSize() const { return m_iStepSize; } void SetRange(int iMin, int iMax); - void GetRange(int& iMin, int& iMax) + void GetRange(int& iMin, int& iMax) const { iMin = m_iMinPos; iMax = m_iMaxPos; } - int GetMaxRange() { return m_iMaxPos; } - int GetMinRange() { return m_iMinPos; } + int GetMaxRange() const { return m_iMaxPos; } + int GetMinRange() const { return m_iMinPos; } void SetPageSize(int iPage) { m_iPageSize = _max(0, iPage); UpdateScrollBar(); } - int GetPageSize() { return m_iPageSize; } + int GetPageSize() const { return m_iPageSize; } void SetScrollPos(int iPos) { SetScrollPosClamped(iPos); UpdateScrollBar(); } - int GetScrollPos() { return _max(m_iMinPos, m_iScrollPos); } + int GetScrollPos() const { return _max(m_iMinPos, m_iScrollPos); } void TryScrollInc(bool by_scrollbox = false); void TryScrollDec(bool by_scrollbox = false); diff --git a/src/xrUICore/ScrollView/UIScrollView.cpp b/src/xrUICore/ScrollView/UIScrollView.cpp index 17890208247..9ff530ba26d 100644 --- a/src/xrUICore/ScrollView/UIScrollView.cpp +++ b/src/xrUICore/ScrollView/UIScrollView.cpp @@ -8,28 +8,12 @@ CUIScrollView::CUIScrollView() : CUIWindow("CUIScrollView") { - m_rightIndent = 0.0f; - m_leftIndent = 0.0f; - m_vertInterval = 0.0f; - m_upIndent = 0.0f; - m_downIndent = 0.0f; - m_flags.zero(); SetFixedScrollBar(true); - m_pad = NULL; - m_VScrollBar = NULL; - m_visible_rgn.set(-1, -1); } + CUIScrollView::CUIScrollView(CUIScrollBar* scroll_bar) : CUIWindow("CUIScrollView") { - m_rightIndent = 0.0f; - m_leftIndent = 0.0f; - m_vertInterval = 0.0f; - m_upIndent = 0.0f; - m_downIndent = 0.0f; - m_flags.zero(); SetFixedScrollBar(true); - m_pad = NULL; - m_visible_rgn.set(-1, -1); m_VScrollBar = scroll_bar; m_VScrollBar->SetAutoDelete(true); @@ -43,10 +27,10 @@ void CUIScrollView::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { CUIWndCallback::OnEvent(pWnd, msg, pData); if (CHILD_CHANGED_SIZE == msg && m_pad->IsChild(pWnd)) - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } -void CUIScrollView::ForceUpdate() { m_flags.set(eNeedRecalc, TRUE); } +void CUIScrollView::ForceUpdate() { m_flags.set(eNeedRecalc, true); } void CUIScrollView::InitScrollView() { if (!m_pad) @@ -88,7 +72,7 @@ void CUIScrollView::InitScrollView() GetWndSize().y, false); } - Fvector2 sc_pos = {m_VScrollBar->GetWndPos().x - m_VScrollBar->GetWndSize().x, m_VScrollBar->GetWndPos().y}; + const Fvector2 sc_pos = {m_VScrollBar->GetWndPos().x - m_VScrollBar->GetWndSize().x, m_VScrollBar->GetWndPos().y}; m_VScrollBar->SetWndPos(sc_pos); m_VScrollBar->SetWindowName("scroll_v"); m_VScrollBar->SetStepSize(_max(1, iFloor(GetHeight() / 10))); @@ -102,19 +86,19 @@ void CUIScrollView::AddWindow(CUIWindow* pWnd, bool auto_delete) pWnd->SetAutoDelete(true); m_pad->AttachChild(pWnd); - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } void CUIScrollView::RemoveWindow(CUIWindow* pWnd) { m_pad->DetachChild(pWnd); - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } void CUIScrollView::Clear() { m_pad->DetachAll(); - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); ScrollToBegin(); } @@ -154,7 +138,7 @@ void CUIScrollView::RecalcSize() if (GetVertFlip()) { - for (WINDOW_LIST::reverse_iterator it = m_pad->GetChildWndList().rbegin(); + for (auto it = m_pad->GetChildWndList().rbegin(); m_pad->GetChildWndList().rend() != it; ++it) { (*it)->SetWndPos(item_pos); @@ -167,14 +151,14 @@ void CUIScrollView::RecalcSize() } else { - for (auto it = m_pad->GetChildWndList().begin(); m_pad->GetChildWndList().end() != it; ++it) + for (auto* it : m_pad->GetChildWndList()) { - (*it)->SetWndPos(item_pos); - item_pos.y += (*it)->GetWndSize().y; + it->SetWndPos(item_pos); + item_pos.y += it->GetWndSize().y; item_pos.y += m_vertInterval; - pad_size.y += (*it)->GetWndSize().y; + pad_size.y += it->GetWndSize().y; pad_size.y += m_vertInterval; - pad_size.x = _max(pad_size.x, (*it)->GetWndSize().x); + pad_size.x = _max(pad_size.x, it->GetWndSize().x); } }; @@ -185,22 +169,22 @@ void CUIScrollView::RecalcSize() UpdateScroll(); - m_flags.set(eNeedRecalc, FALSE); + m_flags.set(eNeedRecalc, false); m_visible_rgn.set(-1, -1); } void CUIScrollView::UpdateScroll() { - Fvector2 w_pos = m_pad->GetWndPos(); + const Fvector2 w_pos = m_pad->GetWndPos(); m_VScrollBar->SetHeight(GetHeight()); m_VScrollBar->SetRange(0, iFloor(m_pad->GetHeight() * Scroll2ViewV())); m_VScrollBar->SetScrollPos(iFloor(-w_pos.y)); } -float CUIScrollView::Scroll2ViewV() +float CUIScrollView::Scroll2ViewV() const { - float h = m_VScrollBar->GetHeight(); + const float h = m_VScrollBar->GetHeight(); return (h + GetVertIndent()) / h; } @@ -254,11 +238,15 @@ void CUIScrollView::Draw() m_VScrollBar->Draw(); } -bool CUIScrollView::NeedShowScrollBar() { return m_flags.test(eFixedScrollBar) || GetHeight() < m_pad->GetHeight(); } +bool CUIScrollView::NeedShowScrollBar() const +{ + return m_flags.test(eFixedScrollBar) || GetHeight() < m_pad->GetHeight(); +} + void CUIScrollView::OnScrollV(CUIWindow*, void*) { - int s_pos = m_VScrollBar->GetScrollPos(); - Fvector2 w_pos = m_pad->GetWndPos(); + const int s_pos = m_VScrollBar->GetScrollPos(); + const Fvector2 w_pos = m_pad->GetWndPos(); m_pad->SetWndPos(Fvector2().set(w_pos.x, float(-s_pos))); m_visible_rgn.set(-1, -1); } @@ -268,7 +256,7 @@ bool CUIScrollView::OnMouseAction(float x, float y, EUIMessages mouse_action) if (inherited::OnMouseAction(x, y, mouse_action)) return true; bool res = false; - int prev_pos = m_VScrollBar->GetScrollPos(); + const int prev_pos = m_VScrollBar->GetScrollPos(); switch (mouse_action) { case WINDOW_MOUSE_WHEEL_UP: @@ -300,9 +288,10 @@ bool CUIScrollView::OnMouseAction(float x, float y, EUIMessages mouse_action) return res; } -int CUIScrollView::GetMinScrollPos() { return m_VScrollBar->GetMinRange(); } -int CUIScrollView::GetMaxScrollPos() { return m_VScrollBar->GetMaxRange(); } -int CUIScrollView::GetCurrentScrollPos() { return m_VScrollBar->GetScrollPos(); } +int CUIScrollView::GetMinScrollPos() const { return m_VScrollBar->GetMinRange(); } +int CUIScrollView::GetMaxScrollPos() const { return m_VScrollBar->GetMaxRange(); } +int CUIScrollView::GetCurrentScrollPos() const { return m_VScrollBar->GetScrollPos(); } + void CUIScrollView::SetScrollPos(int value) { if (m_flags.test(eNeedRecalc)) @@ -310,7 +299,7 @@ void CUIScrollView::SetScrollPos(int value) clamp(value, GetMinScrollPos(), GetMaxScrollPos()); m_VScrollBar->SetScrollPos(value); - OnScrollV(NULL, NULL); + OnScrollV(nullptr, nullptr); } void CUIScrollView::ScrollToBegin() @@ -319,7 +308,7 @@ void CUIScrollView::ScrollToBegin() RecalcSize(); m_VScrollBar->SetScrollPos(m_VScrollBar->GetMinRange()); - OnScrollV(NULL, NULL); + OnScrollV(nullptr, nullptr); } void CUIScrollView::ScrollToEnd() @@ -328,31 +317,31 @@ void CUIScrollView::ScrollToEnd() RecalcSize(); m_VScrollBar->SetScrollPos(m_VScrollBar->GetMaxRange()); - OnScrollV(NULL, NULL); + OnScrollV(nullptr, nullptr); } void CUIScrollView::SetRightIndention(float val) { m_rightIndent = val; - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } void CUIScrollView::SetLeftIndention(float val) { m_leftIndent = val; - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } void CUIScrollView::SetUpIndention(float val) { m_upIndent = val; - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } void CUIScrollView::SetDownIndention(float val) { m_downIndent = val; - m_flags.set(eNeedRecalc, TRUE); + m_flags.set(eNeedRecalc, true); } u32 CUIScrollView::GetSize() const { return m_pad->GetChildNum(); } @@ -360,14 +349,14 @@ u32 CUIScrollView::GetSize() const { return m_pad->GetChildNum(); } CUIWindow* CUIScrollView::GetItem(u32 idx) { if (m_pad->GetChildWndList().size() <= idx) - return NULL; + return nullptr; auto it = m_pad->GetChildWndList().begin(); std::advance(it, idx); - return (*it); + return *it; } -float CUIScrollView::GetDesiredChildWidth() +float CUIScrollView::GetDesiredChildWidth() const { if (NeedShowScrollBar()) return GetWidth() - m_VScrollBar->GetWidth() - m_rightIndent - m_leftIndent; @@ -375,38 +364,39 @@ float CUIScrollView::GetDesiredChildWidth() return GetWidth() - m_rightIndent - m_leftIndent; } -float CUIScrollView::GetHorizIndent() { return m_rightIndent + m_leftIndent; } -float CUIScrollView::GetVertIndent() { return m_upIndent + m_downIndent; } +float CUIScrollView::GetHorizIndent() const { return m_rightIndent + m_leftIndent; } +float CUIScrollView::GetVertIndent() const { return m_upIndent + m_downIndent; } + void CUIScrollView::SetSelected(CUIWindow* w) { if (!m_flags.test(eItemsSelectabe)) return; - for (auto it = m_pad->GetChildWndList().begin(); m_pad->GetChildWndList().end() != it; ++it) + for (auto* it : m_pad->GetChildWndList()) { - smart_cast(*it)->SetSelected(*it == w); + smart_cast(it)->SetSelected(it == w); } } CUIWindow* CUIScrollView::GetSelected() { if (!m_flags.test(eItemsSelectabe)) - return NULL; + return nullptr; - for (auto it = m_pad->GetChildWndList().begin(); m_pad->GetChildWndList().end() != it; ++it) + for (auto* it : m_pad->GetChildWndList()) { - if (smart_cast(*it)->GetSelected()) - return *it; + if (smart_cast(it)->GetSelected()) + return it; } - return NULL; + return nullptr; } void CUIScrollView::UpdateChildrenLenght() { - float len = GetDesiredChildWidth(); - for (auto it = m_pad->GetChildWndList().begin(); m_pad->GetChildWndList().end() != it; ++it) + const float len = GetDesiredChildWidth(); + for (auto* it : m_pad->GetChildWndList()) { - (*it)->SetWidth(len); + it->SetWidth(len); } } diff --git a/src/xrUICore/ScrollView/UIScrollView.h b/src/xrUICore/ScrollView/UIScrollView.h index 0c02a6754c6..4164bc5ffb0 100644 --- a/src/xrUICore/ScrollView/UIScrollView.h +++ b/src/xrUICore/ScrollView/UIScrollView.h @@ -19,19 +19,19 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback eItemsSelectabe = (1 << 3), eInverseDir = (1 << 4) /*,eMultiSelect=(1<<5)*/ }; - CUIScrollBar* m_VScrollBar; - CUIWindow* m_pad; + CUIScrollBar* m_VScrollBar{}; + CUIWindow* m_pad{}; - float m_rightIndent; - float m_leftIndent; - float m_upIndent; - float m_downIndent; + float m_rightIndent{}; + float m_leftIndent{}; + float m_upIndent{}; + float m_downIndent{}; - float m_vertInterval; + float m_vertInterval{}; - Flags16 m_flags; + Flags16 m_flags{}; shared_str m_scrollbar_profile; - Ivector2 m_visible_rgn; + Ivector2 m_visible_rgn{ -1, -1 }; virtual void RecalcSize(); void UpdateScroll(); @@ -56,8 +56,8 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback void Clear(); void ScrollToBegin(); void ScrollToEnd(); - bool GetVertFlip() { return !!m_flags.test(eVertFlip); } - bool Empty() { return m_pad->GetChildWndList().empty(); } + bool GetVertFlip() const { return !!m_flags.test(eVertFlip); } + bool Empty() const { return m_pad->GetChildWndList().empty(); } [[nodiscard]] u32 GetSize() const; @@ -65,21 +65,21 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback WINDOW_LIST& Items() { return m_pad->GetChildWndList(); } CUIWindow* GetItem(u32 idx); void SetFixedScrollBar(bool b); - float GetDesiredChildWidth(); + float GetDesiredChildWidth() const; virtual void SetSelected(CUIWindow*); CUIWindow* GetSelected(); Fvector2 GetPadSize(); void ForceUpdate(); - int GetMinScrollPos(); - int GetMaxScrollPos(); - int GetCurrentScrollPos(); + int GetMinScrollPos() const; + int GetMaxScrollPos() const; + int GetCurrentScrollPos() const; void SetScrollPos(int value); void SetScrollBarProfile(LPCSTR profile); - IC bool NeedShowScrollBar(); // no comment - float GetHorizIndent(); // left + right indent - float GetVertIndent(); // top + bottom indent + IC bool NeedShowScrollBar() const; // no comment + float GetHorizIndent() const; // left + right indent + float GetVertIndent() const; // top + bottom indent void UpdateChildrenLenght(); // set default width for all children - float Scroll2ViewV(); // calculate scale for scroll position + float Scroll2ViewV() const; // calculate scale for scroll position CUIScrollBar* ScrollBar() { return m_VScrollBar; } pcstr GetDebugType() override { return "CUIScrollView"; } diff --git a/src/xrUICore/Windows/UIWindow.h b/src/xrUICore/Windows/UIWindow.h index 2f4ceadf417..555669deb90 100644 --- a/src/xrUICore/Windows/UIWindow.h +++ b/src/xrUICore/Windows/UIWindow.h @@ -77,7 +77,7 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable //ф-ция должна переопределяться // pWnd - указатель на окно, которое послало сообщение // pData - указатель на дополнительные данные, которые могут понадобиться - virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = NULL); + virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = nullptr); virtual void Enable(bool status) { m_bIsEnabled = status; } From 9c5d572e1217511ccd958aa11407a6a4c482e4d0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 20 Feb 2024 08:13:17 +0500 Subject: [PATCH 186/497] xrGame/ui/UICharacterInfo.h: Ability to get an icon through GetIcon() --- src/xrGame/ui/UICharacterInfo.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/xrGame/ui/UICharacterInfo.h b/src/xrGame/ui/UICharacterInfo.h index ff09b7fc398..69e6619a4a4 100644 --- a/src/xrGame/ui/UICharacterInfo.h +++ b/src/xrGame/ui/UICharacterInfo.h @@ -17,17 +17,7 @@ class CUICharacterInfo final : public CUIWindow private: typedef CUIWindow inherited; -protected: - void SetRelation(ALife::ERelationType relation, CHARACTER_GOODWILL goodwill); - void ResetAllStrings(); - void UpdateRelation(); - bool hasOwner() { return (m_ownerID != u16(-1)); } - - // Biography - CUIScrollView* pUIBio{}; - bool m_bForceUpdate{}; - u16 m_ownerID{ u16(-1) }; - +public: enum UIItemType { eIcon = 0, @@ -52,6 +42,18 @@ class CUICharacterInfo final : public CUIWindow eMaxCaption }; + +protected: + void SetRelation(ALife::ERelationType relation, CHARACTER_GOODWILL goodwill); + void ResetAllStrings(); + void UpdateRelation(); + bool hasOwner() { return (m_ownerID != u16(-1)); } + + // Biography + CUIScrollView* pUIBio{}; + bool m_bForceUpdate{}; + u16 m_ownerID{ u16(-1) }; + CUIStatic* m_icons[eMaxCaption]{}; shared_str m_texture_name; u32 m_original_color; @@ -73,6 +75,7 @@ class CUICharacterInfo final : public CUIWindow virtual void Update(); u16 OwnerID() const { return m_ownerID; } + CUIStatic& UIIcon() const { VERIFY(m_icons[eIcon]); @@ -93,6 +96,10 @@ class CUICharacterInfo final : public CUIWindow VERIFY(m_icons[eCommunityCaption]); return *m_icons[eCommunityCaption]; } + CUIStatic* GetIcon(UIItemType icon) const + { + return m_icons[icon]; + } const shared_str& IconName() const { return m_texture_name; } static bool get_actor_community(shared_str* our, shared_str* enemy); From 04cc8e1ebedde626d862b96c23079158ac6d7af1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 20 Feb 2024 08:20:12 +0500 Subject: [PATCH 187/497] Fix misplaced community name in actor statistics window in CS (#382) --- src/xrGame/ui/UIRankingWnd.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/xrGame/ui/UIRankingWnd.cpp b/src/xrGame/ui/UIRankingWnd.cpp index fa48f8301bd..969e504e174 100644 --- a/src/xrGame/ui/UIRankingWnd.cpp +++ b/src/xrGame/ui/UIRankingWnd.cpp @@ -85,6 +85,17 @@ bool CUIRankingWnd::Init() AttachChild(m_actor_ch_info); m_actor_ch_info->InitCharacterInfo(&xml, "actor_ch_info"); + auto* community = m_actor_ch_info->GetIcon(CUICharacterInfo::eCommunity); + auto* communityCaption = m_actor_ch_info->GetIcon(CUICharacterInfo::eCommunityCaption); + + if (community && communityCaption) + { + communityCaption->AdjustWidthToText(); + pos = community->GetWndPos(); + pos.x = communityCaption->GetWndPos().x + communityCaption->GetWndSize().x + 10.0f; + community->SetWndPos(pos); + } + std::ignore = UIHelper::CreateFrameWindow(xml, "actor_icon_over", this, false); auto* money_caption = UIHelper::CreateStatic(xml, "money_caption", this); m_money_value = UIHelper::CreateStatic(xml, "money_value", this); From c6397dc168fb33069c9d2087685457dfd5a51eeb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 21 Feb 2024 00:30:59 +0500 Subject: [PATCH 188/497] xrGame/UIKickPlayer.cpp: return kick/ban list UI background in CS (#382) --- src/xrGame/ui/UIKickPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/ui/UIKickPlayer.cpp b/src/xrGame/ui/UIKickPlayer.cpp index b6133addc22..76f02f56d5d 100644 --- a/src/xrGame/ui/UIKickPlayer.cpp +++ b/src/xrGame/ui/UIKickPlayer.cpp @@ -55,7 +55,7 @@ void CUIKickPlayer::Init_internal(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "kick_ban", 0, this); CUIXmlInit::InitStatic(xml_doc, "kick_ban:background", 0, bkgrnd); - // CUIXmlInit::InitFrameWindow (xml_doc, "kick_ban:list_back", 0, lst_back); + CUIXmlInit::InitFrameWindow(xml_doc, "kick_ban:list_back", 0, lst_back, false); CUIXmlInit::InitListBox(xml_doc, "kick_ban:list", 0, m_ui_players_list); CUIXmlInit::Init3tButton(xml_doc, "kick_ban:btn_ok", 0, btn_ok); CUIXmlInit::Init3tButton(xml_doc, "kick_ban:btn_cancel", 0, btn_cancel); From aa1e4f02054af431e7aac6c94ddf6c95d64cacc3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 21 Feb 2024 01:11:29 +0500 Subject: [PATCH 189/497] Return removed CUIScriptWnd functionality from CS (#382) --- src/xrGame/ui/UIScriptWnd.cpp | 8 ++++++++ src/xrGame/ui/UIScriptWnd.h | 1 + src/xrGame/ui/UIScriptWnd_script.cpp | 19 +++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/xrGame/ui/UIScriptWnd.cpp b/src/xrGame/ui/UIScriptWnd.cpp index 997d6453bcf..19d72749b8b 100644 --- a/src/xrGame/ui/UIScriptWnd.cpp +++ b/src/xrGame/ui/UIScriptWnd.cpp @@ -33,6 +33,14 @@ SCallbackInfo* CUIDialogWndEx::NewCallback() return m_callbacks.back(); } +void CUIDialogWndEx::AddCallback(LPCSTR control_id, s16 evt, const luabind::functor &lua_function) +{ + SCallbackInfo* c = NewCallback (); + c->m_callback.set(lua_function); + c->m_control_name = control_id; + c->m_event = evt; +} + void CUIDialogWndEx::AddCallback(pcstr control_id, s16 evt, const luabind::functor& functor, const luabind::object& object) { SCallbackInfo* c = NewCallback(); diff --git a/src/xrGame/ui/UIScriptWnd.h b/src/xrGame/ui/UIScriptWnd.h index bff00978157..16e96ae1370 100644 --- a/src/xrGame/ui/UIScriptWnd.h +++ b/src/xrGame/ui/UIScriptWnd.h @@ -24,6 +24,7 @@ class CUIDialogWndEx : public CUIDialogWnd, public FactoryObjectBase CUIDialogWndEx(); ~CUIDialogWndEx() override; + void AddCallback(pcstr control_id, s16 event, const luabind::functor& lua_function); void AddCallback(pcstr control_id, s16 event, const luabind::functor& functor, const luabind::object& object); template diff --git a/src/xrGame/ui/UIScriptWnd_script.cpp b/src/xrGame/ui/UIScriptWnd_script.cpp index ebd727568a1..3b6ee495705 100644 --- a/src/xrGame/ui/UIScriptWnd_script.cpp +++ b/src/xrGame/ui/UIScriptWnd_script.cpp @@ -4,6 +4,10 @@ #include "xrUICore/ListWnd/UIListWnd.h" #include "xrUICore/TabControl/UITabControl.h" +#include "xrUICore/Buttons/UICheckButton.h" +#include "xrUICore/Buttons/UIRadioButton.h" +#include "xrUICore/MessageBox/UIMessageBox.h" +#include "xrUICore/PropertiesBox/UIPropertiesBox.h" #include "xrScriptEngine/ScriptExporter.hpp" @@ -206,13 +210,24 @@ SCRIPT_EXPORT(CUIDialogWndEx, (CUIDialogWnd, IFactoryObject), [ class_, luabind::default_holder, WrapType>("CUIScriptWnd") .def(constructor<>()) - .def("AddCallback", &BaseType::AddCallback) - .def("Register", (void (BaseType::*)(CUIWindow*, pcstr)) & BaseType::Register) + + .def("AddCallback", (void(BaseType::*)(pcstr, s16, const luabind::functor&)) &BaseType::AddCallback) + .def("AddCallback", (void(BaseType::*)(pcstr, s16, const luabind::functor&, const luabind::object&)) &BaseType::AddCallback) + + .def("Register", (void (BaseType::*)(CUIWindow*)) &BaseType::Register) + .def("Register", (void (BaseType::*)(CUIWindow*, pcstr)) &BaseType::Register) + .def("OnKeyboard", &BaseType::OnKeyboardAction, &WrapType::OnKeyboard_static) .def("Update", &BaseType::Update, &WrapType::Update_static) .def("Dispatch", &BaseType::Dispatch, &WrapType::Dispatch_static) .def("Load", &BaseType::Load) + .def("GetButton", &BaseType::GetControl) + .def("GetMessageBox", &BaseType::GetControl) + .def("GetPropertiesBox",&BaseType::GetControl) + .def("GetCheckButton", &BaseType::GetControl) + .def("GetRadioButton", &BaseType::GetControl) + // .def("GetRadioGroup", &BaseType::GetControl) .def("GetStatic", &BaseType::GetControl) .def("GetEditBox", &BaseType::GetControl) .def("GetDialogWnd", &BaseType::GetControl) From 4aa42d03d6adbbc2162fe0d9d1e3bca59d682843 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 21 Feb 2024 04:42:19 +0500 Subject: [PATCH 190/497] Show only secondary tasks in task list in Clear Sky (#382) --- src/xrGame/ui/UISecondTaskWnd.cpp | 2 ++ src/xrGame/ui/UISecondTaskWnd.h | 4 +++- src/xrGame/ui/UITaskWnd.cpp | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xrGame/ui/UISecondTaskWnd.cpp b/src/xrGame/ui/UISecondTaskWnd.cpp index a66a79b4437..2c07dbe3fa7 100644 --- a/src/xrGame/ui/UISecondTaskWnd.cpp +++ b/src/xrGame/ui/UISecondTaskWnd.cpp @@ -147,6 +147,8 @@ void UITaskListWnd::UpdateList() if (!task || task->GetTaskState() != eTaskStateInProgress) continue; + if (m_show_only_secondary_tasks && task->GetTaskType() == eTaskTypeStoryline) + continue; auto* item = xr_new(); if (item->init_task(task, this)) diff --git a/src/xrGame/ui/UISecondTaskWnd.h b/src/xrGame/ui/UISecondTaskWnd.h index 9d5c3455d27..419ef64708b 100644 --- a/src/xrGame/ui/UISecondTaskWnd.h +++ b/src/xrGame/ui/UISecondTaskWnd.h @@ -43,6 +43,8 @@ class UITaskListWnd final : public CUIWindow, public CUIWndCallback virtual void Update(); virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); + void ShowOnlySecondaryTasks(bool mode) { m_show_only_secondary_tasks = mode; } + void UpdateList(); pcstr GetDebugType() override { return "UITaskListWnd"; } @@ -63,7 +65,7 @@ class UITaskListWnd final : public CUIWindow, public CUIWndCallback CUI3tButton* m_bt_close{}; float m_orig_h{}; - + bool m_show_only_secondary_tasks{}; }; // class UITaskListWnd // ------------------------------------------------------------------------------------------------- diff --git a/src/xrGame/ui/UITaskWnd.cpp b/src/xrGame/ui/UITaskWnd.cpp index 945c66ef026..52add68dccf 100644 --- a/src/xrGame/ui/UITaskWnd.cpp +++ b/src/xrGame/ui/UITaskWnd.cpp @@ -91,6 +91,7 @@ bool CUITaskWnd::Init() m_task_wnd->SetAutoDelete(true); m_task_wnd->hint_wnd = hint_wnd; m_task_wnd->init_from_xml(xml, "second_task_wnd"); + m_task_wnd->ShowOnlySecondaryTasks(m_pSecondaryTaskItem != nullptr); m_pMapWnd->AttachChild(m_task_wnd); m_task_wnd->SetMessageTarget(this); From 29994fee31e6998209a8880c3b366eb5e66a32c4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 21 Feb 2024 05:07:05 +0500 Subject: [PATCH 191/497] xrGame: removed excess variable and simplified code in CUITaskWnd and UITaskListWnd --- src/xrGame/ui/UISecondTaskWnd.cpp | 5 +---- src/xrGame/ui/UITaskWnd.cpp | 13 ++----------- src/xrGame/ui/UITaskWnd.h | 5 ++--- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/xrGame/ui/UISecondTaskWnd.cpp b/src/xrGame/ui/UISecondTaskWnd.cpp index 2c07dbe3fa7..580df5cf850 100644 --- a/src/xrGame/ui/UISecondTaskWnd.cpp +++ b/src/xrGame/ui/UISecondTaskWnd.cpp @@ -18,7 +18,6 @@ #include "xrUICore/Windows/UIFrameLineWnd.h" #include "xrUICore/ScrollBar/UIFixedScrollBar.h" #include "xrUICore/Hint/UIHint.h" -#include "UITaskWnd.h" #include "GameTaskDefs.h" #include "GameTask.h" #include "map_location.h" @@ -126,9 +125,7 @@ void UITaskListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) void UITaskListWnd::OnBtnClose(CUIWindow* w, void* d) { - if (auto* wnd = smart_cast(GetParent()->GetParent())) - wnd->Show_TaskListWnd(false); - // Show( false ); + Show(false); m_bt_close->SetButtonState(CUIButton::BUTTON_NORMAL); } diff --git a/src/xrGame/ui/UITaskWnd.cpp b/src/xrGame/ui/UITaskWnd.cpp index 52add68dccf..6d89b428390 100644 --- a/src/xrGame/ui/UITaskWnd.cpp +++ b/src/xrGame/ui/UITaskWnd.cpp @@ -96,7 +96,6 @@ bool CUITaskWnd::Init() m_pMapWnd->AttachChild(m_task_wnd); m_task_wnd->SetMessageTarget(this); m_task_wnd->Show(false); - m_task_wnd_show = false; m_map_legend_wnd = xr_new(); m_map_legend_wnd->SetAutoDelete(true); @@ -309,25 +308,17 @@ void CUITaskWnd::Show(bool status) if (status) { ReloadTaskInfo(); - m_task_wnd->Show(m_task_wnd_show); - } - else - { - //m_task_wnd_show = false; - m_task_wnd->Show(false); } } -void CUITaskWnd::OnShowTaskListWnd(CUIWindow* w, void* d) +void CUITaskWnd::OnShowTaskListWnd(CUIWindow* w, void* d) const { - m_task_wnd_show = !m_task_wnd_show; m_task_wnd->Show(!m_task_wnd->IsShown()); } -void CUITaskWnd::Show_TaskListWnd(bool status) +void CUITaskWnd::Show_TaskListWnd(bool status) const { m_task_wnd->Show(status); - m_task_wnd_show = status; } void CUITaskWnd::TaskSetTargetMap(CGameTask* task) const diff --git a/src/xrGame/ui/UITaskWnd.h b/src/xrGame/ui/UITaskWnd.h index d2999e3d741..8fbcca1fd1a 100644 --- a/src/xrGame/ui/UITaskWnd.h +++ b/src/xrGame/ui/UITaskWnd.h @@ -39,7 +39,6 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback CUIMapFilters m_filters; UITaskListWnd* m_task_wnd{}; - bool m_task_wnd_show{}; UIMapLegend* m_map_legend_wnd{}; public: @@ -62,7 +61,7 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback void ReloadTaskInfo(); void ShowMapLegend(bool status) const; void Switch_ShowMapLegend() const; - void Show_TaskListWnd(bool status); + void Show_TaskListWnd(bool status) const; [[nodiscard]] bool IsTreasuresEnabled() const { return m_filters.IsFilterEnabled(CUIMapFilters::Treasures); } @@ -82,7 +81,7 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback void TaskSetTargetMap(CGameTask* task) const; void TaskShowMapSpot(CGameTask* task, bool show) const; - void OnShowTaskListWnd(CUIWindow* w, void* d); + void OnShowTaskListWnd(CUIWindow* w, void* d) const; void OnTask1DbClicked(CUIWindow*, void*); void OnTask2DbClicked(CUIWindow*, void*); }; From 02e6e0999500533c49d1cce0618a4421842f129e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 21 Feb 2024 08:00:08 +0500 Subject: [PATCH 192/497] xrGame/UIZoneMap.h|cpp: use CUIStatic for clip frame like in CS (#382) Also, returned CUIMiniMap pointer instead of CUICustomMap (reverts excess change from 4b1d5920268d65a2ce4d6b8af80a39cc84d26597) --- src/xrGame/UIZoneMap.cpp | 2 +- src/xrGame/UIZoneMap.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xrGame/UIZoneMap.cpp b/src/xrGame/UIZoneMap.cpp index a7dff759555..8dfd304b005 100644 --- a/src/xrGame/UIZoneMap.cpp +++ b/src/xrGame/UIZoneMap.cpp @@ -24,7 +24,7 @@ void CUIZoneMap::Init(bool motionIconAttached) uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "zone_map.xml"); CUIXmlInit::InitStatic(uiXml, "minimap:background", 0, &m_background); - CUIXmlInit::InitWindow(uiXml, "minimap:level_frame", 0, &m_clipFrame); + CUIXmlInit::InitStatic(uiXml, "minimap:level_frame", 0, &m_clipFrame); CUIXmlInit::InitStatic(uiXml, "minimap:center", 0, &m_center); m_clock_wnd = UIHelper::CreateStatic(uiXml, "minimap:clock_wnd", &m_background, false); diff --git a/src/xrGame/UIZoneMap.h b/src/xrGame/UIZoneMap.h index 43492b60941..cb73c38265f 100644 --- a/src/xrGame/UIZoneMap.h +++ b/src/xrGame/UIZoneMap.h @@ -3,7 +3,7 @@ #include "xrUICore/Static/UIStatic.h" class CActor; -class CUICustomMap; +class CUIMiniMap; class CUIZoneMap { @@ -11,12 +11,12 @@ class CUIZoneMap bool visible{ true }; private: - CUICustomMap* m_activeMap{}; + CUIMiniMap* m_activeMap{}; CUIStatic m_background{ "Background" }; CUIStatic m_center{ "Center" }; CUIStatic m_compass{ "Compass" }; - CUIWindow m_clipFrame{ "Clip frame" }; + CUIStatic m_clipFrame{ "Clip frame" }; CUIStatic m_Counter{ "Counter" }; CUIStatic m_Counter_text{ "Counter text" }; CUIStatic* m_clock_wnd{}; From 31d6c288b3fba39625758914fb6b0170c93d21e2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 05:41:13 +0500 Subject: [PATCH 193/497] xrGame/ui/UIEditKeyBind.cpp: support texture from SOC/CS (#382, #392) --- src/xrGame/ui/UIEditKeyBind.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/xrGame/ui/UIEditKeyBind.cpp b/src/xrGame/ui/UIEditKeyBind.cpp index 3dcd2f6f12f..d3d228adadc 100644 --- a/src/xrGame/ui/UIEditKeyBind.cpp +++ b/src/xrGame/ui/UIEditKeyBind.cpp @@ -4,6 +4,7 @@ #include "xrEngine/xr_level_controller.h" #include "Common/object_broker.h" #include "xrEngine/XR_IOConsole.h" +#include "xrUICore/XML/UITextureMaster.h" CUIEditKeyBind::CUIEditKeyBind(bool primary, bool isGamepadBinds /*= false*/) : CUIStatic("CUIEditKeyBind") @@ -64,7 +65,14 @@ void CUIEditKeyBind::InitKeyBind(Fvector2 pos, Fvector2 size) { CUIStatic::SetWndPos(pos); CUIStatic::SetWndSize(size); - InitTexture("ui_listline2"); + + if (CUITextureMaster::ItemExist("ui_listline2")) // cop + InitTexture("ui_listline2"); + else if (CUITextureMaster::ItemExist("ui_options_string")) // soc + InitTexture("ui_options_string"); + else if (CUITextureMaster::ItemExist("ui_options_string_back")) // cs (exists in soc also, that's why it's last) + InitTexture("ui_options_string_back"); + TextItemControl()->SetFont(UI().Font().pFontLetterica16Russian); SetStretchTexture(true); SetEditMode(false); From 292b2697274b9b3ad74f0f6588a4aeda7ea32b8d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 08:14:25 +0500 Subject: [PATCH 194/497] xrUICore/XML/UIXmlInitBase.cpp: huge refactoring Modernization, constify, get rid of excess code --- src/xrUICore/XML/UIXmlInitBase.cpp | 399 ++++++++++++++--------------- src/xrUICore/XML/UIXmlInitBase.h | 66 ++--- 2 files changed, 223 insertions(+), 242 deletions(-) diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index dc72f4c86ac..34879efafdc 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -17,21 +17,21 @@ #include "UITextureMaster.h" #include "Lines/UILines.h" -#define ARIAL_FONT_NAME "arial" +constexpr pcstr ARIAL_FONT_NAME = "arial"; -#define MEDIUM_FONT_NAME "medium" -#define SMALL_FONT_NAME "small" +constexpr pcstr MEDIUM_FONT_NAME = "medium"; +constexpr pcstr SMALL_FONT_NAME = "small"; -#define GRAFFITI19_FONT_NAME "graffiti19" -#define GRAFFITI22_FONT_NAME "graffiti22" -#define GRAFFITI32_FONT_NAME "graffiti32" -#define GRAFFITI50_FONT_NAME "graffiti50" +constexpr pcstr GRAFFITI19_FONT_NAME = "graffiti19"; +constexpr pcstr GRAFFITI22_FONT_NAME = "graffiti22"; +constexpr pcstr GRAFFITI32_FONT_NAME = "graffiti32"; +constexpr pcstr GRAFFITI50_FONT_NAME = "graffiti50"; -#define LETTERICA16_FONT_NAME "letterica16" -#define LETTERICA18_FONT_NAME "letterica18" -#define LETTERICA25_FONT_NAME "letterica25" +constexpr pcstr LETTERICA16_FONT_NAME = "letterica16"; +constexpr pcstr LETTERICA18_FONT_NAME = "letterica18"; +constexpr pcstr LETTERICA25_FONT_NAME = "letterica25"; -#define DI_FONT_NAME "di" +constexpr pcstr DI_FONT_NAME = "di"; ////////////////////////////////////////////////////////////////////////// @@ -43,10 +43,9 @@ CUIXmlInitBase::ColorDefs* CUIXmlInitBase::m_pColorDefs = nullptr; CUIXmlInitBase::CUIXmlInitBase() { InitColorDefs(); } ////////////////////////////////////////////////////////////////////////// -CUIXmlInitBase::~CUIXmlInitBase() {} ////////////////////////////////////////////////////////////////////////// -Frect CUIXmlInitBase::GetFRect(CUIXml& xml_doc, LPCSTR path, int index) +Frect CUIXmlInitBase::GetFRect(const CUIXml& xml_doc, pcstr path, int index) { R_ASSERT4(xml_doc.NavigateToNode(path, index), "XML node not found", path, xml_doc.m_xml_file_name); Frect rect; @@ -59,7 +58,7 @@ Frect CUIXmlInitBase::GetFRect(CUIXml& xml_doc, LPCSTR path, int index) return rect; } -bool CUIXmlInitBase::InitWindow(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitWindow(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pWnd, bool fatal /*= true*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); if (!nodeExist) @@ -90,7 +89,7 @@ bool CUIXmlInitBase::InitWindow(CUIXml& xml_doc, LPCSTR path, int index, CUIWind ////////////////////////////////////////////////////////////////////////// -bool CUIXmlInitBase::InitFrameWindow(CUIXml& xml_doc, LPCSTR path, int index, CUIFrameWindow* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitFrameWindow(CUIXml& xml_doc, pcstr path, int index, CUIFrameWindow* pWnd, bool fatal /*= true*/) { bool result = InitWindow(xml_doc, path, index, pWnd, fatal); result &= InitTexture(xml_doc, path, index, pWnd, fatal); @@ -98,19 +97,18 @@ bool CUIXmlInitBase::InitFrameWindow(CUIXml& xml_doc, LPCSTR path, int index, CU return result; } -bool CUIXmlInitBase::InitOptionsItem(CUIXml& xml_doc, LPCSTR path, int index, CUIOptionsItem* pWnd) +bool CUIXmlInitBase::InitOptionsItem(const CUIXml& xml_doc, pcstr path, int index, CUIOptionsItem* pWnd) { string256 buf; - strconcat(sizeof(buf), buf, path, ":options_item"); + strconcat(buf, path, ":options_item"); if (xml_doc.NavigateToNode(buf, index)) { - shared_str entry = xml_doc.ReadAttrib(buf, index, "entry"); - shared_str group = xml_doc.ReadAttrib(buf, index, "group"); + cpcstr entry = xml_doc.ReadAttrib(buf, index, "entry"); + cpcstr group = xml_doc.ReadAttrib(buf, index, "group"); pWnd->AssignProps(entry, group); - LPCSTR depends = xml_doc.ReadAttrib(buf, index, "depend", NULL); - if (depends) + if (cpcstr depends = xml_doc.ReadAttrib(buf, index, "depend", nullptr)) { CUIOptionsItem::ESystemDepends d = CUIOptionsItem::sdNothing; @@ -125,7 +123,7 @@ bool CUIXmlInitBase::InitOptionsItem(CUIXml& xml_doc, LPCSTR path, int index, CU else if (0 == xr_stricmp(depends, "runtime")) d = CUIOptionsItem::sdApplyOnChange; else - Msg("! unknown param [%s] in optionsItem [%s]", depends, entry.c_str()); + Msg("! unknown param [%s] in optionsItem [%s]", depends, entry); pWnd->SetSystemDepends(d); } @@ -135,20 +133,20 @@ bool CUIXmlInitBase::InitOptionsItem(CUIXml& xml_doc, LPCSTR path, int index, CU return false; } -bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal /*= true*/, bool textWnd /*= false*/) +bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, pcstr path, int index, CUIStatic* pWnd, bool fatal /*= true*/, bool textWnd /*= false*/) { if (!InitWindow(xml_doc, path, index, pWnd, fatal)) return false; string256 buf; - InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd->TextItemControl()); + InitText(xml_doc, strconcat(buf, path, ":text"), index, pWnd->TextItemControl()); InitTexture(xml_doc, path, index, pWnd); InitTextureOffset(xml_doc, path, index, pWnd); - int flag = xml_doc.ReadAttribInt(path, index, "heading", 0); + const int flag = xml_doc.ReadAttribInt(path, index, "heading", 0); pWnd->EnableHeading((flag) ? true : false); - float heading_angle = xml_doc.ReadAttribFlt(path, index, "heading_angle", 0.0f); + const float heading_angle = xml_doc.ReadAttribFlt(path, index, "heading_angle", 0.0f); if (!fis_zero(heading_angle)) { pWnd->EnableHeading(true); @@ -156,11 +154,11 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStat pWnd->SetHeading(deg2rad(heading_angle)); } - LPCSTR str_flag = xml_doc.ReadAttrib(path, index, "light_anim", ""); + pcstr str_flag = xml_doc.ReadAttrib(path, index, "light_anim", ""); int flag_cyclic = xml_doc.ReadAttribInt(path, index, "la_cyclic", 1); - int flag_text = xml_doc.ReadAttribInt(path, index, "la_text", 1); - int flag_texture = xml_doc.ReadAttribInt(path, index, "la_texture", 1); - int flag_alpha = xml_doc.ReadAttribInt(path, index, "la_alpha", 0); + const int flag_text = xml_doc.ReadAttribInt(path, index, "la_text", 1); + const int flag_texture = xml_doc.ReadAttribInt(path, index, "la_texture", 1); + const int flag_alpha = xml_doc.ReadAttribInt(path, index, "la_alpha", 0); u8 flags = 0; if (flag_cyclic) @@ -177,17 +175,16 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStat str_flag = xml_doc.ReadAttrib(path, index, "xform_anim", ""); flag_cyclic = xml_doc.ReadAttribInt(path, index, "xform_anim_cyclic", 1); - pWnd->SetXformLightAnim(str_flag, (flag_cyclic) ? true : false); + pWnd->SetXformLightAnim(str_flag, flag_cyclic ? true : false); - bool bComplexMode = xml_doc.ReadAttribInt(path, index, "complex_mode", 0) ? true : false; - if (bComplexMode) - pWnd->TextItemControl()->SetTextComplexMode(bComplexMode); + if (xml_doc.ReadAttribInt(path, index, "complex_mode", 0) ? true : false) + pWnd->TextItemControl()->SetTextComplexMode(true); pWnd->m_stat_hint_text = xml_doc.ReadAttrib(path, index, "hint", ""); if (textWnd) { - strconcat(sizeof(buf), buf, path, ":texture"); + strconcat(buf, path, ":texture"); R_ASSERT3(nullptr == xml_doc.NavigateToNode(buf, index), xml_doc.m_xml_file_name, buf); R_ASSERT2(pWnd->GetChildWndList().empty(), @@ -197,40 +194,40 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStat return true; } -bool CUIXmlInitBase::InitCheck(CUIXml& xml_doc, LPCSTR path, int index, CUICheckButton* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitCheck(CUIXml& xml_doc, pcstr path, int index, CUICheckButton* pWnd, bool fatal /*= true*/) { if (!InitStatic(xml_doc, path, index, pWnd, fatal)) return false; string256 buf; - strconcat(sizeof(buf), buf, path, ":texture"); - LPCSTR texture = xml_doc.Read(buf, index, "ui_checker"); + strconcat(buf, path, ":texture"); + cpcstr texture = xml_doc.Read(buf, index, "ui_checker"); pWnd->InitCheckButton(pWnd->GetWndPos(), pWnd->GetWndSize(), texture); u32 color; - strconcat(sizeof(buf), buf, path, ":text_color:e"); + strconcat(buf, path, ":text_color:e"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Enabled); } - strconcat(sizeof(buf), buf, path, ":text_color:d"); + strconcat(buf, path, ":text_color:d"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Disabled); } - strconcat(sizeof(buf), buf, path, ":text_color:t"); + strconcat(buf, path, ":text_color:t"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Touched); } - strconcat(sizeof(buf), buf, path, ":text_color:h"); + strconcat(buf, path, ":text_color:h"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); @@ -242,7 +239,7 @@ bool CUIXmlInitBase::InitCheck(CUIXml& xml_doc, LPCSTR path, int index, CUICheck return true; } -bool CUIXmlInitBase::InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustomSpin* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitSpin(CUIXml& xml_doc, pcstr path, int index, CUICustomSpin* pWnd, bool fatal /*= true*/) { if (!InitWindow(xml_doc, path, index, pWnd, fatal)) return false; @@ -252,13 +249,13 @@ bool CUIXmlInitBase::InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustom string256 foo; u32 color; - strconcat(sizeof(foo), foo, path, ":text_color:e"); + strconcat(foo, path, ":text_color:e"); if (xml_doc.NavigateToNode(foo, index)) { color = GetColor(xml_doc, foo, index, 0x00); pWnd->SetTextColor(color); } - strconcat(sizeof(foo), foo, path, ":text_color:d"); + strconcat(foo, path, ":text_color:d"); if (xml_doc.NavigateToNode(foo, index)) { color = GetColor(xml_doc, foo, index, 0x00); @@ -268,13 +265,13 @@ bool CUIXmlInitBase::InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustom return true; } -bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines) +bool CUIXmlInitBase::InitText(CUIXml& xml_doc, pcstr path, int index, CUILines* pLines) { if (!xml_doc.NavigateToNode(path, index)) return false; u32 color; - CGameFont* pTmpFont = NULL; + CGameFont* pTmpFont = nullptr; InitFont(xml_doc, path, index, color, pTmpFont); pLines->SetTextColor(color); if (pTmpFont) @@ -314,14 +311,13 @@ bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines->m_TextOffset = { text_x, text_y }; - shared_str text = xml_doc.Read(path, index, NULL); - if (text.size()) + if (cpcstr text = xml_doc.Read(path, index, nullptr)) pLines->SetText(StringTable().translate(text).c_str()); return true; } -bool CUIXmlInitBase::Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::Init3tButton(CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd, bool fatal /*= true*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); if (!nodeExist) @@ -338,31 +334,31 @@ bool CUIXmlInitBase::Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3t pWnd->InitButton(pWnd->GetWndPos(), pWnd->GetWndSize()); string256 buf; - InitText(xml_doc, strconcat(sizeof(buf), buf, path, ":text"), index, pWnd->TextItemControl()); + InitText(xml_doc, strconcat(buf, path, ":text"), index, pWnd->TextItemControl()); u32 color; - strconcat(sizeof(buf), buf, path, ":text_color:e"); + strconcat(buf, path, ":text_color:e"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Enabled); } - strconcat(sizeof(buf), buf, path, ":text_color:d"); + strconcat(buf, path, ":text_color:d"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Disabled); } - strconcat(sizeof(buf), buf, path, ":text_color:t"); + strconcat(buf, path, ":text_color:t"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); pWnd->SetStateTextColor(color, S_Touched); } - strconcat(sizeof(buf), buf, path, ":text_color:h"); + strconcat(buf, path, ":text_color:h"); if (xml_doc.NavigateToNode(buf, index)) { color = GetColor(xml_doc, buf, index, 0x00); @@ -373,46 +369,44 @@ bool CUIXmlInitBase::Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3t InitTextureOffset(xml_doc, path, index, pWnd); InitSound(xml_doc, path, index, pWnd); - LPCSTR accel = xml_doc.ReadAttrib(path, index, "accel", NULL); - if (accel) + if (cpcstr accel = xml_doc.ReadAttrib(path, index, "accel", nullptr)) { - int acc = KeynameToDik(accel); + const int acc = KeynameToDik(accel); pWnd->SetAccelerator(acc, 0); } - accel = xml_doc.ReadAttrib(path, index, "accel_ext", NULL); - if (accel) + + if (cpcstr accel = xml_doc.ReadAttrib(path, index, "accel_ext", nullptr)) { - int acc = KeynameToDik(accel); + const int acc = KeynameToDik(accel); pWnd->SetAccelerator(acc, 1); } - LPCSTR text_hint = xml_doc.ReadAttrib(path, index, "hint", NULL); - if (text_hint) + if (cpcstr text_hint = xml_doc.ReadAttrib(path, index, "hint", nullptr)) pWnd->m_hint_text = StringTable().translate(text_hint); return true; } -bool CUIXmlInitBase::InitSound(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd) +bool CUIXmlInitBase::InitSound(const CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd) { string256 sound_h; string256 sound_t; - strconcat(sizeof(sound_h), sound_h, path, ":sound_h"); - strconcat(sizeof(sound_t), sound_t, path, ":sound_t"); + strconcat(sound_h, path, ":sound_h"); + strconcat(sound_t, path, ":sound_t"); - shared_str sound_h_result = xml_doc.Read(sound_h, index, ""); - shared_str sound_t_result = xml_doc.Read(sound_t, index, ""); + cpcstr sound_h_result = xml_doc.Read(sound_h, index, ""); + cpcstr sound_t_result = xml_doc.Read(sound_t, index, ""); if (xr_strlen(sound_h_result) != 0) - pWnd->InitSoundH(*sound_h_result); + pWnd->InitSoundH(sound_h_result); if (xr_strlen(sound_t_result) != 0) - pWnd->InitSoundT(*sound_t_result); + pWnd->InitSoundT(sound_t_result); return true; } -bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CUIProgressBar* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, pcstr path, int index, CUIProgressBar* pWnd, bool fatal /*= true*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); if (!nodeExist) @@ -434,8 +428,8 @@ bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CU size.y = xml_doc.ReadAttribFlt(path, index, "height"); CUIProgressBar::EOrientMode mode = CUIProgressBar::om_vert; - int mode_horz = xml_doc.ReadAttribInt(path, index, "horz", 0); - LPCSTR mode_str = xml_doc.ReadAttrib(path, index, "mode"); + const int mode_horz = xml_doc.ReadAttribInt(path, index, "horz", 0); + const pcstr mode_str = xml_doc.ReadAttrib(path, index, "mode"); if (mode_horz == 1) // om_horz { mode = CUIProgressBar::om_horz; @@ -467,16 +461,16 @@ bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CU pWnd->InitProgressBar(pos, size, mode); - float min = xml_doc.ReadAttribFlt(path, index, "min"); - float max = xml_doc.ReadAttribFlt(path, index, "max"); - float ppos = xml_doc.ReadAttribFlt(path, index, "pos"); + const float min = xml_doc.ReadAttribFlt(path, index, "min"); + const float max = xml_doc.ReadAttribFlt(path, index, "max"); + const float ppos = xml_doc.ReadAttribFlt(path, index, "pos"); pWnd->SetRange(min, max); pWnd->SetProgressPos(ppos); pWnd->m_inertion = xml_doc.ReadAttribFlt(path, index, "inertion", 0.0f); // progress - strconcat(sizeof(buf), buf, path, ":progress"); + strconcat(buf, path, ":progress"); if (!xml_doc.NavigateToNode(buf, index)) return false; @@ -486,7 +480,7 @@ bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CU pWnd->m_UIProgressItem.SetWndSize(pWnd->GetWndSize()); // background - strconcat(sizeof(buf), buf, path, ":background"); + strconcat(buf, path, ":background"); if (xml_doc.NavigateToNode(buf, index)) { @@ -495,7 +489,7 @@ bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CU pWnd->m_UIBackgroundItem.SetWndSize(pWnd->GetWndSize()); } - strconcat(sizeof(buf), buf, path, ":min_color"); + strconcat(buf, path, ":min_color"); if (xml_doc.NavigateToNode(buf, index)) { @@ -503,21 +497,21 @@ bool CUIXmlInitBase::InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CU pWnd->m_minColor = GetColor(xml_doc, buf, index, 0xff); - strconcat(sizeof(buf), buf, path, ":middle_color"); + strconcat(buf, path, ":middle_color"); if (xml_doc.NavigateToNode(buf, 0)) { pWnd->m_middleColor = GetColor(xml_doc, buf, index, 0xff); pWnd->m_bUseMiddleColor = true; } - strconcat(sizeof(buf), buf, path, ":max_color"); + strconcat(buf, path, ":max_color"); pWnd->m_maxColor = GetColor(xml_doc, buf, index, 0xff); } return true; } -bool CUIXmlInitBase::InitProgressShape(CUIXml& xml_doc, LPCSTR path, int index, CUIProgressShape* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitProgressShape(CUIXml& xml_doc, pcstr path, int index, CUIProgressShape* pWnd, bool fatal /*= true*/) { if (!InitStatic(xml_doc, path, index, pWnd, fatal)) return false; @@ -527,7 +521,7 @@ bool CUIXmlInitBase::InitProgressShape(CUIXml& xml_doc, LPCSTR path, int index, string256 _path; - strconcat(sizeof(_path), _path, path, ":back"); + strconcat(_path, path, ":back"); if (xml_doc.NavigateToNode(_path, index)) { pWnd->m_pBackground = xr_new("Background"); @@ -536,7 +530,7 @@ bool CUIXmlInitBase::InitProgressShape(CUIXml& xml_doc, LPCSTR path, int index, InitStatic(xml_doc, _path, index, pWnd->m_pBackground); } - strconcat(sizeof(_path), _path, path, ":front"); + strconcat(_path, path, ":front"); if (xml_doc.NavigateToNode(_path, index)) { pWnd->m_pTexture = xr_new("Forefround"); @@ -555,9 +549,9 @@ bool CUIXmlInitBase::InitProgressShape(CUIXml& xml_doc, LPCSTR path, int index, return true; } -void CUIXmlInitBase::InitAutoStaticGroup(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pParentWnd) +void CUIXmlInitBase::InitAutoStaticGroup(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pParentWnd) { - XML_NODE _stored_root = xml_doc.GetLocalRoot(); + const XML_NODE _stored_root = xml_doc.GetLocalRoot(); xml_doc.SetLocalRoot(xml_doc.NavigateToNode(path, index)); XML_NODE curr_root = xml_doc.GetLocalRoot(); @@ -572,7 +566,7 @@ void CUIXmlInitBase::InitAutoStaticGroup(CUIXml& xml_doc, LPCSTR path, int index while (node) { - LPCSTR node_name = node->Value(); + cpcstr node_name = node->Value(); if (0 == xr_stricmp(node_name, "auto_static")) { xr_sprintf(buff, "auto_static_%d", cnt_static); @@ -626,39 +620,36 @@ void CUIXmlInitBase::InitAutoStaticGroup(CUIXml& xml_doc, LPCSTR path, int index xml_doc.SetLocalRoot(_stored_root); } -void CUIXmlInitBase::InitAutoFrameLineGroup(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pParentWnd) +void CUIXmlInitBase::InitAutoFrameLineGroup(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pParentWnd) { - int items_num = xml_doc.GetNodesNum(path, index, "auto_frameline"); + const int items_num = (int)xml_doc.GetNodesNum(path, index, "auto_frameline"); if (items_num == 0) - { return; - } - XML_NODE _stored_root = xml_doc.GetLocalRoot(); + + const XML_NODE _stored_root = xml_doc.GetLocalRoot(); xml_doc.SetLocalRoot(xml_doc.NavigateToNode(path, index)); - CUIFrameLineWnd* pUIFL = NULL; string64 sname; for (int i = 0; i < items_num; ++i) { xr_sprintf(sname, "auto_frameline_%d", i); - pUIFL = xr_new(sname); + auto* pUIFL = xr_new(sname); InitFrameLine(xml_doc, "auto_frameline", i, pUIFL); pUIFL->SetAutoDelete(true); pParentWnd->AttachChild(pUIFL); - pUIFL = NULL; } xml_doc.SetLocalRoot(_stored_root); } -bool CUIXmlInitBase::InitFont(CUIXml& xml_doc, LPCSTR path, int index, u32& color, CGameFont*& pFnt) +bool CUIXmlInitBase::InitFont(const CUIXml& xml_doc, pcstr path, int index, u32& color, CGameFont*& pFnt) { color = GetColor(xml_doc, path, index, 0xff); - LPCSTR font_name = xml_doc.ReadAttrib(path, index, "font", NULL); + cpcstr font_name = xml_doc.ReadAttrib(path, index, "font", nullptr); if (!font_name) { - pFnt = NULL; + pFnt = nullptr; return false; } else @@ -710,13 +701,13 @@ bool CUIXmlInitBase::InitFont(CUIXml& xml_doc, LPCSTR path, int index, u32& colo else { R_ASSERT3(0, "unknown font", font_name); - pFnt = NULL; + pFnt = nullptr; } } return true; } -bool CUIXmlInitBase::InitTabControl(CUIXml& xml_doc, LPCSTR path, +bool CUIXmlInitBase::InitTabControl(CUIXml& xml_doc, pcstr path, int index, CUITabControl* pWnd, bool fatal /*= true*/, bool defaultIdsAllowed /*= false*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); @@ -730,17 +721,15 @@ bool CUIXmlInitBase::InitTabControl(CUIXml& xml_doc, LPCSTR path, status &= InitWindow(xml_doc, path, index, pWnd); InitOptionsItem(xml_doc, path, index, pWnd); - int tabsCount = xml_doc.GetNodesNum(path, index, "button"); - int radio = xml_doc.ReadAttribInt(path, index, "radio"); + const auto tabsCount = (int)xml_doc.GetNodesNum(path, index, "button"); + const int radio = xml_doc.ReadAttribInt(path, index, "radio"); - XML_NODE tab_node = xml_doc.NavigateToNode(path, index); + const XML_NODE tab_node = xml_doc.NavigateToNode(path, index); xml_doc.SetLocalRoot(tab_node); - CUITabButton* newButton; - for (int i = 0; i < tabsCount; ++i) { - newButton = radio ? xr_new() : xr_new(); + CUITabButton* newButton = radio ? xr_new() : xr_new(); status &= Init3tButton(xml_doc, "button", i, newButton); newButton->m_btn_id = xml_doc.ReadAttrib("button", i, "id"); if (!newButton->m_btn_id.size()) @@ -762,7 +751,7 @@ bool CUIXmlInitBase::InitTabControl(CUIXml& xml_doc, LPCSTR path, ////////////////////////////////////////////////////////////////////////// -bool CUIXmlInitBase::InitFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUIFrameLineWnd* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitFrameLine(CUIXml& xml_doc, pcstr path, int index, CUIFrameLineWnd* pWnd, bool fatal /*= true*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); if (!nodeExist) @@ -773,8 +762,7 @@ bool CUIXmlInitBase::InitFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUIF string256 buf; - bool stretch_flag = xml_doc.ReadAttribInt(path, index, "stretch"); - if (stretch_flag) + if (xml_doc.ReadAttribInt(path, index, "stretch")) { Msg("~ [%s] stretch attribute is unsupported for [%s]", xml_doc.m_xml_file_name, path); //. pWnd->SetStretchTexture( stretch_flag ); @@ -788,16 +776,16 @@ bool CUIXmlInitBase::InitFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUIF size.x = xml_doc.ReadAttribFlt(path, index, "width"); size.y = xml_doc.ReadAttribFlt(path, index, "height"); - bool vertical = !!xml_doc.ReadAttribInt(path, index, "vertical"); + const bool vertical = !!xml_doc.ReadAttribInt(path, index, "vertical"); - strconcat(sizeof(buf), buf, path, ":texture"); - shared_str base_name = xml_doc.Read(buf, index, NULL); + strconcat(buf, path, ":texture"); + const shared_str base_name = xml_doc.Read(buf, index, nullptr); #ifdef DEBUG VERIFY(base_name); #endif - u32 color = GetColor(xml_doc, buf, index, 0xff); + const u32 color = GetColor(xml_doc, buf, index, 0xff); pWnd->SetTextureColor(color); InitWindow(xml_doc, path, index, pWnd); @@ -805,16 +793,16 @@ bool CUIXmlInitBase::InitFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUIF return pWnd->InitFrameLineWnd(*base_name, pos, size, !vertical, fatal); } -bool CUIXmlInitBase::InitTextFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUITextFrameLineWnd* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitTextFrameLine(CUIXml& xml_doc, pcstr path, int index, CUITextFrameLineWnd* pWnd, bool fatal /*= true*/) { string256 buf; - strconcat(sizeof(buf), buf, path, ":title"); + strconcat(buf, path, ":title"); InitStatic(xml_doc, buf, index, &pWnd->m_title, false); return InitFrameLine(xml_doc, path, index, &pWnd->m_frameline, fatal); } -bool CUIXmlInitBase::InitCustomEdit(CUIXml& xml_doc, LPCSTR path, int index, CUICustomEdit* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitCustomEdit(CUIXml& xml_doc, pcstr path, int index, CUICustomEdit* pWnd, bool fatal /*= true*/) { if (!InitStatic(xml_doc, path, index, pWnd, fatal)) return false; @@ -822,18 +810,17 @@ bool CUIXmlInitBase::InitCustomEdit(CUIXml& xml_doc, LPCSTR path, int index, CUI pWnd->InitCustomEdit(pWnd->GetWndPos(), pWnd->GetWndSize()); string256 foo; - u32 color; - strconcat(sizeof(foo), foo, path, ":text_color:e"); + strconcat(foo, path, ":text_color:e"); if (xml_doc.NavigateToNode(foo, index)) { - color = GetColor(xml_doc, foo, index, 0x00); + const u32 color = GetColor(xml_doc, foo, index, 0x00); pWnd->TextItemControl()->SetTextColor(color); } int max_count = xml_doc.ReadAttribInt(path, index, "max_symb_count", 0); - bool num_only = (xml_doc.ReadAttribInt(path, index, "num_only", 0) == 1); - bool read_only = (xml_doc.ReadAttribInt(path, index, "read_only", 0) == 1); - bool file_name_mode = (xml_doc.ReadAttribInt(path, index, "file_name_mode", 0) == 1); + const bool num_only = (xml_doc.ReadAttribInt(path, index, "num_only", 0) == 1); + const bool read_only = (xml_doc.ReadAttribInt(path, index, "read_only", 0) == 1); + const bool file_name_mode = (xml_doc.ReadAttribInt(path, index, "file_name_mode", 0) == 1); if (file_name_mode || read_only || num_only || 0 < max_count) { @@ -851,7 +838,7 @@ bool CUIXmlInitBase::InitCustomEdit(CUIXml& xml_doc, LPCSTR path, int index, CUI return true; } -bool CUIXmlInitBase::InitEditBox(CUIXml& xml_doc, LPCSTR path, int index, CUIEditBox* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitEditBox(CUIXml& xml_doc, pcstr path, int index, CUIEditBox* pWnd, bool fatal /*= true*/) { if (!InitCustomEdit(xml_doc, path, index, pWnd)) return false; @@ -864,20 +851,20 @@ bool CUIXmlInitBase::InitEditBox(CUIXml& xml_doc, LPCSTR path, int index, CUIEdi ////////////////////////////////////////////////////////////////////////// -bool CUIXmlInitBase::InitAnimatedStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIAnimatedStatic* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitAnimatedStatic(CUIXml& xml_doc, pcstr path, int index, CUIAnimatedStatic* pWnd, bool fatal /*= true*/) { if (!InitStatic(xml_doc, path, index, pWnd, fatal)) return false; - float x = xml_doc.ReadAttribFlt(path, index, "x_offset", 0); - float y = xml_doc.ReadAttribFlt(path, index, "y_offset", 0); - u32 framesCount = static_cast(xml_doc.ReadAttribInt(path, index, "frames", 0)); - u32 animDuration = static_cast(xml_doc.ReadAttribInt(path, index, "duration", 0)); - u32 animCols = static_cast(xml_doc.ReadAttribInt(path, index, "columns", 0)); - float frameWidth = xml_doc.ReadAttribFlt(path, index, "frame_width", 0); - float frameHeight = xml_doc.ReadAttribFlt(path, index, "frame_height", 0); - bool cyclic = !!xml_doc.ReadAttribInt(path, index, "cyclic", 0); - bool play = !!xml_doc.ReadAttribInt(path, index, "autoplay", 0); + const float x = xml_doc.ReadAttribFlt(path, index, "x_offset", 0); + const float y = xml_doc.ReadAttribFlt(path, index, "y_offset", 0); + const u32 framesCount = static_cast(xml_doc.ReadAttribInt(path, index, "frames", 0)); + const u32 animDuration = static_cast(xml_doc.ReadAttribInt(path, index, "duration", 0)); + const u32 animCols = static_cast(xml_doc.ReadAttribInt(path, index, "columns", 0)); + const float frameWidth = xml_doc.ReadAttribFlt(path, index, "frame_width", 0); + const float frameHeight = xml_doc.ReadAttribFlt(path, index, "frame_height", 0); + const bool cyclic = !!xml_doc.ReadAttribInt(path, index, "cyclic", 0); + const bool play = !!xml_doc.ReadAttribInt(path, index, "autoplay", 0); pWnd->SetFrameDimentions(frameWidth, frameHeight); pWnd->SetFramesCount(framesCount); @@ -892,18 +879,18 @@ bool CUIXmlInitBase::InitAnimatedStatic(CUIXml& xml_doc, LPCSTR path, int index, return true; } -bool CUIXmlInitBase::InitTexture(CUIXml& xml_doc, LPCSTR path, int index, ITextureOwner* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitTexture(const CUIXml& xml_doc, pcstr path, int index, ITextureOwner* pWnd, bool fatal /*= true*/) { bool result = true; string256 buf; - LPCSTR texture = NULL; - LPCSTR shader = NULL; - strconcat(sizeof(buf), buf, path, ":texture"); + pcstr texture = nullptr; + pcstr shader = nullptr; + strconcat(buf, path, ":texture"); if (xml_doc.NavigateToNode(buf)) { - texture = xml_doc.Read(buf, index, NULL); - shader = xml_doc.ReadAttrib(buf, index, "shader", NULL); + texture = xml_doc.Read(buf, index, nullptr); + shader = xml_doc.ReadAttrib(buf, index, "shader", nullptr); } if (texture) { @@ -919,10 +906,10 @@ bool CUIXmlInitBase::InitTexture(CUIXml& xml_doc, LPCSTR path, int index, ITextu rect.x2 = rect.x1 + xml_doc.ReadAttribFlt(buf, index, "width", 0); rect.y2 = rect.y1 + xml_doc.ReadAttribFlt(buf, index, "height", 0); - bool stretch_flag = xml_doc.ReadAttribInt(path, index, "stretch") ? true : false; + const bool stretch_flag = xml_doc.ReadAttribInt(path, index, "stretch") ? true : false; pWnd->SetStretchTexture(stretch_flag); - u32 color = GetColor(xml_doc, buf, index, 0xff); + const u32 color = GetColor(xml_doc, buf, index, 0xff); pWnd->SetTextureColor(color); if (rect.width() != 0 && rect.height() != 0) @@ -931,29 +918,29 @@ bool CUIXmlInitBase::InitTexture(CUIXml& xml_doc, LPCSTR path, int index, ITextu return result; } -bool CUIXmlInitBase::InitTextureOffset(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd) +bool CUIXmlInitBase::InitTextureOffset(const CUIXml& xml_doc, pcstr path, int index, CUIStatic* pWnd) { string256 textureOffset; if (0 == xr_strcmp(path, "")) xr_strcpy(textureOffset, "texture_offset"); else - strconcat(sizeof(textureOffset), textureOffset, path, ":texture_offset"); + strconcat(textureOffset, path, ":texture_offset"); - float x = xml_doc.ReadAttribFlt(textureOffset, index, "x"); - float y = xml_doc.ReadAttribFlt(textureOffset, index, "y"); + const float x = xml_doc.ReadAttribFlt(textureOffset, index, "x"); + const float y = xml_doc.ReadAttribFlt(textureOffset, index, "y"); pWnd->SetTextureOffset(x, y); return true; } -bool CUIXmlInitBase::InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd) +bool CUIXmlInitBase::InitMultiTexture(const CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd) { string256 buff; bool success = false; - strconcat(sizeof(buff), buff, path, ":texture"); - shared_str texture = xml_doc.Read(buff, index, NULL); + strconcat(buff, path, ":texture"); + shared_str texture = xml_doc.Read(buff, index, nullptr); if (texture.size() > 0) { @@ -961,8 +948,8 @@ bool CUIXmlInitBase::InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, C return true; } - strconcat(sizeof(buff), buff, path, ":texture_e"); - texture = xml_doc.Read(buff, index, NULL); + strconcat(buff, path, ":texture_e"); + texture = xml_doc.Read(buff, index, nullptr); if (texture.size()) { if (pWnd->m_background) @@ -977,8 +964,8 @@ bool CUIXmlInitBase::InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, C success = true; } - strconcat(sizeof(buff), buff, path, ":texture_t"); - texture = xml_doc.Read(buff, index, NULL); + strconcat(buff, path, ":texture_t"); + texture = xml_doc.Read(buff, index, nullptr); if (texture.size()) { if (pWnd->m_background) @@ -993,8 +980,8 @@ bool CUIXmlInitBase::InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, C success = true; } - strconcat(sizeof(buff), buff, path, ":texture_d"); - texture = xml_doc.Read(buff, index, NULL); + strconcat(buff, path, ":texture_d"); + texture = xml_doc.Read(buff, index, nullptr); if (texture.size()) { if (pWnd->m_background) @@ -1009,8 +996,8 @@ bool CUIXmlInitBase::InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, C success = true; } - strconcat(sizeof(buff), buff, path, ":texture_h"); - texture = xml_doc.Read(buff, index, NULL); + strconcat(buff, path, ":texture_h"); + texture = xml_doc.Read(buff, index, nullptr); if (texture.size()) { if (pWnd->m_background) @@ -1054,10 +1041,10 @@ constexpr uint32_t hash(const std::string_view data) noexcept return hash; } -bool CUIXmlInitBase::InitAlignment(CUIXml& xml_doc, const char* path, int index, float& x, float& y, CUIWindow* pWnd) +bool CUIXmlInitBase::InitAlignment(const CUIXml& xml_doc, const char* path, int index, float& x, float& y, CUIWindow* pWnd) { // Alignment: top: "t", right: "r", bottom: "b", left: "l", center: "c" - xr_string wnd_alignment = xml_doc.ReadAttrib(path, index, "alignment", ""); + const xr_string wnd_alignment = xml_doc.ReadAttrib(path, index, "alignment", ""); switch (hash(wnd_alignment.c_str())) { @@ -1081,11 +1068,11 @@ bool CUIXmlInitBase::InitAlignment(CUIXml& xml_doc, const char* path, int index, } // Alignment: right: "r", bottom: "b". Top, left - useless - shared_str alignStr = xml_doc.ReadAttrib(path, index, "align", ""); + cpcstr alignStr = xml_doc.ReadAttrib(path, index, "align", ""); bool result = false; - switch (hash(alignStr.c_str())) + switch (hash(alignStr)) { case hash("r"): x = ApplyAlignX(x, alRight); @@ -1116,24 +1103,21 @@ void CUIXmlInitBase::InitColorDefs() CUIXml uiXml; uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, COLOR_DEFINITIONS); - const int num = uiXml.GetNodesNum("colors", 0, "color"); - - shared_str name; - int r, b, g, a; + const auto num = uiXml.GetNodesNum("colors", 0, "color"); - for (int i = 0; i < num; ++i) + for (size_t i = 0; i < num; ++i) { - name = uiXml.ReadAttrib("color", i, "name", ""); - r = uiXml.ReadAttribInt("color", i, "r", 0); - g = uiXml.ReadAttribInt("color", i, "g", 0); - b = uiXml.ReadAttribInt("color", i, "b", 0); - a = uiXml.ReadAttribInt("color", i, "a", 255); + const shared_str name = uiXml.ReadAttrib("color", i, "name", ""); + const int r = uiXml.ReadAttribInt("color", i, "r", 0); + const int g = uiXml.ReadAttribInt("color", i, "g", 0); + const int b = uiXml.ReadAttribInt("color", i, "b", 0); + const int a = uiXml.ReadAttribInt("color", i, "a", 255); (*m_pColorDefs)[name] = color_argb(a, r, g, b); } } -bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUIScrollView* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, pcstr path, int index, CUIScrollView* pWnd, bool fatal /*= true*/) { if (!InitWindow(xml_doc, path, index, pWnd, fatal)) return false; @@ -1143,17 +1127,17 @@ bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUI pWnd->SetUpIndention(xml_doc.ReadAttribFlt(path, index, "top_indent", 0.0f)); pWnd->SetDownIndention(xml_doc.ReadAttribFlt(path, index, "bottom_indent", 0.0f)); - float vi = xml_doc.ReadAttribFlt(path, index, "vert_interval", 0.0f); + const float vi = xml_doc.ReadAttribFlt(path, index, "vert_interval", 0.0f); pWnd->m_vertInterval = (vi); - bool bInverseDir = (1 == xml_doc.ReadAttribInt(path, index, "inverse_dir", 0)); + const bool bInverseDir = (1 == xml_doc.ReadAttribInt(path, index, "inverse_dir", 0)); pWnd->m_flags.set(CUIScrollView::eInverseDir, bInverseDir); pWnd->SetScrollBarProfile(xml_doc.ReadAttrib(path, index, "scroll_profile", "default")); pWnd->InitScrollView(); - bool bVertFlip = (1 == xml_doc.ReadAttribInt(path, index, "flip_vert", 0)); + const bool bVertFlip = (1 == xml_doc.ReadAttribInt(path, index, "flip_vert", 0)); pWnd->SetVertFlip(bVertFlip); bool b = (1 == xml_doc.ReadAttribInt(path, index, "always_show_scroll", 1)); @@ -1165,9 +1149,9 @@ bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUI pWnd->m_flags.set(CUIScrollView::eItemsSelectabe, b); ///////////////////////////////////////////////////////////////////// - int tabsCount = xml_doc.GetNodesNum(path, index, "text"); + const int tabsCount = (int)xml_doc.GetNodesNum(path, index, "text"); - XML_NODE _stored_root = xml_doc.GetLocalRoot(); + const XML_NODE _stored_root = xml_doc.GetLocalRoot(); xml_doc.SetLocalRoot(xml_doc.NavigateToNode(path, index)); for (int i = 0; i < tabsCount; ++i) @@ -1183,7 +1167,7 @@ bool CUIXmlInitBase::InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUI return true; } -bool CUIXmlInitBase::InitListWnd(CUIXml& xml_doc, pcstr path, int index, CUIListWnd* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitListWnd(const CUIXml& xml_doc, pcstr path, int index, CUIListWnd* pWnd, bool fatal /*= true*/) { const bool nodeExist = xml_doc.NavigateToNode(path, index); if (!nodeExist) @@ -1200,15 +1184,15 @@ bool CUIXmlInitBase::InitListWnd(CUIXml& xml_doc, pcstr path, int index, CUIList size.x = xml_doc.ReadAttribFlt(path, index, "width"); size.y = xml_doc.ReadAttribFlt(path, index, "height"); - float item_height = xml_doc.ReadAttribFlt(path, index, "item_height"); - int active_background = xml_doc.ReadAttribInt(path, index, "active_bg"); + const float item_height = xml_doc.ReadAttribFlt(path, index, "item_height"); + const int active_background = xml_doc.ReadAttribInt(path, index, "active_bg"); // Init font from xml config file string256 buf; CGameFont* LocalFont = nullptr; u32 cl; - shared_str text_path = strconcat(sizeof(buf), buf, path, ":font"); + const shared_str text_path = strconcat(buf, path, ":font"); InitFont(xml_doc, *text_path, index, cl, LocalFont); if (LocalFont) { @@ -1233,14 +1217,13 @@ bool CUIXmlInitBase::InitListWnd(CUIXml& xml_doc, pcstr path, int index, CUIList pWnd->EnableAlwaysShowScroll(true); } - - bool bVertFlip = (1 == xml_doc.ReadAttribInt(path, index, "flip_vert", 0)); + const bool bVertFlip = (1 == xml_doc.ReadAttribInt(path, index, "flip_vert", 0)); pWnd->SetVertFlip(bVertFlip); return true; } -bool CUIXmlInitBase::InitListBox(CUIXml& xml_doc, LPCSTR path, int index, CUIListBox* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitListBox(CUIXml& xml_doc, pcstr path, int index, CUIListBox* pWnd, bool fatal /*= true*/) { if (!InitScrollView(xml_doc, path, index, pWnd)) return false; @@ -1248,37 +1231,36 @@ bool CUIXmlInitBase::InitListBox(CUIXml& xml_doc, LPCSTR path, int index, CUILis string512 _path; u32 t_color; CGameFont* pFnt; - strconcat(sizeof(_path), _path, path, ":font"); + strconcat(_path, path, ":font"); InitFont(xml_doc, _path, index, t_color, pFnt); pWnd->SetTextColor(t_color); pWnd->SetFont(pFnt); - float h = xml_doc.ReadAttribFlt(path, index, "item_height", 20.0f); + const float h = xml_doc.ReadAttribFlt(path, index, "item_height", 20.0f); pWnd->SetItemHeight(h); return true; } -bool CUIXmlInitBase::InitTrackBar(CUIXml& xml_doc, LPCSTR path, int index, CUITrackBar* pWnd, bool fatal /*= true*/) +bool CUIXmlInitBase::InitTrackBar(CUIXml& xml_doc, pcstr path, int index, CUITrackBar* pWnd, bool fatal /*= true*/) { if (!InitWindow(xml_doc, path, 0, pWnd, fatal)) return false; pWnd->InitTrackBar(pWnd->GetWndPos(), pWnd->GetWndSize()); - int is_integer = xml_doc.ReadAttribInt(path, index, "is_integer", 0); + const int is_integer = xml_doc.ReadAttribInt(path, index, "is_integer", 0); pWnd->SetType(!is_integer); InitOptionsItem(xml_doc, path, 0, pWnd); - int invert = xml_doc.ReadAttribInt(path, index, "invert", 0); + const int invert = xml_doc.ReadAttribInt(path, index, "invert", 0); pWnd->SetInvert(!!invert); - float step = xml_doc.ReadAttribFlt(path, index, "step", 0.1f); + const float step = xml_doc.ReadAttribFlt(path, index, "step", 0.1f); pWnd->SetStep(step); - bool is_float = !is_integer; - if (is_float) + if (!is_integer) { - float fmin = xml_doc.ReadAttribFlt(path, index, "min", 0.0f); - float fmax = xml_doc.ReadAttribFlt(path, index, "max", 0.0f); + const float fmin = xml_doc.ReadAttribFlt(path, index, "min", 0.0f); + const float fmax = xml_doc.ReadAttribFlt(path, index, "max", 0.0f); if (fmin != fmax) { @@ -1288,8 +1270,8 @@ bool CUIXmlInitBase::InitTrackBar(CUIXml& xml_doc, LPCSTR path, int index, CUITr } else { - int imin = xml_doc.ReadAttribInt(path, index, "min", 0); - int imax = xml_doc.ReadAttribInt(path, index, "max", 0); + const int imin = xml_doc.ReadAttribInt(path, index, "min", 0); + const int imax = xml_doc.ReadAttribInt(path, index, "max", 0); if (imin != imax) { @@ -1299,7 +1281,7 @@ bool CUIXmlInitBase::InitTrackBar(CUIXml& xml_doc, LPCSTR path, int index, CUITr } string512 buf; - strconcat(sizeof(buf), buf, path, ":output_wnd"); + strconcat(buf, path, ":output_wnd"); if (xml_doc.NavigateToNode(buf, index)) { InitStatic(xml_doc, buf, index, pWnd->m_static); @@ -1310,7 +1292,7 @@ bool CUIXmlInitBase::InitTrackBar(CUIXml& xml_doc, LPCSTR path, int index, CUITr return true; } -bool CUIXmlInitBase::InitComboBox(CUIXml& xml_doc, LPCSTR path, int index, CUIComboBox* pWnd) +bool CUIXmlInitBase::InitComboBox(CUIXml& xml_doc, pcstr path, int index, CUIComboBox* pWnd) { u32 color; CGameFont* pFont; @@ -1321,25 +1303,25 @@ bool CUIXmlInitBase::InitComboBox(CUIXml& xml_doc, LPCSTR path, int index, CUICo pWnd->InitComboBox(pWnd->GetWndPos(), pWnd->GetWidth()); InitOptionsItem(xml_doc, path, index, pWnd); - bool b = (1 == xml_doc.ReadAttribInt(path, index, "always_show_scroll", 1)); + const bool b = (1 == xml_doc.ReadAttribInt(path, index, "always_show_scroll", 1)); pWnd->m_list_box.SetFixedScrollBar(b); string512 _path; - strconcat(sizeof(_path), _path, path, ":list_font"); + strconcat(_path, path, ":list_font"); InitFont(xml_doc, _path, index, color, pFont); //. pWnd->SetFont (pFont); pWnd->m_list_box.SetFont(pFont); pWnd->m_list_box.SetTextColor(color); - strconcat(sizeof(_path), _path, path, ":text_color:e"); + strconcat(_path, path, ":text_color:e"); if (xml_doc.NavigateToNode(_path, index)) { color = GetColor(xml_doc, _path, index, 0x00); pWnd->SetTextColor(color); } - strconcat(sizeof(_path), _path, path, ":text_color:d"); + strconcat(_path, path, ":text_color:d"); if (xml_doc.NavigateToNode(_path, index)) { color = GetColor(xml_doc, _path, index, 0x00); @@ -1349,21 +1331,20 @@ bool CUIXmlInitBase::InitComboBox(CUIXml& xml_doc, LPCSTR path, int index, CUICo return true; } -void CUIXmlInitBase::AssignColor(LPCSTR name, u32 clr) { (*m_pColorDefs)[name] = clr; } -u32 CUIXmlInitBase::GetColor(CUIXml& xml_doc, LPCSTR path, int index, u32 def_clr) +void CUIXmlInitBase::AssignColor(pcstr name, u32 clr) { (*m_pColorDefs)[name] = clr; } +u32 CUIXmlInitBase::GetColor(const CUIXml& xml_doc, pcstr path, int index, u32 def_clr) { - LPCSTR clr_def = xml_doc.ReadAttrib(path, index, "color", NULL); - if (clr_def) + if (cpcstr clr_def = xml_doc.ReadAttrib(path, index, "color", nullptr)) { VERIFY(GetColorDefs()->find(clr_def) != GetColorDefs()->end()); return (*m_pColorDefs)[clr_def]; } else { - int r = xml_doc.ReadAttribInt(path, index, "r", def_clr); - int g = xml_doc.ReadAttribInt(path, index, "g", def_clr); - int b = xml_doc.ReadAttribInt(path, index, "b", def_clr); - int a = xml_doc.ReadAttribInt(path, index, "a", 0xff); + const int r = xml_doc.ReadAttribInt(path, index, "r", def_clr); + const int g = xml_doc.ReadAttribInt(path, index, "g", def_clr); + const int b = xml_doc.ReadAttribInt(path, index, "b", def_clr); + const int a = xml_doc.ReadAttribInt(path, index, "a", 0xff); return color_argb(a, r, g, b); } } diff --git a/src/xrUICore/XML/UIXmlInitBase.h b/src/xrUICore/XML/UIXmlInitBase.h index e0eda3f35bb..ffb1bd062f4 100644 --- a/src/xrUICore/XML/UIXmlInitBase.h +++ b/src/xrUICore/XML/UIXmlInitBase.h @@ -37,42 +37,42 @@ class XRUICORE_API CUIXmlInitBase { public: CUIXmlInitBase(); - virtual ~CUIXmlInitBase(); + virtual ~CUIXmlInitBase() = default; - static bool InitWindow(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pWnd, bool fatal = true); - static bool InitFrameWindow(CUIXml& xml_doc, LPCSTR path, int index, CUIFrameWindow* pWnd, bool fatal = true); - static bool InitFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUIFrameLineWnd* pWnd, bool fatal = true); - static bool InitTextFrameLine(CUIXml& xml_doc, LPCSTR path, int index, CUITextFrameLineWnd* pWnd, bool fatal = true); - static bool InitCustomEdit(CUIXml& xml_doc, LPCSTR paht, int index, CUICustomEdit* pWnd, bool fatal = true); - static bool InitEditBox(CUIXml& xml_doc, LPCSTR paht, int index, CUIEditBox* pWnd, bool fatal = true); - static bool InitStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd, bool fatal = true, bool textWnd = false); - static bool InitCheck(CUIXml& xml_doc, LPCSTR path, int index, CUICheckButton* pWnd, bool fatal = true); - static bool InitSpin(CUIXml& xml_doc, LPCSTR path, int index, CUICustomSpin* pWnd, bool fatal = true); - static bool InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* pLines); - static bool Init3tButton(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd, bool fatal = true); - static bool InitProgressBar(CUIXml& xml_doc, LPCSTR path, int index, CUIProgressBar* pWnd, bool fatal = true); - static bool InitProgressShape(CUIXml& xml_doc, LPCSTR path, int index, CUIProgressShape* pWnd, bool fatal = true); - static bool InitFont(CUIXml& xml_doc, LPCSTR path, int index, u32& color, CGameFont*& pFnt); - static bool InitTabControl(CUIXml& xml_doc, LPCSTR path, + static bool InitWindow(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pWnd, bool fatal = true); + static bool InitFrameWindow(CUIXml& xml_doc, pcstr path, int index, CUIFrameWindow* pWnd, bool fatal = true); + static bool InitFrameLine(CUIXml& xml_doc, pcstr path, int index, CUIFrameLineWnd* pWnd, bool fatal = true); + static bool InitTextFrameLine(CUIXml& xml_doc, pcstr path, int index, CUITextFrameLineWnd* pWnd, bool fatal = true); + static bool InitCustomEdit(CUIXml& xml_doc, pcstr paht, int index, CUICustomEdit* pWnd, bool fatal = true); + static bool InitEditBox(CUIXml& xml_doc, pcstr paht, int index, CUIEditBox* pWnd, bool fatal = true); + static bool InitStatic(CUIXml& xml_doc, pcstr path, int index, CUIStatic* pWnd, bool fatal = true, bool textWnd = false); + static bool InitCheck(CUIXml& xml_doc, pcstr path, int index, CUICheckButton* pWnd, bool fatal = true); + static bool InitSpin(CUIXml& xml_doc, pcstr path, int index, CUICustomSpin* pWnd, bool fatal = true); + static bool InitText(CUIXml& xml_doc, pcstr path, int index, CUILines* pLines); + static bool Init3tButton(CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd, bool fatal = true); + static bool InitProgressBar(CUIXml& xml_doc, pcstr path, int index, CUIProgressBar* pWnd, bool fatal = true); + static bool InitProgressShape(CUIXml& xml_doc, pcstr path, int index, CUIProgressShape* pWnd, bool fatal = true); + static bool InitFont(const CUIXml& xml_doc, pcstr path, int index, u32& color, CGameFont*& pFnt); + static bool InitTabControl(CUIXml& xml_doc, pcstr path, int index, CUITabControl* pWnd, bool fatal = true, bool defaultIdsAllowed = false); - static bool InitAnimatedStatic(CUIXml& xml_doc, LPCSTR path, int index, CUIAnimatedStatic* pWnd, bool fatal = true); - static bool InitTextureOffset(CUIXml& xml_doc, LPCSTR path, int index, CUIStatic* pWnd); - static bool InitSound(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd); - static bool InitMultiTexture(CUIXml& xml_doc, LPCSTR path, int index, CUI3tButton* pWnd); - static bool InitTexture(CUIXml& xml_doc, LPCSTR path, int index, ITextureOwner* pWnd, bool fatal = true); - static bool InitOptionsItem(CUIXml& xml_doc, LPCSTR paht, int index, CUIOptionsItem* pWnd); - static bool InitScrollView(CUIXml& xml_doc, LPCSTR path, int index, CUIScrollView* pWnd, bool fatal = true); - static bool InitListWnd(CUIXml& xml_doc, pcstr path, int index, CUIListWnd* pWnd, bool fatal = true); - static bool InitListBox(CUIXml& xml_doc, LPCSTR path, int index, CUIListBox* pWnd, bool fatal = true); - static bool InitComboBox(CUIXml& xml_doc, LPCSTR path, int index, CUIComboBox* pWnd); - static bool InitTrackBar(CUIXml& xml_doc, LPCSTR path, int index, CUITrackBar* pWnd, bool fatal = true); - static Frect GetFRect(CUIXml& xml_doc, LPCSTR path, int index); - static u32 GetColor(CUIXml& xml_doc, LPCSTR path, int index, u32 def_clr); + static bool InitAnimatedStatic(CUIXml& xml_doc, pcstr path, int index, CUIAnimatedStatic* pWnd, bool fatal = true); + static bool InitTextureOffset(const CUIXml& xml_doc, pcstr path, int index, CUIStatic* pWnd); + static bool InitSound(const CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd); + static bool InitMultiTexture(const CUIXml& xml_doc, pcstr path, int index, CUI3tButton* pWnd); + static bool InitTexture(const CUIXml& xml_doc, pcstr path, int index, ITextureOwner* pWnd, bool fatal = true); + static bool InitOptionsItem(const CUIXml& xml_doc, pcstr paht, int index, CUIOptionsItem* pWnd); + static bool InitScrollView(CUIXml& xml_doc, pcstr path, int index, CUIScrollView* pWnd, bool fatal = true); + static bool InitListWnd(const CUIXml& xml_doc, pcstr path, int index, CUIListWnd* pWnd, bool fatal = true); + static bool InitListBox(CUIXml& xml_doc, pcstr path, int index, CUIListBox* pWnd, bool fatal = true); + static bool InitComboBox(CUIXml& xml_doc, pcstr path, int index, CUIComboBox* pWnd); + static bool InitTrackBar(CUIXml& xml_doc, pcstr path, int index, CUITrackBar* pWnd, bool fatal = true); + static Frect GetFRect(const CUIXml& xml_doc, pcstr path, int index); + static u32 GetColor(const CUIXml& xml_doc, pcstr path, int index, u32 def_clr); - static bool InitAlignment(CUIXml& xml_doc, const char* path, int index, float& x, float& y, CUIWindow* pWnd); + static bool InitAlignment(const CUIXml& xml_doc, const char* path, int index, float& x, float& y, CUIWindow* pWnd); - static void InitAutoStaticGroup(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pParentWnd); - static void InitAutoFrameLineGroup(CUIXml& xml_doc, LPCSTR path, int index, CUIWindow* pParentWnd); + static void InitAutoStaticGroup(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pParentWnd); + static void InitAutoFrameLineGroup(CUIXml& xml_doc, pcstr path, int index, CUIWindow* pParentWnd); static float ApplyAlignX(float coord, u32 align); static float ApplyAlignY(float coord, u32 align); @@ -89,7 +89,7 @@ class XRUICORE_API CUIXmlInitBase static void InitColorDefs(); static void DeleteColorDefs() { xr_delete(m_pColorDefs); } - static void AssignColor(LPCSTR name, u32 clr); + static void AssignColor(pcstr name, u32 clr); private: static ColorDefs* m_pColorDefs; From d67a6315c4ee0dd278208e06beb69ebe4106feac Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 08:24:27 +0500 Subject: [PATCH 195/497] Enable drawing window rectangles in UI Debugger by default --- src/xrUICore/ui_debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrUICore/ui_debug.h b/src/xrUICore/ui_debug.h index 8ca530170bb..db4e9fb4f35 100644 --- a/src/xrUICore/ui_debug.h +++ b/src/xrUICore/ui_debug.h @@ -22,8 +22,8 @@ struct CUIDebugState { CUIDebuggable* selected{}; mutable CUIDebuggable* newSelected{}; - bool drawWndRects{}; - bool coloredRects{}; + bool drawWndRects{ true }; + bool coloredRects{ true }; void select(CUIDebuggable* debuggable) const { From 77d5dcb378c2a0f360fe39dd53db44ec10c65fc8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 10:23:33 +0500 Subject: [PATCH 196/497] xrUICore/Options/UIOptions.h|cpp: constify functions --- src/xrUICore/Options/UIOptionsItem.cpp | 39 ++++++++++++++++++-------- src/xrUICore/Options/UIOptionsItem.h | 22 +++++++-------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/xrUICore/Options/UIOptionsItem.cpp b/src/xrUICore/Options/UIOptionsItem.cpp index 8e83f0b426c..d00ca40ed63 100644 --- a/src/xrUICore/Options/UIOptionsItem.cpp +++ b/src/xrUICore/Options/UIOptionsItem.cpp @@ -7,13 +7,14 @@ CUIOptionsManager CUIOptionsItem::m_optionsManager; CUIOptionsItem::CUIOptionsItem() : m_dep(sdNothing) {} CUIOptionsItem::~CUIOptionsItem() { m_optionsManager.UnRegisterItem(this); } + void CUIOptionsItem::AssignProps(const shared_str& entry, const shared_str& group) { m_optionsManager.RegisterItem(this, group); m_entry = entry; } -void CUIOptionsItem::SendMessage2Group(LPCSTR group, LPCSTR message) +void CUIOptionsItem::SendMessage2Group(pcstr group, pcstr message) { m_optionsManager.SendMessage2Group(group, message); } @@ -23,8 +24,12 @@ void CUIOptionsItem::OnMessage(LPCSTR message) // do nothing } -LPCSTR CUIOptionsItem::GetOptStringValue() { return Console->GetString(m_entry.c_str()); } -void CUIOptionsItem::SaveOptStringValue(LPCSTR val) +pcstr CUIOptionsItem::GetOptStringValue() const +{ + return Console->GetString(m_entry.c_str()); +} + +void CUIOptionsItem::SaveOptStringValue(LPCSTR val) const { xr_string command = m_entry.c_str(); command += " "; @@ -32,40 +37,52 @@ void CUIOptionsItem::SaveOptStringValue(LPCSTR val) Console->Execute(command.c_str()); } -void CUIOptionsItem::GetOptIntegerValue(int& val, int& min, int& max) +void CUIOptionsItem::GetOptIntegerValue(int& val, int& min, int& max) const { val = Console->GetInteger(m_entry.c_str(), min, max); } -void CUIOptionsItem::SaveOptIntegerValue(int val) +void CUIOptionsItem::SaveOptIntegerValue(int val) const { string512 command; xr_sprintf(command, "%s %d", m_entry.c_str(), val); Console->Execute(command); } -void CUIOptionsItem::GetOptFloatValue(float& val, float& min, float& max) +void CUIOptionsItem::GetOptFloatValue(float& val, float& min, float& max) const { val = Console->GetFloat(m_entry.c_str(), min, max); } -void CUIOptionsItem::SaveOptFloatValue(float val) +void CUIOptionsItem::SaveOptFloatValue(float val) const { string512 command; xr_sprintf(command, "%s %f", m_entry.c_str(), val); Console->Execute(command); } -bool CUIOptionsItem::GetOptBoolValue() { return Console->GetBool(m_entry.c_str()); } -void CUIOptionsItem::SaveOptBoolValue(bool val) +bool CUIOptionsItem::GetOptBoolValue() const +{ + return Console->GetBool(m_entry.c_str()); +} + +void CUIOptionsItem::SaveOptBoolValue(bool val) const { string512 command; xr_sprintf(command, "%s %s", m_entry.c_str(), (val) ? "1" : "0"); Console->Execute(command); } -LPCSTR CUIOptionsItem::GetOptTokenValue() { return Console->GetToken(m_entry.c_str()); } -const xr_token* CUIOptionsItem::GetOptToken() { return Console->GetXRToken(m_entry.c_str()); } +pcstr CUIOptionsItem::GetOptTokenValue() const +{ + return Console->GetToken(m_entry.c_str()); +} + +const xr_token* CUIOptionsItem::GetOptToken() const +{ + return Console->GetXRToken(m_entry.c_str()); +} + void CUIOptionsItem::SaveOptValue() { if (!IsChangedOptValue()) diff --git a/src/xrUICore/Options/UIOptionsItem.h b/src/xrUICore/Options/UIOptionsItem.h index 5e5c92894c2..c2c0ced5f87 100644 --- a/src/xrUICore/Options/UIOptionsItem.h +++ b/src/xrUICore/Options/UIOptionsItem.h @@ -33,23 +33,23 @@ class XRUICORE_API CUIOptionsItem void OnChangedOptValue(); protected: - void SendMessage2Group(LPCSTR group, LPCSTR message); + void SendMessage2Group(pcstr group, pcstr message); // string - LPCSTR GetOptStringValue(); - void SaveOptStringValue(LPCSTR val); + pcstr GetOptStringValue() const; + void SaveOptStringValue(pcstr val) const; // integer - void GetOptIntegerValue(int& val, int& min, int& max); - void SaveOptIntegerValue(int val); + void GetOptIntegerValue(int& val, int& min, int& max) const; + void SaveOptIntegerValue(int val) const; // float - void GetOptFloatValue(float& val, float& min, float& max); - void SaveOptFloatValue(float val); + void GetOptFloatValue(float& val, float& min, float& max) const; + void SaveOptFloatValue(float val) const; // bool - bool GetOptBoolValue(); - void SaveOptBoolValue(bool val); + bool GetOptBoolValue() const; + void SaveOptBoolValue(bool val) const; // token - LPCSTR GetOptTokenValue(); - const xr_token* GetOptToken(); + pcstr GetOptTokenValue() const; + const xr_token* GetOptToken() const; shared_str m_entry; ESystemDepends m_dep; From 2057bb8b7154cb38976b837e7e254dcb05a6d01c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 10:24:17 +0500 Subject: [PATCH 197/497] xrUICore/EditBox/UIEditBox.cpp: don't crash if backup value is missing --- src/xrUICore/EditBox/UIEditBox.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/xrUICore/EditBox/UIEditBox.cpp b/src/xrUICore/EditBox/UIEditBox.cpp index 3c16d2aed7c..b8477eaf274 100644 --- a/src/xrUICore/EditBox/UIEditBox.cpp +++ b/src/xrUICore/EditBox/UIEditBox.cpp @@ -54,8 +54,16 @@ void CUIEditBox::SaveBackUpOptValue() void CUIEditBox::UndoOptValue() { - SetText(m_opt_backup_value.c_str()); + cpcstr backup = m_opt_backup_value ? m_opt_backup_value.c_str() : GetOptStringValue(); + SetText(backup); CUIOptionsItem::UndoOptValue(); } -bool CUIEditBox::IsChangedOptValue() const { return 0 != xr_strcmp(m_opt_backup_value.c_str(), GetText()); } +bool CUIEditBox::IsChangedOptValue() const +{ + cpcstr current = GetText(); + cpcstr backup = m_opt_backup_value ? m_opt_backup_value.c_str() : GetOptStringValue(); + if (!current || !backup) + return false; + return 0 != xr_strcmp(current, backup); +} From 96096a57f59948160df22791284952d68b57934a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 22 Feb 2024 12:08:32 +0500 Subject: [PATCH 198/497] Fix build --- src/xrUICore/EditBox/UIEditBox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrUICore/EditBox/UIEditBox.cpp b/src/xrUICore/EditBox/UIEditBox.cpp index b8477eaf274..fc6be6a3bd2 100644 --- a/src/xrUICore/EditBox/UIEditBox.cpp +++ b/src/xrUICore/EditBox/UIEditBox.cpp @@ -54,7 +54,7 @@ void CUIEditBox::SaveBackUpOptValue() void CUIEditBox::UndoOptValue() { - cpcstr backup = m_opt_backup_value ? m_opt_backup_value.c_str() : GetOptStringValue(); + cpcstr backup = !m_opt_backup_value ? GetOptStringValue() : m_opt_backup_value.c_str(); SetText(backup); CUIOptionsItem::UndoOptValue(); } @@ -62,7 +62,7 @@ void CUIEditBox::UndoOptValue() bool CUIEditBox::IsChangedOptValue() const { cpcstr current = GetText(); - cpcstr backup = m_opt_backup_value ? m_opt_backup_value.c_str() : GetOptStringValue(); + cpcstr backup = !m_opt_backup_value ? GetOptStringValue() : m_opt_backup_value.c_str(); if (!current || !backup) return false; return 0 != xr_strcmp(current, backup); From 799e9519cb043fb55165f435f3c69ca76a3936fa Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 05:42:52 +0500 Subject: [PATCH 199/497] CUIFrameLineWnd now inherits and implements ITextureOwner --- src/xrUICore/EditBox/UIEditBox.cpp | 2 +- src/xrUICore/ListBox/UIListBox.cpp | 4 +- src/xrUICore/ListBox/UIListBoxItem.cpp | 2 +- src/xrUICore/ScrollBar/UIScrollBar.cpp | 4 +- src/xrUICore/SpinBox/UICustomSpin.cpp | 4 +- src/xrUICore/Windows/UIFrameLineWnd.cpp | 8 ++-- src/xrUICore/Windows/UIFrameLineWnd.h | 48 ++++++++++++++++------- src/xrUICore/Windows/UITextFrameLineWnd.h | 5 --- 8 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/xrUICore/EditBox/UIEditBox.cpp b/src/xrUICore/EditBox/UIEditBox.cpp index fc6be6a3bd2..0e56be49856 100644 --- a/src/xrUICore/EditBox/UIEditBox.cpp +++ b/src/xrUICore/EditBox/UIEditBox.cpp @@ -25,7 +25,7 @@ bool CUIEditBox::InitTextureEx(pcstr texture, pcstr shader, bool fatal /*= true* AttachChild(m_frameLine); m_frameLine->SetAutoDelete(true); } - const bool result = m_frameLine->InitTexture(texture, shader, fatal); + const bool result = m_frameLine->InitTextureEx(texture, shader, fatal); m_frameLine->SetWndPos(Fvector2().set(0, 0)); m_frameLine->SetWndSize(GetWndSize()); return result; diff --git a/src/xrUICore/ListBox/UIListBox.cpp b/src/xrUICore/ListBox/UIListBox.cpp index 53c4876c9a0..5964ded1f9f 100644 --- a/src/xrUICore/ListBox/UIListBox.cpp +++ b/src/xrUICore/ListBox/UIListBox.cpp @@ -55,7 +55,7 @@ CUIListBoxItem* CUIListBox::AddItem() item->SetWidth(GetDesiredChildWidth()); if (m_selection_texture.size()) - item->InitTexture(m_selection_texture.c_str(), "hud" DELIMITER "default"); + item->InitTexture(m_selection_texture.c_str()); else item->InitDefault(); @@ -72,7 +72,7 @@ void CUIListBox::AddExistingItem(CUIListBoxItem* item) item->SetWidth(GetDesiredChildWidth()); if (m_selection_texture.size()) - item->InitTexture(m_selection_texture.c_str(), "hud" DELIMITER "default"); + item->InitTexture(m_selection_texture.c_str()); else item->InitDefault(); diff --git a/src/xrUICore/ListBox/UIListBoxItem.cpp b/src/xrUICore/ListBox/UIListBoxItem.cpp index e18d5a81e28..5975bb69229 100644 --- a/src/xrUICore/ListBox/UIListBoxItem.cpp +++ b/src/xrUICore/ListBox/UIListBoxItem.cpp @@ -27,7 +27,7 @@ void CUIListBoxItem::OnFocusReceive() GetMessageTarget()->SendMessage(this, LIST_ITEM_FOCUS_RECEIVED); } -void CUIListBoxItem::InitDefault() { InitTexture("ui_listline", "hud" DELIMITER "default"); } +void CUIListBoxItem::InitDefault() { InitTexture("ui_listline"); } void CUIListBoxItem::SetFont(CGameFont* F) { m_text->SetFont(F); } CGameFont* CUIListBoxItem::GetFont() { return (m_text) ? m_text->GetFont() : NULL; } bool CUIListBoxItem::OnMouseDown(int mouse_btn) diff --git a/src/xrUICore/ScrollBar/UIScrollBar.cpp b/src/xrUICore/ScrollBar/UIScrollBar.cpp index 73ccddd3b2e..8221f9fb220 100644 --- a/src/xrUICore/ScrollBar/UIScrollBar.cpp +++ b/src/xrUICore/ScrollBar/UIScrollBar.cpp @@ -77,7 +77,7 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, cpcstr texture = xml_doc.Read(_path, 0, nullptr); R_ASSERT(texture); - if (!m_FrameBackground->InitTexture(texture, "hud" DELIMITER "default", false)) + if (!m_FrameBackground->InitTexture(texture, false)) { tempBackground = xr_new("temporary background"); tempBackground->SetWndRect(GetWndRect()); @@ -114,7 +114,7 @@ bool CUIScrollBar::InitScrollBar(Fvector2 pos, float length, bool bIsHorizontal, cpcstr texture = xml_doc.Read(_path, 0, nullptr); R_ASSERT(texture); - if (!m_FrameBackground->InitTexture(texture, "hud" DELIMITER "default", false)) + if (!m_FrameBackground->InitTexture(texture, false)) { tempBackground = xr_new("temporary background"); tempBackground->SetWndRect(GetWndRect()); diff --git a/src/xrUICore/SpinBox/UICustomSpin.cpp b/src/xrUICore/SpinBox/UICustomSpin.cpp index 996f911f0ba..127a6238ecf 100644 --- a/src/xrUICore/SpinBox/UICustomSpin.cpp +++ b/src/xrUICore/SpinBox/UICustomSpin.cpp @@ -52,8 +52,8 @@ void CUICustomSpin::InitSpin(Fvector2 pos, Fvector2 size) m_pFrameLine->SetWndPos(Fvector2().set(0, 0)); m_pFrameLine->SetWndSize(Fvector2().set(size.x, SPIN_HEIGHT)); - if (!m_pFrameLine->InitTexture("ui_inGame2_spin_box", "hud" DELIMITER "default", false)) - m_pFrameLine->InitTexture("ui_spiner", "hud" DELIMITER "default", false); + if (!m_pFrameLine->InitTexture("ui_inGame2_spin_box", false)) + m_pFrameLine->InitTexture("ui_spiner", false); m_pBtnUp->InitButton(Fvector2().set(size.x - BTN_SIZE_X - 2.0f, 1.0f), Fvector2().set(BTN_SIZE_X, BTN_SIZE_Y)); diff --git a/src/xrUICore/Windows/UIFrameLineWnd.cpp b/src/xrUICore/Windows/UIFrameLineWnd.cpp index a423646a7d8..9318fbddfdd 100644 --- a/src/xrUICore/Windows/UIFrameLineWnd.cpp +++ b/src/xrUICore/Windows/UIFrameLineWnd.cpp @@ -8,10 +8,10 @@ CUIFrameLineWnd::CUIFrameLineWnd(pcstr window_name) m_texture_color = color_argb(255, 255, 255, 255); } -bool CUIFrameLineWnd::InitFrameLineWnd(LPCSTR base_name, Fvector2 pos, Fvector2 size, bool horizontal, bool fatal /*= true*/) +bool CUIFrameLineWnd::InitFrameLineWnd(pcstr base_name, Fvector2 pos, Fvector2 size, bool horizontal, bool fatal /*= true*/) { InitFrameLineWnd(pos, size, horizontal); - return InitTexture(base_name, "hud" DELIMITER "default", fatal); + return InitTexture(base_name, fatal); } void CUIFrameLineWnd::InitFrameLineWnd(Fvector2 pos, Fvector2 size, bool horizontal) @@ -24,10 +24,10 @@ void CUIFrameLineWnd::InitFrameLineWnd(Fvector2 pos, Fvector2 size, bool horizon bool CUIFrameLineWnd::InitTexture(pcstr texture, bool fatal /*= true*/) { - return InitTexture(texture, "hud" DELIMITER "default", fatal); + return InitTextureEx(texture, "hud" DELIMITER "default", fatal); } -bool CUIFrameLineWnd::InitTexture(pcstr texture, pcstr shader, bool fatal /*= true*/) +bool CUIFrameLineWnd::InitTextureEx(pcstr texture, pcstr shader, bool fatal /*= true*/) { dbg_tex_name = texture; string256 buf; diff --git a/src/xrUICore/Windows/UIFrameLineWnd.h b/src/xrUICore/Windows/UIFrameLineWnd.h index e036f6420aa..606060dada3 100644 --- a/src/xrUICore/Windows/UIFrameLineWnd.h +++ b/src/xrUICore/Windows/UIFrameLineWnd.h @@ -1,7 +1,7 @@ #pragma once #include "UIWindow.h" -class XRUICORE_API CUIFrameLineWnd : public CUIWindow +class XRUICORE_API CUIFrameLineWnd : public CUIWindow, public ITextureOwner { typedef CUIWindow inherited; @@ -16,27 +16,45 @@ class XRUICORE_API CUIFrameLineWnd : public CUIWindow CUIFrameLineWnd(pcstr window_name); - bool InitFrameLineWnd(LPCSTR base_name, Fvector2 pos, Fvector2 size, bool horizontal = true, bool fatal = true); + bool InitFrameLineWnd(pcstr base_name, Fvector2 pos, Fvector2 size, bool horizontal = true, bool fatal = true); void InitFrameLineWnd(Fvector2 pos, Fvector2 size, bool horizontal = true); - bool InitTexture(pcstr texture, bool fatal = true); - bool InitTexture(pcstr texture, pcstr shader = "hud" DELIMITER "default", bool fatal = true); + bool InitTexture(pcstr texture, bool fatal = true) override; + bool InitTextureEx(pcstr texture, pcstr shader = "hud" DELIMITER "default", bool fatal = true) override; - virtual void Draw(); + void Draw() override; - float GetTextureHeight() const { return m_tex_rect[0].height(); } - float GetTextureWidth() const { return m_tex_rect[0].width(); } - void SetTextureColor(u32 cl) { m_texture_color = cl; } - bool IsHorizontal() { return bHorizontal; } - void SetHorizontal(bool horiz) { bHorizontal = horiz; } - - void SetTextureVisible(bool value) { m_bTextureVisible = value; } - void SetShader(ui_shader sh) { m_shader = sh; } - void SetTextureRect(Frect rect, RectSegment idx) + void SetTextureRect(const Frect rect, RectSegment idx) { - R_ASSERT(idx >= flFirst && idx <= flSecond); + VERIFY(idx >= flFirst && idx < flMax); + if (idx >= flMax) + return; m_tex_rect[idx] = rect; } + void SetTextureRect(const Frect& r) override + { + VERIFY2(false, "This overload is not supposed to be called!!!"); + m_tex_rect[flBack] = r; + } + + const Frect& GetTextureRect() const override + { + VERIFY2(false, "This overload is not supposed to be called!!!"); + return m_tex_rect[flBack]; + } + + void SetTextureColor(u32 cl) override { m_texture_color = cl; } + u32 GetTextureColor() const override { return m_texture_color; } + + void SetStretchTexture(bool /*stretch*/) override {} + bool GetStretchTexture() override { return false; } + + void SetTextureVisible(bool value) { m_bTextureVisible = value; } + void SetShader(const ui_shader& sh) { m_shader = sh; } + + bool IsHorizontal() const { return bHorizontal; } + void SetHorizontal(bool horiz) { bHorizontal = horiz; } + pcstr GetDebugType() override { return "CUIFrameLineWnd"; } protected: diff --git a/src/xrUICore/Windows/UITextFrameLineWnd.h b/src/xrUICore/Windows/UITextFrameLineWnd.h index 5d26b634cdb..d0e104d50c0 100644 --- a/src/xrUICore/Windows/UITextFrameLineWnd.h +++ b/src/xrUICore/Windows/UITextFrameLineWnd.h @@ -18,11 +18,6 @@ class XRUICORE_API CUITextFrameLineWnd final : public CUIWindow m_frameline.SetHorizontal(horizontal); } - float GetTextureHeight() const - { - return m_frameline.GetTextureHeight(); - } - void SetColor(u32 cl) { m_frameline.SetTextureColor(cl); From 4b1986e6b60fbaa16b0ff086c128cce8e2c1c8fc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 06:54:33 +0500 Subject: [PATCH 200/497] CUIButtonHint: support for CS hint (#382) --- src/xrUICore/Buttons/UIBtnHint.cpp | 50 +++++++++++++++++++++++------- src/xrUICore/Buttons/UIBtnHint.h | 7 +++-- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/xrUICore/Buttons/UIBtnHint.cpp b/src/xrUICore/Buttons/UIBtnHint.cpp index f4a02a9001f..ba4efe1cfde 100644 --- a/src/xrUICore/Buttons/UIBtnHint.cpp +++ b/src/xrUICore/Buttons/UIBtnHint.cpp @@ -1,19 +1,28 @@ #include "pch.hpp" #include "UIBtnHint.h" #include "Static/UIStatic.h" +#include "Windows/UIFrameLineWnd.h" #include "XML/UIXmlInitBase.h" CUIButtonHint* g_btnHint = nullptr; CUIButtonHint* g_statHint = nullptr; -CUIButtonHint::CUIButtonHint() - : CUIFrameWindow(CUIButtonHint::GetDebugType()), - m_ownerWnd(nullptr), - m_enabledOnFrame(false) +CUIButtonHint::CUIButtonHint() : CUIFrameWindow(CUIButtonHint::GetDebugType()) { CUIXml uiXml; uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "hint_item.xml"); - CUIXmlInitBase::InitFrameWindow(uiXml, "button_hint", 0, this); + + if (uiXml.NavigateToNode("button_hint:texture")) // COP + CUIXmlInitBase::InitFrameWindow(uiXml, "button_hint", 0, this); + else // CS + { + CUIXmlInitBase::InitWindow(uiXml, "button_hint", 0, this); + + m_border = xr_new("Border"); + m_border->SetAutoDelete(true); + AttachChild(m_border); + CUIXmlInitBase::InitFrameLine(uiXml, "button_hint:frame_line", 0, m_border); + } m_text = xr_new("Text"); m_text->SetAutoDelete(true); @@ -26,7 +35,14 @@ void CUIButtonHint::OnRender() if (m_enabledOnFrame) { m_text->Update(); - SetTextureColor(color_rgba(255, 255, 255, color_get_A(m_text->GetTextColor()))); + + const u32 color = color_rgba(255, 255, 255, color_get_A(m_text->GetTextColor())); + + if (m_border) + m_border->SetTextureColor(color); + else + SetTextureColor(color); + Draw(); m_enabledOnFrame = false; } @@ -37,13 +53,25 @@ void CUIButtonHint::SetHintText(CUIWindow* w, LPCSTR text) m_ownerWnd = w; m_text->SetTextST(text); - m_text->AdjustHeightToText(); + if (m_border) + { + m_text->AdjustWidthToText(); + const float hh = _max(m_text->GetWidth()+30.0f, 80.0f); + SetWidth(hh); + m_border->SetWidth(hh); // XXX: CUIFrameLineWnd ignores this. Fix + } + else + { + m_text->AdjustHeightToText(); - Fvector2 new_size; - new_size.x = GetWndSize().x; - new_size.y = m_text->GetWndSize().y + 20.0f; + const Fvector2 new_size + { + GetWndSize().x, + m_text->GetWndSize().y + 20.0f + }; - SetWndSize(new_size); + SetWndSize(new_size); + } m_text->ResetColorAnimation(); } diff --git a/src/xrUICore/Buttons/UIBtnHint.h b/src/xrUICore/Buttons/UIBtnHint.h index 8e1b8f0a52f..a157b5e5aed 100644 --- a/src/xrUICore/Buttons/UIBtnHint.h +++ b/src/xrUICore/Buttons/UIBtnHint.h @@ -2,13 +2,16 @@ #include "xrUICore/Windows/UIFrameWindow.h" class CUIStatic; +class CUIFrameLineWnd; class XRUICORE_API CUIButtonHint final : public CUIFrameWindow { - CUIWindow* m_ownerWnd; + CUIWindow* m_ownerWnd{}; CUIStatic* m_text; - bool m_enabledOnFrame; + CUIFrameLineWnd* m_border{}; + + bool m_enabledOnFrame{}; public: CUIButtonHint(); From f5415af32384a3771033f61964396059e1b84ee9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 07:13:00 +0500 Subject: [PATCH 201/497] xrGame/ui/UIChangeMap.h|cpp: simplify UI members creation Also constify and cleanup. --- src/xrGame/ui/UIChangeMap.cpp | 80 ++++++++--------------------------- src/xrGame/ui/UIChangeMap.h | 21 ++++----- 2 files changed, 26 insertions(+), 75 deletions(-) diff --git a/src/xrGame/ui/UIChangeMap.cpp b/src/xrGame/ui/UIChangeMap.cpp index 3a7ec32764e..b19b83f4622 100644 --- a/src/xrGame/ui/UIChangeMap.cpp +++ b/src/xrGame/ui/UIChangeMap.cpp @@ -11,67 +11,23 @@ #include "UIMapList.h" #include "Common/object_broker.h" #include "UIGameCustom.h" -#include "UIDialogHolder.h" -#include "xrUICore/Windows/UIFrameWindow.h" +#include "UIHelper.h" -CUIChangeMap::CUIChangeMap() : CUIDialogWnd(CUIChangeMap::GetDebugType()) -{ - m_prev_upd_time = 0; - - bkgrnd = xr_new("Background"); - bkgrnd->SetAutoDelete(true); - AttachChild(bkgrnd); - - header = xr_new("Header"); - header->SetAutoDelete(true); - AttachChild(header); - - map_pic = xr_new("Map picture"); - map_pic->SetAutoDelete(true); - AttachChild(map_pic); - - map_frame = xr_new("Map frame"); - map_frame->SetAutoDelete(true); - AttachChild(map_frame); - - map_version = xr_new("Map version"); - map_version->SetAutoDelete(true); - AttachChild(map_version); - - frame = xr_new("Frame"); - frame->SetAutoDelete(true); - AttachChild(frame); - - lst_back = xr_new("Map list back"); - lst_back->SetAutoDelete(true); - AttachChild(lst_back); - - lst = xr_new(); - lst->SetAutoDelete(true); - AttachChild(lst); - - btn_ok = xr_new(); - btn_ok->SetAutoDelete(true); - AttachChild(btn_ok); - - btn_cancel = xr_new(); - btn_cancel->SetAutoDelete(true); - AttachChild(btn_cancel); -} +CUIChangeMap::CUIChangeMap() : CUIDialogWnd(CUIChangeMap::GetDebugType()) {} void CUIChangeMap::InitChangeMap(CUIXml& xml_doc) { CUIXmlInit::InitWindow(xml_doc, "change_map", 0, this); - CUIXmlInit::InitStatic(xml_doc, "change_map:header", 0, header); - CUIXmlInit::InitStatic(xml_doc, "change_map:background", 0, bkgrnd); - CUIXmlInit::InitStatic(xml_doc, "change_map:map_frame", 0, map_frame); - CUIXmlInit::InitStatic(xml_doc, "change_map:map_ver_txt", 0, map_version); - CUIXmlInit::InitStatic(xml_doc, "change_map:map_pic", 0, map_pic); - // CUIXmlInit::InitFrameWindow (xml_doc, "change_map:list_back", 0, lst_back); - // CUIXmlInit::InitFrameWindow (xml_doc, "change_map:frame", 0, frame); - CUIXmlInit::InitListBox(xml_doc, "change_map:list", 0, lst); - CUIXmlInit::Init3tButton(xml_doc, "change_map:btn_ok", 0, btn_ok); - CUIXmlInit::Init3tButton(xml_doc, "change_map:btn_cancel", 0, btn_cancel); + std::ignore = UIHelper::CreateStatic(xml_doc, "change_map:background", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "change_map:header", this); + map_pic = UIHelper::CreateStatic(xml_doc, "change_map:map_pic", this); + std::ignore = UIHelper::CreateStatic(xml_doc, "change_map:map_frame", this); + map_version = UIHelper::CreateStatic(xml_doc, "change_map:map_ver_txt", this); + // std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:frame", this); + // std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:list_back", this); + lst = UIHelper::CreateListBox(xml_doc, "change_map:list", this); + btn_ok = UIHelper::Create3tButton(xml_doc, "change_map:btn_ok", this); + btn_cancel = UIHelper::Create3tButton(xml_doc, "change_map:btn_cancel", this); FillUpList(); } @@ -103,19 +59,19 @@ void CUIChangeMap::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) void CUIChangeMap::OnItemSelect() { - u32 idx = lst->GetSelectedIDX(); + const u32 idx = lst->GetSelectedIDX(); if (idx == u32(-1)) return; const SGameTypeMaps& M = gMapListHelper.GetMapListFor((EGameIDs)GameID()); const shared_str& name = M.m_map_names[idx].map_name; - pstr map_ver = NULL; + pstr map_ver = nullptr; STRCONCAT(map_ver, "[", M.m_map_names[idx].map_ver.c_str() ? M.m_map_names[idx].map_ver.c_str() : "unknown", "]"); xr_string map_name = "intro" DELIMITER "intro_map_pic_"; map_name += name.c_str(); - xr_string full_name = map_name + ".dds"; + const xr_string full_name = map_name + ".dds"; - Frect orig_rect = map_pic->GetTextureRect(); + const Frect orig_rect = map_pic->GetTextureRect(); if (FS.exist("$game_textures$", full_name.c_str())) map_pic->InitTexture(map_name.c_str()); else @@ -146,11 +102,11 @@ void CUIChangeMap::FillUpList() lst->Clear(); const SGameTypeMaps& M = gMapListHelper.GetMapListFor((EGameIDs)GameID()); - u32 cnt = M.m_map_names.size(); + const u32 cnt = M.m_map_names.size(); for (u32 i = 0; i < cnt; ++i) { CUIListBoxItem* itm = lst->AddTextItem(StringTable().translate(M.m_map_names[i].map_name).c_str()); - itm->Enable(true); // m_pExtraContentFilter->IsDataEnabled(M.m_map_names[i].map_name.c_str())); + itm->Enable(true); } } diff --git a/src/xrGame/ui/UIChangeMap.h b/src/xrGame/ui/UIChangeMap.h index 546c2fc73f4..13cde83137d 100644 --- a/src/xrGame/ui/UIChangeMap.h +++ b/src/xrGame/ui/UIChangeMap.h @@ -26,17 +26,12 @@ class CUIChangeMap final : public CUIDialogWnd protected: void FillUpList(); - CUIStatic* bkgrnd; - CUIStatic* header; - CUIStatic* map_pic; - CUIStatic* map_frame; - CUIStatic* map_version; - CUIFrameWindow* frame; - CUIFrameWindow* lst_back; - CUIListBox* lst; - - CUI3tButton* btn_ok; - CUI3tButton* btn_cancel; - - u32 m_prev_upd_time; + CUIStatic* map_pic{}; + CUIStatic* map_version{}; + CUIListBox* lst{}; + + CUI3tButton* btn_ok{}; + CUI3tButton* btn_cancel{}; + + u32 m_prev_upd_time{}; }; From 9d88f682441548fb5575389473a4507f885e793a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 07:14:45 +0500 Subject: [PATCH 202/497] xrGame/ui/UIChangeMap.cpp: return UI elements from CS (#382) --- src/xrGame/ui/UIChangeMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrGame/ui/UIChangeMap.cpp b/src/xrGame/ui/UIChangeMap.cpp index b19b83f4622..c57ab596915 100644 --- a/src/xrGame/ui/UIChangeMap.cpp +++ b/src/xrGame/ui/UIChangeMap.cpp @@ -23,8 +23,8 @@ void CUIChangeMap::InitChangeMap(CUIXml& xml_doc) map_pic = UIHelper::CreateStatic(xml_doc, "change_map:map_pic", this); std::ignore = UIHelper::CreateStatic(xml_doc, "change_map:map_frame", this); map_version = UIHelper::CreateStatic(xml_doc, "change_map:map_ver_txt", this); - // std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:frame", this); - // std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:list_back", this); + std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:frame", this, false); + std::ignore = UIHelper::CreateFrameWindow(xml_doc, "change_map:list_back", this, false); lst = UIHelper::CreateListBox(xml_doc, "change_map:list", this); btn_ok = UIHelper::Create3tButton(xml_doc, "change_map:btn_ok", this); btn_cancel = UIHelper::Create3tButton(xml_doc, "change_map:btn_cancel", this); From 63276ccbc8f6c463ab3d294eccbb01552443b813 Mon Sep 17 00:00:00 2001 From: yohjimane Date: Thu, 22 Feb 2024 21:38:52 -0800 Subject: [PATCH 203/497] [FIX] possible crash with player hud tuner (#1619) --- src/xrGame/player_hud_tune.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/xrGame/player_hud_tune.cpp b/src/xrGame/player_hud_tune.cpp index e4e50617844..087b4108cb7 100644 --- a/src/xrGame/player_hud_tune.cpp +++ b/src/xrGame/player_hud_tune.cpp @@ -233,14 +233,16 @@ void player_hud::tune(Ivector _values) float _curr_dr = _delta_rot; - u8 idx = m_attached_items[hud_adj_item_idx]->m_parent_hud_item->GetCurrentHudOffsetIdx(); + attachable_hud_item* hi = m_attached_items[hud_adj_item_idx]; + if (!hi) + return; + + u8 idx = hi->m_parent_hud_item->GetCurrentHudOffsetIdx(); if (idx) _curr_dr /= 20.0f; - Fvector& pos_ = (idx != 0) ? m_attached_items[hud_adj_item_idx]->hands_offset_pos() : - m_attached_items[hud_adj_item_idx]->hands_attach_pos(); - Fvector& rot_ = (idx != 0) ? m_attached_items[hud_adj_item_idx]->hands_offset_rot() : - m_attached_items[hud_adj_item_idx]->hands_attach_rot(); + Fvector& pos_ = (idx != 0) ? hi->hands_offset_pos() : hi->hands_attach_pos(); + Fvector& rot_ = (idx != 0) ? hi->hands_offset_rot() : hi->hands_attach_rot(); if (hud_adj_mode == 1) { @@ -269,21 +271,21 @@ void player_hud::tune(Ivector _values) { if (idx == 0) { - Msg("[%s]", m_attached_items[hud_adj_item_idx]->m_sect_name.c_str()); + Msg("[%s]", hi->m_sect_name.c_str()); Msg("hands_position%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); Msg("hands_orientation%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); Log("-----------"); } else if (idx == 1) { - Msg("[%s]", m_attached_items[hud_adj_item_idx]->m_sect_name.c_str()); + Msg("[%s]", hi->m_sect_name.c_str()); Msg("aim_hud_offset_pos%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); Msg("aim_hud_offset_rot%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); Log("-----------"); } else if (idx == 2) { - Msg("[%s]", m_attached_items[hud_adj_item_idx]->m_sect_name.c_str()); + Msg("[%s]", hi->m_sect_name.c_str()); Msg("gl_hud_offset_pos%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); Msg("gl_hud_offset_rot%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); Log("-----------"); From 0e8c0d02405afb4d3501bff647d77a32693c1c08 Mon Sep 17 00:00:00 2001 From: yohjimane Date: Thu, 22 Feb 2024 21:39:50 -0800 Subject: [PATCH 204/497] [FEATURE] Add console command to disable lens flare (#1618) --- src/xrEngine/xr_efflensflare.cpp | 6 ++++++ src/xrEngine/xr_ioc_cmd.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/xrEngine/xr_efflensflare.cpp b/src/xrEngine/xr_efflensflare.cpp index ea41ed8f24d..ca9b005065d 100644 --- a/src/xrEngine/xr_efflensflare.cpp +++ b/src/xrEngine/xr_efflensflare.cpp @@ -30,6 +30,8 @@ #define BLEND_INC_SPEED 8.0f #define BLEND_DEC_SPEED 4.0f +extern ENGINE_API int ps_disable_lens_flare; + //------------------------------------------------------------------------------ void CLensFlareDescriptor::SetSource(float fRadius, bool ign_color, pcstr tex_name, pcstr sh_name) { @@ -535,6 +537,10 @@ blend_lerp(fBlend,TP.vis,BLEND_DEC_SPEED,Device.fTimeDelta); void CLensFlare::Render(bool bSun, bool bFlares, bool bGradient) { + if (ps_disable_lens_flare) + { + bFlares = false; + } if (!bRender) return; if (!m_Current) diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index c9cd8e69918..fff4ce73556 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -624,6 +624,8 @@ ENGINE_API float ps_r3_dyn_wet_surf_near = 5.f; // 10.0f ENGINE_API float ps_r3_dyn_wet_surf_far = 20.f; // 30.0f ENGINE_API int ps_r3_dyn_wet_surf_sm_res = 256; // 256 +int ps_disable_lens_flare = 1; + class CCC_renderer : public CCC_Token { typedef CCC_Token inherited; @@ -978,4 +980,6 @@ void CCC_Register() #endif CMD4(CCC_Vector3, "ssfx_wetness_multiplier", &ssfx_wetness_multiplier, Fvector3({ 0.1f, 0.1f, 0.0f} ), Fvector3({ 20.0f, 20.0f, 0.0f })); + + CMD4(CCC_Integer, "disable_lens_flare", &ps_disable_lens_flare, 0, 1); }; From f4742f9b7676a66c482c72a920c426805b4ddc75 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 10:47:40 +0500 Subject: [PATCH 205/497] vs-chromium-project.txt: ignore hash cache and build folder [skip ci] .hash_cache.txt is a file produced by https://github.com/nitrocaster/gcache --- vs-chromium-project.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vs-chromium-project.txt b/vs-chromium-project.txt index 85db54aa665..7289bf87fdf 100644 --- a/vs-chromium-project.txt +++ b/vs-chromium-project.txt @@ -1,10 +1,10 @@ [SourceExplorer.ignore] .git/ -*.suo bin/ -intermediate/ -lib/ +build/ src/_CppDependOut +*.suo +.hash_cache.txt [SearchableFiles.include] *.cpp From c0d3ff388a32899f9b17c96f4c86caf126611c66 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 24 Feb 2024 05:45:16 +0500 Subject: [PATCH 206/497] Move Device related files to Execution & 3D folder in VS project file --- src/xrEngine/CMakeLists.txt | 2 +- src/xrEngine/xrEngine.vcxproj.filters | 87 +++++++++++++-------------- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index 7625340959c..ea8c28ca5a7 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -319,7 +319,7 @@ target_sources_grouped( target_sources_grouped( TARGET xrEngine - NAME "Render\\Device" + NAME "Render\\Execution & 3D" FILES device.cpp device.h diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 4930fdadfaa..51e86a982d4 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -142,9 +142,6 @@ {88084f61-660e-4bb7-ab64-5fd27a09d18a} - - {e4d34774-3a5b-468f-9400-12c702636fa1} - {9edc9b50-4fb3-495e-b1c7-692a6947715f} @@ -363,21 +360,6 @@ Interfaces\ILoadingScreen - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - Game API\StringTable @@ -396,6 +378,21 @@ General + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + @@ -587,36 +584,9 @@ General\Profiler - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - - - Render\Device - Game API\StringTable - - Render\Device - Game API\Level Controller @@ -638,6 +608,33 @@ Game API\Objects + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + + + Render\Execution & 3D + From 81f3285f91853037fa67f17c8118a093a811c397 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Thu, 29 Feb 2024 17:31:11 +0500 Subject: [PATCH 207/497] appveyor.yml: restored Windows configuration Oops, I removed it by accident in f8de69580f69e4909b1c836b21b2cb6d5aa06ae0 --- appveyor.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 621b7c74a1c..25e1aea9e67 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,6 +26,32 @@ branches: cache: - src/packages -> **/packages.config +for: +- + matrix: + only: + - image: Visual Studio 2022 + + before_build: + - git submodule update --init --recursive + - nuget restore src\engine.sln + + build: + project: src/engine.sln + parallel: true + verbosity: minimal + + after_build: + - cmd: misc/windows/xr_pack_build.cmd "%CONFIGURATION%" "%PLATFORM%" + + artifacts: + - path: res/OpenXRay.*.7z + name: OpenXRay.*.7z + - path: res/Symbols.*.7z + name: Symbols.*.7z + - path: res/Utils.*.7z + name: Utils.*.7z + test: off deploy: From 715e06d152c26f5ac95a875aa9a72cd72a1d46bd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 25 Feb 2024 13:57:11 +0500 Subject: [PATCH 208/497] xrSound/SoundRender_Cache.h: constify get_dataptr Also formatting and set nodiscard attribute xrSound/SoundRender_TargetA.cpp: constify --- src/xrSound/SoundRender_Cache.cpp | 2 +- src/xrSound/SoundRender_Cache.h | 14 ++++++++++---- src/xrSound/SoundRender_TargetA.cpp | 6 +++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/xrSound/SoundRender_Cache.cpp b/src/xrSound/SoundRender_Cache.cpp index 0e0915b4622..d2609915889 100644 --- a/src/xrSound/SoundRender_Cache.cpp +++ b/src/xrSound/SoundRender_Cache.cpp @@ -45,7 +45,7 @@ void CSoundRender_Cache::move2top(cache_line* line) VERIFY(c_end->next == NULL); } -bool CSoundRender_Cache::request(cache_cat& cat, u32 id) +bool CSoundRender_Cache::request(const cache_cat& cat, u32 id) { // 1. check if cached version available id %= cat.size; diff --git a/src/xrSound/SoundRender_Cache.h b/src/xrSound/SoundRender_Cache.h index bad2557d6b4..65ef9b49b34 100644 --- a/src/xrSound/SoundRender_Cache.h +++ b/src/xrSound/SoundRender_Cache.h @@ -28,7 +28,7 @@ struct cache_cat // cache allocation table u16* table; // page-table u32 size; // in pages }; -#define CAT_FREE 0xffff +constexpr u16 CAT_FREE = 0xffff; ////////////////////////////////////////////////////////////////////////// class CSoundRender_Cache { @@ -39,6 +39,7 @@ class CSoundRender_Cache u32 _total; // bytes total (heap) u32 _line; // line size (bytes) u32 _count; // number of lines + public: u32 _stat_hit; u32 _stat_miss; @@ -47,16 +48,21 @@ class CSoundRender_Cache void move2top(cache_line* line); // move one line to TOP-priority void disconnect(); // disconnect from CATs void format(); // format structure (like filesystem) + public: - bool request(cache_cat& cat, u32 id); // TRUE=need to fill, FALSE=cached info avail + bool request(const cache_cat& cat, u32 id); // TRUE=need to fill, FALSE=cached info avail void purge(); // discard all contents of cache - void* get_dataptr(cache_cat& cat, u32 id) + [[nodiscard]] + void* get_dataptr(const cache_cat& cat, u32 id) const { id %= cat.size; return c_storage[cat.table[id]].data; - } //. + } + + [[nodiscard]] u32 get_linesize() const { return _line; } + void cat_create(cache_cat& cat, u32 bytes); void cat_destroy(cache_cat& cat); diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 9dc973dc514..7671236634f 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -27,7 +27,7 @@ bool CSoundRender_TargetA::_initialize() // initialize buffer A_CHK(alGenBuffers(sdef_target_count, pBuffers)); alGenSources(1, &pSource); - ALenum error = alGetError(); + const ALenum error = alGetError(); if (AL_NO_ERROR == error) { A_CHK(alSourcei(pSource, AL_LOOPING, AL_FALSE)); @@ -70,7 +70,7 @@ void CSoundRender_TargetA::start(CSoundRender_Emitter* E) void CSoundRender_TargetA::render() { - for (ALuint pBuffer : pBuffers) + for (const ALuint pBuffer : pBuffers) fill_block(pBuffer); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); @@ -96,7 +96,7 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourceStop(pSource)); A_CHK(alSourcei(pSource, AL_BUFFER, 0)); - for (ALuint pBuffer : pBuffers) + for (const ALuint pBuffer : pBuffers) fill_block(pBuffer); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); From d39eca0c8af889a1acbe143d024da1795db7ebc0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 25 Feb 2024 14:00:32 +0500 Subject: [PATCH 209/497] xrSound/SoundRender_CoreA.cpp: more correct s_targets clearing code And replace push_back with emplace_back --- src/xrSound/SoundRender_CoreA.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 314ab15c3ff..1cb755dd4d1 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -120,7 +120,7 @@ void CSoundRender_CoreA::_initialize() T = xr_new(auxSlot); if (T->_initialize()) { - s_targets.push_back(T); + s_targets.emplace_back(T); } else { @@ -143,13 +143,12 @@ void CSoundRender_CoreA::_clear() inherited::_clear(); xr_delete(m_effects); // remove targets - CSoundRender_Target* T = nullptr; - for (auto& sr_target : s_targets) + for (auto& T : s_targets) { - T = sr_target; T->_destroy(); xr_delete(T); } + s_targets.clear(); // Reset the current context to NULL. alcMakeContextCurrent(nullptr); // Release the context and the device. From 86355afa35d79fa3f38080ae4c0a89088a16f9fc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 25 Feb 2024 20:03:43 +0500 Subject: [PATCH 210/497] xrGame/xrServer_CL_connect.cpp: fix comment During COP development, someone in GSC has changed the comment to incorrect one. Whah? (why?) --- src/xrGame/xrServer_CL_connect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/xrServer_CL_connect.cpp b/src/xrGame/xrServer_CL_connect.cpp index 6d48ebf49c3..af1807a0ab6 100644 --- a/src/xrGame/xrServer_CL_connect.cpp +++ b/src/xrGame/xrServer_CL_connect.cpp @@ -146,7 +146,7 @@ void xrServer::SendConnectResult(IClient* CL, u8 res, u8 res1, pcstr ResultStr) if (!res) // need disconnect { #ifdef MP_LOGGING - Msg("* Server disconnecting client, resaon: %s", ResultStr); + Msg("* Server disconnecting client, reason: %s", ResultStr); #endif Flush_Clients_Buffers(); DisconnectClient(CL, ResultStr); From 2bc880839d8a34fb95f9070435b32341634f44f2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 25 Feb 2024 20:26:03 +0500 Subject: [PATCH 211/497] Always normalize sight directions passed from scripts --- src/xrGame/script_game_object3.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/xrGame/script_game_object3.cpp b/src/xrGame/script_game_object3.cpp index 858b3b9eb59..e7d7a72b1e5 100644 --- a/src/xrGame/script_game_object3.cpp +++ b/src/xrGame/script_game_object3.cpp @@ -769,13 +769,10 @@ void CScriptGameObject::set_sight(SightManager::ESightType sight_type, Fvector* { if ((sight_type == SightManager::eSightTypeDirection) && vector3d && (_abs(vector3d->magnitude() - 1.f) > .01f)) { - if (!ClearSkyMode && !ShadowOfChernobylMode) - { #ifndef MASTER_GOLD - Msg("~ non-normalized direction passed [%f][%f][%f]", VPUSH(*vector3d)); + Msg("~ CSightManager : non-normalized direction passed [%f][%f][%f]", VPUSH(*vector3d)); #endif - vector3d->normalize(); - } + vector3d->normalize(); } stalker->sight().setup(sight_type, vector3d); @@ -803,13 +800,10 @@ void CScriptGameObject::set_sight(SightManager::ESightType sight_type, Fvector& { if ((sight_type == SightManager::eSightTypeDirection) && (_abs(vector3d.magnitude() - 1.f) > .01f)) { - if (!ClearSkyMode && !ShadowOfChernobylMode) - { #ifndef MASTER_GOLD - Msg("~ non-normalized direction passed [%f][%f][%f]", VPUSH(vector3d)); + Msg("~ CSightManager : non-normalized direction passed [%f][%f][%f]", VPUSH(vector3d)); #endif vector3d.normalize(); - } } stalker->sight().setup(sight_type, vector3d, torso_look); @@ -828,10 +822,9 @@ void CScriptGameObject::set_sight(SightManager::ESightType sight_type, Fvector* if ((sight_type == SightManager::eSightTypeDirection) && vector3d && (_abs(vector3d->magnitude() - 1.f) > .01f)) { #ifndef MASTER_GOLD - Msg("~ non-normalized direction passed [%f][%f][%f]", VPUSH(*vector3d)); + Msg("~ CSightManager : non-normalized direction passed [%f][%f][%f]", VPUSH(*vector3d)); #endif - if (!ClearSkyMode && !ShadowOfChernobylMode) - vector3d->normalize(); + vector3d->normalize(); } stalker->sight().setup(sight_type, vector3d); From 4c714cbab9ccf119f92a9b39027df561f003e5a4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 26 Feb 2024 09:52:25 +0500 Subject: [PATCH 212/497] xrGame/PHMovementControl.cpp: fix eHitTypePhysicStrike usage (#382) It should only be used in multiplayer Moved case ALife::eHitTypePhysicStrike in CPHMovementControl::ApplyHit a bit lower. (cosmetical change) --- src/xrGame/PHMovementControl.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/xrGame/PHMovementControl.cpp b/src/xrGame/PHMovementControl.cpp index af825c255aa..1e3b113bd7b 100644 --- a/src/xrGame/PHMovementControl.cpp +++ b/src/xrGame/PHMovementControl.cpp @@ -102,8 +102,9 @@ static ALife::EHitType DefineCollisionHitType(u16 material_idx) { if (GMLib.GetMaterialByIdx(material_idx)->Flags.test(SGameMtl::flInjurious)) return ALife::eHitTypeRadiation; + return ALife::eHitTypeStrike; } - else if (ShadowOfChernobylMode || ClearSkyMode) + if (ShadowOfChernobylMode || ClearSkyMode) return ALife::eHitTypePhysicStrike; return ALife::eHitTypeStrike; } @@ -1285,7 +1286,6 @@ void CPHMovementControl::ApplyHit(const Fvector& dir, const float P, ALife::EHit case ALife::eHitTypeBurn:; // stop case ALife::eHitTypeShock:; // stop case ALife::eHitTypeStrike:; // stop - case ALife::eHitTypePhysicStrike: // stop case ALife::eHitTypeWound: SetVelocity(Fvector().set(0, 0, 0)); break; // stop ; @@ -1296,8 +1296,9 @@ void CPHMovementControl::ApplyHit(const Fvector& dir, const float P, ALife::EHit break; // not stop case ALife::eHitTypeExplosion:; // stop case ALife::eHitTypeFireWound:; // stop - case ALife::eHitTypeWound_2:; - break; // stop //knife's alternative fire + case ALife::eHitTypeWound_2:; // stop //knife's alternative fire + case ALife::eHitTypePhysicStrike: // stop + break; // stop default: NODEFAULT; } } From 64f654b860f43d920768a4d3f456f6672f0a87e8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 26 Feb 2024 09:54:16 +0500 Subject: [PATCH 213/497] xrUICore/FontManager/FontManager.cpp: return size and interval font settings (#382) In original SOC/CS, interval was only set in stat_font, so GSC removed reading of these config values in COP and just set interval manually. But reading from config is generally better. Plus, mods could use interval, so let's return this code. --- src/xrUICore/FontManager/FontManager.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/xrUICore/FontManager/FontManager.cpp b/src/xrUICore/FontManager/FontManager.cpp index e9b8dbeeb04..2c6f53b0625 100644 --- a/src/xrUICore/FontManager/FontManager.cpp +++ b/src/xrUICore/FontManager/FontManager.cpp @@ -37,7 +37,6 @@ void CFontManager::InitializeFonts() InitializeFont(pFontGraffiti50Russian, "ui_font_graff_50"); InitializeFont(pFontLetterica25, "ui_font_letter_25"); InitializeFont(pFontStat, "stat_font", CGameFont::fsDeviceIndependent); - pFontStat->SetInterval(0.75f, 1.0f); } LPCSTR CFontManager::GetFontTexName(LPCSTR section) @@ -78,6 +77,17 @@ void CFontManager::InitializeFont(CGameFont*& F, LPCSTR section, u32 flags) #ifdef DEBUG F->m_font_name = section; #endif + + if (pSettings->line_exist(section, "size")) + { + const float sz = pSettings->r_float(section, "size"); + if (flags & CGameFont::fsDeviceIndependent) + F->SetHeightI(sz); + else + F->SetHeight(sz); + } + if (pSettings->line_exist(section, "interval")) + F->SetInterval(pSettings->r_fvector2(section, "interval")); } CFontManager::~CFontManager() From 0b79e2686d1cc237f3110710f03589e569422882 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 27 Feb 2024 19:05:08 +0500 Subject: [PATCH 214/497] xrGame/Actor_Network.cpp: fix comments --- src/xrGame/Actor_Network.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/xrGame/Actor_Network.cpp b/src/xrGame/Actor_Network.cpp index 140ba839fbc..ff4847b64ff 100644 --- a/src/xrGame/Actor_Network.cpp +++ b/src/xrGame/Actor_Network.cpp @@ -699,7 +699,6 @@ bool CActor::net_Spawn(CSE_Abstract* DC) IKinematicsAnimated* K = smart_cast(Visual()); K->PlayCycle("death_init"); - // m_HeavyBreathSnd.stop(); } @@ -1132,10 +1131,10 @@ void CActor::CalculateInterpolationParams() for (u32 k = 0; k < 3; k++) { SP0[k] = c * (c * (c * SCoeff[k][0] + SCoeff[k][1]) + SCoeff[k][2]) + SCoeff[k][3]; - SP1[k] = (c * c * SCoeff[k][0] * 3 + c * SCoeff[k][1] * 2 + SCoeff[k][2]) / 3; // 3 !!!! + SP1[k] = (c * c * SCoeff[k][0] * 3 + c * SCoeff[k][1] * 2 + SCoeff[k][2]) / 3; // скорость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!! HP0[k] = c * (c * (c * HCoeff[k][0] + HCoeff[k][1]) + HCoeff[k][2]) + HCoeff[k][3]; - HP1[k] = (c * c * HCoeff[k][0] * 3 + c * HCoeff[k][1] * 2 + HCoeff[k][2]) / 3; // 3 !!!! + HP1[k] = (c * c * HCoeff[k][0] * 3 + c * HCoeff[k][1] * 2 + HCoeff[k][2]) / 3; // скорость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!! }; SP1.add(SP0); @@ -1311,8 +1310,7 @@ void CActor::make_Interpolation() case 1: { for (int k = 0; k < 3; k++) - SpeedVector[k] = (factor * factor * SCoeff[k][0] * 3 + factor * SCoeff[k][1] * 2 + SCoeff[k][2]) / - 3; // 3 !!!! + SpeedVector[k] = (factor * factor * SCoeff[k][0] * 3 + factor * SCoeff[k][1] * 2 + SCoeff[k][2]) / 3; // скорость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!! ResPosition.set(IPosS); } @@ -1675,7 +1673,7 @@ void CActor::OnRender_Network() point1S[k] = c * (c * (c * SCoeff[k][0] + SCoeff[k][1]) + SCoeff[k][2]) + SCoeff[k][3]; point1H[k] = c * (c * (c * HCoeff[k][0] + HCoeff[k][1]) + HCoeff[k][2]) + HCoeff[k][3]; - tS[k] = (c * c * SCoeff[k][0] * 3 + c * SCoeff[k][1] * 2 + SCoeff[k][2]) / 3; // 3 !!!! + tS[k] = (c * c * SCoeff[k][0] * 3 + c * SCoeff[k][1] * 2 + SCoeff[k][2]) / 3; // скорость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!! tH[k] = (c * c * HCoeff[k][0] * 3 + c * HCoeff[k][1] * 2 + HCoeff[k][2]); }; @@ -2008,15 +2006,14 @@ void CActor::OnPlayHeadShotParticle(NET_Packet P) P.r_dir(HitDir); HitDir.invert(); P.r_vec3(HitPos); - //----------------------------------- + if (!m_sHeadShotParticle.size()) return; + Fmatrix pos; CParticlesPlayer::MakeXFORM(this, element, HitDir, HitPos, pos); - // particles - CParticlesObject* ps = NULL; - ps = CParticlesObject::Create(m_sHeadShotParticle.c_str(), TRUE); + CParticlesObject* ps = CParticlesObject::Create(m_sHeadShotParticle.c_str(), TRUE); ps->UpdateParent(pos, Fvector().set(0.f, 0.f, 0.f)); GamePersistent().ps_needtoplay.push_back(ps); From f72d9392923f184129c1459c2541660cf0776bd4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 27 Feb 2024 19:06:48 +0500 Subject: [PATCH 215/497] xrGame/Actor_Network.cpp: init encyclopedia registry (#382, #392) --- src/xrGame/Actor_Network.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xrGame/Actor_Network.cpp b/src/xrGame/Actor_Network.cpp index ff4847b64ff..0d5e95cd7a3 100644 --- a/src/xrGame/Actor_Network.cpp +++ b/src/xrGame/Actor_Network.cpp @@ -572,7 +572,8 @@ bool CActor::net_Spawn(CSE_Abstract* DC) m_current_torso.invalidate(); m_current_head.invalidate(); //------------------------------------- - // , + // инициализация реестров, используемых актером + encyclopedia_registry->registry().init(ID()); game_news_registry->registry().init(ID()); if (!CInventoryOwner::net_Spawn(DC)) From ffc3444af5a1a25f2f78992cb01cd929fd85ebdb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 2 Mar 2024 15:26:38 +0500 Subject: [PATCH 216/497] xrSound: removed SoundRender_Cache --- src/xrSound/CMakeLists.txt | 8 - src/xrSound/Sound.h | 2 - src/xrSound/SoundRender.h | 1 - src/xrSound/SoundRender_Cache.cpp | 164 ------------------- src/xrSound/SoundRender_Cache.h | 80 --------- src/xrSound/SoundRender_Core.cpp | 7 - src/xrSound/SoundRender_Core.h | 5 - src/xrSound/SoundRender_Core_Processor.cpp | 4 - src/xrSound/SoundRender_Emitter_streamer.cpp | 29 +--- src/xrSound/SoundRender_Source.cpp | 2 - src/xrSound/SoundRender_Source.h | 5 +- src/xrSound/SoundRender_Source_loader.cpp | 36 +--- src/xrSound/xrSound.vcxproj | 2 - src/xrSound/xrSound.vcxproj.filters | 9 - 14 files changed, 11 insertions(+), 343 deletions(-) delete mode 100644 src/xrSound/SoundRender_Cache.cpp delete mode 100644 src/xrSound/SoundRender_Cache.h diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 2250de18246..88c9732b0bb 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -1,13 +1,5 @@ add_library(xrSound SHARED) -target_sources_grouped( - TARGET xrSound - NAME "Cache" - FILES - SoundRender_Cache.cpp - SoundRender_Cache.h -) - target_sources_grouped( TARGET xrSound NAME "Core" diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 2b1e7ad51ff..2d3fcefddb8 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -189,8 +189,6 @@ class XRSOUND_API CSound_stats public: u32 _rendered; u32 _simulated; - u32 _cache_hits; - u32 _cache_misses; u32 _events; }; diff --git a/src/xrSound/SoundRender.h b/src/xrSound/SoundRender.h index d12f071b392..631027d44b7 100644 --- a/src/xrSound/SoundRender.h +++ b/src/xrSound/SoundRender.h @@ -13,7 +13,6 @@ class SoundEnvironment_LIB; const u32 sdef_target_count = 3; // const u32 sdef_target_block = 400; // ms const u32 sdef_target_size = sdef_target_count * sdef_target_block; // ms -const float s_f_def_source_footer = 0.0f; // sec of silence after buffer data, just for rendering const u32 sdef_env_version = 4; // current version of env-def const u32 sdef_level_version = 1; // current version of level-def const float s_f_def_event_pulse = 0.5f; // sec diff --git a/src/xrSound/SoundRender_Cache.cpp b/src/xrSound/SoundRender_Cache.cpp deleted file mode 100644 index d2609915889..00000000000 --- a/src/xrSound/SoundRender_Cache.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "stdafx.h" - -#include "SoundRender_Cache.h" - -CSoundRender_Cache::CSoundRender_Cache() -{ - data = nullptr; - c_storage = nullptr; - c_begin = nullptr; - c_end = nullptr; - _total = 0; - _line = 0; - _count = 0; -} - -CSoundRender_Cache::~CSoundRender_Cache() {} -void CSoundRender_Cache::move2top(cache_line* line) -{ - VERIFY(line); - if (line == c_begin) - return; // already at top - - // track end - if (line == c_end) - c_end = c_end->prev; - - // cut - cache_line* prev = line->prev; - cache_line* next = line->next; - if (prev) - prev->next = next; - if (next) - next->prev = prev; - - // register at top - line->prev = nullptr; - line->next = c_begin; - - // track begin - c_begin->prev = line; - c_begin = line; - - // internal verify - VERIFY(c_begin->prev == NULL); - VERIFY(c_end->next == NULL); -} - -bool CSoundRender_Cache::request(const cache_cat& cat, u32 id) -{ - // 1. check if cached version available - id %= cat.size; - //. R_ASSERT (idloopback) - { - *c_begin->loopback = CAT_FREE; - c_begin->loopback = nullptr; - } - - // 3. associate - cptr = c_begin->id; - c_begin->loopback = &cptr; - - // 4. fill with data - return true; -} - -void CSoundRender_Cache::initialize(u32 _total_kb_approx, u32 bytes_per_line) -{ - // use twice the requested memory (to avoid bad configs) - _total_kb_approx *= 2; - - // calc - _line = bytes_per_line; - _count = _total_kb_approx * 1024 / bytes_per_line + 1; - _total = _count * _line; - R_ASSERT(_count < CAT_FREE); - Msg("* sound : cache: %d kb, %d lines, %d bpl", _total / 1024, _count, _line); - - // alloc structs - data = xr_alloc(_total); - c_storage = xr_alloc(_count); - - // format - format(); -} - -void CSoundRender_Cache::disconnect() -{ - // disconnect from CATs - for (u32 it = 0; it < _count; it++) - { - cache_line* L = c_storage + it; - if (L->loopback) - { - *L->loopback = CAT_FREE; - L->loopback = nullptr; - } - } -} - -void CSoundRender_Cache::format() -{ - // format structs - for (u32 it = 0; it < _count; it++) - { - cache_line* L = c_storage + it; - L->prev = 0 == it ? nullptr : c_storage + it - 1; - L->next = _count - 1 == it ? nullptr : c_storage + it + 1; - L->data = data + it * _line; - L->loopback = nullptr; - L->id = (u16)it; - } - - // start-end - c_begin = c_storage + 0; - c_end = c_storage + _count - 1; -} - -void CSoundRender_Cache::purge() -{ - disconnect(); // disconnect from CATs - format(); // format -} - -void CSoundRender_Cache::destroy() -{ - disconnect(); - xr_free(data); - xr_free(c_storage); - c_begin = nullptr; - c_end = nullptr; - _total = 0; - _line = 0; - _count = 0; -} - -void CSoundRender_Cache::cat_create(cache_cat& cat, u32 bytes) -{ - cat.size = bytes / _line; - if (bytes % _line) - cat.size += 1; - u32 allocsize = cat.size & 1 ? cat.size + 1 : cat.size; - cat.table = xr_alloc(allocsize); - MemFill32(cat.table, 0xffffffff, allocsize / 2); -} - -void CSoundRender_Cache::cat_destroy(cache_cat& cat) -{ - xr_free(cat.table); - cat.size = 0; -} diff --git a/src/xrSound/SoundRender_Cache.h b/src/xrSound/SoundRender_Cache.h deleted file mode 100644 index 65ef9b49b34..00000000000 --- a/src/xrSound/SoundRender_Cache.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -// --- just thoughts --- -// 1. LRU scheme -// 2. O(1) constant time access -// 3. O(1) constant time LRU-find (deque-like?) -// 4. fixed-count of blocks will allow efficient(cyclic) implementation of deque -// 5. allow FAT-like formatting for sources -// 7. bi-directional cache availability tracking -// 9. "touch" protocol -// 10. in case of cache-hit we have to move line to mark it used -> list - -struct cache_line; -struct cache_ptr; - -////////////////////////////////////////////////////////////////////////// -struct cache_line // internal, LRU queue -{ - cache_line* prev; - cache_line* next; - void* data; // pre-formatted - u16* loopback; // dual-connectivity - u16 id; // need this for dual-connectivity -}; -////////////////////////////////////////////////////////////////////////// -struct cache_cat // cache allocation table -{ - u16* table; // page-table - u32 size; // in pages -}; -constexpr u16 CAT_FREE = 0xffff; -////////////////////////////////////////////////////////////////////////// -class CSoundRender_Cache -{ - u8* data; // just memory - cache_line* c_storage; // just memory - cache_line* c_begin; // >>> - cache_line* c_end; // <<< - u32 _total; // bytes total (heap) - u32 _line; // line size (bytes) - u32 _count; // number of lines - -public: - u32 _stat_hit; - u32 _stat_miss; - -private: - void move2top(cache_line* line); // move one line to TOP-priority - void disconnect(); // disconnect from CATs - void format(); // format structure (like filesystem) - -public: - bool request(const cache_cat& cat, u32 id); // TRUE=need to fill, FALSE=cached info avail - void purge(); // discard all contents of cache - - [[nodiscard]] - void* get_dataptr(const cache_cat& cat, u32 id) const - { - id %= cat.size; - return c_storage[cat.table[id]].data; - } - - [[nodiscard]] - u32 get_linesize() const { return _line; } - - void cat_create(cache_cat& cat, u32 bytes); - void cat_destroy(cache_cat& cat); - - void initialize(u32 _total_kb_approx, u32 bytes_per_line); - void destroy(); - - void stats_clear() - { - _stat_hit = 0; - _stat_miss = 0; - } - - CSoundRender_Cache(); - ~CSoundRender_Cache(); -}; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 6fd1d707e8c..58e628ef427 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -58,10 +58,6 @@ void CSoundRender_Core::_initialize() bPresent = true; - // Cache - cache_bytes_per_line = (sdef_target_block / 8) * 352800 / 1000; - cache.initialize(psSoundCacheSizeMB * 1024, cache_bytes_per_line); - bReady = true; } @@ -70,7 +66,6 @@ extern xr_vector g_target_temp_data; void CSoundRender_Core::_clear() { bReady = false; - cache.destroy(); // remove sources for (auto& kv : s_sources) @@ -109,8 +104,6 @@ int CSoundRender_Core::pause_emitters(bool pauseState) void CSoundRender_Core::_restart() { - cache.destroy(); - cache.initialize(psSoundCacheSizeMB * 1024, cache_bytes_per_line); env_apply(); } diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 53bc3a2a4e9..2b1a06f0ded 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -3,7 +3,6 @@ #include "xrCommon/xr_unordered_map.h" #include "SoundRender.h" -#include "SoundRender_Cache.h" #include "SoundRender_Environment.h" #include "SoundRender_Effects.h" #include "SoundRender_Scene.h" @@ -60,10 +59,6 @@ class CSoundRender_Core : public ISoundManager public: bool supports_float_pcm{}; - // Cache - CSoundRender_Cache cache; - u32 cache_bytes_per_line; - public: CSoundRender_Core(CSoundManager& p); diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 8049639a936..1d2aaee810e 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -139,9 +139,6 @@ void CSoundRender_Core::statistic(CSound_stats* dest, CSound_stats_ext* ext) dest->_simulated += scene->get_emitters().size(); dest->_events += scene->get_prev_events_count(); } - dest->_cache_hits = cache._stat_hit; - dest->_cache_misses = cache._stat_miss; - cache.stats_clear(); } if (ext) { @@ -183,6 +180,5 @@ void CSoundRender_Core::DumpStatistics(IGameFont& font, IPerformanceAlert* alert font.OutNext("Rendered: %d", sndStat._rendered); font.OutNext("Simulated: %d", sndStat._simulated); font.OutNext("Events: %d", sndStat._events); - font.OutNext("Hits/misses: %d/%d", sndStat._cache_hits, sndStat._cache_misses); Stats.FrameStart(); } diff --git a/src/xrSound/SoundRender_Emitter_streamer.cpp b/src/xrSound/SoundRender_Emitter_streamer.cpp index 59f55354898..ab22713f52b 100644 --- a/src/xrSound/SoundRender_Emitter_streamer.cpp +++ b/src/xrSound/SoundRender_Emitter_streamer.cpp @@ -42,34 +42,7 @@ void CSoundRender_Emitter::fill_data(u8* _dest, u32 offset, u32 size) // Msg ("Final: %d - %d",size,size-left); /*/ //* - u32 line_size = SoundRender->cache.get_linesize(); - u32 line = offset / line_size; - - // prepare for first line (it can be unaligned) - u32 line_offs = offset - line * line_size; - u32 line_amount = line_size - line_offs; - - while (size) - { - // cache access - if (SoundRender->cache.request(source()->CAT, line)) - { - source()->decompress(line, target->get_data()); - } - - // fill block - u32 blk_size = std::min(size, line_amount); - u8* ptr = (u8*)SoundRender->cache.get_dataptr(source()->CAT, line); - CopyMemory(_dest, ptr + line_offs, blk_size); - - // advance - line++; - size -= blk_size; - _dest += blk_size; - offset += blk_size; - line_offs = 0; - line_amount = line_size; - } + source()->decompress(_dest, offset, size, target->get_data()); } void CSoundRender_Emitter::fill_block(void* ptr, u32 size) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 712fbd5fea1..b31b20e9d2a 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -11,8 +11,6 @@ CSoundRender_Source::CSoundRender_Source() m_fBaseVolume = 1.f; m_uGameType = 0; fname = nullptr; - CAT.table = nullptr; - CAT.size = 0; } CSoundRender_Source::~CSoundRender_Source() { unload(); } diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index eb6e74554a7..0d37084656f 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -1,7 +1,5 @@ #pragma once -#include "SoundRender_Cache.h" - // refs struct OggVorbis_File; @@ -10,7 +8,6 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source public: shared_str pname; shared_str fname; - cache_cat CAT; float fTimeTotal; u32 dwBytesTotal; @@ -35,7 +32,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source bool load(pcstr name, bool replaceWithNoSound = true, bool crashOnError = true); void unload(); - void decompress(u32 line, OggVorbis_File* ovf); + void decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const; [[nodiscard]] float length_sec() const override { return fTimeTotal; } [[nodiscard]] u32 game_type() const override { return m_uGameType; } diff --git a/src/xrSound/SoundRender_Source_loader.cpp b/src/xrSound/SoundRender_Source_loader.cpp index be993c850e3..e095b6a1144 100644 --- a/src/xrSound/SoundRender_Source_loader.cpp +++ b/src/xrSound/SoundRender_Source_loader.cpp @@ -31,26 +31,21 @@ long ov_tell_func(void* datasource) return static_cast(file->tell()); } -void CSoundRender_Source::decompress(u32 line, OggVorbis_File* ovf) +void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const { VERIFY(ovf); - // decompression of one cache-line - u32 line_size = SoundRender->cache.get_linesize(); - u32 buf_offs = (line * line_size) / (m_wformat.wBitsPerSample / 8) / m_wformat.nChannels; - u32 left_file = dwBytesTotal - buf_offs; - u32 left = (u32)std::min(left_file, line_size); // seek - u32 cur_pos = u32(ov_pcm_tell(ovf)); - if (cur_pos != buf_offs) - ov_pcm_seek(ovf, buf_offs); + const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); + const u32 cur_pos = u32(ov_pcm_tell(ovf)); + if (cur_pos != sample_offset) + ov_pcm_seek(ovf, sample_offset); // decompress - const auto dest = SoundRender->cache.get_dataptr(CAT, line); if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) - i_decompress(ovf, static_cast(dest), left); + i_decompress(ovf, static_cast(dest), size); else - i_decompress(ovf, static_cast(dest), left); + i_decompress(ovf, static_cast(dest), size); } bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) @@ -72,21 +67,10 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) FS.r_close(wave); return false; }); - R_ASSERT3_CURE(ovi->rate == 44100, "Invalid source rate:", pName, !crashOnError, - { - ov_clear(&ovf); - FS.r_close(wave); - return false; - }); - -#ifdef DEBUG - if (ovi->channels == 2) - Msg("stereo sound source [%s]", pName); -#endif ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); - m_wformat.nSamplesPerSec = (ovi->rate); // 44100; + m_wformat.nSamplesPerSec = ovi->rate; m_wformat.nChannels = u16(ovi->channels); if (SoundRender->supports_float_pcm) @@ -105,7 +89,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) s64 pcm_total = ov_pcm_total(&ovf, -1); dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); - fTimeTotal = s_f_def_source_footer + dwBytesTotal / float(m_wformat.nAvgBytesPerSec); + fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); vorbis_comment* ovm = ov_comment(&ovf, -1); if (ovm->comments) @@ -191,7 +175,6 @@ bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, b { if (!LoadWave(fn, crashOnError)) return false; - SoundRender->cache.cat_create(CAT, dwBytesTotal); } return soundExist; @@ -199,7 +182,6 @@ bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, b void CSoundRender_Source::unload() { - SoundRender->cache.cat_destroy(CAT); fTimeTotal = 0.0f; dwBytesTotal = 0; } diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index 2763301039d..bea5752b17a 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -33,7 +33,6 @@ - @@ -54,7 +53,6 @@ - diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index e10f7b3390a..fd4061d8f0c 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -25,9 +25,6 @@ {ea9d1124-af1e-471f-a0a0-d2d77275a8ec} - - {9143e5b9-296c-4d3e-8424-83f75457dfa9} - {cc264c98-2f74-4a25-8885-d8a019b936dd} @@ -72,9 +69,6 @@ Environment - - Cache - Effects @@ -143,9 +137,6 @@ Environment - - Cache - Effects\OpenAL From 4a62bebd55c189445c1c412c6698c806ba601d57 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 2 Mar 2024 22:46:40 +0500 Subject: [PATCH 217/497] xrSound: use default constructors for member variables, cleanup --- src/xrSound/SoundRender_Emitter.cpp | 40 ++++++----------------------- src/xrSound/SoundRender_Emitter.h | 31 ++++++++++------------ src/xrSound/SoundRender_Source.cpp | 1 - src/xrSound/SoundRender_Target.cpp | 31 ---------------------- src/xrSound/SoundRender_Target.h | 25 +++++++++--------- src/xrSound/SoundRender_TargetA.cpp | 14 ++-------- src/xrSound/SoundRender_TargetA.h | 12 ++++----- 7 files changed, 42 insertions(+), 112 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index f805f6c34e8..c0e902e4148 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -35,38 +35,14 @@ void CSoundRender_Emitter::set_time(float t) } CSoundRender_Emitter::CSoundRender_Emitter(CSoundRender_Scene* s) - : scene(s) -{ -#ifdef DEBUG - static u32 incrementalID = 0; - dbg_ID = ++incrementalID; -#endif - target = nullptr; - //source = nullptr; - owner_data = nullptr; - smooth_volume = 1.f; - occluder_volume = 1.f; - fade_volume = 1.f; - occluder[0].set(0, 0, 0); - occluder[1].set(0, 0, 0); - occluder[2].set(0, 0, 0); - m_current_state = stStopped; - set_cursor(0); - bMoved = true; - b2D = false; - bStopping = false; - bRewind = false; - bIgnoringTimeFactor = false; - iPaused = 0; - fTimeStarted = 0.0f; - fTimeToStop = 0.0f; - fTimeToPropagade = 0.0f; - fTimeToRewind = 0.0f; //--#SM+#-- - marker = 0xabababab; - starting_delay = 0.f; - priority_scale = 1.f; - m_cur_handle_cursor = 0; -} + : scene(s), + priority_scale(1.f), + smooth_volume(1.f), + occluder_volume(1.f), + fade_volume(1.f), + m_current_state(stStopped), + bMoved(true), + marker(0xabababab) {} CSoundRender_Emitter::~CSoundRender_Emitter() { diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 35c83ecbbf3..84b55e1c9e3 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -8,8 +8,6 @@ class CSoundRender_Emitter final : public CSound_emitter { - float starting_delay; - public: enum State : u32 { @@ -29,10 +27,6 @@ class CSoundRender_Emitter final : public CSound_emitter }; public: -#ifdef DEBUG - u32 dbg_ID; -#endif - static constexpr float TIME_TO_STOP_INFINITE = static_cast(0xffffffff); CSoundRender_Target* target{}; @@ -47,29 +41,30 @@ class CSoundRender_Emitter final : public CSound_emitter [[nodiscard]] float get_length_sec() const; + float starting_delay{}; float priority_scale; float smooth_volume; float occluder_volume; // USER float fade_volume; - Fvector occluder[3]; + Fvector occluder[3]{}; State m_current_state; - u32 m_stream_cursor; - u32 m_cur_handle_cursor; + u32 m_stream_cursor{}; + u32 m_cur_handle_cursor{}; CSound_params p_source; CSoundRender_Environment e_current; CSoundRender_Environment e_target; - int iPaused; + int iPaused{}; bool bMoved; - bool b2D; - bool bStopping; - bool bRewind; - bool bIgnoringTimeFactor; - float fTimeStarted; // time of "Start" - float fTimeToStop; // time to "Stop" - float fTimeToPropagade; - float fTimeToRewind; // --#SM+#-- + bool b2D{}; + bool bStopping{}; + bool bRewind{}; + bool bIgnoringTimeFactor{}; + float fTimeStarted{}; // time of "Start" + float fTimeToStop{}; // time to "Stop" + float fTimeToPropagade{}; + float fTimeToRewind{}; // --#SM+#-- u32 marker; void i_stop(); diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index b31b20e9d2a..da84046ce8a 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -10,7 +10,6 @@ CSoundRender_Source::CSoundRender_Source() m_fMaxAIDist = 300.f; m_fBaseVolume = 1.f; m_uGameType = 0; - fname = nullptr; } CSoundRender_Source::~CSoundRender_Source() { unload(); } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 10940946f47..6c694b6807b 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -5,39 +5,8 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -CSoundRender_Target::CSoundRender_Target() -{ - m_pEmitter = nullptr; - rendering = false; - wave = nullptr; -} - CSoundRender_Target::~CSoundRender_Target() { VERIFY(wave == 0); } -bool CSoundRender_Target::_initialize() -{ - /* - // Calc format - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 2; //1; - wfx.nSamplesPerSec = SoundRender->wfm.nSamplesPerSec; - wfx.wBitsPerSample = 16; - wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - wfx.cbSize = 0; - */ - /* - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 2; - wfx.wBitsPerSample = 16; - wfx.nBlockAlign = 4; - wfx.nSamplesPerSec = 44100; - wfx.nAvgBytesPerSec = 176400; - wfx.cbSize = 0; - */ - return true; -} - void CSoundRender_Target::start(CSoundRender_Emitter* E) { R_ASSERT(E); diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index e17bb3bb7d2..e321e23d1f6 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -5,15 +5,15 @@ class CSoundRender_Target { protected: - CSoundRender_Emitter* m_pEmitter; - bool rendering; + CSoundRender_Emitter* m_pEmitter{}; + bool rendering{}; public: - float priority; + float priority{}; protected: - OggVorbis_File ovf; - IReader* wave; + OggVorbis_File ovf{}; + IReader* wave{}; void attach(); void detach(); @@ -25,19 +25,20 @@ class CSoundRender_Target return &ovf; } - CSoundRender_Target(); + CSoundRender_Target() = default; virtual ~CSoundRender_Target(); CSoundRender_Emitter* get_emitter() const { return m_pEmitter; } bool get_Rendering() const { return rendering; } + virtual bool _initialize() = 0; virtual void _destroy() = 0; virtual void _restart() = 0; - virtual void start(CSoundRender_Emitter* E) = 0; - virtual void render() = 0; - virtual void rewind() = 0; - virtual void stop() = 0; - virtual void update() = 0; - virtual void fill_parameters() = 0; + virtual void start(CSoundRender_Emitter* E); + virtual void render(); + virtual void rewind(); + virtual void stop(); + virtual void update(); + virtual void fill_parameters(); }; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 7671236634f..01decbcbd5d 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -10,21 +10,11 @@ xr_vector g_target_temp_data; -CSoundRender_TargetA::CSoundRender_TargetA(ALuint slot) : CSoundRender_Target() -{ - cache_gain = 0.f; - cache_pitch = 1.f; - pSource = 0; - pAuxSlot = slot; - buf_block = 0; -} - -CSoundRender_TargetA::~CSoundRender_TargetA() {} +CSoundRender_TargetA::CSoundRender_TargetA(ALuint slot) + : pAuxSlot(slot) {} bool CSoundRender_TargetA::_initialize() { - inherited::_initialize(); - // initialize buffer A_CHK(alGenBuffers(sdef_target_count, pBuffers)); alGenSources(1, &pSource); const ALenum error = alGetError(); diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 4e2182577c9..44d48b1fdbd 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -8,18 +8,18 @@ class CSoundRender_TargetA : public CSoundRender_Target using inherited = CSoundRender_Target; // OpenAL - ALuint pSource; - ALuint pBuffers[sdef_target_count]; + ALuint pSource{}; + ALuint pBuffers[sdef_target_count]{}; ALuint pAuxSlot; // EFX - float cache_gain; - float cache_pitch; - ALuint buf_block; + float cache_gain{}; + float cache_pitch{ 1.0f }; + + ALuint buf_block{}; void fill_block(ALuint BufferID); public: CSoundRender_TargetA(ALuint slot); - virtual ~CSoundRender_TargetA(); bool _initialize() override; void _destroy() override; From 2bcee4adf085fad5abb4120ce44d7742b8f0901f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 2 Mar 2024 23:18:47 +0500 Subject: [PATCH 218/497] xrSound: removed SoundRender_Emitter_streamer.cpp and SoundRender_Source_loader.cpp --- src/xrSound/CMakeLists.txt | 2 - src/xrSound/SoundRender_Emitter.cpp | 100 +++++++++- src/xrSound/SoundRender_Emitter.h | 2 +- src/xrSound/SoundRender_Emitter_streamer.cpp | 135 ------------- src/xrSound/SoundRender_Source.cpp | 189 +++++++++++++++++++ src/xrSound/SoundRender_Source.h | 2 +- src/xrSound/SoundRender_Source_loader.cpp | 187 ------------------ src/xrSound/xrSound.vcxproj | 2 - src/xrSound/xrSound.vcxproj.filters | 6 - 9 files changed, 289 insertions(+), 336 deletions(-) delete mode 100644 src/xrSound/SoundRender_Emitter_streamer.cpp delete mode 100644 src/xrSound/SoundRender_Source_loader.cpp diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index 88c9732b0bb..e37cdfca483 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -46,7 +46,6 @@ target_sources_grouped( SoundRender_Emitter.h SoundRender_Emitter_FSM.cpp SoundRender_Emitter_StartStop.cpp - SoundRender_Emitter_streamer.cpp ) target_sources_grouped( @@ -83,7 +82,6 @@ target_sources_grouped( FILES SoundRender_Source.cpp SoundRender_Source.h - SoundRender_Source_loader.cpp ) target_sources_grouped( diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index c0e902e4148..66ba1b29c44 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -110,7 +110,6 @@ u32 CSoundRender_Emitter::play_time() return 0; } -#include "SoundRender_Source.h" // XXX: remove maybe void CSoundRender_Emitter::set_cursor(u32 p) { m_stream_cursor = p; @@ -140,4 +139,101 @@ u32 CSoundRender_Emitter::get_cursor(bool b_absolute) const return m_stream_cursor - m_cur_handle_cursor; } -void CSoundRender_Emitter::move_cursor(int offset) { set_cursor(get_cursor(true) + offset); } +void CSoundRender_Emitter::move_cursor(int offset) +{ + set_cursor(get_cursor(true) + offset); +} + +void CSoundRender_Emitter::fill_data(u8* _dest, u32 offset, u32 size) const +{ + source()->decompress(_dest, offset, size, target->get_data()); +} + +void CSoundRender_Emitter::fill_block(void* ptr, u32 size) +{ + // Msg ("stream: %10s - [%X]:%d, p=%d, t=%d",*source->fname,ptr,size,position,source->dwBytesTotal); + u8* dest = (u8*)(ptr); + const u32 dwBytesTotal = get_bytes_total(); + + if ((get_cursor(true) + size) > dwBytesTotal) + { + // We are reaching the end of data, what to do? + switch (m_current_state) + { + case stPlaying: + { // Fill as much data as we can, zeroing remainder + if (get_cursor(true) >= dwBytesTotal) + { + // ??? We requested the block after remainder - just zero + memset(dest, 0, size); + } + else + { + // Calculate remainder + const u32 sz_data = dwBytesTotal - get_cursor(true); + const u32 sz_zero = (get_cursor(true) + size) - dwBytesTotal; + VERIFY(size == (sz_data + sz_zero)); + fill_data(dest, get_cursor(false), sz_data); + memset(dest + sz_data, 0, sz_zero); + } + move_cursor(size); + } + break; + case stPlayingLooped: + { + u32 hw_position = 0; + do + { + u32 sz_data = dwBytesTotal - get_cursor(true); + const u32 sz_write = std::min(size - hw_position, sz_data); + fill_data(dest + hw_position, get_cursor(true), sz_write); + hw_position += sz_write; + move_cursor(sz_write); + set_cursor(get_cursor(true) % dwBytesTotal); + } while (0 != (size - hw_position)); + } + break; + default: FATAL("SOUND: Invalid emitter state"); break; + } + } + else + { + const u32 bt_handle = ((CSoundRender_Source*)owner_data->handle)->dwBytesTotal; + if (get_cursor(true) + size > m_cur_handle_cursor + bt_handle) + { + R_ASSERT(owner_data->fn_attached[0].size()); + + u32 rem = 0; + if ((m_cur_handle_cursor + bt_handle) > get_cursor(true)) + { + rem = (m_cur_handle_cursor + bt_handle) - get_cursor(true); + +#ifdef DEBUG + Msg("reminder from prev source %d", rem); +#endif // #ifdef DEBUG + fill_data(dest, get_cursor(false), rem); + move_cursor(rem); + } +#ifdef DEBUG + Msg("recurce from next source %d", size - rem); +#endif // #ifdef DEBUG + fill_block(dest + rem, size - rem); + } + else + { + // Everything OK, just stream + fill_data(dest, get_cursor(false), size); + move_cursor(size); + } + } +} + +u32 CSoundRender_Emitter::get_bytes_total() const +{ + return owner_data->dwBytesTotal; +} + +float CSoundRender_Emitter::get_length_sec() const +{ + return owner_data->fTimeTotal; +} diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 84b55e1c9e3..df226f28517 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -103,7 +103,7 @@ class CSoundRender_Emitter final : public CSound_emitter void set_time(float t) override; //--#SM+#-- const CSound_params* get_params() override { return &p_source; } void fill_block(void* ptr, u32 size); - void fill_data(u8* ptr, u32 offset, u32 size); + void fill_data(u8* ptr, u32 offset, u32 size) const; float priority() const; void start(const ref_sound& _owner, u32 flags, float delay); diff --git a/src/xrSound/SoundRender_Emitter_streamer.cpp b/src/xrSound/SoundRender_Emitter_streamer.cpp deleted file mode 100644 index ab22713f52b..00000000000 --- a/src/xrSound/SoundRender_Emitter_streamer.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "SoundRender_Core.h" -#include "SoundRender_Source.h" -#include "SoundRender_Emitter.h" -#include "SoundRender_Target.h" - -void CSoundRender_Emitter::fill_data(u8* _dest, u32 offset, u32 size) -{ - /* - Msg ("stream: %10s - %d",*source->fname,size); - CopyMemory (_dest,&source->m_buffer.front()+offset,size); - return; - //*/ - /* - memset (_dest,0,size); // debug only - // Msg ("stream: %10s - %d",*source->fname,size); - int dummy; - ov_pcm_seek (source->ovf,(psSoundFreq==sf_22K)?offset:offset/2); - // ov_pcm_seek (source->ovf,0); - char* dest = (char*)_dest; - u32 left = size; - while (left) - { - int ret = ov_read(source->ovf,dest,left,0,2,1,&dummy); - // Msg ("Part: %d - %d",left,ret); - if (ret==0){ - ret=0; - break; - }if (ret>0){ - left -= ret; - dest += ret; - }else{ - switch (ret){ - case OV_HOLE: Msg("OV_HOLE"); continue; break; - case OV_EBADLINK: Msg("OV_EBADLINK"); continue; break; - } - break; - } - } - // Msg ("Final: %d - %d",size,size-left); - /*/ - //* - source()->decompress(_dest, offset, size, target->get_data()); -} - -void CSoundRender_Emitter::fill_block(void* ptr, u32 size) -{ - // Msg ("stream: %10s - [%X]:%d, p=%d, t=%d",*source->fname,ptr,size,position,source->dwBytesTotal); - u8* dest = (u8*)(ptr); - u32 dwBytesTotal = get_bytes_total(); - - if ((get_cursor(true) + size) > dwBytesTotal) - { - // We are reaching the end of data, what to do? - switch (m_current_state) - { - case stPlaying: - { // Fill as much data as we can, zeroing remainder - if (get_cursor(true) >= dwBytesTotal) - { - // ??? We requested the block after remainder - just zero - memset(dest, 0, size); - } - else - { - // Calculate remainder - u32 sz_data = dwBytesTotal - get_cursor(true); - u32 sz_zero = (get_cursor(true) + size) - dwBytesTotal; - VERIFY(size == (sz_data + sz_zero)); - fill_data(dest, get_cursor(false), sz_data); - memset(dest + sz_data, 0, sz_zero); - } - move_cursor(size); - } - break; - case stPlayingLooped: - { - u32 hw_position = 0; - do - { - u32 sz_data = dwBytesTotal - get_cursor(true); - u32 sz_write = std::min(size - hw_position, sz_data); - fill_data(dest + hw_position, get_cursor(true), sz_write); - hw_position += sz_write; - move_cursor(sz_write); - set_cursor(get_cursor(true) % dwBytesTotal); - } while (0 != (size - hw_position)); - } - break; - default: FATAL("SOUND: Invalid emitter state"); break; - } - } - else - { - u32 bt_handle = ((CSoundRender_Source*)owner_data->handle)->dwBytesTotal; - if (get_cursor(true) + size > m_cur_handle_cursor + bt_handle) - { - R_ASSERT(owner_data->fn_attached[0].size()); - - u32 rem = 0; - if ((m_cur_handle_cursor + bt_handle) > get_cursor(true)) - { - rem = (m_cur_handle_cursor + bt_handle) - get_cursor(true); - -#ifdef DEBUG - Msg("reminder from prev source %d", rem); -#endif // #ifdef DEBUG - fill_data(dest, get_cursor(false), rem); - move_cursor(rem); - } -#ifdef DEBUG - Msg("recurce from next source %d", size - rem); -#endif // #ifdef DEBUG - fill_block(dest + rem, size - rem); - } - else - { - // Everything OK, just stream - fill_data(dest, get_cursor(false), size); - move_cursor(size); - } - } -} - -u32 CSoundRender_Emitter::get_bytes_total() const -{ - return owner_data->dwBytesTotal; -} - -float CSoundRender_Emitter::get_length_sec() const -{ - return owner_data->fTimeTotal; -} diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index da84046ce8a..5de71b2835c 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -49,6 +49,23 @@ bool ov_can_continue_read(long res) } } +void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const +{ + VERIFY(ovf); + + // seek + const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); + const u32 cur_pos = u32(ov_pcm_tell(ovf)); + if (cur_pos != sample_offset) + ov_pcm_seek(ovf, sample_offset); + + // decompress + if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + i_decompress(ovf, static_cast(dest), size); + else + i_decompress(ovf, static_cast(dest), size); +} + void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, char* _dest, u32 size) const { long TotalRet = 0; @@ -84,3 +101,175 @@ void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, float* _dest, u32 si left -= samples; } } + +//SEEK_SET 0 File beginning +//SEEK_CUR 1 Current file pointer position +//SEEK_END 2 End-of-file +int ov_seek_func(void* datasource, ogg_int64_t offset, int whence) +{ + switch (whence) + { + case SEEK_SET: ((IReader*)datasource)->seek((int)offset); break; + case SEEK_CUR: ((IReader*)datasource)->advance((int)offset); break; + case SEEK_END: ((IReader*)datasource)->seek((int)offset + ((IReader*)datasource)->length()); break; + } + return 0; +} + +size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource) +{ + auto* file = static_cast(datasource); + const size_t exist_block = _max(0ul, iFloor(file->elapsed() / (float)size)); + const size_t read_block = std::min(exist_block, nmemb); + file->r(ptr, read_block * size); + return read_block; +} + +int ov_close_func(void* datasource) +{ + return 0; +} + +long ov_tell_func(void* datasource) +{ + const auto file = static_cast(datasource); + return static_cast(file->tell()); +} + +bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) +{ + pname = pName; + + // Load file into memory and parse WAV-format + OggVorbis_File ovf; + ov_callbacks ovc = {ov_read_func, ov_seek_func, ov_close_func, ov_tell_func}; + IReader* wave = FS.r_open(pname.c_str()); + R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); + ov_open_callbacks(wave, &ovf, nullptr, 0, ovc); + + vorbis_info* ovi = ov_info(&ovf, -1); + // verify + R_ASSERT3_CURE(ovi, "Invalid source info:", pName, !crashOnError, + { + ov_clear(&ovf); + FS.r_close(wave); + return false; + }); + + ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); + + m_wformat.nSamplesPerSec = ovi->rate; + m_wformat.nChannels = u16(ovi->channels); + + if (SoundRender->supports_float_pcm) + { + m_wformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + m_wformat.wBitsPerSample = 32; + } + else + { + m_wformat.wFormatTag = WAVE_FORMAT_PCM; + m_wformat.wBitsPerSample = 16; + } + + m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; + m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; + + s64 pcm_total = ov_pcm_total(&ovf, -1); + dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); + fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); + + vorbis_comment* ovm = ov_comment(&ovf, -1); + if (ovm->comments) + { + IReader F(ovm->user_comments[0], ovm->comment_lengths[0]); + u32 vers = F.r_u32(); + if (vers == 0x0001) + { + m_fMinDist = F.r_float(); + m_fMaxDist = F.r_float(); + m_fBaseVolume = 1.f; + m_uGameType = F.r_u32(); + m_fMaxAIDist = m_fMaxDist; + } + else if (vers == 0x0002) + { + m_fMinDist = F.r_float(); + m_fMaxDist = F.r_float(); + m_fBaseVolume = F.r_float(); + m_uGameType = F.r_u32(); + m_fMaxAIDist = m_fMaxDist; + } + else if (vers == OGG_COMMENT_VERSION) + { + m_fMinDist = F.r_float(); + m_fMaxDist = F.r_float(); + m_fBaseVolume = F.r_float(); + m_uGameType = F.r_u32(); + m_fMaxAIDist = F.r_float(); + } + else + { +#ifndef MASTER_GOLD + Log("! Invalid ogg-comment version, file: ", pName); +#endif + } + } + else + { +#ifndef MASTER_GOLD + Log("! Missing ogg-comment, file: ", pName); +#endif + } + + R_ASSERT3_CURE(m_fMaxAIDist >= 0.1f && m_fMaxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, + { + ov_clear(&ovf); + FS.r_close(wave); + return false; + }); + + ov_clear(&ovf); + FS.r_close(wave); + return true; +} + +bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, bool crashOnError /*= true*/) +{ + string_path fn, N; + xr_strcpy(N, name); +#ifdef XR_PLATFORM_WINDOWS + xr_strlwr(N); +#endif + + if (strext(N)) + *strext(N) = 0; + + fname = N; + + strconcat(sizeof(fn), fn, N, ".ogg"); + if (!FS.exist("$level$", fn)) + FS.update_path(fn, "$game_sounds$", fn); + + bool soundExist = FS.exist(fn); + if (!soundExist && replaceWithNoSound) + { + Msg("! Can't find sound '%s'", name); + FS.update_path(fn, "$game_sounds$", "$no_sound.ogg"); + soundExist = FS.exist(fn); + } + + if (soundExist) + { + if (!LoadWave(fn, crashOnError)) + return false; + } + + return soundExist; +} + +void CSoundRender_Source::unload() +{ + fTimeTotal = 0.0f; + dwBytesTotal = 0; +} diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 0d37084656f..16f60811e76 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -12,7 +12,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source float fTimeTotal; u32 dwBytesTotal; - WAVEFORMATEX m_wformat; //= SoundRender->wfm; + WAVEFORMATEX m_wformat; float m_fBaseVolume; float m_fMinDist; diff --git a/src/xrSound/SoundRender_Source_loader.cpp b/src/xrSound/SoundRender_Source_loader.cpp deleted file mode 100644 index e095b6a1144..00000000000 --- a/src/xrSound/SoundRender_Source_loader.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include "stdafx.h" - -#include "SoundRender_Core.h" -#include "SoundRender_Source.h" - -//SEEK_SET 0 File beginning -//SEEK_CUR 1 Current file pointer position -//SEEK_END 2 End-of-file -int ov_seek_func(void* datasource, ogg_int64_t offset, int whence) -{ - switch (whence) - { - case SEEK_SET: ((IReader*)datasource)->seek((int)offset); break; - case SEEK_CUR: ((IReader*)datasource)->advance((int)offset); break; - case SEEK_END: ((IReader*)datasource)->seek((int)offset + ((IReader*)datasource)->length()); break; - } - return 0; -} -size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource) -{ - IReader* F = (IReader*)datasource; - size_t exist_block = _max(0ul, iFloor(F->elapsed() / (float)size)); - size_t read_block = std::min(exist_block, nmemb); - F->r(ptr, read_block * size); - return read_block; -} -int ov_close_func(void* datasource) { return 0; } -long ov_tell_func(void* datasource) -{ - const auto file = static_cast(datasource); - return static_cast(file->tell()); -} - -void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const -{ - VERIFY(ovf); - - // seek - const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); - const u32 cur_pos = u32(ov_pcm_tell(ovf)); - if (cur_pos != sample_offset) - ov_pcm_seek(ovf, sample_offset); - - // decompress - if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) - i_decompress(ovf, static_cast(dest), size); - else - i_decompress(ovf, static_cast(dest), size); -} - -bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) -{ - pname = pName; - - // Load file into memory and parse WAV-format - OggVorbis_File ovf; - ov_callbacks ovc = {ov_read_func, ov_seek_func, ov_close_func, ov_tell_func}; - IReader* wave = FS.r_open(pname.c_str()); - R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); - ov_open_callbacks(wave, &ovf, nullptr, 0, ovc); - - vorbis_info* ovi = ov_info(&ovf, -1); - // verify - R_ASSERT3_CURE(ovi, "Invalid source info:", pName, !crashOnError, - { - ov_clear(&ovf); - FS.r_close(wave); - return false; - }); - - ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); - - m_wformat.nSamplesPerSec = ovi->rate; - m_wformat.nChannels = u16(ovi->channels); - - if (SoundRender->supports_float_pcm) - { - m_wformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - m_wformat.wBitsPerSample = 32; - } - else - { - m_wformat.wFormatTag = WAVE_FORMAT_PCM; - m_wformat.wBitsPerSample = 16; - } - - m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; - m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; - - s64 pcm_total = ov_pcm_total(&ovf, -1); - dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); - fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); - - vorbis_comment* ovm = ov_comment(&ovf, -1); - if (ovm->comments) - { - IReader F(ovm->user_comments[0], ovm->comment_lengths[0]); - u32 vers = F.r_u32(); - if (vers == 0x0001) - { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = 1.f; - m_uGameType = F.r_u32(); - m_fMaxAIDist = m_fMaxDist; - } - else if (vers == 0x0002) - { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = F.r_float(); - m_uGameType = F.r_u32(); - m_fMaxAIDist = m_fMaxDist; - } - else if (vers == OGG_COMMENT_VERSION) - { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = F.r_float(); - m_uGameType = F.r_u32(); - m_fMaxAIDist = F.r_float(); - } - else - { -#ifndef MASTER_GOLD - Log("! Invalid ogg-comment version, file: ", pName); -#endif - } - } - else - { -#ifndef MASTER_GOLD - Log("! Missing ogg-comment, file: ", pName); -#endif - } - - R_ASSERT3_CURE(m_fMaxAIDist >= 0.1f && m_fMaxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, - { - ov_clear(&ovf); - FS.r_close(wave); - return false; - }); - - ov_clear(&ovf); - FS.r_close(wave); - return true; -} - -bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, bool crashOnError /*= true*/) -{ - string_path fn, N; - xr_strcpy(N, name); -#ifdef XR_PLATFORM_WINDOWS - xr_strlwr(N); -#endif - - if (strext(N)) - *strext(N) = 0; - - fname = N; - - strconcat(sizeof(fn), fn, N, ".ogg"); - if (!FS.exist("$level$", fn)) - FS.update_path(fn, "$game_sounds$", fn); - - bool soundExist = FS.exist(fn); - if (!soundExist && replaceWithNoSound) - { - Msg("! Can't find sound '%s'", name); - FS.update_path(fn, "$game_sounds$", "$no_sound.ogg"); - soundExist = FS.exist(fn); - } - - if (soundExist) - { - if (!LoadWave(fn, crashOnError)) - return false; - } - - return soundExist; -} - -void CSoundRender_Source::unload() -{ - fTimeTotal = 0.0f; - dwBytesTotal = 0; -} diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index bea5752b17a..8e5163e104c 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -63,11 +63,9 @@ - - diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index fd4061d8f0c..e81e30def6d 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -119,15 +119,9 @@ Emitter - - Emitter - Source - - Source - Target From cefb1e99a3b5deebcaf54da009002284e948e663 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 2 Mar 2024 23:47:52 +0500 Subject: [PATCH 219/497] xrSound: move source file management to CSoundRender_Source --- .../SoundRender_Core_SourceManager.cpp | 1 + src/xrSound/SoundRender_Emitter.cpp | 8 +- src/xrSound/SoundRender_Emitter.h | 2 +- src/xrSound/SoundRender_Source.cpp | 120 ++++++++++-------- src/xrSound/SoundRender_Source.h | 16 ++- src/xrSound/SoundRender_Target.cpp | 31 +---- src/xrSound/SoundRender_Target.h | 15 +-- src/xrSound/SoundRender_TargetA.cpp | 5 - src/xrSound/SoundRender_TargetA.h | 1 - src/xrSound/stdafx.h | 3 - 10 files changed, 87 insertions(+), 115 deletions(-) diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index cd61ad26713..9f721a73769 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -60,6 +60,7 @@ CSoundRender_Source* CSoundRender_Core::i_create_source(pcstr name, bool replace void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) { // No actual destroy at all + S->detach(); } void CSoundRender_Core::i_create_all_sources() diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 66ba1b29c44..b69c38224f0 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -4,7 +4,6 @@ #include "SoundRender_Core.h" #include "SoundRender_Scene.h" #include "SoundRender_Source.h" -#include "SoundRender_TargetA.h" extern u32 psSoundModel; extern float psSoundVEffects; @@ -124,9 +123,6 @@ void CSoundRender_Emitter::set_cursor(u32 p) owner_data->fn_attached[0] = owner_data->fn_attached[1]; owner_data->fn_attached[1] = ""; m_cur_handle_cursor = get_cursor(true); - - if (target) - ((CSoundRender_TargetA*)target)->source_changed(); } } } @@ -144,9 +140,9 @@ void CSoundRender_Emitter::move_cursor(int offset) set_cursor(get_cursor(true) + offset); } -void CSoundRender_Emitter::fill_data(u8* _dest, u32 offset, u32 size) const +void CSoundRender_Emitter::fill_data(void* dest, u32 offset, u32 size) const { - source()->decompress(_dest, offset, size, target->get_data()); + source()->decompress(dest, offset, size); } void CSoundRender_Emitter::fill_block(void* ptr, u32 size) diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index df226f28517..7c91fa3f35f 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -103,7 +103,7 @@ class CSoundRender_Emitter final : public CSound_emitter void set_time(float t) override; //--#SM+#-- const CSound_params* get_params() override { return &p_source; } void fill_block(void* ptr, u32 size); - void fill_data(u8* ptr, u32 offset, u32 size) const; + void fill_data(void* dest, u32 offset, u32 size) const; float priority() const; void start(const ref_sound& _owner, u32 flags, float delay); diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 5de71b2835c..5b86708a177 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -49,44 +49,45 @@ bool ov_can_continue_read(long res) } } -void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const +void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) { - VERIFY(ovf); + if (!wave) + attach(); // seek const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); - const u32 cur_pos = u32(ov_pcm_tell(ovf)); + const u32 cur_pos = u32(ov_pcm_tell(&ovf)); if (cur_pos != sample_offset) - ov_pcm_seek(ovf, sample_offset); + ov_pcm_seek(&ovf, sample_offset); // decompress if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) - i_decompress(ovf, static_cast(dest), size); + i_decompress(static_cast(dest), size); else - i_decompress(ovf, static_cast(dest), size); + i_decompress(static_cast(dest), size); } -void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, char* _dest, u32 size) const +void CSoundRender_Source::i_decompress(char* _dest, u32 size) { long TotalRet = 0; // Read loop while (TotalRet < static_cast(size)) { - const auto ret = ov_read(ovf, _dest + TotalRet, size - TotalRet, 0, 2, 1, nullptr); + const auto ret = ov_read(&ovf, _dest + TotalRet, size - TotalRet, 0, 2, 1, nullptr); if (ret <= 0 && !ov_can_continue_read(ret)) break; TotalRet += ret; } } -void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, float* _dest, u32 size) const +void CSoundRender_Source::i_decompress(float* _dest, u32 size) { s32 left = s32(size / m_wformat.nBlockAlign); while (left) { float** pcm; - long samples = ov_read_float(ovf, &pcm, left, nullptr); + long samples = ov_read_float(&ovf, &pcm, left, nullptr); if (samples <= 0 && !ov_can_continue_read(samples)) break; @@ -102,57 +103,75 @@ void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, float* _dest, u32 si } } -//SEEK_SET 0 File beginning -//SEEK_CUR 1 Current file pointer position -//SEEK_END 2 End-of-file -int ov_seek_func(void* datasource, ogg_int64_t offset, int whence) +constexpr ov_callbacks g_ov_callbacks = { - switch (whence) + // read + [](void* ptr, size_t size, size_t nmemb, void* datasource) -> size_t { - case SEEK_SET: ((IReader*)datasource)->seek((int)offset); break; - case SEEK_CUR: ((IReader*)datasource)->advance((int)offset); break; - case SEEK_END: ((IReader*)datasource)->seek((int)offset + ((IReader*)datasource)->length()); break; - } - return 0; -} - -size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource) -{ - auto* file = static_cast(datasource); - const size_t exist_block = _max(0ul, iFloor(file->elapsed() / (float)size)); - const size_t read_block = std::min(exist_block, nmemb); - file->r(ptr, read_block * size); - return read_block; -} + auto* file = static_cast(datasource); + const size_t exist_block = _max(0ul, iFloor(file->elapsed() / (float)size)); + const size_t read_block = std::min(exist_block, nmemb); + file->r(ptr, read_block * size); + return read_block; + }, + // seek + [](void* datasource, ogg_int64_t offset, int whence) -> int + { + //SEEK_SET 0 File beginning + //SEEK_CUR 1 Current file pointer position + //SEEK_END 2 End-of-file + switch (whence) + { + case SEEK_SET: ((IReader*)datasource)->seek((int)offset); break; + case SEEK_CUR: ((IReader*)datasource)->advance((int)offset); break; + case SEEK_END: ((IReader*)datasource)->seek((int)offset + ((IReader*)datasource)->length()); break; + } + return 0; + }, + // close + [](void* /*datasource*/) -> int + { + return 0; + }, + // tell + [](void* datasource) -> long + { + const auto file = static_cast(datasource); + return static_cast(file->tell()); + }, +}; -int ov_close_func(void* datasource) +void CSoundRender_Source::attach() { - return 0; + VERIFY(0 == wave); + if (wave) + return; + wave = FS.r_open(pname.c_str()); + R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); + ov_open_callbacks(wave, &ovf, nullptr, 0, g_ov_callbacks); } -long ov_tell_func(void* datasource) +void CSoundRender_Source::detach() { - const auto file = static_cast(datasource); - return static_cast(file->tell()); + if (wave) + { + ov_clear(&ovf); + FS.r_close(wave); + } } bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) { pname = pName; - // Load file into memory and parse WAV-format - OggVorbis_File ovf; - ov_callbacks ovc = {ov_read_func, ov_seek_func, ov_close_func, ov_tell_func}; - IReader* wave = FS.r_open(pname.c_str()); - R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); - ov_open_callbacks(wave, &ovf, nullptr, 0, ovc); + attach(); + + const vorbis_info* ovi = ov_info(&ovf, -1); - vorbis_info* ovi = ov_info(&ovf, -1); // verify R_ASSERT3_CURE(ovi, "Invalid source info:", pName, !crashOnError, { - ov_clear(&ovf); - FS.r_close(wave); + detach(); return false; }); @@ -175,15 +194,15 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; - s64 pcm_total = ov_pcm_total(&ovf, -1); + const s64 pcm_total = ov_pcm_total(&ovf, -1); dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); - vorbis_comment* ovm = ov_comment(&ovf, -1); + const vorbis_comment* ovm = ov_comment(&ovf, -1); if (ovm->comments) { IReader F(ovm->user_comments[0], ovm->comment_lengths[0]); - u32 vers = F.r_u32(); + const u32 vers = F.r_u32(); if (vers == 0x0001) { m_fMinDist = F.r_float(); @@ -224,13 +243,11 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) R_ASSERT3_CURE(m_fMaxAIDist >= 0.1f && m_fMaxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, { - ov_clear(&ovf); - FS.r_close(wave); + detach(); return false; }); - ov_clear(&ovf); - FS.r_close(wave); + detach(); return true; } @@ -272,4 +289,5 @@ void CSoundRender_Source::unload() { fTimeTotal = 0.0f; dwBytesTotal = 0; + detach(); } diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 16f60811e76..8400c034875 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -1,7 +1,6 @@ #pragma once -// refs -struct OggVorbis_File; +#include class XRSOUND_API CSoundRender_Source final : public CSound_source { @@ -9,6 +8,9 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source shared_str pname; shared_str fname; + OggVorbis_File ovf{}; + IReader* wave{}; + float fTimeTotal; u32 dwBytesTotal; @@ -21,8 +23,8 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source u32 m_uGameType; private: - void i_decompress(OggVorbis_File* ovf, char* dest, u32 size) const; - void i_decompress(OggVorbis_File* ovf, float* dest, u32 size) const; + void i_decompress(char* dest, u32 size); + void i_decompress(float* dest, u32 size); bool LoadWave(pcstr name, bool crashOnError); @@ -32,7 +34,11 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source bool load(pcstr name, bool replaceWithNoSound = true, bool crashOnError = true); void unload(); - void decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const; + + void attach(); + void detach(); + + void decompress(void* dest, u32 byte_offset, u32 size); [[nodiscard]] float length_sec() const override { return fTimeTotal; } [[nodiscard]] u32 game_type() const override { return m_uGameType; } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 6c694b6807b..9c16e8e67b7 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -5,8 +5,6 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -CSoundRender_Target::~CSoundRender_Target() { VERIFY(wave == 0); } - void CSoundRender_Target::start(CSoundRender_Emitter* E) { R_ASSERT(E); @@ -17,13 +15,13 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) // 5. Deferred-play-signal (emitter-exist, rendering-false) m_pEmitter = E; rendering = false; - //attach(); + //m_pEmitter->source()->attach(); } void CSoundRender_Target::render() { rendering = true; } void CSoundRender_Target::stop() { - detach(); + m_pEmitter->source()->detach(); m_pEmitter = nullptr; rendering = false; } @@ -36,28 +34,3 @@ void CSoundRender_Target::fill_parameters() //if (pEmitter->b2D) // pEmitter->set_position(SoundRender->listener_position()); } - -extern int ov_seek_func(void* datasource, ogg_int64_t offset, int whence); -extern size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource); -extern int ov_close_func(void* datasource); -extern long ov_tell_func(void* datasource); - -void CSoundRender_Target::attach() -{ - VERIFY(0 == wave); - VERIFY(m_pEmitter); - ov_callbacks ovc = {ov_read_func, ov_seek_func, ov_close_func, ov_tell_func}; - wave = FS.r_open(m_pEmitter->source()->pname.c_str()); - R_ASSERT3(wave && wave->length(), "Can't open wave file:", m_pEmitter->source()->pname.c_str()); - ov_open_callbacks(wave, &ovf, nullptr, 0, ovc); - VERIFY(0 != wave); -} - -void CSoundRender_Target::detach() -{ - if (wave) - { - ov_clear(&ovf); - FS.r_close(wave); - } -} diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index e321e23d1f6..04405f27919 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -11,22 +11,9 @@ class CSoundRender_Target public: float priority{}; -protected: - OggVorbis_File ovf{}; - IReader* wave{}; - void attach(); - void detach(); - public: - OggVorbis_File* get_data() - { - if (!wave) - attach(); - return &ovf; - } - CSoundRender_Target() = default; - virtual ~CSoundRender_Target(); + virtual ~CSoundRender_Target() = default; CSoundRender_Emitter* get_emitter() const { return m_pEmitter; } bool get_Rendering() const { return rendering; } diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 01decbcbd5d..bb4b70c8e4c 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -212,8 +212,3 @@ void CSoundRender_TargetA::fill_block(ALuint BufferID) A_CHK(alBufferData( BufferID, format, &g_target_temp_data.front(), buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); } -void CSoundRender_TargetA::source_changed() -{ - detach(); - attach(); -} diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 44d48b1fdbd..dae3652a329 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -31,5 +31,4 @@ class CSoundRender_TargetA : public CSoundRender_Target void stop() override; void update() override; void fill_parameters() override; - void source_changed(); }; diff --git a/src/xrSound/stdafx.h b/src/xrSound/stdafx.h index b8e0fde3f02..52b1529fc67 100644 --- a/src/xrSound/stdafx.h +++ b/src/xrSound/stdafx.h @@ -9,9 +9,6 @@ #include "Sound.h" -#include -#include - #if defined(XR_PLATFORM_WINDOWS) // mmreg.h #define NOMMIDS From 5a15bf6c0b72257cd36a924fba9fd1fe6a7736ac Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 2 Mar 2024 15:34:39 +0500 Subject: [PATCH 220/497] xrSound/SoundRender_TargetA.h/cpp: split sound buffer submission from filling it with data Use member variable instead of global g_target_temp_data. Prefill buffer with the new data immediately after submitting it. --- src/xrSound/SoundRender_Core.cpp | 4 --- src/xrSound/SoundRender_Target.cpp | 11 +++++++ src/xrSound/SoundRender_Target.h | 4 +++ src/xrSound/SoundRender_TargetA.cpp | 50 +++++++++++++++++------------ src/xrSound/SoundRender_TargetA.h | 5 ++- 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 58e628ef427..1ac75dbfb1d 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -61,8 +61,6 @@ void CSoundRender_Core::_initialize() bReady = true; } -extern xr_vector g_target_temp_data; - void CSoundRender_Core::_clear() { bReady = false; @@ -73,8 +71,6 @@ void CSoundRender_Core::_clear() xr_delete(kv.second); } s_sources.clear(); - - g_target_temp_data.clear(); } ISoundScene* CSoundRender_Core::create_scene() diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 9c16e8e67b7..2905be42067 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -16,6 +16,11 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) m_pEmitter = E; rendering = false; //m_pEmitter->source()->attach(); + + // Calc storage + buf_block = sdef_target_block * E->source()->m_wformat.nAvgBytesPerSec / 1000; + for (auto& buf : temp_buf) + buf.resize(buf_block); } void CSoundRender_Target::render() { rendering = true; } @@ -34,3 +39,9 @@ void CSoundRender_Target::fill_parameters() //if (pEmitter->b2D) // pEmitter->set_position(SoundRender->listener_position()); } + +void CSoundRender_Target::fill_block(size_t idx) +{ + R_ASSERT(m_pEmitter); + m_pEmitter->fill_block(temp_buf[idx].data(), buf_block); +} diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index 04405f27919..8ff3c9a84ef 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -8,6 +8,10 @@ class CSoundRender_Target CSoundRender_Emitter* m_pEmitter{}; bool rendering{}; + u32 buf_block{}; + xr_vector temp_buf[sdef_target_count]; + void fill_block(size_t idx); + public: float priority{}; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index bb4b70c8e4c..80671913527 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -8,8 +8,6 @@ # include #endif -xr_vector g_target_temp_data; - CSoundRender_TargetA::CSoundRender_TargetA(ALuint slot) : pAuxSlot(slot) {} @@ -49,24 +47,21 @@ void CSoundRender_TargetA::_restart() _initialize(); } -void CSoundRender_TargetA::start(CSoundRender_Emitter* E) -{ - inherited::start(E); - - // Calc storage - buf_block = sdef_target_block * E->source()->m_wformat.nAvgBytesPerSec / 1000; - g_target_temp_data.resize(buf_block); -} - void CSoundRender_TargetA::render() { - for (const ALuint pBuffer : pBuffers) - fill_block(pBuffer); + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(i); + + for (size_t i = 0; i < sdef_target_count; ++i) + submit_buffer(pBuffers[i], temp_buf[i].data()); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); inherited::render(); + + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(i); // prefill } void CSoundRender_TargetA::stop() @@ -86,10 +81,18 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourceStop(pSource)); A_CHK(alSourcei(pSource, AL_BUFFER, 0)); - for (const ALuint pBuffer : pBuffers) - fill_block(pBuffer); + + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(i); + + for (size_t i = 0; i < sdef_target_count; ++i) + submit_buffer(pBuffers[i], temp_buf[i].data()); + A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); + + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(i); // prefill } void CSoundRender_TargetA::update() @@ -112,7 +115,9 @@ void CSoundRender_TargetA::update() { ALuint BufferID; A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); - fill_block(BufferID); + const auto id = get_block_id(BufferID); + submit_buffer(BufferID, temp_buf[id].data()); + fill_block(id); A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; if ((error = alGetError()) != AL_NO_ERROR) @@ -192,11 +197,15 @@ void CSoundRender_TargetA::fill_parameters() VERIFY2(m_pEmitter, SE->source()->file_name()); } -void CSoundRender_TargetA::fill_block(ALuint BufferID) +size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const { - R_ASSERT(m_pEmitter); + const auto it = std::find(std::begin(pBuffers), std::end(pBuffers), BufferID); + return it - std::begin(pBuffers); +} - m_pEmitter->fill_block(&g_target_temp_data.front(), buf_block); +void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data) const +{ + R_ASSERT(m_pEmitter); const auto& wvf = m_pEmitter->source()->m_wformat; const bool mono = wvf.nChannels == 1; @@ -209,6 +218,5 @@ void CSoundRender_TargetA::fill_block(ALuint BufferID) format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; } - A_CHK(alBufferData( - BufferID, format, &g_target_temp_data.front(), buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); + A_CHK(alBufferData(BufferID, format, data, buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); } diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index dae3652a329..17785412b39 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -15,8 +15,8 @@ class CSoundRender_TargetA : public CSoundRender_Target float cache_gain{}; float cache_pitch{ 1.0f }; - ALuint buf_block{}; - void fill_block(ALuint BufferID); + size_t get_block_id(ALuint BufferID) const; + void submit_buffer(ALuint BufferID, const void* data) const; public: CSoundRender_TargetA(ALuint slot); @@ -25,7 +25,6 @@ class CSoundRender_TargetA : public CSoundRender_Target void _destroy() override; void _restart() override; - void start(CSoundRender_Emitter* E) override; void render() override; void rewind() override; void stop() override; From 6653ca5dfb0d15d4a9568ceb5528941171f7ec41 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Mar 2024 04:07:05 +0500 Subject: [PATCH 221/497] xrSound: prefill sound buffers in parallel --- src/xrSound/SoundRender_Source.cpp | 2 ++ src/xrSound/SoundRender_Source.h | 3 +++ src/xrSound/SoundRender_Target.cpp | 12 ++++++++++++ src/xrSound/SoundRender_Target.h | 7 ++++++- src/xrSound/SoundRender_TargetA.cpp | 13 ++++++++++--- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 5b86708a177..de9752ff927 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -51,6 +51,8 @@ bool ov_can_continue_read(long res) void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) { + std::lock_guard guard{ read_lock }; + if (!wave) attach(); diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 8400c034875..1dee82b32ea 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -1,5 +1,7 @@ #pragma once +#include + #include class XRSOUND_API CSoundRender_Source final : public CSound_source @@ -10,6 +12,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source OggVorbis_File ovf{}; IReader* wave{}; + std::mutex read_lock; float fTimeTotal; u32 dwBytesTotal; diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 2905be42067..b70cfc9d186 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -5,6 +5,11 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" +CSoundRender_Target::CSoundRender_Target() +{ + buffers_to_prefill.reserve(sdef_target_count); +} + void CSoundRender_Target::start(CSoundRender_Emitter* E) { R_ASSERT(E); @@ -45,3 +50,10 @@ void CSoundRender_Target::fill_block(size_t idx) R_ASSERT(m_pEmitter); m_pEmitter->fill_block(temp_buf[idx].data(), buf_block); } + +void CSoundRender_Target::prefill_block(Task&, void*) +{ + for (const size_t idx : buffers_to_prefill) + fill_block(idx); + buffers_to_prefill.clear(); +} diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index 8ff3c9a84ef..ec32893a0a5 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -2,6 +2,8 @@ #include "SoundRender.h" +class Task; + class CSoundRender_Target { protected: @@ -12,11 +14,14 @@ class CSoundRender_Target xr_vector temp_buf[sdef_target_count]; void fill_block(size_t idx); + xr_vector buffers_to_prefill; + void prefill_block(Task&, void*); + public: float priority{}; public: - CSoundRender_Target() = default; + CSoundRender_Target(); virtual ~CSoundRender_Target() = default; CSoundRender_Emitter* get_emitter() const { return m_pEmitter; } diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 80671913527..9670d7fdc73 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -4,6 +4,8 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" +#include "xrCore/Threading/TaskManager.hpp" + #if __has_include() # include #endif @@ -61,7 +63,8 @@ void CSoundRender_TargetA::render() inherited::render(); for (size_t i = 0; i < sdef_target_count; ++i) - fill_block(i); // prefill + buffers_to_prefill.emplace_back(i); // prefill + TaskScheduler->AddTask("CSoundRender_TargetA::render() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); } void CSoundRender_TargetA::stop() @@ -92,7 +95,8 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourcePlay(pSource)); for (size_t i = 0; i < sdef_target_count; ++i) - fill_block(i); // prefill + buffers_to_prefill.emplace_back(i); // prefill + TaskScheduler->AddTask("CSoundRender_TargetA::rewind() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); } void CSoundRender_TargetA::update() @@ -117,7 +121,7 @@ void CSoundRender_TargetA::update() A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); const auto id = get_block_id(BufferID); submit_buffer(BufferID, temp_buf[id].data()); - fill_block(id); + buffers_to_prefill.emplace_back(id); A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; if ((error = alGetError()) != AL_NO_ERROR) @@ -127,6 +131,9 @@ void CSoundRender_TargetA::update() } } + if (!buffers_to_prefill.empty()) + TaskScheduler->AddTask("CSoundRender_TargetA::update() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); + /* Make sure the source hasn't underrun */ if (state != AL_PLAYING && state != AL_PAUSED) { From b3d6775287c8c93e84a647ea15126632a4f4b05a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 23 Feb 2024 08:48:38 +0500 Subject: [PATCH 222/497] Submit level bounding volume to xrSound when setting occlusion --- src/xrCore/_fbox.h | 15 +++++++++++++++ src/xrEngine/IGame_Level.cpp | 2 +- src/xrSound/Sound.h | 4 +++- src/xrSound/SoundRender_Scene.cpp | 8 ++++++-- src/xrSound/SoundRender_Scene.h | 2 +- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/xrCore/_fbox.h b/src/xrCore/_fbox.h index efb0934fa13..f432a1f0414 100644 --- a/src/xrCore/_fbox.h +++ b/src/xrCore/_fbox.h @@ -225,6 +225,21 @@ struct Fbox3 return xform(b, m); } + Fmatrix get_xform() const + { + Fvector center, extent; + center.add(vMin, vMax).div(2.0f); + extent.sub(vMax, vMin).div(2.0f); + + Fmatrix transformMatrix; + transformMatrix.identity(); + + transformMatrix.translate(center); + transformMatrix.scale(extent); + + return transformMatrix; + } + void getsize(Fvector3& R) const { R.sub(vMax, vMin); } void getradius(Fvector3& R) const diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index e3ca7426fca..93b1c27d6db 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -112,7 +112,7 @@ bool IGame_Level::Load(u32 dwNum) g_pGamePersistent->SpatialSpace.initialize(ObjectSpace.GetBoundingVolume()); g_pGamePersistent->SpatialSpacePhysic.initialize(ObjectSpace.GetBoundingVolume()); - Sound->set_geometry_occ(ObjectSpace.GetStaticModel()); + Sound->set_geometry_occ(ObjectSpace.GetStaticModel(), ObjectSpace.GetBoundingVolume()); Sound->set_handler([](const ref_sound& S, float range) { if (g_pGameLevel && S && S->feedback) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 2d3fcefddb8..ea7239d7e24 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -37,6 +37,8 @@ class IReader; template struct _vector2; using Fvector2 = _vector2; +struct Fbox3; +using Fbox = Fbox3; XRSOUND_API extern u32 psSoundModel; XRSOUND_API extern float psSoundVEffects; @@ -221,7 +223,7 @@ class XRSOUND_API XR_NOVTABLE ISoundScene virtual void set_handler(sound_event* E) = 0; virtual void set_geometry_env(IReader* I) = 0; virtual void set_geometry_som(IReader* I) = 0; - virtual void set_geometry_occ(CDB::MODEL* M) = 0; + virtual void set_geometry_occ(CDB::MODEL* M, const Fbox& aabb) = 0; virtual void set_user_env(CSound_environment* E) = 0; virtual void set_environment(u32 id, CSound_environment** dst_env) = 0; diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 50392e35aec..434cce7ec0a 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -12,7 +12,7 @@ CSoundRender_Scene::~CSoundRender_Scene() { stop_emitters(); - set_geometry_occ(nullptr); + set_geometry_occ(nullptr, {}); set_geometry_som(nullptr); set_geometry_env(nullptr); @@ -44,7 +44,11 @@ int CSoundRender_Scene::pause_emitters(bool pauseState) void CSoundRender_Scene::set_handler(sound_event* E) { sound_event_handler = E; } -void CSoundRender_Scene::set_geometry_occ(CDB::MODEL* M) { geom_MODEL = M; } +void CSoundRender_Scene::set_geometry_occ(CDB::MODEL* M, const Fbox& /*aabb*/) +{ + xr_delete(M); + geom_MODEL = M; +} void CSoundRender_Scene::set_geometry_som(IReader* I) { diff --git a/src/xrSound/SoundRender_Scene.h b/src/xrSound/SoundRender_Scene.h index 16bced6d71e..6a6be9cc04b 100644 --- a/src/xrSound/SoundRender_Scene.h +++ b/src/xrSound/SoundRender_Scene.h @@ -16,7 +16,7 @@ class CSoundRender_Scene final : public ISoundScene void set_geometry_env(IReader* I) override; void set_geometry_som(IReader* I) override; - void set_geometry_occ(CDB::MODEL* M) override; + void set_geometry_occ(CDB::MODEL* M, const Fbox& aabb) override; void set_user_env(CSound_environment* E) override; void set_environment(u32 id, CSound_environment** dst_env) override; From c2257244b927847045fba9cbbbcfc5abaf7954f5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Mar 2024 12:21:21 +0500 Subject: [PATCH 223/497] xrMaterialSystem/GameMtlLib.h: set enum underlying type to u32 This fixes warning about 1 << 31 can't be represented by int --- src/xrMaterialSystem/GameMtlLib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 16eac3d9010..9868c2ebc40 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -56,7 +56,7 @@ struct MTL_EXPORT_API SGameMtl protected: int ID; // auto number public: - enum + enum : u32 { flBreakable = (1ul << 0ul), // flShootable = (1ul<<1ul), From c6fd6a583f824aa168185f185487893449d014b3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Mar 2024 12:33:44 +0500 Subject: [PATCH 224/497] xrMaterialSystem/GameMtlLib.h: constify --- src/xrMaterialSystem/GameMtlLib.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 9868c2ebc40..55742ceab58 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -122,7 +122,7 @@ struct MTL_EXPORT_API SGameMtl } void Load(IReader& fs); void Save(IWriter& fs); - int GetID() { return ID; } + int GetID() const { return ID; } #ifdef _EDITOR void FillProp(PropItemVec& values, ListItem* owner); #endif @@ -246,7 +246,7 @@ class MTL_EXPORT_API CGameMtlLibrary auto pred = [&](const SGameMtl* mtl) { return !xr_strcmpi(mtl->m_Name.c_str(), name); }; return std::find_if(materials.begin(), materials.end(), pred); } - GameMtlIt GetMaterialIt(shared_str& name) + GameMtlIt GetMaterialIt(const shared_str& name) { auto pred = [&](const SGameMtl* mtl) { return mtl->m_Name.equal(name); }; return std::find_if(materials.begin(), materials.end(), pred); @@ -258,38 +258,40 @@ class MTL_EXPORT_API CGameMtlLibrary } u32 GetMaterialID(pcstr name) { - auto it = GetMaterialIt(name); + const auto it = GetMaterialIt(name); return it == materials.end() ? GAMEMTL_NONE_ID : (*it)->ID; } SGameMtl* GetMaterial(pcstr name) { - auto it = GetMaterialIt(name); - return materials.end() != it ? *it : 0; + const auto it = GetMaterialIt(name); + return materials.end() != it ? *it : nullptr; } SGameMtl* GetMaterialByID(s32 id) { - auto it = GetMaterialItByID(id); + const auto it = GetMaterialItByID(id); return it != materials.end() ? *it : nullptr; } u16 GetMaterialIdx(int ID) { - auto it = GetMaterialItByID(ID); + const auto it = GetMaterialItByID(ID); VERIFY(materials.end() != it); return u16(it - materials.begin()); } u16 GetMaterialIdx(pcstr name) { - auto it = GetMaterialIt(name); + const auto it = GetMaterialIt(name); VERIFY(materials.end() != it); return u16(it - materials.begin()); } - SGameMtl* GetMaterialByIdx(u16 idx) + SGameMtl* GetMaterialByIdx(u16 idx) const { VERIFY(idx < (u16)materials.size()); return materials[idx]; } + GameMtlIt FirstMaterial() { return materials.begin(); } GameMtlIt LastMaterial() { return materials.end(); } + u32 CountMaterial() const { return materials.size(); } #ifdef _EDITOR @@ -317,13 +319,14 @@ class MTL_EXPORT_API CGameMtlLibrary // game SGameMtlPair* GetMaterialPairByIndices(u16 i0, u16 i1) const { - u32 mtlCount = materials.size(); + const u32 mtlCount = materials.size(); R_ASSERT(i0 < mtlCount && i1 < mtlCount); return material_pairs_rt[i1 * mtlCount + i0]; } GameMtlPairIt FirstMaterialPair() { return material_pairs.begin(); } GameMtlPairIt LastMaterialPair() { return material_pairs.end(); } + // IO routines void Load(); bool Save(); From 56f9fad1d014ec9e365a64f5a1fb7d4c34c28b48 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Mar 2024 12:37:42 +0500 Subject: [PATCH 225/497] xrMaterialSystem/GameMtlLib.h: replace macros with constexpr constants --- src/xrMaterialSystem/GameMtlLib.h | 60 +++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 55742ceab58..1e26912bd26 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -14,36 +14,36 @@ #define MTL_EXPORT_API XR_IMPORT #endif -#define GAMEMTL_CURRENT_VERSION 0x0001 - -#define GAMEMTLS_CHUNK_VERSION 0x1000 -#define GAMEMTLS_CHUNK_AUTOINC 0x1001 -#define GAMEMTLS_CHUNK_MTLS 0x1002 -#define GAMEMTLS_CHUNK_MTLS_PAIR 0x1003 - -#define GAMEMTL_CHUNK_MAIN 0x1000 -#define GAMEMTL_CHUNK_FLAGS 0x1001 -#define GAMEMTL_CHUNK_PHYSICS 0x1002 -#define GAMEMTL_CHUNK_FACTORS 0x1003 -#define GAMEMTL_CHUNK_FLOTATION 0x1004 -#define GAMEMTL_CHUNK_DESC 0x1005 -#define GAMEMTL_CHUNK_INJURIOUS 0x1006 -#define GAMEMTL_CHUNK_DENSITY 0x1007 -#define GAMEMTL_CHUNK_FACTORS_MP 0x1008 - -#define GAMEMTLPAIR_CHUNK_PAIR 0x1000 -//#define GAMEMTLPAIR_CHUNK_FLOTATION 0x1001 - obsolete -#define GAMEMTLPAIR_CHUNK_BREAKING 0x1002 -#define GAMEMTLPAIR_CHUNK_STEP 0x1003 -//#define GAMEMTLPAIR_CHUNK_COLLIDE 0x1004 - obsolete / rename HIT -#define GAMEMTLPAIR_CHUNK_COLLIDE 0x1005 - -#define GAMEMTL_SUBITEM_COUNT 4 - -#define GAMEMTL_NONE_ID u32(-1) -#define GAMEMTL_NONE_IDX u16(-1) - -constexpr pcstr GAMEMTL_FILENAME = "gamemtl.xr"; +constexpr u16 GAMEMTL_CURRENT_VERSION = 0x0001; + +constexpr u32 GAMEMTLS_CHUNK_VERSION = 0x1000; +constexpr u32 GAMEMTLS_CHUNK_AUTOINC = 0x1001; +constexpr u32 GAMEMTLS_CHUNK_MTLS = 0x1002; +constexpr u32 GAMEMTLS_CHUNK_MTLS_PAIR = 0x1003; + +constexpr u32 GAMEMTL_CHUNK_MAIN = 0x1000; +constexpr u32 GAMEMTL_CHUNK_FLAGS = 0x1001; +constexpr u32 GAMEMTL_CHUNK_PHYSICS = 0x1002; +constexpr u32 GAMEMTL_CHUNK_FACTORS = 0x1003; +constexpr u32 GAMEMTL_CHUNK_FLOTATION = 0x1004; +constexpr u32 GAMEMTL_CHUNK_DESC = 0x1005; +constexpr u32 GAMEMTL_CHUNK_INJURIOUS = 0x1006; +constexpr u32 GAMEMTL_CHUNK_DENSITY = 0x1007; +constexpr u32 GAMEMTL_CHUNK_FACTORS_MP = 0x1008; + +constexpr u32 GAMEMTLPAIR_CHUNK_PAIR = 0x1000; +//constexpr u32 GAMEMTLPAIR_CHUNK_FLOTATION = 0x1001; // obsolete +constexpr u32 GAMEMTLPAIR_CHUNK_BREAKING = 0x1002; +constexpr u32 GAMEMTLPAIR_CHUNK_STEP = 0x1003; +//constexpr u32 GAMEMTLPAIR_CHUNK_COLLIDE = 0x1004; // obsolete / rename HIT +constexpr u32 GAMEMTLPAIR_CHUNK_COLLIDE = 0x1005; + +constexpr int GAMEMTL_SUBITEM_COUNT = 4; + +constexpr u32 GAMEMTL_NONE_ID = u32(-1); +constexpr u32 GAMEMTL_NONE_IDX = u16(-1); + +constexpr pcstr GAMEMTL_FILENAME = "gamemtl.xr"; // fwd. decl. class IReader; From 0cd8994736ad17d450adbc91329d6e44036d072f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 3 Mar 2024 18:51:29 +0500 Subject: [PATCH 226/497] Move string hash function to xrCore Add operator""_hash --- src/xrCore/_std_extensions.h | 11 +++++++++++ src/xrUICore/XML/UIXmlInitBase.cpp | 29 ++++++++++------------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/xrCore/_std_extensions.h b/src/xrCore/_std_extensions.h index 89010b7129c..ad45b3d1543 100644 --- a/src/xrCore/_std_extensions.h +++ b/src/xrCore/_std_extensions.h @@ -229,6 +229,17 @@ inline void MemFill32(void* dst, u32 value, size_t dstSize) *ptr++ = value; } +// source: https://stackoverflow.com/a/46711735 +constexpr u32 strhash(const std::string_view data) noexcept +{ + uint32_t hash = 5385; + for (const auto& e : data) + hash = ((hash << 5) + hash) + e; + return hash; +} + +constexpr u32 operator""_hash(char const* p, size_t size) { return strhash({ p, size }); } + XRCORE_API char* timestamp(string64& dest); extern XRCORE_API u32 crc32(const void* P, u32 len); diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 34879efafdc..371d56845fe 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -1032,35 +1032,26 @@ void CUIXmlInitBase::ApplyAlign(float& x, float& y, u32 align) ////////////////////////////////////////////////////////////////////////// -// source: https://stackoverflow.com/questions/650162/why-cant-the-switch-statement-be-applied-to-strings -constexpr uint32_t hash(const std::string_view data) noexcept -{ - uint32_t hash = 5385; - for (const auto& e : data) - hash = ((hash << 5) + hash) + e; - return hash; -} - bool CUIXmlInitBase::InitAlignment(const CUIXml& xml_doc, const char* path, int index, float& x, float& y, CUIWindow* pWnd) { // Alignment: top: "t", right: "r", bottom: "b", left: "l", center: "c" const xr_string wnd_alignment = xml_doc.ReadAttrib(path, index, "alignment", ""); - switch (hash(wnd_alignment.c_str())) + switch (strhash(wnd_alignment)) { - case hash("r"): + case "r"_hash: pWnd->SetAlignment(waRight); break; - case hash("l"): + case "l"_hash: pWnd->SetAlignment(waLeft); break; - case hash("t"): + case "t"_hash: pWnd->SetAlignment(waTop); break; - case hash("b"): + case "b"_hash: pWnd->SetAlignment(waBottom); break; - case hash("c"): + case "c"_hash: pWnd->SetAlignment(waCenter); break; default: @@ -1072,17 +1063,17 @@ bool CUIXmlInitBase::InitAlignment(const CUIXml& xml_doc, const char* path, int bool result = false; - switch (hash(alignStr)) + switch (strhash(alignStr)) { - case hash("r"): + case "r"_hash: x = ApplyAlignX(x, alRight); result = true; break; - case hash("b"): + case "b"_hash: y = ApplyAlignY(y, alBottom); result = true; break; - case hash("c"): + case "c"_hash: ApplyAlign(x, y, alCenter); result = true; break; From 9e2abad3b720463318b20496ef8d9735c0024520 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Mar 2024 12:38:26 +0500 Subject: [PATCH 227/497] Fix crash during level load (fixes #1625) --- src/xrSound/SoundRender_Scene.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 434cce7ec0a..ee08ce00485 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -46,7 +46,6 @@ void CSoundRender_Scene::set_handler(sound_event* E) { sound_event_handler = E; void CSoundRender_Scene::set_geometry_occ(CDB::MODEL* M, const Fbox& /*aabb*/) { - xr_delete(M); geom_MODEL = M; } From 04a805a5b49e0257e37440101b4406a1ab0a70e9 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 4 Mar 2024 13:45:47 +0500 Subject: [PATCH 228/497] Fix compilation --- src/xrCore/_std_extensions.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xrCore/_std_extensions.h b/src/xrCore/_std_extensions.h index ad45b3d1543..12db63e71c8 100644 --- a/src/xrCore/_std_extensions.h +++ b/src/xrCore/_std_extensions.h @@ -5,6 +5,9 @@ #include #include #include + +#include + #include "xrCommon/math_funcs_inline.h" //#include "xr_token.h" From 6a6b92dc72fca4e59b1af1d92af4518bb93102d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:26:10 +0000 Subject: [PATCH 229/497] build(deps): bump Externals/sse2neon from `4a036e6` to `1c258c4` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `4a036e6` to `1c258c4`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/4a036e60472af7dd60a31421fa01557000b5c96b...1c258c41de900d94b09c5d45a15bcc8f0216332d) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 4a036e60472..1c258c41de9 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 4a036e60472af7dd60a31421fa01557000b5c96b +Subproject commit 1c258c41de900d94b09c5d45a15bcc8f0216332d From 602168dbcfb62be0d581860faee72bb20a3c3433 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:26:12 +0000 Subject: [PATCH 230/497] build(deps): bump Externals/zlib from `5c42a23` to `4a5e3e7` Bumps [Externals/zlib](https://github.com/madler/zlib) from `5c42a23` to `4a5e3e7`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/5c42a230b7b468dff011f444161c0145b5efae59...4a5e3e7d255f3f8eba9ecdb8bd8080db43bf0aeb) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 5c42a230b7b..4a5e3e7d255 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 5c42a230b7b468dff011f444161c0145b5efae59 +Subproject commit 4a5e3e7d255f3f8eba9ecdb8bd8080db43bf0aeb From 16d67cad25e901920fb8f3d604e57737fcd1ce80 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 01:52:48 +0500 Subject: [PATCH 231/497] xrSound: sanitize sounds preloading (#1627) --- src/xrSound/SoundRender_Target.cpp | 43 +++++++++++++++++++++++++++-- src/xrSound/SoundRender_Target.h | 9 +++++- src/xrSound/SoundRender_TargetA.cpp | 41 +++++++++++++-------------- src/xrSound/SoundRender_TargetA.h | 1 + 4 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index b70cfc9d186..7bad7c7a674 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -4,6 +4,7 @@ #include "SoundRender_Core.h" #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" +#include "xrCore/Threading/TaskManager.hpp" CSoundRender_Target::CSoundRender_Target() { @@ -28,7 +29,12 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) buf.resize(buf_block); } -void CSoundRender_Target::render() { rendering = true; } +void CSoundRender_Target::render() +{ + VERIFY(!rendering); + rendering = true; +} + void CSoundRender_Target::stop() { m_pEmitter->source()->detach(); @@ -51,9 +57,42 @@ void CSoundRender_Target::fill_block(size_t idx) m_pEmitter->fill_block(temp_buf[idx].data(), buf_block); } -void CSoundRender_Target::prefill_block(Task&, void*) +void CSoundRender_Target::fill_all_blocks() +{ + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(i); +} + +void CSoundRender_Target::prefill_blocks(Task&, void*) { for (const size_t idx : buffers_to_prefill) fill_block(idx); buffers_to_prefill.clear(); + prefill_task.store(nullptr, std::memory_order_release); +} + +void CSoundRender_Target::prefill_all_blocks(Task&, void*) +{ + fill_all_blocks(); + prefill_task.store(nullptr, std::memory_order_release); +} + +void CSoundRender_Target::wait_prefill() const +{ + if (const auto task = prefill_task.load(std::memory_order_relaxed)) + TaskScheduler->Wait(*task); +} + +void CSoundRender_Target::dispatch_prefill() +{ + wait_prefill(); + const auto task = &TaskScheduler->AddTask("CSoundRender_Target::dispatch_prefill()", { this, &CSoundRender_Target::prefill_blocks }); + prefill_task.store(task, std::memory_order_release); +} + +void CSoundRender_Target::dispatch_prefill_all() +{ + wait_prefill(); + const auto task = &TaskScheduler->AddTask("CSoundRender_Target::dispatch_prefill_all()", { this, &CSoundRender_Target::prefill_all_blocks }); + prefill_task.store(task, std::memory_order_release); } diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index ec32893a0a5..f9de2ce554e 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -13,9 +13,16 @@ class CSoundRender_Target u32 buf_block{}; xr_vector temp_buf[sdef_target_count]; void fill_block(size_t idx); + void fill_all_blocks(); xr_vector buffers_to_prefill; - void prefill_block(Task&, void*); + void prefill_blocks(Task&, void*); + void prefill_all_blocks(Task&, void*); + + std::atomic prefill_task{}; + void wait_prefill() const; + void dispatch_prefill(); + void dispatch_prefill_all(); public: float priority{}; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 9670d7fdc73..25d6efbec00 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -4,8 +4,6 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -#include "xrCore/Threading/TaskManager.hpp" - #if __has_include() # include #endif @@ -37,6 +35,7 @@ bool CSoundRender_TargetA::_initialize() void CSoundRender_TargetA::_destroy() { + wait_prefill(); // clean up target if (alIsSource(pSource)) alDeleteSources(1, &pSource); @@ -51,20 +50,15 @@ void CSoundRender_TargetA::_restart() void CSoundRender_TargetA::render() { - for (size_t i = 0; i < sdef_target_count; ++i) - fill_block(i); - - for (size_t i = 0; i < sdef_target_count; ++i) - submit_buffer(pBuffers[i], temp_buf[i].data()); + fill_all_blocks(); + submit_all_buffers(); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); inherited::render(); - for (size_t i = 0; i < sdef_target_count; ++i) - buffers_to_prefill.emplace_back(i); // prefill - TaskScheduler->AddTask("CSoundRender_TargetA::render() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); + dispatch_prefill_all(); } void CSoundRender_TargetA::stop() @@ -75,6 +69,7 @@ void CSoundRender_TargetA::stop() A_CHK(alSourcei(pSource, AL_BUFFER, 0)); A_CHK(alSourcei(pSource, AL_SOURCE_RELATIVE, TRUE)); } + wait_prefill(); inherited::stop(); } @@ -85,18 +80,14 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourceStop(pSource)); A_CHK(alSourcei(pSource, AL_BUFFER, 0)); - for (size_t i = 0; i < sdef_target_count; ++i) - fill_block(i); - - for (size_t i = 0; i < sdef_target_count; ++i) - submit_buffer(pBuffers[i], temp_buf[i].data()); + wait_prefill(); + fill_all_blocks(); + submit_all_buffers(); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); - for (size_t i = 0; i < sdef_target_count; ++i) - buffers_to_prefill.emplace_back(i); // prefill - TaskScheduler->AddTask("CSoundRender_TargetA::rewind() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); + dispatch_prefill_all(); } void CSoundRender_TargetA::update() @@ -115,13 +106,16 @@ void CSoundRender_TargetA::update() return; } + wait_prefill(); + while (processed > 0) { ALuint BufferID; A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); + const auto id = get_block_id(BufferID); submit_buffer(BufferID, temp_buf[id].data()); - buffers_to_prefill.emplace_back(id); + A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; if ((error = alGetError()) != AL_NO_ERROR) @@ -129,10 +123,11 @@ void CSoundRender_TargetA::update() Msg("! %s:: buffering data failed (0x%d)", __FUNCTION__, error); return; } + buffers_to_prefill.emplace_back(id); } if (!buffers_to_prefill.empty()) - TaskScheduler->AddTask("CSoundRender_TargetA::update() - prefill_block", { this, &CSoundRender_TargetA::prefill_block }); + dispatch_prefill(); /* Make sure the source hasn't underrun */ if (state != AL_PLAYING && state != AL_PAUSED) @@ -227,3 +222,9 @@ void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data) cons A_CHK(alBufferData(BufferID, format, data, buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); } + +void CSoundRender_TargetA::submit_all_buffers() const +{ + for (size_t i = 0; i < sdef_target_count; ++i) + submit_buffer(pBuffers[i], temp_buf[i].data()); +} diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 17785412b39..12bf5d81f27 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -17,6 +17,7 @@ class CSoundRender_TargetA : public CSoundRender_Target size_t get_block_id(ALuint BufferID) const; void submit_buffer(ALuint BufferID, const void* data) const; + void submit_all_buffers() const; public: CSoundRender_TargetA(ALuint slot); From 78ad33ec42a9770825d42ffd9dc9ba51d32dc8ef Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 01:54:52 +0500 Subject: [PATCH 232/497] xrSound: increase prefill sound buffers count to 5 Reduces the chance of sound stall, reduces the chance of waiting for sound to load --- src/xrSound/SoundRender.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrSound/SoundRender.h b/src/xrSound/SoundRender.h index 631027d44b7..9c8f86aec43 100644 --- a/src/xrSound/SoundRender.h +++ b/src/xrSound/SoundRender.h @@ -10,7 +10,7 @@ class CSoundRender_Target; class CSoundRender_Environment; class SoundEnvironment_LIB; -const u32 sdef_target_count = 3; // +const u32 sdef_target_count = 5; // const u32 sdef_target_block = 400; // ms const u32 sdef_target_size = sdef_target_count * sdef_target_block; // ms const u32 sdef_env_version = 4; // current version of env-def From 958757e2c8b6737159803ec35f0cfcca3150e075 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 04:27:23 +0500 Subject: [PATCH 233/497] Fix crash when switching sound to simulating state while there's prefill task active (fixes #1627) --- src/xrSound/SoundRender_Emitter_FSM.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 6f1c2c3304a..0be0220ab9a 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -107,16 +107,16 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (fTime >= fTimeToStop) { // STOP - m_current_state = stStopped; SoundRender->i_stop(this); + m_current_state = stStopped; } else { if (!update_culling(dt)) { // switch to: SIMULATE - m_current_state = stSimulating; // switch state SoundRender->i_stop(this); + m_current_state = stSimulating; } else { From c06415ef28637aa2b8d38e695f72f0cfd7c6c306 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 04:29:09 +0500 Subject: [PATCH 234/497] Fix possible bug when rewinding sound --- src/xrSound/SoundRender_Emitter_FSM.cpp | 11 +++++++++++ src/xrSound/SoundRender_Emitter_StartStop.cpp | 8 -------- src/xrSound/SoundRender_Target.cpp | 19 +++++++++++++++++-- src/xrSound/SoundRender_Target.h | 6 ++++-- src/xrSound/SoundRender_TargetA.cpp | 6 +----- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 0be0220ab9a..24434bada57 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -4,6 +4,7 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Core.h" #include "SoundRender_Source.h" +#include "SoundRender_Target.h" XRSOUND_API extern float psSoundCull; @@ -27,6 +28,16 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (bRewind) { + if (target) + target->wait_prefill(); + + const float time = bIgnoringTimeFactor ? SoundRender->TimerPersistent.GetElapsed_sec() : SoundRender->Timer.GetElapsed_sec(); + const float diff = time - fTimeStarted; + fTimeStarted += diff; + fTimeToStop += diff; + fTimeToPropagade = time; + + set_cursor(0); if (target) SoundRender->i_rewind(this); bRewind = FALSE; diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index f61ed499831..ecb184bdb5e 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -62,14 +62,6 @@ void CSoundRender_Emitter::stop(bool isDeffered) void CSoundRender_Emitter::rewind() { bStopping = FALSE; - - const float fTime = bIgnoringTimeFactor ? SoundRender->TimerPersistent.GetElapsed_sec() : SoundRender->Timer.GetElapsed_sec(); - float fDiff = fTime - fTimeStarted; - fTimeStarted += fDiff; - fTimeToStop += fDiff; - fTimeToPropagade = fTime; - - set_cursor(0); bRewind = TRUE; } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 7bad7c7a674..0eb009fc070 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -11,6 +11,11 @@ CSoundRender_Target::CSoundRender_Target() buffers_to_prefill.reserve(sdef_target_count); } +void CSoundRender_Target::_destroy() +{ + wait_prefill(); +} + void CSoundRender_Target::start(CSoundRender_Emitter* E) { R_ASSERT(E); @@ -37,13 +42,23 @@ void CSoundRender_Target::render() void CSoundRender_Target::stop() { + wait_prefill(); m_pEmitter->source()->detach(); m_pEmitter = nullptr; rendering = false; } -void CSoundRender_Target::rewind() { R_ASSERT(rendering); } -void CSoundRender_Target::update() { R_ASSERT(m_pEmitter); } +void CSoundRender_Target::rewind() +{ + R_ASSERT(rendering); +} + +void CSoundRender_Target::update() +{ + R_ASSERT(m_pEmitter); + wait_prefill(); +} + void CSoundRender_Target::fill_parameters() { VERIFY(m_pEmitter); diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index f9de2ce554e..cd9cf9f4af8 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -20,10 +20,12 @@ class CSoundRender_Target void prefill_all_blocks(Task&, void*); std::atomic prefill_task{}; - void wait_prefill() const; void dispatch_prefill(); void dispatch_prefill_all(); +public: + void wait_prefill() const; + public: float priority{}; @@ -35,7 +37,7 @@ class CSoundRender_Target bool get_Rendering() const { return rendering; } virtual bool _initialize() = 0; - virtual void _destroy() = 0; + virtual void _destroy(); virtual void _restart() = 0; virtual void start(CSoundRender_Emitter* E); diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 25d6efbec00..3d772134d2f 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -35,7 +35,7 @@ bool CSoundRender_TargetA::_initialize() void CSoundRender_TargetA::_destroy() { - wait_prefill(); + CSoundRender_Target::_destroy(); // clean up target if (alIsSource(pSource)) alDeleteSources(1, &pSource); @@ -69,7 +69,6 @@ void CSoundRender_TargetA::stop() A_CHK(alSourcei(pSource, AL_BUFFER, 0)); A_CHK(alSourcei(pSource, AL_SOURCE_RELATIVE, TRUE)); } - wait_prefill(); inherited::stop(); } @@ -80,7 +79,6 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourceStop(pSource)); A_CHK(alSourcei(pSource, AL_BUFFER, 0)); - wait_prefill(); fill_all_blocks(); submit_all_buffers(); @@ -106,8 +104,6 @@ void CSoundRender_TargetA::update() return; } - wait_prefill(); - while (processed > 0) { ALuint BufferID; From 0c2542f28b8769756b701b6ee60a9314327a5171 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 04:45:35 +0500 Subject: [PATCH 235/497] Fix crash when more than one sound emitter use one sound source It crashed when one sound emitter was reading from sound source file and other emitter was destroying the handle of that file. --- src/xrSound/SoundRender_Source.cpp | 25 ++++++++++++++++--------- src/xrSound/SoundRender_Source.h | 1 + 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index de9752ff927..e6238fba64a 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -51,11 +51,11 @@ bool ov_can_continue_read(long res) void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) { - std::lock_guard guard{ read_lock }; - if (!wave) attach(); + std::lock_guard guard{ read_lock }; + // seek const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); const u32 cur_pos = u32(ov_pcm_tell(&ovf)); @@ -145,21 +145,28 @@ constexpr ov_callbacks g_ov_callbacks = void CSoundRender_Source::attach() { - VERIFY(0 == wave); - if (wave) - return; - wave = FS.r_open(pname.c_str()); - R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); - ov_open_callbacks(wave, &ovf, nullptr, 0, g_ov_callbacks); + std::lock_guard guard{ read_lock }; + ++refs; + VERIFY(refs > 0); + if (refs == 1) + { + wave = FS.r_open(pname.c_str()); + R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); + ov_open_callbacks(wave, &ovf, nullptr, 0, g_ov_callbacks); + } } void CSoundRender_Source::detach() { - if (wave) + std::lock_guard guard{ read_lock }; + --refs; + if (refs == 0) { ov_clear(&ovf); FS.r_close(wave); } + if (refs < 0) + refs = 0; } bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 1dee82b32ea..c80b88e44f0 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -12,6 +12,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source OggVorbis_File ovf{}; IReader* wave{}; + int refs{}; std::mutex read_lock; float fTimeTotal; From 4a8b6fbffc3acbe0ae3110a7be20e50e0850f319 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 13 Mar 2024 14:13:10 +0500 Subject: [PATCH 236/497] xrSound: replace WAVEFORMATEX with our own structure --- src/xrSound/SoundRender_Emitter_FSM.cpp | 14 +++++------ src/xrSound/SoundRender_Source.cpp | 31 +++++++++++++------------ src/xrSound/SoundRender_Source.h | 22 ++++++++++++++++-- src/xrSound/SoundRender_Target.cpp | 5 ++-- src/xrSound/SoundRender_Target.h | 1 - src/xrSound/SoundRender_TargetA.cpp | 14 +++++------ src/xrSound/SoundRender_TargetA.h | 2 +- src/xrSound/stdafx.h | 23 ------------------ 8 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 24434bada57..82bbe2fe32e 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -8,7 +8,7 @@ XRSOUND_API extern float psSoundCull; -inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const WAVEFORMATEX& wfx) //--#SM+#-- +inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const SoundSourceInfo& info) //--#SM+#-- { if (fTime < fTimeStarted) fTime = fTimeStarted; // Андрюха посоветовал, ассерт что ниже вылетел из за паузы как то хитро @@ -17,8 +17,8 @@ inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTi { fTime -= fTimeTotal / fFreq; } - u32 curr_sample_num = iFloor((fTime - fTimeStarted) * fFreq * wfx.nSamplesPerSec); - return curr_sample_num * (wfx.wBitsPerSample / 8) * wfx.nChannels; + const u32 curr_sample_num = iFloor((fTime - fTimeStarted) * fFreq * info.samplesPerSec); + return curr_sample_num * (info.bitsPerSample / 8) * info.channels; } void CSoundRender_Emitter::update(float fTime, float dt) @@ -151,7 +151,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) } else { - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- set_cursor(ptr); if (update_culling(dt)) @@ -162,7 +162,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) u32 ptr = calc_cursor( fTimeStarted, fTime, get_length_sec(), - source()->m_wformat); + source()->m_info); set_cursor (ptr); */ SoundRender->i_start(this); @@ -204,7 +204,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { // switch to: PLAY m_current_state = stPlayingLooped; // switch state - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- set_cursor(ptr); SoundRender->i_start(this); @@ -253,7 +253,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = fTime + fRemainingTime; } - const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_wformat); + const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_info); set_cursor(ptr); fTimeToRewind = 0.0f; diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index e6238fba64a..482c74d18ee 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -57,13 +57,13 @@ void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) std::lock_guard guard{ read_lock }; // seek - const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); + const auto sample_offset = ogg_int64_t(byte_offset / m_info.blockAlign); const u32 cur_pos = u32(ov_pcm_tell(&ovf)); if (cur_pos != sample_offset) ov_pcm_seek(&ovf, sample_offset); // decompress - if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + if (m_info.format == SoundFormat::Float32) i_decompress(static_cast(dest), size); else i_decompress(static_cast(dest), size); @@ -85,7 +85,7 @@ void CSoundRender_Source::i_decompress(char* _dest, u32 size) void CSoundRender_Source::i_decompress(float* _dest, u32 size) { - s32 left = s32(size / m_wformat.nBlockAlign); + s32 left = s32(size / m_info.blockAlign); while (left) { float** pcm; @@ -98,7 +98,7 @@ void CSoundRender_Source::i_decompress(float* _dest, u32 size) samples = left; for (long j = 0; j < samples; j++) - for (long i = 0; i < m_wformat.nChannels; i++) + for (long i = 0; i < m_info.channels; i++) *_dest++ = pcm[i][j]; left -= samples; @@ -184,28 +184,29 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) return false; }); - ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); + m_info = {}; - m_wformat.nSamplesPerSec = ovi->rate; - m_wformat.nChannels = u16(ovi->channels); + m_info.samplesPerSec = ovi->rate; + m_info.channels = u16(ovi->channels); if (SoundRender->supports_float_pcm) { - m_wformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - m_wformat.wBitsPerSample = 32; + m_info.format = SoundFormat::Float32; + m_info.bitsPerSample = 32; } else { - m_wformat.wFormatTag = WAVE_FORMAT_PCM; - m_wformat.wBitsPerSample = 16; + m_info.format = SoundFormat::PCM; + m_info.bitsPerSample = 16; } - m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; - m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; + m_info.blockAlign = m_info.bitsPerSample / 8 * m_info.channels; + m_info.avgBytesPerSec = m_info.samplesPerSec * m_info.blockAlign; + m_info.bytesPerBuffer = sdef_target_block * m_info.avgBytesPerSec / 1000; const s64 pcm_total = ov_pcm_total(&ovf, -1); - dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); - fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); + dwBytesTotal = u32(pcm_total * m_info.blockAlign); + fTimeTotal = dwBytesTotal / float(m_info.avgBytesPerSec); const vorbis_comment* ovm = ov_comment(&ovf, -1); if (ovm->comments) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index c80b88e44f0..6592fdb57af 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -4,6 +4,24 @@ #include +enum class SoundFormat +{ + Unknown, + PCM, + Float32, +}; + +struct SoundSourceInfo +{ + SoundFormat format{}; + u16 channels{}; // number of channels (i.e. mono, stereo...) + u32 samplesPerSec{}; // sample rate + u32 avgBytesPerSec{}; // for buffer estimation + u16 blockAlign{}; // block size of data + u16 bitsPerSample{}; // number of bits per sample of mono data + u32 bytesPerBuffer{}; // target buffer size +}; + class XRSOUND_API CSoundRender_Source final : public CSound_source { public: @@ -18,7 +36,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source float fTimeTotal; u32 dwBytesTotal; - WAVEFORMATEX m_wformat; + SoundSourceInfo m_info{}; float m_fBaseVolume; float m_fMinDist; @@ -48,6 +66,6 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source [[nodiscard]] u32 game_type() const override { return m_uGameType; } [[nodiscard]] pcstr file_name() const override { return *fname; } [[nodiscard]] float base_volume() const { return m_fBaseVolume; } - [[nodiscard]] u16 channels_num() const override { return m_wformat.nChannels; } + [[nodiscard]] u16 channels_num() const override { return m_info.channels; } [[nodiscard]] u32 bytes_total() const override { return dwBytesTotal; } }; diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 0eb009fc070..41a47480ebb 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -29,9 +29,8 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) //m_pEmitter->source()->attach(); // Calc storage - buf_block = sdef_target_block * E->source()->m_wformat.nAvgBytesPerSec / 1000; for (auto& buf : temp_buf) - buf.resize(buf_block); + buf.resize(E->source()->m_info.bytesPerBuffer); } void CSoundRender_Target::render() @@ -69,7 +68,7 @@ void CSoundRender_Target::fill_parameters() void CSoundRender_Target::fill_block(size_t idx) { R_ASSERT(m_pEmitter); - m_pEmitter->fill_block(temp_buf[idx].data(), buf_block); + m_pEmitter->fill_block(temp_buf[idx].data(), temp_buf[idx].size()); } void CSoundRender_Target::fill_all_blocks() diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index cd9cf9f4af8..ecfb0926e46 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -10,7 +10,6 @@ class CSoundRender_Target CSoundRender_Emitter* m_pEmitter{}; bool rendering{}; - u32 buf_block{}; xr_vector temp_buf[sdef_target_count]; void fill_block(size_t idx); void fill_all_blocks(); diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 3d772134d2f..9ed2d05c0ab 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -110,7 +110,7 @@ void CSoundRender_TargetA::update() A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); const auto id = get_block_id(BufferID); - submit_buffer(BufferID, temp_buf[id].data()); + submit_buffer(BufferID, temp_buf[id].data(), temp_buf[id].size()); A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; @@ -201,26 +201,26 @@ size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const return it - std::begin(pBuffers); } -void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data) const +void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const { R_ASSERT(m_pEmitter); - const auto& wvf = m_pEmitter->source()->m_wformat; - const bool mono = wvf.nChannels == 1; + const auto& info = m_pEmitter->source()->m_info; + const bool mono = info.channels == 1; ALuint format; - if (wvf.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + if (info.format == SoundFormat::Float32) format = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; else { format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; } - A_CHK(alBufferData(BufferID, format, data, buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); + A_CHK(alBufferData(BufferID, format, data, dataSize, info.samplesPerSec)); } void CSoundRender_TargetA::submit_all_buffers() const { for (size_t i = 0; i < sdef_target_count; ++i) - submit_buffer(pBuffers[i], temp_buf[i].data()); + submit_buffer(pBuffers[i], temp_buf[i].data(), temp_buf[i].size()); } diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 12bf5d81f27..9ede60b3f97 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -16,7 +16,7 @@ class CSoundRender_TargetA : public CSoundRender_Target float cache_pitch{ 1.0f }; size_t get_block_id(ALuint BufferID) const; - void submit_buffer(ALuint BufferID, const void* data) const; + void submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const; void submit_all_buffers() const; public: diff --git a/src/xrSound/stdafx.h b/src/xrSound/stdafx.h index 52b1529fc67..210532c408e 100644 --- a/src/xrSound/stdafx.h +++ b/src/xrSound/stdafx.h @@ -8,26 +8,3 @@ #include "xrCDB/xrCDB.h" #include "Sound.h" - -#if defined(XR_PLATFORM_WINDOWS) -// mmreg.h -#define NOMMIDS -#define NONEWRIFF -#define NOJPEGDIB -#define NONEWIC -#define NOBITMAP -#include -#else -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 - -typedef struct { - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *LPWAVEFORMATEX; -#endif From c9c9641856a318929dac60bfb08a579456309d5f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 14 Mar 2024 16:35:25 +0500 Subject: [PATCH 237/497] Revert "SWM: Added global custom linear\curved smooth volume fading for all world sounds" This reverts commit f6d7db71032a44effd97fe712d1bd2b57dd924e7. --- src/xrSound/Sound.h | 1 - src/xrSound/SoundRender_Core.cpp | 1 - src/xrSound/SoundRender_Emitter_FSM.cpp | 17 ----------------- 3 files changed, 19 deletions(-) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index ea7239d7e24..f4a1ba80bc5 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -48,7 +48,6 @@ XRSOUND_API extern float psSoundRolloff; XRSOUND_API extern float psSoundOcclusionScale; XRSOUND_API extern float psSoundVelocityAlpha; // Cribbledirge: Alpha value for moving average. XRSOUND_API extern float psSoundTimeFactor; //--#SM+#-- -XRSOUND_API extern float psSoundLinearFadeFactor; //--#SM+#-- XRSOUND_API extern Flags32 psSoundFlags; XRSOUND_API extern int psSoundTargets; XRSOUND_API extern int psSoundCacheSizeMB; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 1ac75dbfb1d..9cf79598cda 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -21,7 +21,6 @@ XRSOUND_API int psSoundTargets = 32; XRSOUND_API float psSoundOcclusionScale = 0.5f; XRSOUND_API float psSoundVelocityAlpha = 0.05f; XRSOUND_API float psSoundTimeFactor = 1.0f; -XRSOUND_API float psSoundLinearFadeFactor = 0.4f; //--#SM+#-- XRSOUND_API float psSoundCull = 0.01f; XRSOUND_API float psSoundRolloff = 0.75f; XRSOUND_API u32 psSoundModel = 0; diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 82bbe2fe32e..ef7761a809c 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -300,8 +300,6 @@ IC void volume_lerp(float& c, float t, float s, float dt) bool CSoundRender_Emitter::update_culling(float dt) { - float fAttFactor = 1.0f; //--#SM+#-- - if (b2D) { occluder_volume = 1.f; @@ -334,30 +332,15 @@ bool CSoundRender_Emitter::update_culling(float dt) scene->get_occlusion(p_source.position, .2f, occluder); volume_lerp(occluder_volume, occ, 1.f, dt); clamp(occluder_volume, 0.f, 1.f); - - // Calc linear fade --#SM+#-- - // https://www.desmos.com/calculator/lojovfugle - const float fMinDistDiff = dist - p_source.min_distance; - if (fMinDistDiff > 0.0f) - { - const float fMaxDistDiff = p_source.max_distance - p_source.min_distance; - fAttFactor = pow(1.0f - (fMinDistDiff / fMaxDistDiff), psSoundLinearFadeFactor); - } } clamp(fade_volume, 0.f, 1.f); - // Update smoothing smooth_volume = .9f * smooth_volume + .1f * (p_source.base_volume * p_source.volume * (owner_data->s_type == st_Effect ? psSoundVEffects * psSoundVFactor : psSoundVMusic) * occluder_volume * fade_volume); - - // Add linear fade --#SM+#-- - smooth_volume *= fAttFactor; - if (smooth_volume < psSoundCull) return FALSE; // allow volume to go up - // Here we has enought "PRIORITY" to be soundable // If we are playing already, return OK // --- else check availability of resources From 4e7367903798cb90f7469d1cf320a2b088f73957 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Mar 2024 17:29:25 +0500 Subject: [PATCH 238/497] Fix sound parameters doesn't get updated properly This reverts one change from dfa50c2ba16e00878b3065d09bd82d483950efad --- src/xrSound/SoundRender_Core_Processor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 1d2aaee810e..18fce99db2e 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -87,6 +87,7 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector // Has emmitter, maybe just not started rendering if (T->get_Rendering()) { + T->fill_parameters(); T->update(); } else From b580e9b7571ba86e7268ea3fc2ecf83236d5e8cb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Mar 2024 20:08:58 +0500 Subject: [PATCH 239/497] Revert "Added sound doppler effect by Cribbledirge" This reverts commit 0fc1ccf45e87260ee42833b3780dae04904c05a0. --- src/xrSound/Sound.h | 38 +------------------------ src/xrSound/SoundRender_Core.cpp | 1 - src/xrSound/SoundRender_CoreA.cpp | 8 +----- src/xrSound/SoundRender_CoreA.h | 8 ++---- src/xrSound/SoundRender_Emitter.cpp | 4 +-- src/xrSound/SoundRender_Emitter_FSM.cpp | 4 --- src/xrSound/SoundRender_TargetA.cpp | 4 --- 7 files changed, 6 insertions(+), 61 deletions(-) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index f4a1ba80bc5..d44327853b2 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -46,7 +46,6 @@ XRSOUND_API extern float psSoundVFactor; XRSOUND_API extern float psSoundVMusic; XRSOUND_API extern float psSoundRolloff; XRSOUND_API extern float psSoundOcclusionScale; -XRSOUND_API extern float psSoundVelocityAlpha; // Cribbledirge: Alpha value for moving average. XRSOUND_API extern float psSoundTimeFactor; //--#SM+#-- XRSOUND_API extern Flags32 psSoundFlags; XRSOUND_API extern int psSoundTargets; @@ -113,48 +112,13 @@ class XRSOUND_API CSound_environment class XRSOUND_API CSound_params { public: - Fvector position{}; - Fvector velocity{}; // Cribbledirge. Added for doppler effect. - Fvector curVelocity{}; // Current velocity. - Fvector prevVelocity{}; // Previous velocity. - Fvector accVelocity{}; // Velocity accumulator (for moving average). + Fvector position; float base_volume; float volume; float freq; float min_distance; float max_distance; float max_ai_distance; - - // Functions added by Cribbledirge for doppler effect. - void update_position(const Fvector& newPosition) - { - // If the position has been set already, start getting a moving average of the velocity. - if (set) - { - prevVelocity.set(accVelocity); - curVelocity.sub(newPosition, position); - accVelocity.set(curVelocity.mul(psSoundVelocityAlpha).add(prevVelocity.mul(1.f - psSoundVelocityAlpha))); - } - else - { - set = true; - } - position.set(newPosition); - } - - void update_velocity(const float dt) - { - velocity.set(accVelocity).div(dt); - } - -private: - // A variable in place to determine if the position has been set. This is to prevent artifacts when - // the position jumps from its initial position of zero to something greatly different. This is a big - // issue in moving average calculation. We want the velocity to always start at zero for when the sound - // was initiated, or else things will sound really really weird. - bool set{}; - - // End Cribbledirge. }; /// definition (Sound Interface) diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 9cf79598cda..07a9aa7754c 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -19,7 +19,6 @@ XRSOUND_API Flags32 psSoundFlags = XRSOUND_API int psSoundTargets = 32; XRSOUND_API float psSoundOcclusionScale = 0.5f; -XRSOUND_API float psSoundVelocityAlpha = 0.05f; XRSOUND_API float psSoundTimeFactor = 1.0f; XRSOUND_API float psSoundCull = 0.01f; XRSOUND_API float psSoundRolloff = 0.75f; diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 1cb755dd4d1..4b36f63ddaf 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -163,12 +163,6 @@ void CSoundRender_CoreA::update_listener(const Fvector& P, const Fvector& D, con { inherited::update_listener(P, D, N, dt); - // Use exponential moving average for a nice smooth doppler effect. - Listener.prevVelocity.set(Listener.accVelocity); - Listener.curVelocity.sub(P, Listener.position); - Listener.accVelocity.set(Listener.curVelocity.mul(psSoundVelocityAlpha).add(Listener.prevVelocity.mul(1.f - psSoundVelocityAlpha))); - Listener.prevVelocity.set(Listener.accVelocity).div(dt); - if (!Listener.position.similar(P)) { Listener.position.set(P); @@ -178,6 +172,6 @@ void CSoundRender_CoreA::update_listener(const Fvector& P, const Fvector& D, con Listener.orientation[1].set(N.x, N.y, -N.z); A_CHK(alListener3f(AL_POSITION, Listener.position.x, Listener.position.y, -Listener.position.z)); - A_CHK(alListener3f(AL_VELOCITY, Listener.prevVelocity.x, Listener.prevVelocity.y, -Listener.prevVelocity.z)); + A_CHK(alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f)); A_CHK(alListenerfv(AL_ORIENTATION, (const ALfloat*)&Listener.orientation[0].x)); } diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index 6751e633a2c..3afc6476f2b 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -60,12 +60,8 @@ class CSoundRender_CoreA : public CSoundRender_Core struct SListener { - Fvector position{}; - Fvector velocity{}; - Fvector curVelocity{}; - Fvector prevVelocity{}; - Fvector accVelocity{}; - Fvector orientation[2]{}; + Fvector position; + Fvector orientation[2]; }; SListener Listener; diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index b69c38224f0..b157d72eeea 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -11,9 +11,9 @@ extern float psSoundVEffects; void CSoundRender_Emitter::set_position(const Fvector& pos) { if (source()->channels_num() == 1) - p_source.update_position(pos); + p_source.position = pos; else - p_source.update_position({}); + p_source.position.set(0, 0, 0); bMoved = true; } diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index ef7761a809c..dfced028ed7 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -360,10 +360,6 @@ float CSoundRender_Emitter::priority() const void CSoundRender_Emitter::update_environment(float dt) { if (bMoved) - { e_target = *(CSoundRender_Environment*)scene->get_environment(p_source.position); - // Cribbledirge: updates the velocity of the sound. - p_source.update_velocity(dt); - } e_current.lerp(e_current, e_target, dt); } diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 9ed2d05c0ab..8779a8f09f5 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -162,10 +162,6 @@ void CSoundRender_TargetA::fill_parameters() A_CHK(alSource3f(pSource, AL_POSITION, m_pEmitter->p_source.position.x, m_pEmitter->p_source.position.y, -m_pEmitter->p_source.position.z)); - VERIFY2(m_pEmitter, SE->source()->file_name()); - A_CHK(alSource3f(pSource, AL_VELOCITY, m_pEmitter->p_source.velocity.x, m_pEmitter->p_source.velocity.y, - -m_pEmitter->p_source.velocity.z)); - VERIFY2(m_pEmitter, SE->source()->file_name()); A_CHK(alSourcei(pSource, AL_SOURCE_RELATIVE, m_pEmitter->b2D)); From 002663563f584d5ce67b6557e708eba84f480d96 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Mar 2024 23:15:19 +0500 Subject: [PATCH 240/497] Send Right camera vector to xrSound --- src/xrEngine/Engine.cpp | 2 +- src/xrSound/Sound.h | 2 +- src/xrSound/SoundRender_Core.cpp | 2 +- src/xrSound/SoundRender_Core.h | 4 ++-- src/xrSound/SoundRender_CoreA.cpp | 4 ++-- src/xrSound/SoundRender_CoreA.h | 2 +- src/xrSound/SoundRender_Core_Processor.cpp | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 15353fb6a36..3d788ddb98e 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -14,7 +14,7 @@ struct _SoundProcessor final : public pureFrame void OnFrame() override { // Msg ("------------- sound: %d [%3.2f,%3.2f,%3.2f]",u32(Device.dwFrame),VPUSH(Device.vCameraPosition)); - GEnv.Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop); + GEnv.Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop, Device.vCameraRight); } } SoundProcessor; diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index d44327853b2..db6f0d0f624 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -229,7 +229,7 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void set_master_volume(float f = 1.f) = 0; - virtual void update(const Fvector& P, const Fvector& D, const Fvector& N) = 0; + virtual void update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) = 0; virtual void statistic(CSound_stats* s0, CSound_stats_ext* s1) = 0; virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) = 0; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 07a9aa7754c..d07948e5023 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -189,7 +189,7 @@ void CSoundRender_Core::env_apply() bListenerMoved = true; } -void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) +void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) { if (!psSoundFlags.test(ss_EFX) || !m_effects) return; diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 2b1a06f0ded..476dddfc5e1 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -90,13 +90,13 @@ class CSoundRender_Core : public ISoundManager void set_master_volume(float f) override = 0; - void update(const Fvector& P, const Fvector& D, const Fvector& N) override; + void update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) override; void statistic(CSound_stats* dest, CSound_stats_ext* ext) override; void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; // listener // virtual const Fvector& listener_position ( )=0; - virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) = 0; + virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) = 0; void refresh_sources() override; diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 4b36f63ddaf..4e6abd15d1b 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -159,9 +159,9 @@ void CSoundRender_CoreA::_clear() xr_delete(pDeviceList); } -void CSoundRender_CoreA::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) +void CSoundRender_CoreA::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) { - inherited::update_listener(P, D, N, dt); + inherited::update_listener(P, D, N, R, dt); if (!Listener.position.similar(P)) { diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index 3afc6476f2b..bb78058fdf0 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -67,7 +67,7 @@ class CSoundRender_CoreA : public CSoundRender_Core SListener Listener; protected: - void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, float dt) override; + void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) override; public: CSoundRender_CoreA(CSoundManager& p); diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 18fce99db2e..569f55bee34 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -9,7 +9,7 @@ #include "SoundRender_Target.h" #include "SoundRender_Source.h" -void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector& N) +void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) { if (0 == bReady) return; @@ -104,7 +104,7 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector } // update listener - update_listener(P, D, N, fTimer_Delta); + update_listener(P, D, N, R, fTimer_Delta); // Start rendering of pending targets if (!s_targets_defer.empty()) From 6cd727d088f75c2caeeb5be9c5d4c555c35aea7e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 15 Mar 2024 23:34:32 +0500 Subject: [PATCH 241/497] xrSound: moved Listener data to CSoundRender_Core --- src/xrSound/SoundRender_Core.cpp | 10 +++++++++- src/xrSound/SoundRender_Core.h | 30 +++++++++++++++++++++++++++--- src/xrSound/SoundRender_CoreA.cpp | 12 +++--------- src/xrSound/SoundRender_CoreA.h | 9 --------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index d07948e5023..f59a6b6e65c 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -40,7 +40,6 @@ CSoundRender_Core::CSoundRender_Core(CSoundManager& p) s_emitters_u = 0; e_current.set_identity(); e_target.set_identity(); - bListenerMoved = false; bReady = false; isLocked = false; fTimer_Value = Timer.GetElapsed_sec(); @@ -191,6 +190,15 @@ void CSoundRender_Core::env_apply() void CSoundRender_Core::update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) { + if (!Listener.position.similar(P)) + { + Listener.position = P; + bListenerMoved = true; + } + Listener.orientation[0] = D; + Listener.orientation[1] = N; + Listener.orientation[2] = R; + if (!psSoundFlags.test(ss_EFX) || !m_effects) return; diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 476dddfc5e1..97674f3ce34 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -22,8 +22,31 @@ class CSoundRender_Core : public ISoundManager private: volatile bool isLocked; +public: + struct SListener + { + Fvector position; + Fvector orientation[3]; + + [[nodiscard]] + SListener ToRHS() const + { + return + { + { position.x, position.y, -position.z }, + { + { orientation[0].x, orientation[0].y, -orientation[0].z }, + { orientation[1].x, orientation[1].y, -orientation[1].z }, + { orientation[2].x, orientation[2].y, -orientation[2].z }, + }, + }; + } + }; + protected: - bool bListenerMoved; + SListener Listener; + + bool bListenerMoved{}; CSoundRender_Environment e_current; CSoundRender_Environment e_target; @@ -95,8 +118,9 @@ class CSoundRender_Core : public ISoundManager void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; // listener - // virtual const Fvector& listener_position ( )=0; - virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) = 0; + const auto& listener_params() const { return Listener; } + const Fvector& listener_position() override { return Listener.position; } + virtual void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt); void refresh_sources() override; diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 4e6abd15d1b..1eda9d81324 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -163,15 +163,9 @@ void CSoundRender_CoreA::update_listener(const Fvector& P, const Fvector& D, con { inherited::update_listener(P, D, N, R, dt); - if (!Listener.position.similar(P)) - { - Listener.position.set(P); - bListenerMoved = TRUE; - } - Listener.orientation[0].set(D.x, D.y, -D.z); - Listener.orientation[1].set(N.x, N.y, -N.z); + const auto listener = Listener.ToRHS(); - A_CHK(alListener3f(AL_POSITION, Listener.position.x, Listener.position.y, -Listener.position.z)); + A_CHK(alListener3f(AL_POSITION, listener.position.x, listener.position.y, listener.position.z)); A_CHK(alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f)); - A_CHK(alListenerfv(AL_ORIENTATION, (const ALfloat*)&Listener.orientation[0].x)); + A_CHK(alListenerfv(AL_ORIENTATION, &listener.orientation[0].x)); } diff --git a/src/xrSound/SoundRender_CoreA.h b/src/xrSound/SoundRender_CoreA.h index bb78058fdf0..7dc9c9e1e50 100644 --- a/src/xrSound/SoundRender_CoreA.h +++ b/src/xrSound/SoundRender_CoreA.h @@ -58,14 +58,6 @@ class CSoundRender_CoreA : public CSoundRender_Core ALCcontext* pContext; ALDeviceList* pDeviceList; - struct SListener - { - Fvector position; - Fvector orientation[2]; - }; - - SListener Listener; - protected: void update_listener(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R, float dt) override; @@ -79,5 +71,4 @@ class CSoundRender_CoreA : public CSoundRender_Core void set_master_volume(float f) override; - const Fvector& listener_position() override { return Listener.position; } }; From 41493ab6528f534242b2e260bda07b8088e07f53 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Mar 2024 12:24:41 +0500 Subject: [PATCH 242/497] xrMaterialSystem: added material acoustics parameters for SteamAudio needs --- src/xrMaterialSystem/GameMtlLib.cpp | 92 +++++++++++++++++++++++++++++ src/xrMaterialSystem/GameMtlLib.h | 9 +++ 2 files changed, 101 insertions(+) diff --git a/src/xrMaterialSystem/GameMtlLib.cpp b/src/xrMaterialSystem/GameMtlLib.cpp index 2c66f9b1572..7c2ad6c795a 100644 --- a/src/xrMaterialSystem/GameMtlLib.cpp +++ b/src/xrMaterialSystem/GameMtlLib.cpp @@ -15,6 +15,85 @@ const char* SGameMtlPair::dbg_Name() const } #endif +bool assign_default_acoustics(const shared_str& material, SGameMtl::MtlAcoustics& acoustics) +{ + using entry_type = std::tuple; + + static entry_type predefined[] = + { + { "default", { { 0.10f, 0.20f, 0.30f }, 0.05f, { 0.100f, 0.050f, 0.030f } } }, + { "default_object", { { 0.10f, 0.20f, 0.30f }, 0.05f, { 0.100f, 0.050f, 0.030f } } }, + + { "materials\\asphalt", { { 0.15f, 0.25f, 0.35f }, 0.1f, { 0.05f, 0.02f, 0.01f } } }, + { "materials\\bricks", { { 0.03f, 0.04f, 0.07f }, 0.05f, { 0.015f, 0.015f, 0.015f } } }, + { "materials\\bush", { { 0.20f, 0.30f, 0.40f }, 0.2f, { 0.10f, 0.05f, 0.02f } } }, + { "materials\\bush_sux", { { 0.30f, 0.40f, 0.50f }, 0.3f, { 0.15f, 0.07f, 0.03f } } }, + { "materials\\cloth", { { 0.20f, 0.30f, 0.40f }, 0.2f, { 0.10f, 0.05f, 0.02f } } }, + { "materials\\concrete", { { 0.05f, 0.07f, 0.08f }, 0.05f, { 0.015f, 0.002f, 0.001f } } }, + { "materials\\death", { { 0.00f, 0.00f, 0.00f }, 0.00f, { 1.0f, 1.0f, 1.0f } } }, + { "materials\\dirt", { { 0.20f, 0.30f, 0.40f }, 0.15f, { 0.08f, 0.04f, 0.02f } } }, + { "materials\\earth", { { 0.25f, 0.35f, 0.45f }, 0.20f, { 0.10f, 0.05f, 0.03f } } }, + { "materials\\earth_death", { { 0.25f, 0.35f, 0.45f }, 0.20f, { 0.10f, 0.05f, 0.03f } } }, + { "materials\\earth_slide", { { 0.25f, 0.35f, 0.45f }, 0.20f, { 0.10f, 0.05f, 0.03f } } }, + { "materials\\flooring_tile", { { 0.01f, 0.02f, 0.02f }, 0.05f, { 0.060f, 0.044f, 0.011f } } }, + { "materials\\glass", { { 0.06f, 0.03f, 0.02f }, 0.05f, { 0.060f, 0.044f, 0.011f } } }, + { "materials\\grass", { { 0.30f, 0.40f, 0.50f }, 0.25f, { 0.12f, 0.06f, 0.04f } } }, + { "materials\\gravel", { { 0.60f, 0.70f, 0.80f }, 0.05f, { 0.031f, 0.012f, 0.008f } } }, + { "materials\\metal", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "materials\\metal_pipe", { { 0.15f, 0.10f, 0.08f }, 0.10f, { 0.10f, 0.050f, 0.020f } } }, + { "materials\\metal_plate", { { 0.10f, 0.05f, 0.04f }, 0.02f, { 0.30f, 0.030f, 0.015f } } }, + { "materials\\sand", { { 0.20f, 0.30f, 0.40f }, 0.2f, { 0.10f, 0.05f, 0.02f } } }, + { "materials\\setka_rabica", { { 0.01f, 0.01f, 0.01f }, 0.02f, { 0.5f, 0.5f, 0.5f } } }, + { "materials\\shifer", { { 0.02f, 0.04f, 0.06f }, 0.2f, { 0.05f, 0.02f, 0.01f } } }, + { "materials\\stucco", { { 0.01f, 0.02f, 0.02f }, 0.05f, { 0.060f, 0.044f, 0.011f } } }, + { "materials\\tin", { { 0.05f, 0.10f, 0.15f }, 0.2f, { 0.70f, 0.60f, 0.50f } } }, + { "materials\\tree_trunk", { { 0.11f, 0.07f, 0.06f }, 0.05f, { 0.070f, 0.014f, 0.005f } } }, + { "materials\\water", { { 0.01f, 0.02f, 0.03f }, 0.05f, { 0.99f, 0.98f, 0.97f } } }, + { "materials\\water_radiation", { { 0.01f, 0.02f, 0.03f }, 0.05f, { 0.99f, 0.98f, 0.97f } } }, + { "materials\\wood", { { 0.11f, 0.07f, 0.06f }, 0.05f, { 0.070f, 0.014f, 0.005f } } }, + { "materials\\wooden_board", { { 0.11f, 0.07f, 0.06f }, 0.05f, { 0.070f, 0.014f, 0.005f } } }, + + { "objects\\barrel", { { 0.20f, 0.30f, 0.40f }, 0.2f, { 0.05f, 0.03f, 0.02f } } }, + { "objects\\bottle", { { 0.06f, 0.03f, 0.02f }, 0.05f, { 0.06f, 0.04f, 0.01f } } }, + { "objects\\bullet", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "objects\\car_cabine", { { 0.2f, 0.3f, 0.4f }, 0.2f, { 0.1f, 0.05f, 0.02f } } }, + { "objects\\car_wheel", { { 0.2f, 0.3f, 0.4f }, 0.2f, { 0.1f, 0.05f, 0.02f } } }, + { "objects\\clothes", { { 0.25f, 0.35f, 0.45f }, 0.3f, { 0.15f, 0.07f, 0.03f } } }, + { "objects\\concrete_box", { { 0.05f, 0.07f, 0.08f }, 0.05f, { 0.015f, 0.002f, 0.001f } } }, + { "objects\\dead_body", { { 0.10f, 0.20f, 0.30f }, 0.05f, { 0.100f, 0.050f, 0.030f } } }, + { "objects\\fuel_can", { { 0.3f, 0.4f, 0.5f }, 0.2f, { 0.1f, 0.05f, 0.02f } } }, + { "objects\\glass", { { 0.06f, 0.03f, 0.02f }, 0.05f, { 0.060f, 0.044f, 0.011f } } }, + { "objects\\knife", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "objects\\large_furniture", { { 0.20f, 0.30f, 0.40f }, 0.2f, { 0.05f, 0.03f, 0.02f } } }, + { "objects\\large_metal_trash", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "objects\\large_weapon", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "objects\\metal_box", { { 0.20f, 0.07f, 0.06f }, 0.05f, { 0.200f, 0.025f, 0.010f } } }, + { "objects\\monster_body", { { 0.6f, 0.7f, 0.8f }, 0.3f, { 0.1f, 0.05f, 0.02f } } }, + { "objects\\small_box", { { 0.10f, 0.05f, 0.04f }, 0.02f, { 0.30f, 0.030f, 0.015f } } }, + { "objects\\small_metal_trash", { { 0.10f, 0.05f, 0.04f }, 0.02f, { 0.30f, 0.030f, 0.015f } } }, + { "objects\\small_weapon", { { 0.10f, 0.05f, 0.04f }, 0.02f, { 0.30f, 0.030f, 0.015f } } }, + { "objects\\tin_can", { { 0.05f, 0.10f, 0.15f }, 0.2f, { 0.70f, 0.60f, 0.50f } } }, + }; + + auto it = std::find_if(std::begin(predefined), std::end(predefined), [&material](const entry_type& entry) + { + const auto& [name, _] = entry; + return name == material; + }); + + bool found = true; + if (it == std::end(predefined)) + { + // Assign first material, which is 'default' + it = std::begin(predefined); + found = false; + } + + const auto& [_, entry] = *it; + acoustics = entry; + return found; +} + void SGameMtl::Load(IReader& fs) { R_ASSERT(fs.find_chunk(GAMEMTL_CHUNK_MAIN)); @@ -55,6 +134,19 @@ void SGameMtl::Load(IReader& fs) if (fs.find_chunk(GAMEMTL_CHUNK_DENSITY)) fDensityFactor = fs.r_float(); + + if (fs.find_chunk(GAMEMTL_CHUNK_ACOUSTICS)) + fs.r(&Acoustics, sizeof(Acoustics)); + else + { + const bool predefined_found = assign_default_acoustics(m_Name, Acoustics); + if (!predefined_found) + { + Acoustics.fAbsorption[0] = fSndOcclusionFactor; + Acoustics.fAbsorption[1] = fSndOcclusionFactor; + Acoustics.fAbsorption[2] = fSndOcclusionFactor; + } + } } CGameMtlLibrary::CGameMtlLibrary() diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 1e26912bd26..02ed6856b42 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -30,6 +30,7 @@ constexpr u32 GAMEMTL_CHUNK_DESC = 0x1005; constexpr u32 GAMEMTL_CHUNK_INJURIOUS = 0x1006; constexpr u32 GAMEMTL_CHUNK_DENSITY = 0x1007; constexpr u32 GAMEMTL_CHUNK_FACTORS_MP = 0x1008; +constexpr u32 GAMEMTL_CHUNK_ACOUSTICS = 0x1009; constexpr u32 GAMEMTLPAIR_CHUNK_PAIR = 0x1000; //constexpr u32 GAMEMTLPAIR_CHUNK_FLOTATION = 0x1001; // obsolete @@ -98,6 +99,14 @@ struct MTL_EXPORT_API SGameMtl float fSndOcclusionFactor; // 0.f - 1.f (1.f-полностью слышен) float fDensityFactor; + struct MtlAcoustics + { + float fAbsorption[3]; + float fScattering; + float fTransmission[3]; + }; + MtlAcoustics Acoustics{}; + public: SGameMtl() { From 5ad223997f5aa581937294dd67c0adf0e61529f9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Mar 2024 07:01:28 +0500 Subject: [PATCH 243/497] xrGame/Level_load.cpp: modernize with range-based for, emplace_back, cbegin/cend --- src/xrGame/Level_load.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index 4ee77204890..8b7a158881c 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -104,10 +104,9 @@ bool CLevel::Load_GameSpecific_After() { CInifile::Sect& S = pSettings->r_section("sounds_random"); Sounds_Random.reserve(S.Data.size()); - for (auto I = S.Data.cbegin(); S.Data.cend() != I; ++I) + for (const auto& I : S.Data) { - Sounds_Random.push_back(ref_sound()); - Sounds_Random.back().create(*I->first, st_Effect, sg_SourceType); + Sounds_Random.emplace_back().create(I.first.c_str(), st_Effect, sg_SourceType); } Sounds_Random_dwNextTime = Device.TimerAsync() + 50000; Sounds_Random_Enabled = FALSE; @@ -190,7 +189,7 @@ void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) ID_INDEX_PAIRS translator; translator.reserve(GMLib.CountMaterial()); u16 default_id = (u16)GMLib.GetMaterialIdx("default"); - translator.push_back(translation_pair(u32(-1), default_id)); + translator.emplace_back(u32(-1), default_id); u16 index = 0, static_mtl_count = 1; int max_ID = 0; @@ -200,7 +199,7 @@ void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) if (!(*I)->Flags.test(SGameMtl::flDynamic)) { ++static_mtl_count; - translator.push_back(translation_pair((*I)->GetID(), index)); + translator.emplace_back((*I)->GetID(), index); if ((*I)->GetID() > max_static_ID) max_static_ID = (*I)->GetID(); } @@ -216,11 +215,11 @@ void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) CDB::TRI* E = tris + count; for (; I != E; ++I) { - ID_INDEX_PAIRS::iterator i = std::find(translator.begin(), translator.end(), (u16)(*I).material); + const auto i = std::find(translator.cbegin(), translator.cend(), (u16)(*I).material); if (i != translator.end()) { (*I).material = (*i).m_index; - SGameMtl* mtl = GMLib.GetMaterialByIdx((*i).m_index); + const SGameMtl* mtl = GMLib.GetMaterialByIdx((*i).m_index); (*I).suppress_shadows = mtl->Flags.is(SGameMtl::flSuppressShadows); (*I).suppress_wm = mtl->Flags.is(SGameMtl::flSuppressWallmarks); continue; @@ -237,11 +236,11 @@ void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) CDB::TRI* E = tris + count; for (; I != E; ++I) { - ID_INDEX_PAIRS::iterator i = std::lower_bound(translator.begin(), translator.end(), (u16)(*I).material); - if ((i != translator.end()) && ((*i).m_id == (*I).material)) + const auto i = std::lower_bound(translator.cbegin(), translator.cend(), (u16)(*I).material); + if ((i != translator.cend()) && ((*i).m_id == (*I).material)) { (*I).material = (*i).m_index; - SGameMtl* mtl = GMLib.GetMaterialByIdx((*i).m_index); + const SGameMtl* mtl = GMLib.GetMaterialByIdx((*i).m_index); (*I).suppress_shadows = mtl->Flags.is(SGameMtl::flSuppressShadows); (*I).suppress_wm = mtl->Flags.is(SGameMtl::flSuppressWallmarks); continue; From 6c23e102a5b281c0dfc67187f9677b12b23f8a36 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 17 Mar 2024 07:02:03 +0500 Subject: [PATCH 244/497] xrMaterialSystem/GameMtlLib.h: Add Materials() function to allow range-based for usage --- src/xrMaterialSystem/GameMtlLib.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index 02ed6856b42..b7eee1d3ff0 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -301,6 +301,8 @@ class MTL_EXPORT_API CGameMtlLibrary GameMtlIt FirstMaterial() { return materials.begin(); } GameMtlIt LastMaterial() { return materials.end(); } + const auto& Materials() const { return materials; } + u32 CountMaterial() const { return materials.size(); } #ifdef _EDITOR From a857e4c214a60a1accdfbd28e6e9fd2ed83c2445 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Mar 2024 03:24:40 +0500 Subject: [PATCH 245/497] Remove GameMtlVec and GameMtlIt types Less unneeded entities. We have 'auto' type since C++11. --- src/xrGame/Level_load.cpp | 2 +- src/xrMaterialSystem/GameMtlLib.h | 14 ++++++-------- src/xrPhysics/PHActorCharacter.cpp | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index 8b7a158881c..b7a879f4309 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -194,7 +194,7 @@ void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) u16 index = 0, static_mtl_count = 1; int max_ID = 0; int max_static_ID = 0; - for (GameMtlIt I = GMLib.FirstMaterial(); GMLib.LastMaterial() != I; ++I, ++index) + for (auto I = GMLib.FirstMaterial(); GMLib.LastMaterial() != I; ++I, ++index) { if (!(*I)->Flags.test(SGameMtl::flDynamic)) { diff --git a/src/xrMaterialSystem/GameMtlLib.h b/src/xrMaterialSystem/GameMtlLib.h index b7eee1d3ff0..24080c5f65f 100644 --- a/src/xrMaterialSystem/GameMtlLib.h +++ b/src/xrMaterialSystem/GameMtlLib.h @@ -136,8 +136,6 @@ struct MTL_EXPORT_API SGameMtl void FillProp(PropItemVec& values, ListItem* owner); #endif }; -using GameMtlVec = xr_vector; -using GameMtlIt = GameMtlVec::iterator; struct MTL_EXPORT_API SGameMtlPair { @@ -230,7 +228,7 @@ class MTL_EXPORT_API CGameMtlLibrary int material_index; int material_pair_index; - GameMtlVec materials; + xr_vector materials; GameMtlPairVec material_pairs; GameMtlPairVec material_pairs_rt; @@ -250,17 +248,17 @@ class MTL_EXPORT_API CGameMtlLibrary material_pairs.clear(); } - GameMtlIt GetMaterialIt(pcstr name) + auto GetMaterialIt(pcstr name) { auto pred = [&](const SGameMtl* mtl) { return !xr_strcmpi(mtl->m_Name.c_str(), name); }; return std::find_if(materials.begin(), materials.end(), pred); } - GameMtlIt GetMaterialIt(const shared_str& name) + auto GetMaterialIt(const shared_str& name) { auto pred = [&](const SGameMtl* mtl) { return mtl->m_Name.equal(name); }; return std::find_if(materials.begin(), materials.end(), pred); } - GameMtlIt GetMaterialItByID(int id) + auto GetMaterialItByID(int id) { auto pred = [&](const SGameMtl* mtl) { return mtl->ID == id; }; return std::find_if(materials.begin(), materials.end(), pred); @@ -298,8 +296,8 @@ class MTL_EXPORT_API CGameMtlLibrary return materials[idx]; } - GameMtlIt FirstMaterial() { return materials.begin(); } - GameMtlIt LastMaterial() { return materials.end(); } + auto FirstMaterial() { return materials.begin(); } + auto LastMaterial() { return materials.end(); } const auto& Materials() const { return materials; } diff --git a/src/xrPhysics/PHActorCharacter.cpp b/src/xrPhysics/PHActorCharacter.cpp index 3610155de9f..0d1850d593e 100644 --- a/src/xrPhysics/PHActorCharacter.cpp +++ b/src/xrPhysics/PHActorCharacter.cpp @@ -51,7 +51,7 @@ void CPHActorCharacter::Create(dVector3 sizes) } if (slide_material_index == GAMEMTL_NONE_IDX) { - GameMtlIt mi = GMLib.GetMaterialIt("materials" DELIMITER "earth_slide"); + const auto mi = GMLib.GetMaterialIt("materials" DELIMITER "earth_slide"); if (mi != GMLib.LastMaterial()) slide_material_index = u16(mi - GMLib.FirstMaterial()); // slide_material_index = GMLib.GetMaterialIdx("earth_slide"); From 6144d318e2e2f1030b767d6be422152b0d156e2b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Mar 2024 05:28:48 +0500 Subject: [PATCH 246/497] Fix game cannot run on Linux during first launch (fixes #1612) --- src/xrCore/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 4588ed2c130..83085473c2a 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -464,8 +464,8 @@ endif() target_compile_definitions(xrCore PRIVATE XRCORE_EXPORTS - CMAKE_INSTALL_FULL_LIBDIR="${CMAKE_INSTALL_FULL_LIBDIR}" - CMAKE_INSTALL_FULL_DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}" + CMAKE_INSTALL_FULL_LIBDIR=${CMAKE_INSTALL_FULL_LIBDIR} + CMAKE_INSTALL_FULL_DATAROOTDIR=${CMAKE_INSTALL_FULL_DATAROOTDIR} CI=$ENV{CI} GITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} GITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} From a50696b0266a5e2884c9a87e88e15593838be4bf Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Mar 2024 08:53:29 +0500 Subject: [PATCH 247/497] Render sounds in secondary thread This splits sound logic update (which happens in main thread from sound rendering, which happens in secondary thread. --- src/xrEngine/Engine.cpp | 23 ++++++---- src/xrSound/Sound.h | 1 + src/xrSound/SoundRender_Core.cpp | 1 - src/xrSound/SoundRender_Core.h | 10 ++--- src/xrSound/SoundRender_Core_Processor.cpp | 51 +++++++++------------- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 3d788ddb98e..b0a53998377 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -9,14 +9,21 @@ #include "XR_IOConsole.h" #include "xr_ioc_cmd.h" -struct _SoundProcessor final : public pureFrame +struct SoundProcessor final : public pureFrame { void OnFrame() override { - // Msg ("------------- sound: %d [%3.2f,%3.2f,%3.2f]",u32(Device.dwFrame),VPUSH(Device.vCameraPosition)); GEnv.Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop, Device.vCameraRight); } -} SoundProcessor; +} g_sound_processor; + +struct SoundRenderer final : public pureFrame +{ + void OnFrame() override + { + GEnv.Sound->render(); + } +} g_sound_renderer; CEngine Engine; @@ -65,10 +72,8 @@ void CEngine::Initialize(void) Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000); - if (psDeviceFlags.test(mtSound)) - Device.seqFrameMT.Add(&SoundProcessor); - else - Device.seqFrame.Add(&SoundProcessor); + Device.seqFrame.Add(&g_sound_processor, REG_PRIORITY_NORMAL - 1000); // Place it after Level update + Device.seqFrameMT.Add(&g_sound_renderer); External.CreateRendererList(); CheckAndSetupRenderer(); @@ -85,8 +90,8 @@ void CEngine::Destroy() Event.Handler_Detach(eQuit, this); - Device.seqFrameMT.Remove(&SoundProcessor); - Device.seqFrame.Remove(&SoundProcessor); + Device.seqFrameMT.Remove(&g_sound_processor); + Device.seqFrame.Remove(&g_sound_processor); Device.seqFrame.Remove(this); } diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index db6f0d0f624..8b79b5b1751 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -230,6 +230,7 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void set_master_volume(float f = 1.f) = 0; virtual void update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) = 0; + virtual void render() = 0; virtual void statistic(CSound_stats* s0, CSound_stats_ext* s1) = 0; virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) = 0; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index f59a6b6e65c..df0d8fff9df 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -36,7 +36,6 @@ CSoundRender_Core::CSoundRender_Core(CSoundManager& p) : Parent(p) { bPresent = false; - s_targets_pu = 0; s_emitters_u = 0; e_current.set_identity(); e_target.set_identity(); diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 97674f3ce34..4cc04f1a2bc 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -12,11 +12,12 @@ class CSoundRender_Core : public ISoundManager protected: struct SoundStatistics { - CStatTimer Update; // total time taken by sound subsystem (accurate only in single-threaded mode) + CStatTimer Update; + CStatTimer Render; SoundStatistics() { FrameStart(); } - void FrameStart() { Update.FrameStart(); } - void FrameEnd() { Update.FrameEnd(); } + void FrameStart() { Update.FrameStart(); Render.FrameStart(); } + void FrameEnd() { Update.FrameEnd(); Render.FrameEnd(); } }; private: @@ -74,8 +75,6 @@ class CSoundRender_Core : public ISoundManager u32 s_emitters_u; // emitter update marker xr_vector s_targets; - xr_vector s_targets_defer; - u32 s_targets_pu; // parameters update CSoundRender_Effects* m_effects{}; @@ -114,6 +113,7 @@ class CSoundRender_Core : public ISoundManager void set_master_volume(float f) override = 0; void update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) override; + void render() override; void statistic(CSound_stats* dest, CSound_stats_ext* ext) override; void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 569f55bee34..166e6396873 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -76,49 +76,37 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector } } } - // Get currently rendering emitters - s_targets_defer.clear(); - s_targets_pu++; + + // update listener + update_listener(P, D, N, R, fTimer_Delta); + + // Events + for (CSoundRender_Scene* scene : m_scenes) + scene->update(); + + isLocked = false; + Stats.Update.End(); +} + +void CSoundRender_Core::render() +{ + isLocked = true; + Stats.Render.Begin(); for (CSoundRender_Target* T : s_targets) { if (T->get_emitter()) { - // Has emmitter, maybe just not started rendering + T->fill_parameters(); if (T->get_Rendering()) - { - T->fill_parameters(); T->update(); - } else - s_targets_defer.push_back(T); + T->render(); } } - // Commit parameters from pending targets - if (!s_targets_defer.empty()) - { - s_targets_defer.erase(std::unique(s_targets_defer.begin(), s_targets_defer.end()), s_targets_defer.end()); - for (CSoundRender_Target* target : s_targets_defer) - target->fill_parameters(); - } - - // update listener - update_listener(P, D, N, R, fTimer_Delta); - - // Start rendering of pending targets - if (!s_targets_defer.empty()) - { - for (CSoundRender_Target* target : s_targets_defer) - target->render(); - } - - // Events - for (CSoundRender_Scene* scene : m_scenes) - scene->update(); - + Stats.Render.End(); isLocked = false; - Stats.Update.End(); } void CSoundRender_Core::statistic(CSound_stats* dest, CSound_stats_ext* ext) @@ -178,6 +166,7 @@ void CSoundRender_Core::DumpStatistics(IGameFont& font, IPerformanceAlert* alert CSound_stats sndStat; statistic(&sndStat, nullptr); font.OutNext("*** SOUND: %2.2fms", Stats.Update.result); + font.OutNext(" RENDER: %2.2fms", Stats.Render.result); font.OutNext("Rendered: %d", sndStat._rendered); font.OutNext("Simulated: %d", sndStat._simulated); font.OutNext("Events: %d", sndStat._events); From 3fc41881a1b5174d1431585c9eb78375424b8983 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Mar 2024 09:05:08 +0500 Subject: [PATCH 248/497] xrSound: preload sound content right at the sound start --- src/xrSound/SoundRender_Target.cpp | 3 +++ src/xrSound/SoundRender_TargetA.cpp | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 41a47480ebb..cdff9c81835 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -31,12 +31,15 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) // Calc storage for (auto& buf : temp_buf) buf.resize(E->source()->m_info.bytesPerBuffer); + + dispatch_prefill_all(); } void CSoundRender_Target::render() { VERIFY(!rendering); rendering = true; + wait_prefill(); } void CSoundRender_Target::stop() diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 8779a8f09f5..c88bd0f950b 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -50,14 +50,13 @@ void CSoundRender_TargetA::_restart() void CSoundRender_TargetA::render() { - fill_all_blocks(); + inherited::render(); + submit_all_buffers(); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); - inherited::render(); - dispatch_prefill_all(); } From 2c231d79da20ea6757180b5726a6c80e72c1e6e5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 23 Mar 2024 20:48:45 +0500 Subject: [PATCH 249/497] Fix crash when switching sound to stSimulatingLooped state while there's prefill task active (fixes #1640) Addition to 958757e2c8b6737159803ec35f0cfcca3150e075 --- src/xrSound/SoundRender_Emitter_FSM.cpp | 2 +- src/xrSound/SoundRender_Emitter_StartStop.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index dfced028ed7..5e2eccd6d01 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -184,8 +184,8 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (!update_culling(dt)) { // switch to: SIMULATE - m_current_state = stSimulatingLooped; // switch state SoundRender->i_stop(this); + m_current_state = stSimulatingLooped; // switch state } else { diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index ecb184bdb5e..33854fafb1d 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -86,13 +86,13 @@ void CSoundRender_Emitter::cancel() { case stPlaying: // switch to: SIMULATE - m_current_state = stSimulating; // switch state SoundRender->i_stop(this); + m_current_state = stSimulating; // switch state break; case stPlayingLooped: // switch to: SIMULATE - m_current_state = stSimulatingLooped; // switch state SoundRender->i_stop(this); + m_current_state = stSimulatingLooped; // switch state break; default: FATAL("Non playing ref_sound forced out of render queue"); break; } From 2e482a4e7a1e079965b1485295cd7709770a3a79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:24:54 +0000 Subject: [PATCH 250/497] build(deps): bump Externals/zlib from `4a5e3e7` to `d201f04` Bumps [Externals/zlib](https://github.com/madler/zlib) from `4a5e3e7` to `d201f04`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/4a5e3e7d255f3f8eba9ecdb8bd8080db43bf0aeb...d201f04c72b0881220f5ba75ca19fd0e19fa848b) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 4a5e3e7d255..d201f04c72b 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 4a5e3e7d255f3f8eba9ecdb8bd8080db43bf0aeb +Subproject commit d201f04c72b0881220f5ba75ca19fd0e19fa848b From 270cff4a03a33d0dc400b4fcc3a0ef91afac00d1 Mon Sep 17 00:00:00 2001 From: Mikhail Bogdanov Date: Wed, 27 Mar 2024 11:17:26 +0300 Subject: [PATCH 251/497] CMake quotes in definitions (#1639) Co-authored-by: Sultan Uramaev --- cmake/utils.cmake | 4 ++-- src/xrCore/.GitInfo.cmd | 8 ++++---- src/xrCore/CMakeLists.txt | 14 +++++++------- src/xrCore/LocatorAPI.cpp | 2 +- src/xrCore/Threading/Lock.hpp | 1 + src/xrCore/xrCore.cpp | 21 ++++++++++++--------- src/xrCore/xrCore.vcxproj | 2 +- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index b85beb3b043..bcb7f46f4f1 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -24,7 +24,7 @@ function(target_sources_grouped) source_group(${PARSED_ARGS_NAME} FILES ${PARSED_ARGS_FILES}) endfunction() -function(set_git_info) +macro(set_git_info) execute_process(COMMAND git rev-parse --verify HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE GIT_SHA1 @@ -40,7 +40,7 @@ function(set_git_info) OUTPUT_STRIP_TRAILING_WHITESPACE ) message(STATUS "git branch: ${GIT_BRANCH}") -endfunction() +endmacro() function(calculate_xray_build_id output) set(XRAY_START_DAY 31) diff --git a/src/xrCore/.GitInfo.cmd b/src/xrCore/.GitInfo.cmd index 63a571cd495..90e12457c57 100644 --- a/src/xrCore/.GitInfo.cmd +++ b/src/xrCore/.GitInfo.cmd @@ -1,5 +1,5 @@ -echo | set /p dummyName=#define GIT_INFO_CURRENT_COMMIT > .GitInfo.hpp -git rev-parse --verify HEAD >> .GitInfo.hpp +@FOR /f "delims=" %%i in ('git rev-parse --verify HEAD') DO set COMMIT=%%i +echo #define GIT_INFO_CURRENT_COMMIT "%COMMIT%" > .GitInfo.hpp -echo | set /p dummyName=#define GIT_INFO_CURRENT_BRANCH >> .GitInfo.hpp -git rev-parse --abbrev-ref HEAD >> .GitInfo.hpp +@FOR /f "delims=" %%i in ('git rev-parse --abbrev-ref HEAD') DO set BRANCH=%%i +echo #define GIT_INFO_CURRENT_BRANCH "%BRANCH%" >> .GitInfo.hpp diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 83085473c2a..7c2874d306d 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -464,15 +464,15 @@ endif() target_compile_definitions(xrCore PRIVATE XRCORE_EXPORTS - CMAKE_INSTALL_FULL_LIBDIR=${CMAKE_INSTALL_FULL_LIBDIR} - CMAKE_INSTALL_FULL_DATAROOTDIR=${CMAKE_INSTALL_FULL_DATAROOTDIR} + CMAKE_INSTALL_FULL_LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\" + CMAKE_INSTALL_FULL_DATAROOTDIR=\"${CMAKE_INSTALL_FULL_DATAROOTDIR}\" CI=$ENV{CI} GITHUB_ACTIONS=$ENV{GITHUB_ACTIONS} - GITHUB_RUN_ID=$ENV{GITHUB_RUN_ID} - GITHUB_RUN_NUMBER=$ENV{GITHUB_RUN_NUMBER} - GITHUB_REPOSITORY=$ENV{GITHUB_REPOSITORY} - GIT_INFO_CURRENT_COMMIT=${GIT_SHA1} - GIT_INFO_CURRENT_BRANCH=${GIT_BRANCH} + GITHUB_RUN_ID=\"$ENV{GITHUB_RUN_ID}\" + GITHUB_RUN_NUMBER=\"$ENV{GITHUB_RUN_NUMBER}\" + GITHUB_REPOSITORY=\"$ENV{GITHUB_REPOSITORY}\" + GIT_INFO_CURRENT_COMMIT=\"${GIT_SHA1}\" + GIT_INFO_CURRENT_BRANCH=\"${GIT_BRANCH}\" ) if (MEMORY_ALLOCATOR STREQUAL "mimalloc") diff --git a/src/xrCore/LocatorAPI.cpp b/src/xrCore/LocatorAPI.cpp index b14f56bb490..ef8f9ce7db5 100644 --- a/src/xrCore/LocatorAPI.cpp +++ b/src/xrCore/LocatorAPI.cpp @@ -845,7 +845,7 @@ void CLocatorAPI::setup_fs_path(pcstr fs_name) * I propose adding shaders from /openxray/gamedata/shaders so that we remove unnecessary questions from users who want to start * the game using resources not from the proposed ~/.local/share/GSC Game World/Game in this case, this section of code can be safely removed */ chdir(pref_path); - static constexpr pcstr install_dir = MACRO_TO_STRING(CMAKE_INSTALL_FULL_DATAROOTDIR); + static constexpr pcstr install_dir = CMAKE_INSTALL_FULL_DATAROOTDIR; string_path tmp, tmp_link; xr_sprintf(tmp, "%sfsgame.ltx", pref_path); struct stat statbuf; diff --git a/src/xrCore/Threading/Lock.hpp b/src/xrCore/Threading/Lock.hpp index c9474fb8213..ddc0234cd78 100644 --- a/src/xrCore/Threading/Lock.hpp +++ b/src/xrCore/Threading/Lock.hpp @@ -4,6 +4,7 @@ #include "Common/Noncopyable.hpp" #ifdef CONFIG_PROFILE_LOCKS +#include "xrCore.h" typedef void (*add_profile_portion_callback)(LPCSTR id, const u64& time); void XRCORE_API set_add_profile_portion(add_profile_portion_callback callback); diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 42bdb0bf71f..fd01b84bdac 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -62,8 +62,8 @@ static u32 init_counter = 0; void SDLLogOutput(void* userdata, int category, SDL_LogPriority priority, const char* message); const pcstr xrCore::buildDate = __DATE__; -const pcstr xrCore::buildCommit = MACRO_TO_STRING(GIT_INFO_CURRENT_COMMIT); -const pcstr xrCore::buildBranch = MACRO_TO_STRING(GIT_INFO_CURRENT_BRANCH); +const pcstr xrCore::buildCommit = GIT_INFO_CURRENT_COMMIT; +const pcstr xrCore::buildBranch = GIT_INFO_CURRENT_BRANCH; xrCore::xrCore() : ApplicationName{}, ApplicationPath{}, @@ -117,14 +117,14 @@ void xrCore::PrintBuildInfo() #if defined(CI) # if defined(APPVEYOR) name = "AppVeyor"; - buildUniqueId = MACRO_TO_STRING(APPVEYOR_BUILD_ID); - buildId = MACRO_TO_STRING(APPVEYOR_BUILD_VERSION); - builder = MACRO_TO_STRING(APPVEYOR_ACCOUNT_NAME); + buildUniqueId = APPVEYOR_BUILD_ID; + buildId = APPVEYOR_BUILD_VERSION; + builder = APPVEYOR_ACCOUNT_NAME; # elif defined(GITHUB_ACTIONS) name = "GitHub Actions"; - buildUniqueId = MACRO_TO_STRING(GITHUB_RUN_ID); - buildId = MACRO_TO_STRING(GITHUB_RUN_NUMBER); - builder = MACRO_TO_STRING(GITHUB_REPOSITORY); + buildUniqueId = GITHUB_RUN_ID; + buildId = GITHUB_RUN_NUMBER; + builder = GITHUB_REPOSITORY; #else # pragma TODO("PrintBuildInfo for other CIs") name = "CI"; @@ -271,8 +271,11 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback c flags &= ~CLocatorAPI::flCacheFiles; #endif // _EDITOR - if (xr_stricmp(ApplicationPath, MACRO_TO_STRING(CMAKE_INSTALL_FULL_DATAROOTDIR)) != 0) +// TODO Add proper check for CMake Windows build +#if !defined(XR_PLATFORM_WINDOWS) + if (xr_stricmp(ApplicationPath, CMAKE_INSTALL_FULL_DATAROOTDIR) != 0) flags |= CLocatorAPI::flScanAppRoot; +#endif #ifndef _EDITOR #ifndef ELocatorAPIH diff --git a/src/xrCore/xrCore.vcxproj b/src/xrCore/xrCore.vcxproj index a8f7dd0af87..c31c6f74cf1 100644 --- a/src/xrCore/xrCore.vcxproj +++ b/src/xrCore/xrCore.vcxproj @@ -23,7 +23,7 @@ $(xrExternals)lzo\include;$(xrSdkDir)include\mimalloc;%(AdditionalIncludeDirectories) - _USRDLL;XRCORE_EXPORTS;CRYPTO_BUILD;CI=$(CI);APPVEYOR=$(APPVEYOR);APPVEYOR_BUILD_ID=$(APPVEYOR_BUILD_ID);APPVEYOR_BUILD_VERSION=$(APPVEYOR_BUILD_VERSION);APPVEYOR_ACCOUNT_NAME=$(APPVEYOR_ACCOUNT_NAME);GITHUB_ACTIONS=$(GITHUB_ACTIONS);GITHUB_RUN_ID=$(GITHUB_RUN_ID);GITHUB_RUN_NUMBER=$(GITHUB_RUN_NUMBER);GITHUB_REPOSITORY=$(GITHUB_REPOSITORY);%(PreprocessorDefinitions) + _USRDLL;XRCORE_EXPORTS;CRYPTO_BUILD;CI=$(CI);APPVEYOR=$(APPVEYOR);APPVEYOR_BUILD_ID="$(APPVEYOR_BUILD_ID)";APPVEYOR_BUILD_VERSION="$(APPVEYOR_BUILD_VERSION)";APPVEYOR_ACCOUNT_NAME="$(APPVEYOR_ACCOUNT_NAME)";GITHUB_ACTIONS=$(GITHUB_ACTIONS);GITHUB_RUN_ID="$(GITHUB_RUN_ID)";GITHUB_RUN_NUMBER="$(GITHUB_RUN_NUMBER)";GITHUB_REPOSITORY="$(GITHUB_REPOSITORY)";%(PreprocessorDefinitions) DbgHelp.lib;FaultRep.lib;jpeg-static.lib;%(AdditionalDependencies) From 36413944e08860f046df42ca9816bc4a5c62c471 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:04:11 +0000 Subject: [PATCH 252/497] build(deps): bump Externals/sse2neon from `1c258c4` to `8df2f48` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `1c258c4` to `8df2f48`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/1c258c41de900d94b09c5d45a15bcc8f0216332d...8df2f48dbd0674ae5087f7a6281af6f55fa5a8e2) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 1c258c41de9..8df2f48dbd0 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 1c258c41de900d94b09c5d45a15bcc8f0216332d +Subproject commit 8df2f48dbd0674ae5087f7a6281af6f55fa5a8e2 From f0f779790a1e89d27cf63cf5ed4e8d7417669c0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:04:13 +0000 Subject: [PATCH 253/497] build(deps): bump Externals/zlib from `d201f04` to `0f51fb4` Bumps [Externals/zlib](https://github.com/madler/zlib) from `d201f04` to `0f51fb4`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/d201f04c72b0881220f5ba75ca19fd0e19fa848b...0f51fb4933fc9ce18199cb2554dacea8033e7fd3) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index d201f04c72b..0f51fb4933f 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit d201f04c72b0881220f5ba75ca19fd0e19fa848b +Subproject commit 0f51fb4933fc9ce18199cb2554dacea8033e7fd3 From 0ece4cb28a65df016fac1ec55023597e6a8395a3 Mon Sep 17 00:00:00 2001 From: Pavel Rodionov Date: Fri, 5 Apr 2024 13:58:13 -0700 Subject: [PATCH 254/497] Fix SDL2::SDL2 target was not found (fixes #1595) (#1596) --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cfa8d64409b..07d6ee477f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,6 +231,16 @@ add_compile_definitions( if (NOT WIN32) find_package(SDL2 REQUIRED) + # Fix to support older SDL2 + # https://github.com/OpenXRay/xray-16/issues/1595 + if (NOT TARGET SDL2::SDL2 AND DEFINED SDL2_LIBRARIES) + add_library(SDL2::SDL2 UNKNOWN IMPORTED) + set_target_properties( + SDL2::SDL2 PROPERTIES + IMPORTED_LOCATION "${SDL2_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}" + ) + endif() find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) find_package(OpenAL REQUIRED) From 81e6f0097643b2a9c22f7eeeba2b462243e76caf Mon Sep 17 00:00:00 2001 From: Anton <36372201+antoncxx@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:07:59 -0400 Subject: [PATCH 255/497] [xrCore] Getting rid of LPCSTR type (#1628) --- src/xrCore/Animation/Motion.hpp | 4 +-- src/xrCore/Animation/SkeletonMotions.cpp | 4 +-- src/xrCore/Animation/SkeletonMotions.hpp | 4 +-- src/xrCore/FS.cpp | 4 +-- src/xrCore/FS.h | 4 +-- src/xrCore/FileCRC32.cpp | 4 +-- src/xrCore/FileCRC32.h | 4 +-- src/xrCore/FileSystem.cpp | 34 ++++++++++----------- src/xrCore/FileSystem.h | 30 +++++++++---------- src/xrCore/FileSystem_borland.cpp | 6 ++-- src/xrCore/LocatorAPI.cpp | 8 ++--- src/xrCore/LocatorAPI_defs.cpp | 16 +++++----- src/xrCore/LocatorAPI_defs.h | 10 +++---- src/xrCore/NET_utils.cpp | 10 +++---- src/xrCore/PostProcess/PPInfo.cpp | 2 +- src/xrCore/PostProcess/PPInfo.hpp | 2 +- src/xrCore/PostProcess/PostProcess.cpp | 6 ++-- src/xrCore/PostProcess/PostProcess.hpp | 6 ++-- src/xrCore/Threading/Lock.cpp | 4 +-- src/xrCore/Threading/Lock.hpp | 2 +- src/xrCore/_std_extensions.h | 22 +++++++------- src/xrCore/clsid.cpp | 2 +- src/xrCore/clsid.h | 2 +- src/xrCore/log.cpp | 38 ++++++++++++------------ src/xrCore/log.h | 34 ++++++++++----------- src/xrCore/net_utils.h | 2 +- src/xrCore/xrDebug.cpp | 4 +-- src/xrCore/xrDebug.h | 4 +-- 28 files changed, 136 insertions(+), 136 deletions(-) diff --git a/src/xrCore/Animation/Motion.hpp b/src/xrCore/Animation/Motion.hpp index 41b503a7c72..a77eca18b8b 100644 --- a/src/xrCore/Animation/Motion.hpp +++ b/src/xrCore/Animation/Motion.hpp @@ -40,7 +40,7 @@ struct st_BoneMotion m_Flags.zero(); ZeroMemory(envs, sizeof(CEnvelope*) * ctMaxChannel); } - void SetName(LPCSTR nm) { name = nm; } + void SetName(pcstr nm) { name = nm; } }; // vector по костям using BoneMotionVec = xr_vector; @@ -76,7 +76,7 @@ class XRCORE_API CCustomMotion } name = tmp; } - LPCSTR Name() { return name.c_str(); } + pcstr Name() { return name.c_str(); } int FrameStart() { return iFrameStart; } int FrameEnd() { return iFrameEnd; } float FPS() { return fFPS; } diff --git a/src/xrCore/Animation/SkeletonMotions.cpp b/src/xrCore/Animation/SkeletonMotions.cpp index 41cedbea6a9..efff81bfa31 100644 --- a/src/xrCore/Animation/SkeletonMotions.cpp +++ b/src/xrCore/Animation/SkeletonMotions.cpp @@ -22,7 +22,7 @@ u16 CPartition::part_id(const shared_str& name) const return u16(-1); } -void CPartition::load(IKinematics* V, LPCSTR model_name) +void CPartition::load(IKinematics* V, pcstr model_name) { string_path fn, fn_full; xr_strcpy(fn, sizeof(fn), model_name); @@ -74,7 +74,7 @@ u16 find_bone_id(vecBones* bones, shared_str nm) } //----------------------------------------------------------------------- -BOOL motions_value::load(LPCSTR N, IReader* data, vecBones* bones) +BOOL motions_value::load(pcstr N, IReader* data, vecBones* bones) { m_id = N; diff --git a/src/xrCore/Animation/SkeletonMotions.hpp b/src/xrCore/Animation/SkeletonMotions.hpp index 6e8f0fff54d..afc9222fc76 100644 --- a/src/xrCore/Animation/SkeletonMotions.hpp +++ b/src/xrCore/Animation/SkeletonMotions.hpp @@ -189,7 +189,7 @@ class XRCORE_API CPartition IC const CPartDef& part(u16 id) const { return P[id]; } [[nodiscard]] u16 part_id(const shared_str& name) const; [[nodiscard]] u32 mem_usage() const { return P[0].mem_usage() * MAX_PARTS; } - void load(IKinematics* V, LPCSTR model_name); + void load(IKinematics* V, pcstr model_name); [[nodiscard]] u8 count() const { @@ -214,7 +214,7 @@ struct XRCORE_API motions_value shared_str m_id; - BOOL load(LPCSTR N, IReader* data, vecBones* bones); + BOOL load(pcstr N, IReader* data, vecBones* bones); MotionVec* bone_motions(shared_str bone_name); u32 mem_usage() diff --git a/src/xrCore/FS.cpp b/src/xrCore/FS.cpp index b547650786b..6d1c8f5eaf9 100644 --- a/src/xrCore/FS.cpp +++ b/src/xrCore/FS.cpp @@ -18,7 +18,7 @@ u32 g_file_mapped_count = 0; typedef xr_map> FILE_MAPPINGS; FILE_MAPPINGS g_file_mappings; -void register_file_mapping(void* address, const u32& size, LPCSTR file_name) +void register_file_mapping(void* address, const u32& size, pcstr file_name) { FILE_MAPPINGS::const_iterator I = g_file_mappings.find(*(u32*)&address); VERIFY(I == g_file_mappings.end()); @@ -199,7 +199,7 @@ void CMemoryWriter::w(const void* ptr, size_t count) } // static const u32 mb_sz = 0x1000000; -bool CMemoryWriter::save_to(LPCSTR fn) const +bool CMemoryWriter::save_to(pcstr fn) const { IWriter* F = FS.w_open(fn); if (F) diff --git a/src/xrCore/FS.h b/src/xrCore/FS.h index 204df12520f..ccb4dad1706 100644 --- a/src/xrCore/FS.h +++ b/src/xrCore/FS.h @@ -26,7 +26,7 @@ XRCORE_API void VerifyPath(pcstr path); XRCORE_API extern u32 g_file_mapped_memory; XRCORE_API extern u32 g_file_mapped_count; XRCORE_API void dump_file_mappings(); -extern void register_file_mapping(void* address, const u32& size, LPCSTR file_name); +extern void register_file_mapping(void* address, const u32& size, pcstr file_name); extern void unregister_file_mapping(void* address, const u32& size); #endif // DEBUG @@ -161,7 +161,7 @@ class XRCORE_API CMemoryWriter final : public IWriter xr_free(data); } #pragma warning(pop) - bool save_to(LPCSTR fn) const; + bool save_to(pcstr fn) const; void flush() override {} }; diff --git a/src/xrCore/FileCRC32.cpp b/src/xrCore/FileCRC32.cpp index 5558e2f9c5b..546946b8263 100644 --- a/src/xrCore/FileCRC32.cpp +++ b/src/xrCore/FileCRC32.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "FileCRC32.h" -void getFileCrc32(IReader* F, LPCSTR filePath, u32& outCrc, bool parseIncludes) +void getFileCrc32(IReader* F, pcstr filePath, u32& outCrc, bool parseIncludes) { outCrc = crc32(F->pointer(), F->length(), outCrc); string4096 str; @@ -31,7 +31,7 @@ void getFileCrc32(IReader* F, LPCSTR filePath, u32& outCrc, bool parseIncludes) } } -void addFileCrc32(IReader* F, LPCSTR filePath, u32& outCrc, bool parseIncludes) +void addFileCrc32(IReader* F, pcstr filePath, u32& outCrc, bool parseIncludes) { u32 fileCrc = 0; getFileCrc32(F, filePath, fileCrc, parseIncludes); diff --git a/src/xrCore/FileCRC32.h b/src/xrCore/FileCRC32.h index bc931161d98..f5608539606 100644 --- a/src/xrCore/FileCRC32.h +++ b/src/xrCore/FileCRC32.h @@ -1,4 +1,4 @@ #pragma once -XRCORE_API void getFileCrc32(IReader* F, LPCSTR filePath, u32& outCrc, bool parseIncludes = true); // sets the value of outCrc -XRCORE_API void addFileCrc32(IReader* F, LPCSTR filePath, u32& outCrc, bool parseIncludes = true); // just adds to outCrc +XRCORE_API void getFileCrc32(IReader* F, pcstr filePath, u32& outCrc, bool parseIncludes = true); // sets the value of outCrc +XRCORE_API void addFileCrc32(IReader* F, pcstr filePath, u32& outCrc, bool parseIncludes = true); // just adds to outCrc diff --git a/src/xrCore/FileSystem.cpp b/src/xrCore/FileSystem.cpp index e3a0f75969e..00177629620 100644 --- a/src/xrCore/FileSystem.cpp +++ b/src/xrCore/FileSystem.cpp @@ -14,37 +14,37 @@ xr_unique_ptr xr_EFS; //---------------------------------------------------- -xr_string EFS_Utils::ExtractFileName(LPCSTR src) +xr_string EFS_Utils::ExtractFileName(pcstr src) { string_path name; _splitpath(src, 0, 0, name, 0); return xr_string(name); } -xr_string EFS_Utils::ExtractFileExt(LPCSTR src) +xr_string EFS_Utils::ExtractFileExt(pcstr src) { string_path ext; _splitpath(src, 0, 0, 0, ext); return xr_string(ext); } -xr_string EFS_Utils::ExtractFilePath(LPCSTR src) +xr_string EFS_Utils::ExtractFilePath(pcstr src) { string_path drive, dir; _splitpath(src, drive, dir, 0, 0); return xr_string(drive) + dir; } -xr_string EFS_Utils::ExcludeBasePath(LPCSTR full_path, LPCSTR excl_path) +xr_string EFS_Utils::ExcludeBasePath(pcstr full_path, pcstr excl_path) { - LPCSTR sub = strstr(full_path, excl_path); + pcstr sub = strstr(full_path, excl_path); if (0 != sub) return xr_string(sub + xr_strlen(excl_path)); else return xr_string(full_path); } -xr_string EFS_Utils::ChangeFileExt(LPCSTR src, LPCSTR ext) +xr_string EFS_Utils::ChangeFileExt(pcstr src, pcstr ext) { xr_string tmp; pstr src_ext = strext(src); @@ -61,9 +61,9 @@ xr_string EFS_Utils::ChangeFileExt(LPCSTR src, LPCSTR ext) return tmp; } -xr_string EFS_Utils::ChangeFileExt(const xr_string& src, LPCSTR ext) { return ChangeFileExt(src.c_str(), ext); } +xr_string EFS_Utils::ChangeFileExt(const xr_string& src, pcstr ext) { return ChangeFileExt(src.c_str(), ext); } //---------------------------------------------------- -void MakeFilter(string1024& dest, LPCSTR info, LPCSTR ext) +void MakeFilter(string1024& dest, pcstr info, pcstr ext) { std::string res; @@ -121,7 +121,7 @@ UINT_PTR CALLBACK OFNHookProcOldStyle(HWND, UINT, WPARAM, LPARAM) #endif bool EFS_Utils::GetOpenNameInternal( - LPCSTR initial, pstr buffer, size_t sz_buf, bool bMulti /*= false*/, LPCSTR offset /*= 0*/, int start_flt_ext /*= -1*/) + pcstr initial, pstr buffer, size_t sz_buf, bool bMulti /*= false*/, pcstr offset /*= 0*/, int start_flt_ext /*= -1*/) { VERIFY(buffer && (sz_buf > 0)); #if defined(XR_PLATFORM_WINDOWS) @@ -215,7 +215,7 @@ bool EFS_Utils::GetOpenNameInternal( #endif } -bool EFS_Utils::GetSaveName(LPCSTR initial, string_path& buffer, LPCSTR offset, int start_flt_ext) +bool EFS_Utils::GetSaveName(pcstr initial, string_path& buffer, pcstr offset, int start_flt_ext) { // unsigned int dwVersion = GetVersion(); // unsigned int dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); @@ -223,7 +223,7 @@ bool EFS_Utils::GetSaveName(LPCSTR initial, string_path& buffer, LPCSTR offset, FS_Path& P = *FS.get_path(initial); string1024 flt; - LPCSTR def_ext = P.m_DefExt; + pcstr def_ext = P.m_DefExt; if (false) //&& dwWindowsMajorVersion == 6 ) { if (strstr(P.m_DefExt, "*.")) @@ -281,18 +281,18 @@ bool EFS_Utils::GetSaveName(LPCSTR initial, string_path& buffer, LPCSTR offset, #endif } //---------------------------------------------------- -LPCSTR EFS_Utils::AppendFolderToName(pstr tex_name, size_t const tex_name_size, int depth, BOOL full_name) +pcstr EFS_Utils::AppendFolderToName(pstr tex_name, size_t const tex_name_size, int depth, BOOL full_name) { string256 _fn; xr_strcpy(tex_name, tex_name_size, AppendFolderToName(tex_name, _fn, sizeof(_fn), depth, full_name)); return tex_name; } -LPCSTR EFS_Utils::AppendFolderToName( - LPCSTR src_name, pstr dest_name, size_t const dest_name_size, int depth, BOOL full_name) +pcstr EFS_Utils::AppendFolderToName( + pcstr src_name, pstr dest_name, size_t const dest_name_size, int depth, BOOL full_name) { shared_str tmp = src_name; - LPCSTR s = src_name; + pcstr s = src_name; pstr d = dest_name; int sv_depth = depth; for (; *s && depth; s++, d++) @@ -322,8 +322,8 @@ LPCSTR EFS_Utils::AppendFolderToName( return dest_name; } -LPCSTR EFS_Utils::GenerateName( - LPCSTR base_path, LPCSTR base_name, LPCSTR def_ext, pstr out_name, size_t const out_name_size) +pcstr EFS_Utils::GenerateName( + pcstr base_path, pcstr base_name, pcstr def_ext, pstr out_name, size_t const out_name_size) { int cnt = 0; string_path fn; diff --git a/src/xrCore/FileSystem.h b/src/xrCore/FileSystem.h index 366ae395f29..f0e88cc9ea6 100644 --- a/src/xrCore/FileSystem.h +++ b/src/xrCore/FileSystem.h @@ -11,34 +11,34 @@ class XRCORE_API EFS_Utils { protected: bool GetOpenNameInternal( - LPCSTR initial, pstr buffer, size_t sz_buf, bool bMulti = false, LPCSTR offset = 0, int start_flt_ext = -1); + pcstr initial, pstr buffer, size_t sz_buf, bool bMulti = false, pcstr offset = 0, int start_flt_ext = -1); public: void _initialize() {} void _destroy() {} - LPCSTR GenerateName(LPCSTR base_path, LPCSTR base_name, LPCSTR def_ext, pstr out_name, size_t const out_name_size); + pcstr GenerateName(pcstr base_path, pcstr base_name, pcstr def_ext, pstr out_name, size_t const out_name_size); - bool GetOpenName(LPCSTR initial, string_path& buffer, int sz_buf, bool bMulti = false, LPCSTR offset = 0, + bool GetOpenName(pcstr initial, string_path& buffer, int sz_buf, bool bMulti = false, pcstr offset = 0, int start_flt_ext = -1); - bool GetOpenName(LPCSTR initial, xr_string& buf, bool bMulti = false, LPCSTR offset = 0, int start_flt_ext = -1); + bool GetOpenName(pcstr initial, xr_string& buf, bool bMulti = false, pcstr offset = 0, int start_flt_ext = -1); - bool GetSaveName(LPCSTR initial, string_path& buffer, LPCSTR offset = 0, int start_flt_ext = -1); - bool GetSaveName(LPCSTR initial, xr_string& buf, LPCSTR offset = 0, int start_flt_ext = -1); + bool GetSaveName(pcstr initial, string_path& buffer, pcstr offset = 0, int start_flt_ext = -1); + bool GetSaveName(pcstr initial, xr_string& buf, pcstr offset = 0, int start_flt_ext = -1); - void MarkFile(LPCSTR fn, bool bDeleteSource); + void MarkFile(pcstr fn, bool bDeleteSource); xr_string AppendFolderToName(xr_string& tex_name, int depth, BOOL full_name); - LPCSTR AppendFolderToName(pstr tex_name, size_t const tex_name_size, int depth, BOOL full_name); - LPCSTR AppendFolderToName(LPCSTR src_name, pstr dest_name, size_t const dest_name_size, int depth, BOOL full_name); + pcstr AppendFolderToName(pstr tex_name, size_t const tex_name_size, int depth, BOOL full_name); + pcstr AppendFolderToName(pcstr src_name, pstr dest_name, size_t const dest_name_size, int depth, BOOL full_name); - xr_string ChangeFileExt(LPCSTR src, LPCSTR ext); - xr_string ChangeFileExt(const xr_string& src, LPCSTR ext); + xr_string ChangeFileExt(pcstr src, pcstr ext); + xr_string ChangeFileExt(const xr_string& src, pcstr ext); - static xr_string ExtractFileName(LPCSTR src); - static xr_string ExtractFilePath(LPCSTR src); - static xr_string ExtractFileExt(LPCSTR src); - static xr_string ExcludeBasePath(LPCSTR full_path, LPCSTR excl_path); + static xr_string ExtractFileName(pcstr src); + static xr_string ExtractFilePath(pcstr src); + static xr_string ExtractFileExt(pcstr src); + static xr_string ExcludeBasePath(pcstr full_path, pcstr excl_path); }; extern XRCORE_API xr_unique_ptr xr_EFS; #define EFS (*xr_EFS) diff --git a/src/xrCore/FileSystem_borland.cpp b/src/xrCore/FileSystem_borland.cpp index b22bb28fff8..08fc76e23e5 100644 --- a/src/xrCore/FileSystem_borland.cpp +++ b/src/xrCore/FileSystem_borland.cpp @@ -19,7 +19,7 @@ int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpDa return 0; } -bool EFS_Utils::GetOpenName(LPCSTR initial, xr_string& buffer, bool bMulti, LPCSTR offset, int start_flt_ext) +bool EFS_Utils::GetOpenName(pcstr initial, xr_string& buffer, bool bMulti, pcstr offset, int start_flt_ext) { char buf[255 * 255]; // max files to select xr_strcpy(buf, buffer.c_str()); @@ -50,7 +50,7 @@ bool EFS_Utils::GetOpenName(LPCSTR initial, xr_string& buffer, bool bMulti, LPCS return bRes; } -bool EFS_Utils::GetSaveName(LPCSTR initial, xr_string& buffer, LPCSTR offset, int start_flt_ext) +bool EFS_Utils::GetSaveName(pcstr initial, xr_string& buffer, pcstr offset, int start_flt_ext) { string_path buf; xr_strcpy(buf, sizeof(buf), buffer.c_str()); @@ -62,7 +62,7 @@ bool EFS_Utils::GetSaveName(LPCSTR initial, xr_string& buffer, LPCSTR offset, in } //---------------------------------------------------- -void EFS_Utils::MarkFile(LPCSTR fn, bool bDeleteSource) +void EFS_Utils::MarkFile(pcstr fn, bool bDeleteSource) { xr_string ext = strext(fn); ext.insert(1, "~"); diff --git a/src/xrCore/LocatorAPI.cpp b/src/xrCore/LocatorAPI.cpp index ef8f9ce7db5..6d53698fb44 100644 --- a/src/xrCore/LocatorAPI.cpp +++ b/src/xrCore/LocatorAPI.cpp @@ -1232,7 +1232,7 @@ size_t CLocatorAPI::file_list(FS_FileSet& dest, pcstr path, u32 flags /*= FS_Lis // file if ((flags & FS_ListFiles) == 0) continue; - LPCSTR entry_begin = entry.name + base_len; + pcstr entry_begin = entry.name + base_len; if (flags & FS_RootOnly && strchr(entry_begin, _DELIMITER)) continue; // folder in folder // check extension @@ -1266,7 +1266,7 @@ size_t CLocatorAPI::file_list(FS_FileSet& dest, pcstr path, u32 flags /*= FS_Lis // folder if ((flags & FS_ListFolders) == 0) continue; - LPCSTR entry_begin = entry.name + base_len; + pcstr entry_begin = entry.name + base_len; if (flags & FS_RootOnly && strchr(entry_begin, _DELIMITER) != end_symbol) continue; // folder in folder @@ -1286,9 +1286,9 @@ void CLocatorAPI::check_cached_files(pstr fname, const size_t& fname_size, const if (!path_exist("$server_root$")) return; - LPCSTR path_base = get_path("$server_root$")->m_Path; + pcstr path_base = get_path("$server_root$")->m_Path; size_t len_base = xr_strlen(path_base); - LPCSTR path_file = fname; + pcstr path_file = fname; const size_t len_file = xr_strlen(path_file); if (len_file <= len_base) return; diff --git a/src/xrCore/LocatorAPI_defs.cpp b/src/xrCore/LocatorAPI_defs.cpp index 50c465e9af0..eeee687f338 100644 --- a/src/xrCore/LocatorAPI_defs.cpp +++ b/src/xrCore/LocatorAPI_defs.cpp @@ -33,7 +33,7 @@ void FS_File::set(const xr_string& nm, long sz, time_t modif, unsigned attr) ////////////////////////////////////////////////////////////////////// // FS_Path ////////////////////////////////////////////////////////////////////// -FS_Path::FS_Path(LPCSTR _Root, LPCSTR _Add, LPCSTR _DefExt, LPCSTR _FilterCaption, u32 flags) +FS_Path::FS_Path(pcstr _Root, pcstr _Add, pcstr _DefExt, pcstr _FilterCaption, u32 flags) { // VERIFY (_Root&&_Root[0]); string_path temp; @@ -64,7 +64,7 @@ FS_Path::~FS_Path() xr_free(m_FilterCaption); } -void FS_Path::_set(LPCSTR add) +void FS_Path::_set(pcstr add) { // m_Add R_ASSERT(add); @@ -80,7 +80,7 @@ void FS_Path::_set(LPCSTR add) m_Path = xr_fs_strlwr(xr_strdup(temp)); } -void FS_Path::_set_root(LPCSTR root) +void FS_Path::_set_root(pcstr root) { string_path temp; xr_strcpy(temp, root); @@ -97,7 +97,7 @@ void FS_Path::_set_root(LPCSTR root) m_Path = xr_fs_strlwr(xr_strdup(temp)); } -LPCSTR FS_Path::_update(string_path& dest, LPCSTR src) const +pcstr FS_Path::_update(string_path& dest, pcstr src) const { R_ASSERT(dest); R_ASSERT(src); @@ -119,7 +119,7 @@ LPCSTR FS_Path::_update(string_path& dest, LPCSTR src) const return xr_fs_strlwr(dest); } /* -void FS_Path::_update(xr_string& dest, LPCSTR src)const +void FS_Path::_update(xr_string& dest, pcstr src)const { R_ASSERT(src); dest = xr_string(m_Path)+src; @@ -131,10 +131,10 @@ void FS_Path::rescan_path_cb() FS.m_Flags.set(CLocatorAPI::flNeedRescan, TRUE); } -bool XRCORE_API PatternMatch(LPCSTR s, LPCSTR mask) +bool XRCORE_API PatternMatch(pcstr s, pcstr mask) { - LPCSTR cp = 0; - LPCSTR mp = 0; + pcstr cp = 0; + pcstr mp = 0; for (; *s && *mask != '*'; mask++, s++) if (*mask != *s && *mask != '?') return false; diff --git a/src/xrCore/LocatorAPI_defs.h b/src/xrCore/LocatorAPI_defs.h index 671d32d3130..df0572ee1f5 100644 --- a/src/xrCore/LocatorAPI_defs.h +++ b/src/xrCore/LocatorAPI_defs.h @@ -30,11 +30,11 @@ class XRCORE_API FS_Path Flags32 m_Flags; public: - FS_Path(LPCSTR _Root, LPCSTR _Add, LPCSTR _DefExt = 0, LPCSTR _FilterString = 0, u32 flags = 0); + FS_Path(pcstr _Root, pcstr _Add, pcstr _DefExt = 0, pcstr _FilterString = 0, u32 flags = 0); ~FS_Path(); - LPCSTR _update(string_path& dest, LPCSTR src) const; - void _set(LPCSTR add); - void _set_root(LPCSTR root); + pcstr _update(string_path& dest, pcstr src) const; + void _set(pcstr add); + void _set_root(pcstr root); void rescan_path_cb(); }; @@ -65,6 +65,6 @@ struct XRCORE_API FS_File }; using FS_FileSet = xr_set; -extern bool XRCORE_API PatternMatch(LPCSTR s, LPCSTR mask); +extern bool XRCORE_API PatternMatch(pcstr s, pcstr mask); #endif // LocatorAPI_defsH diff --git a/src/xrCore/NET_utils.cpp b/src/xrCore/NET_utils.cpp index 9a8f6e09897..8d63bb23ed5 100644 --- a/src/xrCore/NET_utils.cpp +++ b/src/xrCore/NET_utils.cpp @@ -395,7 +395,7 @@ void NET_Packet::r_stringZ(pstr S) { if (!inistream) { - LPCSTR data = LPCSTR(&B.data[r_pos]); + pcstr data = pcstr(&B.data[r_pos]); size_t len = xr_strlen(data); r(S, (u32)len + 1); } @@ -409,7 +409,7 @@ void NET_Packet::r_stringZ(xr_string& dest) { if (!inistream) { - dest = LPCSTR(&B.data[r_pos]); + dest = pcstr(&B.data[r_pos]); r_advance(u32(dest.size() + 1)); } else @@ -424,7 +424,7 @@ void NET_Packet::r_stringZ(shared_str& dest) { if (!inistream) { - dest = LPCSTR(&B.data[r_pos]); + dest = pcstr(&B.data[r_pos]); r_advance(dest.size() + 1); } else @@ -439,7 +439,7 @@ void NET_Packet::skip_stringZ() { if (!inistream) { - LPCSTR data = LPCSTR(&B.data[r_pos]); + pcstr data = pcstr(&B.data[r_pos]); u32 len = xr_strlen(data); r_advance(len + 1); } @@ -476,7 +476,7 @@ void NET_Packet::r_stringZ_s(pstr string, u32 const size) return; } - LPCSTR data = LPCSTR(B.data + r_pos); + pcstr data = pcstr(B.data + r_pos); u32 length = xr_strlen(data); R_ASSERT2((length + 1) <= size, "buffer overrun"); r(string, length + 1); diff --git a/src/xrCore/PostProcess/PPInfo.cpp b/src/xrCore/PostProcess/PPInfo.cpp index 872cbd7d40d..9000cbb6eb6 100644 --- a/src/xrCore/PostProcess/PPInfo.cpp +++ b/src/xrCore/PostProcess/PPInfo.cpp @@ -58,7 +58,7 @@ SPPInfo::SPPInfo() cm_interpolate = 0.0f; } void SPPInfo::normalize() {} -void SPPInfo::validate(LPCSTR str) +void SPPInfo::validate(pcstr str) { VERIFY2(_valid(duality.h), str); VERIFY2(_valid(duality.v), str); diff --git a/src/xrCore/PostProcess/PPInfo.hpp b/src/xrCore/PostProcess/PPInfo.hpp index 801fac421aa..73cc4796f56 100644 --- a/src/xrCore/PostProcess/PPInfo.hpp +++ b/src/xrCore/PostProcess/PPInfo.hpp @@ -80,5 +80,5 @@ struct XRCORE_API SPPInfo void normalize(); SPPInfo(); SPPInfo& lerp(const SPPInfo& def, const SPPInfo& to, float factor); - void validate(LPCSTR str); + void validate(pcstr str); }; diff --git a/src/xrCore/PostProcess/PostProcess.cpp b/src/xrCore/PostProcess/PostProcess.cpp index d5b534c828e..aa217a2f915 100644 --- a/src/xrCore/PostProcess/PostProcess.cpp +++ b/src/xrCore/PostProcess/PostProcess.cpp @@ -32,7 +32,7 @@ void BasicPostProcessAnimator::Clear() xr_delete(m_Params[a]); } -void BasicPostProcessAnimator::Load(LPCSTR name, bool internalFs /*= true*/) +void BasicPostProcessAnimator::Load(pcstr name, bool internalFs /*= true*/) { m_Name = name; string_path full_path; @@ -47,7 +47,7 @@ void BasicPostProcessAnimator::Load(LPCSTR name, bool internalFs /*= true*/) else xr_strcpy(full_path, name); - LPCSTR ext = strext(full_path); + pcstr ext = strext(full_path); if (ext) { if (!xr_strcmp(ext, POSTPROCESS_FILE_EXTENSION)) @@ -200,7 +200,7 @@ CPostProcessParam* BasicPostProcessAnimator::GetParam(pp_params param) return m_Params[param]; } -void BasicPostProcessAnimator::Save(LPCSTR name) +void BasicPostProcessAnimator::Save(pcstr name) { IWriter* W = FS.w_open(name); VERIFY(W); diff --git a/src/xrCore/PostProcess/PostProcess.hpp b/src/xrCore/PostProcess/PostProcess.hpp index 5962511e11d..a0c13a86340 100644 --- a/src/xrCore/PostProcess/PostProcess.hpp +++ b/src/xrCore/PostProcess/PostProcess.hpp @@ -142,8 +142,8 @@ class XRCORE_API BasicPostProcessAnimator BasicPostProcessAnimator(); virtual ~BasicPostProcessAnimator(); void Clear(); - virtual void Load(LPCSTR name, bool internalFs = true); - IC LPCSTR Name() { return *m_Name; } + virtual void Load(pcstr name, bool internalFs = true); + IC pcstr Name() { return *m_Name; } virtual void Stop(float speed); void SetDesiredFactor(float f, float sp); void SetCurrentFactor(float f); @@ -154,5 +154,5 @@ class XRCORE_API BasicPostProcessAnimator void Create(); CPostProcessParam* GetParam(pp_params param); void ResetParam(pp_params param); - void Save(LPCSTR name); + void Save(pcstr name); }; diff --git a/src/xrCore/Threading/Lock.cpp b/src/xrCore/Threading/Lock.cpp index 8fc9934f7d1..782ca49c719 100644 --- a/src/xrCore/Threading/Lock.cpp +++ b/src/xrCore/Threading/Lock.cpp @@ -28,9 +28,9 @@ void set_add_profile_portion(add_profile_portion_callback callback) { add_profil struct profiler { u64 m_time; - LPCSTR m_timer_id; + pcstr m_timer_id; - IC profiler::profiler(LPCSTR timer_id) + IC profiler::profiler(pcstr timer_id) { if (!add_profile_portion) return; diff --git a/src/xrCore/Threading/Lock.hpp b/src/xrCore/Threading/Lock.hpp index ddc0234cd78..714fbf5635c 100644 --- a/src/xrCore/Threading/Lock.hpp +++ b/src/xrCore/Threading/Lock.hpp @@ -5,7 +5,7 @@ #ifdef CONFIG_PROFILE_LOCKS #include "xrCore.h" -typedef void (*add_profile_portion_callback)(LPCSTR id, const u64& time); +typedef void (*add_profile_portion_callback)(pcstr id, const u64& time); void XRCORE_API set_add_profile_portion(add_profile_portion_callback callback); #define MUTEX_PROFILE_PREFIX_ID #mutexes / diff --git a/src/xrCore/_std_extensions.h b/src/xrCore/_std_extensions.h index 12db63e71c8..a13aa34f6ed 100644 --- a/src/xrCore/_std_extensions.h +++ b/src/xrCore/_std_extensions.h @@ -142,17 +142,17 @@ IC size_t xr_strlen(const char* S) { return strlen(S); } #ifndef MASTER_GOLD -inline int xr_strcpy(pstr destination, size_t const destination_size, LPCSTR source) +inline int xr_strcpy(pstr destination, size_t const destination_size, pcstr source) { return strcpy_s(destination, destination_size, source); } -inline int xr_strcat(pstr destination, size_t const buffer_size, LPCSTR source) +inline int xr_strcat(pstr destination, size_t const buffer_size, pcstr source) { return strcat_s(destination, buffer_size, source); } -inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, LPCSTR format_string, ...) +inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, pcstr format_string, ...) { va_list args; va_start(args, format_string); @@ -162,7 +162,7 @@ inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, LPCSTR } template -inline int __cdecl xr_sprintf(char (&destination)[count], LPCSTR format_string, ...) +inline int __cdecl xr_sprintf(char (&destination)[count], pcstr format_string, ...) { va_list args; va_start(args, format_string); @@ -172,12 +172,12 @@ inline int __cdecl xr_sprintf(char (&destination)[count], LPCSTR format_string, } #else // #ifndef MASTER_GOLD -inline int xr_strcpy(pstr destination, size_t const destination_size, LPCSTR source) +inline int xr_strcpy(pstr destination, size_t const destination_size, pcstr source) { return strncpy_s(destination, destination_size, source, destination_size); } -inline int xr_strcat(pstr destination, size_t const buffer_size, LPCSTR source) +inline int xr_strcat(pstr destination, size_t const buffer_size, pcstr source) { size_t const destination_length = xr_strlen(destination); pstr i = destination + destination_length; @@ -185,14 +185,14 @@ inline int xr_strcat(pstr destination, size_t const buffer_size, LPCSTR source) if (i > e) return 0; - for (LPCSTR j = source; *j && (i != e); ++i, ++j) + for (pcstr j = source; *j && (i != e); ++i, ++j) *i = *j; *i = 0; return 0; } -inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, LPCSTR format_string, ...) +inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, pcstr format_string, ...) { va_list args; va_start(args, format_string); @@ -202,7 +202,7 @@ inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, LPCSTR } template -inline int __cdecl xr_sprintf(char (&destination)[count], LPCSTR format_string, ...) +inline int __cdecl xr_sprintf(char (&destination)[count], pcstr format_string, ...) { va_list args; va_start(args, format_string); @@ -213,13 +213,13 @@ inline int __cdecl xr_sprintf(char (&destination)[count], LPCSTR format_string, #endif // #ifndef MASTER_GOLD template -inline int xr_strcpy(char(&destination)[count], LPCSTR source) +inline int xr_strcpy(char (&destination)[count], pcstr source) { return xr_strcpy(destination, count, source); } template -inline int xr_strcat(char(&destination)[count], LPCSTR source) +inline int xr_strcat(char (&destination)[count], pcstr source) { return xr_strcat(destination, count, source); } diff --git a/src/xrCore/clsid.cpp b/src/xrCore/clsid.cpp index 0e26e28967b..64b87fe3b9e 100644 --- a/src/xrCore/clsid.cpp +++ b/src/xrCore/clsid.cpp @@ -10,7 +10,7 @@ XRCORE_API void CLSID2TEXT(CLASS_ID id, pstr text) id >>= 8; } } -XRCORE_API CLASS_ID TEXT2CLSID(LPCSTR text) +XRCORE_API CLASS_ID TEXT2CLSID(pcstr text) { VERIFY3(xr_strlen(text) <= 8, "Beer from creator CLASS_ID:", text); char buf[9]; diff --git a/src/xrCore/clsid.h b/src/xrCore/clsid.h index 5abefcc4c42..289c28f0f03 100644 --- a/src/xrCore/clsid.h +++ b/src/xrCore/clsid.h @@ -13,4 +13,4 @@ using CLASS_ID = u64; #define MK_CLSID_INV(a, b, c, d, e, f, g, h) MK_CLSID(h, g, f, e, d, c, b, a) extern XRCORE_API void CLSID2TEXT(CLASS_ID id, pstr text); -extern XRCORE_API CLASS_ID TEXT2CLSID(LPCSTR text); +extern XRCORE_API CLASS_ID TEXT2CLSID(pcstr text); diff --git a/src/xrCore/log.cpp b/src/xrCore/log.cpp index 9d515ccedbd..6010cd02d8c 100644 --- a/src/xrCore/log.cpp +++ b/src/xrCore/log.cpp @@ -6,10 +6,10 @@ #include "log.h" #include "xrCore/Threading/Lock.hpp" -BOOL LogExecCB = TRUE; +bool LogExecCB = true; string_path logFName = "engine.log"; string_path log_file_name = "engine.log"; -BOOL no_log = TRUE; +bool no_log = true; #ifdef CONFIG_PROFILE_LOCKS Lock logCS(MUTEX_PROFILE_ID(log)); #else // CONFIG_PROFILE_LOCKS @@ -34,7 +34,7 @@ void FlushLog() } } -void AddOne(const char* split) +void AddOne(pcstr split) { logCS.Enter(); @@ -77,7 +77,7 @@ void AddOne(const char* split) logCS.Leave(); } -void Log(const char* s) +void Log(pcstr s) { int i, j; @@ -105,7 +105,7 @@ void Log(const char* s) AddOne(split); } -void __cdecl Msg(const char* format, ...) +void __cdecl Msg(pcstr format, ...) { va_list mark; string2048 buf; @@ -117,7 +117,7 @@ void __cdecl Msg(const char* format, ...) Log(buf); } -void Log(const char* msg, const char* dop) +void Log(pcstr msg, pcstr dop) { if (!dop) { @@ -131,7 +131,7 @@ void Log(const char* msg, const char* dop) Log(buf); } -void Log(const char* msg, int dop) +void Log(pcstr msg, int dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 11 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -140,7 +140,7 @@ void Log(const char* msg, int dop) Log(buf); } -void Log(const char* msg, unsigned int dop) +void Log(pcstr msg, unsigned int dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 10 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -149,7 +149,7 @@ void Log(const char* msg, unsigned int dop) Log(buf); } -void Log(const char* msg, long dop) +void Log(pcstr msg, long dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -158,7 +158,7 @@ void Log(const char* msg, long dop) Log(buf); } -void Log(const char* msg, unsigned long dop) +void Log(pcstr msg, unsigned long dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -167,7 +167,7 @@ void Log(const char* msg, unsigned long dop) Log(buf); } -void Log(const char* msg, long long dop) +void Log(pcstr msg, long long dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -176,7 +176,7 @@ void Log(const char* msg, long long dop) Log(buf); } -void Log(const char* msg, unsigned long long dop) +void Log(pcstr msg, unsigned long long dop) { const u32 buffer_size = (xr_strlen(msg) + 1 + 64 + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -185,7 +185,7 @@ void Log(const char* msg, unsigned long long dop) Log(buf); } -void Log(const char* msg, float dop) +void Log(pcstr msg, float dop) { // actually, float string representation should be no more, than 40 characters, // but we will count with slight overhead @@ -196,7 +196,7 @@ void Log(const char* msg, float dop) Log(buf); } -void Log(const char* msg, const Fvector& dop) +void Log(pcstr msg, const Fvector& dop) { const u32 buffer_size = (xr_strlen(msg) + 2 + 3 * (64 + 1) + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -205,7 +205,7 @@ void Log(const char* msg, const Fvector& dop) Log(buf); } -void Log(const char* msg, const Fmatrix& dop) +void Log(pcstr msg, const Fmatrix& dop) { const u32 buffer_size = (xr_strlen(msg) + 2 + 4 * (4 * (64 + 1) + 1) + 1) * sizeof(char); pstr buf = static_cast(xr_alloca(buffer_size)); @@ -216,7 +216,7 @@ void Log(const char* msg, const Fmatrix& dop) Log(buf); } -void LogWinErr(const char* msg, long err_code) { Msg("%s: %s", msg, xrDebug::ErrorToString(err_code)); } +void LogWinErr(pcstr msg, long err_code) { Msg("%s: %s", msg, xrDebug::ErrorToString(err_code)); } LogCallback SetLogCB(const LogCallback& cb) { const LogCallback result = LogCB; @@ -224,9 +224,9 @@ LogCallback SetLogCB(const LogCallback& cb) return (result); } -LPCSTR log_name() { return (log_file_name); } +pcstr log_name() { return (log_file_name); } -void CreateLog(BOOL nl) +void CreateLog(bool nl) { LogFile.reserve(1000); @@ -259,7 +259,7 @@ void CreateLog(BOOL nl) for (u32 it = 0; it < LogFile.size(); it++) { - LPCSTR s = LogFile[it].c_str(); + pcstr s = LogFile[it].c_str(); #ifdef USE_LOG_TIMING LogWriter->w_printf("%s%s\r\n", buf, s ? s : ""); #else diff --git a/src/xrCore/log.h b/src/xrCore/log.h index 5465854af93..f436fbd73c6 100644 --- a/src/xrCore/log.h +++ b/src/xrCore/log.h @@ -10,21 +10,21 @@ template struct _matrix; typedef _matrix Fmatrix; #define VPUSH(a) ((a).x), ((a).y), ((a).z) -void XRCORE_API __cdecl Msg(LPCSTR format, ...); - -void XRCORE_API Log(LPCSTR msg); -void XRCORE_API Log(LPCSTR msg, LPCSTR dop); -void XRCORE_API Log(LPCSTR msg, int dop); -void XRCORE_API Log(LPCSTR msg, unsigned int dop); -void XRCORE_API Log(LPCSTR msg, long dop); -void XRCORE_API Log(LPCSTR msg, unsigned long dop); -void XRCORE_API Log(LPCSTR msg, long long dop); -void XRCORE_API Log(LPCSTR msg, unsigned long long dop); -void XRCORE_API Log(LPCSTR msg, float dop); -void XRCORE_API Log(LPCSTR msg, const Fvector& dop); -void XRCORE_API Log(LPCSTR msg, const Fmatrix& dop); - -void XRCORE_API LogWinErr(LPCSTR msg, long err_code); +void XRCORE_API __cdecl Msg(pcstr format, ...); + +void XRCORE_API Log(pcstr msg); +void XRCORE_API Log(pcstr msg, pcstr dop); +void XRCORE_API Log(pcstr msg, int dop); +void XRCORE_API Log(pcstr msg, unsigned int dop); +void XRCORE_API Log(pcstr msg, long dop); +void XRCORE_API Log(pcstr msg, unsigned long dop); +void XRCORE_API Log(pcstr msg, long long dop); +void XRCORE_API Log(pcstr msg, unsigned long long dop); +void XRCORE_API Log(pcstr msg, float dop); +void XRCORE_API Log(pcstr msg, const Fvector& dop); +void XRCORE_API Log(pcstr msg, const Fmatrix& dop); + +void XRCORE_API LogWinErr(pcstr msg, long err_code); struct LogCallback { @@ -40,12 +40,12 @@ struct LogCallback }; LogCallback XRCORE_API SetLogCB(const LogCallback& cb); -void XRCORE_API CreateLog(BOOL no_log = FALSE); +void XRCORE_API CreateLog(bool no_log = false); void InitLog(); void CloseLog(); void XRCORE_API FlushLog(); extern XRCORE_API xr_vector LogFile; -extern XRCORE_API BOOL LogExecCB; +extern XRCORE_API bool LogExecCB; #endif diff --git a/src/xrCore/net_utils.h b/src/xrCore/net_utils.h index a17d07fe471..9aa23ac7b6c 100644 --- a/src/xrCore/net_utils.h +++ b/src/xrCore/net_utils.h @@ -33,7 +33,7 @@ struct XRCORE_API IIniFileStream virtual void __stdcall w_s16(s16 a) = 0; virtual void __stdcall w_u8(u8 a) = 0; virtual void __stdcall w_s8(s8 a) = 0; - virtual void __stdcall w_stringZ(LPCSTR S) = 0; + virtual void __stdcall w_stringZ(pcstr S) = 0; virtual void __stdcall r_vec3(Fvector&) = 0; virtual void __stdcall r_vec4(Fvector4&) = 0; diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 5799aeac99b..04708228347 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -587,7 +587,7 @@ void xrDebug::DoExit(const std::string& message) windowHandler->OnErrorDialog(false); } -LPCSTR xrDebug::ErrorToString(long code) +pcstr xrDebug::ErrorToString(long code) { const char* result = nullptr; #if defined(XR_PLATFORM_WINDOWS) @@ -620,7 +620,7 @@ int out_of_memory_handler(size_t size) return 1; } -extern LPCSTR log_name(); +extern pcstr log_name(); void WINAPI xrDebug::PreErrorHandler(INT_PTR) { diff --git a/src/xrCore/xrDebug.h b/src/xrCore/xrDebug.h index dfa40f57204..0c7d0645c07 100644 --- a/src/xrCore/xrDebug.h +++ b/src/xrCore/xrDebug.h @@ -102,7 +102,7 @@ class XRCORE_API xrDebug static void SetUserConfigHandler(IUserConfigHandler* handler) { userConfigHandler = handler; } static OutOfMemoryCallbackFunc GetOutOfMemoryCallback() { return OutOfMemoryCallback; } static void SetOutOfMemoryCallback(OutOfMemoryCallbackFunc cb) { OutOfMemoryCallback = cb; } - static const char* ErrorToString(long code); + static pcstr ErrorToString(long code); static void SetBugReportFile(const char* fileName); static void GatherInfo(char* assertionInfo, size_t bufferSize, const ErrorLocation& loc, const char* expr, const char* desc, const char* arg1 = nullptr, const char* arg2 = nullptr); @@ -140,7 +140,7 @@ class XRCORE_API xrDebug // forward declaration // Definition is in xrCore/_std_extensions.h -inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, LPCSTR format_string, ...); +inline int __cdecl xr_sprintf(pstr destination, size_t const buffer_size, pcstr format_string, ...); // for debug purposes only template From 2ce53f0871eb034b758665622d9338dcb4db5e67 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Fri, 5 Apr 2024 23:14:33 +0200 Subject: [PATCH 256/497] Sanitize `UserName` and `CompName` (#1538) --- src/xrCore/xrCore.cpp | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index fd01b84bdac..e6cbd62b0bf 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -65,6 +65,26 @@ const pcstr xrCore::buildDate = __DATE__; const pcstr xrCore::buildCommit = GIT_INFO_CURRENT_COMMIT; const pcstr xrCore::buildBranch = GIT_INFO_CURRENT_BRANCH; +void SanitizeString(pcstr str) +{ + pstr mut_str = const_cast(str); + + while (*mut_str != '\0') + { + switch (*mut_str) + { + case '\\': + case '/': + case ',': + case '.': + *mut_str = '_'; + [[fallthrough]]; + default: + ++mut_str; + } + } +} + xrCore::xrCore() : ApplicationName{}, ApplicationPath{}, WorkingPath{}, @@ -221,21 +241,31 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback c #elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) uid_t uid = geteuid(); struct passwd *pw = getpwuid(uid); - if(pw) + if (pw) { - strcpy(UserName, pw->pw_gecos); - char* pos = strchr(UserName, ','); // pw_gecos return string - if(NULL != pos) - *pos = 0; - if(0 == UserName[0]) - strcpy(UserName, pw->pw_name); + strncpy(UserName, pw->pw_gecos, sizeof(UserName) - 1); + if (UserName[0] == '\0') + strncpy(UserName, pw->pw_name, sizeof(UserName) - 1); } + else + Msg("! Failed to get user name"); - gethostname(CompName, sizeof(CompName)); + if (gethostname(CompName, sizeof(CompName)) == 0) + CompName[sizeof(CompName) - 1] = '\0'; + else + Msg("! Failed to get computer name"); #else # error Select or add implementation for your platform #endif + SanitizeString(UserName); + SanitizeString(CompName); + +#ifdef DEBUG + Msg("UserName: %s", UserName); + Msg("ComputerName: %s", CompName); +#endif + Memory._initialize(); SDL_LogSetOutputFunction(SDLLogOutput, nullptr); From dd89487ea6287818c1cfcc3cd769afd44086c9ec Mon Sep 17 00:00:00 2001 From: yohjimane Date: Sun, 7 Apr 2024 07:37:30 -0700 Subject: [PATCH 257/497] Remove incorrect resolution scaling code (#1635) --- src/Layers/xrRenderDX11/dx11HW.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index 7dfe138fc62..a2846135a25 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -505,16 +505,6 @@ void CHW::Present() break; } -#ifdef HAS_DX11_2 - if (m_pSwapChain2 && UsingFlipPresentationModel()) - { - const float fps = Device.GetStats().fFPS; - if (fps < 30) - m_pSwapChain2->SetSourceSize(UINT(Device.dwWidth * 0.85f), UINT(Device.dwHeight * 0.85f)); - else if (fps < 15) - m_pSwapChain2->SetSourceSize(UINT(Device.dwWidth * 0.7f), UINT(Device.dwHeight * 0.7f)); - } -#endif CurrentBackBuffer = (CurrentBackBuffer + 1) % BackBufferCount; } From 3e8fd725dd0d3c970d838b33b451661082a066bc Mon Sep 17 00:00:00 2001 From: Egor Olefirenko <68744350+olefirenque@users.noreply.github.com> Date: Sun, 7 Apr 2024 18:28:50 +0300 Subject: [PATCH 258/497] Task manager enhancements (#1594) Co-authored-by: Sultan Uramaev --- src/xrCore/Threading/TaskManager.cpp | 24 +++++++++++++++--------- src/xrCore/Threading/TaskManager.hpp | 18 ++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 9a53aa845fa..3d5089a0b06 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -166,6 +166,7 @@ class TaskWorker : public TaskQueue, public TaskWorkerStats std::atomic_bool sleeps{}; Event event; size_t id; + CRandom random{ s32(std::intptr_t(this)) }; } static thread_local s_tl_worker; static TaskWorker* s_main_thread_worker = nullptr; @@ -258,7 +259,7 @@ void TaskManager::SetThreadStatus(bool active) activeWorkersCount.fetch_sub(1, std::memory_order_relaxed); } -void TaskManager::WakeUpIfNeeded() +void TaskManager::WakeUpIfNeeded() const { const auto overall = workersCount.load(std::memory_order_relaxed); const auto active = activeWorkersCount.load(std::memory_order_relaxed); @@ -318,7 +319,7 @@ void TaskManager::TaskWorkerStart() } steal: { - task = TryToSteal(&s_tl_worker); + task = TryToSteal(); if (task) goto execute; } @@ -364,7 +365,7 @@ void TaskManager::TaskWorkerStart() s_tl_worker.event.Wait(); // prevent crash when other thread tries to steal } -Task* TaskManager::TryToSteal(TaskWorker* thief) +Task* TaskManager::TryToSteal() const { const auto count = workersCount.load(std::memory_order_relaxed); if (count == 1) @@ -374,13 +375,18 @@ Task* TaskManager::TryToSteal(TaskWorker* thief) return nullptr; // thread itself } - TaskWorker* other = workers[random.randI(count)]; - if (other != thief) + int steal_attempts = 3; + while (steal_attempts > 0) { + TaskWorker* other = workers[s_tl_worker.random.randI(count)]; + if (other == &s_tl_worker) + continue; auto* task = other->steal(); if (!other->empty() && other->sleeps.load(std::memory_order_relaxed)) other->event.Set(); // Wake up, you have work to do! - return task; + if (task) + return task; + --steal_attempts; } return nullptr; } @@ -417,7 +423,7 @@ void TaskManager::IncrementTaskJobsCounter(Task& parent) VERIFY2(prev != std::numeric_limits::max(), "Max jobs overflow. (too much children)"); } -void TaskManager::PushTask(Task& task) +void TaskManager::PushTask(Task& task) const { s_tl_worker.push(&task); WakeUpIfNeeded(); @@ -455,7 +461,7 @@ bool TaskManager::ExecuteOneTask() Task* task = s_tl_worker.pop(); if (!task) - task = TryToSteal(&s_tl_worker); + task = TryToSteal(); if (task) { @@ -539,7 +545,7 @@ void TaskManager::GetStats(size_t& allocated, size_t& allocatedWithFallback, siz finished += s_main_thread_worker->finishedTasks; ScopeLock scope(&workersLock); - for (TaskWorker* worker : workers) + for (const TaskWorker* worker : workers) { allocated += worker->allocatedTasks; pushed += worker->pushedTasks; diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index d8fab683b0c..6e917153457 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -31,12 +31,10 @@ class XRCORE_API TaskManager final std::atomic_bool shouldStop{}; - CRandom random; // non-atomic intentionally, possible data-races can make it even more random - private: ICN void TaskWorkerStart(); - [[nodiscard]] Task* TryToSteal(TaskWorker* thief); + [[nodiscard]] Task* TryToSteal() const; static void ExecuteTask(Task& task); static void FinalizeTask(Task& task); @@ -46,7 +44,7 @@ class XRCORE_API TaskManager final private: void SetThreadStatus(bool active); - void WakeUpIfNeeded(); + void WakeUpIfNeeded() const; public: TaskManager(); @@ -55,18 +53,18 @@ class XRCORE_API TaskManager final public: // TaskFunc is at the end for fancy in-place lambdas // Create a task, but don't run it yet - [[nodiscard]] Task& CreateTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] Task& CreateTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Create a task as child, but don't run it yet - [[nodiscard]] Task& CreateTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] Task& CreateTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Run task in parallel - void PushTask(Task& task); + void PushTask(Task& task) const; // Run task immediately in this thread - void RunTask(Task& task); + static void RunTask(Task& task); // Shortcut: create a task and run it immediately Task& AddTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); From 3682da08c7c288f422482b3520f7b776a761d33a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Apr 2024 00:45:59 +0500 Subject: [PATCH 259/497] xrGame/xrServer_Connect.cpp: correctly translate server ban message. --- src/xrGame/xrServer_Connect.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrGame/xrServer_Connect.cpp b/src/xrGame/xrServer_Connect.cpp index e94ad899980..50f7bbd5a43 100644 --- a/src/xrGame/xrServer_Connect.cpp +++ b/src/xrGame/xrServer_Connect.cpp @@ -164,15 +164,15 @@ void xrServer::ProcessClientDigest(xrClientData* xrCL, NET_Packet* P) { R_ASSERT2(tmp_client != GetServerClient(), "can't disconnect server client"); Msg("--- Client [%s] tried to connect - rejecting connection (he is banned by %s) ...", - tmp_client->m_cAddress.to_string().c_str(), admin_name.size() ? admin_name.c_str() : "Server"); - pstr message_to_user; - if (admin_name.size()) + tmp_client->m_cAddress.to_string().c_str(), admin_name.empty() ? "Server" : admin_name.c_str()); + pcstr message_to_user; + if (admin_name.empty()) { - STRCONCAT(message_to_user, "mp_you_have_been_banned_by ", admin_name.c_str()); + message_to_user = StringTable().translate("mp_you_have_been_banned_by_server").c_str(); } else { - STRCONCAT(message_to_user, ""); + STRCONCAT(message_to_user, StringTable().translate("mp_you_have_been_banned_by").c_str(), " ", admin_name.c_str()); } SendConnectResult(tmp_client, 0, ecr_have_been_banned, message_to_user); return; From cacd494ea27e01b7a2162e655e7370429ff86d88 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Apr 2024 01:03:09 +0500 Subject: [PATCH 260/497] xrGame/ui/UIWindow_script.cpp: export with_battleye property to scripts (#382) It's always false because BattlEye is proprietary technology and it's support in S.T.A.L.K.E.R. was discontinued anyway. --- src/xrGame/ui/UIWindow_script.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xrGame/ui/UIWindow_script.cpp b/src/xrGame/ui/UIWindow_script.cpp index f756ca0a981..8705c5df9a3 100644 --- a/src/xrGame/ui/UIWindow_script.cpp +++ b/src/xrGame/ui/UIWindow_script.cpp @@ -105,6 +105,7 @@ SCRIPT_EXPORT(SServerFilters, (), .def_readwrite("with_pass", &SServerFilters::with_pass) .def_readwrite("without_pass", &SServerFilters::without_pass) .def_readwrite("without_ff", &SServerFilters::without_ff) + .property ("with_battleye", +[] { return false; }) .def_readwrite("listen_servers", &SServerFilters::listen_servers) ]; }); From 4bf34a24a4eea6eafac278f19216a4648b61f65f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Apr 2024 06:06:15 +0500 Subject: [PATCH 261/497] xrGame: cleanup UIList* files --- src/xrGame/CMakeLists.txt | 9 - src/xrGame/ui/UIListBox_script.cpp | 171 ------- src/xrGame/ui/UIListItem.cpp | 44 -- src/xrGame/ui/UIListItem.h | 50 -- src/xrGame/ui/UIListItemEx.cpp | 45 -- src/xrGame/ui/UIListItemEx.h | 27 - src/xrGame/ui/UIListWnd.cpp | 629 ------------------------ src/xrGame/ui/UIListWnd.h | 156 ------ src/xrGame/ui/UIListWnd_inline.h | 72 --- src/xrGame/ui/UIListWnd_script.cpp | 113 ----- src/xrUICore/ListWnd/UIListItemEx.cpp | 2 +- src/xrUICore/ListWnd/UIListWnd.cpp | 40 +- src/xrUICore/ListWnd/UIListWnd.h | 1 + src/xrUICore/ListWnd/UIListWnd_inline.h | 2 - 14 files changed, 20 insertions(+), 1341 deletions(-) delete mode 100644 src/xrGame/ui/UIListBox_script.cpp delete mode 100644 src/xrGame/ui/UIListItem.cpp delete mode 100644 src/xrGame/ui/UIListItem.h delete mode 100644 src/xrGame/ui/UIListItemEx.cpp delete mode 100644 src/xrGame/ui/UIListItemEx.h delete mode 100644 src/xrGame/ui/UIListWnd.cpp delete mode 100644 src/xrGame/ui/UIListWnd.h delete mode 100644 src/xrGame/ui/UIListWnd_inline.h delete mode 100644 src/xrGame/ui/UIListWnd_script.cpp diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 1949afd085a..2121a29d0e8 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -2357,19 +2357,10 @@ target_sources(xrGame PRIVATE ui/UIKickPlayer.h ui/UILabel.cpp ui/UILabel.h - #ui/UIListBox_script.cpp #ui/UIListItemAdv.cpp #ui/UIListItemAdv.h - #ui/UIListItemEx.cpp - #ui/UIListItemEx.h - #ui/UIListItem.cpp - #ui/UIListItem.h ui/UIListItemServer.cpp ui/UIListItemServer.h - #ui/UIListWnd.cpp - #ui/UIListWnd.h - #ui/UIListWnd_inline.h - #ui/UIListWnd_script.cpp ui/UILoadingScreen.cpp ui/UILoadingScreen.h ui/UILoadingScreenHardcoded.h diff --git a/src/xrGame/ui/UIListBox_script.cpp b/src/xrGame/ui/UIListBox_script.cpp deleted file mode 100644 index eecfb56ae81..00000000000 --- a/src/xrGame/ui/UIListBox_script.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "pch_script.h" -#include "UIListBox.h" -#include "UIListBoxItem.h" -#include "UIListBoxItemMsgChain.h" -#include "ServerList.h" -#include "UIMapList.h" -#include "UISpinText.h" -#include "UIMapInfo.h" -#include "UIComboBox.h" -#include "xrScriptEngine/ScriptExporter.hpp" - - -struct CUIListBoxItemWrapper : public CUIListBoxItem, public luabind::wrap_base -{ - CUIListBoxItemWrapper(float h) : CUIListBoxItem(h) {} -}; - -struct CUIListBoxItemMsgChainWrapper : public CUIListBoxItemMsgChain, public luabind::wrap_base -{ - CUIListBoxItemMsgChainWrapper(float h) : CUIListBoxItemMsgChain(h) {} -}; - -SCRIPT_EXPORT(CUIListBox, (CUIScrollView), -{ - using namespace luabind; - using namespace luabind::policy; - - module(luaState) - [ - class_("CUIListBox") - .def(constructor<>()) - .def("ShowSelectedItem", &CUIListBox::Show) - .def("RemoveAll", &CUIListBox::Clear) - .def("GetSize", &CUIListBox::GetSize) - .def("GetSelectedItem", &CUIListBox::GetSelectedItem) - .def("GetSelectedIndex", &CUIListBox::GetSelectedIDX) - - .def("GetItemByIndex", &CUIListBox::GetItemByIDX) - .def("GetItem", &CUIListBox::GetItem) - .def("RemoveItem", &CUIListBox::RemoveWindow) - .def("AddTextItem", &CUIListBox::AddTextItem) - .def("AddExistingItem", &CUIListBox::AddExistingItem, adopt<2>()) - ]; -}); - -SCRIPT_EXPORT(CUIListBoxItem, (CUIFrameLineWnd), -{ - using namespace luabind; - - module(luaState) - [ - class_("CUIListBoxItem") - .def(constructor()) - .def("GetTextItem", &CUIListBoxItem::GetTextItem) - .def("AddTextField", &CUIListBoxItem::AddTextField) - .def("AddIconField", &CUIListBoxItem::AddIconField) - .def("SetTextColor", &CUIListBoxItem::SetTextColor) - ]; -}); - -SCRIPT_EXPORT(CUIListBoxItemMsgChain, (CUIListBoxItem), -{ - using namespace luabind; - - module(luaState) - [ - class_("CUIListBoxItemMsgChain") - .def(constructor()) - ]; -}); - -SCRIPT_EXPORT(SServerFilters, (), -{ - using namespace luabind; - - module(luaState) - [ - class_("SServerFilters") - .def(constructor<>()) - .def_readwrite("empty", &SServerFilters::empty) - .def_readwrite("full", &SServerFilters::full) - .def_readwrite("with_pass", &SServerFilters::with_pass) - .def_readwrite("without_pass", &SServerFilters::without_pass) - .def_readwrite("without_ff", &SServerFilters::without_ff) - .def_readwrite("listen_servers", &SServerFilters::listen_servers) - ]; -}); - -SCRIPT_EXPORT(connect_error_cb, (), -{ - using namespace luabind; - - module(luaState) - [ - class_("connect_error_cb") - .def(constructor<>()) - .def(constructor()) - .def("bind", (connect_error_cb::lua_bind_type)(&connect_error_cb::bind)) - .def("clear", &connect_error_cb::clear) - ]; -}); - -SCRIPT_EXPORT(CServerList, (CUIWindow), -{ - using namespace luabind; - - module(luaState) - [ - class_("CServerList") - .def(constructor<>()) - .enum_("enum_connect_errcode") - [ - value("ece_unique_nick_not_registred", int(ece_unique_nick_not_registred)), - value("ece_unique_nick_expired", int(ece_unique_nick_expired)) - ] - .def("SetConnectionErrCb", &CServerList::SetConnectionErrCb) - .def("ConnectToSelected", &CServerList::ConnectToSelected) - .def("SetFilters", &CServerList::SetFilters) - .def("SetPlayerName", &CServerList::SetPlayerName) - .def("RefreshList", &CServerList::RefreshGameSpyList) - .def("RefreshQuick", &CServerList::RefreshQuick) - .def("ShowServerInfo", &CServerList::ShowServerInfo) - .def("NetRadioChanged", &CServerList::NetRadioChanged) - .def("SetSortFunc", &CServerList::SetSortFunc) - ]; -}); - -SCRIPT_EXPORT(CUIMapList, (CUIWindow), -{ - using namespace luabind; - - module(luaState) - [ - class_("CUIMapList") - .def(constructor<>()) - .def("SetWeatherSelector", &CUIMapList::SetWeatherSelector) - .def("SetModeSelector", &CUIMapList::SetModeSelector) - .def("OnModeChange", &CUIMapList::OnModeChange) - .def("LoadMapList", &CUIMapList::LoadMapList) - .def("SaveMapList", &CUIMapList::SaveMapList) - .def("GetCommandLine", &CUIMapList::GetCommandLine) - .def("SetServerParams", &CUIMapList::SetServerParams) - .def("GetCurGameType", &CUIMapList::GetCurGameType) - .def("StartDedicatedServer", &CUIMapList::StartDedicatedServer) - .def("SetMapPic", &CUIMapList::SetMapPic) - .def("SetMapInfo", &CUIMapList::SetMapInfo) - .def("ClearList", &CUIMapList::ClearList) - .def("IsEmpty", &CUIMapList::IsEmpty) - ]; -}); - -SCRIPT_EXPORT(EnumGameIDs, (), -{ - using namespace luabind; - - class EnumGameIDs - { - }; - - module(luaState) - [ - class_("GAME_TYPE") - .enum_("gametype") - [ - value("GAME_UNKNOWN", int(-1)), - value("eGameIDDeathmatch", int(eGameIDDeathmatch)), - value("eGameIDTeamDeathmatch", int(eGameIDTeamDeathmatch)), - value("eGameIDArtefactHunt", int(eGameIDArtefactHunt)), - value("eGameIDCaptureTheArtefact", int(eGameIDCaptureTheArtefact)) - ]]; -}); diff --git a/src/xrGame/ui/UIListItem.cpp b/src/xrGame/ui/UIListItem.cpp deleted file mode 100644 index ae4e726e41a..00000000000 --- a/src/xrGame/ui/UIListItem.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "StdAfx.h" - -#include "UIListItem.h" - -CUIListItem::CUIListItem(void) -{ - m_eButtonState = BUTTON_NORMAL; - m_ePressMode = NORMAL_PRESS; - - m_bButtonClicked = false; - - m_pData = NULL; - - m_iIndex = -1; - m_iValue = 0; - m_bHighlightText = false; - m_iGroupID = -1; - SetAutoDelete(true); - SetTextAlignment(CGameFont::alLeft); -} - -CUIListItem::~CUIListItem(void) {} -void CUIListItem::InitListItem(Fvector2 pos, Fvector2 size) -{ - inherited::SetWndPos(pos); - inherited::SetWndSize(size); - SetPressMode(CUIButton::DOWN_PRESS); - SetPushOffset(Fvector2().set(0.0f, 0.0f)); -} - -void CUIListItem::InitTexture(LPCSTR tex_name) -{ - CUIButton::InitTexture(tex_name); - SetTextX(m_UIStaticItem.GetRect().width()); -} - -/* -void CUIListItem::Init(const char* str, float x, float y, float width, float height) -{ - Init(x,y,width, height); - SetTextST(str); -}*/ - -bool CUIListItem::IsHighlightText() { return CUIButton::IsHighlightText(); } diff --git a/src/xrGame/ui/UIListItem.h b/src/xrGame/ui/UIListItem.h deleted file mode 100644 index c9143ac6f2c..00000000000 --- a/src/xrGame/ui/UIListItem.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include "UIButton.h" - -class CUIListItem : public CUIButton -{ -private: - typedef CUIButton inherited; - -public: - CUIListItem(); - virtual ~CUIListItem(); - - void InitListItem(Fvector2 pos, Fvector2 size); - //. virtual void Init(const char* str, float x, float y, float width, float height); - virtual void InitTexture(LPCSTR tex_name); - - void* GetData() { return m_pData; } - void SetData(void* pData) { m_pData = pData; } - int GetIndex() { return m_iIndex; } - void SetIndex(int index) - { - m_iIndex = index; - m_iGroupID = index; - } - - int GetValue() { return m_iValue; } - void SetValue(int value) { m_iValue = value; } - int GetGroupID() { return m_iGroupID; } - void SetGroupID(int ID) { m_iGroupID = ID; } - virtual void MarkSelected(bool b){}; - // переопределяем критерий подсвечивания текста - virtual bool IsHighlightText(); - virtual void SetHighlightText(bool Highlight) { m_bHighlightText = Highlight; } -protected: - //указатель на произвольные данные, которые могут - //присоедениены к элементу - void* m_pData; - - //произвольное число, приписанное объекту - int m_iValue; - - //индекс в списке - int m_iIndex; - - // идентификатор группы - int m_iGroupID; - - // подсвечивается кнопка или нет? - bool m_bHighlightText; -}; diff --git a/src/xrGame/ui/UIListItemEx.cpp b/src/xrGame/ui/UIListItemEx.cpp deleted file mode 100644 index 14e92a04c49..00000000000 --- a/src/xrGame/ui/UIListItemEx.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// File: UIListWndEx.cpp -// Description: Extended ListItem -// Requiered to use feature "Selected Item" -// Created: -// Author: Serhiy O. Vynnychenko -// Mail: narrator@gsc-game.kiev.ua - -// Copyright: 2004 GSC Game World - -#include "StdAfx.h" -#include "UIListItemEx.h" - -CUIListItemEx::CUIListItemEx(void) -{ - //. this->InitTexture("ui" DELIMITER "hud_map_point"); - //. this->SetStretchTexture(true); - this->m_dwSelectionColor = color_argb(200, 95, 82, 74); - this->SetColor(color_argb(0, 0, 0, 0)); -} - -CUIListItemEx::~CUIListItemEx(void) {} -void CUIListItemEx::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) -{ - // inherited::SendMessage(pWnd, msg, pData); - - switch (msg) - { - case LIST_ITEM_SELECT: - this->SetColor(m_dwSelectionColor); - // this->Draw(); - break; - case LIST_ITEM_UNSELECT: - this->SetColor(color_argb(0, 0, 0, 0)); - // this->Draw(); - break; - } -} - -void CUIListItemEx::SetSelectionColor(u32 dwColor) { m_dwSelectionColor = dwColor; } -void CUIListItemEx::Draw() -{ - // if (m_bPerformTextLimit) - // this->PerformTextLengthLimit(); - inherited::Draw(); -} diff --git a/src/xrGame/ui/UIListItemEx.h b/src/xrGame/ui/UIListItemEx.h deleted file mode 100644 index 003bb91d6b1..00000000000 --- a/src/xrGame/ui/UIListItemEx.h +++ /dev/null @@ -1,27 +0,0 @@ -// File: UIListWndEx.cpp -// Description: Extended ListItem -// Requiered to use feature "Selected Item" -// Created: -// Author: Serhiy O. Vynnychenko -// Mail: narrator@gsc-game.kiev.ua - -// Copyright: 2004 GSC Game World - -#pragma once -#include "UIListItem.h" - -class CUIListItemEx : public CUIListItem -{ -private: - typedef CUIListItem inherited; - -public: - CUIListItemEx(void); - virtual ~CUIListItemEx(void); - virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); - virtual void SetSelectionColor(u32 dwColor); - virtual void Draw(); - virtual void dummy() {} -protected: - u32 m_dwSelectionColor; -}; diff --git a/src/xrGame/ui/UIListWnd.cpp b/src/xrGame/ui/UIListWnd.cpp deleted file mode 100644 index 17092a42406..00000000000 --- a/src/xrGame/ui/UIListWnd.cpp +++ /dev/null @@ -1,629 +0,0 @@ -#include "StdAfx.h" -#include "UIListWnd.h" -//.#include "uiscrollbar.h" -#include "UIFrameLineWnd.h" - -//. #define ACTIVE_BACKGROUND "ui" DELIMITER "ui_pop_up_active_back" -//. #define ACTIVE_BACKGROUND_WIDTH 16 -//. #define ACTIVE_BACKGROUND_HEIGHT 16 - -// разделитель для интерактивных строк в листе -static const char cSeparatorChar = '%'; - -CUIListWnd::CUIListWnd() -{ - m_ActiveBackgroundFrame = NULL; - m_bListActivity = true; - m_iFocusedItem = -1; - m_iSelectedItem = -1; - m_iFocusedItemGroupID = -1; - m_iSelectedItemGroupID = -1; - m_bShowSelectedItem = false; - m_bActiveBackground = false; - m_dwFontColor = 0xFFFFFFFF; - SetItemHeight(DEFAULT_ITEM_HEIGHT); - m_bVertFlip = false; - m_bUpdateMouseMove = false; - m_bForceFocusedItem = false; - m_iLastUniqueID = 0; - m_bAlwaysShowScroll = false; - m_bAlwaysShowScroll_enable = false; -} - -CUIListWnd::~CUIListWnd() -{ - while (!m_ItemList.empty()) - DetachChild(m_ItemList.front()); - - m_ItemList.clear(); - xr_delete(m_ActiveBackgroundFrame); -} - -/* -void CUIListWnd::Init(float x, float y, float width, float height) -{ - Init(x, y, width, height, m_iItemHeight); -}*/ - -void CUIListWnd::InitListWnd(Fvector2 pos, Fvector2 size, float item_height) -{ - inherited::SetWndPos(pos); - inherited::SetWndSize(size); - - //добавить полосу прокрутки - m_ScrollBar = xr_new(); - m_ScrollBar->SetAutoDelete(true); - AttachChild(m_ScrollBar); - - if (!!m_scrollbar_profile) - m_ScrollBar->InitScrollBar(Fvector2().set(size.x, 0.0f), size.y, false, *m_scrollbar_profile); - else - m_ScrollBar->InitScrollBar(Fvector2().set(size.x, 0.0f), size.y, false); - - m_ScrollBar->SetWndPos( - Fvector2().set(m_ScrollBar->GetWndPos().x - m_ScrollBar->GetWidth(), m_ScrollBar->GetWndPos().y)); - - SetItemWidth(size.x - m_ScrollBar->GetWidth()); - - m_iFirstShownIndex = 0; - - SetItemHeight(item_height); - m_iRowNum = iFloor(size.y / m_iItemHeight); - - m_ScrollBar->SetRange(0, 0); - m_ScrollBar->SetPageSize(0); - m_ScrollBar->SetScrollPos(s16(m_iFirstShownIndex)); - - m_ScrollBar->Show(false); - m_ScrollBar->Enable(false); - - /* - m_StaticActiveBackground.Init(ACTIVE_BACKGROUND,"hud" DELIMITER "default", 0,0,alNone); - m_StaticActiveBackground.SetTile(iFloor(m_iItemWidth/ACTIVE_BACKGROUND_WIDTH), - iFloor(m_iItemHeight/ACTIVE_BACKGROUND_HEIGHT), - fmod(m_iItemWidth,float(ACTIVE_BACKGROUND_WIDTH)), - fmod(m_iItemHeight,float(ACTIVE_BACKGROUND_HEIGHT))); - */ - UpdateList(); -} -////////////////////////////////////////////////////////////////////////// - -/*was made within plan of dinamic changing of appea*/ -void CUIListWnd::SetHeight(float height) -{ - CUIWindow::SetHeight(height); - m_iRowNum = iFloor(height / m_iItemHeight); - m_ScrollBar->SetHeight(height); - this->UpdateList(); - this->UpdateScrollBar(); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::SetWidth(float width) -{ - inherited::SetWidth(width); - /* - m_StaticActiveBackground.SetTile(iFloor(GetWidth()/ACTIVE_BACKGROUND_WIDTH), - iFloor(m_iItemHeight/ACTIVE_BACKGROUND_HEIGHT), - fmod(GetWidth(),float(ACTIVE_BACKGROUND_WIDTH)), - fmod(float(m_iItemHeight),float(ACTIVE_BACKGROUND_HEIGHT)) - ); - */ -} - -void CUIListWnd::RemoveItem(int index) -{ - if (index < 0 || index >= (int)m_ItemList.size()) - return; - - LIST_ITEM_LIST_it it; - - //выбрать нужный элемент - it = m_ItemList.begin(); - for (int i = 0; i < index; ++i, ++it) - ; - - R_ASSERT(m_ItemList.end() != it); - - DetachChild(*it); - - UpdateList(); - - //обновить полосу прокрутки - if (m_ItemList.size() > 0) - m_ScrollBar->SetRange(0, s16(m_ItemList.size() - 1)); - else - m_ScrollBar->SetRange(0, 0); - - m_ScrollBar->SetPageSize((m_iRowNum < (int)m_ItemList.size()) ? m_iRowNum : (int)m_ItemList.size()); - m_ScrollBar->SetScrollPos(s16(m_iFirstShownIndex)); - m_ScrollBar->Refresh(); - - //перенумеровать индексы заново - i = 0; - for (LIST_ITEM_LIST_it it = m_ItemList.begin(); m_ItemList.end() != it; ++it, i++) - { - (*it)->SetIndex(i); - } -} - -////////////////////////////////////////////////////////////////////////// - -CUIListItem* CUIListWnd::GetItem(int index) -{ - if (index < 0 || index >= (int)m_ItemList.size()) - return NULL; - - LIST_ITEM_LIST_it it; - - //выбрать нужный элемент - it = m_ItemList.begin(); - for (int i = 0; i < index; ++i, ++it) - ; - - R_ASSERT(m_ItemList.end() != it); - - return (*it); -} - -void CUIListWnd::DetachChild(CUIWindow* pChild) -{ - LIST_ITEM_LIST_it it = std::find(m_ItemList.begin(), m_ItemList.end(), pChild); - if (it != m_ItemList.end()) - m_ItemList.erase(it); - - inherited::DetachChild(pChild); -} - -void CUIListWnd::RemoveAll() -{ - if (m_ItemList.empty()) - return; - - LIST_ITEM_LIST_it it; - - while (!m_ItemList.empty()) - { - DetachChild(m_ItemList.front()); - } - - m_iFirstShownIndex = 0; - - UpdateList(); - Reset(); - - //обновить полосу прокрутки - m_ScrollBar->SetRange(0, 0); - m_ScrollBar->SetPageSize(1); - m_ScrollBar->SetScrollPos(s16(m_iFirstShownIndex)); - - UpdateScrollBar(); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::UpdateList() -{ - if (m_ItemList.empty()) - { - UpdateScrollBar(); - return; - } - - LIST_ITEM_LIST_it it = m_ItemList.begin(); - - //спрятать все элементы до участка - //отображающейся в данный момент - for (int i = 0; i < _min(m_ItemList.size(), m_iFirstShownIndex); ++i, ++it) - { - (*it)->Show(false); - } - - //показать текущий список - for (i = m_iFirstShownIndex; i < _min(m_ItemList.size(), m_iFirstShownIndex + m_iRowNum + 1); ++i, ++it) - { - Frect rect_to_set; - rect_to_set.lt.set((*it)->GetWndRect().left, m_bVertFlip ? - GetHeight() - (i - m_iFirstShownIndex) * m_iItemHeight - m_iItemHeight : - (i - m_iFirstShownIndex) * m_iItemHeight); - rect_to_set.rb.add(rect_to_set.lt, Fvector2().set(m_iItemWidth, m_iItemHeight)); - - (*it)->SetWndRect(rect_to_set); - (*it)->Show(true); - - if (m_bListActivity) - (*it)->Enable(true); - else - (*it)->Enable(false); - } - - --it; - - //спрятать все после - for (u32 k = m_iFirstShownIndex + m_iRowNum; k < m_ItemList.size(); ++k, ++it) - { - (*it)->Show(false); - // (*it)->Enable(false); - } - - UpdateScrollBar(); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) -{ - if (pWnd == m_ScrollBar) - { - if (msg == SCROLLBAR_VSCROLL) - { - m_iFirstShownIndex = m_ScrollBar->GetScrollPos(); - UpdateList(); - GetMessageTarget()->SendMessage(this, SCROLLBAR_VSCROLL, NULL); - } - } - else - { - //если сообщение пришло от одного из элементов списка - - if (IsChild(pWnd)) - { - CUIListItem* pListItem2; - CUIListItem* pListItem = smart_cast(pWnd); - R_ASSERT(pListItem); - - if (BUTTON_CLICKED == msg) - { - for (WINDOW_LIST_it it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) - { - pListItem2 = smart_cast(*it); - if (!pListItem2) - continue; - if (pListItem2->GetGroupID() == -1) - continue; - if (pListItem2->GetGroupID() == pListItem->GetGroupID()) - { - pListItem2->SetHighlightText(true); - pListItem2->SendMessage(this, LIST_ITEM_SELECT, pData); - m_iSelectedItem = pListItem2->GetIndex(); - m_iSelectedItemGroupID = pListItem2->GetGroupID(); - } - else - { - pListItem2->SetHighlightText(false); - pListItem2->SendMessage(this, LIST_ITEM_UNSELECT, pData); - } - } - GetMessageTarget()->SendMessage(this, LIST_ITEM_CLICKED, pListItem); - } - - else if (STATIC_FOCUS_RECEIVED == msg) - { - if (!m_bForceFocusedItem) - { - m_iFocusedItem = pListItem->GetIndex(); - m_iFocusedItemGroupID = pListItem->GetGroupID(); - } - else if (m_iFocusedItem >= 0) - m_iFocusedItemGroupID = GetItem(m_iFocusedItem)->GetGroupID(); - - // prototype code - - for (WINDOW_LIST_it it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) - { - pListItem2 = smart_cast(*it); - if (!pListItem2) - continue; - if (pListItem2->GetGroupID() == -1) - continue; - if (pListItem2->GetGroupID() == pListItem->GetGroupID()) - { - pListItem2->SetHighlightText(true); - pListItem2->SendMessage(this, STATIC_FOCUS_RECEIVED, pData); - } - else - { - pListItem2->SetHighlightText(false); - pListItem2->SendMessage(this, STATIC_FOCUS_LOST, pData); - } - } - // end prototype code - } - else if (STATIC_FOCUS_LOST == msg) - { - if (pListItem->GetIndex() == m_iFocusedItem && !m_bForceFocusedItem) - m_iFocusedItem = -1; - - for (WINDOW_LIST_it it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) - { - pListItem2 = smart_cast(*it); - if (!pListItem2) - continue; - pListItem2->SetHighlightText(false); - pListItem2->SendMessage(this, STATIC_FOCUS_LOST, pData); - } - m_bUpdateMouseMove = true; - } - } - } - - CUIWindow::SendMessage(pWnd, msg, pData); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::DrawActiveBackFrame(const Frect& rect, CUIListItem* itm) -{ - Fvector2 _pos; - _pos.set(rect.left, rect.top + (itm->GetIndex() - m_iFirstShownIndex) * GetItemHeight()); - float _d = GetItemHeight() - m_ActiveBackgroundFrame->GetHeight(); - if (_d > 0) - _pos.y += (float)iFloor(_d / 2.0f); - - m_ActiveBackgroundFrame->SetWndPos(_pos); - float _w = GetWidth(); - if (m_ScrollBar->IsShown()) - _w -= m_ScrollBar->GetWidth(); - m_ActiveBackgroundFrame->SetWidth(_w); - m_ActiveBackgroundFrame->Draw(); -} - -void CUIListWnd::Draw() -{ - WINDOW_LIST_it it; - - if (m_iFocusedItem != -1 && IsActiveBackgroundEnabled()) - { - Frect rect; - GetAbsoluteRect(rect); - for (it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) - { - CUIListItem* pListItem2 = smart_cast(*it); - if (!pListItem2) - continue; - if (pListItem2->GetGroupID() == -1) - continue; - if ((pListItem2->GetGroupID() == m_iFocusedItemGroupID) && - ((pListItem2->GetIndex() >= m_iFirstShownIndex) && - (pListItem2->GetIndex() <= m_iRowNum + m_iFirstShownIndex - 1))) - { - DrawActiveBackFrame(rect, pListItem2); - } - } - } - - if (m_iSelectedItem != -1 && m_bShowSelectedItem) - { - Frect rect; - GetAbsoluteRect(rect); - for (it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) - { - CUIListItem* pListItem2 = smart_cast(*it); - if (!pListItem2) - continue; - if (pListItem2->GetGroupID() == -1) - continue; - if (pListItem2->GetIndex() == m_iSelectedItem) - { - UI()->PushScissor(rect); - - DrawActiveBackFrame(rect, pListItem2); - - UI()->PopScissor(); - } - } - } - - CUIWindow::Draw(); -} - -void CUIListWnd::SetItemWidth(float iItemWidth) { m_iItemWidth = iItemWidth; } -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::SetItemHeight(float iItemHeight) -{ - m_iItemHeight = iItemHeight; - m_iRowNum = iFloor(GetHeight() / iItemHeight); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::Reset() -{ - for (LIST_ITEM_LIST_it it = m_ItemList.begin(); m_ItemList.end() != it; ++it) - { - (*it)->Reset(); - } - - ResetAll(); - - inherited::Reset(); -} - -////////////////////////////////////////////////////////////////////////// -//находит первый элемент с заданной pData, иначе -1 -////////////////////////////////////////////////////////////////////////// - -int CUIListWnd::FindItem(void* pData) -{ - int i = 0; - for (LIST_ITEM_LIST_it it = m_ItemList.begin(); m_ItemList.end() != it; ++it, ++i) - { - if ((*it)->GetData() == pData) - return i; - } - return -1; -} - -int CUIListWnd::FindItemWithValue(int iValue) -{ - int i = 0; - for (LIST_ITEM_LIST_it it = m_ItemList.begin(); m_ItemList.end() != it; ++it, ++i) - { - if ((*it)->GetValue() == iValue) - return i; - } - return -1; -} - -bool CUIListWnd::OnMouse(float x, float y, EUIMessages mouse_action) -{ - switch (mouse_action) - { - case WINDOW_LBUTTON_DB_CLICK: break; - case WINDOW_MOUSE_WHEEL_DOWN: - m_ScrollBar->TryScrollInc(); - return true; - break; - case WINDOW_MOUSE_WHEEL_UP: - m_ScrollBar->TryScrollDec(); - return true; - break; - } - - return inherited::OnMouse(x, y, mouse_action); -} - -bool CUIListWnd::OnKeyboard(int dik, EUIMessages keyboard_action) -{ - return inherited::OnKeyboard(dik, keyboard_action); -} -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::UpdateScrollBar() -{ - if (m_bAlwaysShowScroll_enable) - { - m_ScrollBar->Show(m_bAlwaysShowScroll); - return; - } - - if ((int)m_ItemList.size() <= m_ScrollBar->GetPageSize()) - m_ScrollBar->Show(false); - else - m_ScrollBar->Show(true); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::EnableScrollBar(bool enable) -{ - m_ScrollBar->SetEnabled(enable); - UpdateScrollBar(); -} - -void CUIListWnd::ActivateList(bool activity) { m_bListActivity = activity; } -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::ScrollToBegin() -{ - m_ScrollBar->SetScrollPos((s16)m_ScrollBar->GetMinRange()); - m_iFirstShownIndex = m_ScrollBar->GetScrollPos(); - UpdateList(); -} - -////////////////////////////////////////////////////////////////////////// - -void CUIListWnd::ScrollToEnd() -{ - u32 pos = m_ScrollBar->GetMaxRange() - m_ScrollBar->GetPageSize() + 1; - - if ((int)pos > m_ScrollBar->GetMinRange()) - m_ScrollBar->SetScrollPos(pos); - else - m_ScrollBar->SetScrollPos(m_ScrollBar->GetMinRange()); - - m_iFirstShownIndex = m_ScrollBar->GetScrollPos(); - UpdateList(); -} - -void CUIListWnd::ScrollToPos(int position) -{ - if (IsScrollBarEnabled()) - { - int pos = position; - clamp(pos, m_ScrollBar->GetMinRange(), (m_ScrollBar->GetMaxRange() - m_ScrollBar->GetPageSize() / +1)); - m_ScrollBar->SetScrollPos(pos); - m_iFirstShownIndex = m_ScrollBar->GetScrollPos(); - UpdateList(); - } -} - -void CUIListWnd::Update() -{ - if (m_bUpdateMouseMove) - { - OnMouse(cursor_pos.x, cursor_pos.y, WINDOW_MOUSE_MOVE); - m_bUpdateMouseMove = false; - } - - inherited::Update(); - if (m_ActiveBackgroundFrame) - m_ActiveBackgroundFrame->Update(); -} - -void CUIListWnd::SetFocusedItem(int iNewFocusedItem) -{ - m_iFocusedItem = iNewFocusedItem; - m_bForceFocusedItem = true; - EnableActiveBackground(true); - if (m_iFocusedItem >= 0) - m_iFocusedItemGroupID = GetItem(m_iFocusedItem)->GetGroupID(); -} - -int CUIListWnd::GetItemPos(CUIListItem* pItem) -{ - LIST_ITEM_LIST_it it = m_ItemList.begin(); - for (u32 i = 0; i < m_ItemList.size(); ++i) - { - if (*it == pItem) - return i; - ++it; - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////// - -bool CUIListWnd::IsScrollBarEnabled() { return m_ScrollBar->GetEnabled(); } -void CUIListWnd::EnableActiveBackground(bool enable) -{ - m_bActiveBackground = enable; - - if (enable) - { - create_active_back(); - } - else - destroy_active_back(); -} - -void CUIListWnd::ShowSelectedItem(bool show) -{ - m_bShowSelectedItem = show; - - if (show) - { - create_active_back(); - } - else - destroy_active_back(); -} - -void CUIListWnd::create_active_back() -{ - if (m_ActiveBackgroundFrame) - return; - - m_ActiveBackgroundFrame = xr_new(); - m_ActiveBackgroundFrame->InitFrameLineWnd( - "ui_listline", Fvector2().set(0.0f, 0.0f), Fvector2().set(GetWidth(), 18.0f)); -} - -void CUIListWnd::destroy_active_back() -{ - if (!m_bShowSelectedItem && !m_bActiveBackground) - xr_delete(m_ActiveBackgroundFrame); -} diff --git a/src/xrGame/ui/UIListWnd.h b/src/xrGame/ui/UIListWnd.h deleted file mode 100644 index 43fe0ac5bfb..00000000000 --- a/src/xrGame/ui/UIListWnd.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once -#include "UIWindow.h" -#include "UIListItem.h" -#include "UIScrollBar.h" - -#include "../../xrServerEntities/script_export_space.h" // Unexisting file !?!? - -#define DEFAULT_ITEM_HEIGHT 30 - -DEF_LIST(LIST_ITEM_LIST, CUIListItem*); -class CUIScrollBar; -class CUIFrameLineWnd; - -class CUIListWnd : public CUIWindow -{ -private: - typedef CUIWindow inherited; - friend class CUIGameLog; - - shared_str m_scrollbar_profile; - void DrawActiveBackFrame(const Frect& rect, CUIListItem* itm); - -public: - CUIListWnd(); - virtual ~CUIListWnd(); - - void InitListWnd(Fvector2 pos, Fvector2 size, float item_height); - - virtual bool OnMouse(float x, float y, EUIMessages mouse_action); - virtual bool OnKeyboard(int dik, EUIMessages keyboard_action); - - virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); - virtual void Draw(); - virtual void Update(); - virtual void DetachChild(CUIWindow* pChild); - void SetScrollBarProfile(LPCSTR profile) { m_scrollbar_profile = profile; }; - // Добавление элементов в листбокс - template - bool AddItem( - const char* str, const float shift = 0.0f, void* pData = NULL, int value = 0, int insertBeforeIdx = -1); - - virtual bool AddItem_script(CUIListItem* item); - - template - bool AddItem(Element* pItem, int insertBeforeIdx = -1); - - void RemoveItem(int index); - void RemoveAll(); - //находит первый элемент с заданной pData, иначе -1 - int FindItem(void* pData); - int FindItemWithValue(int iValue); - CUIListItem* GetItem(int index); - // Получить индекс элемента по адресу. Либо -1 если нет такого - int GetItemPos(CUIListItem* pItem); - - void SetItemWidth(float iItemWidth); - float GetItemWidth() { return m_iItemWidth; } - void SetItemHeight(float iItemHeight); - float GetItemHeight() { return m_iItemHeight; } - virtual void SetHeight(float height); - - void SetAlwaysShowScroll(bool flag = true) { m_bAlwaysShowScroll = flag; } - void EnableAlwaysShowScroll(bool flag) { m_bAlwaysShowScroll_enable = flag; } - int GetItemsCount() { return m_ItemList.size(); } - //подготовить все элементы заново - void Reset(); - - void EnableScrollBar(bool enable); - bool IsScrollBarEnabled(); - void UpdateScrollBar(); - - void ScrollToBegin(); - void ScrollToEnd(); - void ScrollToPos(int position); - - IC bool IsActiveBackgroundEnabled() { return m_bActiveBackground; } - void EnableActiveBackground(bool enable); - - virtual void SetWidth(float width); - - void SetTextColor(u32 color) { m_dwFontColor = color; } - u32 GetTextColor() { return m_dwFontColor; } - //делает активными (как кнопки) элементы списка - void ActivateList(bool activity); - bool IsListActive() { return m_bListActivity; } - void SetVertFlip(bool vert_flip) { m_bVertFlip = vert_flip; } - bool GetVertFlip() { return m_bVertFlip; } - // Принудительная установка фокуса - void SetFocusedItem(int iNewFocusedItem); - int GetFocusedItem() { return m_iFocusedItem; } - int GetSelectedItem() { return m_iSelectedItem; } - void SetSelectedItem(int sel) { m_iSelectedItem = sel; } - void ShowSelectedItem(bool show = true); - - void ResetFocusCapture() { m_bForceFocusedItem = false; } - int GetListPosition() const { return m_iFirstShownIndex; } -protected: - void create_active_back(); - void destroy_active_back(); - - CUIScrollBar* m_ScrollBar; - - //обновления елементов списка, вызвается - //если произошли изменения - void UpdateList(); - - //список элементов листа - LIST_ITEM_LIST m_ItemList; - - //размеры элемента списка - float m_iItemHeight; - float m_iItemWidth; - - //количество рядов для элементов - int m_iRowNum; - - //индекс первого показанного элемента - int m_iFirstShownIndex; - - //элемент над которым курсор в данный момент или -1, если такого нет - int m_iFocusedItem; - int m_iFocusedItemGroupID; - int m_iSelectedItem; - int m_iSelectedItemGroupID; - - bool m_bShowSelectedItem; - bool m_bAlwaysShowScroll_enable; - bool m_bAlwaysShowScroll; - bool m_bActiveBackground; - // Если хотим принудительно выставлять фокус, то поднять этот флаг - bool m_bForceFocusedItem; - - //подсветка активного элемента - CUIFrameLineWnd* m_ActiveBackgroundFrame; - - //текущий цвет текста - u32 m_dwFontColor; - bool m_bListActivity; - - //переворот списка по вертикали - bool m_bVertFlip; - - // Признак того, что мышь подвинули - bool m_bUpdateMouseMove; - - // Текущий уникальный идентификатор - int m_iLastUniqueID; - - DECLARE_SCRIPT_REGISTER_FUNCTION -}; - -#include "UIListWnd_inline.h" - -add_to_type_list(CUIListWnd) -#undef script_type_list -#define script_type_list save_type_list(CUIListWnd) diff --git a/src/xrGame/ui/UIListWnd_inline.h b/src/xrGame/ui/UIListWnd_inline.h deleted file mode 100644 index b4909f667a3..00000000000 --- a/src/xrGame/ui/UIListWnd_inline.h +++ /dev/null @@ -1,72 +0,0 @@ -//============================================================================= -// Filename: UIListWnd_inline.h -// Created by Roman E. Marchenko, vortex@gsc-game.kiev.ua -// Copyright 2004. GSC Game World -// --------------------------------------------------------------------------- -// Реализация темплейтовых функций листбокса -//============================================================================= - -template -bool CUIListWnd::AddItem(const char* str, const float shift, void* pData, int value, int insertBeforeIdx) -{ - //создать новый элемент и добавить его в список - Element* pItem = NULL; - pItem = xr_new(); - - VERIFY(pItem); - - pItem->Init(str, shift, - m_bVertFlip ? GetHeight() - GetSize() * m_iItemHeight - m_iItemHeight : GetSize() * m_iItemHeight, m_iItemWidth, - m_iItemHeight); - - pItem->SetData(pData); - pItem->SetValue(value); - pItem->SetTextColor(m_dwFontColor); - - return AddItem(pItem, insertBeforeIdx); -} - -template -bool CUIListWnd::AddItem(Element* pItem, int insertBeforeIdx) -{ - AttachChild(pItem); - - pItem->InitListItem(Fvector2().set(pItem->GetWndRect().left, m_bVertFlip ? - GetHeight() - GetItemsCount() * m_iItemHeight - m_iItemHeight : - GetItemsCount() * m_iItemHeight), - Fvector2().set(m_iItemWidth, m_iItemHeight)); - - //добавление в конец или начало списка - if (-1 == insertBeforeIdx) - { - m_ItemList.push_back(pItem); - pItem->SetIndex(m_ItemList.size() - 1); - } - else - { - //изменить значения индексов уже добавленых элементов - if (!m_ItemList.empty()) - R_ASSERT(static_cast(insertBeforeIdx) <= m_ItemList.size()); - - LIST_ITEM_LIST_it it2 = m_ItemList.begin(); - std::advance(it2, insertBeforeIdx); - for (LIST_ITEM_LIST_it it = it2; m_ItemList.end() != it; ++it) - { - (*it)->SetIndex((*it)->GetIndex() + 1); - } - m_ItemList.insert(it2, pItem); - pItem->SetIndex(insertBeforeIdx); - } - - UpdateList(); - - //обновить полосу прокрутки - m_ScrollBar->SetRange(0, s16(m_ItemList.size() - 1)); - m_ScrollBar->SetPageSize((m_iRowNum < (int)m_ItemList.size()) ? m_iRowNum : (int)m_ItemList.size()); - m_ScrollBar->SetScrollPos(s16(m_iFirstShownIndex)); - // m_ScrollBar.Refresh(); - - UpdateScrollBar(); - - return true; -} diff --git a/src/xrGame/ui/UIListWnd_script.cpp b/src/xrGame/ui/UIListWnd_script.cpp deleted file mode 100644 index c91f201e0e8..00000000000 --- a/src/xrGame/ui/UIListWnd_script.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "pch_script.h" -#include "UIListWnd.h" -#include "UIListItemEx.h" -#include "ServerList.h" -#include "UIMapList.h" -#include "UISpinText.h" -#include "UIMapInfo.h" -#include "UIComboBox.h" - -bool CUIListWnd::AddItem_script(CUIListItem* item) { return AddItem(item, -1); } - -struct CUIListItemWrapper : public CUIListItem, public luabind::wrap_base -{ -}; - -struct CUIListItemExWrapper : public CUIListItemEx, public luabind::wrap_base -{ -}; - -void CUIListWnd::script_register(lua_State* L) -{ - using namespace luabind; - - module(L) - [ - class_("CUIListWnd") - .def(constructor<>()) - // .def("AddText", &CUIListWnd::AddText_script) - .def("AddItem", &CUIListWnd::AddItem_script, adopt(_2)) - .def("RemoveItem", &CUIListWnd::RemoveItem) - .def("RemoveAll", &CUIListWnd::RemoveAll) - .def("EnableScrollBar", &CUIListWnd::EnableScrollBar) - .def("IsScrollBarEnabled", &CUIListWnd::IsScrollBarEnabled) - .def("ScrollToBegin", &CUIListWnd::ScrollToBegin) - .def("ScrollToEnd", &CUIListWnd::ScrollToEnd) - .def("SetItemHeight", &CUIListWnd::SetItemHeight) - .def("GetItem", &CUIListWnd::GetItem) - .def("GetItemPos", &CUIListWnd::GetItemPos) - .def("GetSize", &CUIListWnd::GetItemsCount) - .def("ScrollToBegin", &CUIListWnd::ScrollToBegin) - .def("ScrollToEnd", &CUIListWnd::ScrollToEnd) - .def("ScrollToPos", &CUIListWnd::ScrollToPos) - .def("SetWidth", &CUIListWnd::SetWidth) - .def("SetTextColor", &CUIListWnd::SetTextColor) - .def("ActivateList", &CUIListWnd::ActivateList) - .def("IsListActive", &CUIListWnd::IsListActive) - .def("SetVertFlip", &CUIListWnd::SetVertFlip) - .def("GetVertFlip", &CUIListWnd::GetVertFlip) - .def("SetFocusedItem", &CUIListWnd::SetFocusedItem) - .def("GetFocusedItem", &CUIListWnd::GetFocusedItem) - .def("ShowSelectedItem", &CUIListWnd::ShowSelectedItem) - - .def("GetSelectedItem", &CUIListWnd::GetSelectedItem) - .def("ResetFocusCapture", &CUIListWnd::ResetFocusCapture), - - class_("CUIListItem") - .def(constructor<>()), - - class_("CUIListItemEx") - .def(constructor<>()) - .def("SetSelectionColor", &CUIListItemEx::SetSelectionColor), - - class_("SServerFilters") - .def(constructor<>()) - .def_readwrite("empty", &SServerFilters::empty) - .def_readwrite("full", &SServerFilters::full) - .def_readwrite("with_pass", &SServerFilters::with_pass) - .def_readwrite("without_pass", &SServerFilters::without_pass) - .def_readwrite("without_ff", &SServerFilters::without_ff) -#ifdef BATTLEYE - .def_readwrite("with_battleye", &SServerFilters::with_battleye) -#endif // BATTLEYE - .def_readwrite("listen_servers", &SServerFilters::listen_servers), - - class_("CServerList") - .def(constructor<>()) - .def("ConnectToSelected", &CServerList::ConnectToSelected) - .def("SetFilters", &CServerList::SetFilters) - .def("SetPlayerName", &CServerList::SetPlayerName) - .def("RefreshList", &CServerList::RefreshGameSpyList) - .def("RefreshQuick", &CServerList::RefreshQuick) - .def("ShowServerInfo", &CServerList::ShowServerInfo) - .def("NetRadioChanged", &CServerList::NetRadioChanged) - .def("SetSortFunc", &CServerList::SetSortFunc), - - class_("CUIMapList") - .def(constructor<>()) - .def("SetWeatherSelector", &CUIMapList::SetWeatherSelector) - .def("SetModeSelector", &CUIMapList::SetModeSelector) - .def("OnModeChange", &CUIMapList::OnModeChange) - .def("LoadMapList", &CUIMapList::LoadMapList) - .def("SaveMapList", &CUIMapList::SaveMapList) - .def("GetCommandLine", &CUIMapList::GetCommandLine) - .def("SetServerParams", &CUIMapList::SetServerParams) - .def("GetCurGameType", &CUIMapList::GetCurGameType) - .def("StartDedicatedServer", &CUIMapList::StartDedicatedServer) - .def("SetMapPic", &CUIMapList::SetMapPic) - .def("SetMapInfo", &CUIMapList::SetMapInfo) - .def("ClearList", &CUIMapList::ClearList) - .def("IsEmpty", &CUIMapList::IsEmpty), - - class_>("GAME_TYPE") - .enum_("gametype") - [ - value("GAME_UNKNOWN", int(-1)), - value("eGameIDDeathmatch", int(eGameIDDeathmatch)), - value("eGameIDTeamDeathmatch", int(eGameIDTeamDeathmatch)), - value("eGameIDArtefactHunt", int(eGameIDArtefactHunt)), - value("eGameIDCaptureTheArtefact", int(eGameIDCaptureTheArtefact)) - ] - - ]; -} diff --git a/src/xrUICore/ListWnd/UIListItemEx.cpp b/src/xrUICore/ListWnd/UIListItemEx.cpp index 1a35a5a91a1..3b7b12710c6 100644 --- a/src/xrUICore/ListWnd/UIListItemEx.cpp +++ b/src/xrUICore/ListWnd/UIListItemEx.cpp @@ -15,7 +15,7 @@ CUIListItemEx::CUIListItemEx() : m_dwSelectionColor(color_argb(200, 95, 82, 74)) { //. InitTexture("ui\\hud_map_point"); //. SetStretchTexture(true); - CUIStatic::SetColor(color_argb(0, 0, 0, 0)); + inherited::SetColor(color_argb(0, 0, 0, 0)); } CUIListItemEx::~CUIListItemEx() diff --git a/src/xrUICore/ListWnd/UIListWnd.cpp b/src/xrUICore/ListWnd/UIListWnd.cpp index b77e0f42bb2..6bb66e764e6 100644 --- a/src/xrUICore/ListWnd/UIListWnd.cpp +++ b/src/xrUICore/ListWnd/UIListWnd.cpp @@ -71,7 +71,6 @@ void CUIListWnd::InitListWnd(Fvector2 pos, Fvector2 size, float item_height) SetItemHeight(item_height); m_iRowNum = iFloor(size.y / m_iItemHeight); - m_ScrollBar->SetRange(0, 0); m_ScrollBar->SetPageSize(0); m_ScrollBar->SetScrollPos(s16(m_iFirstShownIndex)); @@ -130,7 +129,6 @@ void CUIListWnd::RemoveItem(int index) DetachChild(*it); - UpdateList(); //обновить полосу прокрутки @@ -170,7 +168,6 @@ CUIListItem* CUIListWnd::GetItem(int index) return (*it); } - void CUIListWnd::DetachChild(CUIWindow* pChild) { LIST_ITEM_LIST_it it = std::find(m_ItemList.begin(), m_ItemList.end(), pChild); @@ -192,7 +189,6 @@ void CUIListWnd::RemoveAll() m_iFirstShownIndex = 0; - UpdateList(); Reset(); @@ -204,7 +200,6 @@ void CUIListWnd::RemoveAll() UpdateScrollBar(); } - ////////////////////////////////////////////////////////////////////////// void CUIListWnd::UpdateList() @@ -224,7 +219,6 @@ void CUIListWnd::UpdateList() (*it)->Show(false); } - //показать текущий список for (int i = m_iFirstShownIndex; i < _min(m_ItemList.size(), m_iFirstShownIndex + m_iRowNum + 1); @@ -249,14 +243,12 @@ void CUIListWnd::UpdateList() --it; //спрятать все после - for (u32 k = m_iFirstShownIndex + m_iRowNum; - k < m_ItemList.size(); ++k, ++it) + for (u32 k = m_iFirstShownIndex + m_iRowNum; k < m_ItemList.size(); ++k, ++it) { (*it)->Show(false); // (*it)->Enable(false); } - UpdateScrollBar(); } @@ -292,8 +284,7 @@ void CUIListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) continue; if (pListItem2->GetGroupID() == -1) continue; - if (pListItem2->GetGroupID() == - pListItem->GetGroupID()) + if (pListItem2->GetGroupID() == pListItem->GetGroupID()) { pListItem2->SetHighlightText(true); pListItem2->SendMessage(this, LIST_ITEM_SELECT, pData); @@ -319,14 +310,15 @@ void CUIListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) else if (m_iFocusedItem >= 0) m_iFocusedItemGroupID = GetItem(m_iFocusedItem)->GetGroupID(); - // prototype code for (auto it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) { pListItem2 = smart_cast(*it); - if (!pListItem2) continue; - if (pListItem2->GetGroupID() == -1) continue; + if (!pListItem2) + continue; + if (pListItem2->GetGroupID() == -1) + continue; if (pListItem2->GetGroupID() == pListItem->GetGroupID()) { pListItem2->SetHighlightText(true); @@ -342,12 +334,14 @@ void CUIListWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) } else if (WINDOW_FOCUS_LOST == msg) { - if (pListItem->GetIndex() == m_iFocusedItem && !m_bForceFocusedItem) m_iFocusedItem = -1; + if (pListItem->GetIndex() == m_iFocusedItem && !m_bForceFocusedItem) + m_iFocusedItem = -1; for (auto it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) { pListItem2 = smart_cast(*it); - if (!pListItem2) continue; + if (!pListItem2) + continue; pListItem2->SetHighlightText(false); pListItem2->SendMessage(this, WINDOW_FOCUS_LOST, pData); } @@ -386,8 +380,10 @@ void CUIListWnd::Draw() for (auto it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) { CUIListItem* pListItem2 = smart_cast(*it); - if (!pListItem2) continue; - if (pListItem2->GetGroupID() == -1) continue; + if (!pListItem2) + continue; + if (pListItem2->GetGroupID() == -1) + continue; if ((pListItem2->GetGroupID() == m_iFocusedItemGroupID) && ((pListItem2->GetIndex() >= m_iFirstShownIndex) && (pListItem2->GetIndex() <= m_iRowNum + m_iFirstShownIndex - 1))) @@ -404,8 +400,10 @@ void CUIListWnd::Draw() for (auto it = m_ChildWndList.begin(); it != m_ChildWndList.end(); ++it) { CUIListItem* pListItem2 = smart_cast(*it); - if (!pListItem2) continue; - if (pListItem2->GetGroupID() == -1) continue; + if (!pListItem2) + continue; + if (pListItem2->GetGroupID() == -1) + continue; if (pListItem2->GetIndex() == m_iSelectedItem) { GEnv.UI->PushScissor(rect); @@ -420,7 +418,6 @@ void CUIListWnd::Draw() CUIWindow::Draw(); } - void CUIListWnd::SetItemWidth(float iItemWidth) { m_iItemWidth = iItemWidth; @@ -474,7 +471,6 @@ int CUIListWnd::FindItemWithValue(int iValue) return -1; } - bool CUIListWnd::OnMouseAction(float x, float y, EUIMessages mouse_action) { switch (mouse_action) diff --git a/src/xrUICore/ListWnd/UIListWnd.h b/src/xrUICore/ListWnd/UIListWnd.h index 4d8f0297d53..55e8302e835 100644 --- a/src/xrUICore/ListWnd/UIListWnd.h +++ b/src/xrUICore/ListWnd/UIListWnd.h @@ -19,6 +19,7 @@ class XRUICORE_API CUIListWnd final : public CUIWindow shared_str m_scrollbar_profile; void DrawActiveBackFrame(const Frect& rect, CUIListItem* itm); + public: CUIListWnd(); virtual ~CUIListWnd(); diff --git a/src/xrUICore/ListWnd/UIListWnd_inline.h b/src/xrUICore/ListWnd/UIListWnd_inline.h index 1d7452eb9bf..cd7ba61f667 100644 --- a/src/xrUICore/ListWnd/UIListWnd_inline.h +++ b/src/xrUICore/ListWnd/UIListWnd_inline.h @@ -30,7 +30,6 @@ bool CUIListWnd::AddItem(const char* str, const float shift, void* pData, return AddItem(pItem, insertBeforeIdx); } - template bool CUIListWnd::AddItem(Element* pItem, int insertBeforeIdx) { @@ -42,7 +41,6 @@ bool CUIListWnd::AddItem(Element* pItem, int insertBeforeIdx) : GetItemsCount() * m_iItemHeight), Fvector2().set(m_iItemWidth, m_iItemHeight)); - //добавление в конец или начало списка if (-1 == insertBeforeIdx) { From dd33e66c378335fd084ddfbfe2a7c11f949c0e92 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 20 Mar 2024 14:02:05 +0500 Subject: [PATCH 262/497] Return Secondary thread This commit revises b7f2012ca6585f26c0ff8e9be56b3245714897a7, and the thread is returned in the revised state! It can process task manager tasks now! --- src/xrCore/Threading/TaskManager.cpp | 2 +- src/xrEngine/Device_create.cpp | 5 +++++ src/xrEngine/device.cpp | 33 ++++++++++++++++++++-------- src/xrEngine/device.h | 7 ++++-- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 3d5089a0b06..75fa36a26de 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -35,7 +35,7 @@ xr_unique_ptr TaskScheduler; -static constexpr size_t OTHER_THREADS_COUNT = 1; // Primary thread +static constexpr size_t OTHER_THREADS_COUNT = 2; // Primary and Secondary thread static u32 ttapi_dwFastIter = 0; diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index 1bf765e5631..768fde0218c 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -21,6 +21,11 @@ void CRenderDevice::Create() if (b_is_Ready) return; // prevent double call + Threading::SpawnThread([] (void* context) + { + static_cast(context)->SecondaryThreadProc(); + }, "Secondary thread", 0, this); + Statistic = xr_new(); Log("Starting RENDER device..."); #ifdef _EDITOR diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index e6a79f64c09..0140de614b6 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -66,7 +66,7 @@ void CheckPrivilegySlowdown() { if (Device.GetStats().fFPS < 30) Sleep(1); - if (Device.mt_bMustExit || !pSettings || !Console || !pInput) + if (Device.mt_bMustExit.load(std::memory_order_acquire) || !pSettings || !Console || !pInput) return; } }; @@ -253,12 +253,22 @@ void CRenderDevice::DoRender() stats.RenderTotal.accum = renderTotalReal.accum; } -void CRenderDevice::ProcessParallelSequence(Task&, void*) +void CRenderDevice::SecondaryThreadProc() { - for (u32 pit = 0; pit < seqParallel.size(); pit++) - seqParallel[pit](); - seqParallel.clear(); - seqFrameMT.Process(); + while (!mt_bMustExit.load(std::memory_order_acquire)) + { + if (executeSecondaryTasks.load(std::memory_order_acquire)) + { + for (u32 pit = 0; pit < seqParallel.size(); pit++) + seqParallel[pit](); + seqParallel.clear(); + seqFrameMT.Process(); + executeSecondaryTasks.store(false, std::memory_order_relaxed); + secondaryTasksExecuted.store(true, std::memory_order_release); + } + TaskScheduler->ExecuteOneTask(); + } + secondaryThreadFinished.store(true, std::memory_order_release); } void CRenderDevice::ProcessFrame() @@ -272,7 +282,7 @@ void CRenderDevice::ProcessFrame() BeforeRender(); - const auto& processSeqParallel = TaskScheduler->AddTask("Secondary Thread Proc", { this, &CRenderDevice::ProcessParallelSequence }); + executeSecondaryTasks.store(true, std::memory_order_release); DoRender(); @@ -290,7 +300,10 @@ void CRenderDevice::ProcessFrame() if (frameTime < updateDelta) Sleep(updateDelta - frameTime); - TaskScheduler->Wait(processSeqParallel); + while (!secondaryTasksExecuted.load(std::memory_order_acquire)) + TaskScheduler->ExecuteOneTask(); + + secondaryTasksExecuted.store(false, std::memory_order_relaxed); if (!b_is_Active) Sleep(1); @@ -400,7 +413,9 @@ void CRenderDevice::Run() void CRenderDevice::Shutdown() { // Stop Balance-Thread - mt_bMustExit = true; + mt_bMustExit.store(true, std::memory_order_release); + while (!secondaryThreadFinished.load(std::memory_order_acquire)) + SDL_PumpEvents(); seqAppEnd.Process(); } diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 85ef7373a35..0b57322134f 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -164,7 +164,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler bool Paused(); private: - void ProcessParallelSequence(Task&, void*); + void SecondaryThreadProc(); public: // Scene control @@ -230,10 +230,13 @@ class ENGINE_API CRenderDevice : public IWindowHandler return (Timer.time_factor()); } +private: + std::atomic_bool executeSecondaryTasks{}, secondaryTasksExecuted{}, secondaryThreadFinished{}; + public: // Multi-threading Event PresentationFinished = nullptr; - volatile bool mt_bMustExit{}; + std::atomic_bool mt_bMustExit{}; static constexpr u32 MaximalWaitTime = 16; // ms From c1b789a41ebf4b76406d18cd9c88e07feb210c00 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 7 Apr 2024 22:10:38 +0500 Subject: [PATCH 263/497] Task manager refactoring Simplification and enhancement --- src/xrCore/Threading/TaskManager.cpp | 165 ++++++++------------------- src/xrCore/Threading/TaskManager.hpp | 31 +++-- src/xrEngine/Stats.cpp | 12 +- src/xrEngine/device.cpp | 2 + 4 files changed, 63 insertions(+), 147 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 75fa36a26de..0773d906218 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -64,27 +64,6 @@ class TaskStorageSize static constexpr size_t TASK_STORAGE_SIZE = TaskStorageSize::Get<12>(); // 4096 tasks static constexpr size_t TASK_STORAGE_MASK = TASK_STORAGE_SIZE - 1; -class FallbackTaskAllocator -{ - std::atomic_size_t m_allocated{}; - Task m_storage[TASK_STORAGE_SIZE]; - -public: - Task* allocate() - { - const auto task_pos = m_allocated.fetch_add(1, std::memory_order_acq_rel); - Task* task = &m_storage[task_pos & TASK_STORAGE_MASK]; - R_ASSERT2(task->IsFinished(), "Both thread local and fallback task allocator are full. " - "Too much workload for one thread."); - return task; - } - - size_t get_allocated_count() const - { - return m_allocated.load(std::memory_order_relaxed); - } -} static s_task_allocator_mt; - class TaskAllocator { size_t m_allocated{}; @@ -94,11 +73,7 @@ class TaskAllocator Task* allocate() { Task* task = &m_storage[m_allocated++ & TASK_STORAGE_MASK]; - if (!task->IsFinished()) // XXX: mark as unlikely - { - --m_allocated; - return s_task_allocator_mt.allocate(); - } + VERIFY(task->IsFinished()); return task; } } static thread_local s_tl_allocator; @@ -151,9 +126,8 @@ class TaskQueue } }; -class TaskWorkerStats +struct TaskWorkerStats { -public: size_t allocatedTasks{}; size_t pushedTasks{}; size_t finishedTasks{}; @@ -162,11 +136,16 @@ class TaskWorkerStats class TaskWorker : public TaskQueue, public TaskWorkerStats { public: - std::atomic steal_from{}; - std::atomic_bool sleeps{}; - Event event; - size_t id; - CRandom random{ s32(std::intptr_t(this)) }; + Event event; + CRandom random{ s32(std::intptr_t(this)) }; + size_t id { size_t(-1) }; + std::atomic_bool sleeps{ true }; + + void WakeUpIfNeeded() + { + if (!empty() && sleeps.load(std::memory_order_relaxed)) + event.Set(); // Wake up, we have work to do! + } } static thread_local s_tl_worker; static TaskWorker* s_main_thread_worker = nullptr; @@ -210,11 +189,12 @@ void CalcIterations() TaskManager::TaskManager() { + workers.reserve(std::thread::hardware_concurrency()); + s_main_thread_worker = &s_tl_worker; - s_main_thread_worker->id = 0; + RegisterThisThreadAsWorker(); const u32 threads = std::thread::hardware_concurrency() - OTHER_THREADS_COUNT; - workers.reserve(threads); for (u32 i = 0; i < threads; ++i) { Threading::SpawnThread([](void* this_ptr) @@ -236,7 +216,7 @@ TaskManager::~TaskManager() { shouldStop.store(true, std::memory_order_release); { - ScopeLock scope(&workersLock); + std::lock_guard guard{ workersLock }; for (TaskWorker* worker : workers) worker->event.Set(); } @@ -250,46 +230,24 @@ TaskManager::~TaskManager() s_main_thread_worker = nullptr; } -void TaskManager::SetThreadStatus(bool active) +void TaskManager::RegisterThisThreadAsWorker() { - s_tl_worker.sleeps.store(!active, std::memory_order_relaxed); - if (active) - activeWorkersCount.fetch_add(1, std::memory_order_relaxed); - else - activeWorkersCount.fetch_sub(1, std::memory_order_relaxed); + std::lock_guard guard{ workersLock }; + s_tl_worker.id = workers.size(); + workers.emplace_back(&s_tl_worker); } -void TaskManager::WakeUpIfNeeded() const +void TaskManager::UnregisterThisThreadAsWorker() { - const auto overall = workersCount.load(std::memory_order_relaxed); - const auto active = activeWorkersCount.load(std::memory_order_relaxed); - if (active < overall) - { - auto* steal_from = &s_tl_worker; - for (auto* worker : workers) - { - if (worker == &s_tl_worker) - continue; - if (worker->sleeps.load(std::memory_order_relaxed)) - { - worker->steal_from.store(steal_from, std::memory_order_relaxed); - worker->event.Set(); - break; - } - } - } + std::lock_guard guard{ workersLock }; + s_tl_worker.id = size_t(-1); + workers.emplace_back(&s_tl_worker); } void TaskManager::TaskWorkerStart() { - { - ScopeLock scope(&workersLock); - workers.emplace_back(&s_tl_worker); - s_tl_worker.id = workers.size(); - } + RegisterThisThreadAsWorker(); workersCount.fetch_add(1, std::memory_order_release); - activeWorkersCount.fetch_add(1, std::memory_order_relaxed); - s_tl_worker.event.Wait(); const u32 fastIterations = ttapi_dwFastIter; @@ -311,19 +269,13 @@ void TaskManager::TaskWorkerStart() if (task) goto execute; } - check_main_queue: - { - task = s_main_thread_worker->steal(); - if (task) - goto execute; - } - steal: + //steal: { task = TryToSteal(); if (task) goto execute; } - count_spins: + //count_spins: { if (shouldStop.load(std::memory_order_consume)) break; @@ -335,21 +287,14 @@ void TaskManager::TaskWorkerStart() goto check_own_queue; } } - wait: + //wait: { - iteration = 0; - SetThreadStatus(false); - s_tl_worker.event.Wait(); - SetThreadStatus(true); - auto* stealFrom = s_tl_worker.steal_from.load(std::memory_order_relaxed); - if (stealFrom) + s_tl_worker.sleeps.store(true, std::memory_order_relaxed); { - while (Task* t = stealFrom->steal()) - { - ExecuteTask(*t); - } - s_tl_worker.steal_from.store(nullptr, std::memory_order_relaxed); + s_tl_worker.event.Wait(1); } + s_tl_worker.sleeps.store(false, std::memory_order_relaxed); + iteration = 0; goto check_own_queue; } } // while (true) @@ -367,25 +312,19 @@ void TaskManager::TaskWorkerStart() Task* TaskManager::TryToSteal() const { - const auto count = workersCount.load(std::memory_order_relaxed); - if (count == 1) - { - if (&s_tl_worker == s_main_thread_worker) - return workers[0]->steal(); - return nullptr; // thread itself - } + const auto count = workers.size(); - int steal_attempts = 3; + int steal_attempts = 5; while (steal_attempts > 0) { TaskWorker* other = workers[s_tl_worker.random.randI(count)]; if (other == &s_tl_worker) continue; - auto* task = other->steal(); - if (!other->empty() && other->sleeps.load(std::memory_order_relaxed)) - other->event.Set(); // Wake up, you have work to do! - if (task) + if (auto* task = other->steal()) + { + other->WakeUpIfNeeded(); return task; + } --steal_attempts; } return nullptr; @@ -423,10 +362,9 @@ void TaskManager::IncrementTaskJobsCounter(Task& parent) VERIFY2(prev != std::numeric_limits::max(), "Max jobs overflow. (too much children)"); } -void TaskManager::PushTask(Task& task) const +void TaskManager::PushTask(Task& task) { s_tl_worker.push(&task); - WakeUpIfNeeded(); ++s_tl_worker.pushedTasks; } @@ -435,7 +373,7 @@ void TaskManager::RunTask(Task& task) ExecuteTask(task); } -void TaskManager::Wait(const Task& task) +void TaskManager::Wait(const Task& task) const { while (!task.IsFinished()) { @@ -445,7 +383,7 @@ void TaskManager::Wait(const Task& task) } } -void TaskManager::WaitForChildren(const Task& task) +void TaskManager::WaitForChildren(const Task& task) const { while (!task.HasChildren()) { @@ -455,10 +393,8 @@ void TaskManager::WaitForChildren(const Task& task) } } -bool TaskManager::ExecuteOneTask() +bool TaskManager::ExecuteOneTask() const { - WakeUpIfNeeded(); - Task* task = s_tl_worker.pop(); if (!task) task = TryToSteal(); @@ -523,12 +459,7 @@ Task& TaskManager::AddTask(Task& parent, pcstr name, const Task::OnFinishFunc& o size_t TaskManager::GetWorkersCount() const { - return workersCount.load(std::memory_order_relaxed) + OTHER_THREADS_COUNT; -} - -size_t TaskManager::GetActiveWorkersCount() const -{ - return activeWorkersCount.load(std::memory_order_relaxed) + OTHER_THREADS_COUNT; + return workers.size(); } size_t TaskManager::GetCurrentWorkerID() @@ -536,15 +467,9 @@ size_t TaskManager::GetCurrentWorkerID() return s_tl_worker.id; } -void TaskManager::GetStats(size_t& allocated, size_t& allocatedWithFallback, size_t& pushed, size_t& finished) +void TaskManager::GetStats(size_t& allocated, size_t& pushed, size_t& finished) { - allocatedWithFallback += s_task_allocator_mt.get_allocated_count(); - - allocated += s_main_thread_worker->allocatedTasks; - pushed += s_main_thread_worker->pushedTasks; - finished += s_main_thread_worker->finishedTasks; - - ScopeLock scope(&workersLock); + std::lock_guard guard{ workersLock }; for (const TaskWorker* worker : workers) { allocated += worker->allocatedTasks; diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 6e917153457..9b39ae020ff 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -15,6 +15,8 @@ */ #pragma once +#include + #include "Event.hpp" #include "Task.hpp" @@ -24,11 +26,9 @@ class XRCORE_API TaskManager final { private: xr_vector workers; - Lock workersLock; + std::mutex workersLock; std::atomic_size_t workersCount{}; - std::atomic_size_t activeWorkersCount{}; - std::atomic_bool shouldStop{}; private: @@ -42,10 +42,6 @@ class XRCORE_API TaskManager final [[nodiscard]] ICF static Task* AllocateTask(); static void ICF IncrementTaskJobsCounter(Task& parent); -private: - void SetThreadStatus(bool active); - void WakeUpIfNeeded() const; - public: TaskManager(); ~TaskManager(); @@ -61,29 +57,30 @@ class XRCORE_API TaskManager final [[nodiscard]] static Task& CreateTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Run task in parallel - void PushTask(Task& task) const; + static void PushTask(Task& task); // Run task immediately in this thread static void RunTask(Task& task); // Shortcut: create a task and run it immediately - Task& AddTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - Task& AddTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Shortcut: create task and run it immediately - Task& AddTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - Task& AddTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); public: - void Wait(const Task& task); - void WaitForChildren(const Task& task); - bool ExecuteOneTask(); + void RegisterThisThreadAsWorker(); + void UnregisterThisThreadAsWorker(); + void Wait(const Task& task) const; + void WaitForChildren(const Task& task) const; + bool ExecuteOneTask() const; public: [[nodiscard]] size_t GetWorkersCount() const; - [[nodiscard]] size_t GetActiveWorkersCount() const; [[nodiscard]] static size_t GetCurrentWorkerID(); - void GetStats(size_t& allocated, size_t& allocatedWithFallback, size_t& pushed, size_t& finished); + void GetStats(size_t& allocated, size_t& pushed, size_t& finished); }; extern XRCORE_API xr_unique_ptr TaskScheduler; diff --git a/src/xrEngine/Stats.cpp b/src/xrEngine/Stats.cpp index 564655555d3..5fde2fb3c16 100644 --- a/src/xrEngine/Stats.cpp +++ b/src/xrEngine/Stats.cpp @@ -43,34 +43,26 @@ CStats::~CStats() static void DumpTaskManagerStatistics(IGameFont& font, IPerformanceAlert* alert) { - size_t allocated{}, allocatedWithFallback{}, pushed{}, finished{}; - TaskScheduler->GetStats(allocated, allocatedWithFallback, pushed, finished); + size_t allocated{}, pushed{}, finished{}; + TaskScheduler->GetStats(allocated, pushed, finished); static size_t allocatedPrev{}; - static size_t allocatedWithFallbackPrev{}; static size_t pushedPrev{}; static size_t finishedPrev{}; font.OutNext("Task scheduler: "); font.OutNext("- threads: %zu", TaskScheduler->GetWorkersCount()); - font.OutNext(" - active: %zu", TaskScheduler->GetActiveWorkersCount()); font.OutNext("- tasks: "); font.OutNext(" - total: "); font.OutNext(" - allocated: %zu", allocated); - font.OutNext(" - fallback:%zu", allocatedWithFallback); font.OutNext(" - pushed: %zu", pushed); font.OutNext(" - finished: %zu", finished); font.OutNext(" - this frame: "); font.OutNext(" - allocated: %zu", allocated - allocatedPrev); - font.OutNext(" - fallback:%zu", allocatedWithFallback - allocatedWithFallbackPrev); font.OutNext(" - pushed %zu", pushed - pushedPrev); font.OutNext(" - finished: %zu", finished - finishedPrev); - if (allocatedWithFallback != allocatedWithFallbackPrev) - alert->Print(font, "Task scheduler overload!"); - allocatedPrev = allocated; - allocatedWithFallbackPrev = allocatedWithFallback; pushedPrev = pushed; finishedPrev = finished; } diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 0140de614b6..4b4c8eef0ca 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -255,6 +255,7 @@ void CRenderDevice::DoRender() void CRenderDevice::SecondaryThreadProc() { + TaskScheduler->RegisterThisThreadAsWorker(); while (!mt_bMustExit.load(std::memory_order_acquire)) { if (executeSecondaryTasks.load(std::memory_order_acquire)) @@ -268,6 +269,7 @@ void CRenderDevice::SecondaryThreadProc() } TaskScheduler->ExecuteOneTask(); } + TaskScheduler->UnregisterThisThreadAsWorker(); secondaryThreadFinished.store(true, std::memory_order_release); } From 55677278859941f703c1ddee1f5f9715631f5f63 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 8 Apr 2024 00:12:19 +0500 Subject: [PATCH 264/497] xrSound: encapsulate all CSoundRender_Source member variables --- src/xrSound/SoundRender_Core.cpp | 2 +- src/xrSound/SoundRender_Core_Processor.cpp | 2 +- src/xrSound/SoundRender_Emitter.cpp | 4 +- src/xrSound/SoundRender_Emitter_FSM.cpp | 10 +-- src/xrSound/SoundRender_Emitter_StartStop.cpp | 13 ++-- src/xrSound/SoundRender_Source.cpp | 75 +++++++++---------- src/xrSound/SoundRender_Source.h | 43 ++++++----- src/xrSound/SoundRender_Target.cpp | 2 +- src/xrSound/SoundRender_TargetA.cpp | 2 +- 9 files changed, 77 insertions(+), 76 deletions(-) diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index df0d8fff9df..8541c4455f0 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -222,6 +222,6 @@ void CSoundRender_Core::refresh_sources() { CSoundRender_Source* s = kv.second; s->unload(); - s->load(*s->fname); + s->load(s->file_name()); } } diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 166e6396873..00a79bf3a7c 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -143,7 +143,7 @@ void CSoundRender_Core::statistic(CSound_stats* dest, CSound_stats_ext* ext) item.volume = emitter->smooth_volume; if (emitter->owner_data) { - item.name = emitter->source()->fname; + item.name = emitter->source()->file_name(); item.game_object = emitter->owner_data->g_object; item.game_type = emitter->owner_data->g_type; item.type = emitter->owner_data->s_type; diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index b157d72eeea..9826a3c446f 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -115,7 +115,7 @@ void CSoundRender_Emitter::set_cursor(u32 p) if (owner_data._get() && owner_data->fn_attached[0].size()) { - u32 bt = ((CSoundRender_Source*)owner_data->handle)->dwBytesTotal; + u32 bt = ((CSoundRender_Source*)owner_data->handle)->bytes_total(); if (m_stream_cursor >= m_cur_handle_cursor + bt) { SoundRender->i_destroy_source((CSoundRender_Source*)owner_data->handle); @@ -194,7 +194,7 @@ void CSoundRender_Emitter::fill_block(void* ptr, u32 size) } else { - const u32 bt_handle = ((CSoundRender_Source*)owner_data->handle)->dwBytesTotal; + const u32 bt_handle = ((CSoundRender_Source*)owner_data->handle)->bytes_total(); if (get_cursor(true) + size > m_cur_handle_cursor + bt_handle) { R_ASSERT(owner_data->fn_attached[0].size()); diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 5e2eccd6d01..b0030246503 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -8,7 +8,7 @@ XRSOUND_API extern float psSoundCull; -inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const SoundSourceInfo& info) //--#SM+#-- +inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const SoundDataInfo& info) //--#SM+#-- { if (fTime < fTimeStarted) fTime = fTimeStarted; // Андрюха посоветовал, ассерт что ниже вылетел из за паузы как то хитро @@ -151,7 +151,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) } else { - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->data_info()); //--#SM+#-- set_cursor(ptr); if (update_culling(dt)) @@ -162,7 +162,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) u32 ptr = calc_cursor( fTimeStarted, fTime, get_length_sec(), - source()->m_info); + source()->data_info()); set_cursor (ptr); */ SoundRender->i_start(this); @@ -204,7 +204,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { // switch to: PLAY m_current_state = stPlayingLooped; // switch state - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->data_info()); //--#SM+#-- set_cursor(ptr); SoundRender->i_start(this); @@ -253,7 +253,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = fTime + fRemainingTime; } - const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_info); + const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->data_info()); set_cursor(ptr); fTimeToRewind = 0.0f; diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index 33854fafb1d..3aa28f5d3ac 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -14,14 +14,15 @@ void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay VERIFY(_owner); owner_data = _owner; VERIFY(owner_data); - // source = (CSoundRender_Source*)owner_data->handle; p_source.position.set(0, 0, 0); - p_source.min_distance = source()->m_fMinDist; // DS3D_DEFAULTMINDISTANCE; - p_source.max_distance = source()->m_fMaxDist; // 300.f; - p_source.base_volume = source()->m_fBaseVolume; // 1.f - p_source.volume = 1.f; // 1.f + + const auto info = source()->info(); + p_source.min_distance = info.minDist; + p_source.max_distance = info.maxDist; + p_source.base_volume = info.baseVolume; + p_source.volume = 1.f; p_source.freq = 1.f; - p_source.max_ai_distance = source()->m_fMaxAIDist; // 300.f; + p_source.max_ai_distance = info.maxAIDist; if (fis_zero(delay, EPS_L)) { diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 482c74d18ee..4648822232d 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -3,15 +3,6 @@ #include "SoundRender_Core.h" #include "SoundRender_Source.h" -CSoundRender_Source::CSoundRender_Source() -{ - m_fMinDist = 1.f; - m_fMaxDist = 300.f; - m_fMaxAIDist = 300.f; - m_fBaseVolume = 1.f; - m_uGameType = 0; -} - CSoundRender_Source::~CSoundRender_Source() { unload(); } namespace @@ -57,13 +48,13 @@ void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) std::lock_guard guard{ read_lock }; // seek - const auto sample_offset = ogg_int64_t(byte_offset / m_info.blockAlign); + const auto sample_offset = ogg_int64_t(byte_offset / m_data_info.blockAlign); const u32 cur_pos = u32(ov_pcm_tell(&ovf)); if (cur_pos != sample_offset) ov_pcm_seek(&ovf, sample_offset); // decompress - if (m_info.format == SoundFormat::Float32) + if (m_data_info.format == SoundFormat::Float32) i_decompress(static_cast(dest), size); else i_decompress(static_cast(dest), size); @@ -85,7 +76,7 @@ void CSoundRender_Source::i_decompress(char* _dest, u32 size) void CSoundRender_Source::i_decompress(float* _dest, u32 size) { - s32 left = s32(size / m_info.blockAlign); + s32 left = s32(size / m_data_info.blockAlign); while (left) { float** pcm; @@ -98,7 +89,7 @@ void CSoundRender_Source::i_decompress(float* _dest, u32 size) samples = left; for (long j = 0; j < samples; j++) - for (long i = 0; i < m_info.channels; i++) + for (long i = 0; i < m_data_info.channels; i++) *_dest++ = pcm[i][j]; left -= samples; @@ -184,29 +175,31 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) return false; }); - m_info = {}; + m_data_info = {}; - m_info.samplesPerSec = ovi->rate; - m_info.channels = u16(ovi->channels); + m_data_info.samplesPerSec = ovi->rate; + m_data_info.channels = u16(ovi->channels); if (SoundRender->supports_float_pcm) { - m_info.format = SoundFormat::Float32; - m_info.bitsPerSample = 32; + m_data_info.format = SoundFormat::Float32; + m_data_info.bitsPerSample = 32; } else { - m_info.format = SoundFormat::PCM; - m_info.bitsPerSample = 16; + m_data_info.format = SoundFormat::PCM; + m_data_info.bitsPerSample = 16; } - m_info.blockAlign = m_info.bitsPerSample / 8 * m_info.channels; - m_info.avgBytesPerSec = m_info.samplesPerSec * m_info.blockAlign; - m_info.bytesPerBuffer = sdef_target_block * m_info.avgBytesPerSec / 1000; + m_data_info.blockAlign = m_data_info.bitsPerSample / 8 * m_data_info.channels; + m_data_info.avgBytesPerSec = m_data_info.samplesPerSec * m_data_info.blockAlign; + m_data_info.bytesPerBuffer = sdef_target_block * m_data_info.avgBytesPerSec / 1000; const s64 pcm_total = ov_pcm_total(&ovf, -1); - dwBytesTotal = u32(pcm_total * m_info.blockAlign); - fTimeTotal = dwBytesTotal / float(m_info.avgBytesPerSec); + dwBytesTotal = u32(pcm_total * m_data_info.blockAlign); + fTimeTotal = dwBytesTotal / float(m_data_info.avgBytesPerSec); + + m_info = {}; const vorbis_comment* ovm = ov_comment(&ovf, -1); if (ovm->comments) @@ -215,27 +208,27 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) const u32 vers = F.r_u32(); if (vers == 0x0001) { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = 1.f; - m_uGameType = F.r_u32(); - m_fMaxAIDist = m_fMaxDist; + m_info.minDist = F.r_float(); + m_info.maxDist = F.r_float(); + m_info.baseVolume = 1.f; + m_info.gameType = F.r_u32(); + m_info.maxAIDist = m_info.maxDist; } else if (vers == 0x0002) { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = F.r_float(); - m_uGameType = F.r_u32(); - m_fMaxAIDist = m_fMaxDist; + m_info.minDist = F.r_float(); + m_info.maxDist = F.r_float(); + m_info.baseVolume = F.r_float(); + m_info.gameType = F.r_u32(); + m_info.maxAIDist = m_info.maxDist; } else if (vers == OGG_COMMENT_VERSION) { - m_fMinDist = F.r_float(); - m_fMaxDist = F.r_float(); - m_fBaseVolume = F.r_float(); - m_uGameType = F.r_u32(); - m_fMaxAIDist = F.r_float(); + m_info.minDist = F.r_float(); + m_info.maxDist = F.r_float(); + m_info.baseVolume = F.r_float(); + m_info.gameType = F.r_u32(); + m_info.maxAIDist = F.r_float(); } else { @@ -251,7 +244,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) #endif } - R_ASSERT3_CURE(m_fMaxAIDist >= 0.1f && m_fMaxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, + R_ASSERT3_CURE(m_info.maxAIDist >= 0.1f && m_info.maxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, { detach(); return false; diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 6592fdb57af..94dd270a2e4 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -11,7 +11,7 @@ enum class SoundFormat Float32, }; -struct SoundSourceInfo +struct SoundDataInfo { SoundFormat format{}; u16 channels{}; // number of channels (i.e. mono, stereo...) @@ -22,27 +22,30 @@ struct SoundSourceInfo u32 bytesPerBuffer{}; // target buffer size }; -class XRSOUND_API CSoundRender_Source final : public CSound_source +struct SoundSourceInfo { -public: - shared_str pname; - shared_str fname; + float baseVolume; + float minDist; + float maxDist; + float maxAIDist; + u32 gameType; +}; +class XRSOUND_API CSoundRender_Source final : public CSound_source +{ OggVorbis_File ovf{}; IReader* wave{}; int refs{}; std::mutex read_lock; - float fTimeTotal; - u32 dwBytesTotal; + shared_str pname; + shared_str fname; - SoundSourceInfo m_info{}; + float fTimeTotal{}; + u32 dwBytesTotal{}; - float m_fBaseVolume; - float m_fMinDist; - float m_fMaxDist; - float m_fMaxAIDist; - u32 m_uGameType; + SoundDataInfo m_data_info{}; + SoundSourceInfo m_info{}; private: void i_decompress(char* dest, u32 size); @@ -51,7 +54,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source bool LoadWave(pcstr name, bool crashOnError); public: - CSoundRender_Source(); + CSoundRender_Source() = default; ~CSoundRender_Source() override; bool load(pcstr name, bool replaceWithNoSound = true, bool crashOnError = true); @@ -62,10 +65,14 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source void decompress(void* dest, u32 byte_offset, u32 size); + [[nodiscard]] pcstr file_name() const override { return fname.c_str(); } + [[nodiscard]] float length_sec() const override { return fTimeTotal; } - [[nodiscard]] u32 game_type() const override { return m_uGameType; } - [[nodiscard]] pcstr file_name() const override { return *fname; } - [[nodiscard]] float base_volume() const { return m_fBaseVolume; } - [[nodiscard]] u16 channels_num() const override { return m_info.channels; } [[nodiscard]] u32 bytes_total() const override { return dwBytesTotal; } + + [[nodiscard]] u16 channels_num() const override { return data_info().channels; } + [[nodiscard]] u32 game_type() const override { return info().gameType; } + + [[nodiscard]] const auto& data_info() const { return m_data_info; } + [[nodiscard]] const auto& info() const { return m_info; } }; diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index cdff9c81835..3575e75bd90 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -30,7 +30,7 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) // Calc storage for (auto& buf : temp_buf) - buf.resize(E->source()->m_info.bytesPerBuffer); + buf.resize(E->source()->data_info().bytesPerBuffer); dispatch_prefill_all(); } diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index c88bd0f950b..d289b2a7783 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -200,7 +200,7 @@ void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size { R_ASSERT(m_pEmitter); - const auto& info = m_pEmitter->source()->m_info; + const auto& info = m_pEmitter->source()->data_info(); const bool mono = info.channels == 1; ALuint format; From cae5f5e91f3fd2a1879d2e4333709f4397f25edb Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 8 Apr 2024 14:20:54 +0500 Subject: [PATCH 265/497] Fix non-Windows build --- src/xrSound/SoundRender_Source.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 94dd270a2e4..0f7381df05b 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -65,6 +65,9 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source void decompress(void* dest, u32 byte_offset, u32 size); + [[nodiscard]] const auto& data_info() const { return m_data_info; } + [[nodiscard]] const auto& info() const { return m_info; } + [[nodiscard]] pcstr file_name() const override { return fname.c_str(); } [[nodiscard]] float length_sec() const override { return fTimeTotal; } @@ -72,7 +75,4 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source [[nodiscard]] u16 channels_num() const override { return data_info().channels; } [[nodiscard]] u32 game_type() const override { return info().gameType; } - - [[nodiscard]] const auto& data_info() const { return m_data_info; } - [[nodiscard]] const auto& info() const { return m_info; } }; From 536dcc5fd2275286b99b9e4763a35d5bb976d2e7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 9 Apr 2024 02:58:57 +0500 Subject: [PATCH 266/497] Use better RNG in the task manager --- src/xrCore/CMakeLists.txt | 2 + src/xrCore/Math/fast_lc16.cpp | 20 ++++++ src/xrCore/Math/fast_lc16.hpp | 92 ++++++++++++++++++++++++++++ src/xrCore/Threading/TaskManager.cpp | 13 +++- src/xrCore/xrCore.vcxproj | 2 + src/xrCore/xrCore.vcxproj.filters | 6 ++ 6 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 src/xrCore/Math/fast_lc16.cpp create mode 100644 src/xrCore/Math/fast_lc16.hpp diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 7c2874d306d..8737e41b20b 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -305,6 +305,8 @@ target_sources_grouped( TARGET xrCore NAME "Math\\RNG" FILES + Math/fast_lc16.cpp + Math/fast_lc16.hpp Math/Random32.hpp ) diff --git a/src/xrCore/Math/fast_lc16.cpp b/src/xrCore/Math/fast_lc16.cpp new file mode 100644 index 00000000000..6b82e815d8f --- /dev/null +++ b/src/xrCore/Math/fast_lc16.cpp @@ -0,0 +1,20 @@ +#include "stdafx.h" + +#include "fast_lc16.hpp" + +#include + +namespace random +{ +static std::random_device s_random_device; + +fast_lc16::fast_lc16() +{ + seed(s_random_device()); +} + +void fast_lc16::seed() +{ + seed(s_random_device()); +} +} // namespace random diff --git a/src/xrCore/Math/fast_lc16.hpp b/src/xrCore/Math/fast_lc16.hpp new file mode 100644 index 00000000000..45bad8e7c88 --- /dev/null +++ b/src/xrCore/Math/fast_lc16.hpp @@ -0,0 +1,92 @@ +/////////////////////////////////////////////////////////////////////////// +/// @file fast_lc16.hpp +/// @author Sultan Uramaev (Xottab_DUTY) +/// @brief Based on FastRandom class extracted from Intel TBB +/// which is authored by Intel Corporation +/// and licenced by Apache licence +/////////////////////////////////////////////////////////////////////////// +#pragma once + +namespace random +{ +//! A fast random number generator. +/** Uses linear congruential method. */ +class fast_lc16 final +{ + u32 x, c; + +public: + using result_type = u16; + + static + constexpr u32 a = 0x9e3779b1; // a big prime number + +public: + fast_lc16 ( ); + + explicit fast_lc16 ( u32 seed_v ) + { + seed ( seed_v ); + } + + explicit fast_lc16 ( u64 seed_v ) + { + seed ( seed_v ); + } + + fast_lc16 ( void* unique_ptr ) + { + seed ( uintptr_t(unique_ptr) ); + } + +private: + template < int > + struct int_to_type { }; + +public: + void seed ( ); + + template < typename T > + void seed ( T value ) + { + seed ( value, int_to_type() ); + } + + void seed ( uint64_t value, int_to_type<8> ) + { + seed ( uint32_t((value >> 32) + value), int_to_type<4>() ); + } + + void seed ( uint32_t value, int_to_type<4> ) + { + // threads use different seeds for unique sequences + c = (value | 1) * 0xba5703f5; // c must be odd, shuffle by a prime number + x = c ^ (value >> 1); // also shuffle x for the first operator() invocation + } + +public: + result_type operator() ( ) + { + result_type const r = static_cast( x >> 16 ); + VERIFY2 ( c & 1, "c must be odd for big rng period" ); + + x = x * a + c; + return r; + } + +public: + [[nodiscard]] + static + constexpr result_type min ( ) noexcept + { + return std::numeric_limits< result_type >::min ( ); + } + + [[nodiscard]] + static + constexpr result_type max ( ) noexcept + { + return std::numeric_limits< result_type >::max ( ); + } +}; +} // namespace random diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 0773d906218..789685c7571 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -23,6 +23,10 @@ #include #include +#include "Math/fast_lc16.hpp" + +#include + #if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) @@ -136,8 +140,10 @@ struct TaskWorkerStats class TaskWorker : public TaskQueue, public TaskWorkerStats { public: + using rng_t = random::fast_lc16; + Event event; - CRandom random{ s32(std::intptr_t(this)) }; + rng_t random{ this }; size_t id { size_t(-1) }; std::atomic_bool sleeps{ true }; @@ -312,12 +318,13 @@ void TaskManager::TaskWorkerStart() Task* TaskManager::TryToSteal() const { - const auto count = workers.size(); + std::uniform_int_distribution dist{ 0, static_cast(workers.size() - 1) }; int steal_attempts = 5; while (steal_attempts > 0) { - TaskWorker* other = workers[s_tl_worker.random.randI(count)]; + const auto idx = dist(s_tl_worker.random); + TaskWorker* other = workers[idx]; if (other == &s_tl_worker) continue; if (auto* task = other->steal()) diff --git a/src/xrCore/xrCore.vcxproj b/src/xrCore/xrCore.vcxproj index c31c6f74cf1..0c67bcea4ab 100644 --- a/src/xrCore/xrCore.vcxproj +++ b/src/xrCore/xrCore.vcxproj @@ -55,6 +55,7 @@ call .GitInfo.cmd + @@ -177,6 +178,7 @@ call .GitInfo.cmd + diff --git a/src/xrCore/xrCore.vcxproj.filters b/src/xrCore/xrCore.vcxproj.filters index 45d2a51cf57..e086469be15 100644 --- a/src/xrCore/xrCore.vcxproj.filters +++ b/src/xrCore/xrCore.vcxproj.filters @@ -327,6 +327,9 @@ Math + + Math\RNG + @@ -704,6 +707,9 @@ Threading + + Math\RNG + From a9fc9a9f92cee99e5f9750aac487252c524bff2e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 9 Apr 2024 04:02:16 +0500 Subject: [PATCH 267/497] Simplify task manager Fixes crash on exit --- src/xrCore/Threading/TaskManager.cpp | 105 ++++++++++++++++----------- src/xrCore/Threading/TaskManager.hpp | 6 +- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 789685c7571..3f5feddcdaa 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -145,7 +145,7 @@ class TaskWorker : public TaskQueue, public TaskWorkerStats Event event; rng_t random{ this }; size_t id { size_t(-1) }; - std::atomic_bool sleeps{ true }; + std::atomic_bool sleeps{}; void WakeUpIfNeeded() { @@ -154,8 +154,6 @@ class TaskWorker : public TaskQueue, public TaskWorkerStats } } static thread_local s_tl_worker; -static TaskWorker* s_main_thread_worker = nullptr; - class ThreadPriorityHelper { Threading::priority_class m_priority; @@ -195,9 +193,10 @@ void CalcIterations() TaskManager::TaskManager() { + CalcIterations(); + workers.reserve(std::thread::hardware_concurrency()); - s_main_thread_worker = &s_tl_worker; RegisterThisThreadAsWorker(); const u32 threads = std::thread::hardware_concurrency() - OTHER_THREADS_COUNT; @@ -205,39 +204,41 @@ TaskManager::TaskManager() { Threading::SpawnThread([](void* this_ptr) { - TaskManager& self = *static_cast(this_ptr); - self.TaskWorkerStart(); + const auto self = static_cast(this_ptr); + self->TaskWorkerStart(); }, "Task Worker", 0, this); } - CalcIterations(); - while (threads != workersCount.load(std::memory_order_consume)) - { - Sleep(2); - } - for (TaskWorker* worker : workers) - worker->event.Set(); } TaskManager::~TaskManager() { shouldStop.store(true, std::memory_order_release); + + // Finish all pending tasks + while (Task* t = s_tl_worker.pop()) + { + ExecuteTask(*t); + } + + UnregisterThisThreadAsWorker(); { std::lock_guard guard{ workersLock }; for (TaskWorker* worker : workers) worker->event.Set(); } - while (workersCount.load(std::memory_order_consume)) + while (activeWorkersCount.load(std::memory_order_acquire) || workers.size()) { Sleep(2); } - for (TaskWorker* worker : workers) - worker->event.Set(); - - s_main_thread_worker = nullptr; + // Capture the last worker that might still be finishing + std::lock_guard guard{ workersLock }; } void TaskManager::RegisterThisThreadAsWorker() { + R_ASSERT2(workers.size() < std::thread::hardware_concurrency(), + "You must change OTHER_THREADS_COUNT if you want to register more custom threads."); + std::lock_guard guard{ workersLock }; s_tl_worker.id = workers.size(); workers.emplace_back(&s_tl_worker); @@ -246,15 +247,33 @@ void TaskManager::RegisterThisThreadAsWorker() void TaskManager::UnregisterThisThreadAsWorker() { std::lock_guard guard{ workersLock }; + + shouldPause.store(true, std::memory_order_release); + while (activeWorkersCount.load(std::memory_order_relaxed)) + Sleep(2); + s_tl_worker.id = size_t(-1); - workers.emplace_back(&s_tl_worker); + + const auto it = std::find(workers.begin(), workers.end(), &s_tl_worker); + if (it != workers.end()) + workers.erase(it); + + shouldPause.store(false, std::memory_order_release); +} + +void TaskManager::SetThreadStatus(bool active) +{ + s_tl_worker.sleeps.store(!active, std::memory_order_relaxed); + if (active) + activeWorkersCount.fetch_add(1, std::memory_order_relaxed); + else + activeWorkersCount.fetch_sub(1, std::memory_order_relaxed); } void TaskManager::TaskWorkerStart() { RegisterThisThreadAsWorker(); - workersCount.fetch_add(1, std::memory_order_release); - s_tl_worker.event.Wait(); + SetThreadStatus(true); const u32 fastIterations = ttapi_dwFastIter; @@ -262,49 +281,52 @@ void TaskManager::TaskWorkerStart() Task* task; while (true) { - goto check_own_queue; + goto get_task; execute: { ExecuteTask(*task); iteration = 0; } - check_own_queue: + get_task: { + if (shouldStop.load(std::memory_order_consume)) + break; + if (shouldPause.load(std::memory_order_consume)) + goto wait; + task = s_tl_worker.pop(); - if (task) - goto execute; - } - //steal: - { - task = TryToSteal(); + if (!task) + task = TryToSteal(); + if (task) goto execute; } //count_spins: { - if (shouldStop.load(std::memory_order_consume)) - break; - ++iteration; if (iteration < fastIterations) { _mm_pause(); - goto check_own_queue; + goto get_task; } } - //wait: + wait: { - s_tl_worker.sleeps.store(true, std::memory_order_relaxed); + SetThreadStatus(false); + do { s_tl_worker.event.Wait(1); - } - s_tl_worker.sleeps.store(false, std::memory_order_relaxed); + } while (shouldPause.load(std::memory_order_consume)); + SetThreadStatus(true); + iteration = 0; - goto check_own_queue; + goto get_task; } } // while (true) + SetThreadStatus(false); + // Finish all pending tasks while (Task* t = s_tl_worker.pop()) { @@ -312,8 +334,7 @@ void TaskManager::TaskWorkerStart() } // Prepare to exit - workersCount.fetch_sub(1, std::memory_order_release); - s_tl_worker.event.Wait(); // prevent crash when other thread tries to steal + UnregisterThisThreadAsWorker(); } Task* TaskManager::TryToSteal() const @@ -385,7 +406,7 @@ void TaskManager::Wait(const Task& task) const while (!task.IsFinished()) { ExecuteOneTask(); - if (s_main_thread_worker == &s_tl_worker && xrDebug::ProcessingFailure()) + if (s_tl_worker.id == 0 && xrDebug::ProcessingFailure()) SDL_PumpEvents(); // Necessary to prevent dead locks } } @@ -395,7 +416,7 @@ void TaskManager::WaitForChildren(const Task& task) const while (!task.HasChildren()) { ExecuteOneTask(); - if (s_main_thread_worker == &s_tl_worker && xrDebug::ProcessingFailure()) + if (s_tl_worker.id == 0 && xrDebug::ProcessingFailure()) SDL_PumpEvents(); // Necessary to prevent dead locks } } diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 9b39ae020ff..7a1f1f7ab89 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -28,7 +28,9 @@ class XRCORE_API TaskManager final xr_vector workers; std::mutex workersLock; - std::atomic_size_t workersCount{}; + std::atomic_size_t activeWorkersCount{}; + + std::atomic_bool shouldPause{}; std::atomic_bool shouldStop{}; private: @@ -42,6 +44,8 @@ class XRCORE_API TaskManager final [[nodiscard]] ICF static Task* AllocateTask(); static void ICF IncrementTaskJobsCounter(Task& parent); + void SetThreadStatus(bool active); + public: TaskManager(); ~TaskManager(); From b893c1110846b6d907f0b0ebf200fa1bfd85d9db Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 9 Apr 2024 04:41:13 +0500 Subject: [PATCH 268/497] Fix compilation on non-Windows --- src/xrCore/Math/fast_lc16.cpp | 3 --- src/xrCore/Math/fast_lc16.hpp | 3 --- src/xrCore/Threading/TaskManager.cpp | 4 +--- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/xrCore/Math/fast_lc16.cpp b/src/xrCore/Math/fast_lc16.cpp index 6b82e815d8f..993d2852016 100644 --- a/src/xrCore/Math/fast_lc16.cpp +++ b/src/xrCore/Math/fast_lc16.cpp @@ -4,8 +4,6 @@ #include -namespace random -{ static std::random_device s_random_device; fast_lc16::fast_lc16() @@ -17,4 +15,3 @@ void fast_lc16::seed() { seed(s_random_device()); } -} // namespace random diff --git a/src/xrCore/Math/fast_lc16.hpp b/src/xrCore/Math/fast_lc16.hpp index 45bad8e7c88..5d22e106eda 100644 --- a/src/xrCore/Math/fast_lc16.hpp +++ b/src/xrCore/Math/fast_lc16.hpp @@ -7,8 +7,6 @@ /////////////////////////////////////////////////////////////////////////// #pragma once -namespace random -{ //! A fast random number generator. /** Uses linear congruential method. */ class fast_lc16 final @@ -89,4 +87,3 @@ class fast_lc16 final return std::numeric_limits< result_type >::max ( ); } }; -} // namespace random diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 3f5feddcdaa..19ab26a6a23 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -140,10 +140,8 @@ struct TaskWorkerStats class TaskWorker : public TaskQueue, public TaskWorkerStats { public: - using rng_t = random::fast_lc16; - Event event; - rng_t random{ this }; + fast_lc16 random{ this }; size_t id { size_t(-1) }; std::atomic_bool sleeps{}; From 736466258127d71caf4985bc03148115714b3edf Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 9 Apr 2024 15:33:12 +0500 Subject: [PATCH 269/497] Fix Invalid max distance crash (fixes #1654) I forgot to add default values when I was moving the variables to a SoundSourceInfo structure. This fixes a regression introduced in 55677278859941f703c1ddee1f5f9715631f5f63. --- src/xrSound/SoundRender_Source.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 0f7381df05b..786497a912c 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -24,11 +24,11 @@ struct SoundDataInfo struct SoundSourceInfo { - float baseVolume; - float minDist; - float maxDist; - float maxAIDist; - u32 gameType; + float baseVolume{ 1.0f }; + float minDist { 1.0f }; + float maxDist { 300.0f }; + float maxAIDist { 300.0f }; + u32 gameType {}; }; class XRSOUND_API CSoundRender_Source final : public CSound_source From 3b478ff1d459be693457b843e1f0c91fe946e011 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 12 Apr 2024 18:14:17 +0500 Subject: [PATCH 270/497] GitHub Actions: update to CPA 0.24.0 and use OpenBSD 7.5 --- .github/workflows/cibuild.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 3d751c56528..a7f7bf4f8f8 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -182,7 +182,7 @@ jobs: - { name: FreeBSD, os: freebsd, os-version: '14.0', arch: x86_64, install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" } - - { name: OpenBSD, os: openbsd, os-version: 7.4, arch: x86_64, + - { name: OpenBSD, os: openbsd, os-version: 7.5, arch: x86_64, install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", } #- { name: NetBSD, os: netbsd, os-version: 9.3, arch: x86_64, @@ -196,7 +196,7 @@ jobs: submodules: recursive - name: Setup ${{ matrix.platform.name }} and packages - uses: cross-platform-actions/action@v0.23.0 + uses: cross-platform-actions/action@v0.24.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -209,7 +209,7 @@ jobs: run: ${{ matrix.platform.install-cmd }} - name: Run CMake - uses: cross-platform-actions/action@v0.23.0 + uses: cross-platform-actions/action@v0.24.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -222,7 +222,7 @@ jobs: run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON - name: Run CMake Build - uses: cross-platform-actions/action@v0.23.0 + uses: cross-platform-actions/action@v0.24.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} From 23975a522f516fbe765115788c0ed4669bb7b080 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 11 Apr 2024 15:09:22 +0500 Subject: [PATCH 271/497] xrEngine/XR_IOConsole.cpp: don't set global mouse position on Console hide This was probably needed for original engine, where CUICursor wasn't synchronized with system cursor and DirectInput was used. Currently we use SDL which uses Windows.Gaming.Input or RawInput. --- src/xrEngine/XR_IOConsole.cpp | 7 ------- src/xrEngine/XR_IOConsole.h | 1 - 2 files changed, 8 deletions(-) diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index 93a0c553f35..b8d3114f959 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -613,8 +613,6 @@ void CConsole::Show() } bVisible = true; - SDL_GetGlobalMouseState(&m_mouse_pos.x, &m_mouse_pos.y); // Replace with SDL_GetMouseState in case retrieve window-relative coordinates - ec().clear_states(); scroll_delta = 0; reset_cmd_history_idx(); @@ -645,11 +643,6 @@ void CConsole::Hide() // if ( g_pGameLevel || // ( g_pGamePersistent && g_pGamePersistent->m_pMainMenu && g_pGamePersistent->m_pMainMenu->IsActive() )) - if (pInput->IsExclusiveMode()) - { - SDL_WarpMouseGlobal(m_mouse_pos.x, m_mouse_pos.y); // Replace with SDL_WarpMouseInWindow in case set window-relative coordinates - } - bVisible = false; reset_selected_tip(); update_tips(); diff --git a/src/xrEngine/XR_IOConsole.h b/src/xrEngine/XR_IOConsole.h index 7ad9dc49305..16ff543d420 100644 --- a/src/xrEngine/XR_IOConsole.h +++ b/src/xrEngine/XR_IOConsole.h @@ -89,7 +89,6 @@ class ENGINE_API CConsole : FactoryPtr* m_hShader_back{}; - Ivector2 m_mouse_pos{}; bool m_disable_tips; private: From 1b121f18a8a5205c895a038e067abaf963141647 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 15 Apr 2024 21:12:01 +0500 Subject: [PATCH 272/497] ImGui refactoring: support viewports and docking --- src/Common/PlatformWindows.inl | 2 +- src/Layers/xrRender/dxImGuiRender.cpp | 3 + src/xrEngine/CMakeLists.txt | 1 + src/xrEngine/Device_Initialize.cpp | 56 +++++-- src/xrEngine/Device_create.cpp | 4 +- src/xrEngine/Device_destroy.cpp | 8 +- src/xrEngine/Device_imgui.cpp | 220 +++++++++++++++++++++++++ src/xrEngine/Device_mode.cpp | 39 ++++- src/xrEngine/device.cpp | 77 ++++++++- src/xrEngine/device.h | 35 +++- src/xrEngine/editor_base.cpp | 112 +------------ src/xrEngine/editor_base.h | 47 +++--- src/xrEngine/editor_base_input.cpp | 224 +++++++++++++++++++++++--- src/xrEngine/x_ray.cpp | 37 ++--- src/xrEngine/xrEngine.vcxproj | 1 + src/xrEngine/xrEngine.vcxproj.filters | 3 + src/xrEngine/xr_input.cpp | 27 +++- src/xrEngine/xr_input.h | 16 +- src/xrGame/xrGame.cpp | 2 +- src/xrUICore/ui_debug.cpp | 10 +- 20 files changed, 710 insertions(+), 214 deletions(-) create mode 100644 src/xrEngine/Device_imgui.cpp diff --git a/src/Common/PlatformWindows.inl b/src/Common/PlatformWindows.inl index 60bee05ca7d..a9b38aa75d5 100644 --- a/src/Common/PlatformWindows.inl +++ b/src/Common/PlatformWindows.inl @@ -37,7 +37,7 @@ #define NOSOUND //#define NOTEXTMETRIC #define NOWH -#define NOWINOFFSETS +//#define NOWINOFFSETS #define NOCOMM #define NOKANJI #define NOCRYPT diff --git a/src/Layers/xrRender/dxImGuiRender.cpp b/src/Layers/xrRender/dxImGuiRender.cpp index 20ce12931d2..5308c5f7f8d 100644 --- a/src/Layers/xrRender/dxImGuiRender.cpp +++ b/src/Layers/xrRender/dxImGuiRender.cpp @@ -78,6 +78,9 @@ void dxImGuiRender::OnDeviceCreate(ImGuiContext* context) ); ImGui::SetCurrentContext(context); + ImGuiIO& io = ImGui::GetIO(); + io.BackendRendererName = "xrRender"; + #if defined(USE_DX9) ImGui_ImplDX9_Init(HW.pDevice); #elif defined(USE_DX11) diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index ea8c28ca5a7..c9b60f8a476 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -325,6 +325,7 @@ target_sources_grouped( device.h Device_create.cpp Device_destroy.cpp + Device_imgui.cpp Device_Initialize.cpp Device_mode.cpp Device_overdraw.cpp diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index 7fbbb007c73..fe76d6a7983 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -7,12 +7,34 @@ #include "xrCore/ModuleLookup.hpp" #include -#ifdef XR_PLATFORM_WINDOWS -# include -#endif +#include SDL_HitTestResult WindowHitTest(SDL_Window* win, const SDL_Point* area, void* data); +namespace +{ +// This is put in a separate function due to bunch of defines. +// Keeping that in CRenderDevice::Initialize would harm the readability. +void SetSDLSettings(pcstr title) +{ +#ifdef SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); +#endif +#ifdef SDL_HINT_AUDIO_DEVICE_APP_NAME + SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, title); +#endif +#ifdef SDL_HINT_APP_NAME + SDL_SetHint(SDL_HINT_APP_NAME, title); +#endif +#ifdef SDL_HINT_IME_SHOW_UI + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); +#endif +#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE + SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); +#endif +} +} // namespace + void CRenderDevice::Initialize() { Log("Initializing Engine..."); @@ -23,7 +45,6 @@ void CRenderDevice::Initialize() Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE; - SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); GEnv.Render->ObtainRequiredWindowFlags(flags); int icon = IDI_ICON_COP; @@ -44,13 +65,7 @@ void CRenderDevice::Initialize() "window", "title", title).c_str(); xr_strcpy(Core.ApplicationTitle, title); - -#if SDL_VERSION_ATLEAST(2, 0, 14) - SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, title); -# if SDL_VERSION_ATLEAST(2, 0, 18) - SDL_SetHint(SDL_HINT_APP_NAME, title); -# endif -#endif + SetSDLSettings(title); m_sdlWnd = SDL_CreateWindow(title, 0, 0, 640, 480, flags); R_ASSERT3(m_sdlWnd, "Unable to create SDL window", SDL_GetError()); @@ -61,6 +76,25 @@ void CRenderDevice::Initialize() ExtractAndSetWindowIcon(m_sdlWnd, icon); } + // Register main window handle (which is owned by the main application, not by us) + // This is mostly for consistency, so that our code can use same logic for main and secondary viewports. + { + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformUserData = IM_NEW(ImGuiViewportData){ m_sdlWnd }; + main_viewport->PlatformHandle = m_sdlWnd; + main_viewport->PlatformHandleRaw = nullptr; + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(m_sdlWnd, &info)) + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + main_viewport->PlatformHandleRaw = (void*)info.info.win.window; +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) + main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window; +#endif + } + } + if (!GEnv.isDedicatedServer) { seqAppStart.Add(&m_editor); diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index 768fde0218c..a5833fd1ad5 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -48,8 +48,8 @@ void CRenderDevice::Create() string_path fname; FS.update_path(fname, "$game_data$", "shaders.xr"); GEnv.Render->OnDeviceCreate(fname); - if (!GEnv.isDedicatedServer) - m_editor.OnDeviceCreate(); + m_imgui_render = GEnv.RenderFactory->CreateImGuiRender(); + m_imgui_render->OnDeviceCreate(Device.GetImGuiContext()); Statistic->OnDeviceCreate(); dwFrame = 0; } diff --git a/src/xrEngine/Device_destroy.cpp b/src/xrEngine/Device_destroy.cpp index 53273bb5cbe..0bcb6f67436 100644 --- a/src/xrEngine/Device_destroy.cpp +++ b/src/xrEngine/Device_destroy.cpp @@ -10,8 +10,6 @@ void CRenderDevice::Destroy() Log("Destroying Render..."); b_is_Ready = false; Statistic->OnDeviceDestroy(); - if (!GEnv.isDedicatedServer) - m_editor.OnDeviceDestroy(); GEnv.Render->OnDeviceDestroy(false); Memory.mem_compact(); GEnv.Render->Destroy(); @@ -37,14 +35,12 @@ void CRenderDevice::Reset(bool precache /*= true*/) const auto tm_start = TimerAsync(); - if (!GEnv.isDedicatedServer) - m_editor.OnDeviceResetBegin(); + m_imgui_render->OnDeviceResetBegin(); UpdateWindowProps(); GEnv.Render->Reset(m_sdlWnd, dwWidth, dwHeight, fWidth_2, fHeight_2); - if (!GEnv.isDedicatedServer) - m_editor.OnDeviceResetEnd(); + m_imgui_render->OnDeviceResetEnd(); // Update window props again for DX9 renderer if (GEnv.Render->GetBackendAPI() == IRender::BackendAPI::D3D9) // XXX: I don't remember why this hack is needed, thus, I'm not sure if it is needed at all diff --git a/src/xrEngine/Device_imgui.cpp b/src/xrEngine/Device_imgui.cpp new file mode 100644 index 00000000000..2a66a984de4 --- /dev/null +++ b/src/xrEngine/Device_imgui.cpp @@ -0,0 +1,220 @@ +#include "stdafx.h" + +#include + +void CRenderDevice::InitializeImGui() +{ + if (m_imgui_context) + return; + + ImGui::SetAllocatorFunctions( + [](size_t size, void* /*user_data*/) + { + return xr_malloc(size); + }, + [](void* ptr, void* /*user_data*/) + { + xr_free(ptr); + } + ); + m_imgui_context = ImGui::CreateContext(); + + ImGuiIO& io = ImGui::GetIO(); + + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | + ImGuiConfigFlags_NavEnableGamepad | + ImGuiConfigFlags_NavEnableSetMousePos | + ImGuiConfigFlags_ViewportsEnable | + ImGuiConfigFlags_DockingEnable; + + string_path fName; + FS.update_path(fName, "$app_data_root$", io.IniFilename); + convert_path_separators(fName); + io.IniFilename = xr_strdup(fName); + + FS.update_path(fName, "$logs$", io.LogFilename); + io.LogFilename = xr_strdup(fName); + + io.BackendPlatformName = "OpenXRay"; + + io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) + { + if (data->WantVisible) + { + const SDL_Rect r + { + /*.x =*/ (int)(data->InputPos.x - viewport->Pos.x), + /*.y =*/ (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight), + /*.w =*/ 1, + /*.h =*/ (int)data->InputLineHeight, + }; + SDL_SetTextInputRect(&r); + } + }; + + // Register platform interface (will be coupled with a renderer interface) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + + platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) + { + Uint32 sdl_flags{}; + GEnv.Render->ObtainRequiredWindowFlags(sdl_flags); + + //sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI; // XXX: high DPI + sdl_flags |= SDL_WINDOW_HIDDEN; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; +#if !defined(XR_PLATFORM_WINDOWS) + // See SDL hack in ImGui_ImplSDL2_ShowWindow(). + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; +#endif +#if SDL_VERSION_ATLEAST(2, 0, 5) + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; +#endif + + const auto vd = IM_NEW(ImGuiViewportData) + { + viewport->Pos, viewport->Size, sdl_flags + }; + viewport->PlatformUserData = vd; + + viewport->PlatformHandle = vd->Window; + viewport->PlatformHandleRaw = nullptr; + + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(vd->Window, &info)) + { +#if defined(XR_PLATFORM_WINDOWS) && defined(SDL_VIDEO_DRIVER_WINDOWS) + viewport->PlatformHandleRaw = info.info.win.window; +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) + viewport->PlatformHandleRaw = (void*)info.info.cocoa.window; +#endif + } + + if (viewport->ParentViewportId) + { + const auto parentViewport = ImGui::FindViewportByID(viewport->ParentViewportId); + SDL_SetWindowModalFor(vd->Window, (SDL_Window*)parentViewport->PlatformHandle); + } + }; + + platform_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) + { + if (const auto vd = static_cast(viewport->PlatformUserData)) + { + IM_DELETE(vd); + } + viewport->PlatformUserData = nullptr; + viewport->PlatformHandle = nullptr; + viewport->PlatformHandleRaw = nullptr; + }; + + platform_io.Platform_ShowWindow = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); +#if defined(XR_PLATFORM_WINDOWS) + const HWND hwnd = static_cast(viewport->PlatformHandleRaw); + + // SDL hack: Hide icon from task bar + // Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition. + if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) + { + LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + ex_style &= ~WS_EX_APPWINDOW; + ex_style |= WS_EX_TOOLWINDOW; + ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); + } + + // SDL hack: SDL always activate/focus windows :/ + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) + { + ::ShowWindow(hwnd, SW_SHOWNA); + return; + } +#endif + SDL_ShowWindow(vd->Window); + }; + + platform_io.Platform_SetWindowPos = [](ImGuiViewport* viewport, ImVec2 pos) + { + const auto vd = static_cast(viewport->PlatformUserData); + SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y); + }; + + platform_io.Platform_GetWindowPos = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); + int x = 0, y = 0; + SDL_GetWindowPosition(vd->Window, &x, &y); + return ImVec2{ (float)x, (float)y }; + }; + + platform_io.Platform_SetWindowSize = [](ImGuiViewport* viewport, ImVec2 size) + { + const auto vd = static_cast(viewport->PlatformUserData); + SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y); + }; + + platform_io.Platform_GetWindowSize = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); + int w = 0, h = 0; + SDL_GetWindowSize(vd->Window, &w, &h); + return ImVec2{ (float)w, (float)h }; + }; + + platform_io.Platform_SetWindowFocus = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); + SDL_RaiseWindow(vd->Window); + }; + + platform_io.Platform_GetWindowFocus = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; + }; + + platform_io.Platform_GetWindowMinimized = [](ImGuiViewport* viewport) + { + const auto vd = static_cast(viewport->PlatformUserData); + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0; + }; + + platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) + { + const auto vd = static_cast(viewport->PlatformUserData); + SDL_SetWindowTitle(vd->Window, title); + }; + +#if SDL_VERSION_ATLEAST(2, 0, 5) + platform_io.Platform_SetWindowAlpha = [](ImGuiViewport* viewport, float alpha) + { + const auto vd = static_cast(viewport->PlatformUserData); + SDL_SetWindowOpacity(vd->Window, alpha); + }; +#endif + + editor().InitBackend(); +} + +void CRenderDevice::DestroyImGui() +{ + if (!m_imgui_context) + return; + + m_imgui_render->OnDeviceDestroy(); + GEnv.RenderFactory->DestroyImGuiRender(m_imgui_render); + m_imgui_render = nullptr; + + ImGui::DestroyPlatformWindows(); + editor().ShutdownBackend(); + + ImGuiIO& io = ImGui::GetIO(); + xr_free(io.IniFilename); + xr_free(io.LogFilename); + + ImGui::DestroyContext(m_imgui_context); + m_imgui_context = nullptr; +} diff --git a/src/xrEngine/Device_mode.cpp b/src/xrEngine/Device_mode.cpp index 136d9952e26..e6e6261f2b3 100644 --- a/src/xrEngine/Device_mode.cpp +++ b/src/xrEngine/Device_mode.cpp @@ -25,6 +25,37 @@ void FillResolutionsForMonitor(const int monitorID) vid_mode_token[monitorID].emplace_back(nullptr, -1); } +void FillImGuiMonitorData(const int monitorID) +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + + // Warning: the validity of monitor DPI information on Windows + // depends on the application DPI awareness settings, + // which generally needs to be set in the manifest or at runtime. + ImGuiPlatformMonitor monitor; + SDL_Rect r; + SDL_GetDisplayBounds(monitorID, &r); + monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); + +#if SDL_VERSION_ATLEAST(2, 0, 5) + SDL_GetDisplayUsableBounds(monitorID, &r); + monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.WorkSize = ImVec2((float)r.w, (float)r.h); +#endif + +#if SDL_VERSION_ATLEAST(2, 0, 4) + // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set + // DpiScale to cocoa_window.backingScaleFactor here. + float dpi = 0.0f; + if (!SDL_GetDisplayDPI(monitorID, &dpi, nullptr, nullptr)) + monitor.DpiScale = dpi / 96.0f; +#endif + + monitor.PlatformHandle = (void*)(intptr_t)monitorID; + platform_io.Monitors.push_back(monitor); +} + void CRenderDevice::FillVideoModes() { const int displayCount = SDL_GetNumVideoDisplays(); @@ -37,6 +68,7 @@ void CRenderDevice::FillVideoModes() vid_monitor_token.emplace_back(xr_strdup(buf), i); FillResolutionsForMonitor(i); + FillImGuiMonitorData(i); } vid_monitor_token.emplace_back(nullptr, -1); } @@ -60,6 +92,8 @@ void CRenderDevice::CleanupVideoModes() xr_free(tokenName); } vid_monitor_token.clear(); + + ImGui::GetPlatformIO().Monitors.resize(0); } void CRenderDevice::SetWindowDraggable(bool draggable) @@ -117,7 +151,10 @@ void CRenderDevice::UpdateWindowProps() UpdateWindowRects(); SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT); - editor().UpdateWindowProps(); + ImGuiIO& io = ImGui::GetIO(); + + io.DisplaySize = { static_cast(psDeviceMode.Width), static_cast(psDeviceMode.Height) }; + io.DisplayFramebufferScale = ImVec2{ float(dwWidth / m_rcWindowClient.w), float(dwHeight / m_rcWindowClient.h) }; } void CRenderDevice::UpdateWindowRects() diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 4b4c8eef0ca..7886b07063c 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -26,6 +26,8 @@ int ps_fps_limit_in_menu = 60; bool g_bLoaded = false; ref_light precache_light = 0; +using namespace xray; + bool CRenderDevice::RenderBegin() { if (GEnv.isDedicatedServer) @@ -246,6 +248,16 @@ void CRenderDevice::DoRender() CalcFrameStats(); Statistic->Show(); + + ImGui::Render(); + m_imgui_render->Render(ImGui::GetDrawData()); + // Update and Render additional Platform Windows + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + RenderEnd(); // Present goes here } renderTotalReal.End(); @@ -330,7 +342,7 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) #if SDL_VERSION_ATLEAST(2, 0, 14) if (event.display.display == psDeviceMode.Monitor && event.display.type != SDL_DISPLAYEVENT_CONNECTED) #else - if (event.display.display == psDeviceMode.Monitor) + if (event.display.display == psDeviceMode.Monitor) #endif Reset(); else @@ -342,16 +354,28 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) #endif case SDL_WINDOWEVENT: { + const auto window = SDL_GetWindowFromID(event.window.windowID); + if (!window) + break; + ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window); + if (!viewport) + break; + switch (event.window.event) { case SDL_WINDOWEVENT_MOVED: { - UpdateWindowRects(); + if (window == m_sdlWnd) + { + UpdateWindowRects(); #if !SDL_VERSION_ATLEAST(2, 0, 18) // without SDL_WINDOWEVENT_DISPLAY_CHANGED, let's detect monitor change ourselves - const int display = SDL_GetWindowDisplayIndex(m_sdlWnd); - if (display != -1) - psDeviceMode.Monitor = display; + const int display = SDL_GetWindowDisplayIndex(window); + if (display != -1) + psDeviceMode.Monitor = display; #endif + } + if (viewport) + viewport->PlatformRequestMove = true; break; } @@ -361,6 +385,11 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) break; #endif + case SDL_WINDOWEVENT_RESIZED: + if (viewport) + viewport->PlatformRequestResize = true; + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: { if (psDeviceMode.WindowStyle != rsFullscreen) @@ -379,9 +408,24 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) break; } + + case SDL_WINDOWEVENT_CLOSE: + { + if (viewport) + viewport->PlatformRequestClose = true; + + if (window == m_sdlWnd) + { + Engine.Event.Defer("KERNEL:disconnect"); + Engine.Event.Defer("KERNEL:quit"); + } + break; + } } // switch (event.window.event) } } // switch (event.type) + + editor().ProcessEvent(event); } void CRenderDevice::Run() @@ -463,17 +507,26 @@ void CRenderDevice::FrameMove() dwTimeGlobal = TimerGlobal.GetElapsed_ms(); dwTimeDelta = dwTimeGlobal - _old_global; } + ImGui::GetIO().DeltaTime = fTimeDeltaReal; + + m_imgui_render->Frame(); + ImGui::NewFrame(); + // Frame move stats.EngineTotal.FrameStart(); stats.EngineTotal.Begin(); // TODO: HACK to test loading screen. // if(!g_bLoaded) + seqFrame.Process(); + g_bLoaded = true; // else // seqFrame.Process(rp_Frame); stats.EngineTotal.End(); stats.EngineTotal.FrameEnd(); + + ImGui::EndFrame(); } ENGINE_API bool bShowPauseString = true; @@ -531,8 +584,20 @@ void CRenderDevice::Pause(bool bOn, bool bTimer, bool bSound, [[maybe_unused]] p bool CRenderDevice::Paused() { return g_pauseMngr().Paused(); } -void CRenderDevice::OnWindowActivate(bool activated) +void CRenderDevice::OnWindowActivate(SDL_Window* window, bool activated) { + if (editor().GetState() == editor::ide::visible_state::full) + { + if (window != m_sdlWnd) + { + if (activated) + editor().OnAppActivate(); + else + editor().OnAppDeactivate(); + } + return; + } + if (!GEnv.isDedicatedServer && activated) pInput->GrabInput(true); else diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 0b57322134f..127cc39c5e9 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -200,7 +200,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler void Shutdown(); void ProcessEvent(const SDL_Event& event); - void OnWindowActivate(bool activated); + void OnWindowActivate(SDL_Window* window, bool activated); void UpdateWindowProps(); void UpdateWindowRects(); @@ -208,6 +208,9 @@ class ENGINE_API CRenderDevice : public IWindowHandler void Initialize(); + void InitializeImGui(); + void DestroyImGui(); + void FillVideoModes(); void CleanupVideoModes(); @@ -275,8 +278,38 @@ class ENGINE_API CRenderDevice : public IWindowHandler [[nodiscard]] auto editor_mode() const { return m_editor.is_shown(); } + [[nodiscard]] + auto GetImGuiContext() const { return m_imgui_context; } + +public: + struct ImGuiViewportData + { + SDL_Window* Window; + bool WindowOwned; + + ImGuiViewportData(SDL_Window* window) : Window(window), WindowOwned(false) {} + + ImGuiViewportData(ImVec2 pos, ImVec2 size, Uint32 flags) + { + Window = SDL_CreateWindow("ImGui Viewport (no title yet)", + (int)pos.x, (int)pos.y, (int)size.x, (int)size.y, flags); + WindowOwned = true; + } + + ~ImGuiViewportData() + { + if (Window && WindowOwned) + { + SDL_DestroyWindow(Window); + } + } + }; + private: xray::editor::ide m_editor; + + ImGuiContext* m_imgui_context{}; + IImGuiRender* m_imgui_render{}; }; extern ENGINE_API CRenderDevice Device; diff --git a/src/xrEngine/editor_base.cpp b/src/xrEngine/editor_base.cpp index 80390f11380..f77edc5e8c6 100644 --- a/src/xrEngine/editor_base.cpp +++ b/src/xrEngine/editor_base.cpp @@ -32,123 +32,27 @@ void ide::UnregisterTool(const ide_tool* tool) m_tools.erase(it); } -ide::ide() -{ - ImGui::SetAllocatorFunctions( - [](size_t size, void* /*user_data*/) - { - return xr_malloc(size); - }, - [](void* ptr, void* /*user_data*/) - { - xr_free(ptr); - } - ); - m_context = ImGui::CreateContext(); - - InitBackend(); -} - -ide::~ide() -{ - ShutdownBackend(); - ImGui::DestroyContext(m_context); -} - -void ide::UpdateWindowProps() -{ - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = { static_cast(psDeviceMode.Width), static_cast(psDeviceMode.Height) }; -} +ide::ide() = default; -void ide::OnDeviceCreate() -{ - m_render = GEnv.RenderFactory->CreateImGuiRender(); - m_render->OnDeviceCreate(m_context); -} - -void ide::OnDeviceDestroy() -{ - m_render->OnDeviceDestroy(); - GEnv.RenderFactory->DestroyImGuiRender(m_render); - m_render = nullptr; -} - -void ide::OnDeviceResetBegin() const -{ - m_render->OnDeviceResetBegin(); -} - -void ide::OnDeviceResetEnd() const -{ - m_render->OnDeviceResetEnd(); -} +ide::~ide() = default; void ide::OnAppStart() { - ImGuiIO& io = ImGui::GetIO(); - - string_path fName; - FS.update_path(fName, "$app_data_root$", io.IniFilename); - convert_path_separators(fName); - io.IniFilename = xr_strdup(fName); - - FS.update_path(fName, "$logs$", io.LogFilename); - io.LogFilename = xr_strdup(fName); - Device.seqFrame.Add(this, -5); - Device.seqRender.Add(this, -5); } void ide::OnAppEnd() { - ImGuiIO& io = ImGui::GetIO(); - xr_free(io.IniFilename); - xr_free(io.LogFilename); - Device.seqFrame.Remove(this); - Device.seqRender.Remove(this); -} - -void ide::UpdateTextInput(bool force_disable /*= false*/) -{ - if (force_disable) - { - if (m_text_input_enabled) - { - pInput->DisableTextInput(); - m_text_input_enabled = false; - } - return; - } - - const ImGuiIO& io = ImGui::GetIO(); - - if (m_text_input_enabled != io.WantTextInput) - { - m_text_input_enabled = io.WantTextInput; - - if (m_text_input_enabled) - pInput->EnableTextInput(); - else - pInput->DisableTextInput(); - } } void ide::OnFrame() { - const float frametime = m_timer.GetElapsed_sec(); - m_timer.Start(); - - ImGuiIO& io = ImGui::GetIO(); - io.DeltaTime = frametime; - - m_render->Frame(); - ImGui::NewFrame(); - switch (m_state) { case visible_state::full: + UpdateMouseData(); + UpdateMouseCursor(); UpdateTextInput(); ShowMain(); [[fallthrough]]; @@ -167,14 +71,6 @@ void ide::OnFrame() { SwitchToNextState(); } - - ImGui::EndFrame(); -} - -void ide::OnRender() -{ - ImGui::Render(); - m_render->Render(ImGui::GetDrawData()); } void ide::ShowMain() diff --git a/src/xrEngine/editor_base.h b/src/xrEngine/editor_base.h index 896c342b733..3ca2f6f17f3 100644 --- a/src/xrEngine/editor_base.h +++ b/src/xrEngine/editor_base.h @@ -9,8 +9,6 @@ namespace xray::editor { -struct ide_backend; - class XR_NOVTABLE ENGINE_API ide_tool : public pureFrame { bool is_opened{}; @@ -26,7 +24,6 @@ class XR_NOVTABLE ENGINE_API ide_tool : public pureFrame }; class ENGINE_API ide final : - public pureRender, public pureFrame, public pureAppActivate, public pureAppDeactivate, @@ -48,26 +45,22 @@ class ENGINE_API ide final : ide(); ~ide() override; - [[nodiscard]] - bool is_shown() const; + void InitBackend(); + void ShutdownBackend(); -public: - void UpdateWindowProps(); + void ProcessEvent(const SDL_Event& event); - void OnDeviceCreate(); - void OnDeviceDestroy(); - void OnDeviceResetBegin() const; - void OnDeviceResetEnd() const; + [[nodiscard]] + bool is_shown() const; + [[nodiscard]] + auto GetState() const { return m_state; } void SetState(visible_state state); void SwitchToNextState(); - auto GetImGuiContext() const { return m_context; } - public: // Interface implementations void OnFrame() override; - void OnRender() override; void OnAppActivate() override; void OnAppDeactivate() override; @@ -98,10 +91,6 @@ class ENGINE_API ide final : private: ImGuiWindowFlags get_default_window_flags() const; -private: - void InitBackend(); - void ShutdownBackend(); - private: void ShowMain(); void ShowWeatherEditor(); @@ -109,18 +98,26 @@ class ENGINE_API ide final : void RegisterTool(ide_tool* tool); void UnregisterTool(const ide_tool* tool); + void UpdateMouseCursor(); + void UpdateMouseData(); void UpdateTextInput(bool force_disable = false); private: - CTimer m_timer; - IImGuiRender* m_render{}; - ImGuiContext* m_context{}; - ide_backend* m_backend_data{}; - - visible_state m_state; - bool m_show_weather_editor; // to be refactored + visible_state m_state{}; + bool m_show_weather_editor{}; // to be refactored bool m_text_input_enabled{}; xr_vector m_tools; + + struct ImGuiBackend + { + char* clipboard_text_data{}; + SDL_Cursor* mouse_cursors[ImGuiMouseCursor_COUNT]{}; + SDL_Cursor* last_cursor{}; + Uint32 mouse_window_id{}; + int mouse_last_leave_frame{}; + bool mouse_can_report_hovered_viewport{}; + }; + ImGuiBackend m_imgui_backend{}; }; } // namespace xray::editor diff --git a/src/xrEngine/editor_base_input.cpp b/src/xrEngine/editor_base_input.cpp index 64dffde011a..27b740ec37c 100644 --- a/src/xrEngine/editor_base_input.cpp +++ b/src/xrEngine/editor_base_input.cpp @@ -3,23 +3,44 @@ #include "editor_base.h" #include "editor_helper.h" -namespace xray::editor +namespace { -using namespace imgui; +bool mouse_can_use_global_state() +{ +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + cpcstr sdl_backend = SDL_GetCurrentVideoDriver(); -struct ide_backend + // Check and store if we are on a SDL backend that supports global mouse position + // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) + for (cpcstr driver : { "windows", "cocoa", "x11", "DIVE", "VMAN" }) + { + if (strncmp(sdl_backend, driver, strlen(driver)) == 0) + { + // We can create multi-viewports on the Platform side (optional) + return true; + } + } +#endif + return false; +} +} + +namespace xray::editor { - char* clipboard_text_data; -}; +using namespace imgui; void ide::InitBackend() { - m_backend_data = xr_new(); - ImGuiIO& io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad; - io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_HasMouseCursors; - io.BackendPlatformName = "imgui_impl_xray"; + + io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos; + + if (mouse_can_use_global_state()) + { + // We can create multi-viewports on the Platform side (optional) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; + m_imgui_backend.mouse_can_report_hovered_viewport = true; + } // Clipboard functionality io.SetClipboardTextFn = [](void*, const char* text) @@ -28,26 +49,176 @@ void ide::InitBackend() }; io.GetClipboardTextFn = [](void* user_data) -> const char* { - ide_backend& bd = *(ide_backend*)user_data; + auto& bd = *static_cast(user_data); + if (bd.clipboard_text_data) SDL_free(bd.clipboard_text_data); + bd.clipboard_text_data = SDL_GetClipboardText(); + return bd.clipboard_text_data; }; - io.ClipboardUserData = m_backend_data; + io.ClipboardUserData = &m_imgui_backend; + + auto& bd = m_imgui_backend; + + bd.mouse_cursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + bd.mouse_cursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + bd.mouse_cursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + bd.mouse_cursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + bd.mouse_cursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + bd.mouse_cursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + bd.mouse_cursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + bd.mouse_cursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + bd.mouse_cursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); } void ide::ShutdownBackend() { - ide_backend& bd = *m_backend_data; + auto& backend = m_imgui_backend; - if (bd.clipboard_text_data) + if (backend.clipboard_text_data) { - SDL_free(bd.clipboard_text_data); - bd.clipboard_text_data = nullptr; + SDL_free(backend.clipboard_text_data); + backend.clipboard_text_data = nullptr; } - xr_delete(m_backend_data); + for (auto& cursor : backend.mouse_cursors) + { + SDL_FreeCursor(cursor); + cursor = nullptr; + } + backend.last_cursor = nullptr; +} + +void ide::ProcessEvent(const SDL_Event& event) +{ + if (m_state != visible_state::full) + return; + + auto& bd = m_imgui_backend; + + switch (event.type) + { + case SDL_WINDOWEVENT: + { + const auto window = SDL_GetWindowFromID(event.window.windowID); + if (!window) + break; + const ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window); + if (!viewport) + break; + + switch (event.window.event) + { + case SDL_WINDOWEVENT_ENTER: + bd.mouse_window_id = event.window.windowID; + bd.mouse_last_leave_frame = 0; + break; + case SDL_WINDOWEVENT_LEAVE: + bd.mouse_last_leave_frame = ImGui::GetFrameCount() + 1; + break; + } // switch (event.window.event) + } + } // switch (event.type) +} + +void ide::UpdateMouseData() +{ + ImGuiIO& io = ImGui::GetIO(); + auto& bd = m_imgui_backend; + const bool anyMouseButtonPressed = pInput->iAnyMouseButtonDown(); + + if (bd.mouse_last_leave_frame && bd.mouse_last_leave_frame >= ImGui::GetFrameCount() && anyMouseButtonPressed) + { + bd.mouse_window_id = 0; + bd.mouse_last_leave_frame = 0; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + } + + // Our io.AddMouseViewportEvent() calls will only be valid when not capturing. + // Technically speaking testing for 'anyMouseButtonPressed' would be more rygorous, but testing for payload reduces noise and potential side-effects. + if (bd.mouse_can_report_hovered_viewport && ImGui::GetDragDropPayload() == nullptr) + io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; + else + io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport; + + // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below) +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + SDL_CaptureMouse(anyMouseButtonPressed ? SDL_TRUE : SDL_FALSE); +#endif + SDL_Window* focused_window = SDL_GetKeyboardFocus(); + const bool is_app_focused = focused_window && (Device.m_sdlWnd == focused_window || ImGui::FindViewportByPlatformHandle(focused_window)); + + if (is_app_focused) + { + if (io.WantSetMousePos) + { + pInput->iSetMousePos({ (int)io.MousePos.x, (int)io.MousePos.y }, io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable); + } + } + + if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) + { + ImGuiID view_id = 0; + if (SDL_Window* window = SDL_GetWindowFromID(bd.mouse_window_id)) + if (const ImGuiViewport* view = ImGui::FindViewportByPlatformHandle(window)) + view_id = view->ID; + io.AddMouseViewportEvent(view_id); + } +} + +void ide::UpdateMouseCursor() +{ + const ImGuiIO& io = ImGui::GetIO(); + + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + + auto& bd = m_imgui_backend; + const ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + SDL_ShowCursor(SDL_FALSE); + } + else + { + // Show OS mouse cursor + SDL_Cursor* expected_cursor = bd.mouse_cursors[imgui_cursor] ? bd.mouse_cursors[imgui_cursor] : bd.mouse_cursors[ImGuiMouseCursor_Arrow]; + if (bd.last_cursor != expected_cursor) + { + SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113) + bd.last_cursor = expected_cursor; + } + SDL_ShowCursor(SDL_TRUE); + } +} + +void ide::UpdateTextInput(bool force_disable /*= false*/) +{ + if (force_disable) + { + if (m_text_input_enabled) + { + pInput->DisableTextInput(); + m_text_input_enabled = false; + } + return; + } + + const ImGuiIO& io = ImGui::GetIO(); + + if (m_text_input_enabled != io.WantTextInput) + { + m_text_input_enabled = io.WantTextInput; + + if (m_text_input_enabled) + pInput->EnableTextInput(); + else + pInput->DisableTextInput(); + } } void ide::OnAppActivate() @@ -64,16 +235,21 @@ void ide::OnAppDeactivate() void ide::IR_OnActivate() { - ImGuiIO& io = ImGui::GetIO(); - io.MouseDrawCursor = true; + pInput->GrabInput(false); + +#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); +#endif } void ide::IR_OnDeactivate() { UpdateTextInput(true); + pInput->GrabInput(true); - ImGuiIO& io = ImGui::GetIO(); - io.MouseDrawCursor = false; +#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "0"); +#endif } void ide::IR_OnMousePress(int key) @@ -103,10 +279,10 @@ void ide::IR_OnMouseWheel(int x, int y) void ide::IR_OnMouseMove(int /*x*/, int /*y*/) { - // x and y are relative - // ImGui accepts absolute coordinates + // x and y are relative to previous mouse position + // ImGui accepts absolute coordinates (that are relative to window or monitor) Ivector2 p; - pInput->iGetAsyncMousePos(p); + pInput->iGetAsyncMousePos(p, ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable); ImGuiIO& io = ImGui::GetIO(); io.AddMousePosEvent(static_cast(p.x), static_cast(p.y)); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index be3222cb41d..ab40776a514 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -314,6 +314,7 @@ CApplication::CApplication(pcstr commandLine) FPU::m24r(); + Device.InitializeImGui(); Device.FillVideoModes(); InitInput(); InitConsole(); @@ -382,6 +383,7 @@ CApplication::~CApplication() Console->Destroy(); Device.CleanupVideoModes(); + Device.DestroyImGui(); destroySound(); Device.Destroy(); @@ -437,34 +439,33 @@ int CApplication::Run() { case SDL_WINDOWEVENT: { + const auto window = SDL_GetWindowFromID(event.window.windowID); + switch (event.window.event) { case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_MAXIMIZED: - canCallActivate = true; - shouldActivate = true; + if (window != Device.m_sdlWnd) + Device.OnWindowActivate(window, true); + else + { + canCallActivate = true; + shouldActivate = true; + } continue; case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_MINIMIZED: - canCallActivate = true; - shouldActivate = false; - continue; - - case SDL_WINDOWEVENT_ENTER: - SDL_ShowCursor(SDL_FALSE); - continue; - - case SDL_WINDOWEVENT_LEAVE: - SDL_ShowCursor(SDL_TRUE); - continue; - - case SDL_WINDOWEVENT_CLOSE: - Engine.Event.Defer("KERNEL:disconnect"); - Engine.Event.Defer("KERNEL:quit"); + if (window != Device.m_sdlWnd) + Device.OnWindowActivate(window, false); + else + { + canCallActivate = true; + shouldActivate = false; + } continue; } // switch (event.window.event) } @@ -478,7 +479,7 @@ int CApplication::Run() // Workaround for screen blinking when there's too much timeouts if (canCallActivate) { - Device.OnWindowActivate(shouldActivate); + Device.OnWindowActivate(Device.m_sdlWnd, shouldActivate); } Device.ProcessFrame(); diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index baaa4f94e21..c57ec30fd0a 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -121,6 +121,7 @@ + diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 51e86a982d4..8960715ae4f 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -617,6 +617,9 @@ Render\Execution & 3D + + Render\Execution & 3D + Render\Execution & 3D diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index 645ef16312a..e75931096d6 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -520,14 +520,37 @@ void CInput::iGetAsyncScrollPos(Ivector2& p) const p = { mouseAxisState[2], mouseAxisState[3] }; } -void CInput::iGetAsyncMousePos(Ivector2& p) const +bool CInput::iGetAsyncMousePos(Ivector2& p, bool global /*= false*/) const { + if (global) + { +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + SDL_GetGlobalMouseState(&p.x, &p.y); + return true; +#endif + // if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE unavailable + // fallback to SDL_GetMouseState + // but report false + } SDL_GetMouseState(&p.x, &p.y); + return !global; } -void CInput::iSetMousePos(const Ivector2& p) const +bool CInput::iSetMousePos(const Ivector2& p, bool global /*= false*/) const { + if (global) + { +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + SDL_WarpMouseGlobal(p.x, p.y); + return true; +#endif + // if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE unavailable + // fallback to SDL_WarpMouseInWindow + // but report false + } + SDL_WarpMouseInWindow(Device.m_sdlWnd, p.x, p.y); + return !global; } void CInput::GrabInput(const bool grab) diff --git a/src/xrEngine/xr_input.h b/src/xrEngine/xr_input.h index 6af33d63398..75c6b00e9c1 100644 --- a/src/xrEngine/xr_input.h +++ b/src/xrEngine/xr_input.h @@ -1,8 +1,15 @@ #pragma once -#include #include +#include + +#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) +# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 +#else +# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 +#endif + DECLARE_MESSAGE(KeyMapChanged); enum EMouseButton @@ -137,10 +144,13 @@ class ENGINE_API CInput void iRelease(IInputReceiver* pc); bool iGetAsyncKeyState(const int key); + bool iAnyMouseButtonDown() const { return mouseState.any(); } + bool iAnyKeyButtonDown() const { return keyboardState.any(); } + bool iAnyControllerButtonDown() const { return controllerState.any(); } void iGetAsyncScrollPos(Ivector2& p) const; - void iGetAsyncMousePos(Ivector2& p) const; - void iSetMousePos(const Ivector2& p) const; + bool iGetAsyncMousePos(Ivector2& p, bool global = false) const; + bool iSetMousePos(const Ivector2& p, bool global = false) const; void GrabInput(const bool grab); bool InputIsGrabbed() const; diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index 7e98d484a3f..1694b14801e 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -62,7 +62,7 @@ extern "C" xr_free(ptr); } ); - ImGui::SetCurrentContext(Device.editor().GetImGuiContext()); + ImGui::SetCurrentContext(Device.GetImGuiContext()); } XR_EXPORT void finalize_library() diff --git a/src/xrUICore/ui_debug.cpp b/src/xrUICore/ui_debug.cpp index 984985de046..ffd94c7ba94 100644 --- a/src/xrUICore/ui_debug.cpp +++ b/src/xrUICore/ui_debug.cpp @@ -48,15 +48,15 @@ CUIDebugger::CUIDebugger() { ImGui::SetAllocatorFunctions( [](size_t size, void* /*user_data*/) - { + { return xr_malloc(size); - }, + }, [](void* ptr, void* /*user_data*/) - { + { xr_free(ptr); - } + } ); - ImGui::SetCurrentContext(Device.editor().GetImGuiContext()); + ImGui::SetCurrentContext(Device.GetImGuiContext()); } void CUIDebugger::OnFrame() From b0b71646b041d23fee8e1f88b5d9acb9e8a4f15b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 15 Apr 2024 23:29:52 +0500 Subject: [PATCH 273/497] Update imgui submodule --- Externals/imgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/imgui b/Externals/imgui index e3d7cd665d9..c1743eef484 160000 --- a/Externals/imgui +++ b/Externals/imgui @@ -1 +1 @@ -Subproject commit e3d7cd665d9b8cf7c78166ed774bf47e502dd6be +Subproject commit c1743eef48432a08438de0926a6fc657e5ce2d11 From e1217f6f10e2f62466ae8aa8727fcd605370f501 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 16 Apr 2024 00:00:07 +0500 Subject: [PATCH 274/497] Enable ImGui viewports only on Windows This fixes compilation on Ubuntu and OpenBSD. The errors are just missing includes due to missing additional developer packages. But I don't want to make ordinary user to install something unnecessary. --- src/xrEngine/Device_Initialize.cpp | 6 +++++- src/xrEngine/Device_imgui.cpp | 12 ++++++++++-- src/xrEngine/editor_base_input.cpp | 10 +++++++--- src/xrEngine/stdafx.h | 4 ++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index fe76d6a7983..7881e09c877 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -7,7 +7,9 @@ #include "xrCore/ModuleLookup.hpp" #include -#include +#ifdef IMGUI_ENABLE_VIEWPORTS +# include +#endif SDL_HitTestResult WindowHitTest(SDL_Window* win, const SDL_Point* area, void* data); @@ -76,6 +78,7 @@ void CRenderDevice::Initialize() ExtractAndSetWindowIcon(m_sdlWnd, icon); } +#ifdef IMGUI_ENABLE_VIEWPORTS // Register main window handle (which is owned by the main application, not by us) // This is mostly for consistency, so that our code can use same logic for main and secondary viewports. { @@ -94,6 +97,7 @@ void CRenderDevice::Initialize() #endif } } +#endif if (!GEnv.isDedicatedServer) { diff --git a/src/xrEngine/Device_imgui.cpp b/src/xrEngine/Device_imgui.cpp index 2a66a984de4..ae3c8ae8a37 100644 --- a/src/xrEngine/Device_imgui.cpp +++ b/src/xrEngine/Device_imgui.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" -#include +#ifdef IMGUI_ENABLE_VIEWPORTS +# include +#endif void CRenderDevice::InitializeImGui() { @@ -24,7 +26,6 @@ void CRenderDevice::InitializeImGui() io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableSetMousePos | - ImGuiConfigFlags_ViewportsEnable | ImGuiConfigFlags_DockingEnable; string_path fName; @@ -52,6 +53,7 @@ void CRenderDevice::InitializeImGui() } }; +#ifdef IMGUI_ENABLE_VIEWPORTS // Register platform interface (will be coupled with a renderer interface) ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); @@ -195,8 +197,12 @@ void CRenderDevice::InitializeImGui() SDL_SetWindowOpacity(vd->Window, alpha); }; #endif +#endif // IMGUI_ENABLE_VIEWPORTS editor().InitBackend(); + + if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; } void CRenderDevice::DestroyImGui() @@ -208,7 +214,9 @@ void CRenderDevice::DestroyImGui() GEnv.RenderFactory->DestroyImGuiRender(m_imgui_render); m_imgui_render = nullptr; +#ifdef IMGUI_ENABLE_VIEWPORTS ImGui::DestroyPlatformWindows(); +#endif editor().ShutdownBackend(); ImGuiIO& io = ImGui::GetIO(); diff --git a/src/xrEngine/editor_base_input.cpp b/src/xrEngine/editor_base_input.cpp index 27b740ec37c..57c0912e546 100644 --- a/src/xrEngine/editor_base_input.cpp +++ b/src/xrEngine/editor_base_input.cpp @@ -7,7 +7,7 @@ namespace { bool mouse_can_use_global_state() { -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && defined(IMGUI_ENABLE_VIEWPORTS) cpcstr sdl_backend = SDL_GetCurrentVideoDriver(); // Check and store if we are on a SDL backend that supports global mouse position @@ -39,7 +39,9 @@ void ide::InitBackend() { // We can create multi-viewports on the Platform side (optional) io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; +#ifndef XR_PLATFORM_APPLE m_imgui_backend.mouse_can_report_hovered_viewport = true; +#endif } // Clipboard functionality @@ -144,11 +146,13 @@ void ide::UpdateMouseData() io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport; // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below) -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && defined(IMGUI_ENABLE_VIEWPORTS) SDL_CaptureMouse(anyMouseButtonPressed ? SDL_TRUE : SDL_FALSE); -#endif SDL_Window* focused_window = SDL_GetKeyboardFocus(); const bool is_app_focused = focused_window && (Device.m_sdlWnd == focused_window || ImGui::FindViewportByPlatformHandle(focused_window)); +#else + const bool is_app_focused = (SDL_GetWindowFlags(Device.m_sdlWnd) & SDL_WINDOW_INPUT_FOCUS) != 0; +#endif if (is_app_focused) { diff --git a/src/xrEngine/stdafx.h b/src/xrEngine/stdafx.h index 24238016600..7af033375f3 100644 --- a/src/xrEngine/stdafx.h +++ b/src/xrEngine/stdafx.h @@ -12,6 +12,10 @@ #endif // #ifndef INGAME_EDITOR #endif // #ifndef NDEBUG +#ifdef XR_PLATFORM_WINDOWS +# define IMGUI_ENABLE_VIEWPORTS +#endif + #include "xrCore/xrCore.h" #include "xrCore/_std_extensions.h" From b03f8ddb3111a889efb0bc0ffd4af056d9bc9072 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 16 Apr 2024 00:10:51 +0500 Subject: [PATCH 275/497] xrEngine/Device_imgui.cpp: fix compilation on old versions of SDL2 --- src/xrEngine/Device_imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/Device_imgui.cpp b/src/xrEngine/Device_imgui.cpp index ae3c8ae8a37..39ccedc3b8b 100644 --- a/src/xrEngine/Device_imgui.cpp +++ b/src/xrEngine/Device_imgui.cpp @@ -42,7 +42,7 @@ void CRenderDevice::InitializeImGui() { if (data->WantVisible) { - const SDL_Rect r + /*const*/ SDL_Rect r // this is not const because older versions of SDL accept non-const rect { /*.x =*/ (int)(data->InputPos.x - viewport->Pos.x), /*.y =*/ (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight), From f2f1e752a549bc9e650e8e1520aa710b6770dcc3 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 19 Apr 2024 17:21:04 +0300 Subject: [PATCH 276/497] Support compilation on NetBSD (#1659) --- .github/workflows/cibuild.yml | 8 ++++---- Externals/LuaJIT-proj/CMakeLists.txt | 5 ++++- Externals/imgui-proj/CMakeLists.txt | 2 +- Externals/ode/ode/src/util.h | 6 +++--- src/Common/PlatformApple.inl | 3 +-- src/Common/PlatformBSD.inl | 4 ++-- src/Common/PlatformLinux.inl | 3 +-- src/xrCore/CMakeLists.txt | 2 +- src/xrCore/Threading/ThreadUtil.cpp | 2 +- src/xrGame/sound_memory_manager.cpp | 11 ++++++----- 10 files changed, 24 insertions(+), 22 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index a7f7bf4f8f8..f4175021b3c 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -182,12 +182,12 @@ jobs: - { name: FreeBSD, os: freebsd, os-version: '14.0', arch: x86_64, install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" } - - { name: OpenBSD, os: openbsd, os-version: 7.5, arch: x86_64, + - { name: OpenBSD, os: openbsd, os-version: '7.5', arch: x86_64, install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", } - #- { name: NetBSD, os: netbsd, os-version: 9.3, arch: x86_64, - # install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis", - # } + - { name: NetBSD, os: netbsd, os-version: '10.0', arch: x86_64, + install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis", + } configuration: [Debug, Release] steps: diff --git a/Externals/LuaJIT-proj/CMakeLists.txt b/Externals/LuaJIT-proj/CMakeLists.txt index 58eae7997bb..3d982c6ca05 100644 --- a/Externals/LuaJIT-proj/CMakeLists.txt +++ b/Externals/LuaJIT-proj/CMakeLists.txt @@ -46,7 +46,10 @@ elseif (APPLE) else() option(LUA_USE_POSIX "Use POSIX functionality." ON) - if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD has dlopen as a part of libc + # OpenBSD has dl as a part of libc + # NetBSD includes dl functions automatically + if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + # This option only links dl and doesn't change anything other from that. option(LUA_USE_DLOPEN "Use dynamic linker to load modules." ON) endif() endif() diff --git a/Externals/imgui-proj/CMakeLists.txt b/Externals/imgui-proj/CMakeLists.txt index 0e8771536ee..7c218627a03 100644 --- a/Externals/imgui-proj/CMakeLists.txt +++ b/Externals/imgui-proj/CMakeLists.txt @@ -23,7 +23,7 @@ target_include_directories(xrImGui "${IMGUI_DIR}" ) -if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT WIN32) +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "NetBSD" AND NOT WIN32) target_link_libraries(xrImGui PRIVATE $<$>:dl> diff --git a/Externals/ode/ode/src/util.h b/Externals/ode/ode/src/util.h index fe91d400f60..bef6bb0b58d 100644 --- a/Externals/ode/ode/src/util.h +++ b/Externals/ode/ode/src/util.h @@ -27,7 +27,7 @@ #include "float.h" #ifndef MSVC -#include // for fpclassify +#include // for fpclassify #endif void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize); @@ -45,11 +45,11 @@ inline bool dValid(const float x) { #ifdef MSVC // check for: Signaling NaN, Quiet NaN, Negative infinity (-INF), Positive infinity (+INF), Negative denormalized, Positive denormalized - int cls = _fpclass (double(x)); + int cls = _fpclass(double(x)); if (cls&(_FPCLASS_SNAN+_FPCLASS_QNAN+_FPCLASS_NINF+_FPCLASS_PINF+_FPCLASS_ND+_FPCLASS_PD)) return false; #else - int cls = fpclassify((double )x); + int cls = std::fpclassify((double)x); switch (cls) { case FP_NAN: diff --git a/src/Common/PlatformApple.inl b/src/Common/PlatformApple.inl index 7e11485181d..0546393157e 100644 --- a/src/Common/PlatformApple.inl +++ b/src/Common/PlatformApple.inl @@ -36,9 +36,8 @@ #define _copysign copysign #define _cdecl //__attribute__((cdecl)) -#define _fastcall //__attribute__((fastcall)) -#define __cdecl +#define __cdecl _cdecl #define __stdcall #define __fastcall diff --git a/src/Common/PlatformBSD.inl b/src/Common/PlatformBSD.inl index 56a8981345d..58f1edb59c4 100644 --- a/src/Common/PlatformBSD.inl +++ b/src/Common/PlatformBSD.inl @@ -33,10 +33,10 @@ #define _copysign copysign #define _cdecl //__attribute__((cdecl)) -#define _fastcall //__attribute__((fastcall)) -#define __cdecl +#define __cdecl _cdecl #define __stdcall +#define __fastcall #define __pragma(...) _Pragma(#__VA_ARGS__) #define CALLBACK diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index fc342ebb881..a65ea5b68fe 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -33,9 +33,8 @@ #define _copysign copysign #define _cdecl //__attribute__((cdecl)) -#define _fastcall //__attribute__((fastcall)) -#define __cdecl +#define __cdecl _cdecl #define __stdcall #define __fastcall diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 8737e41b20b..55ec3bfdce7 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -456,7 +456,7 @@ target_link_libraries(xrCore LZO::LZO ) -if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT WIN32) +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "NetBSD" AND NOT WIN32) target_link_libraries(xrCore PRIVATE dl diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 4be4c8006cb..3ac6e6fa187 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -15,7 +15,7 @@ static int pthread_setname_np(pthread_t threadId, const char* name) # elif defined(XR_PLATFORM_NETBSD) static int pthread_setname_np(pthread_t threadId, const char* name) { - return pthread_setname_np(threadId, "%s", name); + return pthread_setname_np(threadId, "%s", const_cast(name)); } # elif defined(XR_PLATFORM_APPLE) static int pthread_setname_np(pthread_t /*threadId*/, const char* name) diff --git a/src/xrGame/sound_memory_manager.cpp b/src/xrGame/sound_memory_manager.cpp index 81cd913d308..7f1d8e67280 100644 --- a/src/xrGame/sound_memory_manager.cpp +++ b/src/xrGame/sound_memory_manager.cpp @@ -85,11 +85,12 @@ IC void CSoundMemoryManager::update_sound_threshold() VERIFY(_valid(m_min_sound_threshold)); VERIFY(!fis_zero(m_decrease_factor)); VERIFY(m_sound_decrease_quant); - // t = max(t*f^((tc - tl)/tq),min_threshold) - m_sound_threshold = - _max(m_self_sound_factor * m_sound_threshold * exp(float(Device.dwTimeGlobal - m_last_sound_time) / - float(m_sound_decrease_quant) * log(m_decrease_factor)), - m_min_sound_threshold); + // t = std::max(t*f^((tc - tl)/tq),min_threshold) + + const float exponent = std::exp(float(Device.dwTimeGlobal - m_last_sound_time) / float(m_sound_decrease_quant) * std::log(m_decrease_factor)); + + m_sound_threshold = std::max(m_self_sound_factor * m_sound_threshold * exponent, m_min_sound_threshold); + VERIFY(_valid(m_sound_threshold)); } From ba415329f35d29d042dacefb94b3cccb90a77835 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 19 Apr 2024 19:43:24 +0500 Subject: [PATCH 277/497] README.md: move build status badge into the Development section [skip ci] 1. Removed AppVeyor status, since we plan to discontinue using it. 2. No need to say x64/ARM64/Linux/macOS/BSD/etc twice. It's stated in the Differences from the original X-Ray section. (though, *BSD aren't stated there yet because we currently have problems with running the engine on these platforms) --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index c4eaf564f4f..3b73684402a 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,6 @@ Make sure to visit our [wiki](https://github.com/OpenXRay/xray-16/wiki). |Build and setup|[On Windows](https://github.com/OpenXRay/xray-16/wiki/%5BEN%5D-How-to-build-and-setup-on-Windows)|[On Linux](https://github.com/OpenXRay/xray-16/wiki/%5BEN%5D-How-to-build-and-setup-on-Linux)| |Install and play|[On Windows](https://github.com/OpenXRay/xray-16/wiki/%5BEN%5D-How-to-install-and-play)|-| -## Build status -|CI|Platform|Compiler|Configurations|Platforms|Status| -|---|---|---|---|---|---| -|AppVeyor|Windows, Ubuntu|MSVC, GCC|Debug, Mixed, Release, Release Master Gold|x64, x86|[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/16mp39v0d7fts6yf?svg=true)](https://ci.appveyor.com/project/OpenXRay/xray-16)| -|GitHub Actions|Windows, Ubuntu, Alpine Linux, macOS|MSVC, GCC, Clang|Debug, Mixed, Release, Release Master Gold|x64, x86|[![GitHub Actions Build Status](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml/badge.svg)](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml) - ## Contributing All contributions are more than welcomed. There are several ways how you can contribute: @@ -71,6 +65,7 @@ Join us on our [Discord](https://discord.gg/sjRMQwv), subscribe to our [YouTube Also you can put a star on this repository :) ### Development +[![GitHub Actions Build Status](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml/badge.svg)](https://github.com/OpenXRay/xray-16/actions/workflows/cibuild.yml) [![Contributors](https://img.shields.io/github/contributors/OpenXRay/xray-16.svg?label=Contributors)](https://github.com/OpenXRay/xray-16/graphs/contributors) Join our efforts in making our beloved game better, send pull requests, participate in discussions and code reviews! From fc90cd286ea9e26b73da55befd22f7e9bf62296d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 19:08:16 +0500 Subject: [PATCH 278/497] xrRender/r__occlusion.cpp: correctly show how much queries are there when showing "Too many occlusion queries were issued" warning This corrects small mistake from 35d9772b3760cd17731675f979f25d98828bd6d9 --- src/Layers/xrRender/r__occlusion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index c6e59e01ecc..84318c0fc51 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -48,7 +48,7 @@ u32 R_occlusion::occq_begin(u32& ID) if (pool.empty()) { if ((Device.dwFrame % 40) == 0) - Msg(" RENDER [Warning]: Too many occlusion queries were issued(>%u)!!!", pool.size()); + Msg(" RENDER [Warning]: Too many occlusion queries were issued (>%u)!!!", used.size()); ID = iInvalidHandle; return 0; } From eb1904fecf23a745ed2ef4b07e38b02db3f138b1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 22:38:07 +0500 Subject: [PATCH 279/497] xrRender/r__occlusion.cpp: remove commented code --- src/Layers/xrRender/r__occlusion.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 84318c0fc51..6853ea3d4a0 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -68,11 +68,8 @@ u32 R_occlusion::occq_begin(u32& ID) used.push_back(pool.back()); } pool.pop_back(); - // CHK_DX (used[ID].Q->Issue (D3DISSUE_BEGIN)); CHK_DX(BeginQuery(used[ID].Q)); - // Msg ("begin: [%2d] - %d", used[ID].order, ID); - return used[ID].order; } void R_occlusion::occq_end(u32& ID) @@ -86,8 +83,6 @@ void R_occlusion::occq_end(u32& ID) if (ID == iInvalidHandle) return; - // Msg ("end : [%2d] - %d", used[ID].order, ID); - // CHK_DX (used[ID].Q->Issue (D3DISSUE_END)); CHK_DX(EndQuery(used[ID].Q)); } R_occlusion::occq_result R_occlusion::occq_get(u32& ID) @@ -103,12 +98,9 @@ R_occlusion::occq_result R_occlusion::occq_get(u32& ID) occq_result fragments = 0; HRESULT hr; - // CHK_DX (used[ID].Q->GetData(&fragments,sizeof(fragments),D3DGETDATA_FLUSH)); - // Msg ("get : [%2d] - %d => %d", used[ID].order, ID, fragments); CTimer T; T.Start(); RImplementation.BasicStats.Wait.Begin(); - // while ((hr=used[ID].Q->GetData(&fragments,sizeof(fragments),D3DGETDATA_FLUSH))==S_FALSE) { VERIFY2(ID < used.size(), make_string("_Pos = %d, size() = %d ", ID, used.size())); while ((hr = GetData(used[ID].Q, &fragments, sizeof(fragments))) == S_FALSE) { From cde550c03c3a843e3adfdb694a8be1581e597681 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 22:40:38 +0500 Subject: [PATCH 280/497] xrRender/r__occlusion.cpp: remove VERIFYs that are always true --- src/Layers/xrRender/r__occlusion.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 6853ea3d4a0..c07fd6db163 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -58,13 +58,11 @@ u32 R_occlusion::occq_begin(u32& ID) { ID = fids.back(); fids.pop_back(); - VERIFY(pool.size()); used[ID] = pool.back(); } else { ID = used.size(); - VERIFY(pool.size()); used.push_back(pool.back()); } pool.pop_back(); @@ -101,7 +99,6 @@ R_occlusion::occq_result R_occlusion::occq_get(u32& ID) CTimer T; T.Start(); RImplementation.BasicStats.Wait.Begin(); - VERIFY2(ID < used.size(), make_string("_Pos = %d, size() = %d ", ID, used.size())); while ((hr = GetData(used[ID].Q, &fragments, sizeof(fragments))) == S_FALSE) { if (!SwitchToThread()) From dd142b5d03ee02672cbc156e35bf2c93ad2adbf4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 22:46:09 +0500 Subject: [PATCH 281/497] xrRender/r__occlusion.cpp: optimize the code a bit --- src/Layers/xrRender/r__occlusion.cpp | 30 +++++++++++----------------- src/Layers/xrRender/r__occlusion.h | 6 +++--- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index c07fd6db163..98a821f538a 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -3,7 +3,7 @@ #include "QueryHelper.h" -R_occlusion::R_occlusion(void) { enabled = strstr(Core.Params, "-no_occq") ? FALSE : TRUE; } +R_occlusion::R_occlusion(void) { enabled = strstr(Core.Params, "-no_occq") ? false : true; } R_occlusion::~R_occlusion(void) { occq_destroy(); } void R_occlusion::occq_create(u32 limit) { @@ -16,22 +16,16 @@ void R_occlusion::occq_create(u32 limit) q.order = it; if (FAILED(CreateQuery(&q.Q, D3D_QUERY_OCCLUSION))) break; - pool.push_back(q); + pool.emplace_back(std::move(q)); } std::reverse(pool.begin(), pool.end()); } void R_occlusion::occq_destroy() { - while (!used.empty()) - { - ReleaseQuery(used.back().Q); - used.pop_back(); - } - while (!pool.empty()) - { - ReleaseQuery(pool.back().Q); - pool.pop_back(); - } + for (const auto& q : used) + ReleaseQuery(q.Q); + for (const auto& q : pool) + ReleaseQuery(q.Q); used.clear(); pool.clear(); fids.clear(); @@ -58,12 +52,12 @@ u32 R_occlusion::occq_begin(u32& ID) { ID = fids.back(); fids.pop_back(); - used[ID] = pool.back(); + used[ID] = std::move(pool.back()); } else { - ID = used.size(); - used.push_back(pool.back()); + ID = static_cast(used.size()); + used.emplace_back(std::move(pool.back())); } pool.pop_back(); CHK_DX(BeginQuery(used[ID].Q)); @@ -122,18 +116,18 @@ R_occlusion::occq_result R_occlusion::occq_get(u32& ID) // insert into pool (sorting in decreasing order) Query& Q = used[ID]; if (pool.empty()) - pool.push_back(Q); + pool.emplace_back(Q); else { int it = int(pool.size()) - 1; while ((it >= 0) && (pool[it].order < Q.order)) it--; - pool.insert(pool.begin() + it + 1, Q); + pool.emplace(pool.begin() + it + 1, std::move(Q)); } // remove from used and shrink as nesessary used[ID].Q = 0; - fids.push_back(ID); + fids.emplace_back(ID); ID = 0; return fragments; } diff --git a/src/Layers/xrRender/r__occlusion.h b/src/Layers/xrRender/r__occlusion.h index ceb6039b8f1..87dfc065262 100644 --- a/src/Layers/xrRender/r__occlusion.h +++ b/src/Layers/xrRender/r__occlusion.h @@ -17,7 +17,6 @@ class R_occlusion private: struct Query { - u32 order; #if defined(USE_DX9) || defined(USE_DX11) ID3DQuery* Q; #elif defined(USE_OGL) @@ -25,11 +24,12 @@ class R_occlusion #else # error No graphics API selected or enabled! #endif + u32 order; }; - static const u32 iInvalidHandle = 0xFFFFFFFF; + static constexpr u32 iInvalidHandle = 0xFFFFFFFF; - BOOL enabled; // + bool enabled; xr_vector pool; // sorted (max ... min), insertions are usually at the end xr_vector used; // id's are generated from this and it is cleared from back only xr_vector fids; // free id's From 4987250c55d11ce49e4f25cbd0ace28cdaa2d9ad Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 23:04:55 +0500 Subject: [PATCH 282/497] xrRender/r__occlusion.cpp: create queries on-demand This will eliminate lights flickering and "Too many occlusion queries were issued" warning, but you may experience a bit of slowdown for a frame or few --- src/Layers/xrRender/r__occlusion.cpp | 20 ++++++++++++++++---- src/Layers/xrRender/r__occlusion.h | 3 ++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 98a821f538a..707b044f119 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -41,10 +41,22 @@ u32 R_occlusion::occq_begin(u32& ID) // Igor: prevent release crash if we issue too many queries if (pool.empty()) { - if ((Device.dwFrame % 40) == 0) - Msg(" RENDER [Warning]: Too many occlusion queries were issued (>%u)!!!", used.size()); - ID = iInvalidHandle; - return 0; + const auto sz = used.size(); + Query q; + q.order = static_cast(sz); + if (FAILED(CreateQuery(&q.Q, D3D_QUERY_OCCLUSION))) + { + if ((Device.dwFrame % 40) == 0) + Msg(" RENDER [Warning]: Too many occlusion queries were issued (>%zu)!!!", sz); + ID = iInvalidHandle; + return 0; + } + if (sz == used.capacity()) + { + used.reserve(sz + occq_size_base); + pool.reserve(sz + occq_size_base); + } + pool.emplace(pool.begin(), std::move(q)); } RImplementation.BasicStats.OcclusionQueries++; diff --git a/src/Layers/xrRender/r__occlusion.h b/src/Layers/xrRender/r__occlusion.h index 87dfc065262..2a6e85ddb8a 100644 --- a/src/Layers/xrRender/r__occlusion.h +++ b/src/Layers/xrRender/r__occlusion.h @@ -1,6 +1,7 @@ #pragma once -constexpr u32 occq_size = 2 * 768 * R__NUM_PARALLEL_CONTEXTS; // // queue for occlusion queries +constexpr u32 occq_size_base = 768; // // queue for occlusion queries +constexpr u32 occq_size = 2 * occq_size_base * R__NUM_PARALLEL_CONTEXTS; // // queue for occlusion queries // must conform to following order of allocation/free // a(A), a(B), a(C), a(D), .... From 8950cb0b7ca166d941163f7cb7ac4271568a6257 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Apr 2024 23:07:39 +0500 Subject: [PATCH 283/497] xrRender/r__occlusion.cpp: remove old comments by Igor Shrinking the code which is different anyway now --- src/Layers/xrRender/r__occlusion.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 707b044f119..062e0aa031f 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -33,12 +33,11 @@ void R_occlusion::occq_destroy() u32 R_occlusion::occq_begin(u32& ID) { - ScopeLock lock{ &render_lock }; - if (!enabled) return 0; - // Igor: prevent release crash if we issue too many queries + ScopeLock lock{ &render_lock }; + if (pool.empty()) { const auto sz = used.size(); @@ -78,27 +77,19 @@ u32 R_occlusion::occq_begin(u32& ID) } void R_occlusion::occq_end(u32& ID) { - ScopeLock lock{ &render_lock }; - - if (!enabled) + if (!enabled || ID == iInvalidHandle) return; - // Igor: prevent release crash if we issue too many queries - if (ID == iInvalidHandle) - return; + ScopeLock lock{ &render_lock }; CHK_DX(EndQuery(used[ID].Q)); } R_occlusion::occq_result R_occlusion::occq_get(u32& ID) { - ScopeLock lock{ &render_lock }; - - if (!enabled) + if (!enabled || ID == iInvalidHandle) return 0xffffffff; - // Igor: prevent release crash if we issue too many queries - if (ID == iInvalidHandle) - return 0xFFFFFFFF; + ScopeLock lock{ &render_lock }; occq_result fragments = 0; HRESULT hr; From bae660595ff1c26f67dfa1b9d617e8f649c28dff Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 04:55:30 +0500 Subject: [PATCH 284/497] Ability to set silent level changer mode from scripts (#853) --- src/xrGame/level_changer.h | 2 ++ src/xrGame/script_game_object_script3.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/xrGame/level_changer.h b/src/xrGame/level_changer.h index 02832338900..3ecf57d08b6 100644 --- a/src/xrGame/level_changer.h +++ b/src/xrGame/level_changer.h @@ -43,6 +43,8 @@ class CLevelChanger : public CGameObject, public Feel::Touch virtual bool IsVisibleForZones() { return false; } void EnableLevelChanger(bool b) { m_b_enabled = b; } bool IsLevelChangerEnabled() const { return m_b_enabled; } + void EnableSilentMode(bool silent) { m_bSilentMode = silent; } + bool IsSilentModeEnabled() const { return m_bSilentMode; } void SetLEvelChangerInvitationStr(LPCSTR str) { m_invite_str = str; } // serialization virtual bool net_SaveRelevant(); diff --git a/src/xrGame/script_game_object_script3.cpp b/src/xrGame/script_game_object_script3.cpp index f3efb53d3b4..9543d526912 100644 --- a/src/xrGame/script_game_object_script3.cpp +++ b/src/xrGame/script_game_object_script3.cpp @@ -34,6 +34,7 @@ #include "ZoneCampfire.h" #include "PhysicObject.h" #include "Artefact.h" +#include "level_changer.h" /* New luabind makes incorrect casts in this case. He makes casts only to 'true derived class'. @@ -403,6 +404,17 @@ luabind::class_& script_register_game_object2(luabind::class_ .def("actor_look_at_point", &CScriptGameObject::ActorLookAtPoint) .def("enable_level_changer", &CScriptGameObject::enable_level_changer) .def("is_level_changer_enabled", &CScriptGameObject::is_level_changer_enabled) + .def("enable_silent_level_changer", [](const CScriptGameObject* self, bool silent) + { + if (auto* lch = smart_cast(&self->object())) + lch->EnableSilentMode(silent); + }) + .def("is_level_changer_silent", [](const CScriptGameObject* self) + { + if (const auto* lch = smart_cast(&self->object())) + return lch->IsSilentModeEnabled(); + return false; + }) .def("set_level_changer_invitation", &CScriptGameObject::set_level_changer_invitation) .def("start_particles", &CScriptGameObject::start_particles) From b577663326a108d0cd7ee53491fc4063fc6b82fb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 05:05:50 +0500 Subject: [PATCH 285/497] xrGame/level_changer.cpp: don't change level in silent mode when level changer is disabled (#853) --- src/xrGame/level_changer.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/xrGame/level_changer.cpp b/src/xrGame/level_changer.cpp index fa335f5d43e..f41890824d4 100644 --- a/src/xrGame/level_changer.cpp +++ b/src/xrGame/level_changer.cpp @@ -113,13 +113,16 @@ void CLevelChanger::feel_touch_new(IGameObject* tpObject) if (m_bSilentMode) { - NET_Packet p; - p.w_begin(M_CHANGE_LEVEL); - p.w(&m_game_vertex_id, sizeof(m_game_vertex_id)); - p.w(&m_level_vertex_id, sizeof(m_level_vertex_id)); - p.w_vec3(m_position); - p.w_vec3(m_angles); - Level().Send(p, net_flags(TRUE)); + if (m_b_enabled) + { + NET_Packet p; + p.w_begin(M_CHANGE_LEVEL); + p.w(&m_game_vertex_id, sizeof(m_game_vertex_id)); + p.w(&m_level_vertex_id, sizeof(m_level_vertex_id)); + p.w_vec3(m_position); + p.w_vec3(m_angles); + Level().Send(p, net_flags(TRUE)); + } return; } Fvector p, r; From 701e195bcaf0a0318817ba988301d6f838ba304d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 04:55:49 +0500 Subject: [PATCH 286/497] xrGame/level_changer.cpp: add XXX --- src/xrGame/level_changer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrGame/level_changer.cpp b/src/xrGame/level_changer.cpp index f41890824d4..a9f6e4a68ac 100644 --- a/src/xrGame/level_changer.cpp +++ b/src/xrGame/level_changer.cpp @@ -55,7 +55,7 @@ bool CLevelChanger::net_Spawn(CSE_Abstract* DC) m_bSilentMode = !!l_tpALifeLevelChanger->m_bSilentMode; if (ai().get_level_graph()) { - //. this information should be computed in xrAI + // XXX: this information should be computed in xrAI ai_location().level_vertex(ai().level_graph().vertex(u32(-1), Position())); ai_location().game_vertex(ai().cross_table().vertex(ai_location().level_vertex_id()).game_vertex_id()); } From 29d4448be1279b7c18caf85106d21301caadbdc3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 05:02:10 +0500 Subject: [PATCH 287/497] xrGame/script_game_object_script3.cpp: use lambda functions for level changer --- src/xrGame/level_changer.h | 2 +- src/xrGame/script_game_object.h | 4 +--- src/xrGame/script_game_object4.cpp | 21 --------------------- src/xrGame/script_game_object_script3.cpp | 20 +++++++++++++++++--- 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/xrGame/level_changer.h b/src/xrGame/level_changer.h index 3ecf57d08b6..f93d26e5503 100644 --- a/src/xrGame/level_changer.h +++ b/src/xrGame/level_changer.h @@ -45,7 +45,7 @@ class CLevelChanger : public CGameObject, public Feel::Touch bool IsLevelChangerEnabled() const { return m_b_enabled; } void EnableSilentMode(bool silent) { m_bSilentMode = silent; } bool IsSilentModeEnabled() const { return m_bSilentMode; } - void SetLEvelChangerInvitationStr(LPCSTR str) { m_invite_str = str; } + void SetLevelChangerInvitationStr(LPCSTR str) { m_invite_str = str; } // serialization virtual bool net_SaveRelevant(); virtual void save(NET_Packet& output_packet); diff --git a/src/xrGame/script_game_object.h b/src/xrGame/script_game_object.h index f53e1e96029..eb9da6b8eb5 100644 --- a/src/xrGame/script_game_object.h +++ b/src/xrGame/script_game_object.h @@ -664,9 +664,7 @@ class CScriptGameObject CScriptGameObject* active_detector() const; u32 active_slot(); void activate_slot(u32 slot_id); - void enable_level_changer(bool b); - bool is_level_changer_enabled(); - void set_level_changer_invitation(LPCSTR str); + #ifdef DEBUG void debug_planner(const script_planner* planner); #endif diff --git a/src/xrGame/script_game_object4.cpp b/src/xrGame/script_game_object4.cpp index db5d1525462..5805bd1963b 100644 --- a/src/xrGame/script_game_object4.cpp +++ b/src/xrGame/script_game_object4.cpp @@ -309,27 +309,6 @@ bool CScriptGameObject::inv_box_can_take_status() CZoneCampfire* CScriptGameObject::get_campfire() { return smart_cast(&object()); } CArtefact* CScriptGameObject::get_artefact() { return smart_cast(&object()); } CPhysicObject* CScriptGameObject::get_physics_object() { return smart_cast(&object()); } -#include "level_changer.h" -void CScriptGameObject::enable_level_changer(bool b) -{ - CLevelChanger* lch = smart_cast(&object()); - if (lch) - lch->EnableLevelChanger(b); -} -bool CScriptGameObject::is_level_changer_enabled() -{ - CLevelChanger* lch = smart_cast(&object()); - if (lch) - return lch->IsLevelChangerEnabled(); - return false; -} - -void CScriptGameObject::set_level_changer_invitation(LPCSTR str) -{ - CLevelChanger* lch = smart_cast(&object()); - if (lch) - lch->SetLEvelChangerInvitationStr(str); -} void CScriptGameObject::start_particles(LPCSTR pname, LPCSTR bone) { diff --git a/src/xrGame/script_game_object_script3.cpp b/src/xrGame/script_game_object_script3.cpp index 9543d526912..8f42e756888 100644 --- a/src/xrGame/script_game_object_script3.cpp +++ b/src/xrGame/script_game_object_script3.cpp @@ -402,8 +402,18 @@ luabind::class_& script_register_game_object2(luabind::class_ .def("aim_bone_id", (LPCSTR(CScriptGameObject::*)() const) & CScriptGameObject::aim_bone_id) .def("actor_look_at_point", &CScriptGameObject::ActorLookAtPoint) - .def("enable_level_changer", &CScriptGameObject::enable_level_changer) - .def("is_level_changer_enabled", &CScriptGameObject::is_level_changer_enabled) + + .def("enable_level_changer", [](const CScriptGameObject* self, bool enable) + { + if (auto* lch = smart_cast(&self->object())) + lch->EnableLevelChanger(enable); + }) + .def("is_level_changer_enabled", [](const CScriptGameObject* self) + { + if (const auto* lch = smart_cast(&self->object())) + return lch->IsLevelChangerEnabled(); + return false; + }) .def("enable_silent_level_changer", [](const CScriptGameObject* self, bool silent) { if (auto* lch = smart_cast(&self->object())) @@ -415,8 +425,12 @@ luabind::class_& script_register_game_object2(luabind::class_ return lch->IsSilentModeEnabled(); return false; }) + .def("set_level_changer_invitation", [](const CScriptGameObject* self, pcstr invitation) + { + if (auto* lch = smart_cast(&self->object())) + lch->SetLevelChangerInvitationStr(invitation); + }) - .def("set_level_changer_invitation", &CScriptGameObject::set_level_changer_invitation) .def("start_particles", &CScriptGameObject::start_particles) .def("stop_particles", &CScriptGameObject::stop_particles) From 912d3a6946f1817ab1fd02f8f5bddd0295757cfc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 07:41:43 +0500 Subject: [PATCH 288/497] Fix compilation --- src/xrGame/script_game_object_script3.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrGame/script_game_object_script3.cpp b/src/xrGame/script_game_object_script3.cpp index 8f42e756888..bce41d611bf 100644 --- a/src/xrGame/script_game_object_script3.cpp +++ b/src/xrGame/script_game_object_script3.cpp @@ -403,29 +403,29 @@ luabind::class_& script_register_game_object2(luabind::class_ .def("actor_look_at_point", &CScriptGameObject::ActorLookAtPoint) - .def("enable_level_changer", [](const CScriptGameObject* self, bool enable) + .def("enable_level_changer", +[](const CScriptGameObject* self, bool enable) { if (auto* lch = smart_cast(&self->object())) lch->EnableLevelChanger(enable); }) - .def("is_level_changer_enabled", [](const CScriptGameObject* self) + .def("is_level_changer_enabled", +[](const CScriptGameObject* self) { if (const auto* lch = smart_cast(&self->object())) return lch->IsLevelChangerEnabled(); return false; }) - .def("enable_silent_level_changer", [](const CScriptGameObject* self, bool silent) + .def("enable_silent_level_changer", +[](const CScriptGameObject* self, bool silent) { if (auto* lch = smart_cast(&self->object())) lch->EnableSilentMode(silent); }) - .def("is_level_changer_silent", [](const CScriptGameObject* self) + .def("is_level_changer_silent", +[](const CScriptGameObject* self) { if (const auto* lch = smart_cast(&self->object())) return lch->IsSilentModeEnabled(); return false; }) - .def("set_level_changer_invitation", [](const CScriptGameObject* self, pcstr invitation) + .def("set_level_changer_invitation", +[](const CScriptGameObject* self, pcstr invitation) { if (auto* lch = smart_cast(&self->object())) lch->SetLevelChangerInvitationStr(invitation); From 2a9d42536b8c15ec8e43e2143ad1f5093abb7002 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 07:42:23 +0500 Subject: [PATCH 289/497] Removed level compilers and corresponding dependencies 1. They were almost untested and not properly supported 2. We plan to bring a new life to SDK and tools, but that will come much later, when engine features will be ready. I'm really in favor of SkyLoader's universal compilers, use them. https://ap-pro.ru/forums/topic/3341-universalnye-kompilyatory-urovney-h64/ https://igigog.github.io/anomaly-modding-book/modding-tools/universal-x64-level-compilers.html This also accidentally closes #49 as hxGrid was a dependency for xrLC only which was removed, hence we have removed hxGrid too. --- .gitmodules | 3 - Externals/CMakeLists.txt | 1 - Externals/FreeMagic | 1 - Externals/NVTT/CMakeLists.txt | 6 - Externals/NVTT/NVTT.vcxproj | 181 -- Externals/NVTT/NVTT.vcxproj.filters | 425 ---- Externals/NVTT/NVTT/NVTT.log | 25 - Externals/NVTT/include/nvconfig.h | 16 - Externals/NVTT/include/nvtt/nvtt.h | 308 --- Externals/NVTT/include/nvtt/nvtt_wrapper.h | 241 --- Externals/NVTT/src/nvcore/BitArray.h | 168 -- Externals/NVTT/src/nvcore/CMakeLists.txt | 59 - Externals/NVTT/src/nvcore/Containers.h | 1059 ---------- Externals/NVTT/src/nvcore/Debug.cpp | 539 ----- Externals/NVTT/src/nvcore/Debug.h | 145 -- Externals/NVTT/src/nvcore/DefsGnucDarwin.h | 66 - Externals/NVTT/src/nvcore/DefsGnucLinux.h | 65 - Externals/NVTT/src/nvcore/DefsGnucWin32.h | 59 - Externals/NVTT/src/nvcore/DefsVcWin32.h | 77 - Externals/NVTT/src/nvcore/Library.cpp | 41 - Externals/NVTT/src/nvcore/Library.h | 50 - Externals/NVTT/src/nvcore/Memory.cpp | 36 - Externals/NVTT/src/nvcore/Memory.h | 186 -- Externals/NVTT/src/nvcore/Prefetch.h | 31 - Externals/NVTT/src/nvcore/Ptr.h | 364 ---- Externals/NVTT/src/nvcore/Radix.cpp | 429 ---- Externals/NVTT/src/nvcore/Radix.h | 69 - Externals/NVTT/src/nvcore/StdStream.h | 369 ---- Externals/NVTT/src/nvcore/StrLib.cpp | 584 ------ Externals/NVTT/src/nvcore/StrLib.h | 355 ---- Externals/NVTT/src/nvcore/Stream.h | 160 -- Externals/NVTT/src/nvcore/TextReader.cpp | 86 - Externals/NVTT/src/nvcore/TextReader.h | 38 - Externals/NVTT/src/nvcore/TextWriter.cpp | 45 - Externals/NVTT/src/nvcore/TextWriter.h | 65 - Externals/NVTT/src/nvcore/Tokenizer.cpp | 229 --- Externals/NVTT/src/nvcore/Tokenizer.h | 99 - Externals/NVTT/src/nvcore/nvcore.h | 172 -- .../NVTT/src/nvcore/poshlib/CMakeLists.txt | 6 - Externals/NVTT/src/nvcore/poshlib/posh.c | 1006 ---------- Externals/NVTT/src/nvcore/poshlib/posh.h | 1007 ---------- Externals/NVTT/src/nvimage/BlockDXT.cpp | 666 ------ Externals/NVTT/src/nvimage/BlockDXT.h | 223 -- Externals/NVTT/src/nvimage/CMakeLists.txt | 65 - Externals/NVTT/src/nvimage/ColorBlock.cpp | 404 ---- Externals/NVTT/src/nvimage/ColorBlock.h | 95 - Externals/NVTT/src/nvimage/ConeMap.cpp | 122 -- Externals/NVTT/src/nvimage/ConeMap.h | 39 - .../NVTT/src/nvimage/DirectDrawSurface.cpp | 1321 ------------ .../NVTT/src/nvimage/DirectDrawSurface.h | 155 -- Externals/NVTT/src/nvimage/Filter.cpp | 604 ------ Externals/NVTT/src/nvimage/Filter.h | 219 -- Externals/NVTT/src/nvimage/FloatImage.cpp | 909 --------- Externals/NVTT/src/nvimage/FloatImage.h | 270 --- Externals/NVTT/src/nvimage/HoleFilling.cpp | 753 ------- Externals/NVTT/src/nvimage/HoleFilling.h | 96 - Externals/NVTT/src/nvimage/Image.cpp | 149 -- Externals/NVTT/src/nvimage/Image.h | 83 - Externals/NVTT/src/nvimage/ImageIO.cpp | 1509 -------------- Externals/NVTT/src/nvimage/ImageIO.h | 59 - Externals/NVTT/src/nvimage/NormalMap.cpp | 141 -- Externals/NVTT/src/nvimage/NormalMap.h | 55 - Externals/NVTT/src/nvimage/NormalMipmap.cpp | 98 - Externals/NVTT/src/nvimage/NormalMipmap.h | 17 - Externals/NVTT/src/nvimage/PixelFormat.h | 82 - Externals/NVTT/src/nvimage/PsdFile.h | 70 - Externals/NVTT/src/nvimage/Quantize.cpp | 219 -- Externals/NVTT/src/nvimage/Quantize.h | 31 - Externals/NVTT/src/nvimage/TgaFile.h | 105 - Externals/NVTT/src/nvimage/nvimage.h | 22 - Externals/NVTT/src/nvmath/Basis.cpp | 173 -- Externals/NVTT/src/nvmath/Basis.h | 78 - Externals/NVTT/src/nvmath/Box.h | 140 -- Externals/NVTT/src/nvmath/CMakeLists.txt | 46 - Externals/NVTT/src/nvmath/Color.h | 179 -- Externals/NVTT/src/nvmath/Matrix.h | 1000 --------- Externals/NVTT/src/nvmath/Montecarlo.cpp | 156 -- Externals/NVTT/src/nvmath/Montecarlo.h | 84 - Externals/NVTT/src/nvmath/Plane.cpp | 17 - Externals/NVTT/src/nvmath/Plane.h | 77 - Externals/NVTT/src/nvmath/Quaternion.h | 128 -- Externals/NVTT/src/nvmath/Random.cpp | 54 - Externals/NVTT/src/nvmath/Random.h | 368 ---- .../NVTT/src/nvmath/SphericalHarmonic.cpp | 241 --- Externals/NVTT/src/nvmath/SphericalHarmonic.h | 419 ---- Externals/NVTT/src/nvmath/TriBox.cpp | 226 --- Externals/NVTT/src/nvmath/Triangle.cpp | 168 -- Externals/NVTT/src/nvmath/Triangle.h | 81 - Externals/NVTT/src/nvmath/Vector.h | 805 -------- Externals/NVTT/src/nvmath/nvmath.h | 166 -- Externals/NVTT/src/nvtt/CMakeLists.txt | 139 -- Externals/NVTT/src/nvtt/CompressDXT.cpp | 597 ------ Externals/NVTT/src/nvtt/CompressDXT.h | 87 - Externals/NVTT/src/nvtt/CompressRGB.cpp | 140 -- Externals/NVTT/src/nvtt/CompressRGB.h | 39 - .../NVTT/src/nvtt/CompressionOptions.cpp | 143 -- Externals/NVTT/src/nvtt/CompressionOptions.h | 61 - Externals/NVTT/src/nvtt/Compressor.cpp | 853 -------- Externals/NVTT/src/nvtt/Compressor.h | 80 - Externals/NVTT/src/nvtt/InputOptions.cpp | 408 ---- Externals/NVTT/src/nvtt/InputOptions.h | 113 -- .../NVTT/src/nvtt/OptimalCompressDXT.cpp | 368 ---- Externals/NVTT/src/nvtt/OptimalCompressDXT.h | 49 - Externals/NVTT/src/nvtt/OutputOptions.cpp | 103 - Externals/NVTT/src/nvtt/OutputOptions.h | 76 - Externals/NVTT/src/nvtt/QuickCompressDXT.cpp | 585 ------ Externals/NVTT/src/nvtt/QuickCompressDXT.h | 50 - Externals/NVTT/src/nvtt/SingleColorLookup.h | 588 ------ Externals/NVTT/src/nvtt/cuda/Bitmaps.h | 1119 ----------- .../NVTT/src/nvtt/cuda/CompressKernel.cu | 1122 ----------- .../NVTT/src/nvtt/cuda/ConvolveKernel.cu | 264 --- .../NVTT/src/nvtt/cuda/CudaCompressDXT.cpp | 380 ---- .../NVTT/src/nvtt/cuda/CudaCompressDXT.h | 61 - Externals/NVTT/src/nvtt/cuda/CudaMath.h | 260 --- Externals/NVTT/src/nvtt/cuda/CudaUtils.cpp | 300 --- Externals/NVTT/src/nvtt/cuda/CudaUtils.h | 44 - Externals/NVTT/src/nvtt/nvtt.cpp | 55 - Externals/NVTT/src/nvtt/nvtt.h | 308 --- Externals/NVTT/src/nvtt/nvtt_wrapper.cpp | 208 -- Externals/NVTT/src/nvtt/nvtt_wrapper.h | 241 --- Externals/NVTT/src/nvtt/squish/CMakeLists.txt | 31 - Externals/NVTT/src/nvtt/squish/ChangeLog | 38 - Externals/NVTT/src/nvtt/squish/Doxyfile | 223 -- Externals/NVTT/src/nvtt/squish/Makefile | 31 - Externals/NVTT/src/nvtt/squish/README | 35 - Externals/NVTT/src/nvtt/squish/alpha.cpp | 326 --- Externals/NVTT/src/nvtt/squish/alpha.h | 41 - Externals/NVTT/src/nvtt/squish/clusterfit.cpp | 493 ----- Externals/NVTT/src/nvtt/squish/clusterfit.h | 83 - .../NVTT/src/nvtt/squish/colourblock.cpp | 278 --- Externals/NVTT/src/nvtt/squish/colourblock.h | 44 - Externals/NVTT/src/nvtt/squish/colourfit.cpp | 59 - Externals/NVTT/src/nvtt/squish/colourfit.h | 55 - Externals/NVTT/src/nvtt/squish/colourset.cpp | 153 -- Externals/NVTT/src/nvtt/squish/colourset.h | 69 - Externals/NVTT/src/nvtt/squish/config | 22 - Externals/NVTT/src/nvtt/squish/config.h | 55 - .../NVTT/src/nvtt/squish/extra/squishgen.cpp | 158 -- .../NVTT/src/nvtt/squish/extra/squishpng.cpp | 603 ------ .../NVTT/src/nvtt/squish/extra/squishtest.cpp | 205 -- .../NVTT/src/nvtt/squish/fastclusterfit.cpp | 602 ------ .../NVTT/src/nvtt/squish/fastclusterfit.h | 76 - .../src/nvtt/squish/fastclusterlookup.inl | 1135 ----------- Externals/NVTT/src/nvtt/squish/maths.cpp | 137 -- Externals/NVTT/src/nvtt/squish/maths.h | 239 --- Externals/NVTT/src/nvtt/squish/rangefit.cpp | 203 -- Externals/NVTT/src/nvtt/squish/rangefit.h | 54 - Externals/NVTT/src/nvtt/squish/simd.h | 45 - Externals/NVTT/src/nvtt/squish/simd_3dnow.h | 213 -- Externals/NVTT/src/nvtt/squish/simd_sse.h | 193 -- Externals/NVTT/src/nvtt/squish/simd_ve.h | 176 -- .../NVTT/src/nvtt/squish/singlechannelfit.cpp | 145 -- .../NVTT/src/nvtt/squish/singlechannelfit.h | 53 - .../NVTT/src/nvtt/squish/singlecolourfit.cpp | 173 -- .../NVTT/src/nvtt/squish/singlecolourfit.h | 58 - .../src/nvtt/squish/singlecolourlookup.inl | 1040 ---------- Externals/NVTT/src/nvtt/squish/squish.cpp | 226 --- Externals/NVTT/src/nvtt/squish/squish.h | 244 --- .../squish/squish.xcodeproj/project.pbxproj | 531 ----- .../nvtt/squish/texture_compression_s3tc.txt | 508 ----- .../src/nvtt/squish/weightedclusterfit.cpp | 593 ------ .../NVTT/src/nvtt/squish/weightedclusterfit.h | 78 - Externals/NVTT/src/nvtt/tests/ctest.c | 35 - Externals/NVTT/src/nvtt/tests/filtertest.cpp | 80 - Externals/NVTT/src/nvtt/tools/assemble.cpp | 189 -- Externals/NVTT/src/nvtt/tools/benchmark.cpp | 374 ---- Externals/NVTT/src/nvtt/tools/cmdline.h | 68 - Externals/NVTT/src/nvtt/tools/compress.cpp | 468 ----- .../NVTT/src/nvtt/tools/configdialog.cpp | 170 -- Externals/NVTT/src/nvtt/tools/configdialog.h | 69 - Externals/NVTT/src/nvtt/tools/configdialog.ui | 1046 ---------- Externals/NVTT/src/nvtt/tools/ddsinfo.cpp | 57 - Externals/NVTT/src/nvtt/tools/decompress.cpp | 71 - Externals/NVTT/src/nvtt/tools/imgdiff.cpp | 296 --- Externals/NVTT/src/nvtt/tools/main.cpp | 34 - Externals/NVTT/src/nvtt/tools/resize.cpp | 183 -- sdk/binaries/x64/FreeImage.dll | Bin 6942208 -> 0 bytes sdk/binaries/x64/FreeImagePlus.dll | Bin 139264 -> 0 bytes sdk/binaries/x86/FreeImage.dll | Bin 6018560 -> 0 bytes sdk/binaries/x86/FreeImagePlus.dll | Bin 111104 -> 0 bytes sdk/include/FreeImage.h | 1163 ----------- sdk/include/FreeImagePlus.h | 1786 ----------------- sdk/include/hxgrid/Interface/IAgent.h | 160 -- sdk/include/hxgrid/Interface/IGenericStream.h | 63 - sdk/include/hxgrid/Interface/IGridUser.h | 291 --- sdk/include/hxgrid/Interface/I_Agent.pas | 169 -- .../hxgrid/Interface/I_GenericStream.pas | 62 - sdk/include/hxgrid/Interface/I_GridUser.pas | 331 --- sdk/include/hxgrid/Interface/InOut.h | 9 - sdk/include/hxgrid/Interface/Singleton.h | 19 - sdk/include/hxgrid/Interface/VECOM.h | 123 -- .../hxgrid/Interface/hxGridInterface.cpp | 50 - .../hxgrid/Interface/hxGridInterface.h | 7 - sdk/include/hxgrid/Interface/hxplatform.h | 133 -- sdk/libraries/x64/FreeImage.lib | Bin 65322 -> 0 bytes sdk/libraries/x64/FreeImagePlus.lib | Bin 68708 -> 0 bytes sdk/libraries/x86/FreeImage.lib | Bin 69766 -> 0 bytes sdk/libraries/x86/FreeImagePlus.lib | Bin 67112 -> 0 bytes src/Layers/xrRenderPC_GL/CMakeLists.txt | 1 + src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj | 1 + .../xrRenderPC_GL/xrRender_GL.vcxproj.filters | 3 + src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj | 1 + .../xrRenderPC_R1/xrRender_R1.vcxproj.filters | 3 + src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj | 1 + .../xrRenderPC_R2/xrRender_R2.vcxproj.filters | 3 + src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj | 1 + .../xrRenderPC_R4/xrRender_R4.vcxproj.filters | 3 + src/engine.sln | 349 ---- src/utils/CMakeLists.txt | 10 - src/utils/ETools/ArbitraryList.h | 168 -- src/utils/ETools/BinaryHeap.h | 261 --- src/utils/ETools/DLink.h | 256 --- src/utils/ETools/ETools.cpp | 21 - src/utils/ETools/ETools.h | 7 - src/utils/ETools/ETools.vcxproj | 97 - src/utils/ETools/ETools.vcxproj.filters | 66 - src/utils/ETools/PropSlimTools.cpp | 167 -- src/utils/ETools/PropSlimTools.h | 37 - src/utils/ETools/StdAfx.cpp | 4 - src/utils/ETools/StdAfx.h | 17 - src/utils/ETools/mesh.h | 1746 ---------------- src/utils/ETools/object.cpp | 544 ----- src/utils/ETools/object.h | 159 -- src/utils/ETools/object_sliding.cpp | 382 ---- src/utils/ETools/object_sliding.h | 8 - src/utils/ETools/packages.config | 4 - src/utils/ETools/quad.h | 117 -- src/utils/Shader_xrLC.h | 172 -- src/utils/communicate.h | 265 --- src/utils/xrAI/ESceneAIMapTools.cpp | 627 ------ src/utils/xrAI/ESceneAIMapTools.h | 253 --- src/utils/xrAI/ESceneAIMapTools_Export.cpp | 101 - src/utils/xrAI/ESceneAIMapTools_Export.h | 29 - src/utils/xrAI/ESceneClassList.h | 40 - src/utils/xrAI/ESceneCustomMTools.cpp | 88 - src/utils/xrAI/ESceneCustomMTools.h | 177 -- src/utils/xrAI/StdAfx.cpp | 21 - src/utils/xrAI/StdAfx.h | 35 - src/utils/xrAI/compiler.cpp | 28 - src/utils/xrAI/compiler.h | 148 -- src/utils/xrAI/compiler_cover.cpp | 583 ------ src/utils/xrAI/compiler_load.cpp | 301 --- src/utils/xrAI/compiler_save.cpp | 142 -- src/utils/xrAI/factory_api.h | 25 - src/utils/xrAI/game_graph_builder.cpp | 706 ------- src/utils/xrAI/game_graph_builder.h | 87 - src/utils/xrAI/game_graph_builder_inline.h | 27 - src/utils/xrAI/game_spawn_constructor.cpp | 319 --- src/utils/xrAI/game_spawn_constructor.h | 100 - .../xrAI/game_spawn_constructor_inline.h | 50 - src/utils/xrAI/guid_generator.cpp | 63 - src/utils/xrAI/guid_generator.h | 15 - src/utils/xrAI/level_spawn_constructor.cpp | 625 ------ src/utils/xrAI/level_spawn_constructor.h | 92 - .../xrAI/level_spawn_constructor_inline.h | 31 - src/utils/xrAI/packages.config | 4 - src/utils/xrAI/resource.h | 29 - src/utils/xrAI/resource.rc | 113 -- src/utils/xrAI/server_entity_wrapper.cpp | 106 - src/utils/xrAI/server_entity_wrapper.h | 28 - src/utils/xrAI/server_entity_wrapper_inline.h | 16 - src/utils/xrAI/space_restrictor_wrapper.cpp | 286 --- src/utils/xrAI/space_restrictor_wrapper.h | 49 - .../xrAI/space_restrictor_wrapper_inline.h | 27 - src/utils/xrAI/spawn_constructor_space.h | 18 - src/utils/xrAI/verify_level_graph.cpp | 148 -- src/utils/xrAI/xrAI.cpp | 173 -- src/utils/xrAI/xrAI.h | 3 - src/utils/xrAI/xrAI.vcxproj | 129 -- src/utils/xrAI/xrAI.vcxproj.filters | 194 -- src/utils/xrAI/xrAI_Readme.txt | 63 - src/utils/xrAI/xr_graph_merge.cpp | 695 ------- src/utils/xrAI/xr_graph_merge.h | 26 - src/utils/xrDO_Light/StdAfx.cpp | 21 - src/utils/xrDO_Light/StdAfx.h | 11 - src/utils/xrDO_Light/packages.config | 4 - src/utils/xrDO_Light/xrDO_Light.cpp | 64 - src/utils/xrDO_Light/xrDO_Light.vcxproj | 73 - .../xrDO_Light/xrDO_Light.vcxproj.filters | 27 - src/utils/xrDXT/DXT.cpp | 196 -- src/utils/xrDXT/DXT.vcxproj | 80 - src/utils/xrDXT/DXT.vcxproj.filters | 62 - src/utils/xrDXT/Image_DXTC.cpp | 988 --------- src/utils/xrDXT/Image_DXTC.h | 73 - src/utils/xrDXT/NVI_Convolution.cpp | 174 -- src/utils/xrDXT/NVI_Convolution.h | 68 - src/utils/xrDXT/NVI_Image.cpp | 306 --- src/utils/xrDXT/NVI_Image.h | 157 -- src/utils/xrDXT/NV_Common.h | 107 - src/utils/xrDXT/NormalMapGen.cpp | 675 ------- src/utils/xrDXT/StdAfx.cpp | 1 - src/utils/xrDXT/StdAfx.h | 6 - src/utils/xrDXT/dds.h | 91 - src/utils/xrDXT/dds/ConvertColor.h | 280 --- src/utils/xrDXT/dds/ddsTypes.h | 298 --- src/utils/xrDXT/dds/nvErrorCodes.h | 99 - src/utils/xrDXT/dds/tPixel.h | 1257 ------------ src/utils/xrDXT/dds/tVector.h | 478 ----- src/utils/xrLC/ArbitraryList.h | 169 -- src/utils/xrLC/Build.cpp | 406 ---- src/utils/xrLC/Build.h | 111 - src/utils/xrLC/Build_Load.cpp | 379 ---- src/utils/xrLC/ELight_def.h | 34 - src/utils/xrLC/MeshMenderLayerOGF.h | 49 - .../xrLC/MeshMenderLayerOrdinaryStatic.h | 31 - src/utils/xrLC/NvMender2002/NVMeshMender.cpp | 921 --------- src/utils/xrLC/NvMender2002/NVMeshMender.h | 223 -- src/utils/xrLC/NvMender2002/nv_algebra.cpp | 1420 ------------- src/utils/xrLC/NvMender2002/nv_algebra.h | 631 ------ src/utils/xrLC/NvMender2002/nv_math.h | 54 - src/utils/xrLC/NvMender2002/nv_mathdecl.h | 31 - src/utils/xrLC/NvMeshMenderLayer.h | 9 - src/utils/xrLC/NvMeshMenderLayerInline.h | 64 - src/utils/xrLC/OGF_CalculateTB.cpp | 54 - src/utils/xrLC/OGF_Face.cpp | 571 ------ src/utils/xrLC/OGF_Face.h | 286 --- src/utils/xrLC/OGF_Face_Save.cpp | 269 --- src/utils/xrLC/OGF_Face_Sphere.cpp | 97 - src/utils/xrLC/OGF_Face_Stripify.cpp | 156 -- src/utils/xrLC/OGF_RemoveIsolatedVerts.cpp | 4 - src/utils/xrLC/Sector.cpp | 168 -- src/utils/xrLC/Sector.h | 32 - src/utils/xrLC/StdAfx.cpp | 21 - src/utils/xrLC/StdAfx.h | 18 - src/utils/xrLC/_rect.h | 194 -- src/utils/xrLC/b_globals.h | 24 - src/utils/xrLC/fmesh.cpp | 160 -- src/utils/xrLC/net.cpp | 28 - src/utils/xrLC/net.h | 7 - src/utils/xrLC/nv_library/NvTriStrip.cpp | 259 --- src/utils/xrLC/nv_library/NvTriStrip.h | 115 -- .../xrLC/nv_library/NvTriStripObjects.cpp | 1355 ------------- src/utils/xrLC/nv_library/NvTriStripObjects.h | 240 --- src/utils/xrLC/nv_library/VertexCache.cpp | 21 - src/utils/xrLC/nv_library/VertexCache.h | 56 - src/utils/xrLC/packages.config | 4 - src/utils/xrLC/std_classes.h | 49 - src/utils/xrLC/vbm.h | 207 -- src/utils/xrLC/xrBuildCForm.cpp | 204 -- src/utils/xrLC/xrBuildRapidModel.cpp | 185 -- src/utils/xrLC/xrCalcNormals.cpp | 16 - src/utils/xrLC/xrFlex2OGF.cpp | 184 -- src/utils/xrLC/xrGameMaterials.h | 29 - src/utils/xrLC/xrLC.cpp | 145 -- src/utils/xrLC/xrLC.vcxproj | 180 -- src/utils/xrLC/xrLC.vcxproj.filters | 277 --- src/utils/xrLC/xrLight.cpp | 162 -- src/utils/xrLC/xrMU_Model_Calc_ogf.cpp | 127 -- src/utils/xrLC/xrMU_Model_export_OGF.cpp | 124 -- src/utils/xrLC/xrMU_Model_export_geometry.cpp | 107 - src/utils/xrLC/xrOptimizeCFORM_qslim.cpp | 202 -- src/utils/xrLC/xrPhase_AdaptiveHT.cpp | 490 ----- src/utils/xrLC/xrPhase_AdaptiveHT_qslim.cpp | 426 ---- src/utils/xrLC/xrPhase_GI.cpp | 266 --- src/utils/xrLC/xrPhase_MergeGeometry.cpp | 351 ---- src/utils/xrLC/xrPhase_MergeLM.cpp | 520 ----- src/utils/xrLC/xrPhase_MergeLM_Rect.h | 68 - src/utils/xrLC/xrPhase_MergeLM_Surface.cpp | 283 --- src/utils/xrLC/xrPhase_ResolveMaterials.cpp | 90 - src/utils/xrLC/xrPhase_Subdivide.cpp | 214 -- src/utils/xrLC/xrPhase_TangentBasis.cpp | 135 -- src/utils/xrLC/xrPhase_UVmap.cpp | 163 -- src/utils/xrLC/xrPreOptimize.cpp | 214 -- src/utils/xrLC/xrSaveLights.cpp | 14 - src/utils/xrLC/xrSaveOGF.cpp | 137 -- src/utils/xrLC/xrSectors.cpp | 103 - src/utils/xrLC/xrT_Junction.cpp | 161 -- src/utils/xrLCUtil/CMakeLists.txt | 40 - src/utils/xrLCUtil/ILevelCompilerLogger.hpp | 20 - .../xrLCUtil/LevelCompilerLoggerWindow.cpp | 261 --- .../xrLCUtil/LevelCompilerLoggerWindow.hpp | 53 - src/utils/xrLCUtil/packages.config | 5 - src/utils/xrLCUtil/pch.cpp | 1 - src/utils/xrLCUtil/pch.hpp | 4 - src/utils/xrLCUtil/resource.h | 33 - src/utils/xrLCUtil/resource.rc | 150 -- src/utils/xrLCUtil/xrLCUtil.cpp | 15 - src/utils/xrLCUtil/xrLCUtil.hpp | 20 - src/utils/xrLCUtil/xrLCUtil.vcxproj | 92 - src/utils/xrLCUtil/xrLCUtil.vcxproj.filters | 62 - src/utils/xrLCUtil/xrThread.cpp | 69 - src/utils/xrLCUtil/xrThread.hpp | 73 - src/utils/xrLC_Light/CMakeLists.txt | 210 -- src/utils/xrLC_Light/ETextureParams.cpp | 459 ----- src/utils/xrLC_Light/ETextureParams.h | 203 -- src/utils/xrLC_Light/LightThread.cpp | 30 - src/utils/xrLC_Light/LightThread.h | 20 - src/utils/xrLC_Light/Lightmap.cpp | 224 --- src/utils/xrLC_Light/Lightmap.h | 37 - src/utils/xrLC_Light/MeshStaic.cpp | 101 - src/utils/xrLC_Light/MeshStructure.h | 376 ---- src/utils/xrLC_Light/ReadMe.txt | 41 - src/utils/xrLC_Light/b_build_texture.cpp | 27 - src/utils/xrLC_Light/b_build_texture.h | 30 - src/utils/xrLC_Light/base_basis.cpp | 11 - src/utils/xrLC_Light/base_basis.h | 28 - src/utils/xrLC_Light/base_color.cpp | 18 - src/utils/xrLC_Light/base_color.h | 121 -- src/utils/xrLC_Light/base_face.cpp | 66 - src/utils/xrLC_Light/base_face.h | 56 - src/utils/xrLC_Light/base_face_ptr_storage.h | 34 - src/utils/xrLC_Light/base_lighting.cpp | 43 - src/utils/xrLC_Light/base_lighting.h | 20 - src/utils/xrLC_Light/calculate_normals.h | 91 - src/utils/xrLC_Light/compiler.cpp | 43 - .../xrLC_Light/detail_net_global_data.cpp | 47 - src/utils/xrLC_Light/detail_net_global_data.h | 35 - .../xrLC_Light/detail_slot_calculate.cpp | 415 ---- src/utils/xrLC_Light/detail_slot_calculate.h | 29 - src/utils/xrLC_Light/execute_statistics.cpp | 38 - src/utils/xrLC_Light/execute_statistics.h | 35 - src/utils/xrLC_Light/file_compress.cpp | 76 - src/utils/xrLC_Light/file_compress.h | 7 - src/utils/xrLC_Light/fitter.cpp | 107 - src/utils/xrLC_Light/fitter.h | 29 - src/utils/xrLC_Light/gl_base_cl_data.cpp | 46 - src/utils/xrLC_Light/gl_base_cl_data.h | 29 - .../xrLC_Light/global_calculation_data.cpp | 243 --- .../xrLC_Light/global_calculation_data.h | 32 - src/utils/xrLC_Light/global_slots_data.cpp | 83 - src/utils/xrLC_Light/global_slots_data.h | 77 - src/utils/xrLC_Light/hash2D.h | 106 - .../xrLC_Light/implicit_net_global_data.cpp | 42 - .../xrLC_Light/implicit_net_global_data.h | 30 - src/utils/xrLC_Light/itterate_adjacents.h | 23 - .../xrLC_Light/itterate_adjacents_static.h | 111 - src/utils/xrLC_Light/lc_net_global_data.cpp | 40 - src/utils/xrLC_Light/lc_net_global_data.h | 27 - .../xrLC_Light/lcnet_execution_tasks_add.h | 8 - src/utils/xrLC_Light/lcnet_task_manager.cpp | 214 -- src/utils/xrLC_Light/lcnet_task_manager.h | 65 - .../lcnet_task_menager_run_task.cpp | 32 - src/utils/xrLC_Light/light_execute.cpp | 6 - src/utils/xrLC_Light/light_execute.h | 15 - src/utils/xrLC_Light/light_point.h | 13 - src/utils/xrLC_Light/lightstab_interface.h | 12 - src/utils/xrLC_Light/lm_layer.cpp | 101 - src/utils/xrLC_Light/lm_layer.h | 51 - src/utils/xrLC_Light/lm_net_global_data.cpp | 47 - src/utils/xrLC_Light/lm_net_global_data.h | 26 - src/utils/xrLC_Light/mu_light_net.cpp | 78 - src/utils/xrLC_Light/mu_light_net.h | 10 - src/utils/xrLC_Light/mu_model_face.cpp | 79 - src/utils/xrLC_Light/mu_model_face.h | 59 - src/utils/xrLC_Light/mu_model_face_defs.h | 14 - src/utils/xrLC_Light/mu_model_light.cpp | 20 - src/utils/xrLC_Light/mu_model_light.h | 10 - .../xrLC_Light/mu_model_light_threads.cpp | 113 -- src/utils/xrLC_Light/mu_model_light_threads.h | 7 - src/utils/xrLC_Light/net_all_executions.h | 9 - src/utils/xrLC_Light/net_all_globals.h | 9 - src/utils/xrLC_Light/net_cl_data_prepare.cpp | 106 - src/utils/xrLC_Light/net_cl_data_prepare.h | 10 - src/utils/xrLC_Light/net_exec_pool.cpp | 251 --- src/utils/xrLC_Light/net_exec_pool.h | 55 - src/utils/xrLC_Light/net_execution.cpp | 19 - src/utils/xrLC_Light/net_execution.h | 60 - .../xrLC_Light/net_execution_detail_light.cpp | 113 -- .../xrLC_Light/net_execution_detail_light.h | 39 - .../xrLC_Light/net_execution_factory.cpp | 66 - src/utils/xrLC_Light/net_execution_factory.h | 63 - .../net_execution_factory_register.cpp | 130 -- .../xrLC_Light/net_execution_globals.cpp | 147 -- src/utils/xrLC_Light/net_execution_globals.h | 53 - .../net_execution_implicit_light.cpp | 46 - .../xrLC_Light/net_execution_implicit_light.h | 29 - .../xrLC_Light/net_execution_lightmaps.cpp | 165 -- .../xrLC_Light/net_execution_lightmaps.h | 42 - .../xrLC_Light/net_execution_mu_base.cpp | 63 - src/utils/xrLC_Light/net_execution_mu_base.h | 36 - src/utils/xrLC_Light/net_execution_mu_ref.cpp | 52 - src/utils/xrLC_Light/net_execution_mu_ref.h | 30 - .../xrLC_Light/net_execution_vertex_light.cpp | 110 - .../xrLC_Light/net_execution_vertex_light.h | 47 - src/utils/xrLC_Light/net_global_data.cpp | 220 -- src/utils/xrLC_Light/net_global_data.h | 58 - .../xrLC_Light/net_global_data_cleanup.cpp | 55 - .../xrLC_Light/net_global_data_cleanup.h | 44 - src/utils/xrLC_Light/net_light.cpp | 165 -- src/utils/xrLC_Light/net_light.h | 11 - src/utils/xrLC_Light/net_light_task.cpp | 6 - src/utils/xrLC_Light/net_light_task.h | 15 - .../xrLC_Light/net_lightmaps_add_task.cpp | 104 - src/utils/xrLC_Light/net_stream.cpp | 432 ---- src/utils/xrLC_Light/net_stream.h | 344 ---- src/utils/xrLC_Light/net_task.cpp | 45 - src/utils/xrLC_Light/net_task.h | 37 - src/utils/xrLC_Light/net_task_callback.cpp | 15 - src/utils/xrLC_Light/net_task_callback.h | 26 - src/utils/xrLC_Light/net_task_manager.cpp | 272 --- src/utils/xrLC_Light/net_task_manager.h | 23 - src/utils/xrLC_Light/net_task_menager.cpp | 153 -- src/utils/xrLC_Light/net_task_menager.h | 22 - src/utils/xrLC_Light/packages.config | 4 - src/utils/xrLC_Light/recalculation.cpp | 131 -- src/utils/xrLC_Light/recalculation.h | 62 - .../xrLC_Light/ref_model_net_global_data.cpp | 35 - .../xrLC_Light/ref_model_net_global_data.h | 27 - src/utils/xrLC_Light/serialize.cpp | 35 - src/utils/xrLC_Light/serialize.h | 282 --- src/utils/xrLC_Light/stdafx.cpp | 21 - src/utils/xrLC_Light/stdafx.h | 25 - src/utils/xrLC_Light/tcf.cpp | 30 - src/utils/xrLC_Light/tcf.h | 22 - src/utils/xrLC_Light/uv_tri.cpp | 24 - src/utils/xrLC_Light/uv_tri.h | 12 - src/utils/xrLC_Light/vector_clear.h | 24 - src/utils/xrLC_Light/xrDXTC.h | 26 - src/utils/xrLC_Light/xrDeflectoL_Direct.cpp | 179 -- src/utils/xrLC_Light/xrDeflector.cpp | 485 ----- src/utils/xrLC_Light/xrDeflector.h | 118 -- src/utils/xrLC_Light/xrDeflectorDefs.h | 9 - src/utils/xrLC_Light/xrDeflectorLight.cpp | 977 --------- src/utils/xrLC_Light/xrFace.cpp | 434 ---- src/utils/xrLC_Light/xrFace.h | 95 - src/utils/xrLC_Light/xrFaceDefs.h | 23 - src/utils/xrLC_Light/xrFaceInline.h | 2 - src/utils/xrLC_Light/xrImage_Filter.cpp | 54 - src/utils/xrLC_Light/xrImage_Filter.h | 7 - src/utils/xrLC_Light/xrImage_Resampler.cpp | 584 ------ src/utils/xrLC_Light/xrImage_Resampler.h | 18 - src/utils/xrLC_Light/xrIsect.h | 117 -- src/utils/xrLC_Light/xrLC_GlobalData.cpp | 617 ------ src/utils/xrLC_Light/xrLC_GlobalData.h | 161 -- src/utils/xrLC_Light/xrLC_Light.cpp | 44 - src/utils/xrLC_Light/xrLC_Light.h | 49 - src/utils/xrLC_Light/xrLC_Light.vcxproj | 266 --- .../xrLC_Light/xrLC_Light.vcxproj.filters | 575 ------ src/utils/xrLC_Light/xrLightDoNet.cpp | 66 - src/utils/xrLC_Light/xrLightDoNet.h | 13 - src/utils/xrLC_Light/xrLightVertex.cpp | 215 -- src/utils/xrLC_Light/xrLightVertex.h | 4 - src/utils/xrLC_Light/xrLightVertexNet.cpp | 67 - src/utils/xrLC_Light/xrLight_ImlicitNet.cpp | 60 - src/utils/xrLC_Light/xrLight_Implicit.cpp | 308 --- src/utils/xrLC_Light/xrLight_Implicit.h | 21 - .../xrLC_Light/xrLight_ImplicitCalcGlobs.cpp | 53 - .../xrLC_Light/xrLight_ImplicitCalcGlobs.h | 32 - .../xrLC_Light/xrLight_ImplicitDeflector.cpp | 49 - .../xrLC_Light/xrLight_ImplicitDeflector.h | 35 - src/utils/xrLC_Light/xrLight_ImplicitRun.h | 10 - .../xrLC_Light/xrLight_ImplicitThread.cpp | 34 - src/utils/xrLC_Light/xrMU_Model.cpp | 190 -- src/utils/xrLC_Light/xrMU_Model.h | 142 -- .../xrMU_Model_Calc_faceopacity.cpp | 8 - .../xrLC_Light/xrMU_Model_Calc_lighting.cpp | 236 --- .../xrLC_Light/xrMU_Model_Calc_materials.cpp | 48 - .../xrLC_Light/xrMU_Model_Calc_normals.cpp | 104 - src/utils/xrLC_Light/xrMU_Model_Load.cpp | 104 - src/utils/xrLC_Light/xrMU_Model_Reference.cpp | 134 -- src/utils/xrLC_Light/xrMU_Model_Reference.h | 48 - .../xrMU_Model_Reference_Calc_Lighting.cpp | 138 -- .../xrMU_Model_export_cform_rcast.cpp | 60 - src/utils/xrLC_Light/xrUVpoint.h | 86 - src/utils/xrLC_LightStab/packages.config | 4 - src/utils/xrLC_LightStab/xrLC_LightStab.cpp | 15 - src/utils/xrLC_LightStab/xrLC_LightStab.h | 16 - .../xrLC_LightStab/xrLC_LightStab.vcxproj | 69 - .../xrLC_LightStab.vcxproj.filters | 15 - src/utils/xrQSlim/CMakeLists.txt | 61 - src/utils/xrQSlim/MxBlock.h | 122 -- src/utils/xrQSlim/MxBlock2.h | 47 - src/utils/xrQSlim/MxBlockModel.cpp | 320 --- src/utils/xrQSlim/MxBlockModel.h | 142 -- src/utils/xrQSlim/MxDefines.h | 13 - src/utils/xrQSlim/MxDynBlock.h | 82 - src/utils/xrQSlim/MxGeoPrims.h | 343 ---- src/utils/xrQSlim/MxGeom3D.cpp | 137 -- src/utils/xrQSlim/MxGeom3D.h | 74 - src/utils/xrQSlim/MxHeap.cpp | 140 -- src/utils/xrQSlim/MxHeap.h | 69 - src/utils/xrQSlim/MxMat2.h | 20 - src/utils/xrQSlim/MxMat3-jacobi.cpp | 224 --- src/utils/xrQSlim/MxMat3.h | 25 - src/utils/xrQSlim/MxMat4-jacobi.cpp | 196 -- src/utils/xrQSlim/MxMat4.h | 43 - src/utils/xrQSlim/MxMatrix.cpp | 99 - src/utils/xrQSlim/MxMatrix.h | 87 - src/utils/xrQSlim/MxPropSlim.cpp | 708 ------- src/utils/xrQSlim/MxPropSlim.h | 95 - src/utils/xrQSlim/MxQMetric.cpp | 113 -- src/utils/xrQSlim/MxQMetric.h | 86 - src/utils/xrQSlim/MxQMetric3.cpp | 266 --- src/utils/xrQSlim/MxQMetric3.h | 116 -- src/utils/xrQSlim/MxQSlim.cpp | 764 ------- src/utils/xrQSlim/MxQSlim.h | 118 -- src/utils/xrQSlim/MxStdModel.cpp | 707 ------- src/utils/xrQSlim/MxStdModel.h | 202 -- src/utils/xrQSlim/MxStdSlim.cpp | 40 - src/utils/xrQSlim/MxStdSlim.h | 68 - src/utils/xrQSlim/MxVec3.h | 26 - src/utils/xrQSlim/MxVec4.h | 25 - src/utils/xrQSlim/MxVector.h | 196 -- src/utils/xrQSlim/geom3d.h | 113 -- src/utils/xrQSlim/mat2.cpp | 87 - src/utils/xrQSlim/mat2.h | 160 -- src/utils/xrQSlim/mat3.cpp | 73 - src/utils/xrQSlim/mat3.h | 160 -- src/utils/xrQSlim/mat4.cpp | 215 -- src/utils/xrQSlim/mat4.h | 193 -- src/utils/xrQSlim/mixmops.cpp | 242 --- src/utils/xrQSlim/mixmops.h | 176 -- src/utils/xrQSlim/mixvops.h | 203 -- src/utils/xrQSlim/stdafx.h | 24 - src/utils/xrQSlim/vec2.h | 225 --- src/utils/xrQSlim/vec3.h | 255 --- src/utils/xrQSlim/vec4.h | 266 --- src/utils/xrQSlim/xrQSlim.vcxproj | 94 - src/utils/xrQSlim/xrQSlim.vcxproj.filters | 165 -- 609 files changed, 17 insertions(+), 105960 deletions(-) delete mode 160000 Externals/FreeMagic delete mode 100644 Externals/NVTT/CMakeLists.txt delete mode 100644 Externals/NVTT/NVTT.vcxproj delete mode 100644 Externals/NVTT/NVTT.vcxproj.filters delete mode 100644 Externals/NVTT/NVTT/NVTT.log delete mode 100644 Externals/NVTT/include/nvconfig.h delete mode 100644 Externals/NVTT/include/nvtt/nvtt.h delete mode 100644 Externals/NVTT/include/nvtt/nvtt_wrapper.h delete mode 100644 Externals/NVTT/src/nvcore/BitArray.h delete mode 100644 Externals/NVTT/src/nvcore/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvcore/Containers.h delete mode 100644 Externals/NVTT/src/nvcore/Debug.cpp delete mode 100644 Externals/NVTT/src/nvcore/Debug.h delete mode 100644 Externals/NVTT/src/nvcore/DefsGnucDarwin.h delete mode 100644 Externals/NVTT/src/nvcore/DefsGnucLinux.h delete mode 100644 Externals/NVTT/src/nvcore/DefsGnucWin32.h delete mode 100644 Externals/NVTT/src/nvcore/DefsVcWin32.h delete mode 100644 Externals/NVTT/src/nvcore/Library.cpp delete mode 100644 Externals/NVTT/src/nvcore/Library.h delete mode 100644 Externals/NVTT/src/nvcore/Memory.cpp delete mode 100644 Externals/NVTT/src/nvcore/Memory.h delete mode 100644 Externals/NVTT/src/nvcore/Prefetch.h delete mode 100644 Externals/NVTT/src/nvcore/Ptr.h delete mode 100644 Externals/NVTT/src/nvcore/Radix.cpp delete mode 100644 Externals/NVTT/src/nvcore/Radix.h delete mode 100644 Externals/NVTT/src/nvcore/StdStream.h delete mode 100644 Externals/NVTT/src/nvcore/StrLib.cpp delete mode 100644 Externals/NVTT/src/nvcore/StrLib.h delete mode 100644 Externals/NVTT/src/nvcore/Stream.h delete mode 100644 Externals/NVTT/src/nvcore/TextReader.cpp delete mode 100644 Externals/NVTT/src/nvcore/TextReader.h delete mode 100644 Externals/NVTT/src/nvcore/TextWriter.cpp delete mode 100644 Externals/NVTT/src/nvcore/TextWriter.h delete mode 100644 Externals/NVTT/src/nvcore/Tokenizer.cpp delete mode 100644 Externals/NVTT/src/nvcore/Tokenizer.h delete mode 100644 Externals/NVTT/src/nvcore/nvcore.h delete mode 100644 Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvcore/poshlib/posh.c delete mode 100644 Externals/NVTT/src/nvcore/poshlib/posh.h delete mode 100644 Externals/NVTT/src/nvimage/BlockDXT.cpp delete mode 100644 Externals/NVTT/src/nvimage/BlockDXT.h delete mode 100644 Externals/NVTT/src/nvimage/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvimage/ColorBlock.cpp delete mode 100644 Externals/NVTT/src/nvimage/ColorBlock.h delete mode 100644 Externals/NVTT/src/nvimage/ConeMap.cpp delete mode 100644 Externals/NVTT/src/nvimage/ConeMap.h delete mode 100644 Externals/NVTT/src/nvimage/DirectDrawSurface.cpp delete mode 100644 Externals/NVTT/src/nvimage/DirectDrawSurface.h delete mode 100644 Externals/NVTT/src/nvimage/Filter.cpp delete mode 100644 Externals/NVTT/src/nvimage/Filter.h delete mode 100644 Externals/NVTT/src/nvimage/FloatImage.cpp delete mode 100644 Externals/NVTT/src/nvimage/FloatImage.h delete mode 100644 Externals/NVTT/src/nvimage/HoleFilling.cpp delete mode 100644 Externals/NVTT/src/nvimage/HoleFilling.h delete mode 100644 Externals/NVTT/src/nvimage/Image.cpp delete mode 100644 Externals/NVTT/src/nvimage/Image.h delete mode 100644 Externals/NVTT/src/nvimage/ImageIO.cpp delete mode 100644 Externals/NVTT/src/nvimage/ImageIO.h delete mode 100644 Externals/NVTT/src/nvimage/NormalMap.cpp delete mode 100644 Externals/NVTT/src/nvimage/NormalMap.h delete mode 100644 Externals/NVTT/src/nvimage/NormalMipmap.cpp delete mode 100644 Externals/NVTT/src/nvimage/NormalMipmap.h delete mode 100644 Externals/NVTT/src/nvimage/PixelFormat.h delete mode 100644 Externals/NVTT/src/nvimage/PsdFile.h delete mode 100644 Externals/NVTT/src/nvimage/Quantize.cpp delete mode 100644 Externals/NVTT/src/nvimage/Quantize.h delete mode 100644 Externals/NVTT/src/nvimage/TgaFile.h delete mode 100644 Externals/NVTT/src/nvimage/nvimage.h delete mode 100644 Externals/NVTT/src/nvmath/Basis.cpp delete mode 100644 Externals/NVTT/src/nvmath/Basis.h delete mode 100644 Externals/NVTT/src/nvmath/Box.h delete mode 100644 Externals/NVTT/src/nvmath/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvmath/Color.h delete mode 100644 Externals/NVTT/src/nvmath/Matrix.h delete mode 100644 Externals/NVTT/src/nvmath/Montecarlo.cpp delete mode 100644 Externals/NVTT/src/nvmath/Montecarlo.h delete mode 100644 Externals/NVTT/src/nvmath/Plane.cpp delete mode 100644 Externals/NVTT/src/nvmath/Plane.h delete mode 100644 Externals/NVTT/src/nvmath/Quaternion.h delete mode 100644 Externals/NVTT/src/nvmath/Random.cpp delete mode 100644 Externals/NVTT/src/nvmath/Random.h delete mode 100644 Externals/NVTT/src/nvmath/SphericalHarmonic.cpp delete mode 100644 Externals/NVTT/src/nvmath/SphericalHarmonic.h delete mode 100644 Externals/NVTT/src/nvmath/TriBox.cpp delete mode 100644 Externals/NVTT/src/nvmath/Triangle.cpp delete mode 100644 Externals/NVTT/src/nvmath/Triangle.h delete mode 100644 Externals/NVTT/src/nvmath/Vector.h delete mode 100644 Externals/NVTT/src/nvmath/nvmath.h delete mode 100644 Externals/NVTT/src/nvtt/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvtt/CompressDXT.cpp delete mode 100644 Externals/NVTT/src/nvtt/CompressDXT.h delete mode 100644 Externals/NVTT/src/nvtt/CompressRGB.cpp delete mode 100644 Externals/NVTT/src/nvtt/CompressRGB.h delete mode 100644 Externals/NVTT/src/nvtt/CompressionOptions.cpp delete mode 100644 Externals/NVTT/src/nvtt/CompressionOptions.h delete mode 100644 Externals/NVTT/src/nvtt/Compressor.cpp delete mode 100644 Externals/NVTT/src/nvtt/Compressor.h delete mode 100644 Externals/NVTT/src/nvtt/InputOptions.cpp delete mode 100644 Externals/NVTT/src/nvtt/InputOptions.h delete mode 100644 Externals/NVTT/src/nvtt/OptimalCompressDXT.cpp delete mode 100644 Externals/NVTT/src/nvtt/OptimalCompressDXT.h delete mode 100644 Externals/NVTT/src/nvtt/OutputOptions.cpp delete mode 100644 Externals/NVTT/src/nvtt/OutputOptions.h delete mode 100644 Externals/NVTT/src/nvtt/QuickCompressDXT.cpp delete mode 100644 Externals/NVTT/src/nvtt/QuickCompressDXT.h delete mode 100644 Externals/NVTT/src/nvtt/SingleColorLookup.h delete mode 100644 Externals/NVTT/src/nvtt/cuda/Bitmaps.h delete mode 100644 Externals/NVTT/src/nvtt/cuda/CompressKernel.cu delete mode 100644 Externals/NVTT/src/nvtt/cuda/ConvolveKernel.cu delete mode 100644 Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.cpp delete mode 100644 Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.h delete mode 100644 Externals/NVTT/src/nvtt/cuda/CudaMath.h delete mode 100644 Externals/NVTT/src/nvtt/cuda/CudaUtils.cpp delete mode 100644 Externals/NVTT/src/nvtt/cuda/CudaUtils.h delete mode 100644 Externals/NVTT/src/nvtt/nvtt.cpp delete mode 100644 Externals/NVTT/src/nvtt/nvtt.h delete mode 100644 Externals/NVTT/src/nvtt/nvtt_wrapper.cpp delete mode 100644 Externals/NVTT/src/nvtt/nvtt_wrapper.h delete mode 100644 Externals/NVTT/src/nvtt/squish/CMakeLists.txt delete mode 100644 Externals/NVTT/src/nvtt/squish/ChangeLog delete mode 100644 Externals/NVTT/src/nvtt/squish/Doxyfile delete mode 100644 Externals/NVTT/src/nvtt/squish/Makefile delete mode 100644 Externals/NVTT/src/nvtt/squish/README delete mode 100644 Externals/NVTT/src/nvtt/squish/alpha.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/alpha.h delete mode 100644 Externals/NVTT/src/nvtt/squish/clusterfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/clusterfit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/colourblock.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/colourblock.h delete mode 100644 Externals/NVTT/src/nvtt/squish/colourfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/colourfit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/colourset.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/colourset.h delete mode 100644 Externals/NVTT/src/nvtt/squish/config delete mode 100644 Externals/NVTT/src/nvtt/squish/config.h delete mode 100644 Externals/NVTT/src/nvtt/squish/extra/squishgen.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/extra/squishpng.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/extra/squishtest.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/fastclusterfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/fastclusterfit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/fastclusterlookup.inl delete mode 100644 Externals/NVTT/src/nvtt/squish/maths.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/maths.h delete mode 100644 Externals/NVTT/src/nvtt/squish/rangefit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/rangefit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/simd.h delete mode 100644 Externals/NVTT/src/nvtt/squish/simd_3dnow.h delete mode 100644 Externals/NVTT/src/nvtt/squish/simd_sse.h delete mode 100644 Externals/NVTT/src/nvtt/squish/simd_ve.h delete mode 100644 Externals/NVTT/src/nvtt/squish/singlechannelfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/singlechannelfit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/singlecolourfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/singlecolourfit.h delete mode 100644 Externals/NVTT/src/nvtt/squish/singlecolourlookup.inl delete mode 100644 Externals/NVTT/src/nvtt/squish/squish.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/squish.h delete mode 100644 Externals/NVTT/src/nvtt/squish/squish.xcodeproj/project.pbxproj delete mode 100644 Externals/NVTT/src/nvtt/squish/texture_compression_s3tc.txt delete mode 100644 Externals/NVTT/src/nvtt/squish/weightedclusterfit.cpp delete mode 100644 Externals/NVTT/src/nvtt/squish/weightedclusterfit.h delete mode 100644 Externals/NVTT/src/nvtt/tests/ctest.c delete mode 100644 Externals/NVTT/src/nvtt/tests/filtertest.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/assemble.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/benchmark.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/cmdline.h delete mode 100644 Externals/NVTT/src/nvtt/tools/compress.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/configdialog.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/configdialog.h delete mode 100644 Externals/NVTT/src/nvtt/tools/configdialog.ui delete mode 100644 Externals/NVTT/src/nvtt/tools/ddsinfo.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/decompress.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/imgdiff.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/main.cpp delete mode 100644 Externals/NVTT/src/nvtt/tools/resize.cpp delete mode 100644 sdk/binaries/x64/FreeImage.dll delete mode 100644 sdk/binaries/x64/FreeImagePlus.dll delete mode 100644 sdk/binaries/x86/FreeImage.dll delete mode 100644 sdk/binaries/x86/FreeImagePlus.dll delete mode 100644 sdk/include/FreeImage.h delete mode 100644 sdk/include/FreeImagePlus.h delete mode 100644 sdk/include/hxgrid/Interface/IAgent.h delete mode 100644 sdk/include/hxgrid/Interface/IGenericStream.h delete mode 100644 sdk/include/hxgrid/Interface/IGridUser.h delete mode 100644 sdk/include/hxgrid/Interface/I_Agent.pas delete mode 100644 sdk/include/hxgrid/Interface/I_GenericStream.pas delete mode 100644 sdk/include/hxgrid/Interface/I_GridUser.pas delete mode 100644 sdk/include/hxgrid/Interface/InOut.h delete mode 100644 sdk/include/hxgrid/Interface/Singleton.h delete mode 100644 sdk/include/hxgrid/Interface/VECOM.h delete mode 100644 sdk/include/hxgrid/Interface/hxGridInterface.cpp delete mode 100644 sdk/include/hxgrid/Interface/hxGridInterface.h delete mode 100644 sdk/include/hxgrid/Interface/hxplatform.h delete mode 100644 sdk/libraries/x64/FreeImage.lib delete mode 100644 sdk/libraries/x64/FreeImagePlus.lib delete mode 100644 sdk/libraries/x86/FreeImage.lib delete mode 100644 sdk/libraries/x86/FreeImagePlus.lib delete mode 100644 src/utils/ETools/ArbitraryList.h delete mode 100644 src/utils/ETools/BinaryHeap.h delete mode 100644 src/utils/ETools/DLink.h delete mode 100644 src/utils/ETools/ETools.cpp delete mode 100644 src/utils/ETools/ETools.h delete mode 100644 src/utils/ETools/ETools.vcxproj delete mode 100644 src/utils/ETools/ETools.vcxproj.filters delete mode 100644 src/utils/ETools/PropSlimTools.cpp delete mode 100644 src/utils/ETools/PropSlimTools.h delete mode 100644 src/utils/ETools/StdAfx.cpp delete mode 100644 src/utils/ETools/StdAfx.h delete mode 100644 src/utils/ETools/mesh.h delete mode 100644 src/utils/ETools/object.cpp delete mode 100644 src/utils/ETools/object.h delete mode 100644 src/utils/ETools/object_sliding.cpp delete mode 100644 src/utils/ETools/object_sliding.h delete mode 100644 src/utils/ETools/packages.config delete mode 100644 src/utils/ETools/quad.h delete mode 100644 src/utils/Shader_xrLC.h delete mode 100644 src/utils/communicate.h delete mode 100644 src/utils/xrAI/ESceneAIMapTools.cpp delete mode 100644 src/utils/xrAI/ESceneAIMapTools.h delete mode 100644 src/utils/xrAI/ESceneAIMapTools_Export.cpp delete mode 100644 src/utils/xrAI/ESceneAIMapTools_Export.h delete mode 100644 src/utils/xrAI/ESceneClassList.h delete mode 100644 src/utils/xrAI/ESceneCustomMTools.cpp delete mode 100644 src/utils/xrAI/ESceneCustomMTools.h delete mode 100644 src/utils/xrAI/StdAfx.cpp delete mode 100644 src/utils/xrAI/StdAfx.h delete mode 100644 src/utils/xrAI/compiler.cpp delete mode 100644 src/utils/xrAI/compiler.h delete mode 100644 src/utils/xrAI/compiler_cover.cpp delete mode 100644 src/utils/xrAI/compiler_load.cpp delete mode 100644 src/utils/xrAI/compiler_save.cpp delete mode 100644 src/utils/xrAI/factory_api.h delete mode 100644 src/utils/xrAI/game_graph_builder.cpp delete mode 100644 src/utils/xrAI/game_graph_builder.h delete mode 100644 src/utils/xrAI/game_graph_builder_inline.h delete mode 100644 src/utils/xrAI/game_spawn_constructor.cpp delete mode 100644 src/utils/xrAI/game_spawn_constructor.h delete mode 100644 src/utils/xrAI/game_spawn_constructor_inline.h delete mode 100644 src/utils/xrAI/guid_generator.cpp delete mode 100644 src/utils/xrAI/guid_generator.h delete mode 100644 src/utils/xrAI/level_spawn_constructor.cpp delete mode 100644 src/utils/xrAI/level_spawn_constructor.h delete mode 100644 src/utils/xrAI/level_spawn_constructor_inline.h delete mode 100644 src/utils/xrAI/packages.config delete mode 100644 src/utils/xrAI/resource.h delete mode 100644 src/utils/xrAI/resource.rc delete mode 100644 src/utils/xrAI/server_entity_wrapper.cpp delete mode 100644 src/utils/xrAI/server_entity_wrapper.h delete mode 100644 src/utils/xrAI/server_entity_wrapper_inline.h delete mode 100644 src/utils/xrAI/space_restrictor_wrapper.cpp delete mode 100644 src/utils/xrAI/space_restrictor_wrapper.h delete mode 100644 src/utils/xrAI/space_restrictor_wrapper_inline.h delete mode 100644 src/utils/xrAI/spawn_constructor_space.h delete mode 100644 src/utils/xrAI/verify_level_graph.cpp delete mode 100644 src/utils/xrAI/xrAI.cpp delete mode 100644 src/utils/xrAI/xrAI.h delete mode 100644 src/utils/xrAI/xrAI.vcxproj delete mode 100644 src/utils/xrAI/xrAI.vcxproj.filters delete mode 100644 src/utils/xrAI/xrAI_Readme.txt delete mode 100644 src/utils/xrAI/xr_graph_merge.cpp delete mode 100644 src/utils/xrAI/xr_graph_merge.h delete mode 100644 src/utils/xrDO_Light/StdAfx.cpp delete mode 100644 src/utils/xrDO_Light/StdAfx.h delete mode 100644 src/utils/xrDO_Light/packages.config delete mode 100644 src/utils/xrDO_Light/xrDO_Light.cpp delete mode 100644 src/utils/xrDO_Light/xrDO_Light.vcxproj delete mode 100644 src/utils/xrDO_Light/xrDO_Light.vcxproj.filters delete mode 100644 src/utils/xrDXT/DXT.cpp delete mode 100644 src/utils/xrDXT/DXT.vcxproj delete mode 100644 src/utils/xrDXT/DXT.vcxproj.filters delete mode 100644 src/utils/xrDXT/Image_DXTC.cpp delete mode 100644 src/utils/xrDXT/Image_DXTC.h delete mode 100644 src/utils/xrDXT/NVI_Convolution.cpp delete mode 100644 src/utils/xrDXT/NVI_Convolution.h delete mode 100644 src/utils/xrDXT/NVI_Image.cpp delete mode 100644 src/utils/xrDXT/NVI_Image.h delete mode 100644 src/utils/xrDXT/NV_Common.h delete mode 100644 src/utils/xrDXT/NormalMapGen.cpp delete mode 100644 src/utils/xrDXT/StdAfx.cpp delete mode 100644 src/utils/xrDXT/StdAfx.h delete mode 100644 src/utils/xrDXT/dds.h delete mode 100644 src/utils/xrDXT/dds/ConvertColor.h delete mode 100644 src/utils/xrDXT/dds/ddsTypes.h delete mode 100644 src/utils/xrDXT/dds/nvErrorCodes.h delete mode 100644 src/utils/xrDXT/dds/tPixel.h delete mode 100644 src/utils/xrDXT/dds/tVector.h delete mode 100644 src/utils/xrLC/ArbitraryList.h delete mode 100644 src/utils/xrLC/Build.cpp delete mode 100644 src/utils/xrLC/Build.h delete mode 100644 src/utils/xrLC/Build_Load.cpp delete mode 100644 src/utils/xrLC/ELight_def.h delete mode 100644 src/utils/xrLC/MeshMenderLayerOGF.h delete mode 100644 src/utils/xrLC/MeshMenderLayerOrdinaryStatic.h delete mode 100644 src/utils/xrLC/NvMender2002/NVMeshMender.cpp delete mode 100644 src/utils/xrLC/NvMender2002/NVMeshMender.h delete mode 100644 src/utils/xrLC/NvMender2002/nv_algebra.cpp delete mode 100644 src/utils/xrLC/NvMender2002/nv_algebra.h delete mode 100644 src/utils/xrLC/NvMender2002/nv_math.h delete mode 100644 src/utils/xrLC/NvMender2002/nv_mathdecl.h delete mode 100644 src/utils/xrLC/NvMeshMenderLayer.h delete mode 100644 src/utils/xrLC/NvMeshMenderLayerInline.h delete mode 100644 src/utils/xrLC/OGF_CalculateTB.cpp delete mode 100644 src/utils/xrLC/OGF_Face.cpp delete mode 100644 src/utils/xrLC/OGF_Face.h delete mode 100644 src/utils/xrLC/OGF_Face_Save.cpp delete mode 100644 src/utils/xrLC/OGF_Face_Sphere.cpp delete mode 100644 src/utils/xrLC/OGF_Face_Stripify.cpp delete mode 100644 src/utils/xrLC/OGF_RemoveIsolatedVerts.cpp delete mode 100644 src/utils/xrLC/Sector.cpp delete mode 100644 src/utils/xrLC/Sector.h delete mode 100644 src/utils/xrLC/StdAfx.cpp delete mode 100644 src/utils/xrLC/StdAfx.h delete mode 100644 src/utils/xrLC/_rect.h delete mode 100644 src/utils/xrLC/b_globals.h delete mode 100644 src/utils/xrLC/fmesh.cpp delete mode 100644 src/utils/xrLC/net.cpp delete mode 100644 src/utils/xrLC/net.h delete mode 100644 src/utils/xrLC/nv_library/NvTriStrip.cpp delete mode 100644 src/utils/xrLC/nv_library/NvTriStrip.h delete mode 100644 src/utils/xrLC/nv_library/NvTriStripObjects.cpp delete mode 100644 src/utils/xrLC/nv_library/NvTriStripObjects.h delete mode 100644 src/utils/xrLC/nv_library/VertexCache.cpp delete mode 100644 src/utils/xrLC/nv_library/VertexCache.h delete mode 100644 src/utils/xrLC/packages.config delete mode 100644 src/utils/xrLC/std_classes.h delete mode 100644 src/utils/xrLC/vbm.h delete mode 100644 src/utils/xrLC/xrBuildCForm.cpp delete mode 100644 src/utils/xrLC/xrBuildRapidModel.cpp delete mode 100644 src/utils/xrLC/xrCalcNormals.cpp delete mode 100644 src/utils/xrLC/xrFlex2OGF.cpp delete mode 100644 src/utils/xrLC/xrGameMaterials.h delete mode 100644 src/utils/xrLC/xrLC.cpp delete mode 100644 src/utils/xrLC/xrLC.vcxproj delete mode 100644 src/utils/xrLC/xrLC.vcxproj.filters delete mode 100644 src/utils/xrLC/xrLight.cpp delete mode 100644 src/utils/xrLC/xrMU_Model_Calc_ogf.cpp delete mode 100644 src/utils/xrLC/xrMU_Model_export_OGF.cpp delete mode 100644 src/utils/xrLC/xrMU_Model_export_geometry.cpp delete mode 100644 src/utils/xrLC/xrOptimizeCFORM_qslim.cpp delete mode 100644 src/utils/xrLC/xrPhase_AdaptiveHT.cpp delete mode 100644 src/utils/xrLC/xrPhase_AdaptiveHT_qslim.cpp delete mode 100644 src/utils/xrLC/xrPhase_GI.cpp delete mode 100644 src/utils/xrLC/xrPhase_MergeGeometry.cpp delete mode 100644 src/utils/xrLC/xrPhase_MergeLM.cpp delete mode 100644 src/utils/xrLC/xrPhase_MergeLM_Rect.h delete mode 100644 src/utils/xrLC/xrPhase_MergeLM_Surface.cpp delete mode 100644 src/utils/xrLC/xrPhase_ResolveMaterials.cpp delete mode 100644 src/utils/xrLC/xrPhase_Subdivide.cpp delete mode 100644 src/utils/xrLC/xrPhase_TangentBasis.cpp delete mode 100644 src/utils/xrLC/xrPhase_UVmap.cpp delete mode 100644 src/utils/xrLC/xrPreOptimize.cpp delete mode 100644 src/utils/xrLC/xrSaveLights.cpp delete mode 100644 src/utils/xrLC/xrSaveOGF.cpp delete mode 100644 src/utils/xrLC/xrSectors.cpp delete mode 100644 src/utils/xrLC/xrT_Junction.cpp delete mode 100644 src/utils/xrLCUtil/CMakeLists.txt delete mode 100644 src/utils/xrLCUtil/ILevelCompilerLogger.hpp delete mode 100644 src/utils/xrLCUtil/LevelCompilerLoggerWindow.cpp delete mode 100644 src/utils/xrLCUtil/LevelCompilerLoggerWindow.hpp delete mode 100644 src/utils/xrLCUtil/packages.config delete mode 100644 src/utils/xrLCUtil/pch.cpp delete mode 100644 src/utils/xrLCUtil/pch.hpp delete mode 100644 src/utils/xrLCUtil/resource.h delete mode 100644 src/utils/xrLCUtil/resource.rc delete mode 100644 src/utils/xrLCUtil/xrLCUtil.cpp delete mode 100644 src/utils/xrLCUtil/xrLCUtil.hpp delete mode 100644 src/utils/xrLCUtil/xrLCUtil.vcxproj delete mode 100644 src/utils/xrLCUtil/xrLCUtil.vcxproj.filters delete mode 100644 src/utils/xrLCUtil/xrThread.cpp delete mode 100644 src/utils/xrLCUtil/xrThread.hpp delete mode 100644 src/utils/xrLC_Light/CMakeLists.txt delete mode 100644 src/utils/xrLC_Light/ETextureParams.cpp delete mode 100644 src/utils/xrLC_Light/ETextureParams.h delete mode 100644 src/utils/xrLC_Light/LightThread.cpp delete mode 100644 src/utils/xrLC_Light/LightThread.h delete mode 100644 src/utils/xrLC_Light/Lightmap.cpp delete mode 100644 src/utils/xrLC_Light/Lightmap.h delete mode 100644 src/utils/xrLC_Light/MeshStaic.cpp delete mode 100644 src/utils/xrLC_Light/MeshStructure.h delete mode 100644 src/utils/xrLC_Light/ReadMe.txt delete mode 100644 src/utils/xrLC_Light/b_build_texture.cpp delete mode 100644 src/utils/xrLC_Light/b_build_texture.h delete mode 100644 src/utils/xrLC_Light/base_basis.cpp delete mode 100644 src/utils/xrLC_Light/base_basis.h delete mode 100644 src/utils/xrLC_Light/base_color.cpp delete mode 100644 src/utils/xrLC_Light/base_color.h delete mode 100644 src/utils/xrLC_Light/base_face.cpp delete mode 100644 src/utils/xrLC_Light/base_face.h delete mode 100644 src/utils/xrLC_Light/base_face_ptr_storage.h delete mode 100644 src/utils/xrLC_Light/base_lighting.cpp delete mode 100644 src/utils/xrLC_Light/base_lighting.h delete mode 100644 src/utils/xrLC_Light/calculate_normals.h delete mode 100644 src/utils/xrLC_Light/compiler.cpp delete mode 100644 src/utils/xrLC_Light/detail_net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/detail_net_global_data.h delete mode 100644 src/utils/xrLC_Light/detail_slot_calculate.cpp delete mode 100644 src/utils/xrLC_Light/detail_slot_calculate.h delete mode 100644 src/utils/xrLC_Light/execute_statistics.cpp delete mode 100644 src/utils/xrLC_Light/execute_statistics.h delete mode 100644 src/utils/xrLC_Light/file_compress.cpp delete mode 100644 src/utils/xrLC_Light/file_compress.h delete mode 100644 src/utils/xrLC_Light/fitter.cpp delete mode 100644 src/utils/xrLC_Light/fitter.h delete mode 100644 src/utils/xrLC_Light/gl_base_cl_data.cpp delete mode 100644 src/utils/xrLC_Light/gl_base_cl_data.h delete mode 100644 src/utils/xrLC_Light/global_calculation_data.cpp delete mode 100644 src/utils/xrLC_Light/global_calculation_data.h delete mode 100644 src/utils/xrLC_Light/global_slots_data.cpp delete mode 100644 src/utils/xrLC_Light/global_slots_data.h delete mode 100644 src/utils/xrLC_Light/hash2D.h delete mode 100644 src/utils/xrLC_Light/implicit_net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/implicit_net_global_data.h delete mode 100644 src/utils/xrLC_Light/itterate_adjacents.h delete mode 100644 src/utils/xrLC_Light/itterate_adjacents_static.h delete mode 100644 src/utils/xrLC_Light/lc_net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/lc_net_global_data.h delete mode 100644 src/utils/xrLC_Light/lcnet_execution_tasks_add.h delete mode 100644 src/utils/xrLC_Light/lcnet_task_manager.cpp delete mode 100644 src/utils/xrLC_Light/lcnet_task_manager.h delete mode 100644 src/utils/xrLC_Light/lcnet_task_menager_run_task.cpp delete mode 100644 src/utils/xrLC_Light/light_execute.cpp delete mode 100644 src/utils/xrLC_Light/light_execute.h delete mode 100644 src/utils/xrLC_Light/light_point.h delete mode 100644 src/utils/xrLC_Light/lightstab_interface.h delete mode 100644 src/utils/xrLC_Light/lm_layer.cpp delete mode 100644 src/utils/xrLC_Light/lm_layer.h delete mode 100644 src/utils/xrLC_Light/lm_net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/lm_net_global_data.h delete mode 100644 src/utils/xrLC_Light/mu_light_net.cpp delete mode 100644 src/utils/xrLC_Light/mu_light_net.h delete mode 100644 src/utils/xrLC_Light/mu_model_face.cpp delete mode 100644 src/utils/xrLC_Light/mu_model_face.h delete mode 100644 src/utils/xrLC_Light/mu_model_face_defs.h delete mode 100644 src/utils/xrLC_Light/mu_model_light.cpp delete mode 100644 src/utils/xrLC_Light/mu_model_light.h delete mode 100644 src/utils/xrLC_Light/mu_model_light_threads.cpp delete mode 100644 src/utils/xrLC_Light/mu_model_light_threads.h delete mode 100644 src/utils/xrLC_Light/net_all_executions.h delete mode 100644 src/utils/xrLC_Light/net_all_globals.h delete mode 100644 src/utils/xrLC_Light/net_cl_data_prepare.cpp delete mode 100644 src/utils/xrLC_Light/net_cl_data_prepare.h delete mode 100644 src/utils/xrLC_Light/net_exec_pool.cpp delete mode 100644 src/utils/xrLC_Light/net_exec_pool.h delete mode 100644 src/utils/xrLC_Light/net_execution.cpp delete mode 100644 src/utils/xrLC_Light/net_execution.h delete mode 100644 src/utils/xrLC_Light/net_execution_detail_light.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_detail_light.h delete mode 100644 src/utils/xrLC_Light/net_execution_factory.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_factory.h delete mode 100644 src/utils/xrLC_Light/net_execution_factory_register.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_globals.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_globals.h delete mode 100644 src/utils/xrLC_Light/net_execution_implicit_light.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_implicit_light.h delete mode 100644 src/utils/xrLC_Light/net_execution_lightmaps.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_lightmaps.h delete mode 100644 src/utils/xrLC_Light/net_execution_mu_base.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_mu_base.h delete mode 100644 src/utils/xrLC_Light/net_execution_mu_ref.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_mu_ref.h delete mode 100644 src/utils/xrLC_Light/net_execution_vertex_light.cpp delete mode 100644 src/utils/xrLC_Light/net_execution_vertex_light.h delete mode 100644 src/utils/xrLC_Light/net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/net_global_data.h delete mode 100644 src/utils/xrLC_Light/net_global_data_cleanup.cpp delete mode 100644 src/utils/xrLC_Light/net_global_data_cleanup.h delete mode 100644 src/utils/xrLC_Light/net_light.cpp delete mode 100644 src/utils/xrLC_Light/net_light.h delete mode 100644 src/utils/xrLC_Light/net_light_task.cpp delete mode 100644 src/utils/xrLC_Light/net_light_task.h delete mode 100644 src/utils/xrLC_Light/net_lightmaps_add_task.cpp delete mode 100644 src/utils/xrLC_Light/net_stream.cpp delete mode 100644 src/utils/xrLC_Light/net_stream.h delete mode 100644 src/utils/xrLC_Light/net_task.cpp delete mode 100644 src/utils/xrLC_Light/net_task.h delete mode 100644 src/utils/xrLC_Light/net_task_callback.cpp delete mode 100644 src/utils/xrLC_Light/net_task_callback.h delete mode 100644 src/utils/xrLC_Light/net_task_manager.cpp delete mode 100644 src/utils/xrLC_Light/net_task_manager.h delete mode 100644 src/utils/xrLC_Light/net_task_menager.cpp delete mode 100644 src/utils/xrLC_Light/net_task_menager.h delete mode 100644 src/utils/xrLC_Light/packages.config delete mode 100644 src/utils/xrLC_Light/recalculation.cpp delete mode 100644 src/utils/xrLC_Light/recalculation.h delete mode 100644 src/utils/xrLC_Light/ref_model_net_global_data.cpp delete mode 100644 src/utils/xrLC_Light/ref_model_net_global_data.h delete mode 100644 src/utils/xrLC_Light/serialize.cpp delete mode 100644 src/utils/xrLC_Light/serialize.h delete mode 100644 src/utils/xrLC_Light/stdafx.cpp delete mode 100644 src/utils/xrLC_Light/stdafx.h delete mode 100644 src/utils/xrLC_Light/tcf.cpp delete mode 100644 src/utils/xrLC_Light/tcf.h delete mode 100644 src/utils/xrLC_Light/uv_tri.cpp delete mode 100644 src/utils/xrLC_Light/uv_tri.h delete mode 100644 src/utils/xrLC_Light/vector_clear.h delete mode 100644 src/utils/xrLC_Light/xrDXTC.h delete mode 100644 src/utils/xrLC_Light/xrDeflectoL_Direct.cpp delete mode 100644 src/utils/xrLC_Light/xrDeflector.cpp delete mode 100644 src/utils/xrLC_Light/xrDeflector.h delete mode 100644 src/utils/xrLC_Light/xrDeflectorDefs.h delete mode 100644 src/utils/xrLC_Light/xrDeflectorLight.cpp delete mode 100644 src/utils/xrLC_Light/xrFace.cpp delete mode 100644 src/utils/xrLC_Light/xrFace.h delete mode 100644 src/utils/xrLC_Light/xrFaceDefs.h delete mode 100644 src/utils/xrLC_Light/xrFaceInline.h delete mode 100644 src/utils/xrLC_Light/xrImage_Filter.cpp delete mode 100644 src/utils/xrLC_Light/xrImage_Filter.h delete mode 100644 src/utils/xrLC_Light/xrImage_Resampler.cpp delete mode 100644 src/utils/xrLC_Light/xrImage_Resampler.h delete mode 100644 src/utils/xrLC_Light/xrIsect.h delete mode 100644 src/utils/xrLC_Light/xrLC_GlobalData.cpp delete mode 100644 src/utils/xrLC_Light/xrLC_GlobalData.h delete mode 100644 src/utils/xrLC_Light/xrLC_Light.cpp delete mode 100644 src/utils/xrLC_Light/xrLC_Light.h delete mode 100644 src/utils/xrLC_Light/xrLC_Light.vcxproj delete mode 100644 src/utils/xrLC_Light/xrLC_Light.vcxproj.filters delete mode 100644 src/utils/xrLC_Light/xrLightDoNet.cpp delete mode 100644 src/utils/xrLC_Light/xrLightDoNet.h delete mode 100644 src/utils/xrLC_Light/xrLightVertex.cpp delete mode 100644 src/utils/xrLC_Light/xrLightVertex.h delete mode 100644 src/utils/xrLC_Light/xrLightVertexNet.cpp delete mode 100644 src/utils/xrLC_Light/xrLight_ImlicitNet.cpp delete mode 100644 src/utils/xrLC_Light/xrLight_Implicit.cpp delete mode 100644 src/utils/xrLC_Light/xrLight_Implicit.h delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.cpp delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.h delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitDeflector.cpp delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitDeflector.h delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitRun.h delete mode 100644 src/utils/xrLC_Light/xrLight_ImplicitThread.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model.h delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Calc_faceopacity.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Calc_lighting.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Calc_materials.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Calc_normals.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Load.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Reference.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Reference.h delete mode 100644 src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp delete mode 100644 src/utils/xrLC_Light/xrMU_Model_export_cform_rcast.cpp delete mode 100644 src/utils/xrLC_Light/xrUVpoint.h delete mode 100644 src/utils/xrLC_LightStab/packages.config delete mode 100644 src/utils/xrLC_LightStab/xrLC_LightStab.cpp delete mode 100644 src/utils/xrLC_LightStab/xrLC_LightStab.h delete mode 100644 src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj delete mode 100644 src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj.filters delete mode 100644 src/utils/xrQSlim/CMakeLists.txt delete mode 100644 src/utils/xrQSlim/MxBlock.h delete mode 100644 src/utils/xrQSlim/MxBlock2.h delete mode 100644 src/utils/xrQSlim/MxBlockModel.cpp delete mode 100644 src/utils/xrQSlim/MxBlockModel.h delete mode 100644 src/utils/xrQSlim/MxDefines.h delete mode 100644 src/utils/xrQSlim/MxDynBlock.h delete mode 100644 src/utils/xrQSlim/MxGeoPrims.h delete mode 100644 src/utils/xrQSlim/MxGeom3D.cpp delete mode 100644 src/utils/xrQSlim/MxGeom3D.h delete mode 100644 src/utils/xrQSlim/MxHeap.cpp delete mode 100644 src/utils/xrQSlim/MxHeap.h delete mode 100644 src/utils/xrQSlim/MxMat2.h delete mode 100644 src/utils/xrQSlim/MxMat3-jacobi.cpp delete mode 100644 src/utils/xrQSlim/MxMat3.h delete mode 100644 src/utils/xrQSlim/MxMat4-jacobi.cpp delete mode 100644 src/utils/xrQSlim/MxMat4.h delete mode 100644 src/utils/xrQSlim/MxMatrix.cpp delete mode 100644 src/utils/xrQSlim/MxMatrix.h delete mode 100644 src/utils/xrQSlim/MxPropSlim.cpp delete mode 100644 src/utils/xrQSlim/MxPropSlim.h delete mode 100644 src/utils/xrQSlim/MxQMetric.cpp delete mode 100644 src/utils/xrQSlim/MxQMetric.h delete mode 100644 src/utils/xrQSlim/MxQMetric3.cpp delete mode 100644 src/utils/xrQSlim/MxQMetric3.h delete mode 100644 src/utils/xrQSlim/MxQSlim.cpp delete mode 100644 src/utils/xrQSlim/MxQSlim.h delete mode 100644 src/utils/xrQSlim/MxStdModel.cpp delete mode 100644 src/utils/xrQSlim/MxStdModel.h delete mode 100644 src/utils/xrQSlim/MxStdSlim.cpp delete mode 100644 src/utils/xrQSlim/MxStdSlim.h delete mode 100644 src/utils/xrQSlim/MxVec3.h delete mode 100644 src/utils/xrQSlim/MxVec4.h delete mode 100644 src/utils/xrQSlim/MxVector.h delete mode 100644 src/utils/xrQSlim/geom3d.h delete mode 100644 src/utils/xrQSlim/mat2.cpp delete mode 100644 src/utils/xrQSlim/mat2.h delete mode 100644 src/utils/xrQSlim/mat3.cpp delete mode 100644 src/utils/xrQSlim/mat3.h delete mode 100644 src/utils/xrQSlim/mat4.cpp delete mode 100644 src/utils/xrQSlim/mat4.h delete mode 100644 src/utils/xrQSlim/mixmops.cpp delete mode 100644 src/utils/xrQSlim/mixmops.h delete mode 100644 src/utils/xrQSlim/mixvops.h delete mode 100644 src/utils/xrQSlim/stdafx.h delete mode 100644 src/utils/xrQSlim/vec2.h delete mode 100644 src/utils/xrQSlim/vec3.h delete mode 100644 src/utils/xrQSlim/vec4.h delete mode 100644 src/utils/xrQSlim/xrQSlim.vcxproj delete mode 100644 src/utils/xrQSlim/xrQSlim.vcxproj.filters diff --git a/.gitmodules b/.gitmodules index d653b46d1ba..68228e269d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,9 +31,6 @@ [submodule "Externals/OpenAutomate"] path = Externals/OpenAutomate url = https://github.com/OpenXRay/OpenAutomate.git -[submodule "Externals/FreeMagic"] - path = Externals/FreeMagic - url = https://github.com/OpenXRay/FreeMagic.git [submodule "Externals/gli"] path = Externals/gli url = https://github.com/g-truc/gli.git diff --git a/Externals/CMakeLists.txt b/Externals/CMakeLists.txt index 6ee73375534..a634c9b4c70 100644 --- a/Externals/CMakeLists.txt +++ b/Externals/CMakeLists.txt @@ -14,7 +14,6 @@ endif() add_subdirectory(GameSpy) add_subdirectory(OPCODE) add_subdirectory(ode) -#add_subdirectory(NVTT) add_subdirectory(imgui-proj) if (NOT TARGET xrLuabind) diff --git a/Externals/FreeMagic b/Externals/FreeMagic deleted file mode 160000 index ba39f90bef4..00000000000 --- a/Externals/FreeMagic +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ba39f90bef46fd79166ccdb661e902f45d48560e diff --git a/Externals/NVTT/CMakeLists.txt b/Externals/NVTT/CMakeLists.txt deleted file mode 100644 index b704148eae8..00000000000 --- a/Externals/NVTT/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -project(nvtt) - -add_subdirectory(src/nvcore) -add_subdirectory(src/nvimage) -add_subdirectory(src/nvmath) -add_subdirectory(src/nvtt) diff --git a/Externals/NVTT/NVTT.vcxproj b/Externals/NVTT/NVTT.vcxproj deleted file mode 100644 index 20abf0ecf75..00000000000 --- a/Externals/NVTT/NVTT.vcxproj +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473} - nvtt - - - - - - - StaticLibrary - false - - - - - - - - - - - $(ProjectDir)include;$(ProjectDir)src;$(ProjectDir)src\nvcore;$(ProjectDir)src\nvtt\squish;%(AdditionalIncludeDirectories) - NVTT_EXPORTS;%(PreprocessorDefinitions) - NotUsing - TurnOffAllWarnings - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Externals/NVTT/NVTT.vcxproj.filters b/Externals/NVTT/NVTT.vcxproj.filters deleted file mode 100644 index 113763dfc40..00000000000 --- a/Externals/NVTT/NVTT.vcxproj.filters +++ /dev/null @@ -1,425 +0,0 @@ - - - - - {9c8d4fcf-1a0f-4176-9174-17216abeeffe} - - - {e7a9d246-050a-495e-85fe-8159f6514eff} - - - - - include - - - include - - - include - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - - - src - - - \ No newline at end of file diff --git a/Externals/NVTT/NVTT/NVTT.log b/Externals/NVTT/NVTT/NVTT.log deleted file mode 100644 index dc849e4f89c..00000000000 --- a/Externals/NVTT/NVTT/NVTT.log +++ /dev/null @@ -1,25 +0,0 @@ -Build started 9/24/2014 2:10:23 PM. - 1>Project "E:\git\xray-16\src\3rd party\NVTT\NVTT.vcxproj" on node 2 (Build target(s)). - 1>Building with tools version "12.0". - Project file contains ToolsVersion="4.0". This toolset may be unknown or missing, in which case you may be able to resolve this by installing the appropriate version of MSBuild, or the build may have been forced to a particular ToolsVersion for policy reasons. Treating the project as if it had ToolsVersion="12.0". For more information, please see http://go.microsoft.com/fwlink/?LinkId=293424. - 1>Target "_CheckForInvalidConfigurationAndPlatform" in file "C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets" from project "E:\git\xray-16\src\3rd party\NVTT\NVTT.vcxproj" (entry point): - Using "Error" task from assembly "Microsoft.Build.Tasks.v12.0, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". - Task "Error" - 1>C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(617,5): error : The OutputPath property is not set for project 'NVTT.vcxproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Debug' Platform='Win32'. This error may also appear if some other project is trying to follow a project-to-project reference to this project, this project has been unloaded or is not included in the solution, and the referencing project does not build using the same or an equivalent Configuration or Platform. - Done executing task "Error" -- FAILED. - 1>Done building target "_CheckForInvalidConfigurationAndPlatform" in project "NVTT.vcxproj" -- FAILED. - 1>Done Building Project "E:\git\xray-16\src\3rd party\NVTT\NVTT.vcxproj" (Build target(s)) -- FAILED. - -Project Performance Summary: - 23 ms E:\git\xray-16\src\3rd party\NVTT\NVTT.vcxproj 1 calls - 23 ms Build 1 calls - -Target Performance Summary: - 23 ms _CheckForInvalidConfigurationAndPlatform 1 calls - -Task Performance Summary: - 20 ms Error 1 calls - -Build FAILED. - -Time Elapsed 00:00:00.01 diff --git a/Externals/NVTT/include/nvconfig.h b/Externals/NVTT/include/nvconfig.h deleted file mode 100644 index 31338fb4b1e..00000000000 --- a/Externals/NVTT/include/nvconfig.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NV_CONFIG -#define NV_CONFIG - -//#cmakedefine HAVE_UNISTD_H -#define HAVE_STDARG_H -//#cmakedefine HAVE_SIGNAL_H -//#cmakedefine HAVE_EXECINFO_H -#define HAVE_MALLOC_H - -#if !defined(_M_X64) -//#define HAVE_PNG -//#define HAVE_JPEG -//#define HAVE_TIFF -#endif - -#endif // NV_CONFIG diff --git a/Externals/NVTT/include/nvtt/nvtt.h b/Externals/NVTT/include/nvtt/nvtt.h deleted file mode 100644 index 6ce6deb90de..00000000000 --- a/Externals/NVTT/include/nvtt/nvtt.h +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_H -#define NV_TT_H - -// Function linkage -#if NVTT_SHARED - -#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__ -# ifdef NVTT_EXPORTS -# define NVTT_API __declspec(dllexport) -# else -# define NVTT_API __declspec(dllimport) -# endif -#endif - -#if defined __GNUC__ >= 4 -# ifdef NVTT_EXPORTS -# define NVTT_API __attribute__((visibility("default"))) -# endif -#endif - -#endif // NVTT_SHARED - -#if !defined NVTT_API -# define NVTT_API -#endif - -#define NVTT_VERSION 200 - -#define NVTT_DECLARE_PIMPL(Class) \ - private: \ - Class(const Class &); \ - void operator=(const Class &); \ - public: \ - struct Private; \ - Private & m - - -// Public interface. -namespace nvtt -{ - /// Supported compression formats. - enum Format - { - // No compression. - Format_RGB, - Format_RGBA = Format_RGB, - - // DX9 formats. - Format_DXT1, - Format_DXT1a, // DXT1 with binary alpha. - Format_DXT3, - Format_DXT5, - Format_DXT5n, // Compressed HILO: R=1, G=y, B=0, A=x - - // DX10 formats. - Format_BC1 = Format_DXT1, - Format_BC1a = Format_DXT1a, - Format_BC2 = Format_DXT3, - Format_BC3 = Format_DXT5, - Format_BC3n = Format_DXT5n, - Format_BC4, // ATI1 - Format_BC5, // 3DC, ATI2 - }; - - /// Quality modes. - enum Quality - { - Quality_Fastest, - Quality_Normal, - Quality_Production, - Quality_Highest, - }; - - /// Compression options. This class describes the desired compression format and other compression settings. - struct CompressionOptions - { - NVTT_DECLARE_PIMPL(CompressionOptions); - - NVTT_API CompressionOptions(); - NVTT_API ~CompressionOptions(); - - NVTT_API void reset(); - - NVTT_API void setFormat(Format format); - NVTT_API void setQuality(Quality quality); - NVTT_API void setColorWeights(float red, float green, float blue, float alpha = 1.0f); - - NVTT_API void setExternalCompressor(const char * name); - - // Set color mask to describe the RGB/RGBA format. - NVTT_API void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); - - NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127); - }; - - - /// Wrap modes. - enum WrapMode - { - WrapMode_Clamp, - WrapMode_Repeat, - WrapMode_Mirror, - }; - - /// Texture types. - enum TextureType - { - TextureType_2D, - TextureType_Cube, - // TextureType_3D, - }; - - /// Input formats. - enum InputFormat - { - InputFormat_BGRA_8UB, - // InputFormat_RGBE_8UB, - // InputFormat_BGRA_32F, - }; - - /// Mipmap downsampling filters. - enum MipmapFilter - { - MipmapFilter_Box, ///< Box filter is quite good and very fast. - MipmapFilter_Triangle, ///< Triangle filter blurs the results too much, but that might be what you want. - MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter. - }; - - /// Color transformation. - enum ColorTransform - { - ColorTransform_None, - ColorTransform_Linear, - }; - - /// Extents rounding mode. - enum RoundMode - { - RoundMode_None, - RoundMode_ToNextPowerOfTwo, - RoundMode_ToNearestPowerOfTwo, - RoundMode_ToPreviousPowerOfTwo, - }; - - /// Alpha mode. - enum AlphaMode - { - AlphaMode_None, - AlphaMode_Transparency, - AlphaMode_Premultiplied, - }; - - /// Input options. Specify format and layout of the input texture. - struct InputOptions - { - NVTT_DECLARE_PIMPL(InputOptions); - - NVTT_API InputOptions(); - NVTT_API ~InputOptions(); - - // Set default options. - NVTT_API void reset(); - - // Setup input layout. - NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1); - NVTT_API void resetTextureLayout(); - - // Set mipmap data. Copies the data. - NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0); - - // Describe the format of the input. - NVTT_API void setFormat(InputFormat format); - - // Set the way the input alpha channel is interpreted. - NVTT_API void setAlphaMode(AlphaMode alphaMode); - - // Set gamma settings. - NVTT_API void setGamma(float inputGamma, float outputGamma); - - // Set texture wrappign mode. - NVTT_API void setWrapMode(WrapMode mode); - - // Set mipmapping options. - NVTT_API void setMipmapFilter(MipmapFilter filter); - NVTT_API void setMipmapGeneration(bool enabled, int maxLevel = -1); - NVTT_API void setKaiserParameters(float width, float alpha, float stretch); - - // Set normal map options. - NVTT_API void setNormalMap(bool b); - NVTT_API void setConvertToNormalMap(bool convert); - NVTT_API void setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale); - NVTT_API void setNormalFilter(float sm, float medium, float big, float large); - NVTT_API void setNormalizeMipmaps(bool b); - - // Set color transforms. @@ Not implemented! - NVTT_API void setColorTransform(ColorTransform t); - NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3); - - // Set resizing options. - NVTT_API void setMaxExtents(int d); - NVTT_API void setRoundMode(RoundMode mode); - }; - - - /// Output handler. - struct OutputHandler - { - virtual ~OutputHandler() {} - - /// Indicate the start of a new compressed image that's part of the final texture. - virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) = 0; - - /// Output data. Compressed data is output as soon as it's generated to minimize memory allocations. - virtual bool writeData(const void * data, int size) = 0; - }; - - /// Error codes. - enum Error - { - Error_Unknown, - Error_InvalidInput, - Error_UnsupportedFeature, - Error_CudaError, - Error_FileOpen, - Error_FileWrite, - }; - - /// Error handler. - struct ErrorHandler - { - virtual ~ErrorHandler() {} - - // Signal error. - virtual void error(Error e) = 0; - }; - - - /// Output Options. This class holds pointers to the interfaces that are used to report the output of - /// the compressor to the user. - struct OutputOptions - { - NVTT_DECLARE_PIMPL(OutputOptions); - - NVTT_API OutputOptions(); - NVTT_API ~OutputOptions(); - - // Set default options. - NVTT_API void reset(); - - NVTT_API void setFileName(const char * fileName); - - NVTT_API void setOutputHandler(OutputHandler * outputHandler); - NVTT_API void setErrorHandler(ErrorHandler * errorHandler); - NVTT_API void setOutputHeader(bool outputHeader); - }; - - - /// Texture compressor. - struct Compressor - { - NVTT_DECLARE_PIMPL(Compressor); - - NVTT_API Compressor(); - NVTT_API ~Compressor(); - - NVTT_API void enableCudaAcceleration(bool enable); - NVTT_API bool isCudaAccelerationEnabled() const; - - // Main entrypoint of the compression library. - NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; - - // Estimate the size of compressing the input with the given options. - NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const; - }; - - - // Return string for the given error code. - NVTT_API const char * errorString(Error e); - - // Return NVTT version. - NVTT_API unsigned int version(); - -} // nvtt namespace - -#endif // NV_TT_H diff --git a/Externals/NVTT/include/nvtt/nvtt_wrapper.h b/Externals/NVTT/include/nvtt/nvtt_wrapper.h deleted file mode 100644 index b8407e22470..00000000000 --- a/Externals/NVTT/include/nvtt/nvtt_wrapper.h +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NVTT_WRAPPER_H -#define NVTT_WRAPPER_H - -// Function linkage -#if NVTT_SHARED - -#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__ -# ifdef NVTT_EXPORTS -# define NVTT_API __declspec(dllexport) -# else -# define NVTT_API __declspec(dllimport) -# endif -#endif - -#if defined __GNUC__ >= 4 -# ifdef NVTT_EXPORTS -# define NVTT_API __attribute__((visibility("default"))) -# endif -#endif - -#endif // NVTT_SHARED - -#if !defined NVTT_API -# define NVTT_API -#endif - -#define NVTT_VERSION 200 - -#ifdef __cplusplus -typedef struct nvtt::InputOptions NvttInputOptions; -typedef struct nvtt::CompressionOptions NvttCompressionOptions; -typedef struct nvtt::OutputOptions NvttOutputOptions; -typedef struct nvtt::Compressor NvttCompressor; -#else -typedef struct NvttInputOptions NvttInputOptions; -typedef struct NvttCompressionOptions NvttCompressionOptions; -typedef struct NvttOutputOptions NvttOutputOptions; -typedef struct NvttCompressor NvttCompressor; -#endif - -/// Supported compression formats. -typedef enum -{ - // No compression. - NVTT_Format_RGB, - NVTT_Format_RGBA = NVTT_Format_RGB, - - // DX9 formats. - NVTT_Format_DXT1, - NVTT_Format_DXT1a, - NVTT_Format_DXT3, - NVTT_Format_DXT5, - NVTT_Format_DXT5n, - - // DX10 formats. - NVTT_Format_BC1 = NVTT_Format_DXT1, - NVTT_Format_BC1a = NVTT_Format_DXT1a, - NVTT_Format_BC2 = NVTT_Format_DXT3, - NVTT_Format_BC3 = NVTT_Format_DXT5, - NVTT_Format_BC3n = NVTT_Format_DXT5n, - NVTT_Format_BC4, - NVTT_Format_BC5, -} NvttFormat; - -/// Quality modes. -typedef enum -{ - NVTT_Quality_Fastest, - NVTT_Quality_Normal, - NVTT_Quality_Production, - NVTT_Quality_Highest, -} NvttQuality; - -/// Wrap modes. -typedef enum -{ - NVTT_WrapMode_Clamp, - NVTT_WrapMode_Repeat, - NVTT_WrapMode_Mirror, -} NvttWrapMode; - -/// Texture types. -typedef enum -{ - NVTT_TextureType_2D, - NVTT_TextureType_Cube, -} NvttTextureType; - -/// Input formats. -typedef enum -{ - NVTT_InputFormat_BGRA_8UB, -} NvttInputFormat; - -/// Mipmap downsampling filters. -typedef enum -{ - NVTT_MipmapFilter_Box, - NVTT_MipmapFilter_Triangle, - NVTT_MipmapFilter_Kaiser, -} NvttMipmapFilter; - -/// Color transformation. -typedef enum -{ - NVTT_ColorTransform_None, - NVTT_ColorTransform_Linear, -} NvttColorTransform; - -/// Extents rounding mode. -typedef enum -{ - NVTT_RoundMode_None, - NVTT_RoundMode_ToNextPowerOfTwo, - NVTT_RoundMode_ToNearestPowerOfTwo, - NVTT_RoundMode_ToPreviousPowerOfTwo, -} NvttRoundMode; - -/// Alpha mode. -typedef enum -{ - NVTT_AlphaMode_None, - NVTT_AlphaMode_Transparency, - NVTT_AlphaMode_Premultiplied, -} NvttAlphaMode; - -typedef enum -{ - NVTT_Error_InvalidInput, - NVTT_Error_UserInterruption, - NVTT_Error_UnsupportedFeature, - NVTT_Error_CudaError, - NVTT_Error_Unknown, - NVTT_Error_FileOpen, - NVTT_Error_FileWrite, -} NvttError; - -typedef enum -{ - NVTT_False, - NVTT_True, -} NvttBoolean; - - -#ifdef __cplusplus -extern "C" { -#endif - -// Callbacks -//typedef void (* nvttErrorHandler)(NvttError e); -//typedef void (* nvttOutputHandler)(const void * data, int size); -//typedef void (* nvttImageHandler)(int size, int width, int height, int depth, int face, int miplevel); - - -// InputOptions class. -NVTT_API NvttInputOptions * nvttCreateInputOptions(); -NVTT_API void nvttDestroyInputOptions(NvttInputOptions * inputOptions); - -NVTT_API void nvttSetInputOptionsTextureLayout(NvttInputOptions * inputOptions, NvttTextureType type, int w, int h, int d); -NVTT_API void nvttResetInputOptionsTextureLayout(NvttInputOptions * inputOptions); -NVTT_API NvttBoolean nvttSetInputOptionsMipmapData(NvttInputOptions * inputOptions, const void * data, int w, int h, int d, int face, int mipmap); -NVTT_API void nvttSetInputOptionsFormat(NvttInputOptions * inputOptions, NvttInputFormat format); -NVTT_API void nvttSetInputOptionsAlphaMode(NvttInputOptions * inputOptions, NvttAlphaMode alphaMode); -NVTT_API void nvttSetInputOptionsGamma(NvttInputOptions * inputOptions, float inputGamma, float outputGamma); -NVTT_API void nvttSetInputOptionsWrapMode(NvttInputOptions * inputOptions, NvttWrapMode mode); -NVTT_API void nvttSetInputOptionsMipmapFilter(NvttInputOptions * inputOptions, NvttMipmapFilter filter); -NVTT_API void nvttSetInputOptionsMipmapGeneration(NvttInputOptions * inputOptions, NvttBoolean enabled, int maxLevel); -NVTT_API void nvttSetInputOptionsKaiserParameters(NvttInputOptions * inputOptions, float width, float alpha, float stretch); -NVTT_API void nvttSetInputOptionsNormalMap(NvttInputOptions * inputOptions, NvttBoolean b); -NVTT_API void nvttSetInputOptionsConvertToNormalMap(NvttInputOptions * inputOptions, NvttBoolean convert); -NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale); -NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large); -NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b); -NVTT_API void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t); -NVTT_API void nvttSetInputOptionsLinearTransform(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3); -NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim); -NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode); - - -// CompressionOptions class. -NVTT_API NvttCompressionOptions * nvttCreateCompressionOptions(); -NVTT_API void nvttDestroyCompressionOptions(NvttCompressionOptions * compressionOptions); - -NVTT_API void nvttSetCompressionOptionsFormat(NvttCompressionOptions * compressionOptions, NvttFormat format); -NVTT_API void nvttSetCompressionOptionsQuality(NvttCompressionOptions * compressionOptions, NvttQuality quality); -NVTT_API void nvttSetCompressionOptionsColorWeights(NvttCompressionOptions * compressionOptions, float red, float green, float blue, float alpha); -NVTT_API void nvttSetCompressionOptionsPixelFormat(NvttCompressionOptions * compressionOptions, unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); -NVTT_API void nvttSetCompressionOptionsQuantization(NvttCompressionOptions * compressionOptions, NvttBoolean colorDithering, NvttBoolean alphaDithering, NvttBoolean binaryAlpha, int alphaThreshold); - - -// OutputOptions class. -NVTT_API NvttOutputOptions * nvttCreateOutputOptions(); -NVTT_API void nvttDestroyOutputOptions(NvttOutputOptions * outputOptions); - -NVTT_API void nvttSetOutputOptionsFileName(NvttOutputOptions * outputOptions, const char * fileName); -NVTT_API void nvttSetOutputOptionsOutputHeader(NvttOutputOptions * outputOptions, NvttBoolean b); -//NVTT_API void nvttSetOutputOptionsErrorHandler(NvttOutputOptions * outputOptions, nvttErrorHandler errorHandler); -//NVTT_API void nvttSetOutputOptionsOutputHandler(NvttOutputOptions * outputOptions, nvttOutputHandler outputHandler, nvttImageHandler imageHandler); - - -// Compressor class. -NVTT_API NvttCompressor * nvttCreateCompressor(); -NVTT_API void nvttDestroyCompressor(NvttCompressor * compressor); - -NVTT_API NvttBoolean nvttCompress(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions, const NvttOutputOptions * outputOptions); -NVTT_API int nvttEstimateSize(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions); - - -// Global functions. -NVTT_API const char * nvttErrorString(NvttError e); -NVTT_API unsigned int nvttVersion(); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // NVTT_WRAPPER_H diff --git a/Externals/NVTT/src/nvcore/BitArray.h b/Externals/NVTT/src/nvcore/BitArray.h deleted file mode 100644 index 01ab141f2c9..00000000000 --- a/Externals/NVTT/src/nvcore/BitArray.h +++ /dev/null @@ -1,168 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_BITARRAY_H -#define NV_CORE_BITARRAY_H - -#include -#include - -namespace nv -{ - -/// Count the bits of @a x. -inline uint bitsSet(uint8 x) { - uint count = 0; - for(; x != 0; x >>= 1) { - count += (x & 1); - } - return count; -} - - -/// Count the bits of @a x. -inline uint bitsSet(uint32 x, int bits) { - uint count = 0; - for(; x != 0 && bits != 0; x >>= 1, bits--) { - count += (x & 1); - } - return count; -} - - -/// Simple bit array. -class BitArray -{ -public: - - /// Default ctor. - BitArray() {} - - /// Ctor with initial m_size. - BitArray(uint sz) - { - resize(sz); - } - - /// Get array m_size. - uint size() const { return m_size; } - - /// Clear array m_size. - void clear() { resize(0); } - - /// Set array m_size. - void resize(uint sz) - { - m_size = sz; - m_bitArray.resize( (m_size + 7) >> 3 ); - } - - /// Get bit. - bool bitAt(uint b) const - { - nvDebugCheck( b < m_size ); - return (m_bitArray[b >> 3] & (1 << (b & 7))) != 0; - } - - /// Set a bit. - void setBitAt(uint b) - { - nvDebugCheck( b < m_size ); - m_bitArray[b >> 3] |= (1 << (b & 7)); - } - - /// Clear a bit. - void clearBitAt( uint b ) - { - nvDebugCheck( b < m_size ); - m_bitArray[b >> 3] &= ~(1 << (b & 7)); - } - - /// Clear all the bits. - void clearAll() - { - memset(m_bitArray.unsecureBuffer(), 0, m_bitArray.size()); - } - - /// Set all the bits. - void setAll() - { - memset(m_bitArray.unsecureBuffer(), 0xFF, m_bitArray.size()); - } - - /// Toggle all the bits. - void toggleAll() - { - const uint byte_num = m_bitArray.size(); - for(uint b = 0; b < byte_num; b++) { - m_bitArray[b] ^= 0xFF; - } - } - - /// Get a byte of the bit array. - const uint8 & byteAt(uint index) const - { - return m_bitArray[index]; - } - - /// Set the given byte of the byte array. - void setByteAt(uint index, uint8 b) - { - m_bitArray[index] = b; - } - - /// Count the number of bits set. - uint countSetBits() const - { - const uint num = m_bitArray.size(); - if( num == 0 ) { - return 0; - } - - uint count = 0; - for(uint i = 0; i < num - 1; i++) { - count += bitsSet(m_bitArray[i]); - } - count += bitsSet(m_bitArray[num-1], m_size & 0x7); - - //piDebugCheck(count + countClearBits() == m_size); - return count; - } - - /// Count the number of bits clear. - uint countClearBits() const { - - const uint num = m_bitArray.size(); - if( num == 0 ) { - return 0; - } - - uint count = 0; - for(uint i = 0; i < num - 1; i++) { - count += bitsSet(~m_bitArray[i]); - } - count += bitsSet(~m_bitArray[num-1], m_size & 0x7); - - //piDebugCheck(count + countSetBits() == m_size); - return count; - } - - friend void swap(BitArray & a, BitArray & b) - { - swap(a.m_size, b.m_size); - swap(a.m_bitArray, b.m_bitArray); - } - - -private: - - /// Number of bits stored. - uint m_size; - - /// Array of bits. - Array m_bitArray; - -}; - -} // nv namespace - -#endif // _PI_CORE_BITARRAY_H_ diff --git a/Externals/NVTT/src/nvcore/CMakeLists.txt b/Externals/NVTT/src/nvcore/CMakeLists.txt deleted file mode 100644 index e54b6d10ef5..00000000000 --- a/Externals/NVTT/src/nvcore/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -option(NVCORE_SHARED "Build nvcore as shared library" OFF) - -add_subdirectory(poshlib) - -if (NVCORE_SHARED) - add_library(nvcore SHARED) - - target_compile_definitions(nvcore - PRIVATE - NVCORE_SHARED - ) -else() - add_library(nvcore STATIC) -endif() - -target_sources(nvcore - PRIVATE - nvcore.h - Ptr.h - BitArray.h - Memory.h - Memory.cpp - Debug.h - Debug.cpp - Containers.h - StrLib.h - StrLib.cpp - Stream.h - StdStream.h - TextReader.h - TextReader.cpp - TextWriter.h - TextWriter.cpp - Radix.h - Radix.cpp - Library.h - Library.cpp -) - -target_include_directories(nvcore - PUBLIC - "${CMAKE_SOURCE_DIR}/Externals/NVTT/src" - "${CMAKE_SOURCE_DIR}/Externals/NVTT/include" -) - -target_compile_definitions(nvcore - PRIVATE - NVCORE_EXPORTS - HAVE_EXECINFO_H - HAVE_SIGNAL_H -) - -set_target_properties(nvcore PROPERTIES - POSITION_INDEPENDENT_CODE ON -) - -install(TARGETS nvcore LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/Externals/NVTT/src/nvcore/Containers.h b/Externals/NVTT/src/nvcore/Containers.h deleted file mode 100644 index 88ac5efc40e..00000000000 --- a/Externals/NVTT/src/nvcore/Containers.h +++ /dev/null @@ -1,1059 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_CONTAINER_H -#define NV_CORE_CONTAINER_H - -/* -These containers are based on Thatcher Ulrich containers, -donated to the Public Domain. - -I've also borrowed some ideas from the Qt toolkit, specially the cool -foreach iterator. - -TODO -Do not use memmove in insert & remove, use copy ctors instead. -*/ - - -// nvcore -#include -#include -#include - -#include // memmove -#include // for placement new - - -#if NV_CC_GNUC // If typeof is available: - -#define NV_FOREACH(i, container) \ - typedef typeof(container) NV_STRING_JOIN2(cont,__LINE__); \ - for(NV_STRING_JOIN2(cont,__LINE__)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i)) -/* -#define NV_FOREACH(i, container) \ - for(typename typeof(container)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i)) -*/ - -#else // If typeof not available: - -struct PseudoIndexWrapper { - template - PseudoIndexWrapper(const T & container) { - nvStaticCheck(sizeof(typename T::PseudoIndex) <= sizeof(memory)); - new (memory) typename T::PseudoIndex(container.start()); - } - // PseudoIndex cannot have a dtor! - - template typename T::PseudoIndex & operator()(const T * container) { - return *reinterpret_cast(memory); - } - template const typename T::PseudoIndex & operator()(const T * container) const { - return *reinterpret_cast(memory); - } - - uint8 memory[4]; // Increase the size if we have bigger enumerators. -}; - -#define NV_FOREACH(i, container) \ - for(PseudoIndexWrapper i(container); !(container).isDone(i(&(container))); (container).advance(i(&(container)))) - -#endif - -// Declare foreach keyword. -#if !defined NV_NO_USE_KEYWORDS -# define foreach NV_FOREACH -#endif - - - -namespace nv -{ - // Templates - - /// Return the maximum of two values. - template - inline const T & max(const T & a, const T & b) - { - //return std::max(a, b); - if( a < b ) { - return b; - } - return a; - } - - /// Return the minimum of two values. - template - inline const T & min(const T & a, const T & b) - { - //return std::min(a, b); - if( b < a ) { - return b; - } - return a; - } - - /// Clamp between two values. - template - inline const T & clamp(const T & x, const T & a, const T & b) - { - return min(max(x, a), b); - } - - /// Swap two values. - template - inline void swap(T & a, T & b) - { - //return std::swap(a, b); - T temp = a; - a = b; - b = temp; - } - - template struct hash - { - inline uint sdbm_hash(const void * data_in, uint size, uint h = 5381) - { - const uint8 * data = (const uint8 *) data_in; - uint i = 0; - while (i < size) { - h = (h << 16) + (h << 6) - h + (uint) data[i++]; - } - return h; - } - - uint operator()(const Key & k) { - return sdbm_hash(&k, sizeof(Key)); - } - }; - template <> struct hash - { - uint operator()(int x) const { return x; } - }; - template <> struct hash - { - uint operator()(uint x) const { return x; } - }; - - /// Delete all the elements of a container. - template - void deleteAll(T & container) - { - for(typename T::PseudoIndex i = container.start(); !container.isDone(i); container.advance(i)) - { - delete container[i]; - } - } - - - /** Return the next power of two. - * @see http://graphics.stanford.edu/~seander/bithacks.html - * @warning Behaviour for 0 is undefined. - * @note isPowerOfTwo(x) == true -> nextPowerOfTwo(x) == x - * @note nextPowerOfTwo(x) = 2 << log2(x-1) - */ - inline uint nextPowerOfTwo( uint x ) - { - nvDebugCheck( x != 0 ); - #if 1 // On modern CPUs this is as fast as using the bsr instruction. - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return x+1; - #else - uint p = 1; - while( x > p ) { - p += p; - } - return p; - #endif - } - - /// Return true if @a n is a power of two. - inline bool isPowerOfTwo( uint n ) - { - return (n & (n-1)) == 0; - } - - /// Simple iterator interface. - template - struct Iterator - { - virtual void advance(); - virtual bool isDone(); - virtual T current(); - }; - - - /** - * Replacement for std::vector that is easier to debug and provides - * some nice foreach enumerators. - */ - template - class NVCORE_CLASS Array { - public: - - /// Ctor. - Array() : m_buffer(NULL), m_size(0), m_buffer_size(0) - { - } - - /// Copy ctor. - Array( const Array & a ) : m_buffer(NULL), m_size(0), m_buffer_size(0) - { - copy(a.m_buffer, a.m_size); - } - - /// Ctor that initializes the vector with the given elements. - Array( const T * ptr, int num ) : m_buffer(NULL), m_size(0), m_buffer_size(0) - { - copy(ptr, num); - } - - /// Allocate array. - explicit Array(uint capacity) : m_buffer(NULL), m_size(0), m_buffer_size(0) - { - allocate(capacity); - } - - - /// Dtor. - ~Array() - { - clear(); - allocate(0); - } - - - /// Const and save vector access. - const T & operator[]( uint index ) const - { - nvDebugCheck(index < m_size); - return m_buffer[index]; - } - - /// Safe vector access. - T & operator[] ( uint index ) - { - nvDebugCheck(index < m_size); - return m_buffer[index]; - } - - - /// Get vector size. - uint size() const { return m_size; } - - /// Get vector size. - uint count() const { return m_size; } - - /// Get const vector pointer. - const T * buffer() const { return m_buffer; } - - /// Get vector pointer. - T * unsecureBuffer() { return m_buffer; } - - /// Is vector empty. - bool isEmpty() const { return m_size == 0; } - - /// Is a null vector. - bool isNull() const { return m_buffer == NULL; } - - - /// Push an element at the end of the vector. - void push_back( const T & val ) - { - uint new_size = m_size + 1; - - if (new_size > m_buffer_size) - { - const T copy(val); // create a copy in case value is inside of this array. - resize(new_size); - m_buffer[new_size-1] = copy; - } - else - { - m_size = new_size; - new(m_buffer+new_size-1) T(val); - } - } - void pushBack( const T & val ) - { - push_back(val); - } - void append( const T & val ) - { - push_back(val); - } - - /// Qt like push operator. - Array & operator<< ( T & t ) - { - push_back(t); - return *this; - } - - /// Pop and return element at the end of the vector. - void pop_back() - { - nvDebugCheck( m_size > 0 ); - resize( m_size - 1 ); - } - void popBack() - { - pop_back(); - } - - /// Get back element. - const T & back() const - { - nvDebugCheck( m_size > 0 ); - return m_buffer[m_size-1]; - } - - /// Get back element. - T & back() - { - nvDebugCheck( m_size > 0 ); - return m_buffer[m_size-1]; - } - - /// Get front element. - const T & front() const - { - nvDebugCheck( m_size > 0 ); - return m_buffer[0]; - } - - /// Get front element. - T & front() - { - nvDebugCheck( m_size > 0 ); - return m_buffer[0]; - } - - /// Check if the given element is contained in the array. - bool contains(const T & e) const - { - for (uint i = 0; i < m_size; i++) { - if (m_buffer[i] == e) return true; - } - return false; - } - - /// Remove the element at the given index. This is an expensive operation! - void removeAt( uint index ) - { - nvCheck(index < m_size); - - if( m_size == 1 ) { - clear(); - } - else { - m_buffer[index].~T(); - - memmove( m_buffer+index, m_buffer+index+1, sizeof(T) * (m_size - 1 - index) ); - m_size--; - } - } - - /// Remove the first instance of the given element. - void remove(const T & element) - { - for(PseudoIndex i = start(); !isDone(i); advance(i)) { - removeAt(i); - break; - } - } - - /// Insert the given element at the given index shifting all the elements up. - void insertAt( uint index, const T & val = T() ) - { - nvCheck( index <= m_size ); - - resize( m_size + 1 ); - - if( index < m_size - 1 ) { - memmove( m_buffer+index+1, m_buffer+index, sizeof(T) * (m_size - 1 - index) ); - } - - // Copy-construct into the newly opened slot. - new(m_buffer+index) T(val); - } - - /// Append the given data to our vector. - void append(const Array & other) - { - append(other.m_buffer, other.m_size); - } - - /// Append the given data to our vector. - void append(const T other[], uint count) - { - if( count > 0 ) { - const uint old_size = m_size; - resize(m_size + count); - // Must use operator=() to copy elements, in case of side effects (e.g. ref-counting). - for( uint i = 0; i < count; i++ ) { - m_buffer[old_size + i] = other[i]; - } - } - } - - - /// Remove the given element by replacing it with the last one. - void replaceWithLast(uint index) - { - nvDebugCheck( index < m_size ); - m_buffer[index] = back(); - (m_buffer+m_size-1)->~T(); - m_size--; - } - - - /// Resize the vector preserving existing elements. - void resize(uint new_size) - { - uint i; - uint old_size = m_size; - m_size = new_size; - - // Destruct old elements (if we're shrinking). - for( i = new_size; i < old_size; i++ ) { - (m_buffer+i)->~T(); // Explicit call to the destructor - } - - if( m_size == 0 ) { - //Allocate(0); // Don't shrink automatically. - } - else if( m_size <= m_buffer_size/* && m_size > m_buffer_size >> 1*/) { - // don't compact yet. - nvDebugCheck(m_buffer != NULL); - } - else { - uint new_buffer_size; - if( m_buffer_size == 0 ) { - // first allocation - new_buffer_size = m_size; - } - else { - // growing - new_buffer_size = m_size + (m_size >> 2); - } - allocate( new_buffer_size ); - } - - // Call default constructors - for( i = old_size; i < new_size; i++ ) { - new(m_buffer+i) T; // placement new - } - } - - - /// Resize the vector preserving existing elements and initializing the - /// new ones with the given value. - void resize( uint new_size, const T &elem ) - { - uint i; - uint old_size = m_size; - m_size = new_size; - - // Destruct old elements (if we're shrinking). - for( i = new_size; i < old_size; i++ ) { - (m_buffer+i)->~T(); // Explicit call to the destructor - } - - if( m_size == 0 ) { - //Allocate(0); // Don't shrink automatically. - } - else if( m_size <= m_buffer_size && m_size > m_buffer_size >> 1 ) { - // don't compact yet. - } - else { - uint new_buffer_size; - if( m_buffer_size == 0 ) { - // first allocation - new_buffer_size = m_size; - } - else { - // growing - new_buffer_size = m_size + (m_size >> 2); - } - allocate( new_buffer_size ); - } - - // Call copy constructors - for( i = old_size; i < new_size; i++ ) { - new(m_buffer+i) T( elem ); // placement new - } - } - - /// Tighten the memory used by the container. - void tighten() - { - // TODO Reallocate only if worth. - } - - /// Clear the buffer. - void clear() - { - resize(0); - } - - /// Shrink the allocated vector. - void shrink() - { - if( m_size < m_buffer_size ) { - allocate(m_size); - } - } - - /// Preallocate space. - void reserve(uint desired_size) - { - if( desired_size > m_buffer_size ) { - allocate( desired_size ); - } - } - - /// Copy memory to our vector. Resizes the vector if needed. - void copy( const T * ptr, uint num ) - { - resize( num ); - for(uint i = 0; i < m_size; i++) { - m_buffer[i] = ptr[i]; - } - } - - /// Assignment operator. - void operator=( const Array & a ) - { - copy( a.m_buffer, a.m_size ); - } - - /* - /// Array serialization. - friend Stream & operator<< ( Stream & s, Array & p ) - { - if( s.isLoading() ) { - uint size; - s << size; - p.resize( size ); - } - else { - s << p.m_size; - } - - for( uint i = 0; i < p.m_size; i++ ) { - s << p.m_buffer[i]; - } - - return s; - } - */ - - // Array enumerator. - typedef uint PseudoIndex; - - PseudoIndex start() const { return 0; } - bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); return i == this->m_size; }; - void advance(PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); i++; } - - #if NV_CC_MSVC - T & operator[]( const PseudoIndexWrapper & i ) { - return m_buffer[i(this)]; - } - const T & operator[]( const PseudoIndexWrapper & i ) const { - return m_buffer[i(this)]; - } - #endif - - - /// Swap the members of this vector and the given vector. - friend void swap(Array & a, Array & b) - { - swap(a.m_buffer, b.m_buffer); - swap(a.m_size, b.m_size); - swap(a.m_buffer_size, b.m_buffer_size); - } - - - private: - - /// Change buffer size. - void allocate( uint rsize ) - { - m_buffer_size = rsize; - - // free the buffer. - if( m_buffer_size == 0 ) { - if( m_buffer ) { - mem::free( m_buffer ); - m_buffer = NULL; - } - } - - // realloc the buffer - else { - if( m_buffer ) m_buffer = (T *) mem::realloc( m_buffer, sizeof(T) * m_buffer_size ); - else m_buffer = (T *) mem::malloc( sizeof(T) * m_buffer_size ); - } - } - - - private: - T * m_buffer; - uint m_size; - uint m_buffer_size; - }; - - - - /** Thatcher Ulrich's hash table. - * - * Hash table, linear probing, internal chaining. One - * interesting/nice thing about this implementation is that the table - * itself is a flat chunk of memory containing no pointers, only - * relative indices. If the key and value types of the hash contain - * no pointers, then the hash can be serialized using raw IO. Could - * come in handy. - * - * Never shrinks, unless you explicitly clear() it. Expands on - * demand, though. For best results, if you know roughly how big your - * table will be, default it to that size when you create it. - */ - template > - class NVCORE_CLASS HashMap - { - NV_FORBID_COPY(HashMap) - public: - - /// Default ctor. - HashMap() : entry_count(0), size_mask(-1), table(NULL) { } - - /// Ctor with size hint. - explicit HashMap(int size_hint) : entry_count(0), size_mask(-1), table(NULL) { setCapacity(size_hint); } - - /// Dtor. - ~HashMap() { clear(); } - - - /// Set a new or existing value under the key, to the value. - void set(const T& key, const U& value) - { - int index = findIndex(key); - if (index >= 0) - { - E(index).value = value; - return; - } - - // Entry under key doesn't exist. - add(key, value); - } - - - /// Add a new value to the hash table, under the specified key. - void add(const T& key, const U& value) - { - nvCheck(findIndex(key) == -1); - - checkExpand(); - nvCheck(table != NULL); - entry_count++; - - const uint hash_value = hash_functor()(key); - const int index = hash_value & size_mask; - - Entry * natural_entry = &(E(index)); - - if (natural_entry->isEmpty()) - { - // Put the new entry in. - new (natural_entry) Entry(key, value, -1, hash_value); - } - else - { - // Find a blank spot. - int blank_index = index; - for (;;) - { - blank_index = (blank_index + 1) & size_mask; - if (E(blank_index).isEmpty()) break; // found it - } - Entry * blank_entry = &E(blank_index); - - if (int(natural_entry->hash_value & size_mask) == index) - { - // Collision. Link into this chain. - - // Move existing list head. - new (blank_entry) Entry(*natural_entry); // placement new, copy ctor - - // Put the new info in the natural entry. - natural_entry->key = key; - natural_entry->value = value; - natural_entry->next_in_chain = blank_index; - natural_entry->hash_value = hash_value; - } - else - { - // Existing entry does not naturally - // belong in this slot. Existing - // entry must be moved. - - // Find natural location of collided element (i.e. root of chain) - int collided_index = natural_entry->hash_value & size_mask; - for (;;) - { - Entry * e = &E(collided_index); - if (e->next_in_chain == index) - { - // Here's where we need to splice. - new (blank_entry) Entry(*natural_entry); - e->next_in_chain = blank_index; - break; - } - collided_index = e->next_in_chain; - nvCheck(collided_index >= 0 && collided_index <= size_mask); - } - - // Put the new data in the natural entry. - natural_entry->key = key; - natural_entry->value = value; - natural_entry->hash_value = hash_value; - natural_entry->next_in_chain = -1; - } - } - } - - - /// Remove the first value under the specified key. - bool remove(const T& key) - { - if (table == NULL) - { - return false; - } - - int index = findIndex(key); - if (index < 0) - { - return false; - } - - Entry * entry = &E(index); - - if( entry->isEndOfChain() ) { - entry->clear(); - } - else { - // Get next entry. - Entry & next_entry = E(entry->next_in_chain); - - // Copy next entry in this place. - new (entry) Entry(next_entry); - - next_entry.clear(); - } - - entry_count--; - - return true; - } - - - /// Remove all entries from the hash table. - void clear() - { - if (table != NULL) - { - // Delete the entries. - for (int i = 0, n = size_mask; i <= n; i++) - { - Entry * e = &E(i); - if (e->isEmpty() == false) - { - e->clear(); - } - } - mem::free(table); - table = NULL; - entry_count = 0; - size_mask = -1; - } - } - - - /// Returns true if the hash is empty. - bool isEmpty() const - { - return table == NULL || entry_count == 0; - } - - - /** Retrieve the value under the given key. - * - * If there's no value under the key, then return false and leave - * *value alone. - * - * If there is a value, return true, and set *value to the entry's - * value. - * - * If value == NULL, return true or false according to the - * presence of the key, but don't touch *value. - */ - bool get(const T& key, U* value = NULL) const - { - int index = findIndex(key); - if (index >= 0) - { - if (value) { - *value = E(index).value; // take care with side-effects! - } - return true; - } - return false; - } - - /// Determine if the given key is contained in the hash. - bool contains(const T & key) const - { - return get(key); - } - - /// Number of entries in the hash. - int size() const - { - return entry_count; - } - - /// Number of entries in the hash. - int count() const - { - return size(); - } - - - /** - * Resize the hash table to fit one more entry. Often this - * doesn't involve any action. - */ - void checkExpand() - { - if (table == NULL) { - // Initial creation of table. Make a minimum-sized table. - setRawCapacity(16); - } - else if (entry_count * 3 > (size_mask + 1) * 2) { - // Table is more than 2/3rds full. Expand. - setRawCapacity(entry_count * 2); - } - } - - - /// Hint the bucket count to >= n. - void resize(int n) - { - // Not really sure what this means in relation to - // STLport's hash_map... they say they "increase the - // bucket count to at least n" -- but does that mean - // their real capacity after resize(n) is more like - // n*2 (since they do linked-list chaining within - // buckets?). - setCapacity(n); - } - - /** - * Size the hash so that it can comfortably contain the given - * number of elements. If the hash already contains more - * elements than new_size, then this may be a no-op. - */ - void setCapacity(int new_size) - { - int new_raw_size = (new_size * 3) / 2; - if (new_raw_size < size()) { return; } - - setRawCapacity(new_raw_size); - } - - /// Behaves much like std::pair. - struct Entry - { - int next_in_chain; // internal chaining for collisions - uint hash_value; // avoids recomputing. Worthwhile? - T key; - U value; - - Entry() : next_in_chain(-2) {} - Entry(const Entry& e) - : next_in_chain(e.next_in_chain), hash_value(e.hash_value), key(e.key), value(e.value) - { - } - Entry(const T& k, const U& v, int next, int hash) - : next_in_chain(next), hash_value(hash), key(k), value(v) - { - } - bool isEmpty() const { return next_in_chain == -2; } - bool isEndOfChain() const { return next_in_chain == -1; } - - void clear() - { - key.~T(); // placement delete - value.~U(); // placement delete - next_in_chain = -2; - } - }; - - - // HashMap enumerator. - typedef int PseudoIndex; - PseudoIndex start() const { PseudoIndex i = 0; findNext(i); return i; } - bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= size_mask+1); return i == size_mask+1; }; - void advance(PseudoIndex & i) const { nvDebugCheck(i <= size_mask+1); i++; findNext(i); } - - #if NV_CC_GNUC - Entry & operator[]( const PseudoIndex & i ) { - return E(i); - } - const Entry & operator[]( const PseudoIndex & i ) const { - return E(i); - } - #elif NV_CC_MSVC - Entry & operator[]( const PseudoIndexWrapper & i ) { - return E(i(this)); - } - const Entry & operator[]( const PseudoIndexWrapper & i ) const { - return E(i(this)); - } - #endif - - - - private: - - // Find the index of the matching entry. If no match, then return -1. - int findIndex(const T& key) const - { - if (table == NULL) return -1; - - uint hash_value = hash_functor()(key); - int index = hash_value & size_mask; - - const Entry * e = &E(index); - if (e->isEmpty()) return -1; - if (int(e->hash_value & size_mask) != index) return -1; // occupied by a collider - - for (;;) - { - nvCheck((e->hash_value & size_mask) == (hash_value & size_mask)); - - if (e->hash_value == hash_value && e->key == key) - { - // Found it. - return index; - } - nvDebugCheck(! (e->key == key)); // keys are equal, but hash differs! - - // Keep looking through the chain. - index = e->next_in_chain; - if (index == -1) break; // end of chain - - nvCheck(index >= 0 && index <= size_mask); - e = &E(index); - - nvCheck(e->isEmpty() == false); - } - return -1; - } - - // Helpers. - Entry & E(int index) - { - nvDebugCheck(table != NULL); - nvDebugCheck(index >= 0 && index <= size_mask); - return table[index]; - } - const Entry & E(int index) const - { - nvDebugCheck(table != NULL); - nvDebugCheck(index >= 0 && index <= size_mask); - return table[index]; - } - - - /** - * Resize the hash table to the given size (Rehash the - * contents of the current table). The arg is the number of - * hash table entries, not the number of elements we should - * actually contain (which will be less than this). - */ - void setRawCapacity(int new_size) - { - if (new_size <= 0) { - // Special case. - clear(); - return; - } - - // Force new_size to be a power of two. - new_size = nextPowerOfTwo(new_size); - - HashMap new_hash; - new_hash.table = (Entry *) mem::malloc(sizeof(Entry) * new_size); - nvDebugCheck(new_hash.table != NULL); - - new_hash.entry_count = 0; - new_hash.size_mask = new_size - 1; - for (int i = 0; i < new_size; i++) - { - new_hash.E(i).next_in_chain = -2; // mark empty - } - - // Copy stuff to new_hash - if (table != NULL) - { - for (int i = 0, n = size_mask; i <= n; i++) - { - Entry * e = &E(i); - if (e->isEmpty() == false) - { - // Insert old entry into new hash. - new_hash.add(e->key, e->value); - e->clear(); // placement delete of old element - } - } - - // Delete our old data buffer. - mem::free(table); - } - - // Steal new_hash's data. - entry_count = new_hash.entry_count; - size_mask = new_hash.size_mask; - table = new_hash.table; - new_hash.entry_count = 0; - new_hash.size_mask = -1; - new_hash.table = NULL; - } - - // Move the enumerator to the next valid element. - void findNext(PseudoIndex & i) const { - while (i <= size_mask && E(i).isEmpty()) { - i++; - } - } - - - int entry_count; - int size_mask; - Entry * table; - - }; - - - -} // nv namespace - -#endif // NV_CORE_CONTAINER_H diff --git a/Externals/NVTT/src/nvcore/Debug.cpp b/Externals/NVTT/src/nvcore/Debug.cpp deleted file mode 100644 index 48d16d34bda..00000000000 --- a/Externals/NVTT/src/nvcore/Debug.cpp +++ /dev/null @@ -1,539 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include - -// Extern -#if NV_OS_WIN32 //&& NV_CC_MSVC -# define WIN32_LEAN_AND_MEAN -# define VC_EXTRALEAN -# include -# include -# if NV_CC_MSVC -# include -# if _MSC_VER < 1300 -# define DECLSPEC_DEPRECATED - // VC6: change this path to your Platform SDK headers -# include // must be XP version of file -// include "M:\\dev7\\vs\\devtools\\common\\win32sdk\\include\\dbghelp.h" -# else - // VC7: ships with updated headers -# include -# endif -# endif -#endif - -#if !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) -# include -#endif - -#if NV_OS_LINUX && defined(HAVE_EXECINFO_H) -# include -# include // getpid -# include // backtrace -# if NV_CC_GNUC // defined(HAVE_CXXABI_H) -# include -# endif -#endif - -#if NV_OS_DARWIN -# include // getpid -# include -# include // sysctl -# include -# undef HAVE_EXECINFO_H -# if defined(HAVE_EXECINFO_H) // only after OSX 10.5 -# include // backtrace -# if NV_CC_GNUC // defined(HAVE_CXXABI_H) -# include -# endif -# endif -#endif - -#include // std::runtime_error -#undef assert // defined on mingw - -using namespace nv; - -namespace -{ - - static MessageHandler * s_message_handler = NULL; - static AssertHandler * s_assert_handler = NULL; - - static bool s_sig_handler_enabled = false; - -#if NV_OS_WIN32 && NV_CC_MSVC - - // Old exception filter. - static LPTOP_LEVEL_EXCEPTION_FILTER s_old_exception_filter = NULL; - -#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) - - // Old signal handlers. - struct sigaction s_old_sigsegv; - struct sigaction s_old_sigtrap; - struct sigaction s_old_sigfpe; - struct sigaction s_old_sigbus; - -#endif - - -#if NV_OS_WIN32 && NV_CC_MSVC - - // TODO write minidump - - static LONG WINAPI nvTopLevelFilter( struct _EXCEPTION_POINTERS * pExceptionInfo) - { - NV_UNUSED(pExceptionInfo); - /* BOOL (WINAPI * Dump) (HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION ); - - AutoString dbghelp_path(512); - getcwd(dbghelp_path, 512); - dbghelp_path.Append("\\DbgHelp.dll"); - nvTranslatePath(dbghelp_path); - - PiLibrary DbgHelp_lib(dbghelp_path, true); - - if( !DbgHelp_lib.IsValid() ) { - nvDebug("*** 'DbgHelp.dll' not found.\n"); - return EXCEPTION_CONTINUE_SEARCH; - } - - if( !DbgHelp_lib.BindSymbol( (void **)&Dump, "MiniDumpWriteDump" ) ) { - nvDebug("*** 'DbgHelp.dll' too old.\n"); - return EXCEPTION_CONTINUE_SEARCH; - } - - // create the file - HANDLE hFile = ::CreateFile( "nv.dmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - if( hFile == INVALID_HANDLE_VALUE ) { - nvDebug("*** Failed to create dump file.\n"); - return EXCEPTION_CONTINUE_SEARCH; - } - - - _MINIDUMP_EXCEPTION_INFORMATION ExInfo; - - ExInfo.ThreadId = ::GetCurrentThreadId(); - ExInfo.ExceptionPointers = pExceptionInfo; - ExInfo.ClientPointers = NULL; - - // write the dump - bool ok = Dump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL )!=0; - ::CloseHandle(hFile); - - if( !ok ) { - nvDebug("*** Failed to save dump file.\n"); - return EXCEPTION_CONTINUE_SEARCH; - } - - nvDebug("--- Dump file saved.\n"); - */ - return EXCEPTION_CONTINUE_SEARCH; - } - -#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) // NV_OS_LINUX || NV_OS_DARWIN - -#if defined(HAVE_EXECINFO_H) // NV_OS_LINUX - - static bool nvHasStackTrace() { -#if NV_OS_DARWIN - return backtrace != NULL; -#else - return true; -#endif - } - - static void nvPrintStackTrace(void * trace[], int size, int start=0) { - char ** string_array = backtrace_symbols(trace, size); - - nvDebug( "\nDumping stacktrace:\n" ); - for(int i = start; i < size-1; i++ ) { -# if NV_CC_GNUC // defined(HAVE_CXXABI_H) - char * begin = strchr(string_array[i], '('); - char * end = strchr(string_array[i], '+'); - if( begin != 0 && begin < end ) { - int stat; - *end = '\0'; - *begin = '\0'; - char * module = string_array[i]; - char * name = abi::__cxa_demangle(begin+1, 0, 0, &stat); - if( name == NULL || begin[1] != '_' || begin[2] != 'Z' ) { - nvDebug( " In: [%s] '%s'\n", module, begin+1 ); - } - else { - nvDebug( " In: [%s] '%s'\n", module, name ); - } - free(name); - } - else { - nvDebug( " In: '%s'\n", string_array[i] ); - } -# else - nvDebug( " In: '%s'\n", string_array[i] ); -# endif - } - nvDebug("\n"); - - free(string_array); - } - -#endif // defined(HAVE_EXECINFO_H) - - static void * callerAddress(void * secret) - { -# if NV_OS_DARWIN -# if defined(_STRUCT_MCONTEXT) -# if NV_CPU_PPC - ucontext_t * ucp = (ucontext_t *)secret; - return (void *) ucp->uc_mcontext->__ss.__srr0; -# elif NV_CPU_X86 - ucontext_t * ucp = (ucontext_t *)secret; - return (void *) ucp->uc_mcontext->__ss.__eip; -# endif -# else -# if NV_CPU_PPC - ucontext_t * ucp = (ucontext_t *)secret; - return (void *) ucp->uc_mcontext->ss.srr0; -# elif NV_CPU_X86 - ucontext_t * ucp = (ucontext_t *)secret; - return (void *) ucp->uc_mcontext->ss.eip; -# endif -# endif -# else -# if NV_CPU_X86_64 - // #define REG_RIP REG_INDEX(rip) // seems to be 16 - ucontext_t * ucp = (ucontext_t *)secret; - return (void *)ucp->uc_mcontext.gregs[REG_RIP]; -# elif NV_CPU_X86 - ucontext_t * ucp = (ucontext_t *)secret; - return (void *)ucp->uc_mcontext.gregs[14/*REG_EIP*/]; -# elif NV_CPU_PPC - ucontext_t * ucp = (ucontext_t *)secret; - return (void *) ucp->uc_mcontext.regs->nip; -# endif -# endif - - // How to obtain the instruction pointers in different platforms, from mlton's source code. - // http://mlton.org/ - // OpenBSD && NetBSD - // ucp->sc_eip - // FreeBSD: - // ucp->uc_mcontext.mc_eip - // HPUX: - // ucp->uc_link - // Solaris: - // ucp->uc_mcontext.gregs[REG_PC] - // Linux hppa: - // uc->uc_mcontext.sc_iaoq[0] & ~0x3UL - // Linux sparc: - // ((struct sigcontext*) secret)->sigc_regs.tpc - // Linux sparc64: - // ((struct sigcontext*) secret)->si_regs.pc - - // potentially correct for other archs: - // Linux alpha: ucp->m_context.sc_pc - // Linux arm: ucp->m_context.ctx.arm_pc - // Linux ia64: ucp->m_context.sc_ip & ~0x3UL - // Linux mips: ucp->m_context.sc_pc - // Linux s390: ucp->m_context.sregs->regs.psw.addr - } - - static void nvSigHandler(int sig, siginfo_t *info, void *secret) - { - void * pnt = callerAddress(secret); - - // Do something useful with siginfo_t - if (sig == SIGSEGV) { - if (pnt != NULL) nvDebug("Got signal %d, faulty address is %p, from %p\n", sig, info->si_addr, pnt); - else nvDebug("Got signal %d, faulty address is %p\n", sig, info->si_addr); - } - else if(sig == SIGTRAP) { - nvDebug("Breakpoint hit.\n"); - } - else { - nvDebug("Got signal %d\n", sig); - } - -# if defined(HAVE_EXECINFO_H) - if (nvHasStackTrace()) // in case of weak linking - { - void * trace[64]; - int size = backtrace(trace, 64); - - if (pnt != NULL) { - // Overwrite sigaction with caller's address. - trace[1] = pnt; - } - - nvPrintStackTrace(trace, size, 1); - } -# endif // defined(HAVE_EXECINFO_H) - - exit(0); - } - -#endif // defined(HAVE_SIGNAL_H) - - - -#if NV_OS_WIN32 //&& NV_CC_MSVC - - /** Win32 asset handler. */ - struct Win32AssertHandler : public AssertHandler - { - // Code from Daniel Vogel. - static bool isDebuggerPresent() - { - bool result = false; - - HINSTANCE kern_lib = LoadLibraryExA( "kernel32.dll", NULL, 0 ); - if( kern_lib ) { - FARPROC lIsDebuggerPresent = GetProcAddress( kern_lib, "IsDebuggerPresent" ); - if( lIsDebuggerPresent && lIsDebuggerPresent() ) { - result = true; - } - - FreeLibrary( kern_lib ); - } - return result; - } - - // Flush the message queue. This is necessary for the message box to show up. - static void flushMessageQueue() - { - MSG msg; - while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { - if( msg.message == WM_QUIT ) break; - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } - } - - // Assert handler method. - virtual int assert( const char * exp, const char * file, int line, const char * func/*=NULL*/ ) - { - int ret = NV_ABORT_EXIT; - - StringBuilder error_string; - if( func != NULL ) { - error_string.format( "*** Assertion failed: %s\n On file: %s\n On function: %s\n On line: %d\n ", exp, file, func, line ); - nvDebug( error_string ); - } - else { - error_string.format( "*** Assertion failed: %s\n On file: %s\n On line: %d\n ", exp, file, line ); - nvDebug( error_string ); - } - - #if _DEBUG - - if( isDebuggerPresent() ) { - return NV_ABORT_DEBUG; - } - - flushMessageQueue(); - int action = MessageBoxA(NULL, error_string, "Assertion failed", MB_ABORTRETRYIGNORE|MB_ICONERROR); - switch( action ) { - case IDRETRY: - ret = NV_ABORT_DEBUG; - break; - case IDIGNORE: - ret = NV_ABORT_IGNORE; - break; - case IDABORT: - default: - ret = NV_ABORT_EXIT; - break; - } - /*if( _CrtDbgReport( _CRT_ASSERT, file, line, module, exp ) == 1 ) { - return NV_ABORT_DEBUG; - }*/ - - #endif - - if( ret == NV_ABORT_EXIT ) { - // Exit cleanly. - throw std::runtime_error("Assertion failed"); - } - - return ret; - } - }; - -#else - - /** Unix asset handler. */ - struct UnixAssertHandler : public AssertHandler - { - bool isDebuggerPresent() - { -# if NV_OS_DARWIN - int mib[4]; - struct kinfo_proc info; - size_t size; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - size = sizeof(info); - info.kp_proc.p_flag = 0; - sysctl(mib,4,&info,&size,NULL,0); - return ((info.kp_proc.p_flag & P_TRACED) == P_TRACED); -# else - // if ppid != sid, some process spawned our app, probably a debugger. - return getsid(getpid()) != getppid(); -# endif - } - - // Assert handler method. - virtual int assert(const char * exp, const char * file, int line, const char * func) - { - if( func != NULL ) { - nvDebug( "*** Assertion failed: %s\n On file: %s\n On function: %s\n On line: %d\n ", exp, file, func, line ); - } - else { - nvDebug( "*** Assertion failed: %s\n On file: %s\n On line: %d\n ", exp, file, line ); - } - -# if _DEBUG - if( isDebuggerPresent() ) { - return NV_ABORT_DEBUG; - } -# endif - -# if defined(HAVE_EXECINFO_H) - if (nvHasStackTrace()) - { - void * trace[64]; - int size = backtrace(trace, 64); - nvPrintStackTrace(trace, size, 2); - } -# endif - - // Exit cleanly. - throw std::runtime_error("Assertion failed"); - } - }; - -#endif - -} // namespace - - -/// Handle assertion through the asset handler. -int nvAbort(const char * exp, const char * file, int line, const char * func) -{ -#if NV_OS_WIN32 //&& NV_CC_MSVC - static Win32AssertHandler s_default_assert_handler; -#else - static UnixAssertHandler s_default_assert_handler; -#endif - - if( s_assert_handler != NULL ) { - return s_assert_handler->assert( exp, file, line, func ); - } - else { - return s_default_assert_handler.assert( exp, file, line, func ); - } -} - - -/// Shows a message through the message handler. -void NV_CDECL nvDebug(const char *msg, ...) -{ - va_list arg; - va_start(arg,msg); - if( s_message_handler != NULL ) { - s_message_handler->log( msg, arg ); - } - va_end(arg); -} - - -/// Dump debug info. -void debug::dumpInfo() -{ -#if !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) && defined(HAVE_EXECINFO_H) - if (nvHasStackTrace()) - { - void * trace[64]; - int size = backtrace(trace, 64); - nvPrintStackTrace(trace, size, 1); - } -#endif -} - - -/// Set the debug message handler. -void debug::setMessageHandler(MessageHandler * message_handler) -{ - s_message_handler = message_handler; -} - -/// Reset the debug message handler. -void debug::resetMessageHandler() -{ - s_message_handler = NULL; -} - -/// Set the assert handler. -void debug::setAssertHandler(AssertHandler * assert_handler) -{ - s_assert_handler = assert_handler; -} - -/// Reset the assert handler. -void debug::resetAssertHandler() -{ - s_assert_handler = NULL; -} - - -/// Enable signal handler. -void debug::enableSigHandler() -{ - nvCheck(s_sig_handler_enabled != true); - s_sig_handler_enabled = true; - -#if NV_OS_WIN32 && NV_CC_MSVC - - s_old_exception_filter = ::SetUnhandledExceptionFilter( nvTopLevelFilter ); - -#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) - - // Install our signal handler - struct sigaction sa; - sa.sa_sigaction = nvSigHandler; - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; - - sigaction(SIGSEGV, &sa, &s_old_sigsegv); - sigaction(SIGTRAP, &sa, &s_old_sigtrap); - sigaction(SIGFPE, &sa, &s_old_sigfpe); - sigaction(SIGBUS, &sa, &s_old_sigbus); - -#endif -} - -/// Disable signal handler. -void debug::disableSigHandler() -{ - nvCheck(s_sig_handler_enabled == true); - s_sig_handler_enabled = false; - -#if NV_OS_WIN32 && NV_CC_MSVC - - ::SetUnhandledExceptionFilter( s_old_exception_filter ); - s_old_exception_filter = NULL; - -#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) - - sigaction(SIGSEGV, &s_old_sigsegv, NULL); - sigaction(SIGTRAP, &s_old_sigtrap, NULL); - sigaction(SIGFPE, &s_old_sigfpe, NULL); - sigaction(SIGBUS, &s_old_sigbus, NULL); - -#endif -} - diff --git a/Externals/NVTT/src/nvcore/Debug.h b/Externals/NVTT/src/nvcore/Debug.h deleted file mode 100644 index 5cafb1c22f1..00000000000 --- a/Externals/NVTT/src/nvcore/Debug.h +++ /dev/null @@ -1,145 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_DEBUG_H -#define NV_CORE_DEBUG_H - -#include - -#if defined(HAVE_STDARG_H) -# include // va_list -#endif - -#define NV_ABORT_DEBUG 1 -#define NV_ABORT_IGNORE 2 -#define NV_ABORT_EXIT 3 - -#undef assert // avoid conflicts with assert method. - -#define nvNoAssert(exp) \ - do { \ - (void)sizeof(exp); \ - } while(0) - -#if NV_NO_ASSERT - -# define nvAssert(exp) nvNoAssert(exp) -# define nvCheck(exp) nvNoAssert(exp) -# define nvDebugAssert(exp) nvNoAssert(exp) -# define nvDebugCheck(exp) nvNoAssert(exp) -# define nvDebugBreak() nvNoAssert(0) - -#else // NV_NO_ASSERT - -# if NV_CC_MSVC - // @@ Does this work in msvc-6 and earlier? -# define nvDebugBreak() __debugbreak() -//# define nvDebugBreak() __asm { int 3 } -# elif NV_OS_ORBIS -# define nvDebugBreak() __debugbreak() -# elif NV_CC_GNUC -# define nvDebugBreak() __builtin_trap() -# else -# error "No nvDebugBreak()!" -# endif - -/* -# if NV_CC_MSVC - // @@ Does this work in msvc-6 and earlier? - // @@ Do I have to include ? -# define nvDebugBreak() __debugbreak() - // define nvDebugBreak() __asm int 3 -# elif NV_CC_GNUC && NV_CPU_PPC && NV_OS_DARWIN -# define nvDebugBreak() __asm__ volatile ("trap"); -# elif NV_CC_GNUC && NV_CPU_X86 && NV_OS_DARWIN -# define nvDebugBreak() __asm__ volatile ("int3"); -# elif NV_CC_GNUC && NV_CPU_X86 -# define nvDebugBreak() __asm__ ( "int %0" : :"I"(3) ) -# else -# include -# define nvDebugBreak() raise(SIGTRAP); - // define nvDebugBreak() *((int *)(0)) = 0 -# endif -*/ - -# define nvAssertMacro(exp) \ - do { \ - if(!(exp)) { \ - if( nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG ) { \ - nvDebugBreak(); \ - } \ - } \ - } while(false) - -# define nvAssert(exp) nvAssertMacro(exp) -# define nvCheck(exp) nvAssertMacro(exp) - -# if defined(_DEBUG) -# define nvDebugAssert(exp) nvAssertMacro(exp) -# define nvDebugCheck(exp) nvAssertMacro(exp) -# else // _DEBUG -# define nvDebugAssert(exp) nvNoAssert(exp) -# define nvDebugCheck(exp) nvNoAssert(exp) -# endif // _DEBUG - -#endif // NV_NO_ASSERT - -// Use nvAssume for very simple expresions only: nvAssume(0), nvAssume(value == true), etc. -#if defined(_DEBUG) -# if NV_CC_MSVC -# define nvAssume(exp) __assume(exp) -# else -# define nvAssume(exp) nvCheck(exp) -# endif -#else -# define nvAssume(exp) nvCheck(exp) -#endif - - -#define nvError(x) nvAbort(x, __FILE__, __LINE__, __FUNC__) -#define nvWarning(x) nvDebug("*** Warning %s/%d: %s\n", __FILE__, __LINE__, (x)) - - -#if PI_CC_MSVC -// @@ I'm not sure it's a good idea to use the default static assert. -# define nvStaticCheck(x) _STATIC_ASSERT(x) -#else -# define nvStaticCheck(x) typedef char NV_DO_STRING_JOIN2(__static_assert_,__LINE__)[(x)] -// define nvStaticCheck(x) switch(0) { case 0: case x:; } -#endif - -NVCORE_API int nvAbort(const char *exp, const char *file, int line, const char * func = 0); -NVCORE_API void NV_CDECL nvDebug( const char *msg, ... ) __attribute__((format (printf, 1, 2))); - -namespace nv -{ - /** Message handler interface. */ - struct MessageHandler { - virtual void log(const char * str, va_list arg) = 0; - virtual ~MessageHandler() {} - }; - - /** Assert handler interface. */ - struct AssertHandler { - virtual int assert(const char *exp, const char *file, int line, const char *func = 0) = 0; - virtual ~AssertHandler() {} - }; - - - namespace debug - { - NVCORE_API void dumpInfo(); - - // These functions are not thread safe. - NVCORE_API void setMessageHandler( MessageHandler * messageHandler ); - NVCORE_API void resetMessageHandler(); - - NVCORE_API void setAssertHandler( AssertHandler * assertHanlder ); - NVCORE_API void resetAssertHandler(); - - NVCORE_API void enableSigHandler(); - NVCORE_API void disableSigHandler(); - } - -} // nv namespace - -#endif // NV_CORE_DEBUG_H diff --git a/Externals/NVTT/src/nvcore/DefsGnucDarwin.h b/Externals/NVTT/src/nvcore/DefsGnucDarwin.h deleted file mode 100644 index 5442b79073b..00000000000 --- a/Externals/NVTT/src/nvcore/DefsGnucDarwin.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef NV_CORE_H -#error "Do not include this file directly." -#endif - -#include // uint8_t, int8_t, ... - -// Function linkage -#define DLL_IMPORT -#if __GNUC__ >= 4 -# define DLL_EXPORT __attribute__((visibility("default"))) -# define DLL_EXPORT_CLASS DLL_EXPORT -#else -# define DLL_EXPORT -# define DLL_EXPORT_CLASS -#endif - -// Function calling modes -#if NV_CPU_X86 -# define NV_CDECL __attribute__((cdecl)) -# define NV_STDCALL __attribute__((stdcall)) -#else -# define NV_CDECL -# define NV_STDCALL -#endif - -#define NV_FASTCALL __attribute__((fastcall)) -#define NV_FORCEINLINE __attribute__((always_inline)) -#define NV_DEPRECATED __attribute__((deprecated)) - -#if __GNUC__ > 2 -#define NV_PURE __attribute__((pure)) -#define NV_CONST __attribute__((const)) -#else -#define NV_PURE -#define NV_CONST -#endif - -// Define __FUNC__ properly. -#if __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 -# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__ -# else -# define __FUNC__ "" -# endif -#else -# define __FUNC__ __PRETTY_FUNCTION__ -#endif - -#define restrict __restrict__ - - -// Type definitions -typedef uint8_t uint8; -typedef int8_t int8; - -typedef uint16_t uint16; -typedef int16_t int16; - -typedef uint32_t uint32; -typedef int32_t int32; - -typedef uint64_t uint64; -typedef int64_t int64; - -// Aliases -typedef uint32 uint; diff --git a/Externals/NVTT/src/nvcore/DefsGnucLinux.h b/Externals/NVTT/src/nvcore/DefsGnucLinux.h deleted file mode 100644 index a8e2a29b406..00000000000 --- a/Externals/NVTT/src/nvcore/DefsGnucLinux.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef NV_CORE_H -#error "Do not include this file directly." -#endif - -// Function linkage -#define DLL_IMPORT -#if __GNUC__ >= 4 -# define DLL_EXPORT __attribute__((visibility("default"))) -# define DLL_EXPORT_CLASS DLL_EXPORT -#else -# define DLL_EXPORT -# define DLL_EXPORT_CLASS -#endif - -// Function calling modes -#if NV_CPU_X86 -# define NV_CDECL __attribute__((cdecl)) -# define NV_STDCALL __attribute__((stdcall)) -#else -# define NV_CDECL -# define NV_STDCALL -#endif - -#define NV_FASTCALL __attribute__((fastcall)) -#define NV_FORCEINLINE __attribute__((always_inline)) -#define NV_DEPRECATED __attribute__((deprecated)) - - -#if __GNUC__ > 2 -#define NV_PURE __attribute__((pure)) -#define NV_CONST __attribute__((const)) -#else -#define NV_PURE -#define NV_CONST -#endif - -// Define __FUNC__ properly. -#if __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 -# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__ -# else -# define __FUNC__ "" -# endif -#else -# define __FUNC__ __PRETTY_FUNCTION__ -#endif - -#define restrict __restrict__ - - -// Type definitions -typedef unsigned char uint8; -typedef signed char int8; - -typedef unsigned short uint16; -typedef signed short int16; - -typedef unsigned int uint32; -typedef signed int int32; - -typedef unsigned long long uint64; -typedef signed long long int64; - -// Aliases -typedef uint32 uint; diff --git a/Externals/NVTT/src/nvcore/DefsGnucWin32.h b/Externals/NVTT/src/nvcore/DefsGnucWin32.h deleted file mode 100644 index 2f8e3cc5744..00000000000 --- a/Externals/NVTT/src/nvcore/DefsGnucWin32.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef NV_CORE_H -#error "Do not include this file directly." -#endif - -// Function linkage -#define DLL_IMPORT __declspec(dllimport) -#define DLL_EXPORT __declspec(dllexport) -#define DLL_EXPORT_CLASS DLL_EXPORT - -// Function calling modes -#if NV_CPU_X86 -# define NV_CDECL __attribute__((cdecl)) -# define NV_STDCALL __attribute__((stdcall)) -#else -# define NV_CDECL -# define NV_STDCALL -#endif - -#define NV_FASTCALL __attribute__((fastcall)) -#define NV_FORCEINLINE __attribute__((always_inline)) -#define NV_DEPRECATED __attribute__((deprecated)) - -#if __GNUC__ > 2 -#define NV_PURE __attribute__((pure)) -#define NV_CONST __attribute__((const)) -#else -#define NV_PURE -#define NV_CONST -#endif - -// Define __FUNC__ properly. -#if __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 -# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__ -# else -# define __FUNC__ "" -# endif -#else -# define __FUNC__ __PRETTY_FUNCTION__ -#endif - -#define restrict __restrict__ - - -// Type definitions -typedef unsigned char uint8; -typedef signed char int8; - -typedef unsigned short uint16; -typedef signed short int16; - -typedef unsigned int uint32; -typedef signed int int32; - -typedef unsigned long long uint64; -typedef signed long long int64; - -// Aliases -typedef uint32 uint; diff --git a/Externals/NVTT/src/nvcore/DefsVcWin32.h b/Externals/NVTT/src/nvcore/DefsVcWin32.h deleted file mode 100644 index ec43aa05739..00000000000 --- a/Externals/NVTT/src/nvcore/DefsVcWin32.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef NV_CORE_H -#error "Do not include this file directly." -#endif - -// Function linkage -#define DLL_IMPORT __declspec(dllimport) -#define DLL_EXPORT __declspec(dllexport) -#define DLL_EXPORT_CLASS DLL_EXPORT - -// Function calling modes -#define NV_CDECL __cdecl -#define NV_STDCALL __stdcall -#define NV_FASTCALL __fastcall -#define NV_FORCEINLINE __forceinline -#define NV_DEPRECATED - -#define NV_PURE -#define NV_CONST - -// Set standard function names. -#if _MSC_VER < 1500 -# define vsnprintf _vsnprintf -#endif -#define vsscanf _vsscanf -#define chdir _chdir -#define getcwd _getcwd - -#define va_copy(a, b) a = b - -#if !defined restrict -#define restrict -#endif - -// Ignore gcc attributes. -#define __attribute__(X) - -#if !defined __FUNC__ -#define __FUNC__ __FUNCTION__ -#endif - - -// Type definitions -typedef unsigned char uint8; -typedef signed char int8; - -typedef unsigned short uint16; -typedef signed short int16; - -typedef unsigned int uint32; -typedef signed int int32; - -typedef unsigned __int64 uint64; -typedef signed __int64 int64; - -// Aliases -typedef uint32 uint; - - -// Unwanted VC++ warnings to disable. -/* -#pragma warning(disable : 4244) // conversion to float, possible loss of data -#pragma warning(disable : 4245) // conversion from 'enum ' to 'unsigned long', signed/unsigned mismatch -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#pragma warning(disable : 4710) // inline function not expanded -#pragma warning(disable : 4127) // Conditional expression is constant -#pragma warning(disable : 4305) // truncation from 'const double' to 'float' -#pragma warning(disable : 4505) // unreferenced local function has been removed - -#pragma warning(disable : 4702) // unreachable code in inline expanded function -#pragma warning(disable : 4711) // function selected for automatic inlining -#pragma warning(disable : 4725) // Pentium fdiv bug - -#pragma warning(disable : 4786) // Identifier was truncated and cannot be debugged. - -#pragma warning(disable : 4675) // resolved overload was found by argument-dependent lookup -*/ diff --git a/Externals/NVTT/src/nvcore/Library.cpp b/Externals/NVTT/src/nvcore/Library.cpp deleted file mode 100644 index 179239cc109..00000000000 --- a/Externals/NVTT/src/nvcore/Library.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -#include "Library.h" -#include "Debug.h" - -#if NV_OS_WIN32 -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN -#include -#else -#include -#endif - - - -void * nvLoadLibrary(const char * name) -{ -#if NV_OS_WIN32 - return (void *)LoadLibraryExA( name, NULL, 0 ); -#else - return dlopen(name, RTLD_LAZY); -#endif -} - -void nvUnloadLibrary(void * handle) -{ - nvDebugCheck(handle != NULL); -#if NV_OS_WIN32 - FreeLibrary((HMODULE)handle); -#else - dlclose(handle); -#endif -} - -void * nvBindSymbol(void * handle, const char * symbol) -{ -#if NV_OS_WIN32 - return (void *)GetProcAddress((HMODULE)handle, symbol); -#else - return (void *)dlsym(handle, symbol); -#endif -} diff --git a/Externals/NVTT/src/nvcore/Library.h b/Externals/NVTT/src/nvcore/Library.h deleted file mode 100644 index ee7d416efe2..00000000000 --- a/Externals/NVTT/src/nvcore/Library.h +++ /dev/null @@ -1,50 +0,0 @@ -// This code is in the public domain -- castano@gmail.com - -#ifndef NV_CORE_LIBRARY_H -#define NV_CORE_LIBRARY_H - -#include - -#if NV_OS_WIN32 -#define LIBRARY_NAME(name) #name ".dll" -#elif NV_OS_DARWIN -#define NV_LIBRARY_NAME(name) "lib" #name ".dylib" -#else -#define NV_LIBRARY_NAME(name) "lib" #name ".so" -#endif - -NVCORE_API void * nvLoadLibrary(const char * name); -NVCORE_API void nvUnloadLibrary(void * lib); -NVCORE_API void * nvBindSymbol(void * lib, const char * symbol); - -class NVCORE_CLASS Library -{ -public: - Library(const char * name) - { - handle = nvLoadLibrary(name); - } - ~Library() - { - if (isValid()) - { - nvUnloadLibrary(handle); - } - } - - bool isValid() const - { - return handle != NULL; - } - - void * bindSymbol(const char * symbol) - { - return nvBindSymbol(handle, symbol); - } - -private: - void * handle; -}; - - -#endif // NV_CORE_LIBRARY_H diff --git a/Externals/NVTT/src/nvcore/Memory.cpp b/Externals/NVTT/src/nvcore/Memory.cpp deleted file mode 100644 index 694e616d7b9..00000000000 --- a/Externals/NVTT/src/nvcore/Memory.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -#include "Memory.h" -#include "Debug.h" - -//#if HAVE_MALLOC_H - -//#endif - -#include - - -using namespace nv; - -void * nv::mem::malloc(size_t size) -{ - return ::malloc(size); -} - -void * nv::mem::malloc(size_t size, const char * file, int line) -{ - NV_UNUSED(file); - NV_UNUSED(line); - return ::malloc(size); -} - -void nv::mem::free(const void * ptr) -{ - ::free(const_cast(ptr)); -} - -void * nv::mem::realloc(void * ptr, size_t size) -{ - nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior. - return ::realloc(ptr, size); -} - diff --git a/Externals/NVTT/src/nvcore/Memory.h b/Externals/NVTT/src/nvcore/Memory.h deleted file mode 100644 index 43732064f5b..00000000000 --- a/Externals/NVTT/src/nvcore/Memory.h +++ /dev/null @@ -1,186 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_MEMORY_H -#define NV_CORE_MEMORY_H - -#include - -#include // malloc(), realloc() and free() -#include // size_t - -#include // new and delete - -// Custom memory allocator -namespace nv -{ - namespace mem - { - NVCORE_API void * malloc(size_t size); - NVCORE_API void * malloc(size_t size, const char * file, int line); - - NVCORE_API void free(const void * ptr); - NVCORE_API void * realloc(void * ptr, size_t size); - - } // mem namespace - -} // nv namespace - - -// Override new/delete - -inline void * operator new (size_t size) noexcept -{ - return nv::mem::malloc(size); -} - -inline void operator delete (void *p) noexcept -{ - nv::mem::free(p); -} - -inline void * operator new [] (size_t size) noexcept -{ - return nv::mem::malloc(size); -} - -inline void operator delete [] (void * p) noexcept -{ - nv::mem::free(p); -} - -/* -#ifdef _DEBUG -#define new new(__FILE__, __LINE__) -#define malloc(i) malloc(i, __FILE__, __LINE__) -#endif -*/ - -#if 0 -/* - File: main.cpp - - Version: 1.0 - - Abstract: Overrides the C++ 'operator new' and 'operator delete'. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under Apple’s - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Copyright © 2006 Apple Computer, Inc., All Rights Reserved -*/ - -/* This sample shows how to override the C++ global 'new' and 'delete' operators. */ -#include -#include -#include -#include -#include - -/* Some variables and code to make the example do something. */ -namespace { - unsigned long long gNewCounter; // number of times 'new' was called - unsigned long long gDeleteCounter; // number of times 'delete' was called - - void printCounters() // print the counters above - { - std::cout << "new was called " << gNewCounter << " times and delete was called " << gDeleteCounter << " times\n"; - } -} - -/* These are the overridden new and delete routines. - Most applications will want to override at least these four versions of new/delete if they override any of them. - - In Mac OS, it's not necessary to override the array versions of operator new and delete if all - they would do is call the non-array versions; the C++ standard library, as an extension - to the C++ standard, does this for you. - - Developers should consult the section [lib.support.dynamic] in the C++ standard to see the requirements - on the generic operators new and delete; the system may expect that your overridden operators meet all these - requirements. - - Your operators may be called by the system, even early in start-up before constructors have been executed. */ -void* operator new(std::size_t sz) throw (std::bad_alloc) -{ - void *result = std::malloc (sz == 0 ? 1 : sz); - if (result == NULL) - throw std::bad_alloc(); - gNewCounter++; - return result; -} -void operator delete(void* p) noexcept -{ - if (p == NULL) - return; - std::free (p); - gDeleteCounter++; -} - -/* These are the 'nothrow' versions of the above operators. - The system version will try to call a std::new_handler if they - fail, but your overriding versions are not required to do this. */ -void* operator new(std::size_t sz, const std::nothrow_t&) noexcept -{ - try { - void * result = ::operator new (sz); // calls our overridden operator new - return result; - } catch (std::bad_alloc &) { - return NULL; - } -} -void operator delete(void* p, const std::nothrow_t&) noexcept -{ - ::operator delete (p); -} - -/* Bug 4067110 is that if your program has no weak symbols at all, the linker will not set the - WEAK_DEFINES bit in the Mach-O header and as a result the new and delete operators above won't - be seen by system libraries. This is mostly a problem for test programs and small examples, - since almost all real C++ programs complicated enough to override new and delete will have at - least one weak symbol. However, this is a small example, so: */ -void __attribute__((weak, visibility("default"))) workaroundFor4067110 () { } - -/* This is a simple test program that causes the runtime library to call new and delete. */ -int main() -{ - atexit (printCounters); - try { - std::locale example("does_not_exist"); - } catch (std::runtime_error &x) { - } - return 0; -} -#endif // 0 - -#endif // NV_CORE_MEMORY_H diff --git a/Externals/NVTT/src/nvcore/Prefetch.h b/Externals/NVTT/src/nvcore/Prefetch.h deleted file mode 100644 index 71bd0ed821d..00000000000 --- a/Externals/NVTT/src/nvcore/Prefetch.h +++ /dev/null @@ -1,31 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_PREFETCH_H -#define NV_CORE_PREFETCH_H - -#include - -// nvPrefetch -#if NV_CC_GNUC - -#define nvPrefetch(ptr) __builtin_prefetch(ptr) - -#elif NV_CC_MSVC - -#if NV_CPU_X86 -__forceinline void nvPrefetch(const void * mem) -{ - __asm mov ecx, mem - __asm prefetcht0 [ecx]; -// __asm prefetchnta [ecx]; -} -#endif // NV_CPU_X86 - -#else // NV_CC_MSVC - -// do nothing in other case. -#define nvPrefetch(ptr) - -#endif // NV_CC_MSVC - -#endif // NV_CORE_PREFETCH_H diff --git a/Externals/NVTT/src/nvcore/Ptr.h b/Externals/NVTT/src/nvcore/Ptr.h deleted file mode 100644 index 1d8d9c9a57f..00000000000 --- a/Externals/NVTT/src/nvcore/Ptr.h +++ /dev/null @@ -1,364 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_PTR_H -#define NV_CORE_PTR_H - -#include -#include - -#include // NULL - -namespace nv -{ - -/** Simple auto pointer template class. - * - * This is very similar to the standard auto_ptr class, but with some - * additional limitations to make its use less error prone: - * - Copy constructor and assignment operator are disabled. - * - reset method is removed. - * - * The semantics of the standard auto_ptr are not clear and change depending - * on the std implementation. For a discussion of the problems of auto_ptr read: - * http://www.awprofessional.com/content/images/020163371X/autoptrupdate\auto_ptr_update.html - */ -template -class AutoPtr -{ - NV_FORBID_COPY(AutoPtr); - NV_FORBID_HEAPALLOC(); -public: - - /// Default ctor. - AutoPtr() : m_ptr(NULL) { } - - /// Ctor. - explicit AutoPtr( T * p ) : m_ptr(p) { } - - /** Dtor. Deletes owned pointer. */ - ~AutoPtr() { - delete m_ptr; - m_ptr = NULL; - } - - /** Delete owned pointer and assign new one. */ - void operator=( T * p ) { - if (p != m_ptr) - { - delete m_ptr; - m_ptr = p; - } - } - - /** Member access. */ - T * operator -> () const { - nvDebugCheck(m_ptr != NULL); - return m_ptr; - } - - /** Get reference. */ - T & operator*() const { - nvDebugCheck(m_ptr != NULL); - return *m_ptr; - } - - /** Get pointer. */ - T * ptr() const { return m_ptr; } - - /** Relinquish ownership of the underlying pointer and returns that pointer. */ - T * release() { - T * tmp = m_ptr; - m_ptr = NULL; - return tmp; - } - - /** Const pointer equal comparation. */ - friend bool operator == (const AutoPtr & ap, const T * const p) { - return (ap.ptr() == p); - } - - /** Const pointer nequal comparation. */ - friend bool operator != (const AutoPtr & ap, const T * const p) { - return (ap.ptr() != p); - } - - /** Const pointer equal comparation. */ - friend bool operator == (const T * const p, const AutoPtr & ap) { - return (ap.ptr() == p); - } - - /** Const pointer nequal comparation. */ - friend bool operator != (const T * const p, const AutoPtr & ap) { - return (ap.ptr() != p); - } - -private: - T * m_ptr; -}; - -#if 0 -/** Reference counted base class to be used with Pointer. - * - * The only requirement of the Pointer class is that the RefCounted class implements the - * addRef and release methods. - */ -class RefCounted -{ - NV_FORBID_COPY(RefCounted); -public: - - /// Ctor. - RefCounted() : m_count(0), m_weak_proxy(NULL) - { - s_total_obj_count++; - } - - /// Virtual dtor. - virtual ~RefCounted() - { - nvCheck( m_count == 0 ); - nvCheck( s_total_obj_count > 0 ); - s_total_obj_count--; - } - - - /// Increase reference count. - uint addRef() const - { - s_total_ref_count++; - m_count++; - return m_count; - } - - - /// Decrease reference count and remove when 0. - uint release() const - { - nvCheck( m_count > 0 ); - - s_total_ref_count--; - m_count--; - if( m_count == 0 ) { - releaseWeakProxy(); - delete this; - return 0; - } - return m_count; - } - - /// Get weak proxy. - WeakProxy * getWeakProxy() const - { - if (m_weak_proxy == NULL) { - m_weak_proxy = new WeakProxy; - m_weak_proxy->AddRef(); - } - return m_weak_proxy; - } - - /// Release the weak proxy. - void releaseWeakProxy() const - { - if (m_weak_proxy != NULL) { - m_weak_proxy->NotifyObjectDied(); - m_weak_proxy->Release(); - m_weak_proxy = NULL; - } - } - - /** @name Debug methods: */ - //@{ - /// Get reference count. - int refCount() const - { - return m_count; - } - - /// Get total number of objects. - static int totalObjectCount() - { - return s_total_obj_count; - } - - /// Get total number of references. - static int totalReferenceCount() - { - return s_total_ref_count; - } - //@} - - -private: - - NVCORE_API static int s_total_ref_count; - NVCORE_API static int s_total_obj_count; - - mutable int m_count; - mutable WeakProxy * weak_proxy; - -}; -#endif - -/// Smart pointer template class. -template -class Pointer { -public: - - // BaseClass must implement addRef() and release(). - typedef Pointer ThisType; - - /// Default ctor. - Pointer() : m_ptr(NULL) - { - } - - /** Other type assignment. */ - template - Pointer( const Pointer & tc ) - { - m_ptr = static_cast( tc.ptr() ); - if( m_ptr ) { - m_ptr->addRef(); - } - } - - /** Copy ctor. */ - Pointer( const ThisType & bc ) - { - m_ptr = bc.ptr(); - if( m_ptr ) { - m_ptr->addRef(); - } - } - - /** Copy cast ctor. Pointer(NULL) is valid. */ - explicit Pointer( BaseClass * bc ) - { - m_ptr = bc; - if( m_ptr ) { - m_ptr->addRef(); - } - } - - /** Dtor. */ - ~Pointer() - { - set(NULL); - } - - - /** @name Accessors: */ - //@{ - /** -> operator. */ - BaseClass * operator -> () const - { - nvCheck( m_ptr != NULL ); - return m_ptr; - } - - /** * operator. */ - BaseClass & operator*() const - { - nvCheck( m_ptr != NULL ); - return *m_ptr; - } - - /** Get pointer. */ - BaseClass * ptr() const - { - return m_ptr; - } - //@} - - - /** @name Mutators: */ - //@{ - /** Other type assignment. */ - template - void operator = ( const Pointer & tc ) - { - set( static_cast(tc.ptr()) ); - } - - /** This type assignment. */ - void operator = ( const ThisType & bc ) - { - set( bc.ptr() ); - } - - /** Pointer assignment. */ - void operator = ( BaseClass * bc ) - { - set( bc ); - } - //@} - - - /** @name Comparators: */ - //@{ - /** Other type equal comparation. */ - template - bool operator == ( const Pointer & other ) const - { - return m_ptr == other.ptr(); - } - - /** This type equal comparation. */ - bool operator == ( const ThisType & bc ) const - { - return m_ptr == bc.ptr(); - } - - /** Const pointer equal comparation. */ - bool operator == ( const BaseClass * const bc ) const - { - return m_ptr == bc; - } - - /** Other type not equal comparation. */ - template - bool operator != ( const Pointer & other ) const - { - return m_ptr != other.ptr(); - } - - /** Other type not equal comparation. */ - bool operator != ( const ThisType & bc ) const - { - return m_ptr != bc.ptr(); - } - - /** Const pointer not equal comparation. */ - bool operator != (const BaseClass * const bc) const - { - return m_ptr != bc; - } - - /** This type lower than comparation. */ - bool operator < (const ThisType & p) const - { - return m_ptr < p.ptr(); - } - //@} - -private: - - /** Set this pointer. */ - void set( BaseClass * p ) - { - if( m_ptr != p ) { - if( m_ptr ) m_ptr->release(); - if( p ) p->addRef(); - m_ptr = p; - } - } - -private: - - BaseClass * m_ptr; - -}; - -} // nv namespace - -#endif // NV_CORE_PTR_H diff --git a/Externals/NVTT/src/nvcore/Radix.cpp b/Externals/NVTT/src/nvcore/Radix.cpp deleted file mode 100644 index 713215f3dce..00000000000 --- a/Externals/NVTT/src/nvcore/Radix.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Contains source code from the article "Radix Sort Revisited". - * \file Radix.cpp - * \author Pierre Terdiman - * \date April, 4, 2000 - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Revisited Radix Sort. - * This is my new radix routine: - * - it uses indices and doesn't recopy the values anymore, hence wasting less ram - * - it creates all the histograms in one run instead of four - * - it sorts words faster than dwords and bytes faster than words - * - it correctly sorts negative floating-point values by patching the offsets - * - it automatically takes advantage of temporal coherence - * - multiple keys support is a side effect of temporal coherence - * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] - * - * History: - * - 08.15.98: very first version - * - 04.04.00: recoded for the radix article - * - 12.xx.00: code lifting - * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) - * - 10.11.01: added local ram support - * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... - * - * \class RadixSort - * \author Pierre Terdiman - * \version 1.3 - * \date August, 15, 1998 - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/* -To do: - - add an offset parameter between two input values (avoid some data recopy sometimes) - - unroll ? asm ? -*/ - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Header - -#include - -#include // memset - -//using namespace IceCore; - -#define DELETEARRAY(a) { delete [] a; a = NULL; } -#define CHECKALLOC(a) - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Constructor. - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -RadixSort::RadixSort() : mCurrentSize(0), mPreviousSize(0), mIndices(NULL), mIndices2(NULL), mTotalCalls(0), mNbHits(0) -{ -#ifndef RADIX_LOCAL_RAM - // Allocate input-independent ram - mHistogram = new uint32[256*4]; - mOffset = new uint32[256]; -#endif - // Initialize indices - resetIndices(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Destructor. - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -RadixSort::~RadixSort() -{ - // Release everything -#ifndef RADIX_LOCAL_RAM - DELETEARRAY(mOffset); - DELETEARRAY(mHistogram); -#endif - DELETEARRAY(mIndices2); - DELETEARRAY(mIndices); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Resizes the inner lists. - * \param nb [in] new size (number of dwords) - * \return true if success - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool RadixSort::resize(uint32 nb) -{ - // Free previously used ram - DELETEARRAY(mIndices2); - DELETEARRAY(mIndices); - - // Get some fresh one - mIndices = new uint32[nb]; CHECKALLOC(mIndices); - mIndices2 = new uint32[nb]; CHECKALLOC(mIndices2); - mCurrentSize = nb; - - // Initialize indices so that the input buffer is read in sequential order - resetIndices(); - - return true; -} - -#define CHECK_RESIZE(n) \ - if(n!=mPreviousSize) \ - { \ - if(n>mCurrentSize) resize(n); \ - else resetIndices(); \ - mPreviousSize = n; \ - } - -#define CREATE_HISTOGRAMS(type, buffer) \ - /* Clear counters */ \ - memset(mHistogram, 0, 256*4*sizeof(uint32)); \ - \ - /* Prepare for temporal coherence */ \ - type PrevVal = (type)buffer[mIndices[0]]; \ - bool AlreadySorted = true; /* Optimism... */ \ - uint32* Indices = mIndices; \ - \ - /* Prepare to count */ \ - uint8* p = (uint8*)input; \ - uint8* pe = &p[nb*4]; \ - uint32* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \ - uint32* h1= &mHistogram[256]; /* Histogram for second pass */ \ - uint32* h2= &mHistogram[512]; /* Histogram for third pass */ \ - uint32* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \ - \ - while(p!=pe) \ - { \ - /* Read input buffer in previous sorted order */ \ - type Val = (type)buffer[*Indices++]; \ - /* Check whether already sorted or not */ \ - if(Val>24; // Radix byte, same as above. AND is useless here (uint32). - // ### cmp to be killed. Not good. Later. - if(Radix<128) mIndices2[mOffset[Radix]++] = mIndices[i]; // Number is positive, same as above - else mIndices2[--mOffset[Radix]] = mIndices[i]; // Number is negative, flip the sorting order - } - // Swap pointers for next pass. Valid indices - the most recent ones - are in mIndices after the swap. - uint32* Tmp = mIndices; mIndices = mIndices2; mIndices2 = Tmp; - } - else - { - // The pass is useless, yet we still have to reverse the order of current list if all values are negative. - if(UniqueVal>=128) - { - for(i=0;i - - -#define RADIX_LOCAL_RAM - - -class NVCORE_API RadixSort { - NV_FORBID_COPY(RadixSort); -public: - // Constructor/Destructor - RadixSort(); - ~RadixSort(); - - // Sorting methods - RadixSort & sort(const uint32* input, uint32 nb, bool signedvalues=true); - RadixSort & sort(const float* input, uint32 nb); - - //! Access to results. mIndices is a list of indices in sorted order, i.e. in the order you may further process your data - inline uint32 * indices() const { return mIndices; } - - //! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want. - inline uint32 * recyclable() const { return mIndices2; } - - // Stats - uint32 usedRam() const; - - //! Returns the total number of calls to the radix sorter. - inline uint32 totalCalls() const { return mTotalCalls; } - - //! Returns the number of premature exits due to temporal coherence. - inline uint32 hits() const { return mNbHits; } - - - private: -#ifndef RADIX_LOCAL_RAM - uint32* mHistogram; //!< Counters for each byte - uint32* mOffset; //!< Offsets (nearly a cumulative distribution function) -#endif - uint32 mCurrentSize; //!< Current size of the indices list - uint32 mPreviousSize; //!< Size involved in previous call - uint32* mIndices; //!< Two lists, swapped each pass - uint32* mIndices2; - - // Stats - uint32 mTotalCalls; - uint32 mNbHits; - - // Internal methods - bool resize(uint32 nb); - void resetIndices(); - -}; - - -#endif // NV_CORE_RADIXSORT_H diff --git a/Externals/NVTT/src/nvcore/StdStream.h b/Externals/NVTT/src/nvcore/StdStream.h deleted file mode 100644 index 43046124e9c..00000000000 --- a/Externals/NVTT/src/nvcore/StdStream.h +++ /dev/null @@ -1,369 +0,0 @@ -#ifndef NV_STDSTREAM_H -#define NV_STDSTREAM_H - -#include - -#include // fopen -#include // memcpy -#include // std::exception - -namespace nv -{ - -// Portable version of fopen. -inline FILE * fileOpen(const char * fileName, const char * mode) -{ - nvCheck(fileName != NULL); -#if NV_CC_MSVC && _MSC_VER >= 1400 - FILE * fp; - if (fopen_s(&fp, fileName, mode) == 0) { - return fp; - } - return NULL; -#else - return fopen(fileName, mode); -#endif -} - - -/// Base stdio stream. -class NVCORE_CLASS StdStream : public Stream -{ - NV_FORBID_COPY(StdStream); -public: - - /// Ctor. - StdStream( FILE * fp, bool autoclose=true ) : - m_fp(fp), m_autoclose(autoclose) { } - - /// Dtor. - virtual ~StdStream() - { - if( m_fp != NULL && m_autoclose ) { - fclose( m_fp ); - } - } - - - /** @name Stream implementation. */ - //@{ - virtual void seek( uint pos ) - { - nvDebugCheck(m_fp != NULL); - nvDebugCheck(pos < size()); - fseek(m_fp, pos, SEEK_SET); - } - - virtual uint tell() const - { - nvDebugCheck(m_fp != NULL); - return ftell(m_fp); - } - - virtual uint size() const - { - nvDebugCheck(m_fp != NULL); - uint pos = ftell(m_fp); - fseek(m_fp, 0, SEEK_END); - uint end = ftell(m_fp); - fseek(m_fp, pos, SEEK_SET); - return end; - } - - virtual bool isError() const - { - return m_fp == NULL || ferror( m_fp ) != 0; - } - - virtual void clearError() - { - nvDebugCheck(m_fp != NULL); - clearerr(m_fp); - } - - virtual bool isAtEnd() const - { - nvDebugCheck(m_fp != NULL); - return feof( m_fp ) != 0; - } - - /// Always true. - virtual bool isSeekable() const { return true; } - //@} - -protected: - - FILE * m_fp; - bool m_autoclose; - -}; - - -/// Standard output stream. -class NVCORE_CLASS StdOutputStream : public StdStream -{ - NV_FORBID_COPY(StdOutputStream); -public: - - /// Construct stream by file name. - StdOutputStream( const char * name ) : - StdStream(fileOpen(name, "wb")) { } - - /// Construct stream by file handle. - StdOutputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose) - { - } - - /** @name Stream implementation. */ - //@{ - /// Write data. - virtual uint serialize( void * data, uint len ) - { - nvDebugCheck(data != NULL); - nvDebugCheck(m_fp != NULL); - return (uint)fwrite(data, 1, len, m_fp); - } - - virtual bool isLoading() const - { - return false; - } - - virtual bool isSaving() const - { - return true; - } - //@} - -}; - - -/// Standard input stream. -class NVCORE_CLASS StdInputStream : public StdStream -{ - NV_FORBID_COPY(StdInputStream); -public: - - /// Construct stream by file name. - StdInputStream( const char * name ) : - StdStream(fileOpen(name, "rb")) { } - - /// Construct stream by file handle. - StdInputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose) - { - } - - /** @name Stream implementation. */ - //@{ - /// Read data. - virtual uint serialize( void * data, uint len ) - { - nvDebugCheck(data != NULL); - nvDebugCheck(m_fp != NULL); - return (uint)fread(data, 1, len, m_fp); - } - - virtual bool isLoading() const - { - return true; - } - - virtual bool isSaving() const - { - return false; - } - //@} -}; - - - -/// Memory input stream. -class NVCORE_CLASS MemoryInputStream : public Stream -{ - NV_FORBID_COPY(MemoryInputStream); -public: - - /// Ctor. - MemoryInputStream( const uint8 * mem, uint size ) : - m_mem(mem), m_ptr(mem), m_size(size) { } - - /** @name Stream implementation. */ - //@{ - /// Read data. - virtual uint serialize( void * data, uint len ) - { - nvDebugCheck(data != NULL); - nvDebugCheck(!isError()); - - uint left = m_size - tell(); - if (len > left) len = left; - - memcpy( data, m_ptr, len ); - m_ptr += len; - - return len; - } - - virtual void seek( uint pos ) - { - nvDebugCheck(!isError()); - m_ptr = m_mem + pos; - nvDebugCheck(!isError()); - } - - virtual uint tell() const - { - nvDebugCheck(m_ptr >= m_mem); - return uint(m_ptr - m_mem); - } - - virtual uint size() const - { - return m_size; - } - - virtual bool isError() const - { - return m_mem == NULL || m_ptr > m_mem + m_size || m_ptr < m_mem; - } - - virtual void clearError() - { - // Nothing to do. - } - - virtual bool isAtEnd() const - { - return m_ptr == m_mem + m_size; - } - - /// Always true. - virtual bool isSeekable() const - { - return true; - } - - virtual bool isLoading() const - { - return true; - } - - virtual bool isSaving() const - { - return false; - } - //@} - - -private: - - const uint8 * m_mem; - const uint8 * m_ptr; - uint m_size; - -}; - - -/// Protected input stream. -class NVCORE_CLASS ProtectedStream : public Stream -{ - NV_FORBID_COPY(ProtectedStream); -public: - - /// Ctor. - ProtectedStream( Stream & s ) : m_s(&s), m_autodelete(false) - { - } - - /// Ctor. - ProtectedStream( Stream * s, bool autodelete = true ) : - m_s(s), m_autodelete(autodelete) - { - nvDebugCheck(m_s != NULL); - } - - /// Dtor. - virtual ~ProtectedStream() - { - if( m_autodelete ) { - delete m_s; - } - } - - /** @name Stream implementation. */ - //@{ - /// Read data. - virtual uint serialize( void * data, uint len ) - { - nvDebugCheck(data != NULL); - len = m_s->serialize( data, len ); - - if( m_s->isError() ) { - throw std::exception(); - } - - return len; - } - - virtual void seek( uint pos ) - { - m_s->seek( pos ); - - if( m_s->isError() ) { - throw std::exception(); - } - } - - virtual uint tell() const - { - return m_s->tell(); - } - - virtual uint size() const - { - return m_s->size(); - } - - virtual bool isError() const - { - return m_s->isError(); - } - - virtual void clearError() - { - m_s->clearError(); - } - - virtual bool isAtEnd() const - { - return m_s->isAtEnd(); - } - - virtual bool isSeekable() const - { - return m_s->isSeekable(); - } - - virtual bool isLoading() const - { - return m_s->isLoading(); - } - - virtual bool isSaving() const - { - return m_s->isSaving(); - } - //@} - - -private: - - Stream * const m_s; - bool const m_autodelete; - -}; - -} // nv namespace - - -#endif // NV_STDSTREAM_H diff --git a/Externals/NVTT/src/nvcore/StrLib.cpp b/Externals/NVTT/src/nvcore/StrLib.cpp deleted file mode 100644 index 34cf992399c..00000000000 --- a/Externals/NVTT/src/nvcore/StrLib.cpp +++ /dev/null @@ -1,584 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -#include // log -#include // vsnprintf - -#if NV_CC_MSVC -#include // vsnprintf -#endif - -#if NV_OS_WIN32 -#define NV_PATH_SEPARATOR '\\' -#else -#define NV_PATH_SEPARATOR '/' -#endif - -using namespace nv; - -namespace -{ - static char * strAlloc(uint size) - { - return static_cast(mem::malloc(size)); - } - - static char * strReAlloc(char * str, uint size) - { - return static_cast(mem::realloc(str, size)); - } - - static void strFree(const char * str) - { - return mem::free(const_cast(str)); - } - - /*static char * strDup( const char * str ) - { - nvDebugCheck( str != NULL ); - uint len = uint(strlen( str ) + 1); - char * dup = strAlloc( len ); - memcpy( dup, str, len ); - return dup; - }*/ - - // helper function for integer to string conversion. - static char * i2a( uint i, char *a, uint r ) - { - if( i / r > 0 ) { - a = i2a( i / r, a, r ); - } - *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % r]; - return a + 1; - } - - // Locale independent functions. - static inline char toUpper( char c ) { - return (c<'a' || c>'z') ? (c) : (c+'A'-'a'); - } - static inline char toLower( char c ) { - return (c<'A' || c>'Z') ? (c) : (c+'a'-'A'); - } - static inline bool isAlpha( char c ) { - return (c>='a' && c<='z') || (c>='A' && c<='Z'); - } - static inline bool isDigit( char c ) { - return c>='0' && c<='9'; - } - static inline bool isAlnum( char c ) { - return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'); - } - -} - -int nv::strCmp(const char * s1, const char * s2) -{ - nvDebugCheck(s1 != NULL); - nvDebugCheck(s2 != NULL); - return strcmp(s1, s2); -} - -int nv::strCaseCmp(const char * s1, const char * s2) -{ - nvDebugCheck(s1 != NULL); - nvDebugCheck(s1 != NULL); -#if NV_CC_MSVC - return _stricmp(s1, s2); -#else - return strcasecmp(s1, s2); -#endif -} - -void nv::strCpy(char * dst, int size, const char * src) -{ - nvDebugCheck(dst != NULL); - nvDebugCheck(src != NULL); -#if NV_CC_MSVC && _MSC_VER >= 1400 - strcpy_s(dst, size, src); -#else - NV_UNUSED(size); - strcpy(dst, src); -#endif -} - -void nv::strCpy(char * dst, int size, const char * src, int len) -{ - nvDebugCheck(dst != NULL); - nvDebugCheck(src != NULL); -#if NV_CC_MSVC && _MSC_VER >= 1400 - strncpy_s(dst, size, src, len); -#else - NV_UNUSED(size); - strncpy(dst, src, len); -#endif -} - -void nv::strCat(char * dst, int size, const char * src) -{ - nvDebugCheck(dst != NULL); - nvDebugCheck(src != NULL); -#if NV_CC_MSVC && _MSC_VER >= 1400 - strcat_s(dst, size, src); -#else - NV_UNUSED(size); - strcat(dst, src); -#endif -} - - -/** Pattern matching routine. I don't remember where did I get this. */ -bool nv::strMatch(const char * str, const char * pat) -{ - nvDebugCheck(str != NULL); - nvDebugCheck(pat != NULL); - - char c2; - - while (true) { - if (*pat==0) { - if (*str==0) return true; - else return false; - } - if ((*str==0) && (*pat!='*')) return false; - if (*pat=='*') { - pat++; - if (*pat==0) return true; - while (true) { - if (strMatch(str, pat)) return true; - if (*str==0) return false; - str++; - } - } - if (*pat=='?') goto match; - if (*pat=='[') { - pat++; - while (true) { - if ((*pat==']') || (*pat==0)) return false; - if (*pat==*str) break; - if (pat[1] == '-') { - c2 = pat[2]; - if (c2==0) return false; - if ((*pat<=*str) && (c2>=*str)) break; - if ((*pat>=*str) && (c2<=*str)) break; - pat+=2; - } - pat++; - } - while (*pat!=']') { - if (*pat==0) { - pat--; - break; - } - pat++; - } - goto match; - } - - if (*pat == NV_PATH_SEPARATOR) { - pat++; - if (*pat==0) return false; - } - if (*pat!=*str) return false; - -match: - pat++; - str++; - } -} - - - -/** Empty string. */ -StringBuilder::StringBuilder() : m_size(0), m_str(NULL) -{ -} - -/** Preallocate space. */ -StringBuilder::StringBuilder( int size_hint ) : m_size(size_hint) -{ - nvDebugCheck(m_size > 0); - m_str = strAlloc(m_size); - *m_str = '\0'; -} - -/** Copy ctor. */ -StringBuilder::StringBuilder( const StringBuilder & s ) : m_size(0), m_str(NULL) -{ - copy(s); -} - -/** Copy string. */ -StringBuilder::StringBuilder( const char * s ) : m_size(0), m_str(NULL) -{ - copy(s); -} - -/** Delete the string. */ -StringBuilder::~StringBuilder() -{ - m_size = 0; - strFree(m_str); - m_str = NULL; -} - - -/** Format a string safely. */ -StringBuilder & StringBuilder::format( const char * fmt, ... ) -{ - nvDebugCheck(fmt != NULL); - va_list arg; - va_start( arg, fmt ); - - format( fmt, arg ); - - va_end( arg ); - - return *this; -} - - -/** Format a string safely. */ -StringBuilder & StringBuilder::format( const char * fmt, va_list arg ) -{ - nvDebugCheck(fmt != NULL); - - if( m_size == 0 ) { - m_size = 64; - m_str = strAlloc( m_size ); - } - - va_list tmp; - va_copy(tmp, arg); -#if NV_CC_MSVC && _MSC_VER >= 1400 - int n = vsnprintf_s(m_str, m_size, _TRUNCATE, fmt, tmp); -#else - int n = vsnprintf(m_str, m_size, fmt, tmp); -#endif - va_end(tmp); - - while( n < 0 || n >= int(m_size) ) { - if( n > -1 ) { - m_size = n + 1; - } - else { - m_size *= 2; - } - - m_str = strReAlloc(m_str, m_size); - - va_copy(tmp, arg); -#if NV_CC_MSVC && _MSC_VER >= 1400 - n = vsnprintf_s(m_str, m_size, _TRUNCATE, fmt, tmp); -#else - n = vsnprintf(m_str, m_size, fmt, tmp); -#endif - va_end(tmp); - } - - nvDebugCheck(n < int(m_size)); - - // Make sure it's null terminated. - nvDebugCheck(m_str[n] == '\0'); - //str[n] = '\0'; - - return *this; -} - - -/** Append a string. */ -StringBuilder & StringBuilder::append( const char * s ) -{ - nvDebugCheck(s != NULL); - - const uint slen = uint(strlen( s )); - - if( m_str == NULL ) { - m_size = slen + 1; - m_str = strAlloc(m_size); - strCpy( m_str, m_size, s ); - } - else { - - const uint len = uint(strlen( m_str )); - - if( m_size < len + slen + 1 ) { - m_size = len + slen + 1; - m_str = strReAlloc(m_str, m_size); - } - - strCat( m_str, m_size, s ); - } - - return *this; -} - - -/** Append a formatted string. */ -StringBuilder & StringBuilder::appendFormat( const char * format, ... ) -{ - nvDebugCheck( format != NULL ); - - va_list arg; - va_start( arg, format ); - - appendFormat( format, arg ); - - va_end( arg ); - - return *this; -} - - -/** Append a formatted string. */ -StringBuilder & StringBuilder::appendFormat( const char * format, va_list arg ) -{ - nvDebugCheck( format != NULL ); - - va_list tmp; - va_copy(tmp, arg); - - StringBuilder tmp_str; - tmp_str.format( format, tmp ); - append( tmp_str ); - - va_end(tmp); - - return *this; -} - - -/** Convert number to string in the given base. */ -StringBuilder & StringBuilder::number( int i, int base ) -{ - nvCheck( base >= 2 ); - nvCheck( base <= 36 ); - - // @@ This needs to be done correctly. - // length = floor(log(i, base)); - uint len = uint(log(float(i)) / log(float(base)) + 2); // one more if negative - reserve(len); - - if( i < 0 ) { - *m_str = '-'; - *i2a(uint(-i), m_str+1, base) = 0; - } - else { - *i2a(i, m_str, base) = 0; - } - - return *this; -} - - -/** Convert number to string in the given base. */ -StringBuilder & StringBuilder::number( uint i, int base ) -{ - nvCheck( base >= 2 ); - nvCheck( base <= 36 ); - - // @@ This needs to be done correctly. - // length = floor(log(i, base)); - uint len = uint(log(float(i)) / log(float(base)) - 0.5f + 1); - reserve(len); - - *i2a(i, m_str, base) = 0; - - return *this; -} - - -/** Resize the string preserving the contents. */ -StringBuilder & StringBuilder::reserve( uint size_hint ) -{ - nvCheck(size_hint != 0); - if( size_hint > m_size ) { - m_str = strReAlloc(m_str, size_hint); - m_size = size_hint; - } - return *this; -} - - -/** Copy a string safely. */ -StringBuilder & StringBuilder::copy( const char * s ) -{ - nvCheck( s != NULL ); - uint str_size = uint(strlen( s )) + 1; - reserve(str_size); - strCpy( m_str, str_size, s ); - return *this; -} - - -/** Copy an StringBuilder. */ -StringBuilder & StringBuilder::copy( const StringBuilder & s ) -{ - if( s.m_str == NULL ) { - nvCheck( s.m_size == 0 ); - m_size = 0; - strFree( m_str ); - m_str = NULL; - } - else { - reserve( s.m_size ); - strCpy( m_str, s.m_size, s.m_str ); - } - return *this; -} - -/** Reset the string. */ -void StringBuilder::reset() -{ - m_size = 0; - strFree( m_str ); - m_str = NULL; -} - - -/// Get the file name from a path. -const char * Path::fileName() const -{ - return fileName(m_str); -} - - -/// Get the extension from a file path. -const char * Path::extension() const -{ - return extension(m_str); -} - - -/// Toggles path separators (ie. \\ into /). -void Path::translatePath() -{ - nvCheck( m_str != NULL ); - - for(int i = 0; ; i++) { - if( m_str[i] == '\0' ) break; -#if NV_PATH_SEPARATOR == '/' - if( m_str[i] == '\\' ) m_str[i] = NV_PATH_SEPARATOR; -#else - if( m_str[i] == '/' ) m_str[i] = NV_PATH_SEPARATOR; -#endif - } -} - - -/** - * Strip the file name from a path. - * @warning path cannot end with '/' o '\\', can't it? - */ -void Path::stripFileName() -{ - nvCheck( m_str != NULL ); - - int length = (int)strlen(m_str) - 1; - while (length > 0 && m_str[length] != '/' && m_str[length] != '\\'){ - length--; - } - if( length ) { - m_str[length+1] = 0; - } - else { - m_str[0] = 0; - } -} - - -/// Strip the extension from a path name. -void Path::stripExtension() -{ - nvCheck( m_str != NULL ); - - int length = (int)strlen(m_str) - 1; - while( length > 0 && m_str[length] != '.' ) { - length--; - if( m_str[length] == NV_PATH_SEPARATOR ) { - return; // no extension - } - } - if( length ) { - m_str[length] = 0; - } -} - - -/// Get the path separator. -// static -char Path::separator() -{ - return NV_PATH_SEPARATOR; -} - -// static -const char * Path::fileName(const char * str) -{ - nvCheck( str != NULL ); - - int length = (int)strlen(str) - 1; - while( length >= 0 && str[length] != separator() ) { - length--; - } - - return &str[length+1]; -} - -// static -const char * Path::extension(const char * str) -{ - nvCheck( str != NULL ); - - int length, l; - l = length = (int)strlen( str ); - while( length > 0 && str[length] != '.' ) { - length--; - if( str[length] == separator() ) { - return &str[l]; // no extension - } - } - if( length == 0 ) { - return &str[l]; - } - return &str[length]; -} - - - -/// Clone this string -String String::clone() const -{ - String str(data); - return str; -} - -void String::setString(const char * str) -{ - if (str == NULL) { - data = NULL; - } - else { - allocString( str ); - addRef(); - } -} - -void String::setString(const char * str, int length) -{ - nvDebugCheck(str != NULL); - - allocString(str, length); - addRef(); -} - -void String::setString(const StringBuilder & str) -{ - if (str.str() == NULL) { - data = NULL; - } - else { - allocString(str); - addRef(); - } -} diff --git a/Externals/NVTT/src/nvcore/StrLib.h b/Externals/NVTT/src/nvcore/StrLib.h deleted file mode 100644 index 80122714e84..00000000000 --- a/Externals/NVTT/src/nvcore/StrLib.h +++ /dev/null @@ -1,355 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_STRING_H -#define NV_CORE_STRING_H - -#include -#include // swap - -#include // strlen, strcmp, etc. - - -namespace nv -{ - - uint strHash(const char * str, uint h) NV_PURE; - - /// String hash based on Bernstein's hash. - inline uint strHash(const char * data, uint h = 5381) - { - uint i = 0; - while(data[i] != 0) { - h = (33 * h) ^ uint(data[i]); - i++; - } - return h; - } - - template <> struct hash { - uint operator()(const char * str) const { return strHash(str); } - }; - - NVCORE_API int strCaseCmp(const char * s1, const char * s2) NV_PURE; - NVCORE_API int strCmp(const char * s1, const char * s2) NV_PURE; - NVCORE_API void strCpy(char * dst, int size, const char * src); - NVCORE_API void strCpy(char * dst, int size, const char * src, int len); - NVCORE_API void strCat(char * dst, int size, const char * src); - - NVCORE_API bool strMatch(const char * str, const char * pat) NV_PURE; - - - /// String builder. - class NVCORE_CLASS StringBuilder - { - public: - - StringBuilder(); - explicit StringBuilder( int size_hint ); - StringBuilder( const char * str ); - StringBuilder( const StringBuilder & ); - - ~StringBuilder(); - - StringBuilder & format( const char * format, ... ) __attribute__((format (printf, 2, 3))); - StringBuilder & format( const char * format, va_list arg ); - - StringBuilder & append( const char * str ); - StringBuilder & appendFormat( const char * format, ... ) __attribute__((format (printf, 2, 3))); - StringBuilder & appendFormat( const char * format, va_list arg ); - - StringBuilder & number( int i, int base = 10 ); - StringBuilder & number( uint i, int base = 10 ); - - StringBuilder & reserve( uint size_hint ); - StringBuilder & copy( const char * str ); - StringBuilder & copy( const StringBuilder & str ); - - StringBuilder & toLower(); - StringBuilder & toUpper(); - - void reset(); - bool isNull() const { return m_size == 0; } - - // const char * accessors - operator const char * () const { return m_str; } - operator char * () { return m_str; } - const char * str() const { return m_str; } - char * str() { return m_str; } - - /// Implement value semantics. - StringBuilder & operator=( const StringBuilder & s ) { - return copy(s); - } - - /// Implement value semantics. - StringBuilder & operator=( const char * s ) { - return copy(s); - } - - /// Equal operator. - bool operator==( const StringBuilder & s ) const { - if (s.isNull()) return isNull(); - else if (isNull()) return false; - else return strcmp(s.m_str, m_str) != 0; - } - - /// Return the exact length. - uint length() const { return isNull() ? 0 : uint(strlen(m_str)); } - - /// Return the size of the string container. - uint capacity() const { return m_size; } - - /// Return the hash of the string. - uint hash() const { return isNull() ? 0 : strHash(m_str); } - - /// Swap strings. - friend void swap(StringBuilder & a, StringBuilder & b) { - nv::swap(a.m_size, b.m_size); - nv::swap(a.m_str, b.m_str); - } - - protected: - - /// Size of the string container. - uint m_size; - - /// String. - char * m_str; - - }; - - - /// Path string. @@ This should be called PathBuilder. - class NVCORE_CLASS Path : public StringBuilder - { - public: - Path() : StringBuilder() {} - explicit Path(int size_hint) : StringBuilder(size_hint) {} - Path(const char * str) : StringBuilder(str) {} - Path(const Path & path) : StringBuilder(path) {} - - const char * fileName() const; - const char * extension() const; - - void translatePath(); - - void stripFileName(); - void stripExtension(); - - // statics - NVCORE_API static char separator(); - NVCORE_API static const char * fileName(const char *); - NVCORE_API static const char * extension(const char *); - }; - - - /// String class. - class NVCORE_CLASS String - { - public: - - /// Constructs a null string. @sa isNull() - String() - { - data = NULL; - } - - /// Constructs a shared copy of str. - String(const String & str) - { - data = str.data; - if (data != NULL) addRef(); - } - - /// Constructs a shared string from a standard string. - String(const char * str) - { - setString(str); - } - - /// Constructs a shared string from a standard string. - String(const char * str, int length) - { - setString(str, length); - } - - /// Constructs a shared string from a StringBuilder. - String(const StringBuilder & str) - { - setString(str); - } - - /// Dtor. - ~String() - { - release(); - } - - String clone() const; - - /// Release the current string and allocate a new one. - const String & operator=( const char * str ) - { - release(); - setString( str ); - return *this; - } - - /// Release the current string and allocate a new one. - const String & operator=( const StringBuilder & str ) - { - release(); - setString( str ); - return *this; - } - - /// Implement value semantics. - String & operator=( const String & str ) - { - if (str.data != data) - { - release(); - data = str.data; - addRef(); - } - return *this; - } - - /// Equal operator. - bool operator==( const String & str ) const - { - if( str.data == data ) { - return true; - } - if ((data == NULL) != (str.data == NULL)) { - return false; - } - return strcmp(data, str.data) == 0; - } - - /// Equal operator. - bool operator==( const char * str ) const - { - nvCheck(str != NULL); // Use isNull! - if (data == NULL) { - return false; - } - return strcmp(data, str) == 0; - } - - /// Not equal operator. - bool operator!=( const String & str ) const - { - if( str.data == data ) { - return false; - } - if ((data == NULL) != (str.data == NULL)) { - return true; - } - return strcmp(data, str.data) != 0; - } - - /// Not equal operator. - bool operator!=( const char * str ) const - { - nvCheck(str != NULL); // Use isNull! - if (data == NULL) { - return false; - } - return strcmp(data, str) != 0; - } - - /// Returns true if this string is the null string. - bool isNull() const { return data == NULL; } - - /// Return the exact length. - uint length() const { nvDebugCheck(data != NULL); return uint(strlen(data)); } - - /// Return the hash of the string. - uint hash() const { nvDebugCheck(data != NULL); return strHash(data); } - - /// const char * cast operator. - operator const char * () const { return data; } - - /// Get string pointer. - const char * str() const { return data; } - - - private: - - // Add reference count. - void addRef() - { - if (data != NULL) - { - setRefCount(getRefCount() + 1); - } - } - - // Decrease reference count. - void release() - { - if (data != NULL) - { - const uint16 count = getRefCount(); - setRefCount(count - 1); - if (count - 1 == 0) { - mem::free(data - 2); - data = NULL; - } - } - } - - uint16 getRefCount() const - { - nvDebugCheck(data != NULL); - return *reinterpret_cast(data - 2); - } - - void setRefCount(uint16 count) { - nvDebugCheck(data != NULL); - nvCheck(count < 0xFFFF); - *reinterpret_cast(const_cast(data - 2)) = uint16(count); - } - - void setData(const char * str) { - data = str + 2; - } - - void allocString(const char * str) - { - allocString(str, (int)strlen(str)); - } - - void allocString(const char * str, int len) - { - const char * ptr = static_cast(mem::malloc(2 + len + 1)); - - setData( ptr ); - setRefCount( 0 ); - - // Copy string. - strCpy(const_cast(data), len+1, str, len); - - // Add terminating character. - const_cast(data)[len] = '\0'; - } - - void setString(const char * str); - void setString(const char * str, int length); - void setString(const StringBuilder & str); - - /// Swap strings. - friend void swap(String & a, String & b) { - swap(a.data, b.data); - } - - private: - - const char * data; - - }; - -} // nv namespace - -#endif // NV_CORE_STRING_H diff --git a/Externals/NVTT/src/nvcore/Stream.h b/Externals/NVTT/src/nvcore/Stream.h deleted file mode 100644 index 4a35120f6b2..00000000000 --- a/Externals/NVTT/src/nvcore/Stream.h +++ /dev/null @@ -1,160 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NVCORE_STREAM_H -#define NVCORE_STREAM_H - -#include -#include - -namespace nv -{ - -/// Base stream class. -class NVCORE_CLASS Stream { -public: - - enum ByteOrder { - LittleEndian = false, - BigEndian = true, - }; - - /// Get the byte order of the system. - static ByteOrder getSystemByteOrder() { -# if NV_LITTLE_ENDIAN - return LittleEndian; -# else - return BigEndian; -# endif - } - - - /// Ctor. - Stream() : m_byteOrder(LittleEndian) { } - - /// Virtual destructor. - virtual ~Stream() {} - - /// Set byte order. - void setByteOrder(ByteOrder bo) { m_byteOrder = bo; } - - /// Get byte order. - ByteOrder byteOrder() const { return m_byteOrder; } - - - /// Serialize the given data. - virtual uint serialize( void * data, uint len ) = 0; - - /// Move to the given position in the archive. - virtual void seek( uint pos ) = 0; - - /// Return the current position in the archive. - virtual uint tell() const = 0; - - /// Return the current size of the archive. - virtual uint size() const = 0; - - /// Determine if there has been any error. - virtual bool isError() const = 0; - - /// Clear errors. - virtual void clearError() = 0; - - /// Return true if the stream is at the end. - virtual bool isAtEnd() const = 0; - - /// Return true if the stream is seekable. - virtual bool isSeekable() const = 0; - - /// Return true if this is an input stream. - virtual bool isLoading() const = 0; - - /// Return true if this is an output stream. - virtual bool isSaving() const = 0; - - - // friends - friend Stream & operator<<( Stream & s, bool & c ) { -# if NV_OS_DARWIN - nvStaticCheck(sizeof(bool) == 4); - uint8 b = c ? 1 : 0; - s.serialize( &b, 1 ); - c = (b == 1); -# else - nvStaticCheck(sizeof(bool) == 1); - s.serialize( &c, 1 ); -# endif - return s; - } - friend Stream & operator<<( Stream & s, char & c ) { - nvStaticCheck(sizeof(char) == 1); - s.serialize( &c, 1 ); - return s; - } - friend Stream & operator<<( Stream & s, uint8 & c ) { - nvStaticCheck(sizeof(uint8) == 1); - s.serialize( &c, 1 ); - return s; - } - friend Stream & operator<<( Stream & s, int8 & c ) { - nvStaticCheck(sizeof(int8) == 1); - s.serialize( &c, 1 ); - return s; - } - friend Stream & operator<<( Stream & s, uint16 & c ) { - nvStaticCheck(sizeof(uint16) == 2); - return s.byteOrderSerialize( &c, 2 ); - } - friend Stream & operator<<( Stream & s, int16 & c ) { - nvStaticCheck(sizeof(int16) == 2); - return s.byteOrderSerialize( &c, 2 ); - } - friend Stream & operator<<( Stream & s, uint32 & c ) { - nvStaticCheck(sizeof(uint32) == 4); - return s.byteOrderSerialize( &c, 4 ); - } - friend Stream & operator<<( Stream & s, int32 & c ) { - nvStaticCheck(sizeof(int32) == 4); - return s.byteOrderSerialize( &c, 4 ); - } - friend Stream & operator<<( Stream & s, uint64 & c ) { - nvStaticCheck(sizeof(uint64) == 8); - return s.byteOrderSerialize( &c, 8 ); - } - friend Stream & operator<<( Stream & s, int64 & c ) { - nvStaticCheck(sizeof(int64) == 8); - return s.byteOrderSerialize( &c, 8 ); - } - friend Stream & operator<<( Stream & s, float & c ) { - nvStaticCheck(sizeof(float) == 4); - return s.byteOrderSerialize( &c, 4 ); - } - friend Stream & operator<<( Stream & s, double & c ) { - nvStaticCheck(sizeof(double) == 8); - return s.byteOrderSerialize( &c, 8 ); - } - -protected: - - /// Serialize in the stream byte order. - Stream & byteOrderSerialize( void * v, uint len ) { - if( m_byteOrder == getSystemByteOrder() ) { - serialize( v, len ); - } - else { - for( uint i = len; i > 0; i-- ) { - serialize( (uint8 *)v + i - 1, 1 ); - } - } - return *this; - } - - -private: - - ByteOrder m_byteOrder; - -}; - -} // nv namespace - -#endif // NV_STREAM_H diff --git a/Externals/NVTT/src/nvcore/TextReader.cpp b/Externals/NVTT/src/nvcore/TextReader.cpp deleted file mode 100644 index 8eb74612a56..00000000000 --- a/Externals/NVTT/src/nvcore/TextReader.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -using namespace nv; - -/// Peek next character. -char TextReader::peek() -{ - nvDebugCheck(m_stream != NULL); - nvDebugCheck(m_stream->isSeekable()); - - if (m_stream->isAtEnd()) { - return 0; - } - - uint pos = m_stream->tell(); - - char c; - m_stream->serialize(&c, 1); - m_stream->seek(pos); - return c; -} - -/// Read a single char. -char TextReader::read() -{ - nvDebugCheck(m_stream != NULL); - - char c; - m_stream->serialize(&c, 1); - - if( m_stream->isAtEnd() ) { - return 0; - } - - return c; -} - -/// Read from the current location to the end of the stream. -const char * TextReader::readToEnd() -{ - nvDebugCheck(m_stream != NULL); - const int size = m_stream->size(); - - m_text.clear(); - - m_text.reserve(size + 1); - m_text.resize(size); - - m_stream->serialize(m_text.unsecureBuffer(), size); - m_text.pushBack('\0'); - - return m_text.buffer(); -} - -/// Read from the current location to the end of the line. -const char * TextReader::readLine() -{ - m_text.clear(); - - if (m_stream->isAtEnd()) { - return NULL; - } - - while (true) { - char c = read(); - - if (c == 0 || c == '\n') { - break; - } - else if (c == '\r') { - if( peek() == '\n' ) { - read(); - } - break; - } - - m_text.pushBack(c); - } - - m_text.pushBack('\0'); - return m_text.buffer(); -} - - diff --git a/Externals/NVTT/src/nvcore/TextReader.h b/Externals/NVTT/src/nvcore/TextReader.h deleted file mode 100644 index b3d6d374043..00000000000 --- a/Externals/NVTT/src/nvcore/TextReader.h +++ /dev/null @@ -1,38 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NVCORE_TEXTREADER_H -#define NVCORE_TEXTREADER_H - -#include -#include -#include - -namespace nv -{ - -/// Text reader. -class NVCORE_CLASS TextReader { -public: - - /// Ctor. - TextReader(Stream * stream) : m_stream(stream), m_text(512) { - nvCheck(stream != NULL); - nvCheck(stream->isLoading()); - } - - char peek(); - char read(); - - const char *readToEnd(); - - // Returns a temporary string. - const char * readLine(); - -private: - Stream * m_stream; - Array m_text; -}; - -} // nv namespace - -#endif // NVCORE_TEXTREADER_H diff --git a/Externals/NVTT/src/nvcore/TextWriter.cpp b/Externals/NVTT/src/nvcore/TextWriter.cpp deleted file mode 100644 index f5e1783a44c..00000000000 --- a/Externals/NVTT/src/nvcore/TextWriter.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -using namespace nv; - - -/// Constructor -TextWriter::TextWriter(Stream * s) : - s(s), - str(1024) -{ - nvCheck(s != NULL); - nvCheck(s->isSaving()); -} - -void TextWriter::writeString(const char * str) -{ - nvDebugCheck(s != NULL); - s->serialize(const_cast(str), (int)strlen(str)); -} - -void TextWriter::writeString(const char * str, uint len) -{ - nvDebugCheck(s != NULL); - s->serialize(const_cast(str), len); -} - -void TextWriter::write(const char * format, ...) -{ - va_list arg; - va_start(arg,format); - str.format(format, arg); - writeString(str.str(), str.length()); - va_end(arg); -} - -void TextWriter::write(const char * format, va_list arg) -{ - va_list tmp; - va_copy(tmp, arg); - str.format(format, arg); - writeString(str.str(), str.length()); - va_end(tmp); -} diff --git a/Externals/NVTT/src/nvcore/TextWriter.h b/Externals/NVTT/src/nvcore/TextWriter.h deleted file mode 100644 index 155373cfd02..00000000000 --- a/Externals/NVTT/src/nvcore/TextWriter.h +++ /dev/null @@ -1,65 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NVCORE_TEXTWRITER_H -#define NVCORE_TEXTWRITER_H - -#include -#include -#include - -namespace nv -{ - - /// Text writer. - class NVCORE_CLASS TextWriter - { - public: - - TextWriter(Stream * s); - - void writeString(const char * str); - void writeString(const char * str, uint len); - void write(const char * format, ...) __attribute__((format (printf, 2, 3))); - void write(const char * format, va_list arg); - - private: - - Stream * s; - - // Temporary string. - StringBuilder str; - - }; - - - inline TextWriter & operator<<( TextWriter & tw, int i) - { - tw.write("%d", i); - return tw; - } - - inline TextWriter & operator<<( TextWriter & tw, uint i) - { - tw.write("%u", i); - return tw; - } - - inline TextWriter & operator<<( TextWriter & tw, float f) - { - tw.write("%f", f); - return tw; - } - - inline TextWriter & operator<<( TextWriter & tw, const char * str) - { - tw.writeString(str); - return tw; - } - -} // nv namespace - - - - - -#endif // NVCORE_TEXTWRITER_H diff --git a/Externals/NVTT/src/nvcore/Tokenizer.cpp b/Externals/NVTT/src/nvcore/Tokenizer.cpp deleted file mode 100644 index a7b55de45db..00000000000 --- a/Externals/NVTT/src/nvcore/Tokenizer.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include - -#include // vsscanf -#include // va_list -#include // atof, atoi - -#if NV_CC_MSVC -#if 0 // This doesn't work on MSVC for x64 -/* vsscanf for Win32 - * Written 5/2003 by - * This code is in the Public Domain - */ - -#include // alloca - - -static int vsscanf(const char * buffer, const char * format, va_list argPtr) -{ - // Get an upper bound for the # of args - size_t count = 0; - const char *p = format; - while(1) { - char c = *(p++); - if(c==0) break; - if(c=='%' && (p[0]!='*' && p[0]!='%')) ++count; - } - - // Make a local stack - size_t stackSize = (2+count)*sizeof(void*); - void **newStack = (void**)alloca(stackSize); - - // Fill local stack the way sscanf likes it - newStack[0] = (void*)buffer; - newStack[1] = (void*)format; - memcpy(newStack+2, argPtr, count*sizeof(void*)); - - // @@ Use: CALL DWORD PTR [sscanf] - - // Warp into system sscanf with new stack - int result; - void *savedESP; - __asm - { - mov savedESP, esp - mov esp, newStack -#if _MSC_VER >= 1400 - call DWORD PTR [sscanf_s] -#else - call DWORD PTR [sscanf] -#endif - mov esp, savedESP - mov result, eax - } - return result; -} -#endif -#endif - -using namespace nv; - -Token::Token() : - m_str(""), m_len(0) -{ -} - -Token::Token(const Token & token) : - m_str(token.m_str), m_len(token.m_len) -{ -} - -Token::Token(const char * str, int len) : - m_str(str), m_len(len) -{ -} - -bool Token::operator==(const char * str) const -{ - return strncmp(m_str, str, m_len) == 0; -} -bool Token::operator!=(const char * str) const -{ - return strncmp(m_str, str, m_len) != 0; -} - -bool Token::isNull() -{ - return m_len != 0; -} - -float Token::toFloat() const -{ - return float(atof(m_str)); -} - -int Token::toInt() const -{ - return atoi(m_str); -} - -uint Token::toUnsignedInt() const -{ - // @@ TBD - return uint(atoi(m_str)); -} - -String Token::toString() const -{ - return String(m_str, m_len); -} - -bool Token::parse(const char * format, int count, ...) const -{ - va_list arg; - va_start(arg, count); - - int readCount = vsscanf(m_str, format, arg); - - va_end(arg); - - return readCount == count; -} - - -Tokenizer::Tokenizer(Stream * stream) : - m_reader(stream), m_lineNumber(0), m_columnNumber(0), m_delimiters("{}()="), m_spaces(" \t") -{ -} - -bool Tokenizer::nextLine(bool skipEmptyLines /*= true*/) -{ - do { - if (!readLine()) { - return false; - } - } - while (!readToken() && skipEmptyLines); - - return true; -} - -bool Tokenizer::nextToken(bool skipEndOfLine /*= false*/) -{ - if (!readToken()) { - if (!skipEndOfLine) { - return false; - } - else { - return nextLine(true); - } - } - return true; -} - -bool Tokenizer::readToken() -{ - skipSpaces(); - - const char * begin = m_line + m_columnNumber; - - if (*begin == '\0') { - return false; - } - - char c = readChar(); - if (isDelimiter(c)) { - m_token = Token(begin, 1); - return true; - } - - // @@ Add support for quoted tokens "", '' - - int len = 0; - while (!isDelimiter(c) && !isSpace(c) && c != '\0') { - c = readChar(); - len++; - } - m_columnNumber--; - - m_token = Token(begin, len); - - return true; -} - -char Tokenizer::readChar() -{ - return m_line[m_columnNumber++]; -} - -bool Tokenizer::readLine() -{ - m_lineNumber++; - m_columnNumber = 0; - m_line = m_reader.readLine(); - return m_line != NULL; -} - -void Tokenizer::skipSpaces() -{ - while (isSpace(readChar())) {} - m_columnNumber--; -} - -bool Tokenizer::isSpace(char c) -{ - uint i = 0; - while (m_spaces[i] != '\0') { - if (c == m_spaces[i]) { - return true; - } - i++; - } - return false; -} - -bool Tokenizer::isDelimiter(char c) -{ - uint i = 0; - while (m_delimiters[i] != '\0') { - if (c == m_delimiters[i]) { - return true; - } - i++; - } - return false; -} - diff --git a/Externals/NVTT/src/nvcore/Tokenizer.h b/Externals/NVTT/src/nvcore/Tokenizer.h deleted file mode 100644 index 48579c88f37..00000000000 --- a/Externals/NVTT/src/nvcore/Tokenizer.h +++ /dev/null @@ -1,99 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_TOKENIZER_H -#define NV_CORE_TOKENIZER_H - -#include -#include -#include -#include - -namespace nv -{ - /// A token produced by the Tokenizer. - class NVCORE_CLASS Token - { - public: - Token(); - Token(const Token & token); - Token(const char * str, int len); - - bool operator==(const char * str) const; - bool operator!=(const char * str) const; - - bool isNull(); - - float toFloat() const; - int toInt() const; - uint toUnsignedInt() const; - String toString() const; - - bool parse(const char * format, int count, ...) const __attribute__((format (scanf, 2, 4))); - - private: - const char * m_str; - int m_len; - }; - - /// Exception thrown by the tokenizer. - class TokenizerException - { - public: - TokenizerException(int line, int column) : m_line(line), m_column(column) {} - - int line() const { return m_line; } - int column() const { return m_column; } - - private: - int m_line; - int m_column; - }; - - // @@ Use enums instead of bools for clarity! - //enum SkipEmptyLines { skipEmptyLines, noSkipEmptyLines }; - //enum SkipEndOfLine { skipEndOfLine, noSkipEndOfLine }; - - /// A simple stream tokenizer. - class NVCORE_CLASS Tokenizer - { - public: - Tokenizer(Stream * stream); - - bool nextLine(bool skipEmptyLines = true); - bool nextToken(bool skipEndOfLine = false); - - const Token & token() const { return m_token; } - - int lineNumber() const { return m_lineNumber; } - int columnNumber() const { return m_columnNumber; } - - void setDelimiters(const char * str) { m_delimiters = str; } - const char * delimiters() const { return m_delimiters; } - - void setSpaces(const char * str) { m_spaces = str; } - const char * spaces() const { return m_spaces; } - - private: - char readChar(); - bool readLine(); - bool readToken(); - void skipSpaces(); - bool isSpace(char c); - bool isDelimiter(char c); - - private: - TextReader m_reader; - const char * m_line; - Token m_token; - - int m_lineNumber; - int m_columnNumber; - - const char * m_delimiters; - const char * m_spaces; - }; - -} // nv namespace - - -#endif // NV_CORE_TOKENIZER_H diff --git a/Externals/NVTT/src/nvcore/nvcore.h b/Externals/NVTT/src/nvcore/nvcore.h deleted file mode 100644 index 469f6adb4dd..00000000000 --- a/Externals/NVTT/src/nvcore/nvcore.h +++ /dev/null @@ -1,172 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_CORE_H -#define NV_CORE_H - -// cmake config -#include - -// Function linkage -#if NVCORE_SHARED -#ifdef NVCORE_EXPORTS -#define NVCORE_API DLL_EXPORT -#define NVCORE_CLASS DLL_EXPORT_CLASS -#else -#define NVCORE_API DLL_IMPORT -#define NVCORE_CLASS DLL_IMPORT -#endif -#else // NVCORE_SHARED -#define NVCORE_API -#define NVCORE_CLASS -#endif // NVCORE_SHARED - - -// Platform definitions -#include "poshlib/posh.h" - -// OS: -// NV_OS_WIN32 -// NV_OS_WIN64 -// NV_OS_MINGW -// NV_OS_CYGWIN -// NV_OS_LINUX -// NV_OS_UNIX -// NV_OS_DARWIN - -#define NV_OS_STRING POSH_OS_STRING - -#if defined POSH_OS_LINUX -# define NV_OS_LINUX 1 -# define NV_OS_UNIX 1 -#elif defined POSH_OS_CYGWIN32 -# define NV_OS_CYGWIN 1 -#elif defined POSH_OS_MINGW -# define NV_OS_MINGW 1 -# define NV_OS_WIN32 1 -#elif defined POSH_OS_OSX -# define NV_OS_DARWIN 1 -# define NV_OS_UNIX 1 -#elif defined POSH_OS_UNIX -# define NV_OS_UNIX 1 -#elif defined POSH_OS_WIN32 -# define NV_OS_WIN32 1 -#elif defined POSH_OS_WIN64 -# define NV_OS_WIN64 1 -#else -# error "Unsupported OS" -#endif - - -// CPUs: -// NV_CPU_X86 -// NV_CPU_X86_64 -// NV_CPU_PPC - -#define NV_CPU_STRING POSH_CPU_STRING - -#if defined POSH_CPU_X86_64 -# define NV_CPU_X86_64 1 -#elif defined POSH_CPU_X86 -# define NV_CPU_X86 1 -#elif defined POSH_CPU_PPC -# define NV_CPU_PPC 1 -#else -# error "Unsupported CPU" -#endif - - -// Compiler: -// NV_CC_GNUC -// NV_CC_MSVC -// @@ NV_CC_MSVC6 -// @@ NV_CC_MSVC7 -// @@ NV_CC_MSVC8 - -#if defined POSH_COMPILER_GCC -# define NV_CC_GNUC 1 -# define NV_CC_STRING "gcc" -#elif defined POSH_COMPILER_MSVC -# define NV_CC_MSVC 1 -# define NV_CC_STRING "msvc" -#else -# error "Unsupported compiler" -#endif - - -// Endiannes: -#define NV_LITTLE_ENDIAN POSH_LITTLE_ENDIAN -#define NV_BIG_ENDIAN POSH_BIG_ENDIAN -#define NV_ENDIAN_STRING POSH_ENDIAN_STRING - - -// Version string: -#define NV_VERSION_STRING \ - NV_OS_STRING "/" NV_CC_STRING "/" NV_CPU_STRING"/" \ - NV_ENDIAN_STRING"-endian - " __DATE__ "-" __TIME__ - - -/// Disable copy constructor and assignment operator. -/// @hideinitializer -#define NV_FORBID_COPY(C) \ - private: \ - C( const C & ); \ - C &operator=( const C & ); - - -/// Disable dynamic allocation on the heap. -/// See Prohibiting Heap-Based Objects in More Effective C++. -/// @hideinitializer -#define NV_FORBID_HEAPALLOC() \ - private: \ - static void *operator new(size_t size); \ - static void *operator new[](size_t size); - -// String concatenation macros. -#define NV_STRING_JOIN2(arg1, arg2) NV_DO_STRING_JOIN2(arg1, arg2) -#define NV_DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2 -#define NV_STRING_JOIN3(arg1, arg2, arg3) NV_DO_STRING_JOIN3(arg1, arg2, arg3) -#define NV_DO_STRING_JOIN3(arg1, arg2, arg3) arg1 ## arg2 ## arg3 - -// Startup initialization macro. -#define NV_AT_STARTUP(some_code) \ - namespace { \ - static struct NV_STRING_JOIN2(AtStartup_, __LINE__) { \ - NV_STRING_JOIN2(AtStartup_, __LINE__)() { some_code; } \ - } \ - NV_STRING_JOIN3(AtStartup_, __LINE__, Instance); \ - }; - -/// Indicate the compiler that the parameter is not used to suppress compier warnings. -/// @hideinitializer -#define NV_UNUSED(a) ((a)=(a)) - -/// Null index. @@ Move this somewhere else... This could have collisions with other definitions! -#define NIL uint(~0) - -/// Null pointer. -#ifndef NULL -#define NULL 0 -#endif - -// Platform includes -#if NV_CC_MSVC -# if NV_OS_WIN32 -# include "DefsVcWin32.h" -# else -# error "MSVC: Platform not supported" -# endif -#elif NV_CC_GNUC -# if NV_OS_LINUX -# include "DefsGnucLinux.h" -# elif NV_OS_DARWIN -# include "DefsGnucDarwin.h" -# elif NV_OS_MINGW -# include "DefsGnucWin32.h" -# elif NV_OS_CYGWIN -# error "GCC: Cygwin not supported" -# else -# error "GCC: Platform not supported" -# endif -#endif - -#endif // NV_CORE_H diff --git a/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt b/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt deleted file mode 100644 index 1b8d4e37e2d..00000000000 --- a/Externals/NVTT/src/nvcore/poshlib/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_library(posh STATIC) - -target_sources(posh PRIVATE - posh.c - posh.h -) diff --git a/Externals/NVTT/src/nvcore/poshlib/posh.c b/Externals/NVTT/src/nvcore/poshlib/posh.c deleted file mode 100644 index bd3fcc66ea2..00000000000 --- a/Externals/NVTT/src/nvcore/poshlib/posh.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* -LICENSE: - -Copyright (c) 2004, Brian Hook -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of this package'ss contributors contributors may not - be used to endorse or promote products derived from this - software without specific prior written permission. - - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/** - @file posh.c - @author Brian Hook - @date 2002 - @brief Portable Open Source Harness primary source file -*/ -#include "posh.h" - -#if !defined FORCE_DOXYGEN - -#if !defined POSH_NO_FLOAT -# define POSH_FLOAT_STRING "enabled" -#else -# define POSH_FLOAT_STRING "disabled" -#endif - -#if defined POSH_64BIT_INTEGER -# define POSH_64BIT_INTEGER_STRING "yes" -#else -# define POSH_64BIT_INTEGER_STRING "no" -#endif - -#if defined POSH_64BIT_POINTER -# define POSH_POINTER_STRING "64-bits" -#else -# define POSH_POINTER_STRING "32-bits" -#endif - -#if defined POSH_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 0 - -# define NATIVE16 POSH_LittleU16 -# define NATIVE32 POSH_LittleU32 -# define NATIVE64 POSH_LittleU64 -# define FOREIGN16 POSH_BigU16 -# define FOREIGN32 POSH_BigU32 -# define FOREIGN64 POSH_BigU64 -#else -# define IS_BIG_ENDIAN 1 - -# define NATIVE16 POSH_BigU16 -# define NATIVE32 POSH_BigU32 -# define NATIVE64 POSH_BigU64 -# define FOREIGN16 POSH_LittleU16 -# define FOREIGN32 POSH_LittleU32 -# define FOREIGN64 POSH_LittleU64 -#endif /* POSH_LITTLE_ENDIAN */ - -static -int -s_testBigEndian( void ) -{ - union - { - posh_byte_t c[ 4 ]; - posh_u32_t i; - } u; - - u.i= 1; - - if ( u.c[ 0 ] == 1 ) - { - return 0; - } - return 1; -} - -static -const char * -s_testSerialization( void ) -{ - posh_byte_t serbuf[ 8 ]; - posh_u16_t tmp16; - posh_u32_t tmp32; - - /* 16-bit serialization */ - POSH_WriteU16ToLittle( serbuf, 0xABCD ); - if ( ( tmp16 = POSH_ReadU16FromLittle( serbuf ) ) != 0xABCD ) - { - return "*ERROR: failed little-endian 16-bit serialization test"; - } - - POSH_WriteU16ToBig( serbuf, 0xABCD ); - if ( ( tmp16 = POSH_ReadU16FromBig( serbuf ) ) != 0xABCD ) - { - return "*ERROR: failed big-endian 16-bit serialization test"; - } - - /* 32-bit serialization */ - POSH_WriteU32ToLittle( serbuf, 0xABCD1234L ); - if ( ( tmp32 = POSH_ReadU32FromLittle( serbuf ) ) != 0xABCD1234 ) - { - return "*ERROR: failed little-endian 32-bit serialization test"; - } - - POSH_WriteU32ToBig( serbuf, 0xABCD1234L ); - if ( ( tmp32 = POSH_ReadU32FromBig( serbuf ) ) != 0xABCD1234 ) - { - return "*ERROR: failed big-endian 32-bit serialization test"; - } - -#if defined POSH_64BIT_INTEGER - { -#define REF64 POSH_U64(0xFEDCBA9876543210) - - posh_u64_t tmp64; - - POSH_WriteU64ToLittle( serbuf, REF64 ); - - if ( ( tmp64 = POSH_ReadU64FromLittle( serbuf ) ) != REF64 ) - { - return "*ERROR: failed little-endian 64-bit serialization test"; - } - - POSH_WriteU64ToBig( serbuf, REF64 ); - - if ( ( tmp64 = POSH_ReadU64FromBig( serbuf ) ) != REF64 ) - { - return "*ERROR: failed big-endian 64-bit serialization test"; - } - } -#endif - - return 0; -} - -#if !defined POSH_NO_FLOAT -static -const char * -s_testFloatingPoint( void ) -{ - float fRef = 10.0f/30.0f; - double dRef = 10.0/30.0; - posh_byte_t dbuf[ 8 ]; - float fTmp; - double dTmp; - - fTmp = POSH_FloatFromLittleBits( POSH_LittleFloatBits( fRef ) ); - - if ( fTmp != fRef ) - { - return "*ERROR: POSH little endian floating point conversion failed. Please report this to poshlib@poshlib.org!\n"; - } - - fTmp = POSH_FloatFromBigBits( POSH_BigFloatBits( fRef ) ); - if ( fTmp != fRef ) - { - return "*ERROR: POSH big endian floating point conversion failed. Please report this to poshlib@poshlib.org!\n"; - } - - POSH_DoubleBits( dRef, dbuf ); - - dTmp = POSH_DoubleFromBits( dbuf ); - - if ( dTmp != dRef ) - { - return "*ERROR: POSH double precision floating point serialization failed. Please report this to poshlib@poshlib.org!\n"; - } - - return 0; -} -#endif /* !defined POSH_NO_FLOAT */ - -static -const char * -s_testEndianess( void ) -{ - /* check endianess */ - if ( s_testBigEndian() != IS_BIG_ENDIAN ) - { - return "*ERROR: POSH compile time endianess does not match run-time endianess verification. Please report this to poshlib@poshlib.org!\n"; - } - - /* make sure our endian swap routines work */ - if ( ( NATIVE32( 0x11223344L ) != 0x11223344L ) || - ( FOREIGN32( 0x11223344L ) != 0x44332211L ) || - ( NATIVE16( 0x1234 ) != 0x1234 ) || - ( FOREIGN16( 0x1234 ) != 0x3412 ) ) - { - return "*ERROR: POSH endianess macro selection failed. Please report this to poshlib@poshlib.org!\n"; - } - - /* test serialization routines */ - - return 0; -} -#endif /* !defined FORCE_DOXYGEN */ - -/** - Returns a string describing this platform's basic attributes. - - POSH_GetArchString() reports on an architecture's statically determined - attributes. In addition, it will perform run-time verification checks - to make sure the various platform specific functions work. If an error - occurs, please contact me at poshlib@poshlib.org so we can try to resolve - what the specific failure case is. - @returns a string describing this platform on success, or a string in the - form "*ERROR: [text]" on failure. You can simply check to see if - the first character returned is '*' to verify an error condition. -*/ -const char * -POSH_GetArchString( void ) -{ - const char *err; - const char *s = "OS:.............."POSH_OS_STRING"\n" - "CPU:............."POSH_CPU_STRING"\n" - "endian:.........."POSH_ENDIAN_STRING"\n" - "ptr size:........"POSH_POINTER_STRING"\n" - "64-bit ints......"POSH_64BIT_INTEGER_STRING"\n" - "floating point..."POSH_FLOAT_STRING"\n" - "compiler........."POSH_COMPILER_STRING"\n"; - - /* test endianess */ - err = s_testEndianess(); - - if ( err != 0 ) - { - return err; - } - - /* test serialization */ - err = s_testSerialization(); - - if ( err != 0 ) - { - return err; - } - -#if !defined POSH_NO_FLOAT - /* check that our floating point support is correct */ - err = s_testFloatingPoint(); - - if ( err != 0 ) - { - return err; - } - -#endif - - return s; -} - -/* ---------------------------------------------------------------------------*/ -/* BYTE SWAPPING SUPPORT */ -/* ---------------------------------------------------------------------------*/ -/** - * Byte swaps a 16-bit unsigned value - * - @ingroup ByteSwapFunctions - @param v [in] unsigned 16-bit input value to swap - @returns a byte swapped version of v - */ -posh_u16_t -POSH_SwapU16( posh_u16_t v ) -{ - posh_u16_t swapped; - - swapped = v << 8; - swapped |= v >> 8; - - return swapped; -} - -/** - * Byte swaps a 16-bit signed value - * - @ingroup ByteSwapFunctions - @param v [in] signed 16-bit input value to swap - @returns a byte swapped version of v - @remarks This just calls back to the unsigned version, since byte swapping - is independent of sign. However, we still provide this function to - avoid signed/unsigned mismatch compiler warnings. - */ -posh_i16_t -POSH_SwapI16( posh_i16_t v ) -{ - return ( posh_i16_t ) POSH_SwapU16( v ); -} - -/** - * Byte swaps a 32-bit unsigned value - * - @ingroup ByteSwapFunctions - @param v [in] unsigned 32-bit input value to swap - @returns a byte swapped version of v - */ -posh_u32_t -POSH_SwapU32( posh_u32_t v ) -{ - posh_u32_t swapped; - - swapped = ( v & 0xFF ) << 24; - swapped |= ( v & 0xFF00 ) << 8; - swapped |= ( v >> 8 ) & 0xFF00; - swapped |= ( v >> 24 ); - - return swapped; -} - -/** - * Byte swaps a 32-bit signed value - * - @ingroup ByteSwapFunctions - @param v [in] signed 32-bit input value to swap - @returns a byte swapped version of v - @remarks This just calls back to the unsigned version, since byte swapping - is independent of sign. However, we still provide this function to - avoid signed/unsigned mismatch compiler warnings. - */ -posh_i32_t -POSH_SwapI32( posh_i32_t v ) -{ - return ( posh_i32_t ) POSH_SwapU32( ( posh_u32_t ) v ); -} - -#if defined POSH_64BIT_INTEGER -/** - * Byte swaps a 64-bit unsigned value - - @param v [in] a 64-bit input value to swap - @ingroup SixtyFourBit - @returns a byte swapped version of v -*/ -posh_u64_t -POSH_SwapU64( posh_u64_t v ) -{ - posh_byte_t tmp; - union { - posh_byte_t bytes[ 8 ]; - posh_u64_t u64; - } u; - - u.u64 = v; - - tmp = u.bytes[ 0 ]; u.bytes[ 0 ] = u.bytes[ 7 ]; u.bytes[ 7 ] = tmp; - tmp = u.bytes[ 1 ]; u.bytes[ 1 ] = u.bytes[ 6 ]; u.bytes[ 6 ] = tmp; - tmp = u.bytes[ 2 ]; u.bytes[ 2 ] = u.bytes[ 5 ]; u.bytes[ 5 ] = tmp; - tmp = u.bytes[ 3 ]; u.bytes[ 3 ] = u.bytes[ 4 ]; u.bytes[ 4 ] = tmp; - - return u.u64; -} - -/** - * Byte swaps a 64-bit signed value - - @param v [in] a 64-bit input value to swap - @ingroup SixtyFourBit - @returns a byte swapped version of v -*/ -posh_i64_t -POSH_SwapI64( posh_i64_t v ) -{ - return ( posh_i64_t ) POSH_SwapU64( ( posh_u64_t ) v ); -} - -#endif /* defined POSH_64BIT_INTEGER */ - -/* ---------------------------------------------------------------------------*/ -/* IN-MEMORY SERIALIZATION */ -/* ---------------------------------------------------------------------------*/ - -/** - * Writes an unsigned 16-bit value to a little endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL. Alignment doesn't matter. - @param value [in] host-endian unsigned 16-bit value - @returns a pointer to the location two bytes after dst - @remarks does no validation of the inputs -*/ -posh_u16_t * -POSH_WriteU16ToLittle( void *dst, posh_u16_t value ) -{ - posh_u16_t *p16 = ( posh_u16_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - - p[ 0 ] = value & 0xFF; - p[ 1 ] = ( value & 0xFF00) >> 8; - - return p16 + 1; -} - -/** - * Writes a signed 16-bit value to a little endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 16-bit value - @returns a pointer to the location two bytes after dst - @remarks does no validation of the inputs. This simply calls - POSH_WriteU16ToLittle() with appropriate casting. -*/ -posh_i16_t * -POSH_WriteI16ToLittle( void *dst, posh_i16_t value ) -{ - return ( posh_i16_t * ) POSH_WriteU16ToLittle( dst, ( posh_u16_t ) value ); -} - -/** - * Writes an unsigned 32-bit value to a little endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 32-bit value - @returns a pointer to the location four bytes after dst - @remarks does no validation of the inputs. -*/ -posh_u32_t * -POSH_WriteU32ToLittle( void *dst, posh_u32_t value ) -{ - posh_u32_t *p32 = ( posh_u32_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - - p[ 0 ] = ( value & 0xFF ); - p[ 1 ] = ( value & 0xFF00 ) >> 8; - p[ 2 ] = ( value & 0xFF0000 ) >> 16; - p[ 3 ] = ( value & 0xFF000000 ) >> 24; - - return p32 + 1; -} - -/** - * Writes a signed 32-bit value to a little endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 32-bit value - @returns a pointer to the location four bytes after dst - @remarks does no validation of the inputs. This simply calls - POSH_WriteU32ToLittle() with appropriate casting. -*/ -posh_i32_t * -POSH_WriteI32ToLittle( void *dst, posh_i32_t value ) -{ - return ( posh_i32_t * ) POSH_WriteU32ToLittle( dst, ( posh_u32_t ) value ); -} - -/** - * Writes an unsigned 16-bit value to a big endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian unsigned 16-bit value - @returns a pointer to the location two bytes after dst - @remarks does no validation of the inputs -*/ -posh_u16_t * -POSH_WriteU16ToBig( void *dst, posh_u16_t value ) -{ - posh_u16_t *p16 = ( posh_u16_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - - p[ 1 ] = ( value & 0xFF ); - p[ 0 ] = ( value & 0xFF00 ) >> 8; - - return p16 + 1; -} - -/** - * Writes a signed 16-bit value to a big endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 16-bit value - @returns a pointer to the location two bytes after dst - @remarks does no validation of the inputs. This simply calls - POSH_WriteU16ToLittle() with appropriate casting. -*/ -posh_i16_t * -POSH_WriteI16ToBig( void *dst, posh_i16_t value ) -{ - return ( posh_i16_t * ) POSH_WriteU16ToBig( dst, ( posh_u16_t ) value ); -} - -/** - * Writes an unsigned 32-bit value to a big endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian unsigned 32-bit value - @returns a pointer to the location four bytes after dst - @remarks does no validation of the inputs. -*/ -posh_u32_t * -POSH_WriteU32ToBig( void *dst, posh_u32_t value ) -{ - posh_u32_t *p32 = ( posh_u32_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - - p[ 3 ] = ( value & 0xFF ); - p[ 2 ] = ( value & 0xFF00 ) >> 8; - p[ 1 ] = ( value & 0xFF0000 ) >> 16; - p[ 0 ] = ( value & 0xFF000000 ) >> 24; - - return p32 + 1; -} - -/** - * Writes a signed 32-bit value to a big endian buffer - - @ingroup MemoryBuffer - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 32-bit value - @returns a pointer to the location four bytes after dst - @remarks does no validation of the inputs. This simply calls - POSH_WriteU32ToBig() with appropriate casting. -*/ -posh_i32_t * -POSH_WriteI32ToBig( void *dst, posh_i32_t value ) -{ - return ( posh_i32_t * ) POSH_WriteU32ToBig( dst, ( posh_u32_t ) value ); -} - -#if defined POSH_64BIT_INTEGER -/** - * Writes an unsigned 64-bit value to a little-endian buffer - - @ingroup SixtyFourBit - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian unsigned 64-bit value - @returns a pointer to the location eight bytes after dst - @remarks does no validation of the inputs. -*/ -posh_u64_t * -POSH_WriteU64ToLittle( void *dst, posh_u64_t value ) -{ - posh_u64_t *p64 = ( posh_u64_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - int i; - - for ( i = 0; i < 8; i++, value >>= 8 ) - { - p[ i ] = ( posh_byte_t ) ( value & 0xFF ); - } - - return p64 + 1; -} - -/** - * Writes a signed 64-bit value to a little-endian buffer - - @ingroup SixtyFourBit - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian unsigned 64-bit value - @returns a pointer to the location eight bytes after dst - @remarks does no validation of the inputs. -*/ -posh_i64_t * -POSH_WriteI64ToLittle( void *dst, posh_i64_t value ) -{ - return ( posh_i64_t * ) POSH_WriteU64ToLittle( dst, ( posh_u64_t ) value ); -} - -/** - * Writes an unsigned 64-bit value to a big-endian buffer - - @ingroup SixtyFourBit - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian unsigned 64-bit value - @returns a pointer to the location eight bytes after dst - @remarks does no validation of the inputs. -*/ -posh_u64_t * -POSH_WriteU64ToBig( void *dst, posh_u64_t value ) -{ - posh_u64_t *p64 = ( posh_u64_t * ) dst; - posh_byte_t *p = ( posh_byte_t * ) dst; - int i; - - for ( i = 0; i < 8; i++, value >>= 8 ) - { - p[ 7-i ] = ( posh_byte_t ) ( value & 0xFF ); - } - - return p64 + 8; -} - -/** - * Writes a signed 64-bit value to a big-endian buffer - - @ingroup SixtyFourBit - @param dst [out] pointer to the destination buffer, may not be NULL - @param value [in] host-endian signed 64-bit value - @returns a pointer to the location eight bytes after dst - @remarks does no validation of the inputs. -*/ -posh_i64_t * -POSH_WriteI64ToBig( void *dst, posh_i64_t value ) -{ - return ( posh_i64_t * ) POSH_WriteU64ToBig( dst, ( posh_u64_t ) value ); -} - -#endif /* POSH_64BIT_INTEGER */ - -/* ---------------------------------------------------------------------------*/ -/* IN-MEMORY DESERIALIZATION */ -/* ---------------------------------------------------------------------------*/ - -/** - * Reads an unsigned 16-bit value from a little-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian unsigned 16-bit value -*/ -posh_u16_t -POSH_ReadU16FromLittle( const void *src ) -{ - posh_u16_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - - v |= p[ 0 ]; - v |= ( ( posh_u16_t ) p[ 1 ] ) << 8; - - return v; -} - -/** - * Reads a signed 16-bit value from a little-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian signed 16-bit value -*/ -posh_i16_t -POSH_ReadI16FromLittle( const void *src ) -{ - return ( posh_i16_t ) POSH_ReadU16FromLittle( src ); -} - -/** - * Reads an unsigned 32-bit value from a little-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian unsigned 32-bit value -*/ -posh_u32_t -POSH_ReadU32FromLittle( const void *src ) -{ - posh_u32_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - - v |= p[ 0 ]; - v |= ( ( posh_u32_t ) p[ 1 ] ) << 8; - v |= ( ( posh_u32_t ) p[ 2 ] ) << 16; - v |= ( ( posh_u32_t ) p[ 3 ] ) << 24; - - return v; -} - -/** - * Reads a signed 32-bit value from a little-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian signed 32-bit value -*/ -posh_i32_t -POSH_ReadI32FromLittle( const void *src ) -{ - return ( posh_i32_t ) POSH_ReadU32FromLittle( src ); -} - - -/** - * Reads an unsigned 16-bit value from a big-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian unsigned 16-bit value -*/ -posh_u16_t -POSH_ReadU16FromBig( const void *src ) -{ - posh_u16_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - - v |= p[ 1 ]; - v |= ( ( posh_u16_t ) p[ 0 ] ) << 8; - - return v; -} - -/** - * Reads a signed 16-bit value from a big-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian signed 16-bit value -*/ -posh_i16_t -POSH_ReadI16FromBig( const void *src ) -{ - return ( posh_i16_t ) POSH_ReadU16FromBig( src ); -} - -/** - * Reads an unsigned 32-bit value from a big-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian unsigned 32-bit value -*/ -posh_u32_t -POSH_ReadU32FromBig( const void *src ) -{ - posh_u32_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - - v |= p[ 3 ]; - v |= ( ( posh_u32_t ) p[ 2 ] ) << 8; - v |= ( ( posh_u32_t ) p[ 1 ] ) << 16; - v |= ( ( posh_u32_t ) p[ 0 ] ) << 24; - - return v; -} - -/** - * Reads a signed 32-bit value from a big-endian buffer - @ingroup MemoryBuffer - @param src [in] source buffer - @returns host-endian signed 32-bit value -*/ -posh_i32_t -POSH_ReadI32FromBig( const void *src ) -{ - return POSH_BigI32( (*(const posh_i32_t*)src ) ); -} - -#if defined POSH_64BIT_INTEGER - -/** - * Reads an unsigned 64-bit value from a little-endian buffer - @param src [in] source buffer - @returns host-endian unsigned 32-bit value -*/ -posh_u64_t -POSH_ReadU64FromLittle( const void *src ) -{ - posh_u64_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - int i; - - for ( i = 0; i < 8; i++ ) - { - v |= ( ( posh_u64_t ) p[ i ] ) << (i*8); - } - - return v; -} - -/** - * Reads a signed 64-bit value from a little-endian buffer - @param src [in] source buffer - @returns host-endian signed 32-bit value -*/ -posh_i64_t -POSH_ReadI64FromLittle( const void *src ) -{ - return ( posh_i64_t ) POSH_ReadU64FromLittle( src ); -} - -/** - * Reads an unsigned 64-bit value from a big-endian buffer - @param src [in] source buffer - @returns host-endian unsigned 32-bit value -*/ -posh_u64_t -POSH_ReadU64FromBig( const void *src ) -{ - posh_u64_t v = 0; - posh_byte_t *p = ( posh_byte_t * ) src; - int i; - - for ( i = 0; i < 8; i++ ) - { - v |= ( ( posh_u64_t ) p[ 7-i ] ) << (i*8); - } - - return v; -} - -/** - * Reads an signed 64-bit value from a big-endian buffer - @param src [in] source buffer - @returns host-endian signed 32-bit value -*/ -posh_i64_t -POSH_ReadI64FromBig( const void *src ) -{ - return ( posh_i64_t ) POSH_ReadU64FromBig( src ); -} - -#endif /* POSH_64BIT_INTEGER */ - -/* ---------------------------------------------------------------------------*/ -/* FLOATING POINT SUPPORT */ -/* ---------------------------------------------------------------------------*/ - -#if !defined POSH_NO_FLOAT - -/** @ingroup FloatingPoint - @param[in] f floating point value - @returns a little-endian bit representation of f - */ -posh_u32_t -POSH_LittleFloatBits( float f ) -{ - union - { - float f32; - posh_u32_t u32; - } u; - - u.f32 = f; - - return POSH_LittleU32( u.u32 ); -} - -/** - * Extracts raw big-endian bits from a 32-bit floating point value - * - @ingroup FloatingPoint - @param f [in] floating point value - @returns a big-endian bit representation of f - */ -posh_u32_t -POSH_BigFloatBits( float f ) -{ - union - { - float f32; - posh_u32_t u32; - } u; - - u.f32 = f; - - return POSH_BigU32( u.u32 ); -} - -/** - * Extracts raw, little-endian bit representation from a 64-bit double. - * - @param d [in] 64-bit double precision value - @param dst [out] 8-byte storage buffer - @ingroup FloatingPoint - @returns the raw bits used to represent the value 'd', in the form dst[0]=LSB - */ -void -POSH_DoubleBits( double d, posh_byte_t dst[ 8 ] ) -{ - union - { - double d64; - posh_byte_t bytes[ 8 ]; - } u; - - u.d64 = d; - -#if defined POSH_LITTLE_ENDIAN - dst[ 0 ] = u.bytes[ 0 ]; - dst[ 1 ] = u.bytes[ 1 ]; - dst[ 2 ] = u.bytes[ 2 ]; - dst[ 3 ] = u.bytes[ 3 ]; - dst[ 4 ] = u.bytes[ 4 ]; - dst[ 5 ] = u.bytes[ 5 ]; - dst[ 6 ] = u.bytes[ 6 ]; - dst[ 7 ] = u.bytes[ 7 ]; -#else - dst[ 0 ] = u.bytes[ 7 ]; - dst[ 1 ] = u.bytes[ 6 ]; - dst[ 2 ] = u.bytes[ 5 ]; - dst[ 3 ] = u.bytes[ 4 ]; - dst[ 4 ] = u.bytes[ 3 ]; - dst[ 5 ] = u.bytes[ 2 ]; - dst[ 6 ] = u.bytes[ 1 ]; - dst[ 7 ] = u.bytes[ 0 ]; -#endif -} - -/** - * Creates a double-precision, 64-bit floating point value from a set of raw, - * little-endian bits - - @ingroup FloatingPoint - @param src [in] little-endian byte representation of 64-bit double precision - floating point value - @returns double precision floating point representation of the raw bits - @remarks No error checking is performed, so there are no guarantees that the - result is a valid number, nor is there any check to ensure that src is - non-NULL. BE CAREFUL USING THIS. - */ -double -POSH_DoubleFromBits( const posh_byte_t src[ 8 ] ) -{ - union - { - double d64; - posh_byte_t bytes[ 8 ]; - } u; - -#if defined POSH_LITTLE_ENDIAN - u.bytes[ 0 ] = src[ 0 ]; - u.bytes[ 1 ] = src[ 1 ]; - u.bytes[ 2 ] = src[ 2 ]; - u.bytes[ 3 ] = src[ 3 ]; - u.bytes[ 4 ] = src[ 4 ]; - u.bytes[ 5 ] = src[ 5 ]; - u.bytes[ 6 ] = src[ 6 ]; - u.bytes[ 7 ] = src[ 7 ]; -#else - u.bytes[ 0 ] = src[ 7 ]; - u.bytes[ 1 ] = src[ 6 ]; - u.bytes[ 2 ] = src[ 5 ]; - u.bytes[ 3 ] = src[ 4 ]; - u.bytes[ 4 ] = src[ 3 ]; - u.bytes[ 5 ] = src[ 2 ]; - u.bytes[ 6 ] = src[ 1 ]; - u.bytes[ 7 ] = src[ 0 ]; -#endif - - return u.d64; -} - -/** - * Creates a floating point number from little endian bits - * - @ingroup FloatingPoint - @param bits [in] raw floating point bits in little-endian form - @returns a floating point number based on the given bit representation - @remarks No error checking is performed, so there are no guarantees that the - result is a valid number. BE CAREFUL USING THIS. - */ -float -POSH_FloatFromLittleBits( posh_u32_t bits ) -{ - union - { - float f32; - posh_u32_t u32; - } u; - - u.u32 = bits; -#if defined POSH_BIG_ENDIAN - u.u32 = POSH_SwapU32( u.u32 ); -#endif - - return u.f32; -} - -/** - * Creates a floating point number from big-endian bits - * - @ingroup FloatingPoint - @param bits [in] raw floating point bits in big-endian form - @returns a floating point number based on the given bit representation - @remarks No error checking is performed, so there are no guarantees that the - result is a valid number. BE CAREFUL USING THIS. - */ -float -POSH_FloatFromBigBits( posh_u32_t bits ) -{ - union - { - float f32; - posh_u32_t u32; - } u; - - u.u32 = bits; -#if defined POSH_LITTLE_ENDIAN - u.u32 = POSH_SwapU32( u.u32 ); -#endif - - return u.f32; -} - -#endif /* !defined POSH_NO_FLOAT */ diff --git a/Externals/NVTT/src/nvcore/poshlib/posh.h b/Externals/NVTT/src/nvcore/poshlib/posh.h deleted file mode 100644 index 3a7c38190e4..00000000000 --- a/Externals/NVTT/src/nvcore/poshlib/posh.h +++ /dev/null @@ -1,1007 +0,0 @@ -/** -@file posh.h -@author Brian Hook -@version 1.3.001 - -Header file for POSH, the Portable Open Source Harness project. - -NOTE: Unlike most header files, this one is designed to be included -multiple times, which is why it does not have the @#ifndef/@#define -preamble. - -POSH relies on environment specified preprocessor symbols in order -to infer as much as possible about the target OS/architecture and -the host compiler capabilities. - -NOTE: POSH is simple and focused. It attempts to provide basic -functionality and information, but it does NOT attempt to emulate -missing functionality. I am also not willing to make POSH dirty -and hackish to support truly ancient and/or outmoded and/or bizarre -technologies such as non-ANSI compilers, systems with non-IEEE -floating point formats, segmented 16-bit operating systems, etc. - -Please refer to the accompanying HTML documentation or visit -http://www.poshlib.org for more information on how to use POSH. - -LICENSE: - -Copyright (c) 2004, Brian Hook -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of this package'ss contributors contributors may not - be used to endorse or promote products derived from this - software without specific prior written permission. - - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -REVISION: - -I've been lax about revision histories, so this starts at, um, 1.3.001. -Sorry for any inconveniences. - -1.3.001 - 2/23/2006 - Incorporated fix for bug reported by Bill Cary, - where I was not detecting Visual Studio - compilation on x86-64 systems. Added check for - _M_X64 which should fix that. - -*/ -/* -I have yet to find an authoritative reference on preprocessor -symbols, but so far this is what I've gleaned: - -GNU GCC/G++: - - __GNUC__: GNU C version - - __GNUG__: GNU C++ compiler - - __sun__ : on Sun platforms - - __svr4__: on Solaris and other SysV R4 platforms - - __mips__: on MIPS processor platforms - - __sparc_v9__: on Sparc 64-bit CPUs - - __sparcv9: 64-bit Solaris - - __MIPSEL__: mips processor, compiled for little endian - - __MIPSEB__: mips processor, compiled for big endian - - _R5900: MIPS/Sony/Toshiba R5900 (PS2) - - mc68000: 68K - - m68000: 68K - - m68k: 68K - - __palmos__: PalmOS - -Intel C/C++ Compiler: - - __ECC : compiler version, IA64 only - - __EDG__ - - __ELF__ - - __GXX_ABI_VERSION - - __i386 : IA-32 only - - __i386__ : IA-32 only - - i386 : IA-32 only - - __ia64 : IA-64 only - - __ia64__ : IA-64 only - - ia64 : IA-64 only - - __ICC : IA-32 only - - __INTEL_COMPILER : IA-32 or IA-64, newer versions only - -Apple's C/C++ Compiler for OS X: - - __APPLE_CC__ - - __APPLE__ - - __BIG_ENDIAN__ - - __APPLE__ - - __ppc__ - - __MACH__ - -DJGPP: - - __MSDOS__ - - __unix__ - - __unix - - __GNUC__ - - __GO32 - - DJGPP - - __i386, __i386, i386 - -Cray's C compiler: - - _ADDR64: if 64-bit pointers - - _UNICOS: - - __unix: - -SGI's CC compiler predefines the following (and more) with -ansi: - - __sgi - - __unix - - __host_mips - - _SYSTYPE_SVR4 - - __mips - - _MIPSEB - - anyone know if there is a predefined symbol for the compiler?! - -MinGW: - - as GnuC but also defines _WIN32, __WIN32, WIN32, _X86_, __i386, __i386__, and several others - - __MINGW32__ - -Cygwin: - - as Gnu C, but also - - __unix__ - - __CYGWIN32__ - -Microsoft Visual Studio predefines the following: - - _MSC_VER - - _WIN32: on Win32 - - _M_IX6 (on x86 systems) - - _M_X64: on x86-64 systems - - _M_ALPHA (on DEC AXP systems) - - _SH3: WinCE, Hitachi SH-3 - - _MIPS: WinCE, MIPS - - _ARM: WinCE, ARM - -Sun's C Compiler: - - sun and _sun - - unix and _unix - - sparc and _sparc (SPARC systems only) - - i386 and _i386 (x86 systems only) - - __SVR4 (Solaris only) - - __sparcv9: 64-bit solaris - - __SUNPRO_C - - _LP64: defined in 64-bit LP64 mode, but only if is included - -Borland C/C++ predefines the following: - - __BORLANDC__: - -DEC/Compaq C/C++ on Alpha: - - __alpha - - __arch64__ - - __unix__ (on Tru64 Unix) - - __osf__ - - __DECC - - __DECCXX (C++ compilation) - - __DECC_VER - - __DECCXX_VER - -IBM's AIX compiler: - - __64BIT__ if 64-bit mode - - _AIX - - __IBMC__: C compiler version - - __IBMCPP__: C++ compiler version - - _LONG_LONG: compiler allows long long - -Watcom: - - __WATCOMC__ - - __DOS__ : if targeting DOS - - __386__ : if 32-bit support - - __WIN32__ : if targetin 32-bit Windows - -HP-UX C/C++ Compiler: - - __hpux - - __unix - - __hppa (on PA-RISC) - - __LP64__: if compiled in 64-bit mode - -Metrowerks: - - __MWERKS__ - - __powerpc__ - - _powerc - - __MC68K__ - - macintosh when compiling for MacOS - - __INTEL__ for x86 targets - - __POWERPC__ - -*/ - -/* -** ---------------------------------------------------------------------------- -** Include optionally -** ---------------------------------------------------------------------------- -*/ -#ifdef POSH_USE_LIMITS_H -# include -#endif - -/* -** ---------------------------------------------------------------------------- -** Determine compilation environment -** ---------------------------------------------------------------------------- -*/ -#if defined __ECC || defined __ICC || defined __INTEL_COMPILER -# define POSH_COMPILER_STRING "Intel C/C++" -# define POSH_COMPILER_INTEL 1 -#endif - -#if ( defined __host_mips || defined __sgi ) && !defined __GNUC__ -# define POSH_COMPILER_STRING "MIPSpro C/C++" -# define POSH_COMPILER_MIPSPRO 1 -#endif - -#if defined __hpux && !defined __GNUC__ -# define POSH_COMPILER_STRING "HP-UX CC" -# define POSH_COMPILER_HPCC 1 -#endif - -#if defined __GNUC__ -# define POSH_COMPILER_STRING "Gnu GCC" -# define POSH_COMPILER_GCC 1 -#endif - -#if defined __APPLE_CC__ - /* we don't define the compiler string here, let it be GNU */ -# define POSH_COMPILER_APPLECC 1 -#endif - -#if defined __IBMC__ || defined __IBMCPP__ -# define POSH_COMPILER_STRING "IBM C/C++" -# define POSH_COMPILER_IBM 1 -#endif - -#if defined _MSC_VER -# define POSH_COMPILER_STRING "Microsoft Visual C++" -# define POSH_COMPILER_MSVC 1 -#endif - -#if defined __SUNPRO_C -# define POSH_COMPILER_STRING "Sun Pro" -# define POSH_COMPILER_SUN 1 -#endif - -#if defined __BORLANDC__ -# define POSH_COMPILER_STRING "Borland C/C++" -# define POSH_COMPILER_BORLAND 1 -#endif - -#if defined __MWERKS__ -# define POSH_COMPILER_STRING "MetroWerks CodeWarrior" -# define POSH_COMPILER_METROWERKS 1 -#endif - -#if defined __DECC || defined __DECCXX -# define POSH_COMPILER_STRING "Compaq/DEC C/C++" -# define POSH_COMPILER_DEC 1 -#endif - -#if defined __WATCOMC__ -# define POSH_COMPILER_STRING "Watcom C/C++" -# define POSH_COMPILER_WATCOM 1 -#endif - -#if !defined POSH_COMPILER_STRING -# define POSH_COMPILER_STRING "Unknown compiler" -#endif - -/* -** ---------------------------------------------------------------------------- -** Determine target operating system -** ---------------------------------------------------------------------------- -*/ -#if defined linux || defined __linux__ -# define POSH_OS_LINUX 1 -# define POSH_OS_STRING "Linux" -#endif - -#if defined __CYGWIN32__ -# define POSH_OS_CYGWIN32 1 -# define POSH_OS_STRING "Cygwin" -#endif - -#if defined GEKKO -# define POSH_OS_GAMECUBE -# define __powerpc__ -# define POSH_OS_STRING "GameCube" -#endif - -#if defined __MINGW32__ -# define POSH_OS_MINGW 1 -# define POSH_OS_STRING "MinGW" -#endif - -#if defined GO32 && defined DJGPP && defined __MSDOS__ -# define POSH_OS_GO32 1 -# define POSH_OS_STRING "GO32/MS-DOS" -#endif - -/* NOTE: make sure you use /bt=DOS if compiling for 32-bit DOS, - otherwise Watcom assumes host=target */ -#if defined __WATCOMC__ && defined __386__ && defined __DOS__ -# define POSH_OS_DOS32 1 -# define POSH_OS_STRING "DOS/32-bit" -#endif - -#if defined _UNICOS -# define POSH_OS_UNICOS 1 -# define POSH_OS_STRING "UNICOS" -#endif - -#if ( defined __MWERKS__ && defined __powerc && !defined macintosh ) || defined __APPLE_CC__ || defined macosx -# define POSH_OS_OSX 1 -# define POSH_OS_STRING "MacOS X" -#endif - -#if defined __sun__ || defined sun || defined __sun || defined __solaris__ -# if defined __SVR4 || defined __svr4__ || defined __solaris__ -# define POSH_OS_STRING "Solaris" -# define POSH_OS_SOLARIS 1 -# endif -# if !defined POSH_OS_STRING -# define POSH_OS_STRING "SunOS" -# define POSH_OS_SUNOS 1 -# endif -#endif - -#if defined __sgi__ || defined sgi || defined __sgi -# define POSH_OS_IRIX 1 -# define POSH_OS_STRING "Irix" -#endif - -#if defined __hpux__ || defined __hpux -# define POSH_OS_HPUX 1 -# define POSH_OS_STRING "HP-UX" -#endif - -#if defined _AIX -# define POSH_OS_AIX 1 -# define POSH_OS_STRING "AIX" -#endif - -#if ( defined __alpha && defined __osf__ ) -# define POSH_OS_TRU64 1 -# define POSH_OS_STRING "Tru64" -#endif - -#if defined __BEOS__ || defined __beos__ -# define POSH_OS_BEOS 1 -# define POSH_OS_STRING "BeOS" -#endif - -#if defined amiga || defined amigados || defined AMIGA || defined _AMIGA -# define POSH_OS_AMIGA 1 -# define POSH_OS_STRING "Amiga" -#endif - -#if defined __unix__ -# define POSH_OS_UNIX 1 -# if !defined POSH_OS_STRING -# define POSH_OS_STRING "Unix-like(generic)" -# endif -#endif - -#if defined _WIN32_WCE -# define POSH_OS_WINCE 1 -# define POSH_OS_STRING "Windows CE" -#endif - -#if defined _XBOX -# define POSH_OS_XBOX 1 -# define POSH_OS_STRING "XBOX" -#endif - -#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ -# define POSH_OS_WIN32 1 -# if !defined POSH_OS_XBOX -# if defined _WIN64 -# define POSH_OS_WIN64 1 -# define POSH_OS_STRING "Win64" -# else -# if !defined POSH_OS_STRING -# define POSH_OS_STRING "Win32" -# endif -# endif -# endif -#endif - -#if defined __palmos__ -# define POSH_OS_PALM 1 -# define POSH_OS_STRING "PalmOS" -#endif - -#if defined THINK_C || defined macintosh -# define POSH_OS_MACOS 1 -# define POSH_OS_STRING "MacOS" -#endif - -/* -** ----------------------------------------------------------------------------- -** Determine target CPU -** ----------------------------------------------------------------------------- -*/ - -#if defined GEKKO -# define POSH_CPU_PPC750 1 -# define POSH_CPU_STRING "IBM PowerPC 750 (NGC)" -#endif - -#if defined mc68000 || defined m68k || defined __MC68K__ || defined m68000 -# define POSH_CPU_68K 1 -# define POSH_CPU_STRING "MC68000" -#endif - -#if defined __PPC__ || defined __POWERPC__ || defined powerpc || defined _POWER || defined __ppc__ || defined __powerpc__ -# define POSH_CPU_PPC 1 -# if !defined POSH_CPU_STRING -# if defined __powerpc64__ -# define POSH_CPU_STRING "PowerPC64" -# else -# define POSH_CPU_STRING "PowerPC" -# endif -# endif -#endif - -#if defined _CRAYT3E || defined _CRAYMPP -# define POSH_CPU_CRAYT3E 1 /* target processor is a DEC Alpha 21164 used in a Cray T3E*/ -# define POSH_CPU_STRING "Cray T3E (Alpha 21164)" -#endif - -#if defined CRAY || defined _CRAY && !defined _CRAYT3E -# error Non-AXP Cray systems not supported -#endif - -#if defined _SH3 -# define POSH_CPU_SH3 1 -# define POSH_CPU_STRING "Hitachi SH-3" -#endif - -#if defined __sh4__ || defined __SH4__ -# define POSH_CPU_SH3 1 -# define POSH_CPU_SH4 1 -# define POSH_CPU_STRING "Hitachi SH-4" -#endif - -#if defined __sparc__ || defined __sparc -# if defined __arch64__ || defined __sparcv9 || defined __sparc_v9__ -# define POSH_CPU_SPARC64 1 -# define POSH_CPU_STRING "Sparc/64" -# else -# define POSH_CPU_STRING "Sparc/32" -# endif -# define POSH_CPU_SPARC 1 -#endif - -#if defined ARM || defined __arm__ || defined _ARM -# define POSH_CPU_STRONGARM 1 -# define POSH_CPU_STRING "ARM" -#endif - -#if defined mips || defined __mips__ || defined __MIPS__ || defined _MIPS -# define POSH_CPU_MIPS 1 -# if defined _R5900 -# define POSH_CPU_STRING "MIPS R5900 (PS2)" -# else -# define POSH_CPU_STRING "MIPS" -# endif -#endif - -#if defined __ia64 || defined _M_IA64 || defined __ia64__ -# define POSH_CPU_IA64 1 -# define POSH_CPU_STRING "IA64" -#endif - -#if defined __X86__ || defined __i386__ || defined i386 || defined _M_IX86 || defined __386__ || defined __x86_64__ || defined _M_X64 -# define POSH_CPU_X86 1 -# if defined __x86_64__ || defined _M_X64 -# define POSH_CPU_X86_64 1 -# endif -# if defined POSH_CPU_X86_64 -# define POSH_CPU_STRING "AMD x86-64" -# else -# define POSH_CPU_STRING "Intel 386+" -# endif -#endif - -#if defined __alpha || defined alpha || defined _M_ALPHA || defined __alpha__ -# define POSH_CPU_AXP 1 -# define POSH_CPU_STRING "AXP" -#endif - -#if defined __hppa || defined hppa -# define POSH_CPU_HPPA 1 -# define POSH_CPU_STRING "PA-RISC" -#endif - -#if !defined POSH_CPU_STRING -# error POSH cannot determine target CPU -# define POSH_CPU_STRING "Unknown" /* this is here for Doxygen's benefit */ -#endif - -/* -** ----------------------------------------------------------------------------- -** Attempt to autodetect building for embedded on Sony PS2 -** ----------------------------------------------------------------------------- -*/ -#if !defined POSH_OS_STRING -# if !defined FORCE_DOXYGEN -# define POSH_OS_EMBEDDED 1 -# endif -# if defined _R5900 -# define POSH_OS_STRING "Sony PS2(embedded)" -# else -# define POSH_OS_STRING "Embedded/Unknown" -# endif -#endif - -/* -** --------------------------------------------------------------------------- -** Handle cdecl, stdcall, fastcall, etc. -** --------------------------------------------------------------------------- -*/ -#if defined POSH_CPU_X86 && !defined POSH_CPU_X86_64 -# if defined __GNUC__ -# define POSH_CDECL __attribute__((cdecl)) -# define POSH_STDCALL __attribute__((stdcall)) -# define POSH_FASTCALL __attribute__((fastcall)) -# elif ( defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ || defined __MWERKS__ ) -# define POSH_CDECL __cdecl -# define POSH_STDCALL __stdcall -# define POSH_FASTCALL __fastcall -# endif -#else -# define POSH_CDECL -# define POSH_STDCALL -# define POSH_FASTCALL -#endif - -/* -** --------------------------------------------------------------------------- -** Define POSH_IMPORTEXPORT signature based on POSH_DLL and POSH_BUILDING_LIB -** --------------------------------------------------------------------------- -*/ - -/* -** We undefine this so that multiple inclusions will work -*/ -#if defined POSH_IMPORTEXPORT -# undef POSH_IMPORTEXPORT -#endif - -#if defined POSH_DLL -# if defined POSH_OS_WIN32 -# if defined _MSC_VER -# if ( _MSC_VER >= 800 ) -# if defined POSH_BUILDING_LIB -# define POSH_IMPORTEXPORT __declspec( dllexport ) -# else -# define POSH_IMPORTEXPORT __declspec( dllimport ) -# endif -# else -# if defined POSH_BUILDING_LIB -# define POSH_IMPORTEXPORT __export -# else -# define POSH_IMPORTEXPORT -# endif -# endif -# endif /* defined _MSC_VER */ -# if defined __BORLANDC__ -# if ( __BORLANDC__ >= 0x500 ) -# if defined POSH_BUILDING_LIB -# define POSH_IMPORTEXPORT __declspec( dllexport ) -# else -# define POSH_IMPORTEXPORT __declspec( dllimport ) -# endif -# else -# if defined POSH_BUILDING_LIB -# define POSH_IMPORTEXPORT __export -# else -# define POSH_IMPORTEXPORT -# endif -# endif -# endif /* defined __BORLANDC__ */ - /* for all other compilers, we're just making a blanket assumption */ -# if defined __GNUC__ || defined __WATCOMC__ || defined __MWERKS__ -# if defined POSH_BUILDING_LIB -# define POSH_IMPORTEXPORT __declspec( dllexport ) -# else -# define POSH_IMPORTEXPORT __declspec( dllimport ) -# endif -# endif /* all other compilers */ -# if !defined POSH_IMPORTEXPORT -# error Building DLLs not supported on this compiler (poshlib@poshlib.org if you know how) -# endif -# endif /* defined POSH_OS_WIN32 */ -#endif - -/* On pretty much everything else, we can thankfully just ignore this */ -#if !defined POSH_IMPORTEXPORT -# define POSH_IMPORTEXPORT -#endif - -#if defined FORCE_DOXYGEN -# define POSH_DLL -# define POSH_BUILDING_LIB -# undef POSH_DLL -# undef POSH_BUILDING_LIB -#endif - -/* -** ---------------------------------------------------------------------------- -** (Re)define POSH_PUBLIC_API export signature -** ---------------------------------------------------------------------------- -*/ -#ifdef POSH_PUBLIC_API -# undef POSH_PUBLIC_API -#endif - -#if ( ( defined _MSC_VER ) && ( _MSC_VER < 800 ) ) || ( defined __BORLANDC__ && ( __BORLANDC__ < 0x500 ) ) -# define POSH_PUBLIC_API(rtype) extern rtype POSH_IMPORTEXPORT -#else -# define POSH_PUBLIC_API(rtype) extern POSH_IMPORTEXPORT rtype -#endif - -/* -** ---------------------------------------------------------------------------- -** Try to infer endianess. Basically we just go through the CPUs we know are -** little endian, and assume anything that isn't one of those is big endian. -** As a sanity check, we also do this with operating systems we know are -** little endian, such as Windows. Some processors are bi-endian, such as -** the MIPS series, so we have to be careful about those. -** ---------------------------------------------------------------------------- -*/ -#if defined POSH_CPU_X86 || defined POSH_CPU_AXP || defined POSH_CPU_STRONGARM || defined POSH_OS_WIN32 || defined POSH_OS_WINCE || defined __MIPSEL__ -# define POSH_ENDIAN_STRING "little" -# define POSH_LITTLE_ENDIAN 1 -#else -# define POSH_ENDIAN_STRING "big" -# define POSH_BIG_ENDIAN 1 -#endif - -#if defined FORCE_DOXYGEN -# define POSH_LITTLE_ENDIAN -#endif - -/* -** ---------------------------------------------------------------------------- -** Cross-platform compile time assertion macro -** ---------------------------------------------------------------------------- -*/ -#define POSH_COMPILE_TIME_ASSERT(name, x) typedef int _POSH_dummy_ ## name[(x) ? 1 : -1 ] - -/* -** ---------------------------------------------------------------------------- -** 64-bit Integer -** -** We don't require 64-bit support, nor do we emulate its functionality, we -** simply export it if it's available. Since we can't count on -** for 64-bit support, we ignore the POSH_USE_LIMITS_H directive. -** ---------------------------------------------------------------------------- -*/ -#if defined ( __LP64__ ) || defined ( __powerpc64__ ) || defined POSH_CPU_SPARC64 -# define POSH_64BIT_INTEGER 1 -typedef long posh_i64_t; -typedef unsigned long posh_u64_t; -# define POSH_I64( x ) ((posh_i64_t)x) -# define POSH_U64( x ) ((posh_u64_t)x) -# define POSH_I64_PRINTF_PREFIX "l" -#elif defined _MSC_VER || defined __BORLANDC__ || defined __WATCOMC__ || ( defined __alpha && defined __DECC ) -# define POSH_64BIT_INTEGER 1 -typedef __int64 posh_i64_t; -typedef unsigned __int64 posh_u64_t; -# define POSH_I64( x ) ((posh_i64_t)x) -# define POSH_U64( x ) ((posh_u64_t)x) -# define POSH_I64_PRINTF_PREFIX "I64" -#elif defined __GNUC__ || defined __MWERKS__ || defined __SUNPRO_C || defined __SUNPRO_CC || defined __APPLE_CC__ || defined POSH_OS_IRIX || defined _LONG_LONG || defined _CRAYC -# define POSH_64BIT_INTEGER 1 -typedef long long posh_i64_t; -typedef unsigned long long posh_u64_t; -# define POSH_U64( x ) ((posh_u64_t)(x##LL)) -# define POSH_I64( x ) ((posh_i64_t)(x##LL)) -# define POSH_I64_PRINTF_PREFIX "ll" -#endif - -/* hack */ -/*#ifdef __MINGW32__ -#undef POSH_I64 -#undef POSH_U64 -#undef POSH_I64_PRINTF_PREFIX -#define POSH_I64( x ) ((posh_i64_t)x) -#define POSH_U64( x ) ((posh_u64_t)x) -#define POSH_I64_PRINTF_PREFIX "I64" -#endif*/ - -#ifdef FORCE_DOXYGEN -typedef long long posh_i64_t; -typedef unsigned long posh_u64_t; -# define POSH_64BIT_INTEGER -# define POSH_I64_PRINTF_PREFIX -# define POSH_I64(x) -# define POSH_U64(x) -#endif - -/** Minimum value for a 64-bit signed integer */ -#define POSH_I64_MIN POSH_I64(0x8000000000000000) -/** Maximum value for a 64-bit signed integer */ -#define POSH_I64_MAX POSH_I64(0x7FFFFFFFFFFFFFFF) -/** Minimum value for a 64-bit unsigned integer */ -#define POSH_U64_MIN POSH_U64(0) -/** Maximum value for a 64-bit unsigned integer */ -#define POSH_U64_MAX POSH_U64(0xFFFFFFFFFFFFFFFF) - -/* ---------------------------------------------------------------------------- -** Basic Sized Types -** -** These types are expected to be EXACTLY sized so you can use them for -** serialization. -** ---------------------------------------------------------------------------- -*/ -#define POSH_FALSE 0 -#define POSH_TRUE 1 - -typedef int posh_bool_t; -typedef unsigned char posh_byte_t; - -/* NOTE: These assume that CHAR_BIT is 8!! */ -typedef unsigned char posh_u8_t; -typedef signed char posh_i8_t; - -#if defined POSH_USE_LIMITS_H -# if CHAR_BITS > 8 -# error This machine uses 9-bit characters. This is a warning, you can comment this out now. -# endif /* CHAR_BITS > 8 */ - -/* 16-bit */ -# if ( USHRT_MAX == 65535 ) - typedef unsigned short posh_u16_t; - typedef short posh_i16_t; -# else - /* Yes, in theory there could still be a 16-bit character type and shorts are - 32-bits in size...if you find such an architecture, let me know =P */ -# error No 16-bit type found -# endif - -/* 32-bit */ -# if ( INT_MAX == 2147483647 ) - typedef unsigned posh_u32_t; - typedef int posh_i32_t; -# elif ( LONG_MAX == 2147483647 ) - typedef unsigned long posh_u32_t; - typedef long posh_i32_t; -# else - error No 32-bit type found -# endif - -#else /* POSH_USE_LIMITS_H */ - - typedef unsigned short posh_u16_t; - typedef short posh_i16_t; - -# if !defined POSH_OS_PALM - typedef unsigned posh_u32_t; - typedef int posh_i32_t; -# else - typedef unsigned long posh_u32_t; - typedef long posh_i32_t; -# endif -#endif - -/** Minimum value for a byte */ -#define POSH_BYTE_MIN 0 -/** Maximum value for an 8-bit unsigned value */ -#define POSH_BYTE_MAX 255 -/** Minimum value for a byte */ -#define POSH_I16_MIN ( ( posh_i16_t ) 0x8000 ) -/** Maximum value for a 16-bit signed value */ -#define POSH_I16_MAX ( ( posh_i16_t ) 0x7FFF ) -/** Minimum value for a 16-bit unsigned value */ -#define POSH_U16_MIN 0 -/** Maximum value for a 16-bit unsigned value */ -#define POSH_U16_MAX ( ( posh_u16_t ) 0xFFFF ) -/** Minimum value for a 32-bit signed value */ -#define POSH_I32_MIN ( ( posh_i32_t ) 0x80000000 ) -/** Maximum value for a 32-bit signed value */ -#define POSH_I32_MAX ( ( posh_i32_t ) 0x7FFFFFFF ) -/** Minimum value for a 32-bit unsigned value */ -#define POSH_U32_MIN 0 -/** Maximum value for a 32-bit unsigned value */ -#define POSH_U32_MAX ( ( posh_u32_t ) 0xFFFFFFFF ) - -/* -** ---------------------------------------------------------------------------- -** Sanity checks on expected sizes -** ---------------------------------------------------------------------------- -*/ -#if !defined FORCE_DOXYGEN - -POSH_COMPILE_TIME_ASSERT(posh_byte_t, sizeof(posh_byte_t) == 1); -POSH_COMPILE_TIME_ASSERT(posh_u8_t, sizeof(posh_u8_t) == 1); -POSH_COMPILE_TIME_ASSERT(posh_i8_t, sizeof(posh_i8_t) == 1); -POSH_COMPILE_TIME_ASSERT(posh_u16_t, sizeof(posh_u16_t) == 2); -POSH_COMPILE_TIME_ASSERT(posh_i16_t, sizeof(posh_i16_t) == 2); -POSH_COMPILE_TIME_ASSERT(posh_u32_t, sizeof(posh_u32_t) == 4); -POSH_COMPILE_TIME_ASSERT(posh_i32_t, sizeof(posh_i32_t) == 4); - -#if !defined POSH_NO_FLOAT - POSH_COMPILE_TIME_ASSERT(posh_testfloat_t, sizeof(float)==4 ); - POSH_COMPILE_TIME_ASSERT(posh_testdouble_t, sizeof(double)==8); -#endif - -#if defined POSH_64BIT_INTEGER - POSH_COMPILE_TIME_ASSERT(posh_u64_t, sizeof(posh_u64_t) == 8); - POSH_COMPILE_TIME_ASSERT(posh_i64_t, sizeof(posh_i64_t) == 8); -#endif - -#endif - -/* -** ---------------------------------------------------------------------------- -** 64-bit pointer support -** ---------------------------------------------------------------------------- -*/ -#if defined POSH_CPU_AXP && ( defined POSH_OS_TRU64 || defined POSH_OS_LINUX ) -# define POSH_64BIT_POINTER 1 -#endif - -#if defined POSH_CPU_X86_64 && defined POSH_OS_LINUX -# define POSH_64BIT_POINTER 1 -#endif - -#if defined POSH_CPU_SPARC64 || defined POSH_OS_WIN64 || defined __64BIT__ || defined __LP64 || defined _LP64 || defined __LP64__ || defined _ADDR64 || defined _CRAYC -# define POSH_64BIT_POINTER 1 -#endif - -#if defined POSH_64BIT_POINTER - POSH_COMPILE_TIME_ASSERT( posh_64bit_pointer, sizeof( void * ) == 8 ); -#elif !defined FORCE_DOXYGEN -/* if this assertion is hit then you're on a system that either has 64-bit - addressing and we didn't catch it, or you're on a system with 16-bit - pointers. In the latter case, POSH doesn't actually care, we're just - triggering this assertion to make sure you're aware of the situation, - so feel free to delete it. - - If this assertion is triggered on a known 32 or 64-bit platform, - please let us know (poshlib@poshlib.org) */ - POSH_COMPILE_TIME_ASSERT( posh_32bit_pointer, sizeof( void * ) == 4 ); -#endif - -#if defined FORCE_DOXYGEN -# define POSH_64BIT_POINTER -#endif - -/* -** ---------------------------------------------------------------------------- -** POSH Utility Functions -** -** These are optional POSH utility functions that are not required if you don't -** need anything except static checking of your host and target environment. -** -** These functions are NOT wrapped with POSH_PUBLIC_API because I didn't want -** to enforce their export if your own library is only using them internally. -** ---------------------------------------------------------------------------- -*/ -#ifdef __cplusplus -extern "C" { -#endif - -const char *POSH_GetArchString( void ); - -#if !defined POSH_NO_FLOAT - -posh_u32_t POSH_LittleFloatBits( float f ); -posh_u32_t POSH_BigFloatBits( float f ); -float POSH_FloatFromLittleBits( posh_u32_t bits ); -float POSH_FloatFromBigBits( posh_u32_t bits ); - -void POSH_DoubleBits( double d, posh_byte_t dst[ 8 ] ); -double POSH_DoubleFromBits( const posh_byte_t src[ 8 ] ); - -/* unimplemented -float *POSH_WriteFloatToLittle( void *dst, float f ); -float *POSH_WriteFloatToBig( void *dst, float f ); -float POSH_ReadFloatFromLittle( const void *src ); -float POSH_ReadFloatFromBig( const void *src ); - -double *POSH_WriteDoubleToLittle( void *dst, double d ); -double *POSH_WriteDoubleToBig( void *dst, double d ); -double POSH_ReadDoubleFromLittle( const void *src ); -double POSH_ReadDoubleFromBig( const void *src ); -*/ -#endif /* !defined POSH_NO_FLOAT */ - -#if defined FORCE_DOXYGEN -# define POSH_NO_FLOAT -# undef POSH_NO_FLOAT -#endif - -extern posh_u16_t POSH_SwapU16( posh_u16_t u ); -extern posh_i16_t POSH_SwapI16( posh_i16_t u ); -extern posh_u32_t POSH_SwapU32( posh_u32_t u ); -extern posh_i32_t POSH_SwapI32( posh_i32_t u ); - -#if defined POSH_64BIT_INTEGER - -extern posh_u64_t POSH_SwapU64( posh_u64_t u ); -extern posh_i64_t POSH_SwapI64( posh_i64_t u ); - -#endif /*POSH_64BIT_INTEGER */ - -extern posh_u16_t *POSH_WriteU16ToLittle( void *dst, posh_u16_t value ); -extern posh_i16_t *POSH_WriteI16ToLittle( void *dst, posh_i16_t value ); -extern posh_u32_t *POSH_WriteU32ToLittle( void *dst, posh_u32_t value ); -extern posh_i32_t *POSH_WriteI32ToLittle( void *dst, posh_i32_t value ); - -extern posh_u16_t *POSH_WriteU16ToBig( void *dst, posh_u16_t value ); -extern posh_i16_t *POSH_WriteI16ToBig( void *dst, posh_i16_t value ); -extern posh_u32_t *POSH_WriteU32ToBig( void *dst, posh_u32_t value ); -extern posh_i32_t *POSH_WriteI32ToBig( void *dst, posh_i32_t value ); - -extern posh_u16_t POSH_ReadU16FromLittle( const void *src ); -extern posh_i16_t POSH_ReadI16FromLittle( const void *src ); -extern posh_u32_t POSH_ReadU32FromLittle( const void *src ); -extern posh_i32_t POSH_ReadI32FromLittle( const void *src ); - -extern posh_u16_t POSH_ReadU16FromBig( const void *src ); -extern posh_i16_t POSH_ReadI16FromBig( const void *src ); -extern posh_u32_t POSH_ReadU32FromBig( const void *src ); -extern posh_i32_t POSH_ReadI32FromBig( const void *src ); - -#if defined POSH_64BIT_INTEGER -extern posh_u64_t *POSH_WriteU64ToLittle( void *dst, posh_u64_t value ); -extern posh_i64_t *POSH_WriteI64ToLittle( void *dst, posh_i64_t value ); -extern posh_u64_t *POSH_WriteU64ToBig( void *dst, posh_u64_t value ); -extern posh_i64_t *POSH_WriteI64ToBig( void *dst, posh_i64_t value ); - -extern posh_u64_t POSH_ReadU64FromLittle( const void *src ); -extern posh_i64_t POSH_ReadI64FromLittle( const void *src ); -extern posh_u64_t POSH_ReadU64FromBig( const void *src ); -extern posh_i64_t POSH_ReadI64FromBig( const void *src ); -#endif /* POSH_64BIT_INTEGER */ - -#if defined POSH_LITTLE_ENDIAN - -# define POSH_LittleU16(x) (x) -# define POSH_LittleU32(x) (x) -# define POSH_LittleI16(x) (x) -# define POSH_LittleI32(x) (x) -# if defined POSH_64BIT_INTEGER -# define POSH_LittleU64(x) (x) -# define POSH_LittleI64(x) (x) -# endif /* defined POSH_64BIT_INTEGER */ - -# define POSH_BigU16(x) POSH_SwapU16(x) -# define POSH_BigU32(x) POSH_SwapU32(x) -# define POSH_BigI16(x) POSH_SwapI16(x) -# define POSH_BigI32(x) POSH_SwapI32(x) -# if defined POSH_64BIT_INTEGER -# define POSH_BigU64(x) POSH_SwapU64(x) -# define POSH_BigI64(x) POSH_SwapI64(x) -# endif /* defined POSH_64BIT_INTEGER */ - -#else - -# define POSH_BigU16(x) (x) -# define POSH_BigU32(x) (x) -# define POSH_BigI16(x) (x) -# define POSH_BigI32(x) (x) - -# if defined POSH_64BIT_INTEGER -# define POSH_BigU64(x) (x) -# define POSH_BigI64(x) (x) -# endif /* POSH_64BIT_INTEGER */ - -# define POSH_LittleU16(x) POSH_SwapU16(x) -# define POSH_LittleU32(x) POSH_SwapU32(x) -# define POSH_LittleI16(x) POSH_SwapI16(x) -# define POSH_LittleI32(x) POSH_SwapI32(x) - -# if defined POSH_64BIT_INTEGER -# define POSH_LittleU64(x) POSH_SwapU64(x) -# define POSH_LittleI64(x) POSH_SwapI64(x) -# endif /* POSH_64BIT_INTEGER */ - -#endif - -#ifdef __cplusplus -} -#endif - - diff --git a/Externals/NVTT/src/nvimage/BlockDXT.cpp b/Externals/NVTT/src/nvimage/BlockDXT.cpp deleted file mode 100644 index 6e185b50ec5..00000000000 --- a/Externals/NVTT/src/nvimage/BlockDXT.cpp +++ /dev/null @@ -1,666 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include "ColorBlock.h" -#include "BlockDXT.h" - -using namespace nv; - - -/*---------------------------------------------------------------------------- - BlockDXT1 -----------------------------------------------------------------------------*/ - -uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const -{ - // Does bit expansion before interpolation. - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; - - // @@ Same as above, but faster? -// Color32 c; -// c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); -// c.u |= (c.u >> 5) & 0x070007; -// c.u |= (c.u >> 6) & 0x000300; -// color_array[0].u = c.u; - - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; - - // @@ Same as above, but faster? -// c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000); -// c.u |= (c.u >> 5) & 0x070007; -// c.u |= (c.u >> 6) & 0x000300; -// color_array[1].u = c.u; - - if( col0.u > col1.u ) { - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; - color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; - color_array[2].a = 0xFF; - - color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3; - color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; - color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; - color_array[3].a = 0xFF; - - return 4; - } - else { - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; - - return 3; - } -} - -// Evaluate palette assuming 3 color block. -void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const -{ - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; - - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; - - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; -} - -// Evaluate palette assuming 4 color block. -void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const -{ - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; - - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; - - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; - color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; - color_array[2].a = 0xFF; - - color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3; - color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; - color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; - color_array[3].a = 0xFF; -} - - -/* Jason Dorie's code. -// ---------------------------------------------------------------------------- -// Build palette for a 3 color + traparent black block -// ---------------------------------------------------------------------------- -void DXTCGen::BuildCodes3(cbVector *pVects, cbVector &v1, cbVector &v2) -{ - //pVects[0] = v1; - //pVects[2] = v2; - //pVects[1][0] = v1[0]; - //pVects[1][1] = (BYTE)( ((long)v1[1] + (long)v2[1]) / 2 ); - //pVects[1][2] = (BYTE)( ((long)v1[2] + (long)v2[2]) / 2 ); - //pVects[1][3] = (BYTE)( ((long)v1[3] + (long)v2[3]) / 2 ); - - __asm { - mov ecx, dword ptr pVects - mov eax, dword ptr v1 - mov ebx, dword ptr v2 - - movd mm0, [eax] - movd mm1, [ebx] - pxor mm2, mm2 - nop - - movd [ecx], mm0 - movd [ecx+8], mm1 - - punpcklbw mm0, mm2 - punpcklbw mm1, mm2 - - paddw mm0, mm1 - psrlw mm0, 1 - - packuswb mm0, mm0 - movd [ecx+4], mm0 - } - // *(long *)&pVects[1] = r1; -} - -__int64 ScaleOneThird = 0x5500550055005500; - -// ---------------------------------------------------------------------------- -// Build palette for a 4 color block -// ---------------------------------------------------------------------------- -void DXTCGen::BuildCodes4(cbVector *pVects, cbVector &v1, cbVector &v2) -{ -// pVects[0] = v1; -// pVects[3] = v2; -// -// pVects[1][0] = v1[0]; -// pVects[1][1] = (BYTE)( ((long)v1[1] * 2 + (long)v2[1]) / 3 ); -// pVects[1][2] = (BYTE)( ((long)v1[2] * 2 + (long)v2[2]) / 3 ); -// pVects[1][3] = (BYTE)( ((long)v1[3] * 2 + (long)v2[3]) / 3 ); -// -// pVects[2][0] = v1[0]; -// pVects[2][1] = (BYTE)( ((long)v2[1] * 2 + (long)v1[1]) / 3 ); -// pVects[2][2] = (BYTE)( ((long)v2[2] * 2 + (long)v1[2]) / 3 ); -// pVects[2][3] = (BYTE)( ((long)v2[3] * 2 + (long)v1[3]) / 3 ); - - __asm { - mov ecx, dword ptr pVects - mov eax, dword ptr v1 - mov ebx, dword ptr v2 - - movd mm0, [eax] - movd mm1, [ebx] - - pxor mm2, mm2 - movd [ecx], mm0 - movd [ecx+12], mm1 - - punpcklbw mm0, mm2 - punpcklbw mm1, mm2 - movq mm3, mm0 // mm3 = v0 - - paddw mm0, mm1 // mm0 = v0 + v1 - paddw mm3, mm3 // mm3 = v0*2 - - paddw mm0, mm1 // mm0 = v0 + v1*2 - paddw mm1, mm3 // mm1 = v0*2 + v1 - - pmulhw mm0, ScaleOneThird - pmulhw mm1, ScaleOneThird - packuswb mm1, mm0 - - movq [ecx+4], mm1 - } -} -*/ - -void BlockDXT1::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - // Decode color block. - Color32 color_array[4]; - evaluatePalette(color_array); - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - uint idx = (row[j] >> (2 * i)) & 3; - block->color(i, j) = color_array[idx]; - } - } -} - -void BlockDXT1::setIndices(int * idx) -{ - indices = 0; - for(uint i = 0; i < 16; i++) { - indices |= (idx[i] & 3) << (2 * i); - } -} - - -/// Flip DXT1 block vertically. -inline void BlockDXT1::flip4() -{ - swap(row[0], row[3]); - swap(row[1], row[2]); -} - -/// Flip half DXT1 block vertically. -inline void BlockDXT1::flip2() -{ - swap(row[0], row[1]); -} - - -/*---------------------------------------------------------------------------- - BlockDXT3 -----------------------------------------------------------------------------*/ - -void BlockDXT3::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - // Decode color. - color.decodeBlock(block); - - // Decode alpha. - alpha.decodeBlock(block); -} - -void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - block->color(0x0).a = (alpha0 << 4) | alpha0; - block->color(0x1).a = (alpha1 << 4) | alpha1; - block->color(0x2).a = (alpha2 << 4) | alpha2; - block->color(0x3).a = (alpha3 << 4) | alpha3; - block->color(0x4).a = (alpha4 << 4) | alpha4; - block->color(0x5).a = (alpha5 << 4) | alpha5; - block->color(0x6).a = (alpha6 << 4) | alpha6; - block->color(0x7).a = (alpha7 << 4) | alpha7; - block->color(0x8).a = (alpha8 << 4) | alpha8; - block->color(0x9).a = (alpha9 << 4) | alpha9; - block->color(0xA).a = (alphaA << 4) | alphaA; - block->color(0xB).a = (alphaB << 4) | alphaB; - block->color(0xC).a = (alphaC << 4) | alphaC; - block->color(0xD).a = (alphaD << 4) | alphaD; - block->color(0xE).a = (alphaE << 4) | alphaE; - block->color(0xF).a = (alphaF << 4) | alphaF; -} - -/// Flip DXT3 alpha block vertically. -void AlphaBlockDXT3::flip4() -{ - swap(row[0], row[3]); - swap(row[1], row[2]); -} - -/// Flip half DXT3 alpha block vertically. -void AlphaBlockDXT3::flip2() -{ - swap(row[0], row[1]); -} - -/// Flip DXT3 block vertically. -void BlockDXT3::flip4() -{ - alpha.flip4(); - color.flip4(); -} - -/// Flip half DXT3 block vertically. -void BlockDXT3::flip2() -{ - alpha.flip2(); - color.flip2(); -} - - -/*---------------------------------------------------------------------------- - BlockDXT5 -----------------------------------------------------------------------------*/ - -void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const -{ - if (alpha0 > alpha1) { - evaluatePalette8(alpha); - } - else { - evaluatePalette6(alpha); - } -} - -void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const -{ - // 8-alpha block: derive the other six alphas. - // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. - alpha[0] = alpha0; - alpha[1] = alpha1; - alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010 - alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011 - alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100 - alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101 - alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110 - alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111 -} - -void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const -{ - // 6-alpha block. - // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. - alpha[0] = alpha0; - alpha[1] = alpha1; - alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010 - alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011 - alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100 - alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101 - alpha[6] = 0x00; // Bit code 110 - alpha[7] = 0xFF; // Bit code 111 -} - -void AlphaBlockDXT5::indices(uint8 index_array[16]) const -{ - index_array[0x0] = bits0; - index_array[0x1] = bits1; - index_array[0x2] = bits2; - index_array[0x3] = bits3; - index_array[0x4] = bits4; - index_array[0x5] = bits5; - index_array[0x6] = bits6; - index_array[0x7] = bits7; - index_array[0x8] = bits8; - index_array[0x9] = bits9; - index_array[0xA] = bitsA; - index_array[0xB] = bitsB; - index_array[0xC] = bitsC; - index_array[0xD] = bitsD; - index_array[0xE] = bitsE; - index_array[0xF] = bitsF; -} - -uint AlphaBlockDXT5::index(uint index) const -{ - nvDebugCheck(index < 16); - - int offset = (3 * index + 16); - return uint((this->u >> offset) & 0x7); -} - -void AlphaBlockDXT5::setIndex(uint index, uint value) -{ - nvDebugCheck(index < 16); - nvDebugCheck(value < 8); - - int offset = (3 * index + 16); - uint64 mask = uint64(0x7) << offset; - this->u = (this->u & ~mask) | (uint64(value) << offset); -} - -void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - uint8 alpha_array[8]; - evaluatePalette(alpha_array); - - uint8 index_array[16]; - indices(index_array); - - for(uint i = 0; i < 16; i++) { - block->color(i).a = alpha_array[index_array[i]]; - } -} - -void AlphaBlockDXT5::flip4() -{ - uint64 * b = (uint64 *)this; - - // @@ The masks might have to be byte swapped. - uint64 tmp = (*b & POSH_U64(0x000000000000FFFF)); - tmp |= (*b & POSH_U64(0x000000000FFF0000)) << 36; - tmp |= (*b & POSH_U64(0x000000FFF0000000)) << 12; - tmp |= (*b & POSH_U64(0x000FFF0000000000)) >> 12; - tmp |= (*b & POSH_U64(0xFFF0000000000000)) >> 36; - - *b = tmp; -} - -void AlphaBlockDXT5::flip2() -{ - uint * b = (uint *)this; - - // @@ The masks might have to be byte swapped. - uint tmp = (*b & 0xFF000000); - tmp |= (*b & 0x00000FFF) << 12; - tmp |= (*b & 0x00FFF000) >> 12; - - *b = tmp; -} - -void BlockDXT5::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - // Decode color. - color.decodeBlock(block); - - // Decode alpha. - alpha.decodeBlock(block); - -} - -/// Flip DXT5 block vertically. -void BlockDXT5::flip4() -{ - alpha.flip4(); - color.flip4(); -} - -/// Flip half DXT5 block vertically. -void BlockDXT5::flip2() -{ - alpha.flip2(); - color.flip2(); -} - - -/// Decode ATI1 block. -void BlockATI1::decodeBlock(ColorBlock * block) const -{ - uint8 alpha_array[8]; - alpha.evaluatePalette(alpha_array); - - uint8 index_array[16]; - alpha.indices(index_array); - - for(uint i = 0; i < 16; i++) { - Color32 & c = block->color(i); - c.b = c.g = c.r = alpha_array[index_array[i]]; - c.a = 255; - } -} - -/// Flip ATI1 block vertically. -void BlockATI1::flip4() -{ - alpha.flip4(); -} - -/// Flip half ATI1 block vertically. -void BlockATI1::flip2() -{ - alpha.flip2(); -} - - -/// Decode ATI2 block. -void BlockATI2::decodeBlock(ColorBlock * block) const -{ - uint8 alpha_array[8]; - uint8 index_array[16]; - - x.evaluatePalette(alpha_array); - x.indices(index_array); - - for(uint i = 0; i < 16; i++) { - Color32 & c = block->color(i); - c.r = alpha_array[index_array[i]]; - } - - y.evaluatePalette(alpha_array); - y.indices(index_array); - - for(uint i = 0; i < 16; i++) { - Color32 & c = block->color(i); - c.g = alpha_array[index_array[i]]; - c.b = 0; - c.a = 255; - } -} - -/// Flip ATI2 block vertically. -void BlockATI2::flip4() -{ - x.flip4(); - y.flip4(); -} - -/// Flip half ATI2 block vertically. -void BlockATI2::flip2() -{ - x.flip2(); - y.flip2(); -} - - -void BlockCTX1::evaluatePalette(Color32 color_array[4]) const -{ - // Does bit expansion before interpolation. - color_array[0].b = 0x00; - color_array[0].g = col0[1]; - color_array[0].r = col0[0]; - color_array[0].a = 0xFF; - - color_array[1].r = 0x00; - color_array[1].g = col0[1]; - color_array[1].b = col1[0]; - color_array[1].a = 0xFF; - - color_array[2].r = 0x00; - color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; - color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; - color_array[2].a = 0xFF; - - color_array[3].r = 0x00; - color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; - color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; - color_array[3].a = 0xFF; -} - -void BlockCTX1::decodeBlock(ColorBlock * block) const -{ - nvDebugCheck(block != NULL); - - // Decode color block. - Color32 color_array[4]; - evaluatePalette(color_array); - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - uint idx = (row[j] >> (2 * i)) & 3; - block->color(i, j) = color_array[idx]; - } - } -} - -void BlockCTX1::setIndices(int * idx) -{ - indices = 0; - for(uint i = 0; i < 16; i++) { - indices |= (idx[i] & 3) << (2 * i); - } -} - - -/// Flip CTX1 block vertically. -inline void BlockCTX1::flip4() -{ - swap(row[0], row[3]); - swap(row[1], row[2]); -} - -/// Flip half CTX1 block vertically. -inline void BlockCTX1::flip2() -{ - swap(row[0], row[1]); -} - - - - -Stream & nv::operator<<(Stream & stream, BlockDXT1 & block) -{ - stream << block.col0.u << block.col1.u; - stream.serialize(&block.indices, sizeof(block.indices)); - return stream; -} - -Stream & nv::operator<<(Stream & stream, AlphaBlockDXT3 & block) -{ - stream.serialize(&block, sizeof(block)); - return stream; -} - -Stream & nv::operator<<(Stream & stream, BlockDXT3 & block) -{ - return stream << block.alpha << block.color; -} - -Stream & nv::operator<<(Stream & stream, AlphaBlockDXT5 & block) -{ - stream.serialize(&block, sizeof(block)); - return stream; -} - -Stream & nv::operator<<(Stream & stream, BlockDXT5 & block) -{ - return stream << block.alpha << block.color; -} - -Stream & nv::operator<<(Stream & stream, BlockATI1 & block) -{ - return stream << block.alpha; -} - -Stream & nv::operator<<(Stream & stream, BlockATI2 & block) -{ - return stream << block.x << block.y; -} - -Stream & nv::operator<<(Stream & stream, BlockCTX1 & block) -{ - stream.serialize(&block, sizeof(block)); - return stream; -} - diff --git a/Externals/NVTT/src/nvimage/BlockDXT.h b/Externals/NVTT/src/nvimage/BlockDXT.h deleted file mode 100644 index 5a45c408d51..00000000000 --- a/Externals/NVTT/src/nvimage/BlockDXT.h +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_IMAGE_BLOCKDXT_H -#define NV_IMAGE_BLOCKDXT_H - -#include - -#include - -namespace nv -{ - struct ColorBlock; - class Stream; - - - /// DXT1 block. - struct BlockDXT1 - { - Color16 col0; - Color16 col1; - union { - uint8 row[4]; - uint indices; - }; - - bool isFourColorMode() const; - - uint evaluatePalette(Color32 color_array[4]) const; - uint evaluatePaletteFast(Color32 color_array[4]) const; - void evaluatePalette3(Color32 color_array[4]) const; - void evaluatePalette4(Color32 color_array[4]) const; - - void decodeBlock(ColorBlock * block) const; - - void setIndices(int * idx); - - void flip4(); - void flip2(); - }; - - /// Return true if the block uses four color mode, false otherwise. - inline bool BlockDXT1::isFourColorMode() const - { - return col0.u > col1.u; - } - - - /// DXT3 alpha block with explicit alpha. - struct AlphaBlockDXT3 - { - union { - struct { - uint alpha0 : 4; - uint alpha1 : 4; - uint alpha2 : 4; - uint alpha3 : 4; - uint alpha4 : 4; - uint alpha5 : 4; - uint alpha6 : 4; - uint alpha7 : 4; - uint alpha8 : 4; - uint alpha9 : 4; - uint alphaA : 4; - uint alphaB : 4; - uint alphaC : 4; - uint alphaD : 4; - uint alphaE : 4; - uint alphaF : 4; - }; - uint16 row[4]; - }; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - - /// DXT3 block. - struct BlockDXT3 - { - AlphaBlockDXT3 alpha; - BlockDXT1 color; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - - /// DXT5 alpha block. - struct AlphaBlockDXT5 - { - union { - struct { - uint64 alpha0 : 8; // 8 - uint64 alpha1 : 8; // 16 - uint64 bits0 : 3; // 3 - 19 - uint64 bits1 : 3; // 6 - 22 - uint64 bits2 : 3; // 9 - 25 - uint64 bits3 : 3; // 12 - 28 - uint64 bits4 : 3; // 15 - 31 - uint64 bits5 : 3; // 18 - 34 - uint64 bits6 : 3; // 21 - 37 - uint64 bits7 : 3; // 24 - 40 - uint64 bits8 : 3; // 27 - 43 - uint64 bits9 : 3; // 30 - 46 - uint64 bitsA : 3; // 33 - 49 - uint64 bitsB : 3; // 36 - 52 - uint64 bitsC : 3; // 39 - 55 - uint64 bitsD : 3; // 42 - 58 - uint64 bitsE : 3; // 45 - 61 - uint64 bitsF : 3; // 48 - 64 - }; - uint64 u; - }; - - void evaluatePalette(uint8 alpha[8]) const; - void evaluatePalette8(uint8 alpha[8]) const; - void evaluatePalette6(uint8 alpha[8]) const; - void indices(uint8 index_array[16]) const; - - uint index(uint index) const; - void setIndex(uint index, uint value); - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - - /// DXT5 block. - struct BlockDXT5 - { - AlphaBlockDXT5 alpha; - BlockDXT1 color; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - /// ATI1 block. - struct BlockATI1 - { - AlphaBlockDXT5 alpha; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - /// ATI2 block. - struct BlockATI2 - { - AlphaBlockDXT5 x; - AlphaBlockDXT5 y; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - /// CTX1 block. - struct BlockCTX1 - { - uint8 col0[2]; - uint8 col1[2]; - union { - uint8 row[4]; - uint indices; - }; - - void evaluatePalette(Color32 color_array[4]) const; - void setIndices(int * idx); - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); - }; - - - // Serialization functions. - NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT1 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT3 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT3 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, AlphaBlockDXT5 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, BlockDXT5 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI1 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, BlockATI2 & block); - NVIMAGE_API Stream & operator<<(Stream & stream, BlockCTX1 & block); - -} // nv namespace - -#endif // NV_IMAGE_BLOCKDXT_H diff --git a/Externals/NVTT/src/nvimage/CMakeLists.txt b/Externals/NVTT/src/nvimage/CMakeLists.txt deleted file mode 100644 index 830fd449ba7..00000000000 --- a/Externals/NVTT/src/nvimage/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -option(NVIMAGE_SHARED "Build nvimage as shared library" OFF) - -if (NVIMAGE_SHARED) - add_library(nvimage SHARED) - - target_compile_definitions(nvimage - PRIVATE - NVIMAGE_SHARED=1 - ) -else() - add_library(nvimage STATIC) -endif() - -target_sources(nvimage PRIVATE - nvimage.h - FloatImage.h - FloatImage.cpp - Filter.h - Filter.cpp - Image.h - Image.cpp - ImageIO.h - ImageIO.cpp - ColorBlock.h - ColorBlock.cpp - BlockDXT.h - BlockDXT.cpp - HoleFilling.h - HoleFilling.cpp - DirectDrawSurface.h - DirectDrawSurface.cpp - Quantize.h - Quantize.cpp - NormalMap.h - NormalMap.cpp - NormalMipmap.h - NormalMipmap.cpp - PsdFile.h - TgaFile.h -) - -target_link_libraries(nvimage - PUBLIC - nvcore - nvmath - PRIVATE - posh - $<$:PNG::PNG> - $<$:JPEG::JPEG> - $<$:TIFF::TIFF> - $<$:OpenEXR::OpenEXR> -) - -target_compile_definitions(nvimage - PRIVATE - NVIMAGE_EXPORTS -) - -set_property(TARGET nvimage PROPERTY - POSITION_INDEPENDENT_CODE ON -) - -install(TARGETS nvimage LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/Externals/NVTT/src/nvimage/ColorBlock.cpp b/Externals/NVTT/src/nvimage/ColorBlock.cpp deleted file mode 100644 index 2b100982226..00000000000 --- a/Externals/NVTT/src/nvimage/ColorBlock.cpp +++ /dev/null @@ -1,404 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include -#include - -using namespace nv; - -namespace { - - // Get approximate luminance. - inline static uint colorLuminance(Color32 c) - { - return c.r + c.g + c.b; - } - - // Get the euclidean distance between the given colors. - inline static uint colorDistance(Color32 c0, Color32 c1) - { - return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b); - } - -} // namespace` - - -/// Default constructor. -ColorBlock::ColorBlock() -{ -} - -/// Init the color block from an array of colors. -ColorBlock::ColorBlock(const uint * linearImage) -{ - for(uint i = 0; i < 16; i++) { - color(i) = Color32(linearImage[i]); - } -} - -/// Init the color block with the contents of the given block. -ColorBlock::ColorBlock(const ColorBlock & block) -{ - for(uint i = 0; i < 16; i++) { - color(i) = block.color(i); - } -} - - -/// Initialize this color block. -ColorBlock::ColorBlock(const Image * img, uint x, uint y) -{ - init(img, x, y); -} - -void ColorBlock::init(const Image * img, uint x, uint y) -{ - nvDebugCheck(img != NULL); - - const uint bw = min(img->width() - x, 4U); - const uint bh = min(img->height() - y, 4U); - - nvDebugCheck(bw != 0); - nvDebugCheck(bh != 0); - - static int remainder[] = { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - // Blocks that are smaller than 4x4 are handled by repeating the pixels. - // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :( - - for(uint i = 0; i < 4; i++) { - //const int by = i % bh; - const int by = remainder[(bh - 1) * 4 + i]; - for(uint e = 0; e < 4; e++) { - //const int bx = e % bw; - const int bx = remainder[(bw - 1) * 4 + e]; - color(e, i) = img->pixel(x + bx, y + by); - } - } -} - - -void ColorBlock::swizzleDXT5n() -{ - for(int i = 0; i < 16; i++) - { - Color32 c = m_color[i]; - m_color[i] = Color32(0xFF, c.g, 0, c.r); - } -} - -void ColorBlock::splatX() -{ - for(int i = 0; i < 16; i++) - { - uint8 x = m_color[i].r; - m_color[i] = Color32(x, x, x, x); - } -} - -void ColorBlock::splatY() -{ - for(int i = 0; i < 16; i++) - { - uint8 y = m_color[i].g; - m_color[i] = Color32(y, y, y, y); - } -} - -/// Returns true if the block has a single color. -bool ColorBlock::isSingleColor() const -{ - Color32 mask(0xFF, 0xFF, 0xFF, 0x00); - uint u = m_color[0].u & mask.u; - - for (int i = 1; i < 16; i++) - { - if (u != (m_color[i].u & mask.u)) - { - return false; - } - } - - return true; -} - -/// Count number of unique colors in this color block. -uint ColorBlock::countUniqueColors() const -{ - uint count = 0; - - // @@ This does not have to be o(n^2) - for(int i = 0; i < 16; i++) - { - bool unique = true; - for(int j = 0; j < i; j++) { - if( m_color[i] != m_color[j] ) { - unique = false; - } - } - - if( unique ) { - count++; - } - } - - return count; -} - -/// Get average color of the block. -Color32 ColorBlock::averageColor() const -{ - uint r, g, b, a; - r = g = b = a = 0; - - for(uint i = 0; i < 16; i++) { - r += m_color[i].r; - g += m_color[i].g; - b += m_color[i].b; - a += m_color[i].a; - } - - return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16)); -} - -/// Return true if the block is not fully opaque. -bool ColorBlock::hasAlpha() const -{ - for (uint i = 0; i < 16; i++) - { - if (m_color[i].a != 255) return true; - } - return false; -} - - -/// Get diameter color range. -void ColorBlock::diameterRange(Color32 * start, Color32 * end) const -{ - nvDebugCheck(start != NULL); - nvDebugCheck(end != NULL); - - Color32 c0, c1; - uint best_dist = 0; - - for(int i = 0; i < 16; i++) { - for (int j = i+1; j < 16; j++) { - uint dist = colorDistance(m_color[i], m_color[j]); - if( dist > best_dist ) { - best_dist = dist; - c0 = m_color[i]; - c1 = m_color[j]; - } - } - } - - *start = c0; - *end = c1; -} - -/// Get luminance color range. -void ColorBlock::luminanceRange(Color32 * start, Color32 * end) const -{ - nvDebugCheck(start != NULL); - nvDebugCheck(end != NULL); - - Color32 minColor, maxColor; - uint minLuminance, maxLuminance; - - maxLuminance = minLuminance = colorLuminance(m_color[0]); - - for(uint i = 1; i < 16; i++) - { - uint luminance = colorLuminance(m_color[i]); - - if (luminance > maxLuminance) { - maxLuminance = luminance; - maxColor = m_color[i]; - } - else if (luminance < minLuminance) { - minLuminance = luminance; - minColor = m_color[i]; - } - } - - *start = minColor; - *end = maxColor; -} - -/// Get color range based on the bounding box. -void ColorBlock::boundsRange(Color32 * start, Color32 * end) const -{ - nvDebugCheck(start != NULL); - nvDebugCheck(end != NULL); - - Color32 minColor(255, 255, 255); - Color32 maxColor(0, 0, 0); - - for(uint i = 0; i < 16; i++) - { - if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } - if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } - if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } - if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } - if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } - if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } - } - - // Offset range by 1/16 of the extents - Color32 inset; - inset.r = (maxColor.r - minColor.r) >> 4; - inset.g = (maxColor.g - minColor.g) >> 4; - inset.b = (maxColor.b - minColor.b) >> 4; - - minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; - minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; - minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; - - maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; - maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; - maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; - - *start = minColor; - *end = maxColor; -} - -/// Get color range based on the bounding box. -void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const -{ - nvDebugCheck(start != NULL); - nvDebugCheck(end != NULL); - - Color32 minColor(255, 255, 255, 255); - Color32 maxColor(0, 0, 0, 0); - - for(uint i = 0; i < 16; i++) - { - if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } - if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } - if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } - if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; } - if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } - if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } - if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } - if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; } - } - - // Offset range by 1/16 of the extents - Color32 inset; - inset.r = (maxColor.r - minColor.r) >> 4; - inset.g = (maxColor.g - minColor.g) >> 4; - inset.b = (maxColor.b - minColor.b) >> 4; - inset.a = (maxColor.a - minColor.a) >> 4; - - minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; - minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; - minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; - minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255; - - maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; - maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; - maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; - maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0; - - *start = minColor; - *end = maxColor; -} - - -/// Sort colors by abosolute value in their 16 bit representation. -void ColorBlock::sortColorsByAbsoluteValue() -{ - // Dummy selection sort. - for( uint a = 0; a < 16; a++ ) { - uint max = a; - Color16 cmax(m_color[a]); - - for( uint b = a+1; b < 16; b++ ) { - Color16 cb(m_color[b]); - - if( cb.u > cmax.u ) { - max = b; - cmax = cb; - } - } - swap( m_color[a], m_color[max] ); - } -} - - -/// Find extreme colors in the given axis. -void ColorBlock::computeRange(Vector3::Arg axis, Color32 * start, Color32 * end) const -{ - nvDebugCheck(start != NULL); - nvDebugCheck(end != NULL); - - int mini, maxi; - mini = maxi = 0; - - float min, max; - min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis); - - for(uint i = 1; i < 16; i++) - { - const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); - - float val = dot(vec, axis); - if( val < min ) { - mini = i; - min = val; - } - else if( val > max ) { - maxi = i; - max = val; - } - } - - *start = m_color[mini]; - *end = m_color[maxi]; -} - - -/// Sort colors in the given axis. -void ColorBlock::sortColors(const Vector3 & axis) -{ - float luma_array[16]; - - for(uint i = 0; i < 16; i++) { - const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); - luma_array[i] = dot(vec, axis); - } - - // Dummy selection sort. - for( uint a = 0; a < 16; a++ ) { - uint min = a; - for( uint b = a+1; b < 16; b++ ) { - if( luma_array[b] < luma_array[min] ) { - min = b; - } - } - swap( luma_array[a], luma_array[min] ); - swap( m_color[a], m_color[min] ); - } -} - - -/// Get the volume of the color block. -float ColorBlock::volume() const -{ - Box bounds; - bounds.clearBounds(); - - for(int i = 0; i < 16; i++) { - const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b); - bounds.addPointToBounds(point); - } - - return bounds.volume(); -} - - diff --git a/Externals/NVTT/src/nvimage/ColorBlock.h b/Externals/NVTT/src/nvimage/ColorBlock.h deleted file mode 100644 index 00f9c8eede7..00000000000 --- a/Externals/NVTT/src/nvimage/ColorBlock.h +++ /dev/null @@ -1,95 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_COLORBLOCK_H -#define NV_IMAGE_COLORBLOCK_H - -#include - -namespace nv -{ - class Image; - - /// Uncompressed 4x4 color block. - struct ColorBlock - { - ColorBlock(); - ColorBlock(const uint * linearImage); - ColorBlock(const ColorBlock & block); - ColorBlock(const Image * img, uint x, uint y); - - void init(const Image * img, uint x, uint y); - - void swizzleDXT5n(); - void splatX(); - void splatY(); - - bool isSingleColor() const; - uint countUniqueColors() const; - Color32 averageColor() const; - bool hasAlpha() const; - - void diameterRange(Color32 * start, Color32 * end) const; - void luminanceRange(Color32 * start, Color32 * end) const; - void boundsRange(Color32 * start, Color32 * end) const; - void boundsRangeAlpha(Color32 * start, Color32 * end) const; - - void sortColorsByAbsoluteValue(); - - void computeRange(const Vector3 & axis, Color32 * start, Color32 * end) const; - void sortColors(const Vector3 & axis); - - float volume() const; - - // Accessors - const Color32 * colors() const; - - Color32 color(uint i) const; - Color32 & color(uint i); - - Color32 color(uint x, uint y) const; - Color32 & color(uint x, uint y); - - private: - - Color32 m_color[4*4]; - - }; - - - /// Get pointer to block colors. - inline const Color32 * ColorBlock::colors() const - { - return m_color; - } - - /// Get block color. - inline Color32 ColorBlock::color(uint i) const - { - nvDebugCheck(i < 16); - return m_color[i]; - } - - /// Get block color. - inline Color32 & ColorBlock::color(uint i) - { - nvDebugCheck(i < 16); - return m_color[i]; - } - - /// Get block color. - inline Color32 ColorBlock::color(uint x, uint y) const - { - nvDebugCheck(x < 4 && y < 4); - return m_color[y * 4 + x]; - } - - /// Get block color. - inline Color32 & ColorBlock::color(uint x, uint y) - { - nvDebugCheck(x < 4 && y < 4); - return m_color[y * 4 + x]; - } - -} // nv namespace - -#endif // NV_IMAGE_COLORBLOCK_H diff --git a/Externals/NVTT/src/nvimage/ConeMap.cpp b/Externals/NVTT/src/nvimage/ConeMap.cpp deleted file mode 100644 index 0c99efa9189..00000000000 --- a/Externals/NVTT/src/nvimage/ConeMap.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include - -#include -#include -#include -#include - -using namespace nv; - - -static float processPixel(const FloatImage * img, uint x, uint y) -{ - nvDebugCheck(img != NULL); - - const uint w = img->width(); - const uint h = img->height(); - - float d = img->pixel(x, y, 0); - - float fx0 = (float) x / w; - float fy0 = (float) y / h; - - float best_ratio = INFINITY; - uint best_x = w; - uint best_y = h; - - for (uint yy = 0; yy < h; yy++) - { - for (uint xx = 0; xx < w; xx++) - { - float ch = d - img->pixel(xx, yy, 0); - - if (ch > 0) - { - float dx = float(xx - x); - float dy = float(yy - y); - - float ratio = (dx * dx + dy * dy) / ch; - - if (ratio < best_ratio) - { - best_x = xx; - best_y = yy; - } - } - } - } - - if (best_x != w) - { - nvDebugCheck(best_y !=h); - - float dx = float(best_x - x) / w; - float dy = float(best_y - y) / h; - - float cw = sqrtf(dx*dx + dy*dy); - float ch = d - img->pixel(best_x, best_y, 0); - - return min(1.0f, sqrtf(cw / ch)); - } - - return 1.0f; -} - - -// Create cone map using the given kernels. -FloatImage * createConeMap(const Image * img, Vector4::Arg heightWeights) -{ - nvCheck(img != NULL); - - const uint w = img->width(); - const uint h = img->height(); - - AutoPtr fimage(new FloatImage()); - //fimage->allocate(2, w, h); - fimage->allocate(4, w, h); - - // Compute height and store in red channel: - float * heightChannel = fimage->channel(0); - for(uint i = 0; i < w*h; i++) - { - Vector4 color = toVector4(img->pixel(i)); - heightChannel[i] = dot(color, heightWeights); - } - - // Compute cones: - for(uint y = 0; y < h; y++) - { - for(uint x = 0; x < w; x++) - { - processPixel(fimage.ptr(), x, y); - } - } - - return fimage.release(); -} - diff --git a/Externals/NVTT/src/nvimage/ConeMap.h b/Externals/NVTT/src/nvimage/ConeMap.h deleted file mode 100644 index 0c79533aaf6..00000000000 --- a/Externals/NVTT/src/nvimage/ConeMap.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_IMAGE_CONEMAP_H -#define NV_IMAGE_CONEMAP_H - -#include -#include - -namespace nv -{ - class Image; - class FloatImage; - - FloatImage * createConeMap(const Image * img, Vector4::Arg heightWeights); - -} // nv namespace - -#endif // NV_IMAGE_CONEMAP_H diff --git a/Externals/NVTT/src/nvimage/DirectDrawSurface.cpp b/Externals/NVTT/src/nvimage/DirectDrawSurface.cpp deleted file mode 100644 index 02fe191a1f3..00000000000 --- a/Externals/NVTT/src/nvimage/DirectDrawSurface.cpp +++ /dev/null @@ -1,1321 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include // max -#include - -#include -#include -#include -#include -#include - -#include // memset - - -using namespace nv; - -#if !defined(MAKEFOURCC) -# define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \ - (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 )) -#endif - -namespace -{ - static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); - static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); - static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); - static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); - static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); - static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); - static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); - static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); - static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); - - static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y'); - - static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0'); - - // 32 bit RGB formats. - static const uint D3DFMT_R8G8B8 = 20; - static const uint D3DFMT_A8R8G8B8 = 21; - static const uint D3DFMT_X8R8G8B8 = 22; - static const uint D3DFMT_R5G6B5 = 23; - static const uint D3DFMT_X1R5G5B5 = 24; - static const uint D3DFMT_A1R5G5B5 = 25; - static const uint D3DFMT_A4R4G4B4 = 26; - static const uint D3DFMT_R3G3B2 = 27; - static const uint D3DFMT_A8 = 28; - static const uint D3DFMT_A8R3G3B2 = 29; - static const uint D3DFMT_X4R4G4B4 = 30; - static const uint D3DFMT_A2B10G10R10 = 31; - static const uint D3DFMT_A8B8G8R8 = 32; - static const uint D3DFMT_X8B8G8R8 = 33; - static const uint D3DFMT_G16R16 = 34; - static const uint D3DFMT_A2R10G10B10 = 35; - - static const uint D3DFMT_A16B16G16R16 = 36; - - // Palette formats. - static const uint D3DFMT_A8P8 = 40; - static const uint D3DFMT_P8 = 41; - - // Luminance formats. - static const uint D3DFMT_L8 = 50; - static const uint D3DFMT_A8L8 = 51; - static const uint D3DFMT_A4L4 = 52; - static const uint D3DFMT_L16 = 81; - - // Floating point formats - static const uint D3DFMT_R16F = 111; - static const uint D3DFMT_G16R16F = 112; - static const uint D3DFMT_A16B16G16R16F = 113; - static const uint D3DFMT_R32F = 114; - static const uint D3DFMT_G32R32F = 115; - static const uint D3DFMT_A32B32G32R32F = 116; - - static const uint DDSD_CAPS = 0x00000001U; - static const uint DDSD_PIXELFORMAT = 0x00001000U; - static const uint DDSD_WIDTH = 0x00000004U; - static const uint DDSD_HEIGHT = 0x00000002U; - static const uint DDSD_PITCH = 0x00000008U; - static const uint DDSD_MIPMAPCOUNT = 0x00020000U; - static const uint DDSD_LINEARSIZE = 0x00080000U; - static const uint DDSD_DEPTH = 0x00800000U; - - static const uint DDSCAPS_COMPLEX = 0x00000008U; - static const uint DDSCAPS_TEXTURE = 0x00001000U; - static const uint DDSCAPS_MIPMAP = 0x00400000U; - static const uint DDSCAPS2_VOLUME = 0x00200000U; - static const uint DDSCAPS2_CUBEMAP = 0x00000200U; - - static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U; - static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U; - static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U; - static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U; - static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U; - static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U; - static const uint DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U; - - static const uint DDPF_ALPHAPIXELS = 0x00000001U; - static const uint DDPF_ALPHA = 0x00000002U; - static const uint DDPF_FOURCC = 0x00000004U; - static const uint DDPF_RGB = 0x00000040U; - static const uint DDPF_PALETTEINDEXED1 = 0x00000800U; - static const uint DDPF_PALETTEINDEXED2 = 0x00001000U; - static const uint DDPF_PALETTEINDEXED4 = 0x00000008U; - static const uint DDPF_PALETTEINDEXED8 = 0x00000020U; - static const uint DDPF_LUMINANCE = 0x00020000U; - static const uint DDPF_ALPHAPREMULT = 0x00008000U; - static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. - - // DX10 formats. - enum DXGI_FORMAT - { - DXGI_FORMAT_UNKNOWN = 0, - - DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, - DXGI_FORMAT_R32G32B32A32_FLOAT = 2, - DXGI_FORMAT_R32G32B32A32_UINT = 3, - DXGI_FORMAT_R32G32B32A32_SINT = 4, - - DXGI_FORMAT_R32G32B32_TYPELESS = 5, - DXGI_FORMAT_R32G32B32_FLOAT = 6, - DXGI_FORMAT_R32G32B32_UINT = 7, - DXGI_FORMAT_R32G32B32_SINT = 8, - - DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, - DXGI_FORMAT_R16G16B16A16_FLOAT = 10, - DXGI_FORMAT_R16G16B16A16_UNORM = 11, - DXGI_FORMAT_R16G16B16A16_UINT = 12, - DXGI_FORMAT_R16G16B16A16_SNORM = 13, - DXGI_FORMAT_R16G16B16A16_SINT = 14, - - DXGI_FORMAT_R32G32_TYPELESS = 15, - DXGI_FORMAT_R32G32_FLOAT = 16, - DXGI_FORMAT_R32G32_UINT = 17, - DXGI_FORMAT_R32G32_SINT = 18, - - DXGI_FORMAT_R32G8X24_TYPELESS = 19, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, - DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, - - DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, - DXGI_FORMAT_R10G10B10A2_UNORM = 24, - DXGI_FORMAT_R10G10B10A2_UINT = 25, - - DXGI_FORMAT_R11G11B10_FLOAT = 26, - - DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, - DXGI_FORMAT_R8G8B8A8_UNORM = 28, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, - DXGI_FORMAT_R8G8B8A8_UINT = 30, - DXGI_FORMAT_R8G8B8A8_SNORM = 31, - DXGI_FORMAT_R8G8B8A8_SINT = 32, - - DXGI_FORMAT_R16G16_TYPELESS = 33, - DXGI_FORMAT_R16G16_FLOAT = 34, - DXGI_FORMAT_R16G16_UNORM = 35, - DXGI_FORMAT_R16G16_UINT = 36, - DXGI_FORMAT_R16G16_SNORM = 37, - DXGI_FORMAT_R16G16_SINT = 38, - - DXGI_FORMAT_R32_TYPELESS = 39, - DXGI_FORMAT_D32_FLOAT = 40, - DXGI_FORMAT_R32_FLOAT = 41, - DXGI_FORMAT_R32_UINT = 42, - DXGI_FORMAT_R32_SINT = 43, - - DXGI_FORMAT_R24G8_TYPELESS = 44, - DXGI_FORMAT_D24_UNORM_S8_UINT = 45, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, - DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, - - DXGI_FORMAT_R8G8_TYPELESS = 48, - DXGI_FORMAT_R8G8_UNORM = 49, - DXGI_FORMAT_R8G8_UINT = 50, - DXGI_FORMAT_R8G8_SNORM = 51, - DXGI_FORMAT_R8G8_SINT = 52, - - DXGI_FORMAT_R16_TYPELESS = 53, - DXGI_FORMAT_R16_FLOAT = 54, - DXGI_FORMAT_D16_UNORM = 55, - DXGI_FORMAT_R16_UNORM = 56, - DXGI_FORMAT_R16_UINT = 57, - DXGI_FORMAT_R16_SNORM = 58, - DXGI_FORMAT_R16_SINT = 59, - - DXGI_FORMAT_R8_TYPELESS = 60, - DXGI_FORMAT_R8_UNORM = 61, - DXGI_FORMAT_R8_UINT = 62, - DXGI_FORMAT_R8_SNORM = 63, - DXGI_FORMAT_R8_SINT = 64, - DXGI_FORMAT_A8_UNORM = 65, - - DXGI_FORMAT_R1_UNORM = 66, - - DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, - - DXGI_FORMAT_R8G8_B8G8_UNORM = 68, - DXGI_FORMAT_G8R8_G8B8_UNORM = 69, - - DXGI_FORMAT_BC1_TYPELESS = 70, - DXGI_FORMAT_BC1_UNORM = 71, - DXGI_FORMAT_BC1_UNORM_SRGB = 72, - - DXGI_FORMAT_BC2_TYPELESS = 73, - DXGI_FORMAT_BC2_UNORM = 74, - DXGI_FORMAT_BC2_UNORM_SRGB = 75, - - DXGI_FORMAT_BC3_TYPELESS = 76, - DXGI_FORMAT_BC3_UNORM = 77, - DXGI_FORMAT_BC3_UNORM_SRGB = 78, - - DXGI_FORMAT_BC4_TYPELESS = 79, - DXGI_FORMAT_BC4_UNORM = 80, - DXGI_FORMAT_BC4_SNORM = 81, - - DXGI_FORMAT_BC5_TYPELESS = 82, - DXGI_FORMAT_BC5_UNORM = 83, - DXGI_FORMAT_BC5_SNORM = 84, - - DXGI_FORMAT_B5G6R5_UNORM = 85, - DXGI_FORMAT_B5G5R5A1_UNORM = 86, - DXGI_FORMAT_B8G8R8A8_UNORM = 87, - DXGI_FORMAT_B8G8R8X8_UNORM = 88, - }; - - enum D3D10_RESOURCE_DIMENSION - { - D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, - D3D10_RESOURCE_DIMENSION_BUFFER = 1, - D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, - D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, - D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4, - }; - - - const char * getDxgiFormatString(DXGI_FORMAT dxgiFormat) - { -#define CASE(format) case DXGI_FORMAT_##format: return #format - switch(dxgiFormat) - { - CASE(UNKNOWN); - - CASE(R32G32B32A32_TYPELESS); - CASE(R32G32B32A32_FLOAT); - CASE(R32G32B32A32_UINT); - CASE(R32G32B32A32_SINT); - - CASE(R32G32B32_TYPELESS); - CASE(R32G32B32_FLOAT); - CASE(R32G32B32_UINT); - CASE(R32G32B32_SINT); - - CASE(R16G16B16A16_TYPELESS); - CASE(R16G16B16A16_FLOAT); - CASE(R16G16B16A16_UNORM); - CASE(R16G16B16A16_UINT); - CASE(R16G16B16A16_SNORM); - CASE(R16G16B16A16_SINT); - - CASE(R32G32_TYPELESS); - CASE(R32G32_FLOAT); - CASE(R32G32_UINT); - CASE(R32G32_SINT); - - CASE(R32G8X24_TYPELESS); - CASE(D32_FLOAT_S8X24_UINT); - CASE(R32_FLOAT_X8X24_TYPELESS); - CASE(X32_TYPELESS_G8X24_UINT); - - CASE(R10G10B10A2_TYPELESS); - CASE(R10G10B10A2_UNORM); - CASE(R10G10B10A2_UINT); - - CASE(R11G11B10_FLOAT); - - CASE(R8G8B8A8_TYPELESS); - CASE(R8G8B8A8_UNORM); - CASE(R8G8B8A8_UNORM_SRGB); - CASE(R8G8B8A8_UINT); - CASE(R8G8B8A8_SNORM); - CASE(R8G8B8A8_SINT); - - CASE(R16G16_TYPELESS); - CASE(R16G16_FLOAT); - CASE(R16G16_UNORM); - CASE(R16G16_UINT); - CASE(R16G16_SNORM); - CASE(R16G16_SINT); - - CASE(R32_TYPELESS); - CASE(D32_FLOAT); - CASE(R32_FLOAT); - CASE(R32_UINT); - CASE(R32_SINT); - - CASE(R24G8_TYPELESS); - CASE(D24_UNORM_S8_UINT); - CASE(R24_UNORM_X8_TYPELESS); - CASE(X24_TYPELESS_G8_UINT); - - CASE(R8G8_TYPELESS); - CASE(R8G8_UNORM); - CASE(R8G8_UINT); - CASE(R8G8_SNORM); - CASE(R8G8_SINT); - - CASE(R16_TYPELESS); - CASE(R16_FLOAT); - CASE(D16_UNORM); - CASE(R16_UNORM); - CASE(R16_UINT); - CASE(R16_SNORM); - CASE(R16_SINT); - - CASE(R8_TYPELESS); - CASE(R8_UNORM); - CASE(R8_UINT); - CASE(R8_SNORM); - CASE(R8_SINT); - CASE(A8_UNORM); - - CASE(R1_UNORM); - - CASE(R9G9B9E5_SHAREDEXP); - - CASE(R8G8_B8G8_UNORM); - CASE(G8R8_G8B8_UNORM); - - CASE(BC1_TYPELESS); - CASE(BC1_UNORM); - CASE(BC1_UNORM_SRGB); - - CASE(BC2_TYPELESS); - CASE(BC2_UNORM); - CASE(BC2_UNORM_SRGB); - - CASE(BC3_TYPELESS); - CASE(BC3_UNORM); - CASE(BC3_UNORM_SRGB); - - CASE(BC4_TYPELESS); - CASE(BC4_UNORM); - CASE(BC4_SNORM); - - CASE(BC5_TYPELESS); - CASE(BC5_UNORM); - CASE(BC5_SNORM); - - CASE(B5G6R5_UNORM); - CASE(B5G5R5A1_UNORM); - CASE(B8G8R8A8_UNORM); - CASE(B8G8R8X8_UNORM); - - default: - return "UNKNOWN"; - } -#undef CASE - } - - const char * getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension) - { - switch(resourceDimension) - { - default: - case D3D10_RESOURCE_DIMENSION_UNKNOWN: return "UNKNOWN"; - case D3D10_RESOURCE_DIMENSION_BUFFER: return "BUFFER"; - case D3D10_RESOURCE_DIMENSION_TEXTURE1D: return "TEXTURE1D"; - case D3D10_RESOURCE_DIMENSION_TEXTURE2D: return "TEXTURE2D"; - case D3D10_RESOURCE_DIMENSION_TEXTURE3D: return "TEXTURE3D"; - } - } - -} // namespace - -namespace nv -{ - static Stream & operator<< (Stream & s, DDSPixelFormat & pf) - { - nvStaticCheck(sizeof(DDSPixelFormat) == 32); - s << pf.size; - s << pf.flags; - s << pf.fourcc; - s << pf.bitcount; - s << pf.rmask; - s << pf.gmask; - s << pf.bmask; - s << pf.amask; - return s; - } - - static Stream & operator<< (Stream & s, DDSCaps & caps) - { - nvStaticCheck(sizeof(DDSCaps) == 16); - s << caps.caps1; - s << caps.caps2; - s << caps.caps3; - s << caps.caps4; - return s; - } - - static Stream & operator<< (Stream & s, DDSHeader10 & header) - { - nvStaticCheck(sizeof(DDSHeader10) == 20); - s << header.dxgiFormat; - s << header.resourceDimension; - s << header.miscFlag; - s << header.arraySize; - s << header.reserved; - return s; - } - - Stream & operator<< (Stream & s, DDSHeader & header) - { - nvStaticCheck(sizeof(DDSHeader) == 148); - s << header.fourcc; - s << header.size; - s << header.flags; - s << header.height; - s << header.width; - s << header.pitch; - s << header.depth; - s << header.mipmapcount; - s.serialize(header.reserved, 11 * sizeof(uint)); - s << header.pf; - s << header.caps; - s << header.notused; - - if (header.hasDX10Header()) - { - s << header.header10; - } - - return s; - } - -} // nv namespace - -/* Not used! -namespace -{ - struct FormatDescriptor - { - uint format; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; - }; - - static const FormatDescriptor s_d3dFormats[] = - { - { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 }, - { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM - { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM - { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM - { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 }, - { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM - { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 }, - { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 }, - { D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM - { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 }, - { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 }, - { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2 - { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM - { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 }, - { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM - { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 }, - - { D3DFMT_L8, 8, 8, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM - { D3DFMT_L16, 16, 16, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM - }; - - static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]); - - static uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) - { - for (int i = 0; i < s_d3dFormatCount; i++) - { - if (s_d3dFormats[i].bitcount == bitcount && - s_d3dFormats[i].rmask == rmask && - s_d3dFormats[i].gmask == gmask && - s_d3dFormats[i].bmask == bmask && - s_d3dFormats[i].amask == amask) - { - return s_d3dFormats[i].format; - } - } - - return 0; - } - -} // nv namespace -*/ - -DDSHeader::DDSHeader() -{ - this->fourcc = FOURCC_DDS; - this->size = 124; - this->flags = (DDSD_CAPS|DDSD_PIXELFORMAT); - this->height = 0; - this->width = 0; - this->pitch = 0; - this->depth = 0; - this->mipmapcount = 0; - memset(this->reserved, 0, sizeof(this->reserved)); - - // Store version information on the reserved header attributes. - this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T'); - this->reserved[10] = (2 << 16) | (0 << 8) | (8); // major.minor.revision - - this->pf.size = 32; - this->pf.flags = 0; - this->pf.fourcc = 0; - this->pf.bitcount = 0; - this->pf.rmask = 0; - this->pf.gmask = 0; - this->pf.bmask = 0; - this->pf.amask = 0; - this->caps.caps1 = DDSCAPS_TEXTURE; - this->caps.caps2 = 0; - this->caps.caps3 = 0; - this->caps.caps4 = 0; - this->notused = 0; - - this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN; - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; - this->header10.miscFlag = 0; - this->header10.arraySize = 0; - this->header10.reserved = 0; -} - -void DDSHeader::setWidth(uint w) -{ - this->flags |= DDSD_WIDTH; - this->width = w; -} - -void DDSHeader::setHeight(uint h) -{ - this->flags |= DDSD_HEIGHT; - this->height = h; -} - -void DDSHeader::setDepth(uint d) -{ - this->flags |= DDSD_DEPTH; - this->height = d; -} - -void DDSHeader::setMipmapCount(uint count) -{ - if (count == 0 || count == 1) - { - this->flags &= ~DDSD_MIPMAPCOUNT; - this->mipmapcount = 0; - - if (this->caps.caps2 == 0) { - this->caps.caps1 = DDSCAPS_TEXTURE; - } - else { - this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX; - } - } - else - { - this->flags |= DDSD_MIPMAPCOUNT; - this->mipmapcount = count; - - this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - } -} - -void DDSHeader::setTexture2D() -{ - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; -} - -void DDSHeader::setTexture3D() -{ - this->caps.caps2 = DDSCAPS2_VOLUME; - - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; -} - -void DDSHeader::setTextureCube() -{ - this->caps.caps1 |= DDSCAPS_COMPLEX; - this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES; - - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - this->header10.arraySize = 6; -} - -void DDSHeader::setLinearSize(uint size) -{ - this->flags &= ~DDSD_PITCH; - this->flags |= DDSD_LINEARSIZE; - this->pitch = size; -} - -void DDSHeader::setPitch(uint pitch) -{ - this->flags &= ~DDSD_LINEARSIZE; - this->flags |= DDSD_PITCH; - this->pitch = pitch; -} - -void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3) -{ - // set fourcc pixel format. - this->pf.flags = DDPF_FOURCC; - this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3); - - if (this->pf.fourcc == FOURCC_ATI2) - { - this->pf.bitcount = FOURCC_A2XY; - } - else - { - this->pf.bitcount = 0; - } - - this->pf.rmask = 0; - this->pf.gmask = 0; - this->pf.bmask = 0; - this->pf.amask = 0; -} - -void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) -{ - // Make sure the masks are correct. - nvCheck((rmask & gmask) == 0); - nvCheck((rmask & bmask) == 0); - nvCheck((rmask & amask) == 0); - nvCheck((gmask & bmask) == 0); - nvCheck((gmask & amask) == 0); - nvCheck((bmask & amask) == 0); - - this->pf.flags = DDPF_RGB; - - if (amask != 0) { - this->pf.flags |= DDPF_ALPHAPIXELS; - } - - if (bitcount == 0) - { - // Compute bit count from the masks. - uint total = rmask | gmask | bmask | amask; - while(total != 0) { - bitcount++; - total >>= 1; - } - } - - nvCheck(bitcount > 0 && bitcount <= 32); - - // Align to 8. - if (bitcount <= 8) bitcount = 8; - else if (bitcount <= 16) bitcount = 16; - else if (bitcount <= 24) bitcount = 24; - else bitcount = 32; - - this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); - this->pf.bitcount = bitcount; - this->pf.rmask = rmask; - this->pf.gmask = gmask; - this->pf.bmask = bmask; - this->pf.amask = amask; -} - -void DDSHeader::setDX10Format(uint format) -{ - //this->pf.flags = 0; - this->pf.fourcc = FOURCC_DX10; - this->header10.dxgiFormat = format; -} - -void DDSHeader::setNormalFlag(bool b) -{ - if (b) this->pf.flags |= DDPF_NORMAL; - else this->pf.flags &= ~DDPF_NORMAL; -} - -void DDSHeader::swapBytes() -{ - this->fourcc = POSH_LittleU32(this->fourcc); - this->size = POSH_LittleU32(this->size); - this->flags = POSH_LittleU32(this->flags); - this->height = POSH_LittleU32(this->height); - this->width = POSH_LittleU32(this->width); - this->pitch = POSH_LittleU32(this->pitch); - this->depth = POSH_LittleU32(this->depth); - this->mipmapcount = POSH_LittleU32(this->mipmapcount); - - for(int i = 0; i < 11; i++) { - this->reserved[i] = POSH_LittleU32(this->reserved[i]); - } - - this->pf.size = POSH_LittleU32(this->pf.size); - this->pf.flags = POSH_LittleU32(this->pf.flags); - this->pf.fourcc = POSH_LittleU32(this->pf.fourcc); - this->pf.bitcount = POSH_LittleU32(this->pf.bitcount); - this->pf.rmask = POSH_LittleU32(this->pf.rmask); - this->pf.gmask = POSH_LittleU32(this->pf.gmask); - this->pf.bmask = POSH_LittleU32(this->pf.bmask); - this->pf.amask = POSH_LittleU32(this->pf.amask); - this->caps.caps1 = POSH_LittleU32(this->caps.caps1); - this->caps.caps2 = POSH_LittleU32(this->caps.caps2); - this->caps.caps3 = POSH_LittleU32(this->caps.caps3); - this->caps.caps4 = POSH_LittleU32(this->caps.caps4); - this->notused = POSH_LittleU32(this->notused); - - this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat); - this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension); - this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag); - this->header10.arraySize = POSH_LittleU32(this->header10.arraySize); - this->header10.reserved = POSH_LittleU32(this->header10.reserved); -} - -bool DDSHeader::hasDX10Header() const -{ - return this->pf.fourcc == FOURCC_DX10; // @@ This is according to AMD - //return this->pf.flags == 0; // @@ This is according to MS -} - - - -DirectDrawSurface::DirectDrawSurface(const char * name) : stream(new StdInputStream(name)) -{ - if (!stream->isError()) - { - (*stream) << header; - } -} - -DirectDrawSurface::~DirectDrawSurface() -{ - delete stream; -} - -bool DirectDrawSurface::isValid() const -{ - if (stream->isError()) - { - return false; - } - - if (header.fourcc != FOURCC_DDS || header.size != 124) - { - return false; - } - - const uint required = (DDSD_WIDTH|DDSD_HEIGHT/*|DDSD_CAPS|DDSD_PIXELFORMAT*/); - if( (header.flags & required) != required ) { - return false; - } - - if (header.pf.size != 32) { - return false; - } - - if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) { - return false; - } - - return true; -} - -bool DirectDrawSurface::isSupported() const -{ - nvDebugCheck(isValid()); - - if (header.hasDX10Header()) - { - } - else - { - if (header.pf.flags & DDPF_FOURCC) - { - if (header.pf.fourcc != FOURCC_DXT1 && - header.pf.fourcc != FOURCC_DXT2 && - header.pf.fourcc != FOURCC_DXT3 && - header.pf.fourcc != FOURCC_DXT4 && - header.pf.fourcc != FOURCC_DXT5 && - header.pf.fourcc != FOURCC_RXGB && - header.pf.fourcc != FOURCC_ATI1 && - header.pf.fourcc != FOURCC_ATI2) - { - // Unknown fourcc code. - return false; - } - } - else if (header.pf.flags & DDPF_RGB) - { - // All RGB formats are supported now. - } - else - { - return false; - } - - if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) - { - // Cubemaps must contain all faces. - return false; - } - - if (isTexture3D()) - { - // @@ 3D textures not supported yet. - return false; - } - } - - return true; -} - - -uint DirectDrawSurface::mipmapCount() const -{ - nvDebugCheck(isValid()); - if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount; - else return 1; -} - - -uint DirectDrawSurface::width() const -{ - nvDebugCheck(isValid()); - if (header.flags & DDSD_WIDTH) return header.width; - else return 1; -} - -uint DirectDrawSurface::height() const -{ - nvDebugCheck(isValid()); - if (header.flags & DDSD_HEIGHT) return header.height; - else return 1; -} - -uint DirectDrawSurface::depth() const -{ - nvDebugCheck(isValid()); - if (header.flags & DDSD_DEPTH) return header.depth; - else return 1; -} - -bool DirectDrawSurface::isTexture1D() const -{ - nvDebugCheck(isValid()); - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D; - } - return false; -} - -bool DirectDrawSurface::isTexture2D() const -{ - nvDebugCheck(isValid()); - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D; - } - else - { - return !isTexture3D() && !isTextureCube(); - } -} - -bool DirectDrawSurface::isTexture3D() const -{ - nvDebugCheck(isValid()); - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D; - } - else - { - return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0; - } -} - -bool DirectDrawSurface::isTextureCube() const -{ - nvDebugCheck(isValid()); - return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0; -} - -void DirectDrawSurface::setNormalFlag(bool b) -{ - nvDebugCheck(isValid()); - header.setNormalFlag(b); -} - -void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap) -{ - nvDebugCheck(isValid()); - - stream->seek(offset(face, mipmap)); - - uint w = width(); - uint h = height(); - - // Compute width and height. - for (uint m = 0; m < mipmap; m++) - { - w = max(1U, w / 2); - h = max(1U, h / 2); - } - - img->allocate(w, h); - - if (header.pf.flags & DDPF_RGB) - { - readLinearImage(img); - } - else if (header.pf.flags & DDPF_FOURCC) - { - readBlockImage(img); - } -} - -void DirectDrawSurface::readLinearImage(Image * img) -{ - nvDebugCheck(stream != NULL); - nvDebugCheck(img != NULL); - - const uint w = img->width(); - const uint h = img->height(); - - uint rshift, rsize; - PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize); - - uint gshift, gsize; - PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize); - - uint bshift, bsize; - PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize); - - uint ashift, asize; - PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize); - - uint byteCount = (header.pf.bitcount + 7) / 8; - - // set image format: RGB or ARGB - // alpha channel exists if and only if the alpha mask is non-zero - if (header.pf.amask == 0) - { - img->setFormat(Image::Format_RGB); - } - else - { - img->setFormat(Image::Format_ARGB); - } - - // Read linear RGB images. - for (uint y = 0; y < h; y++) - { - for (uint x = 0; x < w; x++) - { - uint c = 0; - stream->serialize(&c, byteCount); - - Color32 pixel(0, 0, 0, 0xFF); - pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8); - pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8); - pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8); - pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8); - - img->pixel(x, y) = pixel; - } - } -} - -void DirectDrawSurface::readBlockImage(Image * img) -{ - nvDebugCheck(stream != NULL); - nvDebugCheck(img != NULL); - - // set image format: RGB or ARGB - if (header.pf.fourcc == FOURCC_RXGB || - header.pf.fourcc == FOURCC_ATI1 || - header.pf.fourcc == FOURCC_ATI2 || - header.pf.flags & DDPF_NORMAL) - { - img->setFormat(Image::Format_RGB); - } - else - { - img->setFormat(Image::Format_ARGB); - } - - const uint w = img->width(); - const uint h = img->height(); - - const uint bw = (w + 3) / 4; - const uint bh = (h + 3) / 4; - - for (uint by = 0; by < bh; by++) - { - for (uint bx = 0; bx < bw; bx++) - { - ColorBlock block; - - // Read color block. - readBlock(&block); - - // Write color block. - for (uint y = 0; y < min(4U, h-4*by); y++) - { - for (uint x = 0; x < min(4U, w-4*bx); x++) - { - img->pixel(4*bx+x, 4*by+y) = block.color(x, y); - } - } - } - } -} - -static Color32 buildNormal(uint8 x, uint8 y) -{ - float nx = 2 * (x / 255.0f) - 1; - float ny = 2 * (y / 255.0f) - 1; - float nz = 0.0f; - if (1 - nx*nx - ny*ny > 0) nz = sqrtf(1 - nx*nx - ny*ny); - uint8 z = clamp(int(255.0f * (nz + 1) / 2.0f), 0, 255); - - return Color32(x, y, z); -} - - -void DirectDrawSurface::readBlock(ColorBlock * rgba) -{ - nvDebugCheck(stream != NULL); - nvDebugCheck(rgba != NULL); - - if (header.pf.fourcc == FOURCC_DXT1) - { - BlockDXT1 block; - *stream << block; - block.decodeBlock(rgba); - } - else if (header.pf.fourcc == FOURCC_DXT2 || - header.pf.fourcc == FOURCC_DXT3) - { - BlockDXT3 block; - *stream << block; - block.decodeBlock(rgba); - } - else if (header.pf.fourcc == FOURCC_DXT4 || - header.pf.fourcc == FOURCC_DXT5 || - header.pf.fourcc == FOURCC_RXGB) - { - BlockDXT5 block; - *stream << block; - block.decodeBlock(rgba); - - if (header.pf.fourcc == FOURCC_RXGB) - { - // Swap R & A. - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - uint tmp = c.r; - c.r = c.a; - c.a = tmp; - } - } - } - else if (header.pf.fourcc == FOURCC_ATI1) - { - BlockATI1 block; - *stream << block; - block.decodeBlock(rgba); - } - else if (header.pf.fourcc == FOURCC_ATI2) - { - BlockATI2 block; - *stream << block; - block.decodeBlock(rgba); - } - - // If normal flag set, convert to normal. - if (header.pf.flags & DDPF_NORMAL) - { - if (header.pf.fourcc == FOURCC_ATI2) - { - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - c = buildNormal(c.r, c.g); - } - } - else if (header.pf.fourcc == FOURCC_DXT5) - { - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - c = buildNormal(c.a, c.g); - } - } - } -} - - -uint DirectDrawSurface::blockSize() const -{ - switch(header.pf.fourcc) - { - case FOURCC_DXT1: - case FOURCC_ATI1: - return 8; - case FOURCC_DXT2: - case FOURCC_DXT3: - case FOURCC_DXT4: - case FOURCC_DXT5: - case FOURCC_RXGB: - case FOURCC_ATI2: - return 16; - }; - - // Not a block image. - return 0; -} - -uint DirectDrawSurface::mipmapSize(uint mipmap) const -{ - uint w = width(); - uint h = height(); - uint d = depth(); - - for (uint m = 0; m < mipmap; m++) - { - w = max(1U, w / 2); - h = max(1U, h / 2); - d = max(1U, d / 2); - } - - if (header.pf.flags & DDPF_FOURCC) - { - // @@ How are 3D textures aligned? - w = (w + 3) / 4; - h = (h + 3) / 4; - return blockSize() * w * h; - } - else - { - nvDebugCheck(header.pf.flags & DDPF_RGB); - - // Align pixels to bytes. - uint byteCount = (header.pf.bitcount + 7) / 8; - - // Align pitch to 4 bytes. - uint pitch = 4 * ((w * byteCount + 3) / 4); - - return pitch * h * d; - } -} - -uint DirectDrawSurface::faceSize() const -{ - const uint count = mipmapCount(); - uint size = 0; - - for (uint m = 0; m < count; m++) - { - size += mipmapSize(m); - } - - return size; -} - -uint DirectDrawSurface::offset(const uint face, const uint mipmap) -{ - uint size = 128; // sizeof(DDSHeader); - - if (header.hasDX10Header()) - { - size += 20; // sizeof(DDSHeader10); - } - - if (face != 0) - { - size += face * faceSize(); - } - - for (uint m = 0; m < mipmap; m++) - { - size += mipmapSize(m); - } - - return size; -} - - -void DirectDrawSurface::printInfo() const -{ - printf("Flags: 0x%.8X\n", header.flags); - if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n"); - if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n"); - if (header.flags & DDSD_WIDTH) printf("\tDDSD_WIDTH\n"); - if (header.flags & DDSD_HEIGHT) printf("\tDDSD_HEIGHT\n"); - if (header.flags & DDSD_DEPTH) printf("\tDDSD_DEPTH\n"); - if (header.flags & DDSD_PITCH) printf("\tDDSD_PITCH\n"); - if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n"); - if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n"); - - printf("Height: %u\n", header.height); - printf("Width: %u\n", header.width); - printf("Depth: %u\n", header.depth); - if (header.flags & DDSD_PITCH) printf("Pitch: %u\n", header.pitch); - else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %u\n", header.pitch); - printf("Mipmap count: %u\n", header.mipmapcount); - - printf("Pixel Format:\n"); - printf("\tFlags: 0x%.8X\n", header.pf.flags); - if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n"); - if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n"); - if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n"); - if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED1) printf("\t\tDDPF_PALETTEINDEXED1\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED2) printf("\t\tDDPF_PALETTEINDEXED2\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED4) printf("\t\tDDPF_PALETTEINDEXED4\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED8) printf("\t\tDDPF_PALETTEINDEXED8\n"); - if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n"); - if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n"); - - printf("\tFourCC: '%c%c%c%c'\n", - ((header.pf.fourcc >> 0) & 0xFF), - ((header.pf.fourcc >> 8) & 0xFF), - ((header.pf.fourcc >> 16) & 0xFF), - ((header.pf.fourcc >> 24) & 0xFF)); - if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0)) - { - printf("\tSwizzle: '%c%c%c%c'\n", - (header.pf.bitcount >> 0) & 0xFF, - (header.pf.bitcount >> 8) & 0xFF, - (header.pf.bitcount >> 16) & 0xFF, - (header.pf.bitcount >> 24) & 0xFF); - } - else - { - printf("\tBit count: %u\n", header.pf.bitcount); - } - printf("\tRed mask: 0x%.8X\n", header.pf.rmask); - printf("\tGreen mask: 0x%.8X\n", header.pf.gmask); - printf("\tBlue mask: 0x%.8X\n", header.pf.bmask); - printf("\tAlpha mask: 0x%.8X\n", header.pf.amask); - - printf("Caps:\n"); - printf("\tCaps 1: 0x%.8X\n", header.caps.caps1); - if (header.caps.caps1 & DDSCAPS_COMPLEX) printf("\t\tDDSCAPS_COMPLEX\n"); - if (header.caps.caps1 & DDSCAPS_TEXTURE) printf("\t\tDDSCAPS_TEXTURE\n"); - if (header.caps.caps1 & DDSCAPS_MIPMAP) printf("\t\tDDSCAPS_MIPMAP\n"); - - printf("\tCaps 2: 0x%.8X\n", header.caps.caps2); - if (header.caps.caps2 & DDSCAPS2_VOLUME) printf("\t\tDDSCAPS2_VOLUME\n"); - else if (header.caps.caps2 & DDSCAPS2_CUBEMAP) - { - printf("\t\tDDSCAPS2_CUBEMAP\n"); - if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n"); - else { - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n"); - } - } - - printf("\tCaps 3: 0x%.8X\n", header.caps.caps3); - printf("\tCaps 4: 0x%.8X\n", header.caps.caps4); - - if (header.hasDX10Header()) - { - printf("DX10 Header:\n"); - printf("\tDXGI Format: %u (%s)\n", header.header10.dxgiFormat, getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat)); - printf("\tResource dimension: %u (%s)\n", header.header10.resourceDimension, getD3d10ResourceDimensionString((D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension)); - printf("\tMisc flag: %u\n", header.header10.miscFlag); - printf("\tArray size: %u\n", header.header10.arraySize); - } - - if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T')) - { - int major = (header.reserved[10] >> 16) & 0xFF; - int minor = (header.reserved[10] >> 8) & 0xFF; - int revision= header.reserved[10] & 0xFF; - - printf("Version:\n"); - printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision); - } -} - diff --git a/Externals/NVTT/src/nvimage/DirectDrawSurface.h b/Externals/NVTT/src/nvimage/DirectDrawSurface.h deleted file mode 100644 index 6ea8c4ba362..00000000000 --- a/Externals/NVTT/src/nvimage/DirectDrawSurface.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_IMAGE_DIRECTDRAWSURFACE_H -#define NV_IMAGE_DIRECTDRAWSURFACE_H - -#include - -namespace nv -{ - class Image; - class Stream; - struct ColorBlock; - - struct NVIMAGE_CLASS DDSPixelFormat - { - uint size; - uint flags; - uint fourcc; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; - }; - - struct NVIMAGE_CLASS DDSCaps - { - uint caps1; - uint caps2; - uint caps3; - uint caps4; - }; - - /// DDS file header for DX10. - struct NVIMAGE_CLASS DDSHeader10 - { - uint dxgiFormat; - uint resourceDimension; - uint miscFlag; - uint arraySize; - uint reserved; - }; - - /// DDS file header. - struct NVIMAGE_CLASS DDSHeader - { - uint fourcc; - uint size; - uint flags; - uint height; - uint width; - uint pitch; - uint depth; - uint mipmapcount; - uint reserved[11]; - DDSPixelFormat pf; - DDSCaps caps; - uint notused; - DDSHeader10 header10; - - - // Helper methods. - DDSHeader(); - - void setWidth(uint w); - void setHeight(uint h); - void setDepth(uint d); - void setMipmapCount(uint count); - void setTexture2D(); - void setTexture3D(); - void setTextureCube(); - void setLinearSize(uint size); - void setPitch(uint pitch); - void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); - void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); - void setDX10Format(uint format); - void setNormalFlag(bool b); - - void swapBytes(); - - bool hasDX10Header() const; - }; - - NVIMAGE_API Stream & operator<< (Stream & s, DDSHeader & header); - - - /// DirectDraw Surface. (DDS) - class NVIMAGE_CLASS DirectDrawSurface - { - public: - DirectDrawSurface(const char * file); - ~DirectDrawSurface(); - - bool isValid() const; - bool isSupported() const; - - uint mipmapCount() const; - uint width() const; - uint height() const; - uint depth() const; - bool isTexture1D() const; - bool isTexture2D() const; - bool isTexture3D() const; - bool isTextureCube() const; - - void setNormalFlag(bool b); - - void mipmap(Image * img, uint f, uint m); - // void mipmap(FloatImage * img, uint f, uint m); - - void printInfo() const; - - private: - - uint blockSize() const; - uint faceSize() const; - uint mipmapSize(uint m) const; - - uint offset(uint f, uint m); - - void readLinearImage(Image * img); - void readBlockImage(Image * img); - void readBlock(ColorBlock * rgba); - - - private: - Stream * const stream; - DDSHeader header; - DDSHeader10 header10; - }; - -} // nv namespace - -#endif // NV_IMAGE_DIRECTDRAWSURFACE_H diff --git a/Externals/NVTT/src/nvimage/Filter.cpp b/Externals/NVTT/src/nvimage/Filter.cpp deleted file mode 100644 index c460f42e078..00000000000 --- a/Externals/NVTT/src/nvimage/Filter.cpp +++ /dev/null @@ -1,604 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -/** @file Filter.cpp - * @brief Image filters. - * - * Jonathan Blow articles: - * http://number-none.com/product/Mipmapping, Part 1/index.html - * http://number-none.com/product/Mipmapping, Part 2/index.html - * - * References from Thacher Ulrich: - * See _Graphics Gems III_ "General Filtered Image Rescaling", Dale A. Schumacher - * http://tog.acm.org/GraphicsGems/gemsiii/filter.c - * - * References from Paul Heckbert: - * A.V. Oppenheim, R.W. Schafer, Digital Signal Processing, Prentice-Hall, 1975 - * - * R.W. Hamming, Digital Filters, Prentice-Hall, Englewood Cliffs, NJ, 1983 - * - * W.K. Pratt, Digital Image Processing, John Wiley and Sons, 1978 - * - * H.S. Hou, H.C. Andrews, "Cubic Splines for Image Interpolation and - * Digital Filtering", IEEE Trans. Acoustics, Speech, and Signal Proc., - * vol. ASSP-26, no. 6, Dec. 1978, pp. 508-517 - * - * Paul Heckbert's zoom library. - * http://www.xmission.com/~legalize/zoom.html - * - * Reconstruction Filters in Computer Graphics - * http://www.mentallandscape.com/Papers_siggraph88.pdf - * - * More references: - * http://www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf - * http://www.dspguide.com/ch16.htm - */ - -#include "Filter.h" - -#include // Vector4 -#include // swap - -using namespace nv; - -namespace -{ - // Sinc function. - inline static float sincf(const float x) - { - if (fabs(x) < NV_EPSILON) { - //return 1.0; - return 1.0f + x*x*(-1.0f/6.0f + x*x*1.0f/120.0f); - } - else { - return sin(x) / x; - } - } - - // Bessel function of the first kind from Jon Blow's article. - // http://mathworld.wolfram.com/BesselFunctionoftheFirstKind.html - // http://en.wikipedia.org/wiki/Bessel_function - inline static float bessel0(float x) - { - const float EPSILON_RATIO = 1e-6f; - float xh, sum, pow, ds; - int k; - - xh = 0.5f * x; - sum = 1.0f; - pow = 1.0f; - k = 0; - ds = 1.0; - while (ds > sum * EPSILON_RATIO) { - ++k; - pow = pow * (xh / k); - ds = pow * pow; - sum = sum + ds; - } - - return sum; - } - - /*// Alternative bessel function from Paul Heckbert. - static float _bessel0(float x) - { - const float EPSILON_RATIO = 1E-6; - float sum = 1.0f; - float y = x * x / 4.0f; - float t = y; - for(int i = 2; t > EPSILON_RATIO; i++) { - sum += t; - t *= y / float(i * i); - } - return sum; - }*/ - -} // namespace - - -Filter::Filter(float width) : m_width(width) -{ -} - -/*virtual*/ Filter::~Filter() -{ -} - -float Filter::sampleDelta(float x, float scale) const -{ - return evaluate((x + 0.5f)* scale); -} - -float Filter::sampleBox(float x, float scale, int samples) const -{ - float sum = 0; - float isamples = 1.0f / float(samples); - - for(int s = 0; s < samples; s++) - { - float p = (x + (float(s) + 0.5f) * isamples) * scale; - float value = evaluate(p); - sum += value; - } - - return sum * isamples; -} - -float Filter::sampleTriangle(float x, float scale, int samples) const -{ - float sum = 0; - float isamples = 1.0f / float(samples); - - for(int s = 0; s < samples; s++) - { - float offset = (2 * float(s) + 1.0f) * isamples; - float p = (x + offset - 0.5f) * scale; - float value = evaluate(p); - - float weight = offset; - if (weight > 1.0f) weight = 2.0f - weight; - - sum += value * weight; - } - - return 2 * sum * isamples; -} - - - - - -BoxFilter::BoxFilter() : Filter(0.5f) {} -BoxFilter::BoxFilter(float width) : Filter(width) {} - -float BoxFilter::evaluate(float x) const -{ - if (fabs(x) <= m_width) return 1.0f; - else return 0.0f; -} - - -TriangleFilter::TriangleFilter() : Filter(1.0f) {} -TriangleFilter::TriangleFilter(float width) : Filter(width) {} - -float TriangleFilter::evaluate(float x) const -{ - x = fabs(x); - if( x < m_width ) return m_width - x; - return 0.0f; -} - - -QuadraticFilter::QuadraticFilter() : Filter(1.5f) {} - -float QuadraticFilter::evaluate(float x) const -{ - x = fabs(x); - if( x < 0.5f ) return 0.75f - x * x; - if( x < 1.5f ) { - float t = x - 1.5f; - return 0.5f * t * t; - } - return 0.0f; -} - - -CubicFilter::CubicFilter() : Filter(1.0f) {} - -float CubicFilter::evaluate(float x) const -{ - // f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 - x = fabs(x); - if( x < 1.0f ) return((2.0f * x - 3.0f) * x * x + 1.0f); - return 0.0f; -} - - -BSplineFilter::BSplineFilter() : Filter(2.0f) {} - -float BSplineFilter::evaluate(float x) const -{ - x = fabs(x); - if( x < 1.0f ) return (4.0f + x * x * (-6.0f + x * 3.0f)) / 6.0f; - if( x < 2.0f ) { - float t = 2.0f - x; - return t * t * t / 6.0f; - } - return 0.0f; -} - - -MitchellFilter::MitchellFilter() : Filter(2.0f) { setParameters(1.0f/3.0f, 1.0f/3.0f); } - -float MitchellFilter::evaluate(float x) const -{ - x = fabs(x); - if( x < 1.0f ) return p0 + x * x * (p2 + x * p3); - if( x < 2.0f ) return q0 + x * (q1 + x * (q2 + x * q3)); - return 0.0f; -} - -void MitchellFilter::setParameters(float b, float c) -{ - p0 = (6.0f - 2.0f * b) / 6.0f; - p2 = (-18.0f + 12.0f * b + 6.0f * c) / 6.0f; - p3 = (12.0f - 9.0f * b - 6.0f * c) / 6.0f; - q0 = (8.0f * b + 24.0f * c) / 6.0f; - q1 = (-12.0f * b - 48.0f * c) / 6.0f; - q2 = (6.0f * b + 30.0f * c) / 6.0f; - q3 = (-b - 6.0f * c) / 6.0f; -} - - -LanczosFilter::LanczosFilter() : Filter(3.0f) {} - -float LanczosFilter::evaluate(float x) const -{ - x = fabs(x); - if( x < 3.0f ) return sincf(PI * x) * sincf(PI * x / 3.0f); - return 0.0f; -} - - -SincFilter::SincFilter(float w) : Filter(w) {} - -float SincFilter::evaluate(float x) const -{ - return sincf(PI * x); -} - - -KaiserFilter::KaiserFilter(float w) : Filter(w) { setParameters(4.0f, 1.0f); } - -float KaiserFilter::evaluate(float x) const -{ - const float sinc_value = sincf(PI * x * stretch); - const float t = x / m_width; - if ((1 - t * t) >= 0) return sinc_value * bessel0(alpha * sqrtf(1 - t * t)) / bessel0(alpha); - else return 0; -} - -void KaiserFilter::setParameters(float alpha, float stretch) -{ - this->alpha = alpha; - this->stretch = stretch; -} - - - -/// Ctor. -Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/) -{ - nvDebugCheck(iscale > 1); - nvDebugCheck(samples > 0); - - const float scale = 1.0f / iscale; - - m_width = f.width() * iscale; - m_windowSize = (int)ceilf(2 * m_width); - m_data = new float[m_windowSize]; - - const float offset = float(m_windowSize) / 2; - - float total = 0.0f; - for (int i = 0; i < m_windowSize; i++) - { - const float sample = f.sampleBox(i - offset, scale, samples); - m_data[i] = sample; - total += sample; - } - - const float inv = 1.0f / total; - for (int i = 0; i < m_windowSize; i++) - { - m_data[i] *= inv; - } -} - -/// Dtor. -Kernel1::~Kernel1() -{ - delete[] m_data; -} - -/// Print the kernel for debugging purposes. -void Kernel1::debugPrint() -{ - for (int i = 0; i < m_windowSize; i++) { - nvDebug("%d: %f\n", i, m_data[i]); - } -} - - - -/// Ctor. -Kernel2::Kernel2(uint ws) : m_windowSize(ws) -{ - m_data = new float[m_windowSize * m_windowSize]; -} - -/// Copy ctor. -Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize) -{ - m_data = new float[m_windowSize * m_windowSize]; - for (uint i = 0; i < m_windowSize * m_windowSize; i++) { - m_data[i] = k.m_data[i]; - } -} - - -/// Dtor. -Kernel2::~Kernel2() -{ - delete[] m_data; -} - -/// Normalize the filter. -void Kernel2::normalize() -{ - float total = 0.0f; - for(uint i = 0; i < m_windowSize*m_windowSize; i++) { - total += fabs(m_data[i]); - } - - float inv = 1.0f / total; - for(uint i = 0; i < m_windowSize*m_windowSize; i++) { - m_data[i] *= inv; - } -} - -/// Transpose the kernel. -void Kernel2::transpose() -{ - for(uint i = 0; i < m_windowSize; i++) { - for(uint j = i+1; j < m_windowSize; j++) { - swap(m_data[i*m_windowSize + j], m_data[j*m_windowSize + i]); - } - } -} - -/// Init laplacian filter, usually used for sharpening. -void Kernel2::initLaplacian() -{ - nvDebugCheck(m_windowSize == 3); -// m_data[0] = -1; m_data[1] = -1; m_data[2] = -1; -// m_data[3] = -1; m_data[4] = +8; m_data[5] = -1; -// m_data[6] = -1; m_data[7] = -1; m_data[8] = -1; - - m_data[0] = +0; m_data[1] = -1; m_data[2] = +0; - m_data[3] = -1; m_data[4] = +4; m_data[5] = -1; - m_data[6] = +0; m_data[7] = -1; m_data[8] = +0; - -// m_data[0] = +1; m_data[1] = -2; m_data[2] = +1; -// m_data[3] = -2; m_data[4] = +4; m_data[5] = -2; -// m_data[6] = +1; m_data[7] = -2; m_data[8] = +1; -} - - -/// Init simple edge detection filter. -void Kernel2::initEdgeDetection() -{ - nvCheck(m_windowSize == 3); - m_data[0] = 0; m_data[1] = 0; m_data[2] = 0; - m_data[3] =-1; m_data[4] = 0; m_data[5] = 1; - m_data[6] = 0; m_data[7] = 0; m_data[8] = 0; -} - -/// Init sobel filter. -void Kernel2::initSobel() -{ - if (m_windowSize == 3) - { - m_data[0] = -1; m_data[1] = 0; m_data[2] = 1; - m_data[3] = -2; m_data[4] = 0; m_data[5] = 2; - m_data[6] = -1; m_data[7] = 0; m_data[8] = 1; - } - else if (m_windowSize == 5) - { - float elements[] = { - -1, -2, 0, 2, 1, - -2, -3, 0, 3, 2, - -3, -4, 0, 4, 3, - -2, -3, 0, 3, 2, - -1, -2, 0, 2, 1 - }; - - for (int i = 0; i < 5*5; i++) { - m_data[i] = elements[i]; - } - } - else if (m_windowSize == 7) - { - float elements[] = { - -1, -2, -3, 0, 3, 2, 1, - -2, -3, -4, 0, 4, 3, 2, - -3, -4, -5, 0, 5, 4, 3, - -4, -5, -6, 0, 6, 5, 4, - -3, -4, -5, 0, 5, 4, 3, - -2, -3, -4, 0, 4, 3, 2, - -1, -2, -3, 0, 3, 2, 1 - }; - - for (int i = 0; i < 7*7; i++) { - m_data[i] = elements[i]; - } - } - else if (m_windowSize == 9) - { - float elements[] = { - -1, -2, -3, -4, 0, 4, 3, 2, 1, - -2, -3, -4, -5, 0, 5, 4, 3, 2, - -3, -4, -5, -6, 0, 6, 5, 4, 3, - -4, -5, -6, -7, 0, 7, 6, 5, 4, - -5, -6, -7, -8, 0, 8, 7, 6, 5, - -4, -5, -6, -7, 0, 7, 6, 5, 4, - -3, -4, -5, -6, 0, 6, 5, 4, 3, - -2, -3, -4, -5, 0, 5, 4, 3, 2, - -1, -2, -3, -4, 0, 4, 3, 2, 1 - }; - - for (int i = 0; i < 9*9; i++) { - m_data[i] = elements[i]; - } - } -} - -/// Init prewitt filter. -void Kernel2::initPrewitt() -{ - if (m_windowSize == 3) - { - m_data[0] = -1; m_data[1] = 0; m_data[2] = -1; - m_data[3] = -1; m_data[4] = 0; m_data[5] = -1; - m_data[6] = -1; m_data[7] = 0; m_data[8] = -1; - } - else if (m_windowSize == 5) - { - // @@ Is this correct? - float elements[] = { - -2, -1, 0, 1, 2, - -2, -1, 0, 1, 2, - -2, -1, 0, 1, 2, - -2, -1, 0, 1, 2, - -2, -1, 0, 1, 2 - }; - - for (int i = 0; i < 5*5; i++) { - m_data[i] = elements[i]; - } - } -} - -/// Init blended sobel filter. -void Kernel2::initBlendedSobel(const Vector4 & scale) -{ - nvCheck(m_windowSize == 9); - - { - const float elements[] = { - -1, -2, -3, -4, 0, 4, 3, 2, 1, - -2, -3, -4, -5, 0, 5, 4, 3, 2, - -3, -4, -5, -6, 0, 6, 5, 4, 3, - -4, -5, -6, -7, 0, 7, 6, 5, 4, - -5, -6, -7, -8, 0, 8, 7, 6, 5, - -4, -5, -6, -7, 0, 7, 6, 5, 4, - -3, -4, -5, -6, 0, 6, 5, 4, 3, - -2, -3, -4, -5, 0, 5, 4, 3, 2, - -1, -2, -3, -4, 0, 4, 3, 2, 1 - }; - - for (int i = 0; i < 9*9; i++) { - m_data[i] = elements[i] * scale.w(); - } - } - { - const float elements[] = { - -1, -2, -3, 0, 3, 2, 1, - -2, -3, -4, 0, 4, 3, 2, - -3, -4, -5, 0, 5, 4, 3, - -4, -5, -6, 0, 6, 5, 4, - -3, -4, -5, 0, 5, 4, 3, - -2, -3, -4, 0, 4, 3, 2, - -1, -2, -3, 0, 3, 2, 1, - }; - - for (int i = 0; i < 7; i++) { - for (int e = 0; e < 7; e++) { - m_data[(i + 1) * 9 + e + 1] += elements[i * 7 + e] * scale.z(); - } - } - } - { - const float elements[] = { - -1, -2, 0, 2, 1, - -2, -3, 0, 3, 2, - -3, -4, 0, 4, 3, - -2, -3, 0, 3, 2, - -1, -2, 0, 2, 1 - }; - - for (int i = 0; i < 5; i++) { - for (int e = 0; e < 5; e++) { - m_data[(i + 2) * 9 + e + 2] += elements[i * 5 + e] * scale.y(); - } - } - } - { - const float elements[] = { - -1, 0, 1, - -2, 0, 2, - -1, 0, 1, - }; - - for (int i = 0; i < 3; i++) { - for (int e = 0; e < 3; e++) { - m_data[(i + 3) * 9 + e + 3] += elements[i * 3 + e] * scale.x(); - } - } - } -} - - -PolyphaseKernel::PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples/*= 32*/) -{ - nvDebugCheck(samples > 0); - - float scale = float(dstLength) / float(srcLength); - const float iscale = 1.0f / scale; - - if (scale > 1) { - // Upsampling. - samples = 1; - scale = 1; - } - - m_length = dstLength; - m_width = f.width() * iscale; - m_windowSize = (int)ceilf(m_width * 2) + 1; - - m_data = new float[m_windowSize * m_length]; - memset(m_data, 0, sizeof(float) * m_windowSize * m_length); - - for (uint i = 0; i < m_length; i++) - { - const float center = (0.5f + i) * iscale; - - const int left = (int)floorf(center - m_width); - const int right = (int)ceilf(center + m_width); - nvDebugCheck(right - left <= m_windowSize); - - float total = 0.0f; - for (int j = 0; j < m_windowSize; j++) - { - const float sample = f.sampleBox(left + j - center, scale, samples); - - m_data[i * m_windowSize + j] = sample; - total += sample; - } - - // normalize weights. - for (int j = 0; j < m_windowSize; j++) - { - m_data[i * m_windowSize + j] /= total; - } - } -} - -PolyphaseKernel::~PolyphaseKernel() -{ - delete [] m_data; -} - - -/// Print the kernel for debugging purposes. -void PolyphaseKernel::debugPrint() const -{ - for (uint i = 0; i < m_length; i++) - { - nvDebug("%d: ", i); - for (int j = 0; j < m_windowSize; j++) - { - nvDebug(" %6.4f", m_data[i * m_windowSize + j]); - } - nvDebug("\n"); - } -} diff --git a/Externals/NVTT/src/nvimage/Filter.h b/Externals/NVTT/src/nvimage/Filter.h deleted file mode 100644 index 89b56065e88..00000000000 --- a/Externals/NVTT/src/nvimage/Filter.h +++ /dev/null @@ -1,219 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_FILTER_H -#define NV_IMAGE_FILTER_H - -#include -#include - -namespace nv -{ - class Vector4; - - /// Base filter class. - class NVIMAGE_CLASS Filter - { - public: - Filter(float width); - virtual ~Filter(); - - float width() const { return m_width; } - float sampleDelta(float x, float scale) const; - float sampleBox(float x, float scale, int samples) const; - float sampleTriangle(float x, float scale, int samples) const; - - virtual float evaluate(float x) const = 0; - - protected: - const float m_width; - }; - - // Box filter. - class NVIMAGE_CLASS BoxFilter : public Filter - { - public: - BoxFilter(); - BoxFilter(float width); - virtual float evaluate(float x) const; - }; - - // Triangle (bilinear/tent) filter. - class NVIMAGE_CLASS TriangleFilter : public Filter - { - public: - TriangleFilter(); - TriangleFilter(float width); - virtual float evaluate(float x) const; - }; - - // Quadratic (bell) filter. - class NVIMAGE_CLASS QuadraticFilter : public Filter - { - public: - QuadraticFilter(); - virtual float evaluate(float x) const; - }; - - // Cubic filter from Thatcher Ulrich. - class NVIMAGE_CLASS CubicFilter : public Filter - { - public: - CubicFilter(); - virtual float evaluate(float x) const; - }; - - // Cubic b-spline filter from Paul Heckbert. - class NVIMAGE_CLASS BSplineFilter : public Filter - { - public: - BSplineFilter(); - virtual float evaluate(float x) const; - }; - - /// Mitchell & Netravali's two-param cubic - /// @see "Reconstruction Filters in Computer Graphics", SIGGRAPH 88 - class NVIMAGE_CLASS MitchellFilter : public Filter - { - public: - MitchellFilter(); - virtual float evaluate(float x) const; - - void setParameters(float b, float c); - - private: - float p0, p2, p3; - float q0, q1, q2, q3; - }; - - // Lanczos3 filter. - class NVIMAGE_CLASS LanczosFilter : public Filter - { - public: - LanczosFilter(); - virtual float evaluate(float x) const; - }; - - // Sinc filter. - class NVIMAGE_CLASS SincFilter : public Filter - { - public: - SincFilter(float w); - virtual float evaluate(float x) const; - }; - - // Kaiser filter. - class NVIMAGE_CLASS KaiserFilter : public Filter - { - public: - KaiserFilter(float w); - virtual float evaluate(float x) const; - - void setParameters(float a, float stretch); - - private: - float alpha; - float stretch; - }; - - - - /// A 1D kernel. Used to precompute filter weights. - class NVIMAGE_CLASS Kernel1 - { - NV_FORBID_COPY(Kernel1); - public: - Kernel1(const Filter & f, int iscale, int samples = 32); - ~Kernel1(); - - float valueAt(uint x) const { - nvDebugCheck(x < (uint)m_windowSize); - return m_data[x]; - } - - int windowSize() const { - return m_windowSize; - } - - float width() const { - return m_width; - } - - void debugPrint(); - - private: - int m_windowSize; - float m_width; - float * m_data; - }; - - - /// A 2D kernel. - class NVIMAGE_CLASS Kernel2 - { - public: - Kernel2(uint width); - Kernel2(const Kernel2 & k); - ~Kernel2(); - - void normalize(); - void transpose(); - - float valueAt(uint x, uint y) const { - return m_data[y * m_windowSize + x]; - } - - uint windowSize() const { - return m_windowSize; - } - - void initLaplacian(); - void initEdgeDetection(); - void initSobel(); - void initPrewitt(); - - void initBlendedSobel(const Vector4 & scale); - - private: - const uint m_windowSize; - float * m_data; - }; - - - /// A 1D polyphase kernel - class NVIMAGE_CLASS PolyphaseKernel - { - NV_FORBID_COPY(PolyphaseKernel); - public: - PolyphaseKernel(const Filter & f, uint srcLength, uint dstLength, int samples = 32); - ~PolyphaseKernel(); - - int windowSize() const { - return m_windowSize; - } - - uint length() const { - return m_length; - } - - float width() const { - return m_width; - } - - float valueAt(uint column, uint x) const { - nvDebugCheck(column < m_length); - nvDebugCheck(x < (uint)m_windowSize); - return m_data[column * m_windowSize + x]; - } - - void debugPrint() const; - - private: - int m_windowSize; - uint m_length; - float m_width; - float * m_data; - }; - -} // nv namespace - -#endif // NV_IMAGE_FILTER_H diff --git a/Externals/NVTT/src/nvimage/FloatImage.cpp b/Externals/NVTT/src/nvimage/FloatImage.cpp deleted file mode 100644 index 90818cacdab..00000000000 --- a/Externals/NVTT/src/nvimage/FloatImage.cpp +++ /dev/null @@ -1,909 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include "FloatImage.h" -#include "Filter.h" -#include "Image.h" - -#include -#include - -#include -#include - -#include - - -using namespace nv; - -namespace -{ - static int iround(float f) - { - return int(f); - } - - static int ifloor(float f) - { - return int(floor(f)); - } - - static float frac(float f) - { - return f - floor(f); - } - - static int mirror(int x, int w) - { - x = abs(x); - while (x >= w) { - x = 2 * w - x - 2; - } - return x; - } -} - - -/// Ctor. -FloatImage::FloatImage() : m_width(0), m_height(0), - m_componentNum(0), m_count(0), m_mem(NULL) -{ -} - -/// Ctor. Init from image. -FloatImage::FloatImage(const Image * img) : m_width(0), m_height(0), - m_componentNum(0), m_count(0), m_mem(NULL) -{ - initFrom(img); -} - -/// Dtor. -FloatImage::~FloatImage() -{ - free(); -} - - -/// Init the floating point image from a regular image. -void FloatImage::initFrom(const Image * img) -{ - nvCheck(img != NULL); - - allocate(4, img->width(), img->height()); - - float * red_channel = channel(0); - float * green_channel = channel(1); - float * blue_channel = channel(2); - float * alpha_channel = channel(3); - - const uint count = m_width * m_height; - for(uint i = 0; i < count; i++) { - Color32 pixel = img->pixel(i); - red_channel[i] = float(pixel.r) / 255.0f; - green_channel[i] = float(pixel.g) / 255.0f; - blue_channel[i] = float(pixel.b) / 255.0f; - alpha_channel[i] = float(pixel.a) / 255.0f; - } -} - -/// Convert the floating point image to a regular image. -Image * FloatImage::createImage(uint base_component/*= 0*/, uint num/*= 4*/) const -{ - nvCheck(num <= 4); - nvCheck(base_component + num <= m_componentNum); - - AutoPtr img(new Image()); - img->allocate(m_width, m_height); - - const uint size = m_width * m_height; - for(uint i = 0; i < size; i++) { - - uint c; - uint8 rgba[4]= {0, 0, 0, 0xff}; - - for(c = 0; c < num; c++) { - float f = m_mem[size * (base_component + c) + i]; - rgba[c] = nv::clamp(int(255.0f * f), 0, 255); - } - - img->pixel(i) = Color32(rgba[0], rgba[1], rgba[2], rgba[3]); - } - - return img.release(); -} - - -/// Convert the floating point image to a regular image. Correct gamma of rgb, but not alpha. -Image * FloatImage::createImageGammaCorrect(float gamma/*= 2.2f*/) const -{ - nvCheck(m_componentNum == 4); - - AutoPtr img(new Image()); - img->allocate(m_width, m_height); - - const float * rChannel = this->channel(0); - const float * gChannel = this->channel(1); - const float * bChannel = this->channel(2); - const float * aChannel = this->channel(3); - - const uint size = m_width * m_height; - for(uint i = 0; i < size; i++) - { - const uint8 r = nv::clamp(int(255.0f * pow(rChannel[i], 1.0f/gamma)), 0, 255); - const uint8 g = nv::clamp(int(255.0f * pow(gChannel[i], 1.0f/gamma)), 0, 255); - const uint8 b = nv::clamp(int(255.0f * pow(bChannel[i], 1.0f/gamma)), 0, 255); - const uint8 a = nv::clamp(int(255.0f * aChannel[i]), 0, 255); - - img->pixel(i) = Color32(r, g, b, a); - } - - return img.release(); -} - -/// Allocate a 2d float image of the given format and the given extents. -void FloatImage::allocate(uint c, uint w, uint h) -{ - free(); - - m_width = w; - m_height = h; - m_componentNum = c; - m_count = w * h * c; - m_mem = reinterpret_cast(nv::mem::malloc(m_count * sizeof(float))); -} - -/// Free the image, but don't clear the members. -void FloatImage::free() -{ - nv::mem::free( reinterpret_cast(m_mem) ); - m_mem = NULL; -} - -void FloatImage::clear(float f/*=0.0f*/) -{ - for(uint i = 0; i < m_count; i++) { - m_mem[i] = f; - } -} - -void FloatImage::normalize(uint base_component) -{ - nvCheck(base_component + 3 <= m_componentNum); - - float * xChannel = this->channel(base_component + 0); - float * yChannel = this->channel(base_component + 1); - float * zChannel = this->channel(base_component + 2); - - const uint size = m_width * m_height; - for(uint i = 0; i < size; i++) { - - Vector3 normal(xChannel[i], yChannel[i], zChannel[i]); - normal = normalizeSafe(normal, Vector3(zero), 0.0f); - - xChannel[i] = normal.x(); - yChannel[i] = normal.y(); - zChannel[i] = normal.z(); - } -} - -void FloatImage::packNormals(uint base_component) -{ - scaleBias(base_component, 3, 0.5f, 1.0f); -} - -void FloatImage::expandNormals(uint base_component) -{ - scaleBias(base_component, 3, 2, -0.5); -} - -void FloatImage::scaleBias(uint base_component, uint num, float scale, float bias) -{ - const uint size = m_width * m_height; - - for(uint c = 0; c < num; c++) { - float * ptr = this->channel(base_component + c); - - for(uint i = 0; i < size; i++) { - ptr[i] = scale * (ptr[i] + bias); - } - } -} - -/// Clamp the elements of the image. -void FloatImage::clamp(float low, float high) -{ - for(uint i = 0; i < m_count; i++) { - m_mem[i] = nv::clamp(m_mem[i], low, high); - } -} - -/// From gamma to linear space. -void FloatImage::toLinear(uint base_component, uint num, float gamma /*= 2.2f*/) -{ - exponentiate(base_component, num, gamma); -} - -/// From linear to gamma space. -void FloatImage::toGamma(uint base_component, uint num, float gamma /*= 2.2f*/) -{ - exponentiate(base_component, num, 1.0f/gamma); -} - -/// Exponentiate the elements of the image. -void FloatImage::exponentiate(uint base_component, uint num, float power) -{ - const uint size = m_width * m_height; - - for(uint c = 0; c < num; c++) { - float * ptr = this->channel(base_component + c); - - for(uint i = 0; i < size; i++) { - ptr[i] = pow(ptr[i], power); - } - } -} - -float FloatImage::sampleNearest(const float x, const float y, const int c, const WrapMode wm) const -{ - if( wm == WrapMode_Clamp ) return sampleNearestClamp(x, y, c); - else if( wm == WrapMode_Repeat ) return sampleNearestRepeat(x, y, c); - else /*if( wm == WrapMode_Mirror )*/ return sampleNearestMirror(x, y, c); -} - -float FloatImage::sampleLinear(const float x, const float y, const int c, const WrapMode wm) const -{ - if( wm == WrapMode_Clamp ) return sampleLinearClamp(x, y, c); - else if( wm == WrapMode_Repeat ) return sampleLinearRepeat(x, y, c); - else /*if( wm == WrapMode_Mirror )*/ return sampleLinearMirror(x, y, c); -} - -float FloatImage::sampleNearestClamp(const float x, const float y, const int c) const -{ - int ix = ::clamp(iround(x * m_width), 0, m_width-1); - int iy = ::clamp(iround(y * m_height), 0, m_height-1); - return pixel(ix, iy, c); -} - -float FloatImage::sampleNearestRepeat(const float x, const float y, const int c) const -{ - int ix = iround(frac(x) * m_width); - int iy = iround(frac(y) * m_height); - return pixel(ix, iy, c); -} - -float FloatImage::sampleNearestMirror(const float x, const float y, const int c) const -{ - int ix = mirror(iround(x * m_width), m_width); - int iy = mirror(iround(y * m_height), m_height); - return pixel(ix, iy, c); -} - -float FloatImage::sampleLinearClamp(float x, float y, const int c) const -{ - const int w = m_width; - const int h = m_height; - - x *= w; - y *= h; - - const float fracX = frac(x); - const float fracY = frac(y); - - const int ix0 = ::clamp(ifloor(x), 0, w-1); - const int iy0 = ::clamp(ifloor(y), 0, h-1); - const int ix1 = ::clamp(ifloor(x)+1, 0, w-1); - const int iy1 = ::clamp(ifloor(y)+1, 0, h-1); - - float f1 = pixel(ix0, iy0, c); - float f2 = pixel(ix1, iy0, c); - float f3 = pixel(ix0, iy1, c); - float f4 = pixel(ix1, iy1, c); - - float i1 = lerp(f1, f2, fracX); - float i2 = lerp(f3, f4, fracX); - - return lerp(i1, i2, fracY); -} - -float FloatImage::sampleLinearRepeat(float x, float y, int c) const -{ - const int w = m_width; - const int h = m_height; - - const float fracX = frac(x * w); - const float fracY = frac(y * h); - - int ix0 = ifloor(frac(x) * w); - int iy0 = ifloor(frac(y) * h); - int ix1 = ifloor(frac(x + 1.0f/w) * w); - int iy1 = ifloor(frac(y + 1.0f/h) * h); - - float f1 = pixel(ix0, iy0, c); - float f2 = pixel(ix1, iy0, c); - float f3 = pixel(ix0, iy1, c); - float f4 = pixel(ix1, iy1, c); - - float i1 = lerp(f1, f2, fracX); - float i2 = lerp(f3, f4, fracX); - - return lerp(i1, i2, fracY); -} - -float FloatImage::sampleLinearMirror(float x, float y, int c) const -{ - const int w = m_width; - const int h = m_height; - - x *= w; - y *= h; - - const float fracX = frac(x); - const float fracY = frac(y); - - int ix0 = mirror(iround(x), w); - int iy0 = mirror(iround(y), h); - int ix1 = mirror(iround(x) + 1, w); - int iy1 = mirror(iround(y) + 1, h); - - float f1 = pixel(ix0, iy0, c); - float f2 = pixel(ix1, iy0, c); - float f3 = pixel(ix0, iy1, c); - float f4 = pixel(ix1, iy1, c); - - float i1 = lerp(f1, f2, fracX); - float i2 = lerp(f3, f4, fracX); - - return lerp(i1, i2, fracY); -} - - -/// Fast downsampling using box filter. -/// -/// The extents of the image are divided by two and rounded down. -/// -/// When the size of the image is odd, this uses a polyphase box filter as explained in: -/// http://developer.nvidia.com/object/np2_mipmapping.html -/// -FloatImage * FloatImage::fastDownSample() const -{ - nvDebugCheck(m_width != 1 || m_height != 1); - - AutoPtr dst_image( new FloatImage() ); - - const uint w = max(1, m_width / 2); - const uint h = max(1, m_height / 2); - dst_image->allocate(m_componentNum, w, h); - - // 1D box filter. - if (m_width == 1 || m_height == 1) - { - const uint n = w * h; - - if ((m_width * m_height) & 1) - { - const float scale = 1.0f / (2 * n + 1); - - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint x = 0; x < n; x++) - { - const float w0 = float(n - x); - const float w1 = float(n - 0); - const float w2 = float(1 + x); - - *dst++ = scale * (w0 * src[0] + w1 * src[1] + w2 * src[2]); - src += 2; - } - } - } - else - { - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint x = 0; x < n; x++) - { - *dst = 0.5f * (src[0] + src[1]); - dst++; - src += 2; - } - } - } - } - - // Regular box filter. - else if ((m_width & 1) == 0 && (m_height & 1) == 0) - { - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint y = 0; y < h; y++) - { - for(uint x = 0; x < w; x++) - { - *dst = 0.25f * (src[0] + src[1] + src[m_width] + src[m_width + 1]); - dst++; - src += 2; - } - - src += m_width; - } - } - } - - // Polyphase filters. - else if (m_width & 1 && m_height & 1) - { - nvDebugCheck(m_width == 2 * w + 1); - nvDebugCheck(m_height == 2 * h + 1); - - const float scale = 1.0f / (m_width * m_height); - - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint y = 0; y < h; y++) - { - const float v0 = float(h - y); - const float v1 = float(h - 0); - const float v2 = float(1 + y); - - for (uint x = 0; x < w; x++) - { - const float w0 = float(w - x); - const float w1 = float(w - 0); - const float w2 = float(1 + x); - - float f = 0.0f; - f += v0 * (w0 * src[0 * m_width + 2 * x] + w1 * src[0 * m_width + 2 * x + 1] + w2 * src[0 * m_width + 2 * x + 2]); - f += v1 * (w0 * src[1 * m_width + 2 * x] + w1 * src[1 * m_width + 2 * x + 1] + w2 * src[0 * m_width + 2 * x + 2]); - f += v2 * (w0 * src[2 * m_width + 2 * x] + w1 * src[2 * m_width + 2 * x + 1] + w2 * src[0 * m_width + 2 * x + 2]); - - *dst = f * scale; - dst++; - } - - src += 2 * m_width; - } - } - } - else if (m_width & 1) - { - nvDebugCheck(m_width == 2 * w + 1); - const float scale = 1.0f / (2 * m_width); - - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint y = 0; y < h; y++) - { - for (uint x = 0; x < w; x++) - { - const float w0 = float(w - x); - const float w1 = float(w - 0); - const float w2 = float(1 + x); - - float f = 0.0f; - f += w0 * (src[2 * x + 0] + src[m_width + 2 * x + 0]); - f += w1 * (src[2 * x + 1] + src[m_width + 2 * x + 1]); - f += w2 * (src[2 * x + 2] + src[m_width + 2 * x + 2]); - - *dst = f * scale; - dst++; - } - - src += 2 * m_width; - } - } - } - else if (m_height & 1) - { - nvDebugCheck(m_height == 2 * h + 1); - - const float scale = 1.0f / (2 * m_height); - - for(uint c = 0; c < m_componentNum; c++) - { - const float * src = this->channel(c); - float * dst = dst_image->channel(c); - - for(uint y = 0; y < h; y++) - { - const float v0 = float(h - y); - const float v1 = float(h - 0); - const float v2 = float(1 + y); - - for (uint x = 0; x < w; x++) - { - float f = 0.0f; - f += v0 * (src[0 * m_width + 2 * x] + src[0 * m_width + 2 * x + 1]); - f += v1 * (src[1 * m_width + 2 * x] + src[1 * m_width + 2 * x + 1]); - f += v2 * (src[2 * m_width + 2 * x] + src[2 * m_width + 2 * x + 1]); - - *dst = f * scale; - dst++; - } - - src += 2 * m_width; - } - } - } - - return dst_image.release(); -} - -/// Downsample applying a 1D kernel separately in each dimension. -FloatImage * FloatImage::downSample(const Filter & filter, WrapMode wm) const -{ - const uint w = max(1, m_width / 2); - const uint h = max(1, m_height / 2); - - return resize(filter, w, h, wm); -} - -/// Downsample applying a 1D kernel separately in each dimension. -FloatImage * FloatImage::downSample(const Filter & filter, WrapMode wm, uint alpha) const -{ - const uint w = max(1, m_width / 2); - const uint h = max(1, m_height / 2); - - return resize(filter, w, h, wm, alpha); -} - - -/// Downsample applying a 1D kernel separately in each dimension. -FloatImage * FloatImage::resize(const Filter & filter, uint w, uint h, WrapMode wm) const -{ - // @@ Use monophase filters when frac(m_width / w) == 0 - - AutoPtr tmp_image( new FloatImage() ); - AutoPtr dst_image( new FloatImage() ); - - PolyphaseKernel xkernel(filter, m_width, w, 32); - PolyphaseKernel ykernel(filter, m_height, h, 32); - - // @@ Select fastest filtering order: - //if (w * m_height <= h * m_width) - { - tmp_image->allocate(m_componentNum, w, m_height); - dst_image->allocate(m_componentNum, w, h); - - Array tmp_column(h); - tmp_column.resize(h); - - for (uint c = 0; c < m_componentNum; c++) - { - float * tmp_channel = tmp_image->channel(c); - - for (uint y = 0; y < m_height; y++) { - this->applyKernelHorizontal(xkernel, y, c, wm, tmp_channel + y * w); - } - - float * dst_channel = dst_image->channel(c); - - for (uint x = 0; x < w; x++) { - tmp_image->applyKernelVertical(ykernel, x, c, wm, tmp_column.unsecureBuffer()); - - for (uint y = 0; y < h; y++) { - dst_channel[y * w + x] = tmp_column[y]; - } - } - } - } - /*else - { - tmp_image->allocate(m_componentNum, m_width, h); - dst_image->allocate(m_componentNum, w, h); - - Array tmp_column(h); - tmp_column.resize(h); - - for (uint c = 0; c < m_componentNum; c++) - { - float * tmp_channel = tmp_image->channel(c); - - for (uint x = 0; x < w; x++) { - tmp_image->applyKernelVertical(ykernel, x, c, wm, tmp_column.unsecureBuffer()); - - for (uint y = 0; y < h; y++) { - tmp_channel[y * w + x] = tmp_column[y]; - } - } - - float * dst_channel = dst_image->channel(c); - - for (uint y = 0; y < m_height; y++) { - this->applyKernelHorizontal(xkernel, y, c, wm, dst_channel + y * w); - } - } - }*/ - - return dst_image.release(); -} - -/// Downsample applying a 1D kernel separately in each dimension. -FloatImage * FloatImage::resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const -{ - nvCheck(alpha < m_componentNum); - - AutoPtr tmp_image( new FloatImage() ); - AutoPtr dst_image( new FloatImage() ); - - PolyphaseKernel xkernel(filter, m_width, w, 32); - PolyphaseKernel ykernel(filter, m_height, h, 32); - - { - tmp_image->allocate(m_componentNum, w, m_height); - dst_image->allocate(m_componentNum, w, h); - - Array tmp_column(h); - tmp_column.resize(h); - - for (uint c = 0; c < m_componentNum; c++) - { - float * tmp_channel = tmp_image->channel(c); - - for (uint y = 0; y < m_height; y++) { - this->applyKernelHorizontal(xkernel, y, c, alpha, wm, tmp_channel + y * w); - } - } - - // Process all channels before applying vertical kernel to make sure alpha has been computed. - - for (uint c = 0; c < m_componentNum; c++) - { - float * dst_channel = dst_image->channel(c); - - for (uint x = 0; x < w; x++) { - tmp_image->applyKernelVertical(ykernel, x, c, alpha, wm, tmp_column.unsecureBuffer()); - - for (uint y = 0; y < h; y++) { - dst_channel[y * w + x] = tmp_column[y]; - } - } - } - } - - return dst_image.release(); -} - - - -/// Apply 2D kernel at the given coordinates and return result. -float FloatImage::applyKernel(const Kernel2 * k, int x, int y, uint c, WrapMode wm) const -{ - nvDebugCheck(k != NULL); - - const uint kernelWindow = k->windowSize(); - const int kernelOffset = int(kernelWindow / 2) - 1; - - const float * channel = this->channel(c); - - float sum = 0.0f; - for (uint i = 0; i < kernelWindow; i++) - { - const int src_y = int(y + i) - kernelOffset; - - for (uint e = 0; e < kernelWindow; e++) - { - const int src_x = int(x + e) - kernelOffset; - - int idx = this->index(src_x, src_y, wm); - - sum += k->valueAt(e, i) * channel[idx]; - } - } - - return sum; -} - - -/// Apply 1D vertical kernel at the given coordinates and return result. -float FloatImage::applyKernelVertical(const Kernel1 * k, int x, int y, uint c, WrapMode wm) const -{ - nvDebugCheck(k != NULL); - - const uint kernelWindow = k->windowSize(); - const int kernelOffset = int(kernelWindow / 2) - 1; - - const float * channel = this->channel(c); - - float sum = 0.0f; - for (uint i = 0; i < kernelWindow; i++) - { - const int src_y = int(y + i) - kernelOffset; - const int idx = this->index(x, src_y, wm); - - sum += k->valueAt(i) * channel[idx]; - } - - return sum; -} - -/// Apply 1D horizontal kernel at the given coordinates and return result. -float FloatImage::applyKernelHorizontal(const Kernel1 * k, int x, int y, uint c, WrapMode wm) const -{ - nvDebugCheck(k != NULL); - - const uint kernelWindow = k->windowSize(); - const int kernelOffset = int(kernelWindow / 2) - 1; - - const float * channel = this->channel(c); - - float sum = 0.0f; - for (uint e = 0; e < kernelWindow; e++) - { - const int src_x = int(x + e) - kernelOffset; - const int idx = this->index(src_x, y, wm); - - sum += k->valueAt(e) * channel[idx]; - } - - return sum; -} - - -/// Apply 1D vertical kernel at the given coordinates and return result. -void FloatImage::applyKernelVertical(const PolyphaseKernel & k, int x, uint c, WrapMode wm, float * __restrict output) const -{ - const uint length = k.length(); - const float scale = float(length) / float(m_height); - const float iscale = 1.0f / scale; - - const float width = k.width(); - const int windowSize = k.windowSize(); - - const float * channel = this->channel(c); - - for (uint i = 0; i < length; i++) - { - const float center = (0.5f + i) * iscale; - - const int left = (int)floorf(center - width); - const int right = (int)ceilf(center + width); - nvCheck(right - left <= windowSize); - - float sum = 0; - for (int j = 0; j < windowSize; ++j) - { - const int idx = this->index(x, j+left, wm); - - sum += k.valueAt(i, j) * channel[idx]; - } - - output[i] = sum; - } -} - -/// Apply 1D horizontal kernel at the given coordinates and return result. -void FloatImage::applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, WrapMode wm, float * __restrict output) const -{ - const uint length = k.length(); - const float scale = float(length) / float(m_width); - const float iscale = 1.0f / scale; - - const float width = k.width(); - const int windowSize = k.windowSize(); - - const float * channel = this->channel(c); - - for (uint i = 0; i < length; i++) - { - const float center = (0.5f + i) * iscale; - - const int left = (int)floorf(center - width); - const int right = (int)ceilf(center + width); - nvDebugCheck(right - left <= windowSize); - - float sum = 0; - for (int j = 0; j < windowSize; ++j) - { - const int idx = this->index(left + j, y, wm); - - sum += k.valueAt(i, j) * channel[idx]; - } - - output[i] = sum; - } -} - - -/// Apply 1D vertical kernel at the given coordinates and return result. -void FloatImage::applyKernelVertical(const PolyphaseKernel & k, int x, uint c, uint a, WrapMode wm, float * __restrict output) const -{ - const uint length = k.length(); - const float scale = float(length) / float(m_height); - const float iscale = 1.0f / scale; - - const float width = k.width(); - const int windowSize = k.windowSize(); - - const float * channel = this->channel(c); - const float * alpha = this->channel(a); - - for (uint i = 0; i < length; i++) - { - const float center = (0.5f + i) * iscale; - - const int left = (int)floorf(center - width); - const int right = (int)ceilf(center + width); - nvCheck(right - left <= windowSize); - - float norm = 0; - float sum = 0; - for (int j = 0; j < windowSize; ++j) - { - const int idx = this->index(x, j+left, wm); - - float w = k.valueAt(i, j) * (alpha[idx] + (1.0f / 256.0f)); - norm += w; - sum += w * channel[idx]; - } - - output[i] = sum / norm; - } -} - -/// Apply 1D horizontal kernel at the given coordinates and return result. -void FloatImage::applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, uint a, WrapMode wm, float * __restrict output) const -{ - const uint length = k.length(); - const float scale = float(length) / float(m_width); - const float iscale = 1.0f / scale; - - const float width = k.width(); - const int windowSize = k.windowSize(); - - const float * channel = this->channel(c); - const float * alpha = this->channel(a); - - for (uint i = 0; i < length; i++) - { - const float center = (0.5f + i) * iscale; - - const int left = (int)floorf(center - width); - const int right = (int)ceilf(center + width); - nvDebugCheck(right - left <= windowSize); - - float norm = 0.0f; - float sum = 0; - for (int j = 0; j < windowSize; ++j) - { - const int idx = this->index(left + j, y, wm); - - float w = k.valueAt(i, j) * (alpha[idx] + (1.0f / 256.0f)); - norm += w; - sum += w * channel[idx]; - } - - output[i] = sum / norm; - } -} - -FloatImage* FloatImage::clone() const -{ - FloatImage* copy = new FloatImage(); - copy->m_width = m_width; - copy->m_height = m_height; - copy->m_componentNum = m_componentNum; - copy->m_count = m_count; - - if(m_mem) - { - copy->allocate(m_componentNum, m_width, m_height); - memcpy(copy->m_mem, m_mem, m_count * sizeof(float)); - } - - return copy; -} - diff --git a/Externals/NVTT/src/nvimage/FloatImage.h b/Externals/NVTT/src/nvimage/FloatImage.h deleted file mode 100644 index 96d1630f317..00000000000 --- a/Externals/NVTT/src/nvimage/FloatImage.h +++ /dev/null @@ -1,270 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_FLOATIMAGE_H -#define NV_IMAGE_FLOATIMAGE_H - -#include - -#include - -#include -#include // clamp - -#include // abs - - -namespace nv -{ -class Vector4; -class Matrix; -class Image; -class Filter; -class Kernel1; -class Kernel2; -class PolyphaseKernel; - -/// Multicomponent floating point image class. -class FloatImage -{ -public: - - enum WrapMode { - WrapMode_Clamp, - WrapMode_Repeat, - WrapMode_Mirror - }; - - NVIMAGE_API FloatImage(); - NVIMAGE_API FloatImage(const Image * img); - NVIMAGE_API virtual ~FloatImage(); - - /** @name Conversion. */ - //@{ - NVIMAGE_API void initFrom(const Image * img); - NVIMAGE_API Image * createImage(uint base_component = 0, uint num = 4) const; - NVIMAGE_API Image * createImageGammaCorrect(float gamma = 2.2f) const; - //@} - - /** @name Allocation. */ - //@{ - NVIMAGE_API void allocate(uint c, uint w, uint h); - NVIMAGE_API void free(); // Does not clear members. - //@} - - /** @name Manipulation. */ - //@{ - NVIMAGE_API void clear(float f=0.0f); - - NVIMAGE_API void normalize(uint base_component); - - NVIMAGE_API void packNormals(uint base_component); - NVIMAGE_API void expandNormals(uint base_component); - NVIMAGE_API void scaleBias(uint base_component, uint num, float scale, float add); - - //NVIMAGE_API void clamp(uint base_component, uint num); - NVIMAGE_API void clamp(float low, float high); - - NVIMAGE_API void toLinear(uint base_component, uint num, float gamma = 2.2f); - NVIMAGE_API void toGamma(uint base_component, uint num, float gamma = 2.2f); - NVIMAGE_API void exponentiate(uint base_component, uint num, float power); - - - NVIMAGE_API FloatImage * fastDownSample() const; - NVIMAGE_API FloatImage * downSample(const Filter & filter, WrapMode wm) const; - NVIMAGE_API FloatImage * downSample(const Filter & filter, WrapMode wm, uint alpha) const; - NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm) const; - - NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const; - //@} - - NVIMAGE_API float applyKernel(const Kernel2 * k, int x, int y, uint c, WrapMode wm) const; - NVIMAGE_API float applyKernelVertical(const Kernel1 * k, int x, int y, uint c, WrapMode wm) const; - NVIMAGE_API float applyKernelHorizontal(const Kernel1 * k, int x, int y, uint c, WrapMode wm) const; - NVIMAGE_API void applyKernelVertical(const PolyphaseKernel & k, int x, uint c, WrapMode wm, float * output) const; - NVIMAGE_API void applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, WrapMode wm, float * output) const; - NVIMAGE_API void applyKernelVertical(const PolyphaseKernel & k, int x, uint c, uint a, WrapMode wm, float * output) const; - NVIMAGE_API void applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, uint a, WrapMode wm, float * output) const; - - - uint width() const { return m_width; } - uint height() const { return m_height; } - uint componentNum() const { return m_componentNum; } - uint count() const { return m_count; } - - - /** @name Pixel access. */ - //@{ - const float * channel(uint c) const; - float * channel(uint c); - - const float * scanline(uint y, uint c) const; - float * scanline(uint y, uint c); - - void setPixel(float f, uint x, uint y, uint c); - void addPixel(float f, uint x, uint y, uint c); - float pixel(uint x, uint y, uint c) const; - - void setPixel(float f, uint idx); - float pixel(uint idx) const; - - float sampleNearest(float x, float y, int c, WrapMode wm) const; - float sampleLinear(float x, float y, int c, WrapMode wm) const; - - float sampleNearestClamp(float x, float y, int c) const; - float sampleNearestRepeat(float x, float y, int c) const; - float sampleNearestMirror(float x, float y, int c) const; - - float sampleLinearClamp(float x, float y, int c) const; - float sampleLinearRepeat(float x, float y, int c) const; - float sampleLinearMirror(float x, float y, int c) const; - //@} - - - FloatImage* clone() const; - -public: - - uint index(uint x, uint y) const; - uint indexClamp(int x, int y) const; - uint indexRepeat(int x, int y) const; - uint indexMirror(int x, int y) const; - uint index(int x, int y, WrapMode wm) const; - -public: - - uint16 m_width; ///< Width of the texture. - uint16 m_height; ///< Height of the texture. - uint32 m_componentNum; ///< Number of components. - uint32 m_count; ///< Image pixel count. - float * m_mem; - -}; - - -/// Get const channel pointer. -inline const float * FloatImage::channel(uint c) const -{ - nvDebugCheck(m_mem != NULL); - nvDebugCheck(c < m_componentNum); - return m_mem + c * m_width * m_height; -} - -/// Get channel pointer. -inline float * FloatImage::channel(uint c) { - nvDebugCheck(m_mem != NULL); - nvDebugCheck(c < m_componentNum); - return m_mem + c * m_width * m_height; -} - -/// Get const scanline pointer. -inline const float * FloatImage::scanline(uint y, uint c) const -{ - nvDebugCheck(y < m_height); - return channel(c) + y * m_width; -} - -/// Get scanline pointer. -inline float * FloatImage::scanline(uint y, uint c) -{ - nvDebugCheck(y < m_height); - return channel(c) + y * m_width; -} - -/// Set pixel component. -inline void FloatImage::setPixel(float f, uint x, uint y, uint c) -{ - nvDebugCheck(m_mem != NULL); - nvDebugCheck(x < m_width); - nvDebugCheck(y < m_height); - nvDebugCheck(c < m_componentNum); - m_mem[(c * m_height + y) * m_width + x] = f; -} - -/// Add to pixel component. -inline void FloatImage::addPixel(float f, uint x, uint y, uint c) -{ - nvDebugCheck(m_mem != NULL); - nvDebugCheck(x < m_width); - nvDebugCheck(y < m_height); - nvDebugCheck(c < m_componentNum); - m_mem[(c * m_height + y) * m_width + x] += f; -} - -/// Get pixel component. -inline float FloatImage::pixel(uint x, uint y, uint c) const -{ - nvDebugCheck(m_mem != NULL); - nvDebugCheck(x < m_width); - nvDebugCheck(y < m_height); - nvDebugCheck(c < m_componentNum); - return m_mem[(c * m_height + y) * m_width + x]; -} - -/// Set pixel component. -inline void FloatImage::setPixel(float f, uint idx) -{ - nvDebugCheck(idx < m_count); - m_mem[idx] = f; -} - -/// Get pixel component. -inline float FloatImage::pixel(uint idx) const -{ - nvDebugCheck(idx < m_count); - return m_mem[idx]; -} - -inline uint FloatImage::index(uint x, uint y) const -{ - nvDebugCheck(x < m_width); - nvDebugCheck(y < m_height); - return y * m_width + x; -} - -inline uint FloatImage::indexClamp(int x, int y) const -{ - return nv::clamp(y, int(0), int(m_height-1)) * m_width + nv::clamp(x, int(0), int(m_width-1)); -} - -inline int repeat_remainder(int a, int b) -{ - if (a >= 0) return a % b; - else return (a + 1) % b + b - 1; -} - -inline uint FloatImage::indexRepeat(int x, int y) const -{ - return repeat_remainder(y, m_height) * m_width + repeat_remainder(x, m_width); -} - -inline uint FloatImage::indexMirror(int x, int y) const -{ - if (m_width == 1) x = 0; - - x = abs(x); - while (x >= m_width) { - x = abs(m_width + m_width - x - 2); - } - - if (m_height == 1) y = 0; - - y = abs(y); - while (y >= m_height) { - y = abs(m_height + m_height - y - 2); - } - - return index(x, y); -} - -inline uint FloatImage::index(int x, int y, WrapMode wm) const -{ - if (wm == WrapMode_Clamp) return indexClamp(x, y); - if (wm == WrapMode_Repeat) return indexRepeat(x, y); - /*if (wm == WrapMode_Mirror)*/ return indexMirror(x, y); -} - -} // nv namespace - - - -#endif // NV_IMAGE_FLOATIMAGE_H diff --git a/Externals/NVTT/src/nvimage/HoleFilling.cpp b/Externals/NVTT/src/nvimage/HoleFilling.cpp deleted file mode 100644 index 863dc163b04..00000000000 --- a/Externals/NVTT/src/nvimage/HoleFilling.cpp +++ /dev/null @@ -1,753 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include - -#include - -#include -#include - -using namespace nv; - - -// This is a variation of Sapiro's inpainting method. -void nv::fillExtrapolate(int passCount, FloatImage * img, BitMap * bmap) -{ - nvCheck(img != NULL); - nvCheck(bmap != NULL); - - const int w = img->width(); - const int h = img->height(); - const int count = img->componentNum(); - - nvCheck(bmap->width() == uint(w)); - nvCheck(bmap->height() == uint(h)); - - AutoPtr newbmap(new BitMap(w, h)); - - for(int p = 0; p < passCount; p++) - { - for(int c = 0; c < count; c++) - { - float * channel = img->channel(c); - - for(int y = 0; y < h; y++) { - for(int x = 0; x < w; x++) { - - if (bmap->bitAt(x, y)) { - // Not a hole. - newbmap->setBitAt(x, y); - continue; - } - - const bool west = bmap->bitAt(img->indexClamp(x-1, y)); - const bool east = bmap->bitAt(img->indexClamp(x+1, y)); - const bool north = bmap->bitAt(img->indexClamp(x, y-1)); - const bool south = bmap->bitAt(img->indexClamp(x, y+1)); - const bool northwest = bmap->bitAt(img->indexClamp(x-1, y-1)); - const bool northeast = bmap->bitAt(img->indexClamp(x+1, y-1)); - const bool southwest = bmap->bitAt(img->indexClamp(x-1, y+1)); - const bool southeast = bmap->bitAt(img->indexClamp(x+1, y+1)); - - int num = west + east + north + south + northwest + northeast + southwest + southeast; - - if (num != 0) { - - float average = 0.0f; - if (num == 3 && west && northwest && southwest) { - average = channel[img->indexClamp(x-1, y)]; - } - else if (num == 3 && east && northeast && southeast) { - average = channel[img->indexClamp(x+1, y)]; - } - else if (num == 3 && north && northwest && northeast) { - average = channel[img->indexClamp(x, y-1)]; - } - else if (num == 3 && south && southwest && southeast) { - average = channel[img->indexClamp(x, y+1)]; - } - else { - float total = 0.0f; - if (west) { average += 1 * channel[img->indexClamp(x-1, y)]; total += 1; } - if (east) { average += 1 * channel[img->indexClamp(x+1, y)]; total += 1; } - if (north) { average += 1 * channel[img->indexClamp(x, y-1)]; total += 1; } - if (south) { average += 1 * channel[img->indexClamp(x, y+1)]; total += 1; } - - if (northwest) { average += channel[img->indexClamp(x-1, y-1)]; ++total; } - if (northeast) { average += channel[img->indexClamp(x+1, y-1)]; ++total; } - if (southwest) { average += channel[img->indexClamp(x-1, y+1)]; ++total; } - if (southeast) { average += channel[img->indexClamp(x+1, y+1)]; ++total; } - - average /= total; - } - - channel[img->indexClamp(x, y)] = average; - newbmap->setBitAt(x, y); - } - } - } - } - - // Update the bit mask. - swap(*newbmap, *bmap); - } -} - - -namespace { - - struct Neighbor { - uint16 x; - uint16 y; - uint32 d; - }; - - // Compute euclidean squared distance. - static uint dist( uint16 ax, uint16 ay, uint16 bx, uint16 by ) { - int dx = bx - ax; - int dy = by - ay; - return uint(dx*dx + dy*dy); - } - - // Check neighbour, this is the core of the EDT algorithm. - static void checkNeighbour( int x, int y, Neighbor * e, const Neighbor & n ) { - nvDebugCheck(e != NULL); - - uint d = dist( x, y, n.x, n.y ); - if( d < e->d ) { - e->x = n.x; - e->y = n.y; - e->d = d; - } - } - -} // namespace - -// Voronoi filling using EDT-4 -void nv::fillVoronoi(FloatImage * img, const BitMap * bmap) -{ - nvCheck(img != NULL); - - const int w = img->width(); - const int h = img->height(); - const int count = img->componentNum(); - - nvCheck(bmap->width() == uint(w)); - nvCheck(bmap->height() == uint(h)); - - Array edm; - edm.resize(w * h); - - int x, y; - int x0, x1, y0, y1; - - // Init edm. - for( y = 0; y < h; y++ ) { - for( x = 0; x < w; x++ ) { - if( bmap->bitAt(x, y) ) { - edm[y * w + x].x = x; - edm[y * w + x].y = y; - edm[y * w + x].d = 0; - } - else { - edm[y * w + x].x = w; - edm[y * w + x].y = h; - edm[y * w + x].d = w*w + h*h; - } - } - } - - // First pass. - for( y = 0; y < h; y++ ) { - for( x = 0; x < w; x++ ) { - x0 = clamp(x-1, 0, w-1); // @@ Wrap? - x1 = clamp(x+1, 0, w-1); - y0 = clamp(y-1, 0, h-1); - - Neighbor & e = edm[y * w + x]; - checkNeighbour(x, y, &e, edm[y0 * w + x0]); - checkNeighbour(x, y, &e, edm[y0 * w + x]); - checkNeighbour(x, y, &e, edm[y0 * w + x1]); - checkNeighbour(x, y, &e, edm[y * w + x0]); - } - - for( x = w-1; x >= 0; x-- ) { - x1 = clamp(x+1, 0, w-1); - - Neighbor & e = edm[y * w + x]; - checkNeighbour(x, y, &e, edm[y * w + x1]); - } - } - - // Third pass. - for( y = h-1; y >= 0; y-- ) { - for( x = w-1; x >= 0; x-- ) { - x0 = clamp(x-1, 0, w-1); - x1 = clamp(x+1, 0, w-1); - y1 = clamp(y+1, 0, h-1); - - Neighbor & e = edm[y * w + x]; - checkNeighbour(x, y, &e, edm[y * w + x1]); - checkNeighbour(x, y, &e, edm[y1 * w + x0]); - checkNeighbour(x, y, &e, edm[y1 * w + x]); - checkNeighbour(x, y, &e, edm[y1 * w + x1]); - } - - for( x = 0; x < w; x++ ) { - x0 = clamp(x-1, 0, w-1); - - Neighbor & e = edm[y * w + x]; - checkNeighbour(x, y, &e, edm[y * w + x0]); - } - } - - // Fill empty holes. - for( y = 0; y < h; y++ ) { - for( x = 0; x < w; x++ ) { - const int sx = edm[y * w + x].x; - const int sy = edm[y * w + x].y; - nvDebugCheck(sx < w && sy < h); - - if( sx != x || sy != y ) { - for(int c = 0; c < count; c++ ) { - img->setPixel(img->pixel(sx, sy, c), x, y, c); - } - } - } - } - -} - - -void nv::fillBlur(FloatImage * img, const BitMap * bmap) -{ - nvCheck(img != NULL); - - // @@ Apply a 3x3 kernel. -} - - -static bool downsample(const FloatImage * src, const BitMap * srcMask, const FloatImage ** _dst, const BitMap ** _dstMask) -{ - const uint w = src->width(); - const uint h = src->height(); - const uint count = src->componentNum(); - - // count holes in srcMask, return false if fully filled. - uint holes = 0; - for(uint y = 0; y < h; y++) { - for(uint x = 0; x < w; x++) { - holes += srcMask->bitAt(x, y) == 0; - } - } - if (holes == 0 || (w == 2 || h == 2)) { - // Stop when no holes or when the texture is very small. - return false; - } - - // Apply box filter to image and mask and return true. - const uint nw = w / 2; - const uint nh = h / 2; - - FloatImage * dst = new FloatImage(); - dst->allocate(count, nw, nh); - BitMap * dstMask = new BitMap(nw, nh); - - for(uint c = 0; c < count; c++) { - for(uint y = 0; y < nh; y++) { - for(uint x = 0; x < nw; x++) { - - const uint x0 = 2 * x + 0; - const uint x1 = 2 * x + 1; - const uint y0 = 2 * y + 0; - const uint y1 = 2 * y + 1; - - const float f0 = src->pixel(x0, y0, c); - const float f1 = src->pixel(x1, y0, c); - const float f2 = src->pixel(x0, y1, c); - const float f3 = src->pixel(x1, y1, c); - - const bool b0 = srcMask->bitAt(x0, y0); - const bool b1 = srcMask->bitAt(x1, y0); - const bool b2 = srcMask->bitAt(x0, y1); - const bool b3 = srcMask->bitAt(x1, y1); - - if (b0 || b1 || b2 || b3) { - // Set bit mask. - dstMask->setBitAt(x, y); - - // Set pixel. - float value = 0.0f; - int total = 0; - if (b0) { value += f0; total++; } - if (b1) { value += f1; total++; } - if (b2) { value += f2; total++; } - if (b3) { value += f3; total++; } - dst->setPixel(value / total, x, y, c); - } - } - } - } - - *_dst = dst; - *_dstMask = dstMask; - - return true; -} - -// This is the filter used in the Lumigraph paper. -void nv::fillPullPush(FloatImage * img, const BitMap * bmap) -{ - nvCheck(img != NULL); - - const uint count = img->componentNum(); - const uint w = img->width(); - const uint h = img->height(); - const uint num = log2(max(w,h)); - - // Build mipmap chain. - Array mipmaps(num); - Array mipmapMasks(num); - - mipmaps.append(img); - mipmapMasks.append(bmap); - - const FloatImage * current; - const BitMap * currentMask; - - // Compute mipmap chain. - while(downsample(mipmaps.back(), mipmapMasks.back(), ¤t, ¤tMask)) - { - mipmaps.append(current); - mipmapMasks.append(currentMask); - } - - // Sample mipmaps until non-hole is found. - for(uint y = 0; y < h; y++) { - for(uint x = 0; x < w; x++) { - - int sx = x; - int sy = y; - //float sx = x; - //float sy = y; - - const uint levelCount = mipmaps.count(); - for (uint l = 0; l < levelCount; l++) - { - //const float fx = sx / mipmaps[l]->width(); - //const float fy = sy / mipmaps[l]->height(); - - if (mipmapMasks[l]->bitAt(sx, sy)) - { - // Sample mipmaps[l](sx, sy) and copy to img(x, y) - for(uint c = 0; c < count; c++) { - //img->setPixel(mipmaps[l]->linear_clamp(fx, fy, c), x, y, c); - img->setPixel(mipmaps[l]->pixel(sx, sy, c), x, y, c); - } - break; - } - - sx /= 2; - sy /= 2; - } - } - } - - // Don't delete the original image and mask. - mipmaps[0] = NULL; - mipmapMasks[0] = NULL; - - // Delete the mipmaps. - deleteAll(mipmaps); - deleteAll(mipmapMasks); -} - - - -/* - -This Code is from Charles Bloom: - -DoPixelSeamFix -10-20-02 - -Looks in the 5x5 local neighborhood (LocalPixels) of the desired pixel to fill. -It tries to build a quadratic model of the neighborhood surface to use in -extrapolating. You need 5 pixels to establish a 2d quadratic curve. - -This is really just a nice generic way to extrapolate pixels. It also happens -to work great for seam-fixing. - -Note that I'm working on normals, but I treat them just as 3 scalars and normalize -at the end. To be more correct, I would work on the surface of a sphere, but that -just seems like way too much work. - -*/ - -struct LocalPixels -{ - // 5x5 neighborhood - // the center is at result - // index [y][x] - bool fill[5][5]; - float data[5][5]; - - mutable float result; - mutable float weight; - - bool Quad3SubH(float * pQ, int row) const - { - const bool * pFill = fill[row]; - const float * pDat = data[row]; - - if ( pFill[1] && pFill[2] && pFill[3] ) - { - // good row - *pQ = pDat[1] - 2.f * pDat[2] + pDat[3]; - return true; - } - else if ( pFill[0] && pFill[1] && pFill[2] ) - { - // good row - *pQ = pDat[0] - 2.f * pDat[1] + pDat[2]; - return true; - } - else if ( pFill[2] && pFill[3] && pFill[4] ) - { - // good row - *pQ = pDat[2] - 2.f * pDat[3] + pDat[4]; - return true; - } - return false; - } - - // improve result with a horizontal quad in row 1 and/or - bool Quad3SubV(float * pQ, int col) const - { - if ( fill[1][col] && fill[2][col] && fill[3][col] ) - { - // good row - *pQ = data[1][col] - 2.f * data[2][col] + data[3][col]; - return true; - } - else if ( fill[0][col] && fill[1][col] && fill[2][col] ) - { - // good row - *pQ = data[0][col] - 2.f * data[1][col] + data[2][col]; - return true; - } - else if ( fill[2][col] && fill[3][col] && fill[4][col] ) - { - // good row - *pQ = data[2][col] - 2.f * data[3][col] + data[4][col]; - return true; - } - return false; - } - - bool Quad3H(float * pQ) const - { - if (!Quad3SubH(pQ,1)) - { - return Quad3SubH(pQ,3); - } - float q = 0.0f; // initializer not needed, just make it shut up - if (Quad3SubH(&q, 3)) - { - // got q and pQ - *pQ = (*pQ+q)*0.5f; - } - return true; - } - - bool Quad3V(float * pQ) const - { - if (!Quad3SubV(pQ, 1)) - { - return Quad3SubV(pQ, 3); - } - float q = 0.0f; // initializer not needed, just make it shut up - if (Quad3SubV(&q, 3)) - { - // got q and pQ - *pQ = (*pQ + q) * 0.5f; - } - return true; - } - // Quad returns ([0]+[2] - 2.f*[1]) - // a common want is [1] - ([0]+[2])*0.5f ; - // so use -0.5f*Quad - - bool tryQuads() const - { - bool res = false; - - // look for a pair that straddles the middle: - if ( fill[2][1] && fill[2][3] ) - { - // got horizontal straddle - float q; - if ( Quad3H(&q) ) - { - result += (data[2][1] + data[2][3] - q) * 0.5f; - weight += 1.f; - res = true; - } - } - if ( fill[1][2] && fill[3][2] ) - { - // got vertical straddle - float q; - if ( Quad3V(&q) ) - { - result += (data[1][2] + data[3][2] - q) * 0.5f; - weight += 1.f; - res = true; - } - } - - // look for pairs that lead into the middle : - if ( fill[2][0] && fill[2][1] ) - { - // got left-side pair - float q; - if ( Quad3H(&q) ) - { - result += data[2][1]*2.f - data[2][0] + q; - weight += 1.f; - res = true; - } - } - if ( fill[2][3] && fill[2][4] ) - { - // got right-side pair - float q; - if ( Quad3H(&q) ) - { - result += data[2][3]*2.f - data[2][4] + q; - weight += 1.f; - res = true; - } - } - if ( fill[0][2] && fill[1][2] ) - { - // got left-side pair - float q; - if ( Quad3V(&q) ) - { - result += data[1][2]*2.f - data[0][2] + q; - weight += 1.f; - res = true; - } - } - if ( fill[3][2] && fill[4][2] ) - { - // got right-side pair - float q; - if ( Quad3V(&q) ) - { - result += data[3][2]*2.f - data[4][2] + q; - weight += 1.f; - res = true; - } - } - return res; - } - - bool tryPlanar() const - { - // four cases : - const int indices[] = - { - 2,1, 1,2, 1,1, - 2,1, 3,2, 3,1, - 2,3, 1,2, 1,3, - 2,3, 3,2, 3,3 - }; - bool res = false; - for (int i = 0; i < 4; i++) - { - const int * I = indices + i*6; - if (!fill[ I[0] ][ I[1] ]) - continue; - if (!fill[ I[2] ][ I[3] ]) - continue; - if (!fill[ I[4] ][ I[5] ]) - continue; - - result += data[ I[0] ][ I[1] ] + data[ I[2] ][ I[3] ] - data[ I[4] ][ I[5] ]; - weight += 1.0f; - res = true; - } - return res; - } - - bool tryTwos() const - { - bool res = false; - - if (fill[2][1] && fill[2][3]) - { - result += (data[2][1] + data[2][3]) * 0.5f; - weight += 1.0f; - res = true; - } - if (fill[1][2] && fill[3][2]) - { - result += (data[1][2] + data[3][2]) * 0.5f; - weight += 1.0f; - res = true; - } - - // four side-rotates : - const int indices[] = - { - 2,1, 2,0, - 2,3, 2,4, - 1,2, 0,2, - 3,2, 4,2, - }; - for (int i = 0; i < 4; i++) - { - const int * I = indices + i*4; - if (!fill[ I[0] ][ I[1] ]) - continue; - if (!fill[ I[2] ][ I[3] ]) - continue; - - result += data[ I[0] ][ I[1] ]*2.0f - data[ I[2] ][ I[3] ]; - weight += 1.0f; - res = true; - } - - return res; - } - - bool doLocalPixelFill() const - { - result = 0.0f; - weight = 0.0f; - - if (tryQuads()) { - return true; - } - - if (tryPlanar()) { - return true; - } - - return tryTwos(); - } - -}; // struct LocalPixels - - - -// This is a quadratic extrapolation filter from Charles Bloom (DoPixelSeamFix). Used with his permission. -void nv::fillQuadraticExtrapolate(int passCount, FloatImage * img, BitMap * bmap, int coverageIndex /*= -1*/) -{ - nvCheck(passCount > 0); - nvCheck(img != NULL); - nvCheck(bmap != NULL); - - const int w = img->width(); - const int h = img->height(); - const int count = img->componentNum(); - - nvCheck(bmap->width() == uint(w)); - nvCheck(bmap->height() == uint(h)); - - AutoPtr newbmap( new BitMap(w, h) ); - - float * coverageChannel = NULL; - if (coverageIndex != -1) - { - coverageChannel = img->channel(coverageIndex); - } - - int firstChannel = -1; - - for (int p = 0; p < passCount; p++) - { - for (int c = 0; c < count; c++) - { - if (c == coverageIndex) continue; - if (firstChannel == -1) firstChannel = c; - - float * channel = img->channel(c); - - for (int yb = 0; yb < h; yb++) { - for (int xb = 0; xb < w; xb++) { - - if (bmap->bitAt(xb, yb)) { - // Not a hole. - newbmap->setBitAt(xb, yb); - continue; - } - - int numFill = 0; - - LocalPixels lp; - for (int ny = 0; ny < 5; ny++) - { - int y = (yb + ny - 2); - if ( y < 0 || y >= h ) - { - // out of range - for(int i = 0; i < 5; i++) - { - lp.fill[ny][i] = false; - } - continue; - } - - for (int nx = 0; nx < 5; nx++) - { - int x = (xb + nx - 2); - if (x < 0 || x >= w) - { - lp.fill[ny][nx] = false; - } - else - { - int idx = img->index(x, y); - if (!bmap->bitAt(idx)) - { - lp.fill[ny][nx] = false; - } - else - { - lp.fill[ny][nx] = true; - lp.data[ny][nx] = channel[idx]; - numFill++; - } - } - } - } - - // need at least 3 to do anything decent - if (numFill < 2) - continue; - - nvDebugCheck(lp.fill[2][2] == false); - - if (lp.doLocalPixelFill()) - { - const int idx = img->index(xb, yb); - channel[idx] = lp.result / lp.weight; - - if (c == firstChannel) - { - //coverageChannel[idx] /= lp.weight; // @@ Not sure what this was for, coverageChannel[idx] is always zero. - newbmap->setBitAt(xb, yb); - } - } - } - } - } - - // Update the bit mask. - swap(*newbmap, *bmap); - } -} diff --git a/Externals/NVTT/src/nvimage/HoleFilling.h b/Externals/NVTT/src/nvimage/HoleFilling.h deleted file mode 100644 index b437e875c1e..00000000000 --- a/Externals/NVTT/src/nvimage/HoleFilling.h +++ /dev/null @@ -1,96 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_HOLEFILLING_H -#define NV_IMAGE_HOLEFILLING_H - -#include -#include - -namespace nv -{ - class FloatImage; - - /// Bit mask. - class BitMap - { - public: - BitMap(uint w, uint h) : - m_width(w), m_height(h), m_bitArray(w*h) - { - } - - const uint width() const { return m_width; } - const uint height() const { return m_height; } - - bool bitAt(uint x, uint y) const - { - nvDebugCheck(x < m_width && y < m_height); - return m_bitArray.bitAt(y * m_width + x); - } - bool bitAt(uint idx) const - { - return m_bitArray.bitAt(idx); - } - - void setBitAt(uint x, uint y) - { - nvDebugCheck(x < m_width && y < m_height); - m_bitArray.setBitAt(y * m_width + x); - } - void setBitAt(uint idx) - { - m_bitArray.setBitAt(idx); - } - - void clearBitAt(uint x, uint y) - { - nvDebugCheck(x < m_width && y < m_height); - m_bitArray.clearBitAt(y * m_width + x); - } - void clearBitAt(uint idx) - { - m_bitArray.clearBitAt(idx); - } - - void clearAll() - { - m_bitArray.clearAll(); - } - - void setAll() - { - m_bitArray.setAll(); - } - - void toggleAll() - { - m_bitArray.toggleAll(); - } - - friend void swap(BitMap & a, BitMap & b) - { - nvCheck(a.m_width == b.m_width); - nvCheck(a.m_height == b.m_height); - //swap(const_cast(a.m_width), const_cast(b.m_width)); - //swap(const_cast(a.m_height), const_cast(b.m_height)); - swap(a.m_bitArray, b.m_bitArray); - } - - private: - - const uint m_width; - const uint m_height; - BitArray m_bitArray; - - }; - - NVIMAGE_API void fillVoronoi(FloatImage * img, const BitMap * bmap); - NVIMAGE_API void fillBlur(FloatImage * img, const BitMap * bmap); - NVIMAGE_API void fillPullPush(FloatImage * img, const BitMap * bmap); - - NVIMAGE_API void fillExtrapolate(int passCount, FloatImage * img, BitMap * bmap); - NVIMAGE_API void fillQuadraticExtrapolate(int passCount, FloatImage * img, BitMap * bmap, int coverageIndex = -1); - -} // nv namespace - -#endif // NV_IMAGE_HOLEFILLING_H diff --git a/Externals/NVTT/src/nvimage/Image.cpp b/Externals/NVTT/src/nvimage/Image.cpp deleted file mode 100644 index 2307d5c3dac..00000000000 --- a/Externals/NVTT/src/nvimage/Image.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include - -#include - -#include -#include - - -using namespace nv; - -Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL) -{ -} - -Image::Image(const Image & img) : m_data(NULL) -{ - allocate(img.m_width, img.m_height); - m_format = img.m_format; - memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height); -} - -Image::~Image() -{ - free(); -} - -const Image & Image::operator=(const Image & img) -{ - allocate(img.m_width, img.m_height); - m_format = img.m_format; - memcpy(m_data, img.m_data, sizeof(Color32) * m_width * m_height); - return *this; -} - - -void Image::allocate(uint w, uint h) -{ - m_width = w; - m_height = h; - m_data = (Color32 *)realloc(m_data, w * h * sizeof(Color32)); -} - -bool Image::load(const char * name) -{ - free(); - - AutoPtr img(ImageIO::load(name)); - if (img == NULL) { - return false; - } - - swap(m_width, img->m_width); - swap(m_height, img->m_height); - swap(m_format, img->m_format); - swap(m_data, img->m_data); - - return true; -} - -void Image::wrap(void * data, uint w, uint h) -{ - free(); - m_data = (Color32 *)data; - m_width = w; - m_height = h; -} - -void Image::unwrap() -{ - m_data = NULL; - m_width = 0; - m_height = 0; -} - - -void Image::free() -{ - nv::mem::free(m_data); - m_data = NULL; -} - - -uint Image::width() const -{ - return m_width; -} - -uint Image::height() const -{ - return m_height; -} - -const Color32 * Image::scanline(uint h) const -{ - nvDebugCheck(h < m_height); - return m_data + h * m_width; -} - -Color32 * Image::scanline(uint h) -{ - nvDebugCheck(h < m_height); - return m_data + h * m_width; -} - -const Color32 * Image::pixels() const -{ - return m_data; -} - -Color32 * Image::pixels() -{ - return m_data; -} - -const Color32 & Image::pixel(uint idx) const -{ - nvDebugCheck(idx < m_width * m_height); - return m_data[idx]; -} - -Color32 & Image::pixel(uint idx) -{ - nvDebugCheck(idx < m_width * m_height); - return m_data[idx]; -} - - -Image::Format Image::format() const -{ - return m_format; -} - -void Image::setFormat(Image::Format f) -{ - m_format = f; -} - -void Image::fill(Color32 c) -{ - const uint size = m_width * m_height; - for (uint i = 0; i < size; ++i) - { - m_data[i] = c; - } -} - diff --git a/Externals/NVTT/src/nvimage/Image.h b/Externals/NVTT/src/nvimage/Image.h deleted file mode 100644 index da1b0c5eea3..00000000000 --- a/Externals/NVTT/src/nvimage/Image.h +++ /dev/null @@ -1,83 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_IMAGE_H -#define NV_IMAGE_IMAGE_H - -#include -#include - -namespace nv -{ - class Color32; - - /// 32 bit RGBA image. - class NVIMAGE_CLASS Image - { - public: - - enum Format - { - Format_RGB, - Format_ARGB, - }; - - Image(); - Image(const Image & img); - ~Image(); - - const Image & operator=(const Image & img); - - - void allocate(uint w, uint h); - bool load(const char * name); - - void wrap(void * data, uint w, uint h); - void unwrap(); - - uint width() const; - uint height() const; - - const Color32 * scanline(uint h) const; - Color32 * scanline(uint h); - - const Color32 * pixels() const; - Color32 * pixels(); - - const Color32 & pixel(uint idx) const; - Color32 & pixel(uint idx); - - const Color32 & pixel(uint x, uint y) const; - Color32 & pixel(uint x, uint y); - - Format format() const; - void setFormat(Format f); - - void fill(Color32 c); - - private: - void free(); - - private: - uint m_width; - uint m_height; - Format m_format; - Color32 * m_data; - }; - - - inline const Color32 & Image::pixel(uint x, uint y) const - { - nvDebugCheck(x < width() && y < height()); - return pixel(y * width() + x); - } - - inline Color32 & Image::pixel(uint x, uint y) - { - nvDebugCheck(x < width() && y < height()); - return pixel(y * width() + x); - } - -} // nv namespace - - -#endif // NV_IMAGE_IMAGE_H diff --git a/Externals/NVTT/src/nvimage/ImageIO.cpp b/Externals/NVTT/src/nvimage/ImageIO.cpp deleted file mode 100644 index cd17f07bb51..00000000000 --- a/Externals/NVTT/src/nvimage/ImageIO.cpp +++ /dev/null @@ -1,1509 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include -#include -#include - -#include - -#include - -#include "ImageIO.h" -#include "Image.h" -#include "FloatImage.h" -#include "TgaFile.h" -#include "PsdFile.h" - -// Extern -#if defined(HAVE_JPEG) -extern "C" { -# include -} -#endif - -#if defined(HAVE_PNG) -# include -#endif - -#if defined(HAVE_TIFF) -# define _TIFF_DATA_TYPEDEFS_ -# include -#endif - -#if defined(HAVE_OPENEXR) -# include -# include -# include -# include -# include -# include -#endif - -using namespace nv; - -namespace { - - // Array of image load plugins. -// static HashMap s_plugin_load_map; - - // Array of image save plugins. -// static HashMap s_plugin_save_map; - - struct Color555 { - uint16 b : 5; - uint16 g : 5; - uint16 r : 5; - }; - -} // namespace - - -Image * nv::ImageIO::load(const char * fileName) -{ - nvDebugCheck(fileName != NULL); - - StdInputStream stream(fileName); - - if (stream.isError()) { - return NULL; - } - - return ImageIO::load(fileName, stream); -} - -Image * nv::ImageIO::load(const char * fileName, Stream & s) -{ - nvDebugCheck(fileName != NULL); - nvDebugCheck(s.isLoading()); - - const char * extension = Path::extension(fileName); - - if (strCaseCmp(extension, ".tga") == 0) { - return ImageIO::loadTGA(s); - } -#if defined(HAVE_JPEG) - if (strCaseCmp(extension, ".jpg") == 0 || strCaseCmp(extension, ".jpeg") == 0) { - return loadJPG(s); - } -#endif -#if defined(HAVE_PNG) - if (strCaseCmp(extension, ".png") == 0) { - return loadPNG(s); - } -#endif - if (strCaseCmp(extension, ".psd") == 0) { - return loadPSD(s); - } - // @@ use image plugins? - return NULL; -} - -bool nv::ImageIO::save(const char * fileName, Stream & s, Image * img) -{ - nvDebugCheck(fileName != NULL); - nvDebugCheck(s.isSaving()); - nvDebugCheck(img != NULL); - - const char * extension = Path::extension(fileName); - - if (strCaseCmp(extension, ".tga") == 0) { - return ImageIO::saveTGA(s, img); - } - - return false; -} - -bool nv::ImageIO::save(const char * fileName, Image * img) -{ - nvDebugCheck(fileName != NULL); - nvDebugCheck(img != NULL); - - StdOutputStream stream(fileName); - if (stream.isError()) - { - return false; - } - - return ImageIO::save(fileName, stream, img); -} - -FloatImage * nv::ImageIO::loadFloat(const char * fileName) -{ - nvDebugCheck(fileName != NULL); - - StdInputStream stream(fileName); - - if (stream.isError()) { - return NULL; - } - - return loadFloat(fileName, stream); -} - -FloatImage * nv::ImageIO::loadFloat(const char * fileName, Stream & s) -{ - nvDebugCheck(fileName != NULL); - - const char * extension = Path::extension(fileName); - -#if defined(HAVE_TIFF) - if (strCaseCmp(extension, ".tif") == 0 || strCaseCmp(extension, ".tiff") == 0) { - return loadFloatTIFF(fileName, s); - } -#endif -#if defined(HAVE_OPENEXR) - if (strCaseCmp(extension, ".exr") == 0) { - return loadFloatEXR(fileName, s); - } -#endif - -/* // @@ Disable temporarily - if (strCaseCmp(extension, ".pfm") == 0) { - return loadFloatPFM(fileName, s); - } -*/ - - return NULL; -} - - -bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components) -{ - const char * extension = Path::extension(fileName); - -#if defined(HAVE_OPENEXR) - if (strCaseCmp(extension, ".exr") == 0) - { - return ImageIO::saveFloatEXR(fileName, fimage, base_component, num_components); - } -#endif - -#if defined(HAVE_TIFF) - if (strCaseCmp(extension, ".tif") == 0 || strCaseCmp(extension, ".tiff") == 0) - { - return ImageIO::saveFloatTIFF(fileName, fimage, base_component, num_components); - } -#endif - -/* // @@ Disable Temporarily - if (strCaseCmp(extension, ".pfm") == 0) - { -// return ImageIO::saveFloatPFM(fileName, fimage, base_component, num_components); - } -*/ - - if (num_components == 3 || num_components == 4) - { - AutoPtr image(fimage->createImage(base_component, num_components)); - nvCheck(image != NULL); - - if (num_components == 4) - { - image->setFormat(Image::Format_ARGB); - } - - return ImageIO::save(fileName, image.ptr()); - } - - return false; -} - - -/// Load TGA image. -Image * nv::ImageIO::loadTGA(Stream & s) -{ - nvCheck(!s.isError()); - nvCheck(s.isLoading()); - - TgaHeader tga; - s << tga; - s.seek(TgaHeader::Size + tga.id_length); - - // Get header info. - bool rle = false; - bool pal = false; - bool rgb = false; - bool grey = false; - - switch( tga.image_type ) { - case TGA_TYPE_RLE_INDEXED: - rle = true; - // no break is intended! - case TGA_TYPE_INDEXED: - if( tga.colormap_type!=1 || tga.colormap_size!=24 || tga.colormap_length>256 ) { - nvDebug( "*** ImageIO::loadTGA: Error, only 24bit paletted images are supported.\n" ); - return NULL; - } - pal = true; - break; - - case TGA_TYPE_RLE_RGB: - rle = true; - // no break is intended! - case TGA_TYPE_RGB: - rgb = true; - break; - - case TGA_TYPE_RLE_GREY: - rle = true; - // no break is intended! - case TGA_TYPE_GREY: - grey = true; - break; - - default: - nvDebug( "*** ImageIO::loadTGA: Error, unsupported image type.\n" ); - return NULL; - } - - const uint pixel_size = (tga.pixel_size/8); - nvDebugCheck(pixel_size <= 4); - - const uint size = tga.width * tga.height * pixel_size; - - - // Read palette - uint8 palette[768]; - if( pal ) { - nvDebugCheck(tga.colormap_length < 256); - s.serialize(palette, 3 * tga.colormap_length); - } - - // Decode image. - uint8 * mem = new uint8[size]; - if( rle ) { - // Decompress image in src. - uint8 * dst = mem; - int num = size; - - while (num > 0) { - // Get packet header - uint8 c; - s << c; - - uint count = (c & 0x7f) + 1; - num -= count * pixel_size; - - if (c & 0x80) { - // RLE pixels. - uint8 pixel[4]; // uint8 pixel[pixel_size]; - s.serialize( pixel, pixel_size ); - do { - memcpy(dst, pixel, pixel_size); - dst += pixel_size; - } while (--count); - } - else { - // Raw pixels. - count *= pixel_size; - //file->Read8(dst, count); - s.serialize(dst, count); - dst += count; - } - } - } - else { - s.serialize(mem, size); - } - - // Allocate image. - AutoPtr img(new Image()); - img->allocate(tga.width, tga.height); - - int lstep; - Color32 * dst; - if( tga.flags & TGA_ORIGIN_UPPER ) { - lstep = tga.width; - dst = img->pixels(); - } - else { - lstep = - tga.width; - dst = img->pixels() + (tga.height-1) * tga.width; - } - - // Write image. - uint8 * src = mem; - if( pal ) { - for( int y = 0; y < tga.height; y++ ) { - for( int x = 0; x < tga.width; x++ ) { - uint8 idx = *src++; - dst[x].setBGRA(palette[3*idx+0], palette[3*idx+1], palette[3*idx+2], 0xFF); - } - dst += lstep; - } - } - else if( grey ) { - img->setFormat(Image::Format_ARGB); - - for( int y = 0; y < tga.height; y++ ) { - for( int x = 0; x < tga.width; x++ ) { - dst[x].setBGRA(*src, *src, *src, *src); - src++; - } - dst += lstep; - } - } - else { - - if( tga.pixel_size == 16 ) { - for( int y = 0; y < tga.height; y++ ) { - for( int x = 0; x < tga.width; x++ ) { - Color555 c = *reinterpret_cast(src); - uint8 b = (c.b << 3) | (c.b >> 2); - uint8 g = (c.g << 3) | (c.g >> 2); - uint8 r = (c.r << 3) | (c.r >> 2); - dst[x].setBGRA(b, g, r, 0xFF); - src += 2; - } - dst += lstep; - } - } - else if( tga.pixel_size == 24 ) { - for( int y = 0; y < tga.height; y++ ) { - for( int x = 0; x < tga.width; x++ ) { - dst[x].setBGRA(src[0], src[1], src[2], 0xFF); - src += 3; - } - dst += lstep; - } - } - else if( tga.pixel_size == 32 ) { - img->setFormat(Image::Format_ARGB); - - for( int y = 0; y < tga.height; y++ ) { - for( int x = 0; x < tga.width; x++ ) { - dst[x].setBGRA(src[0], src[1], src[2], src[3]); - src += 4; - } - dst += lstep; - } - } - } - - // free uncompressed data. - delete [] mem; - - return img.release(); -} - -/// Save TGA image. -bool nv::ImageIO::saveTGA(Stream & s, const Image * img) -{ - nvCheck(!s.isError()); - nvCheck(img != NULL); - nvCheck(img->pixels() != NULL); - - TgaFile tga; - tga.head.id_length = 0; - tga.head.colormap_type = 0; - tga.head.image_type = TGA_TYPE_RGB; - - tga.head.colormap_index = 0; - tga.head.colormap_length = 0; - tga.head.colormap_size = 0; - - tga.head.x_origin = 0; - tga.head.y_origin = 0; - tga.head.width = img->width(); - tga.head.height = img->height(); - if(img->format() == Image::Format_ARGB) { - tga.head.pixel_size = 32; - tga.head.flags = TGA_ORIGIN_UPPER | TGA_HAS_ALPHA; - } - else { - tga.head.pixel_size = 24; - tga.head.flags = TGA_ORIGIN_UPPER; - } - - // @@ Serialize directly. - tga.allocate(); - - const uint n = img->width() * img->height(); - if(img->format() == Image::Format_ARGB) { - for(uint i = 0; i < n; i++) { - Color32 color = img->pixel(i); - tga.mem[4 * i + 0] = color.b; - tga.mem[4 * i + 1] = color.g; - tga.mem[4 * i + 2] = color.r; - tga.mem[4 * i + 3] = color.a; - } - } - else { - for(uint i = 0; i < n; i++) { - Color32 color = img->pixel(i); - tga.mem[3 * i + 0] = color.b; - tga.mem[3 * i + 1] = color.g; - tga.mem[3 * i + 2] = color.r; - } - } - - s << tga; - - tga.free(); - - return true; -} - -/// Load PSD image. -Image * nv::ImageIO::loadPSD(Stream & s) -{ - nvCheck(!s.isError()); - nvCheck(s.isLoading()); - - s.setByteOrder(Stream::BigEndian); - - PsdHeader header; - s << header; - - if (!header.isValid()) - { - printf("invalid header!\n"); - return NULL; - } - - if (!header.isSupported()) - { - printf("unsupported file!\n"); - return NULL; - } - - int tmp; - - // Skip mode data. - s << tmp; - s.seek(s.tell() + tmp); - - // Skip image resources. - s << tmp; - s.seek(s.tell() + tmp); - - // Skip the reserved data. - s << tmp; - s.seek(s.tell() + tmp); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - uint16 compression; - s << compression; - - if (compression > 1) { - // Unknown compression type. - return NULL; - } - - uint channel_num = header.channel_count; - - AutoPtr img(new Image()); - img->allocate(header.width, header.height); - - if (channel_num < 4) - { - // Clear the image. - img->fill(Color32(0, 0, 0, 0xFF)); - } - else - { - // Enable alpha. - img->setFormat(Image::Format_ARGB); - - // Ignore remaining channels. - channel_num = 4; - } - - - const uint pixel_count = header.height * header.width; - - static const uint components[4] = {2, 1, 0, 3}; - - if (compression) - { - s.seek(s.tell() + header.height * header.channel_count * sizeof(uint16)); - - // Read RLE data. - for (uint channel = 0; channel < channel_num; channel++) - { - uint8 * ptr = (uint8 *)img->pixels() + components[channel]; - - uint count = 0; - while( count < pixel_count ) - { - if (s.isAtEnd()) return NULL; - - uint8 c; - s << c; - - uint len = c; - if (len < 128) - { - // Copy next len+1 bytes literally. - len++; - count += len; - if (count > pixel_count) return NULL; - - while (len != 0) - { - s << *ptr; - ptr += 4; - len--; - } - } - else if (len > 128) - { - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0xFF; - len += 2; - count += len; - if (s.isAtEnd() || count > pixel_count) return NULL; - - uint8 val; - s << val; - while( len != 0 ) { - *ptr = val; - ptr += 4; - len--; - } - } - else if( len == 128 ) { - // No-op. - } - } - } - } - else - { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. - - // Read the data by channel. - for (uint channel = 0; channel < channel_num; channel++) - { - uint8 * ptr = (uint8 *)img->pixels() + components[channel]; - - // Read the data. - uint count = pixel_count; - while (count != 0) - { - s << *ptr; - ptr += 4; - count--; - } - } - } - - return img.release(); -} - -#if defined(HAVE_PNG) - -static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - nvDebugCheck(png_ptr != NULL); - - Stream * s = (Stream *)png_ptr->io_ptr; - s->serialize(data, (int)length); - - if (s->isError()) { - png_error(png_ptr, "Read Error"); - } -} - - -Image * nv::ImageIO::loadPNG(Stream & s) -{ - nvCheck(!s.isError()); - - // Set up a read buffer and check the library version - png_structp png_ptr; - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { - // nvDebug( "*** LoadPNG: Error allocating read buffer in file '%s'.\n", name ); - return false; - } - - // Allocate/initialize a memory block for the image information - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, NULL, NULL); - // nvDebug( "*** LoadPNG: Error allocating image information for '%s'.\n", name ); - return false; - } - - // Set up the error handling - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - // nvDebug( "*** LoadPNG: Error reading png file '%s'.\n", name ); - return false; - } - - // Set up the I/O functions. - png_set_read_fn(png_ptr, (void*)&s, user_read_data); - - - // Retrieve the image header information - png_uint_32 width, height; - int bit_depth, color_type, interlace_type; - png_read_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); - - - if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8) { - // Convert indexed images to RGB. - png_set_expand(png_ptr); - } - else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { - // Convert grayscale to RGB. - png_set_expand(png_ptr); - } - else if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - // Expand images with transparency to full alpha channels - // so the data will be available as RGBA quartets. - png_set_expand(png_ptr); - } - else if (bit_depth < 8) { - // If we have < 8 scale it up to 8. - //png_set_expand(png_ptr); - png_set_packing(png_ptr); - } - - // Reduce bit depth. - if (bit_depth == 16) { - png_set_strip_16(png_ptr); - } - - // Represent gray as RGB - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(png_ptr); - } - - // Convert to RGBA filling alpha with 0xFF. - if (!(color_type & PNG_COLOR_MASK_ALPHA)) { - png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); - } - - // @todo Choose gamma according to the platform? - double screen_gamma = 2.2; - int intent; - if (png_get_sRGB(png_ptr, info_ptr, &intent)) { - png_set_gamma(png_ptr, screen_gamma, 0.45455); - } - else { - double image_gamma; - if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) { - png_set_gamma(png_ptr, screen_gamma, image_gamma); - } - else { - png_set_gamma(png_ptr, screen_gamma, 0.45455); - } - } - - // Perform the selected transforms. - png_read_update_info(png_ptr, info_ptr); - - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); - - AutoPtr img(new Image()); - img->allocate(width, height); - - // Set internal format flags. - if(color_type & PNG_COLOR_MASK_COLOR) { - //img->flags |= PI_IF_HAS_COLOR; - } - if(color_type & PNG_COLOR_MASK_ALPHA) { - //img->flags |= PI_IF_HAS_ALPHA; - img->setFormat(Image::Format_ARGB); - } - - // Read the image - uint8 * pixels = (uint8 *)img->pixels(); - png_bytep * row_data = new png_bytep[sizeof(png_byte) * height]; - for (uint i = 0; i < height; i++) { - row_data[i] = &(pixels[width * 4 * i]); - } - - png_read_image(png_ptr, row_data); - delete [] row_data; - - // Finish things up - png_read_end(png_ptr, info_ptr); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - - // RGBA to BGRA. - uint num = width * height; - for(uint i = 0; i < num; i++) - { - Color32 c = img->pixel(i); - img->pixel(i) = Color32(c.b, c.g, c.r, c.a); - } - - // Compute alpha channel if needed. - /*if( img->flags & PI_IU_BUMPMAP || img->flags & PI_IU_ALPHAMAP ) { - if( img->flags & PI_IF_HAS_COLOR && !(img->flags & PI_IF_HAS_ALPHA)) { - img->ComputeAlphaFromColor(); - } - }*/ - - return img.release(); -} - -#endif // defined(HAVE_PNG) - -#if defined(HAVE_JPEG) - -static void init_source (j_decompress_ptr /*cinfo*/){ -} - -static boolean fill_input_buffer (j_decompress_ptr cinfo){ - struct jpeg_source_mgr * src = cinfo->src; - static JOCTET FakeEOI[] = { 0xFF, JPEG_EOI }; - - // Generate warning - nvDebug("jpeglib: Premature end of file\n"); - - // Insert a fake EOI marker - src->next_input_byte = FakeEOI; - src->bytes_in_buffer = 2; - - return TRUE; -} - -static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) { - struct jpeg_source_mgr * src = cinfo->src; - - if(num_bytes >= (long)src->bytes_in_buffer) { - fill_input_buffer(cinfo); - return; - } - - src->bytes_in_buffer -= num_bytes; - src->next_input_byte += num_bytes; -} - -static void term_source (j_decompress_ptr /*cinfo*/){ - // no work necessary here -} - - -Image * nv::ImageIO::loadJPG(Stream & s) -{ - nvCheck(!s.isError()); - - // Read the entire file. - Array byte_array; - byte_array.resize(s.size()); - s.serialize(byte_array.unsecureBuffer(), s.size()); - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - - cinfo.src = (struct jpeg_source_mgr *) (*cinfo.mem->alloc_small) - ((j_common_ptr) &cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr)); - cinfo.src->init_source = init_source; - cinfo.src->fill_input_buffer = fill_input_buffer; - cinfo.src->skip_input_data = skip_input_data; - cinfo.src->resync_to_restart = jpeg_resync_to_restart; // use default method - cinfo.src->term_source = term_source; - cinfo.src->bytes_in_buffer = byte_array.size(); - cinfo.src->next_input_byte = byte_array.buffer(); - - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - /* - cinfo.do_fancy_upsampling = FALSE; // fast decompression - cinfo.dct_method = JDCT_FLOAT; // Choose floating point DCT method. - */ - - uint8 * tmp_buffer = new uint8 [cinfo.output_width * cinfo.output_height * cinfo.num_components]; - uint8 * scanline = tmp_buffer; - - while( cinfo.output_scanline < cinfo.output_height ){ - int num_scanlines = jpeg_read_scanlines (&cinfo, &scanline, 1); - scanline += num_scanlines * cinfo.output_width * cinfo.num_components; - } - - jpeg_finish_decompress(&cinfo); - - AutoPtr img(new Image()); - img->allocate(cinfo.output_width, cinfo.output_height); - - Color32 * dst = img->pixels(); - const int size = img->height() * img->width(); - const uint8 * src = tmp_buffer; - - if( cinfo.num_components == 3 ) { - img->setFormat(Image::Format_RGB); - for( int i = 0; i < size; i++ ) { - *dst++ = Color32(src[0], src[1], src[2]); - src += 3; - } - } - else { - img->setFormat(Image::Format_ARGB); - for( int i = 0; i < size; i++ ) { - *dst++ = Color32(*src, *src, *src, *src); - src++; - } - } - - delete [] tmp_buffer; - jpeg_destroy_decompress (&cinfo); - - return img.release(); -} - -#endif // defined(HAVE_JPEG) - -#if defined(HAVE_TIFF) - -/* -static tsize_t tiffReadWriteProc(thandle_t h, tdata_t ptr, tsize_t size) -{ - Stream * s = (Stream *)h; - nvDebugCheck(s != NULL); - - s->serialize(ptr, size); - - return size; -} - -static toff_t tiffSeekProc(thandle_t h, toff_t offset, int whence) -{ - Stream * s = (Stream *)h; - nvDebugCheck(s != NULL); - - if (!s->isSeekable()) - { - return (toff_t)-1; - } - - if (whence == SEEK_SET) - { - s->seek(offset); - } - else if (whence == SEEK_CUR) - { - s->seek(s->tell() + offset); - } - else if (whence == SEEK_END) - { - s->seek(s->size() + offset); - } - - return s->tell(); -} - -static int tiffCloseProc(thandle_t) -{ - return 0; -} - -static toff_t tiffSizeProc(thandle_t h) -{ - Stream * s = (Stream *)h; - nvDebugCheck(s != NULL); - return s->size(); -} - -static int tiffMapFileProc(thandle_t, tdata_t*, toff_t*) -{ - // @@ TODO, Implement these functions. - return -1; -} - -static void tiffUnmapFileProc(thandle_t, tdata_t, toff_t) -{ - // @@ TODO, Implement these functions. -} -*/ - -FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName, Stream & s) -{ - nvCheck(!s.isError()); - - TIFF * tif = TIFFOpen(fileName, "r"); - //TIFF * tif = TIFFClientOpen(fileName, "r", &s, tiffReadWriteProc, tiffReadWriteProc, tiffSeekProc, tiffCloseProc, tiffSizeProc, tiffMapFileProc, tiffUnmapFileProc); - - if (!tif) - { - nvDebug("Can't open '%s' for reading\n", fileName); - return NULL; - } - - ::uint16 spp, bpp, format; - ::uint32 width, height; - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp); - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &format); - - if (bpp != 8 && bpp != 16 && bpp != 32) { - nvDebug("Can't load '%s', only 1 sample per pixel supported\n", fileName); - TIFFClose(tif); - return NULL; - } - - AutoPtr fimage(new FloatImage()); - fimage->allocate(spp, width, height); - - int linesize = TIFFScanlineSize(tif); - tdata_t buf = (::uint8 *)nv::mem::malloc(linesize); - - for (uint y = 0; y < height; y++) - { - TIFFReadScanline(tif, buf, y, 0); - - for (uint c=0; cscanline(y, c); - - for(uint x = 0; x < width; x++) - { - if (bpp == 8) - { - dst[x] = float(((::uint8 *)buf)[x*spp+c]) / float(0xFF); - } - else if (bpp == 16) - { - dst[x] = float(((::uint16 *)buf)[x*spp+c]) / float(0xFFFF); - } - else if (bpp == 32) - { - if (format==SAMPLEFORMAT_IEEEFP) - { - dst[x] = float(((float *)buf)[x*spp+c]); - } - else - { - dst[x] = float(((::uint32 *)buf)[x*spp+c] >> 8) / float(0xFFFFFF); - } - - } - - } - } - } - - nv::mem::free(buf); - - TIFFClose(tif); - - return fimage.release(); -} - -bool nv::ImageIO::saveFloatTIFF(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components) -{ - nvCheck(fileName != NULL); - nvCheck(fimage != NULL); - nvCheck(base_component + num_components <= fimage->componentNum()); - - const int iW = fimage->width(); - const int iH = fimage->height(); - const int iC = num_components; - - TIFF * image = TIFFOpen(fileName, "w"); - - // Open the TIFF file - if (image == NULL) - { - nvDebug("Could not open '%s' for writing\n", fileName); - return false; - } - - TIFFSetField(image, TIFFTAG_IMAGEWIDTH, iW); - TIFFSetField(image, TIFFTAG_IMAGELENGTH, iH); - TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, iC); - TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); - TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 32); - - uint32 rowsperstrip = TIFFDefaultStripSize(image, (uint32)-1); - - TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip); - TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS); - if (num_components == 3) - { - // Set this so that it can be visualized with pfstools. - TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - } - TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - - float * scanline = new float[iW * iC]; - for (int y = 0; y < iH; y++) - { - for (int c = 0; c < iC; c++) - { - const float * src = fimage->scanline(y, base_component + c); - for (int x = 0; x < iW; x++) scanline[x * iC + c] = src[x]; - } - if (TIFFWriteScanline(image, scanline, y, 0)==-1) - { - nvDebug("Error writing scanline %d\n", y); - return false; - } - } - delete [] scanline; - - // Close the file - TIFFClose(image); - return true; -} - -#endif - -#if defined(HAVE_OPENEXR) - -namespace -{ - class ExrStream : public Imf::IStream - { - public: - ExrStream(const char * name, Stream & s) : Imf::IStream(name), m_stream(s) - { - nvDebugCheck(s.isLoading()); - } - - virtual bool read(char c[], int n) - { - m_stream.serialize(c, n); - - if (m_stream.isError()) - { - throw Iex::InputExc("I/O error."); - } - - return m_stream.isAtEnd(); - } - - virtual Imf::Int64 tellg() - { - return m_stream.tell(); - } - - virtual void seekg(Imf::Int64 pos) - { - m_stream.seek(pos); - } - - virtual void clear() - { - m_stream.clearError(); - } - - private: - Stream & m_stream; - }; - -} // namespace - -FloatImage * nv::ImageIO::loadFloatEXR(const char * fileName, Stream & s) -{ - nvCheck(s.isLoading()); - nvCheck(!s.isError()); - - ExrStream stream(fileName, s); - Imf::InputFile inputFile(stream); - - Imath::Box2i box = inputFile.header().dataWindow(); - - int width = box.max.x - box.min.y + 1; - int height = box.max.x - box.min.y + 1; - - const Imf::ChannelList & channels = inputFile.header().channels(); - - // Count channels. - uint channelCount= 0; - for (Imf::ChannelList::ConstIterator it = channels.begin(); it != channels.end(); ++it) - { - channelCount++; - } - - // Allocate FloatImage. - AutoPtr fimage(new FloatImage()); - fimage->allocate(channelCount, width, height); - - // Describe image's layout with a framebuffer. - Imf::FrameBuffer frameBuffer; - uint i = 0; - for (Imf::ChannelList::ConstIterator it = channels.begin(); it != channels.end(); ++it, ++i) - { - frameBuffer.insert(it.name(), Imf::Slice(Imf::FLOAT, (char *)fimage->channel(i), sizeof(float), sizeof(float) * width)); - } - - // Read it. - inputFile.setFrameBuffer (frameBuffer); - inputFile.readPixels (box.min.y, box.max.y); - - return fimage.release(); -} - -bool nv::ImageIO::saveFloatEXR(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components) -{ - nvCheck(fileName != NULL); - nvCheck(fimage != NULL); - nvCheck(base_component + num_components <= fimage->componentNum()); - nvCheck(num_components > 0 && num_components <= 4); - - const int w = fimage->width(); - const int h = fimage->height(); - - const char * channelNames[] = {"R", "G", "B", "A"}; - - Imf::Header header (w, h); - - for (uint c = 0; c < num_components; c++) - { - header.channels().insert(channelNames[c], Imf::Channel(Imf::FLOAT)); - } - - Imf::OutputFile file(fileName, header); - Imf::FrameBuffer frameBuffer; - - for (uint c = 0; c < num_components; c++) - { - char * channel = (char *) fimage->channel(base_component + c); - frameBuffer.insert(channelNames[c], Imf::Slice(Imf::FLOAT, channel, sizeof(float), sizeof(float) * w)); - } - - file.setFrameBuffer(frameBuffer); - file.writePixels(h); - - return true; -} - -#endif // defined(HAVE_OPENEXR) - -#if 0 // @@ Disable temporarily. - -FloatImage * nv::ImageIO::loadFloatPFM(const char * fileName, Stream & s) -{ - nvCheck(s.isLoading()); - nvCheck(!s.isError()); - - Tokenizer parser(&s); - - parser.nextToken(); - - bool grayscale; - if (parser.token() == "PF") - { - grayscale = false; - } - else if (parser.token() == "Pf") - { - grayscale = true; - } - else - { - // Invalid file. - return NULL; - } - - parser.nextLine(); - - int width = parser.token().toInt(); parser.nextToken(); - int height = parser.token().toInt(); - - parser.nextLine(); - - float scaleFactor = parser.token().toFloat(); - - if (scaleFactor >= 0) - { - s.setByteOrder(Stream::BigEndian); - } - else - { - s.setByteOrder(Stream::LittleEndian); - } - scaleFactor = fabsf(scaleFactor); - - // Allocate image. - AutoPtr fimage(new FloatImage()); - - if (grayscale) - { - fimage->allocate(1, width, height); - - float * channel = fimage->channel(0); - - for (int i = 0; i < width * height; i++) - { - s << channel[i]; - } - } - else - { - fimage->allocate(3, width, height); - - float * rchannel = fimage->channel(0); - float * gchannel = fimage->channel(1); - float * bchannel = fimage->channel(2); - - for (int i = 0; i < width * height; i++) - { - s << rchannel[i] << gchannel[i] << bchannel[i]; - } - } - - return fimage.release(); -} - -bool nv::ImageIO::saveFloatPFM(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components) -{ - nvCheck(fileName != NULL); - nvCheck(fimage != NULL); - nvCheck(fimage->componentNum() <= base_component + num_components); - nvCheck(num_components == 1 || num_components == 3); - - StdOutputStream stream(fileName); - TextWriter writer(&stream); - - if (num_components == 1) writer.write("Pf\n"); - else /*if (num_components == 3)*/ writer.write("PF\n"); - - int w = fimage->width(); - int h = fimage->height(); - writer.write("%d %d\n", w, h); - writer.write("%f\n", -1.0f); // little endian with 1.0 scale. - - if (num_components == 1) - { - float * channel = const_cast(fimage->channel(0)); - - for (int i = 0; i < w * h; i++) - { - stream << channel[i]; - } - } - else - { - float * rchannel = const_cast(fimage->channel(0)); - float * gchannel = const_cast(fimage->channel(1)); - float * bchannel = const_cast(fimage->channel(2)); - - for (int i = 0; i < w * h; i++) - { - stream << rchannel[i] << gchannel[i] << bchannel[i]; - } - } - - return true; -} - -#endif - -#if 0 - -/** Save PNG*/ -static bool SavePNG(const PiImage * img, const char * name) { - nvCheck( img != NULL ); - nvCheck( img->mem != NULL ); - - if( piStrCmp(piExtension(name), ".png" ) != 0 ) { - return false; - } - - if( img->flags & PI_IT_CUBEMAP ) { - nvDebug("*** Cannot save cubemaps as PNG."); - return false; - } - if( img->flags & PI_IT_DDS ) { - nvDebug("*** Cannot save DDS surface as PNG."); - return false; - } - - nvDebug( "--- Saving '%s'.\n", name ); - - PiAutoPtr ar( PiFileSystem::CreateFileWriter( name ) ); - if( ar == NULL ) { - nvDebug( "*** SavePNG: Error, cannot save file '%s'.\n", name ); - return false; - } - -/* -public class PNGEnc { - - public static function encode(img:BitmapData):ByteArray { - // Create output byte array - var png:ByteArray = new ByteArray(); - // Write PNG signature - png.writeUnsignedInt(0x89504e47); - png.writeUnsignedInt(0x0D0A1A0A); - // Build IHDR chunk - var IHDR:ByteArray = new ByteArray(); - IHDR.writeInt(img.width); - IHDR.writeInt(img.height); - IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA - IHDR.writeByte(0); - writeChunk(png,0x49484452,IHDR); - // Build IDAT chunk - var IDAT:ByteArray= new ByteArray(); - for(var i:int=0;i < img.height;i++) { - // no filter - IDAT.writeByte(0); - var p:uint; - if ( !img.transparent ) { - for(var j:int=0;j < img.width;j++) { - p = img.getPixel(j,i); - IDAT.writeUnsignedInt( - uint(((p&0xFFFFFF) << 8)|0xFF)); - } - } else { - for(var j:int=0;j < img.width;j++) { - p = img.getPixel32(j,i); - IDAT.writeUnsignedInt( - uint(((p&0xFFFFFF) << 8)| - (shr(p,24)))); - } - } - } - IDAT.compress(); - writeChunk(png,0x49444154,IDAT); - // Build IEND chunk - writeChunk(png,0x49454E44,null); - // return PNG - return png; - } - - private static var crcTable:Array; - private static var crcTableComputed:Boolean = false; - - private static function writeChunk(png:ByteArray, - type:uint, data:ByteArray) { - if (!crcTableComputed) { - crcTableComputed = true; - crcTable = []; - for (var n:uint = 0; n < 256; n++) { - var c:uint = n; - for (var k:uint = 0; k < 8; k++) { - if (c & 1) { - c = uint(uint(0xedb88320) ^ - uint(c >>> 1)); - } else { - c = uint(c >>> 1); - } - } - crcTable[n] = c; - } - } - var len:uint = 0; - if (data != null) { - len = data.length; - } - png.writeUnsignedInt(len); - var p:uint = png.position; - png.writeUnsignedInt(type); - if ( data != null ) { - png.writeBytes(data); - } - var e:uint = png.position; - png.position = p; - var c:uint = 0xffffffff; - for (var i:int = 0; i < (e-p); i++) { - c = uint(crcTable[ - (c ^ png.readUnsignedByte()) & - uint(0xff)] ^ uint(c >>> 8)); - } - c = uint(c^uint(0xffffffff)); - png.position = e; - png.writeUnsignedInt(c); - } -} -*/ -} - -#endif // 0 - -#if 0 - - -namespace ImageIO { - - /** Init ImageIO plugins. */ - void InitPlugins() { - // AddInputPlugin( "", LoadANY ); - AddInputPlugin( "tga", LoadTGA ); -#if HAVE_PNG - AddInputPlugin( "png", LoadPNG ); -#endif -#if HAVE_JPEG - AddInputPlugin( "jpg", LoadJPG ); -#endif - AddInputPlugin( "dds", LoadDDS ); - - AddOutputPlugin( "tga", SaveTGA ); - } - - /** Reset ImageIO plugins. */ - void ResetPlugins() { - s_plugin_load_map.Clear(); - s_plugin_save_map.Clear(); - } - - /** Add an input plugin. */ - void AddInputPlugin( const char * ext, ImageInput_Plugin plugin ) { - s_plugin_load_map.Add(ext, plugin); - } - - /** Add an output plugin. */ - void AddOutputPlugin( const char * ext, ImageOutput_Plugin plugin ) { - s_plugin_save_map.Add(ext, plugin); - } - - - bool Load(PiImage * img, const char * name, PiStream & stream) { - - // Get name extension. - const char * extension = piExtension(name); - - // Skip the dot. - if( *extension == '.' ) { - extension++; - } - - // Lookup plugin in the map. - ImageInput_Plugin plugin = NULL; - if( s_plugin_load_map.Get(extension, &plugin) ) { - return plugin(img, stream); - } - - /*foreach(i, s_plugin_load_map) { - nvDebug("%s %s %d\n", s_plugin_load_map[i].key.GetStr(), extension, 0 == strcmp(extension, s_plugin_load_map[i].key)); - } - - nvDebug("No plugin found for '%s' %d.\n", extension, s_plugin_load_map.Size());*/ - - return false; - } - - bool Save(const PiImage * img, const char * name, PiStream & stream) { - - // Get name extension. - const char * extension = piExtension(name); - - // Skip the dot. - if( *extension == '.' ) { - extension++; - } - - // Lookup plugin in the map. - ImageOutput_Plugin plugin = NULL; - if( s_plugin_save_map.Get(extension, &plugin) ) { - return plugin(img, stream); - } - - return false; - } - -} // ImageIO - -#endif // 0 - diff --git a/Externals/NVTT/src/nvimage/ImageIO.h b/Externals/NVTT/src/nvimage/ImageIO.h deleted file mode 100644 index 0902a5d1116..00000000000 --- a/Externals/NVTT/src/nvimage/ImageIO.h +++ /dev/null @@ -1,59 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_IMAGEIO_H -#define NV_IMAGE_IMAGEIO_H - -#include - -namespace nv -{ - class Image; - class FloatImage; - class Stream; - - namespace ImageIO - { - NVIMAGE_API Image * load(const char * fileName); - NVIMAGE_API Image * load(const char * fileName, Stream & s); - - NVIMAGE_API FloatImage * loadFloat(const char * fileName); - NVIMAGE_API FloatImage * loadFloat(const char * fileName, Stream & s); - - NVIMAGE_API bool save(const char * fileName, Stream & s, Image * img); - NVIMAGE_API bool save(const char * fileName, Image * img); - NVIMAGE_API bool saveFloat(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components); - - NVIMAGE_API Image * loadTGA(Stream & s); - NVIMAGE_API bool saveTGA(Stream & s, const Image * img); - - NVIMAGE_API Image * loadPSD(Stream & s); - -#if defined(HAVE_PNG) - NVIMAGE_API Image * loadPNG(Stream & s); -#endif - -#if defined(HAVE_JPEG) - NVIMAGE_API Image * loadJPG(Stream & s); -#endif - -#if defined(HAVE_TIFF) - NVIMAGE_API FloatImage * loadFloatTIFF(const char * fileName, Stream & s); - - NVIMAGE_API bool saveFloatTIFF(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components); -#endif - -#if defined(HAVE_OPENEXR) - NVIMAGE_API FloatImage * loadFloatEXR(const char * fileName, Stream & s); - - NVIMAGE_API bool saveFloatEXR(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components); -#endif - - // NVIMAGE_API FloatImage * loadFloatPFM(const char * fileName, Stream & s); - // NVIMAGE_API bool saveFloatPFM(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components); - - } // ImageIO namespace - -} // nv namespace - - -#endif // NV_IMAGE_IMAGEIO_H diff --git a/Externals/NVTT/src/nvimage/NormalMap.cpp b/Externals/NVTT/src/nvimage/NormalMap.cpp deleted file mode 100644 index 2ece5744452..00000000000 --- a/Externals/NVTT/src/nvimage/NormalMap.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include - -#include - -#include - - -using namespace nv; - -// Create normal map using the given kernels. -static FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, const Kernel2 * kdu, const Kernel2 * kdv) -{ - nvCheck(kdu != NULL); - nvCheck(kdv != NULL); - nvCheck(img != NULL); - - const uint w = img->width(); - const uint h = img->height(); - - AutoPtr fimage(new FloatImage()); - fimage->allocate(4, w, h); - - // Compute height and store in alpha channel: - float * alphaChannel = fimage->channel(3); - for(uint i = 0; i < w*h; i++) - { - Vector4 color = toVector4(img->pixel(i)); - alphaChannel[i] = dot(color, heightWeights); - } - - float heightScale = 1.0f / 16.0f; // @@ Use a user defined factor. - - for(uint y = 0; y < h; y++) - { - for(uint x = 0; x < w; x++) - { - const float du = fimage->applyKernel(kdu, x, y, 3, wm); - const float dv = fimage->applyKernel(kdv, x, y, 3, wm); - - Vector3 n = normalize(Vector3(du, dv, heightScale)); - - fimage->setPixel(0.5f * n.x() + 0.5f, x, y, 0); - fimage->setPixel(0.5f * n.y() + 0.5f, x, y, 1); - fimage->setPixel(0.5f * n.z() + 0.5f, x, y, 2); - } - } - - return fimage.release(); -} - - -/// Create normal map using the given filter. -FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter /*= Sobel3x3*/) -{ - nvCheck(img != NULL); - - // Init the kernels. - Kernel2 * kdu = NULL; - Kernel2 * kdv = NULL; - - switch(filter) - { - case NormalMapFilter_Sobel3x3: - kdu = new Kernel2(3); - break; - case NormalMapFilter_Sobel5x5: - kdu = new Kernel2(5); - break; - case NormalMapFilter_Sobel7x7: - kdu = new Kernel2(7); - break; - case NormalMapFilter_Sobel9x9: - kdu = new Kernel2(9); - break; - default: - nvDebugCheck(false); - }; - - kdu->initSobel(); - kdu->normalize(); - - kdv = new Kernel2(*kdu); - kdv->transpose(); - - return ::createNormalMap(img, wm, heightWeights, kdu, kdv); -} - - -/// Create normal map combining multiple sobel filters. -FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights) -{ - nvCheck(img != NULL); - - Kernel2 * kdu = NULL; - Kernel2 * kdv = NULL; - - kdu = new Kernel2(9); - kdu->initBlendedSobel(filterWeights); - kdu->normalize(); - - kdv = new Kernel2(*kdu); - kdv->transpose(); - - return ::createNormalMap(img, wm, heightWeights, kdu, kdv); -} - -/// Normalize the given image in place. -void nv::normalizeNormalMap(FloatImage * img) -{ - nvCheck(img != NULL); - img->expandNormals(0); - img->normalize(0); - img->packNormals(0); -} - diff --git a/Externals/NVTT/src/nvimage/NormalMap.h b/Externals/NVTT/src/nvimage/NormalMap.h deleted file mode 100644 index 670ead45847..00000000000 --- a/Externals/NVTT/src/nvimage/NormalMap.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_IMAGE_NORMALMAP_H -#define NV_IMAGE_NORMALMAP_H - -#include -#include -#include - - -namespace nv -{ - class Image; - - enum NormalMapFilter - { - NormalMapFilter_Sobel3x3, // fine detail - NormalMapFilter_Sobel5x5, // medium detail - NormalMapFilter_Sobel7x7, // large detail - NormalMapFilter_Sobel9x9, // very large - }; - - FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter = NormalMapFilter_Sobel3x3); - - FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights); - - void normalizeNormalMap(FloatImage * img); - - // @@ Add generation of DU/DV maps. - - -} // nv namespace - -#endif // NV_IMAGE_NORMALMAP_H diff --git a/Externals/NVTT/src/nvimage/NormalMipmap.cpp b/Externals/NVTT/src/nvimage/NormalMipmap.cpp deleted file mode 100644 index 253c6d41acc..00000000000 --- a/Externals/NVTT/src/nvimage/NormalMipmap.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -#include -#include - -#include -#include - -using namespace nv; - -FloatImage * nv::createNormalMipmapMap(const FloatImage * img) -{ - nvDebugCheck(img != NULL); - - uint w = img->width(); - uint h = img->height(); - - uint hw = w / 2; - uint hh = h / 2; - - FloatImage dotImg; - dotImg.allocate(1, w, h); - - FloatImage shImg; - shImg.allocate(9, hw, hh); - - SampleDistribution distribution(256); - const uint sampleCount = distribution.sampleCount(); - - for (uint d = 0; d < sampleCount; d++) - { - const float * xChannel = img->channel(0); - const float * yChannel = img->channel(1); - const float * zChannel = img->channel(2); - - Vector3 dir = distribution.sampleDir(d); - - Sh2 basis; - basis.eval(dir); - - for(uint i = 0; i < w*h; i++) - { - Vector3 normal(xChannel[i], yChannel[i], zChannel[i]); - normal = normalizeSafe(normal, Vector3(zero), 0.0f); - - dotImg.setPixel(dot(dir, normal), d); - } - - // @@ It would be nice to have a fastDownSample that took an existing image as an argument, to avoid allocations. - AutoPtr dotMip(dotImg.fastDownSample()); - - for(uint p = 0; p < hw*hh; p++) - { - float f = dotMip->pixel(p); - - // Project irradiance to sh basis and accumulate. - for (uint i = 0; i < 9; i++) - { - float & sum = shImg.channel(i)[p]; - sum += f * basis.elemAt(i); - } - } - } - - - - FloatImage * normalMipmap = new FloatImage; - normalMipmap->allocate(4, hw, hh); - - // Precompute the clamped cosine radiance transfer. - Sh2 prt; - prt.cosineTransfer(); - - // Allocate outside the loop. - Sh2 sh; - - for(uint p = 0; p < hw*hh; p++) - { - for (uint i = 0; i < 9; i++) - { - sh.elemAt(i) = shImg.channel(i)[p]; - } - - // Convolve sh irradiance by radiance transfer. - sh *= prt; - - // Now sh(0) is the ambient occlusion. - // and sh(1) is the normal direction. - - // Should we use SVD to fit only the normals to the SH? - - } - - return normalMipmap; -} - diff --git a/Externals/NVTT/src/nvimage/NormalMipmap.h b/Externals/NVTT/src/nvimage/NormalMipmap.h deleted file mode 100644 index fc367277e34..00000000000 --- a/Externals/NVTT/src/nvimage/NormalMipmap.h +++ /dev/null @@ -1,17 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_NORMALMIPMAP_H -#define NV_IMAGE_NORMALMIPMAP_H - -#include - - -namespace nv -{ - class FloatImage; - - FloatImage * createNormalMipmapMap(const FloatImage * img); - -} // nv namespace - -#endif // NV_IMAGE_NORMALMIPMAP_H diff --git a/Externals/NVTT/src/nvimage/PixelFormat.h b/Externals/NVTT/src/nvimage/PixelFormat.h deleted file mode 100644 index 0106f3d96b6..00000000000 --- a/Externals/NVTT/src/nvimage/PixelFormat.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_IMAGE_PIXELFORMAT_H -#define NV_IMAGE_PIXELFORMAT_H - -#include - - -namespace nv -{ - namespace PixelFormat - { - - // Convert component @a c having @a inbits to the returned value having @a outbits. - inline uint convert(uint c, uint inbits, uint outbits) - { - if (inbits == 0) - { - return 0; - } - else if (inbits >= outbits) - { - // truncate - return c >> (inbits - outbits); - } - else - { - // bitexpand - return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); - } - } - - // Get pixel component shift and size given its mask. - inline void maskShiftAndSize(uint mask, uint * shift, uint * size) - { - if (!mask) - { - *shift = 0; - *size = 0; - return; - } - - *shift = 0; - while((mask & 1) == 0) { - ++(*shift); - mask >>= 1; - } - - *size = 0; - while((mask & 1) == 1) { - ++(*size); - mask >>= 1; - } - } - - } // PixelFormat namespace - -} // nv namespace - - -#endif // NV_IMAGE_PIXELFORMAT_H diff --git a/Externals/NVTT/src/nvimage/PsdFile.h b/Externals/NVTT/src/nvimage/PsdFile.h deleted file mode 100644 index 41379edd9ca..00000000000 --- a/Externals/NVTT/src/nvimage/PsdFile.h +++ /dev/null @@ -1,70 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_PSDFILE_H -#define NV_IMAGE_PSDFILE_H - -#include - -namespace nv -{ - enum PsdColorMode - { - PsdColorMode_Bitmap = 0, - PsdColorMode_GrayScale = 1, - PsdColorMode_Indexed = 2, - PsdColorMode_RGB = 3, - PsdColorMode_CMYK = 4, - PsdColorMode_MultiChannel = 7, - PsdColorMode_DuoTone = 8, - PsdColorMode_LabColor = 9 - }; - - /// PSD header. - struct PsdHeader - { - uint32 signature; - uint16 version; - uint8 reserved[6]; - uint16 channel_count; - uint32 height; - uint32 width; - uint16 depth; - uint16 color_mode; - - bool isValid() const - { - return signature == 0x38425053; // '8BPS' - } - - bool isSupported() const - { - if (version != 1) { - nvDebug("*** bad version number %u\n", version); - return false; - } - if (channel_count > 4) { - return false; - } - if (depth != 8) { - return false; - } - if (color_mode != PsdColorMode_RGB) { - return false; - } - return true; - } - }; - - - inline Stream & operator<< (Stream & s, PsdHeader & head) - { - s << head.signature << head.version; - for (int i = 0; i < 6; i++) { - s << head.reserved[i]; - } - return s << head.channel_count << head.height << head.width << head.depth << head.color_mode; - } - -} // nv namespace - -#endif // NV_IMAGE_PSDFILE_H diff --git a/Externals/NVTT/src/nvimage/Quantize.cpp b/Externals/NVTT/src/nvimage/Quantize.cpp deleted file mode 100644 index 56812bd4450..00000000000 --- a/Externals/NVTT/src/nvimage/Quantize.cpp +++ /dev/null @@ -1,219 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -/* -http://www.visgraf.impa.br/Courses/ip00/proj/Dithering1/floyd_steinberg_dithering.html -http://www.gamedev.net/reference/articles/article341.asp - -@@ Look at LPS: http://www.cs.rit.edu/~pga/pics2000/i.html - -This is a really nice guide to dithering algorithms: -http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT - -@@ This code needs to be reviewed, I'm not sure it's correct. -*/ - -#include -#include -#include - -#include - -#include // swap - - -using namespace nv; - - -// Simple quantization. -void nv::Quantize::BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ ) -{ - nvCheck(image != NULL); - - const uint w = image->width(); - const uint h = image->height(); - - for(uint y = 0; y < h; y++) { - for(uint x = 0; x < w; x++) { - - Color32 pixel = image->pixel(x, y); - - // Convert color. - if( pixel.a > alpha_threshold ) pixel.a = 255; - else pixel.a = 0; - - // Store color. - image->pixel(x, y) = pixel; - } - } -} - - -// Simple quantization. -void nv::Quantize::RGB16( Image * image ) -{ - Truncate(image, 5, 6, 5, 8); -} - -// Alpha quantization. -void nv::Quantize::Alpha4( Image * image ) -{ - Truncate(image, 8, 8, 8, 4); -} - - -// Error diffusion. Floyd Steinberg. -void nv::Quantize::FloydSteinberg_RGB16( Image * image ) -{ - FloydSteinberg(image, 5, 6, 5, 8); -} - - -// Error diffusion. Floyd Steinberg. -void nv::Quantize::FloydSteinberg_BinaryAlpha( Image * image, int alpha_threshold /*= 127*/ ) -{ - nvCheck(image != NULL); - - const uint w = image->width(); - const uint h = image->height(); - - // @@ Use fixed point? - float * row0 = new float[(w+2)]; - float * row1 = new float[(w+2)]; - memset(row0, 0, sizeof(float)*(w+2)); - memset(row1, 0, sizeof(float)*(w+2)); - - for(uint y = 0; y < h; y++) { - for(uint x = 0; x < w; x++) { - - Color32 pixel = image->pixel(x, y); - - // Add error. - int alpha = int(pixel.a) + int(row0[1+x]); - - // Convert color. - if( alpha > alpha_threshold ) pixel.a = 255; - else pixel.a = 0; - - // Store color. - image->pixel(x, y) = pixel; - - // Compute new error. - float diff = float(alpha - pixel.a); - - // Propagate new error. - row0[1+x+1] += 7.0f / 16.0f * diff; - row1[1+x-1] += 3.0f / 16.0f * diff; - row1[1+x+0] += 5.0f / 16.0f * diff; - row1[1+x+1] += 1.0f / 16.0f * diff; - } - - swap(row0, row1); - memset(row1, 0, sizeof(float)*(w+2)); - } - - delete [] row0; - delete [] row1; -} - - -// Error diffusion. Floyd Steinberg. -void nv::Quantize::FloydSteinberg_Alpha4( Image * image ) -{ - FloydSteinberg(image, 8, 8, 8, 4); -} - - -void nv::Quantize::Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize) -{ - nvCheck(image != NULL); - - const uint w = image->width(); - const uint h = image->height(); - - for(uint y = 0; y < h; y++) { - for(uint x = 0; x < w; x++) { - - Color32 pixel = image->pixel(x, y); - - // Convert to our desired size, and reconstruct. - pixel.r = PixelFormat::convert(pixel.r, 8, rsize); - pixel.r = PixelFormat::convert(pixel.r, rsize, 8); - - pixel.g = PixelFormat::convert(pixel.g, 8, gsize); - pixel.g = PixelFormat::convert(pixel.g, gsize, 8); - - pixel.b = PixelFormat::convert(pixel.b, 8, bsize); - pixel.b = PixelFormat::convert(pixel.b, bsize, 8); - - pixel.a = PixelFormat::convert(pixel.a, 8, asize); - pixel.a = PixelFormat::convert(pixel.a, asize, 8); - - // Store color. - image->pixel(x, y) = pixel; - } - } -} - - -// Error diffusion. Floyd Steinberg. -void nv::Quantize::FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize) -{ - nvCheck(image != NULL); - - const uint w = image->width(); - const uint h = image->height(); - - Vector4 * row0 = new Vector4[w+2]; - Vector4 * row1 = new Vector4[w+2]; - memset(row0, 0, sizeof(Vector4)*(w+2)); - memset(row1, 0, sizeof(Vector4)*(w+2)); - - for (uint y = 0; y < h; y++) { - for (uint x = 0; x < w; x++) { - - Color32 pixel = image->pixel(x, y); - - // Add error. - pixel.r = clamp(int(pixel.r) + int(row0[1+x].x()), 0, 255); - pixel.g = clamp(int(pixel.g) + int(row0[1+x].y()), 0, 255); - pixel.b = clamp(int(pixel.b) + int(row0[1+x].z()), 0, 255); - pixel.a = clamp(int(pixel.a) + int(row0[1+x].w()), 0, 255); - - int r = pixel.r; - int g = pixel.g; - int b = pixel.b; - int a = pixel.a; - - // Convert to our desired size, and reconstruct. - r = PixelFormat::convert(r, 8, rsize); - r = PixelFormat::convert(r, rsize, 8); - - g = PixelFormat::convert(g, 8, gsize); - g = PixelFormat::convert(g, gsize, 8); - - b = PixelFormat::convert(b, 8, bsize); - b = PixelFormat::convert(b, bsize, 8); - - a = PixelFormat::convert(a, 8, asize); - a = PixelFormat::convert(a, asize, 8); - - // Store color. - image->pixel(x, y) = Color32(r, g, b, a); - - // Compute new error. - Vector4 diff(float(int(pixel.r) - r), float(int(pixel.g) - g), float(int(pixel.b) - b), float(int(pixel.a) - a)); - - // Propagate new error. - row0[1+x+1] += 7.0f / 16.0f * diff; - row1[1+x-1] += 3.0f / 16.0f * diff; - row1[1+x+0] += 5.0f / 16.0f * diff; - row1[1+x+1] += 1.0f / 16.0f * diff; - } - - swap(row0, row1); - memset(row1, 0, sizeof(Vector4)*(w+2)); - } - - delete [] row0; - delete [] row1; -} diff --git a/Externals/NVTT/src/nvimage/Quantize.h b/Externals/NVTT/src/nvimage/Quantize.h deleted file mode 100644 index 5b4a9555e86..00000000000 --- a/Externals/NVTT/src/nvimage/Quantize.h +++ /dev/null @@ -1,31 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_QUANTIZE_H -#define NV_IMAGE_QUANTIZE_H - -#include - - -namespace nv -{ - class Image; - - namespace Quantize - { - void RGB16(Image * img); - void BinaryAlpha(Image * img, int alpha_threshold = 127); - void Alpha4(Image * img); - - void FloydSteinberg_RGB16(Image * img); - void FloydSteinberg_BinaryAlpha(Image * img, int alpha_threshold = 127); - void FloydSteinberg_Alpha4(Image * img); - - void Truncate(Image * image, uint rsize, uint gsize, uint bsize, uint asize); - void FloydSteinberg(Image * image, uint rsize, uint gsize, uint bsize, uint asize); - - // @@ Add palette quantization algorithms! - } -} - - -#endif // NV_IMAGE_QUANTIZE_H diff --git a/Externals/NVTT/src/nvimage/TgaFile.h b/Externals/NVTT/src/nvimage/TgaFile.h deleted file mode 100644 index bdbfce5419e..00000000000 --- a/Externals/NVTT/src/nvimage/TgaFile.h +++ /dev/null @@ -1,105 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_TGAFILE_H -#define NV_IMAGE_TGAFILE_H - -#include - -namespace nv -{ - -// TGA types -enum TGAType { - TGA_TYPE_INDEXED = 1, - TGA_TYPE_RGB = 2, - TGA_TYPE_GREY = 3, - TGA_TYPE_RLE_INDEXED = 9, - TGA_TYPE_RLE_RGB = 10, - TGA_TYPE_RLE_GREY = 11 -}; - -#define TGA_INTERLEAVE_MASK 0xc0 -#define TGA_INTERLEAVE_NONE 0x00 -#define TGA_INTERLEAVE_2WAY 0x40 -#define TGA_INTERLEAVE_4WAY 0x80 - -#define TGA_ORIGIN_MASK 0x30 -#define TGA_ORIGIN_LEFT 0x00 -#define TGA_ORIGIN_RIGHT 0x10 -#define TGA_ORIGIN_LOWER 0x00 -#define TGA_ORIGIN_UPPER 0x20 - -#define TGA_HAS_ALPHA 0x0F - - -/// Tga Header. -struct TgaHeader { - uint8 id_length; - uint8 colormap_type; - uint8 image_type; - uint16 colormap_index; - uint16 colormap_length; - uint8 colormap_size; - uint16 x_origin; - uint16 y_origin; - uint16 width; - uint16 height; - uint8 pixel_size; - uint8 flags; - - enum { Size = 18 }; //const static int SIZE = 18; -}; - - -/// Tga File. -struct TgaFile { - - TgaFile() { - mem = NULL; - } - ~TgaFile() { - free(); - } - - uint size() const { - return head.width * head.height * (head.pixel_size / 8); - } - void allocate() { - nvCheck( mem == NULL ); - mem = new uint8[size()]; - } - void free() { - delete [] mem; - mem = NULL; - } - - TgaHeader head; - uint8 * mem; -}; - - -inline Stream & operator<< (Stream & s, TgaHeader & head) -{ - s << head.id_length << head.colormap_type << head.image_type; - s << head.colormap_index << head.colormap_length << head.colormap_size; - s << head.x_origin << head.y_origin << head.width << head.height; - s << head.pixel_size << head.flags; - return s; -} - -inline Stream & operator<< (Stream & s, TgaFile & tga) -{ - s << tga.head; - - if( s.isLoading() ) { - tga.allocate(); - } - - s.serialize( tga.mem, tga.size() ); - - return s; -} - -} // nv namespace - -#endif // NV_IMAGE_TGAFILE_H diff --git a/Externals/NVTT/src/nvimage/nvimage.h b/Externals/NVTT/src/nvimage/nvimage.h deleted file mode 100644 index beb39650a74..00000000000 --- a/Externals/NVTT/src/nvimage/nvimage.h +++ /dev/null @@ -1,22 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_IMAGE_H -#define NV_IMAGE_H - -#include - -// Function linkage -#if NVIMAGE_SHARED -#ifdef NVIMAGE_EXPORTS -#define NVIMAGE_API DLL_EXPORT -#define NVIMAGE_CLASS DLL_EXPORT_CLASS -#else -#define NVIMAGE_API DLL_IMPORT -#define NVIMAGE_CLASS DLL_IMPORT -#endif -#else -#define NVIMAGE_API -#define NVIMAGE_CLASS -#endif - -#endif // NV_IMAGE_H diff --git a/Externals/NVTT/src/nvmath/Basis.cpp b/Externals/NVTT/src/nvmath/Basis.cpp deleted file mode 100644 index 085e25ba902..00000000000 --- a/Externals/NVTT/src/nvmath/Basis.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -using namespace nv; - - -/// Normalize basis vectors. -void Basis::normalize(float epsilon /*= NV_EPSILON*/) -{ - normal = ::normalize(normal, epsilon); - tangent = ::normalize(tangent, epsilon); - bitangent = ::normalize(bitangent, epsilon); -} - - -/// Gram-Schmidt orthogonalization. -/// @note Works only if the vectors are close to orthogonal. -void Basis::orthonormalize(float epsilon /*= NV_EPSILON*/) -{ - // N' = |N| - // T' = |T - (N' dot T) N'| - // B' = |B - (N' dot B) N' - (T' dot B) T'| - - normal = ::normalize(normal, epsilon); - - tangent -= normal * dot(normal, tangent); - tangent = ::normalize(tangent, epsilon); - - bitangent -= normal * dot(normal, bitangent); - bitangent -= tangent * dot(tangent, bitangent); - bitangent = ::normalize(bitangent, epsilon); -} - - -/// Robust orthonormalization. -/// Returns an orthonormal basis even when the original is degenerate. -void Basis::robustOrthonormalize(float epsilon /*= NV_EPSILON*/) -{ - if (length(normal) < epsilon) - { - normal = cross(tangent, bitangent); - - if (length(normal) < epsilon) - { - tangent = Vector3(1, 0, 0); - bitangent = Vector3(0, 1, 0); - normal = Vector3(0, 0, 1); - return; - } - } - normal = ::normalize(normal, epsilon); - - tangent -= normal * dot(normal, tangent); - bitangent -= normal * dot(normal, bitangent); - - if (length(tangent) < epsilon) - { - if (length(bitangent) < epsilon) - { - buildFrameForDirection(normal); - } - else - { - tangent = cross(bitangent, normal); - nvCheck(isNormalized(tangent, epsilon)); - } - } - else - { - tangent = ::normalize(tangent, epsilon); - bitangent -= tangent * dot(tangent, bitangent); - - if (length(bitangent) < epsilon) - { - bitangent = cross(tangent, normal); - nvCheck(isNormalized(bitangent)); - } - else - { - tangent = ::normalize(tangent, epsilon); - } - } - - // Check vector lengths. - nvCheck(isNormalized(normal, epsilon)); - nvCheck(isNormalized(tangent, epsilon)); - nvCheck(isNormalized(bitangent, epsilon)); - - // Check vector angles. - nvCheck(equal(dot(normal, tangent), 0.0f, epsilon)); - nvCheck(equal(dot(normal, bitangent), 0.0f, epsilon)); - nvCheck(equal(dot(tangent, bitangent), 0.0f, epsilon)); - - // Check vector orientation. - const float det = dot(cross(normal, tangent), bitangent); - nvCheck(equal(det, 1.0f, epsilon) || equal(det, -1.0f, epsilon)); -} - - -/// Build an arbitrary frame for the given direction. -void Basis::buildFrameForDirection(Vector3::Arg d) -{ - nvCheck(isNormalized(d)); - normal = d; - - // Choose minimum axis. - if (fabsf(normal.x()) < fabsf(normal.y()) && fabsf(normal.x()) < fabsf(normal.z())) - { - tangent = Vector3(1, 0, 0); - } - else if (fabsf(normal.y()) < fabsf(normal.z())) - { - tangent = Vector3(0, 1, 0); - } - else - { - tangent = Vector3(0, 0, 1); - } - - // Ortogonalize - tangent -= normal * dot(normal, tangent); - tangent = ::normalize(tangent); - - bitangent = cross(normal, tangent); -} - - - -/* -/// Transform by this basis. (From this basis to object space). -Vector3 Basis::transform(Vector3::Arg v) const -{ - Vector3 o = tangent * v.x(); - o += bitangent * v.y(); - o += normal * v.z(); - return o; -} - -/// Transform by the transpose. (From object space to this basis). -Vector3 Basis::transformT(Vector3::Arg v) -{ - return Vector3(dot(tangent, v), dot(bitangent, v), dot(normal, v)); -} - -/// Transform by the inverse. (From object space to this basis). -/// @note Uses Kramer's rule so the inverse is not accurate if the basis is ill-conditioned. -Vector3 Basis::transformI(Vector3::Arg v) const -{ - const float det = determinant(); - nvCheck(!equalf(det, 0.0f)); - - const float idet = 1.0f / det; - - // Rows of the inverse matrix. - Vector3 r0, r1, r2; - r0.x = (bitangent.y() * normal.z() - bitangent.z() * normal.y()) * idet; - r0.y = -(bitangent.x() * normal.z() - bitangent.z() * normal.x()) * idet; - r0.z = (bitangent.x() * normal.y() - bitangent.y() * normal.x()) * idet; - - r1.x = -(tangent.y() * normal.z() - tangent.z() * normal.y()) * idet; - r1.y = (tangent.x() * normal.z() - tangent.z() * normal.x()) * idet; - r1.z = -(tangent.x() * normal.y() - tangent.y() * normal.x()) * idet; - - r2.x = (tangent.y() * bitangent.z() - tangent.z() * bitangent.y()) * idet; - r2.y = -(tangent.x() * bitangent.z() - tangent.z() * bitangent.x()) * idet; - r2.z = (tangent.x() * bitangent.y() - tangent.y() * bitangent.x()) * idet; - - return Vector3(dot(v, r0), dot(v, r1), dot(v, r2)); -} -*/ - - diff --git a/Externals/NVTT/src/nvmath/Basis.h b/Externals/NVTT/src/nvmath/Basis.h deleted file mode 100644 index 7adde577432..00000000000 --- a/Externals/NVTT/src/nvmath/Basis.h +++ /dev/null @@ -1,78 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_BASIS_H -#define NV_MATH_BASIS_H - -#include -#include -#include - -namespace nv -{ - - /// Basis class to compute tangent space basis, ortogonalizations and to - /// transform vectors from one space to another. - struct Basis - { - /// Create a null basis. - Basis() : tangent(0, 0, 0), bitangent(0, 0, 0), normal(0, 0, 0) {} - - /// Create a basis given three vectors. - Basis(Vector3::Arg n, Vector3::Arg t, Vector3::Arg b) : tangent(t), bitangent(b), normal(n) {} - - /// Create a basis with the given tangent vectors and the handness. - Basis(Vector3::Arg n, Vector3::Arg t, float sign) - { - build(n, t, sign); - } - - NVMATH_API void normalize(float epsilon = NV_EPSILON); - NVMATH_API void orthonormalize(float epsilon = NV_EPSILON); - NVMATH_API void robustOrthonormalize(float epsilon = NV_EPSILON); - NVMATH_API void buildFrameForDirection(Vector3::Arg d); - - /// Calculate the determinant [ F G N ] to obtain the handness of the basis. - float handness() const - { - return determinant() > 0.0f ? 1.0f : -1.0f; - } - - /// Build a basis from 2 vectors and a handness flag. - void build(Vector3::Arg n, Vector3::Arg t, float sign) - { - normal = n; - tangent = t; - bitangent = sign * cross(t, n); - } - - /// Compute the determinant of this basis. - float determinant() const - { - return - tangent.x() * bitangent.y() * normal.z() - tangent.z() * bitangent.y() * normal.x() + - tangent.y() * bitangent.z() * normal.x() - tangent.y() * bitangent.x() * normal.z() + - tangent.z() * bitangent.x() * normal.y() - tangent.x() * bitangent.z() * normal.y(); - } - - /* - // Get transform matrix for this basis. - NVMATH_API Matrix matrix() const; - - // Transform by this basis. (From this basis to object space). - NVMATH_API Vector3 transform(Vector3::Arg v) const; - - // Transform by the transpose. (From object space to this basis). - NVMATH_API Vector3 transformT(Vector3::Arg v); - - // Transform by the inverse. (From object space to this basis). - NVMATH_API Vector3 transformI(Vector3::Arg v) const; - */ - - Vector3 tangent; - Vector3 bitangent; - Vector3 normal; - }; - -} // nv namespace - -#endif // NV_MATH_BASIS_H diff --git a/Externals/NVTT/src/nvmath/Box.h b/Externals/NVTT/src/nvmath/Box.h deleted file mode 100644 index 212432d8a2e..00000000000 --- a/Externals/NVTT/src/nvmath/Box.h +++ /dev/null @@ -1,140 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_BOX_H -#define NV_MATH_BOX_H - -#include - -#include // FLT_MAX - -namespace nv -{ - -/// Axis Aligned Bounding Box. -class Box -{ -public: - - /// Default ctor. - Box() { }; - - /// Copy ctor. - Box( const Box & b ) : m_mins(b.m_mins), m_maxs(b.m_maxs) { } - - /// Init ctor. - Box( Vector3::Arg mins, Vector3::Arg maxs ) : m_mins(mins), m_maxs(maxs) { } - - // Cast operators. - operator const float * () const { return reinterpret_cast(this); } - - /// Min corner of the box. - Vector3 mins() const { return m_mins; } - - /// Max corner of the box. - Vector3 maxs() const { return m_maxs; } - - /// Clear the bounds. - void clearBounds() - { - m_mins.set(FLT_MAX, FLT_MAX, FLT_MAX); - m_maxs.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); - } - - /// Build a cube centered on center and with edge = 2*dist - void cube(Vector3::Arg center, float dist) - { - setCenterExtents(center, Vector3(dist, dist, dist)); - } - - /// Build a box, given center and extents. - void setCenterExtents(Vector3::Arg center, Vector3::Arg extents) - { - m_mins = center - extents; - m_maxs = center + extents; - } - - /// Get box center. - Vector3 center() const - { - return (m_mins + m_maxs) * 0.5f; - } - - /// Return extents of the box. - Vector3 extents() const - { - return (m_maxs - m_mins) * 0.5f; - } - - /// Return extents of the box. - scalar extents(uint axis) const - { - nvDebugCheck(axis < 3); - if (axis == 0) return (m_maxs.x() - m_mins.x()) * 0.5f; - if (axis == 1) return (m_maxs.y() - m_mins.y()) * 0.5f; - if (axis == 2) return (m_maxs.z() - m_mins.z()) * 0.5f; - nvAssume(false); - return 0.0f; - } - - /// Add a point to this box. - void addPointToBounds(Vector3::Arg p) - { - m_mins = min(m_mins, p); - m_maxs = max(m_maxs, p); - } - - /// Add a box to this box. - void addBoxToBounds(const Box & b) - { - m_mins = min(m_mins, b.m_mins); - m_maxs = max(m_maxs, b.m_maxs); - } - - /// Translate box. - void translate(Vector3::Arg v) - { - m_mins += v; - m_maxs += v; - } - - /// Scale the box. - void scale(float s) - { - m_mins *= s; - m_maxs *= s; - } - - /// Get the area of the box. - float area() const - { - const Vector3 d = extents(); - return 8.0f * (d.x()*d.y() + d.x()*d.z() + d.y()*d.z()); - } - - /// Get the volume of the box. - float volume() const - { - Vector3 d = extents(); - return 8.0f * (d.x() * d.y() * d.z()); - } - - /// Return true if the box contains the given point. - bool contains(Vector3::Arg p) const - { - return - m_mins.x() < p.x() && m_mins.y() < p.y() && m_mins.z() < p.z() && - m_maxs.x() > p.x() && m_maxs.y() > p.y() && m_maxs.z() > p.z(); - } - -private: - - Vector3 m_mins; - Vector3 m_maxs; -}; - - - -} // nv namespace - - -#endif // NV_MATH_BOX_H diff --git a/Externals/NVTT/src/nvmath/CMakeLists.txt b/Externals/NVTT/src/nvmath/CMakeLists.txt deleted file mode 100644 index 36f7341aa80..00000000000 --- a/Externals/NVTT/src/nvmath/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -option(NVMATH_SHARED "Build nvmath as shared library" OFF) - -if (NVMATH_SHARED) - add_library(nvmath SHARED) - - target_compile_definitions(nvmath - PRIVATE - NVCORE_SHARED - ) -else() - add_library(nvmath STATIC) -endif() - -target_sources(nvmath PRIVATE - nvmath.h - Vector.h - Matrix.h - Quaternion.h - Box.h - Color.h - Montecarlo.h - Montecarlo.cpp - Random.h - Random.cpp - SphericalHarmonic.h - SphericalHarmonic.cpp - Basis.h - Basis.cpp - Triangle.h - Triangle.cpp - TriBox.cpp -) - -target_link_libraries(nvmath - PUBLIC - nvcore -) - -target_compile_definitions(nvmath - PRIVATE - NVCORE_EXPORTS -) - -install(TARGETS nvmath LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/Externals/NVTT/src/nvmath/Color.h b/Externals/NVTT/src/nvmath/Color.h deleted file mode 100644 index b6d548b6afb..00000000000 --- a/Externals/NVTT/src/nvmath/Color.h +++ /dev/null @@ -1,179 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_COLOR_H -#define NV_MATH_COLOR_H - -#include -#include - -namespace nv -{ - -/// 64 bit color stored as BGRA. -class NVMATH_CLASS Color64 -{ -public: - Color64() { } - Color64(const Color64 & c) : u(c.u) { } - Color64(uint16 R, uint16 G, uint16 B, uint16 A) { setRGBA(R, G, B, A); } - explicit Color64(uint64 U) : u(U) { } - - void setRGBA(uint16 R, uint16 G, uint16 B, uint16 A) - { - r = R; - g = G; - b = B; - a = A; - } - - operator uint64 () const { - return u; - } - - union { - struct { -#if NV_LITTLE_ENDIAN - uint16 r, a, b, g; -#else - uint16 a: 16; - uint16 r: 16; - uint16 g: 16; - uint16 b: 16; -#endif - }; - uint64 u; - }; -}; - -/// 32 bit color stored as BGRA. -class NVMATH_CLASS Color32 -{ -public: - Color32() { } - Color32(const Color32 & c) : u(c.u) { } - Color32(uint8 R, uint8 G, uint8 B) { setRGBA(R, G, B, 0xFF); } - Color32(uint8 R, uint8 G, uint8 B, uint8 A) { setRGBA( R, G, B, A); } - //Color32(uint8 c[4]) { setRGBA(c[0], c[1], c[2], c[3]); } - //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); } - //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); } - explicit Color32(uint32 U) : u(U) { } - - void setRGBA(uint8 R, uint8 G, uint8 B, uint8 A) - { - r = R; - g = G; - b = B; - a = A; - } - - void setBGRA(uint8 B, uint8 G, uint8 R, uint8 A = 0xFF) - { - r = R; - g = G; - b = B; - a = A; - } - - operator uint32 () const { - return u; - } - - union { - struct { -#if NV_LITTLE_ENDIAN - uint8 b, g, r, a; -#else - uint8 a: 8; - uint8 r: 8; - uint8 g: 8; - uint8 b: 8; -#endif - }; - uint32 u; - }; -}; - - -/// 16 bit 565 BGR color. -class NVMATH_CLASS Color16 -{ -public: - Color16() { } - Color16(const Color16 & c) : u(c.u) { } - explicit Color16(uint16 U) : u(U) { } - - union { - struct { -#if NV_LITTLE_ENDIAN - uint16 b : 5; - uint16 g : 6; - uint16 r : 5; -#else - uint16 r : 5; - uint16 g : 6; - uint16 b : 5; -#endif - }; - uint16 u; - }; -}; - - -/// Clamp color components. -inline Vector3 colorClamp(Vector3::Arg c) -{ - return Vector3(clamp(c.x(), 0.0f, 1.0f), clamp(c.y(), 0.0f, 1.0f), clamp(c.z(), 0.0f, 1.0f)); -} - -/// Clamp without allowing the hue to change. -inline Vector3 colorNormalize(Vector3::Arg c) -{ - float scale = 1.0f; - if (c.x() > scale) scale = c.x(); - if (c.y() > scale) scale = c.y(); - if (c.z() > scale) scale = c.z(); - return c / scale; -} - -/// Convert Color32 to Color16. -inline Color16 toColor16(Color32 c) -{ - Color16 color; - // rrrrrggggggbbbbb - // rrrrr000gggggg00bbbbb000 -// color.u = (c.u >> 3) & 0x1F; -// color.u |= (c.u >> 5) & 0x7E0; -// color.u |= (c.u >> 8) & 0xF800; - - color.r = c.r >> 3; - color.g = c.g >> 2; - color.b = c.b >> 3; - return color; -} - - -/// Promote 16 bit color to 32 bit using regular bit expansion. -inline Color32 toColor32(Color16 c) -{ - Color32 color; -// c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); -// c.u |= (c.u >> 5) & 0x070007; -// c.u |= (c.u >> 6) & 0x000300; - - color.b = (c.b << 3) | (c.b >> 2); - color.g = (c.g << 2) | (c.g >> 4); - color.r = (c.r << 3) | (c.r >> 2); - color.a = 0xFF; - - return color; -} - -inline Vector4 toVector4(Color32 c) -{ - const float scale = 1.0f / 255.0f; - return Vector4(c.r * scale, c.g * scale, c.b * scale, c.a * scale); -} - -} // nv namespace - -#endif // NV_MATH_COLOR_H diff --git a/Externals/NVTT/src/nvmath/Matrix.h b/Externals/NVTT/src/nvmath/Matrix.h deleted file mode 100644 index 28749baefb8..00000000000 --- a/Externals/NVTT/src/nvmath/Matrix.h +++ /dev/null @@ -1,1000 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_MATRIX_H -#define NV_MATH_MATRIX_H - -#include -#include - -namespace nv -{ - -// @@ Use scalar defined in Vector.h, but should use a template instead. - -/// 4x4 transformation matrix. -/// -# Matrices are stored in memory in column major order. -/// -# Points are to be though of as column vectors. -/// -# Transformation of a point p by a matrix M is: p' = M * p -class NVMATH_CLASS Matrix -{ -public: - typedef Matrix const & Arg; - - Matrix(); - Matrix(zero_t); - Matrix(identity_t); - Matrix(const Matrix & m); - - scalar data(uint idx) const; - scalar & data(uint idx); - scalar get(uint row, uint col) const; - scalar operator()(uint row, uint col) const; - scalar & operator()(uint row, uint col); - const scalar * ptr() const; - - Vector4 row(uint i) const; - Vector4 column(uint i) const; - - void scale(scalar s); - void scale(Vector3::Arg s); - void translate(Vector3::Arg t); - void rotate(scalar theta, scalar v0, scalar v1, scalar v2); - scalar determinant() const; - - void apply(Matrix::Arg m); - -private: - scalar m_data[16]; -}; - - -inline Matrix::Matrix() -{ -} - -inline Matrix::Matrix(zero_t) -{ - for(int i = 0; i < 16; i++) { - m_data[i] = 0.0f; - } -} - -inline Matrix::Matrix(identity_t) -{ - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 4; j++) { - m_data[4*j+i] = (i == j) ? 1.0f : 0.0f; - } - } -} - -inline Matrix::Matrix(const Matrix & m) -{ - for(int i = 0; i < 16; i++) { - m_data[i] = m.m_data[i]; - } -} - - -// Accessors -inline scalar Matrix::data(uint idx) const -{ - nvDebugCheck(idx < 16); - return m_data[idx]; -} -inline scalar & Matrix::data(uint idx) -{ - nvDebugCheck(idx < 16); - return m_data[idx]; -} -inline scalar Matrix::get(uint row, uint col) const -{ - nvDebugCheck(row < 4 && col < 4); - return m_data[col * 4 + row]; -} -inline scalar Matrix::operator()(uint row, uint col) const -{ - nvDebugCheck(row < 4 && col < 4); - return m_data[col * 4 + row]; -} -inline scalar & Matrix::operator()(uint row, uint col) -{ - nvDebugCheck(row < 4 && col < 4); - return m_data[col * 4 + row]; -} - -inline const scalar * Matrix::ptr() const -{ - return m_data; -} - -inline Vector4 Matrix::row(uint i) const -{ - nvDebugCheck(i < 4); - return Vector4(get(i, 0), get(i, 1), get(i, 2), get(i, 3)); -} - -inline Vector4 Matrix::column(uint i) const -{ - nvDebugCheck(i < 4); - return Vector4(get(0, i), get(1, i), get(2, i), get(3, i)); -} - -/// Apply scale. -inline void Matrix::scale(scalar s) -{ - m_data[0] *= s; m_data[1] *= s; m_data[2] *= s; m_data[3] *= s; - m_data[4] *= s; m_data[5] *= s; m_data[6] *= s; m_data[7] *= s; - m_data[8] *= s; m_data[9] *= s; m_data[10] *= s; m_data[11] *= s; - m_data[12] *= s; m_data[13] *= s; m_data[14] *= s; m_data[15] *= s; -} - -/// Apply scale. -inline void Matrix::scale(Vector3::Arg s) -{ - m_data[0] *= s.x(); m_data[1] *= s.x(); m_data[2] *= s.x(); m_data[3] *= s.x(); - m_data[4] *= s.y(); m_data[5] *= s.y(); m_data[6] *= s.y(); m_data[7] *= s.y(); - m_data[8] *= s.z(); m_data[9] *= s.z(); m_data[10] *= s.z(); m_data[11] *= s.z(); -} - -/// Apply translation. -inline void Matrix::translate(Vector3::Arg t) -{ - m_data[12] = m_data[0] * t.x() + m_data[4] * t.y() + m_data[8] * t.z() + m_data[12]; - m_data[13] = m_data[1] * t.x() + m_data[5] * t.y() + m_data[9] * t.z() + m_data[13]; - m_data[14] = m_data[2] * t.x() + m_data[6] * t.y() + m_data[10] * t.z() + m_data[14]; - m_data[15] = m_data[3] * t.x() + m_data[7] * t.y() + m_data[11] * t.z() + m_data[15]; -} - -Matrix rotation(scalar theta, scalar v0, scalar v1, scalar v2); - -/// Apply rotation. -inline void Matrix::rotate(scalar theta, scalar v0, scalar v1, scalar v2) -{ - Matrix R(rotation(theta, v0, v1, v2)); - apply(R); -} - -/// Apply transform. -inline void Matrix::apply(Matrix::Arg m) -{ - nvDebugCheck(this != &m); - - for(int i = 0; i < 4; i++) { - const scalar ai0 = get(i,0), ai1 = get(i,1), ai2 = get(i,2), ai3 = get(i,3); - m_data[0 + i] = ai0 * m(0,0) + ai1 * m(1,0) + ai2 * m(2,0) + ai3 * m(3,0); - m_data[4 + i] = ai0 * m(0,1) + ai1 * m(1,1) + ai2 * m(2,1) + ai3 * m(3,1); - m_data[8 + i] = ai0 * m(0,2) + ai1 * m(1,2) + ai2 * m(2,2) + ai3 * m(3,2); - m_data[12+ i] = ai0 * m(0,3) + ai1 * m(1,3) + ai2 * m(2,3) + ai3 * m(3,3); - } -} - -/// Get scale matrix. -inline Matrix scale(Vector3::Arg s) -{ - Matrix m(identity); - m(0,0) = s.x(); - m(1,1) = s.y(); - m(2,2) = s.z(); - return m; -} - -/// Get scale matrix. -inline Matrix scale(scalar s) -{ - Matrix m(identity); - m(0,0) = m(1,1) = m(2,2) = s; - return m; -} - -/// Get translation matrix. -inline Matrix translation(Vector3::Arg t) -{ - Matrix m(identity); - m(0,3) = t.x(); - m(1,3) = t.y(); - m(2,3) = t.z(); - return m; -} - -/// Get rotation matrix. -inline Matrix rotation(scalar theta, scalar v0, scalar v1, scalar v2) -{ - scalar cost = cosf(theta); - scalar sint = sinf(theta); - - Matrix m(identity); - - if( 1 == v0 && 0 == v1 && 0 == v2 ) { - m(1,1) = cost; m(2,1) = -sint; - m(1,2) = sint; m(2,2) = cost; - } - else if( 0 == v0 && 1 == v1 && 0 == v2 ) { - m(0,0) = cost; m(2,0) = sint; - m(1,2) = -sint; m(2,2) = cost; - } - else if( 0 == v0 && 0 == v1 && 1 == v2 ) { - m(0,0) = cost; m(1,0) = -sint; - m(0,1) = sint; m(1,1) = cost; - } - else { - scalar a2, b2, c2; - a2 = v0 * v0; - b2 = v1 * v1; - c2 = v2 * v2; - - scalar iscale = 1.0f / sqrtf(a2 + b2 + c2); - v0 *= iscale; - v1 *= iscale; - v2 *= iscale; - - scalar abm, acm, bcm; - scalar mcos, asin, bsin, csin; - mcos = 1.0f - cost; - abm = v0 * v1 * mcos; - acm = v0 * v2 * mcos; - bcm = v1 * v2 * mcos; - asin = v0 * sint; - bsin = v1 * sint; - csin = v2 * sint; - m(0,0) = a2 * mcos + cost; - m(1,0) = abm - csin; - m(2,0) = acm + bsin; - m(3,0) = abm + csin; - m(1,1) = b2 * mcos + cost; - m(2,1) = bcm - asin; - m(3,1) = acm - bsin; - m(1,2) = bcm + asin; - m(2,2) = c2 * mcos + cost; - } - return m; -} - -//Matrix rotation(scalar yaw, scalar pitch, scalar roll); -//Matrix skew(scalar angle, Vector3::Arg v1, Vector3::Arg v2); - -/// Get frustum matrix. -inline Matrix frustum(scalar xmin, scalar xmax, scalar ymin, scalar ymax, scalar zNear, scalar zFar) -{ - Matrix m(zero); - - scalar doubleznear = 2.0f * zNear; - scalar one_deltax = 1.0f / (xmax - xmin); - scalar one_deltay = 1.0f / (ymax - ymin); - scalar one_deltaz = 1.0f / (zFar - zNear); - - m(0,0) = doubleznear * one_deltax; - m(1,1) = doubleznear * one_deltay; - m(0,2) = (xmax + xmin) * one_deltax; - m(1,2) = (ymax + ymin) * one_deltay; - m(2,2) = -(zFar + zNear) * one_deltaz; - m(3,2) = -1.0f; - m(2,3) = -(zFar * doubleznear) * one_deltaz; - - return m; -} - -/// Get infinite frustum matrix. -inline Matrix frustum(scalar xmin, scalar xmax, scalar ymin, scalar ymax, scalar zNear) -{ - Matrix m(zero); - - scalar doubleznear = 2.0f * zNear; - scalar one_deltax = 1.0f / (xmax - xmin); - scalar one_deltay = 1.0f / (ymax - ymin); - scalar nudge = 1.0; // 0.999; - - m(0,0) = doubleznear * one_deltax; - m(1,1) = doubleznear * one_deltay; - m(0,2) = (xmax + xmin) * one_deltax; - m(1,2) = (ymax + ymin) * one_deltay; - m(2,2) = -1.0f * nudge; - m(3,2) = -1.0f; - m(2,3) = -doubleznear * nudge; - - return m; -} - -/// Get perspective matrix. -inline Matrix perspective(scalar fovy, scalar aspect, scalar zNear, scalar zFar) -{ - scalar xmax = zNear * tan(fovy / 2); - scalar xmin = -xmax; - - scalar ymax = xmax / aspect; - scalar ymin = -ymax; - - return frustum(xmin, xmax, ymin, ymax, zNear, zFar); -} - -/// Get infinite perspective matrix. -inline Matrix perspective(scalar fovy, scalar aspect, scalar zNear) -{ - scalar x = zNear * tan(fovy / 2); - scalar y = x / aspect; - return frustum( -x, x, -y, y, zNear ); -} - -/// Get matrix determinant. -inline scalar Matrix::determinant() const -{ - return - m_data[3] * m_data[6] * m_data[ 9] * m_data[12] - m_data[2] * m_data[7] * m_data[ 9] * m_data[12] - m_data[3] * m_data[5] * m_data[10] * m_data[12] + m_data[1] * m_data[7] * m_data[10] * m_data[12] + - m_data[2] * m_data[5] * m_data[11] * m_data[12] - m_data[1] * m_data[6] * m_data[11] * m_data[12] - m_data[3] * m_data[6] * m_data[ 8] * m_data[13] + m_data[2] * m_data[7] * m_data[ 8] * m_data[13] + - m_data[3] * m_data[4] * m_data[10] * m_data[13] - m_data[0] * m_data[7] * m_data[10] * m_data[13] - m_data[2] * m_data[4] * m_data[11] * m_data[13] + m_data[0] * m_data[6] * m_data[11] * m_data[13] + - m_data[3] * m_data[5] * m_data[ 8] * m_data[14] - m_data[1] * m_data[7] * m_data[ 8] * m_data[14] - m_data[3] * m_data[4] * m_data[ 9] * m_data[14] + m_data[0] * m_data[7] * m_data[ 9] * m_data[14] + - m_data[1] * m_data[4] * m_data[11] * m_data[14] - m_data[0] * m_data[5] * m_data[11] * m_data[14] - m_data[2] * m_data[5] * m_data[ 8] * m_data[15] + m_data[1] * m_data[6] * m_data[ 8] * m_data[15] + - m_data[2] * m_data[4] * m_data[ 9] * m_data[15] - m_data[0] * m_data[6] * m_data[ 9] * m_data[15] - m_data[1] * m_data[4] * m_data[10] * m_data[15] + m_data[0] * m_data[5] * m_data[10] * m_data[15]; -} - -inline Matrix transpose(Matrix::Arg m) -{ - Matrix r; - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - r(i, j) = m(j, i); - } - } - return r; -} - -inline Matrix inverse(Matrix::Arg m) -{ - Matrix r; - r.data( 0) = m.data(6)*m.data(11)*m.data(13) - m.data(7)*m.data(10)*m.data(13) + m.data(7)*m.data(9)*m.data(14) - m.data(5)*m.data(11)*m.data(14) - m.data(6)*m.data(9)*m.data(15) + m.data(5)*m.data(10)*m.data(15); - r.data( 1) = m.data(3)*m.data(10)*m.data(13) - m.data(2)*m.data(11)*m.data(13) - m.data(3)*m.data(9)*m.data(14) + m.data(1)*m.data(11)*m.data(14) + m.data(2)*m.data(9)*m.data(15) - m.data(1)*m.data(10)*m.data(15); - r.data( 2) = m.data(2)*m.data( 7)*m.data(13) - m.data(3)*m.data( 6)*m.data(13) + m.data(3)*m.data(5)*m.data(14) - m.data(1)*m.data( 7)*m.data(14) - m.data(2)*m.data(5)*m.data(15) + m.data(1)*m.data( 6)*m.data(15); - r.data( 3) = m.data(3)*m.data( 6)*m.data( 9) - m.data(2)*m.data( 7)*m.data( 9) - m.data(3)*m.data(5)*m.data(10) + m.data(1)*m.data( 7)*m.data(10) + m.data(2)*m.data(5)*m.data(11) - m.data(1)*m.data( 6)*m.data(11); - r.data( 4) = m.data(7)*m.data(10)*m.data(12) - m.data(6)*m.data(11)*m.data(12) - m.data(7)*m.data(8)*m.data(14) + m.data(4)*m.data(11)*m.data(14) + m.data(6)*m.data(8)*m.data(15) - m.data(4)*m.data(10)*m.data(15); - r.data( 5) = m.data(2)*m.data(11)*m.data(12) - m.data(3)*m.data(10)*m.data(12) + m.data(3)*m.data(8)*m.data(14) - m.data(0)*m.data(11)*m.data(14) - m.data(2)*m.data(8)*m.data(15) + m.data(0)*m.data(10)*m.data(15); - r.data( 6) = m.data(3)*m.data( 6)*m.data(12) - m.data(2)*m.data( 7)*m.data(12) - m.data(3)*m.data(4)*m.data(14) + m.data(0)*m.data( 7)*m.data(14) + m.data(2)*m.data(4)*m.data(15) - m.data(0)*m.data( 6)*m.data(15); - r.data( 7) = m.data(2)*m.data( 7)*m.data( 8) - m.data(3)*m.data( 6)*m.data( 8) + m.data(3)*m.data(4)*m.data(10) - m.data(0)*m.data( 7)*m.data(10) - m.data(2)*m.data(4)*m.data(11) + m.data(0)*m.data( 6)*m.data(11); - r.data( 8) = m.data(5)*m.data(11)*m.data(12) - m.data(7)*m.data( 9)*m.data(12) + m.data(7)*m.data(8)*m.data(13) - m.data(4)*m.data(11)*m.data(13) - m.data(5)*m.data(8)*m.data(15) + m.data(4)*m.data( 9)*m.data(15); - r.data( 9) = m.data(3)*m.data( 9)*m.data(12) - m.data(1)*m.data(11)*m.data(12) - m.data(3)*m.data(8)*m.data(13) + m.data(0)*m.data(11)*m.data(13) + m.data(1)*m.data(8)*m.data(15) - m.data(0)*m.data( 9)*m.data(15); - r.data(10) = m.data(1)*m.data( 7)*m.data(12) - m.data(3)*m.data( 5)*m.data(12) + m.data(3)*m.data(4)*m.data(13) - m.data(0)*m.data( 7)*m.data(13) - m.data(1)*m.data(4)*m.data(15) + m.data(0)*m.data( 5)*m.data(15); - r.data(11) = m.data(3)*m.data( 5)*m.data( 8) - m.data(1)*m.data( 7)*m.data( 8) - m.data(3)*m.data(4)*m.data( 9) + m.data(0)*m.data( 7)*m.data( 9) + m.data(1)*m.data(4)*m.data(11) - m.data(0)*m.data( 5)*m.data(11); - r.data(12) = m.data(6)*m.data( 9)*m.data(12) - m.data(5)*m.data(10)*m.data(12) - m.data(6)*m.data(8)*m.data(13) + m.data(4)*m.data(10)*m.data(13) + m.data(5)*m.data(8)*m.data(14) - m.data(4)*m.data( 9)*m.data(14); - r.data(13) = m.data(1)*m.data(10)*m.data(12) - m.data(2)*m.data( 9)*m.data(12) + m.data(2)*m.data(8)*m.data(13) - m.data(0)*m.data(10)*m.data(13) - m.data(1)*m.data(8)*m.data(14) + m.data(0)*m.data( 9)*m.data(14); - r.data(14) = m.data(2)*m.data( 5)*m.data(12) - m.data(1)*m.data( 6)*m.data(12) - m.data(2)*m.data(4)*m.data(13) + m.data(0)*m.data( 6)*m.data(13) + m.data(1)*m.data(4)*m.data(14) - m.data(0)*m.data( 5)*m.data(14); - r.data(15) = m.data(1)*m.data( 6)*m.data( 8) - m.data(2)*m.data( 5)*m.data( 8) + m.data(2)*m.data(4)*m.data( 9) - m.data(0)*m.data( 6)*m.data( 9) - m.data(1)*m.data(4)*m.data(10) + m.data(0)*m.data( 5)*m.data(10); - r.scale(1.0f / m.determinant()); - return r; -} - -inline Matrix isometryInverse(Matrix::Arg m) -{ - Matrix r(identity); - - // transposed 3x3 upper left matrix - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 3; j++) - { - r(i, j) = m(j, i); - } - } - - // translate by the negative offsets - r.translate(-Vector3(m.data(12), m.data(13), m.data(14))); - - return r; -} - -//Matrix affineInverse(Matrix::Arg m); - -/// Transform the given 3d point with the given matrix. -inline Vector3 transformPoint(Matrix::Arg m, Vector3::Arg p) -{ - return Vector3( - p.x() * m(0,0) + p.y() * m(0,1) + p.z() * m(0,2) + m(0,3), - p.x() * m(1,0) + p.y() * m(1,1) + p.z() * m(1,2) + m(1,3), - p.x() * m(2,0) + p.y() * m(2,1) + p.z() * m(2,2) + m(2,3)); -} - -/// Transform the given 3d vector with the given matrix. -inline Vector3 transformVector(Matrix::Arg m, Vector3::Arg p) -{ - return Vector3( - p.x() * m(0,0) + p.y() * m(0,1) + p.z() * m(0,2), - p.x() * m(1,0) + p.y() * m(1,1) + p.z() * m(1,2), - p.x() * m(2,0) + p.y() * m(2,1) + p.z() * m(2,2)); -} - -/// Transform the given 4d vector with the given matrix. -inline Vector4 transform(Matrix::Arg m, Vector4::Arg p) -{ - return Vector4( - p.x() * m(0,0) + p.y() * m(0,1) + p.z() * m(0,2) + p.w() * m(0,3), - p.x() * m(1,0) + p.y() * m(1,1) + p.z() * m(1,2) + p.w() * m(1,3), - p.x() * m(2,0) + p.y() * m(2,1) + p.z() * m(2,2) + p.w() * m(2,3), - p.x() * m(3,0) + p.y() * m(3,1) + p.z() * m(3,2) + p.w() * m(3,3)); -} - -inline Matrix mul(Matrix::Arg a, Matrix::Arg b) -{ - // @@ Is this the right order? mul(a, b) = b * a - Matrix m = a; - m.apply(b); - return m; -} - -} // nv namespace - - - - -#if 0 - /** @name Special matrices. */ - //@{ - /** Generate a translation matrix. */ - void TranslationMatrix(const Vec3 & v) { - data[0] = 1; data[1] = 0; data[2] = 0; data[3] = 0; - data[4] = 0; data[5] = 1; data[6] = 0; data[7] = 0; - data[8] = 0; data[9] = 0; data[10] = 1; data[11] = 0; - data[12] = v.x; data[13] = v.y; data[14] = v.z; data[15] = 1; - } - - /** Rotate theta degrees around v. */ - void RotationMatrix( scalar theta, scalar v0, scalar v1, scalar v2 ) { - scalar cost = cos(theta); - scalar sint = sin(theta); - - if( 1 == v0 && 0 == v1 && 0 == v2 ) { - data[0] = 1.0f; data[1] = 0.0f; data[2] = 0.0f; data[3] = 0.0f; - data[4] = 0.0f; data[5] = cost; data[6] = -sint;data[7] = 0.0f; - data[8] = 0.0f; data[9] = sint; data[10] = cost;data[11] = 0.0f; - data[12] = 0.0f;data[13] = 0.0f;data[14] = 0.0f;data[15] = 1.0f; - } - else if( 0 == v0 && 1 == v1 && 0 == v2 ) { - data[0] = cost; data[1] = 0.0f; data[2] = sint; data[3] = 0.0f; - data[4] = 0.0f; data[5] = 1.0f; data[6] = 0.0f; data[7] = 0.0f; - data[8] = -sint;data[9] = 0.0f;data[10] = cost; data[11] = 0.0f; - data[12] = 0.0f;data[13] = 0.0f;data[14] = 0.0f;data[15] = 1.0f; - } - else if( 0 == v0 && 0 == v1 && 1 == v2 ) { - data[0] = cost; data[1] = -sint;data[2] = 0.0f; data[3] = 0.0f; - data[4] = sint; data[5] = cost; data[6] = 0.0f; data[7] = 0.0f; - data[8] = 0.0f; data[9] = 0.0f; data[10] = 1.0f;data[11] = 0.0f; - data[12] = 0.0f;data[13] = 0.0f;data[14] = 0.0f;data[15] = 1.0f; - } - else { - //we need scale a,b,c to unit length. - scalar a2, b2, c2; - a2 = v0 * v0; - b2 = v1 * v1; - c2 = v2 * v2; - - scalar iscale = 1.0f / sqrtf(a2 + b2 + c2); - v0 *= iscale; - v1 *= iscale; - v2 *= iscale; - - scalar abm, acm, bcm; - scalar mcos, asin, bsin, csin; - mcos = 1.0f - cost; - abm = v0 * v1 * mcos; - acm = v0 * v2 * mcos; - bcm = v1 * v2 * mcos; - asin = v0 * sint; - bsin = v1 * sint; - csin = v2 * sint; - data[0] = a2 * mcos + cost; - data[1] = abm - csin; - data[2] = acm + bsin; - data[3] = abm + csin; - data[4] = 0.0f; - data[5] = b2 * mcos + cost; - data[6] = bcm - asin; - data[7] = acm - bsin; - data[8] = 0.0f; - data[9] = bcm + asin; - data[10] = c2 * mcos + cost; - data[11] = 0.0f; - data[12] = 0.0f; - data[13] = 0.0f; - data[14] = 0.0f; - data[15] = 1.0f; - } - } - - /* - void SkewMatrix(scalar angle, const Vec3 & v1, const Vec3 & v2) { - v1.Normalize(); - v2.Normalize(); - - Vec3 v3; - v3.Cross(v1, v2); - v3.Normalize(); - - // Get skew factor. - scalar costheta = Vec3DotProduct(v1, v2); - scalar sintheta = Real.Sqrt(1 - costheta * costheta); - scalar skew = tan(Trig.DegreesToRadians(angle) + acos(sintheta)) * sintheta - costheta; - - // Build orthonormal matrix. - v1 = FXVector3.Cross(v3, v2); - v1.Normalize(); - - Matrix R = Matrix::Identity; - R[0, 0] = v3.X;// Not sure this is in the correct order... - R[1, 0] = v3.Y; - R[2, 0] = v3.Z; - R[0, 1] = v1.X; - R[1, 1] = v1.Y; - R[2, 1] = v1.Z; - R[0, 2] = v2.X; - R[1, 2] = v2.Y; - R[2, 2] = v2.Z; - - // Build skew matrix. - Matrix S = Matrix::Identity; - S[2, 1] = -skew; - - // Return skew transform. - return R * S * R.Transpose; // Not sure this is in the correct order... - } - */ - - /** - * Generate rotation matrix for the euler angles. This is the same as computing - * 3 rotation matrices and multiplying them together in our custom order. - * - * @todo Have to recompute this code for our new convention. - **/ - void RotationMatrix( scalar yaw, scalar pitch, scalar roll ) { - scalar sy = sin(yaw+ToRadian(90)); - scalar cy = cos(yaw+ToRadian(90)); - scalar sp = sin(pitch-ToRadian(90)); - scalar cp = cos(pitch-ToRadian(90)); - scalar sr = sin(roll); - scalar cr = cos(roll); - - data[0] = cr*cy + sr*sp*sy; - data[1] = cp*sy; - data[2] = -sr*cy + cr*sp*sy; - data[3] = 0; - - data[4] = -cr*sy + sr*sp*cy; - data[5] = cp*cy; - data[6] = sr*sy + cr*sp*cy; - data[7] = 0; - - data[8] = sr*cp; - data[9] = -sp; - data[10] = cr*cp; - data[11] = 0; - - data[12] = 0; - data[13] = 0; - data[14] = 0; - data[15] = 1; - } - - /** Create a frustum matrix with the far plane at the infinity. */ - void Frustum( scalar xmin, scalar xmax, scalar ymin, scalar ymax, scalar zNear, scalar zFar ) { - scalar one_deltax, one_deltay, one_deltaz, doubleznear; - - doubleznear = 2.0f * zNear; - one_deltax = 1.0f / (xmax - xmin); - one_deltay = 1.0f / (ymax - ymin); - one_deltaz = 1.0f / (zFar - zNear); - - data[0] = (scalar)(doubleznear * one_deltax); - data[1] = 0.0f; - data[2] = 0.0f; - data[3] = 0.0f; - data[4] = 0.0f; - data[5] = (scalar)(doubleznear * one_deltay); - data[6] = 0.f; - data[7] = 0.f; - data[8] = (scalar)((xmax + xmin) * one_deltax); - data[9] = (scalar)((ymax + ymin) * one_deltay); - data[10] = (scalar)(-(zFar + zNear) * one_deltaz); - data[11] = -1.f; - data[12] = 0.f; - data[13] = 0.f; - data[14] = (scalar)(-(zFar * doubleznear) * one_deltaz); - data[15] = 0.f; - } - - /** Create a frustum matrix with the far plane at the infinity. */ - void FrustumInf( scalar xmin, scalar xmax, scalar ymin, scalar ymax, scalar zNear ) { - scalar one_deltax, one_deltay, doubleznear, nudge; - - doubleznear = 2.0f * zNear; - one_deltax = 1.0f / (xmax - xmin); - one_deltay = 1.0f / (ymax - ymin); - nudge = 1.0; // 0.999; - - data[0] = doubleznear * one_deltax; - data[1] = 0.0f; - data[2] = 0.0f; - data[3] = 0.0f; - - data[4] = 0.0f; - data[5] = doubleznear * one_deltay; - data[6] = 0.f; - data[7] = 0.f; - - data[8] = (xmax + xmin) * one_deltax; - data[9] = (ymax + ymin) * one_deltay; - data[10] = -1.0f * nudge; - data[11] = -1.0f; - - data[12] = 0.f; - data[13] = 0.f; - data[14] = -doubleznear * nudge; - data[15] = 0.f; - } - - /** Create an inverse frustum matrix with the far plane at the infinity. */ - void FrustumInfInv( scalar left, scalar right, scalar bottom, scalar top, scalar zNear ) { - // this matrix is wrong (not tested scalarly) I think it should be transposed. - data[0] = (right - left) / (2 * zNear); - data[1] = 0; - data[2] = 0; - data[3] = (right + left) / (2 * zNear); - data[4] = 0; - data[5] = (top - bottom) / (2 * zNear); - data[6] = 0; - data[7] = (top + bottom) / (2 * zNear); - data[8] = 0; - data[9] = 0; - data[10] = 0; - data[11] = -1; - data[12] = 0; - data[13] = 0; - data[14] = -1 / (2 * zNear); - data[15] = 1 / (2 * zNear); - } - - /** Create an homogeneous projection matrix. */ - void Perspective( scalar fov, scalar aspect, scalar zNear, scalar zFar ) { - scalar xmin, xmax, ymin, ymax; - - xmax = zNear * tan( fov/2 ); - xmin = -xmax; - - ymax = xmax / aspect; - ymin = -ymax; - - Frustum(xmin, xmax, ymin, ymax, zNear, zFar); - } - - /** Create a projection matrix with the far plane at the infinity. */ - void PerspectiveInf( scalar fov, scalar aspect, scalar zNear ) { - scalar x = zNear * tan( fov/2 ); - scalar y = x / aspect; - FrustumInf( -x, x, -y, y, zNear ); - } - - /** Create an inverse projection matrix with far plane at the infinity. */ - void PerspectiveInfInv( scalar fov, scalar aspect, scalar zNear ) { - scalar x = zNear * tan( fov/2 ); - scalar y = x / aspect; - FrustumInfInv( -x, x, -y, y, zNear ); - } - - /** Build bone matrix from quatertion and offset. */ - void BoneMatrix(const Quat & q, const Vec3 & offset) { - scalar x2, y2, z2, xx, xy, xz, yy, yz, zz, wx, wy, wz; - - // calculate coefficients - x2 = q.x + q.x; - y2 = q.y + q.y; - z2 = q.z + q.z; - - xx = q.x * x2; xy = q.x * y2; xz = q.x * z2; - yy = q.y * y2; yz = q.y * z2; zz = q.z * z2; - wx = q.w * x2; wy = q.w * y2; wz = q.w * z2; - - data[0] = 1.0f - (yy + zz); - data[1] = xy - wz; - data[2] = xz + wy; - data[3] = 0.0f; - - data[4] = xy + wz; - data[5] = 1.0f - (xx + zz); - data[6] = yz - wx; - data[7] = 0.0f; - - data[8] = xz - wy; - data[9] = yz + wx; - data[10] = 1.0f - (xx + yy); - data[11] = 0.0f; - - data[12] = offset.x; - data[13] = offset.y; - data[14] = offset.z; - data[15] = 1.0f; - } - - //@} - - - /** @name Transformations: */ - //@{ - - /** Apply a general scale. */ - void Scale( scalar x, scalar y, scalar z ) { - data[0] *= x; data[4] *= y; data[8] *= z; - data[1] *= x; data[5] *= y; data[9] *= z; - data[2] *= x; data[6] *= y; data[10] *= z; - data[3] *= x; data[7] *= y; data[11] *= z; - } - - /** Apply a rotation of theta degrees around the axis v*/ - void Rotate( scalar theta, const Vec3 & v ) { - Matrix b; - b.RotationMatrix( theta, v[0], v[1], v[2] ); - Multiply4x3( b ); - } - - /** Apply a rotation of theta degrees around the axis v*/ - void Rotate( scalar theta, scalar v0, scalar v1, scalar v2 ) { - Matrix b; - b.RotationMatrix( theta, v0, v1, v2 ); - Multiply4x3( b ); - } - - /** - * Translate the matrix by t. This is the same as multiplying by a - * translation matrix with the given offset. - * this = T * this - */ - void Translate( const Vec3 &t ) { - data[12] = data[0] * t.x + data[4] * t.y + data[8] * t.z + data[12]; - data[13] = data[1] * t.x + data[5] * t.y + data[9] * t.z + data[13]; - data[14] = data[2] * t.x + data[6] * t.y + data[10] * t.z + data[14]; - data[15] = data[3] * t.x + data[7] * t.y + data[11] * t.z + data[15]; - } - - /** - * Translate the matrix by x, y, z. This is the same as multiplying by a - * translation matrix with the given offsets. - */ - void Translate( scalar x, scalar y, scalar z ) { - data[12] = data[0] * x + data[4] * y + data[8] * z + data[12]; - data[13] = data[1] * x + data[5] * y + data[9] * z + data[13]; - data[14] = data[2] * x + data[6] * y + data[10] * z + data[14]; - data[15] = data[3] * x + data[7] * y + data[11] * z + data[15]; - } - - /** Compute the transposed matrix. */ - void Transpose() { - piSwap(data[1], data[4]); - piSwap(data[2], data[8]); - piSwap(data[6], data[9]); - piSwap(data[3], data[12]); - piSwap(data[7], data[13]); - piSwap(data[11], data[14]); - } - - /** Compute the inverse of a rigid-body/isometry/orthonormal matrix. */ - void IsometryInverse() { - // transposed 3x3 upper left matrix - piSwap(data[1], data[4]); - piSwap(data[2], data[8]); - piSwap(data[6], data[9]); - - // translate by the negative offsets - Vec3 v(-data[12], -data[13], -data[14]); - data[12] = data[13] = data[14] = 0; - Translate(v); - } - - /** Compute the inverse of the affine portion of this matrix. */ - void AffineInverse() { - data[12] = data[13] = data[14] = 0; - Transpose(); - } - //@} - - /** @name Matrix operations: */ - //@{ - - /** Return the determinant of this matrix. */ - scalar Determinant() const { - return data[0] * data[5] * data[10] * data[15] + - data[1] * data[6] * data[11] * data[12] + - data[2] * data[7] * data[ 8] * data[13] + - data[3] * data[4] * data[ 9] * data[14] - - data[3] * data[6] * data[ 9] * data[12] - - data[2] * data[5] * data[ 8] * data[15] - - data[1] * data[4] * data[11] * data[14] - - data[0] * data[7] * data[10] * data[12]; - } - - - /** Standard matrix product: this *= B. */ - void Multiply4x4( const Matrix & restrict B ) { - Multiply4x4(*this, B); - } - - /** Standard matrix product: this = A * B. this != B*/ - void Multiply4x4( const Matrix & A, const Matrix & restrict B ) { - piDebugCheck(this != &B); - - for(int i = 0; i < 4; i++) { - const scalar ai0 = A(i,0), ai1 = A(i,1), ai2 = A(i,2), ai3 = A(i,3); - GetElem(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - GetElem(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - GetElem(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - GetElem(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } - - /* Unrolled but does not allow this == A - data[0] = A.data[0] * B.data[0] + A.data[4] * B.data[1] + A.data[8] * B.data[2] + A.data[12] * B.data[3]; - data[1] = A.data[1] * B.data[0] + A.data[5] * B.data[1] + A.data[9] * B.data[2] + A.data[13] * B.data[3]; - data[2] = A.data[2] * B.data[0] + A.data[6] * B.data[1] + A.data[10] * B.data[2] + A.data[14] * B.data[3]; - data[3] = A.data[3] * B.data[0] + A.data[7] * B.data[1] + A.data[11] * B.data[2] + A.data[15] * B.data[3]; - data[4] = A.data[0] * B.data[4] + A.data[4] * B.data[5] + A.data[8] * B.data[6] + A.data[12] * B.data[7]; - data[5] = A.data[1] * B.data[4] + A.data[5] * B.data[5] + A.data[9] * B.data[6] + A.data[13] * B.data[7]; - data[6] = A.data[2] * B.data[4] + A.data[6] * B.data[5] + A.data[10] * B.data[6] + A.data[14] * B.data[7]; - data[7] = A.data[3] * B.data[4] + A.data[7] * B.data[5] + A.data[11] * B.data[6] + A.data[15] * B.data[7]; - data[8] = A.data[0] * B.data[8] + A.data[4] * B.data[9] + A.data[8] * B.data[10] + A.data[12] * B.data[11]; - data[9] = A.data[1] * B.data[8] + A.data[5] * B.data[9] + A.data[9] * B.data[10] + A.data[13] * B.data[11]; - data[10]= A.data[2] * B.data[8] + A.data[6] * B.data[9] + A.data[10] * B.data[10] + A.data[14] * B.data[11]; - data[11]= A.data[3] * B.data[8] + A.data[7] * B.data[9] + A.data[11] * B.data[10] + A.data[15] * B.data[11]; - data[12]= A.data[0] * B.data[12] + A.data[4] * B.data[13] + A.data[8] * B.data[14] + A.data[12] * B.data[15]; - data[13]= A.data[1] * B.data[12] + A.data[5] * B.data[13] + A.data[9] * B.data[14] + A.data[13] * B.data[15]; - data[14]= A.data[2] * B.data[12] + A.data[6] * B.data[13] + A.data[10] * B.data[14] + A.data[14] * B.data[15]; - data[15]= A.data[3] * B.data[12] + A.data[7] * B.data[13] + A.data[11] * B.data[14] + A.data[15] * B.data[15]; - */ - } - - /** Standard matrix product: this *= B. */ - void Multiply4x3( const Matrix & restrict B ) { - Multiply4x3(*this, B); - } - - /** Standard product of matrices, where the last row is [0 0 0 1]. */ - void Multiply4x3( const Matrix & A, const Matrix & restrict B ) { - piDebugCheck(this != &B); - - for(int i = 0; i < 3; i++) { - const scalar ai0 = A(i,0), ai1 = A(i,1), ai2 = A(i,2), ai3 = A(i,3); - GetElem(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - GetElem(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - GetElem(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - GetElem(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } - data[3] = 0.0f; data[7] = 0.0f; data[11] = 0.0f; data[15] = 1.0f; - - /* Unrolled but does not allow this == A - data[0] = a.data[0] * b.data[0] + a.data[4] * b.data[1] + a.data[8] * b.data[2] + a.data[12] * b.data[3]; - data[1] = a.data[1] * b.data[0] + a.data[5] * b.data[1] + a.data[9] * b.data[2] + a.data[13] * b.data[3]; - data[2] = a.data[2] * b.data[0] + a.data[6] * b.data[1] + a.data[10] * b.data[2] + a.data[14] * b.data[3]; - data[3] = 0.0f; - data[4] = a.data[0] * b.data[4] + a.data[4] * b.data[5] + a.data[8] * b.data[6] + a.data[12] * b.data[7]; - data[5] = a.data[1] * b.data[4] + a.data[5] * b.data[5] + a.data[9] * b.data[6] + a.data[13] * b.data[7]; - data[6] = a.data[2] * b.data[4] + a.data[6] * b.data[5] + a.data[10] * b.data[6] + a.data[14] * b.data[7]; - data[7] = 0.0f; - data[8] = a.data[0] * b.data[8] + a.data[4] * b.data[9] + a.data[8] * b.data[10] + a.data[12] * b.data[11]; - data[9] = a.data[1] * b.data[8] + a.data[5] * b.data[9] + a.data[9] * b.data[10] + a.data[13] * b.data[11]; - data[10]= a.data[2] * b.data[8] + a.data[6] * b.data[9] + a.data[10] * b.data[10] + a.data[14] * b.data[11]; - data[11]= 0.0f; - data[12]= a.data[0] * b.data[12] + a.data[4] * b.data[13] + a.data[8] * b.data[14] + a.data[12] * b.data[15]; - data[13]= a.data[1] * b.data[12] + a.data[5] * b.data[13] + a.data[9] * b.data[14] + a.data[13] * b.data[15]; - data[14]= a.data[2] * b.data[12] + a.data[6] * b.data[13] + a.data[10] * b.data[14] + a.data[14] * b.data[15]; - data[15]= 1.0f; - */ - } - //@} - - - /** @name Vector operations: */ - //@{ - - /** Transform 3d vector (w=0). */ - void TransformVec3(const Vec3 & restrict orig, Vec3 * restrict dest) const { - piDebugCheck(&orig != dest); - dest->x = orig.x * data[0] + orig.y * data[4] + orig.z * data[8]; - dest->y = orig.x * data[1] + orig.y * data[5] + orig.z * data[9]; - dest->z = orig.x * data[2] + orig.y * data[6] + orig.z * data[10]; - } - /** Transform 3d vector by the transpose (w=0). */ - void TransformVec3T(const Vec3 & restrict orig, Vec3 * restrict dest) const { - piDebugCheck(&orig != dest); - dest->x = orig.x * data[0] + orig.y * data[1] + orig.z * data[2]; - dest->y = orig.x * data[4] + orig.y * data[5] + orig.z * data[6]; - dest->z = orig.x * data[8] + orig.y * data[9] + orig.z * data[10]; - } - - /** Transform a 3d homogeneous vector, where the fourth coordinate is assumed to be 1. */ - void TransformPoint(const Vec3 & restrict orig, Vec3 * restrict dest) const { - piDebugCheck(&orig != dest); - dest->x = orig.x * data[0] + orig.y * data[4] + orig.z * data[8] + data[12]; - dest->y = orig.x * data[1] + orig.y * data[5] + orig.z * data[9] + data[13]; - dest->z = orig.x * data[2] + orig.y * data[6] + orig.z * data[10] + data[14]; - } - - /** Transform a point, normalize it, and return w. */ - scalar TransformPointAndNormalize(const Vec3 & restrict orig, Vec3 * restrict dest) const { - piDebugCheck(&orig != dest); - scalar w; - dest->x = orig.x * data[0] + orig.y * data[4] + orig.z * data[8] + data[12]; - dest->y = orig.x * data[1] + orig.y * data[5] + orig.z * data[9] + data[13]; - dest->z = orig.x * data[2] + orig.y * data[6] + orig.z * data[10] + data[14]; - w = 1 / (orig.x * data[3] + orig.y * data[7] + orig.z * data[11] + data[15]); - *dest *= w; - return w; - } - - /** Transform a point and return w. */ - scalar TransformPointReturnW(const Vec3 & restrict orig, Vec3 * restrict dest) const { - piDebugCheck(&orig != dest); - dest->x = orig.x * data[0] + orig.y * data[4] + orig.z * data[8] + data[12]; - dest->y = orig.x * data[1] + orig.y * data[5] + orig.z * data[9] + data[13]; - dest->z = orig.x * data[2] + orig.y * data[6] + orig.z * data[10] + data[14]; - return orig.x * data[3] + orig.y * data[7] + orig.z * data[11] + data[15]; - } - - /** Transform a normalized 3d point by a 4d matrix and return the resulting 4d vector. */ - void TransformVec4(const Vec3 & orig, Vec4 * dest) const { - dest->x = orig.x * data[0] + orig.y * data[4] + orig.z * data[8] + data[12]; - dest->y = orig.x * data[1] + orig.y * data[5] + orig.z * data[9] + data[13]; - dest->z = orig.x * data[2] + orig.y * data[6] + orig.z * data[10] + data[14]; - dest->w = orig.x * data[3] + orig.y * data[7] + orig.z * data[11] + data[15]; - } - //@} - - /** @name Matrix analysis. */ - //@{ - - /** Get the ZYZ euler angles from the matrix. Assumes the matrix is orthonormal. */ - void GetEulerAnglesZYZ(scalar * s, scalar * t, scalar * r) const { - if( GetElem(2,2) < 1.0f ) { - if( GetElem(2,2) > -1.0f ) { - // cs*ct*cr-ss*sr -ss*ct*cr-cs*sr st*cr - // cs*ct*sr+ss*cr -ss*ct*sr+cs*cr st*sr - // -cs*st ss*st ct - *s = atan2(GetElem(1,2), -GetElem(0,2)); - *t = acos(GetElem(2,2)); - *r = atan2(GetElem(2,1), GetElem(2,0)); - } - else { - // -c(s-r) s(s-r) 0 - // s(s-r) c(s-r) 0 - // 0 0 -1 - *s = atan2(GetElem(0, 1), -GetElem(0, 0)); // = s-r - *t = PI; - *r = 0; - } - } - else { - // c(s+r) -s(s+r) 0 - // s(s+r) c(s+r) 0 - // 0 0 1 - *s = atan2(GetElem(0, 1), GetElem(0, 0)); // = s+r - *t = 0; - *r = 0; - } - } - - //@} - - MATHLIB_API friend PiStream & operator<< ( PiStream & s, Matrix & m ); - - /** Print to debug output. */ - void Print() const { - piDebug( "[ %5.2f %5.2f %5.2f %5.2f ]\n", data[0], data[4], data[8], data[12] ); - piDebug( "[ %5.2f %5.2f %5.2f %5.2f ]\n", data[1], data[5], data[9], data[13] ); - piDebug( "[ %5.2f %5.2f %5.2f %5.2f ]\n", data[2], data[6], data[10], data[14] ); - piDebug( "[ %5.2f %5.2f %5.2f %5.2f ]\n", data[3], data[7], data[11], data[15] ); - } - - -public: - - scalar data[16]; - -}; -#endif - - - - -#endif // NV_MATH_MATRIX_H diff --git a/Externals/NVTT/src/nvmath/Montecarlo.cpp b/Externals/NVTT/src/nvmath/Montecarlo.cpp deleted file mode 100644 index 4cd23a515bc..00000000000 --- a/Externals/NVTT/src/nvmath/Montecarlo.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -using namespace nv; - - -void SampleDistribution::redistribute(Method method/*=Method_NRook*/, Distribution dist/*=Distribution_Cosine*/) -{ - switch(method) - { - case Method_Random: - redistributeRandom(dist); - break; - case Method_Stratified: - redistributeStratified(dist); - break; - case Method_NRook: - redistributeNRook(dist); - break; - }; -} - -void SampleDistribution::redistributeRandom(const Distribution dist) -{ - const uint sampleCount = m_sampleArray.count(); - - // This is the worst method possible! - for(uint i = 0; i < sampleCount; i++) - { - float x = m_rand.getFloat(); - float y = m_rand.getFloat(); - - // Map uniform distribution in the square to the (hemi)sphere. - if( dist == Distribution_Uniform ) { - m_sampleArray[i].setUV(acosf(1 - 2 * x), 2 * PI * y); - } - else { - nvDebugCheck(dist == Distribution_Cosine); - m_sampleArray[i].setUV(acosf(sqrtf(x)), 2 * PI * y); - } - } -} - - -void SampleDistribution::redistributeStratified(const Distribution dist) -{ - const uint sampleCount = m_sampleArray.count(); - const uint sqrtSampleCount = uint(sqrtf(float(sampleCount))); - - nvDebugCheck(sqrtSampleCount*sqrtSampleCount == sampleCount); // Must use exact powers! - - // Create a uniform distribution of points on the hemisphere with low variance. - for(uint v = 0, i = 0; v < sqrtSampleCount; v++) { - for(uint u = 0; u < sqrtSampleCount; u++, i++) { - float x = (u + m_rand.getFloat()) / float(sqrtSampleCount); - float y = (v + m_rand.getFloat()) / float(sqrtSampleCount); - - // Map uniform distribution in the square to the (hemi)sphere. - if( dist == Distribution_Uniform ) { - m_sampleArray[i].setUV(acosf(1 - 2 * x), 2 * PI * y); - } - else { - nvDebugCheck(dist == Distribution_Cosine); - m_sampleArray[i].setUV(acosf(sqrtf(x)), 2 * PI * y); - } - } - } -} - - -/** Multi-Stage N-rooks Sampling Method. - * See: http://www.acm.org/jgt/papers/WangSung9/9 - */ -void SampleDistribution::multiStageNRooks(const int size, int* cells) -{ - if (size == 1) { - return; - } - - int size1 = size >> 1; - int size2 = size >> 1; - - if (size & 1) { - if (m_rand.getFloat() > 0.5) { - size1++; - } - else { - size2++; - } - } - - int* upper_cells = new int[size1]; - int* lower_cells = new int[size2]; - - int i, j; - for(i = 0, j = 0; i < size - 1; i += 2, j++) { - if (m_rand.get() & 1) { - upper_cells[j] = cells[i]; - lower_cells[j] = cells[i + 1]; - } - else { - upper_cells[j] = cells[i + 1]; - lower_cells[j] = cells[i]; - } - } - - if (size1 != size2) { - if (size1 > size2) { - upper_cells[j] = cells[i]; - } - else { - lower_cells[j] = cells[i]; - } - } - - multiStageNRooks(size1, upper_cells); - memcpy(cells, upper_cells, size1 * sizeof(int)); - delete [] upper_cells; - - multiStageNRooks(size2, lower_cells); - memcpy(cells + size1, lower_cells, size2 * sizeof(int)); - delete [] lower_cells; -} - - -void SampleDistribution::redistributeNRook(const Distribution dist) -{ - const uint sampleCount = m_sampleArray.count(); - - // Generate nrook cells - int * cells = new int[sampleCount]; - for(uint32 i = 0; i < sampleCount; i++) - { - cells[i] = i; - } - multiStageNRooks(sampleCount, cells); - - for(uint i = 0; i < sampleCount; i++) - { - float x = (i + m_rand.getFloat()) / sampleCount; - float y = (cells[i] + m_rand.getFloat()) / sampleCount; - - // Map uniform distribution in the square to the (hemi)sphere. - if( dist == Distribution_Uniform ) { - m_sampleArray[i].setUV(acosf(1 - 2 * x), 2 * PI * y); - } - else { - nvDebugCheck(dist == Distribution_Cosine); - m_sampleArray[i].setUV(acosf(sqrtf(x)), 2 * PI * y); - } - } - - delete [] cells; -} - diff --git a/Externals/NVTT/src/nvmath/Montecarlo.h b/Externals/NVTT/src/nvmath/Montecarlo.h deleted file mode 100644 index efda3153163..00000000000 --- a/Externals/NVTT/src/nvmath/Montecarlo.h +++ /dev/null @@ -1,84 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_MONTECARLO_H -#define NV_MATH_MONTECARLO_H - -#include -#include - -namespace nv -{ - -/// A random sample distribution. -class SampleDistribution -{ -public: - - // Sampling method. - enum Method { - Method_Random, - Method_Stratified, - Method_NRook - }; - - // Distribution functions. - enum Distribution { - Distribution_Uniform, - Distribution_Cosine - }; - - /// Constructor. - SampleDistribution(int num) - { - m_sampleArray.resize(num); - } - - void redistribute(Method method=Method_NRook, Distribution dist=Distribution_Cosine); - - /// Get parametric coordinates of the sample. - Vector2 sample(int i) { return m_sampleArray[i].uv; } - - /// Get sample direction. - Vector3 sampleDir(int i) { return m_sampleArray[i].dir; } - - /// Get number of samples. - uint sampleCount() const { return m_sampleArray.count(); } - -private: - - void redistributeRandom(const Distribution dist); - void redistributeStratified(const Distribution dist); - void multiStageNRooks(const int size, int* cells); - void redistributeNRook(const Distribution dist); - - - /// A sample of the random distribution. - struct Sample - { - /// Set sample given the 3d coordinates. - void setDir(float x, float y, float z) { - dir.set(x, y, z); - uv.set(acosf(z), atan2f(y, x)); - } - - /// Set sample given the 2d parametric coordinates. - void setUV(float u, float v) { - uv.set(u, v); - dir.set(sinf(u) * cosf(v), sinf(u) * sinf(v), cosf(u)); - } - - Vector2 uv; - Vector3 dir; - }; - - /// Random seed. - MTRand m_rand; - - /// Samples. - Array m_sampleArray; - -}; - -} // nv namespace - -#endif // NV_MATH_MONTECARLO_H diff --git a/Externals/NVTT/src/nvmath/Plane.cpp b/Externals/NVTT/src/nvmath/Plane.cpp deleted file mode 100644 index 979c099efd1..00000000000 --- a/Externals/NVTT/src/nvmath/Plane.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include "Plane.h" -#include "Matrix.h" - -namespace nv -{ - Plane transformPlane(const Matrix& m, Plane::Arg p) - { - Vector3 newVec = transformVector(m, p.vector()); - - Vector3 ptInPlane = p.offset() * p.vector(); - ptInPlane = transformPoint(m, ptInPlane); - - return Plane(newVec, ptInPlane); - } -} diff --git a/Externals/NVTT/src/nvmath/Plane.h b/Externals/NVTT/src/nvmath/Plane.h deleted file mode 100644 index bc7128c4f59..00000000000 --- a/Externals/NVTT/src/nvmath/Plane.h +++ /dev/null @@ -1,77 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_PLANE_H -#define NV_MATH_PLANE_H - -#include -#include - -namespace nv -{ - class Matrix; - - - class NVMATH_CLASS Plane - { - public: - typedef Plane const & Arg; - - Plane(); - Plane(float x, float y, float z, float w); - Plane(Vector4::Arg v); - Plane(Vector3::Arg v, float d); - Plane(Vector3::Arg normal, Vector3::Arg point); - - const Plane & operator=(Plane::Arg v); - - Vector3 vector() const; - scalar offset() const; - - const Vector4 & asVector() const; - Vector4 & asVector(); - - void operator*=(scalar s); - - private: - Vector4 p; - }; - - inline Plane::Plane() {} - inline Plane::Plane(float x, float y, float z, float w) : p(x, y, z, w) {} - inline Plane::Plane(Vector4::Arg v) : p(v) {} - inline Plane::Plane(Vector3::Arg v, float d) : p(v, d) {} - inline Plane::Plane(Vector3::Arg normal, Vector3::Arg point) : p(normal, dot(normal, point)) {} - - inline const Plane & Plane::operator=(Plane::Arg v) { p = v.p; return *this; } - - inline Vector3 Plane::vector() const { return p.xyz(); } - inline scalar Plane::offset() const { return p.w(); } - - inline const Vector4 & Plane::asVector() const { return p; } - inline Vector4 & Plane::asVector() { return p; } - - // Normalize plane. - inline Plane normalize(Plane::Arg plane, float epsilon = NV_EPSILON) - { - const float len = length(plane.vector()); - nvDebugCheck(!isZero(len, epsilon)); - const float inv = 1.0f / len; - return Plane(plane.asVector() * inv); - } - - // Get the distance from the given point to this plane. - inline float distance(Plane::Arg plane, Vector3::Arg point) - { - return dot(plane.vector(), point) - plane.offset(); - } - - inline void Plane::operator*=(scalar s) - { - scale(p, s); - } - - Plane transformPlane(const Matrix&, Plane::Arg); - -} // nv namespace - -#endif // NV_MATH_PLANE_H diff --git a/Externals/NVTT/src/nvmath/Quaternion.h b/Externals/NVTT/src/nvmath/Quaternion.h deleted file mode 100644 index b5007ccacf1..00000000000 --- a/Externals/NVTT/src/nvmath/Quaternion.h +++ /dev/null @@ -1,128 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_QUATERNION_H -#define NV_MATH_QUATERNION_H - -#include -#include - -namespace nv -{ - - class NVMATH_CLASS Quaternion - { - public: - typedef Quaternion const & Arg; - - Quaternion(); - explicit Quaternion(zero_t); - Quaternion(float x, float y, float z, float w); - Quaternion(Vector4::Arg v); - - const Quaternion & operator=(Quaternion::Arg v); - - scalar x() const; - scalar y() const; - scalar z() const; - scalar w() const; - - const Vector4 & asVector() const; - Vector4 & asVector(); - - private: - Vector4 q; - }; - - inline Quaternion::Quaternion() {} - inline Quaternion::Quaternion(zero_t) : q(zero) {} - inline Quaternion::Quaternion(float x, float y, float z, float w) : q(x, y, z, w) {} - inline Quaternion::Quaternion(Vector4::Arg v) : q(v) {} - - inline const Quaternion & Quaternion::operator=(Quaternion::Arg v) { q = v.q; return *this; } - - inline scalar Quaternion::x() const { return q.x(); } - inline scalar Quaternion::y() const { return q.y(); } - inline scalar Quaternion::z() const { return q.z(); } - inline scalar Quaternion::w() const { return q.w(); } - - inline const Vector4 & Quaternion::asVector() const { return q; } - inline Vector4 & Quaternion::asVector() { return q; } - - - inline Quaternion mul(Quaternion::Arg a, Quaternion::Arg b) - { - // @@ Efficient SIMD implementation? - return Quaternion( - + a.x() * b.w() + a.y()*b.z() - a.z()*b.y() + a.w()*b.x(), - - a.x() * b.z() + a.y()*b.w() + a.z()*b.x() + a.w()*b.y(), - + a.x() * b.y() - a.y()*b.x() + a.z()*b.w() + a.w()*b.z(), - - a.x() * b.x() - a.y()*b.y() - a.z()*b.z() + a.w()*b.w()); - } - - inline Quaternion scale(Quaternion::Arg q, float s) - { - return scale(q.asVector(), s); - } - inline Quaternion operator *(Quaternion::Arg q, float s) - { - return scale(q, s); - } - inline Quaternion operator *(float s, Quaternion::Arg q) - { - return scale(q, s); - } - - inline Quaternion scale(Quaternion::Arg q, Vector4::Arg s) - { - return scale(q.asVector(), s); - } - /*inline Quaternion operator *(Quaternion::Arg q, Vector4::Arg s) - { - return scale(q, s); - } - inline Quaternion operator *(Vector4::Arg s, Quaternion::Arg q) - { - return scale(q, s); - }*/ - - inline Quaternion conjugate(Quaternion::Arg q) - { - return scale(q, Vector4(-1, -1, -1, 1)); - } - - inline float length(Quaternion::Arg q) - { - return length(q.asVector()); - } - - inline bool isNormalized(Quaternion::Arg q, float epsilon = NV_NORMAL_EPSILON) - { - return equal(length(q), 1, epsilon); - } - - inline Quaternion normalize(Quaternion::Arg q, float epsilon = NV_EPSILON) - { - float l = length(q); - nvDebugCheck(!isZero(l, epsilon)); - Quaternion n = scale(q, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; - } - - inline Quaternion inverse(Quaternion::Arg q) - { - return conjugate(normalize(q)); - } - - /// Create a rotation quaternion for @a angle alpha around normal vector @a v. - inline Quaternion axisAngle(Vector3::Arg v, float alpha) - { - float s = sinf(alpha * 0.5f); - float c = cosf(alpha * 0.5f); - return Quaternion(Vector4(v * s, c)); - } - - -} // nv namespace - -#endif // NV_MATH_QUATERNION_H diff --git a/Externals/NVTT/src/nvmath/Random.cpp b/Externals/NVTT/src/nvmath/Random.cpp deleted file mode 100644 index 6178134fa56..00000000000 --- a/Externals/NVTT/src/nvmath/Random.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include -#include - -using namespace nv; - -// Statics -const uint16 Rand48::a0 = 0xE66D; -const uint16 Rand48::a1 = 0xDEEC; -const uint16 Rand48::a2 = 0x0005; -const uint16 Rand48::c0 = 0x000B; - - -/// Get a random seed based on the current time. -uint Rand::randomSeed() -{ - return (uint)time(NULL); -} - - -void MTRand::initialize( uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - uint32 *s = state; - uint32 *r = state; - int i = 1; - *s++ = seed & 0xffffffffUL; - for( ; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - - -void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - uint32 *p = state; - int i; - for( i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for( i = M; --i; ++p ) - *p = twist( p[M-N], p[0], p[1] ); - *p = twist( p[M-N], p[0], state[0] ); - - left = N, next = state; -} - diff --git a/Externals/NVTT/src/nvmath/Random.h b/Externals/NVTT/src/nvmath/Random.h deleted file mode 100644 index 0f76949ea6a..00000000000 --- a/Externals/NVTT/src/nvmath/Random.h +++ /dev/null @@ -1,368 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_RANDOM_H -#define NV_MATH_RANDOM_H - -#include // nextPowerOfTwo -#include - -namespace nv -{ - -/// Interface of the random number generators. -class Rand -{ -public: - - virtual ~Rand() {} - - enum time_e { Time }; - - /// Provide a new seed. - virtual void seed( uint s ) { /* empty */ }; - - /// Get an integer random number. - virtual uint get() = 0; - - /// Get a random number on [0, max] interval. - uint getRange( uint max ) - { - uint n; - // uint mask = Bitmask( max ); - // do { n = Get() & mask; } while( n > max ); - uint np2 = nextPowerOfTwo( max ); - do { n = get() & (np2-1); } while( n > max ); - return n; - } - - /// Random number on [0.0, 1.0] interval. - float getFloat() - { - union - { - uint32 i; - float f; - } pun; - - pun.i = 0x3f800000UL | (get() & 0x007fffffUL); - return pun.f - 1.0f; - } - - /* - /// Random number on [0.0, 1.0] interval. - double getReal() - { - return double(get()) * (1.0/4294967295.0); // 2^32-1 - } - - /// Random number on [0.0, 1.0) interval. - double getRealExclusive() - { - return double(get()) * (1.0/4294967296.0); // 2^32 - } - */ - - /// Get the max value of the random number. - uint max() const { return 4294967295U; } - - // Get a random seed. - static uint randomSeed(); - -}; - - -/// Very simple random number generator with low storage requirements. -class SimpleRand : public Rand -{ -public: - - /// Constructor that uses the current time as the seed. - SimpleRand( time_e ) - { - seed(randomSeed()); - } - - /// Constructor that uses the given seed. - SimpleRand( uint s = 0 ) - { - seed(s); - } - - /// Set the given seed. - virtual void seed( uint s ) - { - current = s; - } - - /// Get a random number. - virtual uint get() - { - return current = current * 1103515245 + 12345; - } - -private: - - uint current; - -}; - - -/// Mersenne twister random number generator. -class MTRand : public Rand -{ -public: - - enum { N = 624 }; // length of state vector - enum { M = 397 }; - - /// Constructor that uses the current time as the seed. - MTRand( time_e ) - { - seed(randomSeed()); - } - - /// Constructor that uses the given seed. - MTRand( uint s = 0 ) - { - seed(s); - } - - /// Constructor that uses the given seeds. - NVMATH_API MTRand( const uint * seed_array, uint length ); - - - /// Provide a new seed. - virtual void seed( uint s ) - { - initialize(s); - reload(); - } - - /// Get a random number between 0 - 65536. - virtual uint get() - { - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - if( left == 0 ) { - reload(); - } - left--; - - uint s1; - s1 = *next++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680U; - s1 ^= (s1 << 15) & 0xefc60000U; - return ( s1 ^ (s1 >> 18) ); - }; - - -private: - - NVMATH_API void initialize( uint32 seed ); - NVMATH_API void reload(); - - uint hiBit( uint u ) const { return u & 0x80000000U; } - uint loBit( uint u ) const { return u & 0x00000001U; } - uint loBits( uint u ) const { return u & 0x7fffffffU; } - uint mixBits( uint u, uint v ) const { return hiBit(u) | loBits(v); } - uint twist( uint m, uint s0, uint s1 ) const { return m ^ (mixBits(s0,s1)>>1) ^ ((~loBit(s1)+1) & 0x9908b0dfU); } - -private: - - uint state[N]; // internal state - uint * next; // next value to get from state - int left; // number of values left before reload needed - -}; - - - -/** George Marsaglia's random number generator. - * Code based on Thatcher Ulrich public domain source code: - * http://cvs.sourceforge.net/viewcvs.py/tu-testbed/tu-testbed/base/tu_random.cpp?rev=1.7&view=auto - * - * PRNG code adapted from the complimentary-multiply-with-carry - * code in the article: George Marsaglia, "Seeds for Random Number - * Generators", Communications of the ACM, May 2003, Vol 46 No 5, - * pp90-93. - * - * The article says: - * - * "Any one of the choices for seed table size and multiplier will - * provide a RNG that has passed extensive tests of randomness, - * particularly those in [3], yet is simple and fast -- - * approximately 30 million random 32-bit integers per second on a - * 850MHz PC. The period is a*b^n, where a is the multiplier, n - * the size of the seed table and b=2^32-1. (a is chosen so that - * b is a primitive root of the prime a*b^n + 1.)" - * - * [3] Marsaglia, G., Zaman, A., and Tsang, W. Toward a universal - * random number generator. _Statistics and Probability Letters - * 8_ (1990), 35-39. - */ -class GMRand : public Rand -{ -public: - - enum { SEED_COUNT = 8 }; - -// const uint64 a = 123471786; // for SEED_COUNT=1024 -// const uint64 a = 123554632; // for SEED_COUNT=512 -// const uint64 a = 8001634; // for SEED_COUNT=255 -// const uint64 a = 8007626; // for SEED_COUNT=128 -// const uint64 a = 647535442; // for SEED_COUNT=64 -// const uint64 a = 547416522; // for SEED_COUNT=32 -// const uint64 a = 487198574; // for SEED_COUNT=16 -// const uint64 a = 716514398U; // for SEED_COUNT=8 - enum { a = 716514398U }; - - - GMRand( time_e ) - { - seed(randomSeed()); - } - - GMRand(uint s = 987654321) - { - seed(s); - } - - - /// Provide a new seed. - virtual void seed( uint s ) - { - c = 362436; - i = SEED_COUNT - 1; - - for(int i = 0; i < SEED_COUNT; i++) { - s = s ^ (s << 13); - s = s ^ (s >> 17); - s = s ^ (s << 5); - Q[i] = s; - } - } - - /// Get a random number between 0 - 65536. - virtual uint get() - { - const uint32 r = 0xFFFFFFFE; - - uint64 t; - uint32 x; - - i = (i + 1) & (SEED_COUNT - 1); - t = a * Q[i] + c; - c = uint32(t >> 32); - x = uint32(t + c); - - if( x < c ) { - x++; - c++; - } - - uint32 val = r - x; - Q[i] = val; - return val; - }; - - -private: - - uint32 c; - uint32 i; - uint32 Q[8]; - -}; - - -/** Random number implementation from the GNU Sci. Lib. (GSL). - * Adapted from Nicholas Chapman version: - * - * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough - * This is the Unix rand48() generator. The generator returns the - * upper 32 bits from each term of the sequence, - * - * x_{n+1} = (a x_n + c) mod m - * - * using 48-bit unsigned arithmetic, with a = 0x5DEECE66D , c = 0xB - * and m = 2^48. The seed specifies the upper 32 bits of the initial - * value, x_1, with the lower 16 bits set to 0x330E. - * - * The theoretical value of x_{10001} is 244131582646046. - * - * The period of this generator is ? FIXME (probably around 2^48). - */ -class Rand48 : public Rand -{ -public: - - Rand48( time_e ) - { - seed(randomSeed()); - } - - Rand48( uint s = 0x1234ABCD ) - { - seed(s); - } - - - /** Set the given seed. */ - virtual void seed( uint s ) { - vstate.x0 = 0x330E; - vstate.x1 = uint16(s & 0xFFFF); - vstate.x2 = uint16((s >> 16) & 0xFFFF); - } - - /** Get a random number. */ - virtual uint get() { - - advance(); - - uint x1 = vstate.x1; - uint x2 = vstate.x2; - return (x2 << 16) + x1; - } - - -private: - - void advance() - { - /* work with unsigned long ints throughout to get correct integer - promotions of any unsigned short ints */ - const uint32 x0 = vstate.x0; - const uint32 x1 = vstate.x1; - const uint32 x2 = vstate.x2; - - uint32 a; - a = a0 * x0 + c0; - - vstate.x0 = uint16(a & 0xFFFF); - a >>= 16; - - /* although the next line may overflow we only need the top 16 bits - in the following stage, so it does not matter */ - - a += a0 * x1 + a1 * x0; - vstate.x1 = uint16(a & 0xFFFF); - - a >>= 16; - a += a0 * x2 + a1 * x1 + a2 * x0; - vstate.x2 = uint16(a & 0xFFFF); - } - - -private: - NVMATH_API static const uint16 a0, a1, a2, c0; - - struct rand48_state_t { - uint16 x0, x1, x2; - } vstate; - -}; - -} // nv namespace - -#endif // NV_MATH_RANDOM_H diff --git a/Externals/NVTT/src/nvmath/SphericalHarmonic.cpp b/Externals/NVTT/src/nvmath/SphericalHarmonic.cpp deleted file mode 100644 index f005b5116ff..00000000000 --- a/Externals/NVTT/src/nvmath/SphericalHarmonic.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include - -using namespace nv; - - -namespace -{ - - // Basic integer factorial. - inline static int factorial( int v ) - { - if (v == 0) { - return 1; - } - - int result = v; - while (--v > 0) { - result *= v; - } - return result; - } - - - // Double factorial. - // Defined as: n!! = n*(n - 2)*(n - 4)..., n!!(0,-1) = 1. - inline static int doubleFactorial( int x ) - { - if (x == 0 || x == -1) { - return 1; - } - - int result = x; - while ((x -= 2) > 0) { - result *= x; - } - - return result; - } - - /// Normalization constant for spherical harmonic. - /// @param l is the band. - /// @param m is the argument, in the range [0, m] - inline static float K( int l, int m ) - { - nvDebugCheck( m >= 0 ); - return sqrtf(((2 * l + 1) * factorial(l - m)) / (4 * PI * factorial(l + m))); - } - - /// Normalization constant for hemispherical harmonic. - inline static float HK( int l, int m ) - { - nvDebugCheck( m >= 0 ); - return sqrtf(((2 * l + 1) * factorial(l - m)) / (2 * PI * factorial(l + m))); - } - - /// Evaluate Legendre polynomial. */ - static float legendre( int l, int m, float x ) - { - // piDebugCheck( m >= 0 ); - // piDebugCheck( m <= l ); - // piDebugCheck( fabs(x) <= 1 ); - - // Rule 2 needs no previous results - if (l == m) { - return powf(-1.0f, float(m)) * doubleFactorial(2 * m - 1) * powf(1 - x*x, 0.5f * m); - } - - // Rule 3 requires the result for the same argument of the previous band - if (l == m + 1) { - return x * (2 * m + 1) * legendrePolynomial(m, m, x); - } - - // Main reccurence used by rule 1 that uses result of the same argument from - // the previous two bands - return (x * (2 * l - 1) * legendrePolynomial(l - 1, m, x) - (l + m - 1) * legendrePolynomial(l - 2, m, x)) / (l - m); - } - - - template float legendre(float x); - - template <> float legendre<0, 0>(float x) { - return 1; - } - - template <> float legendre<1, 0>(float x) { - return x; - } - template <> float legendre<1, 1>(float x) { - return -sqrtf(1 - x * x); - } - - template <> float legendre<2, 0>(float x) { - return -0.5f + (3 * x * x) / 2; - } - template <> float legendre<2, 1>(float x) { - return -3 * x * sqrtf(1 - x * x); - } - template <> float legendre<2, 2>(float x) { - return -3 * (-1 + x * x); - } - - template <> float legendre<3, 0>(float x) { - return -(3 * x) / 2 + (5 * x * x * x) / 2; - } - template <> float legendre<3, 1>(float x) { - return -3 * sqrtf(1 - x * x) / 2 * (-1 + 5 * x * x); - } - template <> float legendre<3, 2>(float x) { - return -15 * (-x + x * x * x); - } - template <> float legendre<3, 3>(float x) { - return -15 * powf(1 - x * x, 1.5f); - } - - template <> float legendre<4, 0>(float x) { - return 0.125f * (3.0f - 30.0f * x * x + 35.0f * x * x * x * x); - } - template <> float legendre<4, 1>(float x) { - return -2.5f * x * sqrtf(1.0f - x * x) * (7.0f * x * x - 3.0f); - } - template <> float legendre<4, 2>(float x) { - return -7.5f * (1.0f - 8.0f * x * x + 7.0f * x * x * x * x); - } - template <> float legendre<4, 3>(float x) { - return -105.0f * x * powf(1 - x * x, 1.5f); - } - template <> float legendre<4, 4>(float x) { - return 105.0f * (x * x - 1.0f) * (x * x - 1.0f); - } - -} // namespace - - -float nv::legendrePolynomial(int l, int m, float x) -{ - switch(l) - { - case 0: - return legendre<0, 0>(x); - case 1: - if(m == 0) return legendre<1, 0>(x); - return legendre<1, 1>(x); - case 2: - if(m == 0) return legendre<2, 0>(x); - else if(m == 1) return legendre<2, 1>(x); - return legendre<2, 2>(x); - case 3: - if(m == 0) return legendre<3, 0>(x); - else if(m == 1) return legendre<3, 1>(x); - else if(m == 2) return legendre<3, 2>(x); - return legendre<3, 3>(x); - case 4: - if(m == 0) return legendre<4, 0>(x); - else if(m == 1) return legendre<4, 1>(x); - else if(m == 2) return legendre<4, 2>(x); - else if(m == 3) return legendre<4, 3>(x); - else return legendre<4, 4>(x); - } - - // Fallback to the expensive version. - return legendre(l, m, x); -} - - -/** - * Evaluate the spherical harmonic function for the given angles. - * @param l is the band. - * @param m is the argument, in the range [-l,l] - * @param theta is the altitude, in the range [0, PI] - * @param phi is the azimuth, in the range [0, 2*PI] - */ -float nv::y( int l, int m, float theta, float phi ) -{ - if( m == 0 ) { - // K(l, 0) = sqrt((2*l+1)/(4*PI)) - return sqrtf((2 * l + 1) / (4 * PI)) * legendrePolynomial(l, 0, cosf(theta)); - } - else if( m > 0 ) { - return sqrtf(2.0f) * K(l, m) * cosf(m * phi) * legendrePolynomial(l, m, cosf(theta)); - } - else { - return sqrtf(2.0f) * K(l, -m) * sinf(-m * phi) * legendrePolynomial(l, -m, cosf(theta)); - } -} - - -/** - * Real spherical harmonic function of an unit vector. Uses the following - * equalities to call the angular function: - * x = sin(theta)*cos(phi) - * y = sin(theta)*sin(phi) - * z = cos(theta) - */ -float nv::y( int l, int m, Vector3::Arg v ) -{ - float theta = acosf(v.z()); - float phi = atan2f(v.y(), v.x()); - return y( l, m, theta, phi ); -} - - -/** - * Evaluate the hemispherical harmonic function for the given angles. - * @param l is the band. - * @param m is the argument, in the range [-l,l] - * @param theta is the altitude, in the range [0, PI/2] - * @param phi is the azimuth, in the range [0, 2*PI] - */ -float nv::hy( int l, int m, float theta, float phi ) -{ - if( m == 0 ) { - // HK(l, 0) = sqrt((2*l+1)/(2*PI)) - return sqrtf((2 * l + 1) / (2 * PI)) * legendrePolynomial(l, 0, 2*cosf(theta)-1); - } - else if( m > 0 ) { - return sqrtf(2.0f) * HK(l, m) * cosf(m * phi) * legendrePolynomial(l, m, 2*cosf(theta)-1); - } - else { - return sqrtf(2.0f) * HK(l, -m) * sinf(-m * phi) * legendrePolynomial(l, -m, 2*cosf(theta)-1); - } -} - - -/** - * Real hemispherical harmonic function of an unit vector. Uses the following - * equalities to call the angular function: - * x = sin(theta)*cos(phi) - * y = sin(theta)*sin(phi) - * z = cos(theta) - */ -float nv::hy( int l, int m, Vector3::Arg v ) -{ - float theta = acosf(v.z()); - float phi = atan2f(v.y(), v.x()); - return y( l, m, theta, phi ); -} - - - diff --git a/Externals/NVTT/src/nvmath/SphericalHarmonic.h b/Externals/NVTT/src/nvmath/SphericalHarmonic.h deleted file mode 100644 index 7e8341ceeeb..00000000000 --- a/Externals/NVTT/src/nvmath/SphericalHarmonic.h +++ /dev/null @@ -1,419 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_SPHERICALHARMONIC_H -#define NV_MATH_SPHERICALHARMONIC_H - -#include - -namespace nv -{ - - NVMATH_API float legendrePolynomial( int l, int m, float x ) NV_CONST; - NVMATH_API float y( int l, int m, float theta, float phi ) NV_CONST; - NVMATH_API float y( int l, int m, Vector3::Arg v ) NV_CONST; - NVMATH_API float hy( int l, int m, float theta, float phi ) NV_CONST; - NVMATH_API float hy( int l, int m, Vector3::Arg v ) NV_CONST; - - class Sh; - float dot(const Sh & a, const Sh & b) NV_CONST; - - - /// Spherical harmonic class. - class Sh - { - friend class Sh2; - friend class ShMatrix; - public: - - /// Construct a spherical harmonic of the given order. - Sh(int o) : m_order(o) - { - m_elemArray = new float[basisNum()]; - } - - /// Copy constructor. - Sh(const Sh & sh) : m_order(sh.order()) - { - m_elemArray = new float[basisNum()]; - memcpy(m_elemArray, sh.m_elemArray, sizeof(float) * basisNum()); - } - - /// Destructor. - ~Sh() - { - delete [] m_elemArray; - m_elemArray = NULL; - } - - /// Get number of bands. - static int bandNum(int order) { - return order + 1; - } - - /// Get number of sh basis. - static int basisNum(int order) { - return (order + 1) * (order + 1); - } - - /// Get the index for the given coefficients. - static int index( int l, int m ) { - return l * l + l + m; - } - - /// Get sh order. - int order() const - { - return m_order; - } - - /// Get sh order. - int bandNum() const - { - return bandNum(m_order); - } - - /// Get sh order. - int basisNum() const - { - return basisNum(m_order); - } - - /// Get sh coefficient indexed by l,m. - float elem( int l, int m ) const - { - return m_elemArray[index(l, m)]; - } - - /// Get sh coefficient indexed by l,m. - float & elem( int l, int m ) - { - return m_elemArray[index(l, m)]; - } - - - /// Get sh coefficient indexed by i. - float elemAt( int i ) const { - return m_elemArray[i]; - } - - /// Get sh coefficient indexed by i. - float & elemAt( int i ) - { - return m_elemArray[i]; - } - - - /// Reset the sh coefficients. - void reset() - { - for( int i = 0; i < basisNum(); i++ ) { - m_elemArray[i] = 0.0f; - } - } - - /// Copy spherical harmonic. - void operator= ( const Sh & sh ) - { - nvDebugCheck(order() <= sh.order()); - - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] = sh.m_elemArray[i]; - } - } - - /// Add spherical harmonics. - void operator+= ( const Sh & sh ) - { - nvDebugCheck(order() == sh.order()); - - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] += sh.m_elemArray[i]; - } - } - - /// Substract spherical harmonics. - void operator-= ( const Sh & sh ) - { - nvDebugCheck(order() == sh.order()); - - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] -= sh.m_elemArray[i]; - } - } - - // Not exactly convolution, nor product. - void operator*= ( const Sh & sh ) - { - nvDebugCheck(order() == sh.order()); - - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] *= sh.m_elemArray[i]; - } - } - - /// Scale spherical harmonics. - void operator*= ( float f ) - { - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] *= f; - } - } - - /// Add scaled spherical harmonics. - void addScaled( const Sh & sh, float f ) - { - nvDebugCheck(order() == sh.order()); - - for(int i = 0; i < basisNum(); i++) { - m_elemArray[i] += sh.m_elemArray[i] * f; - } - } - - - /*/// Add a weighted sample to the sh coefficients. - void AddSample( const Vec3 & dir, const Color3f & color, float w=1.0f ) { - for(int l = 0; l <= order; l++) { - for(int m = -l; m <= l; m++) { - Color3f & elem = GetElem(l, m); - elem.Mad( elem, color, w * y(l, m, dir) ); - } - } - }*/ - - /// Evaluate - void eval(Vector3::Arg dir) - { - for(int l = 0; l <= m_order; l++) { - for(int m = -l; m <= l; m++) { - elem(l, m) = y(l, m, dir); - } - } - } - - - /// Evaluate the spherical harmonic function. - float sample(Vector3::Arg dir) const - { - Sh sh(order()); - sh.eval(dir); - - return dot(sh, *this); - } - - - protected: - - const int m_order; - float * m_elemArray; - - }; - - - /// Compute dot product of the spherical harmonics. - inline float dot(const Sh & a, const Sh & b) - { - nvDebugCheck(a.order() == b.order()); - - float sum = 0; - for( int i = 0; i < Sh::basisNum(a.order()); i++ ) { - sum += a.elemAt(i) * b.elemAt(i); - } - - return sum; - } - - - /// Second order spherical harmonic. - class Sh2 : public Sh - { - public: - - /// Constructor. - Sh2() : Sh(2) {} - - /// Copy constructor. - Sh2(const Sh2 & sh) : Sh(sh) {} - - /// Spherical harmonic resulting from projecting the clamped cosine transfer function to the SH basis. - void cosineTransfer() - { - const float c1 = 0.282095f; // K(0, 0) - const float c2 = 0.488603f; // K(1, 0) - const float c3 = 1.092548f; // sqrt(15.0f / PI) / 2.0f = K(2, -2) - const float c4 = 0.315392f; // sqrt(5.0f / PI) / 4.0f) = K(2, 0) - const float c5 = 0.546274f; // sqrt(15.0f / PI) / 4.0f) = K(2, 2) - - const float normalization = PI * 16.0f / 17.0f; - - const float const1 = c1 * normalization * 1.0f; - const float const2 = c2 * normalization * (2.0f / 3.0f); - const float const3 = c3 * normalization * (1.0f / 4.0f); - const float const4 = c4 * normalization * (1.0f / 4.0f); - const float const5 = c5 * normalization * (1.0f / 4.0f); - - m_elemArray[0] = const1; - - m_elemArray[1] = -const2; - m_elemArray[2] = const2; - m_elemArray[3] = -const2; - - m_elemArray[4] = const3; - m_elemArray[5] = -const3; - m_elemArray[6] = const4; - m_elemArray[7] = -const3; - m_elemArray[8] = const5; - } - }; - - - -#if 0 - -/// Spherical harmonic matrix. -class ShMatrix -{ -public: - - /// Create an identity matrix of the given order. - ShMatrix(int o = 2) : order(o), identity(true) - { - nvCheck(order > 0); - e = new float[Size()]; - band = new float *[GetBandNum()]; - setupBands(); - } - - /// Destroy and free matrix elements. - ~ShMatrix() - { - delete e; - delete band; - } - - /// Set identity matrix. - void setIdentity() - { - identity = true; - } - - /// Return true if this is an identity matrix, false in other case. - bool isIdentity() const { - return identity; - } - - /// Get number of bands of this matrix. - int bandNum() const - { - return order+1; - } - - /// Get total number of elements in the matrix. - int size() const - { - int size = 0; - for( int i = 0; i < bandNum(); i++ ) { - size += SQ(i * 2 + 1); - } - return size; - } - - /// Get element at the given raw index. - float elem(const int idx) const - { - return e[idx]; - } - - /// Get element at the given with the given indices. - float & elem( const int b, const int x, const int y ) - { - nvDebugCheck(b >= 0); - nvDebugCheck(b < bandNum()); - return band[b][(b + y) * (b * 2 + 1) + (b + x)]; - } - - /// Get element at the given with the given indices. - float elem( const int b, const int x, const int y ) const - { - nvDebugCheck(b >= 0); - nvDebugCheck(b < bandNum()); - return band[b][(b + y) * (b * 2 + 1) + (b + x)]; - } - - /** Copy matrix. */ - void Copy( const ShMatrix & m ) - { - nvDebugCheck(order == m.order); - memcpy(e, m.e, Size() * sizeof(float)); - } - - /** Rotate the given coefficients. */ - void transform( const Sh & restrict source, Sh * restrict dest ) const { - piCheck( &source != dest ); // Make sure there's no aliasing. - piCheck( dest->order <= order ); - piCheck( order <= source.order ); - - if( identity ) { - *dest = source; - return; - } - - // Loop through each band. - for( int l = 0; l <= dest->order; l++ ) { - - for( int mo = -l; mo <= l; mo++ ) { - - Color3f rgb = Color3f::Black; - - for( int mi = -l; mi <= l; mi++ ) { - rgb.Mad( rgb, source.elem(l, mi), elem(l, mo, mi) ); - } - - dest->elem(l, mo) = rgb; - } - } - } - - - MATHLIB_API void multiply( const ShMatrix &A, const ShMatrix &B ); - MATHLIB_API void rotation( const Matrix & m ); - MATHLIB_API void rotation( int axis, float angles ); - MATHLIB_API void print(); - - -private: - - // @@ These could be static indices precomputed only once. - /// Setup the band pointers. - void setupBands() - { - int size = 0; - for( int i = 0; i < bandNum(); i++ ) { - band[i] = &e[size]; - size += SQ(i * 2 + 1); - } - } - - -private: - - // Matrix order. - const int m_order; - - // Identity flag for quick transform. - bool m_identity; - - // Array of elements. - float * m_e; - - // Band pointers. - float ** m_band; - -}; - -#endif // 0 - - - -} // nv namespace - -#endif // NV_MATH_SPHERICALHARMONIC_H diff --git a/Externals/NVTT/src/nvmath/TriBox.cpp b/Externals/NVTT/src/nvmath/TriBox.cpp deleted file mode 100644 index 216f42df236..00000000000 --- a/Externals/NVTT/src/nvmath/TriBox.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/********************************************************/ -/* AABB-triangle overlap test code */ -/* by Tomas Akenine-Möller */ -/* Function: int triBoxOverlap(float boxcenter[3], */ -/* float boxhalfsize[3],float triverts[3][3]); */ -/* History: */ -/* 2001-03-05: released the code in its first version */ -/* 2001-06-18: changed the order of the tests, faster */ -/* */ -/* Acknowledgement: Many thanks to Pierre Terdiman for */ -/* suggestions and discussions on how to optimize code. */ -/* Thanks to David Hunt for finding a ">="-bug! */ -/********************************************************/ - -#include -#include - -using namespace nv; - -#define X 0 -#define Y 1 -#define Z 2 - -#define FINDMINMAX(x0,x1,x2,min,max) \ - min = max = x0; \ - if(x1max) max=x1;\ - if(x2max) max=x2; - - -static bool planeBoxOverlap(Vector3::Arg normal, Vector3::Arg vert, Vector3::Arg maxbox) // -NJMP- -{ - Vector3 vmin, vmax; - - float signs[3] = {1, 1, 1}; - if (normal.x() <= 0.0f) signs[0] = -1; - if (normal.y() <= 0.0f) signs[1] = -1; - if (normal.z() <= 0.0f) signs[2] = -1; - - Vector3 sign(signs[0], signs[1], signs[2]); - vmin = -scale(sign, maxbox) - vert; - vmax = scale(sign, maxbox) - vert; - - if (dot(normal, vmin) > 0.0f) return false; - if (dot(normal, vmax) >= 0.0f) return true; - - return false; -} - - -/*======================== X-tests ========================*/ -#define AXISTEST_X01(a, b, fa, fb) \ - p0 = a*v0.y() - b*v0.z(); \ - p2 = a*v2.y() - b*v2.z(); \ - if(p0rad || max<-rad) return false; - -#define AXISTEST_X2(a, b, fa, fb) \ - p0 = a*v0.y() - b*v0.z(); \ - p1 = a*v1.y() - b*v1.z(); \ - if(p0rad || max<-rad) return false; - -/*======================== Y-tests ========================*/ -#define AXISTEST_Y02(a, b, fa, fb) \ - p0 = -a*v0.x() + b*v0.z(); \ - p2 = -a*v2.x() + b*v2.z(); \ - if(p0rad || max<-rad) return false; - -#define AXISTEST_Y1(a, b, fa, fb) \ - p0 = -a*v0.x() + b*v0.z(); \ - p1 = -a*v1.x() + b*v1.z(); \ - if(p0rad || max<-rad) return false; - -/*======================== Z-tests ========================*/ - -#define AXISTEST_Z12(a, b, fa, fb) \ - p1 = a*v1.x() - b*v1.y(); \ - p2 = a*v2.x() - b*v2.y(); \ - if(p2rad || max<-rad) return false; - -#define AXISTEST_Z0(a, b, fa, fb) \ - p0 = a*v0.x() - b*v0.y(); \ - p1 = a*v1.x() - b*v1.y(); \ - if(p0rad || max<-rad) return false; - - -bool triBoxOverlap(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Triangle & tri) -{ - // use separating axis theorem to test overlap between triangle and box - // need to test for overlap in these directions: - // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle - // we do not even need to test these) - // 2) normal of the triangle - // 3) crossproduct(edge from tri, {x,y,z}-directin) - // this gives 3x3=9 more tests - Vector3 v0, v1, v2; - float min, max, p0, p1, p2, rad, fex, fey, fez; - Vector3 normal, e0, e1, e2; - - // This is the fastest branch on Sun. - // move everything so that the boxcenter is in (0,0,0) - v0 = tri.v[0] - boxcenter; - v1 = tri.v[1] - boxcenter; - v2 = tri.v[2] - boxcenter; - - // Compute triangle edges. - e0 = v1 - v0; // tri edge 0 - e1 = v2 - v1; // tri edge 1 - e2 = v0 - v2; // tri edge 2 - - // Bullet 3: - // test the 9 tests first (this was faster) - fex = fabsf(e0.x()); - fey = fabsf(e0.y()); - fez = fabsf(e0.z()); - AXISTEST_X01(e0.z(), e0.y(), fez, fey); - AXISTEST_Y02(e0.z(), e0.x(), fez, fex); - AXISTEST_Z12(e0.y(), e0.x(), fey, fex); - - fex = fabsf(e1.x()); - fey = fabsf(e1.y()); - fez = fabsf(e1.z()); - AXISTEST_X01(e1.z(), e1.y(), fez, fey); - AXISTEST_Y02(e1.z(), e1.x(), fez, fex); - AXISTEST_Z0(e1.y(), e1.x(), fey, fex); - - fex = fabsf(e2.x()); - fey = fabsf(e2.y()); - fez = fabsf(e2.z()); - AXISTEST_X2(e2.z(), e2.y(), fez, fey); - AXISTEST_Y1(e2.z(), e2.x(), fez, fex); - AXISTEST_Z12(e2.y(), e2.x(), fey, fex); - - // Bullet 1: - // first test overlap in the {x,y,z}-directions - // find min, max of the triangle each direction, and test for overlap in - // that direction -- this is equivalent to testing a minimal AABB around - // the triangle against the AABB - - // test in X-direction - FINDMINMAX(v0.x(), v1.x(), v2.x(), min, max); - if(min > boxhalfsize.x() || max < -boxhalfsize.x()) return false; - - // test in Y-direction - FINDMINMAX(v0.y(), v1.y(), v2.y(), min, max); - if(min > boxhalfsize.y() || max < -boxhalfsize.y()) return false; - - // test in Z-direction - FINDMINMAX(v0.z(), v1.z(), v2.z(), min, max); - if(min > boxhalfsize.z() || max < -boxhalfsize.z()) return false; - - // Bullet 2: - // test if the box intersects the plane of the triangle - // compute plane equation of triangle: normal*x+d=0 - normal = cross(e0, e1); - - return planeBoxOverlap(normal, v0, boxhalfsize); -} - - -bool triBoxOverlapNoBounds(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Triangle & tri) -{ - // use separating axis theorem to test overlap between triangle and box - // need to test for overlap in these directions: - // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle - // we do not even need to test these) - // 2) normal of the triangle - // 3) crossproduct(edge from tri, {x,y,z}-directin) - // this gives 3x3=9 more tests - Vector3 v0, v1, v2; - float min, max, p0, p1, p2, rad, fex, fey, fez; - Vector3 normal, e0, e1, e2; - - // This is the fastest branch on Sun. - // move everything so that the boxcenter is in (0,0,0) - v0 = tri.v[0] - boxcenter; - v1 = tri.v[1] - boxcenter; - v2 = tri.v[2] - boxcenter; - - // Compute triangle edges. - e0 = v1 - v0; // tri edge 0 - e1 = v2 - v1; // tri edge 1 - e2 = v0 - v2; // tri edge 2 - - // Bullet 3: - // test the 9 tests first (this was faster) - fex = fabsf(e0.x()); - fey = fabsf(e0.y()); - fez = fabsf(e0.z()); - AXISTEST_X01(e0.z(), e0.y(), fez, fey); - AXISTEST_Y02(e0.z(), e0.x(), fez, fex); - AXISTEST_Z12(e0.y(), e0.x(), fey, fex); - - fex = fabsf(e1.x()); - fey = fabsf(e1.y()); - fez = fabsf(e1.z()); - AXISTEST_X01(e1.z(), e1.y(), fez, fey); - AXISTEST_Y02(e1.z(), e1.x(), fez, fex); - AXISTEST_Z0(e1.y(), e1.x(), fey, fex); - - fex = fabsf(e2.x()); - fey = fabsf(e2.y()); - fez = fabsf(e2.z()); - AXISTEST_X2(e2.z(), e2.y(), fez, fey); - AXISTEST_Y1(e2.z(), e2.x(), fez, fex); - AXISTEST_Z12(e2.y(), e2.x(), fey, fex); - - // Bullet 2: - // test if the box intersects the plane of the triangle - // compute plane equation of triangle: normal*x+d=0 - normal = cross(e0, e1); - - return planeBoxOverlap(normal, v0, boxhalfsize); -} diff --git a/Externals/NVTT/src/nvmath/Triangle.cpp b/Externals/NVTT/src/nvmath/Triangle.cpp deleted file mode 100644 index 54902b9bc1f..00000000000 --- a/Externals/NVTT/src/nvmath/Triangle.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// This code is in the public domain -- Ignacio Castaño - -#include - -using namespace nv; - - -/// Tomas Möller, barycentric ray-triangle test. -bool rayTest_Moller(const Triangle & t, Vector3::Arg orig, Vector3::Arg dir, float * out_t, float * out_u, float * out_v) -{ - // find vectors for two edges sharing vert0 - Vector3 e1 = t.v[1] - t.v[0]; - Vector3 e2 = t.v[2] - t.v[0]; - - // begin calculating determinant - also used to calculate U parameter - Vector3 pvec = cross(dir, e2); - - // if determinant is near zero, ray lies in plane of triangle - float det = dot(e1, pvec); - if (det < -NV_EPSILON) { - return false; - } - - // calculate distance from vert0 to ray origin - Vector3 tvec = orig - t.v[0]; - - // calculate U parameter and test bounds - float u = dot(tvec, pvec); - if( u < 0.0f || u > det ) { - return false; - } - - // prepare to test V parameter - Vector3 qvec = cross(tvec, e1); - - // calculate V parameter and test bounds - float v = dot(dir, qvec); - if (v < 0.0f || u + v > det) { - return false; - } - - // calculate t, scale parameters, ray intersects triangle - float inv_det = 1.0f / det; - *out_t = dot(e2, qvec) * inv_det; - *out_u = u * inv_det; // v - *out_v = v * inv_det; // 1-(u+v) - - return true; -} - - - - - -#if 0 - - -// IC: This code is adapted from my Pi.MathLib code, based on Moller-Trumbore triangle test. -FXVector3 edge1, edge2, pvec, tvec, qvec; - -edge1 = tri.V1 - tri.V0; -edge2 = tri.V2 - tri.V0; - -pvec.Cross(ray.Direction, edge2); - -float det = FXVector3.Dot(edge1, pvec); - -// calculate distance from vert0 to ray origin. -FXVector3 tvec = ray.Origin - vert0; - -if( det < 0 ) -{ - // calculate U parameter and test bounds. - float u = FXVector3.Dot(tvec, pvec); - if (u > 0.0 || u < det) - { - return false; - } - - // prepare to test V parameter. - qvec.Cross(tvec, edge1); - - // calculate V parameter and test bounds. - float v = FXVector3.Dot(dir, qvec); - - return v <= 0.0 && u + v >= det; -} -else -{ - // calculate U parameter and test bounds. - float u = FXVector3.Dot(tvec, pvec); - if (u < 0.0 || u > det) - { - return false; - } - - // prepare to test V parameter. - qvec.Cross(tvec, edge1); - - // calculate V parameter and test bounds. - float v = FXVector3.Dot(dir, qvec); - - return v >= 0.0 && u + v <= det; -} - - - -/** - * Dan Sunday, parametric ray-triangle test. - */ -// Output: *I = intersection point (when it exists) -// Return: -1 = triangle is degenerate (a segment or point) -// 0 = disjoint (no intersect) -// 1 = intersect in unique point I1 -// 2 = are in the same plane -bool RayTriangleTest( const Vec3 &p0, const Vec3 &p1, - const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &n, - Vec3 &I ) { - Vec3 u, v; // triangle vectors - Vec3 dir, w0, w; // ray vectors - float r, a, b; // params to calc ray-plane intersect - - // get triangle edge vectors and plane normal - u.Sub( v1, v0 ); - v.Sub( v2, v0 ); - - dir.Sub( p1, p0 ); // ray direction vector - w0.Sub( p0, v0 ); - a = Vec3DotProduct( n, w0 ); - b = Vec3DotProduct( n, dir ); - - if( fabs(b) < TI_EPSILON ) // ray is parallel to triangle plane - return false; - - - // get intersect point of ray with triangle plane - r = -a / b; - if( r < 0.0f ) // ray goes away from triangle - return false; // => no intersect - - // for a segment, also test if (r > 1.0) => no intersect - - I.Mad( p0, dir, r ); // intersect point of ray and plane - - // is I inside T? - float uu, uv, vv, wu, wv, D; - uu = Vec3DotProduct( u, u ); - uv = Vec3DotProduct( u, v ); - vv = Vec3DotProduct( v, v ); - w = I - v0; - wu = Vec3DotProduct( w, u ); - wv = Vec3DotProduct( w, v ); - D = uv * uv - uu * vv; - - // get and test parametric coords - float s, t; - s = (uv * wv - vv * wu) / D; - if( s<0.0 || s > 1.0) // I is outside T - return false; - t = (uv * wu - uu * wv) / D; - if( t<0.0 || (s + t) > 1.0) // I is outside T - return false; - - return true; // I is in T -} - - -#endif // 0 diff --git a/Externals/NVTT/src/nvmath/Triangle.h b/Externals/NVTT/src/nvmath/Triangle.h deleted file mode 100644 index b3eb5a15c65..00000000000 --- a/Externals/NVTT/src/nvmath/Triangle.h +++ /dev/null @@ -1,81 +0,0 @@ -// This code is in the public domain -- Ignacio Castaño - -#ifndef NV_MATH_TRIANGLE_H -#define NV_MATH_TRIANGLE_H - -#include -#include -#include - -namespace nv -{ - - /// Triangle class with three vertices. - class Triangle - { - public: - Triangle() {}; - - Triangle(Vector3::Arg v0, Vector3::Arg v1, Vector3::Arg v2) - { - v[0] = v0; - v[1] = v1; - v[2] = v2; - } - - /// Get the bounds of the triangle. - Box bounds() const - { - Box bounds; - bounds.clearBounds(); - bounds.addPointToBounds(v[0]); - bounds.addPointToBounds(v[1]); - bounds.addPointToBounds(v[2]); - return bounds; - } - - Vector4 plane() const - { - Vector3 n = cross(v[1]-v[0], v[2]-v[0]); - return Vector4(n, dot(n, v[0])); - } - - Vector3 v[3]; - }; - - - // Tomas Akenine-Möller box-triangle test. - NVMATH_API bool triBoxOverlap(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Triangle & triangle); - NVMATH_API bool triBoxOverlapNoBounds(Vector3::Arg boxcenter, Vector3::Arg boxhalfsize, const Triangle & triangle); - - - // Moller ray triangle test. - NVMATH_API bool rayTest_Moller(const Triangle & t, Vector3::Arg orig, Vector3::Arg dir, float * out_t, float * out_u, float * out_v); - - inline bool rayTest(const Triangle & t, Vector3::Arg orig, Vector3::Arg dir, float * out_t, float * out_u, float * out_v) - { - return rayTest_Moller(t, orig, dir, out_t, out_u, out_v); - } - - inline bool overlap(const Triangle & t, const Box & b) - { - Vector3 center = b.center(); - Vector3 extents = b.extents(); - return triBoxOverlap(center, extents, t); - } - - inline bool overlap(const Box & b, const Triangle & t) - { - return overlap(t, b); - } - - inline bool overlapNoBounds(const Triangle & t, const Box & b) - { - Vector3 center = b.center(); - Vector3 extents = b.extents(); - return triBoxOverlapNoBounds(center, extents, t); - } - -} // nv namespace - -#endif // NV_MATH_TRIANGLE_H diff --git a/Externals/NVTT/src/nvmath/Vector.h b/Externals/NVTT/src/nvmath/Vector.h deleted file mode 100644 index bffdfbe3a00..00000000000 --- a/Externals/NVTT/src/nvmath/Vector.h +++ /dev/null @@ -1,805 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_VECTOR_H -#define NV_MATH_VECTOR_H - -#include -#include // min, max - -namespace nv -{ - -enum zero_t { zero }; -enum identity_t { identity }; - -// I should probably use templates. -typedef float scalar; - -class NVMATH_CLASS Vector2 -{ -public: - typedef Vector2 const & Arg; - - Vector2(); - explicit Vector2(zero_t); - explicit Vector2(scalar f); - Vector2(scalar x, scalar y); - Vector2(Vector2::Arg v); - - const Vector2 & operator=(Vector2::Arg v); - - scalar x() const; - scalar y() const; - - scalar component(uint idx) const; - - const scalar * ptr() const; - - void set(scalar x, scalar y); - - Vector2 operator-() const; - void operator+=(Vector2::Arg v); - void operator-=(Vector2::Arg v); - void operator*=(scalar s); - void operator*=(Vector2::Arg v); - - friend bool operator==(Vector2::Arg a, Vector2::Arg b); - friend bool operator!=(Vector2::Arg a, Vector2::Arg b); - -private: - scalar m_x, m_y; -}; - - -class NVMATH_CLASS Vector3 -{ -public: - typedef Vector3 const & Arg; - - Vector3(); - explicit Vector3(zero_t); - Vector3(scalar x, scalar y, scalar z); - Vector3(Vector2::Arg v, scalar z); - Vector3(Vector3::Arg v); - - const Vector3 & operator=(Vector3::Arg v); - - scalar x() const; - scalar y() const; - scalar z() const; - - const Vector2 & xy() const; - - scalar component(uint idx) const; - - const scalar * ptr() const; - - void set(scalar x, scalar y, scalar z); - - Vector3 operator-() const; - void operator+=(Vector3::Arg v); - void operator-=(Vector3::Arg v); - void operator*=(scalar s); - void operator/=(scalar s); - void operator*=(Vector3::Arg v); - - friend bool operator==(Vector3::Arg a, Vector3::Arg b); - friend bool operator!=(Vector3::Arg a, Vector3::Arg b); - -private: - scalar m_x, m_y, m_z; -}; - - -class NVMATH_CLASS Vector4 -{ -public: - typedef Vector4 const & Arg; - - Vector4(); - explicit Vector4(zero_t); - Vector4(scalar x, scalar y, scalar z, scalar w); - Vector4(Vector2::Arg v, scalar z, scalar w); - Vector4(Vector3::Arg v, scalar w); - Vector4(Vector4::Arg v); -// Vector4(const Quaternion & v); - - const Vector4 & operator=(Vector4::Arg v); - - scalar x() const; - scalar y() const; - scalar z() const; - scalar w() const; - - const Vector2 & xy() const; - const Vector3 & xyz() const; - - scalar component(uint idx) const; - - const scalar * ptr() const; - - void set(scalar x, scalar y, scalar z, scalar w); - - Vector4 operator-() const; - void operator+=(Vector4::Arg v); - void operator-=(Vector4::Arg v); - void operator*=(scalar s); - void operator*=(Vector4::Arg v); - - friend bool operator==(Vector4::Arg a, Vector4::Arg b); - friend bool operator!=(Vector4::Arg a, Vector4::Arg b); - -private: - scalar m_x, m_y, m_z, m_w; -}; - - -// Vector2 - -inline Vector2::Vector2() {} -inline Vector2::Vector2(zero_t) : m_x(0.0f), m_y(0.0f) {} -inline Vector2::Vector2(scalar f) : m_x(f), m_y(f) {} -inline Vector2::Vector2(scalar x, scalar y) : m_x(x), m_y(y) {} -inline Vector2::Vector2(Vector2::Arg v) : m_x(v.x()), m_y(v.y()) {} - -inline const Vector2 & Vector2::operator=(Vector2::Arg v) -{ - m_x = v.x(); - m_y = v.y(); - return *this; -} - -inline scalar Vector2::x() const { return m_x; } -inline scalar Vector2::y() const { return m_y; } - -inline scalar Vector2::component(uint idx) const -{ - nvDebugCheck(idx < 2); - if (idx == 0) return x(); - if (idx == 1) return y(); - nvAssume(false); - return 0.0f; -} - -inline const scalar * Vector2::ptr() const -{ - return &m_x; -} - -inline void Vector2::set(scalar x, scalar y) -{ - m_x = x; - m_y = y; -} - -inline Vector2 Vector2::operator-() const -{ - return Vector2(-m_x, -m_y); -} - -inline void Vector2::operator+=(Vector2::Arg v) -{ - m_x += v.m_x; - m_y += v.m_y; -} - -inline void Vector2::operator-=(Vector2::Arg v) -{ - m_x -= v.m_x; - m_y -= v.m_y; -} - -inline void Vector2::operator*=(scalar s) -{ - m_x *= s; - m_y *= s; -} - -inline void Vector2::operator*=(Vector2::Arg v) -{ - m_x *= v.m_x; - m_y *= v.m_y; -} - -inline bool operator==(Vector2::Arg a, Vector2::Arg b) -{ - return a.m_x == b.m_x && a.m_y == b.m_y; -} -inline bool operator!=(Vector2::Arg a, Vector2::Arg b) -{ - return a.m_x != b.m_x || a.m_y != b.m_y; -} - - -// Vector3 - -inline Vector3::Vector3() {} -inline Vector3::Vector3(zero_t) : m_x(0.0f), m_y(0.0f), m_z(0.0f) {} -inline Vector3::Vector3(scalar x, scalar y, scalar z) : m_x(x), m_y(y), m_z(z) {} -inline Vector3::Vector3(Vector2::Arg v, scalar z) : m_x(v.x()), m_y(v.y()), m_z(z) {} -inline Vector3::Vector3(Vector3::Arg v) : m_x(v.x()), m_y(v.y()), m_z(v.z()) {} - -inline const Vector3 & Vector3::operator=(Vector3::Arg v) -{ - m_x = v.m_x; - m_y = v.m_y; - m_z = v.m_z; - return *this; -} - -inline scalar Vector3::x() const { return m_x; } -inline scalar Vector3::y() const { return m_y; } -inline scalar Vector3::z() const { return m_z; } - -inline const Vector2 & Vector3::xy() const -{ - return *(Vector2 *)this; -} - -inline scalar Vector3::component(uint idx) const -{ - nvDebugCheck(idx < 3); - if (idx == 0) return x(); - if (idx == 1) return y(); - if (idx == 2) return z(); - nvAssume(false); - return 0.0f; -} - -inline const scalar * Vector3::ptr() const -{ - return &m_x; -} - -inline void Vector3::set(scalar x, scalar y, scalar z) -{ - m_x = x; - m_y = y; - m_z = z; -} - -inline Vector3 Vector3::operator-() const -{ - return Vector3(-m_x, -m_y, -m_z); -} - -inline void Vector3::operator+=(Vector3::Arg v) -{ - m_x += v.m_x; - m_y += v.m_y; - m_z += v.m_z; -} - -inline void Vector3::operator-=(Vector3::Arg v) -{ - m_x -= v.m_x; - m_y -= v.m_y; - m_z -= v.m_z; -} - -inline void Vector3::operator*=(scalar s) -{ - m_x *= s; - m_y *= s; - m_z *= s; -} - -inline void Vector3::operator/=(scalar s) -{ - float is = 1.0f / s; - m_x *= is; - m_y *= is; - m_z *= is; -} - -inline void Vector3::operator*=(Vector3::Arg v) -{ - m_x *= v.m_x; - m_y *= v.m_y; - m_z *= v.m_z; -} - -inline bool operator==(Vector3::Arg a, Vector3::Arg b) -{ - return a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z; -} -inline bool operator!=(Vector3::Arg a, Vector3::Arg b) -{ - return a.m_x != b.m_x || a.m_y != b.m_y || a.m_z != b.m_z; -} - - -// Vector4 - -inline Vector4::Vector4() {} -inline Vector4::Vector4(zero_t) : m_x(0.0f), m_y(0.0f), m_z(0.0f), m_w(0.0f) {} -inline Vector4::Vector4(scalar x, scalar y, scalar z, scalar w) : m_x(x), m_y(y), m_z(z), m_w(w) {} -inline Vector4::Vector4(Vector2::Arg v, scalar z, scalar w) : m_x(v.x()), m_y(v.y()), m_z(z), m_w(w) {} -inline Vector4::Vector4(Vector3::Arg v, scalar w) : m_x(v.x()), m_y(v.y()), m_z(v.z()), m_w(w) {} -inline Vector4::Vector4(Vector4::Arg v) : m_x(v.x()), m_y(v.y()), m_z(v.z()), m_w(v.w()) {} - -inline const Vector4 & Vector4::operator=(const Vector4 & v) -{ - m_x = v.m_x; - m_y = v.m_y; - m_z = v.m_z; - m_w = v.m_w; - return *this; -} - -inline scalar Vector4::x() const { return m_x; } -inline scalar Vector4::y() const { return m_y; } -inline scalar Vector4::z() const { return m_z; } -inline scalar Vector4::w() const { return m_w; } - -inline const Vector2 & Vector4::xy() const -{ - return *(Vector2 *)this; -} - -inline const Vector3 & Vector4::xyz() const -{ - return *(Vector3 *)this; -} - -inline scalar Vector4::component(uint idx) const -{ - nvDebugCheck(idx < 4); - if (idx == 0) return x(); - if (idx == 1) return y(); - if (idx == 2) return z(); - if (idx == 3) return w(); - nvAssume(false); - return 0.0f; -} - -inline const scalar * Vector4::ptr() const -{ - return &m_x; -} - -inline void Vector4::set(scalar x, scalar y, scalar z, scalar w) -{ - m_x = x; - m_y = y; - m_z = z; - m_w = w; -} - -inline Vector4 Vector4::operator-() const -{ - return Vector4(-m_x, -m_y, -m_z, -m_w); -} - -inline void Vector4::operator+=(Vector4::Arg v) -{ - m_x += v.m_x; - m_y += v.m_y; - m_z += v.m_z; - m_w += v.m_w; -} - -inline void Vector4::operator-=(Vector4::Arg v) -{ - m_x -= v.m_x; - m_y -= v.m_y; - m_z -= v.m_z; - m_w -= v.m_w; -} - -inline void Vector4::operator*=(scalar s) -{ - m_x *= s; - m_y *= s; - m_z *= s; - m_w *= s; -} - -inline void Vector4::operator*=(Vector4::Arg v) -{ - m_x *= v.m_x; - m_y *= v.m_y; - m_z *= v.m_z; - m_w *= v.m_w; -} - -inline bool operator==(Vector4::Arg a, Vector4::Arg b) -{ - return a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z && a.m_w == b.m_w; -} -inline bool operator!=(Vector4::Arg a, Vector4::Arg b) -{ - return a.m_x != b.m_x || a.m_y != b.m_y || a.m_z != b.m_z || a.m_w != b.m_w; -} - - - -// Functions - - -// Vector2 - -inline Vector2 add(Vector2::Arg a, Vector2::Arg b) -{ - return Vector2(a.x() + b.x(), a.y() + b.y()); -} -inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b) -{ - return add(a, b); -} - -inline Vector2 sub(Vector2::Arg a, Vector2::Arg b) -{ - return Vector2(a.x() - b.x(), a.y() - b.y()); -} -inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b) -{ - return sub(a, b); -} - -inline Vector2 scale(Vector2::Arg v, scalar s) -{ - return Vector2(v.x() * s, v.y() * s); -} - -inline Vector2 scale(Vector2::Arg v, Vector2::Arg s) -{ - return Vector2(v.x() * s.x(), v.y() * s.y()); -} - -inline Vector2 operator*(Vector2::Arg v, scalar s) -{ - return scale(v, s); -} - -inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2) -{ - return Vector2(v1.x()*v2.x(), v1.y()*v2.y()); -} - -inline Vector2 operator*(scalar s, Vector2::Arg v) -{ - return scale(v, s); -} - -inline scalar dot(Vector2::Arg a, Vector2::Arg b) -{ - return a.x() * b.x() + a.y() * b.y(); -} - -inline scalar length_squared(Vector2::Arg v) -{ - return v.x() * v.x() + v.y() * v.y(); -} - -inline scalar length(Vector2::Arg v) -{ - return sqrtf(length_squared(v)); -} - -inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON) -{ - return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon); -} - -inline Vector2 min(Vector2::Arg a, Vector2::Arg b) -{ - return Vector2(min(a.x(), b.x()), min(a.y(), b.y())); -} - -inline Vector2 max(Vector2::Arg a, Vector2::Arg b) -{ - return Vector2(max(a.x(), b.x()), max(a.y(), b.y())); -} - -inline bool isValid(Vector2::Arg v) -{ - return isFinite(v.x()) && isFinite(v.y()); -} - - -// Vector3 - -inline Vector3 add(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(a.x() + b.x(), a.y() + b.y(), a.z() + b.z()); -} -inline Vector3 add(Vector3::Arg a, float b) -{ - return Vector3(a.x() + b, a.y() + b, a.z() + b); -} -inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b) -{ - return add(a, b); -} -inline Vector3 operator+(Vector3::Arg a, float b) -{ - return add(a, b); -} - -inline Vector3 sub(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(a.x() - b.x(), a.y() - b.y(), a.z() - b.z()); -} -inline Vector3 sub(Vector3::Arg a, float b) -{ - return Vector3(a.x() - b, a.y() - b, a.z() - b); -} -inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b) -{ - return sub(a, b); -} -inline Vector3 operator-(Vector3::Arg a, float b) -{ - return sub(a, b); -} - -inline Vector3 cross(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(a.y() * b.z() - a.z() * b.y(), a.z() * b.x() - a.x() * b.z(), a.x() * b.y() - a.y() * b.x()); -} - -inline Vector3 scale(Vector3::Arg v, scalar s) -{ - return Vector3(v.x() * s, v.y() * s, v.z() * s); -} - -inline Vector3 scale(Vector3::Arg v, Vector3::Arg s) -{ - return Vector3(v.x() * s.x(), v.y() * s.y(), v.z() * s.z()); -} - -inline Vector3 operator*(Vector3::Arg v, scalar s) -{ - return scale(v, s); -} - -inline Vector3 operator*(scalar s, Vector3::Arg v) -{ - return scale(v, s); -} - -inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s) -{ - return scale(v, s); -} - -inline Vector3 operator/(Vector3::Arg v, scalar s) -{ - return scale(v, 1.0f/s); -} - -inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, scalar s) -{ - return Vector3(a.x() + b.x() * s, a.y() + b.y() * s, a.z() + b.z() * s); -} - -inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, scalar t) -{ - const scalar s = 1.0f - t; - return Vector3(v1.x() * s + t * v2.x(), v1.y() * s + t * v2.y(), v1.z() * s + t * v2.z()); -} - -inline scalar dot(Vector3::Arg a, Vector3::Arg b) -{ - return a.x() * b.x() + a.y() * b.y() + a.z() * b.z(); -} - -inline scalar length_squared(Vector3::Arg v) -{ - return v.x() * v.x() + v.y() * v.y() + v.z() * v.z(); -} - -inline scalar length(Vector3::Arg v) -{ - return sqrtf(length_squared(v)); -} - -inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON) -{ - return equal(length(v), 1, epsilon); -} - -inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON) -{ - float l = length(v); - nvDebugCheck(!isZero(l, epsilon)); - Vector3 n = scale(v, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; -} - -inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON) -{ - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return scale(v, 1.0f / l); -} - -inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON) -{ - return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon) && equal(v1.z(), v2.z(), epsilon); -} - -inline Vector3 min(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(min(a.x(), b.x()), min(a.y(), b.y()), min(a.z(), b.z())); -} - -inline Vector3 max(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(max(a.x(), b.x()), max(a.y(), b.y()), max(a.z(), b.z())); -} - -inline Vector3 clamp(Vector3::Arg v, float min, float max) -{ - return Vector3(clamp(v.x(), min, max), clamp(v.y(), min, max), clamp(v.z(), min, max)); -} - -inline bool isValid(Vector3::Arg v) -{ - return isFinite(v.x()) && isFinite(v.y()) && isFinite(v.z()); -} - -/* -Vector3 transform(Quaternion, vector3); -Vector3 transform_point(matrix34, vector3); -Vector3 transform_vector(matrix34, vector3); -Vector3 transform_point(matrix44, vector3); -Vector3 transform_vector(matrix44, vector3); -*/ - -// Vector4 - -inline Vector4 add(Vector4::Arg a, Vector4::Arg b) -{ - return Vector4(a.x() + b.x(), a.y() + b.y(), a.z() + b.z(), a.w() + b.w()); -} -inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b) -{ - return add(a, b); -} - -inline Vector4 sub(Vector4::Arg a, Vector4::Arg b) -{ - return Vector4(a.x() - b.x(), a.y() - b.y(), a.z() - b.z(), a.w() - b.w()); -} -inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b) -{ - return sub(a, b); -} - -inline Vector4 scale(Vector4::Arg v, scalar s) -{ - return Vector4(v.x() * s, v.y() * s, v.z() * s, v.w() * s); -} - -inline Vector4 scale(Vector4::Arg v, Vector4::Arg s) -{ - return Vector4(v.x() * s.x(), v.y() * s.y(), v.z() * s.z(), v.w() * s.w()); -} - -inline Vector4 operator*(Vector4::Arg v, scalar s) -{ - return scale(v, s); -} - -inline Vector4 operator*(scalar s, Vector4::Arg v) -{ - return scale(v, s); -} - -inline Vector4 operator/(Vector4::Arg v, scalar s) -{ - return scale(v, 1.0f/s); -} - -inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, scalar s) -{ - return Vector4(a.x() + b.x() * s, a.y() + b.y() * s, a.z() + b.z() * s, a.w() + b.w() * s); -} - -inline scalar dot(Vector4::Arg a, Vector4::Arg b) -{ - return a.x() * b.x() + a.y() * b.y() + a.z() * b.z() + a.w() * b.w(); -} - -inline scalar length_squared(Vector4::Arg v) -{ - return v.x() * v.x() + v.y() * v.y() + v.z() * v.z() + v.w() * v.w(); -} - -inline scalar length(Vector4::Arg v) -{ - return sqrtf(length_squared(v)); -} - -inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON) -{ - return equal(length(v), 1, epsilon); -} - -inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON) -{ - float l = length(v); - nvDebugCheck(!isZero(l, epsilon)); - Vector4 n = scale(v, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; -} - -inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON) -{ - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return scale(v, 1.0f / l); -} - -inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON) -{ - return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon) && equal(v1.z(), v2.z(), epsilon) && equal(v1.w(), v2.w(), epsilon); -} - -inline Vector4 min(Vector4::Arg a, Vector4::Arg b) -{ - return Vector4(min(a.x(), b.x()), min(a.y(), b.y()), min(a.z(), b.z()), min(a.w(), b.w())); -} - -inline Vector4 max(Vector4::Arg a, Vector4::Arg b) -{ - return Vector4(max(a.x(), b.x()), max(a.y(), b.y()), max(a.z(), b.z()), max(a.w(), b.w())); -} - -inline bool isValid(Vector4::Arg v) -{ - return isFinite(v.x()) && isFinite(v.y()) && isFinite(v.z()) && isFinite(v.w()); -} - - - -/* -vector4 transform(matrix34, vector4); -vector4 transform(matrix44, vector4); -*/ - -/* -Quaternion mul(Quaternion, Quaternion); // rotational composition -Quaternion conjugate(Quaternion); -Quaternion inverse(Quaternion); -Quaternion axis_angle(const Vector3 & v, scalar s); -*/ - -/* -matrix34 add(matrix34, matrix34); // note: implicit '1' stays as '1' -matrix34 operator+(matrix34, matrix34); -matrix34 sub(matrix34, matrix34); // note: implicit '1' stays as '1' -matrix34 operator-(matrix34, matrix34); -matrix34 mul(matrix34, matrix34); -matrix34 operator*(matrix34, matrix34); -matrix34 mul(matrix34, quaternion4); // rotation multiplication -matrix34 operator*(matrix34, quaternion4); // rotation multiplication -matrix34 translation(vector3); -matrix34 rotation(quaternion4); -matrix34 rotation(vector3, scalar); // axis/angle - -matrix44 add(matrix44, matrix44); -matrix44 operator+(matrix44, matrix44); -matrix44 sub(matrix44, matrix44); -matrix44 operator-(matrix44, matrix44); -matrix44 mul(matrix44, matrix44); -matrix44 operator*(matrix44, matrix44); -matrix44 mul(matrix44, quaternion4); // rotation multiplication -matrix44 operator*(matrix44, quaternion4); // rotation multiplication -matrix44 invert(matrix34); -matrix44 invert(matrix44); -matrix44 transpose(matrix34); -matrix44 transpose(matrix44); -*/ - -} // nv namespace - -#endif // NV_MATH_VECTOR_H diff --git a/Externals/NVTT/src/nvmath/nvmath.h b/Externals/NVTT/src/nvmath/nvmath.h deleted file mode 100644 index 6699960e476..00000000000 --- a/Externals/NVTT/src/nvmath/nvmath.h +++ /dev/null @@ -1,166 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#ifndef NV_MATH_H -#define NV_MATH_H - -#include -#include - -#include - -// Function linkage -#if NVMATH_SHARED -#ifdef NVMATH_EXPORTS -#define NVMATH_API DLL_EXPORT -#define NVMATH_CLASS DLL_EXPORT_CLASS -#else -#define NVMATH_API DLL_IMPORT -#define NVMATH_CLASS DLL_IMPORT -#endif -#else // NVMATH_SHARED -#define NVMATH_API -#define NVMATH_CLASS -#endif // NVMATH_SHARED - -#ifndef PI -#define PI float(3.1415926535897932384626433833) -#endif - -#define NV_EPSILON (0.0001f) -#define NV_NORMAL_EPSILON (0.001f) - -/* -#define SQ(r) ((r)*(r)) - -#define SIGN_BITMASK 0x80000000 - -/// Integer representation of a floating-point value. -#define IR(x) ((uint32 &)(x)) - -/// Absolute integer representation of a floating-point value -#define AIR(x) (IR(x) & 0x7fffffff) - -/// Floating-point representation of an integer value. -#define FR(x) ((float&)(x)) - -/// Integer-based comparison of a floating point value. -/// Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context. -#define IS_NEGATIVE_FLOAT(x) (IR(x)&SIGN_BITMASK) -*/ - -inline double sqrt_assert(const double f) -{ - nvDebugCheck(f >= 0.0f); - return sqrt(f); -} - -inline float sqrtf_assert(const float f) -{ - nvDebugCheck(f >= 0.0f); - return sqrtf(f); -} - -inline double acos_assert(const double f) -{ - nvDebugCheck(f >= -1.0f && f <= 1.0f); - return acos(f); -} - -inline float acosf_assert(const float f) -{ - nvDebugCheck(f >= -1.0f && f <= 1.0f); - return acosf(f); -} - -inline double asin_assert(const double f) -{ - nvDebugCheck(f >= -1.0f && f <= 1.0f); - return asin(f); -} - -inline float asinf_assert(const float f) -{ - nvDebugCheck(f >= -1.0f && f <= 1.0f); - return asinf(f); -} - -// Replace default functions with asserting ones. -#if ! defined(_MSC_VER) || (defined(_MSC_VER) && (_MSC_VER<1700)) -#define sqrt sqrt_assert -#define sqrtf sqrtf_assert -#define acos acos_assert -#define acosf acosf_assert -#define asin asin_assert -#define asinf asinf_assert -#endif - -#if NV_OS_WIN32 -#include -#endif - -namespace nv -{ -inline float toRadian(float degree) { return degree * (PI / 180.0f); } -inline float toDegree(float radian) { return radian * (180.0f / PI); } - -inline bool equal(const float f0, const float f1, const float epsilon = NV_EPSILON) -{ - return fabs(f0-f1) <= epsilon; -} - -inline bool isZero(const float f, const float epsilon = NV_EPSILON) -{ - return fabs(f) <= epsilon; -} - -inline bool isFinite(const float f) -{ -#if NV_OS_WIN32 && !NV_CC_GNUC - return _finite(f) != 0; -#elif NV_OS_DARWIN || NV_CC_GNUC - return isfinite(f); -#elif NV_OS_LINUX - return finitef(f); -#else -# error "isFinite not supported" -#endif -//return std::isfinite (f); -//return finite (f); -} - -inline bool isNan(const float f) -{ -#if NV_OS_WIN32 && !NV_CC_GNUC - return _isnan(f) != 0; -#elif NV_OS_DARWIN || NV_CC_GNUC - return isnan(f); -#elif NV_OS_LINUX - return isnanf(f); -#else -# error "isNan not supported" -#endif -} - -inline uint log2(uint i) -{ - uint value = 0; - while( i >>= 1 ) { - value++; - } - return value; -} - -inline float lerp(float f0, float f1, float t) -{ - const float s = 1.0f - t; - return f0 * s + f1 * t; -} - -inline float square(float f) -{ - return f * f; -} - -} // nv - -#endif // NV_MATH_H diff --git a/Externals/NVTT/src/nvtt/CMakeLists.txt b/Externals/NVTT/src/nvtt/CMakeLists.txt deleted file mode 100644 index bfa58f4b834..00000000000 --- a/Externals/NVTT/src/nvtt/CMakeLists.txt +++ /dev/null @@ -1,139 +0,0 @@ -add_subdirectory(squish) - -option(NVTT_SHARED "Build nvtt as shared library" OFF) -option(NVTT_BUILD_TEST_EXECUTABLES "Build nvtt test executables" OFF) -option(NVTT_BUILD_UI_TOOLS "Build nvtt UI tools" OFF) - -if (NVTT_SHARED) - add_library(nvtt SHARED) - - target_compile_definitions(nvtt - PRIVATE - NVTT_SHARED - ) -else() - add_library(nvtt STATIC) -endif() - -target_sources(nvtt PRIVATE - nvtt.h - nvtt.cpp - Compressor.h - Compressor.cpp - nvtt_wrapper.h - nvtt_wrapper.cpp - CompressDXT.h - CompressDXT.cpp - CompressRGB.h - CompressRGB.cpp - QuickCompressDXT.h - QuickCompressDXT.cpp - OptimalCompressDXT.h - OptimalCompressDXT.cpp - SingleColorLookup.h - CompressionOptions.h - CompressionOptions.cpp - InputOptions.h - InputOptions.cpp - OutputOptions.h - OutputOptions.cpp - cuda/CudaUtils.h - cuda/CudaUtils.cpp - cuda/CudaMath.h - cuda/Bitmaps.h - cuda/CudaCompressDXT.h - cuda/CudaCompressDXT.cpp -) - -if (CUDA_FOUND) - wrap_cuda(CUDA_SRCS cuda/CompressKernel.cu) - list(APPEND SRC_FILES ${CUDA_SRCS}) -endif() - -target_include_directories(nvtt - PRIVATE - $<$:${CUDA_INCLUDE_PATH}> -) - -target_link_libraries(nvtt - PUBLIC - nvcore - nvmath - nvimage - PRIVATE - squish - $<$:${CUDA_LIBRARIES}> -) - -# TODO use configure_file for nvconfig.h - -target_compile_definitions(nvtt - PRIVATE - NVTT_EXPORTS - HAVE_SIGNAL_H - HAVE_EXECINFO_H - $<$:HAVE_CUDA> -) - -set_target_properties(nvtt PROPERTIES - UNITY_BUILD OFF -) - -install(TARGETS nvtt LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} -) - -install(FILES nvtt.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nvtt") - -if (NVTT_TEST_EXECUTABLES) - add_executable(nvcompress tools/compress.cpp tools/cmdline.h) - target_link_libraries(nvcompress nvtt) - - add_executable(nvdecompress tools/decompress.cpp tools/cmdline.h) - target_link_libraries(nvdecompress nvmath nvimage) - - add_executable(nvddsinfo tools/ddsinfo.cpp tools/cmdline.h) - target_link_libraries(nvddsinfo nvmath nvimage) - - add_executable(nvimgdiff tools/imgdiff.cpp tools/cmdline.h) - target_link_libraries(nvimgdiff nvmath nvimage) - - add_executable(nvassemble tools/assemble.cpp tools/cmdline.h) - target_link_libraries(nvassemble nvmath nvimage) - - add_executable(filtertest tests/filtertest.cpp tools/cmdline.h) - target_link_libraries(filtertest nvmath nvimage) - - add_executable(nvzoom tools/resize.cpp tools/cmdline.h) - target_link_libraries(nvzoom nvmath nvimage) - - install(TARGETS nvcompress nvdecompress nvddsinfo nvimgdiff nvassemble nvzoom - DESTINATION "${CMAKE_INSTALL_BINDIR}" - ) -endif() - -if (NVTT_BUILD_UI_TOOLS) - find_package(Qt5 COMPONENTS Core Widgets OpenGL) - - if (Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5OpenGL_FOUND) - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTOUIC ON) - - add_executable(nvcompressui) - - target_sources(nvcompressui PRIVATE - tools/main.cpp - tools/configdialog.h - tools/configdialog.cpp - tools/configdialog.ui - ) - - target_link_libraries(nvcompressui - PRIVATE - nvtt - Qt5::Core - Qt5::Widgets - Qt5::OpenGL - ) - endif() -endif() diff --git a/Externals/NVTT/src/nvtt/CompressDXT.cpp b/Externals/NVTT/src/nvtt/CompressDXT.cpp deleted file mode 100644 index 005cdecfafa..00000000000 --- a/Externals/NVTT/src/nvtt/CompressDXT.cpp +++ /dev/null @@ -1,597 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include -#include -#include - -#include "nvtt.h" -#include "CompressDXT.h" -#include "QuickCompressDXT.h" -#include "OptimalCompressDXT.h" -#include "CompressionOptions.h" -#include "OutputOptions.h" - -// squish -#include "squish/colourset.h" - -#include "squish/fastclusterfit.h" -#include "squish/weightedclusterfit.h" - - -// s3_quant -#if defined(HAVE_S3QUANT) -#include "s3tc/s3_quant.h" -#endif - -// ati tc -#if defined(HAVE_ATITC) -#include "atitc/ATI_Compress.h" -#endif - - - -using namespace nv; -using namespace nvtt; - - -nv::FastCompressor::FastCompressor() : m_image(NULL), m_alphaMode(AlphaMode_None) -{ -} - -nv::FastCompressor::~FastCompressor() -{ -} - -void nv::FastCompressor::setImage(const Image * image, nvtt::AlphaMode alphaMode) -{ - m_image = image; - m_alphaMode = alphaMode; -} - -void nv::FastCompressor::compressDXT1(const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT1 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - rgba.init(m_image, x, y); - - QuickCompress::compressDXT1(rgba, &block); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::FastCompressor::compressDXT1a(const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT1 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - rgba.init(m_image, x, y); - - QuickCompress::compressDXT1a(rgba, &block); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::FastCompressor::compressDXT3(const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT3 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - rgba.init(m_image, x, y); - - QuickCompress::compressDXT3(rgba, &block); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::FastCompressor::compressDXT5(const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT5 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - rgba.init(m_image, x, y); - - QuickCompress::compressDXT5(rgba, &block, 0); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::FastCompressor::compressDXT5n(const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT5 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - rgba.init(m_image, x, y); - - rgba.swizzleDXT5n(); - - QuickCompress::compressDXT5(rgba, &block, 0); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -nv::SlowCompressor::SlowCompressor() : m_image(NULL), m_alphaMode(AlphaMode_None) -{ -} - -nv::SlowCompressor::~SlowCompressor() -{ -} - -void nv::SlowCompressor::setImage(const Image * image, nvtt::AlphaMode alphaMode) -{ - m_image = image; - m_alphaMode = alphaMode; -} - -void nv::SlowCompressor::compressDXT1(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT1 block; - - squish::WeightedClusterFit fit; - //squish::ClusterFit fit; - //squish::FastClusterFit fit; - fit.SetMetric(compressionOptions.colorWeight.x(), compressionOptions.colorWeight.y(), compressionOptions.colorWeight.z()); - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - if (rgba.isSingleColor()) - { - OptimalCompress::compressDXT1(rgba.color(0), &block); - } - else - { - squish::ColourSet colours((uint8 *)rgba.colors(), 0, true); - fit.SetColourSet(&colours, squish::kDxt1); - fit.Compress(&block); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::SlowCompressor::compressDXT1a(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT1 block; - - squish::WeightedClusterFit fit; - fit.SetMetric(compressionOptions.colorWeight.x(), compressionOptions.colorWeight.y(), compressionOptions.colorWeight.z()); - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - bool anyAlpha = false; - bool allAlpha = true; - - for (uint i = 0; i < 16; i++) - { - if (rgba.color(i).a < 128) anyAlpha = true; - else allAlpha = false; - } - - if ((!anyAlpha && rgba.isSingleColor() || allAlpha)) - { - OptimalCompress::compressDXT1a(rgba.color(0), &block); - } - else - { - squish::ColourSet colours((uint8 *)rgba.colors(), squish::kDxt1|squish::kWeightColourByAlpha); - fit.SetColourSet(&colours, squish::kDxt1); - fit.Compress(&block); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::SlowCompressor::compressDXT3(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT3 block; - - squish::WeightedClusterFit fit; - //squish::FastClusterFit fit; - fit.SetMetric(compressionOptions.colorWeight.x(), compressionOptions.colorWeight.y(), compressionOptions.colorWeight.z()); - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - // Compress explicit alpha. - OptimalCompress::compressDXT3A(rgba, &block.alpha); - - // Compress color. - if (rgba.isSingleColor()) - { - OptimalCompress::compressDXT1(rgba.color(0), &block.color); - } - else - { - squish::ColourSet colours((uint8 *)rgba.colors(), squish::kWeightColourByAlpha); - fit.SetColourSet(&colours, 0); - fit.Compress(&block.color); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - -void nv::SlowCompressor::compressDXT5(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT5 block; - - squish::WeightedClusterFit fit; - fit.SetMetric(compressionOptions.colorWeight.x(), compressionOptions.colorWeight.y(), compressionOptions.colorWeight.z()); - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - // Compress alpha. - if (compressionOptions.quality == Quality_Highest) - { - OptimalCompress::compressDXT5A(rgba, &block.alpha); - } - else - { - QuickCompress::compressDXT5A(rgba, &block.alpha); - } - - // Compress color. - if (rgba.isSingleColor()) - { - OptimalCompress::compressDXT1(rgba.color(0), &block.color); - } - else - { - squish::ColourSet colours((uint8 *)rgba.colors(), squish::kWeightColourByAlpha); - fit.SetColourSet(&colours, 0); - fit.Compress(&block.color); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::SlowCompressor::compressDXT5n(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - BlockDXT5 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - rgba.swizzleDXT5n(); - - // Compress X. - if (compressionOptions.quality == Quality_Highest) - { - OptimalCompress::compressDXT5A(rgba, &block.alpha); - } - else - { - QuickCompress::compressDXT5A(rgba, &block.alpha); - } - - // Compress Y. - OptimalCompress::compressDXT1G(rgba, &block.color); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::SlowCompressor::compressBC4(const CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock rgba; - AlphaBlockDXT5 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - rgba.init(m_image, x, y); - - if (compressionOptions.quality == Quality_Highest) - { - OptimalCompress::compressDXT5A(rgba, &block); - } - else - { - QuickCompress::compressDXT5A(rgba, &block); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -void nv::SlowCompressor::compressBC5(const CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = m_image->width(); - const uint h = m_image->height(); - - ColorBlock xcolor; - ColorBlock ycolor; - - BlockATI2 block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - - xcolor.init(m_image, x, y); - xcolor.splatX(); - - ycolor.init(m_image, x, y); - ycolor.splatY(); - - if (compressionOptions.quality == Quality_Highest) - { - OptimalCompress::compressDXT5A(xcolor, &block.x); - OptimalCompress::compressDXT5A(ycolor, &block.y); - } - else - { - QuickCompress::compressDXT5A(xcolor, &block.x); - QuickCompress::compressDXT5A(ycolor, &block.y); - } - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&block, sizeof(block)); - } - } - } -} - - -#if defined(HAVE_S3QUANT) - -void nv::s3CompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions) -{ - const uint w = image->width(); - const uint h = image->height(); - - float error = 0.0f; - - BlockDXT1 dxtBlock3; - BlockDXT1 dxtBlock4; - ColorBlock block; - - for (uint y = 0; y < h; y += 4) { - for (uint x = 0; x < w; x += 4) { - block.init(image, x, y); - - // Init rgb block. - RGBBlock rgbBlock; - rgbBlock.n = 16; - for (uint i = 0; i < 16; i++) { - rgbBlock.colorChannel[i][0] = clamp(float(block.color(i).r) / 255.0f, 0.0f, 1.0f); - rgbBlock.colorChannel[i][1] = clamp(float(block.color(i).g) / 255.0f, 0.0f, 1.0f); - rgbBlock.colorChannel[i][2] = clamp(float(block.color(i).b) / 255.0f, 0.0f, 1.0f); - } - rgbBlock.weight[0] = 1.0f; - rgbBlock.weight[1] = 1.0f; - rgbBlock.weight[2] = 1.0f; - - rgbBlock.inLevel = 4; - CodeRGBBlock(&rgbBlock); - - // Copy results to DXT block. - dxtBlock4.col0.r = rgbBlock.endPoint[0][0]; - dxtBlock4.col0.g = rgbBlock.endPoint[0][1]; - dxtBlock4.col0.b = rgbBlock.endPoint[0][2]; - - dxtBlock4.col1.r = rgbBlock.endPoint[1][0]; - dxtBlock4.col1.g = rgbBlock.endPoint[1][1]; - dxtBlock4.col1.b = rgbBlock.endPoint[1][2]; - - dxtBlock4.setIndices(rgbBlock.index); - - if (dxtBlock4.col0.u < dxtBlock4.col1.u) { - swap(dxtBlock4.col0.u, dxtBlock4.col1.u); - dxtBlock4.indices ^= 0x55555555; - } - - uint error4 = blockError(block, dxtBlock4); - - rgbBlock.inLevel = 3; - - CodeRGBBlock(&rgbBlock); - - // Copy results to DXT block. - dxtBlock3.col0.r = rgbBlock.endPoint[0][0]; - dxtBlock3.col0.g = rgbBlock.endPoint[0][1]; - dxtBlock3.col0.b = rgbBlock.endPoint[0][2]; - - dxtBlock3.col1.r = rgbBlock.endPoint[1][0]; - dxtBlock3.col1.g = rgbBlock.endPoint[1][1]; - dxtBlock3.col1.b = rgbBlock.endPoint[1][2]; - - dxtBlock3.setIndices(rgbBlock.index); - - if (dxtBlock3.col0.u > dxtBlock3.col1.u) { - swap(dxtBlock3.col0.u, dxtBlock3.col1.u); - dxtBlock3.indices ^= (~dxtBlock3.indices >> 1) & 0x55555555; - } - - uint error3 = blockError(block, dxtBlock3); - - if (error3 < error4) { - error += error3; - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&dxtBlock3, sizeof(dxtBlock3)); - } - } - else { - error += error4; - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(&dxtBlock4, sizeof(dxtBlock4)); - } - } - } - } - - printf("error = %f\n", error/((w+3)/4 * (h+3)/4)); -} - -#endif // defined(HAVE_S3QUANT) - - -#if defined(HAVE_ATITC) - -void nv::atiCompressDXT1(const Image * image, const OutputOptions::Private & outputOptions) -{ - // Init source texture - ATI_TC_Texture srcTexture; - srcTexture.dwSize = sizeof(srcTexture); - srcTexture.dwWidth = image->width(); - srcTexture.dwHeight = image->height(); - srcTexture.dwPitch = image->width() * 4; - srcTexture.format = ATI_TC_FORMAT_ARGB_8888; - srcTexture.dwDataSize = ATI_TC_CalculateBufferSize(&srcTexture); - srcTexture.pData = (ATI_TC_BYTE*) image->pixels(); - - // Init dest texture - ATI_TC_Texture destTexture; - destTexture.dwSize = sizeof(destTexture); - destTexture.dwWidth = image->width(); - destTexture.dwHeight = image->height(); - destTexture.dwPitch = 0; - destTexture.format = ATI_TC_FORMAT_DXT1; - destTexture.dwDataSize = ATI_TC_CalculateBufferSize(&destTexture); - destTexture.pData = (ATI_TC_BYTE*) mem::malloc(destTexture.dwDataSize); - - // Compress - ATI_TC_ConvertTexture(&srcTexture, &destTexture, NULL, NULL, NULL, NULL); - - if (outputOptions.outputHandler != NULL) { - outputOptions.outputHandler->writeData(destTexture.pData, destTexture.dwDataSize); - } -} - -#endif // defined(HAVE_ATITC) diff --git a/Externals/NVTT/src/nvtt/CompressDXT.h b/Externals/NVTT/src/nvtt/CompressDXT.h deleted file mode 100644 index f25112f4126..00000000000 --- a/Externals/NVTT/src/nvtt/CompressDXT.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_COMPRESSDXT_H -#define NV_TT_COMPRESSDXT_H - -#include -#include "nvtt.h" - -namespace nv -{ - class Image; - class FloatImage; - - class FastCompressor - { - public: - FastCompressor(); - ~FastCompressor(); - - void setImage(const Image * image, nvtt::AlphaMode alphaMode); - - void compressDXT1(const nvtt::OutputOptions::Private & outputOptions); - void compressDXT1a(const nvtt::OutputOptions::Private & outputOptions); - void compressDXT3(const nvtt::OutputOptions::Private & outputOptions); - void compressDXT5(const nvtt::OutputOptions::Private & outputOptions); - void compressDXT5n(const nvtt::OutputOptions::Private & outputOptions); - - private: - const Image * m_image; - nvtt::AlphaMode m_alphaMode; - }; - - class SlowCompressor - { - public: - SlowCompressor(); - ~SlowCompressor(); - - void setImage(const Image * image, nvtt::AlphaMode alphaMode); - - void compressDXT1(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT1a(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT3(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT5(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT5n(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressBC4(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressBC5(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - - private: - const Image * m_image; - nvtt::AlphaMode m_alphaMode; - }; - - // External compressors. -#if defined(HAVE_S3QUANT) - void s3CompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions); -#endif - -#if defined(HAVE_ATITC) - void atiCompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions); -#endif - -} // nv namespace - - -#endif // NV_TT_COMPRESSDXT_H diff --git a/Externals/NVTT/src/nvtt/CompressRGB.cpp b/Externals/NVTT/src/nvtt/CompressRGB.cpp deleted file mode 100644 index 4f0ff660a2c..00000000000 --- a/Externals/NVTT/src/nvtt/CompressRGB.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include -#include -#include - -#include "CompressRGB.h" -#include "CompressionOptions.h" -#include "OutputOptions.h" - -using namespace nv; -using namespace nvtt; - -namespace -{ - - inline uint computePitch(uint w, uint bitsize) - { - uint p = w * ((bitsize + 7) / 8); - - // Align to 32 bits. - return ((p + 3) / 4) * 4; - } - - inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w) - { - memcpy(dst, src, 4 * w); - } - - inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w) - { - memcpy(dst, src, 4 * w); - } - -} // namespace - - -// Pixel format converter. -void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions) -{ - nvCheck(image != NULL); - - const uint w = image->width(); - const uint h = image->height(); - - const uint bitCount = compressionOptions.bitcount; - nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32); - - const uint byteCount = bitCount / 8; - - const uint rmask = compressionOptions.rmask; - uint rshift, rsize; - PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize); - - const uint gmask = compressionOptions.gmask; - uint gshift, gsize; - PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize); - - const uint bmask = compressionOptions.bmask; - uint bshift, bsize; - PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize); - - const uint amask = compressionOptions.amask; - uint ashift, asize; - PixelFormat::maskShiftAndSize(amask, &ashift, &asize); - - // Determine pitch. - uint pitch = computePitch(w, compressionOptions.bitcount); - - uint8 * dst = (uint8 *)mem::malloc(pitch + 4); - - for (uint y = 0; y < h; y++) - { - const Color32 * src = image->scanline(y); - - if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000) - { - convert_to_a8r8g8b8(src, dst, w); - } - else if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0) - { - convert_to_x8r8g8b8(src, dst, w); - } - else - { - // Generic pixel format conversion. - for (uint x = 0; x < w; x++) - { - uint c = 0; - c |= PixelFormat::convert(src[x].r, 8, rsize) << rshift; - c |= PixelFormat::convert(src[x].g, 8, gsize) << gshift; - c |= PixelFormat::convert(src[x].b, 8, bsize) << bshift; - c |= PixelFormat::convert(src[x].a, 8, asize) << ashift; - - // Output one byte at a time. - for (uint i = 0; i < byteCount; i++) - { - *(dst + x * byteCount + i) = (c >> (i * 8)) & 0xFF; - } - } - - // Zero padding. - for (uint x = w * byteCount; x < pitch; x++) - { - *(dst + x) = 0; - } - } - - if (outputOptions.outputHandler != NULL) - { - outputOptions.outputHandler->writeData(dst, pitch); - } - } - - mem::free(dst); -} - diff --git a/Externals/NVTT/src/nvtt/CompressRGB.h b/Externals/NVTT/src/nvtt/CompressRGB.h deleted file mode 100644 index 7586254b136..00000000000 --- a/Externals/NVTT/src/nvtt/CompressRGB.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_COMPRESSRGB_H -#define NV_TT_COMPRESSRGB_H - -#include "nvtt.h" - -namespace nv -{ - class Image; - - // Pixel format converter. - void compressRGB(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions); - -} // nv namespace - - -#endif // NV_TT_COMPRESSDXT_H diff --git a/Externals/NVTT/src/nvtt/CompressionOptions.cpp b/Externals/NVTT/src/nvtt/CompressionOptions.cpp deleted file mode 100644 index cc5fa7ba64f..00000000000 --- a/Externals/NVTT/src/nvtt/CompressionOptions.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include "nvtt.h" -#include "CompressionOptions.h" - -using namespace nv; -using namespace nvtt; - - -/// Constructor. Sets compression options to the default values. -CompressionOptions::CompressionOptions() : m(*new CompressionOptions::Private()) -{ - reset(); -} - - -/// Destructor. -CompressionOptions::~CompressionOptions() -{ - delete &m; -} - - -/// Set default compression options. -void CompressionOptions::reset() -{ - m.format = Format_DXT1; - m.quality = Quality_Normal; - m.colorWeight.set(1.0f, 1.0f, 1.0f, 1.0f); - - m.bitcount = 32; - m.bmask = 0x000000FF; - m.gmask = 0x0000FF00; - m.rmask = 0x00FF0000; - m.amask = 0xFF000000; - - m.enableColorDithering = false; - m.enableAlphaDithering = false; - m.binaryAlpha = false; - m.alphaThreshold = 127; -} - - -/// Set desired compression format. -void CompressionOptions::setFormat(Format format) -{ - m.format = format; -} - - -/// Set compression quality settings. -void CompressionOptions::setQuality(Quality quality) -{ - m.quality = quality; -} - - -/// Set the weights of each color channel. -/// The choice for these values is subjective. In many case uniform color weights -/// (1.0, 1.0, 1.0) work very well. A popular choice is to use the NTSC luma encoding -/// weights (0.2126, 0.7152, 0.0722), but I think that blue contributes to our -/// perception more than a 7%. A better choice in my opinion is (3, 4, 2). -void CompressionOptions::setColorWeights(float red, float green, float blue, float alpha/*=1.0f*/) -{ -// float total = red + green + blue; -// float x = red / total; -// float y = green / total; -// m.colorWeight.set(x, y, 1.0f - x - y); - m.colorWeight.set(red, green, blue, alpha); -} - - -/// Set color mask to describe the RGB/RGBA format. -void CompressionOptions::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) -{ - // Validate arguments. - nvCheck(bitcount == 8 || bitcount == 16 || bitcount == 24 || bitcount == 32); - nvCheck((rmask & gmask) == 0); - nvCheck((rmask & bmask) == 0); - nvCheck((rmask & amask) == 0); - nvCheck((gmask & bmask) == 0); - nvCheck((gmask & amask) == 0); - nvCheck((bmask & amask) == 0); - - if (bitcount != 32) - { - uint maxMask = (1 << bitcount); - nvCheck(maxMask > rmask); - nvCheck(maxMask > gmask); - nvCheck(maxMask > bmask); - nvCheck(maxMask > amask); - } - - m.bitcount = bitcount; - m.rmask = rmask; - m.gmask = gmask; - m.bmask = bmask; - m.amask = amask; -} - -/// Use external compressor. -void CompressionOptions::setExternalCompressor(const char * name) -{ - m.externalCompressor = name; -} - -/// Set quantization options. -/// @warning Do not enable dithering unless you know what you are doing. Quantization -/// introduces errors. It's better to let the compressor quantize the result to -/// minimize the error, instead of quantizing the data before handling it to -/// the compressor. -void CompressionOptions::setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold/*= 127*/) -{ - nvCheck(alphaThreshold >= 0 && alphaThreshold < 256); - m.enableColorDithering = colorDithering; - m.enableAlphaDithering = alphaDithering; - m.binaryAlpha = binaryAlpha; - m.alphaThreshold = alphaThreshold; -} - - - diff --git a/Externals/NVTT/src/nvtt/CompressionOptions.h b/Externals/NVTT/src/nvtt/CompressionOptions.h deleted file mode 100644 index b0c26779ca5..00000000000 --- a/Externals/NVTT/src/nvtt/CompressionOptions.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_COMPRESSIONOPTIONS_H -#define NV_TT_COMPRESSIONOPTIONS_H - -#include -#include -#include "nvtt.h" - -namespace nvtt -{ - - struct CompressionOptions::Private - { - Format format; - - Quality quality; - - nv::Vector4 colorWeight; - - // Pixel format description. - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; - - nv::String externalCompressor; - - // Quantization. - bool enableColorDithering; - bool enableAlphaDithering; - bool binaryAlpha; - int alphaThreshold; // reference value used for binary alpha quantization. - }; - -} // nvtt namespace - - -#endif // NV_TT_COMPRESSIONOPTIONS_H diff --git a/Externals/NVTT/src/nvtt/Compressor.cpp b/Externals/NVTT/src/nvtt/Compressor.cpp deleted file mode 100644 index ec788ef267a..00000000000 --- a/Externals/NVTT/src/nvtt/Compressor.cpp +++ /dev/null @@ -1,853 +0,0 @@ -// Copyright NVIDIA Corporation 2008 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Compressor.h" -#include "InputOptions.h" -#include "CompressionOptions.h" -#include "OutputOptions.h" - -#include "CompressDXT.h" -#include "CompressRGB.h" -#include "cuda/CudaUtils.h" -#include "cuda/CudaCompressDXT.h" - - -using namespace nv; -using namespace nvtt; - - -namespace -{ - - static int blockSize(Format format) - { - if (format == Format_DXT1 || format == Format_DXT1a) { - return 8; - } - else if (format == Format_DXT3) { - return 16; - } - else if (format == Format_DXT5 || format == Format_DXT5n) { - return 16; - } - else if (format == Format_BC4) { - return 8; - } - else if (format == Format_BC5) { - return 16; - } - return 0; - } - - inline uint computePitch(uint w, uint bitsize) - { - uint p = w * ((bitsize + 7) / 8); - - // Align to 32 bits. - return ((p + 3) / 4) * 4; - } - - static int computeImageSize(uint w, uint h, uint d, uint bitCount, Format format) - { - if (format == Format_RGBA) { - return d * h * computePitch(w, bitCount); - } - else { - // @@ Handle 3D textures. DXT and VTC have different behaviors. - return ((w + 3) / 4) * ((h + 3) / 4) * blockSize(format); - } - } - -} // namespace - -namespace nvtt -{ - // Mipmap could be: - // - a pointer to an input image. - // - a fixed point image. - // - a floating point image. - struct Mipmap - { - Mipmap() : m_inputImage(NULL) {} - ~Mipmap() {} - - // Reference input image. - void setFromInput(const InputOptions::Private & inputOptions, uint idx) - { - m_inputImage = inputOptions.image(idx); - m_fixedImage = NULL; - m_floatImage = NULL; - } - - // Assign and take ownership of given image. - void setImage(FloatImage * image) - { - m_inputImage = NULL; - m_fixedImage = NULL; - m_floatImage = image; - } - - - // Convert linear float image to fixed image ready for compression. - void toFixedImage(const InputOptions::Private & inputOptions) - { - if (m_floatImage != NULL) // apfaffe - We should check that we have a float image, if so convert it! - { - if (inputOptions.isNormalMap || inputOptions.outputGamma == 1.0f) - { - m_fixedImage = m_floatImage->createImage(); - } - else - { - m_fixedImage = m_floatImage->createImageGammaCorrect(inputOptions.outputGamma); - } - } - } - - // Convert input image to linear float image. - void toFloatImage(const InputOptions::Private & inputOptions) - { - if (m_floatImage == NULL) - { - nvDebugCheck(this->asFixedImage() != NULL); - - m_floatImage = new FloatImage(this->asFixedImage()); - - if (inputOptions.isNormalMap) - { - // Expand normals to [-1, 1] range. - // floatImage->expandNormals(0); - } - else if (inputOptions.inputGamma != 1.0f) - { - // Convert to linear space. - m_floatImage->toLinear(0, 3, inputOptions.inputGamma); - } - } - } - - const FloatImage * asFloatImage() const - { - return m_floatImage.ptr(); - } - - FloatImage * asFloatImage() - { - return m_floatImage.ptr(); - } - - const Image * asFixedImage() const - { - // - apfaffe - switched logic to return the 'processed image' rather than the input! - if (m_fixedImage != NULL && m_fixedImage.ptr() != NULL) - { - return m_fixedImage.ptr(); - } - return m_inputImage; - } - - Image * asMutableFixedImage() - { - if (m_inputImage != NULL) - { - // Do not modify input image, create a copy. - m_fixedImage = new Image(*m_inputImage); - m_inputImage = NULL; - } - return m_fixedImage.ptr(); - } - - - private: - const Image * m_inputImage; - AutoPtr m_fixedImage; - AutoPtr m_floatImage; - }; - -} // nvtt namespace - - -Compressor::Compressor() : m(*new Compressor::Private()) -{ - // CUDA initialization. - m.cudaSupported = cuda::isHardwarePresent(); - m.cudaEnabled = false; - m.cudaDevice = -1; - - enableCudaAcceleration(m.cudaSupported); -} - -Compressor::~Compressor() -{ - enableCudaAcceleration(false); - delete &m; -} - - -/// Enable CUDA acceleration. -void Compressor::enableCudaAcceleration(bool enable) -{ - if (m.cudaSupported) - { - if (m.cudaEnabled && !enable) - { - m.cudaEnabled = false; - m.cuda = NULL; - - if (m.cudaDevice != -1) - { - // Exit device. - cuda::exitDevice(); - } - } - else if (!m.cudaEnabled && enable) - { - // Init the CUDA device. This may return -1 if CUDA was already initialized by the app. - m.cudaEnabled = cuda::initDevice(&m.cudaDevice); - - if (m.cudaEnabled) - { - // Create compressor if initialization succeeds. - m.cuda = new CudaCompressor(); - - // But cleanup if failed. - if (!m.cuda->isValid()) - { - enableCudaAcceleration(false); - } - } - } - } -} - -/// Check if CUDA acceleration is enabled. -bool Compressor::isCudaAccelerationEnabled() const -{ - return m.cudaEnabled; -} - - -/// Compress the input texture with the given compression options. -bool Compressor::process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const -{ - return m.compress(inputOptions.m, compressionOptions.m, outputOptions.m); -} - - -/// Estimate the size of compressing the input with the given options. -int Compressor::estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const -{ - return m.estimateSize(inputOptions.m, compressionOptions.m); -} - - - - -bool Compressor::Private::compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const -{ - // Make sure enums match. - nvStaticCheck(FloatImage::WrapMode_Clamp == (FloatImage::WrapMode)WrapMode_Clamp); - nvStaticCheck(FloatImage::WrapMode_Mirror == (FloatImage::WrapMode)WrapMode_Mirror); - nvStaticCheck(FloatImage::WrapMode_Repeat == (FloatImage::WrapMode)WrapMode_Repeat); - - // Get output handler. - if (!outputOptions.openFile()) - { - if (outputOptions.errorHandler) outputOptions.errorHandler->error(Error_FileOpen); - return false; - } - - inputOptions.computeTargetExtents(); - - // Output DDS header. - if (!outputHeader(inputOptions, compressionOptions, outputOptions)) - { - return false; - } - - for (uint f = 0; f < inputOptions.faceCount; f++) - { - if (!compressMipmaps(f, inputOptions, compressionOptions, outputOptions)) - { - return false; - } - } - - outputOptions.closeFile(); - - return true; -} - - -// Output DDS header. -bool Compressor::Private::outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const -{ - // Output DDS header. - if (outputOptions.outputHandler == NULL || !outputOptions.outputHeader) - { - return true; - } - - DDSHeader header; - - header.setWidth(inputOptions.targetWidth); - header.setHeight(inputOptions.targetHeight); - - int mipmapCount = inputOptions.realMipmapCount(); - nvDebugCheck(mipmapCount > 0); - - header.setMipmapCount(mipmapCount); - - if (inputOptions.textureType == TextureType_2D) { - header.setTexture2D(); - } - else if (inputOptions.textureType == TextureType_Cube) { - header.setTextureCube(); - } - /*else if (inputOptions.textureType == TextureType_3D) { - header.setTexture3D(); - header.setDepth(inputOptions.targetDepth); - }*/ - - if (compressionOptions.format == Format_RGBA) - { - header.setPitch(computePitch(inputOptions.targetWidth, compressionOptions.bitcount)); - header.setPixelFormat(compressionOptions.bitcount, compressionOptions.rmask, compressionOptions.gmask, compressionOptions.bmask, compressionOptions.amask); - } - else - { - header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, inputOptions.targetDepth, compressionOptions.bitcount, compressionOptions.format)); - - if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a) { - header.setFourCC('D', 'X', 'T', '1'); - if (inputOptions.isNormalMap) header.setNormalFlag(true); - } - else if (compressionOptions.format == Format_DXT3) { - header.setFourCC('D', 'X', 'T', '3'); - } - else if (compressionOptions.format == Format_DXT5) { - header.setFourCC('D', 'X', 'T', '5'); - } - else if (compressionOptions.format == Format_DXT5n) { - header.setFourCC('D', 'X', 'T', '5'); - if (inputOptions.isNormalMap) header.setNormalFlag(true); - } - else if (compressionOptions.format == Format_BC4) { - header.setFourCC('A', 'T', 'I', '1'); - } - else if (compressionOptions.format == Format_BC5) { - header.setFourCC('A', 'T', 'I', '2'); - if (inputOptions.isNormalMap) header.setNormalFlag(true); - } - } - - // Swap bytes if necessary. - header.swapBytes(); - - uint headerSize = 128; - if (header.hasDX10Header()) - { - nvStaticCheck(sizeof(DDSHeader) == 128 + 20); - headerSize = 128 + 20; - } - - bool writeSucceed = outputOptions.outputHandler->writeData(&header, headerSize); - if (!writeSucceed && outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_FileWrite); - } - - return writeSucceed; -} - - -bool Compressor::Private::compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const -{ - uint w = inputOptions.targetWidth; - uint h = inputOptions.targetHeight; - uint d = inputOptions.targetDepth; - - Mipmap mipmap; - - const uint mipmapCount = inputOptions.realMipmapCount(); - nvDebugCheck(mipmapCount > 0); - - for (uint m = 0; m < mipmapCount; m++) - { - if (outputOptions.outputHandler) - { - int size = computeImageSize(w, h, d, compressionOptions.bitcount, compressionOptions.format); - outputOptions.outputHandler->beginImage(size, w, h, d, f, m); - } - - // @@ Where to do the color transform? - // - Color transform may not be linear, so we cannot do before computing mipmaps. - // - Should be done in linear space, that is, after gamma correction. - - if (!initMipmap(mipmap, inputOptions, w, h, d, f, m)) - { - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_InvalidInput); - return false; - } - } - - quantizeMipmap(mipmap, compressionOptions); - - compressMipmap(mipmap, inputOptions, compressionOptions, outputOptions); - - // Compute extents of next mipmap: - w = max(1U, w / 2); - h = max(1U, h / 2); - d = max(1U, d / 2); - } - - return true; -} - -bool Compressor::Private::initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const -{ - // Find image from input. - int inputIdx = findExactMipmap(inputOptions, w, h, d, f); - - if ((inputIdx == -1 || inputOptions.convertToNormalMap) && m != 0) - { - // Generate from last, when mipmap not found, or normal map conversion enabled. - downsampleMipmap(mipmap, inputOptions); - } - else - { - if (inputIdx != -1) - { - // If input mipmap found, then get from input. - mipmap.setFromInput(inputOptions, inputIdx); - } - else - { - // If not found, resize closest mipmap. - inputIdx = findClosestMipmap(inputOptions, w, h, d, f); - - if (inputIdx == -1) - { - return false; - } - - mipmap.setFromInput(inputOptions, inputIdx); - - scaleMipmap(mipmap, inputOptions, w, h, d); - } - - processInputImage(mipmap, inputOptions); - } - - // Convert linear float image to fixed image ready for compression. - mipmap.toFixedImage(inputOptions); - - return true; -} - -int Compressor::Private::findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const -{ - for (int m = 0; m < int(inputOptions.mipmapCount); m++) - { - int idx = f * inputOptions.mipmapCount + m; - const InputOptions::Private::InputImage & inputImage = inputOptions.images[idx]; - - if (inputImage.width == int(w) && inputImage.height == int(h) && inputImage.depth == int(d)) - { - if (inputImage.data != NULL) - { - return idx; - } - return -1; - } - else if (inputImage.width < int(w) || inputImage.height < int(h) || inputImage.depth < int(d)) - { - return -1; - } - } - - return -1; -} - -int Compressor::Private::findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const -{ - int bestIdx = -1; - - for (int m = 0; m < int(inputOptions.mipmapCount); m++) - { - int idx = f * inputOptions.mipmapCount + m; - const InputOptions::Private::InputImage & inputImage = inputOptions.images[idx]; - - if (inputImage.data != NULL) - { - int difference = (inputImage.width - w) + (inputImage.height - h) + (inputImage.depth - d); - - if (difference < 0) - { - if (bestIdx == -1) - { - bestIdx = idx; - } - - return bestIdx; - } - - bestIdx = idx; - } - } - - return bestIdx; -} - -// Create mipmap from the given image. -void Compressor::Private::downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const -{ - // Make sure that floating point linear representation is available. - mipmap.toFloatImage(inputOptions); - - const FloatImage * floatImage = mipmap.asFloatImage(); - - if (inputOptions.mipmapFilter == MipmapFilter_Box) - { - // Use fast downsample. - mipmap.setImage(floatImage->fastDownSample()); - } - else if (inputOptions.mipmapFilter == MipmapFilter_Triangle) - { - TriangleFilter filter; - mipmap.setImage(floatImage->downSample(filter, (FloatImage::WrapMode)inputOptions.wrapMode)); - } - else /*if (inputOptions.mipmapFilter == MipmapFilter_Kaiser)*/ - { - nvDebugCheck(inputOptions.mipmapFilter == MipmapFilter_Kaiser); - KaiserFilter filter(inputOptions.kaiserWidth); - filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch); - mipmap.setImage(floatImage->downSample(filter, (FloatImage::WrapMode)inputOptions.wrapMode)); - } - - // Normalize mipmap. - if ((inputOptions.isNormalMap || inputOptions.convertToNormalMap) && inputOptions.normalizeMipmaps) - { - normalizeNormalMap(mipmap.asFloatImage()); - } -} - - -void Compressor::Private::scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const -{ - mipmap.toFloatImage(inputOptions); - - // @@ Add more filters. - // @@ Select different filters for downscaling and reconstruction. - - // Resize image. - BoxFilter boxFilter; - mipmap.setImage(mipmap.asFloatImage()->resize(boxFilter, w, h, (FloatImage::WrapMode)inputOptions.wrapMode)); -} - - -// Process an input image: Convert to normal map, normalize, or convert to linear space. -void Compressor::Private::processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const -{ - if (inputOptions.convertToNormalMap) - { - mipmap.toFixedImage(inputOptions); - - Vector4 heightScale = inputOptions.heightFactors; - mipmap.setImage(createNormalMap(mipmap.asFixedImage(), (FloatImage::WrapMode)inputOptions.wrapMode, heightScale, inputOptions.bumpFrequencyScale)); - } - else if (inputOptions.isNormalMap) - { - if (inputOptions.normalizeMipmaps) - { - // If floating point image available, normalize in place. - if (mipmap.asFloatImage() == NULL) - { - FloatImage * floatImage = new FloatImage(mipmap.asFixedImage()); - normalizeNormalMap(floatImage); - mipmap.setImage(floatImage); - } - else - { - normalizeNormalMap(mipmap.asFloatImage()); - mipmap.setImage(mipmap.asFloatImage()); - } - } - } - else - { - if (inputOptions.inputGamma != inputOptions.outputGamma) - { - mipmap.toFloatImage(inputOptions); - } - } -} - - -// Quantize the given mipmap according to the compression options. -void Compressor::Private::quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const -{ - nvDebugCheck(mipmap.asFixedImage() != NULL); - - if (compressionOptions.binaryAlpha) - { - if (compressionOptions.enableAlphaDithering) - { - Quantize::FloydSteinberg_BinaryAlpha(mipmap.asMutableFixedImage(), compressionOptions.alphaThreshold); - } - else - { - Quantize::BinaryAlpha(mipmap.asMutableFixedImage(), compressionOptions.alphaThreshold); - } - } - - if (compressionOptions.enableColorDithering || compressionOptions.enableAlphaDithering) - { - uint rsize = 8; - uint gsize = 8; - uint bsize = 8; - uint asize = 8; - - if (compressionOptions.enableColorDithering) - { - if (compressionOptions.format >= Format_DXT1 && compressionOptions.format <= Format_DXT5) - { - rsize = 5; - gsize = 6; - bsize = 5; - } - else if (compressionOptions.format == Format_RGB) - { - uint rshift, gshift, bshift; - PixelFormat::maskShiftAndSize(compressionOptions.rmask, &rshift, &rsize); - PixelFormat::maskShiftAndSize(compressionOptions.gmask, &gshift, &gsize); - PixelFormat::maskShiftAndSize(compressionOptions.bmask, &bshift, &bsize); - } - } - - if (compressionOptions.enableAlphaDithering) - { - if (compressionOptions.format == Format_DXT3) - { - asize = 4; - } - else if (compressionOptions.format == Format_RGB) - { - uint ashift; - PixelFormat::maskShiftAndSize(compressionOptions.amask, &ashift, &asize); - } - } - - if (compressionOptions.binaryAlpha) - { - asize = 8; // Already quantized. - } - - Quantize::FloydSteinberg(mipmap.asMutableFixedImage(), rsize, gsize, bsize, asize); - } -} - - -// Compress the given mipmap. -bool Compressor::Private::compressMipmap(const Mipmap & mipmap, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const -{ - const Image * image = mipmap.asFixedImage(); - nvDebugCheck(image != NULL); - - FastCompressor fast; - fast.setImage(image, inputOptions.alphaMode); - - SlowCompressor slow; - slow.setImage(image, inputOptions.alphaMode); - - const bool useCuda = cudaEnabled && image->width() * image->height() >= 512; - - if (compressionOptions.format == Format_RGBA || compressionOptions.format == Format_RGB) - { - compressRGB(image, outputOptions, compressionOptions); - } - else if (compressionOptions.format == Format_DXT1) - { -#if defined(HAVE_S3QUANT) - if (compressionOptions.externalCompressor == "s3") - { - s3CompressDXT1(image, outputOptions); - } - else -#endif - -#if defined(HAVE_ATITC) - if (compressionOptions.externalCompressor == "ati") - { - atiCompressDXT1(image, outputOptions); - } - else -#endif - if (compressionOptions.quality == Quality_Fastest) - { - fast.compressDXT1(outputOptions); - } - else - { - if (useCuda) - { - nvDebugCheck(cudaSupported); - cuda->setImage(image, inputOptions.alphaMode); - cuda->compressDXT1(compressionOptions, outputOptions); - } - else - { - slow.compressDXT1(compressionOptions, outputOptions); - } - } - } - else if (compressionOptions.format == Format_DXT1a) - { - if (compressionOptions.quality == Quality_Fastest) - { - fast.compressDXT1a(outputOptions); - } - else - { - if (useCuda) - { - nvDebugCheck(cudaSupported); - /*cuda*/slow.compressDXT1a(compressionOptions, outputOptions); - } - else - { - slow.compressDXT1a(compressionOptions, outputOptions); - } - } - } - else if (compressionOptions.format == Format_DXT3) - { - if (compressionOptions.quality == Quality_Fastest) - { - fast.compressDXT3(outputOptions); - } - else - { - if (useCuda) - { - nvDebugCheck(cudaSupported); - cuda->setImage(image, inputOptions.alphaMode); - cuda->compressDXT3(compressionOptions, outputOptions); - } - else - { - slow.compressDXT3(compressionOptions, outputOptions); - } - } - } - else if (compressionOptions.format == Format_DXT5) - { - if (compressionOptions.quality == Quality_Fastest) - { - fast.compressDXT5(outputOptions); - } - else - { - if (useCuda) - { - nvDebugCheck(cudaSupported); - cuda->setImage(image, inputOptions.alphaMode); - cuda->compressDXT5(compressionOptions, outputOptions); - } - else - { - slow.compressDXT5(compressionOptions, outputOptions); - } - } - } - else if (compressionOptions.format == Format_DXT5n) - { - if (compressionOptions.quality == Quality_Fastest) - { - fast.compressDXT5n(outputOptions); - } - else - { - slow.compressDXT5n(compressionOptions, outputOptions); - } - } - else if (compressionOptions.format == Format_BC4) - { - slow.compressBC4(compressionOptions, outputOptions); - } - else if (compressionOptions.format == Format_BC5) - { - slow.compressBC5(compressionOptions, outputOptions); - } - - return true; -} - - -int Compressor::Private::estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const -{ - const Format format = compressionOptions.format; - const uint bitCount = compressionOptions.bitcount; - - inputOptions.computeTargetExtents(); - - uint mipmapCount = inputOptions.realMipmapCount(); - - int size = 0; - - for (uint f = 0; f < inputOptions.faceCount; f++) - { - uint w = inputOptions.targetWidth; - uint h = inputOptions.targetHeight; - uint d = inputOptions.targetDepth; - - for (uint m = 0; m < mipmapCount; m++) - { - size += computeImageSize(w, h, d, bitCount, format); - - // Compute extents of next mipmap: - w = max(1U, w / 2); - h = max(1U, h / 2); - d = max(1U, d / 2); - } - } - - return size; -} diff --git a/Externals/NVTT/src/nvtt/Compressor.h b/Externals/NVTT/src/nvtt/Compressor.h deleted file mode 100644 index 31f59c863fe..00000000000 --- a/Externals/NVTT/src/nvtt/Compressor.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright NVIDIA Corporation 2008 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_COMPRESSOR_H -#define NV_TT_COMPRESSOR_H - -#include - -#include - -#include "nvtt.h" - -namespace nv -{ - class Image; -} - -namespace nvtt -{ - struct Mipmap; - - struct Compressor::Private - { - Private() {} - - bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const; - - private: - - bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - - bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const; - - int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const; - int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const; - - void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const; - void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const; - void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const; - void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const; - bool compressMipmap(const Mipmap & mipmap, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; - - - - public: - - bool cudaSupported; - bool cudaEnabled; - int cudaDevice; - - nv::AutoPtr cuda; - - }; - -} // nvtt namespace - - -#endif // NV_TT_COMPRESSOR_H diff --git a/Externals/NVTT/src/nvtt/InputOptions.cpp b/Externals/NVTT/src/nvtt/InputOptions.cpp deleted file mode 100644 index 92177878877..00000000000 --- a/Externals/NVTT/src/nvtt/InputOptions.cpp +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include // memcpy - -#include - -#include "nvtt.h" -#include "InputOptions.h" - -using namespace nv; -using namespace nvtt; - -namespace -{ - - static uint countMipmaps(int w, int h, int d) - { - uint mipmap = 0; - - while (w != 1 || h != 1 || d != 1) { - w = max(1, w / 2); - h = max(1, h / 2); - d = max(1, d / 2); - mipmap++; - } - - return mipmap + 1; - } - - // 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ... - static uint previousPowerOfTwo(const uint v) - { - return nextPowerOfTwo(v + 1) / 2; - } - - static uint nearestPowerOfTwo(const uint v) - { - const uint np2 = nextPowerOfTwo(v); - const uint pp2 = previousPowerOfTwo(v); - - if (np2 - v <= v - pp2) - { - return np2; - } - else - { - return pp2; - } - } - -} // namespace - - -/// Constructor. -InputOptions::InputOptions() : m(*new InputOptions::Private()) -{ - reset(); -} - -// Delete images. -InputOptions::~InputOptions() -{ - resetTextureLayout(); - - delete &m; -} - - -// Reset input options. -void InputOptions::reset() -{ - m.wrapMode = WrapMode_Mirror; - m.textureType = TextureType_2D; - m.inputFormat = InputFormat_BGRA_8UB; - - m.alphaMode = AlphaMode_None; - - m.inputGamma = 2.2f; - m.outputGamma = 2.2f; - - m.colorTransform = ColorTransform_None; - m.linearTransform = Matrix(identity); - - m.generateMipmaps = true; - m.maxLevel = -1; - m.mipmapFilter = MipmapFilter_Box; - - m.kaiserWidth = 3; - m.kaiserAlpha = 4.0f; - m.kaiserStretch = 1.0f; - - m.isNormalMap = false; - m.normalizeMipmaps = true; - m.convertToNormalMap = false; - m.heightFactors.set(0.0f, 0.0f, 0.0f, 1.0f); - m.bumpFrequencyScale = Vector4(1.0f, 0.5f, 0.25f, 0.125f) / (1.0f + 0.5f + 0.25f + 0.125f); - - m.maxExtent = 0; - m.roundMode = RoundMode_None; -} - - -// Setup the input image. -void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth /*= 1*/) -{ - // Validate arguments. - nvCheck(width >= 0); - nvCheck(height >= 0); - nvCheck(depth >= 0); - - // Correct arguments. - if (width == 0) width = 1; - if (height == 0) height = 1; - if (depth == 0) depth = 1; - - // Delete previous images. - resetTextureLayout(); - - m.textureType = type; - - // Allocate images. - m.mipmapCount = countMipmaps(width, height, depth); - m.faceCount = (type == TextureType_Cube) ? 6 : 1; - m.imageCount = m.mipmapCount * m.faceCount; - - m.images = new Private::InputImage[m.imageCount]; - - for(uint f = 0; f < m.faceCount; f++) - { - uint w = width; - uint h = height; - uint d = depth; - - for (uint mipLevel = 0; mipLevel < m.mipmapCount; mipLevel++) - { - Private::InputImage & img = m.images[f * m.mipmapCount + mipLevel]; - img.width = w; - img.height = h; - img.depth = d; - img.mipLevel = mipLevel; - img.face = f; - - img.data = NULL; - - w = max(1U, w / 2); - h = max(1U, h / 2); - d = max(1U, d / 2); - } - } -} - - -void InputOptions::resetTextureLayout() -{ - if (m.images != NULL) - { - // Delete image array. - delete [] m.images; - m.images = NULL; - - m.faceCount = 0; - m.mipmapCount = 0; - m.imageCount = 0; - } -} - - -// Copies the data to our internal structures. -bool InputOptions::setMipmapData(const void * data, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/) -{ - nvCheck(depth == 1); - - const int idx = face * m.mipmapCount + mipLevel; - - if (m.images[idx].width != width || m.images[idx].height != height || m.images[idx].depth != depth || m.images[idx].mipLevel != mipLevel || m.images[idx].face != face) - { - // Invalid dimension or index. - return false; - } - - m.images[idx].data = new nv::Image(); - m.images[idx].data->allocate(width, height); - memcpy(m.images[idx].data->pixels(), data, width * height * 4); - - return true; -} - - -/// Describe the format of the input. -void InputOptions::setFormat(InputFormat format) -{ - m.inputFormat = format; -} - - -/// Set the way the input alpha channel is interpreted. -void InputOptions::setAlphaMode(AlphaMode alphaMode) -{ - m.alphaMode = alphaMode; -} - - -/// Set gamma settings. -void InputOptions::setGamma(float inputGamma, float outputGamma) -{ - m.inputGamma = inputGamma; - m.outputGamma = outputGamma; -} - - -/// Set texture wrappign mode. -void InputOptions::setWrapMode(WrapMode mode) -{ - m.wrapMode = mode; -} - - -/// Set mipmap filter. -void InputOptions::setMipmapFilter(MipmapFilter filter) -{ - m.mipmapFilter = filter; -} - -/// Set mipmap generation. -void InputOptions::setMipmapGeneration(bool enabled, int maxLevel/*= -1*/) -{ - m.generateMipmaps = enabled; - m.maxLevel = maxLevel; -} - -/// Set Kaiser filter parameters. -void InputOptions::setKaiserParameters(float width, float alpha, float stretch) -{ - m.kaiserWidth = width; - m.kaiserAlpha = alpha; - m.kaiserStretch = stretch; -} - -/// Indicate whether input is a normal map or not. -void InputOptions::setNormalMap(bool b) -{ - m.isNormalMap = b; -} - -/// Enable normal map conversion. -void InputOptions::setConvertToNormalMap(bool convert) -{ - m.convertToNormalMap = convert; -} - -/// Set height evaluation factors. -void InputOptions::setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale) -{ - // Do not normalize height factors. -// float total = redScale + greenScale + blueScale + alphaScale; - m.heightFactors = Vector4(redScale, greenScale, blueScale, alphaScale); -} - -/// Set normal map conversion filter. -void InputOptions::setNormalFilter(float small, float medium, float big, float large) -{ - float total = small + medium + big + large; - m.bumpFrequencyScale = Vector4(small, medium, big, large) / total; -} - -/// Enable mipmap normalization. -void InputOptions::setNormalizeMipmaps(bool normalize) -{ - m.normalizeMipmaps = normalize; -} - -/// Set color transform. -void InputOptions::setColorTransform(ColorTransform t) -{ - m.colorTransform = t; -} - -// Set linear transform for the given channel. -void InputOptions::setLinearTransform(int channel, float w0, float w1, float w2, float w3) -{ - nvCheck(channel >= 0 && channel < 4); - - Vector4 w(w0, w1, w2, w3); - //m.linearTransform.setRow(channel, w); -} - -void InputOptions::setMaxExtents(int e) -{ - nvDebugCheck(e > 0); - m.maxExtent = e; -} - -void InputOptions::setRoundMode(RoundMode mode) -{ - m.roundMode = mode; -} - - -void InputOptions::Private::computeTargetExtents() const -{ - nvCheck(images != NULL); - - uint maxExtent = this->maxExtent; - if (roundMode != RoundMode_None) - { - // rounded max extent should never be higher than original max extent. - maxExtent = previousPowerOfTwo(maxExtent); - } - - uint w = images->width; - uint h = images->height; - uint d = images->depth; - - nvDebugCheck(w > 0); - nvDebugCheck(h > 0); - nvDebugCheck(d > 0); - - // Scale extents without changing aspect ratio. - uint maxwhd = max(max(w, h), d); - if (maxExtent != 0 && maxwhd > maxExtent) - { - w = max((w * maxExtent) / maxwhd, 1U); - h = max((h * maxExtent) / maxwhd, 1U); - d = max((d * maxExtent) / maxwhd, 1U); - } - - // Round to power of two. - if (roundMode == RoundMode_ToNextPowerOfTwo) - { - w = nextPowerOfTwo(w); - h = nextPowerOfTwo(h); - d = nextPowerOfTwo(d); - } - else if (roundMode == RoundMode_ToNearestPowerOfTwo) - { - w = nearestPowerOfTwo(w); - h = nearestPowerOfTwo(h); - d = nearestPowerOfTwo(d); - } - else if (roundMode == RoundMode_ToPreviousPowerOfTwo) - { - w = previousPowerOfTwo(w); - h = previousPowerOfTwo(h); - d = previousPowerOfTwo(d); - } - - this->targetWidth = w; - this->targetHeight = h; - this->targetDepth = d; - - this->targetMipmapCount = countMipmaps(w, h, d); -} - - -// Return real number of mipmaps, including first level. -// computeTargetExtents should have been called before. -int InputOptions::Private::realMipmapCount() const -{ - int mipmapCount = targetMipmapCount; - - if (!generateMipmaps) mipmapCount = 1; - else if (maxLevel != -1 && maxLevel < mipmapCount - 1) mipmapCount = maxLevel + 1; - - return mipmapCount; -} - - -const Image * InputOptions::Private::image(uint face, uint mipmap) const -{ - nvDebugCheck(face < faceCount); - nvDebugCheck(mipmap < mipmapCount); - - const InputImage & image = this->images[face * mipmapCount + mipmap]; - nvDebugCheck(image.face == face); - nvDebugCheck(image.mipLevel == mipmap); - - return image.data.ptr(); -} - -const Image * InputOptions::Private::image(uint idx) const -{ - nvDebugCheck(idx < faceCount * mipmapCount); - - const InputImage & image = this->images[idx]; - - return image.data.ptr(); -} diff --git a/Externals/NVTT/src/nvtt/InputOptions.h b/Externals/NVTT/src/nvtt/InputOptions.h deleted file mode 100644 index 44915782a40..00000000000 --- a/Externals/NVTT/src/nvtt/InputOptions.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_INPUTOPTIONS_H -#define NV_TT_INPUTOPTIONS_H - -#include -#include -#include -#include -#include "nvtt.h" - -namespace nvtt -{ - - struct InputOptions::Private - { - Private() : images(NULL) {} - - WrapMode wrapMode; - TextureType textureType; - InputFormat inputFormat; - AlphaMode alphaMode; - - uint faceCount; - uint mipmapCount; - uint imageCount; - - struct InputImage; - InputImage * images; - - // Gamma conversion. - float inputGamma; - float outputGamma; - - // Color transform. - ColorTransform colorTransform; - nv::Matrix linearTransform; - - // Mipmap generation options. - bool generateMipmaps; - int maxLevel; - MipmapFilter mipmapFilter; - - // Kaiser filter parameters. - float kaiserWidth; - float kaiserAlpha; - float kaiserStretch; - - // Normal map options. - bool isNormalMap; - bool normalizeMipmaps; - bool convertToNormalMap; - nv::Vector4 heightFactors; - nv::Vector4 bumpFrequencyScale; - - // Adjust extents. - uint maxExtent; - RoundMode roundMode; - - // @@ These are computed in nvtt::compress, so they should be mutable or stored elsewhere... - mutable uint targetWidth; - mutable uint targetHeight; - mutable uint targetDepth; - mutable uint targetMipmapCount; - - void computeTargetExtents() const; - - int realMipmapCount() const; - - const nv::Image * image(uint face, uint mipmap) const; - const nv::Image * image(uint idx) const; - - }; - - // Internal image structure. - struct InputOptions::Private::InputImage - { - InputImage() {} - - int mipLevel; - int face; - - int width; - int height; - int depth; - - nv::AutoPtr data; - }; - -} // nvtt namespace - -#endif // NV_TT_INPUTOPTIONS_H diff --git a/Externals/NVTT/src/nvtt/OptimalCompressDXT.cpp b/Externals/NVTT/src/nvtt/OptimalCompressDXT.cpp deleted file mode 100644 index 3445f88ac53..00000000000 --- a/Externals/NVTT/src/nvtt/OptimalCompressDXT.cpp +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include // swap - -#include - -#include -#include - -#include "OptimalCompressDXT.h" -#include "SingleColorLookup.h" - - -using namespace nv; -using namespace OptimalCompress; - - - -namespace -{ - static int computeGreenError(const ColorBlock & rgba, const BlockDXT1 * block) - { - nvDebugCheck(block != NULL); - - int palette[4]; - palette[0] = (block->col0.g << 2) | (block->col0.g >> 4); - palette[1] = (block->col1.g << 2) | (block->col1.g >> 4); - palette[2] = (2 * palette[0] + palette[1]) / 3; - palette[3] = (2 * palette[1] + palette[0]) / 3; - - int totalError = 0; - - for (int i = 0; i < 16; i++) - { - const int green = rgba.color(i).g; - - int error = abs(green - palette[0]); - error = min(error, abs(green - palette[1])); - error = min(error, abs(green - palette[2])); - error = min(error, abs(green - palette[3])); - - totalError += error; - } - - return totalError; - } - - static uint computeGreenIndices(const ColorBlock & rgba, const Color32 palette[4]) - { - const int color0 = palette[0].g; - const int color1 = palette[1].g; - const int color2 = palette[2].g; - const int color3 = palette[3].g; - - uint indices = 0; - for (int i = 0; i < 16; i++) - { - const int color = rgba.color(i).g; - - uint d0 = abs(color0 - color); - uint d1 = abs(color1 - color); - uint d2 = abs(color2 - color); - uint d3 = abs(color3 - color); - - uint b0 = d0 > d3; - uint b1 = d1 > d2; - uint b2 = d0 > d2; - uint b3 = d1 > d3; - uint b4 = d2 > d3; - - uint x0 = b1 & b2; - uint x1 = b0 & b3; - uint x2 = b0 & b4; - - indices |= (x2 | ((x0 | x1) << 1)) << (2 * i); - } - - return indices; - } - - // Choose quantized color that produces less error. Used by DXT3 compressor. - inline static uint quantize4(uint8 a) - { - int q0 = (a >> 4) - 1; - int q1 = (a >> 4); - int q2 = (a >> 4) + 1; - - q0 = (q0 << 4) | q0; - q1 = (q1 << 4) | q1; - q2 = (q2 << 4) | q2; - - int d0 = abs(q0 - a); - int d1 = abs(q1 - a); - int d2 = abs(q2 - a); - - if (d0 < d1 && d0 < d2) return q0 >> 4; - if (d1 < d2) return q1 >> 4; - return q2 >> 4; - } - - static uint computeAlphaError(const ColorBlock & rgba, const AlphaBlockDXT5 * block) - { - uint8 alphas[8]; - block->evaluatePalette(alphas); - - uint totalError = 0; - - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - - uint besterror = 256*256; - uint best; - for (uint p = 0; p < 8; p++) - { - int d = alphas[p] - alpha; - uint error = d * d; - - if (error < besterror) - { - besterror = error; - best = p; - } - } - - totalError += besterror; - } - - return totalError; - } - - static void computeAlphaIndices(const ColorBlock & rgba, AlphaBlockDXT5 * block) - { - uint8 alphas[8]; - block->evaluatePalette(alphas); - - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - - uint besterror = 256*256; - uint best = 8; - for(uint p = 0; p < 8; p++) - { - int d = alphas[p] - alpha; - uint error = d * d; - - if (error < besterror) - { - besterror = error; - best = p; - } - } - nvDebugCheck(best < 8); - - block->setIndex(i, best); - } - } - -} // namespace - - - - - -// Single color compressor, based on: -// https://mollyrocket.com/forums/viewtopic.php?t=392 -void OptimalCompress::compressDXT1(Color32 c, BlockDXT1 * dxtBlock) -{ - dxtBlock->col0.r = OMatch5[c.r][0]; - dxtBlock->col0.g = OMatch6[c.g][0]; - dxtBlock->col0.b = OMatch5[c.b][0]; - dxtBlock->col1.r = OMatch5[c.r][1]; - dxtBlock->col1.g = OMatch6[c.g][1]; - dxtBlock->col1.b = OMatch5[c.b][1]; - dxtBlock->indices = 0xaaaaaaaa; - - if (dxtBlock->col0.u < dxtBlock->col1.u) - { - swap(dxtBlock->col0.u, dxtBlock->col1.u); - dxtBlock->indices ^= 0x55555555; - } -} - -void OptimalCompress::compressDXT1a(Color32 rgba, BlockDXT1 * dxtBlock) -{ - if (rgba.a < 128) - { - dxtBlock->col0.u = 0; - dxtBlock->col1.u = 0; - dxtBlock->indices = 0xFFFFFFFF; - } - else - { - compressDXT1(rgba, dxtBlock); - } -} - - -// Brute force green channel compressor -void OptimalCompress::compressDXT1G(const ColorBlock & rgba, BlockDXT1 * block) -{ - nvDebugCheck(block != NULL); - - uint8 ming = 63; - uint8 maxg = 0; - - // Get min/max green. - for (uint i = 0; i < 16; i++) - { - uint8 green = rgba.color(i).g >> 2; - ming = min(ming, green); - maxg = max(maxg, green); - } - - block->col0.r = 31; - block->col1.r = 31; - block->col0.g = maxg; - block->col1.g = ming; - block->col0.b = 0; - block->col1.b = 0; - - if (maxg - ming > 4) - { - int besterror = computeGreenError(rgba, block); - int bestg0 = maxg; - int bestg1 = ming; - - for (int g0 = ming+5; g0 < maxg; g0++) - { - for (int g1 = ming; g1 < g0-4; g1++) - { - if ((maxg-g0) + (g1-ming) > besterror) - continue; - - block->col0.g = g0; - block->col1.g = g1; - int error = computeGreenError(rgba, block); - - if (error < besterror) - { - besterror = error; - bestg0 = g0; - bestg1 = g1; - } - } - } - - block->col0.g = bestg0; - block->col1.g = bestg1; - } - - Color32 palette[4]; - block->evaluatePalette(palette); - block->indices = computeGreenIndices(rgba, palette); -} - -void OptimalCompress::compressDXT3A(const ColorBlock & rgba, AlphaBlockDXT3 * dxtBlock) -{ - dxtBlock->alpha0 = quantize4(rgba.color(0).a); - dxtBlock->alpha1 = quantize4(rgba.color(1).a); - dxtBlock->alpha2 = quantize4(rgba.color(2).a); - dxtBlock->alpha3 = quantize4(rgba.color(3).a); - dxtBlock->alpha4 = quantize4(rgba.color(4).a); - dxtBlock->alpha5 = quantize4(rgba.color(5).a); - dxtBlock->alpha6 = quantize4(rgba.color(6).a); - dxtBlock->alpha7 = quantize4(rgba.color(7).a); - dxtBlock->alpha8 = quantize4(rgba.color(8).a); - dxtBlock->alpha9 = quantize4(rgba.color(9).a); - dxtBlock->alphaA = quantize4(rgba.color(10).a); - dxtBlock->alphaB = quantize4(rgba.color(11).a); - dxtBlock->alphaC = quantize4(rgba.color(12).a); - dxtBlock->alphaD = quantize4(rgba.color(13).a); - dxtBlock->alphaE = quantize4(rgba.color(14).a); - dxtBlock->alphaF = quantize4(rgba.color(15).a); -} - - -void OptimalCompress::compressDXT5A(const ColorBlock & rgba, AlphaBlockDXT5 * dxtBlock) -{ - uint8 mina = 255; - uint8 maxa = 0; - - // Get min/max alpha. - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - mina = min(mina, alpha); - maxa = max(maxa, alpha); - } - - dxtBlock->alpha0 = maxa; - dxtBlock->alpha1 = mina; - - /*int centroidDist = 256; - int centroid; - - // Get the closest to the centroid. - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - int dist = abs(alpha - (maxa + mina) / 2); - if (dist < centroidDist) - { - centroidDist = dist; - centroid = alpha; - } - }*/ - - if (maxa - mina > 8) - { - int besterror = computeAlphaError(rgba, dxtBlock); - int besta0 = maxa; - int besta1 = mina; - - for (int a0 = mina+9; a0 < maxa; a0++) - { - for (int a1 = mina; a1 < a0-8; a1++) - //for (int a1 = mina; a1 < maxa; a1++) - { - //nvCheck(abs(a1-a0) > 8); - - //if (abs(a0 - a1) < 8) continue; - //if ((maxa-a0) + (a1-mina) + min(abs(centroid-a0), abs(centroid-a1)) > besterror) - if ((maxa-a0) + (a1-mina) > besterror) - continue; - - dxtBlock->alpha0 = a0; - dxtBlock->alpha1 = a1; - int error = computeAlphaError(rgba, dxtBlock); - - if (error < besterror) - { - besterror = error; - besta0 = a0; - besta1 = a1; - } - } - } - - dxtBlock->alpha0 = besta0; - dxtBlock->alpha1 = besta1; - } - - computeAlphaIndices(rgba, dxtBlock); -} - diff --git a/Externals/NVTT/src/nvtt/OptimalCompressDXT.h b/Externals/NVTT/src/nvtt/OptimalCompressDXT.h deleted file mode 100644 index 3dc7a811a6a..00000000000 --- a/Externals/NVTT/src/nvtt/OptimalCompressDXT.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright NVIDIA Corporation 2008 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_OPTIMALCOMPRESSDXT_H -#define NV_TT_OPTIMALCOMPRESSDXT_H - -#include - -namespace nv -{ - struct ColorBlock; - struct BlockDXT1; - struct BlockDXT3; - struct BlockDXT5; - struct AlphaBlockDXT3; - struct AlphaBlockDXT5; - - namespace OptimalCompress - { - void compressDXT1(Color32 rgba, BlockDXT1 * dxtBlock); - void compressDXT1a(Color32 rgba, BlockDXT1 * dxtBlock); - - void compressDXT1G(const ColorBlock & rgba, BlockDXT1 * block); - void compressDXT3A(const ColorBlock & rgba, AlphaBlockDXT3 * dxtBlock); - void compressDXT5A(const ColorBlock & rgba, AlphaBlockDXT5 * dxtBlock); - } -} // nv namespace - -#endif // NV_TT_OPTIMALCOMPRESSDXT_H diff --git a/Externals/NVTT/src/nvtt/OutputOptions.cpp b/Externals/NVTT/src/nvtt/OutputOptions.cpp deleted file mode 100644 index d5afcbe0bcb..00000000000 --- a/Externals/NVTT/src/nvtt/OutputOptions.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include "OutputOptions.h" - -using namespace nvtt; - - -OutputOptions::OutputOptions() : m(*new OutputOptions::Private()) -{ - reset(); -} - -OutputOptions::~OutputOptions() -{ - delete &m; -} - -/// Set default output options. -void OutputOptions::reset() -{ - m.fileName.reset(); - m.outputHandler = NULL; - m.errorHandler = NULL; - m.outputHeader = true; -} - - -/// Set output file name. -void OutputOptions::setFileName(const char * fileName) -{ - m.fileName = fileName; - m.outputHandler = NULL; -} - -/// Set output handler. -void OutputOptions::setOutputHandler(OutputHandler * outputHandler) -{ - m.fileName.reset(); - m.outputHandler = outputHandler; -} - -/// Set error handler. -void OutputOptions::setErrorHandler(ErrorHandler * errorHandler) -{ - m.errorHandler = errorHandler; -} - -/// Set output header. -void OutputOptions::setOutputHeader(bool outputHeader) -{ - m.outputHeader = outputHeader; -} - - -bool OutputOptions::Private::openFile() const -{ - if (!fileName.isNull()) - { - nvCheck(outputHandler == NULL); - - DefaultOutputHandler * oh = new DefaultOutputHandler(fileName.str()); - if (oh->stream.isError()) - { - delete oh; - return false; - } - - outputHandler = oh; - } - - return true; -} - -void OutputOptions::Private::closeFile() const -{ - if (!fileName.isNull()) - { - delete outputHandler; - outputHandler = NULL; - } -} - diff --git a/Externals/NVTT/src/nvtt/OutputOptions.h b/Externals/NVTT/src/nvtt/OutputOptions.h deleted file mode 100644 index 3aef72b6101..00000000000 --- a/Externals/NVTT/src/nvtt/OutputOptions.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_OUTPUTOPTIONS_H -#define NV_TT_OUTPUTOPTIONS_H - -#include -#include -#include "nvtt.h" - -namespace nvtt -{ - - struct DefaultOutputHandler : public nvtt::OutputHandler - { - DefaultOutputHandler(const char * fileName) : stream(fileName) {} - - virtual ~DefaultOutputHandler() - { - } - - virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) - { - // ignore. - } - - // Output data. - virtual bool writeData(const void * data, int size) - { - stream.serialize(const_cast(data), size); - - //return !stream.isError(); - return true; - } - - nv::StdOutputStream stream; - }; - - - struct OutputOptions::Private - { - nv::Path fileName; - - mutable OutputHandler * outputHandler; - ErrorHandler * errorHandler; - bool outputHeader; - - bool openFile() const; - void closeFile() const; - }; - - -} // nvtt namespace - - -#endif // NV_TT_OUTPUTOPTIONS_H diff --git a/Externals/NVTT/src/nvtt/QuickCompressDXT.cpp b/Externals/NVTT/src/nvtt/QuickCompressDXT.cpp deleted file mode 100644 index 4eb10384d81..00000000000 --- a/Externals/NVTT/src/nvtt/QuickCompressDXT.cpp +++ /dev/null @@ -1,585 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include -#include - -#include "QuickCompressDXT.h" -#include "OptimalCompressDXT.h" - - -using namespace nv; -using namespace QuickCompress; - - - -inline static void extractColorBlockRGB(const ColorBlock & rgba, Vector3 block[16]) -{ - for (int i = 0; i < 16; i++) - { - const Color32 c = rgba.color(i); - block[i] = Vector3(c.r, c.g, c.b); - } -} - -inline static uint extractColorBlockRGBA(const ColorBlock & rgba, Vector3 block[16]) -{ - int num = 0; - - for (int i = 0; i < 16; i++) - { - const Color32 c = rgba.color(i); - if (c.a > 127) - { - block[num++] = Vector3(c.r, c.g, c.b); - } - } - - return num; -} - - -// find minimum and maximum colors based on bounding box in color space -inline static void findMinMaxColorsBox(const Vector3 * block, uint num, Vector3 * restrict maxColor, Vector3 * restrict minColor) -{ - *maxColor = Vector3(0, 0, 0); - *minColor = Vector3(255, 255, 255); - - for (uint i = 0; i < num; i++) - { - *maxColor = max(*maxColor, block[i]); - *minColor = min(*minColor, block[i]); - } -} - - -inline static void selectDiagonal(const Vector3 * block, uint num, Vector3 * restrict maxColor, Vector3 * restrict minColor) -{ - Vector3 center = (*maxColor + *minColor) * 0.5; - - Vector2 covariance = Vector2(zero); - for (uint i = 0; i < num; i++) - { - Vector3 t = block[i] - center; - covariance += t.xy() * t.z(); - } - - float x0 = maxColor->x(); - float y0 = maxColor->y(); - float x1 = minColor->x(); - float y1 = minColor->y(); - - if (covariance.x() < 0) { - swap(x0, x1); - } - if (covariance.y() < 0) { - swap(y0, y1); - } - - maxColor->set(x0, y0, maxColor->z()); - minColor->set(x1, y1, minColor->z()); -} - -inline static void insetBBox(Vector3 * restrict maxColor, Vector3 * restrict minColor) -{ - Vector3 inset = (*maxColor - *minColor) / 16.0f - (8.0f / 255.0f) / 16.0f; - *maxColor = clamp(*maxColor - inset, 0.0f, 255.0f); - *minColor = clamp(*minColor + inset, 0.0f, 255.0f); -} - -inline static uint16 roundAndExpand(Vector3 * restrict v) -{ - uint r = uint(clamp(v->x() * (31.0f / 255.0f), 0.0f, 31.0f) + 0.5f); - uint g = uint(clamp(v->y() * (63.0f / 255.0f), 0.0f, 63.0f) + 0.5f); - uint b = uint(clamp(v->z() * (31.0f / 255.0f), 0.0f, 31.0f) + 0.5f); - - uint16 w = (r << 11) | (g << 5) | b; - - r = (r << 3) | (r >> 2); - g = (g << 2) | (g >> 4); - b = (b << 3) | (b >> 2); - *v = Vector3(float(r), float(g), float(b)); - - return w; -} - -inline static float colorDistance(Vector3::Arg c0, Vector3::Arg c1) -{ - return dot(c0-c1, c0-c1); -} - -inline static uint computeIndices4(Vector3 block[16], Vector3::Arg maxColor, Vector3::Arg minColor) -{ - Vector3 palette[4]; - palette[0] = maxColor; - palette[1] = minColor; - palette[2] = lerp(palette[0], palette[1], 1.0f / 3.0f); - palette[3] = lerp(palette[0], palette[1], 2.0f / 3.0f); - - uint indices = 0; - for(int i = 0; i < 16; i++) - { - float d0 = colorDistance(palette[0], block[i]); - float d1 = colorDistance(palette[1], block[i]); - float d2 = colorDistance(palette[2], block[i]); - float d3 = colorDistance(palette[3], block[i]); - - uint b0 = d0 > d3; - uint b1 = d1 > d2; - uint b2 = d0 > d2; - uint b3 = d1 > d3; - uint b4 = d2 > d3; - - uint x0 = b1 & b2; - uint x1 = b0 & b3; - uint x2 = b0 & b4; - - indices |= (x2 | ((x0 | x1) << 1)) << (2 * i); - } - - return indices; -} - -inline static uint computeIndices3(const ColorBlock & rgba, Vector3::Arg maxColor, Vector3::Arg minColor) -{ - Vector3 palette[4]; - palette[0] = minColor; - palette[1] = maxColor; - palette[2] = (palette[0] + palette[1]) * 0.5f; - - uint indices = 0; - for(int i = 0; i < 16; i++) - { - Color32 c = rgba.color(i); - Vector3 color = Vector3(c.r, c.g, c.b); - - float d0 = colorDistance(palette[0], color); - float d1 = colorDistance(palette[1], color); - float d2 = colorDistance(palette[2], color); - - uint index; - if (c.a < 128) index = 3; - else if (d0 < d1 && d0 < d2) index = 0; - else if (d1 < d2) index = 1; - else index = 2; - - indices |= index << (2 * i); - } - - return indices; -} - - -static void optimizeEndPoints4(Vector3 block[16], BlockDXT1 * dxtBlock) -{ - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - Vector3 alphax_sum(zero); - Vector3 betax_sum(zero); - - for( int i = 0; i < 16; ++i ) - { - const uint bits = dxtBlock->indices >> (2 * i); - - float beta = float(bits & 1); - if (bits & 2) beta = (1 + beta) / 3.0f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * block[i]; - betax_sum += beta * block[i]; - } - - float denom = alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum; - if (equal(denom, 0.0f)) return; - - float factor = 1.0f / denom; - - Vector3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - Vector3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - a = clamp(a, 0, 255); - b = clamp(b, 0, 255); - - uint16 color0 = roundAndExpand(&a); - uint16 color1 = roundAndExpand(&b); - - if (color0 < color1) - { - swap(a, b); - swap(color0, color1); - } - - dxtBlock->col0 = Color16(color0); - dxtBlock->col1 = Color16(color1); - dxtBlock->indices = computeIndices4(block, a, b); -} - -/*static void optimizeEndPoints3(Vector3 block[16], BlockDXT1 * dxtBlock) -{ - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - Vector3 alphax_sum(zero); - Vector3 betax_sum(zero); - - for( int i = 0; i < 16; ++i ) - { - const uint bits = dxtBlock->indices >> (2 * i); - - float beta = (bits & 1); - if (bits & 2) beta = 0.5f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * block[i]; - betax_sum += beta * block[i]; - } - - float denom = alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum; - if (equal(denom, 0.0f)) return; - - float factor = 1.0f / denom; - - Vector3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - Vector3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - a = clamp(a, 0, 255); - b = clamp(b, 0, 255); - - uint16 color0 = roundAndExpand(&a); - uint16 color1 = roundAndExpand(&b); - - if (color0 < color1) - { - swap(a, b); - swap(color0, color1); - } - - dxtBlock->col0 = Color16(color1); - dxtBlock->col1 = Color16(color0); - dxtBlock->indices = computeIndices3(block, a, b); -}*/ - -namespace -{ - - static uint computeAlphaIndices(const ColorBlock & rgba, AlphaBlockDXT5 * block) - { - uint8 alphas[8]; - block->evaluatePalette(alphas); - - uint totalError = 0; - - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - - uint besterror = 256*256; - uint best = 8; - for(uint p = 0; p < 8; p++) - { - int d = alphas[p] - alpha; - uint error = d * d; - - if (error < besterror) - { - besterror = error; - best = p; - } - } - nvDebugCheck(best < 8); - - totalError += besterror; - block->setIndex(i, best); - } - - return totalError; - } - - static void optimizeAlpha8(const ColorBlock & rgba, AlphaBlockDXT5 * block) - { - float alpha2_sum = 0; - float beta2_sum = 0; - float alphabeta_sum = 0; - float alphax_sum = 0; - float betax_sum = 0; - - for (int i = 0; i < 16; i++) - { - uint idx = block->index(i); - float alpha; - if (idx < 2) alpha = 1.0f - idx; - else alpha = (8.0f - idx) / 7.0f; - - float beta = 1 - alpha; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * rgba.color(i).a; - betax_sum += beta * rgba.color(i).a; - } - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - uint alpha0 = uint(min(max(a, 0.0f), 255.0f)); - uint alpha1 = uint(min(max(b, 0.0f), 255.0f)); - - if (alpha0 < alpha1) - { - swap(alpha0, alpha1); - - // Flip indices: - for (int i = 0; i < 16; i++) - { - uint idx = block->index(i); - if (idx < 2) block->setIndex(i, 1 - idx); - else block->setIndex(i, 9 - idx); - } - } - else if (alpha0 == alpha1) - { - for (int i = 0; i < 16; i++) - { - block->setIndex(i, 0); - } - } - - block->alpha0 = alpha0; - block->alpha1 = alpha1; - } - - /* - static void optimizeAlpha6(const ColorBlock & rgba, AlphaBlockDXT5 * block) - { - float alpha2_sum = 0; - float beta2_sum = 0; - float alphabeta_sum = 0; - float alphax_sum = 0; - float betax_sum = 0; - - for (int i = 0; i < 16; i++) - { - uint8 x = rgba.color(i).a; - if (x == 0 || x == 255) continue; - - uint bits = block->index(i); - if (bits == 6 || bits == 7) continue; - - float alpha; - if (bits == 0) alpha = 1.0f; - else if (bits == 1) alpha = 0.0f; - else alpha = (6.0f - block->index(i)) / 5.0f; - - float beta = 1 - alpha; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * x; - betax_sum += beta * x; - } - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - uint alpha0 = uint(min(max(a, 0.0f), 255.0f)); - uint alpha1 = uint(min(max(b, 0.0f), 255.0f)); - - if (alpha0 > alpha1) - { - swap(alpha0, alpha1); - } - - block->alpha0 = alpha0; - block->alpha1 = alpha1; - } - */ - - static bool sameIndices(const AlphaBlockDXT5 & block0, const AlphaBlockDXT5 & block1) - { - const uint64 mask = ~uint64(0xFFFF); - return (block0.u | mask) == (block1.u | mask); - } - -} // namespace - - - -void QuickCompress::compressDXT1(const ColorBlock & rgba, BlockDXT1 * dxtBlock) -{ - if (rgba.isSingleColor()) - { - OptimalCompress::compressDXT1(rgba.color(0), dxtBlock); - } - else - { - // read block - Vector3 block[16]; - extractColorBlockRGB(rgba, block); - - // find min and max colors - Vector3 maxColor, minColor; - findMinMaxColorsBox(block, 16, &maxColor, &minColor); - - selectDiagonal(block, 16, &maxColor, &minColor); - - insetBBox(&maxColor, &minColor); - - uint16 color0 = roundAndExpand(&maxColor); - uint16 color1 = roundAndExpand(&minColor); - - if (color0 < color1) - { - swap(maxColor, minColor); - swap(color0, color1); - } - - dxtBlock->col0 = Color16(color0); - dxtBlock->col1 = Color16(color1); - dxtBlock->indices = computeIndices4(block, maxColor, minColor); - - optimizeEndPoints4(block, dxtBlock); - } -} - - -void QuickCompress::compressDXT1a(const ColorBlock & rgba, BlockDXT1 * dxtBlock) -{ - bool hasAlpha = false; - - for (uint i = 0; i < 16; i++) - { - if (rgba.color(i).a < 128) { - hasAlpha = true; - break; - } - } - - if (!hasAlpha) - { - compressDXT1(rgba, dxtBlock); - } - // @@ Handle single RGB, with varying alpha? We need tables for single color compressor in 3 color mode. - //else if (rgba.isSingleColorNoAlpha()) { ... } - else - { - // read block - Vector3 block[16]; - uint num = extractColorBlockRGBA(rgba, block); - - // find min and max colors - Vector3 maxColor, minColor; - findMinMaxColorsBox(block, num, &maxColor, &minColor); - - selectDiagonal(block, num, &maxColor, &minColor); - - insetBBox(&maxColor, &minColor); - - uint16 color0 = roundAndExpand(&maxColor); - uint16 color1 = roundAndExpand(&minColor); - - if (color0 < color1) - { - swap(maxColor, minColor); - swap(color0, color1); - } - - dxtBlock->col0 = Color16(color1); - dxtBlock->col1 = Color16(color0); - dxtBlock->indices = computeIndices3(rgba, maxColor, minColor); - - // optimizeEndPoints(block, dxtBlock); - } -} - - -void QuickCompress::compressDXT3(const ColorBlock & rgba, BlockDXT3 * dxtBlock) -{ - compressDXT1(rgba, &dxtBlock->color); - OptimalCompress::compressDXT3A(rgba, &dxtBlock->alpha); -} - - -void QuickCompress::compressDXT5A(const ColorBlock & rgba, AlphaBlockDXT5 * dxtBlock, int iterationCount/*=8*/) -{ - uint8 alpha0 = 0; - uint8 alpha1 = 255; - - // Get min/max alpha. - for (uint i = 0; i < 16; i++) - { - uint8 alpha = rgba.color(i).a; - alpha0 = max(alpha0, alpha); - alpha1 = min(alpha1, alpha); - } - - AlphaBlockDXT5 block; - block.alpha0 = alpha0 - (alpha0 - alpha1) / 34; - block.alpha1 = alpha1 + (alpha0 - alpha1) / 34; - uint besterror = computeAlphaIndices(rgba, &block); - - AlphaBlockDXT5 bestblock = block; - - for (int i = 0; i < iterationCount; i++) - { - optimizeAlpha8(rgba, &block); - uint error = computeAlphaIndices(rgba, &block); - - if (error >= besterror) - { - // No improvement, stop. - break; - } - if (sameIndices(block, bestblock)) - { - bestblock = block; - break; - } - - besterror = error; - bestblock = block; - }; - - // Copy best block to result; - *dxtBlock = bestblock; -} - -void QuickCompress::compressDXT5(const ColorBlock & rgba, BlockDXT5 * dxtBlock, int iterationCount/*=8*/) -{ - compressDXT1(rgba, &dxtBlock->color); - compressDXT5A(rgba, &dxtBlock->alpha, iterationCount); -} diff --git a/Externals/NVTT/src/nvtt/QuickCompressDXT.h b/Externals/NVTT/src/nvtt/QuickCompressDXT.h deleted file mode 100644 index 1297daae72b..00000000000 --- a/Externals/NVTT/src/nvtt/QuickCompressDXT.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_QUICKCOMPRESSDXT_H -#define NV_TT_QUICKCOMPRESSDXT_H - -#include - -namespace nv -{ - struct ColorBlock; - struct BlockDXT1; - struct BlockDXT3; - struct BlockDXT5; - struct AlphaBlockDXT3; - struct AlphaBlockDXT5; - - namespace QuickCompress - { - void compressDXT1(const ColorBlock & rgba, BlockDXT1 * dxtBlock); - void compressDXT1a(const ColorBlock & rgba, BlockDXT1 * dxtBlock); - - void compressDXT3(const ColorBlock & rgba, BlockDXT3 * dxtBlock); - - void compressDXT5A(const ColorBlock & rgba, AlphaBlockDXT5 * dxtBlock, int iterationCount=8); - void compressDXT5(const ColorBlock & rgba, BlockDXT5 * dxtBlock, int iterationCount=8); - } -} // nv namespace - -#endif // NV_TT_QUICKCOMPRESSDXT_H diff --git a/Externals/NVTT/src/nvtt/SingleColorLookup.h b/Externals/NVTT/src/nvtt/SingleColorLookup.h deleted file mode 100644 index 423d74efa7e..00000000000 --- a/Externals/NVTT/src/nvtt/SingleColorLookup.h +++ /dev/null @@ -1,588 +0,0 @@ - -/* -typedef unsigned char uint8; - -static int Mul8Bit(int a, int b) -{ - int t = a * b + 128; - return (t + (t >> 8)) >> 8; -} - -static inline int Lerp13(int fm, int to) -{ - return (fm * 2 + to) / 3; -} - -static void PrepareOptTable(uint8 * Table, const uint8 * expand, int size) -{ - for (int i = 0; i < 256; i++) - { - float bestErr = 256; - - for (int min = 0; min < size; min++) - { - for (int max = 0; max < size; max++) - { - int mine = expand[min]; - int maxe = expand[max]; - float err = abs(maxe + Mul8Bit(mine-maxe, 0x55) - i); - err += 0.03f * abs(max - min); - - if (err < bestErr) - { - Table[i*2+0] = max; - Table[i*2+1] = min; - bestErr = err; - } - } - } - } -} - - -void initTables() -{ - uint8 Expand5[32]; - uint8 Expand6[64]; - - for(sInt i=0;i<32;i++) - Expand5[i] = (i<<3)|(i>>2); - - for(sInt i=0;i<64;i++) - Expand6[i] = (i<<2)|(i>>4); - - PrepareOptTable(OMatch5, Expand5, 32) - PrepareOptTable(OMatch6, Expand6, 64) -}; -*/ - -#if __CUDACC__ -__constant__ unsigned short -#else -const static uint8 -#endif -OMatch5[256][2] = -{ - {0x00, 0x00}, - {0x00, 0x00}, - {0x00, 0x01}, - {0x00, 0x01}, - {0x01, 0x00}, - {0x01, 0x00}, - {0x01, 0x00}, - {0x01, 0x01}, - {0x01, 0x01}, - {0x01, 0x01}, - {0x01, 0x02}, - {0x00, 0x04}, - {0x02, 0x01}, - {0x02, 0x01}, - {0x02, 0x01}, - {0x02, 0x02}, - {0x02, 0x02}, - {0x02, 0x02}, - {0x02, 0x03}, - {0x01, 0x05}, - {0x03, 0x02}, - {0x03, 0x02}, - {0x04, 0x00}, - {0x03, 0x03}, - {0x03, 0x03}, - {0x03, 0x03}, - {0x03, 0x04}, - {0x03, 0x04}, - {0x03, 0x04}, - {0x03, 0x05}, - {0x04, 0x03}, - {0x04, 0x03}, - {0x05, 0x02}, - {0x04, 0x04}, - {0x04, 0x04}, - {0x04, 0x05}, - {0x04, 0x05}, - {0x05, 0x04}, - {0x05, 0x04}, - {0x05, 0x04}, - {0x06, 0x03}, - {0x05, 0x05}, - {0x05, 0x05}, - {0x05, 0x06}, - {0x04, 0x08}, - {0x06, 0x05}, - {0x06, 0x05}, - {0x06, 0x05}, - {0x06, 0x06}, - {0x06, 0x06}, - {0x06, 0x06}, - {0x06, 0x07}, - {0x05, 0x09}, - {0x07, 0x06}, - {0x07, 0x06}, - {0x08, 0x04}, - {0x07, 0x07}, - {0x07, 0x07}, - {0x07, 0x07}, - {0x07, 0x08}, - {0x07, 0x08}, - {0x07, 0x08}, - {0x07, 0x09}, - {0x08, 0x07}, - {0x08, 0x07}, - {0x09, 0x06}, - {0x08, 0x08}, - {0x08, 0x08}, - {0x08, 0x09}, - {0x08, 0x09}, - {0x09, 0x08}, - {0x09, 0x08}, - {0x09, 0x08}, - {0x0A, 0x07}, - {0x09, 0x09}, - {0x09, 0x09}, - {0x09, 0x0A}, - {0x08, 0x0C}, - {0x0A, 0x09}, - {0x0A, 0x09}, - {0x0A, 0x09}, - {0x0A, 0x0A}, - {0x0A, 0x0A}, - {0x0A, 0x0A}, - {0x0A, 0x0B}, - {0x09, 0x0D}, - {0x0B, 0x0A}, - {0x0B, 0x0A}, - {0x0C, 0x08}, - {0x0B, 0x0B}, - {0x0B, 0x0B}, - {0x0B, 0x0B}, - {0x0B, 0x0C}, - {0x0B, 0x0C}, - {0x0B, 0x0C}, - {0x0B, 0x0D}, - {0x0C, 0x0B}, - {0x0C, 0x0B}, - {0x0D, 0x0A}, - {0x0C, 0x0C}, - {0x0C, 0x0C}, - {0x0C, 0x0D}, - {0x0C, 0x0D}, - {0x0D, 0x0C}, - {0x0D, 0x0C}, - {0x0D, 0x0C}, - {0x0E, 0x0B}, - {0x0D, 0x0D}, - {0x0D, 0x0D}, - {0x0D, 0x0E}, - {0x0C, 0x10}, - {0x0E, 0x0D}, - {0x0E, 0x0D}, - {0x0E, 0x0D}, - {0x0E, 0x0E}, - {0x0E, 0x0E}, - {0x0E, 0x0E}, - {0x0E, 0x0F}, - {0x0D, 0x11}, - {0x0F, 0x0E}, - {0x0F, 0x0E}, - {0x10, 0x0C}, - {0x0F, 0x0F}, - {0x0F, 0x0F}, - {0x0F, 0x0F}, - {0x0F, 0x10}, - {0x0F, 0x10}, - {0x0F, 0x10}, - {0x0F, 0x11}, - {0x10, 0x0F}, - {0x10, 0x0F}, - {0x11, 0x0E}, - {0x10, 0x10}, - {0x10, 0x10}, - {0x10, 0x11}, - {0x10, 0x11}, - {0x11, 0x10}, - {0x11, 0x10}, - {0x11, 0x10}, - {0x12, 0x0F}, - {0x11, 0x11}, - {0x11, 0x11}, - {0x11, 0x12}, - {0x10, 0x14}, - {0x12, 0x11}, - {0x12, 0x11}, - {0x12, 0x11}, - {0x12, 0x12}, - {0x12, 0x12}, - {0x12, 0x12}, - {0x12, 0x13}, - {0x11, 0x15}, - {0x13, 0x12}, - {0x13, 0x12}, - {0x14, 0x10}, - {0x13, 0x13}, - {0x13, 0x13}, - {0x13, 0x13}, - {0x13, 0x14}, - {0x13, 0x14}, - {0x13, 0x14}, - {0x13, 0x15}, - {0x14, 0x13}, - {0x14, 0x13}, - {0x15, 0x12}, - {0x14, 0x14}, - {0x14, 0x14}, - {0x14, 0x15}, - {0x14, 0x15}, - {0x15, 0x14}, - {0x15, 0x14}, - {0x15, 0x14}, - {0x16, 0x13}, - {0x15, 0x15}, - {0x15, 0x15}, - {0x15, 0x16}, - {0x14, 0x18}, - {0x16, 0x15}, - {0x16, 0x15}, - {0x16, 0x15}, - {0x16, 0x16}, - {0x16, 0x16}, - {0x16, 0x16}, - {0x16, 0x17}, - {0x15, 0x19}, - {0x17, 0x16}, - {0x17, 0x16}, - {0x18, 0x14}, - {0x17, 0x17}, - {0x17, 0x17}, - {0x17, 0x17}, - {0x17, 0x18}, - {0x17, 0x18}, - {0x17, 0x18}, - {0x17, 0x19}, - {0x18, 0x17}, - {0x18, 0x17}, - {0x19, 0x16}, - {0x18, 0x18}, - {0x18, 0x18}, - {0x18, 0x19}, - {0x18, 0x19}, - {0x19, 0x18}, - {0x19, 0x18}, - {0x19, 0x18}, - {0x1A, 0x17}, - {0x19, 0x19}, - {0x19, 0x19}, - {0x19, 0x1A}, - {0x18, 0x1C}, - {0x1A, 0x19}, - {0x1A, 0x19}, - {0x1A, 0x19}, - {0x1A, 0x1A}, - {0x1A, 0x1A}, - {0x1A, 0x1A}, - {0x1A, 0x1B}, - {0x19, 0x1D}, - {0x1B, 0x1A}, - {0x1B, 0x1A}, - {0x1C, 0x18}, - {0x1B, 0x1B}, - {0x1B, 0x1B}, - {0x1B, 0x1B}, - {0x1B, 0x1C}, - {0x1B, 0x1C}, - {0x1B, 0x1C}, - {0x1B, 0x1D}, - {0x1C, 0x1B}, - {0x1C, 0x1B}, - {0x1D, 0x1A}, - {0x1C, 0x1C}, - {0x1C, 0x1C}, - {0x1C, 0x1D}, - {0x1C, 0x1D}, - {0x1D, 0x1C}, - {0x1D, 0x1C}, - {0x1D, 0x1C}, - {0x1E, 0x1B}, - {0x1D, 0x1D}, - {0x1D, 0x1D}, - {0x1D, 0x1E}, - {0x1D, 0x1E}, - {0x1E, 0x1D}, - {0x1E, 0x1D}, - {0x1E, 0x1D}, - {0x1E, 0x1E}, - {0x1E, 0x1E}, - {0x1E, 0x1E}, - {0x1E, 0x1F}, - {0x1E, 0x1F}, - {0x1F, 0x1E}, - {0x1F, 0x1E}, - {0x1F, 0x1E}, - {0x1F, 0x1F}, - {0x1F, 0x1F}, -}; - -#if __CUDACC__ -__constant__ unsigned short -#else -const static uint8 -#endif -OMatch6[256][2] = -{ - {0x00, 0x00}, - {0x00, 0x01}, - {0x01, 0x00}, - {0x01, 0x01}, - {0x01, 0x01}, - {0x01, 0x02}, - {0x02, 0x01}, - {0x02, 0x02}, - {0x02, 0x02}, - {0x02, 0x03}, - {0x03, 0x02}, - {0x03, 0x03}, - {0x03, 0x03}, - {0x03, 0x04}, - {0x04, 0x03}, - {0x04, 0x04}, - {0x04, 0x04}, - {0x04, 0x05}, - {0x05, 0x04}, - {0x05, 0x05}, - {0x05, 0x05}, - {0x05, 0x06}, - {0x06, 0x05}, - {0x00, 0x11}, - {0x06, 0x06}, - {0x06, 0x07}, - {0x07, 0x06}, - {0x02, 0x10}, - {0x07, 0x07}, - {0x07, 0x08}, - {0x08, 0x07}, - {0x03, 0x11}, - {0x08, 0x08}, - {0x08, 0x09}, - {0x09, 0x08}, - {0x05, 0x10}, - {0x09, 0x09}, - {0x09, 0x0A}, - {0x0A, 0x09}, - {0x06, 0x11}, - {0x0A, 0x0A}, - {0x0A, 0x0B}, - {0x0B, 0x0A}, - {0x08, 0x10}, - {0x0B, 0x0B}, - {0x0B, 0x0C}, - {0x0C, 0x0B}, - {0x09, 0x11}, - {0x0C, 0x0C}, - {0x0C, 0x0D}, - {0x0D, 0x0C}, - {0x0B, 0x10}, - {0x0D, 0x0D}, - {0x0D, 0x0E}, - {0x0E, 0x0D}, - {0x0C, 0x11}, - {0x0E, 0x0E}, - {0x0E, 0x0F}, - {0x0F, 0x0E}, - {0x0E, 0x10}, - {0x0F, 0x0F}, - {0x0F, 0x10}, - {0x10, 0x0E}, - {0x10, 0x0F}, - {0x11, 0x0E}, - {0x10, 0x10}, - {0x10, 0x11}, - {0x11, 0x10}, - {0x12, 0x0F}, - {0x11, 0x11}, - {0x11, 0x12}, - {0x12, 0x11}, - {0x14, 0x0E}, - {0x12, 0x12}, - {0x12, 0x13}, - {0x13, 0x12}, - {0x15, 0x0F}, - {0x13, 0x13}, - {0x13, 0x14}, - {0x14, 0x13}, - {0x17, 0x0E}, - {0x14, 0x14}, - {0x14, 0x15}, - {0x15, 0x14}, - {0x18, 0x0F}, - {0x15, 0x15}, - {0x15, 0x16}, - {0x16, 0x15}, - {0x1A, 0x0E}, - {0x16, 0x16}, - {0x16, 0x17}, - {0x17, 0x16}, - {0x1B, 0x0F}, - {0x17, 0x17}, - {0x17, 0x18}, - {0x18, 0x17}, - {0x13, 0x21}, - {0x18, 0x18}, - {0x18, 0x19}, - {0x19, 0x18}, - {0x15, 0x20}, - {0x19, 0x19}, - {0x19, 0x1A}, - {0x1A, 0x19}, - {0x16, 0x21}, - {0x1A, 0x1A}, - {0x1A, 0x1B}, - {0x1B, 0x1A}, - {0x18, 0x20}, - {0x1B, 0x1B}, - {0x1B, 0x1C}, - {0x1C, 0x1B}, - {0x19, 0x21}, - {0x1C, 0x1C}, - {0x1C, 0x1D}, - {0x1D, 0x1C}, - {0x1B, 0x20}, - {0x1D, 0x1D}, - {0x1D, 0x1E}, - {0x1E, 0x1D}, - {0x1C, 0x21}, - {0x1E, 0x1E}, - {0x1E, 0x1F}, - {0x1F, 0x1E}, - {0x1E, 0x20}, - {0x1F, 0x1F}, - {0x1F, 0x20}, - {0x20, 0x1E}, - {0x20, 0x1F}, - {0x21, 0x1E}, - {0x20, 0x20}, - {0x20, 0x21}, - {0x21, 0x20}, - {0x22, 0x1F}, - {0x21, 0x21}, - {0x21, 0x22}, - {0x22, 0x21}, - {0x24, 0x1E}, - {0x22, 0x22}, - {0x22, 0x23}, - {0x23, 0x22}, - {0x25, 0x1F}, - {0x23, 0x23}, - {0x23, 0x24}, - {0x24, 0x23}, - {0x27, 0x1E}, - {0x24, 0x24}, - {0x24, 0x25}, - {0x25, 0x24}, - {0x28, 0x1F}, - {0x25, 0x25}, - {0x25, 0x26}, - {0x26, 0x25}, - {0x2A, 0x1E}, - {0x26, 0x26}, - {0x26, 0x27}, - {0x27, 0x26}, - {0x2B, 0x1F}, - {0x27, 0x27}, - {0x27, 0x28}, - {0x28, 0x27}, - {0x23, 0x31}, - {0x28, 0x28}, - {0x28, 0x29}, - {0x29, 0x28}, - {0x25, 0x30}, - {0x29, 0x29}, - {0x29, 0x2A}, - {0x2A, 0x29}, - {0x26, 0x31}, - {0x2A, 0x2A}, - {0x2A, 0x2B}, - {0x2B, 0x2A}, - {0x28, 0x30}, - {0x2B, 0x2B}, - {0x2B, 0x2C}, - {0x2C, 0x2B}, - {0x29, 0x31}, - {0x2C, 0x2C}, - {0x2C, 0x2D}, - {0x2D, 0x2C}, - {0x2B, 0x30}, - {0x2D, 0x2D}, - {0x2D, 0x2E}, - {0x2E, 0x2D}, - {0x2C, 0x31}, - {0x2E, 0x2E}, - {0x2E, 0x2F}, - {0x2F, 0x2E}, - {0x2E, 0x30}, - {0x2F, 0x2F}, - {0x2F, 0x30}, - {0x30, 0x2E}, - {0x30, 0x2F}, - {0x31, 0x2E}, - {0x30, 0x30}, - {0x30, 0x31}, - {0x31, 0x30}, - {0x32, 0x2F}, - {0x31, 0x31}, - {0x31, 0x32}, - {0x32, 0x31}, - {0x34, 0x2E}, - {0x32, 0x32}, - {0x32, 0x33}, - {0x33, 0x32}, - {0x35, 0x2F}, - {0x33, 0x33}, - {0x33, 0x34}, - {0x34, 0x33}, - {0x37, 0x2E}, - {0x34, 0x34}, - {0x34, 0x35}, - {0x35, 0x34}, - {0x38, 0x2F}, - {0x35, 0x35}, - {0x35, 0x36}, - {0x36, 0x35}, - {0x3A, 0x2E}, - {0x36, 0x36}, - {0x36, 0x37}, - {0x37, 0x36}, - {0x3B, 0x2F}, - {0x37, 0x37}, - {0x37, 0x38}, - {0x38, 0x37}, - {0x3D, 0x2E}, - {0x38, 0x38}, - {0x38, 0x39}, - {0x39, 0x38}, - {0x3E, 0x2F}, - {0x39, 0x39}, - {0x39, 0x3A}, - {0x3A, 0x39}, - {0x3A, 0x3A}, - {0x3A, 0x3A}, - {0x3A, 0x3B}, - {0x3B, 0x3A}, - {0x3B, 0x3B}, - {0x3B, 0x3B}, - {0x3B, 0x3C}, - {0x3C, 0x3B}, - {0x3C, 0x3C}, - {0x3C, 0x3C}, - {0x3C, 0x3D}, - {0x3D, 0x3C}, - {0x3D, 0x3D}, - {0x3D, 0x3D}, - {0x3D, 0x3E}, - {0x3E, 0x3D}, - {0x3E, 0x3E}, - {0x3E, 0x3E}, - {0x3E, 0x3F}, - {0x3F, 0x3E}, - {0x3F, 0x3F}, - {0x3F, 0x3F}, -}; - diff --git a/Externals/NVTT/src/nvtt/cuda/Bitmaps.h b/Externals/NVTT/src/nvtt/cuda/Bitmaps.h deleted file mode 100644 index 1494092c113..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/Bitmaps.h +++ /dev/null @@ -1,1119 +0,0 @@ - - -/* -static void doPrecomputation() -{ - uint bitmaps[1024]; - - int indices[16]; - int num = 0; - - // Compute bitmaps with 3 clusters: - - // first cluster [0,i) is at the start - for( int m = 0; m < 16; ++m ) - { - indices[m] = 0; - } - const int imax = 15; - for( int i = imax; i >= 0; --i ) - { - // second cluster [i,j) is half along - for( int m = i; m < 16; ++m ) - { - indices[m] = 2; - } - const int jmax = ( i == 0 ) ? 15 : 16; - for( int j = jmax; j >= i; --j ) - { - // last cluster [j,k) is at the end - if( j < 16 ) - { - indices[j] = 1; - } - - uint bitmap = 0; - - for(int p = 0; p < 16; p++) { - bitmap |= indices[p] << (p * 2); - } - - bitmaps[num] = bitmap; - - num++; - } - } - nvDebugCheck(num == 151); - - // Align to 160. - for(int i = 0; i < 9; i++) - { - bitmaps[num] = 0x555AA000; - num++; - } - nvDebugCheck(num == 160); - - // Append bitmaps with 4 clusters: - - // first cluster [0,i) is at the start - for( int m = 0; m < 16; ++m ) - { - indices[m] = 0; - } - for( int i = imax; i >= 0; --i ) - { - // second cluster [i,j) is one third along - for( int m = i; m < 16; ++m ) - { - indices[m] = 2; - } - const int jmax = ( i == 0 ) ? 15 : 16; - for( int j = jmax; j >= i; --j ) - { - // third cluster [j,k) is two thirds along - for( int m = j; m < 16; ++m ) - { - indices[m] = 3; - } - - int kmax = ( j == 0 ) ? 15 : 16; - for( int k = kmax; k >= j; --k ) - { - // last cluster [k,n) is at the end - if( k < 16 ) - { - indices[k] = 1; - } - - uint bitmap = 0; - - bool hasThree = false; - for(int p = 0; p < 16; p++) { - bitmap |= indices[p] << (p * 2); - - if (indices[p] == 3) hasThree = true; - } - - if (hasThree) { - bitmaps[num] = bitmap; - num++; - } - } - } - } - nvDebugCheck(num == 975); - - // Align to 1024. - for(int i = 0; i < 49; i++) - { - bitmaps[num] = 0x555AA000; - num++; - } - - nvDebugCheck(num == 1024); - - printf("uint bitmaps[992] =\n{\n"); - for (int i = 0; i < 992; i++) - { - printf("\t0x%.8X,\n", bitmaps[i]); - } - printf("};\n"); -} -*/ - - -const static uint s_bitmapTable[992] = -{ - 0x80000000, - 0x40000000, - 0xA0000000, - 0x60000000, - 0x50000000, - 0xA8000000, - 0x68000000, - 0x58000000, - 0x54000000, - 0xAA000000, - 0x6A000000, - 0x5A000000, - 0x56000000, - 0x55000000, - 0xAA800000, - 0x6A800000, - 0x5A800000, - 0x56800000, - 0x55800000, - 0x55400000, - 0xAAA00000, - 0x6AA00000, - 0x5AA00000, - 0x56A00000, - 0x55A00000, - 0x55600000, - 0x55500000, - 0xAAA80000, - 0x6AA80000, - 0x5AA80000, - 0x56A80000, - 0x55A80000, - 0x55680000, - 0x55580000, - 0x55540000, - 0xAAAA0000, - 0x6AAA0000, - 0x5AAA0000, - 0x56AA0000, - 0x55AA0000, - 0x556A0000, - 0x555A0000, - 0x55560000, - 0x55550000, - 0xAAAA8000, - 0x6AAA8000, - 0x5AAA8000, - 0x56AA8000, - 0x55AA8000, - 0x556A8000, - 0x555A8000, - 0x55568000, - 0x55558000, - 0x55554000, - 0xAAAAA000, - 0x6AAAA000, - 0x5AAAA000, - 0x56AAA000, - 0x55AAA000, - 0x556AA000, - 0x555AA000, - 0x5556A000, - 0x5555A000, - 0x55556000, - 0x55555000, - 0xAAAAA800, - 0x6AAAA800, - 0x5AAAA800, - 0x56AAA800, - 0x55AAA800, - 0x556AA800, - 0x555AA800, - 0x5556A800, - 0x5555A800, - 0x55556800, - 0x55555800, - 0x55555400, - 0xAAAAAA00, - 0x6AAAAA00, - 0x5AAAAA00, - 0x56AAAA00, - 0x55AAAA00, - 0x556AAA00, - 0x555AAA00, - 0x5556AA00, - 0x5555AA00, - 0x55556A00, - 0x55555A00, - 0x55555600, - 0x55555500, - 0xAAAAAA80, - 0x6AAAAA80, - 0x5AAAAA80, - 0x56AAAA80, - 0x55AAAA80, - 0x556AAA80, - 0x555AAA80, - 0x5556AA80, - 0x5555AA80, - 0x55556A80, - 0x55555A80, - 0x55555680, - 0x55555580, - 0x55555540, - 0xAAAAAAA0, - 0x6AAAAAA0, - 0x5AAAAAA0, - 0x56AAAAA0, - 0x55AAAAA0, - 0x556AAAA0, - 0x555AAAA0, - 0x5556AAA0, - 0x5555AAA0, - 0x55556AA0, - 0x55555AA0, - 0x555556A0, - 0x555555A0, - 0x55555560, - 0x55555550, - 0xAAAAAAA8, - 0x6AAAAAA8, - 0x5AAAAAA8, - 0x56AAAAA8, - 0x55AAAAA8, - 0x556AAAA8, - 0x555AAAA8, - 0x5556AAA8, - 0x5555AAA8, - 0x55556AA8, - 0x55555AA8, - 0x555556A8, - 0x555555A8, - 0x55555568, - 0x55555558, - 0x55555554, - 0x6AAAAAAA, - 0x5AAAAAAA, - 0x56AAAAAA, - 0x55AAAAAA, - 0x556AAAAA, - 0x555AAAAA, - 0x5556AAAA, - 0x5555AAAA, - 0x55556AAA, - 0x55555AAA, - 0x555556AA, - 0x555555AA, - 0x5555556A, - 0x5555555A, - 0x55555556, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0x55555555, - 0xC0000000, - 0xE0000000, - 0xF0000000, - 0x70000000, - 0xE8000000, - 0xF8000000, - 0x78000000, - 0xFC000000, - 0x7C000000, - 0x5C000000, - 0xEA000000, - 0xFA000000, - 0x7A000000, - 0xFE000000, - 0x7E000000, - 0x5E000000, - 0xFF000000, - 0x7F000000, - 0x5F000000, - 0x57000000, - 0xEA800000, - 0xFA800000, - 0x7A800000, - 0xFE800000, - 0x7E800000, - 0x5E800000, - 0xFF800000, - 0x7F800000, - 0x5F800000, - 0x57800000, - 0xFFC00000, - 0x7FC00000, - 0x5FC00000, - 0x57C00000, - 0x55C00000, - 0xEAA00000, - 0xFAA00000, - 0x7AA00000, - 0xFEA00000, - 0x7EA00000, - 0x5EA00000, - 0xFFA00000, - 0x7FA00000, - 0x5FA00000, - 0x57A00000, - 0xFFE00000, - 0x7FE00000, - 0x5FE00000, - 0x57E00000, - 0x55E00000, - 0xFFF00000, - 0x7FF00000, - 0x5FF00000, - 0x57F00000, - 0x55F00000, - 0x55700000, - 0xEAA80000, - 0xFAA80000, - 0x7AA80000, - 0xFEA80000, - 0x7EA80000, - 0x5EA80000, - 0xFFA80000, - 0x7FA80000, - 0x5FA80000, - 0x57A80000, - 0xFFE80000, - 0x7FE80000, - 0x5FE80000, - 0x57E80000, - 0x55E80000, - 0xFFF80000, - 0x7FF80000, - 0x5FF80000, - 0x57F80000, - 0x55F80000, - 0x55780000, - 0xFFFC0000, - 0x7FFC0000, - 0x5FFC0000, - 0x57FC0000, - 0x55FC0000, - 0x557C0000, - 0x555C0000, - 0xEAAA0000, - 0xFAAA0000, - 0x7AAA0000, - 0xFEAA0000, - 0x7EAA0000, - 0x5EAA0000, - 0xFFAA0000, - 0x7FAA0000, - 0x5FAA0000, - 0x57AA0000, - 0xFFEA0000, - 0x7FEA0000, - 0x5FEA0000, - 0x57EA0000, - 0x55EA0000, - 0xFFFA0000, - 0x7FFA0000, - 0x5FFA0000, - 0x57FA0000, - 0x55FA0000, - 0x557A0000, - 0xFFFE0000, - 0x7FFE0000, - 0x5FFE0000, - 0x57FE0000, - 0x55FE0000, - 0x557E0000, - 0x555E0000, - 0xFFFF0000, - 0x7FFF0000, - 0x5FFF0000, - 0x57FF0000, - 0x55FF0000, - 0x557F0000, - 0x555F0000, - 0x55570000, - 0xEAAA8000, - 0xFAAA8000, - 0x7AAA8000, - 0xFEAA8000, - 0x7EAA8000, - 0x5EAA8000, - 0xFFAA8000, - 0x7FAA8000, - 0x5FAA8000, - 0x57AA8000, - 0xFFEA8000, - 0x7FEA8000, - 0x5FEA8000, - 0x57EA8000, - 0x55EA8000, - 0xFFFA8000, - 0x7FFA8000, - 0x5FFA8000, - 0x57FA8000, - 0x55FA8000, - 0x557A8000, - 0xFFFE8000, - 0x7FFE8000, - 0x5FFE8000, - 0x57FE8000, - 0x55FE8000, - 0x557E8000, - 0x555E8000, - 0xFFFF8000, - 0x7FFF8000, - 0x5FFF8000, - 0x57FF8000, - 0x55FF8000, - 0x557F8000, - 0x555F8000, - 0x55578000, - 0xFFFFC000, - 0x7FFFC000, - 0x5FFFC000, - 0x57FFC000, - 0x55FFC000, - 0x557FC000, - 0x555FC000, - 0x5557C000, - 0x5555C000, - 0xEAAAA000, - 0xFAAAA000, - 0x7AAAA000, - 0xFEAAA000, - 0x7EAAA000, - 0x5EAAA000, - 0xFFAAA000, - 0x7FAAA000, - 0x5FAAA000, - 0x57AAA000, - 0xFFEAA000, - 0x7FEAA000, - 0x5FEAA000, - 0x57EAA000, - 0x55EAA000, - 0xFFFAA000, - 0x7FFAA000, - 0x5FFAA000, - 0x57FAA000, - 0x55FAA000, - 0x557AA000, - 0xFFFEA000, - 0x7FFEA000, - 0x5FFEA000, - 0x57FEA000, - 0x55FEA000, - 0x557EA000, - 0x555EA000, - 0xFFFFA000, - 0x7FFFA000, - 0x5FFFA000, - 0x57FFA000, - 0x55FFA000, - 0x557FA000, - 0x555FA000, - 0x5557A000, - 0xFFFFE000, - 0x7FFFE000, - 0x5FFFE000, - 0x57FFE000, - 0x55FFE000, - 0x557FE000, - 0x555FE000, - 0x5557E000, - 0x5555E000, - 0xFFFFF000, - 0x7FFFF000, - 0x5FFFF000, - 0x57FFF000, - 0x55FFF000, - 0x557FF000, - 0x555FF000, - 0x5557F000, - 0x5555F000, - 0x55557000, - 0xEAAAA800, - 0xFAAAA800, - 0x7AAAA800, - 0xFEAAA800, - 0x7EAAA800, - 0x5EAAA800, - 0xFFAAA800, - 0x7FAAA800, - 0x5FAAA800, - 0x57AAA800, - 0xFFEAA800, - 0x7FEAA800, - 0x5FEAA800, - 0x57EAA800, - 0x55EAA800, - 0xFFFAA800, - 0x7FFAA800, - 0x5FFAA800, - 0x57FAA800, - 0x55FAA800, - 0x557AA800, - 0xFFFEA800, - 0x7FFEA800, - 0x5FFEA800, - 0x57FEA800, - 0x55FEA800, - 0x557EA800, - 0x555EA800, - 0xFFFFA800, - 0x7FFFA800, - 0x5FFFA800, - 0x57FFA800, - 0x55FFA800, - 0x557FA800, - 0x555FA800, - 0x5557A800, - 0xFFFFE800, - 0x7FFFE800, - 0x5FFFE800, - 0x57FFE800, - 0x55FFE800, - 0x557FE800, - 0x555FE800, - 0x5557E800, - 0x5555E800, - 0xFFFFF800, - 0x7FFFF800, - 0x5FFFF800, - 0x57FFF800, - 0x55FFF800, - 0x557FF800, - 0x555FF800, - 0x5557F800, - 0x5555F800, - 0x55557800, - 0xFFFFFC00, - 0x7FFFFC00, - 0x5FFFFC00, - 0x57FFFC00, - 0x55FFFC00, - 0x557FFC00, - 0x555FFC00, - 0x5557FC00, - 0x5555FC00, - 0x55557C00, - 0x55555C00, - 0xEAAAAA00, - 0xFAAAAA00, - 0x7AAAAA00, - 0xFEAAAA00, - 0x7EAAAA00, - 0x5EAAAA00, - 0xFFAAAA00, - 0x7FAAAA00, - 0x5FAAAA00, - 0x57AAAA00, - 0xFFEAAA00, - 0x7FEAAA00, - 0x5FEAAA00, - 0x57EAAA00, - 0x55EAAA00, - 0xFFFAAA00, - 0x7FFAAA00, - 0x5FFAAA00, - 0x57FAAA00, - 0x55FAAA00, - 0x557AAA00, - 0xFFFEAA00, - 0x7FFEAA00, - 0x5FFEAA00, - 0x57FEAA00, - 0x55FEAA00, - 0x557EAA00, - 0x555EAA00, - 0xFFFFAA00, - 0x7FFFAA00, - 0x5FFFAA00, - 0x57FFAA00, - 0x55FFAA00, - 0x557FAA00, - 0x555FAA00, - 0x5557AA00, - 0xFFFFEA00, - 0x7FFFEA00, - 0x5FFFEA00, - 0x57FFEA00, - 0x55FFEA00, - 0x557FEA00, - 0x555FEA00, - 0x5557EA00, - 0x5555EA00, - 0xFFFFFA00, - 0x7FFFFA00, - 0x5FFFFA00, - 0x57FFFA00, - 0x55FFFA00, - 0x557FFA00, - 0x555FFA00, - 0x5557FA00, - 0x5555FA00, - 0x55557A00, - 0xFFFFFE00, - 0x7FFFFE00, - 0x5FFFFE00, - 0x57FFFE00, - 0x55FFFE00, - 0x557FFE00, - 0x555FFE00, - 0x5557FE00, - 0x5555FE00, - 0x55557E00, - 0x55555E00, - 0xFFFFFF00, - 0x7FFFFF00, - 0x5FFFFF00, - 0x57FFFF00, - 0x55FFFF00, - 0x557FFF00, - 0x555FFF00, - 0x5557FF00, - 0x5555FF00, - 0x55557F00, - 0x55555F00, - 0x55555700, - 0xEAAAAA80, - 0xFAAAAA80, - 0x7AAAAA80, - 0xFEAAAA80, - 0x7EAAAA80, - 0x5EAAAA80, - 0xFFAAAA80, - 0x7FAAAA80, - 0x5FAAAA80, - 0x57AAAA80, - 0xFFEAAA80, - 0x7FEAAA80, - 0x5FEAAA80, - 0x57EAAA80, - 0x55EAAA80, - 0xFFFAAA80, - 0x7FFAAA80, - 0x5FFAAA80, - 0x57FAAA80, - 0x55FAAA80, - 0x557AAA80, - 0xFFFEAA80, - 0x7FFEAA80, - 0x5FFEAA80, - 0x57FEAA80, - 0x55FEAA80, - 0x557EAA80, - 0x555EAA80, - 0xFFFFAA80, - 0x7FFFAA80, - 0x5FFFAA80, - 0x57FFAA80, - 0x55FFAA80, - 0x557FAA80, - 0x555FAA80, - 0x5557AA80, - 0xFFFFEA80, - 0x7FFFEA80, - 0x5FFFEA80, - 0x57FFEA80, - 0x55FFEA80, - 0x557FEA80, - 0x555FEA80, - 0x5557EA80, - 0x5555EA80, - 0xFFFFFA80, - 0x7FFFFA80, - 0x5FFFFA80, - 0x57FFFA80, - 0x55FFFA80, - 0x557FFA80, - 0x555FFA80, - 0x5557FA80, - 0x5555FA80, - 0x55557A80, - 0xFFFFFE80, - 0x7FFFFE80, - 0x5FFFFE80, - 0x57FFFE80, - 0x55FFFE80, - 0x557FFE80, - 0x555FFE80, - 0x5557FE80, - 0x5555FE80, - 0x55557E80, - 0x55555E80, - 0xFFFFFF80, - 0x7FFFFF80, - 0x5FFFFF80, - 0x57FFFF80, - 0x55FFFF80, - 0x557FFF80, - 0x555FFF80, - 0x5557FF80, - 0x5555FF80, - 0x55557F80, - 0x55555F80, - 0x55555780, - 0xFFFFFFC0, - 0x7FFFFFC0, - 0x5FFFFFC0, - 0x57FFFFC0, - 0x55FFFFC0, - 0x557FFFC0, - 0x555FFFC0, - 0x5557FFC0, - 0x5555FFC0, - 0x55557FC0, - 0x55555FC0, - 0x555557C0, - 0x555555C0, - 0xEAAAAAA0, - 0xFAAAAAA0, - 0x7AAAAAA0, - 0xFEAAAAA0, - 0x7EAAAAA0, - 0x5EAAAAA0, - 0xFFAAAAA0, - 0x7FAAAAA0, - 0x5FAAAAA0, - 0x57AAAAA0, - 0xFFEAAAA0, - 0x7FEAAAA0, - 0x5FEAAAA0, - 0x57EAAAA0, - 0x55EAAAA0, - 0xFFFAAAA0, - 0x7FFAAAA0, - 0x5FFAAAA0, - 0x57FAAAA0, - 0x55FAAAA0, - 0x557AAAA0, - 0xFFFEAAA0, - 0x7FFEAAA0, - 0x5FFEAAA0, - 0x57FEAAA0, - 0x55FEAAA0, - 0x557EAAA0, - 0x555EAAA0, - 0xFFFFAAA0, - 0x7FFFAAA0, - 0x5FFFAAA0, - 0x57FFAAA0, - 0x55FFAAA0, - 0x557FAAA0, - 0x555FAAA0, - 0x5557AAA0, - 0xFFFFEAA0, - 0x7FFFEAA0, - 0x5FFFEAA0, - 0x57FFEAA0, - 0x55FFEAA0, - 0x557FEAA0, - 0x555FEAA0, - 0x5557EAA0, - 0x5555EAA0, - 0xFFFFFAA0, - 0x7FFFFAA0, - 0x5FFFFAA0, - 0x57FFFAA0, - 0x55FFFAA0, - 0x557FFAA0, - 0x555FFAA0, - 0x5557FAA0, - 0x5555FAA0, - 0x55557AA0, - 0xFFFFFEA0, - 0x7FFFFEA0, - 0x5FFFFEA0, - 0x57FFFEA0, - 0x55FFFEA0, - 0x557FFEA0, - 0x555FFEA0, - 0x5557FEA0, - 0x5555FEA0, - 0x55557EA0, - 0x55555EA0, - 0xFFFFFFA0, - 0x7FFFFFA0, - 0x5FFFFFA0, - 0x57FFFFA0, - 0x55FFFFA0, - 0x557FFFA0, - 0x555FFFA0, - 0x5557FFA0, - 0x5555FFA0, - 0x55557FA0, - 0x55555FA0, - 0x555557A0, - 0xFFFFFFE0, - 0x7FFFFFE0, - 0x5FFFFFE0, - 0x57FFFFE0, - 0x55FFFFE0, - 0x557FFFE0, - 0x555FFFE0, - 0x5557FFE0, - 0x5555FFE0, - 0x55557FE0, - 0x55555FE0, - 0x555557E0, - 0x555555E0, - 0xFFFFFFF0, - 0x7FFFFFF0, - 0x5FFFFFF0, - 0x57FFFFF0, - 0x55FFFFF0, - 0x557FFFF0, - 0x555FFFF0, - 0x5557FFF0, - 0x5555FFF0, - 0x55557FF0, - 0x55555FF0, - 0x555557F0, - 0x555555F0, - 0x55555570, - 0xEAAAAAA8, - 0xFAAAAAA8, - 0x7AAAAAA8, - 0xFEAAAAA8, - 0x7EAAAAA8, - 0x5EAAAAA8, - 0xFFAAAAA8, - 0x7FAAAAA8, - 0x5FAAAAA8, - 0x57AAAAA8, - 0xFFEAAAA8, - 0x7FEAAAA8, - 0x5FEAAAA8, - 0x57EAAAA8, - 0x55EAAAA8, - 0xFFFAAAA8, - 0x7FFAAAA8, - 0x5FFAAAA8, - 0x57FAAAA8, - 0x55FAAAA8, - 0x557AAAA8, - 0xFFFEAAA8, - 0x7FFEAAA8, - 0x5FFEAAA8, - 0x57FEAAA8, - 0x55FEAAA8, - 0x557EAAA8, - 0x555EAAA8, - 0xFFFFAAA8, - 0x7FFFAAA8, - 0x5FFFAAA8, - 0x57FFAAA8, - 0x55FFAAA8, - 0x557FAAA8, - 0x555FAAA8, - 0x5557AAA8, - 0xFFFFEAA8, - 0x7FFFEAA8, - 0x5FFFEAA8, - 0x57FFEAA8, - 0x55FFEAA8, - 0x557FEAA8, - 0x555FEAA8, - 0x5557EAA8, - 0x5555EAA8, - 0xFFFFFAA8, - 0x7FFFFAA8, - 0x5FFFFAA8, - 0x57FFFAA8, - 0x55FFFAA8, - 0x557FFAA8, - 0x555FFAA8, - 0x5557FAA8, - 0x5555FAA8, - 0x55557AA8, - 0xFFFFFEA8, - 0x7FFFFEA8, - 0x5FFFFEA8, - 0x57FFFEA8, - 0x55FFFEA8, - 0x557FFEA8, - 0x555FFEA8, - 0x5557FEA8, - 0x5555FEA8, - 0x55557EA8, - 0x55555EA8, - 0xFFFFFFA8, - 0x7FFFFFA8, - 0x5FFFFFA8, - 0x57FFFFA8, - 0x55FFFFA8, - 0x557FFFA8, - 0x555FFFA8, - 0x5557FFA8, - 0x5555FFA8, - 0x55557FA8, - 0x55555FA8, - 0x555557A8, - 0xFFFFFFE8, - 0x7FFFFFE8, - 0x5FFFFFE8, - 0x57FFFFE8, - 0x55FFFFE8, - 0x557FFFE8, - 0x555FFFE8, - 0x5557FFE8, - 0x5555FFE8, - 0x55557FE8, - 0x55555FE8, - 0x555557E8, - 0x555555E8, - 0xFFFFFFF8, - 0x7FFFFFF8, - 0x5FFFFFF8, - 0x57FFFFF8, - 0x55FFFFF8, - 0x557FFFF8, - 0x555FFFF8, - 0x5557FFF8, - 0x5555FFF8, - 0x55557FF8, - 0x55555FF8, - 0x555557F8, - 0x555555F8, - 0x55555578, - 0xFFFFFFFC, - 0x7FFFFFFC, - 0x5FFFFFFC, - 0x57FFFFFC, - 0x55FFFFFC, - 0x557FFFFC, - 0x555FFFFC, - 0x5557FFFC, - 0x5555FFFC, - 0x55557FFC, - 0x55555FFC, - 0x555557FC, - 0x555555FC, - 0x5555557C, - 0x5555555C, - 0xEAAAAAAA, - 0xFAAAAAAA, - 0x7AAAAAAA, - 0xFEAAAAAA, - 0x7EAAAAAA, - 0x5EAAAAAA, - 0xFFAAAAAA, - 0x7FAAAAAA, - 0x5FAAAAAA, - 0x57AAAAAA, - 0xFFEAAAAA, - 0x7FEAAAAA, - 0x5FEAAAAA, - 0x57EAAAAA, - 0x55EAAAAA, - 0xFFFAAAAA, - 0x7FFAAAAA, - 0x5FFAAAAA, - 0x57FAAAAA, - 0x55FAAAAA, - 0x557AAAAA, - 0xFFFEAAAA, - 0x7FFEAAAA, - 0x5FFEAAAA, - 0x57FEAAAA, - 0x55FEAAAA, - 0x557EAAAA, - 0x555EAAAA, - 0xFFFFAAAA, - 0x7FFFAAAA, - 0x5FFFAAAA, - 0x57FFAAAA, - 0x55FFAAAA, - 0x557FAAAA, - 0x555FAAAA, - 0x5557AAAA, - 0xFFFFEAAA, - 0x7FFFEAAA, - 0x5FFFEAAA, - 0x57FFEAAA, - 0x55FFEAAA, - 0x557FEAAA, - 0x555FEAAA, - 0x5557EAAA, - 0x5555EAAA, - 0xFFFFFAAA, - 0x7FFFFAAA, - 0x5FFFFAAA, - 0x57FFFAAA, - 0x55FFFAAA, - 0x557FFAAA, - 0x555FFAAA, - 0x5557FAAA, - 0x5555FAAA, - 0x55557AAA, - 0xFFFFFEAA, - 0x7FFFFEAA, - 0x5FFFFEAA, - 0x57FFFEAA, - 0x55FFFEAA, - 0x557FFEAA, - 0x555FFEAA, - 0x5557FEAA, - 0x5555FEAA, - 0x55557EAA, - 0x55555EAA, - 0xFFFFFFAA, - 0x7FFFFFAA, - 0x5FFFFFAA, - 0x57FFFFAA, - 0x55FFFFAA, - 0x557FFFAA, - 0x555FFFAA, - 0x5557FFAA, - 0x5555FFAA, - 0x55557FAA, - 0x55555FAA, - 0x555557AA, - 0xFFFFFFEA, - 0x7FFFFFEA, - 0x5FFFFFEA, - 0x57FFFFEA, - 0x55FFFFEA, - 0x557FFFEA, - 0x555FFFEA, - 0x5557FFEA, - 0x5555FFEA, - 0x55557FEA, - 0x55555FEA, - 0x555557EA, - 0x555555EA, - 0xFFFFFFFA, - 0x7FFFFFFA, - 0x5FFFFFFA, - 0x57FFFFFA, - 0x55FFFFFA, - 0x557FFFFA, - 0x555FFFFA, - 0x5557FFFA, - 0x5555FFFA, - 0x55557FFA, - 0x55555FFA, - 0x555557FA, - 0x555555FA, - 0x5555557A, - 0xFFFFFFFE, - 0x7FFFFFFE, - 0x5FFFFFFE, - 0x57FFFFFE, - 0x55FFFFFE, - 0x557FFFFE, - 0x555FFFFE, - 0x5557FFFE, - 0x5555FFFE, - 0x55557FFE, - 0x55555FFE, - 0x555557FE, - 0x555555FE, - 0x5555557E, - 0x5555555E, - 0x7FFFFFFF, - 0x5FFFFFFF, - 0x57FFFFFF, - 0x55FFFFFF, - 0x557FFFFF, - 0x555FFFFF, - 0x5557FFFF, - 0x5555FFFF, - 0x55557FFF, - 0x55555FFF, - 0x555557FF, - 0x555555FF, - 0x5555557F, - 0x5555555F, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, - 0x55555557, -}; diff --git a/Externals/NVTT/src/nvtt/cuda/CompressKernel.cu b/Externals/NVTT/src/nvtt/cuda/CompressKernel.cu deleted file mode 100644 index e3daf3e0c42..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CompressKernel.cu +++ /dev/null @@ -1,1122 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include - -#include "CudaMath.h" - -#include "../SingleColorLookup.h" - -#define NUM_THREADS 64 // Number of threads per block. - -#if __DEVICE_EMULATION__ -#define __debugsync() __syncthreads() -#else -#define __debugsync() -#endif - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; - -template -__device__ inline void swap(T & a, T & b) -{ - T tmp = a; - a = b; - b = tmp; -} - -__constant__ float3 kColorMetric = { 1.0f, 1.0f, 1.0f }; -__constant__ float3 kColorMetricSqr = { 1.0f, 1.0f, 1.0f }; - - - -//////////////////////////////////////////////////////////////////////////////// -// Sort colors -//////////////////////////////////////////////////////////////////////////////// -__device__ void sortColors(const float * values, int * cmp) -{ - int tid = threadIdx.x; - -#if 1 - cmp[tid] = (values[0] < values[tid]); - cmp[tid] += (values[1] < values[tid]); - cmp[tid] += (values[2] < values[tid]); - cmp[tid] += (values[3] < values[tid]); - cmp[tid] += (values[4] < values[tid]); - cmp[tid] += (values[5] < values[tid]); - cmp[tid] += (values[6] < values[tid]); - cmp[tid] += (values[7] < values[tid]); - cmp[tid] += (values[8] < values[tid]); - cmp[tid] += (values[9] < values[tid]); - cmp[tid] += (values[10] < values[tid]); - cmp[tid] += (values[11] < values[tid]); - cmp[tid] += (values[12] < values[tid]); - cmp[tid] += (values[13] < values[tid]); - cmp[tid] += (values[14] < values[tid]); - cmp[tid] += (values[15] < values[tid]); - - // Resolve elements with the same index. - if (tid > 0 && cmp[tid] == cmp[0]) ++cmp[tid]; - if (tid > 1 && cmp[tid] == cmp[1]) ++cmp[tid]; - if (tid > 2 && cmp[tid] == cmp[2]) ++cmp[tid]; - if (tid > 3 && cmp[tid] == cmp[3]) ++cmp[tid]; - if (tid > 4 && cmp[tid] == cmp[4]) ++cmp[tid]; - if (tid > 5 && cmp[tid] == cmp[5]) ++cmp[tid]; - if (tid > 6 && cmp[tid] == cmp[6]) ++cmp[tid]; - if (tid > 7 && cmp[tid] == cmp[7]) ++cmp[tid]; - if (tid > 8 && cmp[tid] == cmp[8]) ++cmp[tid]; - if (tid > 9 && cmp[tid] == cmp[9]) ++cmp[tid]; - if (tid > 10 && cmp[tid] == cmp[10]) ++cmp[tid]; - if (tid > 11 && cmp[tid] == cmp[11]) ++cmp[tid]; - if (tid > 12 && cmp[tid] == cmp[12]) ++cmp[tid]; - if (tid > 13 && cmp[tid] == cmp[13]) ++cmp[tid]; - if (tid > 14 && cmp[tid] == cmp[14]) ++cmp[tid]; -#else - - cmp[tid] = 0; - - #pragma unroll - for (int i = 0; i < 16; i++) - { - cmp[tid] += (values[i] < values[tid]); - } - - // Resolve elements with the same index. - #pragma unroll - for (int i = 0; i < 15; i++) - { - if (tid > 0 && cmp[tid] == cmp[i]) ++cmp[tid]; - } -#endif -} - - -//////////////////////////////////////////////////////////////////////////////// -// Load color block to shared mem -//////////////////////////////////////////////////////////////////////////////// -__device__ void loadColorBlock(const uint * image, float3 colors[16], float3 sums[16], int xrefs[16], int * sameColor) -{ - const int bid = blockIdx.x; - const int idx = threadIdx.x; - - __shared__ float dps[16]; - - if (idx < 16) - { - // Read color and copy to shared mem. - uint c = image[(bid) * 16 + idx]; - - colors[idx].z = ((c >> 0) & 0xFF) * (1.0f / 255.0f); - colors[idx].y = ((c >> 8) & 0xFF) * (1.0f / 255.0f); - colors[idx].x = ((c >> 16) & 0xFF) * (1.0f / 255.0f); - - // No need to synchronize, 16 < warp size. -#if __DEVICE_EMULATION__ - } __debugsync(); if (idx < 16) { -#endif - - // Sort colors along the best fit line. - colorSums(colors, sums); - float3 axis = bestFitLine(colors, sums[0], kColorMetric); - - *sameColor = (axis == make_float3(0, 0, 0)); - - dps[idx] = dot(colors[idx], axis); - -#if __DEVICE_EMULATION__ - } __debugsync(); if (idx < 16) { -#endif - - sortColors(dps, xrefs); - - float3 tmp = colors[idx]; - colors[xrefs[idx]] = tmp; - } -} - -__device__ void loadColorBlock(const uint * image, float3 colors[16], float3 sums[16], float weights[16], int xrefs[16], int * sameColor) -{ - const int bid = blockIdx.x; - const int idx = threadIdx.x; - - __shared__ float3 rawColors[16]; - __shared__ float dps[16]; - - if (idx < 16) - { - // Read color and copy to shared mem. - uint c = image[(bid) * 16 + idx]; - - rawColors[idx].z = ((c >> 0) & 0xFF) * (1.0f / 255.0f); - rawColors[idx].y = ((c >> 8) & 0xFF) * (1.0f / 255.0f); - rawColors[idx].x = ((c >> 16) & 0xFF) * (1.0f / 255.0f); - weights[idx] = (((c >> 24) & 0xFF) + 1) * (1.0f / 256.0f); - - colors[idx] = rawColors[idx] * weights[idx]; - - - // No need to synchronize, 16 < warp size. -#if __DEVICE_EMULATION__ - } __debugsync(); if (idx < 16) { -#endif - - // Sort colors along the best fit line. - colorSums(colors, sums); - float3 axis = bestFitLine(colors, sums[0], kColorMetric); - - *sameColor = (axis == make_float3(0, 0, 0)); - - // Single color compressor needs unweighted colors. - if (*sameColor) colors[idx] = rawColors[idx]; - - dps[idx] = dot(rawColors[idx], axis); - -#if __DEVICE_EMULATION__ - } __debugsync(); if (idx < 16) { -#endif - - sortColors(dps, xrefs); - - float3 tmp = colors[idx]; - colors[xrefs[idx]] = tmp; - - float w = weights[idx]; - weights[xrefs[idx]] = w; - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// Round color to RGB565 and expand -//////////////////////////////////////////////////////////////////////////////// -inline __device__ float3 roundAndExpand565(float3 v, ushort * w) -{ - v.x = rintf(__saturatef(v.x) * 31.0f); - v.y = rintf(__saturatef(v.y) * 63.0f); - v.z = rintf(__saturatef(v.z) * 31.0f); - *w = ((ushort)v.x << 11) | ((ushort)v.y << 5) | (ushort)v.z; - v.x *= 0.03227752766457f; // approximate integer bit expansion. - v.y *= 0.01583151765563f; - v.z *= 0.03227752766457f; - return v; -} - - -//////////////////////////////////////////////////////////////////////////////// -// Evaluate permutations -//////////////////////////////////////////////////////////////////////////////// -__device__ float evalPermutation4(const float3 * colors, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - float3 betax_sum = make_float3(0.0f, 0.0f, 0.0f); - - // Compute alpha & beta for this permutation. - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - float beta = (bits & 1); - if (bits & 2) beta = (1 + beta) / 3.0f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * colors[i]; - betax_sum += beta * colors[i]; - } - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return dot(e, kColorMetricSqr); -} - -__device__ float evalPermutation3(const float3 * colors, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - float3 betax_sum = make_float3(0.0f, 0.0f, 0.0f); - - // Compute alpha & beta for this permutation. - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - float beta = (bits & 1); - if (bits & 2) beta = 0.5f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * colors[i]; - betax_sum += beta * colors[i]; - } - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return dot(e, kColorMetricSqr); -} - -__constant__ const float alphaTable4[4] = { 9.0f, 0.0f, 6.0f, 3.0f }; -__constant__ const float alphaTable3[4] = { 4.0f, 0.0f, 2.0f, 2.0f }; -__constant__ const uint prods4[4] = { 0x090000,0x000900,0x040102,0x010402 }; -__constant__ const uint prods3[4] = { 0x040000,0x000400,0x040101,0x010401 }; - -__device__ float evalPermutation4(const float3 * colors, float3 color_sum, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - uint akku = 0; - - // Compute alpha & beta for this permutation. - #pragma unroll - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - alphax_sum += alphaTable4[bits & 3] * colors[i]; - akku += prods4[bits & 3]; - } - - float alpha2_sum = float(akku >> 16); - float beta2_sum = float((akku >> 8) & 0xff); - float alphabeta_sum = float(akku & 0xff); - float3 betax_sum = 9.0f * color_sum - alphax_sum; - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return (1.0f / 9.0f) * dot(e, kColorMetricSqr); -} - -__device__ float evalPermutation3(const float3 * colors, float3 color_sum, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - uint akku = 0; - - // Compute alpha & beta for this permutation. - #pragma unroll - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - alphax_sum += alphaTable3[bits & 3] * colors[i]; - akku += prods3[bits & 3]; - } - - float alpha2_sum = float(akku >> 16); - float beta2_sum = float((akku >> 8) & 0xff); - float alphabeta_sum = float(akku & 0xff); - float3 betax_sum = 4.0f * color_sum - alphax_sum; - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return (1.0f / 4.0f) * dot(e, kColorMetricSqr); -} - -__device__ float evalPermutation4(const float3 * colors, const float * weights, float3 color_sum, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - - // Compute alpha & beta for this permutation. - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - float beta = (bits & 1); - if (bits & 2) beta = (1 + beta) / 3.0f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha * weights[i]; - beta2_sum += beta * beta * weights[i]; - alphabeta_sum += alpha * beta * weights[i]; - alphax_sum += alpha * colors[i]; - } - - float3 betax_sum = color_sum - alphax_sum; - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return dot(e, kColorMetricSqr); -} - -/* -__device__ float evalPermutation3(const float3 * colors, const float * weights, uint permutation, ushort * start, ushort * end) -{ - // Compute endpoints using least squares. - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - float3 alphax_sum = make_float3(0.0f, 0.0f, 0.0f); - - // Compute alpha & beta for this permutation. - for (int i = 0; i < 16; i++) - { - const uint bits = permutation >> (2*i); - - float beta = (bits & 1); - if (bits & 2) beta = 0.5f; - float alpha = 1.0f - beta; - - alpha2_sum += alpha * alpha * weights[i]; - beta2_sum += beta * beta * weights[i]; - alphabeta_sum += alpha * beta * weights[i]; - alphax_sum += alpha * colors[i]; - } - - float3 betax_sum = color_sum - alphax_sum; - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - // Round a, b to the closest 5-6-5 color and expand... - a = roundAndExpand565(a, start); - b = roundAndExpand565(b, end); - - // compute the error - float3 e = a * a * alpha2_sum + b * b * beta2_sum + 2.0f * (a * b * alphabeta_sum - a * alphax_sum - b * betax_sum); - - return dot(e, kColorMetricSqr); -} -*/ - - -//////////////////////////////////////////////////////////////////////////////// -// Evaluate all permutations -//////////////////////////////////////////////////////////////////////////////// -__device__ void evalAllPermutations(const float3 * colors, float3 colorSum, const uint * permutations, ushort & bestStart, ushort & bestEnd, uint & bestPermutation, float * errors) -{ - const int idx = threadIdx.x; - - float bestError = FLT_MAX; - - __shared__ uint s_permutations[160]; - - for(int i = 0; i < 16; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 992) break; - - ushort start, end; - uint permutation = permutations[pidx]; - if (pidx < 160) s_permutations[pidx] = permutation; - - float error = evalPermutation4(colors, colorSum, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - } - } - - if (bestStart < bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= 0x55555555; // Flip indices. - } - - for(int i = 0; i < 3; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 160) break; - - ushort start, end; - uint permutation = s_permutations[pidx]; - float error = evalPermutation3(colors, colorSum, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - - if (bestStart > bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= (~bestPermutation >> 1) & 0x55555555; // Flip indices. - } - } - } - - errors[idx] = bestError; -} - -/* -__device__ void evalAllPermutations(const float3 * colors, const float * weights, const uint * permutations, ushort & bestStart, ushort & bestEnd, uint & bestPermutation, float * errors) -{ - const int idx = threadIdx.x; - - float bestError = FLT_MAX; - - __shared__ uint s_permutations[160]; - - for(int i = 0; i < 16; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 992) break; - - ushort start, end; - uint permutation = permutations[pidx]; - if (pidx < 160) s_permutations[pidx] = permutation; - - float error = evalPermutation4(colors, weights, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - } - } - - if (bestStart < bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= 0x55555555; // Flip indices. - } - - for(int i = 0; i < 3; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 160) break; - - ushort start, end; - uint permutation = s_permutations[pidx]; - float error = evalPermutation3(colors, weights, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - - if (bestStart > bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= (~bestPermutation >> 1) & 0x55555555; // Flip indices. - } - } - } - - errors[idx] = bestError; -} -*/ - -__device__ void evalLevel4Permutations(const float3 * colors, float3 colorSum, const uint * permutations, ushort & bestStart, ushort & bestEnd, uint & bestPermutation, float * errors) -{ - const int idx = threadIdx.x; - - float bestError = FLT_MAX; - - for(int i = 0; i < 16; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 992) break; - - ushort start, end; - uint permutation = permutations[pidx]; - - float error = evalPermutation4(colors, colorSum, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - } - } - - if (bestStart < bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= 0x55555555; // Flip indices. - } - - errors[idx] = bestError; -} - -__device__ void evalLevel4Permutations(const float3 * colors, const float * weights, float3 colorSum, const uint * permutations, ushort & bestStart, ushort & bestEnd, uint & bestPermutation, float * errors) -{ - const int idx = threadIdx.x; - - float bestError = FLT_MAX; - - for(int i = 0; i < 16; i++) - { - int pidx = idx + NUM_THREADS * i; - if (pidx >= 992) break; - - ushort start, end; - uint permutation = permutations[pidx]; - - float error = evalPermutation4(colors, weights, colorSum, permutation, &start, &end); - - if (error < bestError) - { - bestError = error; - bestPermutation = permutation; - bestStart = start; - bestEnd = end; - } - } - - if (bestStart < bestEnd) - { - swap(bestEnd, bestStart); - bestPermutation ^= 0x55555555; // Flip indices. - } - - errors[idx] = bestError; -} - - -//////////////////////////////////////////////////////////////////////////////// -// Find index with minimum error -//////////////////////////////////////////////////////////////////////////////// -__device__ int findMinError(float * errors) -{ - const int idx = threadIdx.x; - - __shared__ int indices[NUM_THREADS]; - indices[idx] = idx; - -#if __DEVICE_EMULATION__ - for(int d = NUM_THREADS/2; d > 0; d >>= 1) - { - __syncthreads(); - - if (idx < d) - { - float err0 = errors[idx]; - float err1 = errors[idx + d]; - - if (err1 < err0) { - errors[idx] = err1; - indices[idx] = indices[idx + d]; - } - } - } - -#else - for(int d = NUM_THREADS/2; d > 32; d >>= 1) - { - __syncthreads(); - - if (idx < d) - { - float err0 = errors[idx]; - float err1 = errors[idx + d]; - - if (err1 < err0) { - errors[idx] = err1; - indices[idx] = indices[idx + d]; - } - } - } - - __syncthreads(); - - // unroll last 6 iterations - if (idx < 32) - { - if (errors[idx + 32] < errors[idx]) { - errors[idx] = errors[idx + 32]; - indices[idx] = indices[idx + 32]; - } - if (errors[idx + 16] < errors[idx]) { - errors[idx] = errors[idx + 16]; - indices[idx] = indices[idx + 16]; - } - if (errors[idx + 8] < errors[idx]) { - errors[idx] = errors[idx + 8]; - indices[idx] = indices[idx + 8]; - } - if (errors[idx + 4] < errors[idx]) { - errors[idx] = errors[idx + 4]; - indices[idx] = indices[idx + 4]; - } - if (errors[idx + 2] < errors[idx]) { - errors[idx] = errors[idx + 2]; - indices[idx] = indices[idx + 2]; - } - if (errors[idx + 1] < errors[idx]) { - errors[idx] = errors[idx + 1]; - indices[idx] = indices[idx + 1]; - } - } -#endif - - __syncthreads(); - - return indices[0]; -} - - -//////////////////////////////////////////////////////////////////////////////// -// Save DXT block -//////////////////////////////////////////////////////////////////////////////// -__device__ void saveBlockDXT1(ushort start, ushort end, uint permutation, int xrefs[16], uint2 * result) -{ - const int bid = blockIdx.x; - - if (start == end) - { - permutation = 0; - } - - // Reorder permutation. - uint indices = 0; - for(int i = 0; i < 16; i++) - { - int ref = xrefs[i]; - indices |= ((permutation >> (2 * ref)) & 3) << (2 * i); - } - - // Write endpoints. - result[bid].x = (end << 16) | start; - - // Write palette indices. - result[bid].y = indices; -} - -__device__ void saveSingleColorBlockDXT1(float3 color, uint2 * result) -{ - const int bid = blockIdx.x; - - int r = color.x * 255; - int g = color.y * 255; - int b = color.z * 255; - - ushort color0 = (OMatch5[r][0] << 11) | (OMatch6[g][0] << 5) | OMatch5[b][0]; - ushort color1 = (OMatch5[r][1] << 11) | (OMatch6[g][1] << 5) | OMatch5[b][1]; - - if (color0 < color1) - { - result[bid].x = (color0 << 16) | color1; - result[bid].y = 0xffffffff; - } - else - { - result[bid].x = (color1 << 16) | color0; - result[bid].y = 0xaaaaaaaa; - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// Compress color block -//////////////////////////////////////////////////////////////////////////////// -__global__ void compressDXT1(const uint * permutations, const uint * image, uint2 * result) -{ - __shared__ float3 colors[16]; - __shared__ float3 sums[16]; - __shared__ int xrefs[16]; - __shared__ int sameColor; - - loadColorBlock(image, colors, sums, xrefs, &sameColor); - - __syncthreads(); - - if (sameColor) - { - if (threadIdx.x == 0) saveSingleColorBlockDXT1(colors[0], result); - return; - } - - ushort bestStart, bestEnd; - uint bestPermutation; - - __shared__ float errors[NUM_THREADS]; - - evalAllPermutations(colors, sums[0], permutations, bestStart, bestEnd, bestPermutation, errors); - - // Use a parallel reduction to find minimum error. - const int minIdx = findMinError(errors); - - // Only write the result of the winner thread. - if (threadIdx.x == minIdx) - { - saveBlockDXT1(bestStart, bestEnd, bestPermutation, xrefs, result); - } -} - -__global__ void compressLevel4DXT1(const uint * permutations, const uint * image, uint2 * result) -{ - __shared__ float3 colors[16]; - __shared__ float3 sums[16]; - __shared__ int xrefs[16]; - __shared__ int sameColor; - - loadColorBlock(image, colors, sums, xrefs, &sameColor); - - __syncthreads(); - - if (sameColor) - { - if (threadIdx.x == 0) saveSingleColorBlockDXT1(colors[0], result); - return; - } - - ushort bestStart, bestEnd; - uint bestPermutation; - - __shared__ float errors[NUM_THREADS]; - - evalLevel4Permutations(colors, sums[0], permutations, bestStart, bestEnd, bestPermutation, errors); - - // Use a parallel reduction to find minimum error. - const int minIdx = findMinError(errors); - - // Only write the result of the winner thread. - if (threadIdx.x == minIdx) - { - saveBlockDXT1(bestStart, bestEnd, bestPermutation, xrefs, result); - } -} - -__global__ void compressWeightedDXT1(const uint * permutations, const uint * image, uint2 * result) -{ - __shared__ float3 colors[16]; - __shared__ float3 sums[16]; - __shared__ float weights[16]; - __shared__ int xrefs[16]; - __shared__ int sameColor; - - loadColorBlock(image, colors, sums, weights, xrefs, &sameColor); - - __syncthreads(); - - if (sameColor) - { - if (threadIdx.x == 0) saveSingleColorBlockDXT1(colors[0], result); - return; - } - - ushort bestStart, bestEnd; - uint bestPermutation; - - __shared__ float errors[NUM_THREADS]; - - evalLevel4Permutations(colors, weights, sums[0], permutations, bestStart, bestEnd, bestPermutation, errors); - - // Use a parallel reduction to find minimum error. - int minIdx = findMinError(errors); - - // Only write the result of the winner thread. - if (threadIdx.x == minIdx) - { - saveBlockDXT1(bestStart, bestEnd, bestPermutation, xrefs, result); - } -} - - -/* -__device__ float computeError(const float weights[16], uchar a0, uchar a1) -{ - float palette[6]; - palette[0] = (6.0f/7.0f * a0 + 1.0f/7.0f * a1); - palette[1] = (5.0f/7.0f * a0 + 2.0f/7.0f * a1); - palette[2] = (4.0f/7.0f * a0 + 3.0f/7.0f * a1); - palette[3] = (3.0f/7.0f * a0 + 4.0f/7.0f * a1); - palette[4] = (2.0f/7.0f * a0 + 5.0f/7.0f * a1); - palette[5] = (1.0f/7.0f * a0 + 6.0f/7.0f * a1); - - float total = 0.0f; - - for (uint i = 0; i < 16; i++) - { - float alpha = weights[i]; - - float error = a0 - alpha; - error = min(error, palette[0] - alpha); - error = min(error, palette[1] - alpha); - error = min(error, palette[2] - alpha); - error = min(error, palette[3] - alpha); - error = min(error, palette[4] - alpha); - error = min(error, palette[5] - alpha); - error = min(error, a1 - alpha); - - total += error; - } - - return total; -} - -inline __device__ uchar roundAndExpand(float a) -{ - return rintf(__saturatef(a) * 255.0f); -} -*/ -/* -__device__ void optimizeAlpha8(const float alphas[16], uchar & a0, uchar & a1) -{ - float alpha2_sum = 0; - float beta2_sum = 0; - float alphabeta_sum = 0; - float alphax_sum = 0; - float betax_sum = 0; - - for (int i = 0; i < 16; i++) - { - uint idx = index[i]; - float alpha; - if (idx < 2) alpha = 1.0f - idx; - else alpha = (8.0f - idx) / 7.0f; - - float beta = 1 - alpha; - - alpha2_sum += alpha * alpha; - beta2_sum += beta * beta; - alphabeta_sum += alpha * beta; - alphax_sum += alpha * alphas[i]; - betax_sum += beta * alphas[i]; - } - - const float factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - float a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor; - float b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor; - - a0 = roundAndExpand8(a); - a1 = roundAndExpand8(b); -} -*/ -/* -__device__ void compressAlpha(const float alphas[16], uint4 * result) -{ - const int tid = threadIdx.x; - - // Compress alpha block! - // Brute force approach: - // Try all color pairs: 256*256/2 = 32768, 32768/64 = 512 iterations? - - // Determine min & max alphas - - float A0, A1; - - if (tid < 16) - { - __shared__ uint s_alphas[16]; - - s_alphas[tid] = alphas[tid]; - s_alphas[tid] = min(s_alphas[tid], s_alphas[tid^8]); - s_alphas[tid] = min(s_alphas[tid], s_alphas[tid^4]); - s_alphas[tid] = min(s_alphas[tid], s_alphas[tid^2]); - s_alphas[tid] = min(s_alphas[tid], s_alphas[tid^1]); - A0 = s_alphas[tid]; - - s_alphas[tid] = alphas[tid]; - s_alphas[tid] = max(s_alphas[tid], s_alphas[tid^8]); - s_alphas[tid] = max(s_alphas[tid], s_alphas[tid^4]); - s_alphas[tid] = max(s_alphas[tid], s_alphas[tid^2]); - s_alphas[tid] = max(s_alphas[tid], s_alphas[tid^1]); - A1 = s_alphas[tid]; - } - - __syncthreads(); - - int minIdx = 0; - - if (A1 - A0 > 8) - { - float bestError = FLT_MAX; - - // 64 threads -> 8x8 - // divide [A1-A0] in partitions. - // test endpoints - - for (int i = 0; i < 128; i++) - { - uint idx = (i * NUM_THREADS + tid) * 4; - uchar a0 = idx & 255; - uchar a1 = idx >> 8; - - float error = computeError(alphas, a0, a1); - - if (error < bestError) - { - bestError = error; - A0 = a0; - A1 = a1; - } - } - - __shared__ float errors[NUM_THREADS]; - errors[tid] = bestError; - - // Minimize error. - minIdx = findMinError(errors); - - } - - if (minIdx == tid) - { - // @@ Compute indices. - - // @@ Write alpha block. - } -} - -__global__ void compressDXT5(const uint * permutations, const uint * image, uint4 * result) -{ - __shared__ float3 colors[16]; - __shared__ float3 sums[16]; - __shared__ float weights[16]; - __shared__ int xrefs[16]; - - loadColorBlock(image, colors, sums, weights, xrefs); - - __syncthreads(); - - compressAlpha(weights, result); - - ushort bestStart, bestEnd; - uint bestPermutation; - - __shared__ float errors[NUM_THREADS]; - - evalLevel4Permutations(colors, weights, sums[0], permutations, bestStart, bestEnd, bestPermutation, errors); - - // Use a parallel reduction to find minimum error. - int minIdx = findMinError(errors); - - // Only write the result of the winner thread. - if (threadIdx.x == minIdx) - { - saveBlockDXT1(bestStart, bestEnd, bestPermutation, xrefs, (uint2 *)result); - } -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -// Setup kernel -//////////////////////////////////////////////////////////////////////////////// - -extern "C" void setupCompressKernel(const float weights[3]) -{ - // Set constants. - cudaMemcpyToSymbol(kColorMetric, weights, sizeof(float) * 3, 0); - - float weightsSqr[3]; - weightsSqr[0] = weights[0] * weights[0]; - weightsSqr[1] = weights[1] * weights[1]; - weightsSqr[2] = weights[2] * weights[2]; - - cudaMemcpyToSymbol(kColorMetricSqr, weightsSqr, sizeof(float) * 3, 0); -} - - -//////////////////////////////////////////////////////////////////////////////// -// Launch kernel -//////////////////////////////////////////////////////////////////////////////// - -extern "C" void compressKernelDXT1(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps) -{ - compressDXT1<<>>(d_bitmaps, d_data, (uint2 *)d_result); -} - -extern "C" void compressKernelDXT1_Level4(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps) -{ - compressLevel4DXT1<<>>(d_bitmaps, d_data, (uint2 *)d_result); -} - -extern "C" void compressWeightedKernelDXT1(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps) -{ - compressWeightedDXT1<<>>(d_bitmaps, d_data, (uint2 *)d_result); -} diff --git a/Externals/NVTT/src/nvtt/cuda/ConvolveKernel.cu b/Externals/NVTT/src/nvtt/cuda/ConvolveKernel.cu deleted file mode 100644 index 35f684da363..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/ConvolveKernel.cu +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include - -#include "CudaMath.h" - -#define TW 16 -#define TH 16 - -#define THREAD_COUNT (TW * TH) - -#define MAX_KERNEL_WIDTH 32 - -#define KW 4 - - - -#if __DEVICE_EMULATION__ -#define __debugsync() __syncthreads() -#else -#define __debugsync() -#endif - -#define TN 256 -#define WARP_COUNT (TN / 32) -#define HWARP_COUNT (TN / 16) - -// Window size -#define WS 20 - - - -struct WrapClamp -{ - int operator()(int i, int h) - { - i = min(max(i, 0), h-1); - } -}; - -struct WrapRepeat -{ - int operator()(int i, int h) - { - i = abs(i) % h; // :( Non power of two! - } -}; - -struct WrapMirror -{ - int operator()(int i, int h) - { - i = abs(i); - while (i >= h) i = 2 * w - i - 2; - } -}; - - -// Vertical convolution filter that processes vertical strips. -__global__ void convolveStrip(float * d_channel, float * d_kernel, int width, int height) -{ - __shared__ float s_kernel[32 * WS]; - - // Preload kernel in shared memory. - for (int i = 0; i < 32 * WS / TN; i++) - { - int idx = i * TN + tid; - if (idx < 32 * WS) s_kernel[idx] = d_kernel[idx]; - } - - __shared__ float s_strip[32 * WS]; // TN/32 - - int wid = tid / 32 - WS/2; - - Mirror wrap; - int row = wrap(wid); - - // Preload image block. - for (int i = 0; i < 32 * WS / TN; i++) - { - } - - // @@ Apply kernel to TN/32 rows. - - // @@ Load - - -} - - - - - - -__constant__ float inputGamma, outputInverseGamma; -__constant__ float kernel[MAX_KERNEL_WIDTH]; - -// Use texture to access input? -// That's the most simple approach. - -texture<> image; - -//////////////////////////////////////////////////////////////////////////////// -// Combined convolution filter -//////////////////////////////////////////////////////////////////////////////// - -__global__ void convolve(float4 * output) -{ - // @@ Use morton order to assing threads. - int x = threadIdx.x; - int y = threadIdx.y; - - float4 color = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - - // texture coordinate. - int2 t; - t.x = 2 * (blockIdx.x * TW + x) - HW; - t.y = blockIdx.y * TH + y; - - // @@ We might want to loop and process strips, to reuse the results of the horizontal convolutions. - - // Horizontal convolution. @@ Unroll loops. - for (int e = HW; e > 0; e--) - { - t.x++; - float w = kernel[e-1]; - color += w * tex2D(image, tc); - } - - for (int e = 0; e < HW; e++) - { - t.x++; - float w = kernel[e]; - color += w * tex2D(image, tc); - } - - // Write color to shared memory. - __shared__ float tile[4 * THREAD_COUNT]; - - int tileIdx = y * TW + x; - tile[tileIdx + 0 * THREAD_COUNT] = color.x; - tile[tileIdx + 1 * THREAD_COUNT] = color.y; - tile[tileIdx + 2 * THREAD_COUNT] = color.z; - tile[tileIdx + 3 * THREAD_COUNT] = color.w; - - __syncthreads(); - - // tile coordinate. - t.x = x; - t.y = y - HW; - - // Vertical convolution. @@ Unroll loops. - for (int i = HW; i > 0; i--) - { - float w = kernel[i-1]; - - t.y++; - int idx = t.y * TW + t.x; - - color.x += w * tile[idx + 0 * THREAD_COUNT]; - color.y += w * tile[idx + 1 * THREAD_COUNT]; - color.z += w * tile[idx + 2 * THREAD_COUNT]; - color.w += w * tile[idx + 3 * THREAD_COUNT]; - } - - for (int i = 0; i < HW; i++) - { - float w = kernel[i]; - - t.y++; - int idx = t.y * TW + t.x; - - color.x += w * tile[idx + 0 * THREAD_COUNT]; - color.y += w * tile[idx + 1 * THREAD_COUNT]; - color.z += w * tile[idx + 2 * THREAD_COUNT]; - color.w += w * tile[idx + 3 * THREAD_COUNT]; - } - - it (x < w && y < h) - { - // @@ Prevent unaligned writes. - - output[y * w + h] = color; - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// Monophase X convolution filter -//////////////////////////////////////////////////////////////////////////////// - -__device__ void convolveY() -{ - -} - - -//////////////////////////////////////////////////////////////////////////////// -// Mipmap convolution filter -//////////////////////////////////////////////////////////////////////////////// - - - -//////////////////////////////////////////////////////////////////////////////// -// Gamma correction -//////////////////////////////////////////////////////////////////////////////// - -/* -__device__ float toLinear(float f, float gamma = 2.2f) -{ - return __pow(f, gamma); -} - -__device__ float toGamma(float f, float gamma = 2.2f) -{ - return pow(f, 1.0f / gamma); -} -*/ - - - - -//////////////////////////////////////////////////////////////////////////////// -// Setup kernel -//////////////////////////////////////////////////////////////////////////////// - -extern "C" void setupConvolveKernel(const float * k, int w) -{ - w = min(w, MAX_KERNEL_WIDTH); - cudaMemcpyToSymbol(kernel, k, sizeof(float) * w, 0); -} - - -//////////////////////////////////////////////////////////////////////////////// -// Launch kernel -//////////////////////////////////////////////////////////////////////////////// - - - - diff --git a/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.cpp b/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.cpp deleted file mode 100644 index c59bedd12a7..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CudaCompressDXT.h" -#include "CudaUtils.h" - - -#if defined HAVE_CUDA -#include -#endif - -#include -#include - -using namespace nv; -using namespace nvtt; - -#if defined HAVE_CUDA - -#define MAX_BLOCKS 8192U // 32768, 65535 - - -extern "C" void setupCompressKernel(const float weights[3]); -extern "C" void compressKernelDXT1(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps); -extern "C" void compressKernelDXT1_Level4(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps); -extern "C" void compressWeightedKernelDXT1(uint blockNum, uint * d_data, uint * d_result, uint * d_bitmaps); - -#include "Bitmaps.h" // @@ Rename to BitmapTable.h - -// Convert linear image to block linear. -static void convertToBlockLinear(const Image * image, uint * blockLinearImage) -{ - const uint w = (image->width() + 3) / 4; - const uint h = (image->height() + 3) / 4; - - for(uint by = 0; by < h; by++) { - for(uint bx = 0; bx < w; bx++) { - const uint bw = min(image->width() - bx * 4, 4U); - const uint bh = min(image->height() - by * 4, 4U); - - for (uint i = 0; i < 16; i++) { - const int x = (i % 4) % bw; - const int y = (i / 4) % bh; - blockLinearImage[(by * w + bx) * 16 + i] = image->pixel(bx * 4 + x, by * 4 + y).u; - } - } - } -} - -#endif - - -CudaCompressor::CudaCompressor() : m_bitmapTable(NULL), m_data(NULL), m_result(NULL) -{ -#if defined HAVE_CUDA - // Allocate and upload bitmaps. - cudaMalloc((void**) &m_bitmapTable, 992 * sizeof(uint)); - if (m_bitmapTable != NULL) - { - cudaMemcpy(m_bitmapTable, s_bitmapTable, 992 * sizeof(uint), cudaMemcpyHostToDevice); - } - - // Allocate scratch buffers. - cudaMalloc((void**) &m_data, MAX_BLOCKS * 64U); - cudaMalloc((void**) &m_result, MAX_BLOCKS * 8U); -#endif -} - -CudaCompressor::~CudaCompressor() -{ -#if defined HAVE_CUDA - // Free device mem allocations. - cudaFree(m_data); - cudaFree(m_result); - cudaFree(m_bitmapTable); -#endif -} - -bool CudaCompressor::isValid() const -{ -#if defined HAVE_CUDA - if (cudaGetLastError() != cudaSuccess) - { - return false; - } -#endif - return m_data != NULL && m_result != NULL && m_bitmapTable != NULL; -} - -// @@ This code is very repetitive and needs to be cleaned up. - -void CudaCompressor::setImage(const Image * image, nvtt::AlphaMode alphaMode) -{ - m_image = image; - m_alphaMode = alphaMode; -} - -/// Compress image using CUDA. -void CudaCompressor::compressDXT1(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - nvDebugCheck(cuda::isHardwarePresent()); -#if defined HAVE_CUDA - - // Image size in blocks. - const uint w = (m_image->width() + 3) / 4; - const uint h = (m_image->height() + 3) / 4; - - uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); - convertToBlockLinear(m_image, blockLinearImage); // @@ Do this in parallel with the GPU, or in the GPU! - - const uint blockNum = w * h; - const uint compressedSize = blockNum * 8; - - clock_t start = clock(); - - setupCompressKernel(compressionOptions.colorWeight.ptr()); - - // TODO: Add support for multiple GPUs. - uint bn = 0; - while(bn != blockNum) - { - uint count = min(blockNum - bn, MAX_BLOCKS); - - cudaMemcpy(m_data, blockLinearImage + bn * 16, count * 64, cudaMemcpyHostToDevice); - - // Launch kernel. - compressKernelDXT1(count, m_data, m_result, m_bitmapTable); - - // Check for errors. - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - { - nvDebug("CUDA Error: %s\n", cudaGetErrorString(err)); - - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } - } - - // Copy result to host, overwrite swizzled image. - cudaMemcpy(blockLinearImage, m_result, count * 8, cudaMemcpyDeviceToHost); - - // Output result. - if (outputOptions.outputHandler != NULL) - { - outputOptions.outputHandler->writeData(blockLinearImage, count * 8); - } - - bn += count; - } - - clock_t end = clock(); - //printf("\rCUDA time taken: %.3f seconds\n", float(end-start) / CLOCKS_PER_SEC); - - free(blockLinearImage); - -#else - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } -#endif -} - - -/// Compress image using CUDA. -void CudaCompressor::compressDXT3(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - nvDebugCheck(cuda::isHardwarePresent()); -#if defined HAVE_CUDA - - // Image size in blocks. - const uint w = (m_image->width() + 3) / 4; - const uint h = (m_image->height() + 3) / 4; - - uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); - convertToBlockLinear(m_image, blockLinearImage); - - const uint blockNum = w * h; - const uint compressedSize = blockNum * 8; - - AlphaBlockDXT3 * alphaBlocks = NULL; - alphaBlocks = (AlphaBlockDXT3 *)malloc(min(compressedSize, MAX_BLOCKS * 8U)); - - setupCompressKernel(compressionOptions.colorWeight.ptr()); - - clock_t start = clock(); - - uint bn = 0; - while(bn != blockNum) - { - uint count = min(blockNum - bn, MAX_BLOCKS); - - cudaMemcpy(m_data, blockLinearImage + bn * 16, count * 64, cudaMemcpyHostToDevice); - - // Launch kernel. - if (m_alphaMode == AlphaMode_Transparency) - { - compressWeightedKernelDXT1(count, m_data, m_result, m_bitmapTable); - } - else - { - compressKernelDXT1_Level4(count, m_data, m_result, m_bitmapTable); - } - - // Compress alpha in parallel with the GPU. - for (uint i = 0; i < count; i++) - { - ColorBlock rgba(blockLinearImage + (bn + i) * 16); - OptimalCompress::compressDXT3A(rgba, alphaBlocks + i); - } - - // Check for errors. - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - { - nvDebug("CUDA Error: %s\n", cudaGetErrorString(err)); - - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } - } - - // Copy result to host, overwrite swizzled image. - cudaMemcpy(blockLinearImage, m_result, count * 8, cudaMemcpyDeviceToHost); - - // Output result. - if (outputOptions.outputHandler != NULL) - { - for (uint i = 0; i < count; i++) - { - outputOptions.outputHandler->writeData(alphaBlocks + i, 8); - outputOptions.outputHandler->writeData(blockLinearImage + i * 2, 8); - } - } - - bn += count; - } - - clock_t end = clock(); - //printf("\rCUDA time taken: %.3f seconds\n", float(end-start) / CLOCKS_PER_SEC); - - free(alphaBlocks); - free(blockLinearImage); - -#else - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } -#endif -} - - -/// Compress image using CUDA. -void CudaCompressor::compressDXT5(const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) -{ - nvDebugCheck(cuda::isHardwarePresent()); -#if defined HAVE_CUDA - - // Image size in blocks. - const uint w = (m_image->width() + 3) / 4; - const uint h = (m_image->height() + 3) / 4; - - uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); - convertToBlockLinear(m_image, blockLinearImage); - - const uint blockNum = w * h; - const uint compressedSize = blockNum * 8; - - AlphaBlockDXT5 * alphaBlocks = NULL; - alphaBlocks = (AlphaBlockDXT5 *)malloc(min(compressedSize, MAX_BLOCKS * 8U)); - - setupCompressKernel(compressionOptions.colorWeight.ptr()); - - clock_t start = clock(); - - uint bn = 0; - while(bn != blockNum) - { - uint count = min(blockNum - bn, MAX_BLOCKS); - - cudaMemcpy(m_data, blockLinearImage + bn * 16, count * 64, cudaMemcpyHostToDevice); - - // Launch kernel. - if (m_alphaMode == AlphaMode_Transparency) - { - compressWeightedKernelDXT1(count, m_data, m_result, m_bitmapTable); - } - else - { - compressKernelDXT1_Level4(count, m_data, m_result, m_bitmapTable); - } - - // Compress alpha in parallel with the GPU. - for (uint i = 0; i < count; i++) - { - ColorBlock rgba(blockLinearImage + (bn + i) * 16); - QuickCompress::compressDXT5A(rgba, alphaBlocks + i); - } - - // Check for errors. - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - { - nvDebug("CUDA Error: %s\n", cudaGetErrorString(err)); - - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } - } - - // Copy result to host, overwrite swizzled image. - cudaMemcpy(blockLinearImage, m_result, count * 8, cudaMemcpyDeviceToHost); - - // Output result. - if (outputOptions.outputHandler != NULL) - { - for (uint i = 0; i < count; i++) - { - outputOptions.outputHandler->writeData(alphaBlocks + i, 8); - outputOptions.outputHandler->writeData(blockLinearImage + i * 2, 8); - } - } - - bn += count; - } - - clock_t end = clock(); - //printf("\rCUDA time taken: %.3f seconds\n", float(end-start) / CLOCKS_PER_SEC); - - free(alphaBlocks); - free(blockLinearImage); - -#else - if (outputOptions.errorHandler != NULL) - { - outputOptions.errorHandler->error(Error_CudaError); - } -#endif -} - - diff --git a/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.h b/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.h deleted file mode 100644 index f72baccd46f..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CudaCompressDXT.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_CUDACOMPRESSDXT_H -#define NV_TT_CUDACOMPRESSDXT_H - -#include -#include - -namespace nv -{ - class Image; - - class CudaCompressor - { - public: - CudaCompressor(); - ~CudaCompressor(); - - bool isValid() const; - - void setImage(const Image * image, nvtt::AlphaMode alphaMode); - - void compressDXT1(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT3(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - void compressDXT5(const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); - - private: - - uint * m_bitmapTable; - uint * m_data; - uint * m_result; - - const Image * m_image; - nvtt::AlphaMode m_alphaMode; - }; - -} // nv namespace - - -#endif // NV_TT_CUDAUTILS_H diff --git a/Externals/NVTT/src/nvtt/cuda/CudaMath.h b/Externals/NVTT/src/nvtt/cuda/CudaMath.h deleted file mode 100644 index 7158070d15e..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CudaMath.h +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// Math functions and operators to be used with vector types. - -#ifndef CUDAMATH_H -#define CUDAMATH_H - -#include - - -inline __device__ __host__ float3 operator *(float3 a, float3 b) -{ - return make_float3(a.x*b.x, a.y*b.y, a.z*b.z); -} - -inline __device__ __host__ float3 operator *(float f, float3 v) -{ - return make_float3(v.x*f, v.y*f, v.z*f); -} - -inline __device__ __host__ float3 operator *(float3 v, float f) -{ - return make_float3(v.x*f, v.y*f, v.z*f); -} - -inline __device__ __host__ float3 operator +(float3 a, float3 b) -{ - return make_float3(a.x+b.x, a.y+b.y, a.z+b.z); -} - -inline __device__ __host__ void operator +=(float3 & b, float3 a) -{ - b.x += a.x; - b.y += a.y; - b.z += a.z; -} - -inline __device__ __host__ float3 operator -(float3 a, float3 b) -{ - return make_float3(a.x-b.x, a.y-b.y, a.z-b.z); -} - -inline __device__ __host__ void operator -=(float3 & b, float3 a) -{ - b.x -= a.x; - b.y -= a.y; - b.z -= a.z; -} - -inline __device__ __host__ float3 operator /(float3 v, float f) -{ - float inv = 1.0f / f; - return v * inv; -} - -inline __device__ __host__ void operator /=(float3 & b, float f) -{ - float inv = 1.0f / f; - b.x *= inv; - b.y *= inv; - b.z *= inv; -} - -inline __device__ __host__ bool operator ==(float3 a, float3 b) -{ - return a.x == b.x && a.y == b.y && a.z == b.z; -} - -inline __device__ __host__ float dot(float3 a, float3 b) -{ - return a.x * b.x + a.y * b.y + a.z * b.z; -} - -inline __device__ __host__ float dot(float4 a, float4 b) -{ - return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; -} - -inline __device__ __host__ float clamp(float f, float a, float b) -{ - return max(a, min(f, b)); -} - -inline __device__ __host__ float3 clamp(float3 v, float a, float b) -{ - return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); -} - -inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b) -{ - return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); -} - - -inline __device__ __host__ float3 normalize(float3 v) -{ - float len = 1.0f / sqrtf(dot(v, v)); - return make_float3(v.x * len, v.y * len, v.z * len); -} - - - - -// Use power method to find the first eigenvector. -// http://www.miislita.com/information-retrieval-tutorial/matrix-tutorial-3-eigenvalues-eigenvectors.html -inline __device__ __host__ float3 firstEigenVector( float matrix[6] ) -{ - // 8 iterations seems to be more than enough. - - float3 row0 = make_float3(matrix[0], matrix[1], matrix[2]); - float3 row1 = make_float3(matrix[1], matrix[3], matrix[4]); - float3 row2 = make_float3(matrix[2], matrix[4], matrix[5]); - - float r0 = dot(row0, row0); - float r1 = dot(row1, row1); - float r2 = dot(row2, row2); - - float3 v; - if (r0 > r1 && r0 > r2) v = row0; - else if (r1 > r2) v = row1; - else v = row2; - - //float3 v = make_float3(1.0f, 1.0f, 1.0f); - for(int i = 0; i < 8; i++) { - float x = v.x * matrix[0] + v.y * matrix[1] + v.z * matrix[2]; - float y = v.x * matrix[1] + v.y * matrix[3] + v.z * matrix[4]; - float z = v.x * matrix[2] + v.y * matrix[4] + v.z * matrix[5]; - float m = max(max(x, y), z); - float iv = 1.0f / m; - if (m == 0.0f) iv = 0.0f; - v = make_float3(x*iv, y*iv, z*iv); - } - - return v; -} - -inline __device__ bool singleColor(const float3 * colors) -{ -#if __DEVICE_EMULATION__ - bool sameColor = false; - for (int i = 0; i < 16; i++) - { - sameColor &= (colors[i] == colors[0]); - } - return sameColor; -#else - __shared__ int sameColor[16]; - - const int idx = threadIdx.x; - - sameColor[idx] = (colors[idx] == colors[0]); - sameColor[idx] &= sameColor[idx^8]; - sameColor[idx] &= sameColor[idx^4]; - sameColor[idx] &= sameColor[idx^2]; - sameColor[idx] &= sameColor[idx^1]; - - return sameColor[0]; -#endif -} - -inline __device__ void colorSums(const float3 * colors, float3 * sums) -{ -#if __DEVICE_EMULATION__ - float3 color_sum = make_float3(0.0f, 0.0f, 0.0f); - for (int i = 0; i < 16; i++) - { - color_sum += colors[i]; - } - - for (int i = 0; i < 16; i++) - { - sums[i] = color_sum; - } -#else - - const int idx = threadIdx.x; - - sums[idx] = colors[idx]; - sums[idx] += sums[idx^8]; - sums[idx] += sums[idx^4]; - sums[idx] += sums[idx^2]; - sums[idx] += sums[idx^1]; - -#endif -} - -inline __device__ float3 bestFitLine(const float3 * colors, float3 color_sum, float3 colorMetric) -{ - // Compute covariance matrix of the given colors. -#if __DEVICE_EMULATION__ - float covariance[6] = {0, 0, 0, 0, 0, 0}; - for (int i = 0; i < 16; i++) - { - float3 a = (colors[i] - color_sum * (1.0f / 16.0f)) * colorMetric; - covariance[0] += a.x * a.x; - covariance[1] += a.x * a.y; - covariance[2] += a.x * a.z; - covariance[3] += a.y * a.y; - covariance[4] += a.y * a.z; - covariance[5] += a.z * a.z; - } -#else - - const int idx = threadIdx.x; - - float3 diff = (colors[idx] - color_sum * (1.0f / 16.0f)) * colorMetric; - - // @@ Eliminate two-way bank conflicts here. - // @@ It seems that doing that and unrolling the reduction doesn't help... - __shared__ float covariance[16*6]; - - covariance[6 * idx + 0] = diff.x * diff.x; // 0, 6, 12, 2, 8, 14, 4, 10, 0 - covariance[6 * idx + 1] = diff.x * diff.y; - covariance[6 * idx + 2] = diff.x * diff.z; - covariance[6 * idx + 3] = diff.y * diff.y; - covariance[6 * idx + 4] = diff.y * diff.z; - covariance[6 * idx + 5] = diff.z * diff.z; - - for(int d = 8; d > 0; d >>= 1) - { - if (idx < d) - { - covariance[6 * idx + 0] += covariance[6 * (idx+d) + 0]; - covariance[6 * idx + 1] += covariance[6 * (idx+d) + 1]; - covariance[6 * idx + 2] += covariance[6 * (idx+d) + 2]; - covariance[6 * idx + 3] += covariance[6 * (idx+d) + 3]; - covariance[6 * idx + 4] += covariance[6 * (idx+d) + 4]; - covariance[6 * idx + 5] += covariance[6 * (idx+d) + 5]; - } - } - -#endif - - // Compute first eigen vector. - return firstEigenVector(covariance); -} - - -#endif // CUDAMATH_H diff --git a/Externals/NVTT/src/nvtt/cuda/CudaUtils.cpp b/Externals/NVTT/src/nvtt/cuda/CudaUtils.cpp deleted file mode 100644 index 49de873c77f..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CudaUtils.cpp +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include "CudaUtils.h" - -#if defined HAVE_CUDA -#include -#include -#endif - -using namespace nv; -using namespace cuda; - -/* @@ Move this to win32 utils or somewhere else. -#if NV_OS_WIN32 - -#define WINDOWS_LEAN_AND_MEAN -#include - -static bool isWindowsVista() -{ -OSVERSIONINFO osvi; -osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - -::GetVersionEx(&osvi); -return osvi.dwMajorVersion >= 6; -} - - -typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); - -static bool isWow32() -{ -LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process"); - -BOOL bIsWow64 = FALSE; - -if (NULL != fnIsWow64Process) -{ -if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) -{ -// Assume 32 bits. -return true; -} -} - -return !bIsWow64; -} - -#endif -*/ - - -static bool isCudaDriverAvailable(int version) -{ -#if defined HAVE_CUDA -#if NV_OS_WIN32 - Library nvcuda("nvcuda.dll"); -#else - Library nvcuda(NV_LIBRARY_NAME(cuda)); -#endif - - if (!nvcuda.isValid()) - { - nvDebug("*** CUDA driver not found.\n"); - return false; - } - - if (version >= 2000) - { - void * address = nvcuda.bindSymbol("cuStreamCreate"); - if (address == NULL) { - nvDebug("*** CUDA driver version < 2.0.\n"); - return false; - } - } - - if (version >= 2010) - { - void * address = nvcuda.bindSymbol("cuModuleLoadDataEx"); - if (address == NULL) { - nvDebug("*** CUDA driver version < 2.1.\n"); - return false; - } - } - - if (version >= 2020) - { - typedef CUresult (CUDAAPI * PFCU_DRIVERGETVERSION)(int * version); - - PFCU_DRIVERGETVERSION driverGetVersion = (PFCU_DRIVERGETVERSION)nvcuda.bindSymbol("cuDriverGetVersion"); - if (driverGetVersion == NULL) { - nvDebug("*** CUDA driver version < 2.2.\n"); - return false; - } - - int driverVersion; - CUresult err = driverGetVersion(&driverVersion); - if (err != CUDA_SUCCESS) { - nvDebug("*** Error querying driver version: '%s'.\n", cudaGetErrorString((cudaError_t)err)); - return false; - } - - return driverVersion >= version; - } -#endif // HAVE_CUDA - - return true; -} - - -/// Determine if CUDA is available. -bool nv::cuda::isHardwarePresent() -{ -#if defined HAVE_CUDA - // Make sure that CUDA driver matches CUDA runtime. - if (!isCudaDriverAvailable(CUDART_VERSION)) - { - nvDebug("CUDA driver not available for CUDA runtime %d\n", CUDART_VERSION); - return false; - } - - int count = deviceCount(); - if (count == 1) - { - // Make sure it's not an emulation device. - cudaDeviceProp deviceProp; - cudaGetDeviceProperties(&deviceProp, 0); - - // deviceProp.name != Device Emulation (CPU) - if (deviceProp.major == -1 || deviceProp.minor == -1) - { - return false; - } - } - - // @@ Make sure that warp size == 32 - - // @@ Make sure available GPU is faster than the CPU. - - return count > 0; -#else - return false; -#endif -} - -/// Get number of CUDA enabled devices. -int nv::cuda::deviceCount() -{ -#if defined HAVE_CUDA - int gpuCount = 0; - - cudaError_t result = cudaGetDeviceCount(&gpuCount); - - if (result == cudaSuccess) - { - return gpuCount; - } -#endif - return 0; -} - - -// Make sure device meets requirements: -// - Not an emulation device. -// - Not an integrated device? -// - Faster than CPU. -bool nv::cuda::isValidDevice(int i) -{ -#if defined HAVE_CUDA - - cudaDeviceProp device_properties; - cudaGetDeviceProperties(&device_properties, i); - int gflops = device_properties.multiProcessorCount * device_properties.clockRate; - - if (device_properties.major == -1 || device_properties.minor == -1) { - // Emulation device. - return false; - } - -#if CUDART_VERSION >= 2030 // 2.3 - /*if (device_properties.integrated) - { - // Integrated devices. - return false; - }*/ -#endif - - return true; -#else - return false; -#endif -} - -int nv::cuda::getFastestDevice() -{ - int max_gflops_device = -1; -#if defined HAVE_CUDA - int max_gflops = 0; - - const int device_count = deviceCount(); - for (int i = 0; i < device_count; i++) - { - if (isValidDevice(i)) - { - cudaDeviceProp device_properties; - cudaGetDeviceProperties(&device_properties, i); - int gflops = device_properties.multiProcessorCount * device_properties.clockRate; - - if (gflops > max_gflops) - { - max_gflops = gflops; - max_gflops_device = i; - } - } - } -#endif - return max_gflops_device; -} - - -/// Activate the given devices. -bool nv::cuda::initDevice(int * device_ptr) -{ - nvDebugCheck(device_ptr != NULL); -#if defined HAVE_CUDA - -#if CUDART_VERSION >= 2030 // 2.3 - - // Set device flags to yield in order to play nice with other threads and to find out if CUDA was already active. - cudaError_t resul = cudaSetDeviceFlags(cudaDeviceScheduleYield); - -#endif - - int device = getFastestDevice(); - - if (device == -1) - { - // No device is fast enough. - *device_ptr = -1; - return false; - } - - // Select CUDA device. - cudaError_t result = cudaSetDevice(device); - - if (result == cudaErrorSetOnActiveProcess) - { - int device; - result = cudaGetDevice(&device); - - *device_ptr = -1; // No device to cleanup. - return isValidDevice(device); // Return true if device is valid. - } - else if (result != cudaSuccess) - { - nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result)); - *device_ptr = -1; - return false; - } - - *device_ptr = device; - return true; -#else - return false; -#endif -} - -void nv::cuda::exitDevice() -{ -#if defined HAVE_CUDA - cudaError_t result = cudaThreadExit(); - - if (result != cudaSuccess) { - nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result)); - } -#endif -} diff --git a/Externals/NVTT/src/nvtt/cuda/CudaUtils.h b/Externals/NVTT/src/nvtt/cuda/CudaUtils.h deleted file mode 100644 index 7128b4d1eef..00000000000 --- a/Externals/NVTT/src/nvtt/cuda/CudaUtils.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_CUDAUTILS_H -#define NV_TT_CUDAUTILS_H - -namespace nv -{ - - namespace cuda - { - bool isHardwarePresent(); - int deviceCount(); - int getFastestDevice(); - bool isValidDevice(int i); - - bool initDevice(int * device_ptr); - void exitDevice(); - }; - -} // nv namespace - - -#endif // NV_TT_CUDAUTILS_H diff --git a/Externals/NVTT/src/nvtt/nvtt.cpp b/Externals/NVTT/src/nvtt/nvtt.cpp deleted file mode 100644 index 13140fd19db..00000000000 --- a/Externals/NVTT/src/nvtt/nvtt.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include "nvtt.h" - -using namespace nvtt; - -/// Return a string for the given error. -const char * nvtt::errorString(Error e) -{ - switch(e) - { - case Error_Unknown: - return "Unknown error"; - case Error_InvalidInput: - return "Invalid input"; - case Error_UnsupportedFeature: - return "Unsupported feature"; - case Error_CudaError: - return "CUDA error"; - case Error_FileOpen: - return "Error opening file"; - case Error_FileWrite: - return "Error writing through output handler"; - } - - return "Invalid error"; -} - -/// Return NVTT version. -unsigned int nvtt::version() -{ - return NVTT_VERSION; -} - diff --git a/Externals/NVTT/src/nvtt/nvtt.h b/Externals/NVTT/src/nvtt/nvtt.h deleted file mode 100644 index 6ce6deb90de..00000000000 --- a/Externals/NVTT/src/nvtt/nvtt.h +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NV_TT_H -#define NV_TT_H - -// Function linkage -#if NVTT_SHARED - -#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__ -# ifdef NVTT_EXPORTS -# define NVTT_API __declspec(dllexport) -# else -# define NVTT_API __declspec(dllimport) -# endif -#endif - -#if defined __GNUC__ >= 4 -# ifdef NVTT_EXPORTS -# define NVTT_API __attribute__((visibility("default"))) -# endif -#endif - -#endif // NVTT_SHARED - -#if !defined NVTT_API -# define NVTT_API -#endif - -#define NVTT_VERSION 200 - -#define NVTT_DECLARE_PIMPL(Class) \ - private: \ - Class(const Class &); \ - void operator=(const Class &); \ - public: \ - struct Private; \ - Private & m - - -// Public interface. -namespace nvtt -{ - /// Supported compression formats. - enum Format - { - // No compression. - Format_RGB, - Format_RGBA = Format_RGB, - - // DX9 formats. - Format_DXT1, - Format_DXT1a, // DXT1 with binary alpha. - Format_DXT3, - Format_DXT5, - Format_DXT5n, // Compressed HILO: R=1, G=y, B=0, A=x - - // DX10 formats. - Format_BC1 = Format_DXT1, - Format_BC1a = Format_DXT1a, - Format_BC2 = Format_DXT3, - Format_BC3 = Format_DXT5, - Format_BC3n = Format_DXT5n, - Format_BC4, // ATI1 - Format_BC5, // 3DC, ATI2 - }; - - /// Quality modes. - enum Quality - { - Quality_Fastest, - Quality_Normal, - Quality_Production, - Quality_Highest, - }; - - /// Compression options. This class describes the desired compression format and other compression settings. - struct CompressionOptions - { - NVTT_DECLARE_PIMPL(CompressionOptions); - - NVTT_API CompressionOptions(); - NVTT_API ~CompressionOptions(); - - NVTT_API void reset(); - - NVTT_API void setFormat(Format format); - NVTT_API void setQuality(Quality quality); - NVTT_API void setColorWeights(float red, float green, float blue, float alpha = 1.0f); - - NVTT_API void setExternalCompressor(const char * name); - - // Set color mask to describe the RGB/RGBA format. - NVTT_API void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); - - NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127); - }; - - - /// Wrap modes. - enum WrapMode - { - WrapMode_Clamp, - WrapMode_Repeat, - WrapMode_Mirror, - }; - - /// Texture types. - enum TextureType - { - TextureType_2D, - TextureType_Cube, - // TextureType_3D, - }; - - /// Input formats. - enum InputFormat - { - InputFormat_BGRA_8UB, - // InputFormat_RGBE_8UB, - // InputFormat_BGRA_32F, - }; - - /// Mipmap downsampling filters. - enum MipmapFilter - { - MipmapFilter_Box, ///< Box filter is quite good and very fast. - MipmapFilter_Triangle, ///< Triangle filter blurs the results too much, but that might be what you want. - MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter. - }; - - /// Color transformation. - enum ColorTransform - { - ColorTransform_None, - ColorTransform_Linear, - }; - - /// Extents rounding mode. - enum RoundMode - { - RoundMode_None, - RoundMode_ToNextPowerOfTwo, - RoundMode_ToNearestPowerOfTwo, - RoundMode_ToPreviousPowerOfTwo, - }; - - /// Alpha mode. - enum AlphaMode - { - AlphaMode_None, - AlphaMode_Transparency, - AlphaMode_Premultiplied, - }; - - /// Input options. Specify format and layout of the input texture. - struct InputOptions - { - NVTT_DECLARE_PIMPL(InputOptions); - - NVTT_API InputOptions(); - NVTT_API ~InputOptions(); - - // Set default options. - NVTT_API void reset(); - - // Setup input layout. - NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1); - NVTT_API void resetTextureLayout(); - - // Set mipmap data. Copies the data. - NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0); - - // Describe the format of the input. - NVTT_API void setFormat(InputFormat format); - - // Set the way the input alpha channel is interpreted. - NVTT_API void setAlphaMode(AlphaMode alphaMode); - - // Set gamma settings. - NVTT_API void setGamma(float inputGamma, float outputGamma); - - // Set texture wrappign mode. - NVTT_API void setWrapMode(WrapMode mode); - - // Set mipmapping options. - NVTT_API void setMipmapFilter(MipmapFilter filter); - NVTT_API void setMipmapGeneration(bool enabled, int maxLevel = -1); - NVTT_API void setKaiserParameters(float width, float alpha, float stretch); - - // Set normal map options. - NVTT_API void setNormalMap(bool b); - NVTT_API void setConvertToNormalMap(bool convert); - NVTT_API void setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale); - NVTT_API void setNormalFilter(float sm, float medium, float big, float large); - NVTT_API void setNormalizeMipmaps(bool b); - - // Set color transforms. @@ Not implemented! - NVTT_API void setColorTransform(ColorTransform t); - NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3); - - // Set resizing options. - NVTT_API void setMaxExtents(int d); - NVTT_API void setRoundMode(RoundMode mode); - }; - - - /// Output handler. - struct OutputHandler - { - virtual ~OutputHandler() {} - - /// Indicate the start of a new compressed image that's part of the final texture. - virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) = 0; - - /// Output data. Compressed data is output as soon as it's generated to minimize memory allocations. - virtual bool writeData(const void * data, int size) = 0; - }; - - /// Error codes. - enum Error - { - Error_Unknown, - Error_InvalidInput, - Error_UnsupportedFeature, - Error_CudaError, - Error_FileOpen, - Error_FileWrite, - }; - - /// Error handler. - struct ErrorHandler - { - virtual ~ErrorHandler() {} - - // Signal error. - virtual void error(Error e) = 0; - }; - - - /// Output Options. This class holds pointers to the interfaces that are used to report the output of - /// the compressor to the user. - struct OutputOptions - { - NVTT_DECLARE_PIMPL(OutputOptions); - - NVTT_API OutputOptions(); - NVTT_API ~OutputOptions(); - - // Set default options. - NVTT_API void reset(); - - NVTT_API void setFileName(const char * fileName); - - NVTT_API void setOutputHandler(OutputHandler * outputHandler); - NVTT_API void setErrorHandler(ErrorHandler * errorHandler); - NVTT_API void setOutputHeader(bool outputHeader); - }; - - - /// Texture compressor. - struct Compressor - { - NVTT_DECLARE_PIMPL(Compressor); - - NVTT_API Compressor(); - NVTT_API ~Compressor(); - - NVTT_API void enableCudaAcceleration(bool enable); - NVTT_API bool isCudaAccelerationEnabled() const; - - // Main entrypoint of the compression library. - NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; - - // Estimate the size of compressing the input with the given options. - NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const; - }; - - - // Return string for the given error code. - NVTT_API const char * errorString(Error e); - - // Return NVTT version. - NVTT_API unsigned int version(); - -} // nvtt namespace - -#endif // NV_TT_H diff --git a/Externals/NVTT/src/nvtt/nvtt_wrapper.cpp b/Externals/NVTT/src/nvtt/nvtt_wrapper.cpp deleted file mode 100644 index 136a99d7ff4..00000000000 --- a/Externals/NVTT/src/nvtt/nvtt_wrapper.cpp +++ /dev/null @@ -1,208 +0,0 @@ - -#include "nvtt.h" -#include "nvtt_wrapper.h" - - -// InputOptions class. -NvttInputOptions * nvttCreateInputOptions() -{ - return new nvtt::InputOptions(); -} - -void nvttDestroyInputOptions(NvttInputOptions * inputOptions) -{ - delete inputOptions; -} - -void nvttSetInputOptionsTextureLayout(NvttInputOptions * inputOptions, NvttTextureType type, int w, int h, int d) -{ - inputOptions->setTextureLayout((nvtt::TextureType)type, w, h, d); -} - -void nvttResetInputOptionsTextureLayout(NvttInputOptions * inputOptions) -{ - inputOptions->resetTextureLayout(); -} - -NvttBoolean nvttSetInputOptionsMipmapData(NvttInputOptions * inputOptions, const void * data, int w, int h, int d, int face, int mipmap) -{ - return (NvttBoolean)inputOptions->setMipmapData(data, w, h, d, face, mipmap); -} - -void nvttSetInputOptionsFormat(NvttInputOptions * inputOptions, NvttInputFormat format) -{ - inputOptions->setFormat((nvtt::InputFormat)format); -} - -void nvttSetInputOptionsAlphaMode(NvttInputOptions * inputOptions, NvttAlphaMode alphaMode) -{ - inputOptions->setAlphaMode((nvtt::AlphaMode)alphaMode); -} - -void nvttSetInputOptionsGamma(NvttInputOptions * inputOptions, float inputGamma, float outputGamma) -{ - inputOptions->setGamma(inputGamma, outputGamma); -} - -void nvttSetInputOptionsWrapMode(NvttInputOptions * inputOptions, NvttWrapMode mode) -{ - inputOptions->setWrapMode((nvtt::WrapMode)mode); -} - -void nvttSetInputOptionsMipmapFilter(NvttInputOptions * inputOptions, NvttMipmapFilter filter) -{ - inputOptions->setMipmapFilter((nvtt::MipmapFilter)filter); -} - -void nvttSetInputOptionsMipmapGeneration(NvttInputOptions * inputOptions, NvttBoolean enabled, int maxLevel) -{ - inputOptions->setMipmapGeneration(enabled != NVTT_False, maxLevel); -} - -void nvttSetInputOptionsKaiserParameters(NvttInputOptions * inputOptions, float width, float alpha, float stretch) -{ - inputOptions->setKaiserParameters(width, alpha, stretch); -} - -void nvttSetInputOptionsNormalMap(NvttInputOptions * inputOptions, NvttBoolean b) -{ - inputOptions->setNormalMap(b != NVTT_False); -} - -void nvttSetInputOptionsConvertToNormalMap(NvttInputOptions * inputOptions, NvttBoolean convert) -{ - inputOptions->setConvertToNormalMap(convert != NVTT_False); -} - -void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale) -{ - inputOptions->setHeightEvaluation(redScale, greenScale, blueScale, alphaScale); -} - -void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float small, float medium, float big, float large) -{ - inputOptions->setNormalFilter(small, medium, big, large); -} - -void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b) -{ - inputOptions->setNormalizeMipmaps(b != NVTT_False); -} - -void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t) -{ - inputOptions->setColorTransform((nvtt::ColorTransform)t); -} - -void nvttSetInputOptionsLinearTransfrom(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3) -{ - inputOptions->setLinearTransform(channel, w0, w1, w2, w3); -} - -void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim) -{ - inputOptions->setMaxExtents(dim); -} - -void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode) -{ - inputOptions->setRoundMode((nvtt::RoundMode)mode); -} - - -// CompressionOptions class. -NvttCompressionOptions * nvttCreateCompressionOptions() -{ - return new nvtt::CompressionOptions(); -} - -void nvttDestroyCompressionOptions(NvttCompressionOptions * compressionOptions) -{ - delete compressionOptions; -} - -void nvttSetCompressionOptionsFormat(NvttCompressionOptions * compressionOptions, NvttFormat format) -{ - compressionOptions->setFormat((nvtt::Format)format); -} - -void nvttSetCompressionOptionsQuality(NvttCompressionOptions * compressionOptions, NvttQuality quality) -{ - compressionOptions->setQuality((nvtt::Quality)quality); -} - -void nvttSetCompressionOptionsColorWeights(NvttCompressionOptions * compressionOptions, float red, float green, float blue, float alpha) -{ - compressionOptions->setColorWeights(red, green, blue, alpha); -} - -/*void nvttEnableCompressionOptionsCudaCompression(NvttCompressionOptions * compressionOptions, NvttBoolean enable) -{ - compressionOptions->enableCudaCompression(enable != NVTT_False); -}*/ - -void nvttSetCompressionOptionsPixelFormat(NvttCompressionOptions * compressionOptions, unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask) -{ - compressionOptions->setPixelFormat(bitcount, rmask, gmask, bmask, amask); -} - -void nvttSetCompressionOptionsQuantization(NvttCompressionOptions * compressionOptions, NvttBoolean colorDithering, NvttBoolean alphaDithering, NvttBoolean binaryAlpha, int alphaThreshold) -{ - compressionOptions->setQuantization(colorDithering != NVTT_False, alphaDithering != NVTT_False, binaryAlpha != NVTT_False, alphaThreshold); -} - - -// OutputOptions class. -NvttOutputOptions * nvttCreateOutputOptions() -{ - return new nvtt::OutputOptions(); -} - -void nvttDestroyOutputOptions(NvttOutputOptions * outputOptions) -{ - delete outputOptions; -} - -void nvttSetOutputOptionsFileName(NvttOutputOptions * outputOptions, const char * fileName) -{ - outputOptions->setFileName(fileName); -} - -void nvttSetOutputOptionsOutputHeader(NvttOutputOptions * outputOptions, NvttBoolean b) -{ - outputOptions->setOutputHeader(b != NVTT_False); -} -/* -void nvttSetOutputOptionsErrorHandler(NvttOutputOptions * outputOptions, nvttErrorHandler errorHandler) -{ - outputOptions->setErrorHandler(errorHandler); -} - -void nvttSetOutputOptionsOutputHandler(NvttOutputOptions * outputOptions, nvttOutputHandler outputHandler, nvttImageHandler imageHandler) -{ -} -*/ - - -// Compressor class. -NvttBoolean nvttCompress(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions, const NvttOutputOptions * outputOptions) -{ - return (NvttBoolean)compressor->process(*inputOptions, *compressionOptions, *outputOptions); -} - -int nvttEstimateSize(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions) -{ - return compressor->estimateSize(*inputOptions, *compressionOptions); -} - - -// Global functions. -const char * nvttErrorString(NvttError e) -{ - return nvtt::errorString((nvtt::Error)e); -} - -unsigned int nvttVersion() -{ - return nvtt::version(); -} diff --git a/Externals/NVTT/src/nvtt/nvtt_wrapper.h b/Externals/NVTT/src/nvtt/nvtt_wrapper.h deleted file mode 100644 index b8407e22470..00000000000 --- a/Externals/NVTT/src/nvtt/nvtt_wrapper.h +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NVTT_WRAPPER_H -#define NVTT_WRAPPER_H - -// Function linkage -#if NVTT_SHARED - -#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__ -# ifdef NVTT_EXPORTS -# define NVTT_API __declspec(dllexport) -# else -# define NVTT_API __declspec(dllimport) -# endif -#endif - -#if defined __GNUC__ >= 4 -# ifdef NVTT_EXPORTS -# define NVTT_API __attribute__((visibility("default"))) -# endif -#endif - -#endif // NVTT_SHARED - -#if !defined NVTT_API -# define NVTT_API -#endif - -#define NVTT_VERSION 200 - -#ifdef __cplusplus -typedef struct nvtt::InputOptions NvttInputOptions; -typedef struct nvtt::CompressionOptions NvttCompressionOptions; -typedef struct nvtt::OutputOptions NvttOutputOptions; -typedef struct nvtt::Compressor NvttCompressor; -#else -typedef struct NvttInputOptions NvttInputOptions; -typedef struct NvttCompressionOptions NvttCompressionOptions; -typedef struct NvttOutputOptions NvttOutputOptions; -typedef struct NvttCompressor NvttCompressor; -#endif - -/// Supported compression formats. -typedef enum -{ - // No compression. - NVTT_Format_RGB, - NVTT_Format_RGBA = NVTT_Format_RGB, - - // DX9 formats. - NVTT_Format_DXT1, - NVTT_Format_DXT1a, - NVTT_Format_DXT3, - NVTT_Format_DXT5, - NVTT_Format_DXT5n, - - // DX10 formats. - NVTT_Format_BC1 = NVTT_Format_DXT1, - NVTT_Format_BC1a = NVTT_Format_DXT1a, - NVTT_Format_BC2 = NVTT_Format_DXT3, - NVTT_Format_BC3 = NVTT_Format_DXT5, - NVTT_Format_BC3n = NVTT_Format_DXT5n, - NVTT_Format_BC4, - NVTT_Format_BC5, -} NvttFormat; - -/// Quality modes. -typedef enum -{ - NVTT_Quality_Fastest, - NVTT_Quality_Normal, - NVTT_Quality_Production, - NVTT_Quality_Highest, -} NvttQuality; - -/// Wrap modes. -typedef enum -{ - NVTT_WrapMode_Clamp, - NVTT_WrapMode_Repeat, - NVTT_WrapMode_Mirror, -} NvttWrapMode; - -/// Texture types. -typedef enum -{ - NVTT_TextureType_2D, - NVTT_TextureType_Cube, -} NvttTextureType; - -/// Input formats. -typedef enum -{ - NVTT_InputFormat_BGRA_8UB, -} NvttInputFormat; - -/// Mipmap downsampling filters. -typedef enum -{ - NVTT_MipmapFilter_Box, - NVTT_MipmapFilter_Triangle, - NVTT_MipmapFilter_Kaiser, -} NvttMipmapFilter; - -/// Color transformation. -typedef enum -{ - NVTT_ColorTransform_None, - NVTT_ColorTransform_Linear, -} NvttColorTransform; - -/// Extents rounding mode. -typedef enum -{ - NVTT_RoundMode_None, - NVTT_RoundMode_ToNextPowerOfTwo, - NVTT_RoundMode_ToNearestPowerOfTwo, - NVTT_RoundMode_ToPreviousPowerOfTwo, -} NvttRoundMode; - -/// Alpha mode. -typedef enum -{ - NVTT_AlphaMode_None, - NVTT_AlphaMode_Transparency, - NVTT_AlphaMode_Premultiplied, -} NvttAlphaMode; - -typedef enum -{ - NVTT_Error_InvalidInput, - NVTT_Error_UserInterruption, - NVTT_Error_UnsupportedFeature, - NVTT_Error_CudaError, - NVTT_Error_Unknown, - NVTT_Error_FileOpen, - NVTT_Error_FileWrite, -} NvttError; - -typedef enum -{ - NVTT_False, - NVTT_True, -} NvttBoolean; - - -#ifdef __cplusplus -extern "C" { -#endif - -// Callbacks -//typedef void (* nvttErrorHandler)(NvttError e); -//typedef void (* nvttOutputHandler)(const void * data, int size); -//typedef void (* nvttImageHandler)(int size, int width, int height, int depth, int face, int miplevel); - - -// InputOptions class. -NVTT_API NvttInputOptions * nvttCreateInputOptions(); -NVTT_API void nvttDestroyInputOptions(NvttInputOptions * inputOptions); - -NVTT_API void nvttSetInputOptionsTextureLayout(NvttInputOptions * inputOptions, NvttTextureType type, int w, int h, int d); -NVTT_API void nvttResetInputOptionsTextureLayout(NvttInputOptions * inputOptions); -NVTT_API NvttBoolean nvttSetInputOptionsMipmapData(NvttInputOptions * inputOptions, const void * data, int w, int h, int d, int face, int mipmap); -NVTT_API void nvttSetInputOptionsFormat(NvttInputOptions * inputOptions, NvttInputFormat format); -NVTT_API void nvttSetInputOptionsAlphaMode(NvttInputOptions * inputOptions, NvttAlphaMode alphaMode); -NVTT_API void nvttSetInputOptionsGamma(NvttInputOptions * inputOptions, float inputGamma, float outputGamma); -NVTT_API void nvttSetInputOptionsWrapMode(NvttInputOptions * inputOptions, NvttWrapMode mode); -NVTT_API void nvttSetInputOptionsMipmapFilter(NvttInputOptions * inputOptions, NvttMipmapFilter filter); -NVTT_API void nvttSetInputOptionsMipmapGeneration(NvttInputOptions * inputOptions, NvttBoolean enabled, int maxLevel); -NVTT_API void nvttSetInputOptionsKaiserParameters(NvttInputOptions * inputOptions, float width, float alpha, float stretch); -NVTT_API void nvttSetInputOptionsNormalMap(NvttInputOptions * inputOptions, NvttBoolean b); -NVTT_API void nvttSetInputOptionsConvertToNormalMap(NvttInputOptions * inputOptions, NvttBoolean convert); -NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale); -NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large); -NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b); -NVTT_API void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t); -NVTT_API void nvttSetInputOptionsLinearTransform(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3); -NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim); -NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode); - - -// CompressionOptions class. -NVTT_API NvttCompressionOptions * nvttCreateCompressionOptions(); -NVTT_API void nvttDestroyCompressionOptions(NvttCompressionOptions * compressionOptions); - -NVTT_API void nvttSetCompressionOptionsFormat(NvttCompressionOptions * compressionOptions, NvttFormat format); -NVTT_API void nvttSetCompressionOptionsQuality(NvttCompressionOptions * compressionOptions, NvttQuality quality); -NVTT_API void nvttSetCompressionOptionsColorWeights(NvttCompressionOptions * compressionOptions, float red, float green, float blue, float alpha); -NVTT_API void nvttSetCompressionOptionsPixelFormat(NvttCompressionOptions * compressionOptions, unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); -NVTT_API void nvttSetCompressionOptionsQuantization(NvttCompressionOptions * compressionOptions, NvttBoolean colorDithering, NvttBoolean alphaDithering, NvttBoolean binaryAlpha, int alphaThreshold); - - -// OutputOptions class. -NVTT_API NvttOutputOptions * nvttCreateOutputOptions(); -NVTT_API void nvttDestroyOutputOptions(NvttOutputOptions * outputOptions); - -NVTT_API void nvttSetOutputOptionsFileName(NvttOutputOptions * outputOptions, const char * fileName); -NVTT_API void nvttSetOutputOptionsOutputHeader(NvttOutputOptions * outputOptions, NvttBoolean b); -//NVTT_API void nvttSetOutputOptionsErrorHandler(NvttOutputOptions * outputOptions, nvttErrorHandler errorHandler); -//NVTT_API void nvttSetOutputOptionsOutputHandler(NvttOutputOptions * outputOptions, nvttOutputHandler outputHandler, nvttImageHandler imageHandler); - - -// Compressor class. -NVTT_API NvttCompressor * nvttCreateCompressor(); -NVTT_API void nvttDestroyCompressor(NvttCompressor * compressor); - -NVTT_API NvttBoolean nvttCompress(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions, const NvttOutputOptions * outputOptions); -NVTT_API int nvttEstimateSize(const NvttCompressor * compressor, const NvttInputOptions * inputOptions, const NvttCompressionOptions * compressionOptions); - - -// Global functions. -NVTT_API const char * nvttErrorString(NvttError e); -NVTT_API unsigned int nvttVersion(); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // NVTT_WRAPPER_H diff --git a/Externals/NVTT/src/nvtt/squish/CMakeLists.txt b/Externals/NVTT/src/nvtt/squish/CMakeLists.txt deleted file mode 100644 index de8dc7194ce..00000000000 --- a/Externals/NVTT/src/nvtt/squish/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -PROJECT(squish) - -add_library(squish STATIC) - -target_sources(squish PRIVATE - fastclusterfit.cpp - fastclusterfit.h - weightedclusterfit.cpp - weightedclusterfit.h - colourblock.cpp - colourblock.h - colourfit.cpp - colourfit.h - colourset.cpp - colourset.h - config.h - maths.cpp - maths.h - simd.h - simd_sse.h - simd_ve.h -) - -target_include_directories(squish - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} -) - -set_property(TARGET squish PROPERTY - POSITION_INDEPENDENT_CODE ON -) diff --git a/Externals/NVTT/src/nvtt/squish/ChangeLog b/Externals/NVTT/src/nvtt/squish/ChangeLog deleted file mode 100644 index e074a89187c..00000000000 --- a/Externals/NVTT/src/nvtt/squish/ChangeLog +++ /dev/null @@ -1,38 +0,0 @@ - -1.7 -* Fixed floating-point equality issue in clusterfit sort (x86 affected only) -* Implemented proper SSE(2) floor function for 50% speedup on SSE builds -* The range fit implementation now uses the correct colour metric - -1.6 -* Fixed bug in CompressImage where masked pixels were not skipped over -* DXT3 and DXT5 alpha compression now properly use the mask to ignore pixels -* Fixed major DXT1 bug that can generate unexpected transparent pixels - -1.5 -* Added CompressMasked function to handle incomplete DXT blocks more cleanly -* Added kWeightColourByAlpha flag for better quality images when alpha blending - -1.4 -* Fixed stack overflow in rangefit - -1.3 -* Worked around SSE floor implementation bug, proper fix needed! -* This release has visual studio and makefile builds that work - -1.2 -* Added provably optimal single colour compressor -* Added extra/squishgen.cpp that generates single colour lookup tables - -1.1 -* Fixed a DXT1 colour output bug -* Changed argument order for Decompress function to match Compress -* Added GetStorageRequirements function -* Added CompressImage function -* Added DecompressImage function -* Moved squishtool.cpp to extra/squishpng.cpp -* Added extra/squishtest.cpp - -1.0 -* Initial release - diff --git a/Externals/NVTT/src/nvtt/squish/Doxyfile b/Externals/NVTT/src/nvtt/squish/Doxyfile deleted file mode 100644 index 3ec51e4bde0..00000000000 --- a/Externals/NVTT/src/nvtt/squish/Doxyfile +++ /dev/null @@ -1,223 +0,0 @@ -# Doxyfile 1.4.6 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = squish -PROJECT_NUMBER = 1.1 -OUTPUT_DIRECTORY = docs -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 4 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = YES -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = squish.h -FILE_PATTERNS = -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = /Applications/Graphviz.app/Contents/MacOS -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/Externals/NVTT/src/nvtt/squish/Makefile b/Externals/NVTT/src/nvtt/squish/Makefile deleted file mode 100644 index 75a72fecebe..00000000000 --- a/Externals/NVTT/src/nvtt/squish/Makefile +++ /dev/null @@ -1,31 +0,0 @@ - -include config - -SRC = alpha.cpp clusterfit.cpp colourblock.cpp colourfit.cpp colourset.cpp maths.cpp rangefit.cpp singlecolourfit.cpp squish.cpp - -OBJ = $(SRC:%.cpp=%.o) - -LIB = libsquish.a - -all : $(LIB) - -install : $(LIB) - install squish.h $(INSTALL_DIR)/include - install libsquish.a $(INSTALL_DIR)/lib - -uninstall: - $(RM) $(INSTALL_DIR)/include/squish.h - $(RM) $(INSTALL_DIR)/lib/libsquish.a - -$(LIB) : $(OBJ) - $(AR) cr $@ $? - ranlib $@ - -%.o : %.cpp - $(CXX) $(CPPFLAGS) -I. $(CXXFLAGS) -o$@ -c $< - -clean : - $(RM) $(OBJ) $(LIB) - - - diff --git a/Externals/NVTT/src/nvtt/squish/README b/Externals/NVTT/src/nvtt/squish/README deleted file mode 100644 index 62b26747091..00000000000 --- a/Externals/NVTT/src/nvtt/squish/README +++ /dev/null @@ -1,35 +0,0 @@ -LICENSE -------- - -The squish library is distributed under the terms and conditions of the MIT -license. This license is specified at the top of each source file and must be -preserved in its entirety. - -BUILDING AND INSTALLING THE LIBRARY ------------------------------------ - -If you are using Visual Studio 2003 or above under Windows then load the Visual -Studio 2003 project in the vs7 folder. By default, the library is built using -SSE optimisations. To change this either change or remove the SQUISH_USE_SSE=1 -from the preprocessor symbols. - -If you are using a Mac then load the Xcode 2.2 project in the distribution. By -default, the library is built using Altivec optimisations. To change this -either change or remove SQUISH_USE_ALTIVEC=1 from the preprocessor symbols. I -guess I'll have to think about changing this for the new Intel Macs that are -rolling out... - -If you are using unix then first edit the config file in the base directory of -the distribution, enabling Altivec or SSE with the USE_ALTIVEC or USE_SSE -variables, and editing the optimisation flags passed to the C++ compiler if -necessary. Then make can be used to build the library, and make install (from -the superuser account) can be used to install (into /usr/local by default). - -REPORTING BUGS OR FEATURE REQUESTS ----------------------------------- - -Feedback can be sent to Simon Brown (the developer) at si@sjbrown.co.uk - -New releases are announced on the squish library homepage at -http://sjbrown.co.uk/?code=squish - diff --git a/Externals/NVTT/src/nvtt/squish/alpha.cpp b/Externals/NVTT/src/nvtt/squish/alpha.cpp deleted file mode 100644 index 4242bb8fef7..00000000000 --- a/Externals/NVTT/src/nvtt/squish/alpha.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "alpha.h" -#include - -namespace squish { - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -void CompressAlphaDxt3( u8 const* rgba, void* block ) -{ - u8* bytes = reinterpret_cast< u8* >( block ); - - // quantise and pack the alpha values pairwise - for( int i = 0; i < 8; ++i ) - { - // quantise down to 4 bits - float alpha1 = ( float )rgba[8*i + 3] * ( 15.0f/255.0f ); - float alpha2 = ( float )rgba[8*i + 7] * ( 15.0f/255.0f ); - int quant1 = FloatToInt( alpha1, 15 ); - int quant2 = FloatToInt( alpha2, 15 ); - - // pack into the byte - bytes[i] = ( u8 )( quant1 | ( quant2 << 4 ) ); - } -} - -void DecompressAlphaDxt3( u8* rgba, void const* block ) -{ - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - - // unpack the alpha values pairwise - for( int i = 0; i < 8; ++i ) - { - // quantise down to 4 bits - u8 quant = bytes[i]; - - // unpack the values - u8 lo = quant & 0x0f; - u8 hi = quant & 0xf0; - - // convert back up to bytes - rgba[8*i + 3] = lo | ( lo << 4 ); - rgba[8*i + 7] = hi | ( hi >> 4 ); - } -} - -static void FixRange( int& min, int& max, int steps ) -{ - if( max - min < steps ) - max = std::min( min + steps, 255 ); - if( max - min < steps ) - min = std::max( 0, max - steps ); -} - -static int FitCodes( u8 const* rgba, u8 const* codes, u8* indices ) -{ - // fit each alpha value to the codebook - int err = 0; - for( int i = 0; i < 16; ++i ) - { - // find the least error and corresponding index - int value = rgba[4*i + 3]; - int least = INT_MAX; - int index = 0; - for( int j = 0; j < 8; ++j ) - { - // get the squared error from this code - int dist = ( int )value - ( int )codes[j]; - dist *= dist; - - // compare with the best so far - if( dist < least ) - { - least = dist; - index = j; - } - } - - // save this index and accumulate the error - indices[i] = ( u8 )index; - err += least; - } - - // return the total error - return err; -} - -static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - u8* bytes = reinterpret_cast< u8* >( block ); - - // write the first two bytes - bytes[0] = ( u8 )alpha0; - bytes[1] = ( u8 )alpha1; - - // pack the indices with 3 bits each - u8* dest = bytes + 2; - u8 const* src = indices; - for( int i = 0; i < 2; ++i ) - { - // pack 8 3-bit values - int value = 0; - for( int j = 0; j < 8; ++j ) - { - int index = *src++; - value |= ( index << 3*j ); - } - - // store in 3 bytes - for( int j = 0; j < 3; ++j ) - { - int byte = ( value >> 8*j ) & 0xff; - *dest++ = ( u8 )byte; - } - } -} - -static void WriteAlphaBlock5( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - // check the relative values of the endpoints - if( alpha0 > alpha1 ) - { - // swap the indices - u8 swapped[16]; - for( int i = 0; i < 16; ++i ) - { - u8 index = indices[i]; - if( index == 0 ) - swapped[i] = 1; - else if( index == 1 ) - swapped[i] = 0; - else if( index <= 5 ) - swapped[i] = 7 - index; - else - swapped[i] = index; - } - - // write the block - WriteAlphaBlock( alpha1, alpha0, swapped, block ); - } - else - { - // write the block - WriteAlphaBlock( alpha0, alpha1, indices, block ); - } -} - -static void WriteAlphaBlock7( int alpha0, int alpha1, u8 const* indices, void* block ) -{ - // check the relative values of the endpoints - if( alpha0 < alpha1 ) - { - // swap the indices - u8 swapped[16]; - for( int i = 0; i < 16; ++i ) - { - u8 index = indices[i]; - if( index == 0 ) - swapped[i] = 1; - else if( index == 1 ) - swapped[i] = 0; - else - swapped[i] = 9 - index; - } - - // write the block - WriteAlphaBlock( alpha1, alpha0, swapped, block ); - } - else - { - // write the block - WriteAlphaBlock( alpha0, alpha1, indices, block ); - } -} - -void CompressAlphaDxt5( u8 const* rgba, void* block ) -{ - // get the range for 5-alpha and 7-alpha interpolation - int min5 = 255; - int max5 = 0; - int min7 = 255; - int max7 = 0; - for( int i = 0; i < 16; ++i ) - { - // incorporate into the min/max - int value = rgba[4*i + 3]; - if( value < min7 ) - min7 = value; - if( value > max7 ) - max7 = value; - if( value != 0 && value < min5 ) - min5 = value; - if( value != 255 && value > max5 ) - max5 = value; - } - - // handle the case that no valid range was found - if( min5 > max5 ) - min5 = max5; - if( min7 > max7 ) - min7 = max7; - - // fix the range to be the minimum in each case - FixRange( min5, max5, 5 ); - FixRange( min7, max7, 7 ); - - // set up the 5-alpha code book - u8 codes5[8]; - codes5[0] = ( u8 )min5; - codes5[1] = ( u8 )max5; - for( int i = 1; i < 5; ++i ) - codes5[1 + i] = ( u8 )( ( ( 5 - i )*min5 + i*max5 )/5 ); - codes5[6] = 0; - codes5[7] = 255; - - // set up the 7-alpha code book - u8 codes7[8]; - codes7[0] = ( u8 )min7; - codes7[1] = ( u8 )max7; - for( int i = 1; i < 7; ++i ) - codes7[1 + i] = ( u8 )( ( ( 7 - i )*min7 + i*max7 )/7 ); - - // fit the data to both code books - u8 indices5[16]; - u8 indices7[16]; - int err5 = FitCodes( rgba, codes5, indices5 ); - int err7 = FitCodes( rgba, codes7, indices7 ); - - // save the block with least error - if( err5 <= err7 ) - WriteAlphaBlock5( min5, max5, indices5, block ); - else - WriteAlphaBlock7( min7, max7, indices7, block ); -} - -void DecompressAlphaDxt5( u8* rgba, void const* block ) -{ - // get the two alpha values - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - int alpha0 = bytes[0]; - int alpha1 = bytes[1]; - - // compare the values to build the codebook - u8 codes[8]; - codes[0] = ( u8 )alpha0; - codes[1] = ( u8 )alpha1; - if( alpha0 <= alpha1 ) - { - // use 5-alpha codebook - for( int i = 1; i < 5; ++i ) - codes[1 + i] = ( u8 )( ( ( 5 - i )*alpha0 + i*alpha1 )/5 ); - codes[6] = 0; - codes[7] = 255; - } - else - { - // use 7-alpha codebook - for( int i = 1; i < 7; ++i ) - codes[1 + i] = ( u8 )( ( ( 7 - i )*alpha0 + i*alpha1 )/7 ); - } - - // decode the indices - u8 indices[16]; - u8 const* src = bytes + 2; - u8* dest = indices; - for( int i = 0; i < 2; ++i ) - { - // grab 3 bytes - int value = 0; - for( int j = 0; j < 3; ++j ) - { - int byte = *src++; - value |= ( byte << 8*j ); - } - - // unpack 8 3-bit values from it - for( int j = 0; j < 8; ++j ) - { - int index = ( value >> 3*j ) & 0x7; - *dest++ = ( u8 )index; - } - } - - // write out the indexed codebook values - for( int i = 0; i < 16; ++i ) - rgba[4*i + 3] = codes[indices[i]]; -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/alpha.h b/Externals/NVTT/src/nvtt/squish/alpha.h deleted file mode 100644 index d09ba0e9b2f..00000000000 --- a/Externals/NVTT/src/nvtt/squish/alpha.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_ALPHA_H -#define SQUISH_ALPHA_H - -#include - -namespace squish { - -void CompressAlphaDxt3( u8 const* rgba, void* block ); -void CompressAlphaDxt5( u8 const* rgba, void* block ); - -void DecompressAlphaDxt3( u8* rgba, void const* block ); -void DecompressAlphaDxt5( u8* rgba, void const* block ); - -} // namespace squish - -#endif // ndef SQUISH_ALPHA_H diff --git a/Externals/NVTT/src/nvtt/squish/clusterfit.cpp b/Externals/NVTT/src/nvtt/squish/clusterfit.cpp deleted file mode 100644 index 186020c5479..00000000000 --- a/Externals/NVTT/src/nvtt/squish/clusterfit.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "clusterfit.h" -#include "colourset.h" -#include "colourblock.h" -#include - -namespace squish { - -ClusterFit::ClusterFit() -{ -} - -void ClusterFit::SetColourSet( ColourSet const* colours, int flags ) -{ - ColourFit::SetColourSet( colours, flags ); - - // initialise the best error -#if SQUISH_USE_SIMD - m_besterror = VEC4_CONST( FLT_MAX ); - Vec3 metric = m_metric.GetVec3(); -#else - m_besterror = FLT_MAX; - Vec3 metric = m_metric; -#endif - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights(), metric ); - - // compute the principle component - Vec3 principle = ComputePrincipleComponent( covariance ); - - // build the list of values - float dps[16]; - for( int i = 0; i < count; ++i ) - { - dps[i] = Dot( values[i], principle ); - m_order[i] = i; - } - - // stable sort - for( int i = 0; i < count; ++i ) - { - for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) - { - std::swap( dps[j], dps[j - 1] ); - std::swap( m_order[j], m_order[j - 1] ); - } - } - - // weight all the points -#if SQUISH_USE_SIMD - Vec4 const* unweighted = m_colours->GetPointsSimd(); - Vec4 const* weights = m_colours->GetWeightsSimd(); - m_xxsum = VEC4_CONST( 0.0f ); -#else - Vec3 const* unweighted = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - m_xxsum = Vec3( 0.0f ); -#endif - for( int i = 0; i < count; ++i ) - { - int p = m_order[i]; - m_unweighted[i] = unweighted[p]; - m_weights[i] = weights[p]; - m_weighted[i] = weights[p]*unweighted[p]; - m_xxsum += m_weighted[i]*m_weighted[i]; - } -} - - -void ClusterFit::SetMetric(float r, float g, float b) -{ -#if SQUISH_USE_SIMD - m_metric = Vec4(r, g, b, 0); -#else - m_metric = Vec3(r, g, b); -#endif - m_metricSqr = m_metric * m_metric; -} - -float ClusterFit::GetBestError() const -{ -#if SQUISH_USE_SIMD - return m_besterror.GetVec3().X(); -#else - return m_besterror; -#endif -} - - -void ClusterFit::Compress3( void* block ) -{ - // declare variables - int const count = m_colours->GetCount(); -#if SQUISH_USE_SIMD - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = VEC4_CONST( FLT_MAX ); - Vec4 const half = VEC4_CONST( 0.5f ); - Vec4 const zero = VEC4_CONST( 0.0f ); -#else - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = FLT_MAX; - float const half = 0.5f; - float const zero = 0.0f; -#endif - - // check all possible clusters for this total order - u8 indices[16]; - u8 bestindices[16]; - - // first cluster [0,i) is at the start - for( int m = 0; m < count; ++m ) - { - indices[m] = 0; - m_alpha[m] = m_weights[m]; - m_beta[m] = zero; - } - for( int i = count; i >= 0; --i ) - { - // second cluster [i,j) is half along - for( int m = i; m < count; ++m ) - { - indices[m] = 2; - m_alpha[m] = m_beta[m] = half*m_weights[m]; - } - for( int j = count; j > i; --j ) - { - // last cluster [j,k) is at the end - if( j < count ) - { - indices[j] = 1; - m_alpha[j] = zero; - m_beta[j] = m_weights[j]; - } - - // solve a least squares problem to place the endpoints -#if SQUISH_USE_SIMD - Vec4 start, end; - Vec4 error = SolveLeastSquares( start, end ); -#else - Vec3 start, end; - float error = SolveLeastSquares( start, end ); -#endif - - // keep the solution if it wins -#if SQUISH_USE_SIMD - if( CompareAnyLessThan( error, besterror ) ) -#else - if( error < besterror ) -#endif - { - beststart = start; - bestend = end; - for( int m = 0; m < 16; ++m ) // TODO: make this faster? - bestindices[m] = indices[m]; - besterror = error; - } - } - } - - // save the block if necessary -#if SQUISH_USE_SIMD - if( CompareAnyLessThan( besterror, m_besterror ) ) -#else - if( besterror < m_besterror ) -#endif - { - // remap the indices - u8 unordered[16]; - for( int i = 0; i < count; ++i ) - unordered[m_order[i]] = bestindices[i]; - m_colours->RemapIndices( unordered, bestindices ); - - // save the block -#if SQUISH_USE_SIMD - WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); -#else - WriteColourBlock3( beststart, bestend, bestindices, block ); -#endif - - // save the error - m_besterror = besterror; - } -} - -//static int run = 0; -//static bool debug = false; - -void ClusterFit::Compress4( void* block ) -{ - //debug = (run == 1); - //run++; - - // declare variables - int const count = m_colours->GetCount(); -#if SQUISH_USE_SIMD - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = m_besterror; - Vec4 const twothirds = VEC4_CONST( 2.0f/3.0f ); - Vec4 const onethird = VEC4_CONST( 1.0f/3.0f ); - Vec4 const zero = VEC4_CONST( 0.0f ); -#else - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = m_besterror; - float const twothirds = 2.0f/3.0f; - float const onethird = 1.0f/3.0f; - float const zero = 0.0f; -#endif - - // check all possible clusters for this total order - u8 indices[16]; - u8 bestindices[16]; - - // first cluster [0,i) is at the start - for( int m = 0; m < count; ++m ) - { - indices[m] = 0; - m_alpha[m] = m_weights[m]; - m_beta[m] = zero; - } - for( int i = count; i >= 0; --i ) - { - // second cluster [i,j) is one third along - for( int m = i; m < count; ++m ) - { - indices[m] = 2; - m_alpha[m] = twothirds*m_weights[m]; - m_beta[m] = onethird*m_weights[m]; - } - for( int j = count; j >= i; --j ) - { - // third cluster [j,k) is two thirds along - for( int m = j; m < count; ++m ) - { - indices[m] = 3; - m_alpha[m] = onethird*m_weights[m]; - m_beta[m] = twothirds*m_weights[m]; - } - for( int k = count; k >= j; --k ) - { - if (j + k == 0) continue; - - // last cluster [k,n) is at the end - if( k < count ) - { - indices[k] = 1; - m_alpha[k] = zero; - m_beta[k] = m_weights[k]; - } - - /*unsigned int permutation = 0; - for(int p = 0; p < 16; p++) { - permutation |= indices[p] << (p * 2); - } - if (debug) printf("%X:\t", permutation); - - if (debug && permutation == 0x55FFFFAA) __debugbreak(); - */ - - // solve a least squares problem to place the endpoints -#if SQUISH_USE_SIMD - Vec4 start, end; - Vec4 error = SolveLeastSquares( start, end ); -#else - Vec3 start, end; - float error = SolveLeastSquares( start, end ); -#endif - - // keep the solution if it wins -#if SQUISH_USE_SIMD - if( CompareAnyLessThan( error, besterror ) ) -#else - if( error < besterror ) -#endif - { - beststart = start; - bestend = end; - for( int m = 0; m < 16; ++m ) // TODO: make this faster? - bestindices[m] = indices[m]; - besterror = error; - } - } - } - } - - // save the block if necessary -#if SQUISH_USE_SIMD - if( CompareAnyLessThan( besterror, m_besterror ) ) -#else - if( besterror < m_besterror ) -#endif - { - // remap the indices - u8 unordered[16]; - for( int i = 0; i < count; ++i ) - unordered[m_order[i]] = bestindices[i]; - m_colours->RemapIndices( unordered, bestindices ); - - // save the block -#if SQUISH_USE_SIMD - WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); -#else - WriteColourBlock4( beststart, bestend, bestindices, block ); -#endif - - // save the error - m_besterror = besterror; - } -} - -#if SQUISH_USE_SIMD -Vec4 ClusterFit::SolveLeastSquares( Vec4& start, Vec4& end ) const -{ - // accumulate all the quantities we need - int const count = m_colours->GetCount(); - Vec4 alpha2_sum = VEC4_CONST( 0.0f ); - Vec4 beta2_sum = VEC4_CONST( 0.0f ); - Vec4 alphabeta_sum = VEC4_CONST( 0.0f ); - Vec4 alphax_sum = VEC4_CONST( 0.0f ); - Vec4 betax_sum = VEC4_CONST( 0.0f ); - for( int i = 0; i < count; ++i ) - { - Vec4 alpha = m_alpha[i]; - Vec4 beta = m_beta[i]; - Vec4 x = m_weighted[i]; - - alpha2_sum = MultiplyAdd( alpha, alpha, alpha2_sum ); - beta2_sum = MultiplyAdd( beta, beta, beta2_sum ); - alphabeta_sum = MultiplyAdd( alpha, beta, alphabeta_sum ); - alphax_sum = MultiplyAdd( alpha, x, alphax_sum ); - betax_sum = MultiplyAdd( beta, x, betax_sum ); - } - - // select the results - Vec4 const zero = VEC4_CONST( 0.0f ); - Vec4 beta2_sum_zero = CompareEqual( beta2_sum, zero ); - Vec4 alpha2_sum_zero = CompareEqual( alpha2_sum, zero ); - - Vec4 a1 = alphax_sum*Reciprocal( alpha2_sum ); - Vec4 b1 = betax_sum*Reciprocal( beta2_sum ); - - Vec4 factor = Reciprocal( NegativeMultiplySubtract( - alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum - ) ); - Vec4 a2 = NegativeMultiplySubtract( - betax_sum, alphabeta_sum, alphax_sum*beta2_sum - )*factor; - Vec4 b2 = NegativeMultiplySubtract( - alphax_sum, alphabeta_sum, betax_sum*alpha2_sum - )*factor; - - Vec4 a = Select( Select( a2, a1, beta2_sum_zero ), zero, alpha2_sum_zero ); - Vec4 b = Select( Select( b2, b1, alpha2_sum_zero ), zero, beta2_sum_zero ); - - // clamp the output to [0, 1] - Vec4 const one = VEC4_CONST( 1.0f ); - Vec4 const half = VEC4_CONST( 0.5f ); - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); -// Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); - Vec4 const gridrcp( 0.03227752766457f, 0.01583151765563f, 0.03227752766457f, 0.0f ); // IC: use approximate grid fitting. - Vec4 const onethird = VEC4_CONST( 1.0f/3.0f ); - Vec4 const twothirds = VEC4_CONST( 2.0f/3.0f ); - a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; - - // compute the error - Vec4 const two = VEC4_CONST( 2.0 ); - Vec4 e1 = MultiplyAdd( b*b, beta2_sum, m_xxsum ); - Vec4 e2 = MultiplyAdd( a, alphax_sum, b*betax_sum ); - Vec4 e3 = MultiplyAdd( a*a, alpha2_sum, e1 ); - Vec4 e4 = MultiplyAdd( a*b*alphabeta_sum - e2, two, e3 ); - - // apply the metric to the error term - Vec4 e5 = e4*m_metricSqr; - Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); - - // save the start and end - start = a; - end = b; - return error; -} -#else -float ClusterFit::SolveLeastSquares( Vec3& start, Vec3& end ) const -{ - // accumulate all the quantities we need - int const count = m_colours->GetCount(); - float alpha2_sum = 0.0f; - float beta2_sum = 0.0f; - float alphabeta_sum = 0.0f; - Vec3 alphax_sum( 0.0f ); - Vec3 betax_sum( 0.0f ); - for( int i = 0; i < count; ++i ) - { - float alpha = m_alpha[i]; - float beta = m_beta[i]; - Vec3 const& x = m_weighted[i]; - - alpha2_sum += alpha*alpha; - beta2_sum += beta*beta; - alphabeta_sum += alpha*beta; - alphax_sum += alpha*x; - betax_sum += beta*x; - } - - //if (debug) printf("%f %f %f", alpha2_sum, beta2_sum, alphabeta_sum); - - // zero where non-determinate - Vec3 a, b; - if( beta2_sum == 0.0f ) - { - a = alphax_sum/alpha2_sum; - b = Vec3( 0.0f ); - } - else if( alpha2_sum == 0.0f ) - { - a = Vec3( 0.0f ); - b = betax_sum/beta2_sum; - } - else - { - float factor = 1.0f/( alpha2_sum*beta2_sum - alphabeta_sum*alphabeta_sum ); - - a = ( alphax_sum*beta2_sum - betax_sum*alphabeta_sum )*factor; - b = ( betax_sum*alpha2_sum - alphax_sum*alphabeta_sum )*factor; - } - - // clamp the output to [0, 1] - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - //Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); - Vec3 const gridrcp(0.03227752766457f, 0.01583151765563f, 0.03227752766457f); // IC: use approximate grid fitting. - Vec3 const half( 0.5f ); - a = Floor( grid*a + half )*gridrcp; - b = Floor( grid*b + half )*gridrcp; - - // compute the error - Vec3 e1 = a*a*alpha2_sum + b*b*beta2_sum /*+ m_xxsum*/ - + 2.0f*( a*b*alphabeta_sum - a*alphax_sum - b*betax_sum ); - - // apply the metric to the error term - float error = Dot( e1, m_metricSqr ); - - //if (debug) printf(" - %f\n", error); - - // save the start and end - start = a; - end = b; - return error; -} -#endif - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/clusterfit.h b/Externals/NVTT/src/nvtt/squish/clusterfit.h deleted file mode 100644 index a870dc4241f..00000000000 --- a/Externals/NVTT/src/nvtt/squish/clusterfit.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_CLUSTERFIT_H -#define SQUISH_CLUSTERFIT_H - -#include "squish.h" -#include "maths.h" -#include "simd.h" -#include "colourfit.h" - -namespace squish { - -class ClusterFit : public ColourFit -{ -public: - ClusterFit(); - - void SetColourSet( ColourSet const* colours, int flags ); - - void SetMetric(float r, float g, float b); - float GetBestError() const; - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - void Reorder( Vec3::Arg principle ); - - Vec3 m_principle; -#if SQUISH_USE_SIMD - Vec4 SolveLeastSquares( Vec4& start, Vec4& end ) const; - - Vec4 m_weighted[16]; - Vec4 m_unweighted[16]; - Vec4 m_weights[16]; - Vec4 m_metric; - Vec4 m_metricSqr; - Vec4 m_alpha[16]; - Vec4 m_beta[16]; - Vec4 m_xxsum; - Vec4 m_besterror; -#else - float SolveLeastSquares( Vec3& start, Vec3& end ) const; - - Vec3 m_weighted[16]; - Vec3 m_unweighted[16]; - float m_weights[16]; - Vec3 m_metric; - Vec3 m_metricSqr; - float m_alpha[16]; - float m_beta[16]; - Vec3 m_xxsum; - float m_besterror; -#endif - int m_order[16]; -}; - -} // namespace squish - -#endif // ndef SQUISH_CLUSTERFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/colourblock.cpp b/Externals/NVTT/src/nvtt/squish/colourblock.cpp deleted file mode 100644 index c2da6e82856..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourblock.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "colourblock.h" - -namespace squish { - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -static int FloatTo565( Vec3::Arg colour ) -{ - // get the components in the correct range - int r = FloatToInt( 31.0f*colour.X(), 31 ); - int g = FloatToInt( 63.0f*colour.Y(), 63 ); - int b = FloatToInt( 31.0f*colour.Z(), 31 ); - - // pack into a single value - return ( r << 11 ) | ( g << 5 ) | b; -} - -void WriteColourBlock( int a, int b, u8* indices, void* block ) -{ - // get the block as bytes - u8* bytes = ( u8* )block; - - // write the endpoints - bytes[0] = ( u8 )( a & 0xff ); - bytes[1] = ( u8 )( a >> 8 ); - bytes[2] = ( u8 )( b & 0xff ); - bytes[3] = ( u8 )( b >> 8 ); - - // write the indices - for( int i = 0; i < 4; ++i ) - { - u8 const* ind = indices + 4*i; - bytes[4 + i] = ind[0] | ( ind[1] << 2 ) | ( ind[2] << 4 ) | ( ind[3] << 6 ); - } -} - -void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - u8 remapped[16]; - if( a <= b ) - { - // use the indices directly - for( int i = 0; i < 16; ++i ) - remapped[i] = indices[i]; - } - else - { - // swap a and b - std::swap( a, b ); - for( int i = 0; i < 16; ++i ) - { - if( indices[i] == 0 ) - remapped[i] = 1; - else if( indices[i] == 1 ) - remapped[i] = 0; - else - remapped[i] = indices[i]; - } - } - - // write the block - WriteColourBlock( a, b, remapped, block ); -} - -void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - u8 remapped[16]; - if( a < b ) - { - // swap a and b - std::swap( a, b ); - for( int i = 0; i < 16; ++i ) - remapped[i] = ( indices[i] ^ 0x1 ) & 0x3; - } - else if( a == b ) - { - // use index 0 - for( int i = 0; i < 16; ++i ) - remapped[i] = 0; - } - else - { - // use the indices directly - for( int i = 0; i < 16; ++i ) - remapped[i] = indices[i]; - } - - // write the block - WriteColourBlock( a, b, remapped, block ); -} - -/* -static void WriteColourBlock( int a, int b, uint indices, void* block ) -{ - // get the block as bytes - u8* bytes = ( u8* )block; - - // write the endpoints - bytes[0] = ( u8 )( a & 0xff ); - bytes[1] = ( u8 )( a >> 8 ); - bytes[2] = ( u8 )( b & 0xff ); - bytes[3] = ( u8 )( b >> 8 ); - - // write the indices @@ Not sure that's correct... - bytes[4] = ( u8 )((indices >> 24) & 0xff); - bytes[5] = ( u8 )((indices >> 16) & 0xff); - bytes[6] = ( u8 )((indices >> 8) & 0xff); - bytes[7] = ( u8 )((indices >> 0) & 0xff); -} - -void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, uint indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - if( a > b ) - { - // swap a and b - std::swap( a, b ); - indices ^= (~indices >> 1) & 0x55555555; - } - else if ( a == b ) - { - indices = 0; - } - - // write the block - WriteColourBlock( a, b, indices, block ); -} - -void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, uint indices, void* block ) -{ - // get the packed values - int a = FloatTo565( start ); - int b = FloatTo565( end ); - - // remap the indices - if( a < b ) - { - // swap a and b - std::swap( a, b ); - indices ^= 0x55555555; - } - else if( a == b ) - { - indices = 0; - } - - // write the block - WriteColourBlock( a, b, indices, block ); -} -*/ - -static int Unpack565( u8 const* packed, u8* colour ) -{ - // build the packed value - int value = ( int )packed[0] | ( ( int )packed[1] << 8 ); - - // get the components in the stored range - u8 red = ( u8 )( ( value >> 11 ) & 0x1f ); - u8 green = ( u8 )( ( value >> 5 ) & 0x3f ); - u8 blue = ( u8 )( value & 0x1f ); - - // scale up to 8 bits - colour[0] = ( red << 3 ) | ( red >> 2 ); - colour[1] = ( green << 2 ) | ( green >> 4 ); - colour[2] = ( blue << 3 ) | ( blue >> 2 ); - colour[3] = 255; - - // return the value - return value; -} - -void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) -{ - // get the block bytes - u8 const* bytes = reinterpret_cast< u8 const* >( block ); - - // unpack the endpoints - u8 codes[16]; - int a = Unpack565( bytes, codes ); - int b = Unpack565( bytes + 2, codes + 4 ); - - // generate the midpoints - for( int i = 0; i < 3; ++i ) - { - int c = codes[i]; - int d = codes[4 + i]; - - if( isDxt1 && a <= b ) - { - codes[8 + i] = ( u8 )( ( c + d )/2 ); - codes[12 + i] = 0; - } - else - { - codes[8 + i] = ( u8 )( ( 2*c + d )/3 ); - codes[12 + i] = ( u8 )( ( c + 2*d )/3 ); - } - } - - // fill in alpha for the intermediate values - codes[8 + 3] = 255; - codes[12 + 3] = ( isDxt1 && a <= b ) ? 0 : 255; - - // unpack the indices - u8 indices[16]; - for( int i = 0; i < 4; ++i ) - { - u8* ind = indices + 4*i; - u8 packed = bytes[4 + i]; - - ind[0] = packed & 0x3; - ind[1] = ( packed >> 2 ) & 0x3; - ind[2] = ( packed >> 4 ) & 0x3; - ind[3] = ( packed >> 6 ) & 0x3; - } - - // store out the colours - for( int i = 0; i < 16; ++i ) - { - u8 offset = 4*indices[i]; - for( int j = 0; j < 4; ++j ) - rgba[4*i + j] = codes[offset + j]; - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/colourblock.h b/Externals/NVTT/src/nvtt/squish/colourblock.h deleted file mode 100644 index 1a501d6af85..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourblock.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_COLOURBLOCK_H -#define SQUISH_COLOURBLOCK_H - -#include "squish.h" -#include "maths.h" - -namespace squish { - -void WriteColourBlock( int a, int b, u8* indices, void* block ); -void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); -void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); -//void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, uint indices, void* block ); -//void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, uint indices, void* block ); - -void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); - -} // namespace squish - -#endif // ndef SQUISH_COLOURBLOCK_H diff --git a/Externals/NVTT/src/nvtt/squish/colourfit.cpp b/Externals/NVTT/src/nvtt/squish/colourfit.cpp deleted file mode 100644 index 15d8a74eed9..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourfit.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "colourfit.h" -#include "colourset.h" - -namespace squish { - -ColourFit::ColourFit() -{ -} - -void ColourFit::SetColourSet( ColourSet const* colours, int flags ) -{ - m_colours = colours; - m_flags = flags; -} - -void ColourFit::Compress( void* block ) -{ - bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 ); - if( isDxt1 ) - { - Compress3( block ); - - if( !m_colours->IsTransparent() ) - { - Compress4( block ); - } - } - else - { - Compress4( block ); - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/colourfit.h b/Externals/NVTT/src/nvtt/squish/colourfit.h deleted file mode 100644 index 23314d89ff3..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourfit.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_COLOURFIT_H -#define SQUISH_COLOURFIT_H - -#include "squish.h" -#include "maths.h" - -namespace squish { - -class ColourSet; - -class ColourFit -{ -public: - ColourFit(); - - void SetColourSet( ColourSet const* colours, int flags ); - - void Compress( void* block ); - -protected: - virtual void Compress3( void* block ) = 0; - virtual void Compress4( void* block ) = 0; - - ColourSet const* m_colours; - int m_flags; -}; - -} // namespace squish - -#endif // ndef SQUISH_COLOURFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/colourset.cpp b/Externals/NVTT/src/nvtt/squish/colourset.cpp deleted file mode 100644 index 82a7571cebf..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourset.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "colourset.h" - -namespace squish { - -// @@ Add flags: -// - MatchTransparent -// - WeightColorByAlpha - - -ColourSet::ColourSet( u8 const* rgba, int flags, bool createMinimalSet/*=false*/ ) - : m_count( 0 ), - m_transparent( false ) -{ - // check the compression mode for dxt1 - bool isDxt1 = ( ( flags & kDxt1 ) != 0 ); - bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 ); - - // create the minimal set - for( int i = 0; i < 16; ++i ) - { - if (createMinimalSet) - { - // check for transparent pixels when using dxt1 - if( isDxt1 && rgba[4*i + 3] == 0 ) - { - m_remap[i] = -1; - m_transparent = true; - continue; - } - - // loop over previous points for a match - for( int j = 0;; ++j ) - { - // allocate a new point - if( j == i ) - { - // normalise coordinates to [0,1] - float x = ( float )rgba[4*i + 2] / 255.0f; - float y = ( float )rgba[4*i + 1] / 255.0f; - float z = ( float )rgba[4*i + 0] / 255.0f; - - // ensure there is always non-zero weight even for zero alpha - float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; - - // add the point - m_points[m_count] = Vec3( x, y, z ); - m_weights[m_count] = ( weightByAlpha ? w : 1.0f ); - m_remap[i] = m_count; - - // advance - ++m_count; - break; - } - - // check for a match - bool match = ( rgba[4*i] == rgba[4*j] ) - && ( rgba[4*i + 1] == rgba[4*j + 1] ) - && ( rgba[4*i + 2] == rgba[4*j + 2] ) - && ( rgba[4*j + 3] != 0 || !isDxt1 ); // @@ I think this check is not necessary. - - if( match ) - { - // get the index of the match - int index = m_remap[j]; - - // ensure there is always non-zero weight even for zero alpha - float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; - - // map to this point and increase the weight - m_weights[index] += ( weightByAlpha ? w : 1.0f ); - m_remap[i] = index; - break; - } - } - } - else - { - // check for transparent pixels when using dxt1 - if( isDxt1 && rgba[4*i + 3] == 0 ) - { - m_remap[i] = -1; - m_transparent = true; - } - else - { - m_remap[i] = m_count; - } - - // normalise coordinates to [0,1] - float x = ( float )rgba[4*i + 2] / 255.0f; - float y = ( float )rgba[4*i + 1] / 255.0f; - float z = ( float )rgba[4*i + 0] / 255.0f; - - // ensure there is always non-zero weight even for zero alpha - float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; - - // add the point - m_points[m_count] = Vec3( x, y, z ); - m_weights[m_count] = ( weightByAlpha ? w : 1.0f ); - - // advance - ++m_count; - } - } - -#if SQUISH_USE_SIMD - // generate vector values - for( int i = 0; i < m_count; ++i ) - { - m_points_simd[i] = Vec4(m_points[i].X(), m_points[i].Y(), m_points[i].Z(), 1); - m_weights_simd[i] = VEC4_CONST(m_weights[i]); - } -#endif -} - -void ColourSet::RemapIndices( u8 const* source, u8* target ) const -{ - for( int i = 0; i < 16; ++i ) - { - int j = m_remap[i]; - if( j == -1 ) - target[i] = 3; - else - target[i] = source[j]; - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/colourset.h b/Externals/NVTT/src/nvtt/squish/colourset.h deleted file mode 100644 index f96aa21b023..00000000000 --- a/Externals/NVTT/src/nvtt/squish/colourset.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_COLOURSET_H -#define SQUISH_COLOURSET_H - -#include "squish.h" -#include "maths.h" -#include "simd.h" - -namespace squish { - -/*! @brief Represents a set of block colours -*/ -class ColourSet -{ -public: - ColourSet( u8 const* rgba, int flags, bool createMinimalSet = false ); - - int GetCount() const { return m_count; } - Vec3 const* GetPoints() const { return m_points; } - float const* GetWeights() const { return m_weights; } - bool IsTransparent() const { return m_transparent; } - - void RemapIndices( u8 const* source, u8* target ) const; - -private: - int m_count; - Vec3 m_points[16]; - float m_weights[16]; - int m_remap[16]; - bool m_transparent; - -#if SQUISH_USE_SIMD -public: - Vec4 const* GetPointsSimd() const { return m_points_simd; } - Vec4 const* GetWeightsSimd() const { return m_weights_simd; } - -private: - Vec4 m_points_simd[16]; - Vec4 m_weights_simd[16]; -#endif -}; - -} // namespace sqish - -#endif // ndef SQUISH_COLOURSET_H diff --git a/Externals/NVTT/src/nvtt/squish/config b/Externals/NVTT/src/nvtt/squish/config deleted file mode 100644 index 3f247da8dcf..00000000000 --- a/Externals/NVTT/src/nvtt/squish/config +++ /dev/null @@ -1,22 +0,0 @@ -# config file used for the Makefile only - -# define to 1 to use altivec instructions -USE_ALTIVEC ?= 0 - -# define to 1 to use sse instructions -USE_SSE ?= 0 - -# default flags -CXXFLAGS ?= -O2 -ifeq ($(USE_ALTIVEC),1) -CPPFLAGS += -DSQUISH_USE_ALTIVEC=1 -CXXFLAGS += -maltivec -endif -ifeq ($(USE_SSE),1) -CPPFLAGS += -DSQUISH_USE_SSE=1 -CXXFLAGS += -msse -endif - -# where should we install to -INSTALL_DIR ?= /usr/local - diff --git a/Externals/NVTT/src/nvtt/squish/config.h b/Externals/NVTT/src/nvtt/squish/config.h deleted file mode 100644 index 465aa89568a..00000000000 --- a/Externals/NVTT/src/nvtt/squish/config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_CONFIG_H -#define SQUISH_CONFIG_H - -// Set to 1 when building squish to use altivec instructions. -#ifndef SQUISH_USE_ALTIVEC -# define SQUISH_USE_ALTIVEC defined(__VEC__) -#endif - -// Set to 1 when building squish to use sse instructions. -#ifndef SQUISH_USE_SSE -# if defined(__SSE2__) -# define SQUISH_USE_SSE 2 -# elif defined(__SSE__) -# define SQUISH_USE_SSE 1 -# else -# define SQUISH_USE_SSE 0 -# endif -#endif - -// Internally et SQUISH_USE_SIMD when either altivec or sse is available. -#if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE -# error "Cannot enable both altivec and sse!" -#endif -#if SQUISH_USE_ALTIVEC || SQUISH_USE_SSE -# define SQUISH_USE_SIMD 1 -#else -# define SQUISH_USE_SIMD 0 -#endif - -#endif // ndef SQUISH_CONFIG_H diff --git a/Externals/NVTT/src/nvtt/squish/extra/squishgen.cpp b/Externals/NVTT/src/nvtt/squish/extra/squishgen.cpp deleted file mode 100644 index e5bd88c25f8..00000000000 --- a/Externals/NVTT/src/nvtt/squish/extra/squishgen.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include - -struct SourceBlock -{ - int start; - int end; - int error; -}; - -struct TargetValue -{ - SourceBlock sources[4]; -}; - -static void GenerateData( std::string const& name, int bits, int colours ) -{ - TargetValue values[256]; - - // initialise the data - for( int target = 0; target < 256; ++target ) - for( int index = 0; index < colours; ++index ) - values[target].sources[index].error = 255; - - // loop over all possible source points - int count = ( 1 << bits ); - for( int value1 = 0; value1 < count; ++value1 ) - { - for( int value2 = 0; value2 < count; ++value2 ) - { - // compute the 8-bit endpoints - int a = ( value1 << ( 8 - bits ) ) | ( value1 >> ( 2*bits - 8 ) ); - int b = ( value2 << ( 8 - bits ) ) | ( value2 >> ( 2*bits - 8 ) ); - - // fill in the codebook with the these and intermediates - int codes[4]; - codes[0] = a; - codes[1] = b; - if( colours == 3 ) - { - codes[2] = ( a + b )/2; - codes[3] = 0; - } - else - { - codes[2] = ( 2*a + b )/3; - codes[3] = ( a + 2*b )/3; - } - - // mark each target point with the endpoints and index needed for it - for( int index = 0; index < colours; ++index ) - { - int target = codes[index]; - - SourceBlock& block = values[target].sources[index]; - if( block.error != 0 ) - { - block.start = value1; - block.end = value2; - block.error = 0; - } - } - } - } - - // iteratively fill in the missing values - for( ;; ) - { - bool stable = true; - for( int index = 0; index < colours; ++index ) - { - for( int target = 0; target < 256; ++target ) - { - if( target != 255 ) - { - SourceBlock& current = values[target].sources[index]; - SourceBlock& next = values[target + 1].sources[index]; - if( current.error > next.error + 1 ) - { - current.start = next.start; - current.end = next.end; - current.error = next.error + 1; - stable = false; - } - } - if( target != 0 ) - { - SourceBlock& current = values[target].sources[index]; - SourceBlock& previous = values[target - 1].sources[index]; - if( current.error > previous.error + 1 ) - { - current.start = previous.start; - current.end = previous.end; - current.error = previous.error + 1; - stable = false; - } - } - } - } - if( stable ) - break; - } - - // debug - std::cout << "\nstatic SingleColourLookup const " << name << "[] = \n{\n"; - for( int i = 0;; ) - { - std::cout << "\t{ { "; - for( int j = 0;; ) - { - SourceBlock const& block = values[i].sources[j]; - if( j < colours ) - std::cout << "{ " << block.start << ", " << block.end << ", " << block.error << " }"; - else - std::cout << "{ 0, 0, 0 }"; - if( ++j == 4 ) - break; - std::cout << ", "; - } - std::cout << " } }"; - if( ++i == 256 ) - break; - std::cout << ",\n"; - } - std::cout << "\n};\n"; -} - -int main() -{ - GenerateData( "lookup_5_3", 5, 3 ); - GenerateData( "lookup_6_3", 6, 3 ); - GenerateData( "lookup_5_4", 5, 4 ); - GenerateData( "lookup_6_4", 6, 4 ); -} diff --git a/Externals/NVTT/src/nvtt/squish/extra/squishpng.cpp b/Externals/NVTT/src/nvtt/squish/extra/squishpng.cpp deleted file mode 100644 index 81246e81fd9..00000000000 --- a/Externals/NVTT/src/nvtt/squish/extra/squishpng.cpp +++ /dev/null @@ -1,603 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -/*! @file - - @brief Example program that converts between the PNG and DXT formats. - - This program requires libpng for PNG input and output, and is designed - to show how to prepare data for the squish library when it is not simply - a contiguous block of memory. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _MSC_VER -#pragma warning( disable: 4511 4512 ) -#endif // def _MSC_VER - -using namespace squish; - -//! Simple exception class. -class Error : public std::exception -{ -public: - Error( std::string const& excuse ) : m_excuse( excuse ) {} - ~Error() throw() {} - - virtual char const* what() const throw() { return m_excuse.c_str(); } - -private: - std::string m_excuse; -}; - -//! Base class to make derived classes non-copyable -class NonCopyable -{ -public: - NonCopyable() {} - -private: - NonCopyable( NonCopyable const& ); - NonCopyable& operator=( NonCopyable const& ); -}; - -//! Memory object. -class Mem : NonCopyable -{ -public: - explicit Mem( int size ) : m_p( new u8[size] ) {} - ~Mem() { delete[] m_p; } - - u8* Get() const { return m_p; } - -private: - u8* m_p; -}; - -//! File object. -class File : NonCopyable -{ -public: - explicit File( FILE* fp ) : m_fp( fp ) {} - ~File() { if( m_fp ) fclose( m_fp ); } - - bool IsValid() const { return m_fp != 0; } - FILE* Get() const { return m_fp; } - -private: - FILE* m_fp; -}; - -//! PNG read object. -class PngReadStruct : NonCopyable -{ -public: - PngReadStruct() - : m_png( 0 ), - m_info( 0 ), - m_end( 0 ) - { - m_png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); - if( !m_png ) - throw Error( "failed to create png read struct" ); - - m_info = png_create_info_struct( m_png ); - m_end = png_create_info_struct( m_png ); - if( !m_info || !m_end ) - { - png_infopp info = m_info ? &m_info : 0; - png_infopp end = m_end ? &m_end : 0; - png_destroy_read_struct( &m_png, info, end ); - throw Error( "failed to create png info structs" ); - } - } - - ~PngReadStruct() - { - png_destroy_read_struct( &m_png, &m_info, &m_end ); - } - - png_structp GetPng() const { return m_png; } - png_infop GetInfo() const { return m_info; } - -private: - png_structp m_png; - png_infop m_info, m_end; -}; - -//! PNG write object. -class PngWriteStruct : NonCopyable -{ -public: - PngWriteStruct() - : m_png( 0 ), - m_info( 0 ) - { - m_png = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); - if( !m_png ) - throw Error( "failed to create png read struct" ); - - m_info = png_create_info_struct( m_png ); - if( !m_info ) - { - png_infopp info = m_info ? &m_info : 0; - png_destroy_write_struct( &m_png, info ); - throw Error( "failed to create png info structs" ); - } - } - - ~PngWriteStruct() - { - png_destroy_write_struct( &m_png, &m_info ); - } - - png_structp GetPng() const { return m_png; } - png_infop GetInfo() const { return m_info; } - -private: - png_structp m_png; - png_infop m_info; -}; - -//! PNG rows object. -class PngRows : NonCopyable -{ -public: - PngRows( int width, int height, int stride ) : m_width( width ), m_height( height ) - { - m_rows = ( png_bytep* )malloc( m_height*sizeof( png_bytep ) ); - for( int i = 0; i < m_height; ++i ) - m_rows[i] = ( png_bytep )malloc( m_width*stride ); - } - - ~PngRows() - { - for( int i = 0; i < m_height; ++i ) - free( m_rows[i] ); - free( m_rows ); - } - - png_bytep* Get() const { return m_rows; } - -private: - png_bytep* m_rows; - int m_width, m_height; -}; - -class PngImage -{ -public: - explicit PngImage( std::string const& fileName ); - - int GetWidth() const { return m_width; } - int GetHeight() const { return m_height; } - int GetStride() const { return m_stride; } - bool IsColour() const { return m_colour; } - bool IsAlpha() const { return m_alpha; } - - u8 const* GetRow( int row ) const { return ( u8* )m_rows[row]; } - -private: - PngReadStruct m_png; - - int m_width; - int m_height; - int m_stride; - bool m_colour; - bool m_alpha; - - png_bytep* m_rows; -}; - -PngImage::PngImage( std::string const& fileName ) -{ - // open the source file - File file( fopen( fileName.c_str(), "rb" ) ); - if( !file.IsValid() ) - { - std::ostringstream oss; - oss << "failed to open \"" << fileName << "\" for reading"; - throw Error( oss.str() ); - } - - // check the signature bytes - png_byte header[8]; - fread( header, 1, 8, file.Get() ); - if( png_sig_cmp( header, 0, 8 ) ) - { - std::ostringstream oss; - oss << "\"" << fileName << "\" does not look like a png file"; - throw Error( oss.str() ); - } - - // read the image into memory - png_init_io( m_png.GetPng(), file.Get() ); - png_set_sig_bytes( m_png.GetPng(), 8 ); - png_read_png( m_png.GetPng(), m_png.GetInfo(), PNG_TRANSFORM_EXPAND, 0 ); - - // get the image info - png_uint_32 width; - png_uint_32 height; - int bitDepth; - int colourType; - png_get_IHDR( m_png.GetPng(), m_png.GetInfo(), &width, &height, &bitDepth, &colourType, 0, 0, 0 ); - - // check the image is 8 bit - if( bitDepth != 8 ) - { - std::ostringstream oss; - oss << "cannot process " << bitDepth << "-bit image (bit depth must be 8)"; - throw Error( oss.str() ); - } - - // save the info - m_width = width; - m_height = height; - m_colour = ( ( colourType & PNG_COLOR_MASK_COLOR ) != 0 ); - m_alpha = ( ( colourType & PNG_COLOR_MASK_ALPHA ) != 0 ); - m_stride = ( m_colour ? 3 : 1 ) + ( m_alpha ? 1 : 0 ); - - // get the image rows - m_rows = png_get_rows( m_png.GetPng(), m_png.GetInfo() ); - if( !m_rows ) - throw Error( "failed to get image rows" ); -} - -static void Compress( std::string const& sourceFileName, std::string const& targetFileName, int flags ) -{ - // load the source image - PngImage sourceImage( sourceFileName ); - - // get the image info - int width = sourceImage.GetWidth(); - int height = sourceImage.GetHeight(); - int stride = sourceImage.GetStride(); - bool colour = sourceImage.IsColour(); - bool alpha = sourceImage.IsAlpha(); - - // check the image dimensions - if( ( width % 4 ) != 0 || ( height % 4 ) != 0 ) - { - std::ostringstream oss; - oss << "cannot compress " << width << "x" << height - << "image (dimensions must be multiples of 4)"; - throw Error( oss.str() ); - } - - // create the target data - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; - int targetDataSize = bytesPerBlock*width*height/16; - Mem targetData( targetDataSize ); - - // loop over blocks and compress them - clock_t start = std::clock(); - u8* targetBlock = targetData.Get(); - for( int y = 0; y < height; y += 4 ) - { - // process a row of blocks - for( int x = 0; x < width; x += 4 ) - { - // get the block data - u8 sourceRgba[16*4]; - for( int py = 0, i = 0; py < 4; ++py ) - { - u8 const* row = sourceImage.GetRow( y + py ) + x*stride; - for( int px = 0; px < 4; ++px, ++i ) - { - // get the pixel colour - if( colour ) - { - for( int j = 0; j < 3; ++j ) - sourceRgba[4*i + j] = *row++; - } - else - { - for( int j = 0; j < 3; ++j ) - sourceRgba[4*i + j] = *row; - ++row; - } - - // skip alpha for now - if( alpha ) - sourceRgba[4*i + 3] = *row++; - else - sourceRgba[4*i + 3] = 255; - } - } - - // compress this block - Compress( sourceRgba, targetBlock, flags ); - - // advance - targetBlock += bytesPerBlock; - } - } - clock_t end = std::clock(); - double duration = ( double )( end - start ) / CLOCKS_PER_SEC; - std::cout << "time taken: " << duration << " seconds" << std::endl; - - // open the target file - File targetFile( fopen( targetFileName.c_str(), "wb" ) ); - if( !targetFile.IsValid() ) - { - std::ostringstream oss; - oss << "failed to open \"" << sourceFileName << "\" for writing"; - throw Error( oss.str() ); - } - - // write the header - fwrite( &width, sizeof( int ), 1, targetFile.Get() ); - fwrite( &height, sizeof( int ), 1, targetFile.Get() ); - - // write the data - fwrite( targetData.Get(), 1, targetDataSize, targetFile.Get() ); -} - -static void Decompress( std::string const& sourceFileName, std::string const& targetFileName, int flags ) -{ - // open the source file - File sourceFile( fopen( sourceFileName.c_str(), "rb" ) ); - if( !sourceFile.IsValid() ) - { - std::ostringstream oss; - oss << "failed to open \"" << sourceFileName << "\" for reading"; - throw Error( oss.str() ); - } - - // get the width and height - int width, height; - fread( &width, sizeof( int ), 1, sourceFile.Get() ); - fread( &height, sizeof( int ), 1, sourceFile.Get() ); - - // work out the data size - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; - int sourceDataSize = bytesPerBlock*width*height/16; - Mem sourceData( sourceDataSize ); - - // read the source data - fread( sourceData.Get(), 1, sourceDataSize, sourceFile.Get() ); - - // create the target rows - PngRows targetRows( width, height, 4 ); - - // loop over blocks and compress them - u8 const* sourceBlock = sourceData.Get(); - for( int y = 0; y < height; y += 4 ) - { - // process a row of blocks - for( int x = 0; x < width; x += 4 ) - { - // decompress back - u8 targetRgba[16*4]; - Decompress( targetRgba, sourceBlock, flags ); - - // write the data into the target rows - for( int py = 0, i = 0; py < 4; ++py ) - { - u8* row = ( u8* )targetRows.Get()[y + py] + x*4; - for( int px = 0; px < 4; ++px, ++i ) - { - for( int j = 0; j < 4; ++j ) - *row++ = targetRgba[4*i + j]; - } - } - - // advance - sourceBlock += bytesPerBlock; - } - } - - // create the target PNG - PngWriteStruct targetPng; - - // set up the image - png_set_IHDR( - targetPng.GetPng(), targetPng.GetInfo(), width, height, - 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT - ); - - // open the target file - File targetFile( fopen( targetFileName.c_str(), "wb" ) ); - if( !targetFile.IsValid() ) - { - std::ostringstream oss; - oss << "failed to open \"" << targetFileName << "\" for writing"; - throw Error( oss.str() ); - } - - // write the image - png_set_rows( targetPng.GetPng(), targetPng.GetInfo(), targetRows.Get() ); - png_init_io( targetPng.GetPng(), targetFile.Get() ); - png_write_png( targetPng.GetPng(), targetPng.GetInfo(), PNG_TRANSFORM_IDENTITY, 0 ); -} - -static void Diff( std::string const& sourceFileName, std::string const& targetFileName ) -{ - // load the images - PngImage sourceImage( sourceFileName ); - PngImage targetImage( targetFileName ); - - // get the image info - int width = sourceImage.GetWidth(); - int height = sourceImage.GetHeight(); - int sourceStride = sourceImage.GetStride(); - int targetStride = targetImage.GetStride(); - int stride = std::min( sourceStride, targetStride ); - - // check they match - if( width != targetImage.GetWidth() || height != targetImage.GetHeight() ) - throw Error( "source and target dimensions do not match" ); - - // work out the error - double error = 0.0; - for( int y = 0; y < height; ++y ) - { - u8 const* sourceRow = sourceImage.GetRow( y ); - u8 const* targetRow = targetImage.GetRow( y ); - for( int x = 0; x < width; ++x ) - { - u8 const* sourcePixel = sourceRow + x*sourceStride; - u8 const* targetPixel = targetRow + x*targetStride; - for( int i = 0; i < stride; ++i ) - { - int diff = ( int )sourcePixel[i] - ( int )targetPixel[i]; - error += ( double )( diff*diff ); - } - } - } - error = std::sqrt( error / ( width*height ) ); - - // print it out - std::cout << "rms error: " << error << std::endl; -} - -enum Mode -{ - kCompress, - kDecompress, - kDiff -}; - -int main( int argc, char* argv[] ) -{ - try - { - // parse the command-line - std::string sourceFileName; - std::string targetFileName; - Mode mode = kCompress; - int method = kDxt1; - int metric = kColourMetricPerceptual; - int fit = kColourClusterFit; - int extra = 0; - bool help = false; - bool arguments = true; - for( int i = 1; i < argc; ++i ) - { - // check for options - char const* word = argv[i]; - if( arguments && word[0] == '-' ) - { - for( int j = 1; word[j] != '\0'; ++j ) - { - switch( word[j] ) - { - case 'h': help = true; break; - case 'c': mode = kCompress; break; - case 'd': mode = kDecompress; break; - case 'e': mode = kDiff; break; - case '1': method = kDxt1; break; - case '3': method = kDxt3; break; - case '5': method = kDxt5; break; - case 'u': metric = kColourMetricUniform; break; - case 'r': fit = kColourRangeFit; break; - case 'w': extra = kWeightColourByAlpha; break; - case '-': arguments = false; break; - default: - std::cerr << "unknown option '" << word[j] << "'" << std::endl; - return -1; - } - } - } - else - { - if( sourceFileName.empty() ) - sourceFileName.assign( word ); - else if( targetFileName.empty() ) - targetFileName.assign( word ); - else - { - std::cerr << "unexpected argument \"" << word << "\"" << std::endl; - } - } - } - - // check arguments - if( help ) - { - std::cout - << "SYNTAX" << std::endl - << "\tsquishpng [-cde135] " << std::endl - << "OPTIONS" << std::endl - << "\t-c\tCompress source png to target raw dxt (default)" << std::endl - << "\t-135\tSpecifies whether to use DXT1 (default), DXT3 or DXT5 compression" << std::endl - << "\t-u\tUse a uniform colour metric during colour compression" << std::endl - << "\t-r\tUse the fast but inferior range-based colour compressor" << std::endl - << "\t-w\tWeight colour values by alpha in the cluster colour compressor" << std::endl - << "\t-d\tDecompress source raw dxt to target png" << std::endl - << "\t-e\tDiff source and target png" << std::endl - ; - - return 0; - } - if( sourceFileName.empty() ) - { - std::cerr << "no source file given" << std::endl; - return -1; - } - if( targetFileName.empty() ) - { - std::cerr << "no target file given" << std::endl; - return -1; - } - - // do the work - switch( mode ) - { - case kCompress: - Compress( sourceFileName, targetFileName, method | metric | fit | extra ); - break; - - case kDecompress: - Decompress( sourceFileName, targetFileName, method ); - break; - - case kDiff: - Diff( sourceFileName, targetFileName ); - break; - - default: - std::cerr << "unknown mode" << std::endl; - throw std::exception(); - } - } - catch( std::exception& excuse ) - { - // complain - std::cerr << "squishpng error: " << excuse.what() << std::endl; - return -1; - } - - // done - return 0; -} diff --git a/Externals/NVTT/src/nvtt/squish/extra/squishtest.cpp b/Externals/NVTT/src/nvtt/squish/extra/squishtest.cpp deleted file mode 100644 index 594d8e259b6..00000000000 --- a/Externals/NVTT/src/nvtt/squish/extra/squishtest.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -/*! @file - - @brief This program tests the error for 1 and 2-colour DXT compression. - - This tests the effectiveness of the DXT compression algorithm for all - possible 1 and 2-colour blocks of pixels. -*/ - -#include -#include -#include -#include - -using namespace squish; - -double GetColourError( u8 const* a, u8 const* b ) -{ - double error = 0.0; - for( int i = 0; i < 16; ++i ) - { - for( int j = 0; j < 3; ++j ) - { - int index = 4*i + j; - int diff = ( int )a[index] - ( int )b[index]; - error += ( double )( diff*diff ); - } - } - return error / 16.0; -} - -void TestOneColour( int flags ) -{ - u8 input[4*16]; - u8 output[4*16]; - u8 block[16]; - - double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; - int counter = 0; - - // test all single-channel colours - for( int i = 0; i < 16*4; ++i ) - input[i] = ( ( i % 4 ) == 3 ) ? 255 : 0; - for( int channel = 0; channel < 3; ++channel ) - { - for( int value = 0; value < 255; ++value ) - { - // set the channnel value - for( int i = 0; i < 16; ++i ) - input[4*i + channel] = ( u8 )value; - - // compress and decompress - Compress( input, block, flags ); - Decompress( output, block, flags ); - - // test the results - double rm = GetColourError( input, output ); - double rms = std::sqrt( rm ); - - // accumulate stats - min = std::min( min, rms ); - max = std::max( max, rms ); - avg += rm; - ++counter; - } - - // reset the channel value - for( int i = 0; i < 16; ++i ) - input[4*i + channel] = 0; - } - - // finish stats - avg = std::sqrt( avg/counter ); - - // show stats - std::cout << "one colour error (min, max, avg): " - << min << ", " << max << ", " << avg << std::endl; -} - -void TestOneColourRandom( int flags ) -{ - u8 input[4*16]; - u8 output[4*16]; - u8 block[16]; - - double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; - int counter = 0; - - // test all single-channel colours - for( int test = 0; test < 1000; ++test ) - { - // set a constant random colour - for( int channel = 0; channel < 3; ++channel ) - { - u8 value = ( u8 )( rand() & 0xff ); - for( int i = 0; i < 16; ++i ) - input[4*i + channel] = value; - } - for( int i = 0; i < 16; ++i ) - input[4*i + 3] = 255; - - // compress and decompress - Compress( input, block, flags ); - Decompress( output, block, flags ); - - // test the results - double rm = GetColourError( input, output ); - double rms = std::sqrt( rm ); - - // accumulate stats - min = std::min( min, rms ); - max = std::max( max, rms ); - avg += rm; - ++counter; - } - - // finish stats - avg = std::sqrt( avg/counter ); - - // show stats - std::cout << "random one colour error (min, max, avg): " - << min << ", " << max << ", " << avg << std::endl; -} - -void TestTwoColour( int flags ) -{ - u8 input[4*16]; - u8 output[4*16]; - u8 block[16]; - - double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; - int counter = 0; - - // test all single-channel colours - for( int i = 0; i < 16*4; ++i ) - input[i] = ( ( i % 4 ) == 3 ) ? 255 : 0; - for( int channel = 0; channel < 3; ++channel ) - { - for( int value1 = 0; value1 < 255; ++value1 ) - { - for( int value2 = value1 + 1; value2 < 255; ++value2 ) - { - // set the channnel value - for( int i = 0; i < 16; ++i ) - input[4*i + channel] = ( u8 )( ( i < 8 ) ? value1 : value2 ); - - // compress and decompress - Compress( input, block, flags ); - Decompress( output, block, flags ); - - // test the results - double rm = GetColourError( input, output ); - double rms = std::sqrt( rm ); - - // accumulate stats - min = std::min( min, rms ); - max = std::max( max, rms ); - avg += rm; - ++counter; - } - } - - // reset the channel value - for( int i = 0; i < 16; ++i ) - input[4*i + channel] = 0; - } - - // finish stats - avg = std::sqrt( avg/counter ); - - // show stats - std::cout << "two colour error (min, max, avg): " - << min << ", " << max << ", " << avg << std::endl; -} - -int main() -{ - TestOneColourRandom( kDxt1 | kColourRangeFit ); - TestOneColour( kDxt1 ); - TestTwoColour( kDxt1 ); -} diff --git a/Externals/NVTT/src/nvtt/squish/fastclusterfit.cpp b/Externals/NVTT/src/nvtt/squish/fastclusterfit.cpp deleted file mode 100644 index 5fdb0ef2950..00000000000 --- a/Externals/NVTT/src/nvtt/squish/fastclusterfit.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2006 Ignacio Castano icastano@nvidia.com - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "fastclusterfit.h" -#include "colourset.h" -#include "colourblock.h" -#include - -#include "fastclusterlookup.inl" - -namespace squish { - -FastClusterFit::FastClusterFit() -{ -} - -void FastClusterFit::SetColourSet( ColourSet const* colours, int flags ) -{ - ColourFit::SetColourSet( colours, flags ); - - // initialise the best error -#if SQUISH_USE_SIMD - m_besterror = VEC4_CONST( FLT_MAX ); - Vec3 metric = m_metric.GetVec3(); -#else - m_besterror = FLT_MAX; - Vec3 metric = m_metric; -#endif - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights(), metric ); - - // compute the principle component - Vec3 principle = ComputePrincipleComponent( covariance ); - - // build the list of values - float dps[16]; - for( int i = 0; i < count; ++i ) - { - dps[i] = Dot( values[i], principle ); - m_order[i] = i; - } - - // stable sort - for( int i = 0; i < count; ++i ) - { - for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) - { - std::swap( dps[j], dps[j - 1] ); - std::swap( m_order[j], m_order[j - 1] ); - } - } - - // weight all the points -#if SQUISH_USE_SIMD - Vec4 const* unweighted = m_colours->GetPointsSimd(); - m_xxsum = VEC4_CONST( 0.0f ); - m_xsum = VEC4_CONST( 0.0f ); -#else - Vec3 const* unweighted = m_colours->GetPoints(); - m_xxsum = Vec3( 0.0f ); - m_xsum = Vec3( 0.0f ); -#endif - - for( int i = 0; i < count; ++i ) - { - int p = m_order[i]; - m_unweighted[i] = unweighted[p]; - m_xxsum += m_unweighted[i]*m_unweighted[i]; - m_xsum += m_unweighted[i]; - } -} - - -void FastClusterFit::SetMetric(float r, float g, float b) -{ -#if SQUISH_USE_SIMD - m_metric = Vec4(r, g, b, 0); -#else - m_metric = Vec3(r, g, b); -#endif - m_metricSqr = m_metric * m_metric; -} - -float FastClusterFit::GetBestError() const -{ -#if SQUISH_USE_SIMD - Vec4 x = m_xxsum * m_metricSqr; - Vec4 error = m_besterror + x.SplatX() + x.SplatY() + x.SplatZ(); - return error.GetVec3().X(); -#else - return m_besterror + Dot(m_xxsum, m_metricSqr); -#endif - -} - -#if SQUISH_USE_SIMD - -void FastClusterFit::Compress3( void* block ) -{ - Vec4 const one = VEC4_CONST(1.0f); - Vec4 const zero = VEC4_CONST(0.0f); - Vec4 const half = VEC4_CONST(0.5f); - Vec4 const two = VEC4_CONST(2.0); - - // declare variables - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = VEC4_CONST( FLT_MAX ); - - Vec4 x0 = zero; - Vec4 x1; - int b0 = 0, b1 = 0; - int i = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= 16; c0++) - { - x1 = zero; - - for( int c1 = 0; c1 <= 16-c0; c1++) - { - Vec4 const constants = Vec4((const float *)&s_threeElement[i]); - Vec4 const alpha2_sum = constants.SplatX(); - Vec4 const beta2_sum = constants.SplatY(); - Vec4 const alphabeta_sum = constants.SplatZ(); - Vec4 const factor = constants.SplatW(); - i++; - - Vec4 const alphax_sum = MultiplyAdd(half, x1, x0); - Vec4 const betax_sum = m_xsum - alphax_sum; - - Vec4 a = NegativeMultiplySubtract(betax_sum, alphabeta_sum, alphax_sum*beta2_sum) * factor; - Vec4 b = NegativeMultiplySubtract(alphax_sum, alphabeta_sum, betax_sum*alpha2_sum) * factor; - - // clamp the output to [0, 1] - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 0.03227752766457f, 0.01583151765563f, 0.03227752766457f, 0.0f ); - a = Truncate( MultiplyAdd( grid, a, half ) ) * gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) ) * gridrcp; - - // compute the error - Vec4 e1 = MultiplyAdd( a, alphax_sum, b*betax_sum ); - Vec4 e2 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e3 = MultiplyAdd( a*b*alphabeta_sum - e1, two, e2 ); - - // apply the metric to the error term - Vec4 e4 = e3 * m_metricSqr; - Vec4 error = e4.SplatX() + e4.SplatY() + e4.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - } - - x1 += m_unweighted[c0+c1]; - } - - x0 += m_unweighted[c0]; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // compute indices from cluster sizes. - /*uint bestindices = 0; - { - int i = b0; - for(; i < b0+b1; i++) { - bestindices |= 2 << (2 * i); - } - for(; i < 16; i++) { - bestindices |= 1 << (2 * i); - } - }*/ - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < 16; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < 16; ++i ) - ordered[m_order[i]] = bestindices[i]; - - m_colours->RemapIndices( ordered, bestindices ); // Set alpha indices. - - // save the block - WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), ordered, block ); - - // save the error - m_besterror = besterror; - } -} - -void FastClusterFit::Compress4( void* block ) -{ - Vec4 const one = VEC4_CONST(1.0f); - Vec4 const zero = VEC4_CONST(0.0f); - Vec4 const half = VEC4_CONST(0.5f); - Vec4 const two = VEC4_CONST(2.0); - Vec4 const onethird = VEC4_CONST( 1.0f/3.0f ); - Vec4 const twothirds = VEC4_CONST( 2.0f/3.0f ); - - // declare variables - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = VEC4_CONST( FLT_MAX ); - - Vec4 x0 = zero; - int b0 = 0, b1 = 0, b2 = 0; - int i = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= 16; c0++) - { - Vec4 x1 = zero; - - for( int c1 = 0; c1 <= 16-c0; c1++) - { - Vec4 x2 = zero; - - for( int c2 = 0; c2 <= 16-c0-c1; c2++) - { - Vec4 const constants = Vec4((const float *)&s_fourElement[i]); - Vec4 const alpha2_sum = constants.SplatX(); - Vec4 const beta2_sum = constants.SplatY(); - Vec4 const alphabeta_sum = constants.SplatZ(); - Vec4 const factor = constants.SplatW(); - i++; - - Vec4 const alphax_sum = x0 + MultiplyAdd(x1, twothirds, x2 * onethird); - Vec4 const betax_sum = m_xsum - alphax_sum; - - Vec4 a = NegativeMultiplySubtract(betax_sum, alphabeta_sum, alphax_sum*beta2_sum) * factor; - Vec4 b = NegativeMultiplySubtract(alphax_sum, alphabeta_sum, betax_sum*alpha2_sum) * factor; - - // clamp the output to [0, 1] - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 0.03227752766457f, 0.01583151765563f, 0.03227752766457f, 0.0f ); - a = Truncate( MultiplyAdd( grid, a, half ) ) * gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) ) * gridrcp; - - // compute the error - Vec4 e1 = MultiplyAdd( a, alphax_sum, b*betax_sum ); - Vec4 e2 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e3 = MultiplyAdd( a*b*alphabeta_sum - e1, two, e2 ); - - // apply the metric to the error term - Vec4 e4 = e3 * m_metricSqr; - Vec4 error = e4.SplatX() + e4.SplatY() + e4.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - b2 = c2; - } - - x2 += m_unweighted[c0+c1+c2]; - } - - x1 += m_unweighted[c0+c1]; - } - - x0 += m_unweighted[c0]; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // compute indices from cluster sizes. - /*uint bestindices = 0; - { - int i = b0; - for(; i < b0+b1; i++) { - bestindices = 2 << (2 * m_order[i]); - } - for(; i < b0+b1+b2; i++) { - bestindices = 3 << (2 * m_order[i]); - } - for(; i < 16; i++) { - bestindices = 1 << (2 * m_order[i]); - } - }*/ - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < b0+b1+b2; i++) { - bestindices[i] = 3; - } - for(; i < 16; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < 16; ++i ) - ordered[m_order[i]] = bestindices[i]; - - // save the block - WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), ordered, block ); - - // save the error - m_besterror = besterror; - } -} - -#else - -void FastClusterFit::Compress3( void* block ) -{ - // declare variables - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = FLT_MAX; - - Vec3 x0(0.0f); - Vec3 x1; - int b0 = 0, b1 = 0; - int i = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 < 16; c0++) - { - x1 = Vec3(0); - - for( int c1 = 0; c1 < 16-c0; c1++) - { - float const alpha2_sum = s_threeElement[i].alpha2_sum; - float const beta2_sum = s_threeElement[i].beta2_sum; - float const alphabeta_sum = s_threeElement[i].alphabeta_sum; - float const factor = s_threeElement[i].factor; - i++; - - Vec3 const alphax_sum = x0 + x1 * 0.5f; - Vec3 const betax_sum = m_xsum - alphax_sum; - - Vec3 a = (alphax_sum*beta2_sum - betax_sum*alphabeta_sum) * factor; - Vec3 b = (betax_sum*alpha2_sum - alphax_sum*alphabeta_sum) * factor; - - // clamp the output to [0, 1] - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 0.03227752766457f, 0.01583151765563f, 0.03227752766457f ); - Vec3 const half( 0.5f ); - a = Floor( grid*a + half )*gridrcp; - b = Floor( grid*b + half )*gridrcp; - - // compute the error - Vec3 e1 = a*a*alpha2_sum + b*b*beta2_sum + 2.0f*( a*b*alphabeta_sum - a*alphax_sum - b*betax_sum ); - - // apply the metric to the error term - float error = Dot( e1, m_metricSqr ); - - // keep the solution if it wins - if( error < besterror ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - } - - x1 += m_unweighted[c0+c1]; - } - - x0 += m_unweighted[c0]; - } - - // save the block if necessary - if( besterror < m_besterror ) - { - // compute indices from cluster sizes. - /*uint bestindices = 0; - { - int i = b0; - for(; i < b0+b1; i++) { - bestindices |= 2 << (2 * m_order[i]); - } - for(; i < 16; i++) { - bestindices |= 1 << (2 * m_order[i]); - } - }*/ - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < 16; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < 16; ++i ) - ordered[m_order[i]] = bestindices[i]; - - // save the block - WriteColourBlock3( beststart, bestend, ordered, block ); - - // save the error - m_besterror = besterror; - } -} - -void FastClusterFit::Compress4( void* block ) -{ - // declare variables - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = FLT_MAX; - - Vec3 x0(0.0f); - Vec3 x1; - Vec3 x2; - int b0 = 0, b1 = 0, b2 = 0; - int i = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 < 16; c0++) - { - x1 = Vec3(0.0f); - - for( int c1 = 0; c1 < 16-c0; c1++) - { - x2 = Vec3(0.0f); - - for( int c2 = 0; c2 < 16-c0-c1; c2++) - { - float const alpha2_sum = s_fourElement[i].alpha2_sum; - float const beta2_sum = s_fourElement[i].beta2_sum; - float const alphabeta_sum = s_fourElement[i].alphabeta_sum; - float const factor = s_fourElement[i].factor; - i++; - - Vec3 const alphax_sum = x0 + x1 * (2.0f / 3.0f) + x2 * (1.0f / 3.0f); - Vec3 const betax_sum = m_xsum - alphax_sum; - - Vec3 a = ( alphax_sum*beta2_sum - betax_sum*alphabeta_sum )*factor; - Vec3 b = ( betax_sum*alpha2_sum - alphax_sum*alphabeta_sum )*factor; - - // clamp the output to [0, 1] - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - - // clamp to the grid - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 0.03227752766457f, 0.01583151765563f, 0.03227752766457f ); - Vec3 const half( 0.5f ); - a = Floor( grid*a + half )*gridrcp; - b = Floor( grid*b + half )*gridrcp; - - // compute the error - Vec3 e1 = a*a*alpha2_sum + b*b*beta2_sum + 2.0f*( a*b*alphabeta_sum - a*alphax_sum - b*betax_sum ); - - // apply the metric to the error term - float error = Dot( e1, m_metricSqr ); - - // keep the solution if it wins - if( error < besterror ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - b2 = c2; - } - - x2 += m_unweighted[c0+c1+c2]; - } - - x1 += m_unweighted[c0+c1]; - } - - x0 += m_unweighted[c0]; - } - - // save the block if necessary - if( besterror < m_besterror ) - { - // compute indices from cluster sizes. - /*uint bestindices = 0; - { - int i = b0; - for(; i < b0+b1; i++) { - bestindices = 2 << (2 * m_order[i]); - } - for(; i < b0+b1+b2; i++) { - bestindices = 3 << (2 * m_order[i]); - } - for(; i < 16; i++) { - bestindices = 1 << (2 * m_order[i]); - } - }*/ - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < b0+b1+b2; i++) { - bestindices[i] = 3; - } - for(; i < 16; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < 16; ++i ) - ordered[m_order[i]] = bestindices[i]; - - // save the block - WriteColourBlock4( beststart, bestend, ordered, block ); - - // save the error - m_besterror = besterror; - } -} - -#endif - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/fastclusterfit.h b/Externals/NVTT/src/nvtt/squish/fastclusterfit.h deleted file mode 100644 index d0ed97115a1..00000000000 --- a/Externals/NVTT/src/nvtt/squish/fastclusterfit.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2006 Ignacio Castano icastano@nvidia.com - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_FASTCLUSTERFIT_H -#define SQUISH_FASTCLUSTERFIT_H - -#include "squish.h" -#include "maths.h" -#include "simd.h" -#include "colourfit.h" - -namespace squish { - -class FastClusterFit : public ColourFit -{ -public: - FastClusterFit(); - - void SetColourSet( ColourSet const* colours, int flags ); - - void SetMetric(float r, float g, float b); - float GetBestError() const; - - // Make them public - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - -private: - - Vec3 m_principle; - -#if SQUISH_USE_SIMD - Vec4 m_unweighted[16]; - Vec4 m_metric; - Vec4 m_metricSqr; - Vec4 m_xxsum; - Vec4 m_xsum; - Vec4 m_besterror; -#else - Vec3 m_unweighted[16]; - Vec3 m_metric; - Vec3 m_metricSqr; - Vec3 m_xxsum; - Vec3 m_xsum; - float m_besterror; -#endif - - int m_order[16]; -}; - -} // namespace squish - -#endif // ndef SQUISH_FASTCLUSTERFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/fastclusterlookup.inl b/Externals/NVTT/src/nvtt/squish/fastclusterlookup.inl deleted file mode 100644 index acdd6801763..00000000000 --- a/Externals/NVTT/src/nvtt/squish/fastclusterlookup.inl +++ /dev/null @@ -1,1135 +0,0 @@ -struct Precomp { - float alpha2_sum; - float beta2_sum; - float alphabeta_sum; - float factor; -}; - -static const SQUISH_ALIGN_16 Precomp s_threeElement[153] = { - { 0.000000f, 16.000000f, 0.000000f, FLT_MAX }, // 0 (0 0 16) - { 0.250000f, 15.250000f, 0.250000f, 0.266667f }, // 1 (0 1 15) - { 0.500000f, 14.500000f, 0.500000f, 0.142857f }, // 2 (0 2 14) - { 0.750000f, 13.750000f, 0.750000f, 0.102564f }, // 3 (0 3 13) - { 1.000000f, 13.000000f, 1.000000f, 0.083333f }, // 4 (0 4 12) - { 1.250000f, 12.250000f, 1.250000f, 0.072727f }, // 5 (0 5 11) - { 1.500000f, 11.500000f, 1.500000f, 0.066667f }, // 6 (0 6 10) - { 1.750000f, 10.750000f, 1.750000f, 0.063492f }, // 7 (0 7 9) - { 2.000000f, 10.000000f, 2.000000f, 0.062500f }, // 8 (0 8 8) - { 2.250000f, 9.250000f, 2.250000f, 0.063492f }, // 9 (0 9 7) - { 2.500000f, 8.500000f, 2.500000f, 0.066667f }, // 10 (0 10 6) - { 2.750000f, 7.750000f, 2.750000f, 0.072727f }, // 11 (0 11 5) - { 3.000000f, 7.000000f, 3.000000f, 0.083333f }, // 12 (0 12 4) - { 3.250000f, 6.250000f, 3.250000f, 0.102564f }, // 13 (0 13 3) - { 3.500000f, 5.500000f, 3.500000f, 0.142857f }, // 14 (0 14 2) - { 3.750000f, 4.750000f, 3.750000f, 0.266667f }, // 15 (0 15 1) - { 4.000000f, 4.000000f, 4.000000f, FLT_MAX }, // 16 (0 16 0) - { 1.000000f, 15.000000f, 0.000000f, 0.066667f }, // 17 (1 0 15) - { 1.250000f, 14.250000f, 0.250000f, 0.056338f }, // 18 (1 1 14) - { 1.500000f, 13.500000f, 0.500000f, 0.050000f }, // 19 (1 2 13) - { 1.750000f, 12.750000f, 0.750000f, 0.045977f }, // 20 (1 3 12) - { 2.000000f, 12.000000f, 1.000000f, 0.043478f }, // 21 (1 4 11) - { 2.250000f, 11.250000f, 1.250000f, 0.042105f }, // 22 (1 5 10) - { 2.500000f, 10.500000f, 1.500000f, 0.041667f }, // 23 (1 6 9) - { 2.750000f, 9.750000f, 1.750000f, 0.042105f }, // 24 (1 7 8) - { 3.000000f, 9.000000f, 2.000000f, 0.043478f }, // 25 (1 8 7) - { 3.250000f, 8.250000f, 2.250000f, 0.045977f }, // 26 (1 9 6) - { 3.500000f, 7.500000f, 2.500000f, 0.050000f }, // 27 (1 10 5) - { 3.750000f, 6.750000f, 2.750000f, 0.056338f }, // 28 (1 11 4) - { 4.000000f, 6.000000f, 3.000000f, 0.066667f }, // 29 (1 12 3) - { 4.250000f, 5.250000f, 3.250000f, 0.085106f }, // 30 (1 13 2) - { 4.500000f, 4.500000f, 3.500000f, 0.125000f }, // 31 (1 14 1) - { 4.750000f, 3.750000f, 3.750000f, 0.266667f }, // 32 (1 15 0) - { 2.000000f, 14.000000f, 0.000000f, 0.035714f }, // 33 (2 0 14) - { 2.250000f, 13.250000f, 0.250000f, 0.033613f }, // 34 (2 1 13) - { 2.500000f, 12.500000f, 0.500000f, 0.032258f }, // 35 (2 2 12) - { 2.750000f, 11.750000f, 0.750000f, 0.031496f }, // 36 (2 3 11) - { 3.000000f, 11.000000f, 1.000000f, 0.031250f }, // 37 (2 4 10) - { 3.250000f, 10.250000f, 1.250000f, 0.031496f }, // 38 (2 5 9) - { 3.500000f, 9.500000f, 1.500000f, 0.032258f }, // 39 (2 6 8) - { 3.750000f, 8.750000f, 1.750000f, 0.033613f }, // 40 (2 7 7) - { 4.000000f, 8.000000f, 2.000000f, 0.035714f }, // 41 (2 8 6) - { 4.250000f, 7.250000f, 2.250000f, 0.038835f }, // 42 (2 9 5) - { 4.500000f, 6.500000f, 2.500000f, 0.043478f }, // 43 (2 10 4) - { 4.750000f, 5.750000f, 2.750000f, 0.050633f }, // 44 (2 11 3) - { 5.000000f, 5.000000f, 3.000000f, 0.062500f }, // 45 (2 12 2) - { 5.250000f, 4.250000f, 3.250000f, 0.085106f }, // 46 (2 13 1) - { 5.500000f, 3.500000f, 3.500000f, 0.142857f }, // 47 (2 14 0) - { 3.000000f, 13.000000f, 0.000000f, 0.025641f }, // 48 (3 0 13) - { 3.250000f, 12.250000f, 0.250000f, 0.025157f }, // 49 (3 1 12) - { 3.500000f, 11.500000f, 0.500000f, 0.025000f }, // 50 (3 2 11) - { 3.750000f, 10.750000f, 0.750000f, 0.025157f }, // 51 (3 3 10) - { 4.000000f, 10.000000f, 1.000000f, 0.025641f }, // 52 (3 4 9) - { 4.250000f, 9.250000f, 1.250000f, 0.026490f }, // 53 (3 5 8) - { 4.500000f, 8.500000f, 1.500000f, 0.027778f }, // 54 (3 6 7) - { 4.750000f, 7.750000f, 1.750000f, 0.029630f }, // 55 (3 7 6) - { 5.000000f, 7.000000f, 2.000000f, 0.032258f }, // 56 (3 8 5) - { 5.250000f, 6.250000f, 2.250000f, 0.036036f }, // 57 (3 9 4) - { 5.500000f, 5.500000f, 2.500000f, 0.041667f }, // 58 (3 10 3) - { 5.750000f, 4.750000f, 2.750000f, 0.050633f }, // 59 (3 11 2) - { 6.000000f, 4.000000f, 3.000000f, 0.066667f }, // 60 (3 12 1) - { 6.250000f, 3.250000f, 3.250000f, 0.102564f }, // 61 (3 13 0) - { 4.000000f, 12.000000f, 0.000000f, 0.020833f }, // 62 (4 0 12) - { 4.250000f, 11.250000f, 0.250000f, 0.020942f }, // 63 (4 1 11) - { 4.500000f, 10.500000f, 0.500000f, 0.021277f }, // 64 (4 2 10) - { 4.750000f, 9.750000f, 0.750000f, 0.021858f }, // 65 (4 3 9) - { 5.000000f, 9.000000f, 1.000000f, 0.022727f }, // 66 (4 4 8) - { 5.250000f, 8.250000f, 1.250000f, 0.023952f }, // 67 (4 5 7) - { 5.500000f, 7.500000f, 1.500000f, 0.025641f }, // 68 (4 6 6) - { 5.750000f, 6.750000f, 1.750000f, 0.027972f }, // 69 (4 7 5) - { 6.000000f, 6.000000f, 2.000000f, 0.031250f }, // 70 (4 8 4) - { 6.250000f, 5.250000f, 2.250000f, 0.036036f }, // 71 (4 9 3) - { 6.500000f, 4.500000f, 2.500000f, 0.043478f }, // 72 (4 10 2) - { 6.750000f, 3.750000f, 2.750000f, 0.056338f }, // 73 (4 11 1) - { 7.000000f, 3.000000f, 3.000000f, 0.083333f }, // 74 (4 12 0) - { 5.000000f, 11.000000f, 0.000000f, 0.018182f }, // 75 (5 0 11) - { 5.250000f, 10.250000f, 0.250000f, 0.018605f }, // 76 (5 1 10) - { 5.500000f, 9.500000f, 0.500000f, 0.019231f }, // 77 (5 2 9) - { 5.750000f, 8.750000f, 0.750000f, 0.020101f }, // 78 (5 3 8) - { 6.000000f, 8.000000f, 1.000000f, 0.021277f }, // 79 (5 4 7) - { 6.250000f, 7.250000f, 1.250000f, 0.022857f }, // 80 (5 5 6) - { 6.500000f, 6.500000f, 1.500000f, 0.025000f }, // 81 (5 6 5) - { 6.750000f, 5.750000f, 1.750000f, 0.027972f }, // 82 (5 7 4) - { 7.000000f, 5.000000f, 2.000000f, 0.032258f }, // 83 (5 8 3) - { 7.250000f, 4.250000f, 2.250000f, 0.038835f }, // 84 (5 9 2) - { 7.500000f, 3.500000f, 2.500000f, 0.050000f }, // 85 (5 10 1) - { 7.750000f, 2.750000f, 2.750000f, 0.072727f }, // 86 (5 11 0) - { 6.000000f, 10.000000f, 0.000000f, 0.016667f }, // 87 (6 0 10) - { 6.250000f, 9.250000f, 0.250000f, 0.017316f }, // 88 (6 1 9) - { 6.500000f, 8.500000f, 0.500000f, 0.018182f }, // 89 (6 2 8) - { 6.750000f, 7.750000f, 0.750000f, 0.019324f }, // 90 (6 3 7) - { 7.000000f, 7.000000f, 1.000000f, 0.020833f }, // 91 (6 4 6) - { 7.250000f, 6.250000f, 1.250000f, 0.022857f }, // 92 (6 5 5) - { 7.500000f, 5.500000f, 1.500000f, 0.025641f }, // 93 (6 6 4) - { 7.750000f, 4.750000f, 1.750000f, 0.029630f }, // 94 (6 7 3) - { 8.000000f, 4.000000f, 2.000000f, 0.035714f }, // 95 (6 8 2) - { 8.250000f, 3.250000f, 2.250000f, 0.045977f }, // 96 (6 9 1) - { 8.500000f, 2.500000f, 2.500000f, 0.066667f }, // 97 (6 10 0) - { 7.000000f, 9.000000f, 0.000000f, 0.015873f }, // 98 (7 0 9) - { 7.250000f, 8.250000f, 0.250000f, 0.016736f }, // 99 (7 1 8) - { 7.500000f, 7.500000f, 0.500000f, 0.017857f }, // 100 (7 2 7) - { 7.750000f, 6.750000f, 0.750000f, 0.019324f }, // 101 (7 3 6) - { 8.000000f, 6.000000f, 1.000000f, 0.021277f }, // 102 (7 4 5) - { 8.250000f, 5.250000f, 1.250000f, 0.023952f }, // 103 (7 5 4) - { 8.500000f, 4.500000f, 1.500000f, 0.027778f }, // 104 (7 6 3) - { 8.750000f, 3.750000f, 1.750000f, 0.033613f }, // 105 (7 7 2) - { 9.000000f, 3.000000f, 2.000000f, 0.043478f }, // 106 (7 8 1) - { 9.250000f, 2.250000f, 2.250000f, 0.063492f }, // 107 (7 9 0) - { 8.000000f, 8.000000f, 0.000000f, 0.015625f }, // 108 (8 0 8) - { 8.250000f, 7.250000f, 0.250000f, 0.016736f }, // 109 (8 1 7) - { 8.500000f, 6.500000f, 0.500000f, 0.018182f }, // 110 (8 2 6) - { 8.750000f, 5.750000f, 0.750000f, 0.020101f }, // 111 (8 3 5) - { 9.000000f, 5.000000f, 1.000000f, 0.022727f }, // 112 (8 4 4) - { 9.250000f, 4.250000f, 1.250000f, 0.026490f }, // 113 (8 5 3) - { 9.500000f, 3.500000f, 1.500000f, 0.032258f }, // 114 (8 6 2) - { 9.750000f, 2.750000f, 1.750000f, 0.042105f }, // 115 (8 7 1) - { 10.000000f, 2.000000f, 2.000000f, 0.062500f }, // 116 (8 8 0) - { 9.000000f, 7.000000f, 0.000000f, 0.015873f }, // 117 (9 0 7) - { 9.250000f, 6.250000f, 0.250000f, 0.017316f }, // 118 (9 1 6) - { 9.500000f, 5.500000f, 0.500000f, 0.019231f }, // 119 (9 2 5) - { 9.750000f, 4.750000f, 0.750000f, 0.021858f }, // 120 (9 3 4) - { 10.000000f, 4.000000f, 1.000000f, 0.025641f }, // 121 (9 4 3) - { 10.250000f, 3.250000f, 1.250000f, 0.031496f }, // 122 (9 5 2) - { 10.500000f, 2.500000f, 1.500000f, 0.041667f }, // 123 (9 6 1) - { 10.750000f, 1.750000f, 1.750000f, 0.063492f }, // 124 (9 7 0) - { 10.000000f, 6.000000f, 0.000000f, 0.016667f }, // 125 (10 0 6) - { 10.250000f, 5.250000f, 0.250000f, 0.018605f }, // 126 (10 1 5) - { 10.500000f, 4.500000f, 0.500000f, 0.021277f }, // 127 (10 2 4) - { 10.750000f, 3.750000f, 0.750000f, 0.025157f }, // 128 (10 3 3) - { 11.000000f, 3.000000f, 1.000000f, 0.031250f }, // 129 (10 4 2) - { 11.250000f, 2.250000f, 1.250000f, 0.042105f }, // 130 (10 5 1) - { 11.500000f, 1.500000f, 1.500000f, 0.066667f }, // 131 (10 6 0) - { 11.000000f, 5.000000f, 0.000000f, 0.018182f }, // 132 (11 0 5) - { 11.250000f, 4.250000f, 0.250000f, 0.020942f }, // 133 (11 1 4) - { 11.500000f, 3.500000f, 0.500000f, 0.025000f }, // 134 (11 2 3) - { 11.750000f, 2.750000f, 0.750000f, 0.031496f }, // 135 (11 3 2) - { 12.000000f, 2.000000f, 1.000000f, 0.043478f }, // 136 (11 4 1) - { 12.250000f, 1.250000f, 1.250000f, 0.072727f }, // 137 (11 5 0) - { 12.000000f, 4.000000f, 0.000000f, 0.020833f }, // 138 (12 0 4) - { 12.250000f, 3.250000f, 0.250000f, 0.025157f }, // 139 (12 1 3) - { 12.500000f, 2.500000f, 0.500000f, 0.032258f }, // 140 (12 2 2) - { 12.750000f, 1.750000f, 0.750000f, 0.045977f }, // 141 (12 3 1) - { 13.000000f, 1.000000f, 1.000000f, 0.083333f }, // 142 (12 4 0) - { 13.000000f, 3.000000f, 0.000000f, 0.025641f }, // 143 (13 0 3) - { 13.250000f, 2.250000f, 0.250000f, 0.033613f }, // 144 (13 1 2) - { 13.500000f, 1.500000f, 0.500000f, 0.050000f }, // 145 (13 2 1) - { 13.750000f, 0.750000f, 0.750000f, 0.102564f }, // 146 (13 3 0) - { 14.000000f, 2.000000f, 0.000000f, 0.035714f }, // 147 (14 0 2) - { 14.250000f, 1.250000f, 0.250000f, 0.056338f }, // 148 (14 1 1) - { 14.500000f, 0.500000f, 0.500000f, 0.142857f }, // 149 (14 2 0) - { 15.000000f, 1.000000f, 0.000000f, 0.066667f }, // 150 (15 0 1) - { 15.250000f, 0.250000f, 0.250000f, 0.266667f }, // 151 (15 1 0) - { 16.000000f, 0.000000f, 0.000000f, FLT_MAX }, // 152 (16 0 0) -}; // 153 three cluster elements - -static const SQUISH_ALIGN_16 Precomp s_fourElement[969] = { - { 0.000000f, 16.000000f, 0.000000f, FLT_MAX }, // 0 (0 0 0 16) - { 0.111111f, 15.444445f, 0.222222f, 0.600000f }, // 1 (0 0 1 15) - { 0.222222f, 14.888889f, 0.444444f, 0.321429f }, // 2 (0 0 2 14) - { 0.333333f, 14.333333f, 0.666667f, 0.230769f }, // 3 (0 0 3 13) - { 0.444444f, 13.777778f, 0.888889f, 0.187500f }, // 4 (0 0 4 12) - { 0.555556f, 13.222222f, 1.111111f, 0.163636f }, // 5 (0 0 5 11) - { 0.666667f, 12.666667f, 1.333333f, 0.150000f }, // 6 (0 0 6 10) - { 0.777778f, 12.111111f, 1.555556f, 0.142857f }, // 7 (0 0 7 9) - { 0.888889f, 11.555555f, 1.777778f, 0.140625f }, // 8 (0 0 8 8) - { 1.000000f, 11.000000f, 2.000000f, 0.142857f }, // 9 (0 0 9 7) - { 1.111111f, 10.444445f, 2.222222f, 0.150000f }, // 10 (0 0 10 6) - { 1.222222f, 9.888889f, 2.444444f, 0.163636f }, // 11 (0 0 11 5) - { 1.333333f, 9.333333f, 2.666667f, 0.187500f }, // 12 (0 0 12 4) - { 1.444444f, 8.777778f, 2.888889f, 0.230769f }, // 13 (0 0 13 3) - { 1.555556f, 8.222222f, 3.111111f, 0.321429f }, // 14 (0 0 14 2) - { 1.666667f, 7.666667f, 3.333333f, 0.600000f }, // 15 (0 0 15 1) - { 1.777778f, 7.111111f, 3.555556f, FLT_MAX }, // 16 (0 0 16 0) - { 0.444444f, 15.111111f, 0.222222f, 0.150000f }, // 17 (0 1 0 15) - { 0.555556f, 14.555555f, 0.444444f, 0.126761f }, // 18 (0 1 1 14) - { 0.666667f, 14.000000f, 0.666667f, 0.112500f }, // 19 (0 1 2 13) - { 0.777778f, 13.444445f, 0.888889f, 0.103448f }, // 20 (0 1 3 12) - { 0.888889f, 12.888889f, 1.111111f, 0.097826f }, // 21 (0 1 4 11) - { 1.000000f, 12.333333f, 1.333333f, 0.094737f }, // 22 (0 1 5 10) - { 1.111111f, 11.777778f, 1.555556f, 0.093750f }, // 23 (0 1 6 9) - { 1.222222f, 11.222222f, 1.777778f, 0.094737f }, // 24 (0 1 7 8) - { 1.333333f, 10.666667f, 2.000000f, 0.097826f }, // 25 (0 1 8 7) - { 1.444444f, 10.111111f, 2.222222f, 0.103448f }, // 26 (0 1 9 6) - { 1.555556f, 9.555555f, 2.444444f, 0.112500f }, // 27 (0 1 10 5) - { 1.666667f, 9.000000f, 2.666667f, 0.126761f }, // 28 (0 1 11 4) - { 1.777778f, 8.444445f, 2.888889f, 0.150000f }, // 29 (0 1 12 3) - { 1.888889f, 7.888889f, 3.111111f, 0.191489f }, // 30 (0 1 13 2) - { 2.000000f, 7.333333f, 3.333333f, 0.281250f }, // 31 (0 1 14 1) - { 2.111111f, 6.777778f, 3.555556f, 0.600000f }, // 32 (0 1 15 0) - { 0.888889f, 14.222222f, 0.444444f, 0.080357f }, // 33 (0 2 0 14) - { 1.000000f, 13.666667f, 0.666667f, 0.075630f }, // 34 (0 2 1 13) - { 1.111111f, 13.111111f, 0.888889f, 0.072581f }, // 35 (0 2 2 12) - { 1.222222f, 12.555555f, 1.111111f, 0.070866f }, // 36 (0 2 3 11) - { 1.333333f, 12.000000f, 1.333333f, 0.070313f }, // 37 (0 2 4 10) - { 1.444444f, 11.444445f, 1.555556f, 0.070866f }, // 38 (0 2 5 9) - { 1.555556f, 10.888889f, 1.777778f, 0.072581f }, // 39 (0 2 6 8) - { 1.666667f, 10.333333f, 2.000000f, 0.075630f }, // 40 (0 2 7 7) - { 1.777778f, 9.777778f, 2.222222f, 0.080357f }, // 41 (0 2 8 6) - { 1.888889f, 9.222222f, 2.444444f, 0.087379f }, // 42 (0 2 9 5) - { 2.000000f, 8.666667f, 2.666667f, 0.097826f }, // 43 (0 2 10 4) - { 2.111111f, 8.111111f, 2.888889f, 0.113924f }, // 44 (0 2 11 3) - { 2.222222f, 7.555556f, 3.111111f, 0.140625f }, // 45 (0 2 12 2) - { 2.333333f, 7.000000f, 3.333333f, 0.191489f }, // 46 (0 2 13 1) - { 2.444444f, 6.444445f, 3.555556f, 0.321429f }, // 47 (0 2 14 0) - { 1.333333f, 13.333333f, 0.666667f, 0.057692f }, // 48 (0 3 0 13) - { 1.444444f, 12.777778f, 0.888889f, 0.056604f }, // 49 (0 3 1 12) - { 1.555556f, 12.222222f, 1.111111f, 0.056250f }, // 50 (0 3 2 11) - { 1.666667f, 11.666667f, 1.333333f, 0.056604f }, // 51 (0 3 3 10) - { 1.777778f, 11.111111f, 1.555556f, 0.057692f }, // 52 (0 3 4 9) - { 1.888889f, 10.555555f, 1.777778f, 0.059603f }, // 53 (0 3 5 8) - { 2.000000f, 10.000000f, 2.000000f, 0.062500f }, // 54 (0 3 6 7) - { 2.111111f, 9.444445f, 2.222222f, 0.066667f }, // 55 (0 3 7 6) - { 2.222222f, 8.888889f, 2.444444f, 0.072581f }, // 56 (0 3 8 5) - { 2.333333f, 8.333333f, 2.666667f, 0.081081f }, // 57 (0 3 9 4) - { 2.444444f, 7.777778f, 2.888889f, 0.093750f }, // 58 (0 3 10 3) - { 2.555556f, 7.222222f, 3.111111f, 0.113924f }, // 59 (0 3 11 2) - { 2.666667f, 6.666667f, 3.333333f, 0.150000f }, // 60 (0 3 12 1) - { 2.777778f, 6.111111f, 3.555556f, 0.230769f }, // 61 (0 3 13 0) - { 1.777778f, 12.444445f, 0.888889f, 0.046875f }, // 62 (0 4 0 12) - { 1.888889f, 11.888889f, 1.111111f, 0.047120f }, // 63 (0 4 1 11) - { 2.000000f, 11.333333f, 1.333333f, 0.047872f }, // 64 (0 4 2 10) - { 2.111111f, 10.777778f, 1.555556f, 0.049180f }, // 65 (0 4 3 9) - { 2.222222f, 10.222222f, 1.777778f, 0.051136f }, // 66 (0 4 4 8) - { 2.333333f, 9.666667f, 2.000000f, 0.053892f }, // 67 (0 4 5 7) - { 2.444444f, 9.111111f, 2.222222f, 0.057692f }, // 68 (0 4 6 6) - { 2.555556f, 8.555555f, 2.444444f, 0.062937f }, // 69 (0 4 7 5) - { 2.666667f, 8.000000f, 2.666667f, 0.070313f }, // 70 (0 4 8 4) - { 2.777778f, 7.444445f, 2.888889f, 0.081081f }, // 71 (0 4 9 3) - { 2.888889f, 6.888889f, 3.111111f, 0.097826f }, // 72 (0 4 10 2) - { 3.000000f, 6.333333f, 3.333333f, 0.126761f }, // 73 (0 4 11 1) - { 3.111111f, 5.777778f, 3.555556f, 0.187500f }, // 74 (0 4 12 0) - { 2.222222f, 11.555555f, 1.111111f, 0.040909f }, // 75 (0 5 0 11) - { 2.333333f, 11.000000f, 1.333333f, 0.041860f }, // 76 (0 5 1 10) - { 2.444444f, 10.444445f, 1.555556f, 0.043269f }, // 77 (0 5 2 9) - { 2.555556f, 9.888889f, 1.777778f, 0.045226f }, // 78 (0 5 3 8) - { 2.666667f, 9.333333f, 2.000000f, 0.047872f }, // 79 (0 5 4 7) - { 2.777778f, 8.777778f, 2.222222f, 0.051429f }, // 80 (0 5 5 6) - { 2.888889f, 8.222222f, 2.444444f, 0.056250f }, // 81 (0 5 6 5) - { 3.000000f, 7.666667f, 2.666667f, 0.062937f }, // 82 (0 5 7 4) - { 3.111111f, 7.111111f, 2.888889f, 0.072581f }, // 83 (0 5 8 3) - { 3.222222f, 6.555556f, 3.111111f, 0.087379f }, // 84 (0 5 9 2) - { 3.333333f, 6.000000f, 3.333333f, 0.112500f }, // 85 (0 5 10 1) - { 3.444444f, 5.444445f, 3.555556f, 0.163636f }, // 86 (0 5 11 0) - { 2.666667f, 10.666667f, 1.333333f, 0.037500f }, // 87 (0 6 0 10) - { 2.777778f, 10.111111f, 1.555556f, 0.038961f }, // 88 (0 6 1 9) - { 2.888889f, 9.555555f, 1.777778f, 0.040909f }, // 89 (0 6 2 8) - { 3.000000f, 9.000000f, 2.000000f, 0.043478f }, // 90 (0 6 3 7) - { 3.111111f, 8.444445f, 2.222222f, 0.046875f }, // 91 (0 6 4 6) - { 3.222222f, 7.888889f, 2.444444f, 0.051429f }, // 92 (0 6 5 5) - { 3.333333f, 7.333333f, 2.666667f, 0.057692f }, // 93 (0 6 6 4) - { 3.444444f, 6.777778f, 2.888889f, 0.066667f }, // 94 (0 6 7 3) - { 3.555556f, 6.222222f, 3.111111f, 0.080357f }, // 95 (0 6 8 2) - { 3.666667f, 5.666667f, 3.333333f, 0.103448f }, // 96 (0 6 9 1) - { 3.777778f, 5.111111f, 3.555556f, 0.150000f }, // 97 (0 6 10 0) - { 3.111111f, 9.777778f, 1.555556f, 0.035714f }, // 98 (0 7 0 9) - { 3.222222f, 9.222222f, 1.777778f, 0.037657f }, // 99 (0 7 1 8) - { 3.333333f, 8.666667f, 2.000000f, 0.040179f }, // 100 (0 7 2 7) - { 3.444444f, 8.111111f, 2.222222f, 0.043478f }, // 101 (0 7 3 6) - { 3.555556f, 7.555555f, 2.444444f, 0.047872f }, // 102 (0 7 4 5) - { 3.666667f, 7.000000f, 2.666667f, 0.053892f }, // 103 (0 7 5 4) - { 3.777778f, 6.444445f, 2.888889f, 0.062500f }, // 104 (0 7 6 3) - { 3.888889f, 5.888889f, 3.111111f, 0.075630f }, // 105 (0 7 7 2) - { 4.000000f, 5.333333f, 3.333333f, 0.097826f }, // 106 (0 7 8 1) - { 4.111111f, 4.777778f, 3.555556f, 0.142857f }, // 107 (0 7 9 0) - { 3.555556f, 8.888889f, 1.777778f, 0.035156f }, // 108 (0 8 0 8) - { 3.666667f, 8.333333f, 2.000000f, 0.037657f }, // 109 (0 8 1 7) - { 3.777778f, 7.777778f, 2.222222f, 0.040909f }, // 110 (0 8 2 6) - { 3.888889f, 7.222222f, 2.444444f, 0.045226f }, // 111 (0 8 3 5) - { 4.000000f, 6.666667f, 2.666667f, 0.051136f }, // 112 (0 8 4 4) - { 4.111111f, 6.111111f, 2.888889f, 0.059603f }, // 113 (0 8 5 3) - { 4.222222f, 5.555555f, 3.111111f, 0.072581f }, // 114 (0 8 6 2) - { 4.333333f, 5.000000f, 3.333333f, 0.094737f }, // 115 (0 8 7 1) - { 4.444445f, 4.444445f, 3.555556f, 0.140625f }, // 116 (0 8 8 0) - { 4.000000f, 8.000000f, 2.000000f, 0.035714f }, // 117 (0 9 0 7) - { 4.111111f, 7.444445f, 2.222222f, 0.038961f }, // 118 (0 9 1 6) - { 4.222222f, 6.888889f, 2.444444f, 0.043269f }, // 119 (0 9 2 5) - { 4.333333f, 6.333333f, 2.666667f, 0.049180f }, // 120 (0 9 3 4) - { 4.444445f, 5.777778f, 2.888889f, 0.057692f }, // 121 (0 9 4 3) - { 4.555556f, 5.222222f, 3.111111f, 0.070866f }, // 122 (0 9 5 2) - { 4.666667f, 4.666667f, 3.333333f, 0.093750f }, // 123 (0 9 6 1) - { 4.777778f, 4.111111f, 3.555556f, 0.142857f }, // 124 (0 9 7 0) - { 4.444445f, 7.111111f, 2.222222f, 0.037500f }, // 125 (0 10 0 6) - { 4.555556f, 6.555555f, 2.444444f, 0.041860f }, // 126 (0 10 1 5) - { 4.666667f, 6.000000f, 2.666667f, 0.047872f }, // 127 (0 10 2 4) - { 4.777778f, 5.444445f, 2.888889f, 0.056604f }, // 128 (0 10 3 3) - { 4.888889f, 4.888889f, 3.111111f, 0.070313f }, // 129 (0 10 4 2) - { 5.000000f, 4.333333f, 3.333333f, 0.094737f }, // 130 (0 10 5 1) - { 5.111111f, 3.777778f, 3.555556f, 0.150000f }, // 131 (0 10 6 0) - { 4.888889f, 6.222222f, 2.444444f, 0.040909f }, // 132 (0 11 0 5) - { 5.000000f, 5.666667f, 2.666667f, 0.047120f }, // 133 (0 11 1 4) - { 5.111111f, 5.111111f, 2.888889f, 0.056250f }, // 134 (0 11 2 3) - { 5.222222f, 4.555555f, 3.111111f, 0.070866f }, // 135 (0 11 3 2) - { 5.333333f, 4.000000f, 3.333333f, 0.097826f }, // 136 (0 11 4 1) - { 5.444445f, 3.444444f, 3.555556f, 0.163636f }, // 137 (0 11 5 0) - { 5.333333f, 5.333333f, 2.666667f, 0.046875f }, // 138 (0 12 0 4) - { 5.444445f, 4.777778f, 2.888889f, 0.056604f }, // 139 (0 12 1 3) - { 5.555556f, 4.222222f, 3.111111f, 0.072581f }, // 140 (0 12 2 2) - { 5.666667f, 3.666667f, 3.333333f, 0.103448f }, // 141 (0 12 3 1) - { 5.777778f, 3.111111f, 3.555556f, 0.187500f }, // 142 (0 12 4 0) - { 5.777778f, 4.444445f, 2.888889f, 0.057692f }, // 143 (0 13 0 3) - { 5.888889f, 3.888889f, 3.111111f, 0.075630f }, // 144 (0 13 1 2) - { 6.000000f, 3.333333f, 3.333333f, 0.112500f }, // 145 (0 13 2 1) - { 6.111111f, 2.777778f, 3.555556f, 0.230769f }, // 146 (0 13 3 0) - { 6.222222f, 3.555556f, 3.111111f, 0.080357f }, // 147 (0 14 0 2) - { 6.333333f, 3.000000f, 3.333333f, 0.126761f }, // 148 (0 14 1 1) - { 6.444445f, 2.444444f, 3.555556f, 0.321429f }, // 149 (0 14 2 0) - { 6.666667f, 2.666667f, 3.333333f, 0.150000f }, // 150 (0 15 0 1) - { 6.777778f, 2.111111f, 3.555556f, 0.600000f }, // 151 (0 15 1 0) - { 7.111111f, 1.777778f, 3.555556f, FLT_MAX }, // 152 (0 16 0 0) - { 1.000000f, 15.000000f, 0.000000f, 0.066667f }, // 153 (1 0 0 15) - { 1.111111f, 14.444445f, 0.222222f, 0.062500f }, // 154 (1 0 1 14) - { 1.222222f, 13.888889f, 0.444444f, 0.059603f }, // 155 (1 0 2 13) - { 1.333333f, 13.333333f, 0.666667f, 0.057692f }, // 156 (1 0 3 12) - { 1.444444f, 12.777778f, 0.888889f, 0.056604f }, // 157 (1 0 4 11) - { 1.555556f, 12.222222f, 1.111111f, 0.056250f }, // 158 (1 0 5 10) - { 1.666667f, 11.666667f, 1.333333f, 0.056604f }, // 159 (1 0 6 9) - { 1.777778f, 11.111111f, 1.555556f, 0.057692f }, // 160 (1 0 7 8) - { 1.888889f, 10.555555f, 1.777778f, 0.059603f }, // 161 (1 0 8 7) - { 2.000000f, 10.000000f, 2.000000f, 0.062500f }, // 162 (1 0 9 6) - { 2.111111f, 9.444445f, 2.222222f, 0.066667f }, // 163 (1 0 10 5) - { 2.222222f, 8.888889f, 2.444444f, 0.072581f }, // 164 (1 0 11 4) - { 2.333333f, 8.333333f, 2.666667f, 0.081081f }, // 165 (1 0 12 3) - { 2.444444f, 7.777778f, 2.888889f, 0.093750f }, // 166 (1 0 13 2) - { 2.555556f, 7.222222f, 3.111111f, 0.113924f }, // 167 (1 0 14 1) - { 2.666667f, 6.666667f, 3.333333f, 0.150000f }, // 168 (1 0 15 0) - { 1.444444f, 14.111111f, 0.222222f, 0.049180f }, // 169 (1 1 0 14) - { 1.555556f, 13.555555f, 0.444444f, 0.047872f }, // 170 (1 1 1 13) - { 1.666667f, 13.000000f, 0.666667f, 0.047120f }, // 171 (1 1 2 12) - { 1.777778f, 12.444445f, 0.888889f, 0.046875f }, // 172 (1 1 3 11) - { 1.888889f, 11.888889f, 1.111111f, 0.047120f }, // 173 (1 1 4 10) - { 2.000000f, 11.333333f, 1.333333f, 0.047872f }, // 174 (1 1 5 9) - { 2.111111f, 10.777778f, 1.555556f, 0.049180f }, // 175 (1 1 6 8) - { 2.222222f, 10.222222f, 1.777778f, 0.051136f }, // 176 (1 1 7 7) - { 2.333333f, 9.666667f, 2.000000f, 0.053892f }, // 177 (1 1 8 6) - { 2.444444f, 9.111111f, 2.222222f, 0.057692f }, // 178 (1 1 9 5) - { 2.555556f, 8.555555f, 2.444444f, 0.062937f }, // 179 (1 1 10 4) - { 2.666667f, 8.000000f, 2.666667f, 0.070313f }, // 180 (1 1 11 3) - { 2.777778f, 7.444445f, 2.888889f, 0.081081f }, // 181 (1 1 12 2) - { 2.888889f, 6.888889f, 3.111111f, 0.097826f }, // 182 (1 1 13 1) - { 3.000000f, 6.333333f, 3.333333f, 0.126761f }, // 183 (1 1 14 0) - { 1.888889f, 13.222222f, 0.444444f, 0.040359f }, // 184 (1 2 0 13) - { 2.000000f, 12.666667f, 0.666667f, 0.040179f }, // 185 (1 2 1 12) - { 2.111111f, 12.111111f, 0.888889f, 0.040359f }, // 186 (1 2 2 11) - { 2.222222f, 11.555555f, 1.111111f, 0.040909f }, // 187 (1 2 3 10) - { 2.333333f, 11.000000f, 1.333333f, 0.041860f }, // 188 (1 2 4 9) - { 2.444444f, 10.444445f, 1.555556f, 0.043269f }, // 189 (1 2 5 8) - { 2.555556f, 9.888889f, 1.777778f, 0.045226f }, // 190 (1 2 6 7) - { 2.666667f, 9.333333f, 2.000000f, 0.047872f }, // 191 (1 2 7 6) - { 2.777778f, 8.777778f, 2.222222f, 0.051429f }, // 192 (1 2 8 5) - { 2.888889f, 8.222222f, 2.444444f, 0.056250f }, // 193 (1 2 9 4) - { 3.000000f, 7.666667f, 2.666667f, 0.062937f }, // 194 (1 2 10 3) - { 3.111111f, 7.111111f, 2.888889f, 0.072581f }, // 195 (1 2 11 2) - { 3.222222f, 6.555556f, 3.111111f, 0.087379f }, // 196 (1 2 12 1) - { 3.333333f, 6.000000f, 3.333333f, 0.112500f }, // 197 (1 2 13 0) - { 2.333333f, 12.333333f, 0.666667f, 0.035294f }, // 198 (1 3 0 12) - { 2.444444f, 11.777778f, 0.888889f, 0.035714f }, // 199 (1 3 1 11) - { 2.555556f, 11.222222f, 1.111111f, 0.036437f }, // 200 (1 3 2 10) - { 2.666667f, 10.666667f, 1.333333f, 0.037500f }, // 201 (1 3 3 9) - { 2.777778f, 10.111111f, 1.555556f, 0.038961f }, // 202 (1 3 4 8) - { 2.888889f, 9.555555f, 1.777778f, 0.040909f }, // 203 (1 3 5 7) - { 3.000000f, 9.000000f, 2.000000f, 0.043478f }, // 204 (1 3 6 6) - { 3.111111f, 8.444445f, 2.222222f, 0.046875f }, // 205 (1 3 7 5) - { 3.222222f, 7.888889f, 2.444444f, 0.051429f }, // 206 (1 3 8 4) - { 3.333333f, 7.333333f, 2.666667f, 0.057692f }, // 207 (1 3 9 3) - { 3.444444f, 6.777778f, 2.888889f, 0.066667f }, // 208 (1 3 10 2) - { 3.555556f, 6.222222f, 3.111111f, 0.080357f }, // 209 (1 3 11 1) - { 3.666667f, 5.666667f, 3.333333f, 0.103448f }, // 210 (1 3 12 0) - { 2.777778f, 11.444445f, 0.888889f, 0.032258f }, // 211 (1 4 0 11) - { 2.888889f, 10.888889f, 1.111111f, 0.033088f }, // 212 (1 4 1 10) - { 3.000000f, 10.333333f, 1.333333f, 0.034221f }, // 213 (1 4 2 9) - { 3.111111f, 9.777778f, 1.555556f, 0.035714f }, // 214 (1 4 3 8) - { 3.222222f, 9.222222f, 1.777778f, 0.037657f }, // 215 (1 4 4 7) - { 3.333333f, 8.666667f, 2.000000f, 0.040179f }, // 216 (1 4 5 6) - { 3.444444f, 8.111111f, 2.222222f, 0.043478f }, // 217 (1 4 6 5) - { 3.555556f, 7.555555f, 2.444444f, 0.047872f }, // 218 (1 4 7 4) - { 3.666667f, 7.000000f, 2.666667f, 0.053892f }, // 219 (1 4 8 3) - { 3.777778f, 6.444445f, 2.888889f, 0.062500f }, // 220 (1 4 9 2) - { 3.888889f, 5.888889f, 3.111111f, 0.075630f }, // 221 (1 4 10 1) - { 4.000000f, 5.333333f, 3.333333f, 0.097826f }, // 222 (1 4 11 0) - { 3.222222f, 10.555555f, 1.111111f, 0.030508f }, // 223 (1 5 0 10) - { 3.333333f, 10.000000f, 1.333333f, 0.031690f }, // 224 (1 5 1 9) - { 3.444444f, 9.444445f, 1.555556f, 0.033210f }, // 225 (1 5 2 8) - { 3.555556f, 8.888889f, 1.777778f, 0.035156f }, // 226 (1 5 3 7) - { 3.666667f, 8.333333f, 2.000000f, 0.037657f }, // 227 (1 5 4 6) - { 3.777778f, 7.777778f, 2.222222f, 0.040909f }, // 228 (1 5 5 5) - { 3.888889f, 7.222222f, 2.444444f, 0.045226f }, // 229 (1 5 6 4) - { 4.000000f, 6.666667f, 2.666667f, 0.051136f }, // 230 (1 5 7 3) - { 4.111111f, 6.111111f, 2.888889f, 0.059603f }, // 231 (1 5 8 2) - { 4.222222f, 5.555556f, 3.111111f, 0.072581f }, // 232 (1 5 9 1) - { 4.333333f, 5.000000f, 3.333333f, 0.094737f }, // 233 (1 5 10 0) - { 3.666667f, 9.666667f, 1.333333f, 0.029703f }, // 234 (1 6 0 9) - { 3.777778f, 9.111111f, 1.555556f, 0.031250f }, // 235 (1 6 1 8) - { 3.888889f, 8.555555f, 1.777778f, 0.033210f }, // 236 (1 6 2 7) - { 4.000000f, 8.000000f, 2.000000f, 0.035714f }, // 237 (1 6 3 6) - { 4.111111f, 7.444445f, 2.222222f, 0.038961f }, // 238 (1 6 4 5) - { 4.222222f, 6.888889f, 2.444444f, 0.043269f }, // 239 (1 6 5 4) - { 4.333333f, 6.333333f, 2.666667f, 0.049180f }, // 240 (1 6 6 3) - { 4.444445f, 5.777778f, 2.888889f, 0.057692f }, // 241 (1 6 7 2) - { 4.555555f, 5.222222f, 3.111111f, 0.070866f }, // 242 (1 6 8 1) - { 4.666667f, 4.666667f, 3.333333f, 0.093750f }, // 243 (1 6 9 0) - { 4.111111f, 8.777778f, 1.555556f, 0.029703f }, // 244 (1 7 0 8) - { 4.222222f, 8.222222f, 1.777778f, 0.031690f }, // 245 (1 7 1 7) - { 4.333333f, 7.666667f, 2.000000f, 0.034221f }, // 246 (1 7 2 6) - { 4.444445f, 7.111111f, 2.222222f, 0.037500f }, // 247 (1 7 3 5) - { 4.555555f, 6.555555f, 2.444444f, 0.041860f }, // 248 (1 7 4 4) - { 4.666667f, 6.000000f, 2.666667f, 0.047872f }, // 249 (1 7 5 3) - { 4.777778f, 5.444445f, 2.888889f, 0.056604f }, // 250 (1 7 6 2) - { 4.888889f, 4.888889f, 3.111111f, 0.070313f }, // 251 (1 7 7 1) - { 5.000000f, 4.333333f, 3.333333f, 0.094737f }, // 252 (1 7 8 0) - { 4.555555f, 7.888889f, 1.777778f, 0.030508f }, // 253 (1 8 0 7) - { 4.666667f, 7.333333f, 2.000000f, 0.033088f }, // 254 (1 8 1 6) - { 4.777778f, 6.777778f, 2.222222f, 0.036437f }, // 255 (1 8 2 5) - { 4.888889f, 6.222222f, 2.444444f, 0.040909f }, // 256 (1 8 3 4) - { 5.000000f, 5.666667f, 2.666667f, 0.047120f }, // 257 (1 8 4 3) - { 5.111111f, 5.111111f, 2.888889f, 0.056250f }, // 258 (1 8 5 2) - { 5.222222f, 4.555555f, 3.111111f, 0.070866f }, // 259 (1 8 6 1) - { 5.333333f, 4.000000f, 3.333333f, 0.097826f }, // 260 (1 8 7 0) - { 5.000000f, 7.000000f, 2.000000f, 0.032258f }, // 261 (1 9 0 6) - { 5.111111f, 6.444445f, 2.222222f, 0.035714f }, // 262 (1 9 1 5) - { 5.222222f, 5.888889f, 2.444444f, 0.040359f }, // 263 (1 9 2 4) - { 5.333333f, 5.333333f, 2.666667f, 0.046875f }, // 264 (1 9 3 3) - { 5.444445f, 4.777778f, 2.888889f, 0.056604f }, // 265 (1 9 4 2) - { 5.555556f, 4.222222f, 3.111111f, 0.072581f }, // 266 (1 9 5 1) - { 5.666667f, 3.666667f, 3.333333f, 0.103448f }, // 267 (1 9 6 0) - { 5.444445f, 6.111111f, 2.222222f, 0.035294f }, // 268 (1 10 0 5) - { 5.555556f, 5.555555f, 2.444444f, 0.040179f }, // 269 (1 10 1 4) - { 5.666667f, 5.000000f, 2.666667f, 0.047120f }, // 270 (1 10 2 3) - { 5.777778f, 4.444445f, 2.888889f, 0.057692f }, // 271 (1 10 3 2) - { 5.888889f, 3.888889f, 3.111111f, 0.075630f }, // 272 (1 10 4 1) - { 6.000000f, 3.333333f, 3.333333f, 0.112500f }, // 273 (1 10 5 0) - { 5.888889f, 5.222222f, 2.444444f, 0.040359f }, // 274 (1 11 0 4) - { 6.000000f, 4.666667f, 2.666667f, 0.047872f }, // 275 (1 11 1 3) - { 6.111111f, 4.111111f, 2.888889f, 0.059603f }, // 276 (1 11 2 2) - { 6.222222f, 3.555556f, 3.111111f, 0.080357f }, // 277 (1 11 3 1) - { 6.333333f, 3.000000f, 3.333333f, 0.126761f }, // 278 (1 11 4 0) - { 6.333333f, 4.333333f, 2.666667f, 0.049180f }, // 279 (1 12 0 3) - { 6.444445f, 3.777778f, 2.888889f, 0.062500f }, // 280 (1 12 1 2) - { 6.555556f, 3.222222f, 3.111111f, 0.087379f }, // 281 (1 12 2 1) - { 6.666667f, 2.666667f, 3.333333f, 0.150000f }, // 282 (1 12 3 0) - { 6.777778f, 3.444444f, 2.888889f, 0.066667f }, // 283 (1 13 0 2) - { 6.888889f, 2.888889f, 3.111111f, 0.097826f }, // 284 (1 13 1 1) - { 7.000000f, 2.333333f, 3.333333f, 0.191489f }, // 285 (1 13 2 0) - { 7.222222f, 2.555556f, 3.111111f, 0.113924f }, // 286 (1 14 0 1) - { 7.333333f, 2.000000f, 3.333333f, 0.281250f }, // 287 (1 14 1 0) - { 7.666667f, 1.666667f, 3.333333f, 0.600000f }, // 288 (1 15 0 0) - { 2.000000f, 14.000000f, 0.000000f, 0.035714f }, // 289 (2 0 0 14) - { 2.111111f, 13.444445f, 0.222222f, 0.035294f }, // 290 (2 0 1 13) - { 2.222222f, 12.888889f, 0.444444f, 0.035156f }, // 291 (2 0 2 12) - { 2.333333f, 12.333333f, 0.666667f, 0.035294f }, // 292 (2 0 3 11) - { 2.444444f, 11.777778f, 0.888889f, 0.035714f }, // 293 (2 0 4 10) - { 2.555556f, 11.222222f, 1.111111f, 0.036437f }, // 294 (2 0 5 9) - { 2.666667f, 10.666667f, 1.333333f, 0.037500f }, // 295 (2 0 6 8) - { 2.777778f, 10.111111f, 1.555556f, 0.038961f }, // 296 (2 0 7 7) - { 2.888889f, 9.555555f, 1.777778f, 0.040909f }, // 297 (2 0 8 6) - { 3.000000f, 9.000000f, 2.000000f, 0.043478f }, // 298 (2 0 9 5) - { 3.111111f, 8.444445f, 2.222222f, 0.046875f }, // 299 (2 0 10 4) - { 3.222222f, 7.888889f, 2.444444f, 0.051429f }, // 300 (2 0 11 3) - { 3.333333f, 7.333333f, 2.666667f, 0.057692f }, // 301 (2 0 12 2) - { 3.444444f, 6.777778f, 2.888889f, 0.066667f }, // 302 (2 0 13 1) - { 3.555556f, 6.222222f, 3.111111f, 0.080357f }, // 303 (2 0 14 0) - { 2.444444f, 13.111111f, 0.222222f, 0.031250f }, // 304 (2 1 0 13) - { 2.555556f, 12.555555f, 0.444444f, 0.031359f }, // 305 (2 1 1 12) - { 2.666667f, 12.000000f, 0.666667f, 0.031690f }, // 306 (2 1 2 11) - { 2.777778f, 11.444445f, 0.888889f, 0.032258f }, // 307 (2 1 3 10) - { 2.888889f, 10.888889f, 1.111111f, 0.033088f }, // 308 (2 1 4 9) - { 3.000000f, 10.333333f, 1.333333f, 0.034221f }, // 309 (2 1 5 8) - { 3.111111f, 9.777778f, 1.555556f, 0.035714f }, // 310 (2 1 6 7) - { 3.222222f, 9.222222f, 1.777778f, 0.037657f }, // 311 (2 1 7 6) - { 3.333333f, 8.666667f, 2.000000f, 0.040179f }, // 312 (2 1 8 5) - { 3.444444f, 8.111111f, 2.222222f, 0.043478f }, // 313 (2 1 9 4) - { 3.555556f, 7.555556f, 2.444444f, 0.047872f }, // 314 (2 1 10 3) - { 3.666667f, 7.000000f, 2.666667f, 0.053892f }, // 315 (2 1 11 2) - { 3.777778f, 6.444445f, 2.888889f, 0.062500f }, // 316 (2 1 12 1) - { 3.888889f, 5.888889f, 3.111111f, 0.075630f }, // 317 (2 1 13 0) - { 2.888889f, 12.222222f, 0.444444f, 0.028481f }, // 318 (2 2 0 12) - { 3.000000f, 11.666667f, 0.666667f, 0.028939f }, // 319 (2 2 1 11) - { 3.111111f, 11.111111f, 0.888889f, 0.029605f }, // 320 (2 2 2 10) - { 3.222222f, 10.555555f, 1.111111f, 0.030508f }, // 321 (2 2 3 9) - { 3.333333f, 10.000000f, 1.333333f, 0.031690f }, // 322 (2 2 4 8) - { 3.444444f, 9.444445f, 1.555556f, 0.033210f }, // 323 (2 2 5 7) - { 3.555556f, 8.888889f, 1.777778f, 0.035156f }, // 324 (2 2 6 6) - { 3.666667f, 8.333333f, 2.000000f, 0.037657f }, // 325 (2 2 7 5) - { 3.777778f, 7.777778f, 2.222222f, 0.040909f }, // 326 (2 2 8 4) - { 3.888889f, 7.222222f, 2.444444f, 0.045226f }, // 327 (2 2 9 3) - { 4.000000f, 6.666667f, 2.666667f, 0.051136f }, // 328 (2 2 10 2) - { 4.111111f, 6.111111f, 2.888889f, 0.059603f }, // 329 (2 2 11 1) - { 4.222222f, 5.555556f, 3.111111f, 0.072581f }, // 330 (2 2 12 0) - { 3.333333f, 11.333333f, 0.666667f, 0.026786f }, // 331 (2 3 0 11) - { 3.444444f, 10.777778f, 0.888889f, 0.027523f }, // 332 (2 3 1 10) - { 3.555556f, 10.222222f, 1.111111f, 0.028481f }, // 333 (2 3 2 9) - { 3.666667f, 9.666667f, 1.333333f, 0.029703f }, // 334 (2 3 3 8) - { 3.777778f, 9.111111f, 1.555556f, 0.031250f }, // 335 (2 3 4 7) - { 3.888889f, 8.555555f, 1.777778f, 0.033210f }, // 336 (2 3 5 6) - { 4.000000f, 8.000000f, 2.000000f, 0.035714f }, // 337 (2 3 6 5) - { 4.111111f, 7.444445f, 2.222222f, 0.038961f }, // 338 (2 3 7 4) - { 4.222222f, 6.888889f, 2.444444f, 0.043269f }, // 339 (2 3 8 3) - { 4.333333f, 6.333333f, 2.666667f, 0.049180f }, // 340 (2 3 9 2) - { 4.444445f, 5.777778f, 2.888889f, 0.057692f }, // 341 (2 3 10 1) - { 4.555555f, 5.222222f, 3.111111f, 0.070866f }, // 342 (2 3 11 0) - { 3.777778f, 10.444445f, 0.888889f, 0.025862f }, // 343 (2 4 0 10) - { 3.888889f, 9.888889f, 1.111111f, 0.026866f }, // 344 (2 4 1 9) - { 4.000000f, 9.333333f, 1.333333f, 0.028125f }, // 345 (2 4 2 8) - { 4.111111f, 8.777778f, 1.555556f, 0.029703f }, // 346 (2 4 3 7) - { 4.222222f, 8.222222f, 1.777778f, 0.031690f }, // 347 (2 4 4 6) - { 4.333333f, 7.666667f, 2.000000f, 0.034221f }, // 348 (2 4 5 5) - { 4.444445f, 7.111111f, 2.222222f, 0.037500f }, // 349 (2 4 6 4) - { 4.555555f, 6.555555f, 2.444444f, 0.041860f }, // 350 (2 4 7 3) - { 4.666667f, 6.000000f, 2.666667f, 0.047872f }, // 351 (2 4 8 2) - { 4.777778f, 5.444445f, 2.888889f, 0.056604f }, // 352 (2 4 9 1) - { 4.888889f, 4.888889f, 3.111111f, 0.070313f }, // 353 (2 4 10 0) - { 4.222222f, 9.555555f, 1.111111f, 0.025568f }, // 354 (2 5 0 9) - { 4.333333f, 9.000000f, 1.333333f, 0.026866f }, // 355 (2 5 1 8) - { 4.444445f, 8.444445f, 1.555556f, 0.028481f }, // 356 (2 5 2 7) - { 4.555555f, 7.888889f, 1.777778f, 0.030508f }, // 357 (2 5 3 6) - { 4.666667f, 7.333333f, 2.000000f, 0.033088f }, // 358 (2 5 4 5) - { 4.777778f, 6.777778f, 2.222222f, 0.036437f }, // 359 (2 5 5 4) - { 4.888889f, 6.222222f, 2.444444f, 0.040909f }, // 360 (2 5 6 3) - { 5.000000f, 5.666667f, 2.666667f, 0.047120f }, // 361 (2 5 7 2) - { 5.111111f, 5.111111f, 2.888889f, 0.056250f }, // 362 (2 5 8 1) - { 5.222222f, 4.555556f, 3.111111f, 0.070866f }, // 363 (2 5 9 0) - { 4.666667f, 8.666667f, 1.333333f, 0.025862f }, // 364 (2 6 0 8) - { 4.777778f, 8.111111f, 1.555556f, 0.027523f }, // 365 (2 6 1 7) - { 4.888889f, 7.555555f, 1.777778f, 0.029605f }, // 366 (2 6 2 6) - { 5.000000f, 7.000000f, 2.000000f, 0.032258f }, // 367 (2 6 3 5) - { 5.111111f, 6.444445f, 2.222222f, 0.035714f }, // 368 (2 6 4 4) - { 5.222222f, 5.888889f, 2.444444f, 0.040359f }, // 369 (2 6 5 3) - { 5.333333f, 5.333333f, 2.666667f, 0.046875f }, // 370 (2 6 6 2) - { 5.444445f, 4.777778f, 2.888889f, 0.056604f }, // 371 (2 6 7 1) - { 5.555555f, 4.222222f, 3.111111f, 0.072581f }, // 372 (2 6 8 0) - { 5.111111f, 7.777778f, 1.555556f, 0.026786f }, // 373 (2 7 0 7) - { 5.222222f, 7.222222f, 1.777778f, 0.028939f }, // 374 (2 7 1 6) - { 5.333333f, 6.666667f, 2.000000f, 0.031690f }, // 375 (2 7 2 5) - { 5.444445f, 6.111111f, 2.222222f, 0.035294f }, // 376 (2 7 3 4) - { 5.555555f, 5.555555f, 2.444444f, 0.040179f }, // 377 (2 7 4 3) - { 5.666667f, 5.000000f, 2.666667f, 0.047120f }, // 378 (2 7 5 2) - { 5.777778f, 4.444445f, 2.888889f, 0.057692f }, // 379 (2 7 6 1) - { 5.888889f, 3.888889f, 3.111111f, 0.075630f }, // 380 (2 7 7 0) - { 5.555555f, 6.888889f, 1.777778f, 0.028481f }, // 381 (2 8 0 6) - { 5.666667f, 6.333333f, 2.000000f, 0.031359f }, // 382 (2 8 1 5) - { 5.777778f, 5.777778f, 2.222222f, 0.035156f }, // 383 (2 8 2 4) - { 5.888889f, 5.222222f, 2.444444f, 0.040359f }, // 384 (2 8 3 3) - { 6.000000f, 4.666667f, 2.666667f, 0.047872f }, // 385 (2 8 4 2) - { 6.111111f, 4.111111f, 2.888889f, 0.059603f }, // 386 (2 8 5 1) - { 6.222222f, 3.555556f, 3.111111f, 0.080357f }, // 387 (2 8 6 0) - { 6.000000f, 6.000000f, 2.000000f, 0.031250f }, // 388 (2 9 0 5) - { 6.111111f, 5.444445f, 2.222222f, 0.035294f }, // 389 (2 9 1 4) - { 6.222222f, 4.888889f, 2.444444f, 0.040909f }, // 390 (2 9 2 3) - { 6.333333f, 4.333333f, 2.666667f, 0.049180f }, // 391 (2 9 3 2) - { 6.444445f, 3.777778f, 2.888889f, 0.062500f }, // 392 (2 9 4 1) - { 6.555556f, 3.222222f, 3.111111f, 0.087379f }, // 393 (2 9 5 0) - { 6.444445f, 5.111111f, 2.222222f, 0.035714f }, // 394 (2 10 0 4) - { 6.555556f, 4.555555f, 2.444444f, 0.041860f }, // 395 (2 10 1 3) - { 6.666667f, 4.000000f, 2.666667f, 0.051136f }, // 396 (2 10 2 2) - { 6.777778f, 3.444444f, 2.888889f, 0.066667f }, // 397 (2 10 3 1) - { 6.888889f, 2.888889f, 3.111111f, 0.097826f }, // 398 (2 10 4 0) - { 6.888889f, 4.222222f, 2.444444f, 0.043269f }, // 399 (2 11 0 3) - { 7.000000f, 3.666667f, 2.666667f, 0.053892f }, // 400 (2 11 1 2) - { 7.111111f, 3.111111f, 2.888889f, 0.072581f }, // 401 (2 11 2 1) - { 7.222222f, 2.555556f, 3.111111f, 0.113924f }, // 402 (2 11 3 0) - { 7.333333f, 3.333333f, 2.666667f, 0.057692f }, // 403 (2 12 0 2) - { 7.444445f, 2.777778f, 2.888889f, 0.081081f }, // 404 (2 12 1 1) - { 7.555556f, 2.222222f, 3.111111f, 0.140625f }, // 405 (2 12 2 0) - { 7.777778f, 2.444444f, 2.888889f, 0.093750f }, // 406 (2 13 0 1) - { 7.888889f, 1.888889f, 3.111111f, 0.191489f }, // 407 (2 13 1 0) - { 8.222222f, 1.555556f, 3.111111f, 0.321429f }, // 408 (2 14 0 0) - { 3.000000f, 13.000000f, 0.000000f, 0.025641f }, // 409 (3 0 0 13) - { 3.111111f, 12.444445f, 0.222222f, 0.025862f }, // 410 (3 0 1 12) - { 3.222222f, 11.888889f, 0.444444f, 0.026239f }, // 411 (3 0 2 11) - { 3.333333f, 11.333333f, 0.666667f, 0.026786f }, // 412 (3 0 3 10) - { 3.444444f, 10.777778f, 0.888889f, 0.027523f }, // 413 (3 0 4 9) - { 3.555556f, 10.222222f, 1.111111f, 0.028481f }, // 414 (3 0 5 8) - { 3.666667f, 9.666667f, 1.333333f, 0.029703f }, // 415 (3 0 6 7) - { 3.777778f, 9.111111f, 1.555556f, 0.031250f }, // 416 (3 0 7 6) - { 3.888889f, 8.555555f, 1.777778f, 0.033210f }, // 417 (3 0 8 5) - { 4.000000f, 8.000000f, 2.000000f, 0.035714f }, // 418 (3 0 9 4) - { 4.111111f, 7.444445f, 2.222222f, 0.038961f }, // 419 (3 0 10 3) - { 4.222222f, 6.888889f, 2.444444f, 0.043269f }, // 420 (3 0 11 2) - { 4.333333f, 6.333333f, 2.666667f, 0.049180f }, // 421 (3 0 12 1) - { 4.444445f, 5.777778f, 2.888889f, 0.057692f }, // 422 (3 0 13 0) - { 3.444444f, 12.111111f, 0.222222f, 0.024000f }, // 423 (3 1 0 12) - { 3.555556f, 11.555555f, 0.444444f, 0.024457f }, // 424 (3 1 1 11) - { 3.666667f, 11.000000f, 0.666667f, 0.025070f }, // 425 (3 1 2 10) - { 3.777778f, 10.444445f, 0.888889f, 0.025862f }, // 426 (3 1 3 9) - { 3.888889f, 9.888889f, 1.111111f, 0.026866f }, // 427 (3 1 4 8) - { 4.000000f, 9.333333f, 1.333333f, 0.028125f }, // 428 (3 1 5 7) - { 4.111111f, 8.777778f, 1.555556f, 0.029703f }, // 429 (3 1 6 6) - { 4.222222f, 8.222222f, 1.777778f, 0.031690f }, // 430 (3 1 7 5) - { 4.333333f, 7.666667f, 2.000000f, 0.034221f }, // 431 (3 1 8 4) - { 4.444445f, 7.111111f, 2.222222f, 0.037500f }, // 432 (3 1 9 3) - { 4.555555f, 6.555556f, 2.444444f, 0.041860f }, // 433 (3 1 10 2) - { 4.666667f, 6.000000f, 2.666667f, 0.047872f }, // 434 (3 1 11 1) - { 4.777778f, 5.444445f, 2.888889f, 0.056604f }, // 435 (3 1 12 0) - { 3.888889f, 11.222222f, 0.444444f, 0.023018f }, // 436 (3 2 0 11) - { 4.000000f, 10.666667f, 0.666667f, 0.023684f }, // 437 (3 2 1 10) - { 4.111111f, 10.111111f, 0.888889f, 0.024523f }, // 438 (3 2 2 9) - { 4.222222f, 9.555555f, 1.111111f, 0.025568f }, // 439 (3 2 3 8) - { 4.333333f, 9.000000f, 1.333333f, 0.026866f }, // 440 (3 2 4 7) - { 4.444445f, 8.444445f, 1.555556f, 0.028481f }, // 441 (3 2 5 6) - { 4.555555f, 7.888889f, 1.777778f, 0.030508f }, // 442 (3 2 6 5) - { 4.666667f, 7.333333f, 2.000000f, 0.033088f }, // 443 (3 2 7 4) - { 4.777778f, 6.777778f, 2.222222f, 0.036437f }, // 444 (3 2 8 3) - { 4.888889f, 6.222222f, 2.444444f, 0.040909f }, // 445 (3 2 9 2) - { 5.000000f, 5.666667f, 2.666667f, 0.047120f }, // 446 (3 2 10 1) - { 5.111111f, 5.111111f, 2.888889f, 0.056250f }, // 447 (3 2 11 0) - { 4.333333f, 10.333333f, 0.666667f, 0.022556f }, // 448 (3 3 0 10) - { 4.444445f, 9.777778f, 0.888889f, 0.023438f }, // 449 (3 3 1 9) - { 4.555555f, 9.222222f, 1.111111f, 0.024523f }, // 450 (3 3 2 8) - { 4.666667f, 8.666667f, 1.333333f, 0.025862f }, // 451 (3 3 3 7) - { 4.777778f, 8.111111f, 1.555556f, 0.027523f }, // 452 (3 3 4 6) - { 4.888889f, 7.555555f, 1.777778f, 0.029605f }, // 453 (3 3 5 5) - { 5.000000f, 7.000000f, 2.000000f, 0.032258f }, // 454 (3 3 6 4) - { 5.111111f, 6.444445f, 2.222222f, 0.035714f }, // 455 (3 3 7 3) - { 5.222222f, 5.888889f, 2.444444f, 0.040359f }, // 456 (3 3 8 2) - { 5.333333f, 5.333333f, 2.666667f, 0.046875f }, // 457 (3 3 9 1) - { 5.444445f, 4.777778f, 2.888889f, 0.056604f }, // 458 (3 3 10 0) - { 4.777778f, 9.444445f, 0.888889f, 0.022556f }, // 459 (3 4 0 9) - { 4.888889f, 8.888889f, 1.111111f, 0.023684f }, // 460 (3 4 1 8) - { 5.000000f, 8.333333f, 1.333333f, 0.025070f }, // 461 (3 4 2 7) - { 5.111111f, 7.777778f, 1.555556f, 0.026786f }, // 462 (3 4 3 6) - { 5.222222f, 7.222222f, 1.777778f, 0.028939f }, // 463 (3 4 4 5) - { 5.333333f, 6.666667f, 2.000000f, 0.031690f }, // 464 (3 4 5 4) - { 5.444445f, 6.111111f, 2.222222f, 0.035294f }, // 465 (3 4 6 3) - { 5.555555f, 5.555555f, 2.444444f, 0.040179f }, // 466 (3 4 7 2) - { 5.666667f, 5.000000f, 2.666667f, 0.047120f }, // 467 (3 4 8 1) - { 5.777778f, 4.444445f, 2.888889f, 0.057692f }, // 468 (3 4 9 0) - { 5.222222f, 8.555555f, 1.111111f, 0.023018f }, // 469 (3 5 0 8) - { 5.333333f, 8.000000f, 1.333333f, 0.024457f }, // 470 (3 5 1 7) - { 5.444445f, 7.444445f, 1.555556f, 0.026239f }, // 471 (3 5 2 6) - { 5.555555f, 6.888889f, 1.777778f, 0.028481f }, // 472 (3 5 3 5) - { 5.666667f, 6.333333f, 2.000000f, 0.031359f }, // 473 (3 5 4 4) - { 5.777778f, 5.777778f, 2.222222f, 0.035156f }, // 474 (3 5 5 3) - { 5.888889f, 5.222222f, 2.444444f, 0.040359f }, // 475 (3 5 6 2) - { 6.000000f, 4.666667f, 2.666667f, 0.047872f }, // 476 (3 5 7 1) - { 6.111111f, 4.111111f, 2.888889f, 0.059603f }, // 477 (3 5 8 0) - { 5.666667f, 7.666667f, 1.333333f, 0.024000f }, // 478 (3 6 0 7) - { 5.777778f, 7.111111f, 1.555556f, 0.025862f }, // 479 (3 6 1 6) - { 5.888889f, 6.555555f, 1.777778f, 0.028213f }, // 480 (3 6 2 5) - { 6.000000f, 6.000000f, 2.000000f, 0.031250f }, // 481 (3 6 3 4) - { 6.111111f, 5.444445f, 2.222222f, 0.035294f }, // 482 (3 6 4 3) - { 6.222222f, 4.888889f, 2.444444f, 0.040909f }, // 483 (3 6 5 2) - { 6.333333f, 4.333333f, 2.666667f, 0.049180f }, // 484 (3 6 6 1) - { 6.444445f, 3.777778f, 2.888889f, 0.062500f }, // 485 (3 6 7 0) - { 6.111111f, 6.777778f, 1.555556f, 0.025641f }, // 486 (3 7 0 6) - { 6.222222f, 6.222222f, 1.777778f, 0.028125f }, // 487 (3 7 1 5) - { 6.333333f, 5.666667f, 2.000000f, 0.031359f }, // 488 (3 7 2 4) - { 6.444445f, 5.111111f, 2.222222f, 0.035714f }, // 489 (3 7 3 3) - { 6.555555f, 4.555555f, 2.444444f, 0.041860f }, // 490 (3 7 4 2) - { 6.666667f, 4.000000f, 2.666667f, 0.051136f }, // 491 (3 7 5 1) - { 6.777778f, 3.444444f, 2.888889f, 0.066667f }, // 492 (3 7 6 0) - { 6.555555f, 5.888889f, 1.777778f, 0.028213f }, // 493 (3 8 0 5) - { 6.666667f, 5.333333f, 2.000000f, 0.031690f }, // 494 (3 8 1 4) - { 6.777778f, 4.777778f, 2.222222f, 0.036437f }, // 495 (3 8 2 3) - { 6.888889f, 4.222222f, 2.444444f, 0.043269f }, // 496 (3 8 3 2) - { 7.000000f, 3.666667f, 2.666667f, 0.053892f }, // 497 (3 8 4 1) - { 7.111111f, 3.111111f, 2.888889f, 0.072581f }, // 498 (3 8 5 0) - { 7.000000f, 5.000000f, 2.000000f, 0.032258f }, // 499 (3 9 0 4) - { 7.111111f, 4.444445f, 2.222222f, 0.037500f }, // 500 (3 9 1 3) - { 7.222222f, 3.888889f, 2.444444f, 0.045226f }, // 501 (3 9 2 2) - { 7.333333f, 3.333333f, 2.666667f, 0.057692f }, // 502 (3 9 3 1) - { 7.444445f, 2.777778f, 2.888889f, 0.081081f }, // 503 (3 9 4 0) - { 7.444445f, 4.111111f, 2.222222f, 0.038961f }, // 504 (3 10 0 3) - { 7.555556f, 3.555556f, 2.444444f, 0.047872f }, // 505 (3 10 1 2) - { 7.666667f, 3.000000f, 2.666667f, 0.062937f }, // 506 (3 10 2 1) - { 7.777778f, 2.444444f, 2.888889f, 0.093750f }, // 507 (3 10 3 0) - { 7.888889f, 3.222222f, 2.444444f, 0.051429f }, // 508 (3 11 0 2) - { 8.000000f, 2.666667f, 2.666667f, 0.070313f }, // 509 (3 11 1 1) - { 8.111111f, 2.111111f, 2.888889f, 0.113924f }, // 510 (3 11 2 0) - { 8.333333f, 2.333333f, 2.666667f, 0.081081f }, // 511 (3 12 0 1) - { 8.444445f, 1.777778f, 2.888889f, 0.150000f }, // 512 (3 12 1 0) - { 8.777778f, 1.444444f, 2.888889f, 0.230769f }, // 513 (3 13 0 0) - { 4.000000f, 12.000000f, 0.000000f, 0.020833f }, // 514 (4 0 0 12) - { 4.111111f, 11.444445f, 0.222222f, 0.021277f }, // 515 (4 0 1 11) - { 4.222222f, 10.888889f, 0.444444f, 0.021845f }, // 516 (4 0 2 10) - { 4.333333f, 10.333333f, 0.666667f, 0.022556f }, // 517 (4 0 3 9) - { 4.444445f, 9.777778f, 0.888889f, 0.023438f }, // 518 (4 0 4 8) - { 4.555555f, 9.222222f, 1.111111f, 0.024523f }, // 519 (4 0 5 7) - { 4.666667f, 8.666667f, 1.333333f, 0.025862f }, // 520 (4 0 6 6) - { 4.777778f, 8.111111f, 1.555556f, 0.027523f }, // 521 (4 0 7 5) - { 4.888889f, 7.555555f, 1.777778f, 0.029605f }, // 522 (4 0 8 4) - { 5.000000f, 7.000000f, 2.000000f, 0.032258f }, // 523 (4 0 9 3) - { 5.111111f, 6.444445f, 2.222222f, 0.035714f }, // 524 (4 0 10 2) - { 5.222222f, 5.888889f, 2.444444f, 0.040359f }, // 525 (4 0 11 1) - { 5.333333f, 5.333333f, 2.666667f, 0.046875f }, // 526 (4 0 12 0) - { 4.444445f, 11.111111f, 0.222222f, 0.020270f }, // 527 (4 1 0 11) - { 4.555555f, 10.555555f, 0.444444f, 0.020882f }, // 528 (4 1 1 10) - { 4.666667f, 10.000000f, 0.666667f, 0.021635f }, // 529 (4 1 2 9) - { 4.777778f, 9.444445f, 0.888889f, 0.022556f }, // 530 (4 1 3 8) - { 4.888889f, 8.888889f, 1.111111f, 0.023684f }, // 531 (4 1 4 7) - { 5.000000f, 8.333333f, 1.333333f, 0.025070f }, // 532 (4 1 5 6) - { 5.111111f, 7.777778f, 1.555556f, 0.026786f }, // 533 (4 1 6 5) - { 5.222222f, 7.222222f, 1.777778f, 0.028939f }, // 534 (4 1 7 4) - { 5.333333f, 6.666667f, 2.000000f, 0.031690f }, // 535 (4 1 8 3) - { 5.444445f, 6.111111f, 2.222222f, 0.035294f }, // 536 (4 1 9 2) - { 5.555555f, 5.555556f, 2.444444f, 0.040179f }, // 537 (4 1 10 1) - { 5.666667f, 5.000000f, 2.666667f, 0.047120f }, // 538 (4 1 11 0) - { 4.888889f, 10.222222f, 0.444444f, 0.020089f }, // 539 (4 2 0 10) - { 5.000000f, 9.666667f, 0.666667f, 0.020882f }, // 540 (4 2 1 9) - { 5.111111f, 9.111111f, 0.888889f, 0.021845f }, // 541 (4 2 2 8) - { 5.222222f, 8.555555f, 1.111111f, 0.023018f }, // 542 (4 2 3 7) - { 5.333333f, 8.000000f, 1.333333f, 0.024457f }, // 543 (4 2 4 6) - { 5.444445f, 7.444445f, 1.555556f, 0.026239f }, // 544 (4 2 5 5) - { 5.555555f, 6.888889f, 1.777778f, 0.028481f }, // 545 (4 2 6 4) - { 5.666667f, 6.333333f, 2.000000f, 0.031359f }, // 546 (4 2 7 3) - { 5.777778f, 5.777778f, 2.222222f, 0.035156f }, // 547 (4 2 8 2) - { 5.888889f, 5.222222f, 2.444444f, 0.040359f }, // 548 (4 2 9 1) - { 6.000000f, 4.666667f, 2.666667f, 0.047872f }, // 549 (4 2 10 0) - { 5.333333f, 9.333333f, 0.666667f, 0.020270f }, // 550 (4 3 0 9) - { 5.444445f, 8.777778f, 0.888889f, 0.021277f }, // 551 (4 3 1 8) - { 5.555555f, 8.222222f, 1.111111f, 0.022500f }, // 552 (4 3 2 7) - { 5.666667f, 7.666667f, 1.333333f, 0.024000f }, // 553 (4 3 3 6) - { 5.777778f, 7.111111f, 1.555556f, 0.025862f }, // 554 (4 3 4 5) - { 5.888889f, 6.555555f, 1.777778f, 0.028213f }, // 555 (4 3 5 4) - { 6.000000f, 6.000000f, 2.000000f, 0.031250f }, // 556 (4 3 6 3) - { 6.111111f, 5.444445f, 2.222222f, 0.035294f }, // 557 (4 3 7 2) - { 6.222222f, 4.888889f, 2.444444f, 0.040909f }, // 558 (4 3 8 1) - { 6.333333f, 4.333333f, 2.666667f, 0.049180f }, // 559 (4 3 9 0) - { 5.777778f, 8.444445f, 0.888889f, 0.020833f }, // 560 (4 4 0 8) - { 5.888889f, 7.888889f, 1.111111f, 0.022113f }, // 561 (4 4 1 7) - { 6.000000f, 7.333333f, 1.333333f, 0.023684f }, // 562 (4 4 2 6) - { 6.111111f, 6.777778f, 1.555556f, 0.025641f }, // 563 (4 4 3 5) - { 6.222222f, 6.222222f, 1.777778f, 0.028125f }, // 564 (4 4 4 4) - { 6.333333f, 5.666667f, 2.000000f, 0.031359f }, // 565 (4 4 5 3) - { 6.444445f, 5.111111f, 2.222222f, 0.035714f }, // 566 (4 4 6 2) - { 6.555555f, 4.555555f, 2.444444f, 0.041860f }, // 567 (4 4 7 1) - { 6.666667f, 4.000000f, 2.666667f, 0.051136f }, // 568 (4 4 8 0) - { 6.222222f, 7.555555f, 1.111111f, 0.021845f }, // 569 (4 5 0 7) - { 6.333333f, 7.000000f, 1.333333f, 0.023499f }, // 570 (4 5 1 6) - { 6.444445f, 6.444445f, 1.555556f, 0.025568f }, // 571 (4 5 2 5) - { 6.555555f, 5.888889f, 1.777778f, 0.028213f }, // 572 (4 5 3 4) - { 6.666667f, 5.333333f, 2.000000f, 0.031690f }, // 573 (4 5 4 3) - { 6.777778f, 4.777778f, 2.222222f, 0.036437f }, // 574 (4 5 5 2) - { 6.888889f, 4.222222f, 2.444444f, 0.043269f }, // 575 (4 5 6 1) - { 7.000000f, 3.666667f, 2.666667f, 0.053892f }, // 576 (4 5 7 0) - { 6.666667f, 6.666667f, 1.333333f, 0.023438f }, // 577 (4 6 0 6) - { 6.777778f, 6.111111f, 1.555556f, 0.025641f }, // 578 (4 6 1 5) - { 6.888889f, 5.555555f, 1.777778f, 0.028481f }, // 579 (4 6 2 4) - { 7.000000f, 5.000000f, 2.000000f, 0.032258f }, // 580 (4 6 3 3) - { 7.111111f, 4.444445f, 2.222222f, 0.037500f }, // 581 (4 6 4 2) - { 7.222222f, 3.888889f, 2.444444f, 0.045226f }, // 582 (4 6 5 1) - { 7.333333f, 3.333333f, 2.666667f, 0.057692f }, // 583 (4 6 6 0) - { 7.111111f, 5.777778f, 1.555556f, 0.025862f }, // 584 (4 7 0 5) - { 7.222222f, 5.222222f, 1.777778f, 0.028939f }, // 585 (4 7 1 4) - { 7.333333f, 4.666667f, 2.000000f, 0.033088f }, // 586 (4 7 2 3) - { 7.444445f, 4.111111f, 2.222222f, 0.038961f }, // 587 (4 7 3 2) - { 7.555555f, 3.555556f, 2.444444f, 0.047872f }, // 588 (4 7 4 1) - { 7.666667f, 3.000000f, 2.666667f, 0.062937f }, // 589 (4 7 5 0) - { 7.555555f, 4.888889f, 1.777778f, 0.029605f }, // 590 (4 8 0 4) - { 7.666667f, 4.333333f, 2.000000f, 0.034221f }, // 591 (4 8 1 3) - { 7.777778f, 3.777778f, 2.222222f, 0.040909f }, // 592 (4 8 2 2) - { 7.888889f, 3.222222f, 2.444444f, 0.051429f }, // 593 (4 8 3 1) - { 8.000000f, 2.666667f, 2.666667f, 0.070313f }, // 594 (4 8 4 0) - { 8.000000f, 4.000000f, 2.000000f, 0.035714f }, // 595 (4 9 0 3) - { 8.111111f, 3.444444f, 2.222222f, 0.043478f }, // 596 (4 9 1 2) - { 8.222222f, 2.888889f, 2.444444f, 0.056250f }, // 597 (4 9 2 1) - { 8.333333f, 2.333333f, 2.666667f, 0.081081f }, // 598 (4 9 3 0) - { 8.444445f, 3.111111f, 2.222222f, 0.046875f }, // 599 (4 10 0 2) - { 8.555555f, 2.555556f, 2.444444f, 0.062937f }, // 600 (4 10 1 1) - { 8.666667f, 2.000000f, 2.666667f, 0.097826f }, // 601 (4 10 2 0) - { 8.888889f, 2.222222f, 2.444444f, 0.072581f }, // 602 (4 11 0 1) - { 9.000000f, 1.666667f, 2.666667f, 0.126761f }, // 603 (4 11 1 0) - { 9.333333f, 1.333333f, 2.666667f, 0.187500f }, // 604 (4 12 0 0) - { 5.000000f, 11.000000f, 0.000000f, 0.018182f }, // 605 (5 0 0 11) - { 5.111111f, 10.444445f, 0.222222f, 0.018750f }, // 606 (5 0 1 10) - { 5.222222f, 9.888889f, 0.444444f, 0.019438f }, // 607 (5 0 2 9) - { 5.333333f, 9.333333f, 0.666667f, 0.020270f }, // 608 (5 0 3 8) - { 5.444445f, 8.777778f, 0.888889f, 0.021277f }, // 609 (5 0 4 7) - { 5.555555f, 8.222222f, 1.111111f, 0.022500f }, // 610 (5 0 5 6) - { 5.666667f, 7.666667f, 1.333333f, 0.024000f }, // 611 (5 0 6 5) - { 5.777778f, 7.111111f, 1.555556f, 0.025862f }, // 612 (5 0 7 4) - { 5.888889f, 6.555555f, 1.777778f, 0.028213f }, // 613 (5 0 8 3) - { 6.000000f, 6.000000f, 2.000000f, 0.031250f }, // 614 (5 0 9 2) - { 6.111111f, 5.444445f, 2.222222f, 0.035294f }, // 615 (5 0 10 1) - { 6.222222f, 4.888889f, 2.444444f, 0.040909f }, // 616 (5 0 11 0) - { 5.444445f, 10.111111f, 0.222222f, 0.018182f }, // 617 (5 1 0 10) - { 5.555555f, 9.555555f, 0.444444f, 0.018908f }, // 618 (5 1 1 9) - { 5.666667f, 9.000000f, 0.666667f, 0.019780f }, // 619 (5 1 2 8) - { 5.777778f, 8.444445f, 0.888889f, 0.020833f }, // 620 (5 1 3 7) - { 5.888889f, 7.888889f, 1.111111f, 0.022113f }, // 621 (5 1 4 6) - { 6.000000f, 7.333333f, 1.333333f, 0.023684f }, // 622 (5 1 5 5) - { 6.111111f, 6.777778f, 1.555556f, 0.025641f }, // 623 (5 1 6 4) - { 6.222222f, 6.222222f, 1.777778f, 0.028125f }, // 624 (5 1 7 3) - { 6.333333f, 5.666667f, 2.000000f, 0.031359f }, // 625 (5 1 8 2) - { 6.444445f, 5.111111f, 2.222222f, 0.035714f }, // 626 (5 1 9 1) - { 6.555555f, 4.555556f, 2.444444f, 0.041860f }, // 627 (5 1 10 0) - { 5.888889f, 9.222222f, 0.444444f, 0.018480f }, // 628 (5 2 0 9) - { 6.000000f, 8.666667f, 0.666667f, 0.019397f }, // 629 (5 2 1 8) - { 6.111111f, 8.111111f, 0.888889f, 0.020501f }, // 630 (5 2 2 7) - { 6.222222f, 7.555555f, 1.111111f, 0.021845f }, // 631 (5 2 3 6) - { 6.333333f, 7.000000f, 1.333333f, 0.023499f }, // 632 (5 2 4 5) - { 6.444445f, 6.444445f, 1.555556f, 0.025568f }, // 633 (5 2 5 4) - { 6.555555f, 5.888889f, 1.777778f, 0.028213f }, // 634 (5 2 6 3) - { 6.666667f, 5.333333f, 2.000000f, 0.031690f }, // 635 (5 2 7 2) - { 6.777778f, 4.777778f, 2.222222f, 0.036437f }, // 636 (5 2 8 1) - { 6.888889f, 4.222222f, 2.444444f, 0.043269f }, // 637 (5 2 9 0) - { 6.333333f, 8.333333f, 0.666667f, 0.019108f }, // 638 (5 3 0 8) - { 6.444445f, 7.777778f, 0.888889f, 0.020270f }, // 639 (5 3 1 7) - { 6.555555f, 7.222222f, 1.111111f, 0.021687f }, // 640 (5 3 2 6) - { 6.666667f, 6.666667f, 1.333333f, 0.023438f }, // 641 (5 3 3 5) - { 6.777778f, 6.111111f, 1.555556f, 0.025641f }, // 642 (5 3 4 4) - { 6.888889f, 5.555555f, 1.777778f, 0.028481f }, // 643 (5 3 5 3) - { 7.000000f, 5.000000f, 2.000000f, 0.032258f }, // 644 (5 3 6 2) - { 7.111111f, 4.444445f, 2.222222f, 0.037500f }, // 645 (5 3 7 1) - { 7.222222f, 3.888889f, 2.444444f, 0.045226f }, // 646 (5 3 8 0) - { 6.777778f, 7.444445f, 0.888889f, 0.020134f }, // 647 (5 4 0 7) - { 6.888889f, 6.888889f, 1.111111f, 0.021635f }, // 648 (5 4 1 6) - { 7.000000f, 6.333333f, 1.333333f, 0.023499f }, // 649 (5 4 2 5) - { 7.111111f, 5.777778f, 1.555556f, 0.025862f }, // 650 (5 4 3 4) - { 7.222222f, 5.222222f, 1.777778f, 0.028939f }, // 651 (5 4 4 3) - { 7.333333f, 4.666667f, 2.000000f, 0.033088f }, // 652 (5 4 5 2) - { 7.444445f, 4.111111f, 2.222222f, 0.038961f }, // 653 (5 4 6 1) - { 7.555555f, 3.555556f, 2.444444f, 0.047872f }, // 654 (5 4 7 0) - { 7.222222f, 6.555555f, 1.111111f, 0.021687f }, // 655 (5 5 0 6) - { 7.333333f, 6.000000f, 1.333333f, 0.023684f }, // 656 (5 5 1 5) - { 7.444445f, 5.444445f, 1.555556f, 0.026239f }, // 657 (5 5 2 4) - { 7.555555f, 4.888889f, 1.777778f, 0.029605f }, // 658 (5 5 3 3) - { 7.666667f, 4.333333f, 2.000000f, 0.034221f }, // 659 (5 5 4 2) - { 7.777778f, 3.777778f, 2.222222f, 0.040909f }, // 660 (5 5 5 1) - { 7.888889f, 3.222222f, 2.444444f, 0.051429f }, // 661 (5 5 6 0) - { 7.666667f, 5.666667f, 1.333333f, 0.024000f }, // 662 (5 6 0 5) - { 7.777778f, 5.111111f, 1.555556f, 0.026786f }, // 663 (5 6 1 4) - { 7.888889f, 4.555555f, 1.777778f, 0.030508f }, // 664 (5 6 2 3) - { 8.000000f, 4.000000f, 2.000000f, 0.035714f }, // 665 (5 6 3 2) - { 8.111111f, 3.444444f, 2.222222f, 0.043478f }, // 666 (5 6 4 1) - { 8.222222f, 2.888889f, 2.444444f, 0.056250f }, // 667 (5 6 5 0) - { 8.111111f, 4.777778f, 1.555556f, 0.027523f }, // 668 (5 7 0 4) - { 8.222222f, 4.222222f, 1.777778f, 0.031690f }, // 669 (5 7 1 3) - { 8.333333f, 3.666667f, 2.000000f, 0.037657f }, // 670 (5 7 2 2) - { 8.444445f, 3.111111f, 2.222222f, 0.046875f }, // 671 (5 7 3 1) - { 8.555555f, 2.555556f, 2.444444f, 0.062937f }, // 672 (5 7 4 0) - { 8.555555f, 3.888889f, 1.777778f, 0.033210f }, // 673 (5 8 0 3) - { 8.666667f, 3.333333f, 2.000000f, 0.040179f }, // 674 (5 8 1 2) - { 8.777778f, 2.777778f, 2.222222f, 0.051429f }, // 675 (5 8 2 1) - { 8.888889f, 2.222222f, 2.444444f, 0.072581f }, // 676 (5 8 3 0) - { 9.000000f, 3.000000f, 2.000000f, 0.043478f }, // 677 (5 9 0 2) - { 9.111111f, 2.444444f, 2.222222f, 0.057692f }, // 678 (5 9 1 1) - { 9.222222f, 1.888889f, 2.444444f, 0.087379f }, // 679 (5 9 2 0) - { 9.444445f, 2.111111f, 2.222222f, 0.066667f }, // 680 (5 10 0 1) - { 9.555555f, 1.555556f, 2.444444f, 0.112500f }, // 681 (5 10 1 0) - { 9.888889f, 1.222222f, 2.444444f, 0.163636f }, // 682 (5 11 0 0) - { 6.000000f, 10.000000f, 0.000000f, 0.016667f }, // 683 (6 0 0 10) - { 6.111111f, 9.444445f, 0.222222f, 0.017341f }, // 684 (6 0 1 9) - { 6.222222f, 8.888889f, 0.444444f, 0.018145f }, // 685 (6 0 2 8) - { 6.333333f, 8.333333f, 0.666667f, 0.019108f }, // 686 (6 0 3 7) - { 6.444445f, 7.777778f, 0.888889f, 0.020270f }, // 687 (6 0 4 6) - { 6.555555f, 7.222222f, 1.111111f, 0.021687f }, // 688 (6 0 5 5) - { 6.666667f, 6.666667f, 1.333333f, 0.023438f }, // 689 (6 0 6 4) - { 6.777778f, 6.111111f, 1.555556f, 0.025641f }, // 690 (6 0 7 3) - { 6.888889f, 5.555555f, 1.777778f, 0.028481f }, // 691 (6 0 8 2) - { 7.000000f, 5.000000f, 2.000000f, 0.032258f }, // 692 (6 0 9 1) - { 7.111111f, 4.444445f, 2.222222f, 0.037500f }, // 693 (6 0 10 0) - { 6.444445f, 9.111111f, 0.222222f, 0.017045f }, // 694 (6 1 0 9) - { 6.555555f, 8.555555f, 0.444444f, 0.017893f }, // 695 (6 1 1 8) - { 6.666667f, 8.000000f, 0.666667f, 0.018908f }, // 696 (6 1 2 7) - { 6.777778f, 7.444445f, 0.888889f, 0.020134f }, // 697 (6 1 3 6) - { 6.888889f, 6.888889f, 1.111111f, 0.021635f }, // 698 (6 1 4 5) - { 7.000000f, 6.333333f, 1.333333f, 0.023499f }, // 699 (6 1 5 4) - { 7.111111f, 5.777778f, 1.555556f, 0.025862f }, // 700 (6 1 6 3) - { 7.222222f, 5.222222f, 1.777778f, 0.028939f }, // 701 (6 1 7 2) - { 7.333333f, 4.666667f, 2.000000f, 0.033088f }, // 702 (6 1 8 1) - { 7.444445f, 4.111111f, 2.222222f, 0.038961f }, // 703 (6 1 9 0) - { 6.888889f, 8.222222f, 0.444444f, 0.017717f }, // 704 (6 2 0 8) - { 7.000000f, 7.666667f, 0.666667f, 0.018789f }, // 705 (6 2 1 7) - { 7.111111f, 7.111111f, 0.888889f, 0.020089f }, // 706 (6 2 2 6) - { 7.222222f, 6.555555f, 1.111111f, 0.021687f }, // 707 (6 2 3 5) - { 7.333333f, 6.000000f, 1.333333f, 0.023684f }, // 708 (6 2 4 4) - { 7.444445f, 5.444445f, 1.555556f, 0.026239f }, // 709 (6 2 5 3) - { 7.555555f, 4.888889f, 1.777778f, 0.029605f }, // 710 (6 2 6 2) - { 7.666667f, 4.333333f, 2.000000f, 0.034221f }, // 711 (6 2 7 1) - { 7.777778f, 3.777778f, 2.222222f, 0.040909f }, // 712 (6 2 8 0) - { 7.333333f, 7.333333f, 0.666667f, 0.018750f }, // 713 (6 3 0 7) - { 7.444445f, 6.777778f, 0.888889f, 0.020134f }, // 714 (6 3 1 6) - { 7.555555f, 6.222222f, 1.111111f, 0.021845f }, // 715 (6 3 2 5) - { 7.666667f, 5.666667f, 1.333333f, 0.024000f }, // 716 (6 3 3 4) - { 7.777778f, 5.111111f, 1.555556f, 0.026786f }, // 717 (6 3 4 3) - { 7.888889f, 4.555555f, 1.777778f, 0.030508f }, // 718 (6 3 5 2) - { 8.000000f, 4.000000f, 2.000000f, 0.035714f }, // 719 (6 3 6 1) - { 8.111111f, 3.444444f, 2.222222f, 0.043478f }, // 720 (6 3 7 0) - { 7.777778f, 6.444445f, 0.888889f, 0.020270f }, // 721 (6 4 0 6) - { 7.888889f, 5.888889f, 1.111111f, 0.022113f }, // 722 (6 4 1 5) - { 8.000000f, 5.333333f, 1.333333f, 0.024457f }, // 723 (6 4 2 4) - { 8.111111f, 4.777778f, 1.555556f, 0.027523f }, // 724 (6 4 3 3) - { 8.222222f, 4.222222f, 1.777778f, 0.031690f }, // 725 (6 4 4 2) - { 8.333333f, 3.666667f, 2.000000f, 0.037657f }, // 726 (6 4 5 1) - { 8.444445f, 3.111111f, 2.222222f, 0.046875f }, // 727 (6 4 6 0) - { 8.222222f, 5.555555f, 1.111111f, 0.022500f }, // 728 (6 5 0 5) - { 8.333333f, 5.000000f, 1.333333f, 0.025070f }, // 729 (6 5 1 4) - { 8.444445f, 4.444445f, 1.555556f, 0.028481f }, // 730 (6 5 2 3) - { 8.555555f, 3.888889f, 1.777778f, 0.033210f }, // 731 (6 5 3 2) - { 8.666667f, 3.333333f, 2.000000f, 0.040179f }, // 732 (6 5 4 1) - { 8.777778f, 2.777778f, 2.222222f, 0.051429f }, // 733 (6 5 5 0) - { 8.666667f, 4.666667f, 1.333333f, 0.025862f }, // 734 (6 6 0 4) - { 8.777778f, 4.111111f, 1.555556f, 0.029703f }, // 735 (6 6 1 3) - { 8.888889f, 3.555556f, 1.777778f, 0.035156f }, // 736 (6 6 2 2) - { 9.000000f, 3.000000f, 2.000000f, 0.043478f }, // 737 (6 6 3 1) - { 9.111111f, 2.444444f, 2.222222f, 0.057692f }, // 738 (6 6 4 0) - { 9.111111f, 3.777778f, 1.555556f, 0.031250f }, // 739 (6 7 0 3) - { 9.222222f, 3.222222f, 1.777778f, 0.037657f }, // 740 (6 7 1 2) - { 9.333333f, 2.666667f, 2.000000f, 0.047872f }, // 741 (6 7 2 1) - { 9.444445f, 2.111111f, 2.222222f, 0.066667f }, // 742 (6 7 3 0) - { 9.555555f, 2.888889f, 1.777778f, 0.040909f }, // 743 (6 8 0 2) - { 9.666667f, 2.333333f, 2.000000f, 0.053892f }, // 744 (6 8 1 1) - { 9.777778f, 1.777778f, 2.222222f, 0.080357f }, // 745 (6 8 2 0) - { 10.000000f, 2.000000f, 2.000000f, 0.062500f }, // 746 (6 9 0 1) - { 10.111111f, 1.444444f, 2.222222f, 0.103448f }, // 747 (6 9 1 0) - { 10.444445f, 1.111111f, 2.222222f, 0.150000f }, // 748 (6 10 0 0) - { 7.000000f, 9.000000f, 0.000000f, 0.015873f }, // 749 (7 0 0 9) - { 7.111111f, 8.444445f, 0.222222f, 0.016667f }, // 750 (7 0 1 8) - { 7.222222f, 7.888889f, 0.444444f, 0.017613f }, // 751 (7 0 2 7) - { 7.333333f, 7.333333f, 0.666667f, 0.018750f }, // 752 (7 0 3 6) - { 7.444445f, 6.777778f, 0.888889f, 0.020134f }, // 753 (7 0 4 5) - { 7.555555f, 6.222222f, 1.111111f, 0.021845f }, // 754 (7 0 5 4) - { 7.666667f, 5.666667f, 1.333333f, 0.024000f }, // 755 (7 0 6 3) - { 7.777778f, 5.111111f, 1.555556f, 0.026786f }, // 756 (7 0 7 2) - { 7.888889f, 4.555555f, 1.777778f, 0.030508f }, // 757 (7 0 8 1) - { 8.000000f, 4.000000f, 2.000000f, 0.035714f }, // 758 (7 0 9 0) - { 7.444445f, 8.111111f, 0.222222f, 0.016575f }, // 759 (7 1 0 8) - { 7.555555f, 7.555555f, 0.444444f, 0.017578f }, // 760 (7 1 1 7) - { 7.666667f, 7.000000f, 0.666667f, 0.018789f }, // 761 (7 1 2 6) - { 7.777778f, 6.444445f, 0.888889f, 0.020270f }, // 762 (7 1 3 5) - { 7.888889f, 5.888889f, 1.111111f, 0.022113f }, // 763 (7 1 4 4) - { 8.000000f, 5.333333f, 1.333333f, 0.024457f }, // 764 (7 1 5 3) - { 8.111111f, 4.777778f, 1.555556f, 0.027523f }, // 765 (7 1 6 2) - { 8.222222f, 4.222222f, 1.777778f, 0.031690f }, // 766 (7 1 7 1) - { 8.333333f, 3.666667f, 2.000000f, 0.037657f }, // 767 (7 1 8 0) - { 7.888889f, 7.222222f, 0.444444f, 0.017613f }, // 768 (7 2 0 7) - { 8.000000f, 6.666667f, 0.666667f, 0.018908f }, // 769 (7 2 1 6) - { 8.111111f, 6.111111f, 0.888889f, 0.020501f }, // 770 (7 2 2 5) - { 8.222222f, 5.555555f, 1.111111f, 0.022500f }, // 771 (7 2 3 4) - { 8.333333f, 5.000000f, 1.333333f, 0.025070f }, // 772 (7 2 4 3) - { 8.444445f, 4.444445f, 1.555556f, 0.028481f }, // 773 (7 2 5 2) - { 8.555555f, 3.888889f, 1.777778f, 0.033210f }, // 774 (7 2 6 1) - { 8.666667f, 3.333333f, 2.000000f, 0.040179f }, // 775 (7 2 7 0) - { 8.333333f, 6.333333f, 0.666667f, 0.019108f }, // 776 (7 3 0 6) - { 8.444445f, 5.777778f, 0.888889f, 0.020833f }, // 777 (7 3 1 5) - { 8.555555f, 5.222222f, 1.111111f, 0.023018f }, // 778 (7 3 2 4) - { 8.666667f, 4.666667f, 1.333333f, 0.025862f }, // 779 (7 3 3 3) - { 8.777778f, 4.111111f, 1.555556f, 0.029703f }, // 780 (7 3 4 2) - { 8.888889f, 3.555556f, 1.777778f, 0.035156f }, // 781 (7 3 5 1) - { 9.000000f, 3.000000f, 2.000000f, 0.043478f }, // 782 (7 3 6 0) - { 8.777778f, 5.444445f, 0.888889f, 0.021277f }, // 783 (7 4 0 5) - { 8.888889f, 4.888889f, 1.111111f, 0.023684f }, // 784 (7 4 1 4) - { 9.000000f, 4.333333f, 1.333333f, 0.026866f }, // 785 (7 4 2 3) - { 9.111111f, 3.777778f, 1.555556f, 0.031250f }, // 786 (7 4 3 2) - { 9.222222f, 3.222222f, 1.777778f, 0.037657f }, // 787 (7 4 4 1) - { 9.333333f, 2.666667f, 2.000000f, 0.047872f }, // 788 (7 4 5 0) - { 9.222222f, 4.555555f, 1.111111f, 0.024523f }, // 789 (7 5 0 4) - { 9.333333f, 4.000000f, 1.333333f, 0.028125f }, // 790 (7 5 1 3) - { 9.444445f, 3.444444f, 1.555556f, 0.033210f }, // 791 (7 5 2 2) - { 9.555555f, 2.888889f, 1.777778f, 0.040909f }, // 792 (7 5 3 1) - { 9.666667f, 2.333333f, 2.000000f, 0.053892f }, // 793 (7 5 4 0) - { 9.666667f, 3.666667f, 1.333333f, 0.029703f }, // 794 (7 6 0 3) - { 9.777778f, 3.111111f, 1.555556f, 0.035714f }, // 795 (7 6 1 2) - { 9.888889f, 2.555556f, 1.777778f, 0.045226f }, // 796 (7 6 2 1) - { 10.000000f, 2.000000f, 2.000000f, 0.062500f }, // 797 (7 6 3 0) - { 10.111111f, 2.777778f, 1.555556f, 0.038961f }, // 798 (7 7 0 2) - { 10.222222f, 2.222222f, 1.777778f, 0.051136f }, // 799 (7 7 1 1) - { 10.333333f, 1.666667f, 2.000000f, 0.075630f }, // 800 (7 7 2 0) - { 10.555555f, 1.888889f, 1.777778f, 0.059603f }, // 801 (7 8 0 1) - { 10.666667f, 1.333333f, 2.000000f, 0.097826f }, // 802 (7 8 1 0) - { 11.000000f, 1.000000f, 2.000000f, 0.142857f }, // 803 (7 9 0 0) - { 8.000000f, 8.000000f, 0.000000f, 0.015625f }, // 804 (8 0 0 8) - { 8.111111f, 7.444445f, 0.222222f, 0.016575f }, // 805 (8 0 1 7) - { 8.222222f, 6.888889f, 0.444444f, 0.017717f }, // 806 (8 0 2 6) - { 8.333333f, 6.333333f, 0.666667f, 0.019108f }, // 807 (8 0 3 5) - { 8.444445f, 5.777778f, 0.888889f, 0.020833f }, // 808 (8 0 4 4) - { 8.555555f, 5.222222f, 1.111111f, 0.023018f }, // 809 (8 0 5 3) - { 8.666667f, 4.666667f, 1.333333f, 0.025862f }, // 810 (8 0 6 2) - { 8.777778f, 4.111111f, 1.555556f, 0.029703f }, // 811 (8 0 7 1) - { 8.888889f, 3.555556f, 1.777778f, 0.035156f }, // 812 (8 0 8 0) - { 8.444445f, 7.111111f, 0.222222f, 0.016667f }, // 813 (8 1 0 7) - { 8.555555f, 6.555555f, 0.444444f, 0.017893f }, // 814 (8 1 1 6) - { 8.666667f, 6.000000f, 0.666667f, 0.019397f }, // 815 (8 1 2 5) - { 8.777778f, 5.444445f, 0.888889f, 0.021277f }, // 816 (8 1 3 4) - { 8.888889f, 4.888889f, 1.111111f, 0.023684f }, // 817 (8 1 4 3) - { 9.000000f, 4.333333f, 1.333333f, 0.026866f }, // 818 (8 1 5 2) - { 9.111111f, 3.777778f, 1.555556f, 0.031250f }, // 819 (8 1 6 1) - { 9.222222f, 3.222222f, 1.777778f, 0.037657f }, // 820 (8 1 7 0) - { 8.888889f, 6.222222f, 0.444444f, 0.018145f }, // 821 (8 2 0 6) - { 9.000000f, 5.666667f, 0.666667f, 0.019780f }, // 822 (8 2 1 5) - { 9.111111f, 5.111111f, 0.888889f, 0.021845f }, // 823 (8 2 2 4) - { 9.222222f, 4.555555f, 1.111111f, 0.024523f }, // 824 (8 2 3 3) - { 9.333333f, 4.000000f, 1.333333f, 0.028125f }, // 825 (8 2 4 2) - { 9.444445f, 3.444444f, 1.555556f, 0.033210f }, // 826 (8 2 5 1) - { 9.555555f, 2.888889f, 1.777778f, 0.040909f }, // 827 (8 2 6 0) - { 9.333333f, 5.333333f, 0.666667f, 0.020270f }, // 828 (8 3 0 5) - { 9.444445f, 4.777778f, 0.888889f, 0.022556f }, // 829 (8 3 1 4) - { 9.555555f, 4.222222f, 1.111111f, 0.025568f }, // 830 (8 3 2 3) - { 9.666667f, 3.666667f, 1.333333f, 0.029703f }, // 831 (8 3 3 2) - { 9.777778f, 3.111111f, 1.555556f, 0.035714f }, // 832 (8 3 4 1) - { 9.888889f, 2.555556f, 1.777778f, 0.045226f }, // 833 (8 3 5 0) - { 9.777778f, 4.444445f, 0.888889f, 0.023438f }, // 834 (8 4 0 4) - { 9.888889f, 3.888889f, 1.111111f, 0.026866f }, // 835 (8 4 1 3) - { 10.000000f, 3.333333f, 1.333333f, 0.031690f }, // 836 (8 4 2 2) - { 10.111111f, 2.777778f, 1.555556f, 0.038961f }, // 837 (8 4 3 1) - { 10.222222f, 2.222222f, 1.777778f, 0.051136f }, // 838 (8 4 4 0) - { 10.222222f, 3.555556f, 1.111111f, 0.028481f }, // 839 (8 5 0 3) - { 10.333333f, 3.000000f, 1.333333f, 0.034221f }, // 840 (8 5 1 2) - { 10.444445f, 2.444444f, 1.555556f, 0.043269f }, // 841 (8 5 2 1) - { 10.555555f, 1.888889f, 1.777778f, 0.059603f }, // 842 (8 5 3 0) - { 10.666667f, 2.666667f, 1.333333f, 0.037500f }, // 843 (8 6 0 2) - { 10.777778f, 2.111111f, 1.555556f, 0.049180f }, // 844 (8 6 1 1) - { 10.888889f, 1.555556f, 1.777778f, 0.072581f }, // 845 (8 6 2 0) - { 11.111111f, 1.777778f, 1.555556f, 0.057692f }, // 846 (8 7 0 1) - { 11.222222f, 1.222222f, 1.777778f, 0.094737f }, // 847 (8 7 1 0) - { 11.555555f, 0.888889f, 1.777778f, 0.140625f }, // 848 (8 8 0 0) - { 9.000000f, 7.000000f, 0.000000f, 0.015873f }, // 849 (9 0 0 7) - { 9.111111f, 6.444445f, 0.222222f, 0.017045f }, // 850 (9 0 1 6) - { 9.222222f, 5.888889f, 0.444444f, 0.018480f }, // 851 (9 0 2 5) - { 9.333333f, 5.333333f, 0.666667f, 0.020270f }, // 852 (9 0 3 4) - { 9.444445f, 4.777778f, 0.888889f, 0.022556f }, // 853 (9 0 4 3) - { 9.555555f, 4.222222f, 1.111111f, 0.025568f }, // 854 (9 0 5 2) - { 9.666667f, 3.666667f, 1.333333f, 0.029703f }, // 855 (9 0 6 1) - { 9.777778f, 3.111111f, 1.555556f, 0.035714f }, // 856 (9 0 7 0) - { 9.444445f, 6.111111f, 0.222222f, 0.017341f }, // 857 (9 1 0 6) - { 9.555555f, 5.555555f, 0.444444f, 0.018908f }, // 858 (9 1 1 5) - { 9.666667f, 5.000000f, 0.666667f, 0.020882f }, // 859 (9 1 2 4) - { 9.777778f, 4.444445f, 0.888889f, 0.023438f }, // 860 (9 1 3 3) - { 9.888889f, 3.888889f, 1.111111f, 0.026866f }, // 861 (9 1 4 2) - { 10.000000f, 3.333333f, 1.333333f, 0.031690f }, // 862 (9 1 5 1) - { 10.111111f, 2.777778f, 1.555556f, 0.038961f }, // 863 (9 1 6 0) - { 9.888889f, 5.222222f, 0.444444f, 0.019438f }, // 864 (9 2 0 5) - { 10.000000f, 4.666667f, 0.666667f, 0.021635f }, // 865 (9 2 1 4) - { 10.111111f, 4.111111f, 0.888889f, 0.024523f }, // 866 (9 2 2 3) - { 10.222222f, 3.555556f, 1.111111f, 0.028481f }, // 867 (9 2 3 2) - { 10.333333f, 3.000000f, 1.333333f, 0.034221f }, // 868 (9 2 4 1) - { 10.444445f, 2.444444f, 1.555556f, 0.043269f }, // 869 (9 2 5 0) - { 10.333333f, 4.333333f, 0.666667f, 0.022556f }, // 870 (9 3 0 4) - { 10.444445f, 3.777778f, 0.888889f, 0.025862f }, // 871 (9 3 1 3) - { 10.555555f, 3.222222f, 1.111111f, 0.030508f }, // 872 (9 3 2 2) - { 10.666667f, 2.666667f, 1.333333f, 0.037500f }, // 873 (9 3 3 1) - { 10.777778f, 2.111111f, 1.555556f, 0.049180f }, // 874 (9 3 4 0) - { 10.777778f, 3.444444f, 0.888889f, 0.027523f }, // 875 (9 4 0 3) - { 10.888889f, 2.888889f, 1.111111f, 0.033088f }, // 876 (9 4 1 2) - { 11.000000f, 2.333333f, 1.333333f, 0.041860f }, // 877 (9 4 2 1) - { 11.111111f, 1.777778f, 1.555556f, 0.057692f }, // 878 (9 4 3 0) - { 11.222222f, 2.555556f, 1.111111f, 0.036437f }, // 879 (9 5 0 2) - { 11.333333f, 2.000000f, 1.333333f, 0.047872f }, // 880 (9 5 1 1) - { 11.444445f, 1.444444f, 1.555556f, 0.070866f }, // 881 (9 5 2 0) - { 11.666667f, 1.666667f, 1.333333f, 0.056604f }, // 882 (9 6 0 1) - { 11.777778f, 1.111111f, 1.555556f, 0.093750f }, // 883 (9 6 1 0) - { 12.111111f, 0.777778f, 1.555556f, 0.142857f }, // 884 (9 7 0 0) - { 10.000000f, 6.000000f, 0.000000f, 0.016667f }, // 885 (10 0 0 6) - { 10.111111f, 5.444445f, 0.222222f, 0.018182f }, // 886 (10 0 1 5) - { 10.222222f, 4.888889f, 0.444444f, 0.020089f }, // 887 (10 0 2 4) - { 10.333333f, 4.333333f, 0.666667f, 0.022556f }, // 888 (10 0 3 3) - { 10.444445f, 3.777778f, 0.888889f, 0.025862f }, // 889 (10 0 4 2) - { 10.555555f, 3.222222f, 1.111111f, 0.030508f }, // 890 (10 0 5 1) - { 10.666667f, 2.666667f, 1.333333f, 0.037500f }, // 891 (10 0 6 0) - { 10.444445f, 5.111111f, 0.222222f, 0.018750f }, // 892 (10 1 0 5) - { 10.555555f, 4.555555f, 0.444444f, 0.020882f }, // 893 (10 1 1 4) - { 10.666667f, 4.000000f, 0.666667f, 0.023684f }, // 894 (10 1 2 3) - { 10.777778f, 3.444444f, 0.888889f, 0.027523f }, // 895 (10 1 3 2) - { 10.888889f, 2.888889f, 1.111111f, 0.033088f }, // 896 (10 1 4 1) - { 11.000000f, 2.333333f, 1.333333f, 0.041860f }, // 897 (10 1 5 0) - { 10.888889f, 4.222222f, 0.444444f, 0.021845f }, // 898 (10 2 0 4) - { 11.000000f, 3.666667f, 0.666667f, 0.025070f }, // 899 (10 2 1 3) - { 11.111111f, 3.111111f, 0.888889f, 0.029605f }, // 900 (10 2 2 2) - { 11.222222f, 2.555556f, 1.111111f, 0.036437f }, // 901 (10 2 3 1) - { 11.333333f, 2.000000f, 1.333333f, 0.047872f }, // 902 (10 2 4 0) - { 11.333333f, 3.333333f, 0.666667f, 0.026786f }, // 903 (10 3 0 3) - { 11.444445f, 2.777778f, 0.888889f, 0.032258f }, // 904 (10 3 1 2) - { 11.555555f, 2.222222f, 1.111111f, 0.040909f }, // 905 (10 3 2 1) - { 11.666667f, 1.666667f, 1.333333f, 0.056604f }, // 906 (10 3 3 0) - { 11.777778f, 2.444444f, 0.888889f, 0.035714f }, // 907 (10 4 0 2) - { 11.888889f, 1.888889f, 1.111111f, 0.047120f }, // 908 (10 4 1 1) - { 12.000000f, 1.333333f, 1.333333f, 0.070313f }, // 909 (10 4 2 0) - { 12.222222f, 1.555556f, 1.111111f, 0.056250f }, // 910 (10 5 0 1) - { 12.333333f, 1.000000f, 1.333333f, 0.094737f }, // 911 (10 5 1 0) - { 12.666667f, 0.666667f, 1.333333f, 0.150000f }, // 912 (10 6 0 0) - { 11.000000f, 5.000000f, 0.000000f, 0.018182f }, // 913 (11 0 0 5) - { 11.111111f, 4.444445f, 0.222222f, 0.020270f }, // 914 (11 0 1 4) - { 11.222222f, 3.888889f, 0.444444f, 0.023018f }, // 915 (11 0 2 3) - { 11.333333f, 3.333333f, 0.666667f, 0.026786f }, // 916 (11 0 3 2) - { 11.444445f, 2.777778f, 0.888889f, 0.032258f }, // 917 (11 0 4 1) - { 11.555555f, 2.222222f, 1.111111f, 0.040909f }, // 918 (11 0 5 0) - { 11.444445f, 4.111111f, 0.222222f, 0.021277f }, // 919 (11 1 0 4) - { 11.555555f, 3.555556f, 0.444444f, 0.024457f }, // 920 (11 1 1 3) - { 11.666667f, 3.000000f, 0.666667f, 0.028939f }, // 921 (11 1 2 2) - { 11.777778f, 2.444444f, 0.888889f, 0.035714f }, // 922 (11 1 3 1) - { 11.888889f, 1.888889f, 1.111111f, 0.047120f }, // 923 (11 1 4 0) - { 11.888889f, 3.222222f, 0.444444f, 0.026239f }, // 924 (11 2 0 3) - { 12.000000f, 2.666667f, 0.666667f, 0.031690f }, // 925 (11 2 1 2) - { 12.111111f, 2.111111f, 0.888889f, 0.040359f }, // 926 (11 2 2 1) - { 12.222222f, 1.555556f, 1.111111f, 0.056250f }, // 927 (11 2 3 0) - { 12.333333f, 2.333333f, 0.666667f, 0.035294f }, // 928 (11 3 0 2) - { 12.444445f, 1.777778f, 0.888889f, 0.046875f }, // 929 (11 3 1 1) - { 12.555555f, 1.222222f, 1.111111f, 0.070866f }, // 930 (11 3 2 0) - { 12.777778f, 1.444444f, 0.888889f, 0.056604f }, // 931 (11 4 0 1) - { 12.888889f, 0.888889f, 1.111111f, 0.097826f }, // 932 (11 4 1 0) - { 13.222222f, 0.555556f, 1.111111f, 0.163636f }, // 933 (11 5 0 0) - { 12.000000f, 4.000000f, 0.000000f, 0.020833f }, // 934 (12 0 0 4) - { 12.111111f, 3.444444f, 0.222222f, 0.024000f }, // 935 (12 0 1 3) - { 12.222222f, 2.888889f, 0.444444f, 0.028481f }, // 936 (12 0 2 2) - { 12.333333f, 2.333333f, 0.666667f, 0.035294f }, // 937 (12 0 3 1) - { 12.444445f, 1.777778f, 0.888889f, 0.046875f }, // 938 (12 0 4 0) - { 12.444445f, 3.111111f, 0.222222f, 0.025862f }, // 939 (12 1 0 3) - { 12.555555f, 2.555556f, 0.444444f, 0.031359f }, // 940 (12 1 1 2) - { 12.666667f, 2.000000f, 0.666667f, 0.040179f }, // 941 (12 1 2 1) - { 12.777778f, 1.444444f, 0.888889f, 0.056604f }, // 942 (12 1 3 0) - { 12.888889f, 2.222222f, 0.444444f, 0.035156f }, // 943 (12 2 0 2) - { 13.000000f, 1.666667f, 0.666667f, 0.047120f }, // 944 (12 2 1 1) - { 13.111111f, 1.111111f, 0.888889f, 0.072581f }, // 945 (12 2 2 0) - { 13.333333f, 1.333333f, 0.666667f, 0.057692f }, // 946 (12 3 0 1) - { 13.444445f, 0.777778f, 0.888889f, 0.103448f }, // 947 (12 3 1 0) - { 13.777778f, 0.444444f, 0.888889f, 0.187500f }, // 948 (12 4 0 0) - { 13.000000f, 3.000000f, 0.000000f, 0.025641f }, // 949 (13 0 0 3) - { 13.111111f, 2.444444f, 0.222222f, 0.031250f }, // 950 (13 0 1 2) - { 13.222222f, 1.888889f, 0.444444f, 0.040359f }, // 951 (13 0 2 1) - { 13.333333f, 1.333333f, 0.666667f, 0.057692f }, // 952 (13 0 3 0) - { 13.444445f, 2.111111f, 0.222222f, 0.035294f }, // 953 (13 1 0 2) - { 13.555555f, 1.555556f, 0.444444f, 0.047872f }, // 954 (13 1 1 1) - { 13.666667f, 1.000000f, 0.666667f, 0.075630f }, // 955 (13 1 2 0) - { 13.888889f, 1.222222f, 0.444444f, 0.059603f }, // 956 (13 2 0 1) - { 14.000000f, 0.666667f, 0.666667f, 0.112500f }, // 957 (13 2 1 0) - { 14.333333f, 0.333333f, 0.666667f, 0.230769f }, // 958 (13 3 0 0) - { 14.000000f, 2.000000f, 0.000000f, 0.035714f }, // 959 (14 0 0 2) - { 14.111111f, 1.444444f, 0.222222f, 0.049180f }, // 960 (14 0 1 1) - { 14.222222f, 0.888889f, 0.444444f, 0.080357f }, // 961 (14 0 2 0) - { 14.444445f, 1.111111f, 0.222222f, 0.062500f }, // 962 (14 1 0 1) - { 14.555555f, 0.555556f, 0.444444f, 0.126761f }, // 963 (14 1 1 0) - { 14.888889f, 0.222222f, 0.444444f, 0.321429f }, // 964 (14 2 0 0) - { 15.000000f, 1.000000f, 0.000000f, 0.066667f }, // 965 (15 0 0 1) - { 15.111111f, 0.444444f, 0.222222f, 0.150000f }, // 966 (15 0 1 0) - { 15.444445f, 0.111111f, 0.222222f, 0.600000f }, // 967 (15 1 0 0) - { 16.000000f, 0.000000f, 0.000000f, FLT_MAX }, // 968 (16 0 0 0) -}; // 969 four cluster elements - diff --git a/Externals/NVTT/src/nvtt/squish/maths.cpp b/Externals/NVTT/src/nvtt/squish/maths.cpp deleted file mode 100644 index 6a5b4ffca9a..00000000000 --- a/Externals/NVTT/src/nvtt/squish/maths.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "maths.h" -#include "simd.h" -#include - -namespace squish { - -Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights, Vec3::Arg metric ) -{ - // compute the centroid - float total = 0.0f; - Vec3 centroid( 0.0f ); - for( int i = 0; i < n; ++i ) - { - total += weights[i]; - centroid += weights[i]*points[i]; - } - centroid /= total; - - // accumulate the covariance matrix - Sym3x3 covariance( 0.0f ); - for( int i = 0; i < n; ++i ) - { - Vec3 a = (points[i] - centroid) * metric; - Vec3 b = weights[i]*a; - - covariance[0] += a.X()*b.X(); - covariance[1] += a.X()*b.Y(); - covariance[2] += a.X()*b.Z(); - covariance[3] += a.Y()*b.Y(); - covariance[4] += a.Y()*b.Z(); - covariance[5] += a.Z()*b.Z(); - } - - // return it - return covariance; -} - - -static Vec3 EstimatePrincipleComponent( Sym3x3 const& matrix ) -{ - Vec3 const row0(matrix[0], matrix[1], matrix[2]); - Vec3 const row1(matrix[1], matrix[3], matrix[4]); - Vec3 const row2(matrix[2], matrix[4], matrix[5]); - - float r0 = Dot(row0, row0); - float r1 = Dot(row1, row1); - float r2 = Dot(row2, row2); - - if (r0 > r1 && r0 > r2) return row0; - if (r1 > r2) return row1; - return row2; -} - - -#define POWER_ITERATION_COUNT 8 - -#if SQUISH_USE_SIMD - -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) -{ - Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f ); - Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f ); - Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f ); - - //Vec4 v = VEC4_CONST( 1.0f ); - //Vec4 v = row0; // row1, row2 - - Vec3 v3 = EstimatePrincipleComponent( matrix ); - Vec4 v( v3.X(), v3.Y(), v3.Z(), 0.0f ); - - for( int i = 0; i < POWER_ITERATION_COUNT; ++i ) - { - // matrix multiply - Vec4 w = row0*v.SplatX(); - w = MultiplyAdd(row1, v.SplatY(), w); - w = MultiplyAdd(row2, v.SplatZ(), w); - - // get max component from xyz in all channels - Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ())); - - // divide through and advance - v = w*Reciprocal(a); - } - return v.GetVec3(); -} - -#else - -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) -{ - Vec3 v = EstimatePrincipleComponent( matrix ); - for (int i = 0; i < POWER_ITERATION_COUNT; i++) - { - float x = v.X() * matrix[0] + v.Y() * matrix[1] + v.Z() * matrix[2]; - float y = v.X() * matrix[1] + v.Y() * matrix[3] + v.Z() * matrix[4]; - float z = v.X() * matrix[2] + v.Y() * matrix[4] + v.Z() * matrix[5]; - - float norm = std::max(std::max(x, y), z); - float iv = 1.0f / norm; - if (norm == 0.0f) { // @@ I think this is not necessary in this case!! - return Vec3(0.0f); - } - - v = Vec3(x*iv, y*iv, z*iv); - } - - return v; -} - -#endif - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/maths.h b/Externals/NVTT/src/nvtt/squish/maths.h deleted file mode 100644 index 087a8890bc6..00000000000 --- a/Externals/NVTT/src/nvtt/squish/maths.h +++ /dev/null @@ -1,239 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_MATHS_H -#define SQUISH_MATHS_H - -#include -#include -#include "config.h" - -namespace squish { - -class Vec3 -{ -public: - typedef Vec3 const& Arg; - - Vec3() - { - } - - explicit Vec3( float a ) - { - m_x = a; - m_y = a; - m_z = a; - } - - Vec3( float a, float b, float c ) - { - m_x = a; - m_y = b; - m_z = c; - } - - float X() const { return m_x; } - float Y() const { return m_y; } - float Z() const { return m_z; } - - Vec3 operator-() const - { - return Vec3( -m_x, -m_y, -m_z ); - } - - Vec3& operator+=( Arg v ) - { - m_x += v.m_x; - m_y += v.m_y; - m_z += v.m_z; - return *this; - } - - Vec3& operator-=( Arg v ) - { - m_x -= v.m_x; - m_y -= v.m_y; - m_z -= v.m_z; - return *this; - } - - Vec3& operator*=( Arg v ) - { - m_x *= v.m_x; - m_y *= v.m_y; - m_z *= v.m_z; - return *this; - } - - Vec3& operator*=( float s ) - { - m_x *= s; - m_y *= s; - m_z *= s; - return *this; - } - - Vec3& operator/=( Arg v ) - { - m_x /= v.m_x; - m_y /= v.m_y; - m_z /= v.m_z; - return *this; - } - - Vec3& operator/=( float s ) - { - float t = 1.0f/s; - m_x *= t; - m_y *= t; - m_z *= t; - return *this; - } - - friend Vec3 operator+( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy += right; - } - - friend Vec3 operator+( Arg left, float right ) - { - Vec3 copy( left ); - return copy += Vec3(right); - } - - friend Vec3 operator-( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy -= right; - } - - friend Vec3 operator*( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy *= right; - } - - friend Vec3 operator*( Arg left, float right ) - { - Vec3 copy( left ); - return copy *= right; - } - - friend Vec3 operator*( float left, Arg right ) - { - Vec3 copy( right ); - return copy *= left; - } - - friend Vec3 operator/( Arg left, Arg right ) - { - Vec3 copy( left ); - return copy /= right; - } - - friend Vec3 operator/( Arg left, float right ) - { - Vec3 copy( left ); - return copy /= right; - } - - friend float Dot( Arg left, Arg right ) - { - return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z; - } - - friend Vec3 Min( Arg left, Arg right ) - { - return Vec3( - std::min( left.m_x, right.m_x ), - std::min( left.m_y, right.m_y ), - std::min( left.m_z, right.m_z ) - ); - } - - friend Vec3 Max( Arg left, Arg right ) - { - return Vec3( - std::max( left.m_x, right.m_x ), - std::max( left.m_y, right.m_y ), - std::max( left.m_z, right.m_z ) - ); - } - - friend Vec3 Floor( Arg v ) - { - return Vec3( - std::floor( v.m_x ), - std::floor( v.m_y ), - std::floor( v.m_z ) - ); - } - -private: - float m_x; - float m_y; - float m_z; -}; - -inline float LengthSquared( Vec3::Arg v ) -{ - return Dot( v, v ); -} - -class Sym3x3 -{ -public: - Sym3x3() - { - } - - Sym3x3( float a ) - { - for( int i = 0; i < 6; ++i ) - m_x[i] = a; - } - - float operator[]( int index ) const - { - return m_x[index]; - } - - float& operator[]( int index ) - { - return m_x[index]; - } - -private: - float m_x[6]; -}; - -Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights, Vec3::Arg metric ); -Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ); - -} // namespace squish - -#endif // ndef SQUISH_MATHS_H diff --git a/Externals/NVTT/src/nvtt/squish/rangefit.cpp b/Externals/NVTT/src/nvtt/squish/rangefit.cpp deleted file mode 100644 index a1934f5d102..00000000000 --- a/Externals/NVTT/src/nvtt/squish/rangefit.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "rangefit.h" -#include "colourset.h" -#include "colourblock.h" -#include - -namespace squish { - -RangeFit::RangeFit( ColourSet const* colours, int flags ) - : ColourFit( /*colours, flags*/ ) -{ - SetColourSet( colours, flags ); - // initialise the metric - bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 ); - if( perceptual ) - m_metric = Vec3( 0.2126f, 0.7152f, 0.0722f ); - else - m_metric = Vec3( 1.0f ); - - // initialise the best error - m_besterror = FLT_MAX; - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights, m_metric ); - - // compute the principle component - Vec3 principle = ComputePrincipleComponent( covariance ); - - // get the min and max range as the codebook endpoints - Vec3 start( 0.0f ); - Vec3 end( 0.0f ); - if( count > 0 ) - { - float min, max; - - // compute the range - start = end = values[0]; - min = max = Dot( values[0], principle ); - for( int i = 1; i < count; ++i ) - { - float val = Dot( values[i], principle ); - if( val < min ) - { - start = values[i]; - min = val; - } - else if( val > max ) - { - end = values[i]; - max = val; - } - } - } - - // clamp the output to [0, 1] - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - start = Min( one, Max( zero, start ) ); - end = Min( one, Max( zero, end ) ); - - // clamp to the grid and save - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); - Vec3 const half( 0.5f ); - m_start = Floor( grid*start + half )*gridrcp; - m_end = Floor( grid*end + half )*gridrcp; -} - -void RangeFit::Compress3( void* block ) -{ - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // create a codebook - Vec3 codes[3]; - codes[0] = m_start; - codes[1] = m_end; - codes[2] = 0.5f*m_start + 0.5f*m_end; - - // match each point to the closest code - u8 closest[16]; - float error = 0.0f; - for( int i = 0; i < count; ++i ) - { - // find the closest code - float dist = FLT_MAX; - int idx = 0; - for( int j = 0; j < 3; ++j ) - { - float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); - if( d < dist ) - { - dist = d; - idx = j; - } - } - - // save the index - closest[i] = ( u8 )idx; - - // accumulate the error - error += dist; - } - - // save this scheme if it wins - if( error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( closest, indices ); - - // save the block - WriteColourBlock3( m_start, m_end, indices, block ); - - // save the error - m_besterror = error; - } -} - -void RangeFit::Compress4( void* block ) -{ - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // create a codebook - Vec3 codes[4]; - codes[0] = m_start; - codes[1] = m_end; - codes[2] = ( 2.0f/3.0f )*m_start + ( 1.0f/3.0f )*m_end; - codes[3] = ( 1.0f/3.0f )*m_start + ( 2.0f/3.0f )*m_end; - - // match each point to the closest code - u8 closest[16]; - float error = 0.0f; - for( int i = 0; i < count; ++i ) - { - // find the closest code - float dist = FLT_MAX; - int idx = 0; - for( int j = 0; j < 4; ++j ) - { - float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); - if( d < dist ) - { - dist = d; - idx = j; - } - } - - // save the index - closest[i] = ( u8 )idx; - - // accumulate the error - error += dist; - } - - // save this scheme if it wins - if( error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( closest, indices ); - - // save the block - WriteColourBlock4( m_start, m_end, indices, block ); - - // save the error - m_besterror = error; - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/rangefit.h b/Externals/NVTT/src/nvtt/squish/rangefit.h deleted file mode 100644 index 795201993aa..00000000000 --- a/Externals/NVTT/src/nvtt/squish/rangefit.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_RANGEFIT_H -#define SQUISH_RANGEFIT_H - -#include -#include "colourfit.h" -#include "maths.h" - -namespace squish { - -class ColourSet; - -class RangeFit : public ColourFit -{ -public: - RangeFit( ColourSet const* colours, int flags ); - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - Vec3 m_metric; - Vec3 m_start; - Vec3 m_end; - float m_besterror; -}; - -} // squish - -#endif // ndef SQUISH_RANGEFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/simd.h b/Externals/NVTT/src/nvtt/squish/simd.h deleted file mode 100644 index cb98e7f18e0..00000000000 --- a/Externals/NVTT/src/nvtt/squish/simd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SIMD_H -#define SQUISH_SIMD_H - -#include "maths.h" - -#ifdef __GNUC__ -# define SQUISH_ALIGN_16 __attribute__ ((__aligned__ (16))) -#else -# define SQUISH_ALIGN_16 __declspec(align(16)) -#endif - -#if SQUISH_USE_ALTIVEC -#include "simd_ve.h" -#endif - -#if SQUISH_USE_SSE -#include "simd_sse.h" -#endif - -#endif // ndef SQUISH_SIMD_H diff --git a/Externals/NVTT/src/nvtt/squish/simd_3dnow.h b/Externals/NVTT/src/nvtt/squish/simd_3dnow.h deleted file mode 100644 index 94377696cf5..00000000000 --- a/Externals/NVTT/src/nvtt/squish/simd_3dnow.h +++ /dev/null @@ -1,213 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SIMD_3DNOW_H -#define SQUISH_SIMD_3DNOW_H - - -#include -#include - -//#define SQUISH_SSE_SPLAT( a ) \ - ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) ) - -namespace squish { - -//#define VEC4_CONST( X ) Vec4( _mm_set1_ps( X ) ) - -class Vec4 -{ -public: - typedef Vec4 const& Arg; - - Vec4() {} - - Vec4( __m64 v0, __m64 v1 ) : m_v0( v0 ), m_v1( v1 ) {} - - Vec4( Vec4 const& arg ) : m_v0( arg.m_v0 ), m_v1( arg.m_v1 ) {} - - Vec4& operator=( Vec4 const& arg ) - { - m_v0 = arg.m_v0; - m_v1 = arg.m_v1; - return *this; - } - - Vec4( float x, float y, float z, float w ) - { - m_v0 = _mm_set_pi32( *(int *)&x, *(int *)&y ); - m_v1 = _mm_set_pi32( *(int *)&z, *(int *)&w ); - } - -/* Vec3 GetVec3() const - { -#ifdef __GNUC__ - __attribute__ ((__aligned__ (16))) float c[4]; -#else - __declspec(align(16)) float c[4]; -#endif - //_mm_store_ps( c, m_v ); - return Vec3( c[0], c[1], c[2] ); - } -*/ -// Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); } -// Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); } -// Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); } -// Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); } - - Vec4& operator+=( Arg v ) - { - m_v0 = _m_pfadd( m_v0, v.m_v0 ); - m_v1 = _m_pfadd( m_v1, v.m_v1 ); - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_v0 = _m_pfsub( m_v0, v.m_v0 ); - m_v1 = _m_pfsub( m_v1, v.m_v1 ); - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_v0 = _m_pfmul( m_v0, v.m_v0 ); - m_v1 = _m_pfmul( m_v1, v.m_v1 ); - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfadd( left.m_v0, right.m_v0 ), - _m_pfadd( left.m_v1, right.m_v1 )); - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfsub( left.m_v0, right.m_v0 ), - _m_pfsub( left.m_v1, right.m_v1 )); - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfmul( left.m_v0, right.m_v0 ), - _m_pfmul( left.m_v1, right.m_v1 )); - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( - _m_pfadd( _m_pfmul( a.m_v0, b.m_v0 ), c.m_v0 ), - _m_pfadd( _m_pfmul( a.m_v1, b.m_v1 ), c.m_v1 )); - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( - _m_pfsub( c.m_v0, _m_pfmul( a.m_v0, b.m_v0 ) ), - _m_pfsub( c.m_v1, _m_pfmul( a.m_v1, b.m_v1 ) )); - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - // get the reciprocal estimate - __m64 x0 = _m_pfrcp(v.m_v0); - __m64 y1 = _m_pfrcp(v.m_v1); - - // Newton-Rhaphson refinement - __m64 x1 = _m_pfrcpit1(v.m_v0, x0); - __m64 y1 = _m_pfrcpit1(v.m_v1, y0); - - __m64 x2 = _m_pfrcpit2(x1, x0); - __m64 y2 = _m_pfrcpit2(y1, y0); - - return Vec4(x2, y2); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfmin( left.m_v0, right.m_v0 ), - _m_pfmin( left.m_v1, right.m_v1 )); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfmax( left.m_v0, right.m_v0 ), - _m_pfmax( left.m_v1, right.m_v1 )); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { - // convert to ints - __m64 i0 = _m_pf2id( v.m_v0 ); - __m64 i1 = _m_pf2id( v.m_v1 ); - - // convert to floats - __m64 f0 = _m_pi2fd( i0 ); - __m64 f1 = _m_pi2fd( i1 ); - - // clear out the MMX multimedia state to allow FP calls later - //_m_femms(); - - return Vec4( f0, f1 ); - } - - friend Vec4 CompareEqual( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( - _m_pfcmpeq( left.m_v0, right.m_v0 ), - _m_pfcmpeq( left.m_v1, right.m_v1 )); - } -/* - friend Vec4 Select( Vec4::Arg off, Vec4::Arg on, Vec4::Arg bits ) - { - __m128 a = _mm_andnot_ps( bits.m_v, off.m_v ); - __m128 b = _mm_and_ps( bits.m_v, on.m_v ); - - return Vec4( _mm_or_ps( a, b ) ); - } -*//* - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v ); - int value = _mm_movemask_ps( bits ); - return value != 0; - } -*/ -private: - __m64 m_v0; - __m64 m_v1; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_3DNOW_H diff --git a/Externals/NVTT/src/nvtt/squish/simd_sse.h b/Externals/NVTT/src/nvtt/squish/simd_sse.h deleted file mode 100644 index 853ee7ac05b..00000000000 --- a/Externals/NVTT/src/nvtt/squish/simd_sse.h +++ /dev/null @@ -1,193 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SIMD_SSE_H -#define SQUISH_SIMD_SSE_H - -#include -#if ( SQUISH_USE_SSE > 1 ) -#include -#endif -#include - -#define SQUISH_SSE_SPLAT( a ) \ - ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) ) - -namespace squish { - -#define VEC4_CONST( X ) Vec4( _mm_set1_ps( X ) ) - -class Vec4 -{ -public: - typedef Vec4 const& Arg; - - Vec4() {} - - explicit Vec4( __m128 v ) : m_v( v ) {} - - Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} - - Vec4& operator=( Vec4 const& arg ) - { - m_v = arg.m_v; - return *this; - } - - Vec4( const float * v ) - { - m_v = _mm_load_ps( v ); - } - - Vec4( float x, float y, float z, float w ) - { - m_v = _mm_setr_ps( x, y, z, w ); - } - - Vec3 GetVec3() const - { - SQUISH_ALIGN_16 float c[4]; - _mm_store_ps( c, m_v ); - return Vec3( c[0], c[1], c[2] ); - } - - Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); } - Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); } - Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); } - Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); } - - Vec4& operator+=( Arg v ) - { - m_v = _mm_add_ps( m_v, v.m_v ); - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_v = _mm_sub_ps( m_v, v.m_v ); - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_v = _mm_mul_ps( m_v, v.m_v ); - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_add_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_sub_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_mul_ps( left.m_v, right.m_v ) ); - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) ); - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) ); - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - // get the reciprocal estimate - __m128 estimate = _mm_rcp_ps( v.m_v ); - - // one round of Newton-Rhaphson refinement - __m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) ); - return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) ); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_min_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_max_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { -#if ( SQUISH_USE_SSE == 1 ) - // convert to ints - __m128 input = v.m_v; - __m64 lo = _mm_cvttps_pi32( input ); - __m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) ); - - // convert to floats - __m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) ); - __m128 truncated = _mm_cvtpi32_ps( part, lo ); - - // clear out the MMX multimedia state to allow FP calls later - _mm_empty(); - return Vec4( truncated ); -#else - // use SSE2 instructions - return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) ); -#endif - } - - friend Vec4 CompareEqual( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( _mm_cmpeq_ps( left.m_v, right.m_v ) ); - } - - friend Vec4 Select( Vec4::Arg off, Vec4::Arg on, Vec4::Arg bits ) - { - __m128 a = _mm_andnot_ps( bits.m_v, off.m_v ); - __m128 b = _mm_and_ps( bits.m_v, on.m_v ); - - return Vec4( _mm_or_ps( a, b ) ); - } - - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v ); - int value = _mm_movemask_ps( bits ); - return value != 0; - } - -private: - __m128 m_v; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_SSE_H diff --git a/Externals/NVTT/src/nvtt/squish/simd_ve.h b/Externals/NVTT/src/nvtt/squish/simd_ve.h deleted file mode 100644 index 56ed95e0a62..00000000000 --- a/Externals/NVTT/src/nvtt/squish/simd_ve.h +++ /dev/null @@ -1,176 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SIMD_VE_H -#define SQUISH_SIMD_VE_H - -#include -#undef bool - -namespace squish { - -#define VEC4_CONST( X ) Vec4( ( vector float )( X ) ) - -class Vec4 -{ -public: - typedef Vec4 Arg; - - Vec4() {} - - explicit Vec4( vector float v ) : m_v( v ) {} - - Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} - - Vec4& operator=( Vec4 const& arg ) - { - m_v = arg.m_v; - return *this; - } - - Vec4( const float * v ) - { - union { vector float v; float c[4]; } u; - u.c[0] = v[0]; - u.c[1] = v[1]; - u.c[2] = v[2]; - u.c[3] = v[3]; - m_v = u.v; - } - - Vec4( float x, float y, float z, float w ) - { - union { vector float v; float c[4]; } u; - u.c[0] = x; - u.c[1] = y; - u.c[2] = z; - u.c[3] = w; - m_v = u.v; - } - - Vec3 GetVec3() const - { - union { vector float v; float c[4]; } u; - u.v = m_v; - return Vec3( u.c[0], u.c[1], u.c[2] ); - } - - Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); } - Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); } - Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); } - Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); } - - Vec4& operator+=( Arg v ) - { - m_v = vec_add( m_v, v.m_v ); - return *this; - } - - Vec4& operator-=( Arg v ) - { - m_v = vec_sub( m_v, v.m_v ); - return *this; - } - - Vec4& operator*=( Arg v ) - { - m_v = vec_madd( m_v, v.m_v, ( vector float )( -0.0f ) ); - return *this; - } - - friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_add( left.m_v, right.m_v ) ); - } - - friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_sub( left.m_v, right.m_v ) ); - } - - friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_madd( left.m_v, right.m_v, ( vector float )( -0.0f ) ) ); - } - - //! Returns a*b + c - friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) ); - } - - //! Returns -( a*b - c ) - friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) - { - return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) ); - } - - friend Vec4 Reciprocal( Vec4::Arg v ) - { - // get the reciprocal estimate - vector float estimate = vec_re( v.m_v ); - - // one round of Newton-Rhaphson refinement - vector float diff = vec_nmsub( estimate, v.m_v, ( vector float )( 1.0f ) ); - return Vec4( vec_madd( diff, estimate, estimate ) ); - } - - friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_min( left.m_v, right.m_v ) ); - } - - friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( vec_max( left.m_v, right.m_v ) ); - } - - friend Vec4 Truncate( Vec4::Arg v ) - { - return Vec4( vec_trunc( v.m_v ) ); - } - - friend Vec4 CompareEqual( Vec4::Arg left, Vec4::Arg right ) - { - return Vec4( ( vector float )vec_cmpeq( left.m_v, right.m_v ) ); - } - - friend Vec4 Select( Vec4::Arg off, Vec4::Arg on, Vec4::Arg bits ) - { - return Vec4( vec_sel( off.m_v, on.m_v, ( vector unsigned int )bits.m_v ) ); - } - - friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) - { - return vec_any_lt( left.m_v, right.m_v ) != 0; - } - -private: - vector float m_v; -}; - -} // namespace squish - -#endif // ndef SQUISH_SIMD_VE_H diff --git a/Externals/NVTT/src/nvtt/squish/singlechannelfit.cpp b/Externals/NVTT/src/nvtt/squish/singlechannelfit.cpp deleted file mode 100644 index 6070bb5beb8..00000000000 --- a/Externals/NVTT/src/nvtt/squish/singlechannelfit.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2006 Ignacio Castano castanyo@yahoo.es - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "singlechannelfit.h" -#include "colourset.h" -#include "colourblock.h" -#include - -namespace squish { - -SingleChannelFit::SingleChannelFit( ColourSet const* colours, int const flags ) - : ColourFit( /*colours, flags*/ ) -{ - SetColourSet( colours, flags ); - // cache some values - unsigned int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // Find bounds of the search space. - m_g_min = 63; - m_g_max = 0; - - for(unsigned int i = 0; i < count; i++) { - - int grey = int(values[i].Y() * 255.0f); // @@ rounding? - grey = std::min(grey, 255); // clamp to [0, 1) - grey = std::max(grey, 0); - m_greys[i] = u8(grey); - - m_g_min = std::min(m_g_min, grey >> 2); - m_g_max = std::max(m_g_max, grey >> 2); - } - - int const g_pad = m_g_max - m_g_min + 1; - - m_g_min = std::max(0, m_g_min - g_pad); - m_g_max = std::min(63, m_g_max + g_pad); -} - -void SingleChannelFit::Compress3( void* block ) -{ - // do not do anything. -} - -void SingleChannelFit::Compress4( void* block ) -{ - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - - int best_g0; - int best_g1; - float best_error = FLT_MAX; - - // Brute force approach, try all the possible endpoints with g0 > g1. - for(int g0 = m_g_min+1; g0 <= m_g_max; g0++) { - for(int g1 = m_g_min; g1 < g0; g1++) { - - // Compute palette. - const int c0 = (g0 << 2) | (g0 >> 4); - const int c1 = (g1 << 2) | (g1 >> 4); - const int c2 = (2 * c0 + c1) / 3; - const int c3 = (2 * c1 + c0) / 3; - - // Evaluate palette error. - float error = 0; - for(int i = 0; i < count; i++) { - const int grey = m_greys[i]; - - int min_dist = abs(c0 - grey); // Use absolute distance, not squared. - min_dist = std::min(min_dist, abs(c1 - grey)); - min_dist = std::min(min_dist, abs(c2 - grey)); - min_dist = std::min(min_dist, abs(c3 - grey)); - - error += min_dist * weights[i]; - } - - if(error < best_error) { - best_error = error; - best_g0 = g0; - best_g1 = g1; - } - } - } - - // Compute best palette. - const int best_c0 = (best_g0 << 2) | (best_g0 >> 4); - const int best_c1 = (best_g1 << 2) | (best_g1 >> 4); - const int best_c2 = (2 * best_c0 + best_c1) / 3; - const int best_c3 = (2 * best_c1 + best_c0) / 3; - - // Compute best indices. - u8 closest[16]; - for(int i = 0; i < count; i++) { - const int grey = m_greys[i]; - - int dist = abs(best_c0 - grey); - int min_dist = dist; - int min_i = 0; - - dist = abs(best_c1 - grey); - if( dist < min_dist ) { min_dist = dist; min_i = 1; } - - dist = abs(best_c2 - grey); - if( dist < min_dist ) { min_dist = dist; min_i = 2; } - - dist = abs(best_c3 - grey); - if( dist < min_dist ) { min_dist = dist; min_i = 3; } - - closest[i] = min_i; - } - - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( closest, indices ); - - // Output block. - WriteColourBlock(best_g0 << 5, best_g1 << 5, indices, block); -} - - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/singlechannelfit.h b/Externals/NVTT/src/nvtt/squish/singlechannelfit.h deleted file mode 100644 index 40de0a2a225..00000000000 --- a/Externals/NVTT/src/nvtt/squish/singlechannelfit.h +++ /dev/null @@ -1,53 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2006 Ignacio Castano castanyo@yahoo.es - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SINGLECHANNELFIT_H -#define SQUISH_SINGLECHANNELFIT_H - -#include -#include "maths.h" -#include "colourfit.h" - -namespace squish { - -class SingleChannelFit : public ColourFit -{ -public: - SingleChannelFit( ColourSet const* colours, int flags ); - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - -private: - u8 m_greys[16]; - int m_g_min; - int m_g_max; -}; - -} // namespace squish - -#endif // ndef SQUISH_SINGLECHANNELFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/singlecolourfit.cpp b/Externals/NVTT/src/nvtt/squish/singlecolourfit.cpp deleted file mode 100644 index ab5de3cda5e..00000000000 --- a/Externals/NVTT/src/nvtt/squish/singlecolourfit.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include "singlecolourfit.h" -#include "colourset.h" -#include "colourblock.h" - -namespace squish { - -struct SourceBlock -{ - u8 start; - u8 end; - u8 error; -}; - -struct SingleColourLookup -{ - SourceBlock sources[4]; -}; - -#include "singlecolourlookup.inl" - -static int FloatToInt( float a, int limit ) -{ - // use ANSI round-to-zero behaviour to get round-to-nearest - int i = ( int )( a + 0.5f ); - - // clamp to the limit - if( i < 0 ) - i = 0; - else if( i > limit ) - i = limit; - - // done - return i; -} - -SingleColourFit::SingleColourFit( ColourSet const* colours, int flags ) - : ColourFit( /*colours, flags*/ ) -{ - SetColourSet( colours, flags ); - // grab the single colour - Vec3 const* values = m_colours->GetPoints(); - m_colour[0] = ( u8 )FloatToInt( 255.0f*values->X(), 255 ); - m_colour[1] = ( u8 )FloatToInt( 255.0f*values->Y(), 255 ); - m_colour[2] = ( u8 )FloatToInt( 255.0f*values->Z(), 255 ); - - // initialise the best error - m_besterror = INT_MAX; -} - -void SingleColourFit::Compress3( void* block ) -{ - // build the table of lookups - SingleColourLookup const* const lookups[] = - { - lookup_5_3, - lookup_6_3, - lookup_5_3 - }; - - // find the best end-points and index - ComputeEndPoints( 3, lookups ); - - // build the block if we win - if( m_error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( &m_index, indices ); - - // save the block - WriteColourBlock3( m_start, m_end, indices, block ); - - // save the error - m_besterror = m_error; - } -} - -void SingleColourFit::Compress4( void* block ) -{ - // build the table of lookups - SingleColourLookup const* const lookups[] = - { - lookup_5_4, - lookup_6_4, - lookup_5_4 - }; - - // find the best end-points and index - ComputeEndPoints( 4, lookups ); - - // build the block if we win - if( m_error < m_besterror ) - { - // remap the indices - u8 indices[16]; - m_colours->RemapIndices( &m_index, indices ); - - // save the block - WriteColourBlock4( m_start, m_end, indices, block ); - - // save the error - m_besterror = m_error; - } -} - -void SingleColourFit::ComputeEndPoints( int count, SingleColourLookup const* const* lookups ) -{ - // check each index combination - m_error = INT_MAX; - for( int index = 0; index < count; ++index ) - { - // check the error for this codebook index - SourceBlock const* sources[3]; - int error = 0; - for( int channel = 0; channel < 3; ++channel ) - { - // grab the lookup table and index for this channel - SingleColourLookup const* lookup = lookups[channel]; - int target = m_colour[channel]; - - // store a pointer to the source for this channel - sources[channel] = lookup[target].sources + index; - - // accumulate the error - int diff = sources[channel]->error; - error += diff*diff; - } - - // keep it if the error is lower - if( error < m_error ) - { - m_start = Vec3( - ( float )sources[0]->start/31.0f, - ( float )sources[1]->start/63.0f, - ( float )sources[2]->start/31.0f - ); - m_end = Vec3( - ( float )sources[0]->end/31.0f, - ( float )sources[1]->end/63.0f, - ( float )sources[2]->end/31.0f - ); - m_index = ( u8 )index; - m_error = error; - } - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/singlecolourfit.h b/Externals/NVTT/src/nvtt/squish/singlecolourfit.h deleted file mode 100644 index 3c4a1a3845e..00000000000 --- a/Externals/NVTT/src/nvtt/squish/singlecolourfit.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_SINGLECOLOURFIT_H -#define SQUISH_SINGLECOLOURFIT_H - -#include -#include "colourfit.h" - -namespace squish { - -class ColourSet; -struct SingleColourLookup; - -class SingleColourFit : public ColourFit -{ -public: - SingleColourFit( ColourSet const* colours, int flags ); - -private: - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - - void ComputeEndPoints( int count, SingleColourLookup const* const* lookups ); - - u8 m_colour[3]; - Vec3 m_start; - Vec3 m_end; - u8 m_index; - int m_error; - int m_besterror; -}; - -} // namespace squish - -#endif // ndef SQUISH_SINGLECOLOURFIT_H diff --git a/Externals/NVTT/src/nvtt/squish/singlecolourlookup.inl b/Externals/NVTT/src/nvtt/squish/singlecolourlookup.inl deleted file mode 100644 index 52800a82e14..00000000000 --- a/Externals/NVTT/src/nvtt/squish/singlecolourlookup.inl +++ /dev/null @@ -1,1040 +0,0 @@ - -static SingleColourLookup const lookup_5_3[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 0 } } }, - { { { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 0 } } }, - { { { 0, 0, 3 }, { 0, 0, 3 }, { 0, 1, 1 }, { 0, 0, 0 } } }, - { { { 0, 0, 4 }, { 0, 0, 4 }, { 0, 1, 0 }, { 0, 0, 0 } } }, - { { { 1, 0, 3 }, { 0, 1, 3 }, { 0, 1, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 0, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 2, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 2, 0 }, { 0, 0, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 2, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 0, 2, 2 }, { 0, 0, 0 } } }, - { { { 1, 0, 3 }, { 0, 1, 3 }, { 0, 3, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 4 }, { 0, 1, 4 }, { 0, 3, 0 }, { 0, 0, 0 } } }, - { { { 2, 0, 3 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 0, 3, 2 }, { 0, 0, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 4, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 0 }, { 0, 2, 0 }, { 0, 4, 0 }, { 0, 0, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 4, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 0, 4, 2 }, { 0, 0, 0 } } }, - { { { 2, 0, 3 }, { 0, 2, 3 }, { 0, 5, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 4 }, { 0, 2, 4 }, { 0, 5, 0 }, { 0, 0, 0 } } }, - { { { 3, 0, 3 }, { 0, 3, 3 }, { 0, 5, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 5, 2 }, { 0, 0, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 6, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 0 }, { 0, 3, 0 }, { 0, 6, 0 }, { 0, 0, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 6, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 6, 2 }, { 0, 0, 0 } } }, - { { { 3, 0, 3 }, { 0, 3, 3 }, { 0, 7, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 4 }, { 0, 3, 4 }, { 0, 7, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 4 }, { 0, 4, 4 }, { 0, 7, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 3 }, { 0, 4, 3 }, { 0, 7, 2 }, { 0, 0, 0 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 1, 7, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 1, 7, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 8, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 2, 7, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 3 }, { 0, 4, 3 }, { 2, 7, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 4 }, { 0, 4, 4 }, { 0, 9, 0 }, { 0, 0, 0 } } }, - { { { 5, 0, 3 }, { 0, 5, 3 }, { 0, 9, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 3, 7, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 3, 7, 0 }, { 0, 0, 0 } } }, - { { { 5, 0, 0 }, { 0, 5, 0 }, { 0, 10, 0 }, { 0, 0, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 0, 10, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 0, 10, 2 }, { 0, 0, 0 } } }, - { { { 5, 0, 3 }, { 0, 5, 3 }, { 0, 11, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 4 }, { 0, 5, 4 }, { 0, 11, 0 }, { 0, 0, 0 } } }, - { { { 6, 0, 3 }, { 0, 6, 3 }, { 0, 11, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 0, 11, 2 }, { 0, 0, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 12, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 0 }, { 0, 6, 0 }, { 0, 12, 0 }, { 0, 0, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 12, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 0, 12, 2 }, { 0, 0, 0 } } }, - { { { 6, 0, 3 }, { 0, 6, 3 }, { 0, 13, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 4 }, { 0, 6, 4 }, { 0, 13, 0 }, { 0, 0, 0 } } }, - { { { 7, 0, 3 }, { 0, 7, 3 }, { 0, 13, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 0, 13, 2 }, { 0, 0, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 14, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 0 }, { 0, 7, 0 }, { 0, 14, 0 }, { 0, 0, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 14, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 0, 14, 2 }, { 0, 0, 0 } } }, - { { { 7, 0, 3 }, { 0, 7, 3 }, { 0, 15, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 4 }, { 0, 7, 4 }, { 0, 15, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 4 }, { 0, 8, 4 }, { 0, 15, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 3 }, { 0, 8, 3 }, { 0, 15, 2 }, { 0, 0, 0 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 1, 15, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 1, 15, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 16, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 2, 15, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 3 }, { 0, 8, 3 }, { 2, 15, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 4 }, { 0, 8, 4 }, { 0, 17, 0 }, { 0, 0, 0 } } }, - { { { 9, 0, 3 }, { 0, 9, 3 }, { 0, 17, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 3, 15, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 3, 15, 0 }, { 0, 0, 0 } } }, - { { { 9, 0, 0 }, { 0, 9, 0 }, { 0, 18, 0 }, { 0, 0, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 0, 18, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 0, 18, 2 }, { 0, 0, 0 } } }, - { { { 9, 0, 3 }, { 0, 9, 3 }, { 0, 19, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 4 }, { 0, 9, 4 }, { 0, 19, 0 }, { 0, 0, 0 } } }, - { { { 10, 0, 3 }, { 0, 10, 3 }, { 0, 19, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 0, 19, 2 }, { 0, 0, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 20, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 20, 0 }, { 0, 0, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 20, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 0, 20, 2 }, { 0, 0, 0 } } }, - { { { 10, 0, 3 }, { 0, 10, 3 }, { 0, 21, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 4 }, { 0, 10, 4 }, { 0, 21, 0 }, { 0, 0, 0 } } }, - { { { 11, 0, 3 }, { 0, 11, 3 }, { 0, 21, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 0, 21, 2 }, { 0, 0, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 0, 22, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 0 }, { 0, 11, 0 }, { 0, 22, 0 }, { 0, 0, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 0, 22, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 0, 22, 2 }, { 0, 0, 0 } } }, - { { { 11, 0, 3 }, { 0, 11, 3 }, { 0, 23, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 4 }, { 0, 11, 4 }, { 0, 23, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 4 }, { 0, 12, 4 }, { 0, 23, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 3 }, { 0, 12, 3 }, { 0, 23, 2 }, { 0, 0, 0 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 1, 23, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 1, 23, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 0 }, { 0, 12, 0 }, { 0, 24, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 0, 24, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 2, 23, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 3 }, { 0, 12, 3 }, { 2, 23, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 4 }, { 0, 12, 4 }, { 0, 25, 0 }, { 0, 0, 0 } } }, - { { { 13, 0, 3 }, { 0, 13, 3 }, { 0, 25, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 3, 23, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 3, 23, 0 }, { 0, 0, 0 } } }, - { { { 13, 0, 0 }, { 0, 13, 0 }, { 0, 26, 0 }, { 0, 0, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 0, 26, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 0, 26, 2 }, { 0, 0, 0 } } }, - { { { 13, 0, 3 }, { 0, 13, 3 }, { 0, 27, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 4 }, { 0, 13, 4 }, { 0, 27, 0 }, { 0, 0, 0 } } }, - { { { 14, 0, 3 }, { 0, 14, 3 }, { 0, 27, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 0, 27, 2 }, { 0, 0, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 0, 28, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 0 }, { 0, 14, 0 }, { 0, 28, 0 }, { 0, 0, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 0, 28, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 0, 28, 2 }, { 0, 0, 0 } } }, - { { { 14, 0, 3 }, { 0, 14, 3 }, { 0, 29, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 4 }, { 0, 14, 4 }, { 0, 29, 0 }, { 0, 0, 0 } } }, - { { { 15, 0, 3 }, { 0, 15, 3 }, { 0, 29, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 0, 29, 2 }, { 0, 0, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 0, 30, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 0 }, { 0, 15, 0 }, { 0, 30, 0 }, { 0, 0, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 0, 30, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 0, 30, 2 }, { 0, 0, 0 } } }, - { { { 15, 0, 3 }, { 0, 15, 3 }, { 0, 31, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 4 }, { 0, 15, 4 }, { 0, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 4 }, { 0, 16, 4 }, { 0, 31, 1 }, { 0, 0, 0 } } }, - { { { 16, 0, 3 }, { 0, 16, 3 }, { 0, 31, 2 }, { 0, 0, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 1, 31, 1 }, { 0, 0, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 1, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 0 }, { 0, 16, 0 }, { 4, 28, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 4, 28, 1 }, { 0, 0, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 2, 31, 1 }, { 0, 0, 0 } } }, - { { { 16, 0, 3 }, { 0, 16, 3 }, { 2, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 4 }, { 0, 16, 4 }, { 4, 29, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 3 }, { 0, 17, 3 }, { 4, 29, 1 }, { 0, 0, 0 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 3, 31, 1 }, { 0, 0, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 3, 31, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 0 }, { 0, 17, 0 }, { 4, 30, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 4, 30, 1 }, { 0, 0, 0 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 4, 30, 2 }, { 0, 0, 0 } } }, - { { { 17, 0, 3 }, { 0, 17, 3 }, { 4, 31, 1 }, { 0, 0, 0 } } }, - { { { 17, 0, 4 }, { 0, 17, 4 }, { 4, 31, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 3 }, { 0, 18, 3 }, { 4, 31, 1 }, { 0, 0, 0 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 4, 31, 2 }, { 0, 0, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 5, 31, 1 }, { 0, 0, 0 } } }, - { { { 18, 0, 0 }, { 0, 18, 0 }, { 5, 31, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 5, 31, 1 }, { 0, 0, 0 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 5, 31, 2 }, { 0, 0, 0 } } }, - { { { 18, 0, 3 }, { 0, 18, 3 }, { 6, 31, 1 }, { 0, 0, 0 } } }, - { { { 18, 0, 4 }, { 0, 18, 4 }, { 6, 31, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 3 }, { 0, 19, 3 }, { 6, 31, 1 }, { 0, 0, 0 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 6, 31, 2 }, { 0, 0, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 7, 31, 1 }, { 0, 0, 0 } } }, - { { { 19, 0, 0 }, { 0, 19, 0 }, { 7, 31, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 7, 31, 1 }, { 0, 0, 0 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 7, 31, 2 }, { 0, 0, 0 } } }, - { { { 19, 0, 3 }, { 0, 19, 3 }, { 8, 31, 1 }, { 0, 0, 0 } } }, - { { { 19, 0, 4 }, { 0, 19, 4 }, { 8, 31, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 4 }, { 0, 20, 4 }, { 8, 31, 1 }, { 0, 0, 0 } } }, - { { { 20, 0, 3 }, { 0, 20, 3 }, { 8, 31, 2 }, { 0, 0, 0 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 9, 31, 1 }, { 0, 0, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 9, 31, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 0 }, { 0, 20, 0 }, { 12, 28, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 12, 28, 1 }, { 0, 0, 0 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 10, 31, 1 }, { 0, 0, 0 } } }, - { { { 20, 0, 3 }, { 0, 20, 3 }, { 10, 31, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 4 }, { 0, 20, 4 }, { 12, 29, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 3 }, { 0, 21, 3 }, { 12, 29, 1 }, { 0, 0, 0 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 11, 31, 1 }, { 0, 0, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 11, 31, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 0 }, { 0, 21, 0 }, { 12, 30, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 12, 30, 1 }, { 0, 0, 0 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 12, 30, 2 }, { 0, 0, 0 } } }, - { { { 21, 0, 3 }, { 0, 21, 3 }, { 12, 31, 1 }, { 0, 0, 0 } } }, - { { { 21, 0, 4 }, { 0, 21, 4 }, { 12, 31, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 3 }, { 0, 22, 3 }, { 12, 31, 1 }, { 0, 0, 0 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 12, 31, 2 }, { 0, 0, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 13, 31, 1 }, { 0, 0, 0 } } }, - { { { 22, 0, 0 }, { 0, 22, 0 }, { 13, 31, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 13, 31, 1 }, { 0, 0, 0 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 13, 31, 2 }, { 0, 0, 0 } } }, - { { { 22, 0, 3 }, { 0, 22, 3 }, { 14, 31, 1 }, { 0, 0, 0 } } }, - { { { 22, 0, 4 }, { 0, 22, 4 }, { 14, 31, 0 }, { 0, 0, 0 } } }, - { { { 23, 0, 3 }, { 0, 23, 3 }, { 14, 31, 1 }, { 0, 0, 0 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 14, 31, 2 }, { 0, 0, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 15, 31, 1 }, { 0, 0, 0 } } }, - { { { 23, 0, 0 }, { 0, 23, 0 }, { 15, 31, 0 }, { 0, 0, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 15, 31, 1 }, { 0, 0, 0 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 15, 31, 2 }, { 0, 0, 0 } } }, - { { { 23, 0, 3 }, { 0, 23, 3 }, { 16, 31, 1 }, { 0, 0, 0 } } }, - { { { 23, 0, 4 }, { 0, 23, 4 }, { 16, 31, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 4 }, { 0, 24, 4 }, { 16, 31, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 3 }, { 0, 24, 3 }, { 16, 31, 2 }, { 0, 0, 0 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 17, 31, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 17, 31, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 0 }, { 0, 24, 0 }, { 20, 28, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 20, 28, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 18, 31, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 3 }, { 0, 24, 3 }, { 18, 31, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 4 }, { 0, 24, 4 }, { 20, 29, 0 }, { 0, 0, 0 } } }, - { { { 25, 0, 3 }, { 0, 25, 3 }, { 20, 29, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 19, 31, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 19, 31, 0 }, { 0, 0, 0 } } }, - { { { 25, 0, 0 }, { 0, 25, 0 }, { 20, 30, 0 }, { 0, 0, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 20, 30, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 20, 30, 2 }, { 0, 0, 0 } } }, - { { { 25, 0, 3 }, { 0, 25, 3 }, { 20, 31, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 4 }, { 0, 25, 4 }, { 20, 31, 0 }, { 0, 0, 0 } } }, - { { { 26, 0, 3 }, { 0, 26, 3 }, { 20, 31, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 20, 31, 2 }, { 0, 0, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 21, 31, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 0 }, { 0, 26, 0 }, { 21, 31, 0 }, { 0, 0, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 21, 31, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 21, 31, 2 }, { 0, 0, 0 } } }, - { { { 26, 0, 3 }, { 0, 26, 3 }, { 22, 31, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 4 }, { 0, 26, 4 }, { 22, 31, 0 }, { 0, 0, 0 } } }, - { { { 27, 0, 3 }, { 0, 27, 3 }, { 22, 31, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 22, 31, 2 }, { 0, 0, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 23, 31, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 0 }, { 0, 27, 0 }, { 23, 31, 0 }, { 0, 0, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 23, 31, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 23, 31, 2 }, { 0, 0, 0 } } }, - { { { 27, 0, 3 }, { 0, 27, 3 }, { 24, 31, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 4 }, { 0, 27, 4 }, { 24, 31, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 4 }, { 0, 28, 4 }, { 24, 31, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 3 }, { 0, 28, 3 }, { 24, 31, 2 }, { 0, 0, 0 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 25, 31, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 25, 31, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 0 }, { 0, 28, 0 }, { 28, 28, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 28, 28, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 26, 31, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 3 }, { 0, 28, 3 }, { 26, 31, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 4 }, { 0, 28, 4 }, { 28, 29, 0 }, { 0, 0, 0 } } }, - { { { 29, 0, 3 }, { 0, 29, 3 }, { 28, 29, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 27, 31, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 27, 31, 0 }, { 0, 0, 0 } } }, - { { { 29, 0, 0 }, { 0, 29, 0 }, { 28, 30, 0 }, { 0, 0, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 28, 30, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 28, 30, 2 }, { 0, 0, 0 } } }, - { { { 29, 0, 3 }, { 0, 29, 3 }, { 28, 31, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 4 }, { 0, 29, 4 }, { 28, 31, 0 }, { 0, 0, 0 } } }, - { { { 30, 0, 3 }, { 0, 30, 3 }, { 28, 31, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 28, 31, 2 }, { 0, 0, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 29, 31, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 0 }, { 0, 30, 0 }, { 29, 31, 0 }, { 0, 0, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 29, 31, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 29, 31, 2 }, { 0, 0, 0 } } }, - { { { 30, 0, 3 }, { 0, 30, 3 }, { 30, 31, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 4 }, { 0, 30, 4 }, { 30, 31, 0 }, { 0, 0, 0 } } }, - { { { 31, 0, 3 }, { 0, 31, 3 }, { 30, 31, 1 }, { 0, 0, 0 } } }, - { { { 31, 0, 2 }, { 0, 31, 2 }, { 30, 31, 2 }, { 0, 0, 0 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 31, 31, 1 }, { 0, 0, 0 } } }, - { { { 31, 0, 0 }, { 0, 31, 0 }, { 31, 31, 0 }, { 0, 0, 0 } } } -}; - -static SingleColourLookup const lookup_6_3[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 0, 0 } } }, - { { { 0, 0, 2 }, { 0, 0, 2 }, { 0, 1, 0 }, { 0, 0, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 2, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 2, 0 }, { 0, 0, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 3, 1 }, { 0, 0, 0 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 0, 3, 0 }, { 0, 0, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 4, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 0 }, { 0, 2, 0 }, { 0, 4, 0 }, { 0, 0, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 5, 1 }, { 0, 0, 0 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 0, 5, 0 }, { 0, 0, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 6, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 0 }, { 0, 3, 0 }, { 0, 6, 0 }, { 0, 0, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 7, 1 }, { 0, 0, 0 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 7, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 8, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 0, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 9, 1 }, { 0, 0, 0 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 0, 9, 0 }, { 0, 0, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 0, 10, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 0 }, { 0, 5, 0 }, { 0, 10, 0 }, { 0, 0, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 0, 11, 1 }, { 0, 0, 0 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 0, 11, 0 }, { 0, 0, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 12, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 0 }, { 0, 6, 0 }, { 0, 12, 0 }, { 0, 0, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 13, 1 }, { 0, 0, 0 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 0, 13, 0 }, { 0, 0, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 14, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 0 }, { 0, 7, 0 }, { 0, 14, 0 }, { 0, 0, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 15, 1 }, { 0, 0, 0 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 0, 15, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 16, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 0, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 17, 1 }, { 0, 0, 0 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 0, 17, 0 }, { 0, 0, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 0, 18, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 0 }, { 0, 9, 0 }, { 0, 18, 0 }, { 0, 0, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 0, 19, 1 }, { 0, 0, 0 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 0, 19, 0 }, { 0, 0, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 20, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 20, 0 }, { 0, 0, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 21, 1 }, { 0, 0, 0 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 0, 21, 0 }, { 0, 0, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 0, 22, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 0 }, { 0, 11, 0 }, { 0, 22, 0 }, { 0, 0, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 0, 23, 1 }, { 0, 0, 0 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 0, 23, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 0, 24, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 0 }, { 0, 12, 0 }, { 0, 24, 0 }, { 0, 0, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 0, 25, 1 }, { 0, 0, 0 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 0, 25, 0 }, { 0, 0, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 0, 26, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 0 }, { 0, 13, 0 }, { 0, 26, 0 }, { 0, 0, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 0, 27, 1 }, { 0, 0, 0 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 0, 27, 0 }, { 0, 0, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 0, 28, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 0 }, { 0, 14, 0 }, { 0, 28, 0 }, { 0, 0, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 0, 29, 1 }, { 0, 0, 0 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 0, 29, 0 }, { 0, 0, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 0, 30, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 0 }, { 0, 15, 0 }, { 0, 30, 0 }, { 0, 0, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 0, 31, 1 }, { 0, 0, 0 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 0, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 1, 31, 1 }, { 0, 0, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 1, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 0 }, { 0, 16, 0 }, { 0, 32, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 2, 31, 0 }, { 0, 0, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 0, 33, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 3, 31, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 0 }, { 0, 17, 0 }, { 0, 34, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 4, 31, 0 }, { 0, 0, 0 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 0, 35, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 5, 31, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 0 }, { 0, 18, 0 }, { 0, 36, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 6, 31, 0 }, { 0, 0, 0 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 0, 37, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 7, 31, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 0 }, { 0, 19, 0 }, { 0, 38, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 8, 31, 0 }, { 0, 0, 0 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 0, 39, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 9, 31, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 0 }, { 0, 20, 0 }, { 0, 40, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 10, 31, 0 }, { 0, 0, 0 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 0, 41, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 11, 31, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 0 }, { 0, 21, 0 }, { 0, 42, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 12, 31, 0 }, { 0, 0, 0 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 0, 43, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 13, 31, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 0 }, { 0, 22, 0 }, { 0, 44, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 14, 31, 0 }, { 0, 0, 0 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 0, 45, 0 }, { 0, 0, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 15, 31, 0 }, { 0, 0, 0 } } }, - { { { 23, 0, 0 }, { 0, 23, 0 }, { 0, 46, 0 }, { 0, 0, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 0, 47, 1 }, { 0, 0, 0 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 0, 47, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 0, 48, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 0 }, { 0, 24, 0 }, { 0, 48, 0 }, { 0, 0, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 0, 49, 1 }, { 0, 0, 0 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 0, 49, 0 }, { 0, 0, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 0, 50, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 0 }, { 0, 25, 0 }, { 0, 50, 0 }, { 0, 0, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 0, 51, 1 }, { 0, 0, 0 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 0, 51, 0 }, { 0, 0, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 0, 52, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 0 }, { 0, 26, 0 }, { 0, 52, 0 }, { 0, 0, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 0, 53, 1 }, { 0, 0, 0 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 0, 53, 0 }, { 0, 0, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 0, 54, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 0 }, { 0, 27, 0 }, { 0, 54, 0 }, { 0, 0, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 0, 55, 1 }, { 0, 0, 0 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 0, 55, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 0, 56, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 0 }, { 0, 28, 0 }, { 0, 56, 0 }, { 0, 0, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 0, 57, 1 }, { 0, 0, 0 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 0, 57, 0 }, { 0, 0, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 0, 58, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 0 }, { 0, 29, 0 }, { 0, 58, 0 }, { 0, 0, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 0, 59, 1 }, { 0, 0, 0 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 0, 59, 0 }, { 0, 0, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 0, 60, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 0 }, { 0, 30, 0 }, { 0, 60, 0 }, { 0, 0, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 0, 61, 1 }, { 0, 0, 0 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 0, 61, 0 }, { 0, 0, 0 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 0, 62, 1 }, { 0, 0, 0 } } }, - { { { 31, 0, 0 }, { 0, 31, 0 }, { 0, 62, 0 }, { 0, 0, 0 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 0, 63, 1 }, { 0, 0, 0 } } }, - { { { 31, 0, 2 }, { 0, 31, 2 }, { 0, 63, 0 }, { 0, 0, 0 } } }, - { { { 32, 0, 2 }, { 0, 32, 2 }, { 1, 63, 1 }, { 0, 0, 0 } } }, - { { { 32, 0, 1 }, { 0, 32, 1 }, { 1, 63, 0 }, { 0, 0, 0 } } }, - { { { 32, 0, 0 }, { 0, 32, 0 }, { 16, 48, 0 }, { 0, 0, 0 } } }, - { { { 32, 0, 1 }, { 0, 32, 1 }, { 2, 63, 0 }, { 0, 0, 0 } } }, - { { { 32, 0, 2 }, { 0, 32, 2 }, { 16, 49, 0 }, { 0, 0, 0 } } }, - { { { 33, 0, 1 }, { 0, 33, 1 }, { 3, 63, 0 }, { 0, 0, 0 } } }, - { { { 33, 0, 0 }, { 0, 33, 0 }, { 16, 50, 0 }, { 0, 0, 0 } } }, - { { { 33, 0, 1 }, { 0, 33, 1 }, { 4, 63, 0 }, { 0, 0, 0 } } }, - { { { 33, 0, 2 }, { 0, 33, 2 }, { 16, 51, 0 }, { 0, 0, 0 } } }, - { { { 34, 0, 1 }, { 0, 34, 1 }, { 5, 63, 0 }, { 0, 0, 0 } } }, - { { { 34, 0, 0 }, { 0, 34, 0 }, { 16, 52, 0 }, { 0, 0, 0 } } }, - { { { 34, 0, 1 }, { 0, 34, 1 }, { 6, 63, 0 }, { 0, 0, 0 } } }, - { { { 34, 0, 2 }, { 0, 34, 2 }, { 16, 53, 0 }, { 0, 0, 0 } } }, - { { { 35, 0, 1 }, { 0, 35, 1 }, { 7, 63, 0 }, { 0, 0, 0 } } }, - { { { 35, 0, 0 }, { 0, 35, 0 }, { 16, 54, 0 }, { 0, 0, 0 } } }, - { { { 35, 0, 1 }, { 0, 35, 1 }, { 8, 63, 0 }, { 0, 0, 0 } } }, - { { { 35, 0, 2 }, { 0, 35, 2 }, { 16, 55, 0 }, { 0, 0, 0 } } }, - { { { 36, 0, 1 }, { 0, 36, 1 }, { 9, 63, 0 }, { 0, 0, 0 } } }, - { { { 36, 0, 0 }, { 0, 36, 0 }, { 16, 56, 0 }, { 0, 0, 0 } } }, - { { { 36, 0, 1 }, { 0, 36, 1 }, { 10, 63, 0 }, { 0, 0, 0 } } }, - { { { 36, 0, 2 }, { 0, 36, 2 }, { 16, 57, 0 }, { 0, 0, 0 } } }, - { { { 37, 0, 1 }, { 0, 37, 1 }, { 11, 63, 0 }, { 0, 0, 0 } } }, - { { { 37, 0, 0 }, { 0, 37, 0 }, { 16, 58, 0 }, { 0, 0, 0 } } }, - { { { 37, 0, 1 }, { 0, 37, 1 }, { 12, 63, 0 }, { 0, 0, 0 } } }, - { { { 37, 0, 2 }, { 0, 37, 2 }, { 16, 59, 0 }, { 0, 0, 0 } } }, - { { { 38, 0, 1 }, { 0, 38, 1 }, { 13, 63, 0 }, { 0, 0, 0 } } }, - { { { 38, 0, 0 }, { 0, 38, 0 }, { 16, 60, 0 }, { 0, 0, 0 } } }, - { { { 38, 0, 1 }, { 0, 38, 1 }, { 14, 63, 0 }, { 0, 0, 0 } } }, - { { { 38, 0, 2 }, { 0, 38, 2 }, { 16, 61, 0 }, { 0, 0, 0 } } }, - { { { 39, 0, 1 }, { 0, 39, 1 }, { 15, 63, 0 }, { 0, 0, 0 } } }, - { { { 39, 0, 0 }, { 0, 39, 0 }, { 16, 62, 0 }, { 0, 0, 0 } } }, - { { { 39, 0, 1 }, { 0, 39, 1 }, { 16, 63, 1 }, { 0, 0, 0 } } }, - { { { 39, 0, 2 }, { 0, 39, 2 }, { 16, 63, 0 }, { 0, 0, 0 } } }, - { { { 40, 0, 1 }, { 0, 40, 1 }, { 17, 63, 1 }, { 0, 0, 0 } } }, - { { { 40, 0, 0 }, { 0, 40, 0 }, { 17, 63, 0 }, { 0, 0, 0 } } }, - { { { 40, 0, 1 }, { 0, 40, 1 }, { 18, 63, 1 }, { 0, 0, 0 } } }, - { { { 40, 0, 2 }, { 0, 40, 2 }, { 18, 63, 0 }, { 0, 0, 0 } } }, - { { { 41, 0, 1 }, { 0, 41, 1 }, { 19, 63, 1 }, { 0, 0, 0 } } }, - { { { 41, 0, 0 }, { 0, 41, 0 }, { 19, 63, 0 }, { 0, 0, 0 } } }, - { { { 41, 0, 1 }, { 0, 41, 1 }, { 20, 63, 1 }, { 0, 0, 0 } } }, - { { { 41, 0, 2 }, { 0, 41, 2 }, { 20, 63, 0 }, { 0, 0, 0 } } }, - { { { 42, 0, 1 }, { 0, 42, 1 }, { 21, 63, 1 }, { 0, 0, 0 } } }, - { { { 42, 0, 0 }, { 0, 42, 0 }, { 21, 63, 0 }, { 0, 0, 0 } } }, - { { { 42, 0, 1 }, { 0, 42, 1 }, { 22, 63, 1 }, { 0, 0, 0 } } }, - { { { 42, 0, 2 }, { 0, 42, 2 }, { 22, 63, 0 }, { 0, 0, 0 } } }, - { { { 43, 0, 1 }, { 0, 43, 1 }, { 23, 63, 1 }, { 0, 0, 0 } } }, - { { { 43, 0, 0 }, { 0, 43, 0 }, { 23, 63, 0 }, { 0, 0, 0 } } }, - { { { 43, 0, 1 }, { 0, 43, 1 }, { 24, 63, 1 }, { 0, 0, 0 } } }, - { { { 43, 0, 2 }, { 0, 43, 2 }, { 24, 63, 0 }, { 0, 0, 0 } } }, - { { { 44, 0, 1 }, { 0, 44, 1 }, { 25, 63, 1 }, { 0, 0, 0 } } }, - { { { 44, 0, 0 }, { 0, 44, 0 }, { 25, 63, 0 }, { 0, 0, 0 } } }, - { { { 44, 0, 1 }, { 0, 44, 1 }, { 26, 63, 1 }, { 0, 0, 0 } } }, - { { { 44, 0, 2 }, { 0, 44, 2 }, { 26, 63, 0 }, { 0, 0, 0 } } }, - { { { 45, 0, 1 }, { 0, 45, 1 }, { 27, 63, 1 }, { 0, 0, 0 } } }, - { { { 45, 0, 0 }, { 0, 45, 0 }, { 27, 63, 0 }, { 0, 0, 0 } } }, - { { { 45, 0, 1 }, { 0, 45, 1 }, { 28, 63, 1 }, { 0, 0, 0 } } }, - { { { 45, 0, 2 }, { 0, 45, 2 }, { 28, 63, 0 }, { 0, 0, 0 } } }, - { { { 46, 0, 1 }, { 0, 46, 1 }, { 29, 63, 1 }, { 0, 0, 0 } } }, - { { { 46, 0, 0 }, { 0, 46, 0 }, { 29, 63, 0 }, { 0, 0, 0 } } }, - { { { 46, 0, 1 }, { 0, 46, 1 }, { 30, 63, 1 }, { 0, 0, 0 } } }, - { { { 46, 0, 2 }, { 0, 46, 2 }, { 30, 63, 0 }, { 0, 0, 0 } } }, - { { { 47, 0, 1 }, { 0, 47, 1 }, { 31, 63, 1 }, { 0, 0, 0 } } }, - { { { 47, 0, 0 }, { 0, 47, 0 }, { 31, 63, 0 }, { 0, 0, 0 } } }, - { { { 47, 0, 1 }, { 0, 47, 1 }, { 32, 63, 1 }, { 0, 0, 0 } } }, - { { { 47, 0, 2 }, { 0, 47, 2 }, { 32, 63, 0 }, { 0, 0, 0 } } }, - { { { 48, 0, 2 }, { 0, 48, 2 }, { 33, 63, 1 }, { 0, 0, 0 } } }, - { { { 48, 0, 1 }, { 0, 48, 1 }, { 33, 63, 0 }, { 0, 0, 0 } } }, - { { { 48, 0, 0 }, { 0, 48, 0 }, { 48, 48, 0 }, { 0, 0, 0 } } }, - { { { 48, 0, 1 }, { 0, 48, 1 }, { 34, 63, 0 }, { 0, 0, 0 } } }, - { { { 48, 0, 2 }, { 0, 48, 2 }, { 48, 49, 0 }, { 0, 0, 0 } } }, - { { { 49, 0, 1 }, { 0, 49, 1 }, { 35, 63, 0 }, { 0, 0, 0 } } }, - { { { 49, 0, 0 }, { 0, 49, 0 }, { 48, 50, 0 }, { 0, 0, 0 } } }, - { { { 49, 0, 1 }, { 0, 49, 1 }, { 36, 63, 0 }, { 0, 0, 0 } } }, - { { { 49, 0, 2 }, { 0, 49, 2 }, { 48, 51, 0 }, { 0, 0, 0 } } }, - { { { 50, 0, 1 }, { 0, 50, 1 }, { 37, 63, 0 }, { 0, 0, 0 } } }, - { { { 50, 0, 0 }, { 0, 50, 0 }, { 48, 52, 0 }, { 0, 0, 0 } } }, - { { { 50, 0, 1 }, { 0, 50, 1 }, { 38, 63, 0 }, { 0, 0, 0 } } }, - { { { 50, 0, 2 }, { 0, 50, 2 }, { 48, 53, 0 }, { 0, 0, 0 } } }, - { { { 51, 0, 1 }, { 0, 51, 1 }, { 39, 63, 0 }, { 0, 0, 0 } } }, - { { { 51, 0, 0 }, { 0, 51, 0 }, { 48, 54, 0 }, { 0, 0, 0 } } }, - { { { 51, 0, 1 }, { 0, 51, 1 }, { 40, 63, 0 }, { 0, 0, 0 } } }, - { { { 51, 0, 2 }, { 0, 51, 2 }, { 48, 55, 0 }, { 0, 0, 0 } } }, - { { { 52, 0, 1 }, { 0, 52, 1 }, { 41, 63, 0 }, { 0, 0, 0 } } }, - { { { 52, 0, 0 }, { 0, 52, 0 }, { 48, 56, 0 }, { 0, 0, 0 } } }, - { { { 52, 0, 1 }, { 0, 52, 1 }, { 42, 63, 0 }, { 0, 0, 0 } } }, - { { { 52, 0, 2 }, { 0, 52, 2 }, { 48, 57, 0 }, { 0, 0, 0 } } }, - { { { 53, 0, 1 }, { 0, 53, 1 }, { 43, 63, 0 }, { 0, 0, 0 } } }, - { { { 53, 0, 0 }, { 0, 53, 0 }, { 48, 58, 0 }, { 0, 0, 0 } } }, - { { { 53, 0, 1 }, { 0, 53, 1 }, { 44, 63, 0 }, { 0, 0, 0 } } }, - { { { 53, 0, 2 }, { 0, 53, 2 }, { 48, 59, 0 }, { 0, 0, 0 } } }, - { { { 54, 0, 1 }, { 0, 54, 1 }, { 45, 63, 0 }, { 0, 0, 0 } } }, - { { { 54, 0, 0 }, { 0, 54, 0 }, { 48, 60, 0 }, { 0, 0, 0 } } }, - { { { 54, 0, 1 }, { 0, 54, 1 }, { 46, 63, 0 }, { 0, 0, 0 } } }, - { { { 54, 0, 2 }, { 0, 54, 2 }, { 48, 61, 0 }, { 0, 0, 0 } } }, - { { { 55, 0, 1 }, { 0, 55, 1 }, { 47, 63, 0 }, { 0, 0, 0 } } }, - { { { 55, 0, 0 }, { 0, 55, 0 }, { 48, 62, 0 }, { 0, 0, 0 } } }, - { { { 55, 0, 1 }, { 0, 55, 1 }, { 48, 63, 1 }, { 0, 0, 0 } } }, - { { { 55, 0, 2 }, { 0, 55, 2 }, { 48, 63, 0 }, { 0, 0, 0 } } }, - { { { 56, 0, 1 }, { 0, 56, 1 }, { 49, 63, 1 }, { 0, 0, 0 } } }, - { { { 56, 0, 0 }, { 0, 56, 0 }, { 49, 63, 0 }, { 0, 0, 0 } } }, - { { { 56, 0, 1 }, { 0, 56, 1 }, { 50, 63, 1 }, { 0, 0, 0 } } }, - { { { 56, 0, 2 }, { 0, 56, 2 }, { 50, 63, 0 }, { 0, 0, 0 } } }, - { { { 57, 0, 1 }, { 0, 57, 1 }, { 51, 63, 1 }, { 0, 0, 0 } } }, - { { { 57, 0, 0 }, { 0, 57, 0 }, { 51, 63, 0 }, { 0, 0, 0 } } }, - { { { 57, 0, 1 }, { 0, 57, 1 }, { 52, 63, 1 }, { 0, 0, 0 } } }, - { { { 57, 0, 2 }, { 0, 57, 2 }, { 52, 63, 0 }, { 0, 0, 0 } } }, - { { { 58, 0, 1 }, { 0, 58, 1 }, { 53, 63, 1 }, { 0, 0, 0 } } }, - { { { 58, 0, 0 }, { 0, 58, 0 }, { 53, 63, 0 }, { 0, 0, 0 } } }, - { { { 58, 0, 1 }, { 0, 58, 1 }, { 54, 63, 1 }, { 0, 0, 0 } } }, - { { { 58, 0, 2 }, { 0, 58, 2 }, { 54, 63, 0 }, { 0, 0, 0 } } }, - { { { 59, 0, 1 }, { 0, 59, 1 }, { 55, 63, 1 }, { 0, 0, 0 } } }, - { { { 59, 0, 0 }, { 0, 59, 0 }, { 55, 63, 0 }, { 0, 0, 0 } } }, - { { { 59, 0, 1 }, { 0, 59, 1 }, { 56, 63, 1 }, { 0, 0, 0 } } }, - { { { 59, 0, 2 }, { 0, 59, 2 }, { 56, 63, 0 }, { 0, 0, 0 } } }, - { { { 60, 0, 1 }, { 0, 60, 1 }, { 57, 63, 1 }, { 0, 0, 0 } } }, - { { { 60, 0, 0 }, { 0, 60, 0 }, { 57, 63, 0 }, { 0, 0, 0 } } }, - { { { 60, 0, 1 }, { 0, 60, 1 }, { 58, 63, 1 }, { 0, 0, 0 } } }, - { { { 60, 0, 2 }, { 0, 60, 2 }, { 58, 63, 0 }, { 0, 0, 0 } } }, - { { { 61, 0, 1 }, { 0, 61, 1 }, { 59, 63, 1 }, { 0, 0, 0 } } }, - { { { 61, 0, 0 }, { 0, 61, 0 }, { 59, 63, 0 }, { 0, 0, 0 } } }, - { { { 61, 0, 1 }, { 0, 61, 1 }, { 60, 63, 1 }, { 0, 0, 0 } } }, - { { { 61, 0, 2 }, { 0, 61, 2 }, { 60, 63, 0 }, { 0, 0, 0 } } }, - { { { 62, 0, 1 }, { 0, 62, 1 }, { 61, 63, 1 }, { 0, 0, 0 } } }, - { { { 62, 0, 0 }, { 0, 62, 0 }, { 61, 63, 0 }, { 0, 0, 0 } } }, - { { { 62, 0, 1 }, { 0, 62, 1 }, { 62, 63, 1 }, { 0, 0, 0 } } }, - { { { 62, 0, 2 }, { 0, 62, 2 }, { 62, 63, 0 }, { 0, 0, 0 } } }, - { { { 63, 0, 1 }, { 0, 63, 1 }, { 63, 63, 1 }, { 0, 0, 0 } } }, - { { { 63, 0, 0 }, { 0, 63, 0 }, { 63, 63, 0 }, { 0, 0, 0 } } } -}; - -static SingleColourLookup const lookup_5_4[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 1, 0, 1 } } }, - { { { 0, 0, 2 }, { 0, 0, 2 }, { 0, 1, 0 }, { 1, 0, 0 } } }, - { { { 0, 0, 3 }, { 0, 0, 3 }, { 0, 1, 1 }, { 1, 0, 1 } } }, - { { { 0, 0, 4 }, { 0, 0, 4 }, { 0, 2, 1 }, { 0, 1, 1 } } }, - { { { 1, 0, 3 }, { 0, 1, 3 }, { 0, 2, 0 }, { 0, 1, 0 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 1 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 3, 1 }, { 1, 1, 1 } } }, - { { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 3, 0 }, { 1, 1, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 1, 2, 1 }, { 0, 2, 1 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 1, 2, 0 }, { 0, 2, 0 } } }, - { { { 1, 0, 3 }, { 0, 1, 3 }, { 0, 4, 0 }, { 4, 0, 0 } } }, - { { { 1, 0, 4 }, { 0, 1, 4 }, { 0, 5, 1 }, { 1, 2, 1 } } }, - { { { 2, 0, 3 }, { 0, 2, 3 }, { 0, 5, 0 }, { 1, 2, 0 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 0, 5, 1 }, { 1, 2, 1 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 6, 1 }, { 0, 3, 1 } } }, - { { { 2, 0, 0 }, { 0, 2, 0 }, { 0, 6, 0 }, { 0, 3, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 2, 3, 1 }, { 1, 3, 1 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 2, 3, 0 }, { 1, 3, 0 } } }, - { { { 2, 0, 3 }, { 0, 2, 3 }, { 0, 7, 0 }, { 5, 1, 0 } } }, - { { { 2, 0, 4 }, { 0, 2, 4 }, { 1, 6, 1 }, { 2, 3, 1 } } }, - { { { 3, 0, 3 }, { 0, 3, 3 }, { 1, 6, 0 }, { 2, 3, 0 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 8, 0 }, { 0, 4, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 9, 1 }, { 1, 4, 1 } } }, - { { { 3, 0, 0 }, { 0, 3, 0 }, { 0, 9, 0 }, { 1, 4, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 9, 1 }, { 1, 4, 1 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 10, 1 }, { 0, 5, 1 } } }, - { { { 3, 0, 3 }, { 0, 3, 3 }, { 0, 10, 0 }, { 0, 5, 0 } } }, - { { { 3, 0, 4 }, { 0, 3, 4 }, { 2, 7, 1 }, { 5, 3, 1 } } }, - { { { 4, 0, 4 }, { 0, 4, 4 }, { 2, 7, 0 }, { 5, 3, 0 } } }, - { { { 4, 0, 3 }, { 0, 4, 3 }, { 0, 11, 0 }, { 1, 5, 0 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 1, 10, 1 }, { 0, 6, 1 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 1, 10, 0 }, { 0, 6, 0 } } }, - { { { 4, 0, 0 }, { 0, 4, 0 }, { 0, 12, 0 }, { 4, 4, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 13, 1 }, { 1, 6, 1 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 0, 13, 0 }, { 1, 6, 0 } } }, - { { { 4, 0, 3 }, { 0, 4, 3 }, { 0, 13, 1 }, { 1, 6, 1 } } }, - { { { 4, 0, 4 }, { 0, 4, 4 }, { 0, 14, 1 }, { 0, 7, 1 } } }, - { { { 5, 0, 3 }, { 0, 5, 3 }, { 0, 14, 0 }, { 0, 7, 0 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 2, 11, 1 }, { 1, 7, 1 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 2, 11, 0 }, { 1, 7, 0 } } }, - { { { 5, 0, 0 }, { 0, 5, 0 }, { 0, 15, 0 }, { 5, 5, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 1, 14, 1 }, { 2, 7, 1 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 1, 14, 0 }, { 2, 7, 0 } } }, - { { { 5, 0, 3 }, { 0, 5, 3 }, { 0, 16, 0 }, { 0, 8, 0 } } }, - { { { 5, 0, 4 }, { 0, 5, 4 }, { 0, 17, 1 }, { 1, 8, 1 } } }, - { { { 6, 0, 3 }, { 0, 6, 3 }, { 0, 17, 0 }, { 1, 8, 0 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 0, 17, 1 }, { 1, 8, 1 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 18, 1 }, { 0, 9, 1 } } }, - { { { 6, 0, 0 }, { 0, 6, 0 }, { 0, 18, 0 }, { 0, 9, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 2, 15, 1 }, { 5, 7, 1 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 2, 15, 0 }, { 5, 7, 0 } } }, - { { { 6, 0, 3 }, { 0, 6, 3 }, { 0, 19, 0 }, { 1, 9, 0 } } }, - { { { 6, 0, 4 }, { 0, 6, 4 }, { 1, 18, 1 }, { 0, 10, 1 } } }, - { { { 7, 0, 3 }, { 0, 7, 3 }, { 1, 18, 0 }, { 0, 10, 0 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 0, 20, 0 }, { 4, 8, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 21, 1 }, { 1, 10, 1 } } }, - { { { 7, 0, 0 }, { 0, 7, 0 }, { 0, 21, 0 }, { 1, 10, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 21, 1 }, { 1, 10, 1 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 0, 22, 1 }, { 0, 11, 1 } } }, - { { { 7, 0, 3 }, { 0, 7, 3 }, { 0, 22, 0 }, { 0, 11, 0 } } }, - { { { 7, 0, 4 }, { 0, 7, 4 }, { 2, 19, 1 }, { 1, 11, 1 } } }, - { { { 8, 0, 4 }, { 0, 8, 4 }, { 2, 19, 0 }, { 1, 11, 0 } } }, - { { { 8, 0, 3 }, { 0, 8, 3 }, { 0, 23, 0 }, { 5, 9, 0 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 1, 22, 1 }, { 2, 11, 1 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 1, 22, 0 }, { 2, 11, 0 } } }, - { { { 8, 0, 0 }, { 0, 8, 0 }, { 0, 24, 0 }, { 0, 12, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 25, 1 }, { 1, 12, 1 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 0, 25, 0 }, { 1, 12, 0 } } }, - { { { 8, 0, 3 }, { 0, 8, 3 }, { 0, 25, 1 }, { 1, 12, 1 } } }, - { { { 8, 0, 4 }, { 0, 8, 4 }, { 0, 26, 1 }, { 0, 13, 1 } } }, - { { { 9, 0, 3 }, { 0, 9, 3 }, { 0, 26, 0 }, { 0, 13, 0 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 2, 23, 1 }, { 5, 11, 1 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 2, 23, 0 }, { 5, 11, 0 } } }, - { { { 9, 0, 0 }, { 0, 9, 0 }, { 0, 27, 0 }, { 1, 13, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 1, 26, 1 }, { 0, 14, 1 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 1, 26, 0 }, { 0, 14, 0 } } }, - { { { 9, 0, 3 }, { 0, 9, 3 }, { 0, 28, 0 }, { 4, 12, 0 } } }, - { { { 9, 0, 4 }, { 0, 9, 4 }, { 0, 29, 1 }, { 1, 14, 1 } } }, - { { { 10, 0, 3 }, { 0, 10, 3 }, { 0, 29, 0 }, { 1, 14, 0 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 0, 29, 1 }, { 1, 14, 1 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 30, 1 }, { 0, 15, 1 } } }, - { { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 30, 0 }, { 0, 15, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 2, 27, 1 }, { 1, 15, 1 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 2, 27, 0 }, { 1, 15, 0 } } }, - { { { 10, 0, 3 }, { 0, 10, 3 }, { 0, 31, 0 }, { 5, 13, 0 } } }, - { { { 10, 0, 4 }, { 0, 10, 4 }, { 1, 30, 1 }, { 2, 15, 1 } } }, - { { { 11, 0, 3 }, { 0, 11, 3 }, { 1, 30, 0 }, { 2, 15, 0 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 4, 24, 0 }, { 0, 16, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 1, 31, 1 }, { 1, 16, 1 } } }, - { { { 11, 0, 0 }, { 0, 11, 0 }, { 1, 31, 0 }, { 1, 16, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 1, 31, 1 }, { 1, 16, 1 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 2, 30, 1 }, { 0, 17, 1 } } }, - { { { 11, 0, 3 }, { 0, 11, 3 }, { 2, 30, 0 }, { 0, 17, 0 } } }, - { { { 11, 0, 4 }, { 0, 11, 4 }, { 2, 31, 1 }, { 5, 15, 1 } } }, - { { { 12, 0, 4 }, { 0, 12, 4 }, { 2, 31, 0 }, { 5, 15, 0 } } }, - { { { 12, 0, 3 }, { 0, 12, 3 }, { 4, 27, 0 }, { 1, 17, 0 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 3, 30, 1 }, { 0, 18, 1 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 3, 30, 0 }, { 0, 18, 0 } } }, - { { { 12, 0, 0 }, { 0, 12, 0 }, { 4, 28, 0 }, { 4, 16, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 3, 31, 1 }, { 1, 18, 1 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 3, 31, 0 }, { 1, 18, 0 } } }, - { { { 12, 0, 3 }, { 0, 12, 3 }, { 3, 31, 1 }, { 1, 18, 1 } } }, - { { { 12, 0, 4 }, { 0, 12, 4 }, { 4, 30, 1 }, { 0, 19, 1 } } }, - { { { 13, 0, 3 }, { 0, 13, 3 }, { 4, 30, 0 }, { 0, 19, 0 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 6, 27, 1 }, { 1, 19, 1 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 6, 27, 0 }, { 1, 19, 0 } } }, - { { { 13, 0, 0 }, { 0, 13, 0 }, { 4, 31, 0 }, { 5, 17, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 5, 30, 1 }, { 2, 19, 1 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 5, 30, 0 }, { 2, 19, 0 } } }, - { { { 13, 0, 3 }, { 0, 13, 3 }, { 8, 24, 0 }, { 0, 20, 0 } } }, - { { { 13, 0, 4 }, { 0, 13, 4 }, { 5, 31, 1 }, { 1, 20, 1 } } }, - { { { 14, 0, 3 }, { 0, 14, 3 }, { 5, 31, 0 }, { 1, 20, 0 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 5, 31, 1 }, { 1, 20, 1 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 6, 30, 1 }, { 0, 21, 1 } } }, - { { { 14, 0, 0 }, { 0, 14, 0 }, { 6, 30, 0 }, { 0, 21, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 6, 31, 1 }, { 5, 19, 1 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 6, 31, 0 }, { 5, 19, 0 } } }, - { { { 14, 0, 3 }, { 0, 14, 3 }, { 8, 27, 0 }, { 1, 21, 0 } } }, - { { { 14, 0, 4 }, { 0, 14, 4 }, { 7, 30, 1 }, { 0, 22, 1 } } }, - { { { 15, 0, 3 }, { 0, 15, 3 }, { 7, 30, 0 }, { 0, 22, 0 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 8, 28, 0 }, { 4, 20, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 7, 31, 1 }, { 1, 22, 1 } } }, - { { { 15, 0, 0 }, { 0, 15, 0 }, { 7, 31, 0 }, { 1, 22, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 7, 31, 1 }, { 1, 22, 1 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 8, 30, 1 }, { 0, 23, 1 } } }, - { { { 15, 0, 3 }, { 0, 15, 3 }, { 8, 30, 0 }, { 0, 23, 0 } } }, - { { { 15, 0, 4 }, { 0, 15, 4 }, { 10, 27, 1 }, { 1, 23, 1 } } }, - { { { 16, 0, 4 }, { 0, 16, 4 }, { 10, 27, 0 }, { 1, 23, 0 } } }, - { { { 16, 0, 3 }, { 0, 16, 3 }, { 8, 31, 0 }, { 5, 21, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 9, 30, 1 }, { 2, 23, 1 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 9, 30, 0 }, { 2, 23, 0 } } }, - { { { 16, 0, 0 }, { 0, 16, 0 }, { 12, 24, 0 }, { 0, 24, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 9, 31, 1 }, { 1, 24, 1 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 9, 31, 0 }, { 1, 24, 0 } } }, - { { { 16, 0, 3 }, { 0, 16, 3 }, { 9, 31, 1 }, { 1, 24, 1 } } }, - { { { 16, 0, 4 }, { 0, 16, 4 }, { 10, 30, 1 }, { 0, 25, 1 } } }, - { { { 17, 0, 3 }, { 0, 17, 3 }, { 10, 30, 0 }, { 0, 25, 0 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 10, 31, 1 }, { 5, 23, 1 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 10, 31, 0 }, { 5, 23, 0 } } }, - { { { 17, 0, 0 }, { 0, 17, 0 }, { 12, 27, 0 }, { 1, 25, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 11, 30, 1 }, { 0, 26, 1 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 11, 30, 0 }, { 0, 26, 0 } } }, - { { { 17, 0, 3 }, { 0, 17, 3 }, { 12, 28, 0 }, { 4, 24, 0 } } }, - { { { 17, 0, 4 }, { 0, 17, 4 }, { 11, 31, 1 }, { 1, 26, 1 } } }, - { { { 18, 0, 3 }, { 0, 18, 3 }, { 11, 31, 0 }, { 1, 26, 0 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 11, 31, 1 }, { 1, 26, 1 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 12, 30, 1 }, { 0, 27, 1 } } }, - { { { 18, 0, 0 }, { 0, 18, 0 }, { 12, 30, 0 }, { 0, 27, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 14, 27, 1 }, { 1, 27, 1 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 14, 27, 0 }, { 1, 27, 0 } } }, - { { { 18, 0, 3 }, { 0, 18, 3 }, { 12, 31, 0 }, { 5, 25, 0 } } }, - { { { 18, 0, 4 }, { 0, 18, 4 }, { 13, 30, 1 }, { 2, 27, 1 } } }, - { { { 19, 0, 3 }, { 0, 19, 3 }, { 13, 30, 0 }, { 2, 27, 0 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 16, 24, 0 }, { 0, 28, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 13, 31, 1 }, { 1, 28, 1 } } }, - { { { 19, 0, 0 }, { 0, 19, 0 }, { 13, 31, 0 }, { 1, 28, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 13, 31, 1 }, { 1, 28, 1 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 14, 30, 1 }, { 0, 29, 1 } } }, - { { { 19, 0, 3 }, { 0, 19, 3 }, { 14, 30, 0 }, { 0, 29, 0 } } }, - { { { 19, 0, 4 }, { 0, 19, 4 }, { 14, 31, 1 }, { 5, 27, 1 } } }, - { { { 20, 0, 4 }, { 0, 20, 4 }, { 14, 31, 0 }, { 5, 27, 0 } } }, - { { { 20, 0, 3 }, { 0, 20, 3 }, { 16, 27, 0 }, { 1, 29, 0 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 15, 30, 1 }, { 0, 30, 1 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 15, 30, 0 }, { 0, 30, 0 } } }, - { { { 20, 0, 0 }, { 0, 20, 0 }, { 16, 28, 0 }, { 4, 28, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 15, 31, 1 }, { 1, 30, 1 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 15, 31, 0 }, { 1, 30, 0 } } }, - { { { 20, 0, 3 }, { 0, 20, 3 }, { 15, 31, 1 }, { 1, 30, 1 } } }, - { { { 20, 0, 4 }, { 0, 20, 4 }, { 16, 30, 1 }, { 0, 31, 1 } } }, - { { { 21, 0, 3 }, { 0, 21, 3 }, { 16, 30, 0 }, { 0, 31, 0 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 18, 27, 1 }, { 1, 31, 1 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 18, 27, 0 }, { 1, 31, 0 } } }, - { { { 21, 0, 0 }, { 0, 21, 0 }, { 16, 31, 0 }, { 5, 29, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 17, 30, 1 }, { 2, 31, 1 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 17, 30, 0 }, { 2, 31, 0 } } }, - { { { 21, 0, 3 }, { 0, 21, 3 }, { 20, 24, 0 }, { 8, 28, 0 } } }, - { { { 21, 0, 4 }, { 0, 21, 4 }, { 17, 31, 1 }, { 3, 31, 1 } } }, - { { { 22, 0, 3 }, { 0, 22, 3 }, { 17, 31, 0 }, { 3, 31, 0 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 17, 31, 1 }, { 3, 31, 1 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 18, 30, 1 }, { 4, 31, 1 } } }, - { { { 22, 0, 0 }, { 0, 22, 0 }, { 18, 30, 0 }, { 4, 31, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 18, 31, 1 }, { 5, 31, 1 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 18, 31, 0 }, { 5, 31, 0 } } }, - { { { 22, 0, 3 }, { 0, 22, 3 }, { 20, 27, 0 }, { 9, 29, 0 } } }, - { { { 22, 0, 4 }, { 0, 22, 4 }, { 19, 30, 1 }, { 6, 31, 1 } } }, - { { { 23, 0, 3 }, { 0, 23, 3 }, { 19, 30, 0 }, { 6, 31, 0 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 20, 28, 0 }, { 12, 28, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 19, 31, 1 }, { 7, 31, 1 } } }, - { { { 23, 0, 0 }, { 0, 23, 0 }, { 19, 31, 0 }, { 7, 31, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 19, 31, 1 }, { 7, 31, 1 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 20, 30, 1 }, { 8, 31, 1 } } }, - { { { 23, 0, 3 }, { 0, 23, 3 }, { 20, 30, 0 }, { 8, 31, 0 } } }, - { { { 23, 0, 4 }, { 0, 23, 4 }, { 22, 27, 1 }, { 9, 31, 1 } } }, - { { { 24, 0, 4 }, { 0, 24, 4 }, { 22, 27, 0 }, { 9, 31, 0 } } }, - { { { 24, 0, 3 }, { 0, 24, 3 }, { 20, 31, 0 }, { 13, 29, 0 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 21, 30, 1 }, { 10, 31, 1 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 21, 30, 0 }, { 10, 31, 0 } } }, - { { { 24, 0, 0 }, { 0, 24, 0 }, { 24, 24, 0 }, { 16, 28, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 21, 31, 1 }, { 11, 31, 1 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 21, 31, 0 }, { 11, 31, 0 } } }, - { { { 24, 0, 3 }, { 0, 24, 3 }, { 21, 31, 1 }, { 11, 31, 1 } } }, - { { { 24, 0, 4 }, { 0, 24, 4 }, { 22, 30, 1 }, { 12, 31, 1 } } }, - { { { 25, 0, 3 }, { 0, 25, 3 }, { 22, 30, 0 }, { 12, 31, 0 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 22, 31, 1 }, { 13, 31, 1 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 22, 31, 0 }, { 13, 31, 0 } } }, - { { { 25, 0, 0 }, { 0, 25, 0 }, { 24, 27, 0 }, { 17, 29, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 23, 30, 1 }, { 14, 31, 1 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 23, 30, 0 }, { 14, 31, 0 } } }, - { { { 25, 0, 3 }, { 0, 25, 3 }, { 24, 28, 0 }, { 20, 28, 0 } } }, - { { { 25, 0, 4 }, { 0, 25, 4 }, { 23, 31, 1 }, { 15, 31, 1 } } }, - { { { 26, 0, 3 }, { 0, 26, 3 }, { 23, 31, 0 }, { 15, 31, 0 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 23, 31, 1 }, { 15, 31, 1 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 24, 30, 1 }, { 16, 31, 1 } } }, - { { { 26, 0, 0 }, { 0, 26, 0 }, { 24, 30, 0 }, { 16, 31, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 26, 27, 1 }, { 17, 31, 1 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 26, 27, 0 }, { 17, 31, 0 } } }, - { { { 26, 0, 3 }, { 0, 26, 3 }, { 24, 31, 0 }, { 21, 29, 0 } } }, - { { { 26, 0, 4 }, { 0, 26, 4 }, { 25, 30, 1 }, { 18, 31, 1 } } }, - { { { 27, 0, 3 }, { 0, 27, 3 }, { 25, 30, 0 }, { 18, 31, 0 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 28, 24, 0 }, { 24, 28, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 25, 31, 1 }, { 19, 31, 1 } } }, - { { { 27, 0, 0 }, { 0, 27, 0 }, { 25, 31, 0 }, { 19, 31, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 25, 31, 1 }, { 19, 31, 1 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 26, 30, 1 }, { 20, 31, 1 } } }, - { { { 27, 0, 3 }, { 0, 27, 3 }, { 26, 30, 0 }, { 20, 31, 0 } } }, - { { { 27, 0, 4 }, { 0, 27, 4 }, { 26, 31, 1 }, { 21, 31, 1 } } }, - { { { 28, 0, 4 }, { 0, 28, 4 }, { 26, 31, 0 }, { 21, 31, 0 } } }, - { { { 28, 0, 3 }, { 0, 28, 3 }, { 28, 27, 0 }, { 25, 29, 0 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 27, 30, 1 }, { 22, 31, 1 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 27, 30, 0 }, { 22, 31, 0 } } }, - { { { 28, 0, 0 }, { 0, 28, 0 }, { 28, 28, 0 }, { 28, 28, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 27, 31, 1 }, { 23, 31, 1 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 27, 31, 0 }, { 23, 31, 0 } } }, - { { { 28, 0, 3 }, { 0, 28, 3 }, { 27, 31, 1 }, { 23, 31, 1 } } }, - { { { 28, 0, 4 }, { 0, 28, 4 }, { 28, 30, 1 }, { 24, 31, 1 } } }, - { { { 29, 0, 3 }, { 0, 29, 3 }, { 28, 30, 0 }, { 24, 31, 0 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 30, 27, 1 }, { 25, 31, 1 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 30, 27, 0 }, { 25, 31, 0 } } }, - { { { 29, 0, 0 }, { 0, 29, 0 }, { 28, 31, 0 }, { 29, 29, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 29, 30, 1 }, { 26, 31, 1 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 29, 30, 0 }, { 26, 31, 0 } } }, - { { { 29, 0, 3 }, { 0, 29, 3 }, { 29, 30, 1 }, { 26, 31, 1 } } }, - { { { 29, 0, 4 }, { 0, 29, 4 }, { 29, 31, 1 }, { 27, 31, 1 } } }, - { { { 30, 0, 3 }, { 0, 30, 3 }, { 29, 31, 0 }, { 27, 31, 0 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 29, 31, 1 }, { 27, 31, 1 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 30, 30, 1 }, { 28, 31, 1 } } }, - { { { 30, 0, 0 }, { 0, 30, 0 }, { 30, 30, 0 }, { 28, 31, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 30, 31, 1 }, { 29, 31, 1 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 30, 31, 0 }, { 29, 31, 0 } } }, - { { { 30, 0, 3 }, { 0, 30, 3 }, { 30, 31, 1 }, { 29, 31, 1 } } }, - { { { 30, 0, 4 }, { 0, 30, 4 }, { 31, 30, 1 }, { 30, 31, 1 } } }, - { { { 31, 0, 3 }, { 0, 31, 3 }, { 31, 30, 0 }, { 30, 31, 0 } } }, - { { { 31, 0, 2 }, { 0, 31, 2 }, { 31, 30, 1 }, { 30, 31, 1 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 31, 31, 1 }, { 31, 31, 1 } } }, - { { { 31, 0, 0 }, { 0, 31, 0 }, { 31, 31, 0 }, { 31, 31, 0 } } } -}; - -static SingleColourLookup const lookup_6_4[] = -{ - { { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } } }, - { { { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } } }, - { { { 0, 0, 2 }, { 0, 0, 2 }, { 0, 2, 0 }, { 0, 1, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 3, 1 }, { 1, 1, 1 } } }, - { { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 3, 0 }, { 1, 1, 0 } } }, - { { { 1, 0, 1 }, { 0, 1, 1 }, { 0, 4, 0 }, { 0, 2, 0 } } }, - { { { 1, 0, 2 }, { 0, 1, 2 }, { 0, 5, 0 }, { 1, 2, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 6, 1 }, { 0, 3, 1 } } }, - { { { 2, 0, 0 }, { 0, 2, 0 }, { 0, 6, 0 }, { 0, 3, 0 } } }, - { { { 2, 0, 1 }, { 0, 2, 1 }, { 0, 7, 0 }, { 1, 3, 0 } } }, - { { { 2, 0, 2 }, { 0, 2, 2 }, { 0, 8, 0 }, { 0, 4, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 9, 1 }, { 1, 4, 1 } } }, - { { { 3, 0, 0 }, { 0, 3, 0 }, { 0, 9, 0 }, { 1, 4, 0 } } }, - { { { 3, 0, 1 }, { 0, 3, 1 }, { 0, 10, 0 }, { 0, 5, 0 } } }, - { { { 3, 0, 2 }, { 0, 3, 2 }, { 0, 11, 0 }, { 1, 5, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 12, 1 }, { 0, 6, 1 } } }, - { { { 4, 0, 0 }, { 0, 4, 0 }, { 0, 12, 0 }, { 0, 6, 0 } } }, - { { { 4, 0, 1 }, { 0, 4, 1 }, { 0, 13, 0 }, { 1, 6, 0 } } }, - { { { 4, 0, 2 }, { 0, 4, 2 }, { 0, 14, 0 }, { 0, 7, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 0, 15, 1 }, { 1, 7, 1 } } }, - { { { 5, 0, 0 }, { 0, 5, 0 }, { 0, 15, 0 }, { 1, 7, 0 } } }, - { { { 5, 0, 1 }, { 0, 5, 1 }, { 0, 16, 0 }, { 0, 8, 0 } } }, - { { { 5, 0, 2 }, { 0, 5, 2 }, { 1, 15, 0 }, { 1, 8, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 17, 0 }, { 17, 0, 0 } } }, - { { { 6, 0, 0 }, { 0, 6, 0 }, { 0, 18, 0 }, { 0, 9, 0 } } }, - { { { 6, 0, 1 }, { 0, 6, 1 }, { 0, 19, 0 }, { 1, 9, 0 } } }, - { { { 6, 0, 2 }, { 0, 6, 2 }, { 3, 14, 0 }, { 0, 10, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 20, 0 }, { 16, 2, 0 } } }, - { { { 7, 0, 0 }, { 0, 7, 0 }, { 0, 21, 0 }, { 1, 10, 0 } } }, - { { { 7, 0, 1 }, { 0, 7, 1 }, { 0, 22, 0 }, { 0, 11, 0 } } }, - { { { 7, 0, 2 }, { 0, 7, 2 }, { 4, 15, 0 }, { 1, 11, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 23, 0 }, { 17, 3, 0 } } }, - { { { 8, 0, 0 }, { 0, 8, 0 }, { 0, 24, 0 }, { 0, 12, 0 } } }, - { { { 8, 0, 1 }, { 0, 8, 1 }, { 0, 25, 0 }, { 1, 12, 0 } } }, - { { { 8, 0, 2 }, { 0, 8, 2 }, { 6, 14, 0 }, { 0, 13, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 0, 26, 0 }, { 16, 5, 0 } } }, - { { { 9, 0, 0 }, { 0, 9, 0 }, { 0, 27, 0 }, { 1, 13, 0 } } }, - { { { 9, 0, 1 }, { 0, 9, 1 }, { 0, 28, 0 }, { 0, 14, 0 } } }, - { { { 9, 0, 2 }, { 0, 9, 2 }, { 7, 15, 0 }, { 1, 14, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 29, 0 }, { 17, 6, 0 } } }, - { { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 30, 0 }, { 0, 15, 0 } } }, - { { { 10, 0, 1 }, { 0, 10, 1 }, { 0, 31, 0 }, { 1, 15, 0 } } }, - { { { 10, 0, 2 }, { 0, 10, 2 }, { 9, 14, 0 }, { 2, 15, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 0, 32, 0 }, { 0, 16, 0 } } }, - { { { 11, 0, 0 }, { 0, 11, 0 }, { 0, 33, 0 }, { 1, 16, 0 } } }, - { { { 11, 0, 1 }, { 0, 11, 1 }, { 2, 30, 0 }, { 4, 15, 0 } } }, - { { { 11, 0, 2 }, { 0, 11, 2 }, { 0, 34, 0 }, { 0, 17, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 0, 35, 0 }, { 1, 17, 0 } } }, - { { { 12, 0, 0 }, { 0, 12, 0 }, { 0, 36, 0 }, { 0, 18, 0 } } }, - { { { 12, 0, 1 }, { 0, 12, 1 }, { 3, 31, 0 }, { 7, 15, 0 } } }, - { { { 12, 0, 2 }, { 0, 12, 2 }, { 0, 37, 0 }, { 1, 18, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 0, 38, 0 }, { 0, 19, 0 } } }, - { { { 13, 0, 0 }, { 0, 13, 0 }, { 0, 39, 0 }, { 1, 19, 0 } } }, - { { { 13, 0, 1 }, { 0, 13, 1 }, { 5, 30, 0 }, { 10, 15, 0 } } }, - { { { 13, 0, 2 }, { 0, 13, 2 }, { 0, 40, 0 }, { 0, 20, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 0, 41, 0 }, { 1, 20, 0 } } }, - { { { 14, 0, 0 }, { 0, 14, 0 }, { 0, 42, 0 }, { 0, 21, 0 } } }, - { { { 14, 0, 1 }, { 0, 14, 1 }, { 6, 31, 0 }, { 13, 15, 0 } } }, - { { { 14, 0, 2 }, { 0, 14, 2 }, { 0, 43, 0 }, { 1, 21, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 0, 44, 0 }, { 0, 22, 0 } } }, - { { { 15, 0, 0 }, { 0, 15, 0 }, { 0, 45, 0 }, { 1, 22, 0 } } }, - { { { 15, 0, 1 }, { 0, 15, 1 }, { 8, 30, 0 }, { 16, 15, 0 } } }, - { { { 15, 0, 2 }, { 0, 15, 2 }, { 0, 46, 0 }, { 0, 23, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 0, 47, 0 }, { 1, 23, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 1, 46, 0 }, { 0, 24, 0 } } }, - { { { 16, 0, 0 }, { 0, 16, 0 }, { 0, 48, 0 }, { 16, 16, 0 } } }, - { { { 16, 0, 1 }, { 0, 16, 1 }, { 0, 49, 0 }, { 1, 24, 0 } } }, - { { { 16, 0, 2 }, { 0, 16, 2 }, { 0, 50, 0 }, { 0, 25, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 2, 47, 0 }, { 1, 25, 0 } } }, - { { { 17, 0, 0 }, { 0, 17, 0 }, { 0, 51, 0 }, { 17, 17, 0 } } }, - { { { 17, 0, 1 }, { 0, 17, 1 }, { 0, 52, 0 }, { 0, 26, 0 } } }, - { { { 17, 0, 2 }, { 0, 17, 2 }, { 0, 53, 0 }, { 1, 26, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 4, 46, 0 }, { 0, 27, 0 } } }, - { { { 18, 0, 0 }, { 0, 18, 0 }, { 0, 54, 0 }, { 16, 19, 0 } } }, - { { { 18, 0, 1 }, { 0, 18, 1 }, { 0, 55, 0 }, { 1, 27, 0 } } }, - { { { 18, 0, 2 }, { 0, 18, 2 }, { 0, 56, 0 }, { 0, 28, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 5, 47, 0 }, { 1, 28, 0 } } }, - { { { 19, 0, 0 }, { 0, 19, 0 }, { 0, 57, 0 }, { 17, 20, 0 } } }, - { { { 19, 0, 1 }, { 0, 19, 1 }, { 0, 58, 0 }, { 0, 29, 0 } } }, - { { { 19, 0, 2 }, { 0, 19, 2 }, { 0, 59, 0 }, { 1, 29, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 7, 46, 0 }, { 0, 30, 0 } } }, - { { { 20, 0, 0 }, { 0, 20, 0 }, { 0, 60, 0 }, { 16, 22, 0 } } }, - { { { 20, 0, 1 }, { 0, 20, 1 }, { 0, 61, 0 }, { 1, 30, 0 } } }, - { { { 20, 0, 2 }, { 0, 20, 2 }, { 0, 62, 0 }, { 0, 31, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 8, 47, 0 }, { 1, 31, 0 } } }, - { { { 21, 0, 0 }, { 0, 21, 0 }, { 0, 63, 0 }, { 17, 23, 0 } } }, - { { { 21, 0, 1 }, { 0, 21, 1 }, { 1, 62, 0 }, { 0, 32, 0 } } }, - { { { 21, 0, 2 }, { 0, 21, 2 }, { 1, 63, 0 }, { 3, 31, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 10, 46, 0 }, { 1, 32, 0 } } }, - { { { 22, 0, 0 }, { 0, 22, 0 }, { 2, 62, 0 }, { 0, 33, 0 } } }, - { { { 22, 0, 1 }, { 0, 22, 1 }, { 2, 63, 0 }, { 1, 33, 0 } } }, - { { { 22, 0, 2 }, { 0, 22, 2 }, { 3, 62, 0 }, { 6, 31, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 11, 47, 0 }, { 0, 34, 0 } } }, - { { { 23, 0, 0 }, { 0, 23, 0 }, { 3, 63, 0 }, { 1, 34, 0 } } }, - { { { 23, 0, 1 }, { 0, 23, 1 }, { 4, 62, 0 }, { 0, 35, 0 } } }, - { { { 23, 0, 2 }, { 0, 23, 2 }, { 4, 63, 0 }, { 9, 31, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 13, 46, 0 }, { 1, 35, 0 } } }, - { { { 24, 0, 0 }, { 0, 24, 0 }, { 5, 62, 0 }, { 0, 36, 0 } } }, - { { { 24, 0, 1 }, { 0, 24, 1 }, { 5, 63, 0 }, { 1, 36, 0 } } }, - { { { 24, 0, 2 }, { 0, 24, 2 }, { 6, 62, 0 }, { 12, 31, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 14, 47, 0 }, { 0, 37, 0 } } }, - { { { 25, 0, 0 }, { 0, 25, 0 }, { 6, 63, 0 }, { 1, 37, 0 } } }, - { { { 25, 0, 1 }, { 0, 25, 1 }, { 7, 62, 0 }, { 0, 38, 0 } } }, - { { { 25, 0, 2 }, { 0, 25, 2 }, { 7, 63, 0 }, { 15, 31, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 16, 45, 0 }, { 1, 38, 0 } } }, - { { { 26, 0, 0 }, { 0, 26, 0 }, { 8, 62, 0 }, { 0, 39, 0 } } }, - { { { 26, 0, 1 }, { 0, 26, 1 }, { 8, 63, 0 }, { 1, 39, 0 } } }, - { { { 26, 0, 2 }, { 0, 26, 2 }, { 9, 62, 0 }, { 18, 31, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 16, 48, 0 }, { 0, 40, 0 } } }, - { { { 27, 0, 0 }, { 0, 27, 0 }, { 9, 63, 0 }, { 1, 40, 0 } } }, - { { { 27, 0, 1 }, { 0, 27, 1 }, { 10, 62, 0 }, { 0, 41, 0 } } }, - { { { 27, 0, 2 }, { 0, 27, 2 }, { 10, 63, 0 }, { 16, 33, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 16, 51, 0 }, { 1, 41, 0 } } }, - { { { 28, 0, 0 }, { 0, 28, 0 }, { 11, 62, 0 }, { 0, 42, 0 } } }, - { { { 28, 0, 1 }, { 0, 28, 1 }, { 11, 63, 0 }, { 1, 42, 0 } } }, - { { { 28, 0, 2 }, { 0, 28, 2 }, { 12, 62, 0 }, { 17, 34, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 16, 54, 0 }, { 0, 43, 0 } } }, - { { { 29, 0, 0 }, { 0, 29, 0 }, { 12, 63, 0 }, { 1, 43, 0 } } }, - { { { 29, 0, 1 }, { 0, 29, 1 }, { 13, 62, 0 }, { 0, 44, 0 } } }, - { { { 29, 0, 2 }, { 0, 29, 2 }, { 13, 63, 0 }, { 16, 36, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 16, 57, 0 }, { 1, 44, 0 } } }, - { { { 30, 0, 0 }, { 0, 30, 0 }, { 14, 62, 0 }, { 0, 45, 0 } } }, - { { { 30, 0, 1 }, { 0, 30, 1 }, { 14, 63, 0 }, { 1, 45, 0 } } }, - { { { 30, 0, 2 }, { 0, 30, 2 }, { 15, 62, 0 }, { 17, 37, 0 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 16, 60, 0 }, { 0, 46, 0 } } }, - { { { 31, 0, 0 }, { 0, 31, 0 }, { 15, 63, 0 }, { 1, 46, 0 } } }, - { { { 31, 0, 1 }, { 0, 31, 1 }, { 24, 46, 0 }, { 0, 47, 0 } } }, - { { { 31, 0, 2 }, { 0, 31, 2 }, { 16, 62, 0 }, { 16, 39, 0 } } }, - { { { 32, 0, 2 }, { 0, 32, 2 }, { 16, 63, 0 }, { 1, 47, 0 } } }, - { { { 32, 0, 1 }, { 0, 32, 1 }, { 17, 62, 0 }, { 2, 47, 0 } } }, - { { { 32, 0, 0 }, { 0, 32, 0 }, { 25, 47, 0 }, { 0, 48, 0 } } }, - { { { 32, 0, 1 }, { 0, 32, 1 }, { 17, 63, 0 }, { 1, 48, 0 } } }, - { { { 32, 0, 2 }, { 0, 32, 2 }, { 18, 62, 0 }, { 0, 49, 0 } } }, - { { { 33, 0, 1 }, { 0, 33, 1 }, { 18, 63, 0 }, { 5, 47, 0 } } }, - { { { 33, 0, 0 }, { 0, 33, 0 }, { 27, 46, 0 }, { 1, 49, 0 } } }, - { { { 33, 0, 1 }, { 0, 33, 1 }, { 19, 62, 0 }, { 0, 50, 0 } } }, - { { { 33, 0, 2 }, { 0, 33, 2 }, { 19, 63, 0 }, { 1, 50, 0 } } }, - { { { 34, 0, 1 }, { 0, 34, 1 }, { 20, 62, 0 }, { 8, 47, 0 } } }, - { { { 34, 0, 0 }, { 0, 34, 0 }, { 28, 47, 0 }, { 0, 51, 0 } } }, - { { { 34, 0, 1 }, { 0, 34, 1 }, { 20, 63, 0 }, { 1, 51, 0 } } }, - { { { 34, 0, 2 }, { 0, 34, 2 }, { 21, 62, 0 }, { 0, 52, 0 } } }, - { { { 35, 0, 1 }, { 0, 35, 1 }, { 21, 63, 0 }, { 11, 47, 0 } } }, - { { { 35, 0, 0 }, { 0, 35, 0 }, { 30, 46, 0 }, { 1, 52, 0 } } }, - { { { 35, 0, 1 }, { 0, 35, 1 }, { 22, 62, 0 }, { 0, 53, 0 } } }, - { { { 35, 0, 2 }, { 0, 35, 2 }, { 22, 63, 0 }, { 1, 53, 0 } } }, - { { { 36, 0, 1 }, { 0, 36, 1 }, { 23, 62, 0 }, { 14, 47, 0 } } }, - { { { 36, 0, 0 }, { 0, 36, 0 }, { 31, 47, 0 }, { 0, 54, 0 } } }, - { { { 36, 0, 1 }, { 0, 36, 1 }, { 23, 63, 0 }, { 1, 54, 0 } } }, - { { { 36, 0, 2 }, { 0, 36, 2 }, { 24, 62, 0 }, { 0, 55, 0 } } }, - { { { 37, 0, 1 }, { 0, 37, 1 }, { 24, 63, 0 }, { 17, 47, 0 } } }, - { { { 37, 0, 0 }, { 0, 37, 0 }, { 32, 47, 0 }, { 1, 55, 0 } } }, - { { { 37, 0, 1 }, { 0, 37, 1 }, { 25, 62, 0 }, { 0, 56, 0 } } }, - { { { 37, 0, 2 }, { 0, 37, 2 }, { 25, 63, 0 }, { 1, 56, 0 } } }, - { { { 38, 0, 1 }, { 0, 38, 1 }, { 26, 62, 0 }, { 17, 48, 0 } } }, - { { { 38, 0, 0 }, { 0, 38, 0 }, { 32, 50, 0 }, { 0, 57, 0 } } }, - { { { 38, 0, 1 }, { 0, 38, 1 }, { 26, 63, 0 }, { 1, 57, 0 } } }, - { { { 38, 0, 2 }, { 0, 38, 2 }, { 27, 62, 0 }, { 0, 58, 0 } } }, - { { { 39, 0, 1 }, { 0, 39, 1 }, { 27, 63, 0 }, { 16, 50, 0 } } }, - { { { 39, 0, 0 }, { 0, 39, 0 }, { 32, 53, 0 }, { 1, 58, 0 } } }, - { { { 39, 0, 1 }, { 0, 39, 1 }, { 28, 62, 0 }, { 0, 59, 0 } } }, - { { { 39, 0, 2 }, { 0, 39, 2 }, { 28, 63, 0 }, { 1, 59, 0 } } }, - { { { 40, 0, 1 }, { 0, 40, 1 }, { 29, 62, 0 }, { 17, 51, 0 } } }, - { { { 40, 0, 0 }, { 0, 40, 0 }, { 32, 56, 0 }, { 0, 60, 0 } } }, - { { { 40, 0, 1 }, { 0, 40, 1 }, { 29, 63, 0 }, { 1, 60, 0 } } }, - { { { 40, 0, 2 }, { 0, 40, 2 }, { 30, 62, 0 }, { 0, 61, 0 } } }, - { { { 41, 0, 1 }, { 0, 41, 1 }, { 30, 63, 0 }, { 16, 53, 0 } } }, - { { { 41, 0, 0 }, { 0, 41, 0 }, { 32, 59, 0 }, { 1, 61, 0 } } }, - { { { 41, 0, 1 }, { 0, 41, 1 }, { 31, 62, 0 }, { 0, 62, 0 } } }, - { { { 41, 0, 2 }, { 0, 41, 2 }, { 31, 63, 0 }, { 1, 62, 0 } } }, - { { { 42, 0, 1 }, { 0, 42, 1 }, { 32, 61, 0 }, { 17, 54, 0 } } }, - { { { 42, 0, 0 }, { 0, 42, 0 }, { 32, 62, 0 }, { 0, 63, 0 } } }, - { { { 42, 0, 1 }, { 0, 42, 1 }, { 32, 63, 0 }, { 1, 63, 0 } } }, - { { { 42, 0, 2 }, { 0, 42, 2 }, { 41, 46, 0 }, { 2, 63, 0 } } }, - { { { 43, 0, 1 }, { 0, 43, 1 }, { 33, 62, 0 }, { 16, 56, 0 } } }, - { { { 43, 0, 0 }, { 0, 43, 0 }, { 33, 63, 0 }, { 3, 63, 0 } } }, - { { { 43, 0, 1 }, { 0, 43, 1 }, { 34, 62, 0 }, { 4, 63, 0 } } }, - { { { 43, 0, 2 }, { 0, 43, 2 }, { 42, 47, 0 }, { 5, 63, 0 } } }, - { { { 44, 0, 1 }, { 0, 44, 1 }, { 34, 63, 0 }, { 17, 57, 0 } } }, - { { { 44, 0, 0 }, { 0, 44, 0 }, { 35, 62, 0 }, { 6, 63, 0 } } }, - { { { 44, 0, 1 }, { 0, 44, 1 }, { 35, 63, 0 }, { 7, 63, 0 } } }, - { { { 44, 0, 2 }, { 0, 44, 2 }, { 44, 46, 0 }, { 8, 63, 0 } } }, - { { { 45, 0, 1 }, { 0, 45, 1 }, { 36, 62, 0 }, { 16, 59, 0 } } }, - { { { 45, 0, 0 }, { 0, 45, 0 }, { 36, 63, 0 }, { 9, 63, 0 } } }, - { { { 45, 0, 1 }, { 0, 45, 1 }, { 37, 62, 0 }, { 10, 63, 0 } } }, - { { { 45, 0, 2 }, { 0, 45, 2 }, { 45, 47, 0 }, { 11, 63, 0 } } }, - { { { 46, 0, 1 }, { 0, 46, 1 }, { 37, 63, 0 }, { 17, 60, 0 } } }, - { { { 46, 0, 0 }, { 0, 46, 0 }, { 38, 62, 0 }, { 12, 63, 0 } } }, - { { { 46, 0, 1 }, { 0, 46, 1 }, { 38, 63, 0 }, { 13, 63, 0 } } }, - { { { 46, 0, 2 }, { 0, 46, 2 }, { 47, 46, 0 }, { 14, 63, 0 } } }, - { { { 47, 0, 1 }, { 0, 47, 1 }, { 39, 62, 0 }, { 16, 62, 0 } } }, - { { { 47, 0, 0 }, { 0, 47, 0 }, { 39, 63, 0 }, { 15, 63, 0 } } }, - { { { 47, 0, 1 }, { 0, 47, 1 }, { 40, 62, 0 }, { 16, 63, 0 } } }, - { { { 47, 0, 2 }, { 0, 47, 2 }, { 48, 46, 0 }, { 32, 55, 0 } } }, - { { { 48, 0, 2 }, { 0, 48, 2 }, { 40, 63, 0 }, { 17, 63, 0 } } }, - { { { 48, 0, 1 }, { 0, 48, 1 }, { 41, 62, 0 }, { 18, 63, 0 } } }, - { { { 48, 0, 0 }, { 0, 48, 0 }, { 41, 63, 0 }, { 19, 63, 0 } } }, - { { { 48, 0, 1 }, { 0, 48, 1 }, { 48, 49, 0 }, { 33, 56, 0 } } }, - { { { 48, 0, 2 }, { 0, 48, 2 }, { 42, 62, 0 }, { 20, 63, 0 } } }, - { { { 49, 0, 1 }, { 0, 49, 1 }, { 42, 63, 0 }, { 21, 63, 0 } } }, - { { { 49, 0, 0 }, { 0, 49, 0 }, { 43, 62, 0 }, { 22, 63, 0 } } }, - { { { 49, 0, 1 }, { 0, 49, 1 }, { 48, 52, 0 }, { 32, 58, 0 } } }, - { { { 49, 0, 2 }, { 0, 49, 2 }, { 43, 63, 0 }, { 23, 63, 0 } } }, - { { { 50, 0, 1 }, { 0, 50, 1 }, { 44, 62, 0 }, { 24, 63, 0 } } }, - { { { 50, 0, 0 }, { 0, 50, 0 }, { 44, 63, 0 }, { 25, 63, 0 } } }, - { { { 50, 0, 1 }, { 0, 50, 1 }, { 48, 55, 0 }, { 33, 59, 0 } } }, - { { { 50, 0, 2 }, { 0, 50, 2 }, { 45, 62, 0 }, { 26, 63, 0 } } }, - { { { 51, 0, 1 }, { 0, 51, 1 }, { 45, 63, 0 }, { 27, 63, 0 } } }, - { { { 51, 0, 0 }, { 0, 51, 0 }, { 46, 62, 0 }, { 28, 63, 0 } } }, - { { { 51, 0, 1 }, { 0, 51, 1 }, { 48, 58, 0 }, { 32, 61, 0 } } }, - { { { 51, 0, 2 }, { 0, 51, 2 }, { 46, 63, 0 }, { 29, 63, 0 } } }, - { { { 52, 0, 1 }, { 0, 52, 1 }, { 47, 62, 0 }, { 30, 63, 0 } } }, - { { { 52, 0, 0 }, { 0, 52, 0 }, { 47, 63, 0 }, { 31, 63, 0 } } }, - { { { 52, 0, 1 }, { 0, 52, 1 }, { 48, 61, 0 }, { 33, 62, 0 } } }, - { { { 52, 0, 2 }, { 0, 52, 2 }, { 48, 62, 0 }, { 32, 63, 0 } } }, - { { { 53, 0, 1 }, { 0, 53, 1 }, { 56, 47, 0 }, { 33, 63, 0 } } }, - { { { 53, 0, 0 }, { 0, 53, 0 }, { 48, 63, 0 }, { 49, 55, 0 } } }, - { { { 53, 0, 1 }, { 0, 53, 1 }, { 49, 62, 0 }, { 34, 63, 0 } } }, - { { { 53, 0, 2 }, { 0, 53, 2 }, { 49, 63, 0 }, { 35, 63, 0 } } }, - { { { 54, 0, 1 }, { 0, 54, 1 }, { 58, 46, 0 }, { 36, 63, 0 } } }, - { { { 54, 0, 0 }, { 0, 54, 0 }, { 50, 62, 0 }, { 48, 57, 0 } } }, - { { { 54, 0, 1 }, { 0, 54, 1 }, { 50, 63, 0 }, { 37, 63, 0 } } }, - { { { 54, 0, 2 }, { 0, 54, 2 }, { 51, 62, 0 }, { 38, 63, 0 } } }, - { { { 55, 0, 1 }, { 0, 55, 1 }, { 59, 47, 0 }, { 39, 63, 0 } } }, - { { { 55, 0, 0 }, { 0, 55, 0 }, { 51, 63, 0 }, { 49, 58, 0 } } }, - { { { 55, 0, 1 }, { 0, 55, 1 }, { 52, 62, 0 }, { 40, 63, 0 } } }, - { { { 55, 0, 2 }, { 0, 55, 2 }, { 52, 63, 0 }, { 41, 63, 0 } } }, - { { { 56, 0, 1 }, { 0, 56, 1 }, { 61, 46, 0 }, { 42, 63, 0 } } }, - { { { 56, 0, 0 }, { 0, 56, 0 }, { 53, 62, 0 }, { 48, 60, 0 } } }, - { { { 56, 0, 1 }, { 0, 56, 1 }, { 53, 63, 0 }, { 43, 63, 0 } } }, - { { { 56, 0, 2 }, { 0, 56, 2 }, { 54, 62, 0 }, { 44, 63, 0 } } }, - { { { 57, 0, 1 }, { 0, 57, 1 }, { 62, 47, 0 }, { 45, 63, 0 } } }, - { { { 57, 0, 0 }, { 0, 57, 0 }, { 54, 63, 0 }, { 49, 61, 0 } } }, - { { { 57, 0, 1 }, { 0, 57, 1 }, { 55, 62, 0 }, { 46, 63, 0 } } }, - { { { 57, 0, 2 }, { 0, 57, 2 }, { 55, 63, 0 }, { 47, 63, 0 } } }, - { { { 58, 0, 1 }, { 0, 58, 1 }, { 56, 62, 1 }, { 48, 63, 1 } } }, - { { { 58, 0, 0 }, { 0, 58, 0 }, { 56, 62, 0 }, { 48, 63, 0 } } }, - { { { 58, 0, 1 }, { 0, 58, 1 }, { 56, 63, 0 }, { 49, 63, 0 } } }, - { { { 58, 0, 2 }, { 0, 58, 2 }, { 57, 62, 0 }, { 50, 63, 0 } } }, - { { { 59, 0, 1 }, { 0, 59, 1 }, { 57, 63, 1 }, { 51, 63, 1 } } }, - { { { 59, 0, 0 }, { 0, 59, 0 }, { 57, 63, 0 }, { 51, 63, 0 } } }, - { { { 59, 0, 1 }, { 0, 59, 1 }, { 58, 62, 0 }, { 52, 63, 0 } } }, - { { { 59, 0, 2 }, { 0, 59, 2 }, { 58, 63, 0 }, { 53, 63, 0 } } }, - { { { 60, 0, 1 }, { 0, 60, 1 }, { 59, 62, 1 }, { 54, 63, 1 } } }, - { { { 60, 0, 0 }, { 0, 60, 0 }, { 59, 62, 0 }, { 54, 63, 0 } } }, - { { { 60, 0, 1 }, { 0, 60, 1 }, { 59, 63, 0 }, { 55, 63, 0 } } }, - { { { 60, 0, 2 }, { 0, 60, 2 }, { 60, 62, 0 }, { 56, 63, 0 } } }, - { { { 61, 0, 1 }, { 0, 61, 1 }, { 60, 63, 1 }, { 57, 63, 1 } } }, - { { { 61, 0, 0 }, { 0, 61, 0 }, { 60, 63, 0 }, { 57, 63, 0 } } }, - { { { 61, 0, 1 }, { 0, 61, 1 }, { 61, 62, 0 }, { 58, 63, 0 } } }, - { { { 61, 0, 2 }, { 0, 61, 2 }, { 61, 63, 0 }, { 59, 63, 0 } } }, - { { { 62, 0, 1 }, { 0, 62, 1 }, { 62, 62, 1 }, { 60, 63, 1 } } }, - { { { 62, 0, 0 }, { 0, 62, 0 }, { 62, 62, 0 }, { 60, 63, 0 } } }, - { { { 62, 0, 1 }, { 0, 62, 1 }, { 62, 63, 0 }, { 61, 63, 0 } } }, - { { { 62, 0, 2 }, { 0, 62, 2 }, { 63, 62, 0 }, { 62, 63, 0 } } }, - { { { 63, 0, 1 }, { 0, 63, 1 }, { 63, 63, 1 }, { 63, 63, 1 } } }, - { { { 63, 0, 0 }, { 0, 63, 0 }, { 63, 63, 0 }, { 63, 63, 0 } } } -}; diff --git a/Externals/NVTT/src/nvtt/squish/squish.cpp b/Externals/NVTT/src/nvtt/squish/squish.cpp deleted file mode 100644 index 515be8d6277..00000000000 --- a/Externals/NVTT/src/nvtt/squish/squish.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#include -#include "colourset.h" -#include "maths.h" -#include "rangefit.h" -#include "clusterfit.h" -#include "colourblock.h" -#include "alpha.h" -#include "singlecolourfit.h" - -namespace squish { - -static int FixFlags( int flags ) -{ - // grab the flag bits - int method = flags & ( kDxt1 | kDxt3 | kDxt5 ); - int fit = flags & ( kColourClusterFit | kColourRangeFit ); - int metric = flags & ( kColourMetricPerceptual | kColourMetricUniform ); - int extra = flags & kWeightColourByAlpha; - - // set defaults - if( method != kDxt3 && method != kDxt5 ) - method = kDxt1; - if( fit != kColourRangeFit ) - fit = kColourClusterFit; - if( metric != kColourMetricUniform ) - metric = kColourMetricPerceptual; - - // done - return method | fit | metric | extra; -} - - -void Compress( u8 const* rgba, void* block, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // get the block locations - void* colourBlock = block; - void* alphaBock = block; - if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) - colourBlock = reinterpret_cast< u8* >( block ) + 8; - - // create the minimal point set - ColourSet colours( rgba, flags ); - - // check the compression type and compress colour - if( colours.GetCount() == 1 ) - { - // always do a single colour fit - SingleColourFit fit( &colours, flags ); - fit.Compress( colourBlock ); - } - else if( ( flags & kColourRangeFit ) != 0 ) - { - // do a range fit - RangeFit fit( &colours, flags ); - fit.Compress( colourBlock ); - } - else - { - // default to a cluster fit - ClusterFit fit; - fit.SetColourSet( &colours, flags ); - fit.Compress( colourBlock ); - } - - // compress alpha separately if necessary - if( ( flags & kDxt3 ) != 0 ) - CompressAlphaDxt3( rgba, alphaBock ); - else if( ( flags & kDxt5 ) != 0 ) - CompressAlphaDxt5( rgba, alphaBock ); -} - - -void Decompress( u8* rgba, void const* block, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // get the block locations - void const* colourBlock = block; - void const* alphaBock = block; - if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) - colourBlock = reinterpret_cast< u8 const* >( block ) + 8; - - // decompress colour - DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); - - // decompress alpha separately if necessary - if( ( flags & kDxt3 ) != 0 ) - DecompressAlphaDxt3( rgba, alphaBock ); - else if( ( flags & kDxt5 ) != 0 ) - DecompressAlphaDxt5( rgba, alphaBock ); -} - -int GetStorageRequirements( int width, int height, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // compute the storage requirements - int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); - int blocksize = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; - return blockcount*blocksize; -} - -void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // initialise the block output - u8* targetBlock = reinterpret_cast< u8* >( blocks ); - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; - - int bh = std::min(width, 4); - int bw = std::min(height, 4); - - // loop over blocks - for( int y = 0; y < height; y += 4 ) - { - for( int x = 0; x < width; x += 4 ) - { - // build the 4x4 block of pixels - u8 sourceRgba[16*4]; - u8* targetPixel = sourceRgba; - for( int py = 0; py < 4; ++py ) - { - for( int px = 0; px < 4; ++px ) - { - // get the source pixel in the image - int sx = x + (px % bw); - int sy = y + (py % bh); - - // copy the rgba value - u8 const* sourcePixel = rgba + 4*( width*sy + sx ); - for( int i = 0; i < 4; ++i ) - *targetPixel++ = *sourcePixel++; - } - } - - // compress it into the output - Compress( sourceRgba, targetBlock, flags ); - - // advance - targetBlock += bytesPerBlock; - } - } -} - -void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) -{ - // fix any bad flags - flags = FixFlags( flags ); - - // initialise the block input - u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; - - // loop over blocks - for( int y = 0; y < height; y += 4 ) - { - for( int x = 0; x < width; x += 4 ) - { - // decompress the block - u8 targetRgba[4*16]; - Decompress( targetRgba, sourceBlock, flags ); - - // write the decompressed pixels to the correct image locations - u8 const* sourcePixel = targetRgba; - for( int py = 0; py < 4; ++py ) - { - for( int px = 0; px < 4; ++px ) - { - // get the target location - int sx = x + px; - int sy = y + py; - if( sx < width && sy < height ) - { - u8* targetPixel = rgba + 4*( width*sy + sx ); - - // copy the rgba value - for( int i = 0; i < 4; ++i ) - *targetPixel++ = *sourcePixel++; - } - else - { - // skip this pixel as its outside the image - sourcePixel += 4; - } - } - } - - // advance - sourceBlock += bytesPerBlock; - } - } -} - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/squish.h b/Externals/NVTT/src/nvtt/squish/squish.h deleted file mode 100644 index fdd8fde35ef..00000000000 --- a/Externals/NVTT/src/nvtt/squish/squish.h +++ /dev/null @@ -1,244 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_H -#define SQUISH_H - -//! All squish API functions live in this namespace. -namespace squish { - -// ----------------------------------------------------------------------------- - -//! Typedef a quantity that is a single unsigned byte. -typedef unsigned char u8; - -// ----------------------------------------------------------------------------- - -enum -{ - //! Use DXT1 compression. - kDxt1 = ( 1 << 0 ), - - //! Use DXT3 compression. - kDxt3 = ( 1 << 1 ), - - //! Use DXT5 compression. - kDxt5 = ( 1 << 2 ), - - //! Use a slow but high quality colour compressor (the default). - kColourClusterFit = ( 1 << 3 ), - - //! Use a fast but low quality colour compressor. - kColourRangeFit = ( 1 << 4 ), - - //! Use a perceptual metric for colour error (the default). - kColourMetricPerceptual = ( 1 << 5 ), - - //! Use a uniform metric for colour error. - kColourMetricUniform = ( 1 << 6 ), - - //! Weight the colour by alpha during cluster fit (disabled by default). - kWeightColourByAlpha = ( 1 << 7 ) -}; - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses a 4x4 block of pixels. - - @param rgba The rgba values of the 16 source pixels. - @param block Storage for the compressed DXT block. - @param flags Compression flags. - - The source pixels should be presented as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for the compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor and - colour error metric to use when fitting the RGB components of the data. - Possible colour compressors are: kColourClusterFit (the default) or - kColourRangeFit. Possible colour error metrics are: kColourMetricPerceptual - (the default) or kColourMetricUniform. If no flags are specified in any - particular category then the default will be used. Unknown flags are - ignored. - - When using kColourClusterFit, an additional flag can be specified to - weight the colour of each pixel by its alpha value. For images that are - rendered using alpha blending, this can significantly increase the - perceived quality. -*/ -void Compress( u8 const* rgba, void* block, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses a 4x4 block of pixels. - - @param rgba The rgba values of the 16 source pixels. - @param mask The valid pixel mask. - @param block Storage for the compressed DXT block. - @param flags Compression flags. - - The source pixels should be presented as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The mask parameter enables only certain pixels within the block. The lowest - bit enables the first pixel and so on up to the 16th bit. Bits beyond the - 16th bit are ignored. Pixels that are not enabled are allowed to take - arbitrary colours in the output block. An example of how this can be used - is in the CompressImage function to disable pixels outside the bounds of - the image when the width or height is not divisible by 4. - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for the compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor and - colour error metric to use when fitting the RGB components of the data. - Possible colour compressors are: kColourClusterFit (the default) or - kColourRangeFit. Possible colour error metrics are: kColourMetricPerceptual - (the default) or kColourMetricUniform. If no flags are specified in any - particular category then the default will be used. Unknown flags are - ignored. - - When using kColourClusterFit, an additional flag can be specified to - weight the colour of each pixel by its alpha value. For images that are - rendered using alpha blending, this can significantly increase the - perceived quality. -*/ -void CompressMasked( u8 const* rgba, int mask, void* block, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Decompresses a 4x4 block of pixels. - - @param rgba Storage for the 16 decompressed pixels. - @param block The compressed DXT block. - @param flags Compression flags. - - The decompressed pixels will be written as a contiguous array of 16 rgba - values, with each component as 1 byte each. In memory this is: - - { r1, g1, b1, a1, .... , r16, g16, b16, a16 } - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. -*/ -void Decompress( u8* rgba, void const* block, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Computes the amount of compressed storage required. - - @param width The width of the image. - @param height The height of the image. - @param flags Compression flags. - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. - - Most DXT images will be a multiple of 4 in each dimension, but this - function supports arbitrary size images by allowing the outer blocks to - be only partially used. -*/ -int GetStorageRequirements( int width, int height, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Compresses an image in memory. - - @param rgba The pixels of the source. - @param width The width of the source image. - @param height The height of the source image. - @param blocks Storage for the compressed output. - @param flags Compression flags. - - The source pixels should be presented as a contiguous array of width*height - rgba values, with each component as 1 byte each. In memory this should be: - - { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. When using DXT1 - compression, 8 bytes of storage are required for each compressed DXT block. - DXT3 and DXT5 compression require 16 bytes of storage per block. - - The flags parameter can also specify a preferred colour compressor and - colour error metric to use when fitting the RGB components of the data. - Possible colour compressors are: kColourClusterFit (the default) or - kColourRangeFit. Possible colour error metrics are: kColourMetricPerceptual - (the default) or kColourMetricUniform. If no flags are specified in any - particular category then the default will be used. Unknown flags are - ignored. - - When using kColourClusterFit, an additional flag can be specified to - weight the colour of each pixel by its alpha value. For images that are - rendered using alpha blending, this can significantly increase the - perceived quality. - - Internally this function calls squish::Compress for each block. To see how - much memory is required in the compressed image, use - squish::GetStorageRequirements. -*/ -void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags ); - -// ----------------------------------------------------------------------------- - -/*! @brief Decompresses an image in memory. - - @param rgba Storage for the decompressed pixels. - @param width The width of the source image. - @param height The height of the source image. - @param blocks The compressed DXT blocks. - @param flags Compression flags. - - The decompressed pixels will be written as a contiguous array of width*height - 16 rgba values, with each component as 1 byte each. In memory this is: - - { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height - - The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, - however, DXT1 will be used by default if none is specified. All other flags - are ignored. - - Internally this function calls squish::Decompress for each block. -*/ -void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ); - -// ----------------------------------------------------------------------------- - -} // namespace squish - -#endif // ndef SQUISH_H - diff --git a/Externals/NVTT/src/nvtt/squish/squish.xcodeproj/project.pbxproj b/Externals/NVTT/src/nvtt/squish/squish.xcodeproj/project.pbxproj deleted file mode 100644 index 7812da80c77..00000000000 --- a/Externals/NVTT/src/nvtt/squish/squish.xcodeproj/project.pbxproj +++ /dev/null @@ -1,531 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 133FA0DC096A7B8E0050752E /* alpha.h in Headers */ = {isa = PBXBuildFile; fileRef = 133FA0DA096A7B8E0050752E /* alpha.h */; }; - 133FA0DD096A7B8E0050752E /* alpha.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 133FA0DB096A7B8E0050752E /* alpha.cpp */; }; - 1342B4160999DF1900152915 /* libsquish.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC046055464E500DB518D /* libsquish.a */; }; - 1342B41A0999DF7000152915 /* squishpng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1342B4190999DF7000152915 /* squishpng.cpp */; }; - 1342B43F0999E0CC00152915 /* squishtest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1342B43E0999E0CC00152915 /* squishtest.cpp */; }; - 1342B4420999E0EC00152915 /* libsquish.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC046055464E500DB518D /* libsquish.a */; }; - 1350D71A092AA858005EE038 /* clusterfit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1350D70B092AA857005EE038 /* clusterfit.cpp */; }; - 1350D71B092AA858005EE038 /* clusterfit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D70C092AA858005EE038 /* clusterfit.h */; }; - 1350D71E092AA858005EE038 /* colourblock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1350D70F092AA858005EE038 /* colourblock.cpp */; }; - 1350D71F092AA858005EE038 /* colourblock.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D710092AA858005EE038 /* colourblock.h */; }; - 1350D720092AA858005EE038 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D711092AA858005EE038 /* config.h */; }; - 1350D721092AA858005EE038 /* maths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1350D712092AA858005EE038 /* maths.cpp */; }; - 1350D722092AA858005EE038 /* maths.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D713092AA858005EE038 /* maths.h */; }; - 1350D725092AA858005EE038 /* rangefit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1350D716092AA858005EE038 /* rangefit.cpp */; }; - 1350D726092AA858005EE038 /* rangefit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D717092AA858005EE038 /* rangefit.h */; }; - 1350D727092AA858005EE038 /* squish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1350D718092AA858005EE038 /* squish.cpp */; }; - 1350D728092AA858005EE038 /* squish.h in Headers */ = {isa = PBXBuildFile; fileRef = 1350D719092AA858005EE038 /* squish.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 139C21CF09ADAB0800A2500D /* squishgen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139C21CE09ADAB0800A2500D /* squishgen.cpp */; }; - 139C234F09B0602700A2500D /* singlecolourfit.h in Headers */ = {isa = PBXBuildFile; fileRef = 139C234D09B0602700A2500D /* singlecolourfit.h */; }; - 139C235009B0602700A2500D /* singlecolourfit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139C234E09B0602700A2500D /* singlecolourfit.cpp */; }; - 13A7CCA40952BE63001C963A /* colourfit.h in Headers */ = {isa = PBXBuildFile; fileRef = 13A7CCA20952BE63001C963A /* colourfit.h */; }; - 13A7CCA50952BE63001C963A /* colourfit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13A7CCA30952BE63001C963A /* colourfit.cpp */; }; - 13C4C7AD0941C18000AC5B89 /* colourset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13C4C7AB0941C18000AC5B89 /* colourset.cpp */; }; - 13C4C7AE0941C18000AC5B89 /* colourset.h in Headers */ = {isa = PBXBuildFile; fileRef = 13C4C7AC0941C18000AC5B89 /* colourset.h */; }; - 13CD64C2092BCF8A00488C97 /* simd.h in Headers */ = {isa = PBXBuildFile; fileRef = 13CD64C0092BCF8A00488C97 /* simd.h */; }; - 13D0DC910931F93A00909807 /* simd_ve.h in Headers */ = {isa = PBXBuildFile; fileRef = 13D0DC900931F93A00909807 /* simd_ve.h */; }; - 13D0DC970931F9D600909807 /* simd_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = 13D0DC960931F9D600909807 /* simd_sse.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 1342B52B099BF72F00152915 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2AAC045055464E500DB518D; - remoteInfo = squish; - }; - 1342B58E099BF93D00152915 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2AAC045055464E500DB518D; - remoteInfo = squish; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 133FA0DA096A7B8E0050752E /* alpha.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alpha.h; sourceTree = ""; }; - 133FA0DB096A7B8E0050752E /* alpha.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = alpha.cpp; sourceTree = ""; }; - 1342B4110999DE7F00152915 /* squishpng */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = squishpng; sourceTree = BUILT_PRODUCTS_DIR; }; - 1342B4190999DF7000152915 /* squishpng.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = squishpng.cpp; path = extra/squishpng.cpp; sourceTree = ""; }; - 1342B4370999E07C00152915 /* squishtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = squishtest; sourceTree = BUILT_PRODUCTS_DIR; }; - 1342B43E0999E0CC00152915 /* squishtest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = squishtest.cpp; path = extra/squishtest.cpp; sourceTree = ""; }; - 1350D70B092AA857005EE038 /* clusterfit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clusterfit.cpp; sourceTree = ""; }; - 1350D70C092AA858005EE038 /* clusterfit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = clusterfit.h; sourceTree = ""; }; - 1350D70F092AA858005EE038 /* colourblock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = colourblock.cpp; sourceTree = ""; }; - 1350D710092AA858005EE038 /* colourblock.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = colourblock.h; sourceTree = ""; }; - 1350D711092AA858005EE038 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; - 1350D712092AA858005EE038 /* maths.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = maths.cpp; sourceTree = ""; }; - 1350D713092AA858005EE038 /* maths.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = maths.h; sourceTree = ""; }; - 1350D716092AA858005EE038 /* rangefit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = rangefit.cpp; sourceTree = ""; }; - 1350D717092AA858005EE038 /* rangefit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = rangefit.h; sourceTree = ""; }; - 1350D718092AA858005EE038 /* squish.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = squish.cpp; sourceTree = ""; }; - 1350D719092AA858005EE038 /* squish.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = squish.h; sourceTree = ""; }; - 13906CE3096938880000A6A7 /* texture_compression_s3tc.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = texture_compression_s3tc.txt; sourceTree = ""; }; - 139C21C409ADAA7000A2500D /* squishgen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = squishgen; sourceTree = BUILT_PRODUCTS_DIR; }; - 139C21CE09ADAB0800A2500D /* squishgen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = squishgen.cpp; path = extra/squishgen.cpp; sourceTree = ""; }; - 139C234D09B0602700A2500D /* singlecolourfit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = singlecolourfit.h; sourceTree = ""; }; - 139C234E09B0602700A2500D /* singlecolourfit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = singlecolourfit.cpp; sourceTree = ""; }; - 139C236D09B060A900A2500D /* singlecolourlookup.inl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = singlecolourlookup.inl; sourceTree = ""; }; - 13A7CCA20952BE63001C963A /* colourfit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colourfit.h; sourceTree = ""; }; - 13A7CCA30952BE63001C963A /* colourfit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = colourfit.cpp; sourceTree = ""; }; - 13C4C7AB0941C18000AC5B89 /* colourset.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = colourset.cpp; sourceTree = ""; }; - 13C4C7AC0941C18000AC5B89 /* colourset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = colourset.h; sourceTree = ""; }; - 13CD64C0092BCF8A00488C97 /* simd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simd.h; sourceTree = ""; }; - 13D0DC900931F93A00909807 /* simd_ve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simd_ve.h; sourceTree = ""; }; - 13D0DC960931F9D600909807 /* simd_sse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simd_sse.h; sourceTree = ""; }; - D2AAC046055464E500DB518D /* libsquish.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsquish.a; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1342B40F0999DE7F00152915 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 1342B4160999DF1900152915 /* libsquish.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1342B4350999E07C00152915 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 1342B4420999E0EC00152915 /* libsquish.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 139C21C209ADAA7000A2500D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D289987405E68DCB004EDB86 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* squish */ = { - isa = PBXGroup; - children = ( - 08FB7795FE84155DC02AAC07 /* Source */, - C6A0FF2B0290797F04C91782 /* Documentation */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = squish; - sourceTree = ""; - }; - 08FB7795FE84155DC02AAC07 /* Source */ = { - isa = PBXGroup; - children = ( - 133FA0DB096A7B8E0050752E /* alpha.cpp */, - 133FA0DA096A7B8E0050752E /* alpha.h */, - 1350D70B092AA857005EE038 /* clusterfit.cpp */, - 1350D70C092AA858005EE038 /* clusterfit.h */, - 13A7CCA30952BE63001C963A /* colourfit.cpp */, - 13A7CCA20952BE63001C963A /* colourfit.h */, - 13C4C7AB0941C18000AC5B89 /* colourset.cpp */, - 13C4C7AC0941C18000AC5B89 /* colourset.h */, - 1350D70F092AA858005EE038 /* colourblock.cpp */, - 1350D710092AA858005EE038 /* colourblock.h */, - 13906CE3096938880000A6A7 /* texture_compression_s3tc.txt */, - 1350D711092AA858005EE038 /* config.h */, - 1350D712092AA858005EE038 /* maths.cpp */, - 1350D713092AA858005EE038 /* maths.h */, - 1350D716092AA858005EE038 /* rangefit.cpp */, - 1350D717092AA858005EE038 /* rangefit.h */, - 13CD64C0092BCF8A00488C97 /* simd.h */, - 13D0DC960931F9D600909807 /* simd_sse.h */, - 13D0DC900931F93A00909807 /* simd_ve.h */, - 139C234E09B0602700A2500D /* singlecolourfit.cpp */, - 139C234D09B0602700A2500D /* singlecolourfit.h */, - 139C236D09B060A900A2500D /* singlecolourlookup.inl */, - 1350D718092AA858005EE038 /* squish.cpp */, - 1350D719092AA858005EE038 /* squish.h */, - 139C21CE09ADAB0800A2500D /* squishgen.cpp */, - 1342B4190999DF7000152915 /* squishpng.cpp */, - 1342B43E0999E0CC00152915 /* squishtest.cpp */, - ); - name = Source; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - D2AAC046055464E500DB518D /* libsquish.a */, - 1342B4110999DE7F00152915 /* squishpng */, - 1342B4370999E07C00152915 /* squishtest */, - 139C21C409ADAA7000A2500D /* squishgen */, - ); - name = Products; - sourceTree = ""; - }; - C6A0FF2B0290797F04C91782 /* Documentation */ = { - isa = PBXGroup; - children = ( - ); - name = Documentation; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC043055464E500DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 1350D71B092AA858005EE038 /* clusterfit.h in Headers */, - 1350D71F092AA858005EE038 /* colourblock.h in Headers */, - 1350D720092AA858005EE038 /* config.h in Headers */, - 1350D722092AA858005EE038 /* maths.h in Headers */, - 1350D726092AA858005EE038 /* rangefit.h in Headers */, - 1350D728092AA858005EE038 /* squish.h in Headers */, - 13CD64C2092BCF8A00488C97 /* simd.h in Headers */, - 13D0DC910931F93A00909807 /* simd_ve.h in Headers */, - 13D0DC970931F9D600909807 /* simd_sse.h in Headers */, - 13C4C7AE0941C18000AC5B89 /* colourset.h in Headers */, - 13A7CCA40952BE63001C963A /* colourfit.h in Headers */, - 133FA0DC096A7B8E0050752E /* alpha.h in Headers */, - 139C234F09B0602700A2500D /* singlecolourfit.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 1342B4100999DE7F00152915 /* squishpng */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1342B4130999DE9F00152915 /* Build configuration list for PBXNativeTarget "squishpng" */; - buildPhases = ( - 1342B40E0999DE7F00152915 /* Sources */, - 1342B40F0999DE7F00152915 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 1342B58F099BF93D00152915 /* PBXTargetDependency */, - ); - name = squishpng; - productName = squishpng; - productReference = 1342B4110999DE7F00152915 /* squishpng */; - productType = "com.apple.product-type.tool"; - }; - 1342B4360999E07C00152915 /* squishtest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1342B43B0999E0C000152915 /* Build configuration list for PBXNativeTarget "squishtest" */; - buildPhases = ( - 1342B4340999E07C00152915 /* Sources */, - 1342B4350999E07C00152915 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 1342B52C099BF72F00152915 /* PBXTargetDependency */, - ); - name = squishtest; - productName = squishtest; - productReference = 1342B4370999E07C00152915 /* squishtest */; - productType = "com.apple.product-type.tool"; - }; - 139C21C309ADAA7000A2500D /* squishgen */ = { - isa = PBXNativeTarget; - buildConfigurationList = 139C21CB09ADAB0300A2500D /* Build configuration list for PBXNativeTarget "squishgen" */; - buildPhases = ( - 139C21C109ADAA7000A2500D /* Sources */, - 139C21C209ADAA7000A2500D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = squishgen; - productName = squishgen; - productReference = 139C21C409ADAA7000A2500D /* squishgen */; - productType = "com.apple.product-type.tool"; - }; - D2AAC045055464E500DB518D /* squish */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "squish" */; - buildPhases = ( - D2AAC043055464E500DB518D /* Headers */, - D2AAC044055464E500DB518D /* Sources */, - D289987405E68DCB004EDB86 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = squish; - productName = squish; - productReference = D2AAC046055464E500DB518D /* libsquish.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "squish" */; - hasScannedForEncodings = 1; - mainGroup = 08FB7794FE84155DC02AAC07 /* squish */; - projectDirPath = ""; - targets = ( - D2AAC045055464E500DB518D /* squish */, - 1342B4100999DE7F00152915 /* squishpng */, - 1342B4360999E07C00152915 /* squishtest */, - 139C21C309ADAA7000A2500D /* squishgen */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 1342B40E0999DE7F00152915 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1342B41A0999DF7000152915 /* squishpng.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1342B4340999E07C00152915 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1342B43F0999E0CC00152915 /* squishtest.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 139C21C109ADAA7000A2500D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 139C21CF09ADAB0800A2500D /* squishgen.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2AAC044055464E500DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1350D71A092AA858005EE038 /* clusterfit.cpp in Sources */, - 1350D71E092AA858005EE038 /* colourblock.cpp in Sources */, - 1350D721092AA858005EE038 /* maths.cpp in Sources */, - 1350D725092AA858005EE038 /* rangefit.cpp in Sources */, - 1350D727092AA858005EE038 /* squish.cpp in Sources */, - 13C4C7AD0941C18000AC5B89 /* colourset.cpp in Sources */, - 13A7CCA50952BE63001C963A /* colourfit.cpp in Sources */, - 133FA0DD096A7B8E0050752E /* alpha.cpp in Sources */, - 139C235009B0602700A2500D /* singlecolourfit.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 1342B52C099BF72F00152915 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2AAC045055464E500DB518D /* squish */; - targetProxy = 1342B52B099BF72F00152915 /* PBXContainerItemProxy */; - }; - 1342B58F099BF93D00152915 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2AAC045055464E500DB518D /* squish */; - targetProxy = 1342B58E099BF93D00152915 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 1342B4140999DE9F00152915 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - .., - /sw/include, - ); - INSTALL_PATH = "$(HOME)/bin"; - LIBRARY_SEARCH_PATHS = /sw/lib; - OTHER_LDFLAGS = "-lpng"; - PRODUCT_NAME = squishpng; - }; - name = Debug; - }; - 1342B4150999DE9F00152915 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - .., - /sw/include, - ); - INSTALL_PATH = "$(HOME)/bin"; - LIBRARY_SEARCH_PATHS = /sw/lib; - OTHER_LDFLAGS = "-lpng"; - PRODUCT_NAME = squishpng; - }; - name = Release; - }; - 1342B43C0999E0C000152915 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ..; - INSTALL_PATH = "$(HOME)/bin"; - PRODUCT_NAME = squishtest; - }; - name = Debug; - }; - 1342B43D0999E0C000152915 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ..; - INSTALL_PATH = "$(HOME)/bin"; - PRODUCT_NAME = squishtest; - }; - name = Release; - }; - 139C21CC09ADAB0300A2500D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ..; - INSTALL_PATH = "$(HOME)/bin"; - PRODUCT_NAME = squishgen; - }; - name = Debug; - }; - 139C21CD09ADAB0300A2500D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ..; - INSTALL_PATH = "$(HOME)/bin"; - PRODUCT_NAME = squishgen; - }; - name = Release; - }; - 1DEB91EC08733DB70010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_PREPROCESSOR_DEFINITIONS = "SQUISH_USE_ALTIVEC=1"; - INSTALL_PATH = /usr/local/lib; - OTHER_CFLAGS = "-maltivec"; - PRODUCT_NAME = squish; - STRIP_INSTALLED_PRODUCT = NO; - }; - name = Debug; - }; - 1DEB91ED08733DB70010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = "SQUISH_USE_ALTIVEC=1"; - INSTALL_PATH = /usr/local/lib; - OTHER_CFLAGS = "-maltivec"; - PRODUCT_NAME = squish; - STRIP_INSTALLED_PRODUCT = YES; - }; - name = Release; - }; - 1DEB91F008733DB70010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_DYNAMIC_NO_PIC = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_PEDANTIC = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - }; - name = Debug; - }; - 1DEB91F108733DB70010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_DYNAMIC_NO_PIC = YES; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_UNROLL_LOOPS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_PEDANTIC = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1342B4130999DE9F00152915 /* Build configuration list for PBXNativeTarget "squishpng" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1342B4140999DE9F00152915 /* Debug */, - 1342B4150999DE9F00152915 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1342B43B0999E0C000152915 /* Build configuration list for PBXNativeTarget "squishtest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1342B43C0999E0C000152915 /* Debug */, - 1342B43D0999E0C000152915 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 139C21CB09ADAB0300A2500D /* Build configuration list for PBXNativeTarget "squishgen" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 139C21CC09ADAB0300A2500D /* Debug */, - 139C21CD09ADAB0300A2500D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "squish" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91EC08733DB70010E9CD /* Debug */, - 1DEB91ED08733DB70010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "squish" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91F008733DB70010E9CD /* Debug */, - 1DEB91F108733DB70010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/Externals/NVTT/src/nvtt/squish/texture_compression_s3tc.txt b/Externals/NVTT/src/nvtt/squish/texture_compression_s3tc.txt deleted file mode 100644 index f229cf36789..00000000000 --- a/Externals/NVTT/src/nvtt/squish/texture_compression_s3tc.txt +++ /dev/null @@ -1,508 +0,0 @@ -Name - - EXT_texture_compression_s3tc - -Name Strings - - GL_EXT_texture_compression_s3tc - -Contact - - Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) - -Status - - FINAL - -Version - - 1.1, 16 November 2001 (containing only clarifications relative to - version 1.0, dated 7 July 2000) - -Number - - 198 - -Dependencies - - OpenGL 1.1 is required. - - GL_ARB_texture_compression is required. - - This extension is written against the OpenGL 1.2.1 Specification. - -Overview - - This extension provides additional texture compression functionality - specific to S3's S3TC format (called DXTC in Microsoft's DirectX API), - subject to all the requirements and limitations described by the extension - GL_ARB_texture_compression. - - This extension supports DXT1, DXT3, and DXT5 texture compression formats. - For the DXT1 image format, this specification supports an RGB-only mode - and a special RGBA mode with single-bit "transparent" alpha. - -IP Status - - Contact S3 Incorporated (http://www.s3.com) regarding any intellectual - property issues associated with implementing this extension. - - WARNING: Vendors able to support S3TC texture compression in Direct3D - drivers do not necessarily have the right to use the same functionality in - OpenGL. - -Issues - - (1) Should DXT2 and DXT4 (premultiplied alpha) formats be supported? - - RESOLVED: No -- insufficient interest. Supporting DXT2 and DXT4 - would require some rework to the TexEnv definition (maybe add a new - base internal format RGBA_PREMULTIPLIED_ALPHA) for these formats. - Note that the EXT_texture_env_combine extension (which extends normal - TexEnv modes) can be used to support textures with premultipled alpha. - - (2) Should generic "RGB_S3TC_EXT" and "RGBA_S3TC_EXT" enums be supported - or should we use only the DXT enums? - - RESOLVED: No. A generic RGBA_S3TC_EXT is problematic because DXT3 - and DXT5 are both nominally RGBA (and DXT1 with the 1-bit alpha is - also) yet one format must be chosen up front. - - (3) Should TexSubImage support all block-aligned edits or just the minimal - functionality required by the ARB_texture_compression extension? - - RESOLVED: Allow all valid block-aligned edits. - - (4) A pre-compressed image with a DXT1 format can be used as either an - RGB_S3TC_DXT1 or an RGBA_S3TC_DXT1 image. If the image has - transparent texels, how are they treated in each format? - - RESOLVED: The renderer has to make sure that an RGB_S3TC_DXT1 format - is decoded as RGB (where alpha is effectively one for all texels), - while RGBA_S3TC_DXT1 is decoded as RGBA (where alpha is zero for all - texels with "transparent" encodings). Otherwise, the formats are - identical. - - (5) Is the encoding of the RGB components for DXT1 formats correct in this - spec? MSDN documentation does not specify an RGB color for the - "transparent" encoding. Is it really black? - - RESOLVED: Yes. The specification for the DXT1 format initially - required black, but later changed that requirement to a - recommendation. All vendors involved in the definition of this - specification support black. In addition, specifying black has a - useful behavior. - - When blending multiple texels (GL_LINEAR filtering), mixing opaque and - transparent samples is problematic. Defining a black color on - transparent texels achieves a sensible result that works like a - texture with premultiplied alpha. For example, if three opaque white - and one transparent sample is being averaged, the result would be a - 75% intensity gray (with an alpha of 75%). This is the same result on - the color channels as would be obtained using a white color, 75% - alpha, and a SRC_ALPHA blend factor. - - (6) Is the encoding of the RGB components for DXT3 and DXT5 formats - correct in this spec? MSDN documentation suggests that the RGB blocks - for DXT3 and DXT5 are decoded as described by the DXT1 format. - - RESOLVED: Yes -- this appears to be a bug in the MSDN documentation. - The specification for the DXT2-DXT5 formats require decoding using the - opaque block encoding, regardless of the relative values of "color0" - and "color1". - -New Procedures and Functions - - None. - -New Tokens - - Accepted by the parameter of TexImage2D, CopyTexImage2D, - and CompressedTexImage2DARB and the parameter of - CompressedTexSubImage2DARB: - - COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 - COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 - COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 - COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - -Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation) - - None. - -Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization) - - Add to Table 3.16.1: Specific Compressed Internal Formats - - Compressed Internal Format Base Internal Format - ========================== ==================== - COMPRESSED_RGB_S3TC_DXT1_EXT RGB - COMPRESSED_RGBA_S3TC_DXT1_EXT RGBA - COMPRESSED_RGBA_S3TC_DXT3_EXT RGBA - COMPRESSED_RGBA_S3TC_DXT5_EXT RGBA - - - Modify Section 3.8.2, Alternate Image Specification - - (add to end of TexSubImage discussion, p.123 -- after edit from the - ARB_texture_compression spec) - - If the internal format of the texture image being modified is - COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the - texture is stored using one of the several S3TC compressed texture image - formats. Such images are easily edited along 4x4 texel boundaries, so the - limitations on TexSubImage2D or CopyTexSubImage2D parameters are relaxed. - TexSubImage2D and CopyTexSubImage2D will result in an INVALID_OPERATION - error only if one of the following conditions occurs: - - * is not a multiple of four or equal to TEXTURE_WIDTH, - unless and are both zero. - * is not a multiple of four or equal to TEXTURE_HEIGHT, - unless and are both zero. - * or is not a multiple of four. - - The contents of any 4x4 block of texels of an S3TC compressed texture - image that does not intersect the area being modified are preserved during - valid TexSubImage2D and CopyTexSubImage2D calls. - - - Add to Section 3.8.2, Alternate Image Specification (adding to the end of - the CompressedTexImage section introduced by the ARB_texture_compression - spec) - - If is COMPRESSED_RGB_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or - COMPRESSED_RGBA_S3TC_DXT5_EXT, the compressed texture is stored using one - of several S3TC compressed texture image formats. The S3TC texture - compression algorithm supports only 2D images without borders. - CompressedTexImage1DARB and CompressedTexImage3DARB produce an - INVALID_ENUM error if is an S3TC format. - CompressedTexImage2DARB will produce an INVALID_OPERATION error if - is non-zero. - - - Add to Section 3.8.2, Alternate Image Specification (adding to the end of - the CompressedTexSubImage section introduced by the - ARB_texture_compression spec) - - If the internal format of the texture image being modified is - COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the - texture is stored using one of the several S3TC compressed texture image - formats. Since the S3TC texture compression algorithm supports only 2D - images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB produce - an INVALID_ENUM error if is an S3TC format. Since S3TC images - are easily edited along 4x4 texel boundaries, the limitations on - CompressedTexSubImage2D are relaxed. CompressedTexSubImage2D will result - in an INVALID_OPERATION error only if one of the following conditions - occurs: - - * is not a multiple of four or equal to TEXTURE_WIDTH. - * is not a multiple of four or equal to TEXTURE_HEIGHT. - * or is not a multiple of four. - - The contents of any 4x4 block of texels of an S3TC compressed texture - image that does not intersect the area being modified are preserved during - valid TexSubImage2D and CopyTexSubImage2D calls. - -Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment -Operations and the Frame Buffer) - - None. - -Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions) - - None. - -Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and -State Requests) - - None. - -Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance) - - None. - -Additions to the AGL/GLX/WGL Specifications - - None. - -GLX Protocol - - None. - -Errors - - INVALID_ENUM is generated by CompressedTexImage1DARB or - CompressedTexImage3DARB if is - COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT. - - INVALID_OPERATION is generated by CompressedTexImage2DARB if - is COMPRESSED_RGB_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or - COMPRESSED_RGBA_S3TC_DXT5_EXT and is not equal to zero. - - INVALID_ENUM is generated by CompressedTexSubImage1DARB or - CompressedTexSubImage3DARB if is COMPRESSED_RGB_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or - COMPRESSED_RGBA_S3TC_DXT5_EXT. - - INVALID_OPERATION is generated by TexSubImage2D CopyTexSubImage2D, or - CompressedTexSubImage2D if TEXTURE_INTERNAL_FORMAT is - COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, - COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT and any of - the following apply: is not a multiple of four or equal to - TEXTURE_WIDTH; is not a multiple of four or equal to - TEXTURE_HEIGHT; or is not a multiple of four. - - - The following restrictions from the ARB_texture_compression specification - do not apply to S3TC texture formats, since subimage modification is - straightforward as long as the subimage is properly aligned. - - DELETE: INVALID_OPERATION is generated by TexSubImage1D, TexSubImage2D, - DELETE: TexSubImage3D, CopyTexSubImage1D, CopyTexSubImage2D, or - DELETE: CopyTexSubImage3D if the internal format of the texture image is - DELETE: compressed and , , or does not equal - DELETE: -b, where b is value of TEXTURE_BORDER. - - DELETE: INVALID_VALUE is generated by CompressedTexSubImage1DARB, - DELETE: CompressedTexSubImage2DARB, or CompressedTexSubImage3DARB if the - DELETE: entire texture image is not being edited: if , - DELETE: , or is greater than -b, + is - DELETE: less than w+b, + is less than h+b, or - DELETE: + is less than d+b, where b is the value of - DELETE: TEXTURE_BORDER, w is the value of TEXTURE_WIDTH, h is the value of - DELETE: TEXTURE_HEIGHT, and d is the value of TEXTURE_DEPTH. - - See also errors in the GL_ARB_texture_compression specification. - -New State - - In the "Textures" state table, increment the TEXTURE_INTERNAL_FORMAT - subscript for Z by 4 in the "Type" row. - -New Implementation Dependent State - - None - -Appendix - - S3TC Compressed Texture Image Formats - - Compressed texture images stored using the S3TC compressed image formats - are represented as a collection of 4x4 texel blocks, where each block - contains 64 or 128 bits of texel data. The image is encoded as a normal - 2D raster image in which each 4x4 block is treated as a single pixel. If - an S3TC image has a width or height less than four, the data corresponding - to texels outside the image are irrelevant and undefined. - - When an S3TC image with a width of , height of , and block size of - (8 or 16 bytes) is decoded, the corresponding image size (in - bytes) is: - - ceil(/4) * ceil(/4) * blocksize. - - When decoding an S3TC image, the block containing the texel at offset - (, ) begins at an offset (in bytes) relative to the base of the - image of: - - blocksize * (ceil(/4) * floor(/4) + floor(/4)). - - The data corresponding to a specific texel (, ) are extracted from a - 4x4 texel block using a relative (x,y) value of - - ( modulo 4, modulo 4). - - There are four distinct S3TC image formats: - - COMPRESSED_RGB_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64 - bits of RGB image data. - - Each RGB image data block is encoded as a sequence of 8 bytes, called (in - order of increasing address): - - c0_lo, c0_hi, c1_lo, c1_hi, bits_0, bits_1, bits_2, bits_3 - - The 8 bytes of the block are decoded into three quantities: - - color0 = c0_lo + c0_hi * 256 - color1 = c1_lo + c1_hi * 256 - bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3)) - - color0 and color1 are 16-bit unsigned integers that are unpacked to - RGB colors RGB0 and RGB1 as though they were 16-bit packed pixels with - a of RGB and a type of UNSIGNED_SHORT_5_6_5. - - bits is a 32-bit unsigned integer, from which a two-bit control code - is extracted for a texel at location (x,y) in the block using: - - code(x,y) = bits[2*(4*y+x)+1..2*(4*y+x)+0] - - where bit 31 is the most significant and bit 0 is the least - significant bit. - - The RGB color for a texel at location (x,y) in the block is given by: - - RGB0, if color0 > color1 and code(x,y) == 0 - RGB1, if color0 > color1 and code(x,y) == 1 - (2*RGB0+RGB1)/3, if color0 > color1 and code(x,y) == 2 - (RGB0+2*RGB1)/3, if color0 > color1 and code(x,y) == 3 - - RGB0, if color0 <= color1 and code(x,y) == 0 - RGB1, if color0 <= color1 and code(x,y) == 1 - (RGB0+RGB1)/2, if color0 <= color1 and code(x,y) == 2 - BLACK, if color0 <= color1 and code(x,y) == 3 - - Arithmetic operations are done per component, and BLACK refers to an - RGB color where red, green, and blue are all zero. - - Since this image has an RGB format, there is no alpha component and the - image is considered fully opaque. - - - COMPRESSED_RGBA_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64 - bits of RGB image data and minimal alpha information. The RGB components - of a texel are extracted in the same way as COMPRESSED_RGB_S3TC_DXT1_EXT. - - The alpha component for a texel at location (x,y) in the block is - given by: - - 0.0, if color0 <= color1 and code(x,y) == 3 - 1.0, otherwise - - IMPORTANT: When encoding an RGBA image into a format using 1-bit - alpha, any texels with an alpha component less than 0.5 end up with an - alpha of 0.0 and any texels with an alpha component greater than or - equal to 0.5 end up with an alpha of 1.0. When encoding an RGBA image - into the COMPRESSED_RGBA_S3TC_DXT1_EXT format, the resulting red, - green, and blue components of any texels with a final alpha of 0.0 - will automatically be zero (black). If this behavior is not desired - by an application, it should not use COMPRESSED_RGBA_S3TC_DXT1_EXT. - This format will never be used when a generic compressed internal - format (Table 3.16.2) is specified, although the nearly identical - format COMPRESSED_RGB_S3TC_DXT1_EXT (above) may be. - - - COMPRESSED_RGBA_S3TC_DXT3_EXT: Each 4x4 block of texels consists of 64 - bits of uncompressed alpha image data followed by 64 bits of RGB image - data. - - Each RGB image data block is encoded according to the - COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code - bits always use the non-transparent encodings. In other words, they are - treated as though color0 > color1, regardless of the actual values of - color0 and color1. - - Each alpha image data block is encoded as a sequence of 8 bytes, called - (in order of increasing address): - - a0, a1, a2, a3, a4, a5, a6, a7 - - The 8 bytes of the block are decoded into one 64-bit integer: - - alpha = a0 + 256 * (a1 + 256 * (a2 + 256 * (a3 + 256 * (a4 + - 256 * (a5 + 256 * (a6 + 256 * a7)))))) - - alpha is a 64-bit unsigned integer, from which a four-bit alpha value - is extracted for a texel at location (x,y) in the block using: - - alpha(x,y) = bits[4*(4*y+x)+3..4*(4*y+x)+0] - - where bit 63 is the most significant and bit 0 is the least - significant bit. - - The alpha component for a texel at location (x,y) in the block is - given by alpha(x,y) / 15. - - - COMPRESSED_RGBA_S3TC_DXT5_EXT: Each 4x4 block of texels consists of 64 - bits of compressed alpha image data followed by 64 bits of RGB image data. - - Each RGB image data block is encoded according to the - COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code - bits always use the non-transparent encodings. In other words, they are - treated as though color0 > color1, regardless of the actual values of - color0 and color1. - - Each alpha image data block is encoded as a sequence of 8 bytes, called - (in order of increasing address): - - alpha0, alpha1, bits_0, bits_1, bits_2, bits_3, bits_4, bits_5 - - The alpha0 and alpha1 are 8-bit unsigned bytes converted to alpha - components by multiplying by 1/255. - - The 6 "bits" bytes of the block are decoded into one 48-bit integer: - - bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + - 256 * (bits_4 + 256 * bits_5)))) - - bits is a 48-bit unsigned integer, from which a three-bit control code - is extracted for a texel at location (x,y) in the block using: - - code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] - - where bit 47 is the most significant and bit 0 is the least - significant bit. - - The alpha component for a texel at location (x,y) in the block is - given by: - - alpha0, code(x,y) == 0 - alpha1, code(x,y) == 1 - - (6*alpha0 + 1*alpha1)/7, alpha0 > alpha1 and code(x,y) == 2 - (5*alpha0 + 2*alpha1)/7, alpha0 > alpha1 and code(x,y) == 3 - (4*alpha0 + 3*alpha1)/7, alpha0 > alpha1 and code(x,y) == 4 - (3*alpha0 + 4*alpha1)/7, alpha0 > alpha1 and code(x,y) == 5 - (2*alpha0 + 5*alpha1)/7, alpha0 > alpha1 and code(x,y) == 6 - (1*alpha0 + 6*alpha1)/7, alpha0 > alpha1 and code(x,y) == 7 - - (4*alpha0 + 1*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 2 - (3*alpha0 + 2*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 3 - (2*alpha0 + 3*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 4 - (1*alpha0 + 4*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 5 - 0.0, alpha0 <= alpha1 and code(x,y) == 6 - 1.0, alpha0 <= alpha1 and code(x,y) == 7 - - -Revision History - - 1.1, 11/16/01 pbrown: Updated contact info, clarified where texels - fall within a single block. - - 1.0, 07/07/00 prbrown1: Published final version agreed to by working - group members. - - 0.9, 06/24/00 prbrown1: Documented that block-aligned TexSubImage calls - do not modify existing texels outside the - modified blocks. Added caveat to allow for a - (0,0)-anchored TexSubImage operation of - arbitrary size. - - 0.7, 04/11/00 prbrown1: Added issues on DXT1, DXT3, and DXT5 encodings - where the MSDN documentation doesn't match what - is really done. Added enum values from the - extension registry. - - 0.4, 03/28/00 prbrown1: Updated to reflect final version of the - ARB_texture_compression extension. Allowed - block-aligned TexSubImage calls. - - 0.3, 03/07/00 prbrown1: Resolved issues pertaining to the format of RGB - blocks in the DXT3 and DXT5 formats (they don't - ever use the "transparent" encoding). Fixed - decoding of DXT1 blocks. Pointed out issue of - "transparent" texels in DXT1 encodings having - different behaviors for RGB and RGBA internal - formats. - - 0.2, 02/23/00 prbrown1: Minor revisions; added several issues. - - 0.11, 02/17/00 prbrown1: Slight modification to error semantics - (INVALID_ENUM instead of INVALID_OPERATION). - - 0.1, 02/15/00 prbrown1: Initial revision. diff --git a/Externals/NVTT/src/nvtt/squish/weightedclusterfit.cpp b/Externals/NVTT/src/nvtt/squish/weightedclusterfit.cpp deleted file mode 100644 index d200f15767e..00000000000 --- a/Externals/NVTT/src/nvtt/squish/weightedclusterfit.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/* ----------------------------------------------------------------------------- - -Copyright (c) 2006 Simon Brown si@sjbrown.co.uk -Copyright (c) 2006 Ignacio Castano icastano@nvidia.com - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------------------------------------------------------------------- */ - -#include "weightedclusterfit.h" -#include "colourset.h" -#include "colourblock.h" -#include - - -namespace squish { - - WeightedClusterFit::WeightedClusterFit() - { - } - - void WeightedClusterFit::SetColourSet( ColourSet const* colours, int flags ) - { - ColourFit::SetColourSet( colours, flags ); - - // initialise the best error -#if SQUISH_USE_SIMD - m_besterror = VEC4_CONST( FLT_MAX ); - Vec3 metric = m_metric.GetVec3(); -#else - m_besterror = FLT_MAX; - Vec3 metric = m_metric; -#endif - - // cache some values - int const count = m_colours->GetCount(); - Vec3 const* values = m_colours->GetPoints(); - - // get the covariance matrix - Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights(), metric ); - - // compute the principle component - Vec3 principle = ComputePrincipleComponent( covariance ); - - // build the list of values - float dps[16]; - for( int i = 0; i < count; ++i ) - { - dps[i] = Dot( values[i], principle ); - m_order[i] = i; - } - - // stable sort - for( int i = 0; i < count; ++i ) - { - for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) - { - std::swap( dps[j], dps[j - 1] ); - std::swap( m_order[j], m_order[j - 1] ); - } - } - - // weight all the points -#if SQUISH_USE_SIMD - Vec4 const* unweighted = m_colours->GetPointsSimd(); - Vec4 const* weights = m_colours->GetWeightsSimd(); - m_xxsum = VEC4_CONST( 0.0f ); - m_xsum = VEC4_CONST( 0.0f ); -#else - Vec3 const* unweighted = m_colours->GetPoints(); - float const* weights = m_colours->GetWeights(); - m_xxsum = Vec3( 0.0f ); - m_xsum = Vec3( 0.0f ); - m_wsum = 0.0f; -#endif - - for( int i = 0; i < count; ++i ) - { - int p = m_order[i]; - m_weighted[i] = weights[p] * unweighted[p]; - m_xxsum += m_weighted[i] * m_weighted[i]; - m_xsum += m_weighted[i]; -#if !SQUISH_USE_SIMD - m_weights[i] = weights[p]; - m_wsum += m_weights[i]; -#endif - } - } - - - void WeightedClusterFit::SetMetric(float r, float g, float b) - { -#if SQUISH_USE_SIMD - m_metric = Vec4(r, g, b, 0); -#else - m_metric = Vec3(r, g, b); -#endif - m_metricSqr = m_metric * m_metric; - } - - float WeightedClusterFit::GetBestError() const - { -#if SQUISH_USE_SIMD - Vec4 x = m_xxsum * m_metricSqr; - Vec4 error = m_besterror + x.SplatX() + x.SplatY() + x.SplatZ(); - return error.GetVec3().X(); -#else - return m_besterror + Dot(m_xxsum, m_metricSqr); -#endif - - } - -#if SQUISH_USE_SIMD - - void WeightedClusterFit::Compress3( void* block ) - { - int const count = m_colours->GetCount(); - Vec4 const one = VEC4_CONST(1.0f); - Vec4 const zero = VEC4_CONST(0.0f); - Vec4 const half(0.5f, 0.5f, 0.5f, 0.25f); - Vec4 const two = VEC4_CONST(2.0); - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); - - // declare variables - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = VEC4_CONST( FLT_MAX ); - - Vec4 x0 = zero; - - int b0 = 0, b1 = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= count; c0++) - { - Vec4 x1 = zero; - - for( int c1 = 0; c1 <= count-c0; c1++) - { - Vec4 const x2 = m_xsum - x1 - x0; - - //Vec3 const alphax_sum = x0 + x1 * 0.5f; - //float const alpha2_sum = w0 + w1 * 0.25f; - Vec4 const alphax_sum = MultiplyAdd(x1, half, x0); // alphax_sum, alpha2_sum - Vec4 const alpha2_sum = alphax_sum.SplatW(); - - //Vec3 const betax_sum = x2 + x1 * 0.5f; - //float const beta2_sum = w2 + w1 * 0.25f; - Vec4 const betax_sum = MultiplyAdd(x1, half, x2); // betax_sum, beta2_sum - Vec4 const beta2_sum = betax_sum.SplatW(); - - //float const alphabeta_sum = w1 * 0.25f; - Vec4 const alphabeta_sum = (x1 * half).SplatW(); // alphabeta_sum - - // float const factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - Vec4 const factor = Reciprocal( NegativeMultiplySubtract(alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum) ); - - Vec4 a = NegativeMultiplySubtract(betax_sum, alphabeta_sum, alphax_sum*beta2_sum) * factor; - Vec4 b = NegativeMultiplySubtract(alphax_sum, alphabeta_sum, betax_sum*alpha2_sum) * factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Truncate( MultiplyAdd( grid, a, half ) ) * gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) ) * gridrcp; - - // compute the error (we skip the constant xxsum) - Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); - Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); - Vec4 e4 = MultiplyAdd( two, e3, e1 ); - - // apply the metric to the error term - Vec4 e5 = e4 * m_metricSqr; - Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - } - - x1 += m_weighted[c0+c1]; - } - - x0 += m_weighted[c0]; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // compute indices from cluster sizes. - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < count; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < count; ++i ) - ordered[m_order[i]] = bestindices[i]; - - m_colours->RemapIndices( ordered, bestindices ); - - - // save the block - WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); - - // save the error - m_besterror = besterror; - } - } - - void WeightedClusterFit::Compress4( void* block ) - { - int const count = m_colours->GetCount(); - Vec4 const one = VEC4_CONST(1.0f); - Vec4 const zero = VEC4_CONST(0.0f); - Vec4 const half = VEC4_CONST(0.5f); - Vec4 const two = VEC4_CONST(2.0); - Vec4 const onethird( 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/9.0f ); - Vec4 const twothirds( 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, 4.0f/9.0f ); - Vec4 const twonineths = VEC4_CONST( 2.0f/9.0f ); - Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); - Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); - - // declare variables - Vec4 beststart = VEC4_CONST( 0.0f ); - Vec4 bestend = VEC4_CONST( 0.0f ); - Vec4 besterror = VEC4_CONST( FLT_MAX ); - - Vec4 x0 = zero; - int b0 = 0, b1 = 0, b2 = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= count; c0++) - { - Vec4 x1 = zero; - - for( int c1 = 0; c1 <= count-c0; c1++) - { - Vec4 x2 = zero; - - for( int c2 = 0; c2 <= count-c0-c1; c2++) - { - Vec4 const x3 = m_xsum - x2 - x1 - x0; - - //Vec3 const alphax_sum = x0 + x1 * (2.0f / 3.0f) + x2 * (1.0f / 3.0f); - //float const alpha2_sum = w0 + w1 * (4.0f/9.0f) + w2 * (1.0f/9.0f); - Vec4 const alphax_sum = MultiplyAdd(x2, onethird, MultiplyAdd(x1, twothirds, x0)); // alphax_sum, alpha2_sum - Vec4 const alpha2_sum = alphax_sum.SplatW(); - - //Vec3 const betax_sum = x3 + x2 * (2.0f / 3.0f) + x1 * (1.0f / 3.0f); - //float const beta2_sum = w3 + w2 * (4.0f/9.0f) + w1 * (1.0f/9.0f); - Vec4 const betax_sum = MultiplyAdd(x2, twothirds, MultiplyAdd(x1, onethird, x3)); // betax_sum, beta2_sum - Vec4 const beta2_sum = betax_sum.SplatW(); - - //float const alphabeta_sum = (w1 + w2) * (2.0f/9.0f); - Vec4 const alphabeta_sum = twonineths*( x1 + x2 ).SplatW(); // alphabeta_sum - - // float const factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - Vec4 const factor = Reciprocal( NegativeMultiplySubtract(alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum) ); - - Vec4 a = NegativeMultiplySubtract(betax_sum, alphabeta_sum, alphax_sum*beta2_sum) * factor; - Vec4 b = NegativeMultiplySubtract(alphax_sum, alphabeta_sum, betax_sum*alpha2_sum) * factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Truncate( MultiplyAdd( grid, a, half ) ) * gridrcp; - b = Truncate( MultiplyAdd( grid, b, half ) ) * gridrcp; - - // compute the error (we skip the constant xxsum) - Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); - Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); - Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); - Vec4 e4 = MultiplyAdd( two, e3, e1 ); - - // apply the metric to the error term - Vec4 e5 = e4 * m_metricSqr; - Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); - - // keep the solution if it wins - if( CompareAnyLessThan( error, besterror ) ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - b2 = c2; - } - - x2 += m_weighted[c0+c1+c2]; - } - - x1 += m_weighted[c0+c1]; - } - - x0 += m_weighted[c0]; - } - - // save the block if necessary - if( CompareAnyLessThan( besterror, m_besterror ) ) - { - // compute indices from cluster sizes. - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < b0+b1+b2; i++) { - bestindices[i] = 3; - } - for(; i < count; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < count; ++i ) - ordered[m_order[i]] = bestindices[i]; - - m_colours->RemapIndices( ordered, bestindices ); - - // save the block - WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); - - // save the error - m_besterror = besterror; - } - } - -#else - - void WeightedClusterFit::Compress3( void* block ) - { - int const count = m_colours->GetCount(); - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - Vec3 const half( 0.5f ); - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); - - // declare variables - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = FLT_MAX; - - Vec3 x0(0.0f); - float w0 = 0.0f; - - int b0 = 0, b1 = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= count; c0++) - { - Vec3 x1(0.0f); - float w1 = 0.0f; - - for( int c1 = 0; c1 <= count-c0; c1++) - { - float w2 = m_wsum - w0 - w1; - - // These factors could be entirely precomputed. - float const alpha2_sum = w0 + w1 * 0.25f; - float const beta2_sum = w2 + w1 * 0.25f; - float const alphabeta_sum = w1 * 0.25f; - float const factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - Vec3 const alphax_sum = x0 + x1 * 0.5f; - Vec3 const betax_sum = m_xsum - alphax_sum; - - Vec3 a = (alphax_sum*beta2_sum - betax_sum*alphabeta_sum) * factor; - Vec3 b = (betax_sum*alpha2_sum - alphax_sum*alphabeta_sum) * factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Floor( grid*a + half )*gridrcp; - b = Floor( grid*b + half )*gridrcp; - - // compute the error - Vec3 e1 = a*a*alpha2_sum + b*b*beta2_sum + 2.0f*( a*b*alphabeta_sum - a*alphax_sum - b*betax_sum ); - - // apply the metric to the error term - float error = Dot( e1, m_metricSqr ); - - // keep the solution if it wins - if( error < besterror ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - } - - x1 += m_weighted[c0+c1]; - w1 += m_weights[c0+c1]; - } - - x0 += m_weighted[c0]; - w0 += m_weights[c0]; - } - - // save the block if necessary - if( besterror < m_besterror ) - { - // compute indices from cluster sizes. - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < count; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < count; ++i ) - ordered[m_order[i]] = bestindices[i]; - - m_colours->RemapIndices( ordered, bestindices ); - - // save the block - WriteColourBlock3( beststart, bestend, bestindices, block ); - - // save the error - m_besterror = besterror; - } - } - - void WeightedClusterFit::Compress4( void* block ) - { - int const count = m_colours->GetCount(); - Vec3 const one( 1.0f ); - Vec3 const zero( 0.0f ); - Vec3 const half( 0.5f ); - Vec3 const grid( 31.0f, 63.0f, 31.0f ); - Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); - - // declare variables - Vec3 beststart( 0.0f ); - Vec3 bestend( 0.0f ); - float besterror = FLT_MAX; - - Vec3 x0(0.0f); - float w0 = 0.0f; - int b0 = 0, b1 = 0, b2 = 0; - - // check all possible clusters for this total order - for( int c0 = 0; c0 <= count; c0++) - { - Vec3 x1(0.0f); - float w1 = 0.0f; - - for( int c1 = 0; c1 <= count-c0; c1++) - { - Vec3 x2(0.0f); - float w2 = 0.0f; - - for( int c2 = 0; c2 <= count-c0-c1; c2++) - { - float w3 = m_wsum - w0 - w1 - w2; - - float const alpha2_sum = w0 + w1 * (4.0f/9.0f) + w2 * (1.0f/9.0f); - float const beta2_sum = w3 + w2 * (4.0f/9.0f) + w1 * (1.0f/9.0f); - float const alphabeta_sum = (w1 + w2) * (2.0f/9.0f); - float const factor = 1.0f / (alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum); - - Vec3 const alphax_sum = x0 + x1 * (2.0f / 3.0f) + x2 * (1.0f / 3.0f); - Vec3 const betax_sum = m_xsum - alphax_sum; - - Vec3 a = ( alphax_sum*beta2_sum - betax_sum*alphabeta_sum )*factor; - Vec3 b = ( betax_sum*alpha2_sum - alphax_sum*alphabeta_sum )*factor; - - // clamp to the grid - a = Min( one, Max( zero, a ) ); - b = Min( one, Max( zero, b ) ); - a = Floor( grid*a + half )*gridrcp; - b = Floor( grid*b + half )*gridrcp; - - // compute the error - Vec3 e1 = a*a*alpha2_sum + b*b*beta2_sum + 2.0f*( a*b*alphabeta_sum - a*alphax_sum - b*betax_sum ); - - // apply the metric to the error term - float error = Dot( e1, m_metricSqr ); - - // keep the solution if it wins - if( error < besterror ) - { - besterror = error; - beststart = a; - bestend = b; - b0 = c0; - b1 = c1; - b2 = c2; - } - - x2 += m_weighted[c0+c1+c2]; - w2 += m_weights[c0+c1+c2]; - } - - x1 += m_weighted[c0+c1]; - w1 += m_weights[c0+c1]; - } - - x0 += m_weighted[c0]; - w0 += m_weights[c0]; - } - - // save the block if necessary - if( besterror < m_besterror ) - { - // compute indices from cluster sizes. - u8 bestindices[16]; - { - int i = 0; - for(; i < b0; i++) { - bestindices[i] = 0; - } - for(; i < b0+b1; i++) { - bestindices[i] = 2; - } - for(; i < b0+b1+b2; i++) { - bestindices[i] = 3; - } - for(; i < count; i++) { - bestindices[i] = 1; - } - } - - // remap the indices - u8 ordered[16]; - for( int i = 0; i < count; ++i ) - ordered[m_order[i]] = bestindices[i]; - - m_colours->RemapIndices( ordered, bestindices ); - - // save the block - WriteColourBlock4( beststart, bestend, bestindices, block ); - - // save the error - m_besterror = besterror; - } - } - -#endif - -} // namespace squish diff --git a/Externals/NVTT/src/nvtt/squish/weightedclusterfit.h b/Externals/NVTT/src/nvtt/squish/weightedclusterfit.h deleted file mode 100644 index a8f6eea22cc..00000000000 --- a/Externals/NVTT/src/nvtt/squish/weightedclusterfit.h +++ /dev/null @@ -1,78 +0,0 @@ -/* ----------------------------------------------------------------------------- - - Copyright (c) 2006 Simon Brown si@sjbrown.co.uk - Copyright (c) 2006 Ignacio Castano icastano@nvidia.com - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------- */ - -#ifndef SQUISH_WEIGHTEDCLUSTERFIT_H -#define SQUISH_WEIGHTEDCLUSTERFIT_H - -#include "squish.h" -#include "maths.h" -#include "simd.h" -#include "colourfit.h" - -namespace squish { - -class WeightedClusterFit : public ColourFit -{ -public: - WeightedClusterFit(); - - void SetColourSet( ColourSet const* colours, int flags ); - - void SetMetric(float r, float g, float b); - float GetBestError() const; - - // Make them public - virtual void Compress3( void* block ); - virtual void Compress4( void* block ); - -private: - - Vec3 m_principle; - -#if SQUISH_USE_SIMD - Vec4 m_weighted[16]; - Vec4 m_metric; - Vec4 m_metricSqr; - Vec4 m_xxsum; - Vec4 m_xsum; - Vec4 m_besterror; -#else - Vec3 m_weighted[16]; - float m_weights[16]; - Vec3 m_metric; - Vec3 m_metricSqr; - Vec3 m_xxsum; - Vec3 m_xsum; - float m_wsum; - float m_besterror; -#endif - - int m_order[16]; -}; - -} // namespace squish - -#endif // ndef SQUISH_WEIGHTEDCLUSTERFIT_H diff --git a/Externals/NVTT/src/nvtt/tests/ctest.c b/Externals/NVTT/src/nvtt/tests/ctest.c deleted file mode 100644 index a20064108bc..00000000000 --- a/Externals/NVTT/src/nvtt/tests/ctest.c +++ /dev/null @@ -1,35 +0,0 @@ - -#include - -#include - - -int main(void) -{ - NvttInputOptions inputOptions = 0; - NvttOutputOptions outputOptions = 0; - NvttCompressionOptions compressionOptions = 0; - - const unsigned int img[16*16]; - - memset(img, 0, sizeof(unsigned int) * 16 * 16); - - inputOptions = nvttCreateInputOptions(); - nvttSetInputOptionsTextureLayout(inputOptions, NVTT_TextureType_2D, 16, 16, 1); - nvttSetInputOptionsMipmapData(inputOptions, img, 16, 16, 1, 0, 0); - - outputOptions = nvttCreateOutputOptions(); - nvttSetOutputOptionsFileName(outputOptions, "output.dds"); - - compressionOptions = nvttCreateCompressionOptions(); - nvttSetCompressionOptionsFormat(compressionOptions, NVTT_Format_BC1); - - nvttCompress(inputOptions, outputOptions, compressionOptions); - - nvttDestroyCompressionOptions(compressionOptions); - nvttDestroyOutputOptions(outputOptions); - nvttDestroyInputOptions(inputOptions); - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tests/filtertest.cpp b/Externals/NVTT/src/nvtt/tests/filtertest.cpp deleted file mode 100644 index 2cb99e099eb..00000000000 --- a/Externals/NVTT/src/nvtt/tests/filtertest.cpp +++ /dev/null @@ -1,80 +0,0 @@ - -#include -#include "../tools/cmdline.h" - -#include - -using namespace nv; - -int main(void) -{ -// MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - BoxFilter box1(0.5); - Kernel1 k1(box1, 2); - k1.debugPrint(); nvDebug("\n"); - - BoxFilter box2(1); - Kernel1 k2(box2, 2); - k2.debugPrint(); nvDebug("\n"); - - BoxFilter boxr3(1); - Kernel1 k3(boxr3, 2); - k3.debugPrint(); nvDebug("\n"); - - KaiserFilter kai4(5); - kai4.setParameters(4, 2); - Kernel1 k4(kai4, 2); - k4.debugPrint(); nvDebug("\n"); - -/* Kernel1 k3(3); - Kernel1 k4(9); - Kernel1 k5(10); - -// k3.initFilter(Filter::Box); -// k4.initFilter(Filter::Box); -// k5.initFilter(Filter::Box); - -// nvDebug("Box Filter:\n"); -// k3.debugPrint(); nvDebug("\n"); -// k4.debugPrint(); nvDebug("\n"); -// k5.debugPrint(); nvDebug("\n"); - - k3.initSinc(0.75); - k4.initSinc(0.75); - k5.initSinc(0.75); - - nvDebug("Sinc Filter:\n"); - k3.debugPrint(); nvDebug("\n"); - k4.debugPrint(); nvDebug("\n"); - k5.debugPrint(); nvDebug("\n"); - - k3.initKaiser(4, 1, 100); - k4.initKaiser(4, 1, 100); - k5.initKaiser(4, 1, 100); - - nvDebug("Kaiser Filter:\n"); - k3.debugPrint(); nvDebug("\n"); - k4.debugPrint(); nvDebug("\n"); - k5.debugPrint(); nvDebug("\n"); - - k3.initKaiser(4, 1, 10); - k4.initKaiser(4, 1, 10); - k5.initKaiser(4, 1, 10); - - nvDebug("Kaiser Filter 2:\n"); - k3.debugPrint(); nvDebug("\n"); - k4.debugPrint(); nvDebug("\n"); - k5.debugPrint(); nvDebug("\n"); -*/ - int l_start = 4; - int l_end = 2; - - BoxFilter filter; - PolyphaseKernel kp(kai4, l_start, l_end); - - kp.debugPrint(); - - return 0; -} diff --git a/Externals/NVTT/src/nvtt/tools/assemble.cpp b/Externals/NVTT/src/nvtt/tools/assemble.cpp deleted file mode 100644 index 9c39a09e0b1..00000000000 --- a/Externals/NVTT/src/nvtt/tools/assemble.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include - -#include - -#include -#include -#include - -#include "cmdline.h" - -// @@ Add decent error messages. -// @@ Add option to resize images. -// @@ Add support for reading DDS files with 2D images and possibly mipmaps. - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - bool assembleCubeMap = true; - bool assembleVolume = false; - bool assembleTextureArray = false; - - nv::Array files; - nv::Path output = "output.dds"; - - // Parse arguments. - for (int i = 1; i < argc; i++) - { - // Input options. - if (strcmp("-cube", argv[i]) == 0) - { - assembleCubeMap = true; - assembleVolume = false; - assembleTextureArray = false; - } - /*if (strcmp("-volume", argv[i]) == 0) - { - assembleCubeMap = false; - assembleVolume = true; - assembleTextureArray = false; - } - if (strcmp("-array", argv[i]) == 0) - { - assembleCubeMap = false; - assembleVolume = false; - assembleTextureArray = true; - }*/ - else if (strcmp("-o", argv[i]) == 0) - { - i++; - if (i < argc && argv[i][0] != '-') - { - output = argv[i]; - } - } - else if (argv[i][0] != '-') - { - files.append(argv[i]); - } - } - - if (files.count() == 0) - { - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - printf("usage: nvassemble [-cube|-volume|-array] 'file0' 'file1' ...\n\n"); - return 1; - } - - if (nv::strCaseCmp(output.extension(), ".dds") != 0) - { - //output.stripExtension(); - output.append(".dds"); - } - - if (assembleCubeMap && files.count() != 6) - { - printf("*** error, 6 files expected, but got %d\n", files.count()); - return 1; - } - - // Load all files. - nv::Array images; - - uint w = 0, h = 0; - bool hasAlpha = false; - - const uint imageCount = files.count(); - images.resize(imageCount); - - for (uint i = 0; i < imageCount; i++) - { - if (!images[i].load(files[i])) - { - printf("*** error loading file\n"); - return 1; - } - - if (i == 0) - { - w = images[i].width(); - h = images[i].height(); - } - else if (images[i].width() != w || images[i].height() != h) - { - printf("*** error, size of image '%s' does not match\n", files[i].str()); - return 1; - } - - if (images[i].format() == nv::Image::Format_ARGB) - { - hasAlpha = true; - } - } - - - nv::StdOutputStream stream(output); - if (stream.isError()) { - printf("Error opening '%s' for writting\n", output.str()); - return 1; - } - - // Output DDS header. - nv::DDSHeader header; - header.setWidth(w); - header.setHeight(h); - - if (assembleCubeMap) - { - header.setTextureCube(); - } - else if (assembleVolume) - { - header.setTexture3D(); - header.setDepth(imageCount); - } - else if (assembleTextureArray) - { - //header.setTextureArray(imageCount); - } - - // @@ It always outputs 32 bpp. - header.setPitch(4 * w); - header.setPixelFormat(32, 0xFF0000, 0xFF00, 0xFF, hasAlpha ? 0xFF000000 : 0); - - stream << header; - - // Output images. - for (uint i = 0; i < imageCount; i++) - { - const uint pixelCount = w * h; - for (uint p = 0; p < pixelCount; p++) - { - nv::Color32 c = images[i].pixel(p); - uint8 r = c.r; - uint8 g = c.g; - uint8 b = c.b; - uint8 a = c.a; - stream << b << g << r << a; - } - } - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tools/benchmark.cpp b/Externals/NVTT/src/nvtt/tools/benchmark.cpp deleted file mode 100644 index 347a3271b59..00000000000 --- a/Externals/NVTT/src/nvtt/tools/benchmark.cpp +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include - -#include -#include - -#include - -#include "cmdline.h" - -#include // clock - - -struct MyErrorHandler : public nvtt::ErrorHandler -{ - virtual void error(nvtt::Error e) - { - nvDebugBreak(); - } -}; - - -// Set color to normal map conversion options. -void setColorToNormalMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(false); - inputOptions.setConvertToNormalMap(true); - inputOptions.setHeightEvaluation(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 0.0f); - //inputOptions.setNormalFilter(1.0f, 0, 0, 0); - //inputOptions.setNormalFilter(0.0f, 0, 0, 1); - inputOptions.setGamma(1.0f, 1.0f); - inputOptions.setNormalizeMipmaps(true); -} - -// Set options for normal maps. -void setNormalMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(true); - inputOptions.setConvertToNormalMap(false); - inputOptions.setGamma(1.0f, 1.0f); - inputOptions.setNormalizeMipmaps(true); -} - -// Set options for color maps. -void setColorMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(false); - inputOptions.setConvertToNormalMap(false); - inputOptions.setGamma(2.2f, 2.2f); - inputOptions.setNormalizeMipmaps(false); -} - - - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - bool normal = false; - bool color2normal = false; - bool wrapRepeat = false; - bool noMipmaps = false; - bool fast = false; - bool nocuda = false; - bool silent = false; - nvtt::Format format = nvtt::Format_BC1; - - const char * externalCompressor = NULL; - - nv::Path input; - nv::Path output; - - - // Parse arguments. - for (int i = 1; i < argc; i++) - { - // Input options. - if (strcmp("-color", argv[i]) == 0) - { - } - else if (strcmp("-normal", argv[i]) == 0) - { - normal = true; - } - else if (strcmp("-tonormal", argv[i]) == 0) - { - color2normal = true; - } - else if (strcmp("-clamp", argv[i]) == 0) - { - } - else if (strcmp("-repeat", argv[i]) == 0) - { - wrapRepeat = true; - } - else if (strcmp("-nomips", argv[i]) == 0) - { - noMipmaps = true; - } - - // Compression options. - else if (strcmp("-fast", argv[i]) == 0) - { - fast = true; - } - else if (strcmp("-nocuda", argv[i]) == 0) - { - nocuda = true; - } - else if (strcmp("-rgb", argv[i]) == 0) - { - format = nvtt::Format_RGB; - } - else if (strcmp("-bc1", argv[i]) == 0) - { - format = nvtt::Format_BC1; - } - else if (strcmp("-bc1a", argv[i]) == 0) - { - format = nvtt::Format_BC1a; - } - else if (strcmp("-bc2", argv[i]) == 0) - { - format = nvtt::Format_BC2; - } - else if (strcmp("-bc3", argv[i]) == 0) - { - format = nvtt::Format_BC3; - } - else if (strcmp("-bc3n", argv[i]) == 0) - { - format = nvtt::Format_BC3n; - } - else if (strcmp("-bc4", argv[i]) == 0) - { - format = nvtt::Format_BC4; - } - else if (strcmp("-bc5", argv[i]) == 0) - { - format = nvtt::Format_BC5; - } - - // Undocumented option. Mainly used for testing. - else if (strcmp("-ext", argv[i]) == 0) - { - if (i+1 < argc && argv[i+1][0] != '-') { - externalCompressor = argv[i+1]; - i++; - } - } - - // Misc options - else if (strcmp("-silent", argv[i]) == 0) - { - silent = true; - } - - else if (argv[i][0] != '-') - { - input = argv[i]; - - if (i+1 < argc && argv[i+1][0] != '-') { - output = argv[i+1]; - } - else - { - output.copy(input.str()); - output.stripExtension(); - output.append(".dds"); - } - - break; - } - } - - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - - if (input.isNull()) - { - printf("usage: nvttbenchmark [options] infile [outfile]\n\n"); - - printf("Input options:\n"); - printf(" -color \tThe input image is a color map (default).\n"); - printf(" -normal \tThe input image is a normal map.\n"); - printf(" -tonormal\tConvert input to normal map.\n"); - printf(" -clamp \tClamp wrapping mode (default).\n"); - printf(" -repeat \tRepeat wrapping mode.\n"); - printf(" -nomips \tDisable mipmap generation.\n\n"); - - printf("Compression options:\n"); - printf(" -fast \tFast compression.\n"); - printf(" -nocuda \tDo not use cuda compressor.\n"); - printf(" -rgb \tRGBA format\n"); - printf(" -bc1 \tBC1 format (DXT1)\n"); - printf(" -bc1a \tBC1 format with binary alpha (DXT1a)\n"); - printf(" -bc2 \tBC2 format (DXT3)\n"); - printf(" -bc3 \tBC3 format (DXT5)\n"); - printf(" -bc3n \tBC3 normal map format (DXT5nm)\n"); - printf(" -bc4 \tBC4 format (ATI1)\n"); - printf(" -bc5 \tBC5 format (3Dc/ATI2)\n\n"); - - return 1; - } - - // @@ Make sure input file exists. - - // Set input options. - nvtt::InputOptions inputOptions; - - if (nv::strCaseCmp(input.extension(), ".dds") == 0) - { - // Load surface. - nv::DirectDrawSurface dds(input); - if (!dds.isValid()) - { - fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str()); - return 1; - } - - if (!dds.isSupported() || dds.isTexture3D()) - { - fprintf(stderr, "The file '%s' is not a supported DDS file.\n", input.str()); - return 1; - } - - uint faceCount; - if (dds.isTexture2D()) - { - inputOptions.setTextureLayout(nvtt::TextureType_2D, dds.width(), dds.height()); - faceCount = 1; - } - else - { - nvDebugCheck(dds.isTextureCube()); - inputOptions.setTextureLayout(nvtt::TextureType_Cube, dds.width(), dds.height()); - faceCount = 6; - } - - uint mipmapCount = dds.mipmapCount(); - - nv::Image mipmap; - - for (uint f = 0; f < faceCount; f++) - { - for (uint m = 0; m <= mipmapCount; m++) - { - dds.mipmap(&mipmap, f, m); - - inputOptions.setMipmapData(mipmap.pixels(), mipmap.width(), mipmap.height(), 1, f, m); - } - } - } - else - { - // Regular image. - nv::Image image; - if (!image.load(input)) - { - fprintf(stderr, "The file '%s' is not a supported image type.\n", input.str()); - return 1; - } - - inputOptions.setTextureLayout(nvtt::TextureType_2D, image.width(), image.height()); - inputOptions.setMipmapData(image.pixels(), image.width(), image.height()); - } - - if (fast) - { - inputOptions.setMipmapping(true, nvtt::MipmapFilter_Box); - } - else - { - inputOptions.setMipmapping(true, nvtt::MipmapFilter_Box); - //inputOptions.setMipmapping(true, nvtt::MipmapFilter_Kaiser); - } - - if (wrapRepeat) - { - inputOptions.setWrapMode(nvtt::WrapMode_Repeat); - } - else - { - inputOptions.setWrapMode(nvtt::WrapMode_Clamp); - } - - if (normal) - { - setNormalMap(inputOptions); - } - else if (color2normal) - { - setColorToNormalMap(inputOptions); - } - else - { - setColorMap(inputOptions); - } - - if (noMipmaps) - { - inputOptions.setMipmapping(false); - } - - - nvtt::CompressionOptions compressionOptions; - compressionOptions.setFormat(format); - if (fast) - { - compressionOptions.setQuality(nvtt::Quality_Fastest); - } - else - { - compressionOptions.setQuality(nvtt::Quality_Normal); - //compressionOptions.setQuality(nvtt::Quality_Production, 0.5f); - //compressionOptions.setQuality(nvtt::Quality_Highest); - } - compressionOptions.enableHardwareCompression(!nocuda); - compressionOptions.setColorWeights(1, 1, 1); - - if (externalCompressor != NULL) - { - compressionOptions.setExternalCompressor(externalCompressor); - } - - - MyErrorHandler errorHandler; - nvtt::OutputOptions outputOptions(NULL, &errorHandler); - -// printf("Press ENTER.\n"); -// fflush(stdout); -// getchar(); - - clock_t start = clock(); - - const int iterationCount = 20; - for (int i = 0; i < iterationCount; i++) - { - nvtt::compress(inputOptions, outputOptions, compressionOptions); - } - - clock_t end = clock(); - - float seconds = float(end-start) / CLOCKS_PER_SEC - printf("total time taken: %.3f seconds\n", seconds); - printf("time taken per texture: %.3f seconds\n", seconds / iterationCount); - printf("textures per second: %.3f T/s\n", iterationCount / seconds); - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tools/cmdline.h b/Externals/NVTT/src/nvtt/tools/cmdline.h deleted file mode 100644 index f4b48b6efca..00000000000 --- a/Externals/NVTT/src/nvtt/tools/cmdline.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef CMDLINE_H -#define CMDLINE_H - -#include - -#include // stderr -#include // exit -#include // va_list - - -struct MyMessageHandler : public nv::MessageHandler { - MyMessageHandler() { - nv::debug::setMessageHandler( this ); - } - ~MyMessageHandler() { - nv::debug::resetMessageHandler(); - } - - virtual void log( const char * str, va_list arg ) { - va_list val; - va_copy(val, arg); - vfprintf(stderr, str, arg); - va_end(val); - } -}; - - -struct MyAssertHandler : public nv::AssertHandler { - MyAssertHandler() { - nv::debug::setAssertHandler( this ); - } - ~MyAssertHandler() { - nv::debug::resetAssertHandler(); - } - - // Handler method, note that func might be NULL! - virtual int assert( const char *exp, const char *file, int line, const char *func ) { - fprintf(stderr, "Assertion failed: %s\nIn %s:%d\n", exp, file, line); - nv::debug::dumpInfo(); - exit(1); - } -}; - - -#endif // CMDLINE_H diff --git a/Externals/NVTT/src/nvtt/tools/compress.cpp b/Externals/NVTT/src/nvtt/tools/compress.cpp deleted file mode 100644 index 3f80f8ec174..00000000000 --- a/Externals/NVTT/src/nvtt/tools/compress.cpp +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include - -#include -#include - -#include - -#include "cmdline.h" - -#include // clock - -//#define WINDOWS_LEAN_AND_MEAN -//#include // TIMER - - -struct MyOutputHandler : public nvtt::OutputHandler -{ - MyOutputHandler(const char * name) : total(0), progress(0), percentage(0), stream(new nv::StdOutputStream(name)) {} - virtual ~MyOutputHandler() { delete stream; } - - void setTotal(int64 t) - { - total = t + 128; - } - void setDisplayProgress(bool b) - { - verbose = b; - } - - virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) - { - // ignore. - } - - // Output data. - virtual bool writeData(const void * data, int size) - { - nvDebugCheck(stream != NULL); - stream->serialize(const_cast(data), size); - - progress += size; - int p = int((100 * progress) / total); - if (verbose && p != percentage) - { - nvCheck(p >= 0); - - percentage = p; - printf("\r%d%%", percentage); - fflush(stdout); - } - - return true; - } - - int64 total; - int64 progress; - int percentage; - bool verbose; - nv::StdOutputStream * stream; -}; - -struct MyErrorHandler : public nvtt::ErrorHandler -{ - virtual void error(nvtt::Error e) - { -#if _DEBUG - nvDebugBreak(); -#endif - printf("Error: '%s'\n", nvtt::errorString(e)); - } -}; - - - - -// Set color to normal map conversion options. -void setColorToNormalMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(false); - inputOptions.setConvertToNormalMap(true); - inputOptions.setHeightEvaluation(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 0.0f); - //inputOptions.setNormalFilter(1.0f, 0, 0, 0); - //inputOptions.setNormalFilter(0.0f, 0, 0, 1); - inputOptions.setGamma(1.0f, 1.0f); - inputOptions.setNormalizeMipmaps(true); -} - -// Set options for normal maps. -void setNormalMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(true); - inputOptions.setConvertToNormalMap(false); - inputOptions.setGamma(1.0f, 1.0f); - inputOptions.setNormalizeMipmaps(true); -} - -// Set options for color maps. -void setColorMap(nvtt::InputOptions & inputOptions) -{ - inputOptions.setNormalMap(false); - inputOptions.setConvertToNormalMap(false); - inputOptions.setGamma(2.2f, 2.2f); - inputOptions.setNormalizeMipmaps(false); -} - - - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - bool alpha = false; - bool normal = false; - bool color2normal = false; - bool wrapRepeat = false; - bool noMipmaps = false; - bool fast = false; - bool nocuda = false; - bool silent = false; - bool bc1n = false; - nvtt::Format format = nvtt::Format_BC1; - - const char * externalCompressor = NULL; - - nv::Path input; - nv::Path output; - - - // Parse arguments. - for (int i = 1; i < argc; i++) - { - // Input options. - if (strcmp("-color", argv[i]) == 0) - { - } - else if (strcmp("-alpha", argv[i]) == 0) - { - alpha = true; - } - else if (strcmp("-normal", argv[i]) == 0) - { - normal = true; - } - else if (strcmp("-tonormal", argv[i]) == 0) - { - color2normal = true; - } - else if (strcmp("-clamp", argv[i]) == 0) - { - } - else if (strcmp("-repeat", argv[i]) == 0) - { - wrapRepeat = true; - } - else if (strcmp("-nomips", argv[i]) == 0) - { - noMipmaps = true; - } - - // Compression options. - else if (strcmp("-fast", argv[i]) == 0) - { - fast = true; - } - else if (strcmp("-nocuda", argv[i]) == 0) - { - nocuda = true; - } - else if (strcmp("-rgb", argv[i]) == 0) - { - format = nvtt::Format_RGB; - } - else if (strcmp("-bc1", argv[i]) == 0) - { - format = nvtt::Format_BC1; - } - else if (strcmp("-bc1n", argv[i]) == 0) - { - format = nvtt::Format_BC1; - bc1n = true; - } - else if (strcmp("-bc1a", argv[i]) == 0) - { - format = nvtt::Format_BC1a; - } - else if (strcmp("-bc2", argv[i]) == 0) - { - format = nvtt::Format_BC2; - } - else if (strcmp("-bc3", argv[i]) == 0) - { - format = nvtt::Format_BC3; - } - else if (strcmp("-bc3n", argv[i]) == 0) - { - format = nvtt::Format_BC3n; - } - else if (strcmp("-bc4", argv[i]) == 0) - { - format = nvtt::Format_BC4; - } - else if (strcmp("-bc5", argv[i]) == 0) - { - format = nvtt::Format_BC5; - } - - // Undocumented option. Mainly used for testing. - else if (strcmp("-ext", argv[i]) == 0) - { - if (i+1 < argc && argv[i+1][0] != '-') { - externalCompressor = argv[i+1]; - i++; - } - } - - // Misc options - else if (strcmp("-silent", argv[i]) == 0) - { - silent = true; - } - - else if (argv[i][0] != '-') - { - input = argv[i]; - - if (i+1 < argc && argv[i+1][0] != '-') { - output = argv[i+1]; - } - else - { - output.copy(input.str()); - output.stripExtension(); - output.append(".dds"); - } - - break; - } - } - - const uint version = nvtt::version(); - const uint major = version / 100; - const uint minor = version % 100; - - - printf("NVIDIA Texture Tools %u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor); - - if (input.isNull()) - { - printf("usage: nvcompress [options] infile [outfile]\n\n"); - - printf("Input options:\n"); - printf(" -color \tThe input image is a color map (default).\n"); - printf(" -alpha \tThe input image has an alpha channel used for transparency.\n"); - printf(" -normal \tThe input image is a normal map.\n"); - printf(" -tonormal\tConvert input to normal map.\n"); - printf(" -clamp \tClamp wrapping mode (default).\n"); - printf(" -repeat \tRepeat wrapping mode.\n"); - printf(" -nomips \tDisable mipmap generation.\n\n"); - - printf("Compression options:\n"); - printf(" -fast \tFast compression.\n"); - printf(" -nocuda \tDo not use cuda compressor.\n"); - printf(" -rgb \tRGBA format\n"); - printf(" -bc1 \tBC1 format (DXT1)\n"); - printf(" -bc1n \tBC1 normal map format (DXT1nm)\n"); - printf(" -bc1a \tBC1 format with binary alpha (DXT1a)\n"); - printf(" -bc2 \tBC2 format (DXT3)\n"); - printf(" -bc3 \tBC3 format (DXT5)\n"); - printf(" -bc3n \tBC3 normal map format (DXT5nm)\n"); - printf(" -bc4 \tBC4 format (ATI1)\n"); - printf(" -bc5 \tBC5 format (3Dc/ATI2)\n\n"); - - return EXIT_FAILURE; - } - - // @@ Make sure input file exists. - - // Set input options. - nvtt::InputOptions inputOptions; - - if (nv::strCaseCmp(input.extension(), ".dds") == 0) - { - // Load surface. - nv::DirectDrawSurface dds(input); - if (!dds.isValid()) - { - fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str()); - return EXIT_FAILURE; - } - - if (!dds.isSupported() || dds.isTexture3D()) - { - fprintf(stderr, "The file '%s' is not a supported DDS file.\n", input.str()); - return EXIT_FAILURE; - } - - uint faceCount; - if (dds.isTexture2D()) - { - inputOptions.setTextureLayout(nvtt::TextureType_2D, dds.width(), dds.height()); - faceCount = 1; - } - else - { - nvDebugCheck(dds.isTextureCube()); - inputOptions.setTextureLayout(nvtt::TextureType_Cube, dds.width(), dds.height()); - faceCount = 6; - } - - uint mipmapCount = dds.mipmapCount(); - - nv::Image mipmap; - - for (uint f = 0; f < faceCount; f++) - { - for (uint m = 0; m < mipmapCount; m++) - { - dds.mipmap(&mipmap, f, m); - - inputOptions.setMipmapData(mipmap.pixels(), mipmap.width(), mipmap.height(), 1, f, m); - } - } - } - else - { - // Regular image. - nv::Image image; - if (!image.load(input)) - { - fprintf(stderr, "The file '%s' is not a supported image type.\n", input.str()); - return EXIT_FAILURE; - } - - inputOptions.setTextureLayout(nvtt::TextureType_2D, image.width(), image.height()); - inputOptions.setMipmapData(image.pixels(), image.width(), image.height()); - } - - if (wrapRepeat) - { - inputOptions.setWrapMode(nvtt::WrapMode_Repeat); - } - else - { - inputOptions.setWrapMode(nvtt::WrapMode_Clamp); - } - - if (alpha) - { - inputOptions.setAlphaMode(nvtt::AlphaMode_Transparency); - } - else - { - inputOptions.setAlphaMode(nvtt::AlphaMode_None); - } - - if (normal) - { - setNormalMap(inputOptions); - } - else if (color2normal) - { - setColorToNormalMap(inputOptions); - } - else - { - setColorMap(inputOptions); - } - - if (noMipmaps) - { - inputOptions.setMipmapGeneration(false); - } - - nvtt::CompressionOptions compressionOptions; - compressionOptions.setFormat(format); - if (fast) - { - compressionOptions.setQuality(nvtt::Quality_Fastest); - } - else - { - compressionOptions.setQuality(nvtt::Quality_Normal); - //compressionOptions.setQuality(nvtt::Quality_Production); - //compressionOptions.setQuality(nvtt::Quality_Highest); - } - - if (bc1n) - { - compressionOptions.setColorWeights(1, 1, 0); - } - - if (externalCompressor != NULL) - { - compressionOptions.setExternalCompressor(externalCompressor); - } - - - MyErrorHandler errorHandler; - MyOutputHandler outputHandler(output); - if (outputHandler.stream->isError()) - { - fprintf(stderr, "Error opening '%s' for writting\n", output.str()); - return EXIT_FAILURE; - } - - nvtt::Compressor compressor; - compressor.enableCudaAcceleration(!nocuda); - - printf("CUDA acceleration "); - if (compressor.isCudaAccelerationEnabled()) - { - printf("ENABLED\n\n"); - } - else - { - printf("DISABLED\n\n"); - } - - outputHandler.setTotal(compressor.estimateSize(inputOptions, compressionOptions)); - outputHandler.setDisplayProgress(!silent); - - nvtt::OutputOptions outputOptions; - //outputOptions.setFileName(output); - outputOptions.setOutputHandler(&outputHandler); - outputOptions.setErrorHandler(&errorHandler); - -// printf("Press ENTER.\n"); -// fflush(stdout); -// getchar(); - - clock_t start = clock(); - - if (!compressor.process(inputOptions, compressionOptions, outputOptions)) - { - return EXIT_FAILURE; - } - - clock_t end = clock(); - printf("\rtime taken: %.3f seconds\n", float(end-start) / CLOCKS_PER_SEC); - - return EXIT_SUCCESS; -} - diff --git a/Externals/NVTT/src/nvtt/tools/configdialog.cpp b/Externals/NVTT/src/nvtt/tools/configdialog.cpp deleted file mode 100644 index 885baa51c90..00000000000 --- a/Externals/NVTT/src/nvtt/tools/configdialog.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include "configdialog.h" - -#include - -#include - - -ConfigDialog::ConfigDialog(QWidget *parent/*=0*/) : QDialog(parent) -{ - init(); -} - -ConfigDialog::ConfigDialog(const char * fileName, QWidget *parent/*=0*/) : QDialog(parent) -{ - init(); - - open(fileName); -} - -void ConfigDialog::init() -{ - ui.setupUi(this); - - connect(ui.openButton, SIGNAL(clicked()), this, SLOT(openClicked())); - connect(ui.generateMipmapsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(generateMipmapsChanged(int))); - connect(ui.mipmapFilterComboBox, SIGNAL(activated(QString)), this, SLOT(mipmapFilterChanged(QString))); - //connect(ui.mipmapFilterSettings, SIGNAL(clicked()), this, SLOT(mipmapFilterSettingsShow())); - - connect(ui.redSpinBox, SIGNAL(valueChanged(double)), this, SLOT(colorWeightChanged())); - connect(ui.greenSpinBox, SIGNAL(valueChanged(double)), this, SLOT(colorWeightChanged())); - connect(ui.blueSpinBox, SIGNAL(valueChanged(double)), this, SLOT(colorWeightChanged())); - connect(ui.uniformButton, SIGNAL(toggled(bool)), this, SLOT(uniformWeightToggled(bool))); - connect(ui.luminanceButton, SIGNAL(toggled(bool)), this, SLOT(luminanceWeightToggled(bool))); - - //connect(ui.rgbMapRadioButton, SIGNAL(toggled(bool)), this, SLOT(colorModeChanged())); - connect(ui.normalMapRadioButton, SIGNAL(toggled(bool)), this, SLOT(normalMapModeChanged(bool))); -} - - -void ConfigDialog::openClicked() -{ - // @@ Open file dialog. - - QString fileName; - - open(fileName); -} - -void ConfigDialog::generateMipmapsChanged(int state) -{ - Q_UNUSED(state); - - bool generateMipmapEnabled = ui.generateMipmapsCheckBox->isChecked(); - - ui.mipmapFilterLabel->setEnabled(generateMipmapEnabled); - ui.mipmapFilterComboBox->setEnabled(generateMipmapEnabled); - ui.limitMipmapsCheckBox->setEnabled(generateMipmapEnabled); - - bool enableFilterSettings = (ui.mipmapFilterComboBox->currentText() == "Kaiser"); - ui.mipmapFilterSettings->setEnabled(generateMipmapEnabled && enableFilterSettings); - - bool enableMaxLevel = ui.limitMipmapsCheckBox->isChecked(); - ui.maxLevelLabel->setEnabled(generateMipmapEnabled && enableMaxLevel); - ui.maxLevelSpinBox->setEnabled(generateMipmapEnabled && enableMaxLevel); -} - -void ConfigDialog::mipmapFilterChanged(QString name) -{ - bool enableFilterSettings = (name == "Kaiser"); - ui.mipmapFilterSettings->setEnabled(enableFilterSettings); -} - - -void ConfigDialog::colorWeightChanged() -{ - double r = ui.redSpinBox->value(); - double g = ui.greenSpinBox->value(); - double b = ui.blueSpinBox->value(); - - bool uniform = (r == 1.0 && g == 1.0 && b == 1.0); - bool luminance = (r == 0.3 && g == 0.59 && b == 0.11); - - ui.uniformButton->setChecked(uniform); - ui.luminanceButton->setChecked(luminance); -} - -void ConfigDialog::uniformWeightToggled(bool checked) -{ - if (checked) - { - ui.redSpinBox->setValue(1.0); - ui.greenSpinBox->setValue(1.0); - ui.blueSpinBox->setValue(1.0); - } -} - -void ConfigDialog::luminanceWeightToggled(bool checked) -{ - if (checked) - { - ui.redSpinBox->setValue(0.3); - ui.greenSpinBox->setValue(0.59); - ui.blueSpinBox->setValue(0.11); - } -} - -void ConfigDialog::normalMapModeChanged(bool checked) -{ - ui.alphaModeGroupBox->setEnabled(!checked); - ui.inputGammaSpinBox->setEnabled(!checked); - ui.inputGammaLabel->setEnabled(!checked); - ui.outputGammaSpinBox->setEnabled(!checked); - ui.outputGammaLabel->setEnabled(!checked); -} - - -bool ConfigDialog::open(QString fileName) -{ - // @@ Load image. - QImage image; - - // @@ If success. - { - ui.imagePathLineEdit->setText(fileName); - - // @@ Set image in graphics view. - - // @@ Set image description. - - // @@ Provide image to nvtt. - - int w = image.width(); - int h = image.height(); - void * data = NULL; - - inputOptions.setTextureLayout(nvtt::TextureType_2D, w, h); - inputOptions.setMipmapData(data, w, h); - - return true; - } - - return false; -} - - - - diff --git a/Externals/NVTT/src/nvtt/tools/configdialog.h b/Externals/NVTT/src/nvtt/tools/configdialog.h deleted file mode 100644 index 46264ca2172..00000000000 --- a/Externals/NVTT/src/nvtt/tools/configdialog.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#ifndef CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include - -#include "ui_configdialog.h" - -#include - - -class ConfigDialog : public QDialog -{ - Q_OBJECT -public: - ConfigDialog(QWidget *parent = 0); - ConfigDialog(const char * fileName, QWidget *parent = 0); - -protected slots: - - void openClicked(); - void generateMipmapsChanged(int state); - void mipmapFilterChanged(QString name); - - void colorWeightChanged(); - void uniformWeightToggled(bool checked); - void luminanceWeightToggled(bool checked); - - void normalMapModeChanged(bool checked); - - bool open(QString fileName); - -private: - - void init(); - -private: - Ui::ConfigDialog ui; - - nvtt::InputOptions inputOptions; - nvtt::CompressionOptions compressionOptions; - nvtt::OutputOptions outputOptions; - -}; - - -#endif // CONFIGDIALOG_H diff --git a/Externals/NVTT/src/nvtt/tools/configdialog.ui b/Externals/NVTT/src/nvtt/tools/configdialog.ui deleted file mode 100644 index a0027985a9b..00000000000 --- a/Externals/NVTT/src/nvtt/tools/configdialog.ui +++ /dev/null @@ -1,1046 +0,0 @@ - - ConfigDialog - - - - 0 - 0 - 674 - 475 - - - - NVIDIA Texture Tools - - - - - - true - - - - - - - - - - - 64 - 0 - - - - - 128 - 16777215 - - - - Qt::ScrollBarAlwaysOff - - - QListView::Static - - - QListView::TopToBottom - - - false - - - QListView::Adjust - - - QListView::ListMode - - - - Input Options - - - - - Compression Options - - - - - Output Options - - - - - Preview - - - ../../../../../../castano-stuff/qshaderedit/src/images/colorpicker.png - - - - - - - - - - - 0 - 0 - - - - 3 - - - - - -1 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - Qt::ElideNone - - - false - - - - File Path - - - - - - - - - - - - 0 - 0 - - - - Open - - - - - - - - - - - - - Image Settings - - - - - - - - - 0 - 0 - - - - Color Mode - - - Qt::AlignHCenter - - - - 0 - - - - - RGB - - - true - - - - - - - Normal Map - - - - - - - - - - - 0 - 0 - - - - Alpha Mode - - - Qt::AlignHCenter - - - - 0 - - - - - None - - - false - - - - - - - Transparency - - - true - - - - - - - Premultiplied - - - - - - - - - - - - 0 - - - - - - 0 - 0 - - - - Wrap Mode: - - - mipmapFilterComboBox - - - - - - - - 16777215 - 26 - - - - - Mirror - - - - - Repeat - - - - - Clamp - - - - - - - - - - - - - 0 - 0 - - - - Input Gamma: - - - inputGammaSpinBox - - - - - - - - 0 - 0 - - - - QAbstractSpinBox::UpDownArrows - - - 0.050000000000000 - - - 4.000000000000000 - - - 0.050000000000000 - - - 2.200000000000000 - - - - - - - - - - - - 0 - 0 - - - - Output Gamma: - - - inputGammaSpinBox - - - - - - - - 0 - 0 - - - - QAbstractSpinBox::UpDownArrows - - - 0.050000000000000 - - - 4.000000000000000 - - - 0.050000000000000 - - - 2.200000000000000 - - - - - - - - - Qt::Vertical - - - - 433 - 16 - - - - - - - - - Mipmaps - - - - - - Generate mipmaps - - - true - - - - - - - 1 - - - - - - 0 - 0 - - - - Mipmap filter: - - - mipmapFilterComboBox - - - - - - - - 16777215 - 26 - - - - - Box - - - - - Triangle - - - - - Kaiser - - - - - - - - false - - - - 0 - 0 - - - - - 16777215 - 24 - - - - false - - - ... - - - Qt::ToolButtonTextOnly - - - - - - - - - - - - 0 - 0 - - - - Limit Mipmaps - - - - - - - false - - - - 0 - 0 - - - - Max Level: - - - - - - - false - - - - 0 - 0 - - - - - 80 - 16777215 - - - - - - - - - - Qt::Vertical - - - - 204 - 71 - - - - - - - - - Normal Map - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 0 - - - - Format: - - - Qt::PlainText - - - Qt::NoTextInteraction - - - formatComboBox - - - - - - - - Uncompressed - - - - - BC1 (DXT1) - - - - - BC1a (DXT1a) - - - - - BC2 (DXT3) - - - - - BC3 (DXT5) - - - - - BC4 - - - - - BC5 - - - - - - - - - - - - - 0 - 0 - - - - Quality: - - - Qt::PlainText - - - Qt::NoTextInteraction - - - formatComboBox - - - - - - - 1 - - - - Fastest - - - - - Normal - - - - - Production - - - - - Highest - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Color Weights - - - Qt::AlignHCenter - - - - - - - - Red - - - redSpinBox - - - - - - - 1.000000000000000 - - - 0.050000000000000 - - - 1.000000000000000 - - - - - - - - - - - Green - - - greenSpinBox - - - - - - - 1.000000000000000 - - - 0.050000000000000 - - - 1.000000000000000 - - - - - - - - - - - Blue - - - blueSpinBox - - - - - - - 1.000000000000000 - - - 0.050000000000000 - - - 1.000000000000000 - - - - - - - - - - - - 16777215 - 22 - - - - Uniform Weights - - - true - - - true - - - - - - - - 16777215 - 22 - - - - Luminance Weights - - - true - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 484 - 31 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - Bilinear Filter - - - true - - - - - - - View difference - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - - Default - - - - - - - true - - - 0 - - - true - - - Qt::Horizontal - - - false - - - - - - - Quit - - - - - - - - - - - listWidget - currentRowChanged(int) - stackedWidget - setCurrentIndex(int) - - - 118 - 193 - - - 154 - 220 - - - - - pushButton - clicked() - ConfigDialog - accept() - - - 565 - 491 - - - 582 - 506 - - - - - limitMipmapsCheckBox - clicked(bool) - maxLevelSpinBox - setEnabled(bool) - - - 451 - 120 - - - 524 - 120 - - - - - limitMipmapsCheckBox - clicked(bool) - maxLevelLabel - setEnabled(bool) - - - 337 - 120 - - - 482 - 124 - - - - - diff --git a/Externals/NVTT/src/nvtt/tools/ddsinfo.cpp b/Externals/NVTT/src/nvtt/tools/ddsinfo.cpp deleted file mode 100644 index 984ed96726b..00000000000 --- a/Externals/NVTT/src/nvtt/tools/ddsinfo.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include - -#include -#include - -#include "cmdline.h" - - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - if (argc != 2) - { - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - printf("usage: nvddsinfo ddsfile\n\n"); - return 1; - } - - // Load surface. - nv::DirectDrawSurface dds(argv[1]); - if (!dds.isValid()) - { - printf("The file '%s' is not a valid DDS file.\n", argv[1]); - return 1; - } - - dds.printInfo(); - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tools/decompress.cpp b/Externals/NVTT/src/nvtt/tools/decompress.cpp deleted file mode 100644 index da0fd211248..00000000000 --- a/Externals/NVTT/src/nvtt/tools/decompress.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include - -#include -#include - -#include - -#include "cmdline.h" - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - if (argc != 2) - { - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - printf("usage: nvdecompress 'ddsfile'\n\n"); - return 1; - } - - // Load surface. - nv::DirectDrawSurface dds(argv[1]); - if (!dds.isValid()) - { - printf("The file '%s' is not a valid DDS file.\n", argv[1]); - return 1; - } - - nv::Path name(argv[1]); - name.stripExtension(); - name.append(".tga"); - - nv::StdOutputStream stream(name.str()); - if (stream.isError()) { - printf("Error opening '%s' for writting\n", name.str()); - return 1; - } - - // @@ TODO: Add command line options to output mipmaps, cubemap faces, etc. - nv::Image img; - dds.mipmap(&img, 0, 0); // get first image - nv::ImageIO::saveTGA(stream, &img); - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tools/imgdiff.cpp b/Externals/NVTT/src/nvtt/tools/imgdiff.cpp deleted file mode 100644 index 107ee7dbd6a..00000000000 --- a/Externals/NVTT/src/nvtt/tools/imgdiff.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include "cmdline.h" - -static bool loadImage(nv::Image & image, const char * fileName) -{ - if (nv::strCaseCmp(nv::Path::extension(fileName), ".dds") == 0) - { - nv::DirectDrawSurface dds(fileName); - if (!dds.isValid()) - { - printf("The file '%s' is not a valid DDS file.\n", fileName); - return false; - } - - dds.mipmap(&image, 0, 0); // get first image - } - else - { - // Regular image. - if (!image.load(fileName)) - { - printf("The file '%s' is not a supported image type.\n", fileName); - return false; - } - } - - return true; -} - -// @@ Compute per-tile errors. -struct Error -{ - Error() - { - samples = 0; - mabse = 0.0f; - maxabse = 0.0f; - mse = 0.0f; - } - - void addSample(float e) - { - samples++; - mabse += fabsf(e); - maxabse = nv::max(maxabse, fabsf(e)); - mse += e * e; - } - - void done() - { - mabse /= samples; - mse /= samples; - rmse = sqrtf(mse); - psnr = (rmse == 0) ? 999.0f : 20.0f * log10(255.0f / rmse); - } - - void print() - { - printf(" Mean absolute error: %f\n", mabse); - printf(" Max absolute error: %f\n", maxabse); - printf(" Root mean squared error: %f\n", rmse); - printf(" Peak signal to noise ratio in dB: %f\n", psnr); - } - - int samples; - float mabse; - float maxabse; - float mse; - float rmse; - float psnr; -}; - -struct NormalError -{ - NormalError() - { - samples = 0; - ade = 0.0f; - mse = 0.0f; - } - - void addSample(nv::Color32 o, nv::Color32 c) - { - nv::Vector3 vo = nv::Vector3(o.r, o.g, o.b); - nv::Vector3 vc = nv::Vector3(c.r, c.g, c.b); - - // Unpack and normalize. - vo = nv::normalize(2.0f * (vo / 255.0f) - 1.0f); - vc = nv::normalize(2.0f * (vc / 255.0f) - 1.0f); - - ade += acosf(nv::clamp(dot(vo, vc), -1.0f, 1.0f)); - mse += length_squared((vo - vc) * (255 / 2.0f)); - - samples++; - } - - void done() - { - if (samples) - { - ade /= samples; - mse /= samples * 3; - rmse = sqrtf(mse); - psnr = (rmse == 0) ? 999.0f : 20.0f * log10(255.0f / rmse); - } - } - - void print() - { - printf(" Angular deviation error: %f\n", ade); - printf(" Root mean squared error: %f\n", rmse); - printf(" Peak signal to noise ratio in dB: %f\n", psnr); - } - - int samples; - float ade; - float mse; - float rmse; - float psnr; -}; - - -int main(int argc, char *argv[]) -{ - MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - bool compareNormal = false; - bool compareAlpha = false; - - nv::Path input0; - nv::Path input1; - nv::Path output; - - // Parse arguments. - for (int i = 1; i < argc; i++) - { - // Input options. - if (strcmp("-normal", argv[i]) == 0) - { - compareNormal = true; - } - if (strcmp("-alpha", argv[i]) == 0) - { - compareAlpha = true; - } - - else if (argv[i][0] != '-') - { - input0 = argv[i]; - - if (i+1 < argc && argv[i+1][0] != '-') { - input1 = argv[i+1]; - } - - break; - } - } - - if (input0.isNull() || input1.isNull()) - { - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - - printf("usage: nvimgdiff [options] original_file updated_file [output]\n\n"); - - printf("Diff options:\n"); - printf(" -normal \tCompare images as if they were normal maps.\n"); - printf(" -alpha \tCompare alpha weighted images.\n"); - - return 1; - } - - nv::Image image0, image1; - if (!loadImage(image0, input0)) return 0; - if (!loadImage(image1, input1)) return 0; - - const uint w0 = image0.width(); - const uint h0 = image0.height(); - const uint w1 = image1.width(); - const uint h1 = image1.height(); - const uint w = nv::min(w0, w1); - const uint h = nv::min(h0, h1); - - // Compute errors. - Error error_r; - Error error_g; - Error error_b; - Error error_a; - Error error_total; - NormalError error_normal; - - for (uint i = 0; i < h; i++) - { - for (uint e = 0; e < w; e++) - { - const nv::Color32 c0(image0.pixel(e, i)); - const nv::Color32 c1(image1.pixel(e, i)); - - float r = float(c0.r - c1.r); - float g = float(c0.g - c1.g); - float b = float(c0.b - c1.b); - float a = float(c0.a - c1.a); - - error_r.addSample(r); - error_g.addSample(g); - error_b.addSample(b); - error_a.addSample(a); - - if (compareNormal) - { - error_normal.addSample(c0, c1); - } - - if (compareAlpha) - { - error_total.addSample(r * c0.a / 255.0f); - error_total.addSample(g * c0.a / 255.0f); - error_total.addSample(b * c0.a / 255.0f); - } - else - { - error_total.addSample(r); - error_total.addSample(g); - error_total.addSample(b); - } - } - } - - error_r.done(); - error_g.done(); - error_b.done(); - error_a.done(); - error_total.done(); - error_normal.done(); - - - printf("Image size compared: %dx%d\n", w, h); - if (w != w0 || w != w1 || h != h0 || h != h1) { - printf("--- NOTE: only the overlap between the 2 images (%d,%d) and (%d,%d) was compared\n", w0, h0, w1, h1); - } - printf("Total pixels: %d\n", w*h); - - printf("Color:\n"); - error_total.print(); - - if (compareNormal) - { - printf("Normal:\n"); - error_normal.print(); - } - - if (compareAlpha) - { - printf("Alpha:\n"); - error_a.print(); - } - - // @@ Write image difference. - - return 0; -} - diff --git a/Externals/NVTT/src/nvtt/tools/main.cpp b/Externals/NVTT/src/nvtt/tools/main.cpp deleted file mode 100644 index 4b5bc07e3b3..00000000000 --- a/Externals/NVTT/src/nvtt/tools/main.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include "configdialog.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - ConfigDialog dialog; - return dialog.exec(); -} - - diff --git a/Externals/NVTT/src/nvtt/tools/resize.cpp b/Externals/NVTT/src/nvtt/tools/resize.cpp deleted file mode 100644 index c7ea21da9f3..00000000000 --- a/Externals/NVTT/src/nvtt/tools/resize.cpp +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright NVIDIA Corporation 2007 -- Ignacio Castano -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "cmdline.h" - -static bool loadImage(nv::Image & image, const char * fileName) -{ - if (nv::strCaseCmp(nv::Path::extension(fileName), ".dds") == 0) - { - nv::DirectDrawSurface dds(fileName); - if (!dds.isValid()) - { - printf("The file '%s' is not a valid DDS file.\n", fileName); - return false; - } - - dds.mipmap(&image, 0, 0); // get first image - } - else - { - // Regular image. - if (!image.load(fileName)) - { - printf("The file '%s' is not a supported image type.\n", fileName); - return false; - } - } - - return true; -} - - -int main(int argc, char *argv[]) -{ - //MyAssertHandler assertHandler; - MyMessageHandler messageHandler; - - float scale = 0.5f; - float gamma = 2.2f; - nv::AutoPtr filter; - nv::Path input; - nv::Path output; - - nv::FloatImage::WrapMode wrapMode = nv::FloatImage::WrapMode_Mirror; - - // Parse arguments. - for (int i = 1; i < argc; i++) - { - // Input options. - if (strcmp("-s", argv[i]) == 0) - { - if (i+1 < argc && argv[i+1][0] != '-') { - scale = (float)atof(argv[i+1]); - i++; - } - } - else if (strcmp("-g", argv[i]) == 0) - { - if (i+1 < argc && argv[i+1][0] != '-') { - gamma = (float)atof(argv[i+1]); - i++; - } - } - else if (strcmp("-f", argv[i]) == 0) - { - if (i+1 == argc) break; - i++; - - if (strcmp("box", argv[i]) == 0) filter = new nv::BoxFilter(); - else if (strcmp("triangle", argv[i]) == 0) filter = new nv::TriangleFilter(); - else if (strcmp("quadratic", argv[i]) == 0) filter = new nv::QuadraticFilter(); - else if (strcmp("bspline", argv[i]) == 0) filter = new nv::BSplineFilter(); - else if (strcmp("mitchell", argv[i]) == 0) filter = new nv::MitchellFilter(); - else if (strcmp("lanczos", argv[i]) == 0) filter = new nv::LanczosFilter(); - else if (strcmp("kaiser", argv[i]) == 0) { - filter = new nv::KaiserFilter(3); - ((nv::KaiserFilter *)filter.ptr())->setParameters(4.0f, 1.0f); - } - } - else if (strcmp("-w", argv[i]) == 0) - { - if (i+1 == argc) break; - i++; - - if (strcmp("mirror", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Mirror; - else if (strcmp("repeat", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Repeat; - else if (strcmp("clamp", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Clamp; - } - else if (argv[i][0] != '-') - { - input = argv[i]; - - if (i+1 < argc && argv[i+1][0] != '-') { - output = argv[i+1]; - } - - break; - } - } - - if (input.isNull() || output.isNull()) - { - printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); - - printf("usage: nvzoom [options] input [output]\n\n"); - - printf("Options:\n"); - printf(" -s scale Scale factor (default = 0.5)\n"); - printf(" -g gamma Gamma correction (default = 2.2)\n"); - printf(" -f filter One of the following: (default = 'box')\n"); - printf(" * box\n"); - printf(" * triangle\n"); - printf(" * quadratic\n"); - printf(" * bspline\n"); - printf(" * mitchell\n"); - printf(" * lanczos\n"); - printf(" * kaiser\n"); - printf(" -w mode One of the following: (default = 'mirror')\n"); - printf(" * mirror\n"); - printf(" * repeat\n"); - printf(" * clamp\n"); - - return 1; - } - - if (filter == NULL) - { - filter = new nv::BoxFilter(); - } - - nv::Image image; - if (!loadImage(image, input)) return 0; - - nv::FloatImage fimage(&image); - fimage.toLinear(0, 3, gamma); - - nv::AutoPtr fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode)); - - nv::AutoPtr result(fresult->createImageGammaCorrect(gamma)); - result->setFormat(nv::Image::Format_ARGB); - - nv::StdOutputStream stream(output); - nv::ImageIO::saveTGA(stream, result.ptr()); // @@ Add generic save function. Add support for png too. - - return 0; -} - diff --git a/sdk/binaries/x64/FreeImage.dll b/sdk/binaries/x64/FreeImage.dll deleted file mode 100644 index ddf91200b192d46e2a0bdf5ad41954712f4ba898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6942208 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

;aw? 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

b(vkc5T=Bi~Fd# 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

    g27C;~&R`DIM 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 z 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â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

      0?TSoyDwUOxEG@$ci)u_F?D; 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

      DtJq1h5BwLw$ly{m#9dttV19moH&d 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⁢kWmc8HMwnoIs4jWmfELgBN8i?MVh*Cs=OYi;u${^9==+TakO(w2 zbY#T`=4Ng6pLfh(-8!+Pe%ZJucqYg?&g%F&4^RYs2bYwU)%{a;M&(ZgJ#E78njCqA zlDgf|7n4;VwsH^ZGG6op2O19v!y{tmexYO&bEbK8FWYUxs*RQJNK|n{S$ux3D3PjLxuTD++G8Gl zhX&o*bc82lI3J=RVQ)Uqn3>VfxHLujGNVk6jcJz1`H;v6I(eC8$(N8#i&!zA#-XA1 zS*m?zJ$C!ssE5*M>I72u(re9@tP2Q|oRwoXG2z37EM!yoBmHdQGmghCQ#8 zaaX4RAl%oG>eTlqD`Ax%07ec+CUdnWi-)kAQhqQr5LG|>wtXoK2|uIH1FtQ&26N75 zT1Xk$=N}GRd&9n0jOYmB@witj+lRGY4f@ zkHx)wf}Yos`^^n3I2nm^%?-8kJ&S`S`3^Ug-N(dfe3|tUeasE{gkw~Qrz7P>gXsQg zX0-A10B=}FkBweh71H3BY4Bfl!9O{z>UxeE5}_w^tFGeQB3nGu#x(#F7h?a!h3Mbp zsDNl2Mq}Fil42xD$2x&oiGe^F%FzLKYTANeDlD&)aCs1Vk_NNv=g0c;aC`l^hW!6s2Tu1kNqVLdgO?2EYGkSb9hW?2REo>6lSC3Y(C-G6RIn$U{b$4JuQ{qOP zxm64KFRug=5atL-IuW-V-Xx|;0=NMkO3>iwHoqi1N97sc9gzj2EpUgE$cqIr)uoML zU%RoQpXyRjpz;hREYi2MdfJE#Zf02xH=v|_L-V3l2cWG({JQuh`Sk%6gZORY_kZcv z8RY*tzY2a)e!t^)6+ergg8g6gtIJ|`pNGODRiJlsqZ};EXFY9_eHnA)-EBCyu5aAE z3wBC&nySvncI{E0>#5Jzr9KP(yZXHS81>0=>T{l3pP^EpPsdW9{!$-iGRkA>x{n~?{>SsS zbMI=n=uzj_wKEN3*jQA`HQ8v)m6Irn=_r}pDxAKNpbz0;tHV$N-azi z8}xt==I7GVE2NwN8QpUD3aWdc{PWe6dA3vL%pPS9{%^`GZm4OLBaWJ5a>il&u%TC_ zM4!vKZW}L2R$Vb&M0!gv?}2~nlpUt)H7>3jRLC~U_Iy?Fa9wsW5rUj~Qqd(537oK# zwOb)z`WHw|PXX;KY0%#M9B6;KK|`DFK+6_rg)X%98d?g8X%4ABs^GdHITBK$5x(1` z)*sPhZmlb%oN}j}*NBi>|Ll8|(@?2ut^3Sa&v|%v-=*LST26w0NgDhi0{_G7bvs5o z@TUv>1wG)e>j}U2d5%1*s2;ulZW{t-Bmwpa>?nq<=uW&?3JJ$HON1G}hqLXanWAxU zC1#+k*NdzM!gucvET`~+k50V$pyXl9Tvhb6w9;>^+s>;8p@m1_p+%9CLS&s0z&fqd-oJ0_Zf|##-9j)m zS5R4${XLG`ltpk?=I7W`lrF(W2jWbQd^ZY`0+zh`9ltv#IOPv*_z|^CxzwnY8wVol zbSQSoUve}u+>U&eV2XD-k^)snzCftckp#INspzR! z9mcCV_yxbZOEf(_AYg@_zEJceQBFM;N(}ZZRC`sQgsc;)3)O8L-9mHs`=Ny&v)_3z z4ZiLb4S#eR{Ive-qk&6Gpo+k5zG|?@?-pP`I7jU0&M_W+1SD9iUnCi59AsI-Qrh>S zsm4i|7`)&xKNwH-$zqo2qsrVtb;g1WqxL!a(#i8K!YZBE!Ju7AV#`vXw?5d{evt%; zK2}sp0Hk17(nE$UKe7S3@rKS^vK)zu!3nI&8SAVrTpVB>Q=iqx`AlszW;CMLF?E+Q zV^@M__f~&KXna;u@xJFZRUbQz=cg=7nP`~#dd)i--VAS~U-j|qO7C;o2^<`qHW@Rw z=tdjs?3fxatT?xUf!WN9s)o#o4SJ5eF8lhUt?t#aRqGiCk$Zkfk&2fcP&iGSKE zhRG`T#F?ye1DN0sCbD19_UWP5`;83@E(ypgz~2NMI}W?ur6se z6g5SJ)pEhN$hZ`yyBmB#H~6Cvy9WOuE&*G-m50n4$7|roL#Qq#i6{v8mB>~G)NBI5O3Sxqs6?ViRs6BT-M7)UG{PuMRG#- z$Pg0oP>(i!3_~F1HBASg2vn?jC{LApQ%URsCvq>5${sS&IYqoB`*IPAHEPJ%8BUr% zDF8X77|64sPUJsODwOIzt|HOpD(5`~H?l=VMwYvfhZfC~tVQ#3oZP?G32uVu$(g6^ zCyUPK!#bkOn#V~^`Ka!QN*yu51({zoZ>Wwfnn%g4_FSD{0BY$2H$Vig_KKX6ufZz^ zc5{qEH5nnZWHLg2$-MpIf|Sn8O&Ds^@~MvQDTdtUOF8sZpOo3$6;MHFdV;cpoD)#CA=;#9KR(`?sL?aNy7Vb zpmLLo1EOd6u$T*t-Zzv}`8$Rh4;Lt3J_+vNrHtYDl)CD2(`w{Kd6V(5M}jq#o)*5Ud z=Hi%i`1b{TT1I(<@O2dzdB7T;${~6tf7QW@OzRqu;}nE-VEZ>ZqTIBGVv;iz@sb_a z5tGa`NOFWkN4Mi#y@uuz~$Ragg*z*Mbm6w(s7*Q3Q-;(aRVJmpPQz*wlF& zA;HG|9^q9HGP2o}iJ~liOH$1~0pq4N`v+W~;suVFCv4eM^jj*%L(+|E(IoxR8ioSO zgtB(Z`g6@gYGZnYGc=hA^>WIDbMZ?bvIxmZlc$zrGPzHv^+h*jFa+$k{w&OW8KHY> zl1gcDHnt;MjcXgM?MC6tyE{BBhl9p>4RRFKXfFt>&8V|by?LwN<#N~+^Pq{5g$4jM ztY|>iFLg*1!x*fRJzRspkwcWzFtf=9o*PS^R`ckmJp^d(uz8rx!MG_O1Kmo)x}~;(hW8z#4#A30aJeY!nnh3P%F*#V4c-`+Xoh zv$G$?6tuDa3+!3)lmRcQVT$NnAs;$RuU$8_+8bx3cT@2~-A%^&He~`6TbM7^G-g!G z8zMX(l5Fz5Svj?6H2tF%oQmIc?pGF|aEY(2G*E^FF zY_t-0r24-e#meQGsoV#9r*_(((&rUHgR%Y_v&6izbx6#~8?{eS-{O5D7yYW0#s8pC zkdTkiUmFe0K9^a8fRv=NWjTAe&IQth+(Cnhgb#AmpZ5)759g>qTg_?e&ojjKeAO5+ zjz3EFNAY0``e@~r$=gmO(P%IpYqpvb1t~4*F;4Ud6`iG{wSh=!4w*UTNH$DaM~3eGLz3M(H%8+%%$CoJxbfHEH^*B!k@)KTS{Z zsD^?mCMn6Q(=1!&Kv-T$2{}40$BA3u#$8L?Kpi*Gi3_-KKH_q9T&@#W=*FE*+)(1I ztA-Ng+qvvCiSg}R-bZb*5DBXdRSiy z%tq%uD^e!<@>)?|R^mT#%#E(RzEeS04a-K192l^NiHvc0!z_DJqq-8XL||l8X`8Hx z+l|~lrZppfkr{2zGIFoTH8-g1b@5?U8R&=&F7*Oi<>#hEA7k+Bp?t5%B?49U*^@Bx zX-}hI6!F_P{gs(vQQ(|67xBD7U4vrKP~#}utFoV>{~eR)z1p9q|76uX$*!q58SQ{_ z1PSIwF+DYHqEXu-E9ttDYtZ7Gd$rlPA1(2n)=@&f;&^agD^4(xNRG=O+MRy`zPX

      }@fFaf&B8I1 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�@9$+RwKuzB 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

      L_)D!Lz_w{#d)b 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�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

        X(c`3Xpv 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

        hq3rG%=V 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

        WLM<-0WS$A@70)+`?a`Duc)E) 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¹NO)%6rWu>4S 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 yRp8KOh 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

        6=3(=QdDJ{+ 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

        &_I7OXe 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

        aSeXyDLFn$u3 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 z8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5o zv;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZf zKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5) z2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;t zZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V z&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){ z0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E z8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5o zv;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZf zKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5) z2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;t zZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V z&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){ z0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E z8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5o zv;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZf zKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5) z2DAZfKpW5ov;l2E8_)){0c}7V&<3;tZ9p5)2DAZfKpW5ov;l2E8_)){0c}7V&<3;t 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

        3TaH`9Wt3qHVawKN>;O$BG&T-U$KKd9N=5N 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%0DU zmX|+KeRW19Og*S1wR1rfa2Q(~K%Ry$TST!->R>>A8YNhP9H9XAV#Mk0w z7Tv_h42k$PtWZmUSuzW^1euBVO0|TDA(M!f6%{Or#am*6$v2BLE7KyggtmD|G*$F4 zvhjvynifq0FPqXNW4DvEG)re6Rkp64i85Y$C?Cs6;jc3+|wrw*tQ$&D$+fMRW&h;pr8qp=qZ@ zTN&MjTAuercOwJdTZtN)_FA_4NK127bU!iR&CX~QYNdR@#&AUs5<@1{$TGJ`MxCJH z$!*zsNK3OX>Lmug*+*KQ{WeA@8X$&5!qFhH;2x=H2(?m<*cwr0a1xKkm_;{<6C)Fq zNJ7gxBv>*#3{1F@YEA<`iRMm=)D=B~T6lUFYG^uY(RN3Vp_bLV@Bmu-yx z=oMl}wZ*bcaUlB@Ft_t z5n{;XrH1t;`ifa9_L`V*t7)yHsFm_tTjL!wI2nt+XBORLj2RO7pka+iKQc>ZpQE3c zN%tBj#*9{pe9^ML3YNqsqTd7)ZuO?1WNqsjV!=JiTT4+Z z<#o2kdS-A^*1CaNc#|!yWyFxlMlEX-v$nO$Y%?qBPIO@^2ukw+TVaO-1c$?R$C6K2xAhM6IeXIj>C z!IIcW>kGl8n~k=PFiXW=YMO6aUkRp~zGgPx5|bIRQSwZdycHOK?ww#sY^?RYVDj_E z1WRTgG|lnWkAkV9pIbi(Hs5nxuw?dynX_Zu%(AbdDbtD8Z=y{%&7M0UnkxEzO7;(h zt>!=B6ZzlqnXb23j?HZxI!Q$cJNYT@YxsG(_&MOzq~i&~!N$L1je-dl(onig2L z3rS0JQEU-0;LXLcBGgKGv5m1TwuBfmS&A&Yg;iRPo+~D4g-tGrtt1A%tAw;Xud*>p zW2=cFk+rck#DaU2$4XHv<#o2kdS-A^7TdrqyvdeW88KwCQOnxItZgxwZAK>E$trC{ z&y|z3-6mJWb`S&KRY6*wciI@0v0cQF$e!44V&Oe1Nz3zITVo$HIH`*5XBOVX8LJ|O zOb%#RuGm3lsaQ2J;a16*6SY!y+ZrBbaN>)3nMF78F+(DL4J#B2FiU3PSdf``uT(5V z44Fi1KCh z1I$vfTiWJr!Mq<+(L2P3J3871Q7h$pw#EZya55Bo$Sk_a5Hlq5NW&VAJ!Y27p2nUq zlkPRl42e9`vYrc;#71H-1e0zy8XIAjioMh{-^5-CrkcKHHr{et+bA()@>a`wCs-02 zi@g_2zS)>y$?SusIUf5cm@4`?_DQh$p5x4#(I&Gm+U8f$l<7q5n`qNbvs+Dwriy+S z?AdLSouxk%wwnLMPr%;*wVB&bi#te~PBM09l9uLzwpql$&lixE=Q%b;VcT3{NMwH7 zJYwNJ3Q5cJ0$XDtGdL+~Tf{89NpV{dF=Vn>!&=t1gjp)Kl$dlYyS$t{U(E6f4N}s! zl3DcT5@twbm4;Q?wwhToTidpVnRu`Awo+oqWSy3^Ua%xq*0w<~>1JEn%9y2M8@0_% zg1N0tMK=?h?r4{{lIP1=-mXC^+IBFD-dw>9iR{#{D%*B3OJ;l8b~BUiRmlvA?A5aN z36{jF+V%@3-OSlm#Vi#&plQ0=4hp84Rx=xKnQU_sLndx5%OhA4^R;;elW*n|ESdQ= z%}`rFFjX|%78Go{XR0m4EES7rn^Dn}X}m2a+R~&jHRxs7{9JBeBI^+U7r&k~sHCbQVCBfu-^a+;CE^C_oZC3PfaU|T=4RP4I8c|$a1I?#4gwE3oY+Xe(vO>a%fzAf7K+tmCHdxGz*L+-J21_km! zlMS^!B{Po3>Y?ZN*;;Pe@zqvbVx{qau4Z1v=LDUbLmH#za#^KTN?MZ~G|PYW}(H z6MNzxasGN_*|=z`=$9$kUlq2BPqckgJV9Ua$;~GewwiyR@)JLlPgpfS&8N)Y{Rz|b zxcQlx(@a3&To9iH8q+TT6wh-MO<{a4XlR-rp9fm=o@MdSc3bj%`U}L!A2Z)M{JEKGdPLIW6YwP z#EFrKOC+IX9TF^=9R?=cNHwQ{pG0$~Me2$lK`lJJ3pF$ywP?HJ$56}jiTH73zcU9`!4@k_+OclD8$ z=gT%mfBXtDByuf&l~{0(!FWGvrF`AixWNog2I4oFg*UkyA0UQIZfRM!nRP!dvpdK% zcXG53f`+GimhA)5(mWJ@NDO@Q5NUaSWMd4+9}`0&PvcLBh4&aHEzi$vjpxkZWF-EA zS$LDt_y{p%@>0Wk6Mw}l6?;ugxYe}wQPfKLt*!Bn8Jvv8-!qGDGR6#ve9*AQ;~$wN zv(NEQ%%ppb6JtiZM80TQUj<8I6Y+0?i8sscF(Fto`_9bS?cB_=AEK$EKcQ{@yT2Xo z3g_v{W+rNIDrldDT6kgsYG|5c(H6GPMJ>wDEv(XV^jtAXD{OK}`$}TqyGlsQ^C}yow0$)(B(k=B4YA-J ziG%Q#9L1w8~ zH8J5<$#y4drR=sfJj~$4*Y0H&-NeTXiTE|FPY*Q3dfHDj3vbff-a`zToYAn(x1VK}ik%}S-O4UsAkX)*d{Kk+ zwO?Wuy}6GW61l8l^|xPPmdviTUu7oVYp}ha7&5u8W!(@gi4C;h6im9=-Sz=ysn{)T z^R{5#Z&%Sf#D+UgOAMk`%J*!I2h8APsQn?c=q5wVkjNtqYq#`!~_1n`Y0Q5KR^R zJ|+8y!dCO2@CozxKMA-woTn?BnW(|3ATbNI@WcYt&@{)QElkWsEzk24^N<1WEkq4X z3oP4(q@}qiv4|M(=Hf&VYNfo`##okELJXNKMHb$|DlJFP6_d2WCYK~u5(D2=LRy|z z*%+mX)x?m<+Qb@S!9B_orKpwiI$L8sGdL+rY+x4NWJ{uq7&6(YWo=^CwuHqMP`bArZfZ6-oq{C9`lM$V|Lf zDiI=vOd?uVRInr#Ps9Y1Zx&}(CLyzgws}Z2RrD~j@rG6@jh;)A)M=Bu5=V%E@9H8g z&qr;H?!+--NaRG~II-{^-K6FDq^)s^8JzSaPBRN{(wpcZhD^?ASmzUGnWbXqh)K7y z%NNM=y)0kUAbp8T%%V5<-D!(jN+2&41!2;BSCB@b)-Ow`^yUmga(vS;WAn7m$|cIW|UN$6R7aWPZmy zV&OdsNz3yBTVo+JI4SB_#4Nl?aYqp`WU^SpTGp|ISt_=am~<<8iQqr-K zS@h--W=Ld}hE>|JnprYi+p&h3c(3w~QewztotCv;uq0O2u|Y8DW?MSSn5AMHwara} zxvfJ*HxrxgXqUH==gV2%u0bj~b})p zmc*($_6sK6%-K=JEEPMTX}UTN3Z|M?GaGN2>~Io8CT=auBUlpib$A7nZ{`y$nfW!% zP)9&8RW#fY6l}U@sw2cK6^m$_QPGrXydx&s(x!32%yg(|VoLTQg{|g?$rE&AyPPJ^ zCt2>)AYC0tm_={yVunPHYFOPJ$CxFv6CKByN%!hzhD1(kS*HX`Vm%$F1(R;p+tI@; z6+5G8p6@s-m}+{C*?dbKa)F)GE0BwttgqveVDdfs1WRU@HO>BxD}t$_*E+5WHr;cu zqn}wSc3s=NA(}EB=(s7`eABxf1A?ihx29y@7VY~TYJP`3!FSdn_t-gu0(qdxhB_V! zCf{R7uw?c~(;V)2ESM_#wBw0j^F4is&F7*i(~*uBqRlrQ?HCbEHGMe+`%T9y z(YE5Rg(sw~b=h0tyit+8n*tr{crV)0R%4>6q93MUk9T|&Z8iVg@kx9_+Iw6yRrJf0 z?5_%2#V0zxDV~rwpHSFp{(Z_%{7^n&)%^VTQ_~zX9J3w&`1k7h>3@{-KQ$Zd{nPQs zZ+Xu8RC-G`|M?$r@Bemh`_GJju9M`?X{xU(-3fa9KI`@m^eRic{BNJPzkz(8jfxo`;_WUk>j^1t323hv!40s2e|4BY`-2E}7mfHNYwLabc zc^%_VvU7F|`g;DS?D4xkAO1>9pS7Cd_s2ikD`@w6@zulXpJG&`<0w?a%o<7f? z;D$u#yNcdpm-(6W32sP)?(qkCefTRT6Ml}~ZQ1t--<-d1sAHG;?eqz5NQ7_qyUx+O zP51Tr<3IH4rvGl?uXOfvm%o4TuYt;xpZ{|P{{Hh%_Uh3aXy#u%dxJkCeRY4=IeNEA z8_2Kwf9hVp`}5R)Mda6MlG69rAM70_?ag0f>2HOeB|RzsE&1K&>EA5xlcoIilU^_R zCh7B$zYpk}^7HbZ@>Z%7Fm>Q$WNfByT|KJssU{z=}c(BuDpwQlX-_5a)F z?Qi&l{mhpo^lS8=vd8cGeDpqR>6Msd^xgXR>y!OW>Hj$Lzg?oQ&wuLI?RUQq^xrY^ z`zTN8_qV^_Uw^;9%)edq-SDUKUjqE^;iOC7Uw{AoRJ~I2Yt3K3KgrJplYf(?rzIxe zu5ZfE|6lp}>!0kkrLPRl{HtMa@Mp4rSLkyzOHXl!pCdgdSu*2aZ+@o^kxu8&NtVp` zUcdYEl)fgD-_xYMrG4a|{Q1*5M0yqYbCM-9Y2V*{p8m~K`xn)J%btJL=RdVqOMVwl zzLWo)jsN}0|6Tcq_^&p-uYjJV|0@0N^Ym|?+AIFwvgcp*`A_ZDn(F)WzvcV|J1#H_vfkqieydxI!#jk&iniIZv{OiRD|Niy+zfO9$N}H(OU($)Hzsa)8|9=1e&wDDL zk!pKs&%f^6scoV9-yW)dcOrcybeX)F^t5cM=>MhH_rLXhq54~H_5PB-@>ajIoB9*{ zd#w507yth6pX|FYy^Uu6-NxSF&t&(Z&(SPB#T|Z*^qgeLjQ@S(cj^%7bpD)V$&Byy zyFX9qYcl!1k@lAM$^L!d-G-?Hal_4!Zj)so+Z z=668)YSJwIz2c7ax$0Tclk#WyyU)|VS>8wW%Ko?P`B#1ZQ+u^kui_+^{@eZc>nnZt zwtgL@*G%>E{eSEG;;(++S--;4J5~K2&NuYu&p+5tpnre=wfd=x|9mCAUh+Fy{yQO2 ziK+e$%C5Ahyw&eGS9ONGh4fRZ`sahcU*Es}`;7b^nhI5YrR6hJwwkNH+x^w&Pkke+ z-zEI{5B~l4@AvoL?{D>c=KsR``@i+SJAeKAa;pC&%>NXpdRNHbU;ZzB9{+!QKmLDz zm9u}3rSI_h6aW05KmYmfAGjTkWd47q8`I2R)8wB8$yo+3_%-GKoC8u}a_+BWew?42 zXFOM!>m2{StuVO&rG>ea|5%h<1p4A+(XRwQE+%AIa!HQhY3VQO`1hT~xqfn9j?#); z%6}|Lu0(xFE}0)!5mK65og;8sn_L6VDNmOEO7P=4M%Ej|oXV0L4C?sz=Te^Bk}S&+ zJZ%)|CWCHE;(7D0#_{V+_~+K#6O(LvF6BQ~BzNS9vR+83ay#frgR+gW@@y3>uB&*SV==C`a%V5or`qILDJQ&^U~f;|9$n@tjaL zhfqV);a{!e*A4K`bndB1)|pHBk6pbbnzM=-FiR3rbI&wEyP2WK~I|bWp z`axQre@+^|?sI@Yr>9_=nM?VP1*uu6FUTeH;~YW?Q*(0!PV-aq&^d*MGkJSqY5^k) z4Ps73sYM2ze6l!Ilp}arEYM}CB?hJQ(p-~2m3~}qJehA+7{r`PQY#Ib_eu-`r&R(i zO|3R4p4X<<7|rCl<*Cvf!P7dCt_Kv(WvLCI$)CI>Rc25+Z&Ws$K(j4H)8<^8zk`0< zYCN59wj0EpDpETPn)fOU0;inuWXhQ%cyf!>11Ow*DKBWulYM~V*{^6qsQ_qb3a5gg&EJzs zg$zpPh_Z>I2B&x`hFW-295k5}O$p2P5NUZnoHKsim`+Y6@G;Fur$NlAD|N)6`IEW~ z0;i(_?M@vtD4tKGjvGz>+-`%w>7+_0*!fIAE0=?tZ4dES3pD4wbWJ6=Iqli zXL5_e^a4f}8pNE6(u)i_`DAgrC`a(LSfI<&OAJcqrMV`5D*d?JcrxFtFo-#oq*od= z@0Az?POAi3nqF;CJg-f!F`CJ9%hRPff~R#NT@NUn%hDS_lRtS&y3C+--l%Lgfo5Bp zrp>uFe+T`z)p$DJY&VEGRit+qH1Aay1Wr2zTAAKuP(1HR?>3tJxs?Wi(_WG80~F3x z>HVO|pX^Lm8I;Zk6pbr=5Hvhh8|~yR$+R;^@Z=V$2T(Zs(q7P*C;I@!vtQAK(gD!W z6ix?0o4+TO4jGir5oHra4NmcN47Kp4IA}6yni7`nA=2`EIA`Q7+Z@R~zbUveK&Zp0U zhNp8zYu+MF7Ywf#Ocxb%U-}Yg%=7vH#q(uF)1STq8k(-9uYxvz&tSUWpme^jY;K?i zr-AfM)S5TlO%H&Er(2foZPeaR^L)oJChv4)26F^Y_eA;tP&f~zAA-g_c?eKEKTBpd<>1p~2Xw7?u0mbt(W%C?0IE|!Vpw_%;G(7?uo?cqCZ_=+&E9KX~$lp3GGip#e zzg0HxP=nK0`aNplO=GB`>4QZ(p8kkho)!A3U!V1`6~=B@0%06HC+UweR$(;1m*5OXTX%ra>HgaU)WX^ub(Gjk1! z=lPj=Mw36c&>(PHAku|^!nr832sHVVi!((ArSoD%vn;a&G(0UeTJsiZT5fp7U|OM= zOEN1#W1d$6D4tg-n$pZ_(9pCtvj(*Jd&)DV2Bq^lWwRbNIF)5Kpw_%;OQsAoJZ-dW zH=%Z0hUd+OVcscCTMe%qOxqQ6MP>(R%=0P$#q&-@Q<>QX8k+WGc7xWurxH*+?^QPY zP=ixdW{(C~D?qIG2sqE^b)z{ua4%s357XScHPpav&j#*12blMgjC`7PQ| zCV*O=!jwmf~T}d zI{}4rSLO(4%#*tS#q&``)15g68k$aIj)T^`ryEc_pHw!dP=ixX<}_-}n|d=npyBC^ zMSDJT7PV472Mlo^Nh|x!^qC}P=eM2)ZjFfd5Bv0 z+z@JLdSuZKXC9-L=ckz`$bk0_qlTtumhE%W(maxRK@52FXl4YpQhsS;yve*GhD=@~ z3vXeS-h$_5caDW-jGF7Ie-+eL*gnALkHK z*f}>x;55H;9y+Jca3=39>|DUeLW7u7QRgCqPCi-OS(GDqS}f3Iol6W#=cTzOe=7aB z+;}qItT2c6~4WIATk=`AIt1v3p!C)D;NY3W>8 zdWsO|^10POx=Le&$kbs|XNxv<+g_YZy@q+9G(m{--T-NFzF{DPr8f!T>2~QY zLajZ+rGs|M=Q~Dn7YL@I(tALiO^-^42$AW&D}4a;NvX^aZDV?8O4;yCgVSTReM(w7 zkCZ+m#Cdsyv^YOEkkQf?gz)sL^d+Iro>9``{Mty~0Kqg?`WC3OX}old5SiY&(2u3> zfok~!F|4h#%Es-M&!3FsGZ0J@rC)&3O%p(P`szX_OTPh?`A6w@FzDV%Lgtk5^wX98 zVwC5p(%;N*HYayYF)H&PFy@z`k<5REp*8<3D;wA%JE$h5{VXO^uc#Cb21v^cLbkgT%xgz&VnYy+Xzo}98QyXEsHBiRfDQ+C-F zpw6ZpW!Z$twAGbv1G=kB=IyrO?9`^6wwFVu-G({0Y!4yMd%2{=d9Q)wmF**hrvqjC z33c}5krwBJMsf%Uru?$QK%GqmW%-22bi{=oFFOiU%g2aeZ7nG)uv1!4U{E-($@!o@N~n44wl^nD)a5KTVObQ zhsy>Dk?D>ry~`-iLuL1vK{r1t8v?53`<})FW;`j=nuo-)ZkSa*Y`1)VY$Q*CU>YfV z29$0Z0m9RB7dl$@0;tTd%3gv&_l^SL>9s3;!zj;VWp9~5H;jfAugX%f2x~Ykrh{XBOTu$*9af!I)o; zMl$~rhHR$FehZ6Ul6+@M7+Ukkm-Sb%^zNT!CV&46q?G@675O<^G;{67nNrK=*{$_L zs@>3OfzqaxFSJ{n7nd)xiS=%p-Oy=?+Abw6ozu&g5n{cZQJ!wMd|qxKtIAgpBGXEn zI$N}9we4k)X^mmdEMH5A^Ij%tab9O2S>@{q;b~*}212bpIptY)%jZo-vKa`b?D8!@ zolQH+vk8%Dt1I0GbXU2|+ik&o z>g>rQEzSpxmpqNj!qA#4 zw&h%)P1kI%giNJ|IZ$3si1S{6v^WP1BvKwCgs0l_Frm(#2x)PyGm-`%n4;xPK%GtT z@+cuPwYt!*@)%GpcMyYaHO<|`kHg&Sk_O5XK$CbPrml9tY?74ryj{8ZB7 zyud)xDi#vL)8dLnggSfDNQ?6lBUuUrQ+mZRpw6a@igZF`TJAzuRjdH2<(0&sTTSz7 z;%C6T#wBG|tOZJ6&jiBLIv1K%u^y<*8!I+|;q1++$Rb3hO|En^qdaFxCVVew0fnQ^^BYcBb+E-RMaT_GmD z$TVNG{W*aWm`hz!prRb8^?LG+01%#nE;LdR0xENDMHmdaHv)vGI#=4jD9_P~CT7sh z@ro!=Ew_3YT@^8A=uHP$c!gW)hVSAm^?KxiiUc!o*8rn3-|#R7D{eAFYi?KEVivt) zxMC2fmhX5PcZDIFp^AIL!b=`i3^7A*?)$PH2!DLt^vZl}M@2&B(6I4xJ&Re=?D z%jcCd#CnzgTy1}8ku`SXOqqeTc58W=c0;FiN}Cl}Z?`ya3~aE;^t(BMteFOSiV3+M z;OUYpz09c0S7r=rBma5Le!(K8cH>NeK)KyoUcheX6ja(sAY`{V*9O8ivEGf?4V~)L zwt=*Cjs}_tv0jb`qIS#YRs-n@#0Zh8!=}y_ZR)nYIGK74^FSa$i1Xe6X>q<`AcKLM zgz$7baEnlD&v0PSZuxx2NbUl`G!(c8)Yq9;lW-5X0I!t8(0K`TWU9J_Ert5%>a>ZkhnX(^nTd8TbZN<{yFYV9>pjgv_br z>8C6G#VF5Hf#1wdHk<5REp*8<3Yx;lpue9#4e$E!nT)T0m)XI5w zYkiq&H*{K{v}u(K?H1?7m5Xd*y_;q?bXuaeOG!)T^vY#~STAQ(rrRx_mmA2c$`ypj zw9=-|7HwK>dl_U}W0*55*An8qmq}Wj*BMAw<$6MR+E}@PP-{<4WtQFYd6SWB27)QO zatlyr(~in)LS)+NO1A;sRVnj!+i-Sj(@xvVA=7TdoLjkv5a+#I(&D_=K=La05yI1f z%Kd~od-6z&^Fbpy1O!ul|RLS#DPLXTG-1*+v^#IUxOR2JARpHCRcNg$XC zD^CHXn+k#OblQa$Rh|JV^SR2iU^siPRu&N=(|K2Vfl;1|D=#twHx~oFUMce>Pvf#M zwC0L!&0G*Hu^O1Jsck7~=^UsmC&YOc|;>Tg`bx8x2383`#0U$ixaG`^hH-XB0yYdzo z&fek5K|*A@<4W%`%JWd=J!a6&k1B_NYWcpW@qigmDz)Yzv8)?r1&8gH&yS7dDG*E} zmCu0EO(Q^fdhS9;D_;PW`BmjhFzDVf!|LsD)UzlW3uuaGqmPM<#%S`9g~d8{1c4% zK{S&2moQ{ARry<3^pfN|Q^L@iKfbKLiluk|EOYwzzo2!M^>emp=Gu)jr3UBOt@UN9 z-Oy=)(xwF$+AYqDgNtlpy_;q?bXuaeOG!)T^x!f=td}!_>2}NK%fjXNCg878Vbi{=o4;}@oTHS!qlC!R z>O#AMF`!!RAO_uPn!AY~hq>1!4FnTF>FWbPc)H<22ZJ|(%6vO`3k+xPaBz?ineMpK zyNvQY6uid_y7^IX2&k6tdm0az@g%4<4~b>nkWw{lw|stVBu{~08VNoFN;i!F;pw>x z9Syz!D)X!0OEBo(Q6N0McBO9^<#{almKk*OcyJ7;mfv|8AA|3ip*J7Ea;}(FHBN|3 zpIqr@MtPnHeqjb~o?ukwuO7x^@EbF<=11^5v+#~dpmVBZ{^@D_5{7K1g1?1DFG+5m z5{B0NVb=UAZY7()iluk|9CP|Nz)(un%w;gmR@=FxrE_Z4JVKoJQb~*R0s~2_T1W^_ zi>nq9>g-7)EzV1fWGN6#=~c^sI-4@8(g~4ixeHxYwF0P?R}zD6HO;Gup8@k4my}tx z7ASo^69`Z1TxeF+dZ03Itl9vEvp1(Iix8PMxzf#y@|<0@g&B17j;d^+THfkuY-7f* zDy`X0EP8`!-bwr%n0LFR+^Ri5>Fc>bc-rei^Q!g%mH9x`elY0XJRm$Bbft$FJ&3@b0MQLpY||{s?IP& zYtB`jWfr~TYE= z4HC6VfnW+$l>?>U1%U7rbfJ-|5Kx(GtHNN=y%8Wh)w$9JMtP1_H8F#3j#ov2YPr?J z=&Fh_LvK33!YkZTH+&aosn;V9R3(^!y9OAQ`G$uvSap*bT64SV7PIIb!&QSowS33Z zxGN0V3{~9|7GCnGYKR$nbKjTsKv++z^zI>;c#~UtOum~F8fNLKM;@tq#tdgy^0g60 zWq$5qj8?s1hSt2QddV!jW0X;uUwayFgdv-;s<**b74y4~`5xq++-tsq3El{R&@Xwz!j%OKMl z!<-pfONjGcCTVeAXCPUj^@Q-WF|>hDYfnxn%WnC+$w)Q>!IT}^0@T^GBa}^uOj}*) zHlVvgGH7P`arQ2v4V7Xi?}4 zP?^t#&Vu3Wy&5VaM5gnu^a7(i7l$q~12-1~y&jVJlBaQ57+Q11www#J>6-18kg3!# z2SVk9IPV2Wi*wLGBB2l=Jk^H6ggSd7q{X?;NE(1(iiVniI-BC5C?PVny3npr45*en zh(WiS=5FH0VeWNF1EB;^`uYG6o^H6%!O%^hGT#o}0>jxm92z7vEuSA7$x|ShMncbk(oG{kczW(aM?)`w%KR$y z5)8U`6bMhRUFjP}c^(VBWd_|m9vTCx<#!&&$IyFb=*Q&U>k(#d(2&q*X5@gr~*TiwJf0 zq>&cqB}TFo2&VMvWk8)x8P(~8$h6#ruBu)ERLd)gLARRb)x^($d5ufTtX>P0zMct$ zr*$qgt9m_9nKxE%0K?gvQ=LVKOq*QkW=46=uHM27x_L)+Hc%~Z^)$9IV^_7-Y$q1I z!8GqAeh$pLT~coK9-#E~Tp&E{b)k9H`+&-Ppn5+TbZ;IIo({UwLyYpAUwxPvbaO#< zK2R+m@i2~8A7zH#90SX_qNKWj5SdQ6(vytxTv&aI8MwKSQJGJB7)8}*n4vZ2s?Rcu z-f^|M2&k6Ndm0ynA)Dgri^AfU6f@&`wboqnWnES*y}Lq8`=W4()3W)Rk(2_#6sRr- zN;d_7@Dy~Rk?IgonQN=VV9>o0AUxH%(gsF(j#f7@gKmyjM}ca&)x+qjjxj@TI>5p! z+)_7u7iX#0BM($3n1Q$J4kg4A~4--xC&I z@~C=<8G3Wym-RqcPpb9qA(+lhv%D?dS=3mt`wf`L3`u#sVednx53Ylh;+2M0ZOXt+^JVG2lm9#i7Fp#wHLPB_2 z99~4IvnP$TI4?1hr9d#HhnE3$Hf4m<36W{J3tbgn0aVK?i9xrT=GDZ{fO(Be$_%ds zN?*?e!qYkzniXCTROXH04PZEXbHZ7K$h66oZf2C{?C=(5(9Ju-*+8|t)zjFWIEwWPcq7LVfYj?aC0G}GN1M^io$1@p*82i zXPHIsxEd}3s^#;Z#sy)>rZ{|2Sp1S=W?Tfqlu@2X!q1q2n@1Rx`MHNN8h*hHt$7uG z$t=8Mlu?;qdm3+qA)B%ATVdfPGH*2nOBVVSxQ%%oS%su>5WI{E`V_Xw6q2)@1mbu=MUn_`5LqU6ah1Q=>IMeObR0OY5e>zZDZNOWrZ1SbFzI znDc9-ne6_mrm6i$?f?D-;J@GdYv`?Xo^6vkkrbHcx}?;ac|ffflW(K~;c0;jO{-Z5 zROZDsi@>0J(}3`_#FZ{(l;`xCWz3+PGiuU-YI(Vbv8rYTGxTO9Sa^k7S`FW2u(ZY_ zXV$D`2JXsaROWRaMpn&wW@ydEnhngNcjVM$0oC#*Ph+z%WRqR9MOb*rj+$&{=*?DN z);3}7s?odcVB$?~X(xP_!_sb#oLjSp8MrH#QJMF87d}ip)5g*p^nxn!pb;p=VuPUi20IKB^p2kUG$fmI7l(6_Eg~HI9 z(>|=Cnlr-EyK^;Xg^71vttn!L-kkSkT~I8oE3UbynDVk>VO_7$yGy>!%c^N=uYipg zx}|IIT?tF29yw4`PK@~x`h7A57?nBbVMJ;|%+Q+JnlQ7RKXdYq2%|FBc^VDEkWI9v zNmzJEye7&Fy=nDfb=Aa#W$HSZ$*=Ot-R%3g$h|(AftrM{_~rp&Xw3~D)?m#|Vd>rN znp?ueyM}89nV~m#d|7uDOY4Se?kOg}>`~2-uuR>3-{u3wd{Sd-A2OTY=#?L{?}tTx z>Z2K{c_u8rc|;gm^W29uTJu6!diSd4C7Ayg!9QOzj|xL;Ui-4%D3;cZ)x1?q`Zt!m zY`kVnSf=isPxE8Vd&M-jAA~Kh^wWG2?~E(WXP@0f%@@U#cT6aj-hK6HPS$)=OjG-# z=DT9cJ0}%O?|%9=f2pS4PSyNYZSB%2)ikw#{wMpd!8Z5*roWi}|NBAyJ3BIc`}BY3 z&Lrz+YGfYp)S2Y`T)>*N$ikV1PKzUp;GHzvnckZgSt6RHcH>Oxk!5x}{bfcZeWt-_ zxzetRtgu@?ubd&)tNiC``%8|WYX|?i)Bf5byY0rAawB`}*79=g zhE98xHZQWzZgD;k*>4l;-8{RY(?PX8L|QuMM-CHWy<8BmSnAVrZggz$7Oa+XkQ&(%ng-SYXokz4?RsW@^G zDBV;{$n^+Mmt5&(MrFP-V^|yc&ujJz7AdtGX9`5h?bh-Fc0;G2(nca7yT!RS61Iu; zZp3crRHwELq@{B-(nN^$ay$~XTRyiMNLM6Ah)f+eb+%|zx9!Er)N7arA_+pA_XbFd z^9=(TjNBxIr`wTRgj#!sBZGF!=Q~Dn7YL@I$UUIWrbm$>LS(w{N*@4y5|R0#ZA|Y> zsU4naaC)q^Pf1JXk;pSboR>#Pi}P~>8I8Okgr`@LmxMZdMoEkFYa@9B1k+gLEl_9E zcw~$anclh3kCFF4wfun?*4A0I<95sEPe$??2&Re17oc?01Q4FSy3onUH=r{AhzZQ*T{woZv`DaHg&dW(`wtxAk!MdoLRe;5a+#2(&D_%K(cDr6T;KR+6{zSdva>C?3T}) zjASzqOxd+tfI6FY)MgVR(^gly4d|{~nYY`9vs0UP+FlNsb{pp0+C79g@8yyf=e-7! zSG$i8o(|ORC)C-KM_QZ@8p$CbnDT2619dhP)aDZ+(-9YXy!I$iEgvI>wY8+Sz;5|` z!bna6!Bkj#3Mk!F2!yB8F0`oj3{aWR)t&{z*?YCNh!C01yV47c@?2bdkr}wT80hs{ znJ;-7mxZAIn>THVFMhTIr)rEG|#(-+MgBWzHY3?R|9Ohn^G*FuWN?#uU!qW{GI#_!X zsLZ!(Z-L?L9j+ZDM5a5g^e&@357pjd2HpIqb_l4J?|T{#nDL}mYaSBIx?xt`u-)?c zv5`Clf@!4o8Bn@u1PD*hUFc}-3!pN;s(lFt-8%||r`N9Z4Wm4d)xKp0-8^1922{)M zJdBUE@0p=DAHc#ZoHVCyoOsFfiDh&@Gs^Qs?H6X?_Y;iD{MEylto_Cet@%;=omqIt zB%?C_1Y>?38p-@i7_ynF{VgndN%Ea3VQ9@CU)Ep6(z}0_IsN-zopqJ&sNTq0<7TO{-gIw>U4ZTVxaK-88$Q(-O5^N?JOn*DWK&dO4#m-ER53+(1^< ztsq3El{R&@Xwz!j%OKMl!<<>SmJsK?Ow!`K&Ooy2))T_h#<~rJT6=Qpvh0@6n~Y>L z5KP&1TYx&7cGP7PBGXn^x((>AI+?fIhO<+fcG_MJnRXlI+`2u4IPc|>7U#VNl2^Bn z5S|Xy?I+aPlSf*d4;slKAei#&4g+;I71ZSuBGVBUdc5u^P%R%LhPAb%uE1{je8Nah z0>M;RcM2%oR0xEp(=N2A?hH_w&()m;!`XYau80ts&b!hJjPhJucaa&mxftm6I+-td z8kdEkHCJrQxj>t)*zaT%o8om*LS$-npjnvt>5ePC%P7x7b@!M-H$SQy0;=Wvp2h=aJgL)~hs3gONU0yTTRuNFlBYm0 zjnq8@N;i!F;pw>x9j$u-ROVN8FTtRDM}hG4+LgXxl;^R!x6GiM$Lq#`YWbaq@v-hb zGxX*ISk4u*>c60t{%qY(jbzhi)n(^-Lf@*7|!0D`Yb|Z+T=<%Gs<&z{T61> z%{%I|fogfHr?HJ0yXv)OJF(~urgl5*?!0Hv?z0^w<|3(c$F2UO+*_4~n~ zd-H(sbkLO^VwC6n`oqkin+xjmfol1PhjG0AC^Pit7+B5~CG`b_$aKP$o@A8g!unIp zz|Dn>%6!_xD5^ih46Qj=f0kMFj;r-WK(&0{)3_iE*%a4b6c)dvm>JjWwdRs9>#}0$ z-4$Zei>!H8Ly2u9=WCFtRSE=CpuQX^{Vo86r=Sas)Q5n|Tw5OogYJz0;i=A*HZaO_ zw7!WMbaT8u3RKIj9!6Jvj2U{<0Ty22mb&4)I7_`Ad7wVQ4BR!qsLVG!jKTVw%+Q+K z^|zQs?-;Hh1ghmbp2l5a$Y!Yip0MzeNA*L@(3|_dtOvq+Qm=Op!Ni-~(qr=7oQ7eR zo_gew`e)2=b|qgMVN~Yl9>!?>3ub7|tNNGB!aGJ8mHD-&@kSW38LNLQEWBjAevBD< z^UjC$vHrcVOx*`&@~gb^C-(ig$e(>Q6ZK!fn%{u$B=dwYwC1Z1YqI{Eu=MUn{dZx~ zzmeo!lfuxNpT4YLiluc^^}iKUUN)szdiTe-`Bybf?LW)5e*0%XXE#_^TR-R8jWeY- z%(Gj|OSKz1El}FDhJ|*E^Wug@HnHAKvl}`sQQM`YrE_}2GD57EGaAzEme0!#WL3io zLS$NLQ)i1dt+u@kGOaPpnGI_Rao)=$Ezau&C0G0V%!&xw#y;mEG2$AW$E4{!d&&3TFnSq;&fnINr`I4t` zSr}S##kQOawCS4dm5`~_Fb5jS331*FkQV2lfkYZYgz!|`5GK^w6Co|mbw<(v1XHx3 z38=Fv-Vh~3rdAi))er-!VvTD{jdKi-p-3-6c&I;Tb!OIkXoHqIl&c_o#! zI4>}ew8n*m@U*yb5uwhWG}7X{#7LF`!Ia*(45+gyqcNQjnU=fIRgEivYI!9w=vLFb zn)n$ouW?D4jcb9@*E50ew9bWQHLeFL^Tx&vU^sho8nXzIX_G76%qY*}u4S?Zl!tnC6|t&w+WjOUiBB1C+j=3xub=E;O%kA5fVOH0}q3?#%G9>(#;qs-8oV_-Q~lr$C)BGU<1dXiC|3mZ={12-2k zD)VU%qp0x=GqmPh<5_0WJFYes0oC$(Pve3xWK-ODQCR$vVrE=#)S64atjmg}cUOpM zU({6Mv~0d+B&9$w1scnN(oF#%JOy27q%j0k=Gw+E7<6w02v2pcw1H8cqm50>pqt~3 zQJ`9G^)R{`W6aQ-4zTbFx6}>a#aZh0$ODZDX5g*?MrFR?VGK6jWQNwtfpZ?WP0pMpEAnxNaHhR z;N}rVWq$5qj5fYthSt1le90`lW0X;uUwayFgdv-;#<#-4OU4_=n4vfCd{`eF-wVss zePAZPism^@<6tNAC(-aPJ_|!O6OCVl#ow6_hSq%bVNEuE6PDinX#6fre%GWhwB{$X z<~MOG+5A#0t($86t(bUO^1Ug=(z`#t&A+N?YX3R*^zZ-Cl%|8Jfe$!!Q(9H!+`9QUN#KSn=bd(u-a||r!ijt-RLS#DON>4J%b79jd zX5i*RMrA(jVH7o;VTRV6YdXs;ddJnKBA{A6?`d2RhHQ$PE((iZQp}9&OW1&)EcJTifu;mAaMu8%GT-np2Agg&Lu+m~-C`EK zW4LJ$sFv?|8h3>uo1vzA!oo`)H4QOCZ|?iD9ti76lioc9)43_7d6*EH9=p<~jPg9v z^o$v}d4y4!pL-aiO)r?CHLsdpG7Ik*WmM+Zp2izt$Y!kRt+4Qt@uo3m=*>GH*2kvz z!ZLLqm`Sgi)jSSV%bz@r&%%(+MAH{x@k=Izp*3H9Sd&fPgr#>sn!XE@-!;jMIn7%0 z)0g#2v9xZg>9=CyWyw3H6ie^^2y=e3G?U$5)ikyLsO|gp3KzLf>N|!Rqb9(bKX3)(U&FMh3yxhZB)x3fk zdb1KNyuvN5hVL?1TH}#3o7XY}cV#jv^EwYBt9d;$v}R-T24>Maa+)m!R@g}#l6TZt~X}3qtZQjES+?C6y%zHhIyykt( z(3%6y`zcw~EOx8*d&HmZ^K^)BM={UNOz>2Vu)A{WPD%JL5|8*=IM={6#V49TSSB zcVB&)lg-~0)71WG{?6?Gi}F8rvYAvYz5D6g{H22}NKEW73NCL`Gl1XFf&3s7g%j%YR^GHrFG+kozh%Dmk+oSoXV)An-6 zwA(P}M)wfnyq8N_oc9_?UUVNJJROMcC)C-KM_QZ@8p$CbnDV2CfjXNCqWOf#bi{=o zj~)f8THTfqlC!R>O#AsF`!!RAO_uPn!AY~hq>1!4MY<_ z>FWbPc)H<22ctKE%6vO|3k+xPaCDFmneMpKyNvQY6urj`y7^Ib2&k6tdm0az@g%A> z4~b>nkkT@2w|stVBu{~08i_swN;i!F;pw>x9gV&KD)X!8OEBo(Q6N0McBO9^<#{an zmKk*OcytV?mfv|8AEWP?p*J7Ea;})wGERt0pIqr@MtPoyeqjb~o?ukwuO7x^^cyp@ z=1259v+#~dpmSPe{^@D_5{7K1qQ8YjFG+5m5{B0NVb=T>ZY7()iluk|9Mk&Euf@5{ znP#i)T+-4xwPhY5&MT>;#d(2&q_r$0gr~(ViwJf0q>&cqB}TFo2&VLwWk8)x87=9A z$h6#ru4-8URLd)gLARRb)x^($d5ufTY*`DGzMct$r*$qgt7SbNx_L)SHc%~Z^)$9IV^@pTY$q1I!8GqAeh$pLT~cn#9-#E~Tp&E{ zb)k7J`+&-Ppk+T8bZ;IIo({UwLyYpA-*T84baO#VK2R+m@i30J9A$>y90SX_qNJsO z5SdQ6(vytxT-b7o8MwKSQJGJB7)32-n4vZ2TFx?y-f^|12&k6Ndm0ynA)Dfsi^AfU z6f@&`i`HE7WnES*y}Lq8`=Ztor)BdsBPj)fDbP|5lx_+D;VI}sBP}7IGS{|*!JvC1 zKzOQir45Yo9BpZ02HhNQi2~JftB29m5@Uwmbby6dxTS9RF3wV~M;>TNFaviDFe>v6 z4`Z<9CNs3=cFQeh(L07)27zk%j;C=~7_u2^xhE{VN_D)Vy>W3=T3GqmPa%S&eA9ixoO{MyraBMjM$wY(J; zUNYV?#tglA=fnEg@?Kb`?gKOVRW#3O9S1v^KZ%Ba@mUzMnP~YUEdI`fFtp~Y4{NgJ zo3QlmN6U9%^1CL5p*265HNTZx$>x`0Y28%IZ^gvRlJ89^mfrpGZT?kFQ~S@ct>6D! zojaXrw%X1mEuB+a=Mmz(l1f^f7Z^xd>q0_!THLybP-jmXX>nd+Bujx{N^e~T)Y+8L znofvJ%U$TI))hdtypkAnt7%?M{0x}axTMV1wLt0XnLv12=R&hu*8`P#W9tSmoV_`% zS%k>6$(3$ql;`Z$EzF>sceG{$)$&$PV;eJewQ9|FV$mB+^G@RDz`WZf<+kntN?*?f z!qZ+Cn%BAysLTgi_k%(A<^kd9pesGZD9`z=hnYb)7qsRB)$$P!<9O>)X6Vf^u$(JO zS_=q~>4Ymi$tcf-t*4lQn+qA0`Lu^o)Ov;)T63=TEVJkxS6hpKYWcjUaX}ceDQ>+e zEPhEbGp@I4%_U#fWyR9FE5xK1ndWQ6FM+w#B?Vf`fzsClKzIte&`4_tsLZvkVKC_4 z2oRp?TxkQNJV#rbm_awkTcbd=-0ER;wZ@pCHyvQ%6>g~;zKgTe>yZaq6U@L}1B}Xi z!^0SCy~zx%x!rn;S@e$K)y^GNG6X5i)#MrD5PVT`uEV20MbYJJHpyknG6nO}PvZ-gP6vDUZ3 z!b`?m$C#lv?|fJvTi*-I)O}zky=qq5I8ZHr@-#jRLpBqwUxdXknGlB7eDz^Xwtf?q z-u-C(E=+#cBs1o;Y0Xbx)-T1p@^TMjRoe#7@CvuI8otY5X^ltDY+K6=+?C0w%;^4j(>Lu(GS?PnI=k;kaa2R)5L!jMgV+hJkhB?WEy%+Q-7KCI(yM}=kT zjxm#7Rnk@fRLdtkjg!KVO<~(9Vev}}g`qX4eON_pXN0A9=i1H+6Ysj(R>TawIq%E5 zpjcX0+;&khafy56RDmwcO-Rnyd70UIxL(yUks@sjBp%jlLe%5$KtoEi9ifKi!) z9!8`s#0;&eZ3{CC?}#uebDgKrAPm_=+nR)hm&Dtm%+Q-wA68deOjxF_gPHs)uiVYP zkBi*vqZw#R2#aqX5Qf&=@L>(M-4vGI-EO-jOuTEjZIBsybH|r;SFyBisO_F&^2;8z z4GGKC-S=%iP|PQ7ruHGT`Hf!rF?>HKHZ1Z}AI(VHGhxxq$#+MDp*7EaSfgz(gr#?{ z+FlBi-!&=>t$FRsdZSocH`ex6G5KZVZDYbRb??Yd2Fmry4zn5$#6ie^E`ZOoozA2`u{n7SavGMOKdFP~J>D^D?<}cOM+o`tSs;yl* zrJAPp&;MlqHQ466{vyM~LI6k{0I$29g$ANC;1hV~YrN z_N0*(=Osq66bPpD*fOBbri@rRAu=s@p{rsmfNFUqG3Zv)yqfqKFt2e*nX$D%>Fb$5 zcv|N|vtsLk%DgeQ0SsqvPArQMnKrr7&5ZJ#9oxbTx_L(|8>p7IdK%l9u`8xE+llqx z4e^v{N-Sr(Rpy;WvKt7d+}IwVbW<)6p7y%Xyx2aVG9QTT2ZQd-1H#imS9*w1p7Ude znL#%f#PWe^`G|*cJa&{BdUFgc=Zcb80U=qc~9elFl194yC^JvNij37$F$~>FYB^m>D?7#(u+*)n^M|`36bfsD}Bl+&m*yC%)refjLQ7n!x)XdV20Mb zioIkO-Z9Fk%&$F-H^Pw3SnRE^@RIS^7&G+doe%3{?7gr|-3MmUt7f&21J&{;Pvf&N zWHS-_A}oH%gfO(`s}E~3_DxuN_apXQnEb9uX3S~VnxDR`Uy7x5Q?cKQiI*ksm{Kgg z`yG>p!D@rAUrK_p=s?4 zfy%tNeGwRRZyFGumblWTjPjh`zKj`kb4GhQP%SU_Fjlp%V20kT1PiZlORM3#43^e- zL1X;T?I5%6!n% zI3x_&=e zg&if7h;+@BmNLq7puL9(Q%qC)qy4*L z%R46(OYeRPbAE?3lie@X)Z3}{->S_oO};y&nx^*8|78C)*yjEp{o=oW|M~CVd^+gm zbe?UKIq?*j=enfSj(I?>7n5(K0^wtH6o$}4xX@8cr( z`e+6^62jt}2ZW(DH+)!w9XExgceguk2@~%c?igf--rVtJ-Bm2D8|t{HnEbLw9Yex0 zb@zRn4;1rBhpBzYYDjbdrtSjSt%TPrj_rilucE z9bXhvUN)gvdiT|*Ioa_|F-`4{j_-;s@0=9YoKC&_>D&CJntD6c@msa|rOB(NRMXV{ zQSAAhnw@O_8f*AJDb+JC@G#Ok7cxU@ z7I!XUmh-1fUX{kE%u76trNWR+dgn4>;UyWJ>CDiZQ*w7U*(lov+pxR zUgM+5>|84>zByAETC>iFmDRakSbDdybAvGPuAI&+X6Vf(U)E;D(z@)O7;EruJOtS;gjeUhOOrmZ>}M+q|HfdRyFiQMI*8ixu;Fr>VX4 zKiQWJwzRZTPxb@V ze$r{~ABr#J&3>B4;+3pV`@{SS3(!1wA&C$*mifL+Jb-q+=dFQBN>D_DJ z<{Q=2+p*5Ksx2=a?;KN1bNlXpus?RbS8ccc1N-9t#rgkSC7W@@(z{Q-&CjZ-w-cRT zR2%<(r!SpQO;h{zf3PPzzp1vl|Iztf{X)BYQZ-HO&;QB(Ww1^CROfHQ7y9K>2HV{K z`Jcb|Yy85E{G0x2`v3Be{C9SI`cE?b-?=l%`k5M^2RwBqIX@S$CM~{jrlHf~_#${G z&301$yCp5YL^Mn7#+lON%j|ag%ZzyXOoP*MrCk+YVYhra@eMXf`R~Gcr|mN|Wo8HexzqmIBD?LznR4TM?AG#f?S@W!l{PQF&u(!(5Z`Z;l$i_j z?1oMU)%Fl+>6{-wOi0Si%LVa#yXEr{134Z)N{CFyY?|`lmXdhEOoP)2wLM8%Iv2)I z5t3rRTu54+Pa8;4{0t#Hor|9(G-YPb)p(KJ^7*`xTmXWpIDQdm3fWXl$n`i+mt5&( zMrFP-W2DS%KnCMC z3E}B>{1%}pGkb>PgLcd3J4SLB2&SRI zrorj4+CC*Mok!x&2uZPD9w9Bx&kbZW{(=ymUd3M$nqu!6B`wacjpPjwOk?r4KvV2Z z*b8Dbi3vA zasye_wSo|tR@&6rqD`x9FM~{L40C4JT0)%nGD(Z`Is?h-T2Ba18@o0TYVFDC%CcKN zZ!(h2Krm%@Z2{_R+R>Fwh)i2u={BIdx@6vN8_rH`+G%?^WZG?*bG!Bs;=GqjTAcS9 zNM6@ILU=mRwVzODPabJ;K4>I|fMCk+Itet}{SoKG$^?3}^4vt|CHYI`2v^Fv@dr*F|RF=3=1N zyJWuPXVvTRwL>PaC^85Nhqo>CUoSK5sIT z%|I|^cW(jeY}(PCO^8feUFkNUySioGZX3={ZQ5yjIb_;xm~*@L5aPU-OIn=w8c1IE zK0-FF*;LS-Pl!xMTKMj2PC|lI{Y#THU4M+uRs)rEF-$AD_NgBWzHY3?R|9Ohn^G|-&@N?#uU!qW{GI@o;^sLZ#! zZ-L?L9qt|^M5a5g^e&@34|U&T2HpIqdkCnO?|T{#nDL}rYaSBIx*?@!*lzj!*hroN z!8FqS3@F_+0)(gME_Af}1yGq^b-x6I?i~ff(`#4yhEbl!y5BN`ZXWL*1FGeB9>&M+ z_sr0n4`4Z0%<35@M5a%!^fRM8Pjr7_25z2UROYW9#$@+5W@yci?(fXPJ0^k7>5=)T zr}0Y|vYG1sEi8ITa`TihwB`@9=J#+b+5A;3z5C~w)4u`sru58Q2GeY{ol9Cer}oSv z#Cb23v^Xy?khGqKgz&VuXAz;!o;1?pyu?VB0>PBtvka)SDWfNy5Sf;{&{aJvfNFUq zG3Zv)yqfqKFt2e*nLTTP($_PA@U+f_X7#KGD)Yvk4PZEXb9%A}k!h1F-OMP@**#mB zK{xN{$p)(Bt)9j|JuznJO$S(bgq(E^Jp>bPa!ZfNcXN7& zS$gV`M|z$y!`YR5ZG=&opL-aiJujG{HLrSJG7Ik*WmM+Zp2izt$Y!kPt+4Qt@t!ee z=*>GH*2kXr!ZLLqn8~m5%AeTx<060d(M=(Ip-(|Q-$EzXO37um#mH_dM7v_x%}l9tZty~_x(Ue4%Ew_83hH;`4m zD+rNkrA?hJ+O*pCGRU;XFlY9zCB%6zle9RmGmxy_^@Q-Wv3CQZ)}EZ+EW73NCL`Gl z1XFhJ7NE|i9lhCv$h6g!ZUefjSLW@u;q26=owk=lrrm})w|5UA&U?9}#d)uRb> zKrj{do&riY6$0VuvK5aQ0s9Eh0pw^RDy)qdXV)UStMtE(UtNSLREe z#${n>%@x~nF3_fHwpT)?Qo|hREhofzFF;zHg9Z}m4H3dqZEu)RXHSH*IM*3T0}xEn z-X@^Vrg(3Z5SdzCXjg9xsFpj3LARRbZsNyb?sZ86y$PW7^#LF}-Eg6Uy*Gi%e7pA+ z7|!0|-a$fSy5makGRpH%?>%PF&5wGAfNJ@^r}2OpPkOcHA+f9*Qu>DNmd}rkrm@!m0@T7KtYeC&PC z488dPmUG3dzHvfi`s7MKGs^Qs?-yp^<_Sh+{_0^&_I_iA*8J%G&MdrR66l;hnSXj3 zzl0&1sovkhqL(B$PYFY7{xEBPAGeatU&Ye9e~xMW=GW(3=1jBIb}nh@oZ2^!5a*Rt z(&D_pK+^ga62jBszD0yOd(udY^AaOj3ItPn-!h=iri{LHLS$O*LRa;z0IKDc#GqSE z^J?N}z`VvKW%jKFN?*?e!qYkzn$@=+sLUJtHh|&m&FRY`M5axybTgwoXZLMk2Hm`) zFB_HyvQ%6>g~;zKgTe>yZcg63oC|1B}Xi!^0TtyU7f#x!re*S@e$K zzCoZ`zT;`!6^3kv`tAt}FL~5A#0y^GM$_ zX5i)#MrD5PVT|^@V20Mb>U+s7yknG6nO}PvZ-gP6vA(y$!b`^c#+acu?|fJv``!!7 z)O}zkzl!ELiE*%#`IBh)7oUY8n~APA?SO(PDl#xg$M5g5~bX8&nP%W<{ z2Hk3!R}()2<~1%UGqDyZeLWKhPwQN0R$@I+nKvdjfZ^=TNn{Zs(l5!J!fYR44Ymi$tcf-iBrtL z&4rB0eA>e(N}OSa)|^Y6Wfr~TYN80Jmd|?{7la|3;>1N^@k@%CaXq0mmwZ{56-)1~ z5R+bHny(SR1m;qg6iAc$9m9!1 zpjy7;Y1|ctY=#o|goT$pN(?bWZ|?iD9ti76Lhl}e>D-jkKTL>Bk6r0gMtL4dJYxoK z9${4G=N`sr;srCb=2hY)v+#~lMrD5OX}l4JY{n9Ag@u=lC&rkeH}8B{9~19|W$HdK zlU_Bee;lZmKY1FTg&~`X#1~=lOD2S&HD7&LlZkJ_(z_pt@51DFO)_Inzt;TpW&Kht zt(!{xR!qDsdB>Du>D?b;&hM9Iviqx=ruHAToqqx7w{D#^kOK2;NYt7O1XF7NJfQTu zR3JPpaG`1a3xUeKxPK8CbZ;6Eo|d@MrHt~N-oK0)baO_3I#4Yy_b^uVuV9AWtON_M za7(MnT*Q3&cn#+U(XD!+1S5dV?DtX=(jw;fEp$t~@K?{Zk$?U8f)_b>x@Npy+2r>h78YJo(4Wr?y*c8;I^KU&Sf=h6GwD?&{RKd^e8ST>DGb>Z z_MZ|KzobwYT65ZmRn&h*SbBG^|Ew_auB-h;%+Qn(Yq)=q8G3WamvvXMv~H;Xo?`OL9`z3i%hcWXZ9Y)UC;g`OA+!07 zUimTmepuwEKAMsKXJE}Az;}{)L>OB0+=n&V|3X-L_p1N@bMo#XQNHW`za1!vXjw!^ zL_doNi3p1bi3mFo5)l>=5)l>=5)l>=5)pPFBqA&#BqA)LHR`D2X&iOb(a~|7A}k^# zA}k^#A}k^#BEEap=QHzMhxh$Fx4(aO*ZcK;-OqIyiw()%>xDAu-$?SVQDq?V%F22T zEX2nC`v#cuvhn|pDa*v(TACmJ`wp09`d-=kN*nS~ePAxp$0vX8B$)&jWc79B&HqOKxpWGeCi;6?_8)_7=6_Q! zQos8Vf6nx!eumVav(vH05Qc37zHvn&q3HrhH!LTaa#2-_1%BIxT{9F`;zM z_AMbz>dQI4>@=10QbV)Cw~RD8El;=37BsC)dpTrUWtek)t4ZU0FPBh0uQ4=vzO|&0 zX}xb9X;XU&e0gaq=MBbYBWrld_ibXWvuT?zpENpcc5Sz?c85>rt!cyAiKgvouYgQD z4RfJy7ipaD6%xwl-G-*fw}&(`?epy=t+S_yP(JTBHV0V4Q?c(LYn@FczGBkobjYPW z>O0I@l#dW2wY9=mlBRM#W^9hLhNn{B3D(k0rL2+Zq)S`oJH=X^&-hL=!`XY;S4JA0 z&bqeeL@RT-@4PVh=5p3v_33=U)3~S%L@uQ*=K?fcNqZG!x@MRweb-6je6NyFKHo4j zRlb{~k?FSY7HOS5RfO{SjO-WLSg9K_Y9nbX=K*6g$QqvFz8GuirZ{V4O1QM6zUQpf`K9j#Gw9w?*2whA zwS6sGna6x@gh4lt`^H#{@>>t%gYTU%FnP}`=ZYD%+DW^7@G&(JHX;;)PV=c!B`Ey|lcjV;31QH#h{V$mB+^LFAFuz9CT zDy-ebTKe@u*2uKmr7f!6!&;s9)$U~m-CM*OnfAN32Sh7#aqU52(9I>a#jHj7kcV-! z_OLK8Il?UGii+A2(&%)|wLLCcnM-R=2!n4f6|K%EJ&dy2Q^G*xOzml5(K{~Jma!J) zv!2E|WoS}fdtO=cl5$~OtwrR5m30wVm|Y@f`l7lDhl=@%vAM|KpWPdu`(_Ng%VE}v+1uJbSgwSHkB(p=jpEP6+zHo#hxTRe?6WoQzr4JwOY(q9`A z1}0rrR#;ilTFiQx>D)Ap0I%YU~3+nPnqtgc0cB5!z&ac}f47zz+T|R43-t1{?5yp->M79!(-e8)y z6Tg7XJ6%#?-7ePBuNSgLrrj=WQQaQa>b$RRFEi-gBG$;X-?cp;TA7RM4hn;AE~zVK zEy{;HjH7jjg@MTtW;s_>)RmA%r(>?|anZ_LT6aPid~>O2bw24~l+~RQ1|nzbP790P zak;LHwJ4wUG|nkQlk&Rr%959q3*%}XA{VTzi@?I{5;5sTruho-E7*L^B~{j4XD$7D zC2M55;nG&s-DIuKx9e^(gYKE+!1VIWAhA6CTEB-E(0e^0MxQ zu=pLLqSg78r}0`DnvB)GQ5L^sylzYwn7p;HKGeNamWjO=CcSD#{Wxn;{^)6ZQidiI zb)S_bFPTsVB3~@5$-1w~!t8t9H)YDZCWSGp9+4kb)=yv|HdXfvnEbNj9aF%b$Ui0W;{{ zEY`@h$hBQ8TA8!!mk5Jy&Z*C4Ey_zhj1~3Egn`L&X7MZB(n|I&N2FCAIk$ebF!-)q z(dxX$!^o>&D-1-|*RK;6y`!K$kF_Xo@H93mLzDdaP0HezY^%=~1}2-WtS!pgQIFYH zX7Zcd(suT)K%|`>xv+khF!-)Q(dxY0!zilXBMe0L)$bJ+zoSUBI`8*14k$yD;`)Qi z;+K@v7YhTELl)N2`oqdHu_MByS5?%PuomTGp2l%yXi{2#LRs>XQe_}=(!wgMKcy_p z&eWe)Cco=)eVH&YIcsH|0~TWC_2+@9FDqBp)q2b>SeqB2X`+{y%`bG)41WdjlIe=b z+`T4RnJeqB3xmI}6s^uTJdCRPo5DckcKt13@jI$StMeUCYpl0ZuThykva=2Q14e3X3h1D%H(%N>I1^S zq{Yf=0~TVT`XDgnW&QObWtmu)wHXFxwBAH}g)MLN$^-2EEPq7hK?@SEk1308PJTD8 z3`7zZ)@c26WnuQR{)IB-U8BlC2eX%qr>%RiiM8DU612+HrO5QmMEX;mbn?Iq6 z=~VqMXroJ~plPDNr)B>!*k=CMdExx_2TU{l&d=gZvk9ehrhg7;96ys#KF>2WS^oK? zk!hiS0co8*S%mU=k+E6K8lJNKOIYh{%JFBDMyI7N?F#=g)}p+e7<8*?UP=5MHm`C? zx&GCxrC-lwjZAA?+C2YS*6O_8zm6Hs-U5FfX>{7)+HMrB%=!LJ!l0YC`SV$e@@7wC zi!gTh5!p&CdV^`+PW%Ek?{rCp{#~r4UoT{hOuJp$BL5!N>b%dtml&GMfs42anyfU7?>PkmUBggzl1b89dm7ui&o}R{|RC6&84E%`J{(Y z=07D2M9%n63ya=y*APh_%GK*i~mL9WrH6lIn$Ugs5Venl((du01VFdhsVIb1%Zxj~2BjOLR7UdRC zqfHr_g#1Be@k{#sAz@(BWo3nx74>7*%S`8{jD`qlbQ*AN2SqD$+#eGL-y9dM&Iu1= z)c;%nE@foAUnxCci9s z#}u$I`>o8m4cbhyKhQMMztsNc-~E9Me@4TQgu#PqyR+fn!5hlH=qM?MfC?E4Qjw?fx(uNbtl9!Y! z1Cf&!R$0R-Wnp%v;j}XOU6&imgn`LfE9)Gv5G!vu4@`Yoxw5V{V0OXUya-Jby~J#C zVPgetRJ!8YUK6d%l?~U0!8ccmR_7ZYMpeU2VIXq5;g+!Y9aW;$`HrV?R~edAH{4Se zzoe$2S{Rtzx3C^HJW!U2Jrt(A$}2w>?`u?kVnKWjPn9J%`;>u5orM)>@GA?m=7vUP z^1C7p0byX$Vr8`f3$ai`5Sa3^{)UjUOsvb=3)LjIb8v0Z(I48Jff! zV#<=2#Fc?a!onJDc&;qWUN*c?ro3xZ8Hl{HvR(rVv9X3Xz?7GbH;gIE#NJw(9~#~P z(@fthTVKh^tj2NiCP_X5rr&)67Ge_(pMj~rHvufnzF3-*4PSw2qTd_70bAcW2`tQh zD06P3Hk0fpG%=lO_yuiwY4W>M&@|EC)3W~ovl{2KR_BF{3z$LoX0b-5MXv2)(aN0NxI`Fqb53J6Yf)b6VXSCe zCJaoLGmBs0mR7QNIU=p{$hnQHg~4~_idN?}9!6f{T45lvzHyzf=p6-(d8|cwgQu}k z8JgrbZc-M%WLsmtFfiF{Wo=Q`jz-M3GLzrrmbSBZ1tRVA$c2r&gu!kCO%uJuY<{6zy29R7h;+>(S2kW32H#aFTAgor7*&log@MTJ##_STcT|a1 z=R2OpU1exe-FQz~{F0i+YGGh<-@{A9J zbrx2j(XTAbnj0IH$?u9Z284l0iML14pQG|B3zFNkT3K>)t}+l=V`1ertyLCg z>zmdoliyX)lqU>KHdt93frVIp(=5|yObq27b*jh-4<3+(;j7Ewy$ZgGUZ)G%0Ohlm307Eh!r;-1g5;Kq^Ve0CU(fu zJlb>^m}YuJ+5F0irV?Rba?Hv)4lKk)iFio_%sS()n&PY>0StizEZMH!Z z(@;|o+WOM|rVudAv};;+7~0V$Gw)R|^vyP8Kz%0y$e<;QH^qRd?}!5nvxKEN+VmWl zCi=4Jg|Pn<>-vpzX%rgBR#( zTlNurZyd5u)1VVgpP`Ment-N>ewl_n+4L3KX8yhD8+?K8o`j}}{+O2i(_owURMRiR z3w-&M!8Y^X(|+;C_`kZw}n%}NtGErN70p>)m;EFn$m%Q=DUG?nvGL$e~Vj5InePq)q%G_6c~Ib>R8 zm~#WGN#lGkmry>hF*JFBwWN`0ePA7FQ+o;md1)%=4aR08Yk0~JY+|jmXXao`|polPZyV$$ez$fZ3RILumu;rr_#U)*3wO-tdZ%Y zOIsE=#af-u1Wq%<*?T!qMjD;Yy0+&;D|30^yfFCYa@JlA=zPJ`xTp+7E~PE!0yJGo zdlh85W|%7j*Gc1iuaZzc-!L>)ft#d}>2}~2X`MY)g!1{0vAN3{o~i@)SnF)62~?9t zr~5ALqrd~!qWq8;bgOB8O#B))KXFOEz*E-JulradQ=Lm22>4m6b911P8P48FAV3{7)+HMrB%=yimgh4lNYtCma%9}ln zEyCE*jL24E(Hl(jcH$SXd8bP%Y~ICM`t?HA$h6y~Eo$DwTAlYb?_~zvTf`cf_Pe$R zL@RS~^Fd+I%_YsntVQ{dhjFy|urM$=!Yt>Cislm1=yc4rJuX_AOPfy!gKsVstdCp2j(4Xj0yMURm;za$#I;M&yE(brD#YT_R@sqLvDW ziusDMxyBlvDx0sfmTszKjZ8OO+N$Q8tkwB;^DSo3y;ZD{>5glASF|!$H{TNm-CWaL z&03W2dl-+J9|!}Jhs@$vxTVMJU5!XjJhHF(sWA91pJ;Wi^DqL}BJdHMGXcB4;DvMvz-y9MKCS6umSXt3#%zByW+%%&lLK>Y0T-!m>${cTw34?Er zi&p1^hcVjxTo{PFY`J*E8#V2KGGSU25S@Js*%0T3cg*DmyRauyQZ~mrCdDo;e5cwgjxh>L4 zlApjrY^wPeF!^Q4?@a*}hNf#*P+5wi1ipV4AlRzktm!?Pb73IzvgL)a_#LC7)%lgD@md+0jJ3Q`7QbY?WlR{DytS}Cw7gT6 ziM4Y*hNsNdIjp5$ z&t#2E^IY1j*7>Z}d131UX3)J^tdVJvYr9yqGH16g5eD6y)0)j%l$UxKD_WNc1C!;< z;#at(mF!)PNUJ<@ZtH4c@Ljp0)p?DFk=MFb7>KNIT_-GhM?q^IYf;|dX>3%6Ci$(K zl*KRE)|xL2Og39tTa>k<6|=3(Mj^ z-7749N0DfC-tTD~P=+SOtp}CGFDYp)76vAVEUcrghm~bwM}$eQs%R}?Ey~9{jpNGD zq_p*fvg9SD%0T3#g;myiN?DklX+5n>e%IyJGGSnH*2+2uEX2xN&jV9mR<5k8t(aY~ zHZMZcL@zO$U+AP6Z56~zrYj3 z&UZYGyUNg{y7iv2_$4*1)xyB!zJ>Lu^?|ZX?4dB_RbKhAcweLP6AR*NeX1MX24t6y1|HMce@liw9-4G0617Ava_ScrvMgTR!R^|ywUWnx{{W*C^!RuktTJ|4d!#GqSE^Gf39uz8hB%57WCTKe@|*2uKRrOj(w%UYe+x2E( z(iXMtVXe;l+V(Po?k!@CO#5Bi1EQ6=xb2`Y=;o5PV%DO3$iq0=c32pg9ATDoMMYZ) zX>>Z~+8!6J%%yE7guyqLidN^79!6Q)DPbUTrtP$_=pC2a%2U_KH7BlGH zD%Qw!$F;pHTA8cc?g@i#u4$`gEz0*jj7Mz`gn`LJX7MZB(qs0nMx-Ym+1K_|7<`vc zv^v*$7=bpwFc4{OYZMl}BhnUNEy^vPMw>D;3AF{4#V_e^3kd_0E-NdntY{l%z07oO z%4m;}MyCPSc2Kl3$J=7U;G5&3)j8o|jJ7=&1|l!pUI>fdF)CV}UwIm@m7&R4+Z$!^ zOUB#Agn`Lh3+qGMJ7t;JdtuV6X0(s97Uhqg#wTTHGST)~S@MzzWgzm!!kTRRsw~XD zw|!HlylYYzv)U2)VP*XU7GhIvzktavOWrXBEX;l@b8fpflk5*PP4q9doqzYY(_860 z)7Z>r4NsZvb688in8_NM=DD<4?ekfy^TPH8%%FR-SR>OS*LJaJWzKG2A`H4Yr#+js zC@=LeRj}Fc4YazD`*5j)L|) z)}p+@)7YpCP4e3}DT`mStvz2Dm~6JPwkT^yJ7!y%$!~H?+u6GUk#>6I!uDOl;JXS% ztMhITqo{q4Fc8_-zE@cMjv~?Oyx-F}pbSll+Yc&>UsBRuEDTHzSy)Hg4=c;WjtG-p zRncC;T9l7@8poBPNoo5DWywoQm4V1f3#+XCl(H~8(|%f+{I1LGWx~MZtd(^RScsLk zp9iMCtXx@F+cCRfZC-??iC$thxiDBk8>|KsXt2}aUaJ4Y_u3XXTyvD=G3$7Ig zBI|?eghlTt2!D3-xa>&9u z8a%8l6FVYIdR0ZRgtaIi^E8etLzB|r31!JkN|k}gNeinicuHBAoe7>+Cco=)uuK@3 zoVBvf0SmG6;CW!`%gU8?HHg^-Yx5#BP4p78`Gs!j3VT-}(lw7<8N4nGzN=ESI^Xax zs)9F#fynLPEn)FHszj^v9Z%z~GBl|U-cuI8q$XG`3{37@SdW4alx1QMg(4{iQs2o>dPj8 zh1nNNb29i9m?ru?_zl?l&Pip>>cH%WwfPg8m`(+ML0ev$ylM)XCi)xLb32foq<;*y zng8W4=x=~Joa<+VGDMmwGIwW-R_4r(Il|!YGexWOJP#wQW4{}b%fyxoQ(onjSBm#JDzCC2xgD#OB{%0P1Cccr zR$j+iWns3yW1TYjT?HL^!oXyMm9-IAh~;-|0;ardTSvaKOl-5YxdoUzI!tt{u;q`udL`O5e6p5tgPd}Laemo1TghwrNF}Mq@`KbaSE6wdZyzv zu;rbXJIa)0VrQ+*bI`=JyyHBy(WT|UyxL)+7p7%jG}vZ-NxYC3d*v(a{j5-h%GWGN zWyf`8(ap*4Rw@IL8x~eo$4zBncDv)2GUZ)W%0T3fm30?bh*fvo1E##JrlVR}CU)P_ zeAMv(m}dG=+4@Qw@>qSR29PI~%-8W0nEDPMurRB$Gy@%eV47%iMip?}!O=Zb*JFN#el5 zEMaMmc032BiN5T30c`&FmArElSeU)CHeW*%)3J^>(AJlZcZ>nkOy5q!{?PFb+HU+k zc!93AWgo%!#v%JO4LZ^B8QSQo322(=muc9O9bchs=HENMsTcnV>A#O8n}nu`{+O2i z(_owURL3vF3;8$x&*f7F+suDY`^6vQ3%BO4^UC?%ADCu_oS)2@W)n*1%+MUtIDRIf ze4b}$vO@DoBh$jr0@6BrvIyn#B4e|dH9Td9max{@loQG(jZRBl+7+Q?tVMY_G3Zv) zyps4iY+mJ(azm?GOTV7W8kyF(w0WVmtkrpaXdN@0y#=8>(&)6owcRLMne#)Ngh4lN z3+1yG<;|YP7GdlNA+nWN^aj(so%jW8-szGGL%Uc@zh1~1nRdIhMWH>c)p=iNFEi-g zBG$;X-?cp;TA7PO2Zcd5mxPL0i}E24<7nuxFfcj7Ea!@fPzh;tI_BCQ7p=^tp%cR3 zn@dHj^GOe*EObg3h@1(X78bqZa;S{8D4+E-&M8Ba^3Zu@$xF(GaW#a<1uN?!urRws zOnQ-NzC!#8HeYi|m7(jbrC+aPjZ8OO+N#h^*6Msabc-2uZxw4~y5rj36|KzGp?kuh zn`=VVtVQ|0hw&)%Kp2=jWEQ`|Ej?!MYD9YCk$s`3!r;4nqSd+1!w7`@!a$@s)F>=^ zMD;359~n;+OP?Lc+kL%gPEXD;mPAmzmB@8J!W*=rrKk4vJRhcqk?e zzBw*hof96$Xy~~x5P2DTAuN8!sAzS5qF?BvP|r~ zFzHn@I>%Xy@<&hOlQJ}!2z^$TyktTdhOnzDNjwxVa_FI{AJGGf)f1qiif2r;KyT6m(O6QrzW;Sbh%IuuOTKdII*2px^ zrOoP`&sv=qb}nEB-J8W4nHIUWi$yDQcIOgd(9JoW*{nr*sfV$mbD1zOSRy{E}^* z`NF_tvz4_)Svxv0+saISlUv%(-W756N6O|&vsc3u|--&`qLoo{#;Rh>75fynL7Tf*XZREbvSJD$c}WoS~} zc~4pVlA6wHVPJCK!g|#CKv^dCP?+*6ul!iNuTlAl1@U!0RhHcBQwAb+7FM9suPn@( zI~$eB?}~H=gn>zmmDL6;#6q1xV9Lw-J44Dcu`X*f49sY!iS`Pc-Z-Nx!djFEJdHtR zXcF&?DN9}wR|X;p3v0CVxw0^O+4(}5@~%;3Ao9w}dJQbZ#yZ~sQ(iXSIi@TVduwTa z=zIrEGkvdYeI+Ney2izuB>4!Ke)kDjh)r~U2B!Yr1h6psVrfoxeg&q9e((GSY<=e> zurT|f%(-3KOtPQQ#B{3j7qsQ2$?r}<(?owy%l>1q&HOKY;r#xmi(XFWnZ{-|Yk11+ zn!{T9#Z1=7G|#2Y>YC45ofmd3UbGp2kLH zXp-NxNm=}oZC&}oz+|(PwMAJwx-i?yOn#GF+Rok;h_urq7k2Fu2H#aETAg=$7)4!s zgn`JuuD!zIcNB?M=l!0>0cB`X+;vb{{F0KcVqsu%$ih0>by!&@c0`!;s*0`>)}nmO z(>SgSO-j2?C`(>astiOpU>^W#!7c z+J)H#Yx5#BP4p78`Gs!j3VT-}(lw7<*>znQd{?Dtb-v+YRCV1H1|qk+ZV8LuQ6*ZP z?|2$_m7z&>*F9zNOKQ5Rg@MU^3+qwW17(@mLt)CRyz*o5zDDII7R1-}R9SMfPZ@~R zSy+KCzp^lE?rKyfzbn!e5C$eKR#qFZ5DRq$fhjNR?+Pi)#Ja4_FfgNCCfX}(dSga+ zgtaIScp8Js&?Md!Q(|MC~kZ-BxX-Q;?e zX1cbsMJsb=_Z(sHU74cQd7g)n)jeMrh%D@0AS`}ImS}Ze1u5*_r7XF* zP#K8qwy=u2_b3aqecgMNDeo#$1|s{dtOLM8thoCiFy&<>-Nni>u|t;T(eA^*G}9x> z=2up9mk0xsV^-F2U?Eo8eFB*JvQl7ScGA);>plfc6Ft*?8rbsA%iU$lGO@GP<~e9$ zTHbvg+UU}9U|#Ju(F@bEFB)t!za(DBi)o$_u3&aDUr|K9xTXwED!Z>MOMa(P8Hn7l zu&TOmDhspQ-M5q}@2XM;B6qB;yTC%My89k5N_=nJh5cH?x(=icldyXS)HXB==KBCM4P)Cfi3ThbO)4WVlCEY8#FNubqArXFYWIR z0n<#ore%kr9ql&rUiCuXY(oabcV>knfDBr)cy|n#{Ep;?IIu8FSem2V&w**8FS}m= zTi-bfEX-b6o3EjX=~(w0XzNSIyT^cOrf;WVf9QS(Z8!cNyg*mmvX9_<t{T13~{=NGfd?EiflXp)-(?owv%l>JwO?;~Rm*EAze9B;( z`R{4J_+xzG*8KgyS2Hp)YBB;D|M&k1n4ZF>d8Te6|9cyr{Z9i^W_S*3|M&HO%}mzF zG|#2Y3eRV)&I`i}m_heuu|}pvuI*yc%A6fuA`H4YC!Eb%l$UxKE5gf!fyr`a@hjZY zO7<>Cq*Wd{H@sRHd{?e$bzb9Pu8GlUEN^-^iO$lTp2TA2&OyM)2t7m8Nr-5y3! zc#kj;*%#g`EPh9kXm#H2X&g|7CdJ`{%Ho%lgo}lN$sr5tX!x+QOzem-=~Wfs64s)8 z%+olo3{6VICzK^GDOCm{CoQb9@F`_sb|!pUnf$KH;WA-ha@NW^2Q0+O!{>piFDqBp z)i7oktj&wiG|@}U<`=r9E9_l`NY^}aW%#-<_^wLP>U_h)s0!Z{1|qk^w}i#-s1mKt zcRY=|%Fv`bd{0^YlA3U}Ffh4qVLb{zP?m{36sEk&D?b+RYgB$>L44t-%95LX%0Q&f z!U}}_%EGKU+^9@`S0o$|1|}_5RvWMo3x$Kgl$Z5~L&`F-E^9Lk%xKs|dxcGJ%;<@* z7Ucm?V^A5I#KSRV$xGtOKqO&djfS5q3$vHu7s`}(jVc3?S60?*U?DaZegjN-*?4$N zStj<@()YAsV|!V7G_^8&B^drV4CRn@Hb%V zJ13Pjs|T|m*5*%WVmcN61#Nk0@~SCln&@v}&+S2WlKwH+X8xDINd5*W^3T8VGJ5#+ zJk3nEvmzN`$NeYG7Ol*gJ#&PS`uacbGexWOJP#wQXTC5HS=h5cSp1GG(dxX&(^#ww zO|pBID2rc`(~~U>OqN<$D|(hG%fyxoQ(onjSBm#JDzCC2xjn0uB{%0P1CccrR$k9q zWns3yXPq+nT?IXP!oXyMm9-IAh~@We0;ardTTi~SOl-5YxdoUzdQ5byu;q`udL`P5e6p5tgPd}Laems1TghwrNF}Mq@`Kba|)OydZyhc4 z@{&qrAacXPs_MC^EX;2A+)}2zt4bM&+_AFm0t>O~o_oNQm(}!CE6c?0Tbhr09stu! zA1Yg4X+s{X@6-VD#FF`Xo&rm?bRD(VpkP zG|`tmFMzG@90e9;udL12(8P4C=MA*=rQrc?cbfV`ow9$7bplPCCreRO^e1*1|fA9GQU!c1up=qK&fIYVt*-84-V4L_< z&o9FZeR=ZxQwH12e^2|xAL9$R<}ZKs@9+Qq_glDL{KvP^8b zFy&QVd8K%tqw*>XlH0plS#oo(G7wo~VdeF%RTgIJd)FzG-&N3?Ck#wBSXmo^g;;*? zCSc0Tw)N&K%fvQYn_Ganqt`^Y3R~XjmA8xc1uE~fAceiVlqEM8Dg%+-7FJR39%W&+ zuXnF9_x^HJ{uV4CSeW$P<#$Yb@L8bF>{GGFggVCp-3z{0G~ z(hT(afoY=6y^X+@cSd>x$}+JQYqJfSn1*_T(AJms_lAIJrd`vr!_bcQnt88!!Ees! ziwFag0V`_|Sct`YW5Cpx#es!c!qOb=eGW_$ecAg0*!s>X8un!GS7@90 z_ug;t1-g3@n6vs!^vAU9p9b5+r+R-GUg*n{H%=LBGye@=%ytl^%riZW*~-u)vu}>FCn)?#2G zmfg1mnDlQfd1+2xwz5oYsinE1Zy7Mnbh)zil{RFh`c4iYt1MY=-)dm$J92@A*&0hT zuWv0dO>}+VI$+B?3;ObuWnvqw&5h8+G{0{XwDqOi`tpHkrkkf_Z-MrXJ~Q8{Ug(=` z$aeLe0zh_JvckSyz|?mX0t>UG3$y*!<^gD8THJRK+WOLx zzG7gS>7i-ZNBa&#+l?OqFXYt~eI?2=v18WeacE*%+IIrl=+aVXn&`=C*kygEpl#-7 z`cA_a`tHkpWxzDkv(vKA8Eg|T?>ldJfiEwI_SHT!zcB3=7mY96noH`H{t0Zz74@A8 zK(1M`%D(Hs)OS<@3$q)RW>w!!V4CRdzFWZ7cUA!lvpd%2U1(xj-FFY#`qG-dYG9h_ z{b|^b`W`^rjXxAG{=bO)&sCDt01LCn*5(svV(ROA3T^)P`_H95Xqsr_Pu~F(A}fZG|^YnvR@l)6Cdk)V|alsAMYE3 zwi|yt%@-f~-WguFH}Byq{8LPaeuUp0H_%VhlSZc_>Gq#36_JvE37?KZdYn)?mqt#I#`$t7p?p4RXv!j|NF&pk$Z681_FRsX zrKz0H8k=*h;i)`wp0#vSIccs&WV+zmUKFj)m;Npg$I^BWvE}?X;j@%dQ5e>NJ(}eM9po@_;ltJxsUG z7BoFhdo^TwVwioAr=)Sd=OdKQb%rJo@smcT=13!HQ+pzjK$^@_S;Ww$A7uPg6O6G&Y}D!_!3M zGi&Ll3D(H;#igB$d}Xc9-y`3cLHACQW>&vUKU~|NqLq0n@=F-b=H#v^(dzu08FTx& zk<5RTfym#K_0PWm`crqL{+y}E>@;zv%>FrPntGX;CUlwyXjcFHH0ATc{srkK_1&yA zq0=Hr7ZXb7?EWRBNqsq|KRZq3ywuRF=wC(}otCFtXA7EEro9|8tuoBH{i{jid@q+! zKCdw}dHriiBh&i+b)-%0Dd^8jQ#o%iHXB*PQ-1#@);gQE_2-jDr_HYI7S`_Q*LiE& zaCV|;d)g}?(@w)&*uRT3&i4ul<@0VsQ`EnQG&1e$-%DC&PZ6Pf-fwIUu!g7N{)4P_ zHkI@jlSZdQF746&!>mR52r*JyEBZ^)RL;kY&2iT7RN8-nwRBS{Yh*g<(w6m~Vy(_+ z`cE^%*?YOaj5Io(b#2dyR_5~l^TObp%UOH1U*`*+#zkcyaw%>7d%-|Oim>Slq}K?g zb7lW^(l}qPB$UrL3{6%4P14A8yZ;txojp~A^7)Rjxyu@!s{8M;*4b3kUridF?z^;) z`X8_s<%h(eTTSz0;@7bGiA(bJKV>cbx{oz7)w#5Rem`qSrEZup5J^)x4;Y(4*6>t%L;pKrVDg?>{0b+{8W<;D zGJO=8yPrfW^F;q=Vet18qSg6}hcVgzRTzkT@Bbz&e#fL}b^gJOxdYrt=AX*YWUBv{ zvgjqr?@TEJk>6IDJkTrj=>-Uz`v&%s*4a}; zD4+Kmn**%jsd(TZYn@Fc1I47#>5xl%bl@;+Q9eS9)YgiDk~Ed`F=KO_H9VCLoM0{8 zRLUBePP(*Z1E*N4^O=Fu%y9Nz9w;M?PG?=)bE1{GeBit=_~vrfULDZ+f~Rp&8Hij; zTh0Y&x{~%P$aKvxR}Ne!jq|-qLiv2d&{PfFB#lhB2X2wp*;7R*pYIr(yR6}V}MHBu(W!U~C3i!&7`9 z##*{5&Kj8#F74>RbJptoa^M9s=-yG*$n?s!eJxs<#|GXAgKi!l7-KEUZ#|3;1Mh@^ z$$MrwSImfxlSZeHuI(q$$~-afSr~ltglKjC;$ch$V%DO3$ip}qJuD1Njxfu)q9R&C8l8^0w#P*)b7}O1 zF!<(D(dvBC!zhcM5(Xk?qNjyL@3nZ>VgOOM&R8j+rOWMA~DF!(N?XmzghFalA( zFc4{uHVTX05s3y^i*k#n(WVSdLeZeI_$B?(kT5Xmva-U;ibgT(WhTGLEe()&vj!s~ z4SM8wG$ssZSMqCd(dwM=Fh--#g@MS+=nG--J4QvT^D9r|wK6mri@s47zhpc*CJap8 zT38>V@04X??}aI^^2#5@`*D>&S&)h7XJ*YEy@42Ir?KpBD};NH?kPW~B+87D2k0P&#K1E+I|o%Q=JDX)5QXhGxa!GScX@ zJl#55(6ln`<&bHWVa^>~O&aHWxrFk0jiJdKTuU06)(@^DZE8=!U|yQad4sXp$QqvV z2RE_S*|cpipENpcc5Sz?cE_O3ThoTK6HVLGUICeQ8s@^mU8HfoS4b$IcN?0b!9Apr zY2V;p(mH#J2<7vBV{?EtJQWWfWUaHQWU!btIvsLpj}9JYEy_oTk=j}@Sdyl4K4xr= zvxcYA!4s^dn@U+D(@B@MZ15Cobv`qAnie1#IIrV6PM&0e9Bt-bsuYFs&i=r zgMQZP+&tLG3}>t%!{9q%VDg?>&J{C;#z~{oN7wd~Xl0%l{45N0fAKIT2fqpfk?(`wgvIZe zWbLdWoqu>5Kb4`$)Zi~=(Myt>r<8%nZ(+?Hl2(%Z0TyO|9W(VWzai%`XPOD=Y(nXr zIW&hf&Q~%CZp zxwgkeD|6}431RTfrJ~jOq=!*9bV?YAoEbVTEPBV~p)%H@eAd%ArwmQXht4ZYUQ#ZM zt3!xfu(B=!3$shaOkWhMaHyEC7@KRX;i+=yI&0~sO4i79!=O z_|TXzFnMcXeHePDEE9V#OnDW}vtr}SPUeq_$QPfKp~=M1XJyInOeh19FBaD1&{t() z_I>D^GUZ*9%0T3Yu;#|3l_Wobh1k^4FJSV^lHZ#G7G}S#%|FmI(Z7!U&%giU8L@xw zWYbJYXA?^2%-9^#IN!@8l+W`FO;&6^X=GX$TR>W8PZptkUSw<*vxcYa*b>${n{r~= zq|s@qOS>YrjI}5)CkEYWnpYA(hs~>8Qf_QDYw6c>StHXLmo_i9mbE&skF8^dv$r6Y zM;e_rxV9TbD|3EqlQ8J!ZLxgTqP*GD*dmM_F+{c!i{4DLQc zBhzk|wkWoTwL0&M?PUhtTf`cf_Pe$RL@RS~?4U5{=8{-3Yf(PrVH}Me76v9qnB`ni z5i22$PRCr^O2bw24~l*LX71CcYa)54;6T#l8o7Ui>^#yMqZQXV_6 zEO|+}Fs{ZBxnN~o1QuqOh)FLp%~yzD!RBi&sWNt*we;(itdZ%4OIsDY$y%Ln$8Ir$ z?yX{tOm|${yP}o3I(APObaPFtnzbn3_b?vC9tZ=Ihs@$vxTVMJU5!XjJhCtLR2Y1h zPqaGMc^HA1Ul@oq#~Ou2?})?#tVOxS(`ZwMCZSkRS^SdzSV$O{bXi$pWkq9{^)l1B zDPuT78l47Q+d!8gZ6t8>D`7>zv_1|lzGFNDSK7!|F~uRM*{%Ftvi_C{I! zlJVG>Ffe&*VSR|bQ<=_e^e?rY-vA7!Zk-X& zVDn6ts5P54JY^2gVJ&@^$r_pFxwKis^I5C&!r=wXpnJ1eBhw<+cClz>&K_PO47xdI zIGeR7FZD213@;M~Cd-+{uW(B%*}EK(R(a&y;nl+6yK+UV^BNB$Z+NXR5LrLGPFVDg zg5f;YqP)S=*r*Im@`pDmi(j&BIA0i;Y__ttC~L5ZO1pS6KXxBGKx+-_tmt3{8rM4=RgaQZigD3``DLSVxBsE6c== z2$Nn_FF^0<$xBL=fyhYDcp7(=p-J`dJ!SDrYKE(YfysRf>(TH7WtrGRValt#@?-J7 zM&&0K#5ep@S#q;a8Hm(bSb<@`vM_5NZd4|}D>57q1|}_5RvWMo3k?T>DKG0E4k^pT zx~$DGFr&jJ+AC~%qgNgf?;|P?T9Ei~j9GKz{5#1UR|X;p3u|=vxw0^OIs8JI^lv12 z*QhcOd1Yn21{Pvt!*75oFB=~oQxN{tQfg z#{{r2`(kNM4u1uviGCmcChY&j<pimzgGXng?iBe14kpd0~7(x=DRED^2LM z2-3xb(m6Z6gfyuy=ftzqRL)Bc&5HOk(&)52-8x&)v@-4GkZF}+&W*1ojq|-+LixPL z(B#F}l18TW@pYt4?J0=orKy}Z7@Li(;VD19iM7tAZSj24=(O3j-NM=(ah>a4+MW}w%;oX(!r+_BS$j3E^94`iqB0P#2V=c;WJ&X_Wcf!ErJ+quEW{ixJMyHRi?I+R7JQ4pa z48D0nv^szBFec+)g@MTT_%~tkJ0@8>YeeTCp2kmQXfhT5r7U_$a`Tij5cw^vxg*j_ zl0U%0?5|^{{^d8~T;@zOA)QSqoij(~kjD8+CZT+uXK1oU=95OIg(C|{>+H!Ql+TNd z&0^N@ls&S9wa%uTk!;fFwA7_tF|v%cC@&`l-D;Xw5b!nr9W$K01tWQ+(P@KgyHT_<=Z|a>2Hm`EB%ie?Z}v2{2xG?xB3p??Z!pc< ziC@6xoi3?xWEX4c*9%!A({7ixXk-s-b>26!mliKRkqcJVMPOleiJ0k&5)}>=^A%%rjWs+~j$CIg z-BigMnQpkWRU znZ>VgOOM&R8j+rOWZ%eBVenl((du01VFX6}!a$^Xq)}M(j>t%WwJ5iE8g0tZBs3CK z7Qdu_BqR(>x~#0QvZ5oH^)l1BX+|PK8l47Q+dG7>K+a zc_A!*$Eav^e&uPrR)!{HBX5+&FBu;h69y)4EvyeC@04X??}aI^qIp(goY~3zQ4#s# zlQJ}!82PL$`JD-6Ao9h+njHD6EX=--d{d^pYf>4A{1DdMgtU_6C$JEk8uDO~v zBhwm}HZQT3wK}g)tYe0=w;+*68l5({wi`t&bADozFzDuOiG0?gyxG&(B8(jgM79!( z-e8)y6Tg7XJ6%#?Vi#-a*9%!A({7ixD6xmNI`2#DWd_|_#2T6QyS4{JD|2z;pfKp> zl0-3UQ9k5h98DY+1|~4o;a^8c}cl2t|kzG0{8ihsgh$I56MY+Y(Xj6tJp+rzw z{F44eNEn!OSy^FaMH86yGSj&!<5`3>It{qCgQAr=o`?y9Z;p#r=Y)qbns_b@L|!Id z2#en_Dq5Xic^a>kp~+a{jk5S9z&xTTfsU5-erJaX={)xzMr zaz(528V@7y*;-*Bvi{jRVbMDZp5?I?y zaqjmaO}~HtKi(B35q&HoB%+^1ghYfzghYg05E2m<5fTv=5fTv=5fTx0K}bYcL`Xzf zL`XzfL`X!~1tB%(Hs_pk&TY;)=iJL8LL%bJ&hxAtkH_PFJdeZQU$5hSyWfuIaaYcN zlJ}{2xpbLj>Rx3n&kbL%F@xT3V6Dv84MyYF8_YoD*4LZNqB|N{EAwrmaYq=EG=04* zEV`umYZEgtxo2TL{CZzlI`)8>e3dCbV)vUxer!QnzCIBaf4M~%h&;8hTE9LM7G^KL zJ{Kn4)&8}W8JN7ZvR(lTv9_|Jo)j9eZPKz6IvTuR8jU*?glZe<1f~y4pql zWI;NZ`i*3dJub=amkr#I=gF>eow1!_#Vqw$!zTv@)-AttCeO-Evo{(#W*lvE9I0p37Vt znW4VC)m27Xls6fT&CJ;DLS&0#sT*|XZHiw`&O01Zg=;5i)vs5OhNoQ)ZKZ2BX=UE) z+CvQW-AdB%w9m2K&sv_VTnCt;zFh69A}z`X4aO1IA!cB5m{|E0^{#5Ak?E*odyKU_ z*SL-|gT7qDTA5E6j9S-8W*~Cfb&6T)j!Uju(xQCEXq**>Bz3NH!s1Knm~q90$ayR4 z0;^-TAWO*OT*Aht%M@Mq2gj4W!}exgBUE!1-k$cT7JvQVP*Ar&Yw^~>$^HYP->Uzcu zL|(X_GfUmk?rJ41$}f$^D`7~|=6WqGy5zm9jTxA{v9jI@>!S;^cf`zZn%3E_G%|f~ zY(KG<=ML9rX3&>ASS#}vgW++xn1P7bg~CLs$e z<_Zf-$0E#BS55DXk{0E-(MSkGl9VecEWRWq3`Eiv)`Tk~EX=;SvclxMCYUj^6Or#$ z)(>DIHtG5aOu8($V-i@H{SxM!PHE=YZ)oc1AJzWffA@Q)xu$jg-&S#+p>1Z7hNgnf z*`!s!UO*b2<~p>6o%2X5^McO##8BTYBn?js9ot2$<+-SHF*DSci#v-*i}DhKvAlCB zGcZ|3EV{xetswV`Sz2kxC7r97LEkE2t<0+pMrr37W+1Yzb1k#f9p#;+q(ynX(bymi zNy<7m3X3k;+F8a7Og33rn}xN#6SFPEq??@5Hgd0=r5%P`(Yccu^sNfk%Dl^9RCexW z1|oYq_b`j@sAR3o`;5kZVMtQdc|cfnNp)uxGcY-5VIAo_BrF{}%uIDveP=akQ9f!k zjtN7On$F|G;!A3TfyfC9tG4r`urNE_c}kdc*QL%{W?*v0$~p@y#OgZF0aGrk6V{bZ z%+6bz7oe%57m2Mbbl0nmNS7VktE}a@q4OFu=*tbPmHE2CXzaYf3`A~q-eeZt(a2hv zZySv}!jPn?^RBSylIG4PW?*v9!g|H zT3D@}&xD29i_Yi5q`TTXTbY5$ODpRYun=qOd<{&#?0sjOuypK=wfPp9A3JsQ9kbPq z)7|Z)Mfro#_#_NTIyyfKi!bRA1|nZ9EKjFPSeSV`-NNL%JitYfAQSjjiW@)EoJ~|G57ypYEAP z&NE0-ty!d@slYv(wCcSA((p9bp)GXJBdyE}-1CW{zFSBdo)$W`i&)EZk$W*S)R&9h zMWjV}iNRRzUdjwimJy4ta7ru4y<(PD8ghwy6*K5tC9IWswZSNLuVDrv>)dOZrS2$q zmy#Cc^+scZFeE8+Zxj|?vejM23`{mzS(}Bm-Hq86V$w}cX&bp$&e9G;u5j;U27Rl7 zwKDHA7?tkb%s^zXdk?edj!M?byw7Ot7ltHN?gPT2ORC*f%)sQJg>}SzNLV^{n3?LT zdUrKxQ9f!kjtN7O8uxKw@g+6FK;(plRqH+}EX+>3PYILmy5z291}0~$th2yEtj>K7 zm~vU2u&%flrEEd^(_TJqlEFF7eZN3HON4Ji? zW45|+T30)1QT|{wJ_$pT4)KIlU{&3{2uyRsvXvrQAti%4I2FVV1TuC)^oe>gYFj z7T9v*9urG^IU^b*fozCh%D%u&n&v5khL-|G#ZP9AxTl! zVqwuG#a%_rz+{PqwY+Pouykx0Gx;i0Ucv4ci@ef;lyt2U7Js=!7>KO4uu8ku2n(}y zU2BC&ca?XQG6R$KR@Me!Ay(G45tw}0)~+&P>DVS~b2Bivcj@RBX7i1vyp7#27kP&T zsp#4%EdFwZFc8^gVO4hR78YiEyY>i^@2V6ABKxeY{lG%3s_OtS`LgP+Dq-o^K}+*U z*CAl)>0x2hmGxcK%)sQRm30hQh}Co*2c}$B11!u=Semt6CxNM>r@Kx8oA12TRVyqV zJ7aC0g(jwTUFV>Umev9DN|%nFpOSq+W9#`vc7rcA<;(1Ty~tNBNJG~(V$Jc;@8oiW zFc7(JVKsK$5Ef>)x^4yH3|cf+g8>cU?JAjbr+a?S#wvDuypL6rTMVyJ}~w4 zfw1LD8}dkerx}pPmaL`g2{7f37GPoa)Y5G2dIn4#ebMzC*nDSuSF5me?4`B&3YwU< zb-jkRT>8GN4VZfRW=i&3Xn*X|^LOHg+-yTWi0`xm^2w5QbbSV<+|dCn%)VHfo-P+K zb=2GCX7>N{@Si(JJix-tXKnhSiD|Ga0B!mk%`J^~1%aujp()t0t}wKncm&))t8G~v zd@l-FVhS|Xm4r50m4c>@rl(*}bY-Be=ij=r@CMpF0ZkqKJ|+8y#@6x4uAiD4c=@Ep z*7ILezVTao!>Rf6_txM4?HBv+4A0-6=|dLI1)Wy>^NN+z zO3k^%vr1|5-z!llJ+Ia@rJglP!_zv?TBZH_PPwP_ALZxu+GYc3Xe#q;ByIkst)4Qa zk!h1-yP34xJu+|kXXM{Rr)~eda^YX;D6`7=K@__f-F*{Crf~93u@)HJ;<7 zRbQ$h4NoT=+FH*^(#m|=bBY-GcQ1Krl}4sBj_q02@?7UR#|-*%9ciz4WIk^+E(imW zi~p?r0(83k&#PBXS2gDb&o!mVf3HEI^n6{@G&V&va#_p~aFOfMbVSFGi^&GVWW>dWsvZKOr{jnR0^jE^2f-YM4K4b!~s|0q9y z&^Dh)LsN(6GilYAI!MFQ7l+p4agkPLug6Uc^<58Xc=9>6e%A6F^aPlpz8v)gNsDsG zV8lFOW?&K_R({2FZ&YbyiaWLm*7BV4B$+{9PO(iGAwBE7Zz*?Tm zyc?OJzP#02Mp~3N8I8@%*zQGSi(;u8bmwh~Urx?D98!gMCu!BMSCEFMT@G!fcQpU~-sP`4#ovYNe6ssAGGK zwLI5&k28b5T*F$KPZ*3^?@4ALa@u=}S?Z2U-dfV4e8y;;6^0~r-gCm@OX`?$#f!*! zE9(NVFuSOj{}%b`^OT)0Yn!X2p{c=pjkM}Z4W!}exgBUE!1-k$cT7JvQVP?-ORww^~>$^HYP- z>V3uxL|%BGGfUmk?rkM4$}f$^D`7~|=6x+Jy5zmLjTxA{v9jI@>!TO5cf`zZn(k{? z8ks&gwx3wbbBFgcGw915td;qT!SHxp%s|BJbu)|Z@UT{9pV9COLz193AS}8h>J2gj zlaPfK^M-|`V-aTZRcfB;ixNAR^Q7meO07I`Jll#;yc6)Ob!z(zoOn(tu!(n zb!?BZmggGZac0n$YgjAu34>AVJIM@0PWw(VOWkqFS4&!y&lruf!jPoScTQM*NgXq; z_z*d7WnBOkW)~GxU8Fl-R{VN$zUq(~eAh^;e!YP-JY9Ea8+|uOEAuViO=76;Hj;*? z+m7uW*7DrsyUPsq#KY>Y?<#tR03$tIsoYO7M9QzGT9sQ%)fBypDpVs|vD?887HnT`W zQ$hD^(yCuCAPrA*9ooX~d8CzjLHB%OsP7h%hNp#&?IPClT-3do8S2Z$-9@BDd5OVT z-o2C=m@Fd}UE!2gkbA`}tu*A4?p4g7ZI~vR3AOMq|G)B&q5?AS}A1y1R-Qm>jgQj&vUqmW~}}rn;)WyPC8p zA2k}sgds^y_iq<9f=dH~P(A3e3#HI`LX}Z5&@p9=h%hbKfTAmxauQ7w(Z(yy=*9}Hv_YGzsa;y6$ zv*?aS*2;X_XxtHoBu(9Sg+-S%cQ-KulY17{!|waS(y<53@j)g4ESa%qhdKwY7Txmn%;yY155|%90on+=5KmT5iq=1E4+R~ip z&Hz(KzjbGUO@CjxofE*q?7Ox31DcplcK?JnS~>|$9sM;W`?to{^FR3;`M>^v(+q$9 zXUU&tDO5cd_-89k-Y-xnJajSUZ`yrk%p!s|6dq?^znGj?I;0Z+D$=T7FCh(2s~y@>{~FTDyw1Ot82NY0 z{iRAH(|X5t18aFM^KWE^`tnwP8EH}8WHdH2W4j-bEsCXX(4Ds_emObsa7Y#YoupO2 zUO^h3b~&__{@tXNd9QyDG1PY}NyF1V$96w!d9LywV21i~wZDqAC?7N!NBoDFfyrTF z^f>zFS#8fQ8tk|0gi%vfPeIU}5%4m~(ohnPb19siS{XJOA(g9(AjF zo}q1Kk%p#%p4p^TzgR#Tp5{8Vg+22~EAxV$`NUA)EhG(33mw}my3If zNQ?3kgR#74DKjuxMl8C*DXk#)idkA|$R$0im_gqvVXe%o4Mu6t8fGA}u4gT?)E(tL zrKCl9z0uep3`xp*HVTU_+1gXa3`{mzS(}Bmy$7=`#H5>?(l&ChoTVLxT+y?W8T73R z*2=ugU{v<(W(FdAd-gDk?x!>FlA505!s1J6gn`Hj3#+#0q_8kM-E&Hqbl0VxT4rE!#>zSiEX3-1 z&H+;{s}t6h9?Z^Ln-`#|qZf&-EDY4EjYyXr+pDbQxuNG8Gw90=td;q?!D#Hc!3;!h z_1t6@-O-+$xAEi6|fL%>v;`KzU+NZo3M23jkWm} zm>+v|^c}O+jnf0|q(%9I(fA|`NjiEy3yUx55C$S&EG$otOIVnBd)&h0yF9``#Ajvs zfrVJGCjd;oEZP$kmX3ui%~($un0gu!wp>Zc%s`ag$&ol<@?HX1h^2axz?9!h0SmLV zr8&`)0j7?A>&XIJ?wkM?X5WQ5Cm_un`vFZ%CwqQEn=j3McM_U9`fEz|Z;h?zf7Ba) z|Nax47WlWEoo8s9S)`$>emZM!_!=cwlFY{v@$OU%qNEWZXs!STIkp=VlB@_ zfyK;FUoH+5krw4824i_(DKjuxMl8C*DXk#)idkA|$R&YQ%%E?TuvX^P2BS2vh8c*g z3#?_9x}!W$N?MfH8;uRZkfbcIQCM`z)<79EFxg~fZ5Gz{0A^c=NjEvAZRB1#OFIm? zBCwMg^sNfk%Dl^9R0ei41ChOfJz1CxUm){(#= zVd>amW~!^|1J$HO`KZx2CJaex0>_2Lm(&OYkrNhHZQ!J^FgqPMB}}^OQlOR@n4Gb) z&H@Xuy1+SL%4K!Jx)Q+bytR1&nmT%s*mR*&x=ilXvvk#v8v@suLEma%t<2XAMq}Ux zGZ48IxXCQKqmi{T-!>X|gds^&;I6RflIB1YGcdVlVLc4o7nY7aU?yK>%8%InW|1FT zke0v`Veyw+gn`IY3#&EoOjww`2s{@i-PImwWdM|+ zEI+Ui3kCwf`L62Q)FA4E%&PUz%Gr2~8dS1?)M!$j;H<8e7l*&>QMs zfO_-mrw6C8G=pX8&SEXk1--MGLGKr^R_3_|qp)`#GZ0zOJD*u}Mi z-o?VAONx7on1RU>3u}4rQeo-XGG_8sro4jPFBW;F1u5xWB`p4Oi7*gZZDE!6t`Qby z>w4D;lkO_-EoBBK>#eK}z(TC7cOx+QvaP*k!qTx#*5+nlZtvC6EzIT{O?ex;UoP?v z3sTX$Q&{}v3Sl6!%fhPc-7PH4_V(@(Cf`*l3`F)>S^I&7SXJ)1Jq}E{tOi(^ov<`(drtyWM^E>j0yf`yskc^G zI(Ej|JPS=s>w3>Y8!fE^=9OL@JwGM;g2vYKi|htpY|59({h7gfk*`{ihTdz!QeVz} zw?P<)T(__qdv6E}vs=A4g~@j{3ImbbR@NP0A=cD;7npomb8nNdbnKp``LOpsF!l6- zu;oe{@<@EA8IZ@8tflt}Fy)RGU}5&u(roR02234&(fb_Od}n)atFUzJrM3AAnwYlr zzJ|73`o6afn0oqVO7>f5f9%!scjAWJY(qYX@3aH*$&z*SerD#JApc&DbN~ypFP5gK z*9A-+_4c}fO@CjxogQFe=Cd~a(8M&@8-TW48tn}NQ%^%vuw%VpXgl!;xPeyNvN-r& z6tct=XsR~}ZL}%{O&v{7!Jg>NKwHnh^=8G5{}+_Mj~ttTrjCA}lKn$t>-c2vPt6Vf z8~@+slNwvke@*$uZ|x1I=1=}s{%?QaG$WY*$?~UJ3RTYq!P!ca_X`wC&vP|RVQ`+( z@U$Q}UupC26e^US7iybDq@k%OxR|v0mx_Z$N+Z(}hjw{zDQQt&rWoq0y7LOfFDB=e z4yh!#inQw2OGv}hYKOKoxQ4VcuM4gvM*iLMV5!o`wBE7Zz*?Tmf*YBkzPvS9Mp~3N z8I8@%*d9b=i(;u8bmwh~Urx?D98yJaCu!BMSCEFMT@Gz!a5rgX-W%LQ4E5bg((ts; zvE9#Fo~wcfn4!L09jqcP$_EX`k>DX_U~-sP`4#oSYNe6ssAGGKwLI4Zk28b5T*F$K zPZ*5a;7Mj6ayod5S?Z2U!CKOye8y;;6^0~r!E?gmOX`?$C5Xs*E9(NVFuSOj>LT6w zvf|g1^Hqn`5WGfO_3I6!;pw_V+Zen-TA6PJZxTa&w~;hF-F9s6u$Jeh;9X{@FEgXTU&i}i=Pu;4XXK0&Qq@k&xZ#HSwFBXu7r@0PoVc$H` z%DkX&J~7mH3rWM%LdSLyYk4l}Tg(jg<>I~~(xSY?U@Y%j$_z}F5sR*HN-M~{VwP4K za!KDRX3)1vSS#~tgHhVIh8c*g>s!k#bw_z$DQQt&Z!|UtLz1$-jl!Z!w)T}V1Cvcw z)@EUC@55{hG3h3!w2j;=XK9BaSM=><27Rl7wKDHA7?pjynSsdOzCFyMJ1SW#^FE`o zUl@{9^&JovT~ggw#SBaiT3AQ=4hc)g4l`3-Ro_=lT9l6(jbp-)q^9qV$Qr53}>u<^^c#=tW{H3q$p4 zBhqEZ_9|<6Zs@zl4Ek~dYh}J}FdF-AFawcWeK(m!cQmqA=G#W&jxZ!?>bol}x}>?U zi5ZyOv#=ia-4~XQJzyqZWy+7({brFLTacE%C&J<{w+I7~rxsRg-!oxh_M-2(FzK%L zzE);n^3uwB1uVqc`d$N*FMHqDCM+F$V{N_#=EpuAeaCEd_>i2}v`@ zen1n`$-bY^=1X(morI>2{+g2gTVw0_AN5B5?>`}Rxq6br%c;c1~`yNIChSvM#iiS?Z4RP$_9qUT-uu2t$&x&_-d=C0j#f z%)n%mm9<$|+e4UbAtv4Al(vz3W?*v0$~p@y#OgxlfGL;N3F}G-v-8&G1!(H%MPk#1 zPU$kaSI^Q_Lv9FNV+MVzfweMUHyDkf8_YoDR_G?P=#EC#%6!{s+!2N(O`*HOqDz`X zP0YaLo`v-=bYECH_JEmul_@`B_nSq2Y(ZK=PlUx^ZV?6|Pc5w0&@*9S_9FCLm~>Zr zsFfL*ytJ}j0SmFV&}(4wW$#06!qTxf*5+Gaehlg8J7%jJr}ej!7Ud5{%?wPAT3N?{g;-7habU`2 zHNe8`gr!;Ae-fBFdbp^E`8tM224GDGbQ^iv_JOi`8#n#ZnhyG z*mq`z+X4Ax$vXN!1C#E^z0d(H%)VHfo_-fFb=2GM2DaSk0TyOHYts)+OoROaXv?M1 z{va^*G&BV})*ptp6OVu!XtgbigYQKlOH6^L`jf(*6PDl2u@p3QG(81-qCW#|J^$99 zg*W(bGq-yJnmYP@O7;(pt>csZKQ%Y-@=1-Y=f9?W@G224S|JxLu7MvC?|J%T{&9U9VTAnMyJDEXW zu3)Xqy9`EUcsDZ;*&E)&EV`qTwKDHB8vBJINmclOu;`NNa1}E!IcQ-W2_F)cjvZ#E zx~e{0ODU8i@>Qn%h}~}%`LP9Q2|p1Q zf4M~%h&;8hTEowTh1rYnb79h5?cr8tVDi$+dIc=R+QP4a$(Owkw+Tzf-dLM&f%!44 zqwkolZk#sIPFj>d7>!TDkfbC0Sy+5YhcFQNVqtm0E@5Hj4ZDTOcX@t(EE*09OUFW%W-J^Ark+NGO;=7Ih%y6{xRsRv7GkMz5}0yX3Rsw>EzOB=2ADef zEu00m+&LkvnFE-8w>E!36Vu7?PiXU{xmATetL9Tn5P+z?JU;vTre=38T73J*2+BBU=$9_V+JA%2Ie!1?kHrf%nOaiB4J2U zG_Y7$bV>0*5i>AZVqq;GSSl+t|tAxd0E)fPIt1Yb3fi=Ry zY~8?GVbWdY1EtKsWWANO0a%EY4QvD^U$%9iOjtU$$=ciu%Veb_$EXTpJI(E>~ zJTh6ZvlEtP?Z8Q3>gef#Q^4jsFAdZR zOUKSwn`fbkY2Cm%XrrZdz`Qb`qvxk&U(nckev#cEizD^41^KekxGD@u8V0Tji!W&q z1|rujtj2*G!ouvK%dtx91Z9V@skcBtU?g?n>=yzbxi6A>ie`stSpB(t9xgnS5 zzCWq4_59bAZ~WHYaBBY0TmSd>zyJA*UxfZFG|f=jnbB!1%`)VI$ZTfhzn=SA0c&NR zYcL8U^O%9ig2;Sk(H(`Xm3g7jSR@QdiXw}JMVAyuikN}P5({g2WT~)pY#B58DpOv; z?iY)^(t?ykRtby0Tp|oaR$Ex5ku}1?Y+YonFzK%HNGUTgS#M=+02X3pk&VFQ%eF?! zgr#Gftj*29+#b=rz59;&39gk)Cx<-&RCmgp^0f-on}BDTe6nO6JW|6Ex^L;sioN(c?L`!eGz#M zY`(KS(kd(+dueUHf+nVIk=M|cOW#M@fT^c%rewc`_Q!~xzY{m;=4pfN%)sP>mGuc& zh;>9h15+;R02XFnEKN_u1xy|FM%=)bJ3YX{%x7)-p^0fQ5`eZ`8jS>jsi&bS*s(|$ z+D<$IZt&I92cyE$vADIFfF`D?ND|s;X$qP;nx29^5y?PX&%Z^o@CMpF0nC|$I{JM| z_79D%J9RrhvykaW0o)^ zDHxnhtU1wXA{SVZxfWL8;5=brwqS6+FxB5cZfBt|5LswtEdmx|MT3ih$(I!m770to zmROq02bTguCyU5#CM7TS!u~i23G-7?kE8kW~(jD(!n*r)X{Z=Yk|#omJgN+ zOUKq*n;W2sY1!aLXv?Kr2g`t|r<y{^ zaqtE(b@bNYO=kbUDF3;0q!Cz{-L^LGKoirZ!Mo6=ztP;%=D{Xl>gl~H*bfKqL)(cz z05{NTTlNTiuNkt(Q=lz_PoRxfwLnuxpH9JU9ef6DJ%2Iy9Nv(-+Xq{Lsi!ZeWWUnb zI^H(;T5|&}e?Qm;Z72R_$~WF>ZhRbcYTkic=x4BHAHet8A^S81+A;VU+Gte=GjZeu=Xlxx%4JI`=`0xLJm!~wgo~NgHV`4C)x#84&8_a5M;h$qdW9#|% zDc|^^y`gU=2Y+gB>3)()?G2~q*Z*I)emmT9?*9C}`S<_xoBel2^zYC2_rJ6Lk^HG3 zI{P2}>lOSX>S->Zh0%HcC_OKT&i~i^{chnuqMjB)x=5kwxhT3=Y5sn>I9l|N^79f+ zvpl*~X=GaVug$-LPAmR-#mZ@==3Ek8r8N2Pl_->+S8JNm=o+QrXHnYa8i@^7Nkwtrr^a@wIeS44LzP5yfo z3Z>^=nx-7YYwBhwkj_AG08 zu8W>y27S4Xv{#}spEnv8gn`J#e^!10I$i$f)hnl~nsY<+n$qOI*Pu{(zOHE+qc@a> zr(4mRN}GSDQK9sFTie_r4NXnayQIy()EsS68kz1nv=5{ANsICW#ZX_>ogXQFGdVwY zNG;JPq*cG(LK>c)I<&3PXQY++Mf5o_^6$1sTa`wpmyYc#*7DpIea#H@<@eDx(xUvv zXuM^{$0#E26zlJXX|eWyl%GFnn@^;nsU!NCwCYP8q~Ym{L+gpUNGr29>L!Nzu7@-{ z`5aq6Yk3Yv1I$ogjz)u|MLA?JV$m=&Fo_T=zhZhUsx&gi9oqzJc}_)>%%Cr)SSxed zU`#|a%s}K@G|McyV}i6ZV={j?8b5>~$z=4Wu+$~FmnVgR$S-EiiE%4Oegg}$KY8=- zzx-nPW%<(#NM|WjJr~4gD^30@1q!9-xtgXhHcx4IS`eGBwE1@m6-v(wwap^Z&{Py# zOxpZQ#jzr#k!guTyF9j(v?woA4E0srd4=K^lk-Z4R1#Z7TJ`HCq~U3`Lt7eKLt2^F z#nuud|89A#RB2>d@7Qi&Ezf1Kjm%JA-Wn?-Ey|mW#%5-0k0G)}vD6K^^ESmVC+8gw zsUo(MwCdL@NW;@Ehqf}do3t|TjqM?Z`fep@c-rUK?q@B}Rj~uiP+zW&Rgo6ug9hVB z><}|BIZUkliuzc!(#Ukwu|39Go@-*qnL%H!VXe$33`TA2Br^~>9XrJ=b;qSxEoo6c zV>HeRLz24KIbrc7b2%aAg#=|VmFDQzS~F|o^Cs~cUa4FQ|vA?)R&uMO{7Knp22t+yUz?v9uSMJa7vHJ zy=Imk8*)qR2{Y(hEv%LKsljNCJ!1wUFJjM`rS52twUQR)mqz22FeGVh0dy~Mz?3cCq8=5-$ zCvX4#_kTRUGk=-^=`4k+=YsfbrOAJ#K%w+JSJM>6=P3O5&?XtA4$NG(4?#XiMX3 zNGtQY_*!D*-z|@qDveC*9or48<+&`rks0dCTjOPoDKPx~C({jBA=Dt>?&>dV#fD$=5S z&|n;iA7Tb3hl!P6Q6H~X8kvqdw#Qh@b4~m>Gw91Ttd;qM!KjU&WCkLqRtrfEa%N+Z(;$MzFzdG3gRW(Iw^gS9e$F&Lh>iy4S`<8Efr z9Uj)o>@ymEVMr2;2ZTkJMB_nbU=p&hV)3xBbS%P5b=CBtC}~lS8;yi8BuT}S!s1I( z!ayW#VNJv{!ouuZJS$ATYl0awhY{f4HF z{!#6}e*s8L8~V4Eoo8s9S)`$ZQ;;7(#pJGXg)F2cMD0w(?Z8~ z5o>ua8d}T@_2uHBBGRI~#9%BRTFMMemJy4ta7ru4y<(PD8gj|dDrV5PN?0rNYJ*Wa zw1ydotQ%U(EOkfuP$_9qUT-uu2t$&xp^d_#OSTS`F$0rLR@P==Z6CsH3o+>?r?idS zD`#nkAy*9TWCne!g0(X5G8mOZyP1K=-l09rqB|;CEAu|1v0oUHR1F;v7F|+3RK*NT z4q8}8h7Ji!#||@7T~$9+Os7P7j?DCf#*u zsFoR+oUyXb0t>Oap>x2L%j$%6WeBtL*5(Ch>gYvc(}npoJyEZCxpbLj>Rx3n&kaM@ zm_hG1uvX^l2BUH41~U-3HFT3%bVnm=Wxj1R?g&GYrlGsSqDz{GnwWvfJqzpM(0yU) z*aK$rRi^xi-ES88u?1-vdLk_Ta*Hq!d1_&`4m}eVW-o@G3zP0@A8KU=CNHh5SHME7 zZRj;H`Lg#zZNk#AH`eA`V169Z(Ra+|8%_BGxj!?}F7hV}(lPW|SnA8U?{)|SkuMgO zXUHWi%)CQxVe(xbVIbnOvi!h8EI1SZCSMjE3JOcdLY8K1C=5(JjR;$=v>|cvohTp) zOO_f+GILIXe=kQ;z``tTX-*7ffT^S3hO)q>zpvcR31DIN-P-&CO-v_;enJ~9orI>2 z{+g2gTVw0_pZtydUw^=9Mk4>S98&(yCvtAPrBu9NNmnZqmxUH?fBp>bsSs;c1^^yPvf@S0xTG zLw&hAQAJvm4;qXki9^i5!;mGT%zvB!>EKBWZZL?bzO7EzeDfyUb8uZca3j7Ug>e<6+`H zGcb8TEV{xeJtFs-S$b^9Er}=0pl`LXR_3P$qc!o28Hl_{JZF}=qdn0|T9jWJjaR~u zq%HAUSaiwzL>n_Od1Gb071qZDX77lZ-!yHwU1?aZpS3BF#9FU zIm6P-vER_t(Lbu4|9Ahex>Y^T&^EJ3LsP-+j_o4W@?12$m>KHJ#luCUMR|$ASU$Xz8JH|17G2?#R*-weEUh%;lHpa%pl_A1 zR_4_PqjY!;GZ0xfyp~z&j`HDB(xSZHXlxLMBxS=Jg+-Ta9WG-ACY!9R&BEF~jM)}q z(oIfj8@X4`(hfte7~aVY`c?&NW!_~lDu;J71ChPMdzeLcRI*m)eMV!yFeIrOJ|HZ* zq(X#7GcY-0Wt{~UVs*pkfGL;N3G2!*X6LQV3((Zji^NtIChOHkq|1)&Ro3#{ zFno;}^yLQD%6#2mG!EZj1|qkHZ!(MSXk@L-w~fXfVMx+6d{N%L?MGcdVlVLcqa zFDxB_I|icSUUE`+I$PlkHb3pj@jzQ>B)A|qWr;Vd=iEv9mAi6#g}vl1CcKl zmS@-{EX=&aZej9W9$_Hjv$FiaLM%8O0484+9S#ah$3m87Y&Z-|J&g!kuB2pUGRp4c zNE|SEF99sXQo~7L%I~Fsg<0CtoEXjkQ%AoIXMrtuP5=wD@4}pulxB|ofF`Ds!#|W#mD|4B_t{#(w@GqlYt($G|poK0Hw>jk9YX|6+Cn4Cvi znHMDI6GMHskTg6kbZi%~mgl16VrHl>7blBIi}DhKu{^ny8JH|17G2?#R*-weEUh%; zlH@98(6>rhEAwiDQJP%C3`Eu?*D_1pQJyR%Ez0YS#s* zc~V%Iolc$-Cf#)@S<4Je&RAJzfrVII@*FVbvN~a1Nn&>1+PnZw9lc0wy3i?ICim)D zx@yP`$!pA@Z#A%1=IaKdF?oX-h}=rvWES1g$Xc0i8;v`{kfbSjS6FmObFzsUnB23l z9wzS#OUE8Cldm%6N9=yH$d4^ZOY(`Z_{%NAK;)@~)tY=JEX-acp9_=jYEQN@1Cy6l z)+=Bk)|Pw?Oup=WvQ1bz_Qu+L3(Sv69eu}ab>p;=cG9B!!DxIEh9n)y&%)wMI)s79 z7YoaibO{SHZ_+JHzRM#FM0{43A6SS5lL27zWzl3%SUMK6G-JsyF!eMdY`Sv#NR%0v z#I39Zun=H}4fQWTBl-2yQ`1KO4uu4bP2n(}yBWs08ca@KnG6R$KR@Me!AyziB5tw}0){!z{>DVS~ zb2BivkLc(YX7i1vyp7#27kP&TsTkQQEdFwZFc8^gVO5Uo78YiENA?Jl@2V6ABKxeY z{lG%3YUBVg`LgPfDq-o^K}++<$RS|r>0x2hmGvXl%)sQRm30hQh}Dc72c}$B11!u= zSemsXCxNM>r$khCGYZ|!= zOunpnq)AvhcF)p$IC3ADdip@va-|J^GV%nNaz_iWFnelgwvIdlrjEWC zc@Av8vwfshSUUF7+I$5~Oxs3YLt8F=Khg$FJ$*AJ`z^FTj_CP2aYJslAs@td+5!1w z$vQ?pGjmRge=kQmfQ8u?OVcyr0;Z07N8G@szpva*53n%vS(|=nVj3I?KwB=2js$_J zr=cm>v5_#eop=P?K&x$89DFYdSz-z_HIjrjT9tyPj;5zzPmE-st>@oHvf{@7OUd6y zj!i&QN54d z@7Qi&Ezf1Cjm%JA-kK^SEy|mW#%5-0Pa(2JvD6K^^ESmVC+8gwsUo$LwCdL@NW;@E zhqf}co3t|TP3<9u`fep@c-rUK?q@B}RjC8aP+zW2Rgo6ug9hVB>JT$9IZUkliuzQw z(#Ukwu|39Go@-LanL%H!VXe$33`TA0Br^~>ojS!Vb;qStEoo6cV>HeRLz24GIbrc7 zbT_dgf^#;=LblstCOx+-@%(qfEiJ`vR zNE)7QJGOUN%X3reE;H1Zn^R4sMfsk=c$m7+3``yni>`1=kI21dmL3~&OX>+T=vytU zmHDZ`XiYt11|ly~&zYs}Xiv407Uh>l1SVaU+c60&%zg=T&ZsnV>^C%Z^p9%i|J^^TZdK1Sw9PEi z&{Qxwo3!c|3rNG$T!*%BbRKDCUNAbJ80x!)q~U3yW4nm8JQs~FW`_E5@n{igQC?y& zmX9uF1}4jhMOQeb735wqODhezWONlX=vyVMm3g(nC>>qH3`EwAu4R_GqkOcKv?#AP z8XJTmN!jQ|VbLX9N6VOj$tEjnv#_?0Vzz~tbdyusM(&lfw8M}qMt3rUzE#0mnRgkC z%F*4-KxFUe9%j)Um8_L{pV8Pa3`wd+4+x7csUEFj1||nBtRtg`gr#GLnW?U-AFU=W z%14dHF=0qjGkRQDd`XQk5IJFC)sCJN7G|eMPYILmx-?qL3{1{gS!aQTSl#G3V9I56 z!n!hw*?DX80yK5>BC(Z)>3X#h>9S*cm9;!Kj9y~~eYt_PGG8|sjiWc1fyk}Vo6Mp+ z8d)pzZKH8V7?L!N-W3*I(mdM43{37>SPw_<3roiyFq5w`G5TDXbXWUmD>E>8X=S|v7GiCquYt*zy&r88mX5u#Hs1pCZDD#IX=PrJo=*(*-9pmvw9v6##9E$<(uGQf6SXj97GqQ(8gp6|=O`kW135m_gqvVXe%o4Mu5t4Kol~mtM;(bw_!+ zl(Z1|oaYdzeLcRI*m)eMV!yFeIr;9}pH@Qk|}11||nBtRv||!qTzB%v4v^ zr>jYe@=>F4Oc;{Xq>l@WFR2j*A}1`Y+Vn|bVRkxwN|9sIgTB?kTA8mKjK=g0W*~AaeUn*q zMk$x^rx~o0i$_z|iT3N4vg;-nqH8ADU`<^DQtxrgiik zv(=5$#@b1X@&}{wNf?rJq(2LbFX<2lB3~>lPue9c%)Dv0F!?TzFc9%sS$<$47EA|# z$(KdbL1F1w$kL3Z!@$(jh_LC(>0?o5U=p{o62L+%l}-XvE=vImv$Ul-kt3)pkUke#EyHMXArp*Qk>0m@7pQ`U<# z!?B&kTAmBWW;27nRlr)A=NgQ{v3bluWWm^cX3-smtd)78(O4u5Ns7i63yUr(9xGx7 zCQB@=mcn{PDbZR~!z$U7`Z#n?_^@s}%v zfygckt8#3&urS*@wnvzJSEVoz*=J?#2Nq&gV+VlAmsO8d2}{QgTAD}34gph74-1>F ztRJgp1|~9k zI|psFv<{e8#&q=jl0aHg`j6DZ7-`PIaDl8p)X>GoOCZ=s;uc0lMz8`A? zrk=i;lKmFiAIJ3kowy-4+mH|JJ2NxwfPAuK9b=z?Nq6L4=l~XGUo1_}mK$_f zTkiA#3p1a!>4zq!!Lb0e<)a|N5sn&&a4hp?aQ08k!0+vq`JoD8?we zT4rE!#>zSiEX3+E=YT1f)d}lL2D9_l<^^c#=tW}Fg-+=*xmVB9RYPvbTw?}(tAVvL zUpE+ynH$VNGfm9Ee3dCb zV)vUxer!QnGEaoXUv3cwB2O)>*32_uVfG^PT$prMd#05cn7p*IUI7cSw#;i_@@4Nc zZNk#AH`eA`V1CT#=sRYs8>fx8lNRL zT^?Z|;_EXi)Mnt(y@@G8Owx$sizTP)0NZ5qs+i0Ze=Bag;*++1g2b; z0v2XzOLHQV0j7?A%VdEqcTNav<~U~Gt<4|M#B?(A6WV-fZq+0-b@Ugo=ZqseM}KQ< zJ^w>*{QaxX#I($`@qg< z&}b|Yh9pJfi-kp(6pt4%1Cu2d*7EVC!qTy2%;c*~c?G*)Eb>YVQZl|uSp4M@VIZ>F z!YUnKBP`6;jjt6Z-Bmtb$_z}_TUi@`g;?46Mqu(~TgS_UrDL0{&CS5vKCYu%n9Vnu z@-}wAT;v@Vq+)!hu=vXr!a!t~g;hDeTUeOw9p58NzN=Cgi0ren_5%yCs__HB?2NT}7MhsWjh}-yT3QFpE8{wPeoFQQjjiVw*$uKdTTfe%FB^@k!jPn4 z{F<=%k_KTQa^1pe9KRtf%x;a}6ei!*C=5hyTUmF2g;>-0U10KM&ErkN(y@D%=EL#( zz|_+R!j>y-$RqKcWHG0EVCw0cDcNtK{c&8+--#P^^Ym;xGcfsJWqkq`Vjbh3fhm`D01LA( zmZoRi1xy|Fj=O;^cY1(@na|qvLle{BcmUdRX>>dYOg#-v!H$iGq3y&Y;09XF+01NI z+|02!r08}6nwX}>lh8)rO+iyf(^Ie~#xu~?^Kau>cmwU8fToUq2lkvSvUBu@#@6x4 z@t>L-a(V9ilNwvke@*$uZ|x1I<`2E4{{1hT|5>I_Ok-&V%ha94TAmBCvzbBf7qC|5 zxdx*!JC7NNEXdAh7TrMk%vi1WDv8wC=VDe?v*(zb_*g;G4NcIpg_4Kf?>B{Yo?4o%*=NAi(HGh0 zz~(#Kv#r9?v6t57D`;ZcmVFIvx%7Ru4VZfRW=i&3Xn)M=`8#ogZl3mEJ2No(U}b#* z7GfRQ&%l(+I)H`Q7faKVbpcaHy;(P~mqxQeVCrdT3U(|T zhPD%rfE#@E^#7v5(y_R;nSdsyscaJ3XlV+XI+~t>J(0~oThG5`v+xGmJps&_|LN%W zDcL_XwvJC`e`;>X<++WM8e7kQ!5ee_!#8sLxAulp^M~L1_ZPtb`J3N={O93$1~Fz% zOcQyQ1u6J%wy@Nfa^Ecw1|oAUtiu212@A6Y|IHUB-&H6KL>5|Ei-3h#(SM79$(I%X zS0pSQTViQ0|8FTU^>mrACKNRdu0r2(m?EY;zUI4I(X zh^b3u0!f(Akc=VV$XXqN($r8JEu|@?cBIrzUFt^5x>=XCL0x}YALA1(>ysC2-O-op zllAcllmC;1HNQLed=AY0p6{8tqp;6*U*z=~&V1hIbI$qRbI-l^+;eZj$*Wnn8tI~w z1&mWq7v$t#$hw!D)bneV5^Bs&$YP})A48TpWd4)O7^fPCpKO;du8 zJi@wnp49X0IhVLkTOw1={Yoiy3!IQ0N~hFzPVOeo@d;XAiqtSJo;~EyS$A>| z`}+gy{wa`^(XhSZZ*=_$$G}Ar~7koKYsE6>(0aaTOgYaprMPWy%3fgVYi8L?Inb7qFSBkgsutF% zqp#%PZaeuZ>(=wvPrjyWyAtEla?bc&Y1ICGf+okEn3$GB)#SvawA?f8xYMZp`xI@?R9lW+Vm}8#F5_eqC|l$m(vTfIu;Vgk_1PtO>?Ek zp!>c!&F`~)Uz$Pr6U%J5>9zZ9IaJ-4Avcg%VarwZt%;R3M|!&fTMkvLGUl!(xl|V> z)(}T}%fUpUEtk`GW^oiH))EI#?y|YgL=jB{({fa`K4We%$)!4!C?yVi%OR4h>P=Z3 z;Y2xcaOCbp1#zXv@n9ls%jI-cR!6nsP)Q`QO>xmkBE+#X!IABbT=y|9p5343Opi$S zeMg!Y)s|b%{N;Tvb1kc-ZDhZ@12tL)D`hbN7;5s_PT` zh$Fq_SfbvR%jx}D9FHds5C=~lv$^b1WKsuhL;@}8WV?! zgCkETo+7UFIGPiUwp>m>lhtuVaj2vz@vP#qM{+FDL>xSM&XMb=;(9T`v*&HjGcg%m z&1pHRdLd)(OC*=-mc+}%VQ;yGuH6o*PW67MT68cB!Z;K&CK zT#3Yoii>AmiB82y<4O?6m@bZVJ970hE{-J={fyHdSt^bs(tSY z(%olP0J_p+P5(Yxn={syV^^-Oakkv_8eO&=swQN}b$3m)<*Ise*Cd-Gy92}Y3HHWy;x|^ zp_0O`HHym~NwBMsICyfW16NVkTE(SfcM)fLRMD=WEtk{lvpR|uhe|?SrHYG25>gx- z+2p_#?kZPYJiEKALUG#Tdax@@96YIV*|9E)^qW1MPa5yiE$i)Y&%JMUwiI(om& zofcttG(AUAJ2K|(BDqx8bnPY%d&@N>SJe+?anyC~Ar6i_()BQL+2g1qxvG9Nt7EU? zP)U8)KE-8^B-T|=96Z_Y!1Z|70mY?bj}a%0Dw{q?%EuIa$N_2SdO~s0mKziYN1k-x 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

        !l6&f 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%0A5_hkKNsdrUS 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�Jd{T%ghp-SI22>*ZA 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≪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%0A!*Ztx%fj!TB%zHH#+$% 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:-4H3+P}=NI$wh0H@o|6F7~9prI2h!R!81 zS`N~1M>r0GUwu}BpWGr4{B>VP@UbiGPw;6MZv`d)c=jX>0pMvW?Sy3tyYuDX#(qQ}JDT8gvR|Xrw_;oa1-m3pfth75d&9g@z82gyqxc<`4&hqox3$$tfBA!5Se z3^Vq~}80K$tP4upxI*laiIdJzJ5a3oic z5x5wqufG?w>1Eo_v$lckMq60ADd0cny(fHw7H(ko+=n%b#X%*I4B? z=I;RUl)>#0=t%m&P=A_8GCPRo?Hxe#I?hb<1Sfq_0z-pFAC!zQ=4~gRh!ajRZwGQg z)GK-W`x6|tTlSRgT&<@p+Db$|_%&t~UYQ4URZ>S;*wC17CoCXh?Z86OC_Fn+KY?8x zBOukO=4v{ntb#d?Z4jy{Asvj)Xuy7dv;dY!%wA$PeI|{x2>V6JOAZD!tzHQOeC~i& zQTHYcuYY1f_rgDUm+0JTo(JwPfm$?9Iyv}{c=o-N7-`Gb~| zxM)?3T98CXCT7PI<8v9(O~ zz-KS~$Y!-nEtYo|*1ZCrUK{p3KM})D%F-mGgN`Z{VMY-dLUuxD@W%R6)hK?t)2bGK z9_U-NbRjnEt5OB|TZ9W5d_H>z{N|PbVzV(*Bvt(ZI=NI8~$eCk2VTt`loLk=sn%*&-zB)+^U zMtxz@uB*E0HqUaP3qd+ebA;ENje@5=$9BSSgpH6tpi>D+!fnOr@_~4?0OeudMwM zq=BN#aMC%Q6)S9ra+*0>*`ks6SgMy(0~s7x)0F)!LlUa zT%fyLDF4sKF(Gusg4nBppe(?F&`R32%{55A;!7bxks*qX%Me9*`^UF8L7)IJ87_?( zMSvElGhd{@6<3CE#RXb;e7%fh)Go+LAe3HozC)O9+5$LjBvHPYbezdy`^D;1x=ezIdI3h? z0V(kulJ$=8;$T*jtv>-~sfu4Y5oCluS8N7lWQj9Zu@%|qrsy+eWs##+d9%dn^$!Il zFG4REBI7aAg&_`cn#Hg5mN*w0=@no!_$_pY8w1ru<^Y8WwOx(cL_Pl6D*nB3Li7v> z7b4rjdPH`Jfi+Tq_0O~9_yo08@wu>JK}Ca>v5WewN;@4QDJR>Gd<(?L;h^X33$~4K zXKn)+I2ox@3A_rhF%1^LXZ(J2aS8Z4!|FD{&9zbQ%Q#gC4ICn8XY_U;_qV!@gk7d% zk<^#b2C{>*Q*XrPrv{KbNz(WH$mD7qNrSw&NZC|+x*2fd8pZVo%BD12YVl}9OL6;? z0loDBDu|*CA|bycK&g){(vO!I9i@@Zb!mEO<_mwiM^-3ta&AE(X9B5V~M;8Vq0_2o1nhEP(3oC2$vk1F*npqwgO5Jf(a~ zhJjvln|w*@?Oa55p!6zU4`HkeE%lE_k;vw(;xx=$1c`Y!El*u)&KBOt{EAUtBDU#04%~ zDUtRg2xcy@AzYLppEBje;l;9xKp`2kOee{;@ zWPYrrr{D9bo$17fR*9i}`<2P%JrjI|8j`$*pZs(A1`Q%eWM zEqG8iwVu+Xh-Yz_b_diNTxaPXH6JQ1!4gAJUl_UUvJVX@e5>@}gu)y*GHCpOAT zKKEMvqigu)O#?RTL4AR^+C(iQr$ z-14mhm~Uaq>JXi-3yCHqu7Hrm5%>jyF-l>#?n3DQEe1c=8RN<64uXV5} z<`JCNjuQi5Ca;fNt+53gI%zmN@iDygZP(?S*?WNo+3jMBx`mAajkXcBvMnA(5t$Fe zP37v4sBrsPD+Em(JuogAcyML2{~5J3icpg`K`JC965V;a=R*E57A=ULvBBLa7HOOi zkv>M7dkm1{AQV^vJ26;9?tt`)m%%&%8yv}^u5l~S{+|S4W?mGVY`howM5d%KNKeIm zF!J>B*_FM&*|rdPKq?BzW_AtbUQ z4LTr)O?@UThX;cQ7GHx_DVs>1qksD$zQtF7!4$^#dM$J=82QH_M{l%K5kdNJjxup5 zby7?8inVlv@)x)O#vE#SZ{(m`V|=Kcmrw+yXT^ER_&Z~pTV&1?aQ>rx zPCI6qcsQO&XD~8xPdt&%U}Pfs4$?j+nVn4hS0u*ip`iEF5J~SH!v($16&Fj9xLCd7 za#ni3QDkwV`!H>@7Kx{v`QnnhN?h{SiHlC}AIFohKf*Fo$=-nq1=wh%aUxAMy7?ta zqMN4MX)-KyW+1rj5#@oK@uc2qR5qLMQI|j)YS-dUSM4@ri5O*?+R9l%Ts%$>DmTjpGeLTDt{odMX8oC8>k(JFOSSZw$ z8sbBorq)9#LqpAF7@o8>?QLc0QRHgvN?CO%eQ0|#rtVECwJcN{>WYT32Xkp|WX4s%pM`A8#%js%$DVn%Zl_ zWeA6-Y)aqP)jVSe-kVJTXSiWsmpCeKo?*FsTeG!b-fde|>s>8>dGg68k009iadQoQ zo{H>7)momAj1o}$CZ(-Ri6+0X;0;cBW~9ZF#dlQL2mq-SR&o4LEO|JRsW8<_sZhB$ zAhR8gY9t>+{xhMCU%}oC-eiNfSAGxeI7@Bd8I?_z;7y2==`{wcGhN%2pKim)s`+~L z29s(nZkcfXFPz5@WpCftW!fIcSD;&TZD_Iqd;L6ZPWE?`mZ*Rz`dPKC&k@G_sAo2gcn_7^R? zfOe+s#}9=*P6<|PO(@2(2=y?%)7}u=tQw^iiBwT)3hJdS;?pcvohhpOIqa{rk8;AL zxu^p^JoAZaP_=<>2Px9Rj}K{aRn9_$K=wlmn>L>3x$({rDZy)KRnY5B41hl;&^ONiU3yLJj7-35 ztYH4pc%6>xaC$=ng={|Bbc#Az=us#szDnx4kHS6)2I+b4WWNKboTRx+J2P;d58Q$) z*h2dTjV&Z5f;a@QgYY``X5Kd51jibr<{(@PTuiTQ)%=UUB(Q&^uP8KKpR7YEd+jn1TNf`1c?U%*Kf;9oe96}uz(4E^I*LvoENlm#h4CNX}~oleR2 z5&s7jdP4@5C~Yxw&==UJ$V&!^{li6>bcsx?;j2aen5m$=Xe7g1T{E)^W*X#K8D07d zbSYR?a=73hs&CmGTd{Y{VQt43Kmw9@P}DokOl~opur|5T7D-|4II#whfz!aHZdC8( z)qh1dP?$i%IoeD76v?#at;AJzla^mb?Yg+~--H@I51a_=fYv5h{AoB0fpOOc^r7i9 z0vRgS1b8ntfcaS5$&MlmXI=&}t-{_~YF#6-5T>AFd+I=x=G{oJ^V|D??n2sU2^=x{ zStVccB%z8Kr}N{a%2k9N3;es1y({|*_NqL02U{vcLKfwxw0L7{eFU-|q+Up<=ujFP zklJ;(Xw=I2=%##iZZx4i7uE2e4WTvw1;83F#(9adVJmb2kyEIP=fgHsHo}VrIB6>t zZwMLzG4zcD?o-t6-f7dpMNCIK{!WO|Rf0RVB`EL~VQI!dqLAb8+iKWx{=C%$4e>r+ zVL%oHVWq9NL*G>fy6tQ#LPp}04?di4pfR)t4xM@w#G(%aXv;eZnd-?$8HcWCM&8HS zACo8-^Y4K-Q7w($Zd@@pmjRau$<1_{Odw%yI;z-PK%}k{n455E0)s)N@nL#}KnXWL zA?K!WvbGwDaOmyjBjAOGT^pO5WtMO{UKzsDPro)d?~l#R`(tzSjRlyS_b1NHv~M&w zKOTz;q4jP-vm7wc%LuzsA8K?9YQWzm^;0)F8#_`R+#qJ>{ju43e{6Q%ADf+zVOTLG zGvv(7OrDvJZ!$9x4cg}oL{gxK7fJEY14h^&vdzUc0|n<+^G88WiTc3(3k{`x>%c7E zfmgM!$x;a_osQ}Hy3kotQt9xY2dp-)@Q=b}y2C$A$TH|4gpB>= z73WFv90{O{e}g<*6SfCCVFIXU71u=g;89S6&`J>A`7gi~Ke>vs#03zZNCV z*-sSt##FPn$c+_;8z_)Zva}WlOHY`6^~f^knv&VGCi_b0lIOdaE?4*~s-MSr8OSkK z4gVo*t$>gEcL?PQbI|8$;pEzyf|7#qQ32Mh^HKzxa6)9m;80&BDOuW-x2b75D$p1iI)Hg$%jt& z#q2sE#%0F?A1c{x$KSi4cYI7LNqI5BT0scsAOBD+sEn(nrogMDh>*8UdFl<4us<4j z--KD3W!mz03&0EYrGQrDAAet22dV6^_6q*e`4}Ja2ZjX(UL2K13Pv9I&=f9l3h=P} z7NU*?klu8f@U1;?+N`WC27w`7V+yVi65JFzno^3FHsVE8^K;Y@cr4K6!I*0~7{>x! z^ASpyRvWRN!CO;&=^9(Z*PG&`zFEONwALZyHJwIFqbOiLsWq-$htladtQl9eE*d(L z;wC~=fk7=nv9n-ucq_Cau`8RU!iUNnET~wddX-JHE;W}zJU+`gD{#ofrmrmumiIAY zi(`+c=+TVF(8p;agN03h5ZTPxP&hTOc##&7K-d=8Y6+l5BQ?T*KPqwpIC5NJgM7aV zE9M@)ToMyxvzhUeWuyVa=NU@VQDWZFlO$jJHQF#p@1V!$urIOZT^959 zOM6B&uN#5;9+a~n8$DYNdnMCn#1A2bx@pBk9GFc|XGfvbHVrk{pYS;X$qh&a$I z!u3?WjTy)R)*MvX3w+hRZ~4Yn^UsMnAm3Uet9gf&#)DWbyXm+#5QQ`lmy#u(x-3ey zYWs1-%`_95?B@GHqi8g?+GsRBF(TwCz)!%W-F$O7zYJRS00m>@MM%x8O$wBK4d`b9pVC94x z37cxy5nkx{MB5XAPof1HK2Zw@pF}R;Q$((tNU`zr&rQH5r-n~i5}yimd~#rjv%UtO z3N?Hx`ZoBKlYmd5(Q$l&Uph$HB|eqt_>@b?fDX#n@hS6c_>@7GJ#l=>O~NOl5X6q; z#PP{K0H4;MCZHSWudchr3Y=!0(1ok zG7W6AE1NPWvbR9e;azIw1RN^#u&wG$^J^TU0#FlH(wGsPdJ1M9{*UM@>apw<&U{iV zC|t26X@@}ck?Mv1O9hCdQ@z1Lpzv4VJ|yn|06;C4DRZzuK0pfqI8_IV%de`|=mU=Y z&$qJU%4Yj5fISCANiBoT z&CSOT0oWXH0?pM?;)sdHw9?=aK|`g5XhXp?yvYJgHej&bHOE<`ti?HD6dp7{@-anq z{^V`yr2f)iwi_FN}mh#%i zU}>-_XRtSd<)_#lJj3Sk{q!}{AIxnokJ5@p#M%z5wq?(8&M76R2u`%mj&sfh%G$YT zn;b8>oS}VWKW#<4E=bzY<7Tzm+*abW7-xcSwS?0S{v+Gwg?>N^f8ImLW`TDR{KlAO ze1&h-QnOd)MOHe8wgy@eg6gNSPh$Dm_2!mkVDUk7+#z5rzQ@N}J-kJHVD2RV;D6d$ z&3D-JT4fR69NrKyrC~)5U~L zfPdJT%iDp>1Im-vVs`;ohcfxgN3=pj3lVx;CLh+5MK8eTgG}Bf zli6;qr}*UKqO}PPO&U^k@|p2@(+vU{V<-ib#88{zp5+*1bgkJo;HQO?)<`!x?&Po&C5t@aKRBk*qvA@?P^f%@ejOa%)W7JEYt}F~; zfFaTv71yiBz7oZ##TGBARpD^@07fTqDhsR@?&k9L3%9G;@73f*K{xD58JR+#U!~pw z0e@PRmp_hAo72khb*bx1e`GFsL%o%@bBX2ObLu}_ei1$$ynLvKnG<^z^pQlGmh9~n zGsT*C4`wL{kR1yt?bSto0!;hYFMkHVF(E&klVT`wx)4sYq1Uk(4vj9c@*q4;M20RO zM)x&Vfqmox`7R^_wdKg`Qy$xs43UKhB>)8|X4Gkc=aO46Zc)kc~z`bS;LxB-d(Y)(v8?aR3Rc40J>5F1pypPN<&tV8da4 zogIwcGz(h{%?y|lcIz4VG=tiduH3y0H-FbU=*P)hc}t(a5% zhYulYYb}0&0+=re>vx}9ObLB5*sJ+4t#F+dCg*P-kpF;1^h}I)wmhCJ55$DAR70P_ zKT%-$?)uSnPa#LRRGwhOLf-L860D+D3;bg6@Arb}gAszt+IE_If7R{!u44U{Fm_Q5~mFEPRcjIFyLS?&^abpY-QKm#<%;z{tkK&WGW*Z%4W;+i(tat};6K3KjAUE@J zC*|@b<~m5Zo=MJi8g7F4O^LZar(A23b9EqBQWKK#ZT7VO`1!-MWPD5D_p*_B0DmTk zD<&xRIGBiDIdzHYB^H=JG!@4RV%lI1f;FMpRBF>^6LooVFikOkK&;PLp8IU&P5<`g zeNlWy_%z58`HRj3{sR4|;a+t(Z53+f_kT(&g}K))SoMNx?nsSeSOU>VT&+Pbuy9%6 z;VeJlmP!P1~30J#RiTu;l^P6ONTC9&I>F>7K`aNeRKMy!hb0oh9vxeRy%4>$y*s|oZ$uMA&23?s*5UVJS z0m!u(M=V2ByVErk)>Z-R`H7A0e?A7Rf&Eq*8Eg$BgDq=6gRKGj!|FokV}b4k;1GS2 z`WvOL?lwb02R-6NZSHy4;?jZ~*Cl=tNXOjEbSBZi5H4ikKPKp221<)_l{#_~uab|L zPM-P@&Q9Iy@-Z=j{-=U-Hxk>&qrY?z)3na3dN_aPQ3v=$FixjZ_`{DmfYyB6X$Y9w z!3V+vX11{?=q_Nz)@;O)@o+qp^Pk9U%P1R`VyWuw&XCKt8Qe7rgBfEXoIShe2mQ1E z0a+a+R^DL4EN*&j9NG1$?h+*M(RgB>`7R6MgdtNYGD8L4zgVq+XFqj@aZP#|xrt`} zjO-K4V`pvIp_-YlzNM2@^AzYv1l@2pX$EU*R`bDz)Rcn-HeV%JVE261LJBviv+E$L zZ*xyaGZEr@dJX^mwbX+N8D1dxsxrua(+*DCSeFBA0e5xRMS{~dgDnB4Z6;0|yj)Ki zA*!_v`U}Kndu6$>J>{iTaMk?4ma{{D@u1K@suha{5L=xoi_NUzJ=X|ug~9^!6tad{ z%BF2oMC%my_MoSboDVYpY^CYnzy;`zN}X&dIWqN+l=corwvV+_M&IYi8myY%wVX1S z%ZO#?xQZ>( zt?c{(cSdKfS2 z9KRMQ(YaGLcN0P5lxaJ)v_DcBm&4zpr9FVO7x0Jb=NY?xONSG5!n~BSYFMUfS-($d zTBDb1X)`EIYxEDaG#905SXQB>?LZ9zeV?Z8O+vQ|VQkh9-5{nbM?WR?2<>X)y>Zt7 zbbETJK(}#Hpfm`&J)Hk7(5+6Ew(q1s-WN!o7k1AkIcL{$AXjn==3FsgOou}7jCOsi z7MvI&S}<4EIYt=WMo6y_rxS(}>2uh0u(!vHlFw~!sZ4FdlO7@!K1~$6>z@U~rBPzIi zwHP8aa_;=#T+-5Q>;d8vBX%CRGB97GQXGaxj8Z-!5Ry}5GBY|L51Gz#$$50!qd|Bi zhqqoV{;*nvGH^%GUrs8(q>^)-;DY)u=^_J(Mh7rpB$os$M2l7jB}20I06$TPg072W3veY#&v0;jxr@GX&&t~tj_DbGBW$_< z3t$TXgHwzW95eUR{#}8yajE?q-2C?1rE#<-4a9=uIS1>dS)n72lU$6Sh z+=c8`OF7J;t|QB{o|>S4IzRj|&b!@ExT6#ATIR`Q4PMo*5@H9dKoERI>`O#E$v&-C znwURx&D5`Ope&JNO^I@kE|4Ug;#-wWd`3uaI+dmV?GN5d?E#(4CKRM!5c|{7l3Wt14hS zlnvYA3ftuA3>`9Mhg8ptUjEASXx%i$6~>d|2_weL#URYtUk0MKdxsJo4*-Bj>OTY= zC}ZwIkl(;ovub`rjIq01#sg^DztW>3_`qw-51qFn*v?HorOvdd*ISvn$?)D~wqS8L z(t2Z0P~)507km1gMt+AF`EpdistQcUOqkQt>9GD!*a!jHw(LSi5&~O^N9nK{p0FuDA#IGGhZUeP!VnCP?c$`sEjNHqyA+xy{K?5 zRT%Y+&7%4q#{&Q_W1dBTH}WjnqPmO3<~8*JhatMu3OtQ2HS@O~bPzXyZYn|)L&U>8 zE&?D-#C{XuI;f~uCjy0@SpA1%7@{Kfk7*hv?^}jHKHC=Q#pwn z5rh@s!;_0UJt_g-^tzp*OU_F!t_P0vF^N8ob%{*)9f||K94xx@mM*V^yIrdK7;I4Y;tdlUe{_a3OY zr-xXzbUD8)ES)TGq=`cGD&BQOgVCbFD4qFeQ0nsRSL}n!v-S7u#ruKsV%feI2DEQ= zHyI;PBgy@Lu%QE<*|mm32`>#m=YnDEh2LSZBH`>R=zdYz5DI!)^0p-?5>6-R!P}aH zb9r!XD<-KiaCDf`co*$v$uICREVZz+$0i$UDN4;YHW$*X!>+9gj!$UE;QJA~O7jBm z`#Kw~MiG-MUl{#A@bKTU(*n`3F{^R8ckf(_`iNrUwndPkfm#J{~& zP`@isJKh1$$Q4A*w)lG&mEF)$)b%IOH6R*oEBhhZdl=mR1BiAE`_QjLv|hrmPZf10 z;nzFLh7Q%dgiz~#fmNpW&~N`+s5REte^ktG%PLCl|Ib0K7Z&%gq2%opy@~;-MdMzI zaeo`Aakwk`t;aq7?N%}F*P!;qagV?MlRoZt-0%r2h;Q!8z&PVJd@MT-KR)j9A_hi*aI4wC2(SxZ%E*TRcXpY z4mkNznkI>?3uEpzrGKr{V1c(}pVa*hF^tc$-bP~~rU|}r;~T_dfDfhH_B|L=cU{>1cpV-0xL*u5&^l!5-J0Sv!-HCG?^d%f{RI-bM4Y`_ zEx56;M2+-p2mN&Ke776oT$Ltr0aizAER3_hYh@ z5&EWLuXtrHkkvm28+#JK%;s;tL(+gbAhO@XNU*9os6fD|bT=viY1 zHH0MKw0gaH&D4`Z1aLx#10V?ainfFA;sAyTER?|{dbR!IXAO`+#l9UI`}TuF@o#JNZ}-(3Uclg?cw1%VO#aDV^qQWd+*0z~ z&a;pmF~j`JR1Z+ii~K;fS#;qI7tqjqg)AZ+@wQ5i}G z*V^v-tl`JB&Ths6t??%1a-l81d#KQHFyC1kd3yj;GJbHTWSL+}z_;O}_3#I^kY?gC z$&JX=2Ot_&3x5xE1!z-M^X#tMF+~W6{fmma%yjQ5QSBG7FVQE;hKA{3cOCU0KsQAr z*U;f_0rM}c=JyOuGgL!x!GD2MDAoE~5D*R~kMQy< zX!EDbBR=ZvCy($7d4xA6kH9m^2d+va-7NDH5qN2zoVY*mJEUvbq@`P%yEu!$s?>*7 ziF`=FUo+-p8t&qK1s{$Z+;#CDGlgV#%>+*|o43y;<^t0c^MwyX2cq*!G18Gu5X;G~ zC=wu<<6ZHrB@Nk^F&koXfa zatNX5k|8hXetL5Bh%8QTC4HW?NId1t7nj_P;*#GgE(P*~!cIK(Qy`N2^V|Wf+P9NG zd^kEboe-Y<-ESp-xC7ZSYk&cR${(PrN`@ks?)Tj;PubF_HJW=Kp)aq!|ChnuQxAiM z3@o!l?VGjVm4fJ#vu$iCR9aY#4WYd{mQGa7=L;1{D7N5zdZn6gL->~aCQx81gnfFiw0?=ReT^vrI z1D-KlW-Iy)UFupPP}0O8$VW>lOIMd>P^?;J&WP%2LF4DME&oqKmLb;yYQM5PQk;AoZGZ3V|a~J+Y*ShOXri(zA5t zHLFu0JiGc7uT$_Edc5crZOEj~E%gH0FZ^F48u8o=#Cf!v5MAh;xzzbJ4wizEv`i^0 zSZoTG75pLpJJ;G=SLEW?Z$UJ*##g9XkCUP+E@NexaElLxFnm$lbYR6T_rg=hU9;dj z8v|HYkR5u|_0GNS6$mZA^g33SlMSO>)9#6Qm1(r}x}7P$yIGkdR>F^{I2$X=rH>sZ zWX|3mr01X|Qo+U&AdzVT9#SH{DsZ*IcR4EkcTwp-lPldTD&3B9vQb#Btkq$(L@Zcq zL~Ed}3?cixU@n%C+rmY1d?=bT45E}bi)_Lfwx;z5XGg-(k={4csBfl`i6iv`4h^YK zre(4$_%3NAO$s2iBhZ)PA48szkdZ8XVN9KEeALu)&dJEtbf$0tTH!yRGQ8UV{rTw6 z5gM4+h<01(bIOK|)!Gq2xqB_(weBd0MZ*m!+5^vG75Q@IV|k6CiWGevtwj~%gh+u z+vW~7v^bWF69e2qQGR(Q8w2Ila&~hLGnuxy_AZ96w3K1oS#>S~JeU<%-{SMGhi&RmR_&O_F2@mVaA@;|a129b zLXR@Lz;ptF-zeL&uPboEu{iyC2hbv7As+rmfTjhk$i3MiS9q~`Uzh(FCDX3Jvo7$T>JA9$vw3m+x5z zsXzb%Otq*_si~^u8^?$h0RE(kphb_4%?RFBfb%IBGvX%~1O&NnDx`~smIy$IbftPWvy_7zfD!44ELF&Bjzb0d?GhBIdi8wuj-jn1^f6OwN}WekMLZa+grVGHbo z`v4=EaFGMF%yT{i@OGn{eB@=K1wXqLbP4`OqDoT*?f|xpy(tgU(BJsN$=;;4BqmYg z5_5?`iS-wPNus|*N7>N>#KekF6l;eQP4-xc-l4xh|4t3;FFWxHRXD$7akuVT?( zE~?+PRrJ|z^w}}+FCKVp1F#kR*-_}TGMG+Nmt~+EY}vancny691}it>1#h^Ac{5j^ z?771TZz#V92vKhadd_bi)*2awFF{jgWNHKj%N=#<9VlLOCKcCgq=EyXXkfqWS>niL z&*ClhEMAM=-LL%Y64|@kl&0~rckSP(cN23(_jfJBx1dw-E*t~(wymH`ME){wi^G~Y zA3^^TA7Ouxw?8of?~|rn|L4TKG{F6z6Y1%?Bzk&he%MHa>l;$7i}wyjwP^mu==I|X z3GjkWqid3Aby}QM z_v_t*FC%(z9~12Td3ifx1TuGlZe@Uthm{(fWktG_39VtF;sO(=b^ zp(FH-q%ZjX3Ju{plW=AHf79xuNvjhA+*kcM3#A@uYVwqtBYud5& z64iX3lqkSd0uqJlN)T1MFqO#}ogh^JOAm1jy|g6>7DxkMywdG?GXS>iCY|4s@|j>m zPd#)&iA?a{?*NcJ^|0fm1;N1gY=Tx^sac(2fu=)nX+CU0!A+@U_TUUygl4K`8No7# zTILLv<)~#@!LnRZbH>tArn6E=p#+LorQhfbSQ!{w@oKJx?Kr+KoK9RHtntESg5wGu zN`c1WzQFeXMcli8)DZTD7(J)@yq!trmh>O#m}NsUlcKu^N@?2@^GH%S&Z`-?h(7 zCJ(Uv_xJyQ{^7%%bN1P1Kh|D*?X}llk8}?=n*U|2p10dEsw;V(fY9B}ruS^(mS3#B zXDHdqATh!){)PF#u+1CMe=+)RbRrh{MA_~4OKTcV1zkmsQtCd293=xkjfgjdQrI#S zp~x7Z6JO{VQCyhtm+)f38!P_5)KUxb4wiEaVV_d?MJtyLLM~aY2ZqM>{LrB({Nukn zG{7u57XQNN3?XUe%45QF`3QI><$ahUmG`Fo3;`}JJQD1Qq z5lN8*Qj&;RoJ7Rp1R@SBt7iXNNAwSTQ5=-W+@odrQrv*#jBSWKxzeaNTILq{VzkT@ zvX*6=?>y!u$Gqgp#rReyB7D1XX1AhCgQwoY$JO|<(!f`SSLGw@ik8h#-y%ils;|VO z5(fCfib!Bv=B)G?`zzkcXLh|Jd+lLy0uo&Ecs8%)^ca!cN%6~uxL4r~Oies=YmudO zsV|5~%b~v%>Q){~J3GXH3@PL28sqgR%tn^~eL!ZXq)>MB(e>{5uC_g~pDKE(&OD6D zsLCF;gnhQK&t5Ca+Gz^L0z~}T!Csp>o~H|fykPuI*s|n#%8%98_Jn@tTSG*ouzolQ zIZrROv(G5Ci(y>Q8V=a>**1ukp5_hMf+vKR+rriM@CuvqU^3h04cH~oo=QZvHjqKJ zJNaXlzrwC(glF?}%<>&l{z-$1cLv8&U@}E2O5Q`?kK2p_{-5QIKo8*=1>P8gFixX7S$SxN#hQmlHYe5saZi*)a9@-oaD7 z+xWqALW#hzFoBEbC}$*)x|Zz(trzQ6w&}&VGYncI#aSG^-EVyOM{)bGGvT}_vIcK6 zf|LPcBPdQWQ*0^$CXGIquFs$j*hOOz9 zEGKG3zv6^}6+Je-lJ57(0YR`2`4N+r4R7dXmv8~2Q2|PwJLsoUX5q0<9_*$p6wH$zCVNwjsl2vWIB+J4c*+wo! z&TS5Wc~+%4t=f1CE@kGh*GJ?XonyY8<5I(8wIl_YCcU!EyAL+G93pURf`TYR z7xnLBWRnh3bSo14a^Z*d)ozd8;LdJ|uby=4ICe|pxjW%joA;BInYo{Y-nPWXnHy>U z9=%aK?No|C6PpbpZ(>JNo09LEHAO7NnjZOPnGMASmDOG1fC984MfuRLn@vv!ly_NPfIN+dgwy zJyd0)Aph1OYuZ)_NbkS|06FdI@NcdlwWUHNLJs47N=CH7iWdLA-LQ5}8*sEz!2)9E zP-Zg=+O1V6dR*(wea^c@yX|Y>LA8FPi@=}aY95>qy`&+ZaC;B4m>-V0^{$tV+-||T zXXV>irnSp^NSl2KYx-l#r9XaFQBaXfchU36@~NTsd%~pya_N`M_jW5jk_mdv z7opCnxkn;pN;EuIKf+XhTh(aiv;l~UMBa&lw(%&XNO|(V#<)LK=2FT-l3$R>Y80dR zY`k>o5OqO0pJn!mbDCrLXMEo@*o|iV-E@)2u3I0?2xsVGlA_#nKpzJ7huKhx@E&ZqR?h%=L#y+l z4oj=WwCfHKM5s(tW1j_4zr5Dx4Ey#(K#&9M%_^m;s}emAv;B zl_U1sfth69R8-+}+X3`B5drz^-siMCYM2_8`VyCN^Z8dZ)JcsNItXa=KQp&Eu<2$M z1ywncxvh}g`j<=|?-3@>5hl)7CeBXp8>xx2^(!aNMpK9*6X!jdIKvNg?ls>h4s>MV zT<`SJYIk^zD-in9xuR6R2s^%AUrw|5Ap&cOXs^y87JLzUZfY)Wl}sN7!ZGQGt7?pH z%3~V2**%9RhfAGHuUxWNjzp>}m4gFbNqpKNuc+n5*`d#!D`x5!`2x(%?@*aOUz`FK zA7=`ls;1yos_k~%XUaO6tjV}}F4`*ZVBnOJr|T~ZE1r%t-L3mPGnai=u<`2x+j0>c zi$J?kgv2sRE+t0J7D@Y?6l;pvcS-+-irF2t>;DZwyGV>xG!x_2FX-ifpxrr4(4H$q zh#Fl(B<@pn5|u6`U*``}yy+2cW{ zDHebh>=z6lOm6~%=nd@KkR>QZRmP>LiU>_9=%Yb%W^j3RgUS5hQ`v=*nb@2a4`gjfwmY&|6372=tH0JZ4!iNaDTj(vVsqlWzbk50UJh=fR;bR z2PTa#Wk9fMwqXSt-0E@9b{eS;iMI#81DN{4U`C32H!&(Nj2y>TthX%l8p}4p+rQG5tJYw)ZEqSokZmXEeN$r(e52B}?VU-jLeUB9E_`EAif_Dv zRbZhiylq~Q$txE9o4le~7j2E5H9z)vsm1!6;sp@Fz&^)n?bo z(YBBl{QI2ZsL%_xn0%I7)M!ajHt>c^EczF@#M}*ViMND=OKij-+(<5-qJ(69 z3HJmi>lKc%yG2I`r`XJd56&L(zU1kC@U`61j)s5pys8 zqW5b?JTBK0KQOP2iRUVw6`qYaKZV>32%E?;{5)uQ{(ts7;g0R_aS=~X?o7)xz>QQNeI?Y*Iuc59nHG5&}5#9)ysdI;a8T7Zbm_-XJSe-AzB5<*bhzClhsqu1N9{lH;2M2*wk*^T5xB+{>TwE1s#- zxL>*X=%c#Sx?(O@TM65WGzU${o5%x@Oz95Kb%|%TO}DEt>1dc3FfKDwqbf=2hzGml z=ie>vmu|-;15IkT-eGD2b80!15GSIPa(?!vX%id=&UM#_0L%@4a-bi*3=A^51fk5(rnB6au6y+zR2IA_8nC4S2Z2VV&Xdt^?A6o%sZ z!#T-P*TGg_`T3|ezJ1yx%r5Fqx6MV4sfNP+BQPJ8yIm_*Wu3J2*lbwTvWd zy6A$`M$uC5@}vDtpLfe#~JPFkpho`Fsre^*=p)Qz5C<si()ZQb(iX*zPyK2V*UnoDKrz+`QsoRcL+ee z4K<;|#_e9Fxrn}H*1be-#NjJQBPFb&`u%~lD)us>;>jGYR)S08XZIqM$dK(LuX1X` zb#{GREuG1(t_>HD(Z_MinUzD`o<+txG>MEjhodC z8+*`TYqe2tJ}zBC6uhk!)pg6~Se*JNbsIV@&N|uJ*1IF6MQom20b?eI3d&}x&SLRd zqPNdz0)6?5mMZWWXCsyePr|ns@q%N|%eTVQD~_67ntgXqR|Z*Ka!?wc&v}h~rj)g0`m zHqIY8BrDA}ilB-~AHB3k4xk*mYCG$=Q}w6DxZ!_Q(_>lQXG*AOO?JS@B`NW?LcMi_ z)w{6zwq14O8EI8+sVjW@JZ{WVmqu@&n`mpY+5vp#+(8s%_20>NqP1)Q!KRBWTFcwq z==aKp3Sc4-(O=lz1K_gfN|Up_f6*cjkg4rXsR~)J?99y?wT(9CZeuFXBG5zaQ#QrZ zl$YBcyR|d4rqH4_i{e+r)gt4in*(G+&aB-fc&pFP=d0a4qtUV~&9-)iOY=jA?5n5h zFXd7{IO_4*8&7O2%`0xrEbCm8XAhO;9}2C>w>Q40->C*0agJ?_In>qJh_aSAclUVr z1Z}g4`Wu;prl?a5c5sfW3S6M7h;2L-nT-LxC#FUjLf~chAyup3%1@hhe98)%>HUAoLn)qguy{bERi#|GB{$>SH5n$(bI3tbi#5~aE zG`2@oPEYiyS;pf;d-l4*g@ zYS+eRN*DzdHUT@HZZg0{?C7GOF)LjPeaAQocw`q4I^$BjxBSk z89!mAX1#hNT(&B6F#M|eB4t*3r8~M96zsjl$ib4k#X86C?bhxR8_kHVQ4J7h2C1Q| z2wY~oXb9}sXtCMov)b3L$q^C`-Zh+o#=40Oji(k9`aE&3Nzk0mpgmriJr*M439rck z`KE)8krsC1Cf?3Ar=0g*p^@6Ui{%AUDG+;(Blo32lgqv#E%r@8*ZJ9L^YhK=zPo2^ zG`G?Y#*#biB!^2nRNj|+sl6*BEiB)ppVuLxqXY*dvV4gQK?H${f}y7mJ0!kT6@H|9 zp{q7PJss1WJMRM|@CA`z5%Nx=x*twkF)3Q=1lFingx09j+HqaQcp0vMbErnKEBAHt z3^lu}i8Fsd+M#hI~3)yAEu-R2_sq9jxq!PS2tJ3JjC6rJ+X7Y*2xVeOjLwlo#?m#%fm=+~x9A+x=5mf(UPR|8rX)Hi+k7$^(K$KhlTrtY&dE2QOh$B$ zVnm~JW=JADAATpPR%^aZ2rUC^6}m5b^#rvPb%jRGx{YgDhveP$lCjLr=E+7N?P{^W zkN7nduSGhVrrq{!-kYg&9I4c+2fj+&B$fbouHbJwiYUlJ~ zdjr9SLd7;)Y)qtTCw3fRz@*Q~i(Hx`FURUtM(X`O-v8t*G0mrg>;|O;W_w2VcmoY; z^J~o=H=nF+>{h*?H@kZV_ripj^gVX{jMKE14YV;)(#NSz+@ebQc*bE|Z!6%K700|Y zjt0jjyOb3>VMaWdlYEreEywHOug@H)Wn!w9v#Di$n}4DlX9KcccD(WWH2A&*#1rir z^o4MEu|EU+7Ps7$#Dh=7&%aLuHhh>|s(HcT{H`H|`v{DQb%Ktum3+PBna(a-KY*T*V#_pe%+yW{=5Jd)z1HA)@ zvM=J6Nz*tHe#I#BLU|`&HsEQ;FN6{%t!{VkDK=5%qVNi8rMZ zpN{&UenRE^Hi=0JBD{I2#H{pVnU&j3X!yi=+lW;?F6b+(y73UYTIL1__$G~pO4ZEO zOLNS!^1rgI$CG8tu}35ni+!?shy)D5S~fx3 z3$`0RA_<5@0~f-<@s-BaIi@fpXz86Xo_t6O9zIi&?B;4?;bY}bc+ozV!h%8mgi8su z$x9H-CNK*`Z+FNef6?3Ri96$TzKY(S&7-7sx*ξ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

          Nn|B}l{cHxj>8<;#&$Daio1tA6lD z8tT%EzvLpP7aPyhi>1Gp8F#D%SueDxB9x^DixaT{7Ve`WzqFgGzJ;Goc%^$DGX0 zL_gq2Az~fTk!ooX&5yYbOWsKv>fYb?12tY%xG9t_Y=57#SJM4NYb`d>y(cuXsGKGy z#i@=#h1loWz58W!@iyiR8jYt`cpKMS+0fPZeu@7}DODqlC;O!ojhAwFp4Eu_M&hXG zvdxf(%>NDeAHOHv=4`XHJLc%j6}&7ALPNr#K;vO~fT%xI;T;H?YTFlLU8nh5%KO z7@@qK<3WF%Le8t+c@UvFzjbOg3aEYB{mvE}_{>eq#;p4xmd=dNv@lvzLMpTQ5oDr)nuPkw0D)0F%Z z|HszeK;8Fp&|KAkySS&VH(oV>TWs-wxc=WzcWg0pxBV-vBFZ!O{Wd+1DK&eL(nJN| zVJv38KZRBG^t`idHX^}=wkIthLwG28i7f9>DtoMm;}sY8xnJGO7s&--WKC7}acM30 z=Ki)51x?oiRnwIMt&$SXg0Pvmrx&oRb6)6Vf*PF##lf=@o}E3Zpd)8;@CajViX39G z<%9Q7>x$)rcgr3@QqBjF6-aBuNm*NWybbph9%CU4wC?PMi*CQe-}mv`auc_JLE2s{ zmp`?VIa>=RXRm)#2#jl|wed&{Wfm9rLK24j(%#AX#bx?FeyDsUDV9HKo-n`Gi-=wf zzCiI6%wCrc#wE+N|Eyf^+n!ADQ6=8#2NewlxHb4|{5I(%yn7eV`k{Xh3k{ShM<4kM zWtCN!X_d@-?O@cbMGFv-D%S8H`ZaX|bGa|qd0i&5j{#6%M$Ww<_o08#TQHJ|Jt6FC z$zqao*bm*$!#ZY+{=!i5DT&=VR9NN@SKU*xr4e?bqSsWBzrG~7zIeed_pvFNEk#V& z-$yG^hofBk3SmcIt~V~?{sDWDAgE6BWUb_D`AR!aq==V!8#l-)K>Ff@L0-0 z4koRd)NxKvF>mcI#W`o)2d_so8rGHrmVPsruTRtroO62q`t)0xSR#)6i`qjMXF@oJ z6s%ff9^KUB-xxBFZ_s0In(Kr zuD&~R#93z*UMdWbwkOL28-(>XAR|ZKa%+Wfc#HI>9#;6}T3xCu_Scs94Pi34(1;eD z#EA+|Pe`JZu=lnNE{JyH*E%>gs0U5*S zv7*c^MdYb-xBor2a~Sn6s`!Go?o`!ln|FlS)dm%JoHgK?vAQbpj$K40t5|qyy_6}o%IWMS6=ZBlym#je*G{@&K`l=3XmWMMux2hiqfO{TwX~8RUau3fdV9@gP zN-a&%*yeRSD))cNYtz&&|JkZnwkSbdlEO^M{tS2EYjj>F4Hg3frqnDHRycc^hU>H+s31mo z=zj5v>Y+6bJi85r8n>G(#MTO+i_T|O8;mXgAcXp(1+s6~w9PKa%oWdYY>VG75%wZT zDi!E(iPonFs7&6S@>~NWG%GIL{6(HsxZHPd09Tugn zrzHeWF9@w~Vq;nt1s>%hy&%pUYl<2%b>~7}3Rbw={}KGKJhVWy1kc%EpeLL>d)^a{ z1sM0F?aA`=0!|l3kwp~c`#nYZKA|YzPDS}*3Mj(&sja9EZ*a+VRh(m&U zPnrnd1u+}$Ya)C{Y=o~Y@9zH;K*t5l8ZDQ$gn4pdw+cco0`_v*?+Sn{_9OBJRroAJuJZc^ zj`Kko8!bVF;vI|T5^Yk8s+HWA*;L_I$m)ss)jRl!I@R~{bu2p)_9N|Tk7xi%;&NPZ zOtnheolI!9xtLd&30-Qh)ZhgL=jBR@6z%gcfK6!{3AfLi)Yd(jDQ_7mL)bGSbB0`? ztNx*|sm|SVvAbuAfe6I;fK%~+08B&@6e7=VS8^M#KB3&=gY z6nxXYjZ@M`rc$cV+~&rbei=5Q*6&&z-r(;r-Ka?v_s-D@OhNA))-I(A!UgF$5oS>l zyZPJTH@Eq_yLV2gf8#|qQ!VogD3QR2Daw_t$gTN~qllJQQ(DnA^b{HlJ-hD1N_cP= zx2^Xozt^8~)td^%H}m)bmGXa}-TWHblIjcU-Hu+kH=YT#GI4M43(cAnfOAmsTy4E8AysL*7{6|= zUjj`aR?)wm=1@PQ^kUs0E!=`-^}~Sa=eG40XVw-Qe`vldBP?VXWKPhZ3wXcJ4$W9M zi(kdK4;hsB_(hYqA#glhTi#o1!ghOWD}{Cc0k!9_hF)!#!VMd0zbG=?Y@v*4ES36S zQML3j;(xU2jNA4@LCIo?8m-(ld$QZsrzcA*IND~rs!X2tGxA6z_g3||bBD-@wEUI^ za1-aNicIKnt;Q=y3`>1&Y;^sIKd-{+nX#c6zJJA6h@!5QJ% z%j!3;hbCIri{$3B*v|e_{=5D475;pM2*s*SZ@M<~Nvtz{N<1o_lVwW>zkRjQnH4Mr zM5|7>3>q6;I^DEH4OBT-UU{CW`l@C1E&qdu(ezD<6*umOs*Ip&PGF>L*Qj8T4Mrmy zJfdO=J)$?g^9+hPpY6VKVX3+~G<)(rm-`YSV}5O^k$Qyo@S#YXw=f zy9qU-1QU5Wd@AU$=Hq;&4za&l1XNPtGR9VU)u#HE&!;DAyQ^T!$)q;+hoP!vT9&P_ z^!1-G4AFvj7x$Tkr)GAs+x7vhN2&cxZN>7;XXO$>;PSENS(MXMH{xGY^{U%ub{^JN zXYMG*f4HI|xi@*3oIrE?1RTKF{B?$jZXpHR(j3RsmV@G|`SIr4&35b9>_zpPms+55 z^4!FCR`s?d+YZA5se%#m6FH!Sxa5Yx4o>E@#ffQ)F0LBhd<^(vb3}K3s}|L_bb=dM zPAOi*K~T7`xbWr*zqVq=&E@_b*3HxHZZ{qm;#V{5bIgbrMrOeZ^&_9H3}BVk{vD0WNRjZV z`pq}XA=@LqA}!R5{%1oC%s&SIX{JpkFtTBAWW(9PzYA`ej41(_GF-vtD^y6c(|JcLSWYjFW$rIPeWn+bXLd*j zr5DF3W1dt{h9?vV={Z|FD=EY06fjRp(+jHEC7Pn5+<9|l!IVDbcc{DmL#6uP*ey3| zHLuKX4x7yRkZswPIzpO+Yv}PBMca!-m$NvNppq*xaEkYsp!B6sk#vCC)4W%b1 z;~&<%PR>8T3+YtycK_QsoMeR+zzNsV`hRy*$N~^ zZ1&=6_rVwGgulQr_v~fG)EvHNp<7T34T$sU`M*%WQaRDX>K-;WIb^4xn=7L>An z(B(d;^$(-}YQ7SY-o5$k+%=rc&Y{o?Dy#Zi22XwpqXdH0+#(T69?7pnM=G|GMl!K- zglG*@l{u=ls(({WlDMNO4VlnYG}W{{I`~;N22awO;Cq8I7$sL_mJxP+KS}W9Us!my zcC^9amgBS)bB;QT|hDb7@+G)|v}PYh53tB!t(hFBxp_+%2~M z{3F8oqG(_mTDx$OK|8e6Qd9(*Jd}Gq#f8x%(g~mJonAaooi`zO?bD{r` zIAinsH2Eqxc`eOH??}&=SrWdTz^`k&B(ux9Ez|g4ic+j@_MBn}I=2LZ&aKz!-jPQO zZwu_lUhGHynU8XUKKMo6TT`)O)^Ao|ti}8XWI_916$EwIFR)h`oi?_ZG2|q1wH=A& zoaNYJSysbHXz}%wKQ~Uqoxh>D?MZElD8*%&*l-ckdu}2paSFv}J$?GKCH@IEh17gX zdF~@pV@v?h_cs?)Dt!7C;opCOgqD+8^Xoil&3{>>4;XH7bsY1OAJfsmjP5S-KUD!yQZG7YIgwIkIWq1Bcz3$3zO8A$UH%Vi>K z-cFq(PHSTG#^9x@RLc|MrksG*dX|(wn>)b!SHuNyKzQ~OV$97onXic1{L9p9zd1xl z7P1SAtSMOqR+7q3i4nJ^@D^borE9)llQHq+kt*|ji$Y?Fsv^G?DBOT-yGpe!wX)6l z*Q&lKaY$lVfXmF2_0KU&CiiQ6_I5Mu9{iGCWdsL!P54(b;n+~=A0{$-_TAN+SNS>- zu`v;~c*hU6i%Mc-LwVZC61)2W;VM(|&uv-eps9j1uGh7>kRtAH{-lc_In9Y!iWXvSl;b# zHv{;KLeTFi6>^JH$OJpJARV~cBkqUh3I>I7n$!`1O31NB$rf+W-jK`fX25ZiOC}d> zTT;reXf_Itdq>Psc-ut^#eJtD@dxrnCY;?+OY2rs#QICy9=B4n-Qeg7gCpeMc;VOW z?-EA*R$<5B zBxs5914`q6VNlvTrQF^(JY=b`x!%dqd9*e`_GD=Gf>L+;bSm>75X9mQn~YIAFQ{_$ z7i^W#%T`Y0S3U}Tv@&V}G?>cWCch1gztokO6Y|l-gl}_ri9eXb3yBnM?c=&a>X1;=-4izp>=S=v`X6$) zlX8C~Pl1A6rX}SKA-hU_)q+H>!Erblg&TW+Lz>(m!CxD{`pez_g6nH`Tom5S-;FTJ zX8v@)m%l6c`y>9=@(d$ac|;7;oA~r0;;}U`BwZD;iQ;s>V8z;kxQu6$$h0KApg5mi z=M9hUN%feu1< zd=8z~F*$TdozrSk=h##{`zYDtUYZ&TGVb*1HL@tUozzcrdPH20dGxAUblXgM-PUc^xuPRmT1mf!c^5->p*T#u zZ+L?IJ!q9M+r3%nLXM-+b}5sORE?Itl)cC1^N~X1NwlEVJOMhM#7Ns5B>j0rF-Tia zUYq3g;|f;V`tspMt{*)Muv=gH@ZIJ!L40B$!Zjb;v_S5IpBsf8inHE=J~2y6WtbWM zRzq#$=x4c2UQ$_VWCJ-x$E7Q6nt}2lBg-xxmHAiN$yS-~%63qifty12gZs7m1MPrM*5X2S`-!>7v7XtX^m5<4Ogk_cx8`6+=g_NC>P~6ci$PjW0f2*j|6t zNb^pfXmhx{^5x)wZdbbL4_GuYmmRlaBD1HMG%prUo|#Etsreg=0YC1xZ&v>>BbF}D zrAy(4?P}q`yx<-AEo`C`5NpCcFa|%$nzFHn*lVH>wnqg4dKaKPV7q#cl4j; zqe}M@yJSJtYxl7Hg7pH<6)(f(yc!7LLHg^v5 zbJ1UBY`JBKILno!(qXAm`H~#JL>sL%ia5l(p3Ti_8*f<#-_>PnoI^3T6xYet^I1bSBN!(dSpEb@3`1`roE&xMSi{C0z-tl z?lm6lZd1Q_FDl`Zk^{GR<3?(UAV+e!YSe&aK!B2o6W36!c#7cmYskm1WHtUP+8?=R z;W_22DVbvO)hs*<5Ae*eiGnkJDhkqeE>{grn@F9d8ni3x>9W=|V;k42n}AedSYJ1= zXf8j^^#(k$()cC+>_;wPyuO>KnJr@MXOh+2DvIaov=D@n}(zDj_%ww{oN zXHX@rCGP!4u@Kn5F#ibtc{@Lk-$jI(vXA!EB;IY#Ht>%!aZG>Lp$~qd&+-J{MF|KIRju!I{7|G-i57Ler z*Ysb7c<%RsdOQWj8-}o;hmrKnrL(zg{*$VK<`1;};HYWd?VYmg%Lbyt;}7wqcgnFZ zkzsBdmrj={{-+e5Mwc$*UHK!VM7vuFN&B1MldFQm3cLQ=R&nxXzE>HgEJ!F%sT>Un zl9PUb2Qjv%aw*nH^iCN95$)P_Ri9kdUXxriVTMwQMor>T(p7P3)^Xm{fX+4k9{iGS zK{L}FyaYt|{Wkz-T{D>4nThkL>)hB&hKT0M{-+~Z!~{%ImpA%`Sl})K`Z==$pxe4D zSUaN|CEUfe028xWKyvkr7-_}0uNr7 z)2Cu!kpIj5eH=H@FtQ;w@-0z+g~?|}K1I`5>FmGM!{D$(?J+9G*g^Lhx4|mJ`2$yr zWyB&73%?ftDopq{!euWlrQ8)i*H7RJ}rWR#qU`X7$6W*EY@b4|epaOVIGE)QBj9SSD_N*%8HpELOIrZ|=l_!Cv_DILzU>{sHJcB&;LX`AfZpTU+#6urS zGNE^K#6`@mV=f!~J1Us9UrfPJnr#kB*}R&s<4L8Bjjyos(XS}QuQb1a#IZBwe=+ur z61-pq7m=3lG+XKh-e_Mwq6OKX({Y1*s^J*GeRkERT|HArTE1y{e9Umeel6ye$iW4x=3lajtU1`<*f}~};I%k#gm=5av8{C?T(P2DekhgW8&36&A#&nT2Ftcz( zr5yNqk<7%51oC$aQX;Z8=p?u;$b`}?i)W98$Sx=~ZPrF*szu!gZ)O!ke3w~p4!}x5 zMyoy{j}4CBS^iSdBI4gvl37WwA>&MU&kb-zb>`M0osUBc+PaAQ*4?v2n?Q*_xzgRU zxRAbAo18T~xX#^kk#mS-D6h~`CEHRH&S~eA9+J_qGE?$t3dfx@&YNaULV-l=o`a6= zo*Th9dX{g&V}wNrXbi7x%@zQq^OTIci|0})$FKr}kgat_Ep1l1+j{6nj((YYi?FIx zA%J6L7iQKL8Sn@hx^W~2sIHJ2?w*vnxWqiCXBX-5R5pPklUY?U@B0bPa`z{3L)IDlr&*y4e5~>)uT`g%e`Ryd{i%y5MyAh4}hghN8Ap{J>sqatF613 zw9i~y_)tHIt$PKZfz;UxW-APsbVYJ1C5dXBqnf{^EH85&cz%!LxacCyHzi?B%vn6g z$G#bgl4MwbMaxk<4Vl`r4TC9-dtZ$FH~7Yc0i0aRpHGEs@G1-dV|hSK#eQr)bcEx+-tsb_gpikPNzqDTqrCLh%FpC z^AHnJ@re|0r1{%ak}0_^$rcH<+-F*5t&z?Hewm?2oDacwyH;IeDRmVL#BylA1Rk-u zvU3M-@nM*vCCPpco~qIMDmlJ3Uyt=2$Y+h}>VG7`(l7zr$BV#3?TFV^$iE<;x5?%m z_5G$Wz<2Men6`?CN)@Z!J~hRgVctC{ZU(Q<1P$Zdm2p;jl^z| zmGjy-ubY6cUyKh0HBxZvi!wvozE8#^Sb+Upa{c<-n7eCN-9q+usxiN*z09B6$cDBA zcVHw$5k*CV*J2DQo|L!`$Rb_pf7z7L&b)F8tXQT)o)Qfs&q{d!2y^w8?_j9-_1}&S z3~%3m?`6qsRd34_vdNr2dh%Vfy7=F9`l_C4nPO7RC{4whbZEnZwsWbLCuvp?v@sX^ zMxuf%MrFiVn_!D@C3m8AG;QBBZzmMv_N`Bx(kP>949$f7MZHRVns)ZAd{LkehTU+9^LrGQ*YVkl zDa_h$>UWk`&Bg2!;-Cw6=XEj;HPPN_k@`|ABoTW#b3}SELLq`8lD1FX?ai2Sw-evE z^+}O?l>EjYhcwnK;(v*=wacqf2h+iw(yGR3(uB;rmHFI1vct?@U=CDTkULQ6Q+(uZ zTgCsufl8es$F^_qzdcat|7u!k4^*1nG}9iabh$k6+y4dwptt6UvY{DM!^fWvZd!Ni zOrGGT;bPusb6#+=(%Rs8ScP^6H@iwH^q1V&^Oa`me5Gh`zS2j6GDF3b`BZRo>;v5V zd2mzkRjOJR-1PqqH#$$yp0%{7=>~h&(oB2S5@2)I(l6+#!0x(&YTliz=3&0PB)I9i ziZ?n!O2zs^-29er?72&THyQBW6pqYVp33an$k+Wrz3~VibO$#LJ9x7vxOvp&%|CJz zoWZ2ov7P3aGnjHmS$%=JKNMnNt!a}|g#$HbF==zRX-X*lZ`}Cz|A=y0QCX<4q{ug^Dlj=*&UV`KT&31?&g1U^LTI*KEut|gPUV7bMsYh-udVz z)j0I?i^C^BW7_{7SL<}uwTG)e*VXPUS1aw&O*h)3n<{m5(+rD>DKx>EO$*rZq_dkA z*t46=9vO?8lkZn81&63*x~cgHSH-$2@4c7+O${M`vCQsB+ZpGxQ`%Z~tYqJlt^GRH zUZlNz7Taiexlc49YuvGt4RDQor8AoTJ2=;v**3>sKq>5adu*?vR_-jy<1bMF{|o2Q zd?@YCoqU9pJCeE#>f~+mW31aHnC_GVY6W=Y4T_g0Ie=|5ed>A3b&9 zN92Jzuch-pnr2Ufy8y<}1z$3Ce#c%FU+~4`^S+o?4mK|Ya!$zwUovGM*VZ(9M%@Ka zhA;S%EZXP^`>_b7&}DvTRg{<(pBREjTQ>e@qNls_DnvgF8G7_X78V>%U#fc4BR;mXAo?iaIdS?9i)5L zuaAB9qJ1_z_Sukq_D1emdhTy=t2X~nnN3oC>QdKNG4>cPWH{3?qH(M*GMv@BJ6Gh7 zSQ@vOf`zyBMX5=&rF0~Ihi{N5i2K~>1X12-8h~e(z$}zt*k9jBweqq@7&p}lSa2Vk zuPJ>(yEqrFnN9p?4gZ%n-@yN==1Tr=Xug*JS2vgO|N7<+3b}5_WI5udaH?)?oSb%_ z?-IuP(w{%Z@A3aan{MYOO5H%=6d~KKJa#)5#odm@DYtXkYPaLBx_Fd5HZA+>X z2;p{qVtpo7nH(lnfwzBiw4lHnT0+!~xA%{#s2c}>W)uJG7@u)aZ|KV8^O`&Wd08fO z13%@-a}bjRJaZb{j{A30%FHHSxCvwkr$;{E2qi!f38ok8b0 zSh>w4>dllG|386pz?G^8zqt0EZ^Z7Bt7d3JbedP?@qsWhAZn!3V+BrcDs zpfUZWE*{XS3Zl98@gftO!JPt3!~Q_>Sw3?PQ`hj_(|stat3bQ z7fvw=U}DMhDC|)?dtPz#+}ZO=n*VI}yl`{n?0J#qS)4lBeD&;kvE~`swBvb#U;!JgEau5yx9oc`I7SP+$ z-co&O$T=)(&rY7fdjc4Q$Y0G*S@I=+0}KIAm-=@{oM(VCaXu{%i$J541piUd@!EiX zuZfmWN=v9w?|{f`eGJZ1K8F>DW`g**rKk6_m;##iLsRhK9D%ZcGSx6)S$25(AFJQl zH>Yp?g)TTKs?=hDtE9QAox+AS3MLQOqGzUW{n@ypwakJo-k?S)*kXqq<$*e3zDORH zpa@8oJu^MmhOGuPkNG?bzQG2ZMFod!gKtdV`t$J(Iy<(_6l?)UwAY4+9F|m08CzN6 zdAOJ}00VEt)+Z%w##q~uKYefhGka%e5jSukgAy1dhB-Iw0gPQxgqYa zZCv4Y-j{MaFLOIGU3%5=M63B}Mpi5Gw=@p-=ox} z(M-xL=05^IONt%@#Ej%2fg*{qE%EK3lq~^+G>G{Qg7IJKjVbeeTLzftf>6~&$KLOD zG}lmh1Ks;`(ETKj{a&|oX%UzXO@w0&_SNHXTnQYNc^s25*&ukeK``mZCc*%(&OZS8 z7`%eJ#METgf5z()^Zs6}n>rt_nizwH6qp0vQM`ikE?!y2uI6p&d3dG3Beno|T>xHp zatFVD5WLn?V<~uD173xB!>^OUYso}-tp~5`$KkaRWHgS!>so`?^#NYjPK4L`QM{6C zd|hIFP6B|(M({^6^ZPCrjsfdBz+4XY>RD`Dv<@Vffm|VC3~~kNA0QIe=kR)Fs>ZT% zj3nznHeQ+X!0pt3hbLgsep*!nY#X59$z|WyxWZZ8awDv_dry zsYgapNUEB$WIw2@Kzo6*MU0Z>m4Qg@Shya**|GIG2KzT9{>ZfS)-Hz|7 z0=Kj7F1KTc=;L;-yx8qrKNB0X5mxQEHIir3F&M2e7#$qNsI-N}XN|$63$OL$@vioer<4$C!JOxrj1DK7;kFIxKm-dF^IJVfR{m5$9Vd#1OrGd0c?iW z4r4rY+_MtQMknT0mf|r9&ciK?y2?2MhKZMYI3eNp4(z(>0^CXqjm7P5?!m2ogxeUf zvcK?iD6fSZ0dy6(eVliHFmCT33!XQRbU;< zH2Dm-nl)@osL`N*loZsOY_J$6G{->mpgyLkeF^0@azfO$#Ebe)=Kfx|^{5Oj%1VkQ z_j*HyOZUpC@?T00Iwyly4jD_$(P|sVq4GJyruJ*uQzR7KX*4cKWhBawa$Ze;+w{{J z#!}x%r!{giAvgJyHzX^{%NlW6PjcC3QAINOyx2D_43k9Mkfqf|1J{K$6 zRhg&GH`-MOi#v2>`&>=8Hs+eQUpoQbi5&@04Q(Vg0KyQAUI_8vK?Bm_-?9K-cJYW! zTfb&PG@cN_JJ{nSIC>e9s?G^%p*r%k=u?IL-ZoP_PYwYBIV=c3($D=w6luATBC2o< zMOywKiZqR(h+z1`DUy6Dhi>LUcK!qWvVScOL7k;ToxDa_q3s07<@-NAe#sG=Q9(D`t3PIwjM%F@t2AAyBSP2EuLt z&r>QtVr;r!KUFeHi0BwXV9HKF1)h!}K`RwcKmu98RywgHZIG{mdF029Xwu;i^%r7( zr%|fsBcJ&SAs9Kyw9S+;=(n?w-zA!&`GJ7@1vLGqAirTkkaG%debE>>RwajzME^|k99k#0fUqw46R&H}R9^j} z2=6Yo=+ zc8lBb(BBJ!Mhu0>doS!*e4>txo43X3n6?zum|oE&uB%&%>7CYNwU;=N{RMcMZJh#4 zC~OK_V61^mLWjkC)OIOT5~U|cd5yDaZXK%?c#+pqEs2De~Ur^Yl%WN$Tv6CdfqL>kOG_-b{owX}|@dDbF@D*`%s< zxlZ9Xy0wH($wRV=PPJUvDLd&0@CEcs0?zhp)%pGUApNSh{i+E16SMs(qd&{(&o|T` z!aC{o<+NKi%51hvx&8o4b@C@;SuUUqfXZ7&kf5e-bvb^k;F*H;8Vsjd@YH58v(Kf(#VFMe}K#Ha9Zq z-eF32+_U~2IBlDJrZz&jEd@5<@?z*mO>d$!@L$D z&ESbR$)n6!{nwIBiMn8n{A!xk8UeH>sa20~60TuYm6{pWEHX?_%D}I&Cg121P)NS# zjqUS^)>b?%+t7$~Y@eT-?w+ybN2YK6wOuj_@sjna&=u|TLz&Pl)%z1uhVF?zTKO^_ z3~O)EWP?+Wz0F}l?enETE^D7Jy=*W-Dj<5$AWW1KW4>mqMoiT4*EoITIlKS zpr>F>N+Ou?*C$qjtWx2lDbWaORt6mh6HXVnFl^Au2V*f%3I-a-VW5=WH}bdAVxTmK z0ZS;ga2^I)eqRQFo@IbYVD@>85ZJ#A|KWfEEa&7FLg~}QJg~OJ!?qejb=;Zi;V8LR zjqPky5x@besp~IZF^%dVA)>-A$f-Gj2{AE zpaKk#w>#+2#G|1lvHJX>(8Of3iIb-$8VaBX=>4@}ka6c&WY`s*G0eYqEH+|b1Mw!a zC1Cy-{VwN^?NMU>nC-ji0u5`hr|2oNfZQEv*YXXV*%n+(q;Ap zgu>R$zCZ@#Iv%0p>))~CO=CMAr{k65Iv%IfmHbuPj>mIEr;~9@!Si@tcn}rmm1y+64NyH(Qc3ttCW3D}c^DJ0l-jVJm##*I zU_^2jSjSD|w4I8tbtQGP)_Wgfo3NTshpA%dZ>~~Be?K4X#JBloY^ViM1BOG47OTN9 z#f2U;@%|(cI7@4+A)$6KaeZS~o5J0k6)2r|Pj&ePgFujhyf3?}W3Q+Av6$t_4m} z3ESf)aD3Zj5E^CaFA7p7z$RaPP)LNn?r9)*=pbD*zR_0P6?!V|X^y zvoI&)lU-va*r?X(o&Zv^bWsfy!HQXS9b-+EgaPt$SiHo2q)kZq z$XJ30W@Kd^qpH5tzzeX|0@fl{P1ON!1Mtc;0p9RCz*`mtEbNwuGD$TNwj+R9Lj*pS zP@-;U14}5&*8_4nBVZLCnVJdV4e&~yYVc}tT81$sFXdEg72b)I+o*|@)`LG$;GlB1 zcAE&Mby}FZ9w5CwjiKZlUav+G<=17ZbMU#qSD8G6gsJl|!p4jgo@=b+NBvl|t;=hQ zQ8{B{f2h3)SwmFL#U=nqh7(7*v$TAUZ$LxCcnw3rVp~vwK(4(cmBF^DCPs&Zfk;u? zAt2pIZ?K*e&1C!Zs`~5os9zWxO&9j9+VriFzBP{PTebT3ALtUDNuD!Zp>wO~S2Q~^ zUAPKNN82lF7aAk-g1*r&^$60hwEZ)EgKdBBzNJjxR@1lDO4&$4ta!hrWW5&{U>x3Hp{8*SGM0R^JQ(pD_6dcI>hx9|nLc*pJZ zNIOYaN{5r*4GL6fKS?g8HpPP)?Y65Yj*TPk-Ok!LaUh660$n>-loO`1Iuk2S_SsC$ z^={|QVcy4?K_cH|lwKIzy0u4cEsa4$>L8if0z5W)@RRQrCK ztC1)Snn76Kj51x6$o^d0NKt+((6h_#oUl1)ofy}oX~-&8Z96Yh4MthfvT6=dv*NVz zYt-W0na{CB#WaL7%J{5SRM=rlgKKTC(GfSJGZ&S+__RGHbB`1toE8PWj3AXWoceiyrE#tN-NO|Y!oJyVIOb1J`nTc z=G1vbGy0WOLX|BmS=j*pDff0|FoWbEBrxTyA_gd8BB*Bo<2dN{8R*s}YA}K(0?5ENtS~k6MXWH`9C&L z@~F;C>ns+z6N~_U9*7eJutrTYRMjp3t$sZZK(K=ae7+nrKpNc&22Jt{3nkzhw60WQ ziP(P}k$J5AyAa4;b^tQ@3C%Xn{C~e znub42-fPMsd}D0ZHb|Xgnlk*Vil|=AT@o}G0oIscwN0vVk5DPo?0v;*kCxx2N!y+pHa#5Q;01kC z)iz%I{4$xJ|3SYU1f+Y_7K zgQe~Y`7UHsHi1N@0@`tWocu(Nf7;^dO((B~jclZFyj_R7Y@20iacLpxvP{l`=p8}O zlM|rW$&;|$l$GqcR#%LiIfXVk5TgdbiLXiBDvb}K+Upp3S z90m%$ckDC-xt$X)bMyGz0Nnbb_DkT$)D8->zICVW4X)burNC812LBts%cCxh>(NfHeNp^tU4~)YeJkG;#*wn@Jwv{Q@F{YheOtA{wj$mlyr>*Re=@0y4 zCL+SDie)OM$WM&V9%Xwe^HY{4K0gznPI>!(G=;JH^w;0dl;;&^h$0F9RWmz{IH!^? zIM4G$E2I!?qb6VF1l@rqvH*6>0gR8u-41WJ+i~w|um7o|if2!HeOC~xg}dJC`W(nh zzMMSiD+{r-c0BniZn$o-X|fkuR(gG3C<6|{oCu)BD!ddAv;cI!3?YseeD<+ z;iFQ`>1vM=BdCihINyags%CGCDc5DoDL-#Sk%Tgl%zhd~nKsm1n*Q2uTO?`%zm*BB zR@PdDlsk1k)XM90?P@m2w5?-*yT|~(NDiU>#Iw3GSPb+-iTm>Thj%8{i@>)H`OO8R zbCb|k7L%KJAwqlei_HjKH0*!kx0vrx<0u<=dIGr?ar6L5Tc(Wx10seckat+*@lOLr zJRna+K%TI3I{604Y@jIsCOGHNYd9+sa8BeHDlqvC=y1|M0~MltGz>@)Lxplc7)t?6 zPf?%(Vni$rz%W7E*C(GFW2ofE)p`1#FU#8JF(;FxGlMWmGLOJYn5QM>vF_DiUkU1^ zeIEN>0@E`0T4k$YRhoGinFEq6It*p`h`MK$AlwZSnf!n|dC z!=r4gYwJldzN2P*@r-V{T_L9+H&XaS1!-#J>>noqRbnlE(oK~tt&MJcZ(QLW>u zy&ryy!JTBi_G;&Ohhk4nX9jbWB05=-qiIW$gIrX@qWw!tDL=F`0%nJk)WKgo`)dw3 zPQH?S2F^)1ud$d0$zsWa!C1{`J2)hN#lQ zguz+N-9CG)Y>0}H#^zJsnRrBiE*svu*G%q-F9>b*-#|Qkndjc3V$mClNJ@z4P&#&L zrUJMx;t;yz5Ia$qDW^@s|HN7EH$v%z1hy7CTOO&Z!ftmg!yRFX8;5E!9c7L2nu;(j zfp!qikSrkI(}p_7(ZJ52SV6#7TKj{LDK^2ESLN>tnOoYZT(t;Im1dOiN0x zms75kC*F{u=&&f7d^Pz-@)f94By%o&SespRA#@~xa0jnrg>^UCZH6d~K^ zU1VsM`z&8DHHXc zUV^O2h0eg&m3$xN)xJyxYJ5LT$%BN~GwFwr>Xi5Fx}(B*M#R&-7-;B*e z1ssMAkj1>d<{tL<_SVv8?!&}n9hx>UGD3gjUhj!Nr2@npRdi2{bB!6{^dNDn9V%d- zFH(h8!|B>%#%_s2Marabi}5C@t>-cJ0H2$heoR8n1g{H9UaCC%fO94hVw}Ks-kG?f z+EmWW>4Fth)d0o}GC(eSZtYHBN|y%vfcI)jTPADA9L7zt*D$gSN%np2`78y$_zSV{lD%8Ab`}`07W7qcN$#KriJm<*Y6(7$zu{`I*a-0*ld_y8LaZY!hb0Xfp9Ot|bPKlq#IT1MLV8A)r z=AX!OPfEQo+=EMI4EIPx8Hxu}q<7d)d@&3~ofU?oMkV2x8K5=c%)a8Q%`B-FNqbeU ziP+mTVKx$*J=MhxHMNa zDS<{Sm1S3+5@$lB^0wir?#_?r1*!yT_tqD?#H>3LefnXi2tRVxemikg5A3|GheV7#ozzkS}*_K>iOmsL`k_V;E^T{`O zRLLXha@I}QJqpi$7(Cf>Qgg} z_$&9`=y+*FsnfL=6z}W|?>DFE8K-c1`!nyhBGNnXaULNb${BHCb~z&H7$MF}-hTfl ze2hr;4m5n&6p66he6Z(Q7$4!_HxeZ|`8!N5R2>^PI`1QAb*K zBNdNe-IdcPMR?PjE4-&oDu-80Du<`?KGJ8Cq>4)>e=K_ssrN{==q2m3?neM+#(@=txaZ!PeT{W00XEZ*oE5G?ZSoBxN%^R*S_`fvm!}{9k={Y=Tdsum6)ul!$~^gCj#dk6L6mz z_OGzn5-^%&0sa`d`AgnVFy+-2i+{XV#WdoFqqwsCy&yd5-^_tG(~?<}2LUSx>dCDe z#iEk_e3dq;%{y;NNVGOC6zZ(>J{>X?r>yUtrC5!BuMYmJ@IO`pUIX%@GP?}uU9np4j5i|E~$i! ztRYK9dIv;he|;!2jWPLx zcE-XMHD>6Tyr@$qe#=|gm$6>%B?$49wHhVs! z0=GLu&MOS8YVTADj>6qYHazf`|MW$7V)}|{SjreS{mR!<#kUl zEhw15oe?{GU&Uhep5hF%g5;aLuSg#Dx|=2eJV93e!08u=!SDW#R{5W$YswEC$2Z(7 ztCKwVoeRT2Urx)cE8WxY?4wUZ)KV`bvmJW3wLI(S?@AL)!~E9kYM4pKBD1_VikJ&i z8du6SUe^s+l2BQ*qOjNVKT|XSm(Oro7-C2fuP^x;V{6|*1>3wnOZ}Fy8TA-THzQhQ zZYIsx>D&8)2I0dCjJX*#Ng~RLaibu{Zr3o9mk+~EACxKg_MNyy$bNl&>UC#70%8cMa9&OJ8BZ!nPGLdZJ~m?A1kYzyi(3#!vLZF#cFDE^ zpPJhO6Sy)p{X|NI=&o_R)tPtJ@isgCl{oLTDbL93+}yn)JwJudix3h7Z04Bw3xQ%j zT&*E`ASl1Rl~=(WUX*}h6il@3Euw(3qi)|#fi^QUFI5`;I6ao5xy;=zdjKPrKw+q$ zRk|2lA1b1$+5V@8{f`a#q5G}h4uM?EbBfh)4z3pOUJ{2|1~#l~+1TkOp^s7k)Ojx% zrac}o?V#5q#^g=4_p;a*7ClL}SFvc1STsoqF`{$avL_`I#Im0d!;-4QvSyEAP35Yp zq`YNIwN_@%L^IwhfBkR$jc5J3kiWKsHMbo5UG2Rfnt~n$?K5A`vEV8bte<1SqcV5d zzQba>pd+-0~jE#hr37F(eQGw zm=QM2GSl2I_JczjoL2+(+h^EM7H*FH>J9tVnE>!{iXgX-6S-#=18n5X>_B8j+UJ7` z>+_w^3=O`?FOyPtb^Cm@hy4c5zR+|HzL6#{ORIn`W2~WlJ{rUhfxKNhb|o=tZ0Y&Z z2Jf?%Xpc*BE%4M7NFF9sdaN(w%AhZa_W799hW!JW#`Ha?TjD=gp74<=ZCPUP>SU==N<;N^z#B{%;QBDkNH1AC< zr$%LWZPE&cj9X<4E0>xWYcDTCQZ7U@+=fQDwaYuBEIZySX4~?B$=)++H78FvPiIQr zr@@;kc`rXq>#s`=WJ*42ym1ldh+XlM%*G>NHP0=nz?Ak*KSA4Ad*1VZ{s9TV5TcD` zjOV=r@59I7J*P}NkdURnOo_aoa#A!QD|nPCnUy@ngA{&*ndU`>cilG zOpY>A4|)49MW&!S5B&vlgdJl8)D}H`6S@L(KluvZD?@sendu>KU|6U)eARV)amG9J z*LX+B%-2#Af^mO6v&0sk=7>Jl2`fF2g+ih%9+AsJs2{oIY3$_m+c6 zPQp%+$2NDK{k_BJhf-cH)BQh7>1MguiLO2 z<2Kpvcf)pZmX`Vrt96UjjEAsC%myPiIEPRt+Co-u@}1YPCr;9y|JLCqYvz7 zx$ZzZ%{GEhC+EOprUCNtp&0+kC1aI?6aoGdu|4{rLOVa9h_)g zCVkL|KG?VdrcA(IrRW2bL2|4nZsi9*Dt#ok@mdv0;TGZ6FQB) zVg?dRQj2@M*3Pp$Q$qf*_f#(y33oA|t?-_?pKOvd;7$JIQ;hLlG?Ax*9#Q+dCr{0Mh#i9pkKqncjW{;X}4^?~pX52Dm z-r?8(m6_vf^3E51NLWy1lukL%d2jxY#SCigxRAg{GaB60AnMClohwPwo>JI_y@9pU zfdEf|cW5@&E2FS7dB{1yU@h|w4&WrBYpLXMN6CfioF5~llh0AS0Rb&_uxqy!==DZ1 zTwy#dje1dR94*(TA8(aNf0jpJtHOx&)%KIJbRDYRs)2Gjz8_8LMUz>hLs?`>t~Dwm zs_Ft2aasD&IE8ou%5qvEhE^~YpOu!NQ#rj*N;#_+(ncjf-FW(u9|gKZFS~W9NOfVl z-RO#df!*yl<@AN-#Fd~ljDDyW_h0FMddSA%SpCpohQu(%>ZKz33@djTRwf+i9D%I+ zGi3@y>O+D@%(OSoa{ejj1+T|2@Ik}CPa6idGmHlR<>YbipxDx3?jUA$PVlu{KoO2E z)4U)?nL!p}G@(5qre=0=I0*8NdUuD!2}BF~_x;w<0X#Keh3tiy5NB<0tKb_@Z$hiY zFFcC-OV9cT{EwF;4{Axp?gi;JEU0CZIxi~*WXinPupf33PpiGXVnMD-{pY+>hUJcU z2MjYlEf6%tHq3X(VNI8j&aj@cIk`^2+Nq42W+F<&$OcxI19KmE;=I zQR5AT>u3nG3>m2%2-E#j7f4BCDT9z2J5$IxSL)j5Uy`%>N8L^U=C@3#2k!z#e%tn|%^VJ1#1?8n7a^=g+Ohj#%(z!~L1I!TU?bvO3 zd7l(kKeG_4iP-ECw38F}xhmMX#bwTq6>Xny{aBQz-f&Jupe?KqUi>}!skDUolnKe$ z*~MrHDUV7ikIJ@T*WLNE{LDgHLo*BFp)@RZCRXZ)uqgdJoLI#V(+aN~K_6T+phNQq87hUOX46DHHa|Jn_p6sx9B%vYFA>aWADfn#3(t3y;EP8%Sz3IK;98=wEa#>F-yK08KocJtrsl`tDabcFv@BrYCv!6;#O5j z>quLnP*5xBU8`(ur7RufCPgL$b(dM1fT)yZoghbRt-9iqO7AkO6ZFx%ZV_MSCP%B7 zr{vcr%$&+7r`+oVU&zU2CNrs=YBE|2S|r@ zoUe2aapDUJwKM$AG{f6#czqZSPw*G<_8Ojtv!oPfu>##E4j0dRJ>qiuUl+K>x(%oI zF~iYJhZ&AI-s={(+Zm4GbO3N(^9~zM-|IbVIGu+1CJfWEdTlrzelWGh@$q_nhST@u zIX&*Y;%IB&N;5%P<@9^|0zR*iQ%yM*$0!%e$meB?W=x( zuNv}-V@x2tnIqWm3xn@-QTws>T9l`zB{@Z9Cls|siU-O&v-pag;Cb~{-(EY-Fh%aW z(Siufyf!gw#5t8%*>oPZa6Gg^M^nn^`_?Nq}>?@(Tw(+)V!foy zHj{SUINnz4-niWOyn;6pLndGUDnv=d=Id9Os%Bdz2q?(cpZfoOzW(S0`TFI+AVy62 z`tgl3U{Lk%kgxy$F!wIdaaLEJuk9)u0fH*%noyyuNlm)aQ=&AWfRczrO_y!iDzI#X zF}4iCX!Uq{`3oj-=h|G8m>xMY!Nuny>D6>P_g-?_vu@@t=7zq`3~47b$;6V4UpRh+ z0EW)P-FdW~c+xgcndkle_xZlBs-%)FaJbzptg8AR=j`)8=j^@DKKtz5q1B7n3brsL zM8kOfZD)$t-!Wml{x*x(&tdX6>*MveGvD%IynZ`oeAamVnYwuWNv20?OuT+u*_<(6 zf2-p4%e_zt$vYu`e-N+VB!IRzG|1Y_oK>}FZOX0G02(I`8Lz{vw`ok?o6*UN)zLV0jG_p@h{2boA7bn&?2 znNBPZa0;799;709K)5s5aMqiwJjhH+9%P-AX(SI=Ee57CNrh64Jm`dw%y@aw6LDDB zQOM8H{v{7|sw|WTX(ta5LX(gOyf1m6_d|Jr_s=Bdfwm(;-n-~b@*vNH0WYmxBEjF^ zkvu?tylZ*T_a4cEwt9J>!HqmZ5Y45n@N@)Ioci3_z98}ah z*8l0)3$_@@N%4PQsHqe3HYKQJF=wp>8JIVm^~e-(LV?*1!^eu>&qv2A6RDQ~hk zMa(br_u1q!DzNwPutg#U`y%DyAHd0_`EjtH#oBR$VBYpw&cNM=|JA}j2KgscXpJ|m zA>J5jF#T%@ zh2K?>zpcAg&=FmaK<0QLvCFpI)&*vsjYjgO+#q#EI8Wi3TAVj?vkvEBE`akpz61e^Kyr?2{hPq-C%a1 zFC(1eV{jG=tHW7b7My>s>k-a`1SJs9w%cw5X9ZaT=PSYali>VA{oHcjqI1Vt!q77j z_|C*1xfX85V`1@X#`10838)LDZ?6$-A(4EjW{NVHsoldy+B@aenvA+2OnroJ}(uKc2-{6Z=lkx8pAilP$Qg^AmPD#$Tx2=#uxAb5y#f&Qa<0$WiGTa{^&0FQe?o3a?VBeC6Ai z;cO&S9hJD=#g-rTM(*m=bC19D4gX%eK=1{TV+i{JA7E3&IU!Y21s==t5_PLPsNQ~0-r^PdZJp|HqK{2U87o_ znXne@n^7&j8|UMLg0WB=@a^fbLO!Q`=Y+mz(?(h(%3Cw zg?3lUHIf$O$2OD}=4fGwmYKT;jc(jPrJPj{TG3nXU7-fnb|0M=J4Kh`Ao^TgFV^&+ zNzkYVd%^}vlm-o4*|33|TmxAHeNkU&;A5_Vtd5p6)4=yd4J3k86#OO}qJKaG(Stts z(V$lwH*j&#Kr4F7y(`b$gX4#%Bo?g*dJm?{b~2Poq6LjZEHXSbd|hG;$O*=(m@3bH z!&)_uHOLpgdXxkN#h%7 zoFr=GqOg%atTu9W!ybItwG6HQi~34izv&vtdSFQ~JR9`fl{9S8_(qATSYx)`bveMa zGna3p`5%`m!4S2gx7@q>-8692wIt}pzOaGPnS)+jJEnnj=2y52mGndp4b(3h_-#HQ z3`KkieB`c7G(+Iw0KKVuzgj8t+! zBNdM6cEX|7bW_Jg*NthQNZMqfu4&)`8u*B7;CEdE(SVo0;_td5YG7xB23|!2`)T0y zXKdiIpn+EOmV4Jtwt*%h*kkXZC0hSi=ivY)qGP$ac+@pKMRNxE8cs*oz|CAS)pM9H zK$D65jURUA%G&*z<_G;>qi@Qx#-r`*(wJ-DN8O=Pcp<7?xv;Z=`_+FK}&Xchiv z-jM5uJ0I#jV`l|lbXumJCe3-z*jd4Q%FG(-7mrPrePH1{=-l=M|CyB1h7INU7#cy5+)LnMJBW*8-)}|51 zxzw<-P|d5pAob8x-Hr2SFmf_d@iIfFXCyY=6CD|RiSb#h;;ldNeXgLbNz~Lvxs(QX zlxs_fT*cR8eASABSTtEe#}sShRBuCs6m%3Yeu+EA=K@tTJY1;iOkM$ik5xLa4GJQo zf?95w9M(~qO2sUtlh=!NFl>B$8yEhBJuDp_Q;ZB{Ah@vb6TbHch04|D5tqZw(fL72 zo|V|PVjA(ZP;V?ubz;k1ak&7wTyfCs2$u6geR%B&Xr@Rk@V!{z7ohnpUM^yt17%I* zYBlV!+#raJA-h;Z_COukn|WAsm$K0lOX!R%(7!BnHPj>1?~;=(WDoP;J15&wBn6hj zv7q&0oLWGyEnYDhw7Vc%aog;iHeu?+;qZv*!Xg{mC=}ar2{r2$I{?8Uvxr;-Ywb=fiS+c4izn4H5sydLb5fWmFzs2e24zW-r#v1q_tMt0zNtZ%8&Yuc|{^ zDr10lE3~3auRyQyrRhK>Ch5C~7p<`^78JE$(qvO48bmK9!3CHC7q6WRv5VY@e)~c< zsMT_pj}+op!$qV7GKB?S(3GG7Sn5h>F}}1Ih({?|feLe12C^p}+Y@rX$4vR7NNjDr z*xDAzuDNb94d`VvQ)?53ALQ?sqHwt$DqQXzi;V@Nr z4b6y4FcuDQpcZ7zo3|=QYb3q%npjEvx%sjza-PNof~*v!-RO{A$^^dx=AFLOe`~y< z#(6-X!fc!`CBuUI@@m?|e|Y{O65%yf+d0>b^QB~5?^GGd`%qu#7++KHf)tFfmUiSm zO5FrXLhypL3KvIs{&d=yl#-AfIz1id?np@xD+!c@^(SPMU=oODn!lRX50SrGGj}vu z@NnjzHoSTaU4QU@I@Q{)HdgXjI7nvj*wr5#GH$ucaoWjVBF6t{70+sXALTxs4_WW;kM)| z>kBH&Q5o9~N|Uw>fibs4C1PX5e56(XIE{u;Jt9S^BLdlKu}@rlyyv__qHgrl7um>ew%51o&!f+#$0p9W2@YcqgrgB8Ln2q)%xDg)W%x}EO7_PQ1+M+jWpS03961czmQtQT> zrccbJgBQfsT{NwmbU-NN((%NmPY^=J#V*wx+A(xO(Kb73S8iQgC@DWdFVS2i`Yb`g zHZ1f6aM^N+=Td1#md-FHcsG-LCe4%)FbKI_X|)jG$~7=E2m#)a*mfsOZYj~iW!6V? zVk`uiYTASJkKLHNXXd27lCp&7VV6srf>7Ym!>JkM^Vz0k0y9gDV#x|uH%Y!!awRG) z#Una^PH8ZMJK=*%nr9|9ByecDlK+0 zNOfrhWtg;UD)Zoi;gb!rLdYb zUkcG~{o-wRCj~7IcLF<&+-BK5Vc$9C5(uUWirQQ%;Bm?^ZJ0_*GKF(-E|8mwtQp%b zN(V3GH|mraDZe+^=G?~a=^Vdf29`+N8T#Fa#tO>FQnlQUcs^;Gj)kZD9rra(v>ny> z8+URooVh}e)?{f-^))7yJA%EjI|c!ZAf>gssY_l#jy!85#a41sWhMMbfzg7Tif9rJ z4F)*x_5hwvl>kS8h4Kh0om|!-0VA(Lq85eF`IbB=Qz)ql!yKtsIx&XeF~dc01R*?# z!ChrYOx8kShY~L{DCPh~ZI(q24Qt=9HpL=`O#r1gLPTj6H#i_kwFn~GSw+8J(F7Eo zHBj`_Ls6`SA_)|^Iw+J;QmGY#w2H|P3K|d{FszU8NAaX8s)Iu~oFThpFcccJKRkzG zV?_bOgS}Idv?%vl)Lvz5Y2QJ<7K>F+b!oI!+it{@ma&`$kj!Ga(8f(aodvs_i%yCd z{<9`a*Fuo1OV{sEJbUiwARmgHoIw}FE3Kqi;WnITu0jkUWXQ3>1(?ZPx$2{deipv; zXU(>(0dsG^)DxzyMHixKJ(aRaDzD(2Vxg_X;nsynGsO^+b1@5(_Tj>*k1l0j~$k++jkN+Cy^1#2)* za|D`8chOvHn^eqwD2(62cJo)v3rF7ly^7_Z@s*S%ZT z!ys2c7~CHuTy!0s;js)48@ow@aC>c?!FkpVc96AJsut0p*3oq-Ry@l&)U$-dmn-=k z+MV4^hc-!lT0!`nA|0&|z}YbVw~_-XG0>ey6I<>e{Ke%51_RJpwqQ9jH!s(6O z(P=(T@7ZZS&Y}mWHd5$#c{!5lG~d-Vr}E?8c*TX{GHmy-8ihhCaLB`NK>@OMRs=zcNHLEGj};h!=XFu z+z0i-Lxb*xzVh5G#wI;Iw@CFF;;303?2ht71MZPFNG}fUo~E(r4%zAbqPy8{Zw`b< zaOCbiv@@=Y4`tmGsqz=!2qWg>+ma6s|7}PhpUL`6z#f zb}5KDp);lR+&`*Qtb3V1E9mYVD-b)uI&KBBn%QJ4kVWrm1;Tc#Rv^9A6-ZCG0>Kn@ zwiQT!xB_A2VQUb#{$M4dSOz85AdEFzg=ohrTzho6wMa~(ppQ}6&sqeRCbt6Vt*!_{ zJqE2lT!AdI6$ocHqZLTkyI6tr*b2l2aH1o_6;CxvfGfRz1yXt!E0EA%C|SD#8GE?V z{Dlr_jBLpLP#h+#+ahpC|7q{uzC~nh% zz-5n!<^)})6+ML)6t@YBAU}G;xJ?}vw`mcRIj1_^isfE7=2|$W3uIp9m^Z^QzqFak zr9dFcyZ9Hvmoh1Ih_uhkhzYxkB+BVoY-= z#e#;oSd?b&pw;C$t87n!M|hHu8y70FE=}g7P>r8-+r-DQu#^y` zr}qtL>!>@Fwdy6E$-<5ioVYp=ow)ijC1Yf{%-gHeRvHHS`7wI2qxRet9o8Cq-p*Zh z%HDEC;l+C6##oy*FSHvgYlW4Cd91K;U>GSx45{#AZklZza|$YarI-oz)J>M^i8@ke zMnFReLQT3XY2V>2mEP( zF|4E5t9VHKNr4ZOGc;0&k8AuXJpq48Y{U40jYUhU8qVZGKU?BJW_!NUYU(R`YmqsN z1<;s~znyVX7-gRA=6nP;mgIrBIA%*7%fh; zF_kB!+cEGoQ?VeGyN^jD`qoL|kDIjd2seurcCdV2`LDI*#iOku`><2n-LjzoVfn9z zxve#oP5g4VMWFhY*>@F%6Ot`7hq=vxHlgB3!T_^$v3JOnZk%GtTEWgecm!z|hAf9v zO3`TL3zeaFIurN*&yY>@agE4>8e)SCqDnFCulTuR5F0e|dXMrzyUQ8ll}?&1jii#! zGuA5|)A*t2Hox~orSnRy$uek($Q#U|FY%FV0m_l(xg>6|R~3Hc9APcDvPMS{!>t&B zqC2t)$1L$*3$~EL^)nOZ5*ZqJx^3gd{BjXc0deC3?2{O&E-gGg(YDiq+Rd%xMpnpY z*>+l>iR-qV7HEQ|G(l5Cr<)U-o{uJ|W@hbLOzXe(C&cWTic^HzCUZZQ8?p{uxaIxO zjx2%d{;g2Hb@9;lB11O0ggM;D2u}l{Vq3ROr;x-4y0obg#;0>}>Ab_1k7=)hc_DS3 zaozt7+90uoGUwB)#16gGA|7XAa$5-ub47+5Y6J#=ONbDP8u4ESsX~l*+@>fmWt_Df z{~emmw7Z&*PF$5?Qc$T-NJ*FcL^^^F&vKA<+YL)|DNQ@Y@7`1#G>V zxc|c%y&E`%3<)|3On726kS>fY8#r-bTn;_t66cIm`5W0$F;V=E4$GrNQ~y~NgdQVrb5aE~W8&Wgjw zWX}9aV4aEl{^Ly>WtoXzxN#Py{&)*Ct$_HxjTmWyCN0VhIHE;zG2W(mNos(Dv!scAz`ZXHEfDssQr)Tjyd{jw@* z%i8+3{B!k7O*8*mnNt&3_q9gE;LV zLBICNYa05n+g7#-V`DGbsN)!W&UZO#-DZlZZ(5@fsBu>vg*E~;-ZavJNfk~e`h4Rw zHz;}Hoy?}1#*oZNjdbquwAIx8VyaP#YKP(`+lq~vCKreLru}mbNSg3nh^e;FQSBGg zHBF*tzVBMC#g9gubQw1?xi`$ksA+rn@h_xlq*8$xT6l<$Y76N+>322EFjLdkh{M}} z{2>oUP5Y7Fs$=hy9FVx1M2uXVG4eU4*Ux=Gz64pc>4ZKWb0?gO*+wm@ACSjtnUvEoTR1#(H4O|0B=1PMbK^4VH61XkX&PHTZ(fRIt`*9^WpV7f zRJ%!I#qu4rhb*C@GV+J|hFa^qp3EOgQ!Mg_YU0i?7c734wgJ*EepgD0B#LM@&dnfx zS6=bEy8h(4IoUPW^S5nH2Y-ueuHkR*npXY}toZ}}u3CdWI0q$ghHNY6`A5p#N&k=% zzwIe^uR4A^aFINi``7bWF|ox=xA?qd*|{p>pfW(-P?5w&X0#wB2<0laLY1uqV8?pW zI2N7Q^8Xy=HAQg68H8ydXCW3}irm$1k-OL*J456y?Ra&fZ)PlVS4YFhU70gQ?rNPd za#zM8cj2V)W_{!?nZ0vibKyy0kVs>?+eWl05>@w5R zO<9cD-S~m{YW_4@xB^h%yh90_PfOrI_mit`;~H zT_jcWXBYW*Gx+WB!($eMCg_TAJ5WbuL4ShH<3(&@xeas%$JPzOt}%OpHM_>qZfW&d z?FZT(F?9CQ)BTQ4wo@6pV!ZwewXZMcNHT&&Ex8Vy7n>U{5sfrsVlu1MzAF-IiE0W6 zg6sk4TM@y#5_p%_q?0e)QUZ323rv9;AP3K}`m91z?iU zm~z7av(4jc*C%btK)oN1i8piAcpuJdDqsz;z|JjB|Q{R(&fg`m6{Qb0KZ z)y=9jL`wUt63LtbVRs%Cprwt!Ym}v-o;%7W+a5Lzb3Do!8X#r5+5qy{{r|xk%+DiW zbrJglU?uPt#kDr0p%b#Kb|RVaL5ak&xx^t8k(75N7vn-8QHd!fyM*-DgMw}gXGw1( z$)_3O!q_I2_9lgM=V65DEHh@H4c0h#$(%y57-}BeOeu(jUV=Wi5z~3V#~<_kB!6-~ zR@m=SSC|ydqR{-qMX^KJS7L}?w~3)Zz_L2ZEJF>5lvdleg*#HqTrSNFrRMs5$kH!7>fDAlj_fdSBtBWcrh5bKC z`U-aH-?|hnq|bTnxHlJhY&(iR|BtYqSxji@2$;5+K9*wI-{%ZO)qUFt-q8ht=4zWdE>;drrOJ`kzH4-mFAj5 zy}cW|uAb`ZrK&~Nq<+`T&ovu-0q%9pqiSHZx?CgueUw>KmBZ6j6#|-q$V?Sb3hz_p zRGU_{LiTgX39EeVQh(ogOvC&HeH*QXjjGL3ZC=#|mF29BpG#G?%37)VsJX5a1A|GB zVeBwPM}Ud~Yjz_zRe{`who0!DWtaHNB^f%YT2H4e7jp6+Zsq7_V%yc`KD=dikwcz| zZA+NSw+xWJv~bLAYQi;cN+!0<%i5~0@oFOPR4?a(gqiHB!f%-O@`e3iV#{o$-%2O8 zeHu=8m$qIhaS80{76NiawXmgi6TE3&ZlYRL19Z1mI-3gGlulMMu9j8?Qahol2B#>G zRED9<8YZF44N3pjDF!Fka{ikmr<0-QcaTLVeho;vV>4aXOr_A2-gagAw_@9cXD186 z)D7SEf67Z8wzI;X{6;I|{q_@Pv5|7Z_nSg8+|&=>zq2}6RektsuJ+Yt+kMZw)QX{} zU|7JiJE9UanXCYe&GdYdo(H2i!jWwe|Ixsu4uQxH#S*qQxyeyF{FL9H*tV8Vy*KM$ z>^veX@ei<#G#WV6y&iMBx1!a#^2IOk7bse{c^cx(7r)?kH_XrU|y4_}1K{*2*{h$#rwHYi9GeZOtF@x47nG z{Ow)yVg3%RDe!mInhzzm;fQ%2!z;=9`18ZO&Wic-NA-D(tLfvvYYXP95?dJ9a~aeR z4012AZ80K#3G3wr0|Y4;<`Omt7wZ17_v9yer;<|qe0KYIwl}fmuQu}xQj@IBZP%jpfLB(QIog*tGGf@ z?#SCsBco0Jv$$&P{8!vy_@xR@DQ#v`VU*5FPh~R%hmS9)T&$<7Y4k4g^*&R+f0!#g zkrgem-7R>S@Xcnnc94AKs%WotPPMsW%U9;Rq6e7xV~Jb-{ANl}mSkOD$1?ZhdZPTv zZ27ig`9>|EljR2o^~`piP{`b1oyQl-Pu;&a@x{4X3zJGm&>`emeJH>dhf*XoTYW!` z2SX|D)J)AxuJhiSp6g0YYr3y1HLsa9D%RaC`Ufaz}h zJ-F#Y6C3lVY@9!p!*d(w$2QKNzH$BxPRk!(Ex<}iye}%9(pgGrc2}{2y3TA>fQ&q2rzMh!mF_-y;sy_-d^?B$XiVm1O3WT zPwYVT9y5$EvrW{;3+g-i?FC(6M;5<`>4o6%AT;Q$yd}VBA9-_nXkUyR#WHwT@BsU# zE+{ilxnKY)MF$#l;m&S=3QszwWk(Q$vwpZ^5Ex;4HMrFD&~G<<7-kWiBos;L#y~(Q zEB1mf({ab?;a+g{MaNp^#~$2d(mUwvpreO|vm57YWQ4vLgh8GjZS{&N7=sW$st|YM zZ3atEu6g~56n9=sBtP=q<5wnORE|k)z?V=)wQXVta^L>eQaHljty%mh*DcMi>E&-?ocOfA0zRIenN3=Aai>#R=wyUZCu3EfXV<L7m0OqaX<#sTc~;%Z;7GEJgoJnd8PYR()sSEiiAQ?JCKjA{5bOS+ePo4mv3EwxWZdlytMCim}hQxHCfI%BUo zOLwo>cq;a^yq}+Q=Pz~YQWu^1!2dOQt`6u-ruTwQTk6aw4uU#@>AkI^nYcfnj=fA< zlCjr;C+!`66N@{iAw4e1c8_D0VmGY%QF-l4u_t5uL`muA+)dko%_n2~?aB#?$jjv? zKXjVj@tv8x!~gm)lh>b}^)K`vKdP_a+00*Ds8e|{9~qtI z#Aun#f@$TyR*CrddV8E#nsAnWjM`qLs*#b=1e*X}WdDvmUDz{nI#D*Ak!F(fM0V0q z!+S({uivdV@vb@IZ8xl+F|0BET;&ZL)-M~@hhirgDKtCwsvSq$BdqyNV75fLH|uf7 zwo7or8F?!~+PvMOW!3;U9NHtX9e4qaCj75IK^y#easNAC<4bvHvwqIb(d=Z|;r#f| zxdh6B)t}u(vcdr80AE4v&tC2@-oUey$5nv5XWBiYC#6oa&HbeBb+0UmveP2$a_S~ye9uU zkMgBF^fmpQZR56V@cNG*<5C1N*~}u4YX|ZQ2l7Uqojk}Y+5hy4I*_Xaxx2|gR*_>s zt{cU8LFqgEmW%iX`NMI zBs)$~?rs*_a16shR>5OH9>*?v8jR%ctMK;}KJ<6qLF;u63MLgoW&jCqxT8#}^Df-1OT;kMR<9UCi;Sh7m@ zKfTI&2c!9!1oj-e#|DA8@;m04=-vDSp7MlL-)v;ZIax!vHb@-oNJrT$$16h@v4dg`) zK>nc$f3H9;_qI1gcy%qpl6lX=Sp2Ua5iRr5{&%!dRUZ1Le$MVNL=9;F@lh^CJh`s{ zyLkL7dP!i1>|$-iF3zZ2sAT`sYbOF3$6*AY3O^gjeGNc9qQc)Rkc}sIG{kvrEzW^< zA-^hrUdI2GicsJ69F1vmwIkLWJ)`+t|TSR&V@QwR71W<&DjO}{4%wSDM`X8)rcLgXOMVxoQX{{kXHF4K7| zj>GA|00FJ$PUUB^1@)aFp2J$s5{D?^bK@=2hmIt+-V-Zhx5h}t$%)u2vE7yU{Zn3G z88WRB|7c-P0ZqX>t?bkO&ccquN`CFR=lA%f{@5Y=p?63@^DCd95|7p=XsRx7-CoOT7D^kI{_#z_eL#u)Q-Y-Z`g829W3n8UgMSC zNy{4*FL;M^I?q*UC(`Wr$IN);3$8fl)UQHkHhVjjT`IOcw#$B}AUsb58`6OS+h@QG zGuVy5c3S}3jF#1cZI)n51DoQA1+WpSbCzIB3but+*eAo2s+!sMw}ah~7GCx6xrsU?Jy!EJL{PYC1`kOsm~aG6ZuG6+KpEq4 zT(1R6J(TOE={Yo0?-iPxMNB>KLs%4cIN@<7-lsLU6BoAHt7Uva5(z-7oyn$9hlm=Q zrjeW*6I`$5d;>JKHX4JbDVa8@)9)3U!&Nj*icAhg!$OOB6F;XVtsR23V^c%04o$6@ z>d-vGg-MT19z+GGmB&WK6Do9^I3Cg>xQeFctvzikikSZw!>ZZetiSijXvdD6sWGw` zqP;|OytPR>i$64|CvPvJ(jb#1nK|m_)R>*#@b_D$OqniAoUCR}n_&*vklcMSWbFCu zAMiFJ+B@`bE;0ys7G!7;1ClTt_~Djk7wsJ#bx(SGp3m{#u7}WntYEYXGY=XaK*;;1 zO`4rre z&xWARwxJLT4)3%8L>+v&3ZfeawLk(Q(YqmE&Ul%^Ss)Z4;~*3Q=LDf9gV7)rr#J?} zy2|`U-gD~F!!WC5r#VBha6r%p@X8#_U)2a~4l4okQEjn78{Gm;H@b;cM z_=L0O@y^&QW9IR!X16SP*#LPb5cW(4LJ>0#LLqQY5Q@VZgslxAMC}PDvJ6F9r!a|y zraxOg9B%fu3AYF{Q!8%otzxFhuf+=dPZM7F`S+}9%nE0rxoKth&LQlb41}U>9E3vP zoFJ5hFbLZkK)9+3p=5Iaq0sba%eU4+*dD+qB>ka>b@z5f6*l0isI9J|I-xX~#d7Q2 zL8#ThS$Uyo8wa5fI41}t)(yh;1`w_eAq>D1j{a<&bxHZYsaF6MNn;t<(*8YbZOAc+ zHQby^d%I5I2cpFAo=70iO21nO6`$;^5Pqc*gjL065)#>~m&PCtdq1H>dz~S+tEEQM+Ks{{-!n47dovUTKc?r|aRBwlTOc^c7>9UAO z$C`=z;oT55g^jY^W{o)=-Rris+#XAP%c%7f9eGHQX5zuYKa?I>52(Z<7kGMI-0JitB}=IaL;&JBoP zZ;H@_W99*qPz{I8UrYYiwc>#dTv0%`%oqsc@=J(8ECH}i&L}EK1&%=~pJ4Gjm%n{d!e=4O`T;a-c z{Kx;6=yc1h5gHP_(+!8HtFU{(+pY`#U#X{{@TTSB%nxklm){*%qpT^kvfFg`U}|S* zYu6+jH8Vc8Rb8|Sk6hX{zEz@Q;#R3Y$G0jswpGi+R%tA&RV%Dj!o=@xs%w=z5M-qm zQ&p=|OCAu}a#`jh0*fy>VTP4P#R&n;25vW%C96qicfu_c* zRn}9zu1yx~%TkLW4uc8hxP(=%!e$cPw0>S8J|-N25rb1&oXO^Xp`g<-V*?Q1T)*3vJ@$$JiLxd~Hk7sV@rlFx z?@#gmYrz>1Wo#yXf;YGbh?%Qm+s(-=>C(gnLMu^;@0@bNZKzeKR0`NrJs5i69%=8O zw$|9mn#T3Ru@TI5d>a|Ppgg-tPBwci)y__(-5Gi9g7PisbKF-Gcp~oYQVt$xPJl(~ z&C?f@ah@r~&xO!g*-G3fb#y{+4V6~6NG}`?h=s1%`7y+nZy^F#mD1b6_-90uVE5%v)=aH zQm%ekGMz&|nJfLdIj4+>P|G_)xUxif!GOPDIZX1NE|$dM5D18k2$cnOvXs7-5V2M- zjZK#4qH&C&w5gWTTu7<cGlnT?5 zVXCS{>^MrBYbni#luGsnm}<3FbQ)+4rYrmfD}`y#nJ~p3cos@wQ^cSoWrM+jO6kLo_@hXi`$Nx1>?_Abkqzcm6z2(2K zDYPg@kJQn6M-8#F+Z?5}{XTEi?MvlDGISzMV>2~UZQ-#Mzci87DUqh=qUXmr4IpWD z9Rdx1h^132?Uxl4{g13~B+S6%fdhBp6d3+8K5{f(b^?zG#?EJYw|u6{pJ@Ucyi_D1 z&M(iB>Yed+1P-TIJ4Q~QU%s(fhJ&3LI;gD!TLHE8QQOCZ+7u1A@{rYbGPXyx{e8TA zBl74IWvrX^)#dA|lWva|J*K)=MWG9;qZ-v%cujR$;~H0oP*HWM`szw`)oJO#Qe;eZ zJzAoN)s1i6|Eq>oRB7R4>=>;p>yZ2>yjRWV9PS#_XvJ!AG4hLeQ0pm^@&u>>!oDi2$o2{rfl{>CY)y!OQ*mD=I0C zp+B9*F$H2IT*I-rQRrkq*Nq?lzUGm)rj^$S=PH>jD6GsoT2*F`mAS&7zp` zDe%tnnx486QQuYKGUvrVf2EYbbm(nm^QC64;BVD_?7E*ZT@+uR>C(^P$QXZd9$M7F z;B99RcXdqF0ge|ckLqw@Y&dqDvVRdT7hGnZ@=AE^ul441O%F|uIaRWEAB zr2N?^m-R)1Smi50(a#Zwcf?Mp|14gfeMJ~3bVpS&tw&xv-&CFEj}=~JJnIUl~96JbCql5*Vcv_~zOKmOdu)wxnP&Q{c`4BFc#^p@xN&aH3TQHrT z&9gOGVhwSCTT90 z6gGoM(B7#B2zg&=))FsUI9_<&ds+_`WJo#q^$#*8XveKx_Dhg5d#VC>1l zuPLeUY`GNo_WyY+)Eq7xbTlyX^~`~h*P5*|MKB>T0w;!blI(QT>WhX>pTGJNj=mnh zU#y*IEyvgK1?u|fhjxDkvvMG|oxlD5Lr14T|EIG4++yrFSJM8n0k9pQtTz9lVQvQa z68*c$|H5WnV6MfE_*)10PSt&t)F<#b>1S;a!#VQLuc?_-u%N3d@$>Z*r^mN%|NWYK z>xcC|G!%A&_@QfO(|YE?F<|fa_Uln#@AG!=`6%BILpBR=%h~Q!CzBUNZ^vED+(w!d zxI^m(bp3uKZ9BdIBysttKdh;A&VWBBTY&X=Cv{y}V)l&wTYdQ*@6bIc3{K~X?Ft1_ z;q}4+Z};7E&5g7ujf*q}+XW>RITl{N|EO9rCr4asAglBcWJ9(Jw1c(^^+X_dO#rgd))3_7{v4(1 z8Vhpa^)WC9N-$s-4p@I8tOd0|7R1)0oepK|*Pp93bDI2RD;&-Ny8S-Nz5xE3?pKcK z@7=7G#c)fqrm>5~LG8pYP$l7p5rDU4v@A0Sd4$wpg4 zkXQI~^6v`dd;^dJHOxRhrq;}9_Lr?33$kfCl}B~IazcOaHiKvg^7pw^2l8XO5P-Z% z&z}Y4<}-n;(jCZ-S!gu9Lw3>u;W8q<&tw%VZ<0q{)Qgiss)*On{j?;B6ckJG1{I9 zWYrLk1;!5sl^=p4>YD$fA(6S`B#eDt}Jfy8^kb0my--ZXlmjm2*=5vegFd zH}tdelK$Q;>u|uR1+ems0q_sGCx8uD8Dqs@{H+h`8)}9D2<`#U@v8!?$H~2!9G;$7 z@Trz_1bNW}AdAw*Ag}i4w7)Bm+p8cuPHbFRtiUjSNj1(%mn+}oiv!iKjOro`oZtQa z-5o+vDC;*0###sV5grn%C~s~ge_Iy9ghUbTv5t`65T#3c*D?pxAoi4ROw=ev*%=apHw zXlYXERLBO_I!l$FrHxC9zsy-2U6w&h!5uj5%->F~#LBGS*v7%<=7u<(*B(1S$7N%u z=^>pC&cvSL^^O)6?kzTBEY(z_=SF|+pxI7CLm>@w1m45^^Bvn|4Lan?@49g}KORqJTdz0Q_+xOY0eIM}S zx?(=CjB4@@Xv>GP*?(cn!Qbazqi(V(Hx~}Z_Lh6o<&whNrIgvjqczIqVVPsRR~~Pr zC_!<`+pkn1Zh;khCibNF?9bSfvPvw74@;_3pT5EdZHDF$vPvmMlzZxD=TpXEw|pw7 ztS1%dsM!@&E@|PFpE>eYb9t3QJShN#mPr@5Wztn{nN&RfAuW?OOKz zDAF0@)=HoGbX)%Nn7{h+qyBdWx#iCrj-B!sT|Ug@%*KW`>uJIz__MQo=uC?GBID0H z8avDvcow&c-0GyvoPP`R*%rK+HVYk>V-%2D#YK%s);dY{>CzqWMt1 zsTgcM?6R!~mePTcR|)3@#%KD^OwaB$e+SbsD-rv}L0T_8mH|W_XGc$1zk0vta?qJ; z!6LqTEdzn|x=8kZ@G+>09f%QPEJ;r~ZpdQWg6OH{nMY|k4tCzb-~ZPtOxyrIVwkNP%9|-m@i;N=9G-AE}3*p9mX~nKHv_lCZ^HZ6c$wc|z z(D^Pn;i@sypZq_jy=<@~6~+aY(3kB|ydK!WqbfG@VC)gg*^t>GqH<}X%^c`|~eVo$c<*2T9ruITumc1C0x zQE0R*5Gx}bX1=>H%-uen@0r-~7RDLh6ev@}p_R{0j!?>GfknZ_-ux*qJ9CI^9n4mY zzNa`)pzp^Sd5XbCUY*Om=T;WPBChiG{^<-l<~jc$DcpYW$)946JN18IuwXi+F`S&f zly30$4>5t6`45UGcu((VN>U?HSd2H&C>3Tg$ntMvvx_|&doq~f2jB$R9lw10ZF@H9 zQR?3@EGWx2{_-ph%~=|_R(pckbD4MiO3qL~0CU`Xu3hFC!^=DMzcLEEColLIe;J^| zj0GCjMvxiEqH!JOzK{fpXS`G8f5iOtl)ZV-d+sA7qq7plQ%>tmk_%Bt?g)d^YK}u& zMwLNZ#b|rV7!(!lqxJSoGtVUd??2Kr6sAoXDyFq!WOU|k$hPM!%%>V*&viu4Jr(d% z8FbobmiZH~sS6#O`Z8gou;vtxR}?>LgN16Y^q`;~hD~)Co8q0yHwGDsh3&LBS#}S7 z$&WYrOSArU{>@?{okVC^Fu)hAKAZW-$9D6#)t@`eM+V{2*+R2)SeMb@&($lb7LZ|V z=Z5BGnG-62ICQq6$;m=HHVQciPD$&0)ErLT~tarfv;vD^Ewkjg%&l0|RPVoYnA~sA9jJRQtMWuT&!w)>EY?w)wg3}#BL#~Glg1#S zM3sDleG}shzS%J~7=s#ViSkz%lwzOjpAfIC=b-CPNWbFoVLl@M*-^_sf2apcojSrd z^dXq1B49NESr@7g`@&qjfEf*sG>xj0?@C%$bcz;?cIh-8E7`+rg`iQ1uWwy?p12y} zv1U}-mG9go?%H}Yob!h1v?yiKvScb+iE$KppiYWC#o$M4B8e`SwX63U9V4bH4w)jV ztA;IF#%hun@{M0PzIXDl_-?TUj?5>qwzw;vtqIXiGHmjdl7FoUOcjeuu8ggP1BHXU z*M>pb+ZR}j(XmEOUqp&BJs3McWsVlja^^RM(D436S zlVUF$Q*YPsVWge@N7+a7aA^+wxAOX*8@@)uHM^ zj@AKz&AA5vL`rzHY-D)aHnf(Dps zDEgpaUja4(;HnkYX=R8dc8Dc*1T3-Hu|!4EgC+JH|LA$Qz)@Xs`pNbxk;*vfJz72DN9>9J$HrBvCSEvr!szv+mL z6S9@-654Gx+~~(VmGhHJtzx5vTeA#Fo%8A_+$yVhdy5-g3eeKQ<)RD_pUDWl=~J>m zI(l(Aemw+a{oM?(PK++Q+yl|=IRp=T=7aR$)6pedR@kTfJ4tjV_s)N1T0W%}Ui5aU zaAO2{l|5^i2IgQom)vg+iD+kXi zWCc$jg^J9kS*{vY$}^u=d4+wpJA;#nckn-H<-yZ9($F^|)3{!HVZTA))Q#APBFegf zVh;yQuS;t=i99&ocOs4_?pDk3)}QzhSKxO?`3P5y?Ml|Fr3H5$&b_3M)(2yc!cL8IpGxlU+>zecV1`nIBy|UJrV!adaZ@v^pr#`|I=R1W_>SH^< zT=43xw@T@RLAAgZG~W1C;_i8jhmuCBdJf=|@W|r&-Gis!ew(^kd)_^RD{Z!|rX_0^ z12A7eCE$CW@5L6jnfdIJVtIhM-!8=xp<=zLjkdehz!s=xDl=5kE~$wek&AN4Q{rLA zNgzsxd;2a$lABhTIf_m|V)Fxki@ek_v{_UCu(y9T1I0Z0_&xHPQYNxnr|5&HPfN-k z&<@)Rh{)J!n1-0r-Yii+lx~!LwYQv_nu+a$+*a?@UovDUA?^6p`(qUS0wCmx^Y=yL zH3!HpaQY(0T`f1{?|8?1*%;&{>7cN2Z}0Vt!jZQxDz6n65MxDA_YO~UOVTVww|RS? z77fw>#VFb7(_NO*?gn6_fg*b?54lWpv3=fi+n5ovF5p_0?yiYODT9p+&6afbC5+-i(A=XY=RZ`jQ5d`x-7JN$0l%*1x_7mxX)e57puvgn`Jg0SIt z*7$XoPeQ8ykY$W2rl5^e#$d4pm^9{Mqb)EbWrdX4`C${pNwBziT@FA=7=qZvJ3OTEK@jH)|F8VUwcaoXOvg&dE0NJ^HDZ; zKg!UK?eTWp>y*!3dDa;G-uc0}?n_>PcvgLJak*sd6_$N+Dr}e4HHUV;q(OBO(=LnZ zuLEi9BO=Zx)T4mcWD2GJSo-9=v_LEUnnYpJU@i56lLQHjF-#BtiAYAo;vc@ z#pORO(vVj10x7RYnz=zK8QA2pkEm_|J>u>84%P5IOX;k(+qJ9_&Du##dna{QMA!{r z=wK*i|2ssQMI#m4?Tzjun5PxCoya`I6ZPopSK8Ec^jDF_TZn>Sxi7xY6WNgtsnzGi>(igO(n*FjAJKEr(-C{p@qBSF zgoDNd2!)z%m|wY5ny$u+#x8D35#JY=7vEoh!ZHDGAm#l;`mI7oJN;Hsr_oL?LcfI@ zbeg(~PJ6Qgf9u3CEFJw8Yhk5TmO|u#>9smoD|Hvm)+3m>Zee0r8sn`+Rz??B&gYj7 zJ0c{O#-Ub0)3f}>q@)+%?@RHsxIvc3JeEfoYHVK%y%jsn!$lr$W!~gl`f;F;GYbQw zjT^FHXW7|qe!_dghy zJeG+)6L2qaxHg4nvR4TE6oLU#I#S7E=D*jlKM6HFFd!9vB&U9#*j%V*hTC)@5xu^LDtjHLL8MM53!I? zDMY0{MKG(_zSuz{Oi6W&^?!@;$@jd;HC!+;i1MrRkA;SN7cw)9fA^k@nrYRSL>fk- z;u)ffR+aTSrTJpVvOncmcK`8zFP6P2mt{a!9?oeno6_u9HbSa$ZxM}|F^|Tqhomuo zGV5Q?Ue0HZ`e=a*H#0I){!K??&+#SgCt?aAnD=k0vg0xgNdr**$Gr~!rXs>|+h$dE z`yf}OOtmrM(4C#$JUGZbUdvdn>sKvsdG)zY?mOfB^KsZsETs7R*?<4HhzctcUPVM-DTtX!Pq8C2vKGn!XNQUlg$Cvd@pSGPvwKwYrGXJ?9I~r zGtqX9Obs0jY&iGQW}YEe58o7=TYOktIT?GFzZf2F7S(C;VZiM8g`whxCX|pgBe@42 z-=apYHiK?XXpKThUm(OT%{8S-P+FKA(mDUS2p$cSAq?AQA%=pc}9xJXXU}cQ92Dq0^@yBY}b2Mn?f+%1KI;Jy+MX5*cFO* zfjP|%j(55Xp6KuAC#rBsO0U+Q+Mw#h{S8sz?bR8g!@rUW{<{&xl}Liaf%@&Nq`3+O1nim#aRNmqd;(mu1wHljCz1E|Owx!+LQn?`8beOu zP4ARygd}YcrMld7Z}nQ=#Yxcx-6!&_)`8 z$5oojX1X!Uy}jBIb1<1|p1S(yfv{<%ojc+>?r92$jfeTe*;VH+_gL&nGT20R`i8n9?TNzw=hHlC)4F=;* zM&dSjwADFh!2g>;5d>?9={$#dSn|u_oG{3H{Qqq;_i1d-9~>av22&kg&ObA$#E!K% z4&TYh>SRO}`PaoTS;Y9w@`;*yNeo+t$6&2mk+0@X$s74I?I<01w1x7q%E6hpA2%}r z#7ny_YS1Lg8wVkP72;vszHtVg8ZywA;af%T&>bw5ctJbNJ>Kx@4^kxh%{D0x0YCR> z@Lw?z;BLG2qNz|>(l}k`pWRH)%Cel>CUqaqPMzq_J-MDs;mk7O&d}ZOiQnqEjzutH zn5Er^RIhRBJe>NKkEp@Jqs*t+NoYiVkUYjBlN(*kZ--i_Zu3Ug?W@__ z12iDtd6NN@zU`>kH&?PRG^aZ zE(RW%RMwy9(~#bf>*ph~AD3$FDXa8=*^iZS2R54s?Z;?oOpu<~Q}Ac;aB<{|VWjEU z^ZbQdn|dwId=Yo0kN3;uVwyFa6un%EHwvp$x}}fDxs>8kKk}!&s*6wOvP^YEKSbMJ zitDm5`}1g=(_f~TT2^~1c)nsPZ-VG}~lWw4eUhj2)@Ex-WNX&gW3F z+9$hB#yh@13>fEXZ}0CTr%*&Snsw*!ao9ewalE~^V!1@c7*xei#hx}?v)#1ET5tCA z8M&Hgo-xiS^mAz%W>1*~eSp58(Vcig_*RSZySCHNtq~nEAi{FI+CjqcGjgrDxItg;7D06>RV1!#q5y?wS#0+%Squi{dNx83H?$doBlon+{;`7?S+c}|gHGvSZgTvE+~__Vi2RMCi5n?F*N@-~0=FrG_MlRB`>0rMr!)Zea| z!;>k^D8%R&448vv@$GWpd_QFU zu9a5WpJc}q0a7ciGA6BX6my%LfwV%ZQE@1(F#ku=s&~A!QaZzq@zSdAOwy`(L z1Y`O*X*IwgYp4FsP+Cbqb%fGNqDvC0i!mY&F3DBmyLgdQc1f{NTFJpVlveV^4W*T& zSeEA{tt7>2q}6~)tL0~sR;AH#;;KCoSK5M=xN48YRR_OV!bIY#b7FBNY1J`-v{IYg z;$tFd#X@4dw32|6wCWrqt=QG5lU5z?N?IvfQe%OYZXmEaB(x%dm8lU}KceAh6Iegz z88_8Jp(cUFepa2pI>A$^Kwx!@6Id?+Vo~d%BI}{Vrh^hs{kfI?*M}tzh`jn8lM6w{ zCgrSvarv{0$QHP0i(~~|t1J~ObzOOyI>J0n0vX2GLAVo34yN53%hc3v8~z=Y*>SAs%6Hhw#3vQ0(ly0!pmQ0Ug0rZ*?1<~?T>JDXg9v0S8Od@t z8?JU}6rmj>TNA1^_el2|e`efE4;kJe@;1R!`w}d$5q%&wj@rzr4-@;U>-U; zMLl6hoCUJsZMj2maP0CQ-@xs#FX#sYefDzUP9lr5BL8z0Zuy%gL|#dp9Q3N{Owd3-zJ3U@$`)i+&|6}n0CdBJTu@RsVC2A;b7`Us^e_(;B@57q>5~I0>WXn);9w6s zqOks?LBEO%6GKlLD93QVbQb7)C*<{N<9iLgvOzU~Ug@A3LI3q18t&iVuMPQcio|&- zmlG=J07HjtQ539B&}fy+r7x5p$}&T7FNELm`qh(VI4`L}%L_Fz^dyIJ&_B$>XBzd@ z+)!gjy_(q&`l^7f6|E+FUDiG)cVm+fvq}@y0D9$#Y6$%i!#eG9L>c68(0|vUe}lgP^oEY*lo}6xzyJ6nJUI^fb(4i& z^|%~TK#yJta2+!K#v=8y+)W~>*hGn>>cng{kJQ*v|07lN9z(B`QVpP2PN{n6!L_{p zyHEt)cM_C1c}ID@aNx*QU$j`Z^H#m6vWrMReao%a?oC`Wc$9}0^C>>W;@Jd2SFUeK z;sb+R(LU4)x0YV1g>fU#3Z31Vz_UWTY7=-?IA`KT6e`aOd1t&U&kC8RCiJYpuH49{ zqL=lc{3Sx4iXz`}NUls_i%C(QB?1tb!?N78XwSxei9Y z6@7tkMI87ruZ6x97z>+t^^Cq1ykd*Fz_&taf9qW<>;c(Mv!s1LA}sk<6S{(RH*#<7)EU#F`kPiRz zgL-_SI=Hn33s@yHO~qi$_7@Il!z)VKz=N7XII>$lFPF5TqhZp9j27gVY%an^uaw-POR0oO+S2fs!Y9I*JWPw=VdKfjqTzD4b7YY8#bigP@M z8}#Ht&4_UrE^mY(VR7C)h%zFd6+}@q4n(!=TtQUYkU@dy;4@&CS3!J~Dg>eySO((P zROhUwx`8NrNeE(pG!QrH$%SGi<3J=P*l%|rYESvB7>b~A7^-3CilOp`435EYMHR!x zs6rTOrDPaBsyb&i*I}sO7a@k#$-GHVE))wMhvCXb7|v}zhk>Yl^|OK~ipGJcmetK< zA^HwyvoePajsbCH6-2El1mYn+4aCRz;?GLffv7#5@gROlPcD?};5ZOhH3Ttv4j@X` z0K|#ep{Q{H8sidAWapr*JfxPL>qu;C0OG1Dh~K0NfvDAsf%py8IZHmzRhFoQ*?15i z){_gRLyQA)bwdzS=K!KM+a>~0V2O6iZxRA26z!r~cCH{Qd&uCJk+`}F;z&Wh5d~{T-Ol9%$Y%~*KKI`a+{ci(}kDIv-=&4247urw80t>MbS7A)v|L1v9ke) z>l}zmt*cZlta`$Xy1j1IGjyVO3l*2hsr$)d#Wbx?PU$^%>z`+)5M-}1J9+J1aMgxc zd*TCK5Q#U6TkrI~5l3XilsdEgM6Mk|j zS1z4|W2AA4VOkUp+G>IDd%&yoxdDhd)E;umBJKAGQMh7OjKlZ>R z&uEV=RdZlc?)j=Uboe+yz2O=18Hr8%v@}_VN5r=_YmA>4CD&;4ZyF%khLmf+TdR{2 zV3&fV4Ml!;p_jALw1zISqyTba4kB0%I!+Mf*9d-x`8C>zDjen42=1BJ^7x4PWcT@r zvKxF2@&db(vm%MpbVvC$fc)TqV{0=q@!YJQEN z(wSXhb_3#0g;_&_dqGAPvi{U(HwaoK?QwjoqWl^`A>EDgYtSlT;__=$TP6LywpFFt zR*C+`EhFPnn6n|MbY{urHfY#arhdoAx2kISBV=fpU!x|e24&kL)_E(u?Jj47^iW2V z@@vp4)2J=KMzvMasB2r*Guc)}`8C2;^_-zqrVlr0l^cQ5ug3RPlwTvLpu16i4O(R? zuI1NgQx2PMskfyluLk4J`bE<%nnrHIMU$*2LT;-1acpdjJFjG4%#YVNeq;~c|eow$J7OAnuFG^?R7h#HxsHHQ51RD(p zq3D>HVMqxX->M+pMpQv}kZi;MD``(^)mm$n>4Du}d=Md{v@nfRix--K0e$%Ta7=q+Jp#(?loX#Dw7 zn1_kS)h>OhQ~J_C#r&|OFMViZpf5F(s@!xWfgW>QB&Y> zWoIt%l=_zwsHefLS3)XcZ<}5Ct+wgXNa)-gY6a>%hF&3KK16ZpY?WHUXD-UWJ1(! z)R&@Je~mOw9*9tgCilfXXcAB=GJ{+fjVUFxZ%7*HjfYeCJ2lq%Hz+~&rhDkldS zIVK5e^Ms&|>Hi+R9#5*IZ7r#-A*nhNKGz22cu8j>mzT1#qMNGdTn{JE)dsFoM3lFqVVwSNzic~V0)6_6UvC}}nBut*)LqI2$| z@|Q(XLsBIdYe{VnN$n7+lGF``>S}+%TK^uz?W9OePZrfaLsb+tBvrDmmeh`r)J~DA zi1Ecb22ftG)=*vN--85otg2>4SyAE%OwlMAOQ}4QGf#g@O-j*aylUdaEdAxbFqsd> z9y76O$ei8j$h@O2G0Qr{YhXwBFR*cYs{Uw|2anEUjLyn?bktb;B(JDKG-`=o5C zR+{(Qp_S6;$Unp?%^#pWNt2EiBx#?VG-37AoOHZ^P0WMlpsC}RuObLY71gWLrzxBR zo8RX>_a8sRO8v=o&DPu$VdZ$!|8?QGcVOrB+<8I1nk0%LLfzhLImhe0{m}UoeJXZ3 z_A=xpW3RKJi|4O-W+GO(B!A42w=NiY`-1YSAC=d>#Hm-J=3U@c_i4Fha)pB;T+wUI{Y9h;Ps7wYIPH=dWtqc3AS5wx_J^ zy>7Y(ZD(<2W9dFI*g1==%vJvU)s4%9caAADZDlU1E0aLXDpLjaS%Itl`D+bF|GtiK z{SK2G-}X#-OPI)DlaT_+giay3OUGrU9%e)CQM8ds2C*EAgvg zQ*@pqn)8${2dAy42_=9fYP{eUD&k-u2?c>|S$;s-N-+tsrkF4! zWVl{rcdajN{}y-c)^^>>c3obq#SB3b5H*0hSgi)N?I5W520@Yef4}FscjnHJ1gQ4c z_Wxf#WbVDs%X!W@&w0*sp11R0>KxefF6yD#Z{3URg`o)lB*R_)on(Ho(2+pen?MXl zY)q`7$2^=UB<6|ea+pXk4He$``3Lh~OW+&*ox>=L0@H$go}~0e7EA`~0R{JhT?l>c z$D9;z>>Q&vxvYuGpfY?bp$*T$F;%&)N53X{FAvEJ>pxbLA7Q!s*vorDoo+7K8`v+guX(pj8#)s?9q?03`SzN>=Rl`T*Y zivz{Hbm$r$a^#6sS-a3S;8OaVFsj3CS7?Vg3{}qkGamTjLq8)I9dWc2eR))LU=&Wu zA&pmm3}yw50p8vy_mb()0AAigIl2)(&_+G(QuoE>T6#Bn%*DInDtXC#0lH$CFSZ-w zmSh?Q%4H5{KRdiN3%4w};j;vCi_SW_e-y`~aT*;9_lW_rT{LfFAP_#-W|WPmC5Y?N zpciv-6JcVtQd+;fJvd3tuG-skj2bMihXYF=;<|7$YAJDjq#@ebHH<$kC3 zL*hPTrTETBoX7Ur&tvnXHci4?19S0~Y87(B9hOOlu?l%Uo8C3NV)fBydLaLx%|i5x zg$TcGpp{M+{ZIn36t9QI4;0Ze)jYXg7 zOu{_v`}Yt;1N$lu%%b^tYk+4IjRyi=RuxbCDsP#K!6@^zZyrwjGSN_{eajN3eS_9% z-vT-9OI8=E)4nya;H$w~<_kEP603PdP(dZ~Oe{1|GFV@D+Ss1v_P&SP-Jau#u`gZnmo z^p-(9c-)sYOeAc_ec=TZfBAOR2ysK+LxEhR$0d329>GiUOb^A{hHum9C%T*|nRw>H{>p{!^BTS!Py=;6 z#rb(EkptR>W(O1#9TmZrG0MIS|74EGsrKMir%TMeA#>dcQBj1uTA+^LcaDf8%UkTKdL@F$MS%rk|> zu(>*`L6!>3)tNWp>a4_abw-_5m|yM(5UQ_&eBL1ĂiZoWACVOfEEad$>vVg7t^ zcUED#JA-|DnfSX*I6Dg}V;N(;t;4uFLkbz_veuxfYd|q~#QBx0vyu^9ok`Ax*fy

          K1~Ll`}V4;K@Q(=$4x@dCvX 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
          cFnj6E;0# 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 z%0D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%0DlI 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

          r$IgOl7&LC%!v&h-x9C9u>kDN~~AQzI0 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%0DH6nov!oCRUTEN!4U(ay5mTQcb0%R@10y)pTll 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

          O97p&k^GT<}~Ra;ZF3D98*6+bwG^wTQJLJQ zNq)&62AL^-#jk?KbieL5*k=D`{}$NFw)waDKZK9i$NrD~pRiB;pZY(8?QDmChyQc< zg6;J0^zUN3{k#2p;7hjGzt{g2+vnfs|C)W{|Hl6MDKl*=y zpV>kGLH{9k*nil6gdO!C^&exu_ICWpZe(=>bptoCn*-z)xRuol)C=6k z>IdovZf7Y0(f}H=MuA3w#;i%8NuVif79h=`1#1~-8MuSB3Xs;&hTRz;ZJ`}&A7~%w zz&ZvPNs!7W z2gnqb7Dx-Ev#9|xjZF_s4`i?z0Wy|JjXT!$n$JtU}FG}nS&SDivjWydpST}VXp?rYk&uR0Uj>}crXy)K`Ouxd!VMw zft%u`W0TNq?U0dZ<-$1Jo|512>k`g`42!l3U=`l6r6( z)GxUmQc4;?Lugde7@Cwcg=Wyaqy@ArxdU23>ykEbXGvRV2klEbKu73Qau?iP(iyry z*OG3~9eR}XgkB}Rp%3&e=?DGco{|AD5C)YDhI`?@k|8j(WEc#G5heG-NElTz8pgob zl5y|=JXkUw9)bxa55prcv1AgY!sL=EkOt``Q(+oRhm4XLFcUIMW~M}VNJp@+860|}@x?RThA z&k|}NkD7R*hGO2Qo382hM7pgAw?ELuxVTuZ1Q()|xap)2SHM!`3LX6Ud6O)`s}zC| zDv=-zGAJb~XrO}un@hI9R@ep~!bk9N$tUnBdcUN>H^VJ(E7XJApg!CVDbN5KLL+Eg+60^a$q*(LLTHp z0nCB9Fc0R#0$2!(;89o%OJFHH29L94rOQf}!xOLqo`jXK3Rc4!cna3S)36TK!!z(K zJO>-#dDzG{m2N710bYcc;AMCPUWL~H59BPxBOpuh;J#8k=8PV~L=PANY91eraZ^*h zrD*c9lp1bB<4>h%42Bz1pc{|rhC$re1ay%-T?mWI%t~?54W06(lPjgDI;DyoI%p9) zT-v}(=@oE6<>U>|%9-@v!*yVCDU_rv#a0DgcU;V1TU>CdGH;Sd~#BXE=*D?L{F z3mk_NaFU%WJym)deuXn|7Jg&rO3#&^hu`4>{J}1kUM#%?f5Kmo6eJa(B2TngS5v&os8m@tBSI zSTA@Rs~@Z%yd6?lgJ6STLukYr2O9^QKvUK%*euwbwFtHdwuC!at6-~OYt|;%CU_@n z8*CeF2klvhV25Bw)+yL2co(}ncz3Wf>k{k|?8>?Yy9K+m9>E^Lo~&1}SFkth6YLZ0 z%lZZT1^csmg7*Xmuz^7`2nMrzgZBpSV?%;Nf;;9NE@NanKzL9&o73X(@*F>1VOx-VX!4U*6@VNZIFCt+8-p}n+^oY52hc3!cRf+v*}=v95Nja3P*zEsOeZx_$5e=n@$9UlR

        1. 5-Np+$|0dj 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

          vUFEc#U^vL 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�Y0M>!rDX8|tI1^(pRko3lyHEfl<^(ssOAdSxk&@}`4>UA%ss*UmQF+vMIQzc zM?7Phz+|Q~hj+*zixsRRj{>&w1qUeQ8%|TnC9ZOlMjp}pKV?g6Lg_*`dJ{t|!+4zp z#xsej%wisCEFp^(tRs&Cwz8cP4)PV{R8Yx})KbT7{>c-bx-CE2(4J02(4AfkAeP~b zCXr;OF_$!!@)uT-OFmoJ&K{0%f>WI564&^JdjvGdif3p=Tf*o{B+>L^FhhxF9Fv$v zDhpXc7CEeEGh5if9u9MY3M#qGPu%7nj|u#TnV~i9=}aU&>CX^GlE9n1MJj2$Pd01G zqma+p%Mr@?o@#2j$z1{({ajk`Yl3M+YW1QqHRa~T&I&N{7M+DyS9z-kJ@*Ls3Odn!+jZq|!#1v*SpA0ft$$IiBVki44 zrJPfoqnaA7Q_mfmXm;0mLrX&FNH|gSW+1VQWDFCS!YtJ{Va#oW^A=}wUDdn8v9M#ltoqF!jM6-XY zpO%Esk#M5u%|K!q$rvUug;~t!T{6ibmyh_A-R$QmWmIsUi(I9iMjq1qzWNEK1J4sh z9|jReJc&$Z1`EhwIjhN|knQZFly5jqC6~C$O&WPb^9RlcS`$hay3v~$;&_8`Br~0P zEGCN_Ht;dUlyI1G&T@gjaf933r&*J^Czw#W(w)8xW&~qNW;*j&OctxyNFh7e$1%R8 zk{W*I4gnAC7%liU!L*|zU5TUzeHchA!x>E?$xLM?^GN4CmXkv+A5us$yE(uyPI8ti zE>cS!x46qA0w3uEt!T@0g!3|eh~YIxkw6ktn8|!H$Ydq!$)|{&?5C7+PH~QEYPe24 zcW9#7WAjf-Lg+|1QS@dYv5aI46PUs*=JPI@|r3=O|@VaGr}?rJhC}(%ipa5ljc3CyG7{B93?xnam6p zkil|RlSd)j*+(hgaGFXkah01i@`&cmng={XYeMNlH+mC89B(j=WTrEZ#blAg20o^k z5)M<&SuXH5Zg89XH2b&a0soa?Lg`9(`ZAaij3t@r%wsWGtYRaD>|h_q_?Aj)_?bHd zG;bad#51&_En##el4$xdn4!coj!8@-m4z%JiyYRonJw&K4~IEH1(jUpCvJ0(#{>q- zm)5kWGm-S9KSLNv0&nsbsig5f*{mgxLOy3NM=0les;T8BcTs%6f8kkz38gbH(USoT zVFY7HB8Ay3WGUIKVIu_;Q^Fz2sGy1(>S*90LI0(BKubdCNH|gSWiZ1@Ac?8WA)RHc zWCH~hQ^Fz2IL!rWspl?FXz`R93F8H#iQzRykw6ktn8|!H$Ydq!$)|{&?5C8IoZ$jj zsH1@<0-u&CZ3rWR9`xr`;u*&zrjbfI%UD4!`D|qu2RY6us<=WO4KxwhLY9QkiAZ`e zh+!l!k+)gEQnFdYMhYmVghP~3K@~OB(ZEB3{;T|GODA3=nt{YInk1$&mqlc;noSh3 zn}ZzZJ1V)%4H|ev&@;^genUID(4AL^C7$t2VK(XfnN{Rb#4f(1jI&(i28{&#O3!G) zuL-6d9qCFWJ?O(gVj0e85=mw%Gnq#^@3EX5a`})#irLKpj&YK+RB@47>bS*S9ufGg zbC6cFREEr=B}B(d^gF1D>WO zA#^01D0(xHSVl622~1%Y^Ldv{a>(T)K4mxiIZ7E7oaZ7}si%>LH2;lVBA5<5PZWI^ zL>%!XGMO1HAcN(sCXYh4vyW2BImJ1uso^^H+@XnPE!9s;Lg+|1QS@dYv5aI46PUs* z=JPI@Jfiu3b3f9WP`c2K-oy~c8;m2F>C9s>S>&*Rk13{v!<2KD3;c~6 z+~z*bTAO=<38gFD>C0e7FqUMdGmph&v5JipvV(mb<6A1J;b-m;5bS*68CubnFuD>+ zH2oONP~sWKB&LzdLY9z44(r*>7Iv_Q!WJK0YuCpp6fu24qLLMI~W#UO@}z(n3=0ZYkd4I3$- zm=X?AMg>*WP)7p~32HAt+R}*^iDn>ij3$Yx%w-W-tY#BM?B*cH`Ho61bAtvR5ftkF zryX7B&MU+c&v>RVn{@unD)J~|7hh7wSuS#eMgltce4e2dZ3&|*kwnvv!3-syaZF+w zsVrm(S>&*u&1_)@dpOJqDyZZ#KXIFTJSH&Atk9bFbS9FX^k)boN#IT1B9%1WC!4k8 zQOM`)*W zP)7p~33|@_5JE@7iJ~uq8BPL8Ol1z~EMp}bD4>`U4pGKwE>KH7cX>jKPHH5K7lV9B6hN$QciM)3tXX&2AT-`A2Ov4VMNe_{=7;&h+TY18E3i34H^k}-u&|{!GzM8m*~j=hA@ILB$2{w7P6FV*07NRiYeg` zWmHf_4Rti|kf3n=BZQ8G6GdMJGn@pHn93Z|S;k5>P(U#y9HNZVT%eYE?(&2d5o#oi z7ld-?_tMo_fJ~N+?}m2uhM|n+kEAf0G?tOW20r04_VN|qQppv5 zrjf@y-Mx9hf1?8tMDu%wkw7vtNh6cBY+?&LImp+XrkZQq;sJp#dw$vzPETSO&RCL} zMH-o`A)jsR;TRQEbDe(>5ast9p5hr=5==Y7=t2bD_#J&2$Pk7RPXgnaND6N=mv_iu z8QH8Nmk%kVnBDB;~dpo;W{^I;6DE%=y&#pV17#{B8Z|7gNP%Zu}okx z)0x9NWRS%Q){#d6+xUV5l=2OyspJw@xk)3BXx>w{v?i1;bfY&h#4?Q6Nnkvan93~X zk;W3TSiw5-C}1nwDd8YrQBDPw{75Zz+~%J=;i+i((T4VPB7*MpVgRuWXEccgcF?NJeRn}FWe)bm#lb(R%6 z=XMwbXHoyF4PWuX}-3wBWvXb@WQ^Zd8Q%X6fI7c-# zT&JEpG|}u8=M60hp(Ei$(VKz9GLkV&U<$LC&%0!jLoOfjDZAOvQOc;`JQul2J&io1 zc|Y?(FdcZFDEcsnIO0iUGBa2}2FqDZ9))aYAElIYigQ#`!*%MpLle#VtDlyH(2;PW z=*>W48OazXFojvn=Up<%A(xN%l-=y-C}mV|o{LbS*S z9uXL$5455!&k@ec^dW}V7)1g}OkpPT$sm)JtS6r$cCw#R$~nb3s;S{R_1vL}W`oT? zEeW9`;Y87!fy6SBF-%|zvzX7jWRgQJAMq)>+0RkRsNg&oxk^2aJf!&_%s;_&;CZ6x z!yw{_Cy~j_U;!B{XEk{gvYmaDQqC#PQB4ikspk$&G#jFRS`tD>!il0c1BqoMW0=4c zW-*_4$s~tdKH^h$v!A1sQNejGa+P`-c}VkE^%G17o+pYv3?hzr5}C{l7LdVmR+C2| z+u27c-*B2rE^(EcH1de%uiAfF6G|7l(VH0Jc!O~yGo5)XCW{<4@G-@daF}w=a)G~b zgWKGv*=y#WU_$9iclt7z5sW37>C9s>S*&6sh3sG-$M}{?YWSHu1jKp&;Tc-dmN2>! zNi_W!%uwPP$0Vka%0iZqMGouP%ocXAhr^tpf=Vv)6Suj?V*-cDm)5kWGm-S9KSLNv z0&nsbsig5f*{mgxLOy3NM=0les;T8BcL^Bg?;ku%FrjqjC3-S|A&g)QNu)5Fg)AkT zHEg7SVoEqf85LAfLmdq~BxtyOB7}~F6GdMJGn@pHn93Z|S;k5>P(U#y9HNZVT%eYE z?(&2dBh*M3FAz-(uQ7@Ql9<9w=957tD_KuIMeJlhrJUpp7q~(l4KxurQl_*aj0k$r zpI3=z9Fv$vD(Ng^1-az2m0cXBS(1k-$XWW&umdW(^xD zpqLU4QAPz-)KEtQ4+(l*ezc_%FA~i_;uuX5Q<=*mvRKU~irCFTj`JOrT;>K1JR;}~ zfB&N$UFgm$#1hYVrZAgy{>&=!C}J01QpQ;>a)Uy5EbAV%<hU?UGhbEf+Pxl`!385q5MA4gp#4?gGOkfJL zn9sXpl0z;Z@hQ96&r!;#;5-+(NJfivk z<$k0!p>&}ey@?@?HyB4U)0xL&vdCcrA5%;ThbiYQ7x)`DxXpcDVRR*uX!v1df+4t!YnZBI!wghA@%@-sCM(N#lL8SxX*;e9m5u zP|o*MQ_D^667Wa&KhF|OD4ltUo(y0JBN#&xDa>XeOUY&p8!4ce5)M&D1y$5gM*|ND znqZ#@p(Ei$(U-vtCxIlUGKX}Qv62lGP)rGjDC0C2sHL8}JfTIB8VTbCqKV-(Mv*`g zQ<%woGRR~l>&d5xo$RNSlbqoKSE!?bCIa7-DQyTNf*$neRpJ@PB&Lx{I?Gr=F8OR_ z7Y8}cDXO?a9St-QI8l~_(1}QTF^FL#Fp;-ez*4eV!$t}yri4S3Q9%_o)X~60f+oq2 zwshh}q8UgWqe)^ab6G?dtJy>myE({lzN3=M+@OI+1SPxwX-5~j^9r%VGoC5TCY?XC ziad(g#g~+EmW$k=k$}lQpJ!-ATf*o{B+>L^FhhxF9Fv$vDhpXc7CEeEGh5if9u9MY z3M#qGPu%7nj|u!=W`)+Yr!$fCq(4I#Ndj;37OAB1KH01#k3v3YFGncnd#b7BCU*&# zV*h!TU_$B4OY~#_Lm0srl1O1T3t37wYuHEu#guS}GAgK|hB_K}NKlITA%u>E6GdMJ zGn@pHn93Z|S;k5>P(U#y9HNZVT%eYE?(&2dQ`JZqFAz-(uQ7@Ql9<9w=957tD_KuI zMeJlhrJUpp7q~(l4Kxw>mP~0w7!mZKKd%zcI3_WTRMJ_-3UbM3E4w(zaZXXi73yf9 ziNI;HB!o^x(u+Y1BY}y$%>tH^%^EgRKrtm8qKpcvsG*Jq9uhQNezc_%FA~i_;uuX5 zQ<=*mvRKU~irCFTj`JOrT;>K1JR<0A`%gQ%(4AL^C7$t2VK(XfnN{Rb#4f(1jI&(i z28{&FF#kMDFrjqjC3-S|A&g)QNu)5Fg)AkTHEg7SVoEqf85LAfLmdq~Bxt7o5kg18 ziJ~uq8BPL8Ol1z~EMp}bD4>`U4pGKwE>KH7cX>jKS!yJV7ld-?_tMo|^4EC6unb%qzt5I^#(pm2{S|f?Pgg8zmf}oHP8uHE!{M zz&ZLyJ37;izWjkvB$C1$7LmnTHnWXAlyZ_YT;K|IG|)ugT>DEK!ib;;{dtvm5}C{l z7O;eD){)OvzTivB_?{oQ#%=D?EYWJK0Yu<(%Ri)zomEdhXCfvxTyy zB_VVqoG5xTkXS}Ch6zkz7V~+ROmfKOBR*v}`#DM(6`bcHSE;9whcr*Kiv-hw=ZT^Z zgNP%ZL?$zX1!SCNYgv7P5paa#+u1wy=Xe9OeWSRC1Z0xXnEt6Szdaw5C0siKHj}8Nx^s zc$2qCC5`vVW-WOX@;Q4sLOI`4O)WRMOTc^He|VN)Lg~y)^ke`-7{M5lNMSY$SxPo* z*hm4zlyHbLDyX7{IvRLL(EIj@5IPc06nz=Ya1uyjDsxC@87tX90mYPXh%!!dfm-Uh z%M)5GRU=`%Kr}JD#wZd=)X_i_fq#}IA#@^=UJPOw2~6Z|7O<3T*07NR ziYeg`WmHf_4Rti|kf2QY(UwlUNHhb9V>C%jWiE@zVl|s6VmAjl&UaLDnHx0lh@dR* z|FokE-Fbyr;u+5rW|PjJSw$X2?BYwxILk$D&`7{?pU*S2qAg)`C6Z|RF_@vmGmc42 zBb9|LA&VT=vzaaIU=N2mK?Rju<|l4*kH-Z5#jMbp_H-tap7du3BT3**-XfJW-Y1*2 z< z7+zx(2_!Lvnan4HOjfdzIvQvqaD_~1Ll_bCpg*q?&p0MAja1TE z#tL%DXDhon$Z<|l#TDvkpozehvLu8~MAC~v3?qSwyv+iZlFb@6Qa~{!9HNX0s;Hrk z1|AZWBR|^Gi5H1xAaRT)iK)zG5m~He6GiOiAjkQRN-lGQ1|AW#%Kp=iE_CM=Vu@!w zQp5=W+6+-W(^xDpqLU4 zQAPz-)KEtQ4+&bMe}vGHaH8nTV1|=G5>uH&I?Gte1_~&qghP~ZnhVrY&t0C-Vyzkp z;{~FLA&xf~M>5ly$6~U`VFMpiObLf6=PcFK@^|j=n5Wh`PYIn>3b@!v;R#GxqWo-%`mH zex{MfJpKRp{htm*5Y6uyMgqyqB#lhgvWYG1Lq6Ns!!atT<~si%AkQB146SHO7+r}ZntlvsDDjMA64OX!Axp?2hxKe`3p?1u zVNOs%C71b$+uY+Zft$=4t!YnZBI!wghA@%@-sCM(N#lL8SxX*;e9m5uP|o*MQ_D^6 z67Zq(k7o%cl+L_FPX;iA5sV>;6lSxKrDU^)jTBH!35O`7f+}jLqk)G6ZI&k?bR?W8 z`ZAc|B#^{Z=8(=ZR$wbXN$C$z{{BVoKiG%>u!C=y6w3Nx8c2AQm6 zJ^2)|ll_!(k~3W33UxHlMBqmo3}P4wOyq4Au#{}pu#p0aDd7-hR8U0?bu{phpiksSTRQO~(F`Px z(IhdIxhx`!)oh}O-5lgN-%-hBZqUFZf(qRKw4)2%d4*Ww8P61Elg^)6MIJ@$;!Dan z%SCR`NI;?a=UIXYr86(llK~821Y<}dh1o1*DcP)HBLx&w!Xe72po$vmXy741|F8ZL zLPx@hqA!CPP6A0xWe({qV^Uy6=Hdv@uZMSI?Gr=E+4Ut5{^*L8Ghgz zw|GF{R{f(Lo#{qj{=g^_Nns9)$YL#<*~T79ImsC=aD_S=Xd>`a`%4?bh@c1kd6jq) znam6pu!L;Zklf__rzbHCWi)>zh1sOBj2t%b37@f-ulSZquJALBJm%@o-2ZeSf@prv zFcL^+CTV1{mQ8G7CkOeO(^PYfTRb4}bI(tE!s$s2!x>95vq&S8HRQ96JshKgYOeDS z0=CJla)t|Bp^gTc2;6P|X+szh^q@bl5>FzNnZW{< zkj*;s*~%AuNg3bs1J}6CeVUcne}d^iI6WA^tGvN@QkcUcvRKO|wy=|fe9dX9xyCIX z5cnVZMSH^ONen|7%^yi&Hfby)hYftfXYA!GzNL~Y{7fT{d3ulirvnj0^LvJoKr%B) zBa^jkVhcMt$k&{vnrqzR0fBoxKkW&pCov3XEXm9wjZD^%&o=gOj0&o`&OZp)XIA+Q zAv{L}J?KX)BN@v?rZbOsS@`PV~Wv}SW z%M4&BWBFgCvY6$pC7*5V;TRQM;41&gBc49yJm!B8MStQLLo%~i#9zpzfSnxTuT*iB z1_DZ*y)-9?r}?iuOG|?J@3bS7=jcp0FA>G>=tW-!Fo+?IlI}z0S;428Q=0fl~i+?|4kjg(8vP`lcIFUrri+;o~gg8bJPXgnaND9-L&7VkT37LGrTGq3X%@k0?XY67x2RX{u{FT$3 z=LfEEji0&29Ukz6ps&?KD?;c%7ha?XeTm@@yvk5U@&;oVM-r2m!Zc=)$~!D(DVb!m zlC|WriH|9wn4SCw2RX_KzU3_ExxhuPaE+h2#U1YRn14GVBc7!-?RbtZyg+xNd4)l| z%1A~tjyFkR2J=W~DVb!mlC|WriH|9wn4SCw2RX_KzU3^H{6G!Y_?iFYE{|wd=8olA zg840-h#-n+Ug7t|GK@DEOA?cr#%va_m}UGsYuUhN3Mpn6`#3@w-*Jv=u5g3@nlM#&9C?ktqCENj&vrRNTTRPKVld{93zM)f$>Zvh3U-ZPo%SiOg>;O>)FU=3Mk?; zcCnX(9OY~N%4yE?16R1l&)nh;4|qb*H|n7kA#|V%FVcg)#4v<7Mi5T|jd>fKpCyl2e?ek{_ty8g=}_Ke*3hn*Y^v(vo1>5k?nY z;AMI-fWgEuiUj`1WTunK0v7QeS$x16Hjqyt+t|ro4so2na+WGCQcE4TxXU8~zjdF{ zincsQI4{$O7-AX5>m)FqNlaxH^GIU}S*&0kc@(gf?UZnkuPCR2N`9o4I&Sk%p77Ln z`bQhu(}@VW(~AMbGMv#QlFT&blEza0!YXpfXA9fe!x2t!it}9J8ozLlfK&FLAfDz| z{D#(q5K2cn6HX*i^r9az3?YsY#FM~yCX&K*X7eY~Swbcsu$J{~WHSX6@fo|=%R!Fv zHGkza=lOvvT;peMafb&yA*ez!Em?A#o3-)n@9-5BL{>r|lKLp$(yQBAjkS(~rRnC7!WNU^3I0 z!#iY<#R}GuM*-XTf&-Ltf|H!$ES3B~4cDmS7yiM09@G4L&q+&yX-61cc!8Jc#Q+8q z$0!o`Ba@joXZxJWH^+~O{e2s~r|X+>L}Bb=A% zLkzJD<8=}k&m^WYi+QB6ge+FDjyww3%63XP$XAq8K_x#@OC7iQCr^0ltp3r4_H-hG z?(|{+u?%N4i6k?Pxumg_zp#p2^4Y?6_Hcv~oZ>u}xW+HsBjB7Yd5ULfNigjQqYDvq z<9GCBAVU~NJPC|vA}PGhT;3srWn{C8Tt1|bVs^8aFZqfxzU2&6T%wj6{K6fYX!id( zuV_gd+S7>$y3>mR#4?=GB$CWD=90!zviN}2OZ_bA{{Nq=EbV zi=gw)9)kHToroZcJ`5s`c*Zh;$xLSs?~p+jD_BP!1#IIB4p7QBoTidXT;(Q>JfeA} zY-vp>UFb${Vu)oJuam%dCNY&+%p;8@WU+#EbT86dBRgw z@}mvy=|lwG>BRtI8O~@DNoE>zNn`4z{{-oXCs>_poq`d#a<3_l&|?Kr#a6LT;Uo&bBjAX z;0ZxLsE1aB(19+zNDulF!w}*aK|BeJXCf&~XEuK#oh4-Q0c*)+6CYE=XMDjvj&Pil zoTic=siltF+~EQLBJfA|D!-u(p>!ggZbZ|M!3-syu}okx)0x9NWRS%Q){#d6+xUV5 zlyZWToZ>8%{6G!YsN)y@!F?Xn{G#WiCBd{Kj4r&u%k*LZgNb7l3H*`COed8EEaE+~ z_<%KRAfH0Ev6Hy5EvzIUViZZ_C3{_mBmK*%S9hzwNH|G^CX+wKD5kYr)F@RWx zGnzz_nZ{hwSV|Tju$o*p@d;bmK?w&qN*UjAj%u!OotrdppMMc_#o0qJzoioqMA3&q z#1YR}CNP=l%;6m}$YKTS$fJO5e8B-q`G(U}a*3)E7uazyW38f3&=uHf<4C8eY z7|$f8GK+bnv4kvEu#P+m*vfWFILKF&Q$Zy^QcE4T`6o|!>VM0RHngV`5p<^)1Bhif zqe�Y0M>!rTm3edTRIUz6nz*(9Px~00+X4} z9Nr;=ELO0NJPO#x7aX9JZ#YdQm$=GJ8hJ$XI@!{iP`c2K-oy~gFkUBt@l0YWvzSL3 zOUPmc>&T;kt!$@+gM39f6;$#gwbXH&fAWN!70vjiEI4AJp%qNE1sbhZ3&|*kwnvv!3-syaZF+wsVrm(S>&*u z&1_)@dpOJqDyZZ#KXIFTJSOm_nV~i9=}aU&>CX^GlE9n1MJj2$Pd01Gqma+p%Mr@? zo@#2j$z1~K{ajk`Yl3M+YW1QqH zRa~T&I&N{7M+E-j{f$<%REE zr=B}B(d?GcgZA&Tt4DccC(+Olu^NXE^?K68hJ?b2K5t62c9R2KKvhs?LMsQ zI{z0u9Pl_Df79R*R~=Dey@6)Xa8z(qj(B7u?+RC3@uwv&nxv*O-ry*f4w##w>540v z7OXchp#|%0-qHv7KhPYsJdexk@voon>+^iRU!M;bd`FQ)GO5gB z9!tq)9h)hjh!T!a&Ur3VO)U*H(aIBo{=GvWU>-Wtjb8NScMM_}35+3$@g$SNG+tvi8NA7# zS;1;@c$Y2Y^FAN4m%s5DM>xe7T;MX*d_z5rw9v-C_=Vtyb}_%9D`7+s$pD5hoYA~Q zGEZqvv;{)0#SOwdn0Cn1E=gWmMz zd0t>BBNtn9CxvSVJ!FvYC9|=OgxUfHID8nhL(;DmC2V z4o%$W5x>ykiQPjeza@ewVu)iDNhC9c>C7U7g)AeRTsE+k0t)$<&p1Xo=ebNZwKUK~ zD^CdeS+;Z`jJ^yYmIM+R%gdxNjhW100hwg6np`%pl>!RcM+s#d=M0rpQO!5h(?|Wpeu2RD-?$E@29`Oqu zf@Dc3za@ewVu)iDNhC9c>C7U7g)AeRTsE+k0t)$<&p1Xo=ebNZwKUK~D^CatmMvWf zqb~!9C4of7@-it*VEVIYT8?RPzn>G}6LPJf&j?`O%f0 zL=eS5hBA^w#xaRh(wNI4vRK1AY$Bgs?4g81oZ=jpxJE6vxyM5S{xxHPKqd|lw+Lb0#~@sP3mdnM;`Em;AesZ{tKPy&T~Za0&yhpA`?kr2I*u5ptFnrY=R zLBBRXq4c6ZF~l*7B$7#G7V}t2HtX0-0Y#K>gmTVvnQCfjpovzV5cI75Ko`R3%K&0Y zAc zpojw;;Vc)arj8$IBOt_lbfgm@gwliF^d*V`{DEP_GlsDwlfpD!V>WNFh-GB6mi25R zpPdv@Oeu%?oHJB#k*~Q=e8w@#InQOPsilD?T6scH7unKszQ zA9=tNg1g&;bf!Dc5y=b0k-&>gB!wBIGoK}7lfy=~v5UPN7=uOC9EQcJo4Gieo8sYX)37V8aHX6nN}VX^jrNPlwR~F zhB!u%L^7$&VjfG$W*wU;pokKVP);S6xJnIm+@YB^+6nAwenRL*IFZBQjPVT55=sxk=|?n! zh$Egv#xaRh(wM`1GFib}tRs(nc2Yz!r5xid7r4T8Zc}Bz9{KEMKcyVyG!;~Fjhi&kOe>EG`k(cmPGK_)B7C6DcVNHJxcq>?M#;5+Wp!XpCv>ph`_(T{-)V>IKL zLK+!lvXWdjv4bKGaD=m5q?$T@ppAe??>}^+Gu`P;KcX4Ja7ObI$xLM?b6L!CR+CE} z+xUPz9N-WqIY$-Me9QN=@Q|Mgj*>53=t&=<8O#XAFo6_a<#iU5#oMfB3k4MM35PjF zC0|iPJxx3y;Q8Qy|IDumC5%4&p23V{4C9&13}*8t%UQ#E-eU)a6jR0tDyZT*bu@CH z$8`9e^F%koi6n+$jAk4u%wP@+S;1O1vYkSTDdPkcT;>M#H1mL`Jo9@q(wpZQLIN)` zkrZZ-&U}`TO%5B`#xC}9kfW4yfv>s2EgHE`JHgR1r7OLOVh|(v6Uj_vCUaTL3f8iL ze0H&qPdUyPT;e*nXyiWa1P_oU-H0HXp^RcIDZIuTEM*Prd5;|wQcM{qsGy4L)X~U& z9@Al<{OC>uzhemTBr%B@%wZ9KA(zd(&t6J7&KG=1HQ#cV`#hn;3&8=up$B~#$R9~0 znQ5f+CM)gIN(3gfnV`&{Dv-cBaCqR5J@yK3}rY8j3J5f zB$L84USl>Hyvd(g!D@1Nmo02#2Om(#UjD|X9OgKu`8)sMGS~Pgx46v@{74)B;wc>l znTO7FqZfVo9fKG~0%J&GJjtXmjn|k>25<6bRZqvv;{)0#SOweGTlMq7bL2vr0o<>^uiKlcN>i*G{omn3giw0Wo4!ObfIl#dc*Zc6WKx*MYs}^i z7O{+M*0P>W)ds=wN&jgRu8M@GuK14H^5sYC1DZI+-EGCP$S&%WdxQkbwU#D>~7c?)0V~(F|cYqj`yBrZSVcEM_^Y$t90%e83(KaEOzf zql#+2<$GFq$j=0i(HXkXlRiWntXVw^`2?3Mk?e4s(i1zM_VDns|Ue z{s;)>8J;DS9)#16Xa*5SJc*2B5~-vyhxuf(g11;l9{KE~h+;}P##t_Kh3nj;o<@G; z0Z$12llM0|)1Bvt1O5QNj_*spJw@siBTLG}A^qfiIb#5V{dgBr(JiPa+eT%yiOO zz!FxGLmv6;WBeDB=J|ILk$tn9CxvSVJ!FvYC9|=OgxUfHID8nhL(;DmC2V4o%$W5x>yk zWnCqd-x5I-F~l*7B$AoJbY_vkLY9$DE*scN0fl_bXB?xP^IWEyS{i7gl_vzfB3rr; zMqdUHO9F|EBAHZXF^{EWvyROaP(%qwD5sK3T&0FO z?$Asd?F3FWKOuA@oJeAbC7whkFq!G3vw$V6B8NQk+0A}RIm&4&sNxzoX`q=_9ut&m zenRO*e`1JZ6iFnL$}Hxwlx)_qnF5L^;RxlN=Q7pQ(m)ffJRxYB{XiGO=*s|NNg#<= zm`WNMWU`W6^4QLY6jR1YD!IZ9zT++}JRSPCud%!XGLA{4lExh7lgSF+VjX$pvy&oCM(Hh6FVs407p2>MXIUe2igco_x?jC zI@6ur^dp)f3}-Yik<3(PGMB|HXEnLxv5gPd!vPL)l5IY@vW6KH)H@sN^eZsHces_>xP&f9BVO5=I|>&tOI}hVe{h z2D5pS<*Z>n@3DhIiYem+6;yGZIvTmpV>-O|!qmIZ8Pf_?jEsqLKTw z6PzJay3(5{1~Gy^k<3(PGMB}yU@aTSXBYeUl;eECC9ZReM()#2@EfwE8xce^lu?W& zh1Yn4rL18+@3DhIiYem+6;yGZIvTmpV>--}AKi)IcMKt(BqlL~IV|EY5SblV+ClN$3kfDquk#S5Sl{DtEh%DCd4x7kl7ken-5T`iDC9YA+ZSL_9Uv3QO zKqorWo!;~#njs8lG%u0NRAw@l#Vltvx#Y2p57@&24snumR8h^hd`}Ax`I+E9>kM7! zNgtva%m~IXffQclbrzGw+pK2`1r+fKhdD(hUr|FnO*|lAiRiEEl-Kb#78mBR}$hCj>9`9zMPN)2_~p_w+?30!915JES?i6n+t;z?uzlbKFB z3s}M`a>yf}-R!57qnxIKDz0&p2AXN*F+t1qgHU?WpBUm8MH0!RGK+aEC7X3@rhpV$xJ7m1uS6|IpmSgZuV2kQBG4q z71y{)1I@JZn4q`xpHO6 zZSxaCH^PY|hFIcBWCD|!PC5%%!YXpeBcI*ur<9|drh+Q2agzp`Y2`6NYs^n5z35L2 zaf~8~WKx;MJeHEpIyO^45hWandd7>NPL=wX=Ml+5SW-y0^ ztY9r0*-jzFlyQOzE^~u=nt8xeo>^~3dh^#lEMtqna>ik$zdbg*u`EBa+Go| z@HIEMMI-lVC-{GtDP8GJ6oVMSpGamZGnva`R06A;pw&f(oj*P92Th=P?~N$dB$s@H>VOPZE=u!5kLx z7joIm`|PEZ<9xxFRP!x&xz7_iZ1nR#J?P6o{zxLpOe38)S;1e~L;-vGl+UT)3OBh+ zD*<`#8PD)6q4Xe}enc~fIO0iU9Fs^TjXBIGlNG$hI`YV8Cq)!f$}!Gzfh%0+CiOJ( zBM*2&@FshZ&UEKFB6)#05_pk`q%ebY=Cg!sa@fc=cCnX(9HpE}E^(C_>bOHQZL|}( z+4GMOx)Dw!F~ky2A`_U*bkbSC5>}Bz9{KEMKcyVyG!;~Fjhi&kOe>EGde2!RlwR~F zhB!u%L^7$&VjfG$W*wU;pokKVP);S6xJnIm+@YB^+6mlZenRL*IFZBL{fQxtQ6!N}Dzli!QnFdcW(p{x zgd>!5p378IO9M@`@`RxO!}F0YgwdA)#F9V~uP~J~GRR~lx#Y2(4=JXMlT>nr8+^xI zT6jd@HoYg5F#0i&VT@)xQ%EC&OjeT1CU#K70giB%i&Rs`53~`GZ@Br}zn%w;jlSxqi^Y~us=aDYRcS^Ku0sp7xKfflFF#7O&1~ZZ|jAt@4n9Z9kXASFl zj~x_JOc^Jrpo;6%(a3!s(_x46L^r~TB!*#(W*jNZU=9me!CE%5okEH!;{+94<_7gN z^MI#3Q(#7V^E^XH;6)~q!VJ=x&l0l9VI$kv#a<3_lyWZcH8;3LBll@1_F*P{noXXyiVR>F|O4=uQN`V+ipiF^L(>VG(~Jm(9G-UP?L67ko)I-*T7x zJfXub&wqN*mx26|M3R|CI&ZRqzp{w}_VOv8Q^6H(a+g*DcKiS7L}$9wn|?$ygyD?l zC6bxSOy;tf<*X)`Jht%xdpN)$PI8Vas`-}hY2hJ16a1mB(1o7#A)3LAUSB!*#(W*jNZU=9me!CE%5okEH!;{+94<_7gN^MI#3 zQ)EVZ^E^XH;6)~q!VJ=x&l0l9VI$kv#a<3_lyWZcH8;3LBll@1`2UhAUFl5}gBZb| zNM-*mA5u&iC#mELHPrL})5gzq{F{AB z82xyGKa$AHOk*~SS;1O1kk4*Dri@cm@-_eDHb3$&fn)PgD7yI~(&#B-m{>g1x zctqd<@4JN3i%14Bl0WeZ)0oXd{z5KWc%MBSg#lP_zy3ma< z!s$aK(Zn#6;UqAIB*v3W3e$Lv*<|o0e`W=%$>CkLu#FvjKp}hi8=rERYBNnskVF`EqD$Y z582D#_>3c*;tMWtnQFeFo<>?|<6rzj@c(U3@f*4lMg)-zU!R+n9n#yIp?^*C9Y7-KdIw3jojluc*M^H9r8H|A(S5UrZ3O)0z(%H(10nvRTV|Hj&RxiYTU(!+g#eD!9nkT&I?L?sAVd+6g>nUlBrA zdJ;ht0~yLl5*f!NQb}Vji^yUPxxC9}@_C<+*vA3NIL2uz_>!yCaEm)Mai2&0LWkpa z525^)2%?A~j!`6$%oL_GiwqXBjBIk*z*Y(<W>ILs+3`HC9qY2pC^r}cx5bRvXMdeED`L@|IrFpPM{FqULen8s_& z<_#9HjBM7jo=xPllOl>KoBldBCGLCVY3clnjHQeG3P2A@ZztG{VED7beL=Z&`af~8~ zWTr5kS!A$~Wn`1f2DVZ_As_P@$0+AKm#LP{=+?DC0P1sHBQ&zM-B*TKI{lbo@eobfqT|L@|(|j3kk9Od^#u z=CX(^*6Ini&S+jDnW@ZVE{j>t zYI4bA8y~QT103Qc=cuBZZ~2}U9`ZB6=X8cH^rR2b3}yslm_Q1z@;Zyj;%(Nmg#wEB zgu|SolCP+to+cg;P~o~f!?T3agK+v0%^>24Cy{YXB9%1eFrQ3T@D}UHBcGiVQA{bv zILigDaGjgf)5woJ;0eK%-rwjUTdYuu!PW?Fen&_(kTN-z2oLmZ<>BAHZX zF^{EWvyROaP(%qwDCazvsiu|&nrP(-L0{SrbRmqs3?P;Sl6Zxwq>(`;E6F8~?R-cv zWt^mvE8O5a?$W{|0x#)3p@h+ofed3b4;~3?f=Q7pQ z(m)ffJR#_7+0unD`Z9o65=dk$FO$MFW-^BbWRk^da@oLE3MgbBC6sZTGgMMVHQ!KA zBQ5;IQ#xLeA6@B51W^oRC?iQ^9Fs^Tjkzo$i#5E%Ci2Ktn8SQBS;1SZBaeJ`QbaMO9OEn(xWaXAQcoj4@_;77>Ig&CwXpCx3I!$!8Ti@hA=DCJagiL2C5#~qq!qn*I(_6;F)Bb-QLh$WsxCNP=l zq_cn}tRjaz^4ZOPN;%4DDyZTbH))`mRvr`d|LO;!^rAm8#4(B_l1XJ2^H@qY>)1>I zMU-%aaw@sRRcff?4$ZXDPT&pm6GAt_i6n+t;z?uzlbKFB3s}M`a>yf}-R!57qnxIK zDz0&p2AXN*F+nxvCzM|FCx$pikwh}7%wir($z~m!DWHfFj!@2dE>le{4K&fp6N3I} zKhT9R`Z9o65=i0|rjkYmnXDw2Jht;8#guW9O0IB&@3>0~j|lum?+GQ0ehg$7qZ!W> z(#Rl_mE^LC9TahZBb?szQA9=tNf@|FeI@6u!h~x$0NZ>^#lEMtqna>ik$zdbg z*u`EBa+Go^xx`g!sN)XJw9!uBxB5>A-3TX=7-EShkqJy@I_WH639HBBspHhx; znhL78#!VV%rj^G8)#*Q>^rAm8#4(B_l1XJ2^H@qY>)1>IMU-%aaw@sRRcff?4$ZXD zPT+UuCxmW<6G;rQ#FNMbCNrIM7O;d>$OeRb1mH4K&lrV}fp(pHO+G|)sVPY9}a{^>#(eHlP32_*3fQ%NI( zOjeRh9^3hlV#+v4C0Dq?cig3gM+E+VdQT`}^kX2y7|nR5kVXcXtR$CB?4XDP9N{b% zsiuw}Xd|G(`wyMyOm}+Ik7$N4oYA~QGEoq=}i=a7{Q-NW-2q8%VJirmJQ^yi+%rtL35M@=R#!SR}x z#DrWWrXJx)qmmpoX(X2n>KN#FUVps){r$er=lwj-=gWmX9O4A0so^ROG|@uf&$1+h z?nE+xp^PMnH+h>yEGL(BY@&z~$~a5~Rn$;N15LCN^f&p@neIGKG_fQwjufUdpC#n5 zmd$LVltY~0JF2uGY92StlGIChOhZIo6c6L(6A-B|6y5YH&akxVKxm`?`F`4el%r;x4eWG_cK$!RWd znd|(*eFBQ zXNcfMVu<5a#*#z|Y0PFJS!A=C4HUAC-5j8tN=|d0TI#q#BX?<`%{}{u_Jj~l1W^nm zmUzZ6p2?&!hlRXLHhJW;h0iGE0LQ4HiVIxg8jUp5O56MTgJ8PxEK$TTlmrq4PqO992~WIyFpa+>qhQpXJ%xl0Re{-J)_6GAub-7V<9Hu0 z#%vanMK-J1Kq1@M%>l}(bOB8cWI%`WA)RX5W52QSc{Aq;0U<4Iu}b6L!Ca#_bFiYTFs!&Fd34Rtio zL@Po6B`BahA%qh_6oVMXD3VBFI`hb61*_Re5havym@Zj%ea| zm9Zp|LK?GKNEX?wW&?$6V>bsV=M-nT$WqJ_ZU$dpcm(VKn@<`oi|$P{LfP9`f@ zMLvaWXAg%s!D(u^N&`)_5ZF$ZgwUNx1~8P7B=IJ1vxw#7vW`s@Q9>Dqsi2A)>S&;e zR)YSk{OC+~o+p}E5*SAc)0xi_a#+h|wo%F z$s?bSD5iu`4sx7RoTG+I)YHIi?(vYor|dyG(3xk5;6-AH<5k9zL<(ulW+7Q*vziSQ zvW?vwpqxrhbDmo2xIrU#X`#*2K>@#^Jt2e>K@(vv<6B#s1L zXCkT0WC2UbA&-rGLJ4IYp^|f4gq^pSg=mFCd5~=|E?~=tU&ayv#60kjO-)FoSd!vy2?_*uckZWfyxn!bz&A z<_bS?hxa!CO%zc=8HcH$iW=%@povz3Ld+8(gcCs&gBZpr zl1O1X^T=cctJz2qC6sZP3eIqmdK$UMW7>6ABVjy8G;zGjSdvH~joBc2fkL*i zn*)?{inCngDh)KzLSPq}(upv7(~rTtLLw8H!VJ>MWCg3pr;zRJ;SeV{O$}FRpota& ze=AEu=uRX97|KYJc$2qT#By?3$0mv>p^U>+P(=-OG|)sVL0#oXXS(w|(ZrI#I8vC- ze3p>IS~jzdQVwx~@2KVqH)-M_L80z{y3mupyhJ>SOd^fBWby%PC}10V_>v0FafzEW z6VT1)^CTVUOc=e0B$}5Q#t0Ib$P{Lf&SI94LmnIWn62z$FGn~@71dnfC+={cM+AoH z6*|(D9z@cg!3<{%NxZ>Zq?5t>KJ~%2<*}A&uEAB#UfTvw=dkv6};wbBeQE+wI`dgV4r|%WHcC0f z3BIG6E8L`shXnO9|8$`zeR+v^5}8CAbIIfb)=KIH@H!JoWhM()N)CB!XDB~!VoaG0ubDLiYeBSxdg&y=_5Px7S z$xLG&OUPk8AG3qKlyi!+T;wVZG|@uf3+9(jgwdOR4CWOQNoFduSi~}N`H(`k^95g0 z!T0>Yb?)$hHj&OVF4K|BZpOdNC8D`XD4MG;wvhtqME-_PXl-O z2akCoT7Gn*E8Xc$Uj{IQct$afWKx;Id@@+hpIAdag=}RfdpXKUPIH0FT;~_=6EHwl zJV^&S6Gks0iRNX7F@i)UGKCqWvzTS%kjDl-W-Ghc%MngeMKxFWi96iq5rG5s3?1o8 z4B;MdH(#ha`a#>FS#eB{_j#A0@)Kbqa?hz2uQVw#QQ=FrQOVrcAZSL`qz(MW>I?$PCh~PzHh~rhp zl0*t=%w{23WV4zL6ta!o9H5*^PII1G>bOB8cWI%`OZE-z2_c*aq8Lal@r+?SlSyL^ z3wf7p^2lckpHa#Ij!{7s7r4YV8fm7LwlC`sg6YPyL=nSK5=bPOsmx*#S*&C&1r)QB z{ghM5Y0gti9XDv?E-kbftbW=PLO2mbF_2i|8N+xclg1nt@-ErrkuQVw#QQ=FrQOVrcAZSL`qz&PhX2Ric%5xhtYalFb{l1L$q*(@ZBY*w>@ zLbkD+1C&$AY0gti9XDv?E-kbfrvGVA2;oE!#Xw?-XAI++Od4}o$h%~dM?PElj8YD8 zj0&o_z$LEHNHeXp{e%7|m~K2v6fq1Xfkcv-$}AR<#Y)yvKruVnPdSyG<~+63af3$g z(n6cz>Zd&+gcCs&1BoS`F^p$2Y0P0E?~+X(`E21cN;$wWDyZTDm$*hF&9u@sUi}2q zjc17>hM^>oNHSBI#Uip;$yy31W+(e8=NryY&1J4}i)J3u_7(F_M?&dI9|jUf0!!?AG4KR?Bxh2siK-I z{KOsZ^N7F^@}(nP=|Lp@8O(6Tki;9jMLHS0PcG{zpqS6u$5ATzo?7a;#XSN>`uzt_ z5lkpOc!B;5VK}21PYTnR%VL(3%Q`kuLhC+45QXEqDSObMkN_IxvnP-ULMPi8KRmPG;3Tez{Az5Uznhg}PjoloeoJvk}o?7a-K_ho*q0Rqr z|IwZh!igY?fy5He7{)W1H0H37cgZG?e75izr5xZG6;yG7OI)LoW?E@G-YgMJH=ZSm z7>1HSBFRi;7K_MYC2J|5n4RpWoJvk}o?7a-K_ho*p-qzdX-^2@L=eS5Vu@!AeuC-7vqTZYP!dQanW@ZT5m~HcEd>;_ zll_$Q4QHt4GS|38GY@I|zq=plNGLt&!$9Il;B_XF%1joplpONd$S0Ig#t|wx$3=eR zCUiC(v1SH!pJV^&S6Gks0 ziRNX7F@i)UGKCqWvzTS%kjDl-W-Ghc%MngeMKxFWi96iq5rLEBOGmoWgGl-_nBj~e zi8pwQbTW9KT-H-SF`u)Kqg3)ewbXNqdj$N^{m)Yb6G{(Wpg%(x&S=Jy!ZhZxnC0ZM zj!hI%LK%mtpo$vmXrPH!f+m|MLI@{KJ~%2<*}A&uEAB#UfTvw=dkv6};wbBeQE zQ$R7FvyY=x@;$ZGbBlWfq?v!7BA8Hm@B;lA!f-}2o)o4rm&Gh6mvwBSh!V;;Oa)cc zP)7qzv=TH;{}4hr5kxVFVT>Y)6s9weOjfX(jTBKr8HcIh3>T@Vk$XI*-E=h)#&bjy z$E%Dbi4@Y9%|f!sW;GiqWE;CVKsl#4%SEozKoczlz9myS5k_zNF_>3KWFk|TK{}bN zU={fkvYkB~;smFu;VKO@(L&%1SrS5bA{oF?Mv}yvyv-t(lgm0bQA7!49HxRQYN(@u zCRz!aDL*>Xo#%-rmITI;!gS`dgdEngnQfGEh!cEAHCMPv6AuY`+x*jop7iA<;z?u@ zY0M>)4_HG1+t|aGRB(<<+@zU+S^A%+2qu&syg+}3Fr3khCxvOuWiiXiWgVL+qJ%OI zQ$ZCq)X_i_tpv?>euNNC1W^oP7^6rch3U*AlNGFHBSn-@#$hTr!$s<8fq?5@C zR*}yZc2LGqDmlv!T<12w5;)KK(S;uLVGw^{EXhn`9!tn!Js-1!y_9o`vs~mV4K&e0 z;C%B-C&K7WKL+y(i6k?XSuA21xqL_=+xdboso;Bl;5v7BK$~>$y9CpX2>LOES9qOC zOk*BP$YDL3*~)GX@ik|t^e_pEyP^jz2Puxn!_{JT~$ve_$s?bS zD5iu`4sx7RoTG+I)YHIi?(vYock~4v=*%-j@FFq9@hW3UB84<&vyd#ZShM^>oNHSBI#Uip;$yy31W+(e8r;^j0r4PqO992~WIyG6!x^f%%r$P&%tP8P^?po8Lg`5#1`+`J$pV&=!x}bG%r5qGoNuY7 zj-RKJ~%2<*}A&uEAB#UfTvw=dkv6};wbBeQE zGFicDHc~_hWgMo0 zGhC#eM(**Lc7IkQVLV4PalFb{l1L$q*(@ZBY*w>@LbkD+1C(=$vs~mV4K&e0;3}EY zi7p8V)ccb+GjSP~dV3e%a-5^`9}X0}nvAx`ie)m-5w zO*|xMjrpewJ?YC!#FNM*(wIvoAFzf3wy}pVso)%!xJfesYxO@*5lkpOc!B;5VK}21 zPYTnR%VL(3%Q`kuL$}ASKj9fmXknMcImsIdQKX9Ep zJfKa!_g#YNMg;vB!YjPaB&IQsCFHQ4&1_{ihxnQ^)N-BM{7T?P=S5c{=uaFY7{?!( z##}O3K^`0Vl)tc#ulSZ~uJSX@JmNS1r=S1nMsK3|JtIjXmDyyF&3ZPomE9cTYtB&1 zb#C)3ftx%(U5TJSag1UDsmvjRY}Qf84)$`KDr&jG-w7x%hdfCKIuk}OB8lc@hB1Of zCNhN?q_dc1Dq zsi2A)>S&;eR)Rj3Cn1CrK@@`+#we0VVLJ23WCg3)ND(EJahM9uaFKc%xyNJL6{?Xi zo+Fw#US%vvq>#pJ7Lr9atJy#y+t|$k$~nbZE^?IynrI<#i%jW67`^GoU|u1SiA-Sz z>148kRpe91cJ^?H6P%`ot2EF=3xS`=k`THR$pD5jk|f^bZ5FYdT-LFPB1$OZFcnl$ zLmdq?(Mr&#@}o1|d7fxuNnji)OlLkz$YCv;*+wacIKg*RbA_8U@sOY*_di|eNnc(f zo)1pQ zC6sZP3aY4~js}`&CFuWheuNNC1W^oP7^6rch3U*AlNGFHBSn-@#$hTr!$s<8Q$p#*i@ZcUuQ7>f zq?5@CR*}yZc2LGqDmlv!T<12w61d&@(S;uLVGw^{EXhn`9!tn!Js-1!y_9o`vs~mV z4K&e0;AiHSPK42$ehlUn5=mw%vslD3a`})#w(|vFQo;B9z;*8MfHpha{{+*G2>LOE zS9qOCOk*BP$YDL3*~)GX@ik|t}$MDu$_l0+)A$sn8cY-TIFImFkTp_c31=2rqg_xyAvg8sxY ziV37LhYYe=M52QSc{Aq;0U<4Iu}b6L!Ca#_bFiYTFs z!&Fd34RtioL@PnN)I$j2L=eRwhB1mHQkc#>GFicDHc~_hWgMo0GhC#eM(**LcDvO` z7|#(+90|P6L{gc_0+y0P9vk_D63RG2CFiK6p1*OIM?A5|{1ZwqUgRa>d5uX-Bb`iE zu!?-Pu!Ay=Qps6<;5xVYmB25YA6@7{9|rLU#*)l5=COnv*7Gqt*h@L5ILk$@(m)d} z1eThAIuS;1`Z1VSNFu6eFq1{R$Dhfkh@Bkd zBIfJi8q*wdu!)Z;VjF*95BoU8F}~(MIKu^g;40VoncLjuR~{2| zLOpaKgl_cYdHOMkIEItJXc9?c5^pk%nat(i$z&PX{F(LSvzbrW#$Wh?{T$^4r#M43 zf2E!V?r@i1`6q#2>qq{LPK45(2>KAs%M4=#iA-QJQ<=#;-XV(|R`DSP6tROZI7m4s zImKztQOyt3ah(Q!;qN@)5p7R;PTCVp7sBYtbG*m^hA@l-#*)MznaWJkS;P|FBZoh; zj*S#j%no+5kHehcKR8DXm#C+K+uY+Jffe2>=s;(lA%Yi)A&z)P@)}7@VhYol!vZo` zMh>g^kOGR>&Q8iW#8*^OMKyn=o(Asl4<7SGrSqc`UFlA5`Z9na#50O!-v;9Jg8!)5BZ$uHccg*K<`E85eEu5_n2eHp+I;u*y_ zl1XI-^T}X2IsBQmS|`a+Mq0qKOCmlc4{wdkE&Ybf-5_#4wZu z5}CkcrZSUxyh9c_tl~ooC}Ia+aFBAo;SAMW<{GzX<{@prl`S0!r6+wDNF4Eu0%h_9%mifaB!Jq_I9A3WxX@8m}(y3(EA^ko1;h-Vbz zNG6pT%qN58{E0Q>Q^;0!vX`Tr*dJsu}1~Z&7B=H7skxmBhlgoMv zDCTqaag<8FruGY92Stl zGIChOhZIo6c6L(6A-B|6y5YH&akxVKxm`?`F z`4el%r;x4eWG_cK$!RWdnd|(*eFFX;S@9$t=u8;Bh$Nbq8O8__naC7okj`S3kwYFE z_?WHiVlPKHNfp&x;V15JpGO2<&@*(TD?Ny$KZ6<07?OB{w@4?0_sL~F1r+l+`#4G^ z-&0FHx41_@weO`JPZLZR!s$gM{fHr!ct$afWKx;VY!;Bod#ognd_JO>5=uG9aZYiL z8ZJ>!1Gl-yLjr5OztMrtJVOL85B?B)RFRC1d0)KbR{ z8o5ggZT?^ThW3OIP6Sa5B$jx_FrLYzF^7e`OE!7rvxUzn|{UXRC1d0)KbR{8o5ggZEDp|dqM~&f+z+O zOFUy3&t%e=!$RIAn>_N_!e^9nfMZlp#RV>LjYgVjrR@*uCzx(LOB68-C4oeenaV5{ zk;O{ZQa~{~*-ts&aE59wbB$Xx^N_ZGwIAq6C_U-JK;lT?btaO^Oct<|9P-%6CzMde z5h^*yMSkQacX&XXOZuK*Lg__c1~H7$Odyq+EMO@)tYH(y>|#I1`Ic(x_?f!|Tvi`X z@FeXCrVC;8q&I!|9fOEvI3r0UiAlW4G~Q-D?~ug`a#=$@A5lyRrR?KNzM_I}IZF+f zsplrYaF-U^T+xrTrxRW2PH*}$fFZ;)ig6^9$_(a{!E$o=Gi%9bGoP}ZU6gT%p13MMI?%U2I(wj89C&!fsfhBF7|SSlT=a76@KCl_jyF% z|EFi@NLP9gNq+`2oG~Qv25*s02Je&0dI~7!bM|qRO1`I-dTw!#fNQ>&c05fmT?nTa zk@O>mSmGJQIFdJq_IE9uEn;ZV%Fd&OAc| zFA_r>uQHY-Qb=Pq3&|pz)oh@UZS3X%02%ue=GP9>)~Pc3!appm<@(B`K4X-^2@L=eS5Vu@!A!#NpHM;>N2uf+7x|H!+~EOj{-*B+`J$pV&=!x}bG%r5qGoNuY7j-R|{UXRC1d0 z)KbR{8o5ggZT?gJv?qjcB8XxjvBWcm@k}O-IV|K|vdJT#Eqq2P2RKFrRb1c_*Jz}f zR@&ZCKf!e4S)zzxCfY*~Na2^DWiX@iTV`X!icYlXRdnVe}%BXkKO*BS>T-QtQ9OtRTX0Y&WP5XU*g zIqJAZGp)1}{EI9JqaV?{z!)Zx%xk>CO4gIdR(4WM85L9#poTgcX{MD9LfYj=FZ%H; zvBZ(cbW)kmo2((1E$pI{a*lI`uc_rKw`k=7Asv1XrZ)o^!iyx3#4OTTN+$2JnL8;Zr^%z*k(Lj_+vV7Jua)?R0wRJfa&t=|evTF@zTwO#+jdP6}x(;7wMuo?QNo zEflbeKeCqtRPYI>2=FzRXy6(*xlJoS^LIl2uI~xuU+BjmVi>^~5=r6}W;2(CEaMMk zk;_KjqmW|u@n=4viZ3}&E#GmS+qCh3&W~hE55gJ1V1^S<0+aY1$;@I7^I5`jRJiQC*KsI$LISDqx4-b6BxXofO^I1-r5bW%uTK8smSCU3KWd+@qaNA&&+9if)7vNfa>*CyoTBGK1NqvxF7AMGpBCu$zx4=NP95P{U=e zaGe&~=%Djs`h!sV@-#7wU<`>Qk-}USv63t{u!TZO*w0a_sOB7(XrPgsv~Z7hI(1P$ z-3TL+C}J2+90^Qi2D3?L2`hMu9P%k(Hy=^XF-{SnhRa;xIxV!(LFZqopHTYpG%<`| z42dL>!dw=yk}Ni`g+fZ$&rz!QlJnH^9oM-{8xQE*)&4*a!WqC|h7(UBFEf)g7P6eR ziM2q+~sFF{iD7olyC+zgprJ83a^mHLYA|ZTsE_l5)N>b(|koO zjr_0EMg^DY+wt8l(3(pR8h@2F3~_EH)-J>?R5HQ_0x?oB8eh~;lz=^ zRAw-nbe6D!x5y!%0(SEe~S{nJ0dj$3H{KMmP zrxy_nB$`-WVk{F$VkUD~KnAN=M=tqn=L7a|fWw^N3u>t4DnD?SpLj@csC?-`ANmu` zFh((ssU-6%uam)Q-XV`|6jH*+9N{F@d_x0G+~z((Js%5tj3)>soc=t=Fh(&as)J1M4&3MvUuLmiDY(@F;+|BHDdj7Xx0VI*UjOfsp=XBnAfvxyxPQ$_`q z1UOGUO|)>IM|2HSBN049Eb&ZW8p))R&SF-OMGl+TP7$RXbOQTt+W%|Tb6{;k7!&as)J1M4&3MvUuLmiDY(@F;+{~|wn(T`_|C5}Xo>GN37Khv854B~T;vM3Xd@`xn$eXf38goY3?!PN zj3AB#CNrHB(wNU;mXpcbY#^Tk-lv2z%K3!ToaG{QT%n0(?r@(61oyQM(w$yBMHJ67 zf_Nq{jbu_uXE7_tB8N?Er-)Jxa*QgfImaa$Xyhg>+@qaN5zarl5k@3Y#4wyV5}3*i zW|PhmR`3=%00uLhcoKP;nWV9h<*X%_e0K05WmIs2YA#aG_uS$xKhvqdz9*D$1~P<^ zjAaV1kj6rmvzA;ovy&1IaFo-0MJ@?(`ypfkYF_ON?bANz7yp3&>y< z>&PXa?R>x<4se(gd_fJhT;&Ju@)HjU9w=XW(1-p+GmKG;V=BqK%IjpXns>-!8-O=knrWq-;Adn?Pa+t^P)0GHBxW*)1!Ry(HXA9R zh`k)*IA=IV9oJ~4m3D%kl_g>HBbpZ&!z7Y$2r5-)N++uwDN$EXy-q@8Nd);B!MJmk&as)J1M4&3MvUuLmiDY(@F;+G5UuvB8eh~ zk&Iz8O3;#NMSCE zSjjr_c#k6X@@GCJz&Cu$4es(Yokn}!C6vBIF_h7a=VfLwk7cYOmu>7~4+lBU=bWd3 z8{FX+g5#_geTZTh@l0eozh@pxSxq+i?BI|5i6eZ*SJZNiA8F$uzxvH%LH~um3?i1_ zFo|T+Sj=j2*v2mQaFFAC&UqTR!5w}fc#QW?AEFpWJd=5aG?uWM9JW%#J`Qu58XCCC z-w2BL`Gzh$PB%j7O#}lN#9)5SNa7gBB$7yG7OydnH+YjjkVQ6mY^H$sDWQyVj_@g; z5#TE>P{(&Paf`olk9InZwbpc_Cw=J0AcpV)qe);g(@7zX1-!{>)|1P>v4sM5@kjP@ zfC@h06al{G5)EAACbwzjXZ}veZ_N#%{0sdUL<}PsLn2AM!ffWUkY)UVEOOb%dlXX4 zKK{%nRPiO}spUJabDK6E(0QC}=|MOH7|d|uNnjGcBbiyuVLnS(&T7_?%SPU#kYe_- zp9+ri8P(KK%fHh^Gk5t<9?>O1e)Oad{TRd$USKo{OlCSMq_KcESmCY1T#2)r@ zn3H_LIWF@ZH~1?*5j0*_JWh9d5y3#BiRC56GLa-^GKU3Zu!?o$lFxQNU=Ig4%n81r zhFY%j19$m}hXha1GxVSj{fTB6qZr3jl6jTa$zV0_kjFL(DdA&|aFS}ip@AlDb00q% z2L;oWCkdrDkqji7p^PAo1ST_`6w;W_VwRK1+iW180^X;DGRpac)12iZbzGr|X6|sG z2Lw-aF3_D`JVg}GGlF;~FpXqVNoO%D$RdYLY^R7)4swhtsyW9c8ffGuE!?A>PLu36 zbR&#NqKIKQaU?L68O$b~C9L2ra>%EE-F!qj$2diR8ZL8%>$K2D2c0MD4?^k7)5I`> zF(i^i3UgV+O0w9%778h0KS!yensZ#Dfktl9!adsQG)4V%BaBF*h+#N!Brug3%qE>B ztl%wj$ftnad_+0NI7NUOE^~$Jw9rNeou{gwQ2O#TF^pggi6oK2To$pCEHKtqP|Zc^`JP+c zd{z(aat0^MK$a>p*vU@f1-! z&j{j~z%-IcC7s2rAd4I}v7I7HImj`psOB7(XrPgsv~Z7hI!)LAbR&#NqKIKQaU?L6 z8O$b~C9L2ra>%EE-F!qj$2diR8ZL8%>$K2D2c7?${wI{aJWUKE7(*gSq%fC7tR#yK zY@v`6_H&dfsyW9c8ffGuE!?A>PBYX`H^PV{iWr6yM*>rs!EDl5!V2CZhkOdy%}11T zj8g=t;WAgaP77^x&^cNCgwmI%iD3j|NF<3A=CX*DWU+xQ6jH)|j#9;!oTrxWxXx|b zctGb@%s)K{X8?m4PCSXc%uLc)$a2<_OFldJkTNPbK{Xet=X-8(m!IkMzv_EJ31=Wf z7|B?s@Cs=xWI1ceWivY|;Q&WD%~#aY$dBA3Xr|{M9;Z9Kh+rVm#PSkjnMe{dnZp7y zSj9SW$!9wsu!jR2<^*3*LoHYNfxG;~LxNM}OAq?cpJ;|Lig8ROnOAw83|8|Fd2FMQ z5eD!lFnjQkVOug*iI3p9OM{PoaF-bT%(y*+6hjTDLsi`5JMToc#@dO92Ss4CfRJH zfFkyCh~u2$9CciynO52fepQx)(T`|eU<{K;<~816CF{v!D?2Hsj0!3VP(vM!G}B54 zA+O1gUi9NxVu>S>>7+8BH(5h2Ti8V@UsKCfZqdpELgx7XkKPPm2rrUA60=BW zDVe;>W(q0g5T6p@B3HOY8$oH-jIKOMD7}efAkhqE1aTxVndzjE#(WmDoJ`(k1Njv2 zJ|&b<&L^DaEElQc3QaU~hxer?)2g*qIjMW#4~|uB$G-yi&;SyIc#D(MU--o zV^mSiIWEyaBR6T`9_@7c@6JEE5k@3Y#4wyV5}3*iW|PhmR`3=%zC29~ zBN#&>Nu)5BMXV%?4Q!#1683YHD!$}AwS32QZqvpCI=}9GqzB;)U@*gpCy|$#Ng4}T z&RTNGX9pirMg=FR<|6fc&n@oqGo2RbdqN3kAVV0*Sf=m_X)I(pYsqCZJ1OA+M>)+` z)Y8b0+#_hA{e{QrPA?)DNHnp$#8@Vh#7yR}fDBf#j$HED&Ijz_0Eaoj7t~P8RespMlz|SvzQfRk;5joQ$#5TIYt#{ zxj;SFXr`5Rf|tsao$2r5-)N++uwDN$E4Cg<+8Nd);B!MJmk!s*X*3}ZCon8FNF zna5IAv7S7(vXf%UsGyPnHPq2aGp%$GvQqyLMkGVDCwP@i z=}82G7|JNdlf+Esuz(CQ$z~%36tR~>9On$@sN)*Vw9-!SYFQFSKcaboF-#(v*LZ`K ztS67H?4+17DySqt4RtiqOe-CPWXg|T^y67#i6fEeq%xm3Swk*c*hMMj9On#QQ_EFu z(aHlt)|h{KGk_tyNCHXBBAumV@-CYxq?AK^N`Q-8;TCNKt=0cLK`7z$=Q)NknsH2F z2C2+rDXUmd9$VQ-F=bRxNq`#aXr!4|ItY2o`VmGXQN%Eku}mhJROYjcOtRU;4vHzG zf=U9Mr=BKSxX&ZHW~q?~o*|Za5_y@Kq_L3YtR9Wp# zN;m^~o)<~rcg$iQ8Dx^pMhe)?J}Nj#H5d4n8{FX+g5S1&^rk<98Od*%Mhf#-#u{?j z#s}=ndq@~e0K{!d>95zB9wL^5eCW;Ho%V;6fk$Zg!8nrP+@_jy3@27N(ydhrxdJkJQ?nZPuX zNhO`dtRRaVHnE)|N;$|es;K51muR4oo3wC`b~^p5Z0SZAkwg*0aNW0lWE#a*lC|05x3Z3fF0&jSf2JnMFeB%hSX#f-xkLL<)0R#7eT*z!nNAVLwNy zqMCDDqJc(k(!xF3>GVI;PdCDdB#Ib@6GsA5nZaz*S;7k5B8Pkm*v&_jbBt32sNphK zxK0agbkO_9ehX`6`Y`&i`4Tyx46sCblRlv2_>9?3}GZ=nZhfi zv5@7gC6~?Yq=W+;p);vvDC&kP<%T2q&rL z8yaZhHuv$L;@yAj`G-)#>CbZvV>IKK!VFTG$5K|Yo;8ToTr{9TDZ?6x^7b=5j;aI@l0SE$)u9b zVpfnv4x89c5v3gD7*(9*0`**@nO52feovwKhX?h6yummGOzMF8LZ|V^4LZpC49^gPEyS`G|ZX^y67#i6fEeq%xm3 zSwk*c*hMMj9On#QQ_EFu(aHltcAI~CGk_tyNCHXBBAumV@-CYxq?AK^N`Q-8;TCNK zeW?F=f>6Tg&vOi8G~<}U3{siLQdY5^JhrlvV#=tXk^nW-(MU6`bP)1K>qi)oL=nSC z#xj{?Qkl;(GRbBWJ1C}%3MvV3o_d;S;XaS(TC7GQc!pTwN#tc_lEy-ovzA=)*};dD zQNanSxkv*|{Dpfwq)UnYlyC;}JTH>K@0i6rGRP#GjTEq(eN=FgYA*0CH@L$u1plAb zkKXiWFeCXb(@0?+%UDA$+xUQe9Hxr1T%ew7G}B5u!F$XvJ&9ltLm9<*l1O1Li&)7z z@_3IT_VQ;wCBQd)%MI@GGo4C3?-EL1q8Q3(#`7|>n8z~Kkjpl9v4?{k=X1`}zzy#3 z3&DG>7k!9g81YPGI=^QgOIb}e`Rw42{D~uc##hvGjUQ>_A;0>_=YRS#h**BZB$7#E zF{{a88@t%UL5}k|=V{;ucld?iecnHPh+-J=Oy(8RSi)*@*h&%mILv8kXy7J)BdE+A z@;Ke;MFazhCYF~N%S4ix$s87t!7A2~OFrBAfIS@GFemte8fv-958UM^9uoW~y+#lE z(4T0AF^X|aC7D-woeWm<4tZ>&kP<%T2q&rL8yaZhHunko*#5^8gc44Fo?{rJ8OIc6 zkjgxkvWoTOv6Y<^Q$_`q1gN2oMw)4*gOL65B#cO+h+!mSnM^XN%x4*yWV4AK6jMe8 zl>|6XJx#Q5pGR~(phhBihFId6z%-IcC7s2rAd4I}v7I7HImj`pILige3KqaV?{z!)Zx%xk>C zO4gIdR(4WM85L9#poTgcX{MD9LjEj2deM((i6xFirjyEi-ee8AY+)CrlyjUjd`&G^ zxkW1v2q|~|)0+Vd;YAWiVixHvC6jmAOd+Kl;!^@#!~$z~%3>}DSooTQoye9H~)@C(65tslMV&tOLKTc(l1JeIMB zT(#6LMeOCzd`f_C_?8>o z|zfGInL*tr-2*X;TM9BTQB+$#W3QT$aH?s zJeIPWZ1UN`ANdnU_>8Zp${3?i1_Fo|T+Sj=j2*v2mQaFFAC&UqTR z!5w}fxYGNl4^a#wp2@sI8cSGB4qGW=ABQq%|2#n`;q>P@hB2CPOkoD8 z%ws95SWg~X*-0^FR8UEP8tQ1InN~UoIjJ7Ph$M;_MlzPkB$LW~mXS#|o7h1yWmHf} zfb-PTL<{$MMAuVlB!Xv%C7wiHW+rJYWI1ceC7&I9NEsEJpqh&`(8OQ3$3wb&X8s9h zAkXt63H**(%p-$Lve`%hyV*wtC#mKF-*SUH{6g?)>ql?;GnkS5mT9Cgk7cYOmu-B& zJ`PjGSuRk|HJWLqo!~0-PfsEk#85^to+MJ3%OX~?jy&F@h`s!oPYLi1-*SVy{7k1a z=ATgd62(wPGoF{3#XOd=hFrF>i#;6VIG=N#25xYNUkLu(deMg{h7r$1rt^E|v6R(h zlg|$R$e%dEXM9C1*Z7e(9`dU%%s+h@L@d8y63L{onAPO4ja}^FAjkQf^E7aSJN!a$ z!272UQ4AxV$-F`uOIS?~TPb26hdE6R4cz2!1Xb%*{+TeIVh}@li3Fzd3a_z{<-ElP zwoyn4A9I9LoaGYVag+bx7lOa^J0rarKnx=p%Vd&yl?5y(iw$gL7o{BHQvzJ%Tdwn0 ze&!#}+Ry040EX})2_!L_1*~8_|AY5)Ad;FcQ|5LB>6wfe>I41Jn zc$I~$J(N>PH5d7gTeR_rfBME;(VyoT%|u?|zmvgQHn5E% z_Hmfg)KJfL{(}en>Vo~4|4Iy_NMr_SEMX1*N&&?jq>}$h9oK0k=%U{@>B8f5Bb44m zFn~b}=GTlQj&V#PiDYK+8uNIAH~9luWRu5c3V5Fq$|&aupYj<2zTyIPd`A(p&x^YVFY7HB#Bp;&0H3;j6aY?E*p7|LW$$%{p?~$a@r0%wG0W!ErvLni^{PcbaJC zF8|3Ry41>#p7fy~gBZdKj3$A}Oecjj7VsvkSSV>^bf*^)3?!OZUScd0Nn$2*SU?7=SVu1TZ07^^aDc;{;0tP~VE?s$&PoNh~jxh z5YGgrkxVM-EM^5+&2qTgxVi-;w2~1@M zvq@(OD|m|>@+n|9A5qRRP7$Dn%Ut0)Ews@==YQ89gwmI%iD3j|NF<3A=CX*DWU+xQ z6jH)|j#5Q6=eR@zjohS#d$iN(iu&nB7?DH~!*JqAU@9}1O*%_h!CT~zPXW96h;oi` ziU2iS<_gzop^XkYf2V#z>C4l^FoH28l0*t~S;R`R*uWMFDPccHsp3n{Q_FW;=QeFT zpz~Gx13d_50D~D$Jc+!_Oww4$a@LYdK0El3GAcMhH5aMpdv0-;pXt=7?+GQGfec|J zW0}G$q_L3YtR%?9!*;C)IcqnuAT%~>u|#}%4r<_`CHK=3u|KzDla6j40S2;!N*G?GaroyDvm ziyStwogzv($T6y@<{X!3ppl!jaF2F6HR*r45k@3Y#4wyV5}3*iW|PhmR`3=%+@qaN*VRuq!iXe_7={x^0#lj6Y|>f63f>}zdmY1`V~%i=YQCX?CT??| zpdWqz$rFSUPJf1(gJ-p^iqHX{CdZznCY&h$M;_ zMlzPkB$LW~mXS#|o7h1yWmHf}fb-PTL<{$MMAzGDB!Xv%C7uaPBbijvSHBbpZ&!z7Yg!8 znrP+@_jy2Yt9_8}^x`R^c%Bi&Gl6L&lS(>^SwR*#Y+^e_lyZ<`R8h@2F3~_EH)-J> z?R5H^^N((X5lIv=3@45RrZR)sq_cz-yhRTA6tJ6*DCZcb2vEaiu5g_e+UTHjn^_{1 zzC29~BN#&>Nu)5BMXV%?4Q!#1683YHDylihB^qetCN12folf`EPdCDdB#Ib@6GsA5 znZaz*S;7k5B8Pkm*v&_jbBt32sNphKxK0agbkO;}`U#~kPZPrk#*j!7Da>UNE6HL5 zTPUQ2{T!u=FF8*w-*KJWwDEw>KRF-iK{x{#%y8mK-{qAFzi59OeXHP(v+O`GLFq#6yCAkuN>yLw}+f z#wf-ym1JJ!buw7ZJLIvALQ43UBb=m~Z)l*2+uSFp-TBWGgc44Fo?{rJ8OIc6kjgxk zvWoTOv6Y<^Q$_`q1gN2oMw)4*gOCpML>Q4o5yMEvGMQvjna?sZ$z~HfD5i`GDhY6& zdYWkAK9A`7K#fH346(#BfoUX@N;->KK^8e|Vmn2Ya*$(Gah40zbB$(NX(#xhOzBAk zgBZ#v#*@TM=CFVaGRbBm1r)KDLmcM}=cwZv&9u@^@ZV)g82yOm1;#LmWM1P9R9`fV;G|u#}sCe$~=~`iuL5Nm7Nq*Mg^4wsG*KVnrWqjkl-#s-3TL+ zC}J4NSSFK9D)U)JCfRIa2gQ_8K_vmsQ%@5u+~*NpL)1tF&k##I6PQLasid=*6=ada zCbm;VDF-=56=%6XJ=bWam3D$3lPNukU=TwY#dwmK$s87tK_=O3q<|v!a){%c;T&~b zqnTFP3GO0G!stgdFEEBlB=Z_?u#)xUv6Y<^Q$_`q1gN2oMw)4*gOFdzk6!fSSz?JJ zk?Eu|pEp@UE?d||DdimJ3|~{rRc_JB146o*e|j^3A-qTeNz5XhrDXChn<=D}Lwrhr zi(KIrZ3O+J{^too38z2LF^tiSV+u1!Wgbge#d`AC%1(+Yqk>8T)KEtw&9u@%$m7eLxI6*ZRX`qR}aF2&{dBT25I0Jc}7fIlE%wirHWRlHB3fRp)DmY0s7xvXY)%>A{fL_Mlqfw zQkcskRb2(R2%4jAsjdB*S zh^4G#4eO|7C%ZX7>}anS9mt~>1q@;c*HFqRCNPCr%;hnjWCbtr1{>MNN9^S=x!=l3 z`xc$Zr#I(v5k-`6I}?~nISW|CQdY8tb=0zx-5elxjK@z0^5{hYgBeN*BbmTdX0wnb zEazovsO5b=A+4=_If8G{mg6{{lju%Qe!w{lWH3V*MhUlYJ7X#1Zti6kb9k7?sbm?? z@iMQmfla)_cIw#8r+iNASf2}yrafKA<8*#N0T*y7MHF*0w{r(~GL@M;#6lLclxJDZ zTK>x0)UuWL*~LB%lKyS)Ep2GW@#N8iGdYKWT*8%H%gv1B4t~Z|W-*7~@H>|AEPtk& z8vc)W*ugILa)``!zKgV_6W^r=Kj4R4NFl?xk=q!@o!rX<%;#}_&!1S$TK>x0)UuWL z*~LB%lHT6)rw#2mo;-SRCg(7aOSqD2xtWpN!Oxh=EavbVe#bJN<-fb{E5~4g>`J?U3Tzq_VPKI-|^>T zj-eyn_#S6cz=d4SRg^G-u}oqbvzW`HR8qwYtYrh6`6nN;hyA2?@VTcg9XW~9=tF-l zW+)|$U@ViE#xI%2<2=ouc$qiY$W}gLA88%^9_H&DO?x_X65Z*|S@dTRg+H`z97S6?(v?%`MLz~`F;`MdDWe$AWTrElc~nqI6|1PG zhD~gxj(QG}b-eEr?Kqx1deDdd45o-;ZecWKOkpN-si2Z7R#DA5HnW{we9D&`(ZzG5 zGbhuV0xsZEiYVr0Zs!i}WGXXxh=nX>DbKQ+*I3VHwoykt2Z^2FJ>^(BlTT01=6njd ziW?Zt7|NK!4Cb(qCwPXHyux4E#5U@v=OD2Yy_dA(1iJHme#k`>aXmj~9Fv*OZ01ox zB~`4Vni@8-l{)GgLb?97i`!qb~y~YHu(3S4=;%o+R2}NAT zt&Cv;KW94S%;#~QVg)ai^QbsYJ$xLT9 z^QfSbDppZV4V&0X9rYX{E8pjbb{tP0J?KM!22(^aw=kMArZAJaR8UD3tEgrjo7v7T zKIKb}IN5WgGbhuV0xsZEiYVr0Zs!i}WGXXxh=nX>DbKQ+*I3VHwoykt2Z^2HJ>^(B zlTT01=6njdiW?Zt7|NK!4Cb(qCwPXHyux4E#5U@v=OD3Dy_dA(1iJHme#k`>aXmj~ z9Fv*OZ01oxB~`4Vni@8-l{)GnSFAG43cGWkFmvJ?vjG>Gv%wP_`VF^{d$XeF3g`Mo?0I@T?ejGKevXV8dqn4fQ<^ZuDc>HuAk6sion4y#~k_k*@HVaw8a$cr}THfaq()#!w z@^y};J)Jp;?)2s?`ZI_^uHpuUGlucp#WZH|5Rb5kr&-Pmyh;rld5;g+!)F{O*4Jl^ zW9UFvy3>oZ8NekJaUHiZh6((f>69~{$9aksyvSPKqL%Ian@>qQ%g;ZKqAeZi%Bl3C z9|O3UD=DUwQH*CY)0xdYDyXE2Ra8^MCbm*XJ%`9T+xtm7jwg>E^r1h4DWaHL7)=>d zn8{o!sHBQjRI`rFY-bmr@+C*~^Bn2S$@Hdx3%Habin*EFxq~~I%1j<&A&Xhcv#jPd z*0Y&y)KSktV&`~IIhM}k)049~pF*zU28J_+GNv$tIV|J}o?#`g@K-jmjXLT%NbFqi zCG9wY?tGsgauG#b&yN|$WTrElc~nqI6|1PGhD~gxj(QG}^+WF;?Ky!{=*>A?$PkLT zg`Y5yX*|FJ7PE|%yuzDo5EkQ^O{~!uj~?`)KZ7Zvm|GZ48B>_aTq>xfid9szj?HXm7oYMaM-1>B>CDOWrhp5%oU15d z1Y?=RG-ffEN2#QW7g);%YT3@m?Bg&w1N}UuBPVe>eHqAQTumusC}RpUn8R;aLKQEv zmi265C%ZX7?0l~u$I+GV(TDT6lwp)Inu$!KoJUx~a#r&i>)FgU>Zs=+u?u{EIhM}k z)049~pF)OlBeyY*yO_>{EaVCP!1Gk|7F*cK9`=)dq2K?sr4xDdq#x&VIagE4XeKg^ zau%?NrL1HP>!@WXyE#B?kk^Y2Twi&)A^*07FRcCwoT#0Go(bRdsj6fl^flrWMBOl39; zS;BH&riNPH=M&N{_WkE5+R~A(oJueHF@TG?l4433#dsz&o!QKzf=a4bMKv{SVk>pj zbBL@5B(WT5yjlXXv&zvOy*KSB~`4VnssbuJG=OlFFE2;&ymiYOm7Of zkjuG>5=JnVNlarFb9t0Xs(695Y@n9ye9S%$lXIExKOH%V)9K4VF5_xS8ABOUn86%= z!xE}^k+rO63p?4(0b-YX{Wy-Ue2+ey$E6ITl+jFN8s$8~5|*=?*I3VHwoykt2Z z{&Osy$)_i0b3TO(<3?^{9CtCD2U*Ay{DJ4G<}J3clRfMweTeTrZRtcFJ?Y2!T+Y>$ zGMb4@qnrgSVks+G!#Zl&$!-o1yTa>52lD7e0fQLAHIy=n2~1%Yb9sy>S;0%Z!A7?6 z5qmjI?v=j(bRwVLoXbTNQNry^U@GM-U=d4M$r{#C%T9K4fLM{oPY3eoMFE2uN(m#G zz*J_lkR>eVWooG9eLf*=sLv|jq#a$zrzdAIkV_cK^^9OFKjU7?na|@q#R~q+YrM_7 zyw86*KjUM!&KZ7aaI)*crJGqzHEMPIu@I2LQU<*6=5Btfu%Fi>}(~Z;U z%Rmabmf_sNWbWrd9%eC1d5%}8VH5x4BlhtHM-1~>r3)w1i*p#n6v-y(nNXLn&b-6PU_u7P5rpyi5(Xyw4}3UFW^z7&?*98Jxo) zinyL1Gmgp3WFCuH#wymbfp__ky?n`$*ZW@4mDB0RAck@iW0=Ifl(Uc}Eazov*vt<8 z%je|Y;O8+X(u1?PkSi%+Bon!hIaIKeRlLq7c2G}RiPx1Q_y%n`j^jCr?)2mboWno{ zGlXH3a0|CHmNM?_o_#qck$S`i? zHpX!$_woSqd7R(#CswnTzw$PkGm<;_ z8B>|X9Dc*^SjMybnQChIKi**nyV%PiGH>zxX-g-*OAmg)54n&+hH)deF^)UAmj{^7 zXW;i0inOF-+j+OsAarJkC?B;6>K*7PV~W-+W5iZT|klQM9EaT{)Fr z^kV=Qb0x);GK%p`W;(N(M+KEsv5IPH*u+-qsOJz_xBEWPj^oLr2Yu+zV2UW_7DiLX z6lOA)3M#2$71gX`Guzq4r+mo~BRxktb27at-~ukCh+=N$cJAO#rZSU8e0p*==Tpd4+`w?gP{tHyFo%Ua!85Gn75>U5woykt2Z@dL zUeb;e=+5`~As11^_57G|OlCT>nMVbcRI!R`YS_e9>Zs=sSwHdq(Vi1Hh2EUQg$$vX zTlfhRnZ^SwU@^;B$t%3cM&9E?>iL|kG5&ncadhJ}`ZAD0uI6S&QN}&|lKCv=8J?$_ z4ZOpL>?Lii{rNga)1J#M3P21zx3wjl9PP z?BO#G6Z@&p3dhiau5_mtXET6HDB?P9WegMeInya;K9BPhD|nH$yhSbB`8S`Ec8Bjj zN70s!bmdff(T@RK%#{>V$|%M&nd!`C9u-tl#VV?)VG~=aqn<-#jq~}T9mkVL5Bkub z!4y%Rp6;x8iDymt>X1247Px+D~{vXeg&YVnd3b=qvDWaI0xt%+>lc~() zAr`Wjr98`OUSmC**+w1p93(d0d&;qNCZC?1&G{5^6*n-PF_bZd8O&iJPw)&Yd4<2S ziEY$T&p~1nyqC1&1iJHme#k`>aXmj~9Fv*OZ01oxB~`4Vni@8-l{)G`49`=|2HxRA_L4Tq=bxi!OGmnLD!u5(050ZAiYa9j)zq+w zt<+J^A+mnv^`jlflSdEw(4WB+QOqrjri>}fWG)p{QpGB&S;uC!vx`spk|XZ)9O=x- z^rnCdxtyygVFY8D#586xmq)3jiWgYR25Q;P$L!-UId}PaN=HuObow%o%eb0S#!$u- zW-y1}u!JgJWG(C2!cKN`fY{w$KaQg--=h!baVf(nWi%6+MmdkLgypQ}HP*A4ZPZcE zL1I7m{pDCXlTT01=6nhn#*N&@IPPLP53-Oa_yf;V&0B0?CwtgW`ec9Jr7fMvqbL11 zpUb(LQbse8X_T{oMJ#0{Ygk7uJK4Cu( zdJd5_-TO&9jwg>E^r1h4DWaHL7)=>dn8{o!sHBQjRI`rFY-bmr@+C*y?>W+$lj%(X z7jP*>6mv7Ta|d@am6<%mLKd@>XIaf_tYUg1qP@*W>j&*x;#^826T z=*DUEWgvxI&CQIWjC=Sc^I6O@JWn+nc!v+!OWH4e{yB=abfhb%(u;l!;9{<%m{LYD zp2Uk}6hFO%0paN*(naBI^OKAMH4vJbKWF{tTvwVs2qHWlUivbE%+`Dppa= zIySSNU3|)y95LH-q%$Yen*uK6a;~C;5sYOL)0o9v9;K2hUSKU7sAW4Jvya2%l>2!~ zM^55&`ZAEqxSCSNP{tHyFo)l;geqQSE$i9BPIhyE*n?g_j-xBzqYvkCDZ?mbG!vOd zIghY}<*ep4*0Y&y)KSktV!!hJvHtfQ8l?B)QmIbJV1kVh{H7{m~+ zp_EZfU<$LC%VRvr3SQz3HnNS6*vnyZ=lcCmC-Ujdxm-jMCEU&grc%xV7O|9-tYICs z>|{3wi2d5*rvrKPqJY5+rG$}8U@Eg&$P$+GGBwolKA+%!^z7e%=lf4vI?|O>=|w*V za4}a>Oev!n&t#@En|V}FNfoQ8riM*yrH*<$7Z&(i%&Q+8!g0W0u8nc+oqf}DG3#?@WwQT2O z_Hme;hkgI)$Vr?|Uj}j+S5wLu%9z3o=I|SqP{oU^Wj$Ni$!-o1d&KLdN#9-I_fz{Y@zQz$I_X6dU7`BQ^+uGUAck-arHo<%Q<%kE9^*+?@DgvZk!^g$UJjG{nD0NG$fq~wauG$8a61#2N;wNy z#8OtWhIQ1klieI3R^jo}fjoLqz+i?_!bm1CmDwz03Cnqz8ftl;Pe^;*XO(Z#jxOZW zld~AeB@E?yMlhD2aWCb}=W(851%Ku>-sWB2=f4~v_FMm)k>lt_5Bkub!4z>F!x_t+ z+{;%3K+~#N*Kum zrZSs_EMYk>Q$sE9^9gBBdM`PKPULe2=P-yOuII;$V=^L?Ksk1H&1^c zAC96e9qG!c^r9aFxR@&`rj${PXEM{7%{(foq>5EkQ^O{?%W^U&W?qn)6 zd5DE9W+~6In%7v*X0}mBJqL+Zc~3c(&g9dRvpJtauHpuUGlnvzFoQWPN!a4kKRk#aRS}>K0o9linyL1GmgnjXEyVwppq(9QB4h-*h(Gs93pGE_mB3R zz$x_R94=%C#oWSAn8-99U;&F+#!6n{O*Zl#A5zcfWUcV~nd9ijY4l|vgiQ1d;K_$u6&O^oX4dMqm!V;FVn%7v*X0}mB zJqL-c^8MvlI+IUN&gOgy8ODv=#yIX`IuEjtC-?);Q_Wj!VJCaoPx=e~{7+jtkw;JZ zaXy!GHKmMZBGV{m0gG75O4hKBT6VIV1H@kRdeMPAdQre2hHwp~jA8;)n8jQk<4IQV z5^u1PZG6OD4wL(5fBvBp`Sj*oE~1DMZf62hDQ5wTSjtM)u#Q@GvYP|MUh??qKpwp) zU@$`|VI&in%4`<0gyp{EaVCP!1Gk|7F*cK9`=*I*7u*b zbRv(Q^y7Rk=W0qB%|xbA&H@&(l$ESu9kuLaHwTFQ#p^`}^5{hYgBZd!lroA5Okoyt zd5kAn!ArcsMz--0dpS(*Yrg+1q@~=C5&VOQ<=>|mav?csiBtl`GmALd{+4;?dU>2JvobkT*6SUX9Q#U8TV4o zd>-d1R`6$D<89vMeg4Yi8iffRBr!?}aW+|PqN%wm@E9IsHrCjQAs?BffLsPS2)3n$Zya~Q-G zT*nB;aW}tU4i)^K=XjM3Y+(ogVLut`Jbv2KjnnAMKnl5*;oQMwW-ylup5{4TWj*im zA$$3fBj2(wCvgS^3}Oh^P|7GKFojvnwW&|L_WPamy0N( zgxi_GRLWVvB9^j}HLRnSo$TfSu?;@|bRdsj6fl^flrWMBOl39;S;BH&riNPH=M&Q2 z_Fi%foyg}5&S4NmT+fdg$7E(Qk3}qF6>HhRyL`xAzU0Wi`CieL)9J?`hH?{Qn8dx5 zvyde$=VfZx%nts`=j8sMpU0d?56K|N_3{r=}D+R~A( zoJueHF@TG?l4433#dsz&o!QKzf=a4bMKv{SVk>pjbBL@>-cQ5B(WT5yjlX zXv&zvOy*KSB~`4VnssbuJG=OlFFE4xo+F((ncfs|A(wL%C5&J!lbFUV=JF_&RPh39 z*+4DZ`IvniCTFwX|8(RePNy#exs0nRWejCZVFq*f4NIuvMb@&OE$n1B2Z+^r{Wy-U ze2+ey$E6ITl+jFN8s$8~5|*=?*I3VHwoykt2Z?R*8Rl3zlTT01=6nhn#*N&@IPPLP z53-Oa_yf;V&0B0?CwtgW`ak^sr!AexqbL11pUb(LQbse8X_T{oMJ#0{Ygk7uJK458sz6_+0YZ=ZROy+(bRl0C8y*P(KT)}mWU>tYz3+7P4?|F__*}xWd@E`V*@h^{`_H^Sk z`ZAD0u4OoPFqs+5rGlqi@7|;ldRw+ z-e4o!_=vq6CU>XLKb^>@H|KH@MU-$m6PQXl3s}TbR6vb!z^Yg&+!U1Y~r7M#6G^@h+V$_bm3%raSnsHg6kN;IPT^b%%Otc^Bk|T zfi3LdKkO&tKOR5r>BedFWgvxI%W&>sGBcP<1yA!Fud<$Z`H;PQ$&tJ5%SoI;0fQLA zHIy=n2~1%Yb9sy>S;0%Z!A7?65qmjI?tgv%=|n!gIhTtlqJ-O-z*Ndvz#^8ik~OTO zmYwY80I@y3|8yXaUKB8xp_DL^2~1@+3t7T)UZ#dx-scn2>b;j7Lnrb%gL4=}5!dr$ z#xa?h%wrMDSjAd4@Gc*+moGW;6W=SkaytDO#87Tx43oH*au%|L<-AM{o7usC`JCLn zzWK|N{v?8ni3hi-h2AJCsm7|IR&m~q_AFPK9G zPqLgp^E!XyJ?hxU7aZ}a?+aZxl^-yGLayd!Mp4E+{F3=B<{6%+nhm_ehwLToGk*$g&?)P{(ksh4I`4m#jaPHve%wisk_yaHUI-B?xdpJbS0iR*I(4D?q zKoKR3ViNZ=mqk>unm71A-lL9BI85$A&!5hmOm7Ofn5(#%F-+oK%2~(~mh&<-Y-R`l z<#TcmdH$S856Up=ME+_iv|3S6|80*|DcXf$^6oHmM(OsFBee6jr@eWn8gB?@F%MI8{64K)Bj~O zUSe(=IPqncWu&+R3&bYPWy(gp-=c$P_=EWnr_>teLJ3aNo%i4-hL<4 zosibCu?t^2OB&WEoETKy8mp$;{Iu@|d46M+xIHD*^+@a9*d?z${hO4Ub}mTkp-SGK z5$SrzyTr9m+L@tw|Fk}hUHE!dv!q`<8ITsP&XqQtn{ZxG4Q#BMZU?1Z5afdztHkZ# zP*<3CNn@A14oSN#xL;v>)^Ji`+7*$mDBdNm!_s~fnwO*vYwW_;Yf_RM(~9Fsw7R}A zO-q}cR-#JY-W2Id<6Yu9BJI}5d_=rUUT;fD#-xpmC*f*r+UU?eQ_{vXcH!$!nXVI`jSv;8__aj8Ipe zHmk8qULQ<*Ah=(7eAaMMdD^cc-JE!rxXw@eb!cAU-y_y=ukiKZl;rWWh4Ca>J=&Ny z-8+2y+xY6HY;n9xTr1Ol7nxVayX5t$lw?`j)A1x+RrxocB~M+Qwyd!WU;o%FSrH`3 zYGvB9LE5n2>aqTPwW`JR#UOn(En2_SIB}D{+D-CyO{A-icZuukX@7~#Uypam z>zgUbhP0Y^60Y7(dn>ZfhG31tBifMmw`R%4AW2rWX@3vWrh9HntBoho>K`qn+tc0+ z($soueBzRxp1!TI3t#`$EZG?($*L~xgCJEj?o<~f;p*cS(miRrf;3v!r|k|VipG8S z#FNbQaP>)x>Ap}JuJ@;X7MdvS+_2yNP#Ucd29uohD}AHUHE!av!paglGTXxTZ1&Q(}*AmSGTp0j!7RG zq|th8`siTNwC|MkG4Ui?{j|k&Tqq6KW$EKXljP22K{_=(T2E?qa%W_c+TGnabwbAE zhAOzdC(=!ecZuu$>GwtE_s6^Bbw)~3o<1v{gsTVBABgNz9;|74EamCHYL?6il4LbM z{ntU-bkB2O1O|2h|PZGPPUVj_hGcj2lB+05W{dYl{SXUV&;p(Xt z(q-vS2WhmfN`EGpH0`@OeOWw-R)1_UT@gyd^~&^TLzBeLucWUG($soYtCJT)lULJI zyO-kAhBMMLRyTIx>zZasb&w>h*VF$Jq=}tg50Y^8W((9D>O;%>eF|Jrpa^mgwkmJNifODNKP8+eUVAD+n@ef zWSTgs;ePuglhp3uS57}qnKtjgXjtL1pO6t$vBs+DHa8EYU7L&}8@uH7 z=!|a!_iGcMHJsEY<6DugZM;id+h=?`H1CqpzOf5mzmt-jkkK)oM61q?X~UUa;`65Z z#7NgI-X*U28Q+b}^W$CedP+*tBcppf30FNcP7Cc*kkO;D3t!J@mh=viWYs6*%ph%e z`~?~PGy24nXmwVLX}=&HkP)rVZJadi8NNL)evhVXV7yCQ2W4CknGcG0$?M>hq%h-> zcoMFLWLy^6r!ZL4bZ%kB70r^OAW2rkGJX`KP4_Ix7#2^W)io`oH)a$EX=;6aeA2M% z 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 z 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

          -	fipImage src, dst;
          -	src.load("test.png");
          -	dst = FreeImage_ConvertTo8Bits(src);
          -	FreeImage_Save(FIF_TIFF, dst, "test.tif", 0);
          -	
          - @see operator=(FIBITMAP *dib) - */ - operator FIBITMAP*() { - return _dib; - } - - /// Returns TRUE if the image is allocated, FALSE otherwise - BOOL isValid() const; - - /** - Returns a pointer to the bitmap's BITMAPINFO header. - @see FreeImage_GetInfo - */ - const BITMAPINFO* getInfo() const; - - /** - Returns a pointer to the bitmap's BITMAPINFOHEADER. - @see FreeImage_GetInfoHeader - */ - const BITMAPINFOHEADER* getInfoHeader() const; - - /** - Returns the size of the bitmap in bytes. - The size of the bitmap is the BITMAPINFOHEADER + the size of the palette + the size of the bitmap data. - @see FreeImage_GetDIBSize - */ - unsigned getImageSize() const; - - /** - Returns the memory footprint of a bitmap, in bytes. - @see FreeImage_GetMemorySize - */ - unsigned getImageMemorySize() const; - - /** - Returns the bitdepth of the bitmap.
          - When the image type is FIT_BITMAP, valid bitdepth can be 1, 4, 8, 16, 24 or 32. - @see FreeImage_GetBPP, getImageType - */ - unsigned getBitsPerPixel() const; - - /** - Returns the width of the bitmap in bytes.
          - This is not the size of the scanline. - @see FreeImage_GetLine, getScanWidth - */ - unsigned getLine() const; - - /** - Returns the bitmap resolution along the X axis, in pixels / cm - @see FreeImage_GetDotsPerMeterX - */ - double getHorizontalResolution() const; - - /** - Returns the bitmap resolution along the Y axis, in pixels / cm - @see FreeImage_GetDotsPerMeterY - */ - double getVerticalResolution() const; - - /** - set the bitmap resolution along the X axis, in pixels / cm - @see FreeImage_GetInfoHeader - */ - void setHorizontalResolution(double value); - - /** - set the bitmap resolution along the Y axis, in pixels / cm - @see FreeImage_GetInfoHeader - */ - void setVerticalResolution(double value); - - //@} - - /**@name Palette operations */ - //@{ - /** - Returns a pointer to the bitmap's palette. If the bitmap doesn't have a palette, getPalette returns NULL. - @see FreeImage_GetPalette - */ - RGBQUAD* getPalette() const; - - /** - Returns the palette size in bytes. - @see FreeImage_GetColorsUsed - */ - unsigned getPaletteSize() const; - - /** - Retrieves the number of colours used in the bitmap. If the bitmap is non-palletised, 0 is returned. - @see FreeImage_GetColorsUsed - */ - unsigned getColorsUsed() const; - - /** - Investigates the colour type of the bitmap. - @see FreeImage_GetColorType, FREE_IMAGE_COLOR_TYPE - */ - FREE_IMAGE_COLOR_TYPE getColorType() const; - - /** - Returns TRUE if the bitmap is a 8-bit bitmap with a greyscale palette, FALSE otherwise - @see FreeImage_GetBPP, FreeImage_GetColorType - */ - BOOL isGrayscale() const; - //@} - - /**@name Thumbnail access */ - //@{ - - /** - Retrieves a copy the thumbnail possibly attached to the bitmap - @return Returns TRUE if the thumbnail is present in the bitmap and successfuly retrieved, returns FALSE otherwise - @see FreeImage_GetThumbnail - */ - BOOL getThumbnail(fipImage& image) const; - - /** - Attach a thumbnail to the bitmap - @return Returns TRUE if the thumbnail was successfuly set, returns FALSE otherwise - @see FreeImage_SetThumbnail - */ - BOOL setThumbnail(const fipImage& image); - - /** - Check if the image has an embedded thumbnail - @return Returns TRUE if a thumbnail is present in the bitmap, returns FALSE otherwise - @see FreeImage_GetThumbnail - */ - BOOL hasThumbnail() const; - - /** - Clear the thumbnail possibly attached to the bitmap - @return Returns TRUE if successful, returns FALSe otherwise - @see FreeImage_SetThumbnail - */ - BOOL clearThumbnail(); - - //@} - - /**@name Pixel access */ - //@{ - - /** @brief Returns a pointer to the bitmap bits. - - It is up to you to interpret these bytes correctly, - according to the results of FreeImage_GetBPP and - GetRedMask, FreeImage_GetGreenMask and FreeImage_GetBlueMask.
          - Use this function with getScanWidth to iterates through the pixels. - @see FreeImage_GetBits - */ - BYTE* accessPixels() const; - - /** @brief Returns a pointer to the start of the given scanline in the bitmaps data-bits. - This pointer can be cast according to the result returned by getImageType.
          - Use this function with getScanWidth to iterates through the pixels. - @see FreeImage_GetScanLine, FreeImage documentation - */ - BYTE* getScanLine(unsigned scanline) const; - - /** - Get the pixel index of a 1-, 4- or 8-bit palettized image at position (x, y), including range check (slow access). - @param x Pixel position in horizontal direction - @param y Pixel position in vertical direction - @param value Pixel index (returned value) - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_GetPixelIndex - */ - BOOL getPixelIndex(unsigned x, unsigned y, BYTE *value) const; - - /** - Get the pixel color of a 16-, 24- or 32-bit image at position (x, y), including range check (slow access). - @param x Pixel position in horizontal direction - @param y Pixel position in vertical direction - @param value Pixel color (returned value) - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_GetPixelColor - */ - BOOL getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const; - - /** - Set the pixel index of a 1-, 4- or 8-bit palettized image at position (x, y), including range check (slow access). - @param x Pixel position in horizontal direction - @param y Pixel position in vertical direction - @param value Pixel index - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SetPixelIndex - */ - BOOL setPixelIndex(unsigned x, unsigned y, BYTE *value); - - /** - Set the pixel color of a 16-, 24- or 32-bit image at position (x, y), including range check (slow access). - @param x Pixel position in horizontal direction - @param y Pixel position in vertical direction - @param value Pixel color - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SetPixelColor - */ - BOOL setPixelColor(unsigned x, unsigned y, RGBQUAD *value); - - //@} - - /** @name Conversion routines - * Bitmaps are always loaded in their default bit depth. If you want the bitmap to be stored in another bit depth, the class provides several conversion functions. - */ - //@{ - /** - Converts an image to a type supported by FreeImage. - @param image_type New image type - @param scale_linear TRUE if image pixels must be scaled linearly when converting to a standard bitmap - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToType, FreeImage_ConvertToStandardType - */ - BOOL convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear = TRUE); - - /** - Converts the bitmap to 1 bit using a threshold T. - @param T Threshold value in [0..255] - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Threshold - */ - BOOL threshold(BYTE T); - - /** - Converts a 8-bit image to a monochrome 1-bit image using a dithering algorithm. - @param algorithm Dithering algorithm to use. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Dither, FREE_IMAGE_DITHER - */ - BOOL dither(FREE_IMAGE_DITHER algorithm); - - /** - Converts the bitmap to 4 bits. Unless the bitmap is a 1-bit palettized bitmap, colour values are converted to greyscale. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo4Bits - */ - BOOL convertTo4Bits(); - - /** - Converts the bitmap to 8 bits. If the bitmap is 24 or 32-bit RGB, the colour values are converted to greyscale. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo8Bits - */ - BOOL convertTo8Bits(); - - /** - Converts the bitmap to 8 bits.
          - For palletized bitmaps, the color map is converted to a greyscale ramp. - @see FreeImage_ConvertToGreyscale - @return Returns TRUE if successful, FALSE otherwise. - */ - BOOL convertToGrayscale(); - - /** - Quantizes a full colour 24-bit bitmap to a palletised 8-bit bitmap.
          - The quantize parameter specifies which colour reduction algorithm should be used. - @param algorithm Color quantization algorithm to use. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ColorQuantize, FREE_IMAGE_QUANTIZE - */ - BOOL colorQuantize(FREE_IMAGE_QUANTIZE algorithm); - - /** - Converts the bitmap to 16 bits. The resulting bitmap has a layout of 5 bits red, 5 bits green, 5 bits blue and 1 unused bit. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo16Bits555 - */ - BOOL convertTo16Bits555(); - - /** - Converts the bitmap to 16 bits. The resulting bitmap has a layout of 5 bits red, 6 bits green and 5 bits blue. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo16Bits565 - */ - BOOL convertTo16Bits565(); - - /** - Converts the bitmap to 24 bits. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo24Bits - */ - BOOL convertTo24Bits(); - - /** - Converts the bitmap to 32 bits. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertTo32Bits - */ - BOOL convertTo32Bits(); - - /** - Converts the bitmap to a 32-bit float image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToFloat - */ - BOOL convertToFloat(); - - /** - Converts the bitmap to a 96-bit RGBF image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToRGBF - */ - BOOL convertToRGBF(); - - /** - Converts the bitmap to a 128-bit RGBAF image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToRGBAF - */ - BOOL convertToRGBAF(); - - /** - Converts the bitmap to a 16-bit unsigned short image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToUINT16 - */ - BOOL convertToUINT16(); - - /** - Converts the bitmap to a 48-bit RGB16 image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToRGB16 - */ - BOOL convertToRGB16(); - - /** - Converts the bitmap to a 64-bit RGBA16 image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ConvertToRGBA16 - */ - BOOL convertToRGBA16(); - - /** - Converts a High Dynamic Range image (48-bit RGB or 96-bit RGB Float) to a 24-bit RGB image. - @param tmo Tone mapping operator - @param first_param First tone mapping algorithm parameter (algorithm dependant) - @param second_param Second tone mapping algorithm parameter (algorithm dependant) - @param third_param Third tone mapping algorithm parameter (algorithm dependant) - @param fourth_param Fourth tone mapping algorithm parameter (algorithm dependant) - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_ToneMapping, FreeImage_TmoReinhard05Ex - */ - BOOL toneMapping(FREE_IMAGE_TMO tmo, double first_param = 0, double second_param = 0, double third_param = 1, double fourth_param = 0); - - //@} - - /** @name Transparency support: background colour and alpha channel */ - //@{ - - /** - Returns TRUE if the image is transparent, returns FALSE otherwise - @see FreeImage_IsTransparent - */ - BOOL isTransparent() const; - - /** - 8-bit transparency : get the number of transparent colors. - @return Returns the number of transparent colors in a palletised bitmap. - @see FreeImage_GetTransparencyCount - */ - unsigned getTransparencyCount() const; - - /** - 8-bit transparency : get the bitmaps transparency table. - @return Returns a pointer to the bitmaps transparency table. - @see FreeImage_GetTransparencyTable - */ - BYTE* getTransparencyTable() const; - - /** - 8-bit transparency : set the bitmaps transparency table. - @see FreeImage_SetTransparencyTable - */ - void setTransparencyTable(BYTE *table, int count); - - /** - Returns TRUE when the image has a file background color, FALSE otherwise. - @see FreeImage_HasBackgroundColor - */ - BOOL hasFileBkColor() const; - - /** - @brief Retrieves the file background color of an image. - - For 8-bit images, the color index - in the palette is returned in the rgbReserved member of the bkcolor parameter. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_GetBackgroundColor - */ - BOOL getFileBkColor(RGBQUAD *bkcolor) const; - - /** - @brief Set the file background color of an image. - - When saving an image to PNG, this background color is transparently saved to the PNG file. - When the bkcolor parameter is NULL, the background color is removed from the image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SetBackgroundColor - */ - BOOL setFileBkColor(RGBQUAD *bkcolor); - //@} - - /**@name Channel processing support */ - //@{ - /** @brief Retrieves the red, green, blue or alpha channel of a 24- or 32-bit BGR[A] image. - @param image Output image to be extracted - @param channel Color channel to extract - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_GetChannel, FREE_IMAGE_COLOR_CHANNEL - */ - BOOL getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const; - - /** - @brief Insert a 8-bit dib into a 24- or 32-bit image. - @param image Input 8-bit image to insert - @param channel Color channel to replace - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SetChannel, FREE_IMAGE_COLOR_CHANNEL - */ - BOOL setChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel); - - /** @brief Split a 24-bit RGB image into 3 greyscale images corresponding to the red, green and blue channels. - @param RedChannel Output red channel. - @param GreenChannel Output green channel. - @param BlueChannel Output blue channel. - @return Returns FALSE if the dib isn't a valid image, if it's not a 24-bit image or if - one of the output channel can't be allocated. Returns TRUE otherwise. - @see FreeImage_GetChannel - */ - BOOL splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel); - - /** @brief Builds a 24-bit RGB image given its red, green and blue channel. - @param red Input red channel. - @param green Input green channel. - @param blue Input blue channel. - @return Returns FALSE if the dib can't be allocated, if the input channels are not 8-bit images. Returns TRUE otherwise. - @see FreeImage_SetChannel - */ - BOOL combineChannels(fipImage& red, fipImage& green, fipImage& blue); - //@} - - /**@name Rotation and flipping */ - //@{ - /** - Image translation and rotation using B-Splines. - @param angle Image rotation angle, in degree - @param x_shift Image horizontal shift - @param y_shift Image vertical shift - @param x_origin Origin of the x-axis - @param y_origin Origin of the y-axis - @param use_mask Whether or not to mask the image. Image mirroring is applied when use_mask is set to FALSE - @return Returns the translated & rotated dib if successful, returns NULL otherwise - @see FreeImage_RotateEx - */ - BOOL rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask); - - /** - Image rotation by means of three shears. - @param angle Image rotation angle, in degree - @param bkcolor Background color (image type dependent), default to black background - @return Returns rotated dib if successful, returns NULL otherwise - @see FreeImage_Rotate - */ - BOOL rotate(double angle, const void *bkcolor = NULL); - - /** - Flip the image horizontally along the vertical axis - @see FreeImage_FlipHorizontal - */ - BOOL flipHorizontal(); - - /** - Flip the image vertically along the horizontal axis - @see FreeImage_FlipVertical - */ - BOOL flipVertical(); - //@} - - /**@name Color manipulation routines */ - //@{ - /** - Inverts each pixel data. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Invert - */ - BOOL invert(); - - /** @brief Perfoms an histogram transformation on a 8, 24 or 32-bit image - according to the values of a lookup table (LUT). - - The transformation is done as follows.
          - Image 8-bit : if the image has a color palette, the LUT is applied to this palette, - otherwise, it is applied to the grey values.
          - Image 24-bit & 32-bit : if channel == IPL_CC_RGB, the same LUT is applied to each color - plane (R,G, and B). Otherwise, the LUT is applied to the specified channel only. - @param LUT Lookup table. The size of 'LUT' is assumed to be 256. - @param channel The color channel to be processed (only used with 24 & 32-bit DIB). - @return Returns TRUE if the operation was successful, FALSE otherwise - @see FreeImage_AdjustCurve, FREE_IMAGE_COLOR_CHANNEL - */ - BOOL adjustCurve(BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel); - - /** @brief Performs gamma correction on a 8, 24 or 32-bit image. - @param gamma Gamma value to use. A value of 1.0 leaves the image alone, - less than one darkens it, and greater than one lightens it. - @return Returns TRUE if the operation was successful, FALSE otherwise - @see FreeImage_AdjustGamma, adjustCurve - */ - BOOL adjustGamma(double gamma); - - /** @brief Adjusts the brightness of a 8, 24 or 32-bit image by a certain amount. - @param percentage Where -100 <= percentage <= 100
          - A value 0 means no change, less than 0 will make the image darker - and greater than 0 will make the image brighter. - @return Returns TRUE if the operation was succesful, FALSE otherwise - @see FreeImage_AdjustBrightness, adjustCurve - */ - BOOL adjustBrightness(double percentage); - - /** @brief Adjusts the contrast of a 8, 24 or 32-bit image by a certain amount. - @param percentage Where -100 <= percentage <= 100
          - A value 0 means no change, less than 0 will decrease the contrast - and greater than 0 will increase the contrast of the image. - @return Returns TRUE if the operation was succesfull, FALSE otherwise - @see FreeImage_AdjustContrast, adjustCurve - */ - BOOL adjustContrast(double percentage); - - /** - Adjusts an image's brightness, contrast and gamma within a single operation. - If more than one of these image display properties need to be adjusted, - using this function should be preferred over calling each adjustment function separately. - That's particularly true for huge images or if performance is an issue. - @see adjustBrightness - @see adjustContrast - @see adjustGamma - @see FreeImage_AdjustColors - */ - BOOL adjustBrightnessContrastGamma(double brightness, double contrast, double gamma); - - /** @brief Computes image histogram - - For 24-bit and 32-bit images, histogram can be computed from red, green, blue and - black channels. For 8-bit images, histogram is computed from the black channel. Other - bit depth is not supported. - @param histo pointer to an histogram array. Size of this array is assumed to be 256. - @param channel Color channel to use - @return Returns TRUE if the operation was succesfull, FALSE otherwise - @see FreeImage_GetHistogram - */ - BOOL getHistogram(DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel = FICC_BLACK) const; - //@} - - /**@name Upsampling / downsampling */ - //@{ - - /** @brief Rescale the image to a new width / height. - - @param new_width New image width - @param new_height New image height - @param filter The filter parameter specifies which resampling filter should be used. - @return Returns TRUE if the operation was successful, FALSE otherwise - @see FreeImage_Rescale, FREE_IMAGE_FILTER - */ - BOOL rescale(unsigned new_width, unsigned new_height, FREE_IMAGE_FILTER filter); - - /** @brief Creates a thumbnail image keeping aspect ratio - - @param max_size Maximum width or height in pixel units - @param convert When set to TRUE, converts the image to a standard type - @return Returns TRUE if the operation was successful, FALSE otherwise - @see FreeImage_MakeThumbnail - */ - BOOL makeThumbnail(unsigned max_size, BOOL convert = TRUE); - //@} - - /**@name Image status */ - //@{ - /** - Set the image status as 'modified'.
          - When using the fipWinImage class, the image status is used to refresh the display. - It is changed to FALSE whenever the display has just been refreshed. - @param bStatus TRUE if the image should be marked as modified, FALSE otherwise - @see isModified - */ - void setModified(BOOL bStatus = TRUE) { - _bHasChanged = bStatus; - } - - /** - Get the image status - @return Returns TRUE if the image is marked as modified, FALSE otherwise - @see setModified - */ - BOOL isModified() { - return _bHasChanged; - } - //@} - - /**@name Metadata */ - //@{ - /** - Returns the number of tags contained in the model metadata model - attached to the dib - @param model Metadata model to look for - */ - unsigned getMetadataCount(FREE_IMAGE_MDMODEL model) const; - /** - Retrieve a metadata attached to the dib - @param model Metadata model to look for - @param key Metadata field name - @param tag Returned tag - @return Returns TRUE if the operation was succesfull, FALSE otherwise - @see FreeImage_GetMetadata - */ - BOOL getMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) const; - /** - Attach a new FreeImage tag to the dib.
          - Sample use :
          -
          -	fipImage image;
          -	// ...
          -	fipTag tag;
          -	tag.setKeyValue("Caption-Abstract", "my caption");
          -	image.setMetadata(FIMD_IPTC, tag.getKey(), tag);
          -	tag.setKeyValue("Keywords", "FreeImage;Library;Images;Compression");
          -	image.setMetadata(FIMD_IPTC, tag.getKey(), tag);
          -	
          - - @param model Metadata model used to store the tag - @param key Tag field name - @param tag Tag to be attached - @return Returns TRUE if the operation was succesfull, FALSE otherwise - @see FreeImage_SetMetadata - */ - BOOL setMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag); - - /** - Clear all metadata contained in the dib - */ - void clearMetadata(); - //@} - - protected: - /**@name Internal use */ - //@{ - BOOL replace(FIBITMAP *new_dib); - //@} - -}; - -// ---------------------------------------------------------- - -/** A class designed for MS Windows (TM) platforms. - - fipWinImage provides methods used to : -
            -
          • Display a DIB on the screen -
          • Copy / Paste a DIB to/from Windows devices (HANDLE, HBITMAP, Clipboard) -
          • Capture a window (HWND) and convert it to an image -
          - @version FreeImage 3 - @author Herv Drolon -*/ -#ifdef _WIN32 - -class FIP_API fipWinImage : public fipImage -{ -public: - /**@name Creation & Destruction */ - //@{ - /// Constructor - fipWinImage(FREE_IMAGE_TYPE image_type = FIT_BITMAP, unsigned width = 0, unsigned height = 0, unsigned bpp = 0); - - /// Destructor - virtual ~fipWinImage(); - - /// Destroy image data - virtual void clear(); - - /// Returns TRUE if the image is allocated, FALSE otherwise - BOOL isValid() const; - //@} - - /**@name Copying */ - //@{ - - /** - Copy constructor. - Delete internal _display_dib data and copy the base class image data. - Tone mapping parameters are left unchanged. - @see FreeImage_Clone - */ - fipWinImage& operator=(const fipImage& src); - - /** - Copy constructor - Delete internal _display_dib data and copy tone mapping parameters. - Copy also the base class image data. - @see FreeImage_Clone - */ - fipWinImage& operator=(const fipWinImage& src); - - /** Clone function used for clipboard copy.
          - Convert the FIBITMAP image to a DIB, - and transfer the DIB in a global bitmap handle.
          - For non standard bitmaps, the BITMAPINFOHEADER->biCompression field is set to 0xFF + FreeImage_GetImageType(_dib), - in order to recognize the bitmap as non standard. - */ - HANDLE copyToHandle() const; - - /** Copy constructor used for clipboard paste.
          - Converts a global object to a FIBITMAP. The clipboard format must be CF_DIB.
          - When the BITMAPINFOHEADER->biCompression field is set to 0xFF + [one of the predefined FREE_IMAGE_TYPE], - the bitmap is recognized as non standard and correctly copied. - @return Returns TRUE if successful, returns FALSE otherwise - */ - BOOL copyFromHandle(HANDLE hMem); - - /** Copy constructor.
          - Converts a HBITMAP object to a FIBITMAP. - @return Returns TRUE if successful, returns FALSE otherwise - */ - BOOL copyFromBitmap(HBITMAP hbmp); - //@} - - /**@name Clipboard operations */ - //@{ - /** - Clipboard copy. - @param hWndNewOwner Handle to the window to be associated with the open clipboard. - In MFC, you can use AfxGetApp()->m_pMainWnd->GetSafeHwnd(). - @return Returns TRUE if successful, returns FALSE otherwise - */ - BOOL copyToClipboard(HWND hWndNewOwner) const; - - /** - Retrieves data from the clipboard. The clipboard format must be CF_DIB. - @return Returns TRUE if successful, returns FALSE otherwise - */ - BOOL pasteFromClipboard(); - //@} - - /**@name Screen capture */ - //@{ - /** Capture a window and convert it to an image - @param hWndApplicationWindow Handle to the application main window - @param hWndSelectedWindow Handle to the window to be captured - @return Returns TRUE if successful, returns FALSE otherwise - */ - BOOL captureWindow(HWND hWndApplicationWindow, HWND hWndSelectedWindow); - //@} - - - /**@name Painting operations */ - //@{ - - /** @brief Draw (stretch) the image on a HDC, using StretchDIBits. - - When the image is transparent or has a file background, this function composite - the foreground image against a checkerboard background image. - @param hDC Handle to the device context - @param rcDest Destination rectangle - @see FreeImage_Composite - */ - void draw(HDC hDC, RECT& rcDest) const { - drawEx(hDC, rcDest, FALSE, NULL, NULL); - } - - /** @brief Draw (stretch) the image on a HDC, using StretchDIBits. - - When the image is transparent or has a file background, this function can composite - the foreground image against a checkerboard background image, against a single background color or - against a user background image.
          - When the image is a High Dynamic Range image (48-bit or RGB float), this function will apply a - tone mapping operator before drawing the image.
          - The original image (located in the fipImage class) will not be affected by any of the operations - that could be done in order to display it. - @param hDC Handle to the device context - @param rcDest Destination rectangle - @param useFileBkg When set to TRUE, the function uses the file color background if there is one - @param appBkColor When a color is given, the function uses it as the background color - @param bg When a FIBITMAP is given, the function uses it as the background image - @see FreeImage_Composite - @see setToneMappingOperator - */ - void drawEx(HDC hDC, RECT& rcDest, BOOL useFileBkg = FALSE, RGBQUAD *appBkColor = NULL, FIBITMAP *bg = NULL) const; - - /** - Select a tone mapping algorithm used for drawing and set the image as modified - so that the display will be refreshed. - @param tmo Tone mapping operator - @param first_param First tone mapping algorithm parameter - @param second_param Second tone mapping algorithm parameter - @param third_param Third tone mapping algorithm parameter - @param fourth_param Fourth tone mapping algorithm parameter - @see FreeImage_ToneMapping - */ - void setToneMappingOperator(FREE_IMAGE_TMO tmo, double first_param = 0, double second_param = 0, double third_param = 1, double fourth_param = 0); - - /** - Get the tone mapping algorithm used for drawing, with its parameters. - @param tmo Tone mapping operator - @param first_param First tone mapping algorithm parameter - @param second_param Second tone mapping algorithm parameter - @param third_param Third tone mapping algorithm parameter - @param fourth_param Fourth tone mapping algorithm parameter - @see FreeImage_ToneMapping - */ - void getToneMappingOperator(FREE_IMAGE_TMO *tmo, double *first_param, double *second_param, double *third_param, double *fourth_param) const; - - //@} - -protected: - /// DIB used for display (this allow to display non-standard bitmaps) - mutable FIBITMAP *_display_dib; - /// remember to delete _display_dib - mutable BOOL _bDeleteMe; - /// tone mapping operator - FREE_IMAGE_TMO _tmo; - /// first tone mapping algorithm parameter - double _tmo_param_1; - /// second tone mapping algorithm parameter - double _tmo_param_2; - /// third tone mapping algorithm parameter - double _tmo_param_3; - /// fourth tone mapping algorithm parameter - double _tmo_param_4; -}; - -#endif // _WIN32 - -// ---------------------------------------------------------- - -/** Memory handle - - fipMemoryIO is a class that allows you to load / save images from / to a memory stream. - @version FreeImage 3 - @author Herv Drolon -*/ -class FIP_API fipMemoryIO : public fipObject -{ -protected: - /// Pointer to a memory stream - FIMEMORY *_hmem; - -public : - /** Constructor. - Wrap a memory buffer containing image data.
          - The memory buffer is read only and has to be freed by the user - when no longer in use.
          - When default arguments are used, open a memory file as read/write. - @param data Pointer to the memory buffer - @param size_in_bytes Buffer size in bytes - @see FreeImage_OpenMemory - */ - fipMemoryIO(BYTE *data = NULL, DWORD size_in_bytes = 0); - - /** Destructor. - Free any allocated memory - @see FreeImage_CloseMemory - */ - virtual ~fipMemoryIO(); - - /** Destructor. - Free any allocated memory and invalidate the stream - @see FreeImage_CloseMemory - */ - void close(); - - /** Returns TRUE if the internal memory buffer is a valid buffer, returns FALSE otherwise - */ - BOOL isValid() const; - - /** Returns the buffer image format - @see FreeImage_GetFileTypeFromMemory - */ - FREE_IMAGE_FORMAT getFileType() const; - - /** - Returns a pointer to the FIMEMORY data. Used for direct access from FREEIMAGE functions - or from your own low level C functions. - */ - operator FIMEMORY*() { - return _hmem; - } - - /**@name Memory IO routines */ - //@{ - /** - Loads a dib from a memory stream - @param fif Format identifier (FreeImage format) - @param flags The signification of this flag depends on the image to be loaded. - @return Returns the loaded dib if successful, returns NULL otherwise - @see FreeImage_LoadFromMemory - */ - FIBITMAP* load(FREE_IMAGE_FORMAT fif, int flags = 0) const; - /** - Loads a multi-page bitmap from a memory stream - @param fif Format identifier (FreeImage format) - @param flags The signification of this flag depends on the multi-page to be loaded. - @return Returns the loaded multi-page if successful, returns NULL otherwise - @see FreeImage_LoadMultiBitmapFromMemory - */ - FIMULTIBITMAP* loadMultiPage(FREE_IMAGE_FORMAT fif, int flags = 0) const; - /** - Saves a dib to a memory stream - @param fif Format identifier (FreeImage format) - @param dib Image to be saved - @param flags The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SaveToMemory - */ - BOOL save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, int flags = 0); - /** - Saves a multi-page bitmap to a memory stream - @param fif Format identifier (FreeImage format) - @param bitmap Multi-page image to be saved - @param flags The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SaveMultiBitmapToMemory - */ - BOOL saveMultiPage(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, int flags = 0); - /** - Reads data from a memory stream - @param buffer Storage location for data - @param size Item size in bytes - @param count Maximum number of items to be read - @return Returns the number of full items actually read, which may be less than count if an error occurs - @see FreeImage_ReadMemory - */ - unsigned read(void *buffer, unsigned size, unsigned count) const; - /** - Writes data to a memory stream - @param buffer Pointer to data to be written - @param size Item size in bytes - @param count Maximum number of items to be written - @return Returns the number of full items actually written, which may be less than count if an error occurs - @see FreeImage_WriteMemory - */ - unsigned write(const void *buffer, unsigned size, unsigned count); - /** - Gets the current position of a memory pointer - @see FreeImage_TellMemory - */ - long tell() const; - /** - Moves the memory pointer to a specified location - @see FreeImage_SeekMemory - */ - BOOL seek(long offset, int origin); - /** - Provides a direct buffer access to a memory stream - @param data Pointer to the memory buffer (returned value) - @param size_in_bytes Buffer size in bytes (returned value) - @see FreeImage_AcquireMemory - */ - BOOL acquire(BYTE **data, DWORD *size_in_bytes); - //@} - -private: - /// Disable copy - fipMemoryIO(const fipMemoryIO& src); - /// Disable copy - fipMemoryIO& operator=(const fipMemoryIO& src); - -}; - -// ---------------------------------------------------------- - -/** Multi-page file stream - - fipMultiPage encapsulates the multi-page API. It supports reading/writing - multi-page TIFF, ICO and GIF files. -*/ -class FIP_API fipMultiPage : public fipObject -{ -protected: - /// Pointer to a multi-page file stream - FIMULTIBITMAP *_mpage; - /// TRUE when using a memory cache, FALSE otherwise - BOOL _bMemoryCache; - -public: - /** - Constructor - @param keep_cache_in_memory When it is TRUE, all gathered bitmap data in the page manipulation process is kept in memory, otherwise it is lazily flushed to a temporary file on the hard disk in 64 Kb blocks. - */ - fipMultiPage(BOOL keep_cache_in_memory = FALSE); - - /** - Destructor - Close the file stream if not already done. - */ - virtual ~fipMultiPage(); - - /// Returns TRUE if the multi-page stream is opened - BOOL isValid() const; - - /** - Returns a pointer to the FIMULTIBITMAP data. Used for direct access from FREEIMAGE functions - or from your own low level C functions. - */ - operator FIMULTIBITMAP*() { - return _mpage; - } - - /** - Open a multi-page file stream - @param lpszPathName Name of the multi-page bitmap file - @param create_new When TRUE, it means that a new bitmap will be created rather than an existing one being opened - @param read_only When TRUE the bitmap is opened read-only - @param flags Load flags. The signification of this flag depends on the image to be loaded. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_OpenMultiBitmap - */ - BOOL open(const char* lpszPathName, BOOL create_new, BOOL read_only, int flags = 0); - - /** - Open a multi-page memory stream as read/write. - @param memIO Memory stream. The memory stream MUST BE a wrapped user buffer. - @param flags Load flags. The signification of this flag depends on the image to be loaded. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_LoadMultiBitmapFromMemory - */ - BOOL open(fipMemoryIO& memIO, int flags = 0); - - /** - Open a multi-page image as read/write, using the specified FreeImageIO struct and fi_handle, and an optional flag. - @param io FreeImageIO structure - @param handle FreeImage fi_handle - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_OpenMultiBitmapFromHandle - */ - BOOL open(FreeImageIO *io, fi_handle handle, int flags = 0); - - /** - Close a file stream - @param flags Save flags. The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_CloseMultiBitmap - */ - BOOL close(int flags = 0); - - /** - Saves a multi-page image using the specified FreeImageIO struct and fi_handle, and an optional flag. - @param fif Format identifier (FreeImage format) - @param io FreeImageIO structure - @param handle FreeImage fi_handle - @param flag The signification of this flag depends on the multi-page image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SaveMultiBitmapToHandle, FreeImage documentation - */ - BOOL saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags = 0) const; - - /** - Saves a multi-page image using the specified memory stream and an optional flag. - @param fif Format identifier (FreeImage format) - @param memIO FreeImage memory stream - @param flag The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SaveMultiBitmapToMemory, FreeImage documentation - */ - BOOL saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flags = 0) const; - - /** - Returns the number of pages currently available in the multi-paged bitmap - @see FreeImage_GetPageCount - */ - int getPageCount() const; - - /** - Appends a new page to the end of the bitmap - @param image Image to append - @see FreeImage_AppendPage - */ - void appendPage(fipImage& image); - - /** - Inserts a new page before the given position in the bitmap - @param page Page number. Page has to be a number smaller than the current number of pages available in the bitmap. - @param image Image to insert - @see FreeImage_InsertPage - */ - void insertPage(int page, fipImage& image); - - /** - Deletes the page on the given position - @param page Page number - @see FreeImage_DeletePage - */ - void deletePage(int page); - - /** - Moves the source page to the position of the target page. - @param target Target page position - @param source Source page position - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_MovePage - */ - BOOL movePage(int target, int source); - - /** - Locks a page in memory for editing. You must call unlockPage to free the page
          - Usage :
          -
          -	fipMultiPage mpage;
          -	// ...
          -	fipImage image;		// You must declare this before
          -	image = mpage.lockPage(2);
          -	if(image.isValid()) {
          -	  // ...
          -	  mpage.unlockPage(image, TRUE);
          -	}
          -	
          - @param page Page number - @return Returns the page if successful, returns NULL otherwise - @see FreeImage_LockPage - */ - FIBITMAP* lockPage(int page); - - /** - Unlocks a previously locked page and gives it back to the multi-page engine - @param image Page to unlock - @param changed When TRUE, the page is marked changed and the new page data is applied in the multi-page bitmap. - @see FreeImage_UnlockPage - */ - void unlockPage(fipImage& image, BOOL changed); - - /** - Returns an array of page-numbers that are currently locked in memory. - When the pages parameter is NULL, the size of the array is returned in the count variable. - You can then allocate the array of the desired size and call - getLockedPageNumbers again to populate the array. - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_GetLockedPageNumbers - */ - BOOL getLockedPageNumbers(int *pages, int *count) const; -}; - -// ---------------------------------------------------------- - -/** -FreeImage Tag - -FreeImage uses this structure to store metadata information. -*/ -class FIP_API fipTag : public fipObject -{ -protected: - /// Pointer to a FreeImage tag - FITAG *_tag; - -public: - /**@name Creation & Destruction */ - //@{ - /** - Constructor - @see FreeImage_CreateTag - */ - fipTag(); - /** - Destructor - @see FreeImage_DeleteTag - */ - virtual ~fipTag(); - /** - Construct a FIDT_ASCII tag (ASCII string).
          - This method is useful to store comments or IPTC tags. - @param name Field name - @param value Field value - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_CreateTag - */ - BOOL setKeyValue(const char *key, const char *value); - - //@} - - /**@name Copying */ - //@{ - /** - Copy constructor - @see FreeImage_CloneTag - */ - fipTag(const fipTag& tag); - /** - Copy constructor - @see FreeImage_CloneTag - */ - fipTag& operator=(const fipTag& tag); - /** - Assignement operator
          - Copy the input pointer and manage its destruction - @see operator FITAG*() - */ - fipTag& operator=(FITAG *tag); - //@} - - /** - Returns a pointer to the FITAG data. Used for direct access from FREEIMAGE functions - or from your own low level C functions. - @see operator=(FITAG *tag) - */ - operator FITAG*() { - return _tag; - } - - /// Returns TRUE if the tag is allocated, FALSE otherwise - BOOL isValid() const; - - /**@name Tag accessors */ - //@{ - /** - Returns the tag field name (unique inside a metadata model). - @see FreeImage_GetTagKey - */ - const char *getKey() const; - /** - Returns the tag description if available, returns NULL otherwise - @see FreeImage_GetTagDescription - */ - const char *getDescription() const; - /** - Returns the tag ID if available, returns 0 otherwise - @see FreeImage_GetTagID - */ - WORD getID() const; - /** - Returns the tag data type - @see FreeImage_GetTagType - */ - FREE_IMAGE_MDTYPE getType() const; - /** - Returns the number of components in the tag (in tag type units) - @see FreeImage_GetTagCount - */ - DWORD getCount() const; - /** - Returns the length of the tag value in bytes - @see FreeImage_GetTagLength - */ - DWORD getLength() const; - /** - Returns the tag value - @see FreeImage_GetTagValue - */ - const void *getValue() const; - /** - Set the tag field name - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagKey - */ - BOOL setKey(const char *key); - /** - Set the (usually optional) tag description - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagDescription - */ - BOOL setDescription(const char *description); - /** - Set the (usually optional) tad ID - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagID - */ - BOOL setID(WORD id); - /** - Set the tag data type - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagType - */ - BOOL setType(FREE_IMAGE_MDTYPE type); - /** - Set the number of data in the tag - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagCount - */ - BOOL setCount(DWORD count); - /** - Set the length of the tag value, in bytes - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagLength - */ - BOOL setLength(DWORD length); - /** - Set the tag value - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_SetTagValue - */ - BOOL setValue(const void *value); - - //@} - - /** - Converts a FreeImage tag structure to a string that represents the interpreted tag value - @param model Metadata model specification (metadata model from which the tag was extracted) - @param Make Camera model (not used yet) - */ - const char* toString(FREE_IMAGE_MDMODEL model, char *Make = NULL) const; - -}; - -/** -Metadata iterator - -Usage :
          -
          -fipImage image;
          -// ...
          -fipTag tag;
          -fipMetadataFind finder;
          -if( finder.findFirstMetadata(FIMD_EXIF_MAIN, image, tag) ) {
          -  do {
          -    // process the tag
          -	cout << tag.getKey() << "\n";
          -
          -  } while( finder.findNextMetadata(tag) );
          -}
          -// the class can be called again with another metadata model
          -if( finder.findFirstMetadata(FIMD_EXIF_EXIF, image, tag) ) {
          -  do {
          -    // process the tag
          -	cout << tag.getKey() << "\n";
          -
          -  } while( finder.findNextMetadata(tag) );
          -}
          -
          -*/ -class FIP_API fipMetadataFind : public fipObject -{ -protected: - /// Pointer to a search handle - FIMETADATA *_mdhandle; - -public: - /// Returns TRUE if the search handle is allocated, FALSE otherwise - BOOL isValid() const; - - /// Constructor - fipMetadataFind(); - /** - Destructor - @see FreeImage_FindCloseMetadata - */ - virtual ~fipMetadataFind(); - /** - Provides information about the first instance of a tag that matches - the metadata model specified in the model argument. - @param model Metadata model - @param image Input image - @param tag Returned tag - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_FindFirstMetadata - */ - BOOL findFirstMetadata(FREE_IMAGE_MDMODEL model, fipImage& image, fipTag& tag); - /** - Find the next tag, if any, that matches the metadata model argument - in a previous call to findFirstMetadata - @param tag Returned tag - @return Returns TRUE if successful, returns FALSE otherwise, indicating that no more matching tags could be found - @see FreeImage_FindNextMetadata - */ - BOOL findNextMetadata(fipTag& tag); - -}; - -#endif // FREEIMAGEPLUS_H diff --git a/sdk/include/hxgrid/Interface/IAgent.h b/sdk/include/hxgrid/Interface/IAgent.h deleted file mode 100644 index 50706992d83..00000000000 --- a/sdk/include/hxgrid/Interface/IAgent.h +++ /dev/null @@ -1,160 +0,0 @@ -#pragma once - -#include "VECOM.h" -#include "INOUT.h" -#include "IGenericStream.h" - -using namespace VITALENGINE; - - -//==================================================== -//==================================================== -#pragma pack(1) -typedef struct -{ - char bind_ip[20]; - WORD bind_port; - - char coordinator_ip[20]; - WORD coordinator_port; - - WORD user_data_port; - - bool useHT; - - bool explicitCPU; - - DWORD freeCPUCount; - - DWORD suspend_timeout; - - bool enableDebugOutput; - - DWORD agent_broadcast_port; - DWORD coordinator_broadcast_port; - - //agent is caching data, requested by IAgent->GetData() - //do not grow datacache large then this value - DWORD maxDataCacheSize; - - //number of threads in thread pool, - //derived from CPUCount and freeCPUCount - DWORD poolSize; - - //allow to discard specified coordinator IP, - //if user(or agent) is unable to connect to coordinator. - //default is 1 (allow) - - //There are four modes: - // - //coordinator_ip='', allowDiscardCoordinatorIp=1 - //user will broadcast network to find coordinator address. - //If valid address is found, it will be stored in 'coordinator_ip' - //field and used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=1 - //actually same as first mode. First, will try to connect to specified address. - //If no success, will discard specified address and broadcast - //network to find coordinator. Valid address will be stored in - //'coordinator_ip' fiend to be used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=0 - //Will constantly try to connect to specified address. - //This mode is recommended is coordinator address is fixed, - //or network does not support broadcasting. - // - //coordinator_ip='', allowDiscardCoordinatorIp=0 - //Will broadcast network, find coordinator and - //connect to it. On next time, also start brom broadcasting. - bool allowDiscardCoordinatorIp; - -} TAgentSettings; -#pragma pack() - -//=========================================================== -// IAgent -//=========================================================== -DECLARE_INTERFACE_(IAgent, IUnknown) -{ - IUNKNOWN_METHODS_PURE(0x85343215,0x00010001) - - virtual HRESULT __stdcall GetVersion(OUT DWORD* version) = 0; - - //Request global data from user. - - //sessionId - sessionId value, passed to TaskProc() - - //dataDesc - symbolic identifier of data, f.e. 'geometry', zero-terminated string, case sensetive. - //Agent can cache data internally during the session to minimize network transfer. - - //stream - address of variable to receive address of stream with data. - //Task should release stream after using data (call stream->Release()). - - //Returns S_OK if success. - //Returns S_FALSE if there is network problem (then task should exit with false result). - //Returns S_FALSE if GetDataCallback did not return data for specified id. - //Returns S_FALSE if GetDataCallback is not binded on user. - - //Stream is read-only; task should not modify it, except chaging current position. - //Returned stream is seeked to zero. - - //What happends internally is that agent returns T_AgentGenericStreamWrapper class - //instance, which is read-only IGenericStream wrapper aroung block of memory in agent - //data cache. - - //IAgent->GetData(stream); IAgent->PurgeCache(); stream->Release() sequences are correctly handled. - - //(NOTE: this behaviour has been implemented since version 1.09; now stream access - //should not be guarded by global critical section). - - virtual HRESULT __stdcall GetData(DWORD sessionId, const char* dataDesc, IGenericStream** stream) = 0; - - //Remove specified data from agent data cache. - //If task is copying received data to manually implemented global cache, - //and so is sure that data will not be requested again by tasks on this agent, - //it is recommended to free cache to lower memory usage. - - //For example, Normalmapeer_task is requesting hi-poly mesh quadtree, - //maked instance of quadtreeclass and places it to manually implemented cache. - //Others tasks will not call GetData(). notmalmampper_Task can - //call FreeCachedData() to free cache. - - //Note: data cache will not grow more than maxDataCacheSize settings. - - virtual HRESULT __stdcall FreeCachedData(DWORD sessionId, const char* dataDesc) = 0; - - //TaskProc should periodically call this method to allow agent to: - //- check for connection; - //- check to cancelation; - //- suspend execution; - - //returns S_OK if ok, - //returns S_FALSE if connection has been lost or task has been cancelled. - //If the case of S_FALSE, taskproc should exit and return false. - // - //This is very fast method and can be called very frequently. - // - //I agent wants to suspend execution, it will sleep() inside method. - virtual HRESULT __stdcall TestConnection(DWORD sessionId) = 0; - - //Return path to directory with task dll and data files. - //If additional files have been specified in IGridUser->RunTask() - //for transferring along with task dll, - //TaskProc can search for additional files there. - //Path contains trailing \. - //[Path] should point to char[MAX_PATH] buffer. - //TaskProc should not relay on current directory. Agents can run several tasks simultaneously. - //TaskProc should use absolute paths only. - virtual HRESULT __stdcall GetSessionCacheDirectory(DWORD sessionId, OUT char* path); - - //Agent can run several tasks simultaneously. - //If task is manipulating some global settings, like current directory, - //or is accessing non-thread-safe library, - //it should use global critical section. - //Example: - // - enter global cs; - // - chdir() - // - delete file in current directory; - // - leave global cs; - virtual HRESULT __stdcall GetGlobalCriticalSection(OUT CRITICAL_SECTION** cs); -}; diff --git a/sdk/include/hxgrid/Interface/IGenericStream.h b/sdk/include/hxgrid/Interface/IGenericStream.h deleted file mode 100644 index 6606ed655b7..00000000000 --- a/sdk/include/hxgrid/Interface/IGenericStream.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef IGENERICSTREAM_INCLUDED -#define IGENERICSTREAM_INCLUDED - -#include "hxplatform.h" -#include "VECOM.h" - -namespace VITALENGINE -{ - -//=========================================================== -// TGENERICSTREAMCREATIONPARAMETERS -//=========================================================== -typedef struct -{ - void* data; - DWORD length; -} TGENERICSTREAMCREATIONPARAMETERS; - -//=========================================================== -// IGenericStream -//=========================================================== -// stream -// , stream -DECLARE_INTERFACE_(IGenericStream, IUnknown) -{ - IUNKNOWN_METHODS_PURE(0x762EFFFE,0x00010000) - - virtual DWORD __stdcall GetVersion() const = 0; - - virtual BYTE* __stdcall GetBasePointer() = 0; - - virtual BYTE* __stdcall GetCurPointer() = 0; - - virtual bool __stdcall isReadOnly() = 0; - - virtual DWORD __stdcall GetLength() = 0; - - virtual void __stdcall Write(const void* Data, DWORD count) = 0; - - virtual DWORD __stdcall Read(void* Data, DWORD count) = 0; - - virtual void __stdcall Seek(DWORD pos) = 0; - - virtual DWORD __stdcall GetPos() = 0; - - virtual void __stdcall Clear() = 0; - - //do not deallocate memory - virtual void __stdcall FastClear() = 0; - - virtual void __stdcall GrowToPos(int DestSize=-1) = 0; - - virtual void __stdcall Skip(DWORD count) = 0; - - virtual void __stdcall SetLength(DWORD newLength) = 0; - - virtual void __stdcall Compact() = 0; - -}; - -} //namespace - -#endif IGENERICSTREAM_INCLUDED \ No newline at end of file diff --git a/sdk/include/hxgrid/Interface/IGridUser.h b/sdk/include/hxgrid/Interface/IGridUser.h deleted file mode 100644 index c0e5ac96e17..00000000000 --- a/sdk/include/hxgrid/Interface/IGridUser.h +++ /dev/null @@ -1,291 +0,0 @@ -#pragma once - -#include "VECOM.h" -#include "INOUT.h" -#include "IGenericStream.h" -#include "IAgent.h" - -using namespace VITALENGINE; - -//==================================================== -// Task callback -//==================================================== -//This callback is called by Agents on remote nodes to run distributed task. -// -// IAgent - interface to agent we are running at; -// -// sessioId - unique sessionId. Agent can run tasks from diferent users -// at the same time. -// -// IAgent and sessionId can be used to request global data. -// -// inStream - stream with input data, passed to IGridUser->RunTask(). -// inSteam is owned by the library. Callback should not call Release() on it. -// inStream is seeked to 0, and ready to read data. -// -// outStream - stream to write output data. -// outStream is created and owned by the library. -// -// Callback should return false, if job has been aborted (see IAgent->TestConnection()). -typedef bool (__cdecl TTaskProc)(DWORD sessionId, IGenericStream* inStream, IGenericStream* outStream); - -//==================================================== -// EndSession callback -//==================================================== -// Called by Agents on remote nodes after ending session. -// Usually used to release any global session data. -// -// IAgent - agent we are running at; -// sessionId - unique session id; -typedef void (__cdecl EndSession)(IAgent* agent, DWORD sessionId); - -//==================================================== -// Finalize callback -//==================================================== -// This callback is called on local workstation to process output data -// from tasks -// -// outStream - data, returned from remote task. -// -// GridUser will release outStream just after the call returns. -// Finalize is allowed to add reference to keep stream in memory -// as long as needed. See GridGMP example. -typedef void (__cdecl TFinalizeProc)(IGenericStream* outStream); - -//==================================================== -// GetData callback -//==================================================== -//This callback is called on local workstation to request -//global data, as a result of call IAgent->GetData(). -// -// dataDesc - simbolic data Id, passed to IAgent->GetData() -// -// stream - variable to receive address of stream, filled with data. -// -// Callback should create stream and fill it with data. -// Ownership of stream is transferred to library. -typedef void (__cdecl TGetDataProc)(const char* dataDesc, IGenericStream** outStream); - -//=========================================================== -//=========================================================== -#pragma pack(1) -typedef struct -{ - //maximum number of tasks, allowed to be sent to agent, - //without waiting for completion of curent task - // - //used to "hide" network transfer time - // - //recommened value for long tasks (transfer time << run task) is 1 - // - //recommended value for shorts tasks (transfer time*~0.5 == run time) is 10 - // - //default is 1 - - DWORD maxSendAheadTasks; - - //maximum number of tasks, buffered by IGridUser, - //before RunTask() method will block until at least one task is completed - // - //larger values are commended if task formation time is significant - // - //value of 1 can be used for debugging - // - //default is 40 - - DWORD maxQueqedTasks; - - //memory limit for tasks queue of IGridUser - //(summ of inoutStream lengths) - //queue length is limited by number of tasks (maxQueqedTasks) and this memory limit - // - //default is max( physicalMemory/8, 100Mb ) - - DWORD userMaxMemoryUsage; - - //do not send tasks to agent, if it has not enought free physical memory - // - //default is 50Mb - - DWORD agentMinFreeMemory; - - //do not send task to agent, if it has less free physical memory then (task stream size)*Factor - // - //default is 1.5x - - float agentMinFreeMemoryFactor; - - //send dublicate tasks to free agent - // - //this allows not to wait for slow agent - // - //default is 1 (enabled) - - bool sendDublicateTasks; - - //swap tasks from queqe to disk if userMaxMemoryUsage reached. - //allows to queque more huge tasks(stream size 100Mb and large) - // - //default is 1 (enabled) - - bool allowSwapping; - - //if stream size if larger then this value, library will compress it before sending. - //compression speed is about 10-20 MB/sec - this will speedup network transfer significanly - //on 100MBit and slower networks - //aslo lowers memory usage, since tasks streams are kept compressed until task is run - // - //default is 65K - - DWORD compressThreshold; - - char coordinator_ip[20]; - WORD coordinator_port; - - WORD user_data_port; - WORD agent_lobby_port; - - WORD coordinator_broadcast_port; - WORD user_broadcast_port; - - //Enable debug output - //default is 0 - - bool enableDebugOutput; - - //suspend sending tasks to agent if it failed last task, ms - //default is 10000 - //if agent has failed task for some reason, we better suspend sending - //tasks to it; let other agents do the job - DWORD failSuspendTimeout; - - //allow to discard specified coordinator IP, - //if user(or agent) is unable to connect to coordinator. - //default is 1 (allow) - - //There are four modes: - // - //coordinator_ip='', allowDiscardCoordinatorIp=1 - //user will broadcast network to find coordinator address. - //If valid address is found, it will be stored in 'coordinator_ip' - //field and used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=1 - //actually same as first mode. First, will try to connect to specified address. - //If no success, will discard specified address and broadcast - //network to find coordinator. Valid address will be stored in - //'coordinator_ip' fiend to be used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=0 - //Will constantly try to connect to specified address. - //This mode is recommended is coordinator address is fixed, - //or network does not support broadcasting. - // - //coordinator_ip='', allowDiscardCoordinatorIp=0 - //Will broadcast network, find coordinator and - //connect to it. On next time, also start brom broadcasting. - bool allowDiscardCoordinatorIp; - -} TGridUserSettings; -#pragma pack() - -#pragma pack(1) - -//==================================================== -//==================================================== -typedef struct -{ - bool bConnectedToCoordinator; - DWORD connectedAgentsCount; -} TGridUserConnectionStatus; -#pragma pack() - -//=========================================================== -// IGridUser -//=========================================================== -DECLARE_INTERFACE_(IGridUser, IUnknown) -{ - IUNKNOWN_METHODS_PURE(0x5623F256,0x00010000) - - //return IGridUser::VESION - virtual HRESULT __stdcall GetVersion(OUT DWORD* version) = 0; - - //moduleName - dll filename with function code - // - //Please note, that some dependent DLLs, for example, - //VC++ runtime libraries, can be missing on remote workstation. - //It is advised to build with static libraries, - //and always check dependencies with tdump utility. - //To send additional DLLs to workstation, - //their names should be specified in RunTask() method, - //separated with comma: - // - //user.RunTask('GridGMP_task.dll,GMPPort.dll','RunTask',stream,Finalize,d,true); - - //taskProcName - Symbolic name of function - //(function should be exported from DLL by name) - - //inStream - input stream. - //Library is receiving ownership of the stream object. - - //finalizeProc - completion callback address - - //taskId - address of variable to receive unique id of task - - //blocking - blocking flag. - - //If task can not be added to queue immediately - //(due to limitations to queue length or queue input streams size), - //and blocking flag is set, method will not return until task - //is added to queue. Otherwise method will return S_FALSE, - //and application can wait for good moment - //with User->WaitForCompletionEvent()) - - virtual HRESULT __stdcall RunTask(IN const char* moduleName, - IN const char* taskProcName, - IGenericStream* inStream, - TFinalizeProc* finalizeProc, - OUT DWORD* taskId, - bool blocking = true) = 0; - - //Wait for completion of all queued tasks - virtual HRESULT __stdcall WaitForCompletion() = 0; - - //Check whether specified task is finalized - virtual HRESULT __stdcall IsComplete(OUT bool* complete) = 0; - - //attach GetData() callback - virtual void __stdcall BindGetDataCallback(TGetDataProc* callback) = 0; - - //return structure with current user settings - //(as read from ini file) - virtual void __stdcall GetSettings(TGridUserSettings* settings) = 0; - - //set settings and save to ini file - virtual void __stdcall SetSettings(TGridUserSettings* settings) = 0; - - //Wait for some task to complete. - //Used to wait for the good moment to call - //RunTask(blocking = false). - //timeout - maximum wait time in milliseconds. - //Returns S_OK if wait is successfull. - //Note - RunTask() can still return S_FALSE. - virtual HRESULT __stdcall WaitForCompletionEvent(DWORD timeout) = 0; - - //Compress specified stream with ZLIB. - //Signature bytes are put at the start of the stream. - //If user or agent is receiving compressed stream, it will - //decompress it on other side automatically. - virtual HRESULT __stdcall CompressStream(IGenericStream* stream) = 0; - - //Cancel all queued tasks. - //Will not return untill queue is empty. - //After cancelation, IGridUser object - //is still ready to queue orher tasks. - virtual HRESULT __stdcall CancelTasks() = 0; - - //return current connection status - //used for progress monitoring - //see \Mandelbrot\GridGMP sample - virtual void __stdcall GetConnectionStatus(OUT TGridUserConnectionStatus* status) = 0; -}; diff --git a/sdk/include/hxgrid/Interface/I_Agent.pas b/sdk/include/hxgrid/Interface/I_Agent.pas deleted file mode 100644 index e3116cb5fad..00000000000 --- a/sdk/include/hxgrid/Interface/I_Agent.pas +++ /dev/null @@ -1,169 +0,0 @@ -//============================================================================== -// hxGrid framework -// Copyright (C) 2007 by Roman Lut -// hax@deep-shadows.com -// http://www.deep-shadows.com/hax/ -//============================================================================== - -unit I_Agent; - -interface -uses Windows, Classes, I_GenericStream; - -//==================================================== -//==================================================== -type TAgentSettings = packed record - bind_ip : array [0..19] of char; - - bind_port : WORD; - - coordinator_ip : array [0..19] of char; - coordinator_port : WORD; - - user_data_port : WORD; - - //todo: handle this - useHT : boolean; - - explicitCPU : boolean; - - freeCPUCount : DWORD; - - suspend_timeout : DWORD; - - enableDebugOutput : boolean; - - agent_broadcast_port : DWORD; - coordinator_broadcast_port : DWORD; - - //agent is caching data, requested by IAgent->GetData() - //do not grow datacache large then this value - maxDataCacheSize : DWORD; - - //number of threads in thread pool, - //derived from CPUCount and freeCPUCount - poolSize : DWORD; - - //allow to discard specified coordinator IP, - //if user(or agent) is unable to connect to coordinator. - //default is 1 (allow) - - //There are four modes: - // - //coordinator_ip='', allowDiscardCoordinatorIp=1 - //user will broadcast network to find coordinator address. - //If valid address is found, it will be stored in 'coordinator_ip' - //field and used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=1 - //actually same as first mode. First, will try to connect to specified address. - //If no success, will discard specified address and broadcast - //network to find coordinator. Valid address will be stored in - //'coordinator_ip' fiend to be used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=0 - //Will constantly try to connect to specified address. - //This mode is recommended is coordinator address is fixed, - //or network does not support broadcasting. - // - //coordinator_ip='', allowDiscardCoordinatorIp=0 - //Will broadcast network, find coordinator and - //connect to it. On next time, also start brom broadcasting. - allowDiscardCoordinatorIp: boolean; - end; - -const IID_IAGENT = $85343215; -const IAGENT_VERSION = $00010001; - -//=========================================================== -// IAgent -//=========================================================== -type IAgent = interface(IUnknown) - - function GetVersion(var version: DWORD): HRESULT; stdcall; - - //Request global data from user. - - //sessionId - sessionId value, passed to TaskProc() - - //dataDesc - symbolic identifier of data, f.e. 'geometry', zero-terminated string, case sensetive. - //Agent can cache data internally during the session to minimize network transfer. - - //stream - address of variable to receive address of stream with data. - //Task should release stream after using data (call stream->Release()). - - //Returns S_OK if success. - //Returns S_FALSE if there is network problem (then task should exit with false result). - //Returns S_FALSE if GetDataCallback did not return data for specified. - //Returns S_FALSE if GetDataCallback is not binded on user. - - //Stream is read-only; task should not modify it, except chaging current position. - //Returned stream is seeked to zero. - - //What happends internally is that agent returns T_AgentGenericStreamWrapper class - //instance, which is read-only IGenericStream wrapper aroung block of memory in agent - //data cache. - - //IAgent->GetData(stream); IAgent->PurgeCache(); stream->Release() aequences are correctly handled. - - //(NOTE: this behaviour has been implemented since version 1.09; now stream access - //should not be guarded by global critical section). - - function GetData(sessionId: DWORD; dataDesc: pchar; var stream:IGenericStream): HRESULT; stdcall; - - //Remove specified data from agent data cache. - //If task is copying received data to manually implemented global cache, - //and so is sure that data will not be requested again by tasks on this agent, - //it is recommended to free cache to lower memory usage. - - //For example, Normalmapeer_task is requesting hi-poly mesh quadtree, - //maked instance of quadtreeclass and places it to manually implemented cache. - //Others tasks will not call GetData(). notmalmampper_Task can - //call FreeCachedData() to free cache. - - //Note: data cache will not grow more than maxDataCacheSize settings. - - function FreeCachedData(sessionId: DWORD; dataDesc: pchar): HRESULT; stdcall; - - //TaskProc should periodically call this method to allow agent to: - //- check for connection; - //- check to cancelation; - //- suspend execution; - - //returns S_OK if ok, - //returns S_FALSE if connection has been lost or task has been cancelled. - //If the case of S_FALSE, taskproc should exit and return false. - // - //This is very fast method and can be called very frequently. - // - //I agent wants to suspend execution, it will sleep() inside method. - function TestConnection(sessionId :DWORD): HRESULT; stdcall; - - //Return path to directory with task dll and data files. - //If additional files have been specified in IGridUser->RunTask() - //for transferring along with task dll, - //TaskProc can search for additional files there. - //Path contains trailing \. - //[Path] should point to char[MAX_PATH] buffer. - //TaskProc should not relay on current directory. Agents can run several tasks simultaneously. - //TaskProc should use absolute paths only. - function GetSessionCacheDirectory(sessionId :DWORD; path: pchar): HRESULT; stdcall; - - //Agent can run several tasks simultaneously. - //If task is manipulating some global settings, like current directory, - //or is accessing non-thread-safe library, - //it should use global critical section. - //Example: - // - enter global cs; - // - chdir() - // - delete file in current directory; - // - leave global cs; - function GetGlobalCriticalSection(var cs: PRTLCriticalSection): HRESULT; stdcall; - - -end; - - -implementation - -end. diff --git a/sdk/include/hxgrid/Interface/I_GenericStream.pas b/sdk/include/hxgrid/Interface/I_GenericStream.pas deleted file mode 100644 index e4eabc13d72..00000000000 --- a/sdk/include/hxgrid/Interface/I_GenericStream.pas +++ /dev/null @@ -1,62 +0,0 @@ -//============================================================================== -// hxGrid framework -// Copyright (C) 2007 by Roman Lut -// hax@deep-shadows.com -// http://www.deep-shadows.com/hax/ -//============================================================================== - -unit I_GenericStream; - -interface -uses windows, sysutils; - -const IID_IGENERICSTREAM = $762EFFFE; -const IGENERICSTREAM_VERSION = $00010000; - -//=========================================================== -// TGENERICSTREAMCREATIONPARAMETERS -//=========================================================== -type TGENERICSTREAMCREATIONPARAMETERS = packed record - ptr: pointer; - length : DWORD; - end; - -//=========================================================== -// IGenericStream -//=========================================================== -type IGenericStream = interface(IUnknown) - - function GetVersion(): DWORD; - - function GetBasePointer(): PByteArray; stdcall; - - function GetCurPointer(): PByteArray; stdcall; - - function isReadOnly(): boolean; stdcall; - - function GetLength(): DWORD; stdcall; - - procedure Write(var data; count: DWORD); stdcall; - - function Read(var data; count: DWORD): DWORD; stdcall; - - procedure Seek(pos: DWORD); stdcall; - - function GetPos(): DWORD; stdcall; - - procedure Clear(); stdcall; - - procedure FastClear(); stdcall; - - procedure GrowToPos(DestSize : integer = -1); stdcall; - - procedure Skip(count: DWORD); stdcall; - - procedure SetLength(newLength: DWORD); stdcall; - - procedure Compact(); stdcall; -end; - -implementation - -end. diff --git a/sdk/include/hxgrid/Interface/I_GridUser.pas b/sdk/include/hxgrid/Interface/I_GridUser.pas deleted file mode 100644 index 9a6b2b21ecf..00000000000 --- a/sdk/include/hxgrid/Interface/I_GridUser.pas +++ /dev/null @@ -1,331 +0,0 @@ -//============================================================================== -// hxGrid framework -// Copyright (C) 2007 by Roman Lut -// hax@deep-shadows.com -// http://www.deep-shadows.com/hax/ -//============================================================================== - -unit I_GridUser; - -interface -uses Windows, I_GenericStream, I_Agent; - -//==================================================== -// Task callback -//==================================================== -//This callback is called by Agents on remote nodes to run distributed task. -// -// IAgent - interface to agent we are running at; -// -// sessioId - unique sessionId. Agent can run tasks from diferent users -// at the same time. -// -// IAgent and sessionId can be used to request global data. -// -// inStream - stream with input data, passed to IGridUser->RunTask(). -// inSteam is owned by the library. Callback should not call Release() on it. -// inStream is seeked to 0, and ready to read data. -// -// outStream - stream to write output data. -// outStream is created and owned by the library. -// -// Callback should return false, if job has been aborted (see IAgent->TestConnection()). -type TTaskProc = function(agent: IAgent; sessionId: DWORD; inStream: IGenericStream; outStream: IGenericStream): boolean; cdecl; - -//==================================================== -// EndSession callback -//==================================================== -// Called by Agents on remote nodes after ending session. -// Usually used to release any global session data. -// -// IAgent - agent we are running at; -// sessionId - unique session id; -type TEndSessionProc = procedure(agent: IAgent; sessionId: DWORD); cdecl; - -//==================================================== -// Finalize callback -//==================================================== -// This callback is called on local workstation to process output data -// from tasks -// -// outStream - data, returned from remote task. -// -// GridUser will release outStream just after the call returns. -// Finalize is allowed to add reference to keep stream in memory -// as long as needed. See GridGMP example. -type TFinalizeProc = procedure(outStream: IGenericStream); cdecl; - -//==================================================== -// GetData callback -//==================================================== -//This callback is called on local workstation to request -//global data, as a result of call IAgent->GetData(). -// -// dataDesc - simbolic data Id, passed to IAgent->GetData() -// -// stream - variable to receive address of stream, filled with data. -// -// Callback should create stream and fill it with data. -// Ownership of stream is transferred to library. -type TGetDataProc = procedure(dataDesc: pchar; var stream: IGenericStream); cdecl; - -//==================================================== -//==================================================== -type TGridUserSettings = packed record - //maximum number of tasks, allowed to be sent to agent, - //without waiting for completion of curent task - // - //used to "hide" network transfer time - // - //recommened value for long tasks (transfer time << run task) is 1 - // - //recommended value for shorts tasks (transfer time*~0.5 == run time) is 10 - // - //default is 1 - - maxSendAheadTasks : DWORD; - - //maximum number of tasks, buffered by IGridUser, - //before RunTask() method will block until at least one task is completed - // - //larger values are commended if task formation time is significant - // - //value of 1 can be used for debugging - // - //default is 40 - - maxQueqedTasks: DWORD; - - //memory limit for tasks queue of IGridUser - //(summ of inoutStream lengths) - //queue length is limited by number of tasks (maxQueqedTasks) and this memory limit - // - //default is max( physicalMemory/8, 100Mb ) - - userMaxMemoryUsage : DWORD; - - //do not send tasks to agent, if it has not enought free physical memory - // - //default is 50Mb - - agentMinFreeMemory: DWORD; - - //do not send task to agent, if it has less free physical memory then (task stream size)*Factor - // - //default is 1.5x - - agentMinFreeMemoryFactor : single; - - //send dublicate tasks to free agent - // - //this allows not to wait for slow agent - // - //default is 1 (enabled) - - sendDublicateTasks : boolean; - - //swap tasks from queqe to disk if userMaxMemoryUsage reached. - //allows to queque more huge tasks(stream size 100Mb and large) - // - //default is 1 (enabled) - - allowSwapping : boolean; - - //if stream size if larger then this value, library will compress it before sending. - //compression speed is about 10-20 MB/sec - this will speedup network transfer significanly - //on 100MBit and slower networks - //aslo lowers memory usage, since tasks streams are kept compressed until task is run - // - //default is 65K - - compressThreshold : DWORD; - - //last seen coordinator IP - coordinator_ip : array [0..19] of char; - coordinator_port : WORD; - - user_data_port : WORD; - agent_lobby_port : WORD; - - //look 'AllowDiscardCoordinatorIP' - coordinator_broadcast_port : WORD; - user_broadcast_port : WORD; - - //Enable debug output - //default is 0 - - enableDebugOutput : boolean; - - //suspend sending tasks to agent if it failed last task, ms - //default is 10000 - //if agent has failed task for some reason, we better suspend sending - //tasks to it; let other agents do the job - failSuspendTimeout : DWORD; - - //allow to discard specified coordinator IP, - //if user(or agent) is unable to connect to coordinator. - //default is 1 (allow) - - //There are four modes: - // - //coordinator_ip='', allowDiscardCoordinatorIp=1 - //user will broadcast network to find coordinator address. - //If valid address is found, it will be stored in 'coordinator_ip' - //field and used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=1 - //actually same as first mode. First, will try to connect to specified address. - //If no success, will discard specified address and broadcast - //network to find coordinator. Valid address will be stored in - //'coordinator_ip' fiend to be used next time. - // - //coordinator_ip='xx.xx.xx.xx', allowDiscardCoordinatorIp=0 - //Will constantly try to connect to specified address. - //This mode is recommended is coordinator address is fixed, - //or network does not support broadcasting. - // - //coordinator_ip='', allowDiscardCoordinatorIp=0 - //Will broadcast network, find coordinator and - //connect to it. On next time, also start brom broadcasting. - allowDiscardCoordinatorIp: boolean; - - end; - -//==================================================== -//==================================================== -type TGridUserConnectionStatus = packed record - bConnectedToCoordinator : boolean; - connectedAgentsCount : DWORD; - end; - -const IID_IGRIDUSER = $5623F256; -const IGRIDUSER_VERSION = $00010000; - -//=========================================================== -// IGridUser -//=========================================================== -type IGridUser = interface(IUnknown) - - //return IGRIDUSER_VERSION - function GetVersion(var version: DWORD): HRESULT; stdcall; - - //moduleName - dll filename with function code - // - //Please note, that some dependent DLLs, for example, - //VC++ runtime libraries, can be missing on remote workstation. - //It is advised to build with static libraries, - //and always check dependencies with tdump utility. - //To send additional DLLs to workstation, - //their names should be specified in RunTask() method, - //separated with comma: - // - //user.RunTask('GridGMP_task.dll,GMPPort.dll','RunTask',stream,Finalize,d,true); - - //taskProcName - Symbolic name of function - //(function should be exported from DLL by name) - - //inStream - input stream. - //Library is receiving ownership of the stream object. - - //finalizeProc - completion callback address - - //taskId - address of variable to receive unique id of task - - //blocking - blocking flag. - - //If task can not be added to queue immediately - //(due to limitations to queue length or queue input streams size), - //and blocking flag is set, method will not return until task - //is added to queue. Otherwise method will return S_FALSE, - //and application can wait for good moment - //with User->WaitForCompletionEvent()) - - function RunTask(moduleName: pchar; - taskProcName: pchar; - inStream : IGenericStream; - finalizeProc : TFinalizeProc; - var taskId: DWORD; - blocking: boolean) : HRESULT; stdcall; - - //Wait for completion of all queued tasks - function WaitForCompletion(): HRESULT; stdcall; - - //Check whether specified task is finalized - function IsComplete(var complete: boolean): HRESULT; stdcall; - - //attach GetData() callback - procedure BindGetDataCallback(callback: TGetDataProc); stdcall; - - //return structure with current user settings - //(as read from ini file) - procedure GetSettings(var settings: TGridUserSettings); stdcall; - - //set settings and save to ini file - procedure SetSettings(var settings: TGridUserSettings); stdcall; - - //Wait for some task to complete. - //Used to wait for the good moment to call - //RunTask(blocking = false). - //timeout - maximum wait time in milliseconds. - //Returns S_OK if wait is successfull. - //Note - RunTask() can still return S_FALSE. - function WaitForCompletionEvent(timeout: DWORD): HRESULT; stdcall; - - //Compress specified stream with ZLIB. - //Signature bytes are put at the start of the stream. - //If user or agent is receiving compressed stream, it will - //decompress it on other side automatically. - function CompressStream(stream: IGenericStream): HRESULT; stdcall; - - //Cancel all queued tasks. - //Will not return untill queue is empty. - //After cancelation, IGridUser object - //is still ready to queue orher tasks. - function CancelTasks(): HRESULT; stdcall; - - //return current connection status - //used for progress monitoring - //see \Mandelbrot\GridGMP sample - procedure GetConnectionStatus(var status: TGridUserConnectionStatus); stdcall; -end; - -procedure IGridUser_Create(var user: IGridUser); - -implementation - -type - TCreateGridUserObject = function(version: DWORD): pointer; cdecl; - - -var - DLLHandle : HINST; - pProc: TCreateGridUserObject; - -//============================================================== -//============================================================== -procedure IGridUser_Create(var user: IGridUser); -var - d: DWORD; -begin - if (DLLHandle=0) then - begin - DLLHandle := LoadLibrary('hxGridUserDLL.dll'); - assert(DLLHandle<>0); - end; - - if (@pProc=nil) then - begin - @pProc := GetProcAddress(DLLHandle,'CreateGridUserObject'); - assert(@pProc<>nil); - end; - - pointer(user):=pProc(IGRIDUSER_VERSION); - - d:=user._AddRef(); - d:=user._Release(); -end; - -begin - DLLHandle:=0; - @pProc:=nil; -end. diff --git a/sdk/include/hxgrid/Interface/InOut.h b/sdk/include/hxgrid/Interface/InOut.h deleted file mode 100644 index 84c079ac81d..00000000000 --- a/sdk/include/hxgrid/Interface/InOut.h +++ /dev/null @@ -1,9 +0,0 @@ - -#ifndef INOUT_INCLUDED -#define INOUT_INCLUDED - -#define IN -#define OUT -#define INOUT - -#endif INOUT_INCLUDED \ No newline at end of file diff --git a/sdk/include/hxgrid/Interface/Singleton.h b/sdk/include/hxgrid/Interface/Singleton.h deleted file mode 100644 index 6be049f5ebb..00000000000 --- a/sdk/include/hxgrid/Interface/Singleton.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SINGLETON_INCLUDED -#define SINGLETON_INCLUDED - -template -class Singleton -{ - protected: - Singleton(); - ~Singleton(); - - public: - - static C& GetInstance() - { - static C Instance; - return Instance; - } -}; -#endif SINGLETON_INCLUDED diff --git a/sdk/include/hxgrid/Interface/VECOM.h b/sdk/include/hxgrid/Interface/VECOM.h deleted file mode 100644 index cbc83788f2b..00000000000 --- a/sdk/include/hxgrid/Interface/VECOM.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef VECOM_INCLUDED -#define VECOM_INCLUDED - -#include - -#include "hxplatform.h" -#include "Singleton.h" - -#ifndef TINTERFACEID -typedef unsigned int TINTERFACEID; -#endif - -#ifndef TCLASSID -typedef unsigned int TCLASSID; -#endif - -// IUnknown methods -#define IUNKNOWN_METHODS_PURE(InterfaceId, InterfaceVersion) \ - virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppv) = 0; \ - virtual ULONG __stdcall AddRef() = 0; \ - virtual ULONG __stdcall Release() =0 ; \ - typedef enum \ - { \ - ID = ##InterfaceId, \ - VERSION = ##InterfaceVersion, \ - FORCE_DWORD = 0xffffffff \ - } desc; \ - static REFIID GetREFIID() { static IID iid; iid.Data1 = InterfaceId; iid.Data2 = 0; iid.Data3 = 0; return iid; } - -//for singleton classes -#define IUNKNOWN_METHODS_IMPLEMENTATION_REFERENCE() \ - virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppv) {*ppv=NULL; return E_NOINTERFACE;}; \ - virtual ULONG __stdcall AddRef() {return 1;}; \ - virtual ULONG __stdcall Release() {return 1;}; - -#define IUNKNOWN_METHODS_IMPLEMENTATION_REFERENCE_EXCLUDEQUERYINTERFACE() \ - virtual ULONG __stdcall AddRef() {return 1;}; \ - virtual ULONG __stdcall Release() {return 1;}; - -//REVIEW: QueryInterface() -//The interface returned by QueryInterface in response to a request for IID_IUnknown (the interface -//ID for IUnknown) should have the same pointer value at all times and from all interfaces on that -//instance. This is not required of any other interface. This pointer value is the instance's -//identity. The identity of an object is the way in which one compares two objects to see if they -//are actually the same one. This can be found only by comparing the IUnknown interface pointers. -//You can find the identity of the object behind any interface by first doing a QueryInterface for IUnknown -//and then comparing the pointers. - -namespace VECOM -{ - -//========================== -//TInitRefCount -//========================== -//helper class in refcount initialization and holding -class TRefCountHolder -{ - public: - std::atomic RefCount; - - TRefCountHolder() - { - RefCount.store(1, std::memory_order_release); - } -}; - -} //namespace - -//for instantiated classes - tracks refcount -#define IUNKNOWN_METHODS_IMPLEMENTATION_INSTANCE() \ - VECOM::TRefCountHolder RefCountHolder; \ - virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppv) {*ppv=NULL; return E_NOINTERFACE;}; \ - virtual ULONG __stdcall AddRef() { return RefCountHolder.RefCount.fetch_add(1, std::memory_order_acq_rel); }; \ - virtual ULONG __stdcall Release() { ULONG r = RefCountHolder.RefCount.fetch_sub(1, std::memory_order_acq_rel); if (r==0) delete this; return r;}; - -#define IUNKNOWN_METHODS_IMPLEMENTATION_INSTANCE_EXCLUDEQUERYINTERFACE() \ - VECOM::TRefCountHolder RefCountHolder; \ - virtual ULONG __stdcall AddRef() { return RefCountHolder.RefCount.fetch_add(1, std::memory_order_acq_rel); }; \ - virtual ULONG __stdcall Release() { ULONG r = RefCountHolder.RefCount.fetch_sub(1, std::memory_order_acq_rel); if (r==0) delete this; return r; }; - - -//factory method for creating interfaces -typedef IUnknown* (__cdecl *PInterfaceFactoryMethod)(TINTERFACEID InterfaceId, DWORD version, const void* ExData); - - -//====================================== -// IInstanceInterfaceProvider -//====================================== -// -// , -//( ExData) -DECLARE_INTERFACE_(IInstanceInterfaceProvider, IUnknown) -{ - IUNKNOWN_METHODS_PURE(0x78923789,0x00010000) - - virtual DWORD __stdcall GetVersion() const = 0; - - // registry , - // , - // Exdata - // , !!! - // TInstanceInterfaceProvider - // - virtual IUnknown* __stdcall GetInterface(TINTERFACEID InterfaceId, DWORD version, const void* ExData) = 0; -}; - - - -//=================================================== -// class TInterfaceObject -//=================================================== -// , , factory method -template -class TInterfaceObject : public InterfaceClass -{ -public: - virtual DWORD __stdcall GetVersion() const - { - return InterfaceClass::VERSION; - } -}; - -#endif VECOM_INCLUDED diff --git a/sdk/include/hxgrid/Interface/hxGridInterface.cpp b/sdk/include/hxgrid/Interface/hxGridInterface.cpp deleted file mode 100644 index f36ec3f5b37..00000000000 --- a/sdk/include/hxgrid/Interface/hxGridInterface.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "hxGridInterface.h" -#include "assert.h" - -typedef IGridUser* (__cdecl TCreateGridUserObject)(DWORD version); - -typedef IGenericStream* (__cdecl TCreateGenericStream)(); - -//============================================================== -//============================================================== -IGridUser* CreateGridUserObject(DWORD version) -{ - static HINSTANCE DLLHandle(0); - - if (DLLHandle==0) - { - DLLHandle = LoadLibrary("hxGridUserDLL.dll"); - assert(DLLHandle!=0); - } - - static TCreateGridUserObject* pProc(NULL); - - if (pProc==NULL) - { - pProc = (TCreateGridUserObject*)GetProcAddress(DLLHandle,"CreateGridUserObject"); - assert(pProc!=NULL); - } - return pProc(version); -} - -//============================================================== -//============================================================== -IGenericStream* CreateGenericStream() -{ - static HINSTANCE DLLHandle(0); - - if (DLLHandle==0) - { - DLLHandle = LoadLibrary("hxGridUserDLL.dll"); - assert(DLLHandle!=0); - } - - static TCreateGenericStream* pProc(NULL); - - if (pProc==NULL) - { - pProc = (TCreateGenericStream*)GetProcAddress(DLLHandle,"CreateGenericStream"); - assert(pProc!=NULL); - } - return pProc(); -} diff --git a/sdk/include/hxgrid/Interface/hxGridInterface.h b/sdk/include/hxgrid/Interface/hxGridInterface.h deleted file mode 100644 index d3271ce0a67..00000000000 --- a/sdk/include/hxgrid/Interface/hxGridInterface.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "IGridUser.h" - -IGridUser* CreateGridUserObject(DWORD version); -IGenericStream* CreateGenericStream(); - diff --git a/sdk/include/hxgrid/Interface/hxplatform.h b/sdk/include/hxgrid/Interface/hxplatform.h deleted file mode 100644 index 311f0d8bffd..00000000000 --- a/sdk/include/hxgrid/Interface/hxplatform.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -#ifdef _XBOX - -#ifdef _WINDOWS_ANYWAY -#include - -#else - -#include "xtl.h" -#include "XBoxMessageBox.h" - -#endif - -#else _WINDOWS_ANYWAY - -// XXX: Perhaps requesting Windows 2000 functionality is a bit silly in 2016? -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0500 -#endif - -#include - -#endif - -#ifdef __cplusplus - -//count -template -void __inline ChangeByteOrder(T* ptr, DWORD count = 1) -{ - char a[0]; // -} - -template<> -void __inline ChangeByteOrder(WORD* ptr, DWORD count) -{ -#ifdef _XBOX - for (DWORD i=0; i> 8) & 0x00FF); - - ptr++; - } -#endif _XBOX -} - -template<> -void __inline ChangeByteOrder(DWORD* ptr, DWORD count) -{ -#ifdef _XBOX - for (DWORD i=0; i> 8) & 0x0000FF00) | - ((((*ptr))>>24) & 0x000000FF)); - - ptr++; - } -#endif _XBOX -} - -template<> -void __inline ChangeByteOrder(unsigned __int64* ptr, DWORD count) -{ -#ifdef _XBOX - for (DWORD i=0; i> 8) & 0x00000000FF000000ULL) | - (((*ptr)>>24) & 0x0000000000FF0000ULL) | - (((*ptr)>>40) & 0x000000000000FF00ULL) | - (((*ptr)>>56) & 0x00000000000000FFULL)); - - ptr++; - } -#endif _XBOX -} - - -template<> -void __inline ChangeByteOrder(int* ptr, DWORD count) -{ - ChangeByteOrder((DWORD*)ptr, count); -} - -template<> -void __inline ChangeByteOrder(long* ptr, DWORD count) -{ - ChangeByteOrder((DWORD*)ptr, count); -} - - -template<> -void __inline ChangeByteOrder(short* ptr, DWORD count) -{ - ChangeByteOrder((WORD*)ptr, count); -} - -template<> -void __inline ChangeByteOrder(__int64* ptr, DWORD count) -{ - ChangeByteOrder((unsigned __int64*)ptr, count); -} - - -template<> -void __inline ChangeByteOrder(double* ptr, DWORD count) -{ - ChangeByteOrder((unsigned __int64*)ptr, count); -} - -template<> -void __inline ChangeByteOrder(float* ptr, DWORD count) -{ - ChangeByteOrder((DWORD*)ptr, count); -} - -#ifdef _XBOX -void __inline MessageBeep(DWORD d) -{ -} -#endif _XBOX - -#endif __cplusplus diff --git a/sdk/libraries/x64/FreeImage.lib b/sdk/libraries/x64/FreeImage.lib deleted file mode 100644 index 8a93d251e087cc3576ba6199b45b9d421094f6b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65322 zcmeHwd7M?nmH)vQV;GY-#&I0S7-Ebui5j+UNyc%21_TA{K!fNw;-mWkPn!2SuOA9b zCUG3c5ceqV`;Pk(7u->C-}ikdF1W98!DPO5>)ls%YB_J~_MhL6&*$*^-m`pbyLIc< zsXFz8?K8#BxjPK}`5^vpn<4xTy6bt|2fcNLro&4_imv*lrmMFlQgjvgitbpd>CUx@6ukvGMQ^UqbR%RH z-2hod_l(wb!$@3%u6tC|Jy+pA=+4EOuGxf0(QUA!=#j%TT~;JgbTMQV-M&oI!>14_ z`sg%GAD&O7=%F(-eT4iedU%kgC%{v*db*}-4gwws$w}zieTWp@wv(p&HY8H?=sRWl z4Sqp)Y^LeDJ&_O4hr=~Jv^8)+*RG@KaQrIz>{3mKZb78zpglAljJzm1G=E+lrojUegiCr=pkE z*YwUQNH6H!4K>}1x=9H4?gibqMAHh?dqNxF7j(sBO@F$dD4}-zf-Zkp)0N|h6kTz* zrdv=(if-DpOi15NpqtldTKORI3A*`!G7ZEp=*DH5o*0UD0($o#O{-=QCG;eIL2tme zqSsKiie5*$6+H)@qGvwU^z3Yu1L)F?G(9$pNYRC5I`VuXMMrI^>5nUj650vBpmUaM zIwen}=%lqZ9k(%&qBHN*blQ_dijF%;)49Wm6rJ*xrjz!E9_ZMmn$AL5DLQ?+rsI(Z zMdx0s>D0Z66fNCc(@|$3eW0^eYC8Q<=z)$uPSdijh!mZ@T+mFdJVmFj(sc4-=!1?y8WkOld@4F;q^1)$BvN$#x|+`0 zm`KrSdulrQBj|&UMLj4w2I*FGCfbmq6Om3u=N+Nx`~zSIbOFjw(M7v!y6{=l9q6J5 zHGKk`iY|kUqQ9W76M7oIpihyfgjV7g^x5{BUPn3=J%{pFbmwYKFQR-DeLhIj^Qa?5 zmmZ?&vB%MVK!+Zq>F#^ckAsdtdKA63MAJ)a@VqHP9u%!vrRht^D*7wREuqWt3;Ggi zQ1rnHP45Fk(R*ua`d}jNgWmg~ObhV~dcRB4gUg8&J#fFK`+%+J!7-ZdNB$D(!7u26 zJv1GT`-(0jO_vNNQuN7snl6W&qJv;p(ZQoNU3m+hchIZLG`)#3Qgr=JnpQuI{vC8J zY%6+ogr<*=AX0SL0h&JE6xX1`25MSzAd#Zw$7s5JDBd%mC2PurbS(k>;q@|=@C$kz zxQZ@0L(|KjqJIWmJYLf)v(ayYjzl^XEl2$-x*F+M^b}+jJ-wf%rxxQH^yHD6p22-Z zPeMo0Q>Yh3&yc1Uktanjz?Pyvca&)*epk+%Ibl-!E>k*Yju|_(ZOVl9j$NkA99PU{ zC(O^x$p8sC5$#obV7c1!2?Y1 zdy?a`nXYUxCST?nEtK(?LaDbsTSSp&i@SM>oj^O3 z_DpxSRPviPv{Dw6A2VTe>=8^^OuntqT`2ZW>&1=Fe-Ms`fLw^S@Fn$XtPUM$Scb^EFI zC5(1kF`Fr61!Ygb=%Sd4Fr6dN;<3K<*7pGigMqUf8z7cw>&gx@qAw$XF2!|4wS857C~#+~zTj9WmU<$5afH z=}gIX#WYfukw=oJ>^NG<_j;+ac}$}{w=mlslrM9PG;)>*Uu zbX0?#yI}sTd?wfJWrQ(}4&dWDjLCFH=SqIwA)eeflF3-bONzd0q^9M&3mN}aQoe2E zMs;@=I?-Qtcoq%EmyQZs?}t=BGPH2mK8Dtdrz_>hG{+T+!4l=bsg$uYu~3+|pl9mz z9m9Qr!*=y%3>hNnRoF(at&ra*TP$@H@Vtx~(&`nh%a3S|lNHBVHM7ftQqKYmEPH$L zy@6M3r>E*m7*sTR#-3X0YRhy7AC910+>)0J7s|@Rgx-m{QmH#THs6)YrEKTYy6t7u<^@r#ytrd5 zOV^SzR(37sO86F3-`5_l%`+NP@L?5EuvkXEBir2_k+)bzerh&5FCuTTjQpt1UoXfN zV|n0Qqct_NPqw2F!?Br0XCmG|LbGt#Mz8$69V}y;XEb){!B{3-DHhAfqgzSF6XA}U zbA7Gw_&(LrT%&~+C17!`uNB5hwE|dEJ2Uy%cV30ZaK=p-r)o(($ob6tZ1@p$Wh4vU zgP|TOZouk;z?r(Br>9UX^-eBC#(yChlLCutzTNzRR75OjXY4|ipx`jkGGj>zRzly> zo)P|KZLw9SlFQHW$}}JnOoQrUs_3U8MqgLhl_4;3MI$d1GwJ<3+KY1Z}C8m`tY_3-*&d-#R$6$g#j#8RTfa~g} ztqeynlTJ{vLwee>pjj4hb)z5WC}GVr8WVckyBEyK<;UjLtbqSf;PQ>8>eWP5Pr&G+ zg`g6%MO9zLe5P9)@^Tsx^X*K;cS*?MlcTT_1h?88XZByVi|e!m6F*v_}S$Nc)IF2 znIdc3B9i`Ce*&(IZ&`qlZ3EMQlxQX1 zA*pnvRv;C$f~t};q6LDws3KWc3j}phHL|W2@N_#0!-mTBR_1$}sx*+9VM8ZndW`#_ z)1MzGzks6hLCeT$U6zCLLCYwJx-19fgO*j_F>I*R2FnsbZPl`d4XvdWm!(82)myQ$ zBD7*TBT2=FpMa``pasIIuU3FbW%#%qg({toW(P6VD57fDGu+2i?OD~QsH+8nxT?Nu z>a?_wWTSdz!-i1TVir)S}?YuBz)1wLIEdNU~AAu3;lq*VVF+@Wbd;GLO0*;XflCg>l`5 zOet34DceI#d_q-RLSTpW{E3W8vx29|_6Jq&2WPxEH-I&@1m8iX*d=Q-seqMf6DD^^ zSuOL8X2;xOws&r!+n>)c93wp@SDG7G;8ebCn#-s(^r5rk# z`54tm6aOJOV@XX(SQ5!hSa_m7E@`Y`A`TNg^Riv-@LNuXQyy+Oua<&B#>S+=K3S#i z=~Wm;RyoT%=LMxLmXTM93rbfQMs`dV%gMqiu~@r&Gp(OtqRlV zU;?-!GY4+s@T%Vm&()Zi&Cdy}2Gr)tOjjq|IJJs9=dJGsUr83rMVK(gs|_s;hAV6P zFf7P+wRtW|uza;b!gA#U<*TJx z`RZGC>4kG{OSnj(^3`^E`J#);XHmjlWmFi(vhJ8e!iHm{^)l0twBZ@Jxh7cAjB;Vl`kx}TdS}Z)t-DW|fr{u5=(v(68 zt7HP{sxXW!o-frGb!Qj0&CTTV+2HCUN5W{M9XPx|`*I|Vw!#)b%Pb?W&?52{%gF2O zdgWHWZRDozo9QX9JjX(STxZsA1OXAFk6}RfB4Z%CFg8ex3L0AqDDiZJ(@+ag*nB{d@l_EGfbnCTFsY= znSguSVY_;xlQnDk&>LNAS^}=_j+y!MGhQ;an&!D0Z3~L}2L;<4e{jF|N^? zg0()O>C5!KCpjhC=}&@{r4wEQ(G^Cd(G^r|h5Pr%222E37=b;bbMGRWayQXdZ)49c z{=VWZqSE0+zr2cQ+pBSn-=%jDt$io%fw$sK+`kd`Zy*|d579{cK6)MEE8y?NklExK z$lQi~sgDp9u|f8#i?JvAcI@ZIzSh$|!v5qBv1j@r;NkB>(d{lCCIV$jmhVGqC0-b%DP_MWcB9^F0h zcMtZ@u6l)NzfZ6)_6_X4{ypShM>#zUOzc}-|0U!Lb~k(%`MDQ=gO(uOhpiym05tgu zl=Yv8+CdLrPBiXH?0d$&66|k!6YPQ3+>E`(z&rrI13}ABwnI@S2f^lyRoFKRDgk?w z*I*miPd@U~h8yJy4J z8Ho3A0_y8zlYcE1R9g1kM5-;YoSZ(W9b{{?%EL6foXcqM3iw1IU| zF4Lbwz1@lQyoh#%`W%Nga0trhag@(7hayhH-LQi?TY_?2^Aa#XtJdKDmq^=Rv0ocB z9e=O*06OoZ+}gIa1h1HP17SA8<9q}>Jav0hJeh1?Bz$HlUaU|L8mtBqfPob?ojdI8Dkx$}pw39*j zT^rYG)AbQ3n`JK$b^IA+2O6*z(Ju5By-sh^JM=cSK9>z)JxaV6ZFq?2|Z1F(tpq%^zXD6&7|jOAgxD#N1xEg^agEAThb8P zie9E|=^yAt8buq@2K4tdmu68X?M}PV9GXpCl%WZ<6YWUjDN8@0f1=g&J=%u8Mc<}> zq^oId`UZWSZlv$hMl_vvrJvFadI;UqBlH+ONDtEkG?;!sKcvlQG;KmZrmg8`RHEzY zT^dO_+Je^5=kz6gMt`AC>96z!{hEsOE4qq$=vw*({SrmLoc=~r=@z<~{*~UR4{0LJ zqiz~7V66eK(DRh16?7#PsGa81Wcm@kL@&_#^c`B4)}eo+9jJq*(cW}7-ADJ*{d5=I zLwC~8X%KBr-=|k;6+K0h=wiAQ4f1mO6J0^W=o%VJm0%PEDP$TPh4gvMt2D zYi9p#1+}3*xbo7v&x+f8;aLEBcb*!3r)yIsrem+NMzh*_sg#ekTb_C4u~&R)rAo?| z^o7L_O1;YZ3c;POv_+4-^2D39f{_gJg`;7i$|_8W9W8@oZCFebew#Q8vsB3kTe8C+ zYrA5S@f9M0RRQVB8NEOvoyK0%VxNdqc|@Xxk(BMg(>CW z{BLABS#Wunv_Oa#wYuSiL*ddYN(H}@Mjv5!Q=b>Vsm5eZV+WufWhb$Z9C7C3b9l}! ze#Q-kSh7P$&ER>kS-WvoU_%{}jJr|yGkEeQMKzjCH{5z)Hq)M$)}RSD*^L-fOtvAi zl0af2n;v7EILll59sAZs|M5Cj0Ee;o-Y8uqz07xW6yI2h{=6Kbh5>~lONE?mz%*R} z&x;8h!z?Ee)4V(0R~8JbksCMZuS;WwbcrPKz?}Q#uy?_`?wS@Lhn8U_w{>tbW+o5< z%-V|Xh$8S#U^}@V*9TzXedKu41k#JU(Z>Y5z_Jg%JOgkLi>z1iI}*t1rARDy#H ziK}IqtCHcMkUg4~T(XAAY9XPuOa7Mfq{P$3)?RD$mcV+sQxYA8pkih5wn?Otw%b=Q zP7GE##fO2`5-7{8x2lTq>=Bkd_<}8)We>i<3d{{!ck!-pyL)h1Te9lHWu<|uSTcie zNN6Va-8ZDV&%z@xQ+OGksBZ>}DD*~D!qywn zedRHBi5IKU^WKHl$}p>N{H1G#i2|yugtYFOxJcH`$`%mop4q^`ZdToi!KBR|3^t=1 z-Y?+=)eG(pKs6+Bz^tN6Zw0$Vo9R9ADbs$A!vUybi_g_$cTp`SGx?Smo^v^C0eOSr zti82ma%8H+?_w=+^VIEie=(-K@=jRt7Fj@-`f)tGisQyxi<3HO#x9I6s4ahU#H?y| z>fe#2;vfNz@%VT~J-<&-qL$^P+6UySb5Br^i;lr7O{i78LIEZ4EZ>kPz&u1E7rlVb zPgni=p6YZ?u)0VPA>==bm`c4wwM76Z`;w~ID(|qaBBlLG)rBx?Tt!Ixn5qj^ zv&8*PqCM_)l0+-B`PGH0q%WD-m#tuaznXwM%P-3huVSz2mfo@}LqM^7RaKrYJYMF+H^H!1c#@Ruh5XNG9O~H%BlJ zoomtZ(}h_fFyCkA>4x{qbN`*I1YbiM%+q-BstN^*-!f&U@%`OJmRQBFCjhFsq0kOH z%S`Iy^Q>@BpU-yveIW_%^$SU`<6t}i?g0$3qkB#;|6E?8mK-!vWdl?wYAGzZQ$lVE zlt?U!ed;9)=%l{F5Ub)bj4_2XQ<(QKsPFg?12U;6F~qWtz?tEVuTU0zVk=+)?Jm0M z7Cd{RD6Gx>jA0q|9a8Z&Ru}QN${;65OkzfR9^*!YFsKzTWLP^5C>!FY9!Y^`O`%kg zD$k_|QsEL{p2~o>@mB_z!bv&OE<)4wg_@V~V+IhV^PeK~3#jMBvl+1F`!@qZx@2Rg z9#y7tgPQi)VgUi;_Y5-QM>ECGM}o&QS$7aBS!=d8fR}nj1FVW~G{D1)IQp=ISLI=c zM0EGOnjsDYieUhPFJ3ePKw*9{5YR#KqKBa#m`epeXN0;hmV>H z_*-3F<8=*iFw_knXk&R`T{X)O>$9*|ujEynUGWfjw?CHj0S{&DLqf5t#tX4W>;7;aCTxM-{KB=o)q&Kf!=H-JIv~T^b_jq8r2gxG zA*}n$T&tbgX0*@3XfwHFFKA<%&J2a zCgi`vIXhC+a?BLtN(+W|K|xo%t&c*a-mHCZ<*p{Fgx zCM?y^#+xR;ESA-q;>kw~AFiunDO?Rj?-W&H0!PU?jZF{Su$u~2Z9U%r;} zqPOkp?ncmsZH5dA{u^Ar+cG#6*lS?dfnTG);oo-#V1GKcU#oxHc4cQRn6t%HeMQ)f zi#_V;MfrCmtv`BOwE`lu#n6Thre^Xu3w<-%1RHlAR-(CM3xQor~$-i&I#;7?POv-f@3%!Ner9oRw`N^P( z6DIFm=ChymaHW!>2%F54zt+e9Ur+vGI5e^oRfzPCnloU)-~MLnKp2~l6{Xo8iCy^W z&fN4)l0l7BmKm;OAYx=%%pG-qbM;^OpRz^RRBryQg-zXr_TSeBj1Od)uA#*YZ5di_ zJF3O3m9&`akTjj-aEs|O`AGh5|LM-uw79~+T& zb9)UWv`Iw2I8gOvTP8VO+gb}1*)guV79&+-@7bDmo`X2*Pk=fA-Akp7%#80xPk`%w z3R|`d=l4fIUMqm?Zg+1G^%r5(9|QGkK~#4)eS^5IVcac%yLJed$1zJlD|Ml+YUt-$ z1kA4oFr8>?jbRQ8=ko{1=QYuPOau0OXzt^NZ?X6t!5EW4^Dzmb-!`oxXmsNQR@ zUfdR;Py9y*H(h_sFzT<_Nc;U6a=NjD=&ft!&~?{sYotHk2H5{p1=}m?`q3lLk$UTH z5<<7vSlat`Me9QZZiqpiJ;Wr zSWiIzeid{t>-D#J0ez5!?!5ni;fGQh z>{C^nOoPqkNqdtezFnlR z9|7d8L}YiZJWmL_s^y&{jH!Miq+_^K0DX!3QvuhC>(%FPxu3;w(_J+EI=u}92}gxKIaR6uX7g6=i6`kyl4`QA=I z_ZnKCB99P|z0S05WNGa13laIN8$0|`NQc|t>wdG z_iuaOK|t=`_Wo}o@>kd1M+)h1UoCaFcVRYgR0y}S$<-T1)ZN##3fQAX>^^Ag!na9V z7~73^+t@dPfIB9P>qgUU2)8BT8&W>{v0+>%R&Qf(a0z!@7}p5}-1oRUhH>@YX!Zcr zKi?y@>G5G)v+24?Y^kg#gt47C$&Hn@!u@?5dX17W(P-Fsd88 zyP@0;kMz@O(c!NgT>Hqw##*v8J357u*yng5Ps$0NHn=vjo&oqb-q< zy;{@M5kTZ&(;F*aX+7RFhRI?+u&gyuwn9#)JE)aY>6^tA>T}lsX7lwat+ScoAVwqB zH}s6QM0#Sicy%|9?8L)wuoVeC;O-2MhwI=~%C2g7UL>#4zcW-TnuZAj!rXn&3x{*M^C=^U*fi;dNIYvgI#8u)w0@GAjPc+s<~TIyZ+Dw`R@P6Mql zum);fz}_o{oknnJ5?dNQXE-(w4bvp9)Q`<_aNU?Q9GYF#QqzLZrqe^_v1}L?_t({e z9O*%oZ?wxpW-)R&aNTnbQY~jWG7rAfEN-MnQ7iLjd$^UTK24%Zs}JTdR77)#g$rsj z4bt0kuA2sSHc5khr_hJwJiOS^CyilOHbFUSe+QwK_x7;a$tnpTE9x4aBWX9nJP$98 z$iz_Ues-mCbhnF{ZqVkC^*^=3(=*@0tb~wi7F8H`<%6g?HWi0uS2fhB^gbx~s4V6c z!>YSxrBO$ZkL<+KY7Sd!Rljzz(->VGvhG$Tef<_aOcwmBACY?{WGh^LgFRGaE=R2; zFS*E-aAiEZ?5fEYy&!;TM@C{;ecGb;2_W6Pt~FrwsXQ&gKax9ccy$CizCSV0Ij~q{m%eyB{E)CkjI8FrE%1uF-+$Gssy!16Tz5oyRQJn)Y8_a2B zjIJUp9N}Rmv1OahrO-$G(MPNVt>v)ns+K-NKs_>u>KuL6Pz#o7^e7iK4YJF!)<7$Y zj1<-P?NS%B61|s$va4E3SHL{l#f0NC^pMtzDa{fc6Ts}dZ|WA|nK?FqY@cw~;8QA$ z&5jEovIF!QYq>%XczgiSJ)W<@d8+(?7R(+a_oyPcX zvaY2*>U0;=Ii|V65{~qWDyqU63^5RuyxH6e{o|P~b`mPq9fq?6)ba!iy~bHCVkL|^ zL#e;l5Zck%4ATnF&LQi5YNZj(ISytog1f81Fwa;6Bbdm{i&|ZDu7jBbly5eV!mQ~s zj@LUeS1NU9$L70onS8VPlvWL&=io+8-EFKt62`*kJGdq=aLLIoEA(2Pm`MMizBDdi zs494UTd~mN0M_4jgFDPPlsFeb+@+GNZk(x{$+9eKAWSL*7aN-$8S2{(t7PbF;-p#JNI#__0$;~)`PnHP zmR&Vjuh(^BgyL}Zw_#y~ad!Z(`KX)H2>Bj{ zs7{dLmDa#}FYo#6~^WddZss(9T;x8Ao-TQ! zo{V8u&d_7E$_u{9I)2K89{fGK&5VbE> zok;7Zp7T)I;fFlC^}mmV@#FI@@>j49f&AIS{3_Ogyy~G^>p=QsC5AME|5_Z~bwAeKH%af^*9F|Z=#iz7 zPLbIi&yv@BnISk+`M-{FYncv}ux_md;l=DRLt<=k8j%C2h3XJi&bc`4p=F|G4> z8BX1$E6tz3A4m13h*&CW$*nMM`heqF=La*Cy7MYUCHRnGmd_>TaP_w$VfNr753i4W zd%|4b#|$$)>X;W}1K&9jM70X;lOST$1yXkjOFjNyqS*c46Mh=RZhAIKcxFChi1uOC zyb-gjTAtI0FF@^)`iraBJ1Swz9}|5p#uI%nL${XbK4V4wg1 diff --git a/sdk/libraries/x64/FreeImagePlus.lib b/sdk/libraries/x64/FreeImagePlus.lib deleted file mode 100644 index eb08f263ff41ed254482be1363728642fe0b8232..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68708 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

          )>BtBm60x1h>Px;XSYk*24(g3Aezz;8XB& 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

          4En0_lw%U7ZE2$wG6} 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 E7jm7|IRF3v diff --git a/sdk/libraries/x86/FreeImage.lib b/sdk/libraries/x86/FreeImage.lib deleted file mode 100644 index 433ad8f5d42fbc05a970d0a518b0883e212324ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69766 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 diff --git a/sdk/libraries/x86/FreeImagePlus.lib b/sdk/libraries/x86/FreeImagePlus.lib deleted file mode 100644 index 640e007a8260a362619fc4826bcc3fc0b7601213..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67112 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 diff --git a/src/Layers/xrRenderPC_GL/CMakeLists.txt b/src/Layers/xrRenderPC_GL/CMakeLists.txt index b9dfc698731..1ac1c5a1a94 100644 --- a/src/Layers/xrRenderPC_GL/CMakeLists.txt +++ b/src/Layers/xrRenderPC_GL/CMakeLists.txt @@ -383,6 +383,7 @@ target_sources(xrRender_GL PRIVATE ../../Include/xrRender/UISequenceVideoItem.h ../../Include/xrRender/UIShader.h ../../Include/xrRender/WallMarkArray.h + ../../utils/xrLC_Light/R_light.h ) target_include_directories(xrRender_GL diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj index 377b39983d3..c6433d8ddaf 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj @@ -240,6 +240,7 @@ + diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters index 9558967ccfd..467e542f2b6 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters @@ -1163,6 +1163,9 @@ Refactored\Execution & 3D\Gamma + + Lights + diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj index bc8efde6f44..9d36ac0de5c 100644 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj +++ b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj @@ -62,6 +62,7 @@ + diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters index 1053ced3304..546a5c031b4 100644 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters +++ b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters @@ -606,6 +606,9 @@ Refactored\Execution & 3D\Shaders\Resources + + Lights + diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj index 492bf05ef2a..1394f9a7511 100644 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj +++ b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj @@ -62,6 +62,7 @@ + diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters index 28e04d1b20d..8b7124fa939 100644 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters +++ b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters @@ -642,6 +642,9 @@ Refactored\Execution & 3D\Shaders\Resources + + Lights + diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj index 882eddac91a..74b76367a31 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj @@ -62,6 +62,7 @@ + diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters index 1959eeca3c1..be0ffd38b06 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters @@ -741,6 +741,9 @@ Shading templates + + Lights + diff --git a/src/engine.sln b/src/engine.sln index 8e4578d7cf3..49994fab5c9 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -25,20 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompressionTest", "utils\Co EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctool", "utils\ctool\ctool.vcxproj", "{2FAAC8BA-369F-465E-B465-2235963FD377}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ETools", "utils\ETools\ETools.vcxproj", "{65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrAI", "utils\xrAI\xrAI.vcxproj", "{EA5932F3-02FE-4AD3-89E8-7072DC465D25}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCompress", "utils\xrCompress\xrCompress.vcxproj", "{EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrDO_Light", "utils\xrDO_Light\xrDO_Light.vcxproj", "{B730F54D-1199-481A-AAD0-5DB684E067C0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXT", "utils\xrDXT\DXT.vcxproj", "{EBF9B543-0830-4866-9B48-DC0740E87E8A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC", "utils\xrLC\xrLC.vcxproj", "{A4ABD75E-825B-4D09-B3B2-2709682E40C8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrQSlim", "utils\xrQSlim\xrQSlim.vcxproj", "{F1836CE2-59EF-4189-8B9C-D103A511CB27}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrSE_Factory", "utils\xrSE_Factory\xrSE_Factory.vcxproj", "{3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCDB", "xrCDB\xrCDB.vcxproj", "{A19B1DF2-82EC-4364-8BDF-85D13A1C89B5}" @@ -66,10 +54,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrAPI", "Layers\xrAPI\xrAPI EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrEngine", "xrEngine\xrEngine.vcxproj", "{2578C6D8-660D-48AE-9322-7422F8664F06}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC_Light", "utils\xrLC_Light\xrLC_Light.vcxproj", "{EFB76D6F-0092-439C-A783-C0BE10BD17C9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLC_LightStab", "utils\xrLC_LightStab\xrLC_LightStab.vcxproj", "{EC924B9B-4991-4931-8623-E1DB9AE005CA}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrPhysics", "xrPhysics\xrPhysics.vcxproj", "{98D24A3D-7666-4C11-9D6E-B10393CE8CBA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrRender_R4", "Layers\xrRenderPC_R4\xrRender_R4.vcxproj", "{AC9B12ED-A2D7-4337-A981-5BD8430E96D8}" @@ -80,14 +64,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp_configs_verifyer", "util EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CxImage", "..\Externals\cximage\cximage.vcxproj", "{880CD250-BA77-4DAF-A8D4-552F12DD3AE4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NVTT", "..\Externals\NVTT\NVTT.vcxproj", "{0EB257DC-5CFC-44B0-82C9-CE6B158BE473}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "editors", "editors", "{CB0C814D-FB4E-453B-B7A0-716F4A1EACA4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrWeatherEditor", "editors\xrWeatherEditor\xrWeatherEditor.vcxproj", "{492D3DFE-9068-4E7E-A008-7C2420A651C0}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrLCUtil", "utils\xrLCUtil\xrLCUtil.vcxproj", "{B90BDC22-A891-4B33-B562-29D701F65DBD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrAICore", "xrAICore\xrAICore.vcxproj", "{5CB057D8-4464-40A6-AF10-C26B826D1D90}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrScriptEngine", "xrScriptEngine\xrScriptEngine.vcxproj", "{132C62DE-DE85-4978-9675-C78ED4DA46F0}" @@ -112,8 +92,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvorbisfile", "..\Externa EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BugTrap", "..\Externals\BugTrap.vcxproj", "{E8CF1ADA-264A-4127-86C2-FD7057D3792C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MagicFM", "..\Externals\MagicFM.vcxproj", "{848E8AB3-9962-4C04-B813-5690399C8A3E}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oalib", "..\Externals\oalib.vcxproj", "{61D4856F-FA82-4F02-BB88-909DDFB1FE74}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "..\Externals\cryptlib.vcxproj", "{C39F4B46-6E89-4074-902E-CA57073044D2}" @@ -326,62 +304,6 @@ Global {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x64.Build.0 = Release|x64 {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x86.ActiveCfg = Release|Win32 {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x86.Build.0 = Release|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|ARM.ActiveCfg = Debug|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|ARM.Build.0 = Debug|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|ARM64.ActiveCfg = Debug|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|ARM64.Build.0 = Debug|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|x64.ActiveCfg = Debug|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|x64.Build.0 = Debug|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|x86.ActiveCfg = Debug|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Debug|x86.Build.0 = Debug|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|ARM.ActiveCfg = Mixed|ARM - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|ARM.Build.0 = Mixed|ARM - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|x64.ActiveCfg = Mixed|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|x64.Build.0 = Mixed|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|x86.ActiveCfg = Mixed|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Mixed|x86.Build.0 = Mixed|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|ARM.ActiveCfg = Release|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|ARM.Build.0 = Release|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|ARM64.ActiveCfg = Release|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|ARM64.Build.0 = Release|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|x64.ActiveCfg = Release|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|x64.Build.0 = Release|x64 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|x86.ActiveCfg = Release|Win32 - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33}.Release|x86.Build.0 = Release|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|ARM.ActiveCfg = Debug|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|ARM.Build.0 = Debug|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|ARM64.ActiveCfg = Debug|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|ARM64.Build.0 = Debug|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|x64.ActiveCfg = Debug|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|x64.Build.0 = Debug|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|x86.ActiveCfg = Debug|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Debug|x86.Build.0 = Debug|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|ARM.ActiveCfg = Mixed|ARM - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|ARM.Build.0 = Mixed|ARM - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|x64.ActiveCfg = Mixed|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|x64.Build.0 = Mixed|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|x86.ActiveCfg = Mixed|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Mixed|x86.Build.0 = Mixed|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|ARM.ActiveCfg = Release|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|ARM.Build.0 = Release|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|ARM64.ActiveCfg = Release|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|ARM64.Build.0 = Release|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|x64.ActiveCfg = Release|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|x64.Build.0 = Release|x64 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|x86.ActiveCfg = Release|Win32 - {EA5932F3-02FE-4AD3-89E8-7072DC465D25}.Release|x86.Build.0 = Release|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.ActiveCfg = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.Build.0 = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -414,118 +336,6 @@ Global {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Release|x64.Build.0 = Release|x64 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Release|x86.ActiveCfg = Release|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Release|x86.Build.0 = Release|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|ARM.ActiveCfg = Debug|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|ARM.Build.0 = Debug|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|ARM64.ActiveCfg = Debug|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|ARM64.Build.0 = Debug|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|x64.ActiveCfg = Debug|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|x64.Build.0 = Debug|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|x86.ActiveCfg = Debug|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Debug|x86.Build.0 = Debug|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|ARM.ActiveCfg = Mixed|ARM - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|ARM.Build.0 = Mixed|ARM - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|x64.ActiveCfg = Mixed|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|x64.Build.0 = Mixed|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|x86.ActiveCfg = Mixed|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Mixed|x86.Build.0 = Mixed|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|ARM.ActiveCfg = Release|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|ARM.Build.0 = Release|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|ARM64.ActiveCfg = Release|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|ARM64.Build.0 = Release|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|x64.ActiveCfg = Release|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|x64.Build.0 = Release|x64 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|x86.ActiveCfg = Release|Win32 - {B730F54D-1199-481A-AAD0-5DB684E067C0}.Release|x86.Build.0 = Release|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|ARM.ActiveCfg = Debug|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|ARM.Build.0 = Debug|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|ARM64.ActiveCfg = Debug|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|ARM64.Build.0 = Debug|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|x64.ActiveCfg = Debug|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|x64.Build.0 = Debug|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|x86.ActiveCfg = Debug|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Debug|x86.Build.0 = Debug|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|ARM.ActiveCfg = Mixed|ARM - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|ARM.Build.0 = Mixed|ARM - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|x64.ActiveCfg = Mixed|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|x64.Build.0 = Mixed|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|x86.ActiveCfg = Mixed|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Mixed|x86.Build.0 = Mixed|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|ARM.ActiveCfg = Release|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|ARM.Build.0 = Release|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|ARM64.ActiveCfg = Release|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|ARM64.Build.0 = Release|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|x64.ActiveCfg = Release|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|x64.Build.0 = Release|x64 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|x86.ActiveCfg = Release|Win32 - {EBF9B543-0830-4866-9B48-DC0740E87E8A}.Release|x86.Build.0 = Release|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|ARM.ActiveCfg = Debug|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|ARM.Build.0 = Debug|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|ARM64.ActiveCfg = Debug|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|ARM64.Build.0 = Debug|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|x64.ActiveCfg = Debug|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|x64.Build.0 = Debug|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|x86.ActiveCfg = Debug|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Debug|x86.Build.0 = Debug|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|ARM.ActiveCfg = Mixed|ARM - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|ARM.Build.0 = Mixed|ARM - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|x64.ActiveCfg = Mixed|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|x64.Build.0 = Mixed|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|x86.ActiveCfg = Mixed|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Mixed|x86.Build.0 = Mixed|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|ARM.ActiveCfg = Release|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|ARM.Build.0 = Release|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|ARM64.ActiveCfg = Release|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|ARM64.Build.0 = Release|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|x64.ActiveCfg = Release|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|x64.Build.0 = Release|x64 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|x86.ActiveCfg = Release|Win32 - {A4ABD75E-825B-4D09-B3B2-2709682E40C8}.Release|x86.Build.0 = Release|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|ARM.ActiveCfg = Debug|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|ARM.Build.0 = Debug|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|ARM64.ActiveCfg = Debug|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|ARM64.Build.0 = Debug|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|x64.ActiveCfg = Debug|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|x64.Build.0 = Debug|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|x86.ActiveCfg = Debug|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Debug|x86.Build.0 = Debug|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|ARM.ActiveCfg = Mixed|ARM - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|ARM.Build.0 = Mixed|ARM - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|x64.ActiveCfg = Mixed|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|x64.Build.0 = Mixed|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|x86.ActiveCfg = Mixed|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Mixed|x86.Build.0 = Mixed|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|ARM.ActiveCfg = Release|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|ARM.Build.0 = Release|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|ARM64.ActiveCfg = Release|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|ARM64.Build.0 = Release|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|x64.ActiveCfg = Release|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|x64.Build.0 = Release|x64 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|x86.ActiveCfg = Release|Win32 - {F1836CE2-59EF-4189-8B9C-D103A511CB27}.Release|x86.Build.0 = Release|Win32 {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}.Debug|ARM.ActiveCfg = Debug|Win32 {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}.Debug|ARM.Build.0 = Debug|Win32 {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -907,62 +717,6 @@ Global {2578C6D8-660D-48AE-9322-7422F8664F06}.Release|x64.Build.0 = Release|x64 {2578C6D8-660D-48AE-9322-7422F8664F06}.Release|x86.ActiveCfg = Release|Win32 {2578C6D8-660D-48AE-9322-7422F8664F06}.Release|x86.Build.0 = Release|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|ARM.ActiveCfg = Debug|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|ARM.Build.0 = Debug|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|ARM64.ActiveCfg = Debug|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|ARM64.Build.0 = Debug|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|x64.ActiveCfg = Debug|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|x64.Build.0 = Debug|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|x86.ActiveCfg = Debug|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Debug|x86.Build.0 = Debug|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|ARM.ActiveCfg = Mixed|ARM - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|ARM.Build.0 = Mixed|ARM - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|x64.ActiveCfg = Mixed|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|x64.Build.0 = Mixed|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|x86.ActiveCfg = Mixed|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Mixed|x86.Build.0 = Mixed|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|ARM.ActiveCfg = Release|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|ARM.Build.0 = Release|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|ARM64.ActiveCfg = Release|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|ARM64.Build.0 = Release|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|x64.ActiveCfg = Release|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|x64.Build.0 = Release|x64 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|x86.ActiveCfg = Release|Win32 - {EFB76D6F-0092-439C-A783-C0BE10BD17C9}.Release|x86.Build.0 = Release|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|ARM.ActiveCfg = Debug|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|ARM.Build.0 = Debug|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|ARM64.ActiveCfg = Debug|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|ARM64.Build.0 = Debug|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|x64.ActiveCfg = Debug|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|x64.Build.0 = Debug|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|x86.ActiveCfg = Debug|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Debug|x86.Build.0 = Debug|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|ARM.ActiveCfg = Mixed|ARM - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|ARM.Build.0 = Mixed|ARM - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|x64.ActiveCfg = Mixed|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|x64.Build.0 = Mixed|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|x86.ActiveCfg = Mixed|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Mixed|x86.Build.0 = Mixed|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|ARM.ActiveCfg = Release|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|ARM.Build.0 = Release|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|ARM64.ActiveCfg = Release|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|ARM64.Build.0 = Release|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|x64.ActiveCfg = Release|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|x64.Build.0 = Release|x64 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|x86.ActiveCfg = Release|Win32 - {EC924B9B-4991-4931-8623-E1DB9AE005CA}.Release|x86.Build.0 = Release|Win32 {98D24A3D-7666-4C11-9D6E-B10393CE8CBA}.Debug|ARM.ActiveCfg = Debug|Win32 {98D24A3D-7666-4C11-9D6E-B10393CE8CBA}.Debug|ARM.Build.0 = Debug|Win32 {98D24A3D-7666-4C11-9D6E-B10393CE8CBA}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1123,38 +877,6 @@ Global {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x64.Build.0 = Release|x64 {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x86.ActiveCfg = Release|Win32 {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x86.Build.0 = Release|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|ARM.ActiveCfg = Debug|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|ARM.Build.0 = Debug|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|ARM64.ActiveCfg = Debug|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|ARM64.Build.0 = Debug|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|x64.ActiveCfg = Debug|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|x64.Build.0 = Debug|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|x86.ActiveCfg = Debug|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Debug|x86.Build.0 = Debug|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|ARM.ActiveCfg = Mixed|ARM - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|ARM.Build.0 = Mixed|ARM - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|x64.ActiveCfg = Mixed|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|x64.Build.0 = Mixed|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|x86.ActiveCfg = Mixed|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Mixed|x86.Build.0 = Mixed|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|ARM.ActiveCfg = Release|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|ARM.Build.0 = Release|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|ARM64.ActiveCfg = Release|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|ARM64.Build.0 = Release|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|x64.ActiveCfg = Release|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|x64.Build.0 = Release|x64 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|x86.ActiveCfg = Release|Win32 - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473}.Release|x86.Build.0 = Release|Win32 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|ARM.ActiveCfg = Debug|Win32 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|ARM64.ActiveCfg = Debug|x64 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|x64.ActiveCfg = Debug|x64 @@ -1171,34 +893,6 @@ Global {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Release|ARM64.ActiveCfg = Release|x64 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Release|x64.ActiveCfg = Release|x64 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Release|x86.ActiveCfg = Release|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|ARM.ActiveCfg = Debug|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|ARM.Build.0 = Debug|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|ARM64.ActiveCfg = Debug|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|ARM64.Build.0 = Debug|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|x64.ActiveCfg = Debug|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|x64.Build.0 = Debug|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|x86.ActiveCfg = Debug|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Debug|x86.Build.0 = Debug|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|ARM.ActiveCfg = Mixed|ARM - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|ARM.Build.0 = Mixed|ARM - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|x64.ActiveCfg = Mixed|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|x64.Build.0 = Mixed|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|x86.ActiveCfg = Mixed|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Mixed|x86.Build.0 = Mixed|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|ARM.ActiveCfg = Release|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|ARM.Build.0 = Release|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|ARM64.ActiveCfg = Release|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|ARM64.Build.0 = Release|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|x64.ActiveCfg = Release|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|x64.Build.0 = Release|x64 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|x86.ActiveCfg = Release|Win32 - {B90BDC22-A891-4B33-B562-29D701F65DBD}.Release|x86.Build.0 = Release|Win32 {5CB057D8-4464-40A6-AF10-C26B826D1D90}.Debug|ARM.ActiveCfg = Debug|Win32 {5CB057D8-4464-40A6-AF10-C26B826D1D90}.Debug|ARM.Build.0 = Debug|Win32 {5CB057D8-4464-40A6-AF10-C26B826D1D90}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1567,38 +1261,6 @@ Global {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x64.Build.0 = Release|x64 {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x86.ActiveCfg = Release|Win32 {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x86.Build.0 = Release|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|ARM.ActiveCfg = Debug|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|ARM.Build.0 = Debug|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|ARM64.ActiveCfg = Debug|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|ARM64.Build.0 = Debug|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|x64.ActiveCfg = Debug|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|x64.Build.0 = Debug|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|x86.ActiveCfg = Debug|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Debug|x86.Build.0 = Debug|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|ARM.ActiveCfg = Mixed|ARM - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|ARM.Build.0 = Mixed|ARM - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|x64.ActiveCfg = Mixed|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|x64.Build.0 = Mixed|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|x86.ActiveCfg = Mixed|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Mixed|x86.Build.0 = Mixed|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|ARM.ActiveCfg = Release|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|ARM.Build.0 = Release|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|ARM64.ActiveCfg = Release|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|ARM64.Build.0 = Release|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|x64.ActiveCfg = Release|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|x64.Build.0 = Release|x64 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|x86.ActiveCfg = Release|Win32 - {848E8AB3-9962-4C04-B813-5690399C8A3E}.Release|x86.Build.0 = Release|Win32 {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM.ActiveCfg = Debug|Win32 {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM.Build.0 = Debug|Win32 {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -2056,22 +1718,12 @@ Global {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {3FC858CB-4888-42FF-ABC5-82DAECB59C2C} {C961EA19-716C-4A6D-BB13-689F8FB78B01} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {2FAAC8BA-369F-465E-B465-2235963FD377} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {EA5932F3-02FE-4AD3-89E8-7072DC465D25} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {B730F54D-1199-481A-AAD0-5DB684E067C0} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {EBF9B543-0830-4866-9B48-DC0740E87E8A} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {A4ABD75E-825B-4D09-B3B2-2709682E40C8} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {F1836CE2-59EF-4189-8B9C-D103A511CB27} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {EFB76D6F-0092-439C-A783-C0BE10BD17C9} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {EC924B9B-4991-4931-8623-E1DB9AE005CA} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {032A10AB-E44C-4751-A290-001EF99E664A} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {880CD250-BA77-4DAF-A8D4-552F12DD3AE4} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} - {0EB257DC-5CFC-44B0-82C9-CE6B158BE473} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {492D3DFE-9068-4E7E-A008-7C2420A651C0} = {CB0C814D-FB4E-453B-B7A0-716F4A1EACA4} - {B90BDC22-A891-4B33-B562-29D701F65DBD} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {CCD4AFAE-AA10-42C6-A452-FDEE497CCDF1} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {67FF193E-2C20-402A-9026-9F5F6327503C} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {614AA57F-58D7-45A8-A5FF-93F04B05FAC6} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} @@ -2081,7 +1733,6 @@ Global {3A214E06-B95E-4D61-A291-1F8DF2EC10FD} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {CEBDE98B-A6AA-46E6-BC79-FAAF823DB9EC} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {E8CF1ADA-264A-4127-86C2-FD7057D3792C} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} - {848E8AB3-9962-4C04-B813-5690399C8A3E} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {61D4856F-FA82-4F02-BB88-909DDFB1FE74} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {C39F4B46-6E89-4074-902E-CA57073044D2} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {B5A3098C-C768-45FF-8B6C-1F707C0344F0} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index b03646682fb..c17a168a038 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -1,11 +1 @@ -if (WIN32) - add_subdirectory(xrLC_Light) -endif() - -add_subdirectory(xrLCUtil) - -if (NOT PROJECT_PLATFORM_E2K) # XXX: fix compilation on E2K - add_subdirectory(xrQSlim) -endif() - add_subdirectory(xrMiscMath) diff --git a/src/utils/ETools/ArbitraryList.h b/src/utils/ETools/ArbitraryList.h deleted file mode 100644 index 81a699ba8cc..00000000000 --- a/src/utils/ETools/ArbitraryList.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -// Some standard useful classes, templates, etc. - -#ifndef ArbitraryListH -#define ArbitraryListH - -// An arbitrary-sized list template class. -// Designed to hold _unsorted_ data, but only RemoveItem() -// actually disturbs the order, so you can use it for general arrays -// if you don't use that function. -template -class ArbitraryList -{ - T* pT; // The list. - u32 iSize; // The current size of the list. - u32 iReservedSize; // The current reserved size of the list. -public: - // Constructor, with optional initial size setting. - ArbitraryList(u32 iInitialSize = 0) - { - pT = NULL; - iSize = 0; - iReservedSize = 0; - if (iInitialSize > 0) - resize(iInitialSize); - } - // Destructor. - ~ArbitraryList(void) - { - if (pT == NULL) - { - VERIFY(iReservedSize == 0); - VERIFY(iSize == 0); - } - else - { - VERIFY(iReservedSize > 0); - VERIFY(iSize > 0); - delete[] pT; - pT = NULL; - } - } - // Returns the pointer to the given item. - IC T* item(u32 iItem) - { - VERIFY(iItem < iSize); - return (&pT[iItem]); - } - // Returns the pointer to the first item. - IC T* ptr() { return (pT); } - // Returns the size of the list - IC u32 size() const { return iSize; } - // Grows or shrinks the list to this number of items. - // Preserves existing items. - // Items that fall off the end of a shrink may vanish. - // Returns the pointer to the first item. - IC T* resize(u32 iNum) - { - iSize = iNum; - if (iNum <= iReservedSize) - { - if (iNum == 0) - { - // Shrunk to 0 - bin the memory. - delete[] pT; - pT = NULL; - iReservedSize = 0; - } - else - { - VERIFY(pT != NULL); - } - return (pT); - } - else - { - // Need to grow. Grow by 50% more than - // needed to avoid constant regrows. - u32 iNewSize = (iNum * 3) >> 1; - if (pT == NULL) - { - VERIFY(iReservedSize == 0); - pT = new T[iNewSize]; - } - else - { - VERIFY(iReservedSize != 0); - - T* pOldT = pT; - pT = new T[iNewSize]; - for (u32 i = 0; i < iReservedSize; i++) - { - pT[i] = pOldT[i]; - } - delete[] pOldT; - } - VERIFY(pT != NULL); - iReservedSize = iNewSize; - return (pT); - } - } - // Adds one item to the list and returns a pointer to that new item. - IC T* append() - { - resize(iSize + 1); - return (&pT[iSize - 1]); - } - // Adds one item to the list and returns a pointer to that new item. - IC void push_back(T& val) - { - resize(iSize + 1); - pT[iSize - 1] = val; - } - // Removes the given item number by copying the last item - // to that position and shrinking the list. - IC void erase_fast(u32 iItemNumber) - { - VERIFY(iItemNumber < iSize); - pT[iItemNumber] = pT[iSize - 1]; - resize(iSize - 1); - } - // Copy the specified data into the list. - IC void insert(u32 iFirstItem, T* p, u32 iNumItems) - { - for (u32 i = 0; i < iNumItems; i++) - *(Item(i + iFirstItem)) = p[i]; - } - // A copy from another arbitrary list of the same type. - IC void insert(u32 iFirstItem, ArbitraryList& other, u32 iFirstOtherItem, u32 iNumItems) - { - for (u32 i = 0; i < iNumItems; i++) - *(item(i + iFirstItem)) = *(other.item(i + iFirstOtherItem)); - } - IC T& operator[](u32 id) - { - VERIFY(id < iSize); - return pT[id]; - } - IC const T& operator[](u32 id) const - { - VERIFY(id < iSize); - return pT[id]; - } - - // Copy constructor. - ArbitraryList(const ArbitraryList& other) - { - u32 iNumItems = other.size(); - - pT = NULL; - iSize = 0; - iReservedSize = 0; - if (iNumItems > 0) - resize(iNumItems); - for (u32 i = 0; i < iNumItems; i++) - *(item(i)) = other[i]; - } -}; - -#endif //#ifndef ArbitraryListH diff --git a/src/utils/ETools/BinaryHeap.h b/src/utils/ETools/BinaryHeap.h deleted file mode 100644 index 76cc6113fdb..00000000000 --- a/src/utils/ETools/BinaryHeap.h +++ /dev/null @@ -1,261 +0,0 @@ -#ifndef BinaryHeapH -#define BinaryHeapH -// A binary heap. Actually stores pointers to type THING, not the THINGs themselves. -template -class BinaryHeap -{ -private: - struct Blob - { - THING* pThing; - SORT Sort; - }; - - Blob* pBlobArray; - int iCurrentSize; - int iAllocatedSize; - - int iCurrentPos; - -#ifdef DEBUG - // A flag that says using FindNext, RemoveNext and RemoveCurrent are OK to call. - bool bFindNextValid; -#endif - -public: - BinaryHeap(void) - { - pBlobArray = NULL; - iCurrentSize = 0; - iAllocatedSize = 0; -#ifdef DEBUG - bFindNextValid = FALSE; -#endif - iCurrentPos = 0; - } - - ~BinaryHeap(void) - { - if (pBlobArray != NULL) - { - delete[] pBlobArray; - pBlobArray = NULL; - } - iCurrentSize = 0; - iAllocatedSize = 0; - } - - void Check(void) - { -#if CHECK_HEAP -#ifdef DEBUG - for (int iCurPos = iCurrentSize - 1; iCurPos >= 2; iCurPos--) - { - VERIFY(pBlobArray[iCurPos].Sort <= pBlobArray[iCurPos >> 1].Sort); - VERIFY(pBlobArray[iCurPos].pThing != NULL); - } -#endif -#endif - } - - void Add(THING* pThisThing, SORT ThisSort) - { - Check(); - -#ifdef DEBUG - bFindNextValid = FALSE; -#endif - iCurrentPos = 0; - - if (iCurrentSize <= 1) - { - iCurrentSize = 1; - } - - // Make sure it's big enough. - if (iAllocatedSize <= iCurrentSize) - { - // Add 50% to the allocated size. - iAllocatedSize = (iAllocatedSize >> 1) + iAllocatedSize; - // And then a bit more. - iAllocatedSize += 32; - // And round up to 1k array size. - iAllocatedSize = (iAllocatedSize + 1023) & ~1023; - - Blob* pOldBlobArray = pBlobArray; - pBlobArray = new Blob[iAllocatedSize]; - VERIFY(pBlobArray != NULL); - if (pOldBlobArray != NULL) - { - memcpy(pBlobArray, pOldBlobArray, (iCurrentSize + 1) * sizeof(Blob)); - delete[] pOldBlobArray; - } - Check(); - } - - // And add the item. - iCurrentPos = iCurrentSize; - while ((iCurrentPos > 1) && (pBlobArray[iCurrentPos >> 1].Sort < ThisSort)) - { - pBlobArray[iCurrentPos] = pBlobArray[iCurrentPos >> 1]; - iCurrentPos >>= 1; - } - pBlobArray[iCurrentPos].Sort = ThisSort; - pBlobArray[iCurrentPos].pThing = pThisThing; - - iCurrentSize++; - - Check(); - } - - THING* FindFirst(void) - { - if (iCurrentSize > 1) - { - VERIFY(pBlobArray != NULL); -#ifdef DEBUG - bFindNextValid = TRUE; -#endif - iCurrentPos = 1; - return pBlobArray[1].pThing; - } - else - { -#ifdef DEBUG - bFindNextValid = FALSE; -#endif - iCurrentPos = 0; - return NULL; - } - } - - // Must have called FindFirst first. - // THIS DOES NOT TRAVERSE IN SORTED ORDER! - THING* FindNextUnsorted(void) - { -#ifdef DEBUG - VERIFY(bFindNextValid); -#endif - if (iCurrentPos >= iCurrentSize - 1) - { - // Reached the end. - return NULL; - } - else - { - iCurrentPos++; - - return pBlobArray[iCurrentPos].pThing; - } - } - - // Must have called FindFirst/FindNext first. - SORT GetCurrentSort(void) - { -#ifdef DEBUG - VERIFY(bFindNextValid); -#endif - VERIFY(iCurrentPos < iCurrentSize); - VERIFY(pBlobArray != NULL); - return pBlobArray[iCurrentPos].Sort; - } - - // Must have called FindFirst/FindNext first. - THING* RemoveCurrent(void) - { -#ifdef DEBUG - VERIFY(bFindNextValid); - bFindNextValid = FALSE; -#endif - if (iCurrentPos < (iCurrentSize - 1)) - { - VERIFY(pBlobArray != NULL); - THING* pThing = pBlobArray[iCurrentPos].pThing; - - SORT MovedSort = pBlobArray[iCurrentSize - 1].Sort; - - // First bubble this item up the list until - // the parent is greater or equal to the last item in the heap. - while ((iCurrentPos > 1) && (pBlobArray[iCurrentPos >> 1].Sort < MovedSort)) - { - pBlobArray[iCurrentPos] = pBlobArray[iCurrentPos >> 1]; - iCurrentPos = iCurrentPos >> 1; - } - - // Then delete it, and replace it by the last in the heap, - // then bubble that item down the heap again. - iCurrentSize--; - - // And bubble the last item back down the tree. - while ((iCurrentPos << 1) < iCurrentSize) - { - if ((MovedSort >= pBlobArray[(iCurrentPos << 1) + 0].Sort) && - ((((iCurrentPos << 1) + 1) >= iCurrentSize) || - (MovedSort >= pBlobArray[(iCurrentPos << 1) + 1].Sort))) - { - // Yep - fits here. - break; - } - else - { - // Find the bigger of the two, and move it up. - if ((((iCurrentPos << 1) + 1) < iCurrentSize) && - (pBlobArray[(iCurrentPos << 1) + 0].Sort < pBlobArray[(iCurrentPos << 1) + 1].Sort)) - { - pBlobArray[iCurrentPos] = pBlobArray[(iCurrentPos << 1) + 1]; - iCurrentPos = (iCurrentPos << 1) + 1; - } - else - { - pBlobArray[iCurrentPos] = pBlobArray[(iCurrentPos << 1) + 0]; - iCurrentPos = (iCurrentPos << 1) + 0; - } - } - } - - // Fits here. - pBlobArray[iCurrentPos] = pBlobArray[iCurrentSize]; - pBlobArray[iCurrentSize].pThing = NULL; - - Check(); - - return pThing; - } - else if (iCurrentPos == iCurrentSize - 1) - { - // This is already the last item - that was easy! - iCurrentSize--; - THING* pThing = pBlobArray[iCurrentPos].pThing; - return pThing; - } - else - { - return NULL; - } - } - - // Must have called FindFirst first. - THING* RemoveNext(void) - { -#ifdef DEBUG - VERIFY(bFindNextValid); -#endif - iCurrentPos++; - return RemoveCurrent(); - } - - THING* RemoveFirst(void) - { -#ifdef DEBUG - // Keep the assert happy. - bFindNextValid = TRUE; -#endif - iCurrentPos = 1; - return RemoveCurrent(); - } - - // Number of items in the heap. - int SizeOfHeap(void) { return (iCurrentSize - 1); } -}; - -#endif diff --git a/src/utils/ETools/DLink.h b/src/utils/ETools/DLink.h deleted file mode 100644 index 8cfc718699d..00000000000 --- a/src/utils/ETools/DLink.h +++ /dev/null @@ -1,256 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -// Some standard useful classes, templates, etc. - -#ifndef DLinkH -#define DLinkH - -// Defines a link -#define DlinkDefine(classname, linkname)\ - classname* linkname##pNextItem;\ - classname* linkname##pPrevItem - -// Defines the class methods for the link. -#define DlinkMethods(classname, linkname)\ - void linkname##Init(void)\ - {\ - linkname##pNextItem = NULL;\ - linkname##pPrevItem = NULL;\ - }\ - \ - /* Find the next in the list. */\ - classname* linkname##Next(void)\ - {\ - VERIFY((linkname##pPrevItem == NULL) || (linkname##pPrevItem->linkname##pNextItem == this));\ - VERIFY((linkname##pNextItem == NULL) || (linkname##pNextItem->linkname##pPrevItem == this));\ - return linkname##pNextItem;\ - }\ - \ - /* Find the previous in the list. */\ - classname* linkname##Prev(void)\ - {\ - VERIFY((linkname##pPrevItem == NULL) || (linkname##pPrevItem->linkname##pNextItem == this));\ - VERIFY((linkname##pNextItem == NULL) || (linkname##pNextItem->linkname##pPrevItem == this));\ - return linkname##pPrevItem;\ - }\ - \ - /* Remove this item from the list. */\ - /* Returns the next item. */\ - classname* linkname##Del(void)\ - {\ - classname* pNext = linkname##pNextItem;\ - classname* pPrev = linkname##pPrevItem;\ - VERIFY((pPrev == NULL) || (pPrev->linkname##pNextItem == this));\ - VERIFY((pNext == NULL) || (pNext->linkname##pPrevItem == this));\ - if (pPrev != NULL)\ - {\ - pPrev->linkname##pNextItem = pNext;\ - }\ - if (pNext != NULL)\ - {\ - pNext->linkname##pPrevItem = pPrev;\ - }\ - linkname##pNextItem = NULL;\ - linkname##pPrevItem = NULL;\ - return pNext;\ - }\ - \ - /* Remove this item from the list. */\ - /* Assumes that this is the first item in the list for speed (asserted). */\ - /* Returns the next item. */\ - classname* linkname##DelScan(void)\ - {\ - VERIFY(linkname##pPrevItem == NULL);\ - classname* pNext = linkname##pNextItem;\ - VERIFY((pNext == NULL) || (pNext->linkname##pPrevItem == this));\ - if (pNext != NULL)\ - {\ - pNext->linkname##pPrevItem = NULL;\ - }\ - linkname##pNextItem = NULL;\ - linkname##pPrevItem = NULL;\ - return pNext;\ - }\ - \ - /* Deletes the item, given a pointer to the first item in the list. */\ - /* Modifies the point as necessary. */\ - /* Returns the next item. */\ - /* Use like pThing->DelFromFirst ( &pFirst ); */\ - classname* linkname##DelFromFirst(classname** ppFirst)\ - {\ - VERIFY(ppFirst != NULL);\ - VERIFY(*ppFirst != NULL);\ - if (*ppFirst == this)\ - {\ - VERIFY(linkname##pPrevItem == NULL);\ - /* First in the list. */\ - *ppFirst = linkname##Del();\ - return *ppFirst;\ - }\ - else\ - {\ - /* DLink lists already know their previous item. */\ - return (linkname##Del());\ - }\ - }\ - \ - /* Add the item after the given item. */\ - /* Return the new next item. */\ - classname* linkname##AddAfter(classname* pPrev)\ - {\ - VERIFY(linkname##pNextItem == NULL);\ - VERIFY(linkname##pPrevItem == NULL);\ - VERIFY(pPrev != NULL);\ - linkname##pNextItem = pPrev->linkname##pNextItem;\ - linkname##pPrevItem = pPrev;\ - if (linkname##pNextItem != NULL)\ - {\ - linkname##pNextItem->linkname##pPrevItem = this;\ - }\ - pPrev->linkname##pNextItem = this;\ - return (linkname##pNextItem);\ - }\ - \ - /* Add the item after the given item. */\ - /* Assumes this is the last item in the list for speed (asserted) */\ - void linkname##AddAfterEnd(classname* pPrev)\ - {\ - VERIFY(linkname##pNextItem == NULL);\ - VERIFY(linkname##pPrevItem == NULL);\ - VERIFY(pPrev != NULL);\ - VERIFY(pPrev->linkname##pNextItem == NULL);\ - linkname##pNextItem = NULL;\ - linkname##pPrevItem = pPrev;\ - pPrev->linkname##pNextItem = this;\ - }\ - \ - /* Add before given item. */\ - /* Returns the new previous item. */\ - classname* linkname##AddBefore(classname* pNext)\ - {\ - VERIFY(linkname##pNextItem == NULL);\ - VERIFY(linkname##pPrevItem == NULL);\ - VERIFY(pNext != NULL);\ - linkname##pNextItem = pNext;\ - linkname##pPrevItem = pNext->linkname##pPrevItem;\ - if (linkname##pPrevItem != NULL)\ - {\ - linkname##pPrevItem->linkname##pNextItem = this;\ - }\ - pNext->linkname##pPrevItem = this;\ - return (linkname##pPrevItem);\ - }\ - \ - /* Add the item before the given item. */\ - /* Assumes this is the first item in the list for speed (asserted) */\ - void linkname##AddBeforeStart(classname* pNext)\ - {\ - VERIFY(linkname##pNextItem == NULL);\ - VERIFY(linkname##pPrevItem == NULL);\ - VERIFY(pNext != NULL);\ - VERIFY(pNext->linkname##pPrevItem == NULL);\ - linkname##pPrevItem = NULL;\ - linkname##pNextItem = pNext;\ - pNext->linkname##pPrevItem = this;\ - }\ - \ - /* Find the last item in the list. */\ - classname* linkname##FindLast(void)\ - {\ - classname* pCurr = this;\ - VERIFY(pCurr != NULL);\ - while (pCurr->linkname##pNextItem != NULL)\ - {\ - VERIFY(\ - (pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY(\ - (pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - pCurr = pCurr->linkname##pNextItem;\ - }\ - return pCurr;\ - }\ - \ - /* Find the first item in the list. */\ - classname* linkname##FindFirst(void)\ - {\ - classname* pCurr = this;\ - VERIFY(pCurr != NULL);\ - while (pCurr->linkname##pPrevItem != NULL)\ - {\ - VERIFY(\ - (pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY(\ - (pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - pCurr = pCurr->linkname##pPrevItem;\ - }\ - return pCurr;\ - }\ - \ - /* Consistency check - checks the current list is sound. */\ - void linkname##ConsistencyCheck(void)\ - {\ - classname* pCurr = this;\ - /* Scan backwards. */\ - VERIFY(pCurr != NULL);\ - while (pCurr->linkname##pPrevItem != NULL)\ - {\ - VERIFY(\ - (pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY(\ - (pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - pCurr = pCurr->linkname##pPrevItem;\ - }\ - VERIFY((pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY((pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - \ - /* Scan forwards. */\ - pCurr = this;\ - VERIFY(pCurr != NULL);\ - while (pCurr->linkname##pNextItem != NULL)\ - {\ - VERIFY(\ - (pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY(\ - (pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - pCurr = pCurr->linkname##pNextItem;\ - }\ - VERIFY((pCurr->linkname##pPrevItem == NULL) || (pCurr->linkname##pPrevItem->linkname##pNextItem == pCurr));\ - VERIFY((pCurr->linkname##pNextItem == NULL) || (pCurr->linkname##pNextItem->linkname##pPrevItem == pCurr));\ - }\ - \ - /* Adds the item to the end of this list */\ - void linkname##AddToEnd(classname* pItem)\ - {\ - VERIFY(pItem != NULL);\ - linkname##AddAfterEnd(pItem->linkname##FindLast());\ - }\ - \ - /* Adds the item the the start of this list */\ - void linkname##AddToStart(classname* pItem)\ - {\ - VERIFY(pItem != NULL);\ - linkname##AddBeforeStart(pItem->linkname##FindFirst());\ - }\ - \ - /* Check that all the pointer are NULL, ready to be deleted */\ - bool linkname##CheckNull(void) { return ((linkname##pNextItem == NULL) && (linkname##pPrevItem == NULL)); }\ - /* Calls delete() on all the objects in this list and deletes it */\ - void linkname##DelWholeList(void)\ - {\ - classname* pCur = linkname##FindFirst();\ - while (pCur != NULL)\ - {\ - classname* pNext = pCur->linkname##DelScan();\ - xr_delete(pCur);\ - pCur = pNext;\ - }\ - } - -#endif //#ifndef DLinkH diff --git a/src/utils/ETools/ETools.cpp b/src/utils/ETools/ETools.cpp deleted file mode 100644 index 3cc7cda7247..00000000000 --- a/src/utils/ETools/ETools.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" - -#include "ETools.h" - -#pragma warning(disable : 4267) - -BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - //xrDebug::Initialize(); - //Core.Initialize("XRayEditorTools", 0, FALSE); - // FPU::m64r (); - break; - case DLL_THREAD_ATTACH: break; - case DLL_THREAD_DETACH: break; - case DLL_PROCESS_DETACH: break;//Core._destroy(); break; - } - return TRUE; -} diff --git a/src/utils/ETools/ETools.h b/src/utils/ETools/ETools.h deleted file mode 100644 index a3643015fac..00000000000 --- a/src/utils/ETools/ETools.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#ifdef ETOOLS_EXPORTS -#define ETOOLS_API XR_EXPORT -#else -#define ETOOLS_API XR_IMPORT -#endif diff --git a/src/utils/ETools/ETools.vcxproj b/src/utils/ETools/ETools.vcxproj deleted file mode 100644 index a1713c1f3ad..00000000000 --- a/src/utils/ETools/ETools.vcxproj +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - {65CBB9D0-FBC6-41A4-8316-F5E9B5D7FB33} - - - - - - - DynamicLibrary - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - $(SolutionDir)utils\xrQSlim;$(xrExternals)libvorbis\include;$(xrExternals)libogg\include;$(xrExternals)libtheora\include;%(AdditionalIncludeDirectories) - ETOOLS_EXPORTS;%(PreprocessorDefinitions) - false - - - - - - - - - Create - - - - - - - - - - - - - - - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {15cbfeff-7965-41f5-b4e2-21e8795c9159} - - - {cebde98b-a6aa-46e6-bc79-faaf823db9ec} - - - {3a214e06-b95e-4d61-a291-1f8df2ec10fd} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - {f1836ce2-59ef-4189-8b9c-d103a511cb27} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/ETools/ETools.vcxproj.filters b/src/utils/ETools/ETools.vcxproj.filters deleted file mode 100644 index eba73561b30..00000000000 --- a/src/utils/ETools/ETools.vcxproj.filters +++ /dev/null @@ -1,66 +0,0 @@ - - - - - {5971a7af-f959-4dcb-b12f-ae50be148628} - - - {96a453df-ab9f-4279-8271-900670d15bbb} - - - - - Kernel - - - Kernel - - - VIPM - - - VIPM - - - VIPM - - - - - Kernel - - - Kernel - - - VIPM - - - VIPM - - - VIPM - - - VIPM - - - VIPM - - - VIPM - - - VIPM - - - VIPM - - - - - - - - - \ No newline at end of file diff --git a/src/utils/ETools/PropSlimTools.cpp b/src/utils/ETools/PropSlimTools.cpp deleted file mode 100644 index a003706a1b7..00000000000 --- a/src/utils/ETools/PropSlimTools.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include "stdafx.h" - -#include "PropSlimTools.h" - -#include "object.h" -#include "object_sliding.h" - -#pragma warning(disable : 4018) - -static Object* g_pObject = 0; -static ArbitraryList g_ppTempPts = 0; -static float g_fSlidingWindowErrorTolerance = 0.1f; -static BOOL g_bOptimiseVertexOrder = FALSE; -static u32 g_bMaxSlidingWindow = u32(-1); -static VIPM_Result* g_pResult = 0; - -ETOOLS_API void VIPM_Init() -{ - //. OutputDebugString("VIPM_INIT-------------------\n"); - R_ASSERT2(0 == g_pObject, "VIPM already in use!"); - g_pObject = xr_new(); - g_pResult = xr_new(); - g_pObject->iNumCollapses = 0; - g_pObject->iCurSlidingWindowLevel = 0; -} - -ETOOLS_API void VIPM_AppendVertex(const Fvector3& p, const Fvector2& uv) -{ - MeshPt* pt = xr_new(&g_pObject->CurPtRoot); - g_ppTempPts.push_back(pt); - pt->mypt.vPos = p; - pt->mypt.fU = uv.x; - pt->mypt.fV = uv.y; - pt->mypt.dwIndex = g_ppTempPts.size() - 1; -} - -ETOOLS_API void VIPM_AppendFace(u16 v0, u16 v1, u16 v2) -{ - xr_new(g_ppTempPts[v0], g_ppTempPts[v1], g_ppTempPts[v2], &g_pObject->CurTriRoot, &g_pObject->CurEdgeRoot); -} - -void CalculateAllCollapses( - Object* m_pObject, u32 max_sliding_window = u32(-1), float m_fSlidingWindowErrorTolerance = 1.f) -{ - m_pObject->BinEdgeCollapse(); - while (true) - { - // Find the best collapse you can. - // (how expensive is this? Ohhhh yes). - float fBestError = 1.0e10f; - MeshEdge* pedgeBestError = NULL; - MeshPt* pptBestError = NULL; - // NL = NewLevel - would force a new level. - float fBestErrorNL = 1.0e10f; - MeshEdge* pedgeBestErrorNL = NULL; - MeshPt* pptBestErrorNL = NULL; - MeshPt* ppt; - MeshEdge* pedge; - - float fAverage = 0.0f; - int iAvCount = 0; - - // Flush the cache, just in case. - m_pObject->FindCollapseError(NULL, NULL, FALSE); - - for (ppt = m_pObject->CurPtRoot.ListNext(); ppt != NULL; ppt = ppt->ListNext()) - { - if (0 == ppt->FirstEdge()) - continue; - // Disallow any pts that are on an edge - shouldn't be collapsing them. - BOOL bAllowed = TRUE; - for (pedge = ppt->FirstEdge(); pedge != NULL; pedge = ppt->NextEdge()) - { - if ((pedge->pTri12 == NULL) || (pedge->pTri21 == NULL)) - { - // This edge does not have two tris on it - disallow it. - bAllowed = FALSE; - break; - } - } - if (!bAllowed) - continue; - - BOOL bRequiresNewLevel = FALSE; - if (!m_pObject->CollapseAllowedForLevel(ppt, m_pObject->iCurSlidingWindowLevel)) - { - // This collapse would force a new level. - bRequiresNewLevel = TRUE; - } - - // collect error - for (pedge = ppt->FirstEdge(); pedge != NULL; pedge = ppt->NextEdge()) - { - float fErrorBin = m_pObject->FindCollapseError(ppt, pedge, TRUE); - iAvCount++; - fAverage += fErrorBin; - if (bRequiresNewLevel) - { - if (fBestErrorNL > fErrorBin) - { - fBestErrorNL = fErrorBin; - pedgeBestErrorNL = pedge; - pptBestErrorNL = ppt; - } - } - else - { - if (fBestError > fErrorBin) - { - fBestError = fErrorBin; - pedgeBestError = pedge; - pptBestError = ppt; - } - } - } - } - fAverage /= (float)iAvCount; - - // Tweak up the NewLevel errors by a factor. - if (fBestError > (fBestErrorNL + fAverage * m_fSlidingWindowErrorTolerance)) - { - // Despite the boost, it's still the best, - // so bite the bullet and do the collapse. - fBestError = fBestErrorNL; - pedgeBestError = pedgeBestErrorNL; - pptBestError = pptBestErrorNL; - } - - //----------------------------------------------------------------------------------------------------------- - // Do we need to do any collapses? - // Collapse auto-found edge. - if ((pedgeBestError != NULL) && (pptBestError != NULL)) - { - MeshPt* pKeptPt = pedgeBestError->OtherPt(pptBestError); - VERIFY(pKeptPt != NULL); - m_pObject->CreateEdgeCollapse(pptBestError, pKeptPt); - } - else - { - break; - } - - // max sliding window - if (m_pObject->iCurSlidingWindowLevel > max_sliding_window) - break; - } -} - -ETOOLS_API VIPM_Result* VIPM_Convert(u32 max_sliding_window, float error_tolerance, u32 optimize_vertex_order) -{ - g_pObject->Initialize(); - if (!g_pObject->Valid()) - return NULL; - CalculateAllCollapses(g_pObject, max_sliding_window, error_tolerance); - if (CalculateSW(g_pObject, g_pResult, optimize_vertex_order)) - return g_pResult; - else - return NULL; -} - -ETOOLS_API void VIPM_Destroy() -{ - //. OutputDebugString ("VIPM_DESTROY-------------------\n"); - xr_delete(g_pResult); - xr_delete(g_pObject); - g_ppTempPts.resize(0); -} diff --git a/src/utils/ETools/PropSlimTools.h b/src/utils/ETools/PropSlimTools.h deleted file mode 100644 index b9e143b101b..00000000000 --- a/src/utils/ETools/PropSlimTools.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "ETools.h" - -#include "ArbitraryList.h" - -#pragma pack(push, 1) -struct VIPM_SWR -{ - u32 offset; // Offset of the first index in the index buffer to start at (note! no retrictions. Can easily be >64k) - u16 num_tris; // Number of tris to render (most cards can't do more than 65536) - u16 num_verts; // Number of vertices to render with (using WORD indices) -}; -#pragma pack(pop) - -struct VIPM_Result -{ - ArbitraryList permute_verts; - ArbitraryList swr_records; // The records of the collapses. - ArbitraryList indices; - ~VIPM_Result() - { - permute_verts.resize(0); - swr_records.resize(0); - indices.resize(0); - } -}; - -extern "C" { -ETOOLS_API void VIPM_Init(); -ETOOLS_API void VIPM_AppendVertex(const Fvector3& pt, const Fvector2& uv); -ETOOLS_API void VIPM_AppendFace(u16 v0, u16 v1, u16 v2); -ETOOLS_API VIPM_Result* VIPM_Convert( - u32 max_sliding_window = u32(-1), float error_tolerance = 0.1f, u32 optimize_vertex_order = 1); -ETOOLS_API void VIPM_Destroy(); -}; - diff --git a/src/utils/ETools/StdAfx.cpp b/src/utils/ETools/StdAfx.cpp deleted file mode 100644 index cf524364f72..00000000000 --- a/src/utils/ETools/StdAfx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" diff --git a/src/utils/ETools/StdAfx.h b/src/utils/ETools/StdAfx.h deleted file mode 100644 index f2b4782d44a..00000000000 --- a/src/utils/ETools/StdAfx.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#define ENGINE_API -#define NO_XRC_STATS - -#include "Common/Common.hpp" -#include "xrCore/xrCore.h" -#include "xrCore/_std_extensions.h" - -#pragma warning(push) -#pragma warning(disable : 4995) -#include "d3dx9.h" -#pragma warning(pop) - -// Warnings -#pragma warning(disable : 4786) // too long names -#pragma warning(disable : 4503) // decorated name length exceeded -#pragma warning(disable : 4251) // object needs DLL interface diff --git a/src/utils/ETools/mesh.h b/src/utils/ETools/mesh.h deleted file mode 100644 index e5b48e58a60..00000000000 --- a/src/utils/ETools/mesh.h +++ /dev/null @@ -1,1746 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -// Helper routines for manipulating large complex meshes. -// Pretty memory-hungry, but good for cross-referencing between -// edges, points and triangles. - -//.#include "tomslib.h" -#include "dlink.h" -#include "arbitrarylist.h" - -// Before including this file, #define the following: -// -// MESHPT_APP_DEFINED -// MESHTRI_APP_DEFINED -// MESHEDGE_APP_DEFINED -// -// These declarations are included in the declarations of the relevant -// classes. They may be defined to be nothing of course. -// -// For efficiency, also define some of the following according to use: -// -// MESHCTRL_EDGES_ALWAYS_ADDED_BEFORE_TRIS: -// Set to 1 to enforce/assume that when adding a tri, all three edges -// will exist. So all tris must have all three edge entries filled. -// This is a speedup, and an error check, if that's what your app does. -// The exception is if autocreation of edges is done for the MeshTri creator. -// Similarly, before deleteing edges, make sure you have deleted all the -// tris that use them -// MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_TRIS: -// Ditto, but for pts. -// MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_EDGES: -// Ditto, but pts must be added before edges are created. - -class MeshPt; -class MeshEdge; -class MeshTri; - -class MeshTri -{ - friend class MeshPt; - friend class MeshEdge; - -private: - DlinkDefine(MeshTri, List); - u32 dwListId; // For use when doing consistency checks. - - void InternalDelete(BOOL bBinUnusedEdges); - -public: - MeshPt* pPt1; // Points. - MeshPt* pPt2; - MeshPt* pPt3; - MeshEdge* pEdge12; // Edges between point numbers. - MeshEdge* pEdge23; - MeshEdge* pEdge31; - - DlinkMethods(MeshTri, List); - - MESHTRI_APP_DEFINED // App-defined data. - - MeshTri(void); - // Set pEdgeListRoot to non-NULL to autocreate edges. - MeshTri( - MeshPt* pNewPt1, MeshPt* pNewPt2, MeshPt* pNewPt3, MeshTri* pListRoot = NULL, MeshEdge* pEdgeListRoot = NULL); - ~MeshTri(void); - // Set bBinUnusedEdges to TRUE to autodestroy edges. - void Delete(BOOL bBinUnusedEdges = FALSE); - // Which list is this tri in? - MeshTri* QueryList(void); - // Move this tri to this list. - void SetList(MeshTri* pListRoot); - // Checks that all edges and pts refer back to this tri, - // and that they're in the respective lists. - // If the lists are NULL, the check is not made. - bool ConsistencyCheck(MeshPt* pPtRoot = NULL, MeshEdge* pEdgeRoot = NULL, MeshTri* pTriRoot = NULL); - -protected: - // Add the edge to this tri. - void AddEdge(MeshEdge* pEdge); - // Remove the edge from this tri. - void RemoveEdge(MeshEdge* pEdge); - -protected: - // Remove the point from this tri. - // NOTE! This is probably not a good thing to do. - void RemovePt(MeshPt* pPt); - -public: - IC bool Equal(MeshTri* F) - { - // Test for 6 variations - if ((pPt1 == F->pPt1) && (pPt2 == F->pPt2) && (pPt3 == F->pPt3)) - return true; - if ((pPt1 == F->pPt1) && (pPt3 == F->pPt2) && (pPt2 == F->pPt3)) - return true; - if ((pPt3 == F->pPt1) && (pPt1 == F->pPt2) && (pPt2 == F->pPt3)) - return true; - if ((pPt3 == F->pPt1) && (pPt2 == F->pPt2) && (pPt1 == F->pPt3)) - return true; - if ((pPt2 == F->pPt1) && (pPt1 == F->pPt2) && (pPt3 == F->pPt3)) - return true; - if ((pPt2 == F->pPt1) && (pPt3 == F->pPt2) && (pPt1 == F->pPt3)) - return true; - return false; - } -}; - -class MeshEdge -{ - friend class MeshPt; - friend class MeshTri; - -private: - DlinkDefine(MeshEdge, List); - u32 dwListId; // For use when doing consistency checks. - -public: - MeshPt* pPt1; - MeshPt* pPt2; - MeshTri* pTri12; // Tri that numbers pt1, pt2 in that order. - MeshTri* pTri21; // Tri that numbers pt2, pt1 in that order. - - MeshEdge* pEdgeProx; // The edge that this is close to, if any. - - DlinkMethods(MeshEdge, List); - - MESHEDGE_APP_DEFINED // App-defined data. - - // BINARY_HEAP_VARS(); // Helper stuff. - - MeshEdge(void); - MeshEdge(MeshPt* pNewPt1, MeshPt* pNewPt2, MeshEdge* pListRoot = NULL); - ~MeshEdge(void); - // Find the other triangle that uses this edge. - MeshTri* OtherTri(MeshTri* pTri); - // Find the other point that uses this edge. - MeshPt* OtherPt(MeshPt* pPt); - // Try to merge these two edges. Result is TRUE if it succeeded - note that the other edge will be NOT deleted. - bool bTryToMergeEdges(MeshEdge* pedge); - // Which list is this Edge in? - MeshEdge* QueryList(void); - // Move this Edge to this list. - void SetList(MeshEdge* pListRoot); - // Makes these two edges prox. - // The point prox data must agree. - // Returns TRUE on success, or FALSE if it failed. - bool AddProx(MeshEdge* pEdge); - // Find the proximity edge, if any. - // Relies on the point proximity values having been set up. - // If one is found, it is returned. - MeshEdge* DoProxMatch(void); - // Removes any edge prox data. - // Returns TRUE if there was some. - // The pt prox data can still agree - it is not touched. - bool RemoveProx(void); - // Checks that all pts and tris refer back to this edge, - // and that they're in the respective lists. - // If the lists are NULL, the check is not made. - bool ConsistencyCheck(MeshPt* pPtRoot = NULL, MeshEdge* pEdgeRoot = NULL, MeshTri* pTriRoot = NULL); - -protected: - // Remove the tri from this edge. - void RemoveTri(MeshTri* pTri); - // Add the tri to this edge. - void AddTri(MeshTri* pTri); - -protected: - // Remove the pt from this edge. - // NOTE! This is probably not a good thing to do. - void RemovePt(MeshPt* pPt); -}; - -class MeshPt -{ - friend class MeshEdge; - friend class MeshTri; - -private: - ArbitraryList EdgeList; // The list of edges that use this point (in no order). - ArbitraryList TriList; // The list of tris that use this point (in no order). - ArbitraryList ProxPtList; // The list of prox pts (in no order). - - int iCurTriNum; // Used with First/NextTri. - int iCurEdgeNum; // Used with First/NextEdge. - int iCurProxNum; // Used with First/NextProx. - - DlinkDefine(MeshPt, List); - u32 dwListId; // For use when doing consistency checks. - -public: - MESHPT_APP_DEFINED // App-defined data. - - DlinkMethods(MeshPt, List); - - MeshPt(MeshPt* pListRoot = NULL); - ~MeshPt(void); - // Find the edge that uses this pt and the other one given. - // NOTE! You almost never want to use this - almost always, - // use FindTriEdge, because edges are typically created on-demand - // when creating tris, and using this rout means that no two - // points can have more than two tris use them, which lots of models - // violate. - MeshEdge* FindEdge(MeshPt* pPt); - // Find the first edge that uses this pt and the other given, and - // also has a free triangle entry, assuming that the points are - // used in that clockwise order. This allows two edges that share - // the same points to exist, e.g. where multiple triangles share - // the same edge (think of the diagonal of the tris of a back-to-back - // quad - same edge, four tris. - // The tri will use the points in the order *this,*pPt. - MeshEdge* FindTriEdge(MeshPt* pPt); - // Find the tri that uses this pt and the other two given. - // They must be in the order this,pPt1,pPt2 - not the other way round. - MeshTri* FindTri(MeshPt* pPt1, MeshPt* pPt2); - - // Retired - there may be several tris like this - call FirstTri/NextTri. - // Return the first tri in the list. MUST be called before calling NextTri(). - // If a non-NULL pPt is supplied, only tris using this,pPt in that order - // are returned, otherwise all tris are returned. - MeshTri* FirstTri(MeshPt* pPt = NULL); - // Return the next tri in the list. - // If a non-NULL pPt is supplied, only tris using this,pPt in that order - // are returned, otherwise all tris are returned. - MeshTri* NextTri(MeshPt* pPt = NULL); - // Terminate the current First/Next loop. - // No need to call this if NULL was returned from NextTri(). - void EndTri(void); - - // Return the first Edge in the list. MUST be called before calling NextEdge(). - // If a non-NULL pPt is supplied, only edges using this and pPt - // are returned, otherwise all edges are returned. - MeshEdge* FirstEdge(MeshPt* pPt = NULL); - // Return the next Edge in the list. - // If a non-NULL pPt is supplied, only edges using this and pPt - // are returned, otherwise all edges are returned. - MeshEdge* NextEdge(MeshPt* pPt = NULL); - // Terminate the current First/Next loop. - // No need to call this if NULL was returned from NextEdge(). - void EndEdge(void); - - // Add the given pt to the prox list (and vice versa). - // If the pt was not already there, returns TRUE; - // If bProxEdges is set to TRUE (default is FALSE ), - // the edges that these two pts use are made prox if possible. - bool AddProx(MeshPt* pPt, bool bProxEdges = FALSE); - // Remove the given pt from the prox list (and vice versa). - // If the pt was there, returns TRUE. - bool RemoveProx(MeshPt* pPt); - // Returns TRUE if the two pts are marked as being in proximity. - bool CheckProx(MeshPt* pPt); - // Return the first prox pt. MUST be called before calling NextProx(). - MeshPt* FirstProx(void); - // Return the next prox pt. - MeshPt* NextProx(void); - // Terminate the current First/Next loop. - // No need to call this if NULL was returned from NextProx(). - void EndProx(void); - - // Which list is this Pt in? - MeshPt* QueryList(void); - // Move this Pt to this list. - void SetList(MeshPt* pListRoot); - // Checks that all edges and tris refer back to this pt, - // and that they're in the respective lists. - // If the lists are NULL, the check is not made. - bool ConsistencyCheck(MeshPt* pPtRoot = NULL, MeshEdge* pEdgeRoot = NULL, MeshTri* pTriRoot = NULL); - -protected: - // Remove the edge from this point. - void RemoveEdge(MeshEdge* pEdge); - // Add the edge to this point. - void AddEdge(MeshEdge* pEdge); - -protected: - // Remove the tri from this point. - void RemoveTri(MeshTri* pTri); - // Add the tri to this point. - void AddTri(MeshTri* pTri); -}; - -inline MeshTri::MeshTri(void) -{ - // Should only be used for list roots. - pPt1 = NULL; - pPt2 = NULL; - pPt3 = NULL; - pEdge12 = NULL; - pEdge23 = NULL; - pEdge31 = NULL; - ListInit(); -} - -inline MeshTri::MeshTri(MeshPt* pNewPt1, MeshPt* pNewPt2, MeshPt* pNewPt3, MeshTri* pListRoot, MeshEdge* pEdgeListRoot) -{ - VERIFY(pNewPt1 != NULL); - VERIFY(pNewPt2 != NULL); - VERIFY(pNewPt3 != NULL); - pPt1 = pNewPt1; - pPt2 = pNewPt2; - pPt3 = pNewPt3; - pEdge12 = NULL; - pEdge23 = NULL; - pEdge31 = NULL; - - pPt1->AddTri(this); - pPt2->AddTri(this); - pPt3->AddTri(this); - - pEdge12 = pPt1->FindTriEdge(pPt2); - if ((pEdge12 == NULL) && (pEdgeListRoot != NULL)) - { - // Autocreate the edge. - pEdge12 = xr_new(pPt1, pPt2, pEdgeListRoot); - } - VERIFY(pEdge12 != NULL); - { - pEdge12->AddTri(this); - } - - pEdge23 = pPt2->FindTriEdge(pPt3); - if ((pEdge23 == NULL) && (pEdgeListRoot != NULL)) - { - // Autocreate the edge. - pEdge23 = xr_new(pPt2, pPt3, pEdgeListRoot); - } - VERIFY(pEdge23 != NULL); - { - pEdge23->AddTri(this); - } - - pEdge31 = pPt3->FindTriEdge(pPt1); - if ((pEdge31 == NULL) && (pEdgeListRoot != NULL)) - { - // Autocreate the edge. - pEdge31 = xr_new(pPt3, pPt1, pEdgeListRoot); - } - VERIFY(pEdge31 != NULL); - { - pEdge31->AddTri(this); - } - - ListInit(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -inline void MeshTri::InternalDelete(BOOL bBinUnusedEdges) -{ - // Remove edge references. - if (pEdge12 != NULL) - { - pEdge12->RemoveTri(this); - if (bBinUnusedEdges && (pEdge12->pTri12 == NULL) && (pEdge12->pTri21 == NULL)) - { - // This edge is no longer in use. - xr_delete(pEdge12); - } - pEdge12 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - if (pEdge23 != NULL) - { - pEdge23->RemoveTri(this); - if (bBinUnusedEdges && (pEdge23->pTri12 == NULL) && (pEdge23->pTri21 == NULL)) - { - // This edge is no longer in use. - xr_delete(pEdge23); - } - pEdge23 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - if (pEdge31 != NULL) - { - pEdge31->RemoveTri(this); - if (bBinUnusedEdges && (pEdge31->pTri12 == NULL) && (pEdge31->pTri21 == NULL)) - { - // This edge is no longer in use. - xr_delete(pEdge31); - } - pEdge31 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - // Remove point references. - if (pPt1 != NULL) - { - pPt1->RemoveTri(this); - pPt1 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - if (pPt2 != NULL) - { - pPt2->RemoveTri(this); - pPt2 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - if (pPt3 != NULL) - { - pPt3->RemoveTri(this); - pPt3 = NULL; - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pEdge12 == NULL); - VERIFY(pEdge23 == NULL); - VERIFY(pEdge31 == NULL); - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pPt3 == NULL); - } - - ListDel(); -} - -inline MeshTri::~MeshTri(void) { InternalDelete(FALSE); } -inline void MeshTri::Delete(BOOL bBinUnusedEdges /*= FALSE*/) -{ - InternalDelete(bBinUnusedEdges); - MeshTri* tri = (MeshTri*)this; - xr_delete(tri); -} - -inline void MeshTri::AddEdge(MeshEdge* pEdge) -{ - // Can't mess with a tri's edges once created. - VERIFY(FALSE); -} - -inline void MeshTri::RemoveEdge(MeshEdge* pEdge) -{ - VERIFY(pEdge != NULL); - if (pEdge12 == pEdge) - { - pEdge12 = NULL; - } - else if (pEdge23 == pEdge) - { - pEdge23 = NULL; - } - else - { - VERIFY(pEdge31 == pEdge); - pEdge31 = NULL; - } -} - -inline void MeshTri::RemovePt(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - if (pPt1 == pPt) - { - pPt1 = NULL; - } - else if (pPt2 == pPt) - { - pPt2 = NULL; - } - else - { - VERIFY(pPt3 == pPt); - pPt3 = NULL; - } -} - -inline MeshTri* MeshTri::QueryList(void) -{ - MeshTri* pListRoot = ListFindFirst(); - if (pListRoot == this) - { - VERIFY(ListFindLast() == this); - pListRoot = NULL; - } - return (pListRoot); -} - -inline void MeshTri::SetList(MeshTri* pListRoot) -{ - ListDel(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -#define FAIL_CHECK()\ - bRes = FALSE;\ - VERIFY(FALSE) -inline bool MeshTri::ConsistencyCheck(MeshPt* pPtRoot, MeshEdge* pEdgeRoot, MeshTri* pTriRoot) -{ - bool bRes = TRUE; - if ((pTriRoot != NULL) && (QueryList() != pTriRoot)) - { - FAIL_CHECK(); - } - - if (pEdge12 != NULL) - { - if ((pEdgeRoot != NULL) && (pEdge12->QueryList() != pEdgeRoot)) - { - FAIL_CHECK(); - } - - if (pEdge12->pTri12 == this) - { - if ((pEdge12->pPt1 != pPt1) || (pEdge12->pPt2 != pPt2)) - { - FAIL_CHECK(); - } - } - else if (pEdge12->pTri21 == this) - { - if ((pEdge12->pPt1 != pPt2) || (pEdge12->pPt2 != pPt1)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - - if (pEdge23 != NULL) - { - if ((pEdgeRoot != NULL) && (pEdge23->QueryList() != pEdgeRoot)) - { - FAIL_CHECK(); - } - - if (pEdge23->pTri12 == this) - { - if ((pEdge23->pPt1 != pPt2) || (pEdge23->pPt2 != pPt3)) - { - FAIL_CHECK(); - } - } - else if (pEdge23->pTri21 == this) - { - if ((pEdge23->pPt1 != pPt3) || (pEdge23->pPt2 != pPt2)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - - if (pEdge31 != NULL) - { - if ((pEdgeRoot != NULL) && (pEdge31->QueryList() != pEdgeRoot)) - { - FAIL_CHECK(); - } - - if (pEdge31->pTri12 == this) - { - if ((pEdge31->pPt1 != pPt3) || (pEdge31->pPt2 != pPt1)) - { - FAIL_CHECK(); - } - } - else if (pEdge31->pTri21 == this) - { - if ((pEdge31->pPt1 != pPt1) || (pEdge31->pPt2 != pPt3)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - - if ((pPt1 == NULL) || (pPt2 == NULL) || (pPt3 == NULL)) - { - FAIL_CHECK(); - } - else - { - if (pPtRoot != NULL) - { - if (pPt1->QueryList() != pPtRoot) - { - FAIL_CHECK(); - } - if (pPt2->QueryList() != pPtRoot) - { - FAIL_CHECK(); - } - if (pPt3->QueryList() != pPtRoot) - { - FAIL_CHECK(); - } - } - } - - return (bRes); -} - -inline MeshEdge::MeshEdge(void) -{ - pPt1 = NULL; - pPt2 = NULL; - pTri12 = NULL; - pTri21 = NULL; - pEdgeProx = NULL; - ListInit(); -} - -inline MeshEdge::MeshEdge(MeshPt* pNewPt1, MeshPt* pNewPt2, MeshEdge* pListRoot) -{ - VERIFY(pNewPt1 != NULL); - VERIFY(pNewPt2 != NULL); - pPt1 = pNewPt1; - pPt2 = pNewPt2; - pTri12 = NULL; - pTri21 = NULL; - pEdgeProx = NULL; - - pPt1->AddEdge(this); - pPt2->AddEdge(this); - - ListInit(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -inline MeshEdge::~MeshEdge(void) -{ - RemoveProx(); - - if (pPt1 != NULL) - { - MeshPt* pPt = pPt1; - RemovePt(pPt); - pPt->RemoveEdge(this); - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pTri12 == NULL); - VERIFY(pTri21 == NULL); - } - - if (pPt2 != NULL) - { - MeshPt* pPt = pPt2; - RemovePt(pPt); - pPt->RemoveEdge(this); - } - else - { - // The only good reason is if this is a local var, - // in which case everything should be NULL. - VERIFY(pPt1 == NULL); - VERIFY(pPt2 == NULL); - VERIFY(pTri12 == NULL); - VERIFY(pTri21 == NULL); - } - - // Any tri should have been binned already - VERIFY(pTri12 == NULL); - VERIFY(pTri21 == NULL); - - ListDel(); -} - -// Remove this edge from the tri. -inline void MeshEdge::RemoveTri(MeshTri* pTri) -{ - VERIFY(pTri != NULL); - if (pTri12 == pTri) - { - pTri12 = NULL; - } - else - { - VERIFY(pTri21 == pTri); - pTri21 = NULL; - } -} - -// Remove this edge from the pt. -inline void MeshEdge::RemovePt(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - if (pPt1 == pPt) - { - pPt1 = NULL; - } - else - { - VERIFY(pPt2 == pPt); - pPt2 = NULL; - } -} - -inline void MeshEdge::AddTri(MeshTri* pTri) -{ - VERIFY(pTri != NULL); - // Assumes the tri's pt pointers have already been set up. - if (((pPt1 == pTri->pPt1) && (pPt2 == pTri->pPt2)) || ((pPt1 == pTri->pPt2) && (pPt2 == pTri->pPt3)) || - ((pPt1 == pTri->pPt3) && (pPt2 == pTri->pPt1))) - { - VERIFY(pTri12 == NULL); - pTri12 = pTri; - } - else - { - VERIFY(((pPt1 == pTri->pPt2) && (pPt2 == pTri->pPt1)) || ((pPt1 == pTri->pPt3) && (pPt2 == pTri->pPt2)) || - ((pPt1 == pTri->pPt1) && (pPt2 == pTri->pPt3))); - VERIFY(pTri21 == NULL); - pTri21 = pTri; - } -} - -// Returns the other triangle that uses this edge. -inline MeshTri* MeshEdge::OtherTri(MeshTri* pTri) -{ - VERIFY(pTri != NULL); - if (pTri == pTri12) - { - return (pTri21); - } - else - { - VERIFY(pTri == pTri21); - return (pTri12); - } -} - -inline MeshPt* MeshEdge::OtherPt(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - if (pPt == pPt1) - { - return (pPt2); - } - else - { - VERIFY(pPt == pPt2); - return (pPt1); - } -} - -// Try to merge these two edges. Result is TRUE if it succeeded - note that the other edge will be NOT deleted. -inline bool MeshEdge::bTryToMergeEdges(MeshEdge* pedge) -{ - VERIFY(pedge != this); - if (pPt1 == pedge->pPt1) - { - VERIFY(pPt2 == pedge->pPt2); - if ((pTri12 == NULL) && (pedge->pTri21 == NULL) && ((pEdgeProx == NULL) || (pedge->pEdgeProx == NULL))) - { - // Merge them. - pTri12 = pedge->pTri12; - if (pTri12 != NULL) - { - if (pTri12->pEdge12 == pedge) - { - pTri12->pEdge12 = this; - } - else if (pTri12->pEdge23 == pedge) - { - pTri12->pEdge23 = this; - } - else - { - VERIFY(pTri12->pEdge31 == pedge); - pTri12->pEdge31 = this; - } - } - pedge->pTri12 = NULL; - if (pedge->pEdgeProx != NULL) - { - VERIFY(pEdgeProx == NULL); - pEdgeProx = pedge->pEdgeProx; - VERIFY(pEdgeProx->pEdgeProx == pedge); - pEdgeProx->pEdgeProx = this; - pedge->pEdgeProx = NULL; - } - return TRUE; - } - else if ((pTri21 == NULL) && (pedge->pTri12 == NULL) && ((pEdgeProx == NULL) || (pedge->pEdgeProx == NULL))) - { - // Merge them. - pTri21 = pedge->pTri21; - if (pTri21 != NULL) - { - if (pTri21->pEdge12 == pedge) - { - pTri21->pEdge12 = this; - } - else if (pTri21->pEdge23 == pedge) - { - pTri21->pEdge23 = this; - } - else - { - VERIFY(pTri21->pEdge31 == pedge); - pTri21->pEdge31 = this; - } - } - pedge->pTri21 = NULL; - if (pedge->pEdgeProx != NULL) - { - VERIFY(pEdgeProx == NULL); - pEdgeProx = pedge->pEdgeProx; - VERIFY(pEdgeProx->pEdgeProx == pedge); - pEdgeProx->pEdgeProx = this; - pedge->pEdgeProx = NULL; - } - return TRUE; - } - else - { - // Nope - they don't match. - return (FALSE); - } - } - else - { - VERIFY(pPt1 == pedge->pPt2); - VERIFY(pPt2 == pedge->pPt1); - if ((pTri12 == NULL) && (pedge->pTri12 == NULL) && ((pEdgeProx == NULL) || (pedge->pEdgeProx == NULL))) - { - // Merge them. - pTri12 = pedge->pTri21; - if (pTri12 != NULL) - { - if (pTri12->pEdge12 == pedge) - { - pTri12->pEdge12 = this; - } - else if (pTri12->pEdge23 == pedge) - { - pTri12->pEdge23 = this; - } - else - { - VERIFY(pTri12->pEdge31 == pedge); - pTri12->pEdge31 = this; - } - } - pedge->pTri21 = NULL; - if (pedge->pEdgeProx != NULL) - { - VERIFY(pEdgeProx == NULL); - pEdgeProx = pedge->pEdgeProx; - VERIFY(pEdgeProx->pEdgeProx == pedge); - pEdgeProx->pEdgeProx = this; - pedge->pEdgeProx = NULL; - } - return TRUE; - } - else if ((pTri21 == NULL) && (pedge->pTri21 == NULL) && ((pEdgeProx == NULL) || (pedge->pEdgeProx == NULL))) - { - // Merge them. - pTri21 = pedge->pTri12; - if (pTri21 != NULL) - { - if (pTri21->pEdge12 == pedge) - { - pTri21->pEdge12 = this; - } - else if (pTri21->pEdge23 == pedge) - { - pTri21->pEdge23 = this; - } - else - { - VERIFY(pTri21->pEdge31 == pedge); - pTri21->pEdge31 = this; - } - } - pedge->pTri12 = NULL; - if (pedge->pEdgeProx != NULL) - { - VERIFY(pEdgeProx == NULL); - pEdgeProx = pedge->pEdgeProx; - VERIFY(pEdgeProx->pEdgeProx == pedge); - pEdgeProx->pEdgeProx = this; - pedge->pEdgeProx = NULL; - } - return TRUE; - } - else - { - // Nope - they don't match. - return (FALSE); - } - } -} - -inline MeshEdge* MeshEdge::QueryList(void) -{ - MeshEdge* pListRoot = ListFindFirst(); - if (pListRoot == this) - { - VERIFY(ListFindLast() == this); - pListRoot = NULL; - } - return (pListRoot); -} - -inline void MeshEdge::SetList(MeshEdge* pListRoot) -{ - ListDel(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -// Makes these two edges prox. -// The point prox data must agree. -// Returns TRUE on success, or FALSE if it failed. -inline bool MeshEdge::AddProx(MeshEdge* pEdge) -{ - VERIFY(pEdge != NULL); - if (pEdgeProx != NULL) - { - // Already got prox. - return (FALSE); - } - else if (pEdge->pEdgeProx != NULL) - { - // Already got prox. - return (FALSE); - } - else - { - // Check that the pts agree. - // Either pPt1<->pPt1 and pPt2<->pPt2, or the other way round. - if (pEdge->pPt1->CheckProx(pPt1)) - { - if (!pEdge->pPt2->CheckProx(pPt2)) - { - return (FALSE); - } - } - else if (pEdge->pPt1->CheckProx(pPt2)) - { - if (!pEdge->pPt2->CheckProx(pPt1)) - { - return (FALSE); - } - } - else - { - return (FALSE); - } - - // OK, must have passed. - pEdgeProx = pEdge; - pEdge->pEdgeProx = this; - return (TRUE); - } -} - -// Find the proximity edge, if any. -// Relies on the point proximity values having been set up. -// If one is found, it is returned. -inline MeshEdge* MeshEdge::DoProxMatch(void) -{ - // Loop through all the prox pts to pPt1 - // Loop through all their edges. - // If the other pt is prox to pPt2, then we found a prox edge. - u32 i; - MeshPt** ppPt = pPt1->ProxPtList.ptr(); - for (i = 0; i < pPt1->ProxPtList.size(); i++) - { - MeshPt* pPtProx = ppPt[i]; - VERIFY(pPtProx != NULL); - - MeshEdge* pEdgeOther = pPtProx->FirstEdge(); - while (pEdgeOther != NULL) - { - MeshPt* pPtOther = pEdgeOther->OtherPt(pPtProx); - if (pPtOther->CheckProx(pPt2)) - { - // Yes - this is prox. - bool bRes = AddProx(pEdgeOther); - if (bRes) - { - pPtProx->EndEdge(); - return pEdgeOther; - } - else - { - // Too many edges trying to be prox! - pPtProx->EndEdge(); - return NULL; - } - } - - pEdgeOther = pPtProx->NextEdge(); - } - } - return NULL; -} - -// Removes any edge prox data. -// Returns TRUE if there was some. -// The pt prox data can still agree - it is not touched. -inline bool MeshEdge::RemoveProx(void) -{ - if (pEdgeProx == NULL) - { - return (FALSE); - } - else - { - VERIFY(pEdgeProx->pEdgeProx == this); - pEdgeProx->pEdgeProx = NULL; - pEdgeProx = NULL; - return (TRUE); - } -} - -inline bool MeshEdge::ConsistencyCheck(MeshPt* pPtRoot, MeshEdge* pEdgeRoot, MeshTri* pTriRoot) -{ - bool bRes = TRUE; - if ((pEdgeRoot != NULL) && (QueryList() != pEdgeRoot)) - { - FAIL_CHECK(); - } - - if (pEdgeProx != NULL) - { - if (pEdgeProx->pEdgeProx != this) - { - FAIL_CHECK(); - } - if ((pEdgeRoot != NULL) && (pEdgeProx->QueryList() != pEdgeRoot)) - { - FAIL_CHECK(); - } - // Either pPt1<->pPt1 and pPt2<->pPt2, or the other way round. - if (pEdgeProx->pPt1->CheckProx(pPt1)) - { - if (!pEdgeProx->pPt2->CheckProx(pPt2)) - { - FAIL_CHECK(); - } - } - else if (pEdgeProx->pPt1->CheckProx(pPt2)) - { - if (!pEdgeProx->pPt2->CheckProx(pPt1)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - - if (pTri12 != NULL) - { - if ((pTriRoot != NULL) && (pTri12->QueryList() != pTriRoot)) - { - FAIL_CHECK(); - } - - if (pTri12->pEdge12 == this) - { - if ((pTri12->pPt1 != pPt1) || (pTri12->pPt2 != pPt2)) - { - FAIL_CHECK(); - } - } - else if (pTri12->pEdge23 == this) - { - if ((pTri12->pPt2 != pPt1) || (pTri12->pPt3 != pPt2)) - { - FAIL_CHECK(); - } - } - else if (pTri12->pEdge31 == this) - { - if ((pTri12->pPt3 != pPt1) || (pTri12->pPt1 != pPt2)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - - if (pTri21 != NULL) - { - if ((pTriRoot != NULL) && (pTri21->QueryList() != pTriRoot)) - { - FAIL_CHECK(); - } - - if (pTri21->pEdge12 == this) - { - if ((pTri21->pPt1 != pPt2) || (pTri21->pPt2 != pPt1)) - { - FAIL_CHECK(); - } - } - else if (pTri21->pEdge23 == this) - { - if ((pTri21->pPt2 != pPt2) || (pTri21->pPt3 != pPt1)) - { - FAIL_CHECK(); - } - } - else if (pTri21->pEdge31 == this) - { - if ((pTri21->pPt3 != pPt2) || (pTri21->pPt1 != pPt1)) - { - FAIL_CHECK(); - } - } - else - { - FAIL_CHECK(); - } - } - - if ((pPt1 == NULL) || (pPt2 == NULL)) - { - FAIL_CHECK(); - } - else - { - if (pPtRoot != NULL) - { - if (pPt1->QueryList() != pPtRoot) - { - FAIL_CHECK(); - } - if (pPt2->QueryList() != pPtRoot) - { - FAIL_CHECK(); - } - } - } - - return (bRes); -} - -inline MeshPt::MeshPt(MeshPt* pListRoot) -{ - iCurEdgeNum = -1; - iCurTriNum = -1; - iCurProxNum = -1; - - ListInit(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -inline MeshPt::~MeshPt(void) -{ - // Can't just do a simple loop - RemoveProx modifies the list. - while (ProxPtList.size() > 0) - { - bool bRes = RemoveProx(ProxPtList.ptr()[0]); - VERIFY(bRes); - } - - // Should not be any tris. - VERIFY(TriList.size() == 0); - - // Should not be any edges. - VERIFY(EdgeList.size() == 0); - - ListDel(); -} - -inline void MeshPt::RemoveEdge(MeshEdge* pEdge) -{ - VERIFY(pEdge != NULL); - MeshEdge** ppEdgeList = EdgeList.ptr(); - u32 i; - for (i = 0; i < EdgeList.size(); i++) - { - if (ppEdgeList[i] == pEdge) - { - break; - } - } - VERIFY(i < EdgeList.size()); - // Bin this entry. - EdgeList.erase_fast(i); -} - -inline void MeshPt::RemoveTri(MeshTri* pTri) -{ - VERIFY(pTri != NULL); - MeshTri** ppTriList = TriList.ptr(); - u32 i; - for (i = 0; i < TriList.size(); i++) - { - if (ppTriList[i] == pTri) - { - break; - } - } - VERIFY(i < TriList.size()); - // Bin this entry with the last entry. - TriList.erase_fast(i); -} - -inline void MeshPt::AddTri(MeshTri* pTri) -{ - VERIFY(pTri != NULL); -#ifdef DEBUG - // Make sure this hasn't been added already. - MeshTri** ppTriList = TriList.ptr(); - u32 i; - for (i = 0; i < TriList.size(); i++) - { - VERIFY(ppTriList[i] != NULL); - VERIFY(ppTriList[i] != pTri); - } -#endif - *(TriList.append()) = pTri; -} - -inline void MeshPt::AddEdge(MeshEdge* pEdge) -{ - VERIFY(pEdge != NULL); -#ifdef DEBUG - // Make sure this hasn't been added already. - u32 i; - MeshEdge** ppEdgeList = EdgeList.ptr(); - for (i = 0; i < EdgeList.size(); i++) - { - VERIFY(ppEdgeList[i] != NULL); - VERIFY(ppEdgeList[i] != pEdge); - } -#endif - *(EdgeList.append()) = pEdge; -} - -inline MeshEdge* MeshPt::FindEdge(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - VERIFY(pPt != this); - MeshEdge** ppEdgeList = EdgeList.ptr(); - u32 i; - for (i = 0; i < EdgeList.size(); i++) - { - MeshEdge* pEdge = ppEdgeList[i]; - VERIFY(pEdge != NULL); - VERIFY((pEdge->pPt1 == this) || (pEdge->pPt2 == this)); - if (pEdge->pPt2 == pPt) - { - VERIFY(pEdge->pPt1 == this); - return (pEdge); - } - if (pEdge->pPt1 == pPt) - { - VERIFY(pEdge->pPt2 == this); - return (pEdge); - } - } - return (NULL); -} - -// Find the first edge that uses this pt and the other given, and -// also has a free triangle entry, assuming that the points are -// used in that clockwise order. This allows two edges that share -// the same points to exist, e.g. where multiple triangles share -// the same edge (think of the diagonal of the tris of a back-to-back -// quad - same edge, four tris. -// The tri will use the points in the order *this,*pPt. -inline MeshEdge* MeshPt::FindTriEdge(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - VERIFY(pPt != this); - MeshEdge** ppEdgeList = EdgeList.ptr(); - u32 i; - for (i = 0; i < EdgeList.size(); i++) - { - MeshEdge* pEdge = ppEdgeList[i]; - VERIFY(pEdge != NULL); - VERIFY((pEdge->pPt1 == this) || (pEdge->pPt2 == this)); - if (pEdge->pPt2 == pPt) - { - VERIFY(pEdge->pPt1 == this); - // Check that it would be possible to add a tri to this. - // The tri will use this,pPt in that order, so must be in - // pTri12 - if (pEdge->pTri12 == NULL) - { - return (pEdge); - } - // else - // { - // int bogus = 0; - // } - } - if (pEdge->pPt1 == pPt) - { - VERIFY(pEdge->pPt2 == this); - // Check that it would be possible to add a tri to this. - // The tri will use this,pPt in that order, so must be in - // pTri21 - if (pEdge->pTri21 == NULL) - { - return (pEdge); - } - // else - // { - // int bogus = 0; - // } - } - } - return (NULL); -} - -inline MeshTri* MeshPt::FindTri(MeshPt* pPt1, MeshPt* pPt2) -{ - VERIFY(pPt1 != NULL); - VERIFY(pPt2 != NULL); - MeshTri** ppTriList = TriList.ptr(); - u32 i; - for (i = 0; i < TriList.size(); i++) - { - MeshTri* pTri = ppTriList[i]; - VERIFY(pTri != NULL); - VERIFY((pTri->pPt1 == this) || (pTri->pPt2 == this) || (pTri->pPt3 == this)); - if ((pTri->pPt1 == this) && (pTri->pPt2 == pPt1) && (pTri->pPt3 == pPt2)) - { - return (pTri); - } - if ((pTri->pPt2 == this) && (pTri->pPt3 == pPt1) && (pTri->pPt1 == pPt2)) - { - return (pTri); - } - if ((pTri->pPt3 == this) && (pTri->pPt1 == pPt1) && (pTri->pPt2 == pPt2)) - { - return (pTri); - } - } - return (NULL); -} - -// Return the next tri in the list. -// If a non-NULL pPt is supplied, only tris using this,pPt in that order -// are returned, otherwise all tris are returned. -inline MeshTri* MeshPt::NextTri(MeshPt* pPt) -{ - VERIFY(this != pPt); - VERIFY(iCurTriNum >= 0); - while (TRUE) - { - if (iCurTriNum < (int)TriList.size()) - { - MeshTri* pTri = (TriList.ptr())[iCurTriNum++]; - VERIFY(pTri != NULL); - if (pPt == NULL) - { - // Return all tris. - return (pTri); - } - - // Return only tris that use this,pPt - if (((pTri->pPt1 == this) && (pTri->pPt2 == pPt)) || ((pTri->pPt2 == this) && (pTri->pPt3 == pPt)) || - ((pTri->pPt3 == this) && (pTri->pPt1 == pPt))) - { - return (pTri); - } - } - else - { - // End of the list. - iCurTriNum = -1; - return (NULL); - } - } -} - -// Return the first tri in the list. MUST be called before calling NextTri(). -// If a non-NULL pPt is supplied, only tris using this,pPt in that order -// are returned, otherwise all tris are returned. -inline MeshTri* MeshPt::FirstTri(MeshPt* pPt) -{ - VERIFY(iCurTriNum == -1); - iCurTriNum = 0; - return (NextTri(pPt)); -} - -// Terminate the current First/Next loop. -inline void MeshPt::EndTri(void) { iCurTriNum = -1; } -// Return the next Edge in the list. -// If a non-NULL pPt is supplied, only edges using this and pPt -// are returned, otherwise all edges are returned. -inline MeshEdge* MeshPt::NextEdge(MeshPt* pPt) -{ - VERIFY(this != pPt); - VERIFY(iCurEdgeNum >= 0); - while (TRUE) - { - if (iCurEdgeNum < (int)EdgeList.size()) - { - MeshEdge* pEdge = (EdgeList.ptr())[iCurEdgeNum++]; - VERIFY(pEdge != NULL); - if (pPt == NULL) - { - // Return all edges. - return (pEdge); - } - - // Return only the edges the use this & pPt. - if ((pEdge->pPt1 == pPt) || (pEdge->pPt2 == pPt)) - { - VERIFY((pEdge->pPt1 == this) || (pEdge->pPt2 == this)); - return (pEdge); - } - } - else - { - // End of the list. - iCurEdgeNum = -1; - return (NULL); - } - } -} - -// Return the first Edge in the list. MUST be called before calling NextEdge(). -// If a non-NULL pPt is supplied, only edges using this and pPt -// are returned, otherwise all edges are returned. -inline MeshEdge* MeshPt::FirstEdge(MeshPt* pPt) -{ - iCurEdgeNum = 0; - return (NextEdge(pPt)); -} - -// Terminate the current First/Next loop. -inline void MeshPt::EndEdge(void) { iCurEdgeNum = -1; } -// Returns TRUE if the two pts are marked as being in proximity. -inline bool MeshPt::CheckProx(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - MeshPt** ppPt = ProxPtList.ptr(); - for (u32 i = 0; i < ProxPtList.size(); i++) - { - VERIFY(ppPt[i] != NULL); - if (ppPt[i] == pPt) - { - // Yes. - return (TRUE); - } - } - return (FALSE); -} - -// Add the given pt to the prox list (and vice versa). -// If the pt was not already there, returns TRUE; -// If bProxEdges is set to TRUE (default is FALSE ), -// the edges that these two pts use are made prox if possible. -inline bool MeshPt::AddProx(MeshPt* pPt, bool bProxEdges) -{ - bool bRes; - - VERIFY(pPt != NULL); - if (CheckProx(pPt)) - { - // Already prox. - VERIFY(pPt->CheckProx(this)); - bRes = FALSE; - } - else - { - VERIFY(!pPt->CheckProx(this)); - - // Add to this pt. - *(ProxPtList.append()) = pPt; - - // Add to the other pt. - *(pPt->ProxPtList.append()) = this; - - bRes = TRUE; - } - - // Now check all their edges for proximity. - // For each edge of this. - // Find other pt and scan proxs of that. - // If those proxes form and edge with pPt, the edges are prox. - MeshEdge* pedge = FirstEdge(); - while (pedge != NULL) - { - MeshPt* pptOther = pedge->OtherPt(this); - MeshPt** ppPt = pptOther->ProxPtList.ptr(); - for (u32 i = 0; i < pptOther->ProxPtList.size(); i++) - { - VERIFY(ppPt[i] != NULL); - MeshEdge* pedgeProx = pPt->FindEdge(ppPt[i]); - if (pedgeProx != NULL) - { - bool bRes = pedgeProx->AddProx(pedge); - VERIFY(bRes); - break; - } - } - - pedge = NextEdge(); - } - - return (bRes); -} - -// Remove the given pt from the prox list (and vice versa). -// If the pt was there, returns TRUE. -inline bool MeshPt::RemoveProx(MeshPt* pPt) -{ - VERIFY(pPt != NULL); - if (CheckProx(pPt)) - { - // Yep, they are prox. - VERIFY(pPt->CheckProx(this)); - - MeshPt** ppPtList; - u32 i; - - // Remove pPt from this. - ppPtList = ProxPtList.ptr(); - for (i = 0; i < ProxPtList.size(); i++) - { - if (ppPtList[i] == pPt) - { - break; - } - } - VERIFY(i < ProxPtList.size()); - // Replace this entry with the last entry. - ProxPtList.erase_fast(i); - - // Remove this from pPt. - ppPtList = pPt->ProxPtList.ptr(); - for (i = 0; i < pPt->ProxPtList.size(); i++) - { - if (ppPtList[i] == this) - { - break; - } - } - VERIFY(i < pPt->ProxPtList.size()); - // Replace this entry with the last entry. - ProxPtList.erase_fast(i); - - return (TRUE); - } - else - { - // No, they're not prox. - VERIFY(!pPt->CheckProx(this)); - return (FALSE); - } -} - -// Return the first prox pt. MUST be called before calling NextProx(). -inline MeshPt* MeshPt::FirstProx(void) -{ - VERIFY(iCurProxNum == -1); - iCurProxNum = 0; - return (NextProx()); -} - -// Return the next prox pt. -inline MeshPt* MeshPt::NextProx(void) -{ - VERIFY(iCurProxNum >= 0); - while (TRUE) - { - if (iCurProxNum < (int)ProxPtList.size()) - { - MeshPt* pptProx = (ProxPtList.ptr())[iCurProxNum++]; - VERIFY(pptProx != NULL); - return (pptProx); - } - else - { - // End of the list. - iCurProxNum = -1; - return (NULL); - } - } -} - -// Terminate the current First/Next loop. -inline void MeshPt::EndProx(void) { iCurProxNum = -1; } -inline MeshPt* MeshPt::QueryList(void) -{ - MeshPt* pListRoot = ListFindFirst(); - if (pListRoot == this) - { - VERIFY(ListFindLast() == this); - pListRoot = NULL; - } - return (pListRoot); -} - -inline void MeshPt::SetList(MeshPt* pListRoot) -{ - ListDel(); - if (pListRoot != NULL) - { - ListAddAfter(pListRoot); - } -} - -inline bool MeshPt::ConsistencyCheck(MeshPt* pPtRoot, MeshEdge* pEdgeRoot, MeshTri* pTriRoot) -{ - bool bRes = TRUE; - if ((pPtRoot != NULL) && (QueryList() != pPtRoot)) - { - FAIL_CHECK(); - } - - // Check prox. - MeshPt** ppPt = ProxPtList.ptr(); - for (u32 i = 0; i < ProxPtList.size(); i++) - { - VERIFY(ppPt[i] != NULL); - if (!ppPt[i]->CheckProx(this)) - { - FAIL_CHECK(); - } - if ((pPtRoot != NULL) && (ppPt[i]->QueryList() != pPtRoot)) - { - FAIL_CHECK(); - } - } - - // Just check the consistency of all tris and edges that use this. - MeshEdge* pEdge = FirstEdge(); - while (pEdge != NULL) - { - if (!pEdge->ConsistencyCheck(pPtRoot, pEdgeRoot, pTriRoot)) - { - // Will have already VERIFYed. - bRes = FALSE; - } - pEdge = NextEdge(); - } - MeshTri* pTri = FirstTri(); - while (pTri != NULL) - { - if (!pTri->ConsistencyCheck(pPtRoot, pEdgeRoot, pTriRoot)) - { - // Will have already VERIFYed. - bRes = FALSE; - } - pTri = NextTri(); - } - return (bRes); -} diff --git a/src/utils/ETools/object.cpp b/src/utils/ETools/object.cpp deleted file mode 100644 index 01b35dcedf3..00000000000 --- a/src/utils/ETools/object.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -#include "stdafx.h" -#pragma hdrstop - -#include "object.h" -#include "MxQMetric.h" -#include "quad.h" - -#define QUAD_SIZE 5 - -int g_iNumOfObjectVertsDrawn = 0; -int g_iMaxNumTrisDrawn = -1; - -Object::Object() -{ - pNextCollapse = &CollapseRoot; - iCurSlidingWindowLevel = 0; -} - -Object::~Object() -{ - BinCurrentObject(); - - while (CollapseRoot.ListNext() != NULL) - { - GeneralCollapseInfo* inf = (GeneralCollapseInfo*)CollapseRoot.ListNext(); - xr_delete(inf); - } -} - -bool Object::Valid(void) -{ - for (MeshTri* pTriTgt = CurTriRoot.ListNext(); pTriTgt != NULL; pTriTgt = pTriTgt->ListNext()) - for (MeshTri* pTriLst = CurTriRoot.ListNext(); pTriLst != NULL; pTriLst = pTriLst->ListNext()) - if (pTriTgt != pTriLst) - if (pTriTgt->Equal(pTriLst)) - return false; - - return true; -} - -void Object::Initialize(void) -{ - iFullNumPts = 0; - for (MeshPt* pPt = CurPtRoot.ListNext(); pPt != NULL; pPt = pPt->ListNext()) - iFullNumPts++; - iFullNumTris = 0; - for (MeshTri* pTri = CurTriRoot.ListNext(); pTri != NULL; pTri = pTri->ListNext()) - iFullNumTris++; - SetNewLevel(0); -} - -// Check that this is sensible. -void Object::CheckObject(void) -{ - MeshEdge* edge; - MeshTri* tri; - - edge = CurEdgeRoot.ListNext(); - while (edge != NULL) - { - // All the pts had better be the same material. - edge = edge->ListNext(); - } - - tri = CurTriRoot.ListNext(); - while (tri != NULL) - { - // And all tris should be the current level or the next. - VERIFY((tri->mytri.iSlidingWindowLevel == iCurSlidingWindowLevel) || - (tri->mytri.iSlidingWindowLevel == iCurSlidingWindowLevel + 1)); - tri = tri->ListNext(); - } -} - -// Bins all the current data. -void Object::BinCurrentObject(void) -{ - while (CurTriRoot.ListNext() != NULL) - { - MeshTri* tri = (MeshTri*)CurTriRoot.ListNext(); - xr_delete(tri); - } - while (CurEdgeRoot.ListNext() != NULL) - { - MeshEdge* edge = (MeshEdge*)CurEdgeRoot.ListNext(); - xr_delete(edge); - } - while (CurPtRoot.ListNext() != NULL) - { - MeshPt* pt = (MeshPt*)CurPtRoot.ListNext(); - xr_delete(pt); - } -} - -// Creates and performs a collapse of pptBinned to pptKept. -// Make sure they actually share an edge! -// Make sure the object is fully collapsed already. -void Object::CreateEdgeCollapse(MeshPt* pptBinned, MeshPt* pptKept) -{ - CheckObject(); - - // The thing had better be fully collapsed. - VERIFY(pNextCollapse == &CollapseRoot); - - MeshEdge* pedge = pptBinned->FindEdge(pptKept); - VERIFY(pedge != NULL); - GeneralCollapseInfo* pGCI = xr_new(&CollapseRoot); - - pGCI->fError = FindCollapseError(pptBinned, pptKept->FindEdge(pptBinned)); - - // Because deleting a tri breaks the FirstTri, NextTri sequence, - // we need to find the tris & just store their pointers. - // Then we delete them. - - pGCI->pptBin = pptBinned; - pGCI->pptKeep = pptKept; - - const int c_iMaxNumTris = 100; // Grow as needed. - MeshTri* pBinnedTris[c_iMaxNumTris]; - - MeshTri* ptri; - int iNumTrisCollapsed = 0; - long bNeedNewLevel = FALSE; - for (ptri = pptBinned->FirstTri(); ptri != NULL; ptri = pptBinned->NextTri()) - { - VERIFY(iNumTrisCollapsed < c_iMaxNumTris); // Grow c_iMaxNumTris as needed. - pBinnedTris[iNumTrisCollapsed++] = ptri; - if (ptri->mytri.iSlidingWindowLevel != iCurSlidingWindowLevel) - { - VERIFY(ptri->mytri.iSlidingWindowLevel == iCurSlidingWindowLevel + 1); - // Need to set a new level before doing this collapse. - bNeedNewLevel = TRUE; - } - } - - if (bNeedNewLevel) - { - // Store which tris were already on this level. - for (MeshTri* pTri = CurTriRoot.ListNext(); pTri != NULL; pTri = pTri->ListNext()) - { - if (pTri->mytri.iSlidingWindowLevel != iCurSlidingWindowLevel) - { - VERIFY(pTri->mytri.iSlidingWindowLevel == iCurSlidingWindowLevel + 1); - GeneralTriInfo* pTriInfoNew = pGCI->TriNextLevel.append(); - pTriInfoNew->ppt[0] = pTri->pPt1; - pTriInfoNew->ppt[1] = pTri->pPt2; - pTriInfoNew->ppt[2] = pTri->pPt3; - } - } - - // And set the new level. - iCurSlidingWindowLevel++; - SetNewLevel(iCurSlidingWindowLevel); - } - - pGCI->iSlidingWindowLevel = iCurSlidingWindowLevel; - - // Now bin them. - // Store the tris so that pptBinned is always ppt[0]. - // This makes some of the optimised mesh versions simpler to code. - // Also, make two passes and store the changed tris first, then the - // binned ones. Again, this makes life easier later on. - // So all the tris in TriCollapsed should correspond with the - // same-numbered item in TriOriginal. - int i; - for (i = iNumTrisCollapsed - 1; i >= 0; i--) - { - MeshPt* ppt[3]; - ppt[0] = pBinnedTris[i]->pPt1; - ppt[1] = pBinnedTris[i]->pPt2; - ppt[2] = pBinnedTris[i]->pPt3; - while (ppt[0] != pptBinned) - { - MeshPt* pptTemp = ppt[0]; - ppt[0] = ppt[1]; - ppt[1] = ppt[2]; - ppt[2] = pptTemp; - } - VERIFY(iCurSlidingWindowLevel == pBinnedTris[i]->mytri.iSlidingWindowLevel); - - if ((ppt[0] == pptKept) || (ppt[1] == pptKept) || (ppt[2] == pptKept)) - { - // This tri will be binned. Store it next time round. - } - else - { - GeneralTriInfo* pTriInfo = pGCI->TriOriginal.append(); - pTriInfo->ppt[0] = ppt[0]; - pTriInfo->ppt[1] = ppt[1]; - pTriInfo->ppt[2] = ppt[2]; - - pBinnedTris[i]->Delete(TRUE); - pBinnedTris[i] = NULL; - } - } - // Do it again, adding the binned tris this time. - int iNumBinned = 0; - for (i = iNumTrisCollapsed - 1; i >= 0; i--) - { - if (pBinnedTris[i] != NULL) - { - iNumBinned++; - - MeshPt* ppt[3]; - ppt[0] = pBinnedTris[i]->pPt1; - ppt[1] = pBinnedTris[i]->pPt2; - ppt[2] = pBinnedTris[i]->pPt3; - while (ppt[0] != pptBinned) - { - MeshPt* pptTemp = ppt[0]; - ppt[0] = ppt[1]; - ppt[1] = ppt[2]; - ppt[2] = pptTemp; - } - VERIFY(iCurSlidingWindowLevel == pBinnedTris[i]->mytri.iSlidingWindowLevel); - - VERIFY((ppt[0] == pptKept) || (ppt[1] == pptKept) || (ppt[2] == pptKept)); - - GeneralTriInfo* pTriInfo = pGCI->TriOriginal.append(); - pTriInfo->ppt[0] = ppt[0]; - pTriInfo->ppt[1] = ppt[1]; - pTriInfo->ppt[2] = ppt[2]; - - pBinnedTris[i]->Delete(TRUE); - pBinnedTris[i] = NULL; - } - } - - // And add in the new tris. - for (i = 0; i < iNumTrisCollapsed; i++) - { - GeneralTriInfo* pTriInfo = pGCI->TriOriginal.item(i); - - // ppt[0] should always be the binned pt. - VERIFY(pTriInfo->ppt[0] == pptBinned); - - // Now, are either of the other two the kept point? - // If so, these are tris that get binned, rather than remapped. - if ((pTriInfo->ppt[1] == pptKept) || (pTriInfo->ppt[2] == pptKept)) - { - // Binned tri - these should be the last few. - VERIFY(i >= iNumTrisCollapsed - iNumBinned); - } - else - { - // A remapped tri. - VERIFY(pGCI->TriCollapsed.size() == u32(i)); - GeneralTriInfo* pTriInfoNew = pGCI->TriCollapsed.append(); - pTriInfoNew->ppt[0] = pptKept; - pTriInfoNew->ppt[1] = pTriInfo->ppt[1]; - pTriInfoNew->ppt[2] = pTriInfo->ppt[2]; - - // And actually create this tri. - MeshTri* pTri = - xr_new(pTriInfoNew->ppt[0], pTriInfoNew->ppt[1], pTriInfoNew->ppt[2], &CurTriRoot, &CurEdgeRoot); - VERIFY(pTri != NULL); - pTri->mytri.iSlidingWindowLevel = iCurSlidingWindowLevel + 1; - } - } - - pGCI->iNumTris = 0; - for (MeshTri* pTri = CurTriRoot.ListNext(); pTri != NULL; pTri = pTri->ListNext()) - { - pGCI->iNumTris++; - } - - iNumCollapses++; -} - -// Bin the last collapse. -// Returns TRUE if these was a last collapse to do. -long Object::BinEdgeCollapse(void) -{ - GeneralCollapseInfo* pGCI = CollapseRoot.ListNext(); - if (pGCI == NULL) - { - // No collapses to bin. - VERIFY(iNumCollapses == 0); - return FALSE; - } - else - { - iNumCollapses--; - if (pNextCollapse == &CollapseRoot) - { - // Fully collapsed - uncollapse once. - UndoCollapse(); - } - if (pNextCollapse == pGCI) - { - // This is the next collapse to be done. - pNextCollapse = &CollapseRoot; - } - pGCI->ListDel(); - xr_delete(pGCI); - - return TRUE; - } -} - -// Returns TRUE if a collapse was undone. -long Object::UndoCollapse(void) -{ - if (pNextCollapse->ListNext() == NULL) - { - // No more to undo. - return FALSE; - } - else - { - pNextCollapse = pNextCollapse->ListNext(); - - VERIFY(pNextCollapse->iSlidingWindowLevel == iCurSlidingWindowLevel); - - u32 i; - for (i = 0; i < pNextCollapse->TriCollapsed.size(); i++) - { - GeneralTriInfo* pTriInfo = pNextCollapse->TriCollapsed.item(i); - MeshTri* pTri = pTriInfo->ppt[0]->FindTri(pTriInfo->ppt[1], pTriInfo->ppt[2]); - VERIFY(pTri != NULL); - pTri->Delete(TRUE); - } - - for (i = 0; i < pNextCollapse->TriOriginal.size(); i++) - { - GeneralTriInfo* pTriInfo = pNextCollapse->TriOriginal.item(i); - MeshTri* pTri = - xr_new(pTriInfo->ppt[0], pTriInfo->ppt[1], pTriInfo->ppt[2], &CurTriRoot, &CurEdgeRoot); - VERIFY(pTri != NULL); - pTri->mytri.iSlidingWindowLevel = iCurSlidingWindowLevel; - } - - // Now see if the _previous_ collapse is on a different level. - if (pNextCollapse->ListNext() != NULL) - { - if (pNextCollapse->ListNext()->iSlidingWindowLevel != iCurSlidingWindowLevel) - { - // Need to go back a level. - VERIFY(pNextCollapse->ListNext()->iSlidingWindowLevel == iCurSlidingWindowLevel - 1); - iCurSlidingWindowLevel--; - SetNewLevel(iCurSlidingWindowLevel); - - // Except that some tris will already be at the lower level. - for (u32 i = 0; i < pNextCollapse->TriNextLevel.size(); i++) - { - GeneralTriInfo* pTriInfo = pNextCollapse->TriNextLevel.item(i); - MeshTri* pTri = pTriInfo->ppt[0]->FindTri(pTriInfo->ppt[1], pTriInfo->ppt[2]); - VERIFY(pTri != NULL); - pTri->mytri.iSlidingWindowLevel = iCurSlidingWindowLevel + 1; - } - } - } - - return TRUE; - } -} - -// Returns TRUE if a collapse was done. -long Object::DoCollapse(void) -{ - if (pNextCollapse == &CollapseRoot) - { - // No more to do. - return FALSE; - } - else - { - if (pNextCollapse->iSlidingWindowLevel != iCurSlidingWindowLevel) - { - // Need to start a new level. - VERIFY(pNextCollapse->TriNextLevel.size() > 0); - VERIFY(pNextCollapse->iSlidingWindowLevel == iCurSlidingWindowLevel + 1); - iCurSlidingWindowLevel++; - SetNewLevel(iCurSlidingWindowLevel); - } - else - { - // No new level to start. - VERIFY(pNextCollapse->TriNextLevel.size() == 0); - } - - u32 i; - for (i = 0; i < pNextCollapse->TriOriginal.size(); i++) - { - GeneralTriInfo* pTriInfo = pNextCollapse->TriOriginal.item(i); - MeshTri* pTri = pTriInfo->ppt[0]->FindTri(pTriInfo->ppt[1], pTriInfo->ppt[2]); - VERIFY(pTri != NULL); - - VERIFY(pTri->mytri.iSlidingWindowLevel == iCurSlidingWindowLevel); - - pTri->Delete(TRUE); - } - - for (i = 0; i < pNextCollapse->TriCollapsed.size(); i++) - { - GeneralTriInfo* pTriInfo = pNextCollapse->TriCollapsed.item(i); - MeshTri* pTri = - xr_new(pTriInfo->ppt[0], pTriInfo->ppt[1], pTriInfo->ppt[2], &CurTriRoot, &CurEdgeRoot); - VERIFY(pTri != NULL); - pTri->mytri.iSlidingWindowLevel = iCurSlidingWindowLevel + 1; - } - - pNextCollapse = pNextCollapse->ListPrev(); - - return TRUE; - } -} - -void Object::SetNewLevel(int iLevel) -{ - for (MeshTri* pTri = CurTriRoot.ListNext(); pTri != NULL; pTri = pTri->ListNext()) - { - pTri->mytri.iSlidingWindowLevel = iLevel; - } -} - -long Object::CollapseAllowedForLevel(MeshPt* pptBinned, int iLevel) -{ - // All the tris that use the binned point must be at the current level. - long bRes = TRUE; - for (MeshTri* pTri = pptBinned->FirstTri(); pTri != NULL; pTri = pptBinned->NextTri()) - { - if (iLevel != pTri->mytri.iSlidingWindowLevel) - { - bRes = FALSE; - } - } - return bRes; -} - -// Return the error from this edge collapse. -// Set bTryToCacheResult=TRUE if you can pass pptBinned in multiple times. -// Make sure you call this with bTryToCacheResult=FALSE if any data changes, -// or you'll confuse the poor thing. -void pack_to_vector(MxVector& tgt, const Fvector3& src_p, float src_u, float src_v) -{ - tgt[0] = src_p.x; - tgt[1] = src_p.y; - tgt[2] = src_p.z; - if (QUAD_SIZE > 3) - { - tgt[3] = src_u; - tgt[4] = src_v; - } -} - -void Object::compute_face_quadric(MeshTri* tri, MxQuadric& Q) -{ - MxVector v1(QUAD_SIZE); - MxVector v2(QUAD_SIZE); - MxVector v3(QUAD_SIZE); - - pack_to_vector(v1, tri->pPt1->mypt.vPos, tri->pPt1->mypt.fU, tri->pPt1->mypt.fV); - pack_to_vector(v2, tri->pPt2->mypt.vPos, tri->pPt2->mypt.fU, tri->pPt2->mypt.fV); - pack_to_vector(v3, tri->pPt3->mypt.vPos, tri->pPt3->mypt.fU, tri->pPt3->mypt.fV); - - Q = MxQuadric(v1, v2, v3, 0.f); -} - -float Object::FindCollapseError(MeshPt* pptBinned, MeshEdge* pedgeCollapse, long bTryToCacheResult /*= FALSE*/) -{ - static MeshPt* pptLast; - static MxQuadric qLast(QUAD_SIZE); - if (pptBinned == NULL) - { - pptLast = 0; - return 0.0f; - } - - MxQuadric qSum = MxQuadric(QUAD_SIZE); - if (bTryToCacheResult && (pptLast == pptBinned)) - { - qSum = qLast; - } - else - { - for (MeshTri* ptri = pptBinned->FirstTri(); ptri != NULL; ptri = pptBinned->NextTri()) - { - MxQuadric qCur(QUAD_SIZE); - compute_face_quadric(ptri, qCur); - qSum += qCur; - } - if (bTryToCacheResult) - { - qLast = qSum; - pptLast = pptBinned; - } - else - { - pptLast = NULL; - } - } - - MeshPt* pptKept = pedgeCollapse->OtherPt(pptBinned); - VERIFY(pptKept != NULL); - - MxVector pos(QUAD_SIZE); - pack_to_vector(pos, pptKept->mypt.vPos, pptKept->mypt.fU, pptKept->mypt.fV); - - return (float)qSum.evaluate(pos); - /* - static MeshPt *pptLast; - static Quad3 qLast; - - if ( pptBinned == NULL ){ - // You can call it like this to flush the cache. - pptLast = NULL; - return 0.0f; - } - - - MeshPt *pptKept = pedgeCollapse->OtherPt ( pptBinned ); - VERIFY ( pptKept != NULL ); - - - Quad3 qSum; - if ( bTryToCacheResult && ( pptLast == pptBinned ) ){ - qSum = qLast; - }else{ - // Find the sum of the QEMs of the tris that will be binned. - for ( MeshTri *ptri = pptBinned->FirstTri(); ptri != NULL; ptri = pptBinned->NextTri() ) - qSum += Quad3 ( ptri->pPt1->mypt.vPos, ptri->pPt2->mypt.vPos, ptri->pPt3->mypt.vPos ); - - if ( bTryToCacheResult ){ - qLast = qSum; - pptLast = pptBinned; - }else{ - pptLast = NULL; - } - } - - // And find the error once the collapse has happened. - return qSum.FindError ( pptKept->mypt.vPos ); - */ -} diff --git a/src/utils/ETools/object.h b/src/utils/ETools/object.h deleted file mode 100644 index 8a4a22502a5..00000000000 --- a/src/utils/ETools/object.h +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -#ifndef objectH -#define objectH - -// Incremented by the draw routs. Display + zero whenever you want. -extern int g_iMaxNumTrisDrawn; - -#define INVALID_INDEX u32(-1) - -// The data that gets stored inside mesh.h's tris, pts and edges. -class MeshPt; -class MeshEdge; -class MeshTri; - -struct MyPt -{ - Fvector3 vPos; - Fvector3 vNorm; - float fU, fV; - - u32 dwIndex; - u32 dwNewIndex; - - // Temporary data. - MeshPt* pTempPt; // Temporary data. -}; - -struct MyEdge -{ - // Temporary data. -}; - -struct MyTri -{ - // Temporary data. - int iSlidingWindowLevel; // Which sliding window level this tri belongs to. - - u32 dwNewIndex; - MeshTri* pOriginalTri; -}; - -// The data that gets stored inside mesh.h's tris, pts and edges. -#define MESHTRI_APP_DEFINED MyTri mytri; -#define MESHEDGE_APP_DEFINED MyEdge myedge; -#define MESHPT_APP_DEFINED MyPt mypt; - -#include "xrCore/xrCore.h" - -#include "mesh.h" -#include "MxQMetric.h" - -struct GeneralTriInfo -{ - MeshPt* ppt[3]; -}; - -struct GeneralCollapseInfo -{ - DlinkDefine(GeneralCollapseInfo, List); - - ArbitraryList TriOriginal; - ArbitraryList TriCollapsed; - - int iSlidingWindowLevel; // Which sliding window level the binned tris will belong to. - ArbitraryList - TriNextLevel; // On collapses that change levels, lists the tris that were on the next level. - - MeshPt* pptBin; - MeshPt* pptKeep; - - float fError; // Error of this collapse. - int iNumTris; // Number of tris after this collapse has been made. - - DlinkMethods(GeneralCollapseInfo, List); - - GeneralCollapseInfo() { ListInit(); } - GeneralCollapseInfo(GeneralCollapseInfo* pPrev) - { - ListInit(); - ListAddAfter(pPrev); - } - - ~GeneralCollapseInfo() { ListDel(); } -}; - -struct Object -{ - // The collapse list is ordered backwards, - // so ptr->ListNext() is the _previous_ collapse to ptr. - GeneralCollapseInfo CollapseRoot; - - // The current shape. - MeshPt CurPtRoot; - MeshTri CurTriRoot; - MeshEdge CurEdgeRoot; - - // pNextCollapse points to the _next_ collapse to do. - // pNextCollapse->ListNext() is the collapse that's just been done. - // &CollapseRoot = no more collapses to do. - GeneralCollapseInfo* pNextCollapse; - - int iFullNumTris; // How many tris with no collapses. - int iFullNumPts; // How many pts with no collapses. - int iNumCollapses; // Total number of collapses. - - int iCurSlidingWindowLevel; - - void compute_face_quadric(MeshTri* tri, MxQuadric& Q); - -public: - Object(); - - ~Object(); - - void Initialize(void); - - // Check that this is sensible. - void CheckObject(void); - - // Bins all the current data. - void BinCurrentObject(void); - - // Creates and performs a collapse of pptBinned to pptKept. - // Make sure they actually share an edge! - // Make sure the object is fully collapsed already. - void CreateEdgeCollapse(MeshPt* pptBinned, MeshPt* pptKept); - - // Bin the last collapse. - // Returns TRUE if these was a last collapse to do. - long BinEdgeCollapse(void); - - // Returns TRUE if a collapse was undone. - long UndoCollapse(void); - - // Returns TRUE if a collapse was done. - long DoCollapse(void); - - void SetNewLevel(int iLevel); - - long CollapseAllowedForLevel(MeshPt* pptBinned, int iLevel); - - // Return the error from this edge collapse. - // Set bTryToCacheResult=TRUE if you can pass pptBinned in multiple times. - // Make sure you call this with bTryToCacheResult=FALSE if any data changes, - // or you'll confuse the poor thing. - float FindCollapseError(MeshPt* pptBinned, MeshEdge* pedgeCollapse, long bTryToCacheResult = FALSE); - - bool Valid(void); -}; - -#endif // objectH diff --git a/src/utils/ETools/object_sliding.cpp b/src/utils/ETools/object_sliding.cpp deleted file mode 100644 index d98ac76d49d..00000000000 --- a/src/utils/ETools/object_sliding.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -#include "stdafx.h" -#pragma hdrstop - -#include "object.h" -#include "object_sliding.h" - -// BOOL g_bUseFastButBadOptimise = FALSE; - -// Call this to reorder the tris in this trilist to get good vertex-cache coherency. -// *pwList is modified (but obviously not changed in size or memory location). -// void OptimiseVertexCoherencyTriList ( WORD *pwList, int iHowManyTris, u32 mode); -void OptimiseVertexCoherencyTriList(u16* pwList, int iHowManyTris, u32 optimize_mode) -{ - if (iHowManyTris) - { - DWORD* remap = xr_alloc(iHowManyTris); - u16 max_idx = 0; - for (int k = 0; k < iHowManyTris * 3; k++) - max_idx = std::max(max_idx, pwList[k]); - HRESULT rhr = D3DXOptimizeFaces(pwList, iHowManyTris, max_idx + 1, FALSE, remap); - R_CHK(rhr); - u16* tmp = xr_alloc(iHowManyTris * 3); - memcpy(tmp, pwList, sizeof(u16) * 3 * iHowManyTris); - for (int it = 0; it < iHowManyTris; it++) - { - pwList[it * 3 + 0] = tmp[remap[it] * 3 + 0]; - pwList[it * 3 + 1] = tmp[remap[it] * 3 + 1]; - pwList[it * 3 + 2] = tmp[remap[it] * 3 + 2]; - } - xr_free(remap); - xr_free(tmp); - } -} - -BOOL CalculateSW(Object* object, VIPM_Result* result, u32 optimize_vertex_order) -{ - result->swr_records.resize(0); - - MeshPt* pt; - MeshTri* tri; - - // Undo all the collapses, so we start from the maximum mesh. - while (object->UndoCollapse()) - { - } - - // How many vertices are we looking at? - u32 iNumVerts = 0; - for (pt = object->CurPtRoot.ListNext(); pt != NULL; pt = pt->ListNext()) - { - pt->mypt.dwNewIndex = INVALID_INDEX; - iNumVerts++; - } - // Er... word indices, guys... nothing supports 32-bit indices yet. - R_ASSERT(iNumVerts < 65535); - - // How many tris are we looking at? - int iNumTris = 0; - for (tri = object->CurTriRoot.ListNext(); tri != NULL; tri = tri->ListNext()) - { - tri->mytri.dwNewIndex = INVALID_INDEX; // Mark them as not being in a collapse. - iNumTris++; - } - // A lot of cards have this annoying limit - see D3DCAPS8.MaxPrimitiveCount, which is - // exactly 65535 for DX7 and previous devices. So might as well stick with that number. - R_ASSERT(iNumTris < 65535); - - // Create a place to put indices while we build up the list. Because we don't know - // how many we need yet, we can't create the IB until the end. Then we'll copy this into it. - result->indices.resize(0); - - // permutation table - result->permute_verts.resize(iNumVerts); - for (u32 k = 0; k < result->permute_verts.size(); k++) - result->permute_verts[k] = u16(-1); - - // Now do all the collapses, so we start from the minimum mesh. - // Along the way, mark the vertices in reverse order. - int iCurVerts = iNumVerts; - int iCurCollapse = 0; - int iCurSlidingWindowLevel = 0; - float total_error = 0.f; - while (TRUE) - { - GeneralCollapseInfo* pCollapse = object->pNextCollapse; - if (object->pNextCollapse == &(object->CollapseRoot)) - break; - - iCurSlidingWindowLevel = pCollapse->iSlidingWindowLevel; - iCurCollapse++; - iCurVerts--; - pCollapse->pptBin->mypt.dwNewIndex = iCurVerts; - total_error += pCollapse->fError; - object->DoCollapse(); - } - - int iNumCollapses = iCurCollapse; - - // Add the remaining existing pts in any old order. - u16 wCurIndex = 0; - for (pt = object->CurPtRoot.ListNext(); pt != NULL; pt = pt->ListNext()) - { - if (pt->mypt.dwNewIndex == INVALID_INDEX) - { - // Not binned in a collapse. - result->permute_verts[pt->mypt.dwIndex] = wCurIndex; - pt->mypt.dwNewIndex = wCurIndex; - wCurIndex++; - } - } - - // Should meet in the middle! - R_ASSERT(wCurIndex == iCurVerts); - - // And count the tris that are left. - int iCurNumTris = 0; - for (tri = object->CurTriRoot.ListNext(); tri != NULL; tri = tri->ListNext()) - iCurNumTris++; - - // Reserve space for the collapse table - this is stored so that - // "number of collapses" is the index. So we'll be adding from the - // back. - iCurCollapse++; // Implicit "last collapse" is state after last collapse. - result->swr_records.resize(iCurCollapse); - // And add the last one. - iCurCollapse--; - VIPM_SWR* swr = result->swr_records.item(iCurCollapse); - swr->offset = 0; - swr->num_tris = (u16)iCurNumTris; - swr->num_verts = wCurIndex; - - // Now go through each level in turn. - - int iCurTriBinned = 0; - - // Useful thing. - ArbitraryList wTempIndices; - - int iMaxSlidingWindowLevel = iCurSlidingWindowLevel; - - while (TRUE) - { - // Now we go through the collapses for this level, undoing them. - // As we go, we add the binned tris to the start of the index list, - // - - // This coming list will be three sections: - // 1. the tris that get binned by the splits. - // 2. the tris that aren't affected. - // 3. the tris that are added by the splits. - // - // We know that at the moment, we are just rendering - // 1+2, which must equal the number of tris. - // So 3 starts iCurNumTris on from the start of 1. - int iCurTriAdded = iCurTriBinned + iCurNumTris; - result->indices.resize(iCurTriAdded * 3); - - int iJustCheckingNumTris = 0; - for (tri = object->CurTriRoot.ListNext(); tri != NULL; tri = tri->ListNext()) - { - tri->mytri.dwNewIndex = INVALID_INDEX; // Mark them as not being in a collapse. - iJustCheckingNumTris++; - } - R_ASSERT(iJustCheckingNumTris == iCurNumTris); - - BOOL bJustStartedANewLevel = TRUE; - - // Now undo all the collapses for this level in turn, adding vertices, - // binned tris, and SlidingWindowRecords as we go. - while ((object->pNextCollapse->ListNext() != NULL) && - (object->pNextCollapse->ListNext()->iSlidingWindowLevel == iCurSlidingWindowLevel)) - { - GeneralCollapseInfo* pCollapse = object->pNextCollapse->ListNext(); - - // If we've just started a new level, EXCEPT on the last level, - // we don't need to store the post-collapse version of the tris, - // since we'll just switch down to the next level instead. - if (!bJustStartedANewLevel || (iCurSlidingWindowLevel == iMaxSlidingWindowLevel)) - { - // These tris will be binned by the split. - if (pCollapse->TriCollapsed.size() > 0) - { - wTempIndices.resize(pCollapse->TriCollapsed.size() * 3); - for (u32 i = 0; i < pCollapse->TriCollapsed.size(); i++) - { - GeneralTriInfo* pTriInfo = pCollapse->TriCollapsed.item(i); - MeshTri* tri = pTriInfo->ppt[0]->FindTri(pTriInfo->ppt[1], pTriInfo->ppt[2]); - R_ASSERT(tri != NULL); - R_ASSERT( - tri->mytri.dwNewIndex == INVALID_INDEX); // Should not have been in a collapse this level. - - R_ASSERT(pTriInfo->ppt[0]->mypt.dwNewIndex < wCurIndex); - R_ASSERT(pTriInfo->ppt[1]->mypt.dwNewIndex < wCurIndex); - R_ASSERT(pTriInfo->ppt[2]->mypt.dwNewIndex < wCurIndex); - *wTempIndices.item(i * 3 + 0) = (u16)pTriInfo->ppt[0]->mypt.dwNewIndex; - *wTempIndices.item(i * 3 + 1) = (u16)pTriInfo->ppt[1]->mypt.dwNewIndex; - *wTempIndices.item(i * 3 + 2) = (u16)pTriInfo->ppt[2]->mypt.dwNewIndex; - iCurNumTris--; - } - - // Now try to order them as best you can. - if (optimize_vertex_order) - OptimiseVertexCoherencyTriList( - wTempIndices.ptr(), pCollapse->TriCollapsed.size(), optimize_vertex_order); - - // And write them to the index list. - result->indices.insert(iCurTriBinned * 3, wTempIndices, 0, 3 * pCollapse->TriCollapsed.size()); - // memcpy ( result->indices.item ( iCurTriBinned * 3 ), wTempIndices.ptr(), sizeof(WORD) * 3 * - // pCollapse->TriCollapsed.size() ); - iCurTriBinned += pCollapse->TriCollapsed.size(); - } - } - else - { - // Keep the bookkeeping happy. - iCurNumTris -= pCollapse->TriCollapsed.size(); - // And move the added tris pointer back, because it didn't know we weren't - // going to store these. - iCurTriAdded -= pCollapse->TriCollapsed.size(); - } - bJustStartedANewLevel = FALSE; - // Do the uncollapse. - object->UndoCollapse(); - // Add the unbinned vertex. - MeshPt* pPt = pCollapse->pptBin; - R_ASSERT(pPt->mypt.dwNewIndex == wCurIndex); - result->permute_verts[pPt->mypt.dwIndex] = wCurIndex; - /* - pCurVertex->pt = pPt->mypt.vPos; - //. pCurVertex->norm = pPt->mypt.vNorm; - pCurVertex->uv.x = pPt->mypt.fU; - pCurVertex->uv.y = pPt->mypt.fV; - pCurVertex++; - */ - wCurIndex++; - - // These tris will be added by the split. - if (pCollapse->TriOriginal.size() > 0) - { - wTempIndices.resize(pCollapse->TriOriginal.size() * 3); - for (u32 i = 0; i < pCollapse->TriOriginal.size(); i++) - { - GeneralTriInfo* pTriInfo = pCollapse->TriOriginal.item(i); - MeshTri* tri = pTriInfo->ppt[0]->FindTri(pTriInfo->ppt[1], pTriInfo->ppt[2]); - R_ASSERT(tri != NULL); - tri->mytri.dwNewIndex = 1; // Mark it has having been in a collapse. - - R_ASSERT(pTriInfo->ppt[0]->mypt.dwNewIndex < wCurIndex); - R_ASSERT(pTriInfo->ppt[1]->mypt.dwNewIndex < wCurIndex); - R_ASSERT(pTriInfo->ppt[2]->mypt.dwNewIndex < wCurIndex); - *wTempIndices.item(i * 3 + 0) = (u16)pTriInfo->ppt[0]->mypt.dwNewIndex; - *wTempIndices.item(i * 3 + 1) = (u16)pTriInfo->ppt[1]->mypt.dwNewIndex; - *wTempIndices.item(i * 3 + 2) = (u16)pTriInfo->ppt[2]->mypt.dwNewIndex; - iCurNumTris++; - } - - // Now try to order them as best you can. - if (optimize_vertex_order) - OptimiseVertexCoherencyTriList( - wTempIndices.ptr(), pCollapse->TriOriginal.size(), optimize_vertex_order); - - // And write them to the index list. - result->indices.resize((iCurTriAdded + pCollapse->TriOriginal.size()) * 3); - result->indices.insert(iCurTriAdded * 3, wTempIndices, 0, 3 * pCollapse->TriOriginal.size()); - // memcpy ( result->indices.item ( iCurTriAdded * 3 ), wTempIndices.ptr(), sizeof(WORD) * 3 * - // pCollapse->TriOriginal.size() ); - iCurTriAdded += pCollapse->TriOriginal.size(); - } - - // Add the collapse record. - iCurCollapse--; - - VIPM_SWR* swr = result->swr_records.item(iCurCollapse); - swr->offset = iCurTriBinned * 3; - swr->num_tris = (u16)iCurNumTris; - swr->num_verts = wCurIndex; - } - - // OK, finished this level. Any tris that are left with an index of -1 - // were not added during this level, and therefore need to be - // added into the middle of the list. - iJustCheckingNumTris = 0; - int iTempTriNum = 0; - //. wTempIndices.resize (0); - for (tri = object->CurTriRoot.ListNext(); tri != NULL; tri = tri->ListNext()) - { - iJustCheckingNumTris++; - if (tri->mytri.dwNewIndex == INVALID_INDEX) - { - // This tri has not been created by a collapse this level. - wTempIndices.resize(iTempTriNum * 3 + 3); - *(wTempIndices.item(iTempTriNum * 3 + 0)) = (u16)tri->pPt1->mypt.dwNewIndex; - *(wTempIndices.item(iTempTriNum * 3 + 1)) = (u16)tri->pPt2->mypt.dwNewIndex; - *(wTempIndices.item(iTempTriNum * 3 + 2)) = (u16)tri->pPt3->mypt.dwNewIndex; - iTempTriNum++; - } - } - R_ASSERT(iJustCheckingNumTris == iCurNumTris); - - // Now try to order them as best you can. - if (optimize_vertex_order) - OptimiseVertexCoherencyTriList(wTempIndices.ptr(), iTempTriNum, optimize_vertex_order); - - // And write them to the index list. - result->indices.insert(iCurTriBinned * 3, wTempIndices, 0, 3 * iTempTriNum); - - if (object->pNextCollapse->ListNext() == NULL) - { - // No more collapses. - R_ASSERT(iCurCollapse == 0); - R_ASSERT(iCurSlidingWindowLevel == 0); - break; - } - - // Start a new level by skipping past all the indices so far. - iCurTriBinned += iCurNumTris; - // Check the maths. - R_ASSERT(iCurTriBinned == iCurTriAdded); - - iCurSlidingWindowLevel = object->pNextCollapse->ListNext()->iSlidingWindowLevel; - } - - /* - int error_found = -1; - // And now check everything is OK. - R_ASSERT ( result->swr_records.size() == u32(iNumCollapses + 1) ); - for ( int i = 0; i <= iNumCollapses; i++ ){ - VIPM_SWR *swr = result->swr_records.item ( i ); - for ( int j = 0; j < swr->num_tris * 3; j++ ){ - R_ASSERT ( (j+swr->offset) < result->indices.size() ); - // R_ASSERT ( *(result->indices.item(j+swr->offset)) < swr->num_verts ); - if (!(*(result->indices.item(j+swr->offset)) < swr->num_verts )){ - error_found = i; - } - } - } - if (error_found>-1){ - string256 tmp; - for ( int i = 0; i <= iNumCollapses; i++ ){ - VIPM_SWR *swr = result->swr_records.item ( i ); - xr_sprintf(tmp,"SWR %d [T:%d, V:%d, O:%d]\n",i,swr->num_tris,swr->num_verts,swr->offset); - OutputDebugString(tmp); - for ( int j = 0; j < swr->num_tris; j++ ){ - xr_sprintf(tmp,"%d - - [%d,%d,%d]\n",j,*result->indices.item(j*3+0+swr->offset),*result->indices.item(j*3+1+swr->offset),*result->indices.item(j*3+2+swr->offset)); - OutputDebugString(tmp); - } - } - } - */ - - BOOL bRes = TRUE; - // And now check everything is OK. - R_ASSERT(result->swr_records.size() == u32(iNumCollapses + 1)); - for (int i = 0; i <= iNumCollapses; i++) - { - VIPM_SWR* swr = result->swr_records.item(i); - for (int j = 0; j < swr->num_tris * 3; j++) - { - R_ASSERT((j + swr->offset) < result->indices.size()); - swr->num_verts = - std::max(swr->num_verts, *(result->indices.item(j + swr->offset))); // fignya index ne doljen bit bolshe!!! - //. R_ASSERT ( *(result->indices.item(j+swr->offset)) < swr->num_verts ); - if (*(result->indices.item(j + swr->offset)) >= swr->num_verts) - { - bRes = FALSE; - //. OutputDebugString("--ERROR-------------------\n"); - } - } - } - return bRes; -} -//----------------------------------------------------------------------------------------- diff --git a/src/utils/ETools/object_sliding.h b/src/utils/ETools/object_sliding.h deleted file mode 100644 index aaefe149ff7..00000000000 --- a/src/utils/ETools/object_sliding.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef Object_SlidingH -#define Object_SlidingH - -#include "PropSlimTools.h" - -BOOL CalculateSW(Object* object, VIPM_Result* result, u32 optimize_vertex_order); - -#endif // Object_SlidingH diff --git a/src/utils/ETools/packages.config b/src/utils/ETools/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/ETools/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/ETools/quad.h b/src/utils/ETools/quad.h deleted file mode 100644 index 9c069c4f8f1..00000000000 --- a/src/utils/ETools/quad.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -#ifndef quadH -#define quadH - -// This Quad only records the error due to the vertex positions. -// A real implementation needs to use smarter QEMs that take account of -// other vertex attrbiutes such as normals, texture coords, vertex colours, -// etc. Hugues Hoppe's version of this looks like the most complete and simple -// version. -// The algo also needs to do smarter things than just look at QEMs, -// such as prevent normal-flipping, deal with degenerate collapses, -// deal with non-manifold meshes, etc. -// -// But this will do for my purposes because: -// (a) it's simple. -// (b) it's flexible - all vertices have a position. -// (c) it is good enough to give plausable collapse orders. - -struct Quad3 -{ - float A00, A01, A02; - float A11, A12; - float A22; - float B0, B1, B2; - float C; - - Quad3(void) - { - A00 = A01 = A02 = A11 = A12 = A22 = 0.0f; - B0 = B1 = B2 = 0.0f; - C = 0.0f; - } - - // Create a quad from a triangle (numbered clockwise). - Quad3(const Fvector3& vec1, const Fvector3& vec2, const Fvector3& vec3) - { - Fvector3 vec12; - vec12.sub(vec2, vec1); - Fvector3 vec13; - vec13.sub(vec3, vec1); - - Fvector3 vNorm; - vNorm.crossproduct(vec12, vec13); - float fArea = vNorm.magnitude(); - vNorm.div(vNorm, fArea); - // Use the area of the tri, not the parallelogram. - fArea *= 0.5f; - - // Find the distance of the origin from the plane, so that - // P*N + D = 0 - // => D = -P*N - float fDist = -vNorm.dotproduct(vec1); - - // And now form the Quadric. - // A = NNt (and bin the lower half, since it is symmetrical). - // B = D*N - // C = D^2 - // The quadric is weighted by the area of the tri. - A00 = fArea * vNorm.x * vNorm.x; - A01 = fArea * vNorm.x * vNorm.y; - A02 = fArea * vNorm.x * vNorm.z; - A11 = fArea * vNorm.y * vNorm.y; - A12 = fArea * vNorm.y * vNorm.z; - A22 = fArea * vNorm.z * vNorm.z; - B0 = fArea * vNorm.x * fDist; - B1 = fArea * vNorm.y * fDist; - B2 = fArea * vNorm.z * fDist; - C = fArea * fDist * fDist; - } - - const float FindError(const Fvector3& vec) - { - return (A00 * vec.x * vec.x + A01 * vec.x * vec.y * 2 + A02 * vec.x * vec.z * 2 + A11 * vec.y * vec.y + - A12 * vec.y * vec.z * 2 + A22 * vec.z * vec.z + B0 * vec.x * 2 + B1 * vec.y * 2 + B2 * vec.z * 2 + C); - } - - Quad3 operator+(const Quad3& q) - { - Quad3 rq; - rq.A00 = A00 + q.A00; - rq.A01 = A01 + q.A01; - rq.A02 = A02 + q.A02; - rq.A11 = A11 + q.A11; - rq.A12 = A12 + q.A12; - rq.A22 = A22 + q.A22; - rq.B0 = B0 + q.B0; - rq.B1 = B1 + q.B1; - rq.B2 = B2 + q.B2; - rq.C = C + q.C; - return rq; - } - - Quad3& operator+=(const Quad3& q) - { - A00 += q.A00; - A01 += q.A01; - A02 += q.A02; - A11 += q.A11; - A12 += q.A12; - A22 += q.A22; - B0 += q.B0; - B1 += q.B1; - B2 += q.B2; - C += q.C; - return (*this); - } -}; - -#endif // quadH diff --git a/src/utils/Shader_xrLC.h b/src/utils/Shader_xrLC.h deleted file mode 100644 index 35e452aa5dc..00000000000 --- a/src/utils/Shader_xrLC.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma once -#ifndef SHADER_XRLC_H -#define SHADER_XRLC_H - -struct Shader_xrLC -{ - enum - { - flCollision = 1 << 0, - flRendering = 1 << 1, - flOptimizeUV = 1 << 2, - flLIGHT_Vertex = 1 << 3, - flLIGHT_CastShadow = 1 << 4, - flLIGHT_Sharp = 1 << 5, - }; - struct Flags - { - u32 bCollision : 1; - u32 bRendering : 1; - u32 bOptimizeUV : 1; - u32 bLIGHT_Vertex : 1; - u32 bLIGHT_CastShadow : 1; - u32 bLIGHT_Sharp : 1; - }; - - char Name[128]; - union - { - Flags32 m_Flags; - Flags flags; - }; - float vert_translucency; - float vert_ambient; - float lm_density; - - Shader_xrLC() - { - xr_strcpy(Name, "unknown"); - m_Flags.assign(0); - flags.bCollision = TRUE; - flags.bRendering = TRUE; - flags.bOptimizeUV = TRUE; - flags.bLIGHT_Vertex = FALSE; - flags.bLIGHT_CastShadow = TRUE; - flags.bLIGHT_Sharp = TRUE; - vert_translucency = .5f; - vert_ambient = .0f; - lm_density = 1.f; - } -}; - -using Shader_xrLCVec = xr_vector; - -class Shader_xrLC_LIB -{ - Shader_xrLCVec library; - -public: - void Load(LPCSTR name) - { - auto fs = FS.r_open(name); - if (NULL == fs) - { - string256 inf; - extern HWND logWindow; - xr_sprintf(inf, sizeof(inf), "Build failed!\nCan't load shaders library: '%s'", name); - // clMsg (inf); - // MessageBox (logWindow,inf,"Error!",MB_OK|MB_ICONERROR); - FATAL(inf); - return; - }; - - const size_t count = fs->length() / sizeof(Shader_xrLC); - R_ASSERT(fs->length() == count * sizeof(Shader_xrLC)); - library.resize(count); - fs->r(&library.front(), fs->length()); - FS.r_close(fs); - } - bool Save(LPCSTR name) - { - auto F = FS.w_open(name); - if (F) - { - F->w(&library.front(), library.size() * sizeof(Shader_xrLC)); - FS.w_close(F); - return true; - } - return false; - } - void Unload() { library.clear(); } - - size_t GetID(LPCSTR name) const - { - for (auto it = library.begin(); it != library.end(); ++it) - if (0 == xr_stricmp(name, it->Name)) - return size_t(it - library.begin()); - return size_t(-1); - } - - Shader_xrLC* Get(LPCSTR name) - { - for (auto& shader : library) - if (0 == xr_stricmp(name, shader.Name)) - return &shader; - return nullptr; - } - - Shader_xrLC* Get(size_t id) { return &library[id]; } - - const Shader_xrLC* Get(size_t id) const { return &library[id]; } - - Shader_xrLC* Append(Shader_xrLC* parent = 0) - { - library.push_back(parent ? Shader_xrLC(*parent) : Shader_xrLC()); - return &library.back(); - } - - void Remove(LPCSTR name) - { - for (auto it = library.begin(); it != library.end(); ++it) - if (0 == xr_stricmp(name, it->Name)) - { - library.erase(it); - break; - } - } - - void Remove(int id) { library.erase(library.begin() + id); } - - Shader_xrLCVec& Library() { return library; } - - const Shader_xrLCVec& Library() const { return library; } -}; - -#ifdef LEVEL_COMPILER - -IC void post_process_materials( - const Shader_xrLC_LIB& shaders, const xr_vector& shader_compile, xr_vector& materials) -{ - for (size_t m = 0; m < materials.size(); m++) - { - b_material& M = materials[m]; - - if (65535 == M.shader_xrlc) - { - // No compiler shader - M.reserved = u16(-1); - // clMsg (" * %20s",shader_render[M.shader].name); - } - else - { - // clMsg (" * %20s / %-20s",shader_render[M.shader].name, shader_compile[M.shader_xrlc].name); - int id = shaders.GetID(shader_compile[M.shader_xrlc].name); - if (id < 0) - { - Logger.clMsg("ERROR: Shader '%s' not found in library", shader_compile[M.shader].name); - R_ASSERT(id >= 0); - } - M.reserved = u16(id); - } - } -} - -IC const Shader_xrLC& shader(u16 dwMaterial, const Shader_xrLC_LIB& shaders, const xr_vector& materials) -{ - u32 shader_id = materials[dwMaterial].reserved; - return *(shaders.Get(shader_id)); -} - -#endif - -#endif diff --git a/src/utils/communicate.h b/src/utils/communicate.h deleted file mode 100644 index d6bdeea5d35..00000000000 --- a/src/utils/communicate.h +++ /dev/null @@ -1,265 +0,0 @@ -#ifndef _XR_COMM_ -#define _XR_COMM_ - -#include "Common/LevelStructure.hpp" - -#pragma pack(push, 4) - -const u32 XR_MAX_PORTAL_VERTS = 6; - -// internal use -struct b_rc_face -{ - u16 dwMaterial; - u32 dwMaterialGame; - Fvector2 t[3]; // TC - u16 reserved; -}; - -// All types to interact with xrLC -typedef Fvector b_vertex; - -struct b_face -{ - u32 v[3]; // vertices - Fvector2 t[3]; // TC - u16 dwMaterial; // index of material - u32 dwMaterialGame; // unique-ID of game material -}; - -struct b_material -{ - u16 surfidx; // indices of texture surface - u16 shader; // index of shader that combine them - u16 shader_xrlc; // compiler options - u16 sector; // *** - u16 reserved; // - u32 internal_max_area; // -}; - -struct b_shader -{ - string128 name; -}; - -struct b_texture -{ - string128 name; - u32 dwWidth; - u32 dwHeight; - BOOL bHasAlpha; - u32* pSurface; - - b_texture() - : name(), dwWidth(0), dwHeight(0), - bHasAlpha(FALSE), pSurface(nullptr) {} - - b_texture(const b_texture& copy) - : name(), dwWidth(copy.dwWidth), dwHeight(copy.dwHeight), - bHasAlpha(copy.bHasAlpha), pSurface(copy.pSurface) - { - xr_strcpy(name, copy.name); - } - - b_texture(IReader*& file) - { - file->r(&name, sizeof(name)); - dwWidth = file->r_u32(); - dwHeight = file->r_u32(); - file->r(&bHasAlpha, sizeof(bHasAlpha)); - std::uint_least32_t temp = 0; // it should be at least 4 bytes, - file->r(&temp, 4); // so that overflow will not happen - pSurface = nullptr; - } -}; - -struct b_light_control // controller or "layer", 30fps -{ - string64 name; // empty for base layer - u32 count; // 0 for base layer - // u32 data[]; -}; - -struct b_light -{ - u32 controller_ID; // 0 = base layer - Flight data; -}; - -struct b_light_static : public b_light // For static lighting -{ -}; - -struct b_light_dynamic : public b_light // For dynamic models -{ - svector sectors; -}; - -struct b_glow -{ - Fvector P; - float size; - u32 flags; // 0x01 = non scalable - u32 dwMaterial; // index of material -}; - -struct b_portal -{ - u16 sector_front; - u16 sector_back; - svector vertices; -}; - -struct b_lod_face -{ - Fvector v[4]; - Fvector2 t[4]; -}; - -struct b_lod -{ - b_lod_face faces[8]; - u32 dwMaterial; -}; - -/* - u32 NUMBER-OF-OBJECTS - - stringZ name - u32 vert_count - b_vertex vertices[] - u32 face_count - b_faces faces[] - u16 lod_id; // u16(-1) = no lod, just static geometry -*/ -struct b_mu_model -{ - string128 name; - int m_iVertexCount; - b_vertex* m_pVertices; - int m_iFaceCount; - b_face* m_pFaces; - u32* m_smgroups; - u16 lod_id; // u16(-1) = no lod, just static geometry -}; - -/* - self-describing -*/ -struct b_mu_reference -{ - u32 model_index; - Fmatrix transform; - Flags32 flags; - u16 sector; - u32 reserved[8]; -}; - -struct b_params -{ - // Normals & optimization - float m_sm_angle; // normal smooth angle - 89.0 - float m_weld_distance; // by default 0.005f - 5mm - - // Light maps - float m_lm_pixels_per_meter; // LM - by default: 4 ppm - u32 m_lm_jitter_samples; // 1/4/9 - by default - 4 - u32 m_lm_rms_zero; // RMS - after what the lightmap will be shrinked to ZERO pixels - u32 m_lm_rms; // RMS - shrink and recalc - - // build quality - u16 m_quality; - u16 u_reserved; - - // Progressive - float f_reserved[6]; - - void SaveLTX(CInifile& ini) - { - LPCSTR section = "build_params"; - ini.w_float(section, "smooth_angle", m_sm_angle); - ini.w_float(section, "weld_distance", m_weld_distance); - ini.w_float(section, "light_pixel_per_meter", m_lm_pixels_per_meter); - ini.w_u32(section, "light_jitter_samples", m_lm_jitter_samples); - ini.w_u32(section, "light_rms_zero", m_lm_rms_zero); - ini.w_u32(section, "light_rms", m_lm_rms); - ini.w_u16(section, "light_quality", m_quality); - ini.w_u16(section, "light_quality_reserved", u_reserved); - for (u32 i = 0; i < 6; ++i) - { - string128 buff; - xr_sprintf(buff, sizeof(buff), "reserved_%d", i); - ini.w_float(section, buff, f_reserved[i]); - } - } - - void LoadLTX(CInifile& ini) - { - LPCSTR section = "build_params"; - m_sm_angle = ini.r_float(section, "smooth_angle"); - m_weld_distance = ini.r_float(section, "weld_distance"); - m_lm_pixels_per_meter = ini.r_float(section, "light_pixel_per_meter"); - m_lm_jitter_samples = ini.r_u32(section, "light_jitter_samples"); - m_lm_rms_zero = ini.r_u32(section, "light_rms_zero"); - m_lm_rms = ini.r_u32(section, "light_rms"); - m_quality = ini.r_u16(section, "light_quality"); - u_reserved = ini.r_u16(section, "light_quality_reserved"); - for (u32 i = 0; i < 6; ++i) - { - string128 buff; - xr_sprintf(buff, sizeof(buff), "reserved_%d", i); - f_reserved[i] = ini.r_float(section, buff); - } - } - - void Init() - { - // Normals & optimization - m_sm_angle = 75.f; - m_weld_distance = 0.005f; - - // Light maps - m_lm_rms_zero = 4; - m_lm_rms = 4; - - setHighQuality(); - } - - void setDraftQuality() - { - m_quality = ebqDraft; - m_lm_pixels_per_meter = 0.1f; - m_lm_jitter_samples = 1; - } - - void setHighQuality() - { - m_quality = ebqHigh; - m_lm_pixels_per_meter = 10; - m_lm_jitter_samples = 9; - } -}; -#pragma pack(pop) - -enum EBUILD_CHUNKS : u32 -{ - EB_Version = 0, // XRCLC_CURRENT_VERSION - EB_Parameters, - EB_Vertices, - EB_Faces, - EB_Materials, - EB_Shaders_Render, - EB_Shaders_Compile, - EB_Textures, - EB_Glows, - EB_Portals, - EB_Light_control, - EB_Light_static, - EB_Light_dynamic, - EB_LOD_models, - EB_MU_models, - EB_MU_refs, - EB_SmoothGroups, -}; - -#endif diff --git a/src/utils/xrAI/ESceneAIMapTools.cpp b/src/utils/xrAI/ESceneAIMapTools.cpp deleted file mode 100644 index 48747a24a54..00000000000 --- a/src/utils/xrAI/ESceneAIMapTools.cpp +++ /dev/null @@ -1,627 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "ESceneAIMapTools.h" -#include "Common/LevelStructure.hpp" -#include "Scene.h" -#include "UI_LevelMain.h" -#include "UI_LevelTools.h" -#include "ESceneAIMapControls.h" -#include "xrPool.h" - -// chunks -#define AIMAP_VERSION 0x0002 -//---------------------------------------------------- -#define AIMAP_CHUNK_VERSION 0x0001 -#define AIMAP_CHUNK_FLAGS 0x0002 -#define AIMAP_CHUNK_BOX 0x0003 -#define AIMAP_CHUNK_PARAMS 0x0004 -#define AIMAP_CHUNK_NODES 0x0006 -#define AIMAP_CHUNK_SNAP_OBJECTS 0x0007 -#define AIMAP_CHUNK_INTERNAL_DATA 0x0008 -#define AIMAP_CHUNK_INTERNAL_DATA2 0x0009 -//---------------------------------------------------- - -poolSS g_ainode_pool; - -void* SAINode::operator new(std::size_t size) { return g_ainode_pool.create(); } -void* SAINode::operator new(std::size_t size, SAINode* src) { return src; } -void SAINode::operator delete(void* ptr) { g_ainode_pool.destroy((SAINode*)ptr); } -void SAINode::PointLF(Fvector& D, float patch_size) -{ - Fvector d; - d.set(0, -1, 0); - Fvector v = Pos; - float s = patch_size / 2; - v.x -= s; - v.z += s; - Plane.intersectRayPoint(v, d, D); -} - -void SAINode::PointFR(Fvector& D, float patch_size) -{ - Fvector d; - d.set(0, -1, 0); - Fvector v = Pos; - float s = patch_size / 2; - v.x += s; - v.z += s; - Plane.intersectRayPoint(v, d, D); -} - -void SAINode::PointRB(Fvector& D, float patch_size) -{ - Fvector d; - d.set(0, -1, 0); - Fvector v = Pos; - float s = patch_size / 2; - v.x += s; - v.z -= s; - Plane.intersectRayPoint(v, d, D); -} - -void SAINode::PointBL(Fvector& D, float patch_size) -{ - Fvector d; - d.set(0, -1, 0); - Fvector v = Pos; - float s = patch_size / 2; - v.x -= s; - v.z -= s; - Plane.intersectRayPoint(v, d, D); -} - -void SAINode::LoadLTX(CInifile& ini, LPCSTR sect_name, ESceneAIMapTool* tools) { R_ASSERT(0); } -void SAINode::SaveLTX(CInifile& ini, LPCSTR sect_name, ESceneAIMapTool* tools) -{ - R_ASSERT2(0, "dont use it !!!"); - u32 id; - u16 pl; - NodePosition np; - - id = n1 ? (u32)n1->idx : InvalidNode; - ini.w_u32(sect_name, "n1", id); - - id = n2 ? (u32)n2->idx : InvalidNode; - ini.w_u32(sect_name, "n2", id); - - id = n3 ? (u32)n3->idx : InvalidNode; - ini.w_u32(sect_name, "n3", id); - - id = n4 ? (u32)n4->idx : InvalidNode; - ini.w_u32(sect_name, "n4", id); - - pl = pvCompress(Plane.n); - ini.w_u16(sect_name, "plane", pl); - - tools->PackPosition(np, Pos, tools->m_AIBBox, tools->m_Params); - string256 buff; - - s16 x; - u16 y; - s16 z; - - sprintf(buff, "%i,%u,%i", np.x, np.y, np.z); - ini.w_string(sect_name, "np", buff); - ini.w_u8(sect_name, "flag", flags.get()); -} - -void SAINode::LoadStream(IReader& F, ESceneAIMapTool* tools) -{ - u32 id; - u16 pl; - NodePosition np; - F.r(&id, 3); - n1 = (SAINode*)tools->UnpackLink(id); - F.r(&id, 3); - n2 = (SAINode*)tools->UnpackLink(id); - F.r(&id, 3); - n3 = (SAINode*)tools->UnpackLink(id); - F.r(&id, 3); - n4 = (SAINode*)tools->UnpackLink(id); - pl = F.r_u16(); - pvDecompress(Plane.n, pl); - F.r(&np, sizeof(np)); - tools->UnpackPosition(Pos, np, tools->m_AIBBox, tools->m_Params); - Plane.build(Pos, Plane.n); - flags.assign(F.r_u8()); -} - -void SAINode::SaveStream(IWriter& F, ESceneAIMapTool* tools) -{ - u32 id; - u16 pl; - NodePosition np; - - id = n1 ? (u32)n1->idx : InvalidNode; - F.w(&id, 3); - id = n2 ? (u32)n2->idx : InvalidNode; - F.w(&id, 3); - id = n3 ? (u32)n3->idx : InvalidNode; - F.w(&id, 3); - id = n4 ? (u32)n4->idx : InvalidNode; - F.w(&id, 3); - pl = pvCompress(Plane.n); - F.w_u16(pl); - tools->PackPosition(np, Pos, tools->m_AIBBox, tools->m_Params); - F.w(&np, sizeof(np)); - F.w_u8(flags.get()); -} - -ESceneAIMapTool::ESceneAIMapTool() : ESceneToolBase(OBJCLASS_AIMAP) -{ - m_Shader = 0; - m_Flags.zero(); - - m_AIBBox.invalidate(); - // m_Header.size_y = m_Header.aabb.max.y-m_Header.aabb.min.y+EPS_L; - hash_Initialize(); - m_VisRadius = 30.f; - m_SmoothHeight = 0.5f; - m_BrushSize = 1; - m_CFModel = 0; -} - -//---------------------------------------------------- - -ESceneAIMapTool::~ESceneAIMapTool() {} -//---------------------------------------------------- - -void ESceneAIMapTool::Clear(bool bOnlyNodes) -{ - inherited::Clear(); - hash_Clear(); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - xr_delete(*it); - m_Nodes.clear(); - if (!bOnlyNodes) - { - m_SnapObjects.clear(); - m_AIBBox.invalidate(); - ExecCommand(COMMAND_REFRESH_SNAP_OBJECTS); - g_ainode_pool.clear(); - } -} - -//---------------------------------------------------- - -void ESceneAIMapTool::CalculateNodesBBox(Fbox& bb) -{ - bb.invalidate(); - for (AINodeIt b_it = m_Nodes.begin(); b_it != m_Nodes.end(); ++b_it) - { - VERIFY(_valid((*b_it)->Pos)); - bb.modify((*b_it)->Pos); - } -} - -//---------------------------------------------------- -extern BOOL ai_map_shown; - -void ESceneAIMapTool::OnActivate() -{ - inherited::OnActivate(); - ai_map_shown = TRUE; -} - -void ESceneAIMapTool::OnFrame() -{ - if (m_Flags.is(flUpdateHL)) - { - m_Flags.set(flUpdateHL, FALSE); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - (*it)->flags.set(SAINode::flHLSelected, FALSE); - for (it = m_Nodes.begin(); it != m_Nodes.end(); it++) - { - SAINode& N = **it; - if (N.flags.is(SAINode::flSelected)) - for (int k = 0; k < 4; k++) - if (N.n[k]) - N.n[k]->flags.set(SAINode::flHLSelected, TRUE); - } - } - if (m_Flags.is(flUpdateSnapList)) - RealUpdateSnapList(); -} - -//---------------------------------------------------- - -void ESceneAIMapTool::EnumerateNodes() -{ - u32 idx = 0; - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++, idx++) - (*it)->idx = idx; -} - -void ESceneAIMapTool::DenumerateNodes() -{ - u32 cnt = m_Nodes.size(); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - { - if (!((((u32)(*it)->n1 < cnt) || ((u32)(*it)->n1 == InvalidNode)) && - (((u32)(*it)->n2 < cnt) || ((u32)(*it)->n2 == InvalidNode)) && - (((u32)(*it)->n3 < cnt) || ((u32)(*it)->n3 == InvalidNode)) && - (((u32)(*it)->n4 < cnt) || ((u32)(*it)->n4 == InvalidNode)))) - { - ELog.Msg(mtError, "Node: has wrong link [%3.2f, %3.2f, %3.2f], {%d,%d,%d,%d}", VPUSH((*it)->Pos), (*it)->n1, - (*it)->n2, (*it)->n3, (*it)->n4); - (*it)->n1 = 0; - (*it)->n2 = 0; - (*it)->n3 = 0; - (*it)->n4 = 0; - continue; - } - // ,"AINode: Wrong link found."); - (*it)->n1 = ((u32)(*it)->n1 == InvalidNode) ? 0 : m_Nodes[(u32)(*it)->n1]; - (*it)->n2 = ((u32)(*it)->n2 == InvalidNode) ? 0 : m_Nodes[(u32)(*it)->n2]; - (*it)->n3 = ((u32)(*it)->n3 == InvalidNode) ? 0 : m_Nodes[(u32)(*it)->n3]; - (*it)->n4 = ((u32)(*it)->n4 == InvalidNode) ? 0 : m_Nodes[(u32)(*it)->n4]; - /* - if (((u32)(*it)->n1n1==InvalidNode)) (*it)->n1 = - ((u32)(*it)->n1==InvalidNode)?0:m_Nodes[(u32)(*it)->n1]; - else (*it)->n1=0; - if (((u32)(*it)->n2n2==InvalidNode)) (*it)->n2 = - ((u32)(*it)->n2==InvalidNode)?0:m_Nodes[(u32)(*it)->n2]; - else (*it)->n2=0; - if (((u32)(*it)->n3n3==InvalidNode)) (*it)->n3 = - ((u32)(*it)->n3==InvalidNode)?0:m_Nodes[(u32)(*it)->n3]; - else (*it)->n3=0; - if (((u32)(*it)->n4n4==InvalidNode)) (*it)->n4 = - ((u32)(*it)->n4==InvalidNode)?0:m_Nodes[(u32)(*it)->n4]; - else (*it)->n4=0; - */ - } -} - -bool ESceneAIMapTool::LoadLTX(CInifile& ini) -{ - R_ASSERT(0); - return true; -} - -void ESceneAIMapTool::SaveLTX(CInifile& ini, int id) -{ - inherited::SaveLTX(ini, id); - - ini.w_u32("main", "version", AIMAP_VERSION); - ini.w_u32("main", "flags", m_Flags.get()); - - ini.w_fvector3("main", "bbox_min", m_AIBBox.min); - ini.w_fvector3("main", "bbox_max", m_AIBBox.max); - - ini.w_float("params", "patch_size", m_Params.fPatchSize); - ini.w_float("params", "test_height", m_Params.fTestHeight); - ini.w_float("params", "can_up", m_Params.fCanUP); - ini.w_float("params", "can_down", m_Params.fCanDOWN); - - EnumerateNodes(); - ini.w_u32("main", "nodes_count", m_Nodes.size()); - - u32 i = 0; - string128 buff; - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); ++it, ++i) - { - sprintf(buff, "n_%d", i); - (*it)->SaveLTX(ini, buff, this); - } - - ini.w_float("main", "vis_radius", m_VisRadius); - ini.w_u32("main", "brush_size", m_BrushSize); - - ini.w_float("main", "smooth_height", m_SmoothHeight); - - for (ObjectIt o_it = m_SnapObjects.begin(); o_it != m_SnapObjects.end(); ++o_it) - ini.w_string("snap_objects", (*o_it)->Name, NULL); -} - -bool ESceneAIMapTool::LoadStream(IReader& F) -{ - inherited::LoadStream(F); - - u16 version = 0; - - R_ASSERT(F.r_chunk(AIMAP_CHUNK_VERSION, &version)); - if (version != AIMAP_VERSION) - { - ELog.DlgMsg(mtError, "AIMap: Unsupported version."); - return false; - } - - R_ASSERT(F.find_chunk(AIMAP_CHUNK_FLAGS)); - F.r(&m_Flags, sizeof(m_Flags)); - - R_ASSERT(F.find_chunk(AIMAP_CHUNK_BOX)); - F.r(&m_AIBBox, sizeof(m_AIBBox)); - - R_ASSERT(F.find_chunk(AIMAP_CHUNK_PARAMS)); - F.r(&m_Params, sizeof(m_Params)); - - R_ASSERT(F.find_chunk(AIMAP_CHUNK_NODES)); - m_Nodes.resize(F.r_u32()); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - { - *it = xr_new(); - (*it)->LoadStream(F, this); - } - DenumerateNodes(); - - if (F.find_chunk(AIMAP_CHUNK_INTERNAL_DATA)) - { - m_VisRadius = F.r_float(); - m_BrushSize = F.r_u32(); - } - if (F.find_chunk(AIMAP_CHUNK_INTERNAL_DATA2)) - { - m_SmoothHeight = F.r_float(); - } - - // snap objects - if (F.find_chunk(AIMAP_CHUNK_SNAP_OBJECTS)) - { - shared_str buf; - int cnt = F.r_u32(); - if (cnt) - { - for (int i = 0; i < cnt; i++) - { - F.r_stringZ(buf); - CCustomObject* O = Scene->FindObjectByName(buf.c_str(), OBJCLASS_SCENEOBJECT); - if (!O) - ELog.Msg(mtError, "AIMap: Can't find snap object '%s'.", buf.c_str()); - else - m_SnapObjects.push_back(O); - } - } - } - - hash_FillFromNodes(); - - return true; -} - -//---------------------------------------------------- - -bool ESceneAIMapTool::LoadSelection(IReader& F) -{ - Clear(); - return LoadStream(F); -} - -void ESceneAIMapTool::OnSynchronize() { RealUpdateSnapList(); } -//---------------------------------------------------- - -void ESceneAIMapTool::SaveStream(IWriter& F) -{ - inherited::SaveStream(F); - - F.open_chunk(AIMAP_CHUNK_VERSION); - F.w_u16(AIMAP_VERSION); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_FLAGS); - F.w(&m_Flags, sizeof(m_Flags)); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_BOX); - F.w(&m_AIBBox, sizeof(m_AIBBox)); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_PARAMS); - F.w(&m_Params, sizeof(m_Params)); - F.close_chunk(); - - EnumerateNodes(); - F.open_chunk(AIMAP_CHUNK_NODES); - F.w_u32(m_Nodes.size()); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - (*it)->SaveStream(F, this); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_INTERNAL_DATA); - F.w_float(m_VisRadius); - F.w_u32(m_BrushSize); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_INTERNAL_DATA2); - F.w_float(m_SmoothHeight); - F.close_chunk(); - - F.open_chunk(AIMAP_CHUNK_SNAP_OBJECTS); - F.w_u32(m_SnapObjects.size()); - for (ObjectIt o_it = m_SnapObjects.begin(); o_it != m_SnapObjects.end(); o_it++) - F.w_stringZ((*o_it)->Name); - F.close_chunk(); -} - -//---------------------------------------------------- - -void ESceneAIMapTool::SaveSelection(IWriter& F) { SaveStream(F); } -bool ESceneAIMapTool::Valid() { return !m_Nodes.empty(); } -bool ESceneAIMapTool::IsNeedSave() { return (!m_Nodes.empty() || !m_SnapObjects.empty()); } -void ESceneAIMapTool::OnObjectRemove(CCustomObject* O, bool bDeleting) -{ - if (OBJCLASS_SCENEOBJECT == O->ClassID) - { - if (find(m_SnapObjects.begin(), m_SnapObjects.end(), O) != m_SnapObjects.end()) - { - m_SnapObjects.remove(O); - RealUpdateSnapList(); - } - } -} - -int ESceneAIMapTool::AddNode(const Fvector& pos, bool bIgnoreConstraints, bool bAutoLink, int sz) -{ - Fvector Pos = pos; - if (1 == sz) - { - SAINode* N = BuildNode(Pos, Pos, bIgnoreConstraints, true); - if (N) - { - N->flags.set(SAINode::flSelected, TRUE); - if (bAutoLink) - UpdateLinks(N, bIgnoreConstraints); - return 1; - } - else - { - ELog.Msg(mtError, "Can't create node."); - return 0; - } - } - else - { - return BuildNodes(Pos, sz, bIgnoreConstraints); - } -} - -struct invalid_node_pred : public std::unary_function -{ - int link; - - invalid_node_pred(int _link) : link(_link) { ; } - bool operator()(const SAINode*& x) { return x->Links() == link; } -}; - -void ESceneAIMapTool::SelectNodesByLink(int link) -{ - SelectObjects(false); - // remove link to sel nodes - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - if ((*it)->Links() == link) - // if (!(*it)->flags.is(SAINode::flHide)) - (*it)->flags.set(SAINode::flSelected, TRUE); - UI->RedrawScene(); -} - -void ESceneAIMapTool::SelectObjects(bool flag) -{ - switch (LTools->GetSubTarget()) - { - case estAIMapNode: - { - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - // if (!(*it)->flags.is(SAINode::flHide)) - (*it)->flags.set(SAINode::flSelected, flag); - } - break; - } - UpdateHLSelected(); - UI->RedrawScene(); -} - -struct delete_sel_node_pred : public std::unary_function -{ - bool operator()(SAINode*& x) - { - // breaking links - for (int k = 0; k < 4; k++) - if (x->n[k] && x->n[k]->flags.is(SAINode::flSelected)) - x->n[k] = 0; - // free memory - bool res = x->flags.is(SAINode::flSelected); - if (res) - xr_delete(x); - return res; - } -}; - -void ESceneAIMapTool::RemoveSelection() -{ - switch (LTools->GetSubTarget()) - { - case estAIMapNode: - { - if (m_Nodes.size() == (u32)SelectionCount(true)) - { - Clear(true); - } - else - { - SPBItem* pb = UI->ProgressStart(3, "Removing nodes..."); - // remove link to sel nodes - pb->Inc("erasing nodes"); - // remove sel nodes - AINodeIt result = std::remove_if(m_Nodes.begin(), m_Nodes.end(), delete_sel_node_pred()); - m_Nodes.erase(result, m_Nodes.end()); - pb->Inc("updating hash"); - hash_Clear(); - hash_FillFromNodes(); - pb->Inc("end"); - UI->ProgressEnd(pb); - } - } - break; - } - UpdateHLSelected(); - UI->RedrawScene(); -} - -void ESceneAIMapTool::InvertSelection() -{ - switch (LTools->GetSubTarget()) - { - case estAIMapNode: - { - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - // if (!(*it)->flags.is(SAINode::flHide)) - (*it)->flags.invert(SAINode::flSelected); - } - break; - } - UpdateHLSelected(); - UI->RedrawScene(); -} - -int ESceneAIMapTool::SelectionCount(bool testflag) -{ - int count = 0; - switch (LTools->GetSubTarget()) - { - case estAIMapNode: - { - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - if ((*it)->flags.is(SAINode::flSelected) == testflag) - count++; - } - break; - } - return count; -} - -void ESceneAIMapTool::FillProp(LPCSTR pref, PropItemVec& items) -{ - PHelper().CreateFlag32( - items, PrepareKey(pref, "Common\\Draw Nodes"), &m_Flags, flHideNodes, 0, 0, FlagValueCustom::flInvertedDraw); - PHelper().CreateFlag32(items, PrepareKey(pref, "Common\\Slow Calculate Mode"), &m_Flags, flSlowCalculate); - PHelper().CreateFloat(items, PrepareKey(pref, "Common\\Visible Radius"), &m_VisRadius, 10.f, 250.f); - PHelper().CreateFloat(items, PrepareKey(pref, "Common\\Smooth Height"), &m_SmoothHeight, 0.1f, 100.f); - - PHelper().CreateU32(items, PrepareKey(pref, "Params\\Brush Size"), &m_BrushSize, 1, 100); - PHelper().CreateFloat(items, PrepareKey(pref, "Params\\Can Up"), &m_Params.fCanUP, 0.f, 10.f); - PHelper().CreateFloat(items, PrepareKey(pref, "Params\\Can Down"), &m_Params.fCanDOWN, 0.f, 10.f); -} - -void ESceneAIMapTool::GetBBox(Fbox& bb, bool bSelOnly) -{ - switch (LTools->GetSubTarget()) - { - case estAIMapNode: - { - if (bSelOnly) - { - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - if ((*it)->flags.is(SAINode::flSelected)) - { - bb.modify(Fvector().add((*it)->Pos, -m_Params.fPatchSize * 0.5f)); - bb.modify(Fvector().add((*it)->Pos, m_Params.fPatchSize * 0.5f)); - } - } - else - { - bb.merge(m_AIBBox); - } - } - break; - } -} diff --git a/src/utils/xrAI/ESceneAIMapTools.h b/src/utils/xrAI/ESceneAIMapTools.h deleted file mode 100644 index 755cb59a040..00000000000 --- a/src/utils/xrAI/ESceneAIMapTools.h +++ /dev/null @@ -1,253 +0,0 @@ -//---------------------------------------------------- -// file: rpoint.h -//---------------------------------------------------- -#ifndef ESceneAIMapToolsH -#define ESceneAIMapToolsH - -#include "ESceneCustomMTools.H" -#include "Common/LevelStructure.hpp" -#include "ESceneAIMapTools_Export.H" - -// refs -class ESceneAIMapTool; -struct SAINode; - -const u32 InvalidNode = (1 << 24) - 1; - -#pragma pack(push, 1) -struct SAINode // definition of "patch" or "node" -{ - union - { - struct - { - SAINode* n1; // Left - SAINode* n2; // Forward - SAINode* n3; // Right - SAINode* n4; // Backward - }; - - SAINode* n[4]; - }; - - Fplane Plane; // plane of patch - Fvector Pos; // position of patch center - - enum - { - flSelected = (1 << 0), - flHLSelected = (1 << 1), - // flHide = (1<<2), // obsolette - - flN1 = (1 << 4), - flN2 = (1 << 5), - flN3 = (1 << 6), - flN4 = (1 << 7), - }; - - Flags8 flags; - u32 idx; - - SAINode() - { - n1 = n2 = n3 = n4 = 0; - idx = 0; - flags.zero(); - } - - SAINode* nLeft() { return n1; } - SAINode* nForward() { return n2; } - SAINode* nRight() { return n3; } - SAINode* nBack() { return n4; } - int Links() const - { - int cnt = 0; - for (int k = 0; k < 4; k++) - if (n[k]) - cnt++; - return cnt; - } - - void PointLF(Fvector& D, float patch_size); - void PointFR(Fvector& D, float patch_size); - void PointRB(Fvector& D, float patch_size); - void PointBL(Fvector& D, float patch_size); - - void LoadStream(IReader&, ESceneAIMapTool*); - void SaveStream(IWriter&, ESceneAIMapTool*); - void LoadLTX(CInifile& ini, LPCSTR sect_name, ESceneAIMapTool*); - void SaveLTX(CInifile& ini, LPCSTR sect_name, ESceneAIMapTool*); - - void* operator new(std::size_t size); - void* operator new(std::size_t size, SAINode*); - void operator delete(void*); -}; -#pragma pack(pop) - -DEFINE_VECTOR(SAINode*, AINodeVec, AINodeIt); - -const int HDIM_X = 128; -const int HDIM_Z = 128; - -class ESceneAIMapTool : public ESceneToolBase -{ - friend class SAINode; - typedef ESceneToolBase inherited; - ObjectList m_SnapObjects; - // hash - AINodeVec m_HASH[HDIM_X + 1][HDIM_Z + 1]; - AINodeVec m_Nodes; - - SAIParams m_Params; - Fbox m_AIBBox; - - ref_geom m_RGeom; - ref_shader m_Shader; - CDB::MODEL* m_CFModel; - -protected: - void hash_FillFromNodes(); - void hash_Initialize(); - void hash_Clear(); - void HashRect(const Fvector& v, float radius, Irect& result); - AINodeVec* HashMap(int ix, int iz); - AINodeVec* HashMap(Fvector& V); - SAINode* FindNode(Fvector& vAt, float eps = 0.05f); - SAINode* FindNeighbor(SAINode* N, int side, bool bIgnoreConstraints); - void MotionSimulate(Fvector& result, Fvector& start, Fvector& end, float _radius, float _height); - - SAINode* BuildNode(Fvector& vFrom, Fvector& vAt, bool bIgnoreConstraints, bool bSuperIgnoreConstraints = false); - int BuildNodes(const Fvector& pos, int sz, bool bIgnoreConstraints); - void BuildNodes(bool bFromSelectedOnly); - BOOL CreateNode(Fvector& vAt, SAINode& N, bool bIgnoreConstraints); - BOOL CanTravel(Fvector _from, Fvector _at); - - SAINode* GetNode(Fvector vAt, bool bIgnoreConstraints); - void UpdateLinks(SAINode* N, bool bIgnoreConstraints); - - void UnpackPosition(Fvector& Pdest, const NodePosition& Psrc, Fbox& bb, SAIParams& params); - u32 UnpackLink(u32& L); - void PackPosition(NodePosition& Dest, Fvector& Src, Fbox& bb, SAIParams& params); - - void EnumerateNodes(); - void DenumerateNodes(); - - bool RealUpdateSnapList(); - int RemoveOutOfBoundsNodes(); - - void CalculateNodesBBox(Fbox& bb); - - // controls - virtual void CreateControls(); - virtual void RemoveControls(); - -public: - enum EMode - { - mdAppend, - mdRemove, - mdInvert, - }; - - enum - { - flUpdateSnapList = (1 << 0), - flHideNodes = (1 << 1), - flSlowCalculate = (1 << 2), - flUpdateHL = (1 << 15), - }; - - Flags32 m_Flags; - - float m_VisRadius; - float m_SmoothHeight; - u32 m_BrushSize; - xr_vector m_ignored_materials; - - bool PickObjects(Fvector& dest, const Fvector& start, const Fvector& dir, float dist); - -public: - ESceneAIMapTool(); - virtual ~ESceneAIMapTool(); - - virtual bool AllowEnabling() { return true; } - virtual BOOL AllowMouseStart() { return true; } - virtual void OnObjectRemove(CCustomObject* O, bool bDeleting); - - virtual void UpdateSnapList() { m_Flags.set(flUpdateSnapList, TRUE); } - virtual ObjectList* GetSnapList() { return &m_SnapObjects; } - // selection manipulate - SAINode* PickNode(const Fvector& start, const Fvector& dir, float& dist); - virtual int RaySelect( - int flag, float& distance, const Fvector& start, const Fvector& direction, BOOL bDistanceOnly); - virtual int FrustumSelect(int flag, const CFrustum& frustum); - virtual void SelectObjects(bool flag); - virtual void InvertSelection(); - virtual void RemoveSelection(); - virtual int SelectionCount(bool testflag); - - virtual void ShowObjects(bool flag, bool bAllowSelectionFlag = false, bool bSelFlag = true) {} - virtual void Clear(bool bOnlyNodes = false); - - // definition - IC LPCSTR ClassName() { return "ai_map"; } - IC LPCSTR ClassDesc() { return "AI Map"; } - IC - - int - RenderPriority() - { - return 10; - } - - // validation - virtual bool Valid(); - - virtual bool Validate(bool) { return true; } - virtual bool IsNeedSave(); - - // events - virtual void OnFrame(); - virtual void OnRender(int priority, bool strictB2F); - virtual void OnActivate(); - - // IO - virtual bool LoadStream(IReader&); - virtual bool LoadLTX(CInifile&); - virtual void SaveStream(IWriter&); - virtual void SaveLTX(CInifile&, int id); - - virtual bool can_use_inifile() { return false; } - virtual bool LoadSelection(IReader&); - virtual void SaveSelection(IWriter&); - virtual bool Export(LPCSTR path); - - // device dependent funcs - virtual void OnDeviceCreate(); - virtual void OnDeviceDestroy(); - - virtual void OnSynchronize(); - - // utils - bool GenerateMap(bool bFromSelectedOnly); - - virtual bool GetSummaryInfo(SSceneSummary* inf) { return false; } - virtual void GetBBox(Fbox& bb, bool bSelOnly); - - // properties - virtual void FillProp(LPCSTR pref, PropItemVec& items); - - // other - int AddNode(const Fvector& pos, bool bIgnoreConstraints, bool bAutoLink, int cnt); - - AINodeVec& Nodes() { return m_Nodes; } - void MakeLinks(u8 side_flag, EMode mode, bool bIgnoreConstraints); - void RemoveLinks(); - void InvertLinks(); - - void UpdateHLSelected() { m_Flags.set(flUpdateHL, TRUE); } - void SmoothNodes(); - void ResetNodes(); - void SelectNodesByLink(int link); -}; -#endif // ESceneAIMapToolsH diff --git a/src/utils/xrAI/ESceneAIMapTools_Export.cpp b/src/utils/xrAI/ESceneAIMapTools_Export.cpp deleted file mode 100644 index 45214a547a3..00000000000 --- a/src/utils/xrAI/ESceneAIMapTools_Export.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "ESceneAIMapTools_Export.h" -#include "ESceneAIMapTools.h" - -void ESceneAIMapTool::UnpackPosition(Fvector& Pdest, const NodePosition& Psrc, Fbox& bb, SAIParams& params) -{ - Pdest.x = float(Psrc.x) * params.fPatchSize; - Pdest.y = (float(Psrc.y) / 65535) * (bb.max.y - bb.min.y) + bb.min.y; - Pdest.z = float(Psrc.z) * params.fPatchSize; -} - -u32 ESceneAIMapTool::UnpackLink(u32& L) { return L & 0x00ffffff; } -void ESceneAIMapTool::PackPosition(NodePosition& Dest, Fvector& Src, Fbox& bb, SAIParams& params) -{ - float sp = 1 / params.fPatchSize; - int px, py, pz; - px = iFloor(Src.x * sp + EPS_L); - py = iFloor(65535.f * (Src.y - bb.min.y) / (bb.max.y - bb.min.y) + EPS_L); - pz = iFloor(Src.z * sp + EPS_L); - - clamp(px, -32767, 32767); - Dest.x = s16(px); - clamp(py, 0, 65535); - Dest.y = u16(py); - clamp(pz, -32767, 32767); - Dest.z = s16(pz); -} - -bool ESceneAIMapTool::Export(LPCSTR path) -{ - //.? if (!RealUpdateSnapList()) return false; - if (!Valid()) - return false; - - // calculate bbox - Fbox bb; - CalculateNodesBBox(bb); - - AnsiString fn = AnsiString(path) + "build.aimap"; - - // export - IWriter* F = FS.w_open(fn.c_str()); - - if (F) - { - F->open_chunk(E_AIMAP_CHUNK_VERSION); - F->w_u16(E_AIMAP_VERSION); - F->close_chunk(); - - F->open_chunk(E_AIMAP_CHUNK_BOX); - F->w(&bb, sizeof(bb)); - F->close_chunk(); - - F->open_chunk(E_AIMAP_CHUNK_PARAMS); - F->w(&m_Params, sizeof(m_Params)); - F->close_chunk(); - - EnumerateNodes(); - F->open_chunk(E_AIMAP_CHUNK_NODES); - F->w_u32(m_Nodes.size()); - for (AINodeIt it = m_Nodes.begin(); it != m_Nodes.end(); it++) - { - u32 id; - u16 pl; - NodePosition np; - - id = (*it)->n1 ? (u32)(*it)->n1->idx : InvalidNode; - F->w(&id, 3); - id = (*it)->n2 ? (u32)(*it)->n2->idx : InvalidNode; - F->w(&id, 3); - id = (*it)->n3 ? (u32)(*it)->n3->idx : InvalidNode; - F->w(&id, 3); - id = (*it)->n4 ? (u32)(*it)->n4->idx : InvalidNode; - F->w(&id, 3); - pl = pvCompress((*it)->Plane.n); - F->w_u16(pl); - PackPosition(np, (*it)->Pos, bb, m_Params); - F->w(&np, sizeof(np)); - } - F->close_chunk(); - - FS.w_close(F); - return true; - } - return false; -} - -/* - u32 id; - u16 pl; - NodePosition np; - F.r (&id,3); n1 = (SAINode*)tools->UnpackLink(id); - F.r (&id,3); n2 = (SAINode*)tools->UnpackLink(id); - F.r (&id,3); n3 = (SAINode*)tools->UnpackLink(id); - F.r (&id,3); n4 = (SAINode*)tools->UnpackLink(id); - pl = F.r_u16(); pvDecompress(Plane.n,pl); - F.r (&np,sizeof(np)); tools->UnpackPosition(Pos,np,tools->m_BBox,tools->m_Params); - Plane.build (Pos,Plane.n); -*/ diff --git a/src/utils/xrAI/ESceneAIMapTools_Export.h b/src/utils/xrAI/ESceneAIMapTools_Export.h deleted file mode 100644 index d94bc9de4ec..00000000000 --- a/src/utils/xrAI/ESceneAIMapTools_Export.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef ESceneAIMapTools_ExportH -#define ESceneAIMapTools_ExportH - -//---------------------------------------------------- -struct SAIParams -{ - float fPatchSize; // patch size - float fTestHeight; // test height (center of the "tester") - float fCanUP; // can reach point in up (dist) - float fCanDOWN; // can reach point down (dist) - - SAIParams() - { - fPatchSize = 0.7f; - fTestHeight = 1.0f; - fCanUP = 1.5f; - fCanDOWN = 4.0f; - } -}; - -// chunks -#define E_AIMAP_VERSION 0x0001 -//---------------------------------------------------- -#define E_AIMAP_CHUNK_VERSION 0x0001 -#define E_AIMAP_CHUNK_BOX 0x0002 -#define E_AIMAP_CHUNK_PARAMS 0x0003 -#define E_AIMAP_CHUNK_NODES 0x0004 -//---------------------------------------------------- -#endif diff --git a/src/utils/xrAI/ESceneClassList.h b/src/utils/xrAI/ESceneClassList.h deleted file mode 100644 index b4cb8f11cb3..00000000000 --- a/src/utils/xrAI/ESceneClassList.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef ESceneClassListH -#define ESceneClassListH - -// refs -class CCustomObject; - -typedef u32 ObjClassID; - -//---------------------------------------------------- -enum : u32 -{ - OBJCLASS_DUMMY = -1, - OBJCLASS_FIRST_CLASS = 0, - OBJCLASS_GROUP = 0, - OBJCLASS_GLOW = 1, - OBJCLASS_SCENEOBJECT = 2, - OBJCLASS_LIGHT = 3, - OBJCLASS_SHAPE = 4, - OBJCLASS_SOUND_SRC = 5, - OBJCLASS_SPAWNPOINT = 6, - OBJCLASS_WAY = 7, - OBJCLASS_SECTOR = 8, - OBJCLASS_PORTAL = 9, - OBJCLASS_SOUND_ENV = 10, - OBJCLASS_PS = 11, - OBJCLASS_DO = 12, - OBJCLASS_AIMAP = 13, - OBJCLASS_WM = 14, - OBJCLASS_FOG_VOL = 15, - OBJCLASS_COUNT = 16, -}; - -//---------------------------------------------------- - -typedef xr_list ObjectList; -typedef ObjectList::iterator ObjectIt; -typedef xr_map ObjectMap; -typedef ObjectMap::iterator ObjectPairIt; - -#endif diff --git a/src/utils/xrAI/ESceneCustomMTools.cpp b/src/utils/xrAI/ESceneCustomMTools.cpp deleted file mode 100644 index 32468beffcd..00000000000 --- a/src/utils/xrAI/ESceneCustomMTools.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "ESceneCustomMTools.h" -#include "editors/ECore/Editor/ui_main.h" -#include "UI_LevelMain.h" -#include "scene.h" - -#define CHUNK_TOOLS_TAG 0x7777 - -ESceneToolBase::ESceneToolBase(ObjClassID cls) -{ - ClassID = cls; - // controls - sub_target = 0; - pCurControl = 0; - pFrame = 0; - action = -1; - m_EditFlags.assign(flEnable | flVisible); - m_ModifName = ""; - m_ModifTime = 0; -} - -ESceneToolBase::~ESceneToolBase() {} -void ESceneToolBase::Clear(bool bSpecific) -{ - m_ModifName = ""; - m_ModifTime = 0; -} - -void ESceneToolBase::Reset() -{ - Clear(); - m_EditFlags.set(flReadonly, FALSE); -} - -void ESceneToolBase::OnCreate() -{ - OnDeviceCreate(); - CreateControls(); -} - -void ESceneToolBase::OnDestroy() -{ - OnDeviceDestroy(); - RemoveControls(); -} - -bool ESceneToolBase::LoadLTX(CInifile& ini) -{ - m_ModifName = ini.r_string("modif", "name"); - m_ModifTime = ini.r_u32("modif", "time"); - return true; -} - -void ESceneToolBase::SaveLTX(CInifile& ini, int id) -{ - ini.w_string("modif", "name", m_ModifName.c_str()); - ini.w_u32("modif", "time", m_ModifTime); -} - -bool ESceneToolBase::LoadStream(IReader& F) -{ - if (F.find_chunk(CHUNK_TOOLS_TAG)) - { - F.r_stringZ(m_ModifName); - F.r(&m_ModifTime, sizeof(m_ModifTime)); - } - else - { - m_ModifName = ""; - m_ModifTime = 0; - } - return true; -} - -void ESceneToolBase::SaveStream(IWriter& F) -{ - /* - xr_string mn = AnsiString().sprintf("\\\\%s\\%s",Core.CompName,Core.UserName).c_str(); - time_t mt = time(NULL); - - F.open_chunk(CHUNK_TOOLS_TAG); - F.w_stringZ (mn); - F.w (&mt,sizeof(mt)); - F.close_chunk(); - */ -} diff --git a/src/utils/xrAI/ESceneCustomMTools.h b/src/utils/xrAI/ESceneCustomMTools.h deleted file mode 100644 index c8acc277a62..00000000000 --- a/src/utils/xrAI/ESceneCustomMTools.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef ESceneCustomMToolsH -#define ESceneCustomMToolsH - -#include "ESceneClassList.h" -// refs -struct SSceneSummary; -class TUI_CustomControl; -class ESceneCustomMTools; -class SceneBuilder; -struct SExportStreams; -struct mesh_build_data; -DEFINE_VECTOR(TUI_CustomControl*, ControlsVec, ControlsIt); - -class ESceneToolBase -{ - ObjClassID FClassID; - -protected: - // controls - ControlsVec m_Controls; - int action; - int sub_target; - -public: - enum - { - flEnable = (1 << 0), - flReadonly = (1 << 1), - flForceReadonly = (1 << 2), - flChanged = (1 << 3), - flVisible = (1 << 4), - }; - - Flags32 m_EditFlags; - - BOOL IsEnabled() { return m_EditFlags.is(flEnable); } - BOOL IsEditable() { return !m_EditFlags.is_any(flReadonly | flForceReadonly); } - BOOL IsReadonly() { return m_EditFlags.is(flReadonly); } - BOOL IsForceReadonly() { return m_EditFlags.is(flForceReadonly); } - BOOL IsChanged() { return m_EditFlags.is(flChanged); } - void SetChanged(BOOL b) { m_EditFlags.set(flChanged, b); } - BOOL IsVisible() { return m_EditFlags.is(flVisible); } - virtual BOOL AllowMouseStart() = 0; - -public: - // modifiers - shared_str m_ModifName; - time_t m_ModifTime; - // frame & Controls - TUI_CustomControl* pCurControl; - TForm* pFrame; - -protected: - void AddControl(TUI_CustomControl* c); - TUI_CustomControl* FindControl(int subtarget, int action); - void UpdateControl(); - -public: - void SetAction(int action); - void SetSubTarget(int target); - void ResetSubTarget(); - -protected: - void CreateDefaultControls(u32 sub_target_id); - virtual void CreateControls() = 0; - virtual void RemoveControls(); - -public: - virtual void OnActivate(); - virtual void OnDeactivate(); - - virtual void OnObjectsUpdate() { ; } -public: - PropertyGP(FClassID, FClassID) ObjClassID ClassID; - // definition - virtual LPCSTR ClassName() = 0; - virtual LPCSTR ClassDesc() = 0; - virtual int RenderPriority() = 0; - -public: - ESceneToolBase(ObjClassID cls); - virtual ~ESceneToolBase(); - - virtual void OnCreate(); - virtual void OnDestroy(); - - virtual bool AllowEnabling() = 0; - // snap - virtual ObjectList* GetSnapList() = 0; - virtual void UpdateSnapList() = 0; - - // selection manipulate - // flags: [0 - FALSE, 1 - TRUE, -1 - INVERT] - virtual int RaySelect( - int flag, float& distance, const Fvector& start, const Fvector& direction, BOOL bDistanceOnly) = 0; - virtual int FrustumSelect(int flag, const CFrustum& frustum) = 0; - virtual void SelectObjects(bool flag) = 0; - virtual void InvertSelection() = 0; - virtual void RemoveSelection() = 0; - virtual int SelectionCount(bool testflag) = 0; - virtual void ShowObjects(bool flag, bool bAllowSelectionFlag = false, bool bSelFlag = true) = 0; - - virtual void Clear(bool bSpecific = false) = 0; - virtual void Reset(); - - // validation - virtual bool Valid() = 0; - virtual bool Validate(bool) = 0; - - // events - virtual void OnDeviceCreate() = 0; - virtual void OnDeviceDestroy() = 0; - virtual void OnSynchronize() = 0; - - virtual void OnSceneUpdate() { ; } - virtual void OnObjectRemove(CCustomObject* O, bool bDeleting) = 0; - - virtual void OnBeforeObjectChange(CCustomObject* O){}; - - virtual void OnFrame() = 0; - - // render - virtual void BeforeRender() { ; } - virtual void OnRender(int priority, bool strictB2F) = 0; - - void OnRenderRoot(int priority, bool strictB2F) - { - if (IsVisible()) - OnRender(priority, strictB2F); - }; - - virtual void AfterRender() { ; } - // IO - virtual int SaveFileCount() const { return 1; } - virtual bool IsNeedSave() = 0; - - virtual bool LoadStream(IReader&) = 0; - virtual bool LoadLTX(CInifile&) = 0; - virtual void SaveStream(IWriter&) = 0; - virtual void SaveLTX(CInifile&, int id) = 0; - - virtual bool can_use_inifile() { return true; } - virtual bool LoadSelection(IReader&) = 0; - virtual void SaveSelection(IWriter&) = 0; - - virtual bool Export(LPCSTR path) { return true; } - virtual bool ExportGame(SExportStreams* F) { return true; } - virtual bool ExportStatic(SceneBuilder* B, bool b_selected_only) { return true; } - virtual void GetStaticDesc(int& v_cnt, int& f_cnt, bool b_selected_only, bool b_cform) {} - virtual bool GetStaticCformData(mesh_build_data& data, bool b_selected_only) - { -#ifdef DEBUG - int cnt_v = 0, cnt_f = 0; - GetStaticDesc(cnt_v, cnt_f, b_selected_only, true); - VERIFY(cnt_v == 0 && cnt_f == 0); -#endif - return true; - } - - virtual void CompileStaticStart(){}; - - virtual void CompileStaticEnd(){}; - - // properties - virtual void FillProp(LPCSTR pref, PropItemVec& items) = 0; - - // utils - virtual bool GetSummaryInfo(SSceneSummary* inf) = 0; - - virtual void HighlightTexture(LPCSTR tex_name, bool allow_ratio, u32 t_width, u32 t_height, BOOL mark) {} - virtual void GetBBox(Fbox& bb, bool bSelOnly) = 0; - - virtual const CCustomObject* LastSelected() const { return NULL; } -}; - -DEFINE_MAP(ObjClassID, ESceneToolBase*, SceneToolsMap, SceneToolsMapPairIt); -#endif // ESceneCustomMToolsH diff --git a/src/utils/xrAI/StdAfx.cpp b/src/utils/xrAI/StdAfx.cpp deleted file mode 100644 index c9cd8f0a45f..00000000000 --- a/src/utils/xrAI/StdAfx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" -#include "xrCore/cdecl_cast.hpp" -#include "utils/xrLCUtil/LevelCompilerLoggerWindow.hpp" - -ILevelCompilerLogger& Logger = LevelCompilerLoggerWindow::instance(); - -CThread::LogFunc ProxyMsg = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.clMsgV(format, args); - va_end(args); -}); - -CThreadManager::ReportStatusFunc ProxyStatus = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.StatusV(format, args); - va_end(args); -}); - -CThreadManager::ReportProgressFunc ProxyProgress = cdecl_cast([](float progress) { Logger.Progress(progress); }); diff --git a/src/utils/xrAI/StdAfx.h b/src/utils/xrAI/StdAfx.h deleted file mode 100644 index db2151bb456..00000000000 --- a/src/utils/xrAI/StdAfx.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#define ECORE_API -#define XR_EPROPS_API - -#include "Common/Common.hpp" -#include "xrCore/xrCore.h" - -#include "xrAICore/AISpaceBase.hpp" - -#include - -#include -#include "Common/_d3d_extensions.h" - -#include "utils/xrLCUtil/ILevelCompilerLogger.hpp" -#include "utils/xrLCUtil/xrThread.hpp" - -#define NUM_THREADS 8 - -extern ILevelCompilerLogger& Logger; -extern CThread::LogFunc ProxyMsg; -extern CThreadManager::ReportStatusFunc ProxyStatus; -extern CThreadManager::ReportProgressFunc ProxyProgress; - -// Hack to include xrServerEntities\PHNetState.h -#define XRPHYSICS_API - -#ifdef AI_COMPILER -#include "xrServerEntities/smart_cast.h" -#endif - -// Used in: -// src\xrServerEntities\xrServer_Objects_ALife_Items.cpp -// src\xrServerEntities\xrServer_Objects_ALife_Monsters.cpp diff --git a/src/utils/xrAI/compiler.cpp b/src/utils/xrAI/compiler.cpp deleted file mode 100644 index 836406aae0a..00000000000 --- a/src/utils/xrAI/compiler.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "stdafx.h" -#include "compiler.h" - -CDB::MODEL Level; -Nodes g_nodes; -SAIParams g_params; - -void mem_Optimize() -{ - Memory.mem_compact(); - Msg("* Memory usage: %d M", Memory.mem_usage() / (1024 * 1024)); -} - -void xrCompiler(LPCSTR name, bool draft_mode, bool pure_covers, LPCSTR out_name) -{ - Logger.Phase("Loading level..."); - xrLoad(name, draft_mode); - mem_Optimize(); - if (!draft_mode) - { - Logger.Phase("Calculating coverage..."); - xrCover(pure_covers); - mem_Optimize(); - } - Logger.Phase("Saving nodes..."); - xrSaveNodes(name, out_name); - mem_Optimize(); -} diff --git a/src/utils/xrAI/compiler.h b/src/utils/xrAI/compiler.h deleted file mode 100644 index e3968b8a84a..00000000000 --- a/src/utils/xrAI/compiler.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include "xrCDB/xrCDB.h" -#include "utils/Shader_xrLC.h" -#include "xrAICore/Navigation/level_graph.h" -#include "utils/communicate.h" -#include "ESceneAIMapTools_Export.h" -#include "Layers/xrRender/ETextureParams.h" - -// base patch used all the time up to merging -const u32 InvalidNode = (1 << 24) - 1; -const u32 UnkonnectedNode = 0xfffffff0; -const u16 InvalidSector = 0xff; - -struct vertex // definition of "patch" or "node" -{ - union - { - struct - { - u32 n1, n2, n3, n4; // neighbourh patches (Left,Forward,Right,Backward) - }; - u32 n[4]; - }; - Fplane Plane; // plane of patch - Fvector Pos; // position of patch center - u16 Sector; // - - u32 Group; - - float LightLevel; - - float high_cover[4]; // cover in four directions - float low_cover[4]; // cover in four directions - - vertex() - { - n1 = n2 = n3 = n4 = UnkonnectedNode; - Sector = InvalidSector; - Group = 0; - } - u32 nLeft() { return n1; } - u32 nForward() { return n2; } - u32 nRight() { return n3; } - u32 nBack() { return n4; } -}; - -//using DWORDs = xr_vector; - -//#define LT_DIRECT 0 -//#define LT_POINT 1 -//#define LT_SECONDARY 2 - -/*struct R_Light -{ - u32 type; // Type of light source - float amount; // Diffuse color of light - Fvector position; // Position in world space - Fvector direction; // Direction in world space - float range; // Cutoff range - float range2; // ^2 - float attenuation0; // Constant attenuation - float attenuation1; // Linear attenuation - float attenuation2; // Quadratic attenuation - - Fvector tri[3]; // Cached triangle for ray-testing -};*/ - -using Nodes = xr_vector; -using Vectors = xr_vector; -using Marks = xr_vector; -//using Lights = xr_vector; - -// data -extern CDB::MODEL Level; -extern Nodes g_nodes; -extern SAIParams g_params; - -struct b_BuildTexture : public b_texture -{ - STextureParams THM; - - b_BuildTexture() : b_texture() {} - b_BuildTexture(IReader*& file) : b_texture(file) {} - b_BuildTexture(const b_texture& p) : b_texture(p) {} - - u32& Texel(u32 x, u32 y) { return pSurface[y * dwWidth + x]; } - void Vflip() - { - R_ASSERT(pSurface); - for (u32 y = 0; y < dwHeight / 2; y++) - { - u32 y2 = dwHeight - y - 1; - for (u32 x = 0; x < dwWidth; x++) - { - u32 t = Texel(x, y); - Texel(x, y) = Texel(x, y2); - Texel(x, y2) = t; - } - } - } -}; - -extern Shader_xrLC_LIB* g_shaders_xrlc; -extern xr_vector g_materials; -//extern xr_vector g_shader_render; -//extern xr_vector g_shader_compile; -extern xr_vector g_textures; -extern xr_vector g_rc_faces; - -// phases -void xrLoad(LPCSTR name, bool draft_mode); -void xrCover(bool pure_covers); -void xrSaveNodes(LPCSTR name, LPCSTR out_name); - -// constants -const int RCAST_MaxTris = (2 * 1024); -const int RCAST_Count = 6; -const int RCAST_Total = (2 * RCAST_Count + 1) * (2 * RCAST_Count + 1); -const float RCAST_Depth = 1.f; - -const float cover_distance = 30.f; -const float high_cover_height = 1.5f; -const float low_cover_height = 0.6f; -const float cover_sqr_dist = cover_distance * cover_distance; - -const float sim_angle = 20.f; -const float sim_dist = 0.15f; -const int sim_light = 32; -const float sim_cover = 48; - -struct CNodePositionCompressor -{ - IC CNodePositionCompressor(NodePosition4& Pdest, Fvector& Psrc, hdrNODES& H); -}; - -IC CNodePositionCompressor::CNodePositionCompressor(NodePosition4& Pdest, Fvector& Psrc, hdrNODES& H) -{ - float sp = 1 / g_params.fPatchSize; - int row_length = iFloor((H.aabb.vMax.z - H.aabb.vMin.z) / H.size + EPS_L + 1.5f); - int pxz = iFloor((Psrc.x - H.aabb.vMin.x) * sp + EPS_L + .5f) * row_length + - iFloor((Psrc.z - H.aabb.vMin.z) * sp + EPS_L + .5f); - int py = iFloor(65535.f * (Psrc.y - H.aabb.vMin.y) / (H.size_y) + EPS_L); - R_ASSERT(pxz < NodePosition4::MAX_XZ); - Pdest.xz(pxz); - clamp(py, 0, 65535); - Pdest.y(u16(py)); -} diff --git a/src/utils/xrAI/compiler_cover.cpp b/src/utils/xrAI/compiler_cover.cpp deleted file mode 100644 index f8e807cdb70..00000000000 --- a/src/utils/xrAI/compiler_cover.cpp +++ /dev/null @@ -1,583 +0,0 @@ -#include "stdafx.h" -#include "compiler.h" -#include "xrCDB/Intersect.hpp" -#include - -#include "xrGame/quadtree.h" -#include "xrGame/cover_point.h" -#include "Common/object_broker.h" -#include "xrCommon/xr_unordered_map.h" - -Shader_xrLC_LIB* g_shaders_xrlc; -xr_vector g_materials; -//xr_vector g_shader_render; -//xr_vector g_shader_compile; -xr_vector g_textures; -xr_vector g_rc_faces; - -typedef xr_vector COVER_NODES; -COVER_NODES g_cover_nodes; - -// -------------------------------- Ray pick -typedef Fvector RayCache[3]; - -IC float getLastRP_Scale(CDB::COLLIDER* DB, RayCache& C) -{ - float scale = 1.f; - - for (u32 I = 0; I < DB->r_count(); I++) - { - CDB::RESULT& rpinf = DB->r_begin()[I]; - // Access to texture - b_rc_face& F = g_rc_faces[rpinf.id]; - - if (F.dwMaterial >= g_materials.size()) - Logger.clMsg("[%d] -> [%d]", F.dwMaterial, g_materials.size()); - b_material& M = g_materials[F.dwMaterial]; - b_texture& T = g_textures[M.surfidx]; - Shader_xrLCVec& LIB = g_shaders_xrlc->Library(); - if (M.shader_xrlc >= LIB.size()) - return 0; //. hack - Shader_xrLC& SH = LIB[M.shader_xrlc]; - if (!SH.flags.bLIGHT_CastShadow) - continue; - - if (T.pSurface == nullptr || T.bHasAlpha == false) - { - T.bHasAlpha = false; - - // Opaque poly - cache it - C[0].set(rpinf.verts[0]); - C[1].set(rpinf.verts[1]); - C[2].set(rpinf.verts[2]); - return 0; - } - - // barycentric coords - // note: W,U,V order - Fvector B; - B.set(1.0f - rpinf.u - rpinf.v, rpinf.u, rpinf.v); - - // calc UV - auto cuv = F.t; - Fvector2 uv; - uv.x = cuv[0].x * B.x + cuv[1].x * B.y + cuv[2].x * B.z; - uv.y = cuv[0].y * B.x + cuv[1].y * B.y + cuv[2].y * B.z; - - int U = iFloor(uv.x * float(T.dwWidth) + .5f); - int V = iFloor(uv.y * float(T.dwHeight) + .5f); - U %= T.dwWidth; - if (U < 0) - U += T.dwWidth; - V %= T.dwHeight; - if (V < 0) - V += T.dwHeight; - - u32 pixel = T.pSurface[V * T.dwWidth + U]; - u32 pixel_a = color_get_A(pixel); - float opac = 1.f - float(pixel_a) / 255.f; - scale *= opac; - } - - return scale; -} - -IC float rayTrace(CDB::COLLIDER* DB, Fvector& P, Fvector& D, float R, RayCache& C) -{ - R_ASSERT(DB); - - // 1. Check cached polygon - float _u, _v, range; - bool res = CDB::TestRayTri(P, D, C, _u, _v, range, false); - if (res) - { - if (range > 0 && range < R) - return 0; - } - - // 2. Polygon doesn't pick - real database query - DB->ray_query(CDB::OPT_CULL, &Level, P, D, R); - - // 3. Analyze polygons and cache nearest if possible - if (0 == DB->r_count()) - { - return 1; - } - else - { - return getLastRP_Scale(DB, C); - } -} - -IC int calcSphereSector(Fvector& dir) -{ - Fvector2 flat; - - // flatten - flat.set(dir.x, dir.z); - flat.norm(); - - // analyze - if (_abs(flat.x) > _abs(flat.y)) - { - // sector 0,7,3,4 - if (flat.x < 0) - { - // sector 3,4 - if (flat.y > 0) - return 3; - else - return 4; - } - else - { - // sector 0,7 - if (flat.y > 0) - return 0; - else - return 7; - } - } - else - { - // sector 1,2,6,5 - if (flat.x < 0) - { - // sector 2,5 - if (flat.y > 0) - return 2; - else - return 5; - } - else - { - // sector 1,6 - if (flat.y > 0) - return 1; - else - return 6; - } - } -} - -// volumetric query -using Nearest = xr_vector; - -class Query -{ -public: - Nearest q_List; - Nearest q_Clear; - xr_unordered_map q_Marks; - Fvector q_Base; - - IC void Begin(const int count) - { - q_List.reserve(8192); - q_Clear.reserve(8192); - q_Marks.reserve(count); - } - - IC void Init(const Fvector& P) - { - q_Base.set(P); - q_List.clear(); - q_Clear.clear(); - } - - IC void Perform(u32 ID) - { - if (ID == InvalidNode) - return; - if (q_Marks[ID]) - return; - - q_Marks[ID] = true; - q_Clear.push_back(ID); - - vertex& N = g_nodes[ID]; - if (q_Base.distance_to_sqr(N.Pos) > cover_sqr_dist) - return; - - // ok - q_List.push_back(ID); - - Perform(N.n1); - Perform(N.n2); - Perform(N.n3); - Perform(N.n4); - } - - IC void Clear() - { - q_Marks.clear(); - } -}; -struct RC -{ - RayCache C; -}; - -class CoverThread : public CThread -{ - u32 Nstart, Nend; - xr_vector cache; - CDB::COLLIDER DB; - Query Q; - - typedef float Cover[4]; - -public: - CoverThread(u32 ID, u32 _start, u32 _end) : CThread(ID, ProxyMsg), Q() - { - Nstart = _start; - Nend = _end; - } - - void compute_cover_value(u32 const& N, vertex& BaseNode, float const& cover_height, Cover& cover) - { - Fvector& BasePos = BaseNode.Pos; - Fvector TestPos = BasePos; - TestPos.y += cover_height; - - int c_total[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - float c_passed[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // perform volumetric query - Q.Init(BasePos); - Q.Perform(N); - - // main cycle: trace rays and compute counts - for (auto &it : Q.q_List) - { - // calc dir & range - u32 ID = it; - R_ASSERT(ID < g_nodes.size()); - if (N == ID) - continue; - vertex& N2 = g_nodes[ID]; - Fvector& Pos = N2.Pos; - Fvector Dir; - Dir.sub(Pos, BasePos); - float range = Dir.magnitude(); - Dir.div(range); - - // raytrace - int sector = calcSphereSector(Dir); - c_total [sector] += 1; - c_passed[sector] += rayTrace(&DB, TestPos, Dir, range, cache[ID].C); // - } - Q.Clear(); - - // analyze probabilities - float value[8]; - for (int dirs = 0; dirs < 8; dirs++) - { - R_ASSERT(c_passed[dirs] <= c_total[dirs]); - if (c_total[dirs] == 0) - value[dirs] = 0; - else - value[dirs] = c_passed[dirs] / float(c_total[dirs]); - clamp(value[dirs], 0.f, 1.f); - } - - cover[0] = (value[2] + value[3] + value[4] + value[5]) / 4.f; - clamp(cover[0], 0.f, 1.f); // left - cover[1] = (value[0] + value[1] + value[2] + value[3]) / 4.f; - clamp(cover[1], 0.f, 1.f); // forward - cover[2] = (value[6] + value[7] + value[0] + value[1]) / 4.f; - clamp(cover[2], 0.f, 1.f); // right - cover[3] = (value[4] + value[5] + value[6] + value[7]) / 4.f; - clamp(cover[3], 0.f, 1.f); // back - } - - virtual void Execute() - { - { - RC rc; - rc.C[0].set(0, 0, 0); - rc.C[1].set(0, 0, 0); - rc.C[2].set(0, 0, 0); - - cache.assign(g_nodes.size() * 2, rc); - } - - FPU::m24r(); - - Q.Begin(g_nodes.size()); - for (u32 N = Nstart; N < Nend; N++) - { - // initialize process - thProgress = float(N - Nstart) / float(Nend - Nstart); - vertex& BaseNode = g_nodes[N]; - - if (!g_cover_nodes[N]) - { - BaseNode.high_cover[0] = flt_max; - BaseNode.high_cover[1] = flt_max; - BaseNode.high_cover[2] = flt_max; - BaseNode.high_cover[3] = flt_max; - BaseNode.low_cover[0] = flt_max; - BaseNode.low_cover[1] = flt_max; - BaseNode.low_cover[2] = flt_max; - BaseNode.low_cover[3] = flt_max; - continue; - } - - compute_cover_value(N, BaseNode, high_cover_height, BaseNode.high_cover); - compute_cover_value(N, BaseNode, low_cover_height, BaseNode.low_cover); - } - } -}; - -bool valid_vertex_id(const u32& vertex_id) { return (vertex_id != InvalidNode); } -bool cover(const vertex& v, u32 index0, u32 index1) -{ - return (valid_vertex_id(v.n[index0]) && valid_vertex_id(g_nodes[v.n[index0]].n[index1])); -} - -bool critical_point(const vertex& v, u32 index, u32 index0, u32 index1) -{ - return (!valid_vertex_id(v.n[index]) && (!valid_vertex_id(v.n[index0]) || !valid_vertex_id(v.n[index1]) || - cover(v, index0, index) || cover(v, index1, index))); -} - -bool is_cover(const vertex& v) -{ - return (critical_point(v, 0, 1, 3) - || critical_point(v, 2, 1, 3) - || critical_point(v, 1, 0, 2) - || critical_point(v, 3, 0, 2)); -} - -void compute_cover_nodes() -{ - g_cover_nodes.assign(g_nodes.size(), false); - - auto J = g_cover_nodes.begin(); - for (auto &I : g_nodes) - *J++ = is_cover(I); -} - -bool vertex_in_direction(const u32& start_vertex_id, const u32& target_vertex_id) -{ - const Fvector& finish_position = g_nodes[target_vertex_id].Pos; - u32 cur_vertex_id = start_vertex_id, prev_vertex_id = u32(-1); - Fbox2 box; - Fvector2 identity, start, dest, dir; - - identity.x = identity.y = g_params.fPatchSize * .5f; - const Fvector& start_position = g_nodes[start_vertex_id].Pos; - start = Fvector2().set(start_position.x, start_position.z); - dest.set(finish_position.x, finish_position.z); - dir.sub(dest, start); - auto temp = start; - - float cur_sqr = _sqr(temp.x - dest.x) + _sqr(temp.y - dest.y); - for (;;) - { - bool found = false; - for (int I = 0, E = 4; I != E; ++I) - { - u32 next_vertex_id = g_nodes[cur_vertex_id].n[I]; - if ((next_vertex_id == prev_vertex_id) || !valid_vertex_id(next_vertex_id)) - continue; - - const Fvector& position = g_nodes[next_vertex_id].Pos; - temp = Fvector2().set(position.x, position.z); - box.min = box.max = temp; - box.grow(identity); - if (box.pick_exact(start, dir)) - { - if (next_vertex_id == target_vertex_id) - return (true); - - Fvector2 temp2; - temp2.add(box.min, box.max); - temp2.mul(.5f); - float dist = _sqr(temp2.x - dest.x) + _sqr(temp2.y - dest.y); - if (dist > cur_sqr) - continue; - - cur_sqr = dist; - found = true; - prev_vertex_id = cur_vertex_id; - cur_vertex_id = next_vertex_id; - break; - } - } - - if (!found) - return (false); - } -} - -extern float CalculateHeight(Fbox& BB); - -void compute_non_covers() -{ - Fbox aabb; - CalculateHeight(aabb); - - CQuadTree covers(aabb, g_params.fPatchSize * .5f, 8 * 65536, 4 * 65536); - - auto J = g_cover_nodes.begin(); - for (auto &I : g_nodes) - { - if (!*J++) - continue; - - if ((I.high_cover[0] + I.high_cover[1] + I.high_cover[2] + I.high_cover[3]) >= 4 * .999f) - if ((I.low_cover[0] + I.low_cover[1] + I.low_cover[2] + I.low_cover[3]) >= 4 * .999f) - continue; - - covers.insert(xr_new(I.Pos, std::distance(&g_nodes.front(), &I))); - } - - VERIFY(covers.size()); - - using COVERS = xr_vector; - using COVER_PAIR = std::pair; - using COVER_PAIRS = xr_vector; - - COVERS nearest; - COVER_PAIRS cover_pairs; - - auto K = g_cover_nodes.begin(); - for (auto &I : g_nodes) - { - if (*K++) - continue; - - covers.nearest(I.Pos, cover_distance, nearest); - if (nearest.empty()) - { - for (int i = 0; i < 4; ++i) - { - VERIFY(I.high_cover[i] == flt_max); - I.high_cover[i] = 1.f; - - VERIFY(I.low_cover[i] == flt_max); - I.low_cover[i] = 1.f; - } - continue; - } - - cover_pairs.clear(); - cover_pairs.reserve(nearest.size()); - - float cumulative_weight = 0.f; - - for (auto &i : nearest) - { - if (!vertex_in_direction(std::distance(&g_nodes.front(), &I), i->level_vertex_id())) - continue; - - float weight = 1.f / i->position().distance_to(I.Pos); - cumulative_weight += weight; - cover_pairs.emplace_back(weight, i); - } - - // this is incorrect - if (cover_pairs.empty()) - { - for (int i = 0; i < 4; ++i) - { - VERIFY(I.high_cover[i] == flt_max); - I.high_cover[i] = 1.f; - - VERIFY(I.low_cover[i] == flt_max); - I.low_cover[i] = 1.f; - } - continue; - } - - for (int j = 0; j < 4; ++j) - { - VERIFY(I.high_cover[j] == flt_max); - I.high_cover[j] = 0.f; - - VERIFY(I.low_cover[j] == flt_max); - I.low_cover[j] = 0.f; - } - - for (auto &i : cover_pairs) - { - vertex& current = g_nodes[i.second->level_vertex_id()]; - float factor = i.first / cumulative_weight; - for (int j = 0; j < 4; ++j) - { - I.high_cover[j] += factor * current.high_cover[j]; - I.low_cover[j] += factor * current.low_cover[j]; - } - } - - for (int i2 = 0; i2 < 4; ++i2) - { - clamp(I.high_cover[i2], 0.f, 1.f); - clamp(I.low_cover[i2], 0.f, 1.f); - } - } - - covers.all(nearest); - delete_data(nearest); -} - -extern void mem_Optimize(); -void xrCover(bool pure_covers) -{ - Logger.Status("Calculating..."); - - if (!pure_covers) - compute_cover_nodes(); - else - g_cover_nodes.assign(g_nodes.size(), true); - - // Start threads, wait, continue --- perform all the work - CTimer timer; - timer.Start(); - CThreadManager Threads(ProxyStatus, ProxyProgress); - u32 stride = g_nodes.size() / NUM_THREADS; - u32 last = g_nodes.size() - stride * (NUM_THREADS - 1); - for (u32 thID = 0; thID < NUM_THREADS; thID++) - Threads.start( - xr_new(thID, thID * stride, thID * stride + ((thID == (NUM_THREADS - 1)) ? last : stride))); - Threads.wait(); - Logger.clMsg("%f seconds elapsed.", timer.GetElapsed_sec()); - - if (!pure_covers) - { - compute_non_covers(); - } - else - { - // Smooth - Logger.Status("Smoothing coverage mask..."); - mem_Optimize(); - auto Old = g_nodes; - for (u32 N = 0; N < g_nodes.size(); N++) - { - vertex& Base = Old[N]; - vertex& Dest = g_nodes[N]; - - for (int dir = 0; dir < 4; dir++) - { - float val = 2 * Base.high_cover[dir]; - float val2 = 2 * Base.low_cover[dir]; - float cnt = 2; - - for (int nid = 0; nid < 4; nid++) - { - if (Base.n[nid] != InvalidNode) - { - val += Old[Base.n[nid]].high_cover[dir]; - val2 += Old[Base.n[nid]].low_cover[dir]; - cnt += 1.f; - } - } - Dest.high_cover[dir] = val / cnt; - Dest.low_cover[dir] = val2 / cnt; - } - } - } -} diff --git a/src/utils/xrAI/compiler_load.cpp b/src/utils/xrAI/compiler_load.cpp deleted file mode 100644 index 98327f4fe67..00000000000 --- a/src/utils/xrAI/compiler_load.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "stdafx.h" -#include "compiler.h" - -// TODO: Do we really need this? -//Lights g_lights; - -IC const Fvector vertex_position(const NodePosition4& Psrc, const Fbox& bb, const SAIParams& params) -{ - Fvector Pdest; - int x, z, row_length; - row_length = iFloor((bb.vMax.z - bb.vMin.z) / params.fPatchSize + EPS_L + 1.5f); - x = Psrc.xz() / row_length; - z = Psrc.xz() % row_length; - Pdest.x = float(x) * params.fPatchSize + bb.vMin.x; - Pdest.y = (float(Psrc.y()) / 65535) * (bb.vMax.y - bb.vMin.y) + bb.vMin.y; - Pdest.z = float(z) * params.fPatchSize + bb.vMin.z; - return (Pdest); -} - -struct CNodePositionConverter -{ - IC CNodePositionConverter(const NodePosition3& Psrc, hdrNODES& m_header, NodePosition4& np); -}; - -IC CNodePositionConverter::CNodePositionConverter(const NodePosition3& Psrc, hdrNODES& m_header, NodePosition4& np) -{ - Fvector Pdest; - Pdest.x = float(Psrc.x) * m_header.size; - Pdest.y = (float(Psrc.y) / 65535) * m_header.size_y + m_header.aabb.vMin.y; - Pdest.z = float(Psrc.z) * m_header.size; - CNodePositionCompressor(np, Pdest, m_header); - np.y(Psrc.y); -} - -//----------------------------------------------------------------- -template -void transfer(const char* name, xr_vector& dest, IReader& F, u32 chunk) -{ - IReader* O = F.open_chunk(chunk); - const size_t count = O ? (O->length() / sizeof(T)) : 0; - Logger.clMsg("* %16s: %d", name, count); - if (count) - { - dest.reserve(count); - dest.insert(dest.begin(), (T*)O->pointer(), (T*)O->pointer() + count); //-V595 - } - if (O) - O->close(); -} - -extern u32* Surface_Load(char* name, u32& w, u32& h); -extern void Surface_Init(); - -void xrLoad(LPCSTR name, bool draft_mode) -{ - FS.get_path("$level$")->_set((pstr)name); - string_path file_name; - if (!draft_mode) - { - // shaders - FS.update_path(file_name, "$game_data$", "shaders_xrlc.xr"); - g_shaders_xrlc = xr_new(); - g_shaders_xrlc->Load(file_name); - - // Load CFORM - { - strconcat(sizeof(file_name), file_name, name, "build.cform"); - IReader* fs = FS.r_open(file_name); - R_ASSERT2(fs, "There is no file 'build.cform'!"); - R_ASSERT(fs->find_chunk(0)); - - hdrCFORM H; - fs->r(&H, sizeof(hdrCFORM)); - R_ASSERT(CFORM_CURRENT_VERSION == H.version); - - Fvector* verts = (Fvector*)fs->pointer(); - CDB::TRI* tris = (CDB::TRI*)(verts + H.vertcount); - Level.build(verts, H.vertcount, tris, H.facecount); - Level.syncronize(); - Msg("* Level CFORM: %dK", Level.memory() / 1024); - - g_rc_faces.resize(H.facecount); - R_ASSERT(fs->find_chunk(1)); - fs->r(&*g_rc_faces.begin(), g_rc_faces.size() * sizeof(b_rc_face)); - - FS.r_close(fs); - } - - // Load level data - { - strconcat(sizeof(file_name), file_name, name, "build.prj"); - IReader* fs = FS.r_open(file_name); - R_ASSERT2(fs, "There is no file 'build.prj'!"); - - // Version - u32 version; - fs->r_chunk(EB_Version, &version); - R_ASSERT(XRCL_CURRENT_VERSION >= 17); - R_ASSERT(XRCL_CURRENT_VERSION <= 18); - - // Header - b_params Params; - fs->r_chunk(EB_Parameters, &Params); - - // Load level data - transfer("materials", g_materials, *fs, EB_Materials); - //transfer("shaders_xrlc", g_shader_compile, *fs, EB_Shaders_Compile); - - // process textures - Logger.Status("Processing textures..."); - { - Surface_Init(); - IReader* F = fs->open_chunk(EB_Textures); - const size_t tex_count = F->length() / sizeof(b_texture); - for (size_t t = 0; t < tex_count; t++) - { - Logger.Progress(float(t) / float(tex_count)); - - b_BuildTexture BT(F); - - // load thumbnail - string128& N = BT.name; - pstr extension = strext(N); - if (extension) - *extension = 0; - - xr_strlwr(N); - - if (0 == xr_strcmp(N, "level_lods")) - { - // HACK for merged lod textures - BT.dwWidth = 1024; - BT.dwHeight = 1024; - BT.bHasAlpha = TRUE; - BT.pSurface = 0; - } - else - { - xr_strcat(N, ".thm"); - IReader* THM = FS.r_open("$game_textures$", N); - R_ASSERT2(THM, N); - - // version - //u32 version = 0; - //R_ASSERT2(THM->r_chunk(THM_CHUNK_VERSION, &version), N); - //if (version != THM_CURRENT_VERSION) FATAL("Unsupported version of THM file."); - - // analyze thumbnail information - BT.THM.Load(*THM); - BOOL bLOD = FALSE; - if (N[0] == 'l' && N[1] == 'o' && N[2] == 'd' && N[3] == '\\') - bLOD = TRUE; - - // load surface if it has an alpha channel or has "implicit lighting" flag - BT.dwWidth = BT.THM.width; - BT.dwHeight = BT.THM.height; - BT.bHasAlpha = BT.THM.HasAlphaChannel(); - BT.pSurface = 0; - if (!bLOD) - { - if (BT.bHasAlpha || BT.THM.flags.test(STextureParams::flImplicitLighted)) - { - Logger.clMsg("- loading: %s", N); - u32 w = 0, h = 0; - BT.pSurface = Surface_Load(N, w, h); - R_ASSERT2(BT.pSurface, "Can't load surface"); - if ((w != BT.dwWidth) || (h != BT.dwHeight)) - { - Msg("! THM doesn't correspond to the texture: %dx%d -> %dx%d", BT.dwWidth, BT.dwHeight, w, h); - BT.dwWidth = BT.THM.width = w; - BT.dwHeight = BT.THM.height = h; - } - BT.Vflip(); - } - } - } - - // save all the stuff we've created - g_textures.push_back(BT); - } - } - } - } - // Load lights - /*{ - strconcat(sizeof(file_name), file_name, name, "build.prj"); - IReader* F = FS.r_open(file_name); - R_ASSERT2(F, "There is no file 'build.prj'!"); - IReader& fs = *F; - - // Version - u32 version; - fs.r_chunk(EB_Version, &version); - R_ASSERT(XRCL_CURRENT_VERSION >= 17); - R_ASSERT(XRCL_CURRENT_VERSION <= 18); - - // Header - b_params Params; - fs.r_chunk(EB_Parameters, &Params); - - // Lights (Static) - { - F = fs.open_chunk(EB_Light_static); - b_light_static temp; - size_t cnt = F->length() / sizeof(temp); - for (size_t i = 0; i < cnt; i++) - { - R_Light RL; - F->r(&temp, sizeof(temp)); - Flight& L = temp.data; - if (_abs(L.range) > 10000.f) - { - Msg("! BAD light range : %f", L.range); - L.range = L.range > 0.f ? 10000.f : -10000.f; - } - - // type - if (L.type == Flight::Type::Directional) - RL.type = LT_DIRECT; - else - RL.type = LT_POINT; - - // generic properties - RL.position.set(L.position); - RL.direction.normalize_safe(L.direction); - RL.range = L.range * 1.1f; - RL.range2 = RL.range * RL.range; - RL.attenuation0 = L.attenuation0; - RL.attenuation1 = L.attenuation1; - RL.attenuation2 = L.attenuation2; - - RL.amount = L.diffuse.magnitude_rgb(); - RL.tri[0].set(0, 0, 0); - RL.tri[1].set(0, 0, 0); - RL.tri[2].set(0, 0, 0); - - // place into layer - if (0 == temp.controller_ID) - g_lights.push_back(RL); - } - F->close(); - } - }*/ - // Load initial map from the Level Editor - { - strconcat(sizeof(file_name), file_name, name, "build.aimap"); - IReader* F = FS.r_open(file_name); - R_ASSERT2(F, "There is no file 'build.aimap'!"); - - R_ASSERT(F->open_chunk(E_AIMAP_CHUNK_VERSION)); - R_ASSERT(F->r_u16() == E_AIMAP_VERSION); - - Fbox LevelBB; - - R_ASSERT(F->open_chunk(E_AIMAP_CHUNK_BOX)); - F->r(&LevelBB, sizeof(LevelBB)); - - R_ASSERT(F->open_chunk(E_AIMAP_CHUNK_PARAMS)); - F->r(&g_params, sizeof(g_params)); - - R_ASSERT(F->open_chunk(E_AIMAP_CHUNK_NODES)); - size_t N = F->r_u32(); - R_ASSERT2(N < (NodeCompressed10::LINK_MASK - 1), "Too many nodes!"); - g_nodes.resize(N); - - hdrNODES H; - H.version = XRAI_CURRENT_VERSION; - H.count = N + 1; - H.size = g_params.fPatchSize; - H.size_y = 1.f; - H.aabb = LevelBB; - - typedef u8 NodeLink[3]; - for (size_t i = 0; i < N; i++) - { - NodeLink id; - u16 pl; - NodePosition3 _np; - NodePosition4 np; - - for (size_t j = 0; j < 4; ++j) - { - F->r(&id, 3); - g_nodes[i].n[j] = (*reinterpret_cast(&id)) & 0x00ffffff; - } - - pl = F->r_u16(); - pvDecompress(g_nodes[i].Plane.n, pl); - F->r(&_np, sizeof(_np)); - CNodePositionConverter(_np, H, np); - g_nodes[i].Pos = vertex_position(np, LevelBB, g_params); - - g_nodes[i].Plane.build(g_nodes[i].Pos, g_nodes[i].Plane.n); - } - - F->close(); - - if (!strstr(Core.Params, "-keep_temp_files")) - DeleteFile(file_name); - } -} diff --git a/src/utils/xrAI/compiler_save.cpp b/src/utils/xrAI/compiler_save.cpp deleted file mode 100644 index a21288c52fa..00000000000 --- a/src/utils/xrAI/compiler_save.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "stdafx.h" -#include "compiler.h" -#include "guid_generator.h" - -IC u8 compress(float c, int max_value) -{ - int cover = iFloor(c * float(max_value) + .5f); - clamp(cover, 0, max_value); - return u8(cover); -} - -struct CNodeCompressed -{ - IC void compress_node(NodeCompressed10& Dest, vertex& Src); -}; - -IC void CNodeCompressed::compress_node(NodeCompressed10& Dest, vertex& Src) -{ - //Dest.light(15); - for (u8 L = 0; L < 4; ++L) - Dest.link(L, Src.n[L]); -} - -void Compress(NodeCompressed10& Dest, vertex& Src, hdrNODES& H) -{ - // Compress plane (normal) - Dest.plane = pvCompress(Src.Plane.n); - // Compress position - CNodePositionCompressor(Dest.p, Src.Pos, H); - // Light & Cover - CNodeCompressed().compress_node(Dest, Src); - Dest.high.cover0 = compress(Src.high_cover[0], 15); - Dest.high.cover1 = compress(Src.high_cover[1], 15); - Dest.high.cover2 = compress(Src.high_cover[2], 15); - Dest.high.cover3 = compress(Src.high_cover[3], 15); - Dest.low.cover0 = compress(Src.low_cover[0], 15); - Dest.low.cover1 = compress(Src.low_cover[1], 15); - Dest.low.cover2 = compress(Src.low_cover[2], 15); - Dest.low.cover3 = compress(Src.low_cover[3], 15); -} - -float CalculateHeight(Fbox& BB) -{ - // All nodes - BB.invalidate(); - - for (auto &i : g_nodes) - BB.modify(i.Pos); - - return BB.vMax.y - BB.vMin.y + EPS_L; -} - -xr_vector compressed_nodes; - -class CNodeRenumberer -{ - xr_vector& m_nodes; - xr_vector& m_sorted; - xr_vector& m_renumbering; - -public: - CNodeRenumberer(xr_vector& nodes, xr_vector& sorted, xr_vector& renumbering) - : m_nodes(nodes), m_sorted(sorted), m_renumbering(renumbering) - { - u32 N = m_nodes.size(); - m_sorted.resize(N); - m_renumbering.resize(N); - - for (u32 i = 0; i < N; ++i) - m_sorted[i] = i; - - std::stable_sort(m_sorted.begin(), m_sorted.end(), [](const u32 vertex_id0, const u32 vertex_id1) - { - return compressed_nodes[vertex_id0].p.xz() < compressed_nodes[vertex_id1].p.xz(); - }); - - for (u32 i = 0; i < N; ++i) - m_renumbering[m_sorted[i]] = i; - - for (auto &i : m_nodes) - { - for (u8 j = 0; j < 4; ++j) - { - u32 vertex_id = i.link(j); - if (vertex_id >= N) - continue; - i.link(j, m_renumbering[vertex_id]); - } - } - - std::stable_sort(m_nodes.begin(), m_nodes.end(), [](const NodeCompressed10& vertex0, const NodeCompressed10& vertex1) - { - return vertex0.p.xz() < vertex1.p.xz(); - }); - } -}; - -void xrSaveNodes(LPCSTR name, LPCSTR out_name) -{ - Logger.Status("Saving nodes..."); - - Logger.clMsg("NS: %d, CNS: %d, ratio: %f%%", sizeof(vertex), sizeof(CLevelGraph::CLevelVertex), - 100 * float(sizeof(CLevelGraph::CLevelVertex)) / float(sizeof(vertex))); - - string_path fName; - strconcat(sizeof(fName), fName, name, out_name); - IWriter* fs = FS.w_open(fName); - - // Header - Logger.clMsg("Saving header..."); - hdrNODES H; - H.version = XRAI_CURRENT_VERSION; - H.count = g_nodes.size(); - H.size = g_params.fPatchSize; - H.size_y = CalculateHeight(H.aabb); - H.guid = generate_guid(); - fs->w(&H, sizeof(H)); - // All nodes - Logger.clMsg("Compressing nodes..."); - compressed_nodes.reserve(g_nodes.size()); - for (auto &i : g_nodes) - { - NodeCompressed10 NC; - Compress(NC, i, H); - compressed_nodes.push_back(NC); - } - - xr_vector sorted; - xr_vector renumbering; - Logger.clMsg("Renumbering nodes..."); - CNodeRenumberer A(compressed_nodes, sorted, renumbering); - - Logger.clMsg("Saving nodes..."); - for (auto &i : compressed_nodes) - fs->w(&i, sizeof(NodeCompressed10)); - - // Stats - u32 SizeTotal = fs->tell(); - Logger.clMsg("%dK saved", SizeTotal / 1024); - - FS.w_close(fs); -} diff --git a/src/utils/xrAI/factory_api.h b/src/utils/xrAI/factory_api.h deleted file mode 100644 index f866058ebea..00000000000 --- a/src/utils/xrAI/factory_api.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "xrServerEntities/xrServer_Object_Base.h" - -extern "C" { -using CreateEntity = XR_IMPORT IServerEntity*(LPCSTR section); -using DestroyEntity = XR_IMPORT void(IServerEntity*&); -}; - -extern CreateEntity* create_entity; -extern DestroyEntity* destroy_entity; - -IC CSE_Abstract* F_entity_Create(LPCSTR section) -{ - IServerEntity* i = create_entity(section); - CSE_Abstract* j = smart_cast(i); - return (j); -} - -IC void F_entity_Destroy(CSE_Abstract*& i) -{ - IServerEntity* j = i; - destroy_entity(j); - i = 0; -} diff --git a/src/utils/xrAI/game_graph_builder.cpp b/src/utils/xrAI/game_graph_builder.cpp deleted file mode 100644 index 43118208324..00000000000 --- a/src/utils/xrAI/game_graph_builder.cpp +++ /dev/null @@ -1,706 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_graph_builder.cpp -// Created : 14.12.2005 -// Modified : 14.12.2005 -// Author : Dmitriy Iassenev -// Description : Game graph builder -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "game_graph_builder.h" -#include "xrServerEntities/xrServer_Objects_ALife.h" -#include "xrServerEntities/xrMessages.h" -#include "factory_api.h" -#include "guid_generator.h" - -CGameGraphBuilder::CGameGraphBuilder() -{ - m_level_graph = 0; - m_graph = 0; - m_cross_table = 0; -} - -CGameGraphBuilder::~CGameGraphBuilder() -{ - Msg("Freeing resources"); - - xr_delete(m_level_graph); - xr_delete(m_graph); - xr_delete(m_cross_table); -} - -void CGameGraphBuilder::create_graph(const float& start, const float& amount) -{ - Logger.Progress(start); - - VERIFY(!m_graph); - m_graph = xr_new(); - - m_graph_guid = generate_guid(); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::load_level_graph(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Loading AI map"); - - VERIFY(!m_level_graph); - m_level_graph = xr_new(*m_level_name); - - Msg("%d nodes loaded", level_graph().header().vertex_count()); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::load_graph_point(NET_Packet& net_packet) -{ - string256 section_id; - u16 id; - net_packet.r_begin(id); - R_ASSERT(M_SPAWN == id); - net_packet.r_stringZ(section_id); - - // if (xr_strcmp("graph_point",section_id)) - // return; - - CSE_Abstract* entity = F_entity_Create(section_id); - if (!entity) - { - Msg("Cannot create entity from section %s, skipping", section_id); - return; - } - - CSE_ALifeGraphPoint* graph_point = smart_cast(entity); - if (!graph_point) - { - F_entity_Destroy(entity); - return; - } - - entity->Spawn_Read(net_packet); - - vertex_type vertex; - vertex.tLocalPoint = graph_point->o_Position; - // Check for duplicate graph point positions - for (const auto &i : graph().vertices()) - { - if (i.second->data().tLocalPoint.distance_to_sqr(vertex.tLocalPoint) < EPS_L) - { - Msg("! removing graph point [%s][%f][%f][%f] because it is too close to the another graph point", entity->name_replace(), VPUSH(entity->o_Position)); - F_entity_Destroy(entity); - return; - } - } - - vertex.tGlobalPoint = graph_point->o_Position; - vertex.tNodeID = level_graph().valid_vertex_position(vertex.tLocalPoint) ? level_graph().vertex_id(vertex.tLocalPoint) : u32(-1); - if (!level_graph().valid_vertex_id(vertex.tNodeID)) - { - Msg("! removing graph point [%s][%f][%f][%f] because it is outside of the AI map", entity->name_replace(), VPUSH(entity->o_Position)); - F_entity_Destroy(entity); - return; - } - - for (const auto &i : graph().vertices()) - { - if (i.second->data().tNodeID == vertex.tNodeID) - { - Msg("! removing graph point [%s][%f][%f][%f] because it has the same AI node as another graph point", entity->name_replace(), VPUSH(entity->o_Position)); - F_entity_Destroy(entity); - return; - } - } - - vertex.tNeighbourCount = 0; - memcpy(vertex.tVertexTypes, graph_point->m_tLocations, GameGraph::LOCATION_TYPE_COUNT * sizeof(GameGraph::_LOCATION_ID)); - vertex.tLevelID = 0; - vertex.tDeathPointCount = 0; - vertex.dwPointOffset = 0; - - graph().add_vertex(vertex, graph().vertices().size()); - - F_entity_Destroy(entity); -} - -void CGameGraphBuilder::load_graph_points(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Loading graph points"); - - string_path spawn_file_name; - strconcat(sizeof(spawn_file_name), spawn_file_name, *m_level_name, "level.spawn"); - IReader* reader = FS.r_open(spawn_file_name); - u32 id; - NET_Packet net_packet; - for (IReader* chunk = reader->open_chunk_iterator(id); chunk; chunk = reader->open_chunk_iterator(id, chunk)) - { - net_packet.B.count = chunk->length(); - chunk->r(net_packet.B.data, net_packet.B.count); - load_graph_point(net_packet); - } - - FS.r_close(reader); - - Msg("%d graph points loaded", graph().vertices().size()); - - Logger.Progress(start + amount); -} - -template -IC bool sort_predicate_less(const T& first, const T& second) -{ - return (first.first < second.first); -} - -template -IC bool sort_predicate_greater(const T& first, const T& second) -{ - return (first.first > second.first); -} - -void CGameGraphBuilder::mark_vertices(u32 level_vertex_id) -{ - m_mark_stack.reserve(8192); - m_mark_stack.push_back(level_vertex_id); - - for (; !m_mark_stack.empty();) - { - level_vertex_id = m_mark_stack.back(); - m_mark_stack.resize(m_mark_stack.size() - 1); - auto node = level_graph().vertex(level_vertex_id); - m_marks[level_vertex_id] = true; - for (const auto &i : {0, 1, 2, 3}) - { - u32 next_level_vertex_id = node->link(i); - - if (!level_graph().valid_vertex_id(next_level_vertex_id)) - continue; - - if (!m_marks[next_level_vertex_id]) - m_mark_stack.push_back(next_level_vertex_id); - } - } -} - -void CGameGraphBuilder::fill_marks(const float& start, const float& amount) -{ - Logger.Progress(start); - - m_marks.assign(level_graph().header().vertex_count(), false); - for (const auto &i : graph().vertices()) - mark_vertices(i.second->data().level_vertex_id()); - m_marks.flip(); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::fill_distances(const float& start, const float& amount) -{ - Logger.Progress(start); - - m_distances.resize(graph().vertices().size()); - for (auto &i : m_distances) - { - i.resize(level_graph().header().vertex_count()); - for (auto &j : i) - j = u32(-1); - } - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::recursive_update(const u32& game_vertex_id, const float& start, const float& amount) -{ - Logger.Progress(start); - - u32 level_vertex_id = graph().vertex(game_vertex_id)->data().level_vertex_id(); - xr_vector& distances = m_distances[game_vertex_id]; - m_distances[m_results[level_vertex_id]][level_vertex_id] = u32(-1); - - m_current_fringe.reserve(distances.size()); - m_next_fringe.reserve(distances.size()); - distances.assign(distances.size(), u32(-1)); - m_current_fringe.push_back(level_vertex_id); - u32 curr_dist = 0; - u32 total_count = 0; - - u32 vertex_count = graph().header().vertex_count(); - - float amount_i = amount / (float(vertex_count) * float(level_graph().header().vertex_count())); - - Logger.Progress(start); - for (; !m_current_fringe.empty();) - { - for (const auto &i : m_current_fringe) - { - u32* result = &m_results[i]; - VERIFY(curr_dist < m_distances[*result][i]); - *result = game_vertex_id; - - distances[i] = curr_dist; - CLevelGraph::CLevelVertex* node = level_graph().vertex(i); - for (const auto &j : {0, 1, 2, 3}) - { - u32 dwNexNodeID = node->link(j); - if (!level_graph().valid_vertex_id(dwNexNodeID)) - continue; - - if (m_marks[dwNexNodeID]) - continue; - - if (distances[dwNexNodeID] <= curr_dist) - continue; - - if (m_distances[m_results[dwNexNodeID]][dwNexNodeID] <= (curr_dist + 1)) - continue; - - m_next_fringe.push_back(dwNexNodeID); - m_marks[dwNexNodeID] = true; - } - } - - for (const auto &i : m_current_fringe) - m_marks[i] = false; - - total_count += m_current_fringe.size(); - m_current_fringe = m_next_fringe; - m_next_fringe.clear(); - ++curr_dist; - - Logger.Progress(start + amount_i * float(total_count)); - } - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::iterate_distances(const float& start, const float& amount) -{ - Logger.Progress(start); - - m_results.assign(level_graph().header().vertex_count(), 0); - - auto size = graph().vertices().size(); - float amount_i = amount / float(size); - - for (auto i = 0; i < size; ++i) - { - if (i) - for (int k = 0, kn = (int)level_graph().header().vertex_count(); k < kn; ++k) - m_distances[i][k] = m_distances[i - 1][k]; - - recursive_update(i, start + amount_i * float(i), amount_i); - } - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::save_cross_table(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Saving cross table"); - - // CTimer timer; - // timer.Start (); - - CMemoryWriter tMemoryStream; - CGameLevelCrossTable::CHeader tCrossTableHeader; - - tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; - tCrossTableHeader.dwNodeCount = level_graph().header().vertex_count(); - tCrossTableHeader.dwGraphPointCount = graph().header().vertex_count(); - tCrossTableHeader.m_level_guid = level_graph().header().guid(); - tCrossTableHeader.m_game_guid = m_graph_guid; - - tMemoryStream.open_chunk(CROSS_TABLE_CHUNK_VERSION); - tMemoryStream.w(&tCrossTableHeader, sizeof(tCrossTableHeader)); - tMemoryStream.close_chunk(); - - tMemoryStream.open_chunk(CROSS_TABLE_CHUNK_DATA); - - for (int i = 0, n = level_graph().header().vertex_count(); i < n; i++) - { - CGameLevelCrossTable::CCell tCrossTableCell; - tCrossTableCell.tGraphIndex = (GameGraph::_GRAPH_ID)m_results[i]; - VERIFY(graph().header().vertex_count() > tCrossTableCell.tGraphIndex); - tCrossTableCell.fDistance = float(m_distances[tCrossTableCell.tGraphIndex][i]) * level_graph().header().cell_size(); - tMemoryStream.w(&tCrossTableCell, sizeof(tCrossTableCell)); - } - - tMemoryStream.close_chunk(); - - // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); - // Msg ("Flushing cross table"); - - tMemoryStream.save_to(m_cross_table_name); - // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); - - // Msg ("Freiing cross table resources"); - - m_marks.clear(); - m_mark_stack.clear(); - m_distances.clear(); - m_current_fringe.clear(); - m_next_fringe.clear(); - - // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::build_cross_table(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Building cross table"); - - // CTimer timer; - // timer.Start (); - - fill_marks(start + 0.000000f * amount, 0.018725f * amount); - // Msg ("CT : %f",timer.GetElapsed_sec()); - fill_distances(start + 0.018725f * amount, 0.183732f * amount); - // Msg ("CT : %f",timer.GetElapsed_sec()); - iterate_distances(start + 0.202457f * amount, 0.757202f * amount); - // Msg ("CT : %f",timer.GetElapsed_sec()); - save_cross_table(start + 0.959659f * amount, 0.040327f * amount); - // Msg ("CT : %f",timer.GetElapsed_sec()); - load_cross_table(start + 0.999986f * amount, 0.000014f * amount); - // Msg ("CT : %f",timer.GetElapsed_sec()); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::load_cross_table(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Loading cross table"); - - VERIFY(!m_cross_table); - m_cross_table = xr_new(m_cross_table_name); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::fill_neighbours(const u32& game_vertex_id) -{ - m_marks.assign(level_graph().header().vertex_count(), false); - m_current_fringe.clear(); - - u32 level_vertex_id = graph().vertex(game_vertex_id)->data().level_vertex_id(); - - m_mark_stack.reserve(8192); - m_mark_stack.push_back(level_vertex_id); - - for (; !m_mark_stack.empty();) - { - level_vertex_id = m_mark_stack.back(); - m_mark_stack.resize(m_mark_stack.size() - 1); - auto node = level_graph().vertex(level_vertex_id); - m_marks[level_vertex_id] = true; - for (const auto &i : {0, 1, 2, 3}) - { - u32 next_level_vertex_id = node->link(i); - - if (!level_graph().valid_vertex_id(next_level_vertex_id)) - continue; - - if (m_marks[next_level_vertex_id]) - continue; - - GameGraph::_GRAPH_ID next_game_vertex_id = cross().vertex(next_level_vertex_id).game_vertex_id(); - VERIFY(next_game_vertex_id < graph().vertices().size()); - if (next_game_vertex_id != (GameGraph::_GRAPH_ID)game_vertex_id) - { - if (std::find(m_current_fringe.begin(), m_current_fringe.end(), next_game_vertex_id) == - m_current_fringe.end()) - m_current_fringe.push_back(next_game_vertex_id); - continue; - } - - m_mark_stack.push_back(next_level_vertex_id); - } - } -} - -float CGameGraphBuilder::path_distance(const u32& game_vertex_id0, const u32& game_vertex_id1) -{ - // return - //(graph().vertex(game_vertex_id0)->data().level_point().distance_to(graph().vertex(game_vertex_id1)->data().level_point())); - - VERIFY(m_graph_engine); - - graph_type::CVertex& vertex0 = *graph().vertex(game_vertex_id0); - graph_type::CVertex& vertex1 = *graph().vertex(game_vertex_id1); - - typedef GraphEngineSpace::CStraightLineParams CStraightLineParams; - CStraightLineParams parameters(vertex0.data().level_point(), vertex1.data().level_point()); - - float pure_distance = vertex0.data().level_point().distance_to_xz(vertex1.data().level_point()); - // float pure_distance = vertex0.data().level_point().distance_to(vertex1.data().level_point()); - VERIFY(pure_distance < parameters.max_range); - - u32 level_vertex_id = level_graph().check_position_in_direction( - vertex0.data().level_vertex_id(), vertex0.data().level_point(), vertex1.data().level_point()); - if (level_graph().valid_vertex_id(level_vertex_id)) - return (pure_distance); - - bool successfull = m_graph_engine->search( - level_graph(), vertex0.data().level_vertex_id(), vertex1.data().level_vertex_id(), &m_path, parameters); - - if (successfull) - return (parameters.m_distance); - - Msg("Cannot build path from [%d] to [%d]", game_vertex_id0, game_vertex_id1); - Msg("Cannot build path from [%f][%f][%f] to [%f][%f][%f]", VPUSH(vertex0.data().level_point()), - VPUSH(vertex1.data().level_point())); - R_ASSERT2(false, "Cannot build path, check AI map"); - return flt_max; -} - -void CGameGraphBuilder::generate_edges(const u32& game_vertex_id) -{ - auto vertex = graph().vertex(game_vertex_id); - - for (const auto &i: m_current_fringe) - { - VERIFY(!vertex->edge(i)); - float distance = path_distance(game_vertex_id, i); - graph().add_edge(game_vertex_id, i, distance); - } -} - -void CGameGraphBuilder::generate_edges(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Generating edges"); - - for (const auto &i : graph().vertices()) - { - fill_neighbours(i.second->vertex_id()); - generate_edges(i.second->vertex_id()); - } - - Msg("%d edges built", graph().edge_count()); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::connectivity_check(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Checking graph connectivity"); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::create_tripples(const float& /*start*/, const float& /*amount*/) -{ - for (const auto &i: graph().vertices()) - { - for (const auto &j : i.second->edges()) - { - if ((j.vertex_id() < i.first) && graph().edge(j.vertex_id(), i.first)) - continue; - - const graph_type::CEdge* edge = graph().vertex(j.vertex_id())->edge(i.first); - - m_tripples.emplace_back(std::min(j.weight(), edge ? edge->weight() : j.weight()), - std::make_pair(i.first, j.vertex_id())); - } - } - - std::sort(m_tripples.begin(), m_tripples.end(), sort_predicate_greater); -} - -void CGameGraphBuilder::process_tripple(const TRIPPLE& tripple) -{ - const graph_type::CVertex& vertex0 = *graph().vertex(tripple.second.first); - const graph_type::CVertex& vertex1 = *graph().vertex(tripple.second.second); - - for (const auto &i : vertex0.edges()) - { - if (i.vertex_id() == tripple.second.second) - continue; - - const graph_type::CEdge* edge; - - edge = vertex1.edge(i.vertex_id()); - if (edge) - { - VERIFY(_min(i.weight(), graph().edge(i.vertex_id(), tripple.second.first) ? - graph().edge(i.vertex_id(), tripple.second.first)->weight() : - i.weight()) <= tripple.first); - VERIFY(_min(edge->weight(), graph().edge(edge->vertex_id(), tripple.second.second) ? - graph().edge(edge->vertex_id(), tripple.second.second)->weight() : - i.weight()) <= tripple.first); - if (vertex0.edge(tripple.second.second)) - graph().remove_edge(tripple.second.first, tripple.second.second); - if (vertex1.edge(tripple.second.first)) - graph().remove_edge(tripple.second.second, tripple.second.first); - return; - } - - edge = graph().vertex(i.vertex_id())->edge(tripple.second.second); - if (edge) - { - VERIFY(_min(i.weight(), graph().edge(i.vertex_id(), tripple.second.first) ? - graph().edge(i.vertex_id(), tripple.second.first)->weight() : - i.weight()) <= tripple.first); - VERIFY(edge->weight() <= tripple.first); - if (vertex0.edge(tripple.second.second)) - graph().remove_edge(tripple.second.first, tripple.second.second); - if (vertex1.edge(tripple.second.first)) - graph().remove_edge(tripple.second.second, tripple.second.first); - return; - } - } - return; -} - -void CGameGraphBuilder::optimize_graph(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Optimizing graph"); - - Msg("edges before optimization : %d", graph().edge_count()); - - create_tripples(start + .00f, amount * .50f); - - for (const auto &i: m_tripples) - process_tripple(i); - - Msg("edges after optimization : %d", graph().edge_count()); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::save_graph(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Saving graph"); - - // header - CMemoryWriter writer; - CGameGraph::CHeader header; - header.m_version = XRAI_CURRENT_VERSION; - VERIFY(graph().vertices().size() < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - header.m_vertex_count = (GameGraph::_GRAPH_ID)graph().vertices().size(); - VERIFY(graph().edge_count() < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - header.m_edge_count = (GameGraph::_GRAPH_ID)graph().edge_count(); - header.m_death_point_count = 0; - header.m_guid = m_graph_guid; - - // levels - CGameGraph::SLevel level; - level.m_offset.set(0, 0, 0); - level.m_id = 0; - level.m_name = m_level_name; - level.m_section = ""; - level.m_guid = level_graph().header().guid(); - - header.m_levels.emplace(level.m_id, level); - - header.save(&writer); - - { - u32 edge_offset = graph().vertices().size() * sizeof(CGameGraph::CGameVertex); - - for (const auto &i: graph().vertices()) - { - CGameGraph::CGameVertex& vertex = i.second->data(); - - VERIFY(i.second->edges().size() < 256); - vertex.tNeighbourCount = (u8)i.second->edges().size(); - vertex.dwEdgeOffset = edge_offset; - edge_offset += vertex.tNeighbourCount * sizeof(CGameGraph::CEdge); - - writer.w(&vertex, sizeof(CGameGraph::CGameVertex)); - } - } - - { - for (const auto &i : graph().vertices()) - { - for (const auto &j: i.second->edges()) - { - GameGraph::CEdge edge; - VERIFY(j.vertex_id() < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - edge.m_vertex_id = (GameGraph::_GRAPH_ID)j.vertex_id(); - edge.m_path_distance = j.weight(); - - writer.w(&edge.m_vertex_id, sizeof(edge.m_vertex_id)); - writer.w_float(edge.m_path_distance); - } - } - } - - writer.save_to(m_graph_name); - Msg("%d bytes saved", int(writer.size())); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::build_graph(const float& start, const float& amount) -{ - Logger.Progress(start); - - Msg("Building graph"); - - CTimer timer; - timer.Start(); - - m_graph_engine = xr_new(level_graph().header().vertex_count()); - Logger.Progress(start + 0.000000f * amount + amount * 0.067204f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - - generate_edges(start + 0.067204f * amount, amount * 0.922647f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - - xr_delete(m_graph_engine); - Logger.Progress(start + 0.989851f * amount + amount * 0.002150f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - - connectivity_check(start + 0.992001f * amount, amount * 0.000030f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - optimize_graph(start + 0.992031f * amount, amount * 0.000454f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - save_graph(start + 0.992485f * amount, amount * 0.007515f); - // Msg ("BG : %f",timer.GetElapsed_sec()); - - Logger.Progress(start + amount); -} - -void CGameGraphBuilder::build_graph(LPCSTR graph_name, LPCSTR cross_table_name, LPCSTR level_name) -{ - Logger.Phase("Building level game graph"); - Msg("level \"%s\"", level_name); - - m_graph_name = graph_name; - m_cross_table_name = cross_table_name; - m_level_name = level_name; - - // CTimer timer; - // timer.Start (); - - create_graph(0.000000f, 0.000047f); - // Msg ("%f",timer.GetElapsed_sec()); - load_level_graph(0.000047f, 0.002470f); - // Msg ("%f",timer.GetElapsed_sec()); - load_graph_points(0.002517f, 0.111812f); - // Msg ("%f",timer.GetElapsed_sec()); - build_cross_table(0.114329f, 0.773423f); - // Msg ("%f",timer.GetElapsed_sec()); - build_graph(0.887752f, 0.112248f); - // Msg ("%f",timer.GetElapsed_sec()); - - Msg("Level graph is generated successfully"); -} diff --git a/src/utils/xrAI/game_graph_builder.h b/src/utils/xrAI/game_graph_builder.h deleted file mode 100644 index f75eb5e11d4..00000000000 --- a/src/utils/xrAI/game_graph_builder.h +++ /dev/null @@ -1,87 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_graph_builder.h -// Created : 14.12.2005 -// Modified : 14.12.2005 -// Author : Dmitriy Iassenev -// Description : Game graph builder -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xrAICore/Navigation/graph_abstract.h" -#include "xrAICore/Navigation/graph_engine.h" - -class CGameGraphBuilder -{ -private: - typedef GameGraph::CGameVertex vertex_type; - typedef CGraphAbstract graph_type; - typedef xr_vector> DISTANCES; - typedef std::pair PAIR; - typedef std::pair TRIPPLE; - typedef xr_vector TRIPPLES; - -private: - LPCSTR m_graph_name; - LPCSTR m_cross_table_name; - -private: - shared_str m_level_name; - -private: - CLevelGraph* m_level_graph; - graph_type* m_graph; - xrGUID m_graph_guid; - // cross table generation stuff - xr_vector m_marks; - xr_vector m_mark_stack; - DISTANCES m_distances; - xr_vector m_current_fringe; - xr_vector m_next_fringe; - xr_vector m_results; - // cross table itself - CGameLevelCrossTable* m_cross_table; - TRIPPLES m_tripples; - xr_vector m_path; - CGraphEngine* m_graph_engine; - -private: - void create_graph(const float& start, const float& amount); - void load_level_graph(const float& start, const float& amount); - void load_graph_point(NET_Packet& net_packet); - void load_graph_points(const float& start, const float& amount); - -private: - void mark_vertices(u32 level_vertex_id); - void fill_marks(const float& start, const float& amount); - void fill_distances(const float& start, const float& amount); - void recursive_update(const u32& index, const float& start, const float& amount); - void iterate_distances(const float& start, const float& amount); - void save_cross_table(const float& start, const float& amount); - void build_cross_table(const float& start, const float& amount); - void load_cross_table(const float& start, const float& amount); - -private: - void fill_neighbours(const u32& game_vertex_id); - float path_distance(const u32& game_vertex_id0, const u32& game_vertex_id1); - void generate_edges(const u32& vertex_id); - void generate_edges(const float& start, const float& amount); - void connectivity_check(const float& start, const float& amount); - void create_tripples(const float& start, const float& amount); - void process_tripple(const TRIPPLE& tripple); - void optimize_graph(const float& start, const float& amount); - void save_graph(const float& start, const float& amount); - void build_graph(const float& start, const float& amount); - -private: - IC CLevelGraph& level_graph() const; - IC graph_type& graph() const; - IC CGameLevelCrossTable& cross() const; - -public: - CGameGraphBuilder(); - ~CGameGraphBuilder(); - void build_graph(LPCSTR graph_name, LPCSTR cross_table_name, LPCSTR level_name); -}; - -#include "game_graph_builder_inline.h" diff --git a/src/utils/xrAI/game_graph_builder_inline.h b/src/utils/xrAI/game_graph_builder_inline.h deleted file mode 100644 index cea1dec6a70..00000000000 --- a/src/utils/xrAI/game_graph_builder_inline.h +++ /dev/null @@ -1,27 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_graph_builder_inline.h -// Created : 14.12.2005 -// Modified : 14.12.2005 -// Author : Dmitriy Iassenev -// Description : Game graph builder inline functions -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -IC CLevelGraph& CGameGraphBuilder::level_graph() const -{ - VERIFY(m_level_graph); - return (*m_level_graph); -} - -IC CGameGraphBuilder::graph_type& CGameGraphBuilder::graph() const -{ - VERIFY(m_graph); - return (*m_graph); -} - -IC CGameLevelCrossTable& CGameGraphBuilder::cross() const -{ - VERIFY(m_cross_table); - return (*m_cross_table); -} diff --git a/src/utils/xrAI/game_spawn_constructor.cpp b/src/utils/xrAI/game_spawn_constructor.cpp deleted file mode 100644 index 273e7adc1d3..00000000000 --- a/src/utils/xrAI/game_spawn_constructor.cpp +++ /dev/null @@ -1,319 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_spawn_constructor.cpp -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Game spawn constructor -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "game_spawn_constructor.h" -#include "xrAICore/Navigation/graph_engine.h" -#include "xrAICore/Navigation/PatrolPath/patrol_path_storage.h" -#include "level_spawn_constructor.h" -#include "xrAI.h" - -extern LPCSTR GAME_CONFIG; -extern LPCSTR generate_temp_file_name(LPCSTR header0, LPCSTR header1, string_path& buffer); - -#define NO_MULTITHREADING - -CGameSpawnConstructor::CGameSpawnConstructor(LPCSTR name, LPCSTR output, LPCSTR start, bool no_separator_check) - : -#ifdef CONFIG_PROFILE_LOCKS - m_critical_section(MUTEX_PROFILE_ID(CGameSpawnConstructor)), -#endif // CONFIG_PROFILE_LOCKS - m_thread_manager(ProxyStatus, ProxyProgress) -{ - load_spawns(name, no_separator_check); - process_spawns(); - process_actor(start); - save_spawn(name, output); -} - -CGameSpawnConstructor::~CGameSpawnConstructor() -{ - delete_data(m_level_spawns); - delete_data(m_spawn_graph); - xr_delete(m_game_graph); - xr_delete(m_game_info); - xr_delete(m_patrol_path_storage); -} - -IC shared_str CGameSpawnConstructor::actor_level_name() -{ - string256 temp; - return (strconcat(sizeof(temp), temp, - *game_graph().header().level(game_graph().vertex(m_actor->m_tGraphID)->level_id()).name(), ".spawn")); -} - -extern void read_levels(CInifile* ini, xr_set& m_levels, bool rebuild_graph, xr_vector*); -void fill_needed_levels(pstr levels, xr_vector& result); - -void CGameSpawnConstructor::load_spawns(LPCSTR name, bool no_separator_check) -{ - m_spawn_id = 0; - - // init spawn graph - m_spawn_graph = xr_new(); - - // init ini file - m_game_info = xr_new(INI_FILE); - R_ASSERT(m_game_info->section_exist("levels")); - - // init patrol path storage - m_patrol_path_storage = xr_new(); - xr_vector needed_levels; - string4096 levels_string; - xr_strcpy(levels_string, name); - xr_strlwr(levels_string); - fill_needed_levels(levels_string, needed_levels); - - // fill level info - read_levels(&game_info(), m_levels, false, &needed_levels); - - // init game graph - generate_temp_file_name("game_graph", "", m_game_graph_id); - xrMergeGraphs(m_game_graph_id, name, false); - m_game_graph = xr_new(m_game_graph_id); - - // load levels - GameGraph::SLevel level; - for (const auto &i : m_levels) - { - level.m_offset = i.m_offset; - level.m_name = i.m_name; - level.m_id = i.m_id; - Msg("%9s %2d %s", "level", level.id(), *i.m_name); - m_level_spawns.push_back(xr_new(level, this, no_separator_check)); - } - - string256 temp; - xr_sprintf(temp, "There are no valid levels (with AI-map and graph) in the section 'levels' in the '%s' to build spawn file from!", GAME_CONFIG); - R_ASSERT2(!m_level_spawns.empty(), temp); -} - -void CGameSpawnConstructor::process_spawns() -{ - for (auto &i: m_level_spawns) -#ifdef NO_MULTITHREADING - i->Execute(); -#else - m_thread_manager.start(i); - m_thread_manager.wait(); -#endif - - for (auto &i : m_level_spawns) - i->update(); - - verify_level_changers(); - verify_spawns(); -} - -void CGameSpawnConstructor::verify_spawns(ALife::_SPAWN_ID spawn_id) -{ - auto J = std::find(m_temp0.begin(), m_temp0.end(), spawn_id); - R_ASSERT3(J == m_temp0.end(), "RECURSIVE Spawn group chain found in spawn", - m_spawn_graph->vertex(spawn_id)->data()->object().name_replace()); - m_temp0.push_back(spawn_id); - - auto vertex = m_spawn_graph->vertex(spawn_id); - for (const auto &i : vertex->edges()) - verify_spawns(i.vertex_id()); -} - -void CGameSpawnConstructor::verify_spawns() -{ - for (const auto &i : m_spawn_graph->vertices()) - { - m_temp0.clear(); - verify_spawns(i.second->vertex_id()); - } -} - -void CGameSpawnConstructor::verify_level_changers() -{ - if (m_level_changers.empty()) - return; - - Msg("List of the level changers which are invalid for some reasons"); - - for (const auto &i : m_level_changers) - Msg("%s", i->name_replace()); - - VERIFY2(m_level_changers.empty(), "Some of the level changers setup incorrectly"); -} - -void CGameSpawnConstructor::save_spawn(LPCSTR name, LPCSTR output) -{ - CMemoryWriter stream; - - m_spawn_header.m_version = XRAI_CURRENT_VERSION; - m_spawn_header.m_guid = generate_guid(); - m_spawn_header.m_graph_guid = game_graph().header().guid(); - m_spawn_header.m_spawn_count = spawn_graph().vertex_count(); - m_spawn_header.m_level_count = (u32)m_level_spawns.size(); - - stream.open_chunk(0); - stream.w_u32(m_spawn_header.m_version); - save_data(m_spawn_header.m_guid, stream); - save_data(m_spawn_header.m_graph_guid, stream); - stream.w_u32(m_spawn_header.m_spawn_count); - stream.w_u32(m_spawn_header.m_level_count); - stream.close_chunk(); - - stream.open_chunk(1); - save_data(spawn_graph(), stream); - stream.close_chunk(); - - stream.open_chunk(2); - save_data(m_level_points, stream); - stream.close_chunk(); - - stream.open_chunk(3); - save_data(m_patrol_path_storage, stream); - stream.close_chunk(); - - stream.open_chunk(4); - m_game_graph->save(stream); - stream.close_chunk(); - - stream.save_to(*spawn_name(output)); -} - -shared_str CGameSpawnConstructor::spawn_name(LPCSTR output) -{ - string_path file_name; - if (!output) - FS.update_path(file_name, "$game_spawn$", *actor_level_name()); - else - { - actor_level_name(); - string_path out; - strconcat(sizeof(out), out, output, ".spawn"); - FS.update_path(file_name, "$game_spawn$", out); - } - return (file_name); -} - -void CGameSpawnConstructor::add_story_object(ALife::_STORY_ID id, CSE_ALifeDynamicObject* object, LPCSTR level_name) -{ - if (id == INVALID_STORY_ID) - return; - - auto I = m_story_objects.find(id); - if (I != m_story_objects.end()) - { - Msg("Object %s, story id %d", object->name_replace(), object->m_story_id); - Msg("Object %s, story id %d", (*I).second->name_replace(), (*I).second->m_story_id); - VERIFY3(I == m_story_objects.end(), "There are several objects which has the same unique story ID, level ", level_name); - } - - m_story_objects.insert(std::make_pair(id, object)); -} - -void CGameSpawnConstructor::add_object(CSE_Abstract* object) -{ - m_critical_section.Enter(); - object->m_tSpawnID = spawn_id(); - spawn_graph().add_vertex(xr_new(object), object->m_tSpawnID); - m_critical_section.Leave(); -} - -void CGameSpawnConstructor::remove_object(CSE_Abstract* object) { spawn_graph().remove_vertex(object->m_tSpawnID); } -void CGameSpawnConstructor::process_actor(LPCSTR start_level_name) -{ - m_actor = nullptr; - - for (const auto &i : m_level_spawns) - { - if (!i->actor()) - continue; - - Msg("Actor is on the level %s", *game_graph().header().level(game_graph().vertex(i->actor()->m_tGraphID)->level_id()).name()); - VERIFY2(!m_actor, "There must be the SINGLE level with ACTOR!"); - m_actor = i->actor(); - } - - R_ASSERT2(m_actor, "There is no ACTOR spawn point!"); - - if (!start_level_name) - return; - - if (!xr_strcmp(*actor_level_name(), start_level_name)) - return; - - const auto& level = game_graph().header().level(start_level_name); - auto dest = GameGraph::_GRAPH_ID(-1); - GraphEngineSpace::CGameLevelParams evaluator(level.id()); - auto graph_engine = xr_new(game_graph().header().vertex_count()); - - bool failed = !graph_engine->search(game_graph(), m_actor->m_tGraphID, GameGraph::_GRAPH_ID(-1), nullptr, evaluator); - if (failed) - { - Msg("! Cannot build path via game graph from the current level to the level %s!", start_level_name); - float min_dist = flt_max; - auto current = game_graph().vertex(m_actor->m_tGraphID)->game_point(); - auto n = game_graph().header().vertex_count(); - for (GameGraph::_GRAPH_ID i = 0; i < n; ++i) - { - if (game_graph().vertex(i)->level_id() == level.id()) - { - float distance = game_graph().vertex(i)->game_point().distance_to_sqr(current); - if (distance < min_dist) - { - min_dist = distance; - dest = i; - } - } - } - if (!game_graph().vertex(dest)) - { - Msg("! There is no game vertices on the level %s, cannot jump to the specified level", start_level_name); - xr_delete(graph_engine); - return; - } - } - else - dest = (GameGraph::_GRAPH_ID)evaluator.selected_vertex_id(); - - m_actor->m_tGraphID = dest; - m_actor->m_tNodeID = game_graph().vertex(dest)->level_vertex_id(); - m_actor->o_Position = game_graph().vertex(dest)->level_point(); - - xr_delete(graph_engine); -} - -void clear_temp_folder() -{ - string_path query; - FS.update_path(query, "$app_data_root$", "temp\\*.*"); - string_path path_root; - FS.update_path(path_root, "$app_data_root$", "temp\\"); - string_path path_final; - - _finddata_t file; - auto handle = _findfirst(query, &file); - if (handle == intptr_t(-1)) - return; - - xr_vector files; - do - { - if (file.attrib & _A_SUBDIR) - continue; - - strconcat(sizeof(path_final), path_final, path_root, file.name); - files.push_back(path_final); - } while (!_findnext(handle, &file)); - - _findclose(handle); - - for (const auto &i : files) - { - if (DeleteFile(*i)) - Msg("file %s is successfully deleted", *i); - else - Msg("cannot delete file %s", *i); - } -} diff --git a/src/utils/xrAI/game_spawn_constructor.h b/src/utils/xrAI/game_spawn_constructor.h deleted file mode 100644 index 093e61178b6..00000000000 --- a/src/utils/xrAI/game_spawn_constructor.h +++ /dev/null @@ -1,100 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_spawn_constructor.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Game spawn constructor -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xr_graph_merge.h" -#include "xrAICore/Navigation/graph_abstract.h" -#include "xrServerEntities/alife_space.h" -#include "level_spawn_constructor.h" -#include "spawn_constructor_space.h" -#include "server_entity_wrapper.h" -#include "guid_generator.h" - -class CLevelSpawnConstructor; - -class CGameSpawnConstructor -{ - friend class CSpawnMerger; - -public: - typedef SpawnConstructorSpace::LEVEL_POINT_STORAGE LEVEL_POINT_STORAGE; - typedef SpawnConstructorSpace::LEVEL_CHANGER_STORAGE LEVEL_CHANGER_STORAGE; - typedef CGraphAbstractSerialize SPAWN_GRAPH; - typedef xr_vector LEVEL_SPAWN_STORAGE; - typedef xr_set LEVEL_INFO_STORAGE; - -public: - struct CSpawnHeader - { - u32 m_version; - xrGUID m_guid; - xrGUID m_graph_guid; - u32 m_spawn_count; - u32 m_level_count; - }; - -private: - Lock m_critical_section; - ALife::_SPAWN_ID m_spawn_id; - CThreadManager m_thread_manager; - CSpawnHeader m_spawn_header; - ALife::STORY_P_MAP m_story_objects; - LEVEL_INFO_STORAGE m_levels; - LEVEL_SPAWN_STORAGE m_level_spawns; - LEVEL_CHANGER_STORAGE m_level_changers; - LEVEL_POINT_STORAGE m_level_points; - bool m_no_separator_check; - -private: - xr_vector m_spawn_roots; - xr_vector m_temp0; - xr_vector m_temp1; - -private: - CGameGraph* m_game_graph; - SPAWN_GRAPH* m_spawn_graph; - CPatrolPathStorage* m_patrol_path_storage; - CInifile* m_game_info; - CSE_ALifeCreatureAbstract* m_actor; - -private: - string_path m_game_graph_id; - -private: - IC shared_str actor_level_name(); - IC shared_str spawn_name(LPCSTR output); - void save_spawn(LPCSTR name, LPCSTR output); - void verify_level_changers(); - void verify_spawns(ALife::_SPAWN_ID spawn_id); - void verify_spawns(); - void process_spawns(); - void load_spawns(LPCSTR name, bool no_separator_check); - IC SPAWN_GRAPH& spawn_graph(); - IC ALife::_SPAWN_ID spawn_id(); - IC void process_spawns(xr_vector& spawns); - void process_actor(LPCSTR start_level_name); - -public: - CGameSpawnConstructor(LPCSTR name, LPCSTR output, LPCSTR start, bool no_separator_check); - virtual ~CGameSpawnConstructor(); - void add_story_object(ALife::_STORY_ID id, CSE_ALifeDynamicObject* object, LPCSTR level_name); - void add_object(CSE_Abstract* object); - void remove_object(CSE_Abstract* object); - IC void add_level_changer(CSE_ALifeLevelChanger* level_changer); - IC void add_level_points(const LEVEL_POINT_STORAGE& level_points); - IC u32 level_id(LPCSTR level_name); - IC CGameGraph& game_graph() const; - IC CInifile& game_info(); - IC void add_edge(ALife::_SPAWN_ID id0, ALife::_SPAWN_ID id1, float weight); - IC u32 level_point_count() const; - IC LEVEL_CHANGER_STORAGE& level_changers(); - IC CPatrolPathStorage& patrol_path_storage() const; -}; - -#include "game_spawn_constructor_inline.h" diff --git a/src/utils/xrAI/game_spawn_constructor_inline.h b/src/utils/xrAI/game_spawn_constructor_inline.h deleted file mode 100644 index 894ab223a3c..00000000000 --- a/src/utils/xrAI/game_spawn_constructor_inline.h +++ /dev/null @@ -1,50 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : game_spawn_constructor_inline.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Game spawn constructor inline functions -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -extern u32 dwfGetIDByLevelName(CInifile* ini, LPCSTR level_name); - -IC CGameGraph& CGameSpawnConstructor::game_graph() const { return (*m_game_graph); } -IC CInifile& CGameSpawnConstructor::game_info() { return (*m_game_info); } -IC CGameSpawnConstructor::SPAWN_GRAPH& CGameSpawnConstructor::spawn_graph() { return (*m_spawn_graph); } -IC u32 CGameSpawnConstructor::level_id(LPCSTR level_name) { return (dwfGetIDByLevelName(&game_info(), level_name)); } -IC ALife::_SPAWN_ID CGameSpawnConstructor::spawn_id() { return (m_spawn_id++); } -IC void CGameSpawnConstructor::add_level_points(const LEVEL_POINT_STORAGE& level_points) -{ - m_level_points.insert(m_level_points.end(), level_points.begin(), level_points.end()); -} - -IC void CGameSpawnConstructor::add_level_changer(CSE_ALifeLevelChanger* level_changer) -{ - m_critical_section.Enter(); - m_level_changers.push_back(level_changer); - m_critical_section.Leave(); -} - -IC void CGameSpawnConstructor::add_edge(ALife::_SPAWN_ID id0, ALife::_SPAWN_ID id1, float weight) -{ - m_critical_section.Enter(); - spawn_graph().add_edge(id0, id1, weight); - m_critical_section.Leave(); -} - -IC u32 CGameSpawnConstructor::level_point_count() const { return ((u32)m_level_points.size()); } -IC CGameSpawnConstructor::LEVEL_CHANGER_STORAGE& CGameSpawnConstructor::level_changers() { return (m_level_changers); } -IC CPatrolPathStorage& CGameSpawnConstructor::patrol_path_storage() const -{ - VERIFY(m_patrol_path_storage); - return (*m_patrol_path_storage); -} - -IC void CGameSpawnConstructor::process_spawns(xr_vector& spawns) -{ - std::sort(spawns.begin(), spawns.end()); - xr_vector::iterator I = std::unique(spawns.begin(), spawns.end()); - spawns.erase(I, spawns.end()); -} diff --git a/src/utils/xrAI/guid_generator.cpp b/src/utils/xrAI/guid_generator.cpp deleted file mode 100644 index a0b39355bf0..00000000000 --- a/src/utils/xrAI/guid_generator.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : guid_generator.cpp -// Created : 21.03.2005 -// Modified : 21.03.2005 -// Author : Dmitriy Iassenev -// Description : GUID generator -//////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#pragma hdrstop - -#include "guid_generator.h" - -#ifdef WINVER -#include -#include -#pragma comment(lib, "rpcrt4.lib") -#endif - -xrGUID generate_guid() -{ - xrGUID result; -#ifdef WINVER - static_assert(sizeof(xrGUID) == sizeof(GUID), "Different GUID types."); - GUID _result; - RPC_STATUS gen_result = UuidCreate(&_result); - memcpy(&result, &_result, sizeof(_result)); - switch (gen_result) - { - case RPC_S_OK: return (result); - case RPC_S_UUID_LOCAL_ONLY: return (result); - case RPC_S_UUID_NO_ADDRESS: - default: break; - } -#endif - static_assert(sizeof(result) >= sizeof(u64), "GUID must have size greater or equal to the long long."); - ZeroMemory(&result, sizeof(result)); - u64 temp = CPU::QPC(); - memcpy(&result, &temp, sizeof(temp)); - return (result); -} - -LPCSTR generate_guid(const xrGUID& guid, pstr buffer, const size_t& buffer_size) -{ -#ifdef WINVER - static_assert(sizeof(xrGUID) == sizeof(GUID), "Different GUID types."); - GUID temp; - memcpy(&temp, &guid, sizeof(guid)); - RPC_CSTR temp2; - RPC_STATUS status = UuidToString(&temp, &temp2); - switch (status) - { - case RPC_S_OK: break; - case RPC_S_OUT_OF_MEMORY: NODEFAULT; - default: NODEFAULT; - } - VERIFY(buffer_size > xr_strlen((LPCSTR)temp2)); - xr_strcpy(buffer, buffer_size, (LPCSTR)temp2); - RpcStringFree(&temp2); - return (buffer); -#else - NODEFAULT; -#endif // WINVER -} diff --git a/src/utils/xrAI/guid_generator.h b/src/utils/xrAI/guid_generator.h deleted file mode 100644 index aadb85076c8..00000000000 --- a/src/utils/xrAI/guid_generator.h +++ /dev/null @@ -1,15 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : guid_generator.h -// Created : 21.03.2005 -// Modified : 21.03.2005 -// Author : Dmitriy Iassenev -// Description : GUID generator -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "Common/GUID.hpp" - -// XXX: move to xrCore -xrGUID generate_guid(); -LPCSTR generate_guid(const xrGUID& guid, pstr buffer, const size_t& buffer_size); diff --git a/src/utils/xrAI/level_spawn_constructor.cpp b/src/utils/xrAI/level_spawn_constructor.cpp deleted file mode 100644 index ff039cee9ec..00000000000 --- a/src/utils/xrAI/level_spawn_constructor.cpp +++ /dev/null @@ -1,625 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : level_spawn_constructor.cpp -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Level spawn constructor -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "level_spawn_constructor.h" -#include "xrServerEntities/restriction_space.h" -#include "xrServerEntities/clsid_game.h" -#include "xrServerEntities/xrMessages.h" -#include "factory_api.h" -#include - -#define IGNORE_ZERO_SPAWN_POSITIONS - -const float y_shift_correction = .15f; - -CLevelSpawnConstructor::~CLevelSpawnConstructor() -{ - for (auto &i : m_graph_points) - F_entity_Destroy((CSE_Abstract*&)i); - - VERIFY(!m_level_graph); - VERIFY(!m_cross_table); - VERIFY(!m_graph_engine); -} - -IC const CGameGraph& CLevelSpawnConstructor::game_graph() const { return (m_game_spawn_constructor->game_graph()); } -IC CLevelSpawnConstructor::LEVEL_CHANGER_STORAGE& CLevelSpawnConstructor::level_changers() const -{ - return (m_game_spawn_constructor->level_changers()); -} - -IC u32 CLevelSpawnConstructor::level_id(shared_str level_name) const -{ - return (m_game_spawn_constructor->level_id(*level_name)); -} - -IC const CLevelGraph& CLevelSpawnConstructor::level_graph() const { return (*m_level_graph); } -IC const CGameLevelCrossTable& CLevelSpawnConstructor::cross_table() const { return (*m_cross_table); } -IC CGraphEngine& CLevelSpawnConstructor::graph_engine() const { return (*m_graph_engine); } -void CLevelSpawnConstructor::init() -{ - // loading level graph - string_path file_name; - FS.update_path(file_name, "$game_levels$", *m_level.name()); - xr_strcat(file_name, "\\"); - m_level_graph = xr_new(file_name); - - // loading cross table - m_game_spawn_constructor->game_graph().set_current_level(game_graph().header().level(*m_level.name()).id()); - m_cross_table = &game_graph().cross_table(); - - // loading patrol paths - FS.update_path(file_name, "$game_levels$", *m_level.name()); - xr_strcat(file_name, "\\level.game"); - if (FS.exist(file_name)) - { - IReader* stream = FS.r_open(file_name); - VERIFY(stream); - m_game_spawn_constructor->patrol_path_storage().load_raw( - &level_graph(), &cross_table(), &game_graph(), *stream); - FS.r_close(stream); - } -} - -CSE_Abstract* CLevelSpawnConstructor::create_object(IReader* chunk) -{ - NET_Packet net_packet; - net_packet.B.count = chunk->length(); - chunk->r(net_packet.B.data, net_packet.B.count); - // we do not need to close chunk since we iterate on them - // chunk->close (); - u16 ID; - net_packet.r_begin(ID); - R_ASSERT2(M_SPAWN == ID, "ID doesn't match to the spawn-point ID!"); - string64 section_name; - net_packet.r_stringZ(section_name); - CSE_Abstract* abstract = F_entity_Create(section_name); - if (!abstract) - { - string256 temp; - xr_sprintf(temp, "Can't create entity '%s' !\n", section_name); - R_ASSERT2(abstract, temp); - } - abstract->Spawn_Read(net_packet); - return (abstract); -} - -void CLevelSpawnConstructor::add_graph_point(CSE_Abstract* abstract) -{ - CSE_ALifeGraphPoint* graph_point = smart_cast(abstract); - R_ASSERT(graph_point); - m_graph_points.push_back(graph_point); -} - -// void CLevelSpawnConstructor::add_spawn_group (CSE_Abstract *abstract) -//{ -// CSE_SpawnGroup *spawn_group = smart_cast(abstract); -// R_ASSERT (spawn_group); -// m_spawn_groups.insert (std::make_pair(spawn_group->name_replace(),spawn_group)); -// if (xr_strlen(spawn_group->m_spawn_control)) -// add_group_object (spawn_group,spawn_group->m_spawn_control); -// add_free_object (abstract); -//} - -void CLevelSpawnConstructor::add_story_object(CSE_ALifeDynamicObject* dynamic_object) -{ - m_game_spawn_constructor->add_story_object(dynamic_object->m_story_id, dynamic_object, *m_level.name()); -} - -void CLevelSpawnConstructor::add_space_restrictor(CSE_ALifeDynamicObject* dynamic_object) -{ - CSE_ALifeSpaceRestrictor* space_restrictor = smart_cast(dynamic_object); - if (!space_restrictor) - return; - - if (space_restrictor->m_space_restrictor_type == RestrictionSpace::eRestrictorTypeNone) - return; - - if (!space_restrictor->m_flags.test(CSE_ALifeObject::flCheckForSeparator)) - return; - - m_space_restrictors.push_back(xr_new(space_restrictor)); -} - -void CLevelSpawnConstructor::add_level_changer(CSE_Abstract* abstract) -{ - CSE_ALifeLevelChanger* level_changer = smart_cast(abstract); - R_ASSERT(level_changer); - m_game_spawn_constructor->add_level_changer(level_changer); - m_level_changers.push_back(level_changer); -} - -void CLevelSpawnConstructor::add_free_object(CSE_Abstract* abstract) { m_game_spawn_constructor->add_object(abstract); } -// void CLevelSpawnConstructor::add_group_object (CSE_Abstract *abstract, shared_str -// group_section, -// bool) -//{ -// SPAWN_GRPOUP_OBJECTS::iterator I = m_spawn_objects.find(group_section); -// if (I == m_spawn_objects.end()) { -// xr_vector *temp = new GROUP_OBJECTS(); -// temp->clear (); -// temp->push_back (abstract); -// m_spawn_objects.insert (std::make_pair(group_section,temp)); -// } -// else -// (*I).second->push_back (abstract); -//} - -// void CLevelSpawnConstructor::add_group_object (CSE_Abstract *abstract, shared_str -// group_section) -//{ -// string256 temp; -// for (u32 i=0, n=_GetItemCount(*group_section); iopen_chunk_iterator(id); - for (; chunk; chunk = level_spawn->open_chunk_iterator(id, chunk)) - { - CSE_Abstract* abstract = create_object(chunk); - if (abstract->m_tClassID == CLSID_AI_GRAPH) - { - add_graph_point(abstract); - continue; - } - - // if (abstract->m_tClassID == CLSID_AI_SPAWN_GROUP) { - // add_spawn_group (abstract); - // continue; - // } - - if (!abstract->m_gameType.MatchType(eGameIDSingle)) - { - F_entity_Destroy(abstract); - continue; - } - - CSE_ALifeObject* alife_object = smart_cast(abstract); - if (!alife_object) - { - F_entity_Destroy(abstract); - continue; - } - - CSE_ALifeCreatureActor* actor = smart_cast(alife_object); - if (actor) - { - R_ASSERT3(!m_actor, "Too many actors on the level ", *m_level.name()); - m_actor = actor; - } - - m_spawns.push_back(alife_object); - - CSE_ALifeDynamicObject* dynamic_object = smart_cast(alife_object); - if (dynamic_object) - { - add_story_object(dynamic_object); - add_space_restrictor(dynamic_object); - } - - if (smart_cast(abstract)) - add_level_changer(abstract); - - // if (xr_strlen(alife_object->m_spawn_control)) - // add_group_object (alife_object,alife_object->m_spawn_control); - - add_free_object(alife_object); - } - - FS.r_close(level_spawn); - - R_ASSERT2(!m_spawns.empty(), "There are no spawn-points!"); -} - -// IC void CLevelSpawnConstructor::normalize_probability (CSE_ALifeAnomalousZone *zone) -//{ -// float accumulator = 0.f; -// for (int ii=0; iim_wItemCount; ii++) -// accumulator += zone->m_faWeights[ii]; -// -// accumulator *= zone->m_fBirthProbability; -// -// for (int ii=0; iim_wItemCount; ii++) -// zone->m_faWeights[ii] /= accumulator; -//} - -// IC void CLevelSpawnConstructor::free_group_objects () -//{ -// SPAWN_GRPOUP_OBJECTS::iterator I = m_spawn_objects.begin(); -// SPAWN_GRPOUP_OBJECTS::iterator E = m_spawn_objects.end(); -// for ( ; I != E; I++) -// xr_delete ((*I).second); -//} - -// void CLevelSpawnConstructor::fill_spawn_groups () -//{ -// SPAWN_GRPOUP_OBJECTS::iterator I = m_spawn_objects.begin(); -// SPAWN_GRPOUP_OBJECTS::iterator E = m_spawn_objects.end(); -// -// for ( ; I != E; I++) { -// R_ASSERT (xr_strlen(*(*I).first)); -// R_ASSERT ((*I).second); -// SPAWN_GROUPS::iterator J = m_spawn_groups.find((*I).first); -// if (J == m_spawn_groups.end()) -// clMsg ("! ERROR (spawn group not found!) : %s",*(*I).first); -// R_ASSERT3 (J != m_spawn_groups.end(),"Specified group control not -// found!",(*(*I).second)[0]->name_replace()); -// -// GROUP_OBJECTS::iterator i = (*I).second->begin(); -// GROUP_OBJECTS::iterator e = (*I).second->end(); -// for ( ; i != e; i++) { -// m_game_spawn_constructor->add_edge ((*J).second->m_tSpawnID,(*i)->m_tSpawnID,(*i)->m_spawn_probability); -// CSE_ALifeAnomalousZone *zone = smart_cast(*i); -// if (zone) -// normalize_probability (zone); -// } -// } -// -// free_group_objects (); -//} - -void CLevelSpawnConstructor::correct_objects() -{ - u32 m_level_graph_vertex_id = u32(-1); - u32 dwStart = game_graph().header().vertex_count(), dwFinish = game_graph().header().vertex_count(), dwCount = 0; - for (u32 i = 0; i < game_graph().header().vertex_count(); ++i) - if (game_graph().vertex(i)->level_id() == m_level.id()) - { - if (m_level_graph_vertex_id == u32(-1)) - m_level_graph_vertex_id = i; - dwCount++; - } - - for (int i = 0; i < (int)game_graph().header().vertex_count(); i++) - if (game_graph().vertex(i)->level_id() == m_level.id()) - { - if (dwStart > (u32)i) - dwStart = (u32)i; - } - else - { - if ((dwStart <= (u32)i) && (dwFinish > (u32)i)) - { - dwFinish = i; - break; - } - } - if (dwStart >= dwFinish) - { - string4096 S; - xr_sprintf(S, "There are no graph vertices in the game graph for the level '%s' !\n", *m_level.name()); - R_ASSERT2(dwStart < dwFinish, S); - } - - for (auto &i : m_spawns) - { - if (!i->used_ai_locations()) - { - i->m_tGraphID = (GameGraph::_GRAPH_ID)m_level_graph_vertex_id; - i->m_fDistance = 0.f; - i->m_tNodeID = game_graph().vertex(m_level_graph_vertex_id)->level_vertex_id(); - continue; - } - Fvector position = i->o_Position; - position.y += y_shift_correction; - i->m_tNodeID = level_graph().vertex(u32(-1), position); - VERIFY(level_graph().valid_vertex_id(i->m_tNodeID)); - if (i->used_ai_locations() && - !level_graph().inside(level_graph().vertex(i->m_tNodeID), position)) - { - Fvector new_position = level_graph().vertex_position(i->m_tNodeID); - Logger.clMsg("[%s][%s][%s] : position changed from [%f][%f][%f] -> [%f][%f][%f]", *m_level.name(), *i->s_name, i->name_replace(), VPUSH(position), VPUSH(new_position)); - i->o_Position = new_position; - } - u32 dwBest = cross_table().vertex(i->m_tNodeID).game_vertex_id(); - if (game_graph().vertex(dwBest)->level_id() != m_level.id()) - { - string4096 S1; - char* S = S1; - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Corresponding graph vertex for the spawn point is located on the ANOTHER level\n", i->name_replace()); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Current level : [%d][%s]\n", m_level.id(), *game_graph().header().level(m_level.id()).name()); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Conflict level : [%d][%s]\n", game_graph().vertex(dwBest)->level_id(), - *game_graph().header().level(game_graph().vertex(dwBest)->level_id()).name()); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Probably, you filled offsets in \"game_levels.ltx\" incorrect"); - R_ASSERT2(game_graph().vertex(dwBest)->level_id() == m_level.id(), S1); - } - - float fCurrentBestDistance = cross_table().vertex(i->m_tNodeID).distance(); - if (dwBest == u32(-1)) - { - string4096 S1; - char* S = S1; - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Can't find a corresponding GRAPH VERTEX for the spawn-point %s\n", i->name_replace()); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Level ID : %d\n", m_level.id()); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Spawn index : %d\n", i); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Spawn node : %d\n", i->m_tNodeID); - S += xr_sprintf(S, sizeof(S1) - (S1 - &S[0]), "Spawn point : [%7.2f][%7.2f][%7.2f]\n", i->o_Position.x, i->o_Position.y, i->o_Position.z); - R_ASSERT2(dwBest != -1, S1); - } - i->m_tGraphID = (GameGraph::_GRAPH_ID)dwBest; - i->m_fDistance = fCurrentBestDistance; - } -} - -void CLevelSpawnConstructor::correct_level_changers() -{ - for (auto &i : m_level_changers) - { - Fvector position = i->o_Position; - position.y += y_shift_correction; - i->m_tNodeID = level_graph().vertex(u32(-1), position); - VERIFY(level_graph().valid_vertex_id(i->m_tNodeID)); - - u32 dwBest = cross_table().vertex(i->m_tNodeID).game_vertex_id(); - VERIFY(game_graph().vertex(dwBest)->level_id() == m_level.id()); - i->m_tGraphID = (GameGraph::_GRAPH_ID)dwBest; - - i->m_fDistance = cross_table().vertex(i->m_tNodeID).distance(); - } -} - -struct remove_too_far_predicate -{ - float m_radius_sqr; - const CLevelGraph* m_graph; - Fvector m_position; - - IC remove_too_far_predicate(const CLevelGraph* graph, const Fvector& position, float radius) - { - VERIFY(graph); - m_graph = graph; - m_position = position; - m_radius_sqr = _sqr(radius); - } - - IC bool operator()(const u32& vertex_id) const - { - return (m_graph->vertex_position(vertex_id).distance_to_sqr(m_position) > m_radius_sqr); - } -}; - -#ifndef IGNORE_ZERO_SPAWN_POSITIONS -class remove_invalid_zones_predicate -{ -public: - typedef CLevelSpawnConstructor::SPAWN_STORAGE SPAWN_STORAGE; - -private: - const SPAWN_STORAGE* m_zones; - const CLevelSpawnConstructor* m_level_spawn_constructor; - -public: - IC remove_invalid_zones_predicate(const CLevelSpawnConstructor* level_spawn_constructor, const SPAWN_STORAGE* zones) - { - VERIFY(level_spawn_constructor); - m_level_spawn_constructor = level_spawn_constructor; - - VERIFY(zones); - m_zones = zones; - } - - IC bool operator()(CSE_ALifeObject* object) const - { - SPAWN_STORAGE::const_iterator I = std::find(m_zones->begin(), m_zones->end(), object); - if (I == m_zones->end()) - return (false); - - VERIFY(!object->m_spawn_control); - VERIFY(object->m_story_id == INVALID_STORY_ID); - m_level_spawn_constructor->game_spawn_constructor().remove_object(object); - CSE_Abstract* abstract = object; - F_entity_Destroy(abstract); - return (true); - } -}; -#endif - -void CLevelSpawnConstructor::generate_artefact_spawn_positions() -{ - // create graph engine - VERIFY(!m_graph_engine); - m_graph_engine = xr_new(m_level_graph->header().vertex_count()); - - xr_vector l_tpaStack; - //SPAWN_STORAGE zones; - l_tpaStack.reserve(1024); - for (auto &K : m_spawns) - { - CSE_ALifeAnomalousZone* zone = smart_cast(K); - if (!zone) - continue; - - //if (!level_graph().valid_vertex_position(zone->o_Position)) - //{ - // zone->m_artefact_spawn_count = 0; - // zone->m_artefact_position_offset = m_level_points.size(); - // continue; - //} - - zone->m_tNodeID = level_graph().vertex(zone->m_tNodeID, zone->o_Position); - if (!level_graph().valid_vertex_position(zone->o_Position) || - !level_graph().inside(zone->m_tNodeID, zone->o_Position)) - zone->m_tNodeID = level_graph().vertex(u32(-1), zone->o_Position); - const CGameLevelCrossTable::CCell& cell = cross_table().vertex(zone->m_tNodeID); - zone->m_tGraphID = cell.game_vertex_id(); - zone->m_fDistance = cell.distance(); - - graph_engine().search(level_graph(), zone->m_tNodeID, zone->m_tNodeID, &l_tpaStack, - SFlooder(zone->m_offline_interactive_radius, u32(-1), u32(-1))); - - l_tpaStack.erase( - std::remove_if(l_tpaStack.begin(), l_tpaStack.end(), - remove_too_far_predicate(&level_graph(), zone->o_Position, zone->m_offline_interactive_radius)), - l_tpaStack.end()); - /* - if (zone->m_artefact_spawn_count >= l_tpaStack.size()) - { - zone->m_artefact_spawn_count = (u16)l_tpaStack.size(); -#ifndef IGNORE_ZERO_SPAWN_POSITIONS - if (!zone->m_artefact_spawn_count) - { - Msg("! CANNOT GENERATE ARTEFACT SPAWN POSITIONS FOR ZONE [%s] ON LEVEL [%s]",zone->name_replace(),*level().name()); - Msg("! ZONE [%s] ON LEVEL [%s] IS REMOVED BY AI COMPILER",zone->name_replace(),*level().name()); - R_ASSERT3(zone->m_story_id == INVALID_STORY_ID,"Cannot remove story object",zone->name_replace()); - R_ASSERT3(!zone->m_spawn_control,"Cannot remove spawn control object",zone->name_replace()); - zones.push_back(zone); - l_tpaStack.clear(); - continue; - } -#endif - } - else*/ - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(l_tpaStack.begin(), l_tpaStack.end(), g); - - zone->m_artefact_position_offset = m_level_points.size(); - m_level_points.resize(zone->m_artefact_position_offset + zone->m_artefact_spawn_count); - - //Msg("%s %f [%f][%f][%f] : artefact spawn positions",zone->name_replace(),zone->m_fRadius,VPUSH(zone->o_Position)); - - LEVEL_POINT_STORAGE::iterator I = m_level_points.begin() + zone->m_artefact_position_offset; - LEVEL_POINT_STORAGE::iterator E = m_level_points.end(); - xr_vector::iterator i = l_tpaStack.begin(); - for (; I != E; ++I, ++i) - { - (*I).tNodeID = *i; - (*I).tPoint = level_graph().vertex_position(*i); - (*I).fDistance = cross_table().vertex(*i).distance(); - //Msg(" [%f][%f][%f] : %f",VPUSH((*I).tPoint),zone->o_Position.distance_to((*I).tPoint)); - } - - l_tpaStack.clear(); - } - -#ifndef IGNORE_ZERO_SPAWN_POSITIONS - I = std::remove_if(m_spawns.begin(), m_spawns.end(), remove_invalid_zones_predicate(this, &zones)); - m_spawns.erase(I, m_spawns.end()); -#endif -} - -void CLevelSpawnConstructor::fill_level_changers() -{ - for (u32 i = 0, n = (u32)level_changers().size(); i < n; ++i) - { - if (level_id(level_changers()[i]->m_caLevelToChange) != m_level.id()) - continue; - - bool found = false; - for (auto &j : m_graph_points) - { - if (!xr_strcmp(*level_changers()[i]->m_caLevelPointToChange, j->name_replace())) - { - bool ok = false; - for (u32 ii = 0, nn = game_graph().header().vertex_count(); ii < nn; ++ii) - { - if ((game_graph().vertex(ii)->level_id() != m_level.id()) || - !game_graph().vertex(ii)->level_point().similar(j->o_Position, .001f)) - continue; - level_changers()[i]->m_tNextGraphID = (GameGraph::_GRAPH_ID)ii; - level_changers()[i]->m_tNextPosition = j->o_Position; - level_changers()[i]->m_tAngles = j->o_Angle; - level_changers()[i]->m_dwNextNodeID = game_graph().vertex(ii)->level_vertex_id(); - ok = true; - break; - } - - R_ASSERT3(ok, "Cannot find a correspndance between graph and graph points from level editor! Rebuild graph for the level ", *level_changers()[i]->m_caLevelToChange); - - level_changers().erase(level_changers().begin() + i); - --i; - --n; - found = true; - break; - } - } - - if (!found) - { - Logger.clMsg("Graph point %s not found (level changer %s)", *level_changers()[i]->m_caLevelPointToChange, level_changers()[i]->name_replace()); - VERIFY(false); - } - } -} - -void CLevelSpawnConstructor::update_artefact_spawn_positions() -{ - u32 level_point_count = m_game_spawn_constructor->level_point_count(); - - for (auto &i : m_spawns) - { - CSE_ALifeObject* alife_object = smart_cast(i); - R_ASSERT2(alife_object, "Non-ALife object!"); - //R_ASSERT3(level_graph().valid_vertex_id(alife_object->m_tNodeID),"Invalid node for object ",alife_object->name_replace()); - VERIFY(game_graph().vertex(alife_object->m_tGraphID)->level_id() == m_level.id()); - //alife_object->m_spawn_control = ""; - CSE_ALifeAnomalousZone* zone = smart_cast(i); - if (zone) - { - zone->m_artefact_position_offset = level_point_count; - level_point_count += zone->m_artefact_spawn_count; - //Msg("%s %f [%f][%f][%f] : artefact spawn positions",zone->name_replace(),zone->m_fRadius,VPUSH(zone->o_Position)); - //for (u32 i=zone->m_artefact_position_offset; io_Position.distance_to(m_level_points[i].tPoint)); - } - } - - m_game_spawn_constructor->add_level_points(m_level_points); -} - -void CLevelSpawnConstructor::Execute() -{ - load_objects(); - //fill_spawn_groups(); - - init(); - - correct_objects(); - generate_artefact_spawn_positions(); - correct_level_changers(); - verify_space_restrictors(); - - xr_delete(m_level_graph); - m_cross_table = 0; - xr_delete(m_graph_engine); -} - -void CLevelSpawnConstructor::update() -{ - fill_level_changers(); - update_artefact_spawn_positions(); -} - -void CLevelSpawnConstructor::verify_space_restrictors() -{ - Msg("Level [%s] : searching for AI map separators space restrictors", *m_level.name()); - - for (auto &i : m_space_restrictors) - { - VERIFY(i); - - if (i->object().m_space_restrictor_type == RestrictionSpace::eRestrictorTypeNone) - continue; - - i->verify(*m_level_graph, *m_graph_engine, m_no_separator_check); - } - - delete_data(m_space_restrictors); - - if (m_no_separator_check) - Msg("Level [%s] : no separators found", *m_level.name()); -} diff --git a/src/utils/xrAI/level_spawn_constructor.h b/src/utils/xrAI/level_spawn_constructor.h deleted file mode 100644 index 61f98d475b7..00000000000 --- a/src/utils/xrAI/level_spawn_constructor.h +++ /dev/null @@ -1,92 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : level_spawn_constructor.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Level spawn constructor -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xrAICore/Navigation/PatrolPath/patrol_path_storage.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "spawn_constructor_space.h" -#include "space_restrictor_wrapper.h" -#include "game_spawn_constructor.h" - -class CGameSpawnConstructor; - -class CLevelSpawnConstructor : public CThread -{ -public: - typedef SpawnConstructorSpace::LEVEL_POINT_STORAGE LEVEL_POINT_STORAGE; - typedef SpawnConstructorSpace::LEVEL_CHANGER_STORAGE LEVEL_CHANGER_STORAGE; - typedef xr_vector SPAWN_STORAGE; - typedef xr_vector GRAPH_POINT_STORAGE; - typedef xr_vector SPACE_RESTRICTORS; - // typedef xr_vector GROUP_OBJECTS; - // typedef xr_map SPAWN_GRPOUP_OBJECTS; - // typedef xr_map SPAWN_GROUPS; - -private: - CGameGraph::SLevel m_level; - SPAWN_STORAGE m_spawns; - LEVEL_POINT_STORAGE m_level_points; - GRAPH_POINT_STORAGE m_graph_points; - SPACE_RESTRICTORS m_space_restrictors; - // SPAWN_GRPOUP_OBJECTS m_spawn_objects; - // SPAWN_GROUPS m_spawn_groups; - CGameSpawnConstructor* m_game_spawn_constructor; - CSE_ALifeCreatureActor* m_actor; - CLevelGraph* m_level_graph; - CGraphEngine* m_graph_engine; - LEVEL_CHANGER_STORAGE m_level_changers; - bool m_no_separator_check; - -private: - const CGameLevelCrossTable* m_cross_table; - -protected: - void init(); - void load_objects(); - // void fill_spawn_groups (); - void correct_objects(); - void generate_artefact_spawn_positions(); - void correct_level_changers(); - void verify_space_restrictors(); - void fill_level_changers(); - CSE_Abstract* create_object(IReader* chunk); - void add_graph_point(CSE_Abstract* abstract); - // void add_spawn_group (CSE_Abstract *abstract); - void add_story_object(CSE_ALifeDynamicObject* dynamic_object); - void add_space_restrictor(CSE_ALifeDynamicObject* dynamic_object); - void add_free_object(CSE_Abstract* abstract); - // void add_group_object (CSE_Abstract *abstract, shared_str - //group_section, - // bool); - // void add_group_object (CSE_Abstract *abstract, - //shared_str - // group_section); - void add_level_changer(CSE_Abstract* abstract); - void update_artefact_spawn_positions(); - // IC void normalize_probability (CSE_ALifeAnomalousZone *zone); - // IC void free_group_objects (); - IC const CGameGraph& game_graph() const; - IC const CLevelGraph& level_graph() const; - IC const CGameLevelCrossTable& cross_table() const; - IC CGraphEngine& graph_engine() const; - IC LEVEL_CHANGER_STORAGE& level_changers() const; - IC u32 level_id(shared_str level_name) const; - -public: - IC CLevelSpawnConstructor( - const CGameGraph::SLevel& level, CGameSpawnConstructor* game_spawn_constructor, bool no_separator_check); - virtual ~CLevelSpawnConstructor(); - virtual void Execute(); - IC CSE_ALifeCreatureActor* actor() const; - IC const CGameGraph::SLevel& level() const; - void update(); - IC CGameSpawnConstructor& game_spawn_constructor() const; -}; - -#include "level_spawn_constructor_inline.h" diff --git a/src/utils/xrAI/level_spawn_constructor_inline.h b/src/utils/xrAI/level_spawn_constructor_inline.h deleted file mode 100644 index c3d9991bca4..00000000000 --- a/src/utils/xrAI/level_spawn_constructor_inline.h +++ /dev/null @@ -1,31 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : level_spawn_constructor_inline.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Level spawn constructor inline functions -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -IC CLevelSpawnConstructor::CLevelSpawnConstructor( - const CGameGraph::SLevel& level, CGameSpawnConstructor* game_spawn_constructor, bool no_separator_check) - : CThread(level.id(), ProxyMsg) -{ - m_level = level; - m_game_spawn_constructor = game_spawn_constructor; - m_no_separator_check = no_separator_check; - thDestroyOnComplete = FALSE; - m_actor = 0; - m_level_graph = 0; - m_cross_table = 0; - m_graph_engine = 0; -} - -IC CSE_ALifeCreatureActor* CLevelSpawnConstructor::actor() const { return (m_actor); } -IC const CGameGraph::SLevel& CLevelSpawnConstructor::level() const { return (m_level); } -IC CGameSpawnConstructor& CLevelSpawnConstructor::game_spawn_constructor() const -{ - VERIFY(m_game_spawn_constructor); - return (*m_game_spawn_constructor); -} diff --git a/src/utils/xrAI/packages.config b/src/utils/xrAI/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/xrAI/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/xrAI/resource.h b/src/utils/xrAI/resource.h deleted file mode 100644 index 5bab51b5921..00000000000 --- a/src/utils/xrAI/resource.h +++ /dev/null @@ -1,29 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define ID_VIEW_NDEPTH 2 -#define ID_VIEW_NHEIGHT 3 -#define ID_VIEW_NSECTOR 4 -#define ID_VIEW_NNORMALS 5 -#define ID_VIEW_NLIGHT 6 -#define ID_VIEW_NSUBDIV 8 -#define ID_VIEW_COVER1 10 -#define ID_VIEW_COVER2 11 -#define ID_VIEW_COVER3 12 -#define ID_VIEW_COVER4 13 -#define IDD_NVIEW 107 -#define IDSTOP2 1005 -#define IDC_STACK 1006 -#define IDC_PROGRESS1 1015 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1016 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/utils/xrAI/resource.rc b/src/utils/xrAI/resource.rc deleted file mode 100644 index 68aefd9b43c..00000000000 --- a/src/utils/xrAI/resource.rc +++ /dev/null @@ -1,113 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Ukrainian (Ukraine) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR) -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Ukrainian (Ukraine) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_NVIEW DIALOG 0, 0, 780, 535 -STYLE DS_ABSALIGN | DS_SETFONT | DS_SETFOREGROUND | DS_NOFAILCREATE | DS_CENTER | WS_VISIBLE | WS_BORDER -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "Close",IDOK,690,5,85,14,BS_FLAT - PUSHBUTTON "View depth",ID_VIEW_NDEPTH,690,30,85,14,BS_FLAT - PUSHBUTTON "View height",ID_VIEW_NHEIGHT,690,45,85,14,BS_FLAT - PUSHBUTTON "View sectors",ID_VIEW_NSECTOR,690,75,85,14,BS_FLAT - PUSHBUTTON "View normals",ID_VIEW_NNORMALS,690,60,85,14,BS_FLAT - PUSHBUTTON "View lighting",ID_VIEW_NLIGHT,690,90,85,14,BS_FLAT - PUSHBUTTON "View subdivisions",ID_VIEW_NSUBDIV,690,105,85,14,BS_FLAT - PUSHBUTTON "View cover left",ID_VIEW_COVER1,690,135,85,14,BS_FLAT - PUSHBUTTON "View cover forward",ID_VIEW_COVER2,690,150,85,14,BS_FLAT - PUSHBUTTON "View cover right",ID_VIEW_COVER3,690,165,85,14,BS_FLAT - PUSHBUTTON "View cover back",ID_VIEW_COVER4,690,180,85,14,BS_FLAT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_NVIEW, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 773 - TOPMARGIN, 7 - BOTTOMMARGIN, 528 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/utils/xrAI/server_entity_wrapper.cpp b/src/utils/xrAI/server_entity_wrapper.cpp deleted file mode 100644 index b64a9f8d5e1..00000000000 --- a/src/utils/xrAI/server_entity_wrapper.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : server_entity_wrapper.cpp -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Server entity wrapper -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "server_entity_wrapper.h" -#include "xrServerEntities/xrServer_Objects.h" -#include "xrServerEntities/xrmessages.h" - -#ifdef AI_COMPILER -#include "factory_api.h" -#endif - -class IServerEntity; - -CServerEntityWrapper::~CServerEntityWrapper() { F_entity_Destroy(m_object); } -void CServerEntityWrapper::save(IWriter& stream) -{ - NET_Packet net_packet; - - // Spawn - stream.open_chunk(0); - - m_object->Spawn_Write(net_packet, TRUE); - stream.w_u16(u16(net_packet.B.count)); - stream.w(net_packet.B.data, net_packet.B.count); - - stream.close_chunk(); - - // Update - stream.open_chunk(1); - - net_packet.w_begin(M_UPDATE); - m_object->UPDATE_Write(net_packet); - stream.w_u16(u16(net_packet.B.count)); - stream.w(net_packet.B.data, net_packet.B.count); - - // u16 ID; - // net_packet.r_begin (ID); - // VERIFY (ID==M_UPDATE); - // m_object->UPDATE_Read (net_packet); - - stream.close_chunk(); -} - -void CServerEntityWrapper::load(IReader& stream) -{ - NET_Packet net_packet; - u16 ID; - IReader* chunk; - - chunk = stream.open_chunk(0); - - net_packet.B.count = chunk->r_u16(); - chunk->r(net_packet.B.data, net_packet.B.count); - - chunk->close(); - - net_packet.r_begin(ID); - R_ASSERT2(M_SPAWN == ID, "Invalid packet ID (!= M_SPAWN)!"); - - string64 s_name; - net_packet.r_stringZ(s_name); - - m_object = F_entity_Create(s_name); - - R_ASSERT3(m_object, "Can't create entity.", s_name); - m_object->Spawn_Read(net_packet); - - chunk = stream.open_chunk(1); - - net_packet.B.count = chunk->r_u16(); - chunk->r(net_packet.B.data, net_packet.B.count); - - chunk->close(); - - net_packet.r_begin(ID); - R_ASSERT2(M_UPDATE == ID, "Invalid packet ID (!= M_UPDATE)!"); - m_object->UPDATE_Read(net_packet); -} - -void CServerEntityWrapper::save_update(IWriter& stream) -{ - // NET_Packet net_packet; - // net_packet.w_begin (M_UPDATE); - // m_object->save_update (net_packet); - // stream.w_u16 (u16(net_packet.B.count)); - // stream.w (net_packet.B.data,net_packet.B.count); -} - -void CServerEntityWrapper::load_update(IReader& stream) -{ - // NET_Packet net_packet; - // u16 ID; - // - // net_packet.B.count = stream.r_u16(); - // stream.r (net_packet.B.data,net_packet.B.count); - // - // net_packet.r_begin (ID); - // R_ASSERT2 (M_UPDATE == ID,"Invalid packet ID (!= M_UPDATE)!"); - // m_object->load_update (net_packet); -} diff --git a/src/utils/xrAI/server_entity_wrapper.h b/src/utils/xrAI/server_entity_wrapper.h deleted file mode 100644 index 52a174efece..00000000000 --- a/src/utils/xrAI/server_entity_wrapper.h +++ /dev/null @@ -1,28 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : server_entity_wrapper.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Server entity wrapper -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xrServerEntities/xrServer_Object_Base.h" - -class CServerEntityWrapper : public ISerializable -{ -private: - CSE_Abstract* m_object; - -public: - IC CServerEntityWrapper(CSE_Abstract* object = 0); - virtual ~CServerEntityWrapper(); - virtual void save(IWriter& stream); - virtual void load(IReader& stream); - void save_update(IWriter& stream); - void load_update(IReader& stream); - IC CSE_Abstract& object() const; -}; - -#include "server_entity_wrapper_inline.h" diff --git a/src/utils/xrAI/server_entity_wrapper_inline.h b/src/utils/xrAI/server_entity_wrapper_inline.h deleted file mode 100644 index 593dcd691f5..00000000000 --- a/src/utils/xrAI/server_entity_wrapper_inline.h +++ /dev/null @@ -1,16 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : server_entity_wrapper_inline.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Server entity wrapper inline functions -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -IC CServerEntityWrapper::CServerEntityWrapper(CSE_Abstract* object) { m_object = object; } -IC CSE_Abstract& CServerEntityWrapper::object() const -{ - VERIFY(m_object); - return (*m_object); -} diff --git a/src/utils/xrAI/space_restrictor_wrapper.cpp b/src/utils/xrAI/space_restrictor_wrapper.cpp deleted file mode 100644 index 50f9d1bf5b7..00000000000 --- a/src/utils/xrAI/space_restrictor_wrapper.cpp +++ /dev/null @@ -1,286 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : space_restrictor_wrapper.cpp -// Created : 28.11.2005 -// Modified : 28.11.2005 -// Author : Dmitriy Iassenev -// Description : space restrictor wrapper -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "space_restrictor_wrapper.h" - -IC Fvector construct_position(CLevelGraph& level_graph, u32 level_vertex_id, float x, float z) -{ - return (Fvector().set(x, level_graph.vertex_plane_y(level_vertex_id, x, z), z)); -} - -CSpaceRestrictorWrapper::CSpaceRestrictorWrapper(CSE_ALifeSpaceRestrictor* object) -{ - m_object = object; - m_level_graph = nullptr; - m_graph_engine = nullptr; - m_xform.setXYZ(object->o_Angle); - m_xform.c.set(object->o_Position); -} - -void CSpaceRestrictorWrapper::clear() -{ - m_border.clear(); - m_level_graph = nullptr; - m_graph_engine = nullptr; -} - -bool CSpaceRestrictorWrapper::inside(const Fvector& position, float radius) const -{ - Fsphere sphere; - sphere.P = position; - sphere.R = radius; - - for (auto &i : object().shapes) - { - switch (i.type) - { - case CShapeData::cfSphere: - { - Fsphere temp; - m_xform.transform_tiny(temp.P, i.data.sphere.P); - temp.R = i.data.sphere.R; - if (sphere.intersect(temp)) - return true; - - continue; - } - case CShapeData::cfBox: - { - Fmatrix temp; - temp.mul_43(m_xform, i.data.box); - - // Build points - Fvector vertices; - Fvector points[8]; - Fplane plane; - - vertices.set(-.5f, -.5f, -.5f); - temp.transform_tiny(points[0], vertices); - vertices.set(-.5f, -.5f, +.5f); - temp.transform_tiny(points[1], vertices); - vertices.set(-.5f, +.5f, +.5f); - temp.transform_tiny(points[2], vertices); - vertices.set(-.5f, +.5f, -.5f); - temp.transform_tiny(points[3], vertices); - vertices.set(+.5f, +.5f, +.5f); - temp.transform_tiny(points[4], vertices); - vertices.set(+.5f, +.5f, -.5f); - temp.transform_tiny(points[5], vertices); - vertices.set(+.5f, -.5f, +.5f); - temp.transform_tiny(points[6], vertices); - vertices.set(+.5f, -.5f, -.5f); - temp.transform_tiny(points[7], vertices); - - plane.build(points[0], points[3], points[5]); - if (plane.classify(sphere.P) > sphere.R) - break; - plane.build(points[1], points[2], points[3]); - if (plane.classify(sphere.P) > sphere.R) - break; - plane.build(points[6], points[5], points[4]); - if (plane.classify(sphere.P) > sphere.R) - break; - plane.build(points[4], points[2], points[1]); - if (plane.classify(sphere.P) > sphere.R) - break; - plane.build(points[3], points[2], points[4]); - if (plane.classify(sphere.P) > sphere.R) - break; - plane.build(points[1], points[0], points[6]); - if (plane.classify(sphere.P) > sphere.R) - break; - return true; - } - default: NODEFAULT; - } - } - - return false; -} - -struct border_merge_predicate -{ - CSpaceRestrictorWrapper* m_restriction; - CLevelGraph* m_level_graph; - - IC border_merge_predicate(CSpaceRestrictorWrapper* restriction, CLevelGraph* level_graph) - { - m_restriction = restriction; - m_level_graph = level_graph; - } - - IC void operator()(const CLevelGraph::CLevelVertex& vertex) const - { - if (m_restriction->inside(m_level_graph->vertex_id(&vertex), true) && - !m_restriction->inside(m_level_graph->vertex_id(&vertex), false)) - m_restriction->m_border.push_back(m_level_graph->vertex_id(&vertex)); - - if (m_restriction->inside(m_level_graph->vertex_id(&vertex), true)) - m_restriction->m_internal.push_back(m_level_graph->vertex_id(&vertex)); - } - - IC bool operator()(const u32& level_vertex_id) const { return (m_restriction->inside(level_vertex_id, false)); } -}; - -void CSpaceRestrictorWrapper::fill_shape(const CShapeData::shape_def& shape) -{ - Fvector start, dest; - switch (shape.type) - { - case CShapeData::cfSphere: - { - start.sub(Fvector().set(shape.data.sphere.P), Fvector().set(shape.data.sphere.R, 0.f, shape.data.sphere.R)); - dest.add(Fvector().set(shape.data.sphere.P), Fvector().set(shape.data.sphere.R, 0.f, shape.data.sphere.R)); - start.add(object().o_Position); - dest.add(object().o_Position); - break; - } - case CShapeData::cfBox: - { - Fvector points[8] = {Fvector().set(-.5f, -.5f, -.5f), Fvector().set(-.5f, -.5f, +.5f), - Fvector().set(-.5f, +.5f, -.5f), Fvector().set(-.5f, +.5f, +.5f), Fvector().set(+.5f, -.5f, -.5f), - Fvector().set(+.5f, -.5f, +.5f), Fvector().set(+.5f, +.5f, -.5f), Fvector().set(+.5f, +.5f, +.5f)}; - start = Fvector().set(flt_max, flt_max, flt_max); - dest = Fvector().set(flt_min, flt_min, flt_min); - Fmatrix Q; - Q.mul_43(m_xform, shape.data.box); - Fvector temp; - for (int i = 0; i < 8; ++i) - { - Q.transform_tiny(temp, points[i]); - start.x = std::min(start.x, temp.x); - start.y = std::min(start.y, temp.y); - start.z = std::min(start.z, temp.z); - dest.x = std::max(dest.x, temp.x); - dest.y = std::max(dest.y, temp.y); - dest.z = std::max(dest.z, temp.z); - } - break; - } - default: NODEFAULT; - } - - level_graph().iterate_vertices(start, dest, border_merge_predicate(this, m_level_graph)); -} - -bool CSpaceRestrictorWrapper::inside(u32 level_vertex_id, bool partially_inside, float radius) const -{ - const auto& position = level_graph().vertex_position(level_vertex_id); - float offset = level_graph().header().cell_size() * .5f - EPS_L; - if (partially_inside) - return (inside(construct_position(level_graph(), level_vertex_id, position.x + offset, position.z + offset), radius) || - inside(construct_position(level_graph(), level_vertex_id, position.x + offset, position.z - offset), radius) || - inside(construct_position(level_graph(), level_vertex_id, position.x - offset, position.z + offset), radius) || - inside(construct_position(level_graph(), level_vertex_id, position.x - offset, position.z - offset), radius) || - inside(Fvector().set(position.x, position.y, position.z), radius)); - else - return (inside(construct_position(level_graph(), level_vertex_id, position.x + offset, position.z + offset), radius) && - inside(construct_position(level_graph(), level_vertex_id, position.x + offset, position.z - offset), radius) && - inside(construct_position(level_graph(), level_vertex_id, position.x - offset, position.z + offset), radius) && - inside(construct_position(level_graph(), level_vertex_id, position.x - offset, position.z - offset), radius) && - inside(Fvector().set(position.x, position.y, position.z), radius)); -} - -struct sort_by_xz_predicate -{ - CLevelGraph* m_level_graph; - - IC sort_by_xz_predicate(CLevelGraph* level_graph) - { - VERIFY(level_graph); - m_level_graph = level_graph; - } - - IC bool operator()(u32 v0, u32 v1) const - { - return (m_level_graph->vertex(v0)->position().xz() < m_level_graph->vertex(v1)->position().xz()); - } -}; - -void CSpaceRestrictorWrapper::build_border() -{ - for (auto &i : object().shapes) - fill_shape(i); - - { - auto I = std::remove_if(m_border.begin(), m_border.end(), border_merge_predicate(this, m_level_graph)); - m_border.erase(I, m_border.end()); - } - - { - std::sort(m_border.begin(), m_border.end()); - auto I = std::unique(m_border.begin(), m_border.end()); - m_border.erase(I, m_border.end()); - std::sort(m_border.begin(), m_border.end(), sort_by_xz_predicate(m_level_graph)); - } - - VERIFY3(!m_border.empty(), "space restrictor has no border", object().name_replace()); -} - -void CSpaceRestrictorWrapper::verify_connectivity() -{ - { - std::sort(m_internal.begin(), m_internal.end()); - auto I = std::unique(m_internal.begin(), m_internal.end()); - m_internal.erase(I, m_internal.end()); - } - - u32 start_vertex_id = u32(-1); - for (auto &i : level_graph()) - { - if (!inside(level_graph().vertex(&i), true)) - { - start_vertex_id = level_graph().vertex(&i); - break; - } - } - - if (!level_graph().valid_vertex_id(start_vertex_id)) - { - Msg("Warning : restrictor %s covers the whole AI map", object().name_replace()); - return; - } - - //level_graph().set_mask(m_border); - level_graph().set_mask(m_internal); - - xr_vector nodes; - - graph_engine().search(level_graph(), start_vertex_id, start_vertex_id, &nodes, - GraphEngineSpace::CFlooder(GraphEngineSpace::_dist_type(6000), GraphEngineSpace::_iteration_type(-1), u32(-1))); - - //level_graph().clear_mask(m_border); - level_graph().clear_mask(m_internal); - - VERIFY(nodes.size() + m_internal.size() <= level_graph().header().vertex_count()); - if (nodes.size() + m_internal.size() == level_graph().header().vertex_count()) - return; - - Msg("! %7d nodes are disconnected! Restrictor '%s' separates AI map into several disconnected components", - level_graph().header().vertex_count() - (nodes.size() + m_internal.size()), object().name_replace()); - - //R_ASSERT3(nodes.size() + m_internal.size() == level_graph().header().vertex_count(), - // "Restrictor separates AI map into several disconnected components", object().name_replace()); -} - -void CSpaceRestrictorWrapper::verify(CLevelGraph& level_graph, CGraphEngine& graph_engine, bool no_separator_check) -{ - VERIFY(!m_level_graph); - m_level_graph = &level_graph; - - VERIFY(!m_graph_engine); - m_graph_engine = &graph_engine; - - build_border(); - - if (!no_separator_check) - verify_connectivity(); - - clear(); -} diff --git a/src/utils/xrAI/space_restrictor_wrapper.h b/src/utils/xrAI/space_restrictor_wrapper.h deleted file mode 100644 index c99e1349637..00000000000 --- a/src/utils/xrAI/space_restrictor_wrapper.h +++ /dev/null @@ -1,49 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : space_restrictor_wrapper.h -// Created : 28.11.2005 -// Modified : 28.11.2005 -// Author : Dmitriy Iassenev -// Description : space restrictor wrapper -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xrAICore/Navigation/graph_abstract.h" -#include "xrAICore/Navigation/graph_engine.h" -#include "xrServerEntities/ShapeData.h" -#include "xrServerEntities/xrServer_Objects_ALife.h" - -class CSpaceRestrictorWrapper -{ -private: - friend struct border_merge_predicate; - -public: - typedef CSE_ALifeSpaceRestrictor object_type; - typedef xr_vector BORDER; - -private: - object_type* m_object; - CLevelGraph* m_level_graph; - CGraphEngine* m_graph_engine; - BORDER m_border; - BORDER m_internal; - Fmatrix m_xform; - -private: - void clear(); - void fill_shape(const CShapeData::shape_def& data); - void build_border(); - void verify_connectivity(); - bool inside(const Fvector& position, float radius = EPS_L) const; - bool inside(u32 level_vertex_id, bool partially_inside, float radius = EPS_L) const; - IC CLevelGraph& level_graph() const; - IC CGraphEngine& graph_engine() const; - -public: - CSpaceRestrictorWrapper(CSE_ALifeSpaceRestrictor* object); - IC object_type& object() const; - void verify(CLevelGraph& level_graph, CGraphEngine& graph_engine, bool no_separator_check); -}; - -#include "space_restrictor_wrapper_inline.h" diff --git a/src/utils/xrAI/space_restrictor_wrapper_inline.h b/src/utils/xrAI/space_restrictor_wrapper_inline.h deleted file mode 100644 index 054abbc4f42..00000000000 --- a/src/utils/xrAI/space_restrictor_wrapper_inline.h +++ /dev/null @@ -1,27 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : space_restrictor_wrapper_inline.h -// Created : 28.11.2005 -// Modified : 28.11.2005 -// Author : Dmitriy Iassenev -// Description : space restrictor wrapper inline functions -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -IC CSpaceRestrictorWrapper::object_type& CSpaceRestrictorWrapper::object() const -{ - VERIFY(m_object); - return (*m_object); -} - -IC CLevelGraph& CSpaceRestrictorWrapper::level_graph() const -{ - VERIFY(m_level_graph); - return (*m_level_graph); -} - -IC CGraphEngine& CSpaceRestrictorWrapper::graph_engine() const -{ - VERIFY(m_graph_engine); - return (*m_graph_engine); -} diff --git a/src/utils/xrAI/spawn_constructor_space.h b/src/utils/xrAI/spawn_constructor_space.h deleted file mode 100644 index 888bab9423e..00000000000 --- a/src/utils/xrAI/spawn_constructor_space.h +++ /dev/null @@ -1,18 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : spawn_constructor_space.h -// Created : 16.10.2004 -// Modified : 16.10.2004 -// Author : Dmitriy Iassenev -// Description : Spawn constructor space -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "xrAICore/Navigation/game_graph.h" -#include "xrServerEntities/xrServer_Objects_ALife_All.h" - -namespace SpawnConstructorSpace -{ -typedef xr_vector LEVEL_POINT_STORAGE; -typedef xr_vector LEVEL_CHANGER_STORAGE; -}; diff --git a/src/utils/xrAI/verify_level_graph.cpp b/src/utils/xrAI/verify_level_graph.cpp deleted file mode 100644 index 55223616996..00000000000 --- a/src/utils/xrAI/verify_level_graph.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : verify_level_graph.cpp -// Created : 25.05.2004 -// Modified : 25.05.2004 -// Author : Dmitriy Iassenev -// Description : Verifying level graph -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "xrAICore/Navigation/level_graph.h" - -#define PUSH(a) *stack_iterator++ = (a) -#define POP() vertex = *--stack_iterator - -void floodfill(const CLevelGraph& level_graph, CLevelGraph::CLevelVertex** stack_storage, xr_vector& marks, const u32 start_vertex_id) -{ - CLevelGraph::CLevelVertex** stack_iterator = stack_storage; - CLevelGraph::CLevelVertex* vertex = nullptr; - PUSH(level_graph.vertex(start_vertex_id)); - while (stack_iterator != stack_storage) - { - POP(); - auto vertex_id = level_graph.vertex_id(vertex); - if (marks[vertex_id]) - continue; - marks[vertex_id] = true; - for (const auto j : { 0, 1, 2, 3 }) - { - auto neighbour_vertex_id = vertex->link(j); - if (level_graph.valid_vertex_id(neighbour_vertex_id) && !marks[neighbour_vertex_id]) - PUSH(level_graph.vertex(neighbour_vertex_id)); - } - } -} - -bool verify_invalid_links(const CLevelGraph& graph) -{ - bool result = true; - for (const auto &vertex : graph) - { - auto vertex_id = graph.vertex_id(&vertex); - for (const auto j : { 0, 1, 2, 3 }) - { - auto link_vertex_id = vertex.link(j); - if (!graph.valid_vertex_id(link_vertex_id)) - continue; - - if (vertex_id == link_vertex_id) - { - Msg("Vertex %d[%f][%f][%f] has link to itself", vertex_id, VPUSH(graph.vertex_position(vertex))); - result = false; - continue; - } - } - } - return result; -} - -void verify_level_graph(LPCSTR name, bool verbose) -{ - Msg("Verifying level %s", name); - Logger.Phase("Verifying level graph"); - Logger.Progress(0.f); - CLevelGraph level_graph(name); - - if (!level_graph.header().vertex_count()) - { - Logger.Progress(1.f); - Msg("Level graph is empty!"); - return; - } - - if (!verify_invalid_links(level_graph)) - { - Logger.Progress(1.f); - Msg("AI map is CORRUPTED : REGENERATE AI-MAP"); - return; - } - - xr_vector single_links; - single_links.reserve(level_graph.header().vertex_count()); - Logger.Progress(0.05f); - - for (const auto &vertex : level_graph) - { - for (const auto j : {0, 1, 2, 3}) - { - auto neighbour_vertex_id = vertex.link(j); - if (level_graph.valid_vertex_id(neighbour_vertex_id) && // Valid vertex - level_graph.vertex(neighbour_vertex_id)->link((j + 2) % 4) != level_graph.vertex_id(&vertex)) // Single vertex - { - single_links.push_back(neighbour_vertex_id); - } - } - Logger.Progress(0.05f + 0.05f * float(level_graph.vertex_id(&vertex)) / float(level_graph.header().vertex_count())); - } - - bool no_single_links = single_links.empty(); - Logger.Progress(0.1f); - if (single_links.empty()) - single_links.push_back(0); - - std::sort(single_links.begin(), single_links.end()); - auto I = std::unique(single_links.begin(), single_links.end()); - single_links.erase(I, single_links.end()); - - if (!no_single_links) - { - if (verbose) - for (const auto &i : single_links) - Msg("Vertex %d[%f][%f][%f] is single linked!", i, VPUSH(level_graph.vertex_position(i))); - Msg("There are %d single linked nodes!", single_links.size()); - } - - Logger.Progress(0.15f); - CLevelGraph::CLevelVertex** stack_storage = (CLevelGraph::CLevelVertex**)xr_malloc(level_graph.header().vertex_count() * sizeof(CLevelGraph::CLevelVertex*)); - xr_vector marks; - bool valid = true; - for (auto &i : single_links) - { - marks.assign(level_graph.header().vertex_count(), false); - floodfill(level_graph, stack_storage, marks, i); - for (auto &j : marks) - { - if (!j) - { - valid = false; - auto J = std::distance(&marks.front(), &j); - Msg("AI-map is NOT valid :\nNode \n%6d[%f][%f][%f]\ncannot be reached from the node\n%6d[%f][%f][%f]\n", - J, VPUSH(level_graph.vertex_position(J)), - i, VPUSH(level_graph.vertex_position(i))); - break; - } - } - - if (!valid) - break; - Logger.Progress(0.15f + 0.85f * float(std::distance(&single_links.front(), &i)) / float(single_links.size())); - } - - xr_free(stack_storage); - Logger.Progress(1.f); - - if (valid) - Msg("AI-map is valid!"); - - Msg("Verifying level %s completed", name); -} diff --git a/src/utils/xrAI/xrAI.cpp b/src/utils/xrAI/xrAI.cpp deleted file mode 100644 index 36a9888d42d..00000000000 --- a/src/utils/xrAI/xrAI.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "stdafx.h" -#include "xrAI.h" - -#include "game_spawn_constructor.h" - -#include - -#pragma comment(linker, "/STACK:0x800000,0x400000") - -#pragma comment(lib, "winmm.LIB") - -#include "xrCore/ModuleLookup.hpp" - -#include "factory_api.h" - -CreateEntity* create_entity = nullptr; -DestroyEntity* destroy_entity = nullptr; - -extern void xrCompiler(LPCSTR name, bool draft_mode, bool pure_covers, LPCSTR out_name); -extern void verify_level_graph(LPCSTR name, bool verbose); - -static const char* h_str = - "-? or -h == this help\n" - "-f == compile level.ai\n" - "-s == build game spawn data\n" - "-verify == verify compiled level.ai\n"; - -void Help() { MessageBox(0, h_str, "Command line options", MB_OK | MB_ICONINFORMATION); } -string_path INI_FILE; - -LPCSTR GAME_CONFIG = "game.ltx"; - -extern void clear_temp_folder(); - -void execute(pstr cmd) -{ - // Load project - string4096 name; - name[0] = 0; - if (strstr(cmd, "-f")) - sscanf(strstr(cmd, "-f") + 2, "%s", name); - else if (strstr(cmd, "-s")) - sscanf(strstr(cmd, "-s") + 2, "%s", name); - else if (strstr(cmd, "-verify")) - sscanf(strstr(cmd, "-verify") + xr_strlen("-verify"), "%s", name); - - if (xr_strlen(name)) - xr_strcat(name, "\\"); - - string_path prjName; - prjName[0] = 0; - bool can_use_name = false; - if (xr_strlen(name) < sizeof(string_path)) - { - can_use_name = true; - FS.update_path(prjName, "$game_levels$", name); - } - - FS.update_path(INI_FILE, "$game_config$", GAME_CONFIG); - - if (strstr(cmd, "-f")) - { - R_ASSERT3(can_use_name, "Too big level name", name); - - char* output = strstr(cmd, "-out"); - string256 temp0; - if (output) - { - output += xr_strlen("-out"); - sscanf(output, "%s", temp0); - _TrimLeft(temp0); - output = temp0; - } - else - output = (pstr)LEVEL_GRAPH_NAME; - - xrCompiler(prjName, !!strstr(cmd, "-draft"), !!strstr(cmd, "-pure_covers"), output); - } - else - { - if (strstr(cmd, "-s")) - { - if (xr_strlen(name)) - name[xr_strlen(name) - 1] = 0; - char* output = strstr(cmd, "-out"); - string256 temp0, temp1; - if (output) - { - output += xr_strlen("-out"); - sscanf(output, "%s", temp0); - _TrimLeft(temp0); - output = temp0; - } - char* start = strstr(cmd, "-start"); - if (start) - { - start += xr_strlen("-start"); - sscanf(start, "%s", temp1); - _TrimLeft(temp1); - start = temp1; - } - char* no_separator_check = strstr(cmd, "-no_separator_check"); - clear_temp_folder(); - - const auto hFactory = XRay::LoadModule("xrSE_Factory"); - - R_ASSERT2(hFactory->IsLoaded(), "Factory DLL raised exception during loading or there is no factory DLL at all"); - -#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) - pcstr create_entity_name = "create_entity"; - pcstr destroy_entity_name = "destroy_entity"; -#else - pcstr create_entity_name = "_create_entity@4"; - pcstr destroy_entity_name = "_destroy_entity@4"; -#endif - create_entity = static_cast(hFactory->GetProcAddress(create_entity_name)); - destroy_entity = static_cast(hFactory->GetProcAddress(destroy_entity_name)); - - R_ASSERT(create_entity); - R_ASSERT(destroy_entity); - - CGameSpawnConstructor(name, output, start, !!no_separator_check); - - create_entity = nullptr; - destroy_entity = nullptr; - } - else if (strstr(cmd, "-verify")) - { - R_ASSERT3(can_use_name, "Too big level name", name); - verify_level_graph(prjName, !strstr(cmd, "-noverbose")); - } - } -} - -void Startup(pstr lpCmdLine) -{ - string4096 cmd; - - xr_strcpy(cmd, lpCmdLine); - xr_strlwr(cmd); - if (strstr(cmd, "-?") || strstr(cmd, "-h")) - { - Help(); - return; - } - if ((strstr(cmd, "-f") == 0) && (strstr(cmd, "-s") == 0) && (strstr(cmd, "-verify") == 0)) - { - Help(); - return; - } - Logger.Initialize("xrAI"); - u32 dwStartupTime = CPU::GetTicks(); - execute(cmd); - // Show statistic - string256 stats; - u32 dwEndTime = CPU::GetTicks(); - xr_sprintf(stats, "Time elapsed: %s", make_time((dwEndTime - dwStartupTime) / 1000).c_str()); - Logger.Success(stats); - FlushLog(); - Logger.Destroy(); -} - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, pstr lpCmdLine, int nCmdShow) -{ - xrDebug::Initialize(lpCmdLine); - Core.Initialize("xrAI"); - - Startup(lpCmdLine); - - Core._destroy(); - - return 0; -} diff --git a/src/utils/xrAI/xrAI.h b/src/utils/xrAI/xrAI.h deleted file mode 100644 index b436e70c3e7..00000000000 --- a/src/utils/xrAI/xrAI.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -extern string_path INI_FILE; diff --git a/src/utils/xrAI/xrAI.vcxproj b/src/utils/xrAI/xrAI.vcxproj deleted file mode 100644 index 9424d043bdd..00000000000 --- a/src/utils/xrAI/xrAI.vcxproj +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - {EA5932F3-02FE-4AD3-89E8-7072DC465D25} - - - - - - - Application - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - $(xrExternals)FreeMagic\Include;$(xrSdkDir)include\FreeImage;%(AdditionalIncludeDirectories) - AI_COMPILER;%(PreprocessorDefinitions) - false - false - - - FreeImage.lib;FreeImagePlus.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {5cb057d8-4464-40a6-af10-c26b826d1d90} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {b90bdc22-a891-4b33-b562-29d701f65dbd} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - {2578c6d8-660d-48ae-9322-7422f8664f06} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/xrAI/xrAI.vcxproj.filters b/src/utils/xrAI/xrAI.vcxproj.filters deleted file mode 100644 index 37ee2d99a76..00000000000 --- a/src/utils/xrAI/xrAI.vcxproj.filters +++ /dev/null @@ -1,194 +0,0 @@ - - - - - {1bd9343c-03aa-41e8-9a44-9eaa4704f675} - - - {d7047094-b5bb-4398-830d-7f17b82d8030} - - - {d720c170-292f-489f-8660-5e5f3f895e3d} - - - {f4a43bfd-7b1d-42d7-8fa1-7283b213c52e} - - - {8000df4c-fadf-45cc-8460-b0d11e11e7bf} - - - {e75d6553-69f1-4700-b0cf-72e8e5898ad0} - - - {9f4c9b4e-64b7-478f-9b0b-82b9ee2006f4} - - - {1f70db45-e478-4193-b9da-dc45e7707537} - - - {2f212b73-5587-4873-a472-c35ddfbee016} - - - {3424b24d-4ae8-4f56-8156-e41fcf0b8d11} - - - {b6d20cf8-dd6d-4875-93c6-e90ec72ceb8b} - - - {abd194f2-1c4c-45a2-a498-344b990c1c61} - - - {1662641a-fb1b-4795-bf6e-272cfc78c210} - - - {fcaa304a-4e9c-4de0-9548-d6d730f309ed} - - - {9d5968b1-6770-4ee6-832d-da35ba558eb9} - - - - - Compiler - - - Compiler - - - Compiler - - - Compiler - - - Compiler\Kernel - - - Compiler\Kernel - - - ALife\Graph - - - ALife\Merge - - - ALife\Shared\Common - - - ALife\Spawn\game_spawn_constructor - - - ALife\Spawn\level_spawn_constructor - - - ALife\Spawn\level_spawn_constructor\space_restrictor_wrapper - - - ALife\Spawn\server_entity_wrapper - - - ALife\Verify - - - ALife\guid_generator - - - Compiler - - - Compiler - - - - - Compiler - - - Compiler - - - Compiler\Kernel - - - Compiler\Kernel - - - Compiler\Kernel - - - ALife\Graph - - - ALife\Graph - - - ALife\Merge - - - ALife\Shared - - - ALife\Shared\Common - - - ALife\Shared\Common - - - ALife\Shared\Common - - - ALife\Shared\Common - - - ALife\Shared\Common - - - ALife\Spawn - - - ALife\Spawn\game_spawn_constructor - - - ALife\Spawn\game_spawn_constructor - - - ALife\Spawn\level_spawn_constructor - - - ALife\Spawn\level_spawn_constructor - - - ALife\Spawn\level_spawn_constructor\space_restrictor_wrapper - - - ALife\Spawn\level_spawn_constructor\space_restrictor_wrapper - - - ALife\Spawn\server_entity_wrapper - - - ALife\Spawn\server_entity_wrapper - - - ALife\guid_generator - - - Resources - - - Compiler - - - - - Resources - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrAI/xrAI_Readme.txt b/src/utils/xrAI/xrAI_Readme.txt deleted file mode 100644 index b09b31e8148..00000000000 --- a/src/utils/xrAI/xrAI_Readme.txt +++ /dev/null @@ -1,63 +0,0 @@ -The following keys are supported / required: --? or -h == this help --f == compile 'level.ai' from 'build.aimap' - -out == name of output file (default: 'level.ai') - -draft == do not load and do not process some stages - -pure_covers == - -keep_temp_files == do not delete 'build.aimap' after load --verify == verify compiled 'level.ai' - -noverbose == do not print all single linked vertices (print only count) --s == build game spawn data - -out == name of output file (default: 'NAME.spawn') - -start == name of game start level - -no_separator_check == do not verify that restrictors separates AI map into several disconnected components - - == level name as 'gamedata/levels//' - == any file name - - : - - level.ai build.aimap: - : - "-f labx8 -keep_temp_files -out level.ai -pure_alloc" -: - gamedata/shaders_xrlc.xr - ShaderEditor. - gamedata/levels//build.cform - xrLC. - gamedata/levels//build.prj - LevelEditor. - gamedata/levels//build.aimap - LevelEditor. - gamedata/textures/.[thm,dds] - ( LevelEditor?). -: - gamedata/levels//level.ai -: - , game spawn data ( CLevelGraph). - - level.ai: - : - "-verify zaton -pure_alloc" -: - gamedata/levels//level.ai - xrAI. -: - - . - - game spawn data : - : - "-s zaton,jupiter,jupiter_underground,labx8,pripyat -start zaton -out all -pure_alloc" -: - gamedata/configs/system.ltx - (*.ltx) xrSE_Factory. - gamedata/configs/gameplay/*.xml - *.xml xrSE_Factory. . - gamedata/configs/game.ltx - game_*.ltx . . - gamedata/scripts/*.script - xrSE_Factory. - gamedata/levels//level.ai - xrAI. - gamedata/levels//level.spawn - LevelEditor. - gamedata/levels//level.game - LevelEditor. - : - _appdata_/temp/* - . -: - gamedata/spawns/all.spawn -: - : *.xml . - : all.spawn ( ) game.spawn ( ). - : game.ltx game_*.ltx () ! - "static SFillPropData fp_data;" xrSE_Factory. - , inc --> load, dec --> unload . - ( ) inc dec. diff --git a/src/utils/xrAI/xr_graph_merge.cpp b/src/utils/xrAI/xr_graph_merge.cpp deleted file mode 100644 index f7729e9315c..00000000000 --- a/src/utils/xrAI/xr_graph_merge.cpp +++ /dev/null @@ -1,695 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : xr_graph_merge.cpp -// Created : 25.01.2003 -// Modified : 25.01.2003 -// Author : Dmitriy Iassenev -// Description : Merging level graphs for off-line AI NPC computations -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "xr_graph_merge.h" -#include "xrAI.h" -#include "factory_api.h" -#include "Common/object_broker.h" -#include "spawn_constructor_space.h" -#include "guid_generator.h" -#include "game_graph_builder.h" -#include "xrServerEntities/xrMessages.h" -#include -#include - -extern LPCSTR GAME_CONFIG; - -using namespace SpawnConstructorSpace; -using namespace ALife; - -typedef struct tagSConnectionVertex -{ - pstr caConnectName; - GameGraph::_GRAPH_ID tGraphID; - GameGraph::_GRAPH_ID tOldGraphID; - u32 dwLevelID; -} SConnectionVertex; - -extern HWND logWindow; - -CGameGraph::CHeader tGraphHeader; - -class CCompareVertexPredicate -{ -public: - IC bool operator()(LPCSTR S1, LPCSTR S2) const { return (xr_strcmp(S1, S2) < 0); } -}; - -u32 dwfGetIDByLevelName(CInifile* Ini, LPCSTR caLevelName) -{ - LPCSTR N, V; - for (u32 k = 0; Ini->r_line("levels", k, &N, &V); k++) - { - R_ASSERT3(Ini->section_exist(N), "Fill section properly!", N); - R_ASSERT3(Ini->line_exist(N, "caption"), "Fill section properly!", N); - R_ASSERT3(Ini->line_exist(N, "id"), "Fill section properly!", N); - if (!xr_strcmp(Ini->r_string_wb(N, "caption"), caLevelName)) - return (Ini->r_u32(N, "id")); - } - return (u32(-1)); -} - -using GRAPH_P_MAP = xr_map; -using VERTEX_MAP = xr_map; - -typedef struct tagSDynamicGraphVertex -{ - Fvector tLocalPoint; - Fvector tGlobalPoint; - u32 tNodeID; - u8 tVertexTypes[GameGraph::LOCATION_TYPE_COUNT]; - u32 tLevelID; - u32 tNeighbourCount; - u32 tDeathPointCount; - u32 dwPointOffset; - CGameGraph::CEdge* tpaEdges; -} SDynamicGraphVertex; - -using GRAPH_VERTEX_VECTOR = xr_vector; -using GRAPH_EDGE_VECTOR = xr_vector; - -class CLevelGameGraph -{ -public: - GRAPH_VERTEX_VECTOR m_tpVertices; - CGameGraph::SLevel m_tLevel; - VERTEX_MAP m_tVertexMap; - u32 m_dwOffset; - LEVEL_POINT_STORAGE m_tpLevelPoints; - CGameGraph* m_tpGraph; - CMemoryWriter m_cross_table; - - CLevelGameGraph(LPCSTR graph_file_name, LPCSTR raw_cross_table_file_name, CGameGraph::SLevel* tLevel, LPCSTR S, u32 dwOffset, u32 dwLevelID, CInifile* Ini) - { - m_tLevel = *tLevel; - m_dwOffset = dwOffset; - m_tpLevelPoints.clear(); - - string_path caFileName; - - // loading graph - xr_strcpy(caFileName, graph_file_name); - m_tpGraph = xr_new(caFileName); - - xr_strcpy(caFileName, raw_cross_table_file_name); - auto l_tpCrossTable = xr_new(caFileName); - - auto l_tpAI_Map = xr_new(S); - - VERIFY2(l_tpCrossTable->header().level_guid() == l_tpAI_Map->header().guid(), - "cross table doesn't correspond to the AI-map, rebuild graph!"); - VERIFY2(l_tpCrossTable->header().game_guid() == m_tpGraph->header().guid(), - "cross table doesn't correspond to the graph, rebuild graph!"); - VERIFY2(m_tpGraph->header().level(GameGraph::_LEVEL_ID(0)).guid() == l_tpAI_Map->header().guid(), - "cross table doesn't correspond to the AI-map, rebuild graph!"); - - VERIFY(l_tpAI_Map->header().vertex_count() == l_tpCrossTable->header().level_vertex_count()); - VERIFY(m_tpGraph->header().vertex_count() == l_tpCrossTable->header().game_vertex_count()); - - tLevel->m_guid = l_tpAI_Map->header().guid(); - - { - for (GameGraph::_GRAPH_ID i = 0, n = m_tpGraph->header().vertex_count(); i < n; ++i) - if ((!l_tpAI_Map->valid_vertex_id(m_tpGraph->vertex(i)->level_vertex_id()) || - (l_tpCrossTable->vertex(m_tpGraph->vertex(i)->level_vertex_id()).game_vertex_id() != i) || - !l_tpAI_Map->inside( - m_tpGraph->vertex(i)->level_vertex_id(), m_tpGraph->vertex(i)->level_point()))) - { - Msg("! Graph doesn't correspond to the cross table"); - R_ASSERT2(false, "Graph doesn't correspond to the cross table"); - } - } - - m_tpVertices.resize(m_tpGraph->header().vertex_count()); - - for (auto &i : m_tpVertices) - { - auto I = std::distance(&m_tpVertices.front(), &i); - i.tLocalPoint = m_tpGraph->vertex(I)->level_point(); - i.tGlobalPoint.add(m_tpGraph->vertex(I)->game_point(), m_tLevel.offset()); - i.tLevelID = dwLevelID; - i.tNodeID = m_tpGraph->vertex(I)->level_vertex_id(); - memcpy(i.tVertexTypes, m_tpGraph->vertex(I)->vertex_type(), GameGraph::LOCATION_TYPE_COUNT * sizeof(GameGraph::_LOCATION_ID)); - i.tNeighbourCount = m_tpGraph->vertex(I)->edge_count(); - CGameGraph::const_iterator b, j, e; - m_tpGraph->begin(I, j, e); - i.tpaEdges = (CGameGraph::CEdge*)xr_malloc(i.tNeighbourCount * sizeof(CGameGraph::CEdge)); - b = j; - for (; j != e; ++j) - { - auto& edge = i.tpaEdges[j - b]; - edge = *j; - VERIFY((edge.vertex_id() + dwOffset) < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - edge.m_vertex_id = (GameGraph::_GRAPH_ID)(edge.m_vertex_id + dwOffset); - } - i.dwPointOffset = 0; - vfGenerateDeathPoints(I, l_tpCrossTable, l_tpAI_Map, i.tDeathPointCount); - } - - xr_delete(l_tpCrossTable); - xr_delete(l_tpAI_Map); - - // updating cross-table - { - xr_strcpy(caFileName, raw_cross_table_file_name); - auto tpCrossTable = xr_new(caFileName); - xr_vector tCrossTableUpdate; - tCrossTableUpdate.resize(tpCrossTable->header().level_vertex_count()); - for (int i = 0; i < (int)tpCrossTable->header().level_vertex_count(); i++) - { - tCrossTableUpdate[i] = tpCrossTable->vertex(i); - VERIFY(u32(tCrossTableUpdate[i].tGraphIndex) < tpCrossTable->header().game_vertex_count()); - tCrossTableUpdate[i].tGraphIndex = tCrossTableUpdate[i].tGraphIndex + (GameGraph::_GRAPH_ID)dwOffset; - } - - CGameLevelCrossTable::CHeader tCrossTableHeader; - - tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; - tCrossTableHeader.dwNodeCount = tpCrossTable->m_tCrossTableHeader.dwNodeCount; - tCrossTableHeader.dwGraphPointCount = tpCrossTable->m_tCrossTableHeader.dwGraphPointCount; - tCrossTableHeader.m_level_guid = tpCrossTable->m_tCrossTableHeader.m_level_guid; - tCrossTableHeader.m_game_guid = tGraphHeader.m_guid; - - xr_delete(tpCrossTable); - - m_cross_table.w(&tCrossTableHeader, sizeof(tCrossTableHeader)); - for (int i = 0; i < (int)tCrossTableHeader.dwNodeCount; i++) - m_cross_table.w(&(tCrossTableUpdate[i]), sizeof(tCrossTableUpdate[i])); - } - - // fill vertex map - { - string_path fName; - strconcat(sizeof(fName), fName, S, "level.spawn"); - auto F = FS.r_open(fName); - u32 id; - auto O = F->open_chunk_iterator(id); - int vertexId = 0; - for (; O; O = F->open_chunk_iterator(id, O)) - { - NET_Packet P; - P.B.count = O->length(); - O->r(P.B.data, P.B.count); - u16 ID; - P.r_begin(ID); - R_ASSERT(M_SPAWN == ID); - P.r_stringZ(fName); - auto E = F_entity_Create(fName); - R_ASSERT3(E, "Can't create entity.", fName); - //E->Spawn_Read(P); - auto tpGraphPoint = smart_cast(E); - if (tpGraphPoint) - { - E->Spawn_Read(P); - - auto tVector = tpGraphPoint->o_Position; - auto tGraphID = GameGraph::_GRAPH_ID(-1); - float fMinDistance = 1000000.f; - { - for (auto &i : m_tpVertices) - { - float fDistance = i.tLocalPoint.distance_to(tVector); - if (fDistance < fMinDistance) - { - fMinDistance = fDistance; - tGraphID = GameGraph::_GRAPH_ID(std::distance(&m_tpVertices.front(), &i)); - if (fMinDistance < EPS_L) - break; - } - } - } - if (fMinDistance < EPS_L) - { - SConnectionVertex T; - pstr S; - S = xr_strdup(tpGraphPoint->name_replace()); - T.caConnectName = xr_strdup(*tpGraphPoint->m_caConnectionPointName); - T.dwLevelID = dwfGetIDByLevelName(Ini, *tpGraphPoint->m_caConnectionLevelName); - // T.tGraphID = (GameGraph::_GRAPH_ID)vertexId; - // T.tOldGraphID = tGraphID; - T.tOldGraphID = (GameGraph::_GRAPH_ID)vertexId; - T.tGraphID = tGraphID; - - bool ok = true; - for (auto &i : m_tVertexMap) - { - if (T.tOldGraphID == i.second.tOldGraphID) - { - ok = false; - Msg("Graph point %s is removed,because it has the same position as some another graph point", E->name_replace()); - break; - } - } - - if (ok) - { - m_tVertexMap.insert(std::make_pair(S, T)); - vertexId++; - } - } - } - F_entity_Destroy(E); - } - if (vertexId != m_tpGraph->header().vertex_count()) - Msg("Graph for the level %s doesn't correspond to the graph points from Level Editor! (%d : %d)", - *m_tLevel.name(), vertexId, m_tpGraph->header().vertex_count()); - - for (auto &i : m_tVertexMap) - R_ASSERT3(!xr_strlen(i.second.caConnectName) || (i.second.tGraphID < m_tpVertices.size()), "Rebuild graph for the level", *m_tLevel.name()); - - //VERIFY3(vertexId==m_tpGraph->header().vertex_count(), "Rebuild graph for the level",m_tLevel.name()); - O->close(); - FS.r_close(F); - } - }; - - virtual ~CLevelGameGraph() - { - for (auto &i : m_tpVertices) - xr_free(i.tpaEdges); - - delete_data(m_tVertexMap); - xr_delete(m_tpGraph); - }; - - void vfAddEdge(u32 dwVertexNumber, CGameGraph::CEdge& tGraphEdge) - { - R_ASSERT(m_tpGraph->header().vertex_count() > dwVertexNumber); - m_tpVertices[dwVertexNumber].tpaEdges = (CGameGraph::CEdge*)xr_realloc(m_tpVertices[dwVertexNumber].tpaEdges, - sizeof(CGameGraph::CEdge) * ++m_tpVertices[dwVertexNumber].tNeighbourCount); - m_tpVertices[dwVertexNumber].tpaEdges[m_tpVertices[dwVertexNumber].tNeighbourCount - 1] = tGraphEdge; - } - - void vfSaveVertices( - CMemoryWriter& tMemoryStream, u32& dwOffset, u32& dwPointOffset, LEVEL_POINT_STORAGE* tpLevelPoints) - { - GameGraph::CGameVertex tVertex; - - for (auto &i : m_tpVertices) - { - tVertex.tLocalPoint = i.tLocalPoint; - tVertex.tGlobalPoint = i.tGlobalPoint; - tVertex.tNodeID = i.tNodeID; - memcpy(tVertex.tVertexTypes, i.tVertexTypes, - GameGraph::LOCATION_TYPE_COUNT * sizeof(GameGraph::_LOCATION_ID)); - tVertex.tLevelID = i.tLevelID; - tVertex.dwEdgeOffset = dwOffset; - tVertex.dwPointOffset = dwPointOffset; - - VERIFY(i.tNeighbourCount < (u32(1) << (8 * sizeof(u8)))); - tVertex.tNeighbourCount = (u8)i.tNeighbourCount; - - VERIFY(i.tDeathPointCount < (u32(1) << (8 * sizeof(u8)))); - tVertex.tDeathPointCount = (u8)i.tDeathPointCount; - - tMemoryStream.w(&tVertex, sizeof(tVertex)); - dwOffset += i.tNeighbourCount * sizeof(CGameGraph::CEdge); - dwPointOffset += i.tDeathPointCount * sizeof(CGameGraph::CLevelPoint); - } - }; - - void vfSaveEdges(CMemoryWriter& tMemoryStream) - { - for (auto &i : m_tpVertices) - for (int j = 0; j < (int)i.tNeighbourCount; j++) - tMemoryStream.w(i.tpaEdges + j, sizeof(CGameGraph::CEdge)); - }; - - void save_cross_table(IWriter& stream) - { - stream.w_u32(m_cross_table.size() + sizeof(u32)); - m_cross_table.seek(0); - stream.w(m_cross_table.pointer(), m_cross_table.size()); - m_cross_table.clear(); - } - - u32 dwfGetEdgeCount() - { - u32 l_dwResult = 0; - for (auto &i : m_tpVertices) - l_dwResult += i.tNeighbourCount; - return (l_dwResult); - } - - u32 dwfGetDeathPointCount() - { - u32 l_dwResult = 0; - for (auto &i : m_tpVertices) - l_dwResult += i.tDeathPointCount; - return (l_dwResult); - } - - void vfGenerateDeathPoints( - int iGraphIndex, CGameLevelCrossTable* tpCrossTable, CLevelGraph* tpAI_Map, u32& dwDeathPointCount) - { - xr_vector l_dwaNodes; - l_dwaNodes.clear(); - { - for (u32 i = 0, n = tpCrossTable->m_tCrossTableHeader.dwNodeCount; i < n; i++) - if (tpCrossTable->m_tpaCrossTable[i].tGraphIndex == iGraphIndex) - l_dwaNodes.push_back(i); - } - - R_ASSERT2(!l_dwaNodes.empty(), "Can't create at least one death point for specified graph point"); - - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(l_dwaNodes.begin(), l_dwaNodes.end(), g); - - u32 m = l_dwaNodes.size() > 10 ? std::min(iFloor(.1f * l_dwaNodes.size()), 255) : l_dwaNodes.size(), - l_dwStartIndex = m_tpLevelPoints.size(); - m_tpLevelPoints.resize(l_dwStartIndex + m); - auto I = m_tpLevelPoints.begin() + l_dwStartIndex; - auto E = m_tpLevelPoints.end(); - auto i = l_dwaNodes.begin(); - - dwDeathPointCount = m; - - for (; I != E; ++I, ++i) - { - (*I).tNodeID = *i; - (*I).tPoint = tpAI_Map->vertex_position(*i); - (*I).fDistance = tpCrossTable->vertex(*i).distance(); - } - } -}; - -class CGraphMerger -{ -public: - CGraphMerger(LPCSTR game_graph_id, LPCSTR name, bool rebuild); -}; - -void read_levels(CInifile* Ini, xr_set& levels, bool rebuild_graph, xr_vector* needed_levels) -{ - pcstr field_name, field_value; - string_path caFileName, file_name; - for (u32 k = 0; Ini->r_line("levels", k, &field_name, &field_value); k++) - { - string256 N; - xr_strcpy(N, field_name); - xr_strlwr(N); - - if (!Ini->section_exist(N)) - { - Msg("! There is no section %s in the %s!", N, GAME_CONFIG); - continue; - } - - if (!Ini->line_exist(N, "name")) - { - Msg("! There is no line \"name\" in the section %s!", N); - continue; - } - - if (!Ini->line_exist(N, "id")) - { - Msg("! There is no line \"id\" in the section %s!", N); - continue; - } - - if (!Ini->line_exist(N, "offset")) - { - Msg("! There is no line \"offset\" in the section %s!", N); - continue; - } - - u8 id = Ini->r_u8(N, "id"); - cpcstr level_name = Ini->r_string(N, "name"); - string256 S; - xr_strcpy(S, level_name); - xr_strlwr(S); - - if (needed_levels) - { - bool found = false; - for (const auto &i : *needed_levels) - { - if (!xr_strcmp(i, S)) - { - found = true; - break; - } - } - - if (!found) - continue; - } - - { - bool ok = true; - for (auto &i : levels) - { - if (!xr_strcmp(i.m_section, N)) - { - Msg("! Duplicated line %s in section \"levels\" in the %s", N, GAME_CONFIG); - ok = false; - break; - } - if (!xr_strcmp(i.m_name, S)) - { - Msg("! Duplicated level name %s in the %s, sections %s, %s", S, GAME_CONFIG, *i.m_section, N); - ok = false; - break; - } - if (i.m_id == id) - { - Msg("! Duplicated level id %d in the %s, section %s, level %s", id, GAME_CONFIG, N, S); - ok = false; - break; - } - } - if (!ok) - continue; - } - IReader* reader; - // ai - strconcat(sizeof(caFileName), caFileName, S, "\\", LEVEL_GRAPH_NAME); - FS.update_path(file_name, "$game_levels$", caFileName); - if (!FS.exist(file_name)) - { - Msg("! There is no ai-map for the level %s! (level is not included into the game graph)", S); - continue; - } - - { - reader = FS.r_open(file_name); - CLevelGraph::CHeader header; - reader->r(&header, sizeof(header)); - FS.r_close(reader); - if (header.version() != XRAI_CURRENT_VERSION) - { - Msg("! AI-map for the level %s is incompatible (version mismatch)! (level is not included into the game graph)", S); - continue; - } - } - - levels.insert(CLevelInfo(id, S, Ini->r_fvector3(N, "offset"), N)); - } -} - -LPCSTR generate_temp_file_name(LPCSTR header0, LPCSTR header1, string_path& buffer) -{ - string_path path; - FS.update_path(path, "$app_data_root$", "temp"); - xr_strcat(path, sizeof(path), "\\"); - - _mkdir(path); - - strconcat(sizeof(buffer), buffer, path, header0, header1); - return (buffer); -} - -void fill_needed_levels(pstr levels, xr_vector& result) -{ - auto I = levels; - for (auto J = I;; ++I) - { - if (*I != ',') - { - if (*I) - continue; - - result.push_back(J); - break; - } - - *I = 0; - result.push_back(J); - J = I + 1; - } -} - -CGraphMerger::CGraphMerger(LPCSTR game_graph_id, LPCSTR name, bool rebuild) -{ - // load all the graphs - Logger.Phase("Processing level graphs"); - - CInifile* Ini = xr_new(INI_FILE); - R_ASSERT(Ini->section_exist("levels")); - - tGraphHeader.m_guid = generate_guid(); - - GRAPH_P_MAP tpGraphs; - string4096 S1, S2; - CGameGraph::SLevel tLevel; - u32 dwOffset = 0; - u32 l_dwPointOffset = 0; - LEVEL_POINT_STORAGE l_tpLevelPoints; - l_tpLevelPoints.clear(); - - xr_set levels; - xr_vector needed_levels; - string4096 levels_string; - xr_strcpy(levels_string, name); - xr_strlwr(levels_string); - fill_needed_levels(levels_string, needed_levels); - - read_levels(Ini, levels, rebuild, &needed_levels); - - for (const auto &i : levels) - { - tLevel.m_offset = i.m_offset; - tLevel.m_name = i.m_name; - xr_strcpy(S1, sizeof(S1), *i.m_name); - strconcat(sizeof(S2), S2, name, S1); - strconcat(sizeof(S1), S1, S2, "\\"); - tLevel.m_id = i.m_id; - tLevel.m_section = i.m_section; - Msg("%9s %2d %s", "level", tLevel.id(), *tLevel.m_name); - string_path _0, _1; - generate_temp_file_name("local_graph_", *tLevel.m_name, _0); - generate_temp_file_name("raw_cross_table_", *tLevel.m_name, _1); - string_path level_folder; - FS.update_path(level_folder, "$game_levels$", *tLevel.m_name); - xr_strcat(level_folder, "\\"); - CGameGraphBuilder().build_graph(_0, _1, level_folder); - auto tpLevelGraph = xr_new<::CLevelGameGraph>(_0, _1, &tLevel, level_folder, dwOffset, tLevel.id(), Ini); - dwOffset += tpLevelGraph->m_tpGraph->header().vertex_count(); - R_ASSERT2(tpGraphs.find(tLevel.id()) == tpGraphs.end(), "Level ids _MUST_ be different!"); - tpGraphs.insert(std::make_pair(tLevel.id(), tpLevelGraph)); - tGraphHeader.m_levels.emplace(tLevel.id(), tLevel); - } - - R_ASSERT(tpGraphs.size()); - - Logger.Phase("Adding interconnection points"); - { - for (auto &i : tpGraphs) - { - for (auto &j : i.second->m_tVertexMap) - { - if (j.second.caConnectName[0]) - { - CGameGraph::CEdge tGraphEdge; - auto& tConnectionVertex = j.second; - auto K = tpGraphs.find(tConnectionVertex.dwLevelID); - if (K == tpGraphs.end()) - { - Msg("Cannot find level with level_id %d. Connection point will not be generated!", tConnectionVertex.dwLevelID); - continue; - } - R_ASSERT(K != tpGraphs.end()); - auto M = (*K).second->m_tVertexMap.find(tConnectionVertex.caConnectName); - if (M == (*K).second->m_tVertexMap.end()) - { - Msg("Level %s with id %d has an INVALID connection point %s,\nwhich references to graph point %s on the level %s with id %d\n", - *i.second->m_tLevel.name(), i.second->m_tLevel.id(), j.first, - tConnectionVertex.caConnectName, *(*K).second->m_tLevel.name(), (*K).second->m_tLevel.id()); - R_ASSERT(M != (*K).second->m_tVertexMap.end()); - } - - //if (!xr_stricmp("l06_rostok",*i.second->m_tLevel.name())) - // __asm int 3; - - Msg("Level %s with id %d has VALID connection point %s,\nwhich references to graph point %s on the level %s with id %d\n", - *i.second->m_tLevel.name(), i.second->m_tLevel.id(), j.first, - tConnectionVertex.caConnectName, *(*K).second->m_tLevel.name(), (*K).second->m_tLevel.id()); - - VERIFY(((*M).second.tGraphID + (*K).second->m_dwOffset) < - (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - tGraphEdge.m_vertex_id = (GameGraph::_GRAPH_ID)((*M).second.tGraphID + (*K).second->m_dwOffset); - VERIFY3(tConnectionVertex.tGraphID < i.second->m_tpVertices.size(), "Rebuild graph for the level", *i.second->m_tLevel.name()); - VERIFY3((*M).second.tGraphID < (*K).second->m_tpVertices.size(), "Rebuild graph for the level", *(*K).second->m_tLevel.name()); - tGraphEdge.m_path_distance = - i.second->m_tpVertices[tConnectionVertex.tGraphID].tGlobalPoint.distance_to( - (*K).second->m_tpVertices[(*M).second.tGraphID].tGlobalPoint); - i.second->vfAddEdge(j.second.tGraphID, tGraphEdge); - //tGraphEdge.dwVertexNumber = j.second.tGraphID + i.second->m_dwOffset; - //(*K).second->vfAddEdge((*M).second.tGraphID,tGraphEdge); - } - } - } - } - // counting edges - { - tGraphHeader.m_edge_count = 0; - tGraphHeader.m_death_point_count = 0; - for (auto &i : tpGraphs) - { - VERIFY((u32(tGraphHeader.m_edge_count) + i.second->dwfGetEdgeCount()) < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - tGraphHeader.m_edge_count += (GameGraph::_GRAPH_ID)i.second->dwfGetEdgeCount(); - tGraphHeader.m_death_point_count += i.second->dwfGetDeathPointCount(); - } - } - - /////////////////////////////////////////////////// - - // save all the graphs - Logger.Phase("Saving graph being merged"); - CMemoryWriter F; - tGraphHeader.m_version = XRAI_CURRENT_VERSION; - VERIFY(dwOffset < (u32(1) << (8 * sizeof(GameGraph::_GRAPH_ID)))); - tGraphHeader.m_vertex_count = (GameGraph::_GRAPH_ID)dwOffset; - tGraphHeader.save(&F); - - u32 vertex_count = 0; - dwOffset *= sizeof(CGameGraph::CGameVertex); - u32 l_dwOffset = F.size(); - l_dwPointOffset = dwOffset + tGraphHeader.edge_count() * sizeof(CGameGraph::CEdge); - u32 l_dwStartPointOffset = l_dwPointOffset; - - for (auto &i : tpGraphs) - { - i.second->vfSaveVertices(F, dwOffset, l_dwPointOffset, &l_tpLevelPoints); - vertex_count += i.second->m_tpGraph->header().vertex_count(); - } - - for (auto &i : tpGraphs) - i.second->vfSaveEdges(F); - - l_tpLevelPoints.clear(); - for (auto &i : tpGraphs) - l_tpLevelPoints.insert(l_tpLevelPoints.end(), i.second->m_tpLevelPoints.begin(), i.second->m_tpLevelPoints.end()); - - R_ASSERT2(l_dwStartPointOffset == F.size() - l_dwOffset, "Graph file format is corrupted"); - - for (auto &i : l_tpLevelPoints) - save_data(i, F); - - for (auto &i : tpGraphs) - { - Msg("cross_table offset: %d", F.size()); - i.second->save_cross_table(F); - } - - string256 l_caFileName; - xr_strcpy(l_caFileName, game_graph_id); - F.save_to(l_caFileName); - - // free all the graphs - Logger.Phase("Freeing resources being allocated"); - - for (auto &i : tpGraphs) - xr_free(i.second); - - xr_delete(Ini); -} - -void xrMergeGraphs(LPCSTR game_graph_id, LPCSTR name, bool rebuild) { CGraphMerger A(game_graph_id, name, rebuild); } diff --git a/src/utils/xrAI/xr_graph_merge.h b/src/utils/xrAI/xr_graph_merge.h deleted file mode 100644 index 9c4eeb68c63..00000000000 --- a/src/utils/xrAI/xr_graph_merge.h +++ /dev/null @@ -1,26 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : xr_graph_merge.h -// Created : 25.01.2003 -// Modified : 25.01.2003 -// Author : Dmitriy Iassenev -// Description : Merging level graphs for off-line AI NPC computations -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -struct CLevelInfo -{ - u8 m_id; - shared_str m_name; - Fvector m_offset; - shared_str m_section; - - CLevelInfo(u8 id, shared_str name, const Fvector& offset, shared_str section) - : m_id(id), m_name(name), m_offset(offset), m_section(section) - { - } - - IC bool operator<(const CLevelInfo& info) const { return (m_id < info.m_id); } -}; - -extern void xrMergeGraphs(LPCSTR game_graph_id, LPCSTR name, bool rebuild); diff --git a/src/utils/xrDO_Light/StdAfx.cpp b/src/utils/xrDO_Light/StdAfx.cpp deleted file mode 100644 index c9cd8f0a45f..00000000000 --- a/src/utils/xrDO_Light/StdAfx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" -#include "xrCore/cdecl_cast.hpp" -#include "utils/xrLCUtil/LevelCompilerLoggerWindow.hpp" - -ILevelCompilerLogger& Logger = LevelCompilerLoggerWindow::instance(); - -CThread::LogFunc ProxyMsg = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.clMsgV(format, args); - va_end(args); -}); - -CThreadManager::ReportStatusFunc ProxyStatus = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.StatusV(format, args); - va_end(args); -}); - -CThreadManager::ReportProgressFunc ProxyProgress = cdecl_cast([](float progress) { Logger.Progress(progress); }); diff --git a/src/utils/xrDO_Light/StdAfx.h b/src/utils/xrDO_Light/StdAfx.h deleted file mode 100644 index cd75ce965b9..00000000000 --- a/src/utils/xrDO_Light/StdAfx.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" - -#include "utils/xrLCUtil/ILevelCompilerLogger.hpp" -#include "utils/xrLCUtil/xrThread.hpp" - -extern ILevelCompilerLogger& Logger; -extern CThread::LogFunc ProxyMsg; -extern CThreadManager::ReportStatusFunc ProxyStatus; -extern CThreadManager::ReportProgressFunc ProxyProgress; diff --git a/src/utils/xrDO_Light/packages.config b/src/utils/xrDO_Light/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/xrDO_Light/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/xrDO_Light/xrDO_Light.cpp b/src/utils/xrDO_Light/xrDO_Light.cpp deleted file mode 100644 index 990a4d4be58..00000000000 --- a/src/utils/xrDO_Light/xrDO_Light.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "stdafx.h" - -#include "utils/xrLC_Light/xrlc_light.h" -//#pragma comment(linker,"/STACK:0x800000,0x400000") - -static const char* h_str = - "The following keys are supported / required:\n" - "-? or -h == this help\n" - "-f == compile level in gamedata\\levels\\\\\n" - "\n" - "NOTE: The last key is required for any functionality\n"; - -void Help() { MessageBox(0, h_str, "Command line options", MB_OK | MB_ICONINFORMATION); } -void Startup(pstr lpCmdLine) -{ - char cmd[512]; - bool bNet = false; - xr_strcpy(cmd, lpCmdLine); - xr_strlwr(cmd); - if (strstr(cmd, "-?") || strstr(cmd, "-h")) - { - Help(); - return; - } - if (strstr(cmd, "-f") == 0) - { - Help(); - return; - } - if (strstr(cmd, "-net")) - bNet = true; - // Load project - char name[256]; - *name = 0; - sscanf(strstr(cmd, "-f") + 2, "%s", name); - string256 temp; - xr_sprintf(temp, "%s - Detail Compiler", name); - Logger.Initialize(temp); - - FS.get_path("$level$")->_set(name); - - CTimer dwStartupTime; - dwStartupTime.Start(); - - xrCompileDO(bNet); - - // Show statistic - char stats[256]; - xr_sprintf(stats, "Time elapsed: %s", make_time((dwStartupTime.GetElapsed_ms()) / 1000).c_str()); - - if (!strstr(cmd, "-silent")) - Logger.Success(stats); - Logger.Destroy(); -} - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - xrDebug::Initialize(lpCmdLine); - Core.Initialize("xrDO"); - - Startup(lpCmdLine); - - return 0; -} diff --git a/src/utils/xrDO_Light/xrDO_Light.vcxproj b/src/utils/xrDO_Light/xrDO_Light.vcxproj deleted file mode 100644 index 4b8723a7157..00000000000 --- a/src/utils/xrDO_Light/xrDO_Light.vcxproj +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - {B730F54D-1199-481A-AAD0-5DB684E067C0} - - - - - - - Application - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - - - - - - - - Create - - - - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {b90bdc22-a891-4b33-b562-29d701f65dbd} - - - {efb76d6f-0092-439c-a783-c0be10bd17c9} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/xrDO_Light/xrDO_Light.vcxproj.filters b/src/utils/xrDO_Light/xrDO_Light.vcxproj.filters deleted file mode 100644 index 02a69538d24..00000000000 --- a/src/utils/xrDO_Light/xrDO_Light.vcxproj.filters +++ /dev/null @@ -1,27 +0,0 @@ - - - - - {b29b8dd4-9ba8-4204-a99d-bdf18bdb8b47} - - - - - Kernel - - - - - Kernel - - - Kernel - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrDXT/DXT.cpp b/src/utils/xrDXT/DXT.cpp deleted file mode 100644 index a2318ebcc6c..00000000000 --- a/src/utils/xrDXT/DXT.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "stdafx.h" -#include -#include "Layers/xrRender/ETextureParams.h" - -class DDSErrorHandler : public nvtt::ErrorHandler -{ -public: - virtual void error(nvtt::Error e) override; -}; - -void DDSErrorHandler::error(nvtt::Error e) -{ - MessageBox(0, nvtt::errorString(e), "DXT compress error", MB_ICONERROR | MB_OK); -} - -u32* Build32MipLevel(u32& _w, u32& _h, u32& _p, u32* pdwPixelSrc, STextureParams* fmt, float blend) -{ - R_ASSERT(pdwPixelSrc); - R_ASSERT(_w % 2 == 0); - R_ASSERT(_h % 2 == 0); - R_ASSERT(_p % 4 == 0); - u32 dwDestPitch = (_w / 2) * 4; - u32* pNewData = xr_alloc((_h / 2) * dwDestPitch); - u8* pDest = (u8*)pNewData; - u8* pSrc = (u8*)pdwPixelSrc; - float mixed_a = (float)u8(fmt->fade_color >> 24); - float mixed_r = (float)u8(fmt->fade_color >> 16); - float mixed_g = (float)u8(fmt->fade_color >> 8); - float mixed_b = (float)u8(fmt->fade_color >> 0); - float inv_blend = 1.f - blend; - for (u32 y = 0; y < _h; y += 2) - { - u8* pScanline = pSrc + y * _p; - for (u32 x = 0; x < _w; x += 2) - { - u8* p1 = pScanline + x * 4; - u8* p2 = p1 + 4; - if (1 == _w) - p2 = p1; - u8* p3 = p1 + _p; - if (1 == _h) - p3 = p1; - u8* p4 = p2 + _p; - if (1 == _h) - p4 = p2; - float c_r = float(u32(p1[0]) + u32(p2[0]) + u32(p3[0]) + u32(p4[0])) / 4.f; - float c_g = float(u32(p1[1]) + u32(p2[1]) + u32(p3[1]) + u32(p4[1])) / 4.f; - float c_b = float(u32(p1[2]) + u32(p2[2]) + u32(p3[2]) + u32(p4[2])) / 4.f; - float c_a = float(u32(p1[3]) + u32(p2[3]) + u32(p3[3]) + u32(p4[3])) / 4.f; - if (fmt->flags.is(STextureParams::flFadeToColor)) - { - c_r = c_r * inv_blend + mixed_r * blend; - c_g = c_g * inv_blend + mixed_g * blend; - c_b = c_b * inv_blend + mixed_b * blend; - } - if (fmt->flags.is(STextureParams::flFadeToAlpha)) - { - c_a = c_a * inv_blend + mixed_a * blend; - } - float A = c_a + c_a / 8.f; - int _r = int(c_r); - clamp(_r, 0, 255); - *pDest++ = u8(_r); - int _g = int(c_g); - clamp(_g, 0, 255); - *pDest++ = u8(_g); - int _b = int(c_b); - clamp(_b, 0, 255); - *pDest++ = u8(_b); - int _a = int(A); - clamp(_a, 0, 255); - *pDest++ = u8(_a); - } - } - _w /= 2; - _h /= 2; - _p = _w * 4; - return pNewData; -} - -IC u32 GetPowerOf2Plus1(u32 v) -{ - u32 cnt = 0; - while (v) - { - v >>= 1; - cnt++; - } - return cnt; -} - -void FillRect(u8* data, u8* new_data, u32 offs, u32 pitch, u32 h, u32 full_pitch) -{ - for (u32 i = 0; i < h; i++) - { - CopyMemory(data + (full_pitch * i + offs), new_data + i * pitch, pitch); - } -} - -int DXTCompressImage(LPCSTR out_name, u8* raw_data, u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth) -{ - R_ASSERT(0 != w && 0 != h); - bool result = false; - nvtt::InputOptions inOpt; - auto layout = fmt->type == STextureParams::ttCubeMap ? nvtt::TextureType_Cube : nvtt::TextureType_2D; - inOpt.setTextureLayout(layout, w, h); - inOpt.setMipmapGeneration(fmt->flags.is(STextureParams::flGenerateMipMaps)); - inOpt.setWrapMode(nvtt::WrapMode_Clamp); - inOpt.setNormalMap(false); - inOpt.setConvertToNormalMap(false); - inOpt.setGamma(2.2f, 2.2f); - inOpt.setNormalizeMipmaps(false); - nvtt::CompressionOptions compOpt; - compOpt.setQuality(nvtt::Quality_Highest); - compOpt.setQuantization(fmt->flags.is(STextureParams::flDitherColor), false, fmt->flags.is(STextureParams::flBinaryAlpha)); - switch (fmt->fmt) - { - case STextureParams::tfDXT1: compOpt.setFormat(nvtt::Format_DXT1 ); break; - case STextureParams::tfADXT1: compOpt.setFormat(nvtt::Format_DXT1a); break; - case STextureParams::tfDXT3: compOpt.setFormat(nvtt::Format_DXT3 ); break; - case STextureParams::tfDXT5: compOpt.setFormat(nvtt::Format_DXT5 ); break; - case STextureParams::tfRGB: compOpt.setFormat(nvtt::Format_RGB ); break; - case STextureParams::tfRGBA: compOpt.setFormat(nvtt::Format_RGBA ); break; - } - switch (fmt->mip_filter) - { - case STextureParams::kMIPFilterAdvanced: break; - case STextureParams::kMIPFilterBox: inOpt.setMipmapFilter(nvtt::MipmapFilter_Box ); break; - case STextureParams::kMIPFilterTriangle: inOpt.setMipmapFilter(nvtt::MipmapFilter_Triangle); break; - case STextureParams::kMIPFilterKaiser: inOpt.setMipmapFilter(nvtt::MipmapFilter_Kaiser ); break; - } - nvtt::OutputOptions outOpt; - outOpt.setFileName(out_name); - DDSErrorHandler handler; - outOpt.setErrorHandler(&handler); - if (fmt->flags.is(STextureParams::flGenerateMipMaps) && STextureParams::kMIPFilterAdvanced == fmt->mip_filter) - { - inOpt.setMipmapGeneration(false); - int numMipmaps = GetPowerOf2Plus1(__min(w, h)); - u32 line_pitch = w * 2 * 4; - u8* pImagePixels = xr_alloc(line_pitch * h); - u32 w_offs = 0; - u32 dwW = w; - u32 dwH = h; - u32 dwP = pitch; - u32* pLastMip = xr_alloc(w * h * 4); - CopyMemory(pLastMip, raw_data, w * h * 4); - FillRect(pImagePixels, (u8*)pLastMip, w_offs, pitch, dwH, line_pitch); - w_offs += dwP; - float inv_fade = clampr(1.f - float(fmt->fade_amount) / 100.f, 0.f, 1.f); - float blend = fmt->flags.is_any(STextureParams::flFadeToColor | STextureParams::flFadeToAlpha) ? inv_fade : 1.f; - for (int i = 1; i < numMipmaps; i++) - { - u32* pNewMip = Build32MipLevel(dwW, dwH, dwP, pLastMip, fmt, i < fmt->fade_delay ? 0.f : 1.f - blend); - FillRect(pImagePixels, (u8*)pNewMip, w_offs, dwP, dwH, line_pitch); - xr_free(pLastMip); - pLastMip = pNewMip; - pNewMip = 0; - w_offs += dwP; - } - xr_free(pLastMip); - inOpt.setMipmapData(pImagePixels, w, h); - result = nvtt::Compressor().process(inOpt, compOpt, outOpt); - xr_free(pImagePixels); - } - else - { - inOpt.setMipmapData(raw_data, w, h); - result = nvtt::Compressor().process(inOpt, compOpt, outOpt); - } - if (!result) - { - xr_unlink(out_name); - return 0; - } - return 1; -} - -extern int DXTCompressBump(LPCSTR out_name, u8* raw_data, u8* normal_map, - u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth); - -extern "C" XR_EXPORT -int DXTCompress(pcstr out_name, u8* raw_data, u8* normal_map, - u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth) -{ - switch (fmt->type) - { - case STextureParams::ttImage: - case STextureParams::ttCubeMap: - case STextureParams::ttNormalMap: - case STextureParams::ttTerrain: return DXTCompressImage(out_name, raw_data, w, h, pitch, fmt, depth); break; - case STextureParams::ttBumpMap: return DXTCompressBump(out_name, raw_data, normal_map, w, h, pitch, fmt, depth); break; - default: NODEFAULT; - } - return -1; -} diff --git a/src/utils/xrDXT/DXT.vcxproj b/src/utils/xrDXT/DXT.vcxproj deleted file mode 100644 index 7ed39bbd746..00000000000 --- a/src/utils/xrDXT/DXT.vcxproj +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - {EBF9B543-0830-4866-9B48-DC0740E87E8A} - DXT - - - - - - - DynamicLibrary - - - - - - - - - - - $(xrBinDir)utils\ - - - - $(xrExternals)nvtt\include;%(AdditionalIncludeDirectories) - _USRDLL;DXT_EXPORTS;%(PreprocessorDefinitions) - FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - false - false - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - {0eb257dc-5cfc-44b0-82c9-ce6b158be473} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrDXT/DXT.vcxproj.filters b/src/utils/xrDXT/DXT.vcxproj.filters deleted file mode 100644 index beabb982019..00000000000 --- a/src/utils/xrDXT/DXT.vcxproj.filters +++ /dev/null @@ -1,62 +0,0 @@ - - - - - {4fe1da01-7a52-4559-bb15-a14fb52a8c9c} - - - {ebd62474-7505-4523-9c9d-ca09233d3704} - - - {6e4bc661-d7f1-4351-8d46-392b19298175} - - - - - NormalMap - - - NormalMap - - - NormalMap - - - NormalMap - - - - - - - - - Shared - - - - - - Convert - - - NormalMap - - - NormalMap - - - NormalMap - - - NormalMap - - - - Shared - - - - - - \ No newline at end of file diff --git a/src/utils/xrDXT/Image_DXTC.cpp b/src/utils/xrDXT/Image_DXTC.cpp deleted file mode 100644 index d9a78291508..00000000000 --- a/src/utils/xrDXT/Image_DXTC.cpp +++ /dev/null @@ -1,988 +0,0 @@ -/*********************************************************************NVMH2**** -Path: C:\Dev\devrel\Nv_sdk_4\Direct3D\Decompress_DXTC -File: Image_DXTC.cpp - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - -******************************************************************************/ - -#include "stdafx.h" - -#include "Image_DXTC.h" -#include - -#define LOW_5 0x001F; -#define MID_6 0x07E0; -#define HIGH_5 0xF800; -#define MID_555 0x03E0; -#define HI_555 0x7C00; - -// should be in ddraw.h -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3)\ - ((u32)(u8)(ch0) | ((u32)(u8)(ch1) << 8) | ((u32)(u8)(ch2) << 16) | ((u32)(u8)(ch3) << 24)) -#endif // defined(MAKEFOURCC) - -// Defined in this module: -u16 GetNumberOfBits(u32 dwMask); - -Image_DXTC::Image_DXTC() -{ - m_pCompBytes = NULL; - m_pDecompBytes = NULL; -} - -Image_DXTC::~Image_DXTC() -{ - if (m_pCompBytes != NULL) - { - free(m_pCompBytes); - m_pCompBytes = NULL; - } - if (m_pDecompBytes != NULL) - { - free(m_pDecompBytes); - m_pDecompBytes = NULL; - } -} - -void Image_DXTC::SaveAsRaw() -{ - // save decompressed bits - FILE* pf = fopen("decom.raw", "wb"); - VERIFY(pf); - // writes only 32 bit format. - fwrite(m_pDecompBytes, m_nHeight * m_nWidth * 4, sizeof(u8), pf); - fclose(pf); - pf = NULL; -} - -bool Image_DXTC::LoadFromFile(LPCSTR filename) -{ - if (m_pCompBytes != NULL) - { - free(m_pCompBytes); - m_pCompBytes = NULL; - } - // only understands .dds files for now - // return true if success - char* exts[] = {".DDS"}; - int next = 1; - char fileupper[256]; - strcpy_s(fileupper, filename); - xr_strupr(fileupper); - // TRACE( "\n" ); - // TRACE( "\n" ); - bool knownformat = false; - for (int i = 0; i < next; i++) - { - char* found = strstr(fileupper, exts[0]); - if (found != NULL) - { - knownformat = true; - break; - } - } - if (knownformat == false) - { - // TRACE("Unknown file format encountered! [%s]\n", filename ); - return false; - } - // TRACE("\n\nLoading file [%s]\n", filename ); - FILE* file = fopen(filename, "rb"); - if (file == NULL) - { - // TRACE("Can't open file for reading! [%s]\n", filename ); - return false; - } - // start reading the file - // from Microsoft's mssdk D3DIM example "Compress" - DDS_HEADER ddsd; - u32 dwMagic; - // Read magic number - fread(&dwMagic, sizeof(u32), 1, file); - if (dwMagic != MAKEFOURCC('D', 'D', 'S', ' ')) - { - fclose(file); - return false; - } - // Read the surface description - fread(&ddsd, sizeof(DDS_HEADER), 1, file); - // Does texture have mipmaps? - m_bMipTexture = ddsd.dwMipMapCount > 0; - // Clear unwanted flags - // Can't do this!!! surface not re-created here - // ddsd.dwFlags &= (~DDSD_PITCH); - // ddsd.dwFlags &= (~DDSD_LINEARSIZE); - // Is it DXTC ? - // I sure hope pixelformat is valid! - DecodePixelFormat(m_strFormat, &ddsd.ddspf); - if (m_CompFormat == PF_DXT1 || m_CompFormat == PF_DXT2 || m_CompFormat == PF_DXT3 || m_CompFormat == PF_DXT4 || - m_CompFormat == PF_DXT5) - { - // TRACE("Yay, a recognized format!\n\n"); - } - else - { - // TRACE("Format is %s. Not loading!\n", m_strFormat ); - return false; - } - // TRACE("ddsd.dwLinearSize: %d\n", ddsd.dwLinearSize); - // TRACE("ddsd.dwHeight: %d\n", ddsd.dwHeight); - // TRACE("ddsd.dwWidth: %d\n", ddsd.dwWidth); - // TRACE("w * h %d\n", ddsd.dwWidth * ddsd.dwHeight); - // Store the return copy of this surfacedesc - m_DDSD = ddsd; - m_nHeight = ddsd.dwHeight; - m_nWidth = ddsd.dwWidth; - // Read only first mip level for now: - if (ddsd.dwHeaderFlags & DDSD_LINEARSIZE) - { - // TRACE("dwFlags has DDSD_LINEARSIZE\n"); - m_pCompBytes = (u8*)calloc(ddsd.dwPitchOrLinearSize, sizeof(u8)); - if (m_pCompBytes == NULL) - { - // TRACE("Can't allocate m_pCompBytes on file read!\n"); - return (false); - } - fread(m_pCompBytes, ddsd.dwPitchOrLinearSize, 1, file); - } - else - { - // TRACE("dwFlags file doesn't have linearsize set\n"); - u32 dwBytesPerRow = ddsd.dwWidth * ddsd.ddspf.dwRGBBitCount / 8; - m_pCompBytes = (u8*)calloc(ddsd.dwPitchOrLinearSize * ddsd.dwHeight, sizeof(u8)); - m_nCompSize = ddsd.dwPitchOrLinearSize * ddsd.dwHeight; - m_nCompLineSz = dwBytesPerRow; - if (m_pCompBytes == NULL) - { - // TRACE("Can't allocate m_pCompBytes on file read!\n"); - return false; - } - u8* pDest = m_pCompBytes; - for (u32 yp = 0; yp < ddsd.dwHeight; yp++) - { - fread(pDest, dwBytesPerRow, 1, file); - pDest += ddsd.dwPitchOrLinearSize; - } - } - // done reading file - fclose(file); - file = NULL; - return true; -} - -void Image_DXTC::AllocateDecompBytes() -{ - if (m_pDecompBytes != NULL) - { - free(m_pDecompBytes); - m_pDecompBytes = NULL; - } - // Allocate for 32 bit surface: - m_pDecompBytes = (u8*)calloc(m_DDSD.dwWidth * m_DDSD.dwHeight * 4, sizeof(u8)); - if (m_pDecompBytes == NULL) - { - // TRACE("Error allocating decompressed byte storage\n"); - } -} - -void Image_DXTC::Decompress() -{ - VERIFY(m_pCompBytes); - AllocateDecompBytes(); - VERIFY(m_pDecompBytes); // must already have allocated memory - switch (m_CompFormat) - { - case PF_DXT1: - // TRACE( "Decompressing image format: DXT1\n" ); - DecompressDXT1(); - break; - case PF_DXT2: - // TRACE( "Decompressing image format: DXT2\n" ); - DecompressDXT2(); - break; - case PF_DXT3: - // TRACE( "Decompressing image format: DXT3\n" ); - DecompressDXT3(); - break; - case PF_DXT4: - // TRACE( "Decompressing image format: DXT4\n" ); - DecompressDXT4(); - break; - case PF_DXT5: - // TRACE( "Decompressing image format: DXT5\n" ); - DecompressDXT5(); - break; - case PF_UNKNOWN: break; - } - //. swap R<->B channels - for (int y = 0; y < m_nHeight; y++) - { - for (int x = 0; x < m_nWidth; x++) - { - u8* ptr = m_pDecompBytes + (y * m_nWidth + x) * 4; - std::swap(ptr[0], ptr[2]); - } - } -} - -struct DXTColBlock -{ - u16 col0; - u16 col1; - // no bit fields - use bytes - u8 row[4]; -}; - -struct DXTAlphaBlockExplicit -{ - u16 row[4]; -}; - -struct DXTAlphaBlock3BitLinear -{ - u8 alpha0; - u8 alpha1; - u8 stuff[6]; -}; - -// use cast to struct instead of RGBA_MAKE as struct is much -struct Color8888 -{ - u8 r; // change the order of names to change the - u8 g; // order of the output ARGB or BGRA, etc... - u8 b; // Last one is MSB, 1st is LSB. - u8 a; -}; - -struct Color565 -{ - unsigned nBlue : 5; // order of names changes - unsigned nGreen : 6; // byte order of output to 32 bit - unsigned nRed : 5; -}; - -inline void GetColorBlockColors( -DXTColBlock* pBlock, Color8888* col_0, Color8888* col_1, Color8888* col_2, Color8888* col_3, u16& wrd) -{ - // There are 4 methods to use - see the Time_ functions. - // 1st = shift = does normal approach per byte for color comps - // 2nd = use freak variable bit field color565 for component extraction - // 3rd = use super-freak DWORD adds BEFORE shifting the color components - // This lets you do only 1 add per color instead of 3 BYTE adds and - // might be faster - // Call RunTimingSession() to run each of them & output result to txt file - // freak variable bit structure method - // normal math - // This method is fastest - Color565* pCol; - pCol = (Color565*)&pBlock->col0; - col_0->a = 0xff; - col_0->r = pCol->nRed; - col_0->r <<= 3; // shift to full precision - col_0->g = pCol->nGreen; - col_0->g <<= 2; - col_0->b = pCol->nBlue; - col_0->b <<= 3; - pCol = (Color565*)&pBlock->col1; - col_1->a = 0xff; - col_1->r = pCol->nRed; - col_1->r <<= 3; // shift to full precision - col_1->g = pCol->nGreen; - col_1->g <<= 2; - col_1->b = pCol->nBlue; - col_1->b <<= 3; - if (pBlock->col0 > pBlock->col1) - { - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - wrd = ((u16)col_0->r * 2 + (u16)col_1->r) / 3; - // no +1 for rounding - // as bits have been shifted to 888 - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g * 2 + (u16)col_1->g) / 3; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b * 2 + (u16)col_1->b) / 3; - col_2->b = (u8)wrd; - col_2->a = 0xff; - wrd = ((u16)col_0->r + (u16)col_1->r * 2) / 3; - col_3->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g * 2) / 3; - col_3->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b * 2) / 3; - col_3->b = (u8)wrd; - col_3->a = 0xff; - } - else - { - // Three-color block: derive the other color. - // 00 = color_0, 01 = color_1, 10 = color_2, - // 11 = transparent. - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - // explicit for each component, unlike some refrasts... - // //TRACE("block has alpha\n"); - wrd = ((u16)col_0->r + (u16)col_1->r) / 2; - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g) / 2; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b) / 2; - col_2->b = (u8)wrd; - col_2->a = 0xff; - col_3->r = 0x00; // random color to indicate alpha - col_3->g = 0xff; - col_3->b = 0xff; - col_3->a = 0x00; - } -} // Get color block colors (...) - -inline void DecodeColorBlock( -u32* pImPos, DXTColBlock* pColorBlock, int width, u32* col_0, u32* col_1, u32* col_2, u32* col_3) -{ - // width is width of image in pixels - u32 bits; - int r, n; - // bit masks = 00000011, 00001100, 00110000, 11000000 - const u32 masks[] = {3, 12, 3 << 4, 3 << 6}; - const int shift[] = {0, 2, 4, 6}; - // r steps through lines in y - for (r = 0; r < 4; r++, pImPos += width - 4) // no width*4 as u32 ptr inc will *4 - { - // width * 4 bytes per pixel per line - // each j dxtc row is 4 lines of pixels - // pImPos = (DWORD*)((DWORD)pBase + i*16 + (r+j*4) * m_nWidth * 4 ); - // n steps through pixels - for (n = 0; n < 4; n++) - { - bits = pColorBlock->row[r] & masks[n]; - bits >>= shift[n]; - switch (bits) - { - case 0: - *pImPos = *col_0; - pImPos++; // increment to next u32 - break; - case 1: - *pImPos = *col_1; - pImPos++; - break; - case 2: - *pImPos = *col_2; - pImPos++; - break; - case 3: - *pImPos = *col_3; - pImPos++; - break; - default: - // TRACE("Your logic is jacked! bits == 0x%x\n", bits ); - pImPos++; - break; - } - } - } -} - -inline void DecodeAlphaExplicit(u32* pImPos, DXTAlphaBlockExplicit* pAlphaBlock, int width, u32 alphazero) -{ - // alphazero is a bit mask that when & with the image color - // will zero the alpha bits, so if the image DWORDs are - // ARGB then alphazero will be 0x00ffffff or if - // RGBA then alphazero will be 0xffffff00 - // alphazero constructed automaticaly from field order of Color8888 structure - // decodes to 32 bit format only - u16 wrd; - Color8888 col; - col.r = col.g = col.b = 0; - // TRACE("\n"); - for (int row = 0; row < 4; row++, pImPos += width - 4) - { - // pImPow += pImPos += width-4 moves to next row down - wrd = pAlphaBlock->row[row]; - // //TRACE("0x%.8x\t\t", wrd); - for (int pix = 0; pix < 4; pix++) - { - // zero the alpha bits of image pixel - *pImPos &= alphazero; - col.a = wrd & 0x000f; // get only low 4 bits - // col.a <<= 4; // shift to full byte precision - // NOTE: with just a << 4 you'll never have alpha - // of 0xff, 0xf0 is max so pure shift doesn't quite - // cover full alpha range. - // It's much cheaper than divide & scale though. - // To correct for this, and get 0xff for max alpha, - // or the low bits back in after left shifting - col.a = col.a | (col.a << 4); // This allows max 4 bit alpha to be 0xff alpha - // in final image, and is crude approach to full - // range scale - *pImPos |= *(u32*)&col; // or the bits into the prev. nulled alpha - wrd >>= 4; // move next bits to lowest 4 - pImPos++; // move to next pixel in the row - } - } -} - -u8 gBits[4][4]; -u16 gAlphas[8]; -Color8888 gACol[4][4]; - -inline void DecodeAlpha3BitLinear(u32* pImPos, DXTAlphaBlock3BitLinear* pAlphaBlock, int width, u32 alphazero) -{ - gAlphas[0] = pAlphaBlock->alpha0; - gAlphas[1] = pAlphaBlock->alpha1; - // 8-alpha or 6-alpha block? - if (gAlphas[0] > gAlphas[1]) - { - // 8-alpha block: derive the other 6 alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - gAlphas[2] = (6 * gAlphas[0] + gAlphas[1]) / 7; // bit code 010 - gAlphas[3] = (5 * gAlphas[0] + 2 * gAlphas[1]) / 7; // Bit code 011 - gAlphas[4] = (4 * gAlphas[0] + 3 * gAlphas[1]) / 7; // Bit code 100 - gAlphas[5] = (3 * gAlphas[0] + 4 * gAlphas[1]) / 7; // Bit code 101 - gAlphas[6] = (2 * gAlphas[0] + 5 * gAlphas[1]) / 7; // Bit code 110 - gAlphas[7] = (gAlphas[0] + 6 * gAlphas[1]) / 7; // Bit code 111 - } - else - { - // 6-alpha block: derive the other alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - gAlphas[2] = (4 * gAlphas[0] + gAlphas[1]) / 5; // Bit code 010 - gAlphas[3] = (3 * gAlphas[0] + 2 * gAlphas[1]) / 5; // Bit code 011 - gAlphas[4] = (2 * gAlphas[0] + 3 * gAlphas[1]) / 5; // Bit code 100 - gAlphas[5] = (gAlphas[0] + 4 * gAlphas[1]) / 5; // Bit code 101 - gAlphas[6] = 0; // Bit code 110 - gAlphas[7] = 255; // Bit code 111 - } - // Decode 3-bit fields into array of 16 BYTES with same value - // first two rows of 4 pixels each: - // pRows = (Alpha3BitRows*) & ( pAlphaBlock->stuff[0] ); - const u32 mask = 0x00000007; // bits = 00 00 01 11 - u32 bits = *(u32*)&pAlphaBlock->stuff[0]; - gBits[0][0] = (u8)(bits & mask); - bits >>= 3; - gBits[0][1] = (u8)(bits & mask); - bits >>= 3; - gBits[0][2] = (u8)(bits & mask); - bits >>= 3; - gBits[0][3] = (u8)(bits & mask); - bits >>= 3; - gBits[1][0] = (u8)(bits & mask); - bits >>= 3; - gBits[1][1] = (u8)(bits & mask); - bits >>= 3; - gBits[1][2] = (u8)(bits & mask); - bits >>= 3; - gBits[1][3] = (u8)(bits & mask); - // now for last two rows: - bits = *(u32*)&pAlphaBlock->stuff[3]; // last 3 bytes - gBits[2][0] = (u8)(bits & mask); - bits >>= 3; - gBits[2][1] = (u8)(bits & mask); - bits >>= 3; - gBits[2][2] = (u8)(bits & mask); - bits >>= 3; - gBits[2][3] = (u8)(bits & mask); - bits >>= 3; - gBits[3][0] = (u8)(bits & mask); - bits >>= 3; - gBits[3][1] = (u8)(bits & mask); - bits >>= 3; - gBits[3][2] = (u8)(bits & mask); - bits >>= 3; - gBits[3][3] = (u8)(bits & mask); - // decode the codes into alpha values - for (int row = 0; row < 4; row++) - { - for (int pix = 0; pix < 4; pix++) - { - gACol[row][pix].a = (u8)gAlphas[gBits[row][pix]]; - VERIFY(gACol[row][pix].r == 0); - VERIFY(gACol[row][pix].g == 0); - VERIFY(gACol[row][pix].b == 0); - } - } - // Write out alpha values to the image bits - for (int row = 0; row < 4; row++, pImPos += width - 4) - { - // pImPow += pImPos += width-4 moves to next row down - for (int pix = 0; pix < 4; pix++) - { - // zero the alpha bits of image pixel - *pImPos &= alphazero; - // or the bits into the prev. nulled alpha - *pImPos |= *((u32*)&(gACol[row][pix])); - pImPos++; - } - } -} - -void Image_DXTC::DecompressDXT1() -{ - // This was hacked up pretty quick & slopily - // decompresses to 32 bit format 0xARGB - int xblocks = m_DDSD.dwWidth / 4; - int yblocks = m_DDSD.dwHeight / 4; - u32* pBase = (u32*)m_pDecompBytes; - u32* pImPos = (u32*)pBase; // pos in decompressed data - u16* pPos = (u16*)m_pCompBytes; // pos in compressed data - DXTColBlock* pBlock; - Color8888 col_0, col_1, col_2, col_3; - u16 wrd; - // TRACE("blocks: x: %d y: %d\n", xblocks, yblocks ); - for (int j = 0; j < yblocks; j++) - { - // 8 bytes per block - pBlock = (DXTColBlock*)((std::uintptr_t)m_pCompBytes + j * xblocks * 8); - for (int i = 0; i < xblocks; i++, pBlock++) - { - // inline func: - GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); - // now decode the color block into the bitmap bits - // inline func: - pImPos = (u32*)((std::uintptr_t)pBase + i * 16 + (j * 4) * m_nWidth * 4); - DecodeColorBlock(pImPos, pBlock, m_nWidth, (u32*)&col_0, (u32*)&col_1, (u32*)&col_2, (u32*)&col_3); - if (false) // Set to RGB test pattern - { - pImPos = (u32*)((std::uintptr_t)pBase + i * 4 + j * m_nWidth * 4); - *pImPos = ((i * 4) << 16) | ((j * 4) << 8) | ((63 - i) * 4); - // checkerboard of only col_0 and col_1 basis colors: - pImPos = (u32*)((std::uintptr_t)pBase + i * 8 + j * m_nWidth * 8); - *pImPos = *((u32*)&col_0); - pImPos += 1 + m_nWidth; - *pImPos = *((u32*)&col_1); - } - } - } -} - -void Image_DXTC::DecompressDXT2() -{ - // Can do color & alpha same as dxt3, but color is pre-multiplied - // so the result will be wrong unless corrected. - // DecompressDXT3(); - VERIFY(false); -} - -void Image_DXTC::DecompressDXT3() -{ - int xblocks = m_DDSD.dwWidth / 4; - int yblocks = m_DDSD.dwHeight / 4; - u32* pBase = (u32*)m_pDecompBytes; - u32* pImPos = (u32*)pBase; // pos in decompressed data - u16* pPos = (u16*)m_pCompBytes; // pos in compressed data - DXTColBlock* pBlock; - DXTAlphaBlockExplicit* pAlphaBlock; - Color8888 col_0, col_1, col_2, col_3; - u16 wrd; - // fill alphazero with appropriate value to zero out alpha when - // alphazero is ANDed with the image color 32 bit DWORD: - col_0.a = 0; - col_0.r = col_0.g = col_0.b = 0xff; - u32 alphazero = *((u32*)&col_0); - // //TRACE("blocks: x: %d y: %d\n", xblocks, yblocks ); - for (int j = 0; j < yblocks; j++) - { - // 8 bytes per block - // 1 block for alpha, 1 block for color - pBlock = (DXTColBlock*)((std::uintptr_t)m_pCompBytes + j * xblocks * 16); - for (int i = 0; i < xblocks; i++, pBlock++) - { - // inline - // Get alpha block - pAlphaBlock = (DXTAlphaBlockExplicit*)pBlock; - // inline func: - // Get color block & colors - pBlock++; - GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); - // Decode the color block into the bitmap bits inline func: - pImPos = (u32*)((std::uintptr_t)pBase + i * 16 + (j * 4) * m_nWidth * 4); - DecodeColorBlock(pImPos, pBlock, m_nWidth, (u32*)&col_0, (u32*)&col_1, (u32*)&col_2, (u32*)&col_3); - // Overwrite the previous alpha bits with the alpha block - // info - // inline func: - DecodeAlphaExplicit(pImPos, pAlphaBlock, m_nWidth, alphazero); - } - } -} - -void Image_DXTC::DecompressDXT4() -{ - // Can do color & alpha same as dxt5, but color is pre-multiplied - // so the result will be wrong unless corrected. - // DecompressDXT5(); - VERIFY(false); -} - -void Image_DXTC::DecompressDXT5() -{ - int xblocks = m_DDSD.dwWidth / 4; - int yblocks = m_DDSD.dwHeight / 4; - u32* pBase = (u32*)m_pDecompBytes; - u32* pImPos = (u32*)pBase; // pos in decompressed data - u16* pPos = (u16*)m_pCompBytes; // pos in compressed data - Color8888 col_0, col_1, col_2, col_3; - // fill alphazero with appropriate value to zero out alpha when - // alphazero is ANDed with the image color 32 bit u32: - col_0.a = 0; - col_0.r = col_0.g = col_0.b = 0xff; - u32 alphazero = *(u32*)&col_0; - u16 wrd; - // //TRACE("blocks: x: %d y: %d\n", xblocks, yblocks ); - for (int j = 0; j < yblocks; j++) - { - // 8 bytes per block - // 1 block for alpha, 1 block for color - DXTColBlock* pBlock = (DXTColBlock*)((std::uintptr_t)m_pCompBytes + j * xblocks * 16); - for (int i = 0; i < xblocks; i++, pBlock++) - { - // inline - // Get alpha block - DXTAlphaBlock3BitLinear* pAlphaBlock = (DXTAlphaBlock3BitLinear*)pBlock; - // inline func: - // Get color block & colors - pBlock++; - // //TRACE("pBlock: 0x%.8x\n", pBlock ); - GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); - // Decode the color block into the bitmap bits inline func: - pImPos = (u32*)((std::uintptr_t)pBase + i * 16 + (j * 4) * m_nWidth * 4); - DecodeColorBlock(pImPos, pBlock, m_nWidth, (u32*)&col_0, (u32*)&col_1, (u32*)&col_2, (u32*)&col_3); - // Overwrite the previous alpha bits with the alpha block info - DecodeAlpha3BitLinear(pImPos, pAlphaBlock, m_nWidth, alphazero); - } - } -} // dxt5 - -//----------------------------------------------------------------------------- -// Name: PixelFormatToString() -// Desc: Creates a string describing a pixel format. -// adapted from microsoft mssdk D3DIM Compress example -// PixelFormatToString() -//----------------------------------------------------------------------------- -void Image_DXTC::DecodePixelFormat(char* strPixelFormat, DDS_PIXELFORMAT* pddpf) -{ - switch (pddpf->dwFourCC) - { - case 0: - // This dds texture isn't compressed so write out ARGB format - sprintf(strPixelFormat, "ARGB-%d%d%d%d%s", GetNumberOfBits(pddpf->dwRGBAlphaBitMask), - GetNumberOfBits(pddpf->dwRBitMask), GetNumberOfBits(pddpf->dwGBitMask), GetNumberOfBits(pddpf->dwBBitMask), - pddpf->dwFlags & DDPF_ALPHAPREMULT ? "-premul" : ""); - m_CompFormat = PF_ARGB; - break; - case MAKEFOURCC('D', 'X', 'T', '1'): - strcpy(strPixelFormat, "DXT1"); - m_CompFormat = PF_DXT1; - break; - case MAKEFOURCC('D', 'X', 'T', '2'): - strcpy(strPixelFormat, "DXT2"); - m_CompFormat = PF_DXT2; - break; - case MAKEFOURCC('D', 'X', 'T', '3'): - strcpy(strPixelFormat, "DXT3"); - m_CompFormat = PF_DXT3; - break; - case MAKEFOURCC('D', 'X', 'T', '4'): - strcpy(strPixelFormat, "DXT4"); - m_CompFormat = PF_DXT4; - break; - case MAKEFOURCC('D', 'X', 'T', '5'): - strcpy(strPixelFormat, "DXT5"); - m_CompFormat = PF_DXT5; - break; - default: - strcpy(strPixelFormat, "Format Unknown"); - m_CompFormat = PF_UNKNOWN; - break; - } -} - -inline void GetColorBlockColors_m2( -DXTColBlock* pBlock, Color8888* col_0, Color8888* col_1, Color8888* col_2, Color8888* col_3, u16& wrd) -{ - // method 2 - // freak variable bit structure method - // normal math - Color565* pCol; - pCol = (Color565*)&pBlock->col0; - col_0->a = 0xff; - col_0->r = pCol->nRed; - col_0->r <<= 3; // shift to full precision - col_0->g = pCol->nGreen; - col_0->g <<= 2; - col_0->b = pCol->nBlue; - col_0->b <<= 3; - pCol = (Color565*)&pBlock->col1; - col_1->a = 0xff; - col_1->r = pCol->nRed; - col_1->r <<= 3; // shift to full precision - col_1->g = pCol->nGreen; - col_1->g <<= 2; - col_1->b = pCol->nBlue; - col_1->b <<= 3; - if (pBlock->col0 > pBlock->col1) - { - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - wrd = ((u16)col_0->r * 2 + (u16)col_1->r) / 3; - // no +1 for rounding - // as bits have been shifted to 888 - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g * 2 + (u16)col_1->g) / 3; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b * 2 + (u16)col_1->b) / 3; - col_2->b = (u8)wrd; - col_2->a = 0xff; - wrd = ((u16)col_0->r + (u16)col_1->r * 2) / 3; - col_3->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g * 2) / 3; - col_3->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b * 2) / 3; - col_3->b = (u8)wrd; - col_3->a = 0xff; - } - else - { - // Three-color block: derive the other color. - // 00 = color_0, 01 = color_1, 10 = color_2, - // 11 = transparent. - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - // explicit for each component, unlike some refrasts... - // //TRACE("block has alpha\n"); - wrd = ((u16)col_0->r + (u16)col_1->r) / 2; - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g) / 2; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b) / 2; - col_2->b = (u8)wrd; - col_2->a = 0xff; - col_3->r = 0x00; // random color to indicate alpha - col_3->g = 0xff; - col_3->b = 0xff; - col_3->a = 0x00; - } -} - -inline void GetColorBlockColors_m3( -DXTColBlock* pBlock, Color8888* col_0, Color8888* col_1, Color8888* col_2, Color8888* col_3, u16& wrd) -{ - // method 3 - // super-freak variable bit structure with - // Cool Math Trick (tm) - // Do 2/3 1/3 math BEFORE bit shift on the whole DWORD - // as the fields will NEVER carry into the next - // or overflow!! =) - Color565* pCol; - pCol = (Color565*)&pBlock->col0; - col_0->a = 0x00; // must set to 0 to avoid overflow in DWORD add - col_0->r = pCol->nRed; - col_0->g = pCol->nGreen; - col_0->b = pCol->nBlue; - pCol = (Color565*)&pBlock->col1; - col_1->a = 0x00; - col_1->r = pCol->nRed; - col_1->g = pCol->nGreen; - col_1->b = pCol->nBlue; - if (pBlock->col0 > pBlock->col1) - { - *(u32*)col_2 = *(u32*)col_0 * 2 + *(u32*)col_1; - *(u32*)col_3 = *(u32*)col_0 + *(u32*)col_1 * 2; - // now shift to appropriate precision & divide by 3. - col_2->r = ((u16)col_2->r << 3) / (u16)3; - col_2->g = ((u16)col_2->g << 2) / (u16)3; - col_2->b = ((u16)col_2->b << 3) / (u16)3; - col_3->r = ((u16)col_3->r << 3) / (u16)3; - col_3->g = ((u16)col_3->g << 2) / (u16)3; - col_3->b = ((u16)col_3->b << 3) / (u16)3; - col_0->a = 0xff; // now set appropriate alpha - col_1->a = 0xff; - col_2->a = 0xff; - col_3->a = 0xff; - } - else - { - *(u32*)col_2 = *(u32*)col_0 + *(u32*)col_1; - // now shift to appropriate precision & divide by 2. - // << 3 ) / 2 == << 2 - // << 2 ) / 2 == << 1 - col_2->r = ((u16)col_2->r << 2); - col_2->g = ((u16)col_2->g << 1); - col_2->b = ((u16)col_2->b << 2); - col_2->a = 0xff; - col_3->a = 0x00; - col_3->r = 0x00; // random color to indicate alpha - col_3->g = 0xff; - col_3->b = 0xff; - } - // now shift orig color components - col_0->r <<= 3; - col_0->g <<= 2; - col_0->b <<= 3; - col_1->r <<= 3; - col_1->g <<= 2; - col_1->b <<= 3; -} - -inline void GetColorBlockColors_m4( -DXTColBlock* pBlock, Color8888* col_0, Color8888* col_1, Color8888* col_2, Color8888* col_3, u16& wrd) -{ - // m1 color extraction from 5-6-5 - // m3 color math on DWORD before bit shift to full precision - wrd = pBlock->col0; - col_0->a = 0x00; // must set to 0 to avoid possible overflow & carry to next field in DWORD add - // extract r,g,b bits - col_0->b = (unsigned char)wrd & 0x1f; // 0x1f = 0001 1111 to mask out upper 3 bits - wrd >>= 5; - col_0->g = (unsigned char)wrd & 0x3f; // 0x3f = 0011 1111 to mask out upper 2 bits - wrd >>= 6; - col_0->r = (unsigned char)wrd & 0x1f; - // same for col # 2: - wrd = pBlock->col1; - col_1->a = 0x00; // must set to 0 to avoid possible overflow in DWORD add - // extract r,g,b bits - col_1->b = (unsigned char)wrd & 0x1f; - wrd >>= 5; - col_1->g = (unsigned char)wrd & 0x3f; - wrd >>= 6; - col_1->r = (unsigned char)wrd & 0x1f; - if (pBlock->col0 > pBlock->col1) - { - *(u32*)col_2 = (*(u32*)col_0 * 2 + *(u32*)col_1); - *(u32*)col_3 = (*(u32*)col_0 + *(u32*)col_1 * 2); - // shift to appropriate precision & divide by 3. - col_2->r = ((u16)col_2->r << 3) / (u16)3; - col_2->g = ((u16)col_2->g << 2) / (u16)3; - col_2->b = ((u16)col_2->b << 3) / (u16)3; - col_3->r = ((u16)col_3->r << 3) / (u16)3; - col_3->g = ((u16)col_3->g << 2) / (u16)3; - col_3->b = ((u16)col_3->b << 3) / (u16)3; - col_0->a = 0xff; // set appropriate alpha - col_1->a = 0xff; - col_2->a = 0xff; - col_3->a = 0xff; - } - else - { - *(u32*)col_2 = *(u32*)col_0 + *(u32*)col_1; - // shift to appropriate precision & divide by 2. - // << 3 ) / 2 == << 2 - // << 2 ) / 2 == << 1 - col_2->r = ((u16)col_2->r << 2); - col_2->g = ((u16)col_2->g << 1); - col_2->b = ((u16)col_2->b << 2); - col_2->a = 0xff; - col_3->a = 0x00; - col_3->r = 0x00; // random color to indicate alpha - col_3->g = 0xff; - col_3->b = 0xff; - } - // shift orig color components to full precision - col_0->r <<= 3; - col_0->g <<= 2; - col_0->b <<= 3; - col_1->r <<= 3; - col_1->g <<= 2; - col_1->b <<= 3; -} - -inline void GetColorBlockColors_m1( -DXTColBlock* pBlock, Color8888* col_0, Color8888* col_1, Color8888* col_2, Color8888* col_3, u16& wrd) -{ - // Method 1: - // Shifty method - wrd = pBlock->col0; - col_0->a = 0xff; - // extract r,g,b bits - col_0->b = (unsigned char)wrd; - col_0->b <<= 3; // shift to full precision - wrd >>= 5; - col_0->g = (unsigned char)wrd; - col_0->g <<= 2; // shift to full precision - wrd >>= 6; - col_0->r = (unsigned char)wrd; - col_0->r <<= 3; // shift to full precision - // same for col # 2: - wrd = pBlock->col1; - col_1->a = 0xff; - // extract r,g,b bits - col_1->b = (unsigned char)wrd; - col_1->b <<= 3; // shift to full precision - wrd >>= 5; - col_1->g = (unsigned char)wrd; - col_1->g <<= 2; // shift to full precision - wrd >>= 6; - col_1->r = (unsigned char)wrd; - col_1->r <<= 3; // shift to full precision - // use this for all but the super-freak math method - if (pBlock->col0 > pBlock->col1) - { - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - wrd = ((u16)col_0->r * 2 + (u16)col_1->r) / 3; - // no +1 for rounding - // as bits have been shifted to 888 - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g * 2 + (u16)col_1->g) / 3; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b * 2 + (u16)col_1->b) / 3; - col_2->b = (u8)wrd; - col_2->a = 0xff; - wrd = ((u16)col_0->r + (u16)col_1->r * 2) / 3; - col_3->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g * 2) / 3; - col_3->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b * 2) / 3; - col_3->b = (u8)wrd; - col_3->a = 0xff; - } - else - { - // Three-color block: derive the other color. - // 00 = color_0, 01 = color_1, 10 = color_2, - // 11 = transparent. - // These two bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - // explicit for each component, unlike some refrasts... - // //TRACE("block has alpha\n"); - wrd = ((u16)col_0->r + (u16)col_1->r) / 2; - col_2->r = (u8)wrd; - wrd = ((u16)col_0->g + (u16)col_1->g) / 2; - col_2->g = (u8)wrd; - wrd = ((u16)col_0->b + (u16)col_1->b) / 2; - col_2->b = (u8)wrd; - col_2->a = 0xff; - col_3->r = 0x00; // random color to indicate alpha - col_3->g = 0xff; - col_3->b = 0xff; - col_3->a = 0x00; - } -} // Get color block colors (...) - -//----------------------------------------------------------------------------- -// Name: GetNumberOfBits() -// Desc: Returns the number of bits set in a DWORD mask -// from microsoft mssdk d3dim sample "Compress" -//----------------------------------------------------------------------------- -u16 GetNumberOfBits(u32 dwMask) -{ - u16 wBits = 0; - while (dwMask) - { - dwMask &= dwMask - 1; - wBits++; - } - return wBits; -} diff --git a/src/utils/xrDXT/Image_DXTC.h b/src/utils/xrDXT/Image_DXTC.h deleted file mode 100644 index 84321c7d617..00000000000 --- a/src/utils/xrDXT/Image_DXTC.h +++ /dev/null @@ -1,73 +0,0 @@ -/*********************************************************************NVMH2**** -Path: C:\Dev\devrel\Nv_sdk_4\Direct3D\Decompress_DXTC -File: Image_DXTC.h - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: -A class to load and decompress DXT textures to 32-bit raw image data format. -.RAW output files can be loaded into photoshop by specifying the resolution -and 4 color channels of 8-bit, interleaved. - -A few approaches to block decompression are in place and a simple code timing -function is called. Output of timing test is saved to a local .txt file. - -******************************************************************************/ - -#pragma once - -#include -#include "dds.h" - -// struct TimingInfo; // defined in Image_DXTC.cpp - -enum PixFormat -{ - PF_ARGB, - PF_DXT1, - PF_DXT2, - PF_DXT3, - PF_DXT4, - PF_DXT5, - PF_UNKNOWN -}; - -class Image_DXTC -{ - u8* m_pCompBytes; // compressed image bytes - u8* m_pDecompBytes; - int m_nCompSize; - int m_nCompLineSz; - string256 m_strFormat; - PixFormat m_CompFormat; - DDS_HEADER m_DDSD; // read from dds file - bool m_bMipTexture; // texture has mipmaps? - int m_nWidth; // in pixels of uncompressed image - int m_nHeight; - -private: - void DecompressDXT1(); - void DecompressDXT2(); - void DecompressDXT3(); - void DecompressDXT4(); - void DecompressDXT5(); - void DecodePixelFormat(pstr strPixelFormat, DDS_PIXELFORMAT* pddpf); - void AllocateDecompBytes(); - -public: - Image_DXTC(); - virtual ~Image_DXTC(); - - bool LoadFromFile(LPCSTR filename); // true if success - void Decompress(); - void SaveAsRaw(); // save decompressed bits - u8* GetCompDataPointer() { return m_pCompBytes; }; - u8* GetDecompDataPointer() { return m_pDecompBytes; }; - int Width() { return m_nWidth; } - int Height() { return m_nHeight; } - bool MipTexture() { return m_bMipTexture; } -}; diff --git a/src/utils/xrDXT/NVI_Convolution.cpp b/src/utils/xrDXT/NVI_Convolution.cpp deleted file mode 100644 index 1ce7a9320c9..00000000000 --- a/src/utils/xrDXT/NVI_Convolution.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/*********************************************************************NVMH2**** -Path: C:\Dev\devrel\Nv_sdk_4\CommonSrc\nvImageLib -File: NVI_Convolution.cpp - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - -******************************************************************************/ -#include "stdafx.h" - -#include "NVI_Convolution.h" - -using namespace xray_nvi; - -ConvolutionKernel::ConvolutionKernel() -{ - m_pElements = NULL; - m_nNumElements = 0; -} - -ConvolutionKernel::~ConvolutionKernel() { Free(); } -ConvolutionKernel& ConvolutionKernel::operator=(const ConvolutionKernel& src) -{ - Initialize(src.m_nNumElements); - for (int n = 0; n < src.m_nNumElements; n++) - { - m_pElements[n] = src.m_pElements[n]; - } - return *this; -} - -HRESULT ConvolutionKernel::Initialize(int numElements) -{ - Free(); - m_pElements = new ConvolutionKernelElement[numElements]; - assert(m_pElements != NULL); - m_nNumElements = numElements; - return S_OK; -} - -HRESULT ConvolutionKernel::Free() -{ - if (m_pElements != NULL) - { - delete[] m_pElements; - m_pElements = NULL; - } - - m_nNumElements = 0; - - return (S_OK); -} - -void ConvolutionKernel::SetElements(int numElements, ConvolutionKernelElement* pElements) -{ - assert(pElements != NULL); - if (numElements != m_nNumElements) - { - HRESULT hr = Initialize(numElements); - ASSERT_IF_FAILED(hr); - } - for (int i = 0; i < m_nNumElements; i++) - { - m_pElements[i].x_offset = pElements[i].x_offset; - m_pElements[i].y_offset = pElements[i].y_offset; - m_pElements[i].weight = pElements[i].weight; - } -} - -//=============================================================== -// Function: ConvolutionKernel::GetKernelExtents -// Description: Querries the kernel elements & finds out what area they -// extend over. -// Parameters: Pointers to values to be written -// Returns: Return values written to pointer addresses -//=============================================================== -void ConvolutionKernel::GetKernelExtents(int* xlow, int* xhigh, int* ylow, int* yhigh) -{ - // querries the kernel elements & finds out what area they - // extend over. - // Return values written to pointer addresses - //. ASSERT_MSG( m_pElements, "Initialize the m_pElements pointer!!\n"); - //. ASSERT_MSG( m_nNumElements > 0, "Kernel has no elements!\n"); - //. ASSERT_MSG( ((xlow!=NULL)&&(ylow!=NULL)&&(xhigh!=NULL)&&(yhigh!=NULL)), "Input pointer is null!\n"); - *xlow = *xhigh = m_pElements[0].x_offset; - *ylow = *yhigh = m_pElements[0].y_offset; - for (int i = 1; i < m_nNumElements; i++) - { - if (m_pElements[i].x_offset < *xlow) - *xlow = m_pElements[i].x_offset; - if (m_pElements[i].x_offset > *xhigh) - *xhigh = m_pElements[i].x_offset; - if (m_pElements[i].y_offset < *ylow) - *ylow = m_pElements[i].y_offset; - if (m_pElements[i].y_offset > *yhigh) - *yhigh = m_pElements[i].y_offset; - } -} - -Convolver::Convolver() : m_BorderedImage() -{ - m_hSrcImage = NULL; - m_pKernels = NULL; - m_nNumKernels = NULL; -} - -Convolver::~Convolver() { Free(); } -HRESULT Convolver::Free() -{ - SAFE_ARRAY_DELETE(m_pKernels); - m_BorderedImage.Free(); - m_hSrcImage = NULL; - m_pKernels = NULL; - m_nNumKernels = NULL; - return S_OK; -} - -HRESULT Convolver::Initialize(NVI_Image** hSrcImage, const ConvolutionKernel* pKernels, int numKernels, bool wrap) -{ - assert(hSrcImage != NULL); - assert(*hSrcImage != NULL); - assert(pKernels != NULL); - assert(numKernels > 0); - m_hSrcImage = hSrcImage; - m_nNumKernels = numKernels; - m_pKernels = new ConvolutionKernel[m_nNumKernels]; - assert(m_pKernels != NULL); - RECT maxKernSize = {0}; - for (int n = 0; n < m_nNumKernels; n++) - { - m_pKernels[n] = pKernels[n]; - int xlow, xhigh, ylow, yhigh; - m_pKernels[n].GetKernelExtents(&xlow, &xhigh, &ylow, &yhigh); - if (xlow < maxKernSize.left) - maxKernSize.left = xlow; - if (ylow < maxKernSize.bottom) - maxKernSize.bottom = ylow; - if (xhigh > maxKernSize.right) - maxKernSize.right = xhigh; - if (yhigh > maxKernSize.top) - maxKernSize.top = yhigh; - } - // Initialize allocated the bordered image & copies from source - m_BorderedImage.Initialize(hSrcImage, &maxKernSize, wrap); - return S_OK; -} - -void Convolver::Convolve_Alpha_At(int i, int j, float* results, int num_results) -{ - assert(num_results == m_nNumKernels); - assert(m_BorderedImage.m_pArray != NULL); - float byte_to_float = 1.0f / 255.0f; - for (int nkern = 0; nkern < m_nNumKernels; nkern++) - { - float result = 0; - for (int n = 0; n < m_pKernels[nkern].m_nNumElements; n++) - { - // extract alpha - u32 color; - m_BorderedImage.GetPixel( - &color, i + m_pKernels[nkern].m_pElements[n].x_offset, j + m_pKernels[nkern].m_pElements[n].y_offset); - // byte_to_float takes 0,255 to 0,1 - float height = (float)(color >> 24) * byte_to_float; - height *= m_pKernels[nkern].m_pElements[n].weight; - result += height; - } - results[nkern] = result; - } -} diff --git a/src/utils/xrDXT/NVI_Convolution.h b/src/utils/xrDXT/NVI_Convolution.h deleted file mode 100644 index 6f30e4093d7..00000000000 --- a/src/utils/xrDXT/NVI_Convolution.h +++ /dev/null @@ -1,68 +0,0 @@ -/*********************************************************************NVMH2**** -Path: C:\Dev\devrel\Nv_sdk_4\CommonSrc\nvImageLib -File: NVI_Convolution.h - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - -******************************************************************************/ - -#ifndef __NVIMAGELIB_CONVOLUTION_H -#define __NVIMAGELIB_CONVOLUTION_H - -#include "NVI_Image.h" - -namespace xray_nvi -{ -struct ConvolutionKernelElement -{ - int x_offset; // Coordinates of sample point - int y_offset; // relative to center - float weight; // Weight to multiply sample point by -}; - -// Kernel with arbitrary sample placement - -// Doesn't have to be square or evenly distributed -class ConvolutionKernel -{ -public: - ConvolutionKernelElement* m_pElements; - int m_nNumElements; - ConvolutionKernel(); - ~ConvolutionKernel(); - HRESULT Initialize(int numElements); - HRESULT Free(); - void SetElements(int numElements, ConvolutionKernelElement* pElements); - // Find extent (rectangle) over which the kernel samples - // Values are the offset from the (0,0) element - void GetKernelExtents(int* xlow, int* xhigh, int* ylow, int* yhigh); - ConvolutionKernel& operator=(const ConvolutionKernel& src); -}; - -// A class to drive convolutions. -// Currently only supports A8R8G8B8 inputs -class Convolver -{ -private: - NVI_Image** m_hSrcImage; - NVI_ImageBordered m_BorderedImage; - ConvolutionKernel* m_pKernels; - int m_nNumKernels; - -public: - Convolver(); - ~Convolver(); - HRESULT Initialize(NVI_Image** pSrcImage, const ConvolutionKernel* pKernels, int numKernels, bool wrap); - HRESULT Free(); - // Coords in source image - // numResults must equal numKernels set on Initialize(); - void Convolve_Alpha_At(int i, int j, float* results, int numResults); -}; -}; - -#endif // __NVIMAGELIB_CONVOLUTION_H diff --git a/src/utils/xrDXT/NVI_Image.cpp b/src/utils/xrDXT/NVI_Image.cpp deleted file mode 100644 index 16fab824c89..00000000000 --- a/src/utils/xrDXT/NVI_Image.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/*********************************************************************NVMH2**** -Path: D:\Dev\devrel\Nv_sdk_4\CommonSrc\nvImageLib -File: NVI_Image.cpp - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: -General image data classes - -class NVI_Image -class NVI_ImageBordered - -******************************************************************************/ - -#include "stdafx.h" - -#include "NVI_Image.h" -#include // for UINT_MAX - -using namespace xray_nvi; - -NVI_Image::NVI_Image() -{ - m_pArray = NULL; - m_Format = IMAGE_NOT_INITIALIZED; - m_nSizeX = 0; - m_nSizeY = 0; -} - -NVI_Image::~NVI_Image() { Free(); } -HRESULT NVI_Image::Free() -{ - SAFE_ARRAY_DELETE(m_pArray); - m_pArray = NULL; - m_Format = IMAGE_NOT_INITIALIZED; - m_nSizeX = 0; - m_nSizeY = 0; - return S_OK; -} - -HRESULT NVI_Image::Initialize(int width, int height, NVI_PIXEL_FORMAT fmt) -{ - NVI_Image::Free(); - m_Format = fmt; - m_nSizeX = width; - m_nSizeY = height; - int bytes_per_pixel = GetBytesPerPixel(); - m_pArray = new u8[width * height * bytes_per_pixel]; - VERIFY(m_pArray); - return S_OK; -} - -HRESULT NVI_Image::Initialize(int width, int height, NVI_PIXEL_FORMAT fmt, u8* data) -{ - NVI_Image::Initialize(width, height, fmt); - int bpp = GetBytesPerPixel(); - CopyMemory(m_pArray, data, width * height * bpp); - return S_OK; -} - -u32 NVI_Image::GetNumPixels() { return GetHeight() * GetWidth(); } -u32 NVI_Image::GetBytesPerPixel() -{ - switch (m_Format) - { - case NVI_A8: return 1; break; - case NVI_A8_R8_G8_B8: return 4; break; - case NVI_A1_R5_G5_B5: - case NVI_R5_G6_B5: - case NVI_A16: return 2; break; - case NVI_R16_G16_B16_A16: return 8; break; - } - //. FDebug("Unrecognized format! %d\n", m_Format ); - assert(false); - return 0; -} - -u32 NVI_Image::GetImageNumBytes() -{ -#ifdef _DEBUG - float numbytes = (float)m_nSizeX * (float)m_nSizeY * (float)GetBytesPerPixel(); - assert(numbytes < (float)UINT_MAX); -#endif - return m_nSizeX * m_nSizeY * GetBytesPerPixel(); -} - -bool NVI_Image::IsDataValid() -{ - bool res = m_pArray != NULL; - res = res && m_nSizeX > 0; - res = res && m_nSizeY > 0; - return res; -} - -void NVI_Image::FlipTopToBottom() -{ - assert(IsDataValid()); - u32 bpp = GetBytesPerPixel(); - assert(bpp >= 1); - u32 width = GetWidth(); - u8* swap = new u8[width * bpp]; - assert(swap != NULL); - u32 height = GetHeight(); - for (u32 row = 0; row < GetHeight() / 2; row++) - { - u8* end_row = &(m_pArray[bpp * width * (height - row - 1)]); - u8* start_row = &(m_pArray[bpp * width * row]); - // copy row toward end of image into temporary swap buffer - memcpy(swap, end_row, bpp * width); - // copy row at beginning to row at end - memcpy(end_row, start_row, bpp * width); - // copy old bytes from row at end (in swap) to row at beginning - memcpy(start_row, swap, bpp * width); - } - SAFE_ARRAY_DELETE(swap); -} - -void NVI_Image::AverageRGBToAlpha() -{ - // write each pixels' avg r,g,b to alpha - assert(IsDataValid()); - // Only implemented for a8r8g8b8 images so far - assert(GetFormat() == NVI_A8_R8_G8_B8); - int cnt = m_nSizeY * m_nSizeX; - // a8r8g8b8 implementation - for (int k = 0; k < cnt; k++) - { - u32 pix; - GetPixel_ARGB8(&pix, k); - float r = (float)((pix & 0x00FF0000) >> 16); - float g = (float)((pix & 0x0000FF00) >> 8); - float b = (float)((pix & 0x000000FF)); - r = (r + g + b) / 3.0f; - pix &= 0x00FFFFFF; - pix |= (u32)r << 24; - SetPixel_ARGB8(k, pix); - } -} - -void NVI_Image::ABGR8_To_ARGB8() -{ - // swaps RGB for all pixels - assert(IsDataValid()); - assert(GetBytesPerPixel() == 4); - u32 hxw = GetNumPixels(); - for (u32 i = 0; i < hxw; i++) - { - u32 col; - GetPixel_ARGB8(&col, i); - u32 a = (col >> 24) & 0x000000FF; - u32 b = (col >> 16) & 0x000000FF; - u32 g = (col >> 8) & 0x000000FF; - u32 r = (col >> 0) & 0x000000FF; - col = (a << 24) | (r << 16) | (g << 8) | b; - SetPixel_ARGB8(i, col); - } -} - -NVI_ImageBordered::NVI_ImageBordered() : NVI_Image() -{ - m_hSrcImage = 0; - m_nBorderXHigh = 0; - m_nBorderYHigh = 0; - m_nBorderXLow = 0; - m_nBorderYLow = 0; - m_bWrap = 0; - m_pArray = NULL; -} - -NVI_ImageBordered::~NVI_ImageBordered() { Free(); } -HRESULT NVI_ImageBordered::Free() -{ - NVI_Image::Free(); - m_hSrcImage = 0; - m_nBorderXHigh = 0; - m_nBorderYHigh = 0; - m_nBorderXLow = 0; - m_nBorderYLow = 0; - m_bWrap = 0; - return S_OK; -} - -HRESULT NVI_ImageBordered::Initialize(NVI_Image** hSrcImage, const RECT* pBorder, bool wrap) -{ - assert(hSrcImage != NULL); - assert(*hSrcImage != NULL); - assert(pBorder != NULL); - assert(pBorder->left <= 0); - assert(pBorder->bottom <= 0); - assert(pBorder->right >= 0); - assert(pBorder->top >= 0); - // only support 32-bit ARGB for now... - assert((*hSrcImage)->m_Format == NVI_A8_R8_G8_B8); - Free(); - m_hSrcImage = hSrcImage; - m_nBorderXLow = pBorder->left; - m_nBorderXHigh = pBorder->right; - m_nBorderYLow = pBorder->bottom; - m_nBorderYHigh = pBorder->top; - // m_nBorderXLow <= 0 - m_nSizeX = (*hSrcImage)->m_nSizeX - m_nBorderXLow + m_nBorderXHigh; - m_nSizeY = (*hSrcImage)->m_nSizeY - m_nBorderYLow + m_nBorderYHigh; - NVI_Image::Initialize(m_nSizeX, m_nSizeY, (*m_hSrcImage)->m_Format); - // Now copy the source bits & pad out the edges - m_bWrap = wrap; - CopyDataFromSource(); - return S_OK; -} - -void NVI_ImageBordered::CopyDataFromSource() -{ - assert(m_pArray); - assert(m_hSrcImage); - assert(*m_hSrcImage); - assert(m_Format == NVI_A8_R8_G8_B8); - // size of image array - int sx = (*m_hSrcImage)->m_nSizeX; - int sy = (*m_hSrcImage)->m_nSizeY; - u32* pSrcArray = (u32*)(*m_hSrcImage)->m_pArray; - assert(pSrcArray != NULL); - u32* pPadArray = (u32*)m_pArray; - assert(m_pArray != NULL); - // Duplicate values into the padded region, taking wrapping into account - //. ASSERT_MSG( m_nBorderXLow < sx, "Borders larger than image not supported! ulow\n" ); - //. ASSERT_MSG( m_nBorderYLow < sy, "Borders larger than image not supported! uhigh\n" ); - //. ASSERT_MSG( m_nBorderXHigh < sx, "Borders larger than image not supported! vlow\n" ); - //. ASSERT_MSG( m_nBorderYHigh < sy, "Borders larger than image not supported! vhigh\n" ); - // First, copy source image within the borders - for (int j = 0; j < sy; j++) - { - // j is in coords of the source image - // low bounds are negative or zero - memcpy(&pPadArray[(j - m_nBorderYLow) * m_nSizeX - m_nBorderXLow], &pSrcArray[j * sx], sizeof(u32) * sx); - } - if (m_bWrap) - { - // copy rows opposite - // copy out values in x first - for (int j = 0; j < m_nSizeY; j++) - { - // j is in coords of the dest padded array - // Copy right side image pixels into left edge border padded area - // Use (- low bound) as the low will be <= 0 - memcpy(&pPadArray[j * m_nSizeX], &pPadArray[(j * m_nSizeX) + sx], sizeof(u32) * (-m_nBorderXLow)); - // Copy left side image pixels into right edge border padded area - memcpy(&pPadArray[j * m_nSizeX - m_nBorderXLow + sx], &pPadArray[j * m_nSizeX - m_nBorderXLow], - sizeof(u32) * (m_nBorderXHigh)); - } - for (int j = 0; j < m_nBorderYHigh; j++) - { - // Copy low source image pixels into upper edge border padded area - // krn_v_lowbound is negative or zero - memcpy(&pPadArray[(j + sy - m_nBorderYLow) * m_nSizeX], &pPadArray[(j - m_nBorderYLow) * m_nSizeX], - sizeof(u32) * m_nSizeX); - } - for (int j = 0; j < -m_nBorderYLow; j++) - { - // Copy high source image pixels into lower border padded area - // krn_v_lowbound is negative or zero - // This completes the image tiling into the larger padded texture - memcpy(&pPadArray[j * m_nSizeX], &pPadArray[(j + sy - 1) * m_nSizeX], sizeof(u32) * m_nSizeX); - } - } - else - { - // If not wrap - // Duplicate border outward as though image texture were clamped at edges - for (int j = 0; j < m_nBorderYHigh; j++) - { - // Copy highest source image pixel row into upper edge border padded area - // krn_v_lowbound is negative or zero - memcpy(&pPadArray[(j + sy - m_nBorderYLow) * m_nSizeX], &pPadArray[(sy - 1 - m_nBorderYLow) * m_nSizeX], - sizeof(u32) * m_nSizeX); - } - for (int j = 0; j < -m_nBorderYLow; j++) - { - // Copy lowest source image pixels into lower border padded area - // krn_v_lowbound is negative or zero - // This completes the image tiling into the larger padded texture - memcpy(&pPadArray[j * m_nSizeX], &pPadArray[(-m_nBorderYLow) * m_nSizeX], sizeof(u32) * m_nSizeX); - } - // Now copy out border pixels to left and right - for (int j = 0; j < m_nSizeY; j++) - { - // j is in coords of the dest padded array - // Copy right side image pixel to fill the right side padded row - for (int i = sx - m_nBorderXLow; i < m_nSizeX; i++) - { - memcpy(&pPadArray[j * m_nSizeX + i], &pPadArray[j * m_nSizeX + i - 1], sizeof(u32)); - } - // Copy left side src image pixel into left edge padded area - for (int i = -m_nBorderXLow - 1; i >= 0; i--) - { - memcpy(&pPadArray[j * m_nSizeX + i], &pPadArray[j * m_nSizeX + i + 1], sizeof(u32)); - } - } - } - // To save the result of the padding operation: - // ulTarga newfile; - // newfile.WriteFile( "temp_result1.tga", (unsigned char*) pPadArray, - // (u32) m_nSizeX, (u32) m_nSizeY, 32, 32, 0 ); -} diff --git a/src/utils/xrDXT/NVI_Image.h b/src/utils/xrDXT/NVI_Image.h deleted file mode 100644 index 88c11a3a025..00000000000 --- a/src/utils/xrDXT/NVI_Image.h +++ /dev/null @@ -1,157 +0,0 @@ -/*********************************************************************NVMH2**** -Path: C:\Dev\devrel\Nv_sdk_4\CommonSrc\nvImageLib -File: NVI_Image.h - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - -******************************************************************************/ - -#ifndef __NVIMAGELIB_NVI_IMAGE_H -#define __NVIMAGELIB_NVI_IMAGE_H - -#include -#include -#include "NV_Common.h" -// Debug test switch -// Define to turn on debug _ASSERT()s -// #define NVIHDEBUG - -namespace xray_nvi -{ -enum NVI_PIXEL_FORMAT -{ - IMAGE_NOT_INITIALIZED, - NVI_A8, - //@ NVI_R8_G8_B8_A8, // unsigned integer - A is most sig byte - NVI_A8_R8_G8_B8, // unsigned integer - A is most sig byte (0xAARRGGBB) - NVI_A1_R5_G5_B5, - NVI_R5_G6_B5, - NVI_A16, // 16-bit unsigned integer - //@ NVI_R16_G16_B16, - NVI_R16_G16_B16_A16, - NVI_FMT_FORCEDWORD = 0xFFFFFFFF -}; - -class NVI_Image -{ -public: - u8* m_pArray; - NVI_PIXEL_FORMAT m_Format; - // Ints so that underflow does not wrap! - int m_nSizeX; - int m_nSizeY; - -public: - NVI_Image(); - virtual ~NVI_Image(); - virtual HRESULT Initialize(int width, int height, NVI_PIXEL_FORMAT format); - virtual HRESULT Initialize(int width, int height, NVI_PIXEL_FORMAT format, u8* data); - virtual HRESULT Free(); - u32 GetBytesPerPixel(); - u32 GetImageNumBytes(); - NVI_PIXEL_FORMAT GetFormat() { return m_Format; } - u32 GetWidth() { return m_nSizeX; } - u32 GetHeight() { return m_nSizeY; } - u32 GetNumPixels(); - u8* GetImageDataPointer() { return m_pArray; } - bool IsDataValid(); - void FlipTopToBottom(); - void AverageRGBToAlpha(); // write each pixels' avg r,g,b to alpha - void ABGR8_To_ARGB8(); - -private: - void GetPixel_ARGB8(u32* outPix, u32 i, u32 j); - void SetPixel_ARGB8(u32 i, u32 j, u32 pix); - void GetPixel_ARGB8(u32* outPix, u32 index); - void SetPixel_ARGB8(u32 index, u32 pix); - - friend class NVI_PNG_File; - friend class NVI_GraphicsFile; - friend class NVI_ImageBordered; -}; - -// Inline functions -// Should not do any new or delete here - -__forceinline void NVI_Image::GetPixel_ARGB8(u32* outPix, u32 i, u32 j) -{ -#ifdef NVIHDEBUG - // _ASSERT because that evaluates for debug only - // assert() evaluates for debug and release - _ASSERT(GetFormat() == NVI_A8_R8_G8_B8); - _ASSERT(outPix != NULL); -#endif - *outPix = ((u32*)m_pArray)[j * m_nSizeX + i]; -} - -__forceinline void NVI_Image::SetPixel_ARGB8(u32 i, u32 j, u32 pix) -{ -#ifdef NVIHDEBUG - _ASSERT(GetFormat() == NVI_A8_R8_G8_B8); -#endif - ((u32*)m_pArray)[j * m_nSizeX + i] = pix; -} - -__forceinline void NVI_Image::GetPixel_ARGB8(u32* outPix, u32 index) -{ -#ifdef NVIHDEBUG - // _ASSERT because that evaluates for debug only - // assert() evaluates for debug and release - _ASSERT(GetFormat() == NVI_A8_R8_G8_B8); - _ASSERT(outPix != NULL); -#endif - *outPix = ((u32*)m_pArray)[index]; -} - -__forceinline void NVI_Image::SetPixel_ARGB8(u32 index, u32 pix) -{ -#ifdef NVIHDEBUG - _ASSERT(GetFormat() == NVI_A8_R8_G8_B8); -#endif - ((u32*)m_pArray)[index] = pix; -} - -class NVI_ImageBordered : public NVI_Image -{ -private: - int m_nBorderXLow; // ** Negative or zero ** - // This is the offset from source images' 0,0 - // that marks the left border. - // Border width on the left = -m_nBorderXLow; - // x = 0 that pixels can be addressed - int m_nBorderXHigh; // Size of border to 'right' of image. >= 0 - int m_nBorderYLow; // Same thing for Y borders - int m_nBorderYHigh; - NVI_Image** m_hSrcImage; // Image from which this was created - bool m_bWrap; // Wrap or clamp the border pixels - - void CopyDataFromSource(); - -public: - NVI_ImageBordered(); - ~NVI_ImageBordered() override; - HRESULT Initialize(NVI_Image** hSrcImage, const RECT* border, bool wrap); - HRESULT Free(); - // i,j relative to src image, so i,j = 0 fetches from - // (i-m_nBorderXLow, j-m_nBorderYLow ) in the m_pArray - void GetPixel(u32* pDest, int i, int j); -}; - -// Inline functions -// Should not do any new or delete here - -// i,j relative to src image, so i,j = 0 fetches from -// (i-m_nBorderXLow, j-m_nBorderYLow ) in the m_pArray -__forceinline void NVI_ImageBordered::GetPixel(u32* outColor, int i, int j) -{ - *outColor = ((u32*)m_pArray)[(j - m_nBorderYLow) * m_nSizeX + (i - m_nBorderXLow)]; -} -}; - -#endif // __NVIMAGELIB_NVI_IMAGE_H diff --git a/src/utils/xrDXT/NV_Common.h b/src/utils/xrDXT/NV_Common.h deleted file mode 100644 index cd97182f8f0..00000000000 --- a/src/utils/xrDXT/NV_Common.h +++ /dev/null @@ -1,107 +0,0 @@ -/*********************************************************************NVMH2**** -Path: c:\Dev\devrel\Nv_sdk_4\Include -File: NV_Common.h - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - - -******************************************************************************/ - -#ifndef __NV_COMMON_H -#define __NV_COMMON_H - -#include -#include - -#ifndef ASSERT_IF_FAILED -#define ASSERT_IF_FAILED(hres)\ - {\ - if (FAILED(hres))\ - assert(false);\ - } -#endif - -#ifndef ASSERT_AND_RET_IF_FAILED -#define ASSERT_AND_RET_IF_FAILED(hres)\ - {\ - if (FAILED(hres))\ - {\ - assert(false);\ - return (hres);\ - }\ - } -#endif - -#ifndef FAIL_IF_NULL -#define FAIL_IF_NULL(x)\ - {\ - if (x == NULL)\ - {\ - assert(false);\ - return E_FAIL;\ - }\ - } -#endif - -// FDebug defined in NV_Error.h -#ifndef ASSERT_MSG -#define ASSERT_MSG(var, msg)\ - {\ - if (!(var))\ - {\ - FDebug(msg);\ - }\ - assert(var);\ - } -#endif - -#ifndef SAFE_ARRAY_DELETE -#define SAFE_ARRAY_DELETE(p)\ - {\ - if (p)\ - {\ - delete[](p);\ - p = NULL;\ - }\ - } -#endif - -#ifndef SAFE_DELETE -#define SAFE_DELETE(p)\ - {\ - if (p)\ - {\ - delete (p);\ - p = NULL;\ - }\ - } -#endif - -#ifndef SAFE_RELEASE -#define SAFE_RELEASE(p)\ - {\ - if (p)\ - {\ - (p)->Release();\ - (p) = NULL;\ - }\ - } -#endif - -#define ifnot(x) if (!(x)) -#define until(x) while (!(x)) -#define ever (;;) -#define wait do {} -#define nothing {} - -// @@ extract more of these from ulCommon.h -typedef unsigned short USHORT; -typedef unsigned short ushort; - -#endif diff --git a/src/utils/xrDXT/NormalMapGen.cpp b/src/utils/xrDXT/NormalMapGen.cpp deleted file mode 100644 index 18234fbef6b..00000000000 --- a/src/utils/xrDXT/NormalMapGen.cpp +++ /dev/null @@ -1,675 +0,0 @@ -#include "stdafx.h" - -#include "NV_Common.h" -#include "NVI_Convolution.h" -#include "NVI_Image.h" - -using namespace xray_nvi; - -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR -#include "xrCore/Media/Image.hpp" -using namespace XRay::Media; -#endif - -enum KernelType : u32 -{ - KERNEL_4x, - KERNEL_3x3, - KERNEL_5x5, - KERNEL_7x7, - KERNEL_9x9, -}; - -void MakeKernelElems(const float* pInWeightArray, int num_x, int num_y, ConvolutionKernelElement* pOutArray); -void RotateArrayCCW(const float* pInArray, int num_x, int num_y, float* pOutArray); - -void ConvertAlphaToNormalMap_4x(float scale, bool wrap); -void ConvertAlphaToNormalMap_3x3(float scale, bool wrap); -void ConvertAlphaToNormalMap_5x5(float scale, bool wrap); -void ConvertAlphaToNormalMap_7x7(float scale, bool wrap); -void ConvertAlphaToNormalMap_9x9(float scale, bool wrap); - -u8 fpack(float v) -{ - s32 _v = iFloor(((v + 1.f) * .5f) * 255.f + .5f); - clamp(_v, 0, 255); - return u8(_v); -} - -Fvector vunpack(s32 x, s32 y, s32 z) -{ - Fvector pck; - pck.x = (float(x) / 255.f - .5f) * 2.f; - pck.y = (float(y) / 255.f - .5f) * 2.f; - pck.z = (float(z) / 255.f - .5f) * 2.f; - return pck; -} - -Fvector vunpack(const Ivector& src) { return vunpack(src.x, src.y, src.z); } -Ivector vpack(Fvector src) -{ - src.normalize(); - Fvector _v; - int bx = fpack(src.x); - int by = fpack(src.y); - int bz = fpack(src.z); - // dumb test - float e_best = flt_max; - int r = bx, g = by, b = bz; - int d = 2; - for (int x = std::max(bx - d, 0); x <= std::min(bx + d, 255); x++) - { - for (int y = std::max(by - d, 0); y <= std::min(by + d, 255); y++) - { - for (int z = std::max(bz - d, 0); z <= std::min(bz + d, 255); z++) - { - _v = vunpack(x, y, z); - float m = _v.magnitude(); - float me = _abs(m - 1.f); - if (me > 0.03f) - { - continue; - } - _v.div(m); - float e = _abs(src.dotproduct(_v) - 1.f); - if (e < e_best) - { - e_best = e; - r = x, g = y, b = z; - } - } - } - } - Ivector ipck; - ipck.set(r, g, b); - return ipck; -} - -void CalculateNormalMap(NVI_Image* pSrc, ConvolutionKernel* pKernels, int num_kernels, float scale, bool wrap) -{ - // pKernels must be an array of at least two kernels - // The first kernel extracts dh/dx (change in height with respect to x ) - // the second extracts dh/dy (change in height with respect to y ) - VERIFY(pKernels); - VERIFY(num_kernels == 2); - float results[2]; - // Set up the convolver & prepare image data - Convolver conv; - conv.Initialize(&pSrc, pKernels, num_kernels, wrap); - int size_x = (int)pSrc->GetWidth(); - int size_y = (int)pSrc->GetHeight(); - auto pArray = (u32*)pSrc->GetImageDataPointer(); - assert(pArray != NULL); - // Now run the kernel over the source image area and write out the values. - // coordinates of source image (not padded) - for (int j = 0; j < size_y; j++) - { - for (int i = 0; i < size_x; i++) - { - // apply kernels - conv.Convolve_Alpha_At(i, j, results, 2); - float du = results[0] * scale; - float dv = results[1] * scale; - // det | x y z | - // | 1 0 du | - // | 0 1 dv | - // - // cross product gives (-du, -dv, 1.0) as normal - float mag = du * du + dv * dv + 1.0f; - mag = (float)_sqrt(mag); - // Get alpha as height - char height = (char)(pArray[j * size_x + i]) >> 24; - Fvector src = {-du / mag, -dv / mag, 1.0f / mag}; - Ivector dst = vpack(src); - unsigned long nmap_color = color_rgba(dst.x, dst.y, dst.z, 0); - //. AlphaAndVectorToARGB(height, -du/mag, -dv/mag, 1.0f / mag, nmap_color); - pArray[j * size_x + i] = nmap_color; - } - } -} - -void ConvertAlphaToNormalMap_4x(NVI_Image* pSrc, float scale, bool wrap) -{ - // Do the conversion using a 4 sample nearest neighbor pattern - // - // d height / du kernel: - // 0 0 0 - // -1/2 0 1/2 - // 0 0 0 - // - // d height / dv kernel: - // 0 1/2 0 - // 0 0 0 - // 0 -1/2 0 - int numelem = 2; // num elements in each kernel - ConvolutionKernelElement du_elem[] = {{-1, 0, -1.0f / 2.0f}, {1, 0, 1.0f / 2.0f}}; - ConvolutionKernelElement dv_elem[] = {{0, 1, 1.0f / 2.0f}, {0, -1, -1.0f / 2.0f}}; - int num_kernels = 2; - ConvolutionKernel kernels[2]; - kernels[0].SetElements(numelem, du_elem); - kernels[1].SetElements(numelem, dv_elem); - // Calc ARGB normal map & write to the "in." file - CalculateNormalMap(pSrc, kernels, num_kernels, scale, wrap); -} - -void ConvertAlphaToNormalMap_3x3(NVI_Image* pSrc, float scale, bool wrap) -{ - // Uses Anders' 3x3 kernels for transforming height into a normal map vector. - // Either wraps or does not wrap. - // The convolver class memcopies to larger surface (width + kernel width-1, - // height + kernel heigh - 1 ) to make wrap code easy for arbitrary - // kernels. Edge texels are duplicated into the border regions or - // copied from the other side of the source image if wrapping is on. - int numelem = 6; // num elements in each kernel - float wt = 1.0f / 6.0f; - // Kernel for change of height in u axis: - // -1/6 0 1/6 - // -1/6 0 1/6 - // -1/6 0 1/6 - ConvolutionKernelElement du_elem[] = { - {-1, 1, -wt}, {1, 1, wt}, {-1, 0, -wt}, {1, 0, wt}, {-1, -1, -wt}, {1, -1, wt}}; - // Kernel for change of height in v axis: - // 1,1 - // 1/6 1/6 1/6 - // 0 0 0 - // -1/6 -1/6 -1/6 - // 0,0 - ConvolutionKernelElement dv_elem[] = { - {-1, 1, wt}, {0, 1, wt}, {1, 1, wt}, {-1, -1, -wt}, {0, -1, -wt}, {1, -1, -wt}}; - int num_kernels = 2; - ConvolutionKernel kernels[2]; - kernels[0].SetElements(numelem, du_elem); - kernels[1].SetElements(numelem, dv_elem); - // Calc ARGB normal map & write to the "in." file - CalculateNormalMap(pSrc, kernels, num_kernels, scale, wrap); -} - -void ConvertAlphaToNormalMap_5x5(NVI_Image* pSrc, float scale, bool wrap) -{ - // Either wraps or does not wrap. - // The convolver class memcopies to larger surface (width + kernel width-1, - // height + kernel heigh - 1 ) to make wrap code easy for arbitrary - // kernels. Edge texels are duplicated into the border regions or - // copied from the other side of the source image if wrapping is on. - int numelem; // num elements in each kernel - float wt1 = 1.0f / 6.0f; - float wt2 = 1.0f / 48.0f; - /* - // Kernel for change of height in u axis: - // The are cubic coefs for interpolation with sample - // points at -2, -1, 1, and 2, hence the 0 coefs along - // center axis. Resulting pattern is undesirable for - // outstanding points in the height field. These become - // a region of 4 mounds, when they should instead become a - // smooth blob. - - // 1/48 -1/6 0 1/6 -1/48 - // 1/48 -1/6 0 1/6 -1/48 - // 0 0 0 0 0 - // 1/48 -1/6 0 1/6 -1/48 - // 1/48 -1/6 0 1/6 -1/48 - - numelem = 16; - ConvolutionKernelElement du_elem[] = { - {-2, 2, wt2}, {-1,2,-wt1}, {1,2,wt1}, {2,2,-wt2}, - {-2, 1, wt2}, {-1,1,-wt1}, {1,1,wt1}, {2,1,-wt2}, - - {-2,-1, wt2}, {-1,-1,-wt1}, {1,-1,wt1}, {2,-1,-wt2}, - {-2,-2, wt2}, {-1,-2,-wt1}, {1,-2,wt1}, {2,-2,-wt2} }; - - // Kernel for change of height in v axis: - // This is same as u kernel above - just rotated 90 degrees - - ConvolutionKernelElement dv_elem[] = { - {-2, 2,-wt2}, {-1,2,-wt2}, {1,2,-wt2}, {2,2,-wt2}, - {-2, 1, wt1}, {-1,1, wt1}, {1,1, wt1}, {2,1, wt1}, - - {-2,-1,-wt1}, {-1,-1,-wt1}, {1,-1,-wt1}, {2,-1,-wt1}, - {-2,-2, wt2}, {-1,-2, wt2}, {1,-2, wt2}, {2,-2, wt2} }; - */ - numelem = 20; - float wt22 = 1.0f / 16.0f; - float wt12 = 1.0f / 10.0f; - float wt02 = 1.0f / 8.0f; - float wt11 = 1.0f / 2.8f; - // Kernels using slope based on distance of that point from the 0,0 - // This is not from math derivation, but makes nice result - ConvolutionKernelElement du_elem[] = {{-2, 2, -wt22}, {-1, 2, -wt12}, {1, 2, wt12}, {2, 2, wt22}, {-2, 1, -wt12}, - {-1, 1, -wt11}, {1, 1, wt11}, {2, 1, wt12}, {-2, 0, -wt02}, {-1, 0, -0.5f}, {1, 0, 0.5f}, {2, 0, wt02}, - {-2, -1, -wt12}, {-1, -1, -wt11}, {1, -1, wt11}, {2, -1, wt12}, {-2, -2, -wt22}, {-1, -2, -wt12}, {1, -2, wt12}, - {2, -2, wt22}}; - ConvolutionKernelElement dv_elem[] = {{-2, 2, wt22}, {-1, 2, wt12}, {0, 2, 1.0f / 4.0f}, {1, 2, wt12}, {2, 2, wt22}, - {-2, 1, wt12}, {-1, 1, wt11}, {0, 1, 1.0f / 2.0f}, {1, 1, wt11}, {2, 1, wt12}, {-2, -1, -wt12}, {-1, -1, -wt11}, - {0, -1, -1.0f / 2.0f}, {1, -1, -wt11}, {2, -1, -wt12}, {-2, -2, -wt22}, {-1, -2, -wt12}, {0, -2, -1.0f / 4.0f}, - {1, -2, -wt12}, {2, -2, -wt22}}; - // normalize the kernel so abs of all weights add to one - float usum = 0.0f, vsum = 0.0f; - for (int i = 0; i < numelem; i++) - { - usum += _abs(du_elem[i].weight); - vsum += _abs(dv_elem[i].weight); - } - for (int i = 0; i < numelem; i++) - { - du_elem[i].weight /= usum; - dv_elem[i].weight /= vsum; - } - int num_kernels = 2; - ConvolutionKernel kernels[2]; - kernels[0].SetElements(numelem, du_elem); - kernels[1].SetElements(numelem, dv_elem); - // Calc ARGB normal map & write to the "in." file - CalculateNormalMap(pSrc, kernels, num_kernels, scale, wrap); -} - -void MakeKernelElems(const float* pInWeightArray, int num_x, int num_y, ConvolutionKernelElement* pOutArray) -{ - // This makes coordinates for an array of weights, assumed to - // be a rectangle. - // - // You must allocate pOutArray outside the function! - // num_x and num_y should be odd - // - // Specify elems from upper left corner (-num_x/2, num_y/2) to - // lower right corner. - // This generates the coordinates of the samples for you - // For example: - // elem_array[] = { 00, 11, 22, 33, 44, 55, 66, 77, 88 } - // MakeKernelsElems( elem_array, 3, 3 ) - // would make: - // - // { -1, 1, 00 } { 0, 1, 11 } { 1, 1, 22 } - // { -1, 0, 33 } { 0, 0, 44 } { 1, 0, 55 } - // { -1, -1, 66} ..etc - // - // As the array of kernel elements written to pOutArray - // - assert(pOutArray != NULL); - assert(pInWeightArray != NULL); - for (int j = 0; j < num_y; j++) - { - for (int i = 0; i < num_x; i++) - { - int ind = i + j * num_x; - assert(ind < num_x * num_y); - pOutArray[ind].x_offset = i - num_x / 2; - pOutArray[ind].y_offset = num_y / 2 - j; - pOutArray[ind].weight = pInWeightArray[ind]; - } - } -} - -void RotateArrayCCW(float* pInArray, int num_x, int num_y, float* pOutArray) -{ - // rotate an array of floats 90 deg CCW, so - // 1, 0 - // 2, 3 - // becomes - // 0, 3 - // 1, 2 - assert(pOutArray != NULL); - assert(pInArray != NULL); - float* pSrc; - // If arrays are same, copy source to new temp array - if (pInArray == pOutArray) - { - pSrc = new float[num_x * num_y]; - assert(pSrc != NULL); - for (int i = 0; i < num_x * num_y; i++) - { - pSrc[i] = pInArray[i]; - } - } - else - { - pSrc = pInArray; - } - for (int j = 0; j < num_y; j++) - { - for (int i = 0; i < num_x; i++) - { - int newj = num_x - i - 1; - int newi = j; - // rotate dims of array too ==> j * num_y - pOutArray[newi + newj * num_y] = pSrc[i + j * num_x]; - } - } - if (pInArray == pOutArray) - { - SAFE_ARRAY_DELETE(pSrc); - } -} - -void ConvertAlphaToNormalMap_7x7(NVI_Image* pSrc, float scale, bool wrap) -{ - // Either wraps or does not wrap. - // The convolver class memcopies to larger surface (width + kernel width-1, - // height + kernel heigh - 1 ) to make wrap code easy for arbitrary - // kernels. Edge texels are duplicated into the border regions or - // copied from the other side of the source image if wrapping is on. - int numelem; // num elements in each kernel - // Kernel for change of height in u axis: - // A Sobel filter kernel - numelem = 49; - float du_f[] = {-1, -2, -3, 0, 3, 2, 1, -2, -3, -4, 0, 4, 3, 2, -3, -4, -5, 0, 5, 4, 3, -4, -5, -6, 0, 6, 5, 4, -3, - -4, -5, 0, 5, 4, 3, -2, -3, -4, 0, 4, 3, 2, -1, -2, -3, 0, 3, 2, 1}; - ConvolutionKernelElement du_elem[49]; - MakeKernelElems(du_f, 7, 7, &(du_elem[0])); - // Kernel for change of height in v axis: - float dv_f[49]; - RotateArrayCCW(&(du_f[0]), 7, 7, &(dv_f[0])); - ConvolutionKernelElement dv_elem[49]; - MakeKernelElems(dv_f, 7, 7, &(dv_elem[0])); - // normalize the kernels so abs of all - // weights add to one - float usum = 0.0f, vsum = 0.0f; - for (int i = 0; i < numelem; i++) - { - usum += _abs(du_elem[i].weight); - vsum += _abs(dv_elem[i].weight); - } - for (int i = 0; i < numelem; i++) - { - du_elem[i].weight /= usum; - dv_elem[i].weight /= vsum; - } - int num_kernels = 2; - ConvolutionKernel kernels[2]; - kernels[0].SetElements(numelem, du_elem); - kernels[1].SetElements(numelem, dv_elem); - // Calc ARGB normal map & write to the "in." file - CalculateNormalMap(pSrc, kernels, num_kernels, scale, wrap); -} - -void ConvertAlphaToNormalMap_9x9(NVI_Image* pSrc, float scale, bool wrap) -{ - // Either wraps or does not wrap. - // The convolver class memcopies to larger surface (width + kernel width-1, - // height + kernel heigh - 1 ) to make wrap code easy for arbitrary - // kernels. Edge texels are duplicated into the border regions or - // copied from the other side of the source image if wrapping is on. - int numelem; // num elements in each kernel - // Kernel for change of height in u axis: - // A Sobel filter kernel - numelem = 81; - float du_f[] = {-1, -2, -3, -4, 0, 4, 3, 2, 1, -2, -3, -4, -5, 0, 5, 4, 3, 2, -3, -4, -5, -6, 0, 6, 5, 4, 3, -4, -5, - -6, -7, 0, 7, 6, 5, 4, -5, -6, -7, -8, 0, 8, 7, 6, 5, -4, -5, -6, -7, 0, 7, 6, 5, 4, -3, -4, -5, -6, 0, 6, 5, 4, - 3, -2, -3, -4, -5, 0, 5, 4, 3, 2, -1, -2, -3, -4, 0, 4, 3, 2, 1}; - ConvolutionKernelElement du_elem[81]; - MakeKernelElems(du_f, 9, 9, &(du_elem[0])); - // Kernel for change of height in v axis: - float dv_f[81]; - RotateArrayCCW(&(du_f[0]), 9, 9, &(dv_f[0])); - ConvolutionKernelElement dv_elem[81]; - MakeKernelElems(dv_f, 9, 9, &(dv_elem[0])); - // normalize the kernels so abs of all - // weights add to one - float usum = 0.0f, vsum = 0.0f; - for (int i = 0; i < numelem; i++) - { - usum += _abs(du_elem[i].weight); - vsum += _abs(dv_elem[i].weight); - } - for (int i = 0; i < numelem; i++) - { - du_elem[i].weight /= usum; - dv_elem[i].weight /= vsum; - } - int num_kernels = 2; - ConvolutionKernel kernels[2]; - kernels[0].SetElements(numelem, du_elem); - kernels[1].SetElements(numelem, dv_elem); - // Calc ARGB normal map & write to the "in." file - CalculateNormalMap(pSrc, kernels, num_kernels, scale, wrap); -} - -void ConvertToNormalMap(NVI_Image* pSrc, KernelType kt, float scale) -{ - switch (kt) - { - case KERNEL_4x: ConvertAlphaToNormalMap_4x(pSrc, scale, true); break; - case KERNEL_3x3: ConvertAlphaToNormalMap_3x3(pSrc, scale, true); break; - case KERNEL_5x5: ConvertAlphaToNormalMap_5x5(pSrc, scale, true); break; - case KERNEL_7x7: ConvertAlphaToNormalMap_7x7(pSrc, scale, true); break; - case KERNEL_9x9: ConvertAlphaToNormalMap_9x9(pSrc, scale, true); break; - default: NODEFAULT; - } -} - -static float gloss_power = 0.f; - -IC u32 it_gloss_rev(u32 d, u32 s) -{ - gloss_power += float(color_get_A(s)) / 255.f; - return color_rgba( - //. color_get_A(s)+1, // gloss - clampr(color_get_A(s) + 1, u32(0), u32(255)), color_get_B(d), color_get_G(d), color_get_R(d)); -} - -IC u32 it_difference(u32 d, u32 orig, u32 ucomp) -{ - return color_rgba(128 + 2 * (int(color_get_R(orig)) - int(color_get_R(ucomp))) / 3, // R-error - 128 + 2 * (int(color_get_G(orig)) - int(color_get_G(ucomp))) / 3, // G-error - 128 + 2 * (int(color_get_B(orig)) - int(color_get_B(ucomp))) / 3, // B-error - 128 + 2 * (int(color_get_A(orig)) - int(color_get_A(ucomp))) / 3); // A-error -} - -IC u32 it_height_rev(u32 d, u32 s) -{ - return color_rgba(color_get_A(d), // diff x - color_get_B(d), // diff y - color_get_G(d), // diff z - color_get_R(s)); // height -} - -template -IC void TW_Iterate_1OP(u32 width, u32 height, u32 pitch, u8* dst, u8* src, const _It pred) -{ - for (u32 y = 0; y < height; y++) - { - for (u32 x = 0; x < width; x++) - { - u32& pSrc = *((u32*)(src + y * pitch) + x); - u32& pDst = *((u32*)(dst + y * pitch) + x); - pDst = pred(pDst, pSrc); - } - } -} - -template -IC void TW_Iterate_2OP(u32 width, u32 height, u32 pitch, u8* dst, u8* src0, u8* src1, const _It pred) -{ - for (u32 y = 0; y < height; y++) - { - for (u32 x = 0; x < width; x++) - { - u32& pSrc0 = *((u32*)(src0 + y * pitch) + x); - u32& pSrc1 = *((u32*)(src1 + y * pitch) + x); - u32& pDst = *((u32*)(dst + y * pitch) + x); - pDst = pred(pDst, pSrc0, pSrc1); - } - } -} - -u32 hsample(s32 w, s32 h, s32 p, s32 x, s32 y, u8* src) -{ - if (x < 0) - { - x += w; - } - x %= w; - if (y < 0) - { - y += h; - } - y %= h; - return color_get_R(*((u32*)(src + y * p) + x)); -} - -#include "Layers/xrRender/ETextureParams.h" -#include "Image_DXTC.h" - -extern int DXTCompressImage(LPCSTR out_name, u8* raw_data, u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth); - -int DXTCompressBump( - LPCSTR out_name, u8* T_height_gloss, u8* T_normal_map, u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth) -{ - VERIFY(4 == depth); - NVI_Image* pSrc = xr_new(); - pSrc->Initialize(w, h, NVI_A8_R8_G8_B8, T_height_gloss); - pSrc->AverageRGBToAlpha(); - // stage 0 - pitch = w * 4; -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image() - .Create(w, h, T_height_gloss, ImageDataFormat::RGBA8) - .SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\0-height-gloss.tga", true); -#endif - if (T_normal_map) - { - u8* ext_nm = pSrc->GetImageDataPointer(); - CopyMemory(ext_nm, T_normal_map, w * h * sizeof(u32)); - } - else - { - ConvertToNormalMap(pSrc, KERNEL_4x, fmt->bump_virtual_height * 200.f); - } - u8* T_normal_1 = pSrc->GetImageDataPointer(); -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image().Create(w, h, T_normal_1, ImageDataFormat::RGBA8).SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\1-normal_1.tga", true); -#endif - gloss_power = 0.0f; - // T_height_gloss.a (gloss) -> T_normal_1 + reverse of channels - TW_Iterate_1OP(w, h, pitch, T_normal_1, T_height_gloss, it_gloss_rev); - gloss_power /= float(w * h); -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image().Create(w, h, T_normal_1, ImageDataFormat::RGBA8).SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\2-normal_1.tga", true); -#endif - STextureParams fmt0; - fmt0.flags.assign(STextureParams::flGenerateMipMaps); - fmt0.type = STextureParams::ttImage; - fmt0.fmt = STextureParams::tfDXT5; - int res = DXTCompressImage(out_name, T_normal_1, w, h, pitch, &fmt0, depth); - // stage 1 - if (res == 1) - { - // Decompress (back) - Image_DXTC* img = xr_new(); - if (img->LoadFromFile(out_name)) - { - VERIFY(w == img->Width() && h == img->Height()); - img->Decompress(); - u8* T_normal_1U = img->GetDecompDataPointer(); -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image() - .Create(w, h, T_normal_1U, TGAImageDataFormat::RGBA8) - .SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\3-normal_1U.tga", true); -#endif - // Calculate difference - u8* T_normal_1D = (u8*)calloc(w * h, sizeof(u32)); - TW_Iterate_2OP(w, h, pitch, T_normal_1D, T_normal_1, T_normal_1U, it_difference); -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image() - .Create(w, h, T_normal_1D, ImageDataFormat::RGBA8) - .SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\4-normal_1D.tga", true); -#endif - // Rescale by virtual height - float h_scale = powf(fmt->bump_virtual_height / 0.05f, 0.75f); // move towards 1.0f - if (h_scale > 1.f) - { - h_scale = _sqrt(h_scale); - } - for (u32 y = 0; y < h; y++) - { - for (u32 x = 0; x < w; x++) - { - u32& sh = *((u32*)(T_height_gloss + y * pitch) + x); - u32 h = color_get_R(sh); // height -> R-channel - h = iFloor(float(h) * h_scale + EPS_S); - sh = color_rgba(h, color_get_G(sh), color_get_B(sh), color_get_A(sh)); - } - } - // Calculate bounds for centering - u32 h_average = 0, h_min = 255, h_max = 0; - { - for (u32 y = 0; y < h; y++) - { - for (u32 x = 0; x < w; x++) - { - u32 sh = *((u32*)(T_height_gloss + y * pitch) + x); - u32 h = color_get_R(sh); // height -> R-channel - h_average += h; - if (h < h_min) - { - h_min = h; - } - if (h > h_max) - { - h_max = h; - } - } - } - } - // final median, which will be used for centering - u32 h_median = 9 * (h_average / (w * h)) + 1 * ((h_max - h_min) / 2 + h_min); - h_median /= 10; - s32 h_correction = s32(127) - s32(h_median); - // Calculate filtered and corrected height - u8* T_height_pf = (u8*)calloc(w * h, sizeof(u32)); // filtered for parallax - for (s32 y = 0; y < s32(h); y++) - { - u32 p = pitch; - u8* T = T_height_gloss; - for (s32 x = 0; x < s32(w); x++) - { - u32& dst = *((u32*)(T_height_pf + y * pitch) + x); -#ifdef XR_DXT_BUMP_FILTERING - u32 val = hsample(w, h, p, x - 1, y - 1, T) + hsample(w, h, p, x + 0, y - 1, T) + - hsample(w, h, p, x + 1, y - 1, T) + hsample(w, h, p, x - 1, y + 0, T) + - hsample(w, h, p, x + 0, y + 0, T) + hsample(w, h, p, x + 1, y + 0, T) + - hsample(w, h, p, x - 1, y + 1, T) + hsample(w, h, p, x + 0, y + 1, T) + - hsample(w, h, p, x + 1, y + 1, T); - val /= 9; -#else - u32 val = hsample(w, h, p, x + 0, y + 0, T); -#endif - s32 r = clampr(s32(val) + h_correction, 0, 255); - dst = color_rgba(r, r, r, r); - } - } - // Reverse channels back + transfer heightmap - TW_Iterate_1OP(w, h, pitch, T_normal_1D, T_height_pf, it_height_rev); -#ifdef XR_DXT_DBG_BUMP_STAGES_DIR - Image() - .Create(w, h, T_normal_1D, ImageDataFormat::RGBA8) - .SaveTGA(XR_DXT_DBG_BUMP_STAGES_DIR "\\5-normal_1D.tga", true); -#endif - // Compress - STextureParams fmt0; - fmt0.flags.assign(STextureParams::flGenerateMipMaps); - fmt0.type = STextureParams::ttImage; - fmt0.fmt = STextureParams::tfDXT5; - string256 out_name1; - xr_strcpy(out_name1, out_name); - if (strext(out_name1)) - { - *strext(out_name1) = 0; - } - xr_strcat(out_name1, "#.dds"); - res |= DXTCompressImage(out_name1, T_normal_1D, w, h, pitch, &fmt0, depth); - free(T_height_pf); - free(T_normal_1D); - } - else - { - res = 0; - } - xr_delete(img); - } - xr_delete(pSrc); - if (gloss_power < 0.1f) - { - res = -1000; - } - return res; -} diff --git a/src/utils/xrDXT/StdAfx.cpp b/src/utils/xrDXT/StdAfx.cpp deleted file mode 100644 index fd4f341c7b2..00000000000 --- a/src/utils/xrDXT/StdAfx.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "stdafx.h" diff --git a/src/utils/xrDXT/StdAfx.h b/src/utils/xrDXT/StdAfx.h deleted file mode 100644 index 39b1726dc83..00000000000 --- a/src/utils/xrDXT/StdAfx.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#define ECORE_API - -#include "Common/Common.hpp" -#include "xrCore/xrCore.h" diff --git a/src/utils/xrDXT/dds.h b/src/utils/xrDXT/dds.h deleted file mode 100644 index 8b228daa827..00000000000 --- a/src/utils/xrDXT/dds.h +++ /dev/null @@ -1,91 +0,0 @@ -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - -#ifndef _DDS_H_ -#define _DDS_H_ - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS - -const DDS_PIXELFORMAT DDSPF_DXT1 = {sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0}; - -const DDS_PIXELFORMAT DDSPF_DXT2 = {sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0}; - -const DDS_PIXELFORMAT DDSPF_DXT3 = {sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0}; - -const DDS_PIXELFORMAT DDSPF_DXT4 = {sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0}; - -const DDS_PIXELFORMAT DDSPF_DXT5 = {sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0}; - -const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = { -sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}; - -const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = { -sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000}; - -const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = { -sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x0000f000, 0x000000f0, 0x0000000f, 0x0000f000}; - -const DDS_PIXELFORMAT DDSPF_R8G8B8 = { -sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}; - -const DDS_PIXELFORMAT DDSPF_R5G6B5 = { -sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000}; - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES\ - (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -struct DDS_HEADER -{ - u32 dwSize; - u32 dwHeaderFlags; - u32 dwHeight; - u32 dwWidth; - u32 dwPitchOrLinearSize; - u32 dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - u32 dwMipMapCount; - u32 dwReserved1[11]; - DDS_PIXELFORMAT ddspf; - u32 dwSurfaceFlags; - u32 dwCubemapFlags; - u32 dwReserved2[3]; -}; - -enum DDS_HEADER_FLAGS -{ - DDSD_CAPS = 1 << 0, - DDSD_HEIGHT = 1 << 1, - DDSD_WIDTH = 1 << 2, - DDSD_PITCH = 1 << 3, - DDSD_PIXELFORMAT = 1 << 12, - DDSD_MIPMAPCOUNT = 1 << 17, - DDSD_LINEARSIZE = 1 << 19, - DDSD_DEPTH = 1 << 23, -}; - -#endif diff --git a/src/utils/xrDXT/dds/ConvertColor.h b/src/utils/xrDXT/dds/ConvertColor.h deleted file mode 100644 index 632d5c2508b..00000000000 --- a/src/utils/xrDXT/dds/ConvertColor.h +++ /dev/null @@ -1,280 +0,0 @@ -#pragma once -#include "tPixel.h" - -namespace nv -{ -template -inline T Min(const T& x, const T& y) -{ - return x < y ?: x : y; -} -template -inline T Max(const T& x, const T& y) -{ - return x > y ? x : y; -} -} - -typedef unsigned short nvhalf; - -union nv_half_data -{ - unsigned short bits; - struct - { - unsigned long m : 10; - unsigned long e : 5; - unsigned long s : 1; - } ieee; -}; - -union nv_ieee_single -{ - float f; - struct - { - unsigned long m : 23; - unsigned long e : 8; - unsigned long s : 1; - } ieee; -}; - -class nvColorConvert -{ -public: - void RGBAToFloat(const RGBAImage& srcImage, fpImage& dstImage); - void RGBAToFloat(const RGBAMipMappedImage& srcMIPImage, fpMipMappedImage& dstMIPImage); - void FloatToRGBA(const fpImage& srcImage, RGBAImage& dstImage); - void FloatToRGBA(const fpMipMappedImage& srcMIPImage, RGBAMipMappedImage& dstMIPImage); - fpPixel RGBEtoFloat(int r, int g, int b, int e); - // photoshop import export - float PSSignedToFloat(int pixel, int depth, int plane); - float PSUnsignedToFloat(int pixel, int depth); - int FloatToUnsignedPS(float pixel, int depth); - int FloatToSignedPS(float pixel, int depth, int plane); - // format to float - static float UnsignedToFloat(int channel); // unsigned, 8 bits - static float UnsignedToFloat(int channel, int nBits); // unsigned - static float SignedToFloat(int channel); // 8 bits - static float SignedToFloat(int channel, int nBits); - - static void RGBAToFloat(int r, int g, int b, int a, fpPixel& fp) - { - fp.r = UnsignedToFloat(r); - fp.g = UnsignedToFloat(g); - fp.b = UnsignedToFloat(b); - fp.a = UnsignedToFloat(a); - } - - static void RGBAToFloat(const rgba_t& inColor, fpPixel& fp) - { - fp.r = UnsignedToFloat(inColor.r); - fp.g = UnsignedToFloat(inColor.g); - fp.b = UnsignedToFloat(inColor.b); - fp.a = UnsignedToFloat(inColor.a); - } - - static void RGBEToFloat(fpPixel& fp, const rgba_t& rgbe); - static void RGBEToFloat(float& r, float& g, float& b, const rgba_t& rgbe); - - static float HalfToFloat(nvhalf val) - { - nv_half_data h; - // h.bits = val.value_bits; - h.bits = val; - nv_ieee_single sng; - sng.ieee.s = h.ieee.s; - // handle special cases - if (h.ieee.e == 0 && h.ieee.m == 0) - { - // zero - sng.ieee.m = 0; - sng.ieee.e = 0; - } - else if (h.ieee.e == 0 && h.ieee.m != 0) - { - // denorm -- denorm half will fit in non-denorm single - const float half_denorm = 1.0f / 16384.0f; // 2^-14 - float mantissa = (float)h.ieee.m / 1024.0f; - float sgn = (h.ieee.s) ? -1.0f : 1.0f; - sng.f = sgn * mantissa * half_denorm; - } - else if (h.ieee.e == 31 && h.ieee.m == 0) - { - // infinity - sng.ieee.e = 0xff; - sng.ieee.m = 0; - } - else if (h.ieee.e == 31 && h.ieee.m != 0) - { - // NaN - sng.ieee.e = 0xff; - sng.ieee.m = 1; - } - else - { - sng.ieee.e = h.ieee.e + 112; - sng.ieee.m = h.ieee.m << 13; - } - return sng.f; - } - - /// float to format - static unsigned long FloatToUnsigned(float channel); // 8 bits - static unsigned long FloatToUnsigned(float channel, int nBits); - static long FloatToSigned(float channel); // 8 bits - static long FloatToSigned(float channel, int nBits); - - static unsigned long NormalToUnsigned(float inColor) { return FloatToUnsigned(inColor * 0.5f + 0.5f); } - static unsigned long NormalToUnsigned(float inColor, int nBits) - { - return FloatToUnsigned(inColor * 0.5f + 0.5f, nBits); - } - - static void NormalToRGBA(const fpPixel& inColor, rgba_t& outColor) - { - outColor.r = (unsigned char)NormalToUnsigned(inColor.r); - outColor.g = (unsigned char)NormalToUnsigned(inColor.g); - outColor.b = (unsigned char)NormalToUnsigned(inColor.b); - outColor.a = (unsigned char)NormalToUnsigned(inColor.a); - } - - static void FloatToRGBA(const fpPixel& inColor, rgba_t& p) - { - p.r = (unsigned char)FloatToUnsigned(inColor.r); - p.g = (unsigned char)FloatToUnsigned(inColor.g); - p.b = (unsigned char)FloatToUnsigned(inColor.b); - p.a = (unsigned char)FloatToUnsigned(inColor.a); - } - - static void FloatToBGRA(const fpPixel& inColor, unsigned long& outColor) - { - unsigned int r = FloatToUnsigned(inColor.r); - unsigned int g = FloatToUnsigned(inColor.g); - unsigned int b = FloatToUnsigned(inColor.b); - unsigned int a = FloatToUnsigned(inColor.a); - outColor = a << 24 | r << 16 | g << 8 | b; - } - - static void FloatToBGRA(float r, float g, float b, float a, unsigned long& outColor) - { - unsigned int ri = FloatToUnsigned(r); - unsigned int gi = FloatToUnsigned(g); - unsigned int bi = FloatToUnsigned(b); - unsigned int ai = FloatToUnsigned(a); - outColor = ai << 24 | ri << 16 | gi << 8 | bi; - } - - static void FloatToQ8W8V8U8(const fpPixel& inColor, q8w8v8u8_t& outColor) - { - outColor.q = (char)FloatToSigned(inColor.r); - outColor.v = (char)FloatToSigned(inColor.g); - outColor.w = (char)FloatToSigned(inColor.b); - outColor.u = (char)FloatToSigned(inColor.a); - } - - static void FloatToU16V16(float u, float v, v16u16_t& outColor) - { - outColor.u = (short)FloatToSigned(u, 16); - outColor.v = (short)FloatToSigned(v, 16); - } - - static void FloatToR12G12B8(const fpPixel& inColor, r12g12b8_t& outColor) - { - outColor.r = FloatToUnsigned(inColor.r, 12); - outColor.g = FloatToUnsigned(inColor.g, 12); - outColor.b = FloatToUnsigned(inColor.b, 8); - } - - static void NormalToR12G12B8(const fpPixel& inColor, r12g12b8_t& outColor) - { - outColor.r = FloatToUnsigned(inColor.r * 0.5f + 0.5f, 12); - outColor.g = FloatToUnsigned(inColor.g * 0.5f + 0.5f, 12); - outColor.b = FloatToUnsigned(inColor.b * 0.5f + 0.5f, 8); - } - - static float FloatToRGBE_Alpha(const fpPixel& fp); - static void FloatToRGBE(rgba_t& rgbe, const float& r, const float& g, const float& b); - static void FloatToRGBE(rgba_t* rgbe, const float& r, const float& g, const float& b); - static void FloatToRGBE(fpPixel& rgbe, const fpPixel& fp); - static void FloatToRGBE(rgba_t& rgbe, const fpPixel& fp); - static unsigned char FloatToRGBE_DXT3Alpha(const fpPixel& fp); - - static nvhalf FloatToHalf(float val) - { - nv_ieee_single f; - f.f = val; - nv_half_data h; - h.ieee.s = f.ieee.s; - // handle special cases - // const float half_denorm = (1.0f/16384.0f); - if (f.ieee.e == 0 && f.ieee.m == 0) - { - // zero - h.ieee.m = 0; - h.ieee.e = 0; - } - else if (f.ieee.e == 0 && f.ieee.m != 0) - { - // denorm -- denorm float maps to 0 half - h.ieee.m = 0; - h.ieee.e = 0; - } - else if (f.ieee.e == 0xff && f.ieee.m == 0) - { - // infinity - h.ieee.m = 0; - h.ieee.e = 31; - } - else if (f.ieee.e == 0xff && f.ieee.m != 0) - { - // NaN - h.ieee.m = 1; - h.ieee.e = 31; - } - else - { - // regular number - int new_exp = f.ieee.e - 127; - if (new_exp < -24) - { // this maps to 0 - h.ieee.m = 0; - h.ieee.e = 0; - } - if (new_exp < -14) - { - // this maps to a denorm - h.ieee.e = 0; - unsigned int exp_val = (unsigned int)(-14 - new_exp); // 2^-exp_val - switch (exp_val) - { - case 0: - // fprintf(stderr, "ftoh: logical error in denorm creation!\n"); - h.ieee.m = 0; - break; - case 1: h.ieee.m = 512 + (f.ieee.m >> 14); break; - case 2: h.ieee.m = 256 + (f.ieee.m >> 15); break; - case 3: h.ieee.m = 128 + (f.ieee.m >> 16); break; - case 4: h.ieee.m = 64 + (f.ieee.m >> 17); break; - case 5: h.ieee.m = 32 + (f.ieee.m >> 18); break; - case 6: h.ieee.m = 16 + (f.ieee.m >> 19); break; - case 7: h.ieee.m = 8 + (f.ieee.m >> 20); break; - case 8: h.ieee.m = 4 + (f.ieee.m >> 21); break; - case 9: h.ieee.m = 2 + (f.ieee.m >> 22); break; - case 10: h.ieee.m = 1; break; - } - } - else if (new_exp > 15) - { // map this value to infinity - h.ieee.m = 0; - h.ieee.e = 31; - } - else - { - h.ieee.e = new_exp + 15; - h.ieee.m = f.ieee.m >> 13; - } - } - return *(nvhalf*)&h.bits; - } -}; diff --git a/src/utils/xrDXT/dds/ddsTypes.h b/src/utils/xrDXT/dds/ddsTypes.h deleted file mode 100644 index ff19b3a5f35..00000000000 --- a/src/utils/xrDXT/dds/ddsTypes.h +++ /dev/null @@ -1,298 +0,0 @@ -#pragma once -#include -#include - -#if defined(WIN32_LEAN_AND_MEAN) -#include // MAKEFOURCC -#endif - -#include -#include - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; - -typedef enum nvD3DFORMAT -{ - nvD3DFMT_UNKNOWN = 0, - nvD3DFMT_R8G8B8 = 20, - nvD3DFMT_A8R8G8B8 = 21, - nvD3DFMT_X8R8G8B8 = 22, - nvD3DFMT_R5G6B5 = 23, - nvD3DFMT_X1R5G5B5 = 24, - nvD3DFMT_A1R5G5B5 = 25, - nvD3DFMT_A4R4G4B4 = 26, - nvD3DFMT_R3G3B2 = 27, - nvD3DFMT_A8 = 28, - nvD3DFMT_A8R3G3B2 = 29, - nvD3DFMT_X4R4G4B4 = 30, - nvD3DFMT_A2B10G10R10 = 31, - nvD3DFMT_A8B8G8R8 = 32, - nvD3DFMT_X8B8G8R8 = 33, - nvD3DFMT_G16R16 = 34, - nvD3DFMT_A2R10G10B10 = 35, - nvD3DFMT_A16B16G16R16 = 36, - nvD3DFMT_A8P8 = 40, - nvD3DFMT_P8 = 41, - nvD3DFMT_L8 = 50, - nvD3DFMT_A8L8 = 51, - nvD3DFMT_A4L4 = 52, - nvD3DFMT_V8U8 = 60, - nvD3DFMT_L6V5U5 = 61, - nvD3DFMT_X8L8V8U8 = 62, - nvD3DFMT_Q8W8V8U8 = 63, - nvD3DFMT_V16U16 = 64, - nvD3DFMT_A2W10V10U10 = 67, - nvD3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), - nvD3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), - nvD3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), - nvD3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), - nvD3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), - nvD3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), - nvD3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), - nvD3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), - nvD3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), - nvD3DFMT_3Dc = MAKEFOURCC('A', 'T', 'I', '2'), - nvD3DFMT_D16_LOCKABLE = 70, - nvD3DFMT_D32 = 71, - nvD3DFMT_D15S1 = 73, - nvD3DFMT_D24S8 = 75, - nvD3DFMT_D24X8 = 77, - nvD3DFMT_D24X4S4 = 79, - nvD3DFMT_D16 = 80, - nvD3DFMT_D32F_LOCKABLE = 82, - nvD3DFMT_D24FS8 = 83, - nvD3DFMT_L16 = 81, - nvD3DFMT_VERTEXDATA = 100, - nvD3DFMT_INDEX16 = 101, - nvD3DFMT_INDEX32 = 102, - nvD3DFMT_Q16W16V16U16 = 110, - nvD3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M', 'E', 'T', '1'), - // Floating point surface formats - // s10e5 formats (16-bits per channel) - nvD3DFMT_R16F = 111, - nvD3DFMT_G16R16F = 112, - nvD3DFMT_A16B16G16R16F = 113, - // IEEE s23e8 formats (32-bits per channel) - nvD3DFMT_R32F = 114, - nvD3DFMT_G32R32F = 115, - nvD3DFMT_A32B32G32R32F = 116, - nvD3DFMT_CxV8U8 = 117, - nvD3DFMT_FORCE_DWORD = 0x7fffffff -} nvD3DFORMAT; - -typedef enum nvRescaleTypes -{ - kRescaleNone, // no rescale - kRescaleNearestPower2, // rescale to nearest power of two - kRescaleBiggestPower2, // rescale to next bigger power of 2 - kRescaleSmallestPower2, // rescale to smaller power of 2 - kRescaleNextSmallestPower2, // rescale to next smaller power of 2 - kRescalePreScale, // rescale to this size - kRescaleRelScale, // relative rescale -} RescaleTypes; - -enum nvSharpenFilterTypes -{ - kSharpenFilterNone, - kSharpenFilterNegative, - kSharpenFilterLighter, - kSharpenFilterDarker, - kSharpenFilterContrastMore, - kSharpenFilterContrastLess, - kSharpenFilterSmoothen, - kSharpenFilterSharpenSoft, - kSharpenFilterSharpenMedium, - kSharpenFilterSharpenStrong, - kSharpenFilterFindEdges, - kSharpenFilterContour, - kSharpenFilterEdgeDetect, - kSharpenFilterEdgeDetectSoft, - kSharpenFilterEmboss, - kSharpenFilterMeanRemoval, - kSharpenFilterUnSharp, - kSharpenFilterXSharpen, - kSharpenFilterWarpSharp, - kSharpenFilterCustom, -}; - -enum nvMipMapGeneration -{ - kGenerateMipMaps = 30, - kUseExistingMipMaps = 31, - kNoMipMaps = 32, - kCompleteMipMapChain = 33, // fill in missing MIP maps -}; - -enum nvMipFilterTypes -{ - kMipFilterPoint, - kMipFilterBox, - kMipFilterTriangle, - kMipFilterQuadratic, - kMipFilterCubic, - kMipFilterCatrom, - kMipFilterMitchell, - kMipFilterGaussian, - kMipFilterSinc, - kMipFilterBessel, - kMipFilterHanning, - kMipFilterHamming, - kMipFilterBlackman, - kMipFilterKaiser, -}; - -enum nvTextureFormats -{ - kDXT1, - kDXT1a, // DXT1 with one bit alpha - kDXT3, // explicit alpha - kDXT5, // interpolated alpha - k4444, // a4 r4 g4 b4 - k1555, // a1 r5 g5 b5 - k565, // a0 r5 g6 b5 - k8888, // a8 r8 g8 b8 - k888, // a0 r8 g8 b8 - k555, // a0 r5 g5 b5 - kP8c, // paletted color only - kV8U8, // DuDv - kCxV8U8, // normal map - kA8, // alpha only - kP4c, // 16 bit color palette - kQ8W8V8U8, - kA8L8, - kR32F, - kA32B32G32R32F, - kA16B16G16R16F, - kL8, // luminance - kP8a, // paletted with alpha - kP4a, // 16 bit color palette with alpha - kR16F, // single component fp16 - kDXT5_NM, // normal map compression. G = Y, A = X - kX888, // aX r8 g8 b8 - kV16U16, - kG16R16, - kG16R16F, - k3Dc, - kL16, - kUnknownTextureFormat = 0xFFFFFFFF, -}; - -enum nvTextureTypes -{ - kTextureTypeTexture2D, - kTextureTypeCubeMap, - kTextureTypeVolumeMap, -}; - -enum nvCompressionWeighting -{ - kLuminanceWeighting, - kGreyScaleWeighting, - kTangentSpaceNormalMapWeighting, - kObjectSpaceNormalMapWeighting, - kUserDefinedWeighting, // used values stored in 'weight' -}; - -enum nvNormalMapFilters -{ - kFilter4x = 1040, - kFilter3x3 = 1041, - kFilter5x5 = 1042, - kFilter7x7 = 1043, - kFilter9x9 = 1044, - kFilterDuDv = 1045, -}; - -enum nvHeightConversionMethods -{ - kAlphaChannel = 1009, - kAverageRGB = 1010, - kBiasedRGB = 1011, - kRed = 1012, - kGreen = 1013, - kBlue = 1014, - kMaxRGB = 1015, - kColorSpace = 1016, - kNormalize = 1017, - kNormalMapToHeightMap = 1018, -}; - -enum nvAlphaResult -{ - kAlphaUnchanged = 1033, - kAlphaHeight = 1034, - kAlphaSetToZero = 1035, - kAlphaSetToOne = 1036, -}; - -enum nvQualitySetting -{ - kQualityFastest = 68, - kQualityNormal = 69, - kQualityProduction = 71, // typical value - kQualityHighest = 72, -}; - -enum nvPixelFormat -{ - PF_RGBA, - PF_FP32, -}; - -// filled in by reading a dds file -struct DDS_PIXELFORMAT -{ - u32 dwSize; - u32 dwFlags; - u32 dwFourCC; - u32 dwRGBBitCount; - u32 dwRBitMask; - u32 dwGBitMask; - u32 dwBBitMask; - u32 dwRGBAlphaBitMask; -}; - -class nvImageContainer -{ -public: - // loaded directly from the .dds header - DDS_PIXELFORMAT m_ddpfPixelFormat; - // in file read - size_t width; // of MIP 0 - size_t height; // of MIP 0 - size_t depth; // for volume maps - size_t actualMipMapCount; - size_t nMIPMapsToLoad; - bool bFoundAlphaInRead; // is alpha field present and non-zero - // in the input file - u32 dwCubeMapFlags; - size_t bits_per_component; - size_t nPlanes; // number of planes in the file format - bool bCompressed; // is file a compressed format - size_t paletteSize; // 16 or 256 entries - rgba_t palette[256]; - u32 fmt; // D3DFORMAT specified in .dds file - nvTextureFormats textureFormat; - nvTextureTypes textureType; - fpMipMappedImage fpMIPImage; - fpMipMappedCubeMap fpMIPCubeMap; - fpMipMappedVolumeMap fpMIPVolumeMap; - RGBAMipMappedImage rgbaMIPImage; - RGBAMipMappedCubeMap rgbaMIPCubeMap; - RGBAMipMappedVolumeMap rgbaMIPVolumeMap; - - nvImageContainer() - { - bits_per_component = 0; // image's resolution in bits per pixel per plane - paletteSize = 0; - bFoundAlphaInRead = false; - bCompressed = false; - fmt = 0; // nvD3DFMT_UNKNOWN - dwCubeMapFlags = 0; - actualMipMapCount = 1; - nMIPMapsToLoad = 1; - depth = 0; - } -}; diff --git a/src/utils/xrDXT/dds/nvErrorCodes.h b/src/utils/xrDXT/dds/nvErrorCodes.h deleted file mode 100644 index a2dc18eaafc..00000000000 --- a/src/utils/xrDXT/dds/nvErrorCodes.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -enum NV_ERROR_CODE -{ - NV_OK = 0, - NV_FAIL = -1, // generic - NV_CANT_OPEN_INPUT_FILE = -2, - NV_CANT_OPEN_OUTPUT_FILE = -3, - NV_BAD_OPTION = -4, - NV_BAD_OUTPUT_DIRECTORY = -5, - NV_CANT_DECOMPRESS_IMAGE = -6, - NV_BAD_LIST_FILE = -7, - NV_CANT_OPEN_LIST_FILE = -8, - NV_BAD_LIST_FILE_CONTENTS = -9, - NV_IMAGE_NOT_SQUARE = -10, - NV_IMAGES_NOT_SAME_SIZE = -11, - NV_UNKNOWN_CONVERSION = -12, // for normal map generation - NV_CANT_OPEN_PROFILE = -13, - NV_IMAGE_NOT_MULT4 = -14, - NV_OUTPUT_FILE_IS_READ_ONLY = -15, - NV_INPUT_POINTER_ZERO = -16, - NV_DEPTH_IS_NOT_3_OR_4 = -17, - NV_IMAGE_NOT_POWER_2 = -18, - NV_CANT_MAKE_MATRIX = -19, - NV_CANT_NORMALIZE = -20, - NV_CANT_INVERT_MATRIX = -21, - NV_CANT_MAKE_VECTOR = -22, - NV_CANT_INITIALIZE_CONVOLVER = -23, - NV_EMPTY_IMAGE = -24, - NV_BAD_FLAGS = -25, - NV_GBM_IO_ERR = -26, - NV_TGA_IO_ERR = -27, - NV_TGA_RLE_ERR = -28, - NV_PNG_IO_ERR = -29, - NV_CANT_CREATE_INDEX_BUFFER = -30, - NV_CANT_CREATE_CUBE_MAP = -31, - NV_BAD_FORMAT = -32, - NV_CANT_CREATE_TEXTURE = -33, - NV_UNKNOWN_FORMAT = -34, - NV_CANT_CREATE_VERTEX_BUFFER = -35, - NV_CANT_CREATE_PIXEL_SHADER = -36, - NV_CANT_CREATE_VERTEX_DECL = -37, - NV_NEED_4_PLANES_FOR_RGBE = -38, - NV_PSD_IO_ERR = -39, - NV_NO_FILENAME = -40, - NV_CANT_DECOMPOSE_MATRIX = -41, - NV_HDR_IO_ERR = -42, - NV_RGBA_IO_ERR = -43, - NV_READ_FAILED = -44, - NV_WRITE_FAILED = -45, - NV_BAD_ARG = -46, - NV_CANT_LOCK = -47, - NV_FAILED_UNLOCK = -48, - NV_NOT_RING_LOOP = -49, - NV_CHART_FOLDED = -50, - NV_CHART_CANNOT_INVERT = -51, - NV_CHART_BAD_PERIMETER = -52, - NV_CHART_NO_DATA = -53, - NV_CHART_CANT_OPTIMIZE = -54, - NV_CHART_NO_POINTS_FOUND = -55, - NV_CHART_ZERO_SIZE = -56, - NV_CHART_NO_UNPINNED = -57, - NV_CHART_OVERLAP = -58, - NV_CHART_NO_FACES = -59, - NV_CHART_MAX_DISTORTION_EXCEEDED = -60, - NV_CHART_AVE_DISTORTION_EXCEEDED = -61, - NV_CANT_CREATE_PRECONDITIONER = -70, - NV_NO_CONVERGENCE = -71, - NV_ZERO_DIAGONAL = -72, - NV_ZERO_TRIANGLE_AREA = -73, - NV_LINE_ON_PLANE = -74, - NV_LINE_AND_PLANE_PARALLEL = -75, - NV_CANT_COMPILE_EFFECT_FILE = -76, - // open - NV_CANT_UNLOCK_INDEX_BUFFER = -78, - NV_CANT_CLONE_MESH = -79, - NV_CANT_FIND_FILE = -80, - NV_INVALID_FILENAME = -81, - NV_CANT_SET_MATRIX = -82, - NV_NEED_PIXEL_SHADER2 = -83, - NV_CANT_UNLOCK_TEXTURE = -84, - NV_OUT_OF_MEMORY = -85, - NV_TIFF_IO_ERR = -86, - NV_FILE_BAD_INDEX = -90, - NV_FILE_NOT_ENOUGH_INDICES = -91, - NV_FILE_FORMAT_NOT_SUPPORTED = -92, - NV_CANT_CREATE_EFFECT = -93, - NV_NAN = -94, - NV_SURFACE_IS_CUBE_MAP = -95, - NV_SURFACE_IS_VOLUME_MAP = -96, - NV_UNSUPPORTED_FORMAT = -97, - NV_MEMORY_ALLOCATION_FAILED = -98, - NV_CUBE_MAP_NEEDS_SIX_FACES = -99, - NV_IMAGE_EXCEEDS_INTERNAL_SIZE = -100, - NV_CUBE_MAP_WIDTH_IS_NOT_SIX_TIMES_HEIGHT = -101, - NV_VOLUME_MAP_IS_NOT_POWER2 = -102, -}; - -//const char* getErrorString(NV_ERROR_CODE hr); diff --git a/src/utils/xrDXT/dds/tPixel.h b/src/utils/xrDXT/dds/tPixel.h deleted file mode 100644 index 656a4bf8f47..00000000000 --- a/src/utils/xrDXT/dds/tPixel.h +++ /dev/null @@ -1,1257 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace nv -{ -// modulo value x between [lo,hi] -// allows value 'hi' -template -inline _Type Clamp(const _Type& x, const _Type& lo, const _Type& hi) -{ - if (x < lo) - return lo; - else if (x > hi) - return hi; - else - return x; -} - -inline int iClamp(int x, int lo, int hi) -{ - if (x < lo) - return lo; - if (x > hi) - return hi; - return x; -} - -inline float fClamp(float x, float lo, float hi) -{ - if (x < lo) - return lo; - if (x > hi) - return hi; - return x; -} - -inline int fmod(int x, int size) { return x % size; } -inline __int64 fmod(__int64 x, __int64 size) { return x % size; } -inline unsigned __int64 fmod(unsigned __int64 x, unsigned __int64 size) { return x % size; } -inline float __cdecl fmod(float x, float y) { return fmodf(x, y); } - -// calcMaxMipmap -// calculates max # of mipmap levels for given texture size -inline size_t calcMaxMipmap(size_t w, size_t h) -{ - size_t n = 0; - size_t count = 0; - count = w > h ? w : h; - while (count) - { - n++; - count >>= 1; - } - return n; -} - -inline size_t calcMaxMipmap(size_t w, size_t h, size_t d) -{ - size_t n = 0; - size_t count = 0; - count = w > h ? w : h; - if (d > count) - count = d; - while (count) - { - n++; - count >>= 1; - } - return n; -} - -// get next mip level size -inline size_t NextMip(size_t m) -{ - size_t next = m / 2; // round down - if (next == 0) - return 1; - else - return next; -} - -// lo = 0; -// allow hi value -template -inline _Type Modulo(const _Type& x, const _Type& hi) -{ - if (x >= 0 && x <= hi) - return x; - _Type f = fmod(x, hi); - if (f < 0) - f += hi; - return f; -} - -// does not allow x == size -inline int iModulo(int x, int size) -{ - if (x < 0) - { - int n = x / size; - x += size * (n + 1); - } - return x % size; -} - -template -inline _Type Modulo(const _Type& x, const _Type& lo, const _Type& hi) -{ - if (x >= lo && x <= hi) - return x; - _Type dw = hi - lo; - _Type t = x - lo; - _Type f = fmod(t, dw); - if (f < 0) - f += dw; - f += lo; - return f; -} -} - -#pragma pack(push, 4) - -// red and green -class v16u16_t -{ -public: - union - { - short uv[4]; - struct - { - short u; - short v; - }; - }; - - v16u16_t& operator+=(const v16u16_t& v); // incrementation by a Vec4f - - void set(unsigned short _u, unsigned short _v) - { - u = _u; - v = _v; - } -}; - -class r12g12b8_t -{ -public: - union - { - struct - { - unsigned long r : 12; - unsigned long g : 12; - unsigned long b : 8; - }; - }; - - r12g12b8_t& operator+=(const r12g12b8_t& v); // incrementation by a Vec4f - - void set(unsigned long _r, unsigned long _g, unsigned long _b) - { - r = _r; - g = _g; - b = _b; - } -}; - -class rgba_t -{ -public: - union - { - unsigned long u; - unsigned char p[4]; - struct - { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - }; - }; - - rgba_t() {} - rgba_t(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) - { - a = _a; - r = _r; - g = _g; - b = _b; - } - - unsigned long bgra() - { - return (unsigned long)a << 24 | (unsigned long)r << 16 | (unsigned long)g << 8 | (unsigned long)b; - } - - rgba_t& operator+=(const rgba_t& v) // incrementation by a rgba_t - { - r = (unsigned char)nv::Clamp((int)((int)r + (int)v.r), 0, 255); - g = (unsigned char)nv::Clamp((int)g + (int)v.g, 0, 255); - b = (unsigned char)nv::Clamp((int)b + (int)v.b, 0, 255); - a = (unsigned char)nv::Clamp((int)a + (int)v.a, 0, 255); - return *this; - } - - rgba_t& operator-=(const rgba_t& v); // decrementation by a rgba_t - rgba_t& operator*=(const float d); // multiplication by a constant - rgba_t& operator/=(const float d); // division by a constant - - rgba_t& operator=(const rgba_t& v) - { - r = v.r; - g = v.g; - b = v.b; - a = v.a; - return *this; - } - - friend rgba_t operator+(const rgba_t& v1, const rgba_t& v2) - { - int r = nv::Clamp((int)v1.r + (int)v2.r, 0, 255); - int g = nv::Clamp((int)v1.g + (int)v2.g, 0, 255); - int b = nv::Clamp((int)v1.b + (int)v2.b, 0, 255); - int a = nv::Clamp((int)v1.a + (int)v2.a, 0, 255); - return rgba_t((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); - } - - friend rgba_t operator/(const rgba_t& v, float s) - { - return rgba_t( - (unsigned char)(v.r / s), (unsigned char)(v.g / s), (unsigned char)(v.b / s), (unsigned char)(v.a / s)); - } - - friend rgba_t operator/(const rgba_t& v, int s) - { - return rgba_t( - (unsigned char)(v.r / s), (unsigned char)(v.g / s), (unsigned char)(v.b / s), (unsigned char)(v.a / s)); - } - - void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) - { - r = _r; - g = _g; - b = _b; - a = _a; - } - - void SetToZero() { r = g = b = a = 0; } -}; - -class rgba16_t -{ -public: - union - { - unsigned short rgba[4]; - struct - { - unsigned short r; - unsigned short g; - unsigned short b; - unsigned short a; - }; - }; - - rgba16_t() {} - rgba16_t(unsigned short _r, unsigned short _g, unsigned short _b, unsigned short _a) - { - a = _a; - r = _r; - g = _g; - b = _b; - } - - rgba16_t& operator+=(const rgba16_t& v) // incrementation by a rgba_t - { - r = (unsigned char)nv::Clamp((int)r + (int)v.r, 0, 65535); - g = (unsigned char)nv::Clamp((int)g + (int)v.g, 0, 65535); - b = (unsigned char)nv::Clamp((int)b + (int)v.b, 0, 65535); - a = (unsigned char)nv::Clamp((int)a + (int)v.a, 0, 65535); - return *this; - } - - rgba16_t& operator-=(const rgba16_t& v); // decrementation by a rgba_t - rgba16_t& operator*=(const float d); // multiplication by a constant - rgba16_t& operator/=(const float d); // division by a constant - - rgba16_t& operator=(const rgba16_t& v) - { - r = v.r; - g = v.g; - b = v.b; - a = v.a; - return *this; - } - - friend rgba16_t operator+(const rgba16_t& v1, const rgba16_t& v2) - { - int r = nv::Clamp((int)v1.r + (int)v2.r, 0, 65535); - int g = nv::Clamp((int)v1.g + (int)v2.g, 0, 65535); - int b = nv::Clamp((int)v1.b + (int)v2.b, 0, 65535); - int a = nv::Clamp((int)v1.a + (int)v2.a, 0, 65535); - return rgba16_t((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); - } - - friend rgba16_t operator/(const rgba16_t& v, float s) - { - return rgba16_t( - (unsigned short)(v.r / s), (unsigned short)(v.g / s), (unsigned short)(v.b / s), (unsigned short)(v.a / s)); - } - - friend rgba16_t operator/(const rgba16_t& v, int s) - { - return rgba16_t( - (unsigned short)(v.r / s), (unsigned short)(v.g / s), (unsigned short)(v.b / s), (unsigned short)(v.a / s)); - } - - void set(unsigned short _r, unsigned short _g, unsigned short _b, unsigned short _a) - { - r = _r; - g = _g; - b = _b; - a = _a; - } -}; - -class urgba_t -{ -public: - union - { - unsigned long u; - char rgba[4]; - struct - { - char r; - char g; - char b; - char a; - }; - }; - - urgba_t& operator+=(const urgba_t& v); // incrementation by a Vec4f - - void set(char _r, char _g, char _b, char _a) - { - r = _r; - g = _g; - b = _b; - a = _a; - } -}; - -class q8w8v8u8_t -{ -public: - union - { - char qwvu[4]; - struct - { - char q; - char w; - char v; - char u; - }; - }; - - q8w8v8u8_t& operator+=(const q8w8v8u8_t& v); // incrementation by a Vec4f - - void set(char _r, char _g, char _b, char _a) - { - q = _r; - w = _g; - v = _b; - u = _a; - } -}; - -class fpPixel -{ -public: - union - { - float p[4]; - struct - { - float r; - float g; - float b; - float a; - }; - struct - { - float x; - float y; - float z; - float w; - }; - }; - - void SetToZero() - { - r = 0; - g = 0; - b = 0; - a = 0; - } - - void Clamp(fpPixel& lo, fpPixel& hi) - { - r = nv::Clamp(r, lo.r, hi.r); - g = nv::Clamp(g, lo.g, hi.g); - b = nv::Clamp(b, lo.b, hi.b); - a = nv::Clamp(a, lo.a, hi.a); - } - - void Wrap(fpPixel& lo, fpPixel& hi) - { - r = nv::Modulo(r, lo.r, hi.r); - g = nv::Modulo(g, lo.g, hi.g); - b = nv::Modulo(b, lo.b, hi.b); - a = nv::Modulo(a, lo.a, hi.a); - } - - void dot(fpPixel& w) - { - float grey = r * w.r + g * w.g + b * w.b + a * w.a; - r = grey; - g = grey; - b = grey; - } - - fpPixel() {} - fpPixel(const float _r, const float _g, const float _b, const float _a) - { - a = _a; - r = _r; - g = _g; - b = _b; - } - - fpPixel(const fpPixel& v) - { - a = v.a; - r = v.r; - g = v.g; - b = v.b; - } - - void set(const float _r, const float _g, const float _b, const float _a) - { - a = _a; - r = _r; - g = _g; - b = _b; - } - - void set(const fpPixel& v) - { - a = v.a; - r = v.r; - g = v.g; - b = v.b; - } - - fpPixel& operator+=(const fpPixel& v) // incrementation by a rgba_t - { - r += v.r; - g += v.g; - b += v.b; - a += v.a; - return *this; - } - - fpPixel& operator-=(const fpPixel& v) // incrementation by a rgba_t - { - r -= v.r; - g -= v.g; - b -= v.b; - a -= v.a; - return *this; - } - - fpPixel& operator*=(const fpPixel& v) // incrementation by a rgba_t - { - r *= v.r; - g *= v.g; - b *= v.b; - a *= v.a; - return *this; - } - - fpPixel& operator/=(const fpPixel& v) // incrementation by a rgba_t - { - r /= v.r; - g /= v.g; - b /= v.b; - a /= v.a; - return *this; - } - - fpPixel& operator/=(const float& s) // incrementation by a rgba_t - { - r /= s; - g /= s; - b /= s; - a /= s; - return *this; - } - - fpPixel& operator=(const fpPixel& v); // assignment of a Vec3f - - friend fpPixel operator+(const fpPixel& v1, const fpPixel& v2) - { - return fpPixel(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a); - } - - friend fpPixel operator/(const fpPixel& v, float s) { return fpPixel(v.r / s, v.g / s, v.b / s, v.a / s); } - friend int operator==(const fpPixel& v1, const fpPixel& v2); - - NV_ERROR_CODE normalize() - { - double u = x * x + y * y + z * z; - if (fabs(u - 1.0) < 1e-12) - return NV_OK; // already normalized - if (fabs((double)u) < 1e-12) - { - x = y = z = 0.0f; - return NV_CANT_NORMALIZE; - } - u = 1.0 / sqrt(u); - x = (float)(x * u); - y = (float)(y * u); - z = (float)(z * u); - return NV_OK; - } -}; - -class fpPixel3 -{ -public: - union - { - float p[3]; - struct - { - float r; - float g; - float b; - }; - struct - { - float x; - float y; - float z; - }; - }; - - void SetToZero() - { - r = 0; - g = 0; - b = 0; - } - - fpPixel3() {} - fpPixel3(const float _r, const float _g, const float _b) - { - r = _r; - g = _g; - b = _b; - } - - fpPixel3(const fpPixel3& v) - { - r = v.r; - g = v.g; - b = v.b; - } - - void set(const float _r, const float _g, const float _b) - { - r = _r; - g = _g; - b = _b; - } - - void set(const fpPixel3& v) - { - r = v.r; - g = v.g; - b = v.b; - } - - fpPixel3& operator+=(const fpPixel3& v); // incrementation by a Vec4f - fpPixel3& operator=(const fpPixel3& v); // assignment of a Vec3f - fpPixel3& operator-=(const fpPixel3& v); // decrementation by a Vec3f - fpPixel3& operator*=(const float d); // multiplication by a constant - fpPixel3& operator/=(const float d); // division by a constant - - friend fpPixel3 operator+(const fpPixel3& v1, const fpPixel3& v2) - { - return fpPixel3(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b); - } - - friend fpPixel3 operator/(const fpPixel3& v, float s) { return fpPixel3(v.r / s, v.g / s, v.b / s); } - friend int operator==(const fpPixel3& v1, const fpPixel3& v2); - - NV_ERROR_CODE normalize() - { - double u = x * x + y * y + z * z; - if (fabs(u - 1.0) < 1e-12) - return NV_OK; // already normalized - if (fabs((double)u) < 1e-12) - { - x = y = z = 0.0f; - return NV_CANT_NORMALIZE; - } - u = 1.0 / sqrt(u); - x = (float)(x * u); - y = (float)(y * u); - z = (float)(z * u); - return NV_OK; - } -}; - -typedef fpPixel* fp_i; - -inline int operator==(const fpPixel& v1, const fpPixel& v2) -{ - return v1.a == v2.a && v1.r == v2.r && v1.b == v2.b && v1.g == v2.g; -} - -inline fpPixel& fpPixel::operator=(const fpPixel& v) -{ - a = v.a; - r = v.r; - g = v.g; - b = v.b; - return *this; -} - -template -class nvImage -{ -private: - size_t m_width; - size_t m_height; - nvVector<_Type> m_pixels; - bool m_RGBE; - -public: - void SetRGBE(bool b) { m_RGBE = b; } - bool isRGBE() const { return m_RGBE; } - size_t size() { return m_width * m_height; } - nvImage<_Type>& operator=(const nvImage<_Type>& v) - { - // resize and copy over - resize(v.width(), v.height()); - m_pixels = v.m_pixels; - m_RGBE = v.m_RGBE; - return *this; - } - - _Type& operator[](size_t i) - { -#ifdef _DEBUG - assert(i < m_width * m_height); -#endif - return m_pixels[i]; - } - - const _Type& operator[](size_t i) const - { -#ifdef _DEBUG - assert(i < m_width * m_height); -#endif - return m_pixels[i]; - } - - _Type& operator()(const size_t& y, const size_t& x) - { -#if _DEBUG - assert(y < m_height); - assert(x < m_width); -#endif - return m_pixels[y * m_width + x]; - } - const _Type& operator()(const size_t& y, const size_t& x) const - { -#if _DEBUG - assert(y < m_height); - assert(x < m_width); -#endif - return m_pixels[y * m_width + x]; - } - - size_t width() const { return m_width; } - size_t height() const { return m_height; } - _Type* pixels(size_t n = 0) { return &m_pixels[n]; } - _Type* pixelsXY(size_t x, size_t y) { return &m_pixels[y * width() + x]; } - _Type* pixelsXY_Safe(size_t x, size_t y) - { - if (m_pixels.size() == 0) - return 0; - else - return &m_pixels[y * width() + x]; - } - - _Type* pixelsYX(size_t y, size_t x) { return &m_pixels[y * width() + x]; } - // row / column - _Type* pixelsRC(size_t y, size_t x) { return &m_pixels[y * width() + x]; } - _Type& pixel_ref(size_t n = 0) { return m_pixels[n]; } - _Type& pixelsXY_ref(size_t x, size_t y) { return m_pixels[y * width() + x]; } - _Type& pixelsYX_ref(size_t y, size_t x) { return m_pixels[y * width() + x]; } - // row / column - _Type& pixelsRC_ref(size_t y, size_t x) { return m_pixels[y * width() + x]; } - _Type* pixelsXY_wrapped(int x, int y) - { - y = mod(y, m_height); - x = mod(x, m_width); - return &m_pixels[y * m_width + x]; - } - - nvImage(const nvImage<_Type>& other) - { - m_width = other.m_width; - m_height = other.m_height; - m_pixels = other.m_pixels; - m_RGBE = other.m_RGBE; - } - - nvImage() - { - m_width = 0; - m_height = 0; - m_RGBE = false; - m_pixels.clear(); - } - - void clear() - { - m_width = 0; - m_height = 0; - m_pixels.clear(); - } - - void resize(size_t width, size_t height) - { - m_pixels.resize(width * height); - m_width = width; - m_height = height; - } - void realloc(size_t width, size_t height) - { - m_pixels.realloc(width * height); - m_width = width; - m_height = height; - } - - nvImage<_Type>(size_t width, size_t height) - { - m_pixels.resize(width * height); - m_width = width; - m_height = height; - m_RGBE = false; - } - - void SwapRB() - { - _Type* p = &m_pixels[0]; - _Type tmp; - for (size_t i = 0; i < m_width * m_height; i++) - { - tmp.r = p->r; - p->r = p->b; - p->b = tmp.r; - ++p; - } - } - - void Scale(_Type s) - { - _Type* p = &m_pixels[0]; - for (size_t i = 0; i < m_width * m_height; i++) - { - *p++ *= s; - } - } - - void Bias(_Type b) - { - _Type* p = &m_pixels[0]; - for (size_t i = 0; i < m_width * m_height; i++) - { - *p++ += b; - } - } - - void dot(_Type w) - { - _Type* p = &m_pixels[0]; - for (size_t i = 0; i < m_width * m_height; i++) - { - p->dot(w); - ++p; - } - } - - void Clamp(_Type low, _Type hi) - { - _Type* p = &m_pixels[0]; - for (size_t i = 0; i < m_width * m_height; i++) - { - p->Clamp(low, hi); - ++p; - } - } - - void Wrap(_Type low, _Type hi) - { - _Type* p = &m_pixels[0]; - for (size_t i = 0; i < m_width * m_height; i++) - { - p->Wrap(low, hi); - ++p; - } - } - - void FlipTopToBottom() - { - _Type* swap = new _Type[m_width]; - size_t row; - _Type* end_row; - _Type* start_row; - size_t len = sizeof(_Type) * m_width; - for (row = 0; row < m_height / 2; row++) - { - end_row = &m_pixels[m_width * (m_height - row - 1)]; - start_row = &m_pixels[m_width * row]; - // copy row toward end of image into temporary swap buffer - memcpy(swap, end_row, len); - // copy row at beginning to row at end - memcpy(end_row, start_row, len); - // copy old bytes from row at end (in swap) to row at beginning - memcpy(start_row, swap, len); - } - delete[] swap; - } - - void SetToZero() - { - for (size_t i = 0; i < m_width * m_height; i++) - { - pixel_ref(i).SetToZero(); - } - } - void SetToZeroDirect() - { - for (size_t i = 0; i < m_width * m_height; i++) - { - m_pixels[i] = 0; - } - } -}; - -typedef nvImage RGBAImage; -typedef nvVector RGBAImageArray; - -class RGBAMipMappedImage -{ -private: - RGBAImageArray mipArray; // array of images, one for each MIP map RGBA - -public: - void resize(size_t width, size_t height, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height); - mipArray.resize(nMIPMaps); - for (size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) - { - RGBAImage& mip = mipArray[mipLevel]; - mip.resize(width, height); - width = nv::NextMip(width); - height = nv::NextMip(height); - } - } - - RGBAMipMappedImage() {} - RGBAMipMappedImage(int width, int height, int nMIPMaps) { resize(width, height, nMIPMaps); } - RGBAImage& operator[](size_t i) { return mipArray[i]; } - const RGBAImage& operator[](size_t i) const { return mipArray[i]; } - size_t numMIPMaps() const { return mipArray.size(); } - void resize(size_t size) { mipArray.resize(size); } - void realloc(size_t size) { mipArray.realloc(size); } - size_t width() const - { - if (mipArray.size() == 0) - return 0; - return mipArray[0].width(); - } - - size_t height() const - { - if (mipArray.size() == 0) - return 0; - return mipArray[0].height(); - } - - void clear() { mipArray.clear(); } -}; - -class RGBAMipMappedCubeMap -{ -private: - RGBAMipMappedImage cubeFaces[6]; // array of images, one for each MIP map RGBA - -public: - void resize(size_t width, size_t height, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height); - for (int f = 0; f < 6; f++) - { - RGBAMipMappedImage& mipFace = cubeFaces[f]; - mipFace.resize(width, height, nMIPMaps); - } - } - - RGBAMipMappedCubeMap() {} - RGBAMipMappedCubeMap(size_t width, size_t height, size_t nMIPMaps) { resize(width, height, nMIPMaps); } - RGBAMipMappedImage& operator[](size_t i) { return cubeFaces[i]; } - const RGBAMipMappedImage& operator[](size_t i) const { return cubeFaces[i]; } - size_t numMIPMaps() const { return cubeFaces[0].numMIPMaps(); } - size_t height() const { return cubeFaces[0].height(); } - size_t width() const { return cubeFaces[0].width(); } - void clear() - { - for (size_t f = 0; f < 6; f++) - { - RGBAMipMappedImage& mipFace = cubeFaces[f]; - mipFace.clear(); - } - } -}; - -typedef nvVector RGBAVolume; - -class RGBAMipMappedVolumeMap -{ -private: - RGBAVolume volumeArray; // array of MIP mapped images - -public: - void resize(size_t width, size_t height, size_t depth, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height, depth); - volumeArray.resize(nMIPMaps); - size_t w = width; - size_t h = height; - size_t d = depth; - for (size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) - { - RGBAImageArray& volImage = volumeArray[mipLevel]; - volImage.resize(d); - for (size_t slice = 0; slice < d; slice++) - { - RGBAImage& mipFace = volImage[slice]; - mipFace.resize(w, h); - } - w = nv::NextMip(w); - h = nv::NextMip(h); - d = nv::NextMip(d); - } - } - - RGBAMipMappedVolumeMap() {} - RGBAMipMappedVolumeMap(size_t width, size_t height, size_t depth, size_t nMIPMaps) - { - resize(width, height, depth, nMIPMaps); - } - - // mip level - RGBAImageArray& operator[](size_t i) { return volumeArray[i]; } - const RGBAImageArray& operator[](size_t i) const { return volumeArray[i]; } - size_t numMIPMaps() const { return volumeArray.size(); } - const RGBAImageArray* vol0() const - { - if (numMIPMaps() == 0) - return 0; - return &volumeArray[0]; - } - - const RGBAImage* slice0() const - { - const RGBAImageArray* v0 = vol0(); - if (v0 == 0) - return 0; - if (v0->size() == 0) - return 0; - const RGBAImageArray& array = *v0; - return &array[0]; - } - - size_t width() const - { - const RGBAImage* image0 = slice0(); - if (image0 == 0) - return 0; - else - return image0->width(); - } - - size_t height() const - { - const RGBAImage* image0 = slice0(); - if (image0 == 0) - return 0; - else - return image0->height(); - } - - size_t depth() const - { - const RGBAImageArray* v0 = vol0(); - if (v0 == 0) - return 0; - return v0->size(); - } -}; - -typedef nvMatrix floatImage; -typedef nvMatrix fpImage; -typedef nvMatrix fpImage3; -typedef nvVector fpImageArray; - -class fpMipMappedImage -{ - fpImageArray mipArray; // array of images, one for each MIP map RGBA - -public: - fpMipMappedImage() {} - fpMipMappedImage(size_t width, size_t height, size_t nMIPMaps) { resize(width, height, nMIPMaps); } - // copy constructor - fpMipMappedImage(const fpMipMappedImage& v) - { - // copy the images over - mipArray.resize(v.mipArray.size()); - for (size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) - { - fpImage& dst = mipArray[mipLevel]; - const fpImage& src = v.mipArray[mipLevel]; - dst = src; - } - } - - void resize(size_t width, size_t height, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height); - mipArray.resize(nMIPMaps); - for (size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) - { - fpImage& mip = mipArray[mipLevel]; - mip.resize(width, height); - width = nv::NextMip(width); - height = nv::NextMip(height); - } - } - - void FlipTopToBottom() - { - // copy the images over - for (size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) - { - fpImage& mip = mipArray[mipLevel]; - mip.FlipTopToBottom(); - } - } - - fpImage& operator[](size_t i) { return mipArray[i]; } - const fpImage& operator[](size_t i) const { return mipArray[i]; } - void SetToZero() - { - for (size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) - { - fpImage& mip = mipArray[mipLevel]; - mip.SetToZero(); - } - } - - void clear() { mipArray.clear(); } - void realloc(size_t size) { mipArray.realloc(size); } - void resize(size_t nMIPLevels) { mipArray.resize(nMIPLevels); } - size_t numMIPMaps() const { return mipArray.size(); } - size_t width() const { return mipArray[0].width(); } - size_t height() const { return mipArray[0].height(); } -}; - -class fpMipMappedCubeMap -{ -private: - fpMipMappedImage cubeFaces[6]; // array of images, one for each MIP map RGBA - -public: - void resize(size_t width, size_t height, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height); - for (size_t f = 0; f < 6; f++) - { - fpMipMappedImage& mipFace = cubeFaces[f]; - mipFace.resize(width, height, nMIPMaps); - } - } - - fpMipMappedCubeMap() {} - fpMipMappedCubeMap(int width, int height, int nMIPMaps) { resize(width, height, nMIPMaps); } - fpMipMappedImage& operator[](size_t i) { return cubeFaces[i]; } - const fpMipMappedImage& operator[](size_t i) const { return cubeFaces[i]; } - size_t numMIPMaps() const { return cubeFaces[0].numMIPMaps(); } - size_t height() const { return cubeFaces[0].height(); } - size_t width() const { return cubeFaces[0].width(); } - void clear() - { - for (size_t f = 0; f < 6; f++) - { - fpMipMappedImage& mipFace = cubeFaces[f]; - mipFace.clear(); - } - } - - void FlipTopToBottom() - { - for (size_t f = 0; f < 6; f++) - { - fpMipMappedImage& mipFace = cubeFaces[f]; - mipFace.FlipTopToBottom(); - } - } -}; - -// mip level, array -typedef nvVector fpVolume; - -class fpMipMappedVolumeMap -{ -private: - // array of MIP mapped images - fpVolume volumeArray; - -public: - void resize(size_t width, size_t height, size_t depth, size_t nMIPMaps) - { - if (nMIPMaps == 0) - nMIPMaps = nv::calcMaxMipmap(width, height, depth); - volumeArray.resize(nMIPMaps); - size_t w = width; - size_t h = height; - size_t d = depth; - for (size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) - { - fpImageArray& volImage = volumeArray[mipLevel]; - volImage.resize(d); - for (size_t slice = 0; slice < d; slice++) - { - fpImage& mipFace = volImage[slice]; - mipFace.resize(w, h); - } - w = nv::NextMip(w); - h = nv::NextMip(h); - d = nv::NextMip(d); - } - } - - void FlipTopToBottom() - { - for (size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) - { - fpImageArray& volImage = volumeArray[mipLevel]; - for (size_t slice = 0; slice < volImage.size(); slice++) - { - fpImage& mipFace = volImage[slice]; - mipFace.FlipTopToBottom(); - } - } - } - - void realloc(size_t size) { volumeArray.realloc(size); } - fpMipMappedVolumeMap() {} - fpMipMappedVolumeMap(size_t width, size_t height, size_t depth, size_t nMIPMaps) - { - resize(width, height, depth, nMIPMaps); - } - - // mip level - fpImageArray& operator[](size_t i) { return volumeArray[i]; } - const fpImageArray& operator[](size_t i) const { return volumeArray[i]; } - size_t numMIPMaps() const { return volumeArray.size(); } - const fpImageArray* vol0() const - { - if (numMIPMaps() == 0) - return 0; - return &volumeArray[0]; - } - - const fpImage* slice0() const - { - const fpImageArray* v0 = vol0(); - if (v0 == 0) - return 0; - if (v0->size() == 0) - return 0; - const fpImageArray& array = *v0; - return &array[0]; - } - - size_t width() const - { - const fpImage* image0 = slice0(); - if (image0 == 0) - return 0; - else - return image0->width(); - } - - size_t height() const - { - const fpImage* image0 = slice0(); - if (image0 == 0) - return 0; - else - return image0->height(); - } - - size_t depth() const - { - const fpImageArray* v0 = vol0(); - if (v0 == 0) - return 0; - return v0->size(); - } - - void clear() { volumeArray.clear(); } -}; -#pragma pack(pop) - -#include diff --git a/src/utils/xrDXT/dds/tVector.h b/src/utils/xrDXT/dds/tVector.h deleted file mode 100644 index 823002a9a07..00000000000 --- a/src/utils/xrDXT/dds/tVector.h +++ /dev/null @@ -1,478 +0,0 @@ -#pragma once -#include - -template -class nvMatrix -{ -private: - _Type** m; - size_t rows, cols; - -public: - nvMatrix() - { - rows = 0; - cols = 0; - m = 0; - } - - nvMatrix(const nvMatrix& v) - { - rows = 0; - cols = 0; - m = 0; - resize(v.width(), v.height()); - for (size_t i = 0; i < v.rows; i++) - { - for (size_t j = 0; j < v.cols; j++) - m[i][j] = v.m[i][j]; - } - } - - nvMatrix(size_t width, size_t height) - { - m = 0; - rows = 0; - cols = 0; - resize(width, height); - } - - ~nvMatrix() { tvfree(); } - _Type& operator[](size_t i) - { - size_t r = i / cols; - size_t c = i % cols; -#if _DEBUG - assert(r < rows); - assert(c < cols); -#endif - return m[r][c]; - } - - _Type* pixels(size_t i = 0) - { - size_t r = i / cols; - size_t c = i % cols; -#if _DEBUG - assert(r < rows); - assert(c < cols); -#endif - return &m[r][c]; - } - - _Type& operator()(const size_t& r, const size_t& c) const - { -#if _DEBUG - assert(r < rows); - assert(c < cols); -#endif - return m[r][c]; - } - - _Type& operator()(const size_t& r, const size_t& c) - { -#if _DEBUG - assert(r < rows); - assert(c < cols); -#endif - return m[r][c]; - } - - _Type* pixelsRC(size_t r, size_t c) - { -#if _DEBUG - assert(r < rows); - assert(c < cols); -#endif - return &m[r][c]; - } - - _Type* pixelsXY(size_t x, size_t y) - { -#if _DEBUG - assert(y < rows); - assert(x < cols); -#endif - return &m[y][x]; - } - - _Type* pixelsYX(size_t y, size_t x) - { -#if _DEBUG - assert(y < rows); - assert(x < cols); -#endif - return &m[y][x]; - } - - _Type* pixelsXY_wrapped(int x, int y) - { - y = iModulo(y, (int)rows); - x = iModulo(x, (int)cols); - return &m[y][x]; - } - - size_t width() const { return cols; } - size_t height() const { return rows; } - void tvfree() - { - if (m) - { - for (size_t i = 0; i < rows; i++) - delete[] m[i]; - delete[] m; - m = 0; - rows = 0; - cols = 0; - } - } - - void tvallocate(size_t r, size_t c) - { - assert(m == NULL); - rows = r; - cols = c; - if (r == 0 || c == 0) - return; - m = new _Type*[r]; - for (size_t i = 0; i < r; i++) - { - m[i] = new _Type[c]; - } - } - - nvMatrix& operator=(const nvMatrix& v) - { - resize(v.width(), v.height()); - for (size_t i = 0; i < v.rows; i++) - { - for (size_t j = 0; j < v.cols; j++) - m[i][j] = v.m[i][j]; - } - return *this; - } - - void SetToZero() - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j].SetToZero(); - } - } - - // destructive - void resize(size_t width, size_t height) - { - if (height != rows || width != cols) - { - tvfree(); - tvallocate(height, width); - } - } - - void Release() { tvfree(); } - void clear() { tvfree(); } - size_t size() const { return rows * cols; } - void FlipTopToBottom() - { - _Type* swap = new _Type[cols]; - size_t row; - int end_row; - int start_row; - size_t len = sizeof(_Type) * cols; - for (row = 0; row < rows / 2; row++) - { - end_row = rows - row - 1; - start_row = row; - // copy row toward end of image into temporary swap buffer - for (size_t i = 0; i < cols; i++) - swap[i] = m[end_row][i]; - // copy row at beginning to row at end - for (size_t i = 0; i < cols; i++) - m[end_row][i] = m[start_row][i]; - // copy old bytes from row at end (in swap) to row at beginning - for (size_t i = 0; i < cols; i++) - m[start_row][i] = swap[i]; - } - delete[] swap; - } - - void Scale(_Type s) - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j] *= s; - } - } - - void Bias(_Type s) - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j] += s; - } - } - - void dot(_Type w) - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j].dot(w); - } - } - - void Clamp(_Type low, _Type hi) - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j].Clamp(low, hi); - } - } - - void Wrap(_Type low, _Type hi) - { - for (size_t i = 0; i < rows; i++) - { - for (size_t j = 0; j < cols; j++) - m[i][j].Wrap(low, hi); - } - } -}; - -#include - -template -class nvVector -{ -public: - // Ctor. - nvVector() : m_buffer(NULL), m_size(0), m_buffer_size(0) {} - // Copy ctor. - nvVector(const nvVector& a) : m_buffer(NULL), m_size(0), m_buffer_size(0) { copy(a.m_buffer, a.m_size); } - // Ctor that initializes the array with the given elements. - nvVector(const T* ptr, size_t num) : m_buffer(NULL), m_size(0), m_buffer_size(0) { copy(ptr, num); } - // Dtor. - ~nvVector() - { - clear(); - allocate(0); - } - - // Const and save array access. - const T& operator[](size_t index) const - { - assert(index < m_size); - return m_buffer[index]; - } - - // Safe array access. - T& operator[](size_t index) - { - assert(index < m_size); - return m_buffer[index]; - } - - // Get array size. - size_t size() const { return m_size; } - // Push an element at the end of the array. - void push_back(const T& val) - { - // DO NOT pass elements of your own vector into - // push_back()! Since we're using references, - // resize() may munge the element storage! - assert(&val < &m_buffer[0] || &val > &m_buffer[m_size]); - int new_size = m_size + 1; - resize(new_size); - m_buffer[new_size - 1] = val; - } - - // Pop and return element at the end of the array. - void pop_back() - { - assert(m_size > 0); - resize(m_size - 1); - } - - // Get back element. - const T& back() const - { - assert(m_size > 0); - return m_buffer[m_size - 1]; - } - - // Get back element. - T& back() - { - assert(m_size > 0); - return m_buffer[m_size - 1]; - } - - // Get back element. - const T& front() const - { - assert(m_size > 0); - return m_buffer[0]; - } - - // Get back element. - T& front() - { - assert(m_size > 0); - return m_buffer[0]; - } - - // nvVector semantics: realloc preserves contents, resize does not. - void realloc(size_t new_size) { resize(new_size); } - // Resize the array preserving existing elements. - void resize(size_t new_size) - { - size_t old_size = m_size; - m_size = new_size; - // Destruct old elements (if we're shrinking). - for (size_t i = new_size; i < old_size; i++) - { - (m_buffer + i)->~T(); // Explicit call to the destructor - } - if (m_size == 0) - { - if (false) // Don't shrink automatically. - { - allocate(0); - } - } - else if (m_size <= m_buffer_size && m_size > m_buffer_size >> 1) - { - // don't compact yet. - assert(m_buffer != NULL); - } - else - { - size_t new_buffer_size; - if (m_buffer_size == 0) - { - // first allocation - new_buffer_size = m_size; - } - else - { - // growing - new_buffer_size = m_size + (m_size >> 2); - } - allocate(new_buffer_size); - } - - // Call default constructors - for (size_t i = old_size; i < new_size; i++) - { - new (m_buffer + i) T(); // placement new - } - } - - // Resize the array preserving existing elements and initializing the - // new ones with the given value. - void resize(size_t new_size, const T& elem) - { - size_t old_size = m_size; - m_size = new_size; - // Destruct old elements (if we're shrinking). - for (size_t i = new_size; i < old_size; i++) - { - (m_buffer + i)->~T(); // Explicit call to the destructor - } - - if (m_size == 0) - { - if (false) // Don't shrink automatically. - { - allocate(0); - } - } - else if (m_size <= m_buffer_size && m_size > m_buffer_size >> 1) - { - // don't compact yet. - assert(m_buffer != NULL); - } - else - { - size_t new_buffer_size; - if (m_buffer_size == 0) - { - // first allocation - new_buffer_size = m_size; - } - else - { - // growing - new_buffer_size = m_size + (m_size >> 2); - } - allocate(new_buffer_size); - } - // Call copy constructors - for (size_t i = old_size; i < new_size; i++) - { - new (m_buffer + i) T(elem); // placement new - } - } - - // Clear the buffer. - void clear() { resize(0); } - // Shrink the allocated array. - void shrink() - { - if (m_size < m_buffer_size) - { - allocate(m_size); - } - } - - // Preallocate space. - void reserve(size_t desired_size) - { - if (desired_size > m_buffer_size) - { - allocate(desired_size); - } - } - - // Assignment operator. - void operator=(const nvVector& a) { copy(a.m_buffer, a.m_size); } -private: - // Change buffer size. - void allocate(size_t rsize) - { - m_buffer_size = rsize; - // free the buffer. - if (m_buffer_size == 0) - { - if (m_buffer) - { - free(m_buffer); - m_buffer = NULL; - } - } - else // realloc the buffer - { - m_buffer = (T*)::realloc(m_buffer, sizeof(T) * m_buffer_size); - } - } - - // Copy memory to our array. Resizes the array if needed. - void copy(const T* ptr, size_t num) - { - resize(num); - for (size_t i = 0; i < m_size; i++) - { - m_buffer[i] = ptr[i]; - } - } - -private: - T* m_buffer; - size_t m_size; - size_t m_buffer_size; -}; diff --git a/src/utils/xrLC/ArbitraryList.h b/src/utils/xrLC/ArbitraryList.h deleted file mode 100644 index dc772ab5000..00000000000 --- a/src/utils/xrLC/ArbitraryList.h +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright (C) Tom Forsyth, 2001. - * All rights reserved worldwide. - * - * This software is provided "as is" without express or implied - * warranties. You may freely copy and compile this source into - * applications you distribute provided that the copyright text - * below is included in the resulting source code, for example: - * "Portions Copyright (C) Tom Forsyth, 2001" - */ -// Some standard useful classes, templates, etc. - -#ifndef ArbitraryListH -#define ArbitraryListH - -// An arbitrary-sized list template class. -// Designed to hold _unsorted_ data, but only RemoveItem() -// actually disturbs the order, so you can use it for general arrays -// if you don't use that function. -template -class ArbitraryList -{ - T* pT; // The list. - u32 iSize; // The current size of the list. - u32 iReservedSize; // The current reserved size of the list. -public: - // Constructor, with optional initial size setting. - ArbitraryList(u32 iInitialSize = 0) - { - pT = NULL; - iSize = 0; - iReservedSize = 0; - if (iInitialSize > 0) - resize(iInitialSize); - } - // Destructor. - ~ArbitraryList(void) - { - if (pT == NULL) - { - VERIFY(iReservedSize == 0); - VERIFY(iSize == 0); - } - else - { - VERIFY(iReservedSize > 0); - VERIFY(iSize > 0); - delete[] pT; - pT = NULL; - } - } - // Returns the pointer to the given item. - IC T* item(u32 iItem) - { - VERIFY(iItem < iSize); - return (&pT[iItem]); - } - // Returns the pointer to the first item. - IC T* ptr() { return (pT); } - // Returns the size of the list - IC u32 size() const { return iSize; } - // Grows or shrinks the list to this number of items. - // Preserves existing items. - // Items that fall off the end of a shrink may vanish. - // Returns the pointer to the first item. - IC T* resize(u32 iNum) - { - VERIFY(iNum >= 0); - iSize = iNum; - if (iNum <= iReservedSize) - { - if (iNum == 0) - { - // Shrunk to 0 - bin the memory. - delete[] pT; - pT = NULL; - iReservedSize = 0; - } - else - { - VERIFY(pT != NULL); - } - return (pT); - } - else - { - // Need to grow. Grow by 50% more than - // needed to avoid constant regrows. - u32 iNewSize = (iNum * 3) >> 1; - if (pT == NULL) - { - VERIFY(iReservedSize == 0); - pT = new T[iNewSize]; - } - else - { - VERIFY(iReservedSize != 0); - - T* pOldT = pT; - pT = new T[iNewSize]; - for (u32 i = 0; i < iReservedSize; i++) - { - pT[i] = pOldT[i]; - } - delete[] pOldT; - } - VERIFY(pT != NULL); - iReservedSize = iNewSize; - return (pT); - } - } - // Adds one item to the list and returns a pointer to that new item. - IC T* append() - { - resize(iSize + 1); - return (&pT[iSize - 1]); - } - // Adds one item to the list and returns a pointer to that new item. - IC void push_back(T& val) - { - resize(iSize + 1); - pT[iSize - 1] = val; - } - // Removes the given item number by copying the last item - // to that position and shrinking the list. - IC void erase_fast(u32 iItemNumber) - { - VERIFY(iItemNumber < iSize); - pT[iItemNumber] = pT[iSize - 1]; - resize(iSize - 1); - } - // Copy the specified data into the list. - IC void insert(u32 iFirstItem, T* p, u32 iNumItems) - { - for (u32 i = 0; i < iNumItems; i++) - *(Item(i + iFirstItem)) = p[i]; - } - // A copy from another arbitrary list of the same type. - IC void insert(u32 iFirstItem, ArbitraryList& other, u32 iFirstOtherItem, u32 iNumItems) - { - for (u32 i = 0; i < iNumItems; i++) - *(item(i + iFirstItem)) = *(other.item(i + iFirstOtherItem)); - } - IC T& operator[](u32 id) - { - VERIFY(id < iSize); - return pT[id]; - } - IC const T& operator[](u32 id) const - { - VERIFY(id < iSize); - return pT[id]; - } - - // Copy constructor. - ArbitraryList(const ArbitraryList& other) - { - u32 iNumItems = other.size(); - - pT = NULL; - iSize = 0; - iReservedSize = 0; - if (iNumItems > 0) - resize(iNumItems); - for (u32 i = 0; i < iNumItems; i++) - *(item(i)) = other[i]; - } -}; - -#endif //#ifndef ArbitraryListH diff --git a/src/utils/xrLC/Build.cpp b/src/utils/xrLC/Build.cpp deleted file mode 100644 index 875629f9407..00000000000 --- a/src/utils/xrLC/Build.cpp +++ /dev/null @@ -1,406 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "utils/xrLC_Light/xrMU_Model.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" -#include "utils/xrLC_Light/mu_model_light.h" -#include "utils/xrLC_Light/net_cl_data_prepare.h" -#include "utils/xrLC_Light/serialize.h" - -void calc_ogf(xrMU_Model& mu_model); -void export_geometry(xrMU_Model& mu_model); - -void export_ogf(xrMU_Reference& mu_reference); - -using namespace std; -struct OGF_Base; -xr_vector g_tree; - -// BOOL b_noise = FALSE; -// BOOL b_radiosity = FALSE; -// BOOL b_net_light = FALSE; -SBuildOptions g_build_options; -vec2Face g_XSplit; - -void CBuild::CheckBeforeSave(u32 stage) -{ - bool b_g_tree_empty = g_tree.empty(); - R_ASSERT(b_g_tree_empty); - bool b_g_XSplit_empty = g_XSplit.empty(); - R_ASSERT(b_g_XSplit_empty); - bool b_IsOGFContainersEmpty = IsOGFContainersEmpty(); - R_ASSERT(b_IsOGFContainersEmpty); -} - -void CBuild::TempSave(u32 stage) { CheckBeforeSave(stage); } -// Fbox scene_bb; -// xr_vector shader_render; -// xr_vector shader_compile; -// xr_vector L_dynamic; -// xr_vector glows; -// xr_vector portals; -// xr_vector lods; -// string_path path; -// xr_vector g_Shaders; -void CBuild::read(INetReader& r) -{ - r_pod(r, g_build_options); - - r_pod(r, scene_bb); - r_pod_vector(r, shader_render); - r_pod_vector(r, shader_compile); - r_pod_vector(r, L_dynamic); - r_pod_vector(r, glows); - r_pod_vector(r, portals); - r_pod_vector(r, lods); - r_pod(r, path); - r_pod_vector(r, g_Shaders); -} -void CBuild::write(IWriter& w) const -{ - w_pod(w, g_build_options); - - w_pod(w, scene_bb); - w_pod_vector(w, shader_render); - w_pod_vector(w, shader_compile); - w_pod_vector(w, L_dynamic); - w_pod_vector(w, glows); - w_pod_vector(w, portals); - w_pod_vector(w, lods); - w_pod(w, path); - w_pod_vector(w, g_Shaders); -} - -////////////////////////////////////////////////////////////////////// - -CBuild::CBuild() {} -CBuild::~CBuild() { destroy_global_data(); } -CMemoryWriter& CBuild::err_invalid() -{ - VERIFY(lc_global_data()); - return lc_global_data()->err_invalid(); -} -CMemoryWriter& CBuild::err_multiedge() -{ - VERIFY(lc_global_data()); - return lc_global_data()->err_multiedge(); -} -CMemoryWriter& CBuild::err_tjunction() -{ - VERIFY(lc_global_data()); - return lc_global_data()->err_tjunction(); -} -xr_vector& CBuild::materials() -{ - VERIFY(lc_global_data()); - return lc_global_data()->materials(); -} -xr_vector& CBuild::textures() -{ - VERIFY(lc_global_data()); - return lc_global_data()->textures(); -} - -base_lighting& CBuild::L_static() -{ - VERIFY(lc_global_data()); - return lc_global_data()->L_static(); -} - -Shader_xrLC_LIB& CBuild::shaders() -{ - VERIFY(lc_global_data()); - return lc_global_data()->shaders(); -} - -extern u16 RegisterShader(LPCSTR T); - -void CBuild::Light_prepare() -{ - for (vecFaceIt I = lc_global_data()->g_faces().begin(); I != lc_global_data()->g_faces().end(); ++I) - (*I)->CacheOpacity(); - for (u32 m = 0; m < mu_models().size(); m++) - mu_models()[m]->calc_faceopacity(); -} - -//.#define CFORM_ONLY -#ifdef LOAD_GL_DATA -void net_light(); -#endif -void CBuild::Run(LPCSTR P) -{ - lc_global_data()->initialize(); -#ifdef LOAD_GL_DATA - net_light(); - return; -#endif - //****************************************** Open Level - strconcat(sizeof(path), path, P, "\\"); - string_path lfn; - IWriter* fs = FS.w_open(strconcat(sizeof(lfn), lfn, path, "level.")); - fs->open_chunk(fsL_HEADER); - hdrLEVEL H; - H.XRLC_version = XRCL_PRODUCTION_VERSION; - H.XRLC_quality = g_params().m_quality; - fs->w(&H, sizeof(H)); - fs->close_chunk(); - - //****************************************** Dumb entry in shader-registration - RegisterShader(""); - - //****************************************** Saving lights - { - string256 fn; - IWriter* fs = FS.w_open(strconcat(sizeof(fn), fn, pBuild->path, "build.lights")); - fs->w_chunk(0, &*L_static().rgb.begin(), L_static().rgb.size() * sizeof(R_Light)); - fs->w_chunk(1, &*L_static().hemi.begin(), L_static().hemi.size() * sizeof(R_Light)); - fs->w_chunk(2, &*L_static().sun.begin(), L_static().sun.size() * sizeof(R_Light)); - FS.w_close(fs); - } - - //****************************************** Optimizing + checking for T-junctions - FPU::m64r(); - Logger.Phase("Optimizing..."); - mem_Compact(); - PreOptimize(); - CorrectTJunctions(); - - //****************************************** HEMI-Tesselate - FPU::m64r(); - Logger.Phase("Adaptive HT..."); - mem_Compact(); -#ifndef CFORM_ONLY - xrPhase_AdaptiveHT(); -#endif - - //****************************************** Building normals - FPU::m64r(); - Logger.Phase("Building normals..."); - mem_Compact(); - CalcNormals(); - // SmoothVertColors (5); - - //****************************************** Collision DB - // should be after normals, so that double-sided faces gets separated - FPU::m64r(); - Logger.Phase("Building collision database..."); - mem_Compact(); - BuildCForm(); - -#ifdef CFORM_ONLY - return; -#endif - - BuildPortals(*fs); - - //****************************************** T-Basis - { - FPU::m64r(); - Logger.Phase("Building tangent-basis..."); - xrPhase_TangentBasis(); - mem_Compact(); - } - - //****************************************** GLOBAL-RayCast model - FPU::m64r(); - Logger.Phase("Building rcast-CFORM model..."); - mem_Compact(); - Light_prepare(); - BuildRapid(TRUE); - - //****************************************** GLOBAL-ILLUMINATION - if (g_build_options.b_radiosity) - { - FPU::m64r(); - Logger.Phase("Radiosity-Solver..."); - mem_Compact(); - Light_prepare(); - xrPhase_Radiosity(); - } - - //****************************************** Starting MU - FPU::m64r(); - Logger.Phase("LIGHT: Starting MU..."); - mem_Compact(); - Light_prepare(); - if (g_build_options.b_net_light) - { - lc_global_data()->mu_models_calc_materials(); - RunNetCompileDataPrepare(); - } - StartMu(); - //****************************************** Resolve materials - FPU::m64r(); - Logger.Phase("Resolving materials..."); - mem_Compact(); - xrPhase_ResolveMaterials(); - IsolateVertices(TRUE); - - //****************************************** UV mapping - { - FPU::m64r(); - Logger.Phase("Build UV mapping..."); - mem_Compact(); - xrPhase_UVmap(); - IsolateVertices(TRUE); - } - - //****************************************** Subdivide geometry - FPU::m64r(); - Logger.Phase("Subdividing geometry..."); - mem_Compact(); - xrPhase_Subdivide(); - // IsolateVertices (TRUE); - lc_global_data()->vertices_isolate_and_pool_reload(); -//****************************************** All lighting + lmaps building and saving -#ifdef NET_CMP - mu_base.wait(500); - mu_secondary.wait(500); -#endif - if (g_build_options.b_net_light) - SetGlobalLightmapsDataInitialized(); - - Light(); - RunAfterLight(fs); -} -void CBuild::StartMu() -{ - // mu_base.start (new CMUThread (0)); - run_mu_light(!!g_build_options.b_net_light); -} -void CBuild::RunAfterLight(IWriter* fs) -{ - //****************************************** Merge geometry - FPU::m64r(); - Logger.Phase("Merging geometry..."); - mem_Compact(); - xrPhase_MergeGeometry(); - - //****************************************** Convert to OGF - FPU::m64r(); - Logger.Phase("Converting to OGFs..."); - mem_Compact(); - Flex2OGF(); - - //****************************************** Wait for MU - FPU::m64r(); - Logger.Phase("LIGHT: Waiting for MU-thread..."); - mem_Compact(); - wait_mu_base(); - - if (!g_build_options.b_net_light) - wait_mu_secondary(); - - /// - // lc_global_data()->clear_mesh (); - //// - - // mu_base.wait (500); - // mu_secondary.wait (500); - - //****************************************** Export MU-models - FPU::m64r(); - Logger.Phase("Converting MU-models to OGFs..."); - mem_Compact(); - { - u32 m; - Logger.Status("MU : Models..."); - for (m = 0; m < mu_models().size(); m++) - { - calc_ogf(*mu_models()[m]); - export_geometry(*mu_models()[m]); - } - - Logger.Status("MU : References..."); - for (m = 0; m < mu_refs().size(); m++) - export_ogf(*mu_refs()[m]); - - // lc_global_data()->clear_mu_models(); - } - - //****************************************** Destroy RCast-model - FPU::m64r(); - Logger.Phase("Destroying ray-trace model..."); - mem_Compact(); - lc_global_data()->destroy_rcmodel(); - - //****************************************** Build sectors - FPU::m64r(); - Logger.Phase("Building sectors..."); - mem_Compact(); - BuildSectors(); - - //****************************************** Saving MISC stuff - FPU::m64r(); - Logger.Phase("Saving..."); - mem_Compact(); - SaveLights(*fs); - - fs->open_chunk(fsL_GLOWS); - - for (u32 i = 0; i < glows.size(); i++) - { - b_glow& G = glows[i]; - fs->w(&G, 4 * sizeof(float)); - string1024 sid; - strconcat(sizeof(sid), sid, shader_render[materials()[G.dwMaterial].shader].name, "/", - textures()[materials()[G.dwMaterial].surfidx].name); - fs->w_u16(RegisterShader(sid)); - } - fs->close_chunk(); - - SaveTREE(*fs); - SaveSectors(*fs); - - err_save(); -} - -void CBuild::err_save() -{ - string_path log_name; - strconcat(sizeof(log_name), log_name, "build_", Core.UserName, ".err"); - FS.update_path(log_name, "$logs$", log_name); - - IWriter* fs = FS.w_open(log_name); - IWriter& err = *fs; - - // t-junction - err.open_chunk(0); - err.w_u32(err_tjunction().size() / (1 * sizeof(Fvector))); - err.w(err_tjunction().pointer(), err_tjunction().size()); - err.close_chunk(); - - // m-edje - err.open_chunk(1); - err.w_u32(err_multiedge().size() / (2 * sizeof(Fvector))); - err.w(err_multiedge().pointer(), err_multiedge().size()); - err.close_chunk(); - - // invalid - err.open_chunk(2); - err.w_u32(err_invalid().size() / (3 * sizeof(Fvector))); - err.w(err_invalid().pointer(), err_invalid().size()); - err.close_chunk(); - - FS.w_close(fs); -} - -void CBuild::MU_ModelsCalculateNormals() -{ - for (u32 m = 0; m < mu_models().size(); m++) - calc_normals(*mu_models()[m]); -} - -xr_vector& CBuild::mu_models() -{ - VERIFY(lc_global_data()); - return lc_global_data()->mu_models(); -} - -xr_vector& CBuild::mu_refs() -{ - VERIFY(lc_global_data()); - return lc_global_data()->mu_refs(); -} - -void CBuild::ImplicitLighting() { ::ImplicitLighting(g_build_options.b_net_light); } diff --git a/src/utils/xrLC/Build.h b/src/utils/xrLC/Build.h deleted file mode 100644 index 006a656ffa4..00000000000 --- a/src/utils/xrLC/Build.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once -#include "xrCore/FS.h" -#include "utils/Shader_xrLC.h" -struct STextureParams; - -extern "C" bool XR_IMPORT DXTCompress( - LPCSTR out_name, u8* raw_data, u8* normal_map, u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth); - -#include "utils/xrLC_Light/b_build_texture.h" -#include "utils/xrLC_Light/xrfacedefs.h" - -class xrLC_GlobalData; -class xrMU_Model; -class xrMU_Reference; -extern "C" XRLC_LIGHT_API xrLC_GlobalData* lc_global_data(); -////////////////////////////////////////////////////////////////////////// -// tesselator callbacks - -typedef int tesscb_estimator(const Face* F); // -1 = none, 0,1,2 = edge-number -typedef void tesscb_face(Face* F); // new face -typedef void tesscb_vertex(Vertex* V); // new vertex - -class base_lighting; -class INetReader; -////////////////////////////////////////////////////////////////////////// -class CBuild -{ -public: - CMemoryWriter& err_invalid(); - CMemoryWriter& err_tjunction(); - CMemoryWriter& err_multiedge(); - void err_save(); - - Fbox scene_bb; - xr_vector shader_render; - xr_vector shader_compile; - xr_vector L_dynamic; - xr_vector glows; - xr_vector portals; - xr_vector lods; - string_path path; - xr_vector g_Shaders; - - xr_vector& materials(); - xr_vector& textures(); - base_lighting& L_static(); - xr_vector& mu_models(); - xr_vector& mu_refs(); - - Shader_xrLC_LIB& shaders(); - - void mem_Compact(); - void mem_CompactSubdivs(); - -public: - void Load(const b_params& P, const IReader& fs); - void Run(LPCSTR path); - void StartMu(); - void RunAfterLight(IWriter* fs); - void Tesselate(); - void PreOptimize(); - void CorrectTJunctions(); - - void xrPhase_AdaptiveHT(); - void u_Tesselate(tesscb_estimator* E, tesscb_face* F, tesscb_vertex* V); - void u_SmoothVertColors(int count); - - void CalcNormals(); - void MU_ModelsCalculateNormals(); - void xrPhase_TangentBasis(); - - void BuildCForm(); - void BuildPortals(IWriter& fs); - void BuildRapid(BOOL bSave); - void xrPhase_Radiosity(); - - void IsolateVertices(BOOL bProgress); - void xrPhase_ResolveMaterials(); - void xrPhase_UVmap(); - void xrPhase_Subdivide(); - void ImplicitLighting(); - void Light_prepare(); - void Light(); - void LMapsLocal(); - void LMaps(); - // void Light_R2 (); - void LightVertex(); - void xrPhase_MergeLM(); - void xrPhase_MergeGeometry(); - - void Flex2OGF(); - void BuildSectors(); - - void SaveLights(IWriter& fs); - void SaveTREE(IWriter& fs); - void SaveSectors(IWriter& fs); - - void validate_splits(); - bool IsOGFContainersEmpty(); - void CheckBeforeSave(u32 stage); - void TempSave(u32 stage); - void read(INetReader& r); - void write(IWriter& w) const; - - CBuild(); - ~CBuild(); -}; - -extern CBuild* pBuild; -; -extern vec2Face g_XSplit; diff --git a/src/utils/xrLC/Build_Load.cpp b/src/utils/xrLC/Build_Load.cpp deleted file mode 100644 index 1cd19125086..00000000000 --- a/src/utils/xrLC/Build_Load.cpp +++ /dev/null @@ -1,379 +0,0 @@ -#include "stdafx.h" -#include "elight_def.h" - -#include "build.h" - -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -#include "utils/xrLC_Light/xrMU_Model.h" -#include "utils/xrLC_Light/xrMU_Model_Reference.h" - -extern u32 version; -template -void transfer(const char* name, xr_vector& dest, IReader& F, u32 chunk) -{ - IReader* O = F.open_chunk(chunk); - size_t count = O ? (O->length() / sizeof(T)) : 0; - Logger.clMsg("* %16s: %d", name, count); - if (count) - { - dest.reserve(count); - dest.insert(dest.begin(), (T*)O->pointer(), (T*)O->pointer() + count); //-V595 - } - if (O) - O->close(); -} - -extern u32* Surface_Load(char* name, u32& w, u32& h); -extern void Surface_Init(); - -struct R_Control -{ - string64 name; - xr_vector data; -}; -struct R_Layer -{ - R_Control control; - xr_vector lights; -}; - -void CBuild::Load(const b_params& Params, const IReader& _in_FS) -{ - IReader& fs = const_cast(_in_FS); - // HANDLE hLargeHeap = HeapCreate(0,64*1024*1024,0); - // clMsg ("* handle: %X",hLargeHeap); - - size_t i = 0; - - float p_total = 0; - float p_cost = 1.f / 3.f; - - IReader* F = 0; - - // - string_path sh_name; - FS.update_path(sh_name, "$game_data$", "shaders_xrlc.xr"); - shaders().Load(sh_name); - - //******* - Logger.Status("Vertices..."); - { - F = fs.open_chunk(EB_Vertices); - size_t v_count = F->length() / sizeof(b_vertex); - lc_global_data()->g_vertices().reserve(3 * v_count / 2); - scene_bb.invalidate(); - for (i = 0; i < v_count; i++) - { - Vertex* pV = lc_global_data()->create_vertex(); - F->r_fvector3(pV->P); - pV->N.set(0, 0, 0); - scene_bb.modify(pV->P); - } - Logger.Progress(p_total += p_cost); - Logger.clMsg("* %16s: %d", "vertices", lc_global_data()->g_vertices().size()); - F->close(); - } - - //******* - Logger.Status("Faces..."); - { - F = fs.open_chunk(EB_Faces); - R_ASSERT(F); - size_t f_count = F->length() / sizeof(b_face); - lc_global_data()->g_faces().reserve(f_count); - for (i = 0; i < f_count; i++) - { - try - { - Face* _F = lc_global_data()->create_face(); - b_face B; - F->r(&B, sizeof(B)); - R_ASSERT(B.dwMaterialGame < 65536); - - _F->dwMaterial = u16(B.dwMaterial); - _F->dwMaterialGame = B.dwMaterialGame; - - // Vertices and adjacement info - for (size_t it = 0; it < 3; ++it) - { - int id = B.v[it]; - R_ASSERT(id < (int)lc_global_data()->g_vertices().size()); - _F->SetVertex(it, lc_global_data()->g_vertices()[id]); - } - - // transfer TC - Fvector2 uv1, uv2, uv3; - uv1.set(B.t[0].x, B.t[0].y); - uv2.set(B.t[1].x, B.t[1].y); - uv3.set(B.t[2].x, B.t[2].y); - _F->AddChannel(uv1, uv2, uv3); - } - catch (...) - { - err_save(); - xrDebug::Fatal(DEBUG_INFO, "* ERROR: Can't process face #%d", i); - } - } - Logger.Progress(p_total += p_cost); - Logger.clMsg("* %16s: %d", "faces", lc_global_data()->g_faces().size()); - F->close(); - - if (g_using_smooth_groups) - { - F = fs.open_chunk(EB_SmoothGroups); - - R_ASSERT2(F, "EB_SmoothGroups chunk not found."); - - u32* sm_groups = NULL; - size_t sm_count = F->length() / sizeof(u32); - - R_ASSERT(sm_count == lc_global_data()->g_faces().size()); - sm_groups = xr_alloc(sm_count); - F->r(sm_groups, F->length()); - F->close(); - - for (size_t idx = 0; idx < sm_count; ++idx) - lc_global_data()->g_faces()[idx]->sm_group = sm_groups[idx]; - - xr_free(sm_groups); - } - - if (InvalideFaces()) - { - err_save(); - if (!g_build_options.b_skipinvalid) - xrDebug::Fatal(DEBUG_INFO, "* FATAL: %d invalid faces. Compilation aborted", InvalideFaces()); - else - Logger.clMsg("* ERROR! Total %d invalid faces found.", InvalideFaces()); - } - } - - //******* - Logger.Status("Models and References"); - F = fs.open_chunk(EB_MU_models); - if (F) - { - while (!F->eof()) - { - mu_models().push_back(xr_new()); - mu_models().back()->Load(*F, version); - } - F->close(); - } - F = fs.open_chunk(EB_MU_refs); - if (F) - { - while (!F->eof()) - { - mu_refs().push_back(xr_new()); - mu_refs().back()->Load(*F, mu_models()); - } - F->close(); - } - - //******* - Logger.Status("Other transfer..."); - transfer("materials", materials(), fs, EB_Materials); - transfer("shaders", shader_render, fs, EB_Shaders_Render); - transfer("shaders_xrlc", shader_compile, fs, EB_Shaders_Compile); - transfer("glows", glows, fs, EB_Glows); - transfer("portals", portals, fs, EB_Portals); - transfer("LODs", lods, fs, EB_LOD_models); - - // Load lights - Logger.Status("Loading lights..."); - { - xr_vector L_layers; - xr_vector L_control_data; - - // Controlles/Layers - { - F = fs.open_chunk(EB_Light_control); - L_control_data.assign((u8*)(F->pointer()), (u8*)(F->pointer()) + F->length()); - - R_Layer temp; - - while (!F->eof()) - { - F->r(temp.control.name, sizeof(temp.control.name)); - size_t cnt = F->r_u32(); - temp.control.data.resize(cnt); - F->r(&*temp.control.data.begin(), cnt * sizeof(u32)); - - L_layers.push_back(temp); - } - - F->close(); - } - // Static - { - F = fs.open_chunk(EB_Light_static); - b_light_static temp; - size_t cnt = F->length() / sizeof(temp); - for (i = 0; i < cnt; i++) - { - R_Light RL; - F->r(&temp, sizeof(temp)); - Flight L = temp.data; - - // type - if (L.type == Flight::Type::Directional) - RL.type = LT_DIRECT; - else - RL.type = LT_POINT; - RL.level = 0; - - // split energy/color - float _e = (L.diffuse.r + L.diffuse.g + L.diffuse.b) / 3.f; - Fvector _c = {L.diffuse.r, L.diffuse.g, L.diffuse.b}; - if (_abs(_e) > EPS_S) - _c.div(_e); - else - { - _c.set(0, 0, 0); - _e = 0; - } - - // generic properties - RL.diffuse.set(_c); - RL.position.set(L.position); - RL.direction.normalize_safe(L.direction); - RL.range = L.range * 1.1f; - RL.range2 = RL.range * RL.range; - RL.attenuation0 = L.attenuation0; - RL.attenuation1 = L.attenuation1; - RL.attenuation2 = L.attenuation2; - RL.falloff = - 1.0f / (RL.range * (RL.attenuation0 + RL.attenuation1 * RL.range + RL.attenuation2 * RL.range2)); - RL.energy = _e; - - // place into layer - R_ASSERT(temp.controller_ID < L_layers.size()); - L_layers[temp.controller_ID].lights.push_back(RL); - } - F->close(); - } - - // ***Search LAYERS*** - for (size_t LH = 0; LH < L_layers.size(); LH++) - { - R_Layer& TEST = L_layers[LH]; - if (0 == xr_stricmp(TEST.control.name, LCONTROL_HEMI)) - { - // Hemi found - L_static().hemi = TEST.lights; - } - if (0 == xr_stricmp(TEST.control.name, LCONTROL_SUN)) - { - // Sun found - L_static().sun = TEST.lights; - } - if (0 == xr_stricmp(TEST.control.name, LCONTROL_STATIC)) - { - // Static found - L_static().rgb = TEST.lights; - } - } - Logger.clMsg("*lighting*: HEMI: %d lights", L_static().hemi.size()); - Logger.clMsg("*lighting*: SUN: %d lights", L_static().sun.size()); - Logger.clMsg("*lighting*: STATIC: %d lights", L_static().rgb.size()); - R_ASSERT(L_static().hemi.size()); - R_ASSERT(L_static().sun.size()); - R_ASSERT(L_static().rgb.size()); - - // Dynamic - transfer("d-lights", L_dynamic, fs, EB_Light_dynamic); - } - - // process textures - Logger.Status("Processing textures..."); - { - Surface_Init(); - F = fs.open_chunk(EB_Textures); - size_t tex_count = F->length() / sizeof(b_texture); - for (size_t t = 0; t < tex_count; t++) - { - Logger.Progress(float(t) / float(tex_count)); - - b_BuildTexture BT(F); - - // load thumbnail - pstr N = BT.name; - if (strchr(N, '.')) - *(strchr(N, '.')) = 0; - xr_strlwr(N); - if (0 == xr_strcmp(N, "level_lods")) - { - // HACK for merged lod textures - BT.dwWidth = 1024; - BT.dwHeight = 1024; - BT.bHasAlpha = TRUE; - BT.THM.SetHasSurface(false); - BT.pSurface = 0; - } - else - { - string_path th_name; - FS.update_path(th_name, "$game_textures$", strconcat(sizeof(th_name), th_name, N, ".thm")); - Logger.clMsg("processing: %s", th_name); - IReader* THM = FS.r_open(th_name); - R_ASSERT2(THM, th_name); - - // version - //u32 version = 0; - //R_ASSERT2(THM->r_chunk(THM_CHUNK_VERSION, &version), th_name); - //if (version != THM_CURRENT_VERSION) FATAL("Unsupported version of THM file."); - - // analyze thumbnail information - BT.THM.Load(*THM); - BOOL bLOD = FALSE; - if (N[0] == 'l' && N[1] == 'o' && N[2] == 'd' && N[3] == '\\') - bLOD = TRUE; - - // load surface if it has an alpha channel or has "implicit lighting" flag - BT.dwWidth = BT.THM.width; - BT.dwHeight = BT.THM.height; - BT.bHasAlpha = BT.THM.HasAlphaChannel(); - if (!bLOD) - { - if (BT.bHasAlpha || BT.THM.flags.test(STextureParams::flImplicitLighted) || g_build_options.b_radiosity) - { - Logger.clMsg("- loading: %s", N); - u32 w = 0, h = 0; - BT.pSurface = Surface_Load(N, w, h); - BT.THM.SetHasSurface(true); - R_ASSERT2(BT.pSurface, "Can't load surface"); - if ((w != BT.dwWidth) || (h != BT.dwHeight)) - { - Msg("! THM doesn't correspond to the texture: %dx%d -> %dx%d", BT.dwWidth, BT.dwHeight, w, h); - BT.dwWidth = BT.THM.width = w; - BT.dwHeight = BT.THM.height = h; - } - BT.Vflip(); - } - else - { - // Free surface memory - } - } - } - - // save all the stuff we've created - textures().push_back(BT); - } - } - - // post-process materials - Logger.Status("Post-process materials..."); - post_process_materials(shaders(), shader_compile, materials()); - - Logger.Progress(p_total += p_cost); - - // Parameter block - CopyMemory(&g_params(), &Params, sizeof(b_params)); - - // - Logger.clMsg("* sizes: V(%d),F(%d)", sizeof(Vertex), sizeof(Face)); -} diff --git a/src/utils/xrLC/ELight_def.h b/src/utils/xrLC/ELight_def.h deleted file mode 100644 index 3f60bbbc486..00000000000 --- a/src/utils/xrLC/ELight_def.h +++ /dev/null @@ -1,34 +0,0 @@ -//---------------------------------------------------- -// file: ELightDef.h -//---------------------------------------------------- - -#ifndef ELightDefH -#define ELightDefH - -#define LCONTROL_HEMI "$hemi" // hemisphere -#define LCONTROL_SUN "$sun" // sun -#define LCONTROL_STATIC "$static" // all other static lights - -namespace ELight -{ -enum EFlags -{ - flAffectStatic = (1 << 0), - flAffectDynamic = (1 << 1), - flProcedural = (1 << 2), - flBreaking = (1 << 3), - flPointFuzzy = (1 << 4), - flCastShadow = (1 << 5), -}; - -enum EType -{ - ltPoint = Flight::Type::Point, - ltSpot = Flight::Type::Spot, - ltDirect = Flight::Type::Directional, - ltMaxCount, - lt_max_type = u32(-1), -}; -}; - -#endif diff --git a/src/utils/xrLC/MeshMenderLayerOGF.h b/src/utils/xrLC/MeshMenderLayerOGF.h deleted file mode 100644 index ba0a348662a..00000000000 --- a/src/utils/xrLC/MeshMenderLayerOGF.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _MESH_MENDER_LAYER_OGF_H_ -#define _MESH_MENDER_LAYER_OGF_H_ - -#include "common/NvMender2003/nvMeshMender.h" -#include "common/NvMender2003/mender_input_output.h" -#include "common/NvMender2003/remove_isolated_verts.h" - -#include "OGF_Face.h" - -IC void set_vertex(MeshMender::Vertex& out_vertex, const OGF_Vertex& in_vertex) -{ - cv_vector(out_vertex.pos, in_vertex.P); - cv_vector(out_vertex.normal, in_vertex.N); - out_vertex.s = in_vertex.UV[0].x; - out_vertex.t = in_vertex.UV[0].y; - // out_vertex.tangent; - // out_vertex.binormal; -} - -IC void set_vertex(OGF_Vertex& out_vertex, const OGF_Vertex& in_old_vertex, const MeshMender::Vertex& in_vertex) -{ - out_vertex = in_old_vertex; - cv_vector(out_vertex.P, in_vertex.pos); - cv_vector(out_vertex.N, in_vertex.normal); - - out_vertex.UV[0].x = in_vertex.s; - out_vertex.UV[0].y = in_vertex.t; - Fvector tangent; - Fvector binormal; - out_vertex.T.set(cv_vector(tangent, in_vertex.tangent)); - out_vertex.B.set(cv_vector(binormal, in_vertex.binormal)); -} - -///////////////////////////////////////////////////////////////////////////////////// -IC u16& face_vertex(OGF_Face& F, u32 vertex_index) -{ - VERIFY(vertex_index < 3); - return F.v[vertex_index]; -} - -IC const u16& face_vertex(const OGF_Face& F, u32 vertex_index) -{ - VERIFY(vertex_index < 3); - return F.v[vertex_index]; -} - -///////////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/utils/xrLC/MeshMenderLayerOrdinaryStatic.h b/src/utils/xrLC/MeshMenderLayerOrdinaryStatic.h deleted file mode 100644 index 6764613d8a2..00000000000 --- a/src/utils/xrLC/MeshMenderLayerOrdinaryStatic.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _MESH_MENDER_LAYER_ORDINARY_STATIC_H_ -#define _MESH_MENDER_LAYER_ORDINARY_STATIC_H_ - -#include "common/NvMender2003/nvMeshMender.h" -#include "common/NvMender2003/mender_input_output.h" - -#include "utils/xrLC_Light/xrFace.h" - -IC void set_vertex(MeshMender::Vertex& out_vertex, const Vertex& in_veretex, const Fvector2 Ftc) -{ - cv_vector(out_vertex.pos, in_veretex.P); - cv_vector(out_vertex.normal, in_veretex.N); - out_vertex.s = Ftc.x; - out_vertex.t = Ftc.y; - // out_vertex.tangent; - // out_vertex.binormal; -} - -IC void set_face(Face& out_face, const MeshMender::Vertex in_vertices[3]) -{ - for (u16 v = 0; v < 3; ++v) - { - out_face.tc.front().uv[v].set(in_vertices[v].s, in_vertices[v].t); - Fvector tangent; - Fvector binormal; - out_face.basis_tangent[v].set(cv_vector(tangent, in_vertices[v].tangent)); - out_face.basis_binormal[v].set(cv_vector(binormal, in_vertices[v].binormal)); - } -} - -#endif diff --git a/src/utils/xrLC/NvMender2002/NVMeshMender.cpp b/src/utils/xrLC/NvMender2002/NVMeshMender.cpp deleted file mode 100644 index b96e2e15345..00000000000 --- a/src/utils/xrLC/NvMender2002/NVMeshMender.cpp +++ /dev/null @@ -1,921 +0,0 @@ -/*********************************************************************NVMH2**** -Copyright (C) 1999, 2000, 2001, 2002 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Questions to sim.dietrich@nvidia.com - -Comments: - - This tool is designed to help condition meshes for use in vertex & pixel shaders. - - It can generate normals, texture coordinates, and perhaps most importantly, texture space - basis matrices. It also can fix common texuring problems that come up when bump mapping, including - - Texture Mirroring - When two one halves of a character use the same part of a texture. - - Cylindrical TexGen - When the rendering relies on cylindrical wrapping, texture space computation - won't work right. - - Stretched Basis - When two adjacend faces use wildly different texture mappings, causing stretching - that can ruin per-pixel lighting. - - - Here is an example usage scenario : - - Say you have positions & indices, and want textures, normals, and tangents. - - NVMeshMender aMender; - - MVMeshMender::VAVector inputAtts; // this is what you have - - MVMeshMender::VAVector outputAtts; // this is what you want - - MVMeshMender::VertexAttribute att; // this is my working attribute - - att.Name_ = "position"; - - for ( int p = 0; p < number_of_vertices; ++p ) - { - att.floatVector_.push_back( myPositions[ p ].x ); - att.floatVector_.push_back( myPositions[ p ].y ); - att.floatVector_.push_back( myPositions[ p ].z ); - } - - att.floatVector.clear(); - - att.Name_ = "indices"; - - for ( int i = 0; i < number_of_indices; ++i ) - { - att.intVector_.push_back( myIndices[ i ] ); - } - - // All inputs except for indices are assumed to be sets of 3 floats - - // "indices" are assumed to be unsigned ints - - // "tex0" is used for the tangent space calculation - - // "tex0" is the only coordinate set generated, and the texture matrix applies only to it - - // All unknown attribute types, including "tex1", "tex2", "random_attribute", "weights", "bones", etc. - // are simply passed through. They will be duplicated as needed just like positions, normals, etc. - - bool bSuccess = aMender.Munge( inputAtts, // these are my positions & indices - outputAtts, // these are the outputs I requested, plus extra stuff -generated on my behalf - 3.141592654f / 2.5f, // tangent space smooth angle - NULL, // no Texture matrix applied to my tex0 coords - FixTangents, // fix degenerate bases & texture mirroring - FixCylindricalTexGen // handle cylidrically mapped textures via vertex duplication - WeightNormalsByFaceSize // weight vertex normals by the triangle's size - ); - - - if ( !bSuccess ) return false; - - // Now the outputAtts may contain more vertex then you sent in ! - // This is because in handling tangent space smoothing, and solving texture mirroring & - // cylindrical texture wrapping problems, we partially duplicate vertices. - - // All attributes are duplicated, even unknowns. - - // You may also get things you didn't ask for. For instance, if you ask for tangent space, - // in other words, you ask for "tangent" or "binormal", you will get "normal", "tex0", - // "tangent" and "binormal". You can then ignore things in the output vector that you don't want. - - // If you ask for FixCylindricalTexGen, it will fix any absolute change in texture coordinates > 0.5 - // across a single edge. Therefore, if you pass in a single quad or cube, it won't work. Any more - // complicated or tessellated mesh should work fine. - -******************************************************************************/ - -#include "stdafx.h" -#pragma hdrstop - -#include "NVMeshMender.h" -#include "nv_math.h" - -bool NVMeshMender::Munge(const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, - const float bSmoothCreaseAngleRadians, const float* pTextureMatrix, const Option _FixTangents, - const Option _FixCylindricalTexGen, const Option _WeightNormalsByFaceSize) -{ - typedef xr_map Mapping; - typedef xr_set EdgeSet; - typedef xr_vector> IdenticalVertices; - - IdenticalVertices IdenticalVertices_; - - // make room for potential tex coords, normals, binormals and tangents - output.resize(input.size() + 4); - - Mapping inmap; - Mapping outmap; - - for (unsigned int a = 0; a < input.size(); ++a) - { - inmap[input[a].Name_] = a; - } - - for (unsigned int b = 0; b < output.size(); ++b) - { - output[b].intVector_.clear(); - output[b].floatVector_.clear(); - outmap[output[b].Name_] = b; - } - - for (unsigned int c = 0; c < output.size(); ++c) - { - // for every output that has a match in the input, just copy it over - Mapping::iterator in = inmap.find(output[c].Name_); - if (in != inmap.end()) - { - // copy over existing indices, position, or whatever - output[c] = input[(*in).second]; - } - } - - if (inmap.find("indices") == inmap.end()) - { - SetLastError("Missing indices from input"); - return false; - } - if (outmap.find("indices") == outmap.end()) - { - SetLastError("Missing indices from output"); - return false; - } - - // Go through all required outputs & generate as necessary - if (inmap.find("position") == inmap.end()) - { - SetLastError("Missing position from input"); - return false; - } - if (outmap.find("position") == outmap.end()) - { - SetLastError("Missing position from output"); - return false; - } - - Mapping::iterator pos = outmap.find("position"); - VertexAttribute::FloatVector& positions = output[(*pos).second].floatVector_; - vec3* pPositions = (vec3*)(&(positions[0])); - - xr_set EmptySet; - - for (unsigned int i = 0; i < positions.size(); i += 3) - { - IdenticalVertices_.push_back(EmptySet); - } - - // initialize all attributes - for (unsigned int att = 0; att < output.size(); ++att) - { - if (output[att].Name_ != "indices") - { - if (output[att].floatVector_.size() == 0) - { - output[att].floatVector_ = positions; - } - } - } - - Mapping::iterator ind = outmap.find("indices"); - VertexAttribute::IntVector& indices = output[(*ind).second].intVector_; - int* pIndices = (int*)(&(indices[0])); - - vec3* pNormals = 0; - // vec3* pBiNormals = 0; - // vec3* pTangents = 0; - vec3* pTex0 = 0; - - bool bNeedNormals = false; - bool bNeedTexCoords = false; - bool bComputeTangentSpace = false; - - // see if texture coords are needed - if (outmap.find("tex0") != outmap.end()) - { - bNeedTexCoords = true; - } - - // see if tangent or binormal are needed - if ((outmap.find("binormal") != outmap.end()) || (outmap.find("tangent") != outmap.end())) - { - bComputeTangentSpace = true; - } - - // see if normals are needed - if (outmap.find("normal") != outmap.end()) - { - bNeedNormals = true; - } - - // Compute normals. - Mapping::iterator want = outmap.find("normal"); - bool have_normals = (inmap.find("normal") != inmap.end()) ? true : false; - - if (bNeedNormals || bComputeTangentSpace) - { - // see if normals are provided - if (!have_normals) - { - // create normals - if (want == outmap.end()) - { - VertexAttribute norAtt; - norAtt.Name_ = "normal"; - output.push_back(norAtt); - - outmap["normal"] = output.size() - 1; - want = outmap.find("normal"); - } - - // just initialize array so it's the correct size - output[(*want).second].floatVector_ = positions; - - // VertexAttribute::FloatVector& normals = output[ (*want).second ].floatVector_; - - // zero out normals - for (unsigned n = 0; n < positions.size(); ++n) - { - output[(*want).second].floatVector_[n] = nv_zero; - } - - pNormals = (vec3*)(&(output[(*want).second].floatVector_[0])); - - // calculate face normals for each face - // & add its normal to vertex normal total - for (unsigned int t = 0; t < indices.size(); t += 3) - { - vec3 edge0; - vec3 edge1; - - edge0 = pPositions[indices[t + 1]] - pPositions[indices[t + 0]]; - edge1 = pPositions[indices[t + 2]] - pPositions[indices[t + 0]]; - - exact_normalize(&edge0.x); - exact_normalize(&edge1.x); - - vec3 faceNormal = edge0 ^ edge1; - - if (_WeightNormalsByFaceSize == DontWeightNormalsByFaceSize) - { - // Renormalize face normal, so it's not weighted by face size - exact_normalize(&faceNormal.x); - } - else - { - // Leave it as-is, to weight by face size naturally by the cross product result - } - - pNormals[indices[t + 0]] += faceNormal; - pNormals[indices[t + 1]] += faceNormal; - pNormals[indices[t + 2]] += faceNormal; - } - - // Renormalize each vertex normal - for (unsigned int v = 0; v < output[(*want).second].floatVector_.size() / 3; ++v) - pNormals[v].normalize(); - } - } - - // Compute texture coordinates. - if (bNeedTexCoords || bComputeTangentSpace) - { - if (outmap.find("tex0") == outmap.end()) - { - VertexAttribute texCoordAtt; - texCoordAtt.Name_ = "tex0"; - output.push_back(texCoordAtt); - outmap["tex0"] = output.size() - 1; - } - want = outmap.find("tex0"); - Mapping::iterator have = inmap.find("tex0"); - bool have_texcoords = (have != inmap.end()); - - // see if texcoords are provided - if (have_texcoords) - output[(*want).second].floatVector_ = input[(*have).second].floatVector_; - else - { - // just initialize array so it's the correct size - output[(*want).second].floatVector_ = positions; - - pTex0 = (vec3*)(&(output[(*want).second].floatVector_[0])); - - // Generate cylindrical coordinates - - // Find min and max positions for object bounding box - - vec3 maxPosition(-flt_max, -flt_max, -flt_max); - vec3 minPosition(flt_max, flt_max, flt_max); - - // there are 1/3 as many vectors as floats - const unsigned int theCount = static_cast(positions.size() / 3.0f); - - for (unsigned int i = 0; i < theCount; ++i) - { - maxPosition.x = nv_max(maxPosition.x, pPositions[i].x); - maxPosition.y = nv_max(maxPosition.y, pPositions[i].y); - maxPosition.z = nv_max(maxPosition.z, pPositions[i].z); - - minPosition.x = nv_min(minPosition.x, pPositions[i].x); - minPosition.y = nv_min(minPosition.y, pPositions[i].y); - minPosition.z = nv_min(minPosition.z, pPositions[i].z); - } - - // Find major, minor and other axis for cylindrical texgen - - vec3 delta = maxPosition - minPosition; - - delta.x = _abs(delta.x); - delta.y = _abs(delta.y); - delta.z = _abs(delta.z); - - bool maxx, maxy, maxz; - maxx = maxy = maxz = false; - bool minz, miny, minx; - minx = miny = minz = false; - - nv_scalar deltaMajor; - - if ((delta.x >= delta.y) && (delta.x >= delta.z)) - { - maxx = true; - deltaMajor = delta.x; - if (delta.y > delta.z) - { - minz = true; - } - else - { - miny = true; - } - } - else if ((delta.z >= delta.y) && (delta.z >= delta.x)) - { - maxz = true; - deltaMajor = delta.z; - if (delta.y > delta.x) - { - minx = true; - } - else - { - miny = true; - } - } - else if ((delta.y >= delta.z) && (delta.y >= delta.x)) - { - maxy = true; - deltaMajor = delta.y; - if (delta.x > delta.z) - { - minz = true; - } - else - { - minx = true; - } - } - - for (unsigned int p = 0; p < theCount; ++p) - { - // Find position relative to center of bounding box - - vec3 texCoords = ((maxPosition + minPosition) / 2.0f) - pPositions[p]; - - nv_scalar Major, Minor, Other = nv_zero; - - if (maxx) - { - Major = texCoords.x; - if (miny) - { - Minor = texCoords.y; - Other = texCoords.z; - } - else - { - Minor = texCoords.z; - Other = texCoords.y; - } - } - else if (maxy) - { - Major = texCoords.y; - if (minx) - { - Minor = texCoords.x; - Other = texCoords.z; - } - else - { - Minor = texCoords.z; - Other = texCoords.x; - } - } - else if (maxz) - { - Major = texCoords.z; - if (miny) - { - Minor = texCoords.y; - Other = texCoords.x; - } - else - { - Minor = texCoords.x; - Other = texCoords.y; - } - } - - nv_scalar longitude = nv_zero; - - // Prevent zero or near-zero from being passed into atan2 - if (_abs(Other) < 0.0001f) - { - if (Other >= nv_zero) - { - Other = 0.0001f; - } - else - { - Other = -0.0001f; - } - } - - // perform cylindrical mapping onto object, and remap from -pi,pi to -1,1 - - longitude = ((atan2(Minor, Other)) / nv_scalar(3.141592654)); - - texCoords.x = 0.5f * longitude + 0.5f; - texCoords.y = (Major / deltaMajor) + 0.5f; - - texCoords.x = nv_max(texCoords.x, nv_zero); - texCoords.y = nv_max(texCoords.y, nv_zero); - - texCoords.x = nv_min(texCoords.x, 1.0f); - texCoords.y = nv_min(texCoords.y, 1.0f); - - pTex0[p].x = texCoords.x - 0.25f; - if (pTex0[p].x < nv_zero) - pTex0[p].x += 1.0; - pTex0[p].y = 1.0f - texCoords.y; - pTex0[p].z = 1.0f; - } - } - - if (_FixCylindricalTexGen == FixCylindricalTexGen) - { - Mapping::iterator texIter = outmap.find("tex0"); - - VertexAttribute::FloatVector& texcoords = (output[(*texIter).second].floatVector_); - - const unsigned int theSize = indices.size(); - - for (unsigned int f = 0; f < theSize; f += 3) - { - for (int v = 0; v < 3; ++v) - { - int start = f + v; - int end = start + 1; - - if (v == 2) - { - end = f; - } - - nv_scalar dS = texcoords[indices[end] * 3 + 0] - texcoords[indices[start] * 3 + 0]; - - nv_scalar newS = nv_zero; - - bool bDoS = false; - - unsigned int theOneToChange = start; - - if (_abs(dS) >= 0.5f) - { - bDoS = true; - if (texcoords[indices[start] * 3 + 0] < texcoords[indices[end] * 3 + 0]) - { - newS = texcoords[indices[start] * 3 + 0] + 1.0f; - } - else - { - theOneToChange = end; - newS = texcoords[indices[end] * 3 + 0] + 1.0f; - } - } - - if (bDoS == true) - { - unsigned int theNewIndex = texcoords.size() / 3; - // Duplicate every part of the vertex - for (unsigned int att = 0; att < output.size(); ++att) - { - // No new indices are created, just vertex attributes - if (output[att].Name_ != "indices") - { - if (output[att].Name_ == "tex0") - { - output[att].floatVector_.push_back((float)newS); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 1]); // x - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 2]); // z - } - else - { - // *3 b/c we are looking up 3vectors in an array of floats - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 0]); // x - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 1]); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 2]); // z - } - } - } - - IdenticalVertices_.push_back(EmptySet); - - IdenticalVertices_[indices[theOneToChange]].insert(theNewIndex); - IdenticalVertices_[theNewIndex].insert(indices[theOneToChange]); - - // point to where the new vertices will go - indices[theOneToChange] = theNewIndex; - } - - } // for v - - { - for (int v = 0; v < 3; ++v) - { - int start = f + v; - int end = start + 1; - - if (v == 2) - { - end = f; - } - - nv_scalar dT = texcoords[indices[end] * 3 + 1] - texcoords[indices[start] * 3 + 1]; - - nv_scalar newT = nv_zero; - - bool bDoT = false; - - unsigned int theOneToChange = start; - - if (_abs(dT) >= 0.5f) - { - bDoT = true; - if (texcoords[indices[start] * 3 + 1] < texcoords[indices[end] * 3 + 1]) - { - newT = texcoords[indices[start] * 3 + 1] + 1.0f; - } - else - { - theOneToChange = end; - newT = texcoords[indices[end] * 3 + 1] + 1.0f; - } - } - - if (bDoT == true) - { - unsigned int theNewIndex = texcoords.size() / 3; - // Duplicate every part of the vertex - for (unsigned int att = 0; att < output.size(); ++att) - { - // No new indices are created, just vertex attributes - if (output[att].Name_ != "indices") - { - if (output[att].Name_ == "tex0") - { - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 0]); // x - output[att].floatVector_.push_back((float)newT); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 2]); // z - } - else - { - // *3 b/c we are looking up 3vectors in an array of floats - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 0]); // x - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 1]); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[theOneToChange] * 3 + 2]); // z - } - } - } - - IdenticalVertices_.push_back(EmptySet); - - IdenticalVertices_[theNewIndex].insert(indices[theOneToChange]); - IdenticalVertices_[indices[theOneToChange]].insert(theNewIndex); - - // point to where the new vertices will go - indices[theOneToChange] = theNewIndex; - } - } - - } // for v - - } // for f - } // if fix texgen - if (pTextureMatrix) - { - const mat4 M(pTextureMatrix[0], pTextureMatrix[1], pTextureMatrix[2], pTextureMatrix[3], pTextureMatrix[4], - pTextureMatrix[5], pTextureMatrix[6], pTextureMatrix[7], pTextureMatrix[8], pTextureMatrix[9], - pTextureMatrix[10], pTextureMatrix[11], pTextureMatrix[12], pTextureMatrix[13], pTextureMatrix[14], - pTextureMatrix[15]); - Mapping::iterator texIter = outmap.find("tex0"); - VertexAttribute::FloatVector& texcoords = output[(*texIter).second].floatVector_; - - // now apply matrix - for (unsigned int v = 0; v < texcoords.size(); v += 3) - { - vec3& V = *reinterpret_cast(&texcoords[v]); - V = V * M; - } - } - } - - if (bComputeTangentSpace) - { - EdgeSet Edges; - - Mapping::iterator texIter = outmap.find("tex0"); - - vec3* tex = (vec3*)&(output[(*texIter).second].floatVector_[0]); - - typedef xr_vector VecVector; - - // create tangents - want = outmap.find("tangent"); - if (want == outmap.end()) - { - VertexAttribute tanAtt; - tanAtt.Name_ = "tangent"; - output.push_back(tanAtt); - outmap["tangent"] = output.size() - 1; - want = outmap.find("tangent"); - } - // just initialize array so it's the correct size - output[(*want).second].floatVector_ = positions; - - // create binormals - want = outmap.find("binormal"); - if (want == outmap.end()) - { - VertexAttribute binAtt; - binAtt.Name_ = "binormal"; - output.push_back(binAtt); - outmap["binormal"] = output.size() - 1; - want = outmap.find("binormal"); - } - // just initialize array so it's the correct size - output[(*want).second].floatVector_ = positions; - - // Create a vector of s,t and sxt for each face of the model - VecVector sVector; - VecVector tVector; - VecVector sxtVector; - - const unsigned int theSize = indices.size(); - // for each face, calculate its S,T & SxT vector, & store its edges - for (unsigned int f = 0; f < theSize; f += 3) - { - vec3d edge0; - vec3d edge1; - - vec3d s; - vec3d t; - - // grap position & tex coords again in case they were reallocated - pPositions = (vec3*)(&(positions[0])); - tex = (vec3*)(&(output[(*texIter).second].floatVector_[0])); - - double _eps = type_epsilon * 10; - double a, b, c; - vec3d sxt; - - // create an edge(s) out of s and t - edge0.y = tex[indices[f + 1]].x - tex[indices[f]].x; - edge0.z = tex[indices[f + 1]].y - tex[indices[f]].y; - edge1.y = tex[indices[f + 2]].x - tex[indices[f]].x; - edge1.z = tex[indices[f + 2]].y - tex[indices[f]].y; - - // create an edge out of x, s and t - edge0.x = pPositions[indices[f + 1]].x - pPositions[indices[f]].x; - edge1.x = pPositions[indices[f + 2]].x - pPositions[indices[f]].x; - sxt = edge0 ^ edge1; - - a = sxt.x; - b = sxt.y; - c = sxt.z; - double ds_dx = nv_zero; - if (_abs(a) > _eps) - ds_dx = -b / a; - double dt_dx = nv_zero; - if (_abs(a) > _eps) - dt_dx = -c / a; - - // create an edge out of y, s and t - edge0.x = pPositions[indices[f + 1]].y - pPositions[indices[f]].y; - edge1.x = pPositions[indices[f + 2]].y - pPositions[indices[f]].y; - sxt = edge0 ^ edge1; - - a = sxt.x; - b = sxt.y; - c = sxt.z; - double ds_dy = nv_zero; - if (_abs(a) > _eps) - ds_dy = -b / a; - double dt_dy = nv_zero; - if (_abs(a) > _eps) - dt_dy = -c / a; - - // create an edge out of z, s and t - edge0.x = pPositions[indices[f + 1]].z - pPositions[indices[f]].z; - edge1.x = pPositions[indices[f + 2]].z - pPositions[indices[f]].z; - sxt = edge0 ^ edge1; - - a = sxt.x; - b = sxt.y; - c = sxt.z; - double ds_dz = nv_zero; - if (_abs(a) > _eps) - ds_dz = -b / a; - double dt_dz = nv_zero; - if (_abs(a) > _eps) - dt_dz = -c / a; - - // generate coordinate frame from the gradients - s = vec3d(ds_dx, ds_dy, ds_dz); - t = vec3d(dt_dx, dt_dy, dt_dz); - - s.normalize(); - t.normalize(); - sxt = s ^ t; - sxt.normalize(); - - // save vectors for this face - sVector.push_back(vec3(s)); - tVector.push_back(vec3(t)); - sxtVector.push_back(vec3(sxt)); - - if (_FixTangents == FixTangents) - { - // Look for each edge of the triangle in the edge map, in order to find - // a neighboring face along the edge - - for (int e = 0; e < 3; ++e) - { - Edge edge; - - int start = f + e; - int end = start + 1; - - if (e == 2) - { - end = f; - } - // order vertex indices ( low, high ) - edge.v0 = (unsigned int)nv_min((nv_scalar)indices[start], (nv_scalar)indices[end]); - edge.v1 = (unsigned int)nv_max((nv_scalar)indices[start], (nv_scalar)indices[end]); - - EdgeSet::iterator iter = Edges.find(edge); - - // if we are the only triangle with this edge... - if (iter == Edges.end()) - { - // ...then add us to the set of edges - edge.face = f / 3; - Edges.insert(edge); - } - else - { - // otherwise, check our neighbor's s,t & sxt vectors vs our own - const nv_scalar sAgreement = dot(s, sVector[(*iter).face]); - const nv_scalar tAgreement = dot(t, tVector[(*iter).face]); - const nv_scalar sxtAgreement = dot(sxt, sxtVector[(*iter).face]); - - // Check Radian angle split limit - const nv_scalar epsilon = _cos(bSmoothCreaseAngleRadians); - - // if the discontinuity in s, t, or sxt is greater than some epsilon, - // duplicate the vertex so it won't smooth with its neighbor anymore - - if ((_abs(sAgreement) < epsilon) || (_abs(tAgreement) < epsilon) || - (_abs(sxtAgreement) < epsilon)) - { - // Duplicate two vertices of this edge for this triangle only. - // This way the faces won't smooth with each other, thus - // preventing the tangent basis from becoming degenerate - - // divide by 3 b/c vector is of floats and not vectors - const unsigned int theNewIndex = positions.size() / 3; - - // Duplicate every part of the vertex - for (unsigned int att = 0; att < output.size(); ++att) - { - // No new indices are created, just vertex attributes - if (output[att].Name_ != "indices") - { - // *3 b/c we are looking up 3vectors in an array of floats - output[att].floatVector_.push_back( - output[att].floatVector_[indices[start] * 3 + 0]); // x - output[att].floatVector_.push_back( - output[att].floatVector_[indices[start] * 3 + 1]); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[start] * 3 + 2]); // z - - output[att].floatVector_.push_back( - output[att].floatVector_[indices[end] * 3 + 0]); // x - output[att].floatVector_.push_back( - output[att].floatVector_[indices[end] * 3 + 1]); // y - output[att].floatVector_.push_back( - output[att].floatVector_[indices[end] * 3 + 2]); // z - } - } - - IdenticalVertices_.push_back(EmptySet); - IdenticalVertices_.push_back(EmptySet); - - // point to where the new vertices will go - indices[start] = theNewIndex; - indices[end] = theNewIndex + 1; - } - - // Now that the vertices are duplicated, smoothing won't occur over this edge, - // because the two faces will sum their tangent basis vectors into separate indices - } - } - } // if fixtangents - } - - // Allocate std::vector & Zero out average basis for tangent space smoothing - VecVector avgS; - VecVector avgT; - - for (unsigned int p = 0; p < positions.size(); p += 3) - { - avgS.push_back(vec3_null); // do S - avgT.push_back(vec3_null); // now t - } - - // go through faces and add up the bases for each vertex - const int theFaceCount = indices.size() / 3; - - for (unsigned int face = 0; face < (unsigned int)theFaceCount; ++face) - { - // sum bases, so we smooth the tangent space across edges - avgS[pIndices[face * 3]] += sVector[face]; - avgT[pIndices[face * 3]] += tVector[face]; - - avgS[pIndices[face * 3 + 1]] += sVector[face]; - avgT[pIndices[face * 3 + 1]] += tVector[face]; - - avgS[pIndices[face * 3 + 2]] += sVector[face]; - avgT[pIndices[face * 3 + 2]] += tVector[face]; - } - - if (_FixCylindricalTexGen == FixCylindricalTexGen) - { - for (unsigned int v = 0; v < IdenticalVertices_.size(); ++v) - { - // go through each vertex & sum up it's true neighbors - for (xr_set::iterator iter = IdenticalVertices_[v].begin(); - iter != IdenticalVertices_[v].end(); ++iter) - { - avgS[v] += avgS[*iter]; - avgT[v] += avgT[*iter]; - } - } - } - - Mapping::iterator tangent = outmap.find("tangent"); - Mapping::iterator binormal = outmap.find("binormal"); - - // now renormalize - for (unsigned int b = 0; b < positions.size(); b += 3) - { - *reinterpret_cast(&output[(*tangent).second].floatVector_[b]) = normalize(avgS[b / 3]); // s - *reinterpret_cast(&output[(*binormal).second].floatVector_[b]) = normalize(avgT[b / 3]); // T - } - } - - // At this point, tex coords, normals, binormals and tangents should be generated if necessary, - // and other attributes are simply copied as available - - return true; -} diff --git a/src/utils/xrLC/NvMender2002/NVMeshMender.h b/src/utils/xrLC/NvMender2002/NVMeshMender.h deleted file mode 100644 index 73b7c15b22f..00000000000 --- a/src/utils/xrLC/NvMender2002/NVMeshMender.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef NVMeshMenderH -#define NVMeshMenderH - -/*********************************************************************NVMH2**** -Copyright (C) 1999, 2000, 2001, 2002 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Questions to sim.dietrich@nvidia.com - -Comments: - - This tool is designed to help condition meshes for use in vertex & pixel shaders. - - It can generate normals, texture coordinates, and perhaps most importantly, texture space - basis matrices. It also can fix common texuring problems that come up when bump mapping, including - - Texture Mirroring - When two one halves of a character use the same part of a texture. - - Cylindrical TexGen - When the rendering relies on cylindrical wrapping, texture space computation - won't work right. - - Stretched Basis - When two adjacend faces use wildly different texture mappings, causing stretching - that can ruin per-pixel lighting. - - - Here is an example usage scenario : - - Say you have positions & indices & normals, and want textures, and tangents, and binormals. - and assume that positions, indices, and normals are in STL arrays: vpos, triIndices and vnor respectively. - - xr_vector vpos; - xr_vector triIndices; - xr_vector vnor; - ... - - NVMeshMender aMender; - - - xr_vector inputAtts; // What you have - xr_vector outputAtts; // What you want. - - NVMeshMender::VertexAttribute posAtt; - posAtt.Name_ = "position"; - posAtt.floatVector_ = vpos; - - NVMeshMender::VertexAttribute triIndAtt; - triIndAtt.Name_ = "indices"; - triIndAtt.intVector_ = triIndices; - - NVMeshMender::VertexAttribute norAtt; - norAtt.Name_ = "normal"; - norAtt.floatVector_ = vnor; - - xr_vector texCoords; - NVMeshMender::VertexAttribute texCoordAtt; - texCoordAtt.Name_ = "tex0"; - texCoordAtt.floatVector_;// = texCoords; - - NVMeshMender::VertexAttribute tgtSpaceAtt; - tgtSpaceAtt.Name_ = "tangent"; - - NVMeshMender::VertexAttribute binormalAtt; - binormalAtt.Name_ = "binormal"; - - inputAtts.push_back(posAtt); - inputAtts.push_back(triIndAtt); - inputAtts.push_back(norAtt); - - outputAtts.push_back(posAtt); - outputAtts.push_back(triIndAtt); - outputAtts.push_back(norAtt); - outputAtts.push_back(texCoordAtt); - outputAtts.push_back(tgtSpaceAtt); - outputAtts.push_back(binormalAtt); - - // All inputs except for indices are assumed to be sets of 3 floats - - // "indices" are assumed to be unsigned ints - - // "tex0" is used for the tangent space calculation - - // "tex0" is the only coordinate set generated, and the texture matrix applies only to it - - // All unknown attribute types, including "tex1", "tex2", "random_attribute", "weights", "bones", etc. - // are simply passed through. They will be duplicated as needed just like positions, normals, etc. - - bool bSuccess = aMender.Munge( inputAtts, // these are my positions & indices - outputAtts, // these are the outputs I requested, plus extra stuff -generated on my behalf - 3.141592654f / 2.5f, // tangent space smooth angle - NULL, // no Texture matrix applied to my tex0 coords - FixTangents, // fix degenerate bases & texture mirroring - FixCylindricalTexGen // handle cylidrically mapped textures via vertex duplication - WeightNormalsByFaceSize // weight vertex normals by the triangle's size - ); - - - if ( !bSuccess ) return false; - - vpos = outputAtts[0].floatVector_; // Note that there may be more vertices than you sent in. - vnor = outputAtts[2].floatVector_; - xr_vector texCoords = outputAtts[3].floatVector_; // texcoords - xr_vector vtgt = outputAtts[4].floatVector_; // tgts - triIndices = outputAtts[1].intVector_; // new indices. - xr_vector vbin = outputAtts[5].floatVector_; // binormals. - - // Now the outputAtts may contain more vertex then you sent in ! - // This is because in handling tangent space smoothing, and solving texture mirroring & - // cylindrical texture wrapping problems, we partially duplicate vertices. - - // All attributes are duplicated, even unknowns. - - // You may also get things you didn't ask for. For instance, if you ask for tangent space, - // in other words, you ask for "tangent" or "binormal", you will get "normal", "tex0", - // "tangent" and "binormal". You can then ignore things in the output vector that you don't want. - - // If you ask for FixCylindricalTexGen, it will fix any absolute change in texture coordinates > 0.5 - // across a single edge. Therefore, if you pass in a single quad or cube, it won't work. Any more - // complicated or tessellated mesh should work fine. - - -******************************************************************************/ - -#pragma warning(push) -#pragma warning(disable : 4995) -#include -#pragma warning(pop) - -class NVMeshMender -{ -private: - mutable xr_vector LastErrors_; - - struct Edge - { - unsigned int v0; - unsigned int v1; - - unsigned int face; - unsigned int face2; - - bool operator==(const Edge& rhs) const { return ((v0 == rhs.v0) && (v1 == rhs.v1)); } - bool operator<(const Edge& rhs) const - { - if (v0 < rhs.v0) - { - return true; - } - - if (v0 > rhs.v0) - { - return false; - } - - return (v1 < rhs.v1); - } - }; - -public: - void SetLastError(const xr_string& rhs) const { LastErrors_.push_back(rhs); } - xr_string GetLastError() const - { - xr_string aString; - - if (LastErrors_.size() > 0) - { - aString = LastErrors_.back(); - } - return aString; - } - - struct VertexAttribute - { - xr_string Name_; - - typedef xr_vector IntVector; - IntVector intVector_; - - typedef xr_vector FloatVector; - FloatVector floatVector_; - - VertexAttribute& operator=(const VertexAttribute& rhs) - { - Name_ = rhs.Name_; - intVector_ = rhs.intVector_; - floatVector_ = rhs.floatVector_; - return *this; - } - - VertexAttribute(const char* pName = "") : Name_(pName) { ; } - VertexAttribute(const VertexAttribute& rhs) { *this = rhs; } - bool operator==(const VertexAttribute& rhs) { return (Name_ == rhs.Name_); } - bool operator<(const VertexAttribute& rhs) { return (Name_ < rhs.Name_); } - }; - - typedef xr_vector VAVector; - - enum Option - { - FixTangents, - DontFixTangents, - - FixCylindricalTexGen, - DontFixCylindricalTexGen, - - WeightNormalsByFaceSize, - DontWeightNormalsByFaceSize - }; - - bool Munge(const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, - const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f, const float* pTextureMatrix = 0, - const Option _FixTangents = FixTangents, const Option _FixCylindricalTexGen = FixCylindricalTexGen, - const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize); - bool MungeD3DX(const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, - const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f, const float* pTextureMatrix = 0, - const Option _FixTangents = FixTangents, const Option _FixCylindricalTexGen = FixCylindricalTexGen, - const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize); -}; - -#endif //_NVMeshMender_H_ diff --git a/src/utils/xrLC/NvMender2002/nv_algebra.cpp b/src/utils/xrLC/NvMender2002/nv_algebra.cpp deleted file mode 100644 index b77db20995f..00000000000 --- a/src/utils/xrLC/NvMender2002/nv_algebra.cpp +++ /dev/null @@ -1,1420 +0,0 @@ -/*********************************************************************NVMH1**** -File: -nv_algebra.cpp - -Copyright (C) 1999, 2000 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - - -******************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#ifndef nv_algebraH -#include "nv_math.h" -#endif - -#ifndef _WIN32 -#define _isnan isnan -#define _finite finite -#endif - -mat3::mat3() {} -mat3::mat3(const nv_scalar* array) { memcpy(mat_array, array, sizeof(nv_scalar) * 9); } -mat3::mat3(const mat3& M) { memcpy(mat_array, M.mat_array, sizeof(nv_scalar) * 9); } -mat4::mat4() {} -mat4::mat4(const nv_scalar* array) { memcpy(mat_array, array, sizeof(nv_scalar) * 16); } -mat4::mat4(const mat4& M) { memcpy(mat_array, M.mat_array, sizeof(nv_scalar) * 16); } -vec3& cross(vec3& u, const vec3& v, const vec3& w) -{ - u.x = v.y * w.z - v.z * w.y; - u.y = v.z * w.x - v.x * w.z; - u.z = v.x * w.y - v.y * w.x; - return u; -} - -nv_scalar& dot(nv_scalar& u, const vec3& v, const vec3& w) -{ - u = v.x * w.x + v.y * w.y + v.z * w.z; - return u; -} - -nv_scalar dot(const vec3& v, const vec3& w) { return v.x * w.x + v.y * w.y + v.z * w.z; } -nv_scalar& dot(nv_scalar& u, const vec4& v, const vec4& w) -{ - u = v.x * w.x + v.y * w.y + v.z * w.z + v.w * w.w; - return u; -} - -nv_scalar dot(const vec4& v, const vec4& w) { return v.x * w.x + v.y * w.y + v.z * w.z + v.w * w.w; } -nv_scalar& dot(nv_scalar& u, const vec3& v, const vec4& w) -{ - u = v.x * w.x + v.y * w.y + v.z * w.z; - return u; -} - -nv_scalar dot(const vec3& v, const vec4& w) { return v.x * w.x + v.y * w.y + v.z * w.z; } -nv_scalar& dot(nv_scalar& u, const vec4& v, const vec3& w) -{ - u = v.x * w.x + v.y * w.y + v.z * w.z; - return u; -} - -nv_scalar dot(const vec4& v, const vec3& w) { return v.x * w.x + v.y * w.y + v.z * w.z; } -vec3& reflect(vec3& r, const vec3& n, const vec3& l) -{ - nv_scalar n_dot_l; - n_dot_l = nv_two * dot(n_dot_l, n, l); - mult(r, l, -nv_one); - madd(r, n, n_dot_l); - return r; -} - -vec3& madd(vec3& u, const vec3& v, const nv_scalar& lambda) -{ - u.x += v.x * lambda; - u.y += v.y * lambda; - u.z += v.z * lambda; - return u; -} - -vec3& mult(vec3& u, const vec3& v, const nv_scalar& lambda) -{ - u.x = v.x * lambda; - u.y = v.y * lambda; - u.z = v.z * lambda; - return u; -} - -vec3& mult(vec3& u, const vec3& v, const vec3& w) -{ - u.x = v.x * w.x; - u.y = v.y * w.y; - u.z = v.z * w.z; - return u; -} - -vec3& sub(vec3& u, const vec3& v, const vec3& w) -{ - u.x = v.x - w.x; - u.y = v.y - w.y; - u.z = v.z - w.z; - return u; -} - -vec3& add(vec3& u, const vec3& v, const vec3& w) -{ - u.x = v.x + w.x; - u.y = v.y + w.y; - u.z = v.z + w.z; - return u; -} - -vec3& scale(vec3& u, const nv_scalar s) -{ - u.x *= s; - u.y *= s; - u.z *= s; - return u; -} - -vec4& scale(vec4& u, const nv_scalar s) -{ - u.x *= s; - u.y *= s; - u.z *= s; - u.w *= s; - return u; -} - -vec3& mult(vec3& u, const mat3& M, const vec3& v) -{ - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z; - return u; -} - -vec3& mult(vec3& u, const vec3& v, const mat3& M) -{ - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z; - return u; -} - -const vec3 operator*(const mat3& M, const vec3& v) -{ - vec3 u; - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z; - return u; -} - -const vec3 operator*(const vec3& v, const mat3& M) -{ - vec3 u; - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z; - return u; -} - -vec4& mult(vec4& u, const mat4& M, const vec4& v) -{ - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z + M.a03 * v.w; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z + M.a13 * v.w; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z + M.a23 * v.w; - u.w = M.a30 * v.x + M.a31 * v.y + M.a32 * v.z + M.a33 * v.w; - return u; -} - -vec4& mult(vec4& u, const vec4& v, const mat4& M) -{ - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z + M.a30 * v.w; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z + M.a31 * v.w; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z + M.a32 * v.w; - u.w = M.a03 * v.x + M.a13 * v.y + M.a23 * v.z + M.a33 * v.w; - return u; -} - -const vec4 operator*(const mat4& M, const vec4& v) -{ - vec4 u; - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z + M.a03 * v.w; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z + M.a13 * v.w; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z + M.a23 * v.w; - u.w = M.a30 * v.x + M.a31 * v.y + M.a32 * v.z + M.a33 * v.w; - return u; -} - -const vec4 operator*(const vec4& v, const mat4& M) -{ - vec4 u; - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z + M.a30 * v.w; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z + M.a31 * v.w; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z + M.a32 * v.w; - u.w = M.a03 * v.x + M.a13 * v.y + M.a23 * v.z + M.a33 * v.w; - return u; -} - -vec3& mult_pos(vec3& u, const mat4& M, const vec3& v) -{ - nv_scalar oow = nv_one / (v.x * M.a30 + v.y * M.a31 + v.z * M.a32 + M.a33); - u.x = (M.a00 * v.x + M.a01 * v.y + M.a02 * v.z + M.a03) * oow; - u.y = (M.a10 * v.x + M.a11 * v.y + M.a12 * v.z + M.a13) * oow; - u.z = (M.a20 * v.x + M.a21 * v.y + M.a22 * v.z + M.a23) * oow; - return u; -} - -vec3& mult_pos(vec3& u, const vec3& v, const mat4& M) -{ - nv_scalar oow = nv_one / (v.x * M.a03 + v.y * M.a13 + v.z * M.a23 + M.a33); - u.x = (M.a00 * v.x + M.a10 * v.y + M.a20 * v.z + M.a30) * oow; - u.y = (M.a01 * v.x + M.a11 * v.y + M.a21 * v.z + M.a31) * oow; - u.z = (M.a02 * v.x + M.a12 * v.y + M.a22 * v.z + M.a32) * oow; - return u; -} - -vec3& mult_dir(vec3& u, const mat4& M, const vec3& v) -{ - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z; - return u; -} - -vec3& mult_dir(vec3& u, const vec3& v, const mat4& M) -{ - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z; - return u; -} - -vec3& mult(vec3& u, const mat4& M, const vec3& v) -{ - u.x = M.a00 * v.x + M.a01 * v.y + M.a02 * v.z + M.a03; - u.y = M.a10 * v.x + M.a11 * v.y + M.a12 * v.z + M.a13; - u.z = M.a20 * v.x + M.a21 * v.y + M.a22 * v.z + M.a23; - return u; -} - -vec3& mult(vec3& u, const vec3& v, const mat4& M) -{ - u.x = M.a00 * v.x + M.a10 * v.y + M.a20 * v.z + M.a30; - u.y = M.a01 * v.x + M.a11 * v.y + M.a21 * v.z + M.a31; - u.z = M.a02 * v.x + M.a12 * v.y + M.a22 * v.z + M.a32; - return u; -} - -mat4& add(mat4& A, const mat4& B) -{ - A.a00 += B.a00; - A.a10 += B.a10; - A.a20 += B.a20; - A.a30 += B.a30; - A.a01 += B.a01; - A.a11 += B.a11; - A.a21 += B.a21; - A.a31 += B.a31; - A.a02 += B.a02; - A.a12 += B.a12; - A.a22 += B.a22; - A.a32 += B.a32; - A.a03 += B.a03; - A.a13 += B.a13; - A.a23 += B.a23; - A.a33 += B.a33; - return A; -} - -mat3& add(mat3& A, const mat3& B) -{ - A.a00 += B.a00; - A.a10 += B.a10; - A.a20 += B.a20; - A.a01 += B.a01; - A.a11 += B.a11; - A.a21 += B.a21; - A.a02 += B.a02; - A.a12 += B.a12; - A.a22 += B.a22; - return A; -} - -// C = A * B - -// C.a00 C.a01 C.a02 C.a03 A.a00 A.a01 A.a02 A.a03 B.a00 B.a01 B.a02 B.a03 -// -// C.a10 C.a11 C.a12 C.a13 A.a10 A.a11 A.a12 A.a13 B.a10 B.a11 B.a12 B.a13 -// -// C.a20 C.a21 C.a22 C.a23 A.a20 A.a21 A.a22 A.a23 B.a20 B.a21 B.a22 B.a23 -// -// C.a30 C.a31 C.a32 C.a33 = A.a30 A.a31 A.a32 A.a33 * B.a30 B.a31 B.a32 B.a33 - -mat4& mult(mat4& C, const mat4& A, const mat4& B) -{ - C.a00 = A.a00 * B.a00 + A.a01 * B.a10 + A.a02 * B.a20 + A.a03 * B.a30; - C.a10 = A.a10 * B.a00 + A.a11 * B.a10 + A.a12 * B.a20 + A.a13 * B.a30; - C.a20 = A.a20 * B.a00 + A.a21 * B.a10 + A.a22 * B.a20 + A.a23 * B.a30; - C.a30 = A.a30 * B.a00 + A.a31 * B.a10 + A.a32 * B.a20 + A.a33 * B.a30; - C.a01 = A.a00 * B.a01 + A.a01 * B.a11 + A.a02 * B.a21 + A.a03 * B.a31; - C.a11 = A.a10 * B.a01 + A.a11 * B.a11 + A.a12 * B.a21 + A.a13 * B.a31; - C.a21 = A.a20 * B.a01 + A.a21 * B.a11 + A.a22 * B.a21 + A.a23 * B.a31; - C.a31 = A.a30 * B.a01 + A.a31 * B.a11 + A.a32 * B.a21 + A.a33 * B.a31; - C.a02 = A.a00 * B.a02 + A.a01 * B.a12 + A.a02 * B.a22 + A.a03 * B.a32; - C.a12 = A.a10 * B.a02 + A.a11 * B.a12 + A.a12 * B.a22 + A.a13 * B.a32; - C.a22 = A.a20 * B.a02 + A.a21 * B.a12 + A.a22 * B.a22 + A.a23 * B.a32; - C.a32 = A.a30 * B.a02 + A.a31 * B.a12 + A.a32 * B.a22 + A.a33 * B.a32; - C.a03 = A.a00 * B.a03 + A.a01 * B.a13 + A.a02 * B.a23 + A.a03 * B.a33; - C.a13 = A.a10 * B.a03 + A.a11 * B.a13 + A.a12 * B.a23 + A.a13 * B.a33; - C.a23 = A.a20 * B.a03 + A.a21 * B.a13 + A.a22 * B.a23 + A.a23 * B.a33; - C.a33 = A.a30 * B.a03 + A.a31 * B.a13 + A.a32 * B.a23 + A.a33 * B.a33; - return C; -} - -mat4 mat4::operator*(const mat4& B) const -{ - mat4 C; - C.a00 = a00 * B.a00 + a01 * B.a10 + a02 * B.a20 + a03 * B.a30; - C.a10 = a10 * B.a00 + a11 * B.a10 + a12 * B.a20 + a13 * B.a30; - C.a20 = a20 * B.a00 + a21 * B.a10 + a22 * B.a20 + a23 * B.a30; - C.a30 = a30 * B.a00 + a31 * B.a10 + a32 * B.a20 + a33 * B.a30; - C.a01 = a00 * B.a01 + a01 * B.a11 + a02 * B.a21 + a03 * B.a31; - C.a11 = a10 * B.a01 + a11 * B.a11 + a12 * B.a21 + a13 * B.a31; - C.a21 = a20 * B.a01 + a21 * B.a11 + a22 * B.a21 + a23 * B.a31; - C.a31 = a30 * B.a01 + a31 * B.a11 + a32 * B.a21 + a33 * B.a31; - C.a02 = a00 * B.a02 + a01 * B.a12 + a02 * B.a22 + a03 * B.a32; - C.a12 = a10 * B.a02 + a11 * B.a12 + a12 * B.a22 + a13 * B.a32; - C.a22 = a20 * B.a02 + a21 * B.a12 + a22 * B.a22 + a23 * B.a32; - C.a32 = a30 * B.a02 + a31 * B.a12 + a32 * B.a22 + a33 * B.a32; - C.a03 = a00 * B.a03 + a01 * B.a13 + a02 * B.a23 + a03 * B.a33; - C.a13 = a10 * B.a03 + a11 * B.a13 + a12 * B.a23 + a13 * B.a33; - C.a23 = a20 * B.a03 + a21 * B.a13 + a22 * B.a23 + a23 * B.a33; - C.a33 = a30 * B.a03 + a31 * B.a13 + a32 * B.a23 + a33 * B.a33; - return C; -} - -// C = A * B - -// C.a00 C.a01 C.a02 A.a00 A.a01 A.a02 B.a00 B.a01 B.a02 -// -// C.a10 C.a11 C.a12 A.a10 A.a11 A.a12 B.a10 B.a11 B.a12 -// -// C.a20 C.a21 C.a22 = A.a20 A.a21 A.a22 * B.a20 B.a21 B.a22 - -mat3& mult(mat3& C, const mat3& A, const mat3& B) -{ - C.a00 = A.a00 * B.a00 + A.a01 * B.a10 + A.a02 * B.a20; - C.a10 = A.a10 * B.a00 + A.a11 * B.a10 + A.a12 * B.a20; - C.a20 = A.a20 * B.a00 + A.a21 * B.a10 + A.a22 * B.a20; - C.a01 = A.a00 * B.a01 + A.a01 * B.a11 + A.a02 * B.a21; - C.a11 = A.a10 * B.a01 + A.a11 * B.a11 + A.a12 * B.a21; - C.a21 = A.a20 * B.a01 + A.a21 * B.a11 + A.a22 * B.a21; - C.a02 = A.a00 * B.a02 + A.a01 * B.a12 + A.a02 * B.a22; - C.a12 = A.a10 * B.a02 + A.a11 * B.a12 + A.a12 * B.a22; - C.a22 = A.a20 * B.a02 + A.a21 * B.a12 + A.a22 * B.a22; - return C; -} - -mat3& transpose(mat3& A) -{ - nv_scalar tmp; - tmp = A.a01; - A.a01 = A.a10; - A.a10 = tmp; - - tmp = A.a02; - A.a02 = A.a20; - A.a20 = tmp; - - tmp = A.a12; - A.a12 = A.a21; - A.a21 = tmp; - return A; -} - -mat4& transpose(mat4& A) -{ - nv_scalar tmp; - tmp = A.a01; - A.a01 = A.a10; - A.a10 = tmp; - - tmp = A.a02; - A.a02 = A.a20; - A.a20 = tmp; - - tmp = A.a03; - A.a03 = A.a30; - A.a30 = tmp; - - tmp = A.a12; - A.a12 = A.a21; - A.a21 = tmp; - - tmp = A.a13; - A.a13 = A.a31; - A.a31 = tmp; - - tmp = A.a23; - A.a23 = A.a32; - A.a32 = tmp; - return A; -} - -mat4& transpose(mat4& B, const mat4& A) -{ - B.a00 = A.a00; - B.a01 = A.a10; - B.a02 = A.a20; - B.a03 = A.a30; - B.a10 = A.a01; - B.a11 = A.a11; - B.a12 = A.a21; - B.a13 = A.a31; - B.a20 = A.a02; - B.a21 = A.a12; - B.a22 = A.a22; - B.a23 = A.a32; - B.a30 = A.a03; - B.a31 = A.a13; - B.a32 = A.a23; - B.a33 = A.a33; - return B; -} - -mat3& transpose(mat3& B, const mat3& A) -{ - B.a00 = A.a00; - B.a01 = A.a10; - B.a02 = A.a20; - B.a10 = A.a01; - B.a11 = A.a11; - B.a12 = A.a21; - B.a20 = A.a02; - B.a21 = A.a12; - B.a22 = A.a22; - return B; -} - -/* - calculate the determinent of a 2x2 matrix in the from - - | a1 a2 | - | b1 b2 | - -*/ -nv_scalar det2x2(nv_scalar a1, nv_scalar a2, nv_scalar b1, nv_scalar b2) { return a1 * b2 - b1 * a2; } -/* - calculate the determinent of a 3x3 matrix in the from - - | a1 a2 a3 | - | b1 b2 b3 | - | c1 c2 c3 | - -*/ -nv_scalar det3x3(nv_scalar a1, nv_scalar a2, nv_scalar a3, nv_scalar b1, nv_scalar b2, nv_scalar b3, nv_scalar c1, - nv_scalar c2, nv_scalar c3) -{ - return a1 * det2x2(b2, b3, c2, c3) - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3); -} - -mat4& invert(mat4& B, const mat4& A) -{ - nv_scalar det, oodet; - - B.a00 = det3x3(A.a11, A.a21, A.a31, A.a12, A.a22, A.a32, A.a13, A.a23, A.a33); - B.a10 = -det3x3(A.a10, A.a20, A.a30, A.a12, A.a22, A.a32, A.a13, A.a23, A.a33); - B.a20 = det3x3(A.a10, A.a20, A.a30, A.a11, A.a21, A.a31, A.a13, A.a23, A.a33); - B.a30 = -det3x3(A.a10, A.a20, A.a30, A.a11, A.a21, A.a31, A.a12, A.a22, A.a32); - - B.a01 = -det3x3(A.a01, A.a21, A.a31, A.a02, A.a22, A.a32, A.a03, A.a23, A.a33); - B.a11 = det3x3(A.a00, A.a20, A.a30, A.a02, A.a22, A.a32, A.a03, A.a23, A.a33); - B.a21 = -det3x3(A.a00, A.a20, A.a30, A.a01, A.a21, A.a31, A.a03, A.a23, A.a33); - B.a31 = det3x3(A.a00, A.a20, A.a30, A.a01, A.a21, A.a31, A.a02, A.a22, A.a32); - - B.a02 = det3x3(A.a01, A.a11, A.a31, A.a02, A.a12, A.a32, A.a03, A.a13, A.a33); - B.a12 = -det3x3(A.a00, A.a10, A.a30, A.a02, A.a12, A.a32, A.a03, A.a13, A.a33); - B.a22 = det3x3(A.a00, A.a10, A.a30, A.a01, A.a11, A.a31, A.a03, A.a13, A.a33); - B.a32 = -det3x3(A.a00, A.a10, A.a30, A.a01, A.a11, A.a31, A.a02, A.a12, A.a32); - - B.a03 = -det3x3(A.a01, A.a11, A.a21, A.a02, A.a12, A.a22, A.a03, A.a13, A.a23); - B.a13 = det3x3(A.a00, A.a10, A.a20, A.a02, A.a12, A.a22, A.a03, A.a13, A.a23); - B.a23 = -det3x3(A.a00, A.a10, A.a20, A.a01, A.a11, A.a21, A.a03, A.a13, A.a23); - B.a33 = det3x3(A.a00, A.a10, A.a20, A.a01, A.a11, A.a21, A.a02, A.a12, A.a22); - - det = (A.a00 * B.a00) + (A.a01 * B.a10) + (A.a02 * B.a20) + (A.a03 * B.a30); - - oodet = nv_one / det; - - B.a00 *= oodet; - B.a10 *= oodet; - B.a20 *= oodet; - B.a30 *= oodet; - - B.a01 *= oodet; - B.a11 *= oodet; - B.a21 *= oodet; - B.a31 *= oodet; - - B.a02 *= oodet; - B.a12 *= oodet; - B.a22 *= oodet; - B.a32 *= oodet; - - B.a03 *= oodet; - B.a13 *= oodet; - B.a23 *= oodet; - B.a33 *= oodet; - - return B; -} - -mat4& invert_rot_trans(mat4& B, const mat4& A) -{ - B.a00 = A.a00; - B.a10 = A.a01; - B.a20 = A.a02; - B.a30 = A.a30; - B.a01 = A.a10; - B.a11 = A.a11; - B.a21 = A.a12; - B.a31 = A.a31; - B.a02 = A.a20; - B.a12 = A.a21; - B.a22 = A.a22; - B.a32 = A.a32; - B.a03 = -(A.a00 * A.a03 + A.a10 * A.a13 + A.a20 * A.a23); - B.a13 = -(A.a01 * A.a03 + A.a11 * A.a13 + A.a21 * A.a23); - B.a23 = -(A.a02 * A.a03 + A.a12 * A.a13 + A.a22 * A.a23); - B.a33 = A.a33; - return B; -} - -nv_scalar det(const mat3& A) { return det3x3(A.a00, A.a01, A.a02, A.a10, A.a11, A.a12, A.a20, A.a21, A.a22); } -mat3& invert(mat3& B, const mat3& A) -{ - nv_scalar det, oodet; - - B.a00 = (A.a11 * A.a22 - A.a21 * A.a12); - B.a10 = -(A.a10 * A.a22 - A.a20 * A.a12); - B.a20 = (A.a10 * A.a21 - A.a20 * A.a11); - B.a01 = -(A.a01 * A.a22 - A.a21 * A.a02); - B.a11 = (A.a00 * A.a22 - A.a20 * A.a02); - B.a21 = -(A.a00 * A.a21 - A.a20 * A.a01); - B.a02 = (A.a01 * A.a12 - A.a11 * A.a02); - B.a12 = -(A.a00 * A.a12 - A.a10 * A.a02); - B.a22 = (A.a00 * A.a11 - A.a10 * A.a01); - - det = (A.a00 * B.a00) + (A.a01 * B.a10) + (A.a02 * B.a20); - - oodet = nv_one / det; - - B.a00 *= oodet; - B.a01 *= oodet; - B.a02 *= oodet; - B.a10 *= oodet; - B.a11 *= oodet; - B.a12 *= oodet; - B.a20 *= oodet; - B.a21 *= oodet; - B.a22 *= oodet; - return B; -} - -vec3& normalize(vec3& u) -{ - nv_scalar norm = _sqrt(u.x * u.x + u.y * u.y + u.z * u.z); - if (norm > nv_eps) - norm = nv_one / norm; - else - norm = nv_zero; - return scale(u, norm); -} - -vec4& normalize(vec4& u) -{ - nv_scalar norm = _sqrt(u.x * u.x + u.y * u.y + u.z * u.z + u.w * u.w); - if (norm > nv_eps) - norm = nv_one / norm; - else - norm = nv_zero; - return scale(u, norm); -} - -quat& normalize(quat& p) -{ - nv_scalar norm = _sqrt(p.x * p.x + p.y * p.y + p.z * p.z + p.w * p.w); - if (norm > nv_eps) - norm = nv_one / norm; - else - norm = nv_zero; - p.x *= norm; - p.y *= norm; - p.z *= norm; - p.w *= norm; - return p; -} - -mat4& look_at(mat4& M, const vec3& eye, const vec3& center, const vec3& up) -{ - vec3 x, y, z; - - // make rotation matrix - - // Z vector - z.x = eye.x - center.x; - z.y = eye.y - center.y; - z.z = eye.z - center.z; - normalize(z); - - // Y vector - y.x = up.x; - y.y = up.y; - y.z = up.z; - - // X vector = Y cross Z - cross(x, y, z); - - // Recompute Y = Z cross X - cross(y, z, x); - - // cross product gives area of parallelogram, which is < 1.0 for - // non-perpendicular unit-length vectors; so normalize x, y here - normalize(x); - normalize(y); - - M.a00 = x.x; - M.a01 = x.y; - M.a02 = x.z; - M.a03 = -x.x * eye.x - x.y * eye.y - x.z * eye.z; - M.a10 = y.x; - M.a11 = y.y; - M.a12 = y.z; - M.a13 = -y.x * eye.x - y.y * eye.y - y.z * eye.z; - M.a20 = z.x; - M.a21 = z.y; - M.a22 = z.z; - M.a23 = -z.x * eye.x - z.y * eye.y - z.z * eye.z; - M.a30 = nv_zero; - M.a31 = nv_zero; - M.a32 = nv_zero; - M.a33 = nv_one; - return M; -} - -mat4& frustum(mat4& M, const nv_scalar l, const nv_scalar r, const nv_scalar b, const nv_scalar t, const nv_scalar n, - const nv_scalar f) -{ - M.a00 = (nv_two * n) / (r - l); - M.a10 = 0.0; - M.a20 = 0.0; - M.a30 = 0.0; - - M.a01 = 0.0; - M.a11 = (nv_two * n) / (t - b); - M.a21 = 0.0; - M.a31 = 0.0; - - M.a02 = (r + l) / (r - l); - M.a12 = (t + b) / (t - b); - M.a22 = -(f + n) / (f - n); - M.a32 = -nv_one; - - M.a03 = 0.0; - M.a13 = 0.0; - M.a23 = -(nv_two * f * n) / (f - n); - M.a33 = 0.0; - return M; -} - -mat4& perspective(mat4& M, const nv_scalar fovy, const nv_scalar aspect, const nv_scalar n, const nv_scalar f) -{ - nv_scalar xmin, xmax, ymin, ymax; - - ymax = n * tan(fovy * nv_to_rad * nv_zero_5); - ymin = -ymax; - - xmin = ymin * aspect; - xmax = ymax * aspect; - - return frustum(M, xmin, xmax, ymin, ymax, n, f); -} - -const quat quat::Identity(0, 0, 0, 1); - -quat::quat(nv_scalar xIn, nv_scalar yIn, nv_scalar zIn, nv_scalar wIn) : x(xIn), y(yIn), z(zIn), w(wIn) {} -quat::quat(const quat& quat) -{ - x = quat.x; - y = quat.y; - z = quat.z; - w = quat.w; -} - -quat::quat(const vec3& axis, nv_scalar angle) -{ - nv_scalar len = axis.norm(); - if (len) - { - nv_scalar invLen = 1 / len; - nv_scalar angle2 = angle / 2; - nv_scalar scale = _sin(angle2) * invLen; - x = scale * axis[0]; - y = scale * axis[1]; - z = scale * axis[2]; - w = _cos(angle2); - } -} - -quat::quat(const mat3& rot) { FromMatrix(rot); } -quat& quat::operator=(const quat& quat) -{ - x = quat.x; - y = quat.y; - z = quat.z; - w = quat.w; - return *this; -} - -quat quat::Inverse() { return quat(-x, -y, -z, w); } -void quat::Normalize() -{ - nv_scalar len = _sqrt(x * x + y * y + z * z + w * w); - if (len > 0) - { - nv_scalar invLen = 1 / len; - x *= invLen; - y *= invLen; - z *= invLen; - w *= invLen; - } -} - -void quat::FromMatrix(const mat3& mat) -{ - nv_scalar trace = mat(0, 0) + mat(1, 1) + mat(2, 2); - if (trace > 0) - { - nv_scalar scale = _sqrt(trace + 1.0f); - w = 0.5f * scale; - scale = 0.5f / scale; - x = scale * (mat(2, 1) - mat(1, 2)); - y = scale * (mat(0, 2) - mat(2, 0)); - z = scale * (mat(1, 0) - mat(0, 1)); - } - else - { - static int next[] = {1, 2, 0}; - int i = 0; - if (mat(1, 1) > mat(0, 0)) - i = 1; - if (mat(2, 2) > mat(i, i)) - i = 2; - int j = next[i]; - int k = next[j]; - nv_scalar scale = _sqrt(mat(i, i) - mat(j, j) - mat(k, k) + 1); - nv_scalar* q[] = {&x, &y, &z}; - *q[i] = 0.5f * scale; - scale = 0.5f / scale; - w = scale * (mat(k, j) - mat(j, k)); - *q[j] = scale * (mat(j, i) + mat(i, j)); - *q[k] = scale * (mat(k, i) + mat(i, k)); - } -} - -void quat::ToMatrix(mat3& mat) const -{ - nv_scalar x2 = x * 2; - nv_scalar y2 = y * 2; - nv_scalar z2 = z * 2; - nv_scalar wx = x2 * w; - nv_scalar wy = y2 * w; - nv_scalar wz = z2 * w; - nv_scalar xx = x2 * x; - nv_scalar xy = y2 * x; - nv_scalar xz = z2 * x; - nv_scalar yy = y2 * y; - nv_scalar yz = z2 * y; - nv_scalar zz = z2 * z; - mat(0, 0) = 1 - (yy + zz); - mat(0, 1) = xy - wz; - mat(0, 2) = xz + wy; - mat(1, 0) = xy + wz; - mat(1, 1) = 1 - (xx + zz); - mat(1, 2) = yz - wx; - mat(2, 0) = xz - wy; - mat(2, 1) = yz + wx; - mat(2, 2) = 1 - (xx + yy); -} - -const quat operator*(const quat& p, const quat& q) -{ - return quat(p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y, p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z, - p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x, p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z); -} - -quat& quat::operator*=(const quat& quat) -{ - *this = *this * quat; - return *this; -} - -mat3& quat_2_mat(mat3& M, const quat& q) -{ - q.ToMatrix(M); - return M; -} - -quat& mat_2_quat(quat& q, const mat3& M) -{ - q.FromMatrix(M); - return q; -} - -quat& mat_2_quat(quat& q, const mat4& M) -{ - mat3 m; - M.get_rot(m); - q.FromMatrix(m); - return q; -} - -/* - Given an axis and angle, compute quaternion. - */ -quat& axis_to_quat(quat& q, const vec3& a, const nv_scalar phi) -{ - vec3 tmp(a.x, a.y, a.z); - - normalize(tmp); - nv_scalar s = _sin(phi / nv_two); - q.x = s * tmp.x; - q.y = s * tmp.y; - q.z = s * tmp.z; - q.w = _cos(phi / nv_two); - return q; -} - -quat& conj(quat& p) -{ - p.x = -p.x; - p.y = -p.y; - p.z = -p.z; - return p; -} - -quat& conj(quat& p, const quat& q) -{ - p.x = -q.x; - p.y = -q.y; - p.z = -q.z; - p.w = q.w; - return p; -} - -quat& add_quats(quat& p, const quat& q1, const quat& q2) -{ - quat t1, t2; - - t1 = q1; - t1.x *= q2.w; - t1.y *= q2.w; - t1.z *= q2.w; - - t2 = q2; - t2.x *= q1.w; - t2.y *= q1.w; - t2.z *= q1.w; - - p.x = (q2.y * q1.z) - (q2.z * q1.y) + t1.x + t2.x; - p.y = (q2.z * q1.x) - (q2.x * q1.z) + t1.y + t2.y; - p.z = (q2.x * q1.y) - (q2.y * q1.x) + t1.z + t2.z; - p.w = q1.w * q2.w - (q1.x * q2.x + q1.y * q2.y + q1.z * q2.z); - - return p; -} - -nv_scalar& dot(nv_scalar& s, const quat& q1, const quat& q2) -{ - s = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; - return s; -} - -nv_scalar dot(const quat& q1, const quat& q2) { return q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; } -#ifndef acosf -#define acosf acos -#endif - -quat& slerp_quats(quat& p, nv_scalar s, const quat& q1, const quat& q2) -{ - nv_scalar cosine = dot(q1, q2); - if (cosine < -1) - cosine = -1; - else if (cosine > 1) - cosine = 1; - nv_scalar angle = (nv_scalar)acosf(cosine); - if (_abs(angle) < nv_eps) - { - p = q1; - return p; - } - nv_scalar sine = _sin(angle); - nv_scalar sineInv = 1.0f / sine; - nv_scalar c1 = _sin((1.0f - s) * angle) * sineInv; - nv_scalar c2 = _sin(s * angle) * sineInv; - p.x = c1 * q1.x + c2 * q2.x; - p.y = c1 * q1.y + c2 * q2.y; - p.z = c1 * q1.z + c2 * q2.z; - p.w = c1 * q1.w + c2 * q2.w; - return p; -} - -const int HALF_RAND = (RAND_MAX / 2); - -nv_scalar nv_random() { return ((nv_scalar)(rand() - HALF_RAND) / (nv_scalar)HALF_RAND); } -// v is normalized -// theta in radians -void mat3::set_rot(const nv_scalar& theta, const vec3& v) -{ - nv_scalar ct = nv_scalar(_cos(theta)); - nv_scalar st = nv_scalar(_sin(theta)); - - nv_scalar xx = v.x * v.x; - nv_scalar yy = v.y * v.y; - nv_scalar zz = v.z * v.z; - nv_scalar xy = v.x * v.y; - nv_scalar xz = v.x * v.z; - nv_scalar yz = v.y * v.z; - - a00 = xx + ct * (1 - xx); - a01 = xy + ct * (-xy) + st * -v.z; - a02 = xz + ct * (-xz) + st * v.y; - - a10 = xy + ct * (-xy) + st * v.z; - a11 = yy + ct * (1 - yy); - a12 = yz + ct * (-yz) + st * -v.x; - - a20 = xz + ct * (-xz) + st * -v.y; - a21 = yz + ct * (-yz) + st * v.x; - a22 = zz + ct * (1 - zz); -} - -void mat3::set_rot(const vec3& u, const vec3& v) -{ - nv_scalar phi; - nv_scalar h; - nv_scalar lambda; - vec3 w; - - cross(w, u, v); - dot(phi, u, v); - dot(lambda, w, w); - if (lambda > nv_eps) - h = (nv_one - phi) / lambda; - else - h = lambda; - - nv_scalar hxy = w.x * w.y * h; - nv_scalar hxz = w.x * w.z * h; - nv_scalar hyz = w.y * w.z * h; - - a00 = phi + w.x * w.x * h; - a01 = hxy - w.z; - a02 = hxz + w.y; - - a10 = hxy + w.z; - a11 = phi + w.y * w.y * h; - a12 = hyz - w.x; - - a20 = hxz - w.y; - a21 = hyz + w.x; - a22 = phi + w.z * w.z * h; -} - -void mat4::set_rot(const quat& q) -{ - mat3 m; - q.ToMatrix(m); - set_rot(m); -} - -// v is normalized -// theta in radians -void mat4::set_rot(const nv_scalar& theta, const vec3& v) -{ - nv_scalar ct = nv_scalar(_cos(theta)); - nv_scalar st = nv_scalar(_sin(theta)); - - nv_scalar xx = v.x * v.x; - nv_scalar yy = v.y * v.y; - nv_scalar zz = v.z * v.z; - nv_scalar xy = v.x * v.y; - nv_scalar xz = v.x * v.z; - nv_scalar yz = v.y * v.z; - - a00 = xx + ct * (1 - xx); - a01 = xy + ct * (-xy) + st * -v.z; - a02 = xz + ct * (-xz) + st * v.y; - - a10 = xy + ct * (-xy) + st * v.z; - a11 = yy + ct * (1 - yy); - a12 = yz + ct * (-yz) + st * -v.x; - - a20 = xz + ct * (-xz) + st * -v.y; - a21 = yz + ct * (-yz) + st * v.x; - a22 = zz + ct * (1 - zz); -} - -void mat4::set_rot(const vec3& u, const vec3& v) -{ - nv_scalar phi; - nv_scalar h; - nv_scalar lambda; - vec3 w; - - cross(w, u, v); - dot(phi, u, v); - dot(lambda, w, w); - if (lambda > nv_eps) - h = (nv_one - phi) / lambda; - else - h = lambda; - - nv_scalar hxy = w.x * w.y * h; - nv_scalar hxz = w.x * w.z * h; - nv_scalar hyz = w.y * w.z * h; - - a00 = phi + w.x * w.x * h; - a01 = hxy - w.z; - a02 = hxz + w.y; - - a10 = hxy + w.z; - a11 = phi + w.y * w.y * h; - a12 = hyz - w.x; - - a20 = hxz - w.y; - a21 = hyz + w.x; - a22 = phi + w.z * w.z * h; -} - -void mat4::set_rot(const mat3& M) -{ - // copy the 3x3 rotation block - a00 = M.a00; - a10 = M.a10; - a20 = M.a20; - a01 = M.a01; - a11 = M.a11; - a21 = M.a21; - a02 = M.a02; - a12 = M.a12; - a22 = M.a22; -} - -void mat4::set_translation(const vec3& t) -{ - a03 = t.x; - a13 = t.y; - a23 = t.z; -} - -vec3& mat4::get_translation(vec3& t) const -{ - t.x = a03; - t.y = a13; - t.z = a23; - return t; -} - -mat3& mat4::get_rot(mat3& M) const -{ - // assign the 3x3 rotation block - M.a00 = a00; - M.a10 = a10; - M.a20 = a20; - M.a01 = a01; - M.a11 = a11; - M.a21 = a21; - M.a02 = a02; - M.a12 = a12; - M.a22 = a22; - return M; -} - -quat& mat4::get_rot(quat& q) const -{ - mat3 m; - get_rot(m); - q.FromMatrix(m); - return q; -} - -mat3& tangent_basis(mat3& basis, const vec3& v0, const vec3& v1, const vec3& v2, const vec2& t0, const vec2& t1, - const vec2& t2, const vec3& n) -{ - vec3 cp; - vec3 e0(v1.x - v0.x, t1.s - t0.s, t1.t - t0.t); - vec3 e1(v2.x - v0.x, t2.s - t0.s, t2.t - t0.t); - - cross(cp, e0, e1); - if (_abs(cp.x) > nv_eps) - { - basis.a00 = -cp.y / cp.x; - basis.a10 = -cp.z / cp.x; - } - - e0.x = v1.y - v0.y; - e1.x = v2.y - v0.y; - - cross(cp, e0, e1); - if (_abs(cp.x) > nv_eps) - { - basis.a01 = -cp.y / cp.x; - basis.a11 = -cp.z / cp.x; - } - - e0.x = v1.z - v0.z; - e1.x = v2.z - v0.z; - - cross(cp, e0, e1); - if (_abs(cp.x) > nv_eps) - { - basis.a02 = -cp.y / cp.x; - basis.a12 = -cp.z / cp.x; - } - - // tangent... - nv_scalar oonorm = nv_one / _sqrt(basis.a00 * basis.a00 + basis.a01 * basis.a01 + basis.a02 * basis.a02); - basis.a00 *= oonorm; - basis.a01 *= oonorm; - basis.a02 *= oonorm; - - // binormal... - oonorm = nv_one / _sqrt(basis.a10 * basis.a10 + basis.a11 * basis.a11 + basis.a12 * basis.a12); - basis.a10 *= oonorm; - basis.a11 *= oonorm; - basis.a12 *= oonorm; - - // normal... - // compute the cross product TxB - basis.a20 = basis.a01 * basis.a12 - basis.a02 * basis.a11; - basis.a21 = basis.a02 * basis.a10 - basis.a00 * basis.a12; - basis.a22 = basis.a00 * basis.a11 - basis.a01 * basis.a10; - - oonorm = nv_one / _sqrt(basis.a20 * basis.a20 + basis.a21 * basis.a21 + basis.a22 * basis.a22); - basis.a20 *= oonorm; - basis.a21 *= oonorm; - basis.a22 *= oonorm; - - // Gram-Schmidt orthogonalization process for B - // compute the cross product B=NxT to obtain - // an orthogonal basis - basis.a10 = basis.a21 * basis.a02 - basis.a22 * basis.a01; - basis.a11 = basis.a22 * basis.a00 - basis.a20 * basis.a02; - basis.a12 = basis.a20 * basis.a01 - basis.a21 * basis.a00; - - if (basis.a20 * n.x + basis.a21 * n.y + basis.a22 * n.z < nv_zero) - { - basis.a20 = -basis.a20; - basis.a21 = -basis.a21; - basis.a22 = -basis.a22; - } - return basis; -} - -/* - * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet - * if we are away from the center of the sphere. - */ -nv_scalar tb_project_to_sphere(nv_scalar r, nv_scalar x, nv_scalar y) -{ - nv_scalar d, t, z; - - d = _sqrt(x * x + y * y); - if (d < r * 0.70710678118654752440) - { /* Inside sphere */ - z = _sqrt(r * r - d * d); - } - else - { /* On hyperbola */ - t = r / (nv_scalar)1.41421356237309504880; - z = t * t / d; - } - return z; -} - -/* - * Ok, simulate a track-ball. Project the points onto the virtual - * trackball, then figure out the axis of rotation, which is the cross - * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) - * Note: This is a deformed trackball-- is a trackball in the center, - * but is deformed into a hyperbolic sheet of rotation away from the - * center. This particular function was chosen after trying out - * several variations. - * - * It is assumed that the arguments to this routine are in the range - * (-1.0 ... 1.0) - */ -quat& trackball(quat& q, vec2& pt1, vec2& pt2, nv_scalar trackballsize) -{ - vec3 a; // Axis of rotation - nv_scalar phi; // how much to rotate about axis - vec3 d; - nv_scalar t; - - if (pt1.x == pt2.x && pt1.y == pt2.y) - { - // Zero rotation - q = quat_id; - return q; - } - - // First, figure out z-coordinates for projection of P1 and P2 to - // deformed sphere - vec3 p1(pt1.x, pt1.y, tb_project_to_sphere(trackballsize, pt1.x, pt1.y)); - vec3 p2(pt2.x, pt2.y, tb_project_to_sphere(trackballsize, pt2.x, pt2.y)); - - // Now, we want the cross product of P1 and P2 - cross(a, p1, p2); - - // Figure out how much to rotate around that axis. - d.x = p1.x - p2.x; - d.y = p1.y - p2.y; - d.z = p1.z - p2.z; - t = _sqrt(d.x * d.x + d.y * d.y + d.z * d.z) / (trackballsize); - - // Avoid problems with out-of-control values... - - if (t > nv_one) - t = nv_one; - if (t < -nv_one) - t = -nv_one; - phi = nv_two * nv_scalar(asin(t)); - axis_to_quat(q, a, phi); - return q; -} - -vec3& cube_map_normal(int i, int x, int y, int cubesize, vec3& v) -{ - nv_scalar s, t, sc, tc; - s = (nv_scalar(x) + nv_zero_5) / nv_scalar(cubesize); - t = (nv_scalar(y) + nv_zero_5) / nv_scalar(cubesize); - sc = s * nv_two - nv_one; - tc = t * nv_two - nv_one; - - switch (i) - { - case 0: - v.x = nv_one; - v.y = -tc; - v.z = -sc; - break; - case 1: - v.x = -nv_one; - v.y = -tc; - v.z = sc; - break; - case 2: - v.x = sc; - v.y = nv_one; - v.z = tc; - break; - case 3: - v.x = sc; - v.y = -nv_one; - v.z = -tc; - break; - case 4: - v.x = sc; - v.y = -tc; - v.z = nv_one; - break; - case 5: - v.x = -sc; - v.y = -tc; - v.z = -nv_one; - break; - } - normalize(v); - return v; -} - -// computes the area of a triangle -nv_scalar nv_area(const vec3& v1, const vec3& v2, const vec3& v3) -{ - vec3 cp_sum; - vec3 cp; - cross(cp_sum, v1, v2); - cp_sum += cross(cp, v2, v3); - cp_sum += cross(cp, v3, v1); - return nv_norm(cp_sum) * nv_zero_5; -} - -// computes the perimeter of a triangle -nv_scalar nv_perimeter(const vec3& v1, const vec3& v2, const vec3& v3) -{ - nv_scalar perim; - vec3 diff; - sub(diff, v1, v2); - perim = nv_norm(diff); - sub(diff, v2, v3); - perim += nv_norm(diff); - sub(diff, v3, v1); - perim += nv_norm(diff); - return perim; -} - -// compute the center and radius of the inscribed circle defined by the three vertices -nv_scalar nv_find_in_circle(vec3& center, const vec3& v1, const vec3& v2, const vec3& v3) -{ - nv_scalar area = nv_area(v1, v2, v3); - // if the area is null - if (area < nv_eps) - { - center = v1; - return nv_zero; - } - - nv_scalar oo_perim = nv_one / nv_perimeter(v1, v2, v3); - - vec3 diff; - - sub(diff, v2, v3); - mult(center, v1, nv_norm(diff)); - - sub(diff, v3, v1); - madd(center, v2, nv_norm(diff)); - - sub(diff, v1, v2); - madd(center, v3, nv_norm(diff)); - - center *= oo_perim; - - return nv_two * area * oo_perim; -} - -// compute the center and radius of the circumscribed circle defined by the three vertices -// i.e. the osculating circle of the three vertices -nv_scalar nv_find_circ_circle(vec3& center, const vec3& v1, const vec3& v2, const vec3& v3) -{ - vec3 e0; - vec3 e1; - nv_scalar d1, d2, d3; - nv_scalar c1, c2, c3, oo_c; - - sub(e0, v3, v1); - sub(e1, v2, v1); - dot(d1, e0, e1); - - sub(e0, v3, v2); - sub(e1, v1, v2); - dot(d2, e0, e1); - - sub(e0, v1, v3); - sub(e1, v2, v3); - dot(d3, e0, e1); - - c1 = d2 * d3; - c2 = d3 * d1; - c3 = d1 * d2; - oo_c = nv_one / (c1 + c2 + c3); - - mult(center, v1, c2 + c3); - madd(center, v2, c3 + c1); - madd(center, v3, c1 + c2); - center *= oo_c * nv_zero_5; - - return nv_zero_5 * _sqrt((d1 + d2) * (d2 + d3) * (d3 + d1) * oo_c); -} - -nv_scalar ffast_cos(const nv_scalar x) -{ - // assert: 0 <= fT <= PI/2 - // maximum absolute error = 1.1880e-03 - // speedup = 2.14 - - nv_scalar x_sqr = x * x; - nv_scalar res = nv_scalar(3.705e-02); - res *= x_sqr; - res -= nv_scalar(4.967e-01); - res *= x_sqr; - res += nv_one; - return res; -} - -nv_scalar fast_cos(const nv_scalar x) -{ - // assert: 0 <= fT <= PI/2 - // maximum absolute error = 2.3082e-09 - // speedup = 1.47 - - nv_scalar x_sqr = x * x; - nv_scalar res = nv_scalar(-2.605e-07); - res *= x_sqr; - res += nv_scalar(2.47609e-05); - res *= x_sqr; - res -= nv_scalar(1.3888397e-03); - res *= x_sqr; - res += nv_scalar(4.16666418e-02); - res *= x_sqr; - res -= nv_scalar(4.999999963e-01); - res *= x_sqr; - res += nv_one; - return res; -} - -void nv_is_valid(const vec3& v) -{ - assert(!_isnan(v.x) && !_isnan(v.y) && !_isnan(v.z) && _finite(v.x) && _finite(v.y) && _finite(v.z)); -} - -void nv_is_valid(nv_scalar lambda) { assert(!_isnan(lambda) && _finite(lambda)); } diff --git a/src/utils/xrLC/NvMender2002/nv_algebra.h b/src/utils/xrLC/NvMender2002/nv_algebra.h deleted file mode 100644 index 0eefeabfdb6..00000000000 --- a/src/utils/xrLC/NvMender2002/nv_algebra.h +++ /dev/null @@ -1,631 +0,0 @@ -/*********************************************************************NVMH1**** -File: -nv_algebra.h - -Copyright (C) 1999, 2002 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - - -******************************************************************************/ - -#ifndef nv_algebraH -#define nv_algebraH - -struct DECLSPEC_NV_MATH vec2 -{ - vec2() {} - vec2(nv_scalar x, nv_scalar y) : x(x), y(y) {} - vec2(const nv_scalar* xy) : x(xy[0]), y(xy[1]) {} - vec2(const vec2& u) : x(u.x), y(u.y) {} - vec2(const vec3t&); - - bool operator==(const vec2& u) const { return (u.x == x && u.y == y) ? true : false; } - bool operator!=(const vec2& u) const { return !(*this == u); } - vec2& operator*=(const nv_scalar& lambda) - { - x *= lambda; - y *= lambda; - return *this; - } - - vec2& operator-=(const vec2& u) - { - x -= u.x; - y -= u.y; - return *this; - } - - vec2& operator+=(const vec2& u) - { - x += u.x; - y += u.y; - return *this; - } - - nv_scalar& operator[](int i) { return vec_array[i]; } - const nv_scalar operator[](int i) const { return vec_array[i]; } - union - { - struct - { - nv_scalar x, y; // standard names for components - }; - struct - { - nv_scalar s, t; // standard names for components - }; - nv_scalar vec_array[2]; // array access - }; -}; - -inline const vec2 operator+(const vec2& u, const vec2& v) { return vec2(u.x + v.x, u.y + v.y); } -inline const vec2 operator-(const vec2& u, const vec2& v) { return vec2(u.x - v.x, u.y - v.y); } -inline const vec2 operator*(const nv_scalar s, const vec2& u) { return vec2(s * u.x, s * u.y); } -inline const vec2 operator/(const vec2& u, const nv_scalar s) { return vec2(u.x / s, u.y / s); } -inline const vec2 operator*(const vec2& u, const vec2& v) { return vec2(u.x * v.x, u.y * v.y); } -template -struct vec3t -{ - vec3t() {} - vec3t(_T x, _T y, _T z) : x(x), y(y), z(z) {} - vec3t(const _T* xyz) : x(xyz[0]), y(xyz[1]), z(xyz[2]) {} - vec3t(const vec2& u) : x(u.x), y(u.y), z(1.0f) {} - vec3t(const vec3t& u) : x(_T(u.x)), y(_T(u.y)), z(_T(u.z)) {} - vec3t(const vec3t& u) : x(_T(u.x)), y(_T(u.y)), z(_T(u.z)) {} - vec3t(const vec4&); - - bool operator==(const vec3t<_T>& u) const { return (u.x == x && u.y == y && u.z == z) ? true : false; } - bool operator!=(const vec3t<_T>& rhs) const { return !(*this == rhs); } - vec3t<_T>& operator*=(const _T& lambda) - { - x *= lambda; - y *= lambda; - z *= lambda; - return *this; - } - vec3t<_T> operator-() const { return vec3t<_T>(-x, -y, -z); } - vec3t<_T>& operator-=(const vec3t<_T>& u) - { - x -= u.x; - y -= u.y; - z -= u.z; - return *this; - } - vec3t<_T>& operator+=(const vec3t<_T>& u) - { - x += u.x; - y += u.y; - z += u.z; - return *this; - } - _T sq_norm() const { return x * x + y * y + z * z; } - _T norm() const { return _sqrt(sq_norm()); } - _T normalize() - { - _T _norm = norm(); - if (_norm > nv_eps) - _norm = nv_one / _norm; - else - _norm = nv_zero; - x *= _norm; - y *= _norm; - z *= _norm; - return _norm; - } - - _T& operator[](int i) { return vec_array[i]; } - union - { - struct - { - _T x, y, z; // standard names for components - }; - struct - { - _T s, t, r; // standard names for components - }; - _T vec_array[3]; // array access - }; - - const _T operator[](int i) const { return vec_array[i]; } -}; - -template -inline const vec3t<_T> operator+(const vec3t<_T>& u, const vec3t<_T>& v) -{ - return vec3t<_T>(u.x + v.x, u.y + v.y, u.z + v.z); -} -template -inline const vec3t<_T> operator-(const vec3t<_T>& u, const vec3t<_T>& v) -{ - return vec3t<_T>(u.x - v.x, u.y - v.y, u.z - v.z); -} -template -inline const vec3t<_T> operator^(const vec3t<_T>& u, const vec3t<_T>& v) -{ - return vec3t<_T>(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x); -} -template -inline const vec3t<_T> operator*(const _T s, const vec3t<_T>& u) -{ - return vec3t<_T>(s * u.x, s * u.y, s * u.z); -} -template -inline const vec3t<_T> operator/(const vec3t<_T>& u, const _T s) -{ - return vec3t<_T>(u.x / s, u.y / s, u.z / s); -} -template -inline const vec3t<_T> operator*(const vec3t<_T>& u, const vec3t<_T>& v) -{ - return vec3t<_T>(u.x * v.x, u.y * v.y, u.z * v.z); -} - -// -typedef vec3t vec3; -typedef vec3t vec3f; -typedef vec3t vec3d; - -inline vec2::vec2(const vec3& u) -{ - nv_scalar k = 1 / u.z; - x = k * u.x; - y = k * u.y; -} - -struct DECLSPEC_NV_MATH vec4 -{ - vec4() {} - vec4(nv_scalar x, nv_scalar y, nv_scalar z, nv_scalar w) : x(x), y(y), z(z), w(w) {} - vec4(const nv_scalar* xyzw) : x(xyzw[0]), y(xyzw[1]), z(xyzw[2]), w(xyzw[3]) {} - vec4(const vec3& u) : x(u.x), y(u.y), z(u.z), w(1.0f) {} - vec4(const vec4& u) : x(u.x), y(u.y), z(u.z), w(u.w) {} - bool operator==(const vec4& u) const { return (u.x == x && u.y == y && u.z == z && u.w == w) ? true : false; } - bool operator!=(const vec4& rhs) const { return !(*this == rhs); } - vec4& operator*=(const nv_scalar& lambda) - { - x *= lambda; - y *= lambda; - z *= lambda; - w *= lambda; - return *this; - } - - vec4& operator-=(const vec4& u) - { - x -= u.x; - y -= u.y; - z -= u.z; - w -= u.w; - return *this; - } - - vec4& operator+=(const vec4& u) - { - x += u.x; - y += u.y; - z += u.z; - w += u.w; - return *this; - } - - vec4 operator-() const { return vec4(-x, -y, -z, -w); } - nv_scalar& operator[](int i) { return vec_array[i]; } - const nv_scalar operator[](int i) const { return vec_array[i]; } - union - { - struct - { - nv_scalar x, y, z, w; // standard names for components - }; - struct - { - nv_scalar s, t, r, q; // standard names for components - }; - nv_scalar vec_array[4]; // array access - }; -}; - -inline const vec4 operator+(const vec4& u, const vec4& v) { return vec4(u.x + v.x, u.y + v.y, u.z + v.z, u.w + v.w); } -inline const vec4 operator-(const vec4& u, const vec4& v) { return vec4(u.x - v.x, u.y - v.y, u.z - v.z, u.w - v.w); } -inline const vec4 operator*(const nv_scalar s, const vec4& u) { return vec4(s * u.x, s * u.y, s * u.z, s * u.w); } -inline const vec4 operator/(const vec4& u, const nv_scalar s) { return vec4(u.x / s, u.y / s, u.z / s, u.w / s); } -inline const vec4 operator*(const vec4& u, const vec4& v) { return vec4(u.x * v.x, u.y * v.y, u.z * v.z, u.w * v.w); } -template -inline vec3t<_T>::vec3t(const vec4& u) -{ - x = u.x; - y = u.y; - z = u.z; -} - -// quaternion -struct quat; - -/* - for all the matrices...a indicates the element at row x, col y - - For example: - a01 <-> row 0, col 1 -*/ - -struct DECLSPEC_NV_MATH mat3 -{ - mat3(); - mat3(const nv_scalar* array); - mat3(const mat3& M); - mat3(const nv_scalar& f0, const nv_scalar& f1, const nv_scalar& f2, const nv_scalar& f3, const nv_scalar& f4, - const nv_scalar& f5, const nv_scalar& f6, const nv_scalar& f7, const nv_scalar& f8) - : a00(f0), a10(f1), a20(f2), a01(f3), a11(f4), a21(f5), a02(f6), a12(f7), a22(f8) - { - } - - const vec3 col(const int i) const { return vec3(&mat_array[i * 3]); } - const vec3 operator[](int i) const { return vec3(mat_array[i], mat_array[i + 3], mat_array[i + 6]); } - const nv_scalar& operator()(const int& i, const int& j) const { return mat_array[j * 3 + i]; } - nv_scalar& operator()(const int& i, const int& j) { return mat_array[j * 3 + i]; } - void set_row(int i, const vec3& v) - { - mat_array[i] = v.x; - mat_array[i + 3] = v.y; - mat_array[i + 6] = v.z; - } - - void set_col(int i, const vec3& v) - { - mat_array[i * 3] = v.x; - mat_array[i * 3 + 1] = v.y; - mat_array[i * 3 + 2] = v.z; - } - - void set_rot(const nv_scalar& theta, const vec3& v); - void set_rot(const vec3& u, const vec3& v); - - union - { - struct - { - nv_scalar a00, a10, a20; // standard names for components - nv_scalar a01, a11, a21; // standard names for components - nv_scalar a02, a12, a22; // standard names for components - }; - nv_scalar mat_array[9]; // array access - }; -}; - -const vec3 operator*(const mat3&, const vec3&); -const vec3 operator*(const vec3&, const mat3&); - -struct DECLSPEC_NV_MATH mat4 -{ - mat4(); - mat4(const nv_scalar* array); - mat4(const mat4& M); - - mat4(const nv_scalar& f0, const nv_scalar& f1, const nv_scalar& f2, const nv_scalar& f3, const nv_scalar& f4, - const nv_scalar& f5, const nv_scalar& f6, const nv_scalar& f7, const nv_scalar& f8, const nv_scalar& f9, - const nv_scalar& f10, const nv_scalar& f11, const nv_scalar& f12, const nv_scalar& f13, const nv_scalar& f14, - const nv_scalar& f15) - : a00(f0), a10(f1), a20(f2), a30(f3), a01(f4), a11(f5), a21(f6), a31(f7), a02(f8), a12(f9), a22(f10), a32(f11), - a03(f12), a13(f13), a23(f14), a33(f15) - { - } - - const vec4 col(const int i) const { return vec4(&mat_array[i * 4]); } - const vec4 operator[](const int& i) const - { - return vec4(mat_array[i], mat_array[i + 4], mat_array[i + 8], mat_array[i + 12]); - } - - const nv_scalar& operator()(const int& i, const int& j) const { return mat_array[j * 4 + i]; } - nv_scalar& operator()(const int& i, const int& j) { return mat_array[j * 4 + i]; } - void set_col(int i, const vec4& v) - { - mat_array[i * 4] = v.x; - mat_array[i * 4 + 1] = v.y; - mat_array[i * 4 + 2] = v.z; - mat_array[i * 4 + 3] = v.w; - } - - void set_row(int i, const vec4& v) - { - mat_array[i] = v.x; - mat_array[i + 4] = v.y; - mat_array[i + 8] = v.z; - mat_array[i + 12] = v.w; - } - - mat3& get_rot(mat3& M) const; - quat& get_rot(quat& q) const; - void set_rot(const quat& q); - void set_rot(const mat3& M); - void set_rot(const nv_scalar& theta, const vec3& v); - void set_rot(const vec3& u, const vec3& v); - - void set_translation(const vec3& t); - vec3& get_translation(vec3& t) const; - - mat4 operator*(const mat4&)const; - - union - { - struct - { - nv_scalar a00, a10, a20, a30; // standard names for components - nv_scalar a01, a11, a21, a31; // standard names for components - nv_scalar a02, a12, a22, a32; // standard names for components - nv_scalar a03, a13, a23, a33; // standard names for components - }; - struct - { - nv_scalar _11, _12, _13, _14; // standard names for components - nv_scalar _21, _22, _23, _24; // standard names for components - nv_scalar _31, _32, _33, _34; // standard names for components - nv_scalar _41, _42, _43, _44; // standard names for components - }; - union - { - struct - { - nv_scalar b00, b10, b20, p; // standard names for components - nv_scalar b01, b11, b21, q; // standard names for components - nv_scalar b02, b12, b22, r; // standard names for components - nv_scalar x, y, z, w; // standard names for components - }; - }; - nv_scalar mat_array[16]; // array access - }; -}; - -const vec4 operator*(const mat4&, const vec4&); -const vec4 operator*(const vec4&, const mat4&); - -// quaternion -struct DECLSPEC_NV_MATH quat -{ -public: - quat(nv_scalar x = 0, nv_scalar y = 0, nv_scalar z = 0, nv_scalar w = 1); - quat(const quat& quat); - quat(const vec3& axis, nv_scalar angle); - quat(const mat3& rot); - quat& operator=(const quat& quat); - quat operator-() { return quat(-x, -y, -z, -w); } - quat Inverse(); - void Normalize(); - void FromMatrix(const mat3& mat); - void ToMatrix(mat3& mat) const; - quat& operator*=(const quat& quat); - static const quat Identity; - nv_scalar& operator[](int i) { return comp[i]; } - const nv_scalar operator[](int i) const { return comp[i]; } - union - { - struct - { - nv_scalar x, y, z, w; - }; - nv_scalar comp[4]; - }; -}; -const quat operator*(const quat&, const quat&); -extern quat& conj(quat& p, const quat& q); -extern quat& add_quats(quat& p, const quat& q1, const quat& q2); -extern nv_scalar dot(const quat& p, const quat& q); -extern quat& dot(nv_scalar s, const quat& p, const quat& q); -extern quat& slerp_quats(quat& p, nv_scalar s, const quat& q1, const quat& q2); -extern quat& axis_to_quat(quat& q, const vec3& a, const nv_scalar phi); -extern mat3& quat_2_mat(mat3& M, const quat& q); -extern quat& mat_2_quat(quat& q, const mat3& M); - -// constant algebraic values -const nv_scalar array16_id[] = {nv_one, nv_zero, nv_zero, nv_zero, nv_zero, nv_one, nv_zero, nv_zero, nv_zero, nv_zero, - nv_one, nv_zero, nv_zero, nv_zero, nv_zero, nv_one}; - -const nv_scalar array16_null[] = {nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, - nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero}; - -const nv_scalar array16_scale_bias[] = {nv_zero_5, nv_zero, nv_zero, nv_zero, nv_zero, nv_zero_5, nv_zero, nv_zero, - nv_zero, nv_zero, nv_zero_5, nv_zero, nv_zero_5, nv_zero_5, nv_zero_5, nv_one}; - -const nv_scalar array9_id[] = {nv_one, nv_zero, nv_zero, nv_zero, nv_one, nv_zero, nv_zero, nv_zero, nv_one}; - -const vec2 vec2_null(nv_zero, nv_zero); -const vec4 vec4_one(nv_one, nv_one, nv_one, nv_one); -const vec3 vec3_one(nv_one, nv_one, nv_one); -const vec3 vec3_null(nv_zero, nv_zero, nv_zero); -const vec3 vec3_x(nv_one, nv_zero, nv_zero); -const vec3 vec3_y(nv_zero, nv_one, nv_zero); -const vec3 vec3_z(nv_zero, nv_zero, nv_one); -const vec3 vec3_neg_x(-nv_one, nv_zero, nv_zero); -const vec3 vec3_neg_y(nv_zero, -nv_one, nv_zero); -const vec3 vec3_neg_z(nv_zero, nv_zero, -nv_one); -const vec4 vec4_null(nv_zero, nv_zero, nv_zero, nv_zero); -const vec4 vec4_x(nv_one, nv_zero, nv_zero, nv_zero); -const vec4 vec4_neg_x(-nv_one, nv_zero, nv_zero, nv_zero); -const vec4 vec4_y(nv_zero, nv_one, nv_zero, nv_zero); -const vec4 vec4_neg_y(nv_zero, -nv_one, nv_zero, nv_zero); -const vec4 vec4_z(nv_zero, nv_zero, nv_one, nv_zero); -const vec4 vec4_neg_z(nv_zero, nv_zero, -nv_one, nv_zero); -const vec4 vec4_w(nv_zero, nv_zero, nv_zero, nv_one); -const vec4 vec4_neg_w(nv_zero, nv_zero, nv_zero, -nv_one); -const quat quat_id(nv_zero, nv_zero, nv_zero, nv_one); -const mat4 mat4_id(array16_id); -const mat3 mat3_id(array9_id); -const mat4 mat4_null(array16_null); -const mat4 mat4_scale_bias(array16_scale_bias); - -// normalizes a vector and return a reference of itself -extern vec3& normalize(vec3& u); -extern vec4& normalize(vec4& u); - -// Computes the squared magnitude -inline nv_scalar nv_sq_norm(const vec3& n) { return n.x * n.x + n.y * n.y + n.z * n.z; } -inline nv_scalar nv_sq_norm(const vec4& n) { return n.x * n.x + n.y * n.y + n.z * n.z + n.w * n.w; } -// Computes the magnitude -inline nv_scalar nv_norm(const vec3& n) { return _sqrt(nv_sq_norm(n)); } -inline nv_scalar nv_norm(const vec4& n) { return _sqrt(nv_sq_norm(n)); } -// computes the cross product ( v cross w) and stores the result in u -// i.e. u = v cross w -extern vec3& cross(vec3& u, const vec3& v, const vec3& w); - -// computes the dot product ( v dot w) and stores the result in u -// i.e. u = v dot w -extern nv_scalar& dot(nv_scalar& u, const vec3& v, const vec3& w); -extern nv_scalar dot(const vec3& v, const vec3& w); -extern nv_scalar& dot(nv_scalar& u, const vec4& v, const vec4& w); -extern nv_scalar dot(const vec4& v, const vec4& w); -extern nv_scalar& dot(nv_scalar& u, const vec3& v, const vec4& w); -extern nv_scalar dot(const vec3& v, const vec4& w); -extern nv_scalar& dot(nv_scalar& u, const vec4& v, const vec3& w); -extern nv_scalar dot(const vec4& v, const vec3& w); - -// compute the reflected vector R of L w.r.t N - vectors need to be -// normalized -// -// R N L -// _ _ -// |\ ^ /| -// \ | / -// \ | / -// \|/ -// + -extern vec3& reflect(vec3& r, const vec3& n, const vec3& l); - -// Computes u = v * lambda + u -extern vec3& madd(vec3& u, const vec3& v, const nv_scalar& lambda); -// Computes u = v * lambda -extern vec3& mult(vec3& u, const vec3& v, const nv_scalar& lambda); -// Computes u = v * w -extern vec3& mult(vec3& u, const vec3& v, const vec3& w); -// Computes u = v + w -extern vec3& add(vec3& u, const vec3& v, const vec3& w); -// Computes u = v - w -extern vec3& sub(vec3& u, const vec3& v, const vec3& w); - -// Computes u = u * s -extern vec3& scale(vec3& u, const nv_scalar s); -extern vec4& scale(vec4& u, const nv_scalar s); - -// Computes u = M * v -extern vec3& mult(vec3& u, const mat3& M, const vec3& v); -extern vec4& mult(vec4& u, const mat4& M, const vec4& v); - -// Computes u = v * M -extern vec3& mult(vec3& u, const vec3& v, const mat3& M); -extern vec4& mult(vec4& u, const vec4& v, const mat4& M); - -// Computes u = M(4x4) * v and divides by w -extern vec3& mult_pos(vec3& u, const mat4& M, const vec3& v); -// Computes u = M(4x4) * v -extern vec3& mult_dir(vec3& u, const mat4& M, const vec3& v); -// Computes u = M(4x4) * v and does not divide by w (assumed to be 1) -extern vec3& mult(vec3& u, const mat4& M, const vec3& v); - -// Computes u = v * M(4x4) and divides by w -extern vec3& mult_pos(vec3& u, const vec3& v, const mat4& M); -// Computes u = v * M(4x4) -extern vec3& mult_dir(vec3& u, const vec3& v, const mat4& M); -// Computes u = v * M(4x4) and does not divide by w (assumed to be 1) -extern vec3& mult(vec3& u, const vec3& v, const mat4& M); - -// Computes A += B -extern mat4& add(mat4& A, const mat4& B); -extern mat3& add(mat3& A, const mat3& B); - -// Computes C = A * B -extern mat4& mult(mat4& C, const mat4& A, const mat4& B); -extern mat3& mult(mat3& C, const mat3& A, const mat3& B); - -// Computes B = Transpose(A) -// T -// B = A -extern mat3& transpose(mat3& B, const mat3& A); -extern mat4& transpose(mat4& B, const mat4& A); -extern mat3& transpose(mat3& B); -extern mat4& transpose(mat4& B); - -// Computes B = inverse(A) -// -1 -// B = A -extern mat4& invert(mat4& B, const mat4& A); -extern mat3& invert(mat3& B, const mat3& A); - -// Computes B = inverse(A) -// T T -// (R t) (R -R t) -// assuming that A = (0 1) so that B = (0 1) -// B = A -extern mat4& invert_rot_trans(mat4& B, const mat4& A); - -extern mat4& look_at(mat4& M, const vec3& eye, const vec3& center, const vec3& up); -extern mat4& frustum(mat4& M, const nv_scalar l, const nv_scalar r, const nv_scalar b, const nv_scalar t, - const nv_scalar n, const nv_scalar f); - -extern mat4& perspective(mat4& M, const nv_scalar fovy, const nv_scalar aspect, const nv_scalar n, const nv_scalar f); - -// quaternion -extern quat& normalize(quat& p); -extern quat& conj(quat& p); -extern quat& conj(quat& p, const quat& q); -extern quat& add_quats(quat& p, const quat& q1, const quat& q2); -extern quat& axis_to_quat(quat& q, const vec3& a, const nv_scalar phi); -extern mat3& quat_2_mat(mat3& M, const quat& q); -extern quat& mat_2_quat(quat& q, const mat3& M); -extern quat& mat_2_quat(quat& q, const mat4& M); - -// surface properties -extern mat3& tangent_basis(mat3& basis, const vec3& v0, const vec3& v1, const vec3& v2, const vec2& t0, const vec2& t1, - const vec2& t2, const vec3& n); - -// linear interpolation -inline nv_scalar lerp(nv_scalar t, nv_scalar a, nv_scalar b) { return a * (nv_one - t) + t * b; } -inline vec3& lerp(vec3& w, const nv_scalar& t, const vec3& u, const vec3& v) -{ - w.x = lerp(t, u.x, v.x); - w.y = lerp(t, u.y, v.y); - w.z = lerp(t, u.z, v.z); - return w; -} - -// utilities -inline nv_scalar nv_min(const nv_scalar& lambda, const nv_scalar& n) { return (lambda < n) ? lambda : n; } -inline nv_scalar nv_max(const nv_scalar& lambda, const nv_scalar& n) { return (lambda > n) ? lambda : n; } -inline nv_scalar nv_clamp(nv_scalar u, const nv_scalar min, const nv_scalar max) -{ - u = (u < min) ? min : u; - u = (u > max) ? max : u; - return u; -} - -extern nv_scalar nv_random(); - -extern quat& trackball(quat& q, vec2& pt1, vec2& pt2, nv_scalar trackballsize); - -extern vec3& cube_map_normal(int i, int x, int y, int cubesize, vec3& v); - -// geometry -// computes the area of a triangle -extern nv_scalar nv_area(const vec3& v1, const vec3& v2, const vec3& v3); -// computes the perimeter of a triangle -extern nv_scalar nv_perimeter(const vec3& v1, const vec3& v2, const vec3& v3); -// find the inscribed circle -extern nv_scalar nv_find_in_circle(vec3& center, const vec3& v1, const vec3& v2, const vec3& v3); -// find the circumscribed circle -extern nv_scalar nv_find_circ_circle(vec3& center, const vec3& v1, const vec3& v2, const vec3& v3); - -// fast cosine functions -extern nv_scalar fast_cos(const nv_scalar x); -extern nv_scalar ffast_cos(const nv_scalar x); - -// determinant -nv_scalar det(const mat3& A); - -extern void nv_is_valid(const vec3& v); -extern void nv_is_valid(nv_scalar lambda); - -#endif // nv_algebraH diff --git a/src/utils/xrLC/NvMender2002/nv_math.h b/src/utils/xrLC/NvMender2002/nv_math.h deleted file mode 100644 index fc8859f70f3..00000000000 --- a/src/utils/xrLC/NvMender2002/nv_math.h +++ /dev/null @@ -1,54 +0,0 @@ -/*********************************************************************NVMH1**** -File: -nv_math.h - -Copyright (C) 1999, 2002 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - - -******************************************************************************/ -#ifndef _nv_math_h_ -#define _nv_math_h_ - -#ifndef _nv_mathdecl_h_ -#include "nv_mathdecl.h" -#endif // _nv_mathdecl_h_ - -#include - -typedef f32 nv_scalar; - -#define nv_zero nv_scalar(0) -#define nv_zero_5 nv_scalar(0.5) -#define nv_one nv_scalar(1.0) -#define nv_two nv_scalar(2) -#define nv_half_pi nv_scalar(3.14159265358979323846264338327950288419716939937510582 * 0.5) -#define nv_quarter_pi nv_scalar(3.14159265358979323846264338327950288419716939937510582 * 0.25) -#define nv_pi nv_scalar(3.14159265358979323846264338327950288419716939937510582) -#define nv_two_pi nv_scalar(3.14159265358979323846264338327950288419716939937510582 * 2.0) -#define nv_oo_pi nv_one / nv_pi -#define nv_oo_two_pi nv_one / nv_two_pi -#define nv_oo_255 nv_one / nv_scalar(255) -#define nv_oo_128 nv_one / nv_scalar(128) -#define nv_to_rad nv_pi / nv_scalar(180) -#define nv_to_deg nv_scalar(180) / nv_pi -#define nv_eps nv_scalar(10e-6) -#define nv_double_eps nv_scalar(10e-6) * nv_two -#define nv_big_eps nv_scalar(10e-6) -#define nv_small_eps nv_scalar(10e-2) - -template -struct vec3t; -struct vec2; -struct vec4; - -#ifndef _nv_algebra_h_ -#include "nv_algebra.h" -#endif // _nv_algebra_h_ - -#endif //_nv_math_h_ diff --git a/src/utils/xrLC/NvMender2002/nv_mathdecl.h b/src/utils/xrLC/NvMender2002/nv_mathdecl.h deleted file mode 100644 index e2f2c7c0af2..00000000000 --- a/src/utils/xrLC/NvMender2002/nv_mathdecl.h +++ /dev/null @@ -1,31 +0,0 @@ -/*********************************************************************NVMH1**** -File: -nv_mathdecl.h - -Copyright (C) 1999, 2002 NVIDIA Corporation -This file is provided without support, instruction, or implied warranty of any -kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is -not liable under any circumstances for any damages or loss whatsoever arising -from the use or inability to use this file or items derived from it. - -Comments: - - -******************************************************************************/ - -#ifndef _nv_mathdecl_h_ -#define _nv_mathdecl_h_ - -#ifdef NV_MATH_DLL - -#ifdef NV_MATH_EXPORTS -#define DECLSPEC_NV_MATH __declspec(dllexport) -#else -#define DECLSPEC_NV_MATH __declspec(dllimport) -#endif - -#else -#define DECLSPEC_NV_MATH -#endif - -#endif // _nv_mathdecl_h_ diff --git a/src/utils/xrLC/NvMeshMenderLayer.h b/src/utils/xrLC/NvMeshMenderLayer.h deleted file mode 100644 index bcf94d037a3..00000000000 --- a/src/utils/xrLC/NvMeshMenderLayer.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __NVMESHMENDERLAYER_H__ -#define __NVMESHMENDERLAYER_H__ - -#include "NvMender2003/nvMeshMender.h" - -IC void set_vertex(MeshMender::Vertex& out_vertex, const Vertex& in_veretex, const Fvector2 Ftc); -IC void set_face(Face& out_face, const MeshMender::Vertex in_vertices[3]); -#include "NvMeshMenderLayerInline.h" -#endif //__NVMESHMENDERLAYER_H__ diff --git a/src/utils/xrLC/NvMeshMenderLayerInline.h b/src/utils/xrLC/NvMeshMenderLayerInline.h deleted file mode 100644 index 40b8853d783..00000000000 --- a/src/utils/xrLC/NvMeshMenderLayerInline.h +++ /dev/null @@ -1,64 +0,0 @@ - -#include "xrFace.h" - -IC D3DXVECTOR3& cv_vector(D3DXVECTOR3& l, const Fvector& r) -{ - l.x = r.x; - l.y = r.y; - l.z = r.z; - return l; -} - -IC Fvector& cv_vector(Fvector& l, const D3DXVECTOR3& r) -{ - l.x = r.x; - l.y = r.y; - l.z = r.z; - return l; -} - -IC void set_vertex(MeshMender::Vertex& out_vertex, const Vertex& in_veretex, const Fvector2 Ftc) -{ - cv_vector(out_vertex.pos, in_veretex.P); - cv_vector(out_vertex.normal, in_veretex.N); - out_vertex.s = Ftc.x; - out_vertex.t = Ftc.y; - // out_vertex.tangent; - // out_vertex.binormal; -} - -IC void set_face(Face& out_face, const MeshMender::Vertex in_vertices[3]) -{ - for (u16 v = 0; v < 3; ++v) - { - out_face.tc.front().uv[v].set(in_vertices[v].s, in_vertices[v].t); - Fvector tangent; - Fvector binormal; - out_face.basis_tangent[v].set(cv_vector(tangent, in_vertices[v].tangent)); - out_face.basis_binormal[v].set(cv_vector(binormal, in_vertices[v].binormal)); - } -} - -IC void set_vertex(MeshMender::Vertex& out_vertex, const OGF_Vertex& in_vertex) -{ - cv_vector(out_vertex.pos, in_vertex.P); - cv_vector(out_vertex.normal, in_vertex.N); - out_vertex.s = in_vertex.UV[0].x; - out_vertex.t = in_vertex.UV[0].y; - // out_vertex.tangent; - // out_vertex.binormal; -} - -IC void set_vertex(OGF_Vertex& out_vertex, const OGF_Vertex& in_old_vertex, const MeshMender::Vertex& in_vertex) -{ - out_vertex = in_old_vertex; - cv_vector(out_vertex.P, in_vertex.pos); - cv_vector(out_vertex.N, in_vertex.normal); - - out_vertex.UV[0].x = in_vertex.s; - out_vertex.UV[0].y = in_vertex.t; - Fvector tangent; - Fvector binormal; - out_vertex.T.set(cv_vector(tangent, in_vertex.tangent)); - out_vertex.B.set(cv_vector(binormal, in_vertex.binormal)); -} diff --git a/src/utils/xrLC/OGF_CalculateTB.cpp b/src/utils/xrLC/OGF_CalculateTB.cpp deleted file mode 100644 index 924f568da97..00000000000 --- a/src/utils/xrLC/OGF_CalculateTB.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "stdafx.h" - -#include "MeshMenderLayerOGF.h" - -static xr_vector mender_in_out_verts; -static xr_vector mender_in_out_indices; -static xr_vector mender_mapping_out_to_in_vert; -void remove_isolated_verts(vecOGF_V& vertices, vecOGF_F& faces); -// Calculate T&B -void OGF::CalculateTB() -{ - remove_isolated_verts(data.vertices, data.faces); - // ************************************* Declare inputs - Logger.Status("Declarator..."); - u32 v_count_reserve = iFloor(float(data.vertices.size()) * 1.33f); - u32 i_count_reserve = 3 * data.faces.size(); - - mender_mapping_out_to_in_vert.clear(); - - mender_mapping_out_to_in_vert.reserve(v_count_reserve); - mender_in_out_verts.reserve(v_count_reserve); - mender_in_out_indices.reserve(i_count_reserve); - - mender_in_out_verts.clear(); - mender_in_out_indices.clear(); - fill_mender_input(data.vertices, data.faces, mender_in_out_verts, mender_in_out_indices); - - u32 v_was = data.vertices.size(); - u32 v_become = mender_in_out_verts.size(); - Logger.clMsg( - "duplication: was[%d] / become[%d] - %2.1f%%", v_was, v_become, 100.f * float(v_become - v_was) / float(v_was)); - - // ************************************* Perform mungle - Logger.Status("Calculating basis..."); - - MeshMender mender; - if (!mender.Mend(mender_in_out_verts, mender_in_out_indices, mender_mapping_out_to_in_vert, 1, 0.5, 0.5, 0.0f, - MeshMender::DONT_CALCULATE_NORMALS, MeshMender::RESPECT_SPLITS, MeshMender::DONT_FIX_CYLINDRICAL)) - { - xrDebug::Fatal(DEBUG_INFO, "NVMeshMender failed "); - // xrDebug::Fatal (DEBUG_INFO,"NVMeshMender failed (%s)",mender.GetLastError().c_str()); - } - - // ************************************* Bind declarators - // bind - - retrive_data_from_mender_otput( - data.vertices, data.faces, mender_in_out_verts, mender_in_out_indices, mender_mapping_out_to_in_vert); - remove_isolated_verts(data.vertices, data.faces); - - mender_in_out_verts.clear(); - mender_in_out_indices.clear(); - mender_mapping_out_to_in_vert.clear(); -} diff --git a/src/utils/xrLC/OGF_Face.cpp b/src/utils/xrLC/OGF_Face.cpp deleted file mode 100644 index 5087d8c6bb1..00000000000 --- a/src/utils/xrLC/OGF_Face.cpp +++ /dev/null @@ -1,571 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "ogf_face.h" -#include "xrCore/fs.h" -#include "xrCore/FMesh.hpp" -#include "xrCore/_sphere.h" -#include "xrCore/Threading/Lock.hpp" - -using namespace std; - -void set_status(char* N, int id, int f, int v) -{ - string1024 status_str; - - xr_sprintf(status_str, "Model #%4d [F:%5d, V:%5d]: %s...", id, f, v, N); - Logger.Status(status_str); - Logger.clMsg(status_str); -} - -BOOL OGF_Vertex::similar(OGF* ogf, OGF_Vertex& V) -{ - const float ntb = _cos(deg2rad(5.f)); - if (!P.similar(V.P)) - return FALSE; - if (!N.similar(V.N)) - return FALSE; - if (!T.similar(V.T)) - return FALSE; - if (!B.similar(V.B)) - return FALSE; - - R_ASSERT(UV.size() == V.UV.size()); - for (size_t i = 0; i < V.UV.size(); i++) - { - OGF_Texture* T = &*ogf->textures.begin() + i; - b_texture* B = T->pBuildSurface; - float eu = 1.f / float(B->dwWidth); - float ev = 1.f / float(B->dwHeight); - if (!UV[i].similar(V.UV[i], eu, ev)) - return FALSE; - } - return TRUE; -} -void OGF_Vertex::dump(u32 id) -{ - // Msg ("%d: "); -} -BOOL x_vertex::similar(OGF* ogf, x_vertex& V) { return P.similar(V.P); } -u16 OGF::x_BuildVertex(x_vertex& V1) -{ - for (itXV it = fast_path_data.vertices.begin(); it != fast_path_data.vertices.end(); ++it) - if (it->similar(this, V1)) - return u16(it - fast_path_data.vertices.begin()); - fast_path_data.vertices.push_back(V1); - return (u32)fast_path_data.vertices.size() - 1; -} -u16 OGF::_BuildVertex(OGF_Vertex& V1) -{ - try - { - for (itOGF_V it = data.vertices.begin(); it != data.vertices.end(); ++it) - { - if (it->similar(this, V1)) - return u16(it - data.vertices.begin()); - } - } - catch (...) - { - Logger.clMsg("* ERROR: OGF::_BuildVertex"); - } - - data.vertices.push_back(V1); - return (u32)data.vertices.size() - 1; -} -void OGF::x_BuildFace(OGF_Vertex& V1, OGF_Vertex& V2, OGF_Vertex& V3, bool _tc_) -{ - if (_tc_) - return; // make empty-list for stuff that has relevant TCs - x_face F; - const size_t VertCount = fast_path_data.vertices.size(); - F.v[0] = x_BuildVertex(x_vertex(V1)); - F.v[1] = x_BuildVertex(x_vertex(V2)); - F.v[2] = x_BuildVertex(x_vertex(V3)); - if (!F.Degenerate()) - { - fast_path_data.faces.push_back(F); - } - else - { - if (fast_path_data.vertices.size() > VertCount) - fast_path_data.vertices.erase(fast_path_data.vertices.begin() + VertCount, fast_path_data.vertices.end()); - } -} -void OGF::_BuildFace(OGF_Vertex& V1, OGF_Vertex& V2, OGF_Vertex& V3, bool _tc_) -{ - OGF_Face F; - const size_t VertCount = data.vertices.size(); - F.v[0] = _BuildVertex(V1); - F.v[1] = _BuildVertex(V2); - F.v[2] = _BuildVertex(V3); - if (!F.Degenerate()) - { - for (itOGF_F I = data.faces.begin(); I != data.faces.end(); ++I) - if (I->Equal(F)) - return; - data.faces.push_back(F); - x_BuildFace(V1, V2, V3, _tc_); - } - else - { - if (data.vertices.size() > VertCount) - data.vertices.erase(data.vertices.begin() + VertCount, data.vertices.end()); - } -} -BOOL OGF::dbg_SphereContainsVertex(Fvector& c, float R) -{ - Fsphere S; - S.set(c, R); - for (size_t it = 0; it < data.vertices.size(); it++) - if (S.contains(data.vertices[it].P)) - return TRUE; - return FALSE; -} - -void OGF::adjacent_select(xr_vector& dest, xr_vector& vmark, xr_vector& fmark) -{ - // 0. Search for the group - for (size_t fit = 0; fit < data.faces.size(); fit++) - { - OGF_Face& F = data.faces[fit]; - if (fmark[fit]) - continue; // already registered - - // new face - if empty - just put it in, else check connectivity - if (dest.empty()) - { - fmark[fit] = true; - dest.push_back(F.v[0]); - vmark[F.v[0]] = true; - dest.push_back(F.v[1]); - vmark[F.v[1]] = true; - dest.push_back(F.v[2]); - vmark[F.v[2]] = true; - } - else - { - // check connectivity - BOOL bConnected = FALSE; - for (size_t vid = 0; vid < 3; vid++) - { - const size_t id = F.v[vid]; // search in already registered verts - for (size_t sid = 0; sid < dest.size(); sid++) - { - if (id == dest[sid]) - { - bConnected = TRUE; // this face shares at least one vertex with already selected faces - break; - } - } - if (bConnected) - break; - } - if (bConnected) - { - // add this face's vertices - fmark[fit] = true; - if (!vmark[F.v[0]]) - { - dest.push_back(F.v[0]); - vmark[F.v[0]] = true; - } - if (!vmark[F.v[1]]) - { - dest.push_back(F.v[1]); - vmark[F.v[1]] = true; - } - if (!vmark[F.v[2]]) - { - dest.push_back(F.v[2]); - vmark[F.v[2]] = true; - } - } - } - } -} - -void OGF::Optimize() -{ - // Real optimization - ////////////////////////////////////////////////////////////////////////// - // x-vertices - try - { - if (fast_path_data.vertices.size() && fast_path_data.faces.size()) - { - try - { - VERIFY(fast_path_data.vertices.size() <= data.vertices.size()); - VERIFY(fast_path_data.faces.size() == data.faces.size()); - } - catch (...) - { - Msg("* ERROR: optimize: x-geom : verify: failed"); - } - - // Optimize texture coordinates - /* - Fvector2 Tdelta; - try { - // 1. Calc bounds - Fvector2 Tmin,Tmax; - Tmin.set(flt_max,flt_max); - Tmax.set(flt_min,flt_min); - for (size_t j=0; jshaders().Get(pBuild->materials()[material].reserved); - if (!SH->flags.bOptimizeUV) - return; - } - catch (...) - { - Msg("* ERROR: optimize: std-geom : find relevant UV"); - } - - // Build p-rep - /* - typedef xr_vector flist ; - xr_vector prep ; prep.resize(vertices.size()); - for (u32 fit=0; fit vmarker; - vmarker.assign(data.vertices.size(), false); - xr_vector fmarker; - fmarker.assign(data.faces.size(), false); - - for (;;) - { - // 0. Search for the group - xr_vector selection; - for (;;) - { - const size_t _old = selection.size(); - adjacent_select(selection, vmarker, fmarker); - const size_t _new = selection.size(); - if (_old == _new) - break; // group selected ! - } - if (selection.empty()) - break; - - // 1. Calc bounds - Fvector2 Tdelta; - try - { - Fvector2 Tmin, Tmax; - Tmin.set(flt_max, flt_max); - Tmax.set(flt_min, flt_min); - for (size_t j = 0; j < selection.size(); j++) - { - OGF_Vertex& V = data.vertices[selection[j]]; - Tmin.min(V.UV[0]); - Tmax.max(V.UV[0]); - } - Tdelta.x = floorf((Tmax.x - Tmin.x) / 2 + Tmin.x); - Tdelta.y = floorf((Tmax.y - Tmin.y) / 2 + Tmin.y); - } - catch (...) - { - Msg("* ERROR: optimize: std-geom : delta UV"); - } - - // 2. Recalc UV mapping - try - { - for (size_t i = 0; i < selection.size(); i++) - data.vertices[selection[i]].UV[0].sub(Tdelta); - } - catch (...) - { - Msg("* ERROR: optimize: std-geom : recalc UV"); - } - selection.clear(); - } -} - -// Make Progressive -Lock progressive_cs -#ifdef CONFIG_PROFILE_LOCKS - (MUTEX_PROFILE_ID(progressive_cs)) -#endif // CONFIG_PROFILE_LOCKS - ; -void OGF::MakeProgressive(float metric_limit) -{ - // test - // there is no-sense to simplify small models - // for batch size 50,100,200 - we are CPU-limited anyway even on nv30 - // for nv40 and up the better guess will probably be around 500 - if (data.faces.size() < c_PM_FaceLimit) - return; - - //. AlexMX added for draft build mode - if (g_params().m_quality == ebqDraft) - return; - - progressive_cs.Enter(); - - ////////////////////////////////////////////////////////////////////////// - // NORMAL - vecOGF_V _saved_vertices = data.vertices; - vecOGF_F _saved_faces = data.faces; - - { - // prepare progressive geom - VIPM_Init(); - // clMsg("--- append v start ."); - for (size_t v_idx = 0; v_idx < data.vertices.size(); v_idx++) - VIPM_AppendVertex(data.vertices[v_idx].P, data.vertices[v_idx].UV[0]); - // clMsg("--- append f start ."); - for (size_t f_idx = 0; f_idx < data.faces.size(); f_idx++) - VIPM_AppendFace(data.faces[f_idx].v[0], data.faces[f_idx].v[1], data.faces[f_idx].v[2]); - // clMsg("--- append end."); - - // Convert - VIPM_Result* VR = 0; - try - { - VR = VIPM_Convert(u32(25), 1.f, 1); - } - catch (...) - { - progressive_clear(); - Logger.clMsg("* mesh simplification failed: access violation"); - } - if (0 == VR) - { - progressive_clear(); - Logger.clMsg("* mesh simplification failed"); - } - while (VR && VR->swr_records.size() > 0) - { - // test metric - u32 _full = data.vertices.size(); - u32 _remove = VR->swr_records.size(); - u32 _simple = _full - _remove; - float _metric = float(_remove) / float(_full); - if (_metric < metric_limit) - { - progressive_clear(); - Logger.clMsg("* mesh simplified from [%4dv] to [%4dv], nf[%4d] ==> em[%0.2f]-discarded", _full, _simple, - VR->indices.size() / 3, metric_limit); - break; - } - else - { - Logger.clMsg("* mesh simplified from [%4dv] to [%4dv], nf[%4d] ==> em[%0.2f]-accepted", _full, _simple, - VR->indices.size() / 3, metric_limit); - } - - // OK - // Permute vertices - for (size_t i = 0; i < data.vertices.size(); i++) - data.vertices[VR->permute_verts[i]] = _saved_vertices[i]; - - // Fill indices - data.faces.resize(VR->indices.size() / 3); - for (size_t f_idx = 0; f_idx < data.faces.size(); f_idx++) - { - data.faces[f_idx].v[0] = VR->indices[f_idx * 3 + 0]; - data.faces[f_idx].v[1] = VR->indices[f_idx * 3 + 1]; - data.faces[f_idx].v[2] = VR->indices[f_idx * 3 + 2]; - } - // Fill SWR - data.m_SWI.count = VR->swr_records.size(); - data.m_SWI.sw = xr_alloc(data.m_SWI.count); - for (size_t swr_idx = 0; swr_idx != data.m_SWI.count; swr_idx++) - { - FSlideWindow& dst = data.m_SWI.sw[swr_idx]; - VIPM_SWR& src = VR->swr_records[swr_idx]; - dst.num_tris = src.num_tris; - dst.num_verts = src.num_verts; - dst.offset = src.offset; - } - - break; - } - // cleanup - VIPM_Destroy(); - } - - ////////////////////////////////////////////////////////////////////////// - // FAST-PATH - if (progressive_test() && fast_path_data.vertices.size() && fast_path_data.faces.size()) - { - // prepare progressive geom - VIPM_Init(); - Fvector2 zero; - zero.set(0, 0); - for (size_t v_idx = 0; v_idx < fast_path_data.vertices.size(); v_idx++) - VIPM_AppendVertex(fast_path_data.vertices[v_idx].P, zero); - for (size_t f_idx = 0; f_idx < fast_path_data.faces.size(); f_idx++) - VIPM_AppendFace( - fast_path_data.faces[f_idx].v[0], fast_path_data.faces[f_idx].v[1], fast_path_data.faces[f_idx].v[2]); - - VIPM_Result* VR = 0; - try - { - VR = VIPM_Convert(u32(25), 1.f, 1); - } - catch (...) - { - data.faces = std::move(_saved_faces); - data.vertices = std::move(_saved_vertices); - progressive_clear(); - Logger.clMsg("* X-mesh simplification failed: access violation"); - } - if (0 == VR) - { - data.faces = std::move(_saved_faces); - data.vertices = std::move(_saved_vertices); - progressive_clear(); - Logger.clMsg("* X-mesh simplification failed"); - } - else - { - // Convert - /* - VIPM_Result* VR = VIPM_Convert (u32(25),1.f,1); - VERIFY (VR->swr_records.size()>0) ; - */ - - // test metric - u32 _full = data.vertices.size(); - u32 _remove = VR->swr_records.size(); - u32 _simple = _full - _remove; - float _metric = float(_remove) / float(_full); - Logger.clMsg( - "X mesh simplified from [%4dv] to [%4dv], nf[%4d]", _full, _simple, VR ? VR->indices.size() / 3 : 0); - - // OK - vec_XV vertices_saved; - - // Permute vertices - vertices_saved = fast_path_data.vertices; - for (size_t i = 0; i < fast_path_data.vertices.size(); i++) - fast_path_data.vertices[VR->permute_verts[i]] = vertices_saved[i]; - - // Fill indices - fast_path_data.faces.resize(VR->indices.size() / 3); - for (size_t f_idx = 0; f_idx < fast_path_data.faces.size(); f_idx++) - { - fast_path_data.faces[f_idx].v[0] = VR->indices[f_idx * 3 + 0]; - fast_path_data.faces[f_idx].v[1] = VR->indices[f_idx * 3 + 1]; - fast_path_data.faces[f_idx].v[2] = VR->indices[f_idx * 3 + 2]; - } - - // Fill SWR - fast_path_data.m_SWI.count = VR->swr_records.size(); - fast_path_data.m_SWI.sw = xr_alloc(fast_path_data.m_SWI.count); - for (size_t swr_idx = 0; swr_idx != fast_path_data.m_SWI.count; swr_idx++) - { - FSlideWindow& dst = fast_path_data.m_SWI.sw[swr_idx]; - VIPM_SWR& src = VR->swr_records[swr_idx]; - dst.num_tris = src.num_tris; - dst.num_verts = src.num_verts; - dst.offset = src.offset; - } - } - - // cleanup - VIPM_Destroy(); - } - - progressive_cs.Leave(); -} - -void OGF_Base::Save(IWriter& fs) {} -// Represent a node as HierrarhyVisual -void OGF_Node::Save(IWriter& fs) -{ - OGF_Base::Save(fs); - - // Header - fs.open_chunk(OGF_HEADER); - ogf_header H; - H.format_version = xrOGF_FormatVersion; - H.type = MT_HIERRARHY; - H.shader_id = 0; - H.bb.min = bbox.vMin; - H.bb.max = bbox.vMax; - H.bs.c = C; - H.bs.r = R; - fs.w(&H, sizeof(H)); - fs.close_chunk(); - - // Children - fs.open_chunk(OGF_CHILDREN_L); - fs.w_u32((u32)chields.size()); - fs.w(&*chields.begin(), (u32)chields.size() * sizeof(u32)); - fs.close_chunk(); -} - -extern u16 RegisterShader(LPCSTR T); - -void OGF_LOD::Save(IWriter& fs) -{ - OGF_Base::Save(fs); - - // Header - ogf_header H; - string1024 sid; - strconcat(sizeof(sid), sid, pBuild->shader_render[pBuild->materials()[lod_Material].shader].name, "/", - pBuild->textures()[pBuild->materials()[lod_Material].surfidx].name); - fs.open_chunk(OGF_HEADER); - H.format_version = xrOGF_FormatVersion; - H.type = MT_LOD; - H.shader_id = RegisterShader(sid); - H.bb.min = bbox.vMin; - H.bb.max = bbox.vMax; - H.bs.c = C; - H.bs.r = R; - fs.w(&H, sizeof(H)); - fs.close_chunk(); - - // Chields - fs.open_chunk(OGF_CHILDREN_L); - fs.w_u32((u32)chields.size()); - fs.w(&*chields.begin(), (u32)chields.size() * sizeof(u32)); - fs.close_chunk(); - - // Lod-def - fs.open_chunk(OGF_LODDEF2); - fs.w(lod_faces, sizeof(lod_faces)); - fs.close_chunk(); -} diff --git a/src/utils/xrLC/OGF_Face.h b/src/utils/xrLC/OGF_Face.h deleted file mode 100644 index b5fadb8d892..00000000000 --- a/src/utils/xrLC/OGF_Face.h +++ /dev/null @@ -1,286 +0,0 @@ -#pragma once -#include "utils/ETools/PropSlimTools.h" -#include "vbm.h" -#include "utils/xrLC_Light/xruvpoint.h" -#include "utils/xrLC_Light/base_basis.h" -#include "utils/xrLC_Light/base_color.h" - -struct OGF_Texture -{ - shared_str name; - b_texture* pBuildSurface; -}; -typedef svector vecOGF_T; -typedef vecOGF_T::iterator itOGF_T; - -struct OGF; -struct OGF_Vertex -{ - Fvector P; - Fvector N; // normal - base_basis T; // tangent - base_basis B; // binormal - base_color Color; - svector UV; - - BOOL similar(OGF* p, OGF_Vertex& other); - void dump(u32 id); -}; -typedef xr_vector vecOGF_V; -typedef vecOGF_V::iterator itOGF_V; -typedef vecOGF_V::const_iterator citOGF_V; -struct x_vertex // "fast" geometry, 16b/vertex -{ - Fvector P; - x_vertex(const OGF_Vertex& c) { P = c.P; } - BOOL similar(OGF* p, x_vertex& other); -}; -typedef xr_vector vec_XV; -typedef vec_XV::iterator itXV; - -#pragma pack(push, 1) -struct OGF_Face -{ - u16 v[3]; - - IC void safe_replace(int what, int to) - { - if (v[0] == what) - v[0] = to; - else if (v[0] > what) - v[0] -= 1; - if (v[1] == what) - v[1] = to; - else if (v[1] > what) - v[1] -= 1; - if (v[2] == what) - v[2] = to; - else if (v[2] > what) - v[2] -= 1; - } - IC bool Degenerate() { return ((v[0] == v[1]) || (v[0] == v[2]) || (v[1] == v[2])); } - IC bool Equal(OGF_Face& F) - { - // Test for 6 variations - if ((v[0] == F.v[0]) && (v[1] == F.v[1]) && (v[2] == F.v[2])) - return true; - if ((v[0] == F.v[0]) && (v[2] == F.v[1]) && (v[1] == F.v[2])) - return true; - if ((v[2] == F.v[0]) && (v[0] == F.v[1]) && (v[1] == F.v[2])) - return true; - if ((v[2] == F.v[0]) && (v[1] == F.v[1]) && (v[0] == F.v[2])) - return true; - if ((v[1] == F.v[0]) && (v[0] == F.v[1]) && (v[2] == F.v[2])) - return true; - if ((v[1] == F.v[0]) && (v[2] == F.v[1]) && (v[0] == F.v[2])) - return true; - return false; - } -}; -typedef xr_vector vecOGF_F; -typedef vecOGF_F::iterator itOGF_F; -typedef vecOGF_F::const_iterator citOGF_F; -typedef OGF_Face x_face; -#pragma pack(pop) - -struct OGF; - -struct OGF_Base -{ - int iLevel; - u16 Sector; - BOOL bConnected; - - Fbox bbox; - Fvector C; - float R; - - OGF_Base(int level) - { - bbox.invalidate(); - iLevel = level; - bConnected = FALSE; - Sector = 0xffff; - } - - IC BOOL IsNode() { return iLevel; } - virtual void PreSave(u32 tree_id){}; - virtual void Save(IWriter& fs); - virtual void GetGeometry(xr_vector& RES) = 0; - void CalcBounds(); -}; -extern xr_vector g_tree; - -struct OGF : public OGF_Base -{ - u32 material; - vecOGF_T textures; - /* - vecOGF_V vertices ; - vecOGF_F faces ; - - // fast-vertices - vec_XV x_vertices ; - vecOGF_F x_faces ; - - // Progressive - FSlideWindowItem m_SWI ; // The records of the collapses. - FSlideWindowItem x_SWI ; // The records of the collapses / fast-path - */ - // for build only - u32 dwRelevantUV; - u32 dwRelevantUVMASK; - /* - u32 vb_id , xvb_id; - u32 vb_start, xvb_start; - u32 ib_id , xib_id; - u32 ib_start, xib_start; - u32 sw_id , xsw_id; - */ - - template - struct ogf_container - { - t_vertices vertices; - vecOGF_F faces; - FSlideWindowItem m_SWI; - u32 vb_id; - u32 vb_start; - u32 ib_id; - u32 ib_start; - u32 sw_id; - ogf_container() : vb_id(-1), vb_start(-1), ib_id(-1), ib_start(-1), sw_id(-1) {} - }; - - ogf_container data; - ogf_container fast_path_data; - - OGF() : OGF_Base(0) - { - data.m_SWI.count = 0; - data.m_SWI.sw = 0; - data.m_SWI.reserved[0] = 0; - data.m_SWI.reserved[1] = 0; - data.m_SWI.reserved[2] = 0; - data.m_SWI.reserved[3] = 0; - dwRelevantUV = 0; - dwRelevantUVMASK = 0; - - // vb_id=xvb_id=vb_start=xvb_start=ib_id=xib_id=ib_start=xib_start=sw_id=xsw_id=u32(-1); - }; - ~OGF() { xr_free(data.m_SWI.sw); } - BOOL dbg_SphereContainsVertex(Fvector& c, float R); - - u16 x_BuildVertex(x_vertex& V); - void x_BuildFace(OGF_Vertex& V1, OGF_Vertex& V2, OGF_Vertex& V3, bool _tc_); - u16 _BuildVertex(OGF_Vertex& V1); - void _BuildFace(OGF_Vertex& V1, OGF_Vertex& V2, OGF_Vertex& V3, bool _tc_ = true); - - void adjacent_select(xr_vector& dest, xr_vector& vmark, xr_vector& fmark); - - void Optimize(); - void CalculateTB(); - void MakeProgressive(float metric_limit); - void Stripify(); - void DumpFaces(); - - BOOL progressive_test() { return data.m_SWI.count; } - void progressive_clear() - { - data.m_SWI.count = 0; - xr_free(data.m_SWI.sw); - } - - virtual void PreSave(u32 tree_id); - virtual void Save(IWriter& fs); - - // void Save_Cached (IWriter &fs, ogf_header& H, BOOL bColors); - - void Save_Normal_PM(IWriter& fs, ogf_header& H, BOOL bColors); - void Load_Normal_PM(IReader& fs, ogf_header& H, BOOL bColors); - - // void Save_Progressive(IWriter &fs, ogf_header& H, BOOL bColors); - - virtual void GetGeometry(xr_vector& R) - { - for (xr_vector::iterator I = data.vertices.begin(); I != data.vertices.end(); ++I) - R.push_back(I->P); - } -}; - -struct OGF_Reference : public OGF_Base -{ - OGF* model; - - u32 material; - vecOGF_T textures; - - u32 vb_id; - u32 vb_start; - u32 ib_id; - u32 ib_start; - u32 sw_id; - - Fmatrix xform; - base_color_c c_scale; - base_color_c c_bias; - - OGF_Reference() : OGF_Base(0) { model = 0; } - virtual void Save(IWriter& fs); - virtual void GetGeometry(xr_vector& R) - { - Fvector P; - for (xr_vector::iterator I = model->data.vertices.begin(); I != model->data.vertices.end(); ++I) - { - xform.transform_tiny(P, I->P); - R.push_back(P); - } - } -}; - -struct OGF_Node : public OGF_Base -{ - xr_vector chields; - - OGF_Node(int level, u16 _Sector) : OGF_Base(level) { Sector = _Sector; } - void AddChield(u32 ID) - { - chields.push_back(ID); - OGF_Base* P = g_tree[ID]; - R_ASSERT(P->Sector == Sector); - bbox.merge(P->bbox); - P->bConnected = TRUE; - } - virtual void Save(IWriter& fs); - virtual void GetGeometry(xr_vector& R) - { - for (xr_vector::iterator I = chields.begin(); I != chields.end(); ++I) - g_tree[*I]->GetGeometry(R); - } -}; - -struct OGF_LOD : public OGF_Node -{ - OGF_LOD(int level, u16 _Sector) : OGF_Node(level, _Sector){}; - - struct _vertex - { - Fvector v; - Fvector2 t; - u32 c_rgb_hemi; // rgb,hemi - u8 c_sun; - }; - struct _face - { - _vertex v[4]; - }; - - _face lod_faces[8]; - u32 lod_Material; - - virtual void Save(IWriter& fs); -}; - -void set_status(char* N, int id, int f, int v); - -extern OGF_Base* g_TREE_ROOT; diff --git a/src/utils/xrLC/OGF_Face_Save.cpp b/src/utils/xrLC/OGF_Face_Save.cpp deleted file mode 100644 index 6728eb9d5e6..00000000000 --- a/src/utils/xrLC/OGF_Face_Save.cpp +++ /dev/null @@ -1,269 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "ogf_face.h" - -#include "xrCore/fs.h" -#include "xrCore/FMesh.hpp" -#include "Common/OGF_GContainer_Vertices.hpp" - -using namespace std; - -extern u16 RegisterShader(LPCSTR T); -extern void geom_batch_average(u32 verts, u32 faces); - -void OGF::Save(IWriter& fs) -{ - OGF_Base::Save(fs); - - // clMsg ("* %d faces",faces.size()); - geom_batch_average((u32)data.vertices.size(), (u32)data.faces.size()); - - // Texture & shader - std::string Tname; - for (u32 i = 0; i < textures.size(); i++) - { - if (!Tname.empty()) - Tname += ','; - string256 t; - xr_strcpy(t, *textures[i].name); - if (strchr(t, '.')) - *strchr(t, '.') = 0; - Tname += t; - } - string1024 sid; - strconcat(sizeof(sid), sid, pBuild->shader_render[pBuild->materials()[material].shader].name, "/", Tname.c_str()); - - // Create header - ogf_header H; - H.format_version = xrOGF_FormatVersion; - H.type = data.m_SWI.count ? MT_PROGRESSIVE : MT_NORMAL; - H.shader_id = RegisterShader(sid); - H.bb.min = bbox.vMin; - H.bb.max = bbox.vMax; - H.bs.c = C; - H.bs.r = R; - - // Vertices - const Shader_xrLC* SH = pBuild->shaders().Get(pBuild->materials()[material].reserved); - bool bVertexColors = (SH->flags.bLIGHT_Vertex); - - switch (H.type) - { - case MT_NORMAL: - case MT_PROGRESSIVE: Save_Normal_PM(fs, H, bVertexColors); break; - } - - // Header - fs.open_chunk(OGF_HEADER); - fs.w(&H, sizeof(H)); - fs.close_chunk(); -} - -void OGF_Reference::Save(IWriter& fs) -{ - OGF_Base::Save(fs); - - // geom_batch_average (vertices.size(),faces.size()); // don't use reference(s) as batch estimate - - // Texture & shader - std::string Tname; - for (u32 i = 0; i < textures.size(); i++) - { - if (!Tname.empty()) - Tname += ','; - string256 t; - xr_strcpy(t, *textures[i].name); - if (strchr(t, '.')) - *strchr(t, '.') = 0; - Tname += t; - } - string1024 sid; - strconcat(sizeof(sid), sid, pBuild->shader_render[pBuild->materials()[material].shader].name, "/", Tname.c_str()); - - // Create header - ogf_header H; - H.format_version = xrOGF_FormatVersion; - H.type = model->data.m_SWI.count ? MT_TREE_PM : MT_TREE_ST; - H.shader_id = RegisterShader(sid); - H.bb.min = bbox.vMin; - H.bb.max = bbox.vMax; - H.bs.c = C; - H.bs.r = R; - - // Vertices - fs.open_chunk(OGF_GCONTAINER); - fs.w_u32(vb_id); - fs.w_u32(vb_start); - fs.w_u32((u32)model->data.vertices.size()); - - fs.w_u32(ib_id); - fs.w_u32(ib_start); - fs.w_u32((u32)model->data.faces.size() * 3); - fs.close_chunk(); - - // Special - fs.open_chunk(OGF_TREEDEF2); - fs.w(&xform, sizeof(xform)); - fs.w(&c_scale, 5 * sizeof(float)); - fs.w(&c_bias, 5 * sizeof(float)); - fs.close_chunk(); - - // Header - fs.open_chunk(OGF_HEADER); - fs.w(&H, sizeof(H)); - fs.close_chunk(); - - // progressive - if (H.type == MT_TREE_PM) - { - // SW - fs.open_chunk(OGF_SWICONTAINER); - fs.w_u32(sw_id); - fs.close_chunk(); - } -} - -void OGF::PreSave(u32 tree_id) -{ - // if (20==tree_id || 18==tree_id) __asm int 3; //. - const Shader_xrLC* SH = pBuild->shaders().Get(pBuild->materials()[material].reserved); - bool bVertexColored = (SH->flags.bLIGHT_Vertex); - - // X-vertices/faces - if (fast_path_data.vertices.size() && fast_path_data.faces.size()) - { - Logger.clMsg("%4d: v(%3d)/f(%3d)", tree_id, fast_path_data.vertices.size(), fast_path_data.faces.size()); - VDeclarator x_D; - x_D.set(x_decl_vert); - x_VB.Begin(x_D); - for (itXV V = fast_path_data.vertices.begin(); V != fast_path_data.vertices.end(); ++V) - { - x_vert v(V->P); - x_VB.Add(&v, sizeof(v)); - } - x_VB.End(&fast_path_data.vb_id, &fast_path_data.vb_start); - x_IB.Register((u16*)(&*fast_path_data.faces.begin()), (u16*)(&*fast_path_data.faces.end()), - &fast_path_data.ib_id, &fast_path_data.ib_start); - } - - // Vertices - VDeclarator D; - if (bVertexColored) - { - // vertex-colored - D.set(r1_decl_vert); - g_VB.Begin(D); - for (itOGF_V V = data.vertices.begin(); V != data.vertices.end(); ++V) - { - r1v_vert v(V->P, V->N, V->T, V->B, V->Color, V->UV[0]); - g_VB.Add(&v, sizeof(v)); - } - g_VB.End(&data.vb_id, &data.vb_start); - } - else - { - // lmap-colored - D.set(r1_decl_lmap); - g_VB.Begin(D); - for (itOGF_V V = data.vertices.begin(); V != data.vertices.end(); ++V) - { - r1v_lmap v(V->P, V->N, V->T, V->B, V->Color, V->UV[0], V->UV[1]); - g_VB.Add(&v, sizeof(v)); - } - g_VB.End(&data.vb_id, &data.vb_start); - } - - // Faces - g_IB.Register((u16*)(&*data.faces.begin()), (u16*)(&*data.faces.end()), &data.ib_id, &data.ib_start); -} - -template -void write_ogf_container(IWriter& fs, const ogf_data_type& ogf_cnt) -{ - fs.open_chunk(OGF_GCONTAINER); - fs.w_u32(ogf_cnt.vb_id); - fs.w_u32(ogf_cnt.vb_start); - fs.w_u32((u32)ogf_cnt.vertices.size()); - - fs.w_u32(ogf_cnt.ib_id); - fs.w_u32(ogf_cnt.ib_start); - fs.w_u32((u32)ogf_cnt.faces.size() * 3); - fs.close_chunk(); -} - -template -void read_ogf_container(IReader& fs_, const ogf_data_type& ogf_cnt) -{ - IReader& fs = *fs_.open_chunk(OGF_GCONTAINER); - - ogf_cnt.vb_id = fs.r_u32(); - ogf_cnt.vb_start = fs.r_u32(); - - u32 vertises_size = fs.r_u32(); - // ogf_cnt.vertices.resize( vertises_size ); - - ogf_cnt.ib_id = fs.r_u32(); - ogf_cnt.ib_start = fs.r_u32(); - u32 faces_size = fs.r_u32(); //(u32)ogf_cnt.faces.size()*3 - // ogf_cnt.faces.resize( vertises_size ); - // fs.close_chunk ( ); -} - -void write_ogf_swidata(IWriter& fs, const FSlideWindowItem& swi) -{ - fs.open_chunk(OGF_SWIDATA); - fs.w_u32(swi.reserved[0]); - fs.w_u32(swi.reserved[1]); - fs.w_u32(swi.reserved[2]); - fs.w_u32(swi.reserved[3]); - fs.w_u32(swi.count); - fs.w(swi.sw, swi.count * sizeof(FSlideWindow)); - fs.close_chunk(); -} - -void read_ogf_swidata(IReader& fs_, FSlideWindowItem& swi) -{ - IReader& fs = *fs_.open_chunk(OGF_SWIDATA); - - swi.reserved[0] = fs.r_u32(); - swi.reserved[1] = fs.r_u32(); - swi.reserved[2] = fs.r_u32(); - swi.reserved[3] = fs.r_u32(); - swi.count = fs.r_u32(); - VERIFY(!swi.sw); - // swi.sw = - fs.r(swi.sw, swi.count * sizeof(FSlideWindow)); - // fs.close_chunk (); -} - -void write_ogf_fastpath(IWriter& fs, const OGF& ogf, BOOL progresive) -{ - fs.open_chunk(OGF_FASTPATH); - { - // Vertices - write_ogf_container(fs, ogf.fast_path_data); - - // progressive-data, if need it - if (progresive) // H.type == MT_PROGRESSIVE - write_ogf_swidata(fs, ogf.fast_path_data.m_SWI); - } - fs.close_chunk(); -} - -void OGF::Save_Normal_PM(IWriter& fs, ogf_header& H, BOOL bVertexColored) -{ - // clMsg ("- saving: normal or clod"); - - // Vertices - write_ogf_container(fs, data); - - // progressive-data, if need it - if (H.type == MT_PROGRESSIVE) - write_ogf_swidata(fs, data.m_SWI); // SW - - // if has x-vertices/x-faces - if (!fast_path_data.vertices.empty() && !fast_path_data.faces.empty()) - write_ogf_fastpath(fs, *this, H.type == MT_PROGRESSIVE); -} - -void OGF::Load_Normal_PM(IReader& fs, ogf_header& H, BOOL bVertexColored) {} diff --git a/src/utils/xrLC/OGF_Face_Sphere.cpp b/src/utils/xrLC/OGF_Face_Sphere.cpp deleted file mode 100644 index 45c63811eec..00000000000 --- a/src/utils/xrLC/OGF_Face_Sphere.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "ogf_face.h" -#include "xrCore/_sphere.h" -#pragma warning(disable : 4995) -#include - -BOOL f_valid(float f) { return _finite(f) && !_isnan(f); } -BOOL SphereValid(xr_vector& geom, Fsphere& test) -{ - if (!f_valid(test.P.x) || !f_valid(test.R)) - { - Logger.clMsg("*** Attention ***: invalid sphere: %f,%f,%f - %f", test.P.x, test.P.y, test.P.z, test.R); - } - - Fsphere S = test; - S.R += EPS_L; - for (xr_vector::iterator I = geom.begin(); I != geom.end(); ++I) - if (!S.contains(*I)) - return FALSE; - return TRUE; -} - -void OGF_Base::CalcBounds() -{ - // get geometry - static xr_vector V; - xr_vector::iterator I; - V.clear(); - V.reserve(4096); - GetGeometry(V); - FPU::m64(); - R_ASSERT(V.size() >= 3); - - // 1: calc first variation - Fsphere S1; - Fsphere_compute(S1, &*V.begin(), (u32)V.size()); - BOOL B1 = SphereValid(V, S1); - - // 2: calc ordinary algorithm (2nd) - Fsphere S2; - bbox.invalidate(); - for (I = V.begin(); I != V.end(); ++I) - bbox.modify(*I); - bbox.grow(EPS_L); - bbox.getsphere(S2.P, S2.R); - S2.R = -1; - for (I = V.begin(); I != V.end(); ++I) - { - float d = S2.P.distance_to_sqr(*I); - if (d > S2.R) - S2.R = d; - } - S2.R = _sqrt(_abs(S2.R)); - BOOL B2 = SphereValid(V, S2); - - // 3: calc magic-fm - Mgc::Sphere _S3 = Mgc::MinSphere((u32)V.size(), (const Mgc::Vector3*)&*V.begin()); - Fsphere S3; - S3.P.set(_S3.Center().x, _S3.Center().y, _S3.Center().z); - S3.R = _S3.Radius(); - BOOL B3 = SphereValid(V, S3); - - // select best one - if (B1 && (S1.R < S2.R)) - { - // miniball or FM - if (B3 && (S3.R < S1.R)) - { - // FM wins - C.set(S3.P); - R = S3.R; - } - else - { - // MiniBall wins - C.set(S1.P); - R = S1.R; - } - } - else - { - // base or FM - if (B3 && (S3.R < S2.R)) - { - // FM wins - C.set(S3.P); - R = S3.R; - } - else - { - // Base wins :) - C.set(S2.P); - R = S2.R; - } - } -} diff --git a/src/utils/xrLC/OGF_Face_Stripify.cpp b/src/utils/xrLC/OGF_Face_Stripify.cpp deleted file mode 100644 index d5991234f94..00000000000 --- a/src/utils/xrLC/OGF_Face_Stripify.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "ogf_face.h" -#include "NV_Library\NvTriStrip.h" -#include "NV_Library\VertexCache.h" -#include - -int xrSimulate(xr_vector& indices, int iCacheSize) -{ - VertexCache C(iCacheSize); - - int count = 0; - for (size_t i = 0; i < indices.size(); i++) - { - int id = indices[i]; - if (C.InCache(id)) - continue; - count++; - C.AddEntry(id); - } - return count; -} - -void xrStripify(xr_vector& indices, xr_vector& perturb, int iCacheSize, int iMinStripLength) -{ - SetCacheSize(iCacheSize); - SetMinStripSize(iMinStripLength); - SetListsOnly(true); - - // Generate strips - xr_vector PGROUP; - // XXX: replace u32 with size_t - GenerateStrips(&*indices.begin(), (u32)indices.size(), PGROUP); - R_ASSERT(PGROUP.size() == 1); - R_ASSERT(PGROUP[0].type == PT_LIST); - if (indices.size() != PGROUP[0].numIndices) - throw "Stripify failed."; - - // Remap indices - xr_vector xPGROUP; - RemapIndices(PGROUP, u16(perturb.size()), xPGROUP); - R_ASSERT(xPGROUP.size() == 1); - R_ASSERT(xPGROUP[0].type == PT_LIST); - - // Build perturberation table - for (size_t index = 0; index < PGROUP[0].numIndices; index++) - { - u16 oldIndex = PGROUP[0].indices[index]; - int newIndex = xPGROUP[0].indices[index]; - R_ASSERT(oldIndex < (int)perturb.size()); - R_ASSERT(newIndex < (int)perturb.size()); - perturb[newIndex] = oldIndex; - } - - // Copy indices - CopyMemory(&indices.front(), xPGROUP[0].indices, indices.size() * sizeof(u16)); - - // Release memory - xPGROUP.clear(); - PGROUP.clear(); -} - -void OGF::Stripify() -{ - if (progressive_test()) - return; // Mesh already progressive - don't stripify it - - // fast verts - if (fast_path_data.vertices.size() && fast_path_data.faces.size()) - /* -try { - xr_vector indices,permute; - - // Stripify - u16* F = (u16*)&x_faces.front(); - indices.assign (F,F+(x_faces.size()*3) ); - permute.resize (x_vertices.size() ); - xrStripify (indices,permute,c_vCacheSize,0); - - // Copy faces - CopyMemory (&x_faces.front(), &indices.front(), indices.size()*sizeof(u16)); - - // Permute vertices - vec_XV temp_list = x_vertices; - for(u32 i=0; i(fast_path_data.faces.size()); - HRESULT rhr = D3DXOptimizeFaces(&fast_path_data.faces.front(), fast_path_data.faces.size(), - fast_path_data.vertices.size(), FALSE, remap); - R_CHK(rhr); - vecOGF_F _source = fast_path_data.faces; - for (u32 it = 0; it < _source.size(); it++) - fast_path_data.faces[it] = _source[remap[it]]; - xr_free(remap); - } - - // alternative stripification - vertices - { - DWORD* remap = xr_alloc(fast_path_data.vertices.size()); - HRESULT rhr = D3DXOptimizeVertices(&fast_path_data.faces.front(), fast_path_data.faces.size(), - fast_path_data.vertices.size(), FALSE, remap); - R_CHK(rhr); - vec_XV _source = fast_path_data.vertices; - for (size_t it = 0; it < _source.size(); it++) - fast_path_data.vertices[remap[it]] = _source[it]; - for (size_t it = 0; it < fast_path_data.faces.size(); it++) - for (size_t j = 0; j < 3; j++) - fast_path_data.faces[it].v[j] = (u16)remap[fast_path_data.faces[it].v[j]]; - xr_free(remap); - } - } - - // normal verts - try - { - xr_vector indices, permute; - - // Stripify - u16* F = (u16*)&data.faces.front(); - indices.assign(F, F + (data.faces.size() * 3)); - permute.resize(data.vertices.size()); - xrStripify(indices, permute, c_vCacheSize, 0); - - // Copy faces - CopyMemory(&data.faces.front(), &indices.front(), indices.size() * sizeof(u16)); - - // Permute vertices - vecOGF_V temp_list = data.vertices; - for (size_t i = 0; i < temp_list.size(); i++) - data.vertices[i] = temp_list[permute[i]]; - } - catch (...) - { - Logger.clMsg("ERROR: [slow-vert] Stripifying failed. Dump below."); - DumpFaces(); - } -} - -void OGF::DumpFaces() -{ - Logger.clMsg("normal:"); - for (size_t i = 0; i < data.faces.size(); i++) - Logger.clMsg( - "face #%4d: %4d %4d %4d", i, int(data.faces[i].v[0]), int(data.faces[i].v[1]), int(data.faces[i].v[2])); - Logger.clMsg("fast:"); - for (size_t i = 0; i < fast_path_data.faces.size(); i++) - Logger.clMsg("face #%4d: %4d %4d %4d", i, int(fast_path_data.faces[i].v[0]), int(fast_path_data.faces[i].v[1]), - int(fast_path_data.faces[i].v[2])); -} diff --git a/src/utils/xrLC/OGF_RemoveIsolatedVerts.cpp b/src/utils/xrLC/OGF_RemoveIsolatedVerts.cpp deleted file mode 100644 index 4890e747bab..00000000000 --- a/src/utils/xrLC/OGF_RemoveIsolatedVerts.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "stdafx.h" -#include "MeshMenderLayerOGF.h" - -void remove_isolated_verts(vecOGF_V& vertices, vecOGF_F& faces) { t_remove_isolated_verts(vertices, faces); } diff --git a/src/utils/xrLC/Sector.cpp b/src/utils/xrLC/Sector.cpp deleted file mode 100644 index b363d21eb48..00000000000 --- a/src/utils/xrLC/Sector.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// Sector.cpp: implementation of the CSector class. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "build.h" -#include "Sector.h" -#include "OGF_Face.h" -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSector::CSector(u32 ID) -{ - SelfID = ID; - TreeRoot = 0; -} - -CSector::~CSector() {} -IC BOOL ValidateMerge(Fbox& bb_base, Fbox& bb, float& volume, float SLimit) -{ - // Size - Fbox merge; - merge.merge(bb_base, bb); - Fvector sz; - merge.getsize(sz); - sz.add(EPS_L); - if (sz.x > SLimit) - return FALSE; // Don't exceed limits (4/3 GEOM) - if (sz.y > SLimit) - return FALSE; - if (sz.z > SLimit) - return FALSE; - - // Volume - volume = merge.getvolume(); - - // OK - return TRUE; -} - -void CSector::BuildHierrarhy() -{ - Fvector scene_size; - float delimiter; - BOOL bAnyNode = FALSE; - - // calc scene BB - Fbox& scene_bb = pBuild->scene_bb; - scene_bb.invalidate(); - for (int I = 0; I < s32(g_tree.size()); I++) - scene_bb.merge(g_tree[I]->bbox); - scene_bb.grow(EPS_L); - - // - scene_bb.getsize(scene_size); - delimiter = _max(scene_size.x, _max(scene_size.y, scene_size.z)); - delimiter *= 2; - - int iLevel = 2; - float SizeLimit = c_SS_maxsize / 4.f; - if (SizeLimit < 4.f) - SizeLimit = 4.f; - if (delimiter <= SizeLimit) - delimiter *= 2; // just very small level - - for (; SizeLimit <= delimiter; SizeLimit *= 2) - { - int iSize = g_tree.size(); - - for (int I = 0; I < iSize; I++) - { - if (g_tree[I]->bConnected) - continue; - if (g_tree[I]->Sector != SelfID) - continue; - - OGF_Node* pNode = xr_new(iLevel, u16(SelfID)); - pNode->AddChield(I); - - // Find best object to connect with - for (;;) - { - // Find best object to connect with - int best_id = -1; - float best_volume = flt_max; - - for (int J = 0; J < iSize; J++) - { - OGF_Base* candidate = g_tree[J]; - if (candidate->bConnected) - continue; - if (candidate->Sector != SelfID) - continue; - - float V; - if (ValidateMerge(pNode->bbox, candidate->bbox, V, SizeLimit)) - { - if (V < best_volume) - { - best_volume = V; - best_id = J; - } - } - } - - // Analyze - if (best_id < 0) - break; - pNode->AddChield(best_id); - } - - if (pNode->chields.size() > 1) - { - pNode->CalcBounds(); - g_tree.push_back(pNode); - bAnyNode = TRUE; - } - else - { - g_tree[I]->bConnected = false; - xr_delete(pNode); - } - } - - if (iSize != (int)g_tree.size()) - iLevel++; - } - TreeRoot = 0; - if (bAnyNode) - TreeRoot = g_tree.back(); - else - { - for (u32 I = 0; I < g_tree.size(); I++) - { - if (g_tree[I]->bConnected) - continue; - if (g_tree[I]->Sector != SelfID) - continue; - R_ASSERT(0 == TreeRoot); - TreeRoot = g_tree[I]; - } - } - if (0 == TreeRoot) - { - Logger.clMsg("Can't build hierrarhy for sector #%d", SelfID); - } -} - -void CSector::Validate() -{ - std::sort(Portals.begin(), Portals.end()); - R_ASSERT(std::unique(Portals.begin(), Portals.end()) == Portals.end()); - R_ASSERT(TreeRoot); - R_ASSERT(TreeRoot->Sector == SelfID); -} - -void CSector::Save(IWriter& fs) -{ - // Root - xr_vector::iterator F = std::find(g_tree.begin(), g_tree.end(), TreeRoot); - R_ASSERT(F != g_tree.end()); - u32 ID = u32(F - g_tree.begin()); - fs.w_chunk(fsP_Root, &ID, sizeof(u32)); - - // Portals - fs.w_chunk(fsP_Portals, &*Portals.begin(), Portals.size() * sizeof(u16)); -} diff --git a/src/utils/xrLC/Sector.h b/src/utils/xrLC/Sector.h deleted file mode 100644 index c0071299ef0..00000000000 --- a/src/utils/xrLC/Sector.h +++ /dev/null @@ -1,32 +0,0 @@ -// Sector.h: interface for the CSector class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SECTOR_H__751706E5_383E_40CB_9F3D_6A4D1BB8F3CD__INCLUDED_) -#define AFX_SECTOR_H__751706E5_383E_40CB_9F3D_6A4D1BB8F3CD__INCLUDED_ -#pragma once -struct OGF_Base; - -class CSector -{ - u32 SelfID; - OGF_Base* TreeRoot; - xr_vector Portals; - xr_vector Glows; - xr_vector Lights; - -public: - void add_portal(u16 P) { Portals.push_back(P); } - void add_glow(u16 G) { Glows.push_back(G); } - void add_light(u16 L) { Lights.push_back(L); } - void BuildHierrarhy(); - void Validate(); - void Save(IWriter& fs); - - CSector(u32 ID); - ~CSector(); -}; - -extern xr_vector g_sectors; - -#endif // !defined(AFX_SECTOR_H__751706E5_383E_40CB_9F3D_6A4D1BB8F3CD__INCLUDED_) diff --git a/src/utils/xrLC/StdAfx.cpp b/src/utils/xrLC/StdAfx.cpp deleted file mode 100644 index c9cd8f0a45f..00000000000 --- a/src/utils/xrLC/StdAfx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" -#include "xrCore/cdecl_cast.hpp" -#include "utils/xrLCUtil/LevelCompilerLoggerWindow.hpp" - -ILevelCompilerLogger& Logger = LevelCompilerLoggerWindow::instance(); - -CThread::LogFunc ProxyMsg = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.clMsgV(format, args); - va_end(args); -}); - -CThreadManager::ReportStatusFunc ProxyStatus = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.StatusV(format, args); - va_end(args); -}); - -CThreadManager::ReportProgressFunc ProxyProgress = cdecl_cast([](float progress) { Logger.Progress(progress); }); diff --git a/src/utils/xrLC/StdAfx.h b/src/utils/xrLC/StdAfx.h deleted file mode 100644 index 498c5922d60..00000000000 --- a/src/utils/xrLC/StdAfx.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#define ENGINE_API - -#include "Common/Common.hpp" -#include "utils/xrLC_Light/xrLC_Light.h" - -#include "utils/xrLCUtil/ILevelCompilerLogger.hpp" -#include "utils/xrLCUtil/xrThread.hpp" - -#define NUM_THREADS 8 - -extern ILevelCompilerLogger& Logger; -extern CThread::LogFunc ProxyMsg; -extern CThreadManager::ReportStatusFunc ProxyStatus; -extern CThreadManager::ReportProgressFunc ProxyProgress; - -#include "b_globals.h" diff --git a/src/utils/xrLC/_rect.h b/src/utils/xrLC/_rect.h deleted file mode 100644 index fc57612d781..00000000000 --- a/src/utils/xrLC/_rect.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef __FRECT -#define __FRECT - -template -struct _rect -{ -public: - typedef T TYPE; - typedef _rect Self; - typedef Self& SelfRef; - typedef const Self& SelfCRef; - typedef _vector2 Tvector; - -public: - union - { - struct - { - T x1, y1, x2, y2; - }; - struct - { - T left, top, right, bottom; - }; - - struct - { - Tvector lt; - Tvector rb; - }; - T m[4]; - }; - - IC SelfRef set(const T _x1, const T _y1, const T _x2, const T _y2) - { - x1 = _x1; - y1 = _y1; - x2 = _x2; - y2 = _y2; - return *this; - }; - IC SelfRef set(const Tvector& mn, const Tvector& mx) - { - x1 = mn.x; - y1 = mn.y; - x2 = mx.x; - y2 = mx.y; - return *this; - }; - IC SelfRef set(const Self& r) - { - x1 = r.x1; - y1 = r.y1; - x2 = r.x2; - y2 = r.y2; - return *this; - }; - IC SelfRef set_zero() - { - x1 = T(0); - y1 = T(0); - x2 = T(0); - y2 = T(0); - return *this; - }; - - IC SelfRef add(T x, T y) - { - x1 += x; - y1 += y; - x2 += x; - y2 += y; - return *this; - }; - IC SelfRef sub(T x, T y) - { - x1 -= x; - y1 -= y; - x2 -= x; - y2 -= y; - return *this; - }; - IC SelfRef mul(T x, T y) - { - x1 *= x; - y1 *= y; - x2 *= x; - y2 *= y; - return *this; - }; - IC SelfRef div(T x, T y) - { - x1 /= x; - y1 /= y; - x2 /= x; - y2 /= y; - return *this; - }; - - IC SelfRef add(const Self& r, T x, T y) - { - x1 = r.x1 + x; - y1 = r.y1 + y; - x2 = r.x2 + x; - y2 = r.y2 + y; - return *this; - }; - IC SelfRef sub(const Self& r, T x, T y) - { - x1 = r.x1 - x; - y1 = r.y1 - y; - x2 = r.x2 - x; - y2 = r.y2 - y; - return *this; - }; - IC SelfRef mul(const Self& r, T x, T y) - { - x1 = r.x1 * x; - y1 = r.y1 * y; - x2 = r.x2 * x; - y2 = r.y2 * y; - return *this; - }; - IC SelfRef div(const Self& r, T x, T y) - { - x1 = r.x1 / x; - y1 = r.y1 / y; - x2 = r.x2 / x; - y2 = r.y2 / y; - return *this; - }; - - IC BOOL in(T x, T y) const { return (x >= x1) && (x <= x2) && (y >= y1) && (y <= y2); }; - IC BOOL in(Tvector& p) const { return (p.x >= x1) && (p.x <= x2) && (p.y >= y1) && (p.y <= y2); }; - IC BOOL cmp(_rect& r) { return x1 == r.x1 && y1 == r.y1 && x2 == r.x2 && y2 == r.y2; }; - IC BOOL cmp(_rect& r) - { - return fsimilar(x1, r.x1) && fsimilar(y1, r.y1) && fsimilar(x2, r.x2) && fsimilar(y2, r.y2); - }; - - IC void getcenter(Tvector& center) - { - center.add(rb, lt); - center.div(2); - } - IC void getsize(Tvector& sz) { sz.sub(rb, lt); } - IC T width() const { return rb.x - lt.x; } - IC T height() const { return rb.y - lt.y; } - IC SelfRef shrink(T x, T y) - { - lt.x += x; - lt.y += y; - rb.x -= x; - rb.y -= y; - return *this; - }; - IC SelfRef grow(T x, T y) - { - lt.x -= x; - lt.y -= y; - rb.x += x; - rb.y += y; - return *this; - }; - - IC BOOL intersected(SelfCRef b1, SelfCRef b2) const - { - return !(b1.x1 > b2.x2 || b1.x2 < b2.x1 || b1.y1 > b2.y2 || b1.y2 < b2.y1); - } - IC BOOL intersected(SelfCRef b) const { return intersected(*this, b); } - IC BOOL intersection(SelfCRef b1, SelfCRef b2) - { - if (!intersected(b1, b2)) - return (FALSE); - - x1 = _max(b1.x1, b2.x1); - y1 = _max(b1.y1, b2.y1); - x2 = _min(b1.x2, b2.x2); - y2 = _min(b1.y2, b2.y2); - return (TRUE); - } -}; - -typedef _rect Frect; -typedef _rect Drect; -typedef _rect Irect; - -template -BOOL _valid(const _rect& m) -{ - return lt._valid() && rb._valid(); -} - -#endif diff --git a/src/utils/xrLC/b_globals.h b/src/utils/xrLC/b_globals.h deleted file mode 100644 index ca3ad018c5c..00000000000 --- a/src/utils/xrLC/b_globals.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -const u32 c_VB_maxVertices = 65535; // count -const u32 c_vCacheSize = 24; // entries -const u32 c_SS_LowVertLimit = 64; // polys -const u32 c_SS_HighVertLimit = 2 * 1024; // polys -const u32 c_SS_maxsize = 32; // meters -const u32 c_PM_FaceLimit = 128; // face-limit -const float c_PM_MetricLimit_static = 0.10f; // vertex-count-simplification-limit -const float c_PM_MetricLimit_mu = 0.05f; // vertex-count-simplification-limit - -// XXX: The following two 'exact_normalize' are also declared in xrCore/_vector3d.h -bool exact_normalize(Fvector3& a); -bool exact_normalize(float* a); - -struct SBuildOptions -{ - BOOL b_skipinvalid; - BOOL b_radiosity; - BOOL b_noise; - BOOL b_net_light; - SBuildOptions() : b_skipinvalid(FALSE), b_radiosity(FALSE), b_noise(FALSE), b_net_light(FALSE) {} -}; -extern SBuildOptions g_build_options; diff --git a/src/utils/xrLC/fmesh.cpp b/src/utils/xrLC/fmesh.cpp deleted file mode 100644 index 9390fcebeed..00000000000 --- a/src/utils/xrLC/fmesh.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include "stdafx.h" - -static u32 dwPositionPart[8] = { - 0, // no position - 3, // x,y,z - 4, // sx,sy,sz,rhw - 4, // x,y,z,b1 - 5, // x,y,z,b1,b2 - 6, // x,y,z,b1,b2,b3 - 7, // x,y,z,b1,b2,b3,b4 - 8 // x,y,z,b1,b2,b3,b4,b5 -}; - -#define FAKES 0xffffffff -#define FAKEZ 0xfffffffe - -void ConvertVertices(u32 dwTypeDest, void* pDest, u32 dwTypeSrc, void* pSource, u32 dwCount) -// assuming that pDest is large enought to maintain all the data -{ - u32 TransferMask[64]; - u32 tmPos = 0; - u32 tmPosSrc = 0; - u32 dwSizeSrc = D3DXGetFVFVertexSize(dwTypeSrc) / 4; - u32 dwSizeDest = D3DXGetFVFVertexSize(dwTypeDest) / 4; - u32* dest = (u32*)pDest; - u32* src = (u32*)pSource; - - // avoid redundant processing - if (dwTypeDest == dwTypeSrc) - { - CopyMemory(pDest, pSource, dwSizeDest * dwCount * 4); - return; - } - - // how many bytes to 'simple copy' - u32 dwPosDest = (dwTypeDest & D3DFVF_POSITION_MASK) >> 1; - u32 dwPosSrc = (dwTypeSrc & D3DFVF_POSITION_MASK) >> 1; - if (dwPosDest == dwPosSrc) - { - u32 cnt = dwPositionPart[dwPosSrc]; - for (u32 i = 0; i < cnt; i++) - TransferMask[tmPos++] = i; - tmPosSrc = tmPos; - } - else - { - VERIFY2(0, "Can't convert between different vertex positions"); - } - - // ---------------------- "Reserved" property - if ((dwTypeDest & D3DFVF_PSIZE) && (dwTypeSrc & D3DFVF_PSIZE)) - { // DEST & SRC - TransferMask[tmPos++] = tmPosSrc++; - } - if ((dwTypeDest & D3DFVF_PSIZE) && !(dwTypeSrc & D3DFVF_PSIZE)) - { // DEST & !SRC - TransferMask[tmPos++] = FAKEZ; // fake data - } - if (!(dwTypeDest & D3DFVF_PSIZE) && (dwTypeSrc & D3DFVF_PSIZE)) - { // !DEST & SRC - tmPosSrc++; // skip it - } - - // ---------------------- "Normal" property - if ((dwTypeDest & D3DFVF_NORMAL) && (dwTypeSrc & D3DFVF_NORMAL)) - { // DEST & SRC - TransferMask[tmPos++] = tmPosSrc++; - TransferMask[tmPos++] = tmPosSrc++; - TransferMask[tmPos++] = tmPosSrc++; - } - if ((dwTypeDest & D3DFVF_NORMAL) && !(dwTypeSrc & D3DFVF_NORMAL)) - { // DEST & !SRC - VERIFY2(0, "Source format doesn't have NORMAL but destination HAS"); - } - if (!(dwTypeDest & D3DFVF_NORMAL) && (dwTypeSrc & D3DFVF_NORMAL)) - { // !DEST & SRC - tmPosSrc++; // skip it - tmPosSrc++; // skip it - tmPosSrc++; // skip it - } - - // ---------------------- "Diffuse" property - if ((dwTypeDest & D3DFVF_DIFFUSE) && (dwTypeSrc & D3DFVF_DIFFUSE)) - { // DEST & SRC - TransferMask[tmPos++] = tmPosSrc++; - } - if ((dwTypeDest & D3DFVF_DIFFUSE) && !(dwTypeSrc & D3DFVF_DIFFUSE)) - { // DEST & !SRC - TransferMask[tmPos++] = FAKES; // fake data - white - } - if (!(dwTypeDest & D3DFVF_DIFFUSE) && (dwTypeSrc & D3DFVF_DIFFUSE)) - { // !DEST & SRC - tmPosSrc++; // skip it - } - - // ---------------------- "Specular" property - if ((dwTypeDest & D3DFVF_SPECULAR) && (dwTypeSrc & D3DFVF_SPECULAR)) - { // DEST & SRC - TransferMask[tmPos++] = tmPosSrc++; - } - if ((dwTypeDest & D3DFVF_SPECULAR) && !(dwTypeSrc & D3DFVF_SPECULAR)) - { // DEST & !SRC - TransferMask[tmPos++] = FAKES; // fake data - white - } - if (!(dwTypeDest & D3DFVF_SPECULAR) && (dwTypeSrc & D3DFVF_SPECULAR)) - { // !DEST & SRC - tmPosSrc++; // skip it - } - - // ---------------------- "Texture coords" property - u32 dwTDest = ((dwTypeDest & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); - u32 dwTSrc = ((dwTypeSrc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); - if (dwTDest <= dwTSrc) - { - for (u32 i = 0; i < dwTDest; i++) - { - TransferMask[tmPos++] = tmPosSrc++; - TransferMask[tmPos++] = tmPosSrc++; - } - } - else - { - if (dwTSrc == 0) - { - R_ASSERT(0 == "Source vertex format doesn't has texture coords at all"); - } - // Copy real TC - u32 dwStage0TC = tmPosSrc; - for (u32 i = 0; i < dwTSrc; i++) - { - TransferMask[tmPos++] = tmPosSrc++; - TransferMask[tmPos++] = tmPosSrc++; - } - // Duplicate stage0 TC - for (u32 i = dwTSrc; i < dwTDest; i++) - { - TransferMask[tmPos++] = dwStage0TC; - TransferMask[tmPos++] = dwStage0TC + 1; - } - } - - // ---------------------- REAL CONVERTION USING BUILDED MASK - for (u32 i = 0; i < dwCount; i++) - { - // one vertex - for (u32 j = 0; j < dwSizeDest; j++) - { - u32 m = TransferMask[j]; - if (m == FAKES) - dest[j] = 0xffffffff; - else if (m == FAKEZ) - dest[j] = 0; - else - dest[j] = src[m]; - } - dest += dwSizeDest; - src += dwSizeSrc; - } - return; -} diff --git a/src/utils/xrLC/net.cpp b/src/utils/xrLC/net.cpp deleted file mode 100644 index 99945780566..00000000000 --- a/src/utils/xrLC/net.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "stdafx.h" - -#include "utils/xrLC_Light/net_task_manager.h" - -#include "utils/xrLC_Light/lcnet_task_manager.h" - -#include "utils/xrLC_Light/lcnet_execution_tasks_add.h" -#include "utils/xrLC_Light/net_exec_pool.h" -void net_light() -{ - /* create_net_task_manager(); - get_net_task_manager()->run(); - destroy_net_task_manager();*/ -} - -namespace lc_net -{ -void net_lightmaps() -{ - // get_task_manager().create_global_data_write(""); - net_lightmaps_add_all_tasks(); - get_task_manager().run("Net Lightmaps"); - // get_task_manager().wait_all(); - - // ImplicitNetWait(); - // -} -} diff --git a/src/utils/xrLC/net.h b/src/utils/xrLC/net.h deleted file mode 100644 index 4d83bfc5250..00000000000 --- a/src/utils/xrLC/net.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -void net_light(); -namespace lc_net -{ -void net_lightmaps(); -} diff --git a/src/utils/xrLC/nv_library/NvTriStrip.cpp b/src/utils/xrLC/nv_library/NvTriStrip.cpp deleted file mode 100644 index 4d5a43bb1fd..00000000000 --- a/src/utils/xrLC/nv_library/NvTriStrip.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "stdafx.h" -#include "NvTriStripObjects.h" -#include "NvTriStrip.h" - -#pragma warning(disable : 4018) - -//////////////////////////////////////////////////////////////////////////////////////// -// private data -static unsigned int cacheSize = CACHESIZE_GEFORCE1_2; -static bool bStitchStrips = true; -static unsigned int minStripSize = 0; -static bool bListsOnly = false; - -//////////////////////////////////////////////////////////////////////////////////////// -// SetListsOnly() -// -// If set to true, will return an optimized list, with no strips at all. -// -// Default value: false -// -void SetListsOnly(const bool _bListsOnly) { bListsOnly = _bListsOnly; } -//////////////////////////////////////////////////////////////////////////////////////// -// SetCacheSize() -// -// Sets the cache size which the stripfier uses to optimize the data. -// Controls the length of the generated individual strips. -// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2 -// You may want to play around with this number to tweak performance. -// -// Default value: 16 -// -void SetCacheSize(const unsigned int _cacheSize) { cacheSize = _cacheSize; } -//////////////////////////////////////////////////////////////////////////////////////// -// SetStitchStrips() -// -// bool to indicate whether to stitch together strips into one huge strip or not. -// If set to true, you'll get back one huge strip stitched together using degenerate -// triangles. -// If set to false, you'll get back a large number of separate strips. -// -// Default value: true -// -void SetStitchStrips(const bool _bStitchStrips) { bStitchStrips = _bStitchStrips; } -//////////////////////////////////////////////////////////////////////////////////////// -// SetMinStripSize() -// -// Sets the minimum acceptable size for a strip, in triangles. -// All strips generated which are shorter than this will be thrown into one big, separate list. -// -// Default value: 0 -// -void SetMinStripSize(const unsigned int _minStripSize) { minStripSize = _minStripSize; } -//////////////////////////////////////////////////////////////////////////////////////// -// GenerateStrips() -// -// in_indices: input index list, the indices you would use to render -// in_numIndices: number of entries in in_indices -// primGroups: array of optimized/stripified PrimitiveGroups -// numGroups: number of groups returned -// -// Be sure to call xr_free on the returned primGroups to avoid leaking mem -// -void GenerateStrips(const u16* in_indices, const s32 in_numIndices, xr_vector& primGroups) -{ - // put data in format that the stripifier likes - WordVec tempIndices; - tempIndices.resize(in_numIndices); - int i; - for (i = 0; i < in_numIndices; i++) - tempIndices[i] = in_indices[i]; - NvStripInfoVec tempStrips; - NvFaceInfoVec tempFaces; - - NvStripifier stripifier; - - // do actual stripification - stripifier.Stripify(tempIndices, cacheSize, minStripSize, tempStrips, tempFaces); - - // stitch strips together - IntVec stripIndices; - unsigned int numSeparateStrips = 0; - - if (bListsOnly) - { - // if we're outputting only lists, we're done - primGroups.resize(1); - - // count the total number of indices - unsigned int numIndices = 0; - for (int i = 0; i < tempStrips.size(); i++) - { - numIndices += tempStrips[i]->m_faces.size() * 3; - } - - // add in the list - numIndices += tempFaces.size() * 3; - - primGroups[0].type = PT_LIST; - primGroups[0].numIndices = numIndices; - primGroups[0].indices = xr_alloc(numIndices); - - // do strips - unsigned int indexCtr = 0; - for (u32 i = 0; i < tempStrips.size(); i++) - { - for (int j = 0; j < tempStrips[i]->m_faces.size(); j++) - { - primGroups[0].indices[indexCtr++] = u16(tempStrips[i]->m_faces[j]->m_v0); - primGroups[0].indices[indexCtr++] = u16(tempStrips[i]->m_faces[j]->m_v1); - primGroups[0].indices[indexCtr++] = u16(tempStrips[i]->m_faces[j]->m_v2); - } - } - - // do lists - for (u32 i = 0; i < tempFaces.size(); i++) - { - primGroups[0].indices[indexCtr++] = u16(tempFaces[i]->m_v0); - primGroups[0].indices[indexCtr++] = u16(tempFaces[i]->m_v1); - primGroups[0].indices[indexCtr++] = u16(tempFaces[i]->m_v2); - } - } - else - { - stripifier.CreateStrips(tempStrips, stripIndices, bStitchStrips, numSeparateStrips); - - // if we're stitching strips together, we better get back only one strip from CreateStrips() - assert((bStitchStrips && (numSeparateStrips == 1)) || !bStitchStrips); - - // convert to output format - int numGroups = u16(numSeparateStrips); // for the strips - if (tempFaces.size() != 0) - numGroups++; // we've got a list as well, increment - primGroups.resize(numGroups); - - // first, the strips - int startingLoc = 0; - int stripCtr; - for (stripCtr = 0; stripCtr < numSeparateStrips; stripCtr++) - { - int stripLength = 0; - if (numSeparateStrips != 1) - { - // if we've got multiple strips, we need to figure out the correct length - int i; - for (i = startingLoc; i < stripIndices.size(); i++) - { - if (stripIndices[i] == -1) - break; - } - - stripLength = i - startingLoc; - } - else - stripLength = stripIndices.size(); - - primGroups[stripCtr].type = PT_STRIP; - primGroups[stripCtr].indices = xr_alloc(stripLength); - primGroups[stripCtr].numIndices = stripLength; - - int indexCtr = 0; - for (int i = startingLoc; i < stripLength + startingLoc; i++) - primGroups[stripCtr].indices[indexCtr++] = u16(stripIndices[i]); - - startingLoc += stripLength + 1; // we add 1 to account for the -1 separating strips - } - - // next, the list - if (tempFaces.size() != 0) - { - int faceGroupLoc = numGroups - 1; // the face group is the last one - primGroups[faceGroupLoc].type = PT_LIST; - primGroups[faceGroupLoc].indices = xr_alloc(tempFaces.size() * 3); - primGroups[faceGroupLoc].numIndices = tempFaces.size() * 3; - int indexCtr = 0; - for (int i = 0; i < tempFaces.size(); i++) - { - primGroups[faceGroupLoc].indices[indexCtr++] = u16(tempFaces[i]->m_v0); - primGroups[faceGroupLoc].indices[indexCtr++] = u16(tempFaces[i]->m_v1); - primGroups[faceGroupLoc].indices[indexCtr++] = u16(tempFaces[i]->m_v2); - } - } - } - - // clean up everything - - //_delete strips - for (u32 i = 0; i < tempStrips.size(); i++) - { - for (int j = 0; j < tempStrips[i]->m_faces.size(); j++) - { - xr_delete(tempStrips[i]->m_faces[j]); - } - xr_delete(tempStrips[i]); - } - - //_delete faces - for (u32 i = 0; i < tempFaces.size(); i++) - { - xr_delete(tempFaces[i]); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -// RemapIndices() -// -// Function to remap your indices to improve spatial locality in your vertex buffer. -// -// in_primGroups: array of PrimitiveGroups you want remapped -// numGroups: number of entries in in_primGroups -// numVerts: number of vertices in your vertex buffer, also can be thought of as the range -// of acceptable values for indices in your primitive groups. -// remappedGroups: array of remapped PrimitiveGroups -// -// Note that, according to the remapping handed back to you, you must reorder your -// vertex buffer. -// -void RemapIndices( - const xr_vector& in_primGroups, const u16 numVerts, xr_vector& remappedGroups) -{ - int numGroups = in_primGroups.size(); - remappedGroups.resize(numGroups); - - // caches oldIndex --> newIndex conversion - int* indexCache; - indexCache = xr_alloc(numVerts); - FillMemory(indexCache, sizeof(int) * numVerts, -1); - - // loop over primitive groups - unsigned int indexCtr = 0; - for (int i = 0; i < numGroups; i++) - { - unsigned int numIndices = in_primGroups[i].numIndices; - - // init remapped group - remappedGroups[i].type = in_primGroups[i].type; - remappedGroups[i].numIndices = numIndices; - remappedGroups[i].indices = xr_alloc(numIndices); - - for (int j = 0; j < numIndices; j++) - { - int cachedIndex = indexCache[in_primGroups[i].indices[j]]; - if (cachedIndex == -1) // we haven't seen this index before - { - // point to "last" vertex in VB - remappedGroups[i].indices[j] = u16(indexCtr); - - // add to index cache, increment - indexCache[in_primGroups[i].indices[j]] = indexCtr++; - } - else - { - // we've seen this index before - remappedGroups[i].indices[j] = u16(cachedIndex); - } - } - } - - xr_free(indexCache); -} diff --git a/src/utils/xrLC/nv_library/NvTriStrip.h b/src/utils/xrLC/nv_library/NvTriStrip.h deleted file mode 100644 index 9e14b1bac4f..00000000000 --- a/src/utils/xrLC/nv_library/NvTriStrip.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef NVTRISTRIP_H -#define NVTRISTRIP_H - -#ifndef NULL -#define NULL 0 -#endif - -//////////////////////////////////////////////////////////////////////////////////////// -// Public interface for stripifier -//////////////////////////////////////////////////////////////////////////////////////// - -// GeForce1 and 2 cache size -#define CACHESIZE_GEFORCE1_2 16 - -// GeForce3 cache size -#define CACHESIZE_GEFORCE3 24 - -enum PrimType -{ - PT_LIST, - PT_STRIP, - PT_FAN -}; - -struct PrimitiveGroup -{ - PrimType type; - unsigned int numIndices; - unsigned short* indices; - - //////////////////////////////////////////////////////////////////////////////////////// - - PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {} - ~PrimitiveGroup() - { - if (indices) - xr_free(indices); - } -}; - -//////////////////////////////////////////////////////////////////////////////////////// -// SetCacheSize() -// -// Sets the cache size which the stripfier uses to optimize the data. -// Controls the length of the generated individual strips. -// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2 -// You may want to play around with this number to tweak performance. -// -// Default value: 16 -// -void SetCacheSize(const unsigned int cacheSize); - -//////////////////////////////////////////////////////////////////////////////////////// -// SetStitchStrips() -// -// bool to indicate whether to stitch together strips into one huge strip or not. -// If set to true, you'll get back one huge strip stitched together using degenerate -// triangles. -// If set to false, you'll get back a large number of separate strips. -// -// Default value: true -// -void SetStitchStrips(const bool bStitchStrips); - -//////////////////////////////////////////////////////////////////////////////////////// -// SetMinStripSize() -// -// Sets the minimum acceptable size for a strip, in triangles. -// All strips generated which are shorter than this will be thrown into one big, separate list. -// -// Default value: 0 -// -void SetMinStripSize(const unsigned int minSize); - -//////////////////////////////////////////////////////////////////////////////////////// -// SetListsOnly() -// -// If set to true, will return an optimized list, with no strips at all. -// -// Default value: false -// -void SetListsOnly(const bool bListsOnly); - -//////////////////////////////////////////////////////////////////////////////////////// -// GenerateStrips() -// -// in_indices: input index list, the indices you would use to render -// in_numIndices: number of entries in in_indices -// primGroups: array of optimized/stripified PrimitiveGroups -// numGroups: number of groups returned -// -// Be sure to call xr_free on the returned primGroups to avoid leaking mem -// -void GenerateStrips(const u16* in_indices, const s32 in_numIndices, xr_vector& primGroups); - -//////////////////////////////////////////////////////////////////////////////////////// -// RemapIndices() -// -// Function to remap your indices to improve spatial locality in your vertex buffer. -// -// in_primGroups: array of PrimitiveGroups you want remapped -// numGroups: number of entries in in_primGroups -// numVerts: number of vertices in your vertex buffer, also can be thought of as the range -// of acceptable values for indices in your primitive groups. -// remappedGroups: array of remapped PrimitiveGroups -// -// Note that, according to the remapping handed back to you, you must reorder your -// vertex buffer. -// -// Credit goes to the MS Xbox crew for the idea for this interface. -// -void RemapIndices( - const xr_vector& in_primGroups, const u16 numVerts, xr_vector& remappedGroups); - -#endif diff --git a/src/utils/xrLC/nv_library/NvTriStripObjects.cpp b/src/utils/xrLC/nv_library/NvTriStripObjects.cpp deleted file mode 100644 index b2cb2ff8199..00000000000 --- a/src/utils/xrLC/nv_library/NvTriStripObjects.cpp +++ /dev/null @@ -1,1355 +0,0 @@ -#include "stdafx.h" -#pragma warning(disable : 4786) -#pragma warning(disable : 4018) - -#include -#include -#include "NvTriStripObjects.h" -#include "VertexCache.h" - -#define CACHE_INEFFICIENCY 6 - -NvStripifier::NvStripifier() {} -NvStripifier::~NvStripifier() {} -/////////////////////////////////////////////////////////////////////////////////////////// -// FindEdgeInfo() -// -// find the edge info for these two indices -// -NvEdgeInfo* NvStripifier::FindEdgeInfo(NvEdgeInfoVec& edgeInfos, int v0, int v1) -{ - // we can get to it through either array - // because the edge infos have a v0 and v1 - // and there is no order except how it was - // first created. - NvEdgeInfo* infoIter = edgeInfos[v0]; - while (infoIter != NULL) - { - if (infoIter->m_v0 == v0) - { - if (infoIter->m_v1 == v1) - return infoIter; - else - infoIter = infoIter->m_nextV0; - } - else - { - assert(infoIter->m_v1 == v0); - if (infoIter->m_v0 == v1) - return infoIter; - else - infoIter = infoIter->m_nextV1; - } - } - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// FindOtherFace -// -// find the other face sharing these vertices -// exactly like the edge info above -// -NvFaceInfo* NvStripifier::FindOtherFace(NvEdgeInfoVec& edgeInfos, int v0, int v1, NvFaceInfo* faceInfo) -{ - NvEdgeInfo* edgeInfo = FindEdgeInfo(edgeInfos, v0, v1); - assert(edgeInfo != NULL); - return (edgeInfo->m_face0 == faceInfo ? edgeInfo->m_face1 : edgeInfo->m_face0); -} - -bool NvStripifier::AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos) -{ - for (int i = 0; i < faceInfos.size(); i++) - { - if ((faceInfos[i]->m_v0 == faceInfo->m_v0) && (faceInfos[i]->m_v1 == faceInfo->m_v1) && - (faceInfos[i]->m_v2 == faceInfo->m_v2)) - return true; - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// BuildStripifyInfo() -// -// Builds the list of all face and edge infos -// -void NvStripifier::BuildStripifyInfo(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos) -{ - // reserve space for the face infos, but do not resize them. - int numIndices = indices.size(); - faceInfos.reserve(numIndices); - - // we actually resize the edge infos, so we must initialize to NULL - edgeInfos.resize(numIndices); - for (int i = 0; i < numIndices; i++) - edgeInfos[i] = NULL; - - // iterate through the triangles of the triangle list - int numTriangles = numIndices / 3; - int index = 0; - for (u32 i = 0; i < numTriangles; i++) - { - // grab the indices - int v0 = indices[index++]; - int v1 = indices[index++]; - int v2 = indices[index++]; - - // create the face info and add it to the list of faces, but only if this exact face doesn't already - // exist in the list - NvFaceInfo* faceInfo = xr_new(v0, v1, v2); - if (!AlreadyExists(faceInfo, faceInfos)) - { - faceInfos.push_back(faceInfo); - - // grab the edge infos, creating them if they do not already exist - NvEdgeInfo* edgeInfo01 = FindEdgeInfo(edgeInfos, v0, v1); - if (edgeInfo01 == NULL) - { - // create the info - edgeInfo01 = xr_new(v0, v1); - - // update the linked list on both - edgeInfo01->m_nextV0 = edgeInfos[v0]; - edgeInfo01->m_nextV1 = edgeInfos[v1]; - edgeInfos[v0] = edgeInfo01; - edgeInfos[v1] = edgeInfo01; - - // set face 0 - edgeInfo01->m_face0 = faceInfo; - } - else - { - if (edgeInfo01->m_face1 != NULL) - ; - // Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); - else - edgeInfo01->m_face1 = faceInfo; - } - - // grab the edge infos, creating them if they do not already exist - NvEdgeInfo* edgeInfo12 = FindEdgeInfo(edgeInfos, v1, v2); - if (edgeInfo12 == NULL) - { - // create the info - edgeInfo12 = xr_new(v1, v2); - - // update the linked list on both - edgeInfo12->m_nextV0 = edgeInfos[v1]; - edgeInfo12->m_nextV1 = edgeInfos[v2]; - edgeInfos[v1] = edgeInfo12; - edgeInfos[v2] = edgeInfo12; - - // set face 0 - edgeInfo12->m_face0 = faceInfo; - } - else - { - if (edgeInfo12->m_face1 != NULL) - ; - // Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); - else - edgeInfo12->m_face1 = faceInfo; - } - - // grab the edge infos, creating them if they do not already exist - NvEdgeInfo* edgeInfo20 = FindEdgeInfo(edgeInfos, v2, v0); - if (edgeInfo20 == NULL) - { - // create the info - edgeInfo20 = xr_new(v2, v0); - - // update the linked list on both - edgeInfo20->m_nextV0 = edgeInfos[v2]; - edgeInfo20->m_nextV1 = edgeInfos[v0]; - edgeInfos[v2] = edgeInfo20; - edgeInfos[v0] = edgeInfo20; - - // set face 0 - edgeInfo20->m_face0 = faceInfo; - } - else - { - if (edgeInfo20->m_face1 != NULL) - ; - // Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); - else - edgeInfo20->m_face1 = faceInfo; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// FindStartPoint() -// -// Finds a good starting point, namely one which has only one neighbor -// -int NvStripifier::FindStartPoint(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos) -{ - for (int i = 0; i < faceInfos.size(); i++) - { - int ctr = 0; - - if (FindOtherFace(edgeInfos, faceInfos[i]->m_v0, faceInfos[i]->m_v1, faceInfos[i]) == NULL) - ctr++; - if (FindOtherFace(edgeInfos, faceInfos[i]->m_v1, faceInfos[i]->m_v2, faceInfos[i]) == NULL) - ctr++; - if (FindOtherFace(edgeInfos, faceInfos[i]->m_v2, faceInfos[i]->m_v0, faceInfos[i]) == NULL) - ctr++; - if (ctr > 1) - return i; - } - return -1; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// FindGoodResetPoint() -// -// A good reset point is one near other commited areas so that -// we know that when we've made the longest strips its because -// we're stripifying in the same general orientation. -// -NvFaceInfo* NvStripifier::FindGoodResetPoint(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos) -{ - // we hop into different areas of the mesh to try to get - // other large open spans done. Areas of small strips can - // just be left to triangle lists added at the end. - NvFaceInfo* result = NULL; - - if (result == NULL) - { - int numFaces = faceInfos.size(); - int startPoint; - if (bFirstTimeResetPoint) - { - // first time, find a face with few neighbors (look for an edge of the mesh) - startPoint = FindStartPoint(faceInfos, edgeInfos); - bFirstTimeResetPoint = false; - } - else - startPoint = (int)(((float)numFaces - 1) * meshJump); - - if (startPoint == -1) - startPoint = (int)(((float)numFaces - 1) * meshJump); - - int i = startPoint; - do - { - // if this guy isn't visited, try him - if (faceInfos[i]->m_stripId < 0) - { - result = faceInfos[i]; - break; - } - - // update the index and clamp to 0-(numFaces-1) - if (++i >= numFaces) - i = 0; - - } while (i != startPoint); - - // update the meshJump - meshJump += 0.1f; - if (meshJump > 1.0f) - meshJump = .05f; - } - - // return the best face we found - return result; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// GetUniqueVertexInB() -// -// Returns the vertex unique to faceB -// -int NvStripifier::GetUniqueVertexInB(NvFaceInfo* faceA, NvFaceInfo* faceB) -{ - int facev0 = faceB->m_v0; - if (facev0 != faceA->m_v0 && facev0 != faceA->m_v1 && facev0 != faceA->m_v2) - return facev0; - - int facev1 = faceB->m_v1; - if (facev1 != faceA->m_v0 && facev1 != faceA->m_v1 && facev1 != faceA->m_v2) - return facev1; - - int facev2 = faceB->m_v2; - if (facev2 != faceA->m_v0 && facev2 != faceA->m_v1 && facev2 != faceA->m_v2) - return facev2; - - // nothing is different - return -1; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// GetSharedVertex() -// -// Returns the vertex shared between the two input faces -// -int NvStripifier::GetSharedVertex(NvFaceInfo* faceA, NvFaceInfo* faceB) -{ - int facev0 = faceB->m_v0; - if (facev0 == faceA->m_v0 || facev0 == faceA->m_v1 || facev0 == faceA->m_v2) - return facev0; - - int facev1 = faceB->m_v1; - if (facev1 == faceA->m_v0 || facev1 == faceA->m_v1 || facev1 == faceA->m_v2) - return facev1; - - int facev2 = faceB->m_v2; - if (facev2 == faceA->m_v0 || facev2 == faceA->m_v1 || facev2 == faceA->m_v2) - return facev2; - - // nothing is shared - return -1; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// GetNextIndex() -// -// Returns vertex of the input face which is "next" in the input index list -// -IC int NvStripifier::GetNextIndex(const WordVec& indices, NvFaceInfo* face) -{ - int numIndices = indices.size(); - assert(numIndices >= 2); - - int v0 = indices[numIndices - 2]; - int v1 = indices[numIndices - 1]; - - int fv0 = face->m_v0; - int fv1 = face->m_v1; - int fv2 = face->m_v2; - - if (fv0 != v0 && fv0 != v1) - { - if ((fv1 != v0 && fv1 != v1) || (fv2 != v0 && fv2 != v1)) - { - Msg("! WARNING: GetNextIndex: Triangle doesn't have all of its vertices"); - Msg("! WARNING: GetNextIndex: Duplicate triangle probably got us derailed"); - } - return fv0; - } - if (fv1 != v0 && fv1 != v1) - { - if ((fv0 != v0 && fv0 != v1) || (fv2 != v0 && fv2 != v1)) - { - Msg("! WARNING: GetNextIndex: Triangle doesn't have all of its vertices"); - Msg("! WARNING: GetNextIndex: Duplicate triangle probably got us derailed"); - } - return fv1; - } - if (fv2 != v0 && fv2 != v1) - { - if ((fv0 != v0 && fv0 != v1) || (fv1 != v0 && fv1 != v1)) - { - Msg("! WARNING: GetNextIndex: Triangle doesn't have all of its vertices"); - Msg("! WARNING: GetNextIndex: Duplicate triangle probably got us derailed"); - } - return fv2; - } - - // shouldn't get here - Msg("! WARNING: GetNextIndex: Duplicate triangle sent"); - return -1; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// IsMarked() -// -// If either the faceInfo has a real strip index because it is -// already assign to a committed strip OR it is assigned in an -// experiment and the experiment index is the one we are building -// for, then it is marked and unavailable -IC bool NvStripInfo::IsMarked(NvFaceInfo* faceInfo) -{ - return (faceInfo->m_stripId >= 0) || (IsExperiment() && faceInfo->m_experimentId == m_experimentId); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// MarkTriangle() -// -// Marks the face with the current strip ID -// -IC void NvStripInfo::MarkTriangle(NvFaceInfo* faceInfo) -{ - assert(!IsMarked(faceInfo)); - if (IsExperiment()) - { - faceInfo->m_experimentId = m_experimentId; - faceInfo->m_testStripId = m_stripId; - } - else - { - assert(faceInfo->m_stripId == -1); - faceInfo->m_experimentId = -1; - faceInfo->m_stripId = m_stripId; - } -} - -bool NvStripInfo::Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face) -{ - bool bv0, bv1, bv2; // bools to indicate whether a vertex is in the faceVec or not - bv0 = bv1 = bv2 = false; - - for (int i = 0; i < faceVec.size(); i++) - { - if (!bv0) - { - if ((faceVec[i]->m_v0 == face->m_v0) || (faceVec[i]->m_v1 == face->m_v0) || - (faceVec[i]->m_v2 == face->m_v0)) - bv0 = true; - } - - if (!bv1) - { - if ((faceVec[i]->m_v0 == face->m_v1) || (faceVec[i]->m_v1 == face->m_v1) || - (faceVec[i]->m_v2 == face->m_v1)) - bv1 = true; - } - - if (!bv2) - { - if ((faceVec[i]->m_v0 == face->m_v2) || (faceVec[i]->m_v1 == face->m_v2) || - (faceVec[i]->m_v2 == face->m_v2)) - bv2 = true; - } - - // the face is not unique, all it's vertices exist in the face vector3 - if (bv0 && bv1 && bv2) - return false; - } - - // if we get out here, it's unique - return true; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// Build() -// -// Builds a strip forward as far as we can go, then builds backwards, and joins the two lists -// -void NvStripInfo::Build(NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& faceInfos) -{ - // used in building the strips forward and backward - static WordVec scratchIndices; - scratchIndices.resize(0); - - // build forward... start with the initial face - NvFaceInfoVec forwardFaces, backwardFaces; - forwardFaces.push_back(m_startInfo.m_startFace); - - MarkTriangle(m_startInfo.m_startFace); - - int v0 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge->m_v0 : m_startInfo.m_startEdge->m_v1); - int v1 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge->m_v1 : m_startInfo.m_startEdge->m_v0); - - // easiest way to get v2 is to use this function which requires the - // other indices to already be in the list. - scratchIndices.push_back(u16(v0)); - scratchIndices.push_back(u16(v1)); - int v2 = NvStripifier::GetNextIndex(scratchIndices, m_startInfo.m_startFace); - scratchIndices.push_back(u16(v2)); - - // - // build the forward list - // - int nv0 = v1; - int nv1 = v2; - - NvFaceInfo* nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace); - while (nextFace != NULL && !IsMarked(nextFace)) - { - // this tests to see if a face is "unique", meaning that its vertices aren't already in the list - // so, strips which "wrap-around" are not allowed - if (!Unique(forwardFaces, nextFace)) - break; - - // add this to the strip - forwardFaces.push_back(nextFace); - - MarkTriangle(nextFace); - - // add the index - nv0 = nv1; - nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); - scratchIndices.push_back(u16(nv1)); - - // and get the next face - nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, nextFace); - } - - // tempAllFaces is going to be forwardFaces + backwardFaces - // it's used for Unique() - NvFaceInfoVec tempAllFaces; - for (int i = 0; i < forwardFaces.size(); i++) - tempAllFaces.push_back(forwardFaces[i]); - - // - // reset the indices for building the strip backwards and do so - // - scratchIndices.resize(0); - scratchIndices.push_back(u16(v2)); - scratchIndices.push_back(u16(v1)); - scratchIndices.push_back(u16(v0)); - nv0 = v1; - nv1 = v0; - nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace); - while (nextFace != NULL && !IsMarked(nextFace)) - { - // this tests to see if a face is "unique", meaning that its vertices aren't already in the list - // so, strips which "wrap-around" are not allowed - if (!Unique(tempAllFaces, nextFace)) - break; - - // add this to the strip - backwardFaces.push_back(nextFace); - - // this is just so Unique() will work - tempAllFaces.push_back(nextFace); - - MarkTriangle(nextFace); - - // add the index - nv0 = nv1; - nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); - scratchIndices.push_back(u16(nv1)); - - // and get the next face - nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, nextFace); - } - - // Combine the forward and backwards stripification lists and put into our own face vector3 - Combine(forwardFaces, backwardFaces); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// Combine() -// -// Combines the two input face vectors and puts the result into m_faces -// -void NvStripInfo::Combine(const NvFaceInfoVec& forward, const NvFaceInfoVec& backward) -{ - // add backward faces - int numFaces = backward.size(); - for (int i = numFaces - 1; i >= 0; i--) - m_faces.push_back(backward[i]); - - // add forward faces - numFaces = forward.size(); - for (u32 i = 0; i < numFaces; i++) - m_faces.push_back(forward[i]); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// SharesEdge() -// -// Returns true if the input face and the current strip share an edge -// -bool NvStripInfo::SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec& edgeInfos) -{ - // check v0->v1 edge - NvEdgeInfo* currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v0, faceInfo->m_v1); - - if (IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) - return true; - - // check v1->v2 edge - currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v1, faceInfo->m_v2); - - if (IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) - return true; - - // check v2->v0 edge - currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v2, faceInfo->m_v0); - - if (IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) - return true; - - return false; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// CommitStrips() -// -// "Commits" the input strips by setting their m_experimentId to -1 and adding to the allStrips -// vector3 -// -void NvStripifier::CommitStrips(NvStripInfoVec& allStrips, const NvStripInfoVec& strips) -{ - // Iterate through strips - int numStrips = strips.size(); - for (int i = 0; i < numStrips; i++) - { - // Tell the strip that it is now real - NvStripInfo* strip = strips[i]; - strip->m_experimentId = -1; - - // add to the list of real strips - allStrips.push_back(strip); - - // Iterate through the faces of the strip - // Tell the faces of the strip that they belong to a real strip now - const NvFaceInfoVec& faces = strips[i]->m_faces; - int numFaces = faces.size(); - - for (int j = 0; j < numFaces; j++) - { - strip->MarkTriangle(faces[j]); - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// FindTraversal() -// -// Finds the next face to start the next strip on. -// -bool NvStripifier::FindTraversal( - NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos, NvStripInfo* strip, NvStripStartInfo& startInfo) -{ - // if the strip was v0->v1 on the edge, then v1 will be a vertex in the next edge. - int v = (strip->m_startInfo.m_toV1 ? strip->m_startInfo.m_startEdge->m_v1 : strip->m_startInfo.m_startEdge->m_v0); - - NvFaceInfo* untouchedFace = NULL; - NvEdgeInfo* edgeIter = edgeInfos[v]; - while (edgeIter != NULL) - { - NvFaceInfo* face0 = edgeIter->m_face0; - NvFaceInfo* face1 = edgeIter->m_face1; - if ((face0 != NULL && !strip->IsInStrip(face0)) && face1 != NULL && !strip->IsMarked(face1)) - { - untouchedFace = face1; - break; - } - if ((face1 != NULL && !strip->IsInStrip(face1)) && face0 != NULL && !strip->IsMarked(face0)) - { - untouchedFace = face0; - break; - } - - // find the next edgeIter - edgeIter = (edgeIter->m_v0 == v ? edgeIter->m_nextV0 : edgeIter->m_nextV1); - } - - startInfo.m_startFace = untouchedFace; - startInfo.m_startEdge = edgeIter; - if (edgeIter != NULL) - { - if (strip->SharesEdge(startInfo.m_startFace, edgeInfos)) - startInfo.m_toV1 = (edgeIter->m_v0 == v); // note! used to be m_v1 - else - startInfo.m_toV1 = (edgeIter->m_v1 == v); - } - return (startInfo.m_startFace != NULL); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// RemoveSmallStrips() -// -// allStrips is the whole strip _vector_...all small strips will be deleted from this list, to avoid leaking mem -// allBigStrips is an out parameter which will contain all strips above minStripLength -// faceList is an out parameter which will contain all faces which were removed from the striplist -// -void NvStripifier::RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList) -{ - faceList.clear(); - allBigStrips.clear(); // make sure these are empty - NvFaceInfoVec tempFaceList; - - for (int i = 0; i < allStrips.size(); i++) - { - if (allStrips[i]->m_faces.size() < minStripLength) - { - // strip is too small, add faces to faceList - for (int j = 0; j < allStrips[i]->m_faces.size(); j++) - tempFaceList.push_back(allStrips[i]->m_faces[j]); - - // and xr_free memory - xr_delete(allStrips[i]); - } - else - { - allBigStrips.push_back(allStrips[i]); - } - } - - bool* bVisitedList = xr_alloc(tempFaceList.size()); - ZeroMemory(bVisitedList, tempFaceList.size() * sizeof(bool)); - - VertexCache* vcache = xr_new(cacheSize); - - int bestNumHits = -1; - int numHits = 0; - int bestIndex = 0; - - while (1) - { - bestNumHits = -1; - - // find best face to add next, given the current cache - for (int i = 0; i < tempFaceList.size(); i++) - { - if (bVisitedList[i]) - continue; - - numHits = CalcNumHitsFace(vcache, tempFaceList[i]); - if (numHits > bestNumHits) - { - bestNumHits = numHits; - bestIndex = i; - } - } - - if (bestNumHits == -1.0f) - break; - bVisitedList[bestIndex] = true; - UpdateCacheFace(vcache, tempFaceList[bestIndex]); - faceList.push_back(tempFaceList[bestIndex]); - } - - xr_delete(vcache); - xr_free(bVisitedList); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// NextIsCW() -// -// Returns true if the next face should be ordered in CW fashion -// -bool NvStripifier::NextIsCW(const int numIndices) { return ((numIndices % 2) == 0); } -/////////////////////////////////////////////////////////////////////////////////////////// -// IsCW() -// -// Returns true if the face is ordered in CW fashion -// -bool NvStripifier::IsCW(NvFaceInfo* faceInfo, int v0, int v1) -{ - if (faceInfo->m_v0 == v0) - return (faceInfo->m_v1 == v1); - - else if (faceInfo->m_v1 == v0) - return (faceInfo->m_v2 == v1); - - else - return (faceInfo->m_v0 == v1); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// CreateStrips() -// -// Generates actual strips from the list-in-strip-order. -// -void NvStripifier::CreateStrips( - const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, unsigned int& numSeparateStrips) -{ - assert(numSeparateStrips == 0); - - NvFaceInfo tLastFace(0, 0, 0); - int nStripCount = allStrips.size(); - assert(nStripCount > 0); - - // we infer the cw/ccw ordering depending on the number of indices - // this is screwed up by the fact that we insert -1s to denote changing strips - // this is to account for that - int accountForNegatives = 0; - - for (int i = 0; i < nStripCount; i++) - { - NvStripInfo* strip = allStrips[i]; - int nStripFaceCount = strip->m_faces.size(); - assert(nStripFaceCount > 0); - - // Handle the first face in the strip - { - NvFaceInfo tFirstFace(strip->m_faces[0]->m_v0, strip->m_faces[0]->m_v1, strip->m_faces[0]->m_v2); - - // If there is a second face, reorder vertices such that the - // unique vertex is first - if (nStripFaceCount > 1) - { - int nUnique = NvStripifier::GetUniqueVertexInB(strip->m_faces[1], &tFirstFace); - if (nUnique == tFirstFace.m_v1) - { - SWAP(tFirstFace.m_v0, tFirstFace.m_v1); - } - else if (nUnique == tFirstFace.m_v2) - { - SWAP(tFirstFace.m_v0, tFirstFace.m_v2); - } - - // If there is a third face, reorder vertices such that the - // shared vertex is last - if (nStripFaceCount > 2) - { - int nShared = GetSharedVertex(strip->m_faces[2], &tFirstFace); - if (nShared == tFirstFace.m_v1) - { - SWAP(tFirstFace.m_v1, tFirstFace.m_v2); - } - } - } - - if ((i == 0) || !bStitchStrips) - { - if (!IsCW(strip->m_faces[0], tFirstFace.m_v0, tFirstFace.m_v1)) - stripIndices.push_back(tFirstFace.m_v0); - } - else - { - // Double tap the first in the _new strip - stripIndices.push_back(tFirstFace.m_v0); - - // Check CW/CCW ordering - if (NextIsCW(stripIndices.size() - accountForNegatives) != - IsCW(strip->m_faces[0], tFirstFace.m_v0, tFirstFace.m_v1)) - { - stripIndices.push_back(tFirstFace.m_v0); - } - } - - stripIndices.push_back(tFirstFace.m_v0); - stripIndices.push_back(tFirstFace.m_v1); - stripIndices.push_back(tFirstFace.m_v2); - - // Update last face info - tLastFace = tFirstFace; - } - - for (int j = 1; j < nStripFaceCount; j++) - { - int nUnique = GetUniqueVertexInB(&tLastFace, strip->m_faces[j]); - if (nUnique != -1) - { - stripIndices.push_back(nUnique); - - // Update last face info - tLastFace.m_v0 = tLastFace.m_v1; - tLastFace.m_v1 = tLastFace.m_v2; - tLastFace.m_v2 = nUnique; - } - } - - // Double tap between strips. - if (bStitchStrips) - { - if (i != nStripCount - 1) - stripIndices.push_back(tLastFace.m_v2); - } - else - { - //-1 index indicates next strip - stripIndices.push_back(-1); - accountForNegatives++; - numSeparateStrips++; - } - - // Update last face info - tLastFace.m_v0 = tLastFace.m_v1; - tLastFace.m_v1 = tLastFace.m_v2; - tLastFace.m_v2 = tLastFace.m_v2; - } - - if (bStitchStrips) - numSeparateStrips = 1; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// Stripify() -// -// -// in_indices are the input indices of the mesh to stripify -// in_cacheSize is the target cache size -// -void NvStripifier::Stripify(const WordVec& in_indices, const int in_cacheSize, const int in_minStripLength, - NvStripInfoVec& outStrips, NvFaceInfoVec& outFaceList) -{ - meshJump = 0.0f; - bFirstTimeResetPoint = true; // used in FindGoodResetPoint() - - // the number of times to run the experiments - int numSamples = 10; - - // the cache size, clamped to one - cacheSize = _max(1, in_cacheSize - CACHE_INEFFICIENCY); - - minStripLength = in_minStripLength; // this is the strip size threshold below which we dump the strip into a list - - indices = in_indices; - - // build the stripification info - NvFaceInfoVec allFaceInfos; - NvEdgeInfoVec allEdgeInfos; - - BuildStripifyInfo(allFaceInfos, allEdgeInfos); - - NvStripInfoVec allStrips; - - // stripify - FindAllStrips(allStrips, allFaceInfos, allEdgeInfos, numSamples); - - // split up the strips into cache friendly pieces, optimize them, then dump these into outStrips - SplitUpStripsAndOptimize(allStrips, outStrips, allEdgeInfos, outFaceList); - - // clean up - for (int i = 0; i < allStrips.size(); i++) - { - xr_delete(allStrips[i]); - } - - for (u32 i = 0; i < allEdgeInfos.size(); i++) - { - NvEdgeInfo* info = allEdgeInfos[i]; - while (info != NULL) - { - NvEdgeInfo* next = (info->m_v0 == int(i) ? info->m_nextV0 : info->m_nextV1); - info->Unref(); - info = next; - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// SplitUpStripsAndOptimize() -// -// Splits the input _vector_ of strips (allBigStrips) into smaller, cache friendly pieces, then -// reorders these pieces to maximize cache hits -// The final strips are output through outStrips -// -void NvStripifier::SplitUpStripsAndOptimize( - NvStripInfoVec& allStrips, NvStripInfoVec& outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList) -{ - int threshold = cacheSize; - NvStripInfoVec tempStrips; - - // split up strips into threshold-sized pieces - int i; - for (i = 0; i < allStrips.size(); i++) - { - NvStripInfo* currentStrip; - NvStripStartInfo startInfo(NULL, NULL, false); - - if (allStrips[i]->m_faces.size() > threshold) - { - int numTimes = allStrips[i]->m_faces.size() / threshold; - int numLeftover = allStrips[i]->m_faces.size() % threshold; - - int j; - for (j = 0; j < numTimes; j++) - { - currentStrip = xr_new(startInfo, 0, -1); - - for (int faceCtr = j * threshold; faceCtr < threshold + (j * threshold); faceCtr++) - { - currentStrip->m_faces.push_back(allStrips[i]->m_faces[faceCtr]); - } - - tempStrips.push_back(currentStrip); - } - - int leftOff = j * threshold; - - if (numLeftover != 0) - { - currentStrip = xr_new(startInfo, 0, -1); - - for (int k = 0; k < numLeftover; k++) - { - currentStrip->m_faces.push_back(allStrips[i]->m_faces[leftOff++]); - } - - tempStrips.push_back(currentStrip); - } - } - else - { - // we're not just doing a tempStrips.push_back(allBigStrips[i]) because - // this way we can _delete allBigStrips later to xr_free the memory - currentStrip = xr_new(startInfo, 0, -1); - - for (int j = 0; j < allStrips[i]->m_faces.size(); j++) - currentStrip->m_faces.push_back(allStrips[i]->m_faces[j]); - - tempStrips.push_back(currentStrip); - } - } - - // add small strips to face list - NvStripInfoVec tempStrips2; - RemoveSmallStrips(tempStrips, tempStrips2, outFaceList); - - outStrips.clear(); - if (tempStrips2.size() != 0) - { - // Optimize for the vertex cache - VertexCache* vcache = xr_new(cacheSize); - - float bestNumHits = -1.0f; - float numHits = 0; - int bestIndex = 0; - - int firstIndex = 0; - float minCost = 10000.0f; - - for (i = 0; i < tempStrips2.size(); i++) - { - int numNeighbors = 0; - - // find strip with least number of neighbors per face - for (int j = 0; j < tempStrips2[i]->m_faces.size(); j++) - { - numNeighbors += NumNeighbors(tempStrips2[i]->m_faces[j], edgeInfos); - } - - float currCost = (float)numNeighbors / (float)tempStrips2[i]->m_faces.size(); - if (currCost < minCost) - { - minCost = currCost; - firstIndex = i; - } - } - - UpdateCacheStrip(vcache, tempStrips2[firstIndex]); - outStrips.push_back(tempStrips2[firstIndex]); - - tempStrips2[firstIndex]->visited = true; - - // this n^2 algo is what slows down stripification so much.... - // needs to be improved - while (1) - { - bestNumHits = -1.0f; - - // find best strip to add next, given the current cache - for (int i = 0; i < tempStrips2.size(); i++) - { - if (tempStrips2[i]->visited) - continue; - - numHits = CalcNumHitsStrip(vcache, tempStrips2[i]); - if (numHits > bestNumHits) - { - bestNumHits = numHits; - bestIndex = i; - } - } - - if (bestNumHits == -1.0f) - break; - tempStrips2[bestIndex]->visited = true; - UpdateCacheStrip(vcache, tempStrips2[bestIndex]); - outStrips.push_back(tempStrips2[bestIndex]); - } - - xr_delete(vcache); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// UpdateCacheStrip() -// -// Updates the input vertex cache with this strip's vertices -// -void NvStripifier::UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip) -{ - for (int i = 0; i < strip->m_faces.size(); i++) - { - if (!vcache->InCache(strip->m_faces[i]->m_v0)) - vcache->AddEntry(strip->m_faces[i]->m_v0); - - if (!vcache->InCache(strip->m_faces[i]->m_v1)) - vcache->AddEntry(strip->m_faces[i]->m_v1); - - if (!vcache->InCache(strip->m_faces[i]->m_v2)) - vcache->AddEntry(strip->m_faces[i]->m_v2); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// UpdateCacheFace() -// -// Updates the input vertex cache with this face's vertices -// -void NvStripifier::UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face) -{ - if (!vcache->InCache(face->m_v0)) - vcache->AddEntry(face->m_v0); - - if (!vcache->InCache(face->m_v1)) - vcache->AddEntry(face->m_v1); - - if (!vcache->InCache(face->m_v2)) - vcache->AddEntry(face->m_v2); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// CalcNumHitsStrip() -// -// returns the number of cache hits per face in the strip -// -float NvStripifier::CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip) -{ - int numHits = 0; - int numFaces = 0; - - for (int i = 0; i < strip->m_faces.size(); i++) - { - if (vcache->InCache(strip->m_faces[i]->m_v0)) - numHits++; - - if (vcache->InCache(strip->m_faces[i]->m_v1)) - numHits++; - - if (vcache->InCache(strip->m_faces[i]->m_v2)) - numHits++; - - numFaces++; - } - - return ((float)numHits / (float)numFaces); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// CalcNumHitsFace() -// -// returns the number of cache hits in the face -// -int NvStripifier::CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face) -{ - int numHits = 0; - - if (vcache->InCache(face->m_v0)) - numHits++; - - if (vcache->InCache(face->m_v1)) - numHits++; - - if (vcache->InCache(face->m_v2)) - numHits++; - - return numHits; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// NumNeighbors() -// -// Returns the number of neighbors that this face has -// -int NvStripifier::NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec) -{ - int numNeighbors = 0; - - if (FindOtherFace(edgeInfoVec, face->m_v0, face->m_v1, face) != NULL) - { - numNeighbors++; - } - - if (FindOtherFace(edgeInfoVec, face->m_v1, face->m_v2, face) != NULL) - { - numNeighbors++; - } - - if (FindOtherFace(edgeInfoVec, face->m_v2, face->m_v0, face) != NULL) - { - numNeighbors++; - } - - return numNeighbors; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// AvgStripSize() -// -// Finds the average strip size of the input _vector_ of strips -// -float NvStripifier::AvgStripSize(const NvStripInfoVec& strips) -{ - int sizeAccum = 0; - int numStrips = strips.size(); - for (int i = 0; i < numStrips; i++) - { - NvStripInfo* strip = strips[i]; - sizeAccum += strip->m_faces.size(); - } - return ((float)sizeAccum) / ((float)numStrips); -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// FindAllStrips() -// -// Does the stripification, puts output strips into _vector_ allStrips -// -// Works by setting runnning a number of experiments in different areas of the mesh, and -// accepting the one which results in the longest strips. It then accepts this, and moves -// on to a different area of the mesh. We try to jump around the mesh some, to ensure that -// large open spans of strips get generated. -// -void NvStripifier::FindAllStrips( - NvStripInfoVec& allStrips, NvFaceInfoVec& allFaceInfos, NvEdgeInfoVec& allEdgeInfos, int numSamples) -{ - // the experiments - int experimentId = 0; - int stripId = 0; - bool done = false; - - int loopCtr = 0; - - while (!done) - { - loopCtr++; - - // - // PHASE 1: Set up numSamples * numEdges experiments - // - xr_vector experiments; - experiments.resize(numSamples * 6); - int experimentIndex = 0; - xr_set resetPoints; - int i; - for (i = 0; i < numSamples; i++) - { - // Try to find another good reset point. - // If there are none to be found, we are done - NvFaceInfo* nextFace = FindGoodResetPoint(allFaceInfos, allEdgeInfos); - if (nextFace == NULL) - { - done = true; - break; - } - - // If we have already evaluated starting at this face in this slew - // of experiments, then skip going any further - else if (resetPoints.find(nextFace) != resetPoints.end()) - { - continue; - } - - // trying it now... - resetPoints.insert(nextFace); - - // otherwise, we shall now try experiments for starting on the 01,12, and 20 edges - assert(nextFace->m_stripId < 0); - - // build the strip off of this face's 0-1 edge - NvEdgeInfo* edge01 = FindEdgeInfo(allEdgeInfos, nextFace->m_v0, nextFace->m_v1); - NvStripInfo* strip01 = xr_new(NvStripStartInfo(nextFace, edge01, true), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip01); - - // build the strip off of this face's 1-0 edge - NvEdgeInfo* edge10 = FindEdgeInfo(allEdgeInfos, nextFace->m_v0, nextFace->m_v1); - NvStripInfo* strip10 = - xr_new(NvStripStartInfo(nextFace, edge10, false), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip10); - - // build the strip off of this face's 1-2 edge - NvEdgeInfo* edge12 = FindEdgeInfo(allEdgeInfos, nextFace->m_v1, nextFace->m_v2); - NvStripInfo* strip12 = xr_new(NvStripStartInfo(nextFace, edge12, true), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip12); - - // build the strip off of this face's 2-1 edge - NvEdgeInfo* edge21 = FindEdgeInfo(allEdgeInfos, nextFace->m_v1, nextFace->m_v2); - NvStripInfo* strip21 = - xr_new(NvStripStartInfo(nextFace, edge21, false), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip21); - - // build the strip off of this face's 2-0 edge - NvEdgeInfo* edge20 = FindEdgeInfo(allEdgeInfos, nextFace->m_v2, nextFace->m_v0); - NvStripInfo* strip20 = xr_new(NvStripStartInfo(nextFace, edge20, true), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip20); - - // build the strip off of this face's 0-2 edge - NvEdgeInfo* edge02 = FindEdgeInfo(allEdgeInfos, nextFace->m_v2, nextFace->m_v0); - NvStripInfo* strip02 = - xr_new(NvStripStartInfo(nextFace, edge02, false), stripId++, experimentId++); - experiments[experimentIndex++].push_back(strip02); - } - - // - // PHASE 2: Iterate through that we setup in the last phase - // and really build each of the strips and strips that follow to see how - // far we get - // - int numExperiments = experimentIndex; - for (i = 0; i < numExperiments; i++) - { - // get the strip set - - // build the first strip of the list - experiments[i][0]->Build(allEdgeInfos, allFaceInfos); - int experimentId = experiments[i][0]->m_experimentId; - - NvStripInfo* stripIter = experiments[i][0]; - NvStripStartInfo startInfo(NULL, NULL, false); - while (FindTraversal(allFaceInfos, allEdgeInfos, stripIter, startInfo)) - { - // create the _new strip info - stripIter = xr_new(startInfo, stripId++, experimentId); - - // build the next strip - stripIter->Build(allEdgeInfos, allFaceInfos); - - // add it to the list - experiments[i].push_back(stripIter); - } - } - - // - // Phase 3: Find the experiment that has the most promise - // - int bestIndex = 0; - float bestValue = 0; - for (i = 0; i < numExperiments; i++) - { - const float avgStripSizeWeight = 1.0f; - const float numTrisWeight = 1.0f; - float avgStripSize = AvgStripSize(experiments[i]); - float numStrips = (float)experiments[i].size(); - float value = avgStripSize * avgStripSizeWeight + (avgStripSize * numStrips * numTrisWeight); - - if (value > bestValue) - { - bestValue = value; - bestIndex = i; - } - } - - // - // Phase 4: commit the best experiment of the bunch - // - CommitStrips(allStrips, experiments[bestIndex]); - - // and destroy all of the others - for (i = 0; i < numExperiments; i++) - { - if (i != bestIndex) - { - int numStrips = experiments[i].size(); - for (int j = 0; j < numStrips; j++) - { - xr_delete(experiments[i][j]); - } - } - } - - // _delete the array that we used for all experiments - experiments.clear(); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// CountRemainingTris() -// -// This will count the number of triangles left in the -// strip list starting at iter and finishing up at end -// -int NvStripifier::CountRemainingTris(xr_list::iterator iter, xr_list::iterator end) -{ - int count = 0; - while (iter != end) - { - count += (*iter)->m_faces.size(); - ++iter; - } - return count; -} diff --git a/src/utils/xrLC/nv_library/NvTriStripObjects.h b/src/utils/xrLC/nv_library/NvTriStripObjects.h deleted file mode 100644 index b43171cbac1..00000000000 --- a/src/utils/xrLC/nv_library/NvTriStripObjects.h +++ /dev/null @@ -1,240 +0,0 @@ - -#ifndef NV_TRISTRIP_OBJECTS_H -#define NV_TRISTRIP_OBJECTS_H - -#include -#include "VertexCache.h" -#include "xrCommon/xr_vector.h" -#include "xrCommon/xr_list.h" - -///////////////////////////////////////////////////////////////////////////////// -// -// Types defined for stripification -// -///////////////////////////////////////////////////////////////////////////////// - -struct MyVertex -{ - float x, y, z; - float nx, ny, nz; -}; - -typedef MyVertex MyVector; - -struct MyFace -{ - int v1, v2, v3; - float nx, ny, nz; -}; - -class NvFaceInfo -{ -public: - // vertex indices - NvFaceInfo(int v0, int v1, int v2) - { - m_v0 = v0; - m_v1 = v1; - m_v2 = v2; - m_stripId = -1; - m_testStripId = -1; - m_experimentId = -1; - } - - // data members are left public - int m_v0, m_v1, m_v2; - int m_stripId; // real strip Id - int m_testStripId; // strip Id in an experiment - int m_experimentId; // in what experiment was it given an experiment Id? -}; - -// nice and dumb edge class that points knows its -// indices, the two faces, and the next edge using -// the lesser of the indices -class NvEdgeInfo -{ -public: - // constructor puts 1 ref on us - NvEdgeInfo(int v0, int v1) - { - m_v0 = v0; - m_v1 = v1; - m_face0 = NULL; - m_face1 = NULL; - m_nextV0 = NULL; - m_nextV1 = NULL; - - // we will appear in 2 lists. this is a good - // way to make sure we _delete it the second time - // we hit it in the edge infos - m_refCount = 2; - } - - // ref and unref - void Unref() - { - if (--m_refCount == 0) - { - auto self = this; - xr_delete(self); - } - } - - // data members are left public - u32 m_refCount; - NvFaceInfo *m_face0, *m_face1; - int m_v0, m_v1; - NvEdgeInfo *m_nextV0, *m_nextV1; -}; - -// This class is a quick summary of parameters used -// to begin a triangle strip. Some operations may -// want to create lists of such items, so they were -// pulled out into a class -class NvStripStartInfo -{ -public: - NvStripStartInfo(NvFaceInfo* startFace, NvEdgeInfo* startEdge, bool toV1) - { - m_startFace = startFace; - m_startEdge = startEdge; - m_toV1 = toV1; - } - NvFaceInfo* m_startFace; - NvEdgeInfo* m_startEdge; - bool m_toV1; -}; - -typedef xr_vector NvFaceInfoVec; -typedef xr_list NvFaceInfoList; -typedef xr_list NvStripList; -typedef xr_vector NvEdgeInfoVec; - -typedef xr_vector WordVec; -typedef xr_vector IntVec; -typedef xr_vector MyVertexVec; -typedef xr_vector MyFaceVec; - -template -inline void SWAP(T& first, T& second) -{ - T temp = first; - first = second; - second = temp; -} - -// This is a summary of a strip that has been built -class NvStripInfo -{ -public: - // A little information about the creation of the triangle strips - NvStripInfo(const NvStripStartInfo& startInfo, int stripId, int experimentId = -1) : m_startInfo(startInfo) - { - m_stripId = stripId; - m_experimentId = experimentId; - visited = false; - } - - // This is an experiment if the experiment id is >= 0 - inline bool IsExperiment() const { return m_experimentId >= 0; } - inline bool IsInStrip(const NvFaceInfo* faceInfo) const - { - if (faceInfo == NULL) - return false; - - return (m_experimentId >= 0 ? faceInfo->m_testStripId == m_stripId : faceInfo->m_stripId == m_stripId); - } - - bool SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec& edgeInfos); - - // take the given forward and backward strips and combine them together - void Combine(const NvFaceInfoVec& forward, const NvFaceInfoVec& backward); - - // returns true if the face is "unique", i.e. has a vertex which doesn't exist in the faceVec - bool Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face); - - // mark the triangle as taken by this strip - bool IsMarked(NvFaceInfo* faceInfo); - void MarkTriangle(NvFaceInfo* faceInfo); - - // build the strip - void Build(NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& faceInfos); - - // public data members - NvStripStartInfo m_startInfo; - NvFaceInfoVec m_faces; - int m_stripId; - int m_experimentId; - - bool visited; -}; - -typedef xr_vector NvStripInfoVec; - -// The actual stripifier -class NvStripifier -{ -public: - // Constructor - NvStripifier(); - ~NvStripifier(); - - // the target vertex cache size, the structure to place the strips in, and the input indices - void Stripify(const WordVec& in_indices, const int in_cacheSize, const int in_minStripLength, - NvStripInfoVec& allStrips, NvFaceInfoVec& allFaces); - void CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, - unsigned int& numSeparateStrips); - - static int GetUniqueVertexInB(NvFaceInfo* faceA, NvFaceInfo* faceB); - static int GetSharedVertex(NvFaceInfo* faceA, NvFaceInfo* faceB); - -protected: - WordVec indices; - int cacheSize; - int minStripLength; - float meshJump; - bool bFirstTimeResetPoint; - - ///////////////////////////////////////////////////////////////////////////////// - // - // Big mess of functions called during stripification - // - ///////////////////////////////////////////////////////////////////////////////// - - bool IsCW(NvFaceInfo* faceInfo, int v0, int v1); - bool NextIsCW(const int numIndices); - static int GetNextIndex(const WordVec& indices, NvFaceInfo* face); - static NvEdgeInfo* FindEdgeInfo(NvEdgeInfoVec& edgeInfos, int v0, int v1); - static NvFaceInfo* FindOtherFace(NvEdgeInfoVec& edgeInfos, int v0, int v1, NvFaceInfo* faceInfo); - NvFaceInfo* FindGoodResetPoint(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos); - - void FindAllStrips( - NvStripInfoVec& allStrips, NvFaceInfoVec& allFaceInfos, NvEdgeInfoVec& allEdgeInfos, int numSamples); - void SplitUpStripsAndOptimize( - NvStripInfoVec& allStrips, NvStripInfoVec& outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList); - void RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList); - - bool FindTraversal( - NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos, NvStripInfo* strip, NvStripStartInfo& startInfo); - int CountRemainingTris(xr_list::iterator iter, xr_list::iterator end); - - void CommitStrips(NvStripInfoVec& allStrips, const NvStripInfoVec& strips); - - float AvgStripSize(const NvStripInfoVec& strips); - int FindStartPoint(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos); - - void UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip); - void UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face); - float CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip); - int CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face); - int NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec); - - void BuildStripifyInfo(NvFaceInfoVec& faceInfos, NvEdgeInfoVec& edgeInfos); - bool AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos); - - // let our strip info classes and the other classes get - // to these protected stripificaton methods if they want - friend NvStripInfo; -}; - -#endif diff --git a/src/utils/xrLC/nv_library/VertexCache.cpp b/src/utils/xrLC/nv_library/VertexCache.cpp deleted file mode 100644 index 1a6221f9da5..00000000000 --- a/src/utils/xrLC/nv_library/VertexCache.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" -#include "VertexCache.h" - -VertexCache::VertexCache() : VertexCache(16) {} -VertexCache::VertexCache(int size) { entries.assign(size, -1); } -VertexCache::~VertexCache() { entries.clear(); } -int VertexCache::At(int index) { return entries[index]; } -void VertexCache::Set(int index, int value) { entries[index] = value; } -void VertexCache::Clear() -{ - for (u32 i = 0; i < entries.size(); i++) - entries[i] = -1; -} - -void VertexCache::Copy(VertexCache* inVcache) -{ - for (u32 i = 0; i < entries.size(); i++) - { - inVcache->Set(i, entries[i]); - } -} diff --git a/src/utils/xrLC/nv_library/VertexCache.h b/src/utils/xrLC/nv_library/VertexCache.h deleted file mode 100644 index 131ca5601ba..00000000000 --- a/src/utils/xrLC/nv_library/VertexCache.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef VERTEX_CACHE_H -#define VERTEX_CACHE_H - -class VertexCache -{ -public: - VertexCache(int size); - VertexCache(); - ~VertexCache(); - - bool InCache(int entry); - int AddEntry(int entry); - void Clear(); - - void Copy(VertexCache* inVcache); - int At(int index); - void Set(int index, int value); - -private: - xr_vector entries; -}; - -IC bool VertexCache::InCache(int entry) -{ - bool returnVal = false; - - for (u32 i = 0; i < entries.size(); i++) - { - if (entries[i] == entry) - { - returnVal = true; - break; - } - } - - return returnVal; -} - -IC int VertexCache::AddEntry(int entry) -{ - int removed; - - removed = entries[entries.size() - 1]; - - // push everything right one - for (int i = (u32)entries.size() - 2; i >= 0; i--) - { - entries[i + 1] = entries[i]; - } - - entries[0] = entry; - - return removed; -} - -#endif diff --git a/src/utils/xrLC/packages.config b/src/utils/xrLC/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/xrLC/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/xrLC/std_classes.h b/src/utils/xrLC/std_classes.h deleted file mode 100644 index 26e1cf9a28d..00000000000 --- a/src/utils/xrLC/std_classes.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "xrCore/clsid.h" - -//***** Standart extension classes -constexpr CLASS_ID CLSID_LEVEL = MK_CLSID('C', 'R', 'E', 'A', 'T', 'O', 'R', ' '); - -constexpr CLASS_ID CLSID_TEXTURE = MK_CLSID('T', 'E', 'X', 'T', 'U', 'R', 'E', ' '); -constexpr CLASS_ID CLSID_OBJECT = MK_CLSID('O', 'B', 'J', 'E', 'C', 'T', ' ', ' '); - -// Actor -constexpr CLASS_ID CLSID_OBJECT_ACTOR = MK_CLSID('O', '_', 'A', 'C', 'T', 'O', 'R', ' '); -constexpr CLASS_ID CLSID_OBJECT_ACTOR_NET = MK_CLSID('R', '_', 'A', 'C', 'T', 'O', 'R', ' '); -constexpr CLASS_ID CLSID_OBJECT_DUMMY = MK_CLSID('O', '_', 'D', 'U', 'M', 'M', 'Y', ' '); -constexpr CLASS_ID CLSID_ENTITY = MK_CLSID('E', 'N', 'T', 'I', 'T', 'Y', ' ', ' '); -constexpr CLASS_ID CLSID_AI_HUMAN = MK_CLSID('A', 'I', '_', 'H', 'U', 'M', 'A', 'N'); - -constexpr CLASS_ID CLSID_OBJECT_DACTOR = MK_CLSID('O', '_', 'D', 'E', 'M', 'O', ' ', ' '); - -constexpr CLASS_ID CLSID_EVENT = MK_CLSID('E', 'V', 'E', 'N', 'T', ' ', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_FLYER = MK_CLSID('O', '_', 'F', 'L', 'Y', 'E', 'R', ' '); -constexpr CLASS_ID CLSID_OBJECT_DOOR = MK_CLSID('O', '_', 'D', 'O', 'O', 'R', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_LIFT = MK_CLSID('O', '_', 'L', 'I', 'F', 'T', ' ', ' '); - -// Weapons -constexpr CLASS_ID CLSID_OBJECT_W_M134 = MK_CLSID('W', '_', 'M', '1', '3', '4', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_W_M134_en = MK_CLSID('W', '_', 'M', '1', '3', '4', 'e', 'n'); -constexpr CLASS_ID CLSID_OBJECT_W_GROZA = MK_CLSID('W', '_', 'G', 'R', 'O', 'Z', 'A', ' '); -constexpr CLASS_ID CLSID_OBJECT_W_PROTECTA = MK_CLSID('W', '_', 'P', 'R', 'O', 'T', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_W_RAIL = MK_CLSID('W', '_', 'R', 'A', 'I', 'L', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_W_ROCKET = MK_CLSID('W', '_', 'R', 'O', 'C', 'K', 'E', 'T'); - -// Weapons Ammo -constexpr CLASS_ID CLSID_OBJECT_A_M134 = MK_CLSID('A', '_', 'M', '1', '3', '4', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_A_GROZA = MK_CLSID('A', '_', 'G', 'R', 'O', 'Z', 'A', ' '); -constexpr CLASS_ID CLSID_OBJECT_A_PROTECTA = MK_CLSID('A', '_', 'P', 'R', 'O', 'T', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_A_RAIL = MK_CLSID('A', '_', 'R', 'A', 'I', 'L', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_A_ROCKET = MK_CLSID('A', '_', 'R', 'O', 'C', 'K', 'E', 'T'); - -// Modifiers -constexpr CLASS_ID CLSID_OBJECT_M_QDAMAGE = MK_CLSID('O', '_', 'Q', 'D', 'M', 'G', ' ', ' '); -constexpr CLASS_ID CLSID_OBJECT_M_IMMORTAL = MK_CLSID('O', '_', 'I', 'M', 'M', 'O', 'R', 'T'); -constexpr CLASS_ID CLSID_OBJECT_M_INVIS = MK_CLSID('O', '_', 'I', 'N', 'V', 'I', 'S', ' '); - -constexpr CLASS_ID CLSID_OBJECT_HEALTH = MK_CLSID('O', '_', 'H', 'E', 'A', 'L', 'T', 'H'); -constexpr CLASS_ID CLSID_OBJECT_ARMOR = MK_CLSID('O', '_', 'A', 'R', 'M', 'O', 'R', ' '); - -// Standart level object -constexpr CLASS_ID CLSID_OBJECT_ITEM_STD = MK_CLSID('O', '_', 'I', 'T', 'E', 'M', ' ', ' '); diff --git a/src/utils/xrLC/vbm.h b/src/utils/xrLC/vbm.h deleted file mode 100644 index 8ef91012820..00000000000 --- a/src/utils/xrLC/vbm.h +++ /dev/null @@ -1,207 +0,0 @@ -#pragma once - -#include "xrCore/FMesh.hpp" -#include "xrCore/fs.h" - -static const u32 c_VB_maxSize = 4096 * 1024; // bytes - -struct VDeclarator : public svector -{ - void set(u32 FVF) - { - D3DXDeclaratorFromFVF(FVF, begin()); - resize(D3DXGetDeclLength(begin()) + 1); - } - void set(const D3DVERTEXELEMENT9* dcl) - { - resize(D3DXGetDeclLength(dcl) + 1); - CopyMemory(begin(), dcl, size() * sizeof(D3DVERTEXELEMENT9)); - } - void set(const VDeclarator& d) - { - *this = d; - } - u32 vertex() - { - return D3DXGetDeclVertexSize(begin(), 0); - } - BOOL equal(VDeclarator& d) - { - if (size() != d.size()) - return false; - return 0 == memcmp(begin(), d.begin(), size() * sizeof(D3DVERTEXELEMENT9)); - } -}; - -// Vertex containers -class VBContainer -{ - xr_vector vDcl; - xr_vector> vContainers; - - // Recording - VDeclarator R_DCL; - xr_vector R_DATA; - -public: - // Constructor & destructor - VBContainer() { R_DCL.clear(); } - // Methods - bool is_empty() const { return vDcl.empty() && vContainers.empty() && R_DCL.empty() && R_DATA.empty(); } - void Begin(u32 dwFVF) - { - R_ASSERT(R_DCL.empty()); - R_ASSERT(R_DATA.empty()); - R_DCL.set(dwFVF); - } - void Begin(const VDeclarator& D) - { - R_ASSERT(R_DCL.empty()); - R_ASSERT(R_DATA.empty()); - R_DCL.set(D); - } - void Add(void* PTR, u32 cnt) - { - R_ASSERT(R_DCL.size()); - u8* P = (u8*)PTR; - R_DATA.insert(R_DATA.end(), P, P + cnt); - } - void End(u32* dwContainerID, u32* dwIndexStart) - { - R_ASSERT(!R_DCL.empty()); - R_ASSERT(!R_DATA.empty()); - - u32 dwSize = R_DCL.vertex(); - R_ASSERT(R_DATA.size() % dwSize == 0); - - // Search for container capable of handling data - u32 bytes_collected = (u32)R_DATA.size(); - u32 vertices_collected = bytes_collected / dwSize; - for (u32 CID = 0; CID < vDcl.size(); CID++) - { - if (!vDcl[CID].equal(R_DCL)) - continue; - - u32 bytes_already = (u32)vContainers[CID].size(); - if ((bytes_already + bytes_collected) > c_VB_maxSize) - continue; - u32 vertices_already = bytes_already / dwSize; - if ((vertices_already + vertices_collected) > c_VB_maxVertices) - continue; - - // If we get here - container CID can take the data - *dwContainerID = CID; - *dwIndexStart = vertices_already; - vContainers[CID].insert(vContainers[CID].end(), R_DATA.begin(), R_DATA.end()); - R_DCL.clear(); - R_DATA.clear(); - return; - } - - // No such format found - // Simple add it and register - *dwContainerID = (u32)vDcl.size(); - *dwIndexStart = 0; - vDcl.push_back(R_DCL); - R_DCL.clear(); - vContainers.push_back(R_DATA); - R_DATA.clear(); - } - void Save(IWriter& fs) - { - R_ASSERT(R_DCL.empty()); - R_ASSERT(R_DATA.empty()); - fs.w_u32((u32)vDcl.size()); - for (u32 i = 0; i < vDcl.size(); i++) - { - u32 dwOneSize = vDcl[i].vertex(); - u32 dwTotalSize = (u32)vContainers[i].size(); - u32 dwVertCount = dwTotalSize / dwOneSize; - - R_ASSERT(dwVertCount * dwOneSize == dwTotalSize); - - fs.w(vDcl[i].begin(), vDcl[i].size() * sizeof(D3DVERTEXELEMENT9)); // Vertex format - fs.w_u32(dwVertCount); // Number of vertices - fs.w(&*vContainers[i].begin(), dwTotalSize); - } - vDcl.clear(); - vContainers.clear(); - } -}; - -class IBContainer -{ - xr_vector> data; - enum - { - LIMIT = 1024ul * 1024ul - }; - -public: - bool is_empty() const { return data.empty(); } - void Register(u16* begin, u16* end, u32* dwContainerID, u32* dwStart) - { - u32 size = (u32)(end - begin); - - // - for (u32 ID = 0; ID < data.size(); ID++) - { - if ((data[ID].size() + size) < LIMIT) - { - *dwContainerID = ID; - *dwStart = (u32)data[ID].size(); - data[ID].insert(data[ID].end(), begin, end); - return; - } - } - - // Can't find suitable container - register new - *dwContainerID = (u32)data.size(); - *dwStart = 0; - data.push_back(xr_vector()); - data.back().assign(begin, end); - } - void Save(IWriter& fs) - { - fs.w_u32((u32)data.size()); - for (u32 i = 0; i < data.size(); i++) - { - fs.w_u32((u32)data[i].size()); - fs.w(&*data[i].begin(), (u32)data[i].size() * 2); - } - data.clear(); - } -}; - -class SWIContainer -{ - xr_vector data; - -public: - bool is_empty() const { return data.empty(); } - void Register(u32* id, FSlideWindowItem* item) - { - data.push_back(item); - *id = data.size() - 1; - } - void Save(IWriter& fs) - { - fs.w_u32((u32)data.size()); - for (u32 i = 0; i < data.size(); i++) - { - fs.w_u32((u32)data[i]->reserved[0]); - fs.w_u32((u32)data[i]->reserved[1]); - fs.w_u32((u32)data[i]->reserved[2]); - fs.w_u32((u32)data[i]->reserved[3]); - fs.w_u32((u32)data[i]->count); - fs.w(data[i]->sw, sizeof(FSlideWindow) * data[i]->count); - } - data.clear(); - } -}; - -extern VBContainer g_VB; - -extern SWIContainer g_SWI, x_SWI; -extern VBContainer g_VB, x_VB; -extern IBContainer g_IB, x_IB; diff --git a/src/utils/xrLC/xrBuildCForm.cpp b/src/utils/xrLC/xrBuildCForm.cpp deleted file mode 100644 index 1417fce7738..00000000000 --- a/src/utils/xrLC/xrBuildCForm.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include "stdafx.h" - -#include "build.h" -#include "utils/xrLC_Light/xrMU_Model.h" -#include "utils/xrLC_Light/xrMU_Model_Reference.h" - -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -#include "xrCore/fs.h" -#include "xrCDB/xrCDB.h" - -int GetVertexIndex(Vertex* F) -{ - vecVertexIt it = std::lower_bound(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end(), F); - - R_ASSERT(it != lc_global_data()->g_vertices().end()); - - return int(it - lc_global_data()->g_vertices().begin()); -} - -int getCFormVID(vecVertex& V, Vertex* F) -{ - vecVertexIt it = std::lower_bound(V.begin(), V.end(), F); - return int(it - V.begin()); -} -int bCriticalErrCnt = 0; -/* - -int getTriByEdge(Vertex *V1, Vertex *V2, Face* parent, vecFace &ids) -{ - Face* found = 0; - int f_count = 0; - - for (vecFaceIt I=V1->m_adjacents.begin(); I!=V1->m_adjacents.end(); ++I) - { - Face* test = *I; - if (test == parent) continue; - if (test->VContains(V2)) - { - ++f_count; - found = test; - } - } - if (f_count>1) - { - bCriticalErrCnt ++; - pBuild->err_multiedge.w_fvector3(V1->P); - pBuild->err_multiedge.w_fvector3(V2->P); - } - if (found) { - vecFaceIt F = std::lower_bound(ids.begin(),ids.end(),found); - if (found == *F) return int(F-ids.begin()); - else return -1; - } else { - return -1; - } -} -*/ -void TestEdge(Vertex* V1, Vertex* V2, Face* parent) -{ - Face* found = 0; - int f_count = 0; - - for (vecFaceIt I = V1->m_adjacents.begin(); I != V1->m_adjacents.end(); ++I) - { - Face* test = *I; - if (test == parent) - continue; - if (test->VContains(V2)) - { - ++f_count; - found = test; - } - } - if (f_count > 1) - { - ++bCriticalErrCnt; - pBuild->err_multiedge().w_fvector3(V1->P); - pBuild->err_multiedge().w_fvector3(V2->P); - } -} -extern void SimplifyCFORM(CDB::CollectorPacked& CL); -void CBuild::BuildCForm() -{ - // Collecting data - Logger.Phase("CFORM: creating..."); - vecFace* cfFaces = xr_new(); - vecVertex* cfVertices = xr_new(); - { - xr_vector cfVertexMarks; - cfVertexMarks.assign(lc_global_data()->g_vertices().size(), false); - - Logger.Status("Sorting..."); - std::sort(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end()); - - Logger.Status("Collecting faces..."); - cfFaces->reserve(lc_global_data()->g_faces().size()); - for (vecFaceIt I = lc_global_data()->g_faces().begin(); I != lc_global_data()->g_faces().end(); ++I) - { - Face* F = *I; - if (F->Shader().flags.bCollision) - { - cfFaces->push_back(F); - int index = GetVertexIndex(F->v[0]); - cfVertexMarks[index] = true; - - index = GetVertexIndex(F->v[1]); - cfVertexMarks[index] = true; - - index = GetVertexIndex(F->v[2]); - cfVertexMarks[index] = true; - } - } - - Logger.Status("Collecting vertices..."); - cfVertices->reserve(lc_global_data()->g_vertices().size()); - std::sort(cfFaces->begin(), cfFaces->end()); - for (u32 V = 0; V < lc_global_data()->g_vertices().size(); V++) - if (cfVertexMarks[V]) - cfVertices->push_back(lc_global_data()->g_vertices()[V]); - } - - float p_total = 0; - float p_cost = 1.f / (cfVertices->size()); - - Fbox BB; - BB.invalidate(); - for (vecVertexIt it = cfVertices->begin(); it != cfVertices->end(); ++it) - BB.modify((*it)->P); - - // CForm - Logger.Phase("CFORM: collision model..."); - Logger.Status("Items to process: %d", cfFaces->size()); - p_total = 0; - p_cost = 1.f / (cfFaces->size()); - - // Collect faces - CDB::CollectorPacked CL(BB, cfVertices->size(), cfFaces->size()); - for (vecFaceIt F = cfFaces->begin(); F != cfFaces->end(); ++F) - { - Face* T = *F; - - TestEdge(T->v[0], T->v[1], T); - TestEdge(T->v[1], T->v[2], T); - TestEdge(T->v[2], T->v[0], T); - - CL.add_face( - T->v[0]->P, T->v[1]->P, T->v[2]->P, T->dwMaterialGame, materials()[T->dwMaterial].sector, T->sm_group); - Logger.Progress(p_total += p_cost); // progress - } - if (bCriticalErrCnt) - { - err_save(); - Logger.clMsg("MultipleEdges: %d faces", bCriticalErrCnt); - } - xr_delete(cfFaces); - xr_delete(cfVertices); - - // Models - Logger.Status("Models..."); - for (u32 ref = 0; ref < mu_refs().size(); ref++) - mu_refs()[ref]->export_cform_game(CL); - - // Simplification - if (g_params().m_quality != ebqDraft) - SimplifyCFORM(CL); - - // bb? - BB.invalidate(); - for (size_t it = 0; it < CL.getVS(); it++) - BB.modify(CL.getV()[it]); - - // Saving - string_path fn; - IWriter* MFS = FS.w_open(strconcat(sizeof(fn), fn, pBuild->path, "level.cform")); - Logger.Status("Saving..."); - - // Header - hdrCFORM hdr; - hdr.version = CFORM_CURRENT_VERSION; - hdr.vertcount = (u32)CL.getVS(); - hdr.facecount = (u32)CL.getTS(); - hdr.aabb = BB; - MFS->w(&hdr, sizeof(hdr)); - - // Data - MFS->w(CL.getV(), (u32)CL.getVS() * sizeof(Fvector)); - MFS->w(CL.getT(), (u32)CL.getTS() * sizeof(CDB::TRI)); - - // Clear pDeflector (it is stored in the same memory space with dwMaterialGame) - for (vecFaceIt I = lc_global_data()->g_faces().begin(); I != lc_global_data()->g_faces().end(); ++I) - { - Face* F = *I; - F->pDeflector = NULL; - } - - FS.w_close(MFS); -} - -void CBuild::BuildPortals(IWriter& fs) -{ - fs.w_chunk(fsL_PORTALS, &*portals.begin(), portals.size() * sizeof(b_portal)); -} diff --git a/src/utils/xrLC/xrBuildRapidModel.cpp b/src/utils/xrLC/xrBuildRapidModel.cpp deleted file mode 100644 index b7e89947d20..00000000000 --- a/src/utils/xrLC/xrBuildRapidModel.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "stdafx.h" - -#include "build.h" -#include "utils/xrLC_Light/xrMU_Model.h" -#include "utils/xrLC_Light/xrMU_Model_Reference.h" - -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "xrCDB/xrCDB.h" -#include "utils/xrLC_Light/xrface.h" -#include "utils/xrLC_Light/base_face_ptr_storage.h" - -//.#include "communicate.h" - -CDB::MODEL* RCAST_Model = 0; - -IC bool FaceEqual(Face& F1, Face& F2) -{ - // Test for 6 variations - if ((F1.v[0] == F2.v[0]) && (F1.v[1] == F2.v[1]) && (F1.v[2] == F2.v[2])) - return true; - if ((F1.v[0] == F2.v[0]) && (F1.v[2] == F2.v[1]) && (F1.v[1] == F2.v[2])) - return true; - if ((F1.v[2] == F2.v[0]) && (F1.v[0] == F2.v[1]) && (F1.v[1] == F2.v[2])) - return true; - if ((F1.v[2] == F2.v[0]) && (F1.v[1] == F2.v[1]) && (F1.v[0] == F2.v[2])) - return true; - if ((F1.v[1] == F2.v[0]) && (F1.v[0] == F2.v[1]) && (F1.v[2] == F2.v[2])) - return true; - if ((F1.v[1] == F2.v[0]) && (F1.v[2] == F2.v[1]) && (F1.v[0] == F2.v[2])) - return true; - return false; -} - -void SaveUVM(LPCSTR fname, xr_vector& vm) -{ - IWriter* W = FS.w_open(fname); - string256 tmp; - // vertices - for (u32 v_idx = 0; v_idx < vm.size(); v_idx++) - { - b_rc_face& rcf = vm[v_idx]; - xr_sprintf(tmp, "f %d %d [%3.2f,%3.2f]-[%3.2f,%3.2f]-[%3.2f,%3.2f]", rcf.dwMaterial, rcf.dwMaterialGame, - rcf.t[0].x, rcf.t[0].y, rcf.t[1].x, rcf.t[1].y, rcf.t[2].x, rcf.t[2].y); - W->w_string(tmp); - } - FS.w_close(W); -} - -void CBuild::BuildRapid(BOOL bSaveForOtherCompilers) -{ - float p_total = 0; - float p_cost = 1.f / (lc_global_data()->g_faces().size()); - - lc_global_data()->destroy_rcmodel(); - Logger.Status("Converting faces..."); - for (u32 fit = 0; fit < lc_global_data()->g_faces().size(); fit++) - lc_global_data()->g_faces()[fit]->flags.bProcessed = false; - - xr_vector adjacent_vec; - adjacent_vec.reserve(6 * 2 * 3); - - CDB::CollectorPacked CL(scene_bb, lc_global_data()->g_vertices().size(), lc_global_data()->g_faces().size()); - - for (vecFaceIt it = lc_global_data()->g_faces().begin(); it != lc_global_data()->g_faces().end(); ++it) - { - Face* F = (*it); - const Shader_xrLC& SH = F->Shader(); - if (!SH.flags.bLIGHT_CastShadow) - continue; - - Logger.Progress(float(it - lc_global_data()->g_faces().begin()) / float(lc_global_data()->g_faces().size())); - - // Collect - adjacent_vec.clear(); - for (int vit = 0; vit < 3; ++vit) - { - Vertex* V = F->v[vit]; - for (u32 adj = 0; adj < V->m_adjacents.size(); adj++) - { - adjacent_vec.push_back(V->m_adjacents[adj]); - } - } - std::sort(adjacent_vec.begin(), adjacent_vec.end()); - adjacent_vec.erase(std::unique(adjacent_vec.begin(), adjacent_vec.end()), adjacent_vec.end()); - - // Unique - BOOL bAlready = FALSE; - for (u32 ait = 0; ait < adjacent_vec.size(); ++ait) - { - Face* Test = adjacent_vec[ait]; - if (Test == F) - continue; - if (!Test->flags.bProcessed) - continue; - if (FaceEqual(*F, *Test)) - { - bAlready = TRUE; - break; - } - } - - // - if (!bAlready) - { - F->flags.bProcessed = true; - CL.add_face_D(F->v[0]->P, F->v[1]->P, F->v[2]->P, *((u32*)&F), F->sm_group); - } - } - - /* - clMsg ("Faces: original(%d), model(%d), ratio(%f)", - g_faces.size(),CL.getTS(),float(CL.getTS())/float(g_faces.size())); - */ - - // Export references - if (bSaveForOtherCompilers) - Logger.Phase("Building rcast-CFORM-mu model..."); - Logger.Status("Models..."); - for (u32 ref = 0; ref < mu_refs().size(); ref++) - mu_refs()[ref]->export_cform_rcast(CL); - - // "Building tree.. - Logger.Status("Building search tree..."); - lc_global_data()->create_rcmodel(CL); - - extern void SaveAsSMF(LPCSTR fname, CDB::CollectorPacked & CL); - - // save source SMF - string_path fn; - - bool keep_temp_files = !!strstr(Core.Params, "-keep_temp_files"); - if (g_params().m_quality != ebqDraft) - { - if (keep_temp_files) - SaveAsSMF(strconcat(sizeof(fn), fn, pBuild->path, "build_cform_source.smf"), CL); - } - - // Saving for AI/DO usage - if (bSaveForOtherCompilers) - { - Logger.Status("Saving..."); - string_path fn; - - IWriter* MFS = FS.w_open(strconcat(sizeof(fn), fn, pBuild->path, "build.cform")); - xr_vector rc_faces; - rc_faces.resize(CL.getTS()); - // Prepare faces - for (u32 k = 0; k < CL.getTS(); k++) - { - CDB::TRI& T = CL.getT(k); - base_Face* F = get_base_face_pointer(T); - b_rc_face& cf = rc_faces[k]; - cf.dwMaterial = F->dwMaterial; - cf.dwMaterialGame = F->dwMaterialGame; - Fvector2* cuv = F->getTC0(); - cf.t[0].set(cuv[0]); - cf.t[1].set(cuv[1]); - cf.t[2].set(cuv[2]); - } - if (g_params().m_quality != ebqDraft) - { - if (keep_temp_files) - SaveUVM(strconcat(sizeof(fn), fn, pBuild->path, "build_cform_source.uvm"), rc_faces); - } - - MFS->open_chunk(0); - - // Header - hdrCFORM hdr; - hdr.version = CFORM_CURRENT_VERSION; - hdr.vertcount = (u32)CL.getVS(); - hdr.facecount = (u32)CL.getTS(); - hdr.aabb = scene_bb; - MFS->w(&hdr, sizeof(hdr)); - - // Data - MFS->w(CL.getV(), (u32)CL.getVS() * sizeof(Fvector)); - MFS->w(CL.getT(), (u32)CL.getTS() * sizeof(CDB::TRI)); - MFS->close_chunk(); - - MFS->open_chunk(1); - MFS->w(&*rc_faces.begin(), (u32)rc_faces.size() * sizeof(b_rc_face)); - MFS->close_chunk(); - } -} diff --git a/src/utils/xrLC/xrCalcNormals.cpp b/src/utils/xrLC/xrCalcNormals.cpp deleted file mode 100644 index 5267e9ac207..00000000000 --- a/src/utils/xrLC/xrCalcNormals.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "utils/xrLC_Light/xrface.h" -#include "utils/xrLC_Light/calculate_normals.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" - -// void -// Performs simple cross-smooth - -void CBuild::CalcNormals() -{ - calculate_normals::calc_normals(lc_global_data()->g_vertices(), lc_global_data()->g_faces()); - // Models - Logger.Status("Models..."); - MU_ModelsCalculateNormals(); -} diff --git a/src/utils/xrLC/xrFlex2OGF.cpp b/src/utils/xrLC/xrFlex2OGF.cpp deleted file mode 100644 index 24f8219335e..00000000000 --- a/src/utils/xrLC/xrFlex2OGF.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "OGF_Face.h" -#include "vbm.h" -#include "utils/xrLC_Light/lightmap.h" -#include "utils/xrLC_Light/xrface.h" - -#define TRY(a)\ - try\ - {\ - a;\ - }\ - catch (...)\ - {\ - Logger.clMsg("* E: %s", #a);\ - } - -void CBuild::validate_splits() -{ - for (splitIt it = g_XSplit.begin(); it != g_XSplit.end(); ++it) - { - u32 MODEL_ID = u32(it - g_XSplit.begin()); - if ((*it)->size() > c_SS_HighVertLimit * 2) - { - Logger.clMsg( - "! ERROR: subdiv #%d has more than %d faces (%d)", MODEL_ID, 2 * c_SS_HighVertLimit, (*it)->size()); - } - }; -} - -void Face2OGF_Vertices(const Face& FF, OGF_Vertex V[3]) -{ - for (u32 fv = 0; fv < 3; fv++) - { - V[fv].P.set(FF.v[fv]->P); - V[fv].N.set(FF.v[fv]->N); - V[fv].T = FF.basis_tangent[fv]; - V[fv].B = FF.basis_binormal[fv]; - V[fv].Color = FF.v[fv]->C; - } - - // Normal order - svector<_TCF, 2>::const_iterator TC = FF.tc.cbegin(); - for (; TC != FF.tc.cend(); TC++) - { - V[0].UV.push_back(TC->uv[0]); - V[1].UV.push_back(TC->uv[1]); - V[2].UV.push_back(TC->uv[2]); - } -} - -void OGF_AddFace(OGF& ogf, const Face& FF, bool _tc_) -{ - OGF_Vertex V[3]; - // Geometry - Face2OGF_Vertices(FF, V); - // build face - TRY(ogf._BuildFace(V[0], V[1], V[2], _tc_)); - V[0].UV.clear(); - V[1].UV.clear(); - V[2].UV.clear(); -} - -void BuildOGFGeom(OGF& ogf, const vecFace& faces, bool _tc_) -{ - for (vecFaceCit Fit = faces.begin(); Fit != faces.end(); ++Fit) - { - Face* FF = *Fit; - R_ASSERT(FF); - OGF_AddFace(ogf, *FF, _tc_); - } -} - -void CBuild::Flex2OGF() -{ - float p_total = 0; - float p_cost = 1 / float(g_XSplit.size()); - - validate_splits(); - - g_tree.clear(); - g_tree.reserve(4096); - for (splitIt it = g_XSplit.begin(); it != g_XSplit.end(); ++it) - { - R_ASSERT(!(*it)->empty()); - - u32 MODEL_ID = u32(it - g_XSplit.begin()); - - OGF* pOGF = xr_new(); - Face* F = *((*it)->begin()); // first face - b_material* M = &(materials()[F->dwMaterial]); // and it's material - R_ASSERT(F && M); - - try - { - // Common data - pOGF->Sector = M->sector; - pOGF->material = F->dwMaterial; - - // Collect textures - OGF_Texture T; - // pOGF->shader = M->shader; - // pOGF->shader_xrlc = &F->Shader(); - - TRY(T.name = textures()[M->surfidx].name); - TRY(T.pBuildSurface = &(textures()[M->surfidx])); - TRY(pOGF->textures.push_back(T)); - - try - { - if (F->hasImplicitLighting()) - { - // specific lmap - string_path tn; - strconcat(sizeof(tn), tn, *T.name, "_lm.dds"); - T.name = tn; - T.pBuildSurface = T.pBuildSurface; // Leave surface intact - R_ASSERT(pOGF); - pOGF->textures.push_back(T); - } - else - { - // If lightmaps persist - CLightmap* LM = F->lmap_layer; - if (LM) - { - string_path fn; - xr_sprintf(fn, "%s_1", LM->lm_texture.name); - T.name = fn; - T.pBuildSurface = &(LM->lm_texture); - R_ASSERT(T.pBuildSurface); - R_ASSERT(pOGF); - pOGF->textures.push_back(T); //. - xr_sprintf(fn, "%s_2", LM->lm_texture.name); - T.name = fn; - pOGF->textures.push_back(T); - } - } - } - catch (...) - { - Logger.clMsg("* ERROR: Flex2OGF, model# %d, *textures*", MODEL_ID); - } - - // Collect faces & vertices - F->CacheOpacity(); - bool _tc_ = !(F->flags.bOpaque); - try - { - BuildOGFGeom(*pOGF, *(*it), _tc_); - } - catch (...) - { - Logger.clMsg("* ERROR: Flex2OGF, model# %d, *faces*", MODEL_ID); - } - } - catch (...) - { - Logger.clMsg("* ERROR: Flex2OGF, 1st part, model# %d", MODEL_ID); - } - - try - { - Logger.clMsg("%3d: opt : v(%d)-f(%d)", MODEL_ID, pOGF->data.vertices.size(), pOGF->data.faces.size()); - pOGF->Optimize(); - Logger.clMsg("%3d: cb : v(%d)-f(%d)", MODEL_ID, pOGF->data.vertices.size(), pOGF->data.faces.size()); - pOGF->CalcBounds(); - Logger.clMsg("%3d: prog: v(%d)-f(%d)", MODEL_ID, pOGF->data.vertices.size(), pOGF->data.faces.size()); - if (!g_build_options.b_noise) - pOGF->MakeProgressive(c_PM_MetricLimit_static); - Logger.clMsg("%3d: strp: v(%d)-f(%d)", MODEL_ID, pOGF->data.vertices.size(), pOGF->data.faces.size()); - pOGF->Stripify(); - } - catch (...) - { - Logger.clMsg("* ERROR: Flex2OGF, 2nd part, model# %d", MODEL_ID); - } - - g_tree.push_back(pOGF); - xr_delete(*it); - Logger.Progress(p_total += p_cost); - } - g_XSplit.clear(); -} diff --git a/src/utils/xrLC/xrGameMaterials.h b/src/utils/xrLC/xrGameMaterials.h deleted file mode 100644 index d6306cd89ad..00000000000 --- a/src/utils/xrLC/xrGameMaterials.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _XR_GAME_MATERIALS_ -#define _XR_GAME_MATERIALS_ -#pragma once - -enum EGameMaterial -{ - gm_Wood, - gm_Stone, - gm_Metal, - - gm_Sand, -}; - -class Material -{ - float transparency_for_sound; - float transparency_for_hit; - -public: - virtual u32 getID() = 0; - virtual LPCSTR getName() = 0; - virtual LPCSTR getWallmark(Material* other) = 0; - virtual LPCSTR getParticles(Material* other) = 0; - virtual LPCSTR getSoundHIT(Material* other) = 0; - virtual LPCSTR getSoundSTEP(Material* other) = 0; - virtual float getFriction(Material* other) = 0; -}; - -#endif diff --git a/src/utils/xrLC/xrLC.cpp b/src/utils/xrLC/xrLC.cpp deleted file mode 100644 index 899d32c4292..00000000000 --- a/src/utils/xrLC/xrLC.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// xrLC.cpp : Defines the entry point for the application. -// -#include "stdafx.h" -#include -#include "math.h" -#include "build.h" -#include "Common/FSMacros.hpp" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "xrCore/ModuleLookup.hpp" - -CBuild* pBuild = nullptr; -u32 version = 0; - -static pcstr h_str = - "The following keys are supported / required:\n" - "-? or -h == this help\n" - "-o == modify build options\n" - "-nosun == disable sun-lighting\n" - "-skipinvalid == skip invalid faces\n" - "-f == compile level in GameData\\Levels\\\\\n" - "\n" - "NOTE: The last key is required for any functionality\n"; - -void Help() { MessageBox(nullptr, h_str, "Command line options", MB_OK | MB_ICONINFORMATION); } -typedef int __cdecl xrOptions(b_params* params, u32 version, bool bRunBuild); - -void Startup(pstr lpCmdLine) -{ - create_global_data(); - string512 cmd; - BOOL bModifyOptions = FALSE; - - xr_strcpy(cmd, lpCmdLine); - xr_strlwr(cmd); - if (strstr(cmd, "-?") || strstr(cmd, "-h")) - { - Help(); - return; - } - if (strstr(cmd, "-f") == 0) - { - Help(); - return; - } - if (strstr(cmd, "-o")) - bModifyOptions = TRUE; - if (strstr(cmd, "-gi")) - g_build_options.b_radiosity = TRUE; - if (strstr(cmd, "-noise")) - g_build_options.b_noise = TRUE; - if (strstr(cmd, "-net")) - g_build_options.b_net_light = TRUE; - if (strstr(cmd, "-skipinvalid")) - g_build_options.b_skipinvalid = TRUE; - VERIFY(lc_global_data()); - lc_global_data()->b_nosun_set(!!strstr(cmd, "-nosun")); - // if (strstr(cmd,"-nosun")) b_nosun = TRUE; - char name[256]; - *name = 0; - sscanf(strstr(cmd, "-f") + 2, "%s", name); - string256 temp; - xr_sprintf(temp, "%s - Levels Compiler", name); - Logger.Initialize(temp); - // Faster FPU - SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); - // Load project - string_path prjName; - FS.update_path(prjName, "$game_levels$", strconcat(sizeof(prjName), prjName, name, "\\build.prj")); - string256 phaseName; - Logger.Phase(strconcat(sizeof(phaseName), phaseName, "Reading project [", name, "]...")); - - string256 inf; - IReader* F = FS.r_open(prjName); - if (nullptr == F) - { - xr_sprintf(inf, "Build failed!\nCan't find level: '%s'", name); - Logger.clMsg(inf); - Logger.Failure(inf); - Logger.Destroy(); - return; - } - - // Version - F->r_chunk(EB_Version, &version); - Logger.clMsg("version: %d", version); - R_ASSERT(XRCL_CURRENT_VERSION == version); - - // Header - b_params Params; - F->r_chunk(EB_Parameters, &Params); - - // Show options if needed - if (bModifyOptions) - { - Logger.Phase("Project options..."); - const auto L = XRay::LoadModule("xrLC_Options"); - - const auto O = (xrOptions*)L->GetProcAddress("_frmScenePropertiesRun"); - R_ASSERT(O); - - const int R = O(&Params, version, false); - if (R == 2) - { - ExitProcess(0); - } - } - - // Conversion - Logger.Phase("Converting data structures..."); - pBuild = xr_new(); - pBuild->Load(Params, *F); - FS.r_close(F); - - // Call for builder - string_path lfn; - CTimer dwStartupTime; - dwStartupTime.Start(); - FS.update_path(lfn, _game_levels_, name); - pBuild->Run(lfn); - xr_delete(pBuild); - - // Show statistic - u32 dwEndTime = dwStartupTime.GetElapsed_ms(); - xr_sprintf(inf, "Time elapsed: %s", make_time(dwEndTime / 1000).c_str()); - Logger.clMsg("Build succesful!\n%s", inf); - if (!strstr(cmd, "-silent")) - Logger.Success(inf); - Logger.Destroy(); -} - -int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - // Initialize debugging - xrDebug::Initialize(lpCmdLine); - Core.Initialize("xrLC"); - - if (strstr(Core.Params, "-nosmg")) - g_using_smooth_groups = false; - - Startup(lpCmdLine); - - Core._destroy(); - - return 0; -} diff --git a/src/utils/xrLC/xrLC.vcxproj b/src/utils/xrLC/xrLC.vcxproj deleted file mode 100644 index 2a4448525a0..00000000000 --- a/src/utils/xrLC/xrLC.vcxproj +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - - {A4ABD75E-825B-4D09-B3B2-2709682E40C8} - - - - - - - Application - false - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - /Gs %(AdditionalOptions) - $(SolutionDir)utils\xrQSlim;$(xrSdkDir)include\FreeImage;$(xrExternals)FreeMagic\Include;%(AdditionalIncludeDirectories) - LEVEL_COMPILER;_USE_MATH_DEFINES;%(PreprocessorDefinitions) - FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - false - - - 2097152 - FreeImage.lib;FreeImagePlus.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(IntDir)%(Filename)1.obj - $(IntDir)%(Filename)1.xdc - - - - - - - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - true - true - true - true - - - - - - - - - - - - - - - - - - {848e8ab3-9962-4c04-b813-5690399c8a3e} - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {65cbb9d0-fbc6-41a4-8316-f5e9b5d7fb33} - - - {b90bdc22-a891-4b33-b562-29d701f65dbd} - - - {efb76d6f-0092-439c-a783-c0be10bd17c9} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - {f1836ce2-59ef-4189-8b9c-d103a511cb27} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/xrLC/xrLC.vcxproj.filters b/src/utils/xrLC/xrLC.vcxproj.filters deleted file mode 100644 index d014485954d..00000000000 --- a/src/utils/xrLC/xrLC.vcxproj.filters +++ /dev/null @@ -1,277 +0,0 @@ - - - - - {3bc7a018-84af-45eb-9bd5-418f1a2b16e6} - - - {1d0904ab-498b-4e38-ab15-361bdfb2b290} - - - {fcbc910c-d613-450b-9f97-266f3deb824f} - - - {6c295aee-813d-4496-9c29-2362327d4e30} - - - {686451bd-e786-4c36-97d5-1fd977ebfc84} - - - {e9c22bda-7cc7-419d-9bf5-feca32af1ea8} - - - {0f03c02c-9ade-4686-b7ea-1341967f8545} - - - {45ad24b8-e104-47e0-b68c-7620c470785b} - - - {f2a35b4d-9391-4ae4-8f32-eba30b42724e} - - - {25a71a9a-faca-4cac-a39b-279adf8b628e} - - - {9f5263c4-141b-47e2-a9f8-645d8dc4c93f} - - - {d3474647-ef89-48bf-a7de-5bbb8dabdad8} - - - - - Kernel - - - External - - - External - - - External - - - External - - - External\NV_Strips - - - External\NV_Strips - - - External\NV_Strips - - - External\NV_Mender2003 - - - External\NV_Mender2003 - - - External\NV_Mender2003 - - - External\NV_Mender2003 - - - External\NV_Mender2002 - - - External\NV_Mender2002\NV_Basis - - - External\NV_Mender2002\NV_Basis - - - External\NV_Mender2002\NV_Basis - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\Internal - - - %2a%2a%2a COMPILER %2a%2a%2a\net - - - - %2a%2a%2a COMPILER %2a%2a%2a - - - External - - - - - Kernel - - - Kernel - - - External\NV_Strips - - - External\NV_Strips - - - External\NV_Strips - - - External\NV_Mender2003 - - - External\NV_Mender2002 - - - External\NV_Mender2002\NV_Basis - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\XRAY - - - %2a%2a%2a COMPILER %2a%2a%2a\Model - - - %2a%2a%2a COMPILER %2a%2a%2a\Model - - - %2a%2a%2a COMPILER %2a%2a%2a\Model - - - %2a%2a%2a COMPILER %2a%2a%2a\net - - - %2a%2a%2a COMPILER %2a%2a%2a\net - - - External - - - %2a%2a%2a COMPILER %2a%2a%2a - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrLC/xrLight.cpp b/src/utils/xrLC/xrLight.cpp deleted file mode 100644 index 0983ab87755..00000000000 --- a/src/utils/xrLC/xrLight.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include - -#include "utils/xrLC_Light/xrdeflector.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrLightVertex.h" - -#include "xrCore/Threading/Lock.hpp" -#include "net.h" - -#include "utils/xrLC_Light/lcnet_task_manager.h" -#include "utils/xrLC_Light/mu_model_light.h" -Lock task_CS -#ifdef CONFIG_PROFILE_LOCKS - (MUTEX_PROFILE_ID(task_C_S)) -#endif // CONFIG_PROFILE_LOCKS - ; - -xr_vector task_pool; - -class CLMThread : public CThread -{ -private: - HASH H; - CDB::COLLIDER DB; - base_lighting LightsSelected; - -public: - CLMThread(u32 ID) : CThread(ID, ProxyMsg) - { - // thMonitor= TRUE; - thMessages = FALSE; - } - - virtual void Execute() - { - CDeflector* D = 0; - - for (;;) - { - // Get task - task_CS.Enter(); - thProgress = 1.f - float(task_pool.size()) / float(lc_global_data()->g_deflectors().size()); - if (task_pool.empty()) - { - task_CS.Leave(); - return; - } - - D = lc_global_data()->g_deflectors()[task_pool.back()]; - task_pool.pop_back(); - task_CS.Leave(); - - // Perform operation - try - { - D->Light(&DB, &LightsSelected, H); - } - catch (...) - { - Logger.clMsg("* ERROR: CLMThread::Execute - light"); - } - } - } -}; - -void CBuild::LMapsLocal() -{ - FPU::m64r(); - - mem_Compact(); - -// Randomize deflectors -#ifndef NET_CMP - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(lc_global_data()->g_deflectors().begin(), lc_global_data()->g_deflectors().end(), g); -#endif - -#ifndef NET_CMP - for (u32 dit = 0; dit < lc_global_data()->g_deflectors().size(); dit++) - task_pool.push_back(dit); -#else - task_pool.push_back(14); - task_pool.push_back(16); -#endif - - // Main process (4 threads) - Logger.Status("Lighting..."); - CThreadManager threads(ProxyStatus, ProxyProgress); - CTimer start_time; - start_time.Start(); - for (int L = 0; L < NUM_THREADS; L++) - threads.start(xr_new(L)); - threads.wait(500); - Logger.clMsg("%f seconds", start_time.GetElapsed_sec()); -} - -void CBuild::LMaps() -{ - //****************************************** Lmaps - Logger.Phase("LIGHT: LMaps..."); -// DeflectorsStats (); -#ifndef NET_CMP - if (g_build_options.b_net_light) - - // net_light (); - lc_net::net_lightmaps(); - else - { - LMapsLocal(); - } -#else - create_net_task_manager(); - get_net_task_manager()->create_global_data_write(pBuild->path); - LMapsLocal(); - get_net_task_manager()->run(); - destroy_net_task_manager(); -// net_light (); -#endif -} -void XRLC_LIGHT_API ImplicitNetWait(); -void CBuild::Light() -{ - //****************************************** Implicit - { - FPU::m64r(); - Logger.Phase("LIGHT: Implicit..."); - mem_Compact(); - ImplicitLighting(); - } - - LMaps(); - - //****************************************** Vertex - FPU::m64r(); - Logger.Phase("LIGHT: Vertex..."); - mem_Compact(); - - LightVertex(); - - // - - ImplicitNetWait(); - WaitMuModelsLocalCalcLightening(); - lc_net::get_task_manager().wait_all(); - // get_task_manager().wait_all(); - lc_net::get_task_manager().release(); - // - //****************************************** Merge LMAPS - { - FPU::m64r(); - Logger.Phase("LIGHT: Merging lightmaps..."); - mem_Compact(); - - xrPhase_MergeLM(); - } -} - -void CBuild::LightVertex() { ::LightVertex(!!g_build_options.b_net_light); } diff --git a/src/utils/xrLC/xrMU_Model_Calc_ogf.cpp b/src/utils/xrLC/xrMU_Model_Calc_ogf.cpp deleted file mode 100644 index 39f1798b4c2..00000000000 --- a/src/utils/xrLC/xrMU_Model_Calc_ogf.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "stdafx.h" -#include "utils/xrLC_Light/xrMU_Model.h" -#include "OGF_Face.h" -#include "build.h" - -#define TRY(a)\ - try\ - {\ - a;\ - }\ - catch (...)\ - {\ - Logger.clMsg("* E: %s", #a);\ - } - -void MModel_face2OGF_Vertices(const _face& FF, OGF_Vertex V[3], const xrMU_Model& model) -{ - for (u32 k = 0; k < 3; k++) - { - _vertex* _V = FF.v[k]; - u32 id = (u32)(std::find(model.m_vertices.begin(), model.m_vertices.end(), _V) - model.m_vertices.begin()); - V[k].P = _V->P; - V[k].N = _V->N; - V[k].Color = model.color[id]; - V[k].T.set(0, 0, 0); - V[k].B.set(0, 0, 0); - V[k].UV.push_back(FF.tc[k]); - } -} - -void OGF_AddFace(OGF& ogf, const _face& FF, const xrMU_Model& model) -{ - OGF_Vertex V[3]; - - MModel_face2OGF_Vertices(FF, V, model); - // build face - TRY(ogf._BuildFace(V[0], V[1], V[2])); - V[0].UV.clear(); - V[1].UV.clear(); - V[2].UV.clear(); -} - -void calc_ogf(xrMU_Model& mu_model) -{ - // Build OGFs - for (xrMU_Model::v_subdivs_it it = mu_model.m_subdivs.begin(); it != mu_model.m_subdivs.end(); ++it) - { - OGF* pOGF = xr_new(); - b_material* M = &(pBuild->materials()[it->material]); // and it's material - R_ASSERT(M); - - try - { - // Common data - pOGF->Sector = 0; - pOGF->material = it->material; - - // Collect textures - OGF_Texture T; - TRY(T.name = pBuild->textures()[M->surfidx].name); - TRY(T.pBuildSurface = &(pBuild->textures()[M->surfidx])); - TRY(pOGF->textures.push_back(T)); - - // Collect faces & vertices - try - { - xrMU_Model::v_faces_it _beg = mu_model.m_faces.begin() + it->start; - xrMU_Model::v_faces_it _end = _beg + it->count; - for (xrMU_Model::v_faces_it Fit = _beg; Fit != _end; ++Fit) - { - _face* FF = *Fit; - R_ASSERT(FF); - OGF_AddFace(*pOGF, *FF, mu_model); - } - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, model %s, *faces*", *(mu_model.m_name)); - } - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, 1st part, model %s", *(mu_model.m_name)); - } - try - { - pOGF->Optimize(); - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, [optimize], model %s", *(mu_model.m_name)); - } - try - { - pOGF->CalcBounds(); - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, [bounds], model %s", *(mu_model.m_name)); - } - try - { - pOGF->CalculateTB(); - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, [calc_tb], model %s", *(mu_model.m_name)); - } - try - { - pOGF->MakeProgressive(c_PM_MetricLimit_mu); - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, [progressive], model %s", *(mu_model.m_name)); - } - try - { - pOGF->Stripify(); - } - catch (...) - { - Logger.clMsg("* ERROR: MU2OGF, [stripify], model %s", *(mu_model.m_name)); - } - it->ogf = pOGF; - } -} diff --git a/src/utils/xrLC/xrMU_Model_export_OGF.cpp b/src/utils/xrLC/xrMU_Model_export_OGF.cpp deleted file mode 100644 index 7b10bf36a10..00000000000 --- a/src/utils/xrLC/xrMU_Model_export_OGF.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "stdafx.h" - -#include "utils/xrLC_Light/xrMU_Model.h" -#include "utils/xrLC_Light/xrMU_Model_Reference.h" - -#include "build.h" -#include "OGF_Face.h" - -#define TRY(a)\ - try\ - {\ - a;\ - }\ - catch (...)\ - {\ - Logger.clMsg("* E: %s", #a);\ - } - -void export_ogf(xrMU_Reference& mu_reference) -{ - xr_vector generated_ids; - xrMU_Model* model = mu_reference.model; - // Export nodes - { - for (xrMU_Model::v_subdivs_it it = model->m_subdivs.begin(); it != model->m_subdivs.end(); ++it) - { - OGF_Reference* pOGF = xr_new(); - b_material* M = &(pBuild->materials()[it->material]); // and it's material - R_ASSERT(M); - - // Common data - pOGF->Sector = mu_reference.sector; - pOGF->material = it->material; - - // Collect textures - OGF_Texture T; - TRY(T.name = pBuild->textures()[M->surfidx].name); - TRY(T.pBuildSurface = &(pBuild->textures()[M->surfidx])); - TRY(pOGF->textures.push_back(T)); - - // Special - pOGF->model = it->ogf; - pOGF->vb_id = it->vb_id; - pOGF->vb_start = it->vb_start; - pOGF->ib_id = it->ib_id; - pOGF->ib_start = it->ib_start; - pOGF->xform.set(mu_reference.xform); - pOGF->c_scale = mu_reference.c_scale; - pOGF->c_bias = mu_reference.c_bias; - pOGF->sw_id = it->sw_id; - - pOGF->CalcBounds(); - generated_ids.push_back((u32)g_tree.size()); - g_tree.push_back(pOGF); - } - } - - // Now, let's fuck with LODs - if (u16(-1) == model->m_lod_ID) - return; - { - // Create Node and fill it with information - b_lod& LOD = pBuild->lods[model->m_lod_ID]; - OGF_LOD* pNode = xr_new(1, mu_reference.sector); - pNode->lod_Material = LOD.dwMaterial; - for (int lf = 0; lf < 8; lf++) - { - b_lod_face& F = LOD.faces[lf]; - OGF_LOD::_face& D = pNode->lod_faces[lf]; - for (int lv = 0; lv < 4; lv++) - { - mu_reference.xform.transform_tiny(D.v[lv].v, F.v[lv]); - D.v[lv].t = F.t[lv]; - D.v[lv].c_rgb_hemi = 0xffffffff; - D.v[lv].c_sun = 0xff; - } - } - - // Add all 'OGFs' with such LOD-id - for (u32 o = 0; o < generated_ids.size(); o++) - pNode->AddChield(generated_ids[o]); - - // Register node - R_ASSERT(pNode->chields.size()); - pNode->CalcBounds(); - g_tree.push_back(pNode); - - // Calculate colors - const float sm_range = 5.f; - for (int lf = 0; lf < 8; lf++) - { - OGF_LOD::_face& F = pNode->lod_faces[lf]; - for (int lv = 0; lv < 4; lv++) - { - Fvector ptPos = F.v[lv].v; - - base_color_c color; - float n = 0; - - for (u32 v_it = 0; v_it < model->m_vertices.size(); v_it++) - { - // get base - Fvector baseP; - mu_reference.xform.transform_tiny(baseP, model->m_vertices[v_it]->P); - base_color_c baseC; - mu_reference.color[v_it]._get(baseC); - - base_color_c vC; - float oD = ptPos.distance_to(baseP); - float oA = 1 / (1 + 100 * oD * oD); - vC = (baseC); - vC.mul(oA); - color.add(vC); - n += oA; - } - - float s = 1 / (n + EPS); - color.mul(s); - F.v[lv].c_rgb_hemi = color_rgba(u8_clr(color.rgb.x), u8_clr(color.rgb.y), u8_clr(color.rgb.z), u8_clr(color.hemi)); - F.v[lv].c_sun = u8_clr(color.sun); - } - } - } -} diff --git a/src/utils/xrLC/xrMU_Model_export_geometry.cpp b/src/utils/xrLC/xrMU_Model_export_geometry.cpp deleted file mode 100644 index 86b71eb2a6c..00000000000 --- a/src/utils/xrLC/xrMU_Model_export_geometry.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "stdafx.h" -#include "utils/xrLC_Light/xrMU_Model.h" -#include "OGF_Face.h" -#include "Common/OGF_GContainer_Vertices.hpp" - -const u32 max_tile = 16; -const s32 quant = 32768 / max_tile; - -s16 QC(float v) -{ - int t = iFloor(v * float(quant)); - clamp(t, -32768, 32767); - return s16(t); -} - -void export_geometry(xrMU_Model& mu_model) -{ - // Declarator - VDeclarator D; - D.set(mu_model_decl); - - // RT-check, BOX, low-point, frac-size - Fbox BB; - BB.invalidate(); - for (xrMU_Model::v_vertices_it vit = mu_model.m_vertices.begin(); vit != mu_model.m_vertices.end(); ++vit) - BB.modify((*vit)->P); - - Fvector frac_low; - float frac_Ysize; - BB.getcenter(frac_low); - frac_low.y = BB.vMin.y; - frac_Ysize = BB.vMax.y - BB.vMin.y; - - // Begin building - for (xrMU_Model::v_subdivs_it it = mu_model.m_subdivs.begin(); it != mu_model.m_subdivs.end(); ++it) - { - // Vertices - { - g_VB.Begin(D); - - vecOGF_V& verts = it->ogf->data.vertices; - for (u32 v_it = 0; v_it < verts.size(); v_it++) - { - OGF_Vertex& oV = verts[v_it]; - - // Position - g_VB.Add(&oV.P, 3 * sizeof(float)); - - // Normal - { - base_color_c oV_c; - oV.Color._get(oV_c); - Fvector N = oV.N; - N.add(1.f); - N.mul(.5f * 255.f); - s32 nx = iFloor(N.x); - clamp(nx, 0, 255); - s32 ny = iFloor(N.y); - clamp(ny, 0, 255); - s32 nz = iFloor(N.z); - clamp(nz, 0, 255); - s32 cc = iFloor(oV_c.hemi * 255.f); - clamp(cc, 0, 255); - u32 uN = color_rgba(nx, ny, nz, cc); - g_VB.Add(&uN, 4); - } - - // Tangent - { - u32 uT = color_rgba(oV.T.x, oV.T.y, oV.T.z, 0); - g_VB.Add(&uT, 4); - } - - // Binormal - { - u32 uB = color_rgba(oV.B.x, oV.B.y, oV.B.z, 0); - g_VB.Add(&uB, 4); - } - - // TC - s16 tu, tv, frac, dummy; - tu = QC(oV.UV.begin()->x); - tv = QC(oV.UV.begin()->y); - g_VB.Add(&tu, 2); - g_VB.Add(&tv, 2); - - // frac - float f1 = (oV.P.y - frac_low.y) / frac_Ysize; - float f2 = oV.P.distance_to(frac_low) / frac_Ysize; - frac = QC((f1 + f2) / 2.f); - dummy = 0; - g_VB.Add(&frac, 2); - g_VB.Add(&dummy, 2); - } - - g_VB.End(&it->vb_id, &it->vb_start); - } - - // Indices - g_IB.Register( - (u16*)(&*it->ogf->data.faces.begin()), (u16*)(&*it->ogf->data.faces.end()), &it->ib_id, &it->ib_start); - - // SW - if (it->ogf->progressive_test()) - g_SWI.Register(&it->sw_id, &it->ogf->data.m_SWI); - } -} diff --git a/src/utils/xrLC/xrOptimizeCFORM_qslim.cpp b/src/utils/xrLC/xrOptimizeCFORM_qslim.cpp deleted file mode 100644 index 3d7c6a6dba5..00000000000 --- a/src/utils/xrLC/xrOptimizeCFORM_qslim.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "MxStdModel.h" -#include "MxQSlim.h" -#include "xrCDB/xrCDB.h" -#include "common/face_smoth_flags.h" - -#define MAX_DECIMATE_ERROR 0.0005f -#define COMPACTNESS_RATIO 0.001f - -void SaveAsSMF(LPCSTR fname, CDB::CollectorPacked& CL) -{ - IWriter* W = FS.w_open(fname); - string256 tmp; - // vertices - for (u32 v_idx = 0; v_idx < CL.getVS(); v_idx++) - { - Fvector* v = CL.getV() + v_idx; - xr_sprintf(tmp, "v %f %f %f", v->x, v->y, -v->z); - W->w_string(tmp); - } - // transfer faces - for (u32 f_idx = 0; f_idx < CL.getTS(); f_idx++) - { - CDB::TRI& t = CL.getT(f_idx); - xr_sprintf(tmp, "f %d %d %d", t.verts[0] + 1, t.verts[2] + 1, t.verts[1] + 1); - W->w_string(tmp); - } - FS.w_close(W); -} - -struct face_props -{ - u16 material; - u16 sector; - u32 flags; - Fvector norm; - void set(u16 mtl, u16 sect, const Fvector& n, u32 _flags) - { - material = mtl; - sector = sect; - norm.set(n); - flags = _flags; - } -}; - -IC u32 common_edge_idx(const MxFace& base_f, u32 base_edge_idx, const MxFace& test_f) -{ - VERIFY(base_edge_idx < 3); - MxVertexID bv0 = base_f[base_edge_idx]; - MxVertexID bv1 = base_f[(base_edge_idx + 1) % 3]; - if (bv0 > bv1) - std::swap(bv0, bv1); - - for (u8 i = 0; i < 3; ++i) - { - MxVertexID tv0 = test_f[i]; - MxVertexID tv1 = test_f[(i + 1) % 3]; - if (tv0 > tv1) - std::swap(tv0, tv1); - if (bv0 == tv0 && bv1 == tv1) - return i; - } - return u32(-1); -} -bool do_constrain(u32 base_edge_idx, u32 test_edg_idx, face_props& base_fprops, face_props& test_fprops) -{ - return (test_fprops.material != base_fprops.material) || (test_fprops.sector != base_fprops.sector) || - !do_connect_faces_by_faces_edge_flags(base_fprops.flags, test_fprops.flags, base_edge_idx, test_edg_idx); -} - -using FPVec = xr_vector; - -void SimplifyCFORM(CDB::CollectorPacked& CL) -{ - FPVec FPs; - - u32 base_verts_cnt = u32(CL.getVS()); - u32 base_faces_cnt = u32(CL.getTS()); - - // save source SMF - bool keep_temp_files = !!strstr(Core.Params, "-keep_temp_files"); - if (keep_temp_files) - { - string_path fn; - SaveAsSMF(strconcat(sizeof(fn), fn, pBuild->path, "cform_source.smf"), CL); - } - - // prepare model - MxStdModel* mdl = xr_new(base_verts_cnt, base_faces_cnt); - - // transfer vertices - for (u32 v_idx = 0; v_idx < base_verts_cnt; v_idx++) - { - Fvector* v = CL.getV() + v_idx; - mdl->add_vertex(v->x, v->y, v->z); - } - // transfer faces - FPs.resize(base_faces_cnt); - for (u32 f_idx = 0; f_idx < base_faces_cnt; f_idx++) - { - CDB::TRI& t = CL.getT(f_idx); - mdl->add_face(t.verts[0], t.verts[1], t.verts[2]); - FPs[f_idx].set(t.material, t.sector, - Fvector().mknormal(*(CL.getV() + t.verts[0]), *(CL.getV() + t.verts[1]), *(CL.getV() + t.verts[2])), - CL.getfFlags(f_idx)); - } - CL.clear(); - - // create and initialize qslim - MxEdgeQSlim* slim = xr_new(mdl); - slim->boundary_weight = 1000000.f; - slim->compactness_ratio = COMPACTNESS_RATIO; - slim->meshing_penalty = 1000000.f; - slim->placement_policy = MX_PLACE_ENDPOINTS; // MX_PLACE_ENDPOINTS;//MX_PLACE_ENDORMID;//MX_PLACE_OPTIMAL; - slim->weighting_policy = MX_WEIGHT_UNIFORM; // MX_WEIGHT_UNIFORM;//MX_WEIGHT_AREA; - slim->initialize(); - - // constraint material§or vertex - Ivector2 f_rm[3] = {{0, 1}, {1, 2}, {2, 0}}; - for (u32 f_idx = 0; f_idx < slim->valid_faces; f_idx++) - { - if (mdl->face_is_valid(f_idx)) - { - MxFace& base_f = mdl->face(f_idx); - for (u32 edge_idx = 0; edge_idx < 3; edge_idx++) - { - int K; - u32 I = f_rm[edge_idx].x; - u32 J = f_rm[edge_idx].y; - const MxFaceList& N0 = mdl->neighbors(base_f[I]); - const MxFaceList& N1 = mdl->neighbors(base_f[J]); - for (K = 0; K < N1.length(); K++) - mdl->face_mark(N1[K], 0); - for (K = 0; K < N0.length(); K++) - mdl->face_mark(N0[K], 1); - for (K = 0; K < N1.length(); K++) - mdl->face_mark(N1[K], mdl->face_mark(N1[K]) + 1); - const MxFaceList& N = (N0.size() < N1.size()) ? N0 : N1; - face_props& base_t = FPs[f_idx]; - if (N.size()) - { - u32 cnt_pos = 0, cnt_neg = 0; - bool need_constraint = false; - for (K = 0; K < N.length(); K++) - { - u32 fff = N[K]; - MxFace& cur_f = mdl->face(fff); - unsigned char mk = mdl->face_mark(fff); - if ((f_idx != N[K]) && (mdl->face_mark(N[K]) == 2)) - { - face_props& cur_t = FPs[N[K]]; - u32 cur_edge_idx = common_edge_idx(base_f, edge_idx, cur_f); - if (do_constrain(edge_idx, cur_edge_idx, base_t, cur_t)) - { - need_constraint = true; - break; - } - float dot = base_t.norm.dotproduct(cur_t.norm); - if (fsimilar(dot, -1.f, EPS)) - cnt_neg++; - else if (fsimilar(dot, 1.f, EPS)) - cnt_pos++; - } - } - if (need_constraint || ((0 == cnt_pos) && (1 == cnt_neg))) - { - slim->constraint_manual(base_f[I], base_f[J], f_idx); - } - } - } - } - } - // collect edges - slim->collect_edges(); - - // decimate - slim->decimate(0, MAX_DECIMATE_ERROR); - mdl->compact_vertices(); - - // rebuild CDB - for (u32 f_idx = 0; f_idx < mdl->face_count(); f_idx++) - { - if (mdl->face_is_valid(f_idx)) - { - MxFace& F = mdl->face(f_idx); - face_props& FP = FPs[f_idx]; - CL.add_face(*((Fvector*)&mdl->vertex(F[0])), *((Fvector*)&mdl->vertex(F[1])), - *((Fvector*)&mdl->vertex(F[2])), FP.material, FP.sector, FP.flags); - } - } - - // save source CDB - if (keep_temp_files) - { - string_path fn; - SaveAsSMF(strconcat(sizeof(fn), fn, pBuild->path, "cform_optimized.smf"), CL); - } - - xr_delete(slim); - xr_delete(mdl); -} diff --git a/src/utils/xrLC/xrPhase_AdaptiveHT.cpp b/src/utils/xrLC/xrPhase_AdaptiveHT.cpp deleted file mode 100644 index 995c766d3d7..00000000000 --- a/src/utils/xrLC/xrPhase_AdaptiveHT.cpp +++ /dev/null @@ -1,490 +0,0 @@ -#include "stdafx.h" -#include "build.h" - -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/light_point.h" -#include "utils/xrLC_Light/xrDeflector.h" -#include "utils/xrLC_Light/xrFace.h" - -#include "xrCDB/xrCDB.h" -#include "common/face_smoth_flags.h" -#include "utils/xrLCUtil/xrThread.hpp" - -const float aht_max_edge = c_SS_maxsize / 2.5f; // 2.0f; // 2 m -// const float aht_min_edge = .2f; // 20 cm -// const float aht_min_err = 16.f/255.f; // ~10% error - -bool is_CCW(int _1, int _2) -{ - if (0 == _1 && 1 == _2) - return true; - if (1 == _1 && 2 == _2) - return true; - if (2 == _1 && 0 == _2) - return true; - return false; -} - -// Iterate on edges - select longest -int callback_edge_longest(const Face* F) -{ - float max_err = -1; - int max_id = -1; - for (u32 e = 0; e < 3; e++) - { - Vertex *V1, *V2; - F->EdgeVerts(e, &V1, &V2); - float len = V1->P.distance_to(V2->P); // len - if (len < aht_max_edge) - continue; - if (len > max_err) - { - max_err = len; - max_id = e; - } - } - return max_id; -} -/* -// Iterate on edges - select with maximum error -int callback_edge_error (Face* F) -{ - float max_err = -1; - int max_id = -1; - for (u32 e=0; e<3; e++) - { - Vertex *V1,*V2; - F->EdgeVerts (e,&V1,&V2); - float len = V1->P.distance_to (V2->P); // len - if (lenmax_err) - { - max_err = len; - max_id = e; - } - } - if (max_id<0) return max_id; - - // There should be an edge larger than "min_edge" - base_color_c c1; F->v[0]->C._get(c1); - base_color_c c2; F->v[1]->C._get(c2); - base_color_c c3; F->v[2]->C._get(c3); - bool b1 = fsimilar (c1.hemi,c2.hemi,aht_min_err); - bool b2 = fsimilar (c2.hemi,c3.hemi,aht_min_err); - bool b3 = fsimilar (c3.hemi,c1.hemi,aht_min_err); - if (b1 && b2 && b3) return -1; // don't touch flat-shaded triangle - else return max_id; // tesselate longest edge -} -void callback_vertex_hemi (Vertex* V) -{ - // calc vertex attributes - CDB::COLLIDER DB; - base_color_c vC; - LightPoint (&DB, 0, RCAST_Model, vC, V->P, V->N, pBuild->L_static, LP_dont_rgb+LP_dont_sun,0); - V->C._set (vC); -} -int smfVertex (Vertex* V) -{ - return 1 + (std::lower_bound(g_vertices.begin(),g_vertices.end(),V)-g_vertices.begin()); -} - -void GSaveAsSMF (LPCSTR fname) -{ - IWriter* W = FS.w_open (fname); - string256 tmp; - - // vertices - std::sort (g_vertices.begin(),g_vertices.end()); - for (u32 v_idx=0; v_idxP; - xr_sprintf (tmp,"v %f %f %f",v.x,v.y,-v.z); - W->w_string (tmp); - } - - // transfer faces - for (u32 f_idx=0; f_idxv[0]), smfVertex(t->v[2]), smfVertex(t->v[1]) - ); - W->w_string (tmp); - } - - // colors - W->w_string ("bind c vertex"); - for (u32 v_idx=0; v_idxC._get(c); - float h = c.hemi/2.f; - xr_sprintf (tmp,"c %f %f %f",h,h,h); - W->w_string (tmp); - } - - FS.w_close (W); -} -*/ -class CPrecalcBaseHemiThread : public CThread -{ - u32 _from, _to; - CDB::COLLIDER DB; - -public: - CPrecalcBaseHemiThread(u32 ID, u32 from, u32 to) : CThread(ID, ProxyMsg), _from(from), _to(to) - { - R_ASSERT(from != u32(-1)); - R_ASSERT(to != u32(-1)); - R_ASSERT(from < to); - R_ASSERT(from >= 0); - R_ASSERT(to > 0); - } - virtual void Execute() - { - for (u32 vit = _from; vit < _to; vit++) - { - base_color_c vC; - vecVertex& verts = lc_global_data()->g_vertices(); - R_ASSERT(vit < verts.size()); - Vertex* V = verts[vit]; - - R_ASSERT(V); - V->normalFromAdj(); - LightPoint(&DB, 0, lc_global_data()->RCAST_Model(), vC, V->P, V->N, - pBuild->L_static(), LP_dont_rgb + LP_dont_sun, 0); - vC.mul(0.5f); - V->C._set(vC); - } - } -}; - -void CBuild::xrPhase_AdaptiveHT() -{ - CDB::COLLIDER DB; - - Logger.Status("Tesselating..."); - if (1) - { - for (u32 fit = 0; fit < lc_global_data()->g_faces().size(); fit++) - { // clear split flag from all faces + calculate normals - lc_global_data()->g_faces()[fit]->flags.bSplitted = false; - lc_global_data()->g_faces()[fit]->flags.bLocked = true; - lc_global_data()->g_faces()[fit]->CalcNormal(); - } - u_Tesselate(callback_edge_longest, 0, 0); // tesselate - } - - // Tesselate + calculate - Logger.Status("Precalculating..."); - { - mem_Compact(); - - // Build model - FPU::m64r(); - BuildRapid(FALSE); - - // Prepare - FPU::m64r(); - Logger.Status("Precalculating : base hemisphere ..."); - mem_Compact(); - Light_prepare(); - - // calc approximate normals for vertices + base lighting - // for (u32 vit=0; vitg_vertices().size(); vit++) - //{ - // base_color_c vC; - // Vertex* V = lc_global_data()->g_vertices()[vit]; - // V->normalFromAdj (); - // LightPoint (&DB, 0, lc_global_data()->RCAST_Model(), vC, V->P, V->N, pBuild->L_static(), - // LP_dont_rgb+LP_dont_sun,0); - // vC.mul (0.5f); - // V->C._set (vC); - //} - - CThreadManager precalc_base_hemi(ProxyStatus, ProxyProgress); - u32 stride = u32(-1); - u32 threads = u32(-1); - u32 rest = u32(-1); - get_intervals(NUM_THREADS, lc_global_data()->g_vertices().size(), threads, stride, rest); - for (u32 thID = 0; thID < threads; thID++) - precalc_base_hemi.start(xr_new(thID, thID * stride, thID * stride + stride)); - if (rest > 0) - precalc_base_hemi.start(xr_new(threads, threads * stride, threads * stride + rest)); - precalc_base_hemi.wait(); - // precalc_base_hemi - } - - ////////////////////////////////////////////////////////////////////////// - /* - Status ("Adaptive tesselation..."); - { - for (u32 fit=0; fitflags.bSplitted = false; - g_faces[fit]->flags.bLocked = true; - } - u_Tesselate (callback_edge_error,0,callback_vertex_hemi); // tesselate - } - */ - - ////////////////////////////////////////////////////////////////////////// - Logger.Status("Gathering lighting information..."); - u_SmoothVertColors(5); - - ////////////////////////////////////////////////////////////////////////// - /* - Status ("Exporting to SMF..."); - { - string_path fn; - GSaveAsSMF (strconcat(fn,pBuild->path,"hemi_source.smf")); - } - */ -} -void CollectProblematicFaces(const Face& F, int max_id, xr_vector& reult, Vertex** V1, Vertex** V2) -{ - xr_vector& adjacent_vec = reult; - adjacent_vec.reserve(6 * 2 * 3); - // now, we need to tesselate all faces which shares this 'problematic' edge - // collect all this faces - - F.EdgeVerts(max_id, V1, V2); - adjacent_vec.clear(); - for (u32 adj = 0; adj < (*V1)->m_adjacents.size(); ++adj) - { - Face* A = (*V1)->m_adjacents[adj]; - if (A->flags.bSplitted) - continue; - - if (A->VContains(*V2)) - adjacent_vec.push_back(A); - } - - std::sort(adjacent_vec.begin(), adjacent_vec.end()); - adjacent_vec.erase(std::unique(adjacent_vec.begin(), adjacent_vec.end()), adjacent_vec.end()); -} - -bool check_and_destroy_splited(u32 face_it) -{ - Face* F = lc_global_data()->g_faces()[face_it]; - VERIFY(F); - if (F->flags.bSplitted) - { - if (!F->flags.bLocked) - lc_global_data()->destroy_face(lc_global_data()->g_faces()[face_it]); - return false; // continue; - } - return true; -} -bool do_tesselate_face(const Face& F, tesscb_estimator* cb_E, int& max_id) -{ - if (F.CalcArea() < EPS_L) - return false; // continue; - max_id = cb_E(&F); - if (max_id < 0) - return false; // continue; // nothing selected - return true; -} - -void tessalate_faces(xr_vector& faces, Vertex* V1, Vertex* V2, tesscb_face* cb_F, tesscb_vertex* cb_V) -{ - xr_vector& adjacent_vec = faces; - // create new vertex (lerp) - Vertex* V = lc_global_data()->create_vertex(); - V->P.lerp(V1->P, V2->P, .5f); - - // iterate on faces which share this 'problematic' edge - for (u32 af_it = 0; af_it < adjacent_vec.size(); ++af_it) - { - Face* AF = adjacent_vec[af_it]; - VERIFY(false == AF->flags.bSplitted); - AF->flags.bSplitted = true; - _TCF& atc = AF->tc.front(); - - // indices & tc - int id1 = AF->VIndex(V1); - VERIFY(id1 >= 0 && id1 <= 2); - int id2 = AF->VIndex(V2); - VERIFY(id2 >= 0 && id2 <= 2); - int idB = 3 - (id1 + id2); - VERIFY(idB >= 0 && idB <= 2); - - Fvector2 UV; - UV.averageA(atc.uv[id1], atc.uv[id2]); - - // Create F1 & F2 - Face* F1 = lc_global_data()->create_face(); - F1->flags.bSplitted = false; - F1->flags.bLocked = false; - F1->dwMaterial = AF->dwMaterial; - F1->dwMaterialGame = AF->dwMaterialGame; - Face* F2 = lc_global_data()->create_face(); - F2->flags.bSplitted = false; - F2->flags.bLocked = false; - F2->dwMaterial = AF->dwMaterial; - F2->dwMaterialGame = AF->dwMaterialGame; - - set_backface(F1->sm_group, is_backface(AF->sm_group)); - set_backface(F2->sm_group, is_backface(AF->sm_group)); - - if (is_CCW(id1, id2)) - { - bool id1_id2_soft = is_soft_edge(AF->sm_group, id1); - bool id2_idB_soft = is_soft_edge(AF->sm_group, id2); - bool idB_id1_soft = is_soft_edge(AF->sm_group, idB); - - // F1 - F1->SetVertices(AF->v[idB], AF->v[id1], V); - F1->AddChannel(atc.uv[idB], atc.uv[id1], UV); - - set_soft_edge(F1->sm_group, 0, idB_id1_soft); - set_soft_edge(F1->sm_group, 1, id1_id2_soft); - set_soft_edge(F1->sm_group, 2, true); - - // F2 - F2->SetVertices(AF->v[idB], V, AF->v[id2]); - F2->AddChannel(atc.uv[idB], UV, atc.uv[id2]); - - set_soft_edge(F2->sm_group, 0, true); - set_soft_edge(F2->sm_group, 1, id1_id2_soft); - set_soft_edge(F2->sm_group, 2, id2_idB_soft); - } - else - { - bool id1_id2_soft = is_soft_edge(AF->sm_group, id2); - bool id2_idB_soft = is_soft_edge(AF->sm_group, idB); - bool idB_id1_soft = is_soft_edge(AF->sm_group, id1); - - // F1 - F1->SetVertices(AF->v[idB], V, AF->v[id1]); - F1->AddChannel(atc.uv[idB], UV, atc.uv[id1]); - - set_soft_edge(F1->sm_group, 0, true); - set_soft_edge(F1->sm_group, 1, id1_id2_soft); - set_soft_edge(F1->sm_group, 2, idB_id1_soft); - - // F2 - F2->SetVertices(AF->v[idB], AF->v[id2], V); - F2->AddChannel(atc.uv[idB], atc.uv[id2], UV); - - set_soft_edge(F2->sm_group, 0, id2_idB_soft); - set_soft_edge(F2->sm_group, 1, id1_id2_soft); - set_soft_edge(F2->sm_group, 2, true); - } - - // Normals and checkpoint - F1->N = AF->N; - if (cb_F) - cb_F(F1); - F2->N = AF->N; - if (cb_F) - cb_F(F2); - // smoth groups - // F1->sm_group= AF->sm_group; - // F2->sm_group= AF->sm_group; - // don't destroy old face (it can be used as occluder during ray-trace) - // if (AF->bLocked) continue; - // FacePool.destroy (g_faces[I]); - } - // calc vertex attributes - { - V->normalFromAdj(); - if (cb_V) - cb_V(V); - } -} -void CBuild::u_Tesselate(tesscb_estimator* cb_E, tesscb_face* cb_F, tesscb_vertex* cb_V) -{ - // main process - FPU::m64r(); - Logger.Status("Tesselating..."); - g_bUnregister = false; - - u32 counter_create = 0; - u32 cnt_verts = lc_global_data()->g_vertices().size(); - // u32 cnt_faces = g_faces.size(); - - for (u32 I = 0; I < lc_global_data()->g_faces().size(); ++I) - { - Face* F = lc_global_data()->g_faces()[I]; - if (0 == F) - continue; - if (!check_and_destroy_splited(I)) - continue; - - Logger.Progress(float(I) / float(lc_global_data()->g_faces().size())); - int max_id = -1; - if (!do_tesselate_face(*F, cb_E, max_id)) - continue; - - xr_vector adjacent_vec; - Vertex *V1, *V2; - CollectProblematicFaces(*F, max_id, adjacent_vec, &V1, &V2); - ++counter_create; - if (0 == (counter_create % 10000)) - { - for (u32 I = 0; I < lc_global_data()->g_vertices().size(); ++I) - if (lc_global_data()->g_vertices()[I]->m_adjacents.empty()) - lc_global_data()->destroy_vertex(lc_global_data()->g_vertices()[I]); - - Logger.Status("Working: %d verts created, %d(now) / %d(was) ...", counter_create, - lc_global_data()->g_vertices().size(), cnt_verts); - FlushLog(); - } - - tessalate_faces(adjacent_vec, V1, V2, cb_F, cb_V); - } - - // Cleanup - for (u32 I = 0; I < lc_global_data()->g_faces().size(); ++I) - if (0 != lc_global_data()->g_faces()[I] && lc_global_data()->g_faces()[I]->flags.bSplitted) - lc_global_data()->destroy_face(lc_global_data()->g_faces()[I]); - - for (u32 I = 0; I < lc_global_data()->g_vertices().size(); ++I) - if (lc_global_data()->g_vertices()[I]->m_adjacents.empty()) - lc_global_data()->destroy_vertex(lc_global_data()->g_vertices()[I]); - - lc_global_data()->g_faces().erase( - std::remove(lc_global_data()->g_faces().begin(), lc_global_data()->g_faces().end(), (Face*)0), - lc_global_data()->g_faces().end()); - lc_global_data()->g_vertices().erase( - std::remove(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end(), (Vertex*)0), - lc_global_data()->g_vertices().end()); - g_bUnregister = true; -} - -void CBuild::u_SmoothVertColors(int count) -{ - for (int iteration = 0; iteration < count; ++iteration) - { - // Gather - xr_vector colors; - colors.resize(lc_global_data()->g_vertices().size()); - for (u32 it = 0; it < lc_global_data()->g_vertices().size(); ++it) - { - // Circle - xr_vector circle_vec; - Vertex* V = lc_global_data()->g_vertices()[it]; - - for (u32 fit = 0; fit < V->m_adjacents.size(); ++fit) - { - Face* F = V->m_adjacents[fit]; - circle_vec.push_back(F->v[0]); - circle_vec.push_back(F->v[1]); - circle_vec.push_back(F->v[2]); - } - std::sort(circle_vec.begin(), circle_vec.end()); - circle_vec.erase(std::unique(circle_vec.begin(), circle_vec.end()), circle_vec.end()); - - // Average - base_color_c avg, tmp; - for (u32 cit = 0; cit < circle_vec.size(); ++cit) - { - circle_vec[cit]->C._get(tmp); - avg.add(tmp); - } - avg.scale(circle_vec.size()); - colors[it]._set(avg); - } - - // Transfer - for (u32 it = 0; it < lc_global_data()->g_vertices().size(); ++it) - lc_global_data()->g_vertices()[it]->C = colors[it]; - } -} diff --git a/src/utils/xrLC/xrPhase_AdaptiveHT_qslim.cpp b/src/utils/xrLC/xrPhase_AdaptiveHT_qslim.cpp deleted file mode 100644 index 403533d6d2e..00000000000 --- a/src/utils/xrLC/xrPhase_AdaptiveHT_qslim.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#include "stdafx.h" -/* -#include "build.h" -#include -#include - -const float aht_max_edge = c_SS_maxsize/2.5f; // 2.0f; // 2 m -const float aht_min_edge = .2f; // 20 cm -const float aht_min_err = 16.f/255.f; // ~10% error - -bool is_CCW (int _1, int _2) -{ - if (0==_1 && 1==_2) return true; - if (1==_1 && 2==_2) return true; - if (2==_1 && 0==_2) return true; - return false; -} - -// Iterate on edges - select longest -int callback_edge_longest (Face* F) -{ - float max_err = -1; - int max_id = -1; - for (u32 e=0; e<3; e++) - { - Vertex *V1,*V2; - F->EdgeVerts (e,&V1,&V2); - float len = V1->P.distance_to (V2->P); // len - if (lenmax_err) - { - max_err = len; - max_id = e; - } - } - return max_id; -} - -// Iterate on edges - select with maximum error -int callback_edge_error (Face* F) -{ - float max_err = -1; - int max_id = -1; - for (u32 e=0; e<3; e++) - { - Vertex *V1,*V2; - F->EdgeVerts (e,&V1,&V2); - float len = V1->P.distance_to (V2->P); // len - if (lenmax_err) - { - max_err = len; - max_id = e; - } - } - if (max_id<0) return max_id; - - // There should be an edge larger than "min_edge" - base_color_c c1; F->v[0]->C._get(c1); - base_color_c c2; F->v[1]->C._get(c2); - base_color_c c3; F->v[2]->C._get(c3); - bool b1 = fsimilar (c1.hemi,c2.hemi,aht_min_err); - bool b2 = fsimilar (c2.hemi,c3.hemi,aht_min_err); - bool b3 = fsimilar (c3.hemi,c1.hemi,aht_min_err); - if (b1 && b2 && b3) return -1; // don't touch flat-shaded triangle - else return max_id; // tesselate longest edge -} - -void callback_vertex_hemi (Vertex* V) -{ - // calc vertex attributes - CDB::COLLIDER DB; - base_color_c vC; - LightPoint (&DB, 0, RCAST_Model, vC, V->P, V->N, pBuild->L_static, LP_dont_rgb+LP_dont_sun,0); - V->C._set (vC); -} - -int smfVertex (Vertex* V) -{ - return 1 + (std::lower_bound(g_vertices.begin(),g_vertices.end(),V)-g_vertices.begin()); -} - -void GSaveAsSMF (LPCSTR fname) -{ - string_path fn; - strconcat (fn,pBuild->path,fname); - - IWriter* W = FS.w_open (fn); - string256 tmp; - - // vertices - std::sort (g_vertices.begin(),g_vertices.end()); - for (u32 v_idx=0; v_idxP; - xr_sprintf (tmp,"v %f %f %f",v.x,v.y,-v.z); - W->w_string (tmp); - } - - // transfer faces - for (u32 f_idx=0; f_idxv[0]), smfVertex(t->v[2]), smfVertex(t->v[1]) - ); - W->w_string (tmp); - } - - // colors - W->w_string ("bind c vertex"); - for (u32 v_idx=0; v_idxC._get(c); - float h = c.hemi/2.f; - xr_sprintf (tmp,"c %f %f %f",h,h,h); - W->w_string (tmp); - } - - FS.w_close (W); -} - -void GSaveAsSMF (MxStdModel* mdl, LPCSTR fname) -{ - string_path fn; - strconcat (fn,pBuild->path,fname); - - IWriter* W = FS.w_open (fn); - string256 tmp; - - - // vertices - for (u32 v_idx=0; v_idxvert_count(); v_idx++){ - MxVertex v = mdl->vertex(v_idx); - xr_sprintf (tmp,"v %f %f %f",v[0],v[1],-v[2]); - W->w_string (tmp); - } - // colors - W->w_string ("bind c vertex"); - for (u32 c_idx=0; c_idxcolor_count(); c_idx++){ - MxColor v = mdl->color(c_idx); - xr_sprintf (tmp,"c %f %f %f",v.R(),v.G(),v.B()); - W->w_string (tmp); - } - // faces - for (u32 f_idx=0; f_idxface_count(); f_idx++){ - if (mdl->face_is_valid(f_idx)){ - MxFace& F = mdl->face(f_idx); - xr_sprintf (tmp,"f %d %d %d", F[0]+1, F[2]+1, F[1]+1); - W->w_string (tmp); - } - } - - FS.w_close (W); -} - -void CBuild::xrPhase_AdaptiveHT () -{ - CDB::COLLIDER DB; - - if (1) - { - GSaveAsSMF ("hemi_before_tess.smf"); - } - - u32 src_face_count = g_faces.size(); - - Status ("Tesselating..."); - if (1) - { - for (u32 fit=0; fitflags.bSplitted = false; - g_faces[fit]->flags.bLocked = true; - g_faces[fit]->CalcNormal (); - } - u_Tesselate (callback_edge_longest,0,0); // tesselate - } - - // Tesselate + calculate - Status ("Precalculating..."); - { - mem_Compact (); - - // Build model - FPU::m64r (); - BuildRapid (FALSE); - - // Prepare - FPU::m64r (); - Status ("Precalculating : base hemisphere ..."); - mem_Compact (); - Light_prepare (); - - // calc approximate normals for vertices + base lighting - for (u32 vit=0; vitnormalFromAdj (); - LightPoint (&DB, 0, RCAST_Model, vC, V->P, V->N, pBuild->L_static, LP_dont_rgb+LP_dont_sun,0); - V->C._set (vC); - } - } - - ////////////////////////////////////////////////////////////////////////// - Status ("Adaptive tesselation..."); - if (1) - { - for (u32 fit=0; fitflags.bSplitted = false; - g_faces[fit]->flags.bLocked = true; - } - u_Tesselate (callback_edge_error,0,callback_vertex_hemi); // tesselate - } - - ////////////////////////////////////////////////////////////////////////// - Status ("Gathering lighting information..."); - u_SmoothVertColors (7); - - ////////////////////////////////////////////////////////////////////////// - Status ("Exporting to SMF..."); - if (1) - { - GSaveAsSMF ("hemi_tess_color.smf"); - } - - // prepare model - MxStdModel* mdl = new MxStdModel(g_vertices.size(),g_faces.size()); - - // transfer vertices - mdl->color_binding (MX_PERVERTEX); - std::sort (g_vertices.begin(),g_vertices.end()); - for (u32 v_idx=0; v_idxP; - mdl->add_vertex (v.x,v.y,v.z); - // color - base_color_c c; g_vertices[v_idx]->C._get(c); - float h = c.hemi/2.f; - mdl->add_color (h,h,h); - } - // transfer faces - for (u32 f_idx=0; f_idxadd_face (smfVertex(t->v[0])-1, smfVertex(t->v[1])-1, smfVertex(t->v[2])-1); - } - - // create and initialize qslim - MxPropSlim* slim = new MxPropSlim(mdl); - slim->boundary_weight = 1000.f; - slim->compactness_ratio = 0; - slim->meshing_penalty = 1000.f; - slim->placement_policy = MX_PLACE_OPTIMAL;//MX_PLACE_ENDPOINTS MX_PLACE_ENDORMID MX_PLACE_OPTIMAL; - slim->weighting_policy = MX_WEIGHT_AREA; - slim->initialize (); - - // collect edges - slim->collect_edges (); - - slim->decimate (src_face_count*2,0.01f); - mdl->compact_vertices (); - - GSaveAsSMF (mdl,"hemi_simple_color.smf"); - - - xr_delete (mdl); - xr_delete (slim); -} - -void CBuild::u_Tesselate (tesscb_estimator* cb_E, tesscb_face* cb_F, tesscb_vertex* cb_V) -{ - // main process - FPU::m64r (); - Status ("Tesselating..."); - g_bUnregister = FALSE; - xr_vector adjacent; adjacent.reserve(6*2*3); - u32 counter_create = 0; - u32 cnt_verts = g_vertices.size (); - u32 cnt_faces = g_faces.size (); - for (u32 I=0; Iflags.bSplitted) { - if (!F->flags.bLocked) FacePool.destroy (g_faces[I]); - continue; - } - if (F->CalcArea()EdgeVerts (max_id,&V1,&V2); - adjacent.clear (); - for (u32 adj=0; adjadjacent.size(); adj++) - { - Face* A = V1->adjacent[adj]; - if (A->flags.bSplitted) continue; - if (A->VContains(V2)) adjacent.push_back (A); - } - std::sort (adjacent.begin(),adjacent.end()); - adjacent.erase (std::unique(adjacent.begin(),adjacent.end()),adjacent.end()); - - // create new vertex (lerp) - counter_create ++; - if (0==(counter_create%10000)) { - for (u32 I=0; Iadjacent.size()) VertexPool.destroy -(g_vertices[I]); - Status ("Working: %d verts created, %d(now) / %d(was) -...",counter_create,g_vertices.size(),cnt_verts); - FlushLog (); - } - - Vertex* V = VertexPool.create(); - V->P.lerp (V1->P, V2->P, .5f); - - // iterate on faces which share this 'problematic' edge - for (u32 af_it=0; af_itflags.bSplitted); - AF->flags.bSplitted = true; - _TCF& atc = AF->tc.front(); - - // indices & tc - int id1 = AF->VIndex(V1); - int id2 = AF->VIndex(V2); - int idB = 3-(id1+id2); - Fvector2 UV; - UV.averageA (atc.uv[id1],atc.uv[id2]); - - // Create F1 & F2 - Face* F1 = FacePool.create(); - F1->flags.bSplitted = false; - F1->flags.bLocked = false; - F1->dwMaterial = AF->dwMaterial; - F1->dwMaterialGame = AF->dwMaterialGame; - Face* F2 = FacePool.create(); - F2->flags.bSplitted = false; - F2->flags.bLocked = false; - F2->dwMaterial = AF->dwMaterial; - F2->dwMaterialGame = AF->dwMaterialGame; - - if (is_CCW(id1,id2)) - { - // F1 - F1->SetVertices (AF->v[idB], AF->v[id1], V); - F1->AddChannel (atc.uv[idB], atc.uv[id1], UV); - // F2 - F2->SetVertices (AF->v[idB], V, AF->v[id2]); - F2->AddChannel (atc.uv[idB], UV, atc.uv[id2]); - } else { - // F1 - F1->SetVertices (AF->v[idB], V, AF->v[id1]); - F1->AddChannel (atc.uv[idB], UV, atc.uv[id1]); - // F2 - F2->SetVertices (AF->v[idB], AF->v[id2], V); - F2->AddChannel (atc.uv[idB], atc.uv[id2], UV); - } - - // Normals and checkpoint - F1->N = AF->N; if (cb_F) cb_F(F1); - F2->N = AF->N; if (cb_F) cb_F(F2); - - // don't destroy old face (it can be used as occluder during ray-trace) - // if (AF->bLocked) continue; - // FacePool.destroy (g_faces[I]); - } - - // calc vertex attributes - { - V->normalFromAdj (); - if (cb_V) cb_V (V); - } - } - - // Cleanup - for (u32 I=0; Iflags.bSplitted) FacePool.destroy -(g_faces[I]); - for (u32 I=0; Iadjacent.size()) VertexPool.destroy -(g_vertices[I]); - g_faces.erase (std::remove(g_faces.begin(),g_faces.end(),(Face*)0),g_faces.end()); - g_vertices.erase (std::remove(g_vertices.begin(),g_vertices.end(),(Vertex*)0),g_vertices.end()); - g_bUnregister = true; -} - -void CBuild::u_SmoothVertColors(int count) -{ - for (int iteration=0; iteration colors; - colors.resize (g_vertices.size()); - for (u32 it=0; it circle; - Vertex* V = g_vertices[it]; - for (u32 fit=0; fitadjacent.size(); fit++) { - Face* F = V->adjacent[fit]; - circle.push_back(F->v[0]); - circle.push_back(F->v[1]); - circle.push_back(F->v[2]); - } - std::sort (circle.begin(),circle.end()); - circle.erase (std::unique(circle.begin(),circle.end()),circle.end()); - - // Average - base_color_c avg,tmp; - for (u32 cit=0; citC._get (tmp); - avg.add (tmp); - } - avg.scale (circle.size()); - colors[it]._set (avg); - } - - // Transfer - for (int it=0; itC = colors[it]; - } -} -*/ diff --git a/src/utils/xrLC/xrPhase_GI.cpp b/src/utils/xrLC/xrPhase_GI.cpp deleted file mode 100644 index cb12095eb33..00000000000 --- a/src/utils/xrLC/xrPhase_GI.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "stdafx.h" -#include "build.h" - -#include "utils/xrLCUtil/xrThread.hpp" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -#include "xrCore/Threading/Lock.hpp" -#include "xrCDB/xrCDB.h" -#include "utils/xrLC_Light/base_face_ptr_storage.h" - -const u32 gi_num_photons = 32; -const float gi_optimal_range = 15.f; -const float gi_reflect = 0.9f; -const float gi_clip = 0.05f; -const u32 gi_maxlevel = 4; -////////////////////////////////////////////////////////////////////////// -static xr_vector* task; -Lock task_cs -#ifdef CONFIG_PROFILE_LOCKS - (MUTEX_PROFILE_ID(task_cs)) -#endif // CONFIG_PROFILE_LOCKS - ; -static u32 task_it; - -////////////////////////////////////////////////////////////////////////// -static Fvector GetPixel_7x7(CDB::RESULT& rpinf) -{ - Fvector B, P, R = {0, 0, 0}; - - // Access to texture - CDB::TRI& clT = lc_global_data()->RCAST_Model()->get_tris()[rpinf.id]; - base_Face* F = get_base_face_pointer(clT); - if (0 == F) - return R; - const Shader_xrLC& SH = F->Shader(); - if (!SH.flags.bLIGHT_CastShadow) - return R; - if (!F->flags.bOpaque) - return R; // don't use transparency - - b_material& M = pBuild->materials()[F->dwMaterial]; - b_texture& T = pBuild->textures()[M.surfidx]; - -#ifdef DEBUG - const b_BuildTexture& build_texture = pBuild->textures()[M.surfidx]; - - VERIFY(!!(build_texture.THM.HasSurface()) == !!(T.pSurface)); -#endif - - if (0 == T.pSurface) - return R; - - // barycentric coords - // note: W,U,V order - B.set(1.0f - rpinf.u - rpinf.v, rpinf.u, rpinf.v); - - // calc UV - Fvector2* cuv = F->getTC0(); - Fvector2 uv; - uv.x = cuv[0].x * B.x + cuv[1].x * B.y + cuv[2].x * B.z; - uv.y = cuv[0].y * B.x + cuv[1].y * B.y + cuv[2].y * B.z; - - for (int _y = -3; _y <= 3; _y++) - { - for (int _x = -3; _x <= 3; _x++) - { - int U = iFloor(uv.x * float(T.dwWidth) + .5f) + _x; - int V = iFloor(uv.y * float(T.dwHeight) + .5f) + _y; - U %= T.dwWidth; - if (U < 0) - U += T.dwWidth; - V %= T.dwHeight; - if (V < 0) - V += T.dwHeight; - u32 pixel = T.pSurface[V * T.dwWidth + U]; - P.set(float(color_get_R(pixel)), float(color_get_G(pixel)), float(color_get_B(pixel))); - R.mad(P, 1.f / 255.f); - } - } - R.div(49.f); - // R.add (1.f); // make it appear more like white material - // R.div (2.f); - return R; -} - -////////////////////////////////////////////////////////////////////////// -class CGI : public CThread -{ -public: - CGI(u32 ID) : CThread(ID, ProxyMsg) { thMessages = FALSE; } - virtual void Execute() - { - CDB::COLLIDER xrc; - CDB::MODEL* model = lc_global_data()->RCAST_Model(); - CDB::TRI* tris = lc_global_data()->RCAST_Model()->get_tris(); - Fvector* verts = lc_global_data()->RCAST_Model()->get_verts(); - - // full iteration - for (;;) - { - // get task - R_Light src, dst; - task_cs.Enter(); - if (task_it >= task->size()) - { - task_cs.Leave(); - return; - } - else - { - src = (*task)[task_it]; - if (0 == src.level) - src.range *= 1.5f; - dst = src; - // if (LT_POINT==src.type) (*task)[task_it].energy = 0.f; - dst.type = LT_SECONDARY; - dst.level++; - task_it++; - thProgress = float(task_it) / float(task->size()) / float(NUM_THREADS); - } - task_cs.Leave(); - if (dst.level > gi_maxlevel) - continue; - - // analyze - CRandom random; - random.seed(0x12071980); - float factor = _sqrt(src.range / gi_optimal_range); // smaller lights get smaller amount of photons - if (factor > 1) - factor = 1; - if (LT_SECONDARY == src.type) - factor /= powf(2.f, float(src.level)); // secondary lights get half the photons - factor *= _sqrt(src.energy); // 2.f is optimal energy = baseline - // factor = _sqrt (factor); // move towards 1.0 (one) - int count = iCeil(factor * float(gi_num_photons)); - // count = gi_num_photons; - float _clip = (_sqrt(src.energy) / 10.f + gi_clip) / 2.f; - float _scale = 1.f / _sqrt(factor); - // clMsg ("src_LER[%d/%f/%f] -> factor(%f), count(%d), clip(%f)", - // src.level, src.energy, src.range, factor, count, _clip - // ); - for (int it = 0; it < count; it++) - { - Fvector dir, idir; - float s = 1.f; - switch (src.type) - { - case LT_POINT: dir.random_dir(random).normalize(); break; - case LT_SECONDARY: - dir.random_dir(src.direction, PI_DIV_2, random); //. or PI ? - s = src.direction.dotproduct(dir.normalize()); - break; - default: - continue; // continue loop - } - xrc.ray_query(CDB::OPT_CULL | CDB::OPT_ONLYNEAREST, model, src.position, dir, src.range); - if (!xrc.r_count()) - continue; - CDB::RESULT* R = xrc.r_begin(); - CDB::TRI& T = tris[R->id]; - Fvector Tv[3] = {verts[T.verts[0]], verts[T.verts[1]], verts[T.verts[2]]}; - Fvector TN; - TN.mknormal(Tv[0], Tv[1], Tv[2]); - float dot = TN.dotproduct(idir.invert(dir)); - - dst.position.mad(src.position, dir, R->range); - dst.position.mad(TN, 0.01f); // 1cm away from surface - dst.direction.reflect(dir, TN); - dst.energy = src.energy * dot * gi_reflect * (1 - R->range / src.range) * _scale; - if (dst.energy < _clip) - continue; - - // color bleeding - dst.diffuse.mul(src.diffuse, GetPixel_7x7(*R)); - dst.diffuse.mul(dst.energy); - { - float _e = (dst.diffuse.x + dst.diffuse.y + dst.diffuse.z) / 3.f; - Fvector _c = {dst.diffuse.x, dst.diffuse.y, dst.diffuse.z}; - if (_abs(_e) > EPS_S) - _c.div(_e); - else - { - _c.set(0, 0, 0); - _e = 0; - } - dst.diffuse = _c; - dst.energy = _e; - } - if (dst.energy < _clip) - continue; - - // scale range in proportion with energy - float _r1 = src.range * _sqrt(dst.energy / src.energy); - float _r2 = (dst.energy - _clip) / _clip; - float _r3 = src.range; - dst.range = 1 * ((1.f * _r1 + 3.f * _r2 + 3.f * _r3) / 7.f); // empirical - // clMsg ("submit: level[%d],type[%d], energy[%f]",dst.level,dst.type,dst.energy); - - // submit answer - if (dst.energy > gi_clip / 4) - { - // clMsg ("dst_ER[%f/%f]", dst.energy, dst.range); - task_cs.Enter(); - task->push_back(dst); - task_cs.Leave(); - } - } - } - } -}; - -// test_radios -void CBuild::xrPhase_Radiosity() -{ - CThreadManager gi(ProxyStatus, ProxyProgress); - Logger.Status("Working..."); - task = &(pBuild->L_static().rgb); - task_it = 0; - - // calculate energy - float _energy_before = 0; - for (u32 l = 0; l < task->size(); l++) - if (task->at(l).type == LT_POINT) - _energy_before += task->at(l).energy; - - // perform all the work - u32 setup_old = task->size(); - for (int t = 0; t < NUM_THREADS; t++) - { - gi.start(xr_new(t)); - Sleep(10); - } - gi.wait(); - u32 setup_new = task->size(); - - // renormalize - float _energy_after = 0; - for (u32 l = 0; l < task->size(); l++) - { - R_Light& L = (*task)[l]; - // clMsg ("type[%d], energy[%f]",L.type,L.energy); - if (LT_SECONDARY == L.type) - { - if (L.energy > gi_clip / 4) - _energy_after += L.energy; - else - { - task->erase(task->begin() + l); - l--; - } - } - } - float _scale = 1.f * _energy_before / _energy_after; - for (u32 l = 0; l < task->size(); l++) - { - R_Light& L = (*task)[l]; - if (LT_SECONDARY == L.type) - L.energy *= _scale; - } - - // info - Logger.clMsg("old setup [%d], new setup[%d]", setup_old, setup_new); - Logger.clMsg("old energy [%f], new energy[%f]", _energy_before, _energy_after); - FlushLog(); -} diff --git a/src/utils/xrLC/xrPhase_MergeGeometry.cpp b/src/utils/xrLC/xrPhase_MergeGeometry.cpp deleted file mode 100644 index eb189891686..00000000000 --- a/src/utils/xrLC/xrPhase_MergeGeometry.cpp +++ /dev/null @@ -1,351 +0,0 @@ -#include "stdafx.h" - -#include "build.h" -#include "utils/xrLC_Light/xrface.h" - -extern void Detach(vecFace* S); - -IC BOOL FaceEqual(Face* F1, Face* F2) -{ - if (F1->dwMaterial != F2->dwMaterial) - return FALSE; - if (F1->tc.size() != F2->tc.size()) - return FALSE; - if (F1->lmap_layer != F2->lmap_layer) - return FALSE; - return TRUE; -} - -BOOL NeedMerge(vecFace& subdiv, Fbox& bb_base) -{ - // 1. Amount of polygons - if (subdiv.size() >= u32(3 * c_SS_HighVertLimit / 4)) - return FALSE; - - // 2. Bounding box - bb_base.invalidate(); - for (u32 it = 0; it < subdiv.size(); it++) - { - Face* F = subdiv[it]; - bb_base.modify(F->v[0]->P); - bb_base.modify(F->v[1]->P); - bb_base.modify(F->v[2]->P); - } - bb_base.grow(EPS_S); // Enshure non-zero volume - - Fvector sz_base; - bb_base.getsize(sz_base); - if (sz_base.x < c_SS_maxsize) - return TRUE; - if (sz_base.y < c_SS_maxsize) - return TRUE; - if (sz_base.z < c_SS_maxsize) - return TRUE; - return FALSE; -} - -float Cuboid(Fbox& BB) -{ - Fvector sz; - BB.getsize(sz); - float min = sz.x; - if (sz.y < min) - min = sz.y; - if (sz.z < min) - min = sz.z; - - float volume_cube = min * min * min; - float volume = sz.x * sz.y * sz.z; - return powf(volume_cube / volume, 1.f / 7.f); -} - -IC void MakeCube(Fbox& BB_dest, const Fbox& BB_src) -{ - Fvector C, D; - BB_src.get_CD(C, D); - float max = D.x; - if (D.y > max) - max = D.y; - if (D.z > max) - max = D.z; - - BB_dest.set(C, C); - BB_dest.grow(max); -} - -IC BOOL ValidateMergeLinearSize(const Fvector& merged, const Fvector& orig1, const Fvector& orig2, int iAxis) -{ - if ((merged[iAxis] > (4 * c_SS_maxsize / 3)) && (merged[iAxis] > (orig1[iAxis] + 1)) && - (merged[iAxis] > (orig2[iAxis] + 1))) - return FALSE; - else - return TRUE; -} - -IC BOOL ValidateMerge(u32 f1, const Fbox& bb_base, const Fbox& bb_base_orig, u32 f2, const Fbox& bb, float& volume) -{ - // Polygons - if ((f1 + f2) > u32(4 * c_SS_HighVertLimit / 3)) - return FALSE; // Don't exceed limits (4/3 max POLY) - - // Size - Fbox merge; - merge.merge(bb_base, bb); - Fvector sz; - merge.getsize(sz); - Fvector orig1; - bb_base_orig.getsize(orig1); - Fvector orig2; - bb.getsize(orig2); - // if (sz.x>(4*c_SS_maxsize/3)) return FALSE; // Don't exceed limits (4/3 GEOM) - // if (sz.y>(4*c_SS_maxsize/3)) return FALSE; - // if (sz.z>(4*c_SS_maxsize/3)) return FALSE; - - if (!ValidateMergeLinearSize(sz, orig1, orig2, 0)) - return FALSE; // Don't exceed limits (4/3 GEOM) - if (!ValidateMergeLinearSize(sz, orig1, orig2, 1)) - return FALSE; - if (!ValidateMergeLinearSize(sz, orig1, orig2, 2)) - return FALSE; - - // Volume - Fbox bb0, bb1; - MakeCube(bb0, bb_base); - float v1 = bb0.getvolume(); - MakeCube(bb1, bb); - float v2 = bb1.getvolume(); - volume = merge.getvolume(); // / Cuboid(merge); - if (volume > 2 * 2 * 2 * (v1 + v2)) - return FALSE; // Don't merge too distant groups (8 vol) - - // OK - return TRUE; -} - -void FindBestMergeCandidate(u32* selected, float* selected_volume, u32 split, u32 split_size, vecFace* subdiv, - Fbox* bb_base_orig, Fbox* bb_base); - -typedef struct MERGEGM_PARAMS -{ - u32 selected; - float selected_volume; - u32 split; - u32 split_size; - vecFace* subdiv; - Fbox* bb_base_orig; - Fbox* bb_base; - HANDLE hEvents[3]; // 0=start,1=terminate,2=ready -} * LP_MERGEGM_PARAMS; - -static CRITICAL_SECTION mergegm_cs; -static BOOL mergegm_threads_initialized = FALSE; -static u32 mergegm_threads_count = 0; -static LPHANDLE mergegm_threads_handles = NULL; -static LPHANDLE mergegm_ready_events = NULL; -static LP_MERGEGM_PARAMS mergegm_params = NULL; - -DWORD WINAPI MergeGmThreadProc(LPVOID lpParameter) -{ - LP_MERGEGM_PARAMS pParams = (LP_MERGEGM_PARAMS)lpParameter; - - while (TRUE) - { - // Wait for "start" and "terminate" events - switch (WaitForMultipleObjects(2, pParams->hEvents, FALSE, INFINITE)) - { - case WAIT_OBJECT_0 + 0: - FindBestMergeCandidate(&pParams->selected, &pParams->selected_volume, pParams->split, pParams->split_size, - pParams->subdiv, pParams->bb_base_orig, pParams->bb_base); - // Signal "ready" event - SetEvent(pParams->hEvents[2]); - break; - case WAIT_OBJECT_0 + 1: ExitThread(0); break; - default: - // Error ? - ExitThread(1); - break; - } // switch - } // while - - return 0; -} - -void InitMergeGmThreads() -{ - if (mergegm_threads_initialized) - return; - - SYSTEM_INFO SystemInfo; - GetSystemInfo(&SystemInfo); - mergegm_threads_count = SystemInfo.dwNumberOfProcessors; - - mergegm_threads_handles = (LPHANDLE)xr_malloc(mergegm_threads_count * sizeof(HANDLE)); - mergegm_ready_events = (LPHANDLE)xr_malloc(mergegm_threads_count * sizeof(HANDLE)); - mergegm_params = (LP_MERGEGM_PARAMS)xr_malloc(mergegm_threads_count * sizeof(MERGEGM_PARAMS)); - - InitializeCriticalSection(&mergegm_cs); - - for (u32 i = 0; i < mergegm_threads_count; i++) - { - ZeroMemory(&mergegm_params[i], sizeof(MERGEGM_PARAMS)); - - // Creating start,terminate,ready events for each thread - for (u32 x = 0; x < 3; x++) - mergegm_params[i].hEvents[x] = CreateEvent(NULL, FALSE, FALSE, NULL); - - // Duplicate ready event into array - mergegm_ready_events[i] = mergegm_params[i].hEvents[2]; - - mergegm_threads_handles[i] = CreateThread(NULL, 0, &MergeGmThreadProc, &mergegm_params[i], 0, NULL); - } - - mergegm_threads_initialized = TRUE; -} - -void DoneMergeGmThreads() -{ - if (!mergegm_threads_initialized) - return; - - // Asking helper threads to terminate - for (u32 i = 0; i < mergegm_threads_count; i++) - SetEvent(mergegm_params[i].hEvents[1]); - - // Waiting threads for completion - WaitForMultipleObjects(mergegm_threads_count, mergegm_threads_handles, TRUE, INFINITE); - - // Deleting events - for (u32 i = 0; i < mergegm_threads_count; i++) - for (u32 x = 0; x < 3; x++) - CloseHandle(mergegm_params[i].hEvents[x]); - - // Freeing resources - DeleteCriticalSection(&mergegm_cs); - - xr_free(mergegm_threads_handles); - mergegm_threads_handles = NULL; - xr_free(mergegm_ready_events); - mergegm_ready_events = NULL; - xr_free(mergegm_params); - mergegm_params = NULL; - - mergegm_threads_count = 0; - - mergegm_threads_initialized = FALSE; -} - -void FindBestMergeCandidate_threads(u32* selected, float* selected_volume, u32 split, u32 split_size, vecFace* subdiv, - Fbox* bb_base_orig, Fbox* bb_base) -{ - u32 m_range = (split_size - split) / mergegm_threads_count; - - // Assigning parameters - for (u32 i = 0; i < mergegm_threads_count; i++) - { - mergegm_params[i].selected = *selected; - mergegm_params[i].selected_volume = *selected_volume; - - mergegm_params[i].split = split + (i * m_range); - mergegm_params[i].split_size = - (i == (mergegm_threads_count - 1)) ? split_size : mergegm_params[i].split + m_range; - - mergegm_params[i].subdiv = subdiv; - mergegm_params[i].bb_base_orig = bb_base_orig; - mergegm_params[i].bb_base = bb_base; - - SetEvent(mergegm_params[i].hEvents[0]); - } // for - - // Wait for result - WaitForMultipleObjects(mergegm_threads_count, mergegm_ready_events, TRUE, INFINITE); - - // Compose results - for (u32 i = 0; i < mergegm_threads_count; i++) - { - if (mergegm_params[i].selected_volume < *selected_volume) - { - *selected = mergegm_params[i].selected; - *selected_volume = mergegm_params[i].selected_volume; - } - } -} - -void FindBestMergeCandidate(u32* selected, float* selected_volume, u32 split, u32 split_size, vecFace* subdiv, - Fbox* bb_base_orig, Fbox* bb_base) -{ - for (u32 test = split; test < split_size; test++) - { - Fbox bb; - float volume; - vecFace& TEST = *(g_XSplit[test]); - - if (!FaceEqual(subdiv->front(), TEST.front())) - continue; - if (!NeedMerge(TEST, bb)) - continue; - if (!ValidateMerge(subdiv->size(), *bb_base, *bb_base_orig, TEST.size(), bb, volume)) - continue; - - if (volume < *selected_volume) - { - *selected = test; - *selected_volume = volume; - } - } -} - -void CBuild::xrPhase_MergeGeometry() -{ - // Initialize helper threads - InitMergeGmThreads(); - - Logger.Status("Processing..."); - validate_splits(); - for (u32 split = 0; split < g_XSplit.size(); split++) - { - vecFace& subdiv = *(g_XSplit[split]); - bool bb_base_orig_inited = false; - Fbox bb_base_orig; - Fbox bb_base; - while (NeedMerge(subdiv, bb_base)) - { - // Save original AABB for later tests - if (!bb_base_orig_inited) - { - bb_base_orig_inited = true; - bb_base_orig = bb_base; - } - - // **OK**. Let's find the best candidate for merge - u32 selected = split; - float selected_volume = flt_max; - - if ((g_XSplit.size() - split) < 200) - { // may need adjustment - // single thread - FindBestMergeCandidate( - &selected, &selected_volume, split + 1, g_XSplit.size(), &subdiv, &bb_base_orig, &bb_base); - } - else - { - // multi thread - FindBestMergeCandidate_threads( - &selected, &selected_volume, split + 1, g_XSplit.size(), &subdiv, &bb_base_orig, &bb_base); - } - - if (selected == split) - break; // No candidates for merge - - // **OK**. Perform merge - subdiv.insert(subdiv.begin(), g_XSplit[selected]->begin(), g_XSplit[selected]->end()); - xr_delete(g_XSplit[selected]); - g_XSplit.erase(g_XSplit.begin() + selected); - } - Logger.Progress(_sqrt(_sqrt(float(split) / float(g_XSplit.size())))); - } - Logger.clMsg("%d subdivisions.", g_XSplit.size()); - validate_splits(); - - // Destroy helper threads - DoneMergeGmThreads(); -} diff --git a/src/utils/xrLC/xrPhase_MergeLM.cpp b/src/utils/xrLC/xrPhase_MergeLM.cpp deleted file mode 100644 index dc23d8a803b..00000000000 --- a/src/utils/xrLC/xrPhase_MergeLM.cpp +++ /dev/null @@ -1,520 +0,0 @@ - -#include "stdafx.h" -#include "build.h" - -#include "xrPhase_MergeLM_Rect.h" -#include "utils/xrLC_Light/xrdeflector.h" -#include "utils/xrLC_Light/xrlc_globaldata.h" -#include "utils/xrLC_Light/lightmap.h" -// Surface access -extern void _InitSurface(); -extern BOOL _rect_place(L_rect& r, lm_layer* D); - -IC int compare_defl(CDeflector* D1, CDeflector* D2) -{ - // First - by material - u16 M1 = D1->GetBaseMaterial(); - u16 M2 = D2->GetBaseMaterial(); - if (M1 < M2) - return 1; // less - if (M1 > M2) - return 0; // more - return 2; // equal -} - -// should define LESS(D1GetBaseMaterial(); - u16 M2 = D2->GetBaseMaterial(); - - // 1. material area - u32 A1 = pBuild->materials()[M1].internal_max_area; - u32 A2 = pBuild->materials()[M2].internal_max_area; - if (A1 < A2) - return 2; // A2 better - if (A1 > A2) - return 1; // A1 better - - // 2. material sector (geom - locality) - u32 s1 = pBuild->materials()[M1].sector; - u32 s2 = pBuild->materials()[M2].sector; - if (s1 < s2) - return 2; // s2 better - if (s1 > s2) - return 1; // s1 better - - // 3. just material index - if (M1 < M2) - return 2; // s2 better - if (M1 > M2) - return 1; // s1 better - - // 4. deflector area - u32 da1 = D1->layer.Area(); - u32 da2 = D2->layer.Area(); - if (da1 < da2) - return 2; // s2 better - if (da1 > da2) - return 1; // s1 better - - // 5. they are EQUAL - return 0; // equal -} - -// should define LESS(D1bMerged) - { - D->bMerged = FALSE; - return TRUE; - } - else - return FALSE; - }; -}; - -void CBuild::xrPhase_MergeLM() -{ - vecDefl Layer; - - // **** Select all deflectors, which contain this light-layer - Layer.clear(); - for (u32 it = 0; it < lc_global_data()->g_deflectors().size(); it++) - { - CDeflector* D = lc_global_data()->g_deflectors()[it]; - if (D->bMerged) - continue; - Layer.push_back(D); - } - - // Merge this layer (which left unmerged) - while (Layer.size()) - { - VERIFY(lc_global_data()); - string512 phase_name; - xr_sprintf(phase_name, "Building lightmap %d...", lc_global_data()->lightmaps().size()); - Logger.Phase(phase_name); - - // Sort layer by similarity (state changes) - // + calc material area - Logger.Status("Selection..."); - for (u32 it = 0; it < materials().size(); it++) - materials()[it].internal_max_area = 0; - for (u32 it = 0; it < Layer.size(); it++) - { - CDeflector* D = Layer[it]; - materials()[D->GetBaseMaterial()].internal_max_area = - _max(D->layer.Area(), materials()[D->GetBaseMaterial()].internal_max_area); - } - std::stable_sort(Layer.begin(), Layer.end(), sort_defl_complex); - - // Select first deflectors which can fit - Logger.Status("Selection..."); - u32 maxarea = c_LMAP_size * c_LMAP_size * 8; // Max up to 8 lm selected - u32 curarea = 0; - u32 merge_count = 0; - for (u32 it = 0; it < (int)Layer.size(); it++) - { - int defl_area = Layer[it]->layer.Area(); - if (curarea + defl_area > maxarea) - break; - curarea += defl_area; - merge_count++; - } - - // Startup - Logger.Status("Processing..."); - _InitSurface(); - CLightmap* lmap = xr_new(); - VERIFY(lc_global_data()); - lc_global_data()->lightmaps().push_back(lmap); - - // Process - for (u32 it = 0; it < merge_count; it++) - { - if (0 == (it % 1024)) - Logger.Status("Process [%d/%d]...", it, merge_count); - lm_layer& L = Layer[it]->layer; - L_rect rT, rS; - rS.a.set(0, 0); - rS.b.set(L.width + 2 * BORDER - 1, L.height + 2 * BORDER - 1); - rS.iArea = L.Area(); - rT = rS; - if (_rect_place(rT, &L)) - { - BOOL bRotated; - if (rT.SizeX() == rS.SizeX()) - { - R_ASSERT(rT.SizeY() == rS.SizeY()); - bRotated = FALSE; - } - else - { - R_ASSERT(rT.SizeX() == rS.SizeY()); - R_ASSERT(rT.SizeY() == rS.SizeX()); - bRotated = TRUE; - } - lmap->Capture(Layer[it], rT.a.x, rT.a.y, rT.SizeX(), rT.SizeY(), bRotated); - Layer[it]->bMerged = TRUE; - } - Logger.Progress(_sqrt(float(it) / float(merge_count))); - } - Logger.Progress(1.f); - - // Remove merged lightmaps - Logger.Status("Cleanup..."); - vecDeflIt last = std::remove_if(Layer.begin(), Layer.end(), pred_remove()); - Layer.erase(last, Layer.end()); - - // Save - Logger.Status("Saving..."); - VERIFY(pBuild); - lmap->Save(pBuild->path); - } - VERIFY(lc_global_data()); - Logger.clMsg("%d lightmaps builded", lc_global_data()->lightmaps().size()); - - // Cleanup deflectors - Logger.Progress(1.f); - Logger.Status("Destroying deflectors..."); - for (u32 it = 0; it < lc_global_data()->g_deflectors().size(); it++) - xr_delete(lc_global_data()->g_deflectors()[it]); - lc_global_data()->g_deflectors().clear(); -} - -/* - -#include "stdafx.h" -#include "build.h" - -#include "xrPhase_MergeLM_Rect.h" -#include "utils/xrLC_Light/xrdeflector.h" -#include "utils/xrLC_Light/xrlc_globaldata.h" -#include "utils/xrLC_Light/lightmap.h" -// Surface access -extern void _InitSurface (); -extern BOOL _rect_place (L_rect &r, lm_layer* D); - -IC int compare_defl (CDeflector* D1, CDeflector* D2) -{ - // First - by material - u16 M1 = D1->GetBaseMaterial(); - u16 M2 = D2->GetBaseMaterial(); - if (M1M2) return 0; // more - return 2; // equal -} - -// should define LESS(D1GetBaseMaterial(); - u16 M2 = D2->GetBaseMaterial(); - - // 1. material area - u32 A1 = pBuild->materials()[M1].internal_max_area; - u32 A2 = pBuild->materials()[M2].internal_max_area; - if (A1A2) return 1; // A1 better - - // 2. material sector (geom - locality) - u32 s1 = pBuild->materials()[M1].sector; - u32 s2 = pBuild->materials()[M2].sector; - if (s1s2) return 1; // s1 better - - // 3. just material index - if (M1M2) return 1; // s1 better - - // 4. deflector area - u32 da1 = D1->layer.Area(); - u32 da2 = D2->layer.Area(); - if (da1da2)return 1; // s1 better - - // 5. they are EQUAL - return 0; // equal -} - -// should define LESS(D1bMerged) -{D->bMerged=FALSE; return TRUE; } else return FALSE; }; }; - -void MergeLM_process( u32 m_from , u32 m_to , vecDefl* pLayer , CLightmap* lmap ); - -typedef struct MERGELM_PARAMS -{ - u32 m_from; - u32 m_to; - vecDefl* Layer; - CLightmap* lmap; - HANDLE hEvents[3]; // 0=start,1=terminate,2=ready -} * LP_MERGELM_PARAMS; - -static CRITICAL_SECTION mergelm_cs; -static BOOL mergelm_threads_initialized = FALSE; -static u32 mergelm_threads_count = 0; -static LPHANDLE mergelm_threads_handles = NULL; -static LPHANDLE mergelm_ready_events = NULL; -static LP_MERGELM_PARAMS mergelm_params = NULL; - -DWORD WINAPI MergeThreadProc( LPVOID lpParameter ) -{ - LP_MERGELM_PARAMS pParams = ( LP_MERGELM_PARAMS ) lpParameter; - - while( TRUE ) { - // Wait for "start" and "terminate" events - switch ( WaitForMultipleObjects( 2 , pParams->hEvents , FALSE , INFINITE ) ) { - case WAIT_OBJECT_0 + 0 : - MergeLM_process( pParams->m_from , pParams->m_to , pParams->Layer , pParams->lmap ); - // Signal "ready" event - SetEvent( pParams->hEvents[ 2 ] ); - break; - case WAIT_OBJECT_0 + 1 : - ExitThread( 0 ); - break; - default : - // Error ? - ExitThread( 1 ); - break; - } // switch - } // while - - return 0; -} - - -void InitMergeThreads() -{ - if ( mergelm_threads_initialized ) - return; - - SYSTEM_INFO SystemInfo; - GetSystemInfo( &SystemInfo ); - mergelm_threads_count = SystemInfo.dwNumberOfProcessors; - - mergelm_threads_handles = (LPHANDLE) xr_malloc( mergelm_threads_count * sizeof( HANDLE ) ); - mergelm_ready_events = (LPHANDLE) xr_malloc( mergelm_threads_count * sizeof( HANDLE ) ); - mergelm_params = (LP_MERGELM_PARAMS) xr_malloc( mergelm_threads_count * sizeof( MERGELM_PARAMS ) ); - - InitializeCriticalSection( &mergelm_cs ); - - for ( u32 i = 0 ; i < mergelm_threads_count ; i++ ) { - - ZeroMemory( &mergelm_params[ i ] , sizeof( MERGELM_PARAMS ) ); - - // Creating start,terminate,ready events for each thread - for( u32 x = 0 ; x < 3 ; x++ ) - mergelm_params[ i ].hEvents[ x ] = CreateEvent( NULL , FALSE , FALSE , NULL ); - - // Duplicate ready event into array - mergelm_ready_events[ i ] = mergelm_params[ i ].hEvents[ 2 ]; - - mergelm_threads_handles[ i ] = CreateThread( NULL , 0 , &MergeThreadProc , &mergelm_params[ i ] , 0 , NULL ); - } - - mergelm_threads_initialized = TRUE; -} - -void DoneMergeThreads() -{ - if ( ! mergelm_threads_initialized ) - return; - - // Asking helper threads to terminate - for ( u32 i = 0 ; i < mergelm_threads_count ; i++ ) - SetEvent( mergelm_params[ i ].hEvents[ 1 ] ); - - // Waiting threads for completion - WaitForMultipleObjects( mergelm_threads_count , mergelm_threads_handles , TRUE , INFINITE ); - - // Deleting events - for ( u32 i = 0 ; i < mergelm_threads_count ; i++ ) - for( u32 x = 0 ; x < 3 ; x++ ) - CloseHandle( mergelm_params[ i ].hEvents[ x ] ); - - // Freeing resources - DeleteCriticalSection( &mergelm_cs ); - - xr_free( mergelm_threads_handles ); mergelm_threads_handles = NULL; - xr_free( mergelm_ready_events ); mergelm_ready_events = NULL; - xr_free( mergelm_params ); mergelm_params = NULL; - - mergelm_threads_count = 0; - - mergelm_threads_initialized = FALSE; -} - - -void MergeLM_process_threads( u32 m_count , vecDefl* pLayer , CLightmap* lmap ) -{ - u32 m_range = m_count / mergelm_threads_count; - - for ( u32 i = 0 ; i < mergelm_threads_count ; i++ ) { - mergelm_params[ i ].Layer = pLayer; - mergelm_params[ i ].lmap = lmap; - - mergelm_params[ i ].m_from = i * m_range; - mergelm_params[ i ].m_to = ( i == ( mergelm_threads_count - 1 ) ) ? m_count : mergelm_params[ i ].m_from + -m_range; - - SetEvent( mergelm_params[ i ].hEvents[ 0 ] ); - } // for - - WaitForMultipleObjects( mergelm_threads_count , mergelm_ready_events , TRUE , INFINITE ); -} - - -void MergeLM_process( u32 m_from , u32 m_to , vecDefl* pLayer , CLightmap* lmap ) -{ - for ( u32 it = m_from ; it < m_to ; it++ ) { - lm_layer& L = (*pLayer)[ it ]->layer; - L_rect rT , rS; - rS.a.set( 0 , 0 ); - rS.b.set( L.width + 2*BORDER - 1 , L.height + 2*BORDER - 1 ); - rS.iArea = L.Area(); - rT = rS; - if ( _rect_place( rT , &L ) ) { - BOOL bRotated; - if ( rT.SizeX() == rS.SizeX() ) { - R_ASSERT(rT.SizeY() == rS.SizeY()); - bRotated = FALSE; - } else { - R_ASSERT(rT.SizeX() == rS.SizeY()); - R_ASSERT(rT.SizeY() == rS.SizeX()); - bRotated = TRUE; - } - - EnterCriticalSection( &mergelm_cs ); - lmap->Capture( (*pLayer)[ it ] , rT.a.x , rT.a.y , rT.SizeX() , rT.SizeY() , bRotated ); - LeaveCriticalSection( &mergelm_cs ); - - (*pLayer)[it]->bMerged = TRUE; - } // if - } // for -} - -void CBuild::xrPhase_MergeLM() -{ - vecDefl Layer; - - // Initialize helper threads - InitMergeThreads(); - - // **** Select all deflectors, which contain this light-layer - Layer.clear (); - for (u32 it=0; itg_deflectors().size(); it++) - { - CDeflector* D = lc_global_data()->g_deflectors()[it]; - if (D->bMerged) continue; - Layer.push_back (D); - } - - // Merge this layer (which left unmerged) - while (Layer.size()) - { - VERIFY( lc_global_data() ); - string512 phase_name; - xr_sprintf (phase_name,"Building lightmap %d...", lc_global_data()->lightmaps().size()); - Phase (phase_name); - - // Sort layer by similarity (state changes) - // + calc material area - Status ("Selection..."); - for (u32 it=0; itGetBaseMaterial()].internal_max_area = -_max(D->layer.Area(),materials()[D->GetBaseMaterial()].internal_max_area); - } - std::stable_sort(Layer.begin(),Layer.end(),sort_defl_complex); - - // Select first deflectors which can fit - Status ("Selection..."); - u32 maxarea = c_LMAP_size*c_LMAP_size*8; // Max up to 8 lm selected - u32 curarea = 0; - u32 merge_count = 0; - for (u32 it=0; it<(int)Layer.size(); it++) { - int defl_area = Layer[it]->layer.Area(); - if (curarea + defl_area > maxarea) break; - curarea += defl_area; - merge_count ++; - } - - // Startup - Status ("Processing..."); - _InitSurface (); - CLightmap* lmap = xr_new (); - VERIFY( lc_global_data() ); - lc_global_data()->lightmaps().push_back (lmap); - - // Process - MergeLM_process_threads( merge_count , &Layer , lmap ); - - Progress (1.f); - - // Remove merged lightmaps - Status ("Cleanup..."); - vecDeflIt last = std::remove_if (Layer.begin(),Layer.end(),pred_remove()); - Layer.erase (last,Layer.end()); - - // Save - Status ("Saving..."); - VERIFY ( pBuild ); - lmap->Save (pBuild->path); - } - VERIFY( lc_global_data() ); - clMsg ( "%d lightmaps builded", lc_global_data()->lightmaps().size() ); - - // Cleanup deflectors - Progress (1.f); - Status ("Destroying deflectors..."); - for (u32 it=0; itg_deflectors().size(); it++) - xr_delete(lc_global_data()->g_deflectors()[it]); - lc_global_data()->g_deflectors().clear(); - - // Destroy helper threads - DoneMergeThreads(); -} -*/ diff --git a/src/utils/xrLC/xrPhase_MergeLM_Rect.h b/src/utils/xrLC/xrPhase_MergeLM_Rect.h deleted file mode 100644 index 765015b9f0b..00000000000 --- a/src/utils/xrLC/xrPhase_MergeLM_Rect.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -struct L_point -{ - int x, y; - IC void set(int _x, int _y) - { - x = _x; - y = _y; - } - IC void set(L_point& P) { set(P.x, P.y); } -}; -struct L_rect -{ - L_point a, b; // min,max - int iArea; - - IC void set(L_rect& R) - { - a.set(R.a); - b.set(R.b); - iArea = R.iArea; - }; - IC void init(int ax, int ay, int bx, int by) - { - a.set(ax, ay); - b.set(bx, by); - } - IC void calc_area() { iArea = SizeX() * SizeY(); }; - IC bool PointInside(L_point& P) { return (P.x >= a.x && P.x <= b.x && P.y >= a.y && P.y <= b.y); }; - IC bool Intersect(L_rect& R) - { - if (R.b.x < a.x) - return false; - if (R.b.y < a.y) - return false; - if (R.a.x > b.x) - return false; - if (R.a.y > b.y) - return false; - return true; - }; - IC void GetAB(L_point& A, L_point& B) - { - A.x = b.x; - A.y = a.y; - B.x = a.x; - B.y = b.y; - }; - IC void Invalidate() - { - a.set(SHRT_MAX, SHRT_MAX); - b.set(SHRT_MIN, SHRT_MIN); - } - IC void Merge(L_rect& R) - { - if (R.a.x < a.x) - a.x = R.a.x; - if (R.a.y < a.y) - a.y = R.a.y; - if (R.b.x > b.x) - b.x = R.b.x; - if (R.b.y > b.y) - b.y = R.b.y; - } - IC int SizeX() { return b.x - a.x + 1; } - IC int SizeY() { return b.y - a.y + 1; } -}; diff --git a/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp b/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp deleted file mode 100644 index a6ad9def3ed..00000000000 --- a/src/utils/xrLC/xrPhase_MergeLM_Surface.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "xrPhase_MergeLM_Rect.h" -#include "utils/xrLC_Light/xrdeflector.h" - -#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) -#include -#else -#include -#include -#endif - -static u8 surface[c_LMAP_size * c_LMAP_size]; -const u32 alpha_ref = 254 - BORDER; - -// Initialization -void _InitSurface() { FillMemory(surface, c_LMAP_size * c_LMAP_size, 0); } -// Rendering of rect -void _rect_register(L_rect& R, lm_layer* D, BOOL bRotate) -{ - u8* lm = &*(D->marker.begin()); - u32 s_x = D->width + 2 * BORDER; - u32 s_y = D->height + 2 * BORDER; - - if (!bRotate) - { - // Normal (and fastest way) - for (u32 y = 0; y < s_y; y++) - { - u8* P = surface + (y + R.a.y) * c_LMAP_size + R.a.x; // destination scan-line - u8* S = lm + y * s_x; - for (u32 x = 0; x < s_x; x++, P++, S++) - if (*S >= alpha_ref) - *P = 255; - } - } - else - { - // Rotated :( - for (u32 y = 0; y < s_x; y++) - { - u8* P = surface + (y + R.a.y) * c_LMAP_size + R.a.x; // destination scan-line - for (u32 x = 0; x < s_y; x++, P++) - if (lm[x * s_x + y] >= alpha_ref) - *P = 255; - } - } -} - -// Test of per-pixel intersection (surface test) -bool Place_Perpixel(L_rect& R, lm_layer* D, BOOL bRotate) -{ - u8* lm = &*(D->marker.begin()); - int s_x = D->width + 2 * BORDER; - int s_y = D->height + 2 * BORDER; - int x; - -#ifdef _M_X64 - __m128i mm_alpha_ref = _mm_set1_epi8(alpha_ref); - __m128i mm_zero = _mm_setzero_si128(); -#else - const __m64 mm_alpha_ref = _mm_set1_pi8(alpha_ref); - const __m64 mm_zero = _mm_setzero_si64(); -#endif - - if (!bRotate) - { - // Normal (and fastest way) - for (int y = 0; y < s_y; y++) - { - u8* P = surface + (y + R.a.y) * c_LMAP_size + R.a.x; // destination scan-line - u8* S = lm + y * s_x; - // accelerated part - for (x = 0; x < s_x - 8; x += 8, P += 8, S += 8) - { - // if ( (*P) && ( *S >= alpha_ref ) ) goto r_false; // overlap -#if defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) - __m128i regS = _mm_set1_epi64x(*((__int64*)S)); - __m128i regP = _mm_set1_epi64x(*((__int64*)P)); - __m128i mm_max = _mm_max_epu8(regS, mm_alpha_ref); - __m128i mm_cmp = _mm_cmpeq_epi8(mm_max, mm_alpha_ref); - __m128i mm_andn = _mm_andnot_si128(mm_cmp, regP); - __m128i mm_andn_low = _mm_move_epi64(mm_andn); - __m128i mm_sad = _mm_sad_epu8(mm_andn_low, mm_zero); - if (_mm_cvtsi128_si32(mm_sad)) - return false; -#else - __m64 mm_max = _mm_max_pu8(*(__m64*)S, mm_alpha_ref); - __m64 mm_cmp = _mm_cmpeq_pi8(mm_max, mm_alpha_ref); - __m64 mm_andn = _mm_andnot_si64(mm_cmp, *(__m64*)P); - __m64 mm_sad = _mm_sad_pu8(mm_andn, mm_zero); - if (_mm_cvtsi64_si32(mm_sad)) - { - _mm_empty(); - return false; - } -#endif - } - // remainder part - for (; x < s_x; x++, P++, S++) - if ((*P) && (*S >= alpha_ref)) - { -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return false; - } - } - } - else - { - // Rotated :( - for (int y = 0; y < s_x; y++) - { - u8* P = surface + (y + R.a.y) * c_LMAP_size + R.a.x; // destination scan-line - for (x = 0; x < s_y; x++, P++) - if ((*P) && (lm[x * s_x + y] >= alpha_ref)) - { -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return false; - } - } - } - - // It's OK to place it -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return true; -} - -// Check for intersection -BOOL _rect_place(L_rect& r, lm_layer* D) -{ - L_rect R; - int X_; - u8* temp_surf; - - // Normal - { - int x_max = c_LMAP_size - r.b.x; - int y_max = c_LMAP_size - r.b.y; - for (int _Y = 0; _Y < y_max; _Y++) - { - temp_surf = surface + _Y * c_LMAP_size; - // accelerated part - for (X_ = 0; X_ < x_max - 8;) - { -#ifdef _M_X64 - __m128i init = _mm_set1_epi64x(*(temp_surf + X_)); - __m128i m64_cmp = _mm_cmpeq_epi8(init, _mm_setzero_si128()); - __m128i m64_cmp_low = _mm_move_epi64(m64_cmp); - __m128i m64_work = _mm_sad_epu8(m64_cmp_low, _mm_setzero_si128()); - - if (!_mm_cvtsi128_si32(m64_work)) { - X_ += 8; - continue; - } -#else - __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + X_), _mm_setzero_si64()); - __m64 m64_work = _mm_sad_pu8(m64_cmp, _mm_setzero_si64()); - - if (!_mm_cvtsi64_si32(m64_work)) - { - X_ += 8; - continue; - } -#endif - if (temp_surf[X_]) - { - X_++; - continue; - } - - R.init(X_, _Y, X_ + r.b.x, _Y + r.b.y); - - X_++; - - if (Place_Perpixel(R, D, FALSE)) - { - _rect_register(R, D, FALSE); - r.set(R); -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return TRUE; - } - } - // remainder part - for (; X_ < x_max; X_++) - { - if (temp_surf[X_]) - continue; - R.init(X_, _Y, X_ + r.b.x, _Y + r.b.y); - if (Place_Perpixel(R, D, FALSE)) - { - _rect_register(R, D, FALSE); - r.set(R); -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return TRUE; - } - } - } - } - - // Rotated - { - int x_max = c_LMAP_size - r.b.y; - int y_max = c_LMAP_size - r.b.x; - for (int _Y = 0; _Y < y_max; _Y++) - { - temp_surf = surface + _Y * c_LMAP_size; - // accelerated part - for (X_ = 0; X_ < x_max - 8;) - { -#ifdef _M_X64 - __m128i init = _mm_set1_epi64x(*(temp_surf + X_)); - __m128i m64_cmp = _mm_cmpeq_epi8(init, _mm_setzero_si128()); - __m128i m64_cmp_low = _mm_move_epi64(m64_cmp); - __m128i m64_work = _mm_sad_epu8(m64_cmp_low, _mm_setzero_si128()); - - if (!_mm_cvtsi128_si32(m64_work)) { - X_ += 8; - continue; - } -#else - __m64 m64_cmp = _mm_cmpeq_pi8(*(__m64*)(temp_surf + X_), _mm_setzero_si64()); - __m64 m64_work = _mm_sad_pu8(m64_cmp, _mm_setzero_si64()); - - if (!_mm_cvtsi64_si32(m64_work)) - { - X_ += 8; - continue; - } -#endif - if (temp_surf[X_]) - { - X_++; - continue; - } - - R.init(X_, _Y, X_ + r.b.y, _Y + r.b.x); - - X_++; - - if (Place_Perpixel(R, D, TRUE)) - { - _rect_register(R, D, TRUE); - r.set(R); -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return TRUE; - } - } - // remainder part - for (; X_ < x_max; X_++) - { - if (temp_surf[X_]) - continue; - R.init(X_, _Y, X_ + r.b.y, _Y + r.b.x); - if (Place_Perpixel(R, D, TRUE)) - { - _rect_register(R, D, TRUE); - r.set(R); -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return TRUE; - } - } - } - } - -#ifdef XR_ARCHITECTURE_X86 - _mm_empty(); -#endif - return FALSE; -} diff --git a/src/utils/xrLC/xrPhase_ResolveMaterials.cpp b/src/utils/xrLC/xrPhase_ResolveMaterials.cpp deleted file mode 100644 index df770f4d962..00000000000 --- a/src/utils/xrLC/xrPhase_ResolveMaterials.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -extern void Detach(vecFace* S); - -struct _counter -{ - u16 dwMaterial; - u32 dwCount; -}; - -void CBuild::xrPhase_ResolveMaterials() -{ - // Count number of materials - Logger.Status("Calculating materials/subdivs..."); - xr_vector<_counter> counts; - { - counts.reserve(256); - for (vecFaceIt F_it = lc_global_data()->g_faces().begin(); F_it != lc_global_data()->g_faces().end(); ++F_it) - { - Face* F = *F_it; - BOOL bCreate = TRUE; - for (u32 I = 0; I < counts.size(); I++) - { - if (F->dwMaterial == counts[I].dwMaterial) - { - counts[I].dwCount += 1; - bCreate = FALSE; - break; - } - } - if (bCreate) - { - _counter C; - C.dwMaterial = F->dwMaterial; - C.dwCount = 1; - counts.push_back(C); - } - Logger.Progress( - float(F_it - lc_global_data()->g_faces().begin()) / float(lc_global_data()->g_faces().size())); - } - } - - Logger.Status("Perfroming subdivisions..."); - { - g_XSplit.reserve(64 * 1024); - g_XSplit.resize(counts.size()); - for (u32 I = 0; I < counts.size(); I++) - { - g_XSplit[I] = xr_new(); - g_XSplit[I]->reserve(counts[I].dwCount); - } - - for (vecFaceIt F_it = lc_global_data()->g_faces().begin(); F_it != lc_global_data()->g_faces().end(); ++F_it) - { - Face* F = *F_it; - if (!F->Shader().flags.bRendering) - continue; - - for (u32 I = 0; I < counts.size(); I++) - { - if (F->dwMaterial == counts[I].dwMaterial) - { - g_XSplit[I]->push_back(F); - } - } - Logger.Progress( - float(F_it - lc_global_data()->g_faces().begin()) / float(lc_global_data()->g_faces().size())); - } - } - - Logger.Status("Removing empty subdivs..."); - { - for (int SP = 0; SP < int(g_XSplit.size()); SP++) - if (g_XSplit[SP]->empty()) - xr_delete(g_XSplit[SP]); - g_XSplit.erase(std::remove(g_XSplit.begin(), g_XSplit.end(), (vecFace*)NULL), g_XSplit.end()); - } - - Logger.Status("Detaching subdivs..."); - { - for (u32 it = 0; it < g_XSplit.size(); it++) - { - Detach(g_XSplit[it]); - } - } - Logger.clMsg("%d subdivisions.", g_XSplit.size()); -} diff --git a/src/utils/xrLC/xrPhase_Subdivide.cpp b/src/utils/xrLC/xrPhase_Subdivide.cpp deleted file mode 100644 index d6963c5025d..00000000000 --- a/src/utils/xrLC/xrPhase_Subdivide.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "utils/xrLC_Light/xrdeflector.h" -#include "utils/xrLC_Light/xrface.h" -#include "utils/xrLC_Light/xrlc_globaldata.h" - -extern void Detach(vecFace* S); - -void setup_bbs(Fbox& b1, Fbox& b2, Fbox& bb, int edge) -{ - Fvector size; - b1.set(bb); - b2.set(bb); - size.sub(bb.vMax, bb.vMin); - switch (edge) - { - case 0: - b1.vMax.x -= size.x / 2; - b2.vMin.x += size.x / 2; - break; - case 1: - b1.vMax.y -= size.y / 2; - b2.vMin.y += size.y / 2; - break; - case 2: - b1.vMax.z -= size.z / 2; - b2.vMin.z += size.z / 2; - break; - } -}; - -void CBuild::xrPhase_Subdivide() -{ - Logger.Status("Subdividing in space..."); - vecFace s1, s2; - Fbox b1, b2; - for (int X = 0; X < int(g_XSplit.size()); X++) - { - if (g_XSplit[X]->empty()) - { - xr_delete(g_XSplit[X]); - g_XSplit.erase(g_XSplit.begin() + X); - X--; - continue; - } - Logger.Progress(float(X) / float(g_XSplit.size())); - - // skip if subdivision is too small already - if (int(g_XSplit[X]->size()) < (c_SS_LowVertLimit * 2)) - continue; - - // calc bounding box - Fbox bb; - Fvector size; - - bb.invalidate(); - for (vecFaceIt F = g_XSplit[X]->begin(); F != g_XSplit[X]->end(); ++F) - { - Face* XF = *F; - bb.modify(XF->v[0]->P); - bb.modify(XF->v[1]->P); - bb.modify(XF->v[2]->P); - } - - // analyze if we need to split - size.sub(bb.vMax, bb.vMin); - BOOL bSplit = FALSE; - if (size.x > c_SS_maxsize) - bSplit = TRUE; - if (size.y > c_SS_maxsize) - bSplit = TRUE; - if (size.z > c_SS_maxsize) - bSplit = TRUE; - if (int(g_XSplit[X]->size()) > c_SS_HighVertLimit) - bSplit = TRUE; - CDeflector* defl_base = (CDeflector*)g_XSplit[X]->front()->pDeflector; - if (!bSplit && defl_base) - { - if (defl_base->layer.width >= (c_LMAP_size - 2 * BORDER)) - bSplit = TRUE; - if (defl_base->layer.height >= (c_LMAP_size - 2 * BORDER)) - bSplit = TRUE; - } - - // perform subdivide if needed - if (!bSplit) - continue; - - // select longest BBox edge - int box_edge = -1; - if (size.x >= size.y && size.x >= size.z) - { - box_edge = 0; - } - else - { - if (size.y >= size.x && size.y >= size.z) - { - box_edge = 1; - } - else - { - box_edge = 2; - } - } - setup_bbs(b1, b2, bb, box_edge); - - // align plane onto vertices - - // Process all faces and rearrange them - u32 iteration_on_edge = 0; // up to 3 - u32 iteration_per_edge = 0; // up to 10 - resplit: - s2.clear(); - s1.clear(); - iteration_per_edge++; - for (vecFaceIt F = g_XSplit[X]->begin(); F != g_XSplit[X]->end(); ++F) - { - Face* XF = *F; - Fvector C; - XF->CalcCenter(C); - if (b1.contains(C)) - { - s1.push_back(XF); - } - else - { - s2.push_back(XF); - } - } - - if ((int(s1.size()) < c_SS_LowVertLimit) || (int(s2.size()) < c_SS_LowVertLimit)) - { - // splitting failed - Logger.clMsg("! ERROR: model #%d - split fail, faces: %d, s1/s2:%d/%d", X, g_XSplit[X]->size(), s1.size(), - s2.size()); - if (iteration_per_edge < 10) - { - if (g_XSplit[X]->size() > c_SS_LowVertLimit * 4) - { - if (s2.size() > s1.size()) - { // b2 -less, b1-grow - size.sub(b2.vMax, b2.vMin); - b1.vMax[box_edge] += size[box_edge] / 2; - b2.vMin[box_edge] = b1.vMax[box_edge]; - } - else - { - // b2 -grow, b1-less - size.sub(b1.vMax, b1.vMin); - b2.vMin[box_edge] -= size[box_edge] / 2; - b1.vMax[box_edge] = b2.vMin[box_edge]; - } - goto resplit; - } - } - else - { - // switch edge - iteration_per_edge = 0; - iteration_on_edge++; - if (iteration_on_edge < 3) - { - box_edge = (box_edge + 1) % 3; - setup_bbs(b1, b2, bb, box_edge); - goto resplit; - } - } - } - else - { - // split deflector into TWO - if (defl_base) - { - // _delete old deflector - for (u32 it = 0; it < lc_global_data()->g_deflectors().size(); it++) - { - if (lc_global_data()->g_deflectors()[it] == defl_base) - { - lc_global_data()->g_deflectors().erase(lc_global_data()->g_deflectors().begin() + it); - xr_delete(defl_base); - break; - } - } - - // Create _new deflectors - CDeflector* D1 = xr_new(); - // Deflector = D1; - D1->OA_Place(s1); - D1->OA_Export(); - lc_global_data()->g_deflectors().push_back(D1); - - CDeflector* D2 = xr_new(); - // Deflector = D2; - D2->OA_Place(s2); - D2->OA_Export(); - lc_global_data()->g_deflectors().push_back(D2); - } - - // Delete old SPLIT and push two new - xr_delete(g_XSplit[X]); - g_XSplit.erase(g_XSplit.begin() + X); - X--; - g_XSplit.push_back(xr_new(s1)); - Detach(&s1); - g_XSplit.push_back(xr_new(s2)); - Detach(&s2); - } - s1.clear(); - s2.clear(); - } - Logger.clMsg("%d subdivisions.", g_XSplit.size()); - validate_splits(); -} diff --git a/src/utils/xrLC/xrPhase_TangentBasis.cpp b/src/utils/xrLC/xrPhase_TangentBasis.cpp deleted file mode 100644 index 18dc97e3cbe..00000000000 --- a/src/utils/xrLC/xrPhase_TangentBasis.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "stdafx.h" -#include "build.h" - -#include "MeshMenderLayerOrdinaryStatic.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" - -static u32 find_same_vertex(const xr_vector& m, const Fvector2& Ftc, const xr_vector& theVerts) -{ - // Search - for (u32 it = 0; it < m.size(); it++) - { - u32 m_id = m[it]; - float tc[2] = {theVerts[m_id].s, theVerts[m_id].t}; - if (!fsimilar(tc[0], Ftc.x)) - continue; - if (!fsimilar(tc[1], Ftc.y)) - continue; - return m_id; - } - return u32(-1); -} - -static u32 add_vertex(const Vertex& V, const Fvector2& Ftc, xr_vector& theVerts) -{ - MeshMender::Vertex new_vertex; - set_vertex(new_vertex, V, Ftc); - theVerts.push_back(new_vertex); - return theVerts.size() - 1; -} - -static void add_face(const Face& F, xr_vector& theVerts, xr_vector& theIndices, - xr_vector>& remap) -{ - for (u32 v = 0; v < 3; v++) - { - const Vertex* V = F.v[v]; - u32 ID = u32(std::lower_bound(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end(), V) - - lc_global_data()->g_vertices().begin()); - xr_vector& m = remap[ID]; - Fvector2 Ftc = F.tc.front().uv[v]; - - u32 vertex_index = find_same_vertex(m, Ftc, theVerts); - - // Register new if not found - if (vertex_index == u32(-1)) - { - vertex_index = add_vertex(*V, Ftc, theVerts); - remap[ID].push_back(vertex_index); - } - - theIndices.push_back(vertex_index); - } -} - -static void fill_mender_input(xr_vector& theVerts, xr_vector& theIndices) -{ - // ************************************* Build vectors + expand TC if nessesary - Logger.Status("Building inputs..."); - std::sort(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end()); - xr_vector> remap; - remap.resize(lc_global_data()->g_vertices().size()); - for (u32 f = 0; f < lc_global_data()->g_faces().size(); f++) - { - Logger.Progress(float(f) / float(lc_global_data()->g_faces().size())); - Face* F = lc_global_data()->g_faces()[f]; - add_face(*F, theVerts, theIndices, remap); - } - remap.clear(); -} - -static void retrive_data_from_mender_otput( - const xr_vector& theVerts, const xr_vector& theIndices) - -{ - // ************************************* Retreive data - Logger.Status("Retreiving basis..."); - for (u32 f = 0; f < lc_global_data()->g_faces().size(); f++) - { - Face* F = lc_global_data()->g_faces()[f]; - u32 id0 = theIndices[f * 3 + 0]; // vertex index - u32 id1 = theIndices[f * 3 + 1]; // vertex index - u32 id2 = theIndices[f * 3 + 2]; // vertex index - R_ASSERT(id0 < theVerts.size()); - R_ASSERT(id1 < theVerts.size()); - R_ASSERT(id2 < theVerts.size()); - MeshMender::Vertex verts[3] = {theVerts[id0], theVerts[id1], theVerts[id2]}; - set_face(*F, verts); - } -} -static xr_vector mender_in_out_verts; -static xr_vector mender_in_out_indices; -static xr_vector mender_mapping_out_to_in_vert; - -void CBuild::xrPhase_TangentBasis() -{ - // ************************************* Declare inputs - Logger.Status("Declarator..."); - u32 v_count_reserve = iFloor(float(lc_global_data()->g_vertices().size()) * 1.33f); - u32 i_count_reserve = 3 * lc_global_data()->g_faces().size(); - - mender_in_out_verts.clear(); - mender_in_out_indices.clear(); - mender_mapping_out_to_in_vert.clear(); - - mender_in_out_verts.reserve(v_count_reserve); - mender_in_out_indices.reserve(i_count_reserve); - mender_mapping_out_to_in_vert.reserve(v_count_reserve); - - fill_mender_input(mender_in_out_verts, mender_in_out_indices); - - u32 v_was = lc_global_data()->g_vertices().size(); - u32 v_become = mender_in_out_verts.size(); - Logger.clMsg( - "duplication: was[%d] / become[%d] - %2.1f%%", v_was, v_become, 100.f * float(v_become - v_was) / float(v_was)); - - // ************************************* Perform mungle - Logger.Status("Calculating basis..."); - - MeshMender mender; - - if (!mender.Mend(mender_in_out_verts, mender_in_out_indices, mender_mapping_out_to_in_vert, 1, 0.5, 0.5, 0.0f, - MeshMender::DONT_CALCULATE_NORMALS, MeshMender::RESPECT_SPLITS, MeshMender::DONT_FIX_CYLINDRICAL)) - { - xrDebug::Fatal(DEBUG_INFO, "NVMeshMender failed "); - // xrDebug::Fatal (DEBUG_INFO,"NVMeshMender failed (%s)",mender.GetLastError().c_str()); - } - - // ************************************* Bind declarators - // bind - - retrive_data_from_mender_otput(mender_in_out_verts, mender_in_out_indices); - mender_in_out_verts.clear(); - mender_in_out_indices.clear(); - mender_mapping_out_to_in_vert.clear(); -} diff --git a/src/utils/xrLC/xrPhase_UVmap.cpp b/src/utils/xrLC/xrPhase_UVmap.cpp deleted file mode 100644 index 5e50f9254b6..00000000000 --- a/src/utils/xrLC/xrPhase_UVmap.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "stdafx.h" -#include "build.h" - -#include "utils/xrLC_Light/xrDeflector.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -void Detach(vecFace* S) -{ - map_v2v verts; - verts.clear(); - - // Collect vertices - for (vecFaceIt F = S->begin(); F != S->end(); ++F) - { - for (int i = 0; i < 3; ++i) - { - Vertex* V = (*F)->v[i]; - Vertex* VC; - map_v2v_it W = verts.find(V); // iterator - - if (W == verts.end()) - { // where is no such-vertex - VC = V->CreateCopy_NOADJ(lc_global_data()->g_vertices()); // make copy - verts.insert(std::make_pair(V, VC)); - } - else - { - // such vertex(key) already exists - update its adjacency - VC = W->second; - } - VC->prep_add(*F); - V->prep_remove(*F); - (*F)->v[i] = VC; - } - } - // vertices are already registered in container - // so we doesn't need "vers" for this time - verts.clear(); -} - -void CBuild::xrPhase_UVmap() -{ - // Main loop - Logger.Status("Processing..."); - lc_global_data()->g_deflectors().reserve(64 * 1024); - float p_cost = 1.f / float(g_XSplit.size()); - float p_total = 0.f; - vecFace faces_affected; - for (int SP = 0; SP < int(g_XSplit.size()); SP++) - { - Logger.Progress(p_total += p_cost); - - // ManOwaR, unsure: - // Call to IsolateVertices() looks useless here - // Calculation speed up, so commented - // IsolateVertices (FALSE); - - // Detect vertex-lighting and avoid this subdivision - R_ASSERT(!g_XSplit[SP]->empty()); - Face* Fvl = g_XSplit[SP]->front(); - if (Fvl->Shader().flags.bLIGHT_Vertex) - continue; // do-not touch (skip) - if (!Fvl->Shader().flags.bRendering) - continue; // do-not touch (skip) - if (Fvl->hasImplicitLighting()) - continue; // do-not touch (skip) - - // find first poly that doesn't has mapping and start recursion - while (TRUE) - { - // Select maximal sized poly - Face* msF = NULL; - float msA = 0; - for (vecFaceIt it = g_XSplit[SP]->begin(); it != g_XSplit[SP]->end(); ++it) - { - if ((*it)->pDeflector == NULL) - { - float a = (*it)->CalcArea(); - if (a > msA) - { - msF = (*it); - msA = a; - } - } - } - if (msF) - { - CDeflector* D = xr_new(); - lc_global_data()->g_deflectors().push_back(D); - // Start recursion from this face - start_unwarp_recursion(); - D->OA_SetNormal(msF->N); - - msF->OA_Unwarp(D); - // Deflector = D; - // break the cycle to startup again - D->OA_Export(); - - // Detach affected faces - faces_affected.clear(); - for (int i = 0; i < int(g_XSplit[SP]->size()); i++) - { - Face* F = (*g_XSplit[SP])[i]; - if (F->pDeflector == D) - { - faces_affected.push_back(F); - g_XSplit[SP]->erase(g_XSplit[SP]->begin() + i); - i--; - } - } - - // detaching itself - Detach(&faces_affected); - g_XSplit.push_back(xr_new(faces_affected)); - } - else - { - if (g_XSplit[SP]->empty()) - { - xr_delete(g_XSplit[SP]); - g_XSplit.erase(g_XSplit.begin() + SP); - SP--; - } - // Cancel infine loop (while) - break; - } - } - } - Logger.clMsg("%d subdivisions...", g_XSplit.size()); - err_save(); -} - -void CBuild::mem_CompactSubdivs() -{ - // Memory compact - CTimer dwT; - dwT.Start(); - vecFace temp; - for (int SP = 0; SP < int(g_XSplit.size()); SP++) - { - temp.clear(); - temp.assign(g_XSplit[SP]->begin(), g_XSplit[SP]->end()); - xr_delete(g_XSplit[SP]); - mem_Compact(); - g_XSplit[SP] = xr_new(); - g_XSplit[SP]->assign(temp.begin(), temp.end()); - } - Logger.clMsg("%d ms for memory compacting...", dwT.GetElapsed_ms()); -} -void CBuild::mem_Compact() -{ - Memory.mem_compact(); - /* - u32 bytes,blocks_used,blocks_free; - bytes = Memory.mem_usage(&blocks_used,&blocks_free); - LPCSTR h_status = 0; - if (HeapValidate (GetProcessHeap(),0,0)) h_status = "OK"; - else h_status = "DAMAGED"; - clMsg ("::MEMORY(%s):: %d MB, %d Bused, %d Bfree", - h_status,bytes/(1024*1024),blocks_used,blocks_free); - */ -} diff --git a/src/utils/xrLC/xrPreOptimize.cpp b/src/utils/xrLC/xrPreOptimize.cpp deleted file mode 100644 index 3be389b4f8c..00000000000 --- a/src/utils/xrLC/xrPreOptimize.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "stdafx.h" - -#include "build.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" - -const int HDIM_X = 56; -const int HDIM_Y = 24; -const int HDIM_Z = 56; - -// extern volatile u32 dwInvalidFaces; - -IC bool FaceEqual(Face& F1, Face& F2) -{ - // Test for 6 variations - if ((F1.v[0] == F2.v[0]) && (F1.v[1] == F2.v[1]) && (F1.v[2] == F2.v[2])) - return true; - if ((F1.v[0] == F2.v[0]) && (F1.v[2] == F2.v[1]) && (F1.v[1] == F2.v[2])) - return true; - if ((F1.v[2] == F2.v[0]) && (F1.v[0] == F2.v[1]) && (F1.v[1] == F2.v[2])) - return true; - if ((F1.v[2] == F2.v[0]) && (F1.v[1] == F2.v[1]) && (F1.v[0] == F2.v[2])) - return true; - if ((F1.v[1] == F2.v[0]) && (F1.v[0] == F2.v[1]) && (F1.v[2] == F2.v[2])) - return true; - if ((F1.v[1] == F2.v[0]) && (F1.v[2] == F2.v[1]) && (F1.v[0] == F2.v[2])) - return true; - return false; -} - -void CBuild::PreOptimize() -{ - // We use overlapping hash table to avoid boundary conflicts - vecVertex* HASH[HDIM_X + 1][HDIM_Y + 1][HDIM_Z + 1]; - Fvector VMmin, VMscale, VMeps, scale; - - // Calculate offset,scale,epsilon - Fbox bb = scene_bb; - VMscale.set(bb.vMax.x - bb.vMin.x, bb.vMax.y - bb.vMin.y, bb.vMax.z - bb.vMin.z); - VMmin.set(bb.vMin); - VMeps.set(VMscale.x / HDIM_X / 2, VMscale.y / HDIM_Y / 2, VMscale.z / HDIM_Z / 2); - VMeps.x = (VMeps.x < EPS_L) ? VMeps.x : EPS_L; - VMeps.y = (VMeps.y < EPS_L) ? VMeps.y : EPS_L; - VMeps.z = (VMeps.z < EPS_L) ? VMeps.z : EPS_L; - scale.set(float(HDIM_X), float(HDIM_Y), float(HDIM_Z)); - scale.div(VMscale); - - u32 Vcount = lc_global_data()->g_vertices().size(), Vremoved = 0; - u32 Fcount = lc_global_data()->g_faces().size(), Fremoved = 0; - - // Pre-alloc memory - int _size = (HDIM_X + 1) * (HDIM_Y + 1) * (HDIM_Z + 1); - int _average = (Vcount / _size) / 2; - if (_average < 2) - _average = 2; - { - for (int ix = 0; ix < HDIM_X + 1; ix++) - for (int iy = 0; iy < HDIM_Y + 1; iy++) - for (int iz = 0; iz < HDIM_Z + 1; iz++) - { - HASH[ix][iy][iz] = xr_new(); - HASH[ix][iy][iz]->reserve(_average); - } - } - - // - Logger.Status("Processing..."); - g_bUnregister = false; - for (int it = 0; it < (int)lc_global_data()->g_vertices().size(); it++) - { - if (0 == (it % 100000)) - { - Logger.Progress(_sqrt(float(it) / float(lc_global_data()->g_vertices().size()))); - Logger.Status("Processing... (%d verts removed)", Vremoved); - } - - if (it >= (int)lc_global_data()->g_vertices().size()) - break; - - Vertex* pTest = lc_global_data()->g_vertices()[it]; - Fvector& V = pTest->P; - - // Hash - u32 ix, iy, iz; - ix = iFloor((V.x - VMmin.x) * scale.x); - iy = iFloor((V.y - VMmin.y) * scale.y); - iz = iFloor((V.z - VMmin.z) * scale.z); - R_ASSERT(ix <= HDIM_X && iy <= HDIM_Y && iz <= HDIM_Z); - vecVertex& H = *(HASH[ix][iy][iz]); - - // Search similar vertices in hash table - for (vecVertexIt T = H.begin(); T != H.end(); ++T) - { - Vertex* pBase = *T; - if (pBase->similar(*pTest, g_params().m_weld_distance)) - { - while (pTest->m_adjacents.size()) - pTest->m_adjacents.front()->VReplace(pTest, pBase); - - lc_global_data()->destroy_vertex(lc_global_data()->g_vertices()[it]); - Vremoved += 1; - pTest = NULL; - break; - } - } - - // If we get here - there is no similar vertices - register in hash tables - if (pTest) - { - H.push_back(pTest); - - u32 ixE, iyE, izE; - ixE = iFloor((V.x + VMeps.x - VMmin.x) * scale.x); - iyE = iFloor((V.y + VMeps.y - VMmin.y) * scale.y); - izE = iFloor((V.z + VMeps.z - VMmin.z) * scale.z); - R_ASSERT(ixE <= HDIM_X && iyE <= HDIM_Y && izE <= HDIM_Z); - - if (ixE != ix) - HASH[ixE][iy][iz]->push_back(pTest); - if (iyE != iy) - HASH[ix][iyE][iz]->push_back(pTest); - if (izE != iz) - HASH[ix][iy][izE]->push_back(pTest); - if ((ixE != ix) && (iyE != iy)) - HASH[ixE][iyE][iz]->push_back(pTest); - if ((ixE != ix) && (izE != iz)) - HASH[ixE][iy][izE]->push_back(pTest); - if ((iyE != iy) && (izE != iz)) - HASH[ix][iyE][izE]->push_back(pTest); - if ((ixE != ix) && (iyE != iy) && (izE != iz)) - HASH[ixE][iyE][izE]->push_back(pTest); - } - } - - Logger.Status("Removing degenerated/duplicated faces..."); - g_bUnregister = false; - for (u32 it = 0; it < lc_global_data()->g_faces().size(); it++) - { - R_ASSERT(it >= 0 && it < (int)lc_global_data()->g_faces().size()); - Face* F = lc_global_data()->g_faces()[it]; - if (F->isDegenerated()) - { - lc_global_data()->destroy_face(lc_global_data()->g_faces()[it]); - Fremoved++; - } - else - { - // Check validity - F->Verify(); - } - Logger.Progress(float(it) / float(lc_global_data()->g_faces().size())); - } - if (InvalideFaces()) - { - err_save(); - if (!g_build_options.b_skipinvalid) - xrDebug::Fatal(DEBUG_INFO, "* FATAL: %d invalid faces. Compilation aborted", InvalideFaces()); - else - Logger.clMsg("* WARNING! Total %d invalid faces found.", InvalideFaces()); - } - - Logger.Status("Adjacency check..."); - g_bUnregister = false; - - for (u32 it = 0; it < lc_global_data()->g_vertices().size(); ++it) - { - if (lc_global_data()->g_vertices()[it] && (lc_global_data()->g_vertices()[it]->m_adjacents.empty())) - { - lc_global_data()->destroy_vertex(lc_global_data()->g_vertices()[it]); - ++Vremoved; - } - } - - Logger.Status("Cleanup..."); - lc_global_data()->g_vertices().erase( - std::remove(lc_global_data()->g_vertices().begin(), lc_global_data()->g_vertices().end(), (Vertex*)0), - lc_global_data()->g_vertices().end()); - lc_global_data()->g_faces().erase( - std::remove(lc_global_data()->g_faces().begin(), lc_global_data()->g_faces().end(), (Face*)0), - lc_global_data()->g_faces().end()); - { - for (int ix = 0; ix < HDIM_X + 1; ix++) - for (int iy = 0; iy < HDIM_Y + 1; iy++) - for (int iz = 0; iz < HDIM_Z + 1; iz++) - { - xr_delete(HASH[ix][iy][iz]); - } - } - mem_Compact(); - Logger.clMsg("%d vertices removed. (%d left)", Vcount - lc_global_data()->g_vertices().size(), - lc_global_data()->g_vertices().size()); - Logger.clMsg( - "%d faces removed. (%d left)", Fcount - lc_global_data()->g_faces().size(), lc_global_data()->g_faces().size()); - - // ------------------------------------------------------------- - /* - int err_count =0 ; - for (int _1=0; _1(bProgress, lc_global_data()->g_vertices()); } diff --git a/src/utils/xrLC/xrSaveLights.cpp b/src/utils/xrLC/xrSaveLights.cpp deleted file mode 100644 index ecb8bfd7d9a..00000000000 --- a/src/utils/xrLC/xrSaveLights.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "stdafx.h" -#include "build.h" - -void CBuild::SaveLights(IWriter& fs) -{ - fs.open_chunk(fsL_LIGHT_DYNAMIC); - for (u32 i = 0; i < L_dynamic.size(); i++) - { - b_light_dynamic& L = L_dynamic[i]; - fs.w_u32(L.controller_ID); - fs.w(&L.data, sizeof(L.data)); - } - fs.close_chunk(); -} diff --git a/src/utils/xrLC/xrSaveOGF.cpp b/src/utils/xrLC/xrSaveOGF.cpp deleted file mode 100644 index d8f781a7bd0..00000000000 --- a/src/utils/xrLC/xrSaveOGF.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "OGF_Face.h" - -SWIContainer g_SWI, x_SWI; -VBContainer g_VB, x_VB; -IBContainer g_IB, x_IB; - -bool CBuild::IsOGFContainersEmpty() -{ - return g_SWI.is_empty() && x_SWI.is_empty() && g_VB.is_empty() && x_VB.is_empty() && g_IB.is_empty() && - x_IB.is_empty(); -} - -static u32 g_batch_count; -static u32 g_batch_verts; -static u32 g_batch_faces; - -static u32 g_batch_50; -static u32 g_batch_100; -static u32 g_batch_500; -static u32 g_batch_1000; -static u32 g_batch_5000; - -u16 RegisterShader(LPCSTR T) -{ - for (u32 it = 0; it < pBuild->g_Shaders.size(); it++) - if (0 == xr_stricmp(T, pBuild->g_Shaders[it])) - return it; - pBuild->g_Shaders.push_back(xr_strdup(T)); - return pBuild->g_Shaders.size() - 1; -} - -void geom_batch_average(u32 verts, u32 faces) -{ - // clMsg ("* batch[%d], %d verts, %d faces",g_batch_count,verts,faces); - g_batch_count++; - g_batch_verts += verts; - g_batch_faces += faces; - - if (faces <= 50) - g_batch_50++; - else if (faces <= 100) - g_batch_100++; - else if (faces <= 500) - g_batch_500++; - else if (faces <= 1000) - g_batch_1000++; - else if (faces <= 5000) - g_batch_5000++; -} - -static bool remap_order(u32 id0, u32 id1) -{ - OGF* o0 = (OGF*)g_tree[id0]; - OGF* o1 = (OGF*)g_tree[id1]; - return xr_strcmp(*o0->textures.front().name, *o1->textures.front().name) < 0; -} - -static void SaveGEOMs(LPCSTR fn, VBContainer& vb, IBContainer& ib, SWIContainer& swi) -{ - Logger.Status("Geometry '%s'...", fn); - // geometry - string_path lfn; - IWriter* file; - file = FS.w_open(strconcat(sizeof(lfn), lfn, pBuild->path, fn)); - hdrLEVEL H; - H.XRLC_version = XRCL_PRODUCTION_VERSION; - file->w_chunk(fsL_HEADER, &H, sizeof(H)); - - // verts - file->open_chunk(fsL_VB); - vb.Save(*file); - file->close_chunk(); - - // indices - file->open_chunk(fsL_IB); - ib.Save(*file); - file->close_chunk(); - - // swis - file->open_chunk(fsL_SWIS); - swi.Save(*file); - file->close_chunk(); -} - -void CBuild::SaveTREE(IWriter& fs) -{ - CMemoryWriter MFS; - - Logger.Status("Geometry buffers..."); - xr_vector remap; - remap.reserve(g_tree.size()); - for (u32 rid = 0; rid < g_tree.size(); rid++) - { - OGF* o = dynamic_cast(g_tree[rid]); - if (o) - remap.push_back(rid); - } - std::stable_sort(remap.begin(), remap.end(), remap_order); - Logger.clMsg("remap-size: %d / %d", remap.size(), g_tree.size()); - for (u32 sid = 0; sid < remap.size(); sid++) - { - u32 id = remap[sid]; - // clMsg ("%3d: subdiv: %d",sid,id); - g_tree[id]->PreSave(id); - } - - Logger.Status("Visuals..."); - fs.open_chunk(fsL_VISUALS); - for (xr_vector::iterator it = g_tree.begin(); it != g_tree.end(); ++it) - { - u32 idx = u32(it - g_tree.begin()); - MFS.open_chunk(idx); - (*it)->Save(MFS); - MFS.close_chunk(); - Logger.Progress(float(idx) / float(g_tree.size())); - } - fs.w(MFS.pointer(), MFS.size()); - fs.close_chunk(); - Logger.clMsg("Average: %d verts/%d faces, 50(%2.1f), 100(%2.1f), 500(%2.1f), 1000(%2.1f), 5000(%2.1f)", - g_batch_verts / g_batch_count, g_batch_faces / g_batch_count, 100.f * float(g_batch_50) / float(g_batch_count), - 100.f * float(g_batch_100) / float(g_batch_count), 100.f * float(g_batch_500) / float(g_batch_count), - 100.f * float(g_batch_1000) / float(g_batch_count), 100.f * float(g_batch_5000) / float(g_batch_count)); - mem_Compact(); - - SaveGEOMs("level.geom", g_VB, g_IB, g_SWI); // Normal - SaveGEOMs("level.geomx", x_VB, x_IB, x_SWI); // Fast-Path - - Logger.Status("Shader table..."); - fs.open_chunk(fsL_SHADERS); - fs.w_u32(g_Shaders.size()); - for (xr_vector::iterator T = g_Shaders.begin(); T != g_Shaders.end(); ++T) - fs.w_stringZ(*T); - fs.close_chunk(); - // mem_Compact (); -} diff --git a/src/utils/xrLC/xrSectors.cpp b/src/utils/xrLC/xrSectors.cpp deleted file mode 100644 index e76337f6bac..00000000000 --- a/src/utils/xrLC/xrSectors.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "sector.h" -#include "OGF_Face.h" -xr_vector g_sectors; - -void CBuild::BuildSectors() -{ - Logger.Status("Determining sectors..."); - Logger.Progress(0); - u32 SectorMax = 0; - for (u32 I = 0; I < g_tree.size(); I++) - if (g_tree[I]->Sector > SectorMax) - SectorMax = g_tree[I]->Sector; - R_ASSERT(SectorMax < 0xffff); - - u32 SectorCount = SectorMax + 1; - g_sectors.resize(SectorCount); - ZeroMemory(&*g_sectors.begin(), (u32)g_sectors.size() * sizeof(void*)); - Logger.clMsg("%d sectors accepted.", SectorCount); - - Logger.Status("Spatializing geometry..."); - for (u32 I = 0; I < g_tree.size(); I++) - { - u32 Sector = g_tree[I]->Sector; - if (0 == g_sectors[Sector]) - g_sectors[Sector] = xr_new(Sector); - } - - Logger.Status("Building hierrarhy..."); - for (u32 I = 0; I < g_sectors.size(); I++) - { - R_ASSERT(g_sectors[I]); - g_sectors[I]->BuildHierrarhy(); - Logger.Progress(float(I) / float(g_sectors.size())); - } - - Logger.Status("Assigning portals, occluders, glows, lights..."); - // portals - for (u32 I = 0; I < portals.size(); I++) - { - b_portal& P = portals[I]; - R_ASSERT(u32(P.sector_front) < g_sectors.size()); - R_ASSERT(u32(P.sector_back) < g_sectors.size()); - g_sectors[u32(P.sector_front)]->add_portal(u16(I)); - g_sectors[u32(P.sector_back)]->add_portal(u16(I)); - } - // glows - for (u32 I = 0; I < glows.size(); I++) - { - b_glow& G = glows[I]; - b_material& M = materials()[G.dwMaterial]; - R_ASSERT(M.sector < g_sectors.size()); - g_sectors[M.sector]->add_glow(u16(I)); - } - // lights - for (u32 I = 0; I < L_dynamic.size(); I++) - { - b_light_dynamic& L = L_dynamic[I]; - if (L.data.type == Flight::Type::Directional) - { - for (u32 j = 0; j < g_sectors.size(); j++) - { - R_ASSERT(g_sectors[j]); - g_sectors[j]->add_light(u16(I)); - } - } - else - { - if (L.sectors.size()) - { - for (u32 j = 0; j < L.sectors.size(); j++) - { - R_ASSERT(L.sectors[j] < g_sectors.size()); - g_sectors[L.sectors[j]]->add_light(u16(I)); - } - } - else - { - Logger.clMsg("Fuck!!! Light at position %f,%f,%f non associated!!!", L.data.position.x, - L.data.position.y, L.data.position.z); - } - } - } -} - -void CBuild::SaveSectors(IWriter& fs) -{ - CMemoryWriter MFS; - Logger.Status("Processing..."); - - // validate & save - for (u32 I = 0; I < g_sectors.size(); I++) - { - MFS.open_chunk(I); - g_sectors[I]->Validate(); - g_sectors[I]->Save(MFS); - MFS.close_chunk(); - Logger.Progress(float(I) / float(g_sectors.size())); - } - - fs.w_chunk(fsL_SECTORS, MFS.pointer(), MFS.size()); -} diff --git a/src/utils/xrLC/xrT_Junction.cpp b/src/utils/xrLC/xrT_Junction.cpp deleted file mode 100644 index 7f70241dc23..00000000000 --- a/src/utils/xrLC/xrT_Junction.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "stdafx.h" -#include "build.h" -#include "utils/xrLC_Light/xrLC_GlobalData.h" -#include "utils/xrLC_Light/xrface.h" -//#define VPUSH(a) ((a).x), ((a).y), ((a).z) - -IC float SqrDistance2Segment(const Fvector& P, const Fvector& A, const Fvector& B) -{ - // Determine t (the length of the vector from ‘a’ to ‘p’) - Fvector c; - c.sub(P, A); - Fvector V; - V.sub(B, A); - - float d = V.magnitude(); - - V.div(d); - float t = V.dotproduct(c); - - // Check to see if ‘t’ is beyond the extents of the line segment - if (t <= 0.0f) - return P.distance_to_sqr(A); - if (t >= d) - return P.distance_to_sqr(B); - - // Return the point between ‘a’ and ‘b’ - // set length of V to t. V is normalized so this is easy - Fvector R; - R.mad(A, V, t); - return P.distance_to_sqr(R); -} - -struct record -{ - Vertex *E1, *E2; - Vertex* T; -}; - -static xr_vector* vecJunctions; -static xr_vector* vecEdges; - -static void check(Vertex* vE1, Vertex* vE2, Vertex* vTEST) -{ - if (_sqrt(SqrDistance2Segment(vTEST->P, vE1->P, vE2->P)) < 0.002f) - { - BOOL bWeld = FALSE; - - // check for duplicated errors - if (vE1 > vE2) - std::swap(vE1, vE2); - for (u32 i = 0; i < vecJunctions->size(); i++) - { - record& rec = (*vecJunctions)[i]; - if (rec.T == vTEST) - return; - if (rec.T->P.similar(vTEST->P, .002f)) - bWeld = TRUE; - } - - // register - record rec; - rec.E1 = vE1; - rec.E2 = vE2; - rec.T = vTEST; - vecJunctions->push_back(rec); - - // display - // if (bWeld) clMsg ("ERROR. unwelded vertex [%3.1f,%3.1f,%3.1f]", VPUSH(vTEST->P)); - // else clMsg ("ERROR. T-junction at vertex [%3.1f,%3.1f,%3.1f]", VPUSH(vTEST->P)); - // pBuild->err_tjunction.w_fvector3 (vTEST->P); - } -} - -static void edge(Vertex* vE1, Vertex* vE2) -{ - float len = vE1->P.distance_to(vE2->P); - if (len < 32.f) - return; - - // check for duplicated errors - if (vE1 > vE2) - std::swap(vE1, vE2); - for (u32 i = 0; i < vecEdges->size(); i++) - { - record& rec = (*vecEdges)[i]; - if ((rec.E1 == vE1) && (rec.E2 == vE2)) - return; - } - - // register - record rec; - rec.E1 = vE1; - rec.E2 = vE2; - rec.T = 0; - vecEdges->push_back(rec); - - // clMsg ("ERROR: too long edge %3.1fm [%3.1f,%3.1f,%3.1f] - - // [%3.1f,%3.1f,%3.1f]",len,VPUSH(vE1->P),VPUSH(vE2->P)); -} - -void CBuild::CorrectTJunctions() -{ - Logger.Status("Processing..."); - vecJunctions = xr_new>(); - vecJunctions->reserve(1024); - vecEdges = xr_new>(); - vecEdges->reserve(1024); - - for (u32 I = 0; I < lc_global_data()->g_faces().size(); ++I) - { - Face* F = lc_global_data()->g_faces()[I]; - - // Iterate on edges - for (u32 e = 0; e < 3; ++e) - { - Vertex *vA, *vB; - F->EdgeVerts(e, &vA, &vB); - - // Iterate on 'vA'-adjacent faces - for (u32 f1 = 0; f1 != vA->m_adjacents.size(); ++f1) - { - Face* F1 = vA->m_adjacents[f1]; - - // Iterate on it's edges - for (u32 e1 = 0; e1 < 3; ++e1) - { - Vertex *v1, *v2; - F1->EdgeVerts(e1, &v1, &v2); - edge(v1, v2); - - if (v1 == vA && v2 != vB) - check(vA, vB, v2); - else if (v2 == vA && v1 != vB) - check(vA, vB, v1); - } - } - // Iterate on 'vB'-adjacent faces - for (u32 f2 = 0; f2 != vB->m_adjacents.size(); ++f2) - { - Face* F2 = vB->m_adjacents[f2]; - - // Iterate on it's edges - for (u32 e1 = 0; e1 < 3; ++e1) - { - Vertex *v1, *v2; - F2->EdgeVerts(e1, &v1, &v2); - edge(v1, v2); - if (v1 == vB && v2 != vA) - check(vA, vB, v2); - else if (v2 == vB && v1 != vA) - check(vA, vB, v1); - } - } - } - Logger.Progress(float(I) / float(lc_global_data()->g_faces().size())); - } - Logger.clMsg("*** %d junctions and %d long edges found.", vecJunctions->size(), vecEdges->size()); - - xr_delete(vecJunctions); - xr_delete(vecEdges); -} diff --git a/src/utils/xrLCUtil/CMakeLists.txt b/src/utils/xrLCUtil/CMakeLists.txt deleted file mode 100644 index 14f6f16ca2a..00000000000 --- a/src/utils/xrLCUtil/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -add_library(xrLCUtil SHARED) - -target_sources(xrLCUtil PRIVATE - #ILevelCompilerLogger.hpp - #LevelCompilerLoggerWindow.hpp - #LevelCompilerLoggerWindow.cpp - pch.cpp - pch.cpp - resource.h - xrLCUtil.hpp - xrLCUtil.cpp - xrThread.hpp - xrThread.cpp -) - -target_include_directories(xrLCUtil - PRIVATE - "${CMAKE_SOURCE_DIR}/src" -) - -target_link_libraries(xrLCUtil - PRIVATE - xrCore -) - -target_compile_definitions(xrLCUtil - PRIVATE - LEVEL_COMPILER - XRLCUTIL_EXPORTS - _USE_MATH_DEFINES -) - -set_target_properties(xrLCUtil PROPERTIES - PREFIX "" -) - -target_precompile_headers(xrLCUtil - PRIVATE - pch.hpp -) diff --git a/src/utils/xrLCUtil/ILevelCompilerLogger.hpp b/src/utils/xrLCUtil/ILevelCompilerLogger.hpp deleted file mode 100644 index 6b0ab401308..00000000000 --- a/src/utils/xrLCUtil/ILevelCompilerLogger.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "xrLCUtil.hpp" - -class XRLCUTIL_API ILevelCompilerLogger -{ -protected: - ILevelCompilerLogger() {} -public: - virtual void Initialize(const char* name) = 0; - virtual void Destroy() = 0; - virtual void clMsg(const char* format, ...) = 0; - virtual void clMsgV(const char* format, va_list args) = 0; - virtual void clLog(const char* format, ...) = 0; - virtual void Status(const char* format, ...) = 0; - virtual void StatusV(const char* format, va_list args) = 0; - virtual void Progress(float progress) = 0; - virtual void Phase(const char* phaseName) = 0; - virtual void Success(const char* msg) = 0; - virtual void Failure(const char* msg) = 0; -}; diff --git a/src/utils/xrLCUtil/LevelCompilerLoggerWindow.cpp b/src/utils/xrLCUtil/LevelCompilerLoggerWindow.cpp deleted file mode 100644 index f8503dcca93..00000000000 --- a/src/utils/xrLCUtil/LevelCompilerLoggerWindow.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "pch.hpp" -#include "LevelCompilerLoggerWindow.hpp" -#include "resource.h" -#include "xrCore/xrCore.h" -#include -#include -#include - -LevelCompilerLoggerWindow::LevelCompilerLoggerWindow() -{ - *status = 0; - *phase = 0; -} - -void LevelCompilerLoggerWindow::Initialize(const char* name) -{ - if (initialized) - return; - InitCommonControls(); - Sleep(150); - xr_strcpy(this->name, name); - Threading::SpawnThread(LogThreadProc, "log-update", 1024 * 1024, this); - while (!logWindow) - Sleep(150); - initialized = true; -} - -void LevelCompilerLoggerWindow::Destroy() -{ - close = true; - Sleep(500); -} - -void LevelCompilerLoggerWindow::LogThreadProc(void* context) -{ - auto ptr = static_cast(context); - ptr->LogThreadProc(); -} - -static INT_PTR CALLBACK LevelCompilerLoggerWindowDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) -{ - switch (msg) - { - case WM_DESTROY: break; - case WM_CLOSE: ExitProcess(0); break; - case WM_COMMAND: - if (LOWORD(wp) == IDCANCEL) - ExitProcess(0); - break; - default: return FALSE; - } - return TRUE; -} - -void LevelCompilerLoggerWindow::LogThreadProc() -{ - SetProcessPriorityBoost(GetCurrentProcess(), TRUE); - logWindow = - CreateDialog(HINSTANCE(GetModuleHandle("xrLCUtil")), MAKEINTRESOURCE(IDD_LOG), 0, LevelCompilerLoggerWindowDlgProc); - if (!logWindow) - R_CHK(GetLastError()); - SetWindowText(logWindow, name); - SetWindowPos(logWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - hwLog = GetDlgItem(logWindow, IDC_LOG); - hwProgress = GetDlgItem(logWindow, IDC_PROGRESS); - hwInfo = GetDlgItem(logWindow, IDC_INFO); - hwStage = GetDlgItem(logWindow, IDC_STAGE); - hwTime = GetDlgItem(logWindow, IDC_TIMING); - hwPText = GetDlgItem(logWindow, IDC_P_TEXT); - hwPhaseTime = GetDlgItem(logWindow, IDC_PHASE_TIME); - SendMessage(hwProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 1000)); - SendMessage(hwProgress, PBM_SETPOS, 0, 0); - Msg("\"LevelBuilder v4.1\" beta build\nCompilation date: %s\n", __DATE__); - { - char tmpbuf[128]; - Msg("Startup time: %s", _strtime(tmpbuf)); - } - BOOL bHighPriority = FALSE; - string256 u_name; - unsigned long u_size = sizeof(u_name) - 1; - GetUserName(u_name, &u_size); - xr_strlwr(u_name); - if (!xr_strcmp(u_name, "oles") || !xr_strcmp(u_name, "alexmx")) - bHighPriority = TRUE; - // Main cycle - u32 LogSize = 0; - float PrSave = 0; - while (true) - { - SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); - // transfer data - while (!csLog.TryEnter()) - { - ProcessMessages(); - Sleep(1); - } - if (progress > 1.f) - progress = 1.f; - else if (progress < 0) - progress = 0; - BOOL bWasChanges = FALSE; - char tbuf[256]; - csLog.Enter(); - if (LogSize != LogFile.size()) - { - bWasChanges = TRUE; - for (; LogSize < LogFile.size(); LogSize++) - { - const char* S = LogFile[LogSize].c_str(); - if (!S) - S = ""; - SendMessage(hwLog, LB_ADDSTRING, 0, (LPARAM)S); - } - SendMessage(hwLog, LB_SETTOPINDEX, LogSize - 1, 0); - FlushLog(); - } - csLog.Leave(); - if (_abs(PrSave - progress) > EPS_L) - { - bWasChanges = TRUE; - PrSave = progress; - SendMessage(hwProgress, PBM_SETPOS, u32(progress * 1000.f), 0); - // timing - if (progress > 0.005f) - { - u32 dwCurrentTime = CPU::GetTicks(); - u32 dwTimeDiff = dwCurrentTime - phase_start_time; - u32 secElapsed = dwTimeDiff / 1000; - u32 secRemain = u32(float(secElapsed) / progress) - secElapsed; - xr_sprintf(tbuf, - "Elapsed: %s\n" - "Remain: %s", - make_time(secElapsed).c_str(), make_time(secRemain).c_str()); - SetWindowText(hwTime, tbuf); - } - else - SetWindowText(hwTime, ""); - // percentage text - xr_sprintf(tbuf, "%3.2f%%", progress * 100.f); - SetWindowText(hwPText, tbuf); - } - if (bStatusChange) - { - bWasChanges = TRUE; - bStatusChange = FALSE; - SetWindowText(hwInfo, status); - } - if (bWasChanges) - { - UpdateWindow(logWindow); - bWasChanges = FALSE; - } - csLog.Leave(); - ProcessMessages(); - if (close) - break; - Sleep(200); - } - // Cleanup - DestroyWindow(logWindow); -} - -void LevelCompilerLoggerWindow::ProcessMessages() -{ - MSG msg; - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -void LevelCompilerLoggerWindow::clMsg(const char* format, ...) -{ - va_list args; - va_start(args, format); - clMsgV(format, args); - va_end(args); -} - -void LevelCompilerLoggerWindow::clMsgV(const char* format, va_list args) -{ - char buf[1024]; - vsprintf(buf, format, args); - csLog.Enter(); - string1024 msg; - strconcat(sizeof(msg), msg, " | | ", buf); - Log(msg); - csLog.Leave(); -} - -void LevelCompilerLoggerWindow::clLog(const char* format, ...) -{ - va_list args; - char buf[1024]; - va_start(args, format); - vsprintf(buf, format, args); - va_end(args); - csLog.Enter(); - Log(buf); - csLog.Leave(); -} - -void LevelCompilerLoggerWindow::Status(const char* format, ...) -{ - va_list args; - va_start(args, format); - StatusV(format, args); - va_end(args); -} - -void LevelCompilerLoggerWindow::StatusV(const char* format, va_list args) -{ - char buf[1024]; - vsprintf(buf, format, args); - csLog.Enter(); - xr_strcpy(status, buf); - bStatusChange = true; - Msg(" | %s", buf); - csLog.Leave(); -} - -void LevelCompilerLoggerWindow::Progress(float progress) { this->progress = progress; } -void LevelCompilerLoggerWindow::Phase(const char* phaseName) -{ - while (!(hwPhaseTime && hwStage)) - Sleep(1); - csLog.Enter(); - // Replace phase name with TIME:Name - char tbuf[512]; - bPhaseChange = TRUE; - phase_total_time = CPU::GetTicks() - phase_start_time; - xr_sprintf(tbuf, "%s : %s", make_time(phase_total_time / 1000).c_str(), phase); - SendMessage(hwPhaseTime, LB_DELETESTRING, SendMessage(hwPhaseTime, LB_GETCOUNT, 0, 0) - 1, 0); - SendMessage(hwPhaseTime, LB_ADDSTRING, 0, (LPARAM)tbuf); - // Start new phase - phase_start_time = CPU::GetTicks(); - xr_strcpy(phase, phaseName); - SetWindowText(hwStage, phaseName); - xr_sprintf(tbuf, "--:--:-- * %s", phase); - SendMessage(hwPhaseTime, LB_ADDSTRING, 0, (LPARAM)tbuf); - SendMessage(hwPhaseTime, LB_SETTOPINDEX, SendMessage(hwPhaseTime, LB_GETCOUNT, 0, 0) - 1, 0); - progress = 0; - // Release focus - Msg("\n* New phase started: %s", phaseName); - csLog.Leave(); -} - -void LevelCompilerLoggerWindow::Success(const char* msg) -{ - MessageBox(logWindow, msg, "Congratulation!", MB_OK | MB_ICONINFORMATION); -} - -void LevelCompilerLoggerWindow::Failure(const char* msg) { MessageBox(logWindow, msg, "Error!", MB_OK | MB_ICONERROR); } -HWND LevelCompilerLoggerWindow::GetWindow() const { return logWindow; } - -LevelCompilerLoggerWindow & LevelCompilerLoggerWindow::instance() -{ - static LevelCompilerLoggerWindow instance; - return instance; -} diff --git a/src/utils/xrLCUtil/LevelCompilerLoggerWindow.hpp b/src/utils/xrLCUtil/LevelCompilerLoggerWindow.hpp deleted file mode 100644 index b7e3daa20fc..00000000000 --- a/src/utils/xrLCUtil/LevelCompilerLoggerWindow.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once -#include "ILevelCompilerLogger.hpp" -#include "xrCore/Threading/Lock.hpp" - -class XRLCUTIL_API LevelCompilerLoggerWindow : public ILevelCompilerLogger -{ -private: - bool initialized = false; - HWND logWindow = 0; - HWND hwLog = 0; - HWND hwProgress = 0; - HWND hwInfo = 0; - HWND hwStage = 0; - HWND hwTime = 0; - HWND hwPText = 0; - HWND hwPhaseTime = 0; - Lock csLog -#ifdef CONFIG_PROFILE_LOCKS - (MUTEX_PROFILE_ID(csLog)) -#endif - ; - volatile bool close = false; - char name[256]; - char status[1024]; - char phase[1024]; - float progress = 0.0f; - u32 phase_start_time = 0; - bool bStatusChange = false; - bool bPhaseChange = false; - u32 phase_total_time = 0; - -protected: - LevelCompilerLoggerWindow(); -public: - virtual void Initialize(const char* name) override; - virtual void Destroy() override; - virtual void clMsg(const char* format, ...) override; - virtual void clMsgV(const char* format, va_list args) override; - virtual void clLog(const char* format, ...) override; - virtual void Status(const char* format, ...) override; - virtual void StatusV(const char* format, va_list args) override; - virtual void Progress(float f) override; - virtual void Phase(const char* phaseName) override; - virtual void Success(const char* msg) override; - virtual void Failure(const char* msg) override; - HWND GetWindow() const; - static LevelCompilerLoggerWindow& instance(); - -private: - static void LogThreadProc(void* context); - void LogThreadProc(); - void ProcessMessages(); -}; diff --git a/src/utils/xrLCUtil/packages.config b/src/utils/xrLCUtil/packages.config deleted file mode 100644 index 7539664cbfc..00000000000 --- a/src/utils/xrLCUtil/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/utils/xrLCUtil/pch.cpp b/src/utils/xrLCUtil/pch.cpp deleted file mode 100644 index 3854579ae1c..00000000000 --- a/src/utils/xrLCUtil/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.hpp" diff --git a/src/utils/xrLCUtil/pch.hpp b/src/utils/xrLCUtil/pch.hpp deleted file mode 100644 index 7fab33a4b13..00000000000 --- a/src/utils/xrLCUtil/pch.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "Common/Common.hpp" -#include "xrLCUtil.hpp" -#include "xrCore/_std_extensions.h" diff --git a/src/utils/xrLCUtil/resource.h b/src/utils/xrLCUtil/resource.h deleted file mode 100644 index 133cc93890e..00000000000 --- a/src/utils/xrLCUtil/resource.h +++ /dev/null @@ -1,33 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDDEBUG 3 -#define IDD_LOG 101 -#define IDD_VERIFY 104 -#define IDD_STEP 105 -#define IDC_LOG 1000 -#define IDC_FILE 1001 -#define IDC_LINE 1002 -#define IDC_DESC 1003 -#define IDSTOP 1004 -#define IDSTOP2 1005 -#define IDC_STACK 1006 -#define IDC_PROGRESS 1008 -#define IDC_STAGE 1010 -#define IDC_INFO 1011 -#define IDC_TIMING 1012 -#define IDC_P_TEXT 1013 -#define IDC_PHASE_TIME 1014 -#define IDC_PROGRESS1 1015 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1016 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/utils/xrLCUtil/resource.rc b/src/utils/xrLCUtil/resource.rc deleted file mode 100644 index b4da9718d4a..00000000000 --- a/src/utils/xrLCUtil/resource.rc +++ /dev/null @@ -1,150 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian (Russia) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_VERIFY DIALOGEX 0, 0, 265, 106 -STYLE DS_ABSALIGN | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "XRay Engine Internal Error" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Stop",IDSTOP,204,72,60,14,BS_FLAT - GROUPBOX "Description",IDC_STATIC,0,0,265,45,BS_FLAT - GROUPBOX "Source File",IDC_STATIC,0,48,200,20,BS_FLAT - GROUPBOX "Line",IDC_STATIC,204,48,60,20,BS_FLAT - LTEXT "",IDC_FILE,4,56,191,8 - LTEXT "",IDC_LINE,209,56,51,8 - LTEXT "",IDC_DESC,5,7,255,35 - PUSHBUTTON "Debug",IDDEBUG,204,90,60,14,BS_FLAT -END - -IDD_LOG DIALOGEX 0, 0, 504, 324 -STYLE DS_ABSALIGN | DS_SETFONT | DS_MODALFRAME | DS_NOFAILCREATE | DS_CENTER | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU -CAPTION "XRay Engine Components Compiler" -FONT 10, "Lucida Console", 400, 0, 0xCC -BEGIN - LISTBOX IDC_LOG,0,0,345,253,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_VSCROLL - CTEXT "Starting...",IDC_STAGE,0,255,345,17,SS_CENTERIMAGE | SS_SUNKEN - CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH,0,309,311,14 - GROUPBOX "Stage information",IDC_STATIC,0,273,218,35 - LTEXT "",IDC_INFO,5,281,207,22 - GROUPBOX "Phase Timing",IDC_STATIC,220,274,125,34 - LTEXT "",IDC_TIMING,225,283,115,19 - CTEXT "",IDC_P_TEXT,313,309,32,14,SS_CENTERIMAGE | SS_SUNKEN - LISTBOX IDC_PHASE_TIME,346,0,158,323,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_VSCROLL -END - -IDD_STEP DIALOGEX 0, 0, 100, 15 -STYLE DS_ABSALIGN | DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_VISIBLE -EXSTYLE WS_EX_NOPARENTNOTIFY -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "Next",IDOK,0,0,50,14,BS_VCENTER | BS_FLAT - PUSHBUTTON "Debug",IDCANCEL,50,0,50,14,BS_FLAT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_VERIFY, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 258 - TOPMARGIN, 7 - BOTTOMMARGIN, 99 - END - - IDD_LOG, DIALOG - BEGIN - RIGHTMARGIN, 432 - BOTTOMMARGIN, 323 - END - - IDD_STEP, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 93 - TOPMARGIN, 7 - BOTTOMMARGIN, 8 - END -END -#endif // APSTUDIO_INVOKED - -#endif // Russian (Russia) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Ukrainian (Ukraine) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR) -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Ukrainian (Ukraine) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/utils/xrLCUtil/xrLCUtil.cpp b/src/utils/xrLCUtil/xrLCUtil.cpp deleted file mode 100644 index 0b55d02e51f..00000000000 --- a/src/utils/xrLCUtil/xrLCUtil.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "pch.hpp" -#include "xrLCUtil.hpp" - -std::string make_time(u32 sec) -{ - char buf[64]; - xr_sprintf(buf, "%2.0d:%2.0d:%2.0d", sec / 3600, (sec % 3600) / 60, sec % 60); - int len = int(xr_strlen(buf)); - for (int i = 0; i < len; i++) - { - if (buf[i] == ' ') - buf[i] = '0'; - } - return std::string(buf); -} diff --git a/src/utils/xrLCUtil/xrLCUtil.hpp b/src/utils/xrLCUtil/xrLCUtil.hpp deleted file mode 100644 index 5e0b92cedc6..00000000000 --- a/src/utils/xrLCUtil/xrLCUtil.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "xrCore/xrCore.h" - -#ifdef XR_PLATFORM_WINDOWS -#pragma comment(lib, "winmm.lib") -#pragma comment(lib, "comctl32.lib") -#endif - -#ifdef XRAY_STATIC_BUILD -#define XRLCUTIL_API -#else -# ifdef XRLCUTIL_EXPORTS -# define XRLCUTIL_API XR_EXPORT -# else -# define XRLCUTIL_API XR_IMPORT -# endif -#endif - -XRLCUTIL_API std::string make_time(u32 sec); diff --git a/src/utils/xrLCUtil/xrLCUtil.vcxproj b/src/utils/xrLCUtil/xrLCUtil.vcxproj deleted file mode 100644 index 699a3106106..00000000000 --- a/src/utils/xrLCUtil/xrLCUtil.vcxproj +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - {B90BDC22-A891-4B33-B562-29D701F65DBD} - xrLCUtil - Win32Proj - xrLCUtil - - - - - - - DynamicLibrary - - - - - - - - - - - $(xrBinDir)utils\ - - - - $(SolutionDir)xrQSlim;$(xrSdkDir)include\FreeImage;$(xrExternals)zlib;%(AdditionalIncludeDirectories) - _USRDLL;LEVEL_COMPILER;XRLCUTIL_EXPORTS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;%(PreprocessorDefinitions) - pch.hpp - - - - - - Create - - - - - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {745dec58-ebb3-47a9-a9b8-4c6627c01bf8} - - - - - - - - - - - - - - - - Document - - - Document - - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - \ No newline at end of file diff --git a/src/utils/xrLCUtil/xrLCUtil.vcxproj.filters b/src/utils/xrLCUtil/xrLCUtil.vcxproj.filters deleted file mode 100644 index 1145a51b4e3..00000000000 --- a/src/utils/xrLCUtil/xrLCUtil.vcxproj.filters +++ /dev/null @@ -1,62 +0,0 @@ - - - - - {1f677f1a-a814-4452-b4bb-80263d3081ee} - - - {c83d0e8b-8f2a-488a-bd7c-06d8f90ea714} - - - {a7a76833-7825-4223-a93e-27c5b9c322bc} - - - {3482a33e-8d3f-4f06-b322-8778dd5f3d37} - - - - - Threading - - - Kernel - - - Log - - - - - - Threading - - - Kernel - - - Log - - - Resources - - - Log - - - - - - Resources - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrLCUtil/xrThread.cpp b/src/utils/xrLCUtil/xrThread.cpp deleted file mode 100644 index 26950b663ab..00000000000 --- a/src/utils/xrLCUtil/xrThread.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "pch.hpp" -#include "xrThread.hpp" - -void CThread::StubLog(const char*, ...) {} -void CThread::startup(void* P) -{ - CThread* T = (CThread*)P; - - if (T->thMessages) - T->log("* THREAD #%d: Started.", T->thID); - FPU::m64r(); - T->Execute(); - T->thCompleted = TRUE; - if (T->thMessages) - T->log("* THREAD #%d: Task Completed.", T->thID); -} - -void CThreadManager::start(CThread* T) -{ - R_ASSERT(T); - threads.push_back(T); - T->Start(); -} - -void CThreadManager::wait(u32 sleep_time) -{ - // Wait for completition - char perf[1024]; - if (threads.empty()) - return; - for (;;) - { - Sleep(sleep_time); - - perf[0] = 0; - float sumProgress = 0; - float sumPerformance = 0; - u32 sumComplete = 0; - for (u32 ID = 0; ID < threads.size(); ID++) - { - sumProgress += threads[ID]->thProgress; - sumComplete += threads[ID]->thCompleted ? 1 : 0; - sumPerformance += threads[ID]->thPerformance; - - char P[64]; - if (ID) - xr_sprintf(P, "*%3.1f", threads[ID]->thPerformance); - else - xr_sprintf(P, " %3.1f", threads[ID]->thPerformance); - xr_strcat(perf, P); - } - if (threads[0]->thMonitor) - { - reportStatus("Performance: %3.1f :%s", sumPerformance, perf); - } - reportProgress(sumProgress / float(threads.size())); - if (sumComplete == threads.size()) - break; - } - - // Delete threads - for (u32 thID = 0; thID < threads.size(); thID++) - if (threads[thID]->thDestroyOnComplete) - xr_delete(threads[thID]); - threads.clear(); -} - -void CThreadManager::StubReportStatus(const char*, ...) {} -void CThreadManager::StubReportProgress(float) {} diff --git a/src/utils/xrLCUtil/xrThread.hpp b/src/utils/xrLCUtil/xrThread.hpp deleted file mode 100644 index d224e827b37..00000000000 --- a/src/utils/xrLCUtil/xrThread.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once -#include "xrLCUtil.hpp" - -class XRLCUTIL_API CThread -{ -public: - using LogFunc = void (*)(const char* format, ...); - -private: - volatile LogFunc log; - static void startup(void* P); - static void StubLog(const char*, ...); - -public: - volatile u32 thID; - volatile float thProgress; - volatile BOOL thCompleted; - volatile BOOL thMessages; - volatile BOOL thMonitor; - volatile float thPerformance; - volatile BOOL thDestroyOnComplete; - - CThread(u32 id, LogFunc log) - { - this->log = log ? log : StubLog; - thID = id; - thProgress = 0; - thCompleted = FALSE; - thMessages = TRUE; - thMonitor = FALSE; - thDestroyOnComplete = TRUE; - } - virtual ~CThread() {} - void Start() { Threading::SpawnThread(startup, "worker-thread", 1024 * 1024, this); } - virtual void Execute() = 0; -}; - -class XRLCUTIL_API CThreadManager -{ -public: - using ReportStatusFunc = void (*)(const char* format, ...); - using ReportProgressFunc = void (*)(float f); - void start(CThread* T); - void wait(u32 sleep_time = 1000); - -private: - static void StubReportStatus(const char*, ...); - static void StubReportProgress(float); - xr_vector threads; - ReportStatusFunc reportStatus; - ReportProgressFunc reportProgress; - -public: - CThreadManager(ReportStatusFunc reportStatus, ReportProgressFunc reportProgress) - { - this->reportStatus = reportStatus ? reportStatus : StubReportStatus; - this->reportProgress = reportProgress ? reportProgress : StubReportProgress; - } -}; - -IC void get_intervals(u32 max_threads, u32 num_items, u32& threads, u32& stride, u32& rest) -{ - if (max_threads <= num_items) - { - threads = max_threads; - stride = num_items / max_threads; - rest = num_items % max_threads; - return; - } - threads = num_items; - stride = 1; - rest = 0; -} diff --git a/src/utils/xrLC_Light/CMakeLists.txt b/src/utils/xrLC_Light/CMakeLists.txt deleted file mode 100644 index ad262e58951..00000000000 --- a/src/utils/xrLC_Light/CMakeLists.txt +++ /dev/null @@ -1,210 +0,0 @@ -add_library(xrLC_Light SHARED) - -target_sources(xrLC_Light PRIVATE - base_basis.cpp - base_basis.h - base_color.cpp - base_color.h - base_face.cpp - base_face.h - base_face_ptr_storage.h - base_lighting.cpp - base_lighting.h - b_build_texture.cpp - b_build_texture.h - calculate_normals.h - compiler.cpp - detail_net_global_data.cpp - detail_net_global_data.h - detail_slot_calculate.cpp - detail_slot_calculate.h - ETextureParams.cpp - ETextureParams.h - execute_statistics.cpp - execute_statistics.h - file_compress.cpp - file_compress.h - fitter.cpp - fitter.h - gl_base_cl_data.cpp - gl_base_cl_data.h - global_calculation_data.cpp - global_calculation_data.h - global_slots_data.cpp - global_slots_data.h - hash2D.h - implicit_net_global_data.cpp - implicit_net_global_data.h - itterate_adjacents.h - itterate_adjacents_static.h - lcnet_execution_tasks_add.h - lc_net_global_data.cpp - lc_net_global_data.h - lcnet_task_manager.cpp - lcnet_task_manager.h - lcnet_task_menager_run_task.cpp - light_execute.cpp - light_execute.h - Lightmap.cpp - Lightmap.h - light_point.h - lightstab_interface.h - LightThread.cpp - LightThread.h - lm_layer.cpp - lm_layer.h - lm_net_global_data.cpp - lm_net_global_data.h - MeshStaic.cpp - MeshStructure.h - mu_light_net.cpp - mu_light_net.h - mu_model_face.cpp - mu_model_face_defs.h - mu_model_face.h - mu_model_light.cpp - mu_model_light.h - mu_model_light_threads.cpp - mu_model_light_threads.h - net_all_executions.h - net_all_globals.h - net_cl_data_prepare.cpp - net_cl_data_prepare.h - net_exec_pool.cpp - net_exec_pool.h - net_execution.cpp - net_execution_detail_light.cpp - net_execution_detail_light.h - net_execution_factory.cpp - net_execution_factory.h - net_execution_factory_register.cpp - net_execution_globals.cpp - net_execution_globals.h - net_execution.h - net_execution_implicit_light.cpp - net_execution_implicit_light.h - net_execution_lightmaps.cpp - net_execution_lightmaps.h - net_execution_mu_base.cpp - net_execution_mu_base.h - net_execution_mu_ref.cpp - net_execution_mu_ref.h - net_execution_vertex_light.cpp - net_execution_vertex_light.h - net_global_data_cleanup.cpp - net_global_data_cleanup.h - net_global_data.cpp - net_global_data.h - net_light.cpp - net_light.h - net_lightmaps_add_task.cpp - net_light_task.cpp - net_light_task.h - net_stream.cpp - net_stream.h - net_task_callback.cpp - net_task_callback.h - net_task.cpp - net_task.h - net_task_manager.cpp - net_task_manager.h - net_task_menager.cpp - net_task_menager.h - recalculation.cpp - recalculation.h - ref_model_net_global_data.cpp - ref_model_net_global_data.h - R_light.h - serialize.cpp - serialize.h - stdafx.cpp - stdafx.h - tcf.cpp - tcf.h - uv_tri.cpp - uv_tri.h - vector_clear.h - xrDeflectoL_Direct.cpp - xrDeflector.cpp - xrDeflectorDefs.h - xrDeflector.h - xrDeflectorLight.cpp - xrDXTC.h - xrFace.cpp - xrFaceDefs.h - xrFace.h - xrFaceInline.h - xrImage_Filter.cpp - xrImage_Filter.h - xrImage_Resampler.cpp - xrImage_Resampler.h - xrIsect.h - xrLC_GlobalData.cpp - xrLC_GlobalData.h - xrLC_Light.cpp - xrLC_Light.h - xrLightDoNet.cpp - xrLightDoNet.h - xrLight_ImlicitNet.cpp - xrLight_ImplicitCalcGlobs.cpp - xrLight_ImplicitCalcGlobs.h - xrLight_Implicit.cpp - xrLight_ImplicitDeflector.cpp - xrLight_ImplicitDeflector.h - xrLight_Implicit.h - xrLight_ImplicitRun.h - xrLight_ImplicitThread.cpp - xrLightVertex.cpp - xrLightVertex.h - xrLightVertexNet.cpp - xrMU_Model_Calc_faceopacity.cpp - xrMU_Model_Calc_lighting.cpp - xrMU_Model_Calc_materials.cpp - xrMU_Model_Calc_normals.cpp - xrMU_Model.cpp - xrMU_Model_export_cform_rcast.cpp - xrMU_Model.h - xrMU_Model_Load.cpp - xrMU_Model_Reference_Calc_Lighting.cpp - xrMU_Model_Reference.cpp - xrMU_Model_Reference.h - xrUVpoint.h - ../Shader_xrLC.h - ../xrLoadSurface.cpp -) - -target_include_directories(xrLC_Light - PRIVATE - "${CMAKE_SOURCE_DIR}/src" - "${CMAKE_SOURCE_DIR}/sdk/include" -) - -target_link_libraries(xrLC_Light - PRIVATE - xrCore - xrCDB - zlib - xrLCUtil -) - -target_compile_definitions(xrLC_Light - PRIVATE - _USRDLL - LEVEL_COMPILER - _USE_MATH_DEFINES - XRLC_LIGHT_EXPORTS - FORCE_NO_EXCEPTIONS -) - -set_target_properties(xrLC_Light PROPERTIES - PREFIX "" -) - -target_precompile_headers(xrLC_Light - PRIVATE - stdafx.h -) - -install(TARGETS xrLC_Light LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/src/utils/xrLC_Light/ETextureParams.cpp b/src/utils/xrLC_Light/ETextureParams.cpp deleted file mode 100644 index 01f26bfd588..00000000000 --- a/src/utils/xrLC_Light/ETextureParams.cpp +++ /dev/null @@ -1,459 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "ETextureParams.h" -#include "xrCore/xr_token.h" - -const xr_token tparam_token[] = {{"Advanced", STextureParams::kMIPFilterAdvanced}, - - {"Point", STextureParams::kMIPFilterPoint}, {"Box", STextureParams::kMIPFilterBox}, - {"Triangle", STextureParams::kMIPFilterTriangle}, {"Quadratic", STextureParams::kMIPFilterQuadratic}, - {"Cubic", STextureParams::kMIPFilterCubic}, - - {"Catrom", STextureParams::kMIPFilterCatrom}, {"Mitchell", STextureParams::kMIPFilterMitchell}, - - {"Gaussian", STextureParams::kMIPFilterGaussian}, {"Sinc", STextureParams::kMIPFilterSinc}, - {"Bessel", STextureParams::kMIPFilterBessel}, - - {"Hanning", STextureParams::kMIPFilterHanning}, {"Hamming", STextureParams::kMIPFilterHamming}, - {"Blackman", STextureParams::kMIPFilterBlackman}, {"Kaiser", STextureParams::kMIPFilterKaiser}, {nullptr, 0}}; - -const xr_token ttype_token[] = {{"2D Texture", STextureParams::ttImage}, {"Cube Map", STextureParams::ttCubeMap}, - {"Bump Map", STextureParams::ttBumpMap}, {"Normal Map", STextureParams::ttNormalMap}, - {"Terrain", STextureParams::ttTerrain}, {nullptr, 0}}; - -const xr_token tfmt_token[] = {{"DXT1", STextureParams::tfDXT1}, {"DXT1 Alpha", STextureParams::tfADXT1}, - {"DXT3", STextureParams::tfDXT3}, {"DXT5", STextureParams::tfDXT5}, {"16 bit (1:5:5:5)", STextureParams::tf1555}, - {"16 bit (5:6:5)", STextureParams::tf565}, {"32 bit (8:8:8:8)", STextureParams::tfRGBA}, - {"8 bit (alpha)", STextureParams::tfA8}, {"8 bit (luminance)", STextureParams::tfL8}, - {"16 bit (alpha:luminance)", STextureParams::tfA8L8}, {nullptr, 0}}; - -const xr_token tmtl_token[] = {{"OrenNayar <-> Blin", STextureParams::tmOrenNayar_Blin}, - {"Blin <-> Phong", STextureParams::tmBlin_Phong}, {"Phong <-> Metal", STextureParams::tmPhong_Metal}, - {"Metal <-> OrenNayar", STextureParams::tmMetal_OrenNayar}, {nullptr, 0}}; - -const xr_token tbmode_token[] = {{"None", STextureParams::tbmNone}, {"Use", STextureParams::tbmUse}, - {"Use parallax", STextureParams::tbmUseParallax}, {nullptr, 0}}; - -void STextureParams::Load(IReader& F) -{ - R_ASSERT(F.find_chunk(THM_CHUNK_TEXTUREPARAM)); - F.r(&fmt, sizeof(ETFormat)); - flags.assign(F.r_u32()); - border_color = F.r_u32(); - fade_color = F.r_u32(); - fade_amount = F.r_u32(); - mip_filter = F.r_u32(); - width = F.r_u32(); - height = F.r_u32(); - - if (F.find_chunk(THM_CHUNK_TEXTURE_TYPE)) - { - type = (ETType)F.r_u32(); - } - - if (F.find_chunk(THM_CHUNK_DETAIL_EXT)) - { - F.r_stringZ(detail_name); - detail_scale = F.r_float(); - } - - if (F.find_chunk(THM_CHUNK_MATERIAL)) - { - material = (ETMaterial)F.r_u32(); - material_weight = F.r_float(); - } - - if (F.find_chunk(THM_CHUNK_BUMP)) - { - bump_virtual_height = F.r_float(); - bump_mode = (ETBumpMode)F.r_u32(); - if (bump_mode < STextureParams::tbmNone) - { - bump_mode = STextureParams::tbmNone; //.. временно (до полного убирания Autogen) - } - F.r_stringZ(bump_name); - } - - if (F.find_chunk(THM_CHUNK_EXT_NORMALMAP)) - F.r_stringZ(ext_normal_map_name); - - if (F.find_chunk(THM_CHUNK_FADE_DELAY)) - fade_delay = F.r_u8(); -} - -void STextureParams::Save(IWriter& F) -{ - F.open_chunk(THM_CHUNK_TEXTUREPARAM); - F.w(&fmt, sizeof(ETFormat)); - F.w_u32(flags.get()); - F.w_u32(border_color); - F.w_u32(fade_color); - F.w_u32(fade_amount); - F.w_u32(mip_filter); - F.w_u32(width); - F.w_u32(height); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_TEXTURE_TYPE); - F.w_u32(type); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_DETAIL_EXT); - F.w_stringZ(detail_name); - F.w_float(detail_scale); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_MATERIAL); - F.w_u32(material); - F.w_float(material_weight); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_BUMP); - F.w_float(bump_virtual_height); - F.w_u32(bump_mode); - F.w_stringZ(bump_name); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_EXT_NORMALMAP); - F.w_stringZ(ext_normal_map_name); - F.close_chunk(); - - F.open_chunk(THM_CHUNK_FADE_DELAY); - F.w_u8(fade_delay); - F.close_chunk(); -} - -#ifdef _EDITOR -#include "xrServerEntities/PropertiesListHelper.h" - -void STextureParams::OnTypeChange(PropValue* prop) -{ - switch (type) - { - case ttImage: - case ttCubeMap: break; - case ttBumpMap: flags.set(flGenerateMipMaps, FALSE); break; - case ttNormalMap: - flags.set(flImplicitLighted | flBinaryAlpha | flAlphaBorder | flColorBorder | flFadeToColor | flFadeToAlpha | - flDitherColor | flDitherEachMIPLevel | flBumpDetail, FALSE); - flags.set(flGenerateMipMaps, TRUE); - mip_filter = kMIPFilterKaiser; - fmt = tfRGBA; - break; - case ttTerrain: - flags.set(flGenerateMipMaps | flBinaryAlpha | flAlphaBorder | flColorBorder | flFadeToColor | flFadeToAlpha | - flDitherColor | flDitherEachMIPLevel | flBumpDetail, FALSE); - flags.set(flImplicitLighted, TRUE); - fmt = tfDXT1; - break; - } - if (!OnTypeChangeEvent.empty()) - OnTypeChangeEvent(prop); -} - -void STextureParams::FillProp(LPCSTR base_name, PropItemVec& items, PropValue::TOnChange on_type_change) -{ - OnTypeChangeEvent = on_type_change; - PropValue* P = PHelper().CreateToken32(items, "Type", (u32*)&type, ttype_token); - P->OnChangeEvent.bind(this, &STextureParams::OnTypeChange); - PHelper().CreateCaption(items, "Source\\Width", shared_str().printf("%d", width)); - PHelper().CreateCaption(items, "Source\\Height", shared_str().printf("%d", height)); - PHelper().CreateCaption(items, "Source\\Alpha", HasAlpha() ? "present" : "absent"); - switch (type) - { - case ttImage: - case ttCubeMap: - PHelper().CreateToken32(items, "Format", (u32*)&fmt, tfmt_token); - - PHelper().CreateFlag32(items, "MipMaps\\Enabled", &flags, flGenerateMipMaps); - PHelper().CreateToken32(items, "MipMaps\\Filter", (u32*)&mip_filter, tparam_token); - - P = PHelper().CreateToken32(items, "Bump\\Mode", (u32*)&bump_mode, tbmode_token); - P->OnChangeEvent.bind(this, &STextureParams::OnTypeChange); - if (tbmUse == bump_mode || tbmUseParallax == bump_mode) - { - AnsiString path; - path = base_name; - PHelper().CreateChoose(items, "Bump\\Texture", &bump_name, smTexture, path.c_str()); - } - - PHelper().CreateFlag32(items, "Details\\Use As Diffuse", &flags, flDiffuseDetail); - PHelper().CreateFlag32(items, "Details\\Use As Bump (R2)", &flags, flBumpDetail); - PHelper().CreateChoose(items, "Details\\Texture", &detail_name, smTexture); - PHelper().CreateFloat(items, "Details\\Scale", &detail_scale, 0.1f, 10000.f, 0.1f, 2); - - PHelper().CreateToken32(items, "Material\\Base", (u32*)&material, tmtl_token); - PHelper().CreateFloat(items, "Material\\Weight", &material_weight); - - // PHelper().CreateFlag32 (items, "Flags\\Binary Alpha", &flags, flBinaryAlpha); - PHelper().CreateFlag32(items, "Flags\\Dither", &flags, flDitherColor); - PHelper().CreateFlag32(items, "Flags\\Dither Each MIP", &flags, flDitherEachMIPLevel); - PHelper().CreateFlag32(items, "Flags\\Implicit Lighted", &flags, flImplicitLighted); - - PHelper().CreateFlag32(items, "Fade\\Enable Color", &flags, flFadeToColor); - PHelper().CreateFlag32(items, "Fade\\Enabled Alpha", &flags, flFadeToAlpha); - PHelper().CreateU8(items, "Fade\\Delay 'n' MIP", &fade_delay, 0, 255); - PHelper().CreateU32(items, "Fade\\% of color to fade in", &fade_amount, 0, 100, 0); - PHelper().CreateColor(items, "Fade\\Color", &fade_color); - PHelper().CreateU8(items, "Fade\\Alpha", ((u8*)&fade_color) + 3, 0, 255); - - PHelper().CreateFlag32(items, "Border\\Enabled Color", &flags, flColorBorder); - PHelper().CreateFlag32(items, "Border\\Enabled Alpha", &flags, flAlphaBorder); - PHelper().CreateColor(items, "Border\\Color", &border_color); - break; - case ttBumpMap: - PHelper().CreateChoose(items, "Bump\\Special NormalMap", &ext_normal_map_name, smTexture, base_name); - PHelper().CreateFloat(items, "Bump\\Virtual Height (m)", &bump_virtual_height, 0.f, 0.1f, 0.001f, 3); - break; - case ttNormalMap: - P = PHelper().CreateToken32(items, "Format", (u32*)&fmt, tfmt_token); - P->Owner()->Enable(false); - - PHelper().CreateFlag32(items, "MipMaps\\Enabled", &flags, flGenerateMipMaps); - PHelper().CreateToken32(items, "MipMaps\\Filter", (u32*)&mip_filter, tparam_token); - break; - case ttTerrain: - P = PHelper().CreateToken32(items, "Format", (u32*)&fmt, tfmt_token); - P->Owner()->Enable(false); - - PHelper().CreateFlag32(items, "Details\\Use As Diffuse", &flags, flDiffuseDetail); - PHelper().CreateFlag32(items, "Details\\Use As Bump (R2)", &flags, flBumpDetail); - PHelper().CreateChoose(items, "Details\\Texture", &detail_name, smTexture); - PHelper().CreateFloat(items, "Details\\Scale", &detail_scale, 0.1f, 10000.f, 0.1f, 2); - - PHelper().CreateToken32(items, "Material\\Base", (u32*)&material, tmtl_token); - PHelper().CreateFloat(items, "Material\\Weight", &material_weight); - - P = PHelper().CreateFlag32(items, "Flags\\Implicit Lighted", &flags, flImplicitLighted); - P->Owner()->Enable(false); - break; - } -} - -BOOL STextureParams::similar(STextureParams& tp1, xr_vector& sel_params) -{ - BOOL res = TRUE; - - xr_vector::iterator it = sel_params.begin(); - xr_vector::iterator it_e = sel_params.end(); - - for (; it != it_e; ++it) - { - const AnsiString& par_name = *it; - if (par_name == "Type") - { - res = (type == tp1.type); - } - else if (par_name == "Source\\Width") - { - res = (width == tp1.width); - } - else if (par_name == "Source\\Height") - { - res = (height == tp1.height); - } - else if (par_name == "Source\\Alpha") - { - res = (HasAlpha() == tp1.HasAlpha()); - } - else if (par_name == "Format") - { - res = (fmt == tp1.fmt); - } - else if (par_name == "MipMaps\\Enabled") - { - res = (flags.test(flGenerateMipMaps) == tp1.flags.test(flGenerateMipMaps)); - } - else if (par_name == "MipMaps\\Filter") - { - res = (mip_filter == tp1.mip_filter); - } - else if (par_name == "Bump\\Mode") - { - res = (bump_mode == tp1.bump_mode); - } - else if (par_name == "Bump\\Texture") - { - res = (bump_name == tp1.bump_name); - } - else if (par_name == "Details\\Use As Diffuse") - { - res = (flags.test(flDiffuseDetail) == tp1.flags.test(flDiffuseDetail)); - } - else if (par_name == "Details\\Use As Bump (R2)") - { - res = (flags.test(flBumpDetail) == tp1.flags.test(flBumpDetail)); - } - else if (par_name == "Details\\Texture") - { - res = (detail_name == tp1.detail_name); - } - else if (par_name == "Details\\Scale") - { - res = (fsimilar(detail_scale, tp1.detail_scale)); - } - else if (par_name == "Material\\Base") - { - res = (material == tp1.material); - } - else if (par_name == "Material\\Weight") - { - res = (fsimilar(material_weight, tp1.material_weight)); - } - else if (par_name == "Flags\\Binary Alpha") - { - res = (flags.test(flBinaryAlpha) == tp1.flags.test(flBinaryAlpha)); - } - else if (par_name == "Flags\\Dither") - { - res = (flags.test(flDitherColor) == tp1.flags.test(flDitherColor)); - } - else if (par_name == "Flags\\Dither Each MIP") - { - res = (flags.test(flDitherEachMIPLevel) == tp1.flags.test(flDitherEachMIPLevel)); - } - else if (par_name == "Flags\\Implicit Lighted") - { - res = (flags.test(flImplicitLighted) == tp1.flags.test(flImplicitLighted)); - } - else if (par_name == "Fade\\Enable Color") - { - res = (flags.test(flFadeToColor) == tp1.flags.test(flFadeToColor)); - } - else if (par_name == "Fade\\Enabled Alpha") - { - res = (flags.test(flFadeToAlpha) == tp1.flags.test(flFadeToAlpha)); - } - else if (par_name == "Fade\\Delay 'n' MIP") - { - res = (fade_delay == tp1.fade_delay); - } - else if (par_name == "Fade\\% of color to fade in") - { - res = (fade_amount == tp1.fade_amount); - } - else if (par_name == "Fade\\Color") - { - res = (fade_color == tp1.fade_color); - } - else if (par_name == "Fade\\Alpha") - { - res = (color_get_A(fade_color) == color_get_A(tp1.fade_color)); - } - else if (par_name == "Border\\Enabled Color") - { - res = (flags.test(flColorBorder) == tp1.flags.test(flColorBorder)); - } - else if (par_name == "Border\\Enabled Alpha") - { - res = (flags.test(flAlphaBorder) == tp1.flags.test(flAlphaBorder)); - } - else if (par_name == "Border\\Color") - { - res = (border_color == tp1.border_color); - } - else if (par_name == "Bump\\Special NormalMap") - { - res = (ext_normal_map_name == tp1.ext_normal_map_name); - } - else if (par_name == "Bump\\Virtual Height (m)") - { - res = (fsimilar(bump_virtual_height, tp1.bump_virtual_height)); - } - else - Msg("! unknown filter [%s]", par_name.c_str()); - if (!res) - break; - } - - return res; -} - -LPCSTR STextureParams::FormatString() { return get_token_name(tfmt_token, fmt); } -u32 STextureParams::MemoryUsage(LPCSTR base_name) -{ - u32 mem_usage = width * height * 4; - if (flags.test(flGenerateMipMaps)) - { - mem_usage *= 3ul; - mem_usage /= 2ul; - } - switch (fmt) - { - case STextureParams::tfDXT1: - case STextureParams::tfADXT1: mem_usage /= 6; break; - case STextureParams::tfDXT3: - case STextureParams::tfDXT5: mem_usage /= 4; break; - case STextureParams::tf4444: - case STextureParams::tf1555: - case STextureParams::tf565: mem_usage /= 2; break; - case STextureParams::tfRGBA: break; - } - string_path fn; - FS.update_path(fn, _game_textures_, EFS.ChangeFileExt(base_name, ".seq").c_str()); - if (FS.exist(fn)) - { - string128 buffer; - IReader* F = FS.r_open(0, fn); - F->r_string(buffer, sizeof(buffer)); - int cnt = 0; - while (!F->eof()) - { - F->r_string(buffer, sizeof(buffer)); - cnt++; - } - FS.r_close(F); - mem_usage *= cnt ? cnt : 1; - } - return mem_usage; -} -#endif - -#include "serialize.h" - -void STextureParams::read(INetReader& r) -{ - r_pod(r, fmt); - r_pod(r, flags); - border_color = r.r_u32(); - fade_color = r.r_u32(); - fade_amount = r.r_u32(); - fade_delay = r.r_u8(); - ; - mip_filter = r.r_u32(); - width = r.r_s32(); - ; - height = r.r_s32(); - // r.r_stringZ( detail_name ); - detail_scale = r.r_float(); - r_pod(r, type); - r_pod(r, material); - material_weight = r.r_float(); - bump_virtual_height = r.r_float(); - r_pod(r, bump_mode); - // r.r_stringZ( bump_name ); - // r.r_stringZ( ext_normal_map_name ); -} - -void STextureParams::write(IWriter& w) const -{ - w_pod(w, fmt); - w_pod(w, flags); - w.w_u32(border_color); - w.w_u32(fade_color); - w.w_u32(fade_amount); - w.w_u8(fade_delay); - w.w_u32(mip_filter); - w.w_s32(width); - w.w_s32(height); - // w.w_stringZ( detail_name ); - w.w_float(detail_scale); - w_pod(w, type); - w_pod(w, material); - w.w_float(material_weight); - w.w_float(bump_virtual_height); - w_pod(w, bump_mode); - // w.w_stringZ( bump_name ); - // w.w_stringZ( ext_normal_map_name ); -} diff --git a/src/utils/xrLC_Light/ETextureParams.h b/src/utils/xrLC_Light/ETextureParams.h deleted file mode 100644 index da649414e09..00000000000 --- a/src/utils/xrLC_Light/ETextureParams.h +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef ETextureParamsH -#define ETextureParamsH -class INetReader; -#pragma pack(push, 1) -struct /*ECORE_API*/ STextureParams -{ - enum ETType - { - ttImage = 0, - ttCubeMap, - ttBumpMap, - ttNormalMap, - ttTerrain, - ttForceU32 = u32(-1) - }; - enum ETFormat - { - tfDXT1 = 0, - tfADXT1, - tfDXT3, - tfDXT5, - tf4444, - tf1555, - tf565, - tfRGB, - tfRGBA, - tfNVHS, - tfNVHU, - tfA8, - tfL8, - tfA8L8, - tfForceU32 = u32(-1) - }; - enum ETBumpMode - { - tbmResereved = 0, - tbmNone, - tbmUse, - tbmUseParallax, - tbmForceU32 = u32(-1) - }; - enum ETMaterial - { - tmOrenNayar_Blin = 0, - tmBlin_Phong, - tmPhong_Metal, - tmMetal_OrenNayar, - tmForceU32 = u32(-1) - }; - enum - { - kMIPFilterAdvanced = 5, - - kMIPFilterPoint = 2, - kMIPFilterBox = 0, - kMIPFilterTriangle = 3, - kMIPFilterQuadratic = 4, - kMIPFilterCubic = 1, - - kMIPFilterCatrom = 6, - kMIPFilterMitchell = 7, - - kMIPFilterGaussian = 8, - kMIPFilterSinc = 9, - kMIPFilterBessel = 10, - - kMIPFilterHanning = 11, - kMIPFilterHamming = 12, - kMIPFilterBlackman = 13, - kMIPFilterKaiser = 14, - }; - - enum - { - flGenerateMipMaps = (1 << 0), - flBinaryAlpha = (1 << 1), - flAlphaBorder = (1 << 4), - flColorBorder = (1 << 5), - flFadeToColor = (1 << 6), - flFadeToAlpha = (1 << 7), - flDitherColor = (1 << 8), - flDitherEachMIPLevel = (1 << 9), - // flGreyScale = (1<<10), // obsolette - - flDiffuseDetail = (1 << 23), - flImplicitLighted = (1 << 24), - flHasAlpha = (1 << 25), - flBumpDetail = (1 << 26), - - flHasSurface = (1 << 27), // for compiler - save the fact the surface was loaded - // use when deleted pSurface for memory issues - - flForceU32 = u32(-1) - }; - - // texture part - ETFormat fmt; - Flags32 flags; - u32 border_color; - u32 fade_color; - u32 fade_amount; - u8 fade_delay; - u32 mip_filter; - int width; - int height; - // detail ext - shared_str detail_name; - float detail_scale; - ETType type; - // material - ETMaterial material; - float material_weight; - // bump - float bump_virtual_height; - ETBumpMode bump_mode; - shared_str bump_name; - shared_str ext_normal_map_name; - - STextureParams() { Clear(); } - void destroy_shared_str(shared_str& object) { object.~shared_str(); } - void construct_shared_str(shared_str& object) { ::new (&object) shared_str(); } - - void Clear() - { - destroy_shared_str(detail_name); - destroy_shared_str(bump_name); - destroy_shared_str(ext_normal_map_name); - - ZeroMemory(this, sizeof(STextureParams)); - - construct_shared_str(detail_name); - construct_shared_str(bump_name); - construct_shared_str(ext_normal_map_name); - - flags.set(flGenerateMipMaps | flDitherColor, TRUE); - mip_filter = kMIPFilterBox; - width = 0; - height = 0; - detail_scale = 1; - bump_mode = tbmNone; - material = tmBlin_Phong; - bump_virtual_height = 0.05f; - } - - BOOL HasAlpha() - { - // исходная текстура содержит альфа канал - return flags.is(flHasAlpha); - } - - BOOL HasAlphaChannel() // игровая текстура содержит альфа канал - { - switch (fmt) - { - case tfADXT1: - case tfDXT3: - case tfDXT5: - case tf4444: - case tf1555: - case tfRGBA: return TRUE; - default: return FALSE; - } - } - void Load(IReader& F); - void Save(IWriter& F); - void read(INetReader& r); - void write(IWriter& w) const; - BOOL HasSurface() const { return flags.is(flHasSurface); } - void SetHasSurface(BOOL val) { flags.set(flHasSurface, val); } -#ifdef _EDITOR - PropValue::TOnChange OnTypeChangeEvent; - void __stdcall OnTypeChange(PropValue* v); - void FillProp(LPCSTR base_name, PropItemVec& items, PropValue::TOnChange OnChangeEvent); - LPCSTR FormatString(); - u32 MemoryUsage(LPCSTR base_name); - BOOL similar(STextureParams& tp1, xr_vector& sel_params); - -#endif -}; -#pragma pack(pop) - -struct xr_token; -extern const xr_token tparam_token[]; -extern const xr_token tfmt_token[]; -extern const xr_token ttype_token[]; - -//---------------------------------------------------- -#define THM_CHUNK_VERSION 0x0810 -#define THM_CHUNK_DATA 0x0811 -#define THM_CHUNK_TEXTUREPARAM 0x0812 -#define THM_CHUNK_TYPE 0x0813 -#define THM_CHUNK_TEXTURE_TYPE 0x0814 -#define THM_CHUNK_DETAIL_EXT 0x0815 -#define THM_CHUNK_MATERIAL 0x0816 -#define THM_CHUNK_BUMP 0x0817 -#define THM_CHUNK_EXT_NORMALMAP 0x0818 -#define THM_CHUNK_FADE_DELAY 0x0819 -//---------------------------------------------------- -#define THUMB_WIDTH 128 -#define THUMB_HEIGHT 128 -#define THUMB_SIZE THUMB_HEIGHT* THUMB_WIDTH -//---------------------------------------------------- -#endif /*_INCDEF_TextureParams_H_*/ diff --git a/src/utils/xrLC_Light/LightThread.cpp b/src/utils/xrLC_Light/LightThread.cpp deleted file mode 100644 index 663ebb6e95c..00000000000 --- a/src/utils/xrLC_Light/LightThread.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "stdafx.h" - -#include "LightThread.h" - -#include "global_calculation_data.h" - -void LightThread::Execute() -{ - // DetailSlot::verify (); - CDB::COLLIDER DB; - base_lighting Selected; - - for (u32 _z = Nstart; _z < Nend; _z++) - { - for (u32 _x = 0; _x < gl_data.slots_data.size_x(); _x++) - { - DetailSlot& DS = gl_data.slots_data.get_slot(_x, _z); - if (!detail_slot_process(_x, _z, DS)) - continue; - if (!detail_slot_calculate(_x, _z, DS, box_result, DB, CDB::OPT_FULL_TEST, CDB::OPT_CULL, Selected)) - continue; //? - gl_data.slots_data.set_slot_calculated(_x, _z); - - thProgress = float(_z - Nstart) / float(Nend - Nstart); - - const auto secs = std::chrono::duration_cast(t_time).count(); - thPerformance = float(double(t_count) / double(secs)) / 1000.f; - } - } -} diff --git a/src/utils/xrLC_Light/LightThread.h b/src/utils/xrLC_Light/LightThread.h deleted file mode 100644 index 9a3fcd67eb8..00000000000 --- a/src/utils/xrLC_Light/LightThread.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __LIGHTTHREAD_H__ -#define __LIGHTTHREAD_H__ - -#include "utils/xrLCUtil/xrThread.hpp" -#include "detail_slot_calculate.h" - -class LightThread : public CThread -{ - u32 Nstart, Nend; - DWORDVec box_result; - -public: - LightThread(u32 ID, u32 _start, u32 _end) : CThread(ID, ProxyMsg) - { - Nstart = _start; - Nend = _end; - } - virtual void Execute(); -}; -#endif //__LIGHTTHREAD_H__ diff --git a/src/utils/xrLC_Light/Lightmap.cpp b/src/utils/xrLC_Light/Lightmap.cpp deleted file mode 100644 index 9d3ad963c9a..00000000000 --- a/src/utils/xrLC_Light/Lightmap.cpp +++ /dev/null @@ -1,224 +0,0 @@ -// Lightmap.cpp: implementation of the CLightmap class. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" - -#include "Lightmap.h" -#include "xrDeflector.h" -#include "xrDXTC.h" -#include "xrImage_Filter.h" -#include "xrface.h" -#include "serialize.h" -#include "ETextureParams.h" - -extern "C" XR_IMPORT -bool DXTCompress(pcstr out_name, u8* raw_data, u8* normal_map, - u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth); - -// extern BOOL ApplyBorders (lm_layer &lm, u32 ref); - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CLightmap::CLightmap() {} -CLightmap::~CLightmap() {} -CLightmap* CLightmap::read_create() { return xr_new(); } -void CLightmap::Capture(CDeflector* D, int b_u, int b_v, int s_u, int s_v, BOOL bRotated) -{ - // Allocate 512x512 texture if needed - if (lm.surface.empty()) - lm.create(c_LMAP_size, c_LMAP_size); - - // Addressing - xr_vector tris; - D->RemapUV( - tris, b_u + BORDER, b_v + BORDER, s_u - 2 * BORDER, s_v - 2 * BORDER, c_LMAP_size, c_LMAP_size, bRotated); - - // Capture faces and setup their coords - for (UVIt T = tris.begin(); T != tris.end(); ++T) - { - UVtri& P = *T; - Face* F = P.owner; - F->lmap_layer = this; - F->AddChannel(P.uv[0], P.uv[1], P.uv[2]); - } - - // Perform BLIT - lm_layer& L = D->layer; - if (!bRotated) - { - u32 real_H = (L.height + 2 * BORDER); - u32 real_W = (L.width + 2 * BORDER); - blit(lm, c_LMAP_size, c_LMAP_size, L, real_W, real_H, b_u, b_v, 254 - BORDER); - } - else - { - u32 real_H = (L.height + 2 * BORDER); - u32 real_W = (L.width + 2 * BORDER); - blit_r(lm, c_LMAP_size, c_LMAP_size, L, real_W, real_H, b_u, b_v, 254 - BORDER); - } -} - -////////////////////////////////////////////////////////////////////// -IC u32 convert(float a) -{ - if (a <= 0) - return 0; - else if (a >= 1) - return 255; - else - return iFloor(a * 255.f); -} -IC void pixel(int x, int y, b_texture* T, u32 C = color_rgba(0, 255, 0, 0)) -{ - if (x < 0) - return; - else if (x >= (int)T->dwWidth) - return; - if (y < 0) - return; - else if (y >= (int)T->dwHeight) - return; - T->pSurface[y * T->dwWidth + x] = C; -} -IC void line(int x1, int y1, int x2, int y2, b_texture* T) -{ - int dx = _abs(x2 - x1); - int dy = _abs(y2 - y1); - int sx = x2 >= x1 ? 1 : -1; - int sy = y2 >= y1 ? 1 : -1; - - if (dy <= dx) - { - int d = (dy << 1) - dx; - int d1 = dy << 1; - int d2 = (dy - dx) << 1; - - pixel(x1, y1, T); - - for (int x = x1 + sx, y = y1, i = 1; i <= dx; i++, x += sx) - { - if (d > 0) - { - d += d2; - y += sy; - } - else - d += d1; - pixel(x, y, T); - } - } - else - { - int d = (dx << 1) - dy; - int d1 = dx << 1; - int d2 = (dx - dy) << 1; - - pixel(x1, y1, T); - for (int x = x1, y = y1 + sy, i = 1; i <= dy; i++, y += sy) - { - if (d > 0) - { - d += d2; - x += sx; - } - else - d += d1; - pixel(x, y, T); - } - } -} - -void CLightmap::Save(LPCSTR path) -{ - static int lmapNameID = 0; - ++lmapNameID; - - Logger.Phase("Saving..."); - - // Borders correction - Logger.Status("Borders..."); - for (u32 _y = 0; _y < c_LMAP_size; _y++) - { - for (u32 _x = 0; _x < c_LMAP_size; _x++) - { - u32 offset = _y * c_LMAP_size + _x; - if (lm.marker[offset] >= (254 - BORDER)) - lm.marker[offset] = 255; - else - lm.marker[offset] = 0; - } - } - for (u32 ref = 254; ref > (254 - 16); ref--) - { - ApplyBorders(lm, ref); - Logger.Progress(1.f - float(ref) / float(254 - 16)); - } - Logger.Progress(1.f); - - xr_vector lm_packed; - lm.Pack(lm_packed); - xr_vector hemi_packed; - lm.Pack_hemi(hemi_packed); - - lm_texture.bHasAlpha = TRUE; - lm_texture.dwWidth = lm.width; - lm_texture.dwHeight = lm.height; - lm_texture.pSurface = NULL; - - lm.destroy(); - - // Saving (DXT5.dds) - Logger.Status("Compression base..."); - { - string_path FN; - xr_sprintf(lm_texture.name, "lmap#%d", lmapNameID); - xr_sprintf(FN, "%s%s_1.dds", path, lm_texture.name); - u8* raw_data = (u8*)(&*lm_packed.begin()); - u32 w = lm_texture.dwWidth; // lm.width; - u32 h = lm_texture.dwHeight; // lm.height; - u32 pitch = w * 4; - - STextureParams fmt; - fmt.fmt = STextureParams::tfDXT5; - fmt.flags.set(STextureParams::flDitherColor, FALSE); - fmt.flags.set(STextureParams::flGenerateMipMaps, FALSE); - fmt.flags.set(STextureParams::flBinaryAlpha, FALSE); - DXTCompress(FN, raw_data, 0, w, h, pitch, &fmt, 4); - } - lm_packed.clear(); - Logger.Status("Compression hemi..."); //. - { - u32 w = lm_texture.dwWidth; // lm.width; - u32 h = lm_texture.dwHeight; // lm.height; - u32 pitch = w * 4; - - string_path FN; - xr_sprintf(lm_texture.name, "lmap#%d", lmapNameID); - xr_sprintf(FN, "%s%s_2.dds", path, lm_texture.name); - u8* raw_data = (u8*)(&*hemi_packed.begin()); - - STextureParams fmt; - fmt.fmt = STextureParams::tfDXT5; - fmt.flags.set(STextureParams::flDitherColor, FALSE); - fmt.flags.set(STextureParams::flGenerateMipMaps, FALSE); - fmt.flags.set(STextureParams::flBinaryAlpha, FALSE); - DXTCompress(FN, raw_data, 0, w, h, pitch, &fmt, 4); - } -} -/* - lm_layer lm; - b_texture lm_texture; -*/ -void CLightmap::read(INetReader& r) -{ - lm.read(r); - ::read(r, lm_texture); -} -void CLightmap::write(IWriter& w) const -{ - lm.write(w); - ::write(w, lm_texture); -} diff --git a/src/utils/xrLC_Light/Lightmap.h b/src/utils/xrLC_Light/Lightmap.h deleted file mode 100644 index a526d71089c..00000000000 --- a/src/utils/xrLC_Light/Lightmap.h +++ /dev/null @@ -1,37 +0,0 @@ -// Lightmap.h: interface for the CLightmap class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_LIGHTMAP_H__889100E6_CF29_47EA_ABFD_41AE28DAC6B1__INCLUDED_) -#define AFX_LIGHTMAP_H__889100E6_CF29_47EA_ABFD_41AE28DAC6B1__INCLUDED_ -#pragma once - -#include "lm_layer.h" -#include "serialize.h" -// refs -class CDeflector; - -// def -class XRLC_LIGHT_API CLightmap -{ -public: - lm_layer lm; - b_texture lm_texture; - -public: - CLightmap(); - ~CLightmap(); - void read(INetReader& r); - void write(IWriter& w) const; - void Capture(CDeflector* D, int b_u, int b_v, int s_u, int s_v, BOOL bRotate); - void Save(LPCSTR path); - static CLightmap* read_create(); -}; - -typedef vector_serialize>> tread_lightmaps; -typedef vector_serialize>> twrite_lightmaps; - -extern tread_lightmaps* read_lightmaps; -extern twrite_lightmaps* write_lightmaps; - -#endif // !defined(AFX_LIGHTMAP_H__889100E6_CF29_47EA_ABFD_41AE28DAC6B1__INCLUDED_) diff --git a/src/utils/xrLC_Light/MeshStaic.cpp b/src/utils/xrLC_Light/MeshStaic.cpp deleted file mode 100644 index 19bb4b5ee46..00000000000 --- a/src/utils/xrLC_Light/MeshStaic.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "stdafx.h" - -#include "xrLC_GlobalData.h" - -#include "xrface.h" -#include "vector_clear.h" - -typedef poolSS poolVertices; -typedef poolSS poolFaces; -static poolVertices _VertexPool; -static poolFaces _FacePool; - -Face* xrLC_GlobalData::create_face() { return _FacePool.create(); } -void xrLC_GlobalData::destroy_face(Face*& f) { _FacePool.destroy(f); } -Vertex* xrLC_GlobalData::create_vertex() { return _VertexPool.create(); } -void xrLC_GlobalData::destroy_vertex(Vertex*& f) { _VertexPool.destroy(f); } -static struct destruct_vertex_not_uregister -{ - static void destruct(Vertex*& v) { ::destroy_vertex(v, false); } -} _destruct_vertex_not_uregister; -static struct destruct_face_not_uregister -{ - static void destruct(Face*& f) { ::destroy_face(f, false); } -} _destruct_face_not_uregister; -void xrLC_GlobalData::gl_mesh_clear() -{ - vec_clear(_g_vertices, _destruct_vertex_not_uregister); - vec_clear(_g_faces, _destruct_face_not_uregister); - - _VertexPool.clear(); - _FacePool.clear(); -} - -void xrLC_GlobalData::vertices_isolate_and_pool_reload() -{ - const u32 inital_verts_count = _g_vertices.size(); - u32 not_empty_verts = 0; - // for(u32 i = 0; i < inital_verts_count; ++i ) - // if(!_g_vertices[i]->m_adjacents.empty()) - // ++not_empty_verts; - ///////////////////////////////////////////////////////// - - string_path path_name; - FS.update_path(path_name, "$app_root$", "ccc__temp__vertices"); - { - IWriter* file = FS.w_open(path_name); - R_ASSERT(file); - for (u32 i = 0; i < inital_verts_count; ++i) - { - Vertex& v = *_g_vertices[i]; - if (v.m_adjacents.empty()) - { - ::destroy_vertex(_g_vertices[i], false); - continue; - } - // isolate_pool_clear_read - // isolate_pool_clear_write - - v.isolate_pool_clear_write(*file); - ::destroy_vertex(_g_vertices[i], false); - ++not_empty_verts; - } - FS.w_close(file); - } - ///////////////////////////////////////////////////////// - _g_vertices.clear(); - Logger.clLog("mem usage before clear pool: %u", Memory.mem_usage()); - - _VertexPool.clear(); - - ///////////////////////////////////////////////////////// - { - b_vert_not_register = true; - _g_vertices.resize(not_empty_verts, 0); - - Memory.mem_compact(); - Logger.clLog("mem usage after clear pool: %u", Memory.mem_usage()); - - INetReaderFile r_verts(path_name); - for (u32 i = 0; i < not_empty_verts; ++i) - { - Vertex*& v = _g_vertices[i]; - v = _VertexPool.create(); - v->isolate_pool_clear_read(r_verts); - } - b_vert_not_register = false; - } -} - -void xrLC_GlobalData::clear_mesh() -{ - // R_ASSERT(g_XSplit.empty()); - Logger.clLog("mem usage before clear mesh: %u", Memory.mem_usage()); - // g_vertices().clear(); - // g_faces().clear(); - //_VertexPool.clear(); - //_FacePool.clear(); - gl_mesh_clear(); - Memory.mem_compact(); - Logger.clLog("mem usage after clear mesh: %u", Memory.mem_usage()); -} diff --git a/src/utils/xrLC_Light/MeshStructure.h b/src/utils/xrLC_Light/MeshStructure.h deleted file mode 100644 index b26815a3e73..00000000000 --- a/src/utils/xrLC_Light/MeshStructure.h +++ /dev/null @@ -1,376 +0,0 @@ -#ifndef __MESHSTRUCTURE_H__ -#define __MESHSTRUCTURE_H__ - -//#ifdef MESHSTRUCTURE_EXSPORTS_IMPORTS -#define MESHSTRUCTURE_API XRLC_LIGHT_API -//#else -//# define MESHSTRUCTURE_API -//#endif - -// typedef xr_vector<_vertex*> v_vertices; -// typedef v_vertices::iterator v_vertices_it; - -// typedef v_faces::iterator v_faces_it; -// typedef xr_vector<_subdiv> v_subdivs; -// typedef v_subdivs::iterator v_subdivs_it; -// extern volatile u32 dwInvalidFaces; -class MESHSTRUCTURE_API vector_item -{ -protected: - vector_item() : m_self_index(u32(-1)) {} -private: - u32 m_self_index; - -public: - IC void set_index(u32 self_index) { m_self_index = self_index; } - IC u32 self_index() const { return m_self_index; } -}; -template -struct Tvertex; -class CDeflector; -template -struct MESHSTRUCTURE_API Tface : public DataVertexType::DataFaceType, public vector_item -{ - typedef Tvertex type_vertex; - typedef Tface type_face; - // private: - type_vertex* v[3]; - // u32 m_self_index; -public: - // IC void set_index ( u32 idx ) { m_self_index = idx; } - // IC u32 self_index ( ) const {return m_self_index ;} - /////////////////////////////////////////////////////////////////////////////////////////////////// - Tface(); - virtual ~Tface(); - static Tface* read_create(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - void Verify(); - void Failure(); - void OA_Unwarp(CDeflector* d); - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; - virtual void read_vertices(INetReader& r); - virtual void write_vertices(IWriter& w) const; - - ////////////////////////////////////////////////////////////////////////////////////////////////// - IC void raw_set_vertex(u8 index, type_vertex* _v) - { - R_ASSERT(index < 3); - v[index] = _v; - } - IC type_vertex* vertex(u8 index) - { - R_ASSERT(index < 3); - return v[index]; - } - - ///////////////////////////////////////////////////////// - // Does the face contains this vertex? - IC bool VContains(const type_vertex* pV) { return VIndex(pV) >= 0; }; - // Replace ONE vertex by ANOTHER - IC void VReplace(type_vertex* what, type_vertex* to) - { - if (v[0] == what) - { - v[0] = to; - what->prep_remove(this); - to->prep_add(this); - } - if (v[1] == what) - { - v[1] = to; - what->prep_remove(this); - to->prep_add(this); - } - if (v[2] == what) - { - v[2] = to; - what->prep_remove(this); - to->prep_add(this); - } - }; - IC void VReplace_not_remove(type_vertex* what, type_vertex* to) - { - if (v[0] == what) - { - v[0] = to; - to->prep_add(this); - } - if (v[1] == what) - { - v[1] = to; - to->prep_add(this); - } - if (v[2] == what) - { - v[2] = to; - to->prep_add(this); - } - }; - IC int VIndex(const type_vertex* pV) - { - if (v[0] == pV) - return 0; - if (v[1] == pV) - return 1; - if (v[2] == pV) - return 2; - return -1; - }; - - IC void SetVertex(size_t idx, type_vertex* V) - { - v[idx] = V; - V->prep_add(this); - }; - IC void SetVertices(type_vertex* V1, type_vertex* V2, type_vertex* V3) - { - SetVertex(0, V1); - SetVertex(1, V2); - SetVertex(2, V3); - }; - IC BOOL isDegenerated() { return (v[0] == v[1] || v[0] == v[2] || v[1] == v[2]); }; - IC float EdgeLen(size_t edge) - { - type_vertex* V1 = v[edge2idx[edge][0]]; - type_vertex* V2 = v[edge2idx[edge][1]]; - return V1->P.distance_to(V2->P); - }; - IC void EdgeVerts(size_t e, type_vertex** A, type_vertex** B) const - { - *A = v[edge2idx[e][0]]; - *B = v[edge2idx[e][1]]; - } - - BOOL isEqual(type_face& F) - { - // Test for 6 variations - if ((v[0] == F.v[0]) && (v[1] == F.v[1]) && (v[2] == F.v[2])) - return true; - if ((v[0] == F.v[0]) && (v[2] == F.v[1]) && (v[1] == F.v[2])) - return true; - if ((v[2] == F.v[0]) && (v[0] == F.v[1]) && (v[1] == F.v[2])) - return true; - if ((v[2] == F.v[0]) && (v[1] == F.v[1]) && (v[0] == F.v[2])) - return true; - if ((v[1] == F.v[0]) && (v[0] == F.v[1]) && (v[2] == F.v[2])) - return true; - if ((v[1] == F.v[0]) && (v[2] == F.v[1]) && (v[0] == F.v[2])) - return true; - return false; - } - - void CalcNormal() - { - Fvector t1, t2; - - Fvector* v0 = &(v[0]->P); - Fvector* v1 = &(v[1]->P); - Fvector* v2 = &(v[2]->P); - t1.sub(*v1, *v0); - t2.sub(*v2, *v1); - N.crossproduct(t1, t2); - float mag = N.magnitude(); - if (mag < EPS_S) - { - Fvector3 save_N = N; - if (exact_normalize(save_N)) - N = save_N; - else - CalcNormal2(); - } - else - { - N.div(mag); - N.normalize(); - } - } - - void CalcNormal2() - { - FPU::m64r(); - Dvector v0, v1, v2, t1, t2, dN; - v0.set(v[0]->P); - v1.set(v[1]->P); - v2.set(v[2]->P); - t1.sub(v1, v0); - t2.sub(v2, v1); - dN.crossproduct(t1, t2); - double mag = dN.magnitude(); - if (mag < dbl_zero) - { - Failure(); - Dvector Nabs; - Nabs.abs(dN); - -#define SIGN(a) ((a >= 0.f) ? 1.f : -1.f) - if (Nabs.x > Nabs.y && Nabs.x > Nabs.z) - N.set(SIGN(N.x), 0.f, 0.f); - else if (Nabs.y > Nabs.x && Nabs.y > Nabs.z) - N.set(0.f, SIGN(N.y), 0.f); - else if (Nabs.z > Nabs.x && Nabs.z > Nabs.y) - N.set(0.f, 0.f, SIGN(N.z)); - else - { - N.set(0, 1, 0); - } -#undef SIGN - } - else - { - dN.div(mag); - N.set(dN); - } - } - - float CalcArea() const - { - float e1 = v[0]->P.distance_to(v[1]->P); - float e2 = v[0]->P.distance_to(v[2]->P); - float e3 = v[1]->P.distance_to(v[2]->P); - - float p = (e1 + e2 + e3) / 2.f; - return _sqrt(p * (p - e1) * (p - e2) * (p - e3)); - } - float CalcMaxEdge() - { - float e1 = v[0]->P.distance_to(v[1]->P); - float e2 = v[0]->P.distance_to(v[2]->P); - float e3 = v[1]->P.distance_to(v[2]->P); - - if (e1 > e2 && e1 > e3) - return e1; - if (e2 > e1 && e2 > e3) - return e2; - return e3; - } - void CalcCenter(Fvector& C) - { - C.set(v[0]->P); - C.add(v[1]->P); - C.add(v[2]->P); - C.div(3); - }; -}; - -template -struct MESHSTRUCTURE_API Tvertex : public DataVertexType, public vector_item -{ - typedef Tface type_face; - typedef Tvertex type_vertex; - - typedef xr_vector v_faces; - typedef typename v_faces::iterator v_faces_it; - - // typedef typename xr_vector::iterator v_dummy; - typedef xr_vector v_vertices; - - typedef typename v_vertices::iterator v_vertices_it; - ////////////////////////////////////////////////////////////// - Tvertex(); - virtual ~Tvertex(); - Tvertex* CreateCopy_NOADJ(v_vertices& vertises_storage) const; - static Tvertex* read_create(); - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; - - ////////////////////////////////////////////////////////////// - void isolate_pool_clear_read(INetReader& r); - void isolate_pool_clear_write(IWriter& w) const; - - void read_adjacents(INetReader& r); - void write_adjacents(IWriter& w) const; - /////////////////////////////////////////////////////////////// - v_faces m_adjacents; - - IC type_vertex* CreateCopy(v_vertices& vertises_storage) - { - type_vertex* V = CreateCopy_NOADJ(vertises_storage); - V->m_adjacents = m_adjacents; - return V; - } - IC void prep_add(type_face* F) - { - v_faces_it I = std::find(m_adjacents.begin(), m_adjacents.end(), F); - if (I == m_adjacents.end()) - m_adjacents.push_back(F); - } - - IC void prep_remove(type_face* F) - { - v_faces_it I = std::find(m_adjacents.begin(), m_adjacents.end(), F); - if (I != m_adjacents.end()) - m_adjacents.erase(I); - } - - IC void normalFromAdj() - { - N.set(0, 0, 0); - for (v_faces_it ad = m_adjacents.begin(); ad != m_adjacents.end(); ++ad) - N.add((*ad)->N); - exact_normalize(N); - } -}; - -template -IC void _destroy_vertex(typeVertex*& v, bool unregister) -{ - destroy_vertex(v, unregister); -} - -template -struct remove_pred -{ - bool operator()(typeVertex*& v) - { - if (v && v->m_adjacents.empty()) - { - _destroy_vertex(v, false); - return true; - } - return false; - } -}; - -template -IC void isolate_vertices(BOOL bProgress, xr_vector& vertices) -{ - if (bProgress) - Logger.Status("Isolating vertices..."); - // g_bUnregister = false; - const size_t verts_old = vertices.size(); - - for (size_t it = 0; it < verts_old; ++it) - { - if (bProgress) - Logger.Progress(float(it) / float(verts_old)); - - if (vertices[it] && vertices[it]->m_adjacents.empty()) - _destroy_vertex(vertices[it], false); - } - VERIFY(verts_old == vertices.size()); - - auto _end = std::remove(vertices.begin(), vertices.end(), (typeVertex*)0); - - /* - remove_pred rp; - xr_vector::iterator _end = std::remove_if (vertices.begin(),vertices.end(),rp); - - */ - vertices.erase(_end, vertices.end()); - // g_bUnregister = true; - Memory.mem_compact(); - - if (bProgress) - Logger.Progress(1.f); - - size_t verts_new = vertices.size(); - size_t _count = verts_old - verts_new; - - if (_count) - Logger.clMsg("::compact:: %d verts removed", _count); -} - -#endif //__MESHSTRUCTURE_H__ diff --git a/src/utils/xrLC_Light/ReadMe.txt b/src/utils/xrLC_Light/ReadMe.txt deleted file mode 100644 index 252227c9dbe..00000000000 --- a/src/utils/xrLC_Light/ReadMe.txt +++ /dev/null @@ -1,41 +0,0 @@ -======================================================================== - DYNAMIC LINK LIBRARY : xrLC_Light Project Overview -======================================================================== - -AppWizard has created this xrLC_Light DLL for you. - -This file contains a summary of what you will find in each of the files that -make up your xrLC_Light application. - - -xrLC_Light.vcproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -xrLC_Light.cpp - This is the main DLL source file. - - When created, this DLL does not export any symbols. As a result, it - will not produce a .lib file when it is built. If you wish this project - to be a project dependency of some other project, you will either need to - add code to export some symbols from the DLL so that an export library - will be produced, or you can set the Ignore Input Library property to Yes - on the General propert page of the Linker folder in the project's Property - Pages dialog box. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named xrLC_Light.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/src/utils/xrLC_Light/b_build_texture.cpp b/src/utils/xrLC_Light/b_build_texture.cpp deleted file mode 100644 index 98fbab56451..00000000000 --- a/src/utils/xrLC_Light/b_build_texture.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "stdafx.h" -#include "b_build_texture.h" -#include "serialize.h" -/* -struct b_texture -{ - string128 name; - u32 dwWidth; - u32 dwHeight; - BOOL bHasAlpha; - u32* pSurface; -}; -STextureParams THM; -*/ - -void clear(b_BuildTexture& texture) { xr_free(texture.pSurface); } -void b_BuildTexture::read(INetReader& r) -{ - ::read(r, *this); - THM.read(r); -} - -void b_BuildTexture::write(IWriter& w) const -{ - ::write(w, *this); - THM.write(w); -} diff --git a/src/utils/xrLC_Light/b_build_texture.h b/src/utils/xrLC_Light/b_build_texture.h deleted file mode 100644 index fa821a3de57..00000000000 --- a/src/utils/xrLC_Light/b_build_texture.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "Etextureparams.h" -struct b_BuildTexture : public b_texture -{ - STextureParams THM; - - b_BuildTexture() : b_texture() {} - b_BuildTexture(IReader*& file) : b_texture(file) {} - b_BuildTexture(const b_texture& p) : b_texture(p) {} - - u32& Texel(u32 x, u32 y) { return pSurface[y * dwWidth + x]; } - void Vflip() - { - R_ASSERT(pSurface); - for (u32 y = 0; y < dwHeight / 2; y++) - { - u32 y2 = dwHeight - y - 1; - for (u32 x = 0; x < dwWidth; x++) - { - u32 t = Texel(x, y); - Texel(x, y) = Texel(x, y2); - Texel(x, y2) = t; - } - } - } - void read(INetReader& r); - void write(IWriter& w) const; -}; - -void clear(b_BuildTexture& texture); diff --git a/src/utils/xrLC_Light/base_basis.cpp b/src/utils/xrLC_Light/base_basis.cpp deleted file mode 100644 index 07f276a852b..00000000000 --- a/src/utils/xrLC_Light/base_basis.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "stdafx.h" - -#include "base_basis.h" - -bool base_basis::similar(const base_basis& o) -{ - s32 dx = _abs(s32(x) - s32(o.x)); - s32 dy = _abs(s32(y) - s32(o.y)); - s32 dz = _abs(s32(z) - s32(o.z)); - return (dx <= 1 && dy <= 1 && dz <= 1); -} diff --git a/src/utils/xrLC_Light/base_basis.h b/src/utils/xrLC_Light/base_basis.h deleted file mode 100644 index 6f3d6730b36..00000000000 --- a/src/utils/xrLC_Light/base_basis.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -class XRLC_LIGHT_API base_basis -{ -public: - u8 x, y, z; - void set(Fvector N) - { - N.normalize_safe(); - N.add(1.f); - N.mul(.5f * 255.f); - s32 nx = iFloor(N.x); - clamp(nx, 0, 255); - x = u8(nx); - s32 ny = iFloor(N.y); - clamp(ny, 0, 255); - y = u8(ny); - s32 nz = iFloor(N.z); - clamp(nz, 0, 255); - z = u8(nz); - } - void set(float x, float y, float z) - { - Fvector N = {x, y, z}; - set(N); - } - bool similar(const base_basis& o); -}; diff --git a/src/utils/xrLC_Light/base_color.cpp b/src/utils/xrLC_Light/base_color.cpp deleted file mode 100644 index 1e55722ac46..00000000000 --- a/src/utils/xrLC_Light/base_color.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "stdafx.h" -#include "base_color.h" - -bool base_color::similar(const base_color& c, float eps /*=EPS*/) const -{ - bool ret = r._value == c.r._value && g._value == c.g._value && b._value == c.b._value && h._value == c.h._value && - s._value == c.s._value && t._value == c.t._value; - if (!ret) - { - Msg("base color diff : dr = %d , dg = %d, db = %d, dh = %d, ds = %d, dt = %d ", r._value - c.r._value, - g._value - c.g._value, b._value - c.b._value, h._value - c.h._value, s._value - c.s._value, - t._value - c.t._value); - Msg("base color : r = %d,%d , g = %d,%d, b = %d,%d, h = %d,%d, s = %d,%d, t = %d,%d ", r._value, c.r._value, - g._value, c.g._value, b._value, c.b._value, h._value, c.h._value, s._value, c.s._value, t._value, - c.t._value); - } - return ret; -} diff --git a/src/utils/xrLC_Light/base_color.h b/src/utils/xrLC_Light/base_color.h deleted file mode 100644 index 014f3a13805..00000000000 --- a/src/utils/xrLC_Light/base_color.h +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -template -struct fixed16 -{ - s16 _value; - - void _w(float a) - { - s32 _v = iFloor(a * 32767.f / float(range)); - clamp(_v, -32768, 32767); - _value = _v; - } - float _r() const { return float((_value / 32767.f) * float(range)); } -}; - -class XRLC_LIGHT_API base_color_c -{ -public: - Fvector rgb; // - all static lighting - float hemi; // - hemisphere - float sun; // - sun - float _tmp_; // ??? - base_color_c() - { - rgb.set(0, 0, 0); - hemi = 0; - sun = 0; - _tmp_ = 0; - } - - void mul(float s) - { - rgb.mul(s); - hemi *= s; - sun *= s; - }; - void add(float s) - { - rgb.add(s); - hemi += s; - sun += s; - }; - void add(base_color_c& s) - { - rgb.add(s.rgb); - hemi += s.hemi; - sun += s.sun; - }; - void scale(int samples) { mul(1.f / float(samples)); }; - void max(base_color_c& s) - { - rgb.max(s.rgb); - hemi = _max(hemi, s.hemi); - sun = _max(sun, s.sun); - }; - void lerp(base_color_c& A, base_color_c& B, float s) - { - rgb.lerp(A.rgb, B.rgb, s); - float is = 1 - s; - hemi = is * A.hemi + s * B.hemi; - sun = is * A.sun + s * B.sun; - }; -}; - -class XRLC_LIGHT_API base_color -{ -public: - union - { - struct - { - fixed16<16> r; - fixed16<16> g; - fixed16<16> b; - fixed16<16> h; - fixed16<16> s; - fixed16<16> t; - }; - struct - { - float _x; - float _y; - float _z; - }; - }; - void _set(float x, float y, float z) - { - _x = x; - _y = y; - _z = z; - } - void _set(base_color_c& C) - { - r._w(C.rgb.x); - g._w(C.rgb.y); - b._w(C.rgb.z); - h._w(C.hemi); - s._w(C.sun); - t._w(C._tmp_); - } - - void _set(Fvector& rgb, float hemi, float sun) - { - r._w(rgb.x); - g._w(rgb.y); - b._w(rgb.z); - h._w(hemi); - s._w(sun); // t._w(_tmp_); - } - void _get(base_color_c& C) const - { - C.rgb.x = r._r(); - C.rgb.y = g._r(); - C.rgb.z = b._r(); - C.hemi = h._r(); - C.sun = s._r(); - C._tmp_ = t._r(); - } - bool similar(const base_color& c, float eps = EPS) const; -}; diff --git a/src/utils/xrLC_Light/base_face.cpp b/src/utils/xrLC_Light/base_face.cpp deleted file mode 100644 index 9e643dae064..00000000000 --- a/src/utils/xrLC_Light/base_face.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "stdafx.h" - -#include "base_face.h" -#include "serialize.h" - -base_Face::base_Face() -{ - basis_tangent[0].set(0, 0, 0); - basis_tangent[1].set(0, 0, 0); - basis_tangent[2].set(0, 0, 0); - basis_binormal[0].set(0, 0, 0); - basis_binormal[1].set(0, 0, 0); - basis_binormal[2].set(0, 0, 0); -}; - -/* - - base_basis basis_tangent [3]; - base_basis basis_binormal [3]; - u16 dwMaterial; // index of material - u16 dwMaterialGame; // unique-id of game material (must persist up to game-CForm saving) - - struct { - u16 bSplitted : 1; - u16 bProcessed : 1; - u16 bOpaque : 1; // For ray-tracing speedup - u16 bLocked : 1; // For tesselation - } flags; -*/ -void base_Face::read(INetReader& r) -{ - r_pod(r, basis_tangent); - r_pod(r, basis_binormal); - dwMaterial = r.r_u16(); - dwMaterialGame = r.r_u16(); - r_pod(r, flags); -} -void base_Face::write(IWriter& w) const -{ - w_pod(w, basis_tangent); - w_pod(w, basis_binormal); - w.w_u16(dwMaterial); - w.w_u16(dwMaterialGame); - w_pod(w, flags); -} - -/* Fvector P; - Fvector N; - base_color C; // all_lighting info - int handle; // used in mesh-processing/optimization/conversion -*/ - -void base_Vertex::read(INetReader& r) -{ - r.r_fvector3(P); - r.r_fvector3(N); - r_pod(r, C); - handle = r.r_s32(); -} -void base_Vertex::write(IWriter& w) const -{ - w.w_fvector3(P); - w.w_fvector3(N); - w_pod(w, C); - w.w_s32(handle); -} diff --git a/src/utils/xrLC_Light/base_face.h b/src/utils/xrLC_Light/base_face.h deleted file mode 100644 index bc3070548bb..00000000000 --- a/src/utils/xrLC_Light/base_face.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "base_basis.h" -#include "base_color.h" - -struct Shader_xrLC; -class INetReader; - -class XRLC_LIGHT_API base_Face -{ -public: - base_basis basis_tangent[3]; - base_basis basis_binormal[3]; - - u16 dwMaterial; // index of material - u16 dwMaterialGame; // unique-id of game material (must persist up to game-CForm saving) - - struct - { - u16 bSplitted : 1; - u16 bProcessed : 1; - u16 bOpaque : 1; // For ray-tracing speedup - u16 bLocked : 1; // For tesselation - } flags; - - virtual const Shader_xrLC& Shader() const; - virtual void CacheOpacity(); - virtual Fvector2* getTC0() = 0; - - base_Face(); - - virtual ~base_Face() = 0; - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; -}; - -inline base_Face::~base_Face() = default; - - -class XRLC_LIGHT_API base_Vertex -{ -public: - Fvector P; - Fvector N; - base_color C; // all_lighting info - int handle; // used in mesh-processing/optimization/conversion -public: - base_Vertex() {} - virtual ~base_Vertex() = 0; - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; -}; - -inline base_Vertex::~base_Vertex() = default; diff --git a/src/utils/xrLC_Light/base_face_ptr_storage.h b/src/utils/xrLC_Light/base_face_ptr_storage.h deleted file mode 100644 index 79e110396d9..00000000000 --- a/src/utils/xrLC_Light/base_face_ptr_storage.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "xrCDB/xrCDB.h" - -class base_Face; - -inline u32 g_base_face_index = 0; -inline xr_vector g_base_face_pointers { nullptr }; - -inline void store_base_face_pointer(CDB::TRI& tri, base_Face* face) -{ - if constexpr (sizeof(u32) == sizeof(base_Face*)) - { - tri.dummy = *reinterpret_cast(&face); - return; - } - const u32 idx = g_base_face_index++; // It's important to have postfix increment! - tri.dummy = idx; - - if (g_base_face_pointers.size() < idx) - g_base_face_pointers.resize(g_base_face_pointers.size() * 2); - - g_base_face_pointers[idx] = face; -} - -inline base_Face* get_base_face_pointer(const CDB::TRI& tri) -{ - if constexpr (sizeof(u32) == sizeof(base_Face*)) - { - return *reinterpret_cast(&tri.dummy); - } - if (tri.dummy < g_base_face_pointers.size()) - return g_base_face_pointers[tri.dummy]; - return nullptr; -} diff --git a/src/utils/xrLC_Light/base_lighting.cpp b/src/utils/xrLC_Light/base_lighting.cpp deleted file mode 100644 index 408ac72e4d0..00000000000 --- a/src/utils/xrLC_Light/base_lighting.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "stdafx.h" - -#include "base_lighting.h" -#include "serialize.h" -void base_lighting::select(xr_vector& dest, xr_vector& src, Fvector& P, float R) -{ - Fsphere Sphere; - Sphere.set(P, R); - dest.clear(); - for (const R_Light& L : src) - { - if (L.type == LT_POINT) - { - float dist = Sphere.P.distance_to(L.position); - if (dist > (Sphere.R + L.range)) - continue; - } - dest.emplace_back(L); - } -} -void base_lighting::select(base_lighting& from, Fvector& P, float R) -{ - select(rgb, from.rgb, P, R); - select(hemi, from.hemi, P, R); - select(sun, from.sun, P, R); -} -/* - xr_vector rgb; // P,N - xr_vector hemi; // P,N - xr_vector sun; // P -*/ -void base_lighting::read(INetReader& r) -{ - r_pod_vector(r, rgb); - r_pod_vector(r, hemi); - r_pod_vector(r, sun); -} -void base_lighting::write(IWriter& w) const -{ - w_pod_vector(w, rgb); - w_pod_vector(w, hemi); - w_pod_vector(w, sun); -} diff --git a/src/utils/xrLC_Light/base_lighting.h b/src/utils/xrLC_Light/base_lighting.h deleted file mode 100644 index d4d80dc9944..00000000000 --- a/src/utils/xrLC_Light/base_lighting.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "r_light.h" - -class INetReader; - -#pragma pack(push, 4) -class XRLC_LIGHT_API base_lighting -{ -public: - xr_vector rgb; // P,N - xr_vector hemi; // P,N - xr_vector sun; // P - - void select(xr_vector& dest, xr_vector& src, Fvector& P, float R); - void select(base_lighting& from, Fvector& P, float R); - void read(INetReader& r); - void write(IWriter& w) const; -}; -#pragma pack(pop) diff --git a/src/utils/xrLC_Light/calculate_normals.h b/src/utils/xrLC_Light/calculate_normals.h deleted file mode 100644 index 8cc7ed1cefb..00000000000 --- a/src/utils/xrLC_Light/calculate_normals.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __CALCULATE_NORMALS_H__ -#define __CALCULATE_NORMALS_H__ - -#include "itterate_adjacents_static.h" -#include "itterate_adjacents.h" - -template -class calculate_normals -{ - typedef typeVertex type_vertex; - typedef calculate_normals type_self; - typedef typename typeVertex::type_face type_face; - // these typedefs to hide global typedefs!!! - typedef xr_vector vecVertex; - typedef typename vecVertex::iterator vecVertexIt; - typedef xr_vector vecFace; - typedef typename vecFace::iterator vecFaceIt; - - typedef vecFace vecAdj; - typedef typename vecAdj::iterator vecAdjIt; - -private: - typedef itterate_adjacents> itterate_adjacents_type; - -public: - static void calc_normals(vecVertex& vertices, vecFace& faces) - { - u32 Vcount = vertices.size(); - float p_total = 0; - float p_cost = 1.f / (Vcount); - - // Clear temporary flag - Logger.Status("Processing..."); - float sm_cos = _cos(deg2rad(g_params().m_sm_angle)); - - for (vecFaceIt it = faces.begin(); it != faces.end(); ++it) - { - (*it)->flags.bSplitted = true; - (*it)->CalcNormal(); - } - - // remark: - // we use Face's bSplitted value to indicate that face is processed - // so bSplitted means bUsed - for (u32 I = 0; I < Vcount; I++) - { - type_vertex* pTestVertex = vertices[I]; - for (vecAdjIt AFit = pTestVertex->m_adjacents.begin(); AFit != pTestVertex->m_adjacents.end(); ++AFit) - { - type_face* F = *AFit; - F->flags.bSplitted = false; - } - std::sort(pTestVertex->m_adjacents.begin(), pTestVertex->m_adjacents.end()); - - while (pTestVertex->m_adjacents.size()) - { - vecFace new_adj; - itterate_adjacents_type::recurse_tri_params p(pTestVertex, new_adj, sm_cos); - itterate_adjacents_type::RecurseTri(0, p); // pTestVertex, new_adj, sm_cos ); - VERIFY(!new_adj.empty()); - - type_vertex* pNewVertex = pTestVertex->CreateCopy_NOADJ(vertices); - - for (u32 a = 0; a < new_adj.size(); ++a) - { - type_face* test = new_adj[a]; - test->VReplace(pTestVertex, pNewVertex); - } - - pNewVertex->normalFromAdj(); - } - Logger.Progress(p_total += p_cost); - } - Logger.Progress(1.f); - - // Destroy unused vertices - - isolate_vertices(FALSE, vertices); - - // Recalculate normals - for (vecVertexIt it = vertices.begin(); it != vertices.end(); ++it) - (*it)->normalFromAdj(); - - Logger.clMsg("%d vertices was duplicated 'cause of SM groups", vertices.size() - Vcount); - - // Clear temporary flag - for (vecFaceIt it = faces.begin(); it != faces.end(); ++it) - (*it)->flags.bSplitted = false; - } -}; -#endif //__CALCULATE_NORMALS_H__ diff --git a/src/utils/xrLC_Light/compiler.cpp b/src/utils/xrLC_Light/compiler.cpp deleted file mode 100644 index 5fed5be2f16..00000000000 --- a/src/utils/xrLC_Light/compiler.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "stdafx.h" -#include "Common/LevelStructure.hpp" -#include "utils/xrLCUtil/xrThread.hpp" - -#include "global_calculation_data.h" -#include "lightthread.h" -#include "xrLightDoNet.h" - -void xrLight() -{ - u32 range = gl_data.slots_data.size_z(); - - // Start threads, wait, continue --- perform all the work - CThreadManager Threads(ProxyStatus, ProxyProgress); - CTimer start_time; - start_time.Start(); - u32 stride = range / NUM_THREADS; - u32 last = range - stride * (NUM_THREADS - 1); - for (u32 thID = 0; thID < NUM_THREADS; thID++) - { - CThread* T = - xr_new(thID, thID * stride, thID * stride + ((thID == (NUM_THREADS - 1)) ? last : stride)); - T->thMessages = FALSE; - T->thMonitor = FALSE; - Threads.start(T); - } - Threads.wait(); - Msg("%d seconds elapsed.", (start_time.GetElapsed_ms()) / 1000); -} - -void xrCompileDO(bool net) -{ - Logger.Phase("Loading level..."); - gl_data.xrLoad(); - - Logger.Phase("Lighting nodes..."); - if (net) - lc_net::xrNetDOLight(); - else - xrLight(); - - gl_data.slots_data.Free(); -} diff --git a/src/utils/xrLC_Light/detail_net_global_data.cpp b/src/utils/xrLC_Light/detail_net_global_data.cpp deleted file mode 100644 index 702273cd634..00000000000 --- a/src/utils/xrLC_Light/detail_net_global_data.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "detail_net_global_data.h" -#include "serialize.h" -#include "file_compress.h" -#include "global_calculation_data.h" -namespace lc_net -{ -void net_global_data_impl::init() -{ - data_init(); // init as new data -} - -void net_global_data_impl::create_data_file(LPCSTR path) -{ - // FPU::m64r (); - // Memory.mem_compact (); - // if(!write_faces) - // inlc_global_data()->create_write_faces(); - Logger.clMsg("gl_detail_cl_data: start"); - - IWriter* file = FS.w_open(path); - gl_data.write(*file); - FS.w_close(file); - compress(path); - Logger.clMsg("gl_detail_cl_data: end"); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - decompress(path); - INetReaderFile r_global(path); - - gl_data.read(r_global); - // FPU::m64r (); - // Memory.mem_compact (); - return true; -} -void net_global_data_impl::destroy_data() -{ - // cl_globs.NetClear(); -} -} diff --git a/src/utils/xrLC_Light/detail_net_global_data.h b/src/utils/xrLC_Light/detail_net_global_data.h deleted file mode 100644 index 7c6a44f0e45..00000000000 --- a/src/utils/xrLC_Light/detail_net_global_data.h +++ /dev/null @@ -1,35 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef DETAIL_NET_GLOBAL_DATA_H_INCLUDED -#define DETAIL_NET_GLOBAL_DATA_H_INCLUDED - -// class detail_net_global_data - -#include "net_global_data.h" - -namespace lc_net -{ -template <> -class net_global_data_impl -{ -public: - net_global_data_impl() {} - void init(); - void cleanup() { data_cleanup(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(); - LPCSTR file_name() { return "gl_detail_cl_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; - -// template<> struct global_add_global{}; -} - -#endif // #ifndef DETAIL_NET_GLOBAL_DATA_H_INCLUDED diff --git a/src/utils/xrLC_Light/detail_slot_calculate.cpp b/src/utils/xrLC_Light/detail_slot_calculate.cpp deleted file mode 100644 index 71618de36be..00000000000 --- a/src/utils/xrLC_Light/detail_slot_calculate.cpp +++ /dev/null @@ -1,415 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "detail_slot_calculate.h" - -#include "xrCDB/Intersect.hpp" -#include "base_lighting.h" -#include "global_calculation_data.h" -#include "utils/Shader_xrLC.h" -#include "base_color.h" - -enum -{ - LP_DEFAULT = 0, - LP_UseFaceDisable = (1 << 0), - LP_dont_rgb = (1 << 1), - LP_dont_hemi = (1 << 2), - LP_dont_sun = (1 << 3), -}; - -float color_intensity(Fcolor& c) -{ - float ntsc = c.r * 0.2125f + c.g * 0.7154f + c.b * 0.0721f; - float absolute = c.magnitude_rgb() / 1.7320508075688772935274463415059f; - return ntsc * 0.5f + absolute * 0.5f; -} - -// IC u8 u8_clr (float a) { s32 _a = iFloor(a*255.f); clamp(_a,0,255); return u8(_a); }; -// IC u8 u8_clr (float a) { s32 _a = iFloor(a*255.f); clamp(_a,0,255); return u8(_a); }; - -//----------------------------------------------------------------------------------------------------------------- -const int LIGHT_Count = 7; - -//----------------------------------------------------------------- -thread_local Time t_start; -thread_local Duration t_time; -thread_local u64 t_count = 0; - -IC bool RayPick(CDB::COLLIDER& DB, u32 ray_options, Fvector& P, Fvector& D, float r, R_Light& L) -{ - // 1. Check cached polygon - float _u, _v, range; - bool res = CDB::TestRayTri(P, D, L.tri, _u, _v, range, true); - if (res) - { - if (range > 0 && range < r) - return true; - } - - // 2. Polygon doesn't pick - real database query - t_start = Clock::now(); - DB.ray_query(ray_options, &gl_data.RCAST_Model, P, D, r); - t_time += Clock::now() - t_start; - t_count += 1; - - // 3. Analyze - if (0 == DB.r_count()) - { - return false; - } - else - { - // cache polygon - CDB::RESULT& rpinf = *DB.r_begin(); - CDB::TRI& T = gl_data.RCAST_Model.get_tris()[rpinf.id]; - L.tri[0].set(rpinf.verts[0]); - L.tri[1].set(rpinf.verts[1]); - L.tri[2].set(rpinf.verts[2]); - return true; - } -} - -float getLastRP_Scale(CDB::COLLIDER* DB, R_Light& L) //, Face* skip) -{ - u32 tris_count = DB->r_count(); - float scale = 1.f; - Fvector B; - - // X_TRY - { - for (u32 I = 0; I < tris_count; I++) - { - CDB::RESULT& rpinf = DB->r_begin()[I]; - // Access to texture - CDB::TRI& clT = gl_data.RCAST_Model.get_tris()[rpinf.id]; - b_rc_face& F = gl_data.g_rc_faces[rpinf.id]; - // if (0==F) continue; - // if (skip==F) continue; - - b_material& M = gl_data.g_materials[F.dwMaterial]; - b_texture& T = gl_data.g_textures[M.surfidx]; - - const Shader_xrLC& SH = shader(F.dwMaterial, *(gl_data.g_shaders_xrlc), gl_data.g_materials); - // Shader_xrLCVec& LIB = gl_data.g_shaders_xrlc->Library (); - // if (M.shader_xrlc>=LIB.size()) return 0; //. hack - vy gonite rebyata - eto ne hack - - //eto - // sledy zamesti - shader_xrlc - index ne togo masiva !! - // Shader_xrLC& SH = LIB [M.shader_xrlc]; - - if (!SH.flags.bLIGHT_CastShadow) - continue; - -#ifdef DEBUG - const b_BuildTexture& build_texture = gl_data.g_textures[M.surfidx]; - - VERIFY(!!(build_texture.THM.HasSurface()) == !!(T.pSurface)); -#endif - - if (0 == T.pSurface) - T.bHasAlpha = FALSE; - if (!T.bHasAlpha) - { - // Opaque poly - cache it - L.tri[0].set(rpinf.verts[0]); - L.tri[1].set(rpinf.verts[1]); - L.tri[2].set(rpinf.verts[2]); - return 0; - } - - // barycentric coords - // note: W,U,V order - B.set(1.0f - rpinf.u - rpinf.v, rpinf.u, rpinf.v); - - // calc UV - Fvector2* cuv = F.t; - Fvector2 uv; - uv.x = cuv[0].x * B.x + cuv[1].x * B.y + cuv[2].x * B.z; - uv.y = cuv[0].y * B.x + cuv[1].y * B.y + cuv[2].y * B.z; - - int U = iFloor(uv.x * float(T.dwWidth) + .5f); - int V = iFloor(uv.y * float(T.dwHeight) + .5f); - U %= T.dwWidth; - if (U < 0) - U += T.dwWidth; - V %= T.dwHeight; - if (V < 0) - V += T.dwHeight; - - u32 pixel = T.pSurface[V * T.dwWidth + U]; - u32 pixel_a = color_get_A(pixel); - float opac = 1.f - float(pixel_a) / 255.f; - scale *= opac; - } - } - // X_CATCH - // { - // clMsg("* ERROR: getLastRP_Scale"); - // } - - return scale; -} - -float rayTrace(CDB::COLLIDER* DB, u32 ray_options, R_Light& L, Fvector& P, Fvector& D, float R) //, Face* skip) -{ - R_ASSERT(DB); - - // 1. Check cached polygon - float _u, _v, range; - bool res = CDB::TestRayTri(P, D, L.tri, _u, _v, range, false); - if (res) - { - if (range > 0 && range < R) - return 0; - } - - // 2. Polygon doesn't pick - real database query - DB->ray_query(ray_options, &gl_data.RCAST_Model, P, D, R); - - // 3. Analyze polygons and cache nearest if possible - if (0 == DB->r_count()) - { - return 1; - } - else - { - return getLastRP_Scale(DB, L); //,skip); - } - return 0; -} - -void LightPoint(CDB::COLLIDER* DB, u32 ray_options, base_color_c& C, Fvector& P, Fvector& N, base_lighting& lights, u32 flags) -{ - Fvector Ldir, Pnew; - Pnew.mad(P, N, 0.01f); - - if (0 == (flags & LP_dont_rgb)) - { - R_Light *L = &*lights.rgb.begin(), *E = &*lights.rgb.end(); - for (; L != E; L++) - { - if (L->type == LT_DIRECT) - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float scale = D * L->energy * rayTrace(DB, ray_options, *L, Pnew, Ldir, 1000.f); - C.rgb.x += scale * L->diffuse.x; - C.rgb.y += scale * L->diffuse.y; - C.rgb.z += scale * L->diffuse.z; - } - else - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, *L, Pnew, Ldir, R); - float A = scale / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD); - - C.rgb.x += A * L->diffuse.x; - C.rgb.y += A * L->diffuse.y; - C.rgb.z += A * L->diffuse.z; - } - } - } - if (0 == (flags & LP_dont_sun)) - { - R_Light* L = &*(lights.sun.begin()), * E = &*(lights.sun.end()); - for (; L != E; L++) - { - if (L->type == LT_DIRECT) - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float scale = L->energy * rayTrace(DB, ray_options, *L, Pnew, Ldir, 1000.f); - C.sun += scale; - } - else - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, *L, Pnew, Ldir, R); - float A = scale / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD); - - C.sun += A; - } - } - } - if (0 == (flags & LP_dont_hemi)) - { - R_Light* L = &*lights.hemi.begin(), * E = &*lights.hemi.end(); - for (; L != E; L++) - { - if (L->type == LT_DIRECT) - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - Fvector PMoved; - PMoved.mad(Pnew, Ldir, 0.001f); - float scale = L->energy * rayTrace(DB, ray_options, *L, PMoved, Ldir, 1000.f); - C.hemi += scale; - } - else - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, *L, Pnew, Ldir, R); - float A = scale / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD); - - C.hemi += A; - } - } - } -} - -bool detail_slot_process(u32 _x, u32 _z, DetailSlot& DS) -{ - process_pallete(DS); - if (gl_data.slots_data.skip_slot(_x, _z)) - return false; - return true; -} - -bool detail_slot_calculate( - u32 _x, u32 _z, DetailSlot& DS, DWORDVec& box_result, CDB::COLLIDER& DB, u32 box_options, u32 ray_options, base_lighting& Selected) -{ - /////////////////////////////////////////////////////////// - // Build slot BB & sphere - Fbox BB; - gl_data.slots_data.get_slot_box(BB, _x, _z); - - Fsphere S; - BB.getsphere(S.P, S.R); - - // Select polygons - Fvector bbC, bbD; - BB.get_CD(bbC, bbD); - bbD.add(0.01f); - DB.box_query(box_options, &gl_data.RCAST_Model, bbC, bbD); - - box_result.clear(); - for (auto &it : *DB.r_get()) - box_result.push_back(it.id); - if (box_result.empty()) - return false; - // continue; - - CDB::TRI* tris = gl_data.RCAST_Model.get_tris(); - Fvector* verts = gl_data.RCAST_Model.get_verts(); - - // select lights - Selected.select(gl_data.g_lights, S.P, S.R); - - // lighting itself - base_color_c amount; - u32 count = 0; - float coeff = DETAIL_SLOT_SIZE_2 / float(LIGHT_Count); - FPU::m64r(); - for (int x = -LIGHT_Count; x <= LIGHT_Count; x++) - { - Fvector P; - P.x = bbC.x + coeff * float(x); - - for (int z = -LIGHT_Count; z <= LIGHT_Count; z++) - { - // compute position - Fvector t_n; - t_n.set(0, 1, 0); - P.z = bbC.z + coeff * float(z); - P.y = BB.vMin.y - 5; - Fvector dir; - dir.set(0, -1, 0); - Fvector start; - start.set(P.x, BB.vMax.y + EPS, P.z); - - float r_u, r_v, r_range; - for (auto tit = box_result.begin(); tit != box_result.end(); ++tit) - { - CDB::TRI& T = tris[*tit]; - Fvector V[3] = {verts[T.verts[0]], verts[T.verts[1]], verts[T.verts[2]]}; - if (CDB::TestRayTri(start, dir, V, r_u, r_v, r_range, TRUE)) - { - if (r_range >= 0.f) - { - float y_test = start.y - r_range; - if (y_test > P.y) - { - P.y = y_test + EPS; - t_n.mknormal(V[0], V[1], V[2]); - } - } - } - } - if (P.y < BB.vMin.y) - continue; - - // light point - LightPoint(&DB, ray_options, amount, P, t_n, Selected, 0); - count += 1; - } - } - - // calculation of luminocity - amount.scale(count); - amount.mul(.5f); - DS.c_dir = DS.w_qclr(amount.sun, 15); - DS.c_hemi = DS.w_qclr(amount.hemi, 15); - DS.c_r = DS.w_qclr(amount.rgb.x, 15); - DS.c_g = DS.w_qclr(amount.rgb.y, 15); - DS.c_b = DS.w_qclr(amount.rgb.z, 15); - //////////////////////////////////////////////////////////// - return true; -} diff --git a/src/utils/xrLC_Light/detail_slot_calculate.h b/src/utils/xrLC_Light/detail_slot_calculate.h deleted file mode 100644 index b48a261e63e..00000000000 --- a/src/utils/xrLC_Light/detail_slot_calculate.h +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef DETAIL_SLOT_CALCULATE_H_INCLUDED -#define DETAIL_SLOT_CALCULATE_H_INCLUDED - -using Clock = std::chrono::high_resolution_clock; -using Time = Clock::time_point; -using Duration = Clock::duration; - -using DWORDVec = xr_vector; - -namespace CDB -{ -class COLLIDER; -} -class base_lighting; -struct DetailSlot; - -extern thread_local Duration t_time; -extern thread_local u64 t_count; - -bool detail_slot_calculate( - u32 _x, u32 _z, DetailSlot& DS, DWORDVec& box_result, CDB::COLLIDER& DB, u32 box_options, u32 ray_options, base_lighting& Selected); -bool detail_slot_process(u32 _x, u32 _z, DetailSlot& DS); -#endif // #ifndef DETAIL_SLOT_CALCULATE_H_INCLUDED diff --git a/src/utils/xrLC_Light/execute_statistics.cpp b/src/utils/xrLC_Light/execute_statistics.cpp deleted file mode 100644 index 738960ca3cc..00000000000 --- a/src/utils/xrLC_Light/execute_statistics.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 04.06.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "execute_statistics.h" -#include "serialize.h" - -LPCSTR make_time(string64& buf, float fsec); -#ifdef COLLECT_EXECUTION_STATS - -void execute_time_statistics::read(INetReader& r) { r_pod(r, *this); } -void execute_time_statistics::write(IWriter& w) const { w_pod(w, *this); } -void execute_time_statistics::log() const -{ - string64 buf; - Msg("calc time: %s ", make_time(buf, m_time)); -} - -void execute_statistics::read(INetReader& r) -{ - r_pod(r, dir); - time_stats.read(r); -} -void execute_statistics::write(IWriter& w) const -{ - w_pod(w, dir); - time_stats.write(w); -} -void execute_statistics::log() const -{ - Msg("agent: %s", dir); - time_stats.log(); -} - -#endif diff --git a/src/utils/xrLC_Light/execute_statistics.h b/src/utils/xrLC_Light/execute_statistics.h deleted file mode 100644 index 9bb371167a1..00000000000 --- a/src/utils/xrLC_Light/execute_statistics.h +++ /dev/null @@ -1,35 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 04.06.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef EXECUTE_STATISTICS_H_INCLUDED -#define EXECUTE_STATISTICS_H_INCLUDED -#ifdef COLLECT_EXECUTION_STATS -class INetReader; -class IWriter; -class execute_time_statistics -{ -public: - execute_time_statistics() : m_time(-1.f) {} - float m_time; - - void read(INetReader& r); - void write(IWriter& w) const; - void log() const; - -private: -}; // class execute_statistics -class execute_statistics -{ -public: - execute_time_statistics time_stats; - string_path dir; - void read(INetReader& r); - void write(IWriter& w) const; - void log() const; -}; - -#endif -#endif // #ifndef EXECUTE_STATISTICS_H_INCLUDED diff --git a/src/utils/xrLC_Light/file_compress.cpp b/src/utils/xrLC_Light/file_compress.cpp deleted file mode 100644 index c2cb5d7f224..00000000000 --- a/src/utils/xrLC_Light/file_compress.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "stdafx.h" -#include - -void compress(LPCSTR f_in, LPCSTR f_out); -void decompress(LPCSTR f_in, LPCSTR f_out); - -void compress(LPCSTR f_in, LPCSTR f_out) -{ - FILE* file = fopen(f_in, "rb"); - u32 buff_size = 1024 * 1024 / 2; - - void* buff = xr_alloca(buff_size); - gzFile z_file = gzopen(f_out, "wb"); - u32 const length = _filelength(_fileno(file)); - - for (int n = length / buff_size, i = 0; i < n; ++i) - { - fread(buff, 1, buff_size, file); - gzwrite(z_file, buff, buff_size); - } - buff_size = length % buff_size; - if (buff_size != 0) - { - fread(buff, 1, buff_size, file); - gzwrite(z_file, buff, buff_size); - } - fclose(file); - gzclose(z_file); -} - -void decompress(LPCSTR f_in, LPCSTR f_out) -{ - FILE* file = fopen(f_out, "wb"); - u32 buff_size = 1024 * 1024 / 2; - - // u32 const length = _filelength( _fileno( file ) ); - - void* buff = xr_alloca(buff_size); - gzFile z_file = gzopen(f_in, "rb"); - - for (;;) - { - u32 read = gzread(z_file, buff, buff_size); - fwrite(buff, 1, read, file); - if (read < buff_size) - break; - } - - fclose(file); - gzclose(z_file); -} - -void compress(LPCSTR f_in_out) -{ - string_path tmp; - strconcat(sizeof(tmp), tmp, f_in_out, "___ctmp"); - compress(f_in_out, tmp); - - if (GetFileAttributes(f_in_out) != u32(-1)) - xr_unlink(f_in_out); - // physically rename file - VerifyPath(f_in_out); - rename(tmp, f_in_out); -} - -void decompress(LPCSTR f_in_out) -{ - string_path tmp; - strconcat(sizeof(tmp), tmp, f_in_out, "___dtmp"); - decompress(f_in_out, tmp); - if (GetFileAttributes(f_in_out) != u32(-1)) - xr_unlink(f_in_out); - // physically rename file - VerifyPath(f_in_out); - rename(tmp, f_in_out); -} diff --git a/src/utils/xrLC_Light/file_compress.h b/src/utils/xrLC_Light/file_compress.h deleted file mode 100644 index d97af1a4d62..00000000000 --- a/src/utils/xrLC_Light/file_compress.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _FILE_COMPRESS_ -#define _FILE_COMPRESS_ -void compress(LPCSTR f_in, LPCSTR f_out); -void decompress(LPCSTR f_in, LPCSTR f_out); -void compress(LPCSTR f_in_out); -void decompress(LPCSTR f_in_out); -#endif diff --git a/src/utils/xrLC_Light/fitter.cpp b/src/utils/xrLC_Light/fitter.cpp deleted file mode 100644 index 9ec17e3c33e..00000000000 --- a/src/utils/xrLC_Light/fitter.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Module : fitter.cpp -// Created : 25.03.2002 -// Modified : 28.02.2003 -// Author : Dmitriy Iassenev -// Description : Weight Fitting Algorithm -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "fitter.h" -#include - -IC REAL dfEvaluation(REAL& A, REAL& C, REAL& D) { return (A * C + D); } -REAL dfComputeEvalResults(xr_vector>& daEvalResults, xr_vector>& A, - xr_vector>& B, xr_vector& C, xr_vector& D) -{ - REAL dResult = 0.0; - u32 dwTestCount = (u32)B.size(); - u32 dwParameterCount = (u32)B[0].size(); - - for (u32 i = 0; i < dwTestCount; i++) - { - for (u32 j = 0; j < dwParameterCount; j++) - { - daEvalResults[i][j] = dfEvaluation(A[i][j], C[j], D[j]); - REAL dTemp = B[i][j] - daEvalResults[i][j]; - dResult += dTemp * dTemp; - } - } - return (dResult); -} - -xr_vector& dafGradient(xr_vector>& daEvalResults, xr_vector& daResult, - xr_vector>& B, REAL dNormaFactor) -{ - REAL dNorma = 0.0; - u32 dwTestCount = (u32)B.size(); - u32 dwParameterCount = (u32)B[0].size(); - daResult.assign(dwParameterCount, 0); - - for (u32 i = 0; i < dwParameterCount; i++) - { - for (u32 j = 0; j < dwTestCount; j++) - daResult[i] -= B[j][i] - daEvalResults[j][i]; - dNorma += daResult[i] * daResult[i]; - } - dNorma = _sqrt(dNorma); - - for (u32 i = 0; i < dwParameterCount; i++) - daResult[i] /= (dNorma > 1.f ? dNorma : 1.f) * dNormaFactor; - - return (daResult); -} - -void vfOptimizeParameters(xr_vector>& A, xr_vector>& B, xr_vector& C, - xr_vector& D, REAL dEpsilon, REAL dAlpha, REAL dBeta, REAL dNormaFactor, u32 dwMaxIterationCount) -{ - u32 dwTestCount = (u32)B.size(); - xr_vector daGradient; - xr_vector daDelta; - xr_vector> daEvalResults; - daEvalResults.resize(dwTestCount); - - if (!B.size()) - { - Logger.clMsg("ERROR : there are no parameters to fit!"); - return; - } - - u32 dwParameterCount = (u32)B[0].size(); - C.assign(dwParameterCount, 1.0f); - D.assign(dwParameterCount, 0.0f); - daDelta.assign(dwParameterCount, 0); - daGradient.assign(dwParameterCount, 0); - { - for (u32 i = 0; i < dwTestCount; i++) - daEvalResults[i].resize(dwParameterCount); - } - u32 i = 0; - REAL dFunctional = dfComputeEvalResults(daEvalResults, A, B, C, D), dPreviousFunctional; - // clMsg ("***MU-fitter***: %6d : %17.8f (%17.8f)",i,dFunctional,dFunctional/dwTestCount); - do - { - dPreviousFunctional = dFunctional; - dafGradient(daEvalResults, daGradient, B, dNormaFactor); - std::transform(daGradient.begin(), daGradient.end(), daGradient.begin(), - std::bind(std::multiplies(), std::placeholders::_1, -dAlpha)); - std::transform(daDelta.begin(), daDelta.end(), daDelta.begin(), - std::bind(std::multiplies(), std::placeholders::_1, dBeta)); - std::transform(daGradient.begin(), daGradient.end(), daDelta.begin(), daDelta.begin(), std::plus()); - std::transform(C.begin(), C.end(), daDelta.begin(), C.begin(), std::plus()); - std::transform(D.begin(), D.end(), daDelta.begin(), D.begin(), std::plus()); - dFunctional = dfComputeEvalResults(daEvalResults, A, B, C, D); - i++; - } while ((((dPreviousFunctional - dFunctional) / dwTestCount) > dEpsilon) && (i <= dwMaxIterationCount)); - - if (dPreviousFunctional < dFunctional) - { - std::transform(daDelta.begin(), daDelta.end(), daDelta.begin(), - std::bind(std::multiplies(), std::placeholders::_1, -1.f)); - std::transform(C.begin(), C.end(), daDelta.begin(), C.begin(), std::plus()); - std::transform(D.begin(), D.end(), daDelta.begin(), D.begin(), std::plus()); - } - - dFunctional = dfComputeEvalResults(daEvalResults, A, B, C, D); - // clMsg ("***MU-fitter***: %6d : %17.8f (%17.8f)",i,dFunctional,dFunctional/dwTestCount); -} diff --git a/src/utils/xrLC_Light/fitter.h b/src/utils/xrLC_Light/fitter.h deleted file mode 100644 index a64f3f99880..00000000000 --- a/src/utils/xrLC_Light/fitter.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -typedef float REAL; - -extern void vfOptimizeParameters(xr_vector>& A, xr_vector>& B, xr_vector& C, - xr_vector& D, REAL dEpsilon = REAL(0.001), REAL dAlpha = REAL(1.0), REAL dBeta = REAL(0.01), - REAL dNormaFactor = REAL(10.0), u32 dwMaxIterationCount = 10000); - -template -void vfComputeLinearRegression(xr_vector& A, xr_vector& B, T2& C, T2& D) -{ - u32 N = A.size(); - T sx = T(0), sy = T(0), sxy = T(0), sx2 = T(0), l_tDenominator; - sx = std::accumulate(A.begin(), A.end(), sx); - sy = std::accumulate(B.begin(), B.end(), sy); - sxy = std::inner_product(A.begin(), A.end(), B.begin(), sxy); - sx2 = std::inner_product(A.begin(), A.end(), A.begin(), sx2); - l_tDenominator = T(N) * sx2 - sx * sx; - if (_abs(l_tDenominator) > EPS_S) - C = T2((T(N) * sxy - sx * sy) / l_tDenominator); - else - C = T2(0); - if (N) - D = T2((sy - C * sx) / T(N)); - else - D = T2(0); -} diff --git a/src/utils/xrLC_Light/gl_base_cl_data.cpp b/src/utils/xrLC_Light/gl_base_cl_data.cpp deleted file mode 100644 index 8a53a39e62b..00000000000 --- a/src/utils/xrLC_Light/gl_base_cl_data.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 19.05.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "gl_base_cl_data.h" - -#include "xrlc_globaldata.h" -#include "file_compress.h" - -namespace lc_net -{ -void net_global_data_impl::create_data_file(LPCSTR path) -{ - FPU::m64r(); - Memory.mem_compact(); - // std::random_shuffle (inlc_global_data()->g_deflectors().begin(),inlc_global_data()->g_deflectors().end()); - Logger.clMsg("create_base_global_data_write: start"); - IWriter* file = FS.w_open(path); - inlc_global_data()->write_base(*file); - FS.w_close(file); - compress(path); - Logger.clMsg("create_base_global_data_write: end"); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - decompress(path); - INetReaderFile r_global(path); - create_global_data(); - - VERIFY(inlc_global_data()); - inlc_global_data()->read_base(r_global); - - // xr_unlink( fn ); - - FPU::m64r(); - Memory.mem_compact(); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); - return true; -} -} diff --git a/src/utils/xrLC_Light/gl_base_cl_data.h b/src/utils/xrLC_Light/gl_base_cl_data.h deleted file mode 100644 index 19d3f5e0270..00000000000 --- a/src/utils/xrLC_Light/gl_base_cl_data.h +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 19.05.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef GL_BASE_CL_DATA_H_INCLUDED -#define GL_BASE_CL_DATA_H_INCLUDED - -#include "net_global_data.h" - -namespace lc_net -{ -template <> -class net_global_data_impl -{ -public: - void init() { data_init(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(){}; - LPCSTR file_name() { return "gl_base_cl_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; -} - -#endif // #ifndef GL_BASE_CL_DATA_H_INCLUDED diff --git a/src/utils/xrLC_Light/global_calculation_data.cpp b/src/utils/xrLC_Light/global_calculation_data.cpp deleted file mode 100644 index 8f6c462b301..00000000000 --- a/src/utils/xrLC_Light/global_calculation_data.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "stdafx.h" -#include "global_calculation_data.h" -#include "utils/Shader_xrLC.h" -#include "serialize.h" - -global_claculation_data gl_data; - -template -void transfer(const char* name, xr_vector& dest, IReader& F, u32 chunk) -{ - IReader* O = F.open_chunk(chunk); - size_t count = O ? (O->length() / sizeof(T)) : 0; - Logger.clMsg("* %16s: %d", name, count); - if (count) - { - dest.reserve(count); - dest.insert(dest.begin(), (T*)O->pointer(), (T*)O->pointer() + count); - } - if (O) - O->close(); -} - -extern u32* Surface_Load(char* name, u32& w, u32& h); -extern void Surface_Init(); - -void global_claculation_data::xrLoad() -{ - string_path N; - FS.update_path(N, "$game_data$", "shaders_xrlc.xr"); - g_shaders_xrlc = xr_new(); - g_shaders_xrlc->Load(N); - - // Load CFORM - { - FS.update_path(N, "$level$", "build.cform"); - IReader* fs = FS.r_open("$level$", "build.cform"); - - R_ASSERT(fs->find_chunk(0)); - hdrCFORM H; - fs->r(&H, sizeof(hdrCFORM)); - R_ASSERT(CFORM_CURRENT_VERSION == H.version); - - Fvector* verts = (Fvector*)fs->pointer(); - CDB::TRI* tris = (CDB::TRI*)(verts + H.vertcount); - RCAST_Model.build(verts, H.vertcount, tris, H.facecount); - Msg("* Level CFORM: %dK", RCAST_Model.memory() / 1024); - - g_rc_faces.resize(H.facecount); - R_ASSERT(fs->find_chunk(1)); - fs->r(&*g_rc_faces.begin(), g_rc_faces.size() * sizeof(b_rc_face)); - - LevelBB.set(H.aabb); - } - - { - slots_data.Load(); - } - // Lights - { - IReader* fs = FS.r_open("$level$", "build.lights"); - IReader* F; - size_t cnt; - R_Light* L; - - // rgb - F = fs->open_chunk(0); - cnt = F->length() / sizeof(R_Light); - L = (R_Light*)F->pointer(); - g_lights.rgb.assign(L, L + cnt); - F->close(); - - // hemi - F = fs->open_chunk(1); - cnt = F->length() / sizeof(R_Light); - L = (R_Light*)F->pointer(); - g_lights.hemi.assign(L, L + cnt); - F->close(); - - // sun - F = fs->open_chunk(2); - cnt = F->length() / sizeof(R_Light); - L = (R_Light*)F->pointer(); - g_lights.sun.assign(L, L + cnt); - F->close(); - - FS.r_close(fs); - } - - // Load level data - { - IReader* fs = FS.r_open("$level$", "build.prj"); - IReader* F; - - // Version - u32 version; - fs->r_chunk(EB_Version, &version); - R_ASSERT(XRCL_CURRENT_VERSION == version); - - // Header - fs->r_chunk(EB_Parameters, &g_params); - - // Load level data - transfer("materials", g_materials, *fs, EB_Materials); - transfer("shaders_xrlc", g_shader_compile, *fs, EB_Shaders_Compile); - post_process_materials(*g_shaders_xrlc, g_shader_compile, g_materials); -// process textures -#ifdef DEBUG - xr_vector dbg_textures; -#endif - Logger.Status("Processing textures..."); - { - Surface_Init(); - F = fs->open_chunk(EB_Textures); - const size_t tex_count = F->length() / sizeof(b_texture); - for (size_t t = 0; t < tex_count; t++) - { - Logger.Progress(float(t) / float(tex_count)); - - b_BuildTexture BT(F); - -#ifdef DEBUG - dbg_textures.push_back(static_cast(BT)); -#endif - - // load thumbnail - pstr N = BT.name; - if (strchr(N, '.')) - *(strchr(N, '.')) = 0; - xr_strlwr(N); - - if (0 == xr_strcmp(N, "level_lods")) - { - // HACK for merged lod textures - BT.dwWidth = 1024; - BT.dwHeight = 1024; - BT.bHasAlpha = TRUE; - BT.pSurface = 0; - BT.THM.SetHasSurface(false); - } - else - { - xr_strcat(N, sizeof(BT.name), ".thm"); - IReader* THM = FS.r_open("$game_textures$", N); - R_ASSERT2(THM, N); - - // version - u32 version = 0; - R_ASSERT(THM->r_chunk(THM_CHUNK_VERSION, &version)); - // if( version!=THM_CURRENT_VERSION ) FATAL ("Unsupported version of THM file."); - - // analyze thumbnail information - R_ASSERT(THM->find_chunk(THM_CHUNK_TEXTUREPARAM)); - THM->r(&BT.THM.fmt, sizeof(STextureParams::ETFormat)); - BT.THM.flags.assign(THM->r_u32()); - BT.THM.border_color = THM->r_u32(); - BT.THM.fade_color = THM->r_u32(); - BT.THM.fade_amount = THM->r_u32(); - BT.THM.mip_filter = THM->r_u32(); - BT.THM.width = THM->r_u32(); - BT.THM.height = THM->r_u32(); - BOOL bLOD = FALSE; - if (N[0] == 'l' && N[1] == 'o' && N[2] == 'd' && N[3] == '\\') - bLOD = TRUE; - - // load surface if it has an alpha channel or has "implicit lighting" flag - BT.dwWidth = BT.THM.width; - BT.dwHeight = BT.THM.height; - BT.bHasAlpha = BT.THM.HasAlphaChannel(); - BT.pSurface = 0; - BT.THM.SetHasSurface(false); - if (!bLOD) - { - if (BT.bHasAlpha || BT.THM.flags.test(STextureParams::flImplicitLighted)) - { - Logger.clMsg("- loading: %s", N); - u32 w = 0, h = 0; - BT.pSurface = Surface_Load(N, w, h); - BT.THM.SetHasSurface(true); - R_ASSERT2(BT.pSurface, "Can't load surface"); - if ((w != BT.dwWidth) || (h != BT.dwHeight)) - Msg("! THM doesn't correspond to the texture: %dx%d -> %dx%d", BT.dwWidth, BT.dwHeight, - w, h); - BT.Vflip(); - } - else - { - // Free surface memory - } - } - } - - // save all the stuff we've created - g_textures.push_back(BT); - } - } - } -} - -void read(INetReader& r, CDB::MODEL& m); - -void global_claculation_data::read(INetReader& r) -{ - g_lights.read(r); - R_ASSERT(!g_shaders_xrlc); - g_shaders_xrlc = xr_new(); - r_pod_vector(r, g_shaders_xrlc->Library()); - r_pod(r, g_params); - r_pod_vector(r, g_materials); - r_vector(r, g_textures); - ::read(r, RCAST_Model); - r_pod(r, LevelBB); - slots_data.read(r); - r_pod_vector(r, g_shader_compile); - r_pod_vector(r, g_rc_faces); -} - -// base_lighting g_lights; /////////////////////lc -// Shader_xrLC_LIB* g_shaders_xrlc;////////////////lc -// b_params g_params;//////////////////////lc -// xr_vector g_materials;///////////////////lc -// xr_vector g_textures;////////////////////lc -// CDB::MODEL RCAST_Model;///////////////////lc - -// Fbox LevelBB;//-----------============ -// global_slots_data slots_data;//-------============= -// xr_vector g_shader_compile;//-----========== -// xr_vector g_rc_faces;//---------=============== - -void write(IWriter& w, const CDB::MODEL& m); -void global_claculation_data::write(IWriter& w) const -{ - g_lights.write(w); - R_ASSERT(g_shaders_xrlc); - w_pod_vector(w, g_shaders_xrlc->Library()); - w_pod(w, g_params); - w_pod_vector(w, g_materials); - w_vector(w, g_textures); - ::write(w, RCAST_Model); - w_pod(w, LevelBB); - slots_data.write(w); - w_pod_vector(w, g_shader_compile); - w_pod_vector(w, g_rc_faces); -} diff --git a/src/utils/xrLC_Light/global_calculation_data.h b/src/utils/xrLC_Light/global_calculation_data.h deleted file mode 100644 index bfc9b28d966..00000000000 --- a/src/utils/xrLC_Light/global_calculation_data.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "utils/communicate.h" -#include "base_lighting.h" -#include "global_slots_data.h" -#include "b_build_texture.h" -#include "global_slots_data.h" -#include "xrCDB/xrCDB.h" -class Shader_xrLC_LIB; -//----------------------------------------------------------------- -struct global_claculation_data -{ - base_lighting g_lights; /////////////////////lc - Shader_xrLC_LIB* g_shaders_xrlc; ////////////////lc - b_params g_params; //////////////////////lc - xr_vector g_materials; ///////////////////lc - xr_vector g_textures; ////////////////////lc - CDB::MODEL RCAST_Model; ///////////////////lc - - Fbox LevelBB; //-----------============ - global_slots_data slots_data; //-------============= - xr_vector g_shader_compile; //-----========== - xr_vector g_rc_faces; //---------=============== - /////////////////////////////////////////////////////////////////////// - void read(INetReader& r); - void write(IWriter& w) const; - ////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////// - global_claculation_data() : g_shaders_xrlc(0) {} - void xrLoad(); -}; -extern global_claculation_data gl_data; diff --git a/src/utils/xrLC_Light/global_slots_data.cpp b/src/utils/xrLC_Light/global_slots_data.cpp deleted file mode 100644 index 34b7e1ee824..00000000000 --- a/src/utils/xrLC_Light/global_slots_data.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "stdafx.h" - -#include "global_slots_data.h" -#include "serialize.h" - -void global_slots_data::Load() -{ - // Load .details - // copy - // if() - - IReader* R = FS.r_open("$level$", "build.details"); - R->r_chunk(0, &dtH); - R->seek(0); - u32 check_sum = crc32(R->pointer(), R->length()); - - recalculation_data.load(check_sum); - if (!recalculation_data.recalculating()) - { - IWriter* W = FS.w_open("$level$", "level.details"); - W->w(R->pointer(), R->length()); - FS.w_close(W); - } - - FS.r_close(R); - - // re-open - string_path N; - FS.update_path(N, "$level$", "level.details"); - dtFS = xr_new(N); - - R_ASSERT(dtH.version() == DETAIL_VERSION); - - dtFS->find_chunk(2); - dtS = (DetailSlot*)dtFS->pointer(); -} - -void global_slots_data::Free() -{ - if (dtFS) - xr_delete(dtFS); - recalculation_data.close(); -} - -// DetailHeader dtH; -// DetailSlot *dtS; -// CVirtualFileRW *dtFS; -// recalculation recalculation_data; - -void global_slots_data::write(IWriter& w) const -{ - w_pod(w, dtH); - const size_t buffer_size = sizeof(DetailSlot) * dtH.slot_count(); - w.w(dtS, buffer_size); - recalculation_data.write(w); -} - -void global_slots_data::read(INetReader& r) -{ - r_pod(r, dtH); - R_ASSERT(!dtS); - const size_t buffer_size = sizeof(DetailSlot) * dtH.slot_count(); - dtS = (DetailSlot*)xr_malloc(buffer_size); - R_ASSERT(dtS); - r.r(dtS, buffer_size); - recalculation_data.read(r); -} - -void global_slots_data::FreeOnAgent() { xr_delete(dtS); } -void global_slots_data::process_all_pallete() -{ - R_ASSERT(header().version() != u32(-1)); - R_ASSERT(header().x_size() != u32(-1)); - R_ASSERT(header().z_size() != u32(-1)); - for (u32 i = 0; i < header().slot_count(); ++i) - { - DetailSlot& DS = get_slot(i); - process_pallete(DS); - - if (is_empty(DS)) - recalculation_data.set_slot_calculated(i); - } -} diff --git a/src/utils/xrLC_Light/global_slots_data.h b/src/utils/xrLC_Light/global_slots_data.h deleted file mode 100644 index 25cf90f3b78..00000000000 --- a/src/utils/xrLC_Light/global_slots_data.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#ifndef __GLOBAL_SLOTS_DATA_H__ -#define __GLOBAL_SLOTS_DATA_H__ - -#include "Layers/xrRender/DetailFormat.h" -#include "recalculation.h" - -class INetReader; -class IWriter; - -class global_slots_data -{ -private: - DetailHeader dtH; - DetailSlot* dtS; - CVirtualFileRW* dtFS; - recalculation recalculation_data; - -public: - global_slots_data() : dtS(0), dtFS(0), recalculation_data(dtH) {} - void Load(); - void Free(); - - void FreeOnAgent(); - - void read(INetReader& r); - void write(IWriter& w) const; - - IC const DetailHeader& header() const { return dtH; } - IC u32 size_x() const { return dtH.x_size(); } - IC u32 size_z() const { return dtH.z_size(); } - IC void set_slot_calculated(int _x, int _z) { recalculation_data.set_slot_calculated(_x, _z); } - IC bool calculate_ignore(int _x, int _z) const { return recalculation_data.skip_slot(_x, _z); } - IC bool skip_slot(int _x, int _z) const { return is_empty(get_slot(_x, _z)) || calculate_ignore(_x, _z); } - IC DetailSlot& get_slot(int _x, int _z) { return dtS[dtH.slot_index(_x, _z)]; } - IC const DetailSlot& get_slot(int _x, int _z) const { return dtS[dtH.slot_index(_x, _z)]; } - IC const DetailSlot& get_slot(u32 idx) const - { - VERIFY(idx < dtH.slot_count()); - return dtS[idx]; - } - IC DetailSlot& get_slot(u32 idx) - { - VERIFY(idx < dtH.slot_count()); - return dtS[idx]; - } - - IC Fvector& get_slot_box_min(Fvector& min, int _x, int _z) const - { - const DetailSlot& DS = get_slot(_x, _z); - min.set(dtH.slot_min_x(_x), DS.r_ybase(), dtH.slot_min_z(_z)); - return min; - } - - IC Fvector& get_slot_box_max(Fvector& max, int _x, int _z) const - { - Fvector min, diameter; - get_slot_box_min(min, _x, _z); - get_slot_diameter(diameter, get_slot(_x, _z)); - max.add(min, diameter); - return max; - } - - IC void get_slot_box(Fbox& BB, int _x, int _z) const - { - get_slot_box_min(BB.vMin, _x, _z); - - Fvector diameter; - get_slot_diameter(diameter, get_slot(_x, _z)); - - BB.vMax.add(BB.vMin, diameter); - BB.grow(0.05f); - } - void process_all_pallete(); -}; - -#endif //__GLOBAL_SLOTS_DATA_H__ diff --git a/src/utils/xrLC_Light/hash2D.h b/src/utils/xrLC_Light/hash2D.h deleted file mode 100644 index 44df0f240ef..00000000000 --- a/src/utils/xrLC_Light/hash2D.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once -#include "serialize.h" -#include "xrCore/xr_types.h" -#include "xrCore/_fbox2.h" -#include "xrCore/_vector2.h" -#include "xrCore/_bitwise.h" -#include "xrCommon/xr_vector.h" - -template -class hash2D -{ - xr_vector table[s_Y][s_X]; - Fbox2 bounds; - Fvector2 size; - -public: - hash2D() - { - bounds.invalidate(); - size.set(0.f, 0.f); - - // for (u32 y=0; y(); - } - ~hash2D() - { - // for (u32 y=0; y& query(float x, float y) - { - int _x = iFloor(float(s_X) * (x - bounds.min.x) / size.x); - clamp(_x, 0, int(s_X - 1)); - int _y = iFloor(float(s_Y) * (y - bounds.min.y) / size.y); - clamp(_y, 0, int(s_Y - 1)); - return table[_y][_x]; - }; - - // vector_serialize< t_read > - // vector_serialize< t_write > - template - struct get_type - { - typedef TP type; - }; - - template - struct get_type - { - typedef TP type; - }; - - typedef typename get_type::type type; - - void read(INetReader& r, vector_serialize>>& rd) - { - r_pod(r, bounds); - - r.r_fvector2(size); - for (u32 y = 0; y < s_Y; y++) - for (u32 x = 0; x < s_Y; x++) - rd.read_ref(r, table[y][x]); - } - void write(IWriter& w, vector_serialize>>& wt) const - { - w_pod(w, bounds); - - w.w_fvector2(size); - for (u32 y = 0; y < s_Y; y++) - for (u32 x = 0; x < s_Y; x++) - wt.write_ref(w, table[y][x]); - } -}; diff --git a/src/utils/xrLC_Light/implicit_net_global_data.cpp b/src/utils/xrLC_Light/implicit_net_global_data.cpp deleted file mode 100644 index 2819c79e009..00000000000 --- a/src/utils/xrLC_Light/implicit_net_global_data.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "stdafx.h" -#include "implicit_net_global_data.h" -#include "xrlight_implicitcalcglobs.h" -#include "xrLC_GlobalData.h" -#include "xrface.h" -#include "file_compress.h" -extern ImplicitCalcGlobs cl_globs; -namespace lc_net -{ -void net_global_data_impl::init() -{ - data_init(); // init as new data -} - -void net_global_data_impl::create_data_file(LPCSTR path) -{ - // FPU::m64r (); - // Memory.mem_compact (); - // if(!write_faces) - // inlc_global_data()->create_write_faces(); - Logger.clMsg("create_implicit_data_write: start"); - R_ASSERT(write_faces); - - IWriter* file = FS.w_open(path); - cl_globs.write(*file); - FS.w_close(file); - - compress(path); - Logger.clMsg("create_implicit_data_write: end"); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - decompress(path); - INetReaderFile r_global(path); - - cl_globs.read(r_global); - FPU::m64r(); - Memory.mem_compact(); - return true; -} -void net_global_data_impl::destroy_data() { cl_globs.NetClear(); } -} diff --git a/src/utils/xrLC_Light/implicit_net_global_data.h b/src/utils/xrLC_Light/implicit_net_global_data.h deleted file mode 100644 index 0a6cc0b9fa6..00000000000 --- a/src/utils/xrLC_Light/implicit_net_global_data.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _NET_IMPLICIT_GLOBAL_DATA_H_ -#define _NET_IMPLICIT_GLOBAL_DATA_H_ -#include "net_global_data.h" -class ImplicitCalcGlobs; -namespace lc_net -{ -template <> -class net_global_data_impl -{ - // ImplicitCalcGlobs *data; -public: - net_global_data_impl() {} - void init(); - void cleanup() { data_cleanup(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(); - LPCSTR file_name() { return "gl_implicit_cl_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; - -template <> -struct global_add_global -{ -}; -// due to vertices gl_cl_data -> gl_lm_data - todo separate vertex data! -} -#endif diff --git a/src/utils/xrLC_Light/itterate_adjacents.h b/src/utils/xrLC_Light/itterate_adjacents.h deleted file mode 100644 index 78b6850de63..00000000000 --- a/src/utils/xrLC_Light/itterate_adjacents.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _ITTERATE_ADJACENTS_H_ -#define _ITTERATE_ADJACENTS_H_ - -template -class itterate_adjacents -{ - typedef typename itterate_adjacents_params::type_vertex type_vertex; - typedef typename itterate_adjacents_params::type_face type_face; - -public: - typedef itterate_adjacents_params recurse_tri_params; - - static void RecurseTri(u32 start_face_idx, recurse_tri_params& p) - { - for (u32 test_face_idx = 0; test_face_idx < p.current_adjacents_size(); ++test_face_idx) - { - if (p.add_adjacents(start_face_idx, test_face_idx)) - RecurseTri(test_face_idx, p); - } - } -}; - -#endif diff --git a/src/utils/xrLC_Light/itterate_adjacents_static.h b/src/utils/xrLC_Light/itterate_adjacents_static.h deleted file mode 100644 index 2151b794f61..00000000000 --- a/src/utils/xrLC_Light/itterate_adjacents_static.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _ITTERATE_ADJACENTS_STATIC_H_ -#define _ITTERATE_ADJACENTS_STATIC_H_ -#include "common/face_smoth_flags.h" - -extern XRLC_LIGHT_API bool g_using_smooth_groups; -extern XRLC_LIGHT_API bool g_smooth_groups_by_faces; - -template -struct itterate_adjacents_params_static -{ - typedef typeVertex type_vertex; - typedef typename typeVertex::type_face type_face; - typedef xr_vector vecFace; - -private: - const type_vertex* pTestVertex; - vecFace& new_adj_vec; - const float sm_cos; - -public: - itterate_adjacents_params_static(const type_vertex* _pTestVertex, vecFace& _new_adj_vec, float _sm_cos) - : pTestVertex(_pTestVertex), new_adj_vec(_new_adj_vec), sm_cos(_sm_cos) - { - } - -private: - IC static bool has_same_edge(const type_face* F1, const type_face* F2, u16& F1_edge_index, u16& F2_edge_index) - { - F1_edge_index = u16(-1); - F2_edge_index = u16(-1); - - for (int e = 0; e < 3; e++) - { - type_vertex *v1_a, *v1_b; - F1->EdgeVerts(e, &v1_a, &v1_b); - if (v1_a > v1_b) - std::swap(v1_a, v1_b); - - for (int r = 0; r < 3; ++r) - { - type_vertex *v2_a, *v2_b; - F2->EdgeVerts(r, &v2_a, &v2_b); - if (v2_a > v2_b) - std::swap(v2_a, v2_b); - - if ((v1_a == v2_a) && (v1_b == v2_b)) - { - F1_edge_index = e; - F2_edge_index = r; - return true; - } - } - } - return false; - } - - IC static bool do_connect_faces(const type_face& start, const type_face& test, u16 start_common_edge_idx, - u16 test_common_edge_idx, float sm_cos) - { - if (g_using_smooth_groups) - { - if (g_smooth_groups_by_faces) - return (start.sm_group != u32(-1) && start.sm_group == test.sm_group); - else - return do_connect_faces_by_faces_edge_flags( - start.sm_group, test.sm_group, start_common_edge_idx, test_common_edge_idx); - } - else - { - float cosa = start.N.dotproduct(test.N); - return (cosa > sm_cos); - } - } - -public: - IC const u32 current_adjacents_size() const - { - VERIFY(pTestVertex); - return u32(pTestVertex->m_adjacents.size()); - } - - IC type_face* current_adjacents_face(u32 i) const - { - VERIFY(pTestVertex); - return pTestVertex->m_adjacents[i]; - } - - IC bool is_processed(const type_face& f) const { return f.flags.bSplitted; } - IC bool add_adjacents(u32 start_face_idx, u32 test_face_idx) - { - const type_face* start_face = current_adjacents_face(start_face_idx); - type_face* test_face = current_adjacents_face(test_face_idx); - if (is_processed(*test_face)) - return false; - u16 StartFace_common_edge_index = u16(-1); - u16 TestFace_common_edge_index = u16(-1); - if (has_same_edge(start_face, test_face, StartFace_common_edge_index, TestFace_common_edge_index)) - { - if ((start_face == test_face) || do_connect_faces(*start_face, *test_face, StartFace_common_edge_index, - TestFace_common_edge_index, sm_cos)) - { - new_adj_vec.push_back(test_face); - test_face->flags.bSplitted = true; - return true; - } - } - return false; - } -}; - -#endif diff --git a/src/utils/xrLC_Light/lc_net_global_data.cpp b/src/utils/xrLC_Light/lc_net_global_data.cpp deleted file mode 100644 index ab5298cd5ea..00000000000 --- a/src/utils/xrLC_Light/lc_net_global_data.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "stdafx.h" -#include "lc_net_global_data.h" -#include "xrlc_globaldata.h" -#include "file_compress.h" -// void DataReadCreate( LPCSTR fn ); - -// void decompress( LPCSTR f_in_out ); -void DataReadCreate(LPCSTR fn) {} -namespace lc_net -{ -void net_global_data_impl::create_data_file(LPCSTR path) -{ - FPU::m64r(); - Memory.mem_compact(); - // std::random_shuffle (inlc_global_data()->g_deflectors().begin(),inlc_global_data()->g_deflectors().end()); - Logger.clMsg("create_global_data_write: start"); - IWriter* file = FS.w_open(path); - inlc_global_data()->write(*file); - FS.w_close(file); - compress(path); - Logger.clMsg("create_global_data_write: end"); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - decompress(path); - INetReaderFile r_global(path); - // create_global_data(); - - VERIFY(inlc_global_data()); - inlc_global_data()->read(r_global); - - FPU::m64r(); - Memory.mem_compact(); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); - return true; -} -} diff --git a/src/utils/xrLC_Light/lc_net_global_data.h b/src/utils/xrLC_Light/lc_net_global_data.h deleted file mode 100644 index 19bf4b52acb..00000000000 --- a/src/utils/xrLC_Light/lc_net_global_data.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _NET_LC_GLOBAL_DATA_H_ -#define _NET_LC_GLOBAL_DATA_H_ - -#include "net_global_data.h" - -namespace lc_net -{ -template <> -class net_global_data_impl -{ -public: - void init() { data_init(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(){}; - LPCSTR file_name() { return "gl_cl_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; - -template <> -struct global_add_global -{ -}; -} -#endif diff --git a/src/utils/xrLC_Light/lcnet_execution_tasks_add.h b/src/utils/xrLC_Light/lcnet_execution_tasks_add.h deleted file mode 100644 index 8c57c6cefc6..00000000000 --- a/src/utils/xrLC_Light/lcnet_execution_tasks_add.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _LCNET_EXECUTION_TASKS_ADD_H_ -#define _LCNET_EXECUTION_TASKS_ADD_H_ -namespace lc_net -{ -XRLC_LIGHT_API void net_lightmaps_add_task(u32 deflector_id); -XRLC_LIGHT_API void net_lightmaps_add_all_tasks(); -}; -#endif diff --git a/src/utils/xrLC_Light/lcnet_task_manager.cpp b/src/utils/xrLC_Light/lcnet_task_manager.cpp deleted file mode 100644 index 81d796ed85d..00000000000 --- a/src/utils/xrLC_Light/lcnet_task_manager.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "stdafx.h" -#include "lcnet_task_manager.h" -#include "net_execution.h" -#include "xrlc_globaldata.h" -#include "file_compress.h" -#include "serialize.h" -#include "net_execution_factory.h" -#include "net_global_data_cleanup.h" - -#include "net_exec_pool.h" - -namespace lc_net -{ -task_manager g_task_manager; - -task_manager& get_task_manager() { return g_task_manager; } -XRLC_LIGHT_API net_task_interface* g_net_task_interface = &g_task_manager; - -void __cdecl Finalize(IGenericStream* inStream) -{ - get_task_manager().receive_result(inStream); - // inStream->Clear(); -} - -task_manager::task_manager() - : _user(0), tasks_completed(0), current_pool(0), start(0), session_id(u32(-1)), _release(false) -{ - for (u8 i = 0; i < num_pools; ++i) - pools[i] = 0; - // create_global_data_write(""); -} - -bool task_manager::initialize_session(u32 _session_id) -{ - init_lock.Enter(); - bool ret = false; - if (session_id == u32(-1)) - { - session_id = _session_id; - ret = true; - } - else - ret = (session_id == _session_id); - init_lock.Leave(); - return ret; -} -void task_manager::receive_result(IGenericStream* inStream) -{ - u8 pool_id(u8(-1)); - // u32 task_id ( u32(-1) ), type_id ( u32(-1) ); - - read_task_pool(inStream, pool_id); - pools[pool_id]->receive_result(inStream); -} - -void task_manager::send_task(IGridUser& user, u32 id) {} -void task_manager::send_result(u8 pool_id, IGenericStream* outStream, net_execution& e) -{ - write_task_pool(outStream, pool_id); - pools[pool_id]->send_result(outStream, e); -} - -net_execution* task_manager::receive_task(u8& pool_id, IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - // u8 pool_id ( u8(-1) ); - read_task_pool(inStream, pool_id); - R_ASSERT(pool_id >= 0); - R_ASSERT(pool_id < num_pools); - - pool_lock.Enter(); - if (pools[pool_id] == 0) - pools[pool_id] = xr_new(this); - pool_lock.Leave(); - return pools[pool_id]->receive_task(agent, sessionId, inStream); -} - -void __cdecl data_cleanup_callback(const char* dataDesc, IGenericStream** stream); -void task_manager::startup() -{ - start_time.Start(); - tasks_completed = 0; - // create_user( ); - Threading::SpawnThread(task_manager::user_thread_proc, "release-user", 1024 * 1024, this); - for (;;) - { - Sleep(1); - bool user_inited = false; - init_lock.Enter(); - user_inited = !!_user; - init_lock.Leave(); - if (user_inited) - break; - } - - R_ASSERT(_user); - FPU::m64r(); - Memory.mem_compact(); -} -void task_manager::create_user() -{ - init_lock.Enter(); - R_ASSERT(!_user); - R_ASSERT(!_release); - _user = CreateGridUserObject(IGridUser::VERSION); - VERIFY(_user); - _user->BindGetDataCallback(data_cleanup_callback); - init_lock.Leave(); -} -void task_manager::user_init_thread() -{ - create_user(); - for (;;) - { - bool release = false; - Sleep(1000); - init_lock.Enter(); - release = _release; - init_lock.Leave(); - if (release) - break; - } - release_user(); -} -void task_manager::wait_all() -{ - for (;;) - { - Sleep(1000); - u32 num_running = 0; - for (u8 i = 0; i < num_pools; ++i) - if (pools[i] && pools[i]->is_running()) - ++num_running; - if (num_running == 0) - break; - } - // R_ASSERT(_user); - //_user->WaitForCompletion(); - // release(); -} -exec_pool* task_manager::run(LPCSTR name_pool) -{ - pool_lock.Enter(); - - if (!pools[current_pool]) - { - pool_lock.Leave(); - return 0; - } - pools[current_pool]->set_name(name_pool); - start = pools[current_pool]->end(); - u8 lrun = current_pool; - ++current_pool; - R_ASSERT(current_pool < num_pools); - - pool_lock.Leave(); - - R_ASSERT(_user); - pools[lrun]->run(*_user, lrun); - return pools[lrun]; -} -void task_manager::progress(u32 task) -{ - u32 l_completed = 0; - log_lock.Enter(); - ++tasks_completed; - l_completed = tasks_completed; - log_lock.Leave(); - Logger.Progress(float(l_completed) / float(start)); -} - -// void task_manager::release_user_thread_proc(void *_this ) -// { -// ((task_manager*)_this)->release_user(); -// } -void task_manager::user_thread_proc(void* _this) { ((task_manager*)_this)->user_init_thread(); } -void task_manager::release_user() -{ - init_lock.Enter(); - if (!_user) - { - init_lock.Leave(); - return; - } - R_ASSERT(_user); - //_user->CancelTasks(); - //_user->Release(); - _user = 0; - for (u8 i = 0; i < num_pools; ++i) - xr_delete(pools[i]); - init_lock.Leave(); -} - -void task_manager::release() -{ - for (u8 i = 0; i < num_pools; ++i) - R_ASSERT(!(pools[i]) || !(pools[i]->is_running())); - init_lock.Enter(); - _release = true; - init_lock.Leave(); - // Threading::SpawnThread(task_manager::release_user_thread_proc, "release-user", 1024 * 1024, this); -} - -void task_manager::add_task(net_execution* task) -{ - pool_lock.Enter(); - - if (!pools[current_pool]) - pools[current_pool] = xr_new(start, this); - - pools[current_pool]->add_task(task); - - pool_lock.Leave(); -} -}; diff --git a/src/utils/xrLC_Light/lcnet_task_manager.h b/src/utils/xrLC_Light/lcnet_task_manager.h deleted file mode 100644 index 3cebe6cdd43..00000000000 --- a/src/utils/xrLC_Light/lcnet_task_manager.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _LCNET_TASK_MANAGER_H_ -#define _LCNET_TASK_MANAGER_H_ -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" -#include "lightstab_interface.h" -#include "xrCore/Threading/Lock.hpp" - -namespace lc_net -{ -#include "hxgrid/Interface/IAgent.h" -// interface IGenericStream; - -class net_execution; -class exec_pool; - -class XRLC_LIGHT_API task_manager : public net_task_interface -{ - friend void Finalize(IGenericStream* inStream); - static const u8 num_pools = 255; - exec_pool* pools[num_pools]; - u8 current_pool; - - u32 start; - - CTimer start_time; - IGridUser* _user; - u32 session_id; - u32 tasks_completed; - bool _release; - Lock pool_lock; - Lock log_lock; - Lock init_lock; - -private: - void send_task(IGridUser& user, u32 id); - void receive_result(IGenericStream* inStream); - bool initialize_session(u32 _session_id); - - void send_result(u8 pool_id, IGenericStream* outStream, net_execution& e); - net_execution* receive_task(u8& pool_id, IAgent* agent, u32 sessionId, IGenericStream* inStream); - virtual bool run_task(IAgent* agent, u32 sessionId, IGenericStream* inStream, IGenericStream* outStream); - xr_vector::iterator find(u32 id); - -public: - task_manager(); - exec_pool* run(LPCSTR name_pool); - void add_task(net_execution* task); - void startup(); - void progress(u32 task); - -private: - void release_user(); - void create_user(); - void user_init_thread(); - // static void release_user_thread_proc( void *_this ); - static void user_thread_proc(void* _this); - -public: - void wait_all(); - void release(); -}; - -XRLC_LIGHT_API task_manager& get_task_manager(); -}; -#endif diff --git a/src/utils/xrLC_Light/lcnet_task_menager_run_task.cpp b/src/utils/xrLC_Light/lcnet_task_menager_run_task.cpp deleted file mode 100644 index 29b540ac77e..00000000000 --- a/src/utils/xrLC_Light/lcnet_task_menager_run_task.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "stdafx.h" - -#include "lcnet_task_manager.h" -#include "net_execution.h" -#include "net_exec_pool.h" -namespace lc_net -{ -bool task_manager::run_task(IAgent* agent, u32 sessionId, IGenericStream* inStream, IGenericStream* outStream) -{ - if (!initialize_session(sessionId)) - return false; - - u8 pool_id(u8(-1)); - - net_execution* e = receive_task(pool_id, agent, sessionId, inStream); - /////////////////////////////////////////////////////// - // inStream->Clear( ); - ////////////////////////////////////////////////////// - R_ASSERT(pools[pool_id]); - if (!e) - return false; - - if (!e->execute(agent, sessionId)) - { - pools[pool_id]->remove_task(e); - return false; - } - send_result(pool_id, outStream, *e); - pools[pool_id]->remove_task(e); - return true; -} -}; diff --git a/src/utils/xrLC_Light/light_execute.cpp b/src/utils/xrLC_Light/light_execute.cpp deleted file mode 100644 index c08b091ab1b..00000000000 --- a/src/utils/xrLC_Light/light_execute.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "stdafx.h" - -#include "light_execute.h" -#include "xrdeflector.h" - -void light_execute::run(CDeflector& D) { D.Light(&DB, &LightsSelected, H); } diff --git a/src/utils/xrLC_Light/light_execute.h b/src/utils/xrLC_Light/light_execute.h deleted file mode 100644 index 97745b665ce..00000000000 --- a/src/utils/xrLC_Light/light_execute.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "xrdeflectordefs.h" -#include "base_lighting.h" -#include "xrCDB/xrCDB.h" - -class light_execute -{ - HASH H; - CDB::COLLIDER DB; - base_lighting LightsSelected; - -public: - void run(CDeflector& D); -}; diff --git a/src/utils/xrLC_Light/light_point.h b/src/utils/xrLC_Light/light_point.h deleted file mode 100644 index e3b7eb9faf1..00000000000 --- a/src/utils/xrLC_Light/light_point.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -enum -{ - LP_DEFAULT = 0, - LP_UseFaceDisable = (1 << 0), - LP_dont_rgb = (1 << 1), - LP_dont_hemi = (1 << 2), - LP_dont_sun = (1 << 3), -}; - -// XRCL_LIGHT_API void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c &C, Fvector &P, Fvector &N, -// base_lighting& lights, u32 flags, Face* skip); diff --git a/src/utils/xrLC_Light/lightstab_interface.h b/src/utils/xrLC_Light/lightstab_interface.h deleted file mode 100644 index 0e81db5e8e6..00000000000 --- a/src/utils/xrLC_Light/lightstab_interface.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _LIGHTSTAB_INTERFACE_H_ -#define _LIGHTSTAB_INTERFACE_H_ -namespace lc_net -{ -class net_task_interface -{ -public: - virtual bool run_task(IAgent* agent, u32 sessionId, IGenericStream* inStream, IGenericStream* outStream) = 0; -}; -extern XRLC_LIGHT_API net_task_interface* g_net_task_interface; -} -#endif diff --git a/src/utils/xrLC_Light/lm_layer.cpp b/src/utils/xrLC_Light/lm_layer.cpp deleted file mode 100644 index 4589197b3c7..00000000000 --- a/src/utils/xrLC_Light/lm_layer.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "stdafx.h" - -#include "lm_layer.h" -#include "serialize.h" - -void lm_layer::Pack(xr_vector& dest) const -{ - dest.resize(width * height); - xr_vector::const_iterator I = surface.begin(); - xr_vector::const_iterator E = surface.end(); - xr_vector::iterator W = dest.begin(); - for (; I != E; ++I) - { - base_color_c C; - I->_get(C); - u8 _r = u8_clr(C.rgb.x); - u8 _g = u8_clr(C.rgb.y); - u8 _b = u8_clr(C.rgb.z); - u8 _d = u8_clr(C.sun); - *W++ = color_rgba(_r, _g, _b, _d); - } -} -void lm_layer::Pack_hemi(xr_vector& dest) const //. -{ - dest.resize(width * height); - xr_vector::const_iterator I = surface.begin(); - xr_vector::const_iterator E = surface.end(); - xr_vector::iterator W = dest.begin(); - for (; I != E; ++I) - { - base_color_c C; - I->_get(C); - u8 _d = u8_clr(C.sun); - u8 _h = u8_clr(C.hemi); - //*W++ = color_rgba(_h,_h,_h,_d); - *W++ = color_rgba(_d, _d, _d, _h); - } -} -void lm_layer::Pixel(u32 ID, u8& r, u8& g, u8& b, u8& s, u8& h) -{ - xr_vector::iterator I = surface.begin() + ID; - base_color_c c; - I->_get(c); - r = u8_clr(c.rgb.x); - g = u8_clr(c.rgb.y); - b = u8_clr(c.rgb.z); - s = u8_clr(c.sun); - h = u8_clr(c.hemi); -} - -/* - u32 width; - u32 height; - xr_vector surface; - xr_vector marker; - LMODE mode; -*/ - -void lm_layer::read(INetReader& r) -{ - width = r.r_u32(); - height = r.r_u32(); - r_pod_vector(r, surface); - r_pod_vector(r, marker); - // mode =(LMODE)r.r_u8(); -} -void lm_layer::write(IWriter& w) const -{ - w.w_u32(width); - w.w_u32(height); - w_pod_vector(w, surface); - w_pod_vector(w, marker); - // w.w_u8((u8)mode); -} - -bool lm_layer::similar(const lm_layer& layer, float eps /* =EPS*/) const -{ - // if( mode != layer.mode ) - // return false; - if (marker.size() != layer.marker.size()) - return false; - for (u32 i = 0; i < marker.size(); ++i) - { - if (marker[i] != layer.marker[i]) - { - return false; - } - } - if (surface.size() != layer.surface.size()) - return false; - for (u32 i = 0; i < surface.size(); ++i) - { - if (!surface[i].similar(layer.surface[i], EPS)) - { - Msg("sufface diff id: %d", i); - return false; - } - } - - return width == layer.width && height == layer.height; -} diff --git a/src/utils/xrLC_Light/lm_layer.h b/src/utils/xrLC_Light/lm_layer.h deleted file mode 100644 index 9c86fcf00bf..00000000000 --- a/src/utils/xrLC_Light/lm_layer.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "base_color.h" - -#ifndef BORDER -#define BORDER 1 -#endif - -class INetReader; -struct XRLC_LIGHT_API lm_layer -{ - /* - enum LMODE - { - LMODE_RGBS = 0, - LMODE_HS = 1, - }; - */ - u32 width; - u32 height; - xr_vector surface; - xr_vector marker; - -private: - // LMODE mode; -public: - void create(u32 w, u32 h) - { - width = w; - height = h; - u32 size = w * h; - surface.clear(); - surface.resize(size); - marker.clear(); - marker.assign(size, 0); - } - void destroy() - { - width = height = 0; - surface.clear(); - marker.clear(); - } - u32 Area() { return (width + 2 * BORDER) * (height + 2 * BORDER); } - void Pixel(u32 ID, u8& r, u8& g, u8& b, u8& s, u8& h); - void Pack(xr_vector& dest) const; - void Pack_hemi(xr_vector& dest) const; - void read(INetReader& r); - void write(IWriter& w) const; - bool similar(const lm_layer& D, float eps = EPS) const; - lm_layer() { width = height = 0; } -}; diff --git a/src/utils/xrLC_Light/lm_net_global_data.cpp b/src/utils/xrLC_Light/lm_net_global_data.cpp deleted file mode 100644 index 2176aaec7cf..00000000000 --- a/src/utils/xrLC_Light/lm_net_global_data.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "stdafx.h" - -#include "lm_net_global_data.h" - -#include "xrlc_globaldata.h" -#include "file_compress.h" -#include "xrdeflector.h" -namespace lc_net -{ -bool cmp_weight(CDeflector* d0, CDeflector* d1) -{ - R_ASSERT(d0); - R_ASSERT(d1); - return d0->weight() > d1->weight(); -} - -void net_global_data_impl::create_data_file(LPCSTR path) -{ - FPU::m64r(); - Memory.mem_compact(); - // std::random_shuffle (inlc_global_data()->g_deflectors().begin(),inlc_global_data()->g_deflectors().end()); - std::sort(inlc_global_data()->g_deflectors().begin(), inlc_global_data()->g_deflectors().end(), cmp_weight); - Logger.clMsg("create_lm_data_write: start"); - IWriter* file = FS.w_open(path); - inlc_global_data()->write_lm_data(*file); - FS.w_close(file); - compress(path); - Logger.clMsg("create_lm_data_write: end"); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - { - R_ASSERT(inlc_global_data()); - decompress(path); - INetReaderFile r_global(path); - inlc_global_data()->read_lm_data(r_global); - } - // xr_unlink( fn ); - // inlc_global_data()->create_read_faces(); - // inlc_global_data()->create_write_faces(); - FPU::m64r(); - Memory.mem_compact(); - return true; -} -} diff --git a/src/utils/xrLC_Light/lm_net_global_data.h b/src/utils/xrLC_Light/lm_net_global_data.h deleted file mode 100644 index 8fb421d1a70..00000000000 --- a/src/utils/xrLC_Light/lm_net_global_data.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _LM_NET_GLOBAL_DATA_H_ -#define _LM_NET_GLOBAL_DATA_H_ -#include "net_global_data.h" - -namespace lc_net -{ -template <> -class net_global_data_impl -{ -public: - void init() { data_init(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(){}; - LPCSTR file_name() { return "gl_lm_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; - -template <> -struct global_add_global -{ -}; -} -#endif diff --git a/src/utils/xrLC_Light/mu_light_net.cpp b/src/utils/xrLC_Light/mu_light_net.cpp deleted file mode 100644 index 6caf3b0f508..00000000000 --- a/src/utils/xrLC_Light/mu_light_net.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "stdafx.h" - -#include "xrlc_globaldata.h" - -#include "net_execution_factory.h" -#include "lcnet_task_manager.h" - -#include "net_execution_mu_ref.h" -#include "net_execution_mu_base.h" -#include "net_exec_pool.h" -#include "net_cl_data_prepare.h" - -// void get_intervals( u32 max_threads, u32 num_items, u32 &threads, u32 &stride, u32 &rest ); -void SetMuModelsLocalCalcLighteningCompleted(); -namespace lc_net -{ -exec_pool* ref_models_pool = 0; -exec_pool* base_models_pool = 0; -void RunRefModelsNet() -{ - SetRefModelLightDataInitialized(); - - const u32 num_tasks = inlc_global_data()->mu_refs().size(); - if (num_tasks == 0) - { - SetMuModelsLocalCalcLighteningCompleted(); - return; - } - for (u32 thID = 0; thID < num_tasks; thID++) - { - // Light references - // u32 stride = 0; - // u32 last = 0; - // u32 tasks = 0; - // const u32 max_tasks = 32; - // get_intervals( max_tasks, inlc_global_data()->mu_refs().size(), threads, stride, last ); - - tnet_execution_base* el = lc_net::execution_factory.create(); - el->implementation().construct(thID); - get_task_manager().add_task(el); - } - - ref_models_pool = get_task_manager().run("Net Models Lighting"); - SetMuModelsLocalCalcLighteningCompleted(); -} -void WaitRefModelsNet() -{ - if (!ref_models_pool) - return; - R_ASSERT(ref_models_pool); - ref_models_pool->wait(); -} - -void RunBaseModelsNet() -{ - WaitNetBaseCompileDataPrepare(); - - const u32 num = inlc_global_data()->mu_models().size(); - if (num == 0) - return; - for (u32 i = 0; i < num; i++) - { - tnet_execution_base* el = lc_net::execution_factory.create(); - el->implementation().construct(i); - get_task_manager().add_task(el); - } - - base_models_pool = get_task_manager().run("Net Base Models Lighting"); -} - -void WaitBaseModelsNet() -{ - if (!base_models_pool) - return; - R_ASSERT(base_models_pool); - base_models_pool->wait(); -} -} diff --git a/src/utils/xrLC_Light/mu_light_net.h b/src/utils/xrLC_Light/mu_light_net.h deleted file mode 100644 index 463f20d20c1..00000000000 --- a/src/utils/xrLC_Light/mu_light_net.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _MU_LIGHT_NET_H_ -#define _MU_LIGHT_NET_H_ -namespace lc_net -{ -void WaitRefModelsNet(); -void RunRefModelsNet(); -void RunBaseModelsNet(); -void WaitBaseModelsNet(); -} -#endif diff --git a/src/utils/xrLC_Light/mu_model_face.cpp b/src/utils/xrLC_Light/mu_model_face.cpp deleted file mode 100644 index 611947d1262..00000000000 --- a/src/utils/xrLC_Light/mu_model_face.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "stdafx.h" - -#include "mu_model_face.h" - -#include "serialize.h" - -#include "xrCore/xrPool.h" - -poolSS<_vertex, 8 * 1024>& mu_vertices_pool(); -poolSS<_face, 8 * 1024>& mu_faces_pool(); - -Tface::Tface() {} -Tvertex::Tvertex() {} -_vertex* _vertex::CreateCopy_NOADJ(v_vertices& vertises_storage) const -{ - // xrMU_Model::_vertex* V = create_vertex(Fvector().set(0,0,0)); - _vertex* V = mu_vertices_pool().create(); - vertises_storage.push_back(V); - V->P.set(P); - V->N.set(N); - V->C = C; - return V; -} - -template <> -Tface::~Tface() -{ -} -template <> -Tvertex::~Tvertex() -{ -} - -void _face::Failure() {} -// Fvector2 tc [3]; -// Fvector N; -// u32 sm_group; -void _face::read_vertices(INetReader& r) {} -void _face::write_vertices(IWriter& w) const {} -void _face::read(INetReader& r) -{ - base_Face::read(r); - r.r_fvector2(tc[0]); - r.r_fvector2(tc[1]); - r.r_fvector2(tc[2]); - r.r_fvector3(N); - sm_group = r.r_u32(); -} - -void _face::write(IWriter& w) const -{ - base_Face::write(w); - w.w_fvector2(tc[0]); - w.w_fvector2(tc[1]); - w.w_fvector2(tc[2]); - w.w_fvector3(N); - w.w_u32(sm_group); -} - -void _vertex::read(INetReader& r) { base_Vertex::read(r); } -void _vertex::write(IWriter& w) const { base_Vertex::write(w); } -////////////////////////////////////////////////////////////// -void _vertex::isolate_pool_clear_read(INetReader& r) { R_ASSERT(false); } -void _vertex::isolate_pool_clear_write(IWriter& w) const { R_ASSERT(false); } -/////////////////////////////////////////////////////////////// -void _vertex::read_adjacents(INetReader& r) {} -void _vertex::write_adjacents(IWriter& w) const {} -_vertex* _vertex::read_create() { return mu_vertices_pool().create(); } -_face* _face::read_create() { return mu_faces_pool().create(); } -poolSS<_vertex, 8 * 1024> mu_vertices; -poolSS<_face, 8 * 1024> mu_faces; - -poolSS<_vertex, 8 * 1024>& mu_vertices_pool() { return mu_vertices; } -poolSS<_face, 8 * 1024>& mu_faces_pool() { return mu_faces; } -void mu_mesh_clear() -{ - mu_vertices.clear(); - mu_faces.clear(); -} diff --git a/src/utils/xrLC_Light/mu_model_face.h b/src/utils/xrLC_Light/mu_model_face.h deleted file mode 100644 index 48804a74321..00000000000 --- a/src/utils/xrLC_Light/mu_model_face.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _MU_MODEL_FACE_ -#define _MU_MODEL_FACE_ - -class INetReader; - -#include "base_face.h" -#include "meshstructure.h" -#include "mu_model_face_defs.h" -//#ifndef MESHSTRUCTURE_EXSPORTS_IMPORTS -//#define MESHSTRUCTURE_EXSPORTS_IMPORTS -//#endif - -struct XRLC_LIGHT_API data_face : public base_Face -{ -public: - //_vertex* v [3]; - Fvector2 tc[3]; - Fvector N; - u32 sm_group; - -public: - virtual Fvector2* getTC0() { return tc; }; - // bool VContains ( _vertex* pV); // Does the face contains this vertex? - // void VReplace ( _vertex* what, _vertex* to); // Replace ONE vertex by ANOTHER - // void VReplace_NoRemove ( _vertex* what, _vertex* to); - // int VIndex ( _vertex* pV); - // void VSet ( int idx, _vertex* V); - // void VSet ( _vertex *V1, _vertex *V2, _vertex *V3); - // BOOL isDegenerated ( ); - // BOOL isEqual ( _face& F ); - // float EdgeLen ( int edge); - // void EdgeVerts ( int e, _vertex** A, _vertex** B); - // void CalcNormal ( ); - // void CalcNormal2 ( ); - // float CalcArea ( )const ; - // float CalcMaxEdge ( ); - // void CalcCenter ( Fvector &C ); - - // BOOL RenderEqualTo ( Face *F ); - - data_face() { sm_group = 0; }; - virtual ~data_face(){}; -}; - -struct XRLC_LIGHT_API data_vertex : public base_Vertex -{ - // v_faces adjacent; - typedef data_face DataFaceType; - -public: - // void prep_add (_face* F); - // void prep_remove (_face* F); - // void calc_normal_adjacent(); - - data_vertex(){}; - virtual ~data_vertex(){}; -}; - -#endif diff --git a/src/utils/xrLC_Light/mu_model_face_defs.h b/src/utils/xrLC_Light/mu_model_face_defs.h deleted file mode 100644 index 7704f56388d..00000000000 --- a/src/utils/xrLC_Light/mu_model_face_defs.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _MU_MODEL_FACE_DEFS_H_ -#define _MU_MODEL_FACE_DEFS_H_ -struct data_vertex; -struct data_face; -typedef Tvertex _vertex; -typedef Tface _face; - -typedef Tvertex _vertex; -typedef Tface _face; - -// XRLC_LIGHT_API poolSS<_vertex,8*1024> &mu_vertices_pool(); -// XRLC_LIGHT_API poolSS<_face,8*1024> &mu_faces_pool(); - -#endif diff --git a/src/utils/xrLC_Light/mu_model_light.cpp b/src/utils/xrLC_Light/mu_model_light.cpp deleted file mode 100644 index be269fd84f8..00000000000 --- a/src/utils/xrLC_Light/mu_model_light.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "stdafx.h" - -#include "mu_model_light.h" -#include "mu_model_light_threads.h" -#include "mu_light_net.h" -extern bool mu_light_net = false; -void run_mu_light(bool net) -{ - mu_light_net = net; - - run_mu_base(net); -} -void wait_mu_base() { wait_mu_base_thread(); } -void wait_mu_secondary() -{ - if (!mu_light_net) - wait_mu_secondary_thread(); - else - lc_net::WaitRefModelsNet(); -} diff --git a/src/utils/xrLC_Light/mu_model_light.h b/src/utils/xrLC_Light/mu_model_light.h deleted file mode 100644 index 05e9888e770..00000000000 --- a/src/utils/xrLC_Light/mu_model_light.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _MU_MODEL_LIGHT_H_ -#define _MU_MODEL_LIGHT_H_ - -extern XRLC_LIGHT_API void run_mu_light(bool net); -extern XRLC_LIGHT_API void wait_mu_base(); -extern XRLC_LIGHT_API void wait_mu_secondary(); -extern XRLC_LIGHT_API void wait_mu_secondary_thread(); -extern XRLC_LIGHT_API void WaitMuModelsLocalCalcLightening(); -extern bool mu_light_net; -#endif diff --git a/src/utils/xrLC_Light/mu_model_light_threads.cpp b/src/utils/xrLC_Light/mu_model_light_threads.cpp deleted file mode 100644 index a242d7d3f7c..00000000000 --- a/src/utils/xrLC_Light/mu_model_light_threads.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "stdafx.h" -#include "mu_model_light_threads.h" - -#include "xrface.h" -#include "xrMU_Model.h" -#include "xrMU_Model_Reference.h" - -#include "xrlc_globaldata.h" - -#include "mu_model_light.h" -#include "mu_light_net.h" - -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrCore/Threading/Lock.hpp" - -CThreadManager mu_base(ProxyStatus, ProxyProgress); -CThreadManager mu_secondary(ProxyStatus, ProxyProgress); -#define MU_THREADS 4 -// mu-light -bool mu_models_local_calc_lightening = false; -Lock mu_models_local_calc_lightening_wait_lock; -void WaitMuModelsLocalCalcLightening() -{ - for (;;) - { - bool complited = false; - Sleep(1000); - mu_models_local_calc_lightening_wait_lock.Enter(); - complited = mu_models_local_calc_lightening; - mu_models_local_calc_lightening_wait_lock.Leave(); - if (complited) - break; - } -} -void SetMuModelsLocalCalcLighteningCompleted() -{ - mu_models_local_calc_lightening_wait_lock.Enter(); - mu_models_local_calc_lightening = true; - mu_models_local_calc_lightening_wait_lock.Leave(); -} -class CMULight : public CThread -{ - u32 low; - u32 high; - -public: - CMULight(u32 ID, u32 _low, u32 _high) : CThread(ID, ProxyMsg) - { - thMessages = FALSE; - low = _low; - high = _high; - } - - virtual void Execute() - { - // Priority - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); - Sleep(0); - - // Light references - for (u32 m = low; m < high; m++) - { - inlc_global_data()->mu_refs()[m]->calc_lighting(); - thProgress = (float(m - low) / float(high - low)); - } - } -}; - -// void LC_WaitRefModelsNet(); -class CMUThread : public CThread -{ -public: - CMUThread(u32 ID) : CThread(ID, ProxyMsg) { thMessages = FALSE; } - virtual void Execute() - { - // Priority - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); - Sleep(0); - - // Light models - - if (mu_light_net) - { - lc_net::RunBaseModelsNet(); - lc_net::RunRefModelsNet(); - return; - // lc_net::WaitRefModelsNet(); - } - - for (u32 m = 0; m < inlc_global_data()->mu_models().size(); m++) - { - inlc_global_data()->mu_models()[m]->calc_materials(); - inlc_global_data()->mu_models()[m]->calc_lighting(); - } - - SetMuModelsLocalCalcLighteningCompleted(); - - // Light references - u32 stride = inlc_global_data()->mu_refs().size() / MU_THREADS; - u32 last = inlc_global_data()->mu_refs().size() - stride * (MU_THREADS - 1); - u32 threads = MU_THREADS; - get_intervals(MU_THREADS, inlc_global_data()->mu_refs().size(), threads, stride, last); - - for (u32 thID = 0; thID < threads; thID++) - mu_secondary.start(xr_new(thID, thID * stride, thID * stride + stride)); - if (last > 0) - mu_secondary.start(xr_new(threads, threads * stride, threads * stride + last)); - } -}; - -void run_mu_base(bool net) { mu_base.start(xr_new(0)); } -void wait_mu_base_thread() { mu_base.wait(500); } -void wait_mu_secondary_thread() { mu_secondary.wait(500); } diff --git a/src/utils/xrLC_Light/mu_model_light_threads.h b/src/utils/xrLC_Light/mu_model_light_threads.h deleted file mode 100644 index 156d915ccf2..00000000000 --- a/src/utils/xrLC_Light/mu_model_light_threads.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _MU_MODEL_LIGHT_THREADS_H_ -#define _MU_MODEL_LIGHT_THREADS_H_ - -void run_mu_base(bool net); -void wait_mu_base_thread(); - -#endif diff --git a/src/utils/xrLC_Light/net_all_executions.h b/src/utils/xrLC_Light/net_all_executions.h deleted file mode 100644 index c5fdf254107..00000000000 --- a/src/utils/xrLC_Light/net_all_executions.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _NET_ALL_EXECUTIONS_H_ -#define _NET_ALL_EXECUTIONS_H_ -#include "net_execution_lightmaps.h" -#include "net_execution_implicit_light.h" -#include "net_execution_mu_ref.h" -#include "net_execution_vertex_light.h" -#include "net_execution_detail_light.h" -#include "net_execution_mu_base.h" -#endif diff --git a/src/utils/xrLC_Light/net_all_globals.h b/src/utils/xrLC_Light/net_all_globals.h deleted file mode 100644 index e4950d9a851..00000000000 --- a/src/utils/xrLC_Light/net_all_globals.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _NET_ALL_GLOBALS_H_ -#define _NET_ALL_GLOBALS_H_ -#include "lc_net_global_data.h" -#include "implicit_net_global_data.h" -#include "lm_net_global_data.h" -#include "ref_model_net_global_data.h" -#include "detail_net_global_data.h" -#include "gl_base_cl_data.h" -#endif diff --git a/src/utils/xrLC_Light/net_cl_data_prepare.cpp b/src/utils/xrLC_Light/net_cl_data_prepare.cpp deleted file mode 100644 index 1bc5e05969d..00000000000 --- a/src/utils/xrLC_Light/net_cl_data_prepare.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "stdafx.h" -#include "net_cl_data_prepare.h" - -#include "lc_net_global_data.h" -#include "gl_base_cl_data.h" -#include "lm_net_global_data.h" -#include "ref_model_net_global_data.h" -#include "lcnet_task_manager.h" -#include "xrlc_globaldata.h" -#include "mu_light_net.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrCore/Threading/Lock.hpp" - -bool global_compile_data_initialized = false; -bool base_global_compile_data_initialized = false; -CThreadManager cl_data_prepare(ProxyStatus, ProxyProgress); -Lock wait_lock; -void SetBaseGlobalCompileDataInitialized(); -class NetCompileDetaPrepare : public CThread -{ -public: - NetCompileDetaPrepare() : CThread(0, ProxyMsg) { thMessages = FALSE; } -private: - virtual void Execute() - { - SetBaseGlobalCompileDataInitialized(); - SetGlobalCompileDataInitialized(); - } -}; - -void RunNetCompileDataPrepare() -{ - cl_data_prepare.start(xr_new()); - SartupNetTaskManager(); //. -} - -void WaitNetCompileDataPrepare() -{ - for (;;) - { - Sleep(1000); - bool inited = false; - wait_lock.Enter(); - // cl_data_prepare.wait(); - inited = global_compile_data_initialized; - wait_lock.Leave(); - if (inited) - break; - } -} -void WaitNetBaseCompileDataPrepare() // to do refactoring -{ - for (;;) - { - Sleep(1000); - bool inited = false; - wait_lock.Enter(); - // cl_data_prepare.wait(); - inited = base_global_compile_data_initialized; - wait_lock.Leave(); - if (inited) - break; - } -} - -void SetBaseGlobalCompileDataInitialized() -{ - lc_net::globals().get().init(); - wait_lock.Enter(); - base_global_compile_data_initialized = true; - wait_lock.Leave(); -} - -void SetGlobalCompileDataInitialized() -{ - lc_net::globals().get().init(); - Logger.clLog("mem usage before collision model destroy: %u", Memory.mem_usage()); - inlc_global_data()->destroy_rcmodel(); - Memory.mem_compact(); - Logger.clLog("mem usage after collision model destroy: %u", Memory.mem_usage()); - // inlc_global_data()->clear_build_textures_surface(); - wait_lock.Enter(); - // cl_data_prepare.wait(); - global_compile_data_initialized = true; - wait_lock.Leave(); -} - -void SartupNetTaskManager() { lc_net::get_task_manager().startup(); } -extern u32 vertises_has_lighting; -u32 CalcAllTranslucency(); - -void SetGlobalLightmapsDataInitialized() -{ - WaitNetCompileDataPrepare(); - // - vertises_has_lighting = CalcAllTranslucency(); - // - lc_net::globals().get().init(); -} - -void SetRefModelLightDataInitialized() -{ - WaitNetCompileDataPrepare(); - lc_net::WaitBaseModelsNet(); - lc_net::globals().get().init(); -} diff --git a/src/utils/xrLC_Light/net_cl_data_prepare.h b/src/utils/xrLC_Light/net_cl_data_prepare.h deleted file mode 100644 index 2bee5a2c200..00000000000 --- a/src/utils/xrLC_Light/net_cl_data_prepare.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _NET_CL_DATA_PREPARE_H_ -#define _NET_CL_DATA_PREPARE_H_ -XRLC_LIGHT_API void SetGlobalCompileDataInitialized(); -XRLC_LIGHT_API void SetGlobalLightmapsDataInitialized(); -XRLC_LIGHT_API void SartupNetTaskManager(); -XRLC_LIGHT_API void RunNetCompileDataPrepare(); -XRLC_LIGHT_API void WaitNetCompileDataPrepare(); -void SetRefModelLightDataInitialized(); -void WaitNetBaseCompileDataPrepare(); -#endif diff --git a/src/utils/xrLC_Light/net_exec_pool.cpp b/src/utils/xrLC_Light/net_exec_pool.cpp deleted file mode 100644 index df918bf9fb4..00000000000 --- a/src/utils/xrLC_Light/net_exec_pool.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include "stdafx.h" -#include "net_exec_pool.h" - -#include "net_execution.h" -#include "xrlc_globaldata.h" -#include "file_compress.h" -#include "serialize.h" -#include "net_execution_factory.h" -#include "net_global_data_cleanup.h" -#include "lcnet_task_manager.h" -#define LOG_ALL_NET_TASKS - -LPCSTR make_time(string64& buf, float fsec) -{ - // char buf[64]; - - int sec = iFloor(fsec); - if (sec < 0) - sec = 0; - xr_sprintf(buf, "%2.0d:%2.0d:%2.0d", sec / 3600, (sec % 3600) / 60, sec % 60); - size_t len = xr_strlen(buf); - for (size_t i = 0; i < len; i++) - if (buf[i] == ' ') - buf[i] = '0'; - return buf; -} - -namespace lc_net -{ -void exec_pool::add_task(net_execution* e) -{ - pool.push_back(e); - ++_end; -} - -bool exec_pool::has(u32 id) -{ - R_ASSERT(id != u32(-1)); - R_ASSERT(_start != u32(-1)); - R_ASSERT(_end != u32(-1)); - R_ASSERT(_start < _end); - - return id >= _start && id < _end; -} - -void exec_pool::receive_result(IGenericStream* inStream) -{ - u32 id = u32(-1), type = u32(-1); // r.r_u32(); - read_task_caption(inStream, id, type); - - // xr_vector::iterator it =std::find( pool.begin(), pool.end(), id ); - const u32 size = pool.size(); - - R_ASSERT(_start != u32(-1)); - R_ASSERT(_end != u32(-1)); - - R_ASSERT(_end > 0); - R_ASSERT(_start < _end); - - R_ASSERT(id >= _start); - R_ASSERT(id < _end); - - R_ASSERT(_running); - R_ASSERT(size > 0); - R_ASSERT(id >= 0); - - u32 pos = id - _start; - - R_ASSERT(pos >= 0); - R_ASSERT(pos < size); - - send_receive_lock.Enter(); - - net_execution* e = pool[pos]; - R_ASSERT(e->type() == type); - if (e == 0) - { - send_receive_lock.Leave(); - return; - } - pool[pos] = 0; - ++tasks_completed; - u32 l_completed = tasks_completed; - send_receive_lock.Leave(); - e->receive_result(inStream); - // xr_delete( e ); - execution_factory.destroy(e); - _task_manager.progress(id); -#ifdef LOG_ALL_NET_TASKS - Logger.clMsg("%s received task : %d", _name, id); - - // Progress( float( tasks_completed )/float( size ) ); - Logger.clMsg("num task complited : %d , num task left %d (task num %d)", l_completed, size - l_completed, size); -#endif - R_ASSERT(l_completed <= size); - if (l_completed == size) - { - string64 buf; - Logger.clLog(" %s, calculation complited", _name); - // clMsg ("%f %s calculation seconds",start_time.GetElapsed_sec(), _name ); - - Logger.clLog("%s %s calculation time", make_time(buf, start_time.GetElapsed_sec()), _name); - // Status ("%s %s calculation time",make_time( buf,start_time.GetElapsed_sec() ), _name ); - - // xr_sprintf( buf, "%s %s calculation time",make_time( buf,start_time.GetElapsed_sec() ), _name ); - // Phase( buf ); - // } - - // if( l_completed == size ) - // { - execution_factory.free_pool(type); - run_lock.Enter(); - _running = false; - run_lock.Leave(); - } -} - -void exec_pool::wait() -{ - do - { - Sleep(1000); - } while (is_running()); -} -bool exec_pool::is_running() -{ - bool running = true; - run_lock.Enter(); - running = _running; - run_lock.Leave(); - return running; -} -exec_pool& exec_pool::run(IGridUser& user, u8 pool_id) -{ - start_time.Start(); - R_ASSERT(!_running); - _running = true; - u32 size = pool.size(); - - // IGenericStream* stream = CreateGenericStream(); - for (u32 dit = _start; dit < _end; dit++) - send_task(user, 0, pool_id, dit); - - return *this; -} -void __cdecl Finalize(IGenericStream* outStream); -Lock run_task_lock; -void exec_pool::send_task(IGridUser& user, IGenericStream* Stream, u8 pool_id, u32 id) -{ - R_ASSERT(_running); - R_ASSERT(has(id)); - IGenericStream* outStream = CreateGenericStream(); - ////////////////////////////////////////////////////// - write_task_pool(outStream, pool_id); //////////////////// - ////////////////////////////////////////////////////// - cleanup().on_net_send(outStream); - - u32 pos = id - _start; - VERIFY(pos < pool.size()); - net_execution* e = pool[pos]; - VERIFY(e != 0); - write_task_caption(outStream, id, e->type()); -#ifdef LOG_ALL_NET_TASKS - Logger.clMsg(" %s, send task : %d", _name, id); -// -#endif - - e->send_task(user, outStream, id); - - DWORD t_id = id; - string_path data; - string_path files; - strconcat(sizeof(data), data, libraries, e->data_files(files)); - run_task_lock.Enter(); - bool ok = false; -run_task:; - - __try - { - user.RunTask(data, "RunTask", outStream, Finalize, &t_id, true); - - ok = true; - } - - __except (EXCEPTION_EXECUTE_HANDLER) - { - if (!ok) - { - Msg("accept run task"); - goto run_task; - } - } - - run_task_lock.Leave(); - return; -} - -net_execution* exec_pool::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - __try - { - cleanup().on_net_receive(agent, sessionId, inStream); - u32 id = u32(-1), type = u32(-1); - read_task_caption(inStream, id, type); - - send_receive_lock.Enter(); - - for (size_t i = 0; i < pool.size(); i++) - { - net_execution* it = pool[i]; - R_ASSERT(it); - if (it->id() == id) - { - send_receive_lock.Leave(); - return 0; - } - } - - net_execution* e = execution_factory.create(type, id); - pool.push_back(e); - send_receive_lock.Leave(); - e->receive_task(agent, sessionId, inStream); - - return e; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - Msg("accept!"); - return 0; - } -} - -void exec_pool::remove_task(net_execution* e) -{ - send_receive_lock.Enter(); - xr_vector::iterator i = std::find(pool.begin(), pool.end(), e); - R_ASSERT(i != pool.end()); - net_execution* pe = *i; - R_ASSERT(pe == e); - R_ASSERT(pe->id() == e->id()); - pool.erase(i); - send_receive_lock.Leave(); - xr_delete(e); -} - -void exec_pool::send_result(IGenericStream* outStream, net_execution& e) -{ - write_task_caption(outStream, e.id(), e.type()); - e.send_result(outStream); -} -} diff --git a/src/utils/xrLC_Light/net_exec_pool.h b/src/utils/xrLC_Light/net_exec_pool.h deleted file mode 100644 index 51973114a2a..00000000000 --- a/src/utils/xrLC_Light/net_exec_pool.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _EXEC_POOL_H_ -#define _EXEC_POOL_H_ -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" -#include "xrCore/Threading/Lock.hpp" - -namespace lc_net -{ -class net_execution; -class task_manager; -class exec_pool -{ - string32 _name; - u32 _start; - u32 _end; - u32 tasks_completed; - Lock send_receive_lock; - Lock run_lock; - xr_vector pool; - CTimer start_time; - task_manager& _task_manager; - // IGridUser *_user; - bool _running; - -public: - ~exec_pool() { R_ASSERT(!_running); } - exec_pool(task_manager* tm) - : _task_manager(*tm), _running(false), tasks_completed(0), _start(u32(-1)), _end(u32(-1)) - { - R_ASSERT(tm); - xr_strcpy(_name, "net noname task"); - }; - exec_pool(u32 start, task_manager* tm) - : _task_manager(*tm), _running(false), tasks_completed(0), _start(start), _end(start) - { - R_ASSERT(tm); - }; - bool has(u32 id); - u32 end() { return _end; } - void add_task(net_execution* task); - void wait(); - void set_name(LPCSTR name) { xr_strcpy(_name, name); } - bool is_running(); - exec_pool& run(IGridUser& user, u8 pool_id); - - void send_task(IGridUser& user, IGenericStream* outStream, u8 pool_id, u32 id); - void receive_result(IGenericStream* inStream); - void remove_task(net_execution* e); - void send_result(IGenericStream* outStream, net_execution& e); - net_execution* receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - -private: -}; -} -#endif diff --git a/src/utils/xrLC_Light/net_execution.cpp b/src/utils/xrLC_Light/net_execution.cpp deleted file mode 100644 index 676bbd698ab..00000000000 --- a/src/utils/xrLC_Light/net_execution.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "stdafx.h" -#include "net_execution.h" - -namespace lc_net -{ -/* - bool net_execution::run( IAgent* agent, DWORD sessionId, IGenericStream* inStream, IGenericStream* outStream ) - { - if( receive_task( agent, sessionId, inStream ) && - execute() ) - { - send_result( outStream ); - return true; - } - return false; - } -*/ -void net_execution::send_task(IGridUser& user, IGenericStream* outStream, u32 id) { _id = id; } -} diff --git a/src/utils/xrLC_Light/net_execution.h b/src/utils/xrLC_Light/net_execution.h deleted file mode 100644 index 49f58f7b0d5..00000000000 --- a/src/utils/xrLC_Light/net_execution.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _NET_EXECUTION_H_ -#define _NET_EXECUTION_H_ -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" - -#include "net_global_data.h" -#include "net_task_callback.h" -namespace lc_net -{ -class net_execution -{ - u32 _id; - -public: - u32 id() const { return _id; } - virtual u32 type() = 0; - - virtual void send_task(IGridUser& user, IGenericStream* outStream, u32 id) = 0; - virtual void receive_result(IGenericStream* outStream) = 0; - virtual bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) = 0; - virtual void send_result(IGenericStream* outStream) = 0; - virtual bool execute(IAgent* agent, u32 sessionId) = 0; - virtual LPCSTR data_files(string_path& buf) = 0; - - net_execution(u32 id) : _id(id) {} - virtual ~net_execution(){}; - -private: -}; - -enum execution_types -{ - et_lightmaps, - et_implicit_light, - et_mu_ref_light, - et_mu_base_light, - et_vertex_light, - et_detail_light, - et_last -}; - -template -class tnet_execution_base : public net_execution -{ -public: - static const execution_types class_type = etype; - class net_execution_impl; - -public: - tnet_execution_base(u32 id) : net_execution(id) {} - virtual net_execution_impl& implementation() = 0; - -private: - virtual u32 type() { return (u32)class_type; } -}; - -template -struct add_global; -}; -#endif diff --git a/src/utils/xrLC_Light/net_execution_detail_light.cpp b/src/utils/xrLC_Light/net_execution_detail_light.cpp deleted file mode 100644 index 2f6c79487ef..00000000000 --- a/src/utils/xrLC_Light/net_execution_detail_light.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "net_execution_detail_light.h" -#include "serialize.h" -#include "global_calculation_data.h" -#include "detail_slot_calculate.h" - -namespace lc_net -{ -static constexpr size_t detail_light_result_buff_size = 512 * 1024; -static constexpr size_t detail_light_task_buff_size = 8; - -void net_execution_detail_light::receive_result(IGenericStream* outStream) -{ - u8 buff[detail_light_result_buff_size]; - INetBlockReader r(outStream, buff, sizeof(buff)); - // INetReaderGenStream r(outStream); - u32 _start = r.r_u32(); - u32 _end = r.r_u32(); - VERIFY(_start == start); - VERIFY(_end == end); - - for (u32 i = start; i < end; ++i) - { - int x, z; - gl_data.slots_data.header().slot_x_z(i, x, z); - - if (gl_data.slots_data.calculate_ignore(x, z)) - continue; - - DetailSlot& DS = gl_data.slots_data.get_slot(x, z); - r_pod(r, DS); - gl_data.slots_data.set_slot_calculated(x, z); - } -} - -void net_execution_detail_light::send_result(IGenericStream* outStream) -{ - u8 buff[detail_light_result_buff_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, 1024*1024 ); - VERIFY(start != u32(-1)); - VERIFY(end != u32(-1)); - w.w_u32(start); - w.w_u32(end); - for (u32 i = start; i < end; ++i) - { - int x, z; - gl_data.slots_data.header().slot_x_z(i, x, z); - if (gl_data.slots_data.calculate_ignore(x, z)) - continue; - DetailSlot& DS = gl_data.slots_data.get_slot(x, z); - w_pod(w, DS); - } -} -void net_execution_detail_light::send_task(IGenericStream* outStream) -{ - { - R_ASSERT(start != u32(-1)); - R_ASSERT(end != u32(-1)); - u8 buff[detail_light_task_buff_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, 100 ); - w.w_u32(start); - w.w_u32(end); - } -} -bool net_execution_detail_light::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - u8 buff[detail_light_task_buff_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r( inStream ); - start = r.r_u32(); - end = r.r_u32(); - R_ASSERT(start != u32(-1)); - R_ASSERT(end != u32(-1)); - - return true; -} - -bool net_execution_detail_light::execute(net_task_callback& net_callback) -{ - DWORDVec box_result; - //////////////////////////////////////////////////////// - CDB::COLLIDER DB; - base_lighting Selected; - - for (u32 i = start; i < end; ++i) - { - int x, z; - gl_data.slots_data.header().slot_x_z(i, x, z); - if (gl_data.slots_data.calculate_ignore(x, z)) - continue; - DetailSlot& DS = gl_data.slots_data.get_slot(x, z); - detail_slot_calculate(x, z, DS, box_result, DB, CDB::OPT_FULL_TEST, CDB::OPT_CULL, Selected); - if (!net_callback.test_connection()) - break; - } - - return !net_callback.break_all(); -} - -void net_execution_detail_light::construct(u32 _start, u32 _end) -{ - start = _start; - end = _end; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_detail_light.h b/src/utils/xrLC_Light/net_execution_detail_light.h deleted file mode 100644 index 55c51ec459f..00000000000 --- a/src/utils/xrLC_Light/net_execution_detail_light.h +++ /dev/null @@ -1,39 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef NET_EXECUTION_DETAIL_LIGHT_H_INCLUDED -#define NET_EXECUTION_DETAIL_LIGHT_H_INCLUDED - -#include "net_execution.h" - -class net_task_callback; - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl net_execution_detail_light; -template <> -class tnet_execution_base::net_execution_impl -{ - u32 start; - u32 end; - -public: - net_execution_impl() : start(u32(-1)), end(-1) {} - void construct(u32 _x, u32 _z); // { start = _start;end = _end; } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* outStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -}; -template <> -struct add_global -{ -}; -// execution_lightmaps -}; - -#endif // #ifndef NET_EXECUTION_DETAIL_LIGHT_H_INCLUDED diff --git a/src/utils/xrLC_Light/net_execution_factory.cpp b/src/utils/xrLC_Light/net_execution_factory.cpp deleted file mode 100644 index 2b1f789f750..00000000000 --- a/src/utils/xrLC_Light/net_execution_factory.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "stdafx.h" - -#include "net_execution_factory.h" - -namespace lc_net -{ -lc_net::factory execution_factory; - -factory::factory() { register_all(); } -factory::~factory() { clear(); } -// struct sfind_type -//{ -// u32 _id; -// sfind_type( u32 id ): _id( id ){} -// bool operator () ( const factory::type_reg &tr ) -// { -// return tr->type() == _id; -// } -//}; - -// xr_vector< factory::type_reg >::iterator factory::find_type( u32 id ) -//{ -// return std::find_if( vec_types.begin(), vec_types.end(), sfind_type( id ) ); -//} - -void lc_net::factory::register_type(base_execution_type_creator* creator) -{ - // R_ASSERT2( vec_types.end() == find_type( creator->type() ),"type already regestred!" ); - VERIFY(creator); - R_ASSERT(vec_types.size() == et_last); - R_ASSERT(vec_types[creator->type()] == 0); - vec_types[creator->type()] = creator; -} - -net_execution* factory::create(u32 type_id, u32 _net_id) -{ - // xr_vector< factory::type_reg >::iterator i= find_type(type_id); - // R_ASSERT2( vec_types.end() != i,"type has not regestred!" ); - // VERIFY((*i)); - R_ASSERT(type_id < et_last); - return vec_types[type_id]->create(_net_id); -} -net_execution* factory::create_in_pool(u32 type_id) -{ - // return create( type_id, u32(-1) ); - R_ASSERT(type_id < et_last); - return vec_types[type_id]->pool_create(); -} - -void factory::destroy(net_execution*& e) { destroy_in_pool(e); } -void factory::destroy_in_pool(net_execution*& e) -{ - if (!e) - return; - type_reg creator = vec_types[e->type()]; - creator->pool_destroy(e); -} - -void factory::clear() -{ - xr_vector::iterator i = vec_types.begin(), e = vec_types.end(); - for (; e != i; ++i) - xr_delete((*i)); - vec_types.clear(); -} -}; diff --git a/src/utils/xrLC_Light/net_execution_factory.h b/src/utils/xrLC_Light/net_execution_factory.h deleted file mode 100644 index c64ddb0c8f1..00000000000 --- a/src/utils/xrLC_Light/net_execution_factory.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _NET_EXECUTION_FACTORY_ -#define _NET_EXECUTION_FACTORY_ - -#include "net_execution.h" - -namespace lc_net -{ -class base_execution_type_creator -{ -public: - virtual net_execution* create(u32 _net_id) = 0; - virtual net_execution* pool_create() = 0; - virtual void pool_destroy(net_execution*& e) = 0; - virtual u32 type() = 0; - virtual void set_pool_size(u32 size) = 0; - virtual void free_pool() = 0; -}; - -class factory -{ -public: - // typedef std::pair type_reg; - typedef base_execution_type_creator* type_reg; - -private: - xr_vector vec_types; - -private: - net_execution* create_in_pool(u32 type_id); - void destroy_in_pool(net_execution*& e); - -public: - net_execution* create(u32 type_id, u32 _net_id); - - template - tnet_execution_base* create() - { - // return (tnet_execution_base< etype >*) create( etype, u32(-1) ); - return (tnet_execution_base*)create_in_pool(etype); - } - virtual void destroy(net_execution*& e); - - void free_pool(u32 type_id) - { - R_ASSERT(type_id < et_last); - vec_types[type_id]->free_pool(); - } - - factory(); - ~factory(); - -public: - void register_type(base_execution_type_creator* creator); - -private: - // xr_vector< type_reg >::iterator find_type ( u32 id ); - void register_all(); - void clear(); -}; - -extern factory execution_factory; -}; -#endif diff --git a/src/utils/xrLC_Light/net_execution_factory_register.cpp b/src/utils/xrLC_Light/net_execution_factory_register.cpp deleted file mode 100644 index 594a3d6c412..00000000000 --- a/src/utils/xrLC_Light/net_execution_factory_register.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "stdafx.h" -#include "net_execution_factory.h" - -#include "net_all_executions.h" - -#include "net_execution_globals.h" -#include "xrCore/xrPool.h" -namespace lc_net -{ -template -class tnet_execution : public tnet_execution_base -{ -private: - typedef tnet_execution self_type; - net_execution_impl execution_impl; - -public: - tnet_execution(u32 id) : tnet_execution_base(id) { on_construct(); } - explicit tnet_execution() : tnet_execution_base(u32(-1)) { on_construct(); } -private: - void on_construct() - { - const xr_vector& v = exe_gl_reg().get_globals(etype); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - globals().get(v[i]).add_ref(); - } - virtual net_execution_impl& implementation() { return execution_impl; }; - virtual void send_task(IGridUser& user, IGenericStream* outStream, u32 id) - { - const xr_vector& v = exe_gl_reg().get_globals(etype); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - globals().get(v[i]).on_task_send(outStream); - tnet_execution_base::send_task(user, outStream, id); - execution_impl.send_task(outStream); - }; - - virtual void receive_result(IGenericStream* outStream) { execution_impl.receive_result(outStream); }; - virtual bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) - { - const xr_vector& v = exe_gl_reg().get_globals(etype); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - if (!globals().get(v[i]).on_task_receive(agent, sessionId, inStream)) - return false; - return execution_impl.receive_task(agent, sessionId, inStream); - }; - virtual void send_result(IGenericStream* outStream) { execution_impl.send_result(outStream); }; - virtual bool execute(IAgent* agent, u32 sessionId) - { - net_task_callback callback(agent, sessionId); - return execution_impl.execute(callback) && !callback.break_all(); - }; - virtual LPCSTR data_files(string_path& buf) - { - const xr_vector& v = exe_gl_reg().get_globals(etype); - // xr_vector::const_iterator i = v.begin(), e = v.end(); - u32 size = v.size(); - buf[0] = 0; - for (u32 i = 0; i < size; ++i) - { - string_path lbuf; - strconcat(sizeof(string_path), buf, buf, globals().get(v[i]).files(lbuf)); - } - return buf; - } - -public: - virtual ~tnet_execution() - { - const xr_vector& v = exe_gl_reg().get_globals(etype); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - globals().get(v[i]).free_ref(); - } -}; - -template -class execution_type_creator : public base_execution_type_creator -{ - poolSS pool; - - virtual void set_pool_size(u32 size){}; - virtual void free_pool() { pool.clear(); } - virtual net_execution* create(u32 _net_id) { return xr_new(_net_id); } - virtual net_execution* pool_create() - { - return xr_new(u32(-1)); - // return pool.create() ; - return pool.create(); // spool::pool.create() ; - } - virtual void pool_destroy(net_execution*& e) - { - net_execution* _e = e; - - execution* ex = static_cast(_e); - VERIFY(ex == dynamic_cast(_e)); - pool.destroy(ex); - e = 0; - } - virtual u32 type() { return execution::class_type; } -}; - -template -static void register_type() -{ - execution_factory.register_type(xr_new>()); -} - -template -struct it -{ - static const execution_types et = (execution_types)(i); - static const execution_types next_et = (execution_types)(i + 1); - typedef it next; - next ni; - it() { register_type>(); } -}; -template <> -struct it -{ -}; - -void factory::register_all() -{ - vec_types.resize(et_last, 0); - it i; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_globals.cpp b/src/utils/xrLC_Light/net_execution_globals.cpp deleted file mode 100644 index 43148bd195e..00000000000 --- a/src/utils/xrLC_Light/net_execution_globals.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "stdafx.h" - -#include "net_execution_globals.h" - -////NEVER REMOVE THESE INCLUDES//// -#include "net_all_executions.h" -#include "net_all_globals.h" -////NEVER REMOVE THESE INCLUDES//// -namespace lc_net -{ -static execution_globals_reg exe_reg; -static globals_globals_reg gl_reg; - -const execution_globals_reg& exe_gl_reg() { return exe_reg; } -const globals_globals_reg& gl_gl_reg() { return gl_reg; } -template -static xr_vector*>& inter_get_table(enum_table& table) -{ - return table.gl_table; -} - -template -struct add_global -{ - add_global() - { - xr_vector& v = *inter_get_table(exe_reg)[ie]; - v.erase(std::find(v.begin(), v.end(), ig)); - } -}; - -template -struct global_add_global -{ - global_add_global() - { - xr_vector& v = *inter_get_table(gl_reg)[ie]; - v.erase(std::find(v.begin(), v.end(), ig)); - } -}; - -template -struct add_enum; - -template -struct add_enum, ig> -{ - global_add_global v; -}; - -template -struct add_enum, ig> -{ - add_global v; -}; - -template -struct list_glob -{ - static const e_net_globals ii = (e_net_globals)(i); - static const e_net_globals next_ii = (e_net_globals)(i + 1); - typedef list_glob next; - next n; - add_enum remove; // -}; - -template -struct list_glob -{ -}; - -/*template< class e > -struct list_exec; - -template< class e > -struct list_exec*/ -template -class n_type; - -template -class n_type> -{ -public: - typedef type_net_globals next; -}; - -template -class n_type> -{ -public: - typedef type_execution next; -}; - -template -struct v_type; -template <> -struct v_type -{ - static const execution_types first = et_lightmaps; - static const execution_types last = et_last; - typedef type_execution enum_type; -}; -template <> -struct v_type -{ - static const e_net_globals first = gl_cl_data; - static const e_net_globals last = gl_last; - typedef type_net_globals enum_type; -}; - -template -struct list_exec -{ - // typedef typename e::type e_type; - // static const e_type ii = ( e_type )(e::value); - // static const e_type next_ii = ( e_type )(i+1); - typedef typename n_type::next n; - typedef list_exec next; - typedef list_glob globs; - next in; - globs gl; -}; - -template <> -struct list_exec> -{ -}; - -template <> -struct list_exec> -{ -}; - -template -enum_table::enum_table() -{ - gl_table.resize(v_type::last, 0); - - for (u32 i = v_type::first; v_type::last != i; ++i) - { - gl_table[i] = xr_new>(); - for (u32 j = gl_cl_data; gl_last != j; ++j) - gl_table[i]->push_back(e_net_globals(j)); - } - list_exec::enum_type> remove_globs; -} -} diff --git a/src/utils/xrLC_Light/net_execution_globals.h b/src/utils/xrLC_Light/net_execution_globals.h deleted file mode 100644 index fa171fdda7c..00000000000 --- a/src/utils/xrLC_Light/net_execution_globals.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _NET_EXECUTION_GLOBALS_REG_ -#define _NET_EXECUTION_GLOBALS_REG_ -#include "net_global_data.h" -#include "net_execution.h" -namespace lc_net -{ -template -class type_net_globals -{ -public: - typedef e_net_globals type; - static const type value = e; - // static const type first = gl_cl_data ; - // static const type last = gl_last ; -}; - -template -class type_execution -{ -public: - typedef execution_types type; - static const type value = e; - // static const type first = et_lightmaps ; - // static const type last = et_last ; -}; - -template -class enum_table; -template -static xr_vector*>& inter_get_table(enum_table& table); - -template -class enum_table -{ -public: - typedef xr_vector*> type_table; - -private: - friend type_table& inter_get_table(enum_table& table); - type_table gl_table; - -public: - enum_table(); - const xr_vector& get_globals(e et) const { return *gl_table[et]; } -private: -}; -typedef enum_table execution_globals_reg; -typedef enum_table globals_globals_reg; - -const execution_globals_reg& exe_gl_reg(); -const globals_globals_reg& gl_gl_reg(); -} -#endif diff --git a/src/utils/xrLC_Light/net_execution_implicit_light.cpp b/src/utils/xrLC_Light/net_execution_implicit_light.cpp deleted file mode 100644 index c0f6e94b1bf..00000000000 --- a/src/utils/xrLC_Light/net_execution_implicit_light.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "stdafx.h" -#include "net_execution_implicit_light.h" -#include "serialize.h" -namespace lc_net -{ -static constexpr size_t implicit_light_task_buffer_size = 32; -static constexpr size_t implicit_light_result_buffer_size = 1024; - -void execution_implicit_light::send_task(IGenericStream* outStream) -{ - { - u8 buff[implicit_light_task_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, send_receive_task_buffer_size ); - exec.write(w); - } -} -bool execution_implicit_light::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - u8 buff[implicit_light_task_buffer_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r( inStream ); - exec.read(r); - return true; -} - -void execution_implicit_light::receive_result(IGenericStream* inStream) -{ - u8 buff[implicit_light_result_buffer_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r(inStream); - exec.receive_result(r); -} -void execution_implicit_light::send_result(IGenericStream* outStream) -{ - u8 buff[implicit_light_result_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, implicit_light_result_buffer_size ); - exec.send_result(w); -} -bool execution_implicit_light::execute(net_task_callback& net_callback) -{ - exec.Execute(&net_callback); - return true; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_implicit_light.h b/src/utils/xrLC_Light/net_execution_implicit_light.h deleted file mode 100644 index 6a841879fd8..00000000000 --- a/src/utils/xrLC_Light/net_execution_implicit_light.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _NET_EXECUTION_IMPLICIT_LIGHT_H_ -#define _NET_EXECUTION_IMPLICIT_LIGHT_H_ -#include "net_execution.h" -#include "xrlight_implicit.h" - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl execution_implicit_light; -template <> -class tnet_execution_base::net_execution_impl -{ - ImplicitExecute exec; - -public: - void construct(const ImplicitExecute& _e) { exec = _e; } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* inStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -}; -// template<> struct add_global{}; -template <> -struct add_global -{ -}; -// execution_lightmaps -}; -#endif diff --git a/src/utils/xrLC_Light/net_execution_lightmaps.cpp b/src/utils/xrLC_Light/net_execution_lightmaps.cpp deleted file mode 100644 index 07aea90a85e..00000000000 --- a/src/utils/xrLC_Light/net_execution_lightmaps.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "stdafx.h" - -#include "net_execution_lightmaps.h" -#include "net_task.h" -#include "xrlc_globaldata.h" -#include "xrdeflector.h" -#include "light_execute.h" -#include "xrdeflector.h" - -#include "execute_statistics.h" -#include "xrCore/ftimer.h" - -namespace lc_net -{ -static constexpr size_t lightmaps_task_buff_size = 8; -static constexpr size_t lightmaps_result_buff_size = 512 * 1024; - -void execution_lightmaps::send_task(IGenericStream* outStream) -{ - { - u8 buff[lightmaps_task_buff_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, lightmaps_task_buff_size ); - - R_ASSERT(from != u32(-1)); - R_ASSERT(to != u32(-1)); - R_ASSERT(from < to); - w.w_u32(from); - w.w_u32(to); - } -} - -bool execution_lightmaps::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - u8 buff[lightmaps_task_buff_size]; - - INetBlockReader r(inStream, buff, lightmaps_task_buff_size); - // INetReaderGenStream r( inStream ); - from = r.r_u32(); - to = r.r_u32(); - R_ASSERT(from != u32(-1)); - R_ASSERT(to != u32(-1)); - R_ASSERT(from < to); - return true; -} - -void execution_lightmaps::send_result(IGenericStream* outStream) -{ - u8 buff[lightmaps_result_buff_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, lightmaps_result_buff_size ); - // VERIFY(deflector_id!= u32(-1)); - // w.w_u32( deflector_id ); - R_ASSERT(from != u32(-1)); - R_ASSERT(to != u32(-1)); - R_ASSERT(from < to); - w.w_u32(from); - w.w_u32(to); - for (u32 i = from; i < to; ++i) - { - CDeflector* D = inlc_global_data()->g_deflectors()[i]; - D->send_result(w); - lm_layer& lm = D->layer; - lm.destroy(); - } -#ifdef COLLECT_EXECUTION_STATS - write_statistics(w); -#endif - return; -} -void execution_lightmaps::receive_result(IGenericStream* outStream) -{ - u8 buff[lightmaps_result_buff_size]; - INetBlockReader r(outStream, buff, sizeof(buff)); - // INetReaderGenStream r(outStream); - // u32 id = r.r_u32(); - // VERIFY(id==deflector_id); - - u32 _from = r.r_u32(); - u32 _to = r.r_u32(); - - R_ASSERT(_from != u32(-1)); - R_ASSERT(_to != u32(-1)); - R_ASSERT(_from < _to); - R_ASSERT(_from == from); - R_ASSERT(_to == to); - for (u32 i = from; i < to; ++i) - inlc_global_data()->g_deflectors()[i]->receive_result(r); -#ifdef COLLECT_EXECUTION_STATS - read_statistics(r); - statistic_log(); -#endif -} -bool execution_lightmaps::execute(net_task_callback& net_callback) -{ -#ifdef COLLECT_EXECUTION_STATS - CTimer gtimer; - gtimer.Start(); - // net_callback.agent().GetSessionCacheDirectory( net_callback.session(), statistics.dir ); - u32 sz = sizeof(statistics.dir); - GetComputerName(statistics.dir, &sz); -#endif - - for (u32 i = from; i < to; ++i) - { -#ifdef COLLECT_EXECUTION_STATS - - CTimer timer; - timer.Start(); -#endif - CDeflector* D = inlc_global_data()->g_deflectors()[i]; - VERIFY(D); - lm_layer& lm = D->layer; - lm.create(lm.width, lm.height); - D->_net_session = &net_callback; - light_execute().run(*D); - D->_net_session = 0; -#ifdef COLLECT_EXECUTION_STATS - - D->time_stat.m_time = timer.GetElapsed_sec(); -#endif - - if (net_callback.break_all()) - break; - } -#ifdef COLLECT_EXECUTION_STATS - statistics.time_stats.m_time = gtimer.GetElapsed_sec(); -#endif - return !net_callback.break_all(); -} - -#ifdef COLLECT_EXECUTION_STATS -void execution_lightmaps::statistic_log() -{ - Msg("STATISTICS "); - Msg("deflectors from: %d, to: %d ", from, to); - Msg("deflectors number: %d", to - from); - statistics.log(); - - for (u32 i = from; i < to; ++i) - { - CDeflector* D = inlc_global_data()->g_deflectors()[i]; - D->statistic_log(); - } -} -void execution_lightmaps::read_statistics(INetReader& r) -{ - statistics.read(r); - for (u32 i = from; i < to; ++i) - { - CDeflector* D = inlc_global_data()->g_deflectors()[i]; - D->time_stat.read(r); - } -} -void execution_lightmaps::write_statistics(IWriter& w) const -{ - statistics.write(w); - for (u32 i = from; i < to; ++i) - { - CDeflector* D = inlc_global_data()->g_deflectors()[i]; - D->time_stat.write(w); - } -} -#endif -}; diff --git a/src/utils/xrLC_Light/net_execution_lightmaps.h b/src/utils/xrLC_Light/net_execution_lightmaps.h deleted file mode 100644 index 746fe2900c5..00000000000 --- a/src/utils/xrLC_Light/net_execution_lightmaps.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _NET_EXECUTION_LIGHTMAPS_H_ -#define _NET_EXECUTION_LIGHTMAPS_H_ -#include "net_execution.h" -#include "execute_statistics.h" - -class net_task_callback; - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl execution_lightmaps; -template <> -class tnet_execution_base::net_execution_impl -{ - u32 from; - u32 to; - -public: - net_execution_impl() : from(u32(-1)), to(u32(-1)) {} - void construct(u32 _from, u32 _to) - { - from = _from; - to = _to; - } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* outStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -#ifdef COLLECT_EXECUTION_STATS - execute_statistics statistics; - void statistic_log(); - void read_statistics(INetReader& r); - void write_statistics(IWriter& w) const; -#endif -}; -template <> -struct add_global -{ -}; -// execution_lightmaps -}; -#endif diff --git a/src/utils/xrLC_Light/net_execution_mu_base.cpp b/src/utils/xrLC_Light/net_execution_mu_base.cpp deleted file mode 100644 index de6840756eb..00000000000 --- a/src/utils/xrLC_Light/net_execution_mu_base.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 03.06.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "net_execution_mu_base.h" - -#include "xrface.h" -#include "xrMU_Model.h" -#include "xrlc_globaldata.h" - -namespace lc_net -{ -static constexpr size_t mu_base_light_result_buffer_size = 128 * 1024; - -void execution_mu_base_light::send_task(IGenericStream* outStream) -{ - R_ASSERT(mu_model_id != u32(-1)); - outStream->Write(&mu_model_id, sizeof(mu_model_id)); -} -bool execution_mu_base_light::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - inStream->Read(&mu_model_id, sizeof(mu_model_id)); - R_ASSERT(mu_model_id != u32(-1)); - return true; -} - -void execution_mu_base_light::receive_result(IGenericStream* inStream) -{ - u8 buff[mu_base_light_result_buffer_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r( inStream ); - mu_model_id = r.r_u32(); - R_ASSERT(mu_model_id != u32(-1)); - xrMU_Model& model = *inlc_global_data()->mu_models()[mu_model_id]; - // model.read_subdivs( r ); - model.read_color(r); -} - -void execution_mu_base_light::send_result(IGenericStream* outStream) -{ - R_ASSERT(mu_model_id != u32(-1)); - - u8 buff[mu_base_light_result_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, 100 ); - w.w_u32(mu_model_id); - xrMU_Model& model = *inlc_global_data()->mu_models()[mu_model_id]; - // model.write_subdivs( w ); - model.write_color(w); -} -bool execution_mu_base_light::execute(net_task_callback& net_callback) -{ - R_ASSERT(mu_model_id != u32(-1)); - xrMU_Model& model = *inlc_global_data()->mu_models()[mu_model_id]; - // model.calc_materials(); - model.calc_lighting(); - - return true; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_mu_base.h b/src/utils/xrLC_Light/net_execution_mu_base.h deleted file mode 100644 index c64c6aa91fe..00000000000 --- a/src/utils/xrLC_Light/net_execution_mu_base.h +++ /dev/null @@ -1,36 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 03.06.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef NET_EXECUTION_MU_BASE_H_INCLUDED -#define NET_EXECUTION_MU_BASE_H_INCLUDED -#include "net_execution.h" - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl execution_mu_base_light; -template <> -class tnet_execution_base::net_execution_impl -{ - u32 mu_model_id; - -public: - net_execution_impl() : mu_model_id(u32(-1)) {} - void construct(u32 id) { mu_model_id = id; } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* inStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -}; -template <> -struct add_global -{ -}; - -// execution_lightmaps -}; - -#endif // #ifndef NET_EXECUTION_MU_BASE_H_INCLUDED diff --git a/src/utils/xrLC_Light/net_execution_mu_ref.cpp b/src/utils/xrLC_Light/net_execution_mu_ref.cpp deleted file mode 100644 index d686508cb82..00000000000 --- a/src/utils/xrLC_Light/net_execution_mu_ref.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "stdafx.h" -#include "net_execution_mu_ref.h" - -#include "xrface.h" -#include "xrMU_Model.h" -#include "xrMU_Model_Reference.h" - -#include "xrlc_globaldata.h" - -namespace lc_net -{ -static constexpr size_t mu_ref_light_result_buffer_size = 128 * 1024; - -void execution_mu_ref_light::send_task(IGenericStream* outStream) -{ - R_ASSERT(mu_ref_id != u32(-1)); - outStream->Write(&mu_ref_id, sizeof(mu_ref_id)); -} -bool execution_mu_ref_light::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - inStream->Read(&mu_ref_id, sizeof(mu_ref_id)); - R_ASSERT(mu_ref_id != u32(-1)); - return true; -} - -void execution_mu_ref_light::receive_result(IGenericStream* inStream) -{ - u8 buff[mu_ref_light_result_buffer_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r( inStream ); - mu_ref_id = r.r_u32(); - R_ASSERT(mu_ref_id != u32(-1)); - inlc_global_data()->mu_refs()[mu_ref_id]->receive_result(r); -} - -void execution_mu_ref_light::send_result(IGenericStream* outStream) -{ - R_ASSERT(mu_ref_id != u32(-1)); - - u8 buff[mu_ref_light_result_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, 100 ); - w.w_u32(mu_ref_id); - inlc_global_data()->mu_refs()[mu_ref_id]->send_result(w); -} -bool execution_mu_ref_light::execute(net_task_callback& net_callback) -{ - R_ASSERT(mu_ref_id != u32(-1)); - inlc_global_data()->mu_refs()[mu_ref_id]->calc_lighting(); - return true; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_mu_ref.h b/src/utils/xrLC_Light/net_execution_mu_ref.h deleted file mode 100644 index ad8916a925c..00000000000 --- a/src/utils/xrLC_Light/net_execution_mu_ref.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _MU_EXECUTION_MU_REF_H_ -#define _MU_EXECUTION_MU_REF_H_ -#include "net_execution.h" - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl execution_mu_ref_light; -template <> -class tnet_execution_base::net_execution_impl -{ - u32 mu_ref_id; - -public: - net_execution_impl() : mu_ref_id(u32(-1)) {} - void construct(u32 id) { mu_ref_id = id; } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* inStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -}; -template <> -struct add_global -{ -}; - -// execution_lightmaps -}; - -#endif diff --git a/src/utils/xrLC_Light/net_execution_vertex_light.cpp b/src/utils/xrLC_Light/net_execution_vertex_light.cpp deleted file mode 100644 index e6393a22a57..00000000000 --- a/src/utils/xrLC_Light/net_execution_vertex_light.cpp +++ /dev/null @@ -1,110 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 23.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "net_execution_vertex_light.h" -#include "xrlc_globaldata.h" -#include "xrface.h" -#include "light_point.h" -#include "xrCDB/xrCDB.h" -extern XRLC_LIGHT_API void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c& C, Fvector& P, Fvector& N, - base_lighting& lights, u32 flags, Face* skip); -void g_trans_register(Vertex* V); -namespace lc_net -{ -static constexpr size_t vertex_light_task_buffer_size = 16; -static constexpr size_t vertex_light_result_buffer_size = 512 * 1024; - -void net_execution_vertex_light::send_task(IGenericStream* outStream) -{ - { - R_ASSERT(start != u32(-1)); - R_ASSERT(end != u32(-1)); - R_ASSERT(start < end); - u8 buff[vertex_light_task_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, vertex_light_task_buffer_size ); - - w.w_u32(start); - w.w_u32(end); - } -} -bool net_execution_vertex_light::receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - u8 buff[vertex_light_task_buffer_size]; - INetBlockReader r(inStream, buff, sizeof(buff)); - // INetReaderGenStream r( inStream ); - start = r.r_u32(); - end = r.r_u32(); - R_ASSERT(start != u32(-1)); - R_ASSERT(end != u32(-1)); - R_ASSERT(start < end); - - return true; -} - -void net_execution_vertex_light::receive_result(IGenericStream* outStream) -{ - u8 buff[vertex_light_result_buffer_size]; - INetBlockReader r(outStream, buff, sizeof(buff)); - // INetReaderGenStream r(outStream); - u32 _start = r.r_u32(); - u32 _end = r.r_u32(); - VERIFY(_start == start); - VERIFY(_end == end); - for (u32 i = start; i < end; ++i) - { - Vertex* V = lc_global_data()->g_vertices()[i]; - V->read(r); - g_trans_register(V); - } - - // inlc_global_data()->g_deflectors()[ deflector_id ]->read( r ); -} - -void net_execution_vertex_light::send_result(IGenericStream* outStream) -{ - u8 buff[vertex_light_result_buffer_size]; - INetMemoryBuffWriter w(outStream, sizeof(buff), buff); - // INetIWriterGenStream w( outStream, vertex_light_result_buffer_size ); - VERIFY(start != u32(-1)); - VERIFY(end != u32(-1)); - w.w_u32(start); - w.w_u32(end); - for (u32 i = start; i < end; ++i) - { - Vertex* V = lc_global_data()->g_vertices()[i]; - V->write(w); - } - return; -} -bool net_execution_vertex_light::execute(net_task_callback& net_callback) -{ - for (u32 i = start; i < end; ++i) - { - Vertex* V = lc_global_data()->g_vertices()[i]; - - base_color_c vC, old; - V->C._get(old); - - CDB::COLLIDER DB; - LightPoint(&DB, 0, lc_global_data()->RCAST_Model(), vC, V->P, V->N, lc_global_data()->L_static(), - (lc_global_data()->b_nosun() ? LP_dont_sun : 0) | LP_dont_hemi, 0); - // vC._tmp_ = v_trans; //we olready have it in V->C.t - vC.mul(.5f); - vC.hemi = old.hemi; // preserve pre-calculated hemisphere - V->C._set(vC.rgb, vC.hemi, vC.sun); - } - - return true; //! net_callback.break_all(); -} - -void net_execution_vertex_light::construct(u32 _start, u32 _end) -{ - start = _start; - end = _end; -} -}; diff --git a/src/utils/xrLC_Light/net_execution_vertex_light.h b/src/utils/xrLC_Light/net_execution_vertex_light.h deleted file mode 100644 index 88a5458418b..00000000000 --- a/src/utils/xrLC_Light/net_execution_vertex_light.h +++ /dev/null @@ -1,47 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 23.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef NET_EXECUTION_VERTEX_LIGHT_H_INCLUDED -#define NET_EXECUTION_VERTEX_LIGHT_H_INCLUDED - -#include "net_execution.h" - -class net_task_callback; - -namespace lc_net -{ -typedef class tnet_execution_base::net_execution_impl net_execution_vertex_light; -template <> -class tnet_execution_base::net_execution_impl -{ - u32 start; - u32 end; - -public: - net_execution_impl() : start(u32(-1)), end(-1) {} - void construct(u32 _start, u32 _end); // { start = _start;end = _end; } - void send_task(IGenericStream* outStream); - void receive_result(IGenericStream* outStream); - bool receive_task(IAgent* agent, u32 sessionId, IGenericStream* inStream); - void send_result(IGenericStream* outStream); - bool execute(net_task_callback& net_callback); -}; -template <> -struct add_global -{ -}; -// execution_lightmaps -}; - -// class net_execution_vertex_light { -// public: -// -// -// private: -// -//}; // class net_execution_vertex_light - -#endif // #ifndef NET_EXECUTION_VERTEX_LIGHT_H_INCLUDED diff --git a/src/utils/xrLC_Light/net_global_data.cpp b/src/utils/xrLC_Light/net_global_data.cpp deleted file mode 100644 index 240ed393553..00000000000 --- a/src/utils/xrLC_Light/net_global_data.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include "stdafx.h" - -#include "net_global_data.h" -#include "net_all_globals.h" -#include "net_global_data_cleanup.h" -#include "net_execution_globals.h" -namespace lc_net -{ -static net_globals globs; - -net_globals& globals() { return globs; } -static LPCSTR global_data_file_path(LPCSTR name, string_path& path_name) -{ - FS.update_path(path_name, "$app_root$", name); - return path_name; -} - -bool global_data_file_path(LPCSTR name, IAgent* agent, u32 sessionId, string_path& path_name) -{ - HRESULT rz = agent->GetSessionCacheDirectory(sessionId, path_name); - if (rz != S_OK) - return false; - strconcat(sizeof(path_name), path_name, path_name, name); - return true; -} - -template -class tnet_global_data : public tnet_global_data_base -// public net_global_data, -// public net_global_data_impl -{ - typedef net_global_data_impl impl; - // net_global_data_impl impl; - - Lock create_data_lock; - Lock ref_lock; - u32 _id; - u32 _use_count; - bool _clear; - -public: - tnet_global_data() : _id(0), _use_count(0), _clear(false) {} - void clear() - { - VERIFY(_id != 0); - ref_lock.Enter(); - create_data_lock.Enter(); - if (_use_count > 0) - _clear = true; - else - destroy_data(); - create_data_lock.Leave(); - ref_lock.Leave(); - } - IC u32 id() { return _id; } -private: - virtual void add_ref() - { - ref_lock.Enter(); - ++_use_count; - ref_lock.Leave(); - } - virtual void free_ref() - { - ref_lock.Enter(); - R_ASSERT(_use_count > 0); - --_use_count; - if (_clear) - { - destroy_data(); - _clear = false; - } - ref_lock.Leave(); - } - virtual void on_task_send(IGenericStream* outStream) const - { - R_ASSERT2(_id > 0, "data not ready call globaldata::init()"); - // - const xr_vector& v = gl_gl_reg().get_globals(gl_type); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - globals().get(v[i]).on_task_send(outStream); - // - outStream->Write(&_id, sizeof(_id)); - } - virtual bool on_task_receive(IAgent* agent, u32 sessionId, IGenericStream* inStream) - { - // - const xr_vector& v = gl_gl_reg().get_globals(gl_type); - u32 size = v.size(); - for (u32 i = 0; i < size; ++i) - globals().get(v[i]).on_task_receive(agent, sessionId, inStream); - // - create_data_lock.Enter(); - u32 i; - inStream->Read(&i, sizeof(i)); - R_ASSERT(i > 0); - if (i == _id) - { - create_data_lock.Leave(); - return true; - } - if (_id == 0) - { - bool ret = create_data(i, agent, sessionId); - create_data_lock.Leave(); - return ret; - } - create_data_lock.Leave(); - return false; - } - - virtual LPCSTR files(string_path& buf) - { - // - - const xr_vector& v = gl_gl_reg().get_globals(gl_type); - // xr_vector::const_iterator i = v.begin(), e = v.end(); - u32 size = v.size(); - buf[0] = 0; - for (u32 i = 0; i < size; ++i) - { - string_path lbuf; - strconcat(sizeof(string256), buf, buf, globals().get(v[i]).files(lbuf)); - } - strconcat(sizeof(string256), buf, buf, ",", impl::file_name()); - return buf; - } - - void create_data_file() - { - R_ASSERT(_id > 0); - string_path path_name; - global_data_file_path(impl::file_name(), path_name); - impl::create_data_file(path_name); - } - - bool create_data(u32 id, IAgent* agent, u32 sessionId) - { - if (_id == id) - return true; - string_path path_name; - if (!global_data_file_path(impl::file_name(), agent, sessionId, path_name)) - return false; - if (impl::create_data(path_name)) - _id = id; - return _id == id; - } - void destroy_data() - { - R_ASSERT(_use_count == 0); - impl::destroy_data(); - _id = 0; - } - virtual void data_init() - { - data_cleanup(); - create_data_lock.Enter(); - impl::data_init(); - ++_id; - create_data_file(); - create_data_lock.Leave(); - } - - virtual void data_cleanup() - { - create_data_lock.Enter(); - - if (_id > 0) - { - R_ASSERT(_use_count == 0); - impl::data_cleanup(); - lc_net::cleanup().set_cleanup(_id); - } - create_data_lock.Leave(); - } -}; - -template -struct it -{ - static const e_net_globals et = (e_net_globals)(i); - static const e_net_globals next_et = (e_net_globals)(i + 1); - typedef it next; - next ni; - it(xr_vector& data) : ni(data) { data[et] = xr_new>(); } - static void cleanup(xr_vector& data) - { - tnet_global_data* gd = static_cast*>(data[et]); - if (gd->id() > 0 && lc_net::cleanup().get_cleanup() >= gd->id()) - gd->clear(); - next::cleanup(data); - } -}; -template <> -struct it -{ - it(xr_vector& data) {} - static void cleanup(xr_vector& data) - { -#ifdef CL_NET_LOG - Msg("clean up end call"); -#endif - } -}; - -net_globals::net_globals() -{ - data.resize(gl_last, 0); - it i(data); -} - -void net_globals::cleanup() -{ -#ifdef CL_NET_LOG - Msg("globals cleanup call"); -#endif - it::cleanup(data); -} -} diff --git a/src/utils/xrLC_Light/net_global_data.h b/src/utils/xrLC_Light/net_global_data.h deleted file mode 100644 index 46578b2c6dc..00000000000 --- a/src/utils/xrLC_Light/net_global_data.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _NET_GLOBAL_DATA_H_ -#define _NET_GLOBAL_DATA_H_ -#include "hxgrid/Interface/hxgridinterface.h" -namespace lc_net -{ -enum e_net_globals -{ - gl_cl_data, - gl_implicit_cl_data, - gl_lm_data, - gl_ref_model_data, - gl_detail_cl_data, - gl_base_cl_data, - gl_last -}; - -class net_global_data -{ -public: - virtual void on_task_send(IGenericStream* outStream) const = 0; - virtual bool on_task_receive(IAgent* agent, u32 sessionId, IGenericStream* inStream) = 0; - virtual LPCSTR files(string_path& buf) = 0; - virtual void add_ref() = 0; - virtual void free_ref() = 0; -}; -template -class net_global_data_impl; - -template -class tnet_global_data_base : public net_global_data, public net_global_data_impl -{ -}; - -class net_globals -{ - xr_vector data; - -public: - net_globals(); - - net_global_data& get(e_net_globals id) { return *data[id]; } - template - net_global_data_impl& get() - { - return *static_cast*>( - static_cast*>(data[gl_type])); - } - -private: - friend class global_data_cleanup; - void cleanup(); -}; - -net_globals& globals(); -template -struct global_add_global; -} -#endif diff --git a/src/utils/xrLC_Light/net_global_data_cleanup.cpp b/src/utils/xrLC_Light/net_global_data_cleanup.cpp deleted file mode 100644 index a22855f0340..00000000000 --- a/src/utils/xrLC_Light/net_global_data_cleanup.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "stdafx.h" - -#include "net_global_data_cleanup.h" -#include "serialize.h" -namespace lc_net -{ -global_data_cleanup _cleanup; -global_data_cleanup& cleanup() { return _cleanup; } -global_data_cleanup::global_data_cleanup() : id_state(0) { vec_cleanup.resize(gl_last, 0); } -void global_data_cleanup::on_net_send(IGenericStream* outStream) { outStream->Write(&id_state, sizeof(id_state)); } -static const u32 data_cleanup_callback_read_write_buff_size = 512; - -void __cdecl data_cleanup_callback(const char* dataDesc, IGenericStream** stream) -{ - *stream = CreateGenericStream(); - u8 buff[data_cleanup_callback_read_write_buff_size]; - w_pod_vector(INetMemoryBuffWriter(*stream, sizeof(buff), buff), _cleanup.vec_cleanup); - // w_pod_vector( INetIWriterGenStream( *stream, 512 ), _cleanup.vec_cleanup ); -} - -#pragma warning(push) -#pragma warning(disable : 4995) -void global_data_cleanup::on_net_receive(IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - u32 state = u32(-1); - inStream->Read(&state, sizeof(id_state)); - lock.Enter(); - if (state == id_state) - { - lock.Leave(); - return; - } - IGenericStream* globalDataStream = 0; - HRESULT rz = agent->GetData(sessionId, "data_cleanup", &globalDataStream); - if (rz != S_OK) - { - lock.Leave(); - return; - } - R_ASSERT(globalDataStream); - u8 buff[data_cleanup_callback_read_write_buff_size]; - r_pod_vector(INetBlockReader(globalDataStream, buff, sizeof(buff)), vec_cleanup); - // r_pod_vector( INetReaderGenStream( globalDataStream ), vec_cleanup ); - - free(globalDataStream->GetCurPointer()); - id_state = state; -#ifdef CL_NET_LOG - Msg("cleanup call"); -#endif - globals().cleanup(); - lock.Leave(); - return; -} -#pragma warning(pop) -} diff --git a/src/utils/xrLC_Light/net_global_data_cleanup.h b/src/utils/xrLC_Light/net_global_data_cleanup.h deleted file mode 100644 index 32e9a5e043a..00000000000 --- a/src/utils/xrLC_Light/net_global_data_cleanup.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _NET_GLOBAL_DATA_CLEANUP_ -#define _NET_GLOBAL_DATA_CLEANUP_ -#include "net_global_data.h" -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" -#include "xrCore/Threading/Lock.hpp" - -namespace lc_net -{ -class global_data_cleanup -{ - u32 id_state; - xr_vector vec_cleanup; - Lock lock; - friend void data_cleanup_callback(const char* dataDesc, IGenericStream** stream); - -public: - global_data_cleanup(); - - template - void set_cleanup(u32 id) - { - lock.Enter(); - if (vec_cleanup[data] == id) - { - lock.Leave(); - return; - } - ++id_state; - vec_cleanup[data] = id; - lock.Leave(); - }; - template - u32 get_cleanup() const - { - return vec_cleanup[data]; - }; - void on_net_send(IGenericStream* outStream); - void on_net_receive(IAgent* agent, u32 sessionId, IGenericStream* inStream); -}; -global_data_cleanup& cleanup(); -} - -#endif diff --git a/src/utils/xrLC_Light/net_light.cpp b/src/utils/xrLC_Light/net_light.cpp deleted file mode 100644 index 3bbf1a4f85a..00000000000 --- a/src/utils/xrLC_Light/net_light.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "stdafx.h" - -#include "net_light.h" -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/IGenericStream.h" -#include "net_light_task.h" -#include "net_stream.h" -#include "xrlc_globaldata.h" -#include "xrdeflector.h" -#include "net_task.h" -//============================================================================== -// function RunTask(): boolean; -//============================================================================== - -static Lock block; -LPCSTR dataDesc = "global_data"; - -xr_vector net_pool; -/* -static struct unload -{ - IAgent* agent; - ~unload() - { - if(!agent) - return; - LPCRITICAL_SECTION gcs; - agent->GetGlobalCriticalSection( &gcs ); - LeaveCriticalSection( gcs ); - } -} _unload; -*/ -#pragma warning(push) -#pragma warning(disable : 4995) -u32 g_sessionId = u32(-1); - -// bool GetGlobalData( IAgent* agent, -// u32 sessionId ); -bool TaskReceive(net_task& task, IAgent* agent, u32 sessionId, IGenericStream* inStream); - -bool GetGlobalData(IAgent* agent, u32 sessionId) -{ - if (!inlc_global_data()) - { - VERIFY(agent); - net_pool.clear(); - - /* - IGenericStream* globalDataStream=0; - HRESULT rz = agent->GetData(sessionId, dataDesc, &globalDataStream); - - if (rz!=S_OK) - return false; - */ - string_path cache_dir; - HRESULT rz = agent->GetSessionCacheDirectory(sessionId, cache_dir); - if (rz != S_OK) - return false; - strconcat(sizeof(cache_dir), cache_dir, cache_dir, gl_data_net_file_name); - - /* - IWriter* file = FS.w_open( cache_dir ); - R_ASSERT(file); - file->w( globalDataStream->GetCurPointer(), globalDataStream->GetLength() ); - - free(globalDataStream->GetCurPointer()); - FS.w_close(file); - - agent->FreeCachedData(sessionId, dataDesc); - ULONG r =globalDataStream->AddRef(); - r = globalDataStream->Release(); - if(r>0) - globalDataStream->Release(); - agent->FreeCachedData(sessionId, dataDesc); - Memory.mem_compact (); - */ - - DataReadCreate(cache_dir); - - return true; - } - return true; -} - -bool TaskReceive(net_task& task, IAgent* agent, u32 sessionId, IGenericStream* inStream) -{ - bool ret = false; - __try - { - ret = GetGlobalData(agent, sessionId) && task.receive(inStream); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - Msg("accept!"); - return ret; - } - FPU::m64r(); - return ret; -} - -class net_task_interface_impl : public net_task_interface -{ - bool TaskReceive(net_task& task, IAgent* agent, u32 sessionId, IGenericStream* inStream) - { - return ::TaskReceive(task, agent, sessionId, inStream); - } - /*bool GetGlobalData( IAgent* agent, - DWORD sessionId ) - { - GetGlobalData() - }*/ - bool TaskSendResult(net_task& task, IGenericStream* outStream) - { - bool ret = false; - __try - { - ret = task.send(outStream); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - Msg("accept!"); - return ret; - } - return ret; - } - - bool RunTask(IAgent* agent, u32 sessionId, IGenericStream* inStream, IGenericStream* outStream) - { - block.Enter(); - - g_sessionId = sessionId; - net_task task(agent, sessionId); - - if (!TaskReceive(task, agent, sessionId, inStream)) - { - block.Leave(); - return false; - } - block.Leave(); - - task.run(); - - block.Enter(); - - if (!TaskSendResult(task, outStream)) - { - block.Leave(); - return false; - } - block.Leave(); - return true; - } -} g_net_task_interface_impl; -#pragma warning(pop) - -XRLC_LIGHT_API net_task_interface* g_net_task_interface = &g_net_task_interface_impl; -/* -XRLC_LIGHT_API void __cdecl EndSession(IAgent* agent, DWORD sessionId) -{ - LPCRITICAL_SECTION gcs; - agent->GetGlobalCriticalSection( &gcs ); - //LeaveCriticalSection( gcs ); - - -*/ diff --git a/src/utils/xrLC_Light/net_light.h b/src/utils/xrLC_Light/net_light.h deleted file mode 100644 index 199191700ce..00000000000 --- a/src/utils/xrLC_Light/net_light.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include -#include "hxgrid/Interface/IAgent.h" -// interface IGenericStream; -__interface net_task_interface -{ -public: - virtual bool RunTask(IAgent * agent, u32 sessionId, IGenericStream * inStream, IGenericStream * outStream) = 0; -}; - -extern XRLC_LIGHT_API net_task_interface* g_net_task_interface; diff --git a/src/utils/xrLC_Light/net_light_task.cpp b/src/utils/xrLC_Light/net_light_task.cpp deleted file mode 100644 index ff0e25f30d6..00000000000 --- a/src/utils/xrLC_Light/net_light_task.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "stdafx.h" -#include "net_light_task.h" -// void net_light_task::run() -//{ -// -//} diff --git a/src/utils/xrLC_Light/net_light_task.h b/src/utils/xrLC_Light/net_light_task.h deleted file mode 100644 index 30fba88462e..00000000000 --- a/src/utils/xrLC_Light/net_light_task.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "net_task.h" -#include "light_execute.h" -/* -class net_light_task: - public net_task -{ - light_execute execute; - - net_light_task( INetReader* inStream, IWriter* outStream ): net_task(inStream, outStream ){} - - virtual void run(); -}; -*/ diff --git a/src/utils/xrLC_Light/net_lightmaps_add_task.cpp b/src/utils/xrLC_Light/net_lightmaps_add_task.cpp deleted file mode 100644 index b17aecafa24..00000000000 --- a/src/utils/xrLC_Light/net_lightmaps_add_task.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "stdafx.h" -#include "net_execution_lightmaps.h" -#include "net_execution_factory.h" -#include "lcnet_task_manager.h" -#include "lcnet_execution_tasks_add.h" -#include "xrlc_globaldata.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrdeflector.h" - -namespace lc_net -{ -void net_lightmaps_add_task(u32 from, u32 to) -{ - tnet_execution_base* el = lc_net::execution_factory.create(); - el->implementation().construct(from, to); - get_task_manager().add_task(el); -} -/* - void net_lightmaps_add_all_tasks( ) - { - // - - u32 stride = u32(-1); - - u32 threads = u32(-1); - u32 rest = u32(-1); - - - u32 size = inlc_global_data()->g_deflectors().size(); - - get_intervals( 20000, size, threads, stride, rest ); - - for (u32 thID=0; thID 0) - net_lightmaps_add_task( threads*stride,threads*stride + rest ); - } - -*/ - -static const u32 num_tasks = 20000; -static const float f_num_tasks = float(num_tasks); - -static u32 get_next(u32 from, float& f_weight_per_task) -{ - u32 size = inlc_global_data()->g_deflectors().size(); - R_ASSERT(from < size); - float weight = 0; - - for (u32 i = from; i < size; ++i) - { - weight += float(inlc_global_data()->g_deflectors()[i]->weight()); - if (weight > f_weight_per_task) - { - f_weight_per_task = weight; - return i + 1; - } - } - - f_weight_per_task = weight; - return size; -} - -void net_lightmaps_add_all_tasks() -{ - u32 stride = u32(-1); - - u32 rest = u32(-1); - u32 local_num_tasks = num_tasks; - - u32 size = inlc_global_data()->g_deflectors().size(); - - get_intervals(num_tasks, size, local_num_tasks, stride, rest); - - if (rest != 0) - ++local_num_tasks; - - // - u32 total_weight = 0; - xr_vector::const_iterator i = inlc_global_data()->g_deflectors().begin(), - e = inlc_global_data()->g_deflectors().end(); - for (; i != e; ++i) - total_weight += (*i)->weight(); - - float f_weight = float(total_weight); - - u32 from = 0; - - for (;;) - { - if (local_num_tasks == 0) - local_num_tasks = 1; - float f_weight_per_task = f_weight / float(local_num_tasks); - u32 to = get_next(from, f_weight_per_task); - f_weight -= f_weight_per_task; - local_num_tasks--; - - net_lightmaps_add_task(from, to); - from = to; - if (to >= size) - break; - } -} -} diff --git a/src/utils/xrLC_Light/net_stream.cpp b/src/utils/xrLC_Light/net_stream.cpp deleted file mode 100644 index 610504551e1..00000000000 --- a/src/utils/xrLC_Light/net_stream.cpp +++ /dev/null @@ -1,432 +0,0 @@ -#include "stdafx.h" -#include "net_stream.h" - -class XRLC_LIGHT_API INetFileBuffWriter : public INetBuffWriter -{ - virtual void w(const void* ptr, size_t count); - -public: - void w_close() - { - CFileWriteBlock* fr = dynamic_cast(mem_writter); - R_ASSERT(fr); - fr->w_close(); - }; - - INetFileBuffWriter(LPCSTR _file_name, size_t block_size, bool _reopen); //:INetWriter(),file_name(file_name) - virtual ~INetFileBuffWriter(); -}; - -INetReader::~INetReader() {} -void INetReaderGenStream::r(void* p, size_t cnt) { stream->Read(p, cnt); } -INetReaderGenStream::~INetReaderGenStream() {} -void INetBlockReader::r(void* p, size_t cnt) -{ - if (cnt == 0) - return; - u8* pointer = (u8*)p; - add(cnt); - for (;;) - { - if (mem_reader.allocated()) - { - size_t read_cnt = _min(cnt, mem_reader.count()); - mem_reader.r(pointer, read_cnt); - pointer += read_cnt; - cnt -= read_cnt; - } - if (mem_reader.allocated() && mem_reader.count() == 0) - mem_reader.free_buff(); - // xr_delete( mem_reader ); - - if (cnt == 0) - return; - R_ASSERT(stream); - size_t block_size; - stream->Read(&block_size, sizeof(block_size)); - create_block(block_size); - stream->Read(mem_reader.pdata(), block_size); - } -} - -void INetBlockReader::create_block(size_t size) -{ - VERIFY(!mem_reader.allocated()); - /* - if( !_buffer ) - { - _buffer = (u8*) xr_malloc ( size - #ifdef DEBUG_MEMORY_NAME - , "INetBlockReader - storage" - #endif // DEBUG_MEMORY_NAME - ); - _block_size = size ; - } - if( _block_size < size ) - { - _buffer = (u8*)xr_realloc (_buffer,size - #ifdef DEBUG_MEMORY_NAME - , "CMemoryWriter - storage" - #endif // DEBUG_MEMORY_NAME - ); - _block_size = size ; - } - */ - // R_ASSERT( _block_size >= size ); - mem_reader.alloc(size); -} - -INetBlockReader::~INetBlockReader() -{ - R_ASSERT(!mem_reader.allocated() || mem_reader.count() == 0); - mem_reader.free_buff(); - // xr_free( _buffer ); -} -/* - IC void w_string(const char *p) { w(p,xr_strlen(p));w_u8(13);w_u8(10); } - IC void w_stringZ(const char *p) { w(p,xr_strlen(p)+1); } - IC void w_stringZ(const shared_str& p) { w(*p?*p:"",p.size());w_u8(0); } - IC void w_stringZ(shared_str& p) { w(*p?*p:"",p.size());w_u8(0); } -*/ - -void INetReader::r_string(char* dest, size_t tgt_sz) -{ - R_ASSERT(tgt_sz < 1024); - char buf[1024]; - - buf[0] = r_u8(); - size_t i = 1; - for (; i < 1024; ++i) - { - buf[i] = r_u8(); - if (buf[i - 1] == 13 && buf[i] == 10) - break; - } - const size_t length = i - 1; - R_ASSERT2(length < (tgt_sz - 1), "Dest string less than needed."); - // R_ASSERT (!IsBadReadPtr((void*)src,sz)); - - buf[length] = 0; - - strncpy_s(dest, tgt_sz, buf, length + 1); - - // dest[sz] = 0; -} - -void INetReader::r_stringZ(char* dest) -{ - // R_ASSERT( tgt_sz < 1024 ); - - size_t i = 0; - for (; i < 1024; ++i) - { - dest[i] = r_u8(); - - if (dest[i] == 0) - break; - } -} -void INetReader::r_stringZ(shared_str& dest) -{ - char buf[1024]; - r_stringZ(buf); - dest._set(buf); -} -void INetBlockReader::load_buffer(LPCSTR fn) -{ - // xr_delete(mem_reader); - mem_reader.free_buff(); - IReader* fs = FS.r_open(fn); - if (fs) - { - // mem_reader = new CReadMemoryBlock( fs->length() ); - create_block(fs->length()); - fs->r(mem_reader.pdata(), fs->length()); - FS.r_close(fs); // ->close(); - } -} -void INetMemoryBuffWriter::send_and_clear() -{ - if (mem_writter.is_empty()) - return; - // send_not_clear( stream ); - // R_ASSERT(mem_writter); - mem_writter.send(stream); - // clear(); - // xr_delete( mem_writter ); - mem_writter.clear(); -} - -void INetBuffWriter::send_not_clear(IGenericStream* _stream) -{ - R_ASSERT(mem_writter); - mem_writter->send(_stream); -} - -void INetBuffWriter::clear() { xr_delete(mem_writter); } -void INetMemoryBuffWriter::w(const void* ptr, size_t count) -{ - if (count == 0) - return; - add(count); - const u8* pointer = (const u8*)ptr; - for (;;) - { - VERIFY(mem_writter.rest() >= 0); - if (mem_writter.rest() != 0) - { - const size_t write_cnt = _min(count, mem_writter.rest()); - mem_writter.w(pointer, write_cnt); - count -= write_cnt; - pointer += write_cnt; - } - else - { - R_ASSERT(size_t(-1) != net_block_write_data_size); - - send_and_clear(); - } - // create_block(); - - // VERIFY(mem_writter->rest()>=0); - // if( !mem_writter.is_empty() && mem_writter.rest()==0 ) - //{ - // R_ASSERT(size_t(-1)!=net_block_write_data_size); - - // send_and_clear (); - // create_block(); - - //} - - if (count == 0) - return; - } -} - -void INetFileBuffWriter::w(const void* ptr, size_t count) -{ - VERIFY(mem_writter); - add(count); - mem_writter->w(ptr, count); -} - -// void INetMemoryBuffWriter::create_block() -//{ -// VERIFY(!mem_writter); -// mem_writter = new CMemoryWriteBlock( net_block_write_data_size ); -//} -INetMemoryBuffWriter::~INetMemoryBuffWriter() -{ - if (!mem_writter.is_empty()) - send_and_clear(); - // R_ASSERT(!mem_writter); -} -INetBuffWriter::~INetBuffWriter() { R_ASSERT(!mem_writter); } -void INetBuffWriter::save_buffer(LPCSTR fn) const -{ - if (mem_writter) - mem_writter->save_to(fn); -} - -INetFileBuffWriter::INetFileBuffWriter(LPCSTR _file_name, size_t block_size, bool _reopen) : INetBuffWriter() -{ - mem_writter = xr_new(_file_name, block_size, _reopen); -} - -INetFileBuffWriter::~INetFileBuffWriter() { xr_delete(mem_writter); } -/* - data = (BYTE*) xr_realloc (data,mem_size -#ifdef DEBUG_MEMORY_NAME - , "CMemoryWriter - storage" -#endif // DEBUG_MEMORY_NAME - ); -*/ -void CReadMemoryBlock::r(void* p, size_t cnt) const -{ - R_ASSERT((position + cnt) <= file_size); - CopyMemory(p, _buffer + position, cnt); - position += cnt; -} - -CReadMemoryBlock::CReadMemoryBlock(const size_t buff_size_, u8* buffer) - : buf_size(buff_size_), file_size(0), position(0), _buffer(buffer) -{ - /* - data = (u8*) xr_malloc (file_size_ - #ifdef DEBUG_MEMORY_NAME - , "CReadMemoryBlock - storage" - #endif // DEBUG_MEMORY_NAME - ); - */ - // data = buffer; -} - -CReadMemoryBlock::~CReadMemoryBlock() -{ - // xr_free( data ); -} - -#include "xrCore/FS_impl.h" -size_t INetReader::find_chunk(u32 ID, bool* bCompressed /*= nullptr*/) -{ - R_ASSERT(false); - return inherited::find_chunk(ID, bCompressed); -} - -void CMemoryWriteBlock::send(IGenericStream* _stream) -{ - size_t block_size = tell(); - _stream->Write(&block_size, sizeof(block_size)); - _stream->Write(pointer(), block_size); -} -CFileWriteBlock::CFileWriteBlock(LPCSTR fn, size_t _size, bool _reopen) - : IWriteBlock(_size), file(0), file_map(0), file_name(fn), reopen(_reopen) -{ - if (reopen) - return; - string_path lfile_name; - FS.update_path(lfile_name, "$level$", fn); - file = fopen(lfile_name, "wb"); - VERIFY(file); -} - -CFileWriteBlock::~CFileWriteBlock() -{ - fclose(file); - if (file_map) - fclose(file_map); - if (reopen) - return; - string_path N; - FS.update_path(N, "$level$", file_name); - if (FS.exist(N)) - FS.file_delete(N); -} - -void CFileWriteBlock::w(const void* ptr, size_t count) { fwrite(const_cast(ptr), 1, count, file); } -void CFileWriteBlock::send(IGenericStream* _stream) -{ - R_ASSERT(file_map); - fseek(file_map, 0, SEEK_SET); - size_t const length = _filelength(_fileno(file_map)); - R_ASSERT(length); - - size_t const position = _stream->GetPos(); - size_t block_size = size; - //_stream->SetLength (position + length + ((int(length) - 1)/block_size + 1)*sizeof(block_size)); - _stream->SetLength(position + length); - _stream->Seek(position); - - void* block = xr_alloca(block_size); - - for (size_t n = length / block_size, i = 0; i < n; ++i) - { - fread(block, 1, block_size, file_map); - // _stream->Write ( &block_size, sizeof( block_size) ); - _stream->Write(block, block_size); - } - - block_size = length % block_size; - if (block_size == 0) - { - // xr_free (block); - return; - } - - fread(block, 1, block_size, file_map); - // _stream->Write ( &block_size, sizeof( block_size) ); - _stream->Write(block, block_size); -} - -size_t CFileWriteBlock::rest() -{ - VERIFY(file); - return size - ftell(file_map); -} - -void CFileWriteBlock::w_close() -{ - R_ASSERT(!file_map); - if (!reopen) - { - VERIFY(file); - fclose(file); - } - string_path lfile_name; - FS.update_path(lfile_name, "$level$", file_name); - file_map = fopen(lfile_name, "rb"); -} - -INetReaderFile::INetReaderFile(LPCSTR file_name) : file(0) -{ - file = fopen(file_name, "rb"); // FS.r_open( file_name ); -} - -INetReaderFile::~INetReaderFile() -{ - fclose(file); // FS.r_close( file ); -} - -void INetReaderFile::r(void* p, size_t cnt) -{ - // file->r( p, cnt ); - fread(p, 1, cnt, file); -} - -CGenStreamOnFile::CGenStreamOnFile(CVirtualFileRW* _file) : file(_file) -{ - VERIFY(file); - // string_path lfile_name; - // FS.update_path ( lfile_name, "$level$", file_name ); - // file = fopen( lfile_name, "rb" ); -} -CGenStreamOnFile::~CGenStreamOnFile() -{ - // fclose(file); -} -DWORD __stdcall CGenStreamOnFile::GetLength() -{ - return file->length(); - // return _filelength( _fileno( file ) ); -} -DWORD __stdcall CGenStreamOnFile::Read(void* Data, DWORD count) -{ - R_ASSERT(false); - // fread( Data, 1, count, file ); - return count; -} - -INetIWriterGenStream::INetIWriterGenStream(IGenericStream* _stream, size_t inital_size) - : stream(_stream), block_size(inital_size) -{ - R_ASSERT(_stream); - size_t const position = _stream->GetPos(); - _stream->SetLength(position + inital_size); - _stream->Seek(position); -} -INetIWriterGenStream::~INetIWriterGenStream() {} -void INetIWriterGenStream::w(const void* ptr, size_t count) -{ - size_t const position = stream->GetPos(); - size_t const length = stream->GetLength(); - - if (position + count > length) - { - stream->SetLength(position + block_size); - stream->Seek(position); - } - - stream->Write(ptr, count); -} - -void CMemoryWriteBlock::w(const void* ptr, size_t count) -{ - VERIFY(rest() >= count); - - R_ASSERT(position + count <= buffer_size); - // mem_writer.w(ptr,count); - - CopyMemory(buffer + position, ptr, count); - position += count; - // if (position>file_size) file_size=position;//? -} diff --git a/src/utils/xrLC_Light/net_stream.h b/src/utils/xrLC_Light/net_stream.h deleted file mode 100644 index 54507821386..00000000000 --- a/src/utils/xrLC_Light/net_stream.h +++ /dev/null @@ -1,344 +0,0 @@ -#pragma once -#include "hxgrid/Interface/IAgent.h" - -class XRLC_LIGHT_API byte_count -{ - size_t _count; - -public: - byte_count() : _count(0) {} - IC size_t count() { return _count; } - IC void reset() { _count = 0; } - IC void add(size_t cnt) { _count += cnt; } -}; - -class CReadMemoryBlock -{ - mutable size_t file_size; - mutable u8* _buffer; - const size_t buf_size; - mutable size_t position; - -public: - CReadMemoryBlock(const size_t buf_size_, u8* buffer); - ~CReadMemoryBlock(); - void r(void* p, size_t cnt) const; - size_t count() const { return file_size - position; } - void* pdata() const { return (void*)_buffer; } - // IC void reset_file_size ( size_t new_size ){file_size = new_size ;} - // IC size_t get_file_size ( ) {return file_size; } - void free_buff() const - { - file_size = 0; - position = 0; - } - void alloc(size_t _file_size) const - { - R_ASSERT(buf_size >= _file_size); - VERIFY(!allocated()); - VERIFY(empty()); - file_size = _file_size; - } - bool allocated() const { return (file_size != 0); } - bool empty() const { return (position == 0); } -}; - -class IReadBlock -{ -public: - virtual void r(void* p, size_t cnt) const = 0; - virtual size_t count() const = 0; - virtual void* pdata() const = 0; -}; - -// class CMemoryReadBlock -// //: -// //public IReadBlock -//{ -// CReadMemoryBlock mem_reader; -// public: -// CMemoryReadBlock ( const size_t file_size_, u8* &buff ):mem_reader(file_size_, buff ){}; -// virtual void r ( void *p, size_t cnt )const { mem_reader.r(p,cnt); } -// virtual size_t count ()const { return mem_reader.count(); } -// virtual void *pdata ()const { return mem_reader.pdata(); } -// -// void free_buff ()const { mem_reader.free_buff(); } -// void alloc (size_t _file_size)const { mem_reader.alloc(_file_size); } -// bool allocated ()const { return mem_reader.allocated(); } -// bool empty ()const { return mem_reader.empty(); } -//}; - -class IWriteBlock -{ -protected: - size_t size; - -public: - IWriteBlock(size_t _size) : size(_size) {} - virtual bool save_to(LPCSTR fn) = 0; - // virtual size_t tell () =0; - // virtual u8* pointer () =0; - virtual void w(const void* ptr, size_t count) = 0; - virtual void send(IGenericStream* _stream) = 0; - virtual size_t rest() = 0; -}; - -class CMemoryWriteBlock -//: public IWriteBlock -{ - // CMemoryWriter mem_writer; - u8* buffer; - const size_t buffer_size; - - // u8* data; - size_t position; - - // size_t mem_size; - // size_t file_size; - -public: - CMemoryWriteBlock(u8* _buffer, size_t _size) : buffer(_buffer), buffer_size(_size), position(0) {} - // bool save_to (LPCSTR fn) { return mem_writer.save_to(fn); } - void send(IGenericStream* _stream); - size_t rest() { return buffer_size - tell(); } - void w(const void* ptr, size_t count); - -public: - void clear() { position = 0; } - bool is_empty() { return 0 == position; } -private: - size_t tell() { return position; } - u8* pointer() { return buffer; } -}; - -class CFileWriteBlock : public IWriteBlock -{ - // IWriter *file; - FILE* file; - FILE* file_map; - // CVirtualFileRW *file_map ; - LPCSTR file_name; - bool reopen; - -public: - CFileWriteBlock(LPCSTR fn, size_t _size, bool _reopen); - ~CFileWriteBlock(); - bool save_to(LPCSTR fn) override { return false; }; - void send(IGenericStream* _stream) override; - size_t rest() override; - void w_close(); - // virtual size_t tell () ; - // virtual u8* pointer () ; - void w(const void* ptr, size_t count) override; -}; - -class XRLC_LIGHT_API INetReader : public IReaderBase, public byte_count - -{ -public: - INetReader() - { - // VERIFY(stream); - } - virtual ~INetReader(); - IC intptr_t elapsed() const - { - VERIFY(false); - return 0; - }; - void seek(size_t pos) { VERIFY(false); }; - IC size_t tell() const - { - VERIFY(false); - return 0; - }; - // IC void seek (size_t ptr) { VERIFY(false); } - IC size_t length() const - { - VERIFY(false); - return 0; - }; - // IC void* pointer () const { VERIFY(false); return 0; }; - IC void advance(size_t cnt) { VERIFY(false); } - void r(void* p, size_t cnt) override = 0; - - void r_string(char* dest, size_t tgt_sz); - void r_stringZ(char* dest); - void r_stringZ(shared_str& dest); - size_t find_chunk(u32 ID, bool* bCompressed = nullptr); - -private: - using inherited = IReaderBase; -}; - -class XRLC_LIGHT_API INetReaderFile : public INetReader -{ - FILE* file; - -public: - INetReaderFile(LPCSTR file); - - virtual ~INetReaderFile(); - -private: - void r(void* p, size_t cnt) override; -}; -////////////////////////////////////////////////////////////////////////////// -class XRLC_LIGHT_API INetBuffWriter : public IWriter, public byte_count -{ -protected: - IWriteBlock* mem_writter; - // CMemoryWriteBlock mem_writter; -private: - virtual void seek(size_t pos) { VERIFY(false); } - - size_t tell() override - { - VERIFY(false); - return 0; - }; - - void flush() override - { VERIFY(false); } -public: - INetBuffWriter() : mem_writter(0) - { - // VERIFY(stream); - } - virtual ~INetBuffWriter(); - - virtual void send_not_clear(IGenericStream* _stream); - virtual void clear(); - virtual void save_buffer(LPCSTR fn) const; -}; -class XRLC_LIGHT_API INetMemoryBuffWriter : public IWriter, public byte_count -// public INetBuffWriter -{ - IGenericStream* stream; - size_t net_block_write_data_size; - CMemoryWriteBlock mem_writter; - -public: - INetMemoryBuffWriter(IGenericStream* _stream, size_t _block_size, u8* buffer) - : mem_writter(buffer, _block_size), stream(_stream), net_block_write_data_size(_block_size) - { - // VERIFY(stream); - } - ~INetMemoryBuffWriter(); - -private: - // void create_block (); - void w(const void* ptr, size_t count); - void send_and_clear(); - -private: - virtual void seek(size_t pos) { VERIFY(false); } - - size_t tell() override - { - VERIFY(false); - return 0; - }; - - void flush() override - { VERIFY(false); } -}; -class XRLC_LIGHT_API INetReaderGenStream : public INetReader -{ -public: - INetReaderGenStream(IGenericStream* _stream) : stream(_stream) {} - virtual ~INetReaderGenStream(); - -protected: - IGenericStream* stream; - -private: - void r(void* p, size_t cnt) override; -}; -class XRLC_LIGHT_API INetIWriterGenStream : public IWriter -{ - IGenericStream* stream; - size_t block_size; - -public: - INetIWriterGenStream(IGenericStream* _stream, size_t inital_size); - virtual ~INetIWriterGenStream(); - -private: - virtual void w(const void* ptr, size_t count); - virtual void seek(size_t pos) { VERIFY(false); } - - size_t tell() override - { - VERIFY(false); - return 0; - }; - - void flush() override - { VERIFY(false); } -}; - -class XRLC_LIGHT_API INetBlockReader : public INetReaderGenStream -{ - CReadMemoryBlock mem_reader; - -public: - INetBlockReader(IGenericStream* _stream, u8* buffer, size_t _size_buffer) - : INetReaderGenStream(_stream), mem_reader(_size_buffer, buffer) - { - } - - void load_buffer(LPCSTR fn); - void r(void* p, size_t cnt) override; - virtual ~INetBlockReader(); - -private: - // size_t _block_size; - // u8 *&_buffer; - void create_block(size_t size); - typedef INetReader inherited; -}; - -//////////////////////////////////////////////////////////////////////////////////// - -class CGenStreamOnFile : public IGenericStream -{ - // FILE *file; - CVirtualFileRW* file; - -public: - CGenStreamOnFile(CVirtualFileRW* _file); - ~CGenStreamOnFile(); - -private: - //======== BEGIN COM INTERFACE ======= - IUNKNOWN_METHODS_IMPLEMENTATION_INSTANCE() - - virtual BYTE* __stdcall GetBasePointer() { return (BYTE*)file->pointer(); } - virtual BYTE* __stdcall GetCurPointer() - { - R_ASSERT(false); - return 0; - } - virtual bool __stdcall isReadOnly() - { - R_ASSERT(false); - return false; - } - virtual DWORD __stdcall GetLength(); - virtual void __stdcall Write(const void* Data, DWORD count) { R_ASSERT(false); } - virtual DWORD __stdcall Read(void* Data, DWORD count); - virtual void __stdcall Seek(DWORD pos) { R_ASSERT(false); } - virtual DWORD __stdcall GetPos() - { - R_ASSERT(false); - return false; - } - virtual void __stdcall Clear() { R_ASSERT(false); } - virtual void __stdcall FastClear() { R_ASSERT(false); } - virtual void __stdcall GrowToPos(int DestSize = -1) { R_ASSERT(false); } - virtual void __stdcall Skip(DWORD count) { R_ASSERT(false); } - virtual void __stdcall SetLength(DWORD newLength) { R_ASSERT(false); } - virtual void __stdcall Compact() { R_ASSERT(false); } - virtual DWORD __stdcall GetVersion() const { return CGenStreamOnFile::VERSION; } -}; diff --git a/src/utils/xrLC_Light/net_task.cpp b/src/utils/xrLC_Light/net_task.cpp deleted file mode 100644 index 64b98c73757..00000000000 --- a/src/utils/xrLC_Light/net_task.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "stdafx.h" - -#include "net_task.h" -#include "xrdeflector.h" -#include "xrlc_globaldata.h" - -extern xr_vector net_pool; - -net_task::net_task(IAgent* agent, u32 session) : net_task_callback(agent, session), _id(u32(-1)), _D(0) {} -net_task::~net_task() { VERIFY(!_D || !_D->_net_session); } -bool net_task::receive(IGenericStream* inStream) -{ - INetBlockReader r(inStream); - // INetReaderGenStream r( inStream ); - _id = r.r_u32(); - if (std::find(net_pool.begin(), net_pool.end(), _id) != net_pool.end()) - return false; - net_pool.push_back(_id); - _D = inlc_global_data()->g_deflectors()[_id]; - _D->_net_session = this; - return true; -} -bool net_task::send(IGenericStream* outStream) -{ - INetMemoryBuffWriter w(outStream, 1024 * 1024); - // INetIWriterGenStream w( outStream, 1024*1024 ); - VERIFY(_id != u32(-1)); - xr_vector::iterator it = std::find(net_pool.begin(), net_pool.end(), _id); - net_pool.erase(it); - _D->_net_session = 0; - if (break_all()) - return false; - // inlc_global_data()->create_write_faces(); - w.w_u32(_id); - _D->write(w); - // inlc_global_data()->destroy_write_faces(); - return true; -} - -void net_task::run() -{ - VERIFY(_id != u32(-1)); - VERIFY(_D); - _execute.run(*_D); -} diff --git a/src/utils/xrLC_Light/net_task.h b/src/utils/xrLC_Light/net_task.h deleted file mode 100644 index 350f547dbb3..00000000000 --- a/src/utils/xrLC_Light/net_task.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "light_execute.h" -#include "net_task_callback.h" -// class IWriter; -// class INetReader; -/* -class net_task -{ - INetReader *in_stream ; - IWriter *out_stream ; -public: - net_task( INetReader* inStream, IWriter* outStream ): in_stream( inStream ), out_stream( outStream ) - { - VERIFY(in_stream); - VERIFY(out_stream); - }; - virtual void run() = 0; -}; - -*/ - -class net_task : public net_task_callback -{ - CDeflector* _D; - u32 _id; - light_execute _execute; - -public: - void run(); - - bool receive(IGenericStream* inStream); - bool send(IGenericStream* outStream); - - net_task(IAgent* agent, u32 session); - ~net_task(); -}; diff --git a/src/utils/xrLC_Light/net_task_callback.cpp b/src/utils/xrLC_Light/net_task_callback.cpp deleted file mode 100644 index 212c2c0d093..00000000000 --- a/src/utils/xrLC_Light/net_task_callback.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "stdafx.h" - -#include "net_task_callback.h" - -bool net_task_callback::test_connection() -{ - VERIFY(_session != u32(-1)); -#ifdef NET_CMP - _agent.TestConnection(_session); -#else - if (!break_all() && _agent.TestConnection(_session) == S_FALSE) - _beak_count--; -#endif - return !break_all(); -} diff --git a/src/utils/xrLC_Light/net_task_callback.h b/src/utils/xrLC_Light/net_task_callback.h deleted file mode 100644 index 274a101ac1b..00000000000 --- a/src/utils/xrLC_Light/net_task_callback.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _NET_TASK_CALLBACK_H_ -#define _NET_TASK_CALLBACK_H_ -#include "hxgrid/Interface/IAgent.h" - -class net_task_callback -{ - static const u16 _break_connection_times = 1; - IAgent& _agent; - u32 _session; - u16 _beak_count; - -public: - net_task_callback(IAgent* agent, u32 session) - : _agent(*agent), _session(session), _beak_count(_break_connection_times) - { - } - -public: - IC bool break_all() const { return _beak_count == 0; } - bool test_connection(); - const IAgent& agent() const { return _agent; } - IAgent& agent() { return _agent; } - u32 session() const { return _session; } -}; - -#endif diff --git a/src/utils/xrLC_Light/net_task_manager.cpp b/src/utils/xrLC_Light/net_task_manager.cpp deleted file mode 100644 index 7922919a950..00000000000 --- a/src/utils/xrLC_Light/net_task_manager.cpp +++ /dev/null @@ -1,272 +0,0 @@ -#include "stdafx.h" - -#include "net_task_manager.h" - -#include "hxgrid/Interface/IGenericStream.h" - -#include "net_stream.h" -#include "xrLC_GlobalData.h" -#include "xrDeflector.h" - -void compress(LPCSTR f_in_out); - -#ifdef NET_CMP -static xr_vector> diff; -void DumpDiff() -{ - Msg("diference: %d ", diff.size()); - xr_vector>::iterator i = diff.begin(), b = diff.begin(), e = diff.end(); - for (; i != e; ++i) - { - Msg("diff %d", u32(i - b)); - DumpDeflctor(*(*i).first); - DumpDeflctor(*(*i).second); - } -} -#endif - -net_task_manager* g_net_task_manager = 0; - -net_task_manager* get_net_task_manager() { return g_net_task_manager; } -void create_net_task_manager() { g_net_task_manager = xr_new(); } -void destroy_net_task_manager() { xr_delete(g_net_task_manager); } -net_task_manager::net_task_manager() : thProgress(0) {} -void __cdecl Finalize(IGenericStream* outStream) -{ - VERIFY(g_net_task_manager); - INetBlockReader r(outStream); - // INetReaderGenStream r(outStream); - get_net_task_manager()->receive(r); - // VERIFY(outStream->GetLength()==4+9); - // VERIFY(outStream->GetPos()==0); - - // DWORD n; - // outStream->Read(&n,4); - - // outStream->Read(&pival[n-1],9); -} - -static Lock send_receive_data_lock; -class INetFileBuffWriter; -static INetFileBuffWriter* gl_data_write = 0; -static CVirtualFileRW* g_net_data = 0; - -void net_task_manager::create_global_data_write(LPCSTR save_path) -{ - FPU::m64r(); - Memory.mem_compact(); - - clMsg("create_global_data_write: start"); -#ifdef NET_CMP - string_path fn; - strconcat(sizeof(fn), fn, save_path, "cl_global_data"); - INetReader fr(0); - fr.load_buffer(fn); - inlc_global_data()->clear(); - inlc_global_data()->read(fr); -#endif -#if !defined(NET_CMP) && !defined(LOAD_GL_DATA) - std::random_shuffle(inlc_global_data()->g_deflectors().begin(), inlc_global_data()->g_deflectors().end()); -#endif - -#ifndef LOAD_GL_DATA - // gl_data_write = new INetFileBuffWriter( "tmp_global_data", 1024*1024/2,false); - // inlc_global_data()->write( *gl_data_write ); - // gl_data_write->w_close(); - - string_path global_data_file_name; - - FS.update_path(global_data_file_name, "$app_root$", gl_data_net_file_name); - IWriter* file = FS.w_open(global_data_file_name); - inlc_global_data()->write(*file); - FS.w_close(file); - compress(global_data_file_name); - // string_path bin_path; - // FS.update_path( bin_path,"$app_root$", gl_data_net_file_name ); - - // g_net_data = new CVirtualFileRW(global_data_file_name); - - // dbg_buf = xr_malloc( 560000000, "dbg_buf" ); - //////////////// - /*{ - string_path blfile_name; - FS.update_path ( blfile_name, "$level$", "btmp_global_data" ); - - string_path blfile_name_z; - FS.update_path ( blfile_name_z, "$level$", "btmp_global_data_z" ); - - string_path blfile_name_uz; - FS.update_path ( blfile_name_uz, "$level$", "btmp_global_data_uz" ); - compress( blfile_name, blfile_name_z ); - decompress( blfile_name_z, blfile_name_uz ); - //"btmp_global_data" - } - */ - /////////////// - clMsg("create_global_data_write: end"); -#else - // gl_data_write = new INetFileBuffWriter( "tmp_global_data", 1024*1024/2,true); - // gl_data_write->w_close(); - string_path lfile_name; - FS.update_path(lfile_name, "$level$", "tmp_global_data"); - g_net_data = xr_new(lfile_name); -#endif - -// send_receive_data_lock.Leave(); - -#ifdef NET_CMP - gl_data_write->save_buffer(fn); -#endif -} - -void __cdecl GetDataCallback(const char* dataDesc, IGenericStream** stream) -{ - clMsg("GetDataCallback: send start"); - VERIFY(xr_strcmp(dataDesc, "global_data") == 0); - CTimer time; - time.Start(); - // R_ASSERT(gl_data_write); - - *stream = xr_new(g_net_data); // CreateGenericStream(); - //*stream = gl_data_write->net_stream(); - - // gl_data_write->send_not_clear(*stream); - // xr_delete( *stream ); - clMsg("GetDataCallback: send end time elapsed sec: %f, ", time.GetElapsed_sec()); - //(*stream) = new TGenericStream(20000000); - - //(*stream)->Write(globalDataStream->GetBasePointer(), globalDataStream->GetLength()); -} - -void net_task_manager::run() -{ - start_time.Start(); -#ifndef NET_CMP - - create_global_data_write(""); -#endif - // inlc_global_data()->create_read_faces(); - - IGridUser* user = CreateGridUserObject(IGridUser::VERSION); - VERIFY(user); - // user->BindGetDataCallback(GetDataCallback); - Status("Lighting..."); - -#if !defined(NET_CMP) && !defined(LOAD_GL_DATA) - VERIFY(inlc_global_data()); - u32 size = inlc_global_data()->g_deflectors().size(); - for (u32 dit = 0; dit < size; dit++) - pool.push_back(dit); -#else - pool.push_back(0); - pool.push_back(1); -#endif - - FPU::m64r(); - Memory.mem_compact(); -#if !defined(NET_CMP) && !defined(LOAD_GL_DATA) - for (u32 dit = 0; dit < size; dit++) - send(*user, dit); - user->WaitForCompletion(); - // gl_data_write->clear(); - // xr_delete(gl_data_write); - xr_delete(g_net_data); -#else - send(*user, 0); - send(*user, 1); - user->WaitForCompletion(); - xr_delete(g_net_data); -#endif - - // inlc_global_data()->destroy_read_faces(); - - user->Release(); -#ifdef NET_CMP - DumpDiff(); -#endif - clMsg("%f net lightmaps seconds", start_time.GetElapsed_sec()); -} - -//#ifdef _DEBUG -// LPCSTR libraries = -// "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,DXT.dll,BugTrapD.dll,msvcr80.dll,Microsoft.VC80.CRT.manifest,tmp_global_data0,tmp_global_data1,tmp_global_data2,tmp_global_data3,tmp_global_data4,tmp_global_data5"; -//#else -// LPCSTR libraries = -// "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,DXT.dll,BugTrap.dll,msvcr80.dll,Microsoft.VC80.CRT.manifest,tmp_global_data0,tmp_global_data1,tmp_global_data2,tmp_global_data3,tmp_global_data4,tmp_global_data5"; -//#endif - -void send_lightmap_task(IGridUser& user, u32 deflector_id) {} -void net_task_manager::send(IGridUser& user, u32 deflector_id) -{ - clMsg("send task : %d", deflector_id); - // send_receive_data_lock.Enter(); - IGenericStream* stream = CreateGenericStream(); - { - INetMemoryBuffWriter w(stream, 100); - // INetIWriterGenStream w( stream, 100 ); - w.w_u32(deflector_id); - } - - u32 t_id = deflector_id; - string_path data; - strconcat(sizeof(data), data, libraries, ",", gl_data_net_file_name); - user.RunTask(data, "RunTask", stream, Finalize, &t_id, true); - -#ifndef LOAD_GL_DATA - DumpDeflctor(deflector_id); -#endif - // send_receive_data_lock.Leave(); -} -void net_task_manager::receive(INetReader& r) -{ -#ifdef LOAD_GL_DATA - return; -#endif - send_receive_data_lock.Enter(); - u32 id = r.r_u32(); - xr_vector::iterator it = std::find(pool.begin(), pool.end(), id); - if (it == pool.end()) - { - send_receive_data_lock.Leave(); - // CDeflector temp; - // temp.read( r ); - return; - } - pool.erase(it); - u32 pool_size = pool.size(); - send_receive_data_lock.Leave(); - - VERIFY(inlc_global_data()); -// inlc_global_data()->create_read_faces(); -#ifdef NET_CMP - CDeflector* netD = xr_new(); - CDeflector* D = inlc_global_data()->g_deflectors()[id]; - netD->read(r); - if (!netD->similar(*D)) - { - send_receive_data_lock.Enter(); - diff.push_back(std::pair(D, netD)); - send_receive_data_lock.Leave(); - } - else - xr_delete(netD); -#else - inlc_global_data()->g_deflectors()[id]->read(r); -#endif - // inlc_global_data()->destroy_read_faces(); - - u32 size = inlc_global_data()->g_deflectors().size(); - - clMsg("received task : %d", id); - DumpDeflctor(id); - - VERIFY(size > 0); - // thProgress+=(1.f/size); - Progress(1.f - float(pool.size()) / float(size)); - clMsg("num task complited : %d , num task left %d (task num %d)", size - pool_size, pool_size, size); - if (pool.empty()) - { - clMsg("calculation complited"); - clMsg("%f net lightmaps calculation seconds", start_time.GetElapsed_sec()); - } -} diff --git a/src/utils/xrLC_Light/net_task_manager.h b/src/utils/xrLC_Light/net_task_manager.h deleted file mode 100644 index 9c67d72bd55..00000000000 --- a/src/utils/xrLC_Light/net_task_manager.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" -// interface IGridUser; -class INetReader; -class XRLC_LIGHT_API net_task_manager -{ - friend void Finalize(IGenericStream* outStream); - xr_vector pool; - CTimer start_time; - float thProgress; - void send(IGridUser& user, u32 id); - void receive(INetReader& r); - -public: - net_task_manager(); - void run(); - void create_global_data_write(LPCSTR save_path); -}; - -XRLC_LIGHT_API net_task_manager* get_net_task_manager(); -XRLC_LIGHT_API void create_net_task_manager(); -XRLC_LIGHT_API void destroy_net_task_manager(); diff --git a/src/utils/xrLC_Light/net_task_menager.cpp b/src/utils/xrLC_Light/net_task_menager.cpp deleted file mode 100644 index 2809a44daa7..00000000000 --- a/src/utils/xrLC_Light/net_task_menager.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "stdafx.h" - -#include "net_task_menager.h" - -#include "hxgrid/Interface/IGenericStream.h" - -#include "net_stream.h" -#include "xrLC_GlobalData.h" -#include "xrDeflector.h" - -net_task_menager* g_net_task_menager = 0; - -net_task_menager* get_net_task_menager() { return g_net_task_menager; } -void create_net_task_menager() { g_net_task_menager = xr_new(); } -void destroy_net_task_menager() { xr_delete(g_net_task_menager); } -net_task_menager::net_task_menager() : thProgress(0) {} -void __cdecl Finalize(IGenericStream* outStream) -{ - VERIFY(g_net_task_menager); - INetReader r(outStream); - get_net_task_menager()->receive(r); - // VERIFY(outStream->GetLength()==4+9); - // VERIFY(outStream->GetPos()==0); - - // DWORD n; - // outStream->Read(&n,4); - - // outStream->Read(&pival[n-1],9); -} - -static xrCriticalSection send_receive_data_lock; - -static INetWriter* gl_data_write = 0; -void create_global_data_write() -{ - clMsg("create_global_data_write: start"); - - gl_data_write = xr_new((IGenericStream*)(0), u32(-1)); - // INetWriter w( *stream, u32(-1) ); - // send_receive_data_lock.Enter(); - inlc_global_data()->write(*gl_data_write); - // send_receive_data_lock.Leave(); - clMsg("create_global_data_write: end, size %d", gl_data_write->count()); -} - -void __cdecl GetDataCallback(const char* dataDesc, IGenericStream** stream) -{ - clMsg("GetDataCallback: send start"); - VERIFY(xr_strcmp(dataDesc, "global_data") == 0); - CTimer time; - time.Start(); - R_ASSERT(gl_data_write); - *stream = CreateGenericStream(); - //*stream = gl_data_write->net_stream(); - gl_data_write->send_not_clear(*stream); - //*stream->Release(); - clMsg("GetDataCallback: send end time elapsed sec: %f, ", time.GetElapsed_sec()); - //(*stream) = new TGenericStream(20000000); - - //(*stream)->Write(globalDataStream->GetBasePointer(), globalDataStream->GetLength()); -} - -void net_task_menager::run() -{ - start_time.Start(); - create_global_data_write(); - inlc_global_data()->create_read_faces(); - - IGridUser* user = CreateGridUserObject(IGridUser::VERSION); - VERIFY(user); - user->BindGetDataCallback(GetDataCallback); - Status("Lighting..."); - - VERIFY(inlc_global_data()); - u32 size = inlc_global_data()->g_deflectors().size(); - - std::random_shuffle(inlc_global_data()->g_deflectors().begin(), inlc_global_data()->g_deflectors().end()); - for (u32 dit = 0; dit < size; dit++) - pool.push_back(dit); - - FPU::m64r(); - Memory.mem_compact(); - - for (u32 dit = 0; dit < size; dit++) - send(*user, dit); - - user->WaitForCompletion(); - - gl_data_write->clear(); - xr_delete(gl_data_write); - inlc_global_data()->destroy_read_faces(); - - user->Release(); - clMsg("%f net lightmaps seconds", start_time.GetElapsed_sec()); -} - -#ifdef _DEBUG -LPCSTR libraries = - "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,DXT.dll,BugTrapD.dll,msvcr80.dll,Microsoft.VC80.CRT." - "manifest"; -#else -LPCSTR libraries = - "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,DXT.dll,BugTrap.dll,msvcr80.dll,Microsoft.VC80.CRT." - "manifest"; -#endif - -void net_task_menager::send(IGridUser& user, u32 id) -{ - // send_receive_data_lock.Enter(); - IGenericStream* stream = CreateGenericStream(); - { - INetWriter w(stream, 100); - w.w_u32(id); - } - u32 t_id = id; - - user.RunTask(libraries, "RunTask", stream, Finalize, &t_id, true); - - clMsg("send task : %d", id); - DumpDeflctor(id); - // send_receive_data_lock.Leave(); -} -void net_task_menager::receive(INetReader& r) -{ - send_receive_data_lock.Enter(); - u32 id = r.r_u32(); - xr_vector::iterator it = std::find(pool.begin(), pool.end(), id); - if (it == pool.end()) - return; - pool.erase(it); - u32 pool_size = pool.size(); - send_receive_data_lock.Leave(); - - VERIFY(inlc_global_data()); - // inlc_global_data()->create_read_faces(); - inlc_global_data()->g_deflectors()[id]->read(r); - // inlc_global_data()->destroy_read_faces(); - - u32 size = inlc_global_data()->g_deflectors().size(); - - clMsg("received task : %d", id); - DumpDeflctor(id); - - VERIFY(size > 0); - // thProgress+=(1.f/size); - Progress(1.f - float(pool.size()) / float(size)); - clMsg("num task complited : %d , num task left %d (task num %d)", size - pool_size, pool_size, size); - if (pool.empty()) - { - clMsg("calculation complited"); - clMsg("%f net lightmaps calculation seconds", start_time.GetElapsed_sec()); - } -} diff --git a/src/utils/xrLC_Light/net_task_menager.h b/src/utils/xrLC_Light/net_task_menager.h deleted file mode 100644 index 1f4c8ceccb5..00000000000 --- a/src/utils/xrLC_Light/net_task_menager.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "hxgrid/Interface/IAgent.h" -#include "hxgrid/Interface/hxgridinterface.h" -// interface IGridUser; -class INetReader; -class XRLC_LIGHT_API net_task_menager -{ - friend void Finalize(IGenericStream* outStream); - xr_vector pool; - CTimer start_time; - float thProgress; - void send(IGridUser& user, u32 id); - void receive(INetReader& r); - -public: - net_task_menager(); - void run(); -}; - -XRLC_LIGHT_API net_task_menager* get_net_task_menager(); -XRLC_LIGHT_API void create_net_task_menager(); -XRLC_LIGHT_API void destroy_net_task_menager(); diff --git a/src/utils/xrLC_Light/packages.config b/src/utils/xrLC_Light/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/xrLC_Light/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/xrLC_Light/recalculation.cpp b/src/utils/xrLC_Light/recalculation.cpp deleted file mode 100644 index 72159c5f31c..00000000000 --- a/src/utils/xrLC_Light/recalculation.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "stdafx.h" - -#include "recalculation.h" -#include "serialize.h" - -void recalculation::load_calculation_params() -{ - IReader* R = FS.r_open("$level$", "do_light.ltx"); - - if (!R) - partial_calculate = false; - else - { - CInifile ini(R); - if (!ini.section_exist("calculation")) - partial_calculate = false; - else - { - partial_calculate = !!ini.r_bool("calculation", "calculate_rect"); - force_recalculate = !!ini.r_bool("calculation", "force_recalculate"); - Fvector2 center_rect = ini.r_fvector2("calculation", "center"); - float radius = ini.r_float("calculation", "radius"); - calculation_rect.lt = center_rect; - calculation_rect.rb = center_rect; - calculation_rect.grow(radius, radius); - } - FS.r_close(R); - } -} - -void recalculation::setup_recalculationflags_file(u32 check_sum) -{ - IWriter* W = FS.w_open("$level$", "recalculation_data_slots.details"); - W->w_chunk(0, &check_sum, sizeof(check_sum)); - // u32 buff_size = dtH.slot_index( dtH.x_size(), dtH.z_size() ) * sizeof( slots_flags[0] ); - u32 buff_size = dtH.slot_count() * sizeof(slots_flags[0]); - void* buff = xr_alloca(buff_size); - memset(buff, 0, buff_size); - W->w_chunk(1, buff, buff_size); - FS.w_close(W); -} - -void recalculation::check_files(u32 check_sum) -{ - string_path N, L; - FS.update_path(L, "$level$", "level.details"); - FS.update_path(N, "$level$", "recalculation_data_slots.details"); - if (!FS.exist(L)) - { - FS.file_delete(N); - return; - } - - IReader* R = FS.r_open("$level$", "recalculation_data_slots.details"); - if (R) - { - u32 check; - R->r_chunk(0, &check); - if (check != check_sum) - FS.file_delete(N); - else - recalculate = true; - - FS.r_close(R); - } -} - -void recalculation::check_load(u32 check_sum) -{ - check_files(check_sum); - string_path N; - FS.update_path(N, "$level$", "recalculation_data_slots.details"); - if (!FS.exist(N)) - setup_recalculationflags_file(check_sum); -} - -void recalculation::load(u32 check_sum) -{ - load_calculation_params(); - - check_load(check_sum); - - string_path N; - FS.update_path(N, "$level$", "recalculation_data_slots.details"); - - dtFS = xr_new(N); - dtFS->find_chunk(1); - slots_flags = (u8*)dtFS->pointer(); -} - -void recalculation::close() -{ - if (dtFS) - xr_delete(dtFS); -} - -// const DetailHeader &dtH; -// u8 *slots_flags; -// CVirtualFileRW *dtFS; - -// Frect calculation_rect; -// bool recalculate; -// bool partial_calculate; -// bool force_recalculate; -void recalculation::read(INetReader& r) -{ - R_ASSERT(!slots_flags); - R_ASSERT(dtH.version() != u32(-1)); - R_ASSERT(dtH.x_size() != u32(-1)); - R_ASSERT(dtH.z_size() != u32(-1)); - - u32 buff_size = dtH.slot_count() * sizeof(slots_flags[0]); - slots_flags = (u8*)xr_malloc(buff_size); - - r.r(slots_flags, dtH.slot_count()); - r_pod(r, calculation_rect); - - r_pod(r, recalculate); - r_pod(r, partial_calculate); - r_pod(r, force_recalculate); -} -void recalculation::write(IWriter& w) const -{ - u32 buff_size = dtH.slot_count() * sizeof(slots_flags[0]); - w.w(slots_flags, buff_size); - w_pod(w, calculation_rect); - - w_pod(w, recalculate); - w_pod(w, partial_calculate); - w_pod(w, force_recalculate); -} diff --git a/src/utils/xrLC_Light/recalculation.h b/src/utils/xrLC_Light/recalculation.h deleted file mode 100644 index d22192b1272..00000000000 --- a/src/utils/xrLC_Light/recalculation.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __RECALCULATION_PARAMS_H__ -#define __RECALCULATION_PARAMS_H__ - -#include "Layers/xrRender/DetailFormat.h" -class INetReader; -class CVirtualFileRW; -class recalculation -{ - const DetailHeader& dtH; - u8* slots_flags; - CVirtualFileRW* dtFS; - - Frect calculation_rect; - bool recalculate; - bool partial_calculate; - bool force_recalculate; - -public: - recalculation(const DetailHeader& _dtH) - : dtH(_dtH), calculation_rect(Frect().invalidate()), recalculate(false), partial_calculate(false), - force_recalculate(false), dtFS(0), slots_flags(0) - { - } // - IC bool recalculating() const { return recalculate; } - IC bool skip_slot(int x, int z) const - { - if (partial_calculate) - { - Frect srect; - dtH.GetSlotRect(srect, x, z); - if (!calculation_rect.intersected(srect)) - return true; - } - if (!recalculating() || force_recalculate) - return false; - return !!slots_flags[dtH.slot_index(x, z)]; - } - - IC void set_slot_calculated(u32 idx) - { - VERIFY(idx < dtH.slot_count()); - slots_flags[idx] = u8(1); - } - - IC void set_slot_calculated(int x, int z) - { - // slots_flags[dtH.slot_index( x, z )] = u8(1); - set_slot_calculated(dtH.slot_index(x, z)); - } - void load(u32 check_sum); - void close(); - void read(INetReader& r); - void write(IWriter& w) const; - -private: - void load_calculation_params(); - void setup_recalculationflags_file(u32 check_sum); - void check_load(u32 check_sum); - void check_files(u32 check_sum); -}; - -#endif //__RECALCULATION_PARAMS_H__ diff --git a/src/utils/xrLC_Light/ref_model_net_global_data.cpp b/src/utils/xrLC_Light/ref_model_net_global_data.cpp deleted file mode 100644 index a2dddccf38c..00000000000 --- a/src/utils/xrLC_Light/ref_model_net_global_data.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "stdafx.h" -#include "ref_model_net_global_data.h" - -#include "xrlc_globaldata.h" -#include "file_compress.h" - -namespace lc_net -{ -void net_global_data_impl::create_data_file(LPCSTR path) -{ - FPU::m64r(); - Memory.mem_compact(); - Logger.clMsg("create_ref_model_data_write: start"); - IWriter* file = FS.w_open(path); - inlc_global_data()->write_mu_model_refs(*file); - inlc_global_data()->write_modes_color(*file); - FS.w_close(file); - compress(path); - Logger.clMsg("create_ref_model_data_write: end"); -} -bool net_global_data_impl::create_data(LPCSTR path) -{ - { - R_ASSERT(inlc_global_data()); - decompress(path); - INetReaderFile r_global(path); - inlc_global_data()->read_mu_model_refs(r_global); - inlc_global_data()->read_modes_color(r_global); - } - // xr_unlink( fn ); - FPU::m64r(); - Memory.mem_compact(); - return true; -} -} diff --git a/src/utils/xrLC_Light/ref_model_net_global_data.h b/src/utils/xrLC_Light/ref_model_net_global_data.h deleted file mode 100644 index 9440e143131..00000000000 --- a/src/utils/xrLC_Light/ref_model_net_global_data.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _REF_MODEL_NET_GLOBAL_DATA_H_ -#define _REF_MODEL_NET_GLOBAL_DATA_H_ -#include "net_global_data.h" - -namespace lc_net -{ -template <> -class net_global_data_impl -{ -public: - void init() { data_init(); } -protected: - void create_data_file(LPCSTR path); - bool create_data(LPCSTR path); - void destroy_data(){}; - LPCSTR file_name() { return "gl_ref_model_data"; } - virtual void data_init() = 0 {}; - virtual void data_cleanup() = 0 {}; -}; - -template <> -struct global_add_global -{ -}; -} - -#endif diff --git a/src/utils/xrLC_Light/serialize.cpp b/src/utils/xrLC_Light/serialize.cpp deleted file mode 100644 index 2c651df5647..00000000000 --- a/src/utils/xrLC_Light/serialize.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "stdafx.h" - -#include "serialize.h" - -void write(IWriter& w, const b_texture& b) -{ - w.w_string(b.name); - w.w_u32(b.dwWidth); - w.w_u32(b.dwHeight); - w.w_s32(b.bHasAlpha); - - bool b_surface = !!b.pSurface; - w.w_u8(u8(b_surface)); - if (b_surface) - { - u32 size = sizeof(u32) * b.dwWidth * b.dwHeight; - w.w(b.pSurface, size); - } -} -void read(INetReader& r, b_texture& b) -{ - r.r_string(b.name, sizeof(b.name)); - b.dwWidth = r.r_u32(); - b.dwHeight = r.r_u32(); - b.bHasAlpha = r.r_s32(); - - b.pSurface = NULL; - bool b_surface = !!r.r_u8(); - if (b_surface) - { - u32 size = sizeof(u32) * b.dwWidth * b.dwHeight; - b.pSurface = (u32*)xr_malloc(size); - r.r(b.pSurface, size); - } -} diff --git a/src/utils/xrLC_Light/serialize.h b/src/utils/xrLC_Light/serialize.h deleted file mode 100644 index 83536e391da..00000000000 --- a/src/utils/xrLC_Light/serialize.h +++ /dev/null @@ -1,282 +0,0 @@ -#pragma once - -#include "net_stream.h" -#include "xrCore/_sphere.h" - -template -void r_pod_vector(INetReader& r, xr_vector& v) -{ - u32 cnt = r.r_u32(); - v.resize(cnt); - r.r(&*v.begin(), cnt * sizeof(T)); -} - -template -void w_pod_vector(IWriter& w, const xr_vector& v) -{ - u32 cnt = v.size(); - w.w_u32(cnt); - w.w(&*v.begin(), cnt * sizeof(T)); -} - -template -void r_pod(INetReader& r, T& v) -{ - r.r(&v, sizeof(T)); -} - -template -void w_pod(IWriter& w, const T& v) -{ - w.w(&v, sizeof(T)); -} - -template -void r_vector(INetReader& r, xr_vector& v) -{ - u32 cnt = r.r_u32(); - v.resize(cnt); - typename xr_vector::iterator i = v.begin(), e = v.end(); - for (; i != e; ++i) - i->read(r); -} - -template -void w_vector(IWriter& w, const xr_vector& v) -{ - u32 cnt = v.size(); - w.w_u32(cnt); - typename xr_vector::const_iterator i = v.cbegin(), e = v.cend(); - for (; i != e; ++i) - i->write(w); -} -template -void r_pointer(INetReader& r, T*& p, xr_vector& storage) -{ - u32 id = r.r_u32(); - R_ASSERT(id < storage.size()); - p = &storage[id]; -} - -template -void w_pointer(IWriter& w, const T* p, const xr_vector& storage) -{ - u32 size = storage.size(); - for (u32 i = 0; i < size; ++i) - if (p == &storage[i]) - { - w.w_u32(i); - return; - } - R_ASSERT2(false, "is not point on the storage"); -} - -template -void r_vector(INetReader& r, svector& v) -{ - u32 cnt = r.r_u32(); - v.resize(cnt); - typename svector::iterator i = v.begin(), e = v.end(); - for (; i != e; ++i) - i->read(r); -} - -template -void w_vector(IWriter& w, const svector& v) -{ - u32 cnt = v.size(); - w.w_u32(cnt); - typename svector::const_iterator i = v.cbegin(), e = v.cend(); - for (; i != e; ++i) - i->write(w); -} - -static void w_sphere(IWriter& w, const Fsphere& v) { w.w(&v, sizeof(Fsphere)); } -static void r_sphere(INetReader& r, Fsphere& v) { r.r(&v, sizeof(Fsphere)); } -template -class get_id_standart -{ - static const u32 id_none = u32(-1); - -public: - static void preset(const xr_vector& vec) {} - static u32 get_id(const type* f, const xr_vector& vec) - { - if (f == 0) - return id_none; - const auto F = std::find(vec.cbegin(), vec.cend(), f); - VERIFY(F != vec.end()); - return u32(F - vec.begin()); - } -}; - -template -class get_id_self_index -{ - static const u32 id_none = u32(-1); - -public: - static void preset(const xr_vector& vec) - { - const u32 number = vec.size(); - for (u32 i = 0; i < number; ++i) - vec[i]->set_index(i); - } - static u32 get_id(const type* f, const xr_vector& vec) - { - if (f == 0) - return id_none; //?? - u32 idx = f->self_index(); - VERIFY(vec[idx] == f); - return idx; - } -}; - -template -class vector_serialize; - -template -class t_write -{ -public: - typedef T type; - -private: - typedef get_id_type id_type; - typedef vector_serialize> t_serialize; - friend class t_serialize; - const xr_vector& vec; - - void write(IWriter& w) const - { - w.w_u32(vec.size()); - typename xr_vector::const_iterator i = vec.cbegin(), e = vec.cend(); - for (; i != e; ++i) - (*i)->write(w); - } - - void write(IWriter& w, const T* f) const - { - u32 id = t_serialize::get_id(f, vec); - - w.w_u32(id); - } - - void write_ref(IWriter& w, const xr_vector& ref_vec) const - { - w.w_u32(ref_vec.size()); - typename xr_vector::const_iterator i = ref_vec.cbegin(), e = ref_vec.cend(); - for (; i != e; ++i) - write(w, *i); - } - - t_write(const xr_vector& _vec) : vec(_vec) - { - // xr_vector::const_iterator i = vec.begin(), e = vec.end(); - // std::sort(i, e); - } -}; - -template -class t_read -{ -public: - typedef T type; - -private: - typedef vector_serialize> t_serialize; - typedef get_id_type id_type; - friend class t_serialize; - xr_vector& vec; - - void read(INetReader& r) - { - vec.resize(r.r_u32(), 0); - // xr_vector::iterator i = vec.begin(), e = vec.end(); - for (u32 i = 0; i < vec.size(); ++i) - { - vec[i] = T::read_create(); - vec[i]->read(r); - } - } - void read(INetReader& r, T*& f) const - { - VERIFY(!f); - u32 id = r.r_u32(); - if (id == t_serialize::id_none) - return; - f = vec[id]; - } - - void read_ref(INetReader& r, xr_vector& ref_vec) const - { - ref_vec.resize(r.r_u32(), 0); - // xr_vector::iterator i = ref_vec.begin(), e = ref_vec.end(); - for (u32 i = 0; i < ref_vec.size(); ++i) - read(r, ref_vec[i]); - } - - t_read(xr_vector& _vec) : vec(_vec) - { - //_vec.clear(); - } -}; - -template -class vector_serialize -{ - typedef typename action::type type; - typedef typename action::id_type id_type; - action serialize; - -public: - static const u32 id_none = u32(-1); - -public: - vector_serialize(xr_vector* _vec) : serialize(*_vec) {} - vector_serialize(const xr_vector* _vec) : serialize(*_vec) {} - static u32 get_id(const type* f, const xr_vector& vec) - { - return id_type::get_id(f, vec); - // if( f == 0 ) - // return id_none; - // xr_vector::const_iterator F = std::find( vec.begin(), vec.end(), f ); - // VERIFY( F != vec.end() ); - // return u32( F - vec.begin() ); - } - - void read(INetReader& r) - { - serialize.read(r); - id_type::preset(serialize.vec); - } - void write(IWriter& w) const - { - id_type::preset(serialize.vec); - serialize.write(w); - } - void read(INetReader& r, type*& f) const { serialize.read(r, f); } - void write(IWriter& w, const type* f) const { serialize.write(w, f); } - void read_ref(INetReader& r, xr_vector& ref_vec) const { serialize.read_ref(r, ref_vec); } - void write_ref(IWriter& w, const xr_vector& ref_vec) const { serialize.write_ref(w, ref_vec); } -}; - -void write(IWriter& w, const b_texture& b); -void read(INetReader& r, b_texture& b); - -IC void write_task_id(IGenericStream* stream, u32 id) { stream->Write(&id, sizeof(id)); } -IC void read_task_id(IGenericStream* stream, u32& id) { stream->Read(&id, sizeof(u32)); } -IC void write_task_type(IGenericStream* stream, u32 type) { stream->Write(&type, sizeof(u32)); } -IC void read_task_type(IGenericStream* stream, u32& type) { stream->Read(&type, sizeof(u32)); } -IC void read_task_pool(IGenericStream* stream, u8& pool_id) { stream->Read(&pool_id, sizeof(u8)); } -IC void write_task_pool(IGenericStream* stream, u8 pool_id) { stream->Write(&pool_id, sizeof(pool_id)); } -IC void write_task_caption(IGenericStream* stream, u32 id, u32 type) -{ - write_task_id(stream, id); - write_task_type(stream, type); -} -IC void read_task_caption(IGenericStream* stream, u32& id, u32& type) -{ - read_task_id(stream, id); - read_task_type(stream, type); -} diff --git a/src/utils/xrLC_Light/stdafx.cpp b/src/utils/xrLC_Light/stdafx.cpp deleted file mode 100644 index c9cd8f0a45f..00000000000 --- a/src/utils/xrLC_Light/stdafx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stdafx.h" -#include "xrCore/cdecl_cast.hpp" -#include "utils/xrLCUtil/LevelCompilerLoggerWindow.hpp" - -ILevelCompilerLogger& Logger = LevelCompilerLoggerWindow::instance(); - -CThread::LogFunc ProxyMsg = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.clMsgV(format, args); - va_end(args); -}); - -CThreadManager::ReportStatusFunc ProxyStatus = cdecl_cast([](const char* format, ...) { - va_list args; - va_start(args, format); - Logger.StatusV(format, args); - va_end(args); -}); - -CThreadManager::ReportProgressFunc ProxyProgress = cdecl_cast([](float progress) { Logger.Progress(progress); }); diff --git a/src/utils/xrLC_Light/stdafx.h b/src/utils/xrLC_Light/stdafx.h deleted file mode 100644 index d73936d6cb7..00000000000 --- a/src/utils/xrLC_Light/stdafx.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" - -//#define COLLECT_EXECUTION_STATS - -#pragma warning(disable : 4661) -#include "xrLC_Light.h" - -#include "utils/xrLCUtil/ILevelCompilerLogger.hpp" -#include "utils/xrLCUtil/xrThread.hpp" - -#define NUM_THREADS 8 - -#include "xrCore/cdecl_cast.hpp" -#include "xrCore/_std_extensions.h" - -extern ILevelCompilerLogger& Logger; -extern CThread::LogFunc ProxyMsg; -extern CThreadManager::ReportStatusFunc ProxyStatus; -extern CThreadManager::ReportProgressFunc ProxyProgress; - -#ifdef DEBUG -#define CL_NET_LOG -#endif diff --git a/src/utils/xrLC_Light/tcf.cpp b/src/utils/xrLC_Light/tcf.cpp deleted file mode 100644 index 52ad4746b92..00000000000 --- a/src/utils/xrLC_Light/tcf.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "stdafx.h" -#include "tcf.h" -#include "net_stream.h" -void _TCF::barycentric(Fvector2& P, float& u, float& v, float& w) -{ - Fvector2 kV02; - kV02.sub(uv[0], uv[2]); - Fvector2 kV12; - kV12.sub(uv[1], uv[2]); - Fvector2 kPV2; - kPV2.sub(P, uv[2]); - - float fM00 = kV02.dot(kV02); - float fM01 = kV02.dot(kV12); - float fM11 = kV12.dot(kV12); - float fR0 = kV02.dot(kPV2); - float fR1 = kV12.dot(kPV2); - float fDet = fM00 * fM11 - fM01 * fM01; - - u = (fM11 * fR0 - fM01 * fR1) / fDet; - v = (fM00 * fR1 - fM01 * fR0) / fDet; - w = 1.0f - u - v; -} -// Fvector2 uv [3]; -void _TCF::read(INetReader& r) { r.r(uv, sizeof(uv)); } -void _TCF::write(IWriter& w) const { w.w(uv, sizeof(uv)); } -bool _TCF::similar(const _TCF& _tc, float eps /*= EPS*/) const -{ - return uv[0].similar(_tc.uv[0], eps) && uv[1].similar(_tc.uv[1], eps) && uv[2].similar(_tc.uv[2], eps); -} diff --git a/src/utils/xrLC_Light/tcf.h b/src/utils/xrLC_Light/tcf.h deleted file mode 100644 index 3d337ea377b..00000000000 --- a/src/utils/xrLC_Light/tcf.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -class INetReader; -struct XRLC_LIGHT_API _TCF -{ - Fvector2 uv[3]; - - void barycentric(Fvector2& P, float& u, float& v, float& w); - IC void barycentric(Fvector2& P, Fvector& B) { barycentric(P, B.x, B.y, B.z); } - IC bool isInside(float u, float v, float w) - { - return (u >= 0 && u <= 1) && (v >= 0 && v <= 1) && (w >= 0 && w <= 1); - } - IC bool isInside(Fvector& B) { return isInside(B.x, B.y, B.z); } - IC bool isInside(Fvector2& P, Fvector& B) - { - barycentric(P, B); - return isInside(B); - } - void read(INetReader& r); - void write(IWriter& w) const; - bool similar(const _TCF& _tc, float eps = EPS) const; -}; diff --git a/src/utils/xrLC_Light/uv_tri.cpp b/src/utils/xrLC_Light/uv_tri.cpp deleted file mode 100644 index d8d7322b040..00000000000 --- a/src/utils/xrLC_Light/uv_tri.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "stdafx.h" - -#include "uv_tri.h" -#include "xrface.h" - -void UVtri::read(INetReader& r) -{ - _TCF::read(r); - VERIFY(read_faces); - owner = 0; - read_faces->read(r, owner); -} -void UVtri::write(IWriter& w) const -{ - _TCF::write(w); - VERIFY(owner); - VERIFY(write_faces); - write_faces->write(w, owner); -} - -bool UVtri::similar(const UVtri& uv, float eps /*eps = EPS*/) const -{ - return uv.owner == owner && _TCF::similar(uv, eps); -} diff --git a/src/utils/xrLC_Light/uv_tri.h b/src/utils/xrLC_Light/uv_tri.h deleted file mode 100644 index a2225c442aa..00000000000 --- a/src/utils/xrLC_Light/uv_tri.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "xrfacedefs.h" -#include "tcf.h" - -struct XRLC_LIGHT_API UVtri : public _TCF -{ - Face* owner; - void read(INetReader& r); - void write(IWriter& w) const; - bool similar(const UVtri& uv, float eps = EPS) const; -}; diff --git a/src/utils/xrLC_Light/vector_clear.h b/src/utils/xrLC_Light/vector_clear.h deleted file mode 100644 index 928ff9e89bd..00000000000 --- a/src/utils/xrLC_Light/vector_clear.h +++ /dev/null @@ -1,24 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 09.04.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef VECTOR_CLEAR_H_INCLUDED -#define VECTOR_CLEAR_H_INCLUDED - -template -void vec_value_destruct(xr_vector& v, TDestruct& destruct) -{ - typename xr_vector::iterator i = v.begin(), e = v.end(); - for (; i != e; ++i) - destruct.destruct(*i); -} -template -void vec_clear(xr_vector& v, TDestruct& destruct) -{ - vec_value_destruct(v, destruct); - v.clear(); -} - -#endif // #ifndef VECTOR_CLEAR_H_INCLUDED diff --git a/src/utils/xrLC_Light/xrDXTC.h b/src/utils/xrLC_Light/xrDXTC.h deleted file mode 100644 index c4ece670f21..00000000000 --- a/src/utils/xrLC_Light/xrDXTC.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Common/Platform.hpp" - -#ifdef XRAY_STATIC_BUILD -#define DXTC_API -#else -# ifdef XRDXTC_EXPORTS -# define DXTC_API XR_EXPORT -# else -# define DXTC_API XR_IMPORT -# endif -#endif - -enum eDXTC -{ - eDXT1 = 1, - eDXT3 = 3, - eDXT5 = 5 -}; - -extern "C" { -// Returns TRUE only if everything OK. -DXTC_API BOOL __cdecl xrDXTC_Compress(const char* dest_file, u32 dest_format, BOOL dest_mipmaps, u32* src_data, - u32 dwWidth, u32 dwHeight, u32 dxt1_alpharef = 0xff); -}; diff --git a/src/utils/xrLC_Light/xrDeflectoL_Direct.cpp b/src/utils/xrLC_Light/xrDeflectoL_Direct.cpp deleted file mode 100644 index a6cb7fb87bd..00000000000 --- a/src/utils/xrLC_Light/xrDeflectoL_Direct.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "stdafx.h" - -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrdeflector.h" -#include "xrlc_globaldata.h" -#include "light_point.h" -#include "xrface.h" -#include "net_task.h" -extern void Jitter_Select(Fvector2*& Jitter, u32& Jcount); - -void CDeflector::L_Direct_Edge(CDB::COLLIDER* DB, base_lighting* LightsSelected, Fvector2& p1, Fvector2& p2, - Fvector& v1, Fvector& v2, Fvector& N, float texel_size, Face* skip) -{ - Fvector vdir; - vdir.sub(v2, v1); - - lm_layer& lm = layer; - - Fvector2 size; - size.x = p2.x - p1.x; - size.y = p2.y - p1.y; - int du = iCeil(_abs(size.x) / texel_size); - int dv = iCeil(_abs(size.y) / texel_size); - int steps = _max(du, dv); - if (steps <= 0) - return; - - for (int I = 0; I <= steps; I++) - { - float time = float(I) / float(steps); - Fvector2 uv; - uv.x = size.x * time + p1.x; - uv.y = size.y * time + p1.y; - int _x = iFloor(uv.x * float(lm.width)); - int _y = iFloor(uv.y * float(lm.height)); - - if ((_x < 0) || (_x >= (int)lm.width)) - continue; - if ((_y < 0) || (_y >= (int)lm.height)) - continue; - - if (lm.marker[_y * lm.width + _x]) - continue; - - // ok - perform lighting - base_color_c C; - Fvector P; - P.mad(v1, vdir, time); - VERIFY(inlc_global_data()); - VERIFY(inlc_global_data()->RCAST_Model()); - - LightPoint(DB, 0, inlc_global_data()->RCAST_Model(), C, P, N, *LightsSelected, - (inlc_global_data()->b_nosun() ? LP_dont_sun : 0) | LP_DEFAULT, skip); //. - - C.mul(.5f); - lm.surface[_y * lm.width + _x]._set(C); - lm.marker[_y * lm.width + _x] = 255; - } -} - -void CDeflector::L_Direct(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H) -{ - R_ASSERT(DB); - R_ASSERT(LightsSelected); - - lm_layer& lm = layer; - - // Setup variables - Fvector2 dim, half; - dim.set(float(lm.width), float(lm.height)); - half.set(.5f / dim.x, .5f / dim.y); - - // Jitter data - Fvector2 JS; - JS.set(.4999f / dim.x, .4999f / dim.y); - - u32 Jcount; - Fvector2* Jitter; - Jitter_Select(Jitter, Jcount); - - // Lighting itself - for (u32 V = 0; V < lm.height; V++) - { - if (_net_session && !_net_session->test_connection()) - return; - for (u32 U = 0; U < lm.width; U++) - { -#ifdef NET_CMP - if (V * lm.width + U != 8335) - continue; -#endif - u32 Fcount = 0; - base_color_c C; - try - { - for (u32 J = 0; J < Jcount; J++) - { - // LUMEL space - Fvector2 P; - P.x = float(U) / dim.x + half.x + Jitter[J].x * JS.x; - P.y = float(V) / dim.y + half.y + Jitter[J].y * JS.y; - - xr_vector& space = H.query(P.x, P.y); - - // World space - Fvector wP, wN, B; - for (UVtri** it = &*space.begin(); it != &*space.end(); it++) - { - if ((*it)->isInside(P, B)) - { - // We found triangle and have barycentric coords - Face* F = (*it)->owner; - Vertex* V1 = F->v[0]; - Vertex* V2 = F->v[1]; - Vertex* V3 = F->v[2]; - wP.from_bary(V1->P, V2->P, V3->P, B); - //. не нужно использовать if (F->Shader().flags.bLIGHT_Sharp) { wN.set(F->N); } - // else - { - wN.from_bary(V1->N, V2->N, V3->N, B); - exact_normalize(wN); - wN.add(F->N); - exact_normalize(wN); - } - try - { - VERIFY(inlc_global_data()); - VERIFY(inlc_global_data()->RCAST_Model()); - LightPoint(DB, 0, inlc_global_data()->RCAST_Model(), C, wP, wN, *LightsSelected, - (inlc_global_data()->b_nosun() ? LP_dont_sun : 0) | LP_UseFaceDisable, F); //. - Fcount += 1; - } - catch (...) - { - Logger.clMsg("* ERROR (CDB). Recovered. "); - } - break; - } - } - } - } - catch (...) - { - Logger.clMsg("* ERROR (Light). Recovered. "); - } - - if (Fcount) - { - C.scale(Fcount); - C.mul(.5f); - lm.surface[V * lm.width + U]._set(C); - lm.marker[V * lm.width + U] = 255; - } - else - { - lm.surface[V * lm.width + U]._set(C); // 0-0-0-0-0 - lm.marker[V * lm.width + U] = 0; - } - } - } - // *** Render Edges - float texel_size = (1.f / float(_max(lm.width, lm.height))) / 8.f; - for (u32 t = 0; t < UVpolys.size(); t++) - { - UVtri& T = UVpolys[t]; - Face* F = T.owner; - R_ASSERT(F); - try - { - L_Direct_Edge(DB, LightsSelected, T.uv[0], T.uv[1], F->v[0]->P, F->v[1]->P, F->N, texel_size, F); - L_Direct_Edge(DB, LightsSelected, T.uv[1], T.uv[2], F->v[1]->P, F->v[2]->P, F->N, texel_size, F); - L_Direct_Edge(DB, LightsSelected, T.uv[2], T.uv[0], F->v[2]->P, F->v[0]->P, F->N, texel_size, F); - } - catch (...) - { - Logger.clMsg("* ERROR (Edge). Recovered. "); - } - } -} diff --git a/src/utils/xrLC_Light/xrDeflector.cpp b/src/utils/xrLC_Light/xrDeflector.cpp deleted file mode 100644 index 4bf5bf6c8ea..00000000000 --- a/src/utils/xrLC_Light/xrDeflector.cpp +++ /dev/null @@ -1,485 +0,0 @@ -#include "stdafx.h" - -#include "xrdeflector.h" -#include "xrIsect.h" -#include "xrlc_globaldata.h" - -#include "math.h" -#include "xrface.h" -#include "serialize.h" - -void blit(u32* dest, u32 ds_x, u32 ds_y, u32* src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF) -{ - R_ASSERT(ds_x >= (ss_x + px)); - R_ASSERT(ds_y >= (ss_y + py)); - for (u32 y = 0; y < ss_y; y++) - for (u32 x = 0; x < ss_x; x++) - { - u32 dx = px + x; - u32 dy = py + y; - u32 sc = src[y * ss_x + x]; - if (color_get_A(sc) >= aREF) - dest[dy * ds_x + dx] = sc; - } -} - -void lblit(lm_layer& dst, lm_layer& src, u32 px, u32 py, u32 aREF) -{ - u32 ds_x = dst.width; - u32 ds_y = dst.height; - u32 ss_x = src.width; - u32 ss_y = src.height; - R_ASSERT(ds_x >= (ss_x + px)); - R_ASSERT(ds_y >= (ss_y + py)); - for (u32 y = 0; y < ss_y; y++) - for (u32 x = 0; x < ss_x; x++) - { - u32 dx = px + x; - u32 dy = py + y; - u8 sm = src.marker[y * ss_x + x]; - if (sm >= aREF) - { - base_color sc = src.surface[y * ss_x + x]; - dst.surface[dy * ds_x + dx] = sc; - dst.marker[dy * ds_x + dx] = sm; - } - } -} - -void blit(lm_layer& dst, u32 ds_x, u32 ds_y, lm_layer& src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF) -{ - R_ASSERT(ds_x >= (ss_x + px)); - R_ASSERT(ds_y >= (ss_y + py)); - for (u32 y = 0; y < ss_y; y++) - for (u32 x = 0; x < ss_x; x++) - { - u32 dx = px + x; - u32 dy = py + y; - u8 sm = src.marker[y * ss_x + x]; - if (sm >= aREF) - { - base_color sc = src.surface[y * ss_x + x]; - dst.surface[dy * ds_x + dx] = sc; - dst.marker[dy * ds_x + dx] = sm; - } - } -} - -void blit_r(u32* dest, u32 ds_x, u32 ds_y, u32* src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF) -{ - R_ASSERT(ds_x >= (ss_y + px)); - R_ASSERT(ds_y >= (ss_x + py)); - for (u32 y = 0; y < ss_y; y++) - for (u32 x = 0; x < ss_x; x++) - { - u32 dx = px + y; - u32 dy = py + x; - u32 sc = src[y * ss_x + x]; - if (color_get_A(sc) >= aREF) - dest[dy * ds_x + dx] = sc; - } -} - -void blit_r(lm_layer& dst, u32 ds_x, u32 ds_y, lm_layer& src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF) -{ - R_ASSERT(ds_x >= (ss_y + px)); - R_ASSERT(ds_y >= (ss_x + py)); - for (u32 y = 0; y < ss_y; y++) - for (u32 x = 0; x < ss_x; x++) - { - u32 dx = px + y; - u32 dy = py + x; - u8 sm = src.marker[y * ss_x + x]; - if (sm >= aREF) - { - base_color sc = src.surface[y * ss_x + x]; - dst.surface[dy * ds_x + dx] = sc; - dst.marker[dy * ds_x + dx] = sm; - } - } -} - -//------------------------------------- - -// CDeflector* Deflector = 0; - -IC BOOL UVpointInside(Fvector2& P, UVtri& T) -{ - Fvector B; - return T.isInside(P, B); -} - -CDeflector::CDeflector() : _net_session(0) -{ - // Deflector = this; - normal.set(0, 1, 0); - Sphere.P.set(flt_max, flt_max, flt_max); - Sphere.R = 0; - bMerged = FALSE; - UVpolys.reserve(32); -} -CDeflector::~CDeflector() {} -void CDeflector::OA_Export() -{ - if (UVpolys.empty()) - return; - - // Correct normal - // (semi-proportional to pixel density) - FPU::m64r(); - Fvector tN; - tN.set(0, 0, 0); - float density = 0; - float fcount = 0; - for (UVIt it = UVpolys.begin(); it != UVpolys.end(); ++it) - { - Face* F = it->owner; - Fvector SN; - SN.set(F->N); - SN.mul(1 + EPS * F->CalcArea()); - tN.add(SN); - - density += F->Shader().lm_density; - fcount += 1.f; - } - if (tN.magnitude() > EPS_S && _valid(tN)) - normal.set(tN).normalize(); - else - { - Logger.clMsg("* ERROR: Internal precision error in CDeflector::OA_Export"); - for (UVIt it = UVpolys.begin(); it != UVpolys.end(); ++it) - { - Face& fc = *((*it).owner); - inlc_global_data()->err_tjunction().w_fvector3(fc.v[0]->P); - inlc_global_data()->err_tjunction().w_fvector3(fc.v[1]->P); - - inlc_global_data()->err_tjunction().w_fvector3(fc.v[1]->P); - inlc_global_data()->err_tjunction().w_fvector3(fc.v[2]->P); - - inlc_global_data()->err_tjunction().w_fvector3(fc.v[2]->P); - inlc_global_data()->err_tjunction().w_fvector3(fc.v[0]->P); - } - } - density /= fcount; - - // Orbitrary Oriented Ortho - Projection - Fmatrix mView; - Fvector at, from, up, right, y; - at.set(0, 0, 0); - from.add(at, normal); - y.set(0, 1, 0); - if (_abs(normal.y) > .99f) - y.set(1, 0, 0); - right.crossproduct(y, normal); - right.normalize_safe(); - up.crossproduct(normal, right); - up.normalize_safe(); - mView.build_camera(from, at, up); - - Fbox bb; - bb.invalidate(); - for (UVIt it = UVpolys.begin(); it != UVpolys.end(); ++it) - { - UVtri* T = &*it; - Face* F = T->owner; - Fvector P; // projected - - for (int i = 0; i < 3; i++) - { - mView.transform_tiny(P, F->v[i]->P); - T->uv[i].set(P.x, P.y); - bb.modify(F->v[i]->P); - } - } - bb.getsphere(Sphere.P, Sphere.R); - - // UV rect - Fvector2 min, max, size; - GetRect(min, max); - size.sub(max, min); - - // Surface - VERIFY(inlc_global_data()); - u32 dwWidth = iCeil(size.x * inlc_global_data()->g_params().m_lm_pixels_per_meter * density + .5f); - clamp(dwWidth, 1u, 512u - 2 * BORDER); - u32 dwHeight = iCeil(size.y * inlc_global_data()->g_params().m_lm_pixels_per_meter * density + .5f); - clamp(dwHeight, 1u, 512u - 2 * BORDER); - layer.create(dwWidth, dwHeight); -} - -BOOL CDeflector::OA_Place(Face* owner) -{ - // It is not correct to rely solely on normal-split-angle for lmaps - imagine smooth sphere - float cosa = normal.dotproduct(owner->N); - VERIFY(inlc_global_data()); - if (cosa < _cos(deg2rad(inlc_global_data()->g_params().m_sm_angle + 1))) - return FALSE; - - UVtri T; - T.owner = owner; - owner->pDeflector = this; - UVpolys.push_back(T); - return TRUE; -} - -void CDeflector::OA_Place(vecFace& lst) -{ - UVpolys.clear(); - UVpolys.reserve(lst.size()); - for (u32 I = 0; I < lst.size(); I++) - { - UVtri T; - Face* F = lst[I]; - T.owner = F; - F->pDeflector = this; - UVpolys.push_back(T); - } -} - -void CDeflector::GetRect(Fvector2& min, Fvector2& max) -{ - // Calculate bounds - xr_vector::iterator it = UVpolys.begin(); - min = max = it->uv[0]; - for (; it != UVpolys.end(); ++it) - { - for (int i = 0; i < 3; i++) - { - min.min(it->uv[i]); - max.max(it->uv[i]); - } - } -} - -void CDeflector::RemapUV( - xr_vector& dest, u32 base_u, u32 base_v, u32 size_u, u32 size_v, u32 lm_u, u32 lm_v, BOOL bRotate) -{ - dest.clear(); - dest.reserve(UVpolys.size()); - - // UV rect (actual) - Fvector2 a_min, a_max, a_size; - GetRect(a_min, a_max); - a_size.sub(a_max, a_min); - - // UV rect (dedicated) - Fvector2 d_min, d_max, d_size; - d_min.x = (float(base_u) + .5f) / float(lm_u); - d_min.y = (float(base_v) + .5f) / float(lm_v); - d_max.x = (float(base_u + size_u) - .5f) / float(lm_u); - d_max.y = (float(base_v + size_v) - .5f) / float(lm_v); - if (d_min.x >= d_max.x) - { - d_min.x = d_max.x = (d_min.x + d_max.x) / 2; - d_min.x -= EPS_S; - d_max.x += EPS_S; - } - if (d_min.y >= d_max.y) - { - d_min.y = d_max.y = (d_min.y + d_max.y) / 2; - d_min.y -= EPS_S; - d_max.y += EPS_S; - } - d_size.sub(d_max, d_min); - - // Remapping - Fvector2 tc; - UVtri tnew; - if (bRotate) - { - for (UVIt it = UVpolys.begin(); it != UVpolys.end(); ++it) - { - UVtri& T = *it; - tnew.owner = T.owner; - for (size_t i = 0; i < 3; i++) - { - tc.x = ((T.uv[i].y - a_min.y) / a_size.y) * d_size.x + d_min.x; - tc.y = ((T.uv[i].x - a_min.x) / a_size.x) * d_size.y + d_min.y; - tnew.uv[i].set(tc); - } - dest.push_back(tnew); - } - } - else - { - for (UVIt it = UVpolys.begin(); it != UVpolys.end(); ++it) - { - UVtri& T = *it; - tnew.owner = T.owner; - for (size_t i = 0; i < 3; i++) - { - tc.x = ((T.uv[i].x - a_min.x) / a_size.x) * d_size.x + d_min.x; - tc.y = ((T.uv[i].y - a_min.y) / a_size.y) * d_size.y + d_min.y; - tnew.uv[i].set(tc); - } - dest.push_back(tnew); - } - } -} - -void CDeflector::RemapUV(u32 base_u, u32 base_v, u32 size_u, u32 size_v, u32 lm_u, u32 lm_v, BOOL bRotate) -{ - xr_vector tris_new; - RemapUV(tris_new, base_u, base_v, size_u, size_v, lm_u, lm_v, bRotate); - UVpolys = std::move(tris_new); -} - -void CDeflector::L_Calculate(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H) -{ - try - { - lm_layer& lm = layer; - - // UV & HASH - RemapUV(0, 0, lm.width, lm.height, lm.width, lm.height, FALSE); - Fbox2 bounds; - Bounds_Summary(bounds); - H.initialize(bounds, (u32)UVpolys.size()); - for (size_t fid = 0; fid < UVpolys.size(); fid++) - { - UVtri* T = &(UVpolys[fid]); - Bounds(fid, bounds); - H.add(bounds, T); - } - - // Calculate - R_ASSERT(lm.width <= (c_LMAP_size - 2 * BORDER)); - R_ASSERT(lm.height <= (c_LMAP_size - 2 * BORDER)); - lm.create(lm.width, lm.height); - L_Direct(DB, LightsSelected, H); - } - catch (...) - { - Logger.clMsg("* ERROR: CDeflector::L_Calculate"); - } -} - -u16 CDeflector::GetBaseMaterial() { return UVpolys.front().owner->dwMaterial; } -/* -xr_vector UVpolys; -Fvector normal; -lm_layer layer; -Fsphere Sphere; - -BOOL bMerged; -*/ - -void CDeflector::receive_result(INetReader& r) -{ - read(r); - layer.read(r); -#ifdef COLLECT_EXECUTION_STATS - time_stat.read(r); -#endif -} -void CDeflector::send_result(IWriter& w) const -{ - write(w); - layer.write(w); -#ifdef COLLECT_EXECUTION_STATS - time_stat.write(w); -#endif -} - -void CDeflector::read(INetReader& r) -{ - u32 sz_polys = r.r_u32(); - UVpolys.resize(sz_polys); - - for (u32 i = 0; i < sz_polys; ++i) - { - UVpolys[i].read(r); - VERIFY(UVpolys[i].owner); - // VERIFY( !UVpolys[i].owner->pDeflector ); - UVpolys[i].owner->pDeflector = this; - } - - r.r_fvector3(normal); - - // layer.read( r ); - layer.width = r.r_u32(); - layer.height = r.r_u32(); - - r_sphere(r, Sphere); - - bMerged = (BOOL)r.r_u8(); -} - -void CDeflector::write(IWriter& w) const -{ - u32 sz_polys = UVpolys.size(); - w.w_u32(sz_polys); - for (u32 i = 0; i < sz_polys; ++i) - UVpolys[i].write(w); - - w.w_fvector3(normal); - - // layer.write( w ); - w.w_u32(layer.width); - w.w_u32(layer.height); - - w_sphere(w, Sphere); - - w.w_u8((u8)bMerged); -} - -bool CDeflector::similar(const CDeflector& D, float eps /* =EPS */) const -{ - if (bMerged != D.bMerged) - return false; - - if (!normal.similar(D.normal, eps)) - return false; - - if (!Sphere.P.similar(D.Sphere.P, eps)) - return false; - - if (!fsimilar(Sphere.R, D.Sphere.R, eps)) - return false; - - if (UVpolys.size() != D.UVpolys.size()) - return false; - - for (u32 i = 0; i < UVpolys.size(); ++i) - { - if (!UVpolys[i].similar(D.UVpolys[i], eps)) - { - return false; - } - } - - return layer.similar(D.layer, eps); -} - -CDeflector* CDeflector::read_create() { return xr_new(); } -void DumpDeflctor(u32 id) -{ - VERIFY(inlc_global_data()->g_deflectors().size() > id); - const CDeflector& D = *inlc_global_data()->g_deflectors()[id]; - Logger.clMsg("deflector id: %d - faces num: %d ", id, D.UVpolys.size()); -} - -void DumpDeflctor(const CDeflector& D) -{ - Logger.clMsg("lightmap size: %d ", D.layer.width * D.layer.height); - Logger.clMsg("lightmap width/height : %d/%d", D.layer.width, D.layer.height); - Logger.clMsg("deflector - faces num: %d ", D.UVpolys.size()); -} - -void DeflectorsStats() -{ - u32 size = inlc_global_data()->g_deflectors().size(); - Logger.clMsg("num deflectors: %d", size); - for (u32 i = 0; i < size; i++) - DumpDeflctor(i); -} - -#ifdef COLLECT_EXECUTION_STATS - -void CDeflector::statistic_log() const -{ - time_stat.log(); - DumpDeflctor(*this); -} - -#endif diff --git a/src/utils/xrLC_Light/xrDeflector.h b/src/utils/xrLC_Light/xrDeflector.h deleted file mode 100644 index 9911403efc5..00000000000 --- a/src/utils/xrLC_Light/xrDeflector.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once - -#include "xrfacedefs.h" -#include "base_color.h" -#include "lm_layer.h" -#include "uv_tri.h" -#include "xrCDB/xrCDB.h" -#include "serialize.h" -#include "xrdeflectordefs.h" -#include "execute_statistics.h" -class base_lighting; -class net_task_callback; -class CDeflector; -// extern XRLC_LIGHT_API CDeflector* Deflector ; -class execute_statistics; -class XRLC_LIGHT_API CDeflector -{ -public: - net_task_callback* _net_session; - xr_vector UVpolys; - Fvector normal; - lm_layer layer; - Fsphere Sphere; - - BOOL bMerged; - -public: - CDeflector(); - // public: - // CDeflector (CDeflector** g_defl) { CDeflector(); Deflector = this ;} - ~CDeflector(); - static CDeflector* read_create(); - - void OA_SetNormal(const Fvector& n) - { - normal.set(n); - normal.normalize(); - VERIFY(_valid(normal)); - } - BOOL OA_Place(Face* owner); - void OA_Place(vecFace& lst); - void OA_Export(); - - void GetRect(Fvector2& min, Fvector2& max); - u32 GetFaceCount() { return (u32)UVpolys.size(); }; - void Light(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H); - void L_Direct(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H); - void L_Direct_Edge(CDB::COLLIDER* DB, base_lighting* LightsSelected, Fvector2& p1, Fvector2& p2, Fvector& v1, - Fvector& v2, Fvector& N, float texel_size, Face* skip); - void L_Calculate(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H); - u32 weight() { return layer.Area(); } - u16 GetBaseMaterial(); - - void Bounds(u32 ID, Fbox2& dest) - { - UVtri& TC = UVpolys[ID]; - dest.min.set(TC.uv[0]); - dest.max.set(TC.uv[0]); - dest.modify(TC.uv[1]); - dest.modify(TC.uv[2]); - } - void Bounds_Summary(Fbox2& bounds) - { - bounds.invalidate(); - for (u32 I = 0; I < UVpolys.size(); I++) - { - Fbox2 B; - Bounds(I, B); - bounds.merge(B); - } - } - void RemapUV( - xr_vector& dest, u32 base_u, u32 base_v, u32 size_u, u32 size_v, u32 lm_u, u32 lm_v, BOOL bRotate); - void RemapUV(u32 base_u, u32 base_v, u32 size_u, u32 size_v, u32 lm_u, u32 lm_v, BOOL bRotate); - void read(INetReader& r); - void write(IWriter& w) const; - - void receive_result(INetReader& r); - void send_result(IWriter& w) const; - - bool similar(const CDeflector& D, float eps = EPS) const; - -#ifdef COLLECT_EXECUTION_STATS -public: - execute_time_statistics time_stat; - void statistic_log() const; - -#endif -}; - -typedef xr_vector::iterator UVIt; - -extern XRLC_LIGHT_API void Jitter_Select(Fvector2*& Jitter, u32& Jcount); -extern void blit(u32* dest, u32 ds_x, u32 ds_y, u32* src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF); -extern XRLC_LIGHT_API void blit( - lm_layer& dst, u32 ds_x, u32 ds_y, lm_layer& src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF); -extern void blit_r(u32* dest, u32 ds_x, u32 ds_y, u32* src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF); -extern XRLC_LIGHT_API void blit_r( - lm_layer& dst, u32 ds_x, u32 ds_y, lm_layer& src, u32 ss_x, u32 ss_y, u32 px, u32 py, u32 aREF); -extern void lblit(lm_layer& dst, lm_layer& src, u32 px, u32 py, u32 aREF); -extern XRLC_LIGHT_API void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c& C, Fvector& P, Fvector& N, - base_lighting& lights, u32 flags, Face* skip); -extern XRLC_LIGHT_API BOOL ApplyBorders(lm_layer& lm, u32 ref); -extern XRLC_LIGHT_API void DumpDeflctor(u32 id); -extern XRLC_LIGHT_API void DumpDeflctor(const CDeflector& d); -extern XRLC_LIGHT_API void DeflectorsStats(); -extern XRLC_LIGHT_API void DumpDeflctor(u32 id); - -static const u32 c_LMAP_size = 1024; // pixels - -#define rms_zero ((4 + g_params().m_lm_rms_zero) / 2) -#define rms_shrink ((8 + g_params().m_lm_rms) / 2) - -typedef vector_serialize>> tread_deflectors; -typedef vector_serialize>> twrite_deflectors; - -extern tread_deflectors* read_deflectors; -extern twrite_deflectors* write_deflectors; diff --git a/src/utils/xrLC_Light/xrDeflectorDefs.h b/src/utils/xrLC_Light/xrDeflectorDefs.h deleted file mode 100644 index 346be23d771..00000000000 --- a/src/utils/xrLC_Light/xrDeflectorDefs.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "hash2D.h" -class CDeflector; -typedef xr_vector vecDefl; -// extern vecDefl g_deflectors ; -typedef vecDefl::iterator vecDeflIt; -struct UVtri; -typedef hash2D HASH; diff --git a/src/utils/xrLC_Light/xrDeflectorLight.cpp b/src/utils/xrLC_Light/xrDeflectorLight.cpp deleted file mode 100644 index 478e70a6ed9..00000000000 --- a/src/utils/xrLC_Light/xrDeflectorLight.cpp +++ /dev/null @@ -1,977 +0,0 @@ -#include "stdafx.h" - -#include "xrdeflector.h" - -#include "xrCDB/Intersect.hpp" -#include "xrlc_globaldata.h" - -#include "xrImage_Resampler.h" -#include "light_point.h" -#include "xrface.h" -#include "net_task.h" -#include "xrCore/buffer_vector.h" -#include "base_face_ptr_storage.h" - -// const u32 rms_discard = 8; -// extern BOOL gl_linear ; - -void Jitter_Select(Fvector2*& Jitter, u32& Jcount) -{ - static Fvector2 Jitter1[1] = {{0, 0}}; - static Fvector2 Jitter4[4] = {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}; - static Fvector2 Jitter9[9] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {0, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}}; - - switch (g_params().m_lm_jitter_samples) - { - case 1: - Jcount = 1; - Jitter = Jitter1; - break; - case 9: - Jcount = 9; - Jitter = Jitter9; - break; - case 4: - default: - Jcount = 4; - Jitter = Jitter4; - break; - } -} - -void GET(const base_color& surface_color, const u8 marker, - // u32 width, u32 height, int x, int y, - u32 ref, u32& count, base_color_c& dst) -{ - // if (x<0) return; - // else if (x>=(int)width) return; - // if (y<0) return; - // else if (y>=(int)height) return; - - // summarize - // u32 id = y*width + x; - if (marker <= ref) - return; - - base_color_c C; - surface_color._get(C); - dst.add(C); - count++; -} - -void GET(const lm_layer& lm, int x, int y, u32 ref, u32& count, base_color_c& dst) -{ - // wrap pixels - if (x < 0) - return; - else if (x >= (int)lm.width) - return; - if (y < 0) - return; - else if (y >= (int)lm.height) - return; - - // summarize - u32 id = y * lm.width + x; - if (lm.marker[id] <= ref) - return; - - base_color_c C; - lm.surface[id]._get(C); - dst.add(C); - count++; -} - -/* -struct Get8_res -{ - Get8_res():count(0), res_surface_color(0), res_marker(0), ref( u32(-1) ) {} - base_color_c dst; - u32 count; - base_color *res_surface_color; - u8 *res_marker; - u32 ref; - void aplly( int x, int y, u32 _ref, bool &bNeedContinue, lm_layer &result ) - { - if (count) { - dst.scale (count); - result.surface [y*result.width+x]._set(dst); - result.marker [y*result.width+x]=u8(_ref); - bNeedContinue = TRUE; - } - } - void apply_delay(int x, int y, u32 _ref, bool &bNeedContinue, lm_layer &result ) - { - if (count) { - dst.scale (count); - res_surface_color = &(result.surface [y*result.width+x]);//._set(dst); - res_marker = &(result.marker [y*result.width+x]);//=u8(ref); - ref = _ref; - bNeedContinue = TRUE; - } - } - ~Get8_res() - { - if( res_surface_color ) - { - R_ASSERT( res_marker ); - R_ASSERT( ref != u32(-1) ); - res_surface_color->_set(dst); - *res_marker =u8(ref); - } - } -}; - -void Get8(const lm_layer &lm, int x, int y, u32 ref, u32 &count, base_color_c& dst ) -{ - GET(lm,x-1,y-1,ref,count,dst); - GET(lm,x ,y-1,ref,count,dst); - GET(lm,x+1,y-1,ref,count,dst); - - GET(lm,x-1,y ,ref,count,dst); - GET(lm,x+1,y ,ref,count,dst); - - GET(lm,x-1,y+1,ref,count,dst); - GET(lm,x ,y+1,ref,count,dst); - GET(lm,x+1,y+1,ref,count,dst); -} - -void Get8(lm_layer &lm, int x, int y, u32 ref, Get8_res &res ) -{ - Get8( lm, x, y, ref, res.count, res.dst ); -} -*/ - -struct lm_line -{ - buffer_vector& surface; - buffer_vector& marker; - u32 y; - u32 height; - lm_line(buffer_vector& surf_buf, buffer_vector& mark_buf) - : surface(surf_buf), marker(mark_buf), y(u32(-1)), height(u32(-1)) - { - } - void save(int _y, const lm_layer& lm) - { - y = _y; - height = lm.height; - - { - xr_vector::const_iterator from = lm.surface.begin() + y * lm.width; - xr_vector::const_iterator to = from + lm.width; - surface.assign(from, to); - } - - { - xr_vector::const_iterator from = lm.marker.begin() + y * lm.width; - xr_vector::const_iterator to = from + lm.width; - marker.assign(from, to); - } - - // surface.resize( lm.width ); - // marker.resize( lm.width ); - // for (int x=0; x<(int)lm.width; x++) - //{ - // surface[x] = lm.surface[y*lm.width+x]; - // marker[x] = lm.marker[y*lm.width+x]; - //} - } -}; -void GET(const lm_line& l, int x, u32 width, u32 ref, u32& count, base_color_c& dst) -{ - if (x < 0) - return; - else if (x >= (int)width) - return; - if (l.y < 0) - return; - else if (l.y >= (int)l.height) - return; - - // summarize - u32 id = x; - if (l.marker[id] <= ref) - return; - - base_color_c C; - l.surface[id]._get(C); - dst.add(C); - count++; -} - -BOOL NEW_ApplyBorders(lm_layer& lm, u32 ref) -{ - bool bNeedContinue = false; - - buffer_vector buf_surf_line0(xr_alloca(lm.width * sizeof(base_color)), lm.width); - - buffer_vector buf_surf_line1(xr_alloca(lm.width * sizeof(base_color)), lm.width); - - buffer_vector buf_marker_line0(xr_alloca(lm.width * sizeof(u8)), lm.width); - - buffer_vector buf_marker_line1(xr_alloca(lm.width * sizeof(u8)), lm.width); - - lm_line line0(buf_surf_line0, buf_marker_line0); - lm_line line1(buf_surf_line1, buf_marker_line1); - - try - { - // lm_layer result = lm; - - lm_line* l_0 = &line0; - lm_line* l_1 = &line1; - - for (int y = 0; y < (int)lm.height; y++) - { - l_0->save(y, lm); - - std::swap(l_0, l_1); - - lm_line& line = *l_0; - - base_color sv_color0; - sv_color0._set(-1, -1, -1); - u8 sv_marker0 = u8(-1); - for (int x = 0; x < (int)lm.width; x++) - { - base_color sv_color = sv_color0; - u8 sv_marker = sv_marker0; - sv_color0 = lm.surface[y * lm.width + x]; - sv_marker0 = lm.marker[y * lm.width + x]; - if (lm.marker[y * lm.width + x] == 0) - { - base_color_c clr; - u32 C = 0; - if (y > 0) - { - GET(line, x - 1, lm.width, ref, C, clr); - GET(line, x, lm.width, ref, C, clr); - GET(line, x + 1, lm.width, ref, C, clr); - } - // GET(lm,x-1,y-1,ref,C,clr); - // GET(lm,x ,y-1,ref,C,clr); - // GET(lm,x+1,y-1,ref,C,clr); - - // GET(lm,x-1,y ,ref,C,clr); - if (x > 0) - GET(sv_color, sv_marker, ref, C, clr); - - GET(lm, x + 1, y, ref, C, clr); - - GET(lm, x - 1, y + 1, ref, C, clr); - GET(lm, x, y + 1, ref, C, clr); - GET(lm, x + 1, y + 1, ref, C, clr); - - if (C) - { - clr.scale(C); - lm.surface[y * lm.width + x]._set(clr); - lm.marker[y * lm.width + x] = u8(ref); - bNeedContinue = TRUE; - } - } - } - } - // lm = result; - } - catch (...) - { - Logger.clMsg("* ERROR: ApplyBorders"); - } - return bNeedContinue; -} - -BOOL OLD_ApplyBorders(lm_layer& lm, u32 ref) -{ - BOOL bNeedContinue = FALSE; - - try - { - lm_layer result = lm; - - for (int y = 0; y < (int)lm.height; y++) - { - for (int x = 0; x < (int)lm.width; x++) - { - if (lm.marker[y * lm.width + x] == 0) - { - base_color_c clr; - u32 C = 0; - GET(lm, x - 1, y - 1, ref, C, clr); - GET(lm, x, y - 1, ref, C, clr); - GET(lm, x + 1, y - 1, ref, C, clr); - - GET(lm, x - 1, y, ref, C, clr); - GET(lm, x + 1, y, ref, C, clr); - - GET(lm, x - 1, y + 1, ref, C, clr); - GET(lm, x, y + 1, ref, C, clr); - GET(lm, x + 1, y + 1, ref, C, clr); - - if (C) - { - clr.scale(C); - result.surface[y * lm.width + x]._set(clr); - result.marker[y * lm.width + x] = u8(ref); - bNeedContinue = TRUE; - } - } - } - } - lm = result; - } - catch (...) - { - Logger.clMsg("* ERROR: ApplyBorders"); - } - return bNeedContinue; -} - -BOOL ApplyBorders(lm_layer& lm, u32 ref) -{ - // lm_layer r_new = lm; - // BOOL bres_new = NEW_ApplyBorders( r_new, ref ); - // lm_layer r_old = lm; - // BOOL bres_old = OLD_ApplyBorders( r_old, ref ); - - // R_ASSERT( r_old.similar( r_new, 0 ) ); - // R_ASSERT( bres_new == bres_old ); - - // - // lm = r_new; - // return bres_new; - // - - return NEW_ApplyBorders(lm, ref); -} - -float getLastRP_Scale(CDB::COLLIDER* DB, CDB::MODEL* MDL, R_Light& L, Face* skip, BOOL bUseFaceDisable) -{ - u32 tris_count = DB->r_count(); - float scale = 1.f; - Fvector B; - - X_TRY - { - for (u32 I = 0; I < tris_count; I++) - { - CDB::RESULT& rpinf = DB->r_begin()[I]; - - // Access to texture - CDB::TRI& clT = MDL->get_tris()[rpinf.id]; - base_Face* F = get_base_face_pointer(clT); - if (0 == F) - continue; - if (skip == F) - continue; - - const Shader_xrLC& SH = F->Shader(); - if (!SH.flags.bLIGHT_CastShadow) - continue; - - if (F->flags.bOpaque) - { - // Opaque poly - cache it - L.tri[0].set(rpinf.verts[0]); - L.tri[1].set(rpinf.verts[1]); - L.tri[2].set(rpinf.verts[2]); - return 0; - } - - b_material& M = inlc_global_data()->materials()[F->dwMaterial]; - b_texture& T = inlc_global_data()->textures()[M.surfidx]; -#ifdef DEBUG - const b_BuildTexture& build_texture = inlc_global_data()->textures()[M.surfidx]; - - VERIFY(!!(build_texture.THM.HasSurface()) == !!(T.pSurface)); -#endif - if (0 == T.pSurface) - { - F->flags.bOpaque = true; - Logger.clMsg("* ERROR: RAY-TRACE: Strange face detected... Has alpha without texture..."); - return 0; - } - - // barycentric coords - // note: W,U,V order - B.set(1.0f - rpinf.u - rpinf.v, rpinf.u, rpinf.v); - - // calc UV - Fvector2* cuv = F->getTC0(); - Fvector2 uv; - uv.x = cuv[0].x * B.x + cuv[1].x * B.y + cuv[2].x * B.z; - uv.y = cuv[0].y * B.x + cuv[1].y * B.y + cuv[2].y * B.z; - - int U = iFloor(uv.x * float(T.dwWidth) + .5f); - int V = iFloor(uv.y * float(T.dwHeight) + .5f); - U %= T.dwWidth; - if (U < 0) - U += T.dwWidth; - V %= T.dwHeight; - if (V < 0) - V += T.dwHeight; - - u32 pixel = T.pSurface[V * T.dwWidth + U]; - u32 pixel_a = color_get_A(pixel); - float opac = 1.f - _sqr(float(pixel_a) / 255.f); - scale *= opac; - } - } - X_CATCH { Logger.clMsg("* ERROR: getLastRP_Scale"); } - return scale; -} - -float rayTrace( - CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, R_Light& L, Fvector& P, Fvector& D, float R, Face* skip, BOOL bUseFaceDisable) -{ - R_ASSERT(DB); - - // 1. Check cached polygon - float _u, _v, range; - bool res = CDB::TestRayTri(P, D, L.tri, _u, _v, range, false); - if (res) - { - if (range > 0 && range < R) - return 0; - } - - // 2. Polygon doesn't pick - real database query - DB->ray_query(ray_options, MDL, P, D, R); - - // 3. Analyze polygons and cache nearest if possible - if (0 == DB->r_count()) - { - return 1; - } - else - { - return getLastRP_Scale(DB, MDL, L, skip, bUseFaceDisable); - } - return 0; -} - -void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c& C, Fvector& P, Fvector& N, base_lighting& lights, - u32 flags, Face* skip) -{ - Fvector Ldir, Pnew; - Pnew.mad(P, N, 0.01f); - - BOOL bUseFaceDisable = flags & LP_UseFaceDisable; - - if (0 == (flags & LP_dont_rgb)) - { - R_Light *L = &*lights.rgb.begin(), *E = &*lights.rgb.end(); - for (; L != E; L++) - { - switch (L->type) - { - case LT_DIRECT: - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float scale = D * L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, 1000.f, skip, bUseFaceDisable); - C.rgb.x += scale * L->diffuse.x; - C.rgb.y += scale * L->diffuse.y; - C.rgb.z += scale * L->diffuse.z; - } - break; - case LT_POINT: - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, R, skip, bUseFaceDisable); - float A; - if (inlc_global_data()->gl_linear()) - A = 1 - R / L->range; - else - { - // Igor: let A equal 0 at the light boundary - A = scale * (1 / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD) - R * L->falloff); - } - - C.rgb.x += A * L->diffuse.x; - C.rgb.y += A * L->diffuse.y; - C.rgb.z += A * L->diffuse.z; - } - break; - case LT_SECONDARY: - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - D *= -Ldir.dotproduct(L->direction); - if (D <= 0) - continue; - - // Jitter + trace light -> monte-carlo method - Fvector Psave = L->position, Pdir; - L->position.mad(Pdir.random_dir(L->direction, PI_DIV_4), .05f); - float R = _sqrt(sqD); - float scale = - powf(D, 1.f / 8.f) * L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, R, skip, bUseFaceDisable); - float A = scale * (1 - R / L->range); - L->position = Psave; - - C.rgb.x += A * L->diffuse.x; - C.rgb.y += A * L->diffuse.y; - C.rgb.z += A * L->diffuse.z; - } - break; - } - } - } - if (0 == (flags & LP_dont_sun)) - { - R_Light *L = &*(lights.sun.begin()), *E = &*(lights.sun.end()); - for (; L != E; L++) - { - if (L->type == LT_DIRECT) - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float scale = L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, 1000.f, skip, bUseFaceDisable); - C.sun += scale; - } - else - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, R, skip, bUseFaceDisable); - float A = scale / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD); - - C.sun += A; - } - } - } - if (0 == (flags & LP_dont_hemi)) - { - R_Light *L = &*lights.hemi.begin(), *E = &*lights.hemi.end(); - for (; L != E; L++) - { - if (L->type == LT_DIRECT) - { - // Cos - Ldir.invert(L->direction); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - Fvector PMoved; - PMoved.mad(Pnew, Ldir, 0.001f); - float scale = L->energy * rayTrace(DB, ray_options, MDL, *L, PMoved, Ldir, 1000.f, skip, bUseFaceDisable); - C.hemi += scale; - } - else - { - // Distance - float sqD = P.distance_to_sqr(L->position); - if (sqD > L->range2) - continue; - - // Dir - Ldir.sub(L->position, P); - Ldir.normalize_safe(); - float D = Ldir.dotproduct(N); - if (D <= 0) - continue; - - // Trace Light - float R = _sqrt(sqD); - float scale = D * L->energy * rayTrace(DB, ray_options, MDL, *L, Pnew, Ldir, R, skip, bUseFaceDisable); - float A = scale / (L->attenuation0 + L->attenuation1 * R + L->attenuation2 * sqD); - - C.hemi += A; - } - } - } -} - -IC u32 rms_diff(u32 a, u32 b) -{ - if (a > b) - return a - b; - else - return b - a; -} - -BOOL __stdcall rms_test(lm_layer& lm, u32 w, u32 h, u32 rms) -{ - if ((w <= 1) || (h <= 1)) - return FALSE; - - // scale down(lanczos3) and up (bilinear, as video board) //. - xr_vector pOriginal_base; - lm.Pack(pOriginal_base); - xr_vector pScaled_base; - pScaled_base.resize(w * h); - xr_vector pRestored_base; - pRestored_base.resize(lm.width * lm.height); - xr_vector pOriginal_hemi; - lm.Pack_hemi(pOriginal_hemi); - xr_vector pScaled_hemi; - pScaled_hemi.resize(w * h); - xr_vector pRestored_hemi; - pRestored_hemi.resize(lm.width * lm.height); - - try - { - // rgb + sun - imf_Process(&*pScaled_base.begin(), w, h, &*pOriginal_base.begin(), lm.width, lm.height, imf_lanczos3); - imf_Process(&*pRestored_base.begin(), lm.width, lm.height, &*pScaled_base.begin(), w, h, imf_filter); - // hemi - //. - /* - if ((lm.width/2>1)&&(lm.height/2>1)){ - imf_Process (&*pRestored_hemi.begin(), lm.width/2, lm.height/2,&*pOriginal_hemi.begin(), - lm.width,lm.height, imf_lanczos3 ); - imf_Process (&*pOriginal_hemi.begin(), lm.width, lm.height, &*pRestored_hemi.begin(), - lm.width/2, lm.height/2,imf_filter ); - } - */ - imf_Process(&*pScaled_hemi.begin(), w, h, &*pOriginal_hemi.begin(), lm.width, lm.height, imf_lanczos3); - imf_Process(&*pRestored_hemi.begin(), lm.width, lm.height, &*pScaled_hemi.begin(), w, h, imf_filter); - } - catch (...) - { - Logger.clMsg("* ERROR: imf_Process"); - return FALSE; - } - - // compare them - const u32 limit = 254 - BORDER; - for (u32 y = 0; y < lm.height; y++) - { - u32 offset = y * lm.width; - u8* scan_mark = (u8*)&*(lm.marker.begin() + offset); //. - u32* scan_lmap_base = (u32*)&*(pOriginal_base.begin() + offset); - u32* scan_rest_base = (u32*)&*(pRestored_base.begin() + offset); - u32* scan_lmap_hemi = (u32*)&*(pOriginal_hemi.begin() + offset); - u32* scan_rest_hemi = (u32*)&*(pRestored_hemi.begin() + offset); - for (u32 x = 0; x < lm.width; x++) - { - if (scan_mark[x] >= limit) - { - u32 pixel_base = scan_lmap_base[x]; - u32 pixel_r_base = scan_rest_base[x]; - u32 pixel_hemi = scan_lmap_hemi[x]; - u32 pixel_r_hemi = scan_rest_hemi[x]; - if (rms_diff(color_get_R(pixel_r_base), color_get_R(pixel_base)) > rms) - return FALSE; - if (rms_diff(color_get_G(pixel_r_base), color_get_G(pixel_base)) > rms) - return FALSE; - if (rms_diff(color_get_B(pixel_r_base), color_get_B(pixel_base)) > rms) - return FALSE; - if (rms_diff(color_get_A(pixel_r_base), color_get_A(pixel_base)) > rms) - return FALSE; - if (rms_diff(color_get_R(pixel_r_hemi), color_get_R(pixel_hemi)) > ((rms * 4) / 3)) - return FALSE; - } - } - } - return TRUE; -} - -BOOL __stdcall rms_test(lm_layer& lm, u32 _r, u32 _g, u32 _b, u32 _s, u32 _h, u32 rms) -{ - u32 x, y; - for (y = 0; y < lm.height; y++) - { - for (x = 0; x < lm.width; x++) - { - u32 offset = y * lm.width + x; - if (lm.marker[offset] >= 254) - { - u8 r, g, b, s, h; - lm.Pixel(offset, r, g, b, s, h); - if (rms_diff(_r, r) > rms) - return FALSE; - if (rms_diff(_g, g) > rms) - return FALSE; - if (rms_diff(_b, b) > rms) - return FALSE; - if (rms_diff(_s, s) > rms) - return FALSE; - if (rms_diff(_h, h) > ((rms * 4) / 3)) - return FALSE; - } - } - } - return TRUE; -} - -u32 __stdcall rms_average(lm_layer& lm, base_color_c& C) -{ - u32 x, y, _count = 0; - - for (y = 0; y < lm.height; y++) - { - for (x = 0; x < lm.width; x++) - { - u32 offset = y * lm.width + x; - if (lm.marker[offset] >= 254) - { - base_color_c cc; - lm.surface[offset]._get(cc); - C.add(cc); - _count++; - } - } - } - return _count; -} - -BOOL compress_Zero(lm_layer& lm, u32 rms) -{ - // Average color - base_color_c _c; - u32 _count = rms_average(lm, _c); - - if (0 == _count) - { - Logger.clMsg("* ERROR: Lightmap not calculated (T:%d)"); - return FALSE; - } - else - _c.scale(_count); - - // Compress if needed - u8 _r = u8_clr(_c.rgb.x); //. - u8 _g = u8_clr(_c.rgb.y); - u8 _b = u8_clr(_c.rgb.z); - u8 _s = u8_clr(_c.sun); - u8 _h = u8_clr(_c.hemi); - if (rms_test(lm, _r, _g, _b, _s, _h, rms)) - { - u32 c_x = BORDER * 2; - u32 c_y = BORDER * 2; - base_color ccc; - ccc._set(_c); - lm.surface.assign(c_x * c_y, ccc); - lm.marker.assign(c_x * c_y, 255); - lm.height = 0; - lm.width = 0; - return TRUE; - } - return FALSE; -} - -BOOL compress_RMS(lm_layer& lm, u32 rms, u32& w, u32& h) -{ - // *** Try to bilinearly filter lightmap down and up - w = 0, h = 0; - if (lm.width >= 2) - { - w = lm.width / 2; - if (!rms_test(lm, w, lm.height, rms)) - { - // 3/4 - w = (lm.width * 3) / 4; - if (!rms_test(lm, w, lm.height, rms)) - w = 0; - } - else - { - // 1/4 - u32 nw = (lm.width * 1) / 4; - if (rms_test(lm, nw, lm.height, rms)) - w = nw; - } - } - if (lm.height >= 2) - { - h = lm.height / 2; - if (!rms_test(lm, lm.width, h, rms)) - { - // 3/4 - h = (lm.height * 3) / 4; - if (!rms_test(lm, lm.width, h, rms)) - h = 0; - } - else - { - // 1/4 - u32 nh = (lm.height * 1) / 4; - if (rms_test(lm, lm.width, nh, rms)) - h = nh; - } - } - if (w || h) - { - if (0 == w) - w = lm.width; - if (0 == h) - h = lm.height; - // clMsg ("* RMS: [%d,%d] => [%d,%d]",lm.width,lm.height,w,h); - return TRUE; - } - return FALSE; -} - -void CDeflector::Light(CDB::COLLIDER* DB, base_lighting* LightsSelected, HASH& H) -{ - // Geometrical bounds - Fbox bb; - bb.invalidate(); - try - { - for (u32 fid = 0; fid < UVpolys.size(); fid++) - { - Face* F = UVpolys[fid].owner; - for (int i = 0; i < 3; i++) - bb.modify(F->v[i]->P); - } - bb.getsphere(Sphere.P, Sphere.R); - } - catch (...) - { - Logger.clMsg("* ERROR: CDeflector::Light - sphere calc"); - } - - // Convert lights to local form - LightsSelected->select(inlc_global_data()->L_static(), Sphere.P, Sphere.R); - - // Calculate and fill borders - L_Calculate(DB, LightsSelected, H); - if (_net_session && !_net_session->test_connection()) - return; - for (u32 ref = 254; ref > 0; ref--) - if (!ApplyBorders(layer, ref)) - break; - - // Compression - try - { - u32 w, h; - if (compress_Zero(layer, rms_zero)) - return; // already with borders - else if (compress_RMS(layer, rms_shrink, w, h)) - { - // Reacalculate lightmap at lower resolution - layer.create(w, h); - L_Calculate(DB, LightsSelected, H); - if (_net_session && !_net_session->test_connection()) - return; - } - } - catch (...) - { - Logger.clMsg("* ERROR: CDeflector::Light - Compression"); - } - - // Expand with borders - try - { - if (layer.width == 1) - { - // Horizontal ZERO - vertical line - lm_layer T; - T.create(2 * BORDER, layer.height + 2 * BORDER); - - // Transfer - for (u32 y = 0; y < T.height; y++) - { - int py = int(y) - BORDER; - clamp(py, 0, int(layer.height - 1)); - base_color C = layer.surface[py]; - T.surface[y * 2 + 0] = C; - T.marker[y * 2 + 0] = 255; - T.surface[y * 2 + 1] = C; - T.marker[y * 2 + 1] = 255; - } - - // Exchange - T.width = 0; - T.height = layer.height; - layer = T; - } - else if (layer.height == 1) - { - // Vertical ZERO - horizontal line - lm_layer T; - T.create(layer.width + 2 * BORDER, 2 * BORDER); - - // Transfer - for (u32 x = 0; x < T.width; x++) - { - int px = int(x) - BORDER; - clamp(px, 0, int(layer.width - 1)); - base_color C = layer.surface[px]; - T.surface[0 * T.width + x] = C; - T.marker[0 * T.width + x] = 255; - T.surface[1 * T.width + x] = C; - T.marker[1 * T.width + x] = 255; - } - - // Exchange - T.width = layer.width; - T.height = 0; - layer = T; - } - else - { - // Generic blit - lm_layer lm_old = layer; - lm_layer lm_new; - lm_new.create(lm_old.width + 2 * BORDER, lm_old.height + 2 * BORDER); - lblit(lm_new, lm_old, BORDER, BORDER, 255 - BORDER); - layer = lm_new; - ApplyBorders(layer, 254); - ApplyBorders(layer, 253); - ApplyBorders(layer, 252); - ApplyBorders(layer, 251); - for (u32 ref = 250; ref > 0; ref--) - if (!ApplyBorders(layer, ref)) - break; - layer.width = lm_old.width; - layer.height = lm_old.height; - } - } - catch (...) - { - Logger.clMsg("* ERROR: CDeflector::Light - BorderExpansion"); - } -} diff --git a/src/utils/xrLC_Light/xrFace.cpp b/src/utils/xrLC_Light/xrFace.cpp deleted file mode 100644 index 3335f4c7f06..00000000000 --- a/src/utils/xrLC_Light/xrFace.cpp +++ /dev/null @@ -1,434 +0,0 @@ -#include "stdafx.h" - -#include "xrFace.h" - -#include "xrDeflector.h" -#include "xrLC_GlobalData.h" -#include "serialize.h" -#include "Lightmap.h" - -volatile u32 dwInvalidFaces; //= 0; -u32 InvalideFaces() { return dwInvalidFaces; } - -const Shader_xrLC& base_Face::Shader() const -{ - VERIFY(inlc_global_data()); - return shader(dwMaterial, inlc_global_data()->shaders(), inlc_global_data()->materials()); -} -void base_Face::CacheOpacity() -{ - flags.bOpaque = true; - VERIFY(inlc_global_data()); - - b_material& M = inlc_global_data()->materials()[dwMaterial]; - b_BuildTexture& T = inlc_global_data()->textures()[M.surfidx]; - if (T.bHasAlpha) - flags.bOpaque = false; - else - flags.bOpaque = true; - if (!flags.bOpaque && !(T.THM.HasSurface())) //(0==T.pSurface)// pSurface was possible deleted - { - flags.bOpaque = true; - Logger.clMsg("Strange face detected... Has alpha without texture..."); - } -} -static bool do_not_add_to_vector_in_global_data = false; -Face* Face::read_create() -{ - do_not_add_to_vector_in_global_data = true; - Face* f = inlc_global_data()->create_face(); - do_not_add_to_vector_in_global_data = false; - - return f; -} - -// -// const int edge2idx [3][2] = { {0,1}, {1,2}, {2,0} }; -// const int edge2idx3 [3][3] = { {0,1,2}, {1,2,0}, {2,0,1} }; -// const int idx2edge [3][3] = { -// {-1, 0, 2}, -// { 0, -1, 1}, -// { 2, 1, -1} -//}; - -// extern CBuild* pBuild; - -bool g_bUnregister = true; - -// template<> -void destroy_vertex(Vertex*& v, bool unregister) -{ - bool tmp_unregister = g_bUnregister; - g_bUnregister = unregister; - inlc_global_data()->destroy_vertex(v); - g_bUnregister = tmp_unregister; -} -void destroy_face(Face*& v, bool unregister) -{ - bool tmp_unregister = g_bUnregister; - g_bUnregister = unregister; - inlc_global_data()->destroy_face(v); - g_bUnregister = tmp_unregister; -} -// vecVertex g_vertices; -// vecFace g_faces; - -// poolVertices VertexPool; -// poolFaces FacePool; - -Tvertex::Tvertex() -{ - VERIFY(inlc_global_data()); - if (inlc_global_data()->vert_construct_register()) - { - // set_index( inlc_global_data()->g_vertices().size() ); - inlc_global_data()->g_vertices().push_back(this); - } - m_adjacents.reserve(4); -} - -template <> -Tvertex::~Tvertex() -{ - if (g_bUnregister) - { - vecVertexIt F = - std::find(inlc_global_data()->g_vertices().begin(), inlc_global_data()->g_vertices().end(), this); - if (F != inlc_global_data()->g_vertices().end()) - { - vecVertex& verts = inlc_global_data()->g_vertices(); - std::swap(*F, *(verts.end() - 1)); - verts.pop_back(); - // faces.erase(F); - - // inlc_global_data()->g_vertices().erase(F); - } - else - Logger.clMsg("* ERROR: Unregistered VERTEX destroyed"); - } -} - -Vertex* Vertex::CreateCopy_NOADJ(vecVertex& vertises_storage) const -{ - VERIFY(&vertises_storage == &inlc_global_data()->g_vertices()); - Vertex* V = inlc_global_data()->create_vertex(); - V->P.set(P); - V->N.set(N); - V->C = C; - return V; -} - -Vertex* Vertex::read_create() -{ - return inlc_global_data()->create_vertex(); - ; -} -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <> -Tface::Tface() -{ - pDeflector = 0; - flags.bSplitted = false; - VERIFY(inlc_global_data()); - if (!do_not_add_to_vector_in_global_data) - { - // set_index( inlc_global_data()->g_faces().size() ); - inlc_global_data()->g_faces().push_back(this); - } - sm_group = u32(-1); - lmap_layer = NULL; -} - -template <> -Tface::~Tface() -{ - if (g_bUnregister) - { - vecFaceIt F = std::find(inlc_global_data()->g_faces().begin(), inlc_global_data()->g_faces().end(), this); - if (F != inlc_global_data()->g_faces().end()) - { - vecFace& faces = inlc_global_data()->g_faces(); - std::swap(*F, *(faces.end() - 1)); - faces.pop_back(); - // faces.erase(F); - } - else - Logger.clMsg("* ERROR: Unregistered FACE destroyed"); - } - // Remove 'this' from adjacency info in vertices - for (int i = 0; i < 3; ++i) - v[i]->prep_remove(this); - - lmap_layer = NULL; -} - -//#define VPUSH(a) ((a).x), ((a).y), ((a).z) - -template <> -void Face::Failure() -{ - dwInvalidFaces++; - - Logger.clMsg("* ERROR: Invalid face. (A=%f,e0=%f,e1=%f,e2=%f)", CalcArea(), v[0]->P.distance_to(v[1]->P), - v[0]->P.distance_to(v[2]->P), v[1]->P.distance_to(v[2]->P)); - Logger.clMsg("* v0[%f,%f,%f], v1[%f,%f,%f], v2[%f,%f,%f]", VPUSH(v[0]->P), VPUSH(v[1]->P), VPUSH(v[2]->P)); - inlc_global_data()->err_invalid().w_fvector3(v[0]->P); - inlc_global_data()->err_invalid().w_fvector3(v[1]->P); - inlc_global_data()->err_invalid().w_fvector3(v[2]->P); -} - -void Face::Verify() -{ - // 1st :: area - float _a = CalcArea(); - if (!_valid(_a) || (_a < EPS)) - { - Failure(); - return; - } - - // 2nd :: TC0 - Fvector2* tc = getTC0(); - float eps = .5f / 4096.f; // half pixel from 4096 texture (0.0001220703125) - float e0 = tc[0].distance_to(tc[1]); - float e1 = tc[1].distance_to(tc[2]); - float e2 = tc[2].distance_to(tc[0]); - float p = e0 + e1 + e2; - if (!_valid(_a) || (p < eps)) - { - Failure(); - return; - } - - // 3rd :: possibility to calc normal - CalcNormal(); - if (!_valid(N)) - { - Failure(); - return; - } -} -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int affected = 0; -void start_unwarp_recursion() { affected = 1; } -void Face::OA_Unwarp(CDeflector* D) -{ - if (pDeflector) - return; - if (!D->OA_Place(this)) - return; - - // now iterate on all our neigbours - for (int i = 0; i < 3; ++i) - for (vecFaceIt it = v[i]->m_adjacents.begin(); it != v[i]->m_adjacents.end(); ++it) - { - affected += 1; - (*it)->OA_Unwarp(D); - } -} - -BOOL DataFace::RenderEqualTo(Face* F) -{ - if (F->dwMaterial != dwMaterial) - return FALSE; - // if (F->tc.size() != F->tc.size() ) return FALSE; // redundant??? - return TRUE; -} - -void DataFace::AddChannel(Fvector2& p1, Fvector2& p2, Fvector2& p3) -{ - _TCF TC; - TC.uv[0] = p1; - TC.uv[1] = p2; - TC.uv[2] = p3; - tc.push_back(TC); -} - -BOOL DataFace::hasImplicitLighting() -{ - if (nullptr == this) - return FALSE; - - if (!Shader().flags.bRendering) - return FALSE; - VERIFY(inlc_global_data()); - b_material& M = inlc_global_data()->materials()[dwMaterial]; - b_BuildTexture& T = inlc_global_data()->textures()[M.surfidx]; - return (T.THM.flags.test(STextureParams::flImplicitLighted)); -} - -/* - Fvector N; // face normal - - svector<_TCF,2> tc; // TC - - void* pDeflector; // does the face has LM-UV map? - CLightmap* lmap_layer; - u32 sm_group; -*/ - -/* -BOOL exact_normalize (Fvector3& a) { return exact_normalize(&a.x); } -BOOL exact_normalize (float* a) -{ - double sqr_magnitude = a[0]*a[0] + a[1]*a[1] + a[2]*a[2]; - double epsilon = 1.192092896e-05F; - if (sqr_magnitude > epsilon) - { - double l = rsqrt(sqr_magnitude); - a[0] *= l; - a[1] *= l; - a[2] *= l; - return TRUE; - } - - double a0,a1,a2,aa0,aa1,aa2,l; - a0 = a[0]; - a1 = a[1]; - a2 = a[2]; - aa0 = _abs(a0); - aa1 = _abs(a1); - aa2 = _abs(a2); - if (aa1 > aa0) { - if (aa2 > aa1) { - goto aa2_largest; - } - else { // aa1 is largest - a0 /= aa1; - a2 /= aa1; - l = rsqrt (a0*a0 + a2*a2 + 1); - a[0] = a0*l; - a[1] = (double)_copysign(l,a1); - a[2] = a2*l; - } - } - else { - if (aa2 > aa0) { -aa2_largest: // aa2 is largest - a0 /= aa2; - a1 /= aa2; - l = rsqrt (a0*a0 + a1*a1 + 1); - a[0] = a0*l; - a[1] = a1*l; - a[2] = (double)_copysign(l,a2); - } - else { // aa0 is largest - if (aa0 <= 0) { - // dDEBUGMSG ("vector has zero size"); ... this messace is annoying - a[0] = 0; // if all a's are zero, this is where we'll end up. - a[1] = 1; // return a default unit length vector. - a[2] = 0; - return FALSE; - } - a1 /= aa0; - a2 /= aa0; - l = rsqrt (a1*a1 + a2*a2 + 1); - a[0] = (double)_copysign(l,a0); - a[1] = a1*l; - a[2] = a2*l; - } - } - return TRUE; -} -*/ - -void DataFace::read(INetReader& r) -{ - base_Face::read(r); - - r.r_fvector3(N); - r_vector(r, tc); - pDeflector = 0; - VERIFY(read_lightmaps); - read_lightmaps->read(r, lmap_layer); - sm_group = r.r_u32(); -} -void DataFace::write(IWriter& w) const -{ - base_Face::write(w); - w.w_fvector3(N); - w_vector(w, tc); - VERIFY(write_lightmaps); - write_lightmaps->write(w, lmap_layer); - w.w_u32(sm_group); -} -void DataVertex::read(INetReader& r) { base_Vertex::read(r); } -void DataVertex::write(IWriter& w) const { base_Vertex::write(w); } -void Face::read_vertices(INetReader& r) -{ - VERIFY(::read_vertices); - ::read_vertices->read(r, v[0]); - ::read_vertices->read(r, v[1]); - ::read_vertices->read(r, v[2]); -} -void Face::write_vertices(IWriter& w) const -{ - VERIFY(::write_vertices); - ::write_vertices->write(w, v[0]); - ::write_vertices->write(w, v[1]); - ::write_vertices->write(w, v[2]); -} - -void Face::read(INetReader& r) -{ - DataFace::read(r); - - // read_vertices( r ); -} - -void Face::write(IWriter& w) const -{ - DataFace::write(w); - - // write_vertices( w ); -} - -void Vertex::read(INetReader& r) -{ - // v_faces m_adjacents; ! - DataVertex::read(r); -} -void Vertex::write(IWriter& w) const -{ - // v_faces m_adjacents; ! - DataVertex::write(w); -} - -////////////////////////////////////////////////////////////// -void Vertex::isolate_pool_clear_read(INetReader& r) -{ - DataVertex::read(r); - r_pod_vector(r, m_adjacents); - for (u32 i = 0; i < m_adjacents.size(); ++i) - { - Face& f = *m_adjacents[i]; - int v_i = -1; - r_pod(r, v_i); - R_ASSERT(v_i >= 0); - R_ASSERT(v_i < 3); - R_ASSERT(f.vertex(v_i) == 0); - f.raw_set_vertex(v_i, this); - } -} -void Vertex::isolate_pool_clear_write(IWriter& w) const -{ - DataVertex::write(w); - w_pod_vector(w, m_adjacents); - for (u32 i = 0; i < m_adjacents.size(); ++i) - { - Face& f = *m_adjacents[i]; - int v_i = f.VIndex(this); - R_ASSERT(v_i >= 0); - R_ASSERT(v_i < 3); - w_pod(w, v_i); - f.raw_set_vertex(v_i, 0); - } -} - -void Vertex::read_adjacents(INetReader& r) -{ - // VERIFY() -} -void Vertex::write_adjacents(IWriter& w) const {} -/////////////////////////////////////////////////////////////// diff --git a/src/utils/xrLC_Light/xrFace.h b/src/utils/xrLC_Light/xrFace.h deleted file mode 100644 index 84c64ff806d..00000000000 --- a/src/utils/xrLC_Light/xrFace.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include "utils/Shader_xrLC.h" -#include "tcf.h" -#include "base_face.h" -#include "MeshStructure.h" -#include "serialize.h" - -#pragma pack(push, 4) - -struct DataFace; -class CLightmap; - -struct DataVertex; -typedef Tvertex Vertex; - -typedef std::pair PAIR_VV; -typedef xr_map map_v2v; // vertex to vertex translation -typedef map_v2v::iterator map_v2v_it; - -struct XRLC_LIGHT_API DataVertex : public base_Vertex -{ -public: - // vecAdj m_adjacents; - typedef DataFace DataFaceType; - - IC BOOL similar(Tvertex& V, float eps); - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; - - DataVertex(){}; - virtual ~DataVertex(){}; -}; - -typedef Tface Face; - -struct XRLC_LIGHT_API DataFace : public base_Face -{ -public: - // Vertex* v[3]; // vertices - Fvector N; // face normal - - svector<_TCF, 2> tc; // TC - - void* pDeflector; // does the face has LM-UV map? - CLightmap* lmap_layer; - u32 sm_group; - virtual Fvector2* getTC0() { return tc[0].uv; } - BOOL RenderEqualTo(Face* F); - - void AddChannel(Fvector2& p1, Fvector2& p2, Fvector2& p3); - BOOL hasImplicitLighting(); - - virtual void read(INetReader& r); - virtual void write(IWriter& w) const; - - DataFace(){}; - virtual ~DataFace(){}; -}; - -// struct Vertex; -// struct DataVertex; -// struct Face; -class Material; -class Edge; - -// Typedefs -namespace detail -{ -typedef xr_vector::iterator dummy_compiler_treatment; -} // namespace detail - -#include "xrUVpoint.h" - -#include "xrFaceInline.h" - -extern XRLC_LIGHT_API bool g_bUnregister; - -#pragma pack(pop) - -extern "C" XRLC_LIGHT_API void start_unwarp_recursion(); -extern "C" XRLC_LIGHT_API void destroy_vertex(Vertex*& v, bool unregister); - -void destroy_face(Face*& v, bool unregister); - -typedef vector_serialize>> tread_vertices; -typedef vector_serialize>> twrite_vertices; -typedef vector_serialize>> tread_faces; -typedef vector_serialize>> twrite_faces; - -extern twrite_faces* write_faces; -extern tread_faces* read_faces; -extern tread_vertices* read_vertices; -extern twrite_vertices* write_vertices; diff --git a/src/utils/xrLC_Light/xrFaceDefs.h b/src/utils/xrLC_Light/xrFaceDefs.h deleted file mode 100644 index ab43c921d7c..00000000000 --- a/src/utils/xrLC_Light/xrFaceDefs.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -struct DataVertex; -template -struct Tface; -using Face = Tface; - -template -struct Tvertex; -using Vertex = Tvertex; - -using vecVertex = xr_vector; -using vecVertexIt = vecVertex::iterator; - -using vecFace = xr_vector ; -using vecFaceIt = vecFace::iterator ; -using vecFaceCit = vecFace::const_iterator; - -using vec2Face = xr_vector; -using splitIt = vec2Face::iterator; - -using vecAdj = vecFace; -using vecAdjIt = vecAdj::iterator; diff --git a/src/utils/xrLC_Light/xrFaceInline.h b/src/utils/xrLC_Light/xrFaceInline.h deleted file mode 100644 index 25c6996390e..00000000000 --- a/src/utils/xrLC_Light/xrFaceInline.h +++ /dev/null @@ -1,2 +0,0 @@ - -IC BOOL DataVertex::similar(Vertex& V, float eps) { return P.similar(V.P, eps); } diff --git a/src/utils/xrLC_Light/xrImage_Filter.cpp b/src/utils/xrLC_Light/xrImage_Filter.cpp deleted file mode 100644 index 62512180500..00000000000 --- a/src/utils/xrLC_Light/xrImage_Filter.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "stdafx.h" -#include "xrImage_Filter.h" - -float imk_blur_gauss[7][7] = {{0, 0, 0, 5, 0, 0, 0}, {0, 5, 18, 32, 18, 5, 0}, {0, 18, 64, 100, 64, 18, 0}, - {5, 32, 100, 100, 100, 32, 5}, {0, 18, 64, 100, 64, 18, 0}, {0, 5, 18, 32, 18, 5, 0}, {0, 0, 0, 5, 0, 0, 0}}; - -/* Un-optimized code to perform general image filtering -outputs to dst using a filter kernel in ker which must be a 2D float -array of size [2*k+1][2*k+1] */ -void imf_BuildKernel(float* dest, float* src, int DIM, float norm) -{ - float *I, *E; - - float sum = 0; - int size = 2 * DIM + 1; - E = src + (size * size); - for (I = src; I != E; I++) - sum += *I; - float scale = norm / sum; - for (I = src; I != E; I++) - *dest++ = *I * scale; -} -void imf_ProcessKernel(Fvector* dest, Fvector* src, int w, int h, float* kern, int DIM) -{ - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - Fvector total; - total.set(0, 0, 0); - float* kp = kern; - for (int j = -DIM; j <= DIM; j++) - for (int i = -DIM; i <= DIM; i++) - { - int x2 = x + i, y2 = y + j; - - // wrap pixels - if (x2 < 0) - x2 += w; - else if (x2 >= w) - x2 -= w; - if (y2 < 0) - y2 += h; - else if (y2 >= h) - y2 -= h; - - total.mad(total, src[y2 * w + x2], *kp); - kp++; - } - dest->set(total); - dest++; - } - } -} diff --git a/src/utils/xrLC_Light/xrImage_Filter.h b/src/utils/xrLC_Light/xrImage_Filter.h deleted file mode 100644 index f9e47986ad7..00000000000 --- a/src/utils/xrLC_Light/xrImage_Filter.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -void imf_BuildKernel(float* dest, float* src, int DIM, float norm = 1.f); -void imf_ProcessKernel(Fvector* dest, Fvector* src, int w, int h, float* kern, int DIM); - -// some filters -extern float imk_blur_gauss[7][7]; diff --git a/src/utils/xrLC_Light/xrImage_Resampler.cpp b/src/utils/xrLC_Light/xrImage_Resampler.cpp deleted file mode 100644 index e935f42b55f..00000000000 --- a/src/utils/xrLC_Light/xrImage_Resampler.cpp +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Filtered Image Rescaling - * - * by Dale Schumacher - */ - -#include "stdafx.h" -#pragma hdrstop - -#include "xrImage_Resampler.h" - -typedef u32 Pixel; -struct Image -{ - int xsize; /* horizontal size of the image in Pixels */ - int ysize; /* vertical size of the image in Pixels */ - Pixel* data; /* pointer to first scanline of image */ - int span; /* byte offset between two scanlines */ -}; - -/* - * generic image access and i/o support routines - */ - -Image* new_image(int xsize, int ysize) /* create a blank image */ -{ - Image* image; - - if ((0 != (image = (Image*)xr_malloc(sizeof(Image)))) && - (0 != (image->data = (Pixel*)xr_malloc(ysize * xsize * sizeof(Pixel))))) - { - ZeroMemory(image->data, ysize * xsize * sizeof(Pixel)); - image->xsize = xsize; - image->ysize = ysize; - image->span = xsize; - } - return (image); -} - -void free_image(Image* image) -{ - xr_free(image->data); - xr_free(image); -} - -Pixel get_pixel(Image* image, int x, int y) -{ - if ((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) - return 0; - return image->data[(y * image->span) + x]; -} - -void get_row(Pixel* row, Image* image, int y) -{ - if ((y < 0) || (y >= image->ysize)) - return; - CopyMemory(row, image->data + (y * image->span), (sizeof(Pixel) * image->xsize)); -} - -void get_column(Pixel* column, Image* image, int x) -{ - int i, d; - Pixel* p; - - if ((x < 0) || (x >= image->xsize)) - return; - - d = image->span; - for (i = image->ysize, p = image->data + x; i-- > 0; p += d) - { - *column++ = *p; - } -} - -Pixel put_pixel(Image* image, int x, int y, Pixel data) -{ - if ((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) - return 0; - return image->data[(y * image->span) + x] = data; -} - -/* - * filter function definitions - */ - -// -constexpr float filter_support = 1.0f; -float filter(float t) -{ - /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */ - if (t < 0.0) - t = -t; - if (t < 1.0) - return float((2.0 * t - 3.0) * t * t + 1.0); - return (0.0); -} - -// -constexpr float box_support = 0.5f; -float box_filter(float t) -{ - if ((t > -0.5) && (t <= 0.5)) - return (1.0); - return (0.0); -} - -// -constexpr float triangle_support = 1.0f; -float triangle_filter(float t) -{ - if (t < 0.0f) - t = -t; - if (t < 1.0f) - return (1.0f - t); - return (0.0f); -} - -// -constexpr float bell_support = 1.5f; -float bell_filter(float t) /* box (*) box (*) box */ -{ - if (t < 0) - t = -t; - if (t < .5) - return float(.75 - (t * t)); - if (t < 1.5) - { - t = (t - 1.5f); - return (.5f * (t * t)); - } - return (0.0); -} - -// -constexpr float B_spline_support = 2.0f; -float B_spline_filter(float t) /* box (*) box (*) box (*) box */ -{ - if (t < 0) - t = -t; - if (t < 1) - { - const float tt = t * t; - return ((.5f * tt * t) - tt + (2.0f / 3.0f)); - } - else if (t < 2) - { - t = 2 - t; - return ((1.0f / 6.0f) * (t * t * t)); - } - return (0.0f); -} - -// -constexpr float Lanczos3_support = 3.0f; -float sinc(float x) -{ - x *= 3.1415926f; - if (x != 0) - return (_sin(x) / x); - return (1.0); -} -float Lanczos3_filter(float t) -{ - if (t < 0) - t = -t; - if (t < 3.0f) - return float(sinc(t) * sinc(t / 3.0f)); - return (0.0); -} - -// -constexpr float Mitchell_support = 2.0f; - -float Mitchell_filter(float t) -{ - constexpr float B = 1.0f / 3.0f; - constexpr float C = 1.0f / 3.0f; - - const float tt = t * t; - if (t < 0) - t = -t; - if (t < 1.0f) - { - t = (((12.0f - 9.0f * B - 6.0f * C) * (t * tt)) + ((-18.0f + 12.0f * B + 6.0f * C) * tt) + (6.0f - 2.0f * B)); - return (t / 6.0f); - } - else if (t < 2.0f) - { - t = (((-1.0f * B - 6.0f * C) * (t * tt)) + ((6.0f * B + 30.0f * C) * tt) + ((-12.0f * B - 48.0f * C) * t) + - (8.0f * B + 24.f * C)); - return (t / 6.0f); - } - return (0.0); -} - -/* - * image rescaling routine - */ - -struct CONTRIB -{ - int pixel; - float weight; -}; - -struct CLIST -{ - int n; /* number of contributors */ - CONTRIB* p; /* pointer to _list_ of contributions */ -}; - -u32 CC(float a) -{ - int p = iFloor(float(a) + .5f); - if (p < 0) - return 0; - else if (p > 255) - return 255; - return p; -} - -void imf_Process(u32* dstI, u32 dstW, u32 dstH, u32* srcI, u32 srcW, u32 srcH, EIMF_Type FILTER) -{ - R_ASSERT(dstI); - R_ASSERT(dstW > 1); - R_ASSERT(dstH > 1); - R_ASSERT(srcI); - R_ASSERT(srcW > 1); - R_ASSERT(srcH > 1); - - // SRC & DST images - Image src; - src.xsize = srcW; - src.ysize = srcH; - src.data = srcI; - src.span = srcW; - Image dst; - dst.xsize = dstW; - dst.ysize = dstH; - dst.data = dstI; - dst.span = dstW; - - // Select filter - float (*filterf)(float); - filterf = 0; - float fwidth = 0; - switch (FILTER) - { - case imf_filter: - filterf = filter; - fwidth = filter_support; - break; - case imf_box: - filterf = box_filter; - fwidth = box_support; - break; - case imf_triangle: - filterf = triangle_filter; - fwidth = triangle_support; - break; - case imf_bell: - filterf = bell_filter; - fwidth = bell_support; - break; - case imf_b_spline: - filterf = B_spline_filter; - fwidth = B_spline_support; - break; - case imf_lanczos3: - filterf = Lanczos3_filter; - fwidth = Lanczos3_support; - break; - case imf_mitchell: - filterf = Mitchell_filter; - fwidth = Mitchell_support; - break; - } - - // - Image* tmp = 0; /* intermediate image */ - float xscale = 0, yscale = 0; /* zoom scale factors */ - int i, j, k; /* loop variables */ - int n; /* pixel number */ - float center, left, right; /* filter calculation variables */ - float width, fscale, weight; /* filter calculation variables */ - Pixel* raster = 0; /* a row or column of pixels */ - CLIST* contrib = 0; /* array of contribution lists */ - - /* create intermediate image to hold horizontal zoom */ - try - { - tmp = new_image(dst.xsize, src.ysize); - xscale = float(dst.xsize) / float(src.xsize); - yscale = float(dst.ysize) / float(src.ysize); - } - catch (...) - { - Msg("imf_Process::1"); - }; - - /* pre-calculate filter contributions for a row */ - try - { - contrib = (CLIST*)xr_malloc(dst.xsize * sizeof(CLIST)); - ZeroMemory(contrib, dst.xsize * sizeof(CLIST)); - } - catch (...) - { - Msg("imf_Process::2"); - }; - if (xscale < 1.0) - { - try - { - width = fwidth / xscale; - fscale = 1.0f / xscale; - for (i = 0; i < dst.xsize; ++i) - { - contrib[i].n = 0; - contrib[i].p = (CONTRIB*)xr_malloc((int)(width * 2 + 1) * sizeof(CONTRIB)); - ZeroMemory(contrib[i].p, (int)(width * 2 + 1) * sizeof(CONTRIB)); - center = float(i) / xscale; - left = ceil(center - width); - right = floor(center + width); - for (j = int(left); j <= int(right); ++j) - { - weight = center - float(j); - weight = filterf(weight / fscale) / fscale; - if (j < 0) - { - n = -j; - } - else if (j >= src.xsize) - { - n = (src.xsize - j) + src.xsize - 1; - } - else - { - n = j; - } - k = contrib[i].n++; - contrib[i].p[k].pixel = (n < src.xsize) ? n : (src.xsize - 1); - contrib[i].p[k].weight = weight; - } - } - } - catch (...) - { - Msg("imf_Process::3 (xscale<1.0)"); - }; - } - else - { - try - { - for (i = 0; i < dst.xsize; ++i) - { - contrib[i].n = 0; - contrib[i].p = (CONTRIB*)xr_malloc((int)(fwidth * 2 + 1) * sizeof(CONTRIB)); - ZeroMemory(contrib[i].p, (int)(fwidth * 2 + 1) * sizeof(CONTRIB)); - center = float(i) / xscale; - left = ceil(center - fwidth); - right = floor(center + fwidth); - for (j = int(left); j <= int(right); ++j) - { - weight = center - (float)j; - weight = (*filterf)(weight); - if (j < 0) - { - n = -j; - } - else if (j >= src.xsize) - { - n = (src.xsize - j) + src.xsize - 1; - } - else - { - n = j; - } - k = contrib[i].n++; - contrib[i].p[k].pixel = (n < src.xsize) ? n : (src.xsize - 1); - contrib[i].p[k].weight = weight; - } - } - } - catch (...) - { - Msg("imf_Process::3 (xscale>1.0)"); - }; - } - - /* apply filter to zoom horizontally from src to tmp */ - try - { - raster = (Pixel*)xr_malloc(src.xsize * sizeof(Pixel)); - ZeroMemory(raster, src.xsize * sizeof(Pixel)); - } - catch (...) - { - Msg("imf_Process::4"); - }; - try - { - for (k = 0; k < tmp->ysize; ++k) - { - get_row(raster, &src, k); - for (i = 0; i < tmp->xsize; ++i) - { - float w_r = 0., w_g = 0., w_b = 0., w_a = 0.; - - for (j = 0; j < contrib[i].n; ++j) - { - float W = contrib[i].p[j].weight; - Pixel P = raster[contrib[i].p[j].pixel]; - w_r += W * float(color_get_R(P)); - w_g += W * float(color_get_G(P)); - w_b += W * float(color_get_B(P)); - w_a += W * float(color_get_A(P)); - } - put_pixel(tmp, i, k, color_rgba(CC(w_r), CC(w_g), CC(w_b), CC(w_a + 0.5f))); - } - } - xr_free(raster); - } - catch (...) - { - Msg("imf_Process::5"); - }; - - /* xr_free the memory allocated for horizontal filter weights */ - try - { - for (i = 0; i < tmp->xsize; ++i) - xr_free(contrib[i].p); - xr_free(contrib); - } - catch (...) - { - Msg("imf_Process::6"); - }; - - /* pre-calculate filter contributions for a column */ - try - { - contrib = (CLIST*)xr_malloc(dst.ysize * sizeof(CLIST)); - ZeroMemory(contrib, dst.ysize * sizeof(CLIST)); - } - catch (...) - { - Msg("imf_Process::7"); - }; - if (yscale < 1.0) - { - try - { - width = fwidth / yscale; - fscale = 1.0f / yscale; - for (i = 0; i < dst.ysize; ++i) - { - contrib[i].n = 0; - contrib[i].p = (CONTRIB*)xr_malloc((int)(width * 2 + 1) * sizeof(CONTRIB)); - ZeroMemory(contrib[i].p, (int)(width * 2 + 1) * sizeof(CONTRIB)); - center = (float)i / yscale; - left = ceil(center - width); - right = floor(center + width); - for (j = int(left); j <= int(right); ++j) - { - weight = center - (float)j; - weight = filterf(weight / fscale) / fscale; - if (j < 0) - { - n = -j; - } - else if (j >= tmp->ysize) - { - n = (tmp->ysize - j) + tmp->ysize - 1; - } - else - { - n = j; - } - k = contrib[i].n++; - contrib[i].p[k].pixel = (n < tmp->ysize) ? n : (tmp->ysize - 1); - contrib[i].p[k].weight = weight; - } - } - } - catch (...) - { - Msg("imf_Process::8 (yscale<1.0)"); - }; - } - else - { - try - { - for (i = 0; i < dst.ysize; ++i) - { - contrib[i].n = 0; - contrib[i].p = (CONTRIB*)xr_malloc((int)(fwidth * 2 + 1) * sizeof(CONTRIB)); - ZeroMemory(contrib[i].p, (int)(fwidth * 2 + 1) * sizeof(CONTRIB)); - center = (float)i / yscale; - left = ceil(center - fwidth); - right = floor(center + fwidth); - for (j = int(left); j <= int(right); ++j) - { - weight = center - (float)j; - weight = (*filterf)(weight); - if (j < 0) - { - n = -j; - } - else if (j >= tmp->ysize) - { - n = (tmp->ysize - j) + tmp->ysize - 1; - } - else - { - n = j; - } - k = contrib[i].n++; - contrib[i].p[k].pixel = (n < tmp->ysize) ? n : (tmp->ysize - 1); - contrib[i].p[k].weight = weight; - } - } - } - catch (...) - { - Msg("imf_Process::8 (yscale>1.0)"); - }; - } - - /* apply filter to zoom vertically from tmp to dst */ - try - { - raster = (Pixel*)xr_malloc(tmp->ysize * sizeof(Pixel)); - ZeroMemory(raster, tmp->ysize * sizeof(Pixel)); - } - catch (...) - { - Msg("imf_Process::9"); - }; - try - { - for (k = 0; k < dst.xsize; ++k) - { - get_column(raster, tmp, k); - for (i = 0; i < dst.ysize; ++i) - { - float w_r = 0., w_g = 0., w_b = 0., w_a = 0.; - - for (j = 0; j < contrib[i].n; ++j) - { - float W = contrib[i].p[j].weight; - Pixel P = raster[contrib[i].p[j].pixel]; - w_r += W * float(color_get_R(P)); - w_g += W * float(color_get_G(P)); - w_b += W * float(color_get_B(P)); - w_a += W * float(color_get_A(P)); - } - put_pixel(&dst, k, i, color_rgba(CC(w_r), CC(w_g), CC(w_b), CC(w_a + 0.5f))); - } - } - xr_free(raster); - } - catch (...) - { - Msg("imf_Process::A"); - }; - - /* xr_free the memory allocated for vertical filter weights */ - try - { - for (i = 0; i < dst.ysize; ++i) - xr_free(contrib[i].p); - xr_free(contrib); - } - catch (...) - { - Msg("imf_Process::B"); - }; - - free_image(tmp); -} diff --git a/src/utils/xrLC_Light/xrImage_Resampler.h b/src/utils/xrLC_Light/xrImage_Resampler.h deleted file mode 100644 index 6de49808f28..00000000000 --- a/src/utils/xrLC_Light/xrImage_Resampler.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef xrImage_ResamplerH -#define xrImage_ResamplerH - -#pragma once - -enum EIMF_Type : u32 -{ - imf_filter = 0, - imf_box, - imf_triangle, - imf_bell, - imf_b_spline, - imf_lanczos3, - imf_mitchell, -}; -XRLC_LIGHT_API void imf_Process(u32* dst, u32 dstW, u32 dstH, u32* src, u32 srcW, u32 srcH, EIMF_Type FILTER); - -#endif diff --git a/src/utils/xrLC_Light/xrIsect.h b/src/utils/xrLC_Light/xrIsect.h deleted file mode 100644 index 32d2de75703..00000000000 --- a/src/utils/xrLC_Light/xrIsect.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once - -/* lines_intersect: AUTHOR: Mukesh Prasad - * - * This function computes whether two line segments, - * respectively joining the input points (x1,y1) -- (x2,y2) - * and the input points (x3,y3) -- (x4,y4) intersect. - * If the lines intersect, the output variables x, y are - * set to coordinates of the point of intersection. - * - * All values are in integers. The returned value is rounded - * to the nearest integer point. - * - * If non-integral grid points are relevant, the function - * can easily be transformed by substituting floating point - * calculations instead of integer calculations. - * - * Entry - * x1, y1, x2, y2 Coordinates of endpoints of one segment. - * x3, y3, x4, y4 Coordinates of endpoints of other segment. - * - * Exit - * x, y Coordinates of intersection point. - * - * The value returned by the function is one of: - * - * DONT_INTERSECT 0 - * DO_INTERSECT 1 - * COLLINEAR 2 - * - * Error conditions: - * - * Depending upon the possible ranges, and particularly on 16-bit - * computers, care should be taken to protect from overflow. - * - * In the following code, 'long' values have been used for this - * purpose, instead of 'int'. - * - */ - -#define LI_NONE 0 -#define LI_COLLINEAR 0 -#define LI_INTERSECT 1 -#define LI_EQUAL 2 - -ICF int lines_intersect(float x1, float y1, /* First line segment */ - float x2, float y2, - - float x3, float y3, /* Second line segment */ - float x4, float y4, - - float* x, float* y /* Output value: point of intersection */ - ) -{ - float a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */ - float r1, r2, r3, r4; /* 'Sign' values */ - float denom, num; /* Intermediate values */ - - /* Compute a1, b1, c1, where line joining points 1 and 2 - * is "a1 x + b1 y + c1 = 0". -*/ - - a1 = y2 - y1; - b1 = x1 - x2; - c1 = x2 * y1 - x1 * y2; - - /* Compute r3 and r4. - */ - - r3 = a1 * x3 + b1 * y3 + c1; - r4 = a1 * x4 + b1 * y4 + c1; - - /* Check signs of r3 and r4. If both point 3 and point 4 lie on - * same side of line 1, the line segments do not intersect. - */ - - if (r3 * r4 > 0) - return (LI_NONE); - - /* Compute a2, b2, c2 */ - - a2 = y4 - y3; - b2 = x3 - x4; - c2 = x4 * y3 - x3 * y4; - - /* Compute r1 and r2 */ - - r1 = a2 * x1 + b2 * y1 + c2; - r2 = a2 * x2 + b2 * y2 + c2; - - /* Check signs of r1 and r2. If both point 1 and point 2 lie - * on same side of second line segment, the line segments do - * not intersect. - */ - - if (r1 * r2 > 0) - return (LI_NONE); - - // Check for equality - if (_abs(r1 * r2) < EPS_S && _abs(r3 * r4) < EPS_S) - return LI_NONE; - - /* Line segments intersect: compute intersection point. - */ - - denom = a1 * b2 - a2 * b1; - if (_abs(denom) < EPS) - return (LI_COLLINEAR); - - num = b1 * c2 - b2 * c1; - *x = num / denom; - - num = a2 * c1 - a1 * c2; - *y = num / denom; - - return (LI_INTERSECT); -} /* lines_intersect */ diff --git a/src/utils/xrLC_Light/xrLC_GlobalData.cpp b/src/utils/xrLC_Light/xrLC_GlobalData.cpp deleted file mode 100644 index 577763971b8..00000000000 --- a/src/utils/xrLC_Light/xrLC_GlobalData.cpp +++ /dev/null @@ -1,617 +0,0 @@ -#include "stdafx.h" - -#include "xrLC_GlobalData.h" -#include "xrface.h" -#include "xrdeflector.h" -#include "lightmap.h" -#include "serialize.h" -#include "mu_model_face.h" -#include "xrmu_model.h" -#include "xrmu_model_reference.h" -#include "xrCDB/xrCDB.h" -#include "base_face_ptr_storage.h" - -bool g_using_smooth_groups = true; -bool g_smooth_groups_by_faces = false; - -xrLC_GlobalData* g_lc_global_data = 0; - -tread_lightmaps* read_lightmaps = 0; -twrite_lightmaps* write_lightmaps = 0; - -twrite_faces* write_faces = 0; -tread_faces* read_faces = 0; -tread_vertices* read_vertices = 0; -twrite_vertices* write_vertices = 0; -tread_deflectors* read_deflectors = 0; -twrite_deflectors* write_deflectors = 0; - -tread_models* read_models = 0; -twrite_models* write_models = 0; -tread_mu_refs* read_mu_refs = 0; -twrite_mu_refs* write_mu_refs = 0; - -xrLC_GlobalData* lc_global_data() { return g_lc_global_data; } -void create_global_data() -{ - VERIFY(!inlc_global_data()); - g_lc_global_data = xr_new(); -} -void destroy_global_data() -{ - VERIFY(inlc_global_data()); - if (g_lc_global_data) - g_lc_global_data->clear(); - xr_delete(g_lc_global_data); -} - -xrLC_GlobalData::xrLC_GlobalData() : _b_nosun(false), _gl_linear(false), b_vert_not_register(false) -{ - _cl_globs._RCAST_Model = 0; - write_faces = xr_new(&_g_faces); - read_faces = xr_new(&_g_faces); -} - -// void xrLC_GlobalData ::create_write_faces() const -//{ -// VERIFY(!write_faces); -// //write_faces = new twrite_faces( &_g_faces ); -//} -// void xrLC_GlobalData::destroy_write_faces() const -//{ -// -// //xr_delete(write_faces); -//} - -// twrite_faces* xrLC_GlobalData::get_write_faces() -//{ -// return write_faces; -//} - -// void xrLC_GlobalData ::create_read_faces() -//{ -// //VERIFY(!read_faces); -// //read_faces = new tread_faces( &_g_faces ); -//} -// void xrLC_GlobalData::destroy_read_faces() -//{ -// -// //xr_delete(read_faces); -//} -// tread_faces * xrLC_GlobalData::get_read_faces() -//{ -// return read_faces; -//} -/* -poolVertices &xrLC_GlobalData ::VertexPool () -{ - return _VertexPool; -} -poolFaces &xrLC_GlobalData ::FacePool () -{ - return _FacePool; -} -*/ - -void xrLC_GlobalData::destroy_rcmodel() { xr_delete(_cl_globs._RCAST_Model); } -void xrLC_GlobalData::clear_build_textures_surface() -{ - Logger.clLog("mem usage before clear build textures surface: %u", Memory.mem_usage()); - // xr_vector _textures; - xr_vector::iterator i = textures().begin(); - xr_vector::const_iterator e = textures().end(); - for (; i != e; ++i) - ::clear((*i)); - Memory.mem_compact(); - Logger.clLog("mem usage after clear build textures surface: %u", Memory.mem_usage()); -} -void xrLC_GlobalData::clear_build_textures_surface(const xr_vector& exept) -{ - Logger.clLog("mem usage before clear build textures surface: %u", Memory.mem_usage()); - xr_vector::iterator i = textures().begin(); - xr_vector::const_iterator e = textures().end(); - xr_vector::const_iterator b = textures().begin(); - for (; i != e; ++i) - { - xr_vector::const_iterator ff = std::find(exept.begin(), exept.end(), u32(i - b)); - if (ff == exept.end()) - ::clear((*i)); - } - Memory.mem_compact(); - Logger.clLog("mem usage after clear build textures surface: %u", Memory.mem_usage()); -} - -void xrLC_GlobalData::create_rcmodel(CDB::CollectorPacked& CL) -{ - VERIFY(!_cl_globs._RCAST_Model); - _cl_globs._RCAST_Model = xr_new(); - _cl_globs._RCAST_Model->build(CL.getV(), (int)CL.getVS(), CL.getT(), (int)CL.getTS()); -} - -void xrLC_GlobalData::initialize() -{ - if (strstr(Core.Params, "-att")) - _gl_linear = true; -} - -/* - xr_vector _textures; - xr_vector _materials; - Shader_xrLC_LIB _shaders; - CMemoryWriter _err_invalid; - b_params _g_params; - vecVertex _g_vertices; - vecFace _g_faces; - vecDefl _g_deflectors; - base_lighting _L_static; - CDB::MODEL* _RCAST_Model; - bool _b_nosun; - bool _gl_linear; -*/ - -// void xrLC_GlobalData :: cdb_read_create () -//{ -// VERIFY(!_RCAST_Model); -// _RCAST_Model = new CDB::MODEL (); -// _RCAST_Model->build( &*verts.begin(), (int)verts.size(), &*tris.begin(), (int)tris.size() ); -//} - -// base_Face* F = (base_Face*)(*((void**)&T.dummy)); - -//*((u32*)&F) - -void write(IWriter& w, const CDB::TRI& tri) -{ - w.w_u32(tri.verts[0]); - w.w_u32(tri.verts[1]); - w.w_u32(tri.verts[2]); -} -void write(IWriter& w, const CDB::TRI& tri, const xrLC_GlobalData& lc_global_data) -{ - ::write(w, tri); - const base_Face* F = get_base_face_pointer(tri); - VERIFY(&lc_global_data); - lc_global_data.write(w, F); -} - -void read(INetReader& r, CDB::TRI& tri) -{ - tri.verts[0] = r.r_u32(); - tri.verts[1] = r.r_u32(); - tri.verts[2] = r.r_u32(); -} - -void read(INetReader& r, CDB::TRI& tri, xrLC_GlobalData& lc_global_data) -{ - ::read(r, tri); - VERIFY(&lc_global_data); - base_Face* F = 0; - lc_global_data.read(r, F); - store_base_face_pointer(tri, F); -} - -static xr_vector verts; -static xr_vector tris; - -void read(INetReader& r, CDB::MODEL*& m, xrLC_GlobalData& lc_global_data) -{ - verts.clear(); - tris.clear(); - r_pod_vector(r, verts); - - u32 tris_count = r.r_u32(); - tris.resize(tris_count); - for (u32 i = 0; i < tris_count; ++i) - ::read(r, tris[i], lc_global_data); - - VERIFY(!m); - m = xr_new(); - m->build(&*verts.begin(), (int)verts.size(), &*tris.begin(), (int)tris.size()); - verts.clear(); - tris.clear(); -} - -void read(INetReader& r, CDB::MODEL& m) -{ - verts.clear(); - tris.clear(); - r_pod_vector(r, verts); - u32 tris_count = r.r_u32(); - tris.resize(tris_count); - for (u32 i = 0; i < tris_count; ++i) - ::read(r, tris[i]); - m.build(&*verts.begin(), (int)verts.size(), &*tris.begin(), (int)tris.size()); - verts.clear(); - tris.clear(); -} - -void write(IWriter& w, const CDB::MODEL& m) -{ - w.w_u32((u32)m.get_verts_count()); - w.w(m.get_verts(), m.get_verts_count() * sizeof(Fvector)); - - u32 tris_count = (u32)m.get_tris_count(); - w.w_u32(tris_count); - for (u32 i = 0; i < tris_count; ++i) - ::write(w, m.get_tris()[i]); - - // w.w( m.get_tris(), m.get_tris_count() * sizeof(CDB::TRI) ); -} - -void write(IWriter& w, const CDB::MODEL& m, const xrLC_GlobalData& lc_global_data) -{ - w.w_u32((u32)m.get_verts_count()); - w.w(m.get_verts(), m.get_verts_count() * sizeof(Fvector)); - - u32 tris_count = (u32)m.get_tris_count(); - w.w_u32(tris_count); - for (u32 i = 0; i < tris_count; ++i) - ::write(w, m.get_tris()[i], lc_global_data); - - // w.w( m.get_tris(), m.get_tris_count() * sizeof(CDB::TRI) ); -} - -void xrLC_GlobalData::read_base(INetReader& r) -{ - _b_nosun = !!r.r_u8(); - _gl_linear = !!r.r_u8(); - r_pod(r, _cl_globs._g_params); - - _cl_globs._L_static.read(r); - - r_vector(r, _cl_globs._textures); - r_pod_vector(r, _cl_globs._materials); - r_pod_vector(r, _cl_globs._shaders.Library()); - // CMemoryWriter _err_invalid; - - read_lightmaps = xr_new(&_g_lightmaps); - read_lightmaps->read(r); - - // - read_mu_models(r); - // -} -void xrLC_GlobalData::write_base(IWriter& w) const -{ - ///////////////////////////////////////////////////////// - w.w_u8(_b_nosun); - w.w_u8(_gl_linear); - w_pod(w, _cl_globs._g_params); - - _cl_globs._L_static.write(w); - - w_vector(w, _cl_globs._textures); - w_pod_vector(w, _cl_globs._materials); - w_pod_vector(w, _cl_globs._shaders.Library()); - // CMemoryWriter _err_invalid; - write_lightmaps = xr_new(&_g_lightmaps); - write_lightmaps->write(w); - - write_mu_models(w); - //////////////////////////////////////////////////////////////////////////// -} - -void xrLC_GlobalData::read(INetReader& r) -{ - // read_faces = new tread_faces( &_g_faces ); - read_faces->read(r); - - ::read(r, _cl_globs._RCAST_Model, *this); - - close_models_read(); - xr_delete(read_lightmaps); - // xr_delete( read_faces ); - - // read_lm_data( r ); -} - -void xrLC_GlobalData::write(IWriter& w) const -{ - // write_faces = new twrite_faces( &_g_faces ); - write_faces->write(w); - - // write_models - ::write(w, *_cl_globs._RCAST_Model, *this); - close_models_write(); - xr_delete(write_lightmaps); - // xr_delete( write_faces ); - - // write_lm_data ( w ); -} - -void xrLC_GlobalData::mu_models_calc_materials() -{ - for (u32 m = 0; m < mu_models().size(); m++) - mu_models()[m]->calc_materials(); -} - -void xrLC_GlobalData::read_lm_data(INetReader& r) -{ - read_vertices(r); - read_deflectors = xr_new(&_g_deflectors); - // create_read_faces(); - read_deflectors->read(r); - // destroy_read_faces(); - xr_delete(::read_vertices); - xr_delete(read_deflectors); -} -void xrLC_GlobalData::write_lm_data(IWriter& w) const -{ - write_vertices(w); - write_deflectors = xr_new(&_g_deflectors); - // create_write_faces(); - write_deflectors->write(w); - // destroy_write_faces(); - xr_delete(::write_vertices); - xr_delete(write_deflectors); -} - -void xrLC_GlobalData::read_vertices(INetReader& r) -{ - // not used for light// - ::read_vertices = xr_new(&_g_vertices); - ::read_vertices->read(r); - vecFaceIt i = _g_faces.begin(), e = _g_faces.end(); - for (; e != i; ++i) - (*i)->read_vertices(r); -} -void xrLC_GlobalData::write_vertices(IWriter& w) const -{ - ::write_vertices = xr_new(&(_g_vertices)); - ::write_vertices->write(w); - vecFaceCit i = _g_faces.begin(), e = _g_faces.end(); - for (; e != i; ++i) - (*i)->write_vertices(w); -} -void xrLC_GlobalData::read_mu_models(INetReader& r) -{ - read_models = xr_new(&_mu_models); - read_models->read(r); - xr_delete(read_models); -} -void xrLC_GlobalData::write_mu_models(IWriter& w) const -{ - write_models = xr_new(&_mu_models); - write_models->write(w); - xr_delete(write_models); -} - -void xrLC_GlobalData::read_modes_color(INetReader& r) -{ - xr_vector::iterator i = _mu_models.begin(), e = _mu_models.end(); - for (; e != i; ++i) - (*i)->read_color(r); -} -void xrLC_GlobalData::write_modes_color(IWriter& w) const -{ - xr_vector::const_iterator i = _mu_models.begin(), e = _mu_models.end(); - for (; e != i; ++i) - (*i)->write_color(w); -} - -void xrLC_GlobalData::read_mu_model_refs(INetReader& r) -{ - read_mu_refs = xr_new(&_mu_refs); - read_models = xr_new(&_mu_models); - // - - read_mu_refs->read(r); - - xr_delete(read_models); - xr_delete(read_mu_refs); -} -void xrLC_GlobalData::write_mu_model_refs(IWriter& w) const -{ - write_mu_refs = xr_new(&_mu_refs); - write_models = xr_new(&_mu_models); - - write_mu_refs->write(w); - - xr_delete(write_models); - xr_delete(write_mu_refs); -} - -bool xrLC_GlobalData::b_r_vertices() { return !!::read_vertices; } -// bool xrLC_GlobalData :: b_r_faces () -//{ -// return !!read_faces; -//} - -void xrLC_GlobalData::close_models_read() -{ - xr_vector::iterator i = _mu_models.begin(), e = _mu_models.end(); - for (; e != i; ++i) - (*i)->reading_close(); -} -void xrLC_GlobalData::close_models_write() const -{ - xr_vector::const_iterator i = _mu_models.begin(), e = _mu_models.end(); - for (; e != i; ++i) - (*i)->writting_close(); -} - -template -std::pair get_id(const xr_vector& mu_models, const T* v) -{ - u32 face_id = u32(-1); - struct find - { - const T* _v; - u32& _id; - find(const T* v, u32& id) : _v(v), _id(id) {} - bool operator()(const xrMU_Model* m) - { - VERIFY(m); - u32 id = m->find(_v); - if (id == u32(-1)) - return false; - _id = id; - return true; - } - } f(v, face_id); - - xr_vector::const_iterator ii = std::find_if(mu_models.begin(), mu_models.end(), f); - if (ii == mu_models.end()) - return std::pair(u32(-1), u32(-1)); - return std::pair(u32(ii - mu_models.begin()), face_id); -} - -// std::pair xrLC_GlobalData :: get_id ( const _face * v ) const -//{ -// return ::get_id( _mu_models, v ); -//} -// -// std::pair xrLC_GlobalData :: get_id ( const _vertex * v ) const -//{ -// return ::get_id( _mu_models, v ); -//} -enum serialize_mesh_item_type -{ - smit_plain = u8(0), - smit_model = u8(1), - smit_null = u8(-1) -}; - -void xrLC_GlobalData::read(INetReader& r, base_Face*& f) -{ - VERIFY(!f); - u8 type = r.r_u8(); - - switch (type) - { - case smit_plain: - { - VERIFY(read_faces); - Face* face = 0; - read_faces->read(r, face); - f = face; - return; - } - case smit_model: - { - u32 model_id = r.r_u32(); - _face* model_face = 0; - _mu_models[model_id]->read(r, model_face); - f = model_face; - return; - } - case smit_null: return; - } -} - -void xrLC_GlobalData::write(IWriter& w, const base_Face* f) const -{ - if (!f) - { - w.w_u8(smit_null); - return; - } - - const Face* face = dynamic_cast(f); - if (face) - { - VERIFY(write_faces); - w.w_u8(smit_plain); - write_faces->write(w, face); - return; - } - - const _face* model_face = dynamic_cast(f); - VERIFY(model_face); - - w.w_u8(smit_model); - - std::pair id = get_id(_mu_models, model_face); - - w.w_u32(id.first); - - _mu_models[id.first]->write(w, id.second, model_face); -} - -xrLC_GlobalData::~xrLC_GlobalData() -{ - xr_delete(write_faces); - xr_delete(read_faces); - // u32 i; - // i++; -} - -template -void vec_clear(xr_vector& v) -{ - typename xr_vector::iterator i = v.begin(), e = v.end(); - for (; i != e; ++i) - xr_delete(*i); - v.clear(); -} - -template -void vec_spetial_clear(xr_vector& v) -{ - typename xr_vector::iterator i = v.begin(), e = v.end(); - for (; i != e; ++i) - clear(*i); - v.clear(); -} - -void mu_mesh_clear(); -void xrLC_GlobalData::clear_mu_models() -{ - Logger.clLog("mem usage before mu_clear %d", Memory.mem_usage()); - vec_clear(_mu_models); // not clear ogf - vec_clear(_mu_refs); - mu_mesh_clear(); - Memory.mem_compact(); - Logger.clLog("mem usage after mu_clear: %d", Memory.mem_usage()); -} -void xrLC_GlobalData::clear() -{ - vec_spetial_clear(_cl_globs._textures); - _cl_globs._materials.clear(); - _cl_globs._shaders.Unload(); - // CMemoryWriter _err_invalid; - // b_params _g_params; - close_models_read(); - close_models_write(); - - vec_clear(_g_lightmaps); - vec_clear(_mu_models); // mem leak - vec_clear(_mu_refs); - mu_mesh_clear(); - gl_mesh_clear(); - // VertexPool; - // FacePool; - - // vecVertex _g_vertices; - // vecFace _g_faces; - gl_mesh_clear(); - vec_clear(_g_deflectors); - - // base_lighting _L_static; - xr_delete(_cl_globs._RCAST_Model); - - xr_delete(write_lightmaps); - xr_delete(::write_vertices); - // xr_delete( write_faces ); - xr_delete(write_deflectors); - - xr_delete(read_lightmaps); - xr_delete(::read_vertices); - // xr_delete( read_faces ); - xr_delete(read_deflectors); - // bool _b_nosun; - // bool _gl_linear; -} - -void xrLC_GlobalData::set_faces_indexses() -{ - // const u32 number = g_faces ().size(); - // for( u32 i=0; i< number; ++i ) - // g_faces()[i]->set_index( i ); -} -void xrLC_GlobalData::set_vertices_indexses() -{ - // const u32 number = g_vertices().size(); - // for( u32 i=0; i< number; ++i ) - // g_vertices()[i]->set_index( i ); -} diff --git a/src/utils/xrLC_Light/xrLC_GlobalData.h b/src/utils/xrLC_Light/xrLC_GlobalData.h deleted file mode 100644 index aa2c63f3c6e..00000000000 --- a/src/utils/xrLC_Light/xrLC_GlobalData.h +++ /dev/null @@ -1,161 +0,0 @@ -#pragma once - -#include "utils/Shader_xrLC.h" -#include "xrCore/xrPool.h" -#include "xrfacedefs.h" -#include "xrdeflectordefs.h" -#include "b_build_texture.h" -#include "base_lighting.h" -#include "utils/communicate.h" -// struct _face; -// struct _vertex; -namespace CDB -{ -class MODEL; -class CollectorPacked; -}; -class CLightmap; -class xrMU_Model; -class xrMU_Reference; -class base_Vertex; -class base_Face; - -struct compilers_global_data -{ - xr_vector _textures; - xr_vector _materials; - Shader_xrLC_LIB _shaders; - b_params _g_params; - base_lighting _L_static; - CDB::MODEL* _RCAST_Model; -}; - -class XRLC_LIGHT_API xrLC_GlobalData -{ - compilers_global_data _cl_globs; - - CMemoryWriter _err_invalid; - CMemoryWriter _err_multiedge; - CMemoryWriter _err_tjunction; - xr_vector _g_lightmaps; - xr_vector _mu_models; - xr_vector _mu_refs; - vecVertex _g_vertices; - vecFace _g_faces; - vecDefl _g_deflectors; - - bool _b_nosun; - bool _gl_linear; - -private: - bool b_vert_not_register; - -public: -public: - xrLC_GlobalData(); //:_RCAST_Model (0), _b_nosun(false),_gl_linear(false){} - ~xrLC_GlobalData(); - IC xr_vector& textures() { return _cl_globs._textures; } - IC xr_vector& lightmaps() { return _g_lightmaps; } - IC xr_vector& materials() { return _cl_globs._materials; } - IC Shader_xrLC_LIB& shaders() { return _cl_globs._shaders; } - IC CMemoryWriter& err_invalid() { return _err_invalid; } - IC CMemoryWriter& err_multiedge() { return _err_multiedge; }; - IC CMemoryWriter& err_tjunction() { return _err_tjunction; }; - IC b_params& g_params() { return _cl_globs._g_params; } - Face* create_face(); - void destroy_face(Face*& f); - - Vertex* create_vertex(); - void destroy_vertex(Vertex*& f); - - void vertices_isolate_and_pool_reload(); - - vecVertex& g_vertices() { return _g_vertices; } - vecFace& g_faces() { return _g_faces; } - vecDefl& g_deflectors() { return _g_deflectors; } - bool b_r_vertices(); - bool vert_construct_register() { return !b_r_vertices() && !b_vert_not_register; } - // bool b_r_faces () ; - base_lighting& L_static() { return _cl_globs._L_static; } - CDB::MODEL* RCAST_Model() { return _cl_globs._RCAST_Model; } - xr_vector& mu_models() { return _mu_models; } - xr_vector& mu_refs() { return _mu_refs; } - void read_mu_models(INetReader& r); - void write_mu_models(IWriter& w) const; - - void read_mu_model_refs(INetReader& r); - void write_mu_model_refs(IWriter& w) const; - void close_models_read(); - void close_models_write() const; - - bool b_nosun() { return _b_nosun; } - bool gl_linear() { return _gl_linear; } - IC void b_nosun_set(bool v) { _b_nosun = v; } - void initialize(); - void destroy_rcmodel(); - - void create_rcmodel(CDB::CollectorPacked& CL); - - void clear_build_textures_surface(); - - void clear_build_textures_surface(const xr_vector& exept); - - void set_faces_indexses(); - void set_vertices_indexses(); - // void create_write_faces () const; - // void destroy_write_faces () const; - // void create_read_faces () ; - // void destroy_read_faces () ; - - // tread_faces *get_read_faces () ; - // twrite_faces *get_write_faces () ; - - void gl_mesh_clear(); - -private: - // std::pair get_id ( const _face * v ) const; - // std::pair get_id ( const _vertex * v ) const; -public: - void read_base(INetReader& r); - void write_base(IWriter& w) const; - void read(INetReader& r); - void write(IWriter& w) const; - void read_vertices(INetReader& r); - void write_vertices(IWriter& w) const; - void read_lm_data(INetReader& r); - void write_lm_data(IWriter& w) const; - - void read_modes_color(INetReader& r); - void write_modes_color(IWriter& w) const; - - void read(INetReader& r, base_Face*& f); - void write(IWriter& r, const base_Face* f) const; - void clear(); - void clear_mesh(); - void clear_mu_models(); - void mu_models_calc_materials(); - // void cdb_read_create () ; -private: -}; - -extern "C" XRLC_LIGHT_API xrLC_GlobalData* lc_global_data(); -extern "C" XRLC_LIGHT_API void create_global_data(); -extern "C" XRLC_LIGHT_API void destroy_global_data(); -extern "C" XRLC_LIGHT_API u32 InvalideFaces(); -XRLC_LIGHT_API void ImplicitLighting(BOOL net); - -extern xrLC_GlobalData* g_lc_global_data; -IC xrLC_GlobalData* inlc_global_data() { return g_lc_global_data; } -static LPCSTR gl_data_net_file_name = "tmp_global_data"; - -#ifdef _DEBUG -static LPCSTR libraries = - "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,xrAPI.dll,DXT.dll,BugTrap.dll,BugTrapD.dll,FreeImage.dll," - "msvcr80.dll,Microsoft.VC80.CRT.manifest"; -#else -static LPCSTR libraries = - "XRLC_LightStab.dll,XRLC_Light.dll,xrCore.dll,xrCDB.dll,xrAPI.dll,DXT.dll,BugTrap.dll,FreeImage.dll,msvcr80.dll," - "Microsoft.VC80.CRT.manifest"; -#endif -//#define NET_CMP -//#define LOAD_GL_DATA diff --git a/src/utils/xrLC_Light/xrLC_Light.cpp b/src/utils/xrLC_Light/xrLC_Light.cpp deleted file mode 100644 index e9492fe4bd2..00000000000 --- a/src/utils/xrLC_Light/xrLC_Light.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// xrLC_Light.cpp : Defines the entry point for the DLL application. -// -#include "stdafx.h" -#include "xrLc_globaldata.h" - -#ifdef _MANAGED -#pragma managed(push, off) -#endif - -b_params& g_params() -{ - VERIFY(inlc_global_data()); - return inlc_global_data()->g_params(); -} - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - { - //xrDebug::Initialize(false); - //bool init_log = (0 != xr_strcmp(Core.ApplicationName, "XRayEditorTools")); - //Core.Initialize("xrLC_Light", 0, FALSE); - //if (init_log) - //CreateLog(); - - // FPU::m64r (); - break; - } - case DLL_THREAD_ATTACH: break; - case DLL_THREAD_DETACH: break; - case DLL_PROCESS_DETACH: - if (inlc_global_data()) - destroy_global_data(); - //Core._destroy(); - break; - } - return TRUE; -} - -#ifdef _MANAGED -#pragma managed(pop) -#endif diff --git a/src/utils/xrLC_Light/xrLC_Light.h b/src/utils/xrLC_Light/xrLC_Light.h deleted file mode 100644 index 6f05fd03e6c..00000000000 --- a/src/utils/xrLC_Light/xrLC_Light.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "xrCore/xrCore.h" - -#ifdef XRAY_STATIC_BUILD -#define XRLC_LIGHT_API -#else -# ifdef XRLC_LIGHT_EXPORTS -# define XRLC_LIGHT_API XR_EXPORT -# else -# define XRLC_LIGHT_API XR_IMPORT -# endif -#endif - -#pragma warning(push) -#pragma warning(disable : 4995) -#include -#include -#include -#include -#include -#pragma warning(pop) - -#include "Common/_d3d_extensions.h" -#include "utils/communicate.h" - -static const int edge2idx3[3][3] = {{0, 1, 2}, {1, 2, 0}, {2, 0, 1}}; -static const int edge2idx[3][2] = {{0, 1}, {1, 2}, {2, 0}}; -static const int idx2edge[3][3] = {{-1, 0, 2}, {0, -1, 1}, {2, 1, -1}}; -extern XRLC_LIGHT_API bool g_using_smooth_groups; -extern XRLC_LIGHT_API bool g_smooth_groups_by_faces; - -XRLC_LIGHT_API void xrCompileDO(bool net); -extern "C" XRLC_LIGHT_API b_params& g_params(); - -IC u8 u8_clr(float a) -{ - s32 _a = iFloor(a * 255.f); - clamp(_a, 0, 255); - return u8(_a); -}; - -#ifndef NDEBUG -#define X_TRY -#define X_CATCH if (0) -#else -#define X_TRY try -#define X_CATCH catch (...) -#endif diff --git a/src/utils/xrLC_Light/xrLC_Light.vcxproj b/src/utils/xrLC_Light/xrLC_Light.vcxproj deleted file mode 100644 index e646d7f414a..00000000000 --- a/src/utils/xrLC_Light/xrLC_Light.vcxproj +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - - {EFB76D6F-0092-439C-A783-C0BE10BD17C9} - xrLC_Light - Win32Proj - - - - - - - DynamicLibrary - false - - - - - - - - - - - $(xrBinDir)utils\ - - - - $(SolutionDir)xrQSlim;$(xrSdkDir)include\FreeImage;$(xrExternals)zlib;%(AdditionalIncludeDirectories) - _USRDLL;LEVEL_COMPILER;XRLC_LIGHT_EXPORTS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;%(PreprocessorDefinitions) - false - false - - - FreeImage.lib;FreeImagePlus.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - true - - - - true - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {745dec58-ebb3-47a9-a9b8-4c6627c01bf8} - - - {ebf9b543-0830-4866-9b48-dc0740e87e8a} - - - {b90bdc22-a891-4b33-b562-29d701f65dbd} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/xrLC_Light/xrLC_Light.vcxproj.filters b/src/utils/xrLC_Light/xrLC_Light.vcxproj.filters deleted file mode 100644 index 739f74ad6b9..00000000000 --- a/src/utils/xrLC_Light/xrLC_Light.vcxproj.filters +++ /dev/null @@ -1,575 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {a4aa0f5d-17f9-48f9-a134-2f930e9ea2a6} - - - {6b464701-38df-4d73-8886-7940983025a8} - - - {966949c4-f7ff-4cbf-9164-592e74fb78e3} - - - {2bf14039-c04f-4cc4-a9eb-1d5e65f38744} - - - {17697c46-b969-4b0b-bc0f-b13b4d4dd3bb} - - - {61f42083-93e1-4dab-8f79-93451fe040b2} - - - {44e00911-1ab9-4de3-8f7f-680922655c21} - - - {b1a2e3e8-4757-4aa4-a054-0d313f3eff80} - - - {9f65323a-4cde-4691-9fca-435b6dbce58b} - - - {34af3974-aec2-40f5-8e72-19d533aec247} - - - {7a98aba9-7bd5-472e-9b2b-2d702b2f0b18} - - - {9306c2a6-75c2-438f-944c-748a648c85ff} - - - {e6f7c62f-5ab9-4675-b49a-da9f96fcc21f} - - - {3e80f9fd-a9ed-4051-9cf4-823cbb7163e0} - - - {b4177f40-c75e-4d73-8ff4-1b67764912dc} - - - {4dd18a4e-3257-427f-8374-4dfa68457cc0} - - - {3f4e9acd-cfe4-4ada-9377-19efb8a40e7e} - - - {959cd6f5-3930-40b5-ac94-30c315dcb81e} - - - {0bca0dd1-6b87-4ce2-b545-24aa75ec817a} - - - {e8c8b367-c88b-4e39-9be9-8897dc577f41} - - - - - kernel - - - kernel - - - Light - - - Light\xrLC_GlobalData - - - Light\xrLC_GlobalData - - - Light\Net - - - Light\Net - - - Light\Net - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\task_manager - - - Light\Net\new\task_manager - - - Light\Net\depr - - - Light\Net\depr - - - Light\Net\depr - - - Light\Net\depr - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\serialize - - - Light\Lightmaps - - - Light\Lightmaps - - - Light\Lightmaps - - - Light\Textures - - - Light\Textures - - - Light\Textures - - - Light\Lights - - - Light\Lights - - - Light\Lights - - - Light\color - - - Light\LightVertex - - - do_light - - - do_light - - - do_light - - - do_light - - - do_light - - - do_light - - - - Light\Mesh - - - - - kernel - - - kernel - - - Light\xrLC_GlobalData - - - Light\xrLC_GlobalData - - - Light\Net - - - Light\Net - - - Light\Net - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_gl_data - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\net_user_execution - - - Light\Net\new\task_manager - - - Light\Net\new\task_manager - - - Light\Net\new\task_manager - - - Light\Net\depr - - - Light\Net\depr - - - Light\Net\depr - - - Light\Net\depr - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\models\mu_light - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\LightImplicit - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\xrDeflector - - - Light\Mesh - - - Light\Mesh - - - Light\Mesh - - - Light\serialize - - - Light\Lightmaps - - - Light\Lightmaps - - - Light\Lightmaps - - - Light\Textures - - - Light\Textures - - - Light\Textures - - - Light\Lights - - - Light\color - - - Light\LightVertex - - - Light\LightVertex - - - do_light - - - do_light - - - do_light - - - do_light - - - do_light - - - do_light - - - do_light - - - kernel - - - do_light - - - - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrLC_Light/xrLightDoNet.cpp b/src/utils/xrLC_Light/xrLightDoNet.cpp deleted file mode 100644 index 490c2632ee7..00000000000 --- a/src/utils/xrLC_Light/xrLightDoNet.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "xrLightDoNet.h" -#include "global_calculation_data.h" -#include "detail_slot_calculate.h" -#include "net_execution_detail_light.h" -#include "detail_net_global_data.h" -#include "net_execution_factory.h" -#include "lcnet_task_manager.h" - -namespace lc_net -{ -void xrNetDOLight() -{ - get_task_manager().startup(); - ///////////////////////////////////////////////////////////////////// - gl_data.slots_data.process_all_pallete(); - lc_net::globals().get().init(); - ////////////////////////////////////////////////////////////////////// - // for ( u32 _z=0; _z *el = lc_net::execution_factory.create(); - // el->implementation( ).construct( _x, _z ); - // get_task_manager().add_task( el ); - // } - //} - - u32 start = 0; - u32 end = 0; - u32 task_slots_number = 0; - const u32 max_task_slots_number = 100; - const u32 slot_count = gl_data.slots_data.header().slot_count(); - do - { - int x, z; - gl_data.slots_data.header().slot_x_z(end, x, z); - ++end; - if (gl_data.slots_data.calculate_ignore(x, z)) - continue; - ++task_slots_number; - if (task_slots_number == max_task_slots_number || end == slot_count) - { - tnet_execution_base* el = lc_net::execution_factory.create(); - el->implementation().construct(start, end); - get_task_manager().add_task(el); - start = end; - task_slots_number = 0; - } - } while (end != slot_count); - - ////////////////////////////////////////////////////////////////////////// - get_task_manager().run("Net Detail Lighting"); - get_task_manager().wait_all(); - get_task_manager().release(); -} -} diff --git a/src/utils/xrLC_Light/xrLightDoNet.h b/src/utils/xrLC_Light/xrLightDoNet.h deleted file mode 100644 index adec71ee889..00000000000 --- a/src/utils/xrLC_Light/xrLightDoNet.h +++ /dev/null @@ -1,13 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Created : 27.03.2009 -// Author : Konstantin Slipchenko -// Copyright (C) GSC Game World - 2009 -//////////////////////////////////////////////////////////////////////////// - -#ifndef XRLIGHTDONET_H_INCLUDED -#define XRLIGHTDONET_H_INCLUDED -namespace lc_net -{ -void xrNetDOLight(); -} -#endif // #ifndef XRLIGHTDONET_H_INCLUDED diff --git a/src/utils/xrLC_Light/xrLightVertex.cpp b/src/utils/xrLC_Light/xrLightVertex.cpp deleted file mode 100644 index d7b0ffab7f1..00000000000 --- a/src/utils/xrLC_Light/xrLightVertex.cpp +++ /dev/null @@ -1,215 +0,0 @@ -#include "stdafx.h" -#include "xrLightVertex.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrface.h" -#include "xrLC_GlobalData.h" -#include "light_point.h" -#include "xrCore/Threading/Lock.hpp" - -#include "xrCDB/xrCDB.h" -//----------------------------------------------------------------------- -typedef xr_multimap mapVert; -typedef mapVert::iterator mapVertIt; -mapVert* g_trans; -Lock g_trans_CS -#ifdef CONFIG_PROFILE_LOCKS - (MUTEX_PROFILE_ID(g_trans_CS)) -#endif // CONFIG_PROFILE_LOCKS - ; -extern XRLC_LIGHT_API void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c& C, Fvector& P, Fvector& N, - base_lighting& lights, u32 flags, Face* skip); - -void g_trans_register_internal(Vertex* V) -{ - R_ASSERT(V); - - const float eps = EPS_L; - const float eps2 = 2.f * eps; - - // Search - const float key = V->P.x; - mapVertIt it = g_trans->lower_bound(key); - mapVertIt it2 = it; - - // Decrement to the start and inc to end - while (it != g_trans->begin() && ((it->first + eps2) > key)) - --it; - while (it2 != g_trans->end() && ((it2->first - eps2) < key)) - ++it2; - if (it2 != g_trans->end()) - ++it2; - - // Search - for (; it != it2; ++it) - { - vecVertex& VL = it->second; - Vertex* Front = VL.front(); - R_ASSERT(Front); - if (Front->P.similar(V->P, eps)) - { - VL.push_back(V); - return; - } - } - - // Register - mapVertIt ins = g_trans->insert(std::make_pair(key, vecVertex())); - ins->second.reserve(32); - ins->second.push_back(V); -} -void g_trans_register(Vertex* V) -{ - g_trans_CS.Enter(); - g_trans_register_internal(V); - g_trans_CS.Leave(); -} - -////////////////////////////////////////////////////////////////////////// -const u32 VLT_END = u32(-1); -class CVertexLightTasker -{ - Lock cs; - volatile u32 index; - -public: - CVertexLightTasker() - : index(0) -#ifdef CONFIG_PROFILE_LOCKS - , - cs(MUTEX_PROFILE_ID(CVertexLightTasker)) -#endif // CONFIG_PROFILE_LOCKS - {}; - - void init() { index = 0; } - u32 get() - { - cs.Enter(); - u32 _res = index; - if (_res >= lc_global_data()->g_vertices().size()) - _res = VLT_END; - else - index += 1; - cs.Leave(); - return _res; - } -}; -CVertexLightTasker VLT; - -bool GetTranslucency(const Vertex* V, float& v_trans) -{ - // Get transluency factor - - bool bVertexLight = FALSE; - u32 L_flags = 0; - for (u32 f = 0; f < V->m_adjacents.size(); ++f) - { - Face* F = V->m_adjacents[f]; - v_trans += F->Shader().vert_translucency; - if (F->Shader().flags.bLIGHT_Vertex) - bVertexLight = TRUE; - } - v_trans /= float(V->m_adjacents.size()); - return bVertexLight; -} - -class CVertexLightThread : public CThread -{ -public: - CVertexLightThread(u32 ID) : CThread(ID, ProxyMsg) { thMessages = FALSE; } - virtual void Execute() - { - u32 counter = 0; - for (;; counter++) - { - u32 id = VLT.get(); - if (id == VLT_END) - break; - - Vertex* V = lc_global_data()->g_vertices()[id]; - - R_ASSERT(V); - - float v_trans = 0.f; - - if (GetTranslucency(V, v_trans)) - { - base_color_c vC, old; - V->C._get(old); - - CDB::COLLIDER DB; - LightPoint(&DB, 0, lc_global_data()->RCAST_Model(), vC, V->P, V->N, lc_global_data()->L_static(), - (lc_global_data()->b_nosun() ? LP_dont_sun : 0) | LP_dont_hemi, 0); - vC._tmp_ = v_trans; - vC.mul(.5f); - vC.hemi = old.hemi; // preserve pre-calculated hemisphere - V->C._set(vC); - - g_trans_register(V); - } - - thProgress = float(counter) / float(lc_global_data()->g_vertices().size()); - } - } -}; -namespace lc_net -{ -void RunLightVertexNet(); -} -void LightVertex(bool net) -{ - g_trans = xr_new(); - - // Start threads, wait, continue --- perform all the work - Logger.Status("Calculating..."); - if (!net) - { - CThreadManager Threads(ProxyStatus, ProxyProgress); - VLT.init(); - CTimer start_time; - start_time.Start(); - for (u32 thID = 0; thID < NUM_THREADS; thID++) - Threads.start(xr_new(thID)); - Threads.wait(); - Logger.clMsg("%f seconds", start_time.GetElapsed_sec()); - } - else - { - lc_net::RunLightVertexNet(); - } - // Process all groups - Logger.Status("Transluenting..."); - for (mapVertIt it = g_trans->begin(); it != g_trans->end(); ++it) - { - // Unique - vecVertex& VL = it->second; - std::sort(VL.begin(), VL.end()); - VL.erase(std::unique(VL.begin(), VL.end()), VL.end()); - - // Calc summary color - base_color_c C; - for (u32 v = 0; v < VL.size(); v++) - { - base_color_c cc; - VL[v]->C._get(cc); - C.max(cc); - } - - // Calculate final vertex color - for (u32 v = 0; v < VL.size(); v++) - { - base_color_c vC; - VL[v]->C._get(vC); - - // trans-level - float level = vC._tmp_; - - // - base_color_c R; - R.lerp(vC, C, level); - R.max(vC); - VL[v]->C._set(R); - } - } - xr_delete(g_trans); - Logger.Status("Wating..."); -} diff --git a/src/utils/xrLC_Light/xrLightVertex.h b/src/utils/xrLC_Light/xrLightVertex.h deleted file mode 100644 index ab80e99c7bf..00000000000 --- a/src/utils/xrLC_Light/xrLightVertex.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _XRLIGHT_VERTEX_H_ -#define _XRLIGHT_VERTEX_H_ -extern XRLC_LIGHT_API void LightVertex(bool net); -#endif diff --git a/src/utils/xrLC_Light/xrLightVertexNet.cpp b/src/utils/xrLC_Light/xrLightVertexNet.cpp deleted file mode 100644 index 4427fbd9bfd..00000000000 --- a/src/utils/xrLC_Light/xrLightVertexNet.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "stdafx.h" -#include "xrLightVertex.h" - -#include "xrface.h" -#include "xrLC_GlobalData.h" -#include "net_execution_vertex_light.h" - -#include "net_execution_factory.h" -#include "lcnet_task_manager.h" -#include "net_exec_pool.h" - -bool GetTranslucency(const Vertex* V, float& v_trans); -u32 vertises_has_lighting = u32(-1); -u32 CalcAllTranslucency() -{ - vecVertex& verts = lc_global_data()->g_vertices(); - u32 end_translucency = verts.size(); - for (u32 i = 0; i < end_translucency; ++i) - { - Vertex* V = verts[i]; - float v_trans = 0.f; - bool trans = GetTranslucency(V, v_trans); - if (trans) - V->C.t._w(v_trans); - else - { - std::swap(verts[end_translucency - 1], verts[i]); - --end_translucency; - --i; - } - } - return end_translucency; -} - -namespace lc_net -{ -void RunLightVertexNet() -{ - // u32 size = CalcAllTranslucency(); - R_ASSERT(vertises_has_lighting != u32(-1)); - - u32 size = vertises_has_lighting; - const u32 vertex_light_task_number = 2048; - const u32 task_size = size / vertex_light_task_number; - const u32 rest_size = size % vertex_light_task_number; - if (task_size != 0) - for (u32 i = 0; i < vertex_light_task_number; ++i) - { - tnet_execution_base* el = execution_factory.create(); - el->implementation().construct(i * task_size, (i + 1) * task_size); - get_task_manager().add_task(el); - } - if (rest_size != 0) - { - tnet_execution_base* el = execution_factory.create(); - el->implementation().construct( - vertex_light_task_number * task_size, vertex_light_task_number * task_size + rest_size); - get_task_manager().add_task(el); - } - - exec_pool* pool = get_task_manager().run("Net Vertex Lighting"); - if (pool) - pool->wait(); - - // get_task_manager().wait_all(); -} -} diff --git a/src/utils/xrLC_Light/xrLight_ImlicitNet.cpp b/src/utils/xrLC_Light/xrLight_ImlicitNet.cpp deleted file mode 100644 index 0e1cd6dfaac..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImlicitNet.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "stdafx.h" -#include "xrlight_implicitrun.h" -#include "xrLight_Implicit.h" -#include "xrlight_implicitdeflector.h" - -#include "implicit_net_global_data.h" - -#include "net_execution_factory.h" -#include "lcnet_task_manager.h" -#include "net_execution_implicit_light.h" -#include "net_exec_pool.h" -#include "mu_model_light.h" -#include "xrLC_GlobalData.h" -extern ImplicitCalcGlobs cl_globs; -namespace lc_net -{ -static void AddImpImplicitNetTask(u32 from, u32 to) -{ - // tmanager.start (new ImplicitThread (thID,&defl,thID*stride,thID*stride+stride)); - if (from == to) - return; - R_ASSERT(from < to); - ImplicitExecute exec(from, to); - - tnet_execution_base* el = lc_net::execution_factory.create(); - el->implementation().construct(exec); - get_task_manager().add_task(el); -} -void RunImplicitnet(ImplicitDeflector& defl, const xr_vector& exept) -{ - globals().get().init(); - - // WaitNetCompileDataPrepare( ); - WaitMuModelsLocalCalcLightening(); - inlc_global_data()->clear_build_textures_surface(exept); - - // u32 num_tasks = 1003; - // u32 stride = defl.Height()/num_tasks; - // if( stride == 0 ) - //{ - // num_tasks = defl.Height(); - // stride = 1; - //} - - const u32 num_tasks = defl.Height(); - const u32 stride = 1; - for (u32 thID = 0; thID < num_tasks; thID++) - { - AddImpImplicitNetTask(thID * stride, thID * stride + stride); - } - AddImpImplicitNetTask(num_tasks * stride, defl.Height()); - - exec_pool* pool = get_task_manager().run("Net Implicit Lighting"); - if (pool) - pool->wait(); - - // get_task_manager().wait_all(); - globals().get().cleanup(); -} -} diff --git a/src/utils/xrLC_Light/xrLight_Implicit.cpp b/src/utils/xrLC_Light/xrLight_Implicit.cpp deleted file mode 100644 index 87ccf5c25df..00000000000 --- a/src/utils/xrLC_Light/xrLight_Implicit.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "stdafx.h" - -#include "xrLight_Implicit.h" -#include "xrLight_ImplicitDeflector.h" -#include "xrLight_ImplicitRun.h" -#include "light_point.h" -#include "xrDeflector.h" -#include "xrLC_GlobalData.h" -#include "xrFace.h" -#include "xrLight_ImplicitCalcGlobs.h" -#include "net_task_callback.h" -#include "xrCDB/xrCDB.h" -#include "xrCore/Threading/Lock.hpp" - -extern "C" bool XR_IMPORT DXTCompress( - LPCSTR out_name, u8* raw_data, u8* normal_map, u32 w, u32 h, u32 pitch, STextureParams* fmt, u32 depth); - -using Implicit = xr_map; - -void ImplicitExecute::read(INetReader& r) -{ - y_start = r.r_u32(); - y_end = r.r_u32(); -} -void ImplicitExecute::write(IWriter& w) const -{ - R_ASSERT(y_start != (u32(-1))); - R_ASSERT(y_end != (u32(-1))); - w.w_u32(y_start); - w.w_u32(y_end); -} - -ImplicitCalcGlobs cl_globs; - -void ImplicitExecute::receive_result(INetReader& r) -{ - R_ASSERT(y_start != (u32(-1))); - R_ASSERT(y_end != (u32(-1))); - ImplicitDeflector& defl = cl_globs.DATA(); - for (u32 V = y_start; V < y_end; V++) - for (u32 U = 0; U < defl.Width(); U++) - { - r_pod(r, defl.Lumel(U, V)); - r_pod(r, defl.Marker(U, V)); - } -} -void ImplicitExecute::send_result(IWriter& w) const -{ - R_ASSERT(y_start != (u32(-1))); - R_ASSERT(y_end != (u32(-1))); - ImplicitDeflector& defl = cl_globs.DATA(); - for (u32 V = y_start; V < y_end; V++) - for (u32 U = 0; U < defl.Width(); U++) - { - w_pod(w, defl.Lumel(U, V)); - w_pod(w, defl.Marker(U, V)); - } -} - -void ImplicitExecute::Execute(net_task_callback* net_callback) -{ - R_ASSERT(y_start != (u32(-1))); - R_ASSERT(y_end != (u32(-1))); - // R_ASSERT (DATA); - ImplicitDeflector& defl = cl_globs.DATA(); - CDB::COLLIDER DB; - - // Setup variables - Fvector2 dim, half; - dim.set(float(defl.Width()), float(defl.Height())); - half.set(.5f / dim.x, .5f / dim.y); - - // Jitter data - Fvector2 JS; - JS.set(.499f / dim.x, .499f / dim.y); - u32 Jcount; - Fvector2* Jitter; - Jitter_Select(Jitter, Jcount); - - // Lighting itself - for (u32 V = y_start; V < y_end; V++) - { - for (u32 U = 0; U < defl.Width(); U++) - { - if (net_callback && !net_callback->test_connection()) - return; - base_color_c C; - u32 Fcount = 0; - - try - { - for (u32 J = 0; J < Jcount; J++) - { - // LUMEL space - Fvector2 P; - P.x = float(U) / dim.x + half.x + Jitter[J].x * JS.x; - P.y = float(V) / dim.y + half.y + Jitter[J].y * JS.y; - xr_vector& space = cl_globs.Hash().query(P.x, P.y); - - // World space - Fvector wP, wN, B; - for (auto it = space.begin(); it != space.end(); ++it) - { - Face* F = *it; - _TCF& tc = F->tc[0]; - if (tc.isInside(P, B)) - { - // We found triangle and have barycentric coords - Vertex* V1 = F->v[0]; - Vertex* V2 = F->v[1]; - Vertex* V3 = F->v[2]; - wP.from_bary(V1->P, V2->P, V3->P, B); - wN.from_bary(V1->N, V2->N, V3->N, B); - wN.normalize(); - LightPoint(&DB, 0, inlc_global_data()->RCAST_Model(), C, wP, wN, - inlc_global_data()->L_static(), (inlc_global_data()->b_nosun() ? LP_dont_sun : 0), F); - Fcount++; - } - } - } - } - catch (...) - { - Logger.clMsg("* THREAD #%d: Access violation. Possibly recovered."); //,thID - } - if (Fcount) - { - // Calculate lighting amount - C.scale(Fcount); - C.mul(.5f); - defl.Lumel(U, V)._set(C); - defl.Marker(U, V) = 255; - } - else - { - defl.Marker(U, V) = 0; - } - } - // thProgress = float(V - y_start) / float(y_end-y_start); - } -} - -//#pragma optimize( "g", off ) - -void ImplicitLightingExec(BOOL b_net); -void ImplicitLightingTreadNetExec(void* p); -void ImplicitLighting(BOOL b_net) -{ - if (g_params().m_quality == ebqDraft) - return; - if (!b_net) - { - ImplicitLightingExec(FALSE); - return; - } - Threading::SpawnThread(ImplicitLightingTreadNetExec, "worker-thread", 1024 * 1024, 0); -} -Lock implicit_net_lock; -void XRLC_LIGHT_API ImplicitNetWait() -{ - implicit_net_lock.Enter(); - implicit_net_lock.Leave(); -} -void ImplicitLightingTreadNetExec(void* p) -{ - implicit_net_lock.Enter(); - ImplicitLightingExec(TRUE); - implicit_net_lock.Leave(); -} - -static xr_vector not_clear; -void ImplicitLightingExec(BOOL b_net) -{ - Implicit calculator; - - cl_globs.Allocate(); - not_clear.clear(); - // Sorting - Logger.Status("Sorting faces..."); - for (auto I = inlc_global_data()->g_faces().begin(); I != inlc_global_data()->g_faces().end(); ++I) - { - Face* F = *I; - if (F->pDeflector) - continue; - if (!F->hasImplicitLighting()) - continue; - - Logger.Progress(float(I - inlc_global_data()->g_faces().begin()) / float(inlc_global_data()->g_faces().size())); - b_material& M = inlc_global_data()->materials()[F->dwMaterial]; - u32 Tid = M.surfidx; - b_BuildTexture* T = &(inlc_global_data()->textures()[Tid]); - - auto it = calculator.find(Tid); - if (it == calculator.end()) - { - ImplicitDeflector ImpD; - ImpD.texture = T; - ImpD.faces.push_back(F); - calculator.insert(std::make_pair(Tid, ImpD)); - not_clear.push_back(Tid); - } - else - { - ImplicitDeflector& ImpD = it->second; - ImpD.faces.push_back(F); - } - } - - // Lighting - for (auto imp = calculator.begin(); imp != calculator.end(); ++imp) - { - ImplicitDeflector& defl = imp->second; - Logger.Status("Lighting implicit map '%s'...", defl.texture->name); - Logger.Progress(0); - defl.Allocate(); - - // Setup cache - Logger.Progress(0); - cl_globs.Initialize(defl); - if (b_net) - lc_net::RunImplicitnet(defl, not_clear); - else - RunImplicitMultithread(defl); - - defl.faces.clear(); - - // Expand - Logger.Status("Processing lightmap..."); - for (u32 ref = 254; ref > 0; ref--) - if (!ApplyBorders(defl.lmap, ref)) - break; - - Logger.Status("Mixing lighting with texture..."); - { - b_BuildTexture& TEX = *defl.texture; - VERIFY(TEX.pSurface); - u32* color = TEX.pSurface; - for (u32 V = 0; V < defl.Height(); V++) - { - for (u32 U = 0; U < defl.Width(); U++) - { - // Retreive Texel - float h = defl.Lumel(U, V).h._r(); - u32& C = color[V * defl.Width() + U]; - C = subst_alpha(C, u8_clr(h)); - } - } - } - - xr_vector packed; - defl.lmap.Pack(packed); - defl.Deallocate(); - - // base - Logger.Status("Saving base..."); - { - string_path name, out_name; - sscanf(strstr(Core.Params, "-f") + 2, "%s", name); - R_ASSERT(name[0] && defl.texture); - b_BuildTexture& TEX = *defl.texture; - strconcat(sizeof(out_name), out_name, name, "\\", TEX.name, ".dds"); - FS.update_path(out_name, "$game_levels$", out_name); - Logger.clMsg("Saving texture '%s'...", out_name); - VerifyPath(out_name); - u8* raw_data = (u8*)(TEX.pSurface); - u32 w = TEX.dwWidth; - u32 h = TEX.dwHeight; - u32 pitch = w * 4; - STextureParams fmt = TEX.THM; - fmt.fmt = STextureParams::tfDXT5; - fmt.flags.set(STextureParams::flDitherColor, FALSE); - fmt.flags.set(STextureParams::flGenerateMipMaps, FALSE); - fmt.flags.set(STextureParams::flBinaryAlpha, FALSE); - DXTCompress(out_name, raw_data, 0, w, h, pitch, &fmt, 4); - } - - // lmap - Logger.Status("Saving lmap..."); - { - // xr_vector packed; - // defl.lmap.Pack (packed); - - string_path name, out_name; - sscanf(strstr(GetCommandLine(), "-f") + 2, "%s", name); - b_BuildTexture& TEX = *defl.texture; - strconcat(sizeof(out_name), out_name, name, "\\", TEX.name, "_lm.dds"); - FS.update_path(out_name, "$game_levels$", out_name); - Logger.clMsg("Saving texture '%s'...", out_name); - VerifyPath(out_name); - u8* raw_data = (u8*)(&*packed.begin()); - u32 w = TEX.dwWidth; - u32 h = TEX.dwHeight; - u32 pitch = w * 4; - STextureParams fmt; - fmt.fmt = STextureParams::tfDXT5; - fmt.flags.set(STextureParams::flDitherColor, FALSE); - fmt.flags.set(STextureParams::flGenerateMipMaps, FALSE); - fmt.flags.set(STextureParams::flBinaryAlpha, FALSE); - DXTCompress(out_name, raw_data, 0, w, h, pitch, &fmt, 4); - } - // defl.Deallocate (); - } - not_clear.clear(); - cl_globs.Deallocate(); - calculator.clear(); - if (b_net) - inlc_global_data()->clear_build_textures_surface(); -} diff --git a/src/utils/xrLC_Light/xrLight_Implicit.h b/src/utils/xrLC_Light/xrLight_Implicit.h deleted file mode 100644 index 38265fed955..00000000000 --- a/src/utils/xrLC_Light/xrLight_Implicit.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _XRLIGHT_IMPLICIED_H_ -#define _XRLIGHT_IMPLICIED_H_ -class INetReader; -class net_task_callback; -class ImplicitExecute -{ - // Data for this thread - u32 y_start, y_end; - -public: - ImplicitExecute(u32 _y_start, u32 _y_end) : y_start(_y_start), y_end(_y_end) {} - ImplicitExecute() : y_start(u32(-1)), y_end(u32(-1)) {} - void Execute(net_task_callback* net_callback); - void read(INetReader& r); - void write(IWriter& w) const; - - void receive_result(INetReader& r); - void send_result(IWriter& w) const; -}; - -#endif diff --git a/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.cpp b/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.cpp deleted file mode 100644 index c4b8a1aed6d..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "stdafx.h" - -#include "xrlight_implicitcalcglobs.h" -#include "xrLight_implicitdeflector.h" -#include "xrface.h" -#include "xrlc_globaldata.h" -void ImplicitCalcGlobs::read(INetReader& r) -{ - // bool create_rf = !read_faces; - // if(!read_faces) - //{ - // inlc_global_data()->create_read_faces(); - //} - - R_ASSERT(read_faces); - NetClear(); - Allocate(); - defl = xr_new(); - ImplicitHash->read(r, *read_faces); - defl->read(r); - - // if(create_rf) - // inlc_global_data()->destroy_read_faces(); -} -void ImplicitCalcGlobs::NetClear() -{ - Deallocate(); - xr_delete(defl); -} -void ImplicitCalcGlobs::write(IWriter& w) const -{ - R_ASSERT(ImplicitHash); - R_ASSERT(write_faces); - ImplicitHash->write(w, *write_faces); - defl->write(w); -} -void ImplicitCalcGlobs::Allocate() { ImplicitHash = xr_new(); } -void ImplicitCalcGlobs::Deallocate() { xr_delete(ImplicitHash); } -void ImplicitCalcGlobs::Initialize(ImplicitDeflector& d) -{ - defl = &d; - R_ASSERT(defl); - Fbox2 bounds; - defl->Bounds_Summary(bounds); - Hash().initialize(bounds, defl->faces.size()); - for (u32 fid = 0; fid < defl->faces.size(); fid++) - { - Face* F = defl->faces[fid]; - F->AddChannel(F->tc[0].uv[0], F->tc[0].uv[1], F->tc[0].uv[2]); // make compatible format with LMAPs - defl->Bounds(fid, bounds); - ImplicitHash->add(bounds, F); - } -} diff --git a/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.h b/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.h deleted file mode 100644 index 74766047a2a..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitCalcGlobs.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _XRLIGHT_IMPLICITCALCGLOBS_H_ -#define _XRLIGHT_IMPLICITCALCGLOBS_H_ -#include "xrFaceDefs.h" -#include "hash2d.h" -class ImplicitDeflector; -typedef hash2D IHASH; -class ImplicitCalcGlobs -{ - IHASH* ImplicitHash; - ImplicitDeflector* defl; - -public: - ImplicitCalcGlobs() : defl(0), ImplicitHash(0) {} - IC IHASH& Hash() - { - R_ASSERT(ImplicitHash); - return *ImplicitHash; - } - IC ImplicitDeflector& DATA() - { - R_ASSERT(defl); - return *defl; - } - void read(INetReader& r); - void write(IWriter& w) const; - void Allocate(); - void Deallocate(); - void Initialize(ImplicitDeflector& d); - void NetClear(); - ///////////////////////////////////////////////////////// -}; -#endif diff --git a/src/utils/xrLC_Light/xrLight_ImplicitDeflector.cpp b/src/utils/xrLC_Light/xrLight_ImplicitDeflector.cpp deleted file mode 100644 index c4b8afab96c..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitDeflector.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "stdafx.h" -#include "xrlight_implicitdeflector.h" -#include "b_build_texture.h" -#include "xrface.h" -#include "xrLC_GlobalData.h" - -u32 ImplicitDeflector::Width() { return texture->dwWidth; } -u32 ImplicitDeflector::Height() { return texture->dwHeight; } -u32& ImplicitDeflector::Texel(u32 x, u32 y) { return texture->pSurface[y * Width() + x]; } -void ImplicitDeflector::Bounds(u32 ID, Fbox2& dest) -{ - Face* F = faces[ID]; - _TCF& TC = F->tc[0]; - dest.min.set(TC.uv[0]); - dest.max.set(TC.uv[0]); - dest.modify(TC.uv[1]); - dest.modify(TC.uv[2]); -} - -void ImplicitDeflector::Bounds_Summary(Fbox2& bounds) -{ - bounds.invalidate(); - for (u32 I = 0; I < faces.size(); I++) - { - Fbox2 B; - Bounds(I, B); - bounds.merge(B); - } -} - -// b_BuildTexture* texture; -// lm_layer lmap; -// vecFace faces; - -void ImplicitDeflector::read(INetReader& r) -{ - r_pointer(r, texture, inlc_global_data()->textures()); - lmap.read(r); - R_ASSERT(read_faces); - read_faces->read_ref(r, faces); -} - -void ImplicitDeflector::write(IWriter& w) const -{ - w_pointer(w, texture, inlc_global_data()->textures()); - lmap.write(w); - R_ASSERT(write_faces); - write_faces->write_ref(w, faces); -} diff --git a/src/utils/xrLC_Light/xrLight_ImplicitDeflector.h b/src/utils/xrLC_Light/xrLight_ImplicitDeflector.h deleted file mode 100644 index 1e862851f44..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitDeflector.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#ifndef _XRLIGHT_IPLICIDDEFLECTOR -#define _XRLIGHT_IPLICIDDEFLECTOR - -#include "lm_layer.h" -#include "xrFacedefs.h" - -// fwd. decl. -struct b_BuildTexture; -struct Fbox2; - -class ImplicitDeflector -{ -public: - b_BuildTexture* texture; - lm_layer lmap; - vecFace faces; - - ImplicitDeflector() : texture(0) {} - ~ImplicitDeflector() { Deallocate(); } - void Allocate() { lmap.create(Width(), Height()); } - void Deallocate() { lmap.destroy(); } - u32 Width(); - u32 Height(); - - u32& Texel(u32 x, u32 y); - base_color& Lumel(u32 x, u32 y) { return lmap.surface[y * Width() + x]; } - u8& Marker(u32 x, u32 y) { return lmap.marker[y * Width() + x]; } - void Bounds(u32 ID, Fbox2& dest); - void Bounds_Summary(Fbox2& bounds); - - void read(INetReader& r); - void write(IWriter& w) const; -}; -#endif diff --git a/src/utils/xrLC_Light/xrLight_ImplicitRun.h b/src/utils/xrLC_Light/xrLight_ImplicitRun.h deleted file mode 100644 index 6ca8c56f07c..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitRun.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _XRLIGHT_IMPLICITTHREAD_H_ -#define _XRLIGHT_IMPLICITTHREAD_H_ -class ImplicitDeflector; -void RunImplicitMultithread(ImplicitDeflector& defl); -namespace lc_net -{ -void RunImplicitnet(ImplicitDeflector& defl, const xr_vector& exept); -} - -#endif diff --git a/src/utils/xrLC_Light/xrLight_ImplicitThread.cpp b/src/utils/xrLC_Light/xrLight_ImplicitThread.cpp deleted file mode 100644 index 55268ccb305..00000000000 --- a/src/utils/xrLC_Light/xrLight_ImplicitThread.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "stdafx.h" -#include "xrlight_implicitrun.h" -#include "utils/xrLCUtil/xrThread.hpp" -#include "xrLight_Implicit.h" -#include "xrlight_implicitdeflector.h" - -class ImplicitThread : public CThread -{ -public: - ImplicitExecute execute; - - ImplicitThread(u32 ID, ImplicitDeflector* _DATA, u32 _y_start, u32 _y_end) - : CThread(ID, ProxyMsg), execute(_y_start, _y_end) - { - } - virtual void Execute(); -}; - -void ImplicitThread::Execute() -{ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); - Sleep(0); - execute.Execute(0); -} - -void RunImplicitMultithread(ImplicitDeflector& defl) -{ - // Start threads - CThreadManager tmanager(ProxyStatus, ProxyProgress); - u32 stride = defl.Height() / NUM_THREADS; - for (u32 thID = 0; thID < NUM_THREADS; thID++) - tmanager.start(xr_new(thID, &defl, thID * stride, thID * stride + stride)); - tmanager.wait(); -} diff --git a/src/utils/xrLC_Light/xrMU_Model.cpp b/src/utils/xrLC_Light/xrMU_Model.cpp deleted file mode 100644 index 1792574f4e2..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "stdafx.h" -#include "xrmu_model.h" - -#include "serialize.h" -#include "mu_model_face.h" -#include "vector_clear.h" -#include "xrCore/xrPool.h" - -xrMU_Model::xrMU_Model() : m_lod_ID(u16(-1)), read_faces(0), read_vertices(0), write_faces(0), write_vertices(0) {} -xrMU_Model::~xrMU_Model() -{ - reading_close(); - writting_close(); - clear_mesh(); -} - -poolSS<_vertex, 8 * 1024>& mu_vertices_pool(); -poolSS<_face, 8 * 1024>& mu_faces_pool(); - -static struct destruct_vertex_not_uregister -{ - static void destruct(_vertex*& v) { mu_vertices_pool().destroy(v); } -} _destruct_vertex; - -static struct destruct_face_not_uregister -{ - static void destruct(_face*& f) { mu_faces_pool().destroy(f); } -} _destruct_face; - -void xrMU_Model::clear_mesh() -{ - vec_clear(m_vertices, _destruct_vertex); - vec_clear(m_faces, _destruct_face); -} - -void xrMU_Model::read_color(INetReader& r) { r_pod_vector(r, color); } -void xrMU_Model::write_color(IWriter& w) const { w_pod_vector(w, color); } -void xrMU_Model::read_subdivs(INetReader& r) { r_pod_vector(r, m_subdivs); } -void xrMU_Model::write_subdivs(IWriter& w) const { w_pod_vector(w, m_subdivs); } -void xrMU_Model::read(INetReader& r) -{ - reading_open(); - r.r_stringZ(m_name); - m_lod_ID = r.r_u16(); - VERIFY(read_vertices); - read_vertices->read(r); - VERIFY(read_faces); - read_faces->read(r); - r_pod_vector(r, m_subdivs); - read_adjacents(r); - - read_face_verts(r); -} -void xrMU_Model::write(IWriter& w) const -{ - writting_open(); - w.w_stringZ(m_name); - w.w_u16(m_lod_ID); - VERIFY(write_vertices); - write_vertices->write(w); - VERIFY(write_faces); - write_faces->write(w); - w_pod_vector(w, m_subdivs); - write_adjacents(w); - - write_face_verts(w); -} - -u32 xrMU_Model::find(const _vertex* v) const -{ - v_vertices::const_iterator i = std::find(m_vertices.begin(), m_vertices.end(), v); - if (i == m_vertices.end()) - return u32(-1); - return u32(i - m_vertices.begin()); -} - -u32 xrMU_Model::find(const _face* f) const -{ - v_faces::const_iterator i = std::find(m_faces.begin(), m_faces.end(), f); - if (i == m_faces.end()) - return u32(-1); - return u32(i - m_faces.begin()); -} - -xrMU_Model* xrMU_Model::read_create() { return xr_new(); } -void xrMU_Model::reading_open() -{ - VERIFY(!read_faces); - read_faces = xr_new(&m_faces); - VERIFY(!read_vertices); - read_vertices = xr_new(&m_vertices); -} -void xrMU_Model::reading_close() -{ - xr_delete(read_faces); - xr_delete(read_vertices); -} -void xrMU_Model::writting_open() const -{ - VERIFY(!write_faces); - write_faces = xr_new(&m_faces); - VERIFY(!write_vertices); - write_vertices = xr_new(&m_vertices); -} -void xrMU_Model::writting_close() const -{ - xr_delete(write_faces); - xr_delete(write_vertices); -} - -void xrMU_Model::read(INetReader& r, _vertex*& v) const -{ - VERIFY(read_vertices); - read_vertices->read(r, v); -} -void xrMU_Model::read(INetReader& r, _face*& v) const -{ - VERIFY(read_faces); - read_faces->read(r, v); -} - -void xrMU_Model::write(IWriter& w, u32 id, const _vertex* v) const -{ - VERIFY(v == m_vertices[id]); - VERIFY(write_vertices); - VERIFY(write_vertices->get_id(v, m_vertices) == id); - write_vertices->write(w, v); -} -void xrMU_Model::write(IWriter& w, u32 id, const _face* v) const -{ - VERIFY(v == m_faces[id]); - VERIFY(write_faces); - VERIFY(write_faces->get_id(v, m_faces) == id); - write_faces->write(w, v); -} - -void xrMU_Model::read_adjacents(INetReader& r, xrMU_Model::tread_faces& read_faces, _vertex& v) -{ - read_faces.read_ref(r, v.m_adjacents); -} - -void xrMU_Model::write_adjacents(IWriter& w, xrMU_Model::twrite_faces& write_faces, const _vertex& v) -{ - write_faces.write_ref(w, v.m_adjacents); -} - -void xrMU_Model::read_adjacents(INetReader& r) -{ - R_ASSERT(read_faces); - v_vertices_it i = m_vertices.begin(), e = m_vertices.end(); - for (; e != i; ++i) - read_adjacents(r, *read_faces, *(*i)); -} -void xrMU_Model::write_adjacents(IWriter& w) const -{ - R_ASSERT(write_faces); - v_vertices_cit i = m_vertices.begin(), e = m_vertices.end(); - for (; e != i; ++i) - write_adjacents(w, *write_faces, *(*i)); -} - -void xrMU_Model::read_face_verts(INetReader& r) -{ - R_ASSERT(read_vertices); - v_faces_it i = m_faces.begin(), e = m_faces.end(); - for (; e != i; ++i) - read_face_verts(r, *read_vertices, *(*i)); -} - -void xrMU_Model::write_face_verts(IWriter& w) const -{ - R_ASSERT(write_vertices); - v_faces_cit i = m_faces.begin(), e = m_faces.end(); - for (; e != i; ++i) - write_face_verts(w, *write_vertices, *(*i)); -} - -void xrMU_Model::read_face_verts(INetReader& r, xrMU_Model::tread_vertices& read_verts, _face& v) -{ - // read_verts - read_verts.read(r, v.v[0]); - read_verts.read(r, v.v[1]); - read_verts.read(r, v.v[2]); -} -void xrMU_Model::write_face_verts(IWriter& w, xrMU_Model::twrite_vertices& write_verts, const _face& v) -{ - write_verts.write(w, v.v[0]); - write_verts.write(w, v.v[1]); - write_verts.write(w, v.v[2]); -} diff --git a/src/utils/xrLC_Light/xrMU_Model.h b/src/utils/xrLC_Light/xrMU_Model.h deleted file mode 100644 index 4ae18e1bd26..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef XRMU_MODEL_H -#define XRMU_MODEL_H - -#include "mu_model_face.h" - -#include "serialize.h" - -namespace CDB -{ -class MODEL; -class CollectorPacked; -}; -struct OGF; -class base_lighting; -class XRLC_LIGHT_API xrMU_Model -{ -public: - //** - // struct _vertex; - // struct _face; - // struct data_face; - // struct data_vertex; - //** - - //** - - struct _subdiv - { - u32 material; - u32 start; - u32 count; - - OGF* ogf; - - u32 vb_id; - u32 vb_start; - - u32 ib_id; - u32 ib_start; - - u32 sw_id; - }; - - typedef xr_vector<_vertex>::iterator dummy_compiler_treatment; - - //** - typedef xr_vector<_vertex*> v_vertices; - typedef v_vertices::iterator v_vertices_it; - typedef v_vertices::const_iterator v_vertices_cit; - - typedef xr_vector<_face*> v_faces; - typedef v_faces::iterator v_faces_it; - typedef v_faces::const_iterator v_faces_cit; - typedef xr_vector<_subdiv> v_subdivs; - typedef v_subdivs::iterator v_subdivs_it; - -public: - shared_str m_name; - u16 m_lod_ID; - v_vertices m_vertices; - v_faces m_faces; - v_subdivs m_subdivs; - - xr_vector color; - -private: - _face* create_face(_vertex* v0, _vertex* v1, _vertex* v2, b_face& F); - _vertex* create_vertex(Fvector& P); - _face* load_create_face(Fvector& P1, Fvector& P2, Fvector& P3, b_face& F); - _vertex* load_create_vertex(Fvector& P); - -public: - xrMU_Model(); - ~xrMU_Model(); - void clear_mesh(); - void Load(IReader& F, u32 version); - // void calc_normals (); - void calc_materials(); - void calc_faceopacity(); - void calc_lighting( - xr_vector& dest, const Fmatrix& xform, CDB::MODEL* M, base_lighting& lights, u32 flags); - void calc_lighting(); - // void calc_ogf (); - // void export_geometry (); - void export_cform_rcast(CDB::CollectorPacked& CL, Fmatrix& xform); - void read(INetReader& r); - void write(IWriter& w) const; - - void read_color(INetReader& r); - void write_color(IWriter& w) const; - void read_subdivs(INetReader& r); - void write_subdivs(IWriter& w) const; - - u32 find(const _vertex* v) const; - u32 find(const _face* v) const; - - void read(INetReader& r, _vertex*& v) const; - void read(INetReader& r, _face*& v) const; - - void write(IWriter& r, u32 id, const _vertex* v) const; - void write(IWriter& r, u32 id, const _face* v) const; - - static xrMU_Model* read_create(); - void reading_open(); - void reading_close(); - void writting_open() const; - void writting_close() const; - -private: - typedef vector_serialize>> tread_faces; - typedef vector_serialize>> twrite_faces; - - typedef vector_serialize>> tread_vertices; - typedef vector_serialize>> twrite_vertices; - - tread_faces* read_faces; - mutable twrite_faces* write_faces; - - tread_vertices* read_vertices; - mutable twrite_vertices* write_vertices; - -private: - void read_adjacents(INetReader& r); - void write_adjacents(IWriter& w) const; - static void read_adjacents(INetReader& r, xrMU_Model::tread_faces& read_faces, _vertex& v); - static void write_adjacents(IWriter& w, xrMU_Model::twrite_faces& write_faces, const _vertex& v); - - void read_face_verts(INetReader& r); - void write_face_verts(IWriter& w) const; - static void read_face_verts(INetReader& r, xrMU_Model::tread_vertices& read_verts, _face& v); - static void write_face_verts(IWriter& w, xrMU_Model::twrite_vertices& write_verts, const _face& v); -}; - -void XRLC_LIGHT_API calc_normals(xrMU_Model& model); - -typedef vector_serialize>> tread_models; -typedef vector_serialize>> twrite_models; - -extern tread_models* read_models; -extern twrite_models* write_models; - -#endif diff --git a/src/utils/xrLC_Light/xrMU_Model_Calc_faceopacity.cpp b/src/utils/xrLC_Light/xrMU_Model_Calc_faceopacity.cpp deleted file mode 100644 index 15e8d3a7022..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Calc_faceopacity.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "stdafx.h" - -#include "xrMU_Model.h" -void xrMU_Model::calc_faceopacity() -{ - for (v_faces_it I = m_faces.begin(); I != m_faces.end(); ++I) - (*I)->CacheOpacity(); -} diff --git a/src/utils/xrLC_Light/xrMU_Model_Calc_lighting.cpp b/src/utils/xrLC_Light/xrMU_Model_Calc_lighting.cpp deleted file mode 100644 index 32922f06150..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Calc_lighting.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include "stdafx.h" -#include "xrMU_Model.h" -#include "light_point.h" -#include "xrCDB/xrCDB.h" -#include "utils/Shader_xrLC.h" -#include "mu_model_face.h" -#include "xrface.h" -#include "xrLC_GlobalData.h" - -void LightPoint(CDB::COLLIDER* DB, u32 ray_options, CDB::MODEL* MDL, base_color_c& C, Fvector& P, Fvector& N, base_lighting& lights, - u32 flags, Face* skip); -union var -{ - int i; - float f; - bool b; - - operator float() { return f; } - operator int() { return i; } - operator bool() { return b; } - var& operator=(float _f) - { - f = _f; - return *this; - } - var& operator=(int _i) - { - i = _i; - return *this; - } - var& operator=(bool _b) - { - b = _b; - return *this; - } - - var() {} - var(float _f) : f(_f) {} - var(int _i) : i(_i) {} - var(bool _b) : b(_b) {} -}; - -/* -var test; - -test = 0.f; -int k = test; - -test = true; -float f = test; - -float x = 10.f; -var _x = var(x); -*/ - -//----------------------------------------------------------------------- -void xrMU_Model::calc_lighting( - xr_vector& dest, const Fmatrix& xform, CDB::MODEL* MDL, base_lighting& lights, u32 flags) -{ - // trans-map - typedef xr_multimap mapVert; - typedef mapVert::iterator mapVertIt; - mapVert g_trans; - u32 I; - - // trans-epsilons - const float eps = EPS_L; - const float eps2 = 2.f * eps; - - // calc pure rotation matrix - Fmatrix Rxform, tmp, R; - R.set(xform); - R.translate_over(0, 0, 0); - tmp.transpose(R); - Rxform.invert(tmp); - - // Perform lighting - CDB::COLLIDER DB; - - // Disable faces if needed - /* - BOOL bDisableFaces = flags&LP_UseFaceDisable; - if (bDisableFaces) - for (I=0; Iflags.bDisableShadowCast = true; - */ - - // Perform lighting - for (I = 0; I < m_vertices.size(); I++) - { - _vertex* V = m_vertices[I]; - - // Get ambient factor - float v_amb = 0.f; - float v_trans = 0.f; - for (u32 f = 0; f < V->m_adjacents.size(); f++) - { - _face* F = V->m_adjacents[f]; - v_amb += F->Shader().vert_ambient; - v_trans += F->Shader().vert_translucency; - } - v_amb /= float(V->m_adjacents.size()); - v_trans /= float(V->m_adjacents.size()); - float v_inv = 1.f - v_amb; - - base_color_c vC; - Fvector vP, vN; - xform.transform_tiny(vP, V->P); - Rxform.transform_dir(vN, V->N); - exact_normalize(vN); - - // multi-sample - const int n_samples = (g_params().m_quality == ebqDraft) ? 1 : 6; - for (u32 sample = 0; sample < (u32)n_samples; sample++) - { - float a = 0.2f * float(sample) / float(n_samples); - Fvector P, N; - N.random_dir(vN, deg2rad(30.f)); - P.mad(vP, N, a); - LightPoint(&DB, 0, MDL, vC, P, N, lights, flags, 0); - } - vC.scale(n_samples); - vC._tmp_ = v_trans; - if (flags & LP_dont_hemi) - ; - else - vC.hemi += v_amb; - V->C._set(vC); - - // Search - const float key = V->P.x; - mapVertIt it = g_trans.lower_bound(key); - mapVertIt it2 = it; - - // Decrement to the start and inc to end - while (it != g_trans.begin() && ((it->first + eps2) > key)) - --it; - while (it2 != g_trans.end() && ((it2->first - eps2) < key)) - ++it2; - if (it2 != g_trans.end()) - ++it2; - - // Search - BOOL found = FALSE; - for (; it != it2; ++it) - { - v_vertices& VL = it->second; - _vertex* Front = VL.front(); - R_ASSERT(Front); - if (Front->P.similar(V->P, eps)) - { - found = TRUE; - VL.push_back(V); - } - } - - // Register - if (!found) - { - mapVertIt ins = g_trans.insert(std::make_pair(key, v_vertices())); - ins->second.reserve(32); - ins->second.push_back(V); - } - } - - // Enable faces if needed - /* - if (bDisableFaces) - for (I=0; Iflags.bDisableShadowCast = true; - */ - - // Process all groups - for (mapVertIt it = g_trans.begin(); it != g_trans.end(); ++it) - { - // Unique - v_vertices& VL = it->second; - std::sort(VL.begin(), VL.end()); - VL.erase(std::unique(VL.begin(), VL.end()), VL.end()); - - // Calc summary color - base_color_c C; - for (int v = 0; v < int(VL.size()); v++) - { - base_color_c vC; - VL[v]->C._get(vC); - C.max(vC); - } - - // Calculate final vertex color - for (u32 v = 0; v < int(VL.size()); v++) - { - base_color_c vC; - VL[v]->C._get(vC); - - // trans-level - float level = vC._tmp_; - - // - base_color_c R; - R.lerp(vC, C, level); - R.max(vC); - R.mul(.5f); - VL[v]->C._set(R); - } - } - - // Transfer colors to destination - dest.resize(m_vertices.size()); - for (I = 0; I < m_vertices.size(); I++) - { - Fvector ptPos = m_vertices[I]->P; - base_color ptColor = m_vertices[I]->C; - dest[I] = ptColor; - } -} - -void xrMU_Model::calc_lighting() -{ - // BB - Fbox BB; - BB.invalidate(); - for (v_vertices_it vit = m_vertices.begin(); vit != m_vertices.end(); ++vit) - BB.modify((*vit)->P); - - // Export CForm - CDB::CollectorPacked CL(BB, (u32)m_vertices.size(), (u32)m_faces.size()); - export_cform_rcast(CL, Fidentity); - - CDB::MODEL* M = xr_new(); - M->build(CL.getV(), (u32)CL.getVS(), CL.getT(), (u32)CL.getTS()); - - calc_lighting(color, Fidentity, M, inlc_global_data()->L_static(), LP_dont_rgb + LP_dont_sun); - - xr_delete(M); - - Logger.clMsg("model '%s' - REF_lighted.", *m_name); -} diff --git a/src/utils/xrLC_Light/xrMU_Model_Calc_materials.cpp b/src/utils/xrLC_Light/xrMU_Model_Calc_materials.cpp deleted file mode 100644 index 7e8e3b09293..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Calc_materials.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "stdafx.h" -#include "xrMU_Model.h" -#include "utils/Shader_xrLC.h" - -bool cmp_face_material(_face* f1, _face* f2) { return f1->dwMaterial < f2->dwMaterial; } -// static xrMU_Model::v_faces temp_vector; -void xrMU_Model::calc_materials() -{ - xrMU_Model::v_faces& temp_vector = m_faces; - - std::sort(temp_vector.begin(), temp_vector.end(), cmp_face_material); - - _subdiv current; - current.material = temp_vector[0]->dwMaterial; - current.start = 0; - current.count = 1; - - for (u32 it = 1; it < temp_vector.size(); it++) - { - if (current.material != temp_vector[it]->dwMaterial) - { - // end of strip - m_subdivs.push_back(current); - current.material = temp_vector[it]->dwMaterial; - current.start = it; - current.count = 1; - } - else - { - // strip continues to grow - current.count++; - } - } - m_subdivs.push_back(current); - - // remove non-visible materials - for (s32 it = 0; it < s32(m_subdivs.size()); it++) - { - _face* first = temp_vector[m_subdivs[it].start]; - if (first->Shader().flags.bRendering) - continue; - - m_subdivs.erase(m_subdivs.begin() + it); - it--; - } - - Logger.clMsg("model '%s' - %d subdivisions", *m_name, m_subdivs.size()); -} diff --git a/src/utils/xrLC_Light/xrMU_Model_Calc_normals.cpp b/src/utils/xrLC_Light/xrMU_Model_Calc_normals.cpp deleted file mode 100644 index f0b214ce93a..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Calc_normals.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "stdafx.h" - -#include "mu_model_face.h" -#include "calculate_normals.h" -#include "xrMU_Model.h" - -#include "xrCore/xrPool.h" - -poolSS<_vertex, 8 * 1024>& mu_vertices_pool(); - -void destroy_vertex(_vertex*& v, bool unregister) -{ - mu_vertices_pool().destroy(v); - v = NULL; -} - -void calc_normals(xrMU_Model& model) { calculate_normals<_vertex>::calc_normals(model.m_vertices, model.m_faces); } -/* -void xrMU_Model::calc_normals() -{ - u32 Vcount = (u32)m_vertices.size(); - float p_total = 0; - float p_cost = 1.f/(Vcount); - - // Clear temporary flag -//. float sm_cos = _cos(deg2rad(g_params.m_sm_angle)); - float sm_cos = _cos(deg2rad(89.f)); - - for (v_faces_it it = m_faces.begin(); it!=m_faces.end(); it++) - { - (*it)->flags.bSplitted = FALSE; - (*it)->CalcNormal (); - } - - // remark: - // we use Face's bSplitted value to indicate that face is processed - // so bSplitted means bUsed - for (u32 I=0; Im_adjacents.begin(); AFit != V->m_adjacents.end(); AFit++) - { - _face* F = *AFit; - F->flags.bSplitted = FALSE; - } - std::sort (V->m_adjacents.begin(), V->m_adjacents.end()); - - for (u32 AF = 0; AF < V->m_adjacents.size(); AF++) - { - _face* F = V->m_adjacents[AF]; - if (F->flags.bSplitted) continue; // Face already used in calculation - - // Create new vertex (except adjacency) - _vertex* NV = mu_vertices.create(); - NV->P = V->P; - - // Calculate it's normal - NV->N.set (0,0,0); - for (u32 NF = 0; NF < V->m_adjacents.size(); NF++) - { - _face* Fn = V->m_adjacents[NF]; - - float cosa = F->N.dotproduct(Fn->N); - if (cosa>sm_cos) - { - NV->N.add (Fn->N); - if (!Fn->flags.bSplitted) { - Fn->VReplace_not_remove (V,NV); - Fn->flags.bSplitted = true; - } - } - } - - if (NV->m_adjacents.empty()) mu_vertices.destroy(NV); - else { - NV->N.normalize_safe(); - m_vertices.push_back(NV); - } - } - } - - // Destroy unused vertices - for (u32 I=0; Im_adjacents.empty()) - { - mu_vertices.destroy (m_vertices[I]); - m_vertices.erase (m_vertices.begin()+I); - I--; - } - } - - // Clear temporary flag - for (v_faces_it it = m_faces.begin(); it!=m_faces.end(); it++) - (*it)->flags.bSplitted = FALSE; - - clMsg("%5s %d vertices duplicated","-",m_vertices.size()-Vcount); -} -*/ diff --git a/src/utils/xrLC_Light/xrMU_Model_Load.cpp b/src/utils/xrLC_Light/xrMU_Model_Load.cpp deleted file mode 100644 index fe12b117947..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Load.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "stdafx.h" -#include "xrMU_Model.h" - -#include "xrCore/xrPool.h" -poolSS<_face, 8 * 1024>& mu_faces_pool(); -poolSS<_vertex, 8 * 1024>& mu_vertices_pool(); -// extern u32 version; - -void xrMU_Model::Load(IReader& F, u32 version) -{ - F.r_stringZ(m_name); - - // READ: vertices - xr_vector b_vertices; - b_vertices.resize(F.r_u32()); - m_vertices.reserve(b_vertices.size()); - F.r(&*b_vertices.begin(), (u32)b_vertices.size() * sizeof(b_vertex)); - - // READ: faces - xr_vector b_faces; - b_faces.resize(F.r_u32()); - m_faces.reserve(b_faces.size()); - F.r(&*b_faces.begin(), (u32)b_faces.size() * sizeof(b_face)); - - // READ: lod-ID - F.r(&m_lod_ID, 2); - - xr_vector sm_groups; - sm_groups.resize(b_faces.size()); - R_ASSERT(version > 17); - F.r(&*sm_groups.begin(), (u32)sm_groups.size() * sizeof(u32)); - - // CONVERT and OPTIMIZE - for (u32 v_it = 0; v_it < b_vertices.size(); v_it++) - { - create_vertex(b_vertices[v_it]); - } - for (u32 f_it = 0; f_it < b_faces.size(); f_it++) - { - b_face& F = b_faces[f_it]; - _face* face = create_face(m_vertices[F.v[0]], m_vertices[F.v[1]], m_vertices[F.v[2]], F); - face->sm_group = sm_groups[f_it]; - } - /* - // CONVERT and OPTIMIZE - for (u32 it=0; itdwMaterial = u16(B.dwMaterial); - face->dwMaterialGame = B.dwMaterialGame; - R_ASSERT(B.dwMaterialGame < 65536); - - // Vertices and adjacement info - face->SetVertex(0, v0); - face->SetVertex(1, v1); - face->SetVertex(2, v2); - - // tc - face->tc[0] = B.t[0]; - face->tc[1] = B.t[1]; - face->tc[2] = B.t[2]; - face->CalcNormal(); - - // register - m_faces.push_back(face); - return face; -} - -_face* xrMU_Model::load_create_face(Fvector& P1, Fvector& P2, Fvector& P3, b_face& B) -{ - return create_face(load_create_vertex(P1), load_create_vertex(P2), load_create_vertex(P3), B); -} - -_vertex* xrMU_Model::create_vertex(Fvector& P) -{ - _vertex* vertex = mu_vertices_pool().create(); - vertex->P = P; - vertex->N.set(0, 0, 0); - m_vertices.push_back(vertex); - return vertex; -} - -_vertex* xrMU_Model::load_create_vertex(Fvector& P) -{ - // find similar - for (u32 it = 0; it < m_vertices.size(); it++) - { - if (m_vertices[it]->P.similar(P, .001f)) - return m_vertices[it]; - } - // create new - return create_vertex(P); -} diff --git a/src/utils/xrLC_Light/xrMU_Model_Reference.cpp b/src/utils/xrLC_Light/xrMU_Model_Reference.cpp deleted file mode 100644 index 4de04eea846..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Reference.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "stdafx.h" -#include "xrMU_Model_Reference.h" -#include "xrLC_GlobalData.h" -#include "xrMU_Model.h" -#include "xrCDB/xrCDB.h" -#include "utils/Shader_xrLC.h" -#include "xrface.h" -#include "serialize.h" - -extern tread_models* read_models; -extern twrite_models* write_models; - -void xrMU_Reference::Load(IReader& F, xr_vector& mu_models) -{ - b_mu_reference R; - F.r(&R, sizeof(R)); - model = mu_models[R.model_index]; - xform = R.transform; - flags = R.flags; - sector = R.sector; - - c_scale.rgb.set(1, 1, 1); - c_scale.hemi = 1; - c_scale.sun = 1; - c_bias.rgb.set(0, 0, 0); - c_bias.hemi = 0; - c_bias.sun = 0; -} - -void xrMU_Reference::export_cform_game(CDB::CollectorPacked& CL) -{ - // Collecting data - xrMU_Model::v_faces* cfFaces = xr_new(); - xrMU_Model::v_vertices* cfVertices = xr_new(); - { - xr_vector cfVertexMarks; - cfVertexMarks.assign(model->m_vertices.size(), false); - - std::sort(model->m_vertices.begin(), model->m_vertices.end()); - - // faces and mark vertices - cfFaces->reserve(model->m_faces.size()); - for (xrMU_Model::v_faces_it I = model->m_faces.begin(); I != model->m_faces.end(); ++I) - { - _face* F = *I; - if (F->Shader().flags.bCollision) - { - cfFaces->push_back(F); - - for (u32 vit = 0; vit < 3; vit++) - { - u32 g_id = u32(std::lower_bound(model->m_vertices.begin(), model->m_vertices.end(), F->v[vit]) - - model->m_vertices.begin()); - cfVertexMarks[g_id] = true; - } - } - } - - // verts - cfVertices->reserve(model->m_vertices.size()); - std::sort(cfFaces->begin(), cfFaces->end()); - for (u32 V = 0; V < model->m_vertices.size(); V++) - if (cfVertexMarks[V]) - cfVertices->push_back(model->m_vertices[V]); - } - - // Collect faces - u32 Offset = (u32)CL.getTS(); - for (xrMU_Model::v_faces_it F = cfFaces->begin(); F != cfFaces->end(); ++F) - { - _face* T = *F; - - // xform - Fvector P[3]; - xform.transform_tiny(P[0], T->v[0]->P); - xform.transform_tiny(P[1], T->v[1]->P); - xform.transform_tiny(P[2], T->v[2]->P); - - CL.add_face(P[0], P[1], P[2], T->dwMaterialGame, sector, T->sm_group); - } - - xr_delete(cfFaces); - xr_delete(cfVertices); -} - -void xrMU_Reference::export_cform_rcast(CDB::CollectorPacked& CL) { model->export_cform_rcast(CL, xform); } -// xrMU_Model* model; -// Fmatrix xform; -// Flags32 flags; -// u16 sector; - -// xr_vector color; - -// base_color_c c_scale; -// base_color_c c_bias; -void xrMU_Reference::read(INetReader& r) -{ - R_ASSERT(read_models); - read_models->read(r, model); - r_pod(r, xform); - r_pod(r, flags); - sector = r.r_u16(); - r_pod_vector(r, color); - r_pod(r, c_scale); - r_pod(r, c_bias); -} -void xrMU_Reference::write(IWriter& w) const -{ - R_ASSERT(write_models); - write_models->write(w, model); - w_pod(w, xform); - w_pod(w, flags); - w.w_u16(sector); - w_pod_vector(w, color); - w_pod(w, c_scale); - w_pod(w, c_bias); -} - -void xrMU_Reference::receive_result(INetReader& r) -{ - r_pod_vector(r, color); - r_pod(r, c_scale); - r_pod(r, c_bias); - // R_ASSERT( model ); - // model->read_color( r ); -} -void xrMU_Reference::send_result(IWriter& w) const -{ - w_pod_vector(w, color); - w_pod(w, c_scale); - w_pod(w, c_bias); - // R_ASSERT( model ); - // model->write_color( w ); -} diff --git a/src/utils/xrLC_Light/xrMU_Model_Reference.h b/src/utils/xrLC_Light/xrMU_Model_Reference.h deleted file mode 100644 index 0bcfb971749..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Reference.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef XRMUMODEL_REFERENCE_H -#define XRMUMODEL_REFERENCE_H - -#include "base_color.h" -#include "serialize.h" - -class xrMU_Model; -namespace CDB -{ -class CollectorPacked; -} -class INetReader; -class IWriter; -class XRLC_LIGHT_API xrMU_Reference -{ -public: - xrMU_Model* model; - Fmatrix xform; - Flags32 flags; - u16 sector; - - xr_vector color; - - base_color_c c_scale; - base_color_c c_bias; - -public: - xrMU_Reference() : model(0), sector(u16(-1)), flags(Flags32().assign(0)), xform(Fidentity) {} - void Load(IReader& fs, xr_vector& mu_models); - void calc_lighting(); - - void export_cform_game(CDB::CollectorPacked& CL); - void export_cform_rcast(CDB::CollectorPacked& CL); - - void read(INetReader& r); - void write(IWriter& w) const; - void receive_result(INetReader& r); - void send_result(IWriter& w) const; - static xrMU_Reference* read_create() { return xr_new(); }; - // void export_ogf (); -}; - -typedef vector_serialize>> tread_mu_refs; -typedef vector_serialize>> twrite_mu_refs; - -extern tread_mu_refs* read_mu_refs; -extern twrite_mu_refs* write_mu_refs; -#endif diff --git a/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp b/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp deleted file mode 100644 index 67f55a642f8..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_Reference_Calc_Lighting.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include "stdafx.h" - -#include "xrMU_Model_Reference.h" -#include "xrMU_Model.h" - -#include "light_point.h" -#include "fitter.h" -#include "xrface.h" -#include "xrLC_GlobalData.h" -template -T simple_optimize(xr_vector& A, xr_vector& B, T2& _scale, T2& _bias) -{ - T accum; - u32 it; - - T scale = _scale; - T bias = _bias; - T error = flt_max; - T elements = T(A.size()); - u32 count = 0; - for (;;) - { - count++; - if (count > 128) - { - _scale = (T2)scale; - _bias = (T2)bias; - return error; - } - - T old_scale = scale; - T old_bias = bias; - - // 1. scale - u32 _ok = 0; - for (accum = 0, it = 0; it < A.size(); it++) - if (_abs(A[it]) > EPS_L) - { - accum += (B[it] - bias) / A[it]; - _ok += 1; - } - T s = _ok ? (accum / _ok) : scale; - - // 2. bias - T b = bias; - if (_abs(scale) > EPS) - { - for (accum = 0, it = 0; it < A.size(); it++) - accum += B[it] - A[it] / scale; - b = accum / elements; - } - - // mix - T conv = 7; - scale = ((conv - 1) * scale + s) / conv; - bias = ((conv - 1) * bias + b) / conv; - - // error - for (accum = 0, it = 0; it < A.size(); it++) - accum += B[it] - (A[it] * scale + bias); - T err = accum / elements; - - if (err < error) - { - // continue? - error = err; - if (error < EPS) - { - _scale = (T2)scale; - _bias = (T2)bias; - return error; - } - } - else - { - // exit - _scale = (T2)old_scale; - _bias = (T2)old_bias; - return error; - } - } -} - -void o_test(int iA, int iB, int count, base_color* A, base_color* B, float& C, float& D) -{ - xr_vector A_, B_; - A_.resize(count); - B_.resize(count); - for (int it = 0; it < count; it++) - { - base_color_c _a; - A[it]._get(_a); - float* f_a = (float*)&_a; - base_color_c _b; - B[it]._get(_b); - float* f_b = (float*)&_b; - A_[it] = f_a[iA]; - B_[it] = f_b[iB]; - } - // C=1, D=0; - simple_optimize(A_, B_, C, D); -} - -void xrMU_Reference::calc_lighting() -{ - model->calc_lighting(color, xform, inlc_global_data()->RCAST_Model(), inlc_global_data()->L_static(), - (inlc_global_data()->b_nosun() ? LP_dont_sun : 0) | LP_DEFAULT); - - R_ASSERT(color.size() == model->color.size()); - - // A*C + D = B - // build data - { - FPU::m64r(); - xr_vector A; - A.resize(color.size()); - xr_vector B; - B.resize(color.size()); - float* _s = (float*)&c_scale; - float* _b = (float*)&c_bias; - for (u32 i = 0; i < 5; i++) - { - for (u32 it = 0; it < color.size(); it++) - { - base_color_c __A; - model->color[it]._get(__A); - base_color_c __B; - color[it]._get(__B); - A[it] = (__A.hemi); - B[it] = ((float*)&__B)[i]; - } - vfComputeLinearRegression(A, B, _s[i], _b[i]); - } - - for (u32 index = 0; index < 5; index++) - o_test(4, index, color.size(), &model->color.front(), &color.front(), _s[index], _b[index]); - } -} diff --git a/src/utils/xrLC_Light/xrMU_Model_export_cform_rcast.cpp b/src/utils/xrLC_Light/xrMU_Model_export_cform_rcast.cpp deleted file mode 100644 index bbe3408d9c0..00000000000 --- a/src/utils/xrLC_Light/xrMU_Model_export_cform_rcast.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "stdafx.h" -#include "xrMU_Model.h" -#include "xrMU_Model_Reference.h" -#include "xrCDB/xrCDB.h" -#include "utils/Shader_xrLC.h" - -void xrMU_Model::export_cform_rcast(CDB::CollectorPacked& CL, Fmatrix& xform) -{ - for (u32 fit = 0; fit < m_faces.size(); fit++) - m_faces[fit]->flags.bProcessed = false; - - v_faces adjacent; - adjacent.reserve(6 * 2 * 3); - - for (v_faces_it it = m_faces.begin(); it != m_faces.end(); ++it) - { - _face* F = (*it); - const Shader_xrLC& SH = F->Shader(); - if (!SH.flags.bLIGHT_CastShadow) - continue; - - // Collect - adjacent.clear(); - for (int vit = 0; vit < 3; vit++) - { - _vertex* V = F->v[vit]; - for (u32 adj = 0; adj < V->m_adjacents.size(); adj++) - adjacent.push_back(V->m_adjacents[adj]); - } - - // Unique - std::sort(adjacent.begin(), adjacent.end()); - adjacent.erase(std::unique(adjacent.begin(), adjacent.end()), adjacent.end()); - BOOL bAlready = FALSE; - for (u32 ait = 0; ait < adjacent.size(); ait++) - { - _face* Test = adjacent[ait]; - if (Test == F) - continue; - if (!Test->flags.bProcessed) - continue; - if (F->isEqual(*Test)) - { - bAlready = TRUE; - break; - } - } - - // - if (!bAlready) - { - F->flags.bProcessed = true; - Fvector P[3]; - xform.transform_tiny(P[0], F->v[0]->P); - xform.transform_tiny(P[1], F->v[1]->P); - xform.transform_tiny(P[2], F->v[2]->P); - CL.add_face_D(P[0], P[1], P[2], *((u32*)&F), F->sm_group); // - } - } -} diff --git a/src/utils/xrLC_Light/xrUVpoint.h b/src/utils/xrLC_Light/xrUVpoint.h deleted file mode 100644 index 5c22d58a69a..00000000000 --- a/src/utils/xrLC_Light/xrUVpoint.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -struct UVpoint -{ - float u, v; - - IC void set(float _u, float _v) - { - u = _u; - v = _v; - } - IC void set(UVpoint& p) - { - u = p.u; - v = p.v; - } - IC void min(UVpoint& p) - { - u = _min(u, p.u); - v = _min(v, p.v); - } - IC void max(UVpoint& p) - { - u = _max(u, p.u); - v = _max(v, p.v); - } - IC void sub(UVpoint& p) - { - u -= p.u; - v -= p.v; - } - IC void add(UVpoint& p) - { - u += p.u; - v += p.v; - } - IC void sub(UVpoint& p1, UVpoint& p2) - { - u = p1.u - p2.u; - v = p1.v - p2.v; - } - IC void add(UVpoint& p1, UVpoint& p2) - { - u = p1.u + p2.u; - v = p1.v + p2.v; - } - IC void mul(const float s) - { - u *= s; - v *= s; - } - IC void mul(UVpoint& p) - { - u *= p.u; - v *= p.v; - } - IC void rot90(void) - { - float t = -u; - u = v; - v = t; - } - IC float dot(UVpoint& p) { return u * p.u + v * p.v; } - IC void norm(void) - { - float m = _sqrt(u * u + v * v); - u /= m; - v /= m; - } - IC float dist(UVpoint& p) { return _sqrt((u - p.u) * (u - p.u) + (v - p.v) * (v - p.v)); } - IC BOOL similar(UVpoint& p, float eu, float ev) { return _abs(u - p.u) < eu && _abs(v - p.v) < ev; } - // average arithmetic - IC void averageA(UVpoint& p1, UVpoint& p2) - { - u = (p1.u + p2.u) * .5f; - v = (p1.v + p2.v) * .5f; - } - // average geometric - IC void averageG(UVpoint& p1, UVpoint& p2) - { - u = _sqrt(p1.u * p2.u); - v = _sqrt(p1.v * p2.v); - } - - IC Fvector2& conv() { return *((Fvector2*)this); }; -}; diff --git a/src/utils/xrLC_LightStab/packages.config b/src/utils/xrLC_LightStab/packages.config deleted file mode 100644 index 8bbd720dd81..00000000000 --- a/src/utils/xrLC_LightStab/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/utils/xrLC_LightStab/xrLC_LightStab.cpp b/src/utils/xrLC_LightStab/xrLC_LightStab.cpp deleted file mode 100644 index 79dfbe836db..00000000000 --- a/src/utils/xrLC_LightStab/xrLC_LightStab.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "xrLC_LightStab.h" -#include "utils/xrLC_Light/net_light.h" - -#include "utils/xrLC_Light/lightstab_interface.h" - -extern "C" XRLC_LIGHT_STUB_API bool __cdecl RunTask( - IAgent* agent, u32 sessionId, IGenericStream* inStream, IGenericStream* outStream) -{ - if (lc_net::g_net_task_interface) - return lc_net::g_net_task_interface->run_task(agent, sessionId, inStream, outStream); - - // if(g_net_task_interface) - // return g_net_task_interface->RunTask( agent, sessionId, inStream, outStream ); - return false; -} diff --git a/src/utils/xrLC_LightStab/xrLC_LightStab.h b/src/utils/xrLC_LightStab/xrLC_LightStab.h deleted file mode 100644 index 2ea01c4c905..00000000000 --- a/src/utils/xrLC_LightStab/xrLC_LightStab.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Common/Platform.hpp" -#include "xrCore/xr_types.h" - -#ifdef XRAY_STATIC_BUILD -#define XRLC_LIGHT_STUB_API -#else -# ifdef XRLC_LIGHT_STAB_EXPORTS -# define XRLC_LIGHT_STUB_API XR_EXPORT -# else -# define XRLC_LIGHT_STUB_API XR_IMPORT -# endif -#endif - -#include "utils/xrLC_Light/xrLC_Light.h" diff --git a/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj b/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj deleted file mode 100644 index dc2d4c73885..00000000000 --- a/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - {EC924B9B-4991-4931-8623-E1DB9AE005CA} - xrLC_LightStab - Win32Proj - - - - - - - DynamicLibrary - - - - - - - - - - - $(xrBinDir)utils\ - - - - _USRDLL;XRLC_LIGHT_STAB_EXPORTS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;FORCE_NO_EXCEPTIONS;%(PreprocessorDefinitions) - _USE_MATH_DEFINES;%(PreprocessorDefinitions) - - - - - - - - - - - - - - {efb76d6f-0092-439c-a783-c0be10bd17c9} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj.filters b/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj.filters deleted file mode 100644 index f9d4c57f879..00000000000 --- a/src/utils/xrLC_LightStab/xrLC_LightStab.vcxproj.filters +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrQSlim/CMakeLists.txt b/src/utils/xrQSlim/CMakeLists.txt deleted file mode 100644 index 5569062f2a3..00000000000 --- a/src/utils/xrQSlim/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -add_library(xrQSlim STATIC) - -target_sources(xrQSlim PRIVATE - geom3d.h - mat2.h - mat2.cpp - mat3.h - mat3.cpp - mat4.h - mat4.cpp - mixmops.h - mixmops.cpp - mixvops.h - MxBlock2.h - MxBlock.h - MxBlockModel.h - MxBlockModel.cpp - MxDefines.h - MxDynBlock.h - MxGeom3D.h - MxGeom3D.cpp - MxGeoPrims.h - MxHeap.h - MxHeap.cpp - MxMat2.h - MxMat3.h - MxMat3-jacobi.cpp - MxMat4-jacobi.cpp - MxMat4.h - MxMatrix.h - MxMatrix.cpp - MxPropSlim.h - MxPropSlim.cpp - MxQMetric3.h - MxQMetric3.cpp - MxQMetric.h - MxQMetric.cpp - MxQSlim.h - MxQSlim.cpp - MxStdModel.h - MxStdModel.cpp - MxStdSlim.h - MxStdSlim.cpp - MxVec3.h - MxVec4.h - MxVector.h - stdafx.h - vec2.h - vec3.h - vec4.h -) - -target_include_directories(xrQSlim - PRIVATE - "${CMAKE_SOURCE_DIR}/src" -) - -target_compile_definitions(xrQSlim - PUBLIC - XR_QSLIM_EXPORTS -) diff --git a/src/utils/xrQSlim/MxBlock.h b/src/utils/xrQSlim/MxBlock.h deleted file mode 100644 index d64b9b25207..00000000000 --- a/src/utils/xrQSlim/MxBlock.h +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once - -/************************************************************************ - - MxBlock provides typed access a contiguous block of elements. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxBlock.h,v 1.18.2.1 2004/07/01 18:38:41 garland Exp $ - - ************************************************************************/ - -// This trivial allocator is a trick we use to resize the array -// without destructing and reconstructing all the elements. -// -enum _array_alloc_policy -{ - ARRAY_ALLOC_INPLACE -}; -inline void* operator new(size_t, void* p, _array_alloc_policy) { return p; } -#if _MSC_VER >= 1200 -// -// This matching delete operator is necessary to avoid warnings in -// VC++ 6.0. For some reason, it seems to periodically cause internal -// compiler errors in some GCC 2.95.x compilers. -// -inline void operator delete(void* mem, void* spot, _array_alloc_policy) {} -#endif - -template -class MxBlock -{ -private: - int N; - T* block; - -protected: - MxBlock() {} - void init_block(int n) - { - // Allocate memory for block - N = n; - block = xr_alloc(n); - - // Initialize each entry - for (int i = 0; i < n; i++) - new ((void*)&block[i], ARRAY_ALLOC_INPLACE) T; - } - void resize_block(int n) - { - T* old = block; - - // Allocate new block - block = (T*)xr_realloc(old, sizeof(T) * n); - - // Initialize all the newly allocated entries - for (int i = N; i < n; i++) - new ((void*)&block[i], ARRAY_ALLOC_INPLACE) T; - - N = n; - } - void free_block() - { - /* - //. - #if defined(_MSC_VER) - // The Microsoft compiler has a problem with the - // standard syntax below. For some reason, - // expanding it into the following pointer-based - // version makes it work. Don't ask me why. - // - for(int i=0; i~T(); } - xr_free(block); - #else - */ - // Call the relevant destructors for each element before - // freeing the block. Has now effect for types like 'int'. - // - for (int i = 0; i < N; i++) - block[i].~T(); - xr_free(block); - //#endif - } - -public: - MxBlock(int n) { init_block(n); } - ~MxBlock() { free_block(); } - operator const T*() const { return block; } - operator T*() { return block; } - int length() const { return N; } - // These parenthesized accessors are included for backwards - // compatibility. Their continued use is discouraged. - // - T& operator()(int i) { return (*this)[i]; } - const T& operator()(int i) const { return (*this)[i]; } - // Primitive methods for altering the data block - // - void resize(int n) { resize_block(n); } - void bitcopy(const T* a, int n) // copy bits directly - { - CopyMemory(block, a, std::min(n, N) * sizeof(T)); - } - void copy(const T* a, const int n) // copy using assignment operator - { - for (int i = 0; i < std::min(n, N); i++) - block[i] = a[i]; - } - void bitcopy(const MxBlock& b) { bitcopy(b, b.length()); } - void copy(const MxBlock& b) { copy(b, b.length()); } - // Restricted STL-like interface for interoperability with - // STL-based code. - // - typedef T value_type; - typedef value_type* iterator; - typedef value_type* const_iterator; - - int size() const { return length(); } - iterator begin() { return block; } - const_iterator begin() const { return block; } - iterator end() { return begin() + size(); } - const_iterator end() const { return begin() + size(); } -}; diff --git a/src/utils/xrQSlim/MxBlock2.h b/src/utils/xrQSlim/MxBlock2.h deleted file mode 100644 index 50f1a3fd2c2..00000000000 --- a/src/utils/xrQSlim/MxBlock2.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef MXBLOCK2_INCLUDED // -*- C++ -*- -#define MXBLOCK2_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - MxBlock2 provides typed access to 2D data blocks. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxBlock2.h,v 1.10.2.1 2004/07/01 18:38:41 garland Exp $ - - ************************************************************************/ - -#include "MxBlock.h" - -template -class MxBlock2 : public MxBlock -{ -private: - int W, H; - -protected: - MxBlock2() {} -public: - MxBlock2(int w, int h) : MxBlock(w * h) - { - W = w; - H = h; - } - - T& operator()(int i, int j) { return (*this)[j * W + i]; } - const T& operator()(int i, int j) const { return (*this)[j * W + i]; } - int width() const { return W; } - int height() const { return H; } - void resize(int w, int h) - { - W = w; - H = h; - MxBlock::resize_block(w * h); - } -}; - -// MXBLOCK2_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxBlockModel.cpp b/src/utils/xrQSlim/MxBlockModel.cpp deleted file mode 100644 index 072872bf0aa..00000000000 --- a/src/utils/xrQSlim/MxBlockModel.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/************************************************************************ - - MxBlockModel - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxBlockModel.cxx,v 1.27 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxBlockModel.h" -#include "MxVector.h" - -//////////////////////////////////////////////////////////////////////// -// -// Basic allocation routines -// - -MxBlockModel* MxBlockModel::clone(MxBlockModel* m) -{ - if (!m) - m = xr_new(vert_count(), face_count()); - - unsigned int i; - - for (i = 0; i < vert_count(); i++) - m->add_vertex(vertex(i)); - for (i = 0; i < face_count(); i++) - m->add_face(face(i)[0], face(i)[1], face(i)[2]); - - m->normal_binding((u8)normal_binding()); - if (normal_binding() != MX_UNBOUND) - { - m->normals->room_for(normal_count()); - m->normals->bitcopy(*normals); - } - - m->color_binding((u8)color_binding()); - if (color_binding() != MX_UNBOUND) - { - m->colors->room_for(color_count()); - m->colors->bitcopy(*colors); - } - - m->texcoord_binding((u8)texcoord_binding()); - if (texcoord_binding() != MX_UNBOUND) - { - m->tcoords->room_for(texcoord_count()); - m->tcoords->bitcopy(*tcoords); - } - - return m; -} - -MxFaceID MxBlockModel::alloc_face(MxVertexID v1, MxVertexID v2, MxVertexID v3) -{ - faces.add(MxFace(v1, v2, v3)); - return faces.last_id(); -} - -MxVertexID MxBlockModel::alloc_vertex(float x, float y, float z) -{ - vertices.add(MxVertex(x, y, z)); - return vertices.last_id(); -} - -MxVertexID MxBlockModel::add_vertex(float x, float y, float z) -{ - auto id = alloc_vertex(x, y, z); - init_vertex(id); - return id; -} - -void MxBlockModel::remove_vertex(MxVertexID v) -{ - VERIFY(v < (unsigned int)vertices.length()); - - free_vertex(v); - vertices.remove(v); - if (normal_binding() == MX_PERVERTEX) - normals->remove(v); - if (color_binding() == MX_PERVERTEX) - colors->remove(v); - if (texcoord_binding() == MX_PERVERTEX) - tcoords->remove(v); -} - -void MxBlockModel::remove_face(MxFaceID f) -{ - VERIFY(f < (unsigned int)faces.length()); - - free_face(f); - faces.remove(f); - if (normal_binding() == MX_PERFACE) - normals->remove(f); - if (color_binding() == MX_PERFACE) - colors->remove(f); - if (texcoord_binding() == MX_PERFACE) - tcoords->remove(f); -} - -MxFaceID MxBlockModel::add_face(unsigned int v1, unsigned int v2, unsigned int v3, bool will_link) -{ - auto id = alloc_face(v1, v2, v3); - if (will_link) - init_face(id); - return id; -} - -unsigned int MxBlockModel::add_color(float r, float g, float b) -{ - VERIFY(colors); - MxColor c(r, g, b); - colors->add(c); - return colors->last_id(); -} - -unsigned int MxBlockModel::add_normal(float x, float y, float z) -{ - MxNormal n(x, y, z); - normals->add(n); - return normals->last_id(); -} - -unsigned int MxBlockModel::add_texcoord(float s, float t) -{ - tcoords->add(MxTexCoord(s, t)); - return tcoords->last_id(); -} - -unsigned int MxBlockModel::add_texmap(const char* name) -{ - if (!name) - name = "tex"; - - if (tex_name) - xr_free(tex_name); - - tex_name = xr_strdup(name); - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// -// Property binding -// - -static const char* bindings[] = {"unbound", "face", "vertex", NULL}; - -static unsigned int binding_size(MxBlockModel& m, unsigned char i) -{ - switch (i) - { - case MX_UNBOUND: return 0; - case MX_PERVERTEX: return std::max(1u, m.vert_count()); - case MX_PERFACE: return std::max(1u, m.face_count()); - default: return 0; - } -} - -const char* MxBlockModel::binding_name(int b) -{ - if (b > MX_MAX_BINDING) - return NULL; - return bindings[b]; -} - -int MxBlockModel::parse_binding(const char* name) -{ - for (int i = 0; i <= MX_MAX_BINDING; i++) - if (streq(bindings[i], name)) - return i; - - return MX_UNBOUND; -} - -void MxBlockModel::color_binding(unsigned char b) -{ - int size = binding_size(*this, b); - - if (b == MX_UNBOUND) - { - if (colors) - { - xr_delete(colors); - } - binding_mask &= (~MX_COLOR_MASK); - } - else - { - if (colors) - colors->reset(); - else - colors = xr_new>(size); - binding_mask |= MX_COLOR_MASK; - } - - cbinding = b; -} - -void MxBlockModel::normal_binding(unsigned char b) -{ - int size = binding_size(*this, b); - - if (b == MX_UNBOUND) - { - if (normals) - { - xr_delete(normals); - } - binding_mask &= (~MX_NORMAL_MASK); - } - else - { - if (normals) - normals->reset(); - else - normals = xr_new>(size); - binding_mask |= MX_NORMAL_MASK; - } - - nbinding = b; -} - -void MxBlockModel::texcoord_binding(unsigned char b) -{ - if (b != MX_UNBOUND && b != MX_PERVERTEX) - FATAL("Illegal texture coordinate binding."); - - int size = binding_size(*this, b); - if (tcoords) - tcoords->reset(); - else - tcoords = xr_new>(size); - - tbinding = b; -} - -//////////////////////////////////////////////////////////////////////// -// -// Utility methods for computing characteristics of faces. -// - -void MxBlockModel::compute_face_normal(MxFaceID f, float* n, bool will_unitize) -{ - float* v1 = vertex(face(f)[0]); - float* v2 = vertex(face(f)[1]); - float* v3 = vertex(face(f)[2]); - - float a[3], b[3]; - - mxv_sub(a, v2, v1, 3); - mxv_sub(b, v3, v1, 3); - mxv_cross3(n, a, b); - if (will_unitize) - mxv_unitize(n, 3); -} - -void MxBlockModel::compute_face_normal(MxFaceID f, double* n, bool will_unitize) -{ - float* v1 = vertex(face(f)[0]); - float* v2 = vertex(face(f)[1]); - float* v3 = vertex(face(f)[2]); - - double a[3], b[3]; - for (int i = 0; i < 3; i++) - { - a[i] = v2[i] - v1[i]; - b[i] = v3[i] - v1[i]; - } - - mxv_cross3(n, a, b); - if (will_unitize) - mxv_unitize(n, 3); -} - -void MxBlockModel::compute_face_plane(MxFaceID f, float* p, bool will_unitize) -{ - compute_face_normal(f, p, will_unitize); - p[3] = -mxv_dot(p, corner(f, 0), 3); -} - -double MxBlockModel::compute_face_area(MxFaceID f) -{ - double n[3]; - - compute_face_normal(f, n, false); - return 0.5 * mxv_norm(n, 3); -} - -double MxBlockModel::compute_face_perimeter(MxFaceID fid, bool* flags) -{ - double perim = 0.0; - const auto& f = face(fid); - - for (unsigned int i = 0; i < 3; i++) - { - if (!flags || flags[i]) - { - float *vi = vertex(f[i]), *vj = vertex(f[(i + 1) % 3]), e[3]; - perim += mxv_norm(mxv_sub(e, vi, vj, 3), 3); - } - } - - return perim; -} - -double MxBlockModel::compute_corner_angle(MxFaceID f, unsigned int i) -{ - auto i_prev = (i == 0) ? 2 : i - 1; - auto i_next = (i == 2) ? 0 : i + 1; - - float e_prev[3], e_next[3]; - mxv_unitize(mxv_sub(e_prev, corner(f, (short)i_prev), corner(f, (short)i), 3), 3); - mxv_unitize(mxv_sub(e_next, corner(f, (short)i_next), corner(f, (short)i), 3), 3); - - return acos(mxv_dot(e_prev, e_next, 3)); -} diff --git a/src/utils/xrQSlim/MxBlockModel.h b/src/utils/xrQSlim/MxBlockModel.h deleted file mode 100644 index cd9444c2517..00000000000 --- a/src/utils/xrQSlim/MxBlockModel.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef MXBLOCKMODEL_INCLUDED // -*- C++ -*- -#define MXBLOCKMODEL_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - MxBlockModel - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxBlockModel.h,v 1.24 2000/02/03 17:32:21 garland Exp $ - - ************************************************************************/ - -#include "MxDynBlock.h" -#include "MxGeoPrims.h" - -#define MX_UNBOUND 0x0 -#define MX_PERFACE 0x1 -#define MX_PERVERTEX 0x2 -#define MX_MAX_BINDING 0x2 - -#define MX_NORMAL_MASK 0x3 -#define MX_COLOR_MASK (0x3 << 2) -#define MX_TEXTURE_MASK (0x3 << 4) -#define MX_ALL_MASK (MX_NORMAL_MASK | MX_COLOR_MASK | MX_TEXTURE_MASK) - -class MxBlockModel -{ -private: - unsigned char cbinding, nbinding, tbinding; - - unsigned int flags; - - // Required blocks - MxDynBlock vertices; - MxDynBlock faces; - - // Optional blocks - MxDynBlock* normals; - MxDynBlock* colors; - MxDynBlock* tcoords; - // prop_block *properties; // Indirect block for arbitrary properties - - // Optional texture map - char* tex_name; - -protected: - virtual MxVertexID alloc_vertex(float, float, float); - virtual void init_vertex(MxVertexID) {} - virtual void free_vertex(MxVertexID) {} - virtual MxFaceID alloc_face(MxVertexID, MxVertexID, MxVertexID); - virtual void init_face(MxFaceID) {} - virtual void free_face(MxFaceID) {} -public: - unsigned int binding_mask; - -public: - MxBlockModel(int nvert, int nface) : vertices(nvert), faces(nface) - { - colors = NULL; - normals = NULL; - tcoords = NULL; - cbinding = nbinding = tbinding = MX_UNBOUND; - binding_mask = MX_ALL_MASK; - tex_name = NULL; - } - virtual ~MxBlockModel() - { - if (normals) - xr_delete(normals); - if (colors) - xr_delete(colors); - if (tcoords) - xr_delete(tcoords); - if (tex_name) - xr_free(tex_name); - } - - MxBlockModel* clone(MxBlockModel* into = NULL); - - unsigned int vert_count() const { return vertices.length(); } - unsigned int face_count() const { return faces.length(); } - unsigned int color_count() const { return (colors ? colors->length() : 0); } - unsigned int normal_count() const { return (normals ? normals->length() : 0); } - unsigned int texcoord_count() const { return (tcoords ? tcoords->length() : 0); } - MxVertexID add_vertex(float, float, float); - MxFaceID add_face(unsigned int, unsigned int, unsigned int, bool will_link = true); - unsigned int add_color(float, float, float); - unsigned int add_normal(float, float, float); - unsigned int add_texcoord(float, float); - - MxVertexID add_vertex(float* v) { return add_vertex(v[0], v[1], v[2]); } - MxFaceID add_face(unsigned int* f) { return add_face(f[0], f[1], f[2]); } - void remove_vertex(MxVertexID v); - void remove_face(MxFaceID f); - - MxVertex& vertex(unsigned int i) { return vertices(i); } - MxFace& face(unsigned int i) { return faces(i); } - MxVertex& corner(MxFaceID f, short i) { return vertex(face(f)[i]); } - MxColor& color(unsigned int i) - { - VERIFY(colors); - return (*colors)(i); - } - MxNormal& normal(unsigned int i) - { - VERIFY(normals); - return (*normals)(i); - } - MxTexCoord& texcoord(unsigned int i) - { - VERIFY(tcoords); - return (*tcoords)(i); - } - - int color_binding() { return (cbinding & (binding_mask >> 2)); } - int normal_binding() { return (nbinding & binding_mask); } - int texcoord_binding() { return (tbinding & (binding_mask >> 4)); } - void color_binding(unsigned char b); - void normal_binding(unsigned char b); - void texcoord_binding(unsigned char b); - - const char* binding_name(int); - int parse_binding(const char*); - - const char* texmap_name() const { return tex_name; } - unsigned int add_texmap(const char* name); - - void compute_face_normal(MxFaceID, double*, bool will_unitize = true); - void compute_face_normal(MxFaceID, float*, bool will_unitize = true); - void compute_face_plane(MxFaceID, float*, bool will_unitize = true); - double compute_face_area(MxFaceID); - double compute_face_perimeter(MxFaceID, bool* edge_flags = NULL); - - double compute_corner_angle(MxFaceID, unsigned int); -}; - -// MXBLOCKMODEL_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxDefines.h b/src/utils/xrQSlim/MxDefines.h deleted file mode 100644 index d7ebf4fe197..00000000000 --- a/src/utils/xrQSlim/MxDefines.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#ifndef MxDefinesH -#define MxDefinesH -#include "xrCommon/math_funcs_inline.h" - -//////////////////////////////////////////////////////////////////////// -const double FEQ_EPS = 1e-6; -const double FEQ_EPS2 = 1e-12; -inline bool FEQ(double a, double b, double e = FEQ_EPS) { return _abs(a - b) < e; } -inline bool FEQ2(double a, double b, double e = FEQ_EPS2) { return _abs(a - b) < e; } -//////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/utils/xrQSlim/MxDynBlock.h b/src/utils/xrQSlim/MxDynBlock.h deleted file mode 100644 index 637b129177c..00000000000 --- a/src/utils/xrQSlim/MxDynBlock.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -/************************************************************************ - -MxDynBlocks are blocks that automatically grow to fit the data added -to them. - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: MxDynBlock.h,v 1.14.2.1 2004/07/01 18:38:41 garland Exp $ - -************************************************************************/ - -#include "MxBlock.h" - -template -class MxDynBlock : public MxBlock -{ -private: - int fill; - using MxBlock::resize; - using MxBlock::begin; - -public: - MxDynBlock(int n = 2) : MxBlock(n) { fill = 0; } - int length() const { return fill; } - int total_space() const { return MxBlock::length(); } - int last_id() const { return fill - 1; } - T& last() { return (*this)[last_id()]; } - const T& last() const { return (*this)[last_id()]; } - void room_for(int len) - { - if (length() < len) - resize(len); - fill = len; - } - - T& add() - { - if (length() == total_space()) - resize(total_space() * 2); - fill++; - return last(); - } - - void add(const T& t) { add() = t; } - void reset() { fill = 0; } - T& drop() { return (*this)[--fill]; } - void drop(int d) { fill -= d; } - void remove(int i) { (*this)[i] = (*this)[--fill]; } -#if defined(XR_PLATFORM_WINDOWS) // Не буду удалять потому как не понимаю как оно собирается на винде - void remove_inorder(int i) { Memory.mem_move(&(*this)[i], &(*this)[i + 1], (--fill - i) * sizeof(T)); } -#endif - // Restricted STL-like interface for interoperability with - // STL-based code. Overrides select MxBlock<> definitions and - // introduces some additional std::vector-like methods. - // - int size() const { return length(); } - typename MxBlock::iterator end() { return begin() + size(); } - typename MxBlock::const_iterator end() const { return begin() + size(); } - void push_back(const T& t) { add(t); } -}; - -template -class MxSizedDynBlock : public MxDynBlock -{ -public: - MxSizedDynBlock(unsigned int n = T_SIZE) : MxDynBlock(n) {} -}; - -template -inline bool varray_find(const MxDynBlock& A, const T& t, unsigned int* index = NULL) -{ - for (unsigned int i = 0; i < (unsigned int)A.length(); i++) - if (A[i] == t) - { - if (index) - *index = i; - return true; - } - return false; -} diff --git a/src/utils/xrQSlim/MxGeoPrims.h b/src/utils/xrQSlim/MxGeoPrims.h deleted file mode 100644 index b64346235f3..00000000000 --- a/src/utils/xrQSlim/MxGeoPrims.h +++ /dev/null @@ -1,343 +0,0 @@ -#ifndef MXGEOPRIMS_INCLUDED // -*- C++ -*- -#define MXGEOPRIMS_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - MxGeoPrims - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxGeoPrims.h,v 1.26.2.1 2004/07/01 18:56:32 garland Exp $ - - ************************************************************************/ - -// -// Standard names for ID types -// -typedef unsigned int MxVertexID; -typedef unsigned int MxFaceID; - -// -// Convenient nicknames -// -#define VID MxVertexID -#define FID MxFaceID - -#if !defined(MX_COLOR_RGBA) && !defined(MX_COLOR_ABGR) -#define MX_COLOR_RGBA -#endif - -#if !defined(HAVE_RINT) -inline double rint(double x) { return floor(x + 0.5); } -#endif - -class MxColor -{ -private: - inline unsigned char _ftop(float x) { return (unsigned char)((x > 1.0f ? 1.0f : x) * 255.0f); } - inline float _ptof(unsigned char c) const { return ((float)c) / 255.0f; } -public: - union - { -#if defined(MX_COLOR_RGBA) - struct - { - unsigned char r, g, b, a; - } chan; -#elif defined(MX_COLOR_ABGR) - struct - { - unsigned char a, b, g, r; - } chan; -#else -#error "Packed color format illegal or left unspecified" -#endif - unsigned int word; - } as; - - MxColor() {} - MxColor(float r, float g, float b) - { - as.chan.a = 0; - set(r, g, b); - } - - void set(float r, float g, float b) - { - as.chan.r = _ftop(r); - as.chan.g = _ftop(g); - as.chan.b = _ftop(b); - } - void set(const float* c) - { - as.chan.r = _ftop(c[0]); - as.chan.g = _ftop(c[1]); - as.chan.b = _ftop(c[2]); - } - void set(const double* c) - { - as.chan.r = _ftop((float)c[0]); - as.chan.g = _ftop((float)c[1]); - as.chan.b = _ftop((float)c[2]); - } - - float R() const { return _ptof(as.chan.r); } - float G() const { return _ptof(as.chan.g); } - float B() const { return _ptof(as.chan.b); } -}; - -class MxTexCoord -{ -public: - float u[2]; - - MxTexCoord() {} - MxTexCoord(float s, float t) - { - u[0] = s; - u[1] = t; - } - MxTexCoord(const MxTexCoord& t) { *this = t; } - float& operator[](int i) { return u[i]; } - float operator[](int i) const { return u[i]; } - operator const float*() const { return u; } - operator const float*() { return u; } - operator float*() { return u; } - MxTexCoord& operator=(const MxTexCoord& t) - { - u[0] = t[0]; - u[1] = t[1]; - return *this; - } -}; - -class MxVertex -{ -public: - union - { - float pos[3]; - struct - { - MxVertexID parent, next, prev; - } proxy; - } as; - - MxVertex() {} - MxVertex(float x, float y, float z) - { - as.pos[0] = x; - as.pos[1] = y; - as.pos[2] = z; - } - MxVertex(const MxVertex& v) { *this = v; } - MxVertex& operator=(const MxVertex& v) - { - as.pos[0] = v.as.pos[0]; - as.pos[1] = v.as.pos[1]; - as.pos[2] = v.as.pos[2]; - return *this; - } - operator const float*() const { return as.pos; } - operator const float*() { return as.pos; } - operator float*() { return as.pos; } - float& operator()(int i) { return as.pos[i]; } - float operator()(int i) const { return as.pos[i]; } - // - // The [] operator is preferred over () - // - float& operator[](int i) { return as.pos[i]; } - float operator[](int i) const { return as.pos[i]; } -}; - -class MxNormal -{ -private: - inline short _ftos(float x) { return (short)rint((x > 1.0f ? 1.0f : x) * (float)SHRT_MAX); } - inline short _dtos(double x) { return (short)rint((x > 1.0 ? 1.0 : x) * (double)SHRT_MAX); } - inline float _stof(short s) const { return (float)s / (float)SHRT_MAX; } - inline double _stod(short s) const { return (double)s / (double)SHRT_MAX; } - short dir[3]; - -public: - MxNormal() {} - MxNormal(float x, float y, float z) { set(x, y, z); } - MxNormal(const float* v) { set(v); } - MxNormal(const double* v) { set(v); } - inline void set(double x, double y, double z) - { - dir[0] = _dtos(x); - dir[1] = _dtos(y); - dir[2] = _dtos(z); - } - inline void set(const float* v) - { - dir[0] = _ftos(v[0]); - dir[1] = _ftos(v[1]); - dir[2] = _ftos(v[2]); - } - inline void set(const double* v) - { - dir[0] = _dtos(v[0]); - dir[1] = _dtos(v[1]); - dir[2] = _dtos(v[2]); - } - - float operator[](unsigned int i) const - { - VERIFY(i < 3); - return _stof(dir[i]); - } - short raw(unsigned int i) const { return dir[i]; } - const short* raw() const { return dir; } -}; - -class MxEdge -{ -public: - MxVertexID v1, v2; - - MxEdge() { v1 = v2 = 0xFFFFFFFFU; } - MxEdge(MxVertexID a, MxVertexID b) - { - v1 = a; - v2 = b; - } - MxEdge(const MxEdge& e) - { - v1 = e.v1; - v2 = e.v2; - } - - MxVertexID opposite_vertex(MxVertexID v) - { - if (v == v1) - return v2; - else - { - VERIFY(v == v2); - return v1; - } - } -}; - -class MxFace -{ -public: - MxVertexID v[3]; - - MxFace() {} - MxFace(MxVertexID v0, MxVertexID v1, MxVertexID v2) - { - v[0] = v0; - v[1] = v1; - v[2] = v2; - } - MxFace(const MxFace& f) - { - v[0] = f.v[0]; - v[1] = f.v[1]; - v[2] = f.v[2]; - } - - MxVertexID& operator()(int i) { return v[i]; } - MxVertexID operator()(int i) const { return v[i]; } - // - // The [] operator is now preferred over the () operator. - // - MxVertexID& operator[](int i) { return v[i]; } - MxVertexID operator[](int i) const { return v[i]; } - int remap_vertex(MxVertexID from, MxVertexID to) - { - int nmapped = 0; - for (int i = 0; i < 3; i++) - if (v[i] == from) - { - v[i] = to; - nmapped++; - } - return nmapped; - } - - unsigned int find_vertex(MxVertexID i) - { - if (v[0] == i) - return 0; - else if (v[1] == i) - return 1; - else - { - VERIFY(v[2] == i); - return 2; - } - } - - MxVertexID opposite_vertex(MxVertexID v0, MxVertexID v1) - { - if (v[0] != v0 && v[0] != v1) - return v[0]; - else if (v[1] != v0 && v[1] != v1) - return v[1]; - else - { - VERIFY(v[2] != v0 && v[2] != v1); - return v[2]; - } - } - - bool is_inorder(MxVertexID v0, MxVertexID v1) - { - if (v[0] == v0) - return v[1] == v1; - else if (v[1] == v0) - return v[2] == v1; - else - { - VERIFY(v[2] == v0); - return v[0] == v1; - } - } -}; - -/* -inline ostream& operator<<(ostream& out, const MxVertex& v) -{ - return out << "v " << v(0) << " " << v(1) << " " << v(2); -} - -inline ostream& operator<<(ostream& out, const MxFace& f) -{ - return out << "f " << f(0)+1 << " " << f(1)+1 << " " << f(2)+1; -} - -inline ostream& operator<<(ostream& out, const MxColor& c) -{ - return out << "c " << c.R() << " " << c.G() << " " << c.B(); -} - -inline ostream& operator<<(ostream& out, const MxNormal& n) -{ - return out << "n " << n[0] << " " << n[1] << " " << n[2]; -} - -inline ostream& operator<<(ostream& out, const MxTexCoord& t) -{ - return out << "r " << t[0] << " " << t[1]; -} -*/ -#ifdef MXGL_INCLUDED -inline void glC(const MxColor& c) { glColor3ub(c.as.chan.r, c.as.chan.g, c.as.chan.b); } -inline void glT(const MxTexCoord& t) { glTexCoord2fv(t); } -inline void glV(const MxVertex& v) { glVertex3fv(v); } -inline void glN(const MxNormal& n) { glNormal3sv(n.raw()); } -inline void glC(const MxColor* c) { glC(*c); } -inline void glT(const MxTexCoord* t) { glT(*t); } -inline void glV(const MxVertex* v) { glV(*v); } -inline void glN(const MxNormal* n) { glN(*n); } -#endif - -// MXGEOPRIMS_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxGeom3D.cpp b/src/utils/xrQSlim/MxGeom3D.cpp deleted file mode 100644 index 321b7a33b49..00000000000 --- a/src/utils/xrQSlim/MxGeom3D.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/************************************************************************ - - Handy 3D geometrical primitives - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxGeom3D.cxx,v 1.13 2000/12/14 17:47:43 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxGeom3D.h" -#include "xrCore/_std_extensions.h" - -void mx3d_box_corners(const Vec3& min, const Vec3& max, Vec3* v) -{ - v[0] = min; - v[1] = Vec3(min[0], max[1], min[2]); - v[2] = Vec3(max[0], min[1], min[2]); - v[3] = Vec3(max[0], max[1], min[2]); - v[4] = Vec3(min[0], min[1], max[2]); - v[5] = Vec3(min[0], max[1], max[2]); - v[6] = Vec3(max[0], min[1], max[2]); - v[7] = max; -} - -//////////////////////////////////////////////////////////////////////// -// -// Basic bounding volumes. -// This has been imported pretty much directly from GFX -// - -void MxBounds::reset() -{ - center[0] = center[1] = center[2] = 0.0; - radius = 0.0; - - points = 0; - is_initialized = false; -} - -void MxBounds::add_point(const double* v, bool will_update) -{ - if (!is_initialized) - { - min[0] = max[0] = v[0]; - min[1] = max[1] = v[1]; - min[2] = max[2] = v[2]; - is_initialized = true; - } - else - { - if (v[0] < min[0]) - min[0] = v[0]; - if (v[1] < min[1]) - min[1] = v[1]; - if (v[2] < min[2]) - min[2] = v[2]; - - if (v[0] > max[0]) - max[0] = v[0]; - if (v[1] > max[1]) - max[1] = v[1]; - if (v[2] > max[2]) - max[2] = v[2]; - } - - if (will_update) - { - center += Vec3(v); - points++; - } -} - -void MxBounds::add_point(const float* v, bool will_update) -{ - if (!is_initialized) - { - min[0] = max[0] = v[0]; - min[1] = max[1] = v[1]; - min[2] = max[2] = v[2]; - is_initialized = true; - } - else - { - if (v[0] < min[0]) - min[0] = v[0]; - if (v[1] < min[1]) - min[1] = v[1]; - if (v[2] < min[2]) - min[2] = v[2]; - - if (v[0] > max[0]) - max[0] = v[0]; - if (v[1] > max[1]) - max[1] = v[1]; - if (v[2] > max[2]) - max[2] = v[2]; - } - - if (will_update) - { - center += Vec3(v); - points++; - } -} - -void MxBounds::complete() -{ - center /= (double)points; - - Vec3 R1 = max - center; - Vec3 R2 = min - center; - - radius = std::max(norm(R1), norm(R2)); -} - -void MxBounds::merge(const MxBounds& b) -{ - add_point(b.min, false); - add_point(b.max, false); - points += b.points; - - Vec3 dC = b.center - center; - double dist = norm(dC); - - if (dist + b.radius > radius) - { - // New sphere does not lie within old sphere - center += b.center; - center /= 2; - - dist /= 2; - radius = std::max(dist + radius, dist + b.radius); - } -} diff --git a/src/utils/xrQSlim/MxGeom3D.h b/src/utils/xrQSlim/MxGeom3D.h deleted file mode 100644 index 81293d15992..00000000000 --- a/src/utils/xrQSlim/MxGeom3D.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef MXGEOM3D_INCLUDED // -*- C++ -*- -#define MXGEOM3D_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Handy 3D geometrical primitives - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxGeom3D.h,v 1.14 2000/12/14 17:47:43 garland Exp $ - - ************************************************************************/ - -#include "geom3d.h" -#include "MxVec3.h" -#include "MxVec4.h" - -extern double triangle_project_point(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v, Vec3* bary = NULL); - -extern void mx3d_box_corners(const Vec3& min, const Vec3& max, Vec3* v); - -class MxBounds -{ -public: - bool is_initialized; - Vec3 min, max; - Vec3 center; - double radius; - unsigned int points; - - void reset(); - void add_point(const double* v, bool will_update = true); - void add_point(const float* v, bool will_update = true); - void complete(); - void merge(const MxBounds&); - - MxBounds() { reset(); } -}; - -class MxPlane3 -{ -private: - float p[4]; - -public: - MxPlane3() {} - MxPlane3(const float* p0) - { - for (unsigned int i = 0; i < 4; i++) - p[i] = p0[i]; - } - MxPlane3(const MxPlane3& n) { *this = n; } - inline MxPlane3& operator=(const MxPlane3& n); - - operator const float*() const { return p; } - operator float*() { return p; } -#ifdef __GNUC__ - float& operator[](int i) { return p[i]; } - const float& operator[](int i) const { return p[i]; } -#endif -}; - -inline MxPlane3& MxPlane3::operator=(const MxPlane3& n) -{ - for (unsigned int i = 0; i < 4; i++) - p[i] = n.p[i]; - return *this; -} - -// MXGEOM3D_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxHeap.cpp b/src/utils/xrQSlim/MxHeap.cpp deleted file mode 100644 index 1d6fd853cdd..00000000000 --- a/src/utils/xrQSlim/MxHeap.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************************************ - - Heap data structure - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxHeap.cxx,v 1.7 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxHeap.h" - -#define ref(i) ((*this)[i]) - -//////////////////////////////////////////////////////////////////////// -// -// Internal functions for manipulating the heap - -inline void MxHeap::place(MxHeapable* x, unsigned int i) -{ - ref(i) = x; - x->set_heap_pos(i); -} - -void MxHeap::swap(unsigned int i, unsigned int j) -{ - MxHeapable* tmp = ref(i); - - place(ref(j), i); - place(tmp, j); -} - -void MxHeap::upheap(unsigned int i) -{ - MxHeapable* moving = ref(i); - unsigned int index = i; - unsigned int p = parent(i); - - while (index > 0 && moving->heap_key() > ref(p)->heap_key()) - { - place(ref(p), index); - index = p; - p = parent(p); - } - - if (index != i) - place(moving, index); -} - -void MxHeap::downheap(unsigned int i) -{ - MxHeapable* moving = ref(i); - unsigned int index = i; - unsigned int l = left(i); - unsigned int r = right(i); - unsigned int largest; - - while (l < (unsigned int)length()) - { - if (r < (unsigned int)length() && ref(l)->heap_key() < ref(r)->heap_key()) - largest = r; - else - largest = l; - - if (moving->heap_key() < ref(largest)->heap_key()) - { - place(ref(largest), index); - index = largest; - l = left(index); - r = right(index); - } - else - break; - } - - if (index != i) - place(moving, index); -} - -//////////////////////////////////////////////////////////////////////// -// -// Exported interface to the heap -// - -void MxHeap::insert(MxHeapable* t, float v) -{ - t->heap_key(v); - - add(t); - unsigned int i = last_id(); - t->set_heap_pos(i); - - upheap(i); -} - -void MxHeap::update(MxHeapable* t, float v) -{ - // VERIFY( t->is_in_heap() ); - t->heap_key(v); - - unsigned int i = t->get_heap_pos(); - - if (i > 0 && v > ref(parent(i))->heap_key()) - upheap(i); - else - downheap(i); -} - -MxHeapable* MxHeap::extract() -{ - if (length() < 1) - return 0; // NULL; - - swap(0, length() - 1); - MxHeapable* dead = drop(); - - downheap(0); - dead->not_in_heap(); - return dead; -} - -MxHeapable* MxHeap::remove(MxHeapable* t) -{ - if (!t->is_in_heap()) - return 0; // NULL; - - int i = t->get_heap_pos(); - swap(i, length() - 1); - drop(); - t->not_in_heap(); - - if (ref(i)->heap_key() < t->heap_key()) - downheap(i); - else - upheap(i); - - return t; -} diff --git a/src/utils/xrQSlim/MxHeap.h b/src/utils/xrQSlim/MxHeap.h deleted file mode 100644 index 758c1338d2f..00000000000 --- a/src/utils/xrQSlim/MxHeap.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef MXHEAP_INCLUDED // -*- C++ -*- -#define MXHEAP_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Heap - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxHeap.h,v 1.11 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "MxDynBlock.h" - -class MxHeapable -{ -private: - float import; - int token; - -public: - MxHeapable() - { - not_in_heap(); - heap_key(0.0f); - } - - inline bool is_in_heap() { return token != -47; } - inline void not_in_heap() { token = -47; } - inline int get_heap_pos() { return token; } - inline void set_heap_pos(int t) { token = t; } - inline void heap_key(float k) { import = k; } - inline float heap_key() const { return import; } -}; - -class MxHeap : private MxDynBlock -{ -private: - void place(MxHeapable* x, unsigned int i); - void swap(unsigned int i, unsigned int j); - - unsigned int parent(unsigned int i) { return (i - 1) / 2; } - unsigned int left(unsigned int i) { return 2 * i + 1; } - unsigned int right(unsigned int i) { return 2 * i + 2; } - void upheap(unsigned int i); - void downheap(unsigned int i); - -public: - MxHeap() : MxDynBlock(8) {} - MxHeap(unsigned int n) : MxDynBlock(n) {} - void insert(MxHeapable* t) { insert(t, t->heap_key()); } - void insert(MxHeapable*, float); - void update(MxHeapable* t) { update(t, t->heap_key()); } - void update(MxHeapable*, float); - - unsigned int size() const { return length(); } - MxHeapable* item(unsigned int i) { return (*this)[i]; } - const MxHeapable* item(unsigned int i) const { return (*this)[i]; } - MxHeapable* extract(); - MxHeapable* top() { return (length() < 1 ? (MxHeapable*)0 : item(0)); } - MxHeapable* remove(MxHeapable*); -}; - -// MXHEAP_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxMat2.h b/src/utils/xrQSlim/MxMat2.h deleted file mode 100644 index 0f5dc91656d..00000000000 --- a/src/utils/xrQSlim/MxMat2.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef MXMAT2_INCLUDED // -*- C++ -*- -#define MXMAT2_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 2x2 Matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxMat2.h,v 1.10 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "mat2.h" - -// MXMAT2_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxMat3-jacobi.cpp b/src/utils/xrQSlim/MxMat3-jacobi.cpp deleted file mode 100644 index 03fa4e5cee4..00000000000 --- a/src/utils/xrQSlim/MxMat3-jacobi.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/************************************************************************ - - Jacobi iteration on 3x3 matrices. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - NOTE: This code was adapted from VTK source code (vtkMath.cxx) which - seems to have been adapted directly from Numerical Recipes in C. - See Hoppe's Recon software for an alternative adaptation of the - Numerical Recipes code. - - $Id: MxMat3-jacobi.cxx,v 1.11 2000/12/14 17:48:24 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxMat3.h" -#include "xrCommon/math_funcs_inline.h" - -#define ROT(a, i, j, k, l)\ - g = a[i][j];\ - h = a[k][l];\ - a[i][j] = g - s * (h + g * tau);\ - a[k][l] = h + s * (g - h * tau); - -#define MAX_ROTATIONS 60 - -// Description: -// Jacobi iteration for the solution of eigenvectors/eigenvalues of a 3x3 -// real symmetric matrix. Square 3x3 matrix a; output eigenvalues in w; -// and output eigenvectors in v. Resulting eigenvalues/vectors are sorted -// in decreasing order; eigenvectors are normalized. -// -static bool internal_jacobi(double a[3][3], double w[3], double v[3][3]) -{ - int i, j, k, iq, ip; - double tresh, theta, tau, t, sm, s, h, g, c; - double b[3], z[3], tmp; - - // initialize - for (ip = 0; ip < 3; ip++) - { - for (iq = 0; iq < 3; iq++) - v[ip][iq] = 0.0; - v[ip][ip] = 1.0; - } - for (ip = 0; ip < 3; ip++) - { - b[ip] = w[ip] = a[ip][ip]; - z[ip] = 0.0; - } - - // begin rotation sequence - for (i = 0; i < MAX_ROTATIONS; i++) - { - sm = 0.0; - for (ip = 0; ip < 2; ip++) - { - for (iq = ip + 1; iq < 3; iq++) - sm += _abs(a[ip][iq]); - } - if (sm == 0.0) - break; - - if (i < 4) - tresh = 0.2 * sm / (9); - else - tresh = 0.0; - - for (ip = 0; ip < 2; ip++) - { - for (iq = ip + 1; iq < 3; iq++) - { - g = 100.0 * _abs(a[ip][iq]); - if (i > 4 && (_abs(w[ip]) + g) == _abs(w[ip]) && (_abs(w[iq]) + g) == _abs(w[iq])) - { - a[ip][iq] = 0.0; - } - else if (_abs(a[ip][iq]) > tresh) - { - h = w[iq] - w[ip]; - if ((_abs(h) + g) == _abs(h)) - t = (a[ip][iq]) / h; - else - { - theta = 0.5 * h / (a[ip][iq]); - t = 1.0 / (_abs(theta) + _sqrt(1.0 + theta * theta)); - if (theta < 0.0) - t = -t; - } - c = 1.0 / _sqrt(1 + t * t); - s = t * c; - tau = s / (1.0 + c); - h = t * a[ip][iq]; - z[ip] -= h; - z[iq] += h; - w[ip] -= h; - w[iq] += h; - a[ip][iq] = 0.0; - for (j = 0; j < ip - 1; j++) - { - ROT(a, j, ip, j, iq) - } - for (j = ip + 1; j < iq - 1; j++) - { - ROT(a, ip, j, j, iq) - } - for (j = iq + 1; j < 3; j++) - { - ROT(a, ip, j, iq, j) - } - for (j = 0; j < 3; j++) - { - ROT(v, j, ip, j, iq) - } - } - } - } - - for (ip = 0; ip < 3; ip++) - { - b[ip] += z[ip]; - w[ip] = b[ip]; - z[ip] = 0.0; - } - } - - if (i >= MAX_ROTATIONS) - { - FATAL("Error computing eigenvalues."); - return false; - } - - // sort eigenfunctions - for (j = 0; j < 3; j++) - { - k = j; - tmp = w[k]; - for (i = j; i < 3; i++) - { - if (w[i] >= tmp) - { - k = i; - tmp = w[k]; - } - } - if (k != j) - { - w[k] = w[j]; - w[j] = tmp; - for (i = 0; i < 3; i++) - { - tmp = v[i][j]; - v[i][j] = v[i][k]; - v[i][k] = tmp; - } - } - } - // insure eigenvector consistency (i.e., Jacobi can compute vectors that - // are negative of one another (.707,.707,0) and (-.707,-.707,0). This can - // reek havoc in hyperstreamline/other stuff. We will select the most - // positive eigenvector. - int numPos; - for (j = 0; j < 3; j++) - { - for (numPos = 0, i = 0; i < 3; i++) - if (v[i][j] >= 0.0) - numPos++; - if (numPos < 2) - for (i = 0; i < 3; i++) - v[i][j] *= -1.0; - } - - return true; -} - -#undef ROT -#undef MAX_ROTATIONS - -bool jacobi(const Mat3& m, Vec3& eig_vals, Vec3 eig_vecs[3]) -{ - double a[3][3], w[3], v[3][3]; - int i, j; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - a[i][j] = m(i, j); - - bool result = internal_jacobi(a, w, v); - if (result) - { - for (i = 0; i < 3; i++) - eig_vals[i] = w[i]; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - eig_vecs[i][j] = v[j][i]; - } - - return result; -} - -bool jacobi(const Mat3& m, double* eig_vals, double* eig_vecs) -{ - double a[3][3], v[3][3]; - int i, j; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - a[i][j] = m(i, j); - - bool result = internal_jacobi(a, eig_vals, v); - if (result) - { - int index = 0; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - // eig_vecs[i][j] = v[j][i]; - eig_vecs[index++] = v[j][i]; - } - - return result; -} diff --git a/src/utils/xrQSlim/MxMat3.h b/src/utils/xrQSlim/MxMat3.h deleted file mode 100644 index 9eda8c260f4..00000000000 --- a/src/utils/xrQSlim/MxMat3.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MXMAT3_INCLUDED // -*- C++ -*- -#define MXMAT3_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 3x3 Matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxMat3.h,v 1.11 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "mat3.h" - -extern bool jacobi(const Mat3& m, Vec3& vals, Vec3 vecs[3]); -extern bool jacobi(const Mat3& m, double* vals, double* vecs); - -extern bool fast_jacobi(const Mat3& m, Vec3& vals, Vec3 vecs[3]); - -// MXMAT3_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxMat4-jacobi.cpp b/src/utils/xrQSlim/MxMat4-jacobi.cpp deleted file mode 100644 index 0646747fc53..00000000000 --- a/src/utils/xrQSlim/MxMat4-jacobi.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/************************************************************************ - - Jacobi iteration on 4x4 matrices. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - NOTE: This code was adapted from VTK source code (vtkMath.cxx) which - seems to have been adapted directly from Numerical Recipes in C. - See Hoppe's Recon software for an alternative adaptation of the - Numerical Recipes code. - - $Id: MxMat4-jacobi.cxx,v 1.6 1999/01/22 17:24:47 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxMat4.h" -#include "xrCore/_std_extensions.h" - -#define ROT(a, i, j, k, l)\ - g = a[i][j];\ - h = a[k][l];\ - a[i][j] = g - s * (h + g * tau);\ - a[k][l] = h + s * (g - h * tau); - -#define MAX_ROTATIONS 60 - -static bool internal_jacobi4(double a[4][4], double w[4], double v[4][4]) -{ - int i, j, k, iq, ip; - double tresh, theta, tau, t, sm, s, h, g, c; - double b[4], z[4], tmp; - - // initialize - for (ip = 0; ip < 4; ip++) - { - for (iq = 0; iq < 4; iq++) - v[ip][iq] = 0.0; - v[ip][ip] = 1.0; - } - for (ip = 0; ip < 4; ip++) - { - b[ip] = w[ip] = a[ip][ip]; - z[ip] = 0.0; - } - - // begin rotation sequence - for (i = 0; i < MAX_ROTATIONS; i++) - { - sm = 0.0; - for (ip = 0; ip < 3; ip++) - { - for (iq = ip + 1; iq < 4; iq++) - sm += _abs(a[ip][iq]); - } - if (sm == 0.0) - break; - - if (i < 4) - tresh = 0.2 * sm / (16); - else - tresh = 0.0; - - for (ip = 0; ip < 3; ip++) - { - for (iq = ip + 1; iq < 4; iq++) - { - g = 100.0 * _abs(a[ip][iq]); - if (i > 4 && (_abs(w[ip]) + g) == _abs(w[ip]) && (_abs(w[iq]) + g) == _abs(w[iq])) - { - a[ip][iq] = 0.0; - } - else if (_abs(a[ip][iq]) > tresh) - { - h = w[iq] - w[ip]; - if ((_abs(h) + g) == _abs(h)) - t = (a[ip][iq]) / h; - else - { - theta = 0.5 * h / (a[ip][iq]); - t = 1.0 / (_abs(theta) + _sqrt(1.0 + theta * theta)); - if (theta < 0.0) - t = -t; - } - c = 1.0 / _sqrt(1 + t * t); - s = t * c; - tau = s / (1.0 + c); - h = t * a[ip][iq]; - z[ip] -= h; - z[iq] += h; - w[ip] -= h; - w[iq] += h; - a[ip][iq] = 0.0; - for (j = 0; j < ip - 1; j++) - { - ROT(a, j, ip, j, iq) - } - for (j = ip + 1; j < iq - 1; j++) - { - ROT(a, ip, j, j, iq) - } - for (j = iq + 1; j < 4; j++) - { - ROT(a, ip, j, iq, j) - } - for (j = 0; j < 4; j++) - { - ROT(v, j, ip, j, iq) - } - } - } - } - - for (ip = 0; ip < 4; ip++) - { - b[ip] += z[ip]; - w[ip] = b[ip]; - z[ip] = 0.0; - } - } - - if (i >= MAX_ROTATIONS) - { - FATAL("Error computing eigenvalues."); - return false; - } - - // sort eigenfunctions - for (j = 0; j < 4; j++) - { - k = j; - tmp = w[k]; - for (i = j; i < 4; i++) - { - if (w[i] >= tmp) - { - k = i; - tmp = w[k]; - } - } - if (k != j) - { - w[k] = w[j]; - w[j] = tmp; - for (i = 0; i < 4; i++) - { - tmp = v[i][j]; - v[i][j] = v[i][k]; - v[i][k] = tmp; - } - } - } - // insure eigenvector consistency (i.e., Jacobi can compute vectors that - // are negative of one another (.707,.707,0) and (-.707,-.707,0). This can - // reek havoc in hyperstreamline/other stuff. We will select the most - // positive eigenvector. - int numPos; - for (j = 0; j < 4; j++) - { - for (numPos = 0, i = 0; i < 4; i++) - if (v[i][j] >= 0.0) - numPos++; - if (numPos < 3) - for (i = 0; i < 4; i++) - v[i][j] *= -1.0; - } - - return true; -} - -#undef ROT -#undef MAX_ROTATIONS - -bool jacobi(const Mat4& m, Vec4& eig_vals, Vec4 eig_vecs[4]) -{ - double a[4][4], w[4], v[4][4]; - int i, j; - - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) - a[i][j] = m(i, j); - - bool result = internal_jacobi4(a, w, v); - if (result) - { - for (i = 0; i < 4; i++) - eig_vals[i] = w[i]; - - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) - eig_vecs[i][j] = v[j][i]; - } - - return result; -} diff --git a/src/utils/xrQSlim/MxMat4.h b/src/utils/xrQSlim/MxMat4.h deleted file mode 100644 index f2d7f1770a5..00000000000 --- a/src/utils/xrQSlim/MxMat4.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef MXMAT4_INCLUDED // -*- C++ -*- -#define MXMAT4_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 4x4 Matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxMat4.h,v 1.12 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "mat4.h" - -extern bool jacobi(const Mat4& m, Vec4& vals, Vec4 vecs[4]); - -#ifdef MXGL_INCLUDED -inline void glGetMatrix(Mat4& m, GLenum which = GL_MODELVIEW_MATRIX) -{ - Mat4 tmp; - glGetDoublev(which, &tmp(0, 0)); - m = transpose(tmp); -} - -inline void glLoadMatrix(const Mat4& m) -{ - Mat4 tmp = transpose(m); - glLoadMatrixd(&tmp(0, 0)); -} - -inline void glMultMatrix(const Mat4& m) -{ - Mat4 tmp = transpose(m); - glMultMatrixd(&tmp(0, 0)); -} -#endif - -// MXMAT4_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxMatrix.cpp b/src/utils/xrQSlim/MxMatrix.cpp deleted file mode 100644 index cf6b54bedf5..00000000000 --- a/src/utils/xrQSlim/MxMatrix.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************ - - NxN Matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxMatrix.cxx,v 1.4 1998/10/26 21:09:09 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxMatrix.h" - -// Originally from Paul's matrix library. -// -// Returns determinant of a, and b=a inverse. -// If matrix is singular, returns 0 and leaves trash in b. -// -// Uses Gaussian elimination with partial pivoting. - -#define SWAP(a, b, t)\ - {\ - t = a;\ - a = b;\ - b = t;\ - } -static double internal_invert(MxMatrix& A, MxMatrix& B) -{ - unsigned int N = A.dim(); - unsigned int i, j = 0, k; - double max, t, det, pivot; - - /*---------- forward elimination ----------*/ - - for (i = 0; i < N; i++) /* put identity matrix in B */ - for (j = 0; j < N; j++) - B(i, j) = (double)(i == j); - - det = 1.0; - for (i = 0; i < N; i++) - { /* eliminate in column i, below diag */ - max = -1.; - for (k = i; k < N; k++) /* find pivot for column i */ - if (_abs(A(k, i)) > max) - { - max = _abs(A(k, i)); - j = k; - } - if (max <= 0.) - return 0.; /* if no nonzero pivot, PUNT */ - if (j != i) - { /* swap rows i and j */ - for (k = i; k < N; k++) - SWAP(A(i, k), A(j, k), t); - for (k = 0; k < N; k++) - SWAP(B(i, k), B(j, k), t); - det = -det; - } - pivot = A(i, i); - det *= pivot; - for (k = i + 1; k < N; k++) /* only do elems to right of pivot */ - A(i, k) /= pivot; - for (k = 0; k < N; k++) - B(i, k) /= pivot; - /* we know that A(i, i) will be set to 1, so don't bother to do it */ - - for (j = i + 1; j < N; j++) - { /* eliminate in rows below i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = i + 1; k < N; k++) /* subtract scaled row i from row j */ - A(j, k) -= A(i, k) * t; /* (ignore k<=i, we know they're 0) */ - for (k = 0; k < N; k++) - B(j, k) -= B(i, k) * t; - } - } - - /*---------- backward elimination ----------*/ - - for (i = N - 1; i > 0; i--) - { /* eliminate in column i, above diag */ - for (j = 0; j < i; j++) - { /* eliminate in rows above i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = 0; k < N; k++) /* subtract scaled row i from row j */ - B(j, k) -= B(i, k) * t; - } - } - - return det; -} - -#undef SWAP - -double mxm_invert(MxMatrix& r, const MxMatrix& a) -{ - MxMatrix a2(a); - return internal_invert(a2, r); -} diff --git a/src/utils/xrQSlim/MxMatrix.h b/src/utils/xrQSlim/MxMatrix.h deleted file mode 100644 index cdb6571d016..00000000000 --- a/src/utils/xrQSlim/MxMatrix.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef MXMATRIX_INCLUDED // -*- C++ -*- -#define MXMATRIX_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Generic n-dimensional matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxMatrix.h,v 1.8 1998/10/26 21:09:10 garland Exp $ - - ************************************************************************/ - -#include "MxVector.h" - -#define __T float -#include "mixmops.h" - -#define __T double -#include "mixmops.h" - -//////////////////////////////////////////////////////////////////////// -// -// Matrix class -// - -#include "MxBlock2.h" - -class MxMatrix : public MxBlock2 -{ -public: - MxMatrix(unsigned int n) : MxBlock2(n, n) { *this = 0.0; } - MxMatrix(const MxMatrix& m) : MxBlock2(m.dim(), m.dim()) { copy(m); } - MxMatrix& operator=(const MxMatrix& m) - { - copy(m); - return *this; - } - MxMatrix& operator=(double d) - { - mxm_set(*this, d, dim()); - return *this; - } - - unsigned int dim() const { return width(); } - MxMatrix& operator+=(const MxMatrix& m) - { - mxm_addinto(*this, m, dim()); - return *this; - } - MxMatrix& operator-=(const MxMatrix& m) - { - mxm_subfrom(*this, m, dim()); - return *this; - } - MxMatrix& operator*=(double d) - { - mxm_scale(*this, d, dim()); - return *this; - } - MxMatrix& operator/=(double d) - { - mxm_invscale(*this, d, dim()); - return *this; - } - - MxVector operator*(const MxVector& v) const - { - MxVector r(dim()); - mxm_xform(r, *this, v, dim()); - return r; - } - - double invert(MxMatrix& inv) const { return mxm_invert(inv, *this, dim()); } -}; - -/* -inline ostream& operator<<(ostream& out, const MxMatrix& a) -{ - return mxm_write(out, a, a.dim()); -} -*/ -// MXMATRIX_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxPropSlim.cpp b/src/utils/xrQSlim/MxPropSlim.cpp deleted file mode 100644 index 370a133c7dd..00000000000 --- a/src/utils/xrQSlim/MxPropSlim.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/************************************************************************ - -MxPropSlim - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: MxPropSlim.cxx,v 1.9 2000/11/20 20:36:38 garland Exp $ - -************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxPropSlim.h" -#include "MxGeom3D.h" - -MxPropSlim::MxPropSlim(MxStdModel* m0) : MxStdSlim(m0), edge_links(m0->vert_count()), __quadrics(m0->vert_count()) -{ - consider_color(); - consider_texture(); - consider_normals(); - - D = compute_dimension(m); - - will_decouple_quadrics = false; - contraction_callback = NULL; -} - -void MxPropSlim::consider_color(bool will) -{ - use_color = will && (m->color_binding() == MX_PERVERTEX); - D = compute_dimension(m); -} - -void MxPropSlim::consider_texture(bool will) -{ - use_texture = will && (m->texcoord_binding() == MX_PERVERTEX); - D = compute_dimension(m); -} - -void MxPropSlim::consider_normals(bool will) -{ - use_normals = will && (m->normal_binding() == MX_PERVERTEX); - D = compute_dimension(m); -} - -unsigned int MxPropSlim::compute_dimension(MxStdModel* m) -{ - unsigned int d = 3; - - if (use_color) - d += 3; - if (use_texture) - d += 2; - if (use_normals) - d += 3; - - return d; -} - -void MxPropSlim::pack_to_vector(MxVertexID id, MxVector& v) -{ - VERIFY(v.dim() == D); - VERIFY(id < m->vert_count()); - - v[0] = m->vertex(id)[0]; - v[1] = m->vertex(id)[1]; - v[2] = m->vertex(id)[2]; - - unsigned int i = 3; - if (use_color) - { - v[i++] = m->color(id).R(); - v[i++] = m->color(id).G(); - v[i++] = m->color(id).B(); - } - if (use_texture) - { - v[i++] = m->texcoord(id)[0]; - v[i++] = m->texcoord(id)[1]; - } - if (use_normals) - { - v[i++] = m->normal(id)[0]; - v[i++] = m->normal(id)[1]; - v[i++] = m->normal(id)[2]; - } -} - -void MxPropSlim::pack_prop_to_vector(MxVertexID id, MxVector& v, unsigned int target) -{ - if (target == 0) - { - v[0] = m->vertex(id)[0]; - v[1] = m->vertex(id)[1]; - v[2] = m->vertex(id)[2]; - return; - } - - unsigned int i = 3; - target--; - - if (use_color) - { - if (target == 0) - { - v[i] = m->color(id).R(); - v[i + 1] = m->color(id).G(); - v[i + 2] = m->color(id).B(); - return; - } - i += 3; - target--; - } - if (use_texture) - { - if (target == 0) - { - v[i] = m->texcoord(id)[0]; - v[i + 1] = m->texcoord(id)[1]; - return; - } - i += 2; - target--; - } - if (use_normals) - { - if (target == 0) - { - v[i] = m->normal(id)[0]; - v[i + 1] = m->normal(id)[1]; - v[i + 2] = m->normal(id)[2]; - return; - } - } -} - -static inline void CLAMP(double& v, double lo, double hi) -{ - if (v < lo) - v = lo; - if (v > hi) - v = hi; -} - -void MxPropSlim::unpack_from_vector(MxVertexID id, MxVector& v) -{ - VERIFY(v.dim() == D); - VERIFY(id < m->vert_count()); - - m->vertex(id)[0] = (float)v[0]; - m->vertex(id)[1] = (float)v[1]; - m->vertex(id)[2] = (float)v[2]; - - unsigned int i = 3; - if (use_color) - { - CLAMP(v[i], 0, 1); - CLAMP(v[i + 1], 0, 1); - CLAMP(v[i + 2], 0, 1); - m->color(id).set((float)v[i], (float)v[i + 1], (float)v[i + 2]); - i += 3; - } - if (use_texture) - { - m->texcoord(id)[0] = (float)v[i++]; - m->texcoord(id)[1] = (float)v[i++]; - } - if (use_normals) - { - float n[3]; - n[0] = (float)v[i++]; - n[1] = (float)v[i++]; - n[2] = (float)v[i++]; - mxv_unitize(n, 3); - m->normal(id).set(n[0], n[1], n[2]); - } -} - -void MxPropSlim::unpack_prop_from_vector(MxVertexID id, MxVector& v, unsigned int target) -{ - if (target == 0) - { - m->vertex(id)[0] = (float)v[0]; - m->vertex(id)[1] = (float)v[1]; - m->vertex(id)[2] = (float)v[2]; - return; - } - - unsigned int i = 3; - target--; - - if (use_color) - { - if (target == 0) - { - m->color(id).set((float)v[i], (float)v[i + 1], (float)v[i + 2]); - return; - } - i += 3; - target--; - } - if (use_texture) - { - if (target == 0) - { - m->texcoord(id)[0] = (float)v[i]; - m->texcoord(id)[1] = (float)v[i + 1]; - return; - } - i += 2; - target--; - } - if (use_normals) - { - if (target == 0) - { - float n[3]; - n[0] = (float)v[i]; - n[1] = (float)v[i + 1]; - n[2] = (float)v[i + 2]; - mxv_unitize(n, 3); - m->normal(id).set(n[0], n[1], n[2]); - return; - } - } -} - -unsigned int MxPropSlim::prop_count() -{ - unsigned int i = 1; - - if (use_color) - i++; - if (use_texture) - i++; - if (use_normals) - i++; - - return i; -} - -void MxPropSlim::compute_face_quadric(MxFaceID i, MxQuadric& Q) -{ - MxFace& f = m->face(i); - - MxVector v1(dim()); - MxVector v2(dim()); - MxVector v3(dim()); - - if (will_decouple_quadrics) - { - Q.clear(); - - for (unsigned int p = 0; p < prop_count(); p++) - { - v1 = 0.0; - v2 = 0.0; - v3 = 0.0; - - pack_prop_to_vector(f[0], v1, p); - pack_prop_to_vector(f[1], v2, p); - pack_prop_to_vector(f[2], v3, p); - - // !!BUG: Will count area multiple times (once per property) - MxQuadric Q_p(v1, v2, v3, m->compute_face_area(i)); - - // !!BUG: Need to only extract the relevant block of the matrix. - // Adding the whole thing gives us extraneous stuff. - Q += Q_p; - } - } - else - { - pack_to_vector(f[0], v1); - pack_to_vector(f[1], v2); - pack_to_vector(f[2], v3); - - Q = MxQuadric(v1, v2, v3, m->compute_face_area(i)); - } -} - -void MxPropSlim::collect_quadrics() -{ - for (unsigned int j = 0; j < quadric_count(); j++) - __quadrics[j] = xr_new(dim()); - - for (MxFaceID i = 0; i < m->face_count(); i++) - { - MxFace& f = m->face(i); - - MxQuadric Q(dim()); - compute_face_quadric(i, Q); - - switch (weighting_policy) - { - case MX_WEIGHT_AREA: - case MX_WEIGHT_AREA_AVG: - Q *= Q.area(); - [[fallthrough]]; - - default: - quadric(f[0]) += Q; - quadric(f[1]) += Q; - quadric(f[2]) += Q; - break; - } - } -} - -void MxPropSlim::initialize() -{ - collect_quadrics(); - - if (boundary_weight > 0.0) - constrain_boundaries(); - - is_initialized = true; -} - -unsigned int MxPropSlim::check_local_validity(unsigned int v, const float* vnew) -{ - const MxFaceList& N = m->neighbors(v); - unsigned int nfailed = 0; - unsigned int i; - - for (i = 0; i < (unsigned int)N.length(); i++) - { - if (m->face_mark(N[i]) == 1) - { - MxFace& f = m->face(N[i]); - unsigned int k = f.find_vertex(v); - unsigned int x = f[(k + 1) % 3]; - unsigned int y = f[(k + 2) % 3]; - - float d_yx[3], d_vx[3], d_vnew[3], f_n[3], n[3]; - mxv_sub(d_yx, m->vertex(y), m->vertex(x), 3); // d_yx = y-x - mxv_sub(d_vx, m->vertex(v), m->vertex(x), 3); // d_vx = v-x - mxv_sub(d_vnew, vnew, m->vertex(x), 3); // d_vnew = vnew-x - - mxv_cross3(f_n, d_yx, d_vx); - mxv_cross3(n, f_n, d_yx); // n = ((y-x)^(v-x))^(y-x) - mxv_unitize(n, 3); - - // R_ASSERT( mxv_dot(d_vx, n, 3) > -FEQ_EPS ); - if (mxv_dot(d_vnew, n, 3) < local_validity_threshold * mxv_dot(d_vx, n, 3)) - nfailed++; - } - } - - return nfailed; -} - -double MxPropSlim::check_local_compactness(unsigned int v, const float* vnew) -{ - const MxFaceList& N = m->neighbors(v); - double c_min = 1.0; - - for (unsigned int i = 0; i < (unsigned int)N.length(); i++) - if (m->face_mark(N[i]) == 1) - { - const MxFace& f = m->face(N[i]); - Vec3 f_after[3]; - for (unsigned int j = 0; j < 3; j++) - f_after[j] = (f[j] == v) ? Vec3(vnew) : Vec3(m->vertex(f[j])); - - double c = triangle_compactness(f_after[0], f_after[1], f_after[2]); - - if (c < c_min) - c_min = c; - } - - return c_min; -} - -void MxPropSlim::apply_mesh_penalties(edge_info* info) -{ - unsigned int i; - - const MxFaceList& N1 = m->neighbors(info->v1); - const MxFaceList& N2 = m->neighbors(info->v2); - - // Set up the face marks as the check_xxx() functions expect. - // - for (i = 0; i < (unsigned int)N2.length(); i++) - m->face_mark(N2[i], 0); - for (i = 0; i < (unsigned int)N1.length(); i++) - m->face_mark(N1[i], 1); - for (i = 0; i < (unsigned int)N2.length(); i++) - m->face_mark(N2[i], m->face_mark(N2[i]) + 1); - - double base_error = info->heap_key(); - double bias = 0.0; - - // Check for excess over degree bounds. - // - unsigned int max_degree = std::max(N1.length(), N2.length()); - if (max_degree > vertex_degree_limit) - bias += (max_degree - vertex_degree_limit) * meshing_penalty * 0.001f; - - // Local validity checks - // - float vnew[3]; - vnew[0] = (float)info->target[0]; - vnew[1] = (float)info->target[1]; - vnew[2] = (float)info->target[2]; - - unsigned int nfailed = 0; - nfailed += check_local_validity(info->v1, vnew); - nfailed += check_local_validity(info->v2, vnew); - if (nfailed) - bias += nfailed * meshing_penalty; - - float _scale = 1.f; - if (compactness_ratio > 0.0) - { - double c1_min = check_local_compactness(info->v1, vnew); - double c2_min = check_local_compactness(info->v2, vnew); - double c_min = std::min(c1_min, c2_min); - - if (c_min < compactness_ratio) - _scale += float((compactness_ratio - c_min) / compactness_ratio); - } - - info->heap_key(float((base_error - EDGE_BASE_ERROR) * _scale - bias)); -} - -void MxPropSlim::compute_target_placement(edge_info* info) -{ - MxVertexID i = info->v1, j = info->v2; - - const MxQuadric &Qi = quadric(i), &Qj = quadric(j); - MxQuadric Q = Qi; - Q += Qj; - - double e_min; - - if (placement_policy == MX_PLACE_OPTIMAL && Q.optimize(info->target)) - { - e_min = Q(info->target); - } - else - { - // Fall back only on endpoints - MxVector vi(dim()); - MxVector vj(dim()); - MxVector best(dim()); - - pack_to_vector(i, vi); - pack_to_vector(j, vj); - - double ei = Q(vi), ej = Q(vj); - - if (ei < ej) - { - e_min = ei; - best = vi; - } - else - { - e_min = ej; - best = vj; - std::swap(info->v1, info->v2); - } - - if (placement_policy >= MX_PLACE_ENDORMID) - { - MxVector mid(dim()); - mid = vi; - mid += vj; - mid /= 2.f; - double e_mid = Q(mid); - - if (e_mid < e_min) - { - e_min = e_mid; - best = mid; - } - } - info->target = best; - } - - if (weighting_policy == MX_WEIGHT_AREA_AVG) - e_min /= Q.area(); - - info->heap_key(float(-e_min)); -} - -bool MxPropSlim::decimate(unsigned int target, float max_error, void* cb_params) -{ - MxPairContraction conx; - - max_error += EDGE_BASE_ERROR; - while (valid_faces > target) - { - MxHeapable* top = heap.top(); - if (!top) - { - return false; - } - if (-top->heap_key() > max_error) - { - return true; - } - - edge_info* info = (edge_info*)heap.extract(); - MxVertexID v1 = info->v1; - MxVertexID v2 = info->v2; - - if (m->vertex_is_valid(v1) && m->vertex_is_valid(v2)) - { - m->compute_contraction(v1, v2, &conx); - - conx.dv1[0] = float(info->target[0] - m->vertex(v1)[0]); - conx.dv1[1] = float(info->target[1] - m->vertex(v1)[1]); - conx.dv1[2] = float(info->target[2] - m->vertex(v1)[2]); - conx.dv2[0] = float(info->target[0] - m->vertex(v2)[0]); - conx.dv2[1] = float(info->target[1] - m->vertex(v2)[1]); - conx.dv2[2] = float(info->target[2] - m->vertex(v2)[2]); - - if (contraction_callback) - (*contraction_callback)(conx, -(info->heap_key() + EDGE_BASE_ERROR), cb_params); - - apply_contraction(conx, info); - } - - xr_delete(info); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////// -// -// This is *very* close to the code in MxEdgeQSlim - -void MxPropSlim::create_edge(MxVertexID i, MxVertexID j) -{ - edge_info* info = xr_new(dim()); - - edge_links(i).add(info); - edge_links(j).add(info); - - info->v1 = i; - info->v2 = j; - - compute_edge_info(info); -} - -void MxPropSlim::discontinuity_constraint(MxVertexID i, MxVertexID j, MxFaceID f) -{ - Vec3 org(m->vertex(i)), dest(m->vertex(j)); - Vec3 e = dest - org; - - Vec3 v1(m->vertex(m->face(f)(0))); - Vec3 v2(m->vertex(m->face(f)(1))); - Vec3 v3(m->vertex(m->face(f)(2))); - Vec3 n = triangle_normal(v1, v2, v3); - - Vec3 n2 = e ^ n; - unitize(n2); - - MxQuadric3 Q3(n2, -(n2 * org)); - Q3 *= boundary_weight; - - if (weighting_policy == MX_WEIGHT_AREA || weighting_policy == MX_WEIGHT_AREA_AVG) - { - Q3.set_area(norm2(e)); - Q3 *= Q3.area(); - } - - MxQuadric Q(Q3, dim()); - - quadric(i) += Q; - quadric(j) += Q; -} - -void MxPropSlim::discontinuity_constraint(MxVertexID i, MxVertexID j, const MxFaceList& faces) -{ - for (unsigned int f = 0; f < (unsigned int)faces.length(); f++) - discontinuity_constraint(i, j, faces[f]); -} - -void MxPropSlim::constraint_manual(MxVertexID v0, MxVertexID v1, MxFaceID f) { discontinuity_constraint(v0, v1, f); } -void MxPropSlim::apply_contraction(const MxPairContraction& conx, edge_info* info) -{ - valid_verts--; - valid_faces -= conx.dead_faces.length(); - quadric(conx.v1) += quadric(conx.v2); - - update_pre_contract(conx); - - m->apply_contraction(conx); - - unpack_from_vector(conx.v1, info->target); - - // Must update edge_info here so that the meshing penalties - // will be computed with respect to the new mesh rather than the old - for (unsigned int i = 0; i < (unsigned int)edge_links(conx.v1).length(); i++) - compute_edge_info(edge_links(conx.v1)[i]); -} - -//////////////////////////////////////////////////////////////////////// -// -// These were copied *unmodified* from MxEdgeQSlim -// (with some unsupported features commented out). -// - -void MxPropSlim::collect_edges() -{ - MxVertexList star; - - for (MxVertexID i = 0; i < m->vert_count(); i++) - { - star.reset(); - m->collect_vertex_star(i, star); - - for (unsigned int j = 0; j < (unsigned int)star.length(); j++) - if (i < star(j)) // Only add particular edge once - create_edge(i, star(j)); - } -} - -void MxPropSlim::constrain_boundaries() -{ - MxVertexList star; - MxFaceList faces; - - for (MxVertexID i = 0; i < m->vert_count(); i++) - { - star.reset(); - m->collect_vertex_star(i, star); - - for (unsigned int j = 0; j < (unsigned int)star.length(); j++) - { - if (i < star(j)) - { - faces.reset(); - m->collect_edge_neighbors(i, star(j), faces); - if (faces.length() == 1) - discontinuity_constraint(i, star(j), faces); - } - } - } -} - -void MxPropSlim::compute_edge_info(edge_info* info) -{ - compute_target_placement(info); - - // if( will_normalize_error ) - // { - // double e_max = Q_max(info->vnew); - // if( weight_by_area ) - // e_max /= Q_max.area(); - - // info->heap_key(info->heap_key() / e_max); - // } - - finalize_edge_update(info); -} - -void MxPropSlim::finalize_edge_update(edge_info* info) -{ - if (meshing_penalty > 1.0) - apply_mesh_penalties(info); - - if (info->is_in_heap()) - heap.update(info); - else - heap.insert(info); -} - -void MxPropSlim::update_pre_contract(const MxPairContraction& conx) -{ - MxVertexID v1 = conx.v1, v2 = conx.v2; - unsigned int i, j; - - star.reset(); - m->collect_vertex_star(v1, star); - - for (i = 0; i < (unsigned int)edge_links(v2).length(); i++) - { - edge_info* e = edge_links(v2)(i); - MxVertexID u = (e->v1 == v2) ? e->v2 : e->v1; - VERIFY(e->v1 == v2 || e->v2 == v2); - VERIFY(u != v2); - - if (u == v1 || varray_find(star, u)) - { - // This is a useless link --- kill it - [[maybe_unused]] bool found = varray_find(edge_links(u), e, &j); - VERIFY(found); - edge_links(u).remove(j); - heap.remove(e); - if (u != v1) - xr_delete(e); // (v1,v2) will be deleted later - } - else - { - // Relink this to v1 - e->v1 = v1; - e->v2 = u; - edge_links(v1).add(e); - } - } - - edge_links(v2).reset(); -} diff --git a/src/utils/xrQSlim/MxPropSlim.h b/src/utils/xrQSlim/MxPropSlim.h deleted file mode 100644 index 416b616713f..00000000000 --- a/src/utils/xrQSlim/MxPropSlim.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef MXPROPSLIM_INCLUDED // -*- C++ -*- -#define MXPROPSLIM_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - -MxPropSlim - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: MxPropSlim.h,v 1.6 1998/10/26 21:09:15 garland Exp $ - -************************************************************************/ - -#include "MxStdSlim.h" -#include "MxQMetric.h" - -class MxPropSlim : public MxStdSlim -{ -private: - unsigned int D; - - bool use_color; - bool use_texture; - bool use_normals; - - class edge_info : public MxHeapable - { - public: - MxVertexID v1, v2; - MxVector target; - - edge_info(unsigned int D) : target(D) {} - }; - typedef MxSizedDynBlock edge_list; - MxBlock edge_links; // 1 per vertex - MxBlock __quadrics; // 1 per vertex - - // - // Temporary variables used by methods - MxVertexList star, star2; - MxPairContraction conx_tmp; - -protected: - unsigned int compute_dimension(MxStdModel*); - void pack_to_vector(MxVertexID, MxVector&); - void unpack_from_vector(MxVertexID, MxVector&); - unsigned int prop_count(); - void pack_prop_to_vector(MxVertexID, MxVector&, unsigned int); - void unpack_prop_from_vector(MxVertexID, MxVector&, unsigned int); - - void compute_face_quadric(MxFaceID, MxQuadric&); - void collect_quadrics(); - - void create_edge(MxVertexID, MxVertexID); - void constrain_boundaries(); - void discontinuity_constraint(MxVertexID, MxVertexID, MxFaceID); - void discontinuity_constraint(MxVertexID, MxVertexID, const MxFaceList&); - void compute_edge_info(edge_info*); - void finalize_edge_update(edge_info*); - void apply_mesh_penalties(edge_info*); - double check_local_compactness(unsigned int v1, const float* vnew); - unsigned int check_local_validity(unsigned int, const float* vnew); - void compute_target_placement(edge_info*); - - void apply_contraction(const MxPairContraction&, edge_info*); - void update_pre_contract(const MxPairContraction&); - -public: - bool will_decouple_quadrics; - -public: - MxPropSlim(MxStdModel*); - - void initialize(); - - void collect_edges(); - void constraint_manual(MxVertexID, MxVertexID, MxFaceID); - - bool decimate(unsigned int, float max_error, void* cb_params = 0); - - unsigned int dim() const { return D; } - void consider_color(bool will = true); - void consider_texture(bool will = true); - void consider_normals(bool will = true); - - unsigned int quadric_count() const { return __quadrics.length(); } - MxQuadric& quadric(unsigned int i) { return *(__quadrics(i)); } - const MxQuadric& quadric(unsigned int i) const { return *(__quadrics(i)); } -}; - -// MXPROPSLIM_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxQMetric.cpp b/src/utils/xrQSlim/MxQMetric.cpp deleted file mode 100644 index 648d7985054..00000000000 --- a/src/utils/xrQSlim/MxQMetric.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************ - - n-D Quadric Error Metrics - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxQMetric.cxx,v 1.5 1998/10/26 21:09:17 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxQMetric.h" - -static void symmetric_subfrom(MxMatrix& A, const MxVector& a, const MxVector& b) -{ - for (unsigned int i = 0; i < A.dim(); i++) - for (unsigned int j = 0; j < A.dim(); j++) - A(i, j) -= a[i] * b[j]; -} - -MxQuadric::MxQuadric(const MxVector& p1, const MxVector& p2, const MxVector& p3, double area) : A(p1.dim()), b(p1.dim()) -{ - VERIFY(p1.dim() == p2.dim() && p1.dim() == p3.dim()); - - MxVector e1 = p2; - e1 -= p1; - unitize(e1); // e1 = p2-p1; unitize - MxVector e2 = p3; - e2 -= p1; // e2 = p3-p1 - MxVector t = e1; - t *= e1 * e2; - e2 -= t; - unitize(e2); // e2 = p3-p1-e1*(e1*(p3-p1)); unitize - - double p1e1 = p1 * e1; - double p1e2 = p1 * e2; - - mxm_identity(A, A.dim()); - symmetric_subfrom(A, e1, e1); - symmetric_subfrom(A, e2, e2); - - // b = e1*p1e1 + e2*p1e2 - p1 - b = e1; - b *= p1e1; - t = e2; - t *= p1e2; - b += t; - b -= p1; - - c = p1 * p1 - p1e1 * p1e1 - p1e2 * p1e2; - - r = area; -} - -MxQuadric::MxQuadric(const MxQuadric3& Q3, unsigned int N) : A(N), b(N) -{ - unsigned int i, j; - - clear(); - - Mat3 A3 = Q3.tensor(); - Vec3 b3 = Q3.vector(); - - for (i = 0; i < 3; i++) - { - for (j = 0; j < 3; j++) - A(i, j) = A3(i, j); - - b[i] = b3[i]; - } - - c = Q3.offset(); - r = Q3.area(); -} - -MxMatrix& MxQuadric::homogeneous(MxMatrix& H) const -{ - VERIFY(H.dim() == A.dim() + 1); - - unsigned int i, j; - - for (i = 0; i < A.dim(); i++) - for (j = 0; j < A.dim(); j++) - H(i, j) = A(i, j); - - for (i = 0; i < b.dim(); i++) - H(i, b.dim()) = H(b.dim(), i) = b[i]; - - H(b.dim(), b.dim()) = c; - - return H; -} - -double MxQuadric::evaluate(const MxVector& v) const -{ - VERIFY(v.dim() == b.dim()); - return v * (A * v) + 2 * (b * v) + c; -} - -bool MxQuadric::optimize(MxVector& v) const -{ - MxMatrix Ainv(A.dim()); - - double det = A.invert(Ainv); - if (FEQ(det, 0.0, 1e-12)) - return false; - - v = (Ainv * b); - mxv_neg(v, v.dim()); - - return true; -} diff --git a/src/utils/xrQSlim/MxQMetric.h b/src/utils/xrQSlim/MxQMetric.h deleted file mode 100644 index 5714fea270c..00000000000 --- a/src/utils/xrQSlim/MxQMetric.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef MXQMETRIC_INCLUDED // -*- C++ -*- -#define MXQMETRIC_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - n-D Quadric Error Metric - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxQMetric.h,v 1.5 1998/10/26 21:09:17 garland Exp $ - - ************************************************************************/ - -#include "MxQMetric3.h" -#include "MxVector.h" -#include "MxMatrix.h" - -class MxQuadric -{ -private: - MxMatrix A; - MxVector b; - double c; - - double r; - -public: - MxQuadric(unsigned int N) : A(N), b(N) { clear(); } - MxQuadric(const MxVector& p1, const MxVector& p2, const MxVector& p3, double area = 1.0); - MxQuadric(const MxQuadric3&, unsigned int N); - MxQuadric(const MxQuadric& Q) : A(Q.A.dim()), b(Q.b.dim()) { *this = Q; } - const MxMatrix& tensor() const { return A; } - const MxVector& vector() const { return b; } - double offset() const { return c; } - double area() const { return r; } - MxMatrix& homogeneous(MxMatrix& H) const; - - void clear(double val = 0.0) - { - A = val; - b = val; - c = val; - r = val; - } - MxQuadric& operator=(const MxQuadric& Q) - { - A = Q.A; - b = Q.b; - c = Q.c; - r = Q.r; - return *this; - } - MxQuadric& operator+=(const MxQuadric& Q) - { - A += Q.A; - b += Q.b; - c += Q.c; - r += Q.r; - return *this; - } - MxQuadric& operator-=(const MxQuadric& Q) - { - A -= Q.A; - b -= Q.b; - c -= Q.c; - r -= Q.r; - return *this; - } - MxQuadric& operator*=(double s) - { - A *= s; - b *= s; - c *= s; - return *this; - } - - double evaluate(const MxVector& v) const; - double operator()(const MxVector& v) const { return evaluate(v); } - bool optimize(MxVector& v) const; -}; - -// MXQMETRIC_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxQMetric3.cpp b/src/utils/xrQSlim/MxQMetric3.cpp deleted file mode 100644 index 8ae38efbaf4..00000000000 --- a/src/utils/xrQSlim/MxQMetric3.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/************************************************************************ - - 3D Quadric Error Metrics - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxQMetric3.cxx,v 1.13.2.1 2002/01/31 19:29:48 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxDefines.h" -#include "MxQMetric3.h" - -#include "MxMat2.h" - -void MxQuadric3::init(double a, double b, double c, double d, double area) -{ - a2 = a * a; - ab = a * b; - ac = a * c; - ad = a * d; - b2 = b * b; - bc = b * c; - bd = b * d; - c2 = c * c; - cd = c * d; - d2 = d * d; - - r = area; -} - -void MxQuadric3::init(const Mat4& Q, double area) -{ - a2 = Q(0, 0); - ab = Q(0, 1); - ac = Q(0, 2); - ad = Q(0, 3); - b2 = Q(1, 1); - bc = Q(1, 2); - bd = Q(1, 3); - c2 = Q(2, 2); - cd = Q(2, 3); - d2 = Q(3, 3); - - r = area; -} - -Mat3 MxQuadric3::tensor() const { return Mat3(Vec3(a2, ab, ac), Vec3(ab, b2, bc), Vec3(ac, bc, c2)); } -Mat4 MxQuadric3::homogeneous() const -{ - return Mat4(Vec4(a2, ab, ac, ad), Vec4(ab, b2, bc, bd), Vec4(ac, bc, c2, cd), Vec4(ad, bd, cd, d2)); -} - -void MxQuadric3::set_coefficients(const double* v) -{ - a2 = v[0]; - ab = v[1]; - ac = v[2]; - ad = v[3]; - b2 = v[4]; - bc = v[5]; - bd = v[6]; - c2 = v[7]; - cd = v[8]; - d2 = v[9]; -} - -void MxQuadric3::point_constraint(const float* p) -{ - // A point constraint quadric measures the squared distance - // of any point v to the given point p. - - a2 = b2 = c2 = 1.0; - ab = ac = bc = 0.0; // A = I - ad = -p[0]; - bd = -p[1]; - cd = -p[2]; // b = -p - d2 = p[0] * p[0] + p[1] * p[1] + p[2] * p[2]; // c = p*p -} - -MxQuadric3& MxQuadric3::operator=(const MxQuadric3& Q) -{ - r = Q.r; - - a2 = Q.a2; - ab = Q.ab; - ac = Q.ac; - ad = Q.ad; - b2 = Q.b2; - bc = Q.bc; - bd = Q.bd; - c2 = Q.c2; - cd = Q.cd; - d2 = Q.d2; - - return *this; -} - -MxQuadric3& MxQuadric3::operator+=(const MxQuadric3& Q) -{ - // Accumulate area - r += Q.r; - - // Accumulate coefficients - a2 += Q.a2; - ab += Q.ab; - ac += Q.ac; - ad += Q.ad; - b2 += Q.b2; - bc += Q.bc; - bd += Q.bd; - c2 += Q.c2; - cd += Q.cd; - d2 += Q.d2; - - return *this; -} - -MxQuadric3& MxQuadric3::operator-=(const MxQuadric3& Q) -{ - r -= Q.r; - - a2 -= Q.a2; - ab -= Q.ab; - ac -= Q.ac; - ad -= Q.ad; - b2 -= Q.b2; - bc -= Q.bc; - bd -= Q.bd; - c2 -= Q.c2; - cd -= Q.cd; - d2 -= Q.d2; - - return *this; -} - -MxQuadric3& MxQuadric3::operator*=(double s) -{ - // Scale coefficients - a2 *= s; - ab *= s; - ac *= s; - ad *= s; - b2 *= s; - bc *= s; - bd *= s; - c2 *= s; - cd *= s; - d2 *= s; - - return *this; -} - -MxQuadric3& MxQuadric3::transform(const Mat4& P) -{ - Mat4 Q = homogeneous(); - Mat4 Pa = adjoint(P); - - // Compute: trans(Pa) * Q * Pa - // NOTE: Pa is symmetric since Q is symmetric - - Q = Pa * Q * Pa; - - // ??BUG: Should we be transforming the area?? - init(Q, r); - - return *this; -} - -double MxQuadric3::evaluate(double x, double y, double z) const -{ - // Evaluate vAv + 2bv + c - - return x * x * a2 + 2 * x * y * ab + 2 * x * z * ac + 2 * x * ad + y * y * b2 + 2 * y * z * bc + 2 * y * bd + - z * z * c2 + 2 * z * cd + d2; -} - -bool MxQuadric3::optimize(Vec3& v) const -{ - Mat3 Ainv; - double det = invert(Ainv, tensor()); - if (FEQ(det, 0.0, 1e-12)) - return false; - - v = -(Ainv * vector()); - - return true; -} - -bool MxQuadric3::optimize(float* x, float* y, float* z) const -{ - Vec3 v; - - bool success = optimize(v); - if (success) - { - *x = (float)v[0]; - *y = (float)v[1]; - *z = (float)v[2]; - } - return success; -} - -bool MxQuadric3::optimize(Vec3& v, const Vec3& v1, const Vec3& v2) const -{ - Vec3 d = v1 - v2; - Mat3 A = tensor(); - - Vec3 Av2 = A * v2; - Vec3 Ad = A * d; - - double denom = 2.0 * d * Ad; - if (FEQ(denom, 0.0, 1e-12)) - return false; - - double a = (-2 * (vector() * d) - (d * Av2) - (v2 * Ad)) / (2 * (d * Ad)); - - if (a < 0.0) - a = 0.0; - else if (a > 1.0) - a = 1.0; - - v = a * d + v2; - return true; -} - -bool MxQuadric3::optimize(Vec3& v, const Vec3& v1, const Vec3& v2, const Vec3& v3) const -{ - Vec3 d13 = v1 - v3; - Vec3 d23 = v2 - v3; - Mat3 A = tensor(); - Vec3 B = vector(); - - Vec3 Ad13 = A * d13; - Vec3 Ad23 = A * d23; - Vec3 Av3 = A * v3; - - double d13_d23 = (d13 * Ad23) + (d23 * Ad13); - double v3_d13 = (d13 * Av3) + (v3 * Ad13); - double v3_d23 = (d23 * Av3) + (v3 * Ad23); - - double d23Ad23 = d23 * Ad23; - double d13Ad13 = d13 * Ad13; - - double denom = d13Ad13 * d23Ad23 - 2 * d13_d23; - if (FEQ(denom, 0.0, 1e-12)) - return false; - - double a = (d23Ad23 * (2 * (B * d13) + v3_d13) - d13_d23 * (2 * (B * d23) + v3_d23)) / -denom; - - double b = (d13Ad13 * (2 * (B * d23) + v3_d23) - d13_d23 * (2 * (B * d13) + v3_d13)) / -denom; - - if (a < 0.0) - a = 0.0; - else if (a > 1.0) - a = 1.0; - if (b < 0.0) - b = 0.0; - else if (b > 1.0) - b = 1.0; - - v = a * d13 + b * d23 + v3; - return true; -} diff --git a/src/utils/xrQSlim/MxQMetric3.h b/src/utils/xrQSlim/MxQMetric3.h deleted file mode 100644 index e6551ce44c8..00000000000 --- a/src/utils/xrQSlim/MxQMetric3.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef MXQMETRIC3_INCLUDED // -*- C++ -*- -#define MXQMETRIC3_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 3D Quadric Error Metric - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxQMetric3.h,v 1.14 1999/12/15 18:07:45 garland Exp $ - - ************************************************************************/ - -#include "MxMat3.h" -#include "MxMat4.h" - -class MxQuadric3 -{ -private: - double a2, ab, ac, ad; - double b2, bc, bd; - double c2, cd; - double d2; - - double r; - - void init(double a, double b, double c, double d, double area); - void init(const Mat4& Q, double area); - -public: - MxQuadric3() { clear(); } - MxQuadric3(double a, double b, double c, double d, double area = 1.0) { init(a, b, c, d, area); } - MxQuadric3(const float* n, double d, double area = 1.0) { init(n[0], n[1], n[2], d, area); } - MxQuadric3(const double* n, double d, double area = 1.0) { init(n[0], n[1], n[2], d, area); } - MxQuadric3(const MxQuadric3& Q) { *this = Q; } - Mat3 tensor() const; - Vec3 vector() const { return Vec3(ad, bd, cd); } - double offset() const { return d2; } - double area() const { return r; } - Mat4 homogeneous() const; - - void set_coefficients(const double*); - void set_area(double a) { r = a; } - void point_constraint(const float*); - - void clear(double val = 0.0) { a2 = ab = ac = ad = b2 = bc = bd = c2 = cd = d2 = r = val; } - MxQuadric3& operator=(const MxQuadric3& Q); - MxQuadric3& operator+=(const MxQuadric3& Q); - MxQuadric3& operator-=(const MxQuadric3& Q); - MxQuadric3& operator*=(double s); - MxQuadric3& transform(const Mat4& P); - - double evaluate(double x, double y, double z) const; - double evaluate(const double* v) const { return evaluate(v[0], v[1], v[2]); } - double evaluate(const float* v) const { return evaluate(v[0], v[1], v[2]); } - double operator()(double x, double y, double z) const { return evaluate(x, y, z); } - double operator()(const double* v) const { return evaluate(v[0], v[1], v[2]); } - double operator()(const float* v) const { return evaluate(v[0], v[1], v[2]); } - bool optimize(Vec3& v) const; - bool optimize(float* x, float* y, float* z) const; - - bool optimize(Vec3& v, const Vec3& v1, const Vec3& v2) const; - bool optimize(Vec3& v, const Vec3& v1, const Vec3& v2, const Vec3& v3) const; - - /* - ostream& write(ostream& out) - { - return out << a2 << " " << ab << " " << ac << " " << ad << " " - << b2 << " " << bc << " " << bd << " " << c2 << " " - << cd << " " << d2 << " " << r; - } - - ostream& write_full(ostream& out) - { - return out << a2 << " " << ab << " " << ac << " " << ad << " " - << ab << " " << b2 << " " << bc << " " << bd << " " - << ac << " " << bc << " " << c2 << " " << cd << " " - << ad << " " << bd << " " << cd << " " << d2; - } - - - istream& read(istream& in) - { - return in >> a2 >> ab >> ac >> ad >> b2 - >> bc >> bd >> c2 >> cd >> d2 >> r; - } - - - istream& read_full(istream& in) - { - return in >> a2 >> ab >> ac >> ad - >> ab >> b2 >> bc >> bd - >> ac >> bc >> c2 >> cd - >> ad >> bd >> cd >> d2; - } - */ -}; - -//////////////////////////////////////////////////////////////////////// -// -// Quadric visualization routines -// - -#define MX_RED_ELLIPSOIDS 0x1 -#define MX_GREEN_ELLIPSOIDS 0x2 -#define MX_CHARCOAL_ELLIPSOIDS 0x3 - -extern void mx_quadric_shading(int c = MX_GREEN_ELLIPSOIDS, bool twosided = true); -extern void mx_draw_quadric(const MxQuadric3& Q, double r, const float* v = NULL); -extern void mx_draw_osculant(float k1, float k2, float extent = 1.0); - -// MXQMETRIC3_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxQSlim.cpp b/src/utils/xrQSlim/MxQSlim.cpp deleted file mode 100644 index 231c7a44958..00000000000 --- a/src/utils/xrQSlim/MxQSlim.cpp +++ /dev/null @@ -1,764 +0,0 @@ -/************************************************************************ - -Surface simplification using quadric error metrics - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: MxQSlim.cxx,v 1.42.2.2 2004/07/01 18:47:32 garland Exp $ - -************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxQSlim.h" -#include "MxGeom3D.h" -#include "MxVector.h" - -MxQSlim::MxQSlim(MxStdModel* _m) : MxStdSlim(_m), quadrics(_m->vert_count()) -{ - // Externally visible variables - object_transform = NULL; -} - -void MxQSlim::initialize() -{ - collect_quadrics(); - if (boundary_weight > 0.0) - constrain_boundaries(); - if (object_transform) - transform_quadrics(*object_transform); - - is_initialized = true; -} - -void MxQSlim::collect_quadrics() -{ - unsigned int j; - - for (j = 0; j < (unsigned int)quadrics.length(); j++) - quadrics(j).clear(); - - for (MxFaceID i = 0; i < m->face_count(); i++) - { - MxFace& f = m->face(i); - - Vec3 v1(m->vertex(f(0))); - Vec3 v2(m->vertex(f(1))); - Vec3 v3(m->vertex(f(2))); - - Vec4 p = (weighting_policy == MX_WEIGHT_RAWNORMALS) ? triangle_raw_plane(v1, v2, v3) : - triangle_plane(v1, v2, v3); - MxQuadric3 Q(p[0], p[1], p[2], p[3], m->compute_face_area(i)); - - switch (weighting_policy) - { - case MX_WEIGHT_ANGLE: - for (j = 0; j < 3; j++) - { - MxQuadric3 Q_j = Q; - Q_j *= m->compute_corner_angle(i, j); - quadrics(f[j]) += Q_j; - } - break; - case MX_WEIGHT_AREA: - case MX_WEIGHT_AREA_AVG: - Q *= Q.area(); - [[fallthrough]]; - - default: - quadrics(f[0]) += Q; - quadrics(f[1]) += Q; - quadrics(f[2]) += Q; - break; - } - } -} - -void MxQSlim::transform_quadrics(const Mat4& P) -{ - for (unsigned int j = 0; j < (unsigned int)quadrics.length(); j++) - quadrics(j).transform(P); -} - -void MxQSlim::discontinuity_constraint(MxVertexID i, MxVertexID j, MxFaceID f) -{ - Vec3 org(m->vertex(i)), dest(m->vertex(j)); - Vec3 e = dest - org; - - Vec3 n; - m->compute_face_normal(f, n); - - Vec3 n2 = e ^ n; - unitize(n2); - - MxQuadric3 Q(n2, -(n2 * org)); - Q *= boundary_weight; - - if (weighting_policy == MX_WEIGHT_AREA || weighting_policy == MX_WEIGHT_AREA_AVG) - { - Q.set_area(norm2(e)); - Q *= Q.area(); - } - - quadrics(i) += Q; - quadrics(j) += Q; -} - -void MxQSlim::discontinuity_constraint(MxVertexID i, MxVertexID j, const MxFaceList& faces) -{ - for (unsigned int f = 0; f < (unsigned int)faces.length(); f++) - discontinuity_constraint(i, j, faces[f]); -} - -void MxQSlim::constrain_boundaries() -{ - MxVertexList star; - MxFaceList faces; - - for (MxVertexID i = 0; i < m->vert_count(); i++) - { - star.reset(); - m->collect_vertex_star(i, star); - - for (unsigned int j = 0; j < (unsigned int)star.length(); j++) - { - if (i < star(j)) - { - faces.reset(); - m->collect_edge_neighbors(i, star(j), faces); - if (faces.length() == 1) - discontinuity_constraint(i, star(j), faces); - } - } - } -} - -void MxQSlim::constraint_manual(MxVertexID v0, MxVertexID v1, MxFaceID f) { discontinuity_constraint(v0, v1, f); } -MxEdgeQSlim::MxEdgeQSlim(MxStdModel* _m) : MxQSlim(_m), edge_links(_m->vert_count()) { contraction_callback = NULL; } -MxEdgeQSlim::~MxEdgeQSlim() -{ - // Delete everything remaining in the heap - for (unsigned int i = 0; i < heap.size(); i++) - { - MxQSlimEdge* edge = ((MxQSlimEdge*)heap.item(i)); - xr_delete(edge); - } -} - -/////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT NOTE: These check_xxx functions assume that the local -// neighborhoods have been marked so that each face -// is marked with the number of involved vertices it has. -// - -double MxEdgeQSlim::check_local_compactness(unsigned int v1, unsigned int /*v2*/, const float* vnew) -{ - const MxFaceList& N1 = m->neighbors(v1); - double c_min = 1.0; - - for (unsigned int i = 0; i < (unsigned int)N1.length(); i++) - if (m->face_mark(N1[i]) == 1) - { - const MxFace& f = m->face(N1[i]); - Vec3 f_after[3]; - for (unsigned int j = 0; j < 3; j++) - f_after[j] = (f[j] == v1) ? Vec3(vnew) : Vec3(m->vertex(f[j])); - - double c = triangle_compactness(f_after[0], f_after[1], f_after[2]); - - if (c < c_min) - c_min = c; - } - - return c_min; -} - -double MxEdgeQSlim::check_local_inversion(unsigned int v1, unsigned int /*v2*/, const float* vnew) -{ - double Nmin = 1.0; - const MxFaceList& N1 = m->neighbors(v1); - - for (unsigned int i = 0; i < (unsigned int)N1.length(); i++) - if (m->face_mark(N1[i]) == 1) - { - const MxFace& f = m->face(N1[i]); - Vec3 n_before; - m->compute_face_normal(N1[i], n_before); - - Vec3 f_after[3]; - for (unsigned int j = 0; j < 3; j++) - f_after[j] = (f[j] == v1) ? Vec3(vnew) : Vec3(m->vertex(f[j])); - - Vec3 n_after = triangle_normal(f_after[0], f_after[1], f_after[2]); - double delta = n_before * n_after; - - if (delta < Nmin) - Nmin = delta; - } - - return Nmin; -} - -unsigned int MxEdgeQSlim::check_local_validity(unsigned int v1, unsigned int /*v2*/, const float* vnew) - -{ - const MxFaceList& N1 = m->neighbors(v1); - unsigned int nfailed = 0; - unsigned int i; - - for (i = 0; i < (unsigned int)N1.length(); i++) - { - if (m->face_mark(N1[i]) == 1) - { - MxFace& f = m->face(N1[i]); - unsigned int k = f.find_vertex(v1); - unsigned int x = f[(k + 1) % 3]; - unsigned int y = f[(k + 2) % 3]; - - float d_yx[3], d_vx[3], d_vnew[3], f_n[3], n[3]; - mxv_sub(d_yx, m->vertex(y), m->vertex(x), 3); // d_yx = y-x - mxv_sub(d_vx, m->vertex(v1), m->vertex(x), 3); // d_vx = v-x - mxv_sub(d_vnew, vnew, m->vertex(x), 3); // d_vnew = vnew-x - - mxv_cross3(f_n, d_yx, d_vx); - mxv_cross3(n, f_n, d_yx); // n = ((y-x)^(v-x))^(y-x) - mxv_unitize(n, 3); - - // R_ASSERT( mxv_dot(d_vx, n, 3) > -FEQ_EPS ); - if (mxv_dot(d_vnew, n, 3) < local_validity_threshold * mxv_dot(d_vx, n, 3)) - nfailed++; - } - } - - return nfailed; -} - -unsigned int MxEdgeQSlim::check_local_degree(unsigned int v1, unsigned int v2, const float*) -{ - const MxFaceList& N1 = m->neighbors(v1); - const MxFaceList& N2 = m->neighbors(v2); - unsigned int i; - unsigned int degree = 0; - - // Compute the degree of the vertex after contraction - // - for (i = 0; i < (unsigned int)N1.length(); i++) - if (m->face_mark(N1[i]) == 1) - degree++; - - for (i = 0; i < (unsigned int)N2.length(); i++) - if (m->face_mark(N2[i]) == 1) - degree++; - - if (degree > vertex_degree_limit) - return degree - vertex_degree_limit; - else - return 0; -} - -void MxEdgeQSlim::apply_mesh_penalties(MxQSlimEdge* info) -{ - unsigned int i; - - const MxFaceList& N1 = m->neighbors(info->v1); - const MxFaceList& N2 = m->neighbors(info->v2); - - // Set up the face marks as the check_xxx() functions expect. - // - for (i = 0; i < (unsigned int)N2.length(); i++) - m->face_mark(N2[i], 0); - for (i = 0; i < (unsigned int)N1.length(); i++) - m->face_mark(N1[i], 1); - for (i = 0; i < (unsigned int)N2.length(); i++) - m->face_mark(N2[i], m->face_mark(N2[i]) + 1); - - double base_error = info->heap_key(); - double bias = 0.0; - - // Check for excess over degree bounds. - // - unsigned int max_degree = std::max(N1.length(), N2.length()); - if (max_degree > vertex_degree_limit) - bias += (max_degree - vertex_degree_limit) * meshing_penalty * 0.001; - -#if ALTERNATE_DEGREE_BIAS - // ??BUG: This code was supposed to be a slight improvement over - // the earlier version above. But it performs worse. - // Should check into why sometime. - // - unsigned int degree_excess = check_local_degree(info->v1, info->v2, info->vnew); - if (degree_excess) - bias += degree_excess * meshing_penalty; -#endif - - // Local validity checks - // - unsigned int nfailed = check_local_validity(info->v1, info->v2, info->vnew); - nfailed += check_local_validity(info->v2, info->v1, info->vnew); - if (nfailed) - bias += nfailed * meshing_penalty; - - // if (a) - { - double Nmin1 = check_local_inversion(info->v1, info->v2, info->vnew); - double Nmin2 = check_local_inversion(info->v2, info->v1, info->vnew); - if (std::min(Nmin1, Nmin2) < 0.0) - bias += meshing_penalty; - } - - float _scale = 1.f; - if (compactness_ratio > 0.0) - { - double c1_min = check_local_compactness(info->v1, info->v2, info->vnew); - double c2_min = check_local_compactness(info->v2, info->v1, info->vnew); - double c_min = _min(c1_min, c2_min); - - // !!BUG: There's a small problem with this: it ignores the scale - // of the errors when adding the bias. For instance, enabling - // this on the cow produces bad results. I also tried - // += (base_error + FEQ_EPS) * (2-c_min), but that works - // poorly on the flat planar thing. A better solution is - // clearly needed. - // - // NOTE: The prior heuristic was - // if( ratio*cmin_before > cmin_after ) apply penalty; - // - if (c_min < compactness_ratio) - _scale += float((compactness_ratio - c_min) / compactness_ratio); - - // if( c_min < compactness_ratio ) - // bias += (1-c_min); - } - -#if USE_OLD_INVERSION_CHECK - double Nmin1 = check_local_inversion(info->v1, info->v2, info->vnew); - double Nmin2 = check_local_inversion(info->v2, info->v1, info->vnew); - if (std::min(Nmin1, Nmin2) < 0.0) - bias += meshing_penalty; -#endif - - info->heap_key(float((base_error - EDGE_BASE_ERROR) * _scale - bias)); - // info->heap_key(float(base_error - bias)); -} - -void MxEdgeQSlim::compute_target_placement(MxQSlimEdge* info) -{ - MxVertexID i = info->v1, j = info->v2; - - const MxQuadric3 &Qi = quadrics(i), &Qj = quadrics(j); - - MxQuadric3 Q = Qi; - Q += Qj; - double e_min; - - if (placement_policy == MX_PLACE_OPTIMAL && Q.optimize(&info->vnew[0], &info->vnew[1], &info->vnew[2])) - { - e_min = Q(info->vnew); - } - else - { - Vec3 vi(m->vertex(i)), vj(m->vertex(j)); - Vec3 best; - - if (placement_policy >= MX_PLACE_LINE && Q.optimize(best, vi, vj)) - e_min = Q(best); - else - { - double ei = Q(vi), ej = Q(vj); - - if (ei < ej) - { - e_min = ei; - best = vi; - } - else - { - e_min = ej; - best = vj; - } - - if (placement_policy >= MX_PLACE_ENDORMID) - { - Vec3 mid = (vi + vj) / 2.0; - double e_mid = Q(mid); - - if (e_mid < e_min) - { - e_min = e_mid; - best = mid; - } - } - } - - info->vnew[0] = (float)best[0]; - info->vnew[1] = (float)best[1]; - info->vnew[2] = (float)best[2]; - } - - if (weighting_policy == MX_WEIGHT_AREA_AVG) - e_min /= Q.area(); - - info->heap_key(float(-e_min)); -} - -void MxEdgeQSlim::finalize_edge_update(MxQSlimEdge* info) -{ - if (meshing_penalty > 1.0) - apply_mesh_penalties(info); - - if (info->is_in_heap()) - heap.update(info); - else - heap.insert(info); -} - -void MxEdgeQSlim::compute_edge_info(MxQSlimEdge* info) -{ - compute_target_placement(info); - - finalize_edge_update(info); -} - -void MxEdgeQSlim::create_edge(MxVertexID i, MxVertexID j) -{ - MxQSlimEdge* info = xr_new(); - - edge_links(i).add(info); - edge_links(j).add(info); - - info->v1 = i; - info->v2 = j; - - compute_edge_info(info); -} - -void MxEdgeQSlim::initialize() { MxQSlim::initialize(); } -void MxEdgeQSlim::collect_edges() -{ - MxVertexList star; - - for (MxVertexID i = 0; i < m->vert_count(); i++) - { - star.reset(); - m->collect_vertex_star(i, star); - - for (unsigned int j = 0; j < (unsigned int)star.length(); j++) - if (i < star(j)) // Only add particular edge once - create_edge(i, star(j)); - } -} - -void MxEdgeQSlim::collect_edges(const MxEdge* edges, unsigned int count) -{ - for (unsigned int i = 0; i < count; i++) - create_edge(edges[i].v1, edges[i].v2); -} - -void MxEdgeQSlim::update_pre_contract(const MxPairContraction& conx) -{ - MxVertexID v1 = conx.v1, v2 = conx.v2; - unsigned int i, j; - - star.reset(); - // - // Before, I was gathering the vertex "star" using: - // m->collect_vertex_star(v1, star); - // This doesn't work when we initially begin with a subset of - // the total edges. Instead, we need to collect the "star" - // from the edge links maintained at v1. - // - for (i = 0; i < (unsigned int)edge_links(v1).length(); i++) - star.add(edge_links(v1)[i]->opposite_vertex(v1)); - - for (i = 0; i < (unsigned int)edge_links(v2).length(); i++) - { - MxQSlimEdge* e = edge_links(v2)(i); - MxVertexID u = (e->v1 == v2) ? e->v2 : e->v1; - VERIFY(e->v1 == v2 || e->v2 == v2); - VERIFY(u != v2); - - if (u == v1 || varray_find(star, u)) - { - // This is a useless link --- kill it - [[maybe_unused]] bool found = varray_find(edge_links(u), e, &j); - VERIFY(found); - edge_links(u).remove(j); - heap.remove(e); - if (u != v1) - xr_delete(e); // (v1,v2) will be deleted later - } - else - { - // Relink this to v1 - e->v1 = v1; - e->v2 = u; - edge_links(v1).add(e); - } - } - - edge_links(v2).reset(); -} - -void MxEdgeQSlim::update_post_contract(const MxPairContraction& conx) {} -void MxEdgeQSlim::apply_contraction(const MxPairContraction& conx) -{ - // - // Pre-contraction update - valid_verts--; - valid_faces -= conx.dead_faces.length(); - quadrics(conx.v1) += quadrics(conx.v2); - - update_pre_contract(conx); - - m->apply_contraction(conx); - - update_post_contract(conx); - - // Must update edge info here so that the meshing penalties - // will be computed with respect to the new mesh rather than the old - //. for(unsigned int i=0; i<(unsigned int)edge_links(conx.v1).length(); i++) - //. compute_edge_info(edge_links(conx.v1)[i]); - star.reset(); - m->collect_vertex_star(conx.v1, star); - star.add(conx.v1); - - edges.clear(); - for (unsigned int j = 0; j < (unsigned int)star.length(); j++) - for (unsigned int i = 0; i < (unsigned int)edge_links(star(j)).length(); i++) - edges.push_back(edge_links(star(j))[i]); - - // u32 r=edges.size(); - std::sort(edges.begin(), edges.end()); - auto new_end = std::unique(edges.begin(), edges.end()); - edges.erase(new_end, edges.end()); - // u32 rr=edges.size(); - // Msg ("%d: %d/%d - %d",(unsigned int)edge_links(conx.v1).length(),r,rr,r-rr); - for (auto it = edges.begin(); it != edges.end(); ++it) - compute_edge_info(*it); -} - -void MxEdgeQSlim::update_pre_expand(const MxPairContraction&) {} -void MxEdgeQSlim::update_post_expand(const MxPairContraction& conx) -{ - MxVertexID v1 = conx.v1, v2 = conx.v2; - unsigned int i; - - star.reset(); - star2.reset(); - //. PRECAUTION(edge_links(conx.v2).reset()); - m->collect_vertex_star(conx.v1, star); - m->collect_vertex_star(conx.v2, star2); - - i = 0; - while (i < (unsigned int)edge_links(v1).length()) - { - MxQSlimEdge* e = edge_links(v1)(i); - MxVertexID u = (e->v1 == v1) ? e->v2 : e->v1; - VERIFY(e->v1 == v1 || e->v2 == v1); - VERIFY(u != v1 && u != v2); - - bool v1_linked = varray_find(star, u); - bool v2_linked = varray_find(star2, u); - - if (v1_linked) - { - if (v2_linked) - create_edge(v2, u); - i++; - } - else - { - // !! BUG: I expected this to be true, but it's not. - // Need to find out why, and whether it's my - // expectation or the code that's wrong. - // VERIFY(v2_linked); - e->v1 = v2; - e->v2 = u; - edge_links(v2).add(e); - edge_links(v1).remove(i); - } - - compute_edge_info(e); - } - - if (varray_find(star, v2)) - // ?? BUG: Is it legitimate for there not to be an edge here ?? - create_edge(v1, v2); -} - -void MxEdgeQSlim::apply_expansion(const MxPairContraction& conx) -{ - update_pre_expand(conx); - - m->apply_expansion(conx); - - // - // Post-expansion update - valid_verts++; - valid_faces += conx.dead_faces.length(); - quadrics(conx.v1) -= quadrics(conx.v2); - - update_post_expand(conx); -} - -bool MxEdgeQSlim::decimate(unsigned int target, float max_error, void* cb_params) -{ - MxPairContraction local_conx; - - max_error += EDGE_BASE_ERROR; - while (valid_faces > target) - { - MxHeapable* top = heap.top(); - if (!top) - { - return false; - } - if (-top->heap_key() > max_error) - { - return true; - } - - MxQSlimEdge* info = (MxQSlimEdge*)heap.extract(); - MxVertexID v1 = info->v1; - MxVertexID v2 = info->v2; - - if (m->vertex_is_valid(v1) && m->vertex_is_valid(v2)) - { - MxPairContraction& conx = local_conx; - - m->compute_contraction(v1, v2, &conx, info->vnew); - - if (will_join_only && conx.dead_faces.length() > 0) - continue; - - if (contraction_callback) - (*contraction_callback)(conx, -(info->heap_key() + EDGE_BASE_ERROR), cb_params); - - apply_contraction(conx); - } - - xr_delete(info); - } - - return true; -} - -void MxFaceQSlim::compute_face_info(MxFaceID f) -{ - tri_info& info = f_info(f); - info.f = f; - - MxVertexID i = m->face(f)(0); - MxVertexID j = m->face(f)(1); - MxVertexID k = m->face(f)(2); - - const MxQuadric3& Qi = quadrics(i); - const MxQuadric3& Qj = quadrics(j); - const MxQuadric3& Qk = quadrics(k); - - MxQuadric3 Q = Qi; - Q += Qj; - Q += Qk; - - if (placement_policy == MX_PLACE_OPTIMAL && Q.optimize(&info.vnew[0], &info.vnew[1], &info.vnew[2])) - { - info.heap_key(float(-Q(info.vnew))); - } - else - { - Vec3 v1(m->vertex(i)), v2(m->vertex(j)), v3(m->vertex(k)); - double e1 = Q(v1), e2 = Q(v2), e3 = Q(v3); - - Vec3 best; - double e_min; - - if (e1 <= e2 && e1 <= e3) - { - e_min = e1; - best = v1; - } - else if (e2 <= e1 && e2 <= e3) - { - e_min = e2; - best = v2; - } - else - { - e_min = e3; - best = v3; - } - - info.vnew[0] = (float)best[0]; - info.vnew[1] = (float)best[1]; - info.vnew[2] = (float)best[2]; - info.heap_key(float(-e_min)); - } - - if (weighting_policy == MX_WEIGHT_AREA_AVG) - info.heap_key(float(info.heap_key() / Q.area())); - - if (info.is_in_heap()) - heap.update(&info); - else - heap.insert(&info); -} - -MxFaceQSlim::MxFaceQSlim(MxStdModel* _m) : MxQSlim(_m), f_info(_m->face_count()) {} -void MxFaceQSlim::initialize() -{ - MxQSlim::initialize(); - - for (MxFaceID f = 0; f < m->face_count(); f++) - compute_face_info(f); -} - -bool MxFaceQSlim::decimate(unsigned int target, float max_error, void* cb_params) -{ - unsigned int i; - - MxFaceList changed; - - while (valid_faces > target) - { - MxHeapable* top = heap.top(); - if (!top) - { - return false; - } - if (-top->heap_key() > max_error) - { - return true; - } - - tri_info* info = (tri_info*)heap.extract(); - - MxFaceID f = info->f; - MxVertexID v1 = m->face(f)(0), v2 = m->face(f)(1), v3 = m->face(f)(2); - - if (m->face_is_valid(f)) - { - // - // Perform the actual contractions - m->contract(v1, v2, v3, info->vnew, changed); - - quadrics(v1) += quadrics(v2); // update quadric of v1 - quadrics(v1) += quadrics(v3); - - // - // Update valid counts - valid_verts -= 2; - for (i = 0; i < (unsigned int)changed.length(); i++) - if (!m->face_is_valid(changed(i))) - valid_faces--; - - for (i = 0; i < (unsigned int)changed.length(); i++) - if (m->face_is_valid(changed(i))) - compute_face_info(changed(i)); - else - heap.remove(&f_info(changed(i))); - } - } - - return true; -} diff --git a/src/utils/xrQSlim/MxQSlim.h b/src/utils/xrQSlim/MxQSlim.h deleted file mode 100644 index 8d0536eb88e..00000000000 --- a/src/utils/xrQSlim/MxQSlim.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef MXQSLIM_INCLUDED // -*- C++ -*- -#define MXQSLIM_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Surface simplification using quadric error metrics - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxQSlim.h,v 1.29 1999/02/18 15:26:07 garland Exp $ - - ************************************************************************/ - -#include "MxStdSlim.h" -#include "MxQMetric3.h" - -class MxQSlim : public MxStdSlim -{ -protected: - MxBlock quadrics; - - void discontinuity_constraint(MxVertexID, MxVertexID, MxFaceID); - void discontinuity_constraint(MxVertexID, MxVertexID, const MxFaceList&); - void collect_quadrics(); - void transform_quadrics(const Mat4&); - void constrain_boundaries(); - -public: - Mat4* object_transform; - -public: - MxQSlim(MxStdModel*); - virtual ~MxQSlim() {} - virtual void initialize(); - - const MxQuadric3& vertex_quadric(MxVertexID v) { return quadrics(v); } - void constraint_manual(MxVertexID, MxVertexID, MxFaceID); -}; - -class MxQSlimEdge : public MxEdge, public MxHeapable -{ -public: - float vnew[3]; -}; - -class MxEdgeQSlim : public MxQSlim -{ - using edge_list = MxSizedDynBlock; - - MxBlock edge_links; - - // - // Temporary variables used by methods - using EdgeVec = xr_vector; - EdgeVec edges; - MxVertexList star, star2; - MxPairContraction conx_tmp; - -protected: - double check_local_compactness(unsigned int v1, unsigned int v2, const float* vnew); - double check_local_inversion(unsigned int v1, unsigned int v2, const float* vnew); - unsigned int check_local_validity(unsigned int v1, unsigned int v2, const float* vnew); - unsigned int check_local_degree(unsigned int v1, unsigned int v2, const float* vnew); - void apply_mesh_penalties(MxQSlimEdge*); - void create_edge(MxVertexID i, MxVertexID j); - - void compute_target_placement(MxQSlimEdge*); - void finalize_edge_update(MxQSlimEdge*); - - virtual void compute_edge_info(MxQSlimEdge*); - virtual void update_pre_contract(const MxPairContraction&); - virtual void update_post_contract(const MxPairContraction&); - virtual void update_pre_expand(const MxPairContraction&); - virtual void update_post_expand(const MxPairContraction&); - -public: - MxEdgeQSlim(MxStdModel*); - virtual ~MxEdgeQSlim(); - - void initialize(); - void collect_edges(); - void collect_edges(const MxEdge* edges, unsigned int count); - bool decimate(unsigned int target, float max_error, void* cb_params = 0); - - void apply_contraction(const MxPairContraction& conx); - void apply_expansion(const MxPairContraction& conx); - - unsigned int edge_count() const { return heap.size(); } - const MxQSlimEdge* edge(unsigned int i) const { return (MxQSlimEdge*)heap.item(i); } -}; - -class MxFaceQSlim : public MxQSlim -{ -private: - class tri_info : public MxHeapable - { - public: - MxFaceID f; - float vnew[3]; - }; - - MxBlock f_info; - -protected: - void compute_face_info(MxFaceID); - -public: - MxFaceQSlim(MxStdModel*); - - void initialize(); - bool decimate(unsigned int target, float max_error, void* cb_params = 0); -}; - -// MXQSLIM_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxStdModel.cpp b/src/utils/xrQSlim/MxStdModel.cpp deleted file mode 100644 index 7177019b389..00000000000 --- a/src/utils/xrQSlim/MxStdModel.cpp +++ /dev/null @@ -1,707 +0,0 @@ -/************************************************************************ - -MxStdModel - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: MxStdModel.cxx,v 1.42 2000/11/20 20:36:38 garland Exp $ - -************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxStdModel.h" -#include "MxVector.h" - -MxPairContraction& MxPairContraction::operator=(const MxPairContraction& c) -{ - v1 = c.v1; - v2 = c.v2; - mxv_set(dv1, c.dv1, 3); - mxv_set(dv2, c.dv2, 3); - - delta_faces.reset(); - dead_faces.reset(); - - for (unsigned int i = 0; i < (unsigned int)c.delta_faces.length(); i++) - delta_faces.add(c.delta_faces[i]); - for (unsigned int j = 0; j < (unsigned int)c.dead_faces.length(); j++) - dead_faces.add(c.dead_faces[j]); - - delta_pivot = c.delta_pivot; - - return *this; -} - -MxStdModel::~MxStdModel() -{ - for (unsigned int i = 0; i < (unsigned int)face_links.length(); i++) - xr_delete(face_links[i]); -} - -MxVertexID MxStdModel::alloc_vertex(float x, float y, float z) -{ - MxVertexID id = MxBlockModel::alloc_vertex(x, y, z); - v_data.add(); - v_data(id).tag = 0x0; - v_data(id).user_tag = 0x0; - vertex_mark_valid(id); - - face_links.add(xr_new()); - VERIFY(face_links.last_id() == id); - VERIFY(neighbors(id).length() == 0); - - return id; -} - -void MxStdModel::free_vertex(MxVertexID v) -{ - xr_delete(face_links[v]); - face_links.remove(v); - v_data.remove(v); -} - -MxFaceID MxStdModel::alloc_face(MxVertexID v1, MxVertexID v2, MxVertexID v3) -{ - MxFaceID id = MxBlockModel::alloc_face(v1, v2, v3); - f_data.add(); - f_data(id).tag = 0x0; - f_data(id).user_tag = 0x0; - face_mark_valid(id); - - return id; -} - -void MxStdModel::free_face(MxFaceID f) { f_data.remove(f); } -void MxStdModel::init_face(MxFaceID id) -{ - neighbors(face(id).v[0]).add(id); - neighbors(face(id).v[1]).add(id); - neighbors(face(id).v[2]).add(id); -} - -MxStdModel* MxStdModel::clone() -{ - MxStdModel* m = xr_new(vert_count(), face_count()); - // ??BUG: Current flags/marks won't be copied. Is this the - // behavior we want? - MxBlockModel::clone(m); - - return m; -} - -void MxStdModel::mark_neighborhood(MxVertexID vid, unsigned short mark) -{ - VERIFY(vid < vert_count()); - - for (unsigned int i = 0; i < (unsigned int)neighbors(vid).length(); i++) - { - unsigned int f = neighbors(vid)(i); - fmark(f, (unsigned char)mark); - } -} - -void MxStdModel::collect_unmarked_neighbors(MxVertexID vid, MxFaceList& faces) -{ - VERIFY(vid < vert_count()); - - for (unsigned int i = 0; i < (unsigned int)neighbors(vid).length(); i++) - { - unsigned int fid = neighbors(vid)(i); - if (!fmark(fid)) - { - faces.add(fid); - fmark(fid, 1); - } - } -} - -void MxStdModel::mark_neighborhood_delta(MxVertexID vid, short delta) -{ - VERIFY(vid < vert_count()); - for (unsigned int i = 0; i < (unsigned int)neighbors(vid).length(); i++) - { - unsigned int f = neighbors(vid)(i); - fmark(f, u8(fmark(f) + delta)); - } -} - -void MxStdModel::partition_marked_neighbors(MxVertexID v, unsigned short pivot, MxFaceList& lo, MxFaceList& hi) -{ - VERIFY(v < vert_count()); - for (unsigned int i = 0; i < (unsigned int)neighbors(v).length(); i++) - { - unsigned int f = neighbors(v)(i); - if (fmark(f)) - { - if (fmark(f) < pivot) - lo.add(f); - else - hi.add(f); - fmark(f, 0); - } - } -} - -void MxStdModel::mark_corners(const MxFaceList& faces, unsigned short mark) -{ - for (unsigned int i = 0; i < (unsigned int)faces.length(); i++) - for (unsigned int j = 0; j < 3; j++) - vmark(face(faces(i))(j), (unsigned char)mark); -} - -void MxStdModel::collect_unmarked_corners(const MxFaceList& faces, MxVertexList& verts) -{ - for (unsigned int i = 0; i < (unsigned int)faces.length(); i++) - for (unsigned int j = 0; j < 3; j++) - { - MxVertexID v = face(faces(i))(j); - if (!vmark(v)) - { - verts.add(v); - vmark(v, 1); - } - } -} - -void MxStdModel::collect_edge_neighbors(unsigned int v1, unsigned int v2, MxFaceList& faces) -{ - mark_neighborhood(v1, 1); - mark_neighborhood(v2, 0); - collect_unmarked_neighbors(v1, faces); -} - -void MxStdModel::collect_vertex_star(unsigned int v, MxVertexList& verts) -{ - const MxFaceList& N = neighbors(v); - - mark_corners(N, 0); - vmark(v, 1); // Don't want to include v in the star - collect_unmarked_corners(N, verts); -} - -void MxStdModel::collect_neighborhood(MxVertexID v, int depth, MxFaceList& faces) -{ - // TODO: This method is somewhat inefficient. It will repeatedly touch - // all the faces within the collected region at each iteration. For now, - // this is acceptable. But ultimately it will need to be fixed. - - int i; - - faces.reset(); - - // Initially copy immediate neighbors of v - for (i = 0; i < neighbors(v).length(); i++) - faces.add(neighbors(v)[i]); - - for (; depth > 0; depth--) - { - // Unmark the neighbors of all vertices in region - for (i = 0; i < faces.length(); i++) - { - mark_neighborhood(face(faces[i])[0], 0); - mark_neighborhood(face(faces[i])[1], 0); - mark_neighborhood(face(faces[i])[2], 0); - } - - // Mark all faces already accumulated - for (i = 0; i < faces.length(); i++) - fmark(faces[i], 1); - - // Collect all unmarked faces - int limit = faces.length(); - for (i = 0; i < limit; i++) - { - collect_unmarked_neighbors(face(faces[i])[0], faces); - collect_unmarked_neighbors(face(faces[i])[1], faces); - collect_unmarked_neighbors(face(faces[i])[2], faces); - } - } -} - -void MxStdModel::compute_vertex_normal(MxVertexID v, float* n) -{ - MxFaceList& star = neighbors(v); - mxv_set(n, 0.0f, 3); - - unsigned int i; - for (i = 0; i < (unsigned int)star.length(); i++) - { - float fn[3]; - - // Weight normals uniformly - compute_face_normal(star(i), fn, false); - // - // Weight normals by angle around vertex - // unsigned int c = face(star[i]).find_vertex(v); - // compute_face_normal(star[i], fn); - // mxv_scale(fn, compute_corner_angle(star[i], c), 3); - - mxv_addinto(n, fn, 3); - } - if (i > 0) - mxv_unitize(n, 3); -} - -void MxStdModel::synthesize_normals(unsigned int start) -{ - float n[3]; - - if (normal_binding() == MX_PERFACE) - { - for (MxFaceID f = start; f < face_count(); f++) - { - compute_face_normal(f, n); - add_normal(n[0], n[1], n[2]); - } - } - else if (normal_binding() == MX_PERVERTEX) - { - for (MxVertexID v = start; v < vert_count(); v++) - { - compute_vertex_normal(v, n); - add_normal(n[0], n[1], n[2]); - } - } - else - FATAL("Unsupported normal binding."); -} - -void MxStdModel::remap_vertex(unsigned int from, unsigned int to) -{ - VERIFY(from < vert_count()); - VERIFY(to < vert_count()); - VERIFY(vertex_is_valid(from)); - VERIFY(vertex_is_valid(to)); - - for (unsigned int i = 0; i < (unsigned int)neighbors(from).length(); i++) - face(neighbors(from)(i)).remap_vertex(from, to); - - mark_neighborhood(from, 0); - mark_neighborhood(to, 1); - collect_unmarked_neighbors(from, neighbors(to)); - - vertex_mark_invalid(from); - neighbors(from).reset(); // remove links in old vertex -} - -unsigned int MxStdModel::split_edge(unsigned int a, unsigned int b) -{ - float *v1 = vertex(a), *v2 = vertex(b); - - return split_edge(a, b, (v1[0] + v2[0]) / 2.0f, (v1[1] + v2[1]) / 2.0f, (v1[2] + v2[2]) / 2.0f); -} - -static void remove_neighbor(MxFaceList& faces, unsigned int f) -{ - unsigned int j; - if (varray_find(faces, f, &j)) - faces.remove(j); -} - -unsigned int MxStdModel::split_edge(unsigned int v1, unsigned int v2, float x, float y, float z) -{ - VERIFY(v1 < vert_count()); - VERIFY(v2 < vert_count()); - VERIFY(vertex_is_valid(v1)); - VERIFY(vertex_is_valid(v2)); - VERIFY(v1 != v2); - - MxFaceList faces; - collect_edge_neighbors(v1, v2, faces); - VERIFY(faces.length() > 0); - - unsigned int vnew = add_vertex(x, y, z); - - for (unsigned int i = 0; i < (unsigned int)faces.length(); i++) - { - unsigned int f = faces(i); - unsigned int v3 = face(f).opposite_vertex(v1, v2); - VERIFY(v3 != v1 && v3 != v2); - VERIFY(vertex_is_valid(v3)); - - // in f, remap v2-->vnew - face(f).remap_vertex(v2, vnew); - neighbors(vnew).add(f); - - // remove f from neighbors(v2) - remove_neighbor(neighbors(v2), f); - - // assure orientation is consistent - if (face(f).is_inorder(vnew, v3)) - add_face(vnew, v2, v3); - else - add_face(vnew, v3, v2); - } - - return vnew; -} - -void MxStdModel::flip_edge(unsigned int v1, unsigned int v2) -{ - MxFaceList faces; - collect_edge_neighbors(v1, v2, faces); - if (faces.length() != 2) - return; - - unsigned int f1 = faces(0); - unsigned int f2 = faces(1); - unsigned int v3 = face(f1).opposite_vertex(v1, v2); - unsigned int v4 = face(f2).opposite_vertex(v1, v2); - - // ?? Should we check for convexity or assume thats been taken care of? - - remove_neighbor(neighbors(v1), f2); - remove_neighbor(neighbors(v2), f1); - neighbors(v3).add(f2); - neighbors(v4).add(f1); - - face(f1).remap_vertex(v2, v4); - face(f2).remap_vertex(v1, v3); -} - -void MxStdModel::split_face4(unsigned int f, unsigned int* newverts) -{ - unsigned int v0 = face(f).v[0]; - unsigned int v1 = face(f).v[1]; - unsigned int v2 = face(f).v[2]; - - unsigned int pivot = split_edge(v0, v1); - unsigned int new1 = split_edge(v1, v2); - unsigned int new2 = split_edge(v0, v2); - - if (newverts) - { - newverts[0] = pivot; - newverts[1] = new1; - newverts[2] = new2; - } - - flip_edge(pivot, v2); -} - -void MxStdModel::compact_vertices() -{ - MxVertexID oldID; - MxVertexID newID = 0; - - for (oldID = 0; oldID < vert_count(); oldID++) - { - if (vertex_is_valid(oldID)) - { - if (newID != oldID) - { - vertex(newID) = vertex(oldID); - if (normal_binding() == MX_PERVERTEX) - normal(newID) = normal(oldID); - if (color_binding() == MX_PERVERTEX) - color(newID) = color(oldID); - if (texcoord_binding() == MX_PERVERTEX) - texcoord(newID) = texcoord(oldID); - - // Because we'll be freeing the link lists for the - // old vertices, we actually have to swap values instead - // of the simple copying in the block above. - // - MxFaceList* t = face_links(newID); - face_links(newID) = face_links(oldID); - face_links(oldID) = t; - - vertex_mark_valid(newID); - - for (unsigned int i = 0; i < (unsigned int)neighbors(newID).length(); i++) - face(neighbors(newID)(i)).remap_vertex(oldID, newID); - } - newID++; - } - } - - for (oldID = newID; newID < vert_count();) - remove_vertex(oldID); -} - -void MxStdModel::unlink_face(MxFaceID fid) -{ - MxFace& f = face(fid); - face_mark_invalid(fid); - - unsigned int j; - int found = 0; - - if (varray_find(neighbors(f(0)), fid, &j)) - { - found++; - neighbors(f(0)).remove(j); - } - if (varray_find(neighbors(f(1)), fid, &j)) - { - found++; - neighbors(f(1)).remove(j); - } - if (varray_find(neighbors(f(2)), fid, &j)) - { - found++; - neighbors(f(2)).remove(j); - } - VERIFY(found > 0); - VERIFY(!varray_find(neighbors(f(0)), fid, &j)); - VERIFY(!varray_find(neighbors(f(1)), fid, &j)); - VERIFY(!varray_find(neighbors(f(2)), fid, &j)); -} - -void MxStdModel::remove_degeneracy(MxFaceList& faces) -{ - for (unsigned int i = 0; i < (unsigned int)faces.length(); i++) - { - VERIFY(face_is_valid(faces(i))); - MxFace& f = face(faces(i)); - - if (f(0) == f(1) || f(1) == f(2) || f(0) == f(2)) - unlink_face(faces(i)); - } -} - -void MxStdModel::compute_contraction(MxVertexID v1, MxVertexID v2, MxPairContraction* conx, const float* vnew) -{ - conx->v1 = v1; - conx->v2 = v2; - - if (vnew) - { - mxv_sub(conx->dv1, vnew, vertex(v1), 3); - mxv_sub(conx->dv2, vnew, vertex(v2), 3); - } - else - { - conx->dv1[0] = conx->dv1[1] = conx->dv1[2] = 0.0; - conx->dv2[0] = conx->dv2[1] = conx->dv2[2] = 0.0; - } - - conx->delta_faces.reset(); - conx->dead_faces.reset(); - - // Mark the neighborhood of (v1,v2) such that each face is - // tagged with the number of times the vertices v1,v2 occur - // in it. Possible values are 1 or 2. - // - mark_neighborhood(v2, 0); - mark_neighborhood(v1, 1); - mark_neighborhood_delta(v2, 1); - - // Now partition the neighborhood of (v1,v2) into those faces - // which degenerate during contraction and those which are merely - // reshaped. - // - partition_marked_neighbors(v1, 2, conx->delta_faces, conx->dead_faces); - conx->delta_pivot = conx->delta_faces.length(); - partition_marked_neighbors(v2, 2, conx->delta_faces, conx->dead_faces); -} - -void MxStdModel::apply_contraction(const MxPairContraction& conx) -{ - MxVertexID v1 = conx.v1, v2 = conx.v2; - - // Move v1 to new position - mxv_addinto(vertex(v1), conx.dv1, 3); - - unsigned int i; - // - // Remove dead faces - for (i = 0; i < (unsigned int)conx.dead_faces.length(); i++) - unlink_face(conx.dead_faces(i)); - - // - // Update changed faces - for (i = conx.delta_pivot; i < (unsigned int)conx.delta_faces.length(); i++) - { - MxFaceID fid = conx.delta_faces(i); - face(fid).remap_vertex(v2, v1); - neighbors(v1).add(fid); - } - - // - // !!HACK: This is really only a temporary solution to the problem - if (normal_binding() == MX_PERFACE) - { - float n[3]; - for (i = 0; i < (unsigned int)conx.delta_faces.length(); i++) - { - compute_face_normal(conx.delta_faces[i], n); - normal(conx.delta_faces[i]) = MxNormal(n); - } - } - - // - // Kill v2 - vertex_mark_invalid(v2); - neighbors(v2).reset(); -} - -void MxStdModel::apply_expansion(const MxPairExpansion& conx) -{ - MxVertexID v1 = conx.v1, v2 = conx.v2; - - mxv_sub(vertex(v2), vertex(v1), conx.dv2, 3); - mxv_subfrom(vertex(v1), conx.dv1, 3); - - unsigned int i, j; - for (i = 0; i < (unsigned int)conx.dead_faces.length(); i++) - { - MxFaceID fid = conx.dead_faces(i); - face_mark_valid(fid); - neighbors(face(fid)(0)).add(fid); - neighbors(face(fid)(1)).add(fid); - neighbors(face(fid)(2)).add(fid); - } - - for (i = conx.delta_pivot; i < (unsigned int)conx.delta_faces.length(); i++) - { - MxFaceID fid = conx.delta_faces(i); - face(fid).remap_vertex(v1, v2); - neighbors(v2).add(fid); - [[maybe_unused]] bool found = varray_find(neighbors(v1), fid, &j); - VERIFY(found); - neighbors(v1).remove(j); - } - - // - // !!HACK: This is really only a temporary solution to the problem - if (normal_binding() == MX_PERFACE) - { - float n[3]; - for (i = 0; i < (unsigned int)conx.delta_faces.length(); i++) - { - compute_face_normal(conx.delta_faces[i], n); - normal(conx.delta_faces[i]) = MxNormal(n); - } - - for (i = 0; i < (unsigned int)conx.dead_faces.length(); i++) - { - compute_face_normal(conx.dead_faces[i], n); - normal(conx.dead_faces[i]) = MxNormal(n); - } - } - - vertex_mark_valid(v2); -} - -void MxStdModel::contract(MxVertexID v1, MxVertexID v2, const float* vnew, MxPairContraction* conx) -{ - compute_contraction(v1, v2, conx); - mxv_sub(conx->dv1, vnew, vertex(v1), 3); - mxv_sub(conx->dv2, vnew, vertex(v2), 3); - apply_contraction(*conx); -} - -void MxStdModel::compute_contraction(MxFaceID fid, MxFaceContraction* conx) -{ - const MxFace& f = face(fid); - - conx->f = fid; - conx->dv1[0] = conx->dv1[1] = conx->dv1[2] = 0.0; - conx->dv2[0] = conx->dv2[1] = conx->dv2[2] = 0.0; - conx->dv3[0] = conx->dv3[1] = conx->dv3[2] = 0.0; - - conx->delta_faces.reset(); - conx->dead_faces.reset(); - - mark_neighborhood(f[0], 0); - mark_neighborhood(f[1], 0); - mark_neighborhood(f[2], 0); - - mark_neighborhood(f[0], 1); - mark_neighborhood_delta(f[1], +1); - mark_neighborhood_delta(f[2], +1); - - fmark(fid, 0); // don't include f in dead_faces - - partition_marked_neighbors(f[0], 2, conx->delta_faces, conx->dead_faces); - partition_marked_neighbors(f[1], 2, conx->delta_faces, conx->dead_faces); - partition_marked_neighbors(f[2], 2, conx->delta_faces, conx->dead_faces); -} - -void MxStdModel::contract(MxVertexID v1, MxVertexID v2, MxVertexID v3, const float* vnew, MxFaceList& changed) -{ - mark_neighborhood(v1, 0); - mark_neighborhood(v2, 0); - mark_neighborhood(v3, 0); - changed.reset(); - collect_unmarked_neighbors(v1, changed); - collect_unmarked_neighbors(v2, changed); - collect_unmarked_neighbors(v3, changed); - - // Move v1 to vnew - vertex(v1)(0) = vnew[0]; - vertex(v1)(1) = vnew[1]; - vertex(v1)(2) = vnew[2]; - - // Replace occurrences of v2 & v3 with v1 - remap_vertex(v2, v1); - remap_vertex(v3, v1); - - remove_degeneracy(changed); - - // - // !!HACK: Only a temporary solution - if (normal_binding() == MX_PERFACE) - { - float n[3]; - for (unsigned int i = 0; i < (unsigned int)changed.length(); i++) - if (face_is_valid(changed[i])) - { - compute_face_normal(changed[i], n); - normal(changed[i]) = MxNormal(n); - } - } -} - -void MxStdModel::contract(MxVertexID v1, const MxVertexList& rest, const float* vnew, MxFaceList& changed) -{ - unsigned int i; - - // Collect all effected faces - mark_neighborhood(v1, 0); - for (i = 0; i < (unsigned int)rest.length(); i++) - mark_neighborhood(rest(i), 0); - - changed.reset(); - - collect_unmarked_neighbors(v1, changed); - for (i = 0; i < (unsigned int)rest.length(); i++) - collect_unmarked_neighbors(rest(i), changed); - - // Move v1 to vnew - vertex(v1)(0) = vnew[0]; - vertex(v1)(1) = vnew[1]; - vertex(v1)(2) = vnew[2]; - - // Replace all occurrences of vi with v1 - for (i = 0; i < (unsigned int)rest.length(); i++) - remap_vertex(rest(i), v1); - - remove_degeneracy(changed); -} - -MxVertexID MxStdModel::resolve_proxies(MxVertexID v) -{ - while (vertex_is_proxy(v)) - v = vertex(v).as.proxy.parent; - return v; -} - -float* MxStdModel::vertex_position(MxVertexID v) { return vertex(resolve_proxies(v)); } -MxVertexID& MxStdModel::vertex_proxy_parent(MxVertexID v) -{ - VERIFY(vertex_is_proxy(v)); - return vertex(v).as.proxy.parent; -} - -MxVertexID MxStdModel::add_proxy_vertex(MxVertexID parent) -{ - MxVertexID v = alloc_vertex(0, 0, 0); // position will be ignored - - vertex_mark_proxy(v); - vertex_proxy_parent(v) = parent; - - return v; -} diff --git a/src/utils/xrQSlim/MxStdModel.h b/src/utils/xrQSlim/MxStdModel.h deleted file mode 100644 index 9d85f50bc39..00000000000 --- a/src/utils/xrQSlim/MxStdModel.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef MXSTDMODEL_INCLUDED // -*- C++ -*- -#define MXSTDMODEL_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - MxStdModel - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxStdModel.h,v 1.35 2000/11/28 15:50:14 garland Exp $ - - ************************************************************************/ - -#include "MxBlockModel.h" - -typedef MxSizedDynBlock MxFaceList; -typedef MxSizedDynBlock MxVertexList; -typedef MxDynBlock MxEdgeList; - -class MxPairContraction -{ -public: - MxPairContraction() {} - MxPairContraction(const MxPairContraction& c) { *this = c; } - MxPairContraction& operator=(const MxPairContraction& c); - - MxVertexID v1, v2; - float dv1[3], dv2[3]; // dv2 is not really necessary - - unsigned int delta_pivot; - MxFaceList delta_faces; - MxFaceList dead_faces; -}; - -class MxFaceContraction -{ -public: - MxFaceID f; - float dv1[3], dv2[3], dv3[3]; - - MxFaceList delta_faces; - MxFaceList dead_faces; -}; - -typedef MxPairContraction MxPairExpansion; - -// Masks for internal tag bits -#define MX_VALID_FLAG 0x01 -#define MX_PROXY_FLAG 0x02 -#define MX_TOUCHED_FLAG 0x04 -#define MX_LOCK_FLAG 0x08 - -class MxStdModel : public MxBlockModel -{ -private: - struct vertex_data - { - unsigned char mark, tag; // Internal tag bits - unsigned char user_mark, user_tag; // External tag bits - }; - struct face_data - { - unsigned char mark, tag; // Internal tag bits - unsigned char user_mark, user_tag; // External tag bits - }; - - MxDynBlock v_data; - MxDynBlock f_data; - MxDynBlock face_links; - -protected: - // - // Accessors for internal tag and mark bits - unsigned int v_check_tag(MxVertexID i, unsigned int tag) const { return v_data(i).tag & tag; } - void v_set_tag(MxVertexID i, unsigned int tag) { v_data(i).tag |= tag; } - void v_unset_tag(MxVertexID i, unsigned int tag) { v_data(i).tag &= ~tag; } - unsigned char vmark(MxVertexID i) const { return v_data(i).mark; } - void vmark(MxVertexID i, unsigned char m) { v_data(i).mark = m; } - unsigned int f_check_tag(MxFaceID i, unsigned int tag) const { return f_data(i).tag & tag; } - void f_set_tag(MxFaceID i, unsigned int tag) { f_data(i).tag |= tag; } - void f_unset_tag(MxFaceID i, unsigned int tag) { f_data(i).tag &= ~tag; } - unsigned char fmark(MxFaceID i) const { return f_data(i).mark; } - void fmark(MxFaceID i, unsigned char m) { f_data(i).mark = m; } -protected: - MxVertexID alloc_vertex(float, float, float); - void free_vertex(MxVertexID); - void free_face(MxFaceID); - MxFaceID alloc_face(MxVertexID, MxVertexID, MxVertexID); - void init_face(MxFaceID); - -public: - MxStdModel(unsigned int nvert, unsigned int nface) - : MxBlockModel(nvert, nface), v_data(nvert), f_data(nface), face_links(nvert) - { - } - virtual ~MxStdModel(); - MxStdModel* clone(); - - //////////////////////////////////////////////////////////////////////// - // Tagging and marking - // - unsigned int vertex_is_valid(MxVertexID i) const { return v_check_tag(i, MX_VALID_FLAG); } - void vertex_mark_valid(MxVertexID i) { v_set_tag(i, MX_VALID_FLAG); } - void vertex_mark_invalid(MxVertexID i) { v_unset_tag(i, MX_VALID_FLAG); } - unsigned int vertex_is_locked(MxVertexID i) const { return v_check_tag(i, MX_LOCK_FLAG); } - void vertex_mark_locked(MxVertexID i) { v_set_tag(i, MX_LOCK_FLAG); } - void vertex_mark_unlocked(MxVertexID i) { v_unset_tag(i, MX_LOCK_FLAG); } - unsigned int face_is_valid(MxFaceID i) const { return f_check_tag(i, MX_VALID_FLAG); } - void face_mark_valid(MxFaceID i) { f_set_tag(i, MX_VALID_FLAG); } - void face_mark_invalid(MxFaceID i) { f_unset_tag(i, MX_VALID_FLAG); } - unsigned int face_is_locked(MxFaceID i) const { return f_check_tag(i, MX_LOCK_FLAG); } - void face_mark_locked(MxFaceID i) { f_set_tag(i, MX_LOCK_FLAG); } - void face_mark_unlocked(MxFaceID i) { f_unset_tag(i, MX_LOCK_FLAG); } - unsigned int vertex_is_proxy(MxVertexID i) const { return v_check_tag(i, MX_PROXY_FLAG); } - void vertex_mark_proxy(MxVertexID i) { v_set_tag(i, MX_PROXY_FLAG); } - void vertex_mark_nonproxy(MxVertexID i) { v_unset_tag(i, MX_PROXY_FLAG); } - // - // Accessors for external tag and mark bits - unsigned int vertex_check_tag(MxVertexID i, unsigned int tag) const { return v_data(i).user_tag & tag; } - void vertex_set_tag(MxVertexID i, unsigned int tag) { v_data(i).user_tag |= tag; } - void vertex_unset_tag(MxVertexID i, unsigned int tag) { v_data(i).user_tag &= ~tag; } - unsigned char vertex_mark(MxVertexID i) { return v_data(i).user_mark; } - void vertex_mark(MxVertexID i, unsigned char m) { v_data(i).user_mark = m; } - unsigned int face_check_tag(MxFaceID i, unsigned int tag) const { return f_data(i).user_tag & tag; } - void face_set_tag(MxFaceID i, unsigned int tag) { f_data(i).user_tag |= tag; } - void face_unset_tag(MxFaceID i, unsigned int tag) { f_data(i).user_tag &= ~tag; } - unsigned char face_mark(MxFaceID i) { return f_data(i).user_mark; } - void face_mark(MxFaceID i, unsigned char m) { f_data(i).user_mark = m; } - //////////////////////////////////////////////////////////////////////// - // Vertex proxy management and proxy-aware accessors - // - MxVertexID add_proxy_vertex(MxVertexID); - MxVertexID& vertex_proxy_parent(MxVertexID); - MxVertexID resolve_proxies(MxVertexID v); - float* vertex_position(MxVertexID v); - - //////////////////////////////////////////////////////////////////////// - // Neighborhood collection and management - // - void mark_neighborhood(MxVertexID, unsigned short mark = 0); - void collect_unmarked_neighbors(MxVertexID, MxFaceList& faces); - void mark_neighborhood_delta(MxVertexID, short delta); - void partition_marked_neighbors(MxVertexID, unsigned short pivot, MxFaceList& below, MxFaceList& above); - - void mark_corners(const MxFaceList& faces, unsigned short mark = 0); - void collect_unmarked_corners(const MxFaceList& faces, MxVertexList& verts); - - void collect_edge_neighbors(MxVertexID, MxVertexID, MxFaceList&); - void collect_vertex_star(MxVertexID v, MxVertexList& verts); - - MxFaceList& neighbors(MxVertexID v) { return *face_links(v); } - const MxFaceList& neighbors(MxVertexID v) const { return *face_links(v); } - void collect_neighborhood(MxVertexID v, int depth, MxFaceList& faces); - - void compute_vertex_normal(MxVertexID v, float*); - void synthesize_normals(unsigned int start = 0); - - //////////////////////////////////////////////////////////////////////// - // Primitive transformation operations - // - void remap_vertex(MxVertexID from, MxVertexID to); - MxVertexID split_edge(MxVertexID v1, MxVertexID v2, float x, float y, float z); - MxVertexID split_edge(MxVertexID v1, MxVertexID v2); - - void flip_edge(MxVertexID v1, MxVertexID v2); - - // split_face3 - void split_face4(MxFaceID f, MxVertexID* newverts = NULL); - - void unlink_face(MxFaceID f); - - //////////////////////////////////////////////////////////////////////// - // Contraction and related operations - // - void compact_vertices(); - void remove_degeneracy(MxFaceList&); - - // Pair contraction interface - void compute_contraction(MxVertexID, MxVertexID, MxPairContraction*, const float* vnew = NULL); - void apply_contraction(const MxPairContraction&); - void apply_expansion(const MxPairExpansion&); - void contract(MxVertexID v1, MxVertexID v2, const float*, MxPairContraction*); - - // Triple contraction interface - void compute_contraction(MxFaceID, MxFaceContraction*); - void contract(MxVertexID v1, MxVertexID v2, MxVertexID v3, const float* vnew, MxFaceList& changed); - - // Generalized contraction interface - void contract(MxVertexID v1, const MxVertexList& rest, const float* vnew, MxFaceList& changed); -}; - -extern void mx_render_model(MxStdModel&); -extern void mx_draw_mesh(MxStdModel&, double* color = NULL); -extern void mx_draw_wireframe(MxStdModel&, double* color = NULL); -extern void mx_draw_boundaries(MxStdModel&); -extern void mx_draw_pointcloud(MxStdModel&, double* color = NULL); - -// MXSTDMODEL_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxStdSlim.cpp b/src/utils/xrQSlim/MxStdSlim.cpp deleted file mode 100644 index d878c3a6b55..00000000000 --- a/src/utils/xrQSlim/MxStdSlim.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************ - - Surface simplification using quadric error metrics - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxStdSlim.cxx,v 1.4 1999/01/08 18:56:30 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxStdSlim.h" - -MxStdSlim::MxStdSlim(MxStdModel* m0) : heap(64) -{ - m = m0; - - // Externally visible variables - placement_policy = MX_PLACE_ENDPOINTS; - weighting_policy = MX_WEIGHT_AREA; - boundary_weight = 1000.0; - compactness_ratio = 1.0; - meshing_penalty = 1000.0; - local_validity_threshold = 0.0; - vertex_degree_limit = 24; - will_join_only = false; - - valid_faces = 0; - valid_verts = 0; - is_initialized = false; - - unsigned int i; - for (i = 0; i < m->face_count(); i++) - if (m->face_is_valid(i)) - valid_faces++; - for (i = 0; i < m->vert_count(); i++) - if (m->vertex_is_valid(i)) - valid_verts++; -} diff --git a/src/utils/xrQSlim/MxStdSlim.h b/src/utils/xrQSlim/MxStdSlim.h deleted file mode 100644 index 0393b820f6e..00000000000 --- a/src/utils/xrQSlim/MxStdSlim.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef MXSTDSLIM_INCLUDED // -*- C++ -*- -#define MXSTDSLIM_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Core simplification interface. The MxStdSlim class defines the - interface which all simplification classes conform to. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxStdSlim.h,v 1.4 1998/11/19 01:57:34 garland Exp $ - - ************************************************************************/ - -#include "MxStdModel.h" -#include "MxHeap.h" - -#define MX_PLACE_ENDPOINTS 0 -#define MX_PLACE_ENDORMID 1 -#define MX_PLACE_LINE 2 -#define MX_PLACE_OPTIMAL 3 - -#define MX_WEIGHT_UNIFORM 0 -#define MX_WEIGHT_AREA 1 -#define MX_WEIGHT_ANGLE 2 -#define MX_WEIGHT_AVERAGE 3 -#define MX_WEIGHT_AREA_AVG 4 -#define MX_WEIGHT_RAWNORMALS 5 - -#define EDGE_BASE_ERROR 1.f - -class MxStdSlim -{ -protected: - MxStdModel* m; - MxHeap heap; - -public: - unsigned int valid_verts; - unsigned int valid_faces; - bool is_initialized; - - int placement_policy; - int weighting_policy; - bool will_join_only; - - double boundary_weight; - double compactness_ratio; - double meshing_penalty; - double local_validity_threshold; - unsigned int vertex_degree_limit; - -public: - MxStdSlim(MxStdModel* m0); - - virtual void initialize() = 0; - virtual bool decimate(unsigned int, float max_error, void* cb_params = 0) = 0; - - MxStdModel& model() { return *m; } -public: - void (*contraction_callback)(const MxPairContraction&, float, void*); -}; - -// MXSTDSLIM_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxVec3.h b/src/utils/xrQSlim/MxVec3.h deleted file mode 100644 index 825a329fb61..00000000000 --- a/src/utils/xrQSlim/MxVec3.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MXVEC3_INCLUDED // -*- C++ -*- -#define MXVEC3_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 3D Vector class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxVec3.h,v 1.10 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "vec3.h" - -#ifdef MXGL_INCLUDED -inline void glV(const Vec3& v) { glVertex3d(v[X], v[Y], v[Z]); } -inline void glN(const Vec3& v) { glNormal3d(v[X], v[Y], v[Z]); } -inline void glC(const Vec3& v) { glColor3d(v[X], v[Y], v[Z]); } -#endif - -// MXVEC3_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxVec4.h b/src/utils/xrQSlim/MxVec4.h deleted file mode 100644 index e87a9813167..00000000000 --- a/src/utils/xrQSlim/MxVec4.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MXVEC4_INCLUDED // -*- C++ -*- -#define MXVEC4_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 4D Vector class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxVec4.h,v 1.11 2000/11/20 20:36:38 garland Exp $ - - ************************************************************************/ - -#include "vec4.h" - -#ifdef MXGL_INCLUDED -inline void glV(const Vec4& v) { glVertex4d(v[0], v[1], v[2], v[3]); } -inline void glC(const Vec4& v) { glColor4d(v[0], v[1], v[2], v[3]); } -#endif - -// MXVEC4_INCLUDED -#endif diff --git a/src/utils/xrQSlim/MxVector.h b/src/utils/xrQSlim/MxVector.h deleted file mode 100644 index 1232ef173bc..00000000000 --- a/src/utils/xrQSlim/MxVector.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef MXVECTOR_INCLUDED // -*- C++ -*- -#define MXVECTOR_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Generic n-dimensional vector class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: MxVector.h,v 1.9 1998/10/28 16:16:06 garland Exp $ - - ************************************************************************/ - -#ifdef __T -#undef __T -#endif - -#define __T float -#include "mixvops.h" - -#define __T double -#include "mixvops.h" - -//////////////////////////////////////////////////////////////////////// -// -// MxVBlock -- fixed-size vector class template -// -// The idea here is that we want a small collection of vector classes, -// {2,3,4}D say, and we want *zero* space overhead. No length fields, -// no vtables, just N numerical values. -// -template -class MxVBlock -{ -private: - T elt[N]; - -protected: - inline void copy(const MxVBlock& v) - { - for (unsigned int i = 0; i < N; i++) - elt[i] = v.elt[i]; - } - -public: - MxVBlock() {} - MxVBlock(const MxVBlock& v) { mxv_set(elt, v, N); } - MxVBlock(const T* v) { mxv_set(elt, v, N); } - inline unsigned int dim() const { return N; } - T& operator()(unsigned int i) - { - VERIFY(i < N); - return elt[i]; - } - T operator()(unsigned int i) const - { - VERIFY(i < N); - return elt[i]; - } - - operator T*() { return elt; } - operator const T*() const { return elt; } - // In-place arithmetic methods - // - inline MxVBlock& operator=(const MxVBlock& v) - { - mxv_set(elt, v, N); - return *this; - } - inline MxVBlock& operator+=(const MxVBlock& v) - { - mxv_addinto(elt, v, N); - return *this; - } - inline MxVBlock& operator-=(const MxVBlock& v) - { - mxv_subfrom(elt, v, N); - return *this; - } - inline MxVBlock& operator*=(T s) - { - mxv_scale(elt, s, N); - return *this; - } - inline MxVBlock& operator/=(T s) - { - mxv_invscale(elt, s, N); - return *this; - } - inline MxVBlock& negate() - { - mxv_neg(elt, N); - return *this; - } - - // Binary arithmetic methods - // - inline MxVBlock operator+(const MxVBlock& v) const - { - MxVBlock r; - mxv_add(r, elt, v, N); - return r; - } - inline MxVBlock operator-(const MxVBlock& v) const - { - MxVBlock r; - mxv_sub(r, elt, v, N); - return r; - } - inline MxVBlock operator*(T s) const - { - MxVBlock r; - mxv_scale(r, elt, s, N); - return r; - } - inline MxVBlock operator/(T s) const - { - MxVBlock r; - mxv_invscale(r, elt, s, N); - return r; - } - inline MxVBlock operator-() const - { - MxVBlock r; - mxv_neg(r, elt, N); - return r; - } - - inline T operator*(const MxVBlock& v) const { return mxv_dot(elt, v, N); } - // Comparison operators - inline bool operator==(const MxVBlock& v) const { return mxv_equal(elt, v, N); } - inline bool operator!=(const MxVBlock& v) const { return !mxv_equal(elt, v, N); } -}; - -//////////////////////////////////////////////////////////////////////// -// -// MxVector -- arbitrarily sized vectors -// -// With MxVector vectors, we're willing to pay a little per-vector space -// overhead to achieve greater flexibility without having to instantiate -// a template class for every single dimension we care about. -// - -#include "MxBlock.h" - -class MxVector : public MxBlock -{ -public: - MxVector(unsigned int n) : MxBlock(n) { mxv_set(*this, 0.0, dim()); } - MxVector(const MxVector& v) : MxBlock(v.length()) { copy(v); } - MxVector& operator=(const MxVector& v) - { - copy(v); - return *this; - } - MxVector& operator=(double d) - { - mxv_set(*this, d, dim()); - return *this; - } - - unsigned int dim() const { return length(); } - MxVector& operator+=(const MxVector& v) - { - mxv_addinto(*this, v, dim()); - return *this; - } - MxVector& operator-=(const MxVector& v) - { - mxv_subfrom(*this, v, dim()); - return *this; - } - MxVector& operator*=(double d) - { - mxv_scale(*this, d, dim()); - return *this; - } - MxVector& operator/=(double d) - { - mxv_invscale(*this, d, dim()); - return *this; - } - - double operator*(const MxVector& v) const { return mxv_dot(*this, v, dim()); } -}; - -// Convenient wrappers for mixvops functionality -// -inline double norm(const MxVector& v) { return mxv_norm(v, v.dim()); } -inline double norm2(const MxVector& v) { return mxv_dot(v, v, v.dim()); } -inline double unitize(MxVector& v) { return mxv_unitize(v, v.dim()); } -// MXVECTOR_INCLUDED -#endif diff --git a/src/utils/xrQSlim/geom3d.h b/src/utils/xrQSlim/geom3d.h deleted file mode 100644 index a7f9b515d00..00000000000 --- a/src/utils/xrQSlim/geom3d.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef GFXGEOM3D_INCLUDED -#define GFXGEOM3D_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - Handy 3D geometrical primitives - - $Id: geom3d.h,v 1.5 2002/05/20 15:25:46 garland Exp $ - - ************************************************************************/ - -// -// Computing properties of triangles -// - -template -inline Vec triangle_raw_normal(const Vec& v1, const Vec& v2, const Vec& v3) -{ - return cross(v2 - v1, v3 - v1); -} - -template -inline typename Vec::value_type triangle_area(const Vec& v1, const Vec& v2, const Vec& v3) -{ - return 0.5 * norm(triangle_raw_normal(v1, v2, v3)); -} - -template -inline Vec triangle_normal(const Vec& v1, const Vec& v2, const Vec& v3) -{ - Vec n = triangle_raw_normal(v1, v2, v3); - unitize(n); - return n; -} - -template -inline Plane triangle_plane(const Vec& v1, const Vec& v2, const Vec& v3) -{ - Vec n = triangle_normal(v1, v2, v3); - return Plane(n, -(n * v1)); -} - -template -inline Plane triangle_raw_plane(const Vec& v1, const Vec& v2, const Vec& v3) -{ - Vec n = triangle_raw_normal(v1, v2, v3); - return Plane(n, -(n * v1)); -} - -template -inline typename Vec::value_type triangle_compactness(const Vec& v1, const Vec& v2, const Vec& v3) -{ - const double FOUR_ROOT3 = 6.928203230275509; - - return FOUR_ROOT3 * triangle_area(v1, v2, v3) / (norm2(v2 - v1) + norm2(v3 - v2) + norm2(v1 - v3)); -} - -// -// Operations with axis-aligned bounding boxes -// - -template -void compute_bbox(Vec& min, Vec& max, const List& items) -{ - typedef typename List::const_iterator iterator; - - if (items.size() == 0) - min = max = 0; - else - min = max = items[0]; - - for (iterator i = items.begin(); i != items.end(); ++i) - { - const Vec& v = *i; - for (int j = 0; j < Vec::dim(); j++) - { - if (v[j] < min[j]) - min[j] = v[j]; - if (v[j] > max[j]) - max[j] = v[j]; - } - } -} - -template -bool is_inside_bbox(const Vec& p, const Vec& min, Vec& max) -{ - for (int i = 0; i < Vec::dim(); i++) - if (p[i] < min[i] || p[i] > max[i]) - return false; - - return true; -} - -template -Vec clamp_to_bbox(Vec p, const Vec& min, const Vec& max) -{ - for (int i = 0; i < Vec::dim(); i++) - { - if (p[i] < min[i]) - p[i] = min[i]; - else if (p[i] > max[i]) - p[i] = max[i]; - } - - return p; -} - -// GFXGEOM3D_INCLUDED -#endif diff --git a/src/utils/xrQSlim/mat2.cpp b/src/utils/xrQSlim/mat2.cpp deleted file mode 100644 index 82954979741..00000000000 --- a/src/utils/xrQSlim/mat2.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************ - - 2x2 Matrix class - - $Id: mat2.cxx,v 1.4 2001/02/08 21:28:53 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxDefines.h" -#include "mat2.h" - -Mat2 Mat2::I() { return Mat2(1, 0, 0, 1); } -Mat2& Mat2::diag(double d) -{ - row[0][0] = d; - row[0][1] = 0; - row[1][0] = 0; - row[1][1] = d; - - return *this; -} - -Mat2 operator*(const Mat2& n, const Mat2& m) -{ - Mat2 A; - int i, j; - - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - A(i, j) = n[i] * m.col(j); - - return A; -} - -double invert(Mat2& inv, const Mat2& m) -{ - double d = det(m); - - if (d == 0.0) - return 0.0; - - inv(0, 0) = m(1, 1) / d; - inv(0, 1) = -m(0, 1) / d; - inv(1, 0) = -m(1, 0) / d; - inv(1, 1) = m(0, 0) / d; - - return d; -} - -bool eigenvalues(const Mat2& M, Vec2& evals) -{ - double B = -M(0, 0) - M(1, 1); - double C = det(M); - - double dis = B * B - 4.0 * C; - if (dis < FEQ_EPS) - return false; - else - { - double s = _sqrt(dis); - - evals[0] = 0.5 * (-B + s); - evals[1] = 0.5 * (-B - s); - return true; - } -} - -bool eigenvectors(const Mat2& M, const Vec2& evals, Vec2 evecs[2]) -{ - evecs[0] = Vec2(-M(0, 1), M(0, 0) - evals[0]); - evecs[1] = Vec2(-M(0, 1), M(0, 0) - evals[1]); - - unitize(evecs[0]); - unitize(evecs[1]); - - return true; -} - -bool eigen(const Mat2& M, Vec2& evals, Vec2 evecs[2]) -{ - bool result = eigenvalues(M, evals); - if (result) - eigenvectors(M, evals, evecs); - return result; -} diff --git a/src/utils/xrQSlim/mat2.h b/src/utils/xrQSlim/mat2.h deleted file mode 100644 index 30708d930d5..00000000000 --- a/src/utils/xrQSlim/mat2.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef GFXMAT2_INCLUDED // -*- C++ -*- -#define GFXMAT2_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 2x2 Matrix class - - $Id: mat2.h,v 1.10 2001/11/19 16:07:42 garland Exp $ - - ************************************************************************/ - -#include "vec2.h" - -class Mat2 -{ -private: - Vec2 row[2]; - -public: - // Standard constructors - // - Mat2() { *this = 0.0; } - Mat2(double a, double b, double c, double d) - { - row[0][0] = a; - row[0][1] = b; - row[1][0] = c; - row[1][1] = d; - } - Mat2(const Vec2& r0, const Vec2& r1) - { - row[0] = r0; - row[1] = r1; - } - Mat2(const Mat2& m) { *this = m; } - // Descriptive interface - // - typedef double value_type; - typedef Vec2 vector_type; - typedef Mat2 inverse_type; - static int dim() { return 2; } - // Access methods note: A(i, j) == row i, col j - // - double& operator()(int i, int j) { return row[i][j]; } - double operator()(int i, int j) const { return row[i][j]; } - Vec2& operator[](int i) { return row[i]; } - const Vec2& operator[](int i) const { return row[i]; } - inline Vec2 col(int i) const { return Vec2(row[0][i], row[1][i]); } - operator double*() { return row[0]; } - operator const double*() { return row[0]; } - operator const double*() const { return row[0]; } - // Assignment methods - // - inline Mat2& operator=(const Mat2& m); - inline Mat2& operator=(double s); - - inline Mat2& operator+=(const Mat2& m); - inline Mat2& operator-=(const Mat2& m); - inline Mat2& operator*=(double s); - inline Mat2& operator/=(double s); - - // Construction of standard matrices - // - static Mat2 I(); - static Mat2 outer_product(const Vec2& u, const Vec2& v) - { - return Mat2(u[0] * v[0], u[0] * v[1], u[1] * v[0], u[1] * v[1]); - } - static Mat2 outer_product(const Vec2& u) { return outer_product(u, u); } - Mat2& diag(double d); - Mat2& ident() { return diag(1.0); } -}; - -//////////////////////////////////////////////////////////////////////// -// -// Method definitions -// - -inline Mat2& Mat2::operator=(const Mat2& m) -{ - row[0] = m[0]; - row[1] = m[1]; - return *this; -} - -inline Mat2& Mat2::operator=(double s) -{ - row[0] = s; - row[1] = s; - return *this; -} - -inline Mat2& Mat2::operator+=(const Mat2& m) -{ - row[0] += m.row[0]; - row[1] += m.row[1]; - return *this; -} - -inline Mat2& Mat2::operator-=(const Mat2& m) -{ - row[0] -= m.row[0]; - row[1] -= m.row[1]; - return *this; -} - -inline Mat2& Mat2::operator*=(double s) -{ - row[0] *= s; - row[1] *= s; - return *this; -} - -inline Mat2& Mat2::operator/=(double s) -{ - row[0] /= s; - row[1] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator definitions -// - -inline Mat2 operator+(const Mat2& n, const Mat2& m) { return Mat2(n[0] + m[0], n[1] + m[1]); } -inline Mat2 operator-(const Mat2& n, const Mat2& m) { return Mat2(n[0] - m[0], n[1] - m[1]); } -inline Mat2 operator-(const Mat2& m) { return Mat2(-m[0], -m[1]); } -inline Mat2 operator*(double s, const Mat2& m) { return Mat2(m[0] * s, m[1] * s); } -inline Mat2 operator*(const Mat2& m, double s) { return s * m; } -inline Mat2 operator/(const Mat2& m, double s) { return Mat2(m[0] / s, m[1] / s); } -inline Vec2 operator*(const Mat2& m, const Vec2& v) { return Vec2(m[0] * v, m[1] * v); } -extern Mat2 operator*(const Mat2& n, const Mat2& m); -/* -inline std::ostream &operator<<(std::ostream &out, const Mat2& M) - { return out << M[0] << std::endl << M[1]; } - -inline std::istream &operator>>(std::istream &in, Mat2& M) - { return in >> M[0] >> M[1]; } -*/ -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -inline double det(const Mat2& m) { return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0); } -inline double trace(const Mat2& m) { return m(0, 0) + m(1, 1); } -inline Mat2 transpose(const Mat2& m) { return Mat2(m.col(0), m.col(1)); } -inline Mat2 adjoint(const Mat2& m) { return Mat2(perp(m[1]), -perp(m[0])); } -extern double invert(Mat2& m_inv, const Mat2& m); - -extern bool eigenvalues(const Mat2&, Vec2& evals); -extern bool eigenvectors(const Mat2&, const Vec2& evals, Vec2 evecs[2]); -extern bool eigen(const Mat2&, Vec2& evals, Vec2 evecs[2]); - -// GFXMAT2_INCLUDED -#endif diff --git a/src/utils/xrQSlim/mat3.cpp b/src/utils/xrQSlim/mat3.cpp deleted file mode 100644 index 362c1f1f4f5..00000000000 --- a/src/utils/xrQSlim/mat3.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************ - - 3x3 Matrix class - - $Id: mat3.cxx,v 1.3 2001/11/19 16:08:30 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "mat3.h" - -Mat3 Mat3::I() { return Mat3(Vec3(1, 0, 0), Vec3(0, 1, 0), Vec3(0, 0, 1)); } -Mat3& Mat3::diag(double d) -{ - *this = 0.0; - row[0][0] = row[1][1] = row[2][2] = d; - return *this; -} - -Mat3 diag(const Vec3& v) { return Mat3(Vec3(v[0], 0, 0), Vec3(0, v[1], 0), Vec3(0, 0, v[2])); } -Mat3 Mat3::outer_product(const Vec3& v) -{ - Mat3 A; - double x = v[0], y = v[1], z = v[2]; - - A(0, 0) = x * x; - A(0, 1) = x * y; - A(0, 2) = x * z; - A(1, 0) = A(0, 1); - A(1, 1) = y * y; - A(1, 2) = y * z; - A(2, 0) = A(0, 2); - A(2, 1) = A(1, 2); - A(2, 2) = z * z; - - return A; -} - -Mat3 Mat3::outer_product(const Vec3& u, const Vec3& v) -{ - Mat3 A; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - A(i, j) = u[i] * v[j]; - - return A; -} - -Mat3 operator*(const Mat3& n, const Mat3& m) -{ - Mat3 A; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - A(i, j) = n[i] * m.col(j); - - return A; -} - -Mat3 adjoint(const Mat3& m) { return Mat3(m[1] ^ m[2], m[2] ^ m[0], m[0] ^ m[1]); } -double invert(Mat3& inv, const Mat3& m) -{ - Mat3 A = adjoint(m); - double d = A[0] * m[0]; - - if (d == 0.0) - return 0.0; - - inv = transpose(A) / d; - return d; -} diff --git a/src/utils/xrQSlim/mat3.h b/src/utils/xrQSlim/mat3.h deleted file mode 100644 index b8c0903d5c4..00000000000 --- a/src/utils/xrQSlim/mat3.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef GFXMAT3_INCLUDED // -*- C++ -*- -#define GFXMAT3_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 3x3 Matrix class - - $Id: mat3.h,v 1.9 2001/11/19 16:07:42 garland Exp $ - - ************************************************************************/ - -#include "vec3.h" - -class Mat3 -{ -private: - Vec3 row[3]; - -public: - // Standard constructors - // - Mat3() { *this = 0.0; } - Mat3(const Vec3& r0, const Vec3& r1, const Vec3& r2) - { - row[0] = r0; - row[1] = r1; - row[2] = r2; - } - Mat3(const Mat3& m) { *this = m; } - // Descriptive interface - // - typedef double value_type; - typedef Vec3 vector_type; - typedef Mat3 inverse_type; - static int dim() { return 3; } - // Access methods - // - double& operator()(int i, int j) { return row[i][j]; } - double operator()(int i, int j) const { return row[i][j]; } - Vec3& operator[](int i) { return row[i]; } - const Vec3& operator[](int i) const { return row[i]; } - inline Vec3 col(int i) const { return Vec3(row[0][i], row[1][i], row[2][i]); } - operator double*() { return row[0]; } - operator const double*() { return row[0]; } - operator const double*() const { return row[0]; } - // Assignment methods - // - inline Mat3& operator=(const Mat3& m); - inline Mat3& operator=(double s); - - inline Mat3& operator+=(const Mat3& m); - inline Mat3& operator-=(const Mat3& m); - inline Mat3& operator*=(double s); - inline Mat3& operator/=(double s); - - // Construction of standard matrices - // - static Mat3 I(); - static Mat3 outer_product(const Vec3& u, const Vec3& v); - static Mat3 outer_product(const Vec3& v); - - Mat3& diag(double d); - Mat3& ident() { return diag(1.0); } -}; - -//////////////////////////////////////////////////////////////////////// -// -// Methods definitions -// - -inline Mat3& Mat3::operator=(const Mat3& m) -{ - row[0] = m[0]; - row[1] = m[1]; - row[2] = m[2]; - return *this; -} - -inline Mat3& Mat3::operator=(double s) -{ - row[0] = s; - row[1] = s; - row[2] = s; - return *this; -} - -inline Mat3& Mat3::operator+=(const Mat3& m) -{ - row[0] += m[0]; - row[1] += m[1]; - row[2] += m[2]; - return *this; -} - -inline Mat3& Mat3::operator-=(const Mat3& m) -{ - row[0] -= m[0]; - row[1] -= m[1]; - row[2] -= m[2]; - return *this; -} - -inline Mat3& Mat3::operator*=(double s) -{ - row[0] *= s; - row[1] *= s; - row[2] *= s; - return *this; -} - -inline Mat3& Mat3::operator/=(double s) -{ - row[0] /= s; - row[1] /= s; - row[2] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator definitions -// - -inline Mat3 operator+(const Mat3& n, const Mat3& m) { return Mat3(n[0] + m[0], n[1] + m[1], n[2] + m[2]); } -inline Mat3 operator-(const Mat3& n, const Mat3& m) { return Mat3(n[0] - m[0], n[1] - m[1], n[2] - m[2]); } -inline Mat3 operator-(const Mat3& m) { return Mat3(-m[0], -m[1], -m[2]); } -inline Mat3 operator*(double s, const Mat3& m) { return Mat3(m[0] * s, m[1] * s, m[2] * s); } -inline Mat3 operator*(const Mat3& m, double s) { return s * m; } -inline Mat3 operator/(const Mat3& m, double s) { return Mat3(m[0] / s, m[1] / s, m[2] / s); } -inline Vec3 operator*(const Mat3& m, const Vec3& v) { return Vec3(m[0] * v, m[1] * v, m[2] * v); } -extern Mat3 operator*(const Mat3& n, const Mat3& m); -/* -inline std::ostream &operator<<(std::ostream &out, const Mat3& M) - { return out << M[0] << std::endl << M[1] << std::endl << M[2]; } - -inline std::istream &operator>>(std::istream &in, Mat3& M) - { return in >> M[0] >> M[1] >> M[2]; } -*/ -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -inline double det(const Mat3& m) { return m[0] * (m[1] ^ m[2]); } -inline double trace(const Mat3& m) { return m(0, 0) + m(1, 1) + m(2, 2); } -inline Mat3 transpose(const Mat3& m) { return Mat3(m.col(0), m.col(1), m.col(2)); } -extern Mat3 adjoint(const Mat3& m); - -extern double invert(Mat3& m_inv, const Mat3& m); - -inline Mat3 row_extend(const Vec3& v) { return Mat3(v, v, v); } -extern Mat3 diag(const Vec3& v); - -extern bool eigen(const Mat3& m, Vec3& eig_vals, Vec3 eig_vecs[3]); - -// GFXMAT3_INCLUDED -#endif diff --git a/src/utils/xrQSlim/mat4.cpp b/src/utils/xrQSlim/mat4.cpp deleted file mode 100644 index 41515cf080a..00000000000 --- a/src/utils/xrQSlim/mat4.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/************************************************************************ - - 4x4 Matrix class - - $Id: mat4.cxx,v 1.4 2000/12/04 06:18:37 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "mat4.h" -#include "xrCommon/math_funcs_inline.h" - -Mat4 Mat4::I() { return Mat4(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), Vec4(0, 0, 0, 1)); } -Mat4 translation_matrix(const Vec3& d) -{ - return Mat4(Vec4(1, 0, 0, d[0]), Vec4(0, 1, 0, d[1]), Vec4(0, 0, 1, d[2]), Vec4(0, 0, 0, 1)); -} - -Mat4 scaling_matrix(const Vec3& s) -{ - return Mat4(Vec4(s[0], 0, 0, 0), Vec4(0, s[1], 0, 0), Vec4(0, 0, s[2], 0), Vec4(0, 0, 0, 1)); -} - -Mat4 rotation_matrix_rad(double theta, const Vec3& axis) -{ - double c = _cos(theta), s = _sin(theta), xx = axis[0] * axis[0], yy = axis[1] * axis[1], zz = axis[2] * axis[2], - xy = axis[0] * axis[1], yz = axis[1] * axis[2], xz = axis[0] * axis[2]; - - double xs = axis[0] * s, ys = axis[1] * s, zs = axis[2] * s; - - Mat4 M; - M(0, 0) = xx * (1 - c) + c; - M(0, 1) = xy * (1 - c) - zs; - M(0, 2) = xz * (1 - c) + ys; - M(0, 3) = 0; - M(1, 0) = xy * (1 - c) + zs; - M(1, 1) = yy * (1 - c) + c; - M(1, 2) = yz * (1 - c) - xs; - M(1, 3) = 0; - M(2, 0) = xz * (1 - c) - ys; - M(2, 1) = yz * (1 - c) + xs; - M(2, 2) = zz * (1 - c) + c; - M(2, 3) = 0; - M(3, 0) = 0; - M(3, 1) = 0; - M(3, 2) = 0; - M(3, 3) = 1; - - return M; -} - -Mat4 perspective_matrix(double fovy, double aspect, double zmin, double zmax) -{ - double A, B; - Mat4 M; - - if (zmax == 0.0) - { - A = B = 1.0; - } - else - { - A = (zmax + zmin) / (zmin - zmax); - B = (2 * zmax * zmin) / (zmin - zmax); - } - - double f = 1.0 / tan(fovy * M_PI / 180.0 / 2.0); - M(0, 0) = f / aspect; - M(1, 1) = f; - M(2, 2) = A; - M(2, 3) = B; - M(3, 2) = -1; - M(3, 3) = 0; - - return M; -} - -Mat4 lookat_matrix(const Vec3& from, const Vec3& at, const Vec3& v_up) -{ - Vec3 up = v_up; - unitize(up); - Vec3 f = at - from; - unitize(f); - - Vec3 s = f ^ up; - Vec3 u = s ^ f; - - // NOTE: These steps are left out of the GL man page!! - unitize(s); - unitize(u); - - Mat4 M(Vec4(s, 0), Vec4(u, 0), Vec4(-f, 0), Vec4(0, 0, 0, 1)); - - return M * translation_matrix(-from); -} - -Mat4 viewport_matrix(double w, double h) -{ - return scaling_matrix(Vec3(w / 2.0, -h / 2.0, 1)) * translation_matrix(Vec3(1, -1, 0)); -} - -Mat4 operator*(const Mat4& n, const Mat4& m) -{ - Mat4 A; - int i, j; - - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) - A(i, j) = n[i] * m.col(j); - - return A; -} - -Mat4 adjoint(const Mat4& m) -{ - Mat4 A; - - A[0] = cross(m[1], m[2], m[3]); - A[1] = cross(-m[0], m[2], m[3]); - A[2] = cross(m[0], m[1], m[3]); - A[3] = cross(-m[0], m[1], m[2]); - - return A; -} - -double invert_cramer(Mat4& inv, const Mat4& m) -{ - Mat4 A = adjoint(m); - double d = A[0] * m[0]; - - if (d == 0.0) - return 0.0; - - inv = transpose(A) / d; - return d; -} - -// Matrix inversion code for 4x4 matrices using Gaussian elimination -// with partial pivoting. This is a specialized version of a -// procedure originally due to Paul Heckbert . -// -// Returns determinant of A, and B=inverse(A) -// If matrix A is singular, returns 0 and leaves trash in B. -// -#define SWAP(a, b, t)\ - {\ - t = a;\ - a = b;\ - b = t;\ - } -double invert(Mat4& B, const Mat4& m) -{ - Mat4 A = m; - int i, j = 0, k; - double max, t, det, pivot; - - /*---------- forward elimination ----------*/ - - for (i = 0; i < 4; i++) /* put identity matrix in B */ - for (j = 0; j < 4; j++) - B(i, j) = (double)(i == j); - - det = 1.0; - for (i = 0; i < 4; i++) - { /* eliminate in column i, below diag */ - max = -1.; - for (k = i; k < 4; k++) /* find pivot for column i */ - if (_abs(A(k, i)) > max) - { - max = _abs(A(k, i)); - j = k; - } - if (max <= 0.) - return 0.; /* if no nonzero pivot, PUNT */ - if (j != i) - { /* swap rows i and j */ - for (k = i; k < 4; k++) - SWAP(A(i, k), A(j, k), t); - for (k = 0; k < 4; k++) - SWAP(B(i, k), B(j, k), t); - det = -det; - } - pivot = A(i, i); - det *= pivot; - for (k = i + 1; k < 4; k++) /* only do elems to right of pivot */ - A(i, k) /= pivot; - for (k = 0; k < 4; k++) - B(i, k) /= pivot; - /* we know that A(i, i) will be set to 1, so don't bother to do it */ - - for (j = i + 1; j < 4; j++) - { /* eliminate in rows below i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = i + 1; k < 4; k++) /* subtract scaled row i from row j */ - A(j, k) -= A(i, k) * t; /* (ignore k<=i, we know they're 0) */ - for (k = 0; k < 4; k++) - B(j, k) -= B(i, k) * t; - } - } - - /*---------- backward elimination ----------*/ - - for (i = 4 - 1; i > 0; i--) - { /* eliminate in column i, above diag */ - for (j = 0; j < i; j++) - { /* eliminate in rows above i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = 0; k < 4; k++) /* subtract scaled row i from row j */ - B(j, k) -= B(i, k) * t; - } - } - - return det; -} diff --git a/src/utils/xrQSlim/mat4.h b/src/utils/xrQSlim/mat4.h deleted file mode 100644 index 1f2db628062..00000000000 --- a/src/utils/xrQSlim/mat4.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef GFXMAT4_INCLUDED // -*- C++ -*- -#define GFXMAT4_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 4x4 Matrix class - - $Id: mat4.h,v 1.10 2001/11/19 16:07:42 garland Exp $ - - ************************************************************************/ - -#include "vec4.h" - -class Mat4 -{ -private: - Vec4 row[4]; - -public: - // Standard constructors - // - Mat4() { *this = 0.0; } - Mat4(const Vec4& r0, const Vec4& r1, const Vec4& r2, const Vec4& r3) - { - row[0] = r0; - row[1] = r1; - row[2] = r2; - row[3] = r3; - } - Mat4(const Mat4& m) { *this = m; } - // Descriptive interface - // - typedef double value_type; - typedef Vec4 vector_type; - typedef Mat4 inverse_type; - static int dim() { return 4; } - // Access methods - // - double& operator()(int i, int j) { return row[i][j]; } - double operator()(int i, int j) const { return row[i][j]; } - Vec4& operator[](int i) { return row[i]; } - const Vec4& operator[](int i) const { return row[i]; } - inline Vec4 col(int i) const { return Vec4(row[0][i], row[1][i], row[2][i], row[3][i]); } - operator double*() { return row[0]; } - operator const double*() { return row[0]; } - operator const double*() const { return row[0]; } - // Assignment methods - // - inline Mat4& operator=(const Mat4& m); - inline Mat4& operator=(double s); - - inline Mat4& operator+=(const Mat4& m); - inline Mat4& operator-=(const Mat4& m); - inline Mat4& operator*=(double s); - inline Mat4& operator/=(double s); - - static Mat4 I(); -}; - -//////////////////////////////////////////////////////////////////////// -// -// Method definitions -// - -inline Mat4& Mat4::operator=(const Mat4& m) -{ - row[0] = m[0]; - row[1] = m[1]; - row[2] = m[2]; - row[3] = m[3]; - return *this; -} - -inline Mat4& Mat4::operator=(double s) -{ - row[0] = s; - row[1] = s; - row[2] = s; - row[3] = s; - return *this; -} - -inline Mat4& Mat4::operator+=(const Mat4& m) -{ - row[0] += m[0]; - row[1] += m[1]; - row[2] += m[2]; - row[3] += m[3]; - return *this; -} - -inline Mat4& Mat4::operator-=(const Mat4& m) -{ - row[0] -= m[0]; - row[1] -= m[1]; - row[2] -= m[2]; - row[3] -= m[3]; - return *this; -} - -inline Mat4& Mat4::operator*=(double s) -{ - row[0] *= s; - row[1] *= s; - row[2] *= s; - row[3] *= s; - return *this; -} - -inline Mat4& Mat4::operator/=(double s) -{ - row[0] /= s; - row[1] /= s; - row[2] /= s; - row[3] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator definitions -// - -inline Mat4 operator+(const Mat4& n, const Mat4& m) { return Mat4(n[0] + m[0], n[1] + m[1], n[2] + m[2], n[3] + m[3]); } -inline Mat4 operator-(const Mat4& n, const Mat4& m) { return Mat4(n[0] - m[0], n[1] - m[1], n[2] - m[2], n[3] - m[3]); } -inline Mat4 operator-(const Mat4& n) { return Mat4(-n[0], -n[1], -n[2], -n[3]); } -inline Mat4 operator*(double s, const Mat4& m) { return Mat4(m[0] * s, m[1] * s, m[2] * s, m[3] * s); } -inline Mat4 operator*(const Mat4& m, double s) { return s * m; } -inline Mat4 operator/(const Mat4& m, double s) { return Mat4(m[0] / s, m[1] / s, m[2] / s, m[3] / s); } -inline Vec4 operator*(const Mat4& m, const Vec4& v) { return Vec4(m[0] * v, m[1] * v, m[2] * v, m[3] * v); } -extern Mat4 operator*(const Mat4& n, const Mat4& m); - -// -// Transform a homogeneous 3-vector and reproject into normal 3-space -// -inline Vec3 operator*(const Mat4& m, const Vec3& v) -{ - Vec4 u = Vec4(v, 1); - double w = m[3] * u; - - if (w == 0.0) - return Vec3(m[0] * u, m[1] * u, m[2] * u); - else - return Vec3(m[0] * u / w, m[1] * u / w, m[2] * u / w); -} -/* -inline std::ostream &operator<<(std::ostream &out, const Mat4& M) - { return out<>(std::istream &in, Mat4& M) - { return in >> M[0] >> M[1] >> M[2] >> M[3]; } -*/ -//////////////////////////////////////////////////////////////////////// -// -// Transformations -// - -extern Mat4 translation_matrix(const Vec3& delta); - -extern Mat4 scaling_matrix(const Vec3& scale); - -extern Mat4 rotation_matrix_rad(double theta, const Vec3& axis); - -inline Mat4 rotation_matrix_deg(double theta, const Vec3& axis) -{ - return rotation_matrix_rad(theta * M_PI / 180.0, axis); -} - -extern Mat4 perspective_matrix(double fovy, double aspect, double zmin = 0.0, double zmax = 0.0); - -extern Mat4 lookat_matrix(const Vec3& from, const Vec3& at, const Vec3& up); - -extern Mat4 viewport_matrix(double w, double h); - -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -inline double det(const Mat4& m) { return m[0] * cross(m[1], m[2], m[3]); } -inline double trace(const Mat4& m) { return m(0, 0) + m(1, 1) + m(2, 2) + m(3, 3); } -inline Mat4 transpose(const Mat4& m) { return Mat4(m.col(0), m.col(1), m.col(2), m.col(3)); } -extern Mat4 adjoint(const Mat4& m); -extern double invert(Mat4& m_inv, const Mat4& m); -extern double invert_cramer(Mat4& m_inv, const Mat4& m); - -extern bool eigen(const Mat4& m, Vec4& eig_vals, Vec4 eig_vecs[4]); - -// GFXMAT4_INCLUDED -#endif diff --git a/src/utils/xrQSlim/mixmops.cpp b/src/utils/xrQSlim/mixmops.cpp deleted file mode 100644 index f3ff1a0b65e..00000000000 --- a/src/utils/xrQSlim/mixmops.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/************************************************************************ - - NxN Matrix class - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: mixmops.cxx,v 1.7 1998/10/26 21:09:38 garland Exp $ - - ************************************************************************/ -#include "stdafx.h" -#pragma hdrstop - -#include "MxMatrix.h" - -// This section originally from Paul's matrix library. - -#define SWAP(a, b, t)\ - {\ - t = a;\ - a = b;\ - b = t;\ - } -#define A(i, j) mxm_ref(_a, i, j, N) -#define B(i, j) mxm_ref(_b, i, j, N) - -// Solve nxn system Ax=b. -// Leaves solution x in b, and destroys original A and b vectors. -// Return value is determinant of A. -// If system is singular, returns 0 and leaves trash in b -// -// Uses Gaussian elimination with partial pivoting. -// -static double internal_solve(double* _a, double* b, const int N) -{ - int i, j = 0, k; - double max, t, det, sum, pivot; - - /*---------- forward elimination ----------*/ - - det = 1.0; - for (i = 0; i < N; i++) - { /* eliminate in column i */ - max = -1.0; - for (k = i; k < N; k++) /* find pivot for column i */ - if (_abs(A(k, i)) > max) - { - max = _abs(A(k, i)); - j = k; - } - if (max <= 0.) - return 0.0; /* if no nonzero pivot, PUNT */ - if (j != i) - { /* swap rows i and j */ - for (k = i; k < N; k++) - SWAP(A(i, k), A(j, k), t); - det = -det; - SWAP(b[i], b[j], t); /* swap elements of column vector */ - } - pivot = A(i, i); - det *= pivot; - for (k = i + 1; k < N; k++) /* only do elems to right of pivot */ - A(i, k) /= pivot; - - /* we know that A(i, i) will be set to 1, so don't bother to do it */ - b[i] /= pivot; - for (j = i + 1; j < N; j++) - { /* eliminate in rows below i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = i + 1; k < N; k++) /* subtract scaled row i from row j */ - A(j, k) -= A(i, k) * t; /* (ignore k<=i, we know they're 0) */ - b[j] -= b[i] * t; - } - } - - /*---------- back substitution ----------*/ - - for (i = N - 1; i >= 0; i--) - { /* solve for x[i] (put it in b[i]) */ - sum = b[i]; - for (k = i + 1; k < N; k++) /* really A(i, k)*x[k] */ - sum -= A(i, k) * b[k]; - b[i] = sum; - } - - return det; -} - -// Returns determinant of a, and b=a inverse. -// If matrix is singular, returns 0 and leaves trash in b. -// -// Uses Gaussian elimination with partial pivoting. -// -static double internal_invert(double* _a, double* _b, const int N) -{ - unsigned int i, j = 0, k; - double max, t, det, pivot; - - /*---------- forward elimination ----------*/ - - for (i = 0; i < (unsigned int)N; i++) /* put identity matrix in B */ - for (j = 0; j < (unsigned int)N; j++) - B(i, j) = (double)(i == j); - - det = 1.0; - for (i = 0; i < (unsigned int)N; i++) - { /* eliminate in column i, below diag */ - max = -1.; - for (k = i; k < (unsigned int)N; k++) /* find pivot for column i */ - if (_abs(A(k, i)) > max) - { - max = _abs(A(k, i)); - j = k; - } - if (max <= 0.) - return 0.; /* if no nonzero pivot, PUNT */ - if (j != i) - { /* swap rows i and j */ - for (k = i; k < (unsigned int)N; k++) - SWAP(A(i, k), A(j, k), t); - for (k = 0; k < (unsigned int)N; k++) - SWAP(B(i, k), B(j, k), t); - det = -det; - } - pivot = A(i, i); - det *= pivot; - for (k = i + 1; k < (unsigned int)N; k++) /* only do elems to right of pivot */ - A(i, k) /= pivot; - for (k = 0; k < (unsigned int)N; k++) - B(i, k) /= pivot; - /* we know that A(i, i) will be set to 1, so don't bother to do it */ - - for (j = i + 1; j < (unsigned int)N; j++) - { /* eliminate in rows below i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = i + 1; k < (unsigned int)N; k++) /* subtract scaled row i from row j */ - A(j, k) -= A(i, k) * t; /* (ignore k<=i, we know they're 0) */ - for (k = 0; k < (unsigned int)N; k++) - B(j, k) -= B(i, k) * t; - } - } - - /*---------- backward elimination ----------*/ - - for (i = N - 1; i > 0; i--) - { /* eliminate in column i, above diag */ - for (j = 0; j < i; j++) - { /* eliminate in rows above i */ - t = A(j, i); /* we're gonna zero this guy */ - for (k = 0; k < (unsigned int)N; k++) /* subtract scaled row i from row j */ - B(j, k) -= B(i, k) * t; - } - } - - return det; -} - -#undef A -#undef B -#undef SWAP - -float mxm_invert(float* r, const float* a, const int N) -{ - mxm_local_block(a2, double, N); - mxm_local_block(r2, double, N); - - unsigned int i; - for (i = 0; i < (unsigned int)N * N; i++) - a2[i] = a[i]; - float det = (float)internal_invert(a2, r2, N); - for (i = 0; i < (unsigned int)N * N; i++) - r[i] = (float)r2[i]; - - mxm_free_local(a2); - mxm_free_local(r2); - return det; -} - -double mxm_invert(double* r, const double* a, const int N) -{ - mxm_local_block(a2, double, N); - mxm_set(a2, a, N); - double det = internal_invert(a2, r, N); - mxm_free_local(a2); - return det; -} - -double mxm_solve(double* x, const double* A, const double* b, const int N) -{ - mxm_local_block(a2, double, N); - mxm_set(a2, A, N); - mxv_set(x, b, N); - double det = internal_solve(a2, x, N); - mxm_free_local(a2); - return det; -} - -// Originally based on public domain code by -// which can be found at http://lib.stat.cmu.edu/general/ajay -// -// The factorization is valid as long as the returned nullity == 0 -// U contains the upper triangular factor itself. -// -int mxm_cholesky(double* U, const double* A, const int N) -{ - double sum; - - int nullity = 0; - mxm_set(U, 0.0, N); - - for (int i = 0; i < N; i++) - { - /* First compute U[i][i] */ - sum = mxm_ref(A, i, i, N); - - for (int j = 0; j <= (i - 1); j++) - sum -= mxm_ref(U, j, i, N) * mxm_ref(U, j, i, N); - - if (sum > 0) - { - mxm_ref(U, i, i, N) = _sqrt(sum); - - /* Now find elements U[i][k], k > i. */ - for (int k = (i + 1); k < N; k++) - { - sum = mxm_ref(A, i, k, N); - - for (int j = 0; j <= (i - 1); j++) - sum -= mxm_ref(U, j, i, N) * mxm_ref(U, j, k, N); - - mxm_ref(U, i, k, N) = sum / mxm_ref(U, i, i, N); - } - } - else - { - for (int k = i; k < N; k++) - mxm_ref(U, i, k, N) = 0.0; - nullity++; - } - } - - return nullity; -} diff --git a/src/utils/xrQSlim/mixmops.h b/src/utils/xrQSlim/mixmops.h deleted file mode 100644 index 1405eaa096a..00000000000 --- a/src/utils/xrQSlim/mixmops.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef MIXMOPS_INCLUDED // -*- C++ -*- -#define MIXMOPS_INCLUDED // -#endif // WARNING: Multiple inclusions allowed - -/************************************************************************ - - Low-level matrix math operations. - - This header file is intended for internal library use only. You should - understand what's going on in here before trying to use it yourself. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: mixmops.h,v 1.8 1999/11/30 02:39:38 garland Exp $ - - ************************************************************************/ - -#ifdef MIXVOPS_DEFAULT_DIM -#define __DIM const int N = MIXVOPS_DEFAULT_DIM -#else -#define __DIM const int N -#endif - -#ifndef __T -#define __T double -#endif - -#define forall(i, N) for (unsigned int i = 0; i < (unsigned int)N * N; i++) - -#define def3(name, op)\ - inline __T* name(__T* r, const __T* a, const __T* b, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def2(name, op)\ - inline __T* name(__T* r, const __T* a, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def1(name, op)\ - inline __T* name(__T* r, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def2s(name, op)\ - inline __T* name(__T* r, const __T* a, __T d, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def1s(name, op)\ - inline __T* name(__T* r, __T d, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -def3(mxm_add, r[i] = a[i] + b[i]) -def3(mxm_sub, r[i] = a[i] - b[i]) -def2(mxm_addinto, r[i] += a[i]) -def2(mxm_subfrom, r[i] -= a[i]) -def2(mxm_set, r[i] = a[i]) -def1(mxm_neg, r[i] = -r[i]) -def2(mxm_neg, r[i] = -a[i]) -def1s(mxm_set, r[i] = d) -def1s(mxm_scale, r[i] *= d) -def1s(mxm_invscale, r[i] /= d) -def2s(mxm_scale, r[i] = a[i] * d) -def2s(mxm_invscale, r[i] = a[i] / d) - -inline __T& mxm_ref(__T* A, unsigned int i, unsigned int j, __DIM) -{ return A[i * N + j]; } -inline __T mxm_ref(const __T* A, unsigned int i, unsigned int j, __DIM) { return A[i * N + j]; } -inline __T* mxm_row(__T* A, unsigned int i, __DIM) { return A + i * N; } -inline const __T* mxm_row(const __T* A, unsigned int i, __DIM) { return A + i * N; } -inline __T* mxm_identity(__T* A, __DIM) -{ - mxm_set(A, 0.0, N); - for (unsigned int i = 0; i < (unsigned int)N; i++) - mxm_ref(A, i, i, N) = 1.0; - return A; -} - -inline __T* mxm_xform(__T* r, const __T* A, const __T* x, __DIM) -{ - const __T* a = A; - for (unsigned int i = 0; i < (unsigned int)N; i++) - { - r[i] = 0.0; - for (unsigned int j = 0; j < (unsigned int)N; j++) - r[i] += (*a++) * x[j]; - } - return r; -} - -//////////////////////////////////////////////////////////////////////// -// The following couple of procedures are fairly straightforward but -// rather inefficient. mxm_ref() provides an easy way to access the -// (i,j) element of the matrix, but it's inefficient for looping over -// all the elements. -// -inline __T* mxm_outerprod(__T* A, const __T* u, const __T* v, __DIM) -{ - for (unsigned int i = 0; i < (unsigned int)N; i++) - for (unsigned int j = 0; j < (unsigned int)N; j++) - mxm_ref(A, i, j, N) = u[i] * v[j]; - return A; -} - -inline __T* mxm_mul(__T* r, const __T* a, const __T* b, __DIM) -{ - mxm_set(r, 0.0, N); - - for (unsigned int i = 0; i < (unsigned int)N; i++) - for (unsigned int j = 0; j < (unsigned int)N; j++) - { - for (unsigned int k = 0; k < (unsigned int)N; k++) - mxm_ref(r, i, j, N) += mxm_ref(a, i, k, N) * mxm_ref(b, k, j, N); - } - - return r; -} - -// -// Only actually implemented for double (and maybe float). -// -extern __T mxm_invert(__T* r, const __T* a, __DIM); -extern __T mxm_solve(__T* x, const __T* A, const __T* b, __DIM); -extern int mxm_cholesky(__T* c, const __T* a, __DIM); -/* -inline ostream& mxm_write(ostream& out, const __T *a, __DIM) -{ - for(unsigned int i=0; i -#define mxm_local_block(a, T, N) T* a = (T*)alloca(sizeof(T) * (N) * (N)) -#define mxm_free_local(a) -#else -#define mxm_local_block(a, T, N) T* a = xr_alloc(sizeof(T) * (N) * (N)) -#define mxm_free_local(a) xr_free(a) -#endif -#endif -#endif - -#undef __T -#undef __DIM -#undef forall -#undef def3 -#undef def2 -#undef def1 -#undef def2s -#undef def1s - -// MIXMOPS_INCLUDED diff --git a/src/utils/xrQSlim/mixvops.h b/src/utils/xrQSlim/mixvops.h deleted file mode 100644 index f52c12e3514..00000000000 --- a/src/utils/xrQSlim/mixvops.h +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef MIXVOPS_INCLUDED // -*- C++ -*- -#define MIXVOPS_INCLUDED // -#endif // WARNING: Multiple inclusions allowed - -#include "xrCommon/math_funcs_inline.h" -#include "xrCore/_std_extensions.h" - -/************************************************************************ - - Low-level vector math operations. - - This header file is intended for internal library use only. You should - understand what's going on in here before trying to use it yourself. - - Using the magic __LINKAGE macro, this file can be compiled either as a - set of templated functions, or as a series of inline functions whose - argument type is determined by the __T macro. My rationale for this is - that some compilers either don't support templated functions or are - incapable of inlining them. - - PUBLIC APOLOGY: I really do apologize for the ugliness of the code in - this header. In order to accommodate various types of compilation and - to avoid lots of typing, I've made pretty heavy use of macros. - - Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - - $Id: mixvops.h,v 1.12 1999/11/30 02:39:02 garland Exp $ - - ************************************************************************/ - -#include "MxDefines.h" - -#ifdef MIXVOPS_DEFAULT_DIM -#define __DIM const int N = MIXVOPS_DEFAULT_DIM -#else -#define __DIM const int N -#endif - -#if !defined(MIXVOPS_USE_TEMPLATES) -#ifndef __T -#define __T double -#endif -#define __LINKAGE inline -#else -#ifdef __T -#undef __T -#endif -#define __LINKAGE\ - template \ - inline -#endif - -#define __OP __LINKAGE __T* - -#define forall(i, N) for (unsigned int i = 0; i < (unsigned int)N; i++) - -#define def3(name, op)\ - __OP name(__T* r, const __T* u, const __T* v, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def2(name, op)\ - __OP name(__T* r, const __T* u, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def1(name, op)\ - __OP name(__T* r, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def2s(name, op)\ - __OP name(__T* r, const __T* u, __T d, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -#define def1s(name, op)\ - __OP name(__T* r, __T d, __DIM)\ - {\ - forall(i, N) op;\ - return r;\ - } - -def3(mxv_add, r[i] = u[i] + v[i]) -def3(mxv_sub, r[i] = u[i] - v[i]) -def3(mxv_mul, r[i] = u[i] * v[i]) -def3(mxv_div, r[i] = u[i] / v[i]) -def3(mxv_min, r[i] = u[i] < v[i] ? u[i] : v[i];) -def3(mxv_max, r[i] = u[i] > v[i] ? u[i] : v[i];) - -def2(mxv_addinto, r[i] += u[i]) -def2(mxv_subfrom, r[i] -= u[i]) -def2(mxv_mulby, r[i] *= u[i]) -def2(mxv_divby, r[i] /= u[i]) - -def2(mxv_set, r[i] = u[i]) -def1(mxv_neg, r[i] = -r[i]) -def2(mxv_neg, r[i] = -u[i]) - -def1s(mxv_set, r[i] = d) -def1s(mxv_scale, r[i] *= d) -def1s(mxv_invscale, r[i] /= d) -def2s(mxv_scale, r[i] = u[i] * d) -def2s(mxv_invscale, r[i] = u[i] / d) - -__LINKAGE __T mxv_dot(const __T* u, const __T* v, __DIM) -{ - __T dot = 0.0; - forall(i, N) dot += u[i] * v[i]; - return dot; -} - -__OP mxv_cross3(__T* r, const __T* u, const __T* v) -{ - r[0] = u[1] * v[2] - v[1] * u[2]; - r[1] = -u[0] * v[2] + v[0] * u[2]; - r[2] = u[0] * v[1] - v[0] * u[1]; - return r; -} - -__OP mxv_lerp(__T* r, const __T* u, const __T* v, __T t, __DIM) -{ - forall(i, N) { r[i] = t * u[i] + (1 - t) * v[i]; } - return r; -} - -__LINKAGE __T mxv_norm(const __T* v, __DIM) { return _sqrt(mxv_dot(v, v, N)); } -__LINKAGE __T mxv_norm2(const __T* v, __DIM) { return mxv_dot(v, v, N); } -__LINKAGE __T mxv_unitize(__T* v, __DIM) -{ - __T l = mxv_norm2(v, N); - if (l != 1.0 && l != 0.0) - { - l = _sqrt(l); - mxv_invscale(v, l, N); - } - return l; -} - -__LINKAGE __T mxv_Linf(const __T* u, const __T* v, __DIM) -{ - __T d = 0.0; - forall(i, N) - { - __T p = _abs(u[i] - v[i]); - d = _min(d, p); - } - return d; -} - -__LINKAGE __T mxv_L1(const __T* u, const __T* v, __DIM) -{ - __T d = 0.0; - forall(i, N) d += _abs(u[i] - v[i]); - return d; -} - -__LINKAGE __T mxv_L2(const __T* u, const __T* v, __DIM) -{ - __T d = 0.0; - forall(i, N) - { - __T p = u[i] - v[i]; - d += p * p; - } - return d; -} - -__LINKAGE bool mxv_eql(const __T* u, const __T* v, __DIM) -{ - bool e = true; - for (unsigned int i = 0; e && i < (unsigned int)N; i++) - e = e && (u[i] == v[i]); - return e; -} - -__LINKAGE bool mxv_equal(const __T* u, const __T* v, __DIM) { return mxv_L2(u, v, N) < FEQ_EPS2; } -__OP mxv_basis(__T* r, unsigned int b, __DIM) -{ - forall(i, N) r[i] = (i == b) ? __T(1.0) : __T(0.0); - return r; -} - -#undef __T -#undef __DIM -#undef __LINKAGE -#undef __OP -#undef forall -#undef def3 -#undef def2 -#undef def1 -#undef def2s -#undef def1s - -// MIXVOPS_INCLUDED diff --git a/src/utils/xrQSlim/stdafx.h b/src/utils/xrQSlim/stdafx.h deleted file mode 100644 index e35b40b0586..00000000000 --- a/src/utils/xrQSlim/stdafx.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" -#include "xrCore/xrCore.h" - -/************************************************************************ - -Standard base include file for the MIX library. This defines various -common stuff that is used elsewhere. - -Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. - -$Id: stdmix.h,v 1.21.2.1 2002/01/31 18:38:37 garland Exp $ - -************************************************************************/ - -#if defined(_DEBUG) && defined(_MSC_VER) -// STL makes Visual C++ complain about identifiers longer than 255 -// characters. Unfortunately, this may limit the debuggability of -// code that uses STL. -#pragma warning(disable : 4786) -#endif - -inline bool streq(const char* a, const char* b) { return !xr_strcmp(a, b); } diff --git a/src/utils/xrQSlim/vec2.h b/src/utils/xrQSlim/vec2.h deleted file mode 100644 index 3928dd7996a..00000000000 --- a/src/utils/xrQSlim/vec2.h +++ /dev/null @@ -1,225 +0,0 @@ -#ifndef GFXVEC2_INCLUDED // -*- C++ -*- -#define GFXVEC2_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 2D Vector class - - $Id: vec2.h,v 1.19 2002/09/20 16:02:25 garland Exp $ - - ************************************************************************/ - -template -class TVec2 -{ -private: - T elt[2]; - -public: - // Standard constructors - // - TVec2(T s = 0) { *this = s; } - TVec2(T x, T y) - { - elt[0] = x; - elt[1] = y; - } - - // Copy constructors & assignment operators - template - TVec2(const TVec2& v) - { - *this = v; - } - template - TVec2(const U v[2]) - { - elt[0] = v[0]; - elt[1] = v[1]; - } - template - TVec2& operator=(const TVec2& v) - { - elt[0] = v[0]; - elt[1] = v[1]; - return *this; - } - TVec2& operator=(T s) - { - elt[0] = elt[1] = s; - return *this; - } - - // Descriptive interface - // - typedef T value_type; - static int dim() { return 2; } - // Access methods - // - operator T*() { return elt; } - operator const T*() const { return elt; } - // In-place arithmetic methods - // - inline TVec2& operator+=(const TVec2& v); - inline TVec2& operator-=(const TVec2& v); - inline TVec2& operator*=(T s); - inline TVec2& operator/=(T s); -}; - -//////////////////////////////////////////////////////////////////////// -// -// Method definitions -// -template -inline TVec2& TVec2::operator+=(const TVec2& v) -{ - elt[0] += v[0]; - elt[1] += v[1]; - return *this; -} - -template -inline TVec2& TVec2::operator-=(const TVec2& v) -{ - elt[0] -= v[0]; - elt[1] -= v[1]; - return *this; -} - -template -inline TVec2& TVec2::operator*=(T s) -{ - elt[0] *= s; - elt[1] *= s; - return *this; -} - -template -inline TVec2& TVec2::operator/=(T s) -{ - elt[0] /= s; - elt[1] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator defintions -// - -template -inline TVec2 operator+(const TVec2& u, const TVec2& v) -{ - return TVec2(u[0] + v[0], u[1] + v[1]); -} - -template -inline TVec2 operator-(const TVec2& u, const TVec2& v) -{ - return TVec2(u[0] - v[0], u[1] - v[1]); -} - -template -inline TVec2 operator-(const TVec2& v) -{ - return TVec2(-v[0], -v[1]); -} - -#if _MSC_VER >= 1200 -// Normally, we use the construct below to allow the scalar -// argument to be different than the template type. This, for example, allows -// the user to write things like v/2. Unfortunately, Microsoft VC6.0 (aka -// v1200) gets confused by this. We used to include explicit versions for the -// case of int's, but this was causing silent (and incorrect) coercion of -// floats to ints. -// - -template -inline TVec2 operator*(T s, const TVec2& v) -{ - return TVec2(v[0] * s, v[1] * s); -} -template -inline TVec2 operator*(const TVec2& v, T s) -{ - return s * v; -} - -template -inline TVec2 operator/(const TVec2& v, T s) -{ - return TVec2(v[0] / s, v[1] / s); -} - -#else -template -inline TVec2 operator*(N s, const TVec2& v) -{ - return TVec2(v[0] * s, v[1] * s); -} -template -inline TVec2 operator*(const TVec2& v, N s) -{ - return s * v; -} - -template -inline TVec2 operator/(const TVec2& v, N s) -{ - return TVec2(v[0] / s, v[1] / s); -} -#endif - -template -inline T operator*(const TVec2& u, const TVec2& v) -{ - return u[0] * v[0] + u[1] * v[1]; -} - -template -inline TVec2 perp(const TVec2& v) -{ - return TVec2(v[1], -v[0]); -} -/* -template -inline std::ostream &operator<<(std::ostream &out, const TVec2 &v) - { return out << v[0] << " " << v[1]; } - -template -inline std::istream &operator>>(std::istream &in, TVec2& v) - { return in >> v[0] >> v[1]; } -*/ - -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -template -inline T norm2(const TVec2& v) -{ - return v * v; -} -template -inline T norm(const TVec2& v) -{ - return _sqrt(norm2(v)); -} - -template -inline void unitize(TVec2& v) -{ - T l = norm2(v); - if (l != 1.0 && l != 0.0) - v /= _sqrt(l); -} - -typedef TVec2 Vec2; -typedef TVec2 Vec2f; - -// GFXVEC2_INCLUDED -#endif diff --git a/src/utils/xrQSlim/vec3.h b/src/utils/xrQSlim/vec3.h deleted file mode 100644 index 201929e709f..00000000000 --- a/src/utils/xrQSlim/vec3.h +++ /dev/null @@ -1,255 +0,0 @@ -#ifndef GFXVEC3_INCLUDED // -*- C++ -*- -#define GFXVEC3_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 3D Vector class - - $Id: vec3.h,v 1.21 2002/09/20 16:02:25 garland Exp $ - - ************************************************************************/ - -#include "vec2.h" - -template -class TVec3 -{ -private: - T elt[3]; - -public: - // Standard constructors - // - TVec3(T s = 0) { *this = s; } - TVec3(T x, T y, T z) - { - elt[0] = x; - elt[1] = y; - elt[2] = z; - } - - // Copy constructors & assignment operators - template - TVec3(const TVec3& v) - { - *this = v; - } - - TVec3(const float* v) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - } - TVec3(const double* v) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - } - - template - TVec3& operator=(const TVec3& v) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - return *this; - } - TVec3& operator=(T s) - { - elt[0] = elt[1] = elt[2] = s; - return *this; - } - - // Descriptive interface - // - typedef T value_type; - static int dim() { return 3; } - // Access methods - // - operator T*() { return elt; } - operator const T*() const { return elt; } - // Assignment and in-place arithmetic methods - // - inline TVec3& operator+=(const TVec3& v); - inline TVec3& operator-=(const TVec3& v); - inline TVec3& operator*=(T s); - inline TVec3& operator/=(T s); -}; - -//////////////////////////////////////////////////////////////////////// -// -// Method definitions -// - -template -inline TVec3& TVec3::operator+=(const TVec3& v) -{ - elt[0] += v[0]; - elt[1] += v[1]; - elt[2] += v[2]; - return *this; -} - -template -inline TVec3& TVec3::operator-=(const TVec3& v) -{ - elt[0] -= v[0]; - elt[1] -= v[1]; - elt[2] -= v[2]; - return *this; -} - -template -inline TVec3& TVec3::operator*=(T s) -{ - elt[0] *= s; - elt[1] *= s; - elt[2] *= s; - return *this; -} - -template -inline TVec3& TVec3::operator/=(T s) -{ - elt[0] /= s; - elt[1] /= s; - elt[2] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator definitions -// - -template -inline TVec3 operator+(const TVec3& u, const TVec3& v) -{ - return TVec3(u[0] + v[0], u[1] + v[1], u[2] + v[2]); -} - -template -inline TVec3 operator-(const TVec3& u, const TVec3& v) -{ - return TVec3(u[0] - v[0], u[1] - v[1], u[2] - v[2]); -} - -template -inline TVec3 operator-(const TVec3& v) -{ - return TVec3(-v[0], -v[1], -v[2]); -} - -#if _MSC_VER >= 1200 -// Normally, we use the construct below to allow the scalar -// argument to be different than the template type. This, for example, allows -// the user to write things like v/2. Unfortunately, Microsoft VC6.0 (aka -// v1200) gets confused by this. We used to include explicit versions for the -// case of int's, but this was causing silent (and incorrect) coercion of -// floats to ints. -// -template -inline TVec3 operator*(T s, const TVec3& v) -{ - return TVec3(v[0] * s, v[1] * s, v[2] * s); -} -template -inline TVec3 operator*(const TVec3& v, T s) -{ - return s * v; -} - -template -inline TVec3 operator/(const TVec3& v, T s) -{ - return TVec3(v[0] / s, v[1] / s, v[2] / s); -} -#else -template -inline TVec3 operator*(N s, const TVec3& v) -{ - return TVec3(v[0] * s, v[1] * s, v[2] * s); -} -template -inline TVec3 operator*(const TVec3& v, N s) -{ - return s * v; -} - -template -inline TVec3 operator/(const TVec3& v, N s) -{ - return TVec3(v[0] / s, v[1] / s, v[2] / s); -} -#endif - -template -inline T operator*(const TVec3& u, const TVec3& v) -{ - return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]; -} - -template -inline TVec3 cross(const TVec3& u, const TVec3& v) -{ - return TVec3(u[1] * v[2] - v[1] * u[2], -u[0] * v[2] + v[0] * u[2], u[0] * v[1] - v[0] * u[1]); -} - -template -inline TVec3 operator^(const TVec3& u, const TVec3& v) -{ - return cross(u, v); -} - -/* -template -inline std::ostream &operator<<(std::ostream &out, const TVec3& v) - { return out << v[0] << " " << v[1] << " " << v[2]; } - -template -inline std::istream &operator>>(std::istream &in, TVec3& v) - { return in >> v[0] >> v[1] >> v[2]; } -*/ -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -template -inline T norm2(const TVec3& v) -{ - return v * v; -} -template -inline T norm(const TVec3& v) -{ - return _sqrt(norm2(v)); -} - -template -inline void unitize(TVec3& v) -{ - T l = norm2(v); - if (l != 1.0 && l != 0.0) - v /= _sqrt(l); -} - -template -inline TVec2 proj(const TVec3& v) -{ - TVec2 u(v[0], v[1]); - if (v[2] != 1.0 && v[2] != 0.0) - u /= v[2]; - return u; -} - -typedef TVec3 Vec3; -typedef TVec3 Vec3f; - -// GFXVEC3_INCLUDED -#endif diff --git a/src/utils/xrQSlim/vec4.h b/src/utils/xrQSlim/vec4.h deleted file mode 100644 index 9cb82c55429..00000000000 --- a/src/utils/xrQSlim/vec4.h +++ /dev/null @@ -1,266 +0,0 @@ -#ifndef GFXVEC4_INCLUDED // -*- C++ -*- -#define GFXVEC4_INCLUDED -#if !defined(__GNUC__) -#pragma once -#endif - -/************************************************************************ - - 4D Vector class - - $Id: vec4.h,v 1.19 2002/09/20 16:02:25 garland Exp $ - - ************************************************************************/ - -#include "vec3.h" - -template -class TVec4 -{ -private: - T elt[4]; - -public: - // Standard constructors - // - TVec4(T s = 0) { *this = s; } - TVec4(T x, T y, T z, T w) - { - elt[0] = x; - elt[1] = y; - elt[2] = z; - elt[3] = w; - } - - // Copy constructors & assignment operators - template - TVec4(const TVec4& v) - { - *this = v; - } - template - TVec4(const TVec3& v, T w) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - elt[3] = w; - } - template - TVec4(const U v[4]) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - elt[3] = v[3]; - } - template - TVec4& operator=(const TVec4& v) - { - elt[0] = v[0]; - elt[1] = v[1]; - elt[2] = v[2]; - elt[3] = v[3]; - return *this; - } - TVec4& operator=(T s) - { - elt[0] = elt[1] = elt[2] = elt[3] = s; - return *this; - } - - // Descriptive interface - // - typedef T value_type; - static int dim() { return 4; } - // Access methods - // - operator T*() { return elt; } - operator const T*() const { return elt; } - // Assignment and in-place arithmetic methods - // - inline TVec4& operator+=(const TVec4& v); - inline TVec4& operator-=(const TVec4& v); - inline TVec4& operator*=(T s); - inline TVec4& operator/=(T s); -}; - -//////////////////////////////////////////////////////////////////////// -// -// Method definitions -// - -template -inline TVec4& TVec4::operator+=(const TVec4& v) -{ - elt[0] += v[0]; - elt[1] += v[1]; - elt[2] += v[2]; - elt[3] += v[3]; - return *this; -} - -template -inline TVec4& TVec4::operator-=(const TVec4& v) -{ - elt[0] -= v[0]; - elt[1] -= v[1]; - elt[2] -= v[2]; - elt[3] -= v[3]; - return *this; -} - -template -inline TVec4& TVec4::operator*=(T s) -{ - elt[0] *= s; - elt[1] *= s; - elt[2] *= s; - elt[3] *= s; - return *this; -} - -template -inline TVec4& TVec4::operator/=(T s) -{ - elt[0] /= s; - elt[1] /= s; - elt[2] /= s; - elt[3] /= s; - return *this; -} - -//////////////////////////////////////////////////////////////////////// -// -// Operator definitions -// - -template -inline TVec4 operator+(const TVec4& u, const TVec4& v) -{ - return TVec4(u[0] + v[0], u[1] + v[1], u[2] + v[2], u[3] + v[3]); -} - -template -inline TVec4 operator-(const TVec4& u, const TVec4& v) -{ - return TVec4(u[0] - v[0], u[1] - v[1], u[2] - v[2], u[3] - v[3]); -} - -template -inline TVec4 operator-(const TVec4& u) -{ - return TVec4(-u[0], -u[1], -u[2], -u[3]); -} - -#if _MSC_VER >= 1200 -// Normally, we use the construct below to allow the scalar -// argument to be different than the template type. This, for example, allows -// the user to write things like v/2. Unfortunately, Microsoft VC6.0 (aka -// v1200) gets confused by this. We used to include explicit versions for the -// case of int's, but this was causing silent (and incorrect) coercion of -// floats to ints. -// -template -inline TVec4 operator*(T s, const TVec4& v) -{ - return TVec4(v[0] * s, v[1] * s, v[2] * s, v[3] * s); -} -template -inline TVec4 operator*(const TVec4& v, T s) -{ - return s * v; -} - -template -inline TVec4 operator/(const TVec4& v, T s) -{ - return TVec4(v[0] / s, v[1] / s, v[2] / s, v[3] / s); -} -#else -template -inline TVec4 operator*(N s, const TVec4& v) -{ - return TVec4(v[0] * s, v[1] * s, v[2] * s, v[3] * s); -} -template -inline TVec4 operator*(const TVec4& v, N s) -{ - return s * v; -} - -template -inline TVec4 operator/(const TVec4& v, N s) -{ - return TVec4(v[0] / s, v[1] / s, v[2] / s, v[3] / s); -} -#endif - -template -inline T operator*(const TVec4& u, const TVec4& v) -{ - return u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]; -} -/* -template -inline std::ostream &operator<<(std::ostream &out, const TVec4& v) - { return out < -inline std::istream &operator>>(std::istream &in, TVec4& v) - { return in >> v[0] >> v[1] >> v[2] >> v[3]; } -*/ -//////////////////////////////////////////////////////////////////////// -// -// Misc. function definitions -// - -template -inline TVec4 cross(const TVec4& a, const TVec4& b, const TVec4& c) -{ - // Code adapted from VecLib4d.c in Graphics Gems V - - T d1 = (b[2] * c[3]) - (b[3] * c[2]); - T d2 = (b[1] * c[3]) - (b[3] * c[1]); - T d3 = (b[1] * c[2]) - (b[2] * c[1]); - T d4 = (b[0] * c[3]) - (b[3] * c[0]); - T d5 = (b[0] * c[2]) - (b[2] * c[0]); - T d6 = (b[0] * c[1]) - (b[1] * c[0]); - - return TVec4(-a[1] * d1 + a[2] * d2 - a[3] * d3, a[0] * d1 - a[2] * d4 + a[3] * d5, - -a[0] * d2 + a[1] * d4 - a[3] * d6, a[0] * d3 - a[1] * d5 + a[2] * d6); -} - -template -inline T norm2(const TVec4& v) -{ - return v * v; -} -template -inline T norm(const TVec4& v) -{ - return _sqrt(norm2(v)); -} - -template -inline void unitize(TVec4& v) -{ - T l = norm2(v); - if (l != 1.0 && l != 0.0) - v /= _sqrt(l); -} - -template -inline TVec3 proj(const TVec4& v) -{ - TVec3 u(v[0], v[1], v[2]); - if (v[3] != 1.0 && v[3] != 0.0) - u /= v[3]; - return u; -} - -typedef TVec4 Vec4; -typedef TVec4 Vec4f; - -// GFXVEC4_INCLUDED -#endif diff --git a/src/utils/xrQSlim/xrQSlim.vcxproj b/src/utils/xrQSlim/xrQSlim.vcxproj deleted file mode 100644 index 89d9d06d255..00000000000 --- a/src/utils/xrQSlim/xrQSlim.vcxproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - {F1836CE2-59EF-4189-8B9C-D103A511CB27} - xrQSlim - Win32Proj - - - - - - - StaticLibrary - - - - - - - - - - - $(xrBinDir)utils\ - - - - XR_QSLIM_EXPORTS;%(PreprocessorDefinitions) - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/utils/xrQSlim/xrQSlim.vcxproj.filters b/src/utils/xrQSlim/xrQSlim.vcxproj.filters deleted file mode 100644 index f323c42a5f0..00000000000 --- a/src/utils/xrQSlim/xrQSlim.vcxproj.filters +++ /dev/null @@ -1,165 +0,0 @@ - - - - - {5cd0feee-0b4e-4929-8a75-b473d039cdab} - - - {4fffaa06-e22a-4ced-9a94-e28246b5e497} - - - {dc6f6314-d4bd-4576-8f57-d9eb43731b85} - - - {b42a2236-2b60-45f1-9a54-06041bda2681} - - - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Model - - - Model - - - QSlim - - - QSlim - - - QSlim - - - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Math - - - Kernel - - - Model - - - Model - - - QSlim - - - QSlim - - - QSlim - - - - - - From a1b57e18af3038fe52921aabb21b9db7038b8625 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 08:04:57 +0500 Subject: [PATCH 290/497] utils/xrLC_Light/R_light.h: replace macros with constexpr u16 global variables --- src/utils/xrLC_Light/R_light.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/xrLC_Light/R_light.h b/src/utils/xrLC_Light/R_light.h index 925398fe508..46b15755819 100644 --- a/src/utils/xrLC_Light/R_light.h +++ b/src/utils/xrLC_Light/R_light.h @@ -1,8 +1,8 @@ #pragma once -#define LT_DIRECT 0 -#define LT_POINT 1 -#define LT_SECONDARY 2 +constexpr u16 LT_DIRECT = 0; +constexpr u16 LT_POINT = 1; +constexpr u16 LT_SECONDARY = 2; struct R_Light { From 5fa5052c95e00aa297f1f16d4cfaa21d4a0e3f58 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 08:36:56 +0500 Subject: [PATCH 291/497] Fix ImGui assertion failure on Alt+Tab when engine goes on pause --- src/xrEngine/device.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 7886b07063c..10a4c87136b 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -233,6 +233,16 @@ void CRenderDevice::BeforeRender() GEnv.Render->SetCacheXform(mView, mProject); } +static void UpdateViewports() +{ + // Update and Render additional Platform Windows + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } +} + void CRenderDevice::DoRender() { if (GEnv.isDedicatedServer) @@ -251,15 +261,14 @@ void CRenderDevice::DoRender() ImGui::Render(); m_imgui_render->Render(ImGui::GetDrawData()); - // Update and Render additional Platform Windows - if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - } + UpdateViewports(); RenderEnd(); // Present goes here } + else + { + UpdateViewports(); + } renderTotalReal.End(); renderTotalReal.FrameEnd(); stats.RenderTotal.accum = renderTotalReal.accum; From 0392dba64b1bbc69a4c28d3c7a6e129729fd45e6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Apr 2024 08:37:20 +0500 Subject: [PATCH 292/497] Pause task manager threads while process is inactive --- src/xrCore/Threading/TaskManager.hpp | 3 +++ src/xrEngine/device.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 7a1f1f7ab89..7aa3c496a02 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -77,10 +77,13 @@ class XRCORE_API TaskManager final public: void RegisterThisThreadAsWorker(); void UnregisterThisThreadAsWorker(); + void Wait(const Task& task) const; void WaitForChildren(const Task& task) const; bool ExecuteOneTask() const; + void Pause(bool pause) { shouldPause.store(pause, std::memory_order_release); } + public: [[nodiscard]] size_t GetWorkersCount() const; [[nodiscard]] static size_t GetCurrentWorkerID(); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 10a4c87136b..63de9357127 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -619,6 +619,7 @@ void CRenderDevice::OnWindowActivate(SDL_Window* window, bool activated) b_is_InFocus = activated; if (b_is_InFocus) { + TaskScheduler->Pause(false); seqAppActivate.Process(); app_inactive_time += TimerMM.GetElapsed_ms() - app_inactive_time_start; } @@ -626,6 +627,7 @@ void CRenderDevice::OnWindowActivate(SDL_Window* window, bool activated) { app_inactive_time_start = TimerMM.GetElapsed_ms(); seqAppDeactivate.Process(); + TaskScheduler->Pause(true); } } } From 09c889aa8908859b9373c1eab116ce710b4b7b64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:17:34 +0000 Subject: [PATCH 293/497] build(deps): bump Externals/sse2neon from `8df2f48` to `ab7a347` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `8df2f48` to `ab7a347`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/8df2f48dbd0674ae5087f7a6281af6f55fa5a8e2...ab7a34794507332edfa93b824b256f41e43f9e31) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 8df2f48dbd0..ab7a3479450 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 8df2f48dbd0674ae5087f7a6281af6f55fa5a8e2 +Subproject commit ab7a34794507332edfa93b824b256f41e43f9e31 From e73a99bee28f1dc0048743fdf05e81c6e622270f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 04:11:00 +0500 Subject: [PATCH 294/497] Better C++17 thread spawning utility Use std::thread and std::invoke, remove bunch of platform code Allow to save thread object for more fine-grained control --- src/xrCDB/xrCDB.cpp | 35 +++------ src/xrCDB/xrCDB.h | 1 - src/xrCore/Threading/TaskManager.cpp | 6 +- src/xrCore/Threading/ThreadUtil.cpp | 105 +-------------------------- src/xrCore/Threading/ThreadUtil.h | 53 ++++++-------- src/xrEngine/Device_create.cpp | 5 +- src/xrEngine/device.cpp | 8 +- src/xrEngine/x_ray.cpp | 6 +- src/xrGame/Level_Bullet_Manager.cpp | 8 +- src/xrGame/Level_Bullet_Manager.h | 2 +- src/xrGame/configs_dumper.cpp | 49 ++++++------- src/xrGame/configs_dumper.h | 1 - src/xrGame/screenshot_manager.cpp | 55 +++++++------- src/xrGame/screenshot_manager.h | 1 - src/xrGameSpy/GameSpy_Browser.cpp | 21 +----- src/xrNetServer/NET_Client.cpp | 9 +-- src/xrNetServer/NET_PlayersMonitor.h | 22 +++--- 17 files changed, 115 insertions(+), 272 deletions(-) diff --git a/src/xrCDB/xrCDB.cpp b/src/xrCDB/xrCDB.cpp index ca73b1f93b2..bdbbe3161ae 100644 --- a/src/xrCDB/xrCDB.cpp +++ b/src/xrCDB/xrCDB.cpp @@ -49,29 +49,6 @@ void MODEL::syncronize_impl() const C->Leave(); } -struct BTHREAD_params -{ - MODEL* M; - Fvector* V; - int Vcnt; - TRI* T; - int Tcnt; - build_callback* BC; - void* BCP; -}; - -void MODEL::build_thread(void* params) -{ - _initialize_cpu_thread(); - FPU::m64r(); - BTHREAD_params P = *((BTHREAD_params*)params); - P.M->pcs->Enter(); - P.M->build_internal(P.V, P.Vcnt, P.T, P.Tcnt, P.BC, P.BCP); - P.M->status = S_READY; - P.M->pcs->Leave(); - // Msg ("* xrCDB: cform build completed, memory usage: %d K",P.M->memory()/1024); -} - void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, void* bcp) { R_ASSERT(S_INIT == status); @@ -86,8 +63,16 @@ void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, vo } else { - BTHREAD_params P = {this, V, Vcnt, T, Tcnt, bc, bcp}; - Threading::SpawnThread(build_thread, "CDB-construction", 0, &P); + Threading::SpawnThread("CDB-construction", [&, this] + { + ScopeLock lock{ pcs }; + FPU::m64r(); + build_internal(V, Vcnt, T, Tcnt, bc, bcp); + status = S_READY; + FPU::m24r(); + // Msg("* xrCDB: cform build completed, memory usage: %d K", memory() / 1024); + }); + while (S_INIT == status) { if (status != S_INIT) diff --git a/src/xrCDB/xrCDB.h b/src/xrCDB/xrCDB.h index 89ae6d7778a..aea35064016 100644 --- a/src/xrCDB/xrCDB.h +++ b/src/xrCDB/xrCDB.h @@ -101,7 +101,6 @@ class XRCDB_API MODEL : Noncopyable syncronize_impl(); } - static void build_thread(void*); void build_internal(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc = NULL, void* bcp = NULL); void build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc = NULL, void* bcp = NULL); u32 memory(); diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 19ab26a6a23..b0e45989b55 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -200,11 +200,7 @@ TaskManager::TaskManager() const u32 threads = std::thread::hardware_concurrency() - OTHER_THREADS_COUNT; for (u32 i = 0; i < threads; ++i) { - Threading::SpawnThread([](void* this_ptr) - { - const auto self = static_cast(this_ptr); - self->TaskWorkerStart(); - }, "Task Worker", 0, this); + Threading::SpawnThread("Task Worker", &TaskManager::TaskWorkerStart, this); } } diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 3ac6e6fa187..8d873f53ab8 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -28,10 +28,6 @@ static int pthread_setname_np(pthread_t /*threadId*/, const char* name) namespace Threading { #if defined(XR_PLATFORM_WINDOWS) -ThreadId GetCurrThreadId() { return GetCurrentThreadId(); } - -bool ThreadIdsAreEqual(ThreadId left, ThreadId right) { return left == right; } - void SetThreadNameImpl(DWORD threadId, pcstr name) { const DWORD MSVC_EXCEPTION = 0x406D1388; @@ -65,7 +61,7 @@ void SetThreadNameImpl(DWORD threadId, pcstr name) } } -void SetCurrentThreadName(pcstr name) +void SetCurrentThreadName(cpcstr name) { SetThreadNameImpl(-1, name); } @@ -131,59 +127,8 @@ void SetCurrentProcessPriorityClass(priority_class cls) } SetPriorityClass(GetCurrentProcess(), dwPriorityClass); } - -u32 __stdcall ThreadEntry(void* params) -{ - SThreadStartupInfo* args = (SThreadStartupInfo*)params; - SetCurrentThreadName(args->threadName); - EntryFuncType entry = args->entryFunc; - void* arglist = args->argList; - xr_delete(args); - _initialize_cpu_thread(); - - // call - entry(arglist); - - return 0; -} - -bool SpawnThread(EntryFuncType entry, pcstr name, u32 stack, void* arglist) -{ - xrDebug::Initialize(Core.Params); - - SThreadStartupInfo* info = xr_new(); - info->threadName = name; - info->entryFunc = entry; - info->argList = arglist; - ThreadHandle threadHandle = (ThreadHandle)_beginthreadex(NULL, stack, ThreadEntry, info, CREATE_SUSPENDED, NULL); - - if (!threadHandle) - { - xr_string errMsg = xrDebug::ErrorToString(GetLastError()); - Msg("SpawnThread: can't create thread '%s'. Error Msg: '%s'", name, errMsg.c_str()); - return false; - } - - ResumeThread(threadHandle); - return true; -} - -void WaitThread(ThreadHandle& threadHandle) { WaitForSingleObject(threadHandle, INFINITE); } - -void CloseThreadHandle(ThreadHandle& threadHandle) -{ - if (threadHandle) - { - CloseHandle(threadHandle); - threadHandle = nullptr; - } -} #elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) -ThreadId GetCurrThreadId() { return pthread_self(); } - -bool ThreadIdsAreEqual(ThreadId left, ThreadId right) { return !!pthread_equal(left, right); } - -void SetCurrentThreadName(pcstr name) +void SetCurrentThreadName(cpcstr name) { if (auto error = pthread_setname_np(pthread_self(), name) != 0) { @@ -210,52 +155,6 @@ void SetCurrentProcessPriorityClass(priority_class cls) { } - -void* __cdecl ThreadEntry(void* params) -{ - SThreadStartupInfo* args = (SThreadStartupInfo*)params; - SetCurrentThreadName(args->threadName); - EntryFuncType entry = args->entryFunc; - void* arglist = args->argList; - xr_delete(args); - _initialize_cpu_thread(); - - // call - entry(arglist); - - return nullptr; -} - -bool SpawnThread(EntryFuncType entry, pcstr name, u32 stack, void* arglist) -{ - xrDebug::Initialize(Core.Params); - - SThreadStartupInfo* info = xr_new(); - info->threadName = name; - info->entryFunc = entry; - info->argList = arglist; - - pthread_t handle = 0; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, stack); - - int res = pthread_create(&handle, &attr, &ThreadEntry, info); - pthread_attr_destroy(&attr); - - if (res != 0) - { - Msg("SpawnThread: can't create thread '%s'.", name); - return false; - } - - return true; -} - -void WaitThread(ThreadHandle& threadHandle) { pthread_join(threadHandle, NULL); } - -void CloseThreadHandle(ThreadHandle& threadHandle) { pthread_detach(threadHandle); } #else # error Add threading code for your platform #endif diff --git a/src/xrCore/Threading/ThreadUtil.h b/src/xrCore/Threading/ThreadUtil.h index 5ee3fa60c54..3c4e2becc03 100644 --- a/src/xrCore/Threading/ThreadUtil.h +++ b/src/xrCore/Threading/ThreadUtil.h @@ -3,6 +3,8 @@ #include #endif +#include + namespace Threading { enum class priority_class @@ -26,40 +28,33 @@ enum class priority_level time_critical, }; -#ifdef XR_PLATFORM_WINDOWS -using ThreadHandle = HANDLE; -using ThreadId = u32; -#else -using ThreadHandle = pthread_t; -using ThreadId = pthread_t; -#endif -using EntryFuncType = void (*)(void*); - -struct SThreadStartupInfo -{ - pcstr threadName; - EntryFuncType entryFunc; - void* argList; -}; - -////////////////////////////////////////////////////////////// - -XRCORE_API ThreadId GetCurrThreadId(); - -XRCORE_API bool ThreadIdsAreEqual(ThreadId left, ThreadId right); - -XRCORE_API void SetCurrentThreadName(pcstr name); - XRCORE_API priority_level GetCurrentThreadPriorityLevel(); XRCORE_API priority_class GetCurrentProcessPriorityClass(); XRCORE_API void SetCurrentThreadPriorityLevel(priority_level prio); XRCORE_API void SetCurrentProcessPriorityClass(priority_class cls); -XRCORE_API bool SpawnThread(EntryFuncType entry, pcstr name, u32 stack, void* arglist); - -XRCORE_API void WaitThread(ThreadHandle& threadHandle); - -XRCORE_API void CloseThreadHandle(ThreadHandle& threadHandle); +XRCORE_API void SetCurrentThreadName(cpcstr name); +template +[[nodiscard]] std::thread RunThread(cpcstr name, Invocable&& invocable, Args&&... args) +{ + return std::move(std::thread + { + [name](Invocable&& invocable2, Args&&... args2) + { + SetCurrentThreadName(name); + _initialize_cpu_thread(); + std::invoke(std::move(invocable2), std::move(args2)...); + }, + std::forward(invocable), + std::forward(args)... + }); +} + +template +void SpawnThread(Args&&... args) +{ + RunThread(std::forward(args)...).detach(); +} } // namespace Threading diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index a5833fd1ad5..7e1fef2d22d 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -21,10 +21,7 @@ void CRenderDevice::Create() if (b_is_Ready) return; // prevent double call - Threading::SpawnThread([] (void* context) - { - static_cast(context)->SecondaryThreadProc(); - }, "Secondary thread", 0, this); + Threading::SpawnThread("Secondary thread", &CRenderDevice::SecondaryThreadProc, this); Statistic = xr_new(); Log("Starting RENDER device..."); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 63de9357127..171660d4ee3 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -62,7 +62,7 @@ namespace void CheckPrivilegySlowdown() { #ifndef MASTER_GOLD - const auto slowdownthread = +[](void*) + const auto slowdownthread = [] { for (;;) { @@ -74,11 +74,11 @@ void CheckPrivilegySlowdown() }; if (strstr(Core.Params, "-slowdown")) - Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); + Threading::SpawnThread("slowdown", slowdownthread); if (strstr(Core.Params, "-slowdown2x")) { - Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); - Threading::SpawnThread(slowdownthread, "slowdown", 0, nullptr); + Threading::SpawnThread("slowdown", slowdownthread); + Threading::SpawnThread("slowdown", slowdownthread); } #endif } diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index ab40776a514..11537c22bd2 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -520,11 +520,7 @@ void CApplication::ShowSplash(bool topmost) SDL_ShowWindow(m_window); SDL_UpdateWindowSurface(m_window); - Threading::SpawnThread(+[](void* self_ptr) - { - auto& self = *static_cast(self_ptr); - self.SplashProc(); - }, "X-Ray Splash Thread", 0, this); + Threading::SpawnThread("Splash Thread", &CApplication::SplashProc, this); while (!m_thread_operational) SDL_PumpEvents(); diff --git a/src/xrGame/Level_Bullet_Manager.cpp b/src/xrGame/Level_Bullet_Manager.cpp index 05ff474bdd8..29d83ac61ab 100644 --- a/src/xrGame/Level_Bullet_Manager.cpp +++ b/src/xrGame/Level_Bullet_Manager.cpp @@ -80,11 +80,11 @@ CBulletManager::CBulletManager() #if 0 // def CONFIG_PROFILE_LOCKS : m_Lock(MUTEX_PROFILE_ID(CBulletManager)) #ifdef DEBUG - ,m_thread_id(Threading::GetCurrThreadId()) + ,m_thread_id(std::this_thread::get_id()) #endif // #ifdef DEBUG #else // #ifdef CONFIG_PROFILE_LOCKS #ifdef DEBUG - : m_thread_id(Threading::GetCurrThreadId()) + : m_thread_id(std::this_thread::get_id()) #endif // #ifdef DEBUG #endif // #ifdef CONFIG_PROFILE_LOCKS { @@ -180,7 +180,7 @@ void CBulletManager::AddBullet(const Fvector& position, const Fvector& direction // Uncomment below if you will change the behaviour // if (!g_mt_config.test(mtBullets)) #ifdef DEBUG - VERIFY(Threading::ThreadIdsAreEqual(m_thread_id, Threading::GetCurrThreadId())); + VERIFY(m_thread_id == std::this_thread::get_id()); #endif VERIFY(u16(-1) != cartridge.bullet_material_idx); @@ -203,7 +203,7 @@ void CBulletManager::AddBullet(const Fvector& position, const Fvector& direction void CBulletManager::UpdateWorkload() { #ifdef DEBUG - VERIFY(g_mt_config.test(mtBullets) || Threading::ThreadIdsAreEqual(m_thread_id, Threading::GetCurrThreadId())); + VERIFY(g_mt_config.test(mtBullets) || m_thread_id == std::this_thread::get_id()); #endif rq_storage.r_clear(); diff --git a/src/xrGame/Level_Bullet_Manager.h b/src/xrGame/Level_Bullet_Manager.h index 90149a5b0e9..df2d72f57c9 100644 --- a/src/xrGame/Level_Bullet_Manager.h +++ b/src/xrGame/Level_Bullet_Manager.h @@ -134,7 +134,7 @@ class CBulletManager xr_vector<_event> m_Events; #ifdef DEBUG - Threading::ThreadId m_thread_id; + std::thread::id m_thread_id; typedef xr_vector BulletPoints; BulletPoints m_bullet_points; diff --git a/src/xrGame/configs_dumper.cpp b/src/xrGame/configs_dumper.cpp index ea914df358c..bee8ec3a0d0 100644 --- a/src/xrGame/configs_dumper.cpp +++ b/src/xrGame/configs_dumper.cpp @@ -230,7 +230,29 @@ void configs_dumper::dump_config(complete_callback_t complete_cb) } m_make_start_event = CreateEvent(NULL, FALSE, TRUE, NULL); m_make_done_event = CreateEvent(NULL, FALSE, FALSE, NULL); - Threading::SpawnThread(&configs_dumper::dumper_thread, "configs_dumper", 0, this); + + Threading::SpawnThread("configs_dumper", [this] + { + u32 wait_result = WaitForSingleObject(m_make_start_event, INFINITE); + while ((wait_result != WAIT_ABANDONED) || (wait_result != WAIT_FAILED)) + { + if (!is_active()) + break; // error + timer_begin("writing configs"); + write_configs(); + timer_end(); + timer_begin("signing configs"); + sign_configs(); + timer_end(); + timer_begin("compressing data"); + compress_configs(); + timer_end(); + SetEvent(m_make_done_event); + wait_result = WaitForSingleObject(m_make_start_event, INFINITE); + } + SetEvent(m_make_done_event); + }); + Engine.Sheduler.Register(this, TRUE); #endif } @@ -247,31 +269,6 @@ void configs_dumper::compress_configs() m_buffer_for_compress, m_buffer_for_compress_capacity, m_dump_result.pointer(), m_dump_result.size(), ts_cb); } -void configs_dumper::dumper_thread(void* my_ptr) -{ -#ifdef XR_PLATFORM_WINDOWS // XXX: use Event class, enable on other platforms - configs_dumper* this_ptr = static_cast(my_ptr); - u32 wait_result = WaitForSingleObject(this_ptr->m_make_start_event, INFINITE); - while ((wait_result != WAIT_ABANDONED) || (wait_result != WAIT_FAILED)) - { - if (!this_ptr->is_active()) - break; // error - this_ptr->timer_begin("writing configs"); - this_ptr->write_configs(); - this_ptr->timer_end(); - this_ptr->timer_begin("signing configs"); - this_ptr->sign_configs(); - this_ptr->timer_end(); - this_ptr->timer_begin("compressing data"); - this_ptr->compress_configs(); - this_ptr->timer_end(); - SetEvent(this_ptr->m_make_done_event); - wait_result = WaitForSingleObject(this_ptr->m_make_start_event, INFINITE); - } - SetEvent(this_ptr->m_make_done_event); -#endif -} - void configs_dumper::yield_cb(long progress) { if (progress % 5 == 0) diff --git a/src/xrGame/configs_dumper.h b/src/xrGame/configs_dumper.h index e4a8b404dd5..d3281144eb5 100644 --- a/src/xrGame/configs_dumper.h +++ b/src/xrGame/configs_dumper.h @@ -43,7 +43,6 @@ class configs_dumper : public ScheduledBase void sign_configs(); void compress_configs(); - static void dumper_thread(void* my_ptr); void yield_cb(long progress); void switch_thread(); diff --git a/src/xrGame/screenshot_manager.cpp b/src/xrGame/screenshot_manager.cpp index e4690c49528..61d8580564e 100644 --- a/src/xrGame/screenshot_manager.cpp +++ b/src/xrGame/screenshot_manager.cpp @@ -248,8 +248,33 @@ void screenshot_manager::process_screenshot(bool singlecore) } m_make_start_event = CreateEvent(NULL, FALSE, TRUE, NULL); m_make_done_event = CreateEvent(NULL, FALSE, FALSE, NULL); + + Threading::SpawnThread("screenshot_maker", [this] + { + u32 wait_result = WaitForSingleObject(m_make_start_event, INFINITE); + while ((wait_result != WAIT_ABANDONED) || (wait_result != WAIT_FAILED)) + { + if (!is_active()) + break; + timer_begin("preparing image"); + prepare_image(); + timer_end(); + timer_begin("making jpeg"); + make_jpeg_file(); + timer_end(); + timer_begin("signing jpeg data"); + sign_jpeg_file(); + timer_end(); + timer_begin("compressing_image"); + compress_image(); + timer_end(); + SetEvent(m_make_done_event); + wait_result = WaitForSingleObject(m_make_start_event, INFINITE); + } + SetEvent(m_make_done_event); + + }); #endif - Threading::SpawnThread(&screenshot_manager::screenshot_maker_thread, "screenshot_maker", 0, this); } void screenshot_manager::jpeg_compress_cb(long progress) { @@ -263,34 +288,6 @@ void screenshot_manager::jpeg_compress_cb(long progress) } } -void screenshot_manager::screenshot_maker_thread(void* arg_ptr) -{ -#ifdef XR_PLATFORM_WINDOWS // FIXME!! - screenshot_manager* this_ptr = static_cast(arg_ptr); - u32 wait_result = WaitForSingleObject(this_ptr->m_make_start_event, INFINITE); - while ((wait_result != WAIT_ABANDONED) || (wait_result != WAIT_FAILED)) - { - if (!this_ptr->is_active()) - break; - this_ptr->timer_begin("preparing image"); - this_ptr->prepare_image(); - this_ptr->timer_end(); - this_ptr->timer_begin("making jpeg"); - this_ptr->make_jpeg_file(); - this_ptr->timer_end(); - this_ptr->timer_begin("signing jpeg data"); - this_ptr->sign_jpeg_file(); - this_ptr->timer_end(); - this_ptr->timer_begin("compressing_image"); - this_ptr->compress_image(); - this_ptr->timer_end(); - SetEvent(this_ptr->m_make_done_event); - wait_result = WaitForSingleObject(this_ptr->m_make_start_event, INFINITE); - } - SetEvent(this_ptr->m_make_done_event); -#endif -} - void screenshot_manager::realloc_compress_buffer(u32 need_size) { if (m_buffer_for_compress && (need_size <= m_buffer_for_compress_capacity)) diff --git a/src/xrGame/screenshot_manager.h b/src/xrGame/screenshot_manager.h index 925fd9613c3..f53b2368d07 100644 --- a/src/xrGame/screenshot_manager.h +++ b/src/xrGame/screenshot_manager.h @@ -56,7 +56,6 @@ class screenshot_manager : public ScheduledBase void process_screenshot(bool in_other_thread); HANDLE m_make_start_event; HANDLE m_make_done_event; - static void screenshot_maker_thread(void* this_ptr); #ifdef DEBUG CTimer m_debug_timer; diff --git a/src/xrGameSpy/GameSpy_Browser.cpp b/src/xrGameSpy/GameSpy_Browser.cpp index 2d0be06a845..d415d29706e 100644 --- a/src/xrGameSpy/GameSpy_Browser.cpp +++ b/src/xrGameSpy/GameSpy_Browser.cpp @@ -148,17 +148,6 @@ void CGameSpy_Browser::RefreshListInternet(const char* FilterStr) m_refresh_lock.Leave(); } -struct RefreshData -{ - CGameSpy_Browser* pGSBrowser; - string4096 FilterStr; - - RefreshData(CGameSpy_Browser* browser, pcstr filter) : pGSBrowser(browser) - { - xr_strcpy(FilterStr, filter); - } -}; - GSUpdateStatus CGameSpy_Browser::RefreshList_Full(bool Local, const char* FilterStr) { if (!m_pGSBrowser) @@ -178,15 +167,13 @@ GSUpdateStatus CGameSpy_Browser::RefreshList_Full(bool Local, const char* Filter m_refresh_lock.Enter(); m_refresh_lock.Leave(); - RefreshData* pRData = xr_new(this, FilterStr); m_bTryingToConnectToMasterServer = true; - Threading::SpawnThread([](void* inData) + xr_string filter{ FilterStr }; + Threading::SpawnThread("GS Internet Refresh", [this, filter] { - RefreshData* pRData = (RefreshData*)inData; - pRData->pGSBrowser->RefreshListInternet(pRData->FilterStr); - xr_delete(pRData); - }, "GS Internet Refresh", 0, pRData); + RefreshListInternet(filter.c_str()); + }); return GSUpdateStatus::ConnectingToMaster; } diff --git a/src/xrNetServer/NET_Client.cpp b/src/xrNetServer/NET_Client.cpp index bb4808d35a8..93c073c24d7 100644 --- a/src/xrNetServer/NET_Client.cpp +++ b/src/xrNetServer/NET_Client.cpp @@ -1074,12 +1074,11 @@ void IPureClient::net_Syncronize() { net_Syncronised = false; net_DeltaArray.clear(); - Threading::SpawnThread([](void* P) + + Threading::SpawnThread( "network-time-sync", [this] { - Threading::SetCurrentThreadPriorityLevel(Threading::priority_level::time_critical); - IPureClient* C = static_cast(P); - C->Sync_Thread(); - }, "network-time-sync", 0, this); + Sync_Thread(); + }); } void IPureClient::ClearStatistic() diff --git a/src/xrNetServer/NET_PlayersMonitor.h b/src/xrNetServer/NET_PlayersMonitor.h index ab6172e7892..f849b284f9a 100644 --- a/src/xrNetServer/NET_PlayersMonitor.h +++ b/src/xrNetServer/NET_PlayersMonitor.h @@ -18,23 +18,21 @@ class PlayersMonitor bool now_iterating_in_net_players; bool now_iterating_in_net_players_disconn; #ifdef DEBUG - Threading::ThreadId iterator_thread_id; + std::thread::id iterator_thread_id; #endif + public: PlayersMonitor() { now_iterating_in_net_players = false; now_iterating_in_net_players_disconn = false; -#ifdef DEBUG - iterator_thread_id = 0; -#endif } #ifdef DEBUG bool IsCurrentThreadIteratingOnClients() const { if (now_iterating_in_net_players || now_iterating_in_net_players_disconn) { - if (Threading::ThreadIdsAreEqual(iterator_thread_id, Threading::GetCurrThreadId())) + if (iterator_thread_id == std::this_thread::get_id()) { return true; } @@ -51,7 +49,7 @@ class PlayersMonitor // make_string("-S- Entered to csPlayers [%d]", Threading::GetCurrThreadId()).c_str()); now_iterating_in_net_players = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif for (players_collection_t::iterator i = net_Players.begin(), ie = net_Players.end(); i != ie; ++i) { @@ -71,7 +69,7 @@ class PlayersMonitor // make_string("-S- Entered to csPlayers [%d]", Threading::GetCurrThreadId()).c_str()); now_iterating_in_net_players = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif for (players_collection_t::iterator i = net_Players.begin(), ie = net_Players.end(); i != ie; ++i) { @@ -93,7 +91,7 @@ class PlayersMonitor // make_string("-S- Entered to csPlayers [%d]", Threading::GetCurrThreadId()).c_str()); now_iterating_in_net_players = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif players_collection_t::iterator players_endi = net_Players.end(); players_collection_t::iterator temp_iter = std::find_if(net_Players.begin(), players_endi, predicate); @@ -120,7 +118,7 @@ class PlayersMonitor VERIFY(!now_iterating_in_net_players); now_iterating_in_net_players = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif players_collection_t::iterator client_iter = std::find_if(net_Players.begin(), net_Players.end(), predicate); IClient* ret_client = nullptr; @@ -173,7 +171,7 @@ class PlayersMonitor //LogStackTrace(make_string("-S- Entered to csPlayers [%d]", Threading::GetCurrThreadId()).c_str()); now_iterating_in_net_players_disconn = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif std::for_each(net_Players_disconnected.begin(), net_Players_disconnected.end(), functor); now_iterating_in_net_players_disconn = false; @@ -190,7 +188,7 @@ class PlayersMonitor VERIFY(!now_iterating_in_net_players_disconn); now_iterating_in_net_players_disconn = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif players_collection_t::iterator client_iter = std::find_if( net_Players_disconnected.begin(), @@ -217,7 +215,7 @@ class PlayersMonitor // make_string("-S- Entered to csPlayers [%d]", Threading::GetCurrThreadId()).c_str()); now_iterating_in_net_players_disconn = true; #ifdef DEBUG - iterator_thread_id = Threading::GetCurrThreadId(); + iterator_thread_id = std::this_thread::get_id(); #endif players_collection_t::iterator client_iter = std::find_if( net_Players_disconnected.begin(), From b7fe4ce126cb36d3743aa6208e16a96990d76c8f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 04:12:01 +0500 Subject: [PATCH 295/497] xrCore/Threading/ThreadUtil.cpp: add empty functions stubs to allow compilation on any platforms --- src/xrCore/Threading/ThreadUtil.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 8d873f53ab8..0ff7e5887d2 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -156,6 +156,12 @@ void SetCurrentProcessPriorityClass(priority_class cls) } #else -# error Add threading code for your platform +void SetCurrentThreadName(cpcstr name) {} + +priority_level GetCurrentThreadPriorityLevel() { return priority_level::normal; } +priority_class GetCurrentProcessPriorityClass() { return priority_class::normal; } + +void SetCurrentThreadPriorityLevel(priority_level prio) {} +void SetCurrentProcessPriorityClass(priority_class cls) {} #endif } // namespace Threading From 3aba4d837c161bcc9c418b35da9f4c5c7432da57 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 05:21:13 +0500 Subject: [PATCH 296/497] Fix non-Windows compilation --- src/xrNetServer/NET_Client.cpp | 2 +- src/xrNetServer/empty/NET_Client.cpp | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/xrNetServer/NET_Client.cpp b/src/xrNetServer/NET_Client.cpp index 93c073c24d7..e6dd6a5bef2 100644 --- a/src/xrNetServer/NET_Client.cpp +++ b/src/xrNetServer/NET_Client.cpp @@ -1075,7 +1075,7 @@ void IPureClient::net_Syncronize() net_Syncronised = false; net_DeltaArray.clear(); - Threading::SpawnThread( "network-time-sync", [this] + Threading::SpawnThread("network-time-sync", [this] { Sync_Thread(); }); diff --git a/src/xrNetServer/empty/NET_Client.cpp b/src/xrNetServer/empty/NET_Client.cpp index f62ba7b397d..c898d533ea1 100644 --- a/src/xrNetServer/empty/NET_Client.cpp +++ b/src/xrNetServer/empty/NET_Client.cpp @@ -557,17 +557,14 @@ void IPureClient::Sync_Thread() void IPureClient::Sync_Average() {} -void sync_thread(void* P) -{ - IPureClient* C = (IPureClient*)P; - C->Sync_Thread(); -} - void IPureClient::net_Syncronize() { net_Syncronised = false; net_DeltaArray.clear(); - Threading::SpawnThread(sync_thread, "network-time-sync", 0, this); + Threading::SpawnThread("network-time-sync", [this] + { + Sync_Thread(); + }); } bool IPureClient::net_isDisconnected() const From 18302bf654737f14f1632f00e42fec6094b28724 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 18:25:03 +0500 Subject: [PATCH 297/497] Use Threading::RunThread and std::thread::join for better thread shutdown control --- src/xrCore/Threading/TaskManager.cpp | 10 +++++----- src/xrCore/Threading/TaskManager.hpp | 1 + src/xrEngine/Device_create.cpp | 2 +- src/xrEngine/device.cpp | 4 +--- src/xrEngine/device.h | 1 + src/xrEngine/x_ray.cpp | 29 +++++++++------------------- src/xrEngine/x_ray.h | 2 +- 7 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index b0e45989b55..7df72d4e4c2 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -198,9 +198,10 @@ TaskManager::TaskManager() RegisterThisThreadAsWorker(); const u32 threads = std::thread::hardware_concurrency() - OTHER_THREADS_COUNT; + workerThreads.reserve(threads); for (u32 i = 0; i < threads; ++i) { - Threading::SpawnThread("Task Worker", &TaskManager::TaskWorkerStart, this); + workerThreads.emplace_back(Threading::RunThread("Task Worker", &TaskManager::TaskWorkerStart, this)); } } @@ -220,12 +221,11 @@ TaskManager::~TaskManager() for (TaskWorker* worker : workers) worker->event.Set(); } - while (activeWorkersCount.load(std::memory_order_acquire) || workers.size()) + for (auto& thread : workerThreads) { - Sleep(2); + if (thread.joinable()) + thread.join(); } - // Capture the last worker that might still be finishing - std::lock_guard guard{ workersLock }; } void TaskManager::RegisterThisThreadAsWorker() diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 7aa3c496a02..70a3d1103ef 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -26,6 +26,7 @@ class XRCORE_API TaskManager final { private: xr_vector workers; + xr_vector workerThreads; std::mutex workersLock; std::atomic_size_t activeWorkersCount{}; diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index 7e1fef2d22d..667fd3b5a03 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -21,7 +21,7 @@ void CRenderDevice::Create() if (b_is_Ready) return; // prevent double call - Threading::SpawnThread("Secondary thread", &CRenderDevice::SecondaryThreadProc, this); + secondaryThread = Threading::RunThread("Secondary thread", &CRenderDevice::SecondaryThreadProc, this); Statistic = xr_new(); Log("Starting RENDER device..."); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 171660d4ee3..52ff6c18b3d 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -291,7 +291,6 @@ void CRenderDevice::SecondaryThreadProc() TaskScheduler->ExecuteOneTask(); } TaskScheduler->UnregisterThisThreadAsWorker(); - secondaryThreadFinished.store(true, std::memory_order_release); } void CRenderDevice::ProcessFrame() @@ -469,8 +468,7 @@ void CRenderDevice::Shutdown() { // Stop Balance-Thread mt_bMustExit.store(true, std::memory_order_release); - while (!secondaryThreadFinished.load(std::memory_order_acquire)) - SDL_PumpEvents(); + secondaryThread.join(); seqAppEnd.Process(); } diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 127cc39c5e9..7d5a03d3ff1 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -234,6 +234,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler } private: + std::thread secondaryThread; std::atomic_bool executeSecondaryTasks{}, secondaryTasksExecuted{}, secondaryThreadFinished{}; public: diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 11537c22bd2..d16c1cb3955 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -520,17 +520,12 @@ void CApplication::ShowSplash(bool topmost) SDL_ShowWindow(m_window); SDL_UpdateWindowSurface(m_window); - Threading::SpawnThread("Splash Thread", &CApplication::SplashProc, this); - - while (!m_thread_operational) - SDL_PumpEvents(); + m_splash_thread = Threading::RunThread("Splash Thread", &CApplication::SplashProc, this); SDL_PumpEvents(); } void CApplication::SplashProc() { - m_thread_operational = true; - while (true) { if (m_should_exit.Wait(SPLASH_FRAMERATE)) @@ -548,15 +543,6 @@ void CApplication::SplashProc() } UpdateDiscordStatus(); } - - for (SDL_Surface* surface : m_surfaces) - SDL_FreeSurface(surface); - m_surfaces.clear(); - - SDL_DestroyWindow(m_window); - m_window = nullptr; - - m_thread_operational = false; } void CApplication::HideSplash() @@ -565,11 +551,14 @@ void CApplication::HideSplash() return; m_should_exit.Set(); - while (m_thread_operational) - { - SDL_PumpEvents(); - SwitchToThread(); - } + m_splash_thread.join(); + + SDL_DestroyWindow(m_window); + m_window = nullptr; + + for (SDL_Surface* surface : m_surfaces) + SDL_FreeSurface(surface); + m_surfaces.clear(); } void CApplication::UpdateDiscordStatus() diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index cac96af80b0..f573164c98b 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -17,8 +17,8 @@ class Core; class ENGINE_API CApplication final { SDL_Window* m_window{}; + std::thread m_splash_thread; Event m_should_exit; - bool m_thread_operational{}; size_t m_current_surface_idx{}; xr_vector m_surfaces; From 4da2c6b6ffc6d000b05fb7b25e614e9f57f348e6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 18:29:26 +0500 Subject: [PATCH 298/497] xrCore/Threading/TaskManager.cpp: simplify main task worker cycle --- src/xrCore/Threading/TaskManager.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 7df72d4e4c2..5e672fb82dc 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -272,16 +272,8 @@ void TaskManager::TaskWorkerStart() const u32 fastIterations = ttapi_dwFastIter; u32 iteration = 0; - Task* task; while (true) { - goto get_task; - - execute: - { - ExecuteTask(*task); - iteration = 0; - } get_task: { if (shouldStop.load(std::memory_order_consume)) @@ -289,12 +281,16 @@ void TaskManager::TaskWorkerStart() if (shouldPause.load(std::memory_order_consume)) goto wait; - task = s_tl_worker.pop(); + Task* task = s_tl_worker.pop(); if (!task) task = TryToSteal(); if (task) - goto execute; + { + ExecuteTask(*task); + iteration = 0; + goto get_task; + } } //count_spins: { From 91ab965ec74c62dbe431794c307f2895fe78241b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 24 Apr 2024 18:44:29 +0500 Subject: [PATCH 299/497] xrCore/Threading/TaskManager.cpp: hardened atomic memory order relaxed was insufficient and incorrect here Possible fix for #1363. --- src/xrCore/Threading/TaskManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 5e672fb82dc..85858b92f4c 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -93,14 +93,14 @@ class TaskQueue public: void push(Task* task) { - const auto task_pos = m_tail_pos.fetch_add(1, std::memory_order_relaxed); - VERIFY2(task_pos - m_head_pos.load(std::memory_order_relaxed) < TASK_STORAGE_SIZE, "Task queue overflow"); + const auto task_pos = m_tail_pos.fetch_add(1, std::memory_order_acq_rel); + VERIFY2(task_pos - m_head_pos.load(std::memory_order_acquire) < TASK_STORAGE_SIZE, "Task queue overflow"); m_storage[task_pos & TASK_STORAGE_MASK] = task; } Task* pop() { - size_t head_pos = m_head_pos.load(std::memory_order_relaxed); + size_t head_pos = m_head_pos.load(std::memory_order_acquire); Task* task = m_storage[head_pos & TASK_STORAGE_MASK]; if (!task) return nullptr; From 3d4722b03da2ede9abf687644e6d68a076433a48 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 25 Apr 2024 06:42:01 +0500 Subject: [PATCH 300/497] Removed xrSASH benchmark (closes #1083) 1. It was using OpenAutomate and I'm not sure about licensing of this library 2. We need to think on implementing some in-game benchmarking tool that can be run using just a console command or a button inside the in-game editor --- .gitmodules | 3 - Externals/OpenAutomate | 1 - Externals/oalib.vcxproj | 41 - src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj | 5 +- src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj | 3 - src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj | 3 - src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj | 3 - src/engine.sln | 35 - src/xrEngine/CMakeLists.txt | 9 - src/xrEngine/Engine.cpp | 3 - src/xrEngine/FDemoPlay.cpp | 17 +- src/xrEngine/device.cpp | 13 +- src/xrEngine/main.cpp | 72 -- src/xrEngine/x_ray.cpp | 12 +- src/xrEngine/xrEngine.vcxproj | 6 - src/xrEngine/xrEngine.vcxproj.filters | 12 - src/xrEngine/xrSASH.cpp | 761 ------------------- src/xrEngine/xrSASH.h | 86 --- src/xrEngine/xr_ioc_cmd.cpp | 4 - src/xrGame/GamePersistent.cpp | 3 +- 20 files changed, 11 insertions(+), 1081 deletions(-) delete mode 160000 Externals/OpenAutomate delete mode 100644 Externals/oalib.vcxproj delete mode 100644 src/xrEngine/main.cpp delete mode 100644 src/xrEngine/xrSASH.cpp delete mode 100644 src/xrEngine/xrSASH.h diff --git a/.gitmodules b/.gitmodules index 68228e269d0..e0b9e0abb38 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,9 +28,6 @@ [submodule "Externals/cryptopp"] path = Externals/cryptopp url = https://github.com/weidai11/cryptopp.git -[submodule "Externals/OpenAutomate"] - path = Externals/OpenAutomate - url = https://github.com/OpenXRay/OpenAutomate.git [submodule "Externals/gli"] path = Externals/gli url = https://github.com/g-truc/gli.git diff --git a/Externals/OpenAutomate b/Externals/OpenAutomate deleted file mode 160000 index 9ee089894c6..00000000000 --- a/Externals/OpenAutomate +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9ee089894c6d403aba5968ce1c8c26578b8e2b0a diff --git a/Externals/oalib.vcxproj b/Externals/oalib.vcxproj deleted file mode 100644 index 33f2b212cd3..00000000000 --- a/Externals/oalib.vcxproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - {61D4856F-FA82-4F02-BB88-909DDFB1FE74} - oalib - Win32Proj - - - - - - - StaticLibrary - - - - - - - - - - - NotUsing - TurnOffAllWarnings - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj index c6433d8ddaf..65400ac586b 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj @@ -30,7 +30,7 @@ /bigobj %(AdditionalOptions) - opengl32.lib;glew32s.lib;glu32.lib;oalib.lib;nvapi$(PlatformArchitecture).lib;amd_ags_$(PlatformShortName).lib;%(AdditionalDependencies) + opengl32.lib;glew32s.lib;glu32.lib;nvapi$(PlatformArchitecture).lib;amd_ags_$(PlatformShortName).lib;%(AdditionalDependencies) $(xrExternals)OpenAutomate\libraries;$(xrExternals)AGS_SDK\ags_lib\lib;%(AdditionalLibraryDirectories) $(xrExternals)nvapi\x86;%(AdditionalLibraryDirectories) $(xrExternals)nvapi\amd64;%(AdditionalLibraryDirectories) @@ -380,9 +380,6 @@ {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - {61d4856f-fa82-4f02-bb88-909ddfb1fe74} - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj index 9d36ac0de5c..489a7a4094b 100644 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj +++ b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj @@ -363,9 +363,6 @@ {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - {61d4856f-fa82-4f02-bb88-909ddfb1fe74} - {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj index 1394f9a7511..467e502e9ff 100644 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj +++ b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj @@ -408,9 +408,6 @@ {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - {61d4856f-fa82-4f02-bb88-909ddfb1fe74} - {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj index 74b76367a31..8c818bc2ea6 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj @@ -471,9 +471,6 @@ {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - {61d4856f-fa82-4f02-bb88-909ddfb1fe74} - {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} diff --git a/src/engine.sln b/src/engine.sln index 49994fab5c9..3b6f1c43ae8 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -92,8 +92,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvorbisfile", "..\Externa EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BugTrap", "..\Externals\BugTrap.vcxproj", "{E8CF1ADA-264A-4127-86C2-FD7057D3792C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oalib", "..\Externals\oalib.vcxproj", "{61D4856F-FA82-4F02-BB88-909DDFB1FE74}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "..\Externals\cryptlib.vcxproj", "{C39F4B46-6E89-4074-902E-CA57073044D2}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{B5A3098C-C768-45FF-8B6C-1F707C0344F0}" @@ -1261,38 +1259,6 @@ Global {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x64.Build.0 = Release|x64 {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x86.ActiveCfg = Release|Win32 {E8CF1ADA-264A-4127-86C2-FD7057D3792C}.Release|x86.Build.0 = Release|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM.ActiveCfg = Debug|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM.Build.0 = Debug|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM64.ActiveCfg = Debug|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|ARM64.Build.0 = Debug|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|x64.ActiveCfg = Debug|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|x64.Build.0 = Debug|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|x86.ActiveCfg = Debug|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Debug|x86.Build.0 = Debug|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|ARM.ActiveCfg = Mixed|ARM - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|ARM.Build.0 = Mixed|ARM - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|x64.ActiveCfg = Mixed|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|x64.Build.0 = Mixed|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|x86.ActiveCfg = Mixed|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Mixed|x86.Build.0 = Mixed|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|ARM.ActiveCfg = Release|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|ARM.Build.0 = Release|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|ARM64.ActiveCfg = Release|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|ARM64.Build.0 = Release|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|x64.ActiveCfg = Release|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|x64.Build.0 = Release|x64 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|x86.ActiveCfg = Release|Win32 - {61D4856F-FA82-4F02-BB88-909DDFB1FE74}.Release|x86.Build.0 = Release|Win32 {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|ARM.ActiveCfg = Debug|Win32 {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|ARM.Build.0 = Debug|Win32 {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1733,7 +1699,6 @@ Global {3A214E06-B95E-4D61-A291-1F8DF2EC10FD} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {CEBDE98B-A6AA-46E6-BC79-FAAF823DB9EC} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {E8CF1ADA-264A-4127-86C2-FD7057D3792C} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} - {61D4856F-FA82-4F02-BB88-909DDFB1FE74} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {C39F4B46-6E89-4074-902E-CA57073044D2} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {B5A3098C-C768-45FF-8B6C-1F707C0344F0} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {7885CF3C-EE04-4C67-9467-1FBF9A36B037} = {49438080-78B8-4056-BDCB-4DACAD652C21} diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index c9b60f8a476..3bc9c26b077 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -236,7 +236,6 @@ target_sources_grouped( defines.cpp defines.h embedded_resources_management.h - main.cpp mp_logging.h stdafx.cpp stdafx.h @@ -309,14 +308,6 @@ target_sources_grouped( xrSheduler.h ) -target_sources_grouped( - TARGET xrEngine - NAME "OpenAutomate" - FILES - xrSASH.cpp - xrSASH.h -) - target_sources_grouped( TARGET xrEngine NAME "Render\\Execution & 3D" diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index b0a53998377..43f0be16114 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -5,7 +5,6 @@ #include "stdafx.h" #include "Engine.h" -#include "xrSASH.h" #include "XR_IOConsole.h" #include "xr_ioc_cmd.h" @@ -102,8 +101,6 @@ void CEngine::OnEvent(EVENT E, u64 P1, u64 P2) if (pInput != nullptr) pInput->GrabInput(false); - g_SASH.EndBenchmark(); - SDL_Event quit = { SDL_QUIT }; SDL_PushEvent(&quit); } diff --git a/src/xrEngine/FDemoPlay.cpp b/src/xrEngine/FDemoPlay.cpp index 13639fc51d4..3dc0800bb83 100644 --- a/src/xrEngine/FDemoPlay.cpp +++ b/src/xrEngine/FDemoPlay.cpp @@ -10,8 +10,6 @@ #include "Render.h" #include "CameraManager.h" -#include "xrSASH.h" - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -22,7 +20,7 @@ CDemoPlay::CDemoPlay(const char* name, float ms, u32 cycles, float life_time) Msg("*** Playing demo: %s", name); Console->Execute("hud_weapon 0"); - if (g_bBenchmark || g_SASH.IsRunning()) + if (g_bBenchmark) Console->Execute("hud_draw 0"); fSpeed = ms; @@ -76,7 +74,7 @@ CDemoPlay::~CDemoPlay() xr_delete(m_pMotion); xr_delete(m_MParam); Console->Execute("hud_weapon 1"); - if (g_bBenchmark || g_SASH.IsRunning()) + if (g_bBenchmark) Console->Execute("hud_draw 1"); } @@ -101,8 +99,6 @@ void CDemoPlay::stat_Stop() if (!stat_started) return; - // g_SASH.EndBenchmark(); - stat_started = false; float stat_total = stat_Timer_total.GetElapsed_sec(); @@ -226,15 +222,8 @@ bool CDemoPlay::ProcessCam(SCamEffectorInfo& info) if (Device.dwPrecacheFrame) return true; - if (stat_started) - { - // g_SASH.DisplayFrame(Device.fTimeGlobal); - } - else - { - // g_SASH.StartBenchmark(); + if (!stat_started) stat_Start(); - } // Per-frame statistics { diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 52ff6c18b3d..3d7eef3664a 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -6,7 +6,6 @@ #include "xrCore/Threading/TaskManager.hpp" #include "xrScriptEngine/ScriptExporter.hpp" -#include "xrSASH.h" #include "XR_IOConsole.h" #include "xr_input.h" @@ -20,6 +19,9 @@ ENGINE_API CLoadScreenRenderer load_screen_renderer; ENGINE_API bool g_bRendering = false; +ENGINE_API bool g_bBenchmark = false; +string512 g_sBenchmarkName; + int ps_fps_limit = 501; int ps_fps_limit_in_menu = 60; @@ -116,12 +118,8 @@ void CRenderDevice::RenderEnd(void) } } } - g_bRendering = false; // end scene - // Present goes here, so call OA Frame end. - if (g_SASH.IsBenchmarkRunning()) - g_SASH.DisplayFrame(fTimeGlobal); - + g_bRendering = false; GEnv.Render->End(); vCameraPositionSaved = vCameraPosition; @@ -205,9 +203,6 @@ bool CRenderDevice::BeforeFrame() return false; } - if (!dwPrecacheFrame && !g_SASH.IsBenchmarkRunning() && g_bLoaded) - g_SASH.StartBenchmark(); - return true; } diff --git a/src/xrEngine/main.cpp b/src/xrEngine/main.cpp deleted file mode 100644 index 513f339a7be..00000000000 --- a/src/xrEngine/main.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "stdafx.h" - -#include "XR_IOConsole.h" -#include "xrSASH.h" - -// global variables -ENGINE_API bool g_bBenchmark = false; -string512 g_sBenchmarkName; - -namespace -{ -void RunBenchmark(pcstr name) -{ - g_bBenchmark = true; - string_path cfgPath; - FS.update_path(cfgPath, "$app_data_root$", name); - CInifile ini(cfgPath); - const u32 benchmarkCount = ini.line_count("benchmark"); - const size_t hyphenLtxLen = xr_strlen("-ltx "); - for (u32 i = 0; i < benchmarkCount; i++) - { - pcstr benchmarkName, t; - ini.r_line("benchmark", i, &benchmarkName, &t); - xr_strcpy(g_sBenchmarkName, benchmarkName); - shared_str benchmarkCommand = ini.r_string_wb("benchmark", benchmarkName); - const auto cmdSize = benchmarkCommand.size() + 1; - Core.Params = (char*)xr_realloc(Core.Params, cmdSize); - xr_strcpy(Core.Params, cmdSize, benchmarkCommand.c_str()); - xr_strlwr(Core.Params); - //InitInput(); - Engine.External.Initialize(); - //if (i) - // InitEngine(); - xr_strcpy(Console->ConfigFile, "user.ltx"); - if (strstr(Core.Params, "-ltx ")) - { - string64 cfgName; - sscanf(strstr(Core.Params, "-ltx ") + hyphenLtxLen, "%[^ ] ", cfgName); - xr_strcpy(Console->ConfigFile, cfgName); - } - //Startup(); - } -} - -bool CheckBenchmark() -{ - pcstr benchName = "-batch_benchmark "; - if (strstr(Core.Params, benchName)) - { - const size_t sz = xr_strlen(benchName); - string64 benchmarkName; - sscanf(strstr(Core.Params, benchName) + sz, "%[^ ] ", benchmarkName); - RunBenchmark(benchmarkName); - return true; - } - - pcstr sashName = "-openautomate "; - if (strstr(Core.Params, sashName)) - { - const size_t sz = xr_strlen(sashName); - string512 sashArg; - sscanf(strstr(Core.Params, sashName) + sz, "%[^ ] ", sashArg); - - if (g_SASH.Init(sashArg)) - g_SASH.MainLoop(); - - return true; - } - - return false; -} -} diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index d16c1cb3955..ef63421a4c2 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -18,7 +18,6 @@ #include "IGame_Persistent.h" #include "LightAnimLibrary.h" #include "XR_IOConsole.h" -#include "xrSASH.h" #if defined(XR_PLATFORM_WINDOWS) #include "AccessibilityShortcuts.hpp" @@ -333,9 +332,6 @@ CApplication::CApplication(pcstr commandLine) } #endif - //if (CheckBenchmark()) - // return 0; - InitSoundDeviceList(); execUserScript(); InitSound(); @@ -372,15 +368,11 @@ CApplication::~CApplication() // Destroying destroyInput(); - if (!g_bBenchmark && !g_SASH.IsRunning()) - destroySettings(); + destroySettings(); LALib.OnDestroy(); - if (!g_bBenchmark && !g_SASH.IsRunning()) - destroyConsole(); - else - Console->Destroy(); + destroyConsole(); Device.CleanupVideoModes(); Device.DestroyImGui(); diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index c57ec30fd0a..ebce9a5f093 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -98,7 +98,6 @@ - @@ -180,7 +179,6 @@ - @@ -195,7 +193,6 @@ - @@ -228,9 +225,6 @@ {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - {61d4856f-fa82-4f02-bb88-909ddfb1fe74} - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 8960715ae4f..58867d8bba0 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -121,9 +121,6 @@ {e23b35a1-652e-47bb-8941-1653504cd776} - - {fe56b488-34f8-4632-9f5e-7805f761b338} - {6e4e4f2d-02fc-4141-9ae3-ca29550fc16d} @@ -336,9 +333,6 @@ Engine\text_editor\edit_actions - - OpenAutomate - Render\Font output @@ -404,9 +398,6 @@ General - - General - Interfaces\Input @@ -569,9 +560,6 @@ Engine\text_editor\edit_actions - - OpenAutomate - Game API\Level diff --git a/src/xrEngine/xrSASH.cpp b/src/xrEngine/xrSASH.cpp deleted file mode 100644 index d1dd322a35f..00000000000 --- a/src/xrEngine/xrSASH.cpp +++ /dev/null @@ -1,761 +0,0 @@ -#include "stdafx.h" -#include "xrSASH.h" - -#include "XR_IOConsole.h" -#include "xr_ioc_cmd.h" - -xrSASH ENGINE_API g_SASH; - -xrSASH::~xrSASH() -{ - VERIFY(!m_bRunning); - VERIFY(!m_bBenchmarkRunning); -} - -bool xrSASH::Init(const char* pszParam) -{ -#ifdef XR_PLATFORM_WINDOWS - oaVersion ver; - oaBool res = oaInit(pszParam, &ver); - if (res) - { - m_bInited = true; - m_bOpenAutomate = true; - - Msg("oa:: Version: %d.%d.%d.%d", ver.Major, ver.Minor, ver.Minor, ver.Custom); - - return true; - } - else -#endif - { - m_bInited = true; - xr_strcpy(m_strBenchCfgName, pszParam); - Msg("oa:: Failed to init."); - Msg("oa:: Running native path."); - return false; - } -} - -void xrSASH::MainLoop() -{ - m_bRunning = true; - m_bReinitEngine = false; - -#ifdef XR_PLATFORM_WINDOWS - if (m_bOpenAutomate) - { - LoopOA(); - } - else -#endif - { - // Native benchmarks - LoopNative(); - } - - m_bRunning = false; -} - -#ifdef XR_PLATFORM_WINDOWS -void xrSASH::LoopOA() -{ - oaCommand Command; - bool bExit = false; - - while (!bExit) - { - // It must be called on the oaCommand object sent to - // oaGetNextCommand() before each call to oaGetNextCommand(). - oaInitCommand(&Command); - switch (oaGetNextCommand(&Command)) - { - /* No more commands, exit program */ - case OA_CMD_EXIT: - Msg("SASH:: Exit."); - bExit = true; - break; - - /* Run as normal */ - case OA_CMD_RUN: - // RunApp(); - // Msg("SASH:: GetCurrentOptions."); - bExit = true; - break; - - /* Enumerate all in-game options */ - case OA_CMD_GET_ALL_OPTIONS: - GetAllOptions(); - break; - - /* Return the option values currently set */ - case OA_CMD_GET_CURRENT_OPTIONS: - GetCurrentOptions(); - break; - - /* Set all in-game options */ - case OA_CMD_SET_OPTIONS: - SetOptions(); - break; - - /* Enumerate all known benchmarks */ - case OA_CMD_GET_BENCHMARKS: - GetBenchmarks(); - break; - - /* Run benchmark */ - case OA_CMD_RUN_BENCHMARK: RunBenchmark(Command.BenchmarkName); break; - } - } -} -#endif - -void xrSASH::LoopNative() -{ - string_path in_file; - FS.update_path(in_file, "$app_data_root$", m_strBenchCfgName); - - CInifile ini(in_file); - - IReader* R = FS.r_open(in_file); - if (R) - { - FS.r_close(R); - - int test_count = ini.line_count("benchmark"); - pcstr test_name, t; - shared_str test_command; - - for (int i = 0; i < test_count; ++i) - { - ini.r_line("benchmark", i, &test_name, &t); - // xr_strcpy(g_sBenchmarkName, test_name); - - test_command = ini.r_string_wb("benchmark", test_name); - u32 cmdSize = test_command.size() + 1; - Core.Params = (char*)xr_realloc(Core.Params, cmdSize); - xr_strcpy(Core.Params, cmdSize, test_command.c_str()); - xr_strlwr(Core.Params); - - RunBenchmark(test_name); - - // Output results - ReportNative(test_name); - } - } - else - Msg("oa:: Native path can't find \"%s\" config file.", in_file); - - FlushLog(); -} - -void xrSASH::ReportNative(pcstr pszTestName) -{ - string_path fname; - xr_sprintf(fname, sizeof(fname), "%s.result", pszTestName); - FS.update_path(fname, "$app_data_root$", fname); - CInifile res(fname, false, false, true); - - // min/max/average - float fMinFps = flt_max; - float fMaxFps = flt_min; - - const u32 iWindowSize = 15; - - if (m_aFrimeTimes.size() > iWindowSize * 4) - { - for (u32 it = 0; it < m_aFrimeTimes.size() - iWindowSize; it++) - { - float fTime = 0; - - for (u32 i = 0; i < iWindowSize; ++i) - fTime += m_aFrimeTimes[it + i]; - - float fFps = iWindowSize / fTime; - if (fFps < fMinFps) - fMinFps = fFps; - if (fFps > fMaxFps) - fMaxFps = fFps; - } - } - else - { - for (u32 it = 0; it < m_aFrimeTimes.size(); it++) - { - float fFps = 1.f / m_aFrimeTimes[it]; - if (fFps < fMinFps) - fMinFps = fFps; - if (fFps > fMaxFps) - fMaxFps = fFps; - } - } - - // res.w_float ("general","test float", float(1.0f)/10.f, "dx-level required" ); - // res.w_float ("general","renderer", float(GlobalEnv.Render->get_generation())/10.f, "dx-level required" ); - // res.w_float ("general","average", rfps_average, "average for this run" ); - // res.w_float ("general","middle", rfps_middlepoint, "per-frame middle-point"); - float fTotal = 0; - float fNumFrames = 0; - for (u32 it = 0; it < m_aFrimeTimes.size(); it++) - { - string32 id; - xr_sprintf(id, sizeof(id), "%07d", it); - res.w_float("per_frame_stats", id, 1.f / m_aFrimeTimes[it]); - fTotal += m_aFrimeTimes[it]; - fNumFrames += 1; - } - - // Output statistics - res.w_float("general", "average", fNumFrames / fTotal, "average for this run"); - res.w_float("general", "min", fMinFps, "absolute (smoothed) minimum"); - res.w_float("general", "max", fMaxFps, "absolute (smoothed) maximum"); -} - -void xrSASH::StartBenchmark() -{ - if (!m_bRunning) - return; - - VERIFY(!m_bBenchmarkRunning); - - m_bBenchmarkRunning = true; -#ifdef XR_PLATFORM_WINDOWS - oaStartBenchmark(); -#endif - - if (!m_bOpenAutomate) - { - m_aFrimeTimes.clear(); - m_aFrimeTimes.reserve(1024); - m_FrameTimer.Start(); - } -} - -void xrSASH::DisplayFrame(float t) -{ - if (!m_bRunning) - return; - - VERIFY(m_bBenchmarkRunning); -#ifdef XR_PLATFORM_WINDOWS - oaDisplayFrame(t); -#endif - - if (!m_bOpenAutomate) - { - m_aFrimeTimes.push_back(m_FrameTimer.GetElapsed_sec()); - m_FrameTimer.Start(); - } -} - -void xrSASH::EndBenchmark() -{ - if (!m_bRunning) - return; - - VERIFY(m_bBenchmarkRunning); - - m_bBenchmarkRunning = false; -#ifdef XR_PLATFORM_WINDOWS - oaEndBenchmark(); -#endif -} - -#ifdef XR_PLATFORM_WINDOWS -void xrSASH::GetAllOptions() -{ - Msg("SASH:: GetAllOptions."); - TryInitEngine(); - - oaNamedOptionStruct Option; - oaInitOption(&Option); - - DescribeOption("renderer", Option.Dependency); - DescribeOption("vid_mode", Option.Dependency); - DescribeOption("rs_fullscreen", Option.Dependency); - - DescribeOption("rs_vis_distance", Option.Dependency); - DescribeOption("r__geometry_lod", Option.Dependency); - DescribeOption("r__detail_density", Option.Dependency); - DescribeOption("texture_lod", Option.Dependency); - DescribeOption("r__tf_aniso", Option.Dependency); - DescribeOption("ai_use_torch_dynamic_lights", Option.Dependency); - - // r1 only - Option.Dependency.ParentName = TEXT("renderer"); - Option.Dependency.ComparisonOp = OA_COMP_OP_EQUAL; - Option.Dependency.ComparisonVal.Enum = (oaString)"renderer_r1"; - Option.Dependency.ComparisonValType = GetOptionType("renderer"); - { - DescribeOption("r__supersample", Option.Dependency); - DescribeOption("r1_no_detail_textures", Option.Dependency); - } - - // >=r2 - oaInitOption(&Option); // Reset dependency info - // Currently only equal/not equal works - // Option.Dependency.ParentName = TEXT("renderer"); - // Option.Dependency.ComparisonOp = OA_COMP_OP_GREATER_OR_EQUAL; - // Option.Dependency.ComparisonVal.Enum = TEXT("renderer_r2"); - // Option.Dependency.ComparisonValType = GetOptionType("renderer"); - { - DescribeOption("r2_sun", Option.Dependency); - DescribeOption("r2_sun_quality", Option.Dependency); - DescribeOption("r2_slight_fade", Option.Dependency); - DescribeOption("r2_ls_squality", Option.Dependency); - DescribeOption("r2_detail_bump", Option.Dependency); - } - - // >=r2.5 - // Option.Dependency.ParentName = TEXT("renderer"); - // Option.Dependency.ComparisonOp = OA_COMP_OP_GREATER_OR_EQUAL; - // Option.Dependency.ComparisonVal.Enum = TEXT("renderer_r2.5"); - // Option.Dependency.ComparisonValType = GetOptionType("renderer"); - { - DescribeOption("r2_sun_shafts", Option.Dependency); - DescribeOption("r2_ssao", Option.Dependency); - DescribeOption("r2_ssao_opt_data", Option.Dependency); - DescribeOption("r2_ssao_half_data", Option.Dependency); - DescribeOption("r2_ssao_hbao", Option.Dependency); - DescribeOption("r2_soft_water", Option.Dependency); - DescribeOption("r2_soft_particles", Option.Dependency); - DescribeOption("r2_dof_enable", Option.Dependency); - DescribeOption("r2_volumetric_lights", Option.Dependency); - DescribeOption("r2_steep_parallax", Option.Dependency); - } - - // >=r3 - // Option.Dependency.ParentName = TEXT("renderer"); - // Option.Dependency.ComparisonOp = OA_COMP_OP_GREATER_OR_EQUAL; - // Option.Dependency.ComparisonVal.Enum = TEXT("renderer_r3"); - // Option.Dependency.ComparisonValType = GetOptionType("renderer"); - { - DescribeOption("r3_dynamic_wet_surfaces", Option.Dependency); - DescribeOption("r3_volumetric_smoke", Option.Dependency); - DescribeOption("r3_gbuff_opt", Option.Dependency); - DescribeOption("r3_use_dx10_1", Option.Dependency); - DescribeOption("r3_minmax_sm", Option.Dependency); - DescribeOption("r3_msaa", Option.Dependency); - // >= 2x - // Option.Dependency.ParentName = TEXT("r3_msaa"); - // Option.Dependency.ComparisonOp = OA_COMP_OP_GREATER_OR_EQUAL; - // Option.Dependency.ComparisonVal.Enum = TEXT("2x"); - // Option.Dependency.ComparisonValType = GetOptionType("r3_msaa"); - { - DescribeOption("r3_msaa_opt", Option.Dependency); - DescribeOption("r3_msaa_alphatest", Option.Dependency); - } - } - - ReleaseEngine(); -} - -void xrSASH::GetCurrentOptions() -{ - Msg("SASH:: GetCurrentOptions."); - TryInitEngine(); - - GetOption("renderer"); - GetOption("vid_mode"); - GetOption("rs_fullscreen"); - - GetOption("rs_vis_distance"); - GetOption("r__geometry_lod"); - GetOption("r__detail_density"); - GetOption("texture_lod"); - GetOption("r__tf_aniso"); - GetOption("ai_use_torch_dynamic_lights"); - - // r1 only - GetOption("r__supersample"); - GetOption("r1_no_detail_textures"); - - // >=r2 - GetOption("r2_sun"); - GetOption("r2_sun_quality"); - GetOption("r2_slight_fade"); - GetOption("r2_ls_squality"); - GetOption("r2_detail_bump"); - - // >=r2.5 - GetOption("r2_sun_shafts"); - GetOption("r2_ssao"); - GetOption("r2_ssao_opt_data"); - GetOption("r2_ssao_half_data"); - GetOption("r2_ssao_hbao"); - GetOption("r2_soft_water"); - GetOption("r2_soft_particles"); - GetOption("r2_dof_enable"); - GetOption("r2_volumetric_lights"); - GetOption("r2_steep_parallax"); - - // >=r3 - GetOption("r3_dynamic_wet_surfaces"); - GetOption("r3_volumetric_smoke"); - GetOption("r3_use_dx10_1"); - GetOption("r3_minmax_sm"); - GetOption("r3_msaa"); - GetOption("r3_msaa_opt"); - GetOption("r3_msaa_alphatest"); - GetOption("r3_gbuff_opt"); - - ReleaseEngine(); -} - -void xrSASH::SetOptions() -{ - Msg("SASH:: SetOptions."); - TryInitEngine(); - - oaNamedOption* Option; - - while ((Option = oaGetNextOption()) != NULL) - SetOption(Option); - - // Console->Save(); - Console->Execute("cfg_save"); - - ReleaseEngine(); -} - -void xrSASH::GetBenchmarks() -{ - Msg("SASH:: GetBenchmarks."); - /* foreach known available benchmark */ - { - /* Set BenchmarkName to a unique string identifying the benchmark */ - - oaAddBenchmark(TEXT("dummy")); - // sashAddBenchmark(TEXT("crates")); - // sashAddBenchmark(TEXT("map1")); - } -} -#endif - -void xrSASH::RunBenchmark(pcstr pszName) -{ - Msg("SASH:: RunBenchmark."); - - TryInitEngine(false); - - //Startup(); - - m_bReinitEngine = true; - - // no need to release engine. Startup will close everything itself. -} - -void xrSASH::TryInitEngine(bool bNoRun) -{ - if (m_bReinitEngine) - { - //InitEngine(); - // It was destroyed on previous exit - Console->Initialize(); - } - - xr_strcpy(Console->ConfigFile, "user.ltx"); - if (strstr(Core.Params, "-ltx ")) - { - string64 c_name; - sscanf(strstr(Core.Params, "-ltx ") + 5, "%[^ ] ", c_name); - xr_strcpy(Console->ConfigFile, c_name); - } - - if (strstr(Core.Params, "-gl")) - Console->Execute("renderer renderer_gl"); - else if (strstr(Core.Params, "-r4")) - Console->Execute("renderer renderer_r4"); - else if (strstr(Core.Params, "-r3")) - Console->Execute("renderer renderer_r3"); - else if (strstr(Core.Params, "-r2.5")) - Console->Execute("renderer renderer_r2.5"); - else if (strstr(Core.Params, "-r2a")) - Console->Execute("renderer renderer_r2a"); - else if (strstr(Core.Params, "-r2")) - Console->Execute("renderer renderer_r2"); - else - { - CCC_LoadCFG_custom* pTmp = xr_new("renderer "); - pTmp->Execute(Console->ConfigFile); - if (m_bOpenAutomate) - pTmp->Execute("SASH.ltx"); - else - pTmp->Execute(Console->ConfigFile); - xr_delete(pTmp); - } - - //InitInput(); - - Engine.External.Initialize(); - - //if (bNoRun) - // InitSoundDeviceList(); - - Console->Execute("unbindall"); - Console->ExecuteScript(Console->ConfigFile); - if (m_bOpenAutomate) - { - // Overwrite setting using SASH.ltx if has any. - xr_strcpy(Console->ConfigFile, "SASH.ltx"); - Console->ExecuteScript(Console->ConfigFile); - } - - if (bNoRun) - { - //InitSound(); - Device.Create(); - } -} - -void xrSASH::ReleaseEngine() -{ - m_bReinitEngine = true; - - //destroyInput(); - Console->Destroy(); - Device.CleanupVideoModes(); - //destroySound(); - //destroyEngine(); -} - -#ifdef XR_PLATFORM_WINDOWS -oaOptionDataType xrSASH::GetOptionType(pcstr pszOptionName) -{ - CConsole::vecCMD_IT I = Console->Commands.find(pszOptionName); - if (I == Console->Commands.end()) - { - Msg("SASH:: Option \"%s\" not found.", pszOptionName); - VERIFY(I != Console->Commands.end()); - return OA_TYPE_BOOL; - } - - IConsole_Command* pCmd = I->second; - CCC_Mask* pMask = dynamic_cast(pCmd); - CCC_Token* pToken = dynamic_cast(pCmd); - CCC_Float* pFloat = dynamic_cast(pCmd); - CCC_Integer* pInt = dynamic_cast(pCmd); - - if (pMask) - return OA_TYPE_BOOL; - else if (pToken) - return OA_TYPE_ENUM; - else if (pFloat) - return OA_TYPE_FLOAT; - else if (pInt) - return OA_TYPE_INT; - else - { - VERIFY(!"Unsupported console command type."); - return OA_TYPE_BOOL; - } -} - -void xrSASH::DescribeOption(pcstr pszOptionName, const oaOptionDependency& Dependency) -{ - oaNamedOptionStruct Option; - oaInitOption(&Option); - - Option.Dependency = Dependency; - - CConsole::vecCMD_IT I = Console->Commands.find(pszOptionName); - if (I == Console->Commands.end()) - { - Msg("SASH:: Option \"%s\" not found.", pszOptionName); - VERIFY(I != Console->Commands.end()); - return; - } - - IConsole_Command* pCmd = I->second; - CCC_Mask* pMask = dynamic_cast(pCmd); - CCC_Token* pToken = dynamic_cast(pCmd); - CCC_Float* pFloat = dynamic_cast(pCmd); - CCC_Integer* pInt = dynamic_cast(pCmd); - - Option.Name = pszOptionName; - - Msg("SASH:: Registering option \"%s\".", pszOptionName); - - if (pMask) - { - Option.DataType = OA_TYPE_BOOL; - oaAddOption(&Option); - } - else if (pToken) - { - Option.DataType = OA_TYPE_ENUM; - const xr_token* pXRToken = pToken->GetToken(); - - while (pXRToken->name) - { - Option.Value.Enum = (char*)pXRToken->name; - oaAddOption(&Option); - ++pXRToken; - } - } - else if (pFloat) - { - Option.DataType = OA_TYPE_FLOAT; - float mn, mx; - - pFloat->GetBounds(mn, mx); - Option.MinValue.Float = mn; - Option.MaxValue.Float = mx; - Option.NumSteps = (int)((mx - mn) / 0.1f); - oaAddOption(&Option); - } - else if (pInt) - { - Option.DataType = OA_TYPE_INT; - int mn, mx; - pInt->GetBounds(mn, mx); - Option.MinValue.Int = mn; - Option.MaxValue.Int = mx; - oaAddOption(&Option); - } - else - { - VERIFY(!"Unsupported console command type."); - } -} - -void xrSASH::GetOption(pcstr pszOptionName) -{ - oaValue Val; - - CConsole::vecCMD_IT I = Console->Commands.find(pszOptionName); - if (I == Console->Commands.end()) - { - Msg("SASH:: Option \"%s\" not found.", pszOptionName); - VERIFY(I != Console->Commands.end()); - return; - } - - IConsole_Command* pCmd = I->second; - CCC_Mask* pMask = dynamic_cast(pCmd); - CCC_Token* pToken = dynamic_cast(pCmd); - CCC_Float* pFloat = dynamic_cast(pCmd); - CCC_Integer* pInt = dynamic_cast(pCmd); - - Msg("SASH:: Getting option \"%s\".", pszOptionName); - - if (pMask) - { - Val.Bool = pMask->GetValue() ? OA_TRUE : OA_FALSE; - oaAddOptionValue(pszOptionName, OA_TYPE_BOOL, &Val); - } - else if (pToken) - { - IConsole_Command::TStatus stat; - pToken->GetStatus(stat); - Val.Enum = stat; - oaAddOptionValue(pszOptionName, OA_TYPE_ENUM, &Val); - } - else if (pFloat) - { - Val.Float = pFloat->GetValue(); - oaAddOptionValue(pszOptionName, OA_TYPE_FLOAT, &Val); - } - else if (pInt) - { - Val.Int = pInt->GetValue(); - oaAddOptionValue(pszOptionName, OA_TYPE_INT, &Val); - } - else - { - VERIFY(!"Unsupported console command type."); - } -} - -void xrSASH::SetOption(oaNamedOption* pOption) -{ - /* - * Set option value to persist for subsequent runs of the game - * to the given value. Option->Name will be the name of the value, - * and Option->Value will contain the appropriate value. - */ - CConsole::vecCMD_IT I = Console->Commands.find(pOption->Name); - if (I == Console->Commands.end()) - { - Msg("SASH:: Option \"%s\" not found.", pOption->Name); - VERIFY(I != Console->Commands.end()); - return; - } - - IConsole_Command* pCmd = I->second; - CCC_Mask* pMask = dynamic_cast(pCmd); - CCC_Token* pToken = dynamic_cast(pCmd); - CCC_Float* pFloat = dynamic_cast(pCmd); - CCC_Integer* pInt = dynamic_cast(pCmd); - - Msg("SASH:: Setting option \"%s\".", pOption->Name); - - string512 CmdBuf; - - if (pMask) - { - xr_sprintf(CmdBuf, "%s %s", pOption->Name, (pOption->Value.Bool ? "1" : "0")); - } - else if (pToken) - { - xr_sprintf(CmdBuf, "%s %s", pOption->Name, pOption->Value.Enum); - } - else if (pFloat) - { - xr_sprintf(CmdBuf, "%s %f", pOption->Name, pOption->Value.Float); - } - else if (pInt) - { - xr_sprintf(CmdBuf, "%s %d", pOption->Name, pOption->Value.Int); - } - else - { - VERIFY(!"Unsupported console command type."); - } - - m_bExecutingConsoleCommand = true; - Console->Execute(CmdBuf); - m_bExecutingConsoleCommand = false; -} - -void xrSASH::Message(oaErrorType MessageType, const char* pszMsg) -{ - VERIFY(m_bInited); - - oaMessage Message; - oaInitMessage(&Message); - Message.Error = MessageType; - Message.Message = pszMsg; - oaSendSignal(OA_SIGNAL_ERROR, &Message); -} - -void xrSASH::Message(oaErrorType MessageType, const char* pszMsg, va_list& mark) -{ - VERIFY(m_bInited); - - string2048 buf; - int sz = _vsnprintf(buf, sizeof(buf) - 1, pszMsg, mark); - buf[sizeof(buf) - 1] = 0; - - if (sz) - Message(MessageType, buf); -} -#endif - -void xrSASH::OnConsoleInvalidSyntax(bool bLastLine, const char* pszMsg, ...) -{ -#ifdef XR_PLATFORM_WINDOWS - if (m_bInited && m_bExecutingConsoleCommand) - { - va_list mark; - va_start(mark, pszMsg); - - if (bLastLine) - Message(OA_ERROR_INVALID_OPTION_VALUE, pszMsg, mark); - else - Message(OA_ERROR_LOG, pszMsg, mark); - - va_end(mark); - } -#endif -} diff --git a/src/xrEngine/xrSASH.h b/src/xrEngine/xrSASH.h deleted file mode 100644 index 3fcf7a1e0a0..00000000000 --- a/src/xrEngine/xrSASH.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#ifdef XR_PLATFORM_WINDOWS -#include - -// struct oaOptionDependencyStruct; -// typedef struct oaOptionDependencyStruct oaOptionDependency; - -// struct oaNamedOptionStruct; -// typedef struct oaNamedOptionStruct oaNamedOption; -#endif - -class ENGINE_API xrSASH -{ -public: - ~xrSASH(); - - // Execution control - bool Init(const char* pszParam); - void MainLoop(); - - bool IsRunning() { return m_bRunning; } - bool IsBenchmarkRunning() { return m_bBenchmarkRunning; } - - // Event handlers - void StartBenchmark(); - void DisplayFrame(float t); - void EndBenchmark(); - - // Error report - void OnConsoleInvalidSyntax(bool bLastLine, const char* pszMsg, ...); - -private: - // Internal loops -#ifdef XR_PLATFORM_WINDOWS - void LoopOA(); -#endif - void LoopNative(); - - // Native specific - void ReportNative(pcstr pszTestName); - -#ifdef XR_PLATFORM_WINDOWS - // OA command handlers - void GetAllOptions(); - void GetCurrentOptions(); - void SetOptions(); - void GetBenchmarks(); -#endif - - void RunBenchmark(pcstr pszName); - - // Effectively restores/releases some engine systems - void TryInitEngine(bool bNoRun = true); - void ReleaseEngine(); - -#ifdef XR_PLATFORM_WINDOWS - // OA option handling - void DescribeOption(pcstr pszOptionName, const oaOptionDependency& Dependency); - oaOptionDataType GetOptionType(pcstr pszOptionName); - void GetOption(pcstr pszOptionName); - void SetOption(oaNamedOption* pOption); - - // OA Error report - void Message(oaErrorType MessageType, const char* pszMsg); - void Message(oaErrorType MessageType, const char* pszMsg, va_list& mark); -#endif - -private: - // States - bool m_bInited{}; - bool m_bOpenAutomate{}; - bool m_bRunning{}; - bool m_bBenchmarkRunning{}; - bool m_bReinitEngine{}; - - // Guards - bool m_bExecutingConsoleCommand{}; // Guard to pass to OA only those command that were issued by OA - - // Native benchmarking - string64 m_strBenchCfgName; - CTimer m_FrameTimer; - xr_vector m_aFrimeTimes; -}; - -extern xrSASH ENGINE_API g_SASH; diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index fff4ce73556..20db9fcbfbe 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -3,7 +3,6 @@ #include "XR_IOConsole.h" #include "xr_ioc_cmd.h" -#include "xrSASH.h" #include "CameraManager.h" #include "Environment.h" @@ -28,9 +27,6 @@ void IConsole_Command::InvalidSyntax() Info(I); Msg("~ Invalid syntax in call to '%s'", cName); Msg("~ Valid arguments: %s", I); - - g_SASH.OnConsoleInvalidSyntax(false, "~ Invalid syntax in call to '%s'", cName); - g_SASH.OnConsoleInvalidSyntax(true, "~ Valid arguments: %s", I); } //----------------------------------------------------------------------- diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 5d713e59e57..092c0984131 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -20,7 +20,6 @@ #include "xrUICore/XML/UITextureMaster.h" -#include "xrEngine/xrSASH.h" #include "ai_space.h" #include "holder_custom.h" @@ -364,7 +363,7 @@ void CGamePersistent::WeathersUpdate() bool allow_intro() { - if ((0 != strstr(Core.Params, "-nointro")) || g_SASH.IsRunning()) + if ((0 != strstr(Core.Params, "-nointro"))) return false; return true; From bb390d88df0635239f2d7a95f8b118a9082ac48b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 25 Apr 2024 07:02:29 +0500 Subject: [PATCH 301/497] xrSound/OpenALDeviceList.cpp: moved constexpr variables into a lower scope [skip ci] Removed one unnecessary #ifdef --- src/xrSound/OpenALDeviceList.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/xrSound/OpenALDeviceList.cpp b/src/xrSound/OpenALDeviceList.cpp index 2f6c3e5a1bc..500133b21d3 100644 --- a/src/xrSound/OpenALDeviceList.cpp +++ b/src/xrSound/OpenALDeviceList.cpp @@ -29,11 +29,6 @@ #include #include -#ifdef XR_PLATFORM_WINDOWS -constexpr pcstr AL_GENERIC_HARDWARE = "Generic Hardware"; -constexpr pcstr AL_GENERIC_SOFTWARE = "Generic Software"; -#endif - ALDeviceList::ALDeviceList() { snd_device_id = (u32)-1; @@ -124,6 +119,9 @@ void ALDeviceList::Enumerate() // Also we assume that if "Generic Hardware" exists, than "Generic Software" is also exists // Maybe wrong + constexpr pcstr AL_GENERIC_HARDWARE = "Generic Hardware"; + constexpr pcstr AL_GENERIC_SOFTWARE = "Generic Software"; + if (0 == xr_stricmp(m_defaultDeviceName, AL_GENERIC_HARDWARE)) { xr_strcpy(m_defaultDeviceName, AL_GENERIC_SOFTWARE); From 9dfa60ac7807d2a9797be176058478940221f2e5 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 26 Apr 2024 15:49:37 +0500 Subject: [PATCH 302/497] Fix crash on game exit (might be related to #1452) --- src/xrCore/LocatorAPI.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrCore/LocatorAPI.cpp b/src/xrCore/LocatorAPI.cpp index 6d53698fb44..4e960b2778e 100644 --- a/src/xrCore/LocatorAPI.cpp +++ b/src/xrCore/LocatorAPI.cpp @@ -183,7 +183,6 @@ CLocatorAPI::CLocatorAPI() : CLocatorAPI::~CLocatorAPI() { VERIFY(0 == m_iLockRescan); - _dump_open_files(1); xr_delete(m_auth_lock); } @@ -1052,8 +1051,6 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) void CLocatorAPI::_destroy() { - CloseLog(); - for (auto& it : m_files) { auto str = pstr(it.name); @@ -1075,6 +1072,9 @@ void CLocatorAPI::_destroy() it.close(); } m_archives.clear(); + + _dump_open_files(1); + CloseLog(); } const CLocatorAPI::file* CLocatorAPI::GetFileDesc(pcstr path) From 15c7a6cc25beec865c9c590a0711b1786198ab25 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 26 Apr 2024 15:51:18 +0500 Subject: [PATCH 303/497] xrCore/xrCore.cpp: assign unique_ptr to nullptr instead of calling reset() [skip ci] Just make it more explicit --- src/xrCore/xrCore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index e6cbd62b0bf..a30d15bdf54 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -327,8 +327,8 @@ void xrCore::_destroy() { FS._destroy(); EFS._destroy(); - xr_FS.reset(); - xr_EFS.reset(); + xr_FS = nullptr; + xr_EFS = nullptr; if (trained_model) { From 814ce8310e860045c15cde759c4e86a683c74468 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 29 Apr 2024 17:39:34 +0500 Subject: [PATCH 304/497] Removed CompressionTest and ctool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't use them anyway. I'm not sure if they will be useful in future – what if we will replace DirectPlay with other networking library and will further refactor our network data load? We could refactor even further and replace traffic compression with other libraries too. So, better to remove earlier than later in this case. In any case, we can restore ctool and CompressionTest if needed. --- src/engine.sln | 62 -- src/utils/CompressionTest/CompressionTest.cpp | 515 ------------- .../CompressionTest/CompressionTest.vcxproj | 67 -- .../CompressionTest.vcxproj.filters | 37 - src/utils/ctool/PPMT_SA.hpp | 209 ------ src/utils/ctool/PPMTrain.cpp | 701 ------------------ src/utils/ctool/ctool.cpp | 365 --------- src/utils/ctool/ctool.vcxproj | 50 -- src/utils/ctool/ctool.vcxproj.filters | 20 - 9 files changed, 2026 deletions(-) delete mode 100644 src/utils/CompressionTest/CompressionTest.cpp delete mode 100644 src/utils/CompressionTest/CompressionTest.vcxproj delete mode 100644 src/utils/CompressionTest/CompressionTest.vcxproj.filters delete mode 100644 src/utils/ctool/PPMT_SA.hpp delete mode 100644 src/utils/ctool/PPMTrain.cpp delete mode 100644 src/utils/ctool/ctool.cpp delete mode 100644 src/utils/ctool/ctool.vcxproj delete mode 100644 src/utils/ctool/ctool.vcxproj.filters diff --git a/src/engine.sln b/src/engine.sln index 3b6f1c43ae8..3ff913abb64 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -21,10 +21,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODE", "..\Externals\ODE.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrD3D9-Null", "xrD3D9-Null\xrD3D9-Null.vcxproj", "{0899B131-F1D4-4876-9BA1-67AC821DB9E1}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompressionTest", "utils\CompressionTest\CompressionTest.vcxproj", "{C961EA19-716C-4A6D-BB13-689F8FB78B01}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctool", "utils\ctool\ctool.vcxproj", "{2FAAC8BA-369F-465E-B465-2235963FD377}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCompress", "utils\xrCompress\xrCompress.vcxproj", "{EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrSE_Factory", "utils\xrSE_Factory\xrSE_Factory.vcxproj", "{3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}" @@ -246,62 +242,6 @@ Global {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x64.Build.0 = Release|x64 {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x86.ActiveCfg = Release|Win32 {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x86.Build.0 = Release|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|ARM.ActiveCfg = Debug|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|ARM.Build.0 = Debug|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|ARM64.ActiveCfg = Debug|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|ARM64.Build.0 = Debug|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|x64.ActiveCfg = Debug|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|x64.Build.0 = Debug|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|x86.ActiveCfg = Debug|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Debug|x86.Build.0 = Debug|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|ARM.ActiveCfg = Mixed|ARM - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|ARM.Build.0 = Mixed|ARM - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|x64.ActiveCfg = Mixed|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|x64.Build.0 = Mixed|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|x86.ActiveCfg = Mixed|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Mixed|x86.Build.0 = Mixed|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|ARM.ActiveCfg = Release|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|ARM.Build.0 = Release|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|ARM64.ActiveCfg = Release|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|ARM64.Build.0 = Release|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|x64.ActiveCfg = Release|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|x64.Build.0 = Release|x64 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|x86.ActiveCfg = Release|Win32 - {C961EA19-716C-4A6D-BB13-689F8FB78B01}.Release|x86.Build.0 = Release|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|ARM.ActiveCfg = Debug|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|ARM.Build.0 = Debug|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|ARM64.ActiveCfg = Debug|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|ARM64.Build.0 = Debug|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|x64.ActiveCfg = Debug|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|x64.Build.0 = Debug|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|x86.ActiveCfg = Debug|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Debug|x86.Build.0 = Debug|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|ARM.ActiveCfg = Mixed|ARM - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|ARM.Build.0 = Mixed|ARM - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|x64.ActiveCfg = Mixed|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|x64.Build.0 = Mixed|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|x86.ActiveCfg = Mixed|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Mixed|x86.Build.0 = Mixed|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|ARM.ActiveCfg = Release|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|ARM.Build.0 = Release|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|ARM64.ActiveCfg = Release|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|ARM64.Build.0 = Release|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x64.ActiveCfg = Release|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x64.Build.0 = Release|x64 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x86.ActiveCfg = Release|Win32 - {2FAAC8BA-369F-465E-B465-2235963FD377}.Release|x86.Build.0 = Release|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.ActiveCfg = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.Build.0 = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1682,8 +1622,6 @@ Global GlobalSection(NestedProjects) = preSolution {1BF75FEB-87DD-486C-880B-227987D191C2} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {3FC858CB-4888-42FF-ABC5-82DAECB59C2C} - {C961EA19-716C-4A6D-BB13-689F8FB78B01} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {2FAAC8BA-369F-465E-B465-2235963FD377} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {032A10AB-E44C-4751-A290-001EF99E664A} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} diff --git a/src/utils/CompressionTest/CompressionTest.cpp b/src/utils/CompressionTest/CompressionTest.cpp deleted file mode 100644 index 939f3a2bccb..00000000000 --- a/src/utils/CompressionTest/CompressionTest.cpp +++ /dev/null @@ -1,515 +0,0 @@ -#include -#include -#include -#include "xrCore/Compression/PPMd.h" -#include "xrCore/Compression/compression_ppmd_stream.h" - -#pragma warning(push) -#pragma warning(disable : 193 128 810) -#include "lzo/lzo1x.h" -#include "lzo/lzo1y.h" -#pragma warning(pop) - -extern compression::ppmd::stream* trained_model; - -typedef compression::ppmd::stream stream; -typedef unsigned char uint8_t; - -using namespace std; - -//============================================================================== - -class StopWatch -{ -public: - StopWatch() { ::QueryPerformanceFrequency(&_freq); } - void start() { ::QueryPerformanceCounter(&_start_time); } - void stop() { ::QueryPerformanceCounter(&_stop_time); } - double cur_time() const - { - LARGE_INTEGER t; - QueryPerformanceCounter(&t); - return ((t.QuadPart - _start_time.QuadPart) * 1000.0) / _freq.QuadPart; - } - double time() const // in milliseconds - { - return ((_stop_time.QuadPart - _start_time.QuadPart) * 1000.0) / _freq.QuadPart; - } - -private: - LARGE_INTEGER _freq; - LARGE_INTEGER _start_time; - LARGE_INTEGER _stop_time; -}; - -//------------------------------------------------------------------------------ - -void _STDCALL PrintInfo(_PPMD_FILE*, _PPMD_FILE*) {} -//------------------------------------------------------------------------------ - -struct BlockInfo -{ - unsigned size; - unsigned count; - - float min_time; - float max_time; - float avg_time; - - float min_ratio; - float max_ratio; - float avg_ratio; - - float total_time; - float total_ratio; - - BlockInfo(unsigned sz = 0) - : size(sz), count(0), min_time(1000.0f), max_time(0), avg_time(0), min_ratio(1.0f), max_ratio(0), avg_ratio(0), - total_time(0), total_ratio(0) - { - } - - class EqualSize - { - public: - EqualSize(unsigned sz) : _sz(sz) {} - bool operator()(const BlockInfo& bi) { return bi.size == this->_sz; } - private: - unsigned _sz; - }; - - static bool GreaterSize(const BlockInfo& i1, const BlockInfo& i2) { return i1.size > i2.size; } -}; - -//------------------------------------------------------------------------------ - -static const char* _DefaultMdlName = "!PPMd.mdl"; -char* _ModelData = NULL; -long _ModelDataSize = 0; - -static const u32 _SuballocatorSize = 32; -static const u32 _OrderModel = 8; -static const MR_METHOD _RestorationMethodCutOff = MRM_FREEZE; -// static const MR_METHOD _RestorationMethodCutOff = MRM_RESTART; - -static char* _LZOWrkMem = NULL; -static uint8_t* _LZO_Dict = NULL; -static unsigned _LZO_Dict_Sz = 0; -static const char* _DefaultDictName = "LZO.dic"; - -static vector _PPM_BlockInfo; -static vector _LZO_BlockInfo; -static unsigned _PPM_TotalUncompressed = 0; -static unsigned _PPM_TotalCompressed = 0; -static unsigned _LZO_TotalUncompressed = 0; -static unsigned _LZO_TotalCompressed = 0; - -//------------------------------------------------------------------------------ - -static void _InitPPM(const char* model_file = 0) -{ - if (model_file) - { - FILE* mdl = fopen(model_file, "rb"); - - if (mdl) - { - fseek(mdl, 0, SEEK_END); - - _ModelDataSize = ftell(mdl); - _ModelData = new char[_ModelDataSize]; - trained_model = xr_new(_ModelData, _ModelDataSize); - - fseek(mdl, 0, SEEK_SET); - fread(_ModelData, _ModelDataSize, 1, mdl); - fclose(mdl); - - printf("using PPMd-model trained data \"%s\"\n", model_file); - } - } - - StartSubAllocator(_SuballocatorSize); -} - -//------------------------------------------------------------------------------ - -static void _InitLZO(const char* dic_name = _DefaultDictName) -{ - lzo_init(); - _LZOWrkMem = new char[LZO1X_999_MEM_COMPRESS + 16]; - _LZOWrkMem = (char*)((std::uintptr_t)(_LZOWrkMem + 16) & (~(16 - 1))); - - FILE* dic = fopen(dic_name, "rb"); - - if (dic) - { - fseek(dic, 0, SEEK_END); - - _LZO_Dict_Sz = ftell(dic); - _LZO_Dict = new uint8_t[_LZO_Dict_Sz]; - - fseek(dic, 0, SEEK_SET); - fread(_LZO_Dict, _LZO_Dict_Sz, 1, dic); - fclose(dic); - - printf("using LZO-dict \"%s\"\n", dic_name); - } -} - -//------------------------------------------------------------------------------ -extern void save_dictionary(); - -static bool _ProcessFile_PPMd(const char* file_name) -{ - bool success = false; - FILE* file = fopen(file_name, "rb"); - - if (file) - { - // read data - - fseek(file, 0, SEEK_END); - - unsigned src_size = ftell(file); - char* src_data = new char[src_size]; - - fseek(file, 0, SEEK_SET); - fread(src_data, src_size, 1, file); - fclose(file); - - // compress it - - unsigned comp_size = src_size * 4; - char* comp_data = new char[comp_size]; - stream src(src_data, src_size); - stream dst(comp_data, comp_size); - - memset(comp_data, 0xCC, comp_size); - - StopWatch timer; - - timer.start(); - if (trained_model) - trained_model->rewind(); - EncodeFile(&dst, &src, _OrderModel, _RestorationMethodCutOff); - timer.stop(); - printf("PPMd1 : %2.0f%% %1.5fms %u->%u\n", 100.0f * float(dst.tell()) / float(src.tell()), - (float)timer.time(), src.tell(), dst.tell()); - - timer.start(); - if (trained_model) - trained_model->rewind(); - EncodeFile(&dst, &src, _OrderModel, _RestorationMethodCutOff); - timer.stop(); - printf("PPMd2 : %2.0f%% %1.5fms %u->%u\n", 100.0f * float(dst.tell()) / float(src.tell()), - (float)timer.time(), src.tell(), dst.tell()); - - timer.start(); - if (trained_model) - trained_model->rewind(); - EncodeFile(&dst, &src, _OrderModel, _RestorationMethodCutOff); - timer.stop(); - printf("PPMd3 : %2.0f%% %1.5fms %u->%u\n", 100.0f * float(dst.tell()) / float(src.tell()), - (float)timer.time(), src.tell(), dst.tell()); - - _PPM_TotalUncompressed += src.tell(); - _PPM_TotalCompressed += (dst.tell() < src.tell()) ? dst.tell() : src.tell(); - - // decompress it - - unsigned uncomp_size = src_size * 4; - char* uncomp_data = new char[uncomp_size]; - stream uncomp(uncomp_data, uncomp_size); - - memset(uncomp_data, 0xDD, uncomp_size); - - dst.rewind(); - if (trained_model) - trained_model->rewind(); - DecodeFile(&uncomp, &dst, _OrderModel, _RestorationMethodCutOff); - - // compare - - bool ok = true; - unsigned err_b = 0; - - for (const char *s = src_data, *u = uncomp_data; s != src_data + src_size; ++s, ++u) - { - if (*s != *u) - { - ok = false; - err_b = s - src_data; - break; - } - } - if (ok) - printf(" OK\n"); - else - printf(" ERROR (#%u %02X != %02X)\n", err_b, src_data[err_b] & 0xFF, uncomp_data[err_b] & 0xFF); - - success = ok; - - // update stats - - vector::iterator i = - find_if(_PPM_BlockInfo.begin(), _PPM_BlockInfo.end(), BlockInfo::EqualSize(src_size)); - - if (i == _PPM_BlockInfo.end()) - { - _PPM_BlockInfo.push_back(BlockInfo(src_size)); - i = _PPM_BlockInfo.end() - 1; - } - - ++i->count; - i->total_time += (float)timer.time(); - i->total_ratio += 100.0f * float(dst.tell()) / float(src.tell()); - - // clean-up - - delete[] uncomp_data; - delete[] comp_data; - delete[] src_data; - } // if file open - - return success; -} - -//------------------------------------------------------------------------------ - -static bool _ProcessFile_LZO(const char* file_name) -{ - bool success = false; - FILE* file = fopen(file_name, "rb"); - - if (file) - { - // read data - - fseek(file, 0, SEEK_END); - - unsigned src_size = ftell(file); - uint8_t* src_data = new uint8_t[src_size]; - - fseek(file, 0, SEEK_SET); - fread(src_data, src_size, 1, file); - fclose(file); - - // compress it - - lzo_uint comp_size = src_size * 4; - uint8_t* comp_data = new uint8_t[comp_size]; - - memset(comp_data, 0xCC, comp_size); - - StopWatch timer; - - timer.start(); - if (_LZO_Dict) - { - lzo1x_999_compress_dict(src_data, src_size, comp_data, &comp_size, _LZOWrkMem, _LZO_Dict, _LZO_Dict_Sz); - } - else - { - lzo1x_999_compress(src_data, src_size, comp_data, &comp_size, _LZOWrkMem); - } - timer.stop(); - printf("LZO : %2.0f%% %1.5fms %u->%u", 100.0f * float(comp_size) / float(src_size), (float)timer.time(), - (unsigned)src_size, (unsigned)comp_size); - - _LZO_TotalUncompressed += src_size; - _LZO_TotalCompressed += (comp_size < src_size) ? comp_size : src_size; - - // decompress it - - lzo_uint uncomp_size = src_size * 4; - uint8_t* uncomp_data = new uint8_t[uncomp_size]; - - memset(uncomp_data, 0xDD, uncomp_size); - if (_LZO_Dict) - { - lzo1x_decompress_dict_safe(comp_data, comp_size, uncomp_data, &uncomp_size, NULL, _LZO_Dict, _LZO_Dict_Sz); - } - else - { - lzo1x_decompress(comp_data, comp_size, uncomp_data, &uncomp_size, NULL); - } - - // compare - - bool ok = true; - unsigned err_b = 0; - - for (const uint8_t *s = src_data, *u = uncomp_data; s != src_data + src_size; ++s, ++u) - { - if (*s != *u) - { - ok = false; - err_b = s - src_data; - break; - } - } - if (ok) - printf(" OK\n"); - else - printf(" ERROR (#%u %02X != %02X)\n", err_b, src_data[err_b] & 0xFF, uncomp_data[err_b] & 0xFF); - - success = ok; - - // update stats - - vector::iterator i = - find_if(_LZO_BlockInfo.begin(), _LZO_BlockInfo.end(), BlockInfo::EqualSize(src_size)); - - if (i == _LZO_BlockInfo.end()) - { - _LZO_BlockInfo.push_back(BlockInfo(src_size)); - i = _LZO_BlockInfo.end() - 1; - } - - ++i->count; - i->total_time += (float)timer.time(); - i->total_ratio += 100.0f * float(comp_size) / float(src_size); - - // clean-up - - delete[] uncomp_data; - delete[] comp_data; - delete[] src_data; - } // if file open - - return success; -} - -//------------------------------------------------------------------------------ - -static bool _ProcessFile(const char* file_name) -{ - printf("\n%s\n", file_name); - return (_ProcessFile_PPMd(file_name) && _ProcessFile_LZO(file_name)); - // return _ProcessFile_LZO( file_name ); -} - -//============================================================================== -// -// entry-point here -// - -int main(int argc, char* argv[]) -{ - const char* src_name = (argc > 1) ? argv[1] : 0; - const char* mdl_name = _DefaultMdlName; - const char* dic_name = _DefaultDictName; - - for (int i = 1; i < argc; ++i) - { - const char* arg = argv[i]; - - if (arg[0] == '-' || arg[0] == '/') - { - if (!_strnicmp(arg + 1, "mdl", 3)) - mdl_name = arg + 1 + 3 + 1; - else if (!_strnicmp(arg + 1, "dic", 3)) - dic_name = arg + 1 + 3 + 1; - } - } - - if (argc > 1) - { - _InitPPM(mdl_name); - _InitLZO(dic_name); - - WIN32_FIND_DATA found_data; - HANDLE handle = ::FindFirstFile(src_name, &found_data); - - // extract dir-part of wildcard - - char dir[MAX_PATH] = "."; - const char* end = src_name + strlen(src_name) - 1; - - while (end > src_name) - { - if (*end == '\\' || *end == '/') - break; - - --end; - } - - if (*end == '\\' || *end == '/') - { - strncpy(dir, src_name, end - src_name); - dir[end - src_name] = '\0'; - } - - // process files - - if (handle != reinterpret_cast(INVALID_HANDLE_VALUE)) - { - BOOL rv = TRUE; - bool all_ok = true; - - while (rv) - { - if (!(found_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - char name[2048]; - - _snprintf(name, sizeof(name), "%s\\%s", dir, found_data.cFileName); - if (!_ProcessFile(name)) - { - all_ok = false; - break; - } - } - - rv = ::FindNextFile(handle, &found_data); - } - - if (all_ok) - printf("\nAll OK\n"); - else - printf("\nERROR(S) ocurred\n"); - } - ::FindClose(handle); - - // dump stats - - for (unsigned i = 0; i < _PPM_BlockInfo.size(); ++i) - { - _PPM_BlockInfo[i].avg_ratio = _PPM_BlockInfo[i].total_ratio / _PPM_BlockInfo[i].count; - _PPM_BlockInfo[i].avg_time = _PPM_BlockInfo[i].total_time / _PPM_BlockInfo[i].count; - } - sort(_PPM_BlockInfo.begin(), _PPM_BlockInfo.end(), BlockInfo::GreaterSize); - - for (unsigned i = 0; i < _LZO_BlockInfo.size(); ++i) - { - _LZO_BlockInfo[i].avg_ratio = _LZO_BlockInfo[i].total_ratio / _LZO_BlockInfo[i].count; - _LZO_BlockInfo[i].avg_time = _LZO_BlockInfo[i].total_time / _LZO_BlockInfo[i].count; - } - sort(_LZO_BlockInfo.begin(), _LZO_BlockInfo.end(), BlockInfo::GreaterSize); - - printf("\n==========\nstats:\n"); - for (unsigned i = 0; i < _PPM_BlockInfo.size(); ++i) - { - // R_ASSERT(_PPM_BlockInfo[i].size == _LZO_BlockInfo[i].size); - - printf("\n%u\n", _PPM_BlockInfo[i].size); - printf("PPM : %2.1f%% %-2.3fms\n", _PPM_BlockInfo[i].avg_ratio, _PPM_BlockInfo[i].avg_time); - printf("LZO : %2.1f%% %-2.3fms\n", _LZO_BlockInfo[i].avg_ratio, _LZO_BlockInfo[i].avg_time); - /* - printf( "%-6u : %2.1f%% %-2.3fms\n", - _PPM_BlockInfo[i].size, - _PPM_BlockInfo[i].avg_ratio, _PPM_BlockInfo[i].avg_time - ); - */ - } - - printf("\nTOTAL\n"); - printf("PPMd : %2.1f%% %u -> %u\n", 100.0f * float(_PPM_TotalCompressed) / float(_PPM_TotalUncompressed), - _PPM_TotalUncompressed, _PPM_TotalCompressed); - printf("LZO : %2.1f%% %u -> %u\n", 100.0f * float(_LZO_TotalCompressed) / float(_LZO_TotalUncompressed), - _LZO_TotalUncompressed, _LZO_TotalCompressed); - - } // if( argc > 1 ) - - return 0; -} diff --git a/src/utils/CompressionTest/CompressionTest.vcxproj b/src/utils/CompressionTest/CompressionTest.vcxproj deleted file mode 100644 index 45114a810b4..00000000000 --- a/src/utils/CompressionTest/CompressionTest.vcxproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - {C961EA19-716C-4A6D-BB13-689F8FB78B01} - CompressionTest - Win32Proj - - - - - - - Application - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - NotUsing - $(xrExternals)lzo\include;$(SolutionDir)xrCore;%(AdditionalIncludeDirectories) - - - Console - - - - - - - - - - - - - - - - - {614aa57f-58d7-45a8-a5ff-93f04b05fac6} - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - - - - - - - \ No newline at end of file diff --git a/src/utils/CompressionTest/CompressionTest.vcxproj.filters b/src/utils/CompressionTest/CompressionTest.vcxproj.filters deleted file mode 100644 index 968afca9984..00000000000 --- a/src/utils/CompressionTest/CompressionTest.vcxproj.filters +++ /dev/null @@ -1,37 +0,0 @@ - - - - - {e3decf37-2cf3-446d-97b9-495ebf775639} - - - - - PPMd - - - PPMd - - - PPMd - - - PPMd - - - PPMd - - - PPMd - - - - - - PPMd - - - - - - \ No newline at end of file diff --git a/src/utils/ctool/PPMT_SA.hpp b/src/utils/ctool/PPMT_SA.hpp deleted file mode 100644 index 3b5c9994fa2..00000000000 --- a/src/utils/ctool/PPMT_SA.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#define _FASTCALL __fastcall -#define _STDCALL __stdcall -template -inline TMP_TYPE CLAMP(const TMP_TYPE& X, const TMP_TYPE& LoX, const TMP_TYPE& HiX) -{ - return (X < LoX) ? (LoX) : ((HiX < X) ? (HiX) : (X)); -} -template -inline void SWAP(TMP_TYPE& t1, TMP_TYPE& t2) -{ - TMP_TYPE tmp = t1; - t1 = t2; - t2 = tmp; -} - -const u32 N1 = 4, N2 = 4, N3 = 4, N4 = (128 + 3 - 1 * N1 - 2 * N2 - 3 * N3) / 4; -const u32 UNIT_SIZE = 20, N_INDEXES = N1 + N2 + N3 + N4; - -#pragma pack(push, 1) -struct MEM_BLK -{ - u32 Stamp, NU; - MEM_BLK *next, *prev; - u32 Dummy; - void insertAt(MEM_BLK* p) - { - next = (prev = p)->next; - p->next = next->prev = this; - } - void remove() - { - prev->next = next; - next->prev = prev; - } -} _PACK_ATTR; -#pragma pack(pop) -static long SubAllocatorSize = 0; -static u8 Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; -static u8 *HeapStart, *pText, *UnitsStart, *LoUnit, *HiUnit; -static struct NODE -{ - NODE* next; -} FreeList[N_INDEXES]; - -inline void InsertNode(void* p, int indx) -{ - ((NODE*)p)->next = FreeList[indx].next; - FreeList[indx].next = (NODE*)p; -} -inline void* RemoveNode(int indx) -{ - NODE* RetVal = FreeList[indx].next; - FreeList[indx].next = RetVal->next; - return RetVal; -} -inline u32 U2B(int NU) { return 16 * NU + 4 * NU; } -inline void SplitBlock(void* pv, int OldIndx, int NewIndx) -{ - int i, UDiff = Indx2Units[OldIndx] - Indx2Units[NewIndx]; - u8* p = ((u8*)pv) + U2B(Indx2Units[NewIndx]); - if (Indx2Units[i = Units2Indx[UDiff - 1]] != UDiff) - { - InsertNode(p, --i); - p += U2B(i = Indx2Units[i]); - UDiff -= i; - } - InsertNode(p, Units2Indx[UDiff - 1]); -} -u32 _STDCALL GetUsedMemory() -{ - u32 i, k, RetVal = SubAllocatorSize - (HiUnit - LoUnit) - (UnitsStart - pText); - for (k = i = 0; i < N_INDEXES; i++, k = 0) - { - for (NODE* pn = FreeList + i; (pn = pn->next) != NULL; k++) - ; - RetVal -= UNIT_SIZE * Indx2Units[i] * k; - } - return (RetVal >> 2); -} -BOOL _STDCALL StartSubAllocator(int SASize) -{ - u32 t = SASize << 20; - if ((HeapStart = new u8[t]) == NULL) - return FALSE; - SubAllocatorSize = t; - return TRUE; -} -static inline void InitSubAllocator() -{ - int i, k; - memset(FreeList, 0, sizeof(FreeList)); - HiUnit = (pText = HeapStart) + SubAllocatorSize; - u32 Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7); - LoUnit = UnitsStart = HiUnit - Diff; - for (i = 0, k = 1; i < N1; i++, k += 1) - Indx2Units[i] = k; - for (k++; i < N1 + N2; i++, k += 2) - Indx2Units[i] = k; - for (k++; i < N1 + N2 + N3; i++, k += 3) - Indx2Units[i] = k; - for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) - Indx2Units[i] = k; - for (GlueCount = k = i = 0; k < 128; k++) - { - i += (Indx2Units[i] < k + 1); - Units2Indx[k] = i; - } -} -static inline void GlueFreeBlocks() -{ - MEM_BLK s0, *p, *p1; - int i, k, sz; - if (LoUnit != HiUnit) - *LoUnit = 0; - for (i = 0, s0.next = s0.prev = &s0; i < N_INDEXES; i++) - while (FreeList[i].next) - { - p = (MEM_BLK*)RemoveNode(i); - p->insertAt(&s0); - p->Stamp = ~0; - p->NU = Indx2Units[i]; - } - for (p = s0.next; p != &s0; p = p->next) - while ((p1 = p + p->NU)->Stamp == u32(~0) && p->NU + p1->NU < 0x10000) - { - p1->remove(); - p->NU += p1->NU; - } - while ((p = s0.next) != &s0) - { - for (p->remove(), sz = p->NU; sz > 128; sz -= 128, p += 128) - InsertNode(p, N_INDEXES - 1); - if (Indx2Units[i = Units2Indx[sz - 1]] != sz) - { - k = sz - Indx2Units[--i]; - InsertNode(p + (sz - k), k - 1); - } - InsertNode(p, i); - } -} -static void* AllocUnitsRare(int indx) -{ - if (!GlueCount) - { - GlueCount = 255; - GlueFreeBlocks(); - if (FreeList[indx].next) - return RemoveNode(indx); - } - int i = indx; - do - { - if (++i == N_INDEXES) - { - GlueCount--; - i = U2B(Indx2Units[indx]); - return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); - } - } while (!FreeList[i].next); - void* RetVal = RemoveNode(i); - SplitBlock(RetVal, i, indx); - return RetVal; -} -inline void* AllocUnits(int NU) -{ - int indx = Units2Indx[NU - 1]; - if (FreeList[indx].next) - return RemoveNode(indx); - void* RetVal = LoUnit; - LoUnit += U2B(Indx2Units[indx]); - if (LoUnit <= HiUnit) - return RetVal; - LoUnit -= U2B(Indx2Units[indx]); - return AllocUnitsRare(indx); -} -inline void* AllocContext() -{ - if (HiUnit != LoUnit) - return (HiUnit -= UNIT_SIZE); - if (FreeList->next) - return RemoveNode(0); - return AllocUnitsRare(0); -} -inline void* ExpandUnits(void* OldPtr, int OldNU) -{ - int i0 = Units2Indx[OldNU - 1], i1 = Units2Indx[OldNU - 1 + 1]; - if (i0 == i1) - return OldPtr; - void* ptr = AllocUnits(OldNU + 1); - if (ptr) - { - memcpy(ptr, OldPtr, U2B(OldNU)); - InsertNode(OldPtr, i0); - } - return ptr; -} -void _STDCALL PrintInfo(FILE* DecodedFile) -{ - u32 NDec = ftell(DecodedFile); - u32 UsedMemory = GetUsedMemory(); - u32 m1 = UsedMemory >> 18; - u32 m2 = (10U * (UsedMemory - (m1 << 18)) + (1 << 17)) >> 18; - if (m2 == 10) - { - m1++; - m2 = 0; - } - printf("%8d, used memory:%3d.%1dMB\r", NDec, m1, m2); -} diff --git a/src/utils/ctool/PPMTrain.cpp b/src/utils/ctool/PPMTrain.cpp deleted file mode 100644 index 6bcbb61abfe..00000000000 --- a/src/utils/ctool/PPMTrain.cpp +++ /dev/null @@ -1,701 +0,0 @@ -/**************************************************************************** - * Contents: program for the building of static PPM tree * - * (C) 2003 by Dmitry Shkarin, e-mail: dmitry.shkarin@mtu-net.ru * - * Comments: It is approximate solution. Algorithm for the building of * - * globally optimal tree is unknown, algorithm for the building of locally * - * optimal tree is too complex and memory demanding. * - ****************************************************************************/ -#include -#include -#define NOMINMAX -#include -#define XR_PLATFORM_WINDOWS -#include "xrCore/xr_types.h" -#pragma hdrstop -#include "PPMT_SA.hpp" - -const int MAX_O = 8; -const int UP_FREQ = 5, INT_BITS = 7, PERIOD_BITS = 7, TOT_BITS = INT_BITS + PERIOD_BITS, INTERVAL = 1 << INT_BITS, - BIN_SCALE = 1 << TOT_BITS, MAX_FREQ = 124; - -#pragma pack(push, 1) -static struct PPM_CONTEXT -{ - u32 EscFreq; - u16 NumStats, Dummy; - u32 SummFreq; - struct STATE - { - u8 Symbol, Flag; - u32 Freq; - PPM_CONTEXT* Successor; - } * Stats; - PPM_CONTEXT* Suffix; - inline void encodeBinSymbol(int symbol); - inline void encodeSymbol(int symbol); - PPM_CONTEXT* cutOff(int o, int ob, double b); - void clean(int o, BOOL FreqsOnly); - void write(int o, FILE* fp); - void write(int o, FILE* fp1, FILE* fp2, FILE* fp3); - inline PPM_CONTEXT* createChild(STATE* pStats, STATE& FirstState); - STATE& oneState() const { return (STATE&)Dummy; } -} * MinContext, *MaxContext; -#pragma pack(pop) - -static u8 QTable[260]; // constants -static PPM_CONTEXT::STATE* FoundState; // found next state transition -static int NumMasked, OrderFall, MaxOrder; -static u8 CharMask[256]; - -inline PPM_CONTEXT* PPM_CONTEXT::createChild(STATE* pStats, STATE& FirstState) -{ - PPM_CONTEXT* pc = (PPM_CONTEXT*)AllocContext(); - if (pc) - { - memset(pc, 0, sizeof(PPM_CONTEXT)); - pc->oneState() = FirstState; - pc->Suffix = this; - pStats->Successor = pc; - } - return pc; -} -static void _FASTCALL StartModelRare(int MaxOrder) -{ - int i, k, m, Step; - ::MaxOrder = OrderFall = MaxOrder; - InitSubAllocator(); - MinContext = MaxContext = (PPM_CONTEXT*)AllocContext(); - MinContext->Suffix = NULL; - MinContext->NumStats = 255; - FoundState = MinContext->Stats = (PPM_CONTEXT::STATE*)AllocUnits(256 / 2); - for (i = MinContext->SummFreq = MinContext->EscFreq = 0; i < 256; i++) - { - MinContext->Stats[i].Symbol = i; - MinContext->Stats[i].Freq = 0; - MinContext->Stats[i].Successor = NULL; - } - for (i = 0; i < UP_FREQ; i++) - QTable[i] = i; - for (m = i = UP_FREQ, k = Step = 1; i < 260; i++) - { - QTable[i] = m; - if (!--k) - { - k = ++Step; - m++; - } - } -} -static inline PPM_CONTEXT* CreateSuccessors(BOOL Skip, PPM_CONTEXT::STATE* p1) -{ - // static UpState declaration bypasses IntelC bug - static PPM_CONTEXT::STATE UpState; - PPM_CONTEXT *pc = MinContext, *UpBranch = FoundState->Successor; - PPM_CONTEXT::STATE *p, *ps[MAX_O], **pps = ps; - if (!Skip) - { - *pps++ = FoundState; - if (!pc->Suffix) - goto NO_LOOP; - } - if (p1) - { - p = p1; - pc = pc->Suffix; - goto LOOP_ENTRY; - } - do - { - pc = pc->Suffix; - if (pc->NumStats) - { - if ((p = pc->Stats)->Symbol != FoundState->Symbol) - do - { - p++; - } while (p->Symbol != FoundState->Symbol); - } - else - p = &(pc->oneState()); - LOOP_ENTRY: - if (p->Successor != UpBranch) - { - pc = p->Successor; - break; - } - *pps++ = p; - } while (pc->Suffix); -NO_LOOP: - if (pps == ps) - return pc; - UpState.Symbol = *(u8*)UpBranch; - UpState.Freq = UpState.Flag = 0; - UpState.Successor = (PPM_CONTEXT*)(((u8*)UpBranch) + 1); - do - { - pc = pc->createChild(*--pps, UpState); - if (!pc) - return NULL; - } while (pps != ps); - return pc; -} -static inline void UpdateModel() -{ - static PPM_CONTEXT::STATE fs; - PPM_CONTEXT::STATE* p = NULL; - fs = *FoundState; - PPM_CONTEXT *pc, *Successor; - u32 ns1; - if (!OrderFall) - { - MinContext = MaxContext = FoundState->Successor = CreateSuccessors(TRUE, p); - if (!MinContext) - goto RESTART_MODEL; - return; - } - *pText++ = fs.Symbol; - Successor = (PPM_CONTEXT*)pText; - if (pText >= UnitsStart) - goto RESTART_MODEL; - if (fs.Successor) - { - if ((u8*)fs.Successor <= pText && (fs.Successor = CreateSuccessors(FALSE, p)) == NULL) - goto RESTART_MODEL; - if (!--OrderFall) - { - Successor = fs.Successor; - pText -= (MaxContext != MinContext); - } - } - else - { - FoundState->Successor = Successor; - fs.Successor = MinContext; - } - for (pc = MaxContext; pc != MinContext; pc = pc->Suffix) - { - if ((ns1 = pc->NumStats) != 0) - { - if ((ns1 & 1) != 0) - { - pc->Stats = (PPM_CONTEXT::STATE*)ExpandUnits(pc->Stats, (ns1 + 1) >> 1); - if (!pc->Stats) - goto RESTART_MODEL; - } - } - else - { - p = (PPM_CONTEXT::STATE*)AllocUnits(1); - if (!p) - goto RESTART_MODEL; - *p = pc->oneState(); - pc->Stats = p; - pc->SummFreq = p->Freq; - pc->Dummy = 0; - } - p = pc->Stats + (++pc->NumStats); - p->Successor = Successor; - p->Symbol = fs.Symbol; - p->Freq = p->Flag = 0; - } - MaxContext = MinContext = fs.Successor; - return; -RESTART_MODEL: - printf("Out of memory!"); - exit(-1); -} -inline void PPM_CONTEXT::encodeBinSymbol(int symbol) -{ - STATE& rs = oneState(); - if (rs.Symbol == symbol) - (FoundState = &rs)->Freq++; - else - { - NumMasked = 0; - FoundState = NULL; - } -} -inline void PPM_CONTEXT::encodeSymbol(int symbol) -{ - STATE* p = Stats; - for (int i = NumStats; p->Symbol != symbol; p++) - if (--i < 0) - { - NumMasked = NumStats; - FoundState = NULL; - return; - } - (FoundState = p)->Freq++; - SummFreq++; - while (p != Stats && p[0].Freq > p[-1].Freq) - { - SWAP(p[0], p[-1]); - FoundState = --p; - } -} -static void EncodeFile2(FILE* DecodedFile) -{ - while (MaxContext->Suffix) - MaxContext = MaxContext->Suffix; - MaxContext->clean(0, TRUE); - rewind(DecodedFile); - MinContext = MaxContext; - for (int ns = MinContext->NumStats, NumBytes = 0;; ns = MinContext->NumStats) - { - int c = getc(DecodedFile); - if (ns) - MinContext->encodeSymbol(c); - else - MinContext->encodeBinSymbol(c); - while (!FoundState) - { - do - { - MinContext->EscFreq++; - MinContext = MinContext->Suffix; - if (!MinContext) - goto STOP_ENCODING; - } while (MinContext->NumStats == NumMasked); - MinContext->encodeSymbol(c); - } - if (FoundState->Successor) - MinContext = FoundState->Successor; - else - while (MinContext->Suffix != NULL) - { - MinContext = MinContext->Suffix; - if (!MinContext->NumStats) - FoundState = &(MinContext->oneState()); - else - for (FoundState = MinContext->Stats; FoundState->Symbol != c; FoundState++) - ; - if (FoundState->Successor) - { - MinContext = FoundState->Successor; - break; - } - } - MaxContext = MinContext; - if (((++NumBytes) & 0x7FFFF) == 0) - PrintInfo(DecodedFile); - } -STOP_ENCODING: - PrintInfo(DecodedFile); - printf("\n"); - while (MaxContext->Suffix) - MaxContext = MaxContext->Suffix; - MaxContext->clean(0, FALSE); -} -static void EncodeFile1(FILE* DecodedFile) -{ - for (int ns = MinContext->NumStats, NumBytes = 0;; ns = MinContext->NumStats) - { - int c = getc(DecodedFile); - if (ns) - MinContext->encodeSymbol(c); - else - MinContext->encodeBinSymbol(c); - while (!FoundState) - { - do - { - OrderFall++; - MinContext = MinContext->Suffix; - if (!MinContext) - goto STOP_ENCODING; - } while (MinContext->NumStats == NumMasked); - MinContext->encodeSymbol(c); - } - if (!OrderFall && (u8*)FoundState->Successor > pText) - MinContext = MaxContext = FoundState->Successor; - else if (UnitsStart - pText > 128 * UNIT_SIZE) - UpdateModel(); - else - break; - if (((++NumBytes) & 0x3FFFF) == 0) - PrintInfo(DecodedFile); - } -STOP_ENCODING: - PrintInfo(DecodedFile); - printf("\n"); - EncodeFile2(DecodedFile); -} -void PPM_CONTEXT::clean(int o, BOOL FreqsOnly) -{ - if (FreqsOnly) - EscFreq = SummFreq = 0; - if (!NumStats) - { - if (o != MaxOrder && (u8*)oneState().Successor >= UnitsStart) - oneState().Successor->clean(o + 1, FreqsOnly); - else if ((u8*)oneState().Successor < UnitsStart || !FreqsOnly) - oneState().Successor = NULL; - } - else - for (STATE* p = Stats; p <= Stats + NumStats; p++) - { - if (FreqsOnly) - p->Freq = 0; - if (o != MaxOrder && (u8*)p->Successor >= UnitsStart) - p->Successor->clean(o + 1, FreqsOnly); - else if ((u8*)p->Successor < UnitsStart || !FreqsOnly) - p->Successor = NULL; - } -} - -static const double MULT = 1.0 / log(2.0), COD_ERR = 0.02; -inline double GetExtraBits(double f, double e, double f1, double sf1, double sf0, int ns) -{ - double ExtraBits = f * log(f * (sf1 + f1 + f) / ((e + f) * double(f1 + f))); - if (e) - ExtraBits += e * log(e * (sf1 + f1 + f) / (sf1 * (e + f))); - if (sf0 != e) - ExtraBits += (sf0 - e) * log((sf0 + f) / sf0); - if (f1) - ExtraBits -= f1 * log((f1 + f) / f1); - ExtraBits *= MULT; - if (ns) - ExtraBits += COD_ERR * f; - else - ExtraBits -= COD_ERR * e; - return ExtraBits; -} -static u32 SizeOfModel, nc; -PPM_CONTEXT* PPM_CONTEXT::cutOff(int o, int ob, double b) -{ - STATE tmp, *p, *p1; - int ns = NumStats; - double sf0, sf1, ExtraBits; - if (o < ob) - { - if (!ns) - { - if ((p = &oneState())->Successor) - p->Successor = p->Successor->cutOff(o + 1, ob, b); - } - else - for (p = Stats + ns; p >= Stats; p--) - if (p->Successor) - p->Successor = p->Successor->cutOff(o + 1, ob, b); - return this; - } - else if (!ns) - { - p = &oneState(); - if (!Suffix->NumStats) - { - sf0 = (p1 = &(Suffix->oneState()))->Freq + (sf1 = Suffix->EscFreq); - } - else - { - for (p1 = Suffix->Stats; p->Symbol != p1->Symbol; p1++) - ; - sf0 = Suffix->SummFreq + Suffix->EscFreq; - sf1 = sf0 - p1->Freq; - } - if (!p->Successor && !p->Flag) - { - ExtraBits = GetExtraBits(p->Freq, EscFreq, p1->Freq, sf1, sf0, 0); - if (ExtraBits < b || 4 * p->Freq < EscFreq) - { - if (!Suffix->NumStats) - Suffix->oneState().Freq += p->Freq; - else - { - p1->Freq += p->Freq; - Suffix->SummFreq += p->Freq; - } - return NULL; - } - } - nc++; - SizeOfModel += 3; - p->Flag = 0; - p1->Flag = 1; - return this; - } - for (p = Stats + ns; p >= Stats; p--) - CharMask[p->Symbol] = 1; - sf0 = Suffix->SummFreq + (sf1 = Suffix->EscFreq); - for (p1 = Suffix->Stats + Suffix->NumStats; p1 >= Suffix->Stats; p1--) - if (!CharMask[p1->Symbol]) - sf1 += p1->Freq; - for (p = Stats + ns; p >= Stats; p--) - { - CharMask[p->Symbol] = 0; - if (p->Flag || p->Successor) - continue; - for (p1 = Suffix->Stats; p->Symbol != p1->Symbol; p1++) - ; - ExtraBits = GetExtraBits(p->Freq, EscFreq, p1->Freq, sf1, sf0, ns); - if (ExtraBits < b || 64 * p->Freq * (ns + 1) < SummFreq) - { - SummFreq -= p->Freq; - EscFreq += p->Freq; - p1->Freq += p->Freq; - Suffix->SummFreq += p->Freq; - sf1 += p1->Freq; - sf0 += p->Freq; - for (p1 = p; p1 != Stats + ns; p1++) - SWAP(p1[0], p1[1]); - p = Stats + ns--; - } - } - for (p = Stats + ns; p >= Stats; p--) - { - for (p1 = Suffix->Stats; p->Symbol != p1->Symbol; p1++) - ; - p->Flag = 0; - p1->Flag = 1; - } - NumStats = ns; - if (ns < 0) - return NULL; - SizeOfModel += 1 + 2 * (ns + 1); - nc++; - if (ns == 0) - { - tmp = Stats[0]; - oneState() = tmp; - } - return this; -} -void PPM_CONTEXT::write(int o, FILE* fp) -{ - STATE* p; - int f, a, b, c; - if ((int)nc < o) - nc = o; - putc(NumStats, fp); - if (!NumStats) - { - f = (p = &oneState())->Freq; - if (EscFreq) - f = (2 * f) / EscFreq; - f = CLAMP(f, 1, 127) | 0x80 * (p->Successor != NULL); - putc(f, fp); - putc(p->Symbol, fp); - if (p->Successor) - p->Successor->write(o + 1, fp); - return; - } - for (p = Stats + 1; p <= Stats + NumStats; p++) - { - if (p[0].Freq > p[-1].Freq) - { - STATE* p1 = p; - do - { - SWAP(p1[0], p1[-1]); - } while (--p1 != Stats && p1[0].Freq > p1[-1].Freq); - } - if (p[0].Freq == p[-1].Freq && p[0].Successor && !p[-1].Successor) - { - STATE* p1 = p; - do - { - SWAP(p1[0], p1[-1]); - } while (--p1 != Stats && p1[0].Freq == p1[-1].Freq && !p1[-1].Successor); - } - } - a = Stats->Freq + !Stats->Freq; - f = (64 * EscFreq + (b = a >> 1)) / a; - f = CLAMP(f, 1, 127) | 0x80 * (Stats->Successor != NULL); - putc(f, fp); - c = 64; - for (p = Stats; p <= Stats + NumStats; p++) - { - f = (64 * p->Freq + b) / a; - f += !f; - if (p != Stats) - putc((c - f) | 0x80 * (p->Successor != NULL), fp); - c = f; - putc(p->Symbol, fp); - } - for (p = Stats; p <= Stats + NumStats; p++) - if (p->Successor) - p->Successor->write(o + 1, fp); -} -void PPM_CONTEXT::write(int o, FILE* fp1, FILE* fp2, FILE* fp3) -{ - STATE *p, *p1; - int f, a, b, c, d; - if (!NumStats) - { - f = (p = &oneState())->Freq; - if (EscFreq) - f = (2 * f) / EscFreq; - putc(QTable[CLAMP(f, 1, 196) - 1] | 0x80, fp1); - if (Suffix->NumStats) - { - for (p1 = Suffix->Stats, d = 0; p1->Symbol != p->Symbol; p1++, d++) - ; - putc(d, fp2); - } - if (o < MaxOrder) - putc(p->Successor != NULL, fp3); - if (p->Successor) - p->Successor->write(o + 1, fp1, fp2, fp3); - return; - } - a = Stats->Freq + !Stats->Freq; - f = (64 * EscFreq + (b = a >> 1)) / a; - putc(QTable[CLAMP(f, 1, 196) - 1] | 0x80, fp1); - memset(CharMask, 0, sizeof(CharMask)); - c = 64; - for (p = Stats; p <= Stats + NumStats; p++) - { - f = (64 * p->Freq + b) / a; - f += !f; - if (p != Stats) - putc(c - f, fp1); - c = f; - if (!Suffix) - putc(p->Symbol, fp2); - else if (p != Stats + NumStats || NumStats != Suffix->NumStats) - { - for (p1 = Suffix->Stats, d = 0; p1->Symbol != p->Symbol; p1++) - d += !CharMask[p1->Symbol]; - putc(d, fp2); - CharMask[p->Symbol] = 1; - } - if (o < MaxOrder) - putc(p->Successor != NULL, fp3); - } - for (p = Stats; p <= Stats + NumStats; p++) - if (p->Successor) - p->Successor->write(o + 1, fp1, fp2, fp3); -} -void ShrinkModel(int MaxSize) -{ - memset(CharMask, 0, sizeof(CharMask)); - double s0 = 0.f, s1 = 0.f, b0 = 0.f, b1 = 0.f, b = 1.0; - for (int k = 0;; k++) - { - printf("b: %6.2f, ", b); - SizeOfModel = 1 + (nc = 1) + 2 * 256; - for (int i = MaxOrder; i > 0; i--) - MaxContext->cutOff(0, i, b); - printf("SizeOfModel: %7lu bytes, nc: %7lu\n", SizeOfModel, nc); - if (MaxSize >= (int)SizeOfModel) - break; - s0 = s1; - b0 = b1; - s1 = SizeOfModel; - b1 = b; - if (!k) - { - b++; - continue; - } - if (s1 != s0) - b = b0 + (b1 - b0) / (s1 - s0) * (MaxSize - s0); - else - b = b1 + 1.0; - if (b > 2.0 * b1) - b = 2.0 * b1; - else if (b < 0.5 * b1) - b = 0.5 * b1; - if (s1 < 1.25 * MaxSize) - b = 0.5 * b + 0.5 * b1; - if (b - b1 < 0.01) - b = b1 + 0.01; - } -} -void _STDCALL EncodeFile(FILE* DecodedFile, int MaxOrder, int MaxSize) -{ - StartModelRare(MaxOrder); - EncodeFile1(DecodedFile); - ShrinkModel(MaxSize); - FILE* fp = fopen("!PPMd.mdl", "wb"); - nc = 0; - putc(MaxOrder, fp); - MaxContext->write(0, fp); - fseek(fp, 0, SEEK_SET); - putc(nc, fp); - fseek(fp, 0, SEEK_END); - fclose(fp); - // FILE* fp1=fopen("!Freqs.mdl","wb"), * fp2=fopen("!PosSym.mdl","wb"), * fp3=fopen("!Flags.mdl","wb"); - // putc(nc,fp1); MaxContext->write(0,fp1,fp2,fp3); - // fclose(fp1); fclose(fp2); fclose(fp3); -} -/* -#define MAKE_FOUR_CC(ch0,ch1,ch2,ch3) \ -((u32)(u8)(ch0) | \ -((u32)(u8)(ch1) << 8) | \ -((u32)(u8)(ch2) << 16) | \ -((u32)(u8)(ch3) << 24 )) - -void _STDCALL EncodeFileChunked(FILE* DecodedFile,int MaxOrder,int MaxSize) -{ - fseek(DecodedFile, 0, SEEK_END); - - long src_sz = ftell(DecodedFile); - u8* src_data = new u8 [src_sz]; - - fseek(DecodedFile, 0, SEEK_SET); - fread( src_data, src_sz, 1, DecodedFile); - - u32 id = *((u32*)src_data); - if(id != MAKE_FOUR_CC('B','I','N','S')) - { - printf("ERROR: bad bins file format"); - fclose(DecodedFile); - delete[] src_data; - return; - } - - const u8* data = src_data + sizeof(u32); - const u8* data_end = src_data + src_sz; - unsigned count = 0; - - static char const * tmp_filename = "tmp_packet.bin"; - while( data < data_end ) - { - FILE* tmp_file = fopen(tmp_filename, "wb"); - u16 sz = *((u16*)data); - data += sizeof(u16); - fwrite(data, sz, 1, tmp_file); - data += sz; - fclose(tmp_file); - FILE* tmp_r_file = fopen(tmp_filename, "rb"); - StartModelRare(MaxOrder); - EncodeFile1(tmp_r_file); - fclose(tmp_r_file); - } - fclose(DecodedFile); - delete[] src_data; - - ShrinkModel(MaxSize); - FILE* fp=fopen("!PPMd.mdl","wb"); nc=0; - putc(MaxOrder,fp); MaxContext->write(0,fp); - fseek(fp,0,SEEK_SET); putc(nc,fp); - fseek(fp,0,SEEK_END); fclose(fp); -} -*/ - -extern int _PPM_MaxOrder; -extern int _PPM_SaSize; -extern int _PPM_ModelSize; - -int MakePPMDictionaryFromFile(FILE* raw_bins_file_src) -{ - int MaxOrder = _PPM_MaxOrder; - int SASize = _PPM_SaSize; - int ModelSize = _PPM_ModelSize; - - StartSubAllocator(SASize); - fseek(raw_bins_file_src, 0, SEEK_SET); - EncodeFile(raw_bins_file_src, MaxOrder, ModelSize * 1024); - return 0; -} - -int MakePPMDictionary(char const* file_name) -{ - FILE* fpIn = fopen(file_name, "rb"); - if (!fpIn) - return 1; - MakePPMDictionaryFromFile(fpIn); - fclose(fpIn); - return 0; -} diff --git a/src/utils/ctool/ctool.cpp b/src/utils/ctool/ctool.cpp deleted file mode 100644 index cd5ef2fa73a..00000000000 --- a/src/utils/ctool/ctool.cpp +++ /dev/null @@ -1,365 +0,0 @@ - - -#include - -#include -#include -#include -#include -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include - -#define XR_PLATFORM_WINDOWS -#include "xrCore/xr_types.h" -#undef FLT_MAX -#undef FLT_MIN - -using namespace std; - -#define MAKE_FOUR_CC(ch0, ch1, ch2, ch3)\ - ((u32)(u8)(ch0) | ((u32)(u8)(ch1) << 8) | ((u32)(u8)(ch2) << 16) | ((u32)(u8)(ch3) << 24)) - -inline bool IsEmptyString(const char* str) { return !(str && str[0] != '\0'); } -static unsigned _LZO_MinPacketSize = 8; -static unsigned _LZO_MaxPacketSize = 8 * 1024; - -int _PPM_MaxOrder = 2; -int _PPM_SaSize = 48; -int _PPM_ModelSize = 64; - -//------------------------------------------------------------------------------ - -static void _UnpackPackets(const char* src_bin, const char* dst_name = "") -{ - FILE* src_file = fopen(src_bin, "rb"); - - if (src_file) - { - // read the file - - fseek(src_file, 0, SEEK_END); - - long src_sz = ftell(src_file); - u8* src_data = new u8[src_sz]; - - fseek(src_file, 0, SEEK_SET); - fread(src_data, src_sz, 1, src_file); - fclose(src_file); - - // process parts - - u32 id = *((u32*)src_data); - - if (id == MAKE_FOUR_CC('B', 'I', 'N', 'S')) - { - const u8* data = src_data + sizeof(u32); - const u8* data_end = src_data + src_sz; - unsigned count = 0; - char bin_name[512]; - - while (data < data_end) - { - _snprintf(bin_name, sizeof(bin_name) - 1, "data-%08u.bin", count + 1); - - u16 sz = *((u16*)data); - FILE* bin = fopen(bin_name, "wb"); - - data += sizeof(u16); - fwrite(data, sz, 1, bin); - fclose(bin); - - data += sz; - ++count; - } - } - else - { - // TODO: error - } - - delete[] src_data; - } - else - { - // TODO: error here - } -} - -//============================================================================== - -struct PacketInfo -{ - PacketInfo(); - ~PacketInfo(); - - void add_data(const u8* data, unsigned data_sz); - void remove_all_data(); - - static bool WeightPredicate(const PacketInfo& p1, const PacketInfo& p2) { return p1.weight > p2.weight; } - static bool SizePredicate(const PacketInfo& p1, const PacketInfo& p2) { return p1.size > p2.size; } -public: - unsigned size; - unsigned count; - float weight; - - struct Data - { - u8* data; - unsigned size; - }; - - vector packet; -}; - -//------------------------------------------------------------------------------ - -PacketInfo::PacketInfo() : size(0), count(0), weight(0) {} -//------------------------------------------------------------------------------ - -PacketInfo::~PacketInfo() {} -//------------------------------------------------------------------------------ - -void PacketInfo::add_data(const u8* data, unsigned data_sz) -{ - if (data_sz == size) - { - packet.push_back(Data()); - - packet.back().data = new u8[data_sz]; - packet.back().size = data_sz; - memcpy(packet.back().data, data, data_sz); - - ++count; - } -} - -//------------------------------------------------------------------------------ - -void PacketInfo::remove_all_data() -{ - for (unsigned i = 0; i < packet.size(); ++i) - delete[] packet[i].data; - packet.clear(); - count = 0; -} - -//------------------------------------------------------------------------------ -extern int MakePPMDictionaryFromFile(FILE* raw_bins_file_src); -extern int MakePPMDictionary(char const* file_name); - -static void _BuildDictionary(const char* bins_file, const char* dst_name = "") -{ - vector packet_info; - unsigned total_packet_count = 0; - - FILE* src_file = fopen(bins_file, "rb"); - static char const* raw_bins_filename = "raw_bins_tmp.bin"; - FILE* raw_bins_file = fopen(raw_bins_filename, "wb"); - if (!raw_bins_file) - { - if (src_file) - fclose(src_file); - printf("ERROR: failed to create raw_bins_tmp.bin"); - return; - } - - if (src_file) - { - // read the file - - fseek(src_file, 0, SEEK_END); - - long src_sz = ftell(src_file); - u8* src_data = new u8[src_sz]; - - fseek(src_file, 0, SEEK_SET); - fread(src_data, src_sz, 1, src_file); - fclose(src_file); - - // get packet data - - u32 id = *((u32*)src_data); - - if (id == MAKE_FOUR_CC('B', 'I', 'N', 'S')) - { - const u8* data = src_data + sizeof(u32); - const u8* data_end = src_data + src_sz; - unsigned count = 0; - - while (data < data_end) - { - u16 sz = *((u16*)data); - - data += sizeof(u16); - - vector::iterator info; - - for (info = packet_info.begin(); info != packet_info.end(); ++info) - { - if (info->size == sz) - break; - } - if (info == packet_info.end()) - { - packet_info.push_back(PacketInfo()); - info = packet_info.end() - 1; - - info->size = sz; - info->count = 0; - } - - info->add_data(data, sz); - fwrite(data, sz, 1, raw_bins_file); - - data += sz; - ++total_packet_count; - } - } - else - { - printf("ERROR: Unknown file format"); - } - - delete[] src_data; - } - else - { - printf("ERROR: can't open file"); - } - - fclose(raw_bins_file); - MakePPMDictionary(raw_bins_filename); - - // dump stats by size - - for (unsigned i = 0; i < packet_info.size(); ++i) - { - packet_info[i].weight = float(packet_info[i].count) / float(total_packet_count); - } - - sort(packet_info.begin(), packet_info.end(), PacketInfo::SizePredicate); - - printf("\nsorted by size\n"); - for (unsigned i = 0; i < packet_info.size(); ++i) - { - printf("%-6u : %-4u (%2.1f%%)\n", packet_info[i].size, packet_info[i].count, packet_info[i].weight * 100.0f); - } - - // dump stats by frequency - - for (unsigned i = 0; i < packet_info.size(); ++i) - { - packet_info[i].weight = float(packet_info[i].count) / float(total_packet_count); - } - - sort(packet_info.begin(), packet_info.end(), PacketInfo::WeightPredicate); - - printf("\nsorted by frequency\n"); - - unsigned total_cnt = 0; - - for (unsigned i = 0; i < packet_info.size(); ++i) - { - printf("%-6u : %-4u (%2.1f%%)\n", packet_info[i].size, packet_info[i].count, packet_info[i].weight * 100.0f); - - total_cnt += packet_info[i].count; - } - printf("total count = %u\n", total_cnt); - - // build dictionary - - const char* dic_file = IsEmptyString(dst_name) ? "lzo.dic" : dst_name; - FILE* dic = fopen(dic_file, "wb"); - - float const lzo_dict_max_size = 5.0f * 1024; // 5 Kb - - if (dic) - { - // unsigned min_sz = 200; - // unsigned max_sz = 350; - unsigned min_sz = _LZO_MinPacketSize; - unsigned max_sz = _LZO_MaxPacketSize; - - for (unsigned i = 0; i < packet_info.size(); ++i) - { - const PacketInfo& info = packet_info[i]; - - if (info.size < min_sz || info.size > max_sz) - continue; - - /*unsigned cnt = (info.size < 32) - ? unsigned((10000.0f/float(info.size)) * info.weight) - : 1;*/ - - unsigned int n = 0; - unsigned int cnt = (unsigned int)((lzo_dict_max_size * info.weight) / info.size); - - for (unsigned p = 0, n = 0; p < cnt; ++p, ++n) - { - if (n >= info.count) - n = 0; - - fwrite(info.packet[n].data, info.packet[n].size, 1, dic); - } - } - - fclose(dic); - } - else - { - printf("ERROR: failed to create LZO dic file"); - } -} - -//============================================================================== - -int main(int argc, char* argv[]) -{ - if (argc < 2) - { - printf("usage: CTOOL [option(s)] [file(s)]\n"); - printf("commands:\n"); - printf("u -- unpack packets from .bins-file\n"); - printf("d -- build dictionary from .bins-file\n"); - return -1; - } - - int i = 2; - string dic_name; - - for (; i < argc; ++i) - { - if (argv[i][0] != '-' && argv[i][0] != '/') - break; - - if (!_strnicmp(argv[i] + 1, "dic", 3)) - dic_name = argv[i] + 1 + 3 + 1; - else if (!_strnicmp(argv[i] + 1, "min_sz", 6)) - _LZO_MinPacketSize = atoi(argv[i] + 1 + 6 + 1); - else if (!_strnicmp(argv[i] + 1, "max_sz", 6)) - _LZO_MaxPacketSize = atoi(argv[i] + 1 + 6 + 1); - else if (!_strnicmp(argv[i] + 1, "order", 5)) - _PPM_MaxOrder = atoi(argv[i] + 1 + 5 + 1); - else if (!_strnicmp(argv[i] + 1, "salloc", 6)) - _PPM_SaSize = atoi(argv[i] + 1 + 6 + 1); - else if (!_strnicmp(argv[i] + 1, "msize", 5)) - _PPM_ModelSize = atoi(argv[i] + 1 + 5 + 1); - - if (_LZO_MinPacketSize < 8) - _LZO_MinPacketSize = 8; - - if (_LZO_MaxPacketSize > 64 * 1024) - _LZO_MinPacketSize = 64 * 1024; - } - - if (i < argc) - { - if (argv[1][0] == 'u') - _UnpackPackets(argv[i]); - else if (argv[1][0] == 'd') - _BuildDictionary(argv[i], dic_name.c_str()); - } - - return 0; -} diff --git a/src/utils/ctool/ctool.vcxproj b/src/utils/ctool/ctool.vcxproj deleted file mode 100644 index d96924e542f..00000000000 --- a/src/utils/ctool/ctool.vcxproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - {2FAAC8BA-369F-465E-B465-2235963FD377} - ctool - Win32Proj - - - - - - - Application - - - - - - - - - - - $(xrBinDir)utils\ - - - - NotUsing - - - Console - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/utils/ctool/ctool.vcxproj.filters b/src/utils/ctool/ctool.vcxproj.filters deleted file mode 100644 index 8b7d1846466..00000000000 --- a/src/utils/ctool/ctool.vcxproj.filters +++ /dev/null @@ -1,20 +0,0 @@ - - - - - {441a0730-e805-4f48-b90d-1c2dcf547b8b} - - - - - PPMTrain - - - - - - - - - - \ No newline at end of file From fab8c4fcded9d9934c870a2ab9a333a2414a335b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 26 Apr 2024 22:08:46 +0500 Subject: [PATCH 305/497] xrCore/_color.h: constexprify --- src/xrCore/_color.h | 83 ++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/src/xrCore/_color.h b/src/xrCore/_color.h index 2b7dbfef4a4..b1c05fd4feb 100644 --- a/src/xrCore/_color.h +++ b/src/xrCore/_color.h @@ -58,9 +58,9 @@ struct Fcolor { float r, g, b, a; - Fcolor() noexcept = default; + constexpr Fcolor() noexcept = default; - Fcolor(float _r, float _g, float _b, float _a) noexcept + constexpr Fcolor(float _r, float _g, float _b, float _a) noexcept : r(_r), g(_g), b(_b), a(_a) {} Fcolor(u32 dw) noexcept @@ -72,7 +72,7 @@ struct Fcolor b = f * float((dw >> 0) & 0xff); } - Fcolor& set(u32 dw) noexcept + constexpr Fcolor& set(u32 dw) noexcept { constexpr float f = 1.f / 255.f; a = f * float((dw >> 24) & 0xff); @@ -82,9 +82,9 @@ struct Fcolor return *this; } - Fcolor& operator=(u32 dw) noexcept { return set(dw); } + constexpr Fcolor& operator=(u32 dw) noexcept { return set(dw); } - Fcolor& set(float _r, float _g, float _b, float _a) noexcept + constexpr Fcolor& set(float _r, float _g, float _b, float _a) noexcept { r = _r; g = _g; @@ -93,7 +93,7 @@ struct Fcolor return *this; } - Fcolor& set(const Fcolor& rhs) noexcept + constexpr Fcolor& set(const Fcolor& rhs) noexcept { r = rhs.r; g = rhs.g; @@ -101,17 +101,19 @@ struct Fcolor a = rhs.a; return *this; } + u32 get() const noexcept { return color_rgba_f(r, g, b, a); } - u32 get_windows() const noexcept // Get color as a Windows DWORD value. + + constexpr u32 get_windows() const noexcept // Get color as a Windows DWORD value. { - u8 _a, _r, _g, _b; - _a = u8(a*255.f); - _r = u8(r*255.f); - _g = u8(g*255.f); - _b = u8(b*255.f); + const u8 _a = u8(a*255.f); + const u8 _r = u8(r*255.f); + const u8 _g = u8(g*255.f); + const u8 _b = u8(b*255.f); return (u32)(_a << 24) | (_b << 16) | (_g << 8) | _r; } - Fcolor& set_windows(u32 dw) noexcept // Set color from a Windows DWORD color value. + + constexpr Fcolor& set_windows(u32 dw) noexcept // Set color from a Windows DWORD color value. { const float f = 1.0f / 255.0f; a = f * (float)(u8)(dw >> 24); @@ -120,80 +122,91 @@ struct Fcolor r = f * (float)(u8)(dw >> 0); return *this; } - Fcolor& adjust_contrast(float f) noexcept // >1 - contrast will be increased + + constexpr Fcolor& adjust_contrast(float f) noexcept // >1 - contrast will be increased { r = 0.5f + f * (r - 0.5f); g = 0.5f + f * (g - 0.5f); b = 0.5f + f * (b - 0.5f); return *this; } - Fcolor& adjust_contrast(const Fcolor& in, float f) noexcept // >1 - contrast will be increased + + constexpr Fcolor& adjust_contrast(const Fcolor& in, float f) noexcept // >1 - contrast will be increased { r = 0.5f + f * (in.r - 0.5f); g = 0.5f + f * (in.g - 0.5f); b = 0.5f + f * (in.b - 0.5f); return *this; } - Fcolor& adjust_saturation(float s) noexcept + + constexpr Fcolor& adjust_saturation(float s) noexcept { // Approximate values for each component's contribution to luminance. // Based upon the NTSC standard described in ITU-R Recommendation BT.709. - float grey = r * 0.2125f + g * 0.7154f + b * 0.0721f; + const float grey = r * 0.2125f + g * 0.7154f + b * 0.0721f; r = grey + s * (r - grey); g = grey + s * (g - grey); b = grey + s * (b - grey); return *this; } - Fcolor& adjust_saturation(const Fcolor& in, float s) noexcept + + constexpr Fcolor& adjust_saturation(const Fcolor& in, float s) noexcept { // Approximate values for each component's contribution to luminance. // Based upon the NTSC standard described in ITU-R Recommendation BT.709. - float grey = in.r*0.2125f + in.g*0.7154f + in.b*0.0721f; + const float grey = in.r*0.2125f + in.g*0.7154f + in.b*0.0721f; r = grey + s * (in.r - grey); g = grey + s * (in.g - grey); b = grey + s * (in.b - grey); return *this; } - Fcolor& modulate(Fcolor& in) noexcept { r *= in.r; g *= in.g; b *= in.b; a *= in.a; return *this; } - Fcolor& modulate(const Fcolor& in1, const Fcolor& in2) noexcept { r = in1.r*in2.r; g = in1.g*in2.g; b = in1.b*in2.b; a = in1.a*in2.a; return *this; } - Fcolor& negative(const Fcolor& in) noexcept { r = 1.0f - in.r; g = 1.0f - in.g; b = 1.0f - in.b; a = 1.0f - in.a; return *this; } - Fcolor& negative() noexcept { r = 1.0f - r; g = 1.0f - g; b = 1.0f - b; a = 1.0f - a; return *this; } - Fcolor& sub_rgb(float s) noexcept { r -= s; g -= s; b -= s; return *this; } - Fcolor& add_rgb(float s) noexcept { r += s; g += s; b += s; return *this; } - Fcolor& add_rgba(float s) noexcept { r += s; g += s; b += s; a += s; return *this; } - Fcolor& mul_rgba(float s) noexcept { r *= s; g *= s; b *= s; a *= s; return *this; } - Fcolor& mul_rgb(float s) noexcept { r *= s; g *= s; b *= s; return *this; } - Fcolor& mul_rgba(const Fcolor& c, float s) noexcept { r = c.r*s; g = c.g*s; b = c.b*s; a = c.a*s; return *this; } - Fcolor& mul_rgb(const Fcolor& c, float s) noexcept { r = c.r*s; g = c.g*s; b = c.b*s; return *this; } + + constexpr Fcolor& modulate(Fcolor& in) noexcept { r *= in.r; g *= in.g; b *= in.b; a *= in.a; return *this; } + constexpr Fcolor& modulate(const Fcolor& in1, const Fcolor& in2) noexcept { r = in1.r*in2.r; g = in1.g*in2.g; b = in1.b*in2.b; a = in1.a*in2.a; return *this; } + constexpr Fcolor& negative(const Fcolor& in) noexcept { r = 1.0f - in.r; g = 1.0f - in.g; b = 1.0f - in.b; a = 1.0f - in.a; return *this; } + constexpr Fcolor& negative() noexcept { r = 1.0f - r; g = 1.0f - g; b = 1.0f - b; a = 1.0f - a; return *this; } + constexpr Fcolor& sub_rgb(float s) noexcept { r -= s; g -= s; b -= s; return *this; } + constexpr Fcolor& add_rgb(float s) noexcept { r += s; g += s; b += s; return *this; } + constexpr Fcolor& add_rgba(float s) noexcept { r += s; g += s; b += s; a += s; return *this; } + constexpr Fcolor& mul_rgba(float s) noexcept { r *= s; g *= s; b *= s; a *= s; return *this; } + constexpr Fcolor& mul_rgb(float s) noexcept { r *= s; g *= s; b *= s; return *this; } + constexpr Fcolor& mul_rgba(const Fcolor& c, float s) noexcept { r = c.r*s; g = c.g*s; b = c.b*s; a = c.a*s; return *this; } + constexpr Fcolor& mul_rgb(const Fcolor& c, float s) noexcept { r = c.r*s; g = c.g*s; b = c.b*s; return *this; } // SQ magnitude - float magnitude_sqr_rgb() const noexcept { return r * r + g * g + b * b;} + constexpr float magnitude_sqr_rgb() const noexcept { return r * r + g * g + b * b;} + // magnitude float magnitude_rgb() const noexcept { return _sqrt(magnitude_sqr_rgb()); } - float intensity() const noexcept + + constexpr float intensity() const noexcept { // XXX: Use the component percentages from adjust_saturation()? return (r + g + b) / 3.f; } + // Normalize Fcolor& normalize_rgb() noexcept { VERIFY( magnitude_sqr_rgb() > EPS_S); return mul_rgb( 1.f / magnitude_rgb()); } Fcolor& normalize_rgb(const Fcolor& c) noexcept { VERIFY(c.magnitude_sqr_rgb() > EPS_S); return mul_rgb(c, 1.f / c.magnitude_rgb()); } - Fcolor& lerp(const Fcolor& c1, const Fcolor& c2, float t) noexcept + + constexpr Fcolor& lerp(const Fcolor& c1, const Fcolor& c2, float t) noexcept { - float invt = 1.f - t; + const float invt = 1.f - t; r = c1.r*invt + c2.r*t; g = c1.g*invt + c2.g*t; b = c1.b*invt + c2.b*t; a = c1.a*invt + c2.a*t; return *this; } - Fcolor& lerp(const Fcolor& c1, const Fcolor& c2, const Fcolor& c3, float t) noexcept + + constexpr Fcolor& lerp(const Fcolor& c1, const Fcolor& c2, const Fcolor& c3, float t) noexcept { if (t>.5f) return lerp(c2, c3, t*2.f - 1.f); else return lerp(c1, c2, t*2.f); } + bool similar_rgba(const Fcolor& v, float E = EPS_L) const noexcept { return _abs(r - v.r) < E && _abs(g - v.g) < E && _abs(b - v.b) < E && _abs(a - v.a) < E; } bool similar_rgb (const Fcolor& v, float E = EPS_L) const noexcept { return _abs(r - v.r) < E && _abs(g - v.g) < E && _abs(b - v.b) < E; } }; From c731d6dc39b7fa572ecc3261244a0aee014dfd3d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 26 Apr 2024 04:51:50 +0500 Subject: [PATCH 306/497] xrSound: constify --- src/xrSound/SoundRender_Core.h | 4 ++-- src/xrSound/SoundRender_Core_StartStop.cpp | 10 +++++----- src/xrSound/SoundRender_Emitter_FSM.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 4cc04f1a2bc..07e2e89fceb 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -131,10 +131,10 @@ class CSoundRender_Core : public ISoundManager void i_create_all_sources(); void i_destroy_source(CSoundRender_Source* S); - void i_start(CSoundRender_Emitter* E); + void i_start(CSoundRender_Emitter* E) const; void i_stop(CSoundRender_Emitter* E); void i_rewind(CSoundRender_Emitter* E); - bool i_allow_play(CSoundRender_Emitter* E); + bool i_allow_play(const CSoundRender_Emitter* E); bool i_locked() override { return isLocked; } void env_apply(); diff --git a/src/xrSound/SoundRender_Core_StartStop.cpp b/src/xrSound/SoundRender_Core_StartStop.cpp index 75a42de77fa..904e94fb46a 100644 --- a/src/xrSound/SoundRender_Core_StartStop.cpp +++ b/src/xrSound/SoundRender_Core_StartStop.cpp @@ -5,7 +5,7 @@ #include "SoundRender_Target.h" #include "SoundRender_Source.h" -void CSoundRender_Core::i_start(CSoundRender_Emitter* E) +void CSoundRender_Core::i_start(CSoundRender_Emitter* E) const { R_ASSERT(E); @@ -13,7 +13,7 @@ void CSoundRender_Core::i_start(CSoundRender_Emitter* E) float Ptest = E->priority(); float Ptarget = flt_max; CSoundRender_Target* T = nullptr; - for (auto Ttest : s_targets) + for (const auto Ttest : s_targets) { if (Ttest->priority < Ptarget) { @@ -49,11 +49,11 @@ void CSoundRender_Core::i_rewind(CSoundRender_Emitter* E) E->target->rewind(); } -bool CSoundRender_Core::i_allow_play(CSoundRender_Emitter* E) +bool CSoundRender_Core::i_allow_play(const CSoundRender_Emitter* E) { // Search available target - float Ptest = E->priority(); - return std::any_of(s_targets.begin(), s_targets.end(), [Ptest](CSoundRender_Target* target) + const float Ptest = E->priority(); + return std::any_of(s_targets.begin(), s_targets.end(), [Ptest](const CSoundRender_Target* target) { return target->priority < Ptest; }); diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index b0030246503..6c2c5737c0a 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -308,7 +308,7 @@ bool CSoundRender_Emitter::update_culling(float dt) else { // Check range - float dist = SoundRender->listener_position().distance_to(p_source.position); + const float dist = SoundRender->listener_position().distance_to(p_source.position); if (dist > p_source.max_distance) { smooth_volume = 0; @@ -351,7 +351,7 @@ bool CSoundRender_Emitter::update_culling(float dt) float CSoundRender_Emitter::priority() const { - float dist = SoundRender->listener_position().distance_to(p_source.position); + const float dist = SoundRender->listener_position().distance_to(p_source.position); float att = p_source.min_distance / (psSoundRolloff * dist); clamp(att, 0.f, 1.f); return smooth_volume * att * priority_scale; From 342735578641d93ebe870b4d3afcd6c04b0dfa0f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 26 Apr 2024 04:55:47 +0500 Subject: [PATCH 307/497] xrSound: replace some asserts to asserts that can be cured --- src/xrSound/SoundRender_Core_StartStop.cpp | 2 +- src/xrSound/SoundRender_Emitter_StartStop.cpp | 2 +- src/xrSound/SoundRender_Target.cpp | 8 ++++---- src/xrSound/SoundRender_TargetA.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/xrSound/SoundRender_Core_StartStop.cpp b/src/xrSound/SoundRender_Core_StartStop.cpp index 904e94fb46a..7e2264543fa 100644 --- a/src/xrSound/SoundRender_Core_StartStop.cpp +++ b/src/xrSound/SoundRender_Core_StartStop.cpp @@ -7,7 +7,7 @@ void CSoundRender_Core::i_start(CSoundRender_Emitter* E) const { - R_ASSERT(E); + R_ASSERT1_CURE(E, true, { return; }); // Search lowest-priority target float Ptest = E->priority(); diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index 3aa28f5d3ac..36628a2cd65 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -95,6 +95,6 @@ void CSoundRender_Emitter::cancel() SoundRender->i_stop(this); m_current_state = stSimulatingLooped; // switch state break; - default: FATAL("Non playing ref_sound forced out of render queue"); break; + default: VERIFY2(false, "Non playing ref_sound forced out of render queue"); break; } } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 3575e75bd90..6364af163eb 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -18,7 +18,7 @@ void CSoundRender_Target::_destroy() void CSoundRender_Target::start(CSoundRender_Emitter* E) { - R_ASSERT(E); + R_ASSERT1_CURE(E, true, { return; }); // *** Initial buffer startup *** // 1. Fill parameters @@ -52,12 +52,12 @@ void CSoundRender_Target::stop() void CSoundRender_Target::rewind() { - R_ASSERT(rendering); + VERIFY(rendering); } void CSoundRender_Target::update() { - R_ASSERT(m_pEmitter); + R_ASSERT1_CURE(m_pEmitter, true, { return; }); wait_prefill(); } @@ -70,7 +70,7 @@ void CSoundRender_Target::fill_parameters() void CSoundRender_Target::fill_block(size_t idx) { - R_ASSERT(m_pEmitter); + R_ASSERT1_CURE(m_pEmitter, true, { return; }); m_pEmitter->fill_block(temp_buf[idx].data(), temp_buf[idx].size()); } diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index d289b2a7783..0067ded9262 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -198,7 +198,7 @@ size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const { - R_ASSERT(m_pEmitter); + R_ASSERT1_CURE(m_pEmitter, true, { return; }); const auto& info = m_pEmitter->source()->data_info(); const bool mono = info.channels == 1; From d95daa79a3d84e685df0161a1ccc4101e60907a2 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 29 Apr 2024 18:25:26 +0500 Subject: [PATCH 308/497] Fix compilation --- src/xrCore/_color.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/_color.h b/src/xrCore/_color.h index b1c05fd4feb..75e16a5a21b 100644 --- a/src/xrCore/_color.h +++ b/src/xrCore/_color.h @@ -58,7 +58,7 @@ struct Fcolor { float r, g, b, a; - constexpr Fcolor() noexcept = default; + Fcolor() noexcept = default; constexpr Fcolor(float _r, float _g, float _b, float _a) noexcept : r(_r), g(_g), b(_b), a(_a) {} From 8d152b1604dc518c2a86e7a39b04edc61d0c3a84 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 26 Apr 2024 04:14:16 +0500 Subject: [PATCH 309/497] xrSound: move target stopping/rewinding sound to emitter Previous idea was that CSoundRender_Core controls everything about sound targets. But it seems very logical to do this logic on emitter's behalf. The code becomes more good looking also. --- src/xrSound/SoundRender_Core.h | 2 -- src/xrSound/SoundRender_Core_StartStop.cpp | 17 ---------------- src/xrSound/SoundRender_Emitter.h | 3 +++ src/xrSound/SoundRender_Emitter_FSM.cpp | 12 +++++------ src/xrSound/SoundRender_Emitter_StartStop.cpp | 20 ++++++++++++------- 5 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 07e2e89fceb..35732afb6bb 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -132,8 +132,6 @@ class CSoundRender_Core : public ISoundManager void i_destroy_source(CSoundRender_Source* S); void i_start(CSoundRender_Emitter* E) const; - void i_stop(CSoundRender_Emitter* E); - void i_rewind(CSoundRender_Emitter* E); bool i_allow_play(const CSoundRender_Emitter* E); bool i_locked() override { return isLocked; } diff --git a/src/xrSound/SoundRender_Core_StartStop.cpp b/src/xrSound/SoundRender_Core_StartStop.cpp index 7e2264543fa..ce679cc43b3 100644 --- a/src/xrSound/SoundRender_Core_StartStop.cpp +++ b/src/xrSound/SoundRender_Core_StartStop.cpp @@ -32,23 +32,6 @@ void CSoundRender_Core::i_start(CSoundRender_Emitter* E) const T->priority = Ptest; } -void CSoundRender_Core::i_stop(CSoundRender_Emitter* E) -{ - // Msg("- %10s : %3d[%1.4f] : %s", "i_stop", E->dbg_ID, E->priority(), E->source->fname); - R_ASSERT(E); - R_ASSERT(E == E->target->get_emitter()); - E->target->stop(); - E->target = nullptr; -} - -void CSoundRender_Core::i_rewind(CSoundRender_Emitter* E) -{ - // Msg("- %10s : %3d[%1.4f] : %s", "i_rewind", E->dbg_ID, E->priority(), E->source->fname); - R_ASSERT(E); - R_ASSERT(E == E->target->get_emitter()); - E->target->rewind(); -} - bool CSoundRender_Core::i_allow_play(const CSoundRender_Emitter* E) { // Search available target diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 7c91fa3f35f..0b97158621f 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -121,4 +121,7 @@ class CSoundRender_Emitter final : public CSound_emitter CSoundRender_Emitter(CSoundRender_Scene* s); ~CSoundRender_Emitter() override; + +private: + void stop_target(); }; diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 6c2c5737c0a..cc6fd7d9d5c 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -39,7 +39,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) set_cursor(0); if (target) - SoundRender->i_rewind(this); + target->rewind(); bRewind = FALSE; } @@ -107,7 +107,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { if (target) { - SoundRender->i_stop(this); + stop_target(); m_current_state = stSimulating; } fTimeStarted += dt; @@ -118,7 +118,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (fTime >= fTimeToStop) { // STOP - SoundRender->i_stop(this); + stop_target(); m_current_state = stStopped; } else @@ -126,7 +126,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (!update_culling(dt)) { // switch to: SIMULATE - SoundRender->i_stop(this); + stop_target(); m_current_state = stSimulating; } else @@ -174,7 +174,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { if (target) { - SoundRender->i_stop(this); + stop_target(); m_current_state = stSimulatingLooped; } fTimeStarted += dt; @@ -184,7 +184,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (!update_culling(dt)) { // switch to: SIMULATE - SoundRender->i_stop(this); + stop_target(); m_current_state = stSimulatingLooped; // switch state } else diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index 36628a2cd65..44901f87070 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -4,6 +4,7 @@ #include "SoundRender_Core.h" #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" +#include "SoundRender_Target.h" void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay) { @@ -41,7 +42,7 @@ void CSoundRender_Emitter::i_stop() { bRewind = FALSE; if (target) - SoundRender->i_stop(this); + stop_target(); if (owner_data) { Event_ReleaseOwner(); @@ -86,15 +87,20 @@ void CSoundRender_Emitter::cancel() switch (m_current_state) { case stPlaying: - // switch to: SIMULATE - SoundRender->i_stop(this); - m_current_state = stSimulating; // switch state + stop_target(); + m_current_state = stSimulating; break; case stPlayingLooped: - // switch to: SIMULATE - SoundRender->i_stop(this); - m_current_state = stSimulatingLooped; // switch state + stop_target(); + m_current_state = stSimulatingLooped; break; default: VERIFY2(false, "Non playing ref_sound forced out of render queue"); break; } } + +void CSoundRender_Emitter::stop_target() +{ + R_ASSERT1_CURE(target, true, { return; }); + target->stop(); + target = nullptr; +} From ff01316e2e2b20b3d65bb1d0cdcb354d580d5747 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 26 Apr 2024 04:38:11 +0500 Subject: [PATCH 310/497] xrSound: move target priority management from core to target --- src/xrSound/SoundRender_Core_Processor.cpp | 10 ---------- src/xrSound/SoundRender_Core_StartStop.cpp | 8 +++----- src/xrSound/SoundRender_Emitter_FSM.cpp | 3 +++ src/xrSound/SoundRender_Target.cpp | 2 ++ src/xrSound/SoundRender_Target.h | 12 ++++++------ 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 00a79bf3a7c..e735dae9431 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -43,16 +43,6 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector if (CSoundRender_Emitter* E = T->get_emitter()) { update_emitter(E); - - E = T->get_emitter(); // update can stop itself - if (E) - T->priority = E->priority(); - else - T->priority = -1; - } - else - { - T->priority = -1; } } diff --git a/src/xrSound/SoundRender_Core_StartStop.cpp b/src/xrSound/SoundRender_Core_StartStop.cpp index ce679cc43b3..6217a945882 100644 --- a/src/xrSound/SoundRender_Core_StartStop.cpp +++ b/src/xrSound/SoundRender_Core_StartStop.cpp @@ -10,15 +10,14 @@ void CSoundRender_Core::i_start(CSoundRender_Emitter* E) const R_ASSERT1_CURE(E, true, { return; }); // Search lowest-priority target - float Ptest = E->priority(); float Ptarget = flt_max; CSoundRender_Target* T = nullptr; for (const auto Ttest : s_targets) { - if (Ttest->priority < Ptarget) + if (Ttest->get_priority() < Ptarget) { T = Ttest; - Ptarget = Ttest->priority; + Ptarget = Ttest->get_priority(); } } @@ -29,7 +28,6 @@ void CSoundRender_Core::i_start(CSoundRender_Emitter* E) const // Associate E->target = T; E->target->start(E); - T->priority = Ptest; } bool CSoundRender_Core::i_allow_play(const CSoundRender_Emitter* E) @@ -38,6 +36,6 @@ bool CSoundRender_Core::i_allow_play(const CSoundRender_Emitter* E) const float Ptest = E->priority(); return std::any_of(s_targets.begin(), s_targets.end(), [Ptest](const CSoundRender_Target* target) { - return target->priority < Ptest; + return target->get_priority() < Ptest; }); } diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index cc6fd7d9d5c..f98d7f5d431 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -345,7 +345,10 @@ bool CSoundRender_Emitter::update_culling(float dt) // If we are playing already, return OK // --- else check availability of resources if (target) + { + target->set_priority(priority()); return TRUE; + } return SoundRender->i_allow_play(this); } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 6364af163eb..8c2db63b6e7 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -25,6 +25,7 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) // 4. Load 2 blocks of data (as much as possible) // 5. Deferred-play-signal (emitter-exist, rendering-false) m_pEmitter = E; + priority = E->priority(); rendering = false; //m_pEmitter->source()->attach(); @@ -48,6 +49,7 @@ void CSoundRender_Target::stop() m_pEmitter->source()->detach(); m_pEmitter = nullptr; rendering = false; + priority = -1; } void CSoundRender_Target::rewind() diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index ecfb0926e46..c6c141eaf87 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -9,6 +9,7 @@ class CSoundRender_Target protected: CSoundRender_Emitter* m_pEmitter{}; bool rendering{}; + float priority{ -1 }; xr_vector temp_buf[sdef_target_count]; void fill_block(size_t idx); @@ -22,12 +23,6 @@ class CSoundRender_Target void dispatch_prefill(); void dispatch_prefill_all(); -public: - void wait_prefill() const; - -public: - float priority{}; - public: CSoundRender_Target(); virtual ~CSoundRender_Target() = default; @@ -45,4 +40,9 @@ class CSoundRender_Target virtual void stop(); virtual void update(); virtual void fill_parameters(); + + ICF auto get_priority() const { return priority; } + ICF void set_priority(const float p) { priority = p; } + + void wait_prefill() const; }; From 7082931be087c591db881fe03ae35cf9737997d5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 30 Apr 2024 01:01:19 +0500 Subject: [PATCH 311/497] Removed DX9 renderers (R1, R2) from the code --- src/Layers/CMakeLists.txt | 2 - src/Layers/xrRender/Blender_Recorder.cpp | 4 +- src/Layers/xrRender/Blender_Recorder.h | 2 +- src/Layers/xrRender/Blender_Recorder_R2.cpp | 4 +- .../Blender_Recorder_StandartBinding.cpp | 28 +- src/Layers/xrRender/ColorMapManager.cpp | 6 +- src/Layers/xrRender/D3DXRenderBase.cpp | 4 +- src/Layers/xrRender/Debug/dxPixEventWrapper.h | 2 +- src/Layers/xrRender/DetailManager.h | 6 - src/Layers/xrRender/DetailModel.cpp | 4 +- src/Layers/xrRender/FVF.h | 6 +- src/Layers/xrRender/HOM.cpp | 2 +- src/Layers/xrRender/ParticleEffect.cpp | 14 +- src/Layers/xrRender/QueryHelper.h | 21 +- src/Layers/xrRender/R_Backend.h | 40 +- src/Layers/xrRender/R_Backend_Runtime.cpp | 114 +- src/Layers/xrRender/R_Backend_Runtime.h | 8 +- src/Layers/xrRender/ResourceManager.cpp | 4 +- src/Layers/xrRender/ResourceManager_Reset.cpp | 8 - src/Layers/xrRender/SH_Atomic.cpp | 6 +- src/Layers/xrRender/SH_Atomic.h | 9 +- src/Layers/xrRender/SH_RT.h | 4 +- src/Layers/xrRender/SH_Texture.h | 17 +- src/Layers/xrRender/Shader.h | 7 +- src/Layers/xrRender/ShaderResourceTraits.h | 25 +- src/Layers/xrRender/blenders/uber_deffer.cpp | 2 +- src/Layers/xrRender/dxDebugRender.cpp | 4 +- src/Layers/xrRender/dxEnvironmentRender.cpp | 10 +- src/Layers/xrRender/dxFontRender.cpp | 5 - src/Layers/xrRender/dxImGuiRender.cpp | 28 +- src/Layers/xrRender/dxStatGraphRender.cpp | 4 +- src/Layers/xrRender/r__occlusion.cpp | 4 - src/Layers/xrRender/r__occlusion.h | 4 +- src/Layers/xrRender/r__pixel_calculator.cpp | 8 +- src/Layers/xrRender/r__sync_point.cpp | 2 +- src/Layers/xrRender/r_constants.cpp | 7 +- src/Layers/xrRender/r_constants.h | 18 +- src/Layers/xrRender/r_constants_cache.h | 174 +-- src/Layers/xrRender/stats_manager.cpp | 36 +- src/Layers/xrRender/xrRender_console.cpp | 18 +- src/Layers/xrRender/xr_effgamma.cpp | 10 +- src/Layers/xrRenderDX9/BufferUtils.cpp | 305 ----- src/Layers/xrRenderDX9/CommonTypes.h | 46 - .../xrRenderDX9/dx9DetailManager_VS.cpp | 184 --- src/Layers/xrRenderDX9/dx9HW.cpp | 495 ------- src/Layers/xrRenderDX9/dx9HW.h | 85 -- src/Layers/xrRenderDX9/dx9HWCaps.cpp | 280 ---- src/Layers/xrRenderDX9/dx9R_Backend_Runtime.h | 358 ----- .../dx9ResourceManager_Resources.cpp | 382 ------ src/Layers/xrRenderDX9/dx9SH_RT.cpp | 250 ---- src/Layers/xrRenderDX9/dx9r_constants.cpp | 134 -- .../xrRenderDX9/dx9r_constants_cache.cpp | 49 - src/Layers/xrRenderDX9/dx9r_constants_cache.h | 220 --- src/Layers/xrRenderDX9/dx9r_screenshot.cpp | 239 ---- src/Layers/xrRenderDX9/dx9shader_utils.h | 250 ---- src/Layers/xrRenderPC_R1/CMakeLists.txt | 59 - src/Layers/xrRenderPC_R1/FStaticRender.cpp | 878 ------------ src/Layers/xrRenderPC_R1/FStaticRender.h | 200 --- .../xrRenderPC_R1/FStaticRender_Blenders.cpp | 47 - .../xrRenderPC_R1/FStaticRender_Loader.cpp | 498 ------- .../FStaticRender_RenderTarget.cpp | 497 ------- .../FStaticRender_RenderTarget.h | 126 -- .../xrRenderPC_R1/FStaticRender_Shaders.cpp | 237 ---- .../xrRenderPC_R1/FStaticRender_Types.h | 34 - src/Layers/xrRenderPC_R1/GlowManager.cpp | 314 ----- src/Layers/xrRenderPC_R1/GlowManager.h | 78 -- src/Layers/xrRenderPC_R1/LightPPA.cpp | 520 -------- src/Layers/xrRenderPC_R1/LightPPA.h | 59 - src/Layers/xrRenderPC_R1/LightProjector.cpp | 407 ------ src/Layers/xrRenderPC_R1/LightProjector.h | 65 - src/Layers/xrRenderPC_R1/LightShadows.cpp | 694 ---------- src/Layers/xrRenderPC_R1/LightShadows.h | 92 -- src/Layers/xrRenderPC_R1/Pipeline.txt | 65 - src/Layers/xrRenderPC_R1/packages.config | 8 - src/Layers/xrRenderPC_R1/stdafx.cpp | 8 - src/Layers/xrRenderPC_R1/stdafx.h | 47 - src/Layers/xrRenderPC_R1/xrRender_R1.cpp | 79 -- src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj | 397 ------ .../xrRenderPC_R1/xrRender_R1.vcxproj.filters | 1035 --------------- src/Layers/xrRenderPC_R2/CMakeLists.txt | 56 - .../Light_Render_Direct_ComputeXFS.cpp | 93 -- src/Layers/xrRenderPC_R2/packages.config | 8 - src/Layers/xrRenderPC_R2/r2_rendertarget.h | 333 ----- .../r2_rendertarget_accum_direct.cpp | 969 -------------- .../r2_rendertarget_accum_point.cpp | 156 --- .../r2_rendertarget_accum_spot.cpp | 425 ------ .../r2_rendertarget_build_textures.cpp | 209 --- .../r2_rendertarget_phase_combine.cpp | 583 -------- .../r2_rendertarget_phase_occq.cpp | 10 - .../r2_rendertarget_phase_scene.cpp | 107 -- .../r2_rendertarget_phase_smap_D.cpp | 53 - .../r2_rendertarget_phase_ssao.cpp | 131 -- .../r2_rendertarget_u_set_rt.cpp | 36 - src/Layers/xrRenderPC_R2/r2_shaders.cpp | 543 -------- src/Layers/xrRenderPC_R2/r2_test_hw.cpp | 34 - src/Layers/xrRenderPC_R2/stdafx.cpp | 8 - src/Layers/xrRenderPC_R2/stdafx.h | 52 - src/Layers/xrRenderPC_R2/todo.txt | 205 --- src/Layers/xrRenderPC_R2/xrRender_R2.cpp | 84 -- src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj | 442 ------- .../xrRenderPC_R2/xrRender_R2.vcxproj.filters | 1176 ----------------- src/Layers/xrRender_R2/r2.cpp | 74 +- src/Layers/xrRender_R2/r2.h | 17 +- src/Layers/xrRender_R2/r2_R_render.cpp | 9 +- src/Layers/xrRender_R2/r2_R_sun_support.h | 4 - src/Layers/xrRender_R2/r2_rendertarget.cpp | 142 +- .../r2_rendertarget_accum_reflected.cpp | 13 +- .../xrRender_R2/r2_rendertarget_phase_PP.cpp | 10 +- .../r2_rendertarget_phase_bloom.cpp | 12 +- .../r2_rendertarget_phase_luminance.cpp | 12 +- .../r2_rendertarget_phase_smap_S.cpp | 9 +- src/Layers/xrRender_R2/render_phase_sun.cpp | 7 - src/engine.sln | 73 - src/xrEngine/EngineAPI.cpp | 12 +- 114 files changed, 154 insertions(+), 16355 deletions(-) delete mode 100644 src/Layers/xrRenderDX9/BufferUtils.cpp delete mode 100644 src/Layers/xrRenderDX9/CommonTypes.h delete mode 100644 src/Layers/xrRenderDX9/dx9DetailManager_VS.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9HW.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9HW.h delete mode 100644 src/Layers/xrRenderDX9/dx9HWCaps.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9R_Backend_Runtime.h delete mode 100644 src/Layers/xrRenderDX9/dx9ResourceManager_Resources.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9SH_RT.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9r_constants.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9r_constants_cache.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9r_constants_cache.h delete mode 100644 src/Layers/xrRenderDX9/dx9r_screenshot.cpp delete mode 100644 src/Layers/xrRenderDX9/dx9shader_utils.h delete mode 100644 src/Layers/xrRenderPC_R1/CMakeLists.txt delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender.cpp delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender.h delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_Blenders.cpp delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.cpp delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.h delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_Shaders.cpp delete mode 100644 src/Layers/xrRenderPC_R1/FStaticRender_Types.h delete mode 100644 src/Layers/xrRenderPC_R1/GlowManager.cpp delete mode 100644 src/Layers/xrRenderPC_R1/GlowManager.h delete mode 100644 src/Layers/xrRenderPC_R1/LightPPA.cpp delete mode 100644 src/Layers/xrRenderPC_R1/LightPPA.h delete mode 100644 src/Layers/xrRenderPC_R1/LightProjector.cpp delete mode 100644 src/Layers/xrRenderPC_R1/LightProjector.h delete mode 100644 src/Layers/xrRenderPC_R1/LightShadows.cpp delete mode 100644 src/Layers/xrRenderPC_R1/LightShadows.h delete mode 100644 src/Layers/xrRenderPC_R1/Pipeline.txt delete mode 100644 src/Layers/xrRenderPC_R1/packages.config delete mode 100644 src/Layers/xrRenderPC_R1/stdafx.cpp delete mode 100644 src/Layers/xrRenderPC_R1/stdafx.h delete mode 100644 src/Layers/xrRenderPC_R1/xrRender_R1.cpp delete mode 100644 src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj delete mode 100644 src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters delete mode 100644 src/Layers/xrRenderPC_R2/CMakeLists.txt delete mode 100644 src/Layers/xrRenderPC_R2/Light_Render_Direct_ComputeXFS.cpp delete mode 100644 src/Layers/xrRenderPC_R2/packages.config delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget.h delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_accum_direct.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_accum_point.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_accum_spot.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_build_textures.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_phase_combine.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_phase_occq.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_phase_scene.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_phase_smap_D.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_phase_ssao.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_rendertarget_u_set_rt.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_shaders.cpp delete mode 100644 src/Layers/xrRenderPC_R2/r2_test_hw.cpp delete mode 100644 src/Layers/xrRenderPC_R2/stdafx.cpp delete mode 100644 src/Layers/xrRenderPC_R2/stdafx.h delete mode 100644 src/Layers/xrRenderPC_R2/todo.txt delete mode 100644 src/Layers/xrRenderPC_R2/xrRender_R2.cpp delete mode 100644 src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj delete mode 100644 src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters diff --git a/src/Layers/CMakeLists.txt b/src/Layers/CMakeLists.txt index b2a84b8aa36..3b3c39c24f1 100644 --- a/src/Layers/CMakeLists.txt +++ b/src/Layers/CMakeLists.txt @@ -2,8 +2,6 @@ add_subdirectory(xrAPI) # TODO test on Windows if (WIN32) - add_subdirectory(xrRenderPC_R1) - add_subdirectory(xrRenderPC_R2) add_subdirectory(xrRenderPC_R4) endif() diff --git a/src/Layers/xrRender/Blender_Recorder.cpp b/src/Layers/xrRender/Blender_Recorder.cpp index 8849573af25..5216ea7b84e 100644 --- a/src/Layers/xrRender/Blender_Recorder.cpp +++ b/src/Layers/xrRender/Blender_Recorder.cpp @@ -226,7 +226,7 @@ void CBlender_Compile::PassSET_Shaders(pcstr _vs, pcstr _ps, pcstr _gs /*= nullp ctable.merge(&dest.ds->constants); dest.cs = RImplementation.Resources->_CreateCS("null"); # endif -#endif // !USE_DX9 +#endif // defined(USE_DX11) || defined(USE_OGL) } #if defined(USE_OGL) RImplementation.Resources->_LinkPP(dest); @@ -261,7 +261,7 @@ void CBlender_Compile::PassSET_ablend_mode(BOOL bABlend, u32 abSRC, u32 abDST) // alpha in DX11 identical to color. RS.SetRS(D3DRS_SRCBLENDALPHA, bABlend ? abSRC : D3DBLEND_ONE); RS.SetRS(D3DRS_DESTBLENDALPHA, bABlend ? abDST : D3DBLEND_ZERO); -#endif // !USE_DX9 +#endif } void CBlender_Compile::PassSET_ablend_aref(BOOL bATest, u32 aRef) { diff --git a/src/Layers/xrRender/Blender_Recorder.h b/src/Layers/xrRender/Blender_Recorder.h index d4532859b32..a4ea7c79743 100644 --- a/src/Layers/xrRender/Blender_Recorder.h +++ b/src/Layers/xrRender/Blender_Recorder.h @@ -145,7 +145,7 @@ class CBlender_Compile u32 Fail = D3DSTENCILOP_KEEP, u32 Pass = D3DSTENCILOP_KEEP, u32 ZFail = D3DSTENCILOP_KEEP); void r_StencilRef(u32 Ref); void r_CullMode(D3DCULL Mode); -#endif // !USE_DX9 +#endif // defined(USE_DX11) || defined(USE_OGL) #if defined(USE_DX11) void r_dx11Texture(LPCSTR ResourceName, LPCSTR texture, bool recursive = false); diff --git a/src/Layers/xrRender/Blender_Recorder_R2.cpp b/src/Layers/xrRender/Blender_Recorder_R2.cpp index 00e7b12cd13..968ed3c7aac 100644 --- a/src/Layers/xrRender/Blender_Recorder_R2.cpp +++ b/src/Layers/xrRender/Blender_Recorder_R2.cpp @@ -44,7 +44,7 @@ void CBlender_Compile::r_Pass(LPCSTR _vs, LPCSTR _ps, bool bFog, BOOL bZtest, BO dest.ds = RImplementation.Resources->_CreateDS("null"); dest.cs = RImplementation.Resources->_CreateCS("null"); # endif -#endif // !USE_DX9 +#endif // defined(USE_DX11) || defined(USE_OGL) } #if defined(USE_OGL) RImplementation.Resources->_LinkPP(dest); @@ -144,7 +144,7 @@ u32 CBlender_Compile::r_Sampler( { #if defined(USE_DX11) r_dx11Texture(_name, texture, true); -#elif defined(USE_DX9) || defined(USE_OGL) +#elif defined(USE_OGL) i_Texture(dwStage, texture); #else # error No graphics API selected or enabled! diff --git a/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp b/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp index b0c1672f8c2..b2c094b07d3 100644 --- a/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp +++ b/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp @@ -66,19 +66,7 @@ class cl_texgen : public R_constant_setup { Fmatrix mTexgen; -#if defined(USE_DX9) - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - float o_w = (.5f / _w); - float o_h = (.5f / _h); - Fmatrix mTexelAdjust = - { - 0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f + o_w, 0.5f + o_h, 0.0f, 1.0f - }; -#elif defined(USE_DX11) +#if defined(USE_DX11) Fmatrix mTexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, @@ -110,19 +98,7 @@ class cl_VPtexgen : public R_constant_setup { Fmatrix mTexgen; -#if defined(USE_DX9) - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - float o_w = (.5f / _w); - float o_h = (.5f / _h); - Fmatrix mTexelAdjust = - { - 0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f + o_w, 0.5f + o_h, 0.0f, 1.0f - }; -#elif defined(USE_DX11) +#if defined(USE_DX11) Fmatrix mTexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, diff --git a/src/Layers/xrRender/ColorMapManager.cpp b/src/Layers/xrRender/ColorMapManager.cpp index 7f1c9ab3f29..a5a214a08d1 100644 --- a/src/Layers/xrRender/ColorMapManager.cpp +++ b/src/Layers/xrRender/ColorMapManager.cpp @@ -26,7 +26,7 @@ void ColorMapManager::UpdateTexture(const shared_str& strTexName, int iTex) if (I != m_TexCache.end()) { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DBaseTexture* e0 = I->second->surface_get(); m_CMap[iTex]->surface_set(e0); _RELEASE(e0); @@ -44,7 +44,7 @@ void ColorMapManager::UpdateTexture(const shared_str& strTexName, int iTex) m_TexCache.emplace(strTexName, tmp); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DBaseTexture* e0 = tmp->surface_get(); m_CMap[iTex]->surface_set(e0); _RELEASE(e0); @@ -58,7 +58,7 @@ void ColorMapManager::UpdateTexture(const shared_str& strTexName, int iTex) } else { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) m_CMap[iTex]->surface_set(nullptr); #elif defined(USE_OGL) m_CMap[iTex]->surface_set(GL_TEXTURE_2D, 0); diff --git a/src/Layers/xrRender/D3DXRenderBase.cpp b/src/Layers/xrRender/D3DXRenderBase.cpp index 59627d0da57..574840706dc 100644 --- a/src/Layers/xrRender/D3DXRenderBase.cpp +++ b/src/Layers/xrRender/D3DXRenderBase.cpp @@ -76,7 +76,7 @@ void D3DXRenderBase::Destroy() void D3DXRenderBase::Reset(SDL_Window* hWnd, u32& dwWidth, u32& dwHeight, float& fWidth_2, float& fHeight_2) { -#if defined(DEBUG) && (defined(USE_DX9) || defined(USE_DX11)) +#if defined(DEBUG) && defined(USE_DX11) _SHOW_REF("*ref -CRenderDevice::ResetTotal: DeviceREF:", HW.pDevice); #endif // DEBUG @@ -98,7 +98,7 @@ void D3DXRenderBase::Reset(SDL_Window* hWnd, u32& dwWidth, u32& dwHeight, float& Resources->Dump(true); #endif -#if defined(DEBUG) && (defined(USE_DX9) || defined(USE_DX11)) +#if defined(DEBUG) && defined(USE_DX11) _SHOW_REF("*ref +CRenderDevice::ResetTotal: DeviceREF:", HW.pDevice); #endif } diff --git a/src/Layers/xrRender/Debug/dxPixEventWrapper.h b/src/Layers/xrRender/Debug/dxPixEventWrapper.h index 87d21c8693c..f728d0650f8 100644 --- a/src/Layers/xrRender/Debug/dxPixEventWrapper.h +++ b/src/Layers/xrRender/Debug/dxPixEventWrapper.h @@ -4,7 +4,7 @@ # define PIX_EVENT(Name) do { } while (false) # define PIX_EVENT_CTX(C,Name) do { } while (false) #else -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) # define PIX_EVENT(Name) dxPixEventWrapper pixEvent##Name(RCache,L ## #Name) # define PIX_EVENT_CTX(C,Name) dxPixEventWrapper pixEvent##Name(C,L ## #Name) diff --git a/src/Layers/xrRender/DetailManager.h b/src/Layers/xrRender/DetailManager.h index 8038027080b..0198125008e 100644 --- a/src/Layers/xrRender/DetailManager.h +++ b/src/Layers/xrRender/DetailManager.h @@ -203,13 +203,7 @@ class ECORE_API CDetailManager void hw_Load_Shaders(); void hw_Unload(); void hw_Render(CBackend& cmd_list); -#if defined(USE_DX9) - void hw_Render_dump(CBackend& cmd_list, ref_constant array, u32 var_id, u32 lod_id, u32 c_base); -#elif defined(USE_DX11) || defined(USE_OGL) void hw_Render_dump(CBackend& cmd_list, const Fvector4& consts, const Fvector4& wave, const Fvector4& wind, u32 var_id, u32 lod_id); -#else -# error No graphics API selected or enabled! -#endif // get unpacked slot DetailSlot& QueryDB(int sx, int sz); diff --git a/src/Layers/xrRender/DetailModel.cpp b/src/Layers/xrRender/DetailModel.cpp index 9b255fa89aa..959bca87e73 100644 --- a/src/Layers/xrRender/DetailModel.cpp +++ b/src/Layers/xrRender/DetailModel.cpp @@ -113,12 +113,12 @@ void CDetail::Load(IReader* S) bv_bb.modify(vertices[i].P); bv_bb.getsphere(bv_sphere.P, bv_sphere.R); -#if !defined(_EDITOR) && (defined(USE_DX9) || defined(USE_DX11)) +#if !defined(_EDITOR) && defined(USE_DX11) Optimize(); #endif } -#if !defined(_EDITOR) && (defined(USE_DX9) || defined(USE_DX11)) +#if !defined(_EDITOR) && defined(USE_DX11) #include "xrstripify.h" void CDetail::Optimize() diff --git a/src/Layers/xrRender/FVF.h b/src/Layers/xrRender/FVF.h index 048c6a86f2c..2523cee312d 100644 --- a/src/Layers/xrRender/FVF.h +++ b/src/Layers/xrRender/FVF.h @@ -2,11 +2,9 @@ #define _FVF_H_ #pragma once -#if defined(USE_DX9) -# define FVF_COLOR(c) (c) -#elif defined(USE_DX11) +#if defined(USE_DX11) # define FVF_COLOR(c) ((c & 0xff00ff00) | ((c >> 16) & 0xff) | ((c & 0xff) << 16u)) -#elif defined(USE_OGL) //the compiler should know to dedup this, defined explicitly for organization +#elif defined(USE_OGL) # define FVF_COLOR(c) (c) #else # error No graphics API selected or enabled! diff --git a/src/Layers/xrRender/HOM.cpp b/src/Layers/xrRender/HOM.cpp index 8438b10689d..3319e1884a8 100644 --- a/src/Layers/xrRender/HOM.cpp +++ b/src/Layers/xrRender/HOM.cpp @@ -154,7 +154,7 @@ void CHOM::Render_DB(CFrustum& base) { // Update projection matrices on every frame to ensure valid HOM culling float view_dim = occ_dim_0; -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) Fmatrix m_viewport = {view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, view_dim / 2.f + 0 + 0, view_dim / 2.f + 0 + 0, 0.0f, 1.0f}; Fmatrix m_viewport_01 = {1.f / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, 1.f / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, diff --git a/src/Layers/xrRender/ParticleEffect.cpp b/src/Layers/xrRender/ParticleEffect.cpp index d51708ef885..036bb18a2e1 100644 --- a/src/Layers/xrRender/ParticleEffect.cpp +++ b/src/Layers/xrRender/ParticleEffect.cpp @@ -32,19 +32,7 @@ static void ApplyTexgen(CBackend& cmd_list, const Fmatrix& mVP) { Fmatrix mTexgen; -#if defined(USE_DX9) - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - float o_w = (.5f / _w); - float o_h = (.5f / _h); - Fmatrix mTexelAdjust = - { - 0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f + o_w, 0.5f + o_h, 0.0f, 1.0f - }; -#elif defined(USE_DX11) +#if defined(USE_DX11) Fmatrix mTexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, diff --git a/src/Layers/xrRender/QueryHelper.h b/src/Layers/xrRender/QueryHelper.h index c217a4f3bd7..8f4b602de13 100644 --- a/src/Layers/xrRender/QueryHelper.h +++ b/src/Layers/xrRender/QueryHelper.h @@ -3,7 +3,7 @@ #pragma once // Interface -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) IC HRESULT CreateQuery(ID3DQuery** ppQuery); IC HRESULT GetData(ID3DQuery* pQuery, void* pData, u32 DataSize); IC HRESULT BeginQuery(ID3DQuery* pQuery); @@ -21,24 +21,7 @@ IC HRESULT ReleaseQuery(GLuint pQuery); // Implementation -#if defined(USE_DX9) // USE_DX9 - -IC HRESULT CreateQuery(ID3DQuery** ppQuery, D3D_QUERY type) { return HW.pDevice->CreateQuery(type, ppQuery); } -IC HRESULT GetData(ID3DQuery* pQuery, void* pData, u32 DataSize) -{ - return pQuery->GetData(pData, DataSize, D3DGETDATA_FLUSH); -} - -IC HRESULT BeginQuery(ID3DQuery* pQuery) { return pQuery->Issue(D3DISSUE_BEGIN); } -IC HRESULT EndQuery(ID3DQuery* pQuery) { return pQuery->Issue(D3DISSUE_END); } - -IC HRESULT ReleaseQuery(ID3DQuery* pQuery) -{ - _RELEASE(pQuery); - return S_OK; -} - -#elif defined(USE_DX11) +#if defined(USE_DX11) IC HRESULT CreateQuery(ID3DQuery** ppQuery, D3D_QUERY type) { diff --git a/src/Layers/xrRender/R_Backend.h b/src/Layers/xrRender/R_Backend.h index 507aa2aa77d..7309c56a2d6 100644 --- a/src/Layers/xrRender/R_Backend.h +++ b/src/Layers/xrRender/R_Backend.h @@ -93,7 +93,7 @@ class ECORE_API CBackend #endif private: // Render-targets -#if defined(USE_DX9) || defined (USE_DX11) +#if defined (USE_DX11) ID3DRenderTargetView* pRT[4]; ID3DDepthStencilView* pZB; #elif defined(USE_OGL) @@ -116,10 +116,7 @@ class ECORE_API CBackend // Shaders/State ID3DState* state; -#if defined(USE_DX9) - ID3DPixelShader* ps; - ID3DVertexShader* vs; -#elif defined(USE_DX11) +#if defined(USE_DX11) ID3DPixelShader* ps; ID3DVertexShader* vs; ID3DGeometryShader* gs; @@ -138,14 +135,12 @@ class ECORE_API CBackend #ifdef DEBUG LPCSTR ps_name; LPCSTR vs_name; -#ifndef USE_DX9 LPCSTR gs_name; -#if defined(USE_DX11) +# if defined(USE_DX11) LPCSTR hs_name; LPCSTR ds_name; LPCSTR cs_name; -#endif // USE_DX11 -#endif // !USE_DX9 +# endif # ifdef USE_OGL pcstr pp_name; # endif @@ -175,17 +170,11 @@ class ECORE_API CBackend CTexture* textures_ps[CTexture::mtMaxPixelShaderTextures]; // stages //CTexture* textures_vs[5]; // dmap + 4 vs CTexture* textures_vs[CTexture::mtMaxVertexShaderTextures]; // 4 vs -#ifndef USE_DX9 CTexture* textures_gs[CTexture::mtMaxGeometryShaderTextures]; // 4 vs -# if defined(USE_DX11) +#if defined(USE_DX11) CTexture* textures_hs[CTexture::mtMaxHullShaderTextures]; // 4 vs CTexture* textures_ds[CTexture::mtMaxDomainShaderTextures]; // 4 vs CTexture* textures_cs[CTexture::mtMaxComputeShaderTextures]; // 4 vs -# endif -#elif defined(USE_DX9) - // Nothing, because DX9 only has VS and PS -#else -# error No graphics API selected or enabled! #endif CMatrix* matrices[8]{}; // matrices are supported only for FFP @@ -260,10 +249,7 @@ class ECORE_API CBackend void apply_lmaterial(); -#if defined(USE_DX9) - R_constant_array& get_ConstantCache_Vertex() { return constants.a_vertex; } - R_constant_array& get_ConstantCache_Pixel() { return constants.a_pixel; } -#elif defined(USE_DX11) +#if defined(USE_DX11) IC void get_ConstantDirect(const shared_str& n, size_t DataSize, void** pVData, void** pGData, void** pPData); #endif @@ -283,7 +269,7 @@ class ECORE_API CBackend IC void set_pass_targets(const ref_rt& mrt0, const ref_rt& mrt1, const ref_rt& mrt2, const ref_rt& zb); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) IC void set_RT(ID3DRenderTargetView* RT, u32 ID = 0); IC void set_ZB(ID3DDepthStencilView* ZB); IC ID3DRenderTargetView* get_RT(u32 ID = 0); @@ -299,7 +285,7 @@ class ECORE_API CBackend # error No graphics API selected or enabled! #endif -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) IC void ClearRT(ID3DRenderTargetView* rt, const Fcolor& color); IC void ClearZB(ID3DDepthStencilView* zb, float depth); @@ -325,7 +311,7 @@ class ECORE_API CBackend return ClearRTRect(rt->pRT, color, numRects, rects); } -#if defined(USE_DX9) || defined(USE_OGL) +#if defined(USE_OGL) ICF void ClearZB(ref_rt& zb, float depth) { ClearZB(zb->pRT, depth);} ICF void ClearZB(ref_rt& zb, float depth, u8 stencil) { ClearZB(zb->pRT, depth, stencil);} ICF bool ClearZBRect(ref_rt& zb, float depth, size_t numRects, const Irect* rects) @@ -367,7 +353,7 @@ class ECORE_API CBackend ICF void set_Format(SDeclaration* _decl); private: -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ICF void set_PS(ID3DPixelShader* _ps, LPCSTR _n = nullptr); #elif defined(USE_OGL) ICF void set_PS(GLuint _ps, LPCSTR _n = 0); @@ -377,7 +363,6 @@ class ECORE_API CBackend ICF void set_PS(ref_ps& _ps) { set_PS(_ps->sh, _ps->cName.c_str()); } -#ifndef USE_DX9 ICF void set_GS(ref_gs& _gs) { set_GS(_gs->sh, _gs->cName.c_str()); } # if defined(USE_DX11) @@ -394,7 +379,6 @@ class ECORE_API CBackend ICF void set_PP(GLuint _pp, pcstr _n = nullptr); ICF void set_PP(ref_pp& _pp) { set_PP(_pp->pp, _pp->cName.c_str()); } # endif -#endif // USE_DX9 ICF void set_VS(ref_vs& _vs); @@ -402,7 +386,7 @@ class ECORE_API CBackend ICF void set_VS(SVS* _vs); #endif -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ICF void set_VS(ID3DVertexShader* _vs, LPCSTR _n = nullptr); #elif defined(USE_OGL) ICF void set_VS(GLuint _vs, LPCSTR _n = 0); @@ -418,7 +402,7 @@ class ECORE_API CBackend #endif public: -#if defined(USE_DX9) || defined(USE_OGL) +#if defined(USE_OGL) ICF bool is_TessEnabled() { return false; } #elif defined(USE_DX11) ICF bool is_TessEnabled(); diff --git a/src/Layers/xrRender/R_Backend_Runtime.cpp b/src/Layers/xrRender/R_Backend_Runtime.cpp index 439699a6789..94e738714ec 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.cpp +++ b/src/Layers/xrRender/R_Backend_Runtime.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #pragma hdrstop -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) #include #endif @@ -9,15 +9,8 @@ void CBackend::OnFrameEnd() { if (!GEnv.isDedicatedServer) { -#if !defined(USE_DX9) && !defined(USE_OGL) +#if defined(USE_DX11) HW.get_context(CHW::IMM_CTX_ID)->ClearState(); -#elif defined(USE_DX9) - for (u32 stage = 0; stage < HW.Caps.raster.dwStages; stage++) - CHK_DX(HW.pDevice->SetTexture(0, nullptr)); - CHK_DX(HW.pDevice->SetStreamSource(0, nullptr, 0, 0)); - CHK_DX(HW.pDevice->SetIndices(nullptr)); - CHK_DX(HW.pDevice->SetVertexShader(nullptr)); - CHK_DX(HW.pDevice->SetPixelShader(nullptr)); #endif Invalidate(); } @@ -140,39 +133,7 @@ void CBackend::Invalidate() void CBackend::set_ClipPlanes(u32 _enable, Fplane* _planes /*=NULL */, u32 count /* =0*/) { -#if defined(USE_DX9) - if (0 == HW.Caps.geometry.dwClipPlanes) - return; - if (!_enable) - { - CHK_DX(HW.pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, FALSE)); - return; - } - - // Enable and setup planes - VERIFY(_planes && count); - if (count > HW.Caps.geometry.dwClipPlanes) - count = HW.Caps.geometry.dwClipPlanes; - - using namespace DirectX; - - const XMMATRIX transform = XMLoadFloat4x4(reinterpret_cast(&Device.mFullTransform)); - XMMATRIX worldToClipMatrixIT = XMMatrixInverse(nullptr, transform); - worldToClipMatrixIT = XMMatrixTranspose(worldToClipMatrixIT); - - for (u32 it = 0; it < count; it++) - { - Fplane& P = _planes[it]; - XMFLOAT4 planeClip; - XMVECTOR planeWorld = XMPlaneNormalize(XMVectorSet(-P.n.x, -P.n.y, -P.n.z, -P.d)); - XMStoreFloat4(&planeClip, XMPlaneTransform(planeWorld, worldToClipMatrixIT)); - CHK_DX(HW.pDevice->SetClipPlane(it, reinterpret_cast(&planeClip))); - } - - // Enable them - u32 e_mask = (1 << count) - 1; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, e_mask)); -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) || defined(USE_OGL) // TODO: DX11: Implement in the corresponding vertex shaders // Use this to set up location, were shader setup code will get data // VERIFY(!"CBackend::set_ClipPlanes not implemented!"); @@ -182,7 +143,7 @@ void CBackend::set_ClipPlanes(u32 _enable, Fplane* _planes /*=NULL */, u32 count return; #else # error No graphics API selected or enabled! -#endif //USE_DX9 +#endif // defined(USE_DX11) || defined(USE_OGL) } #ifndef DEDICATED_SREVER @@ -192,9 +153,7 @@ void CBackend::set_ClipPlanes(u32 _enable, Fmatrix* _xform /*=NULL */, u32 fmask return; if (!_enable) { -#if defined(USE_DX9) - CHK_DX(HW.pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, FALSE)); -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) || defined(USE_OGL) // TODO: DX11: Implement in the corresponding vertex shaders // Use this to set up location, were shader setup code will get data // VERIFY(!"CBackend::set_ClipPlanes not implemented!"); @@ -382,9 +341,7 @@ void CBackend::set_Textures(STextureList* textures_list) continue; textures_ps[_last_ps] = nullptr; -#if defined(USE_DX9) - CHK_DX(HW.pDevice->SetTexture(_last_ps, NULL)); -#elif defined(USE_DX11) +#if defined(USE_DX11) // TODO: DX11: Optimise: set all resources at once ID3DShaderResourceView* pRes = 0; // HW.pDevice->PSSetShaderResources(_last_ps, 1, &pRes); @@ -407,9 +364,7 @@ void CBackend::set_Textures(STextureList* textures_list) continue; textures_vs[_last_vs] = nullptr; -#if defined(USE_DX9) - CHK_DX(HW.pDevice->SetTexture(_last_vs + CTexture::rstVertex, NULL)); -#elif defined(USE_DX11) +#if defined(USE_DX11) // TODO: DX11: Optimise: set all resources at once ID3DShaderResourceView* pRes = 0; // HW.pDevice->VSSetShaderResources(_last_vs, 1, &pRes); @@ -485,56 +440,7 @@ void CBackend::set_Textures(STextureList* textures_list) {} void CBackend::SetupStates() { set_CullMode(CULL_CCW); -#if defined(USE_DX9) - for (u32 i = 0; i < HW.Caps.raster.dwStages; i++) - { - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, ps_r__tf_Anisotropic)); - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, *(u32*)&ps_r__tf_Mipbias)); - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR)); - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR)); - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR)); - } - CHK_DX(HW.pDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_ZENABLE, TRUE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_LOCALVIEWER, TRUE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE)); - - Fmaterial mat - { - /*.diffuse =*/ { 1, 1, 1, 1 }, - /*.ambient =*/ { 1, 1, 1, 1 }, - /*.emissive =*/ { 0, 0, 0, 0 }, - /*.specular =*/ { 1, 1, 1, 1 }, - /*.power =*/ 15.f - }; - CHK_DX(HW.pDevice->SetMaterial(reinterpret_cast(&mat))); - - if (psDeviceFlags.test(rsWireframe)) - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME)); - else - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)); - // ******************** Fog parameters - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FOGCOLOR, 0)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE)); - if (HW.Caps.bTableFog) - { - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); - } - else - { - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR)); - } -#elif defined(USE_DX11) +#if defined(USE_DX11) SSManager.SetMaxAnisotropy(ps_r__tf_Anisotropic); SSManager.SetMipLODBias(ps_r__tf_Mipbias); #elif defined(USE_OGL) @@ -584,9 +490,7 @@ void CBackend::apply_lmaterial() return; VERIFY(RC_dest_sampler == C->destination); -#if defined(USE_DX9) - VERIFY(RC_sampler == C->type); -#elif defined(USE_DX11) +#if defined(USE_DX11) VERIFY(RC_dx11texture == C->type); #elif defined(USE_OGL) VERIFY(RC_sampler == C->type); diff --git a/src/Layers/xrRender/R_Backend_Runtime.h b/src/Layers/xrRender/R_Backend_Runtime.h index 6bb1500cb4c..6240a8803a6 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.h +++ b/src/Layers/xrRender/R_Backend_Runtime.h @@ -9,9 +9,7 @@ #include "Layers/xrRender/Debug/dxPixEventWrapper.h" -#if defined(USE_DX9) -#include "Layers/xrRenderDX9/dx9R_Backend_Runtime.h" -#elif defined(USE_DX11) +#if defined(USE_DX11) #include "Layers/xrRenderDX11/dx11R_Backend_Runtime.h" #elif defined(USE_OGL) #include "Layers/xrRenderGL/glR_Backend_Runtime.h" @@ -60,7 +58,7 @@ IC void CBackend::set_xform_project(const Fmatrix& M) { xforms.set_P(M); } IC const Fmatrix& CBackend::get_xform_world() { return xforms.get_W(); } IC const Fmatrix& CBackend::get_xform_view() { return xforms.get_V(); } IC const Fmatrix& CBackend::get_xform_project() { return xforms.get_P(); } -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) IC ID3DRenderTargetView* CBackend::get_RT(u32 ID) #elif defined(USE_OGL) IC GLuint CBackend::get_RT(u32 ID) @@ -73,7 +71,7 @@ IC GLuint CBackend::get_RT(u32 ID) return pRT[ID]; } -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) IC ID3DDepthStencilView* CBackend::get_ZB() #elif defined(USE_OGL) IC GLuint CBackend::get_ZB() diff --git a/src/Layers/xrRender/ResourceManager.cpp b/src/Layers/xrRender/ResourceManager.cpp index 7cb8c733b22..5138e3d184a 100644 --- a/src/Layers/xrRender/ResourceManager.cpp +++ b/src/Layers/xrRender/ResourceManager.cpp @@ -364,7 +364,7 @@ void CResourceManager::DeferredUpload() if (!Device.b_is_Ready) return; -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) xr_parallel_for_each(m_textures, [&](auto m_tex) { m_tex.second->Load(); }); #elif defined(USE_OGL) // XXX: OGL: Set additional contexts for all worker threads? for (auto& texture : m_textures) @@ -379,7 +379,7 @@ void CResourceManager::DeferredUnload() if (!Device.b_is_Ready) return; -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) xr_parallel_for_each(m_textures, [&](auto m_tex) { m_tex.second->Unload(); }); #elif defined(USE_OGL) // XXX: OGL: Set additional contexts for all worker threads? for (auto& texture : m_textures) diff --git a/src/Layers/xrRender/ResourceManager_Reset.cpp b/src/Layers/xrRender/ResourceManager_Reset.cpp index b99b7733b87..34ed9fd3cb4 100644 --- a/src/Layers/xrRender/ResourceManager_Reset.cpp +++ b/src/Layers/xrRender/ResourceManager_Reset.cpp @@ -26,10 +26,6 @@ void CResourceManager::reset_begin() RImplementation.Index.reset_begin(); RImplementation.Vertex.reset_begin(); - -#ifdef USE_DX9 - DeferredUnload(); -#endif } bool cmp_rt(const CRT* A, const CRT* B) { return A->_order < B->_order; } @@ -92,10 +88,6 @@ void CResourceManager::reset_end() { sstate->state_code.record(sstate->state); } - -#ifdef USE_DX9 - DeferredUpload(); -#endif } template diff --git a/src/Layers/xrRender/SH_Atomic.cpp b/src/Layers/xrRender/SH_Atomic.cpp index 861418867eb..9d13b46ecd5 100644 --- a/src/Layers/xrRender/SH_Atomic.cpp +++ b/src/Layers/xrRender/SH_Atomic.cpp @@ -44,7 +44,7 @@ SVS::~SVS() // Now it is release automatically #endif -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) _RELEASE(sh); #elif defined(USE_OGL) if (HW.SeparateShaderObjectsSupported) @@ -60,7 +60,7 @@ SVS::~SVS() // SPS SPS::~SPS() { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) _RELEASE(sh); #elif defined(USE_OGL) if (HW.SeparateShaderObjectsSupported) @@ -194,8 +194,6 @@ SDeclaration::~SDeclaration() // Release vertex layout _RELEASE(iLayout->second); } -#elif defined(USE_DX9)// USE_DX9 - _RELEASE(dcl); #else # error No graphics API selected or enabled! #endif diff --git a/src/Layers/xrRender/SH_Atomic.h b/src/Layers/xrRender/SH_Atomic.h index a81bc5e5bf2..2bf0011b875 100644 --- a/src/Layers/xrRender/SH_Atomic.h +++ b/src/Layers/xrRender/SH_Atomic.h @@ -28,7 +28,7 @@ typedef resptr_core> ref_input_sig ////////////////////////////////////////////////////////////////////////// struct ECORE_API SVS : public xr_resource_named { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DVertexShader* sh; #elif defined(USE_OGL) GLuint sh; @@ -47,7 +47,7 @@ typedef resptr_core> ref_vs; ////////////////////////////////////////////////////////////////////////// struct ECORE_API SPS : public xr_resource_named { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DPixelShader* sh; #elif defined(USE_OGL) GLuint sh; @@ -147,10 +147,7 @@ typedef resptr_core> ref_state; ////////////////////////////////////////////////////////////////////////// struct ECORE_API SDeclaration : public xr_resource_flagged { -#if defined(USE_DX9) // Don't need it: use ID3DInputLayout instead - // which is per ( declaration, VS input layout) pair - IDirect3DVertexDeclaration9* dcl; -#elif defined(USE_DX11) +#if defined(USE_DX11) // Maps input signature to input layout xr_map vs_to_layout; xr_vector dx11_dcl_code; diff --git a/src/Layers/xrRender/SH_RT.h b/src/Layers/xrRender/SH_RT.h index fa0afb95234..200fc6d30f4 100644 --- a/src/Layers/xrRender/SH_RT.h +++ b/src/Layers/xrRender/SH_RT.h @@ -28,15 +28,13 @@ class CRT : public xr_resource_named void resolve_into(CRT& destination) const; // only RTs with same format supported public: -#if defined(USE_DX9) || (USE_DX11) +#if defined(USE_DX11) ID3DTexture2D* pSurface{}; ID3DRenderTargetView* pRT{}; -# if defined(USE_DX11) ID3DDepthStencilView* pZRT[R__NUM_CONTEXTS]{}; ID3DDepthStencilView* dsv_all{}; xr_vector dsv_per_slice; ID3D11UnorderedAccessView* pUAView{}; -# endif #elif defined(USE_OGL) GLuint pRT{}; GLuint pZRT{}; diff --git a/src/Layers/xrRender/SH_Texture.h b/src/Layers/xrRender/SH_Texture.h index 7b1dc12970c..a248f1e81ed 100644 --- a/src/Layers/xrRender/SH_Texture.h +++ b/src/Layers/xrRender/SH_Texture.h @@ -10,16 +10,7 @@ class ENGINE_API CTheoraSurface; class ECORE_API CTexture : public xr_resource_named { public: -#if defined(USE_DX9) - enum MaxTextures - { - mtMaxPixelShaderTextures = 16, - mtMaxVertexShaderTextures = 4, - mtMaxCombinedShaderTextures = - mtMaxPixelShaderTextures - + mtMaxVertexShaderTextures - }; -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) || defined(USE_OGL) enum MaxTextures { // Actually these values are 128 @@ -45,7 +36,7 @@ class ECORE_API CTexture : public xr_resource_named # error No graphics API selected or enabled! #endif -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) // Since DX11 allows up to 128 unique textures, // distance between enum values should be at leas 128 enum ResourceShaderType // Don't change this since it's hardware-dependent @@ -87,7 +78,7 @@ class ECORE_API CTexture : public xr_resource_named void Unload(); // void Apply(u32 dwStage); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) void surface_set(ID3DBaseTexture* surf); [[nodiscard]] ID3DBaseTexture* surface_get() const; #elif defined(USE_OGL) @@ -172,7 +163,7 @@ class ECORE_API CTexture : public xr_resource_named int last_slice{ -1 }; private: -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DBaseTexture* pSurface{}; ID3DBaseTexture* pTempSurface{}; // Sequence data diff --git a/src/Layers/xrRender/Shader.h b/src/Layers/xrRender/Shader.h index 8a7ad24907e..f3dd6018489 100644 --- a/src/Layers/xrRender/Shader.h +++ b/src/Layers/xrRender/Shader.h @@ -90,15 +90,12 @@ struct ECORE_API SPass : public xr_resource_flagged ref_state state; // Generic state, like Z-Buffering, samplers, etc ref_ps ps; // may be NULL = FFP, in that case "state" must contain TSS setup ref_vs vs; // may be NULL = FFP, in that case "state" must contain RS setup, *and* FVF-compatible declaration must be used -#if defined(USE_DX11) || defined(USE_OGL) ref_gs gs; // may be NULL = don't use geometry shader at all -# ifdef USE_DX11 +#ifdef USE_DX11 ref_hs hs; // may be NULL = don't use hull shader at all ref_ds ds; // may be NULL = don't use domain shader at all ref_cs cs; // may be NULL = don't use compute shader at all -# endif -#endif // !USE_DX9 -#if defined(USE_OGL) +#elif defined(USE_OGL) ref_pp pp; // may be NULL = don't use program pipeline at all #endif ref_ctable constants; // may be NULL diff --git a/src/Layers/xrRender/ShaderResourceTraits.h b/src/Layers/xrRender/ShaderResourceTraits.h index d09e9adb5c7..9a8ca6ea214 100644 --- a/src/Layers/xrRender/ShaderResourceTraits.h +++ b/src/Layers/xrRender/ShaderResourceTraits.h @@ -1,9 +1,6 @@ #pragma once #include "ResourceManager.h" -#ifdef USE_DX9 -# include "Layers/xrRenderDX9/dx9shader_utils.h" -#endif #ifdef USE_OGL static void show_compile_errors(cpcstr filename, GLuint program, GLuint shader) @@ -178,15 +175,13 @@ struct ShaderTypeTraits using HWShaderType = GLuint; using BufferType = pcstr*; using ResultType = std::pair; -#else -#if defined(USE_DX9) - using LinkageType = void*; #elif defined(USE_DX11) using LinkageType = ID3D11ClassLinkage*; -#endif using HWShaderType = ID3DVertexShader*; using BufferType = DWORD const*; using ResultType = HRESULT; +#else +# error No graphics API selected or enabled! #endif static inline const char* GetShaderExt() { return ".vs"; } @@ -223,10 +218,7 @@ struct ShaderTypeTraits { ResultType res{}; -#if defined(USE_DX9) - res = HW.pDevice->CreateVertexShader(buffer, &sh); - UNUSED(linkage, name); -#elif defined(USE_DX11) +#if defined(USE_DX11) res = HW.pDevice->CreateVertexShader(buffer, size, linkage, &sh); UNUSED(name); #elif defined(USE_OGL) @@ -254,15 +246,13 @@ struct ShaderTypeTraits using HWShaderType = GLuint; using BufferType = pcstr*; using ResultType = std::pair; -#else -#if defined(USE_DX9) - using LinkageType = void*; #elif defined(USE_DX11) using LinkageType = ID3D11ClassLinkage*; -#endif using HWShaderType = ID3DPixelShader*; using BufferType = DWORD const*; using ResultType = HRESULT; +#else +# error No graphics API selected or enabled! #endif static inline const char* GetShaderExt() { return ".ps"; } @@ -313,10 +303,7 @@ struct ShaderTypeTraits { ResultType res{}; -#if defined(USE_DX9) - res = HW.pDevice->CreatePixelShader(buffer, &sh); - UNUSED(linkage, name); -#elif defined(USE_DX11) +#if defined(USE_DX11) res = HW.pDevice->CreatePixelShader(buffer, size, linkage, &sh); UNUSED(name); #elif defined(USE_OGL) diff --git a/src/Layers/xrRender/blenders/uber_deffer.cpp b/src/Layers/xrRender/blenders/uber_deffer.cpp index be7fd73fa8a..0cb822dcfd8 100644 --- a/src/Layers/xrRender/blenders/uber_deffer.cpp +++ b/src/Layers/xrRender/blenders/uber_deffer.cpp @@ -205,7 +205,7 @@ void uber_deffer(CBlender_Compile& C, bool hq, LPCSTR _vspec, LPCSTR _pspec, BOO C.r_dx11Texture("s_hemi", C.L_textures[2]); C.r_dx11Sampler("smp_rtlinear"); } -#elif defined(USE_DX9) || defined(USE_OGL) +#elif defined(USE_OGL) C.r_Pass(vs, ps, FALSE); VERIFY(C.L_textures[0].size()); if (bump) diff --git a/src/Layers/xrRender/dxDebugRender.cpp b/src/Layers/xrRender/dxDebugRender.cpp index d0a6f532d12..9f9a6c9ff7f 100644 --- a/src/Layers/xrRender/dxDebugRender.cpp +++ b/src/Layers/xrRender/dxDebugRender.cpp @@ -98,9 +98,7 @@ void dxDebugRender::CacheSetXformWorld(const Fmatrix& M) { RCache.set_xform_worl void dxDebugRender::CacheSetCullMode(CullMode m) { RCache.set_CullMode(CULL_NONE + m); } void dxDebugRender::SetAmbient(u32 colour) { -#if defined(USE_DX9) - CHK_DX(HW.pDevice->SetRenderState(D3DRS_AMBIENT, colour)); -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) || defined(USE_OGL) // TODO: DX11: Check if need this for DX11 VERIFY(!"Not implemented for DX11"); UNUSED(colour); diff --git a/src/Layers/xrRender/dxEnvironmentRender.cpp b/src/Layers/xrRender/dxEnvironmentRender.cpp index 907557637aa..7a2d4768c5a 100644 --- a/src/Layers/xrRender/dxEnvironmentRender.cpp +++ b/src/Layers/xrRender/dxEnvironmentRender.cpp @@ -68,11 +68,7 @@ class CBlender_skybox : public IBlender void Compile(CBlender_Compile& C) override { C.r_Pass("sky2", "sky2", FALSE, TRUE, FALSE); -#if defined(USE_DX9) - C.r_Sampler_clf("s_sky0", "$null"); - C.r_Sampler_clf("s_sky1", "$null"); - C.r_Sampler_rtf("s_tonemap", "$user$tonemap"); //. hack -#elif defined(USE_DX11) +#if defined(USE_DX11) // C.r_Sampler_clf ("s_sky0", "$null" ); // C.r_Sampler_clf ("s_sky1", "$null" ); C.r_dx11Texture("s_sky0", "$null"); @@ -230,7 +226,7 @@ void dxEnvironmentRender::RenderSky(CEnvironment& env) RCache.set_xform_world(mSky); RCache.set_Geometry(sh_2geom); RCache.set_Shader(sh_2sky); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) RCache.set_Textures(&sky_r_textures); #elif defined(USE_OGL) if (HW.Caps.geometry.bVTF) @@ -369,7 +365,7 @@ void dxEnvironmentRender::OnDeviceDestroy() sky_r_textures.clear(); clouds_r_textures.clear(); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) tsky0->surface_set(nullptr); tsky1->surface_set(nullptr); t_envmap_0->surface_set(nullptr); diff --git a/src/Layers/xrRender/dxFontRender.cpp b/src/Layers/xrRender/dxFontRender.cpp index 49081a7bdc8..4f7c74ed521 100644 --- a/src/Layers/xrRender/dxFontRender.cpp +++ b/src/Layers/xrRender/dxFontRender.cpp @@ -187,11 +187,6 @@ inline void dxFontRender::ImprintChar(Fvector l, const CGameFont& owner, FVF::TL //float tv = (l.y / owner.vTS.y) + (0.5f / owner.vTS.y); float tu = (l.x / owner.vTS.x); float tv = (l.y / owner.vTS.y); -#ifdef USE_DX9 - // Make half pixel offset for 1 to 1 mapping - tu += (0.5f / owner.vTS.x); - tv += (0.5f / owner.vTS.y); -#endif // USE_DX9 v->set(X, Y2, clr2, tu, tv + owner.fTCHeight); v++; diff --git a/src/Layers/xrRender/dxImGuiRender.cpp b/src/Layers/xrRender/dxImGuiRender.cpp index 5308c5f7f8d..0489d4ddc41 100644 --- a/src/Layers/xrRender/dxImGuiRender.cpp +++ b/src/Layers/xrRender/dxImGuiRender.cpp @@ -2,9 +2,7 @@ #include "dxImGuiRender.h" -#if defined(USE_DX9) -#include -#elif defined(USE_DX11) +#if defined(USE_DX11) #include #elif defined(USE_OGL) #include @@ -44,9 +42,7 @@ void dxImGuiRender::SetState(ImDrawData* data) void dxImGuiRender::Frame() { -#if defined(USE_DX9) - ImGui_ImplDX9_NewFrame(); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_NewFrame(); #elif defined(USE_OGL) ImGui_ImplOpenGL3_NewFrame(); @@ -55,9 +51,7 @@ void dxImGuiRender::Frame() void dxImGuiRender::Render(ImDrawData* data) { -#if defined(USE_DX9) - ImGui_ImplDX9_RenderDrawData(data); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_RenderDrawData(data); #elif defined(USE_OGL) ImGui_ImplOpenGL3_RenderDrawData(data); @@ -81,9 +75,7 @@ void dxImGuiRender::OnDeviceCreate(ImGuiContext* context) ImGuiIO& io = ImGui::GetIO(); io.BackendRendererName = "xrRender"; -#if defined(USE_DX9) - ImGui_ImplDX9_Init(HW.pDevice); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_Init(HW.pDevice, HW.get_context(CHW::IMM_CTX_ID)); #elif defined(USE_OGL) ImGui_ImplOpenGL3_Init(); @@ -91,9 +83,7 @@ void dxImGuiRender::OnDeviceCreate(ImGuiContext* context) } void dxImGuiRender::OnDeviceDestroy() { -#if defined(USE_DX9) - ImGui_ImplDX9_Shutdown(); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_Shutdown(); #elif defined(USE_OGL) ImGui_ImplOpenGL3_Shutdown(); @@ -102,9 +92,7 @@ void dxImGuiRender::OnDeviceDestroy() void dxImGuiRender::OnDeviceResetBegin() { -#if defined(USE_DX9) - ImGui_ImplDX9_InvalidateDeviceObjects(); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_InvalidateDeviceObjects(); #elif defined(USE_OGL) ImGui_ImplOpenGL3_DestroyDeviceObjects(); @@ -113,9 +101,7 @@ void dxImGuiRender::OnDeviceResetBegin() void dxImGuiRender::OnDeviceResetEnd() { -#if defined(USE_DX9) - ImGui_ImplDX9_CreateDeviceObjects(); -#elif defined(USE_DX11) +#if defined(USE_DX11) ImGui_ImplDX11_CreateDeviceObjects(); #elif defined(USE_OGL) ImGui_ImplOpenGL3_CreateDeviceObjects(); diff --git a/src/Layers/xrRender/dxStatGraphRender.cpp b/src/Layers/xrRender/dxStatGraphRender.cpp index 769365f2211..cb9007b7ebb 100644 --- a/src/Layers/xrRender/dxStatGraphRender.cpp +++ b/src/Layers/xrRender/dxStatGraphRender.cpp @@ -26,9 +26,7 @@ void dxStatGraphRender::OnRender(CStatGraph& owner) RCache.set_xform_world(Fidentity); RCache.set_xform_view(ViewM); RCache.set_xform_project(Fidentity); -#ifdef USE_DX9 - RCache.OnFrameEnd(); -#else // when we don't have FFP support +#ifndef USE_DX9 RCache.set_Shader(RImplementation.m_WireShader); RCache.set_Z(false); RCache.set_c("tfactor", 1.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 062e0aa031f..765f9635b2c 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -108,10 +108,6 @@ R_occlusion::occq_result R_occlusion::occq_get(u32& ID) } } RImplementation.BasicStats.Wait.End(); -#if defined(USE_DX9) || defined(USE_DX11) - if (hr == D3DERR_DEVICELOST) - fragments = 0xffffffff; -#endif if (0 == fragments) RImplementation.BasicStats.OcclusionCulled++; diff --git a/src/Layers/xrRender/r__occlusion.h b/src/Layers/xrRender/r__occlusion.h index 2a6e85ddb8a..5cc2e3a62e5 100644 --- a/src/Layers/xrRender/r__occlusion.h +++ b/src/Layers/xrRender/r__occlusion.h @@ -18,7 +18,7 @@ class R_occlusion private: struct Query { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DQuery* Q; #elif defined(USE_OGL) GLuint Q; @@ -39,7 +39,7 @@ class R_occlusion public: #if defined(USE_DX11) typedef u64 occq_result; -#elif defined(USE_DX9) || defined(USE_OGL) +#elif defined(USE_OGL) typedef u32 occq_result; #else # error No graphics API selected or enabled! diff --git a/src/Layers/xrRender/r__pixel_calculator.cpp b/src/Layers/xrRender/r__pixel_calculator.cpp index 0f93e9f2321..c7bdf429bc3 100644 --- a/src/Layers/xrRender/r__pixel_calculator.cpp +++ b/src/Layers/xrRender/r__pixel_calculator.cpp @@ -3,7 +3,7 @@ #include "r__pixel_calculator.h" #include "Layers/xrRender/FBasicVisual.h" -#if defined(USE_DX9) || defined(USE_DX11)// XXX: support pixel calculator on OpenGL +#if defined(USE_DX11)// XXX: support pixel calculator on OpenGL # include #endif @@ -17,7 +17,7 @@ void r_pixel_calculator::begin() RCache.set_RT(rt->pRT); #ifdef USE_DX11 RCache.set_ZB(zb->pZRT[RCache.context_id]); -#elif defined(USE_DX9) || defined(USE_OGL) +#elif defined(USE_OGL) RCache.set_ZB(zb->pRT); #endif @@ -35,7 +35,7 @@ void r_pixel_calculator::end() rt = nullptr; } -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) // +X, -X, +Y, -Y, +Z, -Z extern Fvector cmNorm[6]; extern Fvector cmDir [6]; @@ -43,7 +43,7 @@ extern Fvector cmDir [6]; r_aabb_ssa r_pixel_calculator::calculate(dxRender_Visual* V) { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) using namespace DirectX; r_aabb_ssa result = {0}; diff --git a/src/Layers/xrRender/r__sync_point.cpp b/src/Layers/xrRender/r__sync_point.cpp index c45f87d291c..1f84ff2941a 100644 --- a/src/Layers/xrRender/r__sync_point.cpp +++ b/src/Layers/xrRender/r__sync_point.cpp @@ -43,7 +43,7 @@ void R_sync_point::End() q_sync_count = (q_sync_count + 1) % HW.Caps.iGPUNum; CHK_GL(glDeleteSync((GLsync)q_sync_point[q_sync_count])); } -#elif defined(USE_DX9) || defined(USE_DX11) +#elif defined(USE_DX11) void R_sync_point::Create() { for (u32 i = 0; i < HW.Caps.iGPUNum; ++i) diff --git a/src/Layers/xrRender/r_constants.cpp b/src/Layers/xrRender/r_constants.cpp index d9cd6463eab..bffaa6ceb85 100644 --- a/src/Layers/xrRender/r_constants.cpp +++ b/src/Layers/xrRender/r_constants.cpp @@ -89,15 +89,12 @@ void R_constant_table::merge(R_constant_table* T) C->type = src->type; C->ps = src->ps; C->vs = src->vs; -#ifndef USE_DX9 C->gs = src->gs; -# if defined(USE_DX11) +#if defined(USE_DX11) C->hs = src->hs; C->ds = src->ds; C->cs = src->cs; -# endif -#endif -#ifdef USE_OGL +#elif defined(USE_OGL) C->pp = src->pp; #endif C->samp = src->samp; diff --git a/src/Layers/xrRender/r_constants.h b/src/Layers/xrRender/r_constants.h index 627b82d742a..d316457e7bf 100644 --- a/src/Layers/xrRender/r_constants.h +++ b/src/Layers/xrRender/r_constants.h @@ -76,7 +76,7 @@ struct ECORE_API R_constant_load u16 index; // linear index (pixel) u16 cls; // element class -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) R_constant_load() : index(u16(-1)), cls(u16(-1)) {}; #elif defined(USE_OGL) GLuint location; @@ -89,7 +89,7 @@ struct ECORE_API R_constant_load BOOL equal(R_constant_load& C) { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) return (index == C.index) && (cls == C.cls); #elif defined(USE_OGL) return (index == C.index) && (cls == C.cls) && (location == C.location) && (program == C.program); @@ -107,15 +107,12 @@ struct ECORE_API R_constant : public xr_resource R_constant_load ps; R_constant_load vs; -#ifndef USE_DX9 R_constant_load gs; -# if defined(USE_DX11) +#if defined(USE_DX11) R_constant_load hs; R_constant_load ds; R_constant_load cs; -# endif -#endif -#ifdef USE_OGL +#elif defined(USE_OGL) R_constant_load pp; #endif @@ -132,15 +129,12 @@ struct ECORE_API R_constant : public xr_resource case RC_dest_vertex: return vs; case RC_dest_pixel: return ps; case RC_dest_sampler: return samp; -#ifndef USE_DX9 case RC_dest_geometry: return gs; -# if defined(USE_DX11) +#if defined(USE_DX11) case RC_dest_hull: return hs; case RC_dest_domain: return ds; case RC_dest_compute: return cs; -# endif -#endif -#ifdef USE_OGL +#elif defined(USE_OGL) case RC_dest_all: return pp; #endif default: FATAL("invalid enumeration for shader"); diff --git a/src/Layers/xrRender/r_constants_cache.h b/src/Layers/xrRender/r_constants_cache.h index af75cfb9d8e..d056fc65616 100644 --- a/src/Layers/xrRender/r_constants_cache.h +++ b/src/Layers/xrRender/r_constants_cache.h @@ -4,9 +4,7 @@ #include "r_constants.h" -#if defined(USE_DX9) -#include "Layers/xrRenderDX9/dx9r_constants_cache.h" -#elif defined(USE_DX11) +#if defined(USE_DX11) #include "Layers/xrRenderDX11/dx11r_constants_cache.h" #elif defined(USE_OGL) #include "Layers/xrRenderGL/glr_constants_cache.h" @@ -14,174 +12,4 @@ # error No graphics API selected or enabled! #endif -/* -template -class R_constant_cache -{ -private: - ALIGN(16) svector array; - u32 lo,hi; -public: - R_constant_cache() - { - array.resize(limit); - flush (); - } - ICF T* access (u32 id) { return &array[id]; } - ICF void flush () { lo=hi=0; } - ICF void dirty (u32 _lo, u32 _hi) { if (_lohi) hi=_hi; } - ICF u32 r_lo () { return lo; } - ICF u32 r_hi () { return hi; } -}; - -class R_constant_array -{ -public: - typedef R_constant_cache t_f; - typedef R_constant_cache t_i; - typedef R_constant_cache t_b; -public: - ALIGN(16) t_f c_f; -// ALIGN(16) t_i c_i; -// ALIGN(16) t_b c_b; - BOOL b_dirty; -public: - t_f& get_array_f () { return c_f; } -// t_i& get_array_i () { return c_i; } -// t_b& get_array_b () { return c_b; } - - void set (R_constant* C, R_constant_load& L, const Fmatrix& A) - { - VERIFY (RC_float == C->type); - Fvector4* it = c_f.access (L.index); - switch (L.cls) - { - case RC_2x4: - c_f.dirty (L.index,L.index+2); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - break; - case RC_3x4: - c_f.dirty (L.index,L.index+3); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - it[2].set (A._13, A._23, A._33, A._43); - break; - case RC_4x4: - c_f.dirty (L.index,L.index+4); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - it[2].set (A._13, A._23, A._33, A._43); - it[3].set (A._14, A._24, A._34, A._44); - break; - default: -#ifdef DEBUG - xrDebug::Fatal (DEBUG_INFO,"Invalid constant run-time-type for '%s'",*C->name); -#else - NODEFAULT; -#endif - } - } - - void set (R_constant* C, R_constant_load& L, const Fvector4& A) - { - VERIFY (RC_float == C->type); - VERIFY (RC_1x4 == L.cls); - c_f.access (L.index)->set (A); - c_f.dirty (L.index,L.index+1); - } - - void seta (R_constant* C, R_constant_load& L, u32 e, const Fmatrix& A) - { - VERIFY (RC_float == C->type); - u32 base; - Fvector4* it; - switch (L.cls) - { - case RC_2x4: - base = L.index + 2*e; - it = c_f.access (base); - c_f.dirty (base,base+2); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - break; - case RC_3x4: - base = L.index + 3*e; - it = c_f.access (base); - c_f.dirty (base,base+3); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - it[2].set (A._13, A._23, A._33, A._43); - break; - case RC_4x4: - base = L.index + 4*e; - it = c_f.access (base); - c_f.dirty (base,base+4); - it[0].set (A._11, A._21, A._31, A._41); - it[1].set (A._12, A._22, A._32, A._42); - it[2].set (A._13, A._23, A._33, A._43); - it[3].set (A._14, A._24, A._34, A._44); - break; - default: -#ifdef DEBUG - xrDebug::Fatal (DEBUG_INFO,"Invalid constant run-time-type for '%s'",*C->name); -#else - NODEFAULT; -#endif - } - } - - void seta (R_constant* C, R_constant_load& L, u32 e, const Fvector4& A) - { - VERIFY (RC_float == C->type); - VERIFY (RC_1x4 == L.cls); - u32 base = L.index + e; - c_f.access (base)->set (A); - c_f.dirty (base,base+1); - } -}; - -class ECORE_API R_constants -{ -public: - ALIGN(16) R_constant_array a_pixel; - ALIGN(16) R_constant_array a_vertex; - - void flush_cache (); -public: - // fp, non-array versions - ICF void set (R_constant* C, const Fmatrix& A) { - if (C->destination&1) { a_pixel.set (C,C->ps,A); a_pixel.b_dirty=TRUE; } - if (C->destination&2) { a_vertex.set (C,C->vs,A); a_vertex.b_dirty=TRUE; } - } - ICF void set (R_constant* C, const Fvector4& A) { - if (C->destination&1) { a_pixel.set (C,C->ps,A); a_pixel.b_dirty=TRUE; } - if (C->destination&2) { a_vertex.set (C,C->vs,A); a_vertex.b_dirty=TRUE; } - } - ICF void set (R_constant* C, float x, float y, float z, float w) { - Fvector4 data; data.set(x,y,z,w); - set (C,data); - } - - // fp, array versions - ICF void seta (R_constant* C, u32 e, const Fmatrix& A) { - if (C->destination&1) { a_pixel.seta (C,C->ps,e,A); a_pixel.b_dirty=TRUE; } - if (C->destination&2) { a_vertex.seta (C,C->vs,e,A); a_vertex.b_dirty=TRUE; } - } - ICF void seta (R_constant* C, u32 e, const Fvector4& A) { - if (C->destination&1) { a_pixel.seta (C,C->ps,e,A); a_pixel.b_dirty=TRUE; } - if (C->destination&2) { a_vertex.seta (C,C->vs,e,A); a_vertex.b_dirty=TRUE; } - } - ICF void seta (R_constant* C, u32 e, float x, float y, float z, float w) { - Fvector4 data; data.set(x,y,z,w); - seta (C,e,data); - } - - // - ICF void flush () - { - if (a_pixel.b_dirty || a_vertex.b_dirty) flush_cache(); - } -}; -*/ #endif diff --git a/src/Layers/xrRender/stats_manager.cpp b/src/Layers/xrRender/stats_manager.cpp index 7f573613794..05f7d77f247 100644 --- a/src/Layers/xrRender/stats_manager.cpp +++ b/src/Layers/xrRender/stats_manager.cpp @@ -44,11 +44,7 @@ void stats_manager::increment_stats_rtarget(ID3DTexture2D* buff) return; _D3DPOOL pool = D3DPOOL_DEFAULT; -#if defined(USE_DX9) - D3DSURFACE_DESC desc; - buff->GetLevelDesc(0, &desc); - pool = desc.Pool; -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_TEXTURE2D_DESC desc; buff->GetDesc(&desc); #else @@ -64,11 +60,7 @@ void stats_manager::increment_stats_vb(ID3DVertexBuffer* buff) if (buff == nullptr || GEnv.isDedicatedServer) return; -#if defined(USE_DX9) - D3DVERTEXBUFFER_DESC desc; - buff->GetDesc(&desc); - increment_stats(desc.Size, enum_stats_buffer_type_vertex, desc.Pool, buff); -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_BUFFER_DESC desc; buff->GetDesc(&desc); increment_stats(desc.ByteWidth, enum_stats_buffer_type_vertex, D3DPOOL_MANAGED, buff); @@ -82,11 +74,7 @@ void stats_manager::increment_stats_ib(ID3DIndexBuffer* buff) if (buff == nullptr || GEnv.isDedicatedServer) return; -#if defined(USE_DX9) - D3DINDEXBUFFER_DESC desc; - buff->GetDesc(&desc); - increment_stats(desc.Size, enum_stats_buffer_type_index, desc.Pool, buff); -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_BUFFER_DESC desc; buff->GetDesc(&desc); increment_stats(desc.ByteWidth, enum_stats_buffer_type_index, D3DPOOL_MANAGED, buff); @@ -106,11 +94,7 @@ void stats_manager::decrement_stats_rtarget(ID3DTexture2D* buff) return; _D3DPOOL pool = D3DPOOL_DEFAULT; -#if defined(USE_DX9) - D3DSURFACE_DESC desc; - buff->GetLevelDesc(0, &desc); - pool = desc.Pool; -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_TEXTURE2D_DESC desc; buff->GetDesc(&desc); #else @@ -131,11 +115,7 @@ void stats_manager::decrement_stats_vb(ID3DVertexBuffer* buff) if ((refcnt = buff->Release()) > 1) return; -#if defined(USE_DX9) - D3DVERTEXBUFFER_DESC desc; - buff->GetDesc(&desc); - decrement_stats(desc.Size, enum_stats_buffer_type_vertex, desc.Pool, buff); -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_BUFFER_DESC desc; buff->GetDesc(&desc); decrement_stats(desc.ByteWidth, enum_stats_buffer_type_vertex, D3DPOOL_MANAGED, buff); @@ -154,11 +134,7 @@ void stats_manager::decrement_stats_ib(ID3DIndexBuffer* buff) if ((refcnt = buff->Release()) > 1) return; -#if defined(USE_DX9) - D3DINDEXBUFFER_DESC desc; - buff->GetDesc(&desc); - decrement_stats(desc.Size, enum_stats_buffer_type_index, desc.Pool, buff); -#elif defined(USE_DX11) +#if defined(USE_DX11) D3D_BUFFER_DESC desc; buff->GetDesc(&desc); decrement_stats(desc.ByteWidth, enum_stats_buffer_type_index, D3DPOOL_MANAGED, buff); diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index 614e020d196..e7e182f67e3 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -90,7 +90,7 @@ u32 ps_r_sun_quality = 1; // = 0; const xr_token qsun_quality_token[] = {{"st_opt_low", 0}, {"st_opt_medium", 1}, {"st_opt_high", 2}, #if defined(USE_DX11) // TODO: OGL: fix ultra and extreme settings {"st_opt_ultra", 3}, {"st_opt_extreme", 4}, -#endif // !USE_DX9 +#endif // USE_DX11 {nullptr, 0}}; u32 ps_r_water_reflection = 3; @@ -368,16 +368,13 @@ class CCC_tf_Aniso : public CCC_Integer public: void apply() { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) if (nullptr == HW.pDevice) return; #endif int val = *value; clamp(val, 1, 16); -#if defined(USE_DX9) - for (u32 i = 0; i < HW.Caps.raster.dwStages; i++) - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, val)); -#elif defined(USE_DX11) +#if defined(USE_DX11) SSManager.SetMaxAnisotropy(val); #elif defined(USE_OGL) // OGL: don't set aniso here because it will be updated after vid restart @@ -402,15 +399,10 @@ class CCC_tf_MipBias : public CCC_Float public: void apply() { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) if (nullptr == HW.pDevice) return; -#endif -#if defined(USE_DX9) - for (u32 i = 0; i < HW.Caps.raster.dwStages; i++) - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, *((u32*)value))); -#elif defined(USE_DX11) SSManager.SetMipLODBias(*value); #endif } @@ -621,7 +613,7 @@ class CCC_memory_stats : public IConsole_Command virtual void Execute(LPCSTR /*args*/) { // TODO: OGL: Implement memory usage statistics. -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) u32 m_base = 0; u32 c_base = 0; u32 m_lmaps = 0; diff --git a/src/Layers/xrRender/xr_effgamma.cpp b/src/Layers/xrRender/xr_effgamma.cpp index fc9842c38f9..851392f66a5 100644 --- a/src/Layers/xrRender/xr_effgamma.cpp +++ b/src/Layers/xrRender/xr_effgamma.cpp @@ -56,15 +56,7 @@ void CGammaControl::GenLUT(const DXGI_GAMMA_CONTROL_CAPABILITIES& GC, DXGI_GAMMA void CGammaControl::Update() const { -#if defined(USE_DX9) - if (HW.pDevice) - { - D3DGAMMARAMP G; - GenLUT(G.red, G.green, G.blue, 256); - HW.pDevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &G); - return; - } -#elif defined(USE_DX11) +#if defined(USE_DX11) if (HW.pDevice) { DXGI_GAMMA_CONTROL_CAPABILITIES GC; diff --git a/src/Layers/xrRenderDX9/BufferUtils.cpp b/src/Layers/xrRenderDX9/BufferUtils.cpp deleted file mode 100644 index 17e51302000..00000000000 --- a/src/Layers/xrRenderDX9/BufferUtils.cpp +++ /dev/null @@ -1,305 +0,0 @@ -#include "stdafx.h" - -#include - -enum -{ - LOCKFLAGS_FLUSH = D3DLOCK_DISCARD, - LOCKFLAGS_APPEND = D3DLOCK_NOOVERWRITE, -}; - -u32 GetFVFVertexSize(u32 FVF) -{ - return static_cast(FVF::ComputeVertexSize(FVF)); -} - -u32 GetDeclVertexSize(const VertexElement* decl, u32 Stream) -{ - return static_cast(FVF::ComputeVertexSize(decl, Stream)); -} - -u32 GetDeclLength(const VertexElement* decl) -{ - return static_cast(FVF::GetDeclLength(decl)); -} - -//----------------------------------------------------------------------------- -VertexStagingBuffer::~VertexStagingBuffer() -{ - Destroy(); -} - -void VertexStagingBuffer::Create(size_t size, bool allowReadBack /*= false*/) -{ - m_Size = size; - m_AllowReadBack = allowReadBack; - - u32 dwUsage = allowReadBack ? 0 : D3DUSAGE_WRITEONLY; - if (HW.Caps.geometry.bSoftware) - dwUsage |= D3DUSAGE_SOFTWAREPROCESSING; - R_CHK(HW.pDevice->CreateVertexBuffer(size, dwUsage, 0, D3DPOOL_MANAGED, &m_DeviceBuffer, nullptr)); - VERIFY(m_DeviceBuffer); - - HW.stats_manager.increment_stats_vb(m_DeviceBuffer); - AddRef(); -} - -bool VertexStagingBuffer::IsValid() const -{ - return !!m_DeviceBuffer; -} - -void* VertexStagingBuffer::Map( - size_t offset /*= 0 */, - size_t size /*= 0 */, - bool read /*= false*/) -{ - VERIFY(IsValid()); - VERIFY2(!read || m_AllowReadBack, "Can't read from write only buffer"); - VERIFY(size <= m_Size); - - u32 mapMode = read ? D3DLOCK_READONLY : 0; - R_CHK(m_DeviceBuffer->Lock(offset, size, const_cast(&m_HostBuffer), mapMode)); - return m_HostBuffer; -} - -void VertexStagingBuffer::Unmap(bool /*doFlush = false*/) -{ - VERIFY(IsValid()); - R_CHK(m_DeviceBuffer->Unlock()); -} - -void VertexStagingBuffer::DiscardHostBuffer() -{ - /* Do nothing */ -} - -VertexBufferHandle VertexStagingBuffer::GetBufferHandle() const -{ - return m_DeviceBuffer; -} - -void VertexStagingBuffer::Destroy() -{ - HW.stats_manager.decrement_stats_vb(m_DeviceBuffer); - _RELEASE(m_DeviceBuffer); - m_DeviceBuffer = nullptr; -} - -size_t VertexStagingBuffer::GetSystemMemoryUsage() const -{ - if (IsValid()) - { - D3DVERTEXBUFFER_DESC desc; - m_DeviceBuffer->GetDesc(&desc); - - if (desc.Pool == D3DPOOL_MANAGED || desc.Pool == D3DPOOL_SCRATCH) - return desc.Size; - } - - return 0; -} - -size_t VertexStagingBuffer::GetVideoMemoryUsage() const -{ - if (IsValid()) - { - D3DVERTEXBUFFER_DESC desc; - m_DeviceBuffer->GetDesc(&desc); - - if (desc.Pool == D3DPOOL_DEFAULT || desc.Pool == D3DPOOL_MANAGED) - return desc.Size; - } - - return 0; -} - -//----------------------------------------------------------------------------- -IndexStagingBuffer::~IndexStagingBuffer() -{ - Destroy(); -} - -void IndexStagingBuffer::Create(size_t size, bool allowReadBack /*= false*/, bool managed /*= true*/) -{ - m_Size = size; - m_AllowReadBack = allowReadBack; - - u32 dwUsage = m_AllowReadBack ? 0 : D3DUSAGE_WRITEONLY; - if (HW.Caps.geometry.bSoftware) - dwUsage |= D3DUSAGE_SOFTWAREPROCESSING; - R_CHK(HW.pDevice->CreateIndexBuffer(size, dwUsage, D3DFMT_INDEX16, managed ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT, &m_DeviceBuffer, NULL)); - - HW.stats_manager.increment_stats_ib(m_DeviceBuffer); - AddRef(); -} - -bool IndexStagingBuffer::IsValid() const -{ - return !!m_DeviceBuffer; -} - -void* IndexStagingBuffer::Map( - size_t offset /*= 0 */, - size_t size /*= 0 */, - bool read /*= false*/) -{ - VERIFY(IsValid()); - VERIFY2(!read || m_AllowReadBack, "Can't read from write only buffer"); - VERIFY(size <= m_Size); - - u32 mapMode = read ? D3DLOCK_READONLY : 0; - R_CHK(m_DeviceBuffer->Lock(offset, size, const_cast(&m_HostBuffer), mapMode)); - return m_HostBuffer; -} - -void IndexStagingBuffer::Unmap(bool /*doFlush = false*/) -{ - VERIFY(IsValid()); - R_CHK(m_DeviceBuffer->Unlock()); -} - -void IndexStagingBuffer::DiscardHostBuffer() -{ - /* Do nothing */ -} - -IndexBufferHandle IndexStagingBuffer::GetBufferHandle() const -{ - return m_DeviceBuffer; -} - -void IndexStagingBuffer::Destroy() -{ - HW.stats_manager.decrement_stats_ib(m_DeviceBuffer); - _RELEASE(m_DeviceBuffer); - m_DeviceBuffer = nullptr; -} - -size_t IndexStagingBuffer::GetSystemMemoryUsage() const -{ - if (IsValid()) - { - D3DINDEXBUFFER_DESC desc; - m_DeviceBuffer->GetDesc(&desc); - - if (desc.Pool == D3DPOOL_MANAGED || desc.Pool == D3DPOOL_SCRATCH) - return desc.Size; - } - - return 0; -} - -size_t IndexStagingBuffer::GetVideoMemoryUsage() const -{ - if (IsValid()) - { - D3DINDEXBUFFER_DESC desc; - m_DeviceBuffer->GetDesc(&desc); - - if (desc.Pool == D3DPOOL_DEFAULT || desc.Pool == D3DPOOL_MANAGED) - return desc.Size; - } - - return 0; -} - -//----------------------------------------------------------------------------- -VertexStreamBuffer::~VertexStreamBuffer() -{ - Destroy(); -} - -void VertexStreamBuffer::Create(size_t size) -{ - R_CHK(HW.pDevice->CreateVertexBuffer( - size, - D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, - 0, - D3DPOOL_DEFAULT, - &m_DeviceBuffer, - NULL)); - VERIFY(m_DeviceBuffer); - AddRef(); - HW.stats_manager.increment_stats_vb(m_DeviceBuffer); -} - -void VertexStreamBuffer::Destroy() -{ - if (m_DeviceBuffer == nullptr) - return; - - HW.stats_manager.decrement_stats_vb(m_DeviceBuffer); - _RELEASE(m_DeviceBuffer); -} - -void* VertexStreamBuffer::Map(size_t offset, size_t size, bool flush /*= false*/) -{ - VERIFY(m_DeviceBuffer); - - void *pData = nullptr; - const auto flags = flush ? LOCKFLAGS_FLUSH : LOCKFLAGS_APPEND; - R_CHK(m_DeviceBuffer->Lock(offset, size, &pData, flags)); - return pData; -} - -void VertexStreamBuffer::Unmap() -{ - VERIFY(m_DeviceBuffer); - m_DeviceBuffer->Unlock(); -} - -bool VertexStreamBuffer::IsValid() const -{ - return !!m_DeviceBuffer; -} - -//----------------------------------------------------------------------------- -IndexStreamBuffer::~IndexStreamBuffer() -{ - Destroy(); -} - -void IndexStreamBuffer::Create(size_t size) -{ - R_CHK(HW.pDevice->CreateIndexBuffer( - size, - D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, - D3DFMT_INDEX16, - D3DPOOL_DEFAULT, - &m_DeviceBuffer, - NULL)); - VERIFY(m_DeviceBuffer); - AddRef(); - HW.stats_manager.increment_stats_ib(m_DeviceBuffer); -} - -void IndexStreamBuffer::Destroy() -{ - if (m_DeviceBuffer == nullptr) - return; - - HW.stats_manager.decrement_stats_ib(m_DeviceBuffer); - _RELEASE(m_DeviceBuffer); -} - -void* IndexStreamBuffer::Map(size_t offset, size_t size, bool flush /*= false*/) -{ - VERIFY(m_DeviceBuffer); - - void *pData = nullptr; - const auto flags = flush ? LOCKFLAGS_FLUSH : LOCKFLAGS_APPEND; - m_DeviceBuffer->Lock(offset, size, &pData, flags); - return pData; -} - -void IndexStreamBuffer::Unmap() -{ - VERIFY(m_DeviceBuffer); - m_DeviceBuffer->Unlock(); -} - -bool IndexStreamBuffer::IsValid() const -{ - return !!m_DeviceBuffer; -} diff --git a/src/Layers/xrRenderDX9/CommonTypes.h b/src/Layers/xrRenderDX9/CommonTypes.h deleted file mode 100644 index e547a9a47e7..00000000000 --- a/src/Layers/xrRenderDX9/CommonTypes.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -typedef IDirect3DVertexShader9 ID3DVertexShader; -typedef IDirect3DPixelShader9 ID3DPixelShader; -typedef IDirect3DQuery9 ID3DQuery; -typedef IDirect3DTexture9 ID3DTexture2D; -typedef IDirect3DSurface9 ID3DRenderTargetView; -typedef IDirect3DSurface9 ID3DDepthStencilView; -typedef IDirect3DDevice9 ID3DDevice; -typedef IDirect3DBaseTexture9 ID3DBaseTexture; -typedef D3DSURFACE_DESC D3D_TEXTURE2D_DESC; -typedef IDirect3DVertexBuffer9 ID3DVertexBuffer; -typedef IDirect3DIndexBuffer9 ID3DIndexBuffer; -typedef IDirect3DVolumeTexture9 ID3DTexture3D; -typedef IDirect3DStateBlock9 ID3DState; - -using D3D_QUERY = D3DQUERYTYPE; -constexpr auto D3D_QUERY_EVENT = D3DQUERYTYPE_EVENT; -constexpr auto D3D_QUERY_OCCLUSION = D3DQUERYTYPE_OCCLUSION; - -#define DX11_ONLY(expr) do {} while (0) - -struct D3D_VIEWPORT : D3DVIEWPORT9 -{ - using D3DVIEWPORT9::D3DVIEWPORT9; - - // Needed to suppress warnings - template - D3D_VIEWPORT(TopLeftCoords x, TopLeftCoords y, Dimensions w, Dimensions h, float minZ, float maxZ) - : D3DVIEWPORT9{ - static_cast(x), static_cast(y), - static_cast(w), static_cast(h), - minZ, maxZ - } - {} -}; - -using unused_t = int[0]; - -using VertexBufferHandle = ID3DVertexBuffer*; -using IndexBufferHandle = ID3DIndexBuffer*; -using ConstantBufferHandle = unused_t; -using HostBufferHandle = void*; - -using VertexElement = D3DVERTEXELEMENT9; -using InputElementDesc = unused_t; diff --git a/src/Layers/xrRenderDX9/dx9DetailManager_VS.cpp b/src/Layers/xrRenderDX9/dx9DetailManager_VS.cpp deleted file mode 100644 index f669e8120e5..00000000000 --- a/src/Layers/xrRenderDX9/dx9DetailManager_VS.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop -#include "Layers/xrRender/DetailManager.h" - -namespace detail_manager -{ -extern const int quant; -extern const int c_hdr; -} - -void CDetailManager::hw_Load_Shaders() -{ - // Create shader to access constant storage - ref_shader S; - S.create("details" DELIMITER "set"); - R_constant_table& T0 = *(S->E[0]->passes[0]->constants); - R_constant_table& T1 = *(S->E[1]->passes[0]->constants); - hwc_consts = T0.get("consts"); - hwc_wave = T0.get("wave"); - hwc_wind = T0.get("dir2D"); - hwc_array = T0.get("array"); - hwc_s_consts = T1.get("consts"); - hwc_s_xform = T1.get("xform"); - hwc_s_array = T1.get("array"); -} - -void CDetailManager::hw_Render(CBackend& cmd_list) -{ - using namespace detail_manager; - - // Render-prepare - // Update timer - // Can't use Device.fTimeDelta since it is smoothed! Don't know why, but smoothed value looks more choppy! - float fDelta = Device.fTimeGlobal - m_global_time_old; - if ((fDelta < 0) || (fDelta > 1)) - fDelta = 0.03f; - m_global_time_old = Device.fTimeGlobal; - - m_time_rot_1 += (PI_MUL_2 * fDelta / swing_current.rot1); - m_time_rot_2 += (PI_MUL_2 * fDelta / swing_current.rot2); - m_time_pos += fDelta * swing_current.speed; - - // float tm_rot1 = (PI_MUL_2*Device.fTimeGlobal/swing_current.rot1); - // float tm_rot2 = (PI_MUL_2*Device.fTimeGlobal/swing_current.rot2); - float tm_rot1 = m_time_rot_1; - float tm_rot2 = m_time_rot_2; - - Fvector4 dir1, dir2; - dir1.set(_sin(tm_rot1), 0, _cos(tm_rot1), 0).normalize().mul(swing_current.amp1); - dir2.set(_sin(tm_rot2), 0, _cos(tm_rot2), 0).normalize().mul(swing_current.amp2); - - // Setup geometry and DMA - cmd_list.set_Geometry(hw_Geom); - - // Wave0 - float scale = 1.f / float(quant); - Fvector4 wave; - // wave.set (1.f/5.f, 1.f/7.f, 1.f/3.f, Device.fTimeGlobal*swing_current.speed); - wave.set(1.f / 5.f, 1.f / 7.f, 1.f / 3.f, m_time_pos); - cmd_list.set_c(&*hwc_consts, scale, scale, ps_r__Detail_l_aniso, ps_r__Detail_l_ambient); // consts - cmd_list.set_c(&*hwc_wave, wave.div(PI_MUL_2)); // wave - cmd_list.set_c(&*hwc_wind, dir1); // wind-dir - hw_Render_dump(cmd_list, &*hwc_array, 1, 0, c_hdr); - - // Wave1 - // wave.set (1.f/3.f, 1.f/7.f, 1.f/5.f, Device.fTimeGlobal*swing_current.speed); - wave.set(1.f / 3.f, 1.f / 7.f, 1.f / 5.f, m_time_pos); - cmd_list.set_c(&*hwc_wave, wave.div(PI_MUL_2)); // wave - cmd_list.set_c(&*hwc_wind, dir2); // wind-dir - hw_Render_dump(cmd_list, &*hwc_array, 2, 0, c_hdr); - - // Still - cmd_list.set_c(&*hwc_s_consts, scale, scale, scale, 1.f); - cmd_list.set_c(&*hwc_s_xform, Device.mFullTransform); - hw_Render_dump(cmd_list, &*hwc_s_array, 0, 1, c_hdr); -} - -void CDetailManager::hw_Render_dump(CBackend& cmd_list, ref_constant x_array, u32 var_id, u32 lod_id, u32 /*c_offset*/) -{ - RImplementation.BasicStats.DetailCount = 0; - - // Matrices and offsets - u32 vOffset = 0; - u32 iOffset = 0; - - vis_list& list = m_visibles[var_id]; - - Fvector c_sun, c_ambient, c_hemi; -#ifndef _EDITOR - const auto& desc = g_pGamePersistent->Environment().CurrentEnv; - c_sun.set(desc.sun_color.x, desc.sun_color.y, desc.sun_color.z); - c_sun.mul(.5f); - c_ambient.set(desc.ambient.x, desc.ambient.y, desc.ambient.z); - c_hemi.set(desc.hemi_color.x, desc.hemi_color.y, desc.hemi_color.z); -#else - c_sun.set(1, 1, 1); - c_sun.mul(.5f); - c_ambient.set(1, 1, 1); - c_hemi.set(1, 1, 1); -#endif - - VERIFY(objects.size() <= list.size()); - - // Iterate - for (u32 O = 0; O < objects.size(); O++) - { - CDetail& Object = *objects[O]; - xr_vector& vis = list[O]; - if (!vis.empty()) - { - // Setup matrices + colors (and flush it as nesessary) - cmd_list.set_Element(Object.shader->E[lod_id]); - cmd_list.apply_lmaterial(); - u32 c_base = x_array->vs.index; - Fvector4* c_storage = cmd_list.get_ConstantCache_Vertex().get_array_f().access(c_base); - - u32 dwBatch = 0; - - xr_vector::iterator _vI = vis.begin(); - xr_vector::iterator _vE = vis.end(); - for (; _vI != _vE; ++_vI) - { - SlotItemVec* items = *_vI; - auto _iI = items->begin(); - auto _iE = items->end(); - for (; _iI != _iE; ++_iI) - { - SlotItem& Instance = **_iI; - u32 base = dwBatch * 4; - - // Build matrix ( 3x4 matrix, last row - color ) - float scale = Instance.scale_calculated; - Fmatrix& M = Instance.mRotY; - c_storage[base + 0].set(M._11 * scale, M._21 * scale, M._31 * scale, M._41); - c_storage[base + 1].set(M._12 * scale, M._22 * scale, M._32 * scale, M._42); - c_storage[base + 2].set(M._13 * scale, M._23 * scale, M._33 * scale, M._43); - -// Build color -#if RENDER == R_R1 - Fvector C; - C.set(c_ambient); - // C.mad (c_lmap,Instance.c_rgb); - C.mad(c_hemi, Instance.c_hemi); - C.mad(c_sun, Instance.c_sun); - c_storage[base + 3].set(C.x, C.y, C.z, 1.f); -#else - // R2 only needs hemisphere - float h = Instance.c_hemi; - float s = Instance.c_sun; - c_storage[base + 3].set(s, s, s, h); -#endif - dwBatch++; - if (dwBatch == hw_BatchSize) - { - // flush - RImplementation.BasicStats.DetailCount += dwBatch; - u32 dwCNT_verts = dwBatch * Object.number_vertices; - u32 dwCNT_prims = (dwBatch * Object.number_indices) / 3; - cmd_list.get_ConstantCache_Vertex().b_dirty = TRUE; - cmd_list.get_ConstantCache_Vertex().get_array_f().dirty(c_base, c_base + dwBatch * 4); - cmd_list.Render(D3DPT_TRIANGLELIST, vOffset, 0, dwCNT_verts, iOffset, dwCNT_prims); - cmd_list.stat.r.s_details.add(dwCNT_verts); - - // restart - dwBatch = 0; - } - } - } - // flush if nessecary - if (dwBatch) - { - RImplementation.BasicStats.DetailCount += dwBatch; - u32 dwCNT_verts = dwBatch * Object.number_vertices; - u32 dwCNT_prims = (dwBatch * Object.number_indices) / 3; - cmd_list.get_ConstantCache_Vertex().b_dirty = TRUE; - cmd_list.get_ConstantCache_Vertex().get_array_f().dirty(c_base, c_base + dwBatch * 4); - cmd_list.Render(D3DPT_TRIANGLELIST, vOffset, 0, dwCNT_verts, iOffset, dwCNT_prims); - cmd_list.stat.r.s_details.add(dwCNT_verts); - } - } - vOffset += hw_BatchSize * Object.number_vertices; - iOffset += hw_BatchSize * Object.number_indices; - } -} diff --git a/src/Layers/xrRenderDX9/dx9HW.cpp b/src/Layers/xrRenderDX9/dx9HW.cpp deleted file mode 100644 index 16f559f9e20..00000000000 --- a/src/Layers/xrRenderDX9/dx9HW.cpp +++ /dev/null @@ -1,495 +0,0 @@ -#include "stdafx.h" - -#include "dx9HW.h" - -#include - -CHW HW; - -CHW::CHW() -{ - if (!ThisInstanceIsGlobal()) - return; - - Device.seqAppActivate.Add(this); - Device.seqAppDeactivate.Add(this); -} - -CHW::~CHW() -{ - if (!ThisInstanceIsGlobal()) - return; - - Device.seqAppActivate.Remove(this); - Device.seqAppDeactivate.Remove(this); -} - -void CHW::OnAppActivate() -{ - if (!DevPP.Windowed) - { - ShowWindow(DevPP.hDeviceWindow, SW_RESTORE); - } -} - -void CHW::OnAppDeactivate() -{ - if (!DevPP.Windowed) - { - if (psDeviceMode.WindowStyle == rsFullscreen || psDeviceMode.WindowStyle == rsFullscreenBorderless) - ShowWindow(DevPP.hDeviceWindow, SW_MINIMIZE); - } -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -void CHW::CreateD3D() -{ - hD3D = XRay::LoadModule(GEnv.isDedicatedServer ? "xrD3D9-Null" : "d3d9"); - if (!hD3D->IsLoaded()) - return; - - // XXX: enable when D3DPOOL_MANAGED will be removed from the engine - //const auto createD3DEx = (decltype(&Direct3DCreate9Ex))hD3D->GetProcAddress("Direct3DCreate9Ex"); - //if (createD3DEx) - //{ - // IDirect3D9Ex* pD3DEx{}; - // if (SUCCEEDED(createD3DEx(D3D_SDK_VERSION, &pD3DEx))) - // pD3D = pD3DEx; - //} - - //if (!pD3D) - { - const auto createD3D = (decltype(&Direct3DCreate9))hD3D->GetProcAddress("Direct3DCreate9"); - if (createD3D) - pD3D = createD3D(D3D_SDK_VERSION); - } - - if (!pD3D) - Log("! Found d3d9.dll, but couldn't initialize it. Please install latest DirectX 9.0."); -} - -void CHW::DestroyD3D() -{ - _SHOW_REF("refCount:pD3D", pD3D); - _RELEASE(pD3D); - hD3D = nullptr; -} - -void CHW::CreateDevice(SDL_Window* sdlWnd) -{ - CreateD3D(); - - const bool bWindowed = ThisInstanceIsGlobal() ? psDeviceMode.WindowStyle != rsFullscreen : true; - - m_DriverType = Caps.bForceGPU_REF ? D3DDEVTYPE_REF : D3DDEVTYPE_HAL; - - DevAdapter = D3DADAPTER_DEFAULT; - - // Display the name of video board - D3DADAPTER_IDENTIFIER9 adapterID; - R_CHK(pD3D->GetAdapterIdentifier(DevAdapter, 0, &adapterID)); - Msg("* GPU [vendor:%X]-[device:%X]: %s", adapterID.VendorId, adapterID.DeviceId, adapterID.Description); - - const u16 driverProduct = HIWORD(adapterID.DriverVersion.HighPart); - const u16 driverVersion = LOWORD(adapterID.DriverVersion.HighPart); - const u16 driverSubVersion = HIWORD(adapterID.DriverVersion.LowPart); - const u16 driverBuild = LOWORD(adapterID.DriverVersion.LowPart); - Msg("* GPU driver: %d.%d.%d.%d", u32(driverProduct), u32(driverVersion), u32(driverSubVersion), u32(driverBuild)); - - Caps.id_vendor = adapterID.VendorId; - Caps.id_device = adapterID.DeviceId; - - // Select back-buffer & depth-stencil format - D3DFORMAT& fTarget = Caps.fTarget; - D3DFORMAT& fDepth = Caps.fDepth; - if (bWindowed) - { - // Retrieve display mode - D3DDISPLAYMODE mode; - R_CHK(pD3D->GetAdapterDisplayMode(DevAdapter, &mode)); - - // Apply its format - fTarget = mode.Format; - - // Apply depth - R_CHK(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, TRUE)); - fDepth = selectDepthStencil(fTarget); - } - else - { - switch (psDeviceMode.BitsPerPixel) - { - default: - case 32: - fTarget = D3DFMT_X8R8G8B8; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_A8R8G8B8; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_R8G8B8; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_UNKNOWN; - break; - case 16: - fTarget = D3DFMT_R5G6B5; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_X1R5G5B5; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_X4R4G4B4; - if (SUCCEEDED(pD3D->CheckDeviceType(DevAdapter, m_DriverType, fTarget, fTarget, FALSE))) - break; - fTarget = D3DFMT_UNKNOWN; - break; - } - fDepth = selectDepthStencil(fTarget); - } - - if (D3DFMT_UNKNOWN == fTarget || D3DFMT_UNKNOWN == fDepth) - { - Log("Failed to initialize graphics hardware.\n" - "Please try to restart the game.\n" - "Can not find matching format for back buffer."); - xrDebug::DoExit("Failed to initialize graphics hardware.\nPlease try to restart the game."); - } - - // Set up the presentation parameters - D3DPRESENT_PARAMETERS& P = DevPP; - ZeroMemory(&P, sizeof(P)); - - P.BackBufferWidth = Device.dwWidth; - P.BackBufferHeight = Device.dwHeight; - - // Back buffer - BackBufferCount = 1; - P.BackBufferFormat = fTarget; - P.BackBufferCount = BackBufferCount; - - // Multisample - P.MultiSampleType = D3DMULTISAMPLE_NONE; - P.MultiSampleQuality = 0; - - // Windoze - P.SwapEffect = bWindowed ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; - P.Windowed = bWindowed; - - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(sdlWnd, &info)) - P.hDeviceWindow = info.info.win.window; - else - { - cpcstr error = SDL_GetError(); - Log("! Couldn't get window information: ", error); - FATAL(error); - } - - // Depth/stencil - P.EnableAutoDepthStencil = TRUE; - P.AutoDepthStencilFormat = fDepth; - P.Flags = 0; //. D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; - - // Refresh rate - if (bWindowed) - { - P.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - P.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - } - else - { - P.PresentationInterval = selectPresentInterval(); // Vsync (R1\R2) - P.FullScreen_RefreshRateInHz = psDeviceMode.RefreshRate; - } - - - // Create the device - const auto GPU = selectGPU(); - auto result = pD3D->CreateDevice(DevAdapter, m_DriverType, P.hDeviceWindow, - GPU | D3DCREATE_MULTITHREADED | D3DCREATE_NOWINDOWCHANGES, //. ? locks at present - &P, &pDevice); - - if (FAILED(result)) - { - result = pD3D->CreateDevice(DevAdapter, m_DriverType, P.hDeviceWindow, - GPU | D3DCREATE_MULTITHREADED | D3DCREATE_NOWINDOWCHANGES, //. ? locks at present - &P, &pDevice); - } - if (D3DERR_DEVICELOST == result) - { - // Fatal error! Cannot create rendering device AT STARTUP !!! - Msg("Failed to initialize graphics hardware.\n" - "Please try to restart the game.\n" - "CreateDevice returned 0x%08x(D3DERR_DEVICELOST)", result); - xrDebug::DoExit("Failed to initialize graphics hardware.\nPlease try to restart the game."); - }; - - _SHOW_REF("* CREATE: DeviceREF:", pDevice); - switch (GPU) - { - case D3DCREATE_SOFTWARE_VERTEXPROCESSING: Log("* Vertex Processor: SOFTWARE" ); break; - case D3DCREATE_MIXED_VERTEXPROCESSING: Log("* Vertex Processor: MIXED" ); break; - case D3DCREATE_HARDWARE_VERTEXPROCESSING: Log("* Vertex Processor: HARDWARE" ); break; - case D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE: Log("* Vertex Processor: PURE HARDWARE"); break; - } - - // Capture PIX events - d3dperf_BeginEvent = static_cast(hD3D->GetProcAddress("D3DPERF_BeginEvent")); - d3dperf_EndEvent = static_cast(hD3D->GetProcAddress("D3DPERF_EndEvent")); - - // Capture misc data -#ifdef DEBUG - R_CHK(pDevice->CreateStateBlock(D3DSBT_ALL, &dwDebugSB)); -#endif - const u32 memory = pDevice->GetAvailableTextureMem(); - Msg("* Texture memory: %d M", memory / (1024 * 1024)); -} - -void CHW::DestroyDevice() -{ -#ifdef DEBUG - _SHOW_REF("refCount:dwDebugSB", dwDebugSB); - _RELEASE(dwDebugSB); -#endif - _SHOW_REF("DeviceREF:", pDevice); - _RELEASE(pDevice); - - DestroyD3D(); -} - -////////////////////////////////////////////////////////////////////// -// Resetting device -////////////////////////////////////////////////////////////////////// -void CHW::Reset() -{ -#ifdef DEBUG - _RELEASE(dwDebugSB); -#endif - DevPP.BackBufferWidth = Device.dwWidth; - DevPP.BackBufferHeight = Device.dwHeight; - - // Windoze - const bool bWindowed = ThisInstanceIsGlobal() ? psDeviceMode.WindowStyle != rsFullscreen : true; - DevPP.SwapEffect = bWindowed ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; - DevPP.Windowed = bWindowed; - if (!bWindowed) - { - DevPP.PresentationInterval = selectPresentInterval(); // Vsync (R1\R2) - DevPP.FullScreen_RefreshRateInHz = psDeviceMode.RefreshRate; - } - else - { - DevPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - DevPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - } - - while (true) - { - const HRESULT result = pDevice->Reset(&DevPP); - - if (SUCCEEDED(result)) - break; - - Msg("! ERROR: [%dx%d]: %s", DevPP.BackBufferWidth, DevPP.BackBufferHeight, xrDebug::ErrorToString(result)); - Sleep(100); - } -#ifdef DEBUG - R_CHK(pDevice->CreateStateBlock(D3DSBT_ALL, &dwDebugSB)); -#endif -} - -void CHW::SetPrimaryAttributes(u32& /*windowFlags*/) -{ - Caps.bForceGPU_SW = strstr(Core.Params, "-gpu_sw"); - Caps.bForceGPU_NonPure = strstr(Core.Params, "-gpu_nopure"); - Caps.bForceGPU_REF = strstr(Core.Params, "-gpu_ref"); -} - -D3DFORMAT CHW::selectDepthStencil(D3DFORMAT fTarget) const -{ - // R2 hack -#pragma todo("R2 need to specify depth format") - if (RImplementation.GenerationIsR2()) - return D3DFMT_D24S8; - - // R1 usual - constexpr D3DFORMAT formats[] = - { - D3DFMT_D24S8, - D3DFMT_D24X4S4, - D3DFMT_D32, - D3DFMT_D24X8, - D3DFMT_D16, - D3DFMT_D15S1 - }; - - for (D3DFORMAT fmt : formats) - { - if (SUCCEEDED(pD3D->CheckDeviceFormat( - DevAdapter, m_DriverType, fTarget, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, fmt))) - { - if (SUCCEEDED(pD3D->CheckDepthStencilMatch(DevAdapter, m_DriverType, fTarget, fTarget, fmt))) - { - return fmt; - } - } - } - return D3DFMT_UNKNOWN; -} - -bool CHW::ThisInstanceIsGlobal() const -{ - return this == &HW; -} - -void CHW::BeginPixEvent(LPCWSTR wszName) const -{ - if (d3dperf_BeginEvent) - d3dperf_BeginEvent(D3DCOLOR_RGBA(127, 0, 0, 255), wszName); -} - -void CHW::EndPixEvent() const -{ - if (d3dperf_EndEvent) - d3dperf_EndEvent(); -} - -u32 CHW::selectPresentInterval() const -{ - D3DCAPS9 caps; - pD3D->GetDeviceCaps(DevAdapter, m_DriverType, &caps); - - if (!psDeviceFlags.test(rsVSync)) - { - if (caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) - return D3DPRESENT_INTERVAL_IMMEDIATE; - if (caps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) - return D3DPRESENT_INTERVAL_ONE; - } - return D3DPRESENT_INTERVAL_DEFAULT; -} - -bool CHW::GivenGPUIsIntelGMA(u32 id_vendor, u32 id_device) -{ - if (id_vendor == 0x8086) // Intel - { - constexpr u32 IntelGMA_SoftList[] = - { - 0x2782, 0x2582, 0x2792, 0x2592, 0x2772, 0x2776, 0x27A2, 0x27A6, 0x27AE, - 0x2982, 0x2983, 0x2992, 0x2993, 0x29A2, 0x29A3, 0x2972, 0x2973, 0x2A02, - 0x2A03, 0x2A12, 0x2A13, 0x29C2, 0x29C3, 0x29B2, 0x29B3, 0x29D2, 0x29D3, - 0x2A42, 0x2A43, 0x2E02, 0x2E03, 0x2E12, 0x2E13, 0x2E22, 0x2E23, 0x2E32, - 0x2E33, 0x2E42, 0x2E43, 0x2E92, 0x2E93, 0x0042, 0x0046 - }; - - for (u32 idx : IntelGMA_SoftList) - { - if (idx == id_device) - return true; - } - } - return false; -} - -void AdjustSkinningMode(bool isIntelGMA) -{ - if (isIntelGMA) - { - switch (ps_r1_SoftwareSkinning) - { - case 0: - Log("* Enabling software skinning"); - ps_r1_SoftwareSkinning = 1; - break; - case 1: Log("* Using software skinning"); break; - case 2: - Log("* WARNING: Using hardware skinning"); - Log("* setting 'r1_software_skinning' to '1' may improve performance"); - break; - } - } - else if (ps_r1_SoftwareSkinning == 1) - { - Msg("* WARNING: Using software skinning"); - Msg("* setting 'r1_software_skinning' to '0' should improve performance"); - } -} - -u32 CHW::selectGPU() const -{ - if (ThisInstanceIsGlobal()) - AdjustSkinningMode(GivenGPUIsIntelGMA(Caps.id_vendor, Caps.id_device)); - - if (Caps.bForceGPU_SW) - return D3DCREATE_SOFTWARE_VERTEXPROCESSING; - - D3DCAPS9 caps; - pD3D->GetDeviceCaps(DevAdapter, m_DriverType, &caps); - - if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) - { - if (Caps.bForceGPU_NonPure) - return D3DCREATE_HARDWARE_VERTEXPROCESSING; - if (caps.DevCaps & D3DDEVCAPS_PUREDEVICE) - return D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; - return D3DCREATE_HARDWARE_VERTEXPROCESSING; - // return D3DCREATE_MIXED_VERTEXPROCESSING; - } - - return D3DCREATE_SOFTWARE_VERTEXPROCESSING; -} - -BOOL CHW::support(D3DFORMAT fmt, u32 type, u32 usage) const -{ - const HRESULT result = pD3D->CheckDeviceFormat(DevAdapter, m_DriverType, Caps.fTarget, usage, (D3DRESOURCETYPE)type, fmt); - if (FAILED(result)) - return FALSE; - return TRUE; -} - -std::pair CHW::GetSurfaceSize() const -{ - return - { - DevPP.BackBufferWidth, - DevPP.BackBufferHeight - }; -} - -void CHW::BeginScene() -{ - CHK_DX(HW.pDevice->BeginScene()); -} - -void CHW::EndScene() -{ - CHK_DX(HW.pDevice->EndScene()); -} - -void CHW::Present() -{ - pDevice->Present(nullptr, nullptr, nullptr, nullptr); - CurrentBackBuffer = (CurrentBackBuffer + 1) % BackBufferCount; -} - -DeviceState CHW::GetDeviceState() const -{ - const auto result = pDevice->TestCooperativeLevel(); - - switch (result) - { - // If the device was lost, do not render until we get it back - case D3DERR_DEVICELOST: - return DeviceState::Lost; - - // Check if the device is ready to be reset - case D3DERR_DEVICENOTRESET: - return DeviceState::NeedReset; - } - - return DeviceState::Normal; -} diff --git a/src/Layers/xrRenderDX9/dx9HW.h b/src/Layers/xrRenderDX9/dx9HW.h deleted file mode 100644 index a7bd59773b2..00000000000 --- a/src/Layers/xrRenderDX9/dx9HW.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include "xrCore/ModuleLookup.hpp" - -#include "Layers/xrRender/HWCaps.h" -#include "Layers/xrRender/stats_manager.h" - -#include - -class CHW - : public pureAppActivate, - public pureAppDeactivate -{ -public: - CHW(); - ~CHW(); - - void CreateD3D(); - void DestroyD3D(); - - void CreateDevice(SDL_Window* sdlWnd); - void DestroyDevice(); - - void Reset(); - - void SetPrimaryAttributes(u32& windowFlags); - - BOOL support(D3DFORMAT fmt, u32 type, u32 usage) const; - static bool GivenGPUIsIntelGMA(u32 id_vendor, u32 id_device); - - std::pair GetSurfaceSize() const; - DeviceState GetDeviceState() const; - -public: - void BeginScene(); - void EndScene(); - void Present(); - -public: - void OnAppActivate() override; - void OnAppDeactivate() override; - -public: - void BeginPixEvent(LPCWSTR wszName) const; - void EndPixEvent() const; - -private: - u32 selectPresentInterval() const; - u32 selectGPU() const; - D3DFORMAT selectDepthStencil(D3DFORMAT) const; - bool ThisInstanceIsGlobal() const; - -public: - static constexpr auto IMM_CTX_ID = 0; - - CHWCaps Caps; - - u32 BackBufferCount{}; - u32 CurrentBackBuffer{}; - - ID3DDevice* pDevice = nullptr; // render device - - D3DDEVTYPE m_DriverType; - -#ifdef DEBUG - IDirect3DStateBlock9* dwDebugSB = nullptr; -#endif - - IDirect3D9* pD3D = nullptr; // D3D - - u32 DevAdapter; - - decltype(&D3DPERF_BeginEvent) d3dperf_BeginEvent = nullptr; - decltype(&D3DPERF_EndEvent) d3dperf_EndEvent = nullptr; - -#if !defined(_MAYA_EXPORT) - stats_manager stats_manager; -#endif - -private: - D3DPRESENT_PARAMETERS DevPP; - XRay::Module hD3D = nullptr; -}; - -extern ECORE_API CHW HW; diff --git a/src/Layers/xrRenderDX9/dx9HWCaps.cpp b/src/Layers/xrRenderDX9/dx9HWCaps.cpp deleted file mode 100644 index e42bb1435b0..00000000000 --- a/src/Layers/xrRenderDX9/dx9HWCaps.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "Layers/xrRender/HWCaps.h" -#include "dx9HW.h" - -#if !defined(_EDITOR) -#include -#endif - -namespace -{ -#if !defined(_EDITOR) -u32 GetNVGpuNum() -{ - NvLogicalGpuHandle logicalGPUs[NVAPI_MAX_LOGICAL_GPUS]; - NvU32 logicalGPUCount; - NvPhysicalGpuHandle physicalGPUs[NVAPI_MAX_PHYSICAL_GPUS]; - NvU32 physicalGPUCount; - - // int result = NVAPI_OK; - - NvAPI_Status status; - status = NvAPI_Initialize(); - - if (status != NVAPI_OK) - { - Msg("* NVAPI is missing."); - return 0; - } - - // enumerate logical gpus - status = NvAPI_EnumLogicalGPUs(logicalGPUs, &logicalGPUCount); - if (status != NVAPI_OK) - { - Msg("* NvAPI_EnumLogicalGPUs failed!"); - return 0; - } - - // enumerate physical gpus - status = NvAPI_EnumPhysicalGPUs(physicalGPUs, &physicalGPUCount); - if (status != NVAPI_OK) - { - Msg("* NvAPI_EnumPhysicalGPUs failed!"); - return 0; - } - - int iGpuNum = 0; - Msg("* NVidia MGPU: Logical(%d), Physical(%d)", physicalGPUCount, logicalGPUCount); - - // Assume that we are running on logical GPU with most physical GPUs connected. - for (u32 i = 0; i < logicalGPUCount; ++i) - { - status = NvAPI_GetPhysicalGPUsFromLogicalGPU(logicalGPUs[i], physicalGPUs, &physicalGPUCount); - if (status == NVAPI_OK) - iGpuNum = _max(iGpuNum, physicalGPUCount); - } - - if (iGpuNum > 1) - Msg("* NVidia MGPU: %d-Way SLI detected.", iGpuNum); - - return iGpuNum; -} - -u32 GetATIGpuNum() -{ - const auto atimgpud = XRay::LoadModule("ATIMGPUD"); - if (!atimgpud->IsLoaded()) - return 0; - - using ATIQUERYMGPUCOUNT = INT(*)(); - - const auto AtiQueryMgpuCount = (ATIQUERYMGPUCOUNT)atimgpud->GetProcAddress("AtiQueryMgpuCount"); - - if (!AtiQueryMgpuCount) - return 0; - - const int iGpuNum = AtiQueryMgpuCount(); - if (iGpuNum > 1) - Msg("* ATI MGPU: %d-Way CrossFire detected.", iGpuNum); - - return iGpuNum; -} - -u32 GetGpuNum() -{ - u32 res = GetNVGpuNum(); - res = _max(res, GetATIGpuNum()); - res = _max(res, 2); - res = _min(res, CHWCaps::MAX_GPUS); - - if (res == 0) - { - Log("! Cannot find graphic adapter. Assuming that you have one..."); - res = 1; - } - - Msg("* Starting rendering as %d-GPU.", res); - - return res; -} -#else -u32 GetGpuNum() { return 1; } -#endif -} - -static pcstr GetVertexShaderProfile(const D3DCAPS9& caps) -{ - switch (caps.VertexShaderVersion) - { -#if RENDER != R_R1 - case D3DVS_VERSION(3, 0): return "vs_3_0"; - - case D3DVS_VERSION(2, 0): - if (caps.VS20Caps.NumTemps >= 13 && - caps.VS20Caps.DynamicFlowControlDepth == 24 && - caps.VS20Caps.Caps & D3DPS20CAPS_PREDICATION) - { - return "vs_2_a"; - } - [[fallthrough]]; -#endif - default: return "vs_2_0"; - - case D3DVS_VERSION(1, 1): return "vs_1_1"; - } -} - -static pcstr GetPixelShaderProfile(const D3DCAPS9& caps) -{ -#if RENDER == R_R1 - return "ps_2_0"; -#else // R2 - switch (caps.PixelShaderVersion) - { - case D3DPS_VERSION(3, 0): return "ps_3_0"; - - case D3DPS_VERSION(2, 0): - if (caps.PS20Caps.NumTemps >= 22 && - caps.PS20Caps.Caps & D3DPS20CAPS_ARBITRARYSWIZZLE && - caps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS && - caps.PS20Caps.Caps & D3DPS20CAPS_PREDICATION && - caps.PS20Caps.Caps & D3DPS20CAPS_NODEPENDENTREADLIMIT && - caps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) - { - return "ps_2_a"; - } - if (caps.PS20Caps.NumTemps >= 32 && - caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) - { - return "ps_2_b"; - } - [[fallthrough]]; - - default: return "ps_2_0"; - - case D3DPS_VERSION(1, 4): return "ps_1_4"; - case D3DPS_VERSION(1, 3): return "ps_1_3"; - case D3DPS_VERSION(1, 2): return "ps_1_2"; - case D3DPS_VERSION(1, 1): return "ps_1_1"; - } -#endif -} - -void CHWCaps::Update() -{ - D3DCAPS9 caps; - HW.pDevice->GetDeviceCaps(&caps); - - // ***************** GEOMETRY - geometry_major = u16((u32(caps.VertexShaderVersion) & (0xf << 8ul)) >> 8); - geometry_minor = u16((u32(caps.VertexShaderVersion) & 0xf)); - geometry_profile = GetVertexShaderProfile(caps); - geometry.bSoftware = (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0; - geometry.bPointSprites = FALSE; - geometry.bNPatches = (caps.DevCaps & D3DDEVCAPS_NPATCHES) != 0; - u32 cnt = (caps.MaxVertexShaderConst); - clamp(cnt, 0, 256); - geometry.dwRegisters = cnt; - geometry.dwInstructions = 256; - geometry.dwClipPlanes = _min(caps.MaxUserClipPlanes, 15); - geometry.bVTF = (geometry_major >= 3) && HW.support(D3DFMT_R32F, D3DRTYPE_TEXTURE, D3DUSAGE_QUERY_VERTEXTEXTURE); - - // ***************** PIXEL processing - raster_major = u16(u32(u32(caps.PixelShaderVersion) & u32(0xf << 8ul)) >> 8); - raster_minor = u16(u32(u32(caps.PixelShaderVersion) & u32(0xf))); - raster_profile = GetPixelShaderProfile(caps); - raster.dwStages = caps.MaxSimultaneousTextures; - raster.bNonPow2 = ((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0) || - ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0); - raster.bCubemap = (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0; - raster.dwMRT_count = (caps.NumSimultaneousRTs); - raster.b_MRT_mixdepth = (caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) != 0; - raster.dwInstructions = (caps.PS20Caps.NumInstructionSlots); - - // ***************** Info - Msg("* GPU shading: vs(%x/%d.%d/%d), ps(%x/%d.%d/%d)", caps.VertexShaderVersion, geometry_major, geometry_minor, - CAP_VERSION(geometry_major, geometry_minor), caps.PixelShaderVersion, raster_major, raster_minor, - CAP_VERSION(raster_major, raster_minor)); - - // *******1********** Vertex cache - ID3DQuery* q_vc; - D3DDEVINFO_VCACHE vc; - HRESULT _hr = HW.pDevice->CreateQuery(D3DQUERYTYPE_VCACHE, &q_vc); - if (FAILED(_hr)) - { - vc.OptMethod = 0; - vc.CacheSize = 16; - geometry.dwVertexCache = 16; - } - else - { - q_vc->Issue(D3DISSUE_END); - q_vc->GetData(&vc, sizeof(vc), D3DGETDATA_FLUSH); - _RELEASE(q_vc); - if (1 == vc.OptMethod) - geometry.dwVertexCache = vc.CacheSize; - else - geometry.dwVertexCache = 16; - } - Msg("* GPU vertex cache: %s, %d", (1 == vc.OptMethod) ? "recognized" : "unrecognized", u32(geometry.dwVertexCache)); - - // *******1********** Compatibility : vertex shader - if (0 == raster_major) - geometry_major = 0; // Disable VS if no PS -#ifdef _EDITOR - geometry_major = 0; -#endif - - // - bTableFog = FALSE; // BOOL (caps.RasterCaps&D3DPRASTERCAPS_FOGTABLE); - - // Detect if stencil available - bStencil = FALSE; - IDirect3DSurface9* surfZS = nullptr; - D3DSURFACE_DESC surfDESC; - CHK_DX(HW.pDevice->GetDepthStencilSurface(&surfZS)); - R_ASSERT(surfZS); - CHK_DX(surfZS->GetDesc(&surfDESC)); - _RELEASE(surfZS); - - switch (surfDESC.Format) - { - case D3DFMT_D15S1: bStencil = TRUE; break; - case D3DFMT_D24S8: bStencil = TRUE; break; - case D3DFMT_D24X4S4: bStencil = TRUE; break; - } - - // Scissoring - if (caps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST) - bScissor = TRUE; - else - bScissor = FALSE; - - // Stencil relative caps - u32 dwStencilCaps = caps.StencilCaps; - if ((!(dwStencilCaps & D3DSTENCILCAPS_INCR) && !(dwStencilCaps & D3DSTENCILCAPS_INCRSAT)) || - (!(dwStencilCaps & D3DSTENCILCAPS_DECR) && !(dwStencilCaps & D3DSTENCILCAPS_DECRSAT))) - { - soDec = soInc = D3DSTENCILOP_KEEP; - dwMaxStencilValue = 0; - } - else - { - // Prefer sat ops that cap at 0/max, but can use other ones as long as enough stencil bits - soInc = (dwStencilCaps & D3DSTENCILCAPS_INCRSAT) ? D3DSTENCILOP_INCRSAT : D3DSTENCILOP_INCR; - soDec = (dwStencilCaps & D3DSTENCILCAPS_DECRSAT) ? D3DSTENCILOP_DECRSAT : D3DSTENCILOP_DECR; - dwMaxStencilValue = (1 << 8) - 1; - } - - // FFP lights - max_ffp_lights = caps.MaxActiveLights; - - // DEV INFO - - iGPUNum = GetGpuNum(); - - hasFixedPipeline = true; - useCombinedSamplers = true; -} diff --git a/src/Layers/xrRenderDX9/dx9R_Backend_Runtime.h b/src/Layers/xrRenderDX9/dx9R_Backend_Runtime.h deleted file mode 100644 index 4577a157d79..00000000000 --- a/src/Layers/xrRenderDX9/dx9R_Backend_Runtime.h +++ /dev/null @@ -1,358 +0,0 @@ -#ifndef dx9R_Backend_Runtime_included -#define dx9R_Backend_Runtime_included -#pragma once - -IC void CBackend::set_xform(u32 ID, const Fmatrix& M) -{ - stat.xforms++; - CHK_DX(HW.pDevice->SetTransform((D3DTRANSFORMSTATETYPE)ID, (D3DMATRIX*)&M)); -} - -IC void CBackend::set_RT(ID3DRenderTargetView* RT, u32 ID) -{ - if (RT != pRT[ID]) - { - PGO(Msg("PGO:setRT")); - stat.target_rt++; - pRT[ID] = RT; - CHK_DX(HW.pDevice->SetRenderTarget(ID, RT)); - } -} - -IC void CBackend::set_ZB(ID3DDepthStencilView* ZB) -{ - if (ZB != pZB) - { - PGO(Msg("PGO:setZB")); - stat.target_zb++; - pZB = ZB; - CHK_DX(HW.pDevice->SetDepthStencilSurface(ZB)); - } -} - -IC void CBackend::ClearRT(ID3DRenderTargetView* rt, const Fcolor& color) -{ - VERIFY(rt == pRT[0]); - CHK_DX(HW.pDevice->Clear(0, nullptr, D3DCLEAR_TARGET, color.get(), 1.0f, 0)); -} - -IC void CBackend::ClearZB(ID3DDepthStencilView* zb, float depth) -{ - VERIFY(zb == pZB); - CHK_DX(HW.pDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, 0, depth, 0)); -} - -IC void CBackend::ClearZB(ID3DDepthStencilView* zb, float depth, u8 stencil) -{ - VERIFY(zb == pZB); - CHK_DX(HW.pDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER | (HW.Caps.bStencil ? D3DCLEAR_STENCIL : 0), 0, depth, stencil)); -} - -IC bool CBackend::ClearRTRect(ID3DRenderTargetView* rt, const Fcolor& color, size_t numRects, const Irect* rects) -{ - VERIFY(rt == pRT[0]); - CHK_DX(HW.pDevice->Clear(numRects, reinterpret_cast(rects), D3DCLEAR_TARGET, color.get(), 1.0f, 0)); - return true; -} - -IC bool CBackend::ClearZBRect(ID3DDepthStencilView* zb, float depth, size_t numRects, const Irect* rects) -{ - VERIFY(zb == pZB); - CHK_DX(HW.pDevice->Clear(numRects, reinterpret_cast(rects), D3DCLEAR_ZBUFFER, 0, depth, 0)); - return true; -} - -ICF void CBackend::set_Format(SDeclaration* _decl) -{ - if (decl != _decl) - { - PGO(Msg("PGO:v_format:%x", _decl)); - stat.decl++; - decl = _decl; - CHK_DX(HW.pDevice->SetVertexDeclaration(decl->dcl)); - } -} - -ICF void CBackend::set_PS(ID3DPixelShader* _ps, LPCSTR _n) -{ - if (ps != _ps) - { - PGO(Msg("PGO:Pshader:%x", _ps)); - stat.ps++; - ps = _ps; - CHK_DX(HW.pDevice->SetPixelShader(ps)); -#ifdef DEBUG - ps_name = _n; -#endif - } -} - -ICF void CBackend::set_VS(ID3DVertexShader* _vs, LPCSTR _n) -{ - if (vs != _vs) - { - PGO(Msg("PGO:Vshader:%x", _vs)); - stat.vs++; - vs = _vs; - CHK_DX(HW.pDevice->SetVertexShader(vs)); -#ifdef DEBUG - vs_name = _n; -#endif - } -} - -ICF void CBackend::set_Vertices(VertexBufferHandle _vb, u32 _vb_stride) -{ - if ((vb != _vb) || (vb_stride != _vb_stride)) - { - PGO(Msg("PGO:VB:%x,%d", _vb, _vb_stride)); - stat.vb++; - vb = _vb; - vb_stride = _vb_stride; - CHK_DX(HW.pDevice->SetStreamSource(0, vb, 0, vb_stride)); - } -} - -ICF void CBackend::set_Indices(IndexBufferHandle _ib) -{ - if (ib != _ib) - { - PGO(Msg("PGO:IB:%x", _ib)); - stat.ib++; - ib = _ib; - CHK_DX(HW.pDevice->SetIndices(ib)); - } -} - -ICF void CBackend::Render(D3DPRIMITIVETYPE T, u32 baseV, u32 startV, u32 countV, u32 startI, u32 PC) -{ - // Fix D3D ERROR - if (PC == 0) - return; - - stat.render.calls++; - stat.render.verts += countV; - stat.render.polys += PC; - constants.flush(); - CHK_DX(HW.pDevice->DrawIndexedPrimitive(T, baseV, startV, countV, startI, PC)); - PGO(Msg("PGO:DIP:%dv/%df", countV, PC)); -} - -ICF void CBackend::Render(D3DPRIMITIVETYPE T, u32 startV, u32 PC) -{ - // Fix D3D ERROR - if (PC == 0) - return; - - stat.render.calls++; - stat.render.verts += 3 * PC; - stat.render.polys += PC; - constants.flush(); - CHK_DX(HW.pDevice->DrawPrimitive(T, startV, PC)); - PGO(Msg("PGO:DIP:%dv/%df", 3 * PC, PC)); -} - -IC void CBackend::set_Geometry(SGeometry* _geom) -{ - set_Format(_geom->dcl._get()); - set_Vertices(_geom->vb, _geom->vb_stride); - set_Indices(_geom->ib); -} - -IC void CBackend::set_Scissor(Irect* R) -{ - if (R) - { - CHK_DX(HW.pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE)); - RECT* clip = (RECT*)R; - CHK_DX(HW.pDevice->SetScissorRect(clip)); - } - else - { - CHK_DX(HW.pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE)); - } -} - -IC void CBackend::SetViewport(const D3D_VIEWPORT& viewport) const -{ - CHK_DX(HW.pDevice->SetViewport(&viewport)); -} - -IC void CBackend::set_Stencil( - u32 _enable, u32 _func, u32 _ref, u32 _mask, u32 _writemask, u32 _fail, u32 _pass, u32 _zfail) -{ - // Simple filter - if (stencil_enable != _enable) - { - stencil_enable = _enable; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILENABLE, _enable)); - } - if (!stencil_enable) - return; - if (stencil_func != _func) - { - stencil_func = _func; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILFUNC, _func)); - } - if (stencil_ref != _ref) - { - stencil_ref = _ref; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILREF, _ref)); - } - if (stencil_mask != _mask) - { - stencil_mask = _mask; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILMASK, _mask)); - } - if (stencil_writemask != _writemask) - { - stencil_writemask = _writemask; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, _writemask)); - } - if (stencil_fail != _fail) - { - stencil_fail = _fail; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILFAIL, _fail)); - } - if (stencil_pass != _pass) - { - stencil_pass = _pass; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILPASS, _pass)); - } - if (stencil_zfail != _zfail) - { - stencil_zfail = _zfail; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILZFAIL, _zfail)); - } -} - -IC void CBackend::set_Z(u32 _enable) -{ - if (z_enable != _enable) - { - z_enable = _enable; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_ZENABLE, _enable)); - } -} - -IC void CBackend::set_ZFunc(u32 _func) -{ - if (z_func != _func) - { - z_func = _func; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_ZFUNC, _func)); - } -} - -IC void CBackend::set_AlphaRef(u32 _value) -{ - if (alpha_ref != _value) - { - alpha_ref = _value; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_ALPHAREF, _value)); - } -} - -IC void CBackend::set_ColorWriteEnable(u32 _mask) -{ - if (colorwrite_mask != _mask) - { - colorwrite_mask = _mask; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, _mask)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_COLORWRITEENABLE1, _mask)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_COLORWRITEENABLE2, _mask)); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_COLORWRITEENABLE3, _mask)); - } -} - -ICF void CBackend::set_CullMode(u32 _mode) -{ - if (cull_mode != _mode) - { - cull_mode = _mode; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_CULLMODE, _mode)); - } -} - -ICF void CBackend::set_FillMode(u32 _mode) -{ - if (fill_mode != _mode) - { - fill_mode = _mode; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_FILLMODE, _mode)); - } -} - -IC void CBackend::SetTextureFactor(u32 factor) const -{ - CHK_DX(HW.pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, factor)); -} - -IC void CBackend::SetAmbient(u32 factor) const -{ - CHK_DX(HW.pDevice->SetRenderState(D3DRS_AMBIENT, factor)); -} - -ICF void CBackend::set_VS(ref_vs& _vs) { set_VS(_vs->sh, _vs->cName.c_str()); } -IC void CBackend::set_Constants(R_constant_table* C) -{ - // caching - if (ctable == C) - return; - ctable = C; - xforms.unmap(); - hemi.unmap(); - tree.unmap(); - if (nullptr == C) - return; - - PGO(Msg("PGO:c-table")); - - // process constant-loaders - R_constant_table::c_table::iterator it = C->table.begin(); - R_constant_table::c_table::iterator end = C->table.end(); - for (; it != end; ++it) - { - R_constant* Cs = &**it; - VERIFY(Cs); - if (Cs && Cs->handler) - Cs->handler->setup(*this, Cs); - } -} - -ICF void CBackend::gpu_mark_begin(const wchar_t* name) -{ - HW.BeginPixEvent(name); -} - -ICF void CBackend::gpu_mark_end() -{ - HW.EndPixEvent(); -} - -IC void CBackend::set_pass_targets(const ref_rt &_1, const ref_rt &_2, const ref_rt &_3, const ref_rt &zb) -{ - VERIFY(_1); - - if (_1) - { - curr_rt_width = _1->dwWidth; - curr_rt_height = _1->dwHeight; - } - else - { - VERIFY(zb); - curr_rt_width = zb->dwWidth; - curr_rt_height = zb->dwHeight; - } - - set_RT(_1 ? _1->pRT : nullptr, 0); - set_RT(_2 ? _2->pRT : nullptr, 1); - set_RT(_3 ? _3->pRT : nullptr, 2); - set_ZB(zb ? zb->pRT : nullptr); - - const D3D_VIEWPORT viewport = { 0, 0, curr_rt_width, curr_rt_height, 0.f, 1.f }; - SetViewport(viewport); -} - -#endif // dx9R_Backend_Runtime_included diff --git a/src/Layers/xrRenderDX9/dx9ResourceManager_Resources.cpp b/src/Layers/xrRenderDX9/dx9ResourceManager_Resources.cpp deleted file mode 100644 index ae5bd78c880..00000000000 --- a/src/Layers/xrRenderDX9/dx9ResourceManager_Resources.cpp +++ /dev/null @@ -1,382 +0,0 @@ -#include "stdafx.h" - -#include "Layers/xrRender/ResourceManager.h" -#include "Layers/xrRender/tss.h" -#include "Layers/xrRender/Blender.h" -#include "Layers/xrRender/Blender_Recorder.h" -#include "Layers/xrRender/ShaderResourceTraits.h" - -//-------------------------------------------------------------------------------------------------------------- -SPass* CResourceManager::_CreatePass(const SPass& proto) -{ - for (SPass* pass : v_passes) - if (pass->equal(proto)) - return pass; - - SPass* P = v_passes.emplace_back(xr_new()); - P->dwFlags |= xr_resource_flagged::RF_REGISTERED; - P->state = proto.state; - P->ps = proto.ps; - P->vs = proto.vs; - P->constants = proto.constants; - P->T = proto.T; -#if defined(USE_DX9) && RENDER == R_R1 - P->M = proto.M; -#endif - P->C = proto.C; - - return P; -} - -//-------------------------------------------------------------------------------------------------------------- - -SDeclaration* CResourceManager::_CreateDecl(const VertexElement* dcl) -{ - // Search equal code - for (SDeclaration* D : v_declarations) - { - if (dcl_equal(dcl, &*D->dcl_code.begin())) - return D; - } - - // Create _new - SDeclaration* D = v_declarations.emplace_back(xr_new()); - u32 dcl_size = GetDeclLength(dcl) + 1; - CHK_DX(HW.pDevice->CreateVertexDeclaration(dcl, &D->dcl)); - D->dcl_code.assign(dcl, dcl + dcl_size); - D->dwFlags |= xr_resource_flagged::RF_REGISTERED; - - return D; -} - -//-------------------------------------------------------------------------------------------------------------- -SVS* CResourceManager::_CreateVS(cpcstr shader, u32 flags /*= 0*/) -{ - string_path name; - xr_strcpy(name, shader); - switch (RImplementation.m_skinning) - { - case 0: - xr_strcat(name, "_0"); - break; - case 1: - xr_strcat(name, "_1"); - break; - case 2: - xr_strcat(name, "_2"); - break; - case 3: - xr_strcat(name, "_3"); - break; - case 4: - xr_strcat(name, "_4"); - break; - } - - return CreateShader(name, shader, flags); -} - -void CResourceManager::_DeleteVS(const SVS* vs) { DestroyShader(vs); } - -//-------------------------------------------------------------------------------------------------------------- -SPS* CResourceManager::_CreatePS(LPCSTR name) { return CreateShader(name, nullptr); } -void CResourceManager::_DeletePS(const SPS* ps) { DestroyShader(ps); } - -#ifdef _EDITOR -//-------------------------------------------------------------------------------------------------------------- -class includer : public ID3DXInclude -{ -public: - HRESULT __stdcall Open( - D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) - { - string_path pname; - strconcat(pname, RImplementation.getShaderPath(), pFileName); - IReader* R = FS.r_open("$game_shaders$", pname); - if (0 == R) - { - // possibly in shared directory or somewhere else - open directly - R = FS.r_open("$game_shaders$", pFileName); - if (0 == R) - return E_FAIL; - } - - // duplicate and zero-terminate - u32 size = R->length(); - u8* data = xr_alloc(size + 1); - CopyMemory(data, R->pointer(), size); - data[size] = 0; - FS.r_close(R); - - *ppData = data; - *pBytes = size; - return D3D_OK; - } - HRESULT __stdcall Close(LPCVOID pData) - { - xr_free(pData); - return D3D_OK; - } -}; - -SVS* CResourceManager::_CreateVS(LPCSTR _name) -{ - string_path name; - xr_strcpy(name, _name); - if (0 == RImplementation.m_skinning) - xr_strcat(name, "_0"); - if (1 == RImplementation.m_skinning) - xr_strcat(name, "_1"); - if (2 == RImplementation.m_skinning) - xr_strcat(name, "_2"); - if (3 == RImplementation.m_skinning) - xr_strcat(name, "_3"); - if (4 == RImplementation.m_skinning) - xr_strcat(name, "_4"); - pstr N = pstr(name); - map_VS::iterator I = m_vs.find(N); - if (I != m_vs.end()) - return I->second; - else - { - SVS* _vs = xr_new(); - _vs->dwFlags |= xr_resource_flagged::RF_REGISTERED; - m_vs.insert(std::make_pair(_vs->set_name(name), _vs)); - if (0 == xr_stricmp(_name, "null")) - { - _vs->vs = NULL; - return _vs; - } - - includer Includer; - LPD3DXBUFFER pShaderBuf = NULL; - LPD3DXBUFFER pErrorBuf = NULL; - LPD3DXSHADER_CONSTANTTABLE pConstants = NULL; - HRESULT _hr = S_OK; - string_path cname; - strconcat(cname, RImplementation.getShaderPath(), _name, ".vs"); - FS.update_path(cname, "$game_shaders$", cname); - // LPCSTR target = NULL; - - IReader* fs = FS.r_open(cname); - R_ASSERT3(fs, "shader file doesnt exist", cname); - - // Select target - LPCSTR c_target = "vs_2_0"; - LPCSTR c_entry = "main"; - /*if (HW.Caps.geometry.dwVersion>=CAP_VERSION(3,0)) target="vs_3_0"; - else*/ if (HW.Caps.geometry_major >= 2) - c_target = "vs_2_0"; - else - c_target = "vs_1_1"; - - u32 needed_len = fs->length() + 1; - pstr pfs = xr_alloc(needed_len); - strncpy_s(pfs, needed_len, (LPCSTR)fs->pointer(), fs->length()); - pfs[fs->length()] = 0; - - if (strstr(pfs, "main_vs_1_1")) - { - c_target = "vs_1_1"; - c_entry = "main_vs_1_1"; - } - if (strstr(pfs, "main_vs_2_0")) - { - c_target = "vs_2_0"; - c_entry = "main_vs_2_0"; - } - - xr_free(pfs); - - // vertex - R_ASSERT2(fs, cname); - _hr = RImplementation.shader_compile(name, LPCSTR(fs->pointer()), fs->length(), NULL, &Includer, c_entry, - c_target, D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR /*| D3DXSHADER_PREFER_FLOW_CONTROL*/, - &pShaderBuf, &pErrorBuf, NULL); - // _hr = D3DXCompileShader (LPCSTR(fs->pointer()),fs->length(), NULL, &Includer, "main", target, - // D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR, &pShaderBuf, &pErrorBuf, NULL); - FS.r_close(fs); - - if (SUCCEEDED(_hr)) - { - if (pShaderBuf) - { - _hr = HW.pDevice->CreateVertexShader((DWORD*)pShaderBuf->GetBufferPointer(), &_vs->vs); - if (SUCCEEDED(_hr)) - { - LPCVOID data = NULL; - _hr = D3DXFindShaderComment( - (DWORD*)pShaderBuf->GetBufferPointer(), MAKEFOURCC('C', 'T', 'A', 'B'), &data, NULL); - if (SUCCEEDED(_hr) && data) - { - pConstants = LPD3DXSHADER_CONSTANTTABLE(data); - _vs->constants.parse(pConstants, 0x2); - } - else - { - Log("! VS: ", _name); - Msg("! D3DXFindShaderComment hr == 0x%08x", _hr); - _hr = E_FAIL; - } - } - else - { - Log("! VS: ", _name); - Msg("! CreateVertexShader hr == 0x%08x", _hr); - } - } - else - { - Log("! VS: ", _name); - Log("! pShaderBuf == NULL"); - _hr = E_FAIL; - } - } - else - { - Log("! VS: ", _name); - if (pErrorBuf) - Log("! error: ", (LPCSTR)pErrorBuf->GetBufferPointer()); - else - Msg("Can't compile shader hr=0x%08x", _hr); - } - - _RELEASE(pShaderBuf); - _RELEASE(pErrorBuf); - pConstants = NULL; - - CHECK_OR_EXIT(!FAILED(_hr), "Your video card doesn't meet game requirements.\n\nTry to lower game settings."); - - return _vs; - } -} - -//-------------------------------------------------------------------------------------------------------------- -SPS* CResourceManager::_CreatePS(LPCSTR name) -{ - pstr N = pstr(name); - map_PS::iterator I = m_ps.find(N); - if (I != m_ps.end()) - return I->second; - else - { - SPS* _ps = xr_new(); - _ps->dwFlags |= xr_resource_flagged::RF_REGISTERED; - m_ps.insert(std::make_pair(_ps->set_name(name), _ps)); - if (0 == xr_stricmp(name, "null")) - { - _ps->ps = NULL; - return _ps; - } - - // Open file - includer Includer; - string_path cname; - LPCSTR shader_path = RImplementation.getShaderPath(); - strconcat(cname, shader_path, name, ".ps"); - FS.update_path(cname, "$game_shaders$", cname); - - // duplicate and zero-terminate - IReader* R = FS.r_open(cname); - R_ASSERT2(R, cname); - u32 size = R->length(); - char* data = xr_alloc(size + 1); - CopyMemory(data, R->pointer(), size); - data[size] = 0; - FS.r_close(R); - - // Select target - LPCSTR c_target = "ps_2_0"; - LPCSTR c_entry = "main"; - if (strstr(data, "main_ps_1_1")) - { - c_target = "ps_1_1"; - c_entry = "main_ps_1_1"; - } - if (strstr(data, "main_ps_1_2")) - { - c_target = "ps_1_2"; - c_entry = "main_ps_1_2"; - } - if (strstr(data, "main_ps_1_3")) - { - c_target = "ps_1_3"; - c_entry = "main_ps_1_3"; - } - if (strstr(data, "main_ps_1_4")) - { - c_target = "ps_1_4"; - c_entry = "main_ps_1_4"; - } - if (strstr(data, "main_ps_2_0")) - { - c_target = "ps_2_0"; - c_entry = "main_ps_2_0"; - } - - // Compile - LPD3DXBUFFER pShaderBuf = NULL; - LPD3DXBUFFER pErrorBuf = NULL; - LPD3DXSHADER_CONSTANTTABLE pConstants = NULL; - HRESULT _hr = S_OK; - _hr = RImplementation.shader_compile(name, data, size, NULL, &Includer, c_entry, c_target, - D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR, &pShaderBuf, &pErrorBuf, NULL); - //_hr = D3DXCompileShader (text,text_size, NULL, &Includer, c_entry, c_target, D3DXSHADER_DEBUG | - // D3DXSHADER_PACKMATRIX_ROWMAJOR, &pShaderBuf, &pErrorBuf, NULL); - xr_free(data); - - if (SUCCEEDED(_hr)) - { - if (pShaderBuf) - { - _hr = HW.pDevice->CreatePixelShader((DWORD*)pShaderBuf->GetBufferPointer(), &_ps->ps); - if (SUCCEEDED(_hr)) - { - LPCVOID data = NULL; - _hr = D3DXFindShaderComment( - (DWORD*)pShaderBuf->GetBufferPointer(), MAKEFOURCC('C', 'T', 'A', 'B'), &data, NULL); - if (SUCCEEDED(_hr) && data) - { - pConstants = LPD3DXSHADER_CONSTANTTABLE(data); - _ps->constants.parse(pConstants, 0x1); - } - else - { - Log("! PS: ", name); - Msg("! D3DXFindShaderComment hr == 0x%08x", _hr); - _hr = E_FAIL; - } - } - else - { - Log("! PS: ", name); - Msg("! CreatePixelShader hr == 0x%08x", _hr); - } - } - else - { - Log("! PS: ", name); - Log("! pShaderBuf == NULL"); - _hr = E_FAIL; - } - } - else - { - Log("! PS: ", name); - if (pErrorBuf) - Log("! error: ", (LPCSTR)pErrorBuf->GetBufferPointer()); - else - Msg("Can't compile shader hr=0x%08x", _hr); - } - - _RELEASE(pShaderBuf); - _RELEASE(pErrorBuf); - pConstants = NULL; - - CHECK_OR_EXIT(!FAILED(_hr), "Your video card doesn't meet game requirements.\n\nTry to lower game settings."); - - return _ps; - } -} - -#endif diff --git a/src/Layers/xrRenderDX9/dx9SH_RT.cpp b/src/Layers/xrRenderDX9/dx9SH_RT.cpp deleted file mode 100644 index d55a5afc4d4..00000000000 --- a/src/Layers/xrRenderDX9/dx9SH_RT.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "Layers/xrRender/ResourceManager.h" - -CRT::~CRT() -{ - destroy(); - - // release external reference - RImplementation.Resources->_DeleteRT(this); -} - -bool used_as_depth(D3DFORMAT fmt) -{ - switch (fmt) - { - case D3DFMT_D16: - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D24X8: - case D3DFMT_D32: - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_D15S1: - case D3DFMT_D24X4S4: - case D3DFMT_D24S8: - case MAKEFOURCC('D', 'F', '2', '4'): - return true; - default: - return false; - } -} - -void CRT::set_slice_read(int slice) {} -void CRT::set_slice_write(u32 context_id, int slice) {} - -void CRT::create(LPCSTR Name, u32 w, u32 h, D3DFORMAT f, u32 SampleCount /*= 1*/, u32 slices_num /*=1*/, Flags32 flags /*= {}*/) -{ - if (pSurface) - return; - - R_ASSERT(HW.pDevice && Name && Name[0] && w && h); - _order = CPU::QPC(); // Device.GetTimerGlobal()->GetElapsed_clk(); - - HRESULT _hr; - - dwWidth = w; - dwHeight = h; - fmt = f; - sampleCount = SampleCount; - - const bool useAsDepth = used_as_depth(fmt); - - if (flags.test(CreateBase)) - { - dwFlags |= CreateBase; - if (useAsDepth) - R_CHK(HW.pDevice->GetDepthStencilSurface(&pRT)); - else - { - u32 idx; - char const* str = strrchr(Name, '_'); - sscanf(++str, "%d", &idx); - R_CHK(HW.pDevice->GetRenderTarget(idx, &pRT)); - } -#ifdef DEBUG - Msg("* created RT(%s), %dx%d", Name, w, h); -#endif - return; - } - - D3DRESOURCETYPE type = D3DRTYPE_TEXTURE; - if (flags.test(CreateSurface)) - { - type = D3DRTYPE_SURFACE; - dwFlags |= CreateSurface; - } - - // Get caps - D3DCAPS9 caps; - R_CHK(HW.pDevice->GetDeviceCaps(&caps)); - - // Pow2 - if (!btwIsPow2(w) || !btwIsPow2(h)) - { - if (!HW.Caps.raster.bNonPow2) - return; - } - - // Check width-and-height of render target surface - if (w > caps.MaxTextureWidth) - return; - if (h > caps.MaxTextureHeight) - return; - - // Select usage - const u32 usage = useAsDepth ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET; - - // Validate render-target usage - _hr = HW.pD3D->CheckDeviceFormat(HW.DevAdapter, HW.m_DriverType, HW.Caps.fTarget, usage, type, f); - if (FAILED(_hr)) - return; - - // Try to create texture/surface - RImplementation.Resources->Evict(); - - switch (type) - { - case D3DRTYPE_TEXTURE: - { - _hr = HW.pDevice->CreateTexture(w, h, 1, usage, f, D3DPOOL_DEFAULT, &pSurface, nullptr); - break; - } - case D3DRTYPE_SURFACE: - { - if (useAsDepth) - _hr = HW.pDevice->CreateDepthStencilSurface(w, h, f, D3DMULTISAMPLE_NONE, 0, TRUE, &pRT, nullptr); - else - _hr = HW.pDevice->CreateOffscreenPlainSurface(w, h, f, D3DPOOL_SYSTEMMEM, &pRT, nullptr); - break; - } - default: NODEFAULT; - } - if (FAILED(_hr)) - return; - - // OK - HW.stats_manager.increment_stats_rtarget(pSurface); -#ifdef DEBUG - Msg("* created RT(%s), %dx%d", Name, w, h); -#endif - if (!pSurface) - return; // special case (when type == D3DRTYPE_SURFACE) - - R_CHK(pSurface->GetSurfaceLevel(0, &pRT)); - pTexture = RImplementation.Resources->_CreateTexture(Name); - pTexture->surface_set(pSurface); -} - -void CRT::destroy() -{ - if (pTexture._get()) - { - pTexture->surface_set(0); - pTexture = NULL; - } - - _RELEASE(pRT); - - HW.stats_manager.decrement_stats_rtarget(pSurface); - _RELEASE(pSurface); -} - -void CRT::reset_begin() { destroy(); } -void CRT::reset_end() { create(*cName, dwWidth, dwHeight, fmt, sampleCount, { dwFlags }); } - -void CRT::resolve_into(CRT& destination) const -{ - HW.pDevice->StretchRect(pRT, nullptr, - destination.pRT, nullptr, D3DTEXF_POINT); -} - -void resptrcode_crt::create(LPCSTR Name, u32 w, u32 h, D3DFORMAT f, u32 SampleCount /*= 1*/, u32 slices_num /*=1*/, Flags32 flags /*= {}*/) -{ - _set(RImplementation.Resources->_CreateRT(Name, w, h, f, SampleCount, 1, flags)); -} - -////////////////////////////////////////////////////////////////////////// -// DX10 cut -/* -CRTC::CRTC () -{ - if (pSurface) return; - - pSurface = NULL; - pRT[0]=pRT[1]=pRT[2]=pRT[3]=pRT[4]=pRT[5] = NULL; - dwSize = 0; - fmt = D3DFMT_UNKNOWN; -} -CRTC::~CRTC () -{ - destroy (); - - // release external reference - DEV->_DeleteRTC (this); -} - -void CRTC::create (LPCSTR Name, u32 size, D3DFORMAT f) -{ - R_ASSERT (HW.pDevice && Name && Name[0] && size && btwIsPow2(size)); - _order = CPU::QPC(); //Device.GetTimerGlobal()->GetElapsed_clk(); - - HRESULT _hr; - - dwSize = size; - fmt = f; - - // Get caps - D3DCAPS9 caps; - R_CHK (HW.pDevice->GetDeviceCaps(&caps)); - - // Check width-and-height of render target surface - if (size>caps.MaxTextureWidth) return; - if (size>caps.MaxTextureHeight) return; - - // Validate render-target usage - _hr = HW.pD3D->CheckDeviceFormat( - HW.DevAdapter, - HW.m_DriverType, - HW.Caps.fTarget, - D3DUSAGE_RENDERTARGET, - D3DRTYPE_CUBETEXTURE, - f - ); - if (FAILED(_hr)) return; - - // Try to create texture/surface - DEV->Evict (); - _hr = HW.pDevice->CreateCubeTexture (size, 1, D3DUSAGE_RENDERTARGET, f, D3DPOOL_DEFAULT, &pSurface,NULL); - if (FAILED(_hr) || (0==pSurface)) return; - - // OK - Msg ("* created RTc(%s), 6(%d)",Name,size); - for (u32 face=0; face<6; face++) - R_CHK (pSurface->GetCubeMapSurface ((D3DCUBEMAP_FACES)face, 0, pRT+face)); - pTexture = DEV->_CreateTexture (Name); - pTexture->surface_set (pSurface); -} - -void CRTC::destroy () -{ - pTexture->surface_set (0); - pTexture = NULL; - for (u32 face=0; face<6; face++) - _RELEASE (pRT[face] ); - _RELEASE (pSurface ); -} -void CRTC::reset_begin () -{ - destroy (); -} -void CRTC::reset_end () -{ - create (*cName,dwSize,fmt); -} - -void resptrcode_crtc::create(LPCSTR Name, u32 size, D3DFORMAT f) -{ - _set (DEV->_CreateRTC(Name,size,f)); -} -*/ diff --git a/src/Layers/xrRenderDX9/dx9r_constants.cpp b/src/Layers/xrRenderDX9/dx9r_constants.cpp deleted file mode 100644 index f8cefffc448..00000000000 --- a/src/Layers/xrRenderDX9/dx9r_constants.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "stdafx.h" - -#include "Layers/xrRender/r_constants.h" -#include "Layers/xrRenderDX9/dx9shader_utils.h" - -BOOL R_constant_table::parse(void* _desc, u32 destination) -{ - D3DXSHADER_CONSTANTTABLE* desc = (D3DXSHADER_CONSTANTTABLE*)_desc; - D3DXSHADER_CONSTANTINFO* it = (D3DXSHADER_CONSTANTINFO*)((u8*)(desc) + desc->ConstantInfo); - u8* ptr = (u8*)(desc); - for (u32 dwCount = desc->Constants; dwCount; dwCount--, it++) - { - // Name - LPCSTR name = LPCSTR(ptr + it->Name); - - // Type - u16 type = RC_float; - if (D3DXRS_BOOL == it->RegisterSet) - type = RC_bool; - if (D3DXRS_INT4 == it->RegisterSet) - type = RC_int; - - // Rindex,Rcount - u16 r_index = it->RegisterIndex; - u16 r_type = u16(-1); - - // TypeInfo + class - D3DXSHADER_TYPEINFO* T = (D3DXSHADER_TYPEINFO*)(ptr + it->TypeInfo); - BOOL bSkip = FALSE; - switch (T->Class) - { - case D3DXPC_SCALAR: r_type = RC_1x1; break; - case D3DXPC_VECTOR: r_type = RC_1x4; break; - case D3DXPC_MATRIX_ROWS: - { - switch (T->Columns) - { - case 4: - switch (T->Rows) - { - case 3: - switch (it->RegisterCount) - { - case 2: r_type = RC_2x4; break; - case 3: r_type = RC_3x4; break; - default: - Msg("Invalid matrix dimension:%dx%d in constant %s", it->RegisterCount, T->Columns, name); - fatal("MATRIX_ROWS: unsupported number of RegisterCount"); - break; - } - break; - case 4: - r_type = RC_4x4; - VERIFY(4 == it->RegisterCount); - break; - default: fatal("MATRIX_ROWS: unsupported number of Rows"); break; - } - break; - default: fatal("MATRIX_ROWS: unsupported number of Columns"); break; - } - } - break; - case D3DXPC_MATRIX_COLUMNS: fatal("Pclass MATRIX_COLUMNS unsupported"); break; - case D3DXPC_STRUCT: fatal("Pclass D3DXPC_STRUCT unsupported"); break; - case D3DXPC_OBJECT: - { - switch (T->Type) - { - case D3DXPT_SAMPLER: - case D3DXPT_SAMPLER1D: - case D3DXPT_SAMPLER2D: - case D3DXPT_SAMPLER3D: - case D3DXPT_SAMPLERCUBE: - { - // ***Register sampler*** - // We have determined all valuable info, search if constant already created - ref_constant C = get(name); - if (!C) - { - C = table.emplace_back(xr_new()); //.g_constant_allocator.create(); - C->name = name; - C->destination = RC_dest_sampler; - C->type = RC_sampler; - R_constant_load& L = C->samp; - L.index = u16(r_index + ((destination & RC_dest_pixel) ? 0 : D3DVERTEXTEXTURESAMPLER0)); - L.cls = RC_sampler; - } - else - { - R_ASSERT(C->destination == RC_dest_sampler); - R_ASSERT(C->type == RC_sampler); - R_constant_load& L = C->samp; - R_ASSERT(L.index == r_index); - R_ASSERT(L.cls == RC_sampler); - } - } - break; - default: fatal("Pclass D3DXPC_OBJECT - object isn't of 'sampler' type"); break; - } - } - bSkip = TRUE; - break; - default: bSkip = TRUE; break; - } - if (bSkip) - continue; - - // We have determined all valuable info, search if constant already created - ref_constant C = get(name); - if (!C) - { - C = table.emplace_back(xr_new()); //.g_constant_allocator.create(); - C->name = name; - C->destination = destination; - C->type = type; - R_constant_load& L = (destination & RC_dest_pixel) ? C->ps : C->vs; - L.index = r_index; - L.cls = r_type; - } - else - { - C->destination |= destination; - VERIFY(C->type == type); - R_constant_load& L = (destination & RC_dest_pixel) ? C->ps : C->vs; - L.index = r_index; - L.cls = r_type; - } - } - std::sort(table.begin(), table.end(), [](const ref_constant& C1, const ref_constant& C2) - { - return xr_strcmp(C1->name, C2->name) < 0; - }); - return TRUE; -} diff --git a/src/Layers/xrRenderDX9/dx9r_constants_cache.cpp b/src/Layers/xrRenderDX9/dx9r_constants_cache.cpp deleted file mode 100644 index 3f4e5d4a755..00000000000 --- a/src/Layers/xrRenderDX9/dx9r_constants_cache.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "stdafx.h" -#pragma hdrstop - -#include "Layers/xrRender/r_constants_cache.h" - -void R_constants::flush_cache() -{ - if (a_pixel.b_dirty) - { - // fp - R_constant_array::t_f& F = a_pixel.c_f; - { - if (F.r_lo() <= 32) //. hack - { - u32 count = F.r_hi() - F.r_lo(); - if (count) - { - count = (count > 31) ? 31 : count; - PGO(Msg("PGO:P_CONST:%d", count)); - CHK_DX(HW.pDevice->SetPixelShaderConstantF(F.r_lo(), (float*)F.access(F.r_lo()), count)); - F.flush(); - } - } - } - a_pixel.b_dirty = false; - } - if (a_vertex.b_dirty) - { - // fp - R_constant_array::t_f& F = a_vertex.c_f; - { - u32 count = F.r_hi() - F.r_lo(); - if (count) - { -#ifdef DEBUG - if (F.r_hi() > HW.Caps.geometry.dwRegisters) - { - xrDebug::Fatal(DEBUG_INFO, "Internal error setting VS-constants: overflow\nregs[%d],hi[%d]", - HW.Caps.geometry.dwRegisters, F.r_hi()); - } - PGO(Msg("PGO:V_CONST:%d", count)); -#endif& - CHK_DX(HW.pDevice->SetVertexShaderConstantF(F.r_lo(), (float*)F.access(F.r_lo()), count)); - F.flush(); - } - } - a_vertex.b_dirty = false; - } -} diff --git a/src/Layers/xrRenderDX9/dx9r_constants_cache.h b/src/Layers/xrRenderDX9/dx9r_constants_cache.h deleted file mode 100644 index 0724ce1f3e5..00000000000 --- a/src/Layers/xrRenderDX9/dx9r_constants_cache.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef dx9r_constants_cacheH -#define dx9r_constants_cacheH -#pragma once - -template -class R_constant_cache -{ - alignas(16) svector array; - u32 lo, hi; - -public: - R_constant_cache() - { - array.resize(limit); - flush(); - } - ICF T* access(u32 id) { return &array[id]; } - ICF void flush() { lo = hi = 0; } - ICF void dirty(u32 _lo, u32 _hi) - { - if (_lo < lo) - lo = _lo; - if (_hi > hi) - hi = _hi; - } - ICF u32 r_lo() { return lo; } - ICF u32 r_hi() { return hi; } -}; - -class R_constant_array -{ -public: - typedef R_constant_cache t_f; - typedef R_constant_cache t_i; - typedef R_constant_cache t_b; - - alignas(16) t_f c_f; - // ALIGN(16) t_i c_i; - // ALIGN(16) t_b c_b; - BOOL b_dirty; - - t_f& get_array_f() { return c_f; } - // t_i& get_array_i () { return c_i; } - // t_b& get_array_b () { return c_b; } - - void set(R_constant* C, R_constant_load& L, const Fmatrix& A) - { - VERIFY(RC_float == C->type); - Fvector4* it = c_f.access(L.index); - switch (L.cls) - { - case RC_2x4: - c_f.dirty(L.index, L.index + 2); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - break; - case RC_3x4: - c_f.dirty(L.index, L.index + 3); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - it[2].set(A._13, A._23, A._33, A._43); - break; - case RC_4x4: - c_f.dirty(L.index, L.index + 4); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - it[2].set(A._13, A._23, A._33, A._43); - it[3].set(A._14, A._24, A._34, A._44); - break; - default: -#ifdef DEBUG - xrDebug::Fatal(DEBUG_INFO, "Invalid constant run-time-type for '%s'", *C->name); -#else - NODEFAULT; -#endif - } - } - - void set(R_constant* C, R_constant_load& L, const Fvector4& A) - { - VERIFY(RC_float == C->type); - VERIFY(RC_1x4 == L.cls); - c_f.access(L.index)->set(A); - c_f.dirty(L.index, L.index + 1); - } - - void seta(R_constant* C, R_constant_load& L, u32 e, const Fmatrix& A) - { - VERIFY(RC_float == C->type); - u32 base; - Fvector4* it; - switch (L.cls) - { - case RC_2x4: - base = L.index + 2 * e; - it = c_f.access(base); - c_f.dirty(base, base + 2); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - break; - case RC_3x4: - base = L.index + 3 * e; - it = c_f.access(base); - c_f.dirty(base, base + 3); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - it[2].set(A._13, A._23, A._33, A._43); - break; - case RC_4x4: - base = L.index + 4 * e; - it = c_f.access(base); - c_f.dirty(base, base + 4); - it[0].set(A._11, A._21, A._31, A._41); - it[1].set(A._12, A._22, A._32, A._42); - it[2].set(A._13, A._23, A._33, A._43); - it[3].set(A._14, A._24, A._34, A._44); - break; - default: -#ifdef DEBUG - xrDebug::Fatal(DEBUG_INFO, "Invalid constant run-time-type for '%s'", *C->name); -#else - NODEFAULT; -#endif - } - } - - void seta(R_constant* C, R_constant_load& L, u32 e, const Fvector4& A) - { - VERIFY(RC_float == C->type); - VERIFY(RC_1x4 == L.cls); - u32 base = L.index + e; - c_f.access(base)->set(A); - c_f.dirty(base, base + 1); - } -}; - -class ECORE_API R_constants -{ -public: - alignas(16) R_constant_array a_pixel; - alignas(16) R_constant_array a_vertex; - - void flush_cache(); - - // fp, non-array versions - ICF void set(R_constant* C, const Fmatrix& A) - { - if (C->destination & 1) - { - a_pixel.set(C, C->ps, A); - a_pixel.b_dirty = TRUE; - } - if (C->destination & 2) - { - a_vertex.set(C, C->vs, A); - a_vertex.b_dirty = TRUE; - } - } - ICF void set(R_constant* C, const Fvector4& A) - { - if (C->destination & 1) - { - a_pixel.set(C, C->ps, A); - a_pixel.b_dirty = TRUE; - } - if (C->destination & 2) - { - a_vertex.set(C, C->vs, A); - a_vertex.b_dirty = TRUE; - } - } - ICF void set(R_constant* C, float x, float y, float z, float w) - { - Fvector4 data; - data.set(x, y, z, w); - set(C, data); - } - - // fp, array versions - ICF void seta(R_constant* C, u32 e, const Fmatrix& A) - { - if (C->destination & 1) - { - a_pixel.seta(C, C->ps, e, A); - a_pixel.b_dirty = TRUE; - } - if (C->destination & 2) - { - a_vertex.seta(C, C->vs, e, A); - a_vertex.b_dirty = TRUE; - } - } - ICF void seta(R_constant* C, u32 e, const Fvector4& A) - { - if (C->destination & 1) - { - a_pixel.seta(C, C->ps, e, A); - a_pixel.b_dirty = TRUE; - } - if (C->destination & 2) - { - a_vertex.seta(C, C->vs, e, A); - a_vertex.b_dirty = TRUE; - } - } - ICF void seta(R_constant* C, u32 e, float x, float y, float z, float w) - { - Fvector4 data; - data.set(x, y, z, w); - seta(C, e, data); - } - - // - ICF void flush() - { - if (a_pixel.b_dirty || a_vertex.b_dirty) - flush_cache(); - } -}; -#endif // dx9r_constants_cacheH diff --git a/src/Layers/xrRenderDX9/dx9r_screenshot.cpp b/src/Layers/xrRenderDX9/dx9r_screenshot.cpp deleted file mode 100644 index 009f769c37b..00000000000 --- a/src/Layers/xrRenderDX9/dx9r_screenshot.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include "stdafx.h" - -//#include "xr_effgamma.h" -#include "xrEngine/xrImage_Resampler.h" - -#include -#include -#include - -#define GAMESAVE_SIZE 128 - -void CRender::Screenshot(ScreenshotMode mode /*= SM_NORMAL*/, pcstr name /*= nullptr*/) -{ - if (!Device.b_is_Ready) - return; - - // Create temp-surface - DirectX::ScratchImage image; - u32* pPixel = nullptr; - u32* pEnd = nullptr; - u32* pDst = nullptr; - IDirect3DSurface9* pFB; - D3DLOCKED_RECT D; - HRESULT hr; - hr = HW.pDevice->CreateOffscreenPlainSurface( - Device.dwWidth, Device.dwHeight, HW.Caps.fTarget, D3DPOOL_SYSTEMMEM, &pFB, nullptr); - if (FAILED(hr)) - return; - hr = HW.pDevice->GetRenderTargetData(Target->get_base_rt(), pFB); - if (FAILED(hr)) - goto _end_; - hr = pFB->LockRect(&D, nullptr, D3DLOCK_NOSYSLOCK); - if (FAILED(hr)) - goto _end_; - hr = image.Initialize2D(DXGI_FORMAT_B8G8R8A8_UNORM, Device.dwWidth, Device.dwHeight, 1, 1); - if (FAILED(hr)) - goto _end_; - // Image processing (gamma-correct) - pDst = (u32*)image.GetPixels(); - pPixel = (u32*)D.pBits; - pEnd = pPixel + (Device.dwWidth * Device.dwHeight); - // IGOR: Remove inverse color correction and kill alpha - /* - D3DGAMMARAMP G; - dxRenderDeviceRender::Instance().gammaGenLUT(G); - for (int i=0; i<256; i++) { - G.red [i] /= 256; - G.green [i] /= 256; - G.blue [i] /= 256; - } - for (;pPixel!=pEnd; pPixel++) { - u32 p = *pPixel; - *pPixel = color_xrgb ( - G.red [color_get_R(p)], - G.green [color_get_G(p)], - G.blue [color_get_B(p)] - ); - } - */ - - // Kill alpha - for (; pPixel != pEnd; pPixel++, pDst++) - { - u32 p = *pPixel; - *pDst = color_xrgb(color_get_R(p), color_get_G(p), color_get_B(p)); - } - - hr = pFB->UnlockRect(); - if (hr != D3D_OK) - goto _end_; - - // Save - switch (mode) - { - case IRender::SM_FOR_GAMESAVE: - { - // resize - DirectX::ScratchImage resized; - hr = Resize(*image.GetImage(0, 0, 0), GAMESAVE_SIZE, GAMESAVE_SIZE, - DirectX::TEX_FILTER_BOX, resized); - if (FAILED(hr)) - goto _end_; - - // compress - DirectX::ScratchImage compressed; - hr = Compress(*resized.GetImage(0, 0, 0), DXGI_FORMAT_BC1_UNORM, - DirectX::TEX_COMPRESS_DEFAULT | DirectX::TEX_COMPRESS_PARALLEL, 0.0f, compressed); - if (FAILED(hr)) - goto _end_; - - // save (logical & physical) - DirectX::Blob saved; - hr = SaveToDDSMemory(*compressed.GetImage(0, 0, 0), DirectX::DDS_FLAGS_FORCE_DX9_LEGACY, saved); - if (FAILED(hr)) - goto _end_; - - if (IWriter* fs = FS.w_open(name)) - { - fs->w(saved.GetBufferPointer(), saved.GetBufferSize()); - FS.w_close(fs); - } - break; - } - case IRender::SM_NORMAL: - { - string64 t_stemp; - string_path buf; - xr_sprintf(buf, "ss_%s_%s_(%s).jpg", Core.UserName, timestamp(t_stemp), g_pGameLevel ? g_pGameLevel->name().c_str() : "mainmenu"); - - DirectX::Blob saved; - hr = SaveToWICMemory(*image.GetImage(0, 0, 0), DirectX::WIC_FLAGS_NONE, GUID_ContainerFormatJpeg, saved); - if (SUCCEEDED(hr)) - { - if (IWriter* fs = FS.w_open("$screenshots$", buf)) - { - fs->w(saved.GetBufferPointer(), saved.GetBufferSize()); - FS.w_close(fs); - } - } - - // hq - if (strstr(Core.Params, "-ss_tga")) - { - xr_sprintf(buf, "ssq_%s_%s_(%s).tga", Core.UserName, timestamp(t_stemp), g_pGameLevel ? g_pGameLevel->name().c_str() : "mainmenu"); - - hr = SaveToTGAMemory(*image.GetImage(0, 0, 0), saved); - if (FAILED(hr)) - goto _end_; - - if (IWriter* fs = FS.w_open("$screenshots$", buf)) - { - fs->w(saved.GetBufferPointer(), saved.GetBufferSize()); - FS.w_close(fs); - } - } - break; - } - case IRender::SM_FOR_LEVELMAP: - case IRender::SM_FOR_CUBEMAP: - { - string_path buf; - VERIFY(name); - strconcat(sizeof(buf), buf, name, ".tga"); - - DirectX::ScratchImage img; - hr = img.Initialize2D(image.GetMetadata().format, Device.dwHeight, Device.dwHeight, 1, 1); - if (FAILED(hr)) - goto _end_; - - imf_Process((u32*)img.GetPixels(), Device.dwHeight, Device.dwHeight, (u32*)image.GetPixels(), Device.dwWidth, Device.dwHeight, imf_lanczos3); - - DirectX::Blob saved; - hr = DirectX::SaveToTGAMemory(*img.GetImage(0, 0, 0), saved); - if (FAILED(hr)) - goto _end_; - - if (IWriter* fs = FS.w_open("$screenshots$", buf)) - { - fs->w(saved.GetBufferPointer(), saved.GetBufferSize()); - FS.w_close(fs); - } - break; - } - } // switch (mode) - -_end_: - _RELEASE(pFB); -} - -void CRender::ScreenshotAsyncEnd(CMemoryWriter& memory_writer) -{ - if (!Device.b_is_Ready) - return; - - VERIFY(!m_bMakeAsyncSS); - - IDirect3DSurface9* pFB = Target->rt_async_ss->pRT; - - D3DLOCKED_RECT D; - const HRESULT hr = pFB->LockRect(&D, nullptr, D3DLOCK_NOSYSLOCK); - if (hr != D3D_OK) - return; - -#if RENDER == R_R1 - u32 rtWidth = Target->get_rtwidth(); - u32 rtHeight = Target->get_rtheight(); -#else // RENDER != R_R1 - u32 rtWidth = Device.dwWidth; - u32 rtHeight = Device.dwHeight; -#endif // RENDER != R_R1 - - // Image processing (gamma-correct) - u32* pPixel = (u32*)D.pBits; - u32* pOrigin = pPixel; - u32* pEnd = pPixel + (rtWidth * rtHeight); - - // Kill alpha -#if RENDER != R_R1 - if (Target->rt_Color->fmt == D3DFMT_A16B16G16R16F) - { - static const int iMaxPixelsInARow = 1024; - auto* pPixelElement16 = (DirectX::PackedVector::HALF*)pPixel; - - float tmpArray[4 * iMaxPixelsInARow]; - while (pPixel != pEnd) - { - const int iProcessPixels = _min(iMaxPixelsInARow, (s32)(pEnd - pPixel)); - - DirectX::PackedVector::XMConvertHalfToFloatStream(tmpArray, sizeof(float), - pPixelElement16, sizeof(DirectX::PackedVector::HALF), iProcessPixels * 4); - - for (int i = 0; i < iProcessPixels; ++i) - { - *pPixel = color_argb_f(1.0f, tmpArray[i * 4], tmpArray[i * 4 + 1], tmpArray[i * 4 + 2]); - - ++pPixel; - } - - pPixelElement16 += iProcessPixels * 4; - } - } - else -#endif // RENDER != R_R1 - { - for (; pPixel != pEnd; pPixel++) - { - u32 p = *pPixel; - *pPixel = color_xrgb(color_get_R(p), color_get_G(p), color_get_B(p)); - } - } - - { - memory_writer.w(&rtWidth, sizeof(rtWidth)); - memory_writer.w(&rtHeight, sizeof(rtHeight)); - memory_writer.w(pOrigin, (rtWidth * rtHeight) * 4); - } - - CHK_DX(pFB->UnlockRect()); -} diff --git a/src/Layers/xrRenderDX9/dx9shader_utils.h b/src/Layers/xrRenderDX9/dx9shader_utils.h deleted file mode 100644 index 22a0f32436f..00000000000 --- a/src/Layers/xrRenderDX9/dx9shader_utils.h +++ /dev/null @@ -1,250 +0,0 @@ -#pragma once - -#if __has_include() -# include -# define USE_D3DX -#else -# include -#endif - -#ifdef USE_D3DX -// When building with Unity build, d3dx9.h and d3dcompiler.h both get included in files -// So we cannot just declare: -// using D3D_SHADER_MACRO = D3DXMACRO; -// because it would conflict. -// I could exclude some files from Unity build, but why? -// Let's just make it robustly compileable in all cases. -using IShaderBlob = ID3DXBuffer; -using IShaderIncluder = ID3DXInclude; -using SHADER_MACRO = D3DXMACRO; -using INCLUDE_TYPE = D3DXINCLUDE_TYPE; -#else -using IShaderBlob = ID3DBlob; -using IShaderIncluder = ID3DInclude; -using SHADER_MACRO = D3D_SHADER_MACRO; -using INCLUDE_TYPE = D3D_INCLUDE_TYPE; - -typedef struct _D3DXSHADER_CONSTANTTABLE -{ - DWORD Size; // sizeof(D3DXSHADER_CONSTANTTABLE) - DWORD Creator; // LPCSTR offset - DWORD Version; // shader version - DWORD Constants; // number of constants - DWORD ConstantInfo; // D3DXSHADER_CONSTANTINFO[Constants] offset - DWORD Flags; // flags shader was compiled with - DWORD Target; // LPCSTR offset - -} D3DXSHADER_CONSTANTTABLE, * LPD3DXSHADER_CONSTANTTABLE; - - -typedef struct _D3DXSHADER_CONSTANTINFO -{ - DWORD Name; // LPCSTR offset - WORD RegisterSet; // D3DXREGISTER_SET - WORD RegisterIndex; // register number - WORD RegisterCount; // number of registers - WORD Reserved; // reserved - DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset - DWORD DefaultValue; // offset of default value - -} D3DXSHADER_CONSTANTINFO, * LPD3DXSHADER_CONSTANTINFO; - - -typedef struct _D3DXSHADER_TYPEINFO -{ - WORD Class; // D3DXPARAMETER_CLASS - WORD Type; // D3DXPARAMETER_TYPE - WORD Rows; // number of rows (matrices) - WORD Columns; // number of columns (vectors and matrices) - WORD Elements; // array dimension - WORD StructMembers; // number of struct members - DWORD StructMemberInfo; // D3DXSHADER_STRUCTMEMBERINFO[Members] offset - -} D3DXSHADER_TYPEINFO, * LPD3DXSHADER_TYPEINFO; - - -typedef struct _D3DXSHADER_STRUCTMEMBERINFO -{ - DWORD Name; // LPCSTR offset - DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset - -} D3DXSHADER_STRUCTMEMBERINFO, * LPD3DXSHADER_STRUCTMEMBERINFO; - -typedef enum _D3DXREGISTER_SET -{ - D3DXRS_BOOL, - D3DXRS_INT4, - D3DXRS_FLOAT4, - D3DXRS_SAMPLER, - D3DXRS_FORCE_DWORD = 0x7fffffff -} D3DXREGISTER_SET, * LPD3DXREGISTER_SET; - -typedef enum D3DXPARAMETER_CLASS -{ - D3DXPC_SCALAR, - D3DXPC_VECTOR, - D3DXPC_MATRIX_ROWS, - D3DXPC_MATRIX_COLUMNS, - D3DXPC_OBJECT, - D3DXPC_STRUCT, - D3DXPC_FORCE_DWORD = 0x7fffffff -} D3DXPARAMETER_CLASS, * LPD3DXPARAMETER_CLASS; - -typedef enum D3DXPARAMETER_TYPE -{ - D3DXPT_VOID, - D3DXPT_BOOL, - D3DXPT_INT, - D3DXPT_FLOAT, - D3DXPT_STRING, - D3DXPT_TEXTURE, - D3DXPT_TEXTURE1D, - D3DXPT_TEXTURE2D, - D3DXPT_TEXTURE3D, - D3DXPT_TEXTURECUBE, - D3DXPT_SAMPLER, - D3DXPT_SAMPLER1D, - D3DXPT_SAMPLER2D, - D3DXPT_SAMPLER3D, - D3DXPT_SAMPLERCUBE, - D3DXPT_PIXELSHADER, - D3DXPT_VERTEXSHADER, - D3DXPT_PIXELFRAGMENT, - D3DXPT_VERTEXFRAGMENT, - D3DXPT_UNSUPPORTED, - D3DXPT_FORCE_DWORD = 0x7fffffff -} D3DXPARAMETER_TYPE, * LPD3DXPARAMETER_TYPE; - -// Errors -#define _FACDD 0x876 -#define MAKE_DDHRESULT(code) MAKE_HRESULT(1, _FACDD, code) - -enum _D3DXERR -{ - D3DXERR_CANNOTMODIFYINDEXBUFFER = MAKE_DDHRESULT(2900), - D3DXERR_INVALIDMESH = MAKE_DDHRESULT(2901), - D3DXERR_CANNOTATTRSORT = MAKE_DDHRESULT(2902), - D3DXERR_SKINNINGNOTSUPPORTED = MAKE_DDHRESULT(2903), - D3DXERR_TOOMANYINFLUENCES = MAKE_DDHRESULT(2904), - D3DXERR_INVALIDDATA = MAKE_DDHRESULT(2905), - D3DXERR_LOADEDMESHASNODATA = MAKE_DDHRESULT(2906), - D3DXERR_DUPLICATENAMEDFRAGMENT = MAKE_DDHRESULT(2907), - D3DXERR_CANNOTREMOVELASTITEM = MAKE_DDHRESULT(2908), -}; -#endif - -class ShaderIncluder final : public IShaderIncluder -{ -public: - HRESULT __stdcall Open( - INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) noexcept override - { - string_path pname; - strconcat(pname, RImplementation.getShaderPath(), pFileName); - IReader* R = FS.r_open("$game_shaders$", pname); - if (nullptr == R) - { - // possibly in shared directory or somewhere else - open directly - R = FS.r_open("$game_shaders$", pFileName); - if (nullptr == R) - return E_FAIL; - } - - // duplicate and zero-terminate - const size_t size = R->length(); - u8* data = xr_alloc(size + 1); - CopyMemory(data, R->pointer(), size); - data[size] = 0; - FS.r_close(R); - - *ppData = data; - *pBytes = size; - return D3D_OK; - } - - HRESULT __stdcall Close(LPCVOID pData) noexcept override - { - auto mutableData = const_cast(pData); - xr_free(mutableData); - return D3D_OK; - } -}; - -inline HRESULT WINAPI FindShaderComment(const DWORD* byte_code, DWORD fourcc, const void** data, UINT* size) -{ -#ifdef USE_D3DX - return D3DXFindShaderComment(byte_code, fourcc, data, size); -#else - const DWORD* ptr = byte_code; - - if (data) - *data = nullptr; - if (size) - *size = 0; - - if (!byte_code) - return D3DERR_INVALIDCALL; - - const DWORD version = *ptr >> 16; - if (version != 0x4658 /* FX */ - && version != 0x5458 /* TX */ - && version != 0x7ffe - && version != 0x7fff - && version != 0xfffe /* VS */ - && version != 0xffff) /* PS */ - { - return D3DXERR_INVALIDDATA; - } - - while (*++ptr != D3DSIO_END) - { - /* Check if it is a comment */ - if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT) - { - const DWORD comment_size = (*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - - /* Check if this is the comment we are looking for */ - if (*(ptr + 1) == fourcc) - { - const UINT ctab_size = (comment_size - 1) * sizeof(DWORD); - const void* ctab_data = ptr + 2; - if (size) - *size = ctab_size; - if (data) - *data = ctab_data; - return D3D_OK; - } - ptr += comment_size; - } - } - - return S_FALSE; -#endif -} - -inline HRESULT WINAPI DisassembleShader(CONST DWORD* pShader, SIZE_T SrcDataSize, - BOOL EnableColorCode, LPCSTR pComments, IShaderBlob** ppDisassembly) -{ -#ifdef USE_D3DX - std::ignore = SrcDataSize; - return D3DXDisassembleShader(pShader, EnableColorCode, pComments, ppDisassembly); -#else - return D3DDisassemble(pShader, SrcDataSize, EnableColorCode ? D3D_DISASM_ENABLE_COLOR_CODE : 0, pComments, ppDisassembly); -#endif -} - -inline HRESULT WINAPI CompileShader(LPCVOID pSrcData, SIZE_T SrcDataSize, - CONST SHADER_MACRO* pDefines, IShaderIncluder* pInclude, - LPCSTR pEntrypoint, LPCSTR pTarget, DWORD Flags, - IShaderBlob** ppCode, IShaderBlob** ppErrorMsgs) -{ -#ifdef USE_D3DX - return D3DXCompileShader((LPCSTR)pSrcData, SrcDataSize, pDefines, pInclude, - pEntrypoint, pTarget, Flags | D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, - ppCode, ppErrorMsgs, nullptr); -#else - return D3DCompile(pSrcData, SrcDataSize, nullptr, pDefines, pInclude, - pEntrypoint, pTarget, Flags | D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY, 0, - ppCode, ppErrorMsgs); -#endif -} diff --git a/src/Layers/xrRenderPC_R1/CMakeLists.txt b/src/Layers/xrRenderPC_R1/CMakeLists.txt deleted file mode 100644 index 54800c07124..00000000000 --- a/src/Layers/xrRenderPC_R1/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -add_library(xrRenderPC_R1 SHARED) - -target_sources(xrRenderPC_R1 PRIVATE - FStaticRender_Blenders.cpp - FStaticRender.cpp - FStaticRender_DetectSector.cpp - FStaticRender.h - FStaticRender_Loader.cpp - FStaticRender_RenderTarget.cpp - FStaticRender_RenderTarget.h - FStaticRender_Shaders.cpp - FStaticRender_Types.h - GlowManager.cpp - GlowManager.h - LightPPA.cpp - LightPPA.h - LightProjector.cpp - LightProjector.h - LightShadows.cpp - LightShadows.h - stdafx.cpp - stdafx.h - xrRender_R1.cpp -) - -target_include_directories(xrRenderPC_R1 - PRIVATE - "${CMAKE_SOURCE_DIR}/src" - "${CMAKE_SOURCE_DIR}/sdk/include" -) - -target_link_libraries(xrRenderPC_R1 - PRIVATE - xrCore - xrCDB - xrEngine - xrParticles - xrScriptEngine - xrAPI - xrMiscMath -) - -target_compile_definitions(xrRenderPC_R1 - PRIVATE - XRRENDER_R1_EXPORTS -) - -set_target_properties(xrRenderPC_R1 PROPERTIES - PREFIX "" -) - -target_precompile_headers(xrRenderPC_R1 - PRIVATE - stdafx.h -) - -install(TARGETS xrRenderPC_R1 LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/src/Layers/xrRenderPC_R1/FStaticRender.cpp b/src/Layers/xrRenderPC_R1/FStaticRender.cpp deleted file mode 100644 index 0e83e26464f..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender.cpp +++ /dev/null @@ -1,878 +0,0 @@ -#include "stdafx.h" - -#include "xrCore/Threading/TaskManager.hpp" - -#include "FStaticRender.h" - -#include "xrEngine/xr_object.h" -#include "xrEngine/CustomHUD.h" -#include "xrEngine/IGame_Persistent.h" -#include "xrEngine/Environment.h" -#include "xrEngine/GameFont.h" -#include "xrEngine/PerformanceAlert.hpp" - -#include "Layers/xrRender/FBasicVisual.h" -#include "Layers/xrRender/SkeletonCustom.h" -#include "Layers/xrRender/LightTrack.h" -#include "Layers/xrRender/dxWallMarkArray.h" -#include "Layers/xrRender/dxUIShader.h" -#include "Layers/xrRender/ShaderResourceTraits.h" - -CRender RImplementation; - -////////////////////////////////////////////////////////////////////////// -ShaderElement* CRender::rimp_select_sh_dynamic(dxRender_Visual* pVisual, float /*cdist_sq*/, u32 phase) -{ - switch (phase) - { - case PHASE_NORMAL: - return (RImplementation.L_Projector->shadowing() ? - pVisual->shader->E[SE_R1_NORMAL_HQ] : pVisual->shader->E[SE_R1_NORMAL_LQ])._get(); - case PHASE_POINT: return pVisual->shader->E[SE_R1_LPOINT]._get(); - case PHASE_SPOT: return pVisual->shader->E[SE_R1_LSPOT]._get(); - default: NODEFAULT; - } -#ifdef DEBUG - return nullptr; -#endif -} -////////////////////////////////////////////////////////////////////////// -ShaderElement* CRender::rimp_select_sh_static(dxRender_Visual* pVisual, float cdist_sq, u32 phase) -{ - switch (phase) - { - case PHASE_NORMAL: - return (((_sqrt(cdist_sq) - pVisual->vis.sphere.R) < 44) ? pVisual->shader->E[SE_R1_NORMAL_HQ] : - pVisual->shader->E[SE_R1_NORMAL_LQ]) - ._get(); - case PHASE_POINT: return pVisual->shader->E[SE_R1_LPOINT]._get(); - case PHASE_SPOT: return pVisual->shader->E[SE_R1_LSPOT]._get(); - default: NODEFAULT; - } -#ifdef DEBUG - return nullptr; -#endif -} - -void CRender::OnDeviceCreate(pcstr shName) -{ - o.new_shader_support = 0; - D3DXRenderBase::OnDeviceCreate(shName); -} - -////////////////////////////////////////////////////////////////////////// -void CRender::create() -{ - L_Shadows = nullptr; - L_Projector = nullptr; - - Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 0x12345678); - - // c-setup - Resources->RegisterConstantSetup("L_dynamic_pos", &r1_dlight_binder_PR); - Resources->RegisterConstantSetup("L_dynamic_color", &r1_dlight_binder_color); - Resources->RegisterConstantSetup("L_dynamic_xform", &r1_dlight_binder_xform); - - // distortion - u32 v_dev = CAP_VERSION(HW.Caps.raster_major, HW.Caps.raster_minor); - u32 v_need = CAP_VERSION(1, 4); - if (v_dev >= v_need) - o.distortion = TRUE; - else - o.distortion = FALSE; - if (strstr(Core.Params, "-nodistort")) - o.distortion = FALSE; - Msg("* distortion: %s, dev(%d),need(%d)", o.distortion ? "used" : "unavailable", v_dev, v_need); - - // Color mapping - if (v_dev >= v_need) - o.color_mapping = TRUE; - else - o.color_mapping = FALSE; - if (strstr(Core.Params, "-nocolormap")) - o.color_mapping = FALSE; - Msg("* color_mapping: %s, dev(%d),need(%d)", o.color_mapping ? "used" : "unavailable", v_dev, v_need); - - m_skinning = -1; - - // Fixed-function pipeline - o.ffp = HW.Caps.hasFixedPipeline && ps_r1_flags.test(R1FLAG_FFP); - - // disasm - o.disasm = (strstr(Core.Params, "-disasm")) ? TRUE : FALSE; - o.forceskinw = (strstr(Core.Params, "-skinw")) ? TRUE : FALSE; - o.no_detail_textures = !ps_r2_ls_flags.test(R1FLAG_DETAIL_TEXTURES); - - m_bMakeAsyncSS = false; - - Target = xr_new(); // Main target - - Models = xr_new(); - L_Dynamic = xr_new(); - PSLibrary.OnCreate(); - //. HWOCC.occq_create (occq_size); -} - -void CRender::destroy() -{ - m_bMakeAsyncSS = false; - //. HWOCC.occq_destroy (); - PSLibrary.OnDestroy(); - - xr_delete(L_Dynamic); - xr_delete(Models); - - //*** Components - xr_delete(Target); - Device.seqFrame.Remove(this); -} - -void CRender::reset_begin() -{ - Resources->reset_begin(); - - //AVO: let's reload details while changed details options on vid_restart - if (b_loaded && (dm_current_size != dm_size || - !fsimilar(ps_r__Detail_density, ps_current_detail_density) || - !fsimilar(ps_r__Detail_height, ps_current_detail_height))) - { - Details->Unload(); - xr_delete(Details); - } - xr_delete(Target); - //HWOCC.occq_destroy(); -} - -void CRender::reset_end() -{ - //. HWOCC.occq_create (occq_size); - Target = xr_new(); - if (L_Projector) - L_Projector->invalidate(); - - // let's reload details while changed details options on vid_restart - if (b_loaded && (dm_current_size != dm_size || - !fsimilar(ps_r__Detail_density, ps_current_detail_density) || - !fsimilar(ps_r__Detail_height, ps_current_detail_height))) - { - Details = xr_new(); - Details->Load(); - } - - // Set this flag true to skip the first render frame, - // that some data is not ready in the first frame (for example device camera position) - m_bFirstFrameAfterReset = true; -} - -void CRender::BeforeRender() -{ - if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) - return; - - ProcessHOMTask = &TaskScheduler->AddTask("MT-HOM", { &HOM, &CHOM::MT_RENDER }); -} - -void CRender::OnFrame() -{ - Models->DeleteQueue(); - if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) - return; - if (ps_r2_ls_flags.test(R2FLAG_EXP_MT_CALC)) - { - // MT-details (@front) - Device.seqParallel.insert( - Device.seqParallel.begin(), fastdelegate::FastDelegate0<>(Details, &CDetailManager::MT_CALC)); - } -} - -// Перед началом рендера мира --#SM+#-- -void CRender::BeforeWorldRender() {} - -// После рендера мира и пост-эффектов --#SM+#-- -void CRender::AfterWorldRender() {} - -// Implementation -IRender_ObjectSpecific* CRender::ros_create(IRenderable* parent) { return xr_new(); } -void CRender::ros_destroy(IRender_ObjectSpecific*& p) { xr_delete(p); } -IRenderVisual* CRender::model_Create(LPCSTR name, IReader* data) { return Models->Create(name, data); } -IRenderVisual* CRender::model_CreateChild(LPCSTR name, IReader* data) { return Models->CreateChild(name, data); } -IRenderVisual* CRender::model_Duplicate(IRenderVisual* V) { return Models->Instance_Duplicate((dxRender_Visual*)V); } -void CRender::model_Delete(IRenderVisual*& V, bool bDiscard) -{ - dxRender_Visual* pVisual = (dxRender_Visual*)V; - Models->Delete(pVisual, bDiscard); - V = nullptr; -} -IRender_DetailModel* CRender::model_CreateDM(IReader* F) -{ - CDetail* D = xr_new(); - D->Load(F); - return D; -} -void CRender::model_Delete(IRender_DetailModel*& F) -{ - if (F) - { - CDetail* D = (CDetail*)F; - D->Unload(); - xr_delete(D); - F = nullptr; - } -} -IRenderVisual* CRender::model_CreatePE(LPCSTR name) -{ - PS::CPEDef* SE = PSLibrary.FindPED(name); - R_ASSERT3(SE, "Particle effect doesn't exist", name); - return Models->CreatePE(SE); -} -IRenderVisual* CRender::model_CreateParticles(LPCSTR name) -{ - PS::CPEDef* SE = PSLibrary.FindPED(name); - if (SE) - return Models->CreatePE(SE); - else - { - PS::CPGDef* SG = PSLibrary.FindPGD(name); - R_ASSERT3(SG, "Particle effect or group doesn't exist", name); - return Models->CreatePG(SG); - } -} -void CRender::models_Prefetch() { Models->Prefetch(); } -void CRender::models_Clear(bool b_complete) { Models->ClearPool(b_complete); } -ref_shader CRender::getShader(int id) -{ - VERIFY(id < int(Shaders.size())); - return Shaders[id]; -} -IRenderVisual* CRender::getVisual(int id) -{ - VERIFY(id < int(Visuals.size())); - return Visuals[id]; -} -VertexElement* CRender::getVB_Format(int id, bool alternative) -{ - if (alternative) - { - VERIFY(id < int(xDC.size())); - return xDC[id].begin(); - } - else - { - VERIFY(id < int(nDC.size())); - return nDC[id].begin(); - } -} -VertexStagingBuffer* CRender::getVB(int id, bool alternative) -{ - if (alternative) - { - VERIFY(id < int(xVB.size())); - return &xVB[id]; - } - else - { - VERIFY(id < int(nVB.size())); - return &nVB[id]; - } -} -IndexStagingBuffer* CRender::getIB(int id, bool alternative) -{ - if (alternative) - { - VERIFY(id < int(xIB.size())); - return &xIB[id]; - } - else - { - VERIFY(id < int(nIB.size())); - return &nIB[id]; - } -} -FSlideWindowItem* CRender::getSWI(int id) -{ - VERIFY(id < int(SWIs.size())); - return &SWIs[id]; -} -IRender_Target* CRender::getTarget() { return Target; } -IRender_Light* CRender::light_create() { return Lights.Create(); } -IRender_Glow* CRender::glow_create() { return xr_new(); } -bool CRender::occ_visible(vis_data& P) { return HOM.visible(P); } -bool CRender::occ_visible(sPoly& P) { return HOM.visible(P); } -bool CRender::occ_visible(Fbox& P) { return HOM.visible(P); } -void CRender::add_Visual(u32 context_id, IRenderable* root, IRenderVisual* V, Fmatrix& m) -{ - // TODO: this whole function should be replaced by a list of renderables+xforms returned from `renderable_Render` call - auto& dsgraph = get_context(context_id); - set_Object(root, dsgraph.o.phase); - dsgraph.add_leafs_dynamic(root, (dxRender_Visual*)V, m); -} -void CRender::add_StaticWallmark(ref_shader& S, const Fvector& P, float s, CDB::TRI* T, Fvector* verts) -{ - if (T->suppress_wm) - return; - VERIFY2(_valid(P) && _valid(s) && T && verts && (s > EPS_L), "Invalid static wallmark params"); - Wallmarks->AddStaticWallmark(T, verts, P, &*S, s); -} - -void CRender::add_StaticWallmark(IWallMarkArray* pArray, const Fvector& P, float s, CDB::TRI* T, Fvector* V) -{ - dxWallMarkArray* pWMA = (dxWallMarkArray*)pArray; - ref_shader* pShader = pWMA->dxGenerateWallmark(); - if (pShader) - add_StaticWallmark(*pShader, P, s, T, V); -} - -void CRender::add_StaticWallmark(const wm_shader& S, const Fvector& P, float s, CDB::TRI* T, Fvector* V) -{ - dxUIShader* pShader = (dxUIShader*)&*S; - add_StaticWallmark(pShader->hShader, P, s, T, V); -} - -void CRender::clear_static_wallmarks() { Wallmarks->clear(); } -void CRender::add_SkeletonWallmark(intrusive_ptr wm) { Wallmarks->AddSkeletonWallmark(wm); } -void CRender::add_SkeletonWallmark( - const Fmatrix* xf, CKinematics* obj, ref_shader& sh, const Fvector& start, const Fvector& dir, float size) -{ - Wallmarks->AddSkeletonWallmark(xf, obj, sh, start, dir, size); -} -void CRender::add_SkeletonWallmark( - const Fmatrix* xf, IKinematics* obj, IWallMarkArray* pArray, const Fvector& start, const Fvector& dir, float size) -{ - dxWallMarkArray* pWMA = (dxWallMarkArray*)pArray; - ref_shader* pShader = pWMA->dxGenerateWallmark(); - if (pShader) - add_SkeletonWallmark(xf, (CKinematics*)obj, *pShader, start, dir, size); -} - -#include "xrEngine/PS_instance.h" -void CRender::set_Object(IRenderable* O, u32 phase) -{ - if (O) - { - VERIFY(dynamic_cast(O) || dynamic_cast(O)); - if (O->GetRenderData().pROS) - { - VERIFY(dynamic_cast(O->GetRenderData().pROS)); - } - } - if (PHASE_NORMAL == phase) - { - if (L_Shadows) - L_Shadows->set_object(O); - - if (L_Projector) - L_Projector->set_object(O); - } - else - { - if (L_Shadows) - L_Shadows->set_object(nullptr); - - if (L_Projector) - L_Projector->set_object(nullptr); - } -} - -static u32 gm_Ambient = 0; -IC void gm_SetAmbient(u32 C) -{ - if (C != gm_Ambient) - { - gm_Ambient = C; - CHK_DX(HW.pDevice->SetRenderState(D3DRS_AMBIENT, color_xrgb(C, C, C))); - } -} - -void CRender::apply_object(CBackend& cmd_list, IRenderable* O) -{ - if (nullptr == O) - return; - if (O->renderable_ROS()) - { - CROS_impl& LT = *((CROS_impl*)O->GetRenderData().pROS); - VERIFY(dynamic_cast(O) || dynamic_cast(O)); - VERIFY(dynamic_cast(O->GetRenderData().pROS)); - float o_hemi = 0.5f * LT.get_hemi(); - float o_sun = 0.5f * LT.get_sun(); - RCache.set_c(c_ldynamic_props, o_sun, o_sun, o_sun, o_hemi); - // shadowing - if ((LT.shadow_recv_frame == Device.dwFrame) && O->renderable_ShadowReceive()) - { - gm_SetAmbient(0); - RImplementation.L_Projector->setup(LT.shadow_recv_slot); - } - else - { - //gm_SetAmbient(iFloor(LT.ambient) / 2); - } - - // ambience - //gm_SetAmbient(iFloor(LT.ambient) / 2); - - // set up to 8 lights to device - const int max = _min(int(LT.lights.size()), HW.Caps.max_ffp_lights); - for (int L = 0; L < max; L++) - { - CHK_DX(HW.pDevice->SetLight(L, (D3DLIGHT9*)<.lights[L].source->ldata)); - } - - // enable them, disable others - static int gm_Lcount = 0; - for (int L = gm_Lcount; L < max; L++) - { - CHK_DX(HW.pDevice->LightEnable(L, TRUE)); - } - for (int L = max; L < gm_Lcount; L++) - { - CHK_DX(HW.pDevice->LightEnable(L, FALSE)); - } - gm_Lcount = max; - } -} - -// Misc -float g_fSCREEN; - -void CRender::rmNear(CBackend& cmd_list) -{ - IRender_Target* T = getTarget(); - RCache.SetViewport({ 0, 0, T->get_width(RCache), T->get_height(RCache), 0, 0.02f }); -} - -void CRender::rmFar(CBackend& cmd_list) -{ - IRender_Target* T = getTarget(); - RCache.SetViewport({ 0, 0, T->get_width(RCache), T->get_height(RCache), 0.99999f, 1.f }); -} - -void CRender::rmNormal(CBackend& cmd_list) -{ - IRender_Target* T = getTarget(); - RCache.SetViewport({ 0, 0, T->get_width(RCache), T->get_height(RCache), 0, 1.f }); -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -CRender::CRender() : m_bFirstFrameAfterReset(false), Sectors_xrc("render") {} -CRender::~CRender() {} -extern float r_ssaDISCARD; -extern float r_ssaDONTSORT; -extern float r_ssaLOD_A, r_ssaLOD_B; -extern float r_ssaGLOD_start, r_ssaGLOD_end; -extern float r_ssaHZBvsTEX; - -void CRender::Calculate() -{ -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("CRender::Calculate()"); -#endif // _GPA_ENABLED - - BasicStats.Culling.Begin(); - - // Transfer to global space to avoid deep pointer access - IRender_Target* T = getTarget(); - float fov_factor = _sqr(90.f / Device.fFOV); - g_fSCREEN = float(T->get_width(RCache) * T->get_height(RCache)) * fov_factor * (EPS_S + ps_r__LOD); - r_ssaDISCARD = _sqr(ps_r__ssaDISCARD) / g_fSCREEN; - r_ssaDONTSORT = _sqr(ps_r__ssaDONTSORT / 3) / g_fSCREEN; - r_ssaLOD_A = _sqr(ps_r1_ssaLOD_A / 3) / g_fSCREEN; - r_ssaLOD_B = _sqr(ps_r1_ssaLOD_B / 3) / g_fSCREEN; - r_ssaGLOD_start = _sqr(ps_r__GLOD_ssa_start / 3) / g_fSCREEN; - r_ssaGLOD_end = _sqr(ps_r__GLOD_ssa_end / 3) / g_fSCREEN; - r_ssaHZBvsTEX = _sqr(ps_r__ssaHZBvsTEX / 3) / g_fSCREEN; - - // Frustum - ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB | FRUSTUM_P_FAR); - - // Build L_DB visibility & perform basic initialization - gm_Ambient = 0xFFFFFFFF; - gm_SetAmbient(0); - - if (!ps_r1_flags.is_any(R1FLAG_FFP_LIGHTMAPS | R1FLAG_DLIGHTS)) - HW.pDevice->SetRenderState(D3DRS_AMBIENT, 0xFFFFFFFF); - else - HW.pDevice->SetRenderState(D3DRS_AMBIENT, 0x00000000); - - rmNormal(RCache); - auto& dsgraph = get_imm_context(); - dsgraph.o.use_hom = true; - dsgraph.o.phase = PHASE_NORMAL; - - // Detect camera-sector - if (!vLastCameraPos.similar(Device.vCameraPosition, EPS_S)) - { - const auto sector_id = dsgraph.detect_sector(Device.vCameraPosition); - if (sector_id != IRender_Sector::INVALID_SECTOR_ID) - { - if (sector_id != last_sector_id) - g_pGamePersistent->OnSectorChanged(sector_id); - - last_sector_id = sector_id; - } - vLastCameraPos.set(Device.vCameraPosition); - - // Check if camera is too near to some portal - if so force DualRender - if (rmPortals) - { - Fvector box_radius; - box_radius.set(EPS_L * 2, EPS_L * 2, EPS_L * 2); - dsgraph.Sectors_xrc.box_query(CDB::OPT_FULL_TEST, rmPortals, Device.vCameraPosition, box_radius); - for (size_t K = 0; K < dsgraph.Sectors_xrc.r_count(); K++) - { - CPortal* pPortal = dsgraph.Portals[rmPortals->get_tris()[dsgraph.Sectors_xrc.r_begin()[K].id].dummy]; - pPortal->bDualRender = TRUE; - } - } - } - - // - Lights.Update(); - - // Main process - dsgraph.marker++; - set_Object(nullptr, dsgraph.o.phase); - TaskScheduler->Wait(*ProcessHOMTask); - if (last_sector_id != IRender_Sector::INVALID_SECTOR_ID) - { - // Traverse sector/portal structure - dsgraph.PortalTraverser.traverse(dsgraph.Sectors[last_sector_id], ViewBase, Device.vCameraPosition, - Device.mFullTransform, - CPortalTraverser::VQ_HOM + CPortalTraverser::VQ_SSA + CPortalTraverser::VQ_FADE); - - // Determine visibility for static geometry hierarchy - if (psDeviceFlags.test(rsDrawStatic)) - { - for (u32 s_it = 0; s_it < dsgraph.PortalTraverser.r_sectors.size(); s_it++) - { - CSector* sector = (CSector*)dsgraph.PortalTraverser.r_sectors[s_it]; - dxRender_Visual* root = sector->root(); - for (u32 v_it = 0; v_it < sector->r_frustums.size(); v_it++) - { - dsgraph.add_static(root, sector->r_frustums[v_it], sector->r_frustums[v_it].getMask()); - } - } - } - - // Traverse object database - if (psDeviceFlags.test(rsDrawDynamic)) - { - g_pGamePersistent->SpatialSpace.q_frustum( - dsgraph.lstRenderables, ISpatial_DB::O_ORDERED, STYPE_RENDERABLE + STYPE_LIGHTSOURCE, ViewBase); - - // Exact sorting order (front-to-back) - std::sort(dsgraph.lstRenderables.begin(), dsgraph.lstRenderables.end(), [](ISpatial* s1, ISpatial* s2) - { - const float d1 = s1->GetSpatialData().sphere.P.distance_to_sqr(Device.vCameraPosition); - const float d2 = s2->GetSpatialData().sphere.P.distance_to_sqr(Device.vCameraPosition); - return d1 < d2; - }); - - if (ps_r__common_flags.test(RFLAG_ACTOR_SHADOW)) // Actor Shadow (Sun + Light) - g_pGameLevel->pHUD->Render_First(dsgraph.context_id); // R1 shadows - - g_pGameLevel->pHUD->Render_Last(dsgraph.context_id); - - // Determine visibility for dynamic part of scene - u32 uID_LTRACK = 0xffffffff; - if (dsgraph.o.phase == PHASE_NORMAL) - { - uLastLTRACK++; - if (dsgraph.lstRenderables.size()) - uID_LTRACK = uLastLTRACK % dsgraph.lstRenderables.size(); - - // update light-vis for current entity / actor - IGameObject* O = g_pGameLevel->CurrentViewEntity(); - if (O) - { - CROS_impl* R = (CROS_impl*)O->ROS(); - if (R) - R->update(O); - } - } - for (u32 o_it = 0; o_it < dsgraph.lstRenderables.size(); o_it++) - { - ISpatial* spatial = dsgraph.lstRenderables[o_it]; - const auto& entity_pos = spatial->spatial_sector_point(); - spatial->spatial_updatesector(dsgraph.detect_sector(entity_pos)); - const auto sector_id = spatial->GetSpatialData().sector_id; - if (sector_id == IRender_Sector::INVALID_SECTOR_ID) - continue; // disassociated from S/P structure - CSector* sector = dsgraph.Sectors[sector_id]; - - // Filter only not light spatial - if (dsgraph.PortalTraverser.i_marker != sector->r_marker && (spatial->GetSpatialData().type & STYPE_RENDERABLE)) - continue; // inactive (untouched) sector - - if (spatial->GetSpatialData().type & STYPE_RENDERABLE) - { - for (u32 v_it = 0; v_it < sector->r_frustums.size(); v_it++) - { - const CFrustum& view = sector->r_frustums[v_it]; - - if (!view.testSphere_dirty(spatial->GetSpatialData().sphere.P, - spatial->GetSpatialData().sphere.R) /*&& (spatial->spatial.type & STYPE_RENDERABLE)*/) - continue; - // renderable - IRenderable* renderable = spatial->dcast_Renderable(); - if (nullptr == renderable) - { - // It may be an glow - CGlow* glow = dynamic_cast(spatial); - VERIFY(glow); -#ifdef DEBUG - BasicStats.Glows.Begin(); -#endif - L_Glows->add(glow); -#ifdef DEBUG - BasicStats.Glows.End(); -#endif - } - else - { - // Occlusiond - vis_data& v_orig = renderable->GetRenderData().visual->getVisData(); - vis_data v_copy = v_orig; - v_copy.box.xform(renderable->GetRenderData().xform); - BOOL bVisible = HOM.visible(v_copy); - v_orig.accept_frame = v_copy.accept_frame; - memcpy(v_orig.marker, v_copy.marker, sizeof(v_copy.marker)); - v_orig.hom_frame = v_copy.hom_frame; - v_orig.hom_tested = v_copy.hom_tested; - if (!bVisible) - break; // exit loop on frustums - - // update light-vis for selected entity - if (o_it == uID_LTRACK && renderable->renderable_ROS()) - { - // track lighting environment - CROS_impl* T = (CROS_impl*)renderable->renderable_ROS(); - T->update(renderable); - } - - // Rendering - renderable->renderable_Render(dsgraph.context_id, renderable); - } - break; // exit loop on frustums - } - } - else - { - if (ViewBase.testSphere_dirty( - spatial->GetSpatialData().sphere.P, spatial->GetSpatialData().sphere.R)) - { - VERIFY(spatial->GetSpatialData().type & STYPE_LIGHTSOURCE); - // lightsource - light* L = (light*)spatial->dcast_Light(); - VERIFY(L); - if (L->spatial.sector_id != IRender_Sector::INVALID_SECTOR_ID) - { - vis_data& vis = L->get_homdata(); - if (HOM.visible(vis)) - Lights.add_light(L); - } - } - } - } - } - - // Calculate miscellaneous stuff - BasicStats.ShadowsCalc.Begin(); - L_Shadows->calculate(); - BasicStats.ShadowsCalc.End(); - BasicStats.Projectors.Begin(); - L_Projector->calculate(); - BasicStats.Projectors.End(); - } - - // End calc - BasicStats.Culling.End(); -} - -void CRender::RenderMenu() -{ - Target->Begin(); - - if (g_pGamePersistent) - g_pGamePersistent->OnRenderPPUI_main(); // PP-UI - - // find if distortion is needed at all - const bool bPerform = Target->Perform(); - const bool _menu_pp = o.distortion && (g_pGamePersistent ? g_pGamePersistent->OnRenderPPUI_query() : false); - if (bPerform || _menu_pp) - { - Target->phase_distortion(); - - if (g_pGamePersistent) - g_pGamePersistent->OnRenderPPUI_PP(); // PP-UI - - // combination/postprocess - Target->phase_combine(_menu_pp, false); - } -} - -extern u32 g_r; -void CRender::Render() -{ -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("CRender::Render()"); -#endif // _GPA_ENABLED - - if (m_bFirstFrameAfterReset) - { - m_bFirstFrameAfterReset = false; - return; - } - - g_r = 1; - BasicStats.Primitives.Begin(); - // Begin - Target->Begin(); - o.vis_intersect = FALSE; - auto& dsgraph = get_imm_context(); - dsgraph.o.phase = PHASE_NORMAL; - dsgraph.render_hud(); // hud - dsgraph.render_graph(0); // normal level - if (Details) - Details->Render(RCache); // grass / details - dsgraph.render_lods(true, false); // lods - FB - - g_pGamePersistent->Environment().RenderSky(); // sky / sun - g_pGamePersistent->Environment().RenderClouds(); // clouds - - dsgraph.r_pmask(true, false); // disable priority "1" - o.vis_intersect = TRUE; - dsgraph.o.use_hom = false; - L_Dynamic->render(0); // additional light sources - if (Wallmarks) - { - g_r = 0; - Wallmarks->Render(); // wallmarks has priority as normal geometry - } - dsgraph.o.use_hom = true; - o.vis_intersect = FALSE; - dsgraph.o.phase = PHASE_NORMAL; - dsgraph.r_pmask(true, true); // enable priority "0" and "1" - BasicStats.ShadowsRender.Begin(); - if (L_Shadows) - L_Shadows->render(); // ... and shadows - BasicStats.ShadowsRender.End(); - dsgraph.render_lods(false, true); // lods - FB - dsgraph.render_graph(1); // normal level, secondary priority - L_Dynamic->render(1); // additional light sources, secondary priority - dsgraph.PortalTraverser.fade_render(); // faded-portals - dsgraph.render_sorted(); // strict-sorted geoms - BasicStats.Glows.Begin(); - if (L_Glows) - L_Glows->Render(); // glows - BasicStats.Glows.End(); - g_pGamePersistent->Environment().RenderFlares(); // lens-flares - g_pGamePersistent->Environment().RenderLast(); // rain/thunder-bolts - -#ifdef DEBUG - for (int _priority = 0; _priority < 2; ++_priority) - { - for (u32 iPass = 0; iPass < SHADER_PASSES_MAX; ++iPass) - { - R_ASSERT(dsgraph.mapNormalPasses[_priority][iPass].size() == 0); - R_ASSERT(dsgraph.mapMatrixPasses[_priority][iPass].size() == 0); - } - } - -#endif - // Postprocess, if necessary - Target->End(); - if (L_Projector) - L_Projector->finalize(); - - // HUD - BasicStats.Primitives.End(); -} - -void CRender::ApplyBlur2(FVF::TL2uv* pv, u32 size) const -{ - const float dim = float(size); - Fvector2 shift, p0, p1, a0, a1, b0, b1, c0, c1, d0, d1; - p0.set(.5f / dim, .5f / dim); - p1.set((dim + .5f) / dim, (dim + .5f) / dim); - shift.set(.5f / dim, .5f / dim); - a0.add(p0, shift); - a1.add(p1, shift); - b0.sub(p0, shift); - b1.sub(p1, shift); - shift.set(.5f / dim, -.5f / dim); - c0.add(p0, shift); - c1.add(p1, shift); - d0.sub(p0, shift); - d1.sub(p1, shift); - - constexpr u32 C = 0xffffffff; - - // Fill VB - pv->set(0.f, dim, C, a0.x, a1.y, b0.x, b1.y); - pv++; - pv->set(0.f, 0.f, C, a0.x, a0.y, b0.x, b0.y); - pv++; - pv->set(dim, dim, C, a1.x, a1.y, b1.x, b1.y); - pv++; - pv->set(dim, 0.f, C, a1.x, a0.y, b1.x, b0.y); - pv++; - - pv->set(0.f, dim, C, c0.x, c1.y, d0.x, d1.y); - pv++; - pv->set(0.f, 0.f, C, c0.x, c0.y, d0.x, d0.y); - pv++; - pv->set(dim, dim, C, c1.x, c1.y, d1.x, d1.y); - pv++; - pv->set(dim, 0.f, C, c1.x, c0.y, d1.x, d0.y); - pv++; -} - -void CRender::ApplyBlur4(FVF::TL4uv* pv, u32 w, u32 h, float k) const -{ - float _w = float(w); - float _h = float(h); - float kw = (1.f / _w) * k; - float kh = (1.f / _h) * k; - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - u32 _c = 0xffffffff; - - // Fill vertex buffer - pv->p.set(EPS, float(_h + EPS), EPS, 1.f); - pv->color = _c; - pv->uv[0].set(p0.x - kw, p1.y - kh); - pv->uv[1].set(p0.x + kw, p1.y + kh); - pv->uv[2].set(p0.x + kw, p1.y - kh); - pv->uv[3].set(p0.x - kw, p1.y + kh); - pv++; - pv->p.set(EPS, EPS, EPS, 1.f); - pv->color = _c; - pv->uv[0].set(p0.x - kw, p0.y - kh); - pv->uv[1].set(p0.x + kw, p0.y + kh); - pv->uv[2].set(p0.x + kw, p0.y - kh); - pv->uv[3].set(p0.x - kw, p0.y + kh); - pv++; - pv->p.set(float(_w + EPS), float(_h + EPS), EPS, 1.f); - pv->color = _c; - pv->uv[0].set(p1.x - kw, p1.y - kh); - pv->uv[1].set(p1.x + kw, p1.y + kh); - pv->uv[2].set(p1.x + kw, p1.y - kh); - pv->uv[3].set(p1.x - kw, p1.y + kh); - pv++; - pv->p.set(float(_w + EPS), EPS, EPS, 1.f); - pv->color = _c; - pv->uv[0].set(p1.x - kw, p0.y - kh); - pv->uv[1].set(p1.x + kw, p0.y + kh); - pv->uv[2].set(p1.x + kw, p0.y - kh); - pv->uv[3].set(p1.x - kw, p0.y + kh); - pv++; -} - -void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) -{ - D3DXRenderBase::DumpStatistics(font, alert); - HOM.DumpStatistics(font, alert); - Sectors_xrc.DumpStatistics(font, alert); -} diff --git a/src/Layers/xrRenderPC_R1/FStaticRender.h b/src/Layers/xrRenderPC_R1/FStaticRender.h deleted file mode 100644 index a569fb5adf1..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender.h +++ /dev/null @@ -1,200 +0,0 @@ -#pragma once -#include "Layers/xrRender/D3DXRenderBase.h" -#include "Layers/xrRender/PSLibrary.h" -#include "Layers/xrRender/HOM.h" -#include "Layers/xrRender/DetailManager.h" -#include "GlowManager.h" -#include "Layers/xrRender/WallmarksEngine.h" -#include "FStaticRender_Types.h" -#include "FStaticRender_RenderTarget.h" -#include "Layers/xrRender/ModelPool.h" -#include "LightShadows.h" -#include "LightProjector.h" -#include "LightPPA.h" -#include "Layers/xrRender/Light_DB.h" -#include "xrCore/FMesh.hpp" - -class dxRender_Visual; - -class CRender : public D3DXRenderBase -{ -public: - enum - { - PHASE_NORMAL, - PHASE_SMAP, - PHASE_POINT = PHASE_SMAP, - PHASE_SPOT - }; - - struct _options - { - u32 vis_intersect : 1; // config - u32 distortion : 1; // run-time modified - u32 color_mapping : 1; // true if SM 1.4 and higher - u32 disasm : 1; // config - u32 forceskinw : 1; // config - u32 no_detail_textures : 1; // config - u32 ffp : 1; // don't use shaders, only fixed-function pipeline or software processing - u32 new_shader_support : 1; // always disabled for r1 - } o; - -public: - // Sector detection and visibility - IRender_Sector::sector_id_t last_sector_id{IRender_Sector::INVALID_SECTOR_ID}; - Fvector vLastCameraPos; - u32 uLastLTRACK; - xrXRC Sectors_xrc; - CDB::MODEL* rmPortals; - Task* ProcessHOMTask; - CHOM HOM; - - // Global containers - xr_vector SWIs; - xr_vector Shaders; - typedef svector VertexDeclarator; - xr_vector nDC, xDC; - xr_vector nVB, xVB; - xr_vector nIB, xIB; - xr_vector Visuals; - CPSLibrary PSLibrary; - CLight_DB Lights; - CLightR_Manager* L_Dynamic; - CLightShadows* L_Shadows; - CLightProjector* L_Projector; - CGlowManager* L_Glows; - CWallmarksEngine* Wallmarks; - CDetailManager* Details; - CModelPool* Models; - CRenderTarget* Target; // Render-target - - // R1-specific global constants - Fmatrix r1_dlight_tcgen; - light* r1_dlight_light; - float r1_dlight_scale; - cl_light_PR r1_dlight_binder_PR; - cl_light_C r1_dlight_binder_color; - cl_light_XFORM r1_dlight_binder_xform; - - bool m_bMakeAsyncSS; - bool m_bFirstFrameAfterReset; // Determines weather the frame is the first after resetting device. - -private: - // Loading / Unloading - void LoadBuffers(CStreamReader* fs, bool alternative = false); - void LoadVisuals(IReader* fs); - void LoadLights(IReader* fs); - void LoadSectors(IReader* fs); - void LoadSWIs(CStreamReader* fs); - -public: - ShaderElement* rimp_select_sh_static(dxRender_Visual* pVisual, float cdist_sq, u32 phase); - ShaderElement* rimp_select_sh_dynamic(dxRender_Visual* pVisual, float cdist_sq, u32 phase); - VertexElement* getVB_Format(int id, bool alternative = false); - VertexStagingBuffer* getVB(int id, bool alternative = false); - IndexStagingBuffer* getIB(int id, bool alternative = false); - FSlideWindowItem* getSWI(int id); - IRenderVisual* model_CreatePE(LPCSTR name); - void ApplyBlur2(FVF::TL2uv* dest, u32 size) const; - void ApplyBlur4(FVF::TL4uv* dest, u32 w, u32 h, float k) const; - void apply_object(CBackend& cmd_list, IRenderable* O); - -public: - // feature level - virtual GenerationLevel GetGeneration() const override { return IRender::GENERATION_R1; } - virtual BackendAPI GetBackendAPI() const override { return IRender::BackendAPI::D3D9; } - virtual u32 get_dx_level() override { return 0x00090000; } - virtual bool is_sun_static() override { return true; } - // Loading / Unloading - virtual void OnDeviceCreate(pcstr shName) override; - virtual void create() override; - virtual void destroy() override; - virtual void reset_begin() override; - virtual void reset_end() override; - virtual void level_Load(IReader* fs) override; - virtual void level_Unload() override; - - ID3DBaseTexture* texture_load(LPCSTR fname, u32& msize); - virtual HRESULT shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, pcstr pTarget, u32 Flags, - void*& result) override; - - // Information - virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) override; - virtual LPCSTR getShaderPath() override { return "r1" DELIMITER ""; } - virtual ref_shader getShader(int id); - virtual IRenderVisual* getVisual(int id) override; - virtual IRender_Target* getTarget() override; - - // Main - void set_Object(IRenderable* O, u32 phase); - void add_Visual(u32 context_id, IRenderable* root, IRenderVisual* V, Fmatrix& m) override; // add visual leaf (no culling performed at all) - - // wallmarks - virtual void add_StaticWallmark(ref_shader& S, const Fvector& P, float s, CDB::TRI* T, Fvector* V); - virtual void add_StaticWallmark( - IWallMarkArray* pArray, const Fvector& P, float s, CDB::TRI* T, Fvector* V) override; - virtual void add_StaticWallmark(const wm_shader& S, const Fvector& P, float s, CDB::TRI* T, Fvector* V) override; - virtual void clear_static_wallmarks() override; - virtual void add_SkeletonWallmark(intrusive_ptr wm); - virtual void add_SkeletonWallmark( - const Fmatrix* xf, CKinematics* obj, ref_shader& sh, const Fvector& start, const Fvector& dir, float size); - virtual void add_SkeletonWallmark(const Fmatrix* xf, IKinematics* obj, IWallMarkArray* pArray, const Fvector& start, - const Fvector& dir, float size) override; - - // - virtual IBlender* blender_create(CLASS_ID cls); - virtual void blender_destroy(IBlender*&); - - // - virtual IRender_ObjectSpecific* ros_create(IRenderable* parent) override; - virtual void ros_destroy(IRender_ObjectSpecific*&) override; - - // Particle library - virtual CPSLibrary* ps_library() { return &PSLibrary; } - // Lighting - virtual IRender_Light* light_create() override; - virtual IRender_Glow* glow_create() override; - - // Models - virtual IRenderVisual* model_CreateParticles(LPCSTR name) override; - virtual IRender_DetailModel* model_CreateDM(IReader* F); - virtual IRenderVisual* model_Create(LPCSTR name, IReader* data = nullptr) override; - virtual IRenderVisual* model_CreateChild(LPCSTR name, IReader* data) override; - virtual IRenderVisual* model_Duplicate(IRenderVisual* V) override; - virtual void model_Delete(IRenderVisual*& V, bool bDiscard) override; - virtual void model_Delete(IRender_DetailModel*& F); - virtual void model_Logging(bool bEnable) override { Models->Logging(bEnable); } - virtual void models_Prefetch() override; - virtual void models_Clear(bool b_complete) override; - - // Occlusion culling - virtual bool occ_visible(vis_data& V) override; - virtual bool occ_visible(Fbox& B) override; - virtual bool occ_visible(sPoly& P) override; - - // Main - void BeforeRender() override; - - void Calculate() override; - void Render() override; - void RenderMenu() override; - - virtual void Screenshot(ScreenshotMode mode = SM_NORMAL, pcstr name = nullptr) override; - virtual void ScreenshotAsyncBegin() override; - virtual void ScreenshotAsyncEnd(CMemoryWriter& memory_writer) override; - virtual void OnFrame() override; - - void BeforeWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается перед началом рендера мира и пост-эффектов - void AfterWorldRender() override; //--#SM+#-- +SecondVP+ Вызывается после рендера мира и перед UI - - // Render mode - void rmNear(CBackend& cmd_list) override; - void rmFar(CBackend& cmd_list) override; - void rmNormal(CBackend& cmd_list) override; - - // Constructor/destructor/loader - CRender(); - virtual ~CRender(); -}; - -extern CRender RImplementation; diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Blenders.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Blenders.cpp deleted file mode 100644 index a2a2dc38cb8..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Blenders.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "stdafx.h" -#include "Layers/xrRender/blenders/blenderdefault.h" -#include "Layers/xrRender/blenders/blender_default_aref.h" -#include "Layers/xrRender/blenders/blender_vertex.h" -#include "Layers/xrRender/blenders/blender_vertex_aref.h" -#include "Layers/xrRender/blenders/blender_screen_set.h" -#include "Layers/xrRender/blenders/blender_screen_gray.h" -#include "Layers/xrRender/blenders/blender_editor_wire.h" -#include "Layers/xrRender/blenders/blender_editor_selection.h" -#include "Layers/xrRender/blenders/blender_LaEmB.h" -#include "Layers/xrRender/blenders/blender_Lm(EbB).h" -#include "Layers/xrRender/blenders/blender_BmmD.h" -#include "Layers/xrRender/blenders/blender_shadow_world.h" -#include "Layers/xrRender/blenders/blender_blur.h" -#include "Layers/xrRender/blenders/blender_model.h" -#include "Layers/xrRender/blenders/Blender_Model_EbB.h" -#include "Layers/xrRender/blenders/Blender_detail_still.h" -#include "Layers/xrRender/blenders/Blender_tree.h" -#include "Layers/xrRender/blenders/Blender_Particle.h" - -IBlender* CRender::blender_create(CLASS_ID cls) -{ - switch (cls) - { - case B_DEFAULT: return xr_new(); - case B_DEFAULT_AREF: return xr_new(); - case B_VERT: return xr_new(); - case B_VERT_AREF: return xr_new(); - case B_SCREEN_SET: return xr_new(); - case B_SCREEN_GRAY: return xr_new(); - case B_EDITOR_WIRE: return xr_new(); - case B_EDITOR_SEL: return xr_new(); - case B_LaEmB: return xr_new(); - case B_LmEbB: return xr_new(); - case B_BmmD: return xr_new(); - case B_SHADOW_WORLD: return xr_new(); - case B_BLUR: return xr_new(); - case B_MODEL: return xr_new(); - case B_MODEL_EbB: return xr_new(); - case B_DETAIL: return xr_new(); - case B_TREE: return xr_new(); - case B_PARTICLE: return xr_new(); - } - return nullptr; -} - -void CRender::blender_destroy(IBlender*& B) { xr_delete(B); } diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp deleted file mode 100644 index b1a7d3f5c55..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Loader.cpp +++ /dev/null @@ -1,498 +0,0 @@ -#include "stdafx.h" -#include "Layers/xrRender/FBasicVisual.h" -#include "xrCore/FMesh.hpp" -#include "Common/LevelStructure.hpp" -#include "Common/OGF_GContainer_Vertices.hpp" -#include "xrEngine/IGame_Persistent.h" -#include "xrCore/stream_reader.h" - -void CRender::level_Load(IReader* fs) -{ - R_ASSERT(nullptr != g_pGameLevel); - R_ASSERT(!b_loaded); - - // Begin - g_pGamePersistent->LoadBegin(); - Resources->DeferredLoad(TRUE); - IReader* chunk; - - // Shaders - g_pGamePersistent->LoadTitle("st_loading_shaders"); - { - chunk = fs->open_chunk(fsL_SHADERS); - R_ASSERT2(chunk, "Level doesn't builded correctly."); - u32 count = chunk->r_u32(); - Shaders.resize(count); - for (u32 i = 0; i < count; i++) // skip first shader as "reserved" one - { - string512 n_sh, n_tlist; - LPCSTR n = LPCSTR(chunk->pointer()); - chunk->skip_stringZ(); - if (0 == n[0]) - continue; - xr_strcpy(n_sh, n); - pstr delim = strchr(n_sh, '/'); - *delim = 0; - xr_strcpy(n_tlist, delim + 1); - Shaders[i] = Resources->Create(n_sh, n_tlist); - } - chunk->close(); - } - - // Components - L_Shadows = xr_new(); - L_Projector = xr_new(); - L_Glows = xr_new(); - Wallmarks = xr_new(); - Details = xr_new(); - - rmFar(RCache); - rmNormal(RCache); - - if (!GEnv.isDedicatedServer) - { - // VB,IB,SWI - g_pGamePersistent->LoadTitle("st_loading_geometry"); - { - CStreamReader* geom = FS.rs_open("$level$", "level.geom"); - R_ASSERT2(geom, "level.geom"); - LoadBuffers(geom, false); - LoadSWIs(geom); - FS.r_close(geom); - } - - //...and alternate/fast geometry - if (ps_r1_force_geomx) - { - CStreamReader* geom = FS.rs_open("$level$", "level.geomx"); - R_ASSERT2(geom, "level.geomX"); - LoadBuffers(geom, true); - FS.r_close(geom); - } - - // Visuals - g_pGamePersistent->LoadTitle("st_loading_spatial_db"); - chunk = fs->open_chunk(fsL_VISUALS); - LoadVisuals(chunk); - chunk->close(); - - // Details - g_pGamePersistent->LoadTitle("st_loading_details"); - Details->Load(); - } - - // Sectors - g_pGamePersistent->LoadTitle("st_loading_sectors_portals"); - LoadSectors(fs); - - // HOM - HOM.Load(); - - // Lights - g_pGamePersistent->LoadTitle("st_loading_lights"); - LoadLights(fs); - - // End - g_pGamePersistent->LoadEnd(); - b_loaded = TRUE; -} - -void CRender::level_Unload() -{ - if (nullptr == g_pGameLevel) - return; - if (!b_loaded) - return; - - u32 I; - - // HOM - HOM.Unload(); - - //*** Details - Details->Unload(); - - //*** Sectors - // 1. - xr_delete(rmPortals); - last_sector_id = IRender_Sector::INVALID_SECTOR_ID; - vLastCameraPos.set(flt_max, flt_max, flt_max); - uLastLTRACK = 0; - - // 2. - cleanup_contexts(); - - //*** Lights - L_Glows->Unload(); - Lights.Unload(); - - //*** Visuals - for (I = 0; I < Visuals.size(); I++) - { - Visuals[I]->Release(); - xr_delete(Visuals[I]); - } - Visuals.clear(); - - //*** SWI - for (I = 0; I < SWIs.size(); I++) - xr_free(SWIs[I].sw); - SWIs.clear(); - - //*** VB/IB - for (I = 0; I < nVB.size(); I++) - { - nVB[I].Release(); - } - - for (I = 0; I < xVB.size(); I++) - { - xVB[I].Release(); - } - nVB.clear(); - xVB.clear(); - - for (I = 0; I < nIB.size(); I++) - { - nIB[I].Release(); - } - - for (I = 0; I < xIB.size(); I++) - { - xIB[I].Release(); - } - - nIB.clear(); - xIB.clear(); - nDC.clear(); - xDC.clear(); - - //*** Components - xr_delete(Details); - xr_delete(Wallmarks); - xr_delete(L_Glows); - xr_delete(L_Projector); - xr_delete(L_Shadows); - - //*** Shaders - Shaders.clear(); - -#ifdef DEBUG - Resources->DBG_VerifyGeoms(); - Resources->DBG_VerifyTextures(); -#endif - b_loaded = FALSE; -} - -void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) -{ - Resources->Evict(); - - // Vertex buffers - if (base_fs->find_chunk(fsL_VB)) - { - xr_vector& _DC = alternative ? xDC : nDC; - xr_vector& _VB = alternative ? xVB : nVB; - - // Use DX9-style declarators - CStreamReader* fs = base_fs->open_chunk(fsL_VB); - u32 count = fs->r_u32(); - _DC.resize(count); - _VB.resize(count); - - u32 buffer_size = (MAXD3DDECLLENGTH + 1) * sizeof(VertexElement); - VertexElement* dcl = (VertexElement*)xr_alloca(buffer_size); - - for (u32 i = 0; i < count; i++) - { - // decl - - // D3DVERTEXELEMENT9 *dcl = (D3DVERTEXELEMENT9*) fs->pointer(); - - fs->r(dcl, buffer_size); - fs->advance(-(int)buffer_size); - - u32 dcl_len = GetDeclLength(dcl) + 1; - - _DC[i].resize(dcl_len); - fs->r(_DC[i].begin(), dcl_len * sizeof(VertexElement)); - - // count, size - const u32 vCount = fs->r_u32(); - u32 vSize = GetDeclVertexSize(dcl, 0); -#ifndef MASTER_GOLD - Msg("* [Loading VB] %d verts, %d Kb", vCount, (vCount * vSize) / 1024); -#endif - - if (o.ffp) - { - // Replace packed data with unpacked - xr_vector temp; - temp.resize(vCount * vSize); - fs->r(temp.data(), vCount * vSize); - - if (dcl_equal(dcl, r1_decl_lmap)) - { - dcl_len = std::size(r1_decl_lmap_unpacked); - _DC[i].resize(dcl_len); - CopyMemory(_DC[i].begin(), r1_decl_lmap_unpacked, dcl_len * sizeof(VertexElement)); - - vSize = GetDeclVertexSize(r1_decl_lmap_unpacked, 0); - _VB[i].Create(vCount * vSize); - auto* data = static_cast(_VB[i].Map()); - const auto* packedData = (r1v_lmap*)temp.data(); - for (size_t i = 0; i < vCount; ++i) - data[i] = packedData[i]; - } - else if (dcl_equal(dcl, r1_decl_vert)) - { - dcl_len = std::size(r1_decl_vert_unpacked); - _DC[i].resize(dcl_len); - CopyMemory(_DC[i].begin(), r1_decl_vert_unpacked, dcl_len * sizeof(VertexElement)); - - vSize = GetDeclVertexSize(r1_decl_vert_unpacked, 0); - _VB[i].Create(vCount * vSize); - auto* data = static_cast(_VB[i].Map()); - const auto* packedData = (r1v_vert*)temp.data(); - for (size_t i = 0; i < vCount; ++i) - data[i] = packedData[i]; - } - /*else if (dcl_equal(dcl, mu_model_decl)) - { - dcl_len = std::size(mu_model_decl_unpacked); - _DC[i].resize(dcl_len); - CopyMemory(_DC[i].begin(), mu_model_decl_unpacked, dcl_len * sizeof(VertexElement)); - - vSize = GetDeclVertexSize(mu_model_decl_unpacked, 0); - _VB[i].Create(vCount * vSize, true); - auto* data = static_cast(_VB[i].Map()); - const auto* packedData = (mu_model_vert*)temp.data(); - for (size_t i = 0; i < vCount; ++i) - data[i] = packedData[i]; - }*/ - else - { - _VB[i].Create(vCount * vSize); - u8* pData = static_cast(_VB[i].Map()); - CopyMemory(pData, temp.data(), vCount * vSize); - } - - _VB[i].Unmap(true); // upload vertex data - } - else - { - // Create and fill - _VB[i].Create(vCount * vSize); - u8* pData = static_cast(_VB[i].Map()); - fs->r(pData, vCount * vSize); - _VB[i].Unmap(true); // upload vertex data - } - } - fs->close(); - } - else - { - FATAL("DX7-style FVFs unsupported"); - } - - // Index buffers - if (base_fs->find_chunk(fsL_IB)) - { - xr_vector& _IB = alternative ? xIB : nIB; - - CStreamReader* fs = base_fs->open_chunk(fsL_IB); - u32 count = fs->r_u32(); - _IB.resize(count); - for (u32 i = 0; i < count; i++) - { - u32 iCount = fs->r_u32(); -#ifndef MASTER_GOLD - Msg("* [Loading IB] %d indices, %d Kb", iCount, (iCount * 2) / 1024); -#endif - - // Create and fill - _IB[i].Create(iCount * 2); - u8* pData = static_cast(_IB[i].Map()); - // CopyMemory (pData,fs->pointer(),iCount*2); - fs->r(pData, iCount * 2); - _IB[i].Unmap(true); // upload index data - - // fs->advance (iCount*2); - } - fs->close(); - } -} - -void CRender::LoadVisuals(IReader* fs) -{ - IReader* chunk = nullptr; - u32 index = 0; - dxRender_Visual* V = nullptr; - ogf_header H; - - while ((chunk = fs->open_chunk(index)) != nullptr) - { - chunk->r_chunk_safe(OGF_HEADER, &H, sizeof(H)); - V = Models->Instance_Create(H.type); - V->Load(nullptr, chunk, 0); - Visuals.push_back(V); - - chunk->close(); - index++; - } -} - -void CRender::LoadLights(IReader* fs) -{ - // lights - Lights.Load(fs); - - // glows - IReader* chunk = fs->open_chunk(fsL_GLOWS); - R_ASSERT(chunk && "Can't find glows"); - L_Glows->Load(chunk); - chunk->close(); -} - -void CRender::LoadSectors(IReader* fs) -{ - // allocate memory for portals - u32 size = fs->find_chunk(fsL_PORTALS); - R_ASSERT(0 == size % sizeof(CPortal::level_portal_data_t)); - const u32 portals_count = size / sizeof(CPortal::level_portal_data_t); - xr_vector portals_data{portals_count}; - - // load sectors - xr_vector sectors_data; - IReader* S = fs->open_chunk(fsL_SECTORS); - for (u32 i = 0;; i++) - { - IReader* P = S->open_chunk(i); - if (!P) - break; - - auto& sector_data = sectors_data.emplace_back(); - { - u32 size = P->find_chunk(fsP_Portals); - R_ASSERT(0 == (size & 1)); - u32 portals_in_sector = size / sizeof(u16); - - sector_data.portals_id.reserve(portals_in_sector); - while (portals_in_sector) - { - const u16 ID = P->r_u16(); - sector_data.portals_id.emplace_back(ID); - --portals_in_sector; - } - - size = P->find_chunk(fsP_Root); - R_ASSERT(size == 4); - sector_data.root_id = P->r_u32(); - } - P->close(); - } - S->close(); - - // load portals - if (portals_count) - { - bool do_rebuild = true; - const bool use_cache = !strstr(Core.Params, "-no_cdb_cache"); - const bool checkCrc32 = !strstr(Core.Params, "-skip_cdb_cache_crc32_check"); - - string_path fName; - strconcat(fName, "cdb_cache" DELIMITER, FS.get_path("$level$")->m_Add, "portals.bin"); - FS.update_path(fName, "$app_data_root$", fName); - - // build portal model - rmPortals = xr_new(); - rmPortals->set_version(fs->get_age()); - if (use_cache && FS.exist(fName) && rmPortals->deserialize(fName, checkCrc32)) - { -#ifndef MASTER_GOLD - Msg("* Loaded portals cache (%s)...", fName); -#endif - do_rebuild = false; - } - else - { -#ifndef MASTER_GOLD - Msg("* Portals cache for '%s' was not loaded. " - "Building the model from scratch..", fName); -#endif - } - - CDB::Collector CL; - fs->find_chunk(fsL_PORTALS); - for (u32 i = 0; i < portals_count; i++) - { - auto& P = portals_data[i]; - fs->r(&P, sizeof(P)); - - if (do_rebuild) - { - for (u32 j = 2; j < P.vertices.size(); j++) - CL.add_face_packed_D(P.vertices[0], P.vertices[j - 1], P.vertices[j], u32(i)); - } - } - - if (do_rebuild) - { - if (CL.getTS() < 2) - { - Fvector v1, v2, v3; - v1.set(-20000.f, -20000.f, -20000.f); - v2.set(-20001.f, -20001.f, -20001.f); - v3.set(-20002.f, -20002.f, -20002.f); - CL.add_face_packed_D(v1, v2, v3, 0); - } - rmPortals->build(CL.getV(), int(CL.getVS()), CL.getT(), int(CL.getTS())); - if (use_cache) - rmPortals->serialize(fName); - } - } - else - { - rmPortals = nullptr; - } - - auto& dsgraph = get_imm_context(); - dsgraph.reset(); - dsgraph.load(sectors_data, portals_data); - - last_sector_id = IRender_Sector::INVALID_SECTOR_ID; -} - -void CRender::LoadSWIs(CStreamReader* base_fs) -{ - // allocate memory for portals - if (base_fs->find_chunk(fsL_SWIS)) - { - CStreamReader* fs = base_fs->open_chunk(fsL_SWIS); - u32 item_count = fs->r_u32(); - - xr_vector::iterator it = SWIs.begin(); - xr_vector::iterator it_e = SWIs.end(); - - for (; it != it_e; ++it) - xr_free((*it).sw); - - SWIs.clear(); - - SWIs.resize(item_count); - for (u32 c = 0; c < item_count; c++) - { - FSlideWindowItem& swi = SWIs[c]; - swi.reserved[0] = fs->r_u32(); - swi.reserved[1] = fs->r_u32(); - swi.reserved[2] = fs->r_u32(); - swi.reserved[3] = fs->r_u32(); - swi.count = fs->r_u32(); - VERIFY(NULL == swi.sw); - swi.sw = xr_alloc(swi.count); - fs->r(swi.sw, sizeof(FSlideWindow) * swi.count); - } - - fs->close(); - } -} diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.cpp deleted file mode 100644 index 1514aa46371..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.cpp +++ /dev/null @@ -1,497 +0,0 @@ -#include "stdafx.h" -#include "FStaticRender_RenderTarget.h" - -#include "Layers/xrRender/blenders/Blender_Blur.h" -#include "Layers/xrRender/blenders/Blender_Screen_GRAY.h" - -#include "xrEngine/IGame_Persistent.h" - -CRenderTarget::CRenderTarget() - : im_noise_time(1.f / 100.0f), - param_noise_scale(1.f), - param_noise_fps(25.f), - param_color_base(color_rgba(127, 127, 127, 0)), - param_color_gray(color_rgba(85, 85, 85, 0)) -{ - curWidth = Device.dwWidth; - curHeight = Device.dwHeight; - - // Select mode to operate in - const float amount = ps_r__Supersample ? float(ps_r__Supersample) : 1; - const float scale = _sqrt(amount); - rtWidth = clampr(iFloor(scale * Device.dwWidth + .5f), 128, 2048); - rtHeight = clampr(iFloor(scale * Device.dwHeight + .5f), 128, 2048); - while (rtWidth % 2) - rtWidth--; - while (rtHeight % 2) - rtHeight--; - Msg("* SSample: %dx%d", rtWidth, rtHeight); - - // Bufferts - rt_Base.resize(HW.BackBufferCount); - for (u32 i = 0; i < HW.BackBufferCount; i++) - { - string32 temp; - xr_sprintf(temp, "%s%d", r1_RT_base, i); - rt_Base[i].create(temp, curWidth, curHeight, HW.Caps.fTarget, 1, { CRT::CreateBase }); - } - rt_Base_Depth.create(r1_RT_base_depth, curWidth, curHeight, HW.Caps.fDepth, 1, { CRT::CreateBase }); - - rt_Generic.create(r1_RT_generic, rtWidth, rtHeight, HW.Caps.fTarget); - rt_distort.create(rt_RT_distort, rtWidth, rtHeight, HW.Caps.fTarget); - if (RImplementation.o.color_mapping) - { - //rt_color_map.create(rt_RT_color_map, rtWidth, rtHeight, HW.Caps.fTarget); - rt_color_map.create(rt_RT_color_map, curWidth, curHeight, HW.Caps.fTarget); - } - // RImplementation.o.color_mapping = RT_color_map->valid(); - - if (rtHeight != Device.dwHeight || rtWidth != Device.dwWidth) - { - rt_Depth.create(r1_RT_depth, rtWidth, rtHeight, HW.Caps.fDepth, 0, { CRT::CreateSurface }); - } - else - { - rt_Depth = rt_Base_Depth; - } - - // Temp ZB, used by some of the shadowing code - rt_temp_zb.create(rt_RT_temp_zb, 512, 512, HW.Caps.fDepth, 0, { CRT::CreateSurface }); - - // Igor: TMP - // Create an RT for online screenshot makining - rt_async_ss.create(r1_RT_async_ss, rtWidth, rtHeight, HW.Caps.fTarget, 0, { CRT::CreateSurface }); - - // Shaders and stream - if (RImplementation.o.ffp) - { - g_postprocess[0].create(FVF::F_TL, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); - g_postprocess[1].create(FVF::F_TL2uv, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); - s_set.create("effects\\screen_set", r1_RT_generic); - s_gray.create("effects\\screen_gray", r1_RT_generic); - if (!s_gray) - { - CBlender_Screen_GRAY b; - s_gray.create(&b, "effects\\screen_gray", r1_RT_generic); - } - s_blend.create("effects\\screen_blend", r1_RT_generic); - s_duality.create("effects\\blur", r1_RT_generic "," r1_RT_generic); - if (!s_duality) - { - CBlender_Blur b; - s_duality.create(&b, "effects\\blur", r1_RT_generic "," r1_RT_generic); - } - s_noise.create("effects\\screen_noise", "fx\\fx_noise2"); - } - else - { - s_postprocess[0].create("postprocess"); - if (RImplementation.o.distortion) - s_postprocess_D[0].create("postprocess_d"); - - if (RImplementation.o.color_mapping) - { - s_postprocess[1].create("postprocess_cm"); - if (RImplementation.o.distortion) - s_postprocess_D[1].create("postprocess_dcm"); - if (!s_postprocess[1] || !s_postprocess_D[1]) - { - Log("~ Color mapping disabled due to lack of one shader or both shaders"); - s_postprocess[1].destroy(); - s_postprocess_D[1].destroy(); - rt_color_map->destroy(); - RImplementation.o.color_mapping = FALSE; - } - } - g_postprocess[0].create(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX3, - RImplementation.Vertex.Buffer(), RImplementation.QuadIB); - } - - bAvailable = rt_Generic->valid() && rt_distort->valid(); - Msg("* SSample: %s", bAvailable ? "enabled" : "disabled"); -} - -void CRenderTarget::calc_tc_noise(Fvector2& p0, Fvector2& p1) -{ - //. CTexture* T = RCache.get_ActiveTexture (2); - //. VERIFY2 (T, "Texture #3 in noise shader should be setted up"); - //. u32 tw = iCeil(float(T->get_Width ())*param_noise_scale+EPS_S); - //. u32 th = iCeil(float(T->get_Height ())*param_noise_scale+EPS_S); - const u32 tw = iCeil(256 * param_noise_scale + EPS_S); - const u32 th = iCeil(256 * param_noise_scale + EPS_S); - VERIFY2(tw && th, "Noise scale can't be zero in any way"); - //. if (bDebug) Msg ("%d,%d,%f",tw,th,param_noise_scale); - - // calculate shift from FPSes - im_noise_time -= Device.fTimeDelta; - if (im_noise_time < 0) - { - im_noise_shift_w = ::Random.randI(tw ? tw : 1); - im_noise_shift_h = ::Random.randI(th ? th : 1); - const float fps_time = 1 / param_noise_fps; - while (im_noise_time < 0) - im_noise_time += fps_time; - } - - const u32 shift_w = im_noise_shift_w; - const u32 shift_h = im_noise_shift_h; - const float start_u = (float(shift_w) + .5f) / (tw); - const float start_v = (float(shift_h) + .5f) / (th); - const u32 _w = Device.dwWidth; - const u32 _h = Device.dwHeight; - const u32 cnt_w = _w / tw; - const u32 cnt_h = _h / th; - const float end_u = start_u + float(cnt_w) + 1; - const float end_v = start_v + float(cnt_h) + 1; - - p0.set(start_u, start_v); - p1.set(end_u, end_v); -} - -void CRenderTarget::calc_tc_duality_ss(Fvector2& r0, Fvector2& r1, Fvector2& l0, Fvector2& l1) -{ - // Calculate ordinaty TCs from blur and SS - const float tw = float(rtWidth); - const float th = float(rtHeight); - if (rtHeight != Device.dwHeight) - param_blur = 1.f; - Fvector2 shift, p0, p1; - shift.set(.5f / tw, .5f / th); - shift.mul(param_blur); - p0.set(.5f / tw, .5f / th).add(shift); - p1.set((tw + .5f) / tw, (th + .5f) / th).add(shift); - - // Calculate Duality TC - const float shift_u = param_duality_h * .5f; - const float shift_v = param_duality_v * .5f; - - r0.set(p0.x, p0.y); - r1.set(p1.x - shift_u, p1.y - shift_v); - l0.set(p0.x + shift_u, p0.y + shift_v); - l1.set(p1.x, p1.y); -} - -bool CRenderTarget::NeedColorMapping() const -{ - return RImplementation.o.color_mapping && param_color_map_influence > 0.001f; -} - -bool CRenderTarget::NeedPostProcess() const -{ - const bool _blur = param_blur > 0.001f; - const bool _gray = param_gray > 0.001f; - const bool _noise = param_noise > 0.001f; - const bool _dual = param_duality_h > 0.001f || param_duality_v > 0.001f; - - const bool _menu_pp = g_pGamePersistent ? g_pGamePersistent->OnRenderPPUI_query() : false; - - const bool _cmap = NeedColorMapping(); - - bool _cbase = false; - { - int _r = color_get_R(param_color_base); - _r = _abs(_r - int(0x7f)); - int _g = color_get_G(param_color_base); - _g = _abs(_g - int(0x7f)); - int _b = color_get_B(param_color_base); - _b = _abs(_b - int(0x7f)); - if (_r > 2 || _g > 2 || _b > 2) - _cbase = true; - } - bool _cadd = false; - { - const int _r = _abs((int)(param_color_add.x * 255)); - const int _g = _abs((int)(param_color_add.y * 255)); - const int _b = _abs((int)(param_color_add.z * 255)); - if (_r > 2 || _g > 2 || _b > 2) - _cadd = true; - } - return _blur || _gray || _noise || _dual || _cbase || _cadd || _cmap || _menu_pp; -} - -bool CRenderTarget::Perform() const -{ - return Available() && ((RImplementation.m_bMakeAsyncSS) || NeedPostProcess() || (ps_r__Supersample > 1) || - (frame_distort == (Device.dwFrame - 1))); -} - -void CRenderTarget::Begin() -{ - if (!Perform()) - { - // Base RT - RCache.set_RT(get_base_rt()); - RCache.set_ZB(get_base_zb()); - curWidth = Device.dwWidth; - curHeight = Device.dwHeight; - } - else - { - // Our - RCache.set_RT(rt_Generic->pRT); - RCache.set_ZB(rt_Depth->pRT); - curWidth = rtWidth; - curHeight = rtHeight; - } - Device.Clear(); -} - -struct TL_2c3uv -{ - Fvector4 p; - u32 color0; - u32 color1; - Fvector2 uv[3]; - - void set(float x, float y, u32 c0, u32 c1, float u0, float v0, float u1, float v1, float u2, float v2) - { - p.set(x, y, EPS_S, 1.f); - color0 = c0; - color1 = c1; - uv[0].set(u0, v0); - uv[1].set(u1, v1); - uv[2].set(u2, v2); - } -}; - -void CRenderTarget::DoAsyncScreenshot() const -{ - // Igor: screenshot will not have postprocess applied. - // TODO: fox that later - if (RImplementation.m_bMakeAsyncSS) - { - HRESULT hr; - - IDirect3DSurface9* pFBSrc = get_base_rt(); - // Don't addref, no need to release. - // ID3DTexture2D *pTex = RT->pSurface; - - // hr = pTex->GetSurfaceLevel(0, &pFBSrc); - - // SHould be async function - hr = HW.pDevice->GetRenderTargetData(pFBSrc, rt_async_ss->pRT); - - // pFBSrc->Release(); - - RImplementation.m_bMakeAsyncSS = false; - } -} - -void CRenderTarget::End() -{ - auto& dsgraph = RImplementation.get_imm_context(); - - // find if distortion is needed at all - const bool bPerform = Perform(); - bool bDistort = RImplementation.o.distortion; - const bool bCMap = NeedColorMapping(); - - if (dsgraph.mapDistort.empty()) - bDistort = FALSE; - if (bDistort) - { - phase_distortion(); - - dsgraph.render_distort(); - dsgraph.mapDistort.clear(); - } - - // combination/postprocess - RCache.set_RT(get_base_rt()); - RCache.set_ZB(get_base_zb()); - curWidth = Device.dwWidth; - curHeight = Device.dwHeight; - - if (!bPerform) - return; - - phase_combine(bDistort, bCMap); -} - -void CRenderTarget::phase_combine(bool bDistort, bool bCMap) -{ - RCache.set_RT(get_base_rt()); - RCache.set_ZB(get_base_zb()); - curWidth = Device.dwWidth; - curHeight = Device.dwHeight; - - const int gblend = clampr(iFloor((1 - param_gray) * 255.f), 0, 255); - const int nblend = clampr(iFloor((1 - param_noise) * 255.f), 0, 255); - const u32 p_color = subst_alpha(param_color_base, nblend); - const u32 p_gray = subst_alpha(param_color_gray, gblend); - Fvector p_brightness = param_color_add; - - Fvector2 n0, n1, r0, r1, l0, l1; - calc_tc_duality_ss(r0, r1, l0, l1); - calc_tc_noise(n0, n1); - - if (RImplementation.o.ffp) - { - const u32 p_alpha = color_rgba(255, 255, 255, gblend); - phase_combine_fpp(p_color, p_gray, p_alpha, n0, n1, r0, r1, l0, l1); - return; - } - - // Draw full-screen quad textured with our scene image - u32 Offset; - const float _w = float(Device.dwWidth); - const float _h = float(Device.dwHeight); - - // Fill vertex buffer - const float du = ps_r1_pps_u, dv = ps_r1_pps_v; - TL_2c3uv* pv = (TL_2c3uv*)RImplementation.Vertex.Lock(4, g_postprocess[0].stride(), Offset); - pv->set(du + 0, dv + float(_h), p_color, p_gray, r0.x, r1.y, l0.x, l1.y, n0.x, n1.y); - pv++; - pv->set(du + 0, dv + 0, p_color, p_gray, r0.x, r0.y, l0.x, l0.y, n0.x, n0.y); - pv++; - pv->set(du + float(_w), dv + float(_h), p_color, p_gray, r1.x, r1.y, l1.x, l1.y, n1.x, n1.y); - pv++; - pv->set(du + float(_w), dv + 0, p_color, p_gray, r1.x, r0.y, l1.x, l0.y, n1.x, n0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_postprocess[0].stride()); - - static shared_str s_colormap = "c_colormap"; - if (bCMap) - { - RCache.set_RT(rt_color_map->pRT); - - // Prepare colormapped buffer - RCache.set_Element(bDistort ? s_postprocess_D[1]->E[4] : s_postprocess[1]->E[4]); - RCache.set_Geometry(g_postprocess[0]); - RCache.set_c(s_colormap, param_color_map_influence, param_color_map_interpolate, 0.0f, 0.0f); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - RCache.set_RT(get_base_rt()); - // return; - } - - // Element 0 for for normal post-process - // Element 4 for color map post-process - // int iShaderElement = bCMap ? 4 : 0; - // RCache.set_Element (bDistort ? s_postprocess_D->E[iShaderElement] : s_postprocess->E[iShaderElement]); - - RCache.set_Shader(bDistort ? s_postprocess_D[bCMap] : s_postprocess[bCMap]); - - // RCache.set_Shader (bDistort ? s_postprocess_D : s_postprocess); - - // Actual rendering - static shared_str s_brightness = "c_brightness"; - RCache.set_c(s_brightness, p_brightness.x, p_brightness.y, p_brightness.z, 0.0f); - RCache.set_c(s_colormap, param_color_map_influence, param_color_map_interpolate, 0.0f, 0.0f); - RCache.set_Geometry(g_postprocess[0]); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); -} - -void CRenderTarget::phase_combine_fpp(u32 p_color, u32 p_gray, u32 p_alpha, - Fvector2 n0, Fvector2 n1, Fvector2 r0, Fvector2 r1, Fvector2 l0, Fvector2 l1) -{ - u32 Offset; - const float _w = float(Device.dwWidth); - const float _h = float(Device.dwHeight); - - // Fill vertex buffer - auto pv = static_cast(RImplementation.Vertex.Lock(12, g_postprocess[0].stride(), Offset)); - pv->set(0, float(_h), EPS_S, 1.f, p_gray, r0.x, l1.y); - pv++; - pv->set(0, 0, EPS_S, 1.f, p_gray, r0.x, r0.y); - pv++; - pv->set(float(_w), float(_h), EPS_S, 1.f, p_gray, l1.x, l1.y); - pv++; - pv->set(float(_w), 0, EPS_S, 1.f, p_gray, l1.x, r0.y); - pv++; - - pv->set(0, float(_h), EPS_S, 1.f, p_color, r0.x, l1.y); - pv++; - pv->set(0, 0, EPS_S, 1.f, p_color, r0.x, r0.y); - pv++; - pv->set(float(_w), float(_h), EPS_S, 1.f, p_color, l1.x, l1.y); - pv++; - pv->set(float(_w), 0, EPS_S, 1.f, p_color, l1.x, r0.y); - pv++; - - pv->set(0, float(_h), EPS_S, 1.f, p_alpha, r0.x, l1.y); - pv++; - pv->set(0, 0, EPS_S, 1.f, p_alpha, r0.x, r0.y); - pv++; - pv->set(float(_w), float(_h), EPS_S, 1.f, p_alpha, l1.x, l1.y); - pv++; - pv->set(float(_w), 0, EPS_S, 1.f, p_alpha, l1.x, r0.y); - pv++; - RImplementation.Vertex.Unlock(12, g_postprocess[0].stride()); - - // Actual rendering - if (param_duality_h > 0.001f || param_duality_v > 0.001f) - { - constexpr u32 C = 0xffffffff; - - auto pv2 = static_cast(RImplementation.Vertex.Lock(4, g_postprocess[1].stride(), Offset)); - pv2->set(0, float(_h), EPS_S, 1.f, C, r0.x, r1.y, l0.x, l1.y); - pv2++; - pv2->set(0, 0, EPS_S, 1.f, C, r0.x, r0.y, l0.x, l0.y); - pv2++; - pv2->set(float(_w), float(_h), EPS_S, 1.f, C, r1.x, r1.y, l1.x, l1.y); - pv2++; - pv2->set(float(_w), 0, EPS_S, 1.f, C, r1.x, r0.y, l1.x, l0.y); - pv2++; - RImplementation.Vertex.Unlock(4, g_postprocess[1].stride()); - - // Draw Noise - RCache.set_Shader(s_duality); - RCache.set_Geometry(g_postprocess[1]); - RCache.Render(D3DPT_TRIANGLELIST, Offset + 0, 0, 4, 0, 2); - } - else - { - if (param_gray > 0.001f) - { - // Draw GRAY - RCache.set_Shader(s_gray); - RCache.set_Geometry(g_postprocess[0]); - RCache.Render(D3DPT_TRIANGLELIST, Offset + 0, 0, 4, 0, 2); - - if (param_gray < 0.999f) - { - // Blend COLOR - RCache.set_Shader(s_blend); - RCache.set_Geometry(g_postprocess[0]); - RCache.Render(D3DPT_TRIANGLELIST, Offset + 4, 0, 4, 0, 2); - } - } - else - { - // Draw COLOR - RCache.set_Shader(s_set); - RCache.set_Geometry(g_postprocess[0]); - RCache.Render(D3DPT_TRIANGLELIST, Offset + 8, 0, 4, 0, 2); - } - } - - if (param_noise > 0.001f) - { - auto* pv2 = static_cast(RImplementation.Vertex.Lock(4, g_postprocess[0].stride(), Offset)); - pv2->set(0, float(_h), EPS_S, 1.f, p_color, n0.x, n1.y); - pv2++; - pv2->set(0, 0, EPS_S, 1.f, p_color, n0.x, n0.y); - pv2++; - pv2->set(float(_w), float(_h), EPS_S, 1.f, p_color, n1.x, n1.y); - pv2++; - pv2->set(float(_w), 0, EPS_S, 1.f, p_color, n1.x, n0.y); - pv2++; - RImplementation.Vertex.Unlock(4, g_postprocess[0].stride()); - - // Draw Noise - RCache.set_Shader(s_noise); - RCache.set_Geometry(g_postprocess[0]); - RCache.Render(D3DPT_TRIANGLELIST, Offset + 0, 0, 4, 0, 2); - } -} - -void CRenderTarget::phase_distortion() -{ - frame_distort = Device.dwFrame; - RCache.set_RT(rt_distort->pRT); - RCache.set_ZB(rt_Depth->pRT); - RCache.set_CullMode(CULL_CCW); - RCache.set_ColorWriteEnable(); - RCache.ClearRT(rt_distort, color_rgba(127, 127, 127, 127)); -} diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.h b/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.h deleted file mode 100644 index 6ae1444044a..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_RenderTarget.h +++ /dev/null @@ -1,126 +0,0 @@ -#pragma once - -#include "Layers/xrRender/ColorMapManager.h" - -class CRenderTarget : public IRender_Target -{ -private: - bool bAvailable; - u32 rtWidth; - u32 rtHeight; - - u32 curWidth; - u32 curHeight; - -public: - // Base targets - xr_vector rt_Base; - ref_rt rt_Base_Depth; - -private: - ref_rt rt_Generic; - ref_rt rt_Depth; - - ref_rt rt_color_map; - ref_rt rt_distort; - - // FFP postprocessing - ref_shader s_set; - ref_shader s_gray; - ref_shader s_blend; - ref_shader s_duality; - ref_shader s_noise; - - // Can't implement in a single pass of a shader since - // should be compiled only for the hardware that supports it. - ref_shader s_postprocess[2]{}; // Igor: 0 - plain, 1 - colormapped - ref_shader s_postprocess_D[2]{}; // Igor: 0 - plain, 1 - colormapped - ref_geom g_postprocess[2]{}; - - float im_noise_time; - u32 im_noise_shift_w{}; - u32 im_noise_shift_h{}; - - float param_blur{}; - float param_gray{}; - float param_duality_h{}; - float param_duality_v{}; - float param_noise{}; - float param_noise_scale; - float param_noise_fps; - - // Color mapping - float param_color_map_influence{}; - float param_color_map_interpolate{}; - ColorMapManager color_map_manager; - - u32 param_color_base; - u32 param_color_gray; - Fvector param_color_add{}; - - u32 frame_distort; - -public: - ref_rt rt_temp_zb; - - // Igor: for async screenshots - ref_rt rt_async_ss; // 32bit (r,g,b,a) is situated in the system memory - -private: - [[nodiscard]] - bool NeedColorMapping() const; - - [[nodiscard]] - bool NeedPostProcess() const; - - [[nodiscard]] - bool Available() const { return bAvailable; } - - void calc_tc_noise(Fvector2& p0, Fvector2& p1); - void calc_tc_duality_ss(Fvector2& r0, Fvector2& r1, Fvector2& l0, Fvector2& l1); - -public: - CRenderTarget(); - - void Begin(); - void End(); - - void DoAsyncScreenshot() const; - [[nodiscard]] - bool Perform() const; - - [[nodiscard]] - ID3DRenderTargetView* get_base_rt() const { return rt_Base[HW.CurrentBackBuffer]->pRT; } - [[nodiscard]] - ID3DDepthStencilView* get_base_zb() const { return rt_Base_Depth->pRT; } - - void set_blur(float f) override { param_blur = f; } - void set_gray(float f) override { param_gray = f; } - void set_duality_h(float f) override { param_duality_h = _abs(f); } - void set_duality_v(float f) override { param_duality_v = _abs(f); } - void set_noise(float f) override { param_noise = f; } - void set_noise_scale(float f) override { param_noise_scale = f; } - void set_noise_fps(float f) override { param_noise_fps = _abs(f) + EPS_S; } - void set_color_base(u32 f) override { param_color_base = f; } - void set_color_gray(u32 f) override { param_color_gray = f; } - void set_color_add(const Fvector& f) override { param_color_add = f; } - void set_cm_imfluence(float f) override { param_color_map_influence = f; } - void set_cm_interpolate(float f) override { param_color_map_interpolate = f; } - - void set_cm_textures(const shared_str& tex0, const shared_str& tex1) override - { - color_map_manager.SetTextures(tex0, tex1); - } - - u32 get_width(CBackend& cmd_list) override { return curWidth; } - u32 get_height(CBackend& cmd_list) override { return curHeight; } - u32 get_rtwidth() const { return rtWidth; } - u32 get_rtheight() const { return rtHeight; } - - void phase_distortion(); - void phase_combine(bool bDistort, bool bCMap); - -private: - void phase_combine_fpp(u32 p_color, u32 p_gray, u32 p_alpha, - Fvector2 n0, Fvector2 n1, Fvector2 r0, Fvector2 r1, Fvector2 l0, Fvector2 l1); -}; diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Shaders.cpp b/src/Layers/xrRenderPC_R1/FStaticRender_Shaders.cpp deleted file mode 100644 index 3869e0f34ab..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Shaders.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include "stdafx.h" -#include "FStaticRender.h" -#include "Layers/xrRender/ShaderResourceTraits.h" -#include "Layers/xrRenderDX9/dx9shader_utils.h" -#include "xrCore/FileCRC32.h" - -template -static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, - T*& result, bool const disasm) -{ - HRESULT _hr = ShaderTypeTraits::CreateHWShader(buffer, buffer_size, result->sh); - if (FAILED(_hr)) - { - Log("! Shader: ", file_name); - Msg("! CreateHWShader hr == 0x%08x", _hr); - return E_FAIL; - } - - LPCVOID data = nullptr; - - _hr = FindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); - - if (SUCCEEDED(_hr) && data) - { - // Parse constant table data - result->constants.parse(const_cast(data), ShaderTypeTraits::GetShaderDest()); - } - else - Msg("! D3DXFindShaderComment %s hr == 0x%08x", file_name, _hr); - - if (disasm) - { - IShaderBlob* blob = nullptr; - DisassembleShader(buffer, buffer_size, FALSE, nullptr, &blob); - if (!blob) - return _hr; - - string_path dname; - strconcat(sizeof(dname), dname, "disasm" DELIMITER, file_name, ('v' == pTarget[0]) ? ".vs" : ".ps"); - IWriter* W = FS.w_open("$app_data_root$", dname); - W->w(blob->GetBufferPointer(), blob->GetBufferSize()); - FS.w_close(W); - _RELEASE(blob); - } - - return _hr; -} - -inline HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, - void*& result, bool const disasm) -{ - if (pTarget[0] == 'p') - return create_shader(pTarget, buffer, buffer_size, file_name, (SPS*&)result, disasm); - - if (pTarget[0] == 'v') - return create_shader(pTarget, buffer, buffer_size, file_name, (SVS*&)result, disasm); - - NODEFAULT; - return E_FAIL; -} - -HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, pcstr pTarget, u32 Flags, void*& result) -{ - SHADER_MACRO defines[128]; - int def_it = 0; - - char sh_name[MAX_PATH] = ""; - u32 len = 0; - // options - if (o.forceskinw) - { - defines[def_it].Name = "SKIN_COLOR"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.forceskinw); - ++len; - - // skinning - if (m_skinning < 0) - { - defines[def_it].Name = "SKIN_NONE"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (0 == m_skinning) - { - defines[def_it].Name = "SKIN_0"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(0 == m_skinning); - ++len; - - if (1 == m_skinning) - { - defines[def_it].Name = "SKIN_1"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(1 == m_skinning); - ++len; - - if (2 == m_skinning) - { - defines[def_it].Name = "SKIN_2"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(2 == m_skinning); - ++len; - - if (3 == m_skinning) - { - defines[def_it].Name = "SKIN_3"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(3 == m_skinning); - ++len; - - if (4 == m_skinning) - { - defines[def_it].Name = "SKIN_4"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(4 == m_skinning); - ++len; - - sh_name[len] = '\0'; - -#ifndef USE_D3DX - // Required for compatibility with D3DCompile() - defines[def_it].Name = "point"; - defines[def_it].Definition = "__pnt__"; - def_it++; -#endif - - // finish - defines[def_it].Name = nullptr; - defines[def_it].Definition = nullptr; - def_it++; - R_ASSERT(def_it < 128); - - HRESULT _result = E_FAIL; - - char extension[3]; - strncpy_s(extension, pTarget, 2); - - string_path filename; - strconcat(sizeof(filename), filename, "r1" DELIMITER, name, ".", extension); - - string_path file_name; - { - string_path file; - strconcat(sizeof(file), file, "shaders_cache_oxr" DELIMITER, filename, DELIMITER, sh_name); - strconcat(sizeof(filename), filename, filename, DELIMITER, sh_name); - FS.update_path(file_name, "$app_data_root$", file); - } - - string_path shadersFolder; - FS.update_path(shadersFolder, "$game_shaders$", RImplementation.getShaderPath()); - - u32 fileCrc = 0; - getFileCrc32(fs, shadersFolder, fileCrc); - fs->seek(0); - - if (FS.exist(file_name)) - { - IReader* file = FS.r_open(file_name); - if (file->length() > 4) - { - u32 savedFileCrc = file->r_u32(); - if (savedFileCrc == fileCrc) - { - u32 savedBytecodeCrc = file->r_u32(); - u32 bytecodeCrc = crc32(file->pointer(), file->elapsed()); - if (bytecodeCrc == savedBytecodeCrc) - { -#ifdef DEBUG - Log("* Loading shader:", file_name); -#endif - _result = - create_shader(pTarget, (DWORD*)file->pointer(), file->elapsed(), filename, result, o.disasm); - } - } - } - file->close(); - } - - if (FAILED(_result)) - { - ShaderIncluder includer; - IShaderBlob* pShaderBuf = nullptr; - IShaderBlob* pErrorBuf = nullptr; - - _result = CompileShader(fs->pointer(), fs->length(), defines, &includer, - pFunctionName, pTarget, Flags, &pShaderBuf, &pErrorBuf); - if (SUCCEEDED(_result)) - { - IWriter* file = FS.w_open(file_name); - - file->w_u32(fileCrc); - - u32 crc = crc32(pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize()); - file->w_u32(crc); // Do not write anything below this line, take a look at reading (crc32) - - file->w(pShaderBuf->GetBufferPointer(), (u32)pShaderBuf->GetBufferSize()); - - FS.w_close(file); -#ifdef DEBUG - Log("- Compile shader:", file_name); -#endif - _result = create_shader(pTarget, (DWORD*)pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize(), - filename, result, o.disasm); - } - else - { - Log("! ", file_name); - if (pErrorBuf) - Log("! error: ", (LPCSTR)pErrorBuf->GetBufferPointer()); - else - Msg("Can't compile shader hr=0x%08x", _result); - } - } - - return _result; -} diff --git a/src/Layers/xrRenderPC_R1/FStaticRender_Types.h b/src/Layers/xrRenderPC_R1/FStaticRender_Types.h deleted file mode 100644 index 809fb58d34b..00000000000 --- a/src/Layers/xrRenderPC_R1/FStaticRender_Types.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// Base targets -#define r1_RT_base "$user$base_" -#define r1_RT_base_depth "$user$base_depth" - -#define r1_RT_generic "$user$rendertarget" - -#define rt_RT_color_map "$user$rendertarget_color_map" -#define rt_RT_distort "$user$distort" - -#define r1_RT_depth "$user$depth" // surface - -// Used in LightShadows -#define r1_RT_shadow "$user$shadow" -#define r1_RT_temp "$user$temp" -#define rt_RT_temp_zb "$user$temp_zb" // surface - -#define r1_RT_async_ss "$user$async_ss" // surface - -#define r2_T_sky0 "$user$sky0" -#define r2_T_sky1 "$user$sky1" - -#define r2_T_envs0 "$user$env_s0" -#define r2_T_envs1 "$user$env_s1" - -#define r2_RT_luminance_cur "$user$tonemap" // --- result - -static constexpr auto c_ldynamic_props = "L_dynamic_props"; -static constexpr auto c_sbase = "s_base"; -static constexpr auto c_ssky0 = "s_sky0"; -static constexpr auto c_ssky1 = "s_sky1"; -static constexpr auto c_sclouds0 = "s_clouds0"; -static constexpr auto c_sclouds1 = "s_clouds1"; diff --git a/src/Layers/xrRenderPC_R1/GlowManager.cpp b/src/Layers/xrRenderPC_R1/GlowManager.cpp deleted file mode 100644 index 9908d7dfe3f..00000000000 --- a/src/Layers/xrRenderPC_R1/GlowManager.cpp +++ /dev/null @@ -1,314 +0,0 @@ -// GlowManager.cpp: implementation of the CGlowManager class. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "xrEngine/IGame_Persistent.h" -#include "xrEngine/Environment.h" -#include "xrEngine/GameFont.h" -#include "GlowManager.h" -#include "xrEngine/xr_object.h" - -#define FADE_SCALE_UP 4096.f -#define FADE_SCALE_DOWN 1024.f -#define MAX_GlowsDist1 float(g_pGamePersistent->Environment().CurrentEnv.far_plane) -#define MAX_GlowsDist2 float(MAX_GlowsDist1 * MAX_GlowsDist1) - -////////////////////////////////////////////////////////////////////// -CGlow::CGlow() : SpatialBase(g_pGamePersistent->SpatialSpace) -{ - flags.bActive = false; - position.set(0, 0, 0); - direction.set(0, 0, 0); - radius = 0.1f; - color.set(1, 1, 1, 1); - bTestResult = FALSE; - fade = 1.f; - dwFrame = 0; - spatial.type = STYPE_RENDERABLE; -} -CGlow::~CGlow() -{ - set_active(false); - shader.destroy(); -} - -void CGlow::set_active(bool a) -{ - if (a) - { - if (flags.bActive) - return; - flags.bActive = true; - spatial_register(); - } - else - { - if (!flags.bActive) - return; - flags.bActive = false; - spatial_unregister(); - } -} - -bool CGlow::get_active() { return flags.bActive; } -void CGlow::set_position(const Fvector& P) -{ - if (position.similar(P)) - return; - position.set(P); - spatial_move(); -}; -void CGlow::set_direction(const Fvector& D) { direction.normalize_safe(D); }; -void CGlow::set_radius(float R) -{ - if (fsimilar(radius, R)) - return; - radius = R; - spatial_move(); -}; -void CGlow::set_texture(LPCSTR name) { shader.create("effects" DELIMITER "glow", name); } -void CGlow::set_color(const Fcolor& C) { color = C; } -void CGlow::set_color(float r, float g, float b) { color.set(r, g, b, 1); } -void CGlow::spatial_move() -{ - spatial.sphere.set(position, radius); - SpatialBase::spatial_move(); -} -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CGlowManager::CGlowManager() {} -CGlowManager::~CGlowManager() {} -void CGlowManager::Load(IReader* fs) -{ - // glows itself - const size_t size = fs->length(); - R_ASSERT(size); - const size_t one = sizeof(Fvector) + sizeof(float) + sizeof(u16); - R_ASSERT(size % one == 0); - size_t count = size / one; - Glows.reserve(count); - - for (; count; count--) - { - CGlow* G = xr_new(); - fs->r(&G->position, sizeof(Fvector)); - fs->r(&G->radius, sizeof(float)); - G->spatial.sphere.set(G->position, G->radius); - G->direction.set(0, 0, 0); - - u16 S = fs->r_u16(); - G->shader = ::RImplementation.getShader(S); - - G->fade = 255.f; - G->dwFrame = 0x0; - G->bTestResult = TRUE; - - G->spatial.type = STYPE_RENDERABLE; - - G->set_active(true); - - Glows.push_back(G); - } - dwTestID = 0; - - hGeom.create(FVF::F_LIT, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); -} - -void CGlowManager::Unload() -{ - // glows - SelectedToTest_2.clear(); - SelectedToTest_1.clear(); - SelectedToTest_0.clear(); - Selected.clear(); - Glows.clear(); -} - -IC bool glow_compare(ref_glow g1, ref_glow g2) { return ((CGlow*)g1._get())->shader < ((CGlow*)g2._get())->shader; } -void CGlowManager::add(ref_glow G_) -{ - CGlow* G = (CGlow*)G_._get(); - if (G->dwFrame == Device.dwFrame) - return; - G->dwFrame = Device.dwFrame; - float dt = Device.fTimeDelta; - float dlim2 = MAX_GlowsDist2; - - float range = Device.vCameraPosition.distance_to_sqr(G->spatial.sphere.P); - if (range < dlim2) - { - // 2. Use result of test - if (G->bTestResult) - { - G->fade -= dt * FADE_SCALE_DOWN; - if (G->fade < 1.) - G->fade = 1; - } - else - { - G->fade += dt * FADE_SCALE_UP; - if (G->fade > 255.f) - G->fade = 255.f; - } - - Selected.push_back(G); - return; - } - G->fade -= dt * FADE_SCALE_DOWN; - if (G->fade < 1.) - G->fade = 1; -} - -IC void FillSprite(FVF::LIT*& pv, const Fvector& pos, float r, u32 clr) -{ - const Fvector& T = Device.vCameraTop; - const Fvector& R = Device.vCameraRight; - Fvector Vr, Vt; - Vr.mul(R, r); - Vt.mul(T, r); - - Fvector a, b, c, d; - a.sub(Vt, Vr); - b.add(Vt, Vr); - c.invert(a); - d.invert(b); - pv->set(d.x + pos.x, d.y + pos.y, d.z + pos.z, clr, 0.f, 1.f); - pv++; - pv->set(a.x + pos.x, a.y + pos.y, a.z + pos.z, clr, 0.f, 0.f); - pv++; - pv->set(c.x + pos.x, c.y + pos.y, c.z + pos.z, clr, 1.f, 1.f); - pv++; - pv->set(b.x + pos.x, b.y + pos.y, b.z + pos.z, clr, 1.f, 0.f); - pv++; -} - -void CGlowManager::Render() -{ - if (Selected.empty()) - return; - RCache.set_xform_world(Fidentity); - render_sw(); -} - -void CGlowManager::render_sw() -{ - // 0. save main view and disable - IGameObject* o_main = g_pGameLevel->CurrentViewEntity(); - - // 1. Test some number of glows - Fvector start = Device.vCameraPosition; - for (int i = 0; i < ps_r1_GlowsPerFrame; i++, dwTestID++) - { - u32 ID = dwTestID % Selected.size(); - CGlow& G = *((CGlow*)Selected[ID]._get()); - if (G.dwFrame == 'test') - break; - G.dwFrame = 'test'; - Fvector dir; - dir.sub(G.spatial.sphere.P, start); - float range = dir.magnitude(); - if (range > EPS_S) - { - dir.div(range); - G.bTestResult = g_pGameLevel->ObjectSpace.RayTest(start, dir, range, collide::rqtBoth, &G.RayCache, o_main); - } - } - - // 2. Render selected - render_selected(); -} - -void CGlowManager::render_hw() -{ - // 0. query result from 'SelectedToTest_2' - SelectedToTest_2 = SelectedToTest_1; - SelectedToTest_1 = SelectedToTest_0; - SelectedToTest_0.clear(); - - // 1. Sort into two parts - 1(selected-to-test)[to-test], 2(selected)[just-draw] - // Fvector &start = Device.vCameraPosition; - for (int i = 0; (i < ps_r1_GlowsPerFrame) && Selected.size(); i++, dwTestID++) - { - u32 ID = dwTestID % Selected.size(); - SelectedToTest_0.push_back(Selected[ID]); - Selected.erase(Selected.begin() + ID); - } - - // 2. Render selected - render_selected(); - - // -} - -void CGlowManager::render_selected() -{ - // 2. Sort by shader - std::sort(Selected.begin(), Selected.end(), glow_compare); - - FVF::LIT* pv; - - u32 pos = 0, count; - ref_shader T; - - Fplane NP; - NP.build(Device.vCameraPosition, Device.vCameraDirection); - - float dlim2 = MAX_GlowsDist2; - for (; pos < Selected.size();) - { - T = ((CGlow*)Selected[pos]._get())->shader; - count = 0; - while ((pos + count < Selected.size()) && (((CGlow*)Selected[pos + count]._get())->shader == T)) - count++; - - u32 vOffset; - u32 end = pos + count; - FVF::LIT* pvs = pv = (FVF::LIT*)RImplementation.Vertex.Lock(count * 4, hGeom->vb_stride, vOffset); - for (; pos < end; pos++) - { - // Cull invisible - CGlow& G = *((CGlow*)Selected[pos]._get()); - if (G.fade <= 1.f) - continue; - - // Now perform dotproduct if need it - float scale = 1.f, dist_sq; - Fvector dir; - dir.sub(Device.vCameraPosition, G.position); - dist_sq = dir.square_magnitude(); - if (G.direction.square_magnitude() > EPS) - { - dir.div(_sqrt(dist_sq)); - scale = dir.dotproduct(G.direction); - } - if (G.fade * scale <= 1.f) - continue; - - // near fade - float dist_np = NP.distance(G.position) - VIEWPORT_NEAR; - float snear = dist_np / 0.15f; - clamp(snear, 0.f, 1.f); - scale *= snear; - if (G.fade * scale <= 1.f) - continue; - - u32 C = iFloor(G.fade * scale * (1 - (dist_sq / dlim2))); - u32 clr = color_rgba(C, C, C, C); - Fvector gp; - gp.mad(G.position, dir, G.radius * scale); - FillSprite(pv, G.position, G.radius, clr); - } - int vCount = int(pv - pvs); - RImplementation.Vertex.Unlock(vCount, hGeom->vb_stride); - if (vCount) - { - RCache.set_Shader(T); - RCache.set_Geometry(hGeom); - RCache.Render(D3DPT_TRIANGLELIST, vOffset, 0, vCount, 0, vCount / 2); - } - } - Selected.clear(); -} diff --git a/src/Layers/xrRenderPC_R1/GlowManager.h b/src/Layers/xrRenderPC_R1/GlowManager.h deleted file mode 100644 index 187bd638848..00000000000 --- a/src/Layers/xrRenderPC_R1/GlowManager.h +++ /dev/null @@ -1,78 +0,0 @@ -// GlowManager.h: interface for the CGlowManager class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_GLOWMANAGER_H__EC35911F_479B_469A_845C_1A64D81D0326__INCLUDED_) -#define AFX_GLOWMANAGER_H__EC35911F_479B_469A_845C_1A64D81D0326__INCLUDED_ -#pragma once - -#include "xrCDB/ISpatial.h" -#include "xrCDB/xr_collide_defs.h" - -class CGlow : public IRender_Glow, public SpatialBase -{ -public: - struct - { - u32 bActive : 1; - } flags; - float fade; - ref_shader shader; - u32 dwFrame; - - Fvector position; - Fvector direction; - float radius; - Fcolor color; - - // Ray-testing cache - BOOL bTestResult; - collide::ray_cache RayCache; - u32 qid_pass; - u32 qid_total; - -public: - CGlow(); - virtual ~CGlow(); - - virtual void set_active(bool); - virtual bool get_active(); - virtual void set_position(const Fvector& P); - virtual void set_direction(const Fvector& P); - virtual void set_radius(float R); - virtual void set_texture(LPCSTR name); - virtual void set_color(const Fcolor& C); - virtual void set_color(float r, float g, float b); - virtual void spatial_move(); -}; - -#define MAX_GlowsPerFrame 64 - -class CGlowManager -{ - xr_vector Glows; - xr_vector Selected; - xr_vector SelectedToTest_2; // 2-frames behind - xr_vector SelectedToTest_1; // 1-frames behind - xr_vector SelectedToTest_0; // 0-frames behind - ref_geom hGeom; - - BOOL b_hardware; - u32 dwTestID; - -public: - void add(ref_glow g); - - void Load(IReader* fs); - void Unload(); - - void render_selected(); - void render_sw(); - void render_hw(); - void Render(); - - CGlowManager(); - ~CGlowManager(); -}; - -#endif // !defined(AFX_GLOWMANAGER_H__EC35911F_479B_469A_845C_1A64D81D0326__INCLUDED_) diff --git a/src/Layers/xrRenderPC_R1/LightPPA.cpp b/src/Layers/xrRenderPC_R1/LightPPA.cpp deleted file mode 100644 index 9764b248cc5..00000000000 --- a/src/Layers/xrRenderPC_R1/LightPPA.cpp +++ /dev/null @@ -1,520 +0,0 @@ -// LightPPA.cpp: implementation of the CLightPPA class. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "LightPPA.h" -#include "xrEngine/IGame_Persistent.h" -#include "xrEngine/Environment.h" -#include "Layers/xrRender/FBasicVisual.h" -#include "Layers/xrRender/blenders/Blender_light.h" -#include "xrEngine/CustomHUD.h" - -const u32 MAX_POLYGONS = 1024 * 8; -const float MAX_DISTANCE = 50.f; -const float SSM_near_plane = .1f; -const float SSM_tex_size = 32.f; - -////////////////////////////////////////////////////////////////////////// -// binders for lighting -////////////////////////////////////////////////////////////////////////// -void cl_light_PR::setup(CBackend& cmd_list, R_constant* C) -{ - // NOTE: an actual context id is required here. However, we have only main context - // in R1 so it is safe to go with `eRDSG_MAIN`. - auto& dsgraph = RImplementation.get_imm_context(); - - Fvector& P = RImplementation.r1_dlight_light->position; - float R = RImplementation.r1_dlight_light->range; - if (dsgraph.o.phase == CRender::PHASE_POINT) - RCache.set_c(C, P.x, P.y, P.z, .5f / R); - else - RCache.set_c(C, P.x, P.y, P.z, 1.f / R); -} -void cl_light_C::setup(CBackend& cmd_list, R_constant* constant) -{ - Fcolor color = RImplementation.r1_dlight_light->color; - color.mul_rgb(RImplementation.r1_dlight_scale); - RCache.set_c(constant, color.r, color.g, color.b, 1.f); -} -void cl_light_XFORM::setup(CBackend& cmd_list, R_constant* C) { RCache.set_c(C, RImplementation.r1_dlight_tcgen); } -////////////////////////////////////////////////////////////////////////// -/* -IC void mk_vertex (CLightR_Vertex& D, Fvector& P, Fvector& N, Fvector& C, float r2) -{ - D.P.set (P); - D.N.set (P); - D.u0 = (P.x-C.x)/r2+.5f; - D.v0 = (P.z-C.z)/r2+.5f; - D.u1 = (P.y-C.y)/r2+.5f; - D.v1 =.5f; -} - -void CLightR_Manager::render_point () -{ - // Implementation banned / non-working ? - // return; - - // World/View/Projection - float _43 = Device.mProject._43; - Device.mProject._43 -= 0.001f; - RCache.set_xform_world (Fidentity); - RCache.set_xform_project (Device.mProject); - - RImplementation.r1_dlight_light = selected_point.front(); - RCache.set_Shader (hShader); - for (xr_vector::iterator it=selected_point.begin(); it!=selected_point.end(); it++) - { - // 2. Set global light-params to be used by shading - RImplementation.r1_dlight_light = *it; - light& PPL = *(*it); - - // Culling - if (PPL.range<0.05f) continue; - if (PPL.color.magnitude_sqr_rgb()=1) continue; - if (!RImplementation.ViewBase.testSphere_dirty (PPL.position,PPL.range)) continue; - - // Calculations and rendering - Device.Statistic->RenderDUMP_Lights.Begin(); - Fcolor factor; - factor.mul_rgba (PPL.color,(1-alpha)); - RCache.set_c (hPPAcolor,factor.r,factor.g,factor.b,1); - { - // Build bbox - float size_f = PPL.range+EPS_L; - Fvector size; - size.set (size_f,size_f,size_f); - - // Query collision DB (Select polygons) - xrc.box_options (0); - xrc.box_query (g_pGameLevel->ObjectSpace.GetStaticModel(),PPL.position,size); - u32 triCount = xrc.r_count (); - if (0==triCount) return; - CDB::TRI* tris = g_pGameLevel->ObjectSpace.GetStaticTris(); - Fvector* verts = g_pGameLevel->ObjectSpace.GetStaticVerts(); - - // Lock - RCache.set_Geometry (hGeom); - u32 triLock = _min(256u,triCount); - u32 vOffset; - CLightR_Vertex* VB = (CLightR_Vertex*)RImplementation.Vertex.Lock(triLock*3,hGeom->vb_stride,vOffset); - - // Cull and triangulate polygons - Fvector cam = Device.vCameraPosition; - float r2 = PPL.range*2; - u32 actual = 0; - for (u32 t=0; t=triLock) - { - RImplementation.Vertex.Unlock (actual*3,hGeom->vb_stride); - if (actual) RCache.Render (D3DPT_TRIANGLELIST,vOffset,actual); - actual = 0; - triLock = _min(256u,triCount-t); - VB = -(CLightR_Vertex*)RImplementation.Vertex.Lock(triLock*3,hGeom->vb_stride,vOffset); - } - } - - // Unlock and render - RImplementation.Vertex.Unlock (actual*3,hGeom->vb_stride); - if (actual) RCache.Render (D3DPT_TRIANGLELIST,vOffset,actual); - } - Device.Statistic->RenderDUMP_Lights.End (); - } - - // Projection - Device.mProject._43 = _43; - RCache.set_xform_project (Device.mProject); -} -*/ - -void CLightR_Manager::render_point(u32 _priority) -{ - auto &dsgraph = RImplementation.get_imm_context(); - - // for each light - Fvector lc_COP = Device.vCameraPosition; - float lc_limit = ps_r1_dlights_clip; - for (xr_vector::iterator it = selected_point.begin(); it != selected_point.end(); ++it) - { - light* L = *it; - VERIFY(L->spatial.sector_id != IRender_Sector::INVALID_SECTOR_ID && _valid(L->range)); - - // 0. Dimm & Clip - float lc_dist = lc_COP.distance_to(L->spatial.sphere.P) - L->spatial.sphere.R; - float lc_scale = 1 - lc_dist / lc_limit; - if (lc_scale < EPS) - continue; - if (L->range < 0.01f) - continue; - - RImplementation.BasicStats.Lights.Begin(); - - // 1. Calculate light frustum - Fvector L_dir, L_up, L_right, L_pos; - Fmatrix L_view, L_project, L_combine; - L_dir.set(0, -1, 0); - L_up.set(0, 0, 1); - L_right.crossproduct(L_up, L_dir); - L_right.normalize(); - L_up.crossproduct(L_dir, L_right); - L_up.normalize(); - float _camrange = 300.f; - L_pos.set(L->position); - // L_pos.y += _camrange; - L_view.build_camera_dir(L_pos, L_dir, L_up); - L_project.build_projection(deg2rad(2.f), 1.f, _camrange - L->range, _camrange + L->range); - L_combine.mul(L_project, L_view); - - // 2. Calculate matrix for TC-gen - float fTexelOffs = (.5f / SSM_tex_size); - float fRange = 1.f / L->range; - float fBias = 0.f; - Fmatrix m_TexelAdjust = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, - 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f}; - Fmatrix L_texgen; - L_texgen.mul(m_TexelAdjust, L_combine); - - // 2. Set global light-params to be used by shading - RImplementation.r1_dlight_light = L; - RImplementation.r1_dlight_scale = clampr(lc_scale, 0.f, 1.f); - RImplementation.r1_dlight_tcgen = L_texgen; - - // 3. Calculate visibility for light + build soring tree - VERIFY(L->spatial.sector_id != IRender_Sector::INVALID_SECTOR_ID); - if (_priority == 1) - dsgraph.r_pmask(false, true); - - dsgraph.o.sector_id = L->spatial.sector_id; - dsgraph.o.view_pos = L_pos; - dsgraph.o.xform = L_combine; - dsgraph.o.view_frustum.CreateFromMatrix(L_combine, FRUSTUM_P_ALL & (~FRUSTUM_P_NEAR)); - dsgraph.o.precise_portals = true; - - dsgraph.build_subspace(); - - if (_priority == 1) - dsgraph.r_pmask(true, true); - - // 4. Analyze if HUD intersects light volume - BOOL bHUD = FALSE; - CFrustum F; - F.CreateFromMatrix(L_combine, FRUSTUM_P_ALL); - bHUD = F.testSphere_dirty(Device.vCameraPosition, 2.f); - - // 5. Dump sorting tree - RCache.set_Constants((R_constant_table*)nullptr); - if (bHUD && _priority == 0) - g_pGameLevel->pHUD->Render_Last(dsgraph.context_id); - dsgraph.render_graph(_priority); - if (bHUD && _priority == 0) - dsgraph.render_hud(); - - RImplementation.BasicStats.Lights.End(); - } - // ??? grass ??? -} - -void CLightR_Manager::render_spot(u32 _priority) -{ - auto& dsgraph = RImplementation.get_imm_context(); - - // for each light - // Msg ("l=%d",selected_spot.size()); - Fvector lc_COP = Device.vCameraPosition; - float lc_limit = ps_r1_dlights_clip; - - for (xr_vector::iterator it = selected_spot.begin(); it != selected_spot.end(); ++it) - { - light* L = *it; - - // 0. Dimm & Clip - float lc_dist = lc_COP.distance_to(L->spatial.sphere.P) - L->spatial.sphere.R; - float lc_scale = 1 - lc_dist / lc_limit; - if (lc_scale < EPS) - continue; - - RImplementation.BasicStats.Lights.Begin(); - - // 1. Calculate light frustum - Fvector L_dir, L_up, L_right, L_pos; - Fmatrix L_view, L_project, L_combine; - L_dir.set(L->direction); - L_dir.normalize(); - L_up.set(0, 1, 0); - if (_abs(L_up.dotproduct(L_dir)) > .99f) - L_up.set(0, 0, 1); - L_right.crossproduct(L_up, L_dir); - L_right.normalize(); - L_up.crossproduct(L_dir, L_right); - L_up.normalize(); - L_pos.set(L->position); - L_view.build_camera_dir(L_pos, L_dir, L_up); - L_project.build_projection(L->cone, 1.f, SSM_near_plane, L->range + EPS_S); - L_combine.mul(L_project, L_view); - - // 2. Calculate matrix for TC-gen - float fTexelOffs = (.5f / SSM_tex_size); - float fRange = 1.f / L->range; - float fBias = 0.f; - Fmatrix m_TexelAdjust = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, - 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f}; - Fmatrix L_texgen; - L_texgen.mul(m_TexelAdjust, L_combine); - - // 2. Set global light-params to be used by shading - RImplementation.r1_dlight_light = L; - RImplementation.r1_dlight_scale = clampr(lc_scale, 0.f, 1.f); - RImplementation.r1_dlight_tcgen = L_texgen; - - // 3. Calculate visibility for light + build soring tree - VERIFY(L->spatial.sector_id != IRender_Sector::INVALID_SECTOR_ID); - if (_priority == 1) - dsgraph.r_pmask(false, true); - - dsgraph.o.sector_id = L->spatial.sector_id; - dsgraph.o.view_pos = L_pos; - dsgraph.o.xform = L_combine; - dsgraph.o.view_frustum.CreateFromMatrix(L_combine, FRUSTUM_P_ALL & (~FRUSTUM_P_NEAR)); - dsgraph.o.precise_portals = true; - - dsgraph.build_subspace(); - - if (_priority == 1) - dsgraph.r_pmask(true, true); - - // 4. Analyze if HUD intersects light volume - BOOL bHUD = FALSE; - CFrustum F; - F.CreateFromMatrix(L_combine, FRUSTUM_P_ALL); - bHUD = F.testSphere_dirty(Device.vCameraPosition, 2.f); - // if (bHUD) Msg ("HUD"); - - // 4. Dump sorting tree - //RCache.set_ClipPlanes(true, &L_combine); - RCache.set_Constants((R_constant_table*)nullptr); - if (bHUD && _priority == 0) - g_pGameLevel->pHUD->Render_Last(dsgraph.context_id); - dsgraph.render_graph(_priority); - if (bHUD && _priority == 0) - dsgraph.render_hud(); - //RCache.set_ClipPlanes(false, &L_combine); - - RImplementation.BasicStats.Lights.End(); - } - // ??? grass ???l -} - -void CLightR_Manager::render_ffp() -{ - // Projection - const float _43 = Device.mProject._43; - Device.mProject._43 -= 0.001f; - RCache.set_xform_project(Device.mProject); - - RCache.set_Shader(hShader); - for (light* light : selected_spot) - render_ffp_light(*light); - for (light* light : selected_point) - render_ffp_light(*light); - - // Projection - Device.mProject._43 = _43; - RCache.set_xform_project(Device.mProject); -} - -void CLightR_Manager::render_ffp_light(const light& L) -{ - // Culling - if (L.range < 0.05f) - return; - if (L.color.magnitude_sqr_rgb() < EPS) - return; - - const float alpha = Device.vCameraPosition.distance_to(L.position) / MAX_DISTANCE; - if (alpha >= 1) - return; - if (!RImplementation.ViewBase.testSphere_dirty(L.position, L.range)) - return; - - // Calculations and rendering - Fcolor factor; - factor.mul_rgba(L.color, 1 - alpha); - RCache.SetTextureFactor(factor.get()); - - // Build bbox - Fvector size; - size.set(L.range + EPS_L, L.range + EPS_L, L.range + EPS_L); - - // Query collision DB (Select polygons) - CDB::MODEL* DB = g_pGameLevel->ObjectSpace.GetStaticModel(); - - XRC.box_query(0, DB, L.position, size); - const u32 triCount = static_cast(XRC.r_count()); - if (0 == triCount) - return; - - RImplementation.BasicStats.Lights.Begin(); - - const CDB::TRI* tris = g_pGameLevel->ObjectSpace.GetStaticTris(); - const Fvector* VERTS = DB->get_verts(); - - const auto mk_vertex = [](CLightR_Vertex& D, const Fvector& P, const Fvector& /*N*/, const Fvector& C, const float r2) - { - D.P.set(P); - D.N.set(P); // P use instead of N. Why? - D.u0 = (P.x - C.x) / r2 + .5f; - D.v0 = (P.z - C.z) / r2 + .5f; - D.u1 = (P.y - C.y) / r2 + .5f; - D.v1 = .5f; - }; - - // Lock - RCache.set_Geometry(hGeom); - u32 triLock = _min(256u, triCount); - u32 vOffset; - CLightR_Vertex* VB = (CLightR_Vertex*)RImplementation.Vertex.Lock(triLock * 3, hGeom->vb_stride, vOffset); - - // Cull and triangulate polygons - const Fvector cam = Device.vCameraPosition; - const float r2 = L.range * 2; - - u32 actual = 0; - for (u32 t = 0; t < triCount; t++) - { - const CDB::TRI& T = tris[XRC.r_begin()[t].id]; - - const auto& V1 = VERTS[T.verts[0]]; - const auto& V2 = VERTS[T.verts[1]]; - const auto& V3 = VERTS[T.verts[2]]; - Fplane Poly; - Poly.build(V1, V2, V3); - - // Test for poly facing away from light or camera - if (Poly.classify(L.position) < 0) - continue; - if (Poly.classify(cam) < 0) - continue; - - // Triangulation and UV0/UV1 - mk_vertex(*VB, V1, Poly.n, L.position, r2); - VB++; - mk_vertex(*VB, V2, Poly.n, L.position, r2); - VB++; - mk_vertex(*VB, V3, Poly.n, L.position, r2); - VB++; - actual++; - - if (actual >= triLock) - { - RImplementation.Vertex.Unlock(actual * 3, hGeom->vb_stride); - if (actual) - RCache.Render(D3DPT_TRIANGLELIST, vOffset, actual); - actual = 0; - triLock = _min(256u, triCount - t); - VB = (CLightR_Vertex*)RImplementation.Vertex.Lock(triLock * 3, hGeom->vb_stride, vOffset); - } - } - - // Unlock and render - RImplementation.Vertex.Unlock(actual * 3, hGeom->vb_stride); - if (actual) - RCache.Render(D3DPT_TRIANGLELIST, vOffset, actual); - - RImplementation.BasicStats.Lights.End(); -} - -void CLightR_Manager::render(u32 _priority) -{ - if (RImplementation.o.ffp) - { - if (ps_r1_flags.test(R1FLAG_DLIGHTS)) - render_ffp(); - - if (_priority == 1) - { - selected_spot.clear(); - selected_point.clear(); - } - return; - } - - auto& dsgraph = RImplementation.get_imm_context(); - - if (selected_spot.size()) - { - dsgraph.o.phase = CRender::PHASE_SPOT; - render_spot(_priority); - - if (_priority == 1) - selected_spot.clear(); - } - if (selected_point.size()) - { - dsgraph.o.phase = CRender::PHASE_POINT; - render_point(_priority); - - if (_priority == 1) - selected_point.clear(); - } -} - -void CLightR_Manager::add(light* L) -{ - if (L->range < 0.1f) - return; - if (L->spatial.sector_id == IRender_Sector::INVALID_SECTOR_ID) - return; - if (IRender_Light::POINT == L->flags.type) - { - // PPA - selected_point.push_back(L); - } - else - { - // spot/flash - selected_spot.push_back(L); - } - VERIFY(L->spatial.sector_id != IRender_Sector::INVALID_SECTOR_ID); -} - -// XXX stats: add to statistics -CLightR_Manager::CLightR_Manager() : xrc("LightR_Manager") -{ - if (RImplementation.o.ffp) - { - hGeom.create(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2, RImplementation.Vertex.Buffer(), nullptr); - - static constexpr pcstr shader = "effects\\light"; - static constexpr pcstr textures = "effects\\light,effects\\light"; - - hShader.create(shader, textures); - if (!hShader) - { - CBlender_LIGHT blender; - hShader.create(&blender, shader, textures); - } - } -} - -CLightR_Manager::~CLightR_Manager() {} diff --git a/src/Layers/xrRenderPC_R1/LightPPA.h b/src/Layers/xrRenderPC_R1/LightPPA.h deleted file mode 100644 index 99549892cb4..00000000000 --- a/src/Layers/xrRenderPC_R1/LightPPA.h +++ /dev/null @@ -1,59 +0,0 @@ -// LightPPA.h: interface for the CLightPPA class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_LIGHTPPA_H__E5B97AC9_84A6_4773_9FEF_3BC5D1CEF8B6__INCLUDED_) -#define AFX_LIGHTPPA_H__E5B97AC9_84A6_4773_9FEF_3BC5D1CEF8B6__INCLUDED_ -#pragma once - -#include "Layers/xrRender/light.h" - -struct CLightR_Vertex -{ - Fvector P; - Fvector N; - float u0, v0; - float u1, v1; -}; - -class CLightR_Manager -{ - xrXRC xrc; - xr_vector selected_point; - xr_vector selected_spot; - - // For FFP - ref_shader hShader; - ref_geom hGeom; - -public: - CLightR_Manager(); - virtual ~CLightR_Manager(); - - void add(light* L); - void render(u32 _priority); - void render_point(u32 _priority); - void render_spot(u32 _priority); - void render_ffp(); - -private: - void render_ffp_light(const light& L); -}; - -////////////////////////////////////////////////////////////////////////// -// binders for lighting -////////////////////////////////////////////////////////////////////////// -class cl_light_PR : public R_constant_setup -{ - void setup(CBackend& cmd_list, R_constant* C) override; -}; -class cl_light_C : public R_constant_setup -{ - void setup(CBackend& cmd_list, R_constant* C) override; -}; -class cl_light_XFORM : public R_constant_setup -{ - void setup(CBackend& cmd_list, R_constant* C) override; -}; - -#endif // !defined(AFX_LIGHTPPA_H__E5B97AC9_84A6_4773_9FEF_3BC5D1CEF8B6__INCLUDED_) diff --git a/src/Layers/xrRenderPC_R1/LightProjector.cpp b/src/Layers/xrRenderPC_R1/LightProjector.cpp deleted file mode 100644 index 7db73586626..00000000000 --- a/src/Layers/xrRenderPC_R1/LightProjector.cpp +++ /dev/null @@ -1,407 +0,0 @@ -// LightProjector.cpp: implementation of the CLightProjector class. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "LightProjector.h" -#include "Include/xrRender/RenderVisual.h" -#include "xrEngine/xr_object.h" -#include "Layers/xrRender/LightTrack.h" - -// tir2.xrdemo -> 45.2 -// tir2.xrdemo -> 61.8 - -const float P_distance = 50; // switch distance between LOW-q light and HIGH-q light -const float P_cam_dist = 200; -const float P_cam_range = 7.f; -const D3DFORMAT P_rtf = D3DFMT_A8R8G8B8; -const float P_blur_kernel = .5f; -const int time_min = 30 * 1000; -const int time_max = 90 * 1000; -const float P_ideal_size = 1.f; - -float clipD(float R) { return P_distance * (R / P_ideal_size); } -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CLightProjector::CLightProjector() -{ - current = nullptr; - RT = nullptr; - - // - RT.create("$user$projector", P_rt_size, P_rt_size, P_rtf); - - // ref-str for faster const-search - c_xform = "m_plmap_xform"; - c_clamp = "m_plmap_clamp"; - c_factor = "m_plmap_factor"; - - cache.resize(P_o_count); - Device.seqAppActivate.Add(this); -} - -CLightProjector::~CLightProjector() -{ - Device.seqAppActivate.Remove(this); - RT.destroy(); -} - -void CLightProjector::set_object(IRenderable* O) -{ - if (current == O) - return; - - if ((nullptr == O) || (receivers.size() >= P_o_count)) - current = nullptr; - else - { - if (!O->renderable_ShadowReceive() || O->renderable_Invisible() || - ((CROS_impl*)O->renderable_ROS())->shadow_recv_frame == Device.dwFrame) - { - current = nullptr; - return; - } - - const vis_data& vis = O->GetRenderData().visual->getVisData(); - Fvector C; - O->GetRenderData().xform.transform_tiny(C, vis.sphere.P); - float R = vis.sphere.R; - float D = C.distance_to(Device.vCameraPosition) + R; - - if (D < clipD(R)) - current = O; - else - current = nullptr; - - if (current) - { - ISpatial* spatial = dynamic_cast(O); - if (nullptr == spatial) - current = nullptr; - else - { - auto& dsgraph = RImplementation.get_imm_context(); - const auto& entity_pos = spatial->spatial_sector_point(); - spatial->spatial_updatesector(dsgraph.detect_sector(entity_pos)); - if (spatial->GetSpatialData().sector_id == IRender_Sector::INVALID_SECTOR_ID) - { - IGameObject* obj = dynamic_cast(O); - if (obj) - Msg("! Invalid object '%s' position. Outside of sector structure.", obj->cName().c_str()); - current = nullptr; - } - } - } - if (current) - { - CROS_impl* LT = (CROS_impl*)current->renderable_ROS(); - LT->shadow_recv_frame = Device.dwFrame; - receivers.push_back(current); - } - } -} - -// -void CLightProjector::setup(int id) -{ - if (id >= int(cache.size()) || id < 0) - { - //Log("! CLightProjector::setup - ID out of range"); - return; - } - recv& R = cache[id]; - float Rd = R.O->GetRenderData().visual->getVisData().sphere.R; - float dist = R.C.distance_to(Device.vCameraPosition) + Rd; - float factor = _sqr(dist / clipD(Rd)) * (1 - ps_r1_lmodel_lerp) + ps_r1_lmodel_lerp; - RCache.set_c(c_xform, R.UVgen); - Fvector& m = R.UVclamp_min; - RCache.set_ca(c_clamp, 0, m.x, m.y, m.z, factor); - Fvector& M = R.UVclamp_max; - RCache.set_ca(c_clamp, 1, M.x, M.y, M.z, 0.0f); -} - -void CLightProjector::invalidate() -{ - for (u32 c_it = 0; c_it < cache.size(); c_it++) - cache[c_it].dwTimeValid = 0; -} - -void CLightProjector::OnAppActivate() { invalidate(); } -// -#include "Layers/xrRender/SkeletonCustom.h" -void CLightProjector::calculate() -{ -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("CLightProjector::calculate()"); -#endif // _GPA_ENABLED - - if (receivers.empty()) - return; - - // perform validate / markup - for (u32 r_it = 0; r_it < receivers.size(); r_it++) - { - // validate - BOOL bValid = TRUE; - IRenderable* O = receivers[r_it]; - CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); - int slot = LT->shadow_recv_slot; - if (slot < 0 || slot >= P_o_count) - bValid = FALSE; // invalid slot - else if (cache[slot].O != O) - bValid = FALSE; // not the same object - else - { - // seems to be valid - Fbox bb; - bb.xform(O->GetRenderData().visual->getVisData().box, O->GetRenderData().xform); - if (cache[slot].BB.contains(bb)) - { - // inside, but maybe timelimit exceeded? - if (Device.dwTimeGlobal > cache[slot].dwTimeValid) - bValid = FALSE; // timeout - } - else - bValid = FALSE; // out of bounds - } - - // - if (bValid) - { - // Ok, use cached version - cache[slot].dwFrame = Device.dwFrame; - } - else - { - taskid.push_back(r_it); - } - } - if (taskid.empty()) - return; - - // Begin - RCache.set_RT(RT->pRT); - RCache.set_ZB(RImplementation.Target->rt_temp_zb->pRT); - RCache.ClearZB(RImplementation.Target->rt_temp_zb, 1.f, 0); - RCache.set_xform_world(Fidentity); - - auto& dsgraph = RImplementation.get_imm_context(); - - // reallocate/reassociate structures + perform all the work - for (u32 c_it = 0; c_it < cache.size(); c_it++) - { - if (taskid.empty()) - break; - if (Device.dwFrame == cache[c_it].dwFrame) - continue; - - // found not used slot - int tid = taskid.back(); - taskid.pop_back(); - recv& R = cache[c_it]; - IRenderable* O = receivers[tid]; - const vis_data& vis = O->GetRenderData().visual->getVisData(); - CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); - VERIFY2(_valid(O->GetRenderData().xform), "Invalid object transformation"); - VERIFY2(_valid(vis.sphere.P), "Invalid object's visual sphere"); - - Fvector C; - O->GetRenderData().xform.transform_tiny(C, vis.sphere.P); - R.O = O; - R.C = C; - R.C.y += vis.sphere.R * 0.1f; //. YURA: 0.1 can be more - R.BB.xform(vis.box, O->GetRenderData().xform).scale(0.1f); - R.dwTimeValid = Device.dwTimeGlobal + ::Random.randI(time_min, time_max); - LT->shadow_recv_slot = c_it; - - // Msg ("[%f,%f,%f]-%f",C.C.x,C.C.y,C.C.z,C.O->renderable.visual->vis.sphere.R); - // calculate projection-matrix - Fmatrix mProject; - float p_R = R.O->GetRenderData().visual->getVisData().sphere.R * 1.1f; - // VERIFY2 (p_R>EPS_L,"Object has no physical size"); - VERIFY3(p_R > EPS_L, "Object has no physical size", R.O->GetRenderData().visual->getDebugName().c_str()); - float p_hat = p_R / P_cam_dist; - float p_asp = 1.f; - float p_near = P_cam_dist - EPS_L; - float p_far = P_cam_dist + p_R + P_cam_range; - mProject.build_projection_HAT(p_hat, p_asp, p_near, p_far); - RCache.set_xform_project(mProject); - - // calculate view-matrix - Fmatrix mView; - Fvector v_C, v_Cs, v_N; - v_C.set(R.C); - v_Cs = v_C; - v_C.y += P_cam_dist; - v_N.set(0, 0, 1); - VERIFY(_valid(v_C) && _valid(v_Cs) && _valid(v_N)); - - // validate - Fvector v; - v.sub(v_Cs, v_C); - ; -#ifdef DEBUG - if ((v.x * v.x + v.y * v.y + v.z * v.z) <= flt_zero) - { - IGameObject* OO = dynamic_cast(R.O); - Msg("Object[%s] Visual[%s] has invalid position. ", *OO->cName(), *OO->cNameVisual()); - Fvector cc; - OO->Center(cc); - Log("center=", cc); - - Log("visual_center=", OO->Visual()->getVisData().sphere.P); - - Log("full_matrix=", OO->XFORM()); - - Log("v_N", v_N); - Log("v_C", v_C); - Log("v_Cs", v_Cs); - - Log("all bones transform:--------"); - CKinematics* K = dynamic_cast(OO->Visual()); - - for (u16 ii = 0; ii < K->LL_BoneCount(); ++ii) - { - Fmatrix tr; - - tr = K->LL_GetTransform(ii); - Log("bone ", K->LL_BoneName_dbg(ii)); - Log("bone_matrix", tr); - } - Log("end-------"); - } -#endif - // handle invalid object-bug - if ((v.x * v.x + v.y * v.y + v.z * v.z) <= flt_zero) - { - // invalidate record, so that object will be unshadowed, but doesn't crash - R.dwTimeValid = Device.dwTimeGlobal; - LT->shadow_recv_frame = Device.dwFrame - 1; - LT->shadow_recv_slot = -1; - continue; - } - - mView.build_camera(v_C, v_Cs, v_N); - RCache.set_xform_view(mView); - - // Select slot, set viewport - int s_x = c_it % P_o_line; - int s_y = c_it / P_o_line; - const D3D_VIEWPORT viewport = { s_x * P_o_size, s_y * P_o_size, P_o_size, P_o_size, 0.f, 1.f }; - RCache.SetViewport(viewport); - - // Clear color to ambience - Fvector& cap = LT->get_approximate(); - RCache.ClearRT(RT, color_rgba_f(cap.x, cap.y, cap.z, (cap.x + cap.y + cap.z) / 4.f)); - - // calculate uv-gen matrix and clamper - Fmatrix mCombine; - mCombine.mul(mProject, mView); - Fmatrix mTemp; - float fSlotSize = float(P_o_size) / float(P_rt_size); - float fSlotX = float(s_x * P_o_size) / float(P_rt_size); - float fSlotY = float(s_y * P_o_size) / float(P_rt_size); - float fTexelOffs = (.5f / P_rt_size); - Fmatrix m_TexelAdjust = {0.5f /*x-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f /*y-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, - 1.0f /*z-range*/, 0.0f, 0.5f /*x-bias*/, 0.5f + fTexelOffs /*y-bias*/, 0.0f /*z-bias*/, 1.0f}; - R.UVgen.mul(m_TexelAdjust, mCombine); - mTemp.scale(fSlotSize, fSlotSize, 1); - R.UVgen.mulA_44(mTemp); - mTemp.translate(fSlotX + fTexelOffs, fSlotY + fTexelOffs, 0); - R.UVgen.mulA_44(mTemp); - - // Build bbox and render - Fvector min, max; - Fbox BB; - min.set(R.C.x - p_R, R.C.y - (p_R + P_cam_range), R.C.z - p_R); - max.set(R.C.x + p_R, R.C.y + 0, R.C.z + p_R); - BB.set(min, max); - R.UVclamp_min.set(min).add(.05f); // shrink a little - R.UVclamp_max.set(max).sub(.05f); // shrink a little - ISpatial* spatial = dynamic_cast(O); - if (spatial) - { - const auto& entity_pos = spatial->spatial_sector_point(); - const auto sector_id = dsgraph.detect_sector(entity_pos); - spatial->spatial_updatesector(sector_id); - if (spatial->GetSpatialData().sector_id != IRender_Sector::INVALID_SECTOR_ID) - dsgraph.render_R1_box(spatial->GetSpatialData().sector_id, BB, SE_R1_LMODELS); - } - /*if (spatial) - { - dsgraph.o.sector_id = spatial->GetSpatialData().sector_id; - dsgraph.o.xform = mCombine; - dsgraph.o.view_pos = v_C; - dsgraph.build_subspace(); - }*/ - } - - // Blur - /* - { - // Fill vertex buffer - u32 Offset; - if (RImplementation.o.ffp) { - FVF::TL2uv* pv = (FVF::TL2uv*) RImplementation.Vertex.Lock (8,geom_Blur.stride(),Offset); - RImplementation.ApplyBlur2 (pv, rt_size); - RImplementation.Vertex.Unlock (8,geom_Blur.stride()); - } else { - FVF::TL4uv* pv = (FVF::TL4uv*) RImplementation.Vertex.Lock (4,geom_Blur.stride(),Offset); - RImplementation.ApplyBlur4 (pv,P_rt_size,P_rt_size,P_blur_kernel); - RImplementation.Vertex.Unlock (4,geom_Blur.stride()); - } - - // Actual rendering (pass0, temp2real) - RCache.set_RT (RT->pRT); - RCache.set_ZB (NULL); - RCache.set_Shader (sh_BlurTR ); - RCache.set_Geometry (geom_Blur ); - RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); - } - */ - - // Finita la comedia - RCache.set_xform_project(Device.mProject); - RCache.set_xform_view(Device.mView); -} - -#ifdef DEBUG -void CLightProjector::render() -{ - /* - #define CLS(a) color_rgba(a,a,a,a) - RCache.set_xform_world (Fidentity); - Device.Resources->OnFrameEnd (); - for (u32 it=0; itLock(4,Offset); - pv->set(0, float(_h), .0001f,.9999f, C, p0.x, p1.y); pv++; - pv->set(0, 0, .0001f,.9999f, C, p0.x, p0.y); pv++; - pv->set(float(_w), float(_h), .0001f,.9999f, C, p1.x, p1.y); pv++; - pv->set(float(_w), 0, .0001f,.9999f, C, p1.x, p0.y); pv++; - geom_Screen->Unlock (4); - - // Actual rendering - RCache.set_Shader(sh_Screen); - RCache.Draw (geom_Screen,4,2,Offset,Device.Streams_QuadIB); - } - */ -} -#endif diff --git a/src/Layers/xrRenderPC_R1/LightProjector.h b/src/Layers/xrRenderPC_R1/LightProjector.h deleted file mode 100644 index fc028e2fc94..00000000000 --- a/src/Layers/xrRenderPC_R1/LightProjector.h +++ /dev/null @@ -1,65 +0,0 @@ -// LightShadows.h: interface for the CLightShadows class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_LIGHTPRJ_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_) -#define AFX_LIGHTPRJ_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_ -#pragma once - -#include "Layers/xrRender/r__dsgraph_types.h" - -class CLightProjector : public pureAppActivate -{ -private: - static const int P_rt_size = 512; - static const int P_o_size = 51; - static const int P_o_line = P_rt_size / P_o_size; - static const int P_o_count = P_o_line * P_o_line; - - // - typedef R_dsgraph::_MatrixItem NODE; - struct recv - { - IRenderable* O; - Fvector C; - Fmatrix UVgen; - Fvector UVclamp_min; - Fvector UVclamp_max; - Fbox BB; - u32 dwFrame; - u32 dwTimeValid; - }; - -private: - IRenderable* current; - xr_vector cache; // same as number of slots - xr_vector receivers; - xr_vector taskid; - - ref_rt RT; - shared_str c_xform; - shared_str c_clamp; - shared_str c_factor; - -public: - void set_object(IRenderable* O); - BOOL shadowing() { return current != nullptr; } - void calculate(); - void setup(int slot); - void finalize() - { - receivers.clear(); - taskid.clear(); - } - void invalidate(); - - virtual void OnAppActivate(); -#ifdef DEBUG - void render(); -#endif - - CLightProjector(); - ~CLightProjector(); -}; - -#endif // !defined(AFX_LIGHTPRJ_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_) diff --git a/src/Layers/xrRenderPC_R1/LightShadows.cpp b/src/Layers/xrRenderPC_R1/LightShadows.cpp deleted file mode 100644 index c584f5521b3..00000000000 --- a/src/Layers/xrRenderPC_R1/LightShadows.cpp +++ /dev/null @@ -1,694 +0,0 @@ -#include "stdafx.h" -#include "LightShadows.h" -#include "Layers/xrRender/LightTrack.h" -#include "xrEngine/xr_object.h" -#include "Layers/xrRender/FBasicVisual.h" -#include "Layers/xrRender/blenders/Blender_Blur.h" -#include "Layers/xrRender/blenders/Blender_Shadow_Texture.h" -#include "xrEngine/CustomHUD.h" - -const float S_distance = 144; -const float S_distance2 = S_distance * S_distance; -const float S_ideal_size = 4.f; // ideal size for the object -const float S_fade = 4.5; -const float S_fade2 = S_fade * S_fade; - -const float S_level = .05f; // clip by energy level -const int batch_size = 256; -const float S_tess = .5f; -const int S_ambient = 32; -const int S_clip = 256 - 8; -const D3DFORMAT S_rtf = D3DFMT_A8R8G8B8; -const float S_blur_kernel = 0.75f; - -const u32 cache_old = 30 * 1000; // 30 secs - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -void CLightShadows::recreate_rt() -{ - rt_shadow.destroy(); - rt_temp.destroy(); - - rt_size = ps_r2_smapsize / 2; - rt_shadow.create(r1_RT_shadow, rt_size, rt_size, S_rtf); - rt_temp.create(r1_RT_temp, rt_size, rt_size, S_rtf); -} - -#define TWO_TEMP_TEXTURES r1_RT_temp "," r1_RT_temp -#define TWO_SHADOW_TEXTURES r1_RT_shadow "," r1_RT_shadow - -// XXX: add to statistics -CLightShadows::CLightShadows() : xrc("LightShadows") -{ - current = nullptr; - rt_size = 0; - - // - recreate_rt(); - - if (RImplementation.o.ffp) - { - sh_Texture.create("effects\\shadow_texture"); - if (!sh_Texture) - { - CBlender_ShTex blender; - sh_Texture.create(&blender, "effects\\shadow_texture"); - } - } - - sh_World.create("effects" DELIMITER "shadow_world", r1_RT_shadow); - geom_World.create(FVF::F_LIT, RImplementation.Vertex.Buffer(), nullptr); - - if (RImplementation.o.ffp) - { - CBlender_Blur blender; - - sh_BlurTR.create("effects\\blur", TWO_TEMP_TEXTURES); - if (!sh_BlurTR) - sh_BlurTR.create(&blender, "effects\\blur", TWO_TEMP_TEXTURES); - - sh_BlurRT.create("effects\\blur", TWO_SHADOW_TEXTURES); - if (!sh_BlurRT) - sh_BlurRT.create(&blender, "effects\\blur", TWO_SHADOW_TEXTURES); - - geom_Blur.create(FVF::F_TL2uv, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); - } - else - { - sh_BlurTR.create("blur4", TWO_TEMP_TEXTURES); - sh_BlurRT.create("blur4", TWO_SHADOW_TEXTURES); - geom_Blur.create(FVF::F_TL4uv, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); - } - - // Debug - sh_Screen.create("effects" DELIMITER "screen_set", r1_RT_shadow); - geom_Screen.create(FVF::F_TL, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); -} - -CLightShadows::~CLightShadows() -{ - // Debug - sh_Screen.destroy(); - geom_Screen.destroy(); - - geom_Blur.destroy(); - geom_World.destroy(); - - sh_BlurRT.destroy(); - sh_BlurTR.destroy(); - sh_World.destroy(); - rt_temp.destroy(); - rt_shadow.destroy(); - - // casters - for (u32 it = 0; it < casters_pool.size(); it++) - xr_delete(casters_pool[it]); - casters_pool.clear(); - - // cache - for (u32 it = 0; it < cache.size(); it++) - xr_free(cache[it].tris); - cache.clear(); -} - -void CLightShadows::set_object(IRenderable* O) -{ - if (current == O) - return; - - if (nullptr == O) - current = nullptr; - else - { - if (!O->renderable_ShadowGenerate() || O->renderable_HUD() || - ((CROS_impl*)O->renderable_ROS())->shadow_gen_frame == Device.dwFrame) - { - current = nullptr; - return; - } - - const vis_data& vis = O->GetRenderData().visual->getVisData(); - Fvector C; - O->GetRenderData().xform.transform_tiny(C, vis.sphere.P); - float R = vis.sphere.R; - float D = C.distance_to(Device.vCameraPosition) + R; - // D=0 -> P=0; - // R P=max, R>S_ideal_size -> P=min - float _priority = (D / S_distance) * (S_ideal_size / (R + EPS)); - if (_priority < 1.f) - current = O; - else - current = nullptr; - - if (current) - { - ((CROS_impl*)O->renderable_ROS())->shadow_gen_frame = Device.dwFrame; - - // alloc - caster* cs = nullptr; - if (casters_pool.empty()) - cs = xr_new(); - else - { - cs = casters_pool.back(); - casters_pool.pop_back(); - } - - // - casters.push_back(cs); - cs->O = current; - cs->C = C; - cs->D = D; - cs->nodes.clear(); - } - } -} - -void CLightShadows::add_element(const NODE& N) -{ - if (nullptr == current) - return; - VERIFY2(casters.back()->nodes.size() < 24, "Object exceeds limit of 24 renderable parts/materials"); - if (nullptr == N.pVisual->shader->E[SE_R1_LMODELS]._get()) - return; - casters.back()->nodes.push_back(N); -} - -// -void CLightShadows::calculate() -{ -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("CLightShadows::calculate()"); -#endif // _GPA_ENABLED - - if (casters.empty()) - return; - - auto& dsgraph = RImplementation.get_imm_context(); - - BOOL bRTS = FALSE; - RCache.set_Z(false); - - if (rt_size != ps_r2_smapsize / 2) - recreate_rt(); - - // iterate on objects - int slot_id = 0; - int s_size = int(rt_size * ps_r2_ls_squality / (512 / 85)); - int slot_line = rt_size / s_size; - int slot_max = slot_line * slot_line; - const float eps = 2 * EPS_L; - for (u32 o_it = 0; o_it < casters.size(); o_it++) - { - caster& C = *casters[o_it]; - if (C.nodes.empty()) - continue; - - // Select lights and calc importance - CROS_impl* LT = (CROS_impl*)C.O->renderable_ROS(); - xr_vector& lights = LT->lights; - - // iterate on lights - for (u32 l_it = 0; (l_it < lights.size()) && (slot_id < slot_max); l_it++) - { - CROS_impl::Light& L = lights[l_it]; - if (L.energy < S_level) - continue; - - // Msg ("~ light: %d",l_it); - - // setup rt+state(s) for first use - if (!bRTS) - { - bRTS = TRUE; - RCache.set_RT(rt_temp->pRT); - RCache.set_ZB(RImplementation.Target->rt_temp_zb->pRT); - if (RImplementation.o.ffp) - RCache.set_Shader(sh_Texture); - RCache.ClearRT(rt_temp, { 1.0f, 1.0f, 1.0f, 1.0f }); - } - - // calculate light center - Fvector Lpos = L.source->position; - float Lrange = L.source->range; - // Log ("* l-pos:",Lpos); - // Msg ("* l-range: %f",Lrange); - if (L.source->flags.type == IRender_Light::DIRECT) - { - // Msg (" -direct- : %f",L.energy); - Lpos.mul(L.source->direction, -100); - Lpos.add(C.C); - Lrange = 120; - } - else - { - VERIFY(_valid(Lpos)); - VERIFY(_valid(C.C)); - float _dist; - while (true) - { - _dist = C.C.distance_to(Lpos); - // Msg ("* o-dist: %f", _dist); - if (_dist > EPS_L) - break; - Lpos.y += .01f; //. hack to avoid light-in-the-center-of-object - } - const float radius = C.O->GetRenderData().visual->getVisData().sphere.R + 0.1f; - // Msg ("* o-r: %f", radius); - if (_dist < radius) - { - Fvector Ldir; - Ldir.sub(C.C, Lpos); - Ldir.normalize(); - Lpos.mad(Lpos, Ldir, _dist - radius); - // Msg ("* moving lpos"); - } - } - - // calculate projection-matrix - Fmatrix mProject, mProjectR; - float p_dist = C.C.distance_to(Lpos); - float p_R = C.O->GetRenderData().visual->getVisData().sphere.R; - float p_hat = p_R / p_dist; - float p_asp = 1.f; - float p_near = p_dist - p_R - eps; - // float p_nearR = C.C.distance_to(L.source->position) + p_R*0.85f + eps; - // p_nearR = p_near; - float p_far = std::min(Lrange, std::max(p_dist + S_fade, p_dist + p_R)); - if (p_near < eps) - continue; - if (p_far < (p_near + eps)) - continue; - // Igor: make check here instead of assertion in buil_projection_hat - if (!(_abs(p_far - p_near) > eps)) - continue; - if (p_hat > 0.9f) - continue; - if (p_hat < 0.01f) - continue; - - // Msg ("* near(%f), near-x(%f)",p_near,p_nearR); - - mProject.build_projection_HAT(p_hat, p_asp, p_near, p_far); - // Igor: strange bug with building projection_hat - // building projection with the same parameters fails for the - // second time - // mProjectR.build_projection_HAT (p_hat,p_asp,p_nearR, p_far); - mProjectR = mProject; - RCache.set_xform_project(mProject); - - // calculate view-matrix - Fmatrix mView; - Fvector v_D, v_N, v_R; - v_D.sub(C.C, Lpos); - v_D.normalize(); - if (1 - _abs(v_D.y) < EPS) - v_N.set(1, 0, 0); - else - v_N.set(0, 1, 0); - v_R.crossproduct(v_N, v_D); - v_N.crossproduct(v_D, v_R); - mView.build_camera(Lpos, C.C, v_N); - RCache.set_xform_view(mView); - - // combine and build frustum - Fmatrix mCombine, mCombineR; - mCombine.mul(mProject, mView); - mCombineR.mul(mProjectR, mView); - - // Select slot and set viewport - int s_x = slot_id % slot_line; - int s_y = slot_id / slot_line; - const D3D_VIEWPORT viewport = { s_x * s_size, s_y * s_size, s_size, s_size, 0.f, 1.f }; - RCache.SetViewport(viewport); - - // Render object-parts - for (u32 n_it = 0; n_it < C.nodes.size(); n_it++) - { - NODE& N = C.nodes[n_it]; - dxRender_Visual* V = N.pVisual; - if (!RImplementation.o.ffp) - RCache.set_Element(V->shader->E[SE_R1_LMODELS]); - RCache.set_xform_world(N.Matrix); - V->Render(RCache, -1.0f, dsgraph.o.phase == CRender::PHASE_SMAP); - } - - // register shadow and increment slot - shadows.push_back(shadow()); - shadows.back().O = C.O; - shadows.back().slot = slot_id; - shadows.back().C = C.C; - shadows.back().M = mCombineR; - shadows.back().L = L.source; - shadows.back().E = L.energy; -#ifdef DEBUG - shadows.back().dbg_HAT = p_hat; -#endif - slot_id++; - } - } - - // clear casters - for (u32 cs = 0; cs < casters.size(); cs++) - casters_pool.push_back(casters[cs]); - casters.clear(); - - // Blur - if (bRTS) - { - // Fill VB - u32 Offset; - if (RImplementation.o.ffp) - { - FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(8, geom_Blur.stride(), Offset); - RImplementation.ApplyBlur2(pv, rt_size); - RImplementation.Vertex.Unlock(8, geom_Blur.stride()); - } - else - { - FVF::TL4uv* pv = (FVF::TL4uv*)RImplementation.Vertex.Lock(4, geom_Blur.stride(), Offset); - RImplementation.ApplyBlur4(pv, rt_size, rt_size, S_blur_kernel); - RImplementation.Vertex.Unlock(4, geom_Blur.stride()); - } - - // Actual rendering (pass0, temp2real) - RCache.set_RT(rt_shadow->pRT); - RCache.set_ZB(RImplementation.Target->rt_temp_zb->pRT); - RCache.set_Shader(sh_BlurTR); - RCache.set_Geometry(geom_Blur); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // Finita la comedia - RCache.set_Z(true); - - RCache.set_xform_project(Device.mProject); - RCache.set_xform_view(Device.mView); -} - -#define CLS(a) color_rgba(a, a, a, a) - -inline bool cache_search(const CLightShadows::cache_item& A, const CLightShadows::cache_item& B) -{ - if (A.O < B.O) - return true; - if (A.O > B.O) - return false; - if (A.L < B.L) - return true; - if (A.L > B.L) - return false; - return false; // eq -} - -static ICF float PLC_energy_SSE(const Fvector& p, const Fvector& n, const light* L, float e) -{ - Fvector lDir; - if (L->flags.type == IRender_Light::DIRECT) - { - // Cos - lDir.invert(L->direction); - const float D = lDir.dotproduct(n); - if (D <= 0) - return 0; - return e; - } - // Distance - const float sqD = p.distance_to_sqr(L->position); - if (sqD > L->range * L->range) - return 0; - // Dir - lDir.sub(L->position, p); - lDir.normalize_safe(); - const float D = lDir.dotproduct(n); - if (D <= 0) - return 0; - - // Trace Light - if (RImplementation.o.ffp) - { - const auto& ldata = L->ldata; - const float R = _sqrt(sqD); - const float A = D * e / (ldata.attenuation0 + ldata.attenuation1 * R + ldata.attenuation2 * sqD); - return A; - } - __m128 rcpr = _mm_rsqrt_ss(_mm_load_ss(&sqD)); - rcpr = _mm_rcp_ss(_mm_add_ss(rcpr, _mm_set_ss(1.0f))); - float att; - _mm_store_ss(&att, rcpr); - return e * att; -} - -static ICF int iCeil_SSE(float x) { return _mm_cvt_ss2si(_mm_set_ss(x)); } -void PLCCalc(int& c0, int& c1, int& c2, const Fvector& camPos, const Fvector* ps, const Fvector& n, const light* l, - float energy, const Fvector& obj) -{ - float e = PLC_energy_SSE(ps[0], n, l, energy); - float nc1 = clampr(camPos.distance_to_sqr(ps[0]) / S_distance2, 0.f, 1.f); - float nc2 = clampr(obj.distance_to_sqr(ps[0]) / S_fade2, 0.f, 1.f); - float a = 1.f - 1.5f * e * (1.f - nc1) * (1.f - nc2); - c0 = iCeil_SSE(255.f * a); - e = PLC_energy_SSE(ps[1], n, l, energy); - nc1 = clampr(camPos.distance_to_sqr(ps[1]) / S_distance2, 0.f, 1.f); - nc2 = clampr(obj.distance_to_sqr(ps[1]) / S_fade2, 0.f, 1.f); - a = 1.f - 1.5f * e * (1.f - nc1) * (1.f - nc2); - c1 = iCeil_SSE(255.f * a); - e = PLC_energy_SSE(ps[2], n, l, energy); - nc1 = clampr(camPos.distance_to_sqr(ps[2]) / S_distance2, 0.f, 1.f); - nc2 = clampr(obj.distance_to_sqr(ps[2]) / S_fade2, 0.f, 1.f); - a = 1.f - 1.5f * e * (1.f - nc1) * (1.f - nc2); - c2 = iCeil_SSE(255.f * a); -} - -void CLightShadows::render() -{ - // Gain access to collision-DB - CDB::MODEL* DB = g_pGameLevel->ObjectSpace.GetStaticModel(); - CDB::TRI* TRIS = DB->get_tris(); - Fvector* VERTS = DB->get_verts(); - - int s_size = int(rt_size * ps_r2_ls_squality / (512 / 85)); - int slot_line = rt_size / s_size; - - // Projection and xform - float _43 = Device.mProject._43; - - // Handle biasing problem when near changes - const float fMinNear = 0.1f; - const float fMaxNear = 0.2f; - const float fMinNearBias = 0.0002f; - const float fMaxNearBias = 0.002f; - float fLerpCoeff = (_43 - fMinNear) / (fMaxNear - fMinNear); - clamp(fLerpCoeff, 0.0f, 1.0f); - // lerp - Device.mProject._43 -= fMinNearBias + (fMaxNearBias - fMinNearBias) * fLerpCoeff; - // Device.mProject._43 -= 0.0002f; - Device.mProject._43 -= 0.002f; - // Device.mProject._43 -= 0.0008f; - RCache.set_xform_world(Fidentity); - RCache.set_xform_project(Device.mProject); - Fvector View = Device.vCameraPosition; - - // Render shadows - RCache.set_Shader(sh_World); - RCache.set_Geometry(geom_World); - int batch = 0; - u32 Offset = 0; - FVF::LIT* pv = (FVF::LIT*)RImplementation.Vertex.Lock(batch_size * 3, geom_World->vb_stride, Offset); - for (u32 s_it = 0; s_it < shadows.size(); s_it++) - { - shadow& S = shadows[s_it]; - float Le = RImplementation.o.ffp ? S.L->ldata.diffuse.magnitude_rgb() : S.L->color.intensity() * S.E; - int s_x = S.slot % slot_line; - int s_y = S.slot / slot_line; - Fvector2 t_scale, t_offset; - t_scale.set(float(s_size) / float(rt_size), float(s_size) / float(rt_size)); - t_scale.mul(.5f); - t_offset.set(float(s_x) / float(slot_line), float(s_y) / float(slot_line)); - t_offset.x += .5f / rt_size; - t_offset.y += .5f / rt_size; - - // Search the cache - cache_item* CI = nullptr; - BOOL bValid = FALSE; - cache_item CI_what; - CI_what.O = S.O; - CI_what.L = S.L; - CI_what.tris = nullptr; - xr_vector::iterator CI_ptr = std::lower_bound(cache.begin(), cache.end(), CI_what, cache_search); - if (CI_ptr == cache.end()) - { // empty ? - CI_ptr = cache.insert(CI_ptr, CI_what); - CI = &*CI_ptr; - bValid = FALSE; - } - else - { - if (CI_ptr->O != CI_what.O || CI_ptr->L != CI_what.L) - { // we found something different - CI_ptr = cache.insert(CI_ptr, CI_what); - CI = &*CI_ptr; - bValid = FALSE; - } - else - { - // Everything, OK. Check if info is still relevant... - CI = &*CI_ptr; - bValid = TRUE; - if (!CI->Op.similar(CI->O->GetRenderData().xform.c)) - bValid = FALSE; - else if (!CI->Lp.similar(CI->L->position)) - bValid = FALSE; - } - } - CI->time = Device.dwTimeGlobal; // acess time - - if (!bValid) - { - // Frustum - CFrustum F; - F.CreateFromMatrix(S.M, FRUSTUM_P_ALL); - - // Query - xrc.frustum_query(0, DB, F); - if (0 == xrc.r_count()) - continue; - - // Clip polys by frustum - tess.clear(); - for (auto &p : *xrc.r_get()) - { - VERIFY((p.id >= 0) && (p.id < DB->get_tris_count())); - // - CDB::TRI& t = TRIS[p.id]; - if (t.suppress_shadows) - continue; - sPoly A, B; - A.push_back(VERTS[t.verts[0]]); - A.push_back(VERTS[t.verts[1]]); - A.push_back(VERTS[t.verts[2]]); - - // Calc plane, throw away degenerate tris and invisible to light polygons - Fplane P; - float mag = 0; - Fvector t1, t2, n; - t1.sub(A[0], A[1]); - t2.sub(A[0], A[2]); - n.crossproduct(t1, t2); - mag = n.square_magnitude(); - if (mag < EPS_S) - continue; - n.mul(1.f / _sqrt(mag)); - P.build_unit_normal(A[0], n); - float DOT_Fade = P.classify(S.L->position); - if (DOT_Fade < 0) - continue; - - // Clip polygon - sPoly* clip = F.ClipPoly(A, B); - if (nullptr == clip) - continue; - - // Triangulate poly - for (u32 v = 2; v < clip->size(); v++) - { - tess.push_back(tess_tri()); - tess_tri& T = tess.back(); - T.v[0] = (*clip)[0]; - T.v[1] = (*clip)[v - 1]; - T.v[2] = (*clip)[v]; - T.N = P.n; - } - } - - // Remember params which builded cache item - CI->O = S.O; - CI->Op = CI->O->GetRenderData().xform.c; - CI->L = S.L; - CI->Lp = CI->L->position; - CI->tcnt = tess.size(); - // Msg ("---free--- %x",u32(CI->tris)); - xr_free(CI->tris); - VERIFY(nullptr == CI->tris); - if (tess.size()) - { - CI->tris = xr_alloc(CI->tcnt); - // Msg ("---alloc--- %x",u32(CI->tris)); - CopyMemory(CI->tris, &*tess.begin(), CI->tcnt * sizeof(tess_tri)); - } - } - - // Fill VB - for (u32 tid = 0; tid < CI->tcnt; tid++) - { - tess_tri& TT = CI->tris[tid]; - Fvector* v = TT.v; - Fvector T; - Fplane ttp; - ttp.build_unit_normal(v[0], TT.N); - - if (ttp.classify(View) < 0) - continue; - - int c0, c1, c2; - PLCCalc(c0, c1, c2, Device.vCameraPosition, v, TT.N, S.L, Le, S.C); - - if (c0 > S_clip && c1 > S_clip && c2 > S_clip) - continue; - clamp(c0, S_ambient, 255); - clamp(c1, S_ambient, 255); - clamp(c2, S_ambient, 255); - - S.M.transform(T, v[0]); - pv->set(v[0], CLS(c0), (T.x + 1) * t_scale.x + t_offset.x, (1 - T.y) * t_scale.y + t_offset.y); - pv++; - S.M.transform(T, v[1]); - pv->set(v[1], CLS(c1), (T.x + 1) * t_scale.x + t_offset.x, (1 - T.y) * t_scale.y + t_offset.y); - pv++; - S.M.transform(T, v[2]); - pv->set(v[2], CLS(c2), (T.x + 1) * t_scale.x + t_offset.x, (1 - T.y) * t_scale.y + t_offset.y); - pv++; - - batch++; - if (batch == batch_size) - { - // Flush - RImplementation.Vertex.Unlock(batch * 3, geom_World->vb_stride); - RCache.Render(D3DPT_TRIANGLELIST, Offset, batch); - - pv = (FVF::LIT*)RImplementation.Vertex.Lock(batch_size * 3, geom_World->vb_stride, Offset); - batch = 0; - } - } - } - - // Flush if nessesary - RImplementation.Vertex.Unlock(batch * 3, geom_World->vb_stride); - if (batch) - { - RCache.Render(D3DPT_TRIANGLELIST, Offset, batch); - } - - // Clear all shadows and free old entries in the cache - shadows.clear(); - for (int cit = 0; cit < int(cache.size()); cit++) - { - cache_item& ci = cache[cit]; - u32 time = Device.dwTimeGlobal - ci.time; - if (time > cache_old) - { - // Msg ("---free--- %x",u32(ci.tris)); - xr_free(ci.tris); - VERIFY(nullptr == ci.tris); - cache.erase(cache.begin() + cit); - cit--; - } - } - - // Projection - Device.mProject._43 = _43; - RCache.set_xform_project(Device.mProject); -} diff --git a/src/Layers/xrRenderPC_R1/LightShadows.h b/src/Layers/xrRenderPC_R1/LightShadows.h deleted file mode 100644 index 7e097826a55..00000000000 --- a/src/Layers/xrRenderPC_R1/LightShadows.h +++ /dev/null @@ -1,92 +0,0 @@ -#if !defined(AFX_LIGHTSHADOWS_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_) -#define AFX_LIGHTSHADOWS_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_ -#pragma once - -#include "Layers/xrRender/light.h" -#include "Layers/xrRender/r__dsgraph_types.h" - -class CLightShadows -{ -private: - // - typedef R_dsgraph::_MatrixItem NODE; - struct caster - { - IRenderable* O; - Fvector C; - float D; - xr_vector nodes; - }; - struct shadow - { -#ifdef DEBUG - float dbg_HAT; -#endif - IRenderable* O; - int slot; - Fvector C; - Fmatrix M; - light* L; - float E; - }; - struct tess_tri - { - Fvector v[3]; - Fvector N; - }; - -public: - struct cache_item - { - IRenderable* O; - Fvector Op; - light* L; - Fvector Lp; - u32 time; - tess_tri* tris; - u32 tcnt; - - cache_item() - { - O = nullptr; - L = nullptr; - tris = nullptr; - } - }; - -private: - IRenderable* current; - xr_vector casters_pool; - xr_vector casters; - xr_vector shadows; - xr_vector tess; - xr_vector cache; - xrXRC xrc; - - ref_rt rt_shadow; - ref_rt rt_temp; - ref_shader sh_Texture; - ref_shader sh_BlurTR; - ref_shader sh_BlurRT; - ref_geom geom_Blur; - ref_shader sh_World; - ref_geom geom_World; - ref_shader sh_Screen; - ref_geom geom_Screen; - - u32 rt_size; - -private: - void recreate_rt(); - -public: - void set_object(IRenderable* O); - void add_element(const NODE& N); - void calculate(); - void render(); - - CLightShadows(); - ~CLightShadows(); -}; - -#endif // !defined(AFX_LIGHTSHADOWS_H__CFA216D9_CACB_4515_9FBE_7C531649168F__INCLUDED_) diff --git a/src/Layers/xrRenderPC_R1/Pipeline.txt b/src/Layers/xrRenderPC_R1/Pipeline.txt deleted file mode 100644 index f9eb41541fe..00000000000 --- a/src/Layers/xrRenderPC_R1/Pipeline.txt +++ /dev/null @@ -1,65 +0,0 @@ -hw-cull: - 1. divide into two parts: - untested(occluder), tested(occludee) - - render occluder geometry -> create pending list - get results for previous frame -> mark invisible nodes as "invisible" - render pending list -> - -state: - visible : - verify/probe : test real object - invisible : test box - - -new object entered : - - - - - - - - - - -lmapped -------------------------------------------------------------------------------- -input: - constants: - hemi_color - vector - sun_color - vector - sun_dir - vector - lmap_color - vector (other lights) - vertex: - tc0 - base () - tc1 - lmap () - diffuse.rgb - ??? - diffuse.a - hemi-occlusion - COLOR_0 - normal - for lighting - COLOR_1 - vertex-math: - diffuse = hemi_color * vertex.diffuse.a - specular = light_direct(sun_color,sun_dir,vertex.normal) - pixel: - t_diff = tex(diffuse) - t_lmap = tex(lmap) - light = t_lmap.rgb * lmap_color + diffuse.rgb(hemi + ) + specular.rgb(sun)*t_lmap.a - out := (t_diff * light)x2; - -------------------------------------------------------------------------------- -vertex -------------------------------------------------------------------------------- - constants: - hemi_color - vector - sun_color - vector - sun_dir - vector - lmap_color - vector (other lights) - vertex: - diffuse.rgb - other-lights - COLOR_0 - diffuse.a - hemi-occlusion - normal - for lighting - normal.a - dir-occlusion - COLOR_1 (???) -------------------------------------------------------------------------------- -rgb - all static lights | lmap : lmap.rgb | vert: diffuse.rgb | mu: diffuse.rgb*Argb+Brgb | models: prj+dlights -hemi - hemisphere | diffuse.a | diffuse.a | diffuse.a*Ah+Bh | prj -sun - sun | lmap.a | normal.a | diffuse.a*As+Bs | prj+dlights diff --git a/src/Layers/xrRenderPC_R1/packages.config b/src/Layers/xrRenderPC_R1/packages.config deleted file mode 100644 index 86b0d14a90d..00000000000 --- a/src/Layers/xrRenderPC_R1/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_R1/stdafx.cpp b/src/Layers/xrRenderPC_R1/stdafx.cpp deleted file mode 100644 index 726a13677a0..00000000000 --- a/src/Layers/xrRenderPC_R1/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// xrRender_R1.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/src/Layers/xrRenderPC_R1/stdafx.h b/src/Layers/xrRenderPC_R1/stdafx.h deleted file mode 100644 index 91ae6bf2e2b..00000000000 --- a/src/Layers/xrRenderPC_R1/stdafx.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" - -#include "xrEngine/stdafx.h" - -#include "xrEngine/vis_common.h" -#include "xrEngine/Render.h" -#include "xrEngine/IGame_Level.h" - -#include "xrParticles/psystem.h" - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#include - -#include "Layers/xrRenderDX9/CommonTypes.h" - -#include "Layers/xrRenderDX9/dx9HW.h" - -#include "Layers/xrRender/BufferUtils.h" - -#include "Layers/xrRender/Shader.h" - -#include "Layers/xrRender/R_Backend.h" -#include "Layers/xrRender/R_Backend_Runtime.h" - -#include "Layers/xrRender/Blender.h" -#include "Layers/xrRender/Blender_CLSID.h" - -#define R_GL 0 -#define R_R1 1 -#define R_R2 2 -#define R_R3 3 -#define R_R4 4 -#define RENDER R_R1 - -#include "Common/_d3d_extensions.h" - -#include "Layers/xrRender/ResourceManager.h" -#include "Layers/xrRender/xrRender_console.h" - -#include "FStaticRender.h" - -#define TEX_POINT_ATT "internal" DELIMITER "internal_light_attpoint" -#define TEX_SPOT_ATT "internal" DELIMITER "internal_light_attclip" diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.cpp b/src/Layers/xrRenderPC_R1/xrRender_R1.cpp deleted file mode 100644 index cae34c3f3bb..00000000000 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "stdafx.h" - -#include "Layers/xrRender/dxRenderFactory.h" -#include "Layers/xrRender/dxUIRender.h" -#include "Layers/xrRender/dxDebugRender.h" -#include "Layers/xrRender/D3DUtils.h" - -#include "Layers/xrRenderDX9/dx9shader_utils.h" - -constexpr pcstr RENDERER_R1_MODE = "renderer_r1"; - -class R1RendererModule final : public RendererModule -{ - xr_vector modes; - -public: - bool CheckCanAddMode() const - { - // don't duplicate - if (!modes.empty()) - { - return false; - } - // Check if shaders are available - if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) - { - Log("~ No shaders found for xrRender_R1"); - return false; - } - CHW hw; - hw.CreateD3D(); - const bool result = hw.pD3D && hw.pD3D->GetAdapterCount() > 0; - hw.DestroyD3D(); - -#ifdef USE_D3DX - const bool shaderCompilerAvailable = XRay::ModuleHandle{ "d3dx9_31" }.IsLoaded(); -#else - constexpr bool shaderCompilerAvailable = true; -#endif - - return result && shaderCompilerAvailable; - } - - const xr_vector& ObtainSupportedModes() override - { - if (CheckCanAddMode()) - { - modes.emplace_back(RENDERER_R1_MODE); - } - return modes; - } - - void CheckModeConsistency(pcstr mode) const - { - R_ASSERT3(0 == xr_strcmp(mode, RENDERER_R1_MODE), - "Wrong mode passed to xrRender_R1", mode); - } - - void SetupEnv(pcstr mode) override - { - CheckModeConsistency(mode); - GEnv.Render = &RImplementation; - GEnv.RenderFactory = &RenderFactoryImpl; - GEnv.DU = &DUImpl; - GEnv.UIRender = &UIRenderImpl; -#ifdef DEBUG - GEnv.DRender = &DebugRenderImpl; -#endif - xrRender_initconsole(); - } -} static s_r1_module; - -extern "C" -{ -XR_EXPORT RendererModule* GetRendererModule() -{ - return &s_r1_module; -} -} diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj deleted file mode 100644 index 489a7a4094b..00000000000 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} - xrRender_R1 - Win32Proj - - - - - - - x64 - - - - - - - - - - - - $(xrExternals)imgui;$(xrExternals)OpenAutomate\inc;$(xrSdkDir)include\nvapi;$(xrSdkDir)include\DirectXMesh;%(AdditionalIncludeDirectories) - _USRDLL;XRRENDER_R1_EXPORTS;USE_DX9;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - nvapi$(PlatformArchitecture).lib;%(AdditionalDependencies) - $(xrExternals)OpenAutomate\libraries;%(AdditionalLibraryDirectories) - $(xrExternals)nvapi\x86;%(AdditionalLibraryDirectories) - $(xrExternals)nvapi\amd64;%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - - - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {2578c6d8-660d-48ae-9322-7422f8664f06} - - - {94a1c366-3d19-48e6-8170-4adc2e70df97} - - - {132c62de-de85-4978-9675-c78ed4da46f0} - - - {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {ccd4afae-aa10-42c6-a452-fdee497ccdf1} - - - {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - - {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} - - - {2c419512-6eee-4707-bc51-2e834855552e} - - - - - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters b/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters deleted file mode 100644 index 546a5c031b4..00000000000 --- a/src/Layers/xrRenderPC_R1/xrRender_R1.vcxproj.filters +++ /dev/null @@ -1,1035 +0,0 @@ - - - - - {d20e30ac-a0c2-4c5d-9c5d-98239175f95d} - - - {aa70fc28-ad7e-4c84-923b-67e5bad0bb22} - - - {94289d53-8bce-47ee-b6a3-7bd40f187842} - - - {56b1ef7c-d745-47a9-b97a-ecfda1685ee6} - - - {e335f18b-e79a-4a63-ad42-2635fae165ca} - - - {5a2a6297-0742-4e10-ad9d-148429119c67} - - - {f362ac90-e081-4ae5-bf82-2afaff5e3b8d} - - - {62f446be-e40c-45cb-b678-13fbaf88f103} - - - {f61d78ad-8bc5-4ee3-887a-b99735247683} - - - {b751bdf8-4824-46ad-9c71-a83becefb71c} - - - {67c6d54d-5182-4f90-b236-8eb5b15e3cbe} - - - {ea428694-2b88-4d5d-8ccf-9867535a0128} - - - {38d0807c-eb1a-4719-8f31-d3a62dbcd99b} - - - {b015ca6a-d62c-4bcf-aa05-964d95101276} - - - {fb91aa85-38a4-44c4-988e-a6c4608e421a} - - - {4bc3705f-0312-42a9-9c04-71a4e17647d2} - - - {66d08dfb-b689-48d3-9f9c-58e949f5e6c7} - - - {8e643d5a-2333-414d-94d0-bd3b6af60ca4} - - - {3bd0be1c-3d2a-4d1c-b6ba-edb4ac3ad03f} - - - {ccd303ff-7af1-40dc-9900-5695143286c6} - - - {8842d9db-0ed0-485a-8c4c-593be3902820} - - - {5abddc08-e7aa-430e-9d1b-cca64b08b0fc} - - - {7d42b98b-7ac3-4006-9966-e35ea8237855} - - - {334782cb-bef8-436e-b8b7-5fc24b84fa03} - - - {acc438b5-6f37-45ea-bb13-d5e31298b733} - - - {2f617ea1-91cd-4273-81f3-71333014a1a6} - - - {81602497-3433-41cd-99df-828e0f3b33e2} - - - {70abdbe0-5414-4c57-84d3-3c87db6afe4a} - - - {025a08f5-9104-413d-b196-d537225343b0} - - - {142a12fd-bffd-4b0b-8c71-b3377a72a53d} - - - {f868f8bf-e10d-4fa4-800f-7b6ae4d2cac0} - - - {e23ab82d-de2d-4d32-a7ec-fa4628b63982} - - - {abff5563-b6a9-4373-b73c-2f68342e9056} - - - {5943c1a5-d8da-4b83-987e-8fa360e74a33} - - - {8395d7ee-36d7-4976-904d-da14a7441e4c} - - - {ee69b180-c562-417f-8c86-924cf5f3a989} - - - {08063a0f-5fd4-4fe0-b225-eee710ef1c1e} - - - {51e44ec6-6871-4bc1-b4bb-c331c2e64244} - - - {b0161bfa-db03-487f-b3e2-334cd1ad0375} - - - {d345b891-53f6-4a48-ae0b-a842420cd7f5} - - - {db38553d-ce02-45a5-b88d-08b43f73e71e} - - - {30e655d3-a486-47c4-8d8e-08698e168ced} - - - {d118a1ec-f8d6-4dbf-9d05-d5b5be72beaa} - - - {12b2bbc5-3ac4-4d4a-bb6e-c6731ab67487} - - - {1c1d6ff9-2dc4-4417-8633-908ed69079b1} - - - {46b96d75-9c27-4322-b372-4981f0618cb0} - - - {b4233fe2-78dd-48d9-94ff-620753340597} - - - {8b1f96de-4574-4866-a5c0-371b1d2d7a17} - - - {7d69ca51-2287-4521-a2e2-24e530c955ba} - - - - - Kernel - - - Kernel - - - Core - - - Core - - - Core - - - Core - - - Core\ColorMap - - - Details - - - Details - - - Details - - - Stripifier - - - Stripifier - - - Stripifier - - - Stripifier - - - Glows - - - Wallmarks - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Visibility\Sector/Portal - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Interface implementations\RenderFactory - - - Interface implementations\RenderFactory - - - Interface implementations\LensFlare - - - Interface implementations\LensFlare - - - Interface implementations\FactoryPtr - - - Interface implementations\RainRender - - - Interface implementations\RainRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\FontRender - - - Interface implementations\FontRender - - - Interface implementations\WallMarkArray - - - Interface implementations\WallMarkArray - - - Interface implementations\StatGraphRender - - - Interface implementations\StatGraphRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\Debug - - - Interface implementations\Debug\DebugRender - - - Interface implementations\Debug\DebugRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UISequenceVideoItem - - - Interface implementations\UI\UISequenceVideoItem - - - Refactored\HW - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Gamma - - - Refactored\Interfaces - - - Refactored\Interfaces - - - Refactored\stats_manager - - - Models - - - Models - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Core - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\HW - - - Kernel - - - Refactored\HW - - - Models\Visuals - - - Core - - - Core - - - Debug - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Interface implementations\ImGuiRender - - - Interface implementations\ImGuiRender - - - Shading templates - - - Shading templates - - - Refactored\Execution & 3D\Shaders\Resources - - - Lights - - - - - Kernel - - - Kernel - - - Kernel - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core\ColorMap - - - Details - - - Details - - - Details - - - Details - - - Details - - - Details - - - Stripifier - - - Stripifier - - - Stripifier - - - Stripifier - - - Glows - - - Wallmarks - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Visibility\Sector/Portal - - - Visibility\Sector/Portal - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Interface implementations\RenderFactory - - - Interface implementations\LensFlare - - - Interface implementations\RainRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\FontRender - - - Interface implementations\WallMarkArray - - - Interface implementations\StatGraphRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\Debug\DebugRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UISequenceVideoItem - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Gamma - - - Refactored\stats_manager - - - Models - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Core - - - Core - - - Refactored\HW - - - Refactored\HW - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\HW - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Visibility\Sector/Portal - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Interface implementations\ImGuiRender - - - Shading templates - - - Shading templates - - - Details - - - Core - - - Refactored\Execution & 3D\Shaders\Resources - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_R2/CMakeLists.txt b/src/Layers/xrRenderPC_R2/CMakeLists.txt deleted file mode 100644 index b38400485b9..00000000000 --- a/src/Layers/xrRenderPC_R2/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -add_library(xrRenderPC_R2 SHARED) - -target_sources(xrRenderPC_R2 PRIVATE - Light_Render_Direct_ComputeXFS.cpp - r2_rendertarget.h - r2_rendertarget_accum_direct.cpp - r2_rendertarget_accum_point.cpp - r2_rendertarget_accum_spot.cpp - r2_rendertarget_build_textures.cpp - r2_rendertarget_phase_combine.cpp - r2_rendertarget_phase_occq.cpp - r2_rendertarget_phase_scene.cpp - r2_rendertarget_phase_smap_D.cpp - r2_rendertarget_phase_ssao.cpp - r2_rendertarget_u_set_rt.cpp - r2_shaders.cpp - r2_test_hw.cpp - stdafx.cpp - stdafx.h - xrRender_R2.cpp -) - -target_include_directories(xrRenderPC_R2 - PRIVATE - "${CMAKE_SOURCE_DIR}/src" - "${CMAKE_SOURCE_DIR}/sdk/include" -) - -target_link_libraries(xrRenderPC_R2 - PRIVATE - xrCore - xrCDB - xrEngine - xrParticles - xrScriptEngine - xrAPI - xrMiscMath -) - -target_compile_definitions(xrRenderPC_R2 - PRIVATE - XRRENDER_R2_EXPORTS -) - -set_target_properties(xrRenderPC_R2 PROPERTIES - PREFIX "" -) - -target_precompile_headers(xrRenderPC_R2 - PRIVATE - stdafx.h -) - -install(TARGETS xrRenderPC_R2 LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) diff --git a/src/Layers/xrRenderPC_R2/Light_Render_Direct_ComputeXFS.cpp b/src/Layers/xrRenderPC_R2/Light_Render_Direct_ComputeXFS.cpp deleted file mode 100644 index 8880d8c3221..00000000000 --- a/src/Layers/xrRenderPC_R2/Light_Render_Direct_ComputeXFS.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "stdafx.h" -#include "light_render_direct.h" - -void CLight_Compute_XFORM_and_VIS::compute_xf_spot(light* L) -{ - // Build EYE-space xform - Fvector L_dir, L_up, L_right, L_pos; - L_dir.set(L->direction); - L_dir.normalize(); - - if (L->right.square_magnitude() > EPS) - { - // use specified 'up' and 'right', just enshure ortho-normalization - L_right.set(L->right); - L_right.normalize(); - L_up.crossproduct(L_dir, L_right); - L_up.normalize(); - L_right.crossproduct(L_up, L_dir); - L_right.normalize(); - } - else - { - // auto find 'up' and 'right' vectors - L_up.set(0, 1, 0); - if (_abs(L_up.dotproduct(L_dir)) > .99f) - L_up.set(0, 0, 1); - L_right.crossproduct(L_up, L_dir); - L_right.normalize(); - L_up.crossproduct(L_dir, L_right); - L_up.normalize(); - } - L_pos.set(L->position); - - // - int _cached_size = L->X.S.size; - L->X.S.posX = L->X.S.posY = 0; - L->X.S.size = SMAP_adapt_max; - L->X.S.transluent = FALSE; - - // Compute approximate screen area (treating it as an point light) - R*R/dist_sq - // Note: we clamp screen space area to ONE, although it is not correct at all - float dist = Device.vCameraPosition.distance_to(L->spatial.sphere.P) - L->spatial.sphere.R; - if (dist < 0) - dist = 0; - float ssa = clampr(L->range * L->range / (1.f + dist * dist), 0.f, 1.f); - - // compute intensity - float intensity0 = (L->color.r + L->color.g + L->color.b) / 3.f; - float intensity1 = (L->color.r * 0.2125f + L->color.g * 0.7154f + L->color.b * 0.0721f); - float intensity = (intensity0 + intensity1) / 2.f; // intensity1 tends to underestimate... - - // compute how much duelling frusta occurs [-1..1]-> 1 + [-0.5 .. +0.5] - float duel_dot = 1.f - 0.5f * Device.vCameraDirection.dotproduct(L_dir); - - // compute how large the light is - give more texels to larger lights, assume 8m as being optimal radius - float sizefactor = L->range / 8.f; // 4m = .5, 8m=1.f, 16m=2.f, 32m=4.f - - // compute how wide the light frustum is - assume 90deg as being optimal - float widefactor = L->cone / deg2rad(90.f); // - - // factors - float factor0 = powf(ssa, 1.f / 2.f); // ssa is quadratic - float factor1 = powf(intensity, 1.f / 16.f); // less perceptually important? - float factor2 = powf(duel_dot, 1.f / 4.f); // difficult to fast-change this -> visible - float factor3 = powf(sizefactor, 1.f / 4.f); // this shouldn't make much difference - float factor4 = powf(widefactor, 1.f / 2.f); // make it linear ??? - float factor = ps_r2_ls_squality * factor0 * factor1 * factor2 * factor3 * factor4; - - // final size calc - u32 _size = iFloor(factor * SMAP_adapt_optimal); - if (_size < SMAP_adapt_min) - _size = SMAP_adapt_min; - if (_size > SMAP_adapt_max) - _size = SMAP_adapt_max; - int _epsilon = iCeil(float(_size) * 0.01f); - int _diff = _abs(int(_size) - int(_cached_size)); - L->X.S.size = (_diff >= _epsilon) ? _size : _cached_size; - - // make N pixel border - L->X.S.view.build_camera_dir(L_pos, L_dir, L_up); - // float n = 2.f ; - // float x = float(L->X.S.size) ; - // float alpha = L->cone/2 ; - // float tan_beta = (x+2*n)*tanf(alpha) / x ; - // float g_alpha = 2*rad2deg (alpha); - // float g_beta = 2*rad2deg (atanf(tan_beta)); - // Msg ("x(%f) : a(%f), b(%f)",x,g_alpha,g_beta); - - // _min(L->cone + deg2rad(4.5f), PI*0.98f) - Here, it is needed to enlarge the shadow map frustum to include also - // displaced pixels and the pixels neighbor to the examining one. - L->X.S.project.build_projection(std::min(L->cone + deg2rad(5.f), PI * 0.98f), 1.f, SMAP_near_plane, L->range + EPS_S); - L->X.S.combine.mul(L->X.S.project, L->X.S.view); -} diff --git a/src/Layers/xrRenderPC_R2/packages.config b/src/Layers/xrRenderPC_R2/packages.config deleted file mode 100644 index 86b0d14a90d..00000000000 --- a/src/Layers/xrRenderPC_R2/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget.h b/src/Layers/xrRenderPC_R2/r2_rendertarget.h deleted file mode 100644 index 79420105091..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget.h +++ /dev/null @@ -1,333 +0,0 @@ -#pragma once - -#include "Layers/xrRender/ColorMapManager.h" - -class light; - -//#define DU_SPHERE_NUMVERTEX 92 -//#define DU_SPHERE_NUMFACES 180 -//#define DU_CONE_NUMVERTEX 18 -//#define DU_CONE_NUMFACES 32 -// no less than 2 -#define VOLUMETRIC_SLICES 100 - -class CRenderTarget : public IRender_Target -{ - u32 dwWidth[R__NUM_CONTEXTS]; - u32 dwHeight[R__NUM_CONTEXTS]; - u32 dwAccumulatorClearMark; - -public: - enum eStencilOptimizeMode - { - SO_Light = 0, // Default - SO_Combine, // Default - }; - - u32 dwLightMarkerID; - - IBlender* b_accum_spot{}; - -#ifdef DEBUG - struct dbg_line_t - { - Fvector P0, P1; - u32 color; - }; - xr_vector> dbg_spheres; - xr_vector dbg_lines; - xr_vector dbg_planes; -#endif - - // Base targets - xr_vector rt_Base; - ref_rt rt_Base_Depth; - - // MRT-path - ref_rt rt_Depth; // Z-buffer like - initial depth - ref_rt rt_MSAADepth; // z-buffer for MSAA deferred shading. If MSAA is disabled, points to rt_Base_Depth so we can reduce branching - ref_rt rt_Generic_0_r; // MRT generic 0, if MSAA is disabled, just an alias of rt_Generic_0 - ref_rt rt_Generic_1_r; // MRT generic 1, if MSAA is disabled, just an alias of rt_Generic_1 - ref_rt rt_Position; // 64bit, fat (x,y,z,?) (eye-space) - ref_rt rt_Normal; // 64bit, fat (x,y,z,hemi) (eye-space) - ref_rt rt_Color; // 64/32bit,fat (r,g,b,specular-gloss) (or decompressed MET-8-8-8-8) - - // - ref_rt rt_Accumulator; // 64bit (r,g,b,specular) - ref_rt rt_Accumulator_temp; // only for HW which doesn't feature fp16 blend - ref_rt rt_Generic_0; // 32bit (r,g,b,a) // post-process, intermidiate results, etc. - ref_rt rt_Generic_1; // 32bit (r,g,b,a) // post-process, intermidiate results, etc. - // Igor: for volumetric lights - ref_rt rt_Generic_2; // 32bit (r,g,b,a) // post-process, intermidiate results, etc. - ref_rt rt_Bloom_1; // 32bit, dim/4 (r,g,b,?) - ref_rt rt_Bloom_2; // 32bit, dim/4 (r,g,b,?) - ref_rt rt_LUM_64; // 64bit, 64x64, log-average in all components - ref_rt rt_LUM_8; // 64bit, 8x8, log-average in all components - - // Igor: for async screenshots - ref_rt rt_async_ss; // 32bit (r,g,b,a) is situated in the system memory - - ref_rt rt_LUM_pool[CHWCaps::MAX_GPUS * 2]; // 1xfp32,1x1, exp-result -> scaler - ref_texture t_LUM_src; // source - ref_texture t_LUM_dest; // destination & usage for current frame - - // smap - ref_rt rt_smap_surf; // 32bit, color - ref_rt rt_smap_depth; // 24(32) bit, depth - - // Textures - ref_texture t_material; - ref_texture t_noise[TEX_jitter_count]; - - // Anomaly - ref_rt rt_Generic_temp; - -private: - // OCCq - ref_shader s_occq; - - // Accum - ref_shader s_accum_mask; - ref_shader s_accum_direct; - ref_shader s_accum_direct_volumetric; - ref_shader s_accum_point; - ref_shader s_accum_spot; - ref_shader s_accum_reflected; - ref_shader s_accum_volume; - - ref_geom g_accum_point; - ref_geom g_accum_spot; - ref_geom g_accum_omnipart; - ref_geom g_accum_volumetric; - - VertexStagingBuffer g_accum_point_vb; - IndexStagingBuffer g_accum_point_ib; - - VertexStagingBuffer g_accum_omnip_vb; - IndexStagingBuffer g_accum_omnip_ib; - - VertexStagingBuffer g_accum_spot_vb; - IndexStagingBuffer g_accum_spot_ib; - - VertexStagingBuffer g_accum_volumetric_vb; - IndexStagingBuffer g_accum_volumetric_ib; - - // SSAO - ref_rt rt_ssao_temp; - ref_rt rt_half_depth; - ref_shader s_ssao; - - // Bloom - ref_geom g_bloom_build; - ref_geom g_bloom_filter; - ref_shader s_bloom_dbg_1; - ref_shader s_bloom_dbg_2; - ref_shader s_bloom; - ref_shader s_bloom_msaa; // if MSAA is disabled, just an alias of s_bloom - float f_bloom_factor; - - // Luminance - ref_shader s_luminance; - float f_luminance_adapt; - - // Combine - ref_geom g_combine; - ref_geom g_combine_VP; // xy=p,zw=tc - ref_geom g_combine_2UV; - ref_geom g_combine_cuboid; - ref_geom g_aa_blur; - ref_geom g_aa_AA; - ref_shader s_combine_dbg_0; - ref_shader s_combine_dbg_1; - ref_shader s_combine_dbg_Accumulator; - ref_shader s_combine; - ref_shader s_combine_volumetric; - -public: - ref_shader s_postprocess; - ref_shader s_postprocess_msaa; // if MSAA is disabled, just an alias of s_bloom - ref_geom g_postprocess; - ref_shader s_menu; - ref_geom g_menu; - -private: - float im_noise_time; - u32 im_noise_shift_w; - u32 im_noise_shift_h; - - float param_blur; - float param_gray; - float param_duality_h; - float param_duality_v; - float param_noise; - float param_noise_scale; - float param_noise_fps; - u32 param_color_base; - u32 param_color_gray; - Fvector param_color_add; - - // Color mapping - float param_color_map_influence; - float param_color_map_interpolate; - ColorMapManager color_map_manager; - - // Igor: used for volumetric lights - bool m_bHasActiveVolumetric; - -public: - CRenderTarget(); - ~CRenderTarget() override; - - void build_textures(); - - void accum_point_geom_create(); - void accum_point_geom_destroy(); - void accum_omnip_geom_create(); - void accum_omnip_geom_destroy(); - void accum_spot_geom_create(); - void accum_spot_geom_destroy(); - // Igor: used for volumetric lights - void accum_volumetric_geom_create(); - void accum_volumetric_geom_destroy(); - - ID3DRenderTargetView* get_base_rt() { return rt_Base[HW.CurrentBackBuffer]->pRT; } - ID3DDepthStencilView* get_base_zb() { return rt_Base_Depth->pRT; } - - void u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, IDirect3DSurface9* zb); - void u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb) - { - u_setrt(cmd_list, _1, _2, _3, _zb ? _zb->pRT : nullptr); - } - void u_setrt(CBackend& cmd_list, u32 W, u32 H, IDirect3DSurface9* _1, IDirect3DSurface9* _2, IDirect3DSurface9* _3, - IDirect3DSurface9* zb); - - void u_stencil_optimize(CBackend& cmd_list, BOOL common_stencil = TRUE); - void u_compute_texgen_screen(CBackend& cmd_list, Fmatrix& dest); - void u_compute_texgen_jitter(CBackend& cmd_list, Fmatrix& dest); - void u_calc_tc_noise(Fvector2& p0, Fvector2& p1); - void u_calc_tc_duality_ss(Fvector2& r0, Fvector2& r1, Fvector2& l0, Fvector2& l1); - bool u_need_PP(); - bool u_need_CM(); - bool u_DBT_enable(float zMin, float zMax); - void u_DBT_disable(); - - void phase_scene_prepare(); - void phase_scene_begin(); - void phase_scene_end(); - void phase_occq(); - void phase_ssao(); - void phase_downsamp(); - void phase_wallmarks(); - void phase_smap_direct(CBackend& cmd_list, light* L, u32 sub_phase); - void phase_smap_direct_tsh(CBackend& cmd_list, light* L, u32 sub_phase); - void phase_smap_spot_clear(CBackend& cmd_list); - void phase_smap_spot(CBackend& cmd_list, light* L); - void phase_smap_spot_tsh(CBackend& cmd_list, light* L); - void phase_accumulator(CBackend& cmd_list); - void phase_vol_accumulator(CBackend& cmd_list); - - // Generates min/max sm - void create_minmax_SM(CBackend& cmd_list) {} - bool need_to_render_sunshafts(); - bool use_minmax_sm_this_frame() { return false; } - - bool enable_scissor(light* L); // true if intersects near plane - void enable_dbt_bounds(light* L); - - void disable_aniso(); - - void draw_volume(CBackend& cmd_list, light* L); - void accum_direct(CBackend& cmd_list, u32 sub_phase); - void accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmatrix& xform, Fmatrix& xform_prev, float fBias); - void accum_direct_f(CBackend& cmd_list, u32 sub_phase); - void accum_direct_lum(CBackend& cmd_list); - void accum_direct_blend(CBackend& cmd_list); - void accum_direct_volumetric(CBackend& cmd_list, u32 sub_phase, const u32 Offset, const Fmatrix& mShadow); - void accum_point(CBackend& cmd_list, light* L); - void accum_spot(CBackend& cmd_list, light* L); - void accum_reflected(CBackend& cmd_list, light* L); - // Igor: for volumetric lights - void accum_volumetric(CBackend& cmd_list, light* L); - - void phase_bloom(); - void phase_luminance(); - void phase_combine(); - void phase_combine_volumetric(); - void phase_pp(); - - u32 get_width(CBackend& cmd_list) override { return dwWidth[cmd_list.context_id]; } - u32 get_height(CBackend& cmd_list) override { return dwHeight[cmd_list.context_id]; } - - void set_blur(float f) override { param_blur = f; } - void set_gray(float f) override { param_gray = f; } - void set_duality_h(float f) override { param_duality_h = _abs(f); } - void set_duality_v(float f) override { param_duality_v = _abs(f); } - void set_noise(float f) override { param_noise = f; } - void set_noise_scale(float f) override { param_noise_scale = f; } - void set_noise_fps(float f) override { param_noise_fps = _abs(f) + EPS_S; } - void set_color_base(u32 f) override { param_color_base = f; } - void set_color_gray(u32 f) override { param_color_gray = f; } - void set_color_add(const Fvector& f) override { param_color_add = f; } - void set_cm_imfluence(float f) override { param_color_map_influence = f; } - void set_cm_interpolate(float f) override { param_color_map_interpolate = f; } - void set_cm_textures(const shared_str& tex0, const shared_str& tex1) override - { - color_map_manager.SetTextures(tex0, tex1); - } - - // Need to reset stencil only when marker overflows. - // Don't clear when render for the first time - void reset_light_marker(CBackend& cmd_list, bool bResetStencil = false); - void increment_light_marker(CBackend& cmd_list); - - void DoAsyncScreenshot(); - -#ifdef DEBUG - void dbg_addline(const Fvector& P0, const Fvector& P1, u32 c) - { - dbg_lines.emplace_back(dbg_line_t{ P0, P1, c }); - } - - void dbg_addbox(const Fbox& box, const u32& color) - { - Fvector c, r; - box.getcenter(c); - box.getradius(r); - dbg_addbox(c, r.x, r.y, r.z, color); - } - - void dbg_addbox(const Fvector& c, float rx, float ry, float rz, u32 color) - { - Fvector p1, p2, p3, p4, p5, p6, p7, p8; - - p1.set(c.x + rx, c.y + ry, c.z + rz); - p2.set(c.x + rx, c.y - ry, c.z + rz); - p3.set(c.x - rx, c.y - ry, c.z + rz); - p4.set(c.x - rx, c.y + ry, c.z + rz); - - p5.set(c.x + rx, c.y + ry, c.z - rz); - p6.set(c.x + rx, c.y - ry, c.z - rz); - p7.set(c.x - rx, c.y - ry, c.z - rz); - p8.set(c.x - rx, c.y + ry, c.z - rz); - - dbg_addline(p1, p2, color); - dbg_addline(p2, p3, color); - dbg_addline(p3, p4, color); - dbg_addline(p4, p1, color); - - dbg_addline(p5, p6, color); - dbg_addline(p6, p7, color); - dbg_addline(p7, p8, color); - dbg_addline(p8, p5, color); - - dbg_addline(p1, p5, color); - dbg_addline(p2, p6, color); - dbg_addline(p3, p7, color); - dbg_addline(p4, p8, color); - } - void dbg_addplane(Fplane& P0, u32 /*c*/) { dbg_planes.emplace_back(P0); } -#else - void dbg_addline(Fvector& /*P0*/, Fvector& /*P1*/, u32 /*c*/) {} - void dbg_addplane(Fplane& /*P0*/, u32 /*c*/) {} -#endif -}; diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_direct.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_direct.cpp deleted file mode 100644 index 94ad88264dc..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_direct.cpp +++ /dev/null @@ -1,969 +0,0 @@ -#include "stdafx.h" -#include "xrEngine/IGame_Persistent.h" -#include "xrEngine/Environment.h" - -////////////////////////////////////////////////////////////////////////// -// tables to calculate view-frustum bounds in world space -// note: D3D uses [0..1] range for Z -namespace accum_direct -{ -static Fvector3 corners[8] = -{ - { -1, -1, 0.7f }, { -1, -1, +1 }, - { -1, +1, +1 }, { -1, +1, 0.7f }, - { +1, +1, +1 }, { +1, +1, 0.7f }, - { +1, -1, +1 }, { +1, -1, 0.7f } -}; - -static u16 facetable[16][3] = -{ - { 3, 2, 1 }, - { 3, 1, 0 }, - { 7, 6, 5 }, - { 5, 6, 4 }, - { 3, 5, 2 }, - { 4, 2, 5 }, - { 1, 6, 7 }, - { 7, 0, 1 }, - - { 5, 3, 0 }, - { 7, 5, 0 }, - - { 1, 4, 6 }, - { 2, 4, 1 }, -}; -} // namespace accum_direct - -void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) -{ - // Choose normal code-path or filtered - phase_accumulator(cmd_list); - if (RImplementation.o.sunfilter) - { - accum_direct_f(cmd_list, sub_phase); - return; - } - - // *** assume accumulator setted up *** - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - - // Common calc for quad-rendering - u32 Offset; - u32 C = color_rgba(255, 255, 255, 255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S, d_W = 1.f; - - // Common constants (light-related) - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - // Perform masking (only once - on the first/near phase) - cmd_list.set_CullMode(CULL_NONE); - PIX_EVENT(SE_SUN_NEAR_sub_phase); - if (SE_SUN_NEAR == sub_phase) //. - { - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine->vb_stride); - cmd_list.set_Geometry(g_combine); - - // setup - float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; - Fvector dir = L_dir; - dir.normalize().mul(-_sqrt(intensity + EPS)); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker - cmd_list.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.f); - - // if (stencil>=1 && aref_pass) stencil = light_id - cmd_list.set_ColorWriteEnable(FALSE); - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // recalculate d_Z, to perform depth-clipping - Fvector center_pt; - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, ps_r2_sun_near); - Device.mFullTransform.transform(center_pt); - d_Z = center_pt.z; - - // nv-stencil recompression - if (RImplementation.o.nvstencil && (SE_SUN_NEAR == sub_phase)) - u_stencil_optimize(cmd_list); //. driver bug? - - PIX_EVENT(Perform_lighting); - - // Perform lighting - { - phase_accumulator(cmd_list); - cmd_list.set_CullMode(CULL_NONE); - cmd_list.set_ColorWriteEnable(); - - // texture adjustment matrix - float fTexelOffs = (.5f / float(RImplementation.o.smapsize)); - float fRange = (SE_SUN_NEAR == sub_phase) ? ps_r2_sun_depth_near_scale : ps_r2_sun_depth_far_scale; - //float fBias = (SE_SUN_NEAR==sub_phase) ? ps_r2_sun_depth_near_bias : ps_r2_sun_depth_far_bias; - // Use this when triangle culling is not inverted. - float fBias = (SE_SUN_NEAR == sub_phase) ? (-ps_r2_sun_depth_near_bias) : ps_r2_sun_depth_far_bias; - Fmatrix m_TexelAdjust = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, - 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f}; - - // compute xforms - FPU::m64r(); - - // shadow xform - Fmatrix m_shadow; - { - Fmatrix xf_project; - xf_project.mul(m_TexelAdjust, fuckingsun->X.D[sub_phase].combine); - m_shadow.mul(xf_project, Device.mInvView); - - // tsm-bias - if ((SE_SUN_FAR == sub_phase) && (RImplementation.o.HW_smap)) - { - Fvector bias; - bias.mul(L_dir, ps_r2_sun_tsm_bias); - Fmatrix bias_t; - bias_t.translate(bias); - m_shadow.mulB_44(bias_t); - } - FPU::m24r(); - } - - // clouds xform - Fmatrix m_clouds_shadow; - { - static float w_shift = 0; - Fmatrix m_xform; - Fvector direction = fuckingsun->direction; - float w_dir = g_pGamePersistent->Environment().CurrentEnv.wind_direction; - // float w_speed = g_pGamePersistent->Environment().CurrentEnv.wind_velocity; - Fvector normal; - normal.setHP(w_dir, 0); - w_shift += 0.003f * Device.fTimeDelta; - Fvector position; - position.set(0, 0, 0); - m_xform.build_camera_dir(position, direction, normal); - Fvector localnormal; - m_xform.transform_dir(localnormal, normal); - localnormal.normalize(); - m_clouds_shadow.mul(m_xform, Device.mInvView); - m_xform.scale(0.002f, 0.002f, 1.f); - m_clouds_shadow.mulA_44(m_xform); - m_xform.translate(localnormal.mul(w_shift)); - m_clouds_shadow.mulA_44(m_xform); - } - - // Make jitter texture - Fvector2 j0, j1; - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - //float scale_Y = float(Device.dwHeight)/ float(TEX_jitter); - float offset = (.5f / float(TEX_jitter)); - j0.set(offset, offset); - j1.set(scale_X, scale_X).add(offset); - - // Fill vertex buffer - FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); - cmd_list.set_Geometry(g_combine_2UV); - - // setup - cmd_list.set_Element(s_accum_direct->E[sub_phase]); - cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.0f); - cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - cmd_list.set_c("m_shadow", m_shadow); - cmd_list.set_c("m_sunmask", m_clouds_shadow); - - // nv-DBT - float zMin, zMax; - if (SE_SUN_NEAR == sub_phase) - { - zMin = 0; - zMax = ps_r2_sun_near; - } - else - { - extern float OLES_SUN_LIMIT_27_01_07; - zMin = ps_r2_sun_near; - zMax = OLES_SUN_LIMIT_27_01_07; - } - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMin); - Device.mFullTransform.transform(center_pt); - zMin = center_pt.z; - - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMax); - Device.mFullTransform.transform(center_pt); - zMax = center_pt.z; - - if (u_DBT_enable(zMin, zMax)) - { - // z-test always - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - // setup stencil - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - - // disable depth bounds - u_DBT_disable(); - - // Igor: draw volumetric here - // if (ps_r2_ls_flags.test(R2FLAG_SUN_SHAFTS)) - if (RImplementation.o.advancedpp && (ps_r_sun_shafts > 0)) - accum_direct_volumetric(cmd_list, sub_phase, Offset, m_shadow); - } -} - -void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmatrix& xform, Fmatrix& xform_prev, float fBias) -{ - // Choose normal code-path or filtered - phase_accumulator(cmd_list); - if (RImplementation.o.sunfilter) - { - accum_direct_f(cmd_list, sub_phase); - return; - } - - // *** assume accumulator setted up *** - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - - // Common calc for quad-rendering - u32 Offset; - u32 C = color_rgba(255, 255, 255, 255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S, d_W = 1.f; - - // Common constants (light-related) - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - // Perform masking (only once - on the first/near phase) - cmd_list.set_CullMode(CULL_NONE); - PIX_EVENT(SE_SUN_NEAR_sub_phase); - if (SE_SUN_NEAR == sub_phase) //. - { - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine->vb_stride); - cmd_list.set_Geometry(g_combine); - - // setup - float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; - Fvector dir = L_dir; - dir.normalize().mul(-_sqrt(intensity + EPS)); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker - cmd_list.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.0f); - - //if (stencil>=1 && aref_pass) stencil = light_id - cmd_list.set_ColorWriteEnable(FALSE); - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // recalculate d_Z, to perform depth-clipping - Fvector center_pt; - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, ps_r2_sun_near); - Device.mFullTransform.transform(center_pt); - d_Z = center_pt.z; - - // nv-stencil recompression - if (RImplementation.o.nvstencil && (SE_SUN_NEAR == sub_phase)) - u_stencil_optimize(cmd_list); //. driver bug? - - PIX_EVENT(Perform_lighting); - - // Perform lighting - // if( sub_phase == SE_SUN_FAR ) //****************************************************************** - { - phase_accumulator(cmd_list); - cmd_list.set_CullMode(CULL_CCW); //****************************************************************** - cmd_list.set_ColorWriteEnable(); - - // texture adjustment matrix - float fTexelOffs = (0.5f / float(RImplementation.o.smapsize)); - float fRange = (SE_SUN_NEAR == sub_phase) ? ps_r2_sun_depth_near_scale : ps_r2_sun_depth_far_scale; - //float fBias = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias; - // Use this when triangle culling is not inverted. - //float fBias = (SE_SUN_NEAR==sub_phase) ? (-ps_r2_sun_depth_near_bias) : ps_r2_sun_depth_far_bias; - Fmatrix m_TexelAdjust = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, - 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f}; - - // compute xforms - FPU::m64r(); - - // shadow xform - Fmatrix m_shadow; - { - Fmatrix xf_project; - xf_project.mul(m_TexelAdjust, fuckingsun->X.D[sub_phase].combine); - m_shadow.mul(xf_project, Device.mInvView); - - // tsm-bias - if ((SE_SUN_FAR == sub_phase) && (RImplementation.o.HW_smap)) - { - Fvector bias; - bias.mul(L_dir, ps_r2_sun_tsm_bias); - Fmatrix bias_t; - bias_t.translate(bias); - m_shadow.mulB_44(bias_t); - } - FPU::m24r(); - } - - // clouds xform - Fmatrix m_clouds_shadow; - { - static float w_shift = 0; - Fmatrix m_xform; - Fvector direction = fuckingsun->direction; - float w_dir = g_pGamePersistent->Environment().CurrentEnv.wind_direction; - //float w_speed = g_pGamePersistent->Environment().CurrentEnv.wind_velocity; - Fvector normal; - normal.setHP(w_dir, 0); - w_shift += 0.003f * Device.fTimeDelta; - Fvector position; - position.set(0, 0, 0); - m_xform.build_camera_dir(position, direction, normal); - Fvector localnormal; - m_xform.transform_dir(localnormal, normal); - localnormal.normalize(); - m_clouds_shadow.mul(m_xform, Device.mInvView); - m_xform.scale(0.002f, 0.002f, 1.f); - m_clouds_shadow.mulA_44(m_xform); - m_xform.translate(localnormal.mul(w_shift)); - m_clouds_shadow.mulA_44(m_xform); - } - - // Compute textgen texture for pixel shader, for possitions texture. - Fmatrix m_Texgen; - m_Texgen.identity(); - cmd_list.xforms.set_W(m_Texgen); - cmd_list.xforms.set_V(Device.mView); - cmd_list.xforms.set_P(Device.mProject); - u_compute_texgen_screen(cmd_list, m_Texgen); - - // Make jitter texture - Fvector2 j0, j1; - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - //float scale_Y = float(Device.dwHeight) / float(TEX_jitter); - float offset = (.5f / float(TEX_jitter)); - j0.set(offset, offset); - j1.set(scale_X, scale_X).add(offset); - - // Fill vertex buffer - u32 i_offset; - { - u16* pib = RImplementation.Index.Lock(sizeof(accum_direct::facetable) / sizeof(u16), i_offset); - CopyMemory(pib, &accum_direct::facetable, sizeof(accum_direct::facetable)); - RImplementation.Index.Unlock(sizeof(accum_direct::facetable) / sizeof(u16)); - // corners - u32 ver_count = sizeof(accum_direct::corners) / sizeof(Fvector3); - FVF::L* pv = (FVF::L*)RImplementation.Vertex.Lock(ver_count, g_combine_cuboid.stride(), Offset); - - Fmatrix inv_XDcombine; - if (/*ps_r2_ls_flags_ext.is(R2FLAGEXT_SUN_ZCULLING) &&*/ sub_phase == SE_SUN_FAR) - inv_XDcombine.invert(xform_prev); - else - inv_XDcombine.invert(xform); - - for (u32 i = 0; i < ver_count; ++i) - { - Fvector3 tmp_vec; - inv_XDcombine.transform(tmp_vec, accum_direct::corners[i]); - pv->set(tmp_vec, C); - pv++; - } - RImplementation.Vertex.Unlock(ver_count, g_combine_cuboid.stride()); - } - - cmd_list.set_Geometry(g_combine_cuboid); - - // setup - cmd_list.set_Element(s_accum_direct->E[sub_phase]); - - cmd_list.set_c("m_texgen", m_Texgen); - cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.0f); - cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - cmd_list.set_c("m_shadow", m_shadow); - cmd_list.set_c("m_sunmask", m_clouds_shadow); - - // Pass view vector projected in shadow space to far pixel shader - // Needed for shadow fading. - if (sub_phase == SE_SUN_FAR) - { - Fvector3 view_viewspace; - view_viewspace.set(0.0f, 0.0f, 1.0f); - - m_shadow.transform_dir(view_viewspace); - Fvector4 view_projlightspace; - view_projlightspace.set(view_viewspace.x, view_viewspace.y, 0.0f, 0.0f); - view_projlightspace.normalize(); - - cmd_list.set_c("view_shadow_proj", view_projlightspace); - } - - // nv-DBT - float zMin, zMax; - if (SE_SUN_NEAR == sub_phase) - { - zMin = 0; - zMax = ps_r2_sun_near; - } - else - { - extern float OLES_SUN_LIMIT_27_01_07; - zMin = ps_r2_sun_near; - zMax = OLES_SUN_LIMIT_27_01_07; - } - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMin); - Device.mFullTransform.transform(center_pt); - zMin = center_pt.z; - - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMax); - Device.mFullTransform.transform(center_pt); - zMax = center_pt.z; - - if (u_DBT_enable(zMin, zMax)) - { - // z-test always - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } - - // Enable Z function only for near and middle cascades, the far one is restricted by only stencil. - if ((SE_SUN_NEAR == sub_phase || SE_SUN_MIDDLE == sub_phase)) - cmd_list.set_ZFunc(D3DCMP_GREATEREQUAL); - else if (!ps_r2_ls_flags_ext.is(R2FLAGEXT_SUN_ZCULLING)) - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - else - cmd_list.set_ZFunc(D3DCMP_LESS); - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - // setup stencil - if (SE_SUN_NEAR == sub_phase || sub_phase == SE_SUN_MIDDLE /*|| SE_SUN_FAR==sub_phase*/) - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0xFE, - D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO, D3DSTENCILOP_KEEP); - else - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - - // disable depth bounds - u_DBT_disable(); - - // Igor: draw volumetric here - // if (ps_r2_ls_flags.test(R2FLAG_SUN_SHAFTS)) - if (RImplementation.o.advancedpp && (ps_r_sun_shafts > 0) && sub_phase == SE_SUN_FAR) - accum_direct_volumetric(cmd_list, sub_phase, Offset, m_shadow); - } -} - -void CRenderTarget::accum_direct_blend(CBackend& cmd_list) -{ - PIX_EVENT(accum_direct_blend); - // blend-copy - if (!RImplementation.o.fp16_blend) - { - u_setrt(cmd_list, rt_Accumulator, NULL, NULL, get_base_zb()); - - // Common calc for quad-rendering - u32 Offset; - u32 C = color_rgba(255, 255, 255, 255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S, d_W = 1.f; - - // Fill vertex buffer - FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y, p0.x, p1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y, p0.x, p0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y, p1.x, p1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y, p1.x, p0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); - cmd_list.set_Geometry(g_combine_2UV); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_2D]); - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - //dwLightMarkerID += 2; - increment_light_marker(cmd_list); -} - -void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) -{ - PIX_EVENT(accum_direct_f); - // Select target - if (SE_SUN_LUMINANCE == sub_phase) - { - accum_direct_lum(cmd_list); - return; - } - phase_accumulator(cmd_list); - u_setrt(cmd_list, rt_Generic_0, NULL, NULL, get_base_zb()); - - // *** assume accumulator setted up *** - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - - // Common calc for quad-rendering - u32 Offset; - u32 C = color_rgba(255, 255, 255, 255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S, d_W = 1.f; - - // Common constants (light-related) - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - // Perform masking (only once - on the first/near phase) - cmd_list.set_CullMode(CULL_NONE); - if (SE_SUN_NEAR == sub_phase) //. - { - // For sun-filter - clear to zero - cmd_list.ClearRT(rt_Generic_0, {}); - - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine->vb_stride); - cmd_list.set_Geometry(g_combine); - - // setup - float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; - Fvector dir = L_dir; - dir.normalize().mul(-_sqrt(intensity + EPS)); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker - cmd_list.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.f); - - // if (stencil>=1 && aref_pass) stencil = light_id - cmd_list.set_ColorWriteEnable(FALSE); - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, - D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // recalculate d_Z, to perform depth-clipping - Fvector center_pt; - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, ps_r2_sun_near); - Device.mFullTransform.transform(center_pt); - d_Z = center_pt.z; - - // nv-stencil recompression - if (RImplementation.o.nvstencil && (SE_SUN_NEAR == sub_phase)) - u_stencil_optimize(cmd_list); //. driver bug? - - // Perform lighting - { - u_setrt(cmd_list, rt_Generic_0, NULL, NULL, get_base_zb()); // ensure RT is set - cmd_list.set_CullMode(CULL_NONE); - cmd_list.set_ColorWriteEnable(); - - // texture adjustment matrix - float fTexelOffs = (.5f / float(RImplementation.o.smapsize)); - float fRange = (SE_SUN_NEAR == sub_phase) ? ps_r2_sun_depth_near_scale : ps_r2_sun_depth_far_scale; - float fBias = (SE_SUN_NEAR == sub_phase) ? ps_r2_sun_depth_near_bias : ps_r2_sun_depth_far_bias; - Fmatrix m_TexelAdjust = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, - 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f}; - - // compute xforms - Fmatrix m_shadow; - { - FPU::m64r(); - Fmatrix xf_invview; - xf_invview.invert(Device.mView); - Fmatrix xf_project; - xf_project.mul(m_TexelAdjust, fuckingsun->X.D[0].combine); - m_shadow.mul(xf_project, xf_invview); - - // tsm-bias - if (SE_SUN_FAR == sub_phase) - { - Fvector bias; - bias.mul(L_dir, ps_r2_sun_tsm_bias); - Fmatrix bias_t; - bias_t.translate(bias); - m_shadow.mulB_44(bias_t); - } - FPU::m24r(); - } - - // Make jitter texture - Fvector2 j0, j1; - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - // float scale_Y = float(Device.dwHeight)/ float(TEX_jitter); - float offset = (.5f / float(TEX_jitter)); - j0.set(offset, offset); - j1.set(scale_X, scale_X).add(offset); - - // Fill vertex buffer - FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); - cmd_list.set_Geometry(g_combine_2UV); - - // setup - cmd_list.set_Element(s_accum_direct->E[sub_phase]); - cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); - cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - cmd_list.set_c("m_shadow", m_shadow); - - // setup stencil - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // Igor: draw volumetric here - // accum_direct_volumetric (sub_phase, Offset); - } -} - -void CRenderTarget::accum_direct_lum(CBackend& cmd_list) -{ - PIX_EVENT(accum_direct_lum); - // Select target - phase_accumulator(cmd_list); - - // *** assume accumulator setted up *** - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - - // Common calc for quad-rendering - u32 Offset; - // u32 C = color_rgba (255,255,255,255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S; //, d_W = 1.f; - - // Common constants (light-related) - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - // recalculate d_Z, to perform depth-clipping - Fvector center_pt; - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, ps_r2_sun_near); - Device.mFullTransform.transform(center_pt); - d_Z = center_pt.z; - - // nv-stencil recompression - /* - if (RImplementation.o.nvstencil && (SE_SUN_NEAR==sub_phase)) u_stencil_optimize(); //. driver bug? - */ - - // Perform lighting - cmd_list.set_CullMode(CULL_NONE); - cmd_list.set_ColorWriteEnable(); - - // Make jitter texture - Fvector2 j0, j1; - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - // float scale_Y = float(Device.dwHeight)/ float(TEX_jitter); - float offset = (.5f / float(TEX_jitter)); - j0.set(offset, offset); - j1.set(scale_X, scale_X).add(offset); - - struct v_aa - { - Fvector4 p; - Fvector2 uv0; - Fvector2 uvJ; - Fvector2 uv1; - Fvector2 uv2; - Fvector2 uv3; - Fvector4 uv4; - Fvector4 uv5; - }; - float smooth = 0.6f; - float ddw = smooth / _w; - float ddh = smooth / _h; - - // Fill vertex buffer - VERIFY(sizeof(v_aa) == g_aa_AA->vb_stride); - v_aa* pv = (v_aa*)RImplementation.Vertex.Lock(4, g_aa_AA->vb_stride, Offset); - pv->p.set(EPS, float(_h + EPS), EPS, 1.f); - pv->uv0.set(p0.x, p1.y); - pv->uvJ.set(j0.x, j1.y); - pv->uv1.set(p0.x - ddw, p1.y - ddh); - pv->uv2.set(p0.x + ddw, p1.y + ddh); - pv->uv3.set(p0.x + ddw, p1.y - ddh); - pv->uv4.set(p0.x - ddw, p1.y + ddh, 0, 0); - pv->uv5.set(0, 0, 0, 0); - pv++; - pv->p.set(EPS, EPS, EPS, 1.f); - pv->uv0.set(p0.x, p0.y); - pv->uvJ.set(j0.x, j0.y); - pv->uv1.set(p0.x - ddw, p0.y - ddh); - pv->uv2.set(p0.x + ddw, p0.y + ddh); - pv->uv3.set(p0.x + ddw, p0.y - ddh); - pv->uv4.set(p0.x - ddw, p0.y + ddh, 0, 0); - pv->uv5.set(0, 0, 0, 0); - pv++; - pv->p.set(float(_w + EPS), float(_h + EPS), EPS, 1.f); - pv->uv0.set(p1.x, p1.y); - pv->uvJ.set(j1.x, j1.y); - pv->uv1.set(p1.x - ddw, p1.y - ddh); - pv->uv2.set(p1.x + ddw, p1.y + ddh); - pv->uv3.set(p1.x + ddw, p1.y - ddh); - pv->uv4.set(p1.x - ddw, p1.y + ddh, 0, 0); - pv->uv5.set(0, 0, 0, 0); - pv++; - pv->p.set(float(_w + EPS), EPS, EPS, 1.f); - pv->uv0.set(p1.x, p0.y); - pv->uvJ.set(j1.x, j0.y); - pv->uv1.set(p1.x - ddw, p0.y - ddh); - pv->uv2.set(p1.x + ddw, p0.y + ddh); - pv->uv3.set(p1.x + ddw, p0.y - ddh); - pv->uv4.set(p1.x - ddw, p0.y + ddh, 0, 0); - pv->uv5.set(0, 0, 0, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_aa_AA->vb_stride); - cmd_list.set_Geometry(g_aa_AA); - - // setup - cmd_list.set_Element(s_accum_direct->E[SE_SUN_LUMINANCE]); - cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); - cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - - // setup stencil - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); -} - -void CRenderTarget::accum_direct_volumetric(CBackend& cmd_list, u32 sub_phase, const u32 Offset, const Fmatrix& mShadow) -{ - PIX_EVENT(accum_direct_volumetric); - - if ((sub_phase != SE_SUN_NEAR) && (sub_phase != SE_SUN_MIDDLE) && (sub_phase != SE_SUN_FAR)) - return; - - if (!(RImplementation.o.advancedpp && ps_r_sun_shafts)) - return; - - { - const auto& env = g_pGamePersistent->Environment().CurrentEnv; - const float fValue = env.m_fSunShaftsIntensity; - // TODO: add multiplication by sun color here - if (fValue < 0.0001) - return; - } - - // Test. draw only for near part - // if (sub_phase!=SE_SUN_N/EAR) return; - // if (sub_phase!=SE_SUN_FAR) return; - - phase_vol_accumulator(cmd_list); - - cmd_list.set_ColorWriteEnable(); - - // Assume everything was recalculated before this call by accum_direct - - // Perform lighting - { - // *** assume accumulator setted up *** - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - - // Common constants (light-related) - Fvector L_dir, L_clr; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - // Use g_combine_2UV that was set up by accum_direct - // cmd_list.set_Geometry (g_combine_2UV); - - // setup - cmd_list.set_Element(s_accum_direct_volumetric->E[0]); - if (!RImplementation.o.oldshadowcascades) - { - cmd_list.set_CullMode(CULL_CCW); - } - - cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); - cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, 0.f); - cmd_list.set_c("m_shadow", mShadow); - Fmatrix m_Texgen; - m_Texgen.identity(); - cmd_list.xforms.set_W(m_Texgen); - cmd_list.xforms.set_V(Device.mView); - cmd_list.xforms.set_P(Device.mProject); - u_compute_texgen_screen(cmd_list, m_Texgen); - - cmd_list.set_c("m_texgen", m_Texgen); - // cmd_list.set_c ("m_sunmask", m_clouds_shadow); - - // nv-DBT - float zMin, zMax; - if (SE_SUN_NEAR == sub_phase) - { - zMin = 0; - zMax = ps_r2_sun_near; - } - else - { - extern float OLES_SUN_LIMIT_27_01_07; - if (RImplementation.o.oldshadowcascades) - zMin = ps_r2_sun_near; - else - zMin = 0; /////***************************************************************************************** - zMax = OLES_SUN_LIMIT_27_01_07; - } - - cmd_list.set_c("volume_range", zMin, zMax, 0.f, 0.f); - - Fvector center_pt; - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMin); - Device.mFullTransform.transform(center_pt); - zMin = center_pt.z; - - center_pt.mad(Device.vCameraPosition, Device.vCameraDirection, zMax); - Device.mFullTransform.transform(center_pt); - zMax = center_pt.z; - - if (u_DBT_enable(zMin, zMax)) - { - // z-test always - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } - else - { - if (SE_SUN_NEAR == sub_phase) - cmd_list.set_ZFunc(D3DCMP_GREATER); - else - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - } - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - // setup stencil: we have to draw to both lit and unlit pixels - // cmd_list.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00); - - if (RImplementation.o.oldshadowcascades) - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - else - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - - // disable depth bounds - u_DBT_disable(); - } -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_point.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_point.cpp deleted file mode 100644 index 9c982cd20f9..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_point.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "stdafx.h" - -void CRenderTarget::accum_point(CBackend& cmd_list, light* L) -{ - phase_accumulator(RCache); - RImplementation.Stats.l_visible++; - - ref_shader shader = L->s_point; - if (!shader) - shader = s_accum_point; - - Fmatrix Pold = Fidentity; - Fmatrix FTold = Fidentity; - - if (L->flags.bHudMode) - { - extern ENGINE_API float psHUD_FOV; - Pold = Device.mProject; - FTold = Device.mFullTransform; - Device.mProject.build_projection(deg2rad(psHUD_FOV * Device.fFOV /* *Device.fASPECT*/), Device.fASPECT, - VIEWPORT_NEAR, g_pGamePersistent->Environment().CurrentEnv.far_plane); - - Device.mFullTransform.mul(Device.mProject, Device.mView); - RCache.set_xform_project(Device.mProject); - RImplementation.rmNear(RCache); - } - - // Common - Fvector L_pos; - float L_spec; - // float L_R = L->range; - float L_R = L->range * 0.95f; - Fvector L_clr; - L_clr.set(L->color.r, L->color.g, L->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_tiny(L_pos, L->position); - - // Xforms - L->xform_calc(); - RCache.set_xform_world(L->m_xform); - RCache.set_xform_view(Device.mView); - RCache.set_xform_project(Device.mProject); - enable_scissor(L); - enable_dbt_bounds(L); - - // ***************************** Mask by stencil ************************************* - // *** similar to "Carmack's reverse", but assumes convex, non intersecting objects, - // *** thus can cope without stencil clear with 127 lights - // *** in practice, 'cause we "clear" it back to 0x1 it usually allows us to > 200 lights :) - RCache.set_Element(s_accum_mask->E[SE_MASK_POINT]); // masker - RCache.set_ColorWriteEnable(FALSE); - - // backfaces: if (stencil>=1 && zfail) stencil = light_id - RCache.set_CullMode(CULL_CW); - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, - D3DSTENCILOP_REPLACE); - draw_volume(RCache, L); - - // frontfaces: if (stencil>=light_id && zfail) stencil = 0x1 - RCache.set_CullMode(CULL_CCW); - RCache.set_Stencil( - TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); - draw_volume(RCache, L); - - // nv-stencil recompression - if (RImplementation.o.nvstencil) - u_stencil_optimize(RCache); - - // ***************************** Minimize overdraw ************************************* - // Select shader (front or back-faces), *** back, if intersect near plane - RCache.set_ColorWriteEnable(); - RCache.set_CullMode(CULL_CW); // back - /* - if (bIntersect) RCache.set_CullMode (CULL_CW); // back - else RCache.set_CullMode (CULL_CCW); // front - */ - - // 2D texgens - Fmatrix m_Texgen; - u_compute_texgen_screen(RCache, m_Texgen); - Fmatrix m_Texgen_J; - u_compute_texgen_jitter(RCache, m_Texgen_J); - - // Draw volume with projective texgen - { - // Select shader - u32 _id = 0; - if (L->flags.bShadow) - { - bool bFullSize = (L->X.S.size == u32(RImplementation.o.smapsize)); - if (L->X.S.transluent) - _id = SE_L_TRANSLUENT; - else if (bFullSize) - _id = SE_L_FULLSIZE; - else - _id = SE_L_NORMAL; - } - else - { - _id = SE_L_UNSHADOWED; - // m_Shadow = m_Lmap; - } - RCache.set_Element(shader->E[_id]); - - // Constants - RCache.set_c("Ldynamic_pos", L_pos.x, L_pos.y, L_pos.z, 1 / (L_R * L_R)); - RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - RCache.set_c("m_texgen", m_Texgen); - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - // Render if (stencil >= light_id && z-pass) - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, - D3DSTENCILOP_KEEP); - draw_volume(RCache, L); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - } - - // blend-copy - if (!RImplementation.o.fp16_blend) - { - u_setrt(RCache, rt_Accumulator, NULL, NULL, get_base_zb()); - RCache.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); - RCache.set_c("m_texgen", m_Texgen); - draw_volume(RCache, L); - } - - RCache.set_Scissor(0); - - // dwLightMarkerID += 2; // keep lowest bit always setted up - increment_light_marker(RCache); - - u_DBT_disable(); - - if (L->flags.bHudMode) - { - RImplementation.rmNormal(RCache); - // Restore projection - Device.mProject = Pold; - Device.mFullTransform = FTold; - RCache.set_xform_project(Device.mProject); - } -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_spot.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_spot.cpp deleted file mode 100644 index 7df332ec713..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_accum_spot.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "stdafx.h" -#include "Layers/xrRender/du_cone.h" - -// extern Fvector du_cone_vertices[DU_CONE_NUMVERTEX]; - -void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) -{ - phase_accumulator(RCache); - RImplementation.Stats.l_visible++; - - // *** assume accumulator setted up *** - // ***************************** Mask by stencil ************************************* - ref_shader shader; - if (IRender_Light::OMNIPART == L->flags.type) - { - shader = L->s_point; - if (!shader) - shader = s_accum_point; - } - else - { - shader = L->s_spot; - if (!shader) - shader = s_accum_spot; - } - - BOOL bIntersect = FALSE; // enable_scissor(L); - { - // setup xform - L->xform_calc(); - RCache.set_xform_world(L->m_xform); - RCache.set_xform_view(Device.mView); - RCache.set_xform_project(Device.mProject); - bIntersect = enable_scissor(L); - enable_dbt_bounds(L); - - // *** similar to "Carmack's reverse", but assumes convex, non intersecting objects, - // *** thus can cope without stencil clear with 127 lights - // *** in practice, 'cause we "clear" it back to 0x1 it usually allows us to > 200 lights :) - RCache.set_ColorWriteEnable(FALSE); - RCache.set_Element(s_accum_mask->E[SE_MASK_SPOT]); // masker - - // backfaces: if (stencil>=1 && zfail) stencil = light_id - RCache.set_CullMode(CULL_CW); - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, - D3DSTENCILOP_REPLACE); - draw_volume(RCache, L); - - // frontfaces: if (stencil>=light_id && zfail) stencil = 0x1 - RCache.set_CullMode(CULL_CCW); - RCache.set_Stencil( - TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); - draw_volume(RCache, L); - } - - // nv-stencil recompression - if (RImplementation.o.nvstencil) - u_stencil_optimize(RCache); - - // ***************************** Minimize overdraw ************************************* - // Select shader (front or back-faces), *** back, if intersect near plane - RCache.set_ColorWriteEnable(); - RCache.set_CullMode(CULL_CW); // back - - // 2D texgens - Fmatrix m_Texgen; - u_compute_texgen_screen(RCache, m_Texgen); - Fmatrix m_Texgen_J; - u_compute_texgen_jitter(RCache, m_Texgen_J); - - // Shadow xform (+texture adjustment matrix) - Fmatrix m_Shadow, m_Lmap; - { - float smapsize = float(RImplementation.o.smapsize); - float fTexelOffs = (.5f / smapsize); - float view_dim = float(L->X.S.size - 2) / smapsize; - float view_sx = float(L->X.S.posX + 1) / smapsize; - float view_sy = float(L->X.S.posY + 1) / smapsize; - float fRange = float(1.f) * ps_r2_ls_depth_scale; - float fBias = ps_r2_ls_depth_bias; - Fmatrix m_TexelAdjust = {view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, -view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, - fRange, 0.0f, view_dim / 2.f + view_sx + fTexelOffs, view_dim / 2.f + view_sy + fTexelOffs, fBias, 1.0f}; - - // compute xforms - Fmatrix xf_view = L->X.S.view; - Fmatrix xf_project; - xf_project.mul(m_TexelAdjust, L->X.S.project); - m_Shadow.mul(xf_view, Device.mInvView); - m_Shadow.mulA_44(xf_project); - - // lmap - view_dim = 1.f; - view_sx = 0.f; - view_sy = 0.f; - Fmatrix m_TexelAdjust2 = {view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, -view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, - fRange, 0.0f, view_dim / 2.f + view_sx + fTexelOffs, view_dim / 2.f + view_sy + fTexelOffs, fBias, 1.0f}; - - // compute xforms - xf_project.mul(m_TexelAdjust2, L->X.S.project); - m_Lmap.mul(xf_view, Device.mInvView); - m_Lmap.mulA_44(xf_project); - } - - // Common constants - Fvector L_dir, L_clr, L_pos; - float L_spec; - L_clr.set(L->color.r, L->color.g, L->color.b); - L_clr.mul(L->get_LOD()); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_tiny(L_pos, L->position); - Device.mView.transform_dir(L_dir, L->direction); - L_dir.normalize(); - - // Draw volume with projective texgen - { - // Select shader - u32 _id = 0; - if (L->flags.bShadow) - { - bool bFullSize = (L->X.S.size == RImplementation.o.smapsize); - if (L->X.S.transluent) - _id = SE_L_TRANSLUENT; - else if (bFullSize) - _id = SE_L_FULLSIZE; - else - _id = SE_L_NORMAL; - } - else - { - _id = SE_L_UNSHADOWED; - m_Shadow = m_Lmap; - } - RCache.set_Element(shader->E[_id]); - - // Constants - float att_R = L->range * .95f; - float att_factor = 1.f / (att_R * att_R); - RCache.set_c("Ldynamic_pos", L_pos.x, L_pos.y, L_pos.z, att_factor); - RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - RCache.set_c("m_texgen", m_Texgen); - RCache.set_c("m_texgen_J", m_Texgen_J); - RCache.set_c("m_shadow", m_Shadow); - RCache.set_ca("m_lmap", 0, m_Lmap._11, m_Lmap._21, m_Lmap._31, m_Lmap._41); - RCache.set_ca("m_lmap", 1, m_Lmap._12, m_Lmap._22, m_Lmap._32, m_Lmap._42); - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - draw_volume(RCache, L); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - } - - // blend-copy - if (!RImplementation.o.fp16_blend) - { - u_setrt(RCache, rt_Accumulator, NULL, NULL, get_base_zb()); - RCache.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); - RCache.set_c("m_texgen", m_Texgen); - RCache.set_c("m_texgen_J", m_Texgen_J); - draw_volume(RCache, L); - } - RCache.set_Scissor(0); - // dwLightMarkerID += 2; // keep lowest bit always setted up - increment_light_marker(RCache); - - u_DBT_disable(); -} - -void CRenderTarget::accum_volumetric(CBackend& cmd_list, light* L) -{ - // if (L->flags.type != IRender_Light::SPOT) return; - if (!L->flags.bVolumetric) - return; - - phase_vol_accumulator(RCache); - - ref_shader shader; - shader = L->s_volumetric; - if (!shader) - shader = s_accum_volume; - - // *** assume accumulator setted up *** - // ***************************** Mask by stencil ************************************* - BOOL bIntersect = FALSE; // enable_scissor(L); - { - // setup xform - L->xform_calc(); - RCache.set_xform_world(L->m_xform); - RCache.set_xform_view(Device.mView); - RCache.set_xform_project(Device.mProject); - bIntersect = enable_scissor(L); - - // enable_dbt_bounds (L); - } - - RCache.set_ColorWriteEnable(); - RCache.set_CullMode(CULL_NONE); // back - - // 2D texgens - Fmatrix m_Texgen; - u_compute_texgen_screen(RCache, m_Texgen); - Fmatrix m_Texgen_J; - u_compute_texgen_jitter(RCache, m_Texgen_J); - - // Shadow xform (+texture adjustment matrix) - Fmatrix m_Shadow, m_Lmap; - Fmatrix mFrustumSrc; - CFrustum ClipFrustum; - { - float smapsize = float(RImplementation.o.smapsize); - float fTexelOffs = (.5f / smapsize); - float view_dim = float(L->X.S.size - 2) / smapsize; - float view_sx = float(L->X.S.posX + 1) / smapsize; - float view_sy = float(L->X.S.posY + 1) / smapsize; - float fRange = float(1.f) * ps_r2_ls_depth_scale; - float fBias = ps_r2_ls_depth_bias; - Fmatrix m_TexelAdjust = {view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, -view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, - fRange, 0.0f, view_dim / 2.f + view_sx + fTexelOffs, view_dim / 2.f + view_sy + fTexelOffs, fBias, 1.0f}; - - // compute xforms - Fmatrix xf_view = L->X.S.view; - Fmatrix xf_project; - xf_project.mul(m_TexelAdjust, L->X.S.project); - m_Shadow.mul(xf_view, Device.mInvView); - m_Shadow.mulA_44(xf_project); - - // lmap - view_dim = 1.f; - view_sx = 0.f; - view_sy = 0.f; - Fmatrix m_TexelAdjust2 = {view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, -view_dim / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, - fRange, 0.0f, view_dim / 2.f + view_sx + fTexelOffs, view_dim / 2.f + view_sy + fTexelOffs, fBias, 1.0f}; - - // compute xforms - xf_project.mul(m_TexelAdjust2, L->X.S.project); - m_Lmap.mul(xf_view, Device.mInvView); - m_Lmap.mulA_44(xf_project); - - // Compute light frustum in world space - mFrustumSrc.mul(L->X.S.project, xf_view); - ClipFrustum.CreateFromMatrix(mFrustumSrc, FRUSTUM_P_ALL); - // Adjust frustum far plane - // 4 - far, 5 - near - ClipFrustum.planes[4].d -= (ClipFrustum.planes[4].d + ClipFrustum.planes[5].d) * (1 - L->m_volumetric_distance); - } - - // Calculate camera space AABB - // xform BB - /* - Fbox BB; - Fvector rr; rr.set(L->spatial.sphere.R,L->spatial.sphere.R,L->spatial.sphere.R); - BB.setb (L->spatial.sphere.P, rr); - - Fbox bbp; bbp.invalidate(); - for (u32 i=0; i<8; i++) { - Fvector pt; - BB.getpoint (i,pt); - //Device.mFullTransform.transform (pt); - Device.mFullTransform.transform (mView); - bbp.modify (pt); - } - */ - - // Calculate camera space AABB - // Adjust AABB according to the adjusted distance for the light volume - Fbox aabb; - - // float scaledRadius = L->spatial.sphere.R * (1+L->m_volumetric_distance)*0.5f; - float scaledRadius = L->spatial.sphere.R * L->m_volumetric_distance; - Fvector rr = Fvector().set(scaledRadius, scaledRadius, scaledRadius); - Fvector pt = L->spatial.sphere.P; - pt.sub(L->position); - pt.mul(L->m_volumetric_distance); - pt.add(L->position); - // Don't adjust AABB - // float scaledRadius = L->spatial.sphere.R; - // Fvector rr = Fvector().set(scaledRadius,scaledRadius,scaledRadius); - // Fvector pt = L->spatial.sphere.P; - Device.mView.transform(pt); - aabb.setb(pt, rr); - /* - // Calculate presise AABB assuming we are drawing for the spot light - { - aabb.invalidate(); - Fmatrix transform; - transform.mul( Device.mView, L->m_xform); - for (u32 i=0; im_volumetric_quality; - int iNumSlises = (int)(VOLUMETRIC_SLICES * fQuality); - // min 10 surfaces - iNumSlises = _max(10, iNumSlises); - // Adjust slice intensity - fQuality = ((float)iNumSlises) / VOLUMETRIC_SLICES; - Fvector L_dir, L_clr, L_pos; - float L_spec; - L_clr.set(L->color.r, L->color.g, L->color.b); - L_clr.mul(L->m_volumetric_intensity); - L_clr.mul(L->m_volumetric_distance); - L_clr.mul(1 / fQuality); - L_clr.mul(L->get_LOD()); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_tiny(L_pos, L->position); - Device.mView.transform_dir(L_dir, L->direction); - L_dir.normalize(); - - // Draw volume with projective texgen - { - /* - // Select shader - u32 _id = 0; - if (L->flags.bShadow) { - bool bFullSize = (L->X.S.size == RImplementation.o.smapsize); - if (L->X.S.transluent) _id = SE_L_TRANSLUENT; - else if (bFullSize) _id = SE_L_FULLSIZE; - else _id = SE_L_NORMAL; - } else { - _id = SE_L_UNSHADOWED; - m_Shadow = m_Lmap; - } - RCache.set_Element (shader->E[ _id ] ); - */ - - RCache.set_Element(shader->E[0]); - - // Constants - float att_R = L->m_volumetric_distance * L->range * .95f; - float att_factor = 1.f / (att_R * att_R); - RCache.set_c("Ldynamic_pos", L_pos.x, L_pos.y, L_pos.z, att_factor); - RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - RCache.set_c("m_texgen", m_Texgen); - RCache.set_c("m_texgen_J", m_Texgen_J); - RCache.set_c("m_shadow", m_Shadow); - RCache.set_ca("m_lmap", 0, m_Lmap._11, m_Lmap._21, m_Lmap._31, m_Lmap._41); - RCache.set_ca("m_lmap", 1, m_Lmap._12, m_Lmap._22, m_Lmap._32, m_Lmap._42); - RCache.set_c("vMinBounds", aabb.x1, aabb.y1, aabb.z1, 0.f); - // Increase camera-space aabb z size to compensate decrease of slices number - RCache.set_c("vMaxBounds", aabb.x2, aabb.y2, aabb.z1 + (aabb.z2 - aabb.z1) / fQuality, 0.0f); - - // Set up user clip planes - { - // Transform frustum to clip space - Fmatrix PlaneTransform; - PlaneTransform.transpose(Device.mInvFullTransform); - HW.pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0x3F); - - for (int i = 0; i < 6; ++i) - { - Fvector4& ClipPlane = *(Fvector4*)&ClipFrustum.planes[i].n.x; - Fvector4 TransformedPlane; - PlaneTransform.transform(TransformedPlane, ClipPlane); - TransformedPlane.mul(-1.0f); - HW.pDevice->SetClipPlane(i, &TransformedPlane.x); - } - } - - /* - float clip[4]; - clip[0] = 1; - clip[1] = - clip[2] = - clip[3] = 0; - HW.pDevice->SetClipPlane( 0, clip); - */ - - // Fetch4 : enable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET4 MAKEFOURCC('G', 'E', 'T', '4') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4); - } - - RCache.set_ColorWriteEnable(D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); - - RCache.set_Geometry(g_accum_volumetric); - // RCache.Render(D3DPT_TRIANGLELIST,0,0,VOLUMETRIC_SLICES*4,0,VOLUMETRIC_SLICES*2); - RCache.Render(D3DPT_TRIANGLELIST, 0, 0, iNumSlises * 4, 0, iNumSlises * 2); - - RCache.set_ColorWriteEnable(); - - // Fetch4 : disable - if (RImplementation.o.HW_smap_FETCH4) - { -//. we hacked the shader to force smap on S0 -#define FOURCC_GET1 MAKEFOURCC('G', 'E', 'T', '1') - HW.pDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1); - } - - // Restore clip planes - RCache.set_ClipPlanes(FALSE, (Fmatrix*)0, 0); - } - /* - // blend-copy - if (!RImplementation.o.fp16_blend) { - u_setrt (rt_Accumulator,NULL,NULL,get_base_zb()); - RCache.set_Element (s_accum_mask->E[SE_MASK_ACCUM_VOL] ); - RCache.set_c ("m_texgen", m_Texgen); - RCache.set_c ("m_texgen_J", m_Texgen_J ); - draw_volume (L); - } - */ - RCache.set_Scissor(0); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_build_textures.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_build_textures.cpp deleted file mode 100644 index 86c1ec383dd..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_build_textures.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "stdafx.h" - -static void generate_jitter(u32* dest, u32 elem_count) -{ - const int cmax = 8; - svector samples; - while (samples.size() < elem_count * 2) - { - Ivector2 test; - test.set(Random.randI(0, 256), Random.randI(0, 256)); - BOOL valid = TRUE; - for (u32 t = 0; t < samples.size(); t++) - { - int dist = _abs(test.x - samples[t].x) + _abs(test.y - samples[t].y); - if (dist < 32) - { - valid = FALSE; - break; - } - } - if (valid) - samples.push_back(test); - } - for (u32 it = 0; it < elem_count; it++, dest++) - *dest = color_rgba(samples[2 * it].x, samples[2 * it].y, samples[2 * it + 1].y, samples[2 * it + 1].x); -} - -void CRenderTarget::build_textures() -{ - // Igor: TMP - // Create an RT for online screenshot makining - { - D3DSURFACE_DESC desc; - get_base_rt()->GetDesc(&desc); - rt_async_ss.create(r2_async_ss, Device.dwWidth, Device.dwHeight, desc.Format, 1, { CRT::CreateSurface }); - } - // Build material(s) - { - // Surface - ID3DTexture3D* temp_material_surf; - ID3DTexture3D* t_material_surf; - - R_CHK(HW.pDevice->CreateVolumeTexture(TEX_material_LdotN, TEX_material_LdotH, 4, 1, 0, D3DFMT_A8L8, - D3DPOOL_SYSTEMMEM, &temp_material_surf, nullptr)); - R_CHK(HW.pDevice->CreateVolumeTexture(TEX_material_LdotN, TEX_material_LdotH, 4, 1, 0, D3DFMT_A8L8, - D3DPOOL_DEFAULT, &t_material_surf, nullptr)); - - // Fill it (addr: x=dot(L,N),y=dot(L,H)) - D3DLOCKED_BOX R; - R_CHK(temp_material_surf->LockBox(0, &R, 0, 0)); - for (u32 slice = 0; slice < 4; slice++) - { - for (u32 y = 0; y < TEX_material_LdotH; y++) - { - for (u32 x = 0; x < TEX_material_LdotN; x++) - { - u16* p = (u16*)((u8*)(R.pBits) + slice * R.SlicePitch + y * R.RowPitch + x * 2); - float ld = float(x) / float(TEX_material_LdotN - 1); - float ls = float(y) / float(TEX_material_LdotH - 1) + EPS_S; - ls *= powf(ld, 1 / 32.f); - float fd, fs; - - switch (slice) - { - case 0: - { // looks like OrenNayar - fd = powf(ld, 0.75f); // 0.75 - fs = powf(ls, 16.f) * .5f; - } - break; - case 1: - { // looks like Blinn - fd = powf(ld, 0.90f); // 0.90 - fs = powf(ls, 24.f); - } - break; - case 2: - { // looks like Phong - fd = ld; // 1.0 - fs = powf(ls * 1.01f, 128.f); - } - break; - case 3: - { // looks like Metal - float s0 = _abs(1 - _abs(0.05f * _sin(33.f * ld) + ld - ls)); - float s1 = _abs(1 - _abs(0.05f * _cos(33.f * ld * ls) + ld - ls)); - float s2 = _abs(1 - _abs(ld - ls)); - fd = ld; // 1.0 - fs = powf(_max(_max(s0, s1), s2), 24.f); - fs *= powf(ld, 1 / 7.f); - } - break; - default: fd = fs = 0; - } - s32 _d = clampr(iFloor(fd * 255.5f), 0, 255); - s32 _s = clampr(iFloor(fs * 255.5f), 0, 255); - if ((y == (TEX_material_LdotH - 1)) && (x == (TEX_material_LdotN - 1))) - { - _d = 255; - _s = 255; - } - *p = u16(_s * 256 + _d); - } - } - } - R_CHK(temp_material_surf->UnlockBox(0)); - - HW.pDevice->UpdateTexture(temp_material_surf, t_material_surf); - _RELEASE(temp_material_surf); - - t_material = RImplementation.Resources->_CreateTexture(r2_material); - t_material->surface_set(t_material_surf); - _RELEASE(t_material_surf); - } - - // Build noise table - { - // Surfaces - ID3DTexture2D* temp_noise_surf[TEX_jitter_count]{}; - ID3DTexture2D* t_noise_surf[TEX_jitter_count]{}; - D3DLOCKED_RECT R[TEX_jitter_count]{}; - - for (int it1 = 0; it1 < TEX_jitter_count - 1; it1++) - { - string_path name; - xr_sprintf(name, "%s%d", r2_jitter, it1); - t_noise[it1] = RImplementation.Resources->_CreateTexture(name); - - R_CHK(HW.pDevice->CreateTexture(TEX_jitter, TEX_jitter, 1, 0, - D3DFMT_Q8W8V8U8, D3DPOOL_SYSTEMMEM, &temp_noise_surf[it1], nullptr)); - R_CHK(HW.pDevice->CreateTexture(TEX_jitter, TEX_jitter, 1, 0, - D3DFMT_Q8W8V8U8, D3DPOOL_DEFAULT, &t_noise_surf[it1], nullptr)); - - R_CHK(temp_noise_surf[it1]->LockRect(0, &R[it1], nullptr, 0)); - } - - // Fill it, - for (u32 y = 0; y < TEX_jitter; y++) - { - for (u32 x = 0; x < TEX_jitter; x++) - { - u32 data[TEX_jitter_count - 1]; - generate_jitter(data, TEX_jitter_count - 1); - for (u32 it2 = 0; it2 < TEX_jitter_count - 1; it2++) - { - u32* p = (u32*)((u8*)(R[it2].pBits) + y * R[it2].Pitch + x * 4); - *p = data[it2]; - } - } - } - - for (int it3 = 0; it3 < TEX_jitter_count - 1; it3++) - { - R_CHK(temp_noise_surf[it3]->UnlockRect(0)); - - HW.pDevice->UpdateTexture(temp_noise_surf[it3], t_noise_surf[it3]); - _RELEASE(temp_noise_surf[it3]); - - t_noise[it3]->surface_set(t_noise_surf[it3]); - _RELEASE(t_noise_surf[it3]); - } - - // generate HBAO jitter texture (last) - int it = TEX_jitter_count - 1; - - R_CHK(HW.pDevice->CreateTexture(TEX_jitter, TEX_jitter, 1, 0, - D3DFMT_A32B32G32R32F, D3DPOOL_SYSTEMMEM, &temp_noise_surf[it], nullptr)); - R_CHK(HW.pDevice->CreateTexture(TEX_jitter, TEX_jitter, 1, 0, - D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &t_noise_surf[it], nullptr)); - - R_CHK(temp_noise_surf[it]->LockRect(0, &R[it], 0, 0)); - - // Fill it, - for (u32 y = 0; y < TEX_jitter; y++) - { - for (u32 x = 0; x < TEX_jitter; x++) - { - float numDir = 1.0f; - switch (ps_r_ssao) - { - case 1: numDir = 4.0f; break; - case 2: numDir = 6.0f; break; - case 3: numDir = 8.0f; break; - } - float angle = 2 * PI * ::Random.randF(0.0f, 1.0f) / numDir; - float dist = ::Random.randF(0.0f, 1.0f); - // float dest[4]; - - float* p = (float*)((u8*)(R[it].pBits) + y * R[it].Pitch + x * 4 * sizeof(float)); - *p = (float)(_cos(angle)); - *(p + 1) = (float)(_sin(angle)); - *(p + 2) = (float)(dist); - *(p + 3) = 0; - - // generate_hbao_jitter (data,TEX_jitter*TEX_jitter); - } - } - R_CHK(temp_noise_surf[it]->UnlockRect(0)); - - HW.pDevice->UpdateTexture(temp_noise_surf[it], t_noise_surf[it]); - _RELEASE(temp_noise_surf[it]); - - string_path name; - xr_sprintf(name, "%s%d", r2_jitter, it); - t_noise[it] = RImplementation.Resources->_CreateTexture(name); - t_noise[it]->surface_set(t_noise_surf[it]); - _RELEASE(t_noise_surf[it]); - } -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_combine.cpp deleted file mode 100644 index a3c1f6ebaa0..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_combine.cpp +++ /dev/null @@ -1,583 +0,0 @@ -#include "stdafx.h" -#include "xrEngine/IGame_Persistent.h" -#include "xrEngine/Environment.h" -#include "Layers/xrRender/dxEnvironmentRender.h" - -#define STENCIL_CULL 0 - -void CRenderTarget::DoAsyncScreenshot() -{ - if (RImplementation.m_bMakeAsyncSS) - { - HRESULT hr; - - IDirect3DSurface9* pFBSrc = get_base_rt(); - - // Don't addref, no need to release. - // ID3DTexture2D *pTex = rt_Color->pSurface; - - // hr = pTex->GetSurfaceLevel(0, &pFBSrc); - - // SHould be async function - hr = HW.pDevice->GetRenderTargetData(pFBSrc, rt_async_ss->pRT); - - // pFBSrc->Release(); - - RImplementation.m_bMakeAsyncSS = false; - } -} - -float hclip(float v, float dim) { return 2.f * v / dim - 1.f; } -void CRenderTarget::phase_combine() -{ - PIX_EVENT(phase_combine); - - bool _menu_pp = g_pGamePersistent ? g_pGamePersistent->OnRenderPPUI_query() : false; - - u32 Offset = 0; - Fvector2 p0, p1; - - //*** exposure-pipeline - u32 gpu_id = Device.dwFrame % HW.Caps.iGPUNum; - { - t_LUM_src->surface_set(rt_LUM_pool[gpu_id * 2 + 0]->pSurface); - t_LUM_dest->surface_set(rt_LUM_pool[gpu_id * 2 + 1]->pSurface); - } - - RCache.set_CullMode(CULL_NONE); - - if (RImplementation.o.ssao_opt_data) - { - phase_downsamp(); - // phase_ssao(); - } - else if (RImplementation.o.ssao_blur_on) - phase_ssao(); - - // low/hi RTs - u_setrt(RCache, rt_Generic_0, rt_Generic_1, 0, get_base_zb()); - RCache.set_Stencil(FALSE); - - BOOL split_the_scene_to_minimize_wait = FALSE; - if (ps_r2_ls_flags.test(R2FLAG_EXP_SPLIT_SCENE)) - split_the_scene_to_minimize_wait = TRUE; - - // draw skybox - if (1) - { - RCache.set_ColorWriteEnable(); - RCache.set_Z(false); - g_pGamePersistent->Environment().RenderSky(); - // Igor: Render clouds before compine without Z-test - // to avoid siluets. HOwever, it's a bit slower process. - g_pGamePersistent->Environment().RenderClouds(); - RCache.set_Z(true); - } - - // - // if (RImplementation.o.bug) { - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); // stencil should be >= 1 - if (RImplementation.o.nvstencil) - { - u_stencil_optimize(RCache, FALSE); - RCache.set_ColorWriteEnable(); - } - //} - - // calc m-blur matrices - Fmatrix m_previous, m_current; - Fvector2 m_blur_scale; - { - static Fmatrix m_saved_viewproj; - - // (new-camera) -> (world) -> (old_viewproj) - m_previous.mul(m_saved_viewproj, Device.mInvView); - m_current.set(Device.mProject); - m_saved_viewproj.set(Device.mFullTransform); - float scale = ps_r2_mblur / 2.f; - m_blur_scale.set(scale, -scale).div(12.f); - } - - // Draw full-screen quad textured with our scene image - if (!_menu_pp) - { - // Compute params - const auto& envdesc = g_pGamePersistent->Environment().CurrentEnv; - const float minamb = 0.001f; - Fvector4 ambclr = - { - std::max(envdesc.ambient.x * 2.f, minamb), - std::max(envdesc.ambient.y * 2.f, minamb), - std::max(envdesc.ambient.z * 2.f, minamb), - 0 - }; - ambclr.mul(ps_r2_sun_lumscale_amb); - - Fvector4 envclr = envdesc.env_color; - envclr.x *= 2 * ps_r2_sun_lumscale_hemi; - envclr.y *= 2 * ps_r2_sun_lumscale_hemi; - envclr.z *= 2 * ps_r2_sun_lumscale_hemi; - - Fvector4 fogclr = {envdesc.fog_color.x, envdesc.fog_color.y, envdesc.fog_color.z, 0}; - Fvector4 sunclr, sundir; - - float fSSAONoise = 2.0f; - fSSAONoise *= tan(deg2rad(67.5f / 2.0f)); - fSSAONoise /= tan(deg2rad(Device.fFOV / 2.0f)); - - float fSSAOKernelSize = 150.0f; - fSSAOKernelSize *= tan(deg2rad(67.5f / 2.0f)); - fSSAOKernelSize /= tan(deg2rad(Device.fFOV / 2.0f)); - - // sun-params - { - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - sunclr.set(L_clr.x, L_clr.y, L_clr.z, L_spec); - sundir.set(L_dir.x, L_dir.y, L_dir.z, 0); - } - - // Fill VB - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - - // Fill vertex buffer - // Fvector4* pv = (Fvector4*) RImplementation.Vertex.Lock (4,g_combine_VP->vb_stride,Offset); - // pv->set (hclip(EPS, _w), hclip(_h+EPS, _h), p0.x, p1.y); pv++; - // pv->set (hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y); pv++; - // pv->set (hclip(_w+EPS, _w), hclip(_h+EPS, _h), p1.x, p1.y); pv++; - // pv->set (hclip(_w+EPS, _w), hclip(EPS, _h), p1.x, p0.y); pv++; - // RImplementation.Vertex.Unlock (4,g_combine_VP->vb_stride); - - // Fill VB - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - float scale_Y = float(Device.dwHeight) / float(TEX_jitter); - - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine_VP->vb_stride, Offset); - pv->set(hclip(EPS, _w), hclip(_h + EPS, _h), p0.x, p1.y, 0, 0, scale_Y); - pv++; - pv->set(hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y, 0, 0, 0); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(_h + EPS, _h), p1.x, p1.y, 0, scale_X, scale_Y); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(EPS, _h), p1.x, p0.y, 0, scale_X, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_VP->vb_stride); - - // Draw - RCache.set_Element(s_combine->E[0]); - RCache.set_Geometry(g_combine_VP); - //RCache.set_Geometry(g_combine); - - RCache.set_c("m_v2w", Device.mInvView); - RCache.set_c("L_ambient", ambclr); - - RCache.set_c("Ldynamic_color", sunclr); - RCache.set_c("Ldynamic_dir", sundir); - - RCache.set_c("env_color", envclr); - RCache.set_c("fog_color", fogclr); - RCache.set_c("ssao_params", fSSAONoise, fSSAOKernelSize, 0.0f, 0.0f); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // Forward rendering - { - PIX_EVENT(Forward_rendering); - u_setrt(RCache, rt_Generic_0, 0, 0, get_base_zb()); // LDR RT - RCache.set_CullMode(CULL_CCW); - RCache.set_Stencil(FALSE); - RCache.set_ColorWriteEnable(); - // g_pGamePersistent->Environment().RenderClouds (); - RImplementation.render_forward(); - if (g_pGamePersistent) - g_pGamePersistent->OnRenderPPUI_main(); // PP-UI - } - - // Igor: for volumetric lights - // combine light volume here - if (m_bHasActiveVolumetric) - phase_combine_volumetric(); - - // Perform blooming filter and distortion if needed - RCache.set_Stencil(FALSE); - phase_bloom(); // HDR RT invalidated here - - // Distortion filter - BOOL bDistort = RImplementation.o.distortion_enabled; // This can be modified - { - auto& dsgraph = RImplementation.get_imm_context(); - if ((0 == dsgraph.mapDistort.size()) && !_menu_pp) - bDistort = FALSE; - if (bDistort) - { - PIX_EVENT(render_distort_objects); - u_setrt(RCache, rt_Generic_1, 0, 0, get_base_zb()); // Now RT is a distortion mask - RCache.ClearRT(rt_Generic_1, color_rgba(127, 127, 0, 127)); - RCache.set_CullMode(CULL_CCW); - RCache.set_Stencil(FALSE); - RCache.set_ColorWriteEnable(); - dsgraph.render_distort(); - } - } - - // PP enabled ? - // Render to RT texture to be able to copy RT even in windowed mode. - BOOL PP_Complex = u_need_PP() | (BOOL)RImplementation.m_bMakeAsyncSS; - if (_menu_pp) - PP_Complex = FALSE; - - // Combine everything + perform AA - if (PP_Complex) - u_setrt(RCache, rt_Color, 0, 0, get_base_zb()); // LDR RT - else - u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), NULL, NULL, get_base_zb()); - //. u_setrt ( Device.dwWidth,Device.dwHeight,get_base_rt(),NULL,NULL,get_base_zb()); - RCache.set_CullMode(CULL_NONE); - RCache.set_Stencil(FALSE); - if (1) - { - PIX_EVENT(combine_2); - // - struct v_aa - { - Fvector4 p; - Fvector2 uv0; - Fvector2 uv1; - Fvector2 uv2; - Fvector2 uv3; - Fvector2 uv4; - Fvector4 uv5; - Fvector4 uv6; - }; - - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - float ddw = 1.f / _w; - float ddh = 1.f / _h; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - - // Fill vertex buffer - v_aa* pv = (v_aa*)RImplementation.Vertex.Lock(4, g_aa_AA->vb_stride, Offset); - pv->p.set(EPS, float(_h + EPS), EPS, 1.f); - pv->uv0.set(p0.x, p1.y); - pv->uv1.set(p0.x - ddw, p1.y - ddh); - pv->uv2.set(p0.x + ddw, p1.y + ddh); - pv->uv3.set(p0.x + ddw, p1.y - ddh); - pv->uv4.set(p0.x - ddw, p1.y + ddh); - pv->uv5.set(p0.x - ddw, p1.y, p1.y, p0.x + ddw); - pv->uv6.set(p0.x, p1.y - ddh, p1.y + ddh, p0.x); - pv++; - pv->p.set(EPS, EPS, EPS, 1.f); - pv->uv0.set(p0.x, p0.y); - pv->uv1.set(p0.x - ddw, p0.y - ddh); - pv->uv2.set(p0.x + ddw, p0.y + ddh); - pv->uv3.set(p0.x + ddw, p0.y - ddh); - pv->uv4.set(p0.x - ddw, p0.y + ddh); - pv->uv5.set(p0.x - ddw, p0.y, p0.y, p0.x + ddw); - pv->uv6.set(p0.x, p0.y - ddh, p0.y + ddh, p0.x); - pv++; - pv->p.set(float(_w + EPS), float(_h + EPS), EPS, 1.f); - pv->uv0.set(p1.x, p1.y); - pv->uv1.set(p1.x - ddw, p1.y - ddh); - pv->uv2.set(p1.x + ddw, p1.y + ddh); - pv->uv3.set(p1.x + ddw, p1.y - ddh); - pv->uv4.set(p1.x - ddw, p1.y + ddh); - pv->uv5.set(p1.x - ddw, p1.y, p1.y, p1.x + ddw); - pv->uv6.set(p1.x, p1.y - ddh, p1.y + ddh, p1.x); - pv++; - pv->p.set(float(_w + EPS), EPS, EPS, 1.f); - pv->uv0.set(p1.x, p0.y); - pv->uv1.set(p1.x - ddw, p0.y - ddh); - pv->uv2.set(p1.x + ddw, p0.y + ddh); - pv->uv3.set(p1.x + ddw, p0.y - ddh); - pv->uv4.set(p1.x - ddw, p0.y + ddh); - pv->uv5.set(p1.x - ddw, p0.y, p0.y, p1.x + ddw); - pv->uv6.set(p1.x, p0.y - ddh, p0.y + ddh, p1.x); - pv++; - RImplementation.Vertex.Unlock(4, g_aa_AA->vb_stride); - - // Set up variable - Fvector2 vDofKernel; - vDofKernel.set(0.5f / Device.dwWidth, 0.5f / Device.dwHeight); - vDofKernel.mul(ps_r2_dof_kernel_size); - - // Draw COLOR - if (ps_r2_ls_flags.test(R2FLAG_AA)) - RCache.set_Element(s_combine->E[bDistort ? 3 : 1]); // look at blender_combine.cpp - else - RCache.set_Element(s_combine->E[bDistort ? 4 : 2]); // look at blender_combine.cpp - RCache.set_c("e_barrier", ps_r2_aa_barier.x, ps_r2_aa_barier.y, ps_r2_aa_barier.z, 0.f); - RCache.set_c("e_weights", ps_r2_aa_weight.x, ps_r2_aa_weight.y, ps_r2_aa_weight.z, 0.f); - RCache.set_c("e_kernel", ps_r2_aa_kernel, ps_r2_aa_kernel, ps_r2_aa_kernel, 0.f); - RCache.set_c("m_current", m_current); - RCache.set_c("m_previous", m_previous); - RCache.set_c("m_blur", m_blur_scale.x, m_blur_scale.y, 0.f, 0.f); - Fvector3 dof; - g_pGamePersistent->GetCurrentDof(dof); - RCache.set_c("dof_params", dof.x, dof.y, dof.z, ps_r2_dof_sky); - //. RCache.set_c ("dof_params", ps_r2_dof.x, ps_r2_dof.y, ps_r2_dof.z, ps_r2_dof_sky); - RCache.set_c("dof_kernel", vDofKernel.x, vDofKernel.y, ps_r2_dof_kernel_size, 0.f); - - RCache.set_Geometry(g_aa_AA); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - RCache.set_Stencil(FALSE); - - // if FP16-BLEND !not! supported - draw flares here, overwise they are already in the bloom target - /* if (!RImplementation.o.fp16_blend)*/ - PIX_EVENT(LENS_FLARES); - g_pGamePersistent->Environment().RenderFlares(); // lens-flares - - // Igor: screenshot will not have postprocess applied. - // TODO: fox that later - - // PP-if required - if (PP_Complex) - { - PIX_EVENT(phase_pp); - phase_pp(); - } - - // Re-adapt luminance - RCache.set_Stencil(FALSE); - - //*** exposure-pipeline-clear - { - std::swap(rt_LUM_pool[gpu_id * 2 + 0], rt_LUM_pool[gpu_id * 2 + 1]); - t_LUM_src->surface_set(NULL); - t_LUM_dest->surface_set(NULL); - } - -#ifdef DEBUG - RCache.set_CullMode(CULL_CCW); - static xr_vector saved_dbg_planes; - if (bDebug) - saved_dbg_planes = dbg_planes; - else - dbg_planes = saved_dbg_planes; - - if (1) - for (u32 it = 0; it < dbg_planes.size(); it++) - { - Fplane& P = dbg_planes[it]; - Fvector zero; - zero.mul(P.n, P.d); - - Fvector L_dir, L_up = P.n, L_right; - L_dir.set(0, 0, 1); - if (_abs(L_up.dotproduct(L_dir)) > .99f) - L_dir.set(1, 0, 0); - L_right.crossproduct(L_up, L_dir); - L_right.normalize(); - L_dir.crossproduct(L_right, L_up); - L_dir.normalize(); - - Fvector p0, p1, p2, p3; - float sz = 100.f; - p0.mad(zero, L_right, sz).mad(L_dir, sz); - p1.mad(zero, L_right, sz).mad(L_dir, -sz); - p2.mad(zero, L_right, -sz).mad(L_dir, -sz); - p3.mad(zero, L_right, -sz).mad(L_dir, +sz); - RCache.dbg_DrawTRI(Fidentity, p0, p1, p2, 0xffffffff); - RCache.dbg_DrawTRI(Fidentity, p2, p3, p0, 0xffffffff); - } - - static xr_vector saved_dbg_lines; - if (bDebug) - saved_dbg_lines = dbg_lines; - else - dbg_lines = saved_dbg_lines; - - RCache.set_Z(true); - RCache.set_ZFunc(D3DCMP_LESSEQUAL); - HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - if (1) - for (u32 it = 0; it < dbg_lines.size(); it++) - { - RCache.dbg_DrawLINE(Fidentity, dbg_lines[it].P0, dbg_lines[it].P1, dbg_lines[it].color); - } -#endif - -// ********************* Debug -/* -if (0) { - u32 C = color_rgba (255,255,255,255); - float _w = float(Device.dwWidth)/3; - float _h = float(Device.dwHeight)/3; - - // draw light-spheres -#ifdef DEBUG - if (0) for (u32 it=0; itvb_stride,Offset); - pv->set ((IX+0)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p0.x, p1.y); pv++; - pv->set ((IX+0)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p0.x, p0.y); pv++; - pv->set ((IX+1)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p1.x, p1.y); pv++; - pv->set ((IX+1)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p1.x, p0.y); pv++; - RImplementation.Vertex.Unlock (4,g_combine->vb_stride); - - // Draw COLOR - RCache.set_Shader (s_combine_dbg_0); - RCache.set_Geometry (g_combine); - RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); - } - - // Draw quater-screen quad textured with our accumulator - if (0) - { - u32 IX=1,IY=1; - p0.set (.5f/_w, .5f/_h); - p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); - - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*) RImplementation.Vertex.Lock (4,g_combine->vb_stride,Offset); - pv->set ((IX+0)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p0.x, p1.y); pv++; - pv->set ((IX+0)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p0.x, p0.y); pv++; - pv->set ((IX+1)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p1.x, p1.y); pv++; - pv->set ((IX+1)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p1.x, p0.y); pv++; - RImplementation.Vertex.Unlock (4,g_combine->vb_stride); - - // Draw COLOR - RCache.set_Shader (s_combine_dbg_1); - RCache.set_Geometry (g_combine); - RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); - } -} -*/ -#ifdef DEBUG - dbg_spheres.clear(); - dbg_lines.clear(); - dbg_planes.clear(); -#endif -} - -void CRenderTarget::phase_wallmarks() -{ - // Targets - RCache.set_RT(NULL, 2); - RCache.set_RT(NULL, 1); - u_setrt(RCache, rt_Color, NULL, NULL, get_base_zb()); - // Stencil - draw only where stencil >= 0x1 - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); - RCache.set_CullMode(CULL_CCW); - RCache.set_ColorWriteEnable(D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); -} - -void CRenderTarget::phase_combine_volumetric() -{ - PIX_EVENT(phase_combine_volumetric); - u32 Offset = 0; - Fvector2 p0, p1; - - // u_setrt(rt_Generic_0,0,0,get_base_zb() ); // LDR RT - u_setrt(RCache, rt_Generic_0, rt_Generic_1, 0, get_base_zb()); - // Sets limits to both render targets - RCache.set_ColorWriteEnable(D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); - { - // Compute params - const auto& envdesc = g_pGamePersistent->Environment().CurrentEnv; - const float minamb = 0.001f; - Fvector4 ambclr = - { - std::max(envdesc.ambient.x * 2.f, minamb), - std::max(envdesc.ambient.y * 2.f, minamb), - std::max(envdesc.ambient.z * 2.f, minamb), - 0 - }; - ambclr.mul(ps_r2_sun_lumscale_amb); - - Fvector4 envclr = envdesc.env_color; - envclr.x *= 2 * ps_r2_sun_lumscale_hemi; - envclr.y *= 2 * ps_r2_sun_lumscale_hemi; - envclr.z *= 2 * ps_r2_sun_lumscale_hemi; - - Fvector4 fogclr = {envdesc.fog_color.x, envdesc.fog_color.y, envdesc.fog_color.z, 0}; - Fvector4 sunclr, sundir; - - // sun-params - { - light* fuckingsun = (light*)RImplementation.Lights.sun._get(); - Fvector L_dir, L_clr; - float L_spec; - L_clr.set(fuckingsun->color.r, fuckingsun->color.g, fuckingsun->color.b); - L_spec = u_diffuse2s(L_clr); - Device.mView.transform_dir(L_dir, fuckingsun->direction); - L_dir.normalize(); - - sunclr.set(L_clr.x, L_clr.y, L_clr.z, L_spec); - sundir.set(L_dir.x, L_dir.y, L_dir.z, 0); - } - - // Fill VB - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - - // Fill vertex buffer - // Fvector4* pv = (Fvector4*) RImplementation.Vertex.Lock (4,g_combine_VP->vb_stride,Offset); - // pv->set (hclip(EPS, _w), hclip(_h+EPS, _h), p0.x, p1.y); pv++; - // pv->set (hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y); pv++; - // pv->set (hclip(_w+EPS, _w), hclip(_h+EPS, _h), p1.x, p1.y); pv++; - // pv->set (hclip(_w+EPS, _w), hclip(EPS, _h), p1.x, p0.y); pv++; - // RImplementation.Vertex.Unlock (4,g_combine_VP->vb_stride); - - // Fill VB - float scale_X = float(Device.dwWidth) / float(TEX_jitter); - float scale_Y = float(Device.dwHeight) / float(TEX_jitter); - - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine_VP->vb_stride, Offset); - pv->set(hclip(EPS, _w), hclip(_h + EPS, _h), p0.x, p1.y, 0, 0, scale_Y); - pv++; - pv->set(hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y, 0, 0, 0); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(_h + EPS, _h), p1.x, p1.y, 0, scale_X, scale_Y); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(EPS, _h), p1.x, p0.y, 0, scale_X, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_VP->vb_stride); - - // Draw - RCache.set_Element(s_combine_volumetric->E[0]); - RCache.set_Geometry(g_combine_VP); - - RCache.set_c("m_v2w", Device.mInvView); - RCache.set_c("L_ambient", ambclr); - - RCache.set_c("Ldynamic_color", sunclr); - RCache.set_c("Ldynamic_dir", sundir); - - RCache.set_c("env_color", envclr); - RCache.set_c("fog_color", fogclr); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - RCache.set_ColorWriteEnable(); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_occq.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_occq.cpp deleted file mode 100644 index 933b6272941..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_occq.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "stdafx.h" - -void CRenderTarget::phase_occq() -{ - u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), NULL, NULL, get_base_zb()); - RCache.set_CullMode(CULL_CCW); - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); - RCache.set_ColorWriteEnable(FALSE); - RCache.set_Shader(s_occq); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_scene.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_scene.cpp deleted file mode 100644 index d24bc39e1e8..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_scene.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "stdafx.h" - -// startup -void CRenderTarget::phase_scene_prepare() -{ - PIX_EVENT(phase_scene_prepare); - // Clear depth & stencil - // u_setrt ( Device.dwWidth,Device.dwHeight,get_base_rt(),NULL,NULL,get_base_zb() ); - // CHK_DX ( HW.pDevice->Clear ( 0L, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x0, 1.0f, 0L) ); - // Igor: soft particles - - const auto& env = g_pGamePersistent->Environment().CurrentEnv; - const float fValue = env.m_fSunShaftsIntensity; - // TODO: add multiplication by sun color here - // if (fValue<0.0001) FlagSunShafts = 0; - - if (RImplementation.o.advancedpp && (ps_r2_ls_flags.test(R2FLAG_SOFT_PARTICLES | R2FLAG_DOF) || - ((ps_r_sun_shafts > 0) && (fValue >= 0.0001)) || (ps_r_ssao > 0))) - { - u_setrt(RCache, Device.dwWidth, Device.dwHeight, rt_Position->pRT, NULL, NULL, get_base_zb()); - CHK_DX(HW.pDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0x0, 1.0f, 0L)); - } - else - { - u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), NULL, NULL, get_base_zb()); - RCache.ClearZB(get_base_zb(), 1.f, 0); - } - - // Igor: for volumetric lights - m_bHasActiveVolumetric = false; - // Clear later if try to draw volumetric -} - -// begin -void CRenderTarget::phase_scene_begin() -{ - // Enable ANISO - for (u32 i = 0; i < HW.Caps.raster.dwStages; i++) - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, ps_r__tf_Anisotropic)); - - // Targets, use accumulator for temporary storage - if (RImplementation.o.albedo_wo) - u_setrt(RCache, rt_Position, rt_Normal, rt_Accumulator, get_base_zb()); - else - u_setrt(RCache, rt_Position, rt_Normal, rt_Color, get_base_zb()); - - // Stencil - write 0x1 at pixel pos - RCache.set_Stencil( - TRUE, D3DCMP_ALWAYS, 0x01, 0xff, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - - // Misc - draw only front-faces - CHK_DX(HW.pDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE)); - RCache.set_CullMode(CULL_CCW); - RCache.set_ColorWriteEnable(); -} - -void CRenderTarget::disable_aniso() -{ - // Disable ANISO - for (u32 i = 0; i < HW.Caps.raster.dwStages; i++) - CHK_DX(HW.pDevice->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1)); -} - -// end -void CRenderTarget::phase_scene_end() -{ - disable_aniso(); - - if (!RImplementation.o.albedo_wo) - return; - - // transfer from "rt_Accumulator" into "rt_Color" - u_setrt(RCache, rt_Color, 0, 0, get_base_zb()); - RCache.set_CullMode(CULL_NONE); - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); // stencil should be >= 1 - if (RImplementation.o.nvstencil) - u_stencil_optimize(RCache, FALSE); - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); // stencil should be >= 1 - RCache.set_ColorWriteEnable(); - - // common calc for quad-rendering - u32 Offset; - u32 C = color_rgba(255, 255, 255, 255); - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - Fvector2 p0, p1; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - float d_Z = EPS_S, d_W = 1.f; - - // Fill vertex buffer - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); - pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); - pv++; - pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); - pv++; - pv->set(float(_w + EPS), float(_h + EPS), d_Z, d_W, C, p1.x, p1.y); - pv++; - pv->set(float(_w + EPS), EPS, d_Z, d_W, C, p1.x, p0.y); - pv++; - RImplementation.Vertex.Unlock(4, g_combine->vb_stride); - - // if (stencil>=1 && aref_pass) stencil = light_id - RCache.set_Element(s_accum_mask->E[SE_MASK_ALBEDO]); // masker - RCache.set_Geometry(g_combine); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_smap_D.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_smap_D.cpp deleted file mode 100644 index 6019033543a..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_smap_D.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "stdafx.h" - -void CRenderTarget::phase_smap_direct(CBackend& cmd_list, light* L, u32 sub_phase) -{ - cmd_list.set_pass_targets( - rt_smap_surf, - nullptr, - nullptr, - rt_smap_depth - ); - - // Clear - if (SE_SUN_NEAR == sub_phase) - { - // optimized clear - const Irect rect = - { - L->X.D[sub_phase].minX, L->X.D[sub_phase].minY, - L->X.D[sub_phase].maxX, L->X.D[sub_phase].maxY - }; - cmd_list.ClearZBRect(rt_smap_depth, 1.0f, 1, &rect); - } - else - { - // full-clear - cmd_list.ClearZB(rt_smap_depth, 1.0f); - } - - // Stencil - disable - cmd_list.set_Stencil(FALSE); - - // Misc - draw only front/back-faces - /* - if (SE_SUN_NEAR==sub_phase) RCache.set_CullMode ( CULL_CCW ); // near - else { - if (RImplementation.o.HW_smap) RCache.set_CullMode ( CULL_CW ); // far, reversed - else RCache.set_CullMode ( CULL_CCW ); // far, front-faces - } - */ - // Cull always CCW. If you want to revert to previouse solution, please, revert bias setup/ - cmd_list.set_CullMode(CULL_CCW); // near - if (RImplementation.o.HW_smap) - cmd_list.set_ColorWriteEnable(FALSE); - else - cmd_list.set_ColorWriteEnable(); -} - -void CRenderTarget::phase_smap_direct_tsh(CBackend& cmd_list, light* /*L*/, u32 /*sub_phase*/) -{ - VERIFY(RImplementation.o.Tshadows); - cmd_list.set_ColorWriteEnable(); - cmd_list.ClearRT(cmd_list.get_RT(), { 1.0f, 1.0f, 1.0f, 1.0f }); // color_rgba(127, 127, 12, 12); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_ssao.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_ssao.cpp deleted file mode 100644 index d05e30df0f3..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_phase_ssao.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "stdafx.h" - -#pragma pack(push, 4) -struct v_ssao -{ - Fvector4 p; - Fvector2 uv0; - Fvector2 uv1; -}; -#pragma pack(pop) - -float hclip(float v, float dim); - -void CRenderTarget::phase_ssao() -{ - Fvector2 p0, p1; - u32 Offset = 0; - - // Targets - u_setrt(RCache, rt_ssao_temp, NULL, NULL, NULL); // No need for ZBuffer at all - RCache.ClearRT(rt_ssao_temp, {}); // black - - RCache.set_Z(false); - - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); // stencil should be >= 1 - if (RImplementation.o.nvstencil) - { - u_stencil_optimize(RCache, FALSE); - RCache.set_ColorWriteEnable(); - } - - RCache.set_Stencil(FALSE); // TODO - disable later - - { - // Fill VB - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - - float fSSAONoise = 2.0f; - fSSAONoise *= tan(deg2rad(67.5f)); - fSSAONoise /= tan(deg2rad(Device.fFOV)); - - float fSSAOKernelSize = 150.0f; - fSSAOKernelSize *= tan(deg2rad(67.5f)); - fSSAOKernelSize /= tan(deg2rad(Device.fFOV)); - - float scale_X = _w / float(TEX_jitter); - float scale_Y = _h / float(TEX_jitter); - - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine_VP->vb_stride, Offset); - pv->set(hclip(EPS, _w), hclip(_h + EPS, _h), p0.x, p1.y, 0, 0, scale_Y); - pv++; - pv->set(hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y, 0, 0, 0); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(_h + EPS, _h), p1.x, p1.y, 0, scale_X, scale_Y); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(EPS, _h), p1.x, p0.y, 0, scale_X, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_VP->vb_stride); - - RCache.set_Element(s_ssao->E[0]); - RCache.set_Geometry(g_combine_VP); - RCache.set_c("ssao_params", fSSAONoise, fSSAOKernelSize, 0.0f, 0.0f); - RCache.set_c("m_v2w", Device.mInvView); - - // HBAO constants - RCache.set_c("c1", _w * 0.5f, _h * 0.5f, 2.0f / _w, 2.0f / _h); - RCache.set_c("c2", 1.12245429f, 1.49660575f, 0.890904903f, 0.668178618f); - // RCache.set_c ("c3", 8.f, 8.f, 1.5f, 0.0f); - RCache.set_c("c4", 0.400009334f, 0.160007462f, 2.49994159f, _h / _w); - - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // re-enable z-buffer - RCache.set_Z(true); - RCache.set_Stencil(FALSE); -} - -void CRenderTarget::phase_downsamp() -{ - // IDirect3DSurface9 *source, *dest; - // rt_Position->pSurface->GetSurfaceLevel(0, &source); - // rt_half_depth->pSurface->GetSurfaceLevel(0, &dest); - // HW.pDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_POINT); - - Fvector2 p0, p1; - u32 Offset = 0; - - // Targets - u_setrt(RCache, rt_half_depth, NULL, NULL, NULL); // No need for ZBuffer at all - RCache.ClearRT(rt_half_depth, {}); // black - - RCache.set_Z(false); - - RCache.set_Stencil(FALSE); // TODO - disable later - - { - // Fill VB - float _w = float(Device.dwWidth) * 0.5f; - float _h = float(Device.dwHeight) * 0.5f; - p0.set(.5f / _w, .5f / _h); - p1.set((_w + .5f) / _w, (_h + .5f) / _h); - - float scale_X = _w / float(TEX_jitter); - float scale_Y = _h / float(TEX_jitter); - - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine_VP->vb_stride, Offset); - pv->set(hclip(EPS, _w), hclip(_h + EPS, _h), p0.x, p1.y, 0, 0, scale_Y); - pv++; - pv->set(hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y, 0, 0, 0); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(_h + EPS, _h), p1.x, p1.y, 0, scale_X, scale_Y); - pv++; - pv->set(hclip(_w + EPS, _w), hclip(EPS, _h), p1.x, p0.y, 0, scale_X, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_combine_VP->vb_stride); - - RCache.set_Element(s_ssao->E[1]); - RCache.set_Geometry(g_combine_VP); - RCache.set_c("m_v2w", Device.mInvView); - - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - - // re-enable z-buffer - RCache.set_Z(true); - RCache.set_Stencil(FALSE); -} diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget_u_set_rt.cpp b/src/Layers/xrRenderPC_R2/r2_rendertarget_u_set_rt.cpp deleted file mode 100644 index c88e5f5b4da..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget_u_set_rt.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "stdafx.h" - -void CRenderTarget::u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, IDirect3DSurface9* zb) -{ - VERIFY(_1); - dwWidth[cmd_list.context_id] = _1->dwWidth; - dwHeight[cmd_list.context_id] = _1->dwHeight; - if (_1) - cmd_list.set_RT(_1->pRT, 0); - else - cmd_list.set_RT(NULL, 0); - if (_2) - cmd_list.set_RT(_2->pRT, 1); - else - cmd_list.set_RT(NULL, 1); - if (_3) - cmd_list.set_RT(_3->pRT, 2); - else - cmd_list.set_RT(NULL, 2); - cmd_list.set_ZB(zb); - //RImplementation.rmNormal(); -} - -void CRenderTarget::u_setrt(CBackend& cmd_list, - u32 W, u32 H, IDirect3DSurface9* _1, IDirect3DSurface9* _2, IDirect3DSurface9* _3, IDirect3DSurface9* zb) -{ - VERIFY(_1); - dwWidth[cmd_list.context_id] = W; - dwHeight[cmd_list.context_id] = H; - VERIFY(_1); - cmd_list.set_RT(_1, 0); - cmd_list.set_RT(_2, 1); - cmd_list.set_RT(_3, 2); - cmd_list.set_ZB(zb); - //RImplementation.rmNormal(); -} diff --git a/src/Layers/xrRenderPC_R2/r2_shaders.cpp b/src/Layers/xrRenderPC_R2/r2_shaders.cpp deleted file mode 100644 index 8013e91f6c9..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_shaders.cpp +++ /dev/null @@ -1,543 +0,0 @@ -#include "stdafx.h" -#include "r2.h" -#include "Layers/xrRender/ShaderResourceTraits.h" -#include "Layers/xrRenderDX9/dx9shader_utils.h" -#include "xrCore/FileCRC32.h" - -template -static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, - T*& result, bool const disasm) -{ - HRESULT _hr = ShaderTypeTraits::CreateHWShader(buffer, buffer_size, result->sh); - if (FAILED(_hr)) - { - Log("! Shader: ", file_name); - Msg("! CreateHWShader hr == 0x%08x", _hr); - return E_FAIL; - } - - LPCVOID data = nullptr; - - _hr = FindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); - - if (SUCCEEDED(_hr) && data) - { - // Parse constant table data - result->constants.parse(const_cast(data), ShaderTypeTraits::GetShaderDest()); - } - else - Msg("! D3DXFindShaderComment %s hr == 0x%08x", file_name, _hr); - - if (disasm) - { - IShaderBlob* blob = nullptr; - DisassembleShader(buffer, buffer_size, FALSE, nullptr, &blob); - if (!blob) - return _hr; - - string_path dname; - strconcat(sizeof(dname), dname, "disasm" DELIMITER, file_name, ('v' == pTarget[0]) ? ".vs" : ".ps"); - IWriter* W = FS.w_open("$app_data_root$", dname); - W->w(blob->GetBufferPointer(), blob->GetBufferSize()); - FS.w_close(W); - _RELEASE(blob); - } - - return _hr; -} - -inline HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, - void*& result, bool const disasm) -{ - if (pTarget[0] == 'p') - return create_shader(pTarget, buffer, buffer_size, file_name, (SPS*&)result, disasm); - - if (pTarget[0] == 'v') - return create_shader(pTarget, buffer, buffer_size, file_name, (SVS*&)result, disasm); - - NODEFAULT; - return E_FAIL; -} - -HRESULT CRender::shader_compile( - pcstr name, IReader* fs, pcstr pFunctionName, pcstr pTarget, u32 Flags, void*& result) -{ - SHADER_MACRO defines[128]; - int def_it = 0; - - // Don't move these variables to lower scope! - string32 c_smapsize; - string32 c_gloss; - string32 c_sun_shafts; - string32 c_ssao; - string32 c_sun_quality; - - // Ascii's Screen Space Shaders - SSS preprocessor stuff - char c_rain_quality[32]; - char c_inter_grass[32]; - - char sh_name[MAX_PATH] = ""; - u32 len = 0; - // options - { - xr_sprintf(c_smapsize, "%04d", u32(m_SMAPSize)); - defines[def_it].Name = "SMAP_size"; - defines[def_it].Definition = c_smapsize; - def_it++; - xr_strcat(sh_name, c_smapsize); - len += xr_strlen(c_smapsize); - } - - if (o.fp16_filter) - { - defines[def_it].Name = "FP16_FILTER"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.fp16_filter); - ++len; - - if (o.fp16_blend) - { - defines[def_it].Name = "FP16_BLEND"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.fp16_blend); - ++len; - - if (o.HW_smap) - { - defines[def_it].Name = "USE_HWSMAP"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.HW_smap); - ++len; - - if (o.HW_smap_PCF) - { - defines[def_it].Name = "USE_HWSMAP_PCF"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.HW_smap_PCF); - ++len; - - if (o.HW_smap_FETCH4) - { - defines[def_it].Name = "USE_FETCH4"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.HW_smap_FETCH4); - ++len; - - if (o.sjitter) - { - defines[def_it].Name = "USE_SJITTER"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.sjitter); - ++len; - - if (HW.Caps.raster_major >= 3) - { - defines[def_it].Name = "USE_BRANCHING"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(HW.Caps.raster_major >= 3); - ++len; - - if (HW.Caps.geometry.bVTF) - { - defines[def_it].Name = "USE_VTF"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(HW.Caps.geometry.bVTF); - ++len; - - if (o.Tshadows) - { - defines[def_it].Name = "USE_TSHADOWS"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.Tshadows); - ++len; - - if (o.mblur) - { - defines[def_it].Name = "USE_MBLUR"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.mblur); - ++len; - - if (o.sunfilter) - { - defines[def_it].Name = "USE_SUNFILTER"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.sunfilter); - ++len; - - if (o.sunstatic) - { - defines[def_it].Name = "USE_R2_STATIC_SUN"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.sunstatic); - ++len; - - if (o.forcegloss) - { - xr_sprintf(c_gloss, "%f", o.forcegloss_v); - defines[def_it].Name = "FORCE_GLOSS"; - defines[def_it].Definition = c_gloss; - def_it++; - } - sh_name[len] = '0' + char(o.forcegloss); - ++len; - - if (o.forceskinw) - { - defines[def_it].Name = "SKIN_COLOR"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.forceskinw); - ++len; - - if (o.ssao_blur_on) - { - defines[def_it].Name = "USE_SSAO_BLUR"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.ssao_blur_on); - ++len; - - if (o.ssao_hbao) - { - defines[def_it].Name = "USE_HBAO"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.ssao_hbao); - ++len; - - if (o.ssao_opt_data) - { - defines[def_it].Name = "SSAO_OPT_DATA"; - if (o.ssao_half_data) - defines[def_it].Definition = "2"; - else - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(o.ssao_opt_data ? (o.ssao_half_data ? 2 : 1) : 0); - ++len; - - // skinning - if (m_skinning < 0) - { - defines[def_it].Name = "SKIN_NONE"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (0 == m_skinning) - { - defines[def_it].Name = "SKIN_0"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(0 == m_skinning); - ++len; - - if (1 == m_skinning) - { - defines[def_it].Name = "SKIN_1"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(1 == m_skinning); - ++len; - - if (2 == m_skinning) - { - defines[def_it].Name = "SKIN_2"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(2 == m_skinning); - ++len; - - if (3 == m_skinning) - { - defines[def_it].Name = "SKIN_3"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(3 == m_skinning); - ++len; - - if (4 == m_skinning) - { - defines[def_it].Name = "SKIN_4"; - defines[def_it].Definition = "1"; - def_it++; - } - sh_name[len] = '0' + char(4 == m_skinning); - ++len; - - // Igor: need restart options - if (RImplementation.o.advancedpp && ps_r2_ls_flags.test(R2FLAG_SOFT_WATER)) - { - defines[def_it].Name = "USE_SOFT_WATER"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r2_ls_flags.test(R2FLAG_SOFT_PARTICLES)) - { - defines[def_it].Name = "USE_SOFT_PARTICLES"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r2_ls_flags.test(R2FLAG_DOF)) - { - defines[def_it].Name = "USE_DOF"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r_sun_shafts) - { - xr_sprintf(c_sun_shafts, "%d", ps_r_sun_shafts); - defines[def_it].Name = "SUN_SHAFTS_QUALITY"; - defines[def_it].Definition = c_sun_shafts; - def_it++; - sh_name[len] = '0' + char(ps_r_sun_shafts); - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r_ssao) - { - xr_sprintf(c_ssao, "%d", ps_r_ssao); - defines[def_it].Name = "SSAO_QUALITY"; - defines[def_it].Definition = c_ssao; - def_it++; - sh_name[len] = '0' + char(ps_r_ssao); - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r_sun_quality) - { - xr_sprintf(c_sun_quality, "%d", ps_r_sun_quality); - defines[def_it].Name = "SUN_QUALITY"; - defines[def_it].Definition = c_sun_quality; - def_it++; - sh_name[len] = '0' + char(ps_r_sun_quality); - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (RImplementation.o.advancedpp && ps_r2_ls_flags.test(R2FLAG_STEEP_PARALLAX)) - { - defines[def_it].Name = "ALLOW_STEEPPARALLAX"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (ps_ssfx_rain_1.w > 0) - { - xr_sprintf(c_rain_quality, "%d", (u8)ps_ssfx_rain_1.w); - defines[def_it].Name = "SSFX_RAIN_QUALITY"; - defines[def_it].Definition = c_rain_quality; - def_it++; - xr_strcat(sh_name, c_rain_quality); - len += xr_strlen(c_rain_quality); - } - else - { - sh_name[len] = '0'; - ++len; - } - - if (ps_ssfx_grass_interactive.y > 0) - { - xr_sprintf(c_inter_grass, "%d", (u8)ps_ssfx_grass_interactive.y); - defines[def_it].Name = "SSFX_INT_GRASS"; - defines[def_it].Definition = c_inter_grass; - def_it++; - xr_strcat(sh_name, c_inter_grass); - len += xr_strlen(c_inter_grass); - } - else - { - sh_name[len] = '0'; - ++len; - } - - defines[def_it].Name = "SSFX_MODEXE"; - defines[def_it].Definition = "1"; - def_it++; - sh_name[len] = '1'; - ++len; - - sh_name[len] = '\0'; - -#ifndef USE_D3DX - // Required for compatibility with D3DCompile() - defines[def_it].Name = "point"; - defines[def_it].Definition = "__pnt__"; - def_it++; -#endif - - // finish - defines[def_it].Name = nullptr; - defines[def_it].Definition = nullptr; - def_it++; - - HRESULT _result = E_FAIL; - - char extension[3]; - strncpy_s(extension, pTarget, 2); - - string_path filename; - strconcat(sizeof(filename), filename, "r2" DELIMITER, name, ".", extension); - - string_path file_name; - { - string_path file; - strconcat(sizeof(file), file, "shaders_cache_oxr" DELIMITER, filename, DELIMITER, sh_name); - strconcat(sizeof(filename), filename, filename, DELIMITER, sh_name); - FS.update_path(file_name, "$app_data_root$", file); - } - - string_path shadersFolder; - FS.update_path(shadersFolder, "$game_shaders$", RImplementation.getShaderPath()); - - u32 fileCrc = 0; - getFileCrc32(fs, shadersFolder, fileCrc); - fs->seek(0); - - if (FS.exist(file_name)) - { - IReader* file = FS.r_open(file_name); - if (file->length() > 4) - { - u32 savedFileCrc = file->r_u32(); - if (savedFileCrc == fileCrc) - { - u32 savedBytecodeCrc = file->r_u32(); - u32 bytecodeCrc = crc32(file->pointer(), file->elapsed()); - if (bytecodeCrc == savedBytecodeCrc) - { -#ifdef DEBUG - Log("* Loading shader:", file_name); -#endif - _result = - create_shader(pTarget, (DWORD*)file->pointer(), file->elapsed(), filename, result, o.disasm); - } - } - } - file->close(); - } - - if (FAILED(_result)) - { - ShaderIncluder includer; - IShaderBlob* pShaderBuf = nullptr; - IShaderBlob* pErrorBuf = nullptr; - - _result = CompileShader(fs->pointer(), fs->length(), defines, &includer, - pFunctionName, pTarget, Flags, &pShaderBuf, &pErrorBuf); - if (SUCCEEDED(_result)) - { - IWriter* file = FS.w_open(file_name); - - file->w_u32(fileCrc); - - u32 crc = crc32(pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize()); - file->w_u32(crc); // Do not write anything below this line, take a look at reading (crc32) - - file->w(pShaderBuf->GetBufferPointer(), (u32)pShaderBuf->GetBufferSize()); - - FS.w_close(file); -#ifdef DEBUG - Log("- Compile shader:", file_name); -#endif - _result = create_shader(pTarget, (DWORD*)pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize(), - filename, result, o.disasm); - } - else - { - Log("! ", file_name); - if (pErrorBuf) - Log("! error: ", (LPCSTR)pErrorBuf->GetBufferPointer()); - else - Msg("Can't compile shader hr=0x%08x", _result); - } - } - - return _result; -} diff --git a/src/Layers/xrRenderPC_R2/r2_test_hw.cpp b/src/Layers/xrRenderPC_R2/r2_test_hw.cpp deleted file mode 100644 index 38cf98b2a66..00000000000 --- a/src/Layers/xrRenderPC_R2/r2_test_hw.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "stdafx.h" - -#include "Layers/xrRenderDX9/dx9shader_utils.h" - -BOOL xrRender_test_hw() -{ - D3DCAPS9 caps; - CHW _HW; - _HW.CreateD3D(); - - if (!_HW.pD3D || _HW.pD3D->GetAdapterCount() == 0) - return FALSE; - -#ifdef USE_D3DX - const bool shaderCompilerAvailable = XRay::ModuleHandle{ "d3dx9_31" }.IsLoaded(); - if (!shaderCompilerAvailable) - return FALSE; -#endif - - _HW.pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); - _HW.DestroyD3D(); - u16 ps_ver_major = u16(u32(u32(caps.PixelShaderVersion) & u32(0xf << 8ul)) >> 8); - u16 ps_instructions = u16(caps.PS20Caps.NumInstructionSlots); - u16 mrt_count = u16(caps.NumSimultaneousRTs); - if (ps_ver_major < 2) - return FALSE; - if (ps_instructions < 256) - return FALSE; - if (mrt_count < 3) - return FALSE; - if (ps_ver_major >= 3) - return TRUE+TRUE; // XXX: remove hack - return TRUE; -} diff --git a/src/Layers/xrRenderPC_R2/stdafx.cpp b/src/Layers/xrRenderPC_R2/stdafx.cpp deleted file mode 100644 index 80ac7d20a53..00000000000 --- a/src/Layers/xrRenderPC_R2/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// xrRender_R2.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/src/Layers/xrRenderPC_R2/stdafx.h b/src/Layers/xrRenderPC_R2/stdafx.h deleted file mode 100644 index a99ad8281ac..00000000000 --- a/src/Layers/xrRenderPC_R2/stdafx.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" - -#include "xrEngine/stdafx.h" - -#include "xrEngine/vis_common.h" -#include "xrEngine/Render.h" -#include "xrEngine/IGame_Level.h" - -#include "xrParticles/psystem.h" - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#include - -#include "Layers/xrRenderDX9/CommonTypes.h" - -#include "Layers/xrRenderDX9/dx9HW.h" - -#include "Layers/xrRender/Shader.h" - -#include "Layers/xrRender/R_Backend.h" -#include "Layers/xrRender/R_Backend_Runtime.h" - -#include "Layers/xrRender/Blender.h" -#include "Layers/xrRender/Blender_CLSID.h" - -#define R_GL 0 -#define R_R1 1 -#define R_R2 2 -#define R_R3 3 -#define R_R4 4 -#define RENDER R_R2 - -#include "Common/_d3d_extensions.h" - -#include "Layers/xrRender/ResourceManager.h" -#include "Layers/xrRender/xrRender_console.h" - -#include "r2.h" -#include "r2_rendertarget.h" - -IC void jitter(CBlender_Compile& C) -{ - C.r_Sampler("jitter0", JITTER(0), true, D3DTADDRESS_WRAP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); - C.r_Sampler("jitter1", JITTER(1), true, D3DTADDRESS_WRAP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); - C.r_Sampler("jitter2", JITTER(2), true, D3DTADDRESS_WRAP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); - C.r_Sampler("jitter3", JITTER(3), true, D3DTADDRESS_WRAP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); - C.r_Sampler("jitter4", JITTER(4), true, D3DTADDRESS_WRAP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); -} diff --git a/src/Layers/xrRenderPC_R2/todo.txt b/src/Layers/xrRenderPC_R2/todo.txt deleted file mode 100644 index 033eddd47d9..00000000000 --- a/src/Layers/xrRenderPC_R2/todo.txt +++ /dev/null @@ -1,205 +0,0 @@ ----------------------------- -done, ~7% perf-gain : intelligent RT-switches sheduling + give some time to complete RT-rendering -done, ~5.5% perf-gain : cull point-light frustums against real frustum -done, works OK : fixed coordinate system for point lights - should minimize flickering - : clip every-light frustums against real frustum - difficult - : scissoring ??? -done, works OK : 3*32 bit RTs - position/normal compression -done, works OK : bilinear/q-linear filter for cubemaps -done, works OK : 2*DXT5 bumpmaps + heightmaps - lower quality, 8 bit, faster(?) ----------------------------- - : A8L8 encoding of encodeRG - : L8 encoding of encodeB + mov instead add - : A8L8 encoding of material ----------------------------- -smap_res: fixed(36.0), adaptive(36.9), minus one RT-switch(37.5) -433/1.08Ghz:optimized spot-shadow-shaders + aref( 31.3 ) -433/1.08Ghz:agressive scissoring ( 33.8 ) -same,60.50 :all + optimized sphere ( 42.83 ) -same, + optimized order ( 57.20 ) ----------------------------- -433/1.2/60.50: 23.92/23.22 -433/1.2/60.60: ~23.8 -same,occq-delay: ~25.9 ----------------------------- -+BUG: mt_physics -+BUG: particles -+BUG: self-illum -+BUG: optimized sphere around cone-shape -BUG: scissor - reprojection -BUG: light - spanning multiple sectors -> connect to portals - -OPT: clipping light volume by visibility frustum (or primary) - should minimize geometry/fill req -OPT: if scissor is inside light volume we can construct more precise/smaller volume -OPT: occlusion culling of light volumes - 1. if camera inside - assume visible - 2. employ temporal coherence -OPT: precompute invisible list (visuals) for static lights at load time - -FEAT: shadows from transparent particles - 2x for light boost + colorful shadows? - -+FEATURE: incremental object level culling -+FEATURE: stats: -+FEATURE: materials: -+FEATURE: anisotropic -+FEATURE: range-fog -+FEATURE: particles/transparency -+ : light-sleeping logic -+ : faster bloom blur -+ : fading of bloom -+BUG : jumping transform for projected texture -+BUG : biasing for spot-lighting -+BUG : fucking light-flickering!!! -+BUG : DX-WARN: RT used while bound -+FEATURE: self-ilum -+BUG : fucking light near viewpoint!!! - -hw-pointlight -volume-fog -z-fade particles - -Engine/Game: - * refactor/rebuild collision detection infrastructure (along with Slipch) - - should speed up physics considerably ~1 week for me, ??? for Slipch - -Sound: - * I3DL2_reverb (?) - 3 days / Sanya (???) - -LevelCompiler/GeometryProcessing: - * R2: xrLC geometry selection for point/spot lights (???) - ? R2 only ? - * CDB - qSlim (???) / discrete attrs - ~1week - * better hemisphere / qSlim (???) - ~2weeks? - * SlidingWindow VIPM (???) - ~1week - -R1: - * per-pixel displacement + secondary channel - ~1week / ps2.0 / ps1.3 (1 day + 1 day) - * wallmarks on dynamic objects (?) - ~1week - * SlidingWindow VIPM / screen-error (???) - 3 day (max) - * ShadowCast cache (:BUG:) - -R2: - * work out point-light-hw-shadowmaps() - 1 day -done* work out tonemapping (?) - ? -done* work out blooming (again) -\ 3 days -done* work out skybox (again) -/ - * work out hemisphere (again) - 1 day (?) -done* work out ordinary rendering + transparency - 1 day (?) -done* work out HUD - 1 day (?) - * sRGB convert diffuse (???) - ? - * transluency (again + experiment) - 1day - 1week - * reverse culling for spot/point with initial clears - should avoid most biasing (?) - 1day - but can just not work :) - * 4*32bit RT(s) / emissive - 1day + emissive shaders (as need them) - * perspective shadow maps and all that stuff Gary talks about - 1month... 1year :))) - * wallmarks :) (?) - ? - * generated bumpmaps leaks - * surface material: - - emmisive map - done- detail-bump map - - anisotropic materials - 1 day - - material definition - (blin-bump-low-spec, 1=blin-bump-high-spec, 2=anisotroptic-low, 3=anisotroptic-high) / () - * SlidingWindow VIPM / screen-error (???) - 3 day (max) / R1 - * IRender_Light -> save/load -> R2 / shadow-no-shadow - 1 day me / 1 day sanya ----------------------------- - surface: - diffuse texture / diffuse detail (???) - height map [rgb](5cm) / detail heightmap - gloss map [a] (0..1) / - emisssive / 1 scalar / 1 koeff - none - material-id / 1 scalar - transluency / ??? ----------------------------- -blin-bump-low-spec , blin-bump-high-spec -blin-bump-high-spec , anisotroptic-low, -anisotroptic-low , anisotroptic-high ----------------------------- - bump: - format : Bump - + virtual_height : float (5cm default) - mipmaps : none - details : inaplicable - flags : inaplicable - fade : inaplicable - border : inaplicable - -> 2 textures (DXT5) - - texture: - format : 2D/Cube - + material_id : float - + bump_mode : flat, autogen, use - bump_autogen : height (5 cm, default) - bump_use : bump-texture - detail_mode : - bump_or_diffuse/diffuse/none - ----------------------------- -I think I understand it. Maybe I can help myself (and others) understand it better if I try to explain it. -I assume you know how the normal mapping works. The question is: how is the offset computed? - -1) for each vertex, transform the eye vector into tangent space so that 'z' represents the normal component -now for each fragment: -2) normalize the tangent-space eye vector. call it ~v -3) fetch the height of the texture, which represents the displacement of the surface. Scale and bias is used to map the fetched values of 0-1 to some range, such as -.02 to .02. You wouldn't need to do this with float textures, but you probably don't need the precision. Call the final height h. -4) to compute the offset, you have to find the intersection of a ray with direction ~v and height h to a a plane at height 0.(representing the texture surface). Because the x and y components of ~v represent the tangent plane coordinates, and 2D texture fetches ignore the z component, all you need to do is scale ~v by h. - -I think that's it? Any corrections/clarifications? ---- -Nice demo, Humus. The shadows do a nice job of hiding some of the ugly artifacts from the offset mapping -I noticed a couple posts complaining about things looking wrong at a distance, which is a good observation. -Keep in mind that the offset I calculate in the fragment program is a small-angle approximation. This code - -# calculate offset -TEX height, fragment.texcoord[0], texture[2], 2D; -MAD height, height, 0.04, -0.02; # scale and bias -MAD newtexcoord, height, eyevects, fragment.texcoord[0]; - -should really look like this: - -# calculate offset -TEX height, fragment.texcoord[0], texture[2], 2D; -MAD height, height, 0.04, -0.02; # scale and bias -RCP temp, eyevects.z; -MUL height, height, temp; -MAD newtexcoord, height, eyevects, fragment.texcoord[0]; - -All I did there was add a couple instructions to divide the offset by the eye vector's z component. This is more mathematically correct in one sense because it increases the steep angle offsets to their proper lengths. - -However, all these offsets assume that the texcoord their pointing to is the same height as the texcoord they're -starting at, which is almost never true. So making the offsets the correct length causes extra swimming in the -textures and actually makes things look worse in my opinion. In a nutshell, I'm using a small angle approximation -to tone down artifacts that result from another completely different approximation. - -Anyway, I hope that explanation makes some sense. It's really hard to describe this stuff without drawing pictures :P - /-------------------------------\ /-------------------------------\ - | RT_0 = depth | | RT_P = pos.1/len(pos), 4xFP16| /---------------------------\ -deffer -----| RT_1 = norm.mid |--decompress---| RT_N = norm.mid, 4xFP16 |--accumulate---| RT_ACCUM = total_light |--combine - | RT_COLOR = rgb.gloss | \-------------------------------/ \---------------------------/ - | RT_ACCUM = hemi+emissive | ------------------------------------------------------------------------------------------------ -light - logic: - color-animator + brightness - motion = pos + rotation - name (access) - -light - physic: - type = spot/point/... - flags = shadow cast/active/... - xform = pos/dir/right/... - range = - cone-angle = (spot) - virtual-size= point/spot - color = - texture = ------------------------------------------------------------------------------------------------ -struct def : public def -{ - typedef _previous AAA; - typedef _current BBB; -} -struct def : public def -{ - typedef _previous def::_current; - typedef _current CCC; -} - -accum (a,b) diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.cpp b/src/Layers/xrRenderPC_R2/xrRender_R2.cpp deleted file mode 100644 index 2863a6be4b0..00000000000 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "stdafx.h" -#include "Layers/xrRender/dxRenderFactory.h" -#include "Layers/xrRender/dxUIRender.h" -#include "Layers/xrRender/dxDebugRender.h" -#include "Layers/xrRender/D3DUtils.h" - -constexpr pcstr RENDERER_R2A_MODE = "renderer_r2a"; -constexpr pcstr RENDERER_R2_MODE = "renderer_r2"; -constexpr pcstr RENDERER_R2_5_MODE = "renderer_r2.5"; - -class R2RendererModule final : public RendererModule -{ - xr_vector modes; - -public: - BOOL CheckCanAddMode() const - { - // don't duplicate - if (!modes.empty()) - { - return FALSE; - } - // Check if shaders are available - if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) - { - Log("~ No shaders found for xrRender_R2"); - return FALSE; - } - return xrRender_test_hw(); - } - - const xr_vector& ObtainSupportedModes() override - { - switch (CheckCanAddMode()) - { - case TRUE: - modes.emplace_back(RENDERER_R2A_MODE); - modes.emplace_back(RENDERER_R2_MODE); - break; - case TRUE+TRUE: // XXX: remove hack - modes.emplace_back(RENDERER_R2A_MODE); // don't optimize this switch with fallthrough, - modes.emplace_back(RENDERER_R2_MODE); // because order matters. - modes.emplace_back(RENDERER_R2_5_MODE); - } - return modes; - } - - void CheckModeConsistency(pcstr mode) const - { - bool modeIsCorrect = false; - if (0 == xr_strcmp(mode, RENDERER_R2A_MODE) || - 0 == xr_strcmp(mode, RENDERER_R2_MODE) || - 0 == xr_strcmp(mode, RENDERER_R2_5_MODE)) - { - modeIsCorrect = true; - } - R_ASSERT3(modeIsCorrect, "Wrong mode passed to xrRender_R2", mode); - } - - void SetupEnv(pcstr mode) override - { - CheckModeConsistency(mode); - - ps_r2_sun_static = xr_strcmp(mode, RENDERER_R2A_MODE) == 0; - ps_r2_advanced_pp = xr_strcmp(mode, RENDERER_R2_5_MODE) == 0; - - GEnv.Render = &RImplementation; - GEnv.RenderFactory = &RenderFactoryImpl; - GEnv.DU = &DUImpl; - GEnv.UIRender = &UIRenderImpl; -#ifdef DEBUG - GEnv.DRender = &DebugRenderImpl; -#endif - xrRender_initconsole(); - } -} static s_r2_module; - -extern "C" -{ -XR_EXPORT RendererModule* GetRendererModule() -{ - return &s_r2_module; -} -} diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj deleted file mode 100644 index 467e502e9ff..00000000000 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - {963BA4E5-499A-454D-B002-1D5ECE0527A6} - xrRender_R2 - Win32Proj - - - - - - - x64 - - - - - - - - - - - - _USRDLL;XRRENDER_R2_EXPORTS;USE_DX9;%(PreprocessorDefinitions) - $(SolutionDir)Layers\xrRender_R2;$(xrExternals)imgui;$(xrExternals)OpenAutomate\inc;$(xrSdkDir)include\nvapi;$(xrSdkDir)include\DirectXMesh;%(AdditionalIncludeDirectories) - /bigobj %(AdditionalOptions) - - - nvapi$(PlatformArchitecture).lib;%(AdditionalDependencies) - $(xrExternals)OpenAutomate\libraries;%(AdditionalLibraryDirectories) - $(xrExternals)nvapi\x86;%(AdditionalLibraryDirectories) - $(xrExternals)nvapi\amd64;%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - - - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - {2578c6d8-660d-48ae-9322-7422f8664f06} - - - {94a1c366-3d19-48e6-8170-4adc2e70df97} - - - {132c62de-de85-4978-9675-c78ed4da46f0} - - - {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} - - - {7885cf3c-ee04-4c67-9467-1fbf9a36b037} - - - {a19b1df2-82ec-4364-8bdf-85d13a1c89b5} - - - {ccd4afae-aa10-42c6-a452-fdee497ccdf1} - - - {632aeeb6-dc06-4e15-9551-b2b09a4b73c5} - - - {c8fbc3ce-d6de-4fc3-bc15-7b647614db09} - - - {2c419512-6eee-4707-bc51-2e834855552e} - - - - - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters b/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters deleted file mode 100644 index 8b7124fa939..00000000000 --- a/src/Layers/xrRenderPC_R2/xrRender_R2.vcxproj.filters +++ /dev/null @@ -1,1176 +0,0 @@ - - - - - {a51ed64d-8e56-4d71-abea-3060f5d9e3c0} - - - {439c31f6-3e16-44fb-b8ed-199cfbb71813} - - - {344e2441-a9a8-4117-9694-95ebe5bf0b16} - - - {038140d7-515b-482b-af73-75646e6a4de0} - - - {4793b3f9-2f36-4910-93a8-113fb6608ff0} - - - {e0ae9ee9-4bce-4242-b2d6-723f2fe5203c} - - - {aafe15ce-aad2-4bbd-8fa0-132006e0ef6c} - - - {62a00cc7-2db9-438d-b84b-3016c647523b} - - - {00ec9ceb-c0ef-45d6-b1d3-88294881a041} - - - {265a0cd4-f150-4bc9-81df-a45405059083} - - - {dde972fa-cd29-40f9-a862-417c9e61d037} - - - {d3fa8b42-3bab-4a7b-9590-db689ad8ed6e} - - - {a8bdb93d-2d1c-4b8e-af27-829b011a134f} - - - {b19e237d-5eec-40a4-9962-3ac1ea52f9c0} - - - {29a85803-3f7b-4083-ae5d-f5e0fe981b79} - - - {f330c03c-e9fc-4160-85ff-28560f405afe} - - - {587e902d-66f6-49a4-a5d2-a497a1197372} - - - {b8f21539-a903-414f-b0b2-03fa30d30ef2} - - - {bcbbf091-ffb7-4cdf-938e-fc7c0ecdeb0d} - - - {efa0c1d4-7a2b-4031-80c2-30b1c2ed02f8} - - - {fb60f0a9-bc3d-4a9f-b1ce-d65046bb2d2f} - - - {e8655ea5-2e95-459e-ae9f-1ff51f999bc1} - - - {e3674591-33c3-4df5-baa0-7f4bdc31cae1} - - - {f2429e16-2b32-4ed2-8828-39ae85a7974d} - - - {b07ea356-5d83-4c65-a67b-1290c493cb68} - - - {1cda8ad5-51e4-42ef-8634-6d140e2e44cd} - - - {6ba4970f-ee23-4d83-9dea-837fe4f43392} - - - {03e91b32-39d7-4f8e-981d-5b3ce07b74be} - - - {432f159c-f346-4ed5-a927-4c88d68e179c} - - - {0c303bb7-4065-4aa3-9b55-aff83970241b} - - - {39da3398-290f-4e63-a57e-f621bc23b0b0} - - - {afcb6596-3146-4aff-bd85-c1b8ed4e3f1a} - - - {666e1d0a-9bd0-44fa-a402-cce51c34bfc2} - - - {ff32e41c-def1-48da-8ed3-bbec449f48fa} - - - {1c48aca4-e371-4968-83ef-8f28085aa575} - - - {528b5203-f36f-4523-8265-056946861d77} - - - {5b90fbc6-f737-4db5-af8b-aba7c1a592e4} - - - {ccd599e3-f117-4ddd-af5a-dc6d299fb889} - - - {b90449f5-b1cc-4f28-ab0a-296a6dc364bb} - - - {7758a04e-f21a-4151-9ef3-faa8c678ee68} - - - {316d97f2-7ec1-4450-97d6-4c7183304694} - - - {216e5078-cd0b-46d5-9dc0-1679fdf89816} - - - {22595237-844c-4760-8674-9e23f6e7899d} - - - {45cad128-d7a5-4099-bcbb-2d79b3553af7} - - - {14df8674-1067-4998-a470-187a5f3ac2a1} - - - {5054e2bc-1256-4afe-a525-19244eb688fd} - - - {0ac82fb7-e1cb-48cd-aed2-da8da1f3f01c} - - - {ee0c57b5-63d3-44e2-8eb5-9ba0d7d9891c} - - - {7b446f08-e762-4e42-9b67-0dd22dbfc8b4} - - - {6333f8ba-25fb-43b9-a4b6-e8aaf84692e5} - - - {84b8d63d-8ab9-454e-8af1-b51e4713fec0} - - - - - Kernel - - - Kernel - - - Kernel - - - Core - - - Core - - - Core - - - Core - - - Core - - - Details - - - Details - - - Stripifier - - - Stripifier - - - Stripifier - - - Stripifier - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Wallmarks - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates\R1 - - - Shading templates\R1 - - - Models - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Visibility\Sector/Portal - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Core_Target - - - Core_Target\ColorMap - - - Refactored\HW - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Gamma - - - Refactored\Interfaces - - - Refactored\Interfaces - - - Refactored\stats_manager - - - Interface implementations\RenderFactory - - - Interface implementations\RenderFactory - - - Interface implementations\LensFlare - - - Interface implementations\LensFlare - - - Interface implementations\FactoryPtr - - - Interface implementations\RainRender - - - Interface implementations\RainRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\FontRender - - - Interface implementations\FontRender - - - Interface implementations\WallMarkArray - - - Interface implementations\WallMarkArray - - - Interface implementations\StatGraphRender - - - Interface implementations\StatGraphRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\Debug - - - Interface implementations\Debug\DebugRender - - - Interface implementations\Debug\DebugRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UISequenceVideoItem - - - Interface implementations\UI\UISequenceVideoItem - - - Details - - - Lights - - - Core - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\HW - - - Kernel - - - Refactored\HW - - - Models\Visuals - - - Shading templates - - - Shading templates - - - Shading templates - - - Core - - - Core_Target - - - Lights - - - Core - - - Core - - - Debug - - - Core - - - Core - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Interface implementations\ImGuiRender - - - Interface implementations\ImGuiRender - - - Refactored\Execution & 3D\Shaders\Resources - - - Lights - - - - - Kernel - - - Kernel - - - Kernel - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Core - - - Details - - - Details - - - Details - - - Details - - - Details - - - Details - - - Stripifier - - - Stripifier - - - Stripifier - - - Stripifier - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Lights - - - Wallmarks - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates\R1 - - - Shading templates\R1 - - - Models - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Models\Visuals - - - Visibility\Sector/Portal - - - Visibility\Sector/Portal - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Visibility\HOM Occlusion - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target\ColorMap - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Backend - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\Execution & 3D\Shaders\Resources\dx9_R_shader - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\Shaders\Blender - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\DebugDraw - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Gamma - - - Refactored\stats_manager - - - Interface implementations\RenderFactory - - - Interface implementations\LensFlare - - - Interface implementations\RainRender - - - Interface implementations\ThunderboltRender - - - Interface implementations\EnvironmentRender - - - Interface implementations\ObjectSpaceRender - - - Interface implementations\FontRender - - - Interface implementations\WallMarkArray - - - Interface implementations\StatGraphRender - - - Interface implementations\ThunderboltDescRender - - - Interface implementations\Debug\DebugRender - - - Interface implementations\UI\UIRender - - - Interface implementations\UI\UIShader - - - Interface implementations\UI\UISequenceVideoItem - - - Core - - - Core - - - Refactored\HW - - - Refactored\HW - - - Refactored\Execution & 3D\Shaders\Resources - - - Refactored\HW - - - Refactored\Execution & 3D\Shaders\ShaderManager - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Shading templates - - - Core - - - Core - - - Core_Target - - - Core - - - Core_Target - - - Core - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Core - - - Core_Target - - - Core_Target - - - Core_Target - - - Core - - - Core_Target - - - Core - - - Core_Target - - - Core_Target - - - Core_Target - - - Core_Target - - - Visibility\Sector/Portal - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Refactored\Execution & 3D\Visuals\Skeleton - - - Interface implementations\ImGuiRender - - - Core - - - Core - - - Details - - - Core - - - Refactored\Execution & 3D\Shaders\Resources - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index d1433aecefc..1163872b819 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -76,7 +76,7 @@ static class cl_pos_decompress_params : public R_constant_setup { void setup(CBackend& cmd_list, R_constant* C) override { -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) const float VertTan = -1.0f * tanf(deg2rad(Device.fFOV / 2.0f)); const float HorzTan = -VertTan / Device.fASPECT; #elif defined(USE_OGL) @@ -228,9 +228,7 @@ void CRender::create() Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 0x12345678); m_skinning = -1; -#ifndef USE_DX9 m_MSAASample = -1; -#endif m_SMAPSize = ps_r2_smapsize; // hardware @@ -240,14 +238,8 @@ void CRender::create() o.mrtmixdepth = (HW.Caps.raster.b_MRT_mixdepth); // Check for NULL render target support -#ifdef USE_DX9 - D3DFORMAT nullrt = (D3DFORMAT)MAKEFOURCC('N', 'U', 'L', 'L'); - o.nullrt = HW.support(nullrt, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET); -#elif defined(USE_DX11) || defined(USE_OGL) o.nullrt = false; -#else -# error No graphics API selected or enabled! -#endif + /* if (o.nullrt) { Msg ("* NULLRT supported and used"); @@ -312,14 +304,9 @@ void CRender::create() // SMAP / DST o.HW_smap_FETCH4 = FALSE; -#ifdef USE_DX9 - o.HW_smap = HW.support(D3DFMT_D24X8, D3DRTYPE_TEXTURE, D3DUSAGE_DEPTHSTENCIL); -#elif defined(USE_DX11) || defined(USE_OGL) o.HW_smap = true; -#else -# error No graphics API selected or enabled! -#endif o.HW_smap_PCF = o.HW_smap; + if (o.HW_smap) { #if defined(USE_DX11) @@ -334,30 +321,8 @@ void CRender::create() Msg("* HWDST/PCF supported and used"); } -#ifdef USE_DX9 - // search for ATI formats - if (!o.HW_smap && (0 == strstr(Core.Params, "-nodf24"))) - { - o.HW_smap = HW.support((D3DFORMAT)(MAKEFOURCC('D', 'F', '2', '4')), D3DRTYPE_TEXTURE, D3DUSAGE_DEPTHSTENCIL); - if (o.HW_smap) - { - o.HW_smap_FORMAT = MAKEFOURCC('D', 'F', '2', '4'); - o.HW_smap_PCF = FALSE; - o.HW_smap_FETCH4 = TRUE; - } - Msg("* DF24/F4 supported and used [%X]", o.HW_smap_FORMAT); - } -#endif - -#ifdef USE_DX9 - o.fp16_filter = HW.support(D3DFMT_A16B16G16R16F, D3DRTYPE_TEXTURE, D3DUSAGE_QUERY_FILTER); - o.fp16_blend = HW.support(D3DFMT_A16B16G16R16F, D3DRTYPE_TEXTURE, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING); -#elif defined(USE_DX11) || defined(USE_OGL) o.fp16_filter = true; o.fp16_blend = true; -#else -# error No graphics API selected or enabled! -#endif // emulate ATI-R4xx series if (strstr(Core.Params, "-r4xx")) @@ -382,27 +347,12 @@ void CRender::create() // if hardware support early stencil (>= GF 8xxx) stencil reset trick only // slows down. o.nvstencil = FALSE; -#ifdef USE_DX9 - if ((HW.Caps.id_vendor == 0x10DE) && (HW.Caps.id_device >= 0x40)) - { - // o.nvstencil = HW.support ((D3DFORMAT)MAKEFOURCC('R','A','W','Z'), D3DRTYPE_SURFACE, 0); - // o.nvstencil = TRUE; - o.nvstencil = (S_OK == - HW.pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, - (D3DFORMAT MAKEFOURCC('R', 'A', 'W', 'Z')))); - } -#endif if (strstr(Core.Params, "-nonvs")) o.nvstencil = FALSE; // nv-dbt -#ifdef USE_DX9 - o.nvdbt = HW.support((D3DFORMAT)MAKEFOURCC('N', 'V', 'D', 'B'), D3DRTYPE_SURFACE, 0); -#elif defined(USE_DX11) || defined(USE_OGL) o.nvdbt = false; -#else -# error No graphics API selected or enabled! -#endif + if (o.nvdbt) Msg("* NV-DBT supported and used"); @@ -460,13 +410,9 @@ void CRender::create() o.ssao_blur_on = ps_r2_ls_flags_ext.test(R2FLAGEXT_SSAO_BLUR) && (ps_r_ssao != 0); o.ssao_opt_data = ps_r2_ls_flags_ext.test(R2FLAGEXT_SSAO_OPT_DATA) && (ps_r_ssao != 0); o.ssao_half_data = ps_r2_ls_flags_ext.test(R2FLAGEXT_SSAO_HALF_DATA) && o.ssao_opt_data && (ps_r_ssao != 0); -#if defined(USE_DX9) || defined(USE_DX11) -# if defined(USE_DX9) - o.ssao_hdao = false; -# elif defined(USE_DX11) +#if defined(USE_DX11) o.ssao_hdao = ps_r2_ls_flags_ext.test(R2FLAGEXT_SSAO_HDAO) && (ps_r_ssao != 0); o.ssao_ultra = HW.ComputeShadersSupported && ssao_hdao_cs_shaders_exist(); -# endif o.ssao_hbao = !o.ssao_hdao && ps_r2_ls_flags_ext.test(R2FLAGEXT_SSAO_HBAO) && (ps_r_ssao != 0); #elif defined(USE_OGL) // TODO: OGL: temporary disabled HBAO/HDAO, need to fix it @@ -476,13 +422,7 @@ void CRender::create() # error No graphics API selected or enabled! #endif -#ifdef USE_DX9 - if ((HW.Caps.id_vendor == 0x1002) && (HW.Caps.id_device <= 0x72FF)) - { - o.ssao_opt_data = false; - o.ssao_hbao = false; - } -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) || defined(USE_OGL) // TODO: fix hbao shader to allow to perform per-subsample effect! o.hbao_vectorized = false; if (o.ssao_hdao) @@ -493,7 +433,7 @@ void CRender::create() o.hbao_vectorized = true; o.ssao_opt_data = true; } -#endif // USE_DX9 +#endif // defined(USE_DX11) || defined(USE_OGL) #if defined(USE_DX11) || defined(USE_OGL) # if defined(USE_DX11) diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index 52c4a6be11d..2d3f2ee680a 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -404,11 +404,7 @@ class CRender final : public D3DXRenderBase GenerationLevel GetGeneration() const override { return IRender::GENERATION_R2; } bool is_sun_static() override { return o.sunstatic; } -#if defined(USE_DX9) - BackendAPI GetBackendAPI() const override { return IRender::BackendAPI::D3D9; } - u32 get_dx_level() override { return 0x00090000; } - pcstr getShaderPath() override { return "r2\\"; } -#elif defined(USE_DX11) +#if defined(USE_DX11) BackendAPI GetBackendAPI() const override { return IRender::BackendAPI::D3D11; } u32 get_dx_level() override { return HW.FeatureLevel >= D3D_FEATURE_LEVEL_10_1 ? 0x000A0001 : 0x000A0000; } pcstr getShaderPath() override @@ -433,7 +429,7 @@ class CRender final : public D3DXRenderBase void level_Load(IReader*) override; void level_Unload() override; -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) ID3DBaseTexture* texture_load(pcstr fname, u32& msize); #elif defined(USE_OGL) GLuint texture_load(pcstr fname, u32& msize, GLenum& ret_desc); @@ -521,25 +517,18 @@ class CRender final : public D3DXRenderBase CRender(); ~CRender() override; -#if defined(USE_DX9) - // nothing -#elif defined(USE_DX11) void addShaderOption(pcstr name, pcstr value); void clearAllShaderOptions() { m_ShaderOptions.clear(); } private: +#if defined(USE_DX11) xr_vector m_ShaderOptions; #elif defined(USE_OGL) - void addShaderOption(pcstr name, pcstr value); - void clearAllShaderOptions() { m_ShaderOptions.clear(); } - -private: xr_string m_ShaderOptions; #else # error No graphics API selected or enabled! #endif -private: IRender_Sector::sector_id_t largest_sector_id{ IRender_Sector::INVALID_SECTOR_ID }; }; diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index df78c903e70..c4489a284df 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -44,7 +44,7 @@ void CRender::RenderMenu() p1.set((_w + .5f) / _w, (_h + .5f) / _h); FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, Target->g_menu->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); pv++; pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); @@ -316,7 +316,6 @@ void CRender::Render() Lights_LastFrame.clear(); } -#if defined(USE_DX11) || defined(USE_OGL) // full screen pass to mark msaa-edge pixels in highest stencil bit if (o.msaa) { @@ -325,7 +324,6 @@ void CRender::Render() } r_rain.sync(); -#endif // !USE_DX9 // Directional light - fucking sun { @@ -345,10 +343,6 @@ void CRender::Render() dsgraph.cmd_list.set_xform_project(Device.mProject); dsgraph.cmd_list.set_xform_view(Device.mView); // Stencil - write 0x1 at pixel pos - -#if defined(USE_DX9) - RCache.set_Stencil(TRUE, D3DCMP_ALWAYS, 0x01, 0xff, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); -#elif defined(USE_DX11) || defined(USE_OGL) if (!o.msaa) { dsgraph.cmd_list.set_Stencil(TRUE, D3DCMP_ALWAYS, 0x01, 0xff, 0xff, @@ -359,7 +353,6 @@ void CRender::Render() dsgraph.cmd_list.set_Stencil(TRUE, D3DCMP_ALWAYS, 0x01, 0xff, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); } -#endif // USE_DX9 dsgraph.cmd_list.set_CullMode(CULL_CCW); dsgraph.cmd_list.set_ColorWriteEnable(); dsgraph.render_emissive(); diff --git a/src/Layers/xrRender_R2/r2_R_sun_support.h b/src/Layers/xrRender_R2/r2_R_sun_support.h index 4b9ab79a31d..7b710e4e1c0 100644 --- a/src/Layers/xrRender_R2/r2_R_sun_support.h +++ b/src/Layers/xrRender_R2/r2_R_sun_support.h @@ -390,9 +390,6 @@ class DumbConvexVolume Fvector3 t1, t2; t1.sub(points[P.points[0]], points[P.points[1]]); t2.sub(points[P.points[0]], points[P.points[2]]); -#ifdef USE_DX9 - P.planeN.crossproduct(t1, t2).normalize(); -#else P.planeN.crossproduct(t1, t2); float len = P.planeN.magnitude(); @@ -418,7 +415,6 @@ class DumbConvexVolume continue; } } -#endif P.planeD = -P.planeN.dotproduct(points[P.points[0]]); // verify diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index 7490a391dfa..7d23c6b3efc 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -11,10 +11,6 @@ #include "Layers/xrRender/blenders/blender_luminance.h" #include "Layers/xrRender/blenders/blender_ssao.h" -#if RENDER == R_R2 // XXX: merge old/new cascade blenders into one file -#include "Layers/xrRender/blenders/blender_light_direct_cascade.h" -#endif - #if defined(USE_DX11) || defined(USE_OGL) # include "Layers/xrRender/blenders/dx11MSAABlender.h" # include "Layers/xrRender/blenders/dx11RainBlender.h" @@ -33,38 +29,19 @@ #include "Layers/xrRender/blenders/blender_gasmask_drops.h" #include "Layers/xrRender/blenders/blender_gasmask_dudv.h" #endif -#if defined(USE_DX9) -void CRenderTarget::u_stencil_optimize(CBackend& cmd_list, BOOL common_stencil) -#elif defined(USE_DX11) || defined(USE_OGL) + void CRenderTarget::u_stencil_optimize(CBackend& cmd_list, eStencilOptimizeMode eSOM) -#else -# error No graphics API selected or enabled! -#endif { PIX_EVENT(stencil_optimize); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) // TODO: DX11: remove half pixel offset? VERIFY(RImplementation.o.nvstencil); -# ifdef USE_DX9 - cmd_list.set_ColorWriteEnable(false); -# endif u32 Offset; float _w = float(Device.dwWidth); float _h = float(Device.dwHeight); u32 C = color_rgba(255, 255, 255, 255); FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); -# ifdef USE_DX9 - float eps = EPS_S; - pv->set(eps, float(_h + eps), eps, 1.f, C, 0, 0); - pv++; - pv->set(eps, eps, eps, 1.f, C, 0, 0); - pv++; - pv->set(float(_w + eps), float(_h + eps), eps, 1.f, C, 0, 0); - pv++; - pv->set(float(_w + eps), eps, eps, 1.f, C, 0, 0); - pv++; -# elif defined(USE_DX11) float eps = 0; float _dw = 0.5f; float _dh = 0.5f; @@ -76,23 +53,16 @@ void CRenderTarget::u_stencil_optimize(CBackend& cmd_list, eStencilOptimizeMode pv++; pv->set(_w - _dw, -_dh, eps, 1.f, C, 0, 0); pv++; -# endif RImplementation.Vertex.Unlock(4, g_combine->vb_stride); -# ifdef USE_DX9 - cmd_list.set_CullMode(CULL_NONE); - if (common_stencil) - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); // keep/keep/keep -# endif + cmd_list.set_Element(s_occq->E[1]); -# if defined(USE_DX11) switch (eSOM) { case SO_Light: cmd_list.StateManager.SetStencilRef(dwLightMarkerID); break; case SO_Combine: cmd_list.StateManager.SetStencilRef(0x01); break; default: VERIFY(!"CRenderTarget::u_stencil_optimize. switch no default!"); } -# endif cmd_list.set_Geometry(g_combine); cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); @@ -103,25 +73,13 @@ void CRenderTarget::u_stencil_optimize(CBackend& cmd_list, eStencilOptimizeMode UNUSED(eSOM); #else # error No graphics API selected or enabled! -#endif // USE_DX9 || USE_DX11 +#endif // USE_DX11 } // 2D texgen (texture adjustment matrix) void CRenderTarget::u_compute_texgen_screen(CBackend& cmd_list, Fmatrix& m_Texgen) { -#if defined(USE_DX9) - float _w = float(Device.dwWidth); - float _h = float(Device.dwHeight); - float o_w = (.5f / _w); - float o_h = (.5f / _h); - Fmatrix m_TexelAdjust = - { - 0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f + o_w, 0.5f + o_h, 0.0f, 1.0f - }; -#elif defined(USE_DX11) +#if defined(USE_DX11) Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, @@ -151,7 +109,7 @@ void CRenderTarget::u_compute_texgen_jitter(CBackend& cmd_list, Fmatrix& m_Texge Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) 0.0f, -0.5f, 0.0f, 0.0f, #elif defined(USE_OGL) 0.0f, 0.5f, 0.0f, 0.0f, @@ -167,10 +125,6 @@ void CRenderTarget::u_compute_texgen_jitter(CBackend& cmd_list, Fmatrix& m_Texge float scale_X = float(Device.dwWidth) / float(TEX_jitter); float scale_Y = float(Device.dwHeight) / float(TEX_jitter); m_TexelAdjust.scale(scale_X, scale_Y, 1.f); -#ifdef USE_DX9 - float offset = (.5f / float(TEX_jitter)); - m_TexelAdjust.translate_over(offset, offset, 0); -#endif m_Texgen_J.mulA_44(m_TexelAdjust); } @@ -360,9 +314,8 @@ CRenderTarget::CRenderTarget() // generic(LDR) RTs rt_Generic_0.create(r2_RT_generic0, w, h, D3DFMT_A8R8G8B8, 1); rt_Generic_1.create(r2_RT_generic1, w, h, D3DFMT_A8R8G8B8, 1); -#if defined(USE_DX11) || defined(USE_OGL) rt_Generic.create(r2_RT_generic, w, h, D3DFMT_A8R8G8B8, 1); -#endif + if (!options.msaa) { rt_Generic_0_r = rt_Generic_0; @@ -447,7 +400,7 @@ CRenderTarget::CRenderTarget() // We only need to create rt_smap_surf on DX9, on DX10+ it's always a NULL render target // TODO: OGL: Don't create a color buffer for the shadow map. -#if defined(USE_DX9) || defined(USE_OGL) +#if defined(USE_OGL) rt_smap_surf.create(r2_RT_smap_surf, smapsize, smapsize, surf_format); #endif @@ -507,16 +460,7 @@ CRenderTarget::CRenderTarget() // Accum volumetric if (options.advancedpp) { -#ifdef USE_DX9 - if (options.oldshadowcascades) - s_accum_direct_volumetric.create("accum_volumetric_sun"); - else - s_accum_direct_volumetric.create("accum_volumetric_sun_cascade"); -#elif defined(USE_DX11) || defined(USE_OGL) s_accum_direct_volumetric.create("accum_volumetric_sun_nomsaa"); -#else -# error No graphics API selected or enabled! -#endif manually_assign_texture(s_accum_direct_volumetric, "s_smap", smapTarget); #if defined(USE_DX11) || defined(USE_OGL) @@ -651,14 +595,8 @@ CRenderTarget::CRenderTarget() s_bloom_msaa = s_bloom; else { -#ifdef USE_DX9 - NODEFAULT; -#elif defined(USE_DX11) || defined(USE_OGL) CBlender_bloom_build_msaa b_bloom_msaa; s_bloom_msaa.create(&b_bloom_msaa, "r2" DELIMITER "bloom"); -#else -# error No graphics API selected or enabled! -#endif } f_bloom_factor = 0.5f; } @@ -694,13 +632,8 @@ CRenderTarget::CRenderTarget() // HDAO/SSAO const bool ssao_blur_on = options.ssao_blur_on; -#ifdef USE_DX9 - constexpr bool ssao_hdao_ultra = false; -#elif defined(USE_DX11) || defined(USE_OGL) const bool ssao_hdao_ultra = options.ssao_hdao && options.ssao_ultra && ps_r_ssao > 3; -#else -# error No graphics API selected or enabled! -#endif + if (ssao_blur_on || ssao_hdao_ultra) { const u32 w = Device.dwWidth, h = Device.dwHeight; @@ -757,9 +690,6 @@ CRenderTarget::CRenderTarget() string256 name; xr_sprintf(name, "%s_%d", r2_RT_luminance_pool, it); rt_LUM_pool[it].create(name, 1, 1, D3DFMT_R32F); -#ifdef USE_DX9 - u_setrt(RCache, rt_LUM_pool[it], 0, 0, 0); -#endif RCache.ClearRT(rt_LUM_pool[it], 0x7f7f7f7f); } u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, get_base_zb()); @@ -767,23 +697,12 @@ CRenderTarget::CRenderTarget() // COMBINE { -#ifdef USE_DX9 - static D3DVERTEXELEMENT9 dwDecl[] = - { - { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos+uv - { 0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - D3DDECL_END() - }; -#elif defined(USE_DX11) || defined(USE_OGL) static D3DVERTEXELEMENT9 dwDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos+uv D3DDECL_END() }; -#else -# error No graphics API selected or enabled! -#endif + CBlender_combine b_combine; s_combine.create(&b_combine, "r2" DELIMITER "combine"); s_combine_volumetric.create("combine_volumetric"); @@ -793,13 +712,8 @@ CRenderTarget::CRenderTarget() g_combine_VP.create(dwDecl, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); g_combine.create(FVF::F_TL, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); g_combine_2UV.create(FVF::F_TL2uv, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); -#ifdef USE_DX9 - g_combine_cuboid.create(FVF::F_L, RImplementation.Vertex.Buffer(), RImplementation.Index.Buffer()); -#elif defined(USE_DX11) || defined(USE_OGL) g_combine_cuboid.create(dwDecl, RImplementation.Vertex.Buffer(), RImplementation.Index.Buffer()); -#else -# error No graphics API selected or enabled! -#endif + constexpr u32 fvf_aa_blur = D3DFVF_XYZRHW | D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(3); g_aa_blur.create(fvf_aa_blur, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); @@ -821,14 +735,8 @@ CRenderTarget::CRenderTarget() s_postprocess_msaa = s_postprocess; else { -#ifdef USE_DX9 - NODEFAULT; -#elif defined(USE_DX11) || defined(USE_OGL) CBlender_postprocess_msaa b_postprocess_msaa; s_postprocess_msaa.create(&b_postprocess_msaa, "r2" DELIMITER "post"); -#else -# error No graphics API selected or enabled! -#endif } // Menu @@ -850,10 +758,8 @@ CRenderTarget::CRenderTarget() CRenderTarget::~CRenderTarget() { -#if defined(USE_DX9) || defined(USE_DX11) -# if defined(USE_DX11) +#if defined(USE_DX11) _RELEASE(t_ss_async); -# endif #elif defined(USE_OGL) glDeleteTextures(1, &t_ss_async); @@ -906,31 +812,10 @@ void CRenderTarget::reset_light_marker(CBackend& cmd_list, bool bResetStencil) dwLightMarkerID = 5; if (bResetStencil) { -#ifdef USE_DX9 - cmd_list.set_ColorWriteEnable(FALSE); -#endif u32 Offset; float _w = float(Device.dwWidth); float _h = float(Device.dwHeight); u32 C = color_rgba(255, 255, 255, 255); -#ifdef USE_DX9 - float eps = EPS_S; - FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); - pv->set(eps, float(_h + eps), eps, 1.f, C, 0, 0); - pv++; - pv->set(eps, eps, eps, 1.f, C, 0, 0); - pv++; - pv->set(float(_w + eps), float(_h + eps), eps, 1.f, C, 0, 0); - pv++; - pv->set(float(_w + eps), eps, eps, 1.f, C, 0, 0); - pv++; - RImplementation.Vertex.Unlock(4, g_combine->vb_stride); - cmd_list.set_CullMode(CULL_NONE); - // Clear everything except last bit - cmd_list.set_Stencil(TRUE, D3DCMP_ALWAYS, dwLightMarkerID, 0x00, 0xFE, - D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO); - cmd_list.set_Element(s_occq->E[1]); -#elif defined(USE_DX11) || defined(USE_OGL) float eps = 0; float _dw = 0.5f; float _dh = 0.5f; @@ -945,9 +830,6 @@ void CRenderTarget::reset_light_marker(CBackend& cmd_list, bool bResetStencil) pv++; RImplementation.Vertex.Unlock(4, g_combine->vb_stride); cmd_list.set_Element(s_occq->E[2]); -#else -# error No graphics API selected or enabled! -#endif cmd_list.set_Geometry(g_combine); cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } diff --git a/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp b/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp index fd26587ae05..997724b63a1 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp @@ -31,7 +31,7 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) float _h = float(Device.dwHeight); float o_w = (.5f / _w); float o_h = (.5f / _h); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, @@ -72,10 +72,6 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) cmd_list.set_c("direction", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("m_texgen", m_Texgen); -#ifdef USE_DX9 - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); - draw_volume(cmd_list, L); -#elif defined(USE_DX11) || defined(USE_OGL) if (!RImplementation.o.msaa) { cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); @@ -118,7 +114,6 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) # endif // USE_DX11 } } -#endif // USE_DX9 } // blend-copy @@ -127,9 +122,6 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); cmd_list.set_c("m_texgen", m_Texgen); -#ifdef USE_DX9 - draw_volume(cmd_list, L); -#elif defined(USE_DX11) || defined(USE_OGL) if (!RImplementation.o.msaa) { // per pixel @@ -163,11 +155,10 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) VERIFY(!"Only optimized MSAA is supported in OpenGL"); # endif // USE_DX11 } -# if defined(USE_DX9) || defined(USE_DX11) // XXX: not sure why this is needed. Just preserving original behaviour +# if defined(USE_DX11) // XXX: not sure why this is needed. Just preserving original behaviour cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); # endif // !USE_OGL } -#endif // USE_DX9 } // diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp index b4b9046af02..bf81ba551bc 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp @@ -5,10 +5,10 @@ void CRenderTarget::u_calc_tc_noise(Fvector2& p0, Fvector2& p1) R_constant* C = RCache.get_c(c_snoise)._get(); // get texture VERIFY2(C, "s_noise texture in noise shader should be set"); VERIFY(RC_dest_sampler == C->destination); -#if defined(USE_DX9) || defined(USE_OGL) - VERIFY(RC_sampler == C->type); -#elif defined(USE_DX11) +#if defined(USE_DX11) VERIFY(RC_dx11texture == C->type); +#elif defined(USE_OGL) + VERIFY(RC_sampler == C->type); #else # error Select correct check for your graphics API #endif @@ -157,7 +157,7 @@ void CRenderTarget::phase_pp() // Fill vertex buffer float du = ps_r1_pps_u, dv = ps_r1_pps_v; TL_2c3uv* pv = (TL_2c3uv*)RImplementation.Vertex.Lock(4, g_postprocess.stride(), Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->set(du + 0, dv + float(_h), p_color, p_gray, r0.x, r1.y, l0.x, l1.y, n0.x, n1.y); pv++; pv->set(du + 0, dv + 0, p_color, p_gray, r0.x, r0.y, l0.x, l0.y, n0.x, n0.y); @@ -177,7 +177,7 @@ void CRenderTarget::phase_pp() pv++; #else # error No graphics API selected or enabled! -#endif // USE_DX9 || USE_DX11 +#endif RImplementation.Vertex.Unlock(4, g_postprocess.stride()); // Actual rendering diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp index 83493140ba7..0f6a93dad56 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp @@ -110,7 +110,7 @@ void CRenderTarget::phase_bloom() // Fill vertex buffer v_build* pv = (v_build*)RImplementation.Vertex.Lock(4, g_bloom_build->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->p.set(EPS, float(th + EPS), EPS, 1.f); pv->uv0.set(a_0.x, b_0.y); pv->uv1.set(a_1.x, b_1.y); @@ -162,7 +162,7 @@ void CRenderTarget::phase_bloom() pv++; #else # error No graphics API selected or enabled! -#endif // USE_DX9/11 +#endif // USE_DX11 RImplementation.Vertex.Unlock(4, g_bloom_build->vb_stride); // Perform combine (all scalers must account for 4 samples + final diffuse multiply); @@ -190,7 +190,7 @@ void CRenderTarget::phase_bloom() p1.set((_w + .5f) / _w, (_h + .5f) / _h); v_build* pv = (v_build*)RImplementation.Vertex.Lock(4, g_bloom_build->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->p.set(EPS, float(_h + EPS), EPS, 1.f); pv->uv0.set(p0.x - ddw, p1.y - ddh); pv->uv1.set(p0.x + ddw, p1.y + ddh); @@ -278,7 +278,7 @@ void CRenderTarget::phase_bloom() // Fill vertex buffer v_filter* pv = (v_filter*)RImplementation.Vertex.Lock(4, g_bloom_filter->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) // 0 - LB pv->p.set(EPS, float(_h + EPS), EPS, 1.f); pv->uv0.set(a_0.x, 1 + a_0.y, 0, 0); @@ -410,7 +410,7 @@ void CRenderTarget::phase_bloom() // Fill vertex buffer v_filter* pv = (v_filter*)RImplementation.Vertex.Lock(4, g_bloom_filter->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) // 0 - LB pv->p.set(EPS, float(_h + EPS), EPS, 1.f); pv->uv0.set(a_0.x, 1 + a_0.y, 0, 0); @@ -508,7 +508,7 @@ void CRenderTarget::phase_bloom() pv++; #else # error No graphics API selected or enabled! -#endif // !USE_OGL +#endif // USE_DX11 RImplementation.Vertex.Unlock(4, g_bloom_filter->vb_stride); // Perform filtering diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp index e1b3710fe0c..3bc9180468a 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp @@ -57,7 +57,7 @@ void CRenderTarget::phase_luminance() // Fill vertex buffer v_build* pv = (v_build*)RImplementation.Vertex.Lock(4, g_bloom_build->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->p.set(eps, float(ts + eps), eps, 1.f); pv->uv0.set(a_0.x, b_0.y); pv->uv1.set(a_1.x, b_1.y); @@ -109,7 +109,7 @@ void CRenderTarget::phase_luminance() pv++; #else # error No graphics API selected or enabled! -#endif // USE_OGL +#endif RImplementation.Vertex.Unlock(4, g_bloom_build->vb_stride); RCache.set_Element(s_luminance->E[0]); RCache.set_Geometry(g_bloom_build); @@ -133,7 +133,7 @@ void CRenderTarget::phase_luminance() // Fill vertex buffer v_filter* pv = (v_filter*)RImplementation.Vertex.Lock(4, g_bloom_filter->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->p.set(eps, float(_ts + eps), eps, 1.f); for (int t = 0; t < 8; t++) pv->uv[t].set(a[t].x, b[t].y, b[t + 8].y, a[t + 8].x); // xy/yx - left+down @@ -169,7 +169,7 @@ void CRenderTarget::phase_luminance() pv++; #else # error No graphics API selected or enabled! -#endif // !USE_OGL +#endif RImplementation.Vertex.Unlock(4, g_bloom_filter->vb_stride); RCache.set_Element(s_luminance->E[1]); RCache.set_Geometry(g_bloom_filter); @@ -194,7 +194,7 @@ void CRenderTarget::phase_luminance() // Fill vertex buffer v_filter* pv = (v_filter*)RImplementation.Vertex.Lock(4, g_bloom_filter->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->p.set(eps, float(_ts + eps), eps, 1.f); for (int t = 0; t < 8; t++) pv->uv[t].set(a[t].x, b[t].y, b[t + 8].y, a[t + 8].x); // xy/yx - left+down @@ -230,7 +230,7 @@ void CRenderTarget::phase_luminance() pv++; #else # error No graphics API selected or enabled! -#endif // !USE_OGL +#endif RImplementation.Vertex.Unlock(4, g_bloom_filter->vb_stride); f_luminance_adapt = .9f * f_luminance_adapt + .1f * Device.fTimeDelta * ps_r2_tonemap_adaptation; diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_smap_S.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_smap_S.cpp index 6d003625d9e..3e93558f6f8 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_smap_S.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_smap_S.cpp @@ -36,11 +36,6 @@ void CRenderTarget::phase_smap_spot(CBackend& cmd_list, light* L) #pragma todo("can optimize for multi-lights covering more than say 50%...") if (RImplementation.o.HW_smap) cmd_list.set_ColorWriteEnable(FALSE); - - // For DX11 do it once per smap generation pass in phase_smap_spot_clear -#ifdef USE_DX9 - cmd_list.ClearZB(rt_smap_depth, 1.0f); -#endif } void CRenderTarget::phase_smap_spot_tsh(CBackend& cmd_list, light* L) @@ -74,7 +69,7 @@ void CRenderTarget::phase_smap_spot_tsh(CBackend& cmd_list, light* L) p1.set((_w + .5f) / _w, (_h + .5f) / _h); FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); -#if defined(USE_DX9) || defined(USE_DX11) +#if defined(USE_DX11) pv->set(EPS, float(_h + EPS), d_Z, d_W, C, p0.x, p1.y); pv++; pv->set(EPS, EPS, d_Z, d_W, C, p0.x, p0.y); @@ -94,7 +89,7 @@ void CRenderTarget::phase_smap_spot_tsh(CBackend& cmd_list, light* L) pv++; #else # error No graphics API selected or enabled! -#endif // USE_DX9 || USE_DX11 +#endif RImplementation.Vertex.Unlock(4, g_combine->vb_stride); cmd_list.set_Geometry(g_combine); diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index da491b07be1..93c1beaedbb 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -159,18 +159,11 @@ void render_sun::calculate() #if defined(USE_OGL) XRMatrixOrthoOffCenterLH(&mdir_Project, -map_size * 0.5f, map_size * 0.5f, -map_size * 0.5f, map_size * 0.5f, 0.1f, dist + /*sqrt(2)*/1.41421f * map_size); -#else -#ifdef USE_DX9 - XMStoreFloat4x4((XMFLOAT4X4*)&mdir_Project, XMMatrixOrthographicOffCenterLH( - -map_size * 0.5f, map_size * 0.5f, -map_size * 0.5f, - map_size * 0.5f, 0.1f, dist + map_size) - ); #else XMStoreFloat4x4((XMFLOAT4X4*)&mdir_Project, XMMatrixOrthographicOffCenterLH( -map_size * 0.5f, map_size * 0.5f, -map_size * 0.5f, map_size * 0.5f, 0.1f, dist + /*sqrt(2)*/ 1.41421f * map_size) ); -#endif #endif ////////////////////////////////////////////////////////////////////////// // snap view-position to pixel diff --git a/src/engine.sln b/src/engine.sln index 3ff913abb64..bdd2654fe27 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -6,8 +6,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XR_3DA", "xr_3da\xr_3da.vcx ProjectSection(ProjectDependencies) = postProject {200652A6-043E-4634-8837-87983B3BD5E0} = {200652A6-043E-4634-8837-87983B3BD5E0} {2C5AF8C8-96A6-45B2-860B-5E9C9911DDD6} = {2C5AF8C8-96A6-45B2-860B-5E9C9911DDD6} - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} = {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2} - {963BA4E5-499A-454D-B002-1D5ECE0527A6} = {963BA4E5-499A-454D-B002-1D5ECE0527A6} {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} = {AC9B12ED-A2D7-4337-A981-5BD8430E96D8} EndProjectSection EndProject @@ -37,13 +35,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrNetServer", "xrNetServer\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrParticles", "xrParticles\xrParticles.vcxproj", "{94A1C366-3D19-48E6-8170-4ADC2E70DF97}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrRender_R1", "Layers\xrRenderPC_R1\xrRender_R1.vcxproj", "{57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}" - ProjectSection(ProjectDependencies) = postProject - {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {0899B131-F1D4-4876-9BA1-67AC821DB9E1} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrRender_R2", "Layers\xrRenderPC_R2\xrRender_R2.vcxproj", "{963BA4E5-499A-454D-B002-1D5ECE0527A6}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrSound", "xrSound\xrSound.vcxproj", "{CCCA7859-EB86-493E-9B53-C4235F45B3C5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrAPI", "Layers\xrAPI\xrAPI.vcxproj", "{1DAEC516-E52C-4A3C-A4DA-AE3553E6E0F8}" @@ -495,70 +486,6 @@ Global {94A1C366-3D19-48E6-8170-4ADC2E70DF97}.Release|x64.Build.0 = Release|x64 {94A1C366-3D19-48E6-8170-4ADC2E70DF97}.Release|x86.ActiveCfg = Release|Win32 {94A1C366-3D19-48E6-8170-4ADC2E70DF97}.Release|x86.Build.0 = Release|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|ARM.ActiveCfg = Debug|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|ARM.Build.0 = Debug|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|ARM64.ActiveCfg = Debug|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|ARM64.Build.0 = Debug|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|x64.ActiveCfg = Debug|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|x64.Build.0 = Debug|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|x86.ActiveCfg = Debug|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Debug|x86.Build.0 = Debug|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|ARM.ActiveCfg = Mixed|ARM - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|ARM.Build.0 = Mixed|ARM - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|x64.ActiveCfg = Mixed|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|x64.Build.0 = Mixed|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|x86.ActiveCfg = Mixed|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Mixed|x86.Build.0 = Mixed|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|ARM.ActiveCfg = Release|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|ARM.Build.0 = Release|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|ARM64.ActiveCfg = Release|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|ARM64.Build.0 = Release|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|x64.ActiveCfg = Release|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|x64.Build.0 = Release|x64 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|x86.ActiveCfg = Release|Win32 - {57A498C9-A741-4DDF-8EFC-BFB9EB6B00E2}.Release|x86.Build.0 = Release|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|ARM.ActiveCfg = Debug|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|ARM.Build.0 = Debug|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|ARM64.ActiveCfg = Debug|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|ARM64.Build.0 = Debug|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|x64.ActiveCfg = Debug|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|x64.Build.0 = Debug|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|x86.ActiveCfg = Debug|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Debug|x86.Build.0 = Debug|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|ARM.ActiveCfg = Mixed|ARM - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|ARM.Build.0 = Mixed|ARM - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|x64.ActiveCfg = Mixed|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|x64.Build.0 = Mixed|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|x86.ActiveCfg = Mixed|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Mixed|x86.Build.0 = Mixed|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|ARM.ActiveCfg = Release|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|ARM.Build.0 = Release|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|ARM64.ActiveCfg = Release|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|ARM64.Build.0 = Release|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|x64.ActiveCfg = Release|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|x64.Build.0 = Release|x64 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|x86.ActiveCfg = Release|Win32 - {963BA4E5-499A-454D-B002-1D5ECE0527A6}.Release|x86.Build.0 = Release|Win32 {CCCA7859-EB86-493E-9B53-C4235F45B3C5}.Debug|ARM.ActiveCfg = Debug|Win32 {CCCA7859-EB86-493E-9B53-C4235F45B3C5}.Debug|ARM.Build.0 = Debug|Win32 {CCCA7859-EB86-493E-9B53-C4235F45B3C5}.Debug|ARM64.ActiveCfg = Debug|x64 diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 4fd06c75ace..53c2f4f3f3d 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -16,16 +16,12 @@ extern xr_vector VidQualityToken; constexpr pcstr GET_RENDERER_MODULE_FUNC = "GetRendererModule"; -constexpr pcstr r1_library = "xrRender_R1"; +constexpr pcstr r4_library = "xrRender_R4"; constexpr pcstr gl_library = "xrRender_GL"; constexpr pcstr RENDER_LIBRARIES[] = { -#if defined(XR_PLATFORM_WINDOWS) - r1_library, - "xrRender_R2", - "xrRender_R4", -#endif + r4_library, gl_library }; @@ -175,7 +171,7 @@ void CEngineAPI::CreateRendererList() if (GEnv.isDedicatedServer) { #if defined(XR_PLATFORM_WINDOWS) - R_ASSERT2(loadLibrary(r1_library), "Dedicated server needs xrRender_R1 to work"); + R_ASSERT2(loadLibrary(r4_library), "Dedicated server needs xrRender_R1 to work"); #else R_ASSERT2(loadLibrary(gl_library), "Dedicated server needs xrRender_GL to work"); #endif @@ -184,7 +180,7 @@ void CEngineAPI::CreateRendererList() { for (pcstr library : RENDER_LIBRARIES) { - if (loadLibrary(library) && library != r1_library) + if (loadLibrary(library) && library != r4_library) r2_available = true; } } From f26a5d32de485cd0d622e9e0fcef1ad9c929fabd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 30 Apr 2024 05:03:18 +0500 Subject: [PATCH 312/497] xrRender: removed #if defined(USE_DX11) || defined(USE_OGL) constructs Since we only have DX11 and OGL, these are always true and our code is much cleaner now. --- src/Layers/xrRender/Blender_Recorder.cpp | 9 ++-- src/Layers/xrRender/Blender_Recorder.h | 2 - src/Layers/xrRender/Blender_Recorder_R2.cpp | 6 +-- src/Layers/xrRender/R_Backend.h | 3 -- src/Layers/xrRender/R_Backend_DBG.cpp | 52 ------------------- src/Layers/xrRender/R_Backend_Runtime.cpp | 2 +- src/Layers/xrRender/R_Backend_Runtime.h | 14 ++--- src/Layers/xrRender/ResourceManager.cpp | 3 -- src/Layers/xrRender/ResourceManager.h | 17 ------ src/Layers/xrRender/ResourceManager_Reset.cpp | 4 +- src/Layers/xrRender/SH_Atomic.cpp | 8 ++- src/Layers/xrRender/SH_Atomic.h | 37 ++++++------- src/Layers/xrRender/SH_Texture.h | 12 ++--- src/Layers/xrRender/Shader.cpp | 7 +-- src/Layers/xrRender/ShaderResourceTraits.h | 4 -- src/Layers/xrRender/dxDebugRender.cpp | 4 -- src/Layers/xrRender/r_constants.h | 7 +-- src/Layers/xrRender/tss.h | 2 - src/Layers/xrRender/xrRender_console.cpp | 8 +-- src/Layers/xrRender_R2/r2.cpp | 39 ++++---------- src/Layers/xrRender_R2/r2_R_render.cpp | 4 -- src/Layers/xrRender_R2/r2_rendertarget.cpp | 34 +++--------- .../r2_rendertarget_phase_accumulator.cpp | 2 - 23 files changed, 57 insertions(+), 223 deletions(-) diff --git a/src/Layers/xrRender/Blender_Recorder.cpp b/src/Layers/xrRender/Blender_Recorder.cpp index 5216ea7b84e..c1421a60700 100644 --- a/src/Layers/xrRender/Blender_Recorder.cpp +++ b/src/Layers/xrRender/Blender_Recorder.cpp @@ -216,17 +216,15 @@ void CBlender_Compile::PassSET_Shaders(pcstr _vs, pcstr _ps, pcstr _gs /*= nullp #endif dest.vs = RImplementation.Resources->_CreateVS(_vs, flags); ctable.merge(&dest.vs->constants); -#if defined(USE_DX11) || defined(USE_OGL) dest.gs = RImplementation.Resources->_CreateGS(_gs); ctable.merge(&dest.gs->constants); -# ifdef USE_DX11 +#ifdef USE_DX11 dest.hs = RImplementation.Resources->_CreateHS(_hs); dest.ds = RImplementation.Resources->_CreateDS(_ds); ctable.merge(&dest.hs->constants); ctable.merge(&dest.ds->constants); dest.cs = RImplementation.Resources->_CreateCS("null"); -# endif -#endif // defined(USE_DX11) || defined(USE_OGL) +#endif } #if defined(USE_OGL) RImplementation.Resources->_LinkPP(dest); @@ -254,14 +252,13 @@ void CBlender_Compile::PassSET_ablend_mode(BOOL bABlend, u32 abSRC, u32 abDST) RS.SetRS(D3DRS_SRCBLEND, bABlend ? abSRC : D3DBLEND_ONE); RS.SetRS(D3DRS_DESTBLEND, bABlend ? abDST : D3DBLEND_ZERO); -#if defined(USE_DX11) || defined(USE_OGL) // Since in our engine D3DRS_SEPARATEALPHABLENDENABLE state is // always set to false and in DirectX 10 blend functions for // color and alpha are always independent, assign blend options for // alpha in DX11 identical to color. + // XXX: do we want to change this behaviour? RS.SetRS(D3DRS_SRCBLENDALPHA, bABlend ? abSRC : D3DBLEND_ONE); RS.SetRS(D3DRS_DESTBLENDALPHA, bABlend ? abDST : D3DBLEND_ZERO); -#endif } void CBlender_Compile::PassSET_ablend_aref(BOOL bATest, u32 aRef) { diff --git a/src/Layers/xrRender/Blender_Recorder.h b/src/Layers/xrRender/Blender_Recorder.h index a4ea7c79743..81e4c0782a6 100644 --- a/src/Layers/xrRender/Blender_Recorder.h +++ b/src/Layers/xrRender/Blender_Recorder.h @@ -131,7 +131,6 @@ class CBlender_Compile D3DBLEND abSRC = D3DBLEND_ONE, D3DBLEND abDST = D3DBLEND_ZERO, BOOL aTest = FALSE, u32 aRef = 0); void r_Constant(LPCSTR name, R_constant_setup* s); -#if defined(USE_DX11) || defined(USE_OGL) void r_Pass(LPCSTR vs, LPCSTR gs, LPCSTR ps, bool bFog, BOOL bZtest = TRUE, BOOL bZwrite = TRUE, BOOL bABlend = FALSE, D3DBLEND abSRC = D3DBLEND_ONE, D3DBLEND abDST = D3DBLEND_ZERO, BOOL aTest = FALSE, u32 aRef = 0); @@ -145,7 +144,6 @@ class CBlender_Compile u32 Fail = D3DSTENCILOP_KEEP, u32 Pass = D3DSTENCILOP_KEEP, u32 ZFail = D3DSTENCILOP_KEEP); void r_StencilRef(u32 Ref); void r_CullMode(D3DCULL Mode); -#endif // defined(USE_DX11) || defined(USE_OGL) #if defined(USE_DX11) void r_dx11Texture(LPCSTR ResourceName, LPCSTR texture, bool recursive = false); diff --git a/src/Layers/xrRender/Blender_Recorder_R2.cpp b/src/Layers/xrRender/Blender_Recorder_R2.cpp index 968ed3c7aac..ede1699f9df 100644 --- a/src/Layers/xrRender/Blender_Recorder_R2.cpp +++ b/src/Layers/xrRender/Blender_Recorder_R2.cpp @@ -37,14 +37,12 @@ void CBlender_Compile::r_Pass(LPCSTR _vs, LPCSTR _ps, bool bFog, BOOL bZtest, BO #endif dest.vs = RImplementation.Resources->_CreateVS(_vs, flags); ctable.merge(&dest.vs->constants); -#if defined(USE_DX11) || defined(USE_OGL) dest.gs = RImplementation.Resources->_CreateGS("null"); -# ifdef USE_DX11 +#ifdef USE_DX11 dest.hs = RImplementation.Resources->_CreateHS("null"); dest.ds = RImplementation.Resources->_CreateDS("null"); dest.cs = RImplementation.Resources->_CreateCS("null"); -# endif -#endif // defined(USE_DX11) || defined(USE_OGL) +#endif } #if defined(USE_OGL) RImplementation.Resources->_LinkPP(dest); diff --git a/src/Layers/xrRender/R_Backend.h b/src/Layers/xrRender/R_Backend.h index 7309c56a2d6..8ea0a9589b9 100644 --- a/src/Layers/xrRender/R_Backend.h +++ b/src/Layers/xrRender/R_Backend.h @@ -578,11 +578,8 @@ class ECORE_API CBackend void InitializeDebugDraw(); void DestroyDebugDraw(); - // DX9 doesn't need this -#ifndef USE_DX9 ref_geom vs_L; ref_geom vs_TL; -#endif #if defined(USE_DX11) private: diff --git a/src/Layers/xrRender/R_Backend_DBG.cpp b/src/Layers/xrRender/R_Backend_DBG.cpp index 4d117f569f0..c97d61c97df 100644 --- a/src/Layers/xrRender/R_Backend_DBG.cpp +++ b/src/Layers/xrRender/R_Backend_DBG.cpp @@ -1,24 +1,18 @@ #include "stdafx.h" #pragma hdrstop -#if defined(USE_DX11) || defined(USE_OGL) extern IC u32 GetIndexCount(D3DPRIMITIVETYPE T, u32 iPrimitiveCount); -#endif void CBackend::InitializeDebugDraw() { -#ifndef USE_DX9 vs_L.create(FVF::F_L, RImplementation.Vertex.Buffer(), RImplementation.Index.Buffer()); vs_TL.create(FVF::F_TL, RImplementation.Vertex.Buffer(), RImplementation.Index.Buffer()); -#endif } void CBackend::DestroyDebugDraw() { -#ifndef USE_DX9 vs_L.destroy(); vs_TL.destroy(); -#endif } void CBackend::dbg_DP(D3DPRIMITIVETYPE pt, ref_geom geom, u32 vBase, u32 pc) @@ -37,7 +31,6 @@ void CBackend::dbg_DIP(D3DPRIMITIVETYPE pt, ref_geom geom, u32 baseV, u32 startV void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, int vcnt, u16* pIdx, int pcnt) { -#ifndef USE_DX9 u32 vBase; { FVF::L* pv = (FVF::L*)RImplementation.Vertex.Lock(vcnt, vs_L->vb_stride, vBase); @@ -61,17 +54,9 @@ void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, int vcnt, u16* pIdx, RImplementation.rmNormal(RCache); set_Stencil(FALSE); Render(T, vBase, 0, vcnt, iBase, pcnt); -#elif defined(USE_DX9) - OnFrameEnd(); - CHK_DX(HW.pDevice->SetFVF(FVF::F_L)); - CHK_DX(HW.pDevice->DrawIndexedPrimitiveUP(T, 0, vcnt, pcnt, pIdx, D3DFMT_INDEX16, pVerts, sizeof(FVF::L))); -#else -# error No graphics API selected or enabled! -#endif } void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, int pcnt) { -#ifndef USE_DX9 u32 vBase; { const size_t count = GetIndexCount(T, pcnt); @@ -87,13 +72,6 @@ void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, int pcnt) RImplementation.rmFar(RCache); set_Stencil(FALSE); Render(T, vBase, pcnt); -#elif defined(USE_DX9) - OnFrameEnd(); - CHK_DX(HW.pDevice->SetFVF(FVF::F_L)); - CHK_DX(HW.pDevice->DrawPrimitiveUP(T, pcnt, pVerts, sizeof(FVF::L))); -#else -# error No graphics API selected or enabled! -#endif } #define RGBA_GETALPHA(rgb) ((rgb) >> 24) @@ -256,28 +234,13 @@ void CBackend::dbg_OverdrawEnd() OnFrameEnd(); // Draw a rectangle wherever the count equal I -#if defined(USE_DX9) - CHK_DX(HW.pDevice->SetFVF(FVF::F_TL)); -#elif defined(USE_DX11) || defined(USE_OGL) set_Geometry(vs_TL); -#else -# error No graphics API defined or enabled! -#endif // Render gradients for (int I = 0; I < 12; I++) { u32 _c = I * 256 / 13; u32 c = color_xrgb(_c, _c, _c); -#ifdef USE_DX9 - FVF::TL pv[4]; - pv[0].set(float(0), float(Device.dwHeight), c, 0, 0); - pv[1].set(float(0), float(0), c, 0, 0); - pv[2].set(float(Device.dwWidth), float(Device.dwHeight), c, 0, 0); - pv[3].set(float(Device.dwWidth), float(0), c, 0, 0); - CHK_DX(HW.pDevice->SetRenderState(D3DRS_STENCILREF, I)); - CHK_DX(HW.pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pv, sizeof(FVF::TL))); -#elif defined(USE_DX11) || defined(USE_OGL) u32 vBase; FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, vs_L->vb_stride, vBase); pv[0].set(float(0), float(Device.dwHeight), c, 0, 0); @@ -289,31 +252,16 @@ void CBackend::dbg_OverdrawEnd() set_Stencil(TRUE, D3DCMP_EQUAL, I, 0xff, 0xffffffff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP); Render(D3DPT_TRIANGLESTRIP, vBase, 4); -#else -# error No graphics API defined or enabled! -#endif } set_Stencil(FALSE); } void CBackend::dbg_SetRS(D3DRENDERSTATETYPE p1, u32 p2) { -#ifdef USE_DX9 - CHK_DX(HW.pDevice->SetRenderState(p1, p2)); -#elif defined(USE_DX11) || defined(USE_OGL) VERIFY(!"Not implemented"); -#else -# error No graphics API defined or enabled! -#endif } void CBackend::dbg_SetSS(u32 sampler, D3DSAMPLERSTATETYPE type, u32 value) { -#ifdef USE_DX9 - CHK_DX(HW.pDevice->SetSamplerState(sampler, type, value)); -#elif defined(USE_DX11) || defined(USE_OGL) VERIFY(!"Not implemented"); -#else -# error No graphics API defined or enabled! -#endif } diff --git a/src/Layers/xrRender/R_Backend_Runtime.cpp b/src/Layers/xrRender/R_Backend_Runtime.cpp index 94e738714ec..e1a66552195 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.cpp +++ b/src/Layers/xrRender/R_Backend_Runtime.cpp @@ -143,7 +143,7 @@ void CBackend::set_ClipPlanes(u32 _enable, Fplane* _planes /*=NULL */, u32 count return; #else # error No graphics API selected or enabled! -#endif // defined(USE_DX11) || defined(USE_OGL) +#endif } #ifndef DEDICATED_SREVER diff --git a/src/Layers/xrRender/R_Backend_Runtime.h b/src/Layers/xrRender/R_Backend_Runtime.h index 6240a8803a6..ef236b1981f 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.h +++ b/src/Layers/xrRender/R_Backend_Runtime.h @@ -83,20 +83,14 @@ IC GLuint CBackend::get_ZB() } ICF void CBackend::set_States(SState* _state) { -// DX11 Manages states using it's own algorithm. Don't mess with it. -#ifdef USE_DX9 - if (state != _state->state) -#endif - { - PGO(Msg("PGO:state_block")); - stat.states++; - state = _state->state; + PGO(Msg("PGO:state_block")); + stat.states++; + state = _state->state; #if defined(USE_DX11) - state->Apply(*this); + state->Apply(*this); #else state->Apply(); #endif - } } IC void CBackend::set_Matrices(SMatrixList* matrix_list) diff --git a/src/Layers/xrRender/ResourceManager.cpp b/src/Layers/xrRender/ResourceManager.cpp index 5138e3d184a..b03cc4939f3 100644 --- a/src/Layers/xrRender/ResourceManager.cpp +++ b/src/Layers/xrRender/ResourceManager.cpp @@ -462,9 +462,6 @@ void CResourceManager::_DumpMemoryUsage() void CResourceManager::Evict() { // TODO: DX11: check if we really need this method -#ifdef USE_DX9 - CHK_DX(HW.pDevice->EvictManagedResources()); -#endif } /* BOOL CResourceManager::_GetDetailTexture(LPCSTR Name,LPCSTR& T, R_constant_setup* &CS) diff --git a/src/Layers/xrRender/ResourceManager.h b/src/Layers/xrRender/ResourceManager.h index ef5dd5c336b..61f2f30202d 100644 --- a/src/Layers/xrRender/ResourceManager.h +++ b/src/Layers/xrRender/ResourceManager.h @@ -37,20 +37,13 @@ class ECORE_API CResourceManager using map_RT = xr_map; // DX10 cut DEFINE_MAP_PRED(const char*,CRTC*, map_RTC, map_RTCIt, str_pred); using map_VS = xr_map; - -#if defined(USE_DX11) || defined(USE_OGL) using map_GS = xr_map; -#endif - -#if defined(USE_DX11) || defined(USE_OGL) using map_HS = xr_map; using map_DS = xr_map; using map_CS = xr_map; -#endif #if defined(USE_OGL) using map_PP = xr_map; #endif - using map_PS = xr_map; using map_TD = xr_map; @@ -64,16 +57,10 @@ class ECORE_API CResourceManager // DX10 cut map_RTC m_rtargets_c; map_VS m_vs; map_PS m_ps; - -#if defined(USE_DX11) || defined(USE_OGL) map_GS m_gs; -#endif - -#if defined(USE_DX11) || defined(USE_OGL) map_DS m_ds; map_HS m_hs; map_CS m_cs; -#endif #if defined(USE_OGL) map_PP m_pp; #endif @@ -171,12 +158,9 @@ class ECORE_API CResourceManager void _DeletePP(const SPP* p); #endif -#if defined(USE_DX11) || defined(USE_OGL) SGS* _CreateGS(LPCSTR Name); void _DeleteGS(const SGS* GS); -#endif -#if defined(USE_DX11) || defined(USE_OGL) SHS* _CreateHS(LPCSTR Name); void _DeleteHS(const SHS* HS); @@ -185,7 +169,6 @@ class ECORE_API CResourceManager SCS* _CreateCS(LPCSTR Name); void _DeleteCS(const SCS* CS); -#endif SPS* _CreatePS(LPCSTR Name); void _DeletePS(const SPS* PS); diff --git a/src/Layers/xrRender/ResourceManager_Reset.cpp b/src/Layers/xrRender/ResourceManager_Reset.cpp index 34ed9fd3cb4..90eecce1257 100644 --- a/src/Layers/xrRender/ResourceManager_Reset.cpp +++ b/src/Layers/xrRender/ResourceManager_Reset.cpp @@ -122,11 +122,10 @@ void CResourceManager::Dump(bool bBrief) Msg("* RM_Dump: ps : %d", m_ps.size()); if (!bBrief) mdump(m_ps); -#if defined(USE_DX11) || defined(USE_OGL) Msg("* RM_Dump: gs : %d", m_gs.size()); if (!bBrief) mdump(m_gs); -# ifdef USE_DX11 +#ifdef USE_DX11 Msg("* RM_Dump: cs : %d", m_cs.size()); if (!bBrief) mdump(m_cs); @@ -136,7 +135,6 @@ void CResourceManager::Dump(bool bBrief) Msg("* RM_Dump: ds : %d", m_ds.size()); if (!bBrief) mdump(m_ds); -# endif #endif Msg("* RM_Dump: dcl : %d", v_declarations.size()); Msg("* RM_Dump: states : %d", v_states.size()); diff --git a/src/Layers/xrRender/SH_Atomic.cpp b/src/Layers/xrRender/SH_Atomic.cpp index 9d13b46ecd5..d70792211b1 100644 --- a/src/Layers/xrRender/SH_Atomic.cpp +++ b/src/Layers/xrRender/SH_Atomic.cpp @@ -74,7 +74,6 @@ SPS::~SPS() RImplementation.Resources->_DeletePS(this); } -#if defined(USE_DX11) || defined(USE_OGL) /////////////////////////////////////////////////////////////////////// // SGS SGS::~SGS() @@ -138,7 +137,6 @@ SCS::~SCS() RImplementation.Resources->_DeleteCS(this); } -#endif // USE_DX11 || USE_OGL #if defined(USE_OGL) SPP::~SPP() @@ -184,9 +182,7 @@ SDeclaration::~SDeclaration() { RImplementation.Resources->_DeleteDecl(this); // Release vertex layout -#ifdef USE_OGL - glDeleteVertexArrays(1, &dcl); -#elif defined(USE_DX11) || defined(USE_OGL) +#if defined(USE_DX11) xr_map::iterator iLayout; iLayout = vs_to_layout.begin(); for (; iLayout != vs_to_layout.end(); ++iLayout) @@ -194,6 +190,8 @@ SDeclaration::~SDeclaration() // Release vertex layout _RELEASE(iLayout->second); } +#elif defined(USE_OGL) + glDeleteVertexArrays(1, &dcl); #else # error No graphics API selected or enabled! #endif diff --git a/src/Layers/xrRender/SH_Atomic.h b/src/Layers/xrRender/SH_Atomic.h index 2bf0011b875..4ed26bd51a4 100644 --- a/src/Layers/xrRender/SH_Atomic.h +++ b/src/Layers/xrRender/SH_Atomic.h @@ -59,17 +59,16 @@ struct ECORE_API SPS : public xr_resource_named }; typedef resptr_core> ref_ps; -#if defined(USE_DX11) || defined(USE_OGL) ////////////////////////////////////////////////////////////////////////// struct ECORE_API SGS : public xr_resource_named { -# if defined(USE_DX11) +#if defined(USE_DX11) ID3DGeometryShader* sh; -# elif defined(USE_OGL) +#elif defined(USE_OGL) GLuint sh; -# else -# error No graphics API selected or enabled! -# endif +#else +# error No graphics API selected or enabled! +#endif R_constant_table constants; ~SGS(); }; @@ -77,12 +76,12 @@ typedef resptr_core> ref_gs; struct ECORE_API SHS : public xr_resource_named { -# if defined(USE_DX11) +#if defined(USE_DX11) ID3D11HullShader* sh; -# elif defined(USE_OGL) +#elif defined(USE_OGL) GLuint sh; -# else -# error No graphics API selected or enabled! +#else +# error No graphics API selected or enabled! #endif R_constant_table constants; ~SHS(); @@ -91,12 +90,12 @@ typedef resptr_core> ref_hs; struct ECORE_API SDS : public xr_resource_named { -# if defined(USE_DX11) +#if defined(USE_DX11) ID3D11DomainShader* sh; -# elif defined(USE_OGL) +#elif defined(USE_OGL) GLuint sh; -# else -# error No graphics API selected or enabled! +#else +# error No graphics API selected or enabled! #endif R_constant_table constants; ~SDS(); @@ -105,20 +104,18 @@ typedef resptr_core> ref_ds; struct ECORE_API SCS : public xr_resource_named { -# if defined(USE_DX11) +#if defined(USE_DX11) ID3D11ComputeShader* sh; -# elif defined(USE_OGL) +#elif defined(USE_OGL) GLuint sh; -# else -# error No graphics API selected or enabled! +#else +# error No graphics API selected or enabled! #endif R_constant_table constants; ~SCS(); }; typedef resptr_core> ref_cs; -#endif // USE_DX11 || USE_OGL - #if defined(USE_OGL) struct ECORE_API SPP : public xr_resource_named { diff --git a/src/Layers/xrRender/SH_Texture.h b/src/Layers/xrRender/SH_Texture.h index a248f1e81ed..63dbcc695b8 100644 --- a/src/Layers/xrRender/SH_Texture.h +++ b/src/Layers/xrRender/SH_Texture.h @@ -10,31 +10,27 @@ class ENGINE_API CTheoraSurface; class ECORE_API CTexture : public xr_resource_named { public: -#if defined(USE_DX11) || defined(USE_OGL) enum MaxTextures { // Actually these values are 128 mtMaxPixelShaderTextures = 16, mtMaxVertexShaderTextures = 4, mtMaxGeometryShaderTextures = 16, -# ifdef USE_DX11 +#ifdef USE_DX11 mtMaxHullShaderTextures = 16, mtMaxDomainShaderTextures = 16, mtMaxComputeShaderTextures = 16, -# endif +#endif mtMaxCombinedShaderTextures = mtMaxPixelShaderTextures + mtMaxVertexShaderTextures + mtMaxGeometryShaderTextures -# ifdef USE_DX11 +#ifdef USE_DX11 + mtMaxHullShaderTextures + mtMaxDomainShaderTextures + mtMaxComputeShaderTextures -# endif - }; -#else -# error No graphics API selected or enabled! #endif + }; #if defined(USE_DX11) // Since DX11 allows up to 128 unique textures, diff --git a/src/Layers/xrRender/Shader.cpp b/src/Layers/xrRender/Shader.cpp index 3a12aff9535..e36d92aeabb 100644 --- a/src/Layers/xrRender/Shader.cpp +++ b/src/Layers/xrRender/Shader.cpp @@ -48,19 +48,16 @@ bool SPass::equal(const SPass& other) const return false; if (vs != other.vs) return false; -#if defined(USE_DX11) || defined(USE_OGL) if (gs != other.gs) return false; -# ifdef USE_DX11 +#ifdef USE_DX11 if (hs != other.hs) return false; if (ds != other.ds) return false; if (cs != other.cs) return false; -# endif -#endif // USE_DX11 || USE_OGL -#ifdef USE_OGL +#elif defined(USE_OGL) if (pp != other.pp) return false; #endif diff --git a/src/Layers/xrRender/ShaderResourceTraits.h b/src/Layers/xrRender/ShaderResourceTraits.h index 9a8ca6ea214..c258a6bd67d 100644 --- a/src/Layers/xrRender/ShaderResourceTraits.h +++ b/src/Layers/xrRender/ShaderResourceTraits.h @@ -321,7 +321,6 @@ struct ShaderTypeTraits static inline u32 GetShaderDest() { return RC_dest_pixel; } }; -#if defined(USE_DX11) || defined(USE_OGL) template <> struct ShaderTypeTraits { @@ -575,7 +574,6 @@ struct ShaderTypeTraits static inline u32 GetShaderDest() { return RC_dest_compute; } }; -#endif template <> inline CResourceManager::map_PS& CResourceManager::GetShaderMap() @@ -589,7 +587,6 @@ inline CResourceManager::map_VS& CResourceManager::GetShaderMap() return m_vs; } -#if defined(USE_DX11) || defined(USE_OGL) template <> inline CResourceManager::map_GS& CResourceManager::GetShaderMap() { @@ -613,7 +610,6 @@ inline CResourceManager::map_CS& CResourceManager::GetShaderMap() { return m_cs; } -#endif // USE_DX11 || USE_OGL template T* CResourceManager::CreateShader(cpcstr name, pcstr filename /*= nullptr*/, u32 flags /*= 0*/) diff --git a/src/Layers/xrRender/dxDebugRender.cpp b/src/Layers/xrRender/dxDebugRender.cpp index 9f9a6c9ff7f..336c2f24564 100644 --- a/src/Layers/xrRender/dxDebugRender.cpp +++ b/src/Layers/xrRender/dxDebugRender.cpp @@ -98,13 +98,9 @@ void dxDebugRender::CacheSetXformWorld(const Fmatrix& M) { RCache.set_xform_worl void dxDebugRender::CacheSetCullMode(CullMode m) { RCache.set_CullMode(CULL_NONE + m); } void dxDebugRender::SetAmbient(u32 colour) { -#if defined(USE_DX11) || defined(USE_OGL) // TODO: DX11: Check if need this for DX11 VERIFY(!"Not implemented for DX11"); UNUSED(colour); -#else -# error No graphics API selected or enabled! -#endif } void dxDebugRender::SetDebugShader(dbgShaderHandle shdHandle) diff --git a/src/Layers/xrRender/r_constants.h b/src/Layers/xrRender/r_constants.h index d316457e7bf..ad275a515ca 100644 --- a/src/Layers/xrRender/r_constants.h +++ b/src/Layers/xrRender/r_constants.h @@ -149,16 +149,13 @@ struct ECORE_API R_constant : public xr_resource && destination == C.destination && ps.equal(C.ps) && vs.equal(C.vs) -#if defined(USE_DX11) || defined(USE_OGL) && gs.equal(C.gs) -# if defined(USE_DX11) +#if defined(USE_DX11) && hs.equal(C.hs) && ds.equal(C.ds) && cs.equal(C.cs) -# endif -# if defined(USE_OGL) +#elif defined(USE_OGL) && pp.equal(C.pp) -# endif #endif && samp.equal(C.samp) && handler == C.handler; diff --git a/src/Layers/xrRender/tss.h b/src/Layers/xrRender/tss.h index f7b1dceefe8..e49c7c834a5 100644 --- a/src/Layers/xrRender/tss.h +++ b/src/Layers/xrRender/tss.h @@ -4,7 +4,6 @@ #include "tss_def.h" -#if defined(USE_DX11) || defined(USE_OGL) enum XRDX11SAMPLERSTATETYPE { XRDX11SAMP_ANISOTROPICFILTER = 256, @@ -16,7 +15,6 @@ enum XRDX11RENDERSTATETYPE { XRDX11RS_ALPHATOCOVERAGE = 1024 }; -#endif // !USE_DX9 class CSimulatorTSS { diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index e7e182f67e3..3c3ede2b782 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -55,8 +55,7 @@ const xr_token qsmapsize_token[] = { "2560", 2560 }, { "3072", 3072 }, { "3584", 3584 }, - { "4096", 4096 }, -#if defined(USE_DX11) || defined(USE_OGL) // XXX: check if values more than 8192 are supported on OpenGL + { "4096", 4096 }, // XXX: runtime check for maximum smap-size on OpenGL { "5120", 5120 }, { "6144", 6144 }, { "7168", 7168 }, @@ -69,7 +68,6 @@ const xr_token qsmapsize_token[] = { "14336", 14336 }, { "15360", 15360 }, { "16384", 16384 }, -#endif // !USE_DX9 { nullptr, 0 } }; @@ -81,10 +79,8 @@ const xr_token qsun_shafts_token[] = {{"st_opt_off", 0}, {"st_opt_low", 1}, {"st u32 ps_r_ssao = 3; const xr_token qssao_token[] = {{"st_opt_off", 0}, {"st_opt_low", 1}, {"st_opt_medium", 2}, {"st_opt_high", 3}, -#if defined(USE_DX11) || defined(USE_OGL) {"st_opt_ultra", 4}, -#endif - {nullptr, 0}}; +{nullptr, 0}}; u32 ps_r_sun_quality = 1; // = 0; const xr_token qsun_quality_token[] = {{"st_opt_low", 0}, {"st_opt_medium", 1}, {"st_opt_high", 2}, diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 1163872b819..57b6e90b30f 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -130,7 +130,6 @@ static class cl_sun_shafts_intensity : public R_constant_setup } } binder_sun_shafts_intensity; -#if defined(USE_DX11) || defined(USE_OGL) static class cl_alpha_ref : public R_constant_setup { void setup(CBackend& cmd_list, R_constant* C) override @@ -141,7 +140,6 @@ static class cl_alpha_ref : public R_constant_setup # endif } } binder_alpha_ref; -#endif // Defined in ResourceManager.cpp IReader* open_shader(pcstr shader); @@ -150,14 +148,7 @@ IReader* open_shader(pcstr shader); static bool must_enable_old_cascades() { bool oldCascades = false; -#if RENDER == R_R2 - { - // Check for new cascades support on R2 - IReader* accumSunNearCascade = open_shader("accum_sun_cascade.ps"); - oldCascades = !accumSunNearCascade; - FS.r_close(accumSunNearCascade); - } -#elif RENDER != R_R1 +#if RENDER != R_R1 { IReader* accumSunNear = open_shader("accum_sun_near.ps"); R_ASSERT3(accumSunNear, "Can't open shader", "accum_sun_near.ps"); @@ -388,13 +379,11 @@ void CRender::create() //. o.sunstatic = (strstr(Core.Params,"-sunstatic"))? TRUE :FALSE ; o.sunstatic = ps_r2_sun_static; o.advancedpp = ps_r2_advanced_pp; -#if defined(USE_DX11) || defined(USE_OGL) -# if defined(USE_DX11) +#if defined(USE_DX11) o.volumetricfog = ps_r2_ls_flags.test(R3FLAG_VOLUMETRIC_SMOKE); -# elif defined(USE_OGL) +#elif defined(USE_OGL) // TODO: OGL: temporary disabled, need to fix it o.volumetricfog = false; -# endif #endif o.sjitter = (strstr(Core.Params, "-sjitter")) ? TRUE : FALSE; o.depth16 = (strstr(Core.Params, "-depth16")) ? TRUE : FALSE; @@ -422,7 +411,6 @@ void CRender::create() # error No graphics API selected or enabled! #endif -#if defined(USE_DX11) || defined(USE_OGL) // TODO: fix hbao shader to allow to perform per-subsample effect! o.hbao_vectorized = false; if (o.ssao_hdao) @@ -433,20 +421,18 @@ void CRender::create() o.hbao_vectorized = true; o.ssao_opt_data = true; } -#endif // defined(USE_DX11) || defined(USE_OGL) -#if defined(USE_DX11) || defined(USE_OGL) -# if defined(USE_DX11) +#if defined(USE_DX11) o.dx11_sm4_1 = ps_r2_ls_flags.test((u32)R3FLAG_USE_DX10_1); o.dx11_sm4_1 = o.dx11_sm4_1 && (HW.FeatureLevel >= D3D_FEATURE_LEVEL_10_1); -# elif defined(USE_OGL) +#elif defined(USE_OGL) o.dx11_sm4_1 = true; #else # error No graphics API selected or enabled! -# endif +#endif // MSAA option dependencies -# if defined(USE_DX11) +#if defined(USE_DX11) o.msaa = !!ps_r3_msaa; o.msaa_samples = (1 << ps_r3_msaa); @@ -457,7 +443,7 @@ void CRender::create() // o.msaa_hybrid = ps_r2_ls_flags.test(R3FLAG_MSAA_HYBRID); o.msaa_hybrid = ps_r2_ls_flags.test((u32)R3FLAG_USE_DX10_1); o.msaa_hybrid &= !o.msaa_opt && o.msaa && (HW.FeatureLevel >= D3D_FEATURE_LEVEL_10_1); -# elif defined(USE_OGL) +#elif defined(USE_OGL) // TODO: OGL: temporary disabled, need to fix it o.msaa = false; o.msaa_samples = 0; @@ -465,7 +451,7 @@ void CRender::create() o.msaa_hybrid = false; #else # error No graphics API selected or enabled! -# endif +#endif // Allow alpha test MSAA for DX10.0 // o.msaa_alphatest= ps_r2_ls_flags.test((u32)R3FLAG_MSAA_ALPHATEST); @@ -531,7 +517,6 @@ void CRender::create() } } } -#endif // constants Resources->RegisterConstantSetup("parallax", &binder_parallax); @@ -539,11 +524,9 @@ void CRender::create() Resources->RegisterConstantSetup("sun_shafts_intensity", &binder_sun_shafts_intensity); Resources->RegisterConstantSetup("pos_decompression_params", &binder_pos_decompress_params); Resources->RegisterConstantSetup("pos_decompression_params2", &binder_pos_decompress_params2); -#if defined(USE_DX11) || defined(USE_OGL) Resources->RegisterConstantSetup("m_AlphaRef", &binder_alpha_ref); -# if defined(USE_DX11) +#if defined(USE_DX11) Resources->RegisterConstantSetup("triLOD", &binder_LOD); -# endif #endif m_bMakeAsyncSS = false; @@ -554,9 +537,7 @@ void CRender::create() PSLibrary.OnCreate(); HWOCC.occq_create(occq_size); -#if defined(USE_DX11) || defined(USE_OGL) rmNormal(RCache); -#endif q_sync_point.Create(); // TODO: OGL: Implement FluidManager. diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index c4489a284df..55f374b0290 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -76,9 +76,7 @@ void CRender::Render() g_r = 1; -#if defined(USE_DX11) || defined(USE_OGL) rmNormal(RCache); -#endif IMainMenu* pMainMenu = g_pGamePersistent ? g_pGamePersistent->m_pMainMenu : 0; bool bMenu = pMainMenu ? pMainMenu->CanSkipSceneRendering() : false; @@ -87,9 +85,7 @@ void CRender::Render() // if (!(g_pGameLevel && g_hud) || bMenu) if (!g_pGameLevel || bMenu) { -#if defined(USE_DX11) || defined(USE_OGL) // XXX: probably we can just enable this on DX9 too Target->u_setrt(RCache, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), 0, 0, Target->get_base_zb()); -#endif return; } diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index 7d23c6b3efc..71b4a2829c2 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -11,14 +11,12 @@ #include "Layers/xrRender/blenders/blender_luminance.h" #include "Layers/xrRender/blenders/blender_ssao.h" -#if defined(USE_DX11) || defined(USE_OGL) -# include "Layers/xrRender/blenders/dx11MSAABlender.h" -# include "Layers/xrRender/blenders/dx11RainBlender.h" - -# include "Layers/xrRender/blenders/dx11MinMaxSMBlender.h" -# if defined(USE_DX11) -# include "Layers/xrRender/blenders/dx11HDAOCSBlender.h" -# endif +#include "Layers/xrRender/blenders/dx11MSAABlender.h" +#include "Layers/xrRender/blenders/dx11RainBlender.h" + +#include "Layers/xrRender/blenders/dx11MinMaxSMBlender.h" +#if defined(USE_DX11) +# include "Layers/xrRender/blenders/dx11HDAOCSBlender.h" #endif //Anomaly blenders @@ -245,7 +243,6 @@ CRenderTarget::CRenderTarget() // Blenders b_accum_spot = xr_new(); -#if defined(USE_DX11) || defined(USE_OGL) if (options.msaa) { for (u32 i = 0; i < BoundSamples; ++i) @@ -254,7 +251,6 @@ CRenderTarget::CRenderTarget() b_accum_volumetric_msaa[i] = xr_new("ISAMPLE", SAMPLE_DEFS[i]); } } -#endif // USE_DX11 || USE_OGL // NORMAL { @@ -408,7 +404,6 @@ CRenderTarget::CRenderTarget() // otherwise - create texture with specified HW_smap_FORMAT const auto num_slices = RImplementation.o.support_rt_arrays ? R__NUM_SUN_CASCADES : 1; rt_smap_depth.create(r2_RT_smap_depth, smapsize, smapsize, depth_format, 1, num_slices, flags); -#if defined(USE_DX11) || defined(USE_OGL) rt_smap_rain.create(r2_RT_smap_rain, options.rain_smapsize, options.rain_smapsize, depth_format); if (options.minmax_sm) { @@ -416,7 +411,6 @@ CRenderTarget::CRenderTarget() CBlender_createminmax b_create_minmax; s_create_minmax_sm.create(&b_create_minmax, "null"); } -#endif // Accum mask { @@ -444,7 +438,6 @@ CRenderTarget::CRenderTarget() } // Accum direct/mask MSAA -#if defined(USE_DX11) || defined(USE_OGL) if (options.msaa) { for (u32 i = 0; i < BoundSamples; ++i) @@ -455,7 +448,6 @@ CRenderTarget::CRenderTarget() s_accum_mask_msaa[i].create(&b_accum_mask_msaa, "r2" DELIMITER "accum_direct"); } } -#endif // Accum volumetric if (options.advancedpp) @@ -463,7 +455,6 @@ CRenderTarget::CRenderTarget() s_accum_direct_volumetric.create("accum_volumetric_sun_nomsaa"); manually_assign_texture(s_accum_direct_volumetric, "s_smap", smapTarget); -#if defined(USE_DX11) || defined(USE_OGL) if (options.minmax_sm) { s_accum_direct_volumetric_minmax.create("accum_volumetric_sun_nomsaa_minmax"); @@ -488,14 +479,12 @@ CRenderTarget::CRenderTarget() manually_assign_texture(s_accum_direct_volumetric_msaa[i], "s_smap", smapTarget); } } -#endif // USE_DX11 || USE_OGL } } // RAIN // TODO: DX11: Create resources only when DX11 rain is enabled. // Or make DX11 rain switch dynamic? -#if defined(USE_DX11) || defined(USE_OGL) { CBlender_rain b_rain; s_rain.create(&b_rain, "null"); @@ -521,15 +510,12 @@ CRenderTarget::CRenderTarget() } } } -#endif // USE_DX11 || USE_OGL -#if defined(USE_DX11) || defined(USE_OGL) if (options.msaa) { CBlender_msaa b_msaa; s_mark_msaa_edges.create(&b_msaa, "null"); } -#endif // POINT { @@ -561,7 +547,6 @@ CRenderTarget::CRenderTarget() { CBlender_accum_reflected b_accum_reflected; s_accum_reflected.create(&b_accum_reflected, "r2" DELIMITER "accum_refl"); -#if defined(USE_DX11) || defined(USE_OGL) if (options.msaa) { for (u32 i = 0; i < BoundSamples; ++i) @@ -570,7 +555,6 @@ CRenderTarget::CRenderTarget() s_accum_reflected_msaa[i].create(&b_accum_reflected_msaa, "null"); } } -#endif // USE_DX11 || USE_OGL } // BLOOM @@ -601,11 +585,9 @@ CRenderTarget::CRenderTarget() f_bloom_factor = 0.5f; } -#if defined(USE_DX11) || defined(USE_OGL) // Check if SSAO Ultra is allowed if (ps_r_ssao_mode != 2 /*hdao*/ || !options.ssao_ultra) ps_r_ssao = _min(ps_r_ssao, 3); -#endif // HBAO if (options.ssao_opt_data) @@ -793,7 +775,6 @@ CRenderTarget::~CRenderTarget() // Blenders xr_delete(b_accum_spot); -#if defined(USE_DX11) || defined(USE_OGL) if (RImplementation.o.msaa) { const u32 bound = RImplementation.o.msaa_opt ? 1 : RImplementation.o.msaa_samples; @@ -804,7 +785,6 @@ CRenderTarget::~CRenderTarget() xr_delete(b_accum_volumetric_msaa[i]); } } -#endif } void CRenderTarget::reset_light_marker(CBackend& cmd_list, bool bResetStencil) @@ -861,7 +841,6 @@ bool CRenderTarget::need_to_render_sunshafts() return true; } -#if defined(USE_DX11) || defined(USE_OGL) bool CRenderTarget::use_minmax_sm_this_frame() { switch (RImplementation.o.minmax_sm) @@ -881,4 +860,3 @@ bool CRenderTarget::use_minmax_sm_this_frame() default: return false; } } -#endif diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp index 2f21c6253d4..07df52f2442 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp @@ -49,10 +49,8 @@ void CRenderTarget::phase_accumulator(CBackend& cmd_list) cmd_list.set_ColorWriteEnable(); } -#if defined(USE_DX11) || defined(USE_OGL) // Restore viewport after shadow map rendering RImplementation.rmNormal(cmd_list); -#endif } void CRenderTarget::phase_vol_accumulator(CBackend& cmd_list) From 604e84f65488539344f0d3caed9c06598477dc0d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 30 Apr 2024 05:58:53 +0500 Subject: [PATCH 313/497] Lie to game scripts about the renderer to make game options work correctly Sorry. --- src/Layers/xrRenderPC_R4/xrRender_R4.cpp | 56 +++++++++++++++++------- src/xrEngine/EngineAPI.cpp | 9 ++-- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index e7efafe36eb..5476335200b 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -1,11 +1,16 @@ #include "stdafx.h" + #include "Layers/xrRender/dxRenderFactory.h" #include "Layers/xrRender/dxUIRender.h" #include "Layers/xrRender/dxDebugRender.h" #include "Layers/xrRender/D3DUtils.h" -constexpr pcstr RENDERER_R3_MODE = "renderer_r3"; -constexpr pcstr RENDERER_R4_MODE = "renderer_r4"; +constexpr pcstr RENDERER_R1_MODE = "renderer_r1"; +constexpr pcstr RENDERER_R2A_MODE = "renderer_r2a"; +constexpr pcstr RENDERER_R2_MODE = "renderer_r2"; +constexpr pcstr RENDERER_R2_5_MODE = "renderer_r2.5"; +constexpr pcstr RENDERER_R3_MODE = "renderer_r3"; +constexpr pcstr RENDERER_R4_MODE = "renderer_r4"; class R4RendererModule final : public RendererModule { @@ -30,7 +35,17 @@ class R4RendererModule final : public RendererModule const xr_vector& ObtainSupportedModes() override { - switch (CheckCanAddMode()) + const BOOL result = CheckCanAddMode(); + if (result != FALSE) + { + // Lie to game scripts to make options work correctly + // (so that we don't need to modify scripts) + modes.emplace_back(RENDERER_R1_MODE); + modes.emplace_back(RENDERER_R2A_MODE); + modes.emplace_back(RENDERER_R2_MODE); + modes.emplace_back(RENDERER_R2_5_MODE); + } + switch (result) { case TRUE: modes.emplace_back(RENDERER_R3_MODE); @@ -42,23 +57,32 @@ class R4RendererModule final : public RendererModule return modes; } - void CheckModeConsistency(pcstr mode) const + void SetupEnv(pcstr mode) override { - bool modeIsCorrect = false; - if (0 == xr_strcmp(mode, RENDERER_R3_MODE) || - 0 == xr_strcmp(mode, RENDERER_R4_MODE)) + ps_r2_sun_static = false; + + switch (strhash(mode)) { - modeIsCorrect = true; + case strhash(RENDERER_R1_MODE): + case strhash(RENDERER_R2A_MODE): + // vanilla shaders fail to compile with static sun enabled + //ps_r2_sun_static = true; + [[fallthrough]]; + + case strhash(RENDERER_R2_MODE): + ps_r2_advanced_pp = false; + break; + + case strhash(RENDERER_R2_5_MODE): + case strhash(RENDERER_R3_MODE): + HW.DX10Only = true; + [[fallthrough]]; + + case strhash(RENDERER_R4_MODE): + ps_r2_advanced_pp = true; + break; } - R_ASSERT3(modeIsCorrect, "Wrong mode passed to xrRender_R4", mode); - } - void SetupEnv(pcstr mode) override - { - CheckModeConsistency(mode); - ps_r2_sun_static = false; - ps_r2_advanced_pp = true; - HW.DX10Only = xr_strcmp(mode, RENDERER_R3_MODE) == 0; GEnv.Render = &RImplementation; GEnv.RenderFactory = &RenderFactoryImpl; GEnv.DU = &DUImpl; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 53c2f4f3f3d..ec1838880ac 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -25,8 +25,6 @@ constexpr pcstr RENDER_LIBRARIES[] = gl_library }; -static bool r2_available = false; - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -178,10 +176,9 @@ void CEngineAPI::CreateRendererList() } else { - for (pcstr library : RENDER_LIBRARIES) + for (cpcstr library : RENDER_LIBRARIES) { - if (loadLibrary(library) && library != r4_library) - r2_available = true; + loadLibrary(library); } } @@ -230,6 +227,6 @@ SCRIPT_EXPORT(CheckRendererSupport, (), using namespace luabind; module(luaState) [ - def("xrRender_test_r2_hw", +[](){ return r2_available; }) + def("xrRender_test_r2_hw", +[](){ return true; }) ]; }); From f57bc5a3464e5f38cb6a405397c52aa54f4319e7 Mon Sep 17 00:00:00 2001 From: Chugunov Roman Date: Tue, 30 Apr 2024 19:03:45 +0300 Subject: [PATCH 314/497] .vscode/tasks.json: remove dependsOn from run tasks --- .vscode/tasks.json | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9a8c5fdffe1..aa238731345 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -15,10 +15,7 @@ "cwd": "${workspaceFolder}" }, "command": "rm", - "args": [ - "-rf", - "bin" - ], + "args": ["-rf", "bin"], "problemMatcher": [] }, { @@ -28,10 +25,7 @@ "options": { "cwd": "${workspaceFolder}" }, - "args": [ - "-p", - "bin" - ] + "args": ["-p", "bin"] }, { "label": "Configure", @@ -40,9 +34,7 @@ "cwd": "${workspaceFolder}/bin" }, "command": "cmake .. -DCMAKE_BUILD_TYPE=${input:buildType}", - "dependsOn": [ - "mkdir" - ], + "dependsOn": ["mkdir"], "problemMatcher": [] }, { @@ -52,9 +44,7 @@ "cwd": "${workspaceFolder}/bin" }, "command": "cmake --build . -j${CPU_COUNT}", - "dependsOn": [ - "Configure" - ] + "dependsOn": ["Configure"] }, { "label": "Run SoC", @@ -63,9 +53,6 @@ "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" }, "command": "./xr_3da -soc -nointro -fsltx ${SOC_LTX_FILE_PATH}", - "dependsOn": [ - "Compile" - ], "problemMatcher": [] }, { @@ -75,9 +62,6 @@ "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" }, "command": "./xr_3da -cs -nointro -fsltx ${CS_LTX_FILE_PATH}", - "dependsOn": [ - "Compile" - ], "problemMatcher": [] }, { @@ -87,23 +71,15 @@ "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" }, "command": "./xr_3da -nointro -fsltx ${COP_LTX_FILE_PATH}", - "dependsOn": [ - "Compile" - ], "problemMatcher": [] - }, + } ], "inputs": [ { "id": "buildType", "type": "pickString", "description": "choose build type:", - "options": [ - "Debug", - "Release", - "MinSizeRel", - "RelWithDebInfo" - ], + "options": ["Debug", "Release", "MinSizeRel", "RelWithDebInfo"], "default": "Debug" } ] From 7c4e9219b9887845e87f162c4335cdc12fe31835 Mon Sep 17 00:00:00 2001 From: Chugunov Roman Date: Tue, 30 Apr 2024 19:08:12 +0300 Subject: [PATCH 315/497] .vscode/tasks.json: replace x64 on x86_64 --- .vscode/tasks.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index aa238731345..b41119189f1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "options": { "env": { - "LD_LIBRARY_PATH": "${workspaceFolder}/bin/x64/Debug:${workspaceFolder}/bin/x64/Mixed:${workspaceFolder}/bin/x64/Release" + "LD_LIBRARY_PATH": "${workspaceFolder}/bin/x86_64/Debug:${workspaceFolder}/bin/x86_64/Mixed:${workspaceFolder}/bin/x86_64/Release" } }, "tasks": [ @@ -50,7 +50,7 @@ "label": "Run SoC", "type": "shell", "options": { - "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" + "cwd": "${workspaceFolder}/bin/x86_64/${input:buildType}" }, "command": "./xr_3da -soc -nointro -fsltx ${SOC_LTX_FILE_PATH}", "problemMatcher": [] @@ -59,7 +59,7 @@ "label": "Run CS", "type": "shell", "options": { - "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" + "cwd": "${workspaceFolder}/bin/x86_64/${input:buildType}" }, "command": "./xr_3da -cs -nointro -fsltx ${CS_LTX_FILE_PATH}", "problemMatcher": [] @@ -68,7 +68,7 @@ "label": "Run CoP", "type": "shell", "options": { - "cwd": "${workspaceFolder}/bin/x64/${input:buildType}" + "cwd": "${workspaceFolder}/bin/x86_64/${input:buildType}" }, "command": "./xr_3da -nointro -fsltx ${COP_LTX_FILE_PATH}", "problemMatcher": [] From 38f6d2752187449c88c87660ca54f23c8476052f Mon Sep 17 00:00:00 2001 From: Chugunov Roman Date: Tue, 30 Apr 2024 19:10:10 +0300 Subject: [PATCH 316/497] .vscode/tasks.json: add path to the RelWithDebInfo in the LD_LIBRARY_PATH env var --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b41119189f1..3f753305e7d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "options": { "env": { - "LD_LIBRARY_PATH": "${workspaceFolder}/bin/x86_64/Debug:${workspaceFolder}/bin/x86_64/Mixed:${workspaceFolder}/bin/x86_64/Release" + "LD_LIBRARY_PATH": "${workspaceFolder}/bin/x86_64/Debug:${workspaceFolder}/bin/x86_64/Mixed:${workspaceFolder}/bin/x86_64/Release:${workspaceFolder}/bin/x86_64/RelWithDebInfo" } }, "tasks": [ From 8f7a58f3cf980aec3fd955fbb04d4745715548a0 Mon Sep 17 00:00:00 2001 From: vTurbine Date: Wed, 1 May 2024 03:28:02 +0200 Subject: [PATCH 317/497] Reference implementation of profiler usage (#1662) Co-authored-by: Sultan Uramaev --- Externals/tracy/AUTHORS | 20 + Externals/tracy/LICENSE | 27 + Externals/tracy/public/TracyClient.cpp | 58 + Externals/tracy/public/client/TracyAlloc.cpp | 43 + .../tracy/public/client/TracyArmCpuTable.hpp | 401 + .../tracy/public/client/TracyCallstack.cpp | 1070 +++ .../tracy/public/client/TracyCallstack.h | 35 + .../tracy/public/client/TracyCallstack.hpp | 142 + Externals/tracy/public/client/TracyCpuid.hpp | 12 + Externals/tracy/public/client/TracyDebug.hpp | 11 + Externals/tracy/public/client/TracyDxt1.cpp | 644 ++ Externals/tracy/public/client/TracyDxt1.hpp | 11 + .../tracy/public/client/TracyFastVector.hpp | 118 + Externals/tracy/public/client/TracyLock.hpp | 546 ++ .../tracy/public/client/TracyOverride.cpp | 26 + .../tracy/public/client/TracyProfiler.cpp | 4419 ++++++++++ .../tracy/public/client/TracyProfiler.hpp | 1002 +++ .../tracy/public/client/TracyRingBuffer.hpp | 141 + Externals/tracy/public/client/TracyScoped.hpp | 175 + .../public/client/TracyStringHelpers.hpp | 41 + .../tracy/public/client/TracySysPower.cpp | 164 + .../tracy/public/client/TracySysPower.hpp | 44 + .../tracy/public/client/TracySysTime.cpp | 108 + .../tracy/public/client/TracySysTime.hpp | 36 + .../tracy/public/client/TracySysTrace.cpp | 1602 ++++ .../tracy/public/client/TracySysTrace.hpp | 28 + Externals/tracy/public/client/TracyThread.hpp | 90 + .../tracy/public/client/tracy_SPSCQueue.h | 148 + .../public/client/tracy_concurrentqueue.h | 1441 ++++ .../tracy/public/client/tracy_rpmalloc.cpp | 3518 ++++++++ .../tracy/public/client/tracy_rpmalloc.hpp | 363 + Externals/tracy/public/common/TracyAlign.hpp | 27 + Externals/tracy/public/common/TracyAlloc.hpp | 72 + Externals/tracy/public/common/TracyApi.h | 16 + Externals/tracy/public/common/TracyColor.hpp | 690 ++ .../tracy/public/common/TracyForceInline.hpp | 20 + Externals/tracy/public/common/TracyMutex.hpp | 24 + .../tracy/public/common/TracyProtocol.hpp | 169 + Externals/tracy/public/common/TracyQueue.hpp | 884 ++ Externals/tracy/public/common/TracySocket.cpp | 749 ++ Externals/tracy/public/common/TracySocket.hpp | 155 + .../tracy/public/common/TracyStackFrames.cpp | 122 + .../tracy/public/common/TracyStackFrames.hpp | 22 + Externals/tracy/public/common/TracySystem.cpp | 306 + Externals/tracy/public/common/TracySystem.hpp | 32 + Externals/tracy/public/common/TracyUwp.hpp | 11 + .../tracy/public/common/TracyVersion.hpp | 14 + Externals/tracy/public/common/TracyYield.hpp | 28 + Externals/tracy/public/common/tracy_lz4.cpp | 2720 ++++++ Externals/tracy/public/common/tracy_lz4.hpp | 847 ++ Externals/tracy/public/common/tracy_lz4hc.cpp | 1636 ++++ Externals/tracy/public/common/tracy_lz4hc.hpp | 405 + Externals/tracy/public/libbacktrace/LICENSE | 29 + Externals/tracy/public/libbacktrace/alloc.cpp | 174 + .../tracy/public/libbacktrace/backtrace.hpp | 186 + Externals/tracy/public/libbacktrace/config.h | 26 + Externals/tracy/public/libbacktrace/dwarf.cpp | 4425 ++++++++++ Externals/tracy/public/libbacktrace/elf.cpp | 7491 +++++++++++++++++ .../tracy/public/libbacktrace/fileline.cpp | 351 + .../tracy/public/libbacktrace/filenames.hpp | 52 + .../tracy/public/libbacktrace/internal.hpp | 394 + Externals/tracy/public/libbacktrace/macho.cpp | 1360 +++ .../tracy/public/libbacktrace/mmapio.cpp | 115 + Externals/tracy/public/libbacktrace/posix.cpp | 109 + Externals/tracy/public/libbacktrace/sort.cpp | 113 + Externals/tracy/public/libbacktrace/state.cpp | 76 + Externals/tracy/public/tracy/Tracy.hpp | 283 + Externals/tracy/public/tracy/TracyC.h | 370 + Externals/tracy/public/tracy/TracyD3D11.hpp | 446 + Externals/tracy/public/tracy/TracyD3D12.hpp | 500 ++ Externals/tracy/public/tracy/TracyLua.hpp | 431 + Externals/tracy/public/tracy/TracyOpenCL.hpp | 414 + Externals/tracy/public/tracy/TracyOpenGL.hpp | 325 + Externals/tracy/public/tracy/TracyVulkan.hpp | 705 ++ src/Layers/xrRenderDX11/dx11HW.cpp | 7 + src/Layers/xrRenderDX11/dx11HW.h | 1 + src/Layers/xrRenderPC_R4/stdafx.h | 2 + src/Layers/xrRender_R2/r2_R_calculate.cpp | 4 + src/Layers/xrRender_R2/r2_R_render.cpp | 6 + src/xrCore/CMakeLists.txt | 3 + src/xrCore/Threading/ThreadUtil.h | 3 + src/xrCore/xrCore.h | 3 + src/xrCore/xrCore.vcxproj | 5 +- src/xrCore/xrCore.vcxproj.filters | 6 + src/xrEngine/device.cpp | 6 + src/xray_build.props | 8 +- src/xray_input.props | 1 + 87 files changed, 43861 insertions(+), 2 deletions(-) create mode 100644 Externals/tracy/AUTHORS create mode 100644 Externals/tracy/LICENSE create mode 100644 Externals/tracy/public/TracyClient.cpp create mode 100644 Externals/tracy/public/client/TracyAlloc.cpp create mode 100644 Externals/tracy/public/client/TracyArmCpuTable.hpp create mode 100644 Externals/tracy/public/client/TracyCallstack.cpp create mode 100644 Externals/tracy/public/client/TracyCallstack.h create mode 100644 Externals/tracy/public/client/TracyCallstack.hpp create mode 100644 Externals/tracy/public/client/TracyCpuid.hpp create mode 100644 Externals/tracy/public/client/TracyDebug.hpp create mode 100644 Externals/tracy/public/client/TracyDxt1.cpp create mode 100644 Externals/tracy/public/client/TracyDxt1.hpp create mode 100644 Externals/tracy/public/client/TracyFastVector.hpp create mode 100644 Externals/tracy/public/client/TracyLock.hpp create mode 100644 Externals/tracy/public/client/TracyOverride.cpp create mode 100644 Externals/tracy/public/client/TracyProfiler.cpp create mode 100644 Externals/tracy/public/client/TracyProfiler.hpp create mode 100644 Externals/tracy/public/client/TracyRingBuffer.hpp create mode 100644 Externals/tracy/public/client/TracyScoped.hpp create mode 100644 Externals/tracy/public/client/TracyStringHelpers.hpp create mode 100644 Externals/tracy/public/client/TracySysPower.cpp create mode 100644 Externals/tracy/public/client/TracySysPower.hpp create mode 100644 Externals/tracy/public/client/TracySysTime.cpp create mode 100644 Externals/tracy/public/client/TracySysTime.hpp create mode 100644 Externals/tracy/public/client/TracySysTrace.cpp create mode 100644 Externals/tracy/public/client/TracySysTrace.hpp create mode 100644 Externals/tracy/public/client/TracyThread.hpp create mode 100644 Externals/tracy/public/client/tracy_SPSCQueue.h create mode 100644 Externals/tracy/public/client/tracy_concurrentqueue.h create mode 100644 Externals/tracy/public/client/tracy_rpmalloc.cpp create mode 100644 Externals/tracy/public/client/tracy_rpmalloc.hpp create mode 100644 Externals/tracy/public/common/TracyAlign.hpp create mode 100644 Externals/tracy/public/common/TracyAlloc.hpp create mode 100644 Externals/tracy/public/common/TracyApi.h create mode 100644 Externals/tracy/public/common/TracyColor.hpp create mode 100644 Externals/tracy/public/common/TracyForceInline.hpp create mode 100644 Externals/tracy/public/common/TracyMutex.hpp create mode 100644 Externals/tracy/public/common/TracyProtocol.hpp create mode 100644 Externals/tracy/public/common/TracyQueue.hpp create mode 100644 Externals/tracy/public/common/TracySocket.cpp create mode 100644 Externals/tracy/public/common/TracySocket.hpp create mode 100644 Externals/tracy/public/common/TracyStackFrames.cpp create mode 100644 Externals/tracy/public/common/TracyStackFrames.hpp create mode 100644 Externals/tracy/public/common/TracySystem.cpp create mode 100644 Externals/tracy/public/common/TracySystem.hpp create mode 100644 Externals/tracy/public/common/TracyUwp.hpp create mode 100644 Externals/tracy/public/common/TracyVersion.hpp create mode 100644 Externals/tracy/public/common/TracyYield.hpp create mode 100644 Externals/tracy/public/common/tracy_lz4.cpp create mode 100644 Externals/tracy/public/common/tracy_lz4.hpp create mode 100644 Externals/tracy/public/common/tracy_lz4hc.cpp create mode 100644 Externals/tracy/public/common/tracy_lz4hc.hpp create mode 100644 Externals/tracy/public/libbacktrace/LICENSE create mode 100644 Externals/tracy/public/libbacktrace/alloc.cpp create mode 100644 Externals/tracy/public/libbacktrace/backtrace.hpp create mode 100644 Externals/tracy/public/libbacktrace/config.h create mode 100644 Externals/tracy/public/libbacktrace/dwarf.cpp create mode 100644 Externals/tracy/public/libbacktrace/elf.cpp create mode 100644 Externals/tracy/public/libbacktrace/fileline.cpp create mode 100644 Externals/tracy/public/libbacktrace/filenames.hpp create mode 100644 Externals/tracy/public/libbacktrace/internal.hpp create mode 100644 Externals/tracy/public/libbacktrace/macho.cpp create mode 100644 Externals/tracy/public/libbacktrace/mmapio.cpp create mode 100644 Externals/tracy/public/libbacktrace/posix.cpp create mode 100644 Externals/tracy/public/libbacktrace/sort.cpp create mode 100644 Externals/tracy/public/libbacktrace/state.cpp create mode 100644 Externals/tracy/public/tracy/Tracy.hpp create mode 100644 Externals/tracy/public/tracy/TracyC.h create mode 100644 Externals/tracy/public/tracy/TracyD3D11.hpp create mode 100644 Externals/tracy/public/tracy/TracyD3D12.hpp create mode 100644 Externals/tracy/public/tracy/TracyLua.hpp create mode 100644 Externals/tracy/public/tracy/TracyOpenCL.hpp create mode 100644 Externals/tracy/public/tracy/TracyOpenGL.hpp create mode 100644 Externals/tracy/public/tracy/TracyVulkan.hpp diff --git a/Externals/tracy/AUTHORS b/Externals/tracy/AUTHORS new file mode 100644 index 00000000000..e12c978137b --- /dev/null +++ b/Externals/tracy/AUTHORS @@ -0,0 +1,20 @@ +Bartosz Taudul +Kamil Klimek (initial find zone implementation) +Bartosz Szreder (view/worker split) +Arvid Gerstmann (compatibility fixes) +Rokas Kupstys (compatibility fixes, initial CI work, MingW support) +Till Rathmann (DLL support) +Sherief Farouk (compatibility fixes) +Dedmen Miller (find zone bug fixes, improvements) +Michał Cichoń (OSX call stack decoding backport) +Thales Sabino (OpenCL support) +Andrew Depke (Direct3D 12 support) +Simonas Kazlauskas (OSX CI, external bindings) +Jakub Žádník (csvexport utility) +Andrey Voroshilov (multi-DLL fixes) +Benoit Jacob (Android improvements) +David Farrel (Direct3D 11 support) +Terence Rokop (Non-reentrant zones) +Lukas Berbuer (CMake integration) +Xavier Bouchoux (sample data in find zone) +Balazs Kovacsics (Universal Windows Platform) diff --git a/Externals/tracy/LICENSE b/Externals/tracy/LICENSE new file mode 100644 index 00000000000..72a6fe1c389 --- /dev/null +++ b/Externals/tracy/LICENSE @@ -0,0 +1,27 @@ +Tracy Profiler (https://github.com/wolfpld/tracy) is licensed under the +3-clause BSD license. + +Copyright (c) 2017-2023, Bartosz Taudul +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Externals/tracy/public/TracyClient.cpp b/Externals/tracy/public/TracyClient.cpp new file mode 100644 index 00000000000..26387b762ed --- /dev/null +++ b/Externals/tracy/public/TracyClient.cpp @@ -0,0 +1,58 @@ +// +// Tracy profiler +// ---------------- +// +// For fast integration, compile and +// link with this source file (and none +// other) in your executable (or in the +// main DLL / shared object on multi-DLL +// projects). +// + +// Define TRACY_ENABLE to enable profiler. + +#include "common/TracySystem.cpp" + +#ifdef TRACY_ENABLE + +#ifdef _MSC_VER +# pragma warning(push, 0) +#endif + +#include "common/tracy_lz4.cpp" +#include "client/TracyProfiler.cpp" +#include "client/TracyCallstack.cpp" +#include "client/TracySysPower.cpp" +#include "client/TracySysTime.cpp" +#include "client/TracySysTrace.cpp" +#include "common/TracySocket.cpp" +#include "client/tracy_rpmalloc.cpp" +#include "client/TracyDxt1.cpp" +#include "client/TracyAlloc.cpp" +#include "client/TracyOverride.cpp" + +#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 +# include "libbacktrace/alloc.cpp" +# include "libbacktrace/dwarf.cpp" +# include "libbacktrace/fileline.cpp" +# include "libbacktrace/mmapio.cpp" +# include "libbacktrace/posix.cpp" +# include "libbacktrace/sort.cpp" +# include "libbacktrace/state.cpp" +# if TRACY_HAS_CALLSTACK == 4 +# include "libbacktrace/macho.cpp" +# else +# include "libbacktrace/elf.cpp" +# endif +# include "common/TracyStackFrames.cpp" +#endif + +#ifdef _MSC_VER +# pragma comment(lib, "ws2_32.lib") +# pragma comment(lib, "dbghelp.lib") +# pragma comment(lib, "advapi32.lib") +# pragma comment(lib, "user32.lib") +# pragma warning(pop) +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyAlloc.cpp b/Externals/tracy/public/client/TracyAlloc.cpp new file mode 100644 index 00000000000..c675b6d3f88 --- /dev/null +++ b/Externals/tracy/public/client/TracyAlloc.cpp @@ -0,0 +1,43 @@ +#include "../common/TracyAlloc.hpp" + +#ifdef TRACY_USE_RPMALLOC + +#include + +#include "../common/TracyForceInline.hpp" +#include "../common/TracyYield.hpp" + +namespace tracy +{ + +extern thread_local bool RpThreadInitDone; +extern std::atomic RpInitDone; +extern std::atomic RpInitLock; + +tracy_no_inline static void InitRpmallocPlumbing() +{ + const auto done = RpInitDone.load( std::memory_order_acquire ); + if( !done ) + { + int expected = 0; + while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); } + const auto done = RpInitDone.load( std::memory_order_acquire ); + if( !done ) + { + rpmalloc_initialize(); + RpInitDone.store( 1, std::memory_order_release ); + } + RpInitLock.store( 0, std::memory_order_release ); + } + rpmalloc_thread_initialize(); + RpThreadInitDone = true; +} + +TRACY_API void InitRpmalloc() +{ + if( !RpThreadInitDone ) InitRpmallocPlumbing(); +} + +} + +#endif diff --git a/Externals/tracy/public/client/TracyArmCpuTable.hpp b/Externals/tracy/public/client/TracyArmCpuTable.hpp new file mode 100644 index 00000000000..2b445976439 --- /dev/null +++ b/Externals/tracy/public/client/TracyArmCpuTable.hpp @@ -0,0 +1,401 @@ +namespace tracy +{ + +#if defined __linux__ && defined __ARM_ARCH + +static const char* DecodeArmImplementer( uint32_t v ) +{ + static char buf[16]; + switch( v ) + { + case 0x41: return "ARM"; + case 0x42: return "Broadcom"; + case 0x43: return "Cavium"; + case 0x44: return "DEC"; + case 0x46: return "Fujitsu"; + case 0x48: return "HiSilicon"; + case 0x49: return "Infineon"; + case 0x4d: return "Motorola"; + case 0x4e: return "Nvidia"; + case 0x50: return "Applied Micro"; + case 0x51: return "Qualcomm"; + case 0x53: return "Samsung"; + case 0x54: return "Texas Instruments"; + case 0x56: return "Marvell"; + case 0x61: return "Apple"; + case 0x66: return "Faraday"; + case 0x68: return "HXT"; + case 0x69: return "Intel"; + case 0xc0: return "Ampere Computing"; + default: break; + } + sprintf( buf, "0x%x", v ); + return buf; +} + +static const char* DecodeArmPart( uint32_t impl, uint32_t part ) +{ + static char buf[16]; + switch( impl ) + { + case 0x41: // ARM + switch( part ) + { + case 0x810: return "810"; + case 0x920: return "920"; + case 0x922: return "922"; + case 0x926: return "926"; + case 0x940: return "940"; + case 0x946: return "946"; + case 0x966: return "966"; + case 0xa20: return "1020"; + case 0xa22: return "1022"; + case 0xa26: return "1026"; + case 0xb02: return "11 MPCore"; + case 0xb36: return "1136"; + case 0xb56: return "1156"; + case 0xb76: return "1176"; + case 0xc05: return " Cortex-A5"; + case 0xc07: return " Cortex-A7"; + case 0xc08: return " Cortex-A8"; + case 0xc09: return " Cortex-A9"; + case 0xc0c: return " Cortex-A12"; + case 0xc0d: return " Rockchip RK3288"; + case 0xc0e: return " Cortex-A17"; + case 0xc0f: return " Cortex-A15"; + case 0xc14: return " Cortex-R4"; + case 0xc15: return " Cortex-R5"; + case 0xc17: return " Cortex-R7"; + case 0xc18: return " Cortex-R8"; + case 0xc20: return " Cortex-M0"; + case 0xc21: return " Cortex-M1"; + case 0xc23: return " Cortex-M3"; + case 0xc24: return " Cortex-M4"; + case 0xc27: return " Cortex-M7"; + case 0xc60: return " Cortex-M0+"; + case 0xd00: return " AArch64 simulator"; + case 0xd01: return " Cortex-A32"; + case 0xd02: return " Cortex-A34"; + case 0xd03: return " Cortex-A53"; + case 0xd04: return " Cortex-A35"; + case 0xd05: return " Cortex-A55"; + case 0xd06: return " Cortex-A65"; + case 0xd07: return " Cortex-A57"; + case 0xd08: return " Cortex-A72"; + case 0xd09: return " Cortex-A73"; + case 0xd0a: return " Cortex-A75"; + case 0xd0b: return " Cortex-A76"; + case 0xd0c: return " Neoverse N1"; + case 0xd0d: return " Cortex-A77"; + case 0xd0e: return " Cortex-A76AE"; + case 0xd0f: return " AEMv8"; + case 0xd13: return " Cortex-R52"; + case 0xd20: return " Cortex-M23"; + case 0xd21: return " Cortex-M33"; + case 0xd22: return " Cortex-M55"; + case 0xd40: return " Neoverse V1"; + case 0xd41: return " Cortex-A78"; + case 0xd42: return " Cortex-A78AE"; + case 0xd43: return " Cortex-A65AE"; + case 0xd44: return " Cortex-X1"; + case 0xd47: return " Cortex-A710"; + case 0xd48: return " Cortex-X2"; + case 0xd49: return " Neoverse N2"; + case 0xd4a: return " Neoverse E1"; + case 0xd4b: return " Cortex-A78C"; + case 0xd4c: return " Cortex-X1C"; + default: break; + } + case 0x42: // Broadcom + switch( part ) + { + case 0xf: return " Brahma B15"; + case 0x100: return " Brahma B53"; + case 0x516: return " ThunderX2"; + default: break; + } + case 0x43: // Cavium + switch( part ) + { + case 0xa0: return " ThunderX"; + case 0xa1: return " ThunderX 88XX"; + case 0xa2: return " ThunderX 81XX"; + case 0xa3: return " ThunderX 83XX"; + case 0xaf: return " ThunderX2 99xx"; + case 0xb0: return " OcteonTX2"; + case 0xb1: return " OcteonTX2 T98"; + case 0xb2: return " OcteonTX2 T96"; + case 0xb3: return " OcteonTX2 F95"; + case 0xb4: return " OcteonTX2 F95N"; + case 0xb5: return " OcteonTX2 F95MM"; + case 0xb6: return " OcteonTX2 F95O"; + case 0xb8: return " ThunderX3 T110"; + default: break; + } + case 0x44: // DEC + switch( part ) + { + case 0xa10: return " SA110"; + case 0xa11: return " SA1100"; + default: break; + } + case 0x46: // Fujitsu + switch( part ) + { + case 0x1: return " A64FX"; + default: break; + } + case 0x48: // HiSilicon + switch( part ) + { + case 0xd01: return " TSV100"; + case 0xd40: return " Kirin 980"; + default: break; + } + case 0x4e: // Nvidia + switch( part ) + { + case 0x0: return " Denver"; + case 0x3: return " Denver 2"; + case 0x4: return " Carmel"; + default: break; + } + case 0x50: // Applied Micro + switch( part ) + { + case 0x0: return " X-Gene"; + default: break; + } + case 0x51: // Qualcomm + switch( part ) + { + case 0xf: return " Scorpion"; + case 0x2d: return " Scorpion"; + case 0x4d: return " Krait"; + case 0x6f: return " Krait"; + case 0x200: return " Kryo"; + case 0x201: return " Kryo Silver (Snapdragon 821)"; + case 0x205: return " Kryo Gold"; + case 0x211: return " Kryo Silver (Snapdragon 820)"; + case 0x800: return " Kryo 260 / 280 Gold"; + case 0x801: return " Kryo 260 / 280 Silver"; + case 0x802: return " Kryo 385 Gold"; + case 0x803: return " Kryo 385 Silver"; + case 0x804: return " Kryo 485 Gold"; + case 0x805: return " Kryo 4xx/5xx Silver"; + case 0xc00: return " Falkor"; + case 0xc01: return " Saphira"; + default: break; + } + case 0x53: // Samsung + switch( part ) + { + case 0x1: return " Exynos M1/M2"; + case 0x2: return " Exynos M3"; + case 0x3: return " Exynos M4"; + case 0x4: return " Exynos M5"; + default: break; + } + case 0x54: // Texas Instruments + switch( part ) + { + case 0x925: return " TI925"; + default: break; + } + case 0x56: // Marvell + switch( part ) + { + case 0x131: return " Feroceon 88FR131"; + case 0x581: return " PJ4 / PJ4B"; + case 0x584: return " PJ4B-MP / PJ4C"; + default: break; + } + case 0x61: // Apple + switch( part ) + { + case 0x1: return " Cyclone"; + case 0x2: return " Typhoon"; + case 0x3: return " Typhoon/Capri"; + case 0x4: return " Twister"; + case 0x5: return " Twister/Elba/Malta"; + case 0x6: return " Hurricane"; + case 0x7: return " Hurricane/Myst"; + case 0x22: return " M1 Icestorm"; + case 0x23: return " M1 Firestorm"; + case 0x24: return " M1 Icestorm Pro"; + case 0x25: return " M1 Firestorm Pro"; + case 0x28: return " M1 Icestorm Max"; + case 0x29: return " M1 Firestorm Max"; + default: break; + } + case 0x66: // Faraday + switch( part ) + { + case 0x526: return " FA526"; + case 0x626: return " FA626"; + default: break; + } + case 0x68: // HXT + switch( part ) + { + case 0x0: return " Phecda"; + default: break; + } + case 0xc0: // Ampere Computing + switch( part ) + { + case 0xac3: return " Ampere1"; + default: break; + } + default: break; + } + sprintf( buf, " 0x%x", part ); + return buf; +} + +#elif defined __APPLE__ && TARGET_OS_IPHONE == 1 + +static const char* DecodeIosDevice( const char* id ) +{ + static const char* DeviceTable[] = { + "i386", "32-bit simulator", + "x86_64", "64-bit simulator", + "iPhone1,1", "iPhone", + "iPhone1,2", "iPhone 3G", + "iPhone2,1", "iPhone 3GS", + "iPhone3,1", "iPhone 4 (GSM)", + "iPhone3,2", "iPhone 4 (GSM)", + "iPhone3,3", "iPhone 4 (CDMA)", + "iPhone4,1", "iPhone 4S", + "iPhone5,1", "iPhone 5 (A1428)", + "iPhone5,2", "iPhone 5 (A1429)", + "iPhone5,3", "iPhone 5c (A1456/A1532)", + "iPhone5,4", "iPhone 5c (A1507/A1516/1526/A1529)", + "iPhone6,1", "iPhone 5s (A1433/A1533)", + "iPhone6,2", "iPhone 5s (A1457/A1518/A1528/A1530)", + "iPhone7,1", "iPhone 6 Plus", + "iPhone7,2", "iPhone 6", + "iPhone8,1", "iPhone 6S", + "iPhone8,2", "iPhone 6S Plus", + "iPhone8,4", "iPhone SE", + "iPhone9,1", "iPhone 7 (CDMA)", + "iPhone9,2", "iPhone 7 Plus (CDMA)", + "iPhone9,3", "iPhone 7 (GSM)", + "iPhone9,4", "iPhone 7 Plus (GSM)", + "iPhone10,1", "iPhone 8 (CDMA)", + "iPhone10,2", "iPhone 8 Plus (CDMA)", + "iPhone10,3", "iPhone X (CDMA)", + "iPhone10,4", "iPhone 8 (GSM)", + "iPhone10,5", "iPhone 8 Plus (GSM)", + "iPhone10,6", "iPhone X (GSM)", + "iPhone11,2", "iPhone XS", + "iPhone11,4", "iPhone XS Max", + "iPhone11,6", "iPhone XS Max China", + "iPhone11,8", "iPhone XR", + "iPhone12,1", "iPhone 11", + "iPhone12,3", "iPhone 11 Pro", + "iPhone12,5", "iPhone 11 Pro Max", + "iPhone12,8", "iPhone SE 2nd Gen", + "iPhone13,1", "iPhone 12 Mini", + "iPhone13,2", "iPhone 12", + "iPhone13,3", "iPhone 12 Pro", + "iPhone13,4", "iPhone 12 Pro Max", + "iPhone14,2", "iPhone 13 Pro", + "iPhone14,3", "iPhone 13 Pro Max", + "iPhone14,4", "iPhone 13 Mini", + "iPhone14,5", "iPhone 13", + "iPhone14,6", "iPhone SE 3rd Gen", + "iPad1,1", "iPad (A1219/A1337)", + "iPad2,1", "iPad 2 (A1395)", + "iPad2,2", "iPad 2 (A1396)", + "iPad2,3", "iPad 2 (A1397)", + "iPad2,4", "iPad 2 (A1395)", + "iPad2,5", "iPad Mini (A1432)", + "iPad2,6", "iPad Mini (A1454)", + "iPad2,7", "iPad Mini (A1455)", + "iPad3,1", "iPad 3 (A1416)", + "iPad3,2", "iPad 3 (A1403)", + "iPad3,3", "iPad 3 (A1430)", + "iPad3,4", "iPad 4 (A1458)", + "iPad3,5", "iPad 4 (A1459)", + "iPad3,6", "iPad 4 (A1460)", + "iPad4,1", "iPad Air (A1474)", + "iPad4,2", "iPad Air (A1475)", + "iPad4,3", "iPad Air (A1476)", + "iPad4,4", "iPad Mini 2 (A1489)", + "iPad4,5", "iPad Mini 2 (A1490)", + "iPad4,6", "iPad Mini 2 (A1491)", + "iPad4,7", "iPad Mini 3 (A1599)", + "iPad4,8", "iPad Mini 3 (A1600)", + "iPad4,9", "iPad Mini 3 (A1601)", + "iPad5,1", "iPad Mini 4 (A1538)", + "iPad5,2", "iPad Mini 4 (A1550)", + "iPad5,3", "iPad Air 2 (A1566)", + "iPad5,4", "iPad Air 2 (A1567)", + "iPad6,3", "iPad Pro 9.7\" (A1673)", + "iPad6,4", "iPad Pro 9.7\" (A1674)", + "iPad6,5", "iPad Pro 9.7\" (A1675)", + "iPad6,7", "iPad Pro 12.9\" (A1584)", + "iPad6,8", "iPad Pro 12.9\" (A1652)", + "iPad6,11", "iPad 5th gen (A1822)", + "iPad6,12", "iPad 5th gen (A1823)", + "iPad7,1", "iPad Pro 12.9\" 2nd gen (A1670)", + "iPad7,2", "iPad Pro 12.9\" 2nd gen (A1671/A1821)", + "iPad7,3", "iPad Pro 10.5\" (A1701)", + "iPad7,4", "iPad Pro 10.5\" (A1709)", + "iPad7,5", "iPad 6th gen (A1893)", + "iPad7,6", "iPad 6th gen (A1954)", + "iPad7,11", "iPad 7th gen 10.2\" (Wifi)", + "iPad7,12", "iPad 7th gen 10.2\" (Wifi+Cellular)", + "iPad8,1", "iPad Pro 11\" (A1980)", + "iPad8,2", "iPad Pro 11\" (A1980)", + "iPad8,3", "iPad Pro 11\" (A1934/A1979/A2013)", + "iPad8,4", "iPad Pro 11\" (A1934/A1979/A2013)", + "iPad8,5", "iPad Pro 12.9\" 3rd gen (A1876)", + "iPad8,6", "iPad Pro 12.9\" 3rd gen (A1876)", + "iPad8,7", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)", + "iPad8,8", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)", + "iPad8,9", "iPad Pro 11\" 2nd gen (Wifi)", + "iPad8,10", "iPad Pro 11\" 2nd gen (Wifi+Cellular)", + "iPad8,11", "iPad Pro 12.9\" 4th gen (Wifi)", + "iPad8,12", "iPad Pro 12.9\" 4th gen (Wifi+Cellular)", + "iPad11,1", "iPad Mini 5th gen (A2133)", + "iPad11,2", "iPad Mini 5th gen (A2124/A2125/A2126)", + "iPad11,3", "iPad Air 3rd gen (A2152)", + "iPad11,4", "iPad Air 3rd gen (A2123/A2153/A2154)", + "iPad11,6", "iPad 8th gen (WiFi)", + "iPad11,7", "iPad 8th gen (WiFi+Cellular)", + "iPad13,1", "iPad Air 4th gen (WiFi)", + "iPad13,2", "iPad Air 4th gen (WiFi+Cellular)", + "iPad13,4", "iPad Pro 11\" 3rd gen", + "iPad13,5", "iPad Pro 11\" 3rd gen", + "iPad13,6", "iPad Pro 11\" 3rd gen", + "iPad13,7", "iPad Pro 11\" 3rd gen", + "iPad13,8", "iPad Pro 12.9\" 5th gen", + "iPad13,9", "iPad Pro 12.9\" 5th gen", + "iPad13,10", "iPad Pro 12.9\" 5th gen", + "iPad13,11", "iPad Pro 12.9\" 5th gen", + "iPad13,16", "iPad Air 5th Gen (WiFi)", + "iPad13,17", "iPad Air 5th Gen (WiFi+Cellular)", + "iPod1,1", "iPod Touch", + "iPod2,1", "iPod Touch 2nd gen", + "iPod3,1", "iPod Touch 3rd gen", + "iPod4,1", "iPod Touch 4th gen", + "iPod5,1", "iPod Touch 5th gen", + "iPod7,1", "iPod Touch 6th gen", + "iPod9,1", "iPod Touch 7th gen", + nullptr + }; + + auto ptr = DeviceTable; + while( *ptr ) + { + if( strcmp( ptr[0], id ) == 0 ) return ptr[1]; + ptr += 2; + } + return id; +} + +#endif + +} diff --git a/Externals/tracy/public/client/TracyCallstack.cpp b/Externals/tracy/public/client/TracyCallstack.cpp new file mode 100644 index 00000000000..0de7c9d2e9a --- /dev/null +++ b/Externals/tracy/public/client/TracyCallstack.cpp @@ -0,0 +1,1070 @@ +#include +#include +#include +#include +#include "TracyCallstack.hpp" +#include "TracyFastVector.hpp" +#include "TracyStringHelpers.hpp" +#include "../common/TracyAlloc.hpp" +#include "TracyDebug.hpp" + +#ifdef TRACY_HAS_CALLSTACK + +#if TRACY_HAS_CALLSTACK == 1 +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# include +# include +# ifdef _MSC_VER +# pragma warning( push ) +# pragma warning( disable : 4091 ) +# endif +# include +# ifdef _MSC_VER +# pragma warning( pop ) +# endif +#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 +# include "../libbacktrace/backtrace.hpp" +# include +# include +# include +# include +# include "TracyFastVector.hpp" +#elif TRACY_HAS_CALLSTACK == 5 +# include +# include +#endif + +#ifdef TRACY_DBGHELP_LOCK +# include "TracyProfiler.hpp" + +# define DBGHELP_INIT TracyConcat( TRACY_DBGHELP_LOCK, Init() ) +# define DBGHELP_LOCK TracyConcat( TRACY_DBGHELP_LOCK, Lock() ); +# define DBGHELP_UNLOCK TracyConcat( TRACY_DBGHELP_LOCK, Unlock() ); + +extern "C" +{ + void DBGHELP_INIT; + void DBGHELP_LOCK; + void DBGHELP_UNLOCK; +}; +#endif + +#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 5 || TRACY_HAS_CALLSTACK == 6 +// If you want to use your own demangling functionality (e.g. for another language), +// define TRACY_DEMANGLE and provide your own implementation of the __tracy_demangle +// function. The input parameter is a function name. The demangle function must +// identify whether this name is mangled, and fail if it is not. Failure is indicated +// by returning nullptr. If demangling succeeds, a pointer to the C string containing +// demangled function must be returned. The demangling function is responsible for +// managing memory for this string. It is expected that it will be internally reused. +// When a call to ___tracy_demangle is made, previous contents of the string memory +// do not need to be preserved. Function may return string of any length, but the +// profiler can choose to truncate it. +extern "C" const char* ___tracy_demangle( const char* mangled ); + +#ifndef TRACY_DEMANGLE +constexpr size_t ___tracy_demangle_buffer_len = 1024*1024; +char* ___tracy_demangle_buffer; + +void ___tracy_init_demangle_buffer() +{ + ___tracy_demangle_buffer = (char*)tracy::tracy_malloc( ___tracy_demangle_buffer_len ); +} + +void ___tracy_free_demangle_buffer() +{ + tracy::tracy_free( ___tracy_demangle_buffer ); +} + +extern "C" const char* ___tracy_demangle( const char* mangled ) +{ + if( !mangled || mangled[0] != '_' ) return nullptr; + if( strlen( mangled ) > ___tracy_demangle_buffer_len ) return nullptr; + int status; + size_t len = ___tracy_demangle_buffer_len; + return abi::__cxa_demangle( mangled, ___tracy_demangle_buffer, &len, &status ); +} +#endif +#endif + +namespace tracy +{ + +#if TRACY_HAS_CALLSTACK == 1 + +enum { MaxCbTrace = 64 }; +enum { MaxNameSize = 8*1024 }; + +int cb_num; +CallstackEntry cb_data[MaxCbTrace]; + +extern "C" +{ + typedef DWORD (__stdcall *t_SymAddrIncludeInlineTrace)( HANDLE hProcess, DWORD64 Address ); + typedef BOOL (__stdcall *t_SymQueryInlineTrace)( HANDLE hProcess, DWORD64 StartAddress, DWORD StartContext, DWORD64 StartRetAddress, DWORD64 CurAddress, LPDWORD CurContext, LPDWORD CurFrameIndex ); + typedef BOOL (__stdcall *t_SymFromInlineContext)( HANDLE hProcess, DWORD64 Address, ULONG InlineContext, PDWORD64 Displacement, PSYMBOL_INFO Symbol ); + typedef BOOL (__stdcall *t_SymGetLineFromInlineContext)( HANDLE hProcess, DWORD64 qwAddr, ULONG InlineContext, DWORD64 qwModuleBaseAddress, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64 ); + + TRACY_API ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain = 0; + t_SymAddrIncludeInlineTrace _SymAddrIncludeInlineTrace = 0; + t_SymQueryInlineTrace _SymQueryInlineTrace = 0; + t_SymFromInlineContext _SymFromInlineContext = 0; + t_SymGetLineFromInlineContext _SymGetLineFromInlineContext = 0; +} + + +struct ModuleCache +{ + uint64_t start; + uint64_t end; + char* name; +}; + +static FastVector* s_modCache; + + +struct KernelDriver +{ + uint64_t addr; + const char* mod; + const char* path; +}; + +KernelDriver* s_krnlCache = nullptr; +size_t s_krnlCacheCnt; + + +void InitCallstackCritical() +{ + ___tracy_RtlWalkFrameChain = (___tracy_t_RtlWalkFrameChain)GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "RtlWalkFrameChain" ); +} + +void InitCallstack() +{ + _SymAddrIncludeInlineTrace = (t_SymAddrIncludeInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymAddrIncludeInlineTrace" ); + _SymQueryInlineTrace = (t_SymQueryInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymQueryInlineTrace" ); + _SymFromInlineContext = (t_SymFromInlineContext)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymFromInlineContext" ); + _SymGetLineFromInlineContext = (t_SymGetLineFromInlineContext)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymGetLineFromInlineContext" ); + +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_INIT; + DBGHELP_LOCK; +#endif + + SymInitialize( GetCurrentProcess(), nullptr, true ); + SymSetOptions( SYMOPT_LOAD_LINES ); + + DWORD needed; + LPVOID dev[4096]; + if( EnumDeviceDrivers( dev, sizeof(dev), &needed ) != 0 ) + { + char windir[MAX_PATH]; + if( !GetWindowsDirectoryA( windir, sizeof( windir ) ) ) memcpy( windir, "c:\\windows", 11 ); + const auto windirlen = strlen( windir ); + + const auto sz = needed / sizeof( LPVOID ); + s_krnlCache = (KernelDriver*)tracy_malloc( sizeof(KernelDriver) * sz ); + int cnt = 0; + for( size_t i=0; i", 2 ); + s_krnlCache[cnt] = KernelDriver { (uint64_t)dev[i], buf }; + + const auto len = GetDeviceDriverFileNameA( dev[i], fn, sizeof( fn ) ); + if( len != 0 ) + { + char full[MAX_PATH]; + char* path = fn; + + if( memcmp( fn, "\\SystemRoot\\", 12 ) == 0 ) + { + memcpy( full, windir, windirlen ); + strcpy( full + windirlen, fn + 11 ); + path = full; + } + + SymLoadModuleEx( GetCurrentProcess(), nullptr, path, nullptr, (DWORD64)dev[i], 0, nullptr, 0 ); + + const auto psz = strlen( path ); + auto pptr = (char*)tracy_malloc_fast( psz+1 ); + memcpy( pptr, path, psz ); + pptr[psz] = '\0'; + s_krnlCache[cnt].path = pptr; + } + + cnt++; + } + } + s_krnlCacheCnt = cnt; + std::sort( s_krnlCache, s_krnlCache + s_krnlCacheCnt, []( const KernelDriver& lhs, const KernelDriver& rhs ) { return lhs.addr > rhs.addr; } ); + } + + s_modCache = (FastVector*)tracy_malloc( sizeof( FastVector ) ); + new(s_modCache) FastVector( 512 ); + + HANDLE proc = GetCurrentProcess(); + HMODULE mod[1024]; + if( EnumProcessModules( proc, mod, sizeof( mod ), &needed ) != 0 ) + { + const auto sz = needed / sizeof( HMODULE ); + for( size_t i=0; i 0 ) + { + // This may be a new module loaded since our call to SymInitialize. + // Just in case, force DbgHelp to load its pdb ! + SymLoadModuleEx(proc, NULL, name, NULL, (DWORD64)info.lpBaseOfDll, info.SizeOfImage, NULL, 0); + + auto ptr = name + res; + while( ptr > name && *ptr != '\\' && *ptr != '/' ) ptr--; + if( ptr > name ) ptr++; + const auto namelen = name + res - ptr; + auto cache = s_modCache->push_next(); + cache->start = base; + cache->end = base + info.SizeOfImage; + cache->name = (char*)tracy_malloc_fast( namelen+3 ); + cache->name[0] = '['; + memcpy( cache->name+1, ptr, namelen ); + cache->name[namelen+1] = ']'; + cache->name[namelen+2] = '\0'; + } + } + } + } + +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_UNLOCK; +#endif +} + +void EndCallstack() +{ +} + +const char* DecodeCallstackPtrFast( uint64_t ptr ) +{ + static char ret[MaxNameSize]; + const auto proc = GetCurrentProcess(); + + char buf[sizeof( SYMBOL_INFO ) + MaxNameSize]; + auto si = (SYMBOL_INFO*)buf; + si->SizeOfStruct = sizeof( SYMBOL_INFO ); + si->MaxNameLen = MaxNameSize; + +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_LOCK; +#endif + if( SymFromAddr( proc, ptr, nullptr, si ) == 0 ) + { + *ret = '\0'; + } + else + { + memcpy( ret, si->Name, si->NameLen ); + ret[si->NameLen] = '\0'; + } +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_UNLOCK; +#endif + return ret; +} + +const char* GetKernelModulePath( uint64_t addr ) +{ + assert( addr >> 63 != 0 ); + if( !s_krnlCache ) return nullptr; + auto it = std::lower_bound( s_krnlCache, s_krnlCache + s_krnlCacheCnt, addr, []( const KernelDriver& lhs, const uint64_t& rhs ) { return lhs.addr > rhs; } ); + if( it == s_krnlCache + s_krnlCacheCnt ) return nullptr; + return it->path; +} + +static const char* GetModuleNameAndPrepareSymbols( uint64_t addr ) +{ + if( ( addr >> 63 ) != 0 ) + { + if( s_krnlCache ) + { + auto it = std::lower_bound( s_krnlCache, s_krnlCache + s_krnlCacheCnt, addr, []( const KernelDriver& lhs, const uint64_t& rhs ) { return lhs.addr > rhs; } ); + if( it != s_krnlCache + s_krnlCacheCnt ) + { + return it->mod; + } + } + return ""; + } + + for( auto& v : *s_modCache ) + { + if( addr >= v.start && addr < v.end ) + { + return v.name; + } + } + + HMODULE mod[1024]; + DWORD needed; + HANDLE proc = GetCurrentProcess(); + + InitRpmalloc(); + if( EnumProcessModules( proc, mod, sizeof( mod ), &needed ) != 0 ) + { + const auto sz = needed / sizeof( HMODULE ); + for( size_t i=0; i= base && addr < base + info.SizeOfImage ) + { + char name[1024]; + const auto res = GetModuleFileNameA( mod[i], name, 1021 ); + if( res > 0 ) + { + // since this is the first time we encounter this module, load its symbols (needed for modules loaded after SymInitialize) + SymLoadModuleEx(proc, NULL, name, NULL, (DWORD64)info.lpBaseOfDll, info.SizeOfImage, NULL, 0); + auto ptr = name + res; + while( ptr > name && *ptr != '\\' && *ptr != '/' ) ptr--; + if( ptr > name ) ptr++; + const auto namelen = name + res - ptr; + auto cache = s_modCache->push_next(); + cache->start = base; + cache->end = base + info.SizeOfImage; + cache->name = (char*)tracy_malloc_fast( namelen+3 ); + cache->name[0] = '['; + memcpy( cache->name+1, ptr, namelen ); + cache->name[namelen+1] = ']'; + cache->name[namelen+2] = '\0'; + return cache->name; + } + } + } + } + } + return "[unknown]"; +} + +CallstackSymbolData DecodeSymbolAddress( uint64_t ptr ) +{ + CallstackSymbolData sym; + IMAGEHLP_LINE64 line; + DWORD displacement = 0; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_LOCK; +#endif + const auto res = SymGetLineFromAddr64( GetCurrentProcess(), ptr, &displacement, &line ); + if( res == 0 || line.LineNumber >= 0xF00000 ) + { + sym.file = "[unknown]"; + sym.line = 0; + sym.needFree = false; + } + else + { + sym.file = CopyString( line.FileName ); + sym.line = line.LineNumber; + sym.needFree = true; + } +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_UNLOCK; +#endif + return sym; +} + +CallstackEntryData DecodeCallstackPtr( uint64_t ptr ) +{ + int write; + const auto proc = GetCurrentProcess(); + InitRpmalloc(); + +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_LOCK; +#endif + + const auto moduleName = GetModuleNameAndPrepareSymbols(ptr); + +#if !defined TRACY_NO_CALLSTACK_INLINES + BOOL doInline = FALSE; + DWORD ctx = 0; + DWORD inlineNum = 0; + if( _SymAddrIncludeInlineTrace ) + { + inlineNum = _SymAddrIncludeInlineTrace( proc, ptr ); + if( inlineNum > MaxCbTrace - 1 ) inlineNum = MaxCbTrace - 1; + DWORD idx; + if( inlineNum != 0 ) doInline = _SymQueryInlineTrace( proc, ptr, 0, ptr, ptr, &ctx, &idx ); + } + if( doInline ) + { + write = inlineNum; + cb_num = 1 + inlineNum; + } + else +#endif + { + write = 0; + cb_num = 1; + } + + char buf[sizeof( SYMBOL_INFO ) + MaxNameSize]; + auto si = (SYMBOL_INFO*)buf; + si->SizeOfStruct = sizeof( SYMBOL_INFO ); + si->MaxNameLen = MaxNameSize; + + const auto symValid = SymFromAddr( proc, ptr, nullptr, si ) != 0; + + IMAGEHLP_LINE64 line; + DWORD displacement = 0; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + { + const char* filename; + const auto res = SymGetLineFromAddr64( proc, ptr, &displacement, &line ); + if( res == 0 || line.LineNumber >= 0xF00000 ) + { + filename = "[unknown]"; + cb_data[write].line = 0; + } + else + { + filename = line.FileName; + cb_data[write].line = line.LineNumber; + } + + cb_data[write].name = symValid ? CopyStringFast( si->Name, si->NameLen ) : CopyStringFast( moduleName ); + cb_data[write].file = CopyStringFast( filename ); + if( symValid ) + { + cb_data[write].symLen = si->Size; + cb_data[write].symAddr = si->Address; + } + else + { + cb_data[write].symLen = 0; + cb_data[write].symAddr = 0; + } + } + +#if !defined TRACY_NO_CALLSTACK_INLINES + if( doInline ) + { + for( DWORD i=0; iName, si->NameLen ) : CopyStringFast( moduleName ); + cb.file = CopyStringFast( filename ); + if( symInlineValid ) + { + cb.symLen = si->Size; + cb.symAddr = si->Address; + } + else + { + cb.symLen = 0; + cb.symAddr = 0; + } + + ctx++; + } + } +#endif +#ifdef TRACY_DBGHELP_LOCK + DBGHELP_UNLOCK; +#endif + + return { cb_data, uint8_t( cb_num ), moduleName }; +} + +#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 + +enum { MaxCbTrace = 64 }; + +struct backtrace_state* cb_bts; +int cb_num; +CallstackEntry cb_data[MaxCbTrace]; +int cb_fixup; + +#ifdef TRACY_DEBUGINFOD +debuginfod_client* s_debuginfod; + +struct DebugInfo +{ + uint8_t* buildid; + size_t buildid_size; + char* filename; + int fd; +}; + +FastVector s_di_known( 16 ); +#endif + +#ifdef __linux +struct KernelSymbol +{ + uint64_t addr; + const char* name; + const char* mod; +}; + +KernelSymbol* s_kernelSym = nullptr; +size_t s_kernelSymCnt; + +static void InitKernelSymbols() +{ + FILE* f = fopen( "/proc/kallsyms", "rb" ); + if( !f ) return; + tracy::FastVector tmpSym( 1024 ); + size_t linelen = 16 * 1024; // linelen must be big enough to prevent reallocs in getline() + auto linebuf = (char*)tracy_malloc( linelen ); + ssize_t sz; + while( ( sz = getline( &linebuf, &linelen, f ) ) != -1 ) + { + auto ptr = linebuf; + uint64_t addr = 0; + while( *ptr != ' ' ) + { + auto v = *ptr; + if( v >= '0' && v <= '9' ) + { + v -= '0'; + } + else if( v >= 'a' && v <= 'f' ) + { + v -= 'a'; + v += 10; + } + else if( v >= 'A' && v <= 'F' ) + { + v -= 'A'; + v += 10; + } + else + { + assert( false ); + } + assert( ( v & ~0xF ) == 0 ); + addr <<= 4; + addr |= v; + ptr++; + } + if( addr == 0 ) continue; + ptr++; + if( *ptr != 'T' && *ptr != 't' ) continue; + ptr += 2; + const auto namestart = ptr; + while( *ptr != '\t' && *ptr != '\n' ) ptr++; + const auto nameend = ptr; + const char* modstart = nullptr; + const char* modend; + if( *ptr == '\t' ) + { + ptr += 2; + modstart = ptr; + while( *ptr != ']' ) ptr++; + modend = ptr; + } + + auto strname = (char*)tracy_malloc_fast( nameend - namestart + 1 ); + memcpy( strname, namestart, nameend - namestart ); + strname[nameend-namestart] = '\0'; + + char* strmod = nullptr; + if( modstart ) + { + strmod = (char*)tracy_malloc_fast( modend - modstart + 1 ); + memcpy( strmod, modstart, modend - modstart ); + strmod[modend-modstart] = '\0'; + } + + auto sym = tmpSym.push_next(); + sym->addr = addr; + sym->name = strname; + sym->mod = strmod; + } + tracy_free_fast( linebuf ); + fclose( f ); + if( tmpSym.empty() ) return; + + std::sort( tmpSym.begin(), tmpSym.end(), []( const KernelSymbol& lhs, const KernelSymbol& rhs ) { return lhs.addr > rhs.addr; } ); + s_kernelSymCnt = tmpSym.size(); + s_kernelSym = (KernelSymbol*)tracy_malloc_fast( sizeof( KernelSymbol ) * s_kernelSymCnt ); + memcpy( s_kernelSym, tmpSym.data(), sizeof( KernelSymbol ) * s_kernelSymCnt ); + TracyDebug( "Loaded %zu kernel symbols\n", s_kernelSymCnt ); +} +#endif + +char* NormalizePath( const char* path ) +{ + if( path[0] != '/' ) return nullptr; + + const char* ptr = path; + const char* end = path; + while( *end ) end++; + + char* res = (char*)tracy_malloc( end - ptr + 1 ); + size_t rsz = 0; + + while( ptr < end ) + { + const char* next = ptr; + while( next < end && *next != '/' ) next++; + size_t lsz = next - ptr; + switch( lsz ) + { + case 2: + if( memcmp( ptr, "..", 2 ) == 0 ) + { + const char* back = res + rsz - 1; + while( back > res && *back != '/' ) back--; + rsz = back - res; + ptr = next + 1; + continue; + } + break; + case 1: + if( *ptr == '.' ) + { + ptr = next + 1; + continue; + } + break; + case 0: + ptr = next + 1; + continue; + } + if( rsz != 1 ) res[rsz++] = '/'; + memcpy( res+rsz, ptr, lsz ); + rsz += lsz; + ptr = next + 1; + } + + if( rsz == 0 ) + { + memcpy( res, "/", 2 ); + } + else + { + res[rsz] = '\0'; + } + return res; +} + +void InitCallstackCritical() +{ +} + +void InitCallstack() +{ + cb_bts = backtrace_create_state( nullptr, 0, nullptr, nullptr ); +#ifndef TRACY_DEMANGLE + ___tracy_init_demangle_buffer(); +#endif + +#ifdef __linux + InitKernelSymbols(); +#endif +#ifdef TRACY_DEBUGINFOD + s_debuginfod = debuginfod_begin(); +#endif +} + +#ifdef TRACY_DEBUGINFOD +void ClearDebugInfoVector( FastVector& vec ) +{ + for( auto& v : vec ) + { + tracy_free( v.buildid ); + tracy_free( v.filename ); + if( v.fd >= 0 ) close( v.fd ); + } + vec.clear(); +} + +DebugInfo* FindDebugInfo( FastVector& vec, const uint8_t* buildid_data, size_t buildid_size ) +{ + for( auto& v : vec ) + { + if( v.buildid_size == buildid_size && memcmp( v.buildid, buildid_data, buildid_size ) == 0 ) + { + return &v; + } + } + return nullptr; +} + +int GetDebugInfoDescriptor( const char* buildid_data, size_t buildid_size, const char* filename ) +{ + auto buildid = (uint8_t*)buildid_data; + auto it = FindDebugInfo( s_di_known, buildid, buildid_size ); + if( it ) return it->fd >= 0 ? dup( it->fd ) : -1; + + int fd = debuginfod_find_debuginfo( s_debuginfod, buildid, buildid_size, nullptr ); + it = s_di_known.push_next(); + it->buildid_size = buildid_size; + it->buildid = (uint8_t*)tracy_malloc( buildid_size ); + memcpy( it->buildid, buildid, buildid_size ); + const auto fnsz = strlen( filename ) + 1; + it->filename = (char*)tracy_malloc( fnsz ); + memcpy( it->filename, filename, fnsz ); + it->fd = fd >= 0 ? fd : -1; + TracyDebug( "DebugInfo descriptor query: %i, fn: %s\n", fd, filename ); + return it->fd; +} + +const uint8_t* GetBuildIdForImage( const char* image, size_t& size ) +{ + assert( image ); + for( auto& v : s_di_known ) + { + if( strcmp( image, v.filename ) == 0 ) + { + size = v.buildid_size; + return v.buildid; + } + } + return nullptr; +} + +debuginfod_client* GetDebuginfodClient() +{ + return s_debuginfod; +} +#endif + +void EndCallstack() +{ +#ifndef TRACY_DEMANGLE + ___tracy_free_demangle_buffer(); +#endif +#ifdef TRACY_DEBUGINFOD + ClearDebugInfoVector( s_di_known ); + debuginfod_end( s_debuginfod ); +#endif +} + +const char* DecodeCallstackPtrFast( uint64_t ptr ) +{ + static char ret[1024]; + auto vptr = (void*)ptr; + const char* symname = nullptr; + Dl_info dlinfo; + if( dladdr( vptr, &dlinfo ) && dlinfo.dli_sname ) + { + symname = dlinfo.dli_sname; + } + if( symname ) + { + strcpy( ret, symname ); + } + else + { + *ret = '\0'; + } + return ret; +} + +static int SymbolAddressDataCb( void* data, uintptr_t pc, uintptr_t lowaddr, const char* fn, int lineno, const char* function ) +{ + auto& sym = *(CallstackSymbolData*)data; + if( !fn ) + { + sym.file = "[unknown]"; + sym.line = 0; + sym.needFree = false; + } + else + { + sym.file = NormalizePath( fn ); + if( !sym.file ) sym.file = CopyString( fn ); + sym.line = lineno; + sym.needFree = true; + } + + return 1; +} + +static void SymbolAddressErrorCb( void* data, const char* /*msg*/, int /*errnum*/ ) +{ + auto& sym = *(CallstackSymbolData*)data; + sym.file = "[unknown]"; + sym.line = 0; + sym.needFree = false; +} + +CallstackSymbolData DecodeSymbolAddress( uint64_t ptr ) +{ + CallstackSymbolData sym; + backtrace_pcinfo( cb_bts, ptr, SymbolAddressDataCb, SymbolAddressErrorCb, &sym ); + return sym; +} + +static int CallstackDataCb( void* /*data*/, uintptr_t pc, uintptr_t lowaddr, const char* fn, int lineno, const char* function ) +{ + cb_data[cb_num].symLen = 0; + cb_data[cb_num].symAddr = (uint64_t)lowaddr; + + if( !fn && !function ) + { + const char* symname = nullptr; + auto vptr = (void*)pc; + ptrdiff_t symoff = 0; + + Dl_info dlinfo; + if( dladdr( vptr, &dlinfo ) ) + { + symname = dlinfo.dli_sname; + symoff = (char*)pc - (char*)dlinfo.dli_saddr; + const char* demangled = ___tracy_demangle( symname ); + if( demangled ) symname = demangled; + } + + if( !symname ) symname = "[unknown]"; + + if( symoff == 0 ) + { + const auto len = std::min( strlen( symname ), std::numeric_limits::max() ); + cb_data[cb_num].name = CopyStringFast( symname, len ); + } + else + { + char buf[32]; + const auto offlen = sprintf( buf, " + %td", symoff ); + const auto namelen = std::min( strlen( symname ), std::numeric_limits::max() - offlen ); + auto name = (char*)tracy_malloc_fast( namelen + offlen + 1 ); + memcpy( name, symname, namelen ); + memcpy( name + namelen, buf, offlen ); + name[namelen + offlen] = '\0'; + cb_data[cb_num].name = name; + } + + cb_data[cb_num].file = CopyStringFast( "[unknown]" ); + cb_data[cb_num].line = 0; + } + else + { + if( !fn ) fn = "[unknown]"; + if( !function ) + { + function = "[unknown]"; + } + else + { + const char* demangled = ___tracy_demangle( function ); + if( demangled ) function = demangled; + } + + const auto len = std::min( strlen( function ), std::numeric_limits::max() ); + cb_data[cb_num].name = CopyStringFast( function, len ); + cb_data[cb_num].file = NormalizePath( fn ); + if( !cb_data[cb_num].file ) cb_data[cb_num].file = CopyStringFast( fn ); + cb_data[cb_num].line = lineno; + } + + if( ++cb_num >= MaxCbTrace ) + { + return 1; + } + else + { + return 0; + } +} + +static void CallstackErrorCb( void* /*data*/, const char* /*msg*/, int /*errnum*/ ) +{ + for( int i=0; i> 63 == 0 ) + { + cb_num = 0; + backtrace_pcinfo( cb_bts, ptr, CallstackDataCb, CallstackErrorCb, nullptr ); + assert( cb_num > 0 ); + + backtrace_syminfo( cb_bts, ptr, SymInfoCallback, SymInfoError, nullptr ); + + const char* symloc = nullptr; + Dl_info dlinfo; + if( dladdr( (void*)ptr, &dlinfo ) ) symloc = dlinfo.dli_fname; + + return { cb_data, uint8_t( cb_num ), symloc ? symloc : "[unknown]" }; + } +#ifdef __linux + else if( s_kernelSym ) + { + auto it = std::lower_bound( s_kernelSym, s_kernelSym + s_kernelSymCnt, ptr, []( const KernelSymbol& lhs, const uint64_t& rhs ) { return lhs.addr > rhs; } ); + if( it != s_kernelSym + s_kernelSymCnt ) + { + cb_data[0].name = CopyStringFast( it->name ); + cb_data[0].file = CopyStringFast( "" ); + cb_data[0].line = 0; + cb_data[0].symLen = 0; + cb_data[0].symAddr = it->addr; + return { cb_data, 1, it->mod ? it->mod : "" }; + } + } +#endif + + cb_data[0].name = CopyStringFast( "[unknown]" ); + cb_data[0].file = CopyStringFast( "" ); + cb_data[0].line = 0; + cb_data[0].symLen = 0; + cb_data[0].symAddr = 0; + return { cb_data, 1, "" }; +} + +#elif TRACY_HAS_CALLSTACK == 5 + +void InitCallstackCritical() +{ +} + +void InitCallstack() +{ + ___tracy_init_demangle_buffer(); +} + +void EndCallstack() +{ + ___tracy_free_demangle_buffer(); +} + +const char* DecodeCallstackPtrFast( uint64_t ptr ) +{ + static char ret[1024]; + auto vptr = (void*)ptr; + const char* symname = nullptr; + Dl_info dlinfo; + if( dladdr( vptr, &dlinfo ) && dlinfo.dli_sname ) + { + symname = dlinfo.dli_sname; + } + if( symname ) + { + strcpy( ret, symname ); + } + else + { + *ret = '\0'; + } + return ret; +} + +CallstackSymbolData DecodeSymbolAddress( uint64_t ptr ) +{ + const char* symloc = nullptr; + Dl_info dlinfo; + if( dladdr( (void*)ptr, &dlinfo ) ) symloc = dlinfo.dli_fname; + if( !symloc ) symloc = "[unknown]"; + return CallstackSymbolData { symloc, 0, false, 0 }; +} + +CallstackEntryData DecodeCallstackPtr( uint64_t ptr ) +{ + static CallstackEntry cb; + cb.line = 0; + + const char* symname = nullptr; + const char* symloc = nullptr; + auto vptr = (void*)ptr; + ptrdiff_t symoff = 0; + void* symaddr = nullptr; + + Dl_info dlinfo; + if( dladdr( vptr, &dlinfo ) ) + { + symloc = dlinfo.dli_fname; + symname = dlinfo.dli_sname; + symoff = (char*)ptr - (char*)dlinfo.dli_saddr; + symaddr = dlinfo.dli_saddr; + const char* demangled = ___tracy_demangle( symname ); + if( demangled ) symname = demangled; + } + + if( !symname ) symname = "[unknown]"; + if( !symloc ) symloc = "[unknown]"; + + if( symoff == 0 ) + { + const auto len = std::min( strlen( symname ), std::numeric_limits::max() ); + cb.name = CopyString( symname, len ); + } + else + { + char buf[32]; + const auto offlen = sprintf( buf, " + %td", symoff ); + const auto namelen = std::min( strlen( symname ), std::numeric_limits::max() - offlen ); + auto name = (char*)tracy_malloc( namelen + offlen + 1 ); + memcpy( name, symname, namelen ); + memcpy( name + namelen, buf, offlen ); + name[namelen + offlen] = '\0'; + cb.name = name; + } + + cb.file = CopyString( "[unknown]" ); + cb.symLen = 0; + cb.symAddr = (uint64_t)symaddr; + + return { &cb, 1, symloc }; +} + +#endif + +} + +#endif diff --git a/Externals/tracy/public/client/TracyCallstack.h b/Externals/tracy/public/client/TracyCallstack.h new file mode 100644 index 00000000000..2c7ecad9f34 --- /dev/null +++ b/Externals/tracy/public/client/TracyCallstack.h @@ -0,0 +1,35 @@ +#ifndef __TRACYCALLSTACK_H__ +#define __TRACYCALLSTACK_H__ + +#ifndef TRACY_NO_CALLSTACK + +# if !defined _WIN32 +# include +# endif + +# if defined _WIN32 +# include "../common/TracyUwp.hpp" +# ifndef TRACY_UWP +# define TRACY_HAS_CALLSTACK 1 +# endif +# elif defined __ANDROID__ +# if !defined __arm__ || __ANDROID_API__ >= 21 +# define TRACY_HAS_CALLSTACK 2 +# else +# define TRACY_HAS_CALLSTACK 5 +# endif +# elif defined __linux +# if defined _GNU_SOURCE && defined __GLIBC__ +# define TRACY_HAS_CALLSTACK 3 +# else +# define TRACY_HAS_CALLSTACK 2 +# endif +# elif defined __APPLE__ +# define TRACY_HAS_CALLSTACK 4 +# elif defined BSD +# define TRACY_HAS_CALLSTACK 6 +# endif + +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyCallstack.hpp b/Externals/tracy/public/client/TracyCallstack.hpp new file mode 100644 index 00000000000..0b522b730c6 --- /dev/null +++ b/Externals/tracy/public/client/TracyCallstack.hpp @@ -0,0 +1,142 @@ +#ifndef __TRACYCALLSTACK_HPP__ +#define __TRACYCALLSTACK_HPP__ + +#include "../common/TracyApi.h" +#include "../common/TracyForceInline.hpp" +#include "TracyCallstack.h" + +#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5 +# include +#elif TRACY_HAS_CALLSTACK >= 3 +# include +#endif + + +#ifndef TRACY_HAS_CALLSTACK + +namespace tracy +{ +static tracy_force_inline void* Callstack( int depth ) { return nullptr; } +} + +#else + +#ifdef TRACY_DEBUGINFOD +# include +#endif + +#include +#include + +#include "../common/TracyAlloc.hpp" + +namespace tracy +{ + +struct CallstackSymbolData +{ + const char* file; + uint32_t line; + bool needFree; + uint64_t symAddr; +}; + +struct CallstackEntry +{ + const char* name; + const char* file; + uint32_t line; + uint32_t symLen; + uint64_t symAddr; +}; + +struct CallstackEntryData +{ + const CallstackEntry* data; + uint8_t size; + const char* imageName; +}; + +CallstackSymbolData DecodeSymbolAddress( uint64_t ptr ); +const char* DecodeCallstackPtrFast( uint64_t ptr ); +CallstackEntryData DecodeCallstackPtr( uint64_t ptr ); +void InitCallstack(); +void InitCallstackCritical(); +void EndCallstack(); +const char* GetKernelModulePath( uint64_t addr ); + +#ifdef TRACY_DEBUGINFOD +const uint8_t* GetBuildIdForImage( const char* image, size_t& size ); +debuginfod_client* GetDebuginfodClient(); +#endif + +#if TRACY_HAS_CALLSTACK == 1 + +extern "C" +{ + typedef unsigned long (__stdcall *___tracy_t_RtlWalkFrameChain)( void**, unsigned long, unsigned long ); + TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain; +} + +static tracy_force_inline void* Callstack( int depth ) +{ + assert( depth >= 1 && depth < 63 ); + auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) ); + const auto num = ___tracy_RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 ); + *trace = num; + return trace; +} + +#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5 + +struct BacktraceState +{ + void** current; + void** end; +}; + +static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg ) +{ + auto state = (BacktraceState*)arg; + uintptr_t pc = _Unwind_GetIP( ctx ); + if( pc ) + { + if( state->current == state->end ) return _URC_END_OF_STACK; + *state->current++ = (void*)pc; + } + return _URC_NO_REASON; +} + +static tracy_force_inline void* Callstack( int depth ) +{ + assert( depth >= 1 && depth < 63 ); + + auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) ); + BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) }; + _Unwind_Backtrace( tracy_unwind_callback, &state ); + + *trace = (uintptr_t*)state.current - trace + 1; + + return trace; +} + +#elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 + +static tracy_force_inline void* Callstack( int depth ) +{ + assert( depth >= 1 ); + + auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) ); + const auto num = (size_t)backtrace( (void**)(trace+1), depth ); + *trace = num; + + return trace; +} + +#endif + +} + +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyCpuid.hpp b/Externals/tracy/public/client/TracyCpuid.hpp new file mode 100644 index 00000000000..9820be00bb3 --- /dev/null +++ b/Externals/tracy/public/client/TracyCpuid.hpp @@ -0,0 +1,12 @@ +#ifndef __TRACYCPUID_HPP__ +#define __TRACYCPUID_HPP__ + +// Prior to GCC 11 the cpuid.h header did not have any include guards and thus +// including it more than once would cause a compiler error due to symbol +// redefinitions. In order to support older GCC versions, we have to wrap this +// include between custom include guards to prevent this issue. +// See also https://github.com/wolfpld/tracy/issues/452 + +#include + +#endif diff --git a/Externals/tracy/public/client/TracyDebug.hpp b/Externals/tracy/public/client/TracyDebug.hpp new file mode 100644 index 00000000000..8723356f49b --- /dev/null +++ b/Externals/tracy/public/client/TracyDebug.hpp @@ -0,0 +1,11 @@ +#ifndef __TRACYPRINT_HPP__ +#define __TRACYPRINT_HPP__ + +#ifdef TRACY_VERBOSE +# include +# define TracyDebug(...) fprintf( stderr, __VA_ARGS__ ); +#else +# define TracyDebug(...) +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyDxt1.cpp b/Externals/tracy/public/client/TracyDxt1.cpp new file mode 100644 index 00000000000..930d098207d --- /dev/null +++ b/Externals/tracy/public/client/TracyDxt1.cpp @@ -0,0 +1,644 @@ +#include "TracyDxt1.hpp" +#include "../common/TracyForceInline.hpp" + +#include +#include +#include + +#ifdef __ARM_NEON +# include +#endif + +#if defined __AVX__ && !defined __SSE4_1__ +# define __SSE4_1__ +#endif + +#if defined __SSE4_1__ || defined __AVX2__ +# ifdef _MSC_VER +# include +# else +# include +# ifndef _mm256_cvtsi256_si32 +# define _mm256_cvtsi256_si32( v ) ( _mm_cvtsi128_si32( _mm256_castsi256_si128( v ) ) ) +# endif +# endif +#endif + +namespace tracy +{ + +static inline uint16_t to565( uint8_t r, uint8_t g, uint8_t b ) +{ + return ( ( r & 0xF8 ) << 8 ) | ( ( g & 0xFC ) << 3 ) | ( b >> 3 ); +} + +static inline uint16_t to565( uint32_t c ) +{ + return + ( ( c & 0xF80000 ) >> 19 ) | + ( ( c & 0x00FC00 ) >> 5 ) | + ( ( c & 0x0000F8 ) << 8 ); +} + +static const uint16_t DivTable[255*3+1] = { + 0xffff, 0xffff, 0xffff, 0xffff, 0xcccc, 0xaaaa, 0x9249, 0x8000, 0x71c7, 0x6666, 0x5d17, 0x5555, 0x4ec4, 0x4924, 0x4444, 0x4000, + 0x3c3c, 0x38e3, 0x35e5, 0x3333, 0x30c3, 0x2e8b, 0x2c85, 0x2aaa, 0x28f5, 0x2762, 0x25ed, 0x2492, 0x234f, 0x2222, 0x2108, 0x2000, + 0x1f07, 0x1e1e, 0x1d41, 0x1c71, 0x1bac, 0x1af2, 0x1a41, 0x1999, 0x18f9, 0x1861, 0x17d0, 0x1745, 0x16c1, 0x1642, 0x15c9, 0x1555, + 0x14e5, 0x147a, 0x1414, 0x13b1, 0x1352, 0x12f6, 0x129e, 0x1249, 0x11f7, 0x11a7, 0x115b, 0x1111, 0x10c9, 0x1084, 0x1041, 0x1000, + 0x0fc0, 0x0f83, 0x0f48, 0x0f0f, 0x0ed7, 0x0ea0, 0x0e6c, 0x0e38, 0x0e07, 0x0dd6, 0x0da7, 0x0d79, 0x0d4c, 0x0d20, 0x0cf6, 0x0ccc, + 0x0ca4, 0x0c7c, 0x0c56, 0x0c30, 0x0c0c, 0x0be8, 0x0bc5, 0x0ba2, 0x0b81, 0x0b60, 0x0b40, 0x0b21, 0x0b02, 0x0ae4, 0x0ac7, 0x0aaa, + 0x0a8e, 0x0a72, 0x0a57, 0x0a3d, 0x0a23, 0x0a0a, 0x09f1, 0x09d8, 0x09c0, 0x09a9, 0x0991, 0x097b, 0x0964, 0x094f, 0x0939, 0x0924, + 0x090f, 0x08fb, 0x08e7, 0x08d3, 0x08c0, 0x08ad, 0x089a, 0x0888, 0x0876, 0x0864, 0x0853, 0x0842, 0x0831, 0x0820, 0x0810, 0x0800, + 0x07f0, 0x07e0, 0x07d1, 0x07c1, 0x07b3, 0x07a4, 0x0795, 0x0787, 0x0779, 0x076b, 0x075d, 0x0750, 0x0743, 0x0736, 0x0729, 0x071c, + 0x070f, 0x0703, 0x06f7, 0x06eb, 0x06df, 0x06d3, 0x06c8, 0x06bc, 0x06b1, 0x06a6, 0x069b, 0x0690, 0x0685, 0x067b, 0x0670, 0x0666, + 0x065c, 0x0652, 0x0648, 0x063e, 0x0634, 0x062b, 0x0621, 0x0618, 0x060f, 0x0606, 0x05fd, 0x05f4, 0x05eb, 0x05e2, 0x05d9, 0x05d1, + 0x05c9, 0x05c0, 0x05b8, 0x05b0, 0x05a8, 0x05a0, 0x0598, 0x0590, 0x0588, 0x0581, 0x0579, 0x0572, 0x056b, 0x0563, 0x055c, 0x0555, + 0x054e, 0x0547, 0x0540, 0x0539, 0x0532, 0x052b, 0x0525, 0x051e, 0x0518, 0x0511, 0x050b, 0x0505, 0x04fe, 0x04f8, 0x04f2, 0x04ec, + 0x04e6, 0x04e0, 0x04da, 0x04d4, 0x04ce, 0x04c8, 0x04c3, 0x04bd, 0x04b8, 0x04b2, 0x04ad, 0x04a7, 0x04a2, 0x049c, 0x0497, 0x0492, + 0x048d, 0x0487, 0x0482, 0x047d, 0x0478, 0x0473, 0x046e, 0x0469, 0x0465, 0x0460, 0x045b, 0x0456, 0x0452, 0x044d, 0x0448, 0x0444, + 0x043f, 0x043b, 0x0436, 0x0432, 0x042d, 0x0429, 0x0425, 0x0421, 0x041c, 0x0418, 0x0414, 0x0410, 0x040c, 0x0408, 0x0404, 0x0400, + 0x03fc, 0x03f8, 0x03f4, 0x03f0, 0x03ec, 0x03e8, 0x03e4, 0x03e0, 0x03dd, 0x03d9, 0x03d5, 0x03d2, 0x03ce, 0x03ca, 0x03c7, 0x03c3, + 0x03c0, 0x03bc, 0x03b9, 0x03b5, 0x03b2, 0x03ae, 0x03ab, 0x03a8, 0x03a4, 0x03a1, 0x039e, 0x039b, 0x0397, 0x0394, 0x0391, 0x038e, + 0x038b, 0x0387, 0x0384, 0x0381, 0x037e, 0x037b, 0x0378, 0x0375, 0x0372, 0x036f, 0x036c, 0x0369, 0x0366, 0x0364, 0x0361, 0x035e, + 0x035b, 0x0358, 0x0355, 0x0353, 0x0350, 0x034d, 0x034a, 0x0348, 0x0345, 0x0342, 0x0340, 0x033d, 0x033a, 0x0338, 0x0335, 0x0333, + 0x0330, 0x032e, 0x032b, 0x0329, 0x0326, 0x0324, 0x0321, 0x031f, 0x031c, 0x031a, 0x0317, 0x0315, 0x0313, 0x0310, 0x030e, 0x030c, + 0x0309, 0x0307, 0x0305, 0x0303, 0x0300, 0x02fe, 0x02fc, 0x02fa, 0x02f7, 0x02f5, 0x02f3, 0x02f1, 0x02ef, 0x02ec, 0x02ea, 0x02e8, + 0x02e6, 0x02e4, 0x02e2, 0x02e0, 0x02de, 0x02dc, 0x02da, 0x02d8, 0x02d6, 0x02d4, 0x02d2, 0x02d0, 0x02ce, 0x02cc, 0x02ca, 0x02c8, + 0x02c6, 0x02c4, 0x02c2, 0x02c0, 0x02be, 0x02bc, 0x02bb, 0x02b9, 0x02b7, 0x02b5, 0x02b3, 0x02b1, 0x02b0, 0x02ae, 0x02ac, 0x02aa, + 0x02a8, 0x02a7, 0x02a5, 0x02a3, 0x02a1, 0x02a0, 0x029e, 0x029c, 0x029b, 0x0299, 0x0297, 0x0295, 0x0294, 0x0292, 0x0291, 0x028f, + 0x028d, 0x028c, 0x028a, 0x0288, 0x0287, 0x0285, 0x0284, 0x0282, 0x0280, 0x027f, 0x027d, 0x027c, 0x027a, 0x0279, 0x0277, 0x0276, + 0x0274, 0x0273, 0x0271, 0x0270, 0x026e, 0x026d, 0x026b, 0x026a, 0x0268, 0x0267, 0x0265, 0x0264, 0x0263, 0x0261, 0x0260, 0x025e, + 0x025d, 0x025c, 0x025a, 0x0259, 0x0257, 0x0256, 0x0255, 0x0253, 0x0252, 0x0251, 0x024f, 0x024e, 0x024d, 0x024b, 0x024a, 0x0249, + 0x0247, 0x0246, 0x0245, 0x0243, 0x0242, 0x0241, 0x0240, 0x023e, 0x023d, 0x023c, 0x023b, 0x0239, 0x0238, 0x0237, 0x0236, 0x0234, + 0x0233, 0x0232, 0x0231, 0x0230, 0x022e, 0x022d, 0x022c, 0x022b, 0x022a, 0x0229, 0x0227, 0x0226, 0x0225, 0x0224, 0x0223, 0x0222, + 0x0220, 0x021f, 0x021e, 0x021d, 0x021c, 0x021b, 0x021a, 0x0219, 0x0218, 0x0216, 0x0215, 0x0214, 0x0213, 0x0212, 0x0211, 0x0210, + 0x020f, 0x020e, 0x020d, 0x020c, 0x020b, 0x020a, 0x0209, 0x0208, 0x0207, 0x0206, 0x0205, 0x0204, 0x0203, 0x0202, 0x0201, 0x0200, + 0x01ff, 0x01fe, 0x01fd, 0x01fc, 0x01fb, 0x01fa, 0x01f9, 0x01f8, 0x01f7, 0x01f6, 0x01f5, 0x01f4, 0x01f3, 0x01f2, 0x01f1, 0x01f0, + 0x01ef, 0x01ee, 0x01ed, 0x01ec, 0x01eb, 0x01ea, 0x01e9, 0x01e9, 0x01e8, 0x01e7, 0x01e6, 0x01e5, 0x01e4, 0x01e3, 0x01e2, 0x01e1, + 0x01e0, 0x01e0, 0x01df, 0x01de, 0x01dd, 0x01dc, 0x01db, 0x01da, 0x01da, 0x01d9, 0x01d8, 0x01d7, 0x01d6, 0x01d5, 0x01d4, 0x01d4, + 0x01d3, 0x01d2, 0x01d1, 0x01d0, 0x01cf, 0x01cf, 0x01ce, 0x01cd, 0x01cc, 0x01cb, 0x01cb, 0x01ca, 0x01c9, 0x01c8, 0x01c7, 0x01c7, + 0x01c6, 0x01c5, 0x01c4, 0x01c3, 0x01c3, 0x01c2, 0x01c1, 0x01c0, 0x01c0, 0x01bf, 0x01be, 0x01bd, 0x01bd, 0x01bc, 0x01bb, 0x01ba, + 0x01ba, 0x01b9, 0x01b8, 0x01b7, 0x01b7, 0x01b6, 0x01b5, 0x01b4, 0x01b4, 0x01b3, 0x01b2, 0x01b2, 0x01b1, 0x01b0, 0x01af, 0x01af, + 0x01ae, 0x01ad, 0x01ad, 0x01ac, 0x01ab, 0x01aa, 0x01aa, 0x01a9, 0x01a8, 0x01a8, 0x01a7, 0x01a6, 0x01a6, 0x01a5, 0x01a4, 0x01a4, + 0x01a3, 0x01a2, 0x01a2, 0x01a1, 0x01a0, 0x01a0, 0x019f, 0x019e, 0x019e, 0x019d, 0x019c, 0x019c, 0x019b, 0x019a, 0x019a, 0x0199, + 0x0198, 0x0198, 0x0197, 0x0197, 0x0196, 0x0195, 0x0195, 0x0194, 0x0193, 0x0193, 0x0192, 0x0192, 0x0191, 0x0190, 0x0190, 0x018f, + 0x018f, 0x018e, 0x018d, 0x018d, 0x018c, 0x018b, 0x018b, 0x018a, 0x018a, 0x0189, 0x0189, 0x0188, 0x0187, 0x0187, 0x0186, 0x0186, + 0x0185, 0x0184, 0x0184, 0x0183, 0x0183, 0x0182, 0x0182, 0x0181, 0x0180, 0x0180, 0x017f, 0x017f, 0x017e, 0x017e, 0x017d, 0x017d, + 0x017c, 0x017b, 0x017b, 0x017a, 0x017a, 0x0179, 0x0179, 0x0178, 0x0178, 0x0177, 0x0177, 0x0176, 0x0175, 0x0175, 0x0174, 0x0174, + 0x0173, 0x0173, 0x0172, 0x0172, 0x0171, 0x0171, 0x0170, 0x0170, 0x016f, 0x016f, 0x016e, 0x016e, 0x016d, 0x016d, 0x016c, 0x016c, + 0x016b, 0x016b, 0x016a, 0x016a, 0x0169, 0x0169, 0x0168, 0x0168, 0x0167, 0x0167, 0x0166, 0x0166, 0x0165, 0x0165, 0x0164, 0x0164, + 0x0163, 0x0163, 0x0162, 0x0162, 0x0161, 0x0161, 0x0160, 0x0160, 0x015f, 0x015f, 0x015e, 0x015e, 0x015d, 0x015d, 0x015d, 0x015c, + 0x015c, 0x015b, 0x015b, 0x015a, 0x015a, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0157, 0x0157, 0x0156, 0x0156 +}; + +#if defined __ARM_NEON && defined __aarch64__ +static const uint16_t DivTableNEON[255*3+1] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1c71, 0x1af2, 0x1999, 0x1861, 0x1745, 0x1642, 0x1555, 0x147a, 0x13b1, 0x12f6, 0x1249, 0x11a7, 0x1111, 0x1084, 0x1000, + 0x0f83, 0x0f0f, 0x0ea0, 0x0e38, 0x0dd6, 0x0d79, 0x0d20, 0x0ccc, 0x0c7c, 0x0c30, 0x0be8, 0x0ba2, 0x0b60, 0x0b21, 0x0ae4, 0x0aaa, + 0x0a72, 0x0a3d, 0x0a0a, 0x09d8, 0x09a9, 0x097b, 0x094f, 0x0924, 0x08fb, 0x08d3, 0x08ad, 0x0888, 0x0864, 0x0842, 0x0820, 0x0800, + 0x07e0, 0x07c1, 0x07a4, 0x0787, 0x076b, 0x0750, 0x0736, 0x071c, 0x0703, 0x06eb, 0x06d3, 0x06bc, 0x06a6, 0x0690, 0x067b, 0x0666, + 0x0652, 0x063e, 0x062b, 0x0618, 0x0606, 0x05f4, 0x05e2, 0x05d1, 0x05c0, 0x05b0, 0x05a0, 0x0590, 0x0581, 0x0572, 0x0563, 0x0555, + 0x0547, 0x0539, 0x052b, 0x051e, 0x0511, 0x0505, 0x04f8, 0x04ec, 0x04e0, 0x04d4, 0x04c8, 0x04bd, 0x04b2, 0x04a7, 0x049c, 0x0492, + 0x0487, 0x047d, 0x0473, 0x0469, 0x0460, 0x0456, 0x044d, 0x0444, 0x043b, 0x0432, 0x0429, 0x0421, 0x0418, 0x0410, 0x0408, 0x0400, + 0x03f8, 0x03f0, 0x03e8, 0x03e0, 0x03d9, 0x03d2, 0x03ca, 0x03c3, 0x03bc, 0x03b5, 0x03ae, 0x03a8, 0x03a1, 0x039b, 0x0394, 0x038e, + 0x0387, 0x0381, 0x037b, 0x0375, 0x036f, 0x0369, 0x0364, 0x035e, 0x0358, 0x0353, 0x034d, 0x0348, 0x0342, 0x033d, 0x0338, 0x0333, + 0x032e, 0x0329, 0x0324, 0x031f, 0x031a, 0x0315, 0x0310, 0x030c, 0x0307, 0x0303, 0x02fe, 0x02fa, 0x02f5, 0x02f1, 0x02ec, 0x02e8, + 0x02e4, 0x02e0, 0x02dc, 0x02d8, 0x02d4, 0x02d0, 0x02cc, 0x02c8, 0x02c4, 0x02c0, 0x02bc, 0x02b9, 0x02b5, 0x02b1, 0x02ae, 0x02aa, + 0x02a7, 0x02a3, 0x02a0, 0x029c, 0x0299, 0x0295, 0x0292, 0x028f, 0x028c, 0x0288, 0x0285, 0x0282, 0x027f, 0x027c, 0x0279, 0x0276, + 0x0273, 0x0270, 0x026d, 0x026a, 0x0267, 0x0264, 0x0261, 0x025e, 0x025c, 0x0259, 0x0256, 0x0253, 0x0251, 0x024e, 0x024b, 0x0249, + 0x0246, 0x0243, 0x0241, 0x023e, 0x023c, 0x0239, 0x0237, 0x0234, 0x0232, 0x0230, 0x022d, 0x022b, 0x0229, 0x0226, 0x0224, 0x0222, + 0x021f, 0x021d, 0x021b, 0x0219, 0x0216, 0x0214, 0x0212, 0x0210, 0x020e, 0x020c, 0x020a, 0x0208, 0x0206, 0x0204, 0x0202, 0x0200, + 0x01fe, 0x01fc, 0x01fa, 0x01f8, 0x01f6, 0x01f4, 0x01f2, 0x01f0, 0x01ee, 0x01ec, 0x01ea, 0x01e9, 0x01e7, 0x01e5, 0x01e3, 0x01e1, + 0x01e0, 0x01de, 0x01dc, 0x01da, 0x01d9, 0x01d7, 0x01d5, 0x01d4, 0x01d2, 0x01d0, 0x01cf, 0x01cd, 0x01cb, 0x01ca, 0x01c8, 0x01c7, + 0x01c5, 0x01c3, 0x01c2, 0x01c0, 0x01bf, 0x01bd, 0x01bc, 0x01ba, 0x01b9, 0x01b7, 0x01b6, 0x01b4, 0x01b3, 0x01b2, 0x01b0, 0x01af, + 0x01ad, 0x01ac, 0x01aa, 0x01a9, 0x01a8, 0x01a6, 0x01a5, 0x01a4, 0x01a2, 0x01a1, 0x01a0, 0x019e, 0x019d, 0x019c, 0x019a, 0x0199, + 0x0198, 0x0197, 0x0195, 0x0194, 0x0193, 0x0192, 0x0190, 0x018f, 0x018e, 0x018d, 0x018b, 0x018a, 0x0189, 0x0188, 0x0187, 0x0186, + 0x0184, 0x0183, 0x0182, 0x0181, 0x0180, 0x017f, 0x017e, 0x017d, 0x017b, 0x017a, 0x0179, 0x0178, 0x0177, 0x0176, 0x0175, 0x0174, + 0x0173, 0x0172, 0x0171, 0x0170, 0x016f, 0x016e, 0x016d, 0x016c, 0x016b, 0x016a, 0x0169, 0x0168, 0x0167, 0x0166, 0x0165, 0x0164, + 0x0163, 0x0162, 0x0161, 0x0160, 0x015f, 0x015e, 0x015d, 0x015c, 0x015b, 0x015a, 0x0159, 0x0158, 0x0158, 0x0157, 0x0156, 0x0155, + 0x0154, 0x0153, 0x0152, 0x0151, 0x0150, 0x0150, 0x014f, 0x014e, 0x014d, 0x014c, 0x014b, 0x014a, 0x014a, 0x0149, 0x0148, 0x0147, + 0x0146, 0x0146, 0x0145, 0x0144, 0x0143, 0x0142, 0x0142, 0x0141, 0x0140, 0x013f, 0x013e, 0x013e, 0x013d, 0x013c, 0x013b, 0x013b, + 0x013a, 0x0139, 0x0138, 0x0138, 0x0137, 0x0136, 0x0135, 0x0135, 0x0134, 0x0133, 0x0132, 0x0132, 0x0131, 0x0130, 0x0130, 0x012f, + 0x012e, 0x012e, 0x012d, 0x012c, 0x012b, 0x012b, 0x012a, 0x0129, 0x0129, 0x0128, 0x0127, 0x0127, 0x0126, 0x0125, 0x0125, 0x0124, + 0x0123, 0x0123, 0x0122, 0x0121, 0x0121, 0x0120, 0x0120, 0x011f, 0x011e, 0x011e, 0x011d, 0x011c, 0x011c, 0x011b, 0x011b, 0x011a, + 0x0119, 0x0119, 0x0118, 0x0118, 0x0117, 0x0116, 0x0116, 0x0115, 0x0115, 0x0114, 0x0113, 0x0113, 0x0112, 0x0112, 0x0111, 0x0111, + 0x0110, 0x010f, 0x010f, 0x010e, 0x010e, 0x010d, 0x010d, 0x010c, 0x010c, 0x010b, 0x010a, 0x010a, 0x0109, 0x0109, 0x0108, 0x0108, + 0x0107, 0x0107, 0x0106, 0x0106, 0x0105, 0x0105, 0x0104, 0x0104, 0x0103, 0x0103, 0x0102, 0x0102, 0x0101, 0x0101, 0x0100, 0x0100, + 0x00ff, 0x00ff, 0x00fe, 0x00fe, 0x00fd, 0x00fd, 0x00fc, 0x00fc, 0x00fb, 0x00fb, 0x00fa, 0x00fa, 0x00f9, 0x00f9, 0x00f8, 0x00f8, + 0x00f7, 0x00f7, 0x00f6, 0x00f6, 0x00f5, 0x00f5, 0x00f4, 0x00f4, 0x00f4, 0x00f3, 0x00f3, 0x00f2, 0x00f2, 0x00f1, 0x00f1, 0x00f0, + 0x00f0, 0x00f0, 0x00ef, 0x00ef, 0x00ee, 0x00ee, 0x00ed, 0x00ed, 0x00ed, 0x00ec, 0x00ec, 0x00eb, 0x00eb, 0x00ea, 0x00ea, 0x00ea, + 0x00e9, 0x00e9, 0x00e8, 0x00e8, 0x00e7, 0x00e7, 0x00e7, 0x00e6, 0x00e6, 0x00e5, 0x00e5, 0x00e5, 0x00e4, 0x00e4, 0x00e3, 0x00e3, + 0x00e3, 0x00e2, 0x00e2, 0x00e1, 0x00e1, 0x00e1, 0x00e0, 0x00e0, 0x00e0, 0x00df, 0x00df, 0x00de, 0x00de, 0x00de, 0x00dd, 0x00dd, + 0x00dd, 0x00dc, 0x00dc, 0x00db, 0x00db, 0x00db, 0x00da, 0x00da, 0x00da, 0x00d9, 0x00d9, 0x00d9, 0x00d8, 0x00d8, 0x00d7, 0x00d7, + 0x00d7, 0x00d6, 0x00d6, 0x00d6, 0x00d5, 0x00d5, 0x00d5, 0x00d4, 0x00d4, 0x00d4, 0x00d3, 0x00d3, 0x00d3, 0x00d2, 0x00d2, 0x00d2, + 0x00d1, 0x00d1, 0x00d1, 0x00d0, 0x00d0, 0x00d0, 0x00cf, 0x00cf, 0x00cf, 0x00ce, 0x00ce, 0x00ce, 0x00cd, 0x00cd, 0x00cd, 0x00cc, + 0x00cc, 0x00cc, 0x00cb, 0x00cb, 0x00cb, 0x00ca, 0x00ca, 0x00ca, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c8, 0x00c7, + 0x00c7, 0x00c7, 0x00c6, 0x00c6, 0x00c6, 0x00c5, 0x00c5, 0x00c5, 0x00c5, 0x00c4, 0x00c4, 0x00c4, 0x00c3, 0x00c3, 0x00c3, 0x00c3, + 0x00c2, 0x00c2, 0x00c2, 0x00c1, 0x00c1, 0x00c1, 0x00c1, 0x00c0, 0x00c0, 0x00c0, 0x00bf, 0x00bf, 0x00bf, 0x00bf, 0x00be, 0x00be, + 0x00be, 0x00bd, 0x00bd, 0x00bd, 0x00bd, 0x00bc, 0x00bc, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00bb, 0x00ba, 0x00ba, 0x00ba, 0x00ba, + 0x00b9, 0x00b9, 0x00b9, 0x00b9, 0x00b8, 0x00b8, 0x00b8, 0x00b8, 0x00b7, 0x00b7, 0x00b7, 0x00b7, 0x00b6, 0x00b6, 0x00b6, 0x00b6, + 0x00b5, 0x00b5, 0x00b5, 0x00b5, 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b3, 0x00b3, 0x00b2, 0x00b2, 0x00b2, 0x00b2, + 0x00b1, 0x00b1, 0x00b1, 0x00b1, 0x00b0, 0x00b0, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00af, 0x00af, 0x00ae, 0x00ae, 0x00ae, 0x00ae, + 0x00ae, 0x00ad, 0x00ad, 0x00ad, 0x00ad, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ab, 0x00ab, 0x00ab, 0x00ab, +}; +#endif + + +static tracy_force_inline uint64_t ProcessRGB( const uint8_t* src ) +{ +#ifdef __SSE4_1__ + __m128i px0 = _mm_loadu_si128(((__m128i*)src) + 0); + __m128i px1 = _mm_loadu_si128(((__m128i*)src) + 1); + __m128i px2 = _mm_loadu_si128(((__m128i*)src) + 2); + __m128i px3 = _mm_loadu_si128(((__m128i*)src) + 3); + + __m128i smask = _mm_set1_epi32( 0xF8FCF8 ); + __m128i sd0 = _mm_and_si128( px0, smask ); + __m128i sd1 = _mm_and_si128( px1, smask ); + __m128i sd2 = _mm_and_si128( px2, smask ); + __m128i sd3 = _mm_and_si128( px3, smask ); + + __m128i sc = _mm_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0)); + + __m128i sc0 = _mm_cmpeq_epi8(sd0, sc); + __m128i sc1 = _mm_cmpeq_epi8(sd1, sc); + __m128i sc2 = _mm_cmpeq_epi8(sd2, sc); + __m128i sc3 = _mm_cmpeq_epi8(sd3, sc); + + __m128i sm0 = _mm_and_si128(sc0, sc1); + __m128i sm1 = _mm_and_si128(sc2, sc3); + __m128i sm = _mm_and_si128(sm0, sm1); + + if( _mm_testc_si128(sm, _mm_set1_epi32(-1)) ) + { + return uint64_t( to565( src[0], src[1], src[2] ) ) << 16; + } + + __m128i amask = _mm_set1_epi32( 0xFFFFFF ); + px0 = _mm_and_si128( px0, amask ); + px1 = _mm_and_si128( px1, amask ); + px2 = _mm_and_si128( px2, amask ); + px3 = _mm_and_si128( px3, amask ); + + __m128i min0 = _mm_min_epu8( px0, px1 ); + __m128i min1 = _mm_min_epu8( px2, px3 ); + __m128i min2 = _mm_min_epu8( min0, min1 ); + + __m128i max0 = _mm_max_epu8( px0, px1 ); + __m128i max1 = _mm_max_epu8( px2, px3 ); + __m128i max2 = _mm_max_epu8( max0, max1 ); + + __m128i min3 = _mm_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) ); + __m128i max3 = _mm_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) ); + __m128i min4 = _mm_min_epu8( min2, min3 ); + __m128i max4 = _mm_max_epu8( max2, max3 ); + + __m128i min5 = _mm_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) ); + __m128i max5 = _mm_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) ); + __m128i rmin = _mm_min_epu8( min4, min5 ); + __m128i rmax = _mm_max_epu8( max4, max5 ); + + __m128i range1 = _mm_subs_epu8( rmax, rmin ); + __m128i range2 = _mm_sad_epu8( rmax, rmin ); + + uint32_t vrange = _mm_cvtsi128_si32( range2 ) >> 1; + __m128i range = _mm_set1_epi16( DivTable[vrange] ); + + __m128i inset1 = _mm_srli_epi16( range1, 4 ); + __m128i inset = _mm_and_si128( inset1, _mm_set1_epi8( 0xF ) ); + __m128i min = _mm_adds_epu8( rmin, inset ); + __m128i max = _mm_subs_epu8( rmax, inset ); + + __m128i c0 = _mm_subs_epu8( px0, rmin ); + __m128i c1 = _mm_subs_epu8( px1, rmin ); + __m128i c2 = _mm_subs_epu8( px2, rmin ); + __m128i c3 = _mm_subs_epu8( px3, rmin ); + + __m128i is0 = _mm_maddubs_epi16( c0, _mm_set1_epi8( 1 ) ); + __m128i is1 = _mm_maddubs_epi16( c1, _mm_set1_epi8( 1 ) ); + __m128i is2 = _mm_maddubs_epi16( c2, _mm_set1_epi8( 1 ) ); + __m128i is3 = _mm_maddubs_epi16( c3, _mm_set1_epi8( 1 ) ); + + __m128i s0 = _mm_hadd_epi16( is0, is1 ); + __m128i s1 = _mm_hadd_epi16( is2, is3 ); + + __m128i m0 = _mm_mulhi_epu16( s0, range ); + __m128i m1 = _mm_mulhi_epu16( s1, range ); + + __m128i p0 = _mm_packus_epi16( m0, m1 ); + + __m128i p1 = _mm_or_si128( _mm_srai_epi32( p0, 6 ), _mm_srai_epi32( p0, 12 ) ); + __m128i p2 = _mm_or_si128( _mm_srai_epi32( p0, 18 ), p0 ); + __m128i p3 = _mm_or_si128( p1, p2 ); + __m128i p =_mm_shuffle_epi8( p3, _mm_set1_epi32( 0x0C080400 ) ); + + uint32_t vmin = _mm_cvtsi128_si32( min ); + uint32_t vmax = _mm_cvtsi128_si32( max ); + uint32_t vp = _mm_cvtsi128_si32( p ); + + return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) ); +#elif defined __ARM_NEON +# ifdef __aarch64__ + uint8x16x4_t px = vld4q_u8( src ); + + uint8x16_t lr = px.val[0]; + uint8x16_t lg = px.val[1]; + uint8x16_t lb = px.val[2]; + + uint8_t rmaxr = vmaxvq_u8( lr ); + uint8_t rmaxg = vmaxvq_u8( lg ); + uint8_t rmaxb = vmaxvq_u8( lb ); + + uint8_t rminr = vminvq_u8( lr ); + uint8_t rming = vminvq_u8( lg ); + uint8_t rminb = vminvq_u8( lb ); + + int rr = rmaxr - rminr; + int rg = rmaxg - rming; + int rb = rmaxb - rminb; + + int vrange1 = rr + rg + rb; + uint16_t vrange2 = DivTableNEON[vrange1]; + + uint8_t insetr = rr >> 4; + uint8_t insetg = rg >> 4; + uint8_t insetb = rb >> 4; + + uint8_t minr = rminr + insetr; + uint8_t ming = rming + insetg; + uint8_t minb = rminb + insetb; + + uint8_t maxr = rmaxr - insetr; + uint8_t maxg = rmaxg - insetg; + uint8_t maxb = rmaxb - insetb; + + uint8x16_t cr = vsubq_u8( lr, vdupq_n_u8( rminr ) ); + uint8x16_t cg = vsubq_u8( lg, vdupq_n_u8( rming ) ); + uint8x16_t cb = vsubq_u8( lb, vdupq_n_u8( rminb ) ); + + uint16x8_t is0l = vaddl_u8( vget_low_u8( cr ), vget_low_u8( cg ) ); + uint16x8_t is0h = vaddl_u8( vget_high_u8( cr ), vget_high_u8( cg ) ); + uint16x8_t is1l = vaddw_u8( is0l, vget_low_u8( cb ) ); + uint16x8_t is1h = vaddw_u8( is0h, vget_high_u8( cb ) ); + + int16x8_t range = vdupq_n_s16( vrange2 ); + uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1l ), range ) ); + uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1h ), range ) ); + + uint8x8_t p00 = vmovn_u16( m0 ); + uint8x8_t p01 = vmovn_u16( m1 ); + uint8x16_t p0 = vcombine_u8( p00, p01 ); + + uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) ); + uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) ); + uint32x4_t p3 = vaddq_u32( p1, p2 ); + + uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) ); + uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) ); + + uint32_t vp; + vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 ); + + return uint64_t( ( uint64_t( to565( minr, ming, minb ) ) << 16 ) | to565( maxr, maxg, maxb ) | ( uint64_t( vp ) << 32 ) ); +# else + uint32x4_t px0 = vld1q_u32( (uint32_t*)src ); + uint32x4_t px1 = vld1q_u32( (uint32_t*)src + 4 ); + uint32x4_t px2 = vld1q_u32( (uint32_t*)src + 8 ); + uint32x4_t px3 = vld1q_u32( (uint32_t*)src + 12 ); + + uint32x4_t smask = vdupq_n_u32( 0xF8FCF8 ); + uint32x4_t sd0 = vandq_u32( smask, px0 ); + uint32x4_t sd1 = vandq_u32( smask, px1 ); + uint32x4_t sd2 = vandq_u32( smask, px2 ); + uint32x4_t sd3 = vandq_u32( smask, px3 ); + + uint32x4_t sc = vdupq_n_u32( sd0[0] ); + + uint32x4_t sc0 = vceqq_u32( sd0, sc ); + uint32x4_t sc1 = vceqq_u32( sd1, sc ); + uint32x4_t sc2 = vceqq_u32( sd2, sc ); + uint32x4_t sc3 = vceqq_u32( sd3, sc ); + + uint32x4_t sm0 = vandq_u32( sc0, sc1 ); + uint32x4_t sm1 = vandq_u32( sc2, sc3 ); + int64x2_t sm = vreinterpretq_s64_u32( vandq_u32( sm0, sm1 ) ); + + if( sm[0] == -1 && sm[1] == -1 ) + { + return uint64_t( to565( src[0], src[1], src[2] ) ) << 16; + } + + uint32x4_t mask = vdupq_n_u32( 0xFFFFFF ); + uint8x16_t l0 = vreinterpretq_u8_u32( vandq_u32( mask, px0 ) ); + uint8x16_t l1 = vreinterpretq_u8_u32( vandq_u32( mask, px1 ) ); + uint8x16_t l2 = vreinterpretq_u8_u32( vandq_u32( mask, px2 ) ); + uint8x16_t l3 = vreinterpretq_u8_u32( vandq_u32( mask, px3 ) ); + + uint8x16_t min0 = vminq_u8( l0, l1 ); + uint8x16_t min1 = vminq_u8( l2, l3 ); + uint8x16_t min2 = vminq_u8( min0, min1 ); + + uint8x16_t max0 = vmaxq_u8( l0, l1 ); + uint8x16_t max1 = vmaxq_u8( l2, l3 ); + uint8x16_t max2 = vmaxq_u8( max0, max1 ); + + uint8x16_t min3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( min2 ) ) ); + uint8x16_t max3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( max2 ) ) ); + + uint8x16_t min4 = vminq_u8( min2, min3 ); + uint8x16_t max4 = vmaxq_u8( max2, max3 ); + + uint8x16_t min5 = vcombine_u8( vget_high_u8( min4 ), vget_low_u8( min4 ) ); + uint8x16_t max5 = vcombine_u8( vget_high_u8( max4 ), vget_low_u8( max4 ) ); + + uint8x16_t rmin = vminq_u8( min4, min5 ); + uint8x16_t rmax = vmaxq_u8( max4, max5 ); + + uint8x16_t range1 = vsubq_u8( rmax, rmin ); + uint8x8_t range2 = vget_low_u8( range1 ); + uint8x8x2_t range3 = vzip_u8( range2, vdup_n_u8( 0 ) ); + uint16x4_t range4 = vreinterpret_u16_u8( range3.val[0] ); + + uint16_t vrange1; + uint16x4_t range5 = vpadd_u16( range4, range4 ); + uint16x4_t range6 = vpadd_u16( range5, range5 ); + vst1_lane_u16( &vrange1, range6, 0 ); + + uint32_t vrange2 = ( 2 << 16 ) / uint32_t( vrange1 + 1 ); + uint16x8_t range = vdupq_n_u16( vrange2 ); + + uint8x16_t inset = vshrq_n_u8( range1, 4 ); + uint8x16_t min = vaddq_u8( rmin, inset ); + uint8x16_t max = vsubq_u8( rmax, inset ); + + uint8x16_t c0 = vsubq_u8( l0, rmin ); + uint8x16_t c1 = vsubq_u8( l1, rmin ); + uint8x16_t c2 = vsubq_u8( l2, rmin ); + uint8x16_t c3 = vsubq_u8( l3, rmin ); + + uint16x8_t is0 = vpaddlq_u8( c0 ); + uint16x8_t is1 = vpaddlq_u8( c1 ); + uint16x8_t is2 = vpaddlq_u8( c2 ); + uint16x8_t is3 = vpaddlq_u8( c3 ); + + uint16x4_t is4 = vpadd_u16( vget_low_u16( is0 ), vget_high_u16( is0 ) ); + uint16x4_t is5 = vpadd_u16( vget_low_u16( is1 ), vget_high_u16( is1 ) ); + uint16x4_t is6 = vpadd_u16( vget_low_u16( is2 ), vget_high_u16( is2 ) ); + uint16x4_t is7 = vpadd_u16( vget_low_u16( is3 ), vget_high_u16( is3 ) ); + + uint16x8_t s0 = vcombine_u16( is4, is5 ); + uint16x8_t s1 = vcombine_u16( is6, is7 ); + + uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s0 ), vreinterpretq_s16_u16( range ) ) ); + uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s1 ), vreinterpretq_s16_u16( range ) ) ); + + uint8x8_t p00 = vmovn_u16( m0 ); + uint8x8_t p01 = vmovn_u16( m1 ); + uint8x16_t p0 = vcombine_u8( p00, p01 ); + + uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) ); + uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) ); + uint32x4_t p3 = vaddq_u32( p1, p2 ); + + uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) ); + uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) ); + + uint32_t vmin, vmax, vp; + vst1q_lane_u32( &vmin, vreinterpretq_u32_u8( min ), 0 ); + vst1q_lane_u32( &vmax, vreinterpretq_u32_u8( max ), 0 ); + vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 ); + + return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) ); +# endif +#else + uint32_t ref; + memcpy( &ref, src, 4 ); + uint32_t refMask = ref & 0xF8FCF8; + auto stmp = src + 4; + for( int i=1; i<16; i++ ) + { + uint32_t px; + memcpy( &px, stmp, 4 ); + if( ( px & 0xF8FCF8 ) != refMask ) break; + stmp += 4; + } + if( stmp == src + 64 ) + { + return uint64_t( to565( ref ) ) << 16; + } + + uint8_t min[3] = { src[0], src[1], src[2] }; + uint8_t max[3] = { src[0], src[1], src[2] }; + auto tmp = src + 4; + for( int i=1; i<16; i++ ) + { + for( int j=0; j<3; j++ ) + { + if( tmp[j] < min[j] ) min[j] = tmp[j]; + else if( tmp[j] > max[j] ) max[j] = tmp[j]; + } + tmp += 4; + } + + const uint32_t range = DivTable[max[0] - min[0] + max[1] - min[1] + max[2] - min[2]]; + const uint32_t rmin = min[0] + min[1] + min[2]; + for( int i=0; i<3; i++ ) + { + const uint8_t inset = ( max[i] - min[i] ) >> 4; + min[i] += inset; + max[i] -= inset; + } + + uint32_t data = 0; + for( int i=0; i<16; i++ ) + { + const uint32_t c = src[0] + src[1] + src[2] - rmin; + const uint8_t idx = ( c * range ) >> 16; + data |= idx << (i*2); + src += 4; + } + + return uint64_t( ( uint64_t( to565( min[0], min[1], min[2] ) ) << 16 ) | to565( max[0], max[1], max[2] ) | ( uint64_t( data ) << 32 ) ); +#endif +} + +#ifdef __AVX2__ +static tracy_force_inline void ProcessRGB_AVX( const uint8_t* src, char*& dst ) +{ + __m256i px0 = _mm256_loadu_si256(((__m256i*)src) + 0); + __m256i px1 = _mm256_loadu_si256(((__m256i*)src) + 1); + __m256i px2 = _mm256_loadu_si256(((__m256i*)src) + 2); + __m256i px3 = _mm256_loadu_si256(((__m256i*)src) + 3); + + __m256i smask = _mm256_set1_epi32( 0xF8FCF8 ); + __m256i sd0 = _mm256_and_si256( px0, smask ); + __m256i sd1 = _mm256_and_si256( px1, smask ); + __m256i sd2 = _mm256_and_si256( px2, smask ); + __m256i sd3 = _mm256_and_si256( px3, smask ); + + __m256i sc = _mm256_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0)); + + __m256i sc0 = _mm256_cmpeq_epi8( sd0, sc ); + __m256i sc1 = _mm256_cmpeq_epi8( sd1, sc ); + __m256i sc2 = _mm256_cmpeq_epi8( sd2, sc ); + __m256i sc3 = _mm256_cmpeq_epi8( sd3, sc ); + + __m256i sm0 = _mm256_and_si256( sc0, sc1 ); + __m256i sm1 = _mm256_and_si256( sc2, sc3 ); + __m256i sm = _mm256_and_si256( sm0, sm1 ); + + const int64_t solid0 = 1 - _mm_testc_si128( _mm256_castsi256_si128( sm ), _mm_set1_epi32( -1 ) ); + const int64_t solid1 = 1 - _mm_testc_si128( _mm256_extracti128_si256( sm, 1 ), _mm_set1_epi32( -1 ) ); + + if( solid0 + solid1 == 0 ) + { + const auto c0 = uint64_t( to565( src[0], src[1], src[2] ) ) << 16; + const auto c1 = uint64_t( to565( src[16], src[17], src[18] ) ) << 16; + memcpy( dst, &c0, 8 ); + memcpy( dst+8, &c1, 8 ); + dst += 16; + return; + } + + __m256i amask = _mm256_set1_epi32( 0xFFFFFF ); + px0 = _mm256_and_si256( px0, amask ); + px1 = _mm256_and_si256( px1, amask ); + px2 = _mm256_and_si256( px2, amask ); + px3 = _mm256_and_si256( px3, amask ); + + __m256i min0 = _mm256_min_epu8( px0, px1 ); + __m256i min1 = _mm256_min_epu8( px2, px3 ); + __m256i min2 = _mm256_min_epu8( min0, min1 ); + + __m256i max0 = _mm256_max_epu8( px0, px1 ); + __m256i max1 = _mm256_max_epu8( px2, px3 ); + __m256i max2 = _mm256_max_epu8( max0, max1 ); + + __m256i min3 = _mm256_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) ); + __m256i max3 = _mm256_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) ); + __m256i min4 = _mm256_min_epu8( min2, min3 ); + __m256i max4 = _mm256_max_epu8( max2, max3 ); + + __m256i min5 = _mm256_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) ); + __m256i max5 = _mm256_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) ); + __m256i rmin = _mm256_min_epu8( min4, min5 ); + __m256i rmax = _mm256_max_epu8( max4, max5 ); + + __m256i range1 = _mm256_subs_epu8( rmax, rmin ); + __m256i range2 = _mm256_sad_epu8( rmax, rmin ); + + uint16_t vrange0 = DivTable[_mm256_cvtsi256_si32( range2 ) >> 1]; + uint16_t vrange1 = DivTable[_mm256_extract_epi16( range2, 8 ) >> 1]; + __m256i range00 = _mm256_set1_epi16( vrange0 ); + __m256i range = _mm256_inserti128_si256( range00, _mm_set1_epi16( vrange1 ), 1 ); + + __m256i inset1 = _mm256_srli_epi16( range1, 4 ); + __m256i inset = _mm256_and_si256( inset1, _mm256_set1_epi8( 0xF ) ); + __m256i min = _mm256_adds_epu8( rmin, inset ); + __m256i max = _mm256_subs_epu8( rmax, inset ); + + __m256i c0 = _mm256_subs_epu8( px0, rmin ); + __m256i c1 = _mm256_subs_epu8( px1, rmin ); + __m256i c2 = _mm256_subs_epu8( px2, rmin ); + __m256i c3 = _mm256_subs_epu8( px3, rmin ); + + __m256i is0 = _mm256_maddubs_epi16( c0, _mm256_set1_epi8( 1 ) ); + __m256i is1 = _mm256_maddubs_epi16( c1, _mm256_set1_epi8( 1 ) ); + __m256i is2 = _mm256_maddubs_epi16( c2, _mm256_set1_epi8( 1 ) ); + __m256i is3 = _mm256_maddubs_epi16( c3, _mm256_set1_epi8( 1 ) ); + + __m256i s0 = _mm256_hadd_epi16( is0, is1 ); + __m256i s1 = _mm256_hadd_epi16( is2, is3 ); + + __m256i m0 = _mm256_mulhi_epu16( s0, range ); + __m256i m1 = _mm256_mulhi_epu16( s1, range ); + + __m256i p0 = _mm256_packus_epi16( m0, m1 ); + + __m256i p1 = _mm256_or_si256( _mm256_srai_epi32( p0, 6 ), _mm256_srai_epi32( p0, 12 ) ); + __m256i p2 = _mm256_or_si256( _mm256_srai_epi32( p0, 18 ), p0 ); + __m256i p3 = _mm256_or_si256( p1, p2 ); + __m256i p =_mm256_shuffle_epi8( p3, _mm256_set1_epi32( 0x0C080400 ) ); + + __m256i mm0 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), min ); + __m256i mm1 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), max ); + __m256i mm2 = _mm256_unpacklo_epi64( mm1, mm0 ); + __m256i mmr = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 11 ), 11 ); + __m256i mmg = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 26 ), 5 ); + __m256i mmb = _mm256_srli_epi64( _mm256_slli_epi64( mm2, 16 ), 59 ); + __m256i mm3 = _mm256_or_si256( mmr, mmg ); + __m256i mm4 = _mm256_or_si256( mm3, mmb ); + __m256i mm5 = _mm256_shuffle_epi8( mm4, _mm256_set1_epi32( 0x09080100 ) ); + + __m256i d0 = _mm256_unpacklo_epi32( mm5, p ); + __m256i d1 = _mm256_permute4x64_epi64( d0, _MM_SHUFFLE( 3, 2, 2, 0 ) ); + __m128i d2 = _mm256_castsi256_si128( d1 ); + + __m128i mask = _mm_set_epi64x( 0xFFFF0000 | -solid1, 0xFFFF0000 | -solid0 ); + __m128i d3 = _mm_and_si128( d2, mask ); + _mm_storeu_si128( (__m128i*)dst, d3 ); + dst += 16; +} +#endif + +void CompressImageDxt1( const char* src, char* dst, int w, int h ) +{ + assert( (w % 4) == 0 && (h % 4) == 0 ); + +#ifdef __AVX2__ + if( w%8 == 0 ) + { + uint32_t buf[8*4]; + int i = 0; + + auto blocks = w * h / 32; + do + { + auto tmp = (char*)buf; + memcpy( tmp, src, 8*4 ); + memcpy( tmp + 8*4, src + w * 4, 8*4 ); + memcpy( tmp + 16*4, src + w * 8, 8*4 ); + memcpy( tmp + 24*4, src + w * 12, 8*4 ); + src += 8*4; + if( ++i == w/8 ) + { + src += w * 3 * 4; + i = 0; + } + + ProcessRGB_AVX( (uint8_t*)buf, dst ); + } + while( --blocks ); + } + else +#endif + { + uint32_t buf[4*4]; + int i = 0; + + auto ptr = dst; + auto blocks = w * h / 16; + do + { + auto tmp = (char*)buf; + memcpy( tmp, src, 4*4 ); + memcpy( tmp + 4*4, src + w * 4, 4*4 ); + memcpy( tmp + 8*4, src + w * 8, 4*4 ); + memcpy( tmp + 12*4, src + w * 12, 4*4 ); + src += 4*4; + if( ++i == w/4 ) + { + src += w * 3 * 4; + i = 0; + } + + const auto c = ProcessRGB( (uint8_t*)buf ); + memcpy( ptr, &c, sizeof( uint64_t ) ); + ptr += sizeof( uint64_t ); + } + while( --blocks ); + } +} + +} diff --git a/Externals/tracy/public/client/TracyDxt1.hpp b/Externals/tracy/public/client/TracyDxt1.hpp new file mode 100644 index 00000000000..c2313542789 --- /dev/null +++ b/Externals/tracy/public/client/TracyDxt1.hpp @@ -0,0 +1,11 @@ +#ifndef __TRACYDXT1_HPP__ +#define __TRACYDXT1_HPP__ + +namespace tracy +{ + +void CompressImageDxt1( const char* src, char* dst, int w, int h ); + +} + +#endif diff --git a/Externals/tracy/public/client/TracyFastVector.hpp b/Externals/tracy/public/client/TracyFastVector.hpp new file mode 100644 index 00000000000..38accc926b0 --- /dev/null +++ b/Externals/tracy/public/client/TracyFastVector.hpp @@ -0,0 +1,118 @@ +#ifndef __TRACYFASTVECTOR_HPP__ +#define __TRACYFASTVECTOR_HPP__ + +#include +#include + +#include "../common/TracyAlloc.hpp" +#include "../common/TracyForceInline.hpp" + +namespace tracy +{ + +template +class FastVector +{ +public: + using iterator = T*; + using const_iterator = const T*; + + FastVector( size_t capacity ) + : m_ptr( (T*)tracy_malloc( sizeof( T ) * capacity ) ) + , m_write( m_ptr ) + , m_end( m_ptr + capacity ) + { + assert( capacity != 0 ); + } + + FastVector( const FastVector& ) = delete; + FastVector( FastVector&& ) = delete; + + ~FastVector() + { + tracy_free( m_ptr ); + } + + FastVector& operator=( const FastVector& ) = delete; + FastVector& operator=( FastVector&& ) = delete; + + bool empty() const { return m_ptr == m_write; } + size_t size() const { return m_write - m_ptr; } + + T* data() { return m_ptr; } + const T* data() const { return m_ptr; }; + + T* begin() { return m_ptr; } + const T* begin() const { return m_ptr; } + T* end() { return m_write; } + const T* end() const { return m_write; } + + T& front() { assert( !empty() ); return m_ptr[0]; } + const T& front() const { assert( !empty() ); return m_ptr[0]; } + + T& back() { assert( !empty() ); return m_write[-1]; } + const T& back() const { assert( !empty() ); return m_write[-1]; } + + T& operator[]( size_t idx ) { return m_ptr[idx]; } + const T& operator[]( size_t idx ) const { return m_ptr[idx]; } + + T* push_next() + { + if( m_write == m_end ) AllocMore(); + return m_write++; + } + + T* prepare_next() + { + if( m_write == m_end ) AllocMore(); + return m_write; + } + + void commit_next() + { + m_write++; + } + + void clear() + { + m_write = m_ptr; + } + + void swap( FastVector& vec ) + { + const auto ptr1 = m_ptr; + const auto ptr2 = vec.m_ptr; + const auto write1 = m_write; + const auto write2 = vec.m_write; + const auto end1 = m_end; + const auto end2 = vec.m_end; + + m_ptr = ptr2; + vec.m_ptr = ptr1; + m_write = write2; + vec.m_write = write1; + m_end = end2; + vec.m_end = end1; + } + +private: + tracy_no_inline void AllocMore() + { + const auto cap = size_t( m_end - m_ptr ) * 2; + const auto size = size_t( m_write - m_ptr ); + T* ptr = (T*)tracy_malloc( sizeof( T ) * cap ); + memcpy( ptr, m_ptr, size * sizeof( T ) ); + tracy_free_fast( m_ptr ); + m_ptr = ptr; + m_write = m_ptr + size; + m_end = m_ptr + cap; + } + + T* m_ptr; + T* m_write; + T* m_end; +}; + +} + +#endif diff --git a/Externals/tracy/public/client/TracyLock.hpp b/Externals/tracy/public/client/TracyLock.hpp new file mode 100644 index 00000000000..d12a3c16d6d --- /dev/null +++ b/Externals/tracy/public/client/TracyLock.hpp @@ -0,0 +1,546 @@ +#ifndef __TRACYLOCK_HPP__ +#define __TRACYLOCK_HPP__ + +#include +#include + +#include "../common/TracySystem.hpp" +#include "../common/TracyAlign.hpp" +#include "TracyProfiler.hpp" + +namespace tracy +{ + +class LockableCtx +{ +public: + tracy_force_inline LockableCtx( const SourceLocationData* srcloc ) + : m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) ) +#ifdef TRACY_ON_DEMAND + , m_lockCount( 0 ) + , m_active( false ) +#endif + { + assert( m_id != (std::numeric_limits::max)() ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockAnnounce ); + MemWrite( &item->lockAnnounce.id, m_id ); + MemWrite( &item->lockAnnounce.time, Profiler::GetTime() ); + MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc ); + MemWrite( &item->lockAnnounce.type, LockType::Lockable ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + LockableCtx( const LockableCtx& ) = delete; + LockableCtx& operator=( const LockableCtx& ) = delete; + + tracy_force_inline ~LockableCtx() + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockTerminate ); + MemWrite( &item->lockTerminate.id, m_id ); + MemWrite( &item->lockTerminate.time, Profiler::GetTime() ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + tracy_force_inline bool BeforeLock() + { +#ifdef TRACY_ON_DEMAND + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return false; +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockWait ); + MemWrite( &item->lockWait.thread, GetThreadHandle() ); + MemWrite( &item->lockWait.id, m_id ); + MemWrite( &item->lockWait.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + return true; + } + + tracy_force_inline void AfterLock() + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterUnlock() + { +#ifdef TRACY_ON_DEMAND + m_lockCount.fetch_sub( 1, std::memory_order_relaxed ); + if( !m_active.load( std::memory_order_relaxed ) ) return; + if( !GetProfiler().IsConnected() ) + { + m_active.store( false, std::memory_order_relaxed ); + return; + } +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockRelease ); + MemWrite( &item->lockRelease.id, m_id ); + MemWrite( &item->lockRelease.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterTryLock( bool acquired ) + { +#ifdef TRACY_ON_DEMAND + if( !acquired ) return; + + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return; +#endif + + if( acquired ) + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + } + + tracy_force_inline void Mark( const SourceLocationData* srcloc ) + { +#ifdef TRACY_ON_DEMAND + const auto active = m_active.load( std::memory_order_relaxed ); + if( !active ) return; + const auto connected = GetProfiler().IsConnected(); + if( !connected ) + { + if( active ) m_active.store( false, std::memory_order_relaxed ); + return; + } +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockMark ); + MemWrite( &item->lockMark.thread, GetThreadHandle() ); + MemWrite( &item->lockMark.id, m_id ); + MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void CustomName( const char* name, size_t size ) + { + assert( size < (std::numeric_limits::max)() ); + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, name, size ); + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockName ); + MemWrite( &item->lockNameFat.id, m_id ); + MemWrite( &item->lockNameFat.name, (uint64_t)ptr ); + MemWrite( &item->lockNameFat.size, (uint16_t)size ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + +private: + uint32_t m_id; + +#ifdef TRACY_ON_DEMAND + std::atomic m_lockCount; + std::atomic m_active; +#endif +}; + +template +class Lockable +{ +public: + tracy_force_inline Lockable( const SourceLocationData* srcloc ) + : m_ctx( srcloc ) + { + } + + Lockable( const Lockable& ) = delete; + Lockable& operator=( const Lockable& ) = delete; + + tracy_force_inline void lock() + { + const auto runAfter = m_ctx.BeforeLock(); + m_lockable.lock(); + if( runAfter ) m_ctx.AfterLock(); + } + + tracy_force_inline void unlock() + { + m_lockable.unlock(); + m_ctx.AfterUnlock(); + } + + tracy_force_inline bool try_lock() + { + const auto acquired = m_lockable.try_lock(); + m_ctx.AfterTryLock( acquired ); + return acquired; + } + + tracy_force_inline void Mark( const SourceLocationData* srcloc ) + { + m_ctx.Mark( srcloc ); + } + + tracy_force_inline void CustomName( const char* name, size_t size ) + { + m_ctx.CustomName( name, size ); + } + +private: + T m_lockable; + LockableCtx m_ctx; +}; + + +class SharedLockableCtx +{ +public: + tracy_force_inline SharedLockableCtx( const SourceLocationData* srcloc ) + : m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) ) +#ifdef TRACY_ON_DEMAND + , m_lockCount( 0 ) + , m_active( false ) +#endif + { + assert( m_id != (std::numeric_limits::max)() ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockAnnounce ); + MemWrite( &item->lockAnnounce.id, m_id ); + MemWrite( &item->lockAnnounce.time, Profiler::GetTime() ); + MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc ); + MemWrite( &item->lockAnnounce.type, LockType::SharedLockable ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + SharedLockableCtx( const SharedLockableCtx& ) = delete; + SharedLockableCtx& operator=( const SharedLockableCtx& ) = delete; + + tracy_force_inline ~SharedLockableCtx() + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockTerminate ); + MemWrite( &item->lockTerminate.id, m_id ); + MemWrite( &item->lockTerminate.time, Profiler::GetTime() ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + tracy_force_inline bool BeforeLock() + { +#ifdef TRACY_ON_DEMAND + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return false; +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockWait ); + MemWrite( &item->lockWait.thread, GetThreadHandle() ); + MemWrite( &item->lockWait.id, m_id ); + MemWrite( &item->lockWait.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + return true; + } + + tracy_force_inline void AfterLock() + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterUnlock() + { +#ifdef TRACY_ON_DEMAND + m_lockCount.fetch_sub( 1, std::memory_order_relaxed ); + if( !m_active.load( std::memory_order_relaxed ) ) return; + if( !GetProfiler().IsConnected() ) + { + m_active.store( false, std::memory_order_relaxed ); + return; + } +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockRelease ); + MemWrite( &item->lockRelease.id, m_id ); + MemWrite( &item->lockRelease.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterTryLock( bool acquired ) + { +#ifdef TRACY_ON_DEMAND + if( !acquired ) return; + + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return; +#endif + + if( acquired ) + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + } + + tracy_force_inline bool BeforeLockShared() + { +#ifdef TRACY_ON_DEMAND + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return false; +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockSharedWait ); + MemWrite( &item->lockWait.thread, GetThreadHandle() ); + MemWrite( &item->lockWait.id, m_id ); + MemWrite( &item->lockWait.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + return true; + } + + tracy_force_inline void AfterLockShared() + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockSharedObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterUnlockShared() + { +#ifdef TRACY_ON_DEMAND + m_lockCount.fetch_sub( 1, std::memory_order_relaxed ); + if( !m_active.load( std::memory_order_relaxed ) ) return; + if( !GetProfiler().IsConnected() ) + { + m_active.store( false, std::memory_order_relaxed ); + return; + } +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockSharedRelease ); + MemWrite( &item->lockReleaseShared.thread, GetThreadHandle() ); + MemWrite( &item->lockReleaseShared.id, m_id ); + MemWrite( &item->lockReleaseShared.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void AfterTryLockShared( bool acquired ) + { +#ifdef TRACY_ON_DEMAND + if( !acquired ) return; + + bool queue = false; + const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed ); + const auto active = m_active.load( std::memory_order_relaxed ); + if( locks == 0 || active ) + { + const bool connected = GetProfiler().IsConnected(); + if( active != connected ) m_active.store( connected, std::memory_order_relaxed ); + if( connected ) queue = true; + } + if( !queue ) return; +#endif + + if( acquired ) + { + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockSharedObtain ); + MemWrite( &item->lockObtain.thread, GetThreadHandle() ); + MemWrite( &item->lockObtain.id, m_id ); + MemWrite( &item->lockObtain.time, Profiler::GetTime() ); + Profiler::QueueSerialFinish(); + } + } + + tracy_force_inline void Mark( const SourceLocationData* srcloc ) + { +#ifdef TRACY_ON_DEMAND + const auto active = m_active.load( std::memory_order_relaxed ); + if( !active ) return; + const auto connected = GetProfiler().IsConnected(); + if( !connected ) + { + if( active ) m_active.store( false, std::memory_order_relaxed ); + return; + } +#endif + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockMark ); + MemWrite( &item->lockMark.thread, GetThreadHandle() ); + MemWrite( &item->lockMark.id, m_id ); + MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void CustomName( const char* name, size_t size ) + { + assert( size < (std::numeric_limits::max)() ); + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, name, size ); + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::LockName ); + MemWrite( &item->lockNameFat.id, m_id ); + MemWrite( &item->lockNameFat.name, (uint64_t)ptr ); + MemWrite( &item->lockNameFat.size, (uint16_t)size ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + +private: + uint32_t m_id; + +#ifdef TRACY_ON_DEMAND + std::atomic m_lockCount; + std::atomic m_active; +#endif +}; + +template +class SharedLockable +{ +public: + tracy_force_inline SharedLockable( const SourceLocationData* srcloc ) + : m_ctx( srcloc ) + { + } + + SharedLockable( const SharedLockable& ) = delete; + SharedLockable& operator=( const SharedLockable& ) = delete; + + tracy_force_inline void lock() + { + const auto runAfter = m_ctx.BeforeLock(); + m_lockable.lock(); + if( runAfter ) m_ctx.AfterLock(); + } + + tracy_force_inline void unlock() + { + m_lockable.unlock(); + m_ctx.AfterUnlock(); + } + + tracy_force_inline bool try_lock() + { + const auto acquired = m_lockable.try_lock(); + m_ctx.AfterTryLock( acquired ); + return acquired; + } + + tracy_force_inline void lock_shared() + { + const auto runAfter = m_ctx.BeforeLockShared(); + m_lockable.lock_shared(); + if( runAfter ) m_ctx.AfterLockShared(); + } + + tracy_force_inline void unlock_shared() + { + m_lockable.unlock_shared(); + m_ctx.AfterUnlockShared(); + } + + tracy_force_inline bool try_lock_shared() + { + const auto acquired = m_lockable.try_lock_shared(); + m_ctx.AfterTryLockShared( acquired ); + return acquired; + } + + tracy_force_inline void Mark( const SourceLocationData* srcloc ) + { + m_ctx.Mark( srcloc ); + } + + tracy_force_inline void CustomName( const char* name, size_t size ) + { + m_ctx.CustomName( name, size ); + } + +private: + T m_lockable; + SharedLockableCtx m_ctx; +}; + + +} + +#endif diff --git a/Externals/tracy/public/client/TracyOverride.cpp b/Externals/tracy/public/client/TracyOverride.cpp new file mode 100644 index 00000000000..591508a7ff4 --- /dev/null +++ b/Externals/tracy/public/client/TracyOverride.cpp @@ -0,0 +1,26 @@ +#ifdef TRACY_ENABLE +# ifdef __linux__ +# include "TracyDebug.hpp" +# ifdef TRACY_VERBOSE +# include +# include +# endif + +extern "C" int dlclose( void* hnd ) +{ +#ifdef TRACY_VERBOSE + struct link_map* lm; + if( dlinfo( hnd, RTLD_DI_LINKMAP, &lm ) == 0 ) + { + TracyDebug( "Overriding dlclose for %s\n", lm->l_name ); + } + else + { + TracyDebug( "Overriding dlclose for unknown object (%s)\n", dlerror() ); + } +#endif + return 0; +} + +# endif +#endif diff --git a/Externals/tracy/public/client/TracyProfiler.cpp b/Externals/tracy/public/client/TracyProfiler.cpp new file mode 100644 index 00000000000..ed580123a7a --- /dev/null +++ b/Externals/tracy/public/client/TracyProfiler.cpp @@ -0,0 +1,4419 @@ +#ifdef TRACY_ENABLE + +#ifdef _WIN32 +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# include +# include +# include +# include +# include "../common/TracyUwp.hpp" +#else +# include +# include +#endif + +#ifdef _GNU_SOURCE +# include +#endif + +#ifdef __linux__ +# include +# include +# include +# include +#endif + +#if defined __APPLE__ || defined BSD +# include +# include +#endif + +#if defined __APPLE__ +# include "TargetConditionals.h" +# include +#endif + +#ifdef __ANDROID__ +# include +# include +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/TracyAlign.hpp" +#include "../common/TracyAlloc.hpp" +#include "../common/TracySocket.hpp" +#include "../common/TracySystem.hpp" +#include "../common/TracyYield.hpp" +#include "../common/tracy_lz4.hpp" +#include "tracy_rpmalloc.hpp" +#include "TracyCallstack.hpp" +#include "TracyDebug.hpp" +#include "TracyDxt1.hpp" +#include "TracyScoped.hpp" +#include "TracyProfiler.hpp" +#include "TracyThread.hpp" +#include "TracyArmCpuTable.hpp" +#include "TracySysTrace.hpp" +#include "../tracy/TracyC.h" + +#ifdef TRACY_PORT +# ifndef TRACY_DATA_PORT +# define TRACY_DATA_PORT TRACY_PORT +# endif +# ifndef TRACY_BROADCAST_PORT +# define TRACY_BROADCAST_PORT TRACY_PORT +# endif +#endif + +#ifdef __APPLE__ +# ifndef TRACY_DELAYED_INIT +# define TRACY_DELAYED_INIT +# endif +#else +# ifdef __GNUC__ +# define init_order( val ) __attribute__ ((init_priority(val))) +# else +# define init_order(x) +# endif +#endif + +#if defined _WIN32 +# include +extern "C" typedef LONG (WINAPI *t_RtlGetVersion)( PRTL_OSVERSIONINFOW ); +extern "C" typedef BOOL (WINAPI *t_GetLogicalProcessorInformationEx)( LOGICAL_PROCESSOR_RELATIONSHIP, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD ); +#else +# include +# include +#endif +#if defined __linux__ +# include +# include +#endif + +#if !defined _WIN32 && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) +# include "TracyCpuid.hpp" +#endif + +#if !( ( defined _WIN32 && _WIN32_WINNT >= _WIN32_WINNT_VISTA ) || defined __linux__ ) +# include +#endif + +namespace tracy +{ + +#ifdef __ANDROID__ +// Implementation helpers of EnsureReadable(address). +// This is so far only needed on Android, where it is common for libraries to be mapped +// with only executable, not readable, permissions. Typical example (line from /proc/self/maps): +/* +746b63b000-746b6dc000 --xp 00042000 07:48 35 /apex/com.android.runtime/lib64/bionic/libc.so +*/ +// See https://github.com/wolfpld/tracy/issues/125 . +// To work around this, we parse /proc/self/maps and we use mprotect to set read permissions +// on any mappings that contain symbols addresses hit by HandleSymbolCodeQuery. + +namespace { +// Holds some information about a single memory mapping. +struct MappingInfo { + // Start of address range. Inclusive. + uintptr_t start_address; + // End of address range. Exclusive, so the mapping is the half-open interval + // [start, end) and its length in bytes is `end - start`. As in /proc/self/maps. + uintptr_t end_address; + // Read/Write/Executable permissions. + bool perm_r, perm_w, perm_x; +}; +} // anonymous namespace + + // Internal implementation helper for LookUpMapping(address). + // + // Parses /proc/self/maps returning a vector. + // /proc/self/maps is assumed to be sorted by ascending address, so the resulting + // vector is sorted by ascending address too. +static std::vector ParseMappings() +{ + std::vector result; + FILE* file = fopen( "/proc/self/maps", "r" ); + if( !file ) return result; + char line[1024]; + while( fgets( line, sizeof( line ), file ) ) + { + uintptr_t start_addr; + uintptr_t end_addr; + if( sscanf( line, "%lx-%lx", &start_addr, &end_addr ) != 2 ) continue; + char* first_space = strchr( line, ' ' ); + if( !first_space ) continue; + char* perm = first_space + 1; + char* second_space = strchr( perm, ' ' ); + if( !second_space || second_space - perm != 4 ) continue; + result.emplace_back(); + auto& mapping = result.back(); + mapping.start_address = start_addr; + mapping.end_address = end_addr; + mapping.perm_r = perm[0] == 'r'; + mapping.perm_w = perm[1] == 'w'; + mapping.perm_x = perm[2] == 'x'; + } + fclose( file ); + return result; +} + +// Internal implementation helper for LookUpMapping(address). +// +// Takes as input an `address` and a known vector `mappings`, assumed to be +// sorted by increasing addresses, as /proc/self/maps seems to be. +// Returns a pointer to the MappingInfo describing the mapping that this +// address belongs to, or nullptr if the address isn't in `mappings`. +static MappingInfo* LookUpMapping(std::vector& mappings, uintptr_t address) +{ + // Comparison function for std::lower_bound. Returns true if all addresses in `m1` + // are lower than `addr`. + auto Compare = []( const MappingInfo& m1, uintptr_t addr ) { + // '<=' because the address ranges are half-open intervals, [start, end). + return m1.end_address <= addr; + }; + auto iter = std::lower_bound( mappings.begin(), mappings.end(), address, Compare ); + if( iter == mappings.end() || iter->start_address > address) { + return nullptr; + } + return &*iter; +} + +// Internal implementation helper for EnsureReadable(address). +// +// Takes as input an `address` and returns a pointer to a MappingInfo +// describing the mapping that this address belongs to, or nullptr if +// the address isn't in any known mapping. +// +// This function is stateful and not reentrant (assumes to be called from +// only one thread). It holds a vector of mappings parsed from /proc/self/maps. +// +// Attempts to react to mappings changes by re-parsing /proc/self/maps. +static MappingInfo* LookUpMapping(uintptr_t address) +{ + // Static state managed by this function. Not constant, we mutate that state as + // we turn some mappings readable. Initially parsed once here, updated as needed below. + static std::vector s_mappings = ParseMappings(); + MappingInfo* mapping = LookUpMapping( s_mappings, address ); + if( mapping ) return mapping; + + // This address isn't in any known mapping. Try parsing again, maybe + // mappings changed. + s_mappings = ParseMappings(); + return LookUpMapping( s_mappings, address ); +} + +// Internal implementation helper for EnsureReadable(address). +// +// Attempts to make the specified `mapping` readable if it isn't already. +// Returns true if and only if the mapping is readable. +static bool EnsureReadable( MappingInfo& mapping ) +{ + if( mapping.perm_r ) + { + // The mapping is already readable. + return true; + } + int prot = PROT_READ; + if( mapping.perm_w ) prot |= PROT_WRITE; + if( mapping.perm_x ) prot |= PROT_EXEC; + if( mprotect( reinterpret_cast( mapping.start_address ), + mapping.end_address - mapping.start_address, prot ) == -1 ) + { + // Failed to make the mapping readable. Shouldn't happen, hasn't + // been observed yet. If it happened in practice, we should consider + // adding a bool to MappingInfo to track this to avoid retrying mprotect + // everytime on such mappings. + return false; + } + // The mapping is now readable. Update `mapping` so the next call will be fast. + mapping.perm_r = true; + return true; +} + +// Attempts to set the read permission on the entire mapping containing the +// specified address. Returns true if and only if the mapping is now readable. +static bool EnsureReadable( uintptr_t address ) +{ + MappingInfo* mapping = LookUpMapping(address); + return mapping && EnsureReadable( *mapping ); +} + +#endif // defined __ANDROID__ + +#ifndef TRACY_DELAYED_INIT + +struct InitTimeWrapper +{ + int64_t val; +}; + +struct ProducerWrapper +{ + tracy::moodycamel::ConcurrentQueue::ExplicitProducer* ptr; +}; + +struct ThreadHandleWrapper +{ + uint32_t val; +}; +#endif + + +#if defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 +static inline void CpuId( uint32_t* regs, uint32_t leaf ) +{ + memset(regs, 0, sizeof(uint32_t) * 4); +#if defined _WIN32 + __cpuidex( (int*)regs, leaf, 0 ); +#else + __get_cpuid( leaf, regs, regs+1, regs+2, regs+3 ); +#endif +} + +static void InitFailure( const char* msg ) +{ +#if defined _WIN32 + bool hasConsole = false; + bool reopen = false; + const auto attached = AttachConsole( ATTACH_PARENT_PROCESS ); + if( attached ) + { + hasConsole = true; + reopen = true; + } + else + { + const auto err = GetLastError(); + if( err == ERROR_ACCESS_DENIED ) + { + hasConsole = true; + } + } + if( hasConsole ) + { + fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg ); + if( reopen ) + { + freopen( "CONOUT$", "w", stderr ); + fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg ); + } + } + else + { +# ifndef TRACY_UWP + MessageBoxA( nullptr, msg, "Tracy Profiler initialization failure", MB_ICONSTOP ); +# endif + } +#else + fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg ); +#endif + exit( 1 ); +} + +static bool CheckHardwareSupportsInvariantTSC() +{ + const char* noCheck = GetEnvVar( "TRACY_NO_INVARIANT_CHECK" ); + if( noCheck && noCheck[0] == '1' ) return true; + + uint32_t regs[4]; + CpuId( regs, 1 ); + if( !( regs[3] & ( 1 << 4 ) ) ) + { +#if !defined TRACY_TIMER_QPC && !defined TRACY_TIMER_FALLBACK + InitFailure( "CPU doesn't support RDTSC instruction." ); +#else + return false; +#endif + } + CpuId( regs, 0x80000007 ); + if( regs[3] & ( 1 << 8 ) ) return true; + + return false; +} + +#if defined TRACY_TIMER_FALLBACK && defined TRACY_HW_TIMER +bool HardwareSupportsInvariantTSC() +{ + static bool cachedResult = CheckHardwareSupportsInvariantTSC(); + return cachedResult; +} +#endif + +static int64_t SetupHwTimer() +{ +#if !defined TRACY_TIMER_QPC && !defined TRACY_TIMER_FALLBACK + if( !CheckHardwareSupportsInvariantTSC() ) + { +#if defined _WIN32 + InitFailure( "CPU doesn't support invariant TSC.\nDefine TRACY_NO_INVARIANT_CHECK=1 to ignore this error, *if you know what you are doing*.\nAlternatively you may rebuild the application with the TRACY_TIMER_QPC or TRACY_TIMER_FALLBACK define to use lower resolution timer." ); +#else + InitFailure( "CPU doesn't support invariant TSC.\nDefine TRACY_NO_INVARIANT_CHECK=1 to ignore this error, *if you know what you are doing*.\nAlternatively you may rebuild the application with the TRACY_TIMER_FALLBACK define to use lower resolution timer." ); +#endif + } +#endif + + return Profiler::GetTime(); +} +#else +static int64_t SetupHwTimer() +{ + return Profiler::GetTime(); +} +#endif + +static const char* GetProcessName() +{ + const char* processName = "unknown"; +#ifdef _WIN32 + static char buf[_MAX_PATH]; + GetModuleFileNameA( nullptr, buf, _MAX_PATH ); + const char* ptr = buf; + while( *ptr != '\0' ) ptr++; + while( ptr > buf && *ptr != '\\' && *ptr != '/' ) ptr--; + if( ptr > buf ) ptr++; + processName = ptr; +#elif defined __ANDROID__ +# if __ANDROID_API__ >= 21 + auto buf = getprogname(); + if( buf ) processName = buf; +# endif +#elif defined __linux__ && defined _GNU_SOURCE + if( program_invocation_short_name ) processName = program_invocation_short_name; +#elif defined __APPLE__ || defined BSD + auto buf = getprogname(); + if( buf ) processName = buf; +#endif + return processName; +} + +static const char* GetProcessExecutablePath() +{ +#ifdef _WIN32 + static char buf[_MAX_PATH]; + GetModuleFileNameA( nullptr, buf, _MAX_PATH ); + return buf; +#elif defined __ANDROID__ + return nullptr; +#elif defined __linux__ && defined _GNU_SOURCE + return program_invocation_name; +#elif defined __APPLE__ + static char buf[1024]; + uint32_t size = 1024; + _NSGetExecutablePath( buf, &size ); + return buf; +#elif defined __DragonFly__ + static char buf[1024]; + readlink( "/proc/curproc/file", buf, 1024 ); + return buf; +#elif defined __FreeBSD__ + static char buf[1024]; + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + size_t cb = 1024; + sysctl( mib, 4, buf, &cb, nullptr, 0 ); + return buf; +#elif defined __NetBSD__ + static char buf[1024]; + readlink( "/proc/curproc/exe", buf, 1024 ); + return buf; +#else + return nullptr; +#endif +} + +#if defined __linux__ && defined __ARM_ARCH +static uint32_t GetHex( char*& ptr, int skip ) +{ + uint32_t ret; + ptr += skip; + char* end; + if( ptr[0] == '0' && ptr[1] == 'x' ) + { + ptr += 2; + ret = strtol( ptr, &end, 16 ); + } + else + { + ret = strtol( ptr, &end, 10 ); + } + ptr = end; + return ret; +} +#endif + +static const char* GetHostInfo() +{ + static char buf[1024]; + auto ptr = buf; +#if defined _WIN32 +# ifdef TRACY_UWP + auto GetVersion = &::GetVersionEx; +# else + auto GetVersion = (t_RtlGetVersion)GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "RtlGetVersion" ); +# endif + if( !GetVersion ) + { +# ifdef __MINGW32__ + ptr += sprintf( ptr, "OS: Windows (MingW)\n" ); +# else + ptr += sprintf( ptr, "OS: Windows\n" ); +# endif + } + else + { + RTL_OSVERSIONINFOW ver = { sizeof( RTL_OSVERSIONINFOW ) }; + GetVersion( &ver ); + +# ifdef __MINGW32__ + ptr += sprintf( ptr, "OS: Windows %i.%i.%i (MingW)\n", (int)ver.dwMajorVersion, (int)ver.dwMinorVersion, (int)ver.dwBuildNumber ); +# else + ptr += sprintf( ptr, "OS: Windows %i.%i.%i\n", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber ); +# endif + } +#elif defined __linux__ + struct utsname utsName; + uname( &utsName ); +# if defined __ANDROID__ + ptr += sprintf( ptr, "OS: Linux %s (Android)\n", utsName.release ); +# else + ptr += sprintf( ptr, "OS: Linux %s\n", utsName.release ); +# endif +#elif defined __APPLE__ +# if TARGET_OS_IPHONE == 1 + ptr += sprintf( ptr, "OS: Darwin (iOS)\n" ); +# elif TARGET_OS_MAC == 1 + ptr += sprintf( ptr, "OS: Darwin (OSX)\n" ); +# else + ptr += sprintf( ptr, "OS: Darwin (unknown)\n" ); +# endif +#elif defined __DragonFly__ + ptr += sprintf( ptr, "OS: BSD (DragonFly)\n" ); +#elif defined __FreeBSD__ + ptr += sprintf( ptr, "OS: BSD (FreeBSD)\n" ); +#elif defined __NetBSD__ + ptr += sprintf( ptr, "OS: BSD (NetBSD)\n" ); +#elif defined __OpenBSD__ + ptr += sprintf( ptr, "OS: BSD (OpenBSD)\n" ); +#else + ptr += sprintf( ptr, "OS: unknown\n" ); +#endif + +#if defined _MSC_VER +# if defined __clang__ + ptr += sprintf( ptr, "Compiler: MSVC clang-cl %i.%i.%i\n", __clang_major__, __clang_minor__, __clang_patchlevel__ ); +# else + ptr += sprintf( ptr, "Compiler: MSVC %i\n", _MSC_VER ); +# endif +#elif defined __clang__ + ptr += sprintf( ptr, "Compiler: clang %i.%i.%i\n", __clang_major__, __clang_minor__, __clang_patchlevel__ ); +#elif defined __GNUC__ + ptr += sprintf( ptr, "Compiler: gcc %i.%i.%i\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ ); +#else + ptr += sprintf( ptr, "Compiler: unknown\n" ); +#endif + +#if defined _WIN32 + InitWinSock(); + + char hostname[512]; + gethostname( hostname, 512 ); + +# ifdef TRACY_UWP + const char* user = ""; +# else + DWORD userSz = UNLEN+1; + char user[UNLEN+1]; + GetUserNameA( user, &userSz ); +# endif + + ptr += sprintf( ptr, "User: %s@%s\n", user, hostname ); +#else + char hostname[_POSIX_HOST_NAME_MAX]{}; + char user[_POSIX_LOGIN_NAME_MAX]{}; + + gethostname( hostname, _POSIX_HOST_NAME_MAX ); +# if defined __ANDROID__ + const auto login = getlogin(); + if( login ) + { + strcpy( user, login ); + } + else + { + memcpy( user, "(?)", 4 ); + } +# else + getlogin_r( user, _POSIX_LOGIN_NAME_MAX ); +# endif + + ptr += sprintf( ptr, "User: %s@%s\n", user, hostname ); +#endif + +#if defined __i386 || defined _M_IX86 + ptr += sprintf( ptr, "Arch: x86\n" ); +#elif defined __x86_64__ || defined _M_X64 + ptr += sprintf( ptr, "Arch: x64\n" ); +#elif defined __aarch64__ + ptr += sprintf( ptr, "Arch: ARM64\n" ); +#elif defined __ARM_ARCH + ptr += sprintf( ptr, "Arch: ARM\n" ); +#else + ptr += sprintf( ptr, "Arch: unknown\n" ); +#endif + +#if defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 + uint32_t regs[4]; + char cpuModel[4*4*3+1] = {}; + auto modelPtr = cpuModel; + for( uint32_t i=0x80000002; i<0x80000005; ++i ) + { + CpuId( regs, i ); + memcpy( modelPtr, regs, sizeof( regs ) ); modelPtr += sizeof( regs ); + } + + ptr += sprintf( ptr, "CPU: %s\n", cpuModel ); +#elif defined __linux__ && defined __ARM_ARCH + bool cpuFound = false; + FILE* fcpuinfo = fopen( "/proc/cpuinfo", "rb" ); + if( fcpuinfo ) + { + enum { BufSize = 4*1024 }; + char buf[BufSize]; + const auto sz = fread( buf, 1, BufSize, fcpuinfo ); + fclose( fcpuinfo ); + const auto end = buf + sz; + auto cptr = buf; + + uint32_t impl = 0; + uint32_t var = 0; + uint32_t part = 0; + uint32_t rev = 0; + + while( end - cptr > 20 ) + { + while( end - cptr > 20 && memcmp( cptr, "CPU ", 4 ) != 0 ) + { + cptr += 4; + while( end - cptr > 20 && *cptr != '\n' ) cptr++; + cptr++; + } + if( end - cptr <= 20 ) break; + cptr += 4; + if( memcmp( cptr, "implementer\t: ", 14 ) == 0 ) + { + if( impl != 0 ) break; + impl = GetHex( cptr, 14 ); + } + else if( memcmp( cptr, "variant\t: ", 10 ) == 0 ) var = GetHex( cptr, 10 ); + else if( memcmp( cptr, "part\t: ", 7 ) == 0 ) part = GetHex( cptr, 7 ); + else if( memcmp( cptr, "revision\t: ", 11 ) == 0 ) rev = GetHex( cptr, 11 ); + while( *cptr != '\n' && *cptr != '\0' ) cptr++; + cptr++; + } + + if( impl != 0 || var != 0 || part != 0 || rev != 0 ) + { + cpuFound = true; + ptr += sprintf( ptr, "CPU: %s%s r%ip%i\n", DecodeArmImplementer( impl ), DecodeArmPart( impl, part ), var, rev ); + } + } + if( !cpuFound ) + { + ptr += sprintf( ptr, "CPU: unknown\n" ); + } +#elif defined __APPLE__ && TARGET_OS_IPHONE == 1 + { + size_t sz; + sysctlbyname( "hw.machine", nullptr, &sz, nullptr, 0 ); + auto str = (char*)tracy_malloc( sz ); + sysctlbyname( "hw.machine", str, &sz, nullptr, 0 ); + ptr += sprintf( ptr, "Device: %s\n", DecodeIosDevice( str ) ); + tracy_free( str ); + } +#else + ptr += sprintf( ptr, "CPU: unknown\n" ); +#endif +#ifdef __ANDROID__ + char deviceModel[PROP_VALUE_MAX+1]; + char deviceManufacturer[PROP_VALUE_MAX+1]; + __system_property_get( "ro.product.model", deviceModel ); + __system_property_get( "ro.product.manufacturer", deviceManufacturer ); + ptr += sprintf( ptr, "Device: %s %s\n", deviceManufacturer, deviceModel ); +#endif + + ptr += sprintf( ptr, "CPU cores: %i\n", std::thread::hardware_concurrency() ); + +#if defined _WIN32 + MEMORYSTATUSEX statex; + statex.dwLength = sizeof( statex ); + GlobalMemoryStatusEx( &statex ); +# ifdef _MSC_VER + ptr += sprintf( ptr, "RAM: %I64u MB\n", statex.ullTotalPhys / 1024 / 1024 ); +# else + ptr += sprintf( ptr, "RAM: %llu MB\n", statex.ullTotalPhys / 1024 / 1024 ); +# endif +#elif defined __linux__ + struct sysinfo sysInfo; + sysinfo( &sysInfo ); + ptr += sprintf( ptr, "RAM: %lu MB\n", sysInfo.totalram / 1024 / 1024 ); +#elif defined __APPLE__ + size_t memSize; + size_t sz = sizeof( memSize ); + sysctlbyname( "hw.memsize", &memSize, &sz, nullptr, 0 ); + ptr += sprintf( ptr, "RAM: %zu MB\n", memSize / 1024 / 1024 ); +#elif defined BSD + size_t memSize; + size_t sz = sizeof( memSize ); + sysctlbyname( "hw.physmem", &memSize, &sz, nullptr, 0 ); + ptr += sprintf( ptr, "RAM: %zu MB\n", memSize / 1024 / 1024 ); +#else + ptr += sprintf( ptr, "RAM: unknown\n" ); +#endif + + return buf; +} + +static uint64_t GetPid() +{ +#if defined _WIN32 + return uint64_t( GetCurrentProcessId() ); +#else + return uint64_t( getpid() ); +#endif +} + +void Profiler::AckServerQuery() +{ + QueueItem item; + MemWrite( &item.hdr.type, QueueType::AckServerQueryNoop ); + NeedDataSize( QueueDataSize[(int)QueueType::AckServerQueryNoop] ); + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::AckServerQueryNoop] ); +} + +void Profiler::AckSymbolCodeNotAvailable() +{ + QueueItem item; + MemWrite( &item.hdr.type, QueueType::AckSymbolCodeNotAvailable ); + NeedDataSize( QueueDataSize[(int)QueueType::AckSymbolCodeNotAvailable] ); + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::AckSymbolCodeNotAvailable] ); +} + +static BroadcastMessage& GetBroadcastMessage( const char* procname, size_t pnsz, int& len, int port ) +{ + static BroadcastMessage msg; + + msg.broadcastVersion = BroadcastVersion; + msg.protocolVersion = ProtocolVersion; + msg.listenPort = port; + msg.pid = GetPid(); + + memcpy( msg.programName, procname, pnsz ); + memset( msg.programName + pnsz, 0, WelcomeMessageProgramNameSize - pnsz ); + + len = int( offsetof( BroadcastMessage, programName ) + pnsz + 1 ); + return msg; +} + +#if defined _WIN32 && !defined TRACY_UWP && !defined TRACY_NO_CRASH_HANDLER +static DWORD s_profilerThreadId = 0; +static DWORD s_symbolThreadId = 0; +static char s_crashText[1024]; + +LONG WINAPI CrashFilter( PEXCEPTION_POINTERS pExp ) +{ + if( !GetProfiler().IsConnected() ) return EXCEPTION_CONTINUE_SEARCH; + + const unsigned ec = pExp->ExceptionRecord->ExceptionCode; + auto msgPtr = s_crashText; + switch( ec ) + { + case EXCEPTION_ACCESS_VIOLATION: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_ACCESS_VIOLATION (0x%x). ", ec ); + switch( pExp->ExceptionRecord->ExceptionInformation[0] ) + { + case 0: + msgPtr += sprintf( msgPtr, "Read violation at address 0x%" PRIxPTR ".", pExp->ExceptionRecord->ExceptionInformation[1] ); + break; + case 1: + msgPtr += sprintf( msgPtr, "Write violation at address 0x%" PRIxPTR ".", pExp->ExceptionRecord->ExceptionInformation[1] ); + break; + case 8: + msgPtr += sprintf( msgPtr, "DEP violation at address 0x%" PRIxPTR ".", pExp->ExceptionRecord->ExceptionInformation[1] ); + break; + default: + break; + } + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED (0x%x). ", ec ); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_DATATYPE_MISALIGNMENT (0x%x). ", ec ); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_FLT_DIVIDE_BY_ZERO (0x%x). ", ec ); + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_ILLEGAL_INSTRUCTION (0x%x). ", ec ); + break; + case EXCEPTION_IN_PAGE_ERROR: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_IN_PAGE_ERROR (0x%x). ", ec ); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_INT_DIVIDE_BY_ZERO (0x%x). ", ec ); + break; + case EXCEPTION_PRIV_INSTRUCTION: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_PRIV_INSTRUCTION (0x%x). ", ec ); + break; + case EXCEPTION_STACK_OVERFLOW: + msgPtr += sprintf( msgPtr, "Exception EXCEPTION_STACK_OVERFLOW (0x%x). ", ec ); + break; + default: + return EXCEPTION_CONTINUE_SEARCH; + } + + { + GetProfiler().SendCallstack( 60, "KiUserExceptionDispatcher" ); + + TracyQueuePrepare( QueueType::CrashReport ); + item->crashReport.time = Profiler::GetTime(); + item->crashReport.text = (uint64_t)s_crashText; + TracyQueueCommit( crashReportThread ); + } + + HANDLE h = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); + if( h == INVALID_HANDLE_VALUE ) return EXCEPTION_CONTINUE_SEARCH; + + THREADENTRY32 te = { sizeof( te ) }; + if( !Thread32First( h, &te ) ) + { + CloseHandle( h ); + return EXCEPTION_CONTINUE_SEARCH; + } + + const auto pid = GetCurrentProcessId(); + const auto tid = GetCurrentThreadId(); + + do + { + if( te.th32OwnerProcessID == pid && te.th32ThreadID != tid && te.th32ThreadID != s_profilerThreadId && te.th32ThreadID != s_symbolThreadId ) + { + HANDLE th = OpenThread( THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID ); + if( th != INVALID_HANDLE_VALUE ) + { + SuspendThread( th ); + CloseHandle( th ); + } + } + } + while( Thread32Next( h, &te ) ); + CloseHandle( h ); + + { + TracyLfqPrepare( QueueType::Crash ); + TracyLfqCommit; + } + + std::this_thread::sleep_for( std::chrono::milliseconds( 500 ) ); + GetProfiler().RequestShutdown(); + while( !GetProfiler().HasShutdownFinished() ) { std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); }; + + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + +static Profiler* s_instance = nullptr; +static Thread* s_thread; +#ifndef TRACY_NO_FRAME_IMAGE +static Thread* s_compressThread; +#endif +#ifdef TRACY_HAS_CALLSTACK +static Thread* s_symbolThread; +std::atomic s_symbolThreadGone { false }; +#endif +#ifdef TRACY_HAS_SYSTEM_TRACING +static Thread* s_sysTraceThread = nullptr; +#endif + +#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER +# ifndef TRACY_CRASH_SIGNAL +# define TRACY_CRASH_SIGNAL SIGPWR +# endif + +static long s_profilerTid = 0; +static long s_symbolTid = 0; +static char s_crashText[1024]; +static std::atomic s_alreadyCrashed( false ); + +static void ThreadFreezer( int /*signal*/ ) +{ + for(;;) sleep( 1000 ); +} + +static inline void HexPrint( char*& ptr, uint64_t val ) +{ + if( val == 0 ) + { + *ptr++ = '0'; + return; + } + + static const char HexTable[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + char buf[16]; + auto bptr = buf; + + do + { + *bptr++ = HexTable[val%16]; + val /= 16; + } + while( val > 0 ); + + do + { + *ptr++ = *--bptr; + } + while( bptr != buf ); +} + +static void CrashHandler( int signal, siginfo_t* info, void* /*ucontext*/ ) +{ + bool expected = false; + if( !s_alreadyCrashed.compare_exchange_strong( expected, true ) ) ThreadFreezer( signal ); + + struct sigaction act = {}; + act.sa_handler = SIG_DFL; + sigaction( SIGABRT, &act, nullptr ); + + auto msgPtr = s_crashText; + switch( signal ) + { + case SIGILL: + strcpy( msgPtr, "Illegal Instruction.\n" ); + while( *msgPtr ) msgPtr++; + switch( info->si_code ) + { + case ILL_ILLOPC: + strcpy( msgPtr, "Illegal opcode.\n" ); + break; + case ILL_ILLOPN: + strcpy( msgPtr, "Illegal operand.\n" ); + break; + case ILL_ILLADR: + strcpy( msgPtr, "Illegal addressing mode.\n" ); + break; + case ILL_ILLTRP: + strcpy( msgPtr, "Illegal trap.\n" ); + break; + case ILL_PRVOPC: + strcpy( msgPtr, "Privileged opcode.\n" ); + break; + case ILL_PRVREG: + strcpy( msgPtr, "Privileged register.\n" ); + break; + case ILL_COPROC: + strcpy( msgPtr, "Coprocessor error.\n" ); + break; + case ILL_BADSTK: + strcpy( msgPtr, "Internal stack error.\n" ); + break; + default: + break; + } + break; + case SIGFPE: + strcpy( msgPtr, "Floating-point exception.\n" ); + while( *msgPtr ) msgPtr++; + switch( info->si_code ) + { + case FPE_INTDIV: + strcpy( msgPtr, "Integer divide by zero.\n" ); + break; + case FPE_INTOVF: + strcpy( msgPtr, "Integer overflow.\n" ); + break; + case FPE_FLTDIV: + strcpy( msgPtr, "Floating-point divide by zero.\n" ); + break; + case FPE_FLTOVF: + strcpy( msgPtr, "Floating-point overflow.\n" ); + break; + case FPE_FLTUND: + strcpy( msgPtr, "Floating-point underflow.\n" ); + break; + case FPE_FLTRES: + strcpy( msgPtr, "Floating-point inexact result.\n" ); + break; + case FPE_FLTINV: + strcpy( msgPtr, "Floating-point invalid operation.\n" ); + break; + case FPE_FLTSUB: + strcpy( msgPtr, "Subscript out of range.\n" ); + break; + default: + break; + } + break; + case SIGSEGV: + strcpy( msgPtr, "Invalid memory reference.\n" ); + while( *msgPtr ) msgPtr++; + switch( info->si_code ) + { + case SEGV_MAPERR: + strcpy( msgPtr, "Address not mapped to object.\n" ); + break; + case SEGV_ACCERR: + strcpy( msgPtr, "Invalid permissions for mapped object.\n" ); + break; +# ifdef SEGV_BNDERR + case SEGV_BNDERR: + strcpy( msgPtr, "Failed address bound checks.\n" ); + break; +# endif +# ifdef SEGV_PKUERR + case SEGV_PKUERR: + strcpy( msgPtr, "Access was denied by memory protection keys.\n" ); + break; +# endif + default: + break; + } + break; + case SIGPIPE: + strcpy( msgPtr, "Broken pipe.\n" ); + while( *msgPtr ) msgPtr++; + break; + case SIGBUS: + strcpy( msgPtr, "Bus error.\n" ); + while( *msgPtr ) msgPtr++; + switch( info->si_code ) + { + case BUS_ADRALN: + strcpy( msgPtr, "Invalid address alignment.\n" ); + break; + case BUS_ADRERR: + strcpy( msgPtr, "Nonexistent physical address.\n" ); + break; + case BUS_OBJERR: + strcpy( msgPtr, "Object-specific hardware error.\n" ); + break; +# ifdef BUS_MCEERR_AR + case BUS_MCEERR_AR: + strcpy( msgPtr, "Hardware memory error consumed on a machine check; action required.\n" ); + break; +# endif +# ifdef BUS_MCEERR_AO + case BUS_MCEERR_AO: + strcpy( msgPtr, "Hardware memory error detected in process but not consumed; action optional.\n" ); + break; +# endif + default: + break; + } + break; + case SIGABRT: + strcpy( msgPtr, "Abort signal from abort().\n" ); + break; + default: + abort(); + } + while( *msgPtr ) msgPtr++; + + if( signal != SIGPIPE ) + { + strcpy( msgPtr, "Fault address: 0x" ); + while( *msgPtr ) msgPtr++; + HexPrint( msgPtr, uint64_t( info->si_addr ) ); + *msgPtr++ = '\n'; + } + + { + GetProfiler().SendCallstack( 60, "__kernel_rt_sigreturn" ); + + TracyQueuePrepare( QueueType::CrashReport ); + item->crashReport.time = Profiler::GetTime(); + item->crashReport.text = (uint64_t)s_crashText; + TracyQueueCommit( crashReportThread ); + } + + DIR* dp = opendir( "/proc/self/task" ); + if( !dp ) abort(); + + const auto selfTid = syscall( SYS_gettid ); + + struct dirent* ep; + while( ( ep = readdir( dp ) ) != nullptr ) + { + if( ep->d_name[0] == '.' ) continue; + int tid = atoi( ep->d_name ); + if( tid != selfTid && tid != s_profilerTid && tid != s_symbolTid ) + { + syscall( SYS_tkill, tid, TRACY_CRASH_SIGNAL ); + } + } + closedir( dp ); + +#ifdef TRACY_HAS_CALLSTACK + if( selfTid == s_symbolTid ) s_symbolThreadGone.store( true, std::memory_order_release ); +#endif + + TracyLfqPrepare( QueueType::Crash ); + TracyLfqCommit; + + std::this_thread::sleep_for( std::chrono::milliseconds( 500 ) ); + GetProfiler().RequestShutdown(); + while( !GetProfiler().HasShutdownFinished() ) { std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); }; + + abort(); +} +#endif + + +enum { QueuePrealloc = 256 * 1024 }; + +TRACY_API int64_t GetFrequencyQpc() +{ +#if defined _WIN32 + LARGE_INTEGER t; + QueryPerformanceFrequency( &t ); + return t.QuadPart; +#else + return 0; +#endif +} + +#ifdef TRACY_DELAYED_INIT +struct ThreadNameData; +TRACY_API moodycamel::ConcurrentQueue& GetQueue(); + +struct ProfilerData +{ + int64_t initTime = SetupHwTimer(); + moodycamel::ConcurrentQueue queue; + Profiler profiler; + std::atomic lockCounter { 0 }; + std::atomic gpuCtxCounter { 0 }; + std::atomic threadNameData { nullptr }; +}; + +struct ProducerWrapper +{ + ProducerWrapper( ProfilerData& data ) : detail( data.queue ), ptr( data.queue.get_explicit_producer( detail ) ) {} + moodycamel::ProducerToken detail; + tracy::moodycamel::ConcurrentQueue::ExplicitProducer* ptr; +}; + +struct ProfilerThreadData +{ + ProfilerThreadData( ProfilerData& data ) : token( data ), gpuCtx( { nullptr } ) {} + ProducerWrapper token; + GpuCtxWrapper gpuCtx; +# ifdef TRACY_ON_DEMAND + LuaZoneState luaZoneState; +# endif +}; + +std::atomic RpInitDone { 0 }; +std::atomic RpInitLock { 0 }; +thread_local bool RpThreadInitDone = false; +thread_local bool RpThreadShutdown = false; + +# ifdef TRACY_MANUAL_LIFETIME +ProfilerData* s_profilerData = nullptr; +static ProfilerThreadData& GetProfilerThreadData(); +TRACY_API void StartupProfiler() +{ + s_profilerData = (ProfilerData*)tracy_malloc( sizeof( ProfilerData ) ); + new (s_profilerData) ProfilerData(); + s_profilerData->profiler.SpawnWorkerThreads(); + GetProfilerThreadData().token = ProducerWrapper( *s_profilerData ); +} +static ProfilerData& GetProfilerData() +{ + assert( s_profilerData ); + return *s_profilerData; +} +TRACY_API void ShutdownProfiler() +{ + s_profilerData->~ProfilerData(); + tracy_free( s_profilerData ); + s_profilerData = nullptr; + rpmalloc_finalize(); + RpThreadInitDone = false; + RpInitDone.store( 0, std::memory_order_release ); +} +# else +static std::atomic profilerDataLock { 0 }; +static std::atomic profilerData { nullptr }; + +static ProfilerData& GetProfilerData() +{ + auto ptr = profilerData.load( std::memory_order_acquire ); + if( !ptr ) + { + int expected = 0; + while( !profilerDataLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); } + ptr = profilerData.load( std::memory_order_acquire ); + if( !ptr ) + { + ptr = (ProfilerData*)tracy_malloc( sizeof( ProfilerData ) ); + new (ptr) ProfilerData(); + profilerData.store( ptr, std::memory_order_release ); + } + profilerDataLock.store( 0, std::memory_order_release ); + } + return *ptr; +} +# endif + +// GCC prior to 8.4 had a bug with function-inline thread_local variables. Versions of glibc beginning with +// 2.18 may attempt to work around this issue, which manifests as a crash while running static destructors +// if this function is compiled into a shared object. Unfortunately, centos7 ships with glibc 2.17. If running +// on old GCC, use the old-fashioned way as a workaround +// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85400 +#if !defined(__clang__) && defined(__GNUC__) && ((__GNUC__ < 8) || ((__GNUC__ == 8) && (__GNUC_MINOR__ < 4))) +struct ProfilerThreadDataKey +{ +public: + ProfilerThreadDataKey() + { + int val = pthread_key_create(&m_key, sDestructor); + static_cast(val); // unused + assert(val == 0); + } + ~ProfilerThreadDataKey() + { + int val = pthread_key_delete(m_key); + static_cast(val); // unused + assert(val == 0); + } + ProfilerThreadData& get() + { + void* p = pthread_getspecific(m_key); + if (!p) + { + p = (ProfilerThreadData*)tracy_malloc( sizeof( ProfilerThreadData ) ); + new (p) ProfilerThreadData(GetProfilerData()); + pthread_setspecific(m_key, p); + } + return *static_cast(p); + } +private: + pthread_key_t m_key; + + static void sDestructor(void* p) + { + ((ProfilerThreadData*)p)->~ProfilerThreadData(); + tracy_free(p); + } +}; + +static ProfilerThreadData& GetProfilerThreadData() +{ + static ProfilerThreadDataKey key; + return key.get(); +} +#else +static ProfilerThreadData& GetProfilerThreadData() +{ + thread_local ProfilerThreadData data( GetProfilerData() ); + return data; +} +#endif + +TRACY_API moodycamel::ConcurrentQueue::ExplicitProducer* GetToken() { return GetProfilerThreadData().token.ptr; } +TRACY_API Profiler& GetProfiler() { return GetProfilerData().profiler; } +TRACY_API moodycamel::ConcurrentQueue& GetQueue() { return GetProfilerData().queue; } +TRACY_API int64_t GetInitTime() { return GetProfilerData().initTime; } +TRACY_API std::atomic& GetLockCounter() { return GetProfilerData().lockCounter; } +TRACY_API std::atomic& GetGpuCtxCounter() { return GetProfilerData().gpuCtxCounter; } +TRACY_API GpuCtxWrapper& GetGpuCtx() { return GetProfilerThreadData().gpuCtx; } +TRACY_API uint32_t GetThreadHandle() { return detail::GetThreadHandleImpl(); } +std::atomic& GetThreadNameData() { return GetProfilerData().threadNameData; } + +# ifdef TRACY_ON_DEMAND +TRACY_API LuaZoneState& GetLuaZoneState() { return GetProfilerThreadData().luaZoneState; } +# endif + +# ifndef TRACY_MANUAL_LIFETIME +namespace +{ + const auto& __profiler_init = GetProfiler(); +} +# endif + +#else + +// MSVC static initialization order solution. gcc/clang uses init_order() to avoid all this. + +// 1a. But s_queue is needed for initialization of variables in point 2. +extern moodycamel::ConcurrentQueue s_queue; + +// 2. If these variables would be in the .CRT$XCB section, they would be initialized only in main thread. +thread_local moodycamel::ProducerToken init_order(107) s_token_detail( s_queue ); +thread_local ProducerWrapper init_order(108) s_token { s_queue.get_explicit_producer( s_token_detail ) }; +thread_local ThreadHandleWrapper init_order(104) s_threadHandle { detail::GetThreadHandleImpl() }; + +# ifdef _MSC_VER +// 1. Initialize these static variables before all other variables. +# pragma warning( disable : 4075 ) +# pragma init_seg( ".CRT$XCB" ) +# endif + +static InitTimeWrapper init_order(101) s_initTime { SetupHwTimer() }; +std::atomic init_order(102) RpInitDone( 0 ); +std::atomic init_order(102) RpInitLock( 0 ); +thread_local bool RpThreadInitDone = false; +thread_local bool RpThreadShutdown = false; +moodycamel::ConcurrentQueue init_order(103) s_queue( QueuePrealloc ); +std::atomic init_order(104) s_lockCounter( 0 ); +std::atomic init_order(104) s_gpuCtxCounter( 0 ); + +thread_local GpuCtxWrapper init_order(104) s_gpuCtx { nullptr }; + +struct ThreadNameData; +static std::atomic init_order(104) s_threadNameDataInstance( nullptr ); +std::atomic& s_threadNameData = s_threadNameDataInstance; + +# ifdef TRACY_ON_DEMAND +thread_local LuaZoneState init_order(104) s_luaZoneState { 0, false }; +# endif + +static Profiler init_order(105) s_profiler; + +TRACY_API moodycamel::ConcurrentQueue::ExplicitProducer* GetToken() { return s_token.ptr; } +TRACY_API Profiler& GetProfiler() { return s_profiler; } +TRACY_API moodycamel::ConcurrentQueue& GetQueue() { return s_queue; } +TRACY_API int64_t GetInitTime() { return s_initTime.val; } +TRACY_API std::atomic& GetLockCounter() { return s_lockCounter; } +TRACY_API std::atomic& GetGpuCtxCounter() { return s_gpuCtxCounter; } +TRACY_API GpuCtxWrapper& GetGpuCtx() { return s_gpuCtx; } +TRACY_API uint32_t GetThreadHandle() { return s_threadHandle.val; } + +std::atomic& GetThreadNameData() { return s_threadNameData; } + +# ifdef TRACY_ON_DEMAND +TRACY_API LuaZoneState& GetLuaZoneState() { return s_luaZoneState; } +# endif +#endif + +TRACY_API bool ProfilerAvailable() { return s_instance != nullptr; } +TRACY_API bool ProfilerAllocatorAvailable() { return !RpThreadShutdown; } + +Profiler::Profiler() + : m_timeBegin( 0 ) + , m_mainThread( detail::GetThreadHandleImpl() ) + , m_epoch( std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ).count() ) + , m_shutdown( false ) + , m_shutdownManual( false ) + , m_shutdownFinished( false ) + , m_sock( nullptr ) + , m_broadcast( nullptr ) + , m_noExit( false ) + , m_userPort( 0 ) + , m_zoneId( 1 ) + , m_samplingPeriod( 0 ) + , m_stream( LZ4_createStream() ) + , m_buffer( (char*)tracy_malloc( TargetFrameSize*3 ) ) + , m_bufferOffset( 0 ) + , m_bufferStart( 0 ) + , m_lz4Buf( (char*)tracy_malloc( LZ4Size + sizeof( lz4sz_t ) ) ) + , m_serialQueue( 1024*1024 ) + , m_serialDequeue( 1024*1024 ) +#ifndef TRACY_NO_FRAME_IMAGE + , m_fiQueue( 16 ) + , m_fiDequeue( 16 ) +#endif + , m_symbolQueue( 8*1024 ) + , m_frameCount( 0 ) + , m_isConnected( false ) +#ifdef TRACY_ON_DEMAND + , m_connectionId( 0 ) + , m_deferredQueue( 64*1024 ) +#endif + , m_paramCallback( nullptr ) + , m_sourceCallback( nullptr ) + , m_queryImage( nullptr ) + , m_queryData( nullptr ) + , m_crashHandlerInstalled( false ) + , m_programName( nullptr ) +{ + assert( !s_instance ); + s_instance = this; + +#ifndef TRACY_DELAYED_INIT +# ifdef _MSC_VER + // 3. But these variables need to be initialized in main thread within the .CRT$XCB section. Do it here. + s_token_detail = moodycamel::ProducerToken( s_queue ); + s_token = ProducerWrapper { s_queue.get_explicit_producer( s_token_detail ) }; + s_threadHandle = ThreadHandleWrapper { m_mainThread }; +# endif +#endif + + CalibrateTimer(); + CalibrateDelay(); + ReportTopology(); + +#ifndef TRACY_NO_EXIT + const char* noExitEnv = GetEnvVar( "TRACY_NO_EXIT" ); + if( noExitEnv && noExitEnv[0] == '1' ) + { + m_noExit = true; + } +#endif + + const char* userPort = GetEnvVar( "TRACY_PORT" ); + if( userPort ) + { + m_userPort = atoi( userPort ); + } + +#if !defined(TRACY_DELAYED_INIT) || !defined(TRACY_MANUAL_LIFETIME) + SpawnWorkerThreads(); +#endif +} + +void Profiler::SpawnWorkerThreads() +{ +#ifdef TRACY_HAS_SYSTEM_TRACING + if( SysTraceStart( m_samplingPeriod ) ) + { + s_sysTraceThread = (Thread*)tracy_malloc( sizeof( Thread ) ); + new(s_sysTraceThread) Thread( SysTraceWorker, nullptr ); + std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); + } +#endif + + s_thread = (Thread*)tracy_malloc( sizeof( Thread ) ); + new(s_thread) Thread( LaunchWorker, this ); + +#ifndef TRACY_NO_FRAME_IMAGE + s_compressThread = (Thread*)tracy_malloc( sizeof( Thread ) ); + new(s_compressThread) Thread( LaunchCompressWorker, this ); +#endif + +#ifdef TRACY_HAS_CALLSTACK + s_symbolThread = (Thread*)tracy_malloc( sizeof( Thread ) ); + new(s_symbolThread) Thread( LaunchSymbolWorker, this ); +#endif + +#if defined _WIN32 && !defined TRACY_UWP && !defined TRACY_NO_CRASH_HANDLER + s_profilerThreadId = GetThreadId( s_thread->Handle() ); +# ifdef TRACY_HAS_CALLSTACK + s_symbolThreadId = GetThreadId( s_symbolThread->Handle() ); +# endif + m_exceptionHandler = AddVectoredExceptionHandler( 1, CrashFilter ); +#endif + +#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER + struct sigaction threadFreezer = {}; + threadFreezer.sa_handler = ThreadFreezer; + sigaction( TRACY_CRASH_SIGNAL, &threadFreezer, &m_prevSignal.pwr ); + + struct sigaction crashHandler = {}; + crashHandler.sa_sigaction = CrashHandler; + crashHandler.sa_flags = SA_SIGINFO; + sigaction( SIGILL, &crashHandler, &m_prevSignal.ill ); + sigaction( SIGFPE, &crashHandler, &m_prevSignal.fpe ); + sigaction( SIGSEGV, &crashHandler, &m_prevSignal.segv ); + sigaction( SIGPIPE, &crashHandler, &m_prevSignal.pipe ); + sigaction( SIGBUS, &crashHandler, &m_prevSignal.bus ); + sigaction( SIGABRT, &crashHandler, &m_prevSignal.abrt ); +#endif + +#ifndef TRACY_NO_CRASH_HANDLER + m_crashHandlerInstalled = true; +#endif + +#ifdef TRACY_HAS_CALLSTACK + InitCallstackCritical(); +#endif + + m_timeBegin.store( GetTime(), std::memory_order_relaxed ); +} + +Profiler::~Profiler() +{ + m_shutdown.store( true, std::memory_order_relaxed ); + +#if defined _WIN32 && !defined TRACY_UWP + if( m_crashHandlerInstalled ) RemoveVectoredExceptionHandler( m_exceptionHandler ); +#endif + +#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER + if( m_crashHandlerInstalled ) + { + sigaction( TRACY_CRASH_SIGNAL, &m_prevSignal.pwr, nullptr ); + sigaction( SIGILL, &m_prevSignal.ill, nullptr ); + sigaction( SIGFPE, &m_prevSignal.fpe, nullptr ); + sigaction( SIGSEGV, &m_prevSignal.segv, nullptr ); + sigaction( SIGPIPE, &m_prevSignal.pipe, nullptr ); + sigaction( SIGBUS, &m_prevSignal.bus, nullptr ); + sigaction( SIGABRT, &m_prevSignal.abrt, nullptr ); + } +#endif + +#ifdef TRACY_HAS_SYSTEM_TRACING + if( s_sysTraceThread ) + { + SysTraceStop(); + s_sysTraceThread->~Thread(); + tracy_free( s_sysTraceThread ); + } +#endif + +#ifdef TRACY_HAS_CALLSTACK + s_symbolThread->~Thread(); + tracy_free( s_symbolThread ); +#endif + +#ifndef TRACY_NO_FRAME_IMAGE + s_compressThread->~Thread(); + tracy_free( s_compressThread ); +#endif + + s_thread->~Thread(); + tracy_free( s_thread ); + +#ifdef TRACY_HAS_CALLSTACK + EndCallstack(); +#endif + + tracy_free( m_lz4Buf ); + tracy_free( m_buffer ); + LZ4_freeStream( (LZ4_stream_t*)m_stream ); + + if( m_sock ) + { + m_sock->~Socket(); + tracy_free( m_sock ); + } + + if( m_broadcast ) + { + m_broadcast->~UdpBroadcast(); + tracy_free( m_broadcast ); + } + + assert( s_instance ); + s_instance = nullptr; +} + +bool Profiler::ShouldExit() +{ + return s_instance->m_shutdown.load( std::memory_order_relaxed ); +} + +void Profiler::Worker() +{ +#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER + s_profilerTid = syscall( SYS_gettid ); +#endif + + ThreadExitHandler threadExitHandler; + + SetThreadName( "Tracy Profiler" ); + +#ifdef TRACY_DATA_PORT + const bool dataPortSearch = false; + auto dataPort = m_userPort != 0 ? m_userPort : TRACY_DATA_PORT; +#else + const bool dataPortSearch = m_userPort == 0; + auto dataPort = m_userPort != 0 ? m_userPort : 8086; +#endif +#ifdef TRACY_BROADCAST_PORT + const auto broadcastPort = TRACY_BROADCAST_PORT; +#else + const auto broadcastPort = 8086; +#endif + + while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + +#ifdef TRACY_USE_RPMALLOC + rpmalloc_thread_initialize(); +#endif + + m_exectime = 0; + const auto execname = GetProcessExecutablePath(); + if( execname ) + { + struct stat st; + if( stat( execname, &st ) == 0 ) + { + m_exectime = (uint64_t)st.st_mtime; + } + } + + const auto procname = GetProcessName(); + const auto pnsz = std::min( strlen( procname ), WelcomeMessageProgramNameSize - 1 ); + + const auto hostinfo = GetHostInfo(); + const auto hisz = std::min( strlen( hostinfo ), WelcomeMessageHostInfoSize - 1 ); + + const uint64_t pid = GetPid(); + + uint8_t flags = 0; + +#ifdef TRACY_ON_DEMAND + flags |= WelcomeFlag::OnDemand; +#endif +#ifdef __APPLE__ + flags |= WelcomeFlag::IsApple; +#endif +#ifndef TRACY_NO_CODE_TRANSFER + flags |= WelcomeFlag::CodeTransfer; +#endif +#ifdef _WIN32 + flags |= WelcomeFlag::CombineSamples; +# ifndef TRACY_NO_CONTEXT_SWITCH + flags |= WelcomeFlag::IdentifySamples; +# endif +#endif + +#if defined __i386 || defined _M_IX86 + uint8_t cpuArch = CpuArchX86; +#elif defined __x86_64__ || defined _M_X64 + uint8_t cpuArch = CpuArchX64; +#elif defined __aarch64__ + uint8_t cpuArch = CpuArchArm64; +#elif defined __ARM_ARCH + uint8_t cpuArch = CpuArchArm32; +#else + uint8_t cpuArch = CpuArchUnknown; +#endif + +#if defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 + uint32_t regs[4]; + char manufacturer[12]; + CpuId( regs, 0 ); + memcpy( manufacturer, regs+1, 4 ); + memcpy( manufacturer+4, regs+3, 4 ); + memcpy( manufacturer+8, regs+2, 4 ); + + CpuId( regs, 1 ); + uint32_t cpuId = ( regs[0] & 0xFFF ) | ( ( regs[0] & 0xFFF0000 ) >> 4 ); +#else + const char manufacturer[12] = {}; + uint32_t cpuId = 0; +#endif + + WelcomeMessage welcome; + MemWrite( &welcome.timerMul, m_timerMul ); + MemWrite( &welcome.initBegin, GetInitTime() ); + MemWrite( &welcome.initEnd, m_timeBegin.load( std::memory_order_relaxed ) ); + MemWrite( &welcome.delay, m_delay ); + MemWrite( &welcome.resolution, m_resolution ); + MemWrite( &welcome.epoch, m_epoch ); + MemWrite( &welcome.exectime, m_exectime ); + MemWrite( &welcome.pid, pid ); + MemWrite( &welcome.samplingPeriod, m_samplingPeriod ); + MemWrite( &welcome.flags, flags ); + MemWrite( &welcome.cpuArch, cpuArch ); + memcpy( welcome.cpuManufacturer, manufacturer, 12 ); + MemWrite( &welcome.cpuId, cpuId ); + memcpy( welcome.programName, procname, pnsz ); + memset( welcome.programName + pnsz, 0, WelcomeMessageProgramNameSize - pnsz ); + memcpy( welcome.hostInfo, hostinfo, hisz ); + memset( welcome.hostInfo + hisz, 0, WelcomeMessageHostInfoSize - hisz ); + + moodycamel::ConsumerToken token( GetQueue() ); + + ListenSocket listen; + bool isListening = false; + if( !dataPortSearch ) + { + isListening = listen.Listen( dataPort, 4 ); + } + else + { + for( uint32_t i=0; i<20; i++ ) + { + if( listen.Listen( dataPort+i, 4 ) ) + { + dataPort += i; + isListening = true; + break; + } + } + } + if( !isListening ) + { + for(;;) + { + if( ShouldExit() ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + + ClearQueues( token ); + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } + } + +#ifndef TRACY_NO_BROADCAST + m_broadcast = (UdpBroadcast*)tracy_malloc( sizeof( UdpBroadcast ) ); + new(m_broadcast) UdpBroadcast(); +# ifdef TRACY_ONLY_LOCALHOST + const char* addr = "127.255.255.255"; +# else + const char* addr = "255.255.255.255"; +# endif + if( !m_broadcast->Open( addr, broadcastPort ) ) + { + m_broadcast->~UdpBroadcast(); + tracy_free( m_broadcast ); + m_broadcast = nullptr; + } +#endif + + int broadcastLen = 0; + auto& broadcastMsg = GetBroadcastMessage( procname, pnsz, broadcastLen, dataPort ); + uint64_t lastBroadcast = 0; + + // Connections loop. + // Each iteration of the loop handles whole connection. Multiple iterations will only + // happen in the on-demand mode or when handshake fails. + for(;;) + { + // Wait for incoming connection + for(;;) + { +#ifndef TRACY_NO_EXIT + if( !m_noExit && ShouldExit() ) + { + if( m_broadcast ) + { + broadcastMsg.activeTime = -1; + m_broadcast->Send( broadcastPort, &broadcastMsg, broadcastLen ); + } + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } +#endif + m_sock = listen.Accept(); + if( m_sock ) break; +#ifndef TRACY_ON_DEMAND + ProcessSysTime(); +# ifdef TRACY_HAS_SYSPOWER + m_sysPower.Tick(); +# endif +#endif + + if( m_broadcast ) + { + const auto t = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + if( t - lastBroadcast > 3000000000 ) // 3s + { + m_programNameLock.lock(); + if( m_programName ) + { + broadcastMsg = GetBroadcastMessage( m_programName, strlen( m_programName ), broadcastLen, dataPort ); + m_programName = nullptr; + } + m_programNameLock.unlock(); + + lastBroadcast = t; + const auto ts = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ).count(); + broadcastMsg.activeTime = int32_t( ts - m_epoch ); + assert( broadcastMsg.activeTime >= 0 ); + m_broadcast->Send( broadcastPort, &broadcastMsg, broadcastLen ); + } + } + } + + if( m_broadcast ) + { + lastBroadcast = 0; + broadcastMsg.activeTime = -1; + m_broadcast->Send( broadcastPort, &broadcastMsg, broadcastLen ); + } + + // Handshake + { + char shibboleth[HandshakeShibbolethSize]; + auto res = m_sock->ReadRaw( shibboleth, HandshakeShibbolethSize, 2000 ); + if( !res || memcmp( shibboleth, HandshakeShibboleth, HandshakeShibbolethSize ) != 0 ) + { + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + continue; + } + + uint32_t protocolVersion; + res = m_sock->ReadRaw( &protocolVersion, sizeof( protocolVersion ), 2000 ); + if( !res ) + { + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + continue; + } + + if( protocolVersion != ProtocolVersion ) + { + HandshakeStatus status = HandshakeProtocolMismatch; + m_sock->Send( &status, sizeof( status ) ); + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + continue; + } + } + +#ifdef TRACY_ON_DEMAND + const auto currentTime = GetTime(); + ClearQueues( token ); + m_connectionId.fetch_add( 1, std::memory_order_release ); +#endif + m_isConnected.store( true, std::memory_order_release ); + + HandshakeStatus handshake = HandshakeWelcome; + m_sock->Send( &handshake, sizeof( handshake ) ); + + LZ4_resetStream( (LZ4_stream_t*)m_stream ); + m_sock->Send( &welcome, sizeof( welcome ) ); + + m_threadCtx = 0; + m_refTimeSerial = 0; + m_refTimeCtx = 0; + m_refTimeGpu = 0; + +#ifdef TRACY_ON_DEMAND + OnDemandPayloadMessage onDemand; + onDemand.frames = m_frameCount.load( std::memory_order_relaxed ); + onDemand.currentTime = currentTime; + + m_sock->Send( &onDemand, sizeof( onDemand ) ); + + m_deferredLock.lock(); + for( auto& item : m_deferredQueue ) + { + uint64_t ptr; + uint16_t size; + const auto idx = MemRead( &item.hdr.idx ); + switch( (QueueType)idx ) + { + case QueueType::MessageAppInfo: + ptr = MemRead( &item.messageFat.text ); + size = MemRead( &item.messageFat.size ); + SendSingleString( (const char*)ptr, size ); + break; + case QueueType::LockName: + ptr = MemRead( &item.lockNameFat.name ); + size = MemRead( &item.lockNameFat.size ); + SendSingleString( (const char*)ptr, size ); + break; + case QueueType::GpuContextName: + ptr = MemRead( &item.gpuContextNameFat.ptr ); + size = MemRead( &item.gpuContextNameFat.size ); + SendSingleString( (const char*)ptr, size ); + break; + default: + break; + } + AppendData( &item, QueueDataSize[idx] ); + } + m_deferredLock.unlock(); +#endif + + // Main communications loop + int keepAlive = 0; + for(;;) + { + ProcessSysTime(); +#ifdef TRACY_HAS_SYSPOWER + m_sysPower.Tick(); +#endif + const auto status = Dequeue( token ); + const auto serialStatus = DequeueSerial(); + if( status == DequeueStatus::ConnectionLost || serialStatus == DequeueStatus::ConnectionLost ) + { + break; + } + else if( status == DequeueStatus::QueueEmpty && serialStatus == DequeueStatus::QueueEmpty ) + { + if( ShouldExit() ) break; + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) break; + } + if( keepAlive == 500 ) + { + QueueItem ka; + ka.hdr.type = QueueType::KeepAlive; + AppendData( &ka, QueueDataSize[ka.hdr.idx] ); + if( !CommitData() ) break; + + keepAlive = 0; + } + else if( !m_sock->HasData() ) + { + keepAlive++; + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } + } + else + { + keepAlive = 0; + } + + bool connActive = true; + while( m_sock->HasData() ) + { + connActive = HandleServerQuery(); + if( !connActive ) break; + } + if( !connActive ) break; + } + if( ShouldExit() ) break; + + m_isConnected.store( false, std::memory_order_release ); +#ifdef TRACY_ON_DEMAND + m_bufferOffset = 0; + m_bufferStart = 0; +#endif + + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + +#ifndef TRACY_ON_DEMAND + // Client is no longer available here. Accept incoming connections, but reject handshake. + for(;;) + { + if( ShouldExit() ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + + ClearQueues( token ); + + m_sock = listen.Accept(); + if( m_sock ) + { + char shibboleth[HandshakeShibbolethSize]; + auto res = m_sock->ReadRaw( shibboleth, HandshakeShibbolethSize, 1000 ); + if( !res || memcmp( shibboleth, HandshakeShibboleth, HandshakeShibbolethSize ) != 0 ) + { + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + continue; + } + + uint32_t protocolVersion; + res = m_sock->ReadRaw( &protocolVersion, sizeof( protocolVersion ), 1000 ); + if( !res ) + { + m_sock->~Socket(); + tracy_free( m_sock ); + m_sock = nullptr; + continue; + } + + HandshakeStatus status = HandshakeNotAvailable; + m_sock->Send( &status, sizeof( status ) ); + m_sock->~Socket(); + tracy_free( m_sock ); + } + } +#endif + } + // End of connections loop + + // Wait for symbols thread to terminate. Symbol resolution will continue in this thread. +#ifdef TRACY_HAS_CALLSTACK + while( s_symbolThreadGone.load() == false ) { YieldThread(); } +#endif + + // Client is exiting. Send items remaining in queues. + for(;;) + { + const auto status = Dequeue( token ); + const auto serialStatus = DequeueSerial(); + if( status == DequeueStatus::ConnectionLost || serialStatus == DequeueStatus::ConnectionLost ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + else if( status == DequeueStatus::QueueEmpty && serialStatus == DequeueStatus::QueueEmpty ) + { + if( m_bufferOffset != m_bufferStart ) CommitData(); + break; + } + + while( m_sock->HasData() ) + { + if( !HandleServerQuery() ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + } + +#ifdef TRACY_HAS_CALLSTACK + for(;;) + { + auto si = m_symbolQueue.front(); + if( !si ) break; + HandleSymbolQueueItem( *si ); + m_symbolQueue.pop(); + } +#endif + } + + // Send client termination notice to the server + QueueItem terminate; + MemWrite( &terminate.hdr.type, QueueType::Terminate ); + if( !SendData( (const char*)&terminate, 1 ) ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + // Handle remaining server queries + for(;;) + { + while( m_sock->HasData() ) + { + if( !HandleServerQuery() ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + } +#ifdef TRACY_HAS_CALLSTACK + for(;;) + { + auto si = m_symbolQueue.front(); + if( !si ) break; + HandleSymbolQueueItem( *si ); + m_symbolQueue.pop(); + } +#endif + const auto status = Dequeue( token ); + const auto serialStatus = DequeueSerial(); + if( status == DequeueStatus::ConnectionLost || serialStatus == DequeueStatus::ConnectionLost ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } + } + } +} + +#ifndef TRACY_NO_FRAME_IMAGE +void Profiler::CompressWorker() +{ + ThreadExitHandler threadExitHandler; + SetThreadName( "Tracy DXT1" ); + while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + +#ifdef TRACY_USE_RPMALLOC + rpmalloc_thread_initialize(); +#endif + + for(;;) + { + const auto shouldExit = ShouldExit(); + + { + bool lockHeld = true; + while( !m_fiLock.try_lock() ) + { + if( m_shutdownManual.load( std::memory_order_relaxed ) ) + { + lockHeld = false; + break; + } + } + if( !m_fiQueue.empty() ) m_fiQueue.swap( m_fiDequeue ); + if( lockHeld ) + { + m_fiLock.unlock(); + } + } + + const auto sz = m_fiDequeue.size(); + if( sz > 0 ) + { + auto fi = m_fiDequeue.data(); + auto end = fi + sz; + while( fi != end ) + { + const auto w = fi->w; + const auto h = fi->h; + const auto csz = size_t( w * h / 2 ); + auto etc1buf = (char*)tracy_malloc( csz ); + CompressImageDxt1( (const char*)fi->image, etc1buf, w, h ); + tracy_free( fi->image ); + + TracyLfqPrepare( QueueType::FrameImage ); + MemWrite( &item->frameImageFat.image, (uint64_t)etc1buf ); + MemWrite( &item->frameImageFat.frame, fi->frame ); + MemWrite( &item->frameImageFat.w, w ); + MemWrite( &item->frameImageFat.h, h ); + uint8_t flip = fi->flip; + MemWrite( &item->frameImageFat.flip, flip ); + TracyLfqCommit; + + fi++; + } + m_fiDequeue.clear(); + } + else + { + std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) ); + } + + if( shouldExit ) + { + return; + } + } +} +#endif + +static void FreeAssociatedMemory( const QueueItem& item ) +{ + if( item.hdr.idx >= (int)QueueType::Terminate ) return; + + uint64_t ptr; + switch( item.hdr.type ) + { + case QueueType::ZoneText: + case QueueType::ZoneName: + ptr = MemRead( &item.zoneTextFat.text ); + tracy_free( (void*)ptr ); + break; + case QueueType::MessageColor: + case QueueType::MessageColorCallstack: + ptr = MemRead( &item.messageColorFat.text ); + tracy_free( (void*)ptr ); + break; + case QueueType::Message: + case QueueType::MessageCallstack: +#ifndef TRACY_ON_DEMAND + case QueueType::MessageAppInfo: +#endif + ptr = MemRead( &item.messageFat.text ); + tracy_free( (void*)ptr ); + break; + case QueueType::ZoneBeginAllocSrcLoc: + case QueueType::ZoneBeginAllocSrcLocCallstack: + ptr = MemRead( &item.zoneBegin.srcloc ); + tracy_free( (void*)ptr ); + break; + case QueueType::GpuZoneBeginAllocSrcLoc: + case QueueType::GpuZoneBeginAllocSrcLocCallstack: + case QueueType::GpuZoneBeginAllocSrcLocSerial: + case QueueType::GpuZoneBeginAllocSrcLocCallstackSerial: + ptr = MemRead( &item.gpuZoneBegin.srcloc ); + tracy_free( (void*)ptr ); + break; + case QueueType::CallstackSerial: + case QueueType::Callstack: + ptr = MemRead( &item.callstackFat.ptr ); + tracy_free( (void*)ptr ); + break; + case QueueType::CallstackAlloc: + ptr = MemRead( &item.callstackAllocFat.nativePtr ); + tracy_free( (void*)ptr ); + ptr = MemRead( &item.callstackAllocFat.ptr ); + tracy_free( (void*)ptr ); + break; + case QueueType::CallstackSample: + case QueueType::CallstackSampleContextSwitch: + ptr = MemRead( &item.callstackSampleFat.ptr ); + tracy_free( (void*)ptr ); + break; + case QueueType::FrameImage: + ptr = MemRead( &item.frameImageFat.image ); + tracy_free( (void*)ptr ); + break; +#ifdef TRACY_HAS_CALLSTACK + case QueueType::CallstackFrameSize: + { + InitRpmalloc(); + auto size = MemRead( &item.callstackFrameSizeFat.size ); + auto data = (const CallstackEntry*)MemRead( &item.callstackFrameSizeFat.data ); + for( uint8_t i=0; i( &item.symbolInformationFat.needFree ); + if( needFree ) + { + ptr = MemRead( &item.symbolInformationFat.fileString ); + tracy_free( (void*)ptr ); + } + break; + } + case QueueType::SymbolCodeMetadata: + ptr = MemRead( &item.symbolCodeMetadata.ptr ); + tracy_free( (void*)ptr ); + break; +#endif +#ifndef TRACY_ON_DEMAND + case QueueType::LockName: + ptr = MemRead( &item.lockNameFat.name ); + tracy_free( (void*)ptr ); + break; + case QueueType::GpuContextName: + ptr = MemRead( &item.gpuContextNameFat.ptr ); + tracy_free( (void*)ptr ); + break; +#endif +#ifdef TRACY_ON_DEMAND + case QueueType::MessageAppInfo: + case QueueType::GpuContextName: + // Don't free memory associated with deferred messages. + break; +#endif +#ifdef TRACY_HAS_SYSTEM_TRACING + case QueueType::ExternalNameMetadata: + ptr = MemRead( &item.externalNameMetadata.name ); + tracy_free( (void*)ptr ); + ptr = MemRead( &item.externalNameMetadata.threadName ); + tracy_free_fast( (void*)ptr ); + break; +#endif + case QueueType::SourceCodeMetadata: + ptr = MemRead( &item.sourceCodeMetadata.ptr ); + tracy_free( (void*)ptr ); + break; + default: + break; + } +} + +void Profiler::ClearQueues( moodycamel::ConsumerToken& token ) +{ + for(;;) + { + const auto sz = GetQueue().try_dequeue_bulk_single( token, [](const uint64_t&){}, []( QueueItem* item, size_t sz ) { assert( sz > 0 ); while( sz-- > 0 ) FreeAssociatedMemory( *item++ ); } ); + if( sz == 0 ) break; + } + + ClearSerial(); +} + +void Profiler::ClearSerial() +{ + bool lockHeld = true; + while( !m_serialLock.try_lock() ) + { + if( m_shutdownManual.load( std::memory_order_relaxed ) ) + { + lockHeld = false; + break; + } + } + for( auto& v : m_serialQueue ) FreeAssociatedMemory( v ); + m_serialQueue.clear(); + if( lockHeld ) + { + m_serialLock.unlock(); + } + + for( auto& v : m_serialDequeue ) FreeAssociatedMemory( v ); + m_serialDequeue.clear(); +} + +Profiler::DequeueStatus Profiler::Dequeue( moodycamel::ConsumerToken& token ) +{ + bool connectionLost = false; + const auto sz = GetQueue().try_dequeue_bulk_single( token, + [this, &connectionLost] ( const uint32_t& threadId ) + { + if( ThreadCtxCheck( threadId ) == ThreadCtxStatus::ConnectionLost ) connectionLost = true; + }, + [this, &connectionLost] ( QueueItem* item, size_t sz ) + { + if( connectionLost ) return; + InitRpmalloc(); + assert( sz > 0 ); + int64_t refThread = m_refTimeThread; + int64_t refCtx = m_refTimeCtx; + int64_t refGpu = m_refTimeGpu; + while( sz-- > 0 ) + { + uint64_t ptr; + uint16_t size; + auto idx = MemRead( &item->hdr.idx ); + if( idx < (int)QueueType::Terminate ) + { + switch( (QueueType)idx ) + { + case QueueType::ZoneText: + case QueueType::ZoneName: + ptr = MemRead( &item->zoneTextFat.text ); + size = MemRead( &item->zoneTextFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::Message: + case QueueType::MessageCallstack: + ptr = MemRead( &item->messageFat.text ); + size = MemRead( &item->messageFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::MessageColor: + case QueueType::MessageColorCallstack: + ptr = MemRead( &item->messageColorFat.text ); + size = MemRead( &item->messageColorFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::MessageAppInfo: + ptr = MemRead( &item->messageFat.text ); + size = MemRead( &item->messageFat.size ); + SendSingleString( (const char*)ptr, size ); +#ifndef TRACY_ON_DEMAND + tracy_free_fast( (void*)ptr ); +#endif + break; + case QueueType::ZoneBeginAllocSrcLoc: + case QueueType::ZoneBeginAllocSrcLocCallstack: + { + int64_t t = MemRead( &item->zoneBegin.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneBegin.time, dt ); + ptr = MemRead( &item->zoneBegin.srcloc ); + SendSourceLocationPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::Callstack: + ptr = MemRead( &item->callstackFat.ptr ); + SendCallstackPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::CallstackAlloc: + ptr = MemRead( &item->callstackAllocFat.nativePtr ); + if( ptr != 0 ) + { + CutCallstack( (void*)ptr, "lua_pcall" ); + SendCallstackPayload( ptr ); + tracy_free_fast( (void*)ptr ); + } + ptr = MemRead( &item->callstackAllocFat.ptr ); + SendCallstackAlloc( ptr ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::CallstackSample: + case QueueType::CallstackSampleContextSwitch: + { + ptr = MemRead( &item->callstackSampleFat.ptr ); + SendCallstackPayload64( ptr ); + tracy_free_fast( (void*)ptr ); + int64_t t = MemRead( &item->callstackSampleFat.time ); + int64_t dt = t - refCtx; + refCtx = t; + MemWrite( &item->callstackSampleFat.time, dt ); + break; + } + case QueueType::FrameImage: + { + ptr = MemRead( &item->frameImageFat.image ); + const auto w = MemRead( &item->frameImageFat.w ); + const auto h = MemRead( &item->frameImageFat.h ); + const auto csz = size_t( w * h / 2 ); + SendLongString( ptr, (const char*)ptr, csz, QueueType::FrameImageData ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::ZoneBegin: + case QueueType::ZoneBeginCallstack: + { + int64_t t = MemRead( &item->zoneBegin.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneBegin.time, dt ); + break; + } + case QueueType::ZoneEnd: + { + int64_t t = MemRead( &item->zoneEnd.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneEnd.time, dt ); + break; + } + case QueueType::GpuZoneBegin: + case QueueType::GpuZoneBeginCallstack: + { + int64_t t = MemRead( &item->gpuZoneBegin.cpuTime ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->gpuZoneBegin.cpuTime, dt ); + break; + } + case QueueType::GpuZoneBeginAllocSrcLoc: + case QueueType::GpuZoneBeginAllocSrcLocCallstack: + { + int64_t t = MemRead( &item->gpuZoneBegin.cpuTime ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->gpuZoneBegin.cpuTime, dt ); + ptr = MemRead( &item->gpuZoneBegin.srcloc ); + SendSourceLocationPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::GpuZoneEnd: + { + int64_t t = MemRead( &item->gpuZoneEnd.cpuTime ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->gpuZoneEnd.cpuTime, dt ); + break; + } + case QueueType::GpuContextName: + ptr = MemRead( &item->gpuContextNameFat.ptr ); + size = MemRead( &item->gpuContextNameFat.size ); + SendSingleString( (const char*)ptr, size ); +#ifndef TRACY_ON_DEMAND + tracy_free_fast( (void*)ptr ); +#endif + break; + case QueueType::PlotDataInt: + case QueueType::PlotDataFloat: + case QueueType::PlotDataDouble: + { + int64_t t = MemRead( &item->plotDataInt.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->plotDataInt.time, dt ); + break; + } + case QueueType::ContextSwitch: + { + int64_t t = MemRead( &item->contextSwitch.time ); + int64_t dt = t - refCtx; + refCtx = t; + MemWrite( &item->contextSwitch.time, dt ); + break; + } + case QueueType::ThreadWakeup: + { + int64_t t = MemRead( &item->threadWakeup.time ); + int64_t dt = t - refCtx; + refCtx = t; + MemWrite( &item->threadWakeup.time, dt ); + break; + } + case QueueType::GpuTime: + { + int64_t t = MemRead( &item->gpuTime.gpuTime ); + int64_t dt = t - refGpu; + refGpu = t; + MemWrite( &item->gpuTime.gpuTime, dt ); + break; + } +#ifdef TRACY_HAS_CALLSTACK + case QueueType::CallstackFrameSize: + { + auto data = (const CallstackEntry*)MemRead( &item->callstackFrameSizeFat.data ); + auto datasz = MemRead( &item->callstackFrameSizeFat.size ); + auto imageName = (const char*)MemRead( &item->callstackFrameSizeFat.imageName ); + SendSingleString( imageName ); + AppendData( item++, QueueDataSize[idx] ); + + for( uint8_t i=0; i( &item->symbolInformationFat.fileString ); + auto needFree = MemRead( &item->symbolInformationFat.needFree ); + SendSingleString( fileString ); + if( needFree ) tracy_free_fast( (void*)fileString ); + break; + } + case QueueType::SymbolCodeMetadata: + { + auto symbol = MemRead( &item->symbolCodeMetadata.symbol ); + auto ptr = (const char*)MemRead( &item->symbolCodeMetadata.ptr ); + auto size = MemRead( &item->symbolCodeMetadata.size ); + SendLongString( symbol, ptr, size, QueueType::SymbolCode ); + tracy_free_fast( (void*)ptr ); + ++item; + continue; + } +#endif +#ifdef TRACY_HAS_SYSTEM_TRACING + case QueueType::ExternalNameMetadata: + { + auto thread = MemRead( &item->externalNameMetadata.thread ); + auto name = (const char*)MemRead( &item->externalNameMetadata.name ); + auto threadName = (const char*)MemRead( &item->externalNameMetadata.threadName ); + SendString( thread, threadName, QueueType::ExternalThreadName ); + SendString( thread, name, QueueType::ExternalName ); + tracy_free_fast( (void*)threadName ); + tracy_free_fast( (void*)name ); + ++item; + continue; + } +#endif + case QueueType::SourceCodeMetadata: + { + auto ptr = (const char*)MemRead( &item->sourceCodeMetadata.ptr ); + auto size = MemRead( &item->sourceCodeMetadata.size ); + auto id = MemRead( &item->sourceCodeMetadata.id ); + SendLongString( (uint64_t)id, ptr, size, QueueType::SourceCode ); + tracy_free_fast( (void*)ptr ); + ++item; + continue; + } + default: + assert( false ); + break; + } + } + if( !AppendData( item++, QueueDataSize[idx] ) ) + { + connectionLost = true; + m_refTimeThread = refThread; + m_refTimeCtx = refCtx; + m_refTimeGpu = refGpu; + return; + } + } + m_refTimeThread = refThread; + m_refTimeCtx = refCtx; + m_refTimeGpu = refGpu; + } + ); + if( connectionLost ) return DequeueStatus::ConnectionLost; + return sz > 0 ? DequeueStatus::DataDequeued : DequeueStatus::QueueEmpty; +} + +Profiler::DequeueStatus Profiler::DequeueContextSwitches( tracy::moodycamel::ConsumerToken& token, int64_t& timeStop ) +{ + const auto sz = GetQueue().try_dequeue_bulk_single( token, [] ( const uint64_t& ) {}, + [this, &timeStop] ( QueueItem* item, size_t sz ) + { + assert( sz > 0 ); + int64_t refCtx = m_refTimeCtx; + while( sz-- > 0 ) + { + FreeAssociatedMemory( *item ); + if( timeStop < 0 ) return; + const auto idx = MemRead( &item->hdr.idx ); + if( idx == (uint8_t)QueueType::ContextSwitch ) + { + const auto csTime = MemRead( &item->contextSwitch.time ); + if( csTime > timeStop ) + { + timeStop = -1; + m_refTimeCtx = refCtx; + return; + } + int64_t dt = csTime - refCtx; + refCtx = csTime; + MemWrite( &item->contextSwitch.time, dt ); + if( !AppendData( item, QueueDataSize[(int)QueueType::ContextSwitch] ) ) + { + timeStop = -2; + m_refTimeCtx = refCtx; + return; + } + } + else if( idx == (uint8_t)QueueType::ThreadWakeup ) + { + const auto csTime = MemRead( &item->threadWakeup.time ); + if( csTime > timeStop ) + { + timeStop = -1; + m_refTimeCtx = refCtx; + return; + } + int64_t dt = csTime - refCtx; + refCtx = csTime; + MemWrite( &item->threadWakeup.time, dt ); + if( !AppendData( item, QueueDataSize[(int)QueueType::ThreadWakeup] ) ) + { + timeStop = -2; + m_refTimeCtx = refCtx; + return; + } + } + item++; + } + m_refTimeCtx = refCtx; + } + ); + + if( timeStop == -2 ) return DequeueStatus::ConnectionLost; + return ( timeStop == -1 || sz > 0 ) ? DequeueStatus::DataDequeued : DequeueStatus::QueueEmpty; +} + +#define ThreadCtxCheckSerial( _name ) \ + uint32_t thread = MemRead( &item->_name.thread ); \ + switch( ThreadCtxCheck( thread ) ) \ + { \ + case ThreadCtxStatus::Same: break; \ + case ThreadCtxStatus::Changed: assert( m_refTimeThread == 0 ); refThread = 0; break; \ + case ThreadCtxStatus::ConnectionLost: return DequeueStatus::ConnectionLost; \ + default: assert( false ); break; \ + } + +Profiler::DequeueStatus Profiler::DequeueSerial() +{ + { + bool lockHeld = true; + while( !m_serialLock.try_lock() ) + { + if( m_shutdownManual.load( std::memory_order_relaxed ) ) + { + lockHeld = false; + break; + } + } + if( !m_serialQueue.empty() ) m_serialQueue.swap( m_serialDequeue ); + if( lockHeld ) + { + m_serialLock.unlock(); + } + } + + const auto sz = m_serialDequeue.size(); + if( sz > 0 ) + { + InitRpmalloc(); + int64_t refSerial = m_refTimeSerial; + int64_t refGpu = m_refTimeGpu; +#ifdef TRACY_FIBERS + int64_t refThread = m_refTimeThread; +#endif + auto item = m_serialDequeue.data(); + auto end = item + sz; + while( item != end ) + { + uint64_t ptr; + auto idx = MemRead( &item->hdr.idx ); + if( idx < (int)QueueType::Terminate ) + { + switch( (QueueType)idx ) + { + case QueueType::CallstackSerial: + ptr = MemRead( &item->callstackFat.ptr ); + SendCallstackPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + case QueueType::LockWait: + case QueueType::LockSharedWait: + { + int64_t t = MemRead( &item->lockWait.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->lockWait.time, dt ); + break; + } + case QueueType::LockObtain: + case QueueType::LockSharedObtain: + { + int64_t t = MemRead( &item->lockObtain.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->lockObtain.time, dt ); + break; + } + case QueueType::LockRelease: + case QueueType::LockSharedRelease: + { + int64_t t = MemRead( &item->lockRelease.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->lockRelease.time, dt ); + break; + } + case QueueType::LockName: + { + ptr = MemRead( &item->lockNameFat.name ); + uint16_t size = MemRead( &item->lockNameFat.size ); + SendSingleString( (const char*)ptr, size ); +#ifndef TRACY_ON_DEMAND + tracy_free_fast( (void*)ptr ); +#endif + break; + } + case QueueType::MemAlloc: + case QueueType::MemAllocNamed: + case QueueType::MemAllocCallstack: + case QueueType::MemAllocCallstackNamed: + { + int64_t t = MemRead( &item->memAlloc.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->memAlloc.time, dt ); + break; + } + case QueueType::MemFree: + case QueueType::MemFreeNamed: + case QueueType::MemFreeCallstack: + case QueueType::MemFreeCallstackNamed: + { + int64_t t = MemRead( &item->memFree.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->memFree.time, dt ); + break; + } + case QueueType::GpuZoneBeginSerial: + case QueueType::GpuZoneBeginCallstackSerial: + { + int64_t t = MemRead( &item->gpuZoneBegin.cpuTime ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->gpuZoneBegin.cpuTime, dt ); + break; + } + case QueueType::GpuZoneBeginAllocSrcLocSerial: + case QueueType::GpuZoneBeginAllocSrcLocCallstackSerial: + { + int64_t t = MemRead( &item->gpuZoneBegin.cpuTime ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->gpuZoneBegin.cpuTime, dt ); + ptr = MemRead( &item->gpuZoneBegin.srcloc ); + SendSourceLocationPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::GpuZoneEndSerial: + { + int64_t t = MemRead( &item->gpuZoneEnd.cpuTime ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->gpuZoneEnd.cpuTime, dt ); + break; + } + case QueueType::GpuTime: + { + int64_t t = MemRead( &item->gpuTime.gpuTime ); + int64_t dt = t - refGpu; + refGpu = t; + MemWrite( &item->gpuTime.gpuTime, dt ); + break; + } + case QueueType::GpuContextName: + { + ptr = MemRead( &item->gpuContextNameFat.ptr ); + uint16_t size = MemRead( &item->gpuContextNameFat.size ); + SendSingleString( (const char*)ptr, size ); +#ifndef TRACY_ON_DEMAND + tracy_free_fast( (void*)ptr ); +#endif + break; + } +#ifdef TRACY_FIBERS + case QueueType::ZoneBegin: + case QueueType::ZoneBeginCallstack: + { + ThreadCtxCheckSerial( zoneBeginThread ); + int64_t t = MemRead( &item->zoneBegin.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneBegin.time, dt ); + break; + } + case QueueType::ZoneBeginAllocSrcLoc: + case QueueType::ZoneBeginAllocSrcLocCallstack: + { + ThreadCtxCheckSerial( zoneBeginThread ); + int64_t t = MemRead( &item->zoneBegin.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneBegin.time, dt ); + ptr = MemRead( &item->zoneBegin.srcloc ); + SendSourceLocationPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::ZoneEnd: + { + ThreadCtxCheckSerial( zoneEndThread ); + int64_t t = MemRead( &item->zoneEnd.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->zoneEnd.time, dt ); + break; + } + case QueueType::ZoneText: + case QueueType::ZoneName: + { + ThreadCtxCheckSerial( zoneTextFatThread ); + ptr = MemRead( &item->zoneTextFat.text ); + uint16_t size = MemRead( &item->zoneTextFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::Message: + case QueueType::MessageCallstack: + { + ThreadCtxCheckSerial( messageFatThread ); + ptr = MemRead( &item->messageFat.text ); + uint16_t size = MemRead( &item->messageFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::MessageColor: + case QueueType::MessageColorCallstack: + { + ThreadCtxCheckSerial( messageColorFatThread ); + ptr = MemRead( &item->messageColorFat.text ); + uint16_t size = MemRead( &item->messageColorFat.size ); + SendSingleString( (const char*)ptr, size ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::Callstack: + { + ThreadCtxCheckSerial( callstackFatThread ); + ptr = MemRead( &item->callstackFat.ptr ); + SendCallstackPayload( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::CallstackAlloc: + { + ThreadCtxCheckSerial( callstackAllocFatThread ); + ptr = MemRead( &item->callstackAllocFat.nativePtr ); + if( ptr != 0 ) + { + CutCallstack( (void*)ptr, "lua_pcall" ); + SendCallstackPayload( ptr ); + tracy_free_fast( (void*)ptr ); + } + ptr = MemRead( &item->callstackAllocFat.ptr ); + SendCallstackAlloc( ptr ); + tracy_free_fast( (void*)ptr ); + break; + } + case QueueType::FiberEnter: + { + ThreadCtxCheckSerial( fiberEnter ); + int64_t t = MemRead( &item->fiberEnter.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->fiberEnter.time, dt ); + break; + } + case QueueType::FiberLeave: + { + ThreadCtxCheckSerial( fiberLeave ); + int64_t t = MemRead( &item->fiberLeave.time ); + int64_t dt = t - refThread; + refThread = t; + MemWrite( &item->fiberLeave.time, dt ); + break; + } +#endif + default: + assert( false ); + break; + } + } +#ifdef TRACY_FIBERS + else + { + switch( (QueueType)idx ) + { + case QueueType::ZoneColor: + { + ThreadCtxCheckSerial( zoneColorThread ); + break; + } + case QueueType::ZoneValue: + { + ThreadCtxCheckSerial( zoneValueThread ); + break; + } + case QueueType::ZoneValidation: + { + ThreadCtxCheckSerial( zoneValidationThread ); + break; + } + case QueueType::MessageLiteral: + case QueueType::MessageLiteralCallstack: + { + ThreadCtxCheckSerial( messageLiteralThread ); + break; + } + case QueueType::MessageLiteralColor: + case QueueType::MessageLiteralColorCallstack: + { + ThreadCtxCheckSerial( messageColorLiteralThread ); + break; + } + case QueueType::CrashReport: + { + ThreadCtxCheckSerial( crashReportThread ); + break; + } + default: + break; + } + } +#endif + if( !AppendData( item, QueueDataSize[idx] ) ) return DequeueStatus::ConnectionLost; + item++; + } + m_refTimeSerial = refSerial; + m_refTimeGpu = refGpu; +#ifdef TRACY_FIBERS + m_refTimeThread = refThread; +#endif + m_serialDequeue.clear(); + } + else + { + return DequeueStatus::QueueEmpty; + } + return DequeueStatus::DataDequeued; +} + +Profiler::ThreadCtxStatus Profiler::ThreadCtxCheck( uint32_t threadId ) +{ + if( m_threadCtx == threadId ) return ThreadCtxStatus::Same; + QueueItem item; + MemWrite( &item.hdr.type, QueueType::ThreadContext ); + MemWrite( &item.threadCtx.thread, threadId ); + if( !AppendData( &item, QueueDataSize[(int)QueueType::ThreadContext] ) ) return ThreadCtxStatus::ConnectionLost; + m_threadCtx = threadId; + m_refTimeThread = 0; + return ThreadCtxStatus::Changed; +} + +bool Profiler::CommitData() +{ + bool ret = SendData( m_buffer + m_bufferStart, m_bufferOffset - m_bufferStart ); + if( m_bufferOffset > TargetFrameSize * 2 ) m_bufferOffset = 0; + m_bufferStart = m_bufferOffset; + return ret; +} + +bool Profiler::SendData( const char* data, size_t len ) +{ + const lz4sz_t lz4sz = LZ4_compress_fast_continue( (LZ4_stream_t*)m_stream, data, m_lz4Buf + sizeof( lz4sz_t ), (int)len, LZ4Size, 1 ); + memcpy( m_lz4Buf, &lz4sz, sizeof( lz4sz ) ); + return m_sock->Send( m_lz4Buf, lz4sz + sizeof( lz4sz_t ) ) != -1; +} + +void Profiler::SendString( uint64_t str, const char* ptr, size_t len, QueueType type ) +{ + assert( type == QueueType::StringData || + type == QueueType::ThreadName || + type == QueueType::PlotName || + type == QueueType::FrameName || + type == QueueType::ExternalName || + type == QueueType::ExternalThreadName || + type == QueueType::FiberName ); + + QueueItem item; + MemWrite( &item.hdr.type, type ); + MemWrite( &item.stringTransfer.ptr, str ); + + assert( len <= std::numeric_limits::max() ); + auto l16 = uint16_t( len ); + + NeedDataSize( QueueDataSize[(int)type] + sizeof( l16 ) + l16 ); + + AppendDataUnsafe( &item, QueueDataSize[(int)type] ); + AppendDataUnsafe( &l16, sizeof( l16 ) ); + AppendDataUnsafe( ptr, l16 ); +} + +void Profiler::SendSingleString( const char* ptr, size_t len ) +{ + QueueItem item; + MemWrite( &item.hdr.type, QueueType::SingleStringData ); + + assert( len <= std::numeric_limits::max() ); + auto l16 = uint16_t( len ); + + NeedDataSize( QueueDataSize[(int)QueueType::SingleStringData] + sizeof( l16 ) + l16 ); + + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::SingleStringData] ); + AppendDataUnsafe( &l16, sizeof( l16 ) ); + AppendDataUnsafe( ptr, l16 ); +} + +void Profiler::SendSecondString( const char* ptr, size_t len ) +{ + QueueItem item; + MemWrite( &item.hdr.type, QueueType::SecondStringData ); + + assert( len <= std::numeric_limits::max() ); + auto l16 = uint16_t( len ); + + NeedDataSize( QueueDataSize[(int)QueueType::SecondStringData] + sizeof( l16 ) + l16 ); + + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::SecondStringData] ); + AppendDataUnsafe( &l16, sizeof( l16 ) ); + AppendDataUnsafe( ptr, l16 ); +} + +void Profiler::SendLongString( uint64_t str, const char* ptr, size_t len, QueueType type ) +{ + assert( type == QueueType::FrameImageData || + type == QueueType::SymbolCode || + type == QueueType::SourceCode ); + + QueueItem item; + MemWrite( &item.hdr.type, type ); + MemWrite( &item.stringTransfer.ptr, str ); + + assert( len <= std::numeric_limits::max() ); + assert( QueueDataSize[(int)type] + sizeof( uint32_t ) + len <= TargetFrameSize ); + auto l32 = uint32_t( len ); + + NeedDataSize( QueueDataSize[(int)type] + sizeof( l32 ) + l32 ); + + AppendDataUnsafe( &item, QueueDataSize[(int)type] ); + AppendDataUnsafe( &l32, sizeof( l32 ) ); + AppendDataUnsafe( ptr, l32 ); +} + +void Profiler::SendSourceLocation( uint64_t ptr ) +{ + auto srcloc = (const SourceLocationData*)ptr; + QueueItem item; + MemWrite( &item.hdr.type, QueueType::SourceLocation ); + MemWrite( &item.srcloc.name, (uint64_t)srcloc->name ); + MemWrite( &item.srcloc.file, (uint64_t)srcloc->file ); + MemWrite( &item.srcloc.function, (uint64_t)srcloc->function ); + MemWrite( &item.srcloc.line, srcloc->line ); + MemWrite( &item.srcloc.b, uint8_t( ( srcloc->color ) & 0xFF ) ); + MemWrite( &item.srcloc.g, uint8_t( ( srcloc->color >> 8 ) & 0xFF ) ); + MemWrite( &item.srcloc.r, uint8_t( ( srcloc->color >> 16 ) & 0xFF ) ); + AppendData( &item, QueueDataSize[(int)QueueType::SourceLocation] ); +} + +void Profiler::SendSourceLocationPayload( uint64_t _ptr ) +{ + auto ptr = (const char*)_ptr; + + QueueItem item; + MemWrite( &item.hdr.type, QueueType::SourceLocationPayload ); + MemWrite( &item.stringTransfer.ptr, _ptr ); + + uint16_t len; + memcpy( &len, ptr, sizeof( len ) ); + assert( len > 2 ); + len -= 2; + ptr += 2; + + NeedDataSize( QueueDataSize[(int)QueueType::SourceLocationPayload] + sizeof( len ) + len ); + + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::SourceLocationPayload] ); + AppendDataUnsafe( &len, sizeof( len ) ); + AppendDataUnsafe( ptr, len ); +} + +void Profiler::SendCallstackPayload( uint64_t _ptr ) +{ + auto ptr = (uintptr_t*)_ptr; + + QueueItem item; + MemWrite( &item.hdr.type, QueueType::CallstackPayload ); + MemWrite( &item.stringTransfer.ptr, _ptr ); + + const auto sz = *ptr++; + const auto len = sz * sizeof( uint64_t ); + const auto l16 = uint16_t( len ); + + NeedDataSize( QueueDataSize[(int)QueueType::CallstackPayload] + sizeof( l16 ) + l16 ); + + AppendDataUnsafe( &item, QueueDataSize[(int)QueueType::CallstackPayload] ); + AppendDataUnsafe( &l16, sizeof( l16 ) ); + + if( compile_time_condition::value ) + { + AppendDataUnsafe( ptr, sizeof( uint64_t ) * sz ); + } + else + { + for( uintptr_t i=0; i> 63 != 0 ) + { + SendSingleString( "" ); + QueueItem item; + MemWrite( &item.hdr.type, QueueType::SymbolInformation ); + MemWrite( &item.symbolInformation.line, 0 ); + MemWrite( &item.symbolInformation.symAddr, symbol ); + AppendData( &item, QueueDataSize[(int)QueueType::SymbolInformation] ); + } + else + { + m_symbolQueue.emplace( SymbolQueueItem { SymbolQueueItemType::SymbolQuery, symbol } ); + } +#else + AckServerQuery(); +#endif +} + +void Profiler::QueueExternalName( uint64_t ptr ) +{ +#ifdef TRACY_HAS_SYSTEM_TRACING + m_symbolQueue.emplace( SymbolQueueItem { SymbolQueueItemType::ExternalName, ptr } ); +#endif +} + +void Profiler::QueueKernelCode( uint64_t symbol, uint32_t size ) +{ + assert( symbol >> 63 != 0 ); +#ifdef TRACY_HAS_CALLSTACK + m_symbolQueue.emplace( SymbolQueueItem { SymbolQueueItemType::KernelCode, symbol, size } ); +#else + AckSymbolCodeNotAvailable(); +#endif +} + +void Profiler::QueueSourceCodeQuery( uint32_t id ) +{ + assert( m_exectime != 0 ); + assert( m_queryData ); + m_symbolQueue.emplace( SymbolQueueItem { SymbolQueueItemType::SourceCode, uint64_t( m_queryData ), uint64_t( m_queryImage ), id } ); + m_queryData = nullptr; + m_queryImage = nullptr; +} + +#ifdef TRACY_HAS_CALLSTACK +void Profiler::HandleSymbolQueueItem( const SymbolQueueItem& si ) +{ + switch( si.type ) + { + case SymbolQueueItemType::CallstackFrame: + { + const auto frameData = DecodeCallstackPtr( si.ptr ); + auto data = tracy_malloc_fast( sizeof( CallstackEntry ) * frameData.size ); + memcpy( data, frameData.data, sizeof( CallstackEntry ) * frameData.size ); + TracyLfqPrepare( QueueType::CallstackFrameSize ); + MemWrite( &item->callstackFrameSizeFat.ptr, si.ptr ); + MemWrite( &item->callstackFrameSizeFat.size, frameData.size ); + MemWrite( &item->callstackFrameSizeFat.data, (uint64_t)data ); + MemWrite( &item->callstackFrameSizeFat.imageName, (uint64_t)frameData.imageName ); + TracyLfqCommit; + break; + } + case SymbolQueueItemType::SymbolQuery: + { +#ifdef __ANDROID__ + // On Android it's common for code to be in mappings that are only executable + // but not readable. + if( !EnsureReadable( si.ptr ) ) + { + TracyLfqPrepare( QueueType::AckServerQueryNoop ); + TracyLfqCommit; + break; + } +#endif + const auto sym = DecodeSymbolAddress( si.ptr ); + TracyLfqPrepare( QueueType::SymbolInformation ); + MemWrite( &item->symbolInformationFat.line, sym.line ); + MemWrite( &item->symbolInformationFat.symAddr, si.ptr ); + MemWrite( &item->symbolInformationFat.fileString, (uint64_t)sym.file ); + MemWrite( &item->symbolInformationFat.needFree, (uint8_t)sym.needFree ); + TracyLfqCommit; + break; + } +#ifdef TRACY_HAS_SYSTEM_TRACING + case SymbolQueueItemType::ExternalName: + { + const char* threadName; + const char* name; + SysTraceGetExternalName( si.ptr, threadName, name ); + TracyLfqPrepare( QueueType::ExternalNameMetadata ); + MemWrite( &item->externalNameMetadata.thread, si.ptr ); + MemWrite( &item->externalNameMetadata.name, (uint64_t)name ); + MemWrite( &item->externalNameMetadata.threadName, (uint64_t)threadName ); + TracyLfqCommit; + break; + } +#endif + case SymbolQueueItemType::KernelCode: + { +#ifdef _WIN32 + auto mod = GetKernelModulePath( si.ptr ); + if( mod ) + { + auto fn = DecodeCallstackPtrFast( si.ptr ); + if( *fn ) + { + auto hnd = LoadLibraryExA( mod, nullptr, DONT_RESOLVE_DLL_REFERENCES ); + if( hnd ) + { + auto ptr = (const void*)GetProcAddress( hnd, fn ); + if( ptr ) + { + auto buf = (char*)tracy_malloc( si.extra ); + memcpy( buf, ptr, si.extra ); + FreeLibrary( hnd ); + TracyLfqPrepare( QueueType::SymbolCodeMetadata ); + MemWrite( &item->symbolCodeMetadata.symbol, si.ptr ); + MemWrite( &item->symbolCodeMetadata.ptr, (uint64_t)buf ); + MemWrite( &item->symbolCodeMetadata.size, (uint32_t)si.extra ); + TracyLfqCommit; + break; + } + FreeLibrary( hnd ); + } + } + } +#endif + TracyLfqPrepare( QueueType::AckSymbolCodeNotAvailable ); + TracyLfqCommit; + break; + } + case SymbolQueueItemType::SourceCode: + HandleSourceCodeQuery( (char*)si.ptr, (char*)si.extra, si.id ); + break; + default: + assert( false ); + break; + } +} + +void Profiler::SymbolWorker() +{ +#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER + s_symbolTid = syscall( SYS_gettid ); +#endif + + ThreadExitHandler threadExitHandler; + SetThreadName( "Tracy Symbol Worker" ); +#ifdef TRACY_USE_RPMALLOC + InitRpmalloc(); +#endif + InitCallstack(); + while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + + for(;;) + { + const auto shouldExit = ShouldExit(); +#ifdef TRACY_ON_DEMAND + if( !IsConnected() ) + { + if( shouldExit ) + { + s_symbolThreadGone.store( true, std::memory_order_release ); + return; + } + while( m_symbolQueue.front() ) m_symbolQueue.pop(); + std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) ); + continue; + } +#endif + auto si = m_symbolQueue.front(); + if( si ) + { + HandleSymbolQueueItem( *si ); + m_symbolQueue.pop(); + } + else + { + if( shouldExit ) + { + s_symbolThreadGone.store( true, std::memory_order_release ); + return; + } + std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) ); + } + } +} +#endif + +bool Profiler::HandleServerQuery() +{ + ServerQueryPacket payload; + if( !m_sock->Read( &payload, sizeof( payload ), 10 ) ) return false; + + uint8_t type; + uint64_t ptr; + memcpy( &type, &payload.type, sizeof( payload.type ) ); + memcpy( &ptr, &payload.ptr, sizeof( payload.ptr ) ); + + switch( type ) + { + case ServerQueryString: + SendString( ptr, (const char*)ptr, QueueType::StringData ); + break; + case ServerQueryThreadString: + if( ptr == m_mainThread ) + { + SendString( ptr, "Main thread", 11, QueueType::ThreadName ); + } + else + { + SendString( ptr, GetThreadName( ptr ), QueueType::ThreadName ); + } + break; + case ServerQuerySourceLocation: + SendSourceLocation( ptr ); + break; + case ServerQueryPlotName: + SendString( ptr, (const char*)ptr, QueueType::PlotName ); + break; + case ServerQueryTerminate: + return false; + case ServerQueryCallstackFrame: + QueueCallstackFrame( ptr ); + break; + case ServerQueryFrameName: + SendString( ptr, (const char*)ptr, QueueType::FrameName ); + break; + case ServerQueryDisconnect: + HandleDisconnect(); + return false; +#ifdef TRACY_HAS_SYSTEM_TRACING + case ServerQueryExternalName: + QueueExternalName( ptr ); + break; +#endif + case ServerQueryParameter: + HandleParameter( ptr ); + break; + case ServerQuerySymbol: + QueueSymbolQuery( ptr ); + break; +#ifndef TRACY_NO_CODE_TRANSFER + case ServerQuerySymbolCode: + HandleSymbolCodeQuery( ptr, payload.extra ); + break; +#endif + case ServerQuerySourceCode: + QueueSourceCodeQuery( uint32_t( ptr ) ); + break; + case ServerQueryDataTransfer: + if( m_queryData ) + { + assert( !m_queryImage ); + m_queryImage = m_queryData; + } + m_queryDataPtr = m_queryData = (char*)tracy_malloc( ptr + 11 ); + AckServerQuery(); + break; + case ServerQueryDataTransferPart: + memcpy( m_queryDataPtr, &ptr, 8 ); + memcpy( m_queryDataPtr+8, &payload.extra, 4 ); + m_queryDataPtr += 12; + AckServerQuery(); + break; +#ifdef TRACY_FIBERS + case ServerQueryFiberName: + SendString( ptr, (const char*)ptr, QueueType::FiberName ); + break; +#endif + default: + assert( false ); + break; + } + + return true; +} + +void Profiler::HandleDisconnect() +{ + moodycamel::ConsumerToken token( GetQueue() ); + +#ifdef TRACY_HAS_SYSTEM_TRACING + if( s_sysTraceThread ) + { + auto timestamp = GetTime(); + for(;;) + { + const auto status = DequeueContextSwitches( token, timestamp ); + if( status == DequeueStatus::ConnectionLost ) + { + return; + } + else if( status == DequeueStatus::QueueEmpty ) + { + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + } + if( timestamp < 0 ) + { + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + break; + } + ClearSerial(); + if( m_sock->HasData() ) + { + while( m_sock->HasData() ) + { + if( !HandleServerQuery() ) return; + } + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + } + else + { + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } + } + } +#endif + + QueueItem terminate; + MemWrite( &terminate.hdr.type, QueueType::Terminate ); + if( !SendData( (const char*)&terminate, 1 ) ) return; + for(;;) + { + ClearQueues( token ); + if( m_sock->HasData() ) + { + while( m_sock->HasData() ) + { + if( !HandleServerQuery() ) return; + } + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + } + else + { + if( m_bufferOffset != m_bufferStart ) + { + if( !CommitData() ) return; + } + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } + } +} + +void Profiler::CalibrateTimer() +{ + m_timerMul = 1.; + +#ifdef TRACY_HW_TIMER + +# if !defined TRACY_TIMER_QPC && defined TRACY_TIMER_FALLBACK + const bool needCalibration = HardwareSupportsInvariantTSC(); +# else + const bool needCalibration = true; +# endif + if( needCalibration ) + { + std::atomic_signal_fence( std::memory_order_acq_rel ); + const auto t0 = std::chrono::high_resolution_clock::now(); + const auto r0 = GetTime(); + std::atomic_signal_fence( std::memory_order_acq_rel ); + std::this_thread::sleep_for( std::chrono::milliseconds( 200 ) ); + std::atomic_signal_fence( std::memory_order_acq_rel ); + const auto t1 = std::chrono::high_resolution_clock::now(); + const auto r1 = GetTime(); + std::atomic_signal_fence( std::memory_order_acq_rel ); + + const auto dt = std::chrono::duration_cast( t1 - t0 ).count(); + const auto dr = r1 - r0; + + m_timerMul = double( dt ) / double( dr ); + } +#endif +} + +void Profiler::CalibrateDelay() +{ + constexpr int Iterations = 50000; + + auto mindiff = std::numeric_limits::max(); + for( int i=0; i 0 && dti < mindiff ) mindiff = dti; + } + m_resolution = mindiff; + +#ifdef TRACY_DELAYED_INIT + m_delay = m_resolution; +#else + constexpr int Events = Iterations * 2; // start + end + static_assert( Events < QueuePrealloc, "Delay calibration loop will allocate memory in queue" ); + + static const tracy::SourceLocationData __tracy_source_location { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; + const auto t0 = GetTime(); + for( int i=0; izoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)&__tracy_source_location ); + TracyLfqCommit; + } + { + TracyLfqPrepare( QueueType::ZoneEnd ); + MemWrite( &item->zoneEnd.time, GetTime() ); + TracyLfqCommit; + } + } + const auto t1 = GetTime(); + const auto dt = t1 - t0; + m_delay = dt / Events; + + moodycamel::ConsumerToken token( GetQueue() ); + int left = Events; + while( left != 0 ) + { + const auto sz = GetQueue().try_dequeue_bulk_single( token, [](const uint64_t&){}, [](QueueItem* item, size_t sz){} ); + assert( sz > 0 ); + left -= (int)sz; + } + assert( GetQueue().size_approx() == 0 ); +#endif +} + +void Profiler::ReportTopology() +{ +#ifndef TRACY_DELAYED_INIT + struct CpuData + { + uint32_t package; + uint32_t core; + uint32_t thread; + }; + +#if defined _WIN32 +# ifdef TRACY_UWP + t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = &::GetLogicalProcessorInformationEx; +# else + t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetLogicalProcessorInformationEx" ); +# endif + if( !_GetLogicalProcessorInformationEx ) return; + + DWORD psz = 0; + _GetLogicalProcessorInformationEx( RelationProcessorPackage, nullptr, &psz ); + auto packageInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)tracy_malloc( psz ); + auto res = _GetLogicalProcessorInformationEx( RelationProcessorPackage, packageInfo, &psz ); + assert( res ); + + DWORD csz = 0; + _GetLogicalProcessorInformationEx( RelationProcessorCore, nullptr, &csz ); + auto coreInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)tracy_malloc( csz ); + res = _GetLogicalProcessorInformationEx( RelationProcessorCore, coreInfo, &csz ); + assert( res ); + + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + const uint32_t numcpus = sysinfo.dwNumberOfProcessors; + + auto cpuData = (CpuData*)tracy_malloc( sizeof( CpuData ) * numcpus ); + for( uint32_t i=0; iRelationship == RelationProcessorPackage ); + // FIXME account for GroupCount + auto mask = ptr->Processor.GroupMask[0].Mask; + int core = 0; + while( mask != 0 ) + { + if( mask & 1 ) cpuData[core].package = idx; + core++; + mask >>= 1; + } + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size); + idx++; + } + + idx = 0; + ptr = coreInfo; + while( (char*)ptr < ((char*)coreInfo) + csz ) + { + assert( ptr->Relationship == RelationProcessorCore ); + // FIXME account for GroupCount + auto mask = ptr->Processor.GroupMask[0].Mask; + int core = 0; + while( mask != 0 ) + { + if( mask & 1 ) cpuData[core].core = idx; + core++; + mask >>= 1; + } + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size); + idx++; + } + + for( uint32_t i=0; icpuTopology.package, data.package ); + MemWrite( &item->cpuTopology.core, data.core ); + MemWrite( &item->cpuTopology.thread, data.thread ); + +#ifdef TRACY_ON_DEMAND + DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + tracy_free( cpuData ); + tracy_free( coreInfo ); + tracy_free( packageInfo ); +#elif defined __linux__ + const int numcpus = std::thread::hardware_concurrency(); + auto cpuData = (CpuData*)tracy_malloc( sizeof( CpuData ) * numcpus ); + memset( cpuData, 0, sizeof( CpuData ) * numcpus ); + + const char* basePath = "/sys/devices/system/cpu/cpu"; + for( int i=0; icpuTopology.package, data.package ); + MemWrite( &item->cpuTopology.core, data.core ); + MemWrite( &item->cpuTopology.thread, data.thread ); + +#ifdef TRACY_ON_DEMAND + DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + tracy_free( cpuData ); +#endif +#endif +} + +void Profiler::SendCallstack( int depth, const char* skipBefore ) +{ +#ifdef TRACY_HAS_CALLSTACK + auto ptr = Callstack( depth ); + CutCallstack( ptr, skipBefore ); + + TracyQueuePrepare( QueueType::Callstack ); + MemWrite( &item->callstackFat.ptr, (uint64_t)ptr ); + TracyQueueCommit( callstackFatThread ); +#endif +} + +void Profiler::CutCallstack( void* callstack, const char* skipBefore ) +{ +#ifdef TRACY_HAS_CALLSTACK + auto data = (uintptr_t*)callstack; + const auto sz = *data++; + uintptr_t i; + for( i=0; i 100000000 ) // 100 ms + { + auto sysTime = m_sysTime.Get(); + if( sysTime >= 0 ) + { + m_sysTimeLast = t; + + TracyLfqPrepare( QueueType::SysTimeReport ); + MemWrite( &item->sysTime.time, GetTime() ); + MemWrite( &item->sysTime.sysTime, sysTime ); + TracyLfqCommit; + } + } +} +#endif + +void Profiler::HandleParameter( uint64_t payload ) +{ + assert( m_paramCallback ); + const auto idx = uint32_t( payload >> 32 ); + const auto val = int32_t( payload & 0xFFFFFFFF ); + m_paramCallback( m_paramCallbackData, idx, val ); + AckServerQuery(); +} + +void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size ) +{ + if( symbol >> 63 != 0 ) + { + QueueKernelCode( symbol, size ); + } + else + { +#ifdef __ANDROID__ + // On Android it's common for code to be in mappings that are only executable + // but not readable. + if( !EnsureReadable( symbol ) ) + { + AckSymbolCodeNotAvailable(); + return; + } +#endif + SendLongString( symbol, (const char*)symbol, size, QueueType::SymbolCode ); + } +} + +void Profiler::HandleSourceCodeQuery( char* data, char* image, uint32_t id ) +{ + bool ok = false; + struct stat st; + if( stat( data, &st ) == 0 && (uint64_t)st.st_mtime < m_exectime ) + { + if( st.st_size < ( TargetFrameSize - 16 ) ) + { + FILE* f = fopen( data, "rb" ); + if( f ) + { + auto ptr = (char*)tracy_malloc_fast( st.st_size ); + auto rd = fread( ptr, 1, st.st_size, f ); + fclose( f ); + if( rd == (size_t)st.st_size ) + { + TracyLfqPrepare( QueueType::SourceCodeMetadata ); + MemWrite( &item->sourceCodeMetadata.ptr, (uint64_t)ptr ); + MemWrite( &item->sourceCodeMetadata.size, (uint32_t)rd ); + MemWrite( &item->sourceCodeMetadata.id, id ); + TracyLfqCommit; + ok = true; + } + } + } + } + +#ifdef TRACY_DEBUGINFOD + else if( image && data[0] == '/' ) + { + size_t size; + auto buildid = GetBuildIdForImage( image, size ); + if( buildid ) + { + auto d = debuginfod_find_source( GetDebuginfodClient(), buildid, size, data, nullptr ); + TracyDebug( "DebugInfo source query: %s, fn: %s, image: %s\n", d >= 0 ? " ok " : "fail", data, image ); + if( d >= 0 ) + { + struct stat st; + fstat( d, &st ); + if( st.st_size < ( TargetFrameSize - 16 ) ) + { + lseek( d, 0, SEEK_SET ); + auto ptr = (char*)tracy_malloc_fast( st.st_size ); + auto rd = read( d, ptr, st.st_size ); + if( rd == (size_t)st.st_size ) + { + TracyLfqPrepare( QueueType::SourceCodeMetadata ); + MemWrite( &item->sourceCodeMetadata.ptr, (uint64_t)ptr ); + MemWrite( &item->sourceCodeMetadata.size, (uint32_t)rd ); + MemWrite( &item->sourceCodeMetadata.id, id ); + TracyLfqCommit; + ok = true; + } + } + close( d ); + } + } + } + else + { + TracyDebug( "DebugInfo invalid query fn: %s, image: %s\n", data, image ); + } +#endif + + if( !ok && m_sourceCallback ) + { + size_t sz; + char* ptr = m_sourceCallback( m_sourceCallbackData, data, sz ); + if( ptr ) + { + if( sz < ( TargetFrameSize - 16 ) ) + { + TracyLfqPrepare( QueueType::SourceCodeMetadata ); + MemWrite( &item->sourceCodeMetadata.ptr, (uint64_t)ptr ); + MemWrite( &item->sourceCodeMetadata.size, (uint32_t)sz ); + MemWrite( &item->sourceCodeMetadata.id, id ); + TracyLfqCommit; + ok = true; + } + } + } + + if( !ok ) + { + TracyLfqPrepare( QueueType::AckSourceCodeNotAvailable ); + MemWrite( &item->sourceCodeNotAvailable, id ); + TracyLfqCommit; + } + + tracy_free_fast( data ); + tracy_free_fast( image ); +} + +#if defined _WIN32 && defined TRACY_TIMER_QPC +int64_t Profiler::GetTimeQpc() +{ + LARGE_INTEGER t; + QueryPerformanceCounter( &t ); + return t.QuadPart; +} +#endif + +} + +#ifdef __cplusplus +extern "C" { +#endif + +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin( const struct ___tracy_source_location_data* srcloc, int active ) +{ + ___tracy_c_zone_context ctx; +#ifdef TRACY_ON_DEMAND + ctx.active = active && tracy::GetProfiler().IsConnected(); +#else + ctx.active = active; +#endif + if( !ctx.active ) return ctx; + const auto id = tracy::GetProfiler().GetNextZoneId(); + ctx.id = id; + +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneBegin ); + tracy::MemWrite( &item->zoneBegin.time, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc ); + TracyQueueCommitC( zoneBeginThread ); + } + return ctx; +} + +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_callstack( const struct ___tracy_source_location_data* srcloc, int depth, int active ) +{ + ___tracy_c_zone_context ctx; +#ifdef TRACY_ON_DEMAND + ctx.active = active && tracy::GetProfiler().IsConnected(); +#else + ctx.active = active; +#endif + if( !ctx.active ) return ctx; + const auto id = tracy::GetProfiler().GetNextZoneId(); + ctx.id = id; + +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + tracy::GetProfiler().SendCallstack( depth ); + { + TracyQueuePrepareC( tracy::QueueType::ZoneBeginCallstack ); + tracy::MemWrite( &item->zoneBegin.time, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc ); + TracyQueueCommitC( zoneBeginThread ); + } + return ctx; +} + +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc( uint64_t srcloc, int active ) +{ + ___tracy_c_zone_context ctx; +#ifdef TRACY_ON_DEMAND + ctx.active = active && tracy::GetProfiler().IsConnected(); +#else + ctx.active = active; +#endif + if( !ctx.active ) + { + tracy::tracy_free( (void*)srcloc ); + return ctx; + } + const auto id = tracy::GetProfiler().GetNextZoneId(); + ctx.id = id; + +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneBeginAllocSrcLoc ); + tracy::MemWrite( &item->zoneBegin.time, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommitC( zoneBeginThread ); + } + return ctx; +} + +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc_callstack( uint64_t srcloc, int depth, int active ) +{ + ___tracy_c_zone_context ctx; +#ifdef TRACY_ON_DEMAND + ctx.active = active && tracy::GetProfiler().IsConnected(); +#else + ctx.active = active; +#endif + if( !ctx.active ) + { + tracy::tracy_free( (void*)srcloc ); + return ctx; + } + const auto id = tracy::GetProfiler().GetNextZoneId(); + ctx.id = id; + +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + tracy::GetProfiler().SendCallstack( depth ); + { + TracyQueuePrepareC( tracy::QueueType::ZoneBeginAllocSrcLocCallstack ); + tracy::MemWrite( &item->zoneBegin.time, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommitC( zoneBeginThread ); + } + return ctx; +} + +TRACY_API void ___tracy_emit_zone_end( TracyCZoneCtx ctx ) +{ + if( !ctx.active ) return; +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, ctx.id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneEnd ); + tracy::MemWrite( &item->zoneEnd.time, tracy::Profiler::GetTime() ); + TracyQueueCommitC( zoneEndThread ); + } +} + +TRACY_API void ___tracy_emit_zone_text( TracyCZoneCtx ctx, const char* txt, size_t size ) +{ + assert( size < std::numeric_limits::max() ); + if( !ctx.active ) return; + auto ptr = (char*)tracy::tracy_malloc( size ); + memcpy( ptr, txt, size ); +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, ctx.id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneText ); + tracy::MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + tracy::MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommitC( zoneTextFatThread ); + } +} + +TRACY_API void ___tracy_emit_zone_name( TracyCZoneCtx ctx, const char* txt, size_t size ) +{ + assert( size < std::numeric_limits::max() ); + if( !ctx.active ) return; + auto ptr = (char*)tracy::tracy_malloc( size ); + memcpy( ptr, txt, size ); +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, ctx.id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneName ); + tracy::MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + tracy::MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommitC( zoneTextFatThread ); + } +} + +TRACY_API void ___tracy_emit_zone_color( TracyCZoneCtx ctx, uint32_t color ) { + if( !ctx.active ) return; +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, ctx.id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneColor ); + tracy::MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) ); + tracy::MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) ); + tracy::MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) ); + TracyQueueCommitC( zoneColorThread ); + } +} + +TRACY_API void ___tracy_emit_zone_value( TracyCZoneCtx ctx, uint64_t value ) +{ + if( !ctx.active ) return; +#ifndef TRACY_NO_VERIFY + { + TracyQueuePrepareC( tracy::QueueType::ZoneValidation ); + tracy::MemWrite( &item->zoneValidation.id, ctx.id ); + TracyQueueCommitC( zoneValidationThread ); + } +#endif + { + TracyQueuePrepareC( tracy::QueueType::ZoneValue ); + tracy::MemWrite( &item->zoneValue.value, value ); + TracyQueueCommitC( zoneValueThread ); + } +} + +TRACY_API void ___tracy_emit_memory_alloc( const void* ptr, size_t size, int secure ) { tracy::Profiler::MemAlloc( ptr, size, secure != 0 ); } +TRACY_API void ___tracy_emit_memory_alloc_callstack( const void* ptr, size_t size, int depth, int secure ) { tracy::Profiler::MemAllocCallstack( ptr, size, depth, secure != 0 ); } +TRACY_API void ___tracy_emit_memory_free( const void* ptr, int secure ) { tracy::Profiler::MemFree( ptr, secure != 0 ); } +TRACY_API void ___tracy_emit_memory_free_callstack( const void* ptr, int depth, int secure ) { tracy::Profiler::MemFreeCallstack( ptr, depth, secure != 0 ); } +TRACY_API void ___tracy_emit_memory_alloc_named( const void* ptr, size_t size, int secure, const char* name ) { tracy::Profiler::MemAllocNamed( ptr, size, secure != 0, name ); } +TRACY_API void ___tracy_emit_memory_alloc_callstack_named( const void* ptr, size_t size, int depth, int secure, const char* name ) { tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, secure != 0, name ); } +TRACY_API void ___tracy_emit_memory_free_named( const void* ptr, int secure, const char* name ) { tracy::Profiler::MemFreeNamed( ptr, secure != 0, name ); } +TRACY_API void ___tracy_emit_memory_free_callstack_named( const void* ptr, int depth, int secure, const char* name ) { tracy::Profiler::MemFreeCallstackNamed( ptr, depth, secure != 0, name ); } +TRACY_API void ___tracy_emit_frame_mark( const char* name ) { tracy::Profiler::SendFrameMark( name ); } +TRACY_API void ___tracy_emit_frame_mark_start( const char* name ) { tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart ); } +TRACY_API void ___tracy_emit_frame_mark_end( const char* name ) { tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd ); } +TRACY_API void ___tracy_emit_frame_image( const void* image, uint16_t w, uint16_t h, uint8_t offset, int flip ) { tracy::Profiler::SendFrameImage( image, w, h, offset, flip ); } +TRACY_API void ___tracy_emit_plot( const char* name, double val ) { tracy::Profiler::PlotData( name, val ); } +TRACY_API void ___tracy_emit_plot_float( const char* name, float val ) { tracy::Profiler::PlotData( name, val ); } +TRACY_API void ___tracy_emit_plot_int( const char* name, int64_t val ) { tracy::Profiler::PlotData( name, val ); } +TRACY_API void ___tracy_emit_plot_config( const char* name, int type, int step, int fill, uint32_t color ) { tracy::Profiler::ConfigurePlot( name, tracy::PlotFormatType(type), step, fill, color ); } +TRACY_API void ___tracy_emit_message( const char* txt, size_t size, int callstack ) { tracy::Profiler::Message( txt, size, callstack ); } +TRACY_API void ___tracy_emit_messageL( const char* txt, int callstack ) { tracy::Profiler::Message( txt, callstack ); } +TRACY_API void ___tracy_emit_messageC( const char* txt, size_t size, uint32_t color, int callstack ) { tracy::Profiler::MessageColor( txt, size, color, callstack ); } +TRACY_API void ___tracy_emit_messageLC( const char* txt, uint32_t color, int callstack ) { tracy::Profiler::MessageColor( txt, color, callstack ); } +TRACY_API void ___tracy_emit_message_appinfo( const char* txt, size_t size ) { tracy::Profiler::MessageAppInfo( txt, size ); } + +TRACY_API uint64_t ___tracy_alloc_srcloc( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz ) { + return tracy::Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz ); +} + +TRACY_API uint64_t ___tracy_alloc_srcloc_name( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz ) { + return tracy::Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); +} + +TRACY_API void ___tracy_emit_gpu_zone_begin( const struct ___tracy_gpu_zone_begin_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuZoneBegin ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_callstack( const struct ___tracy_gpu_zone_begin_callstack_data data ) +{ + tracy::GetProfiler().SendCallstack( data.depth ); + TracyLfqPrepareC( tracy::QueueType::GpuZoneBeginCallstack ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc( const struct ___tracy_gpu_zone_begin_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuZoneBeginAllocSrcLoc ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack( const struct ___tracy_gpu_zone_begin_callstack_data data ) +{ + tracy::GetProfiler().SendCallstack( data.depth ); + TracyLfqPrepareC( tracy::QueueType::GpuZoneBeginAllocSrcLocCallstack ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_time( const struct ___tracy_gpu_time_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuTime ); + tracy::MemWrite( &item->gpuTime.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuTime.queryId, data.queryId ); + tracy::MemWrite( &item->gpuTime.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_zone_end( const struct ___tracy_gpu_zone_end_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuZoneEnd ); + tracy::MemWrite( &item->gpuZoneEnd.cpuTime, tracy::Profiler::GetTime() ); + memset( &item->gpuZoneEnd.thread, 0, sizeof( item->gpuZoneEnd.thread ) ); + tracy::MemWrite( &item->gpuZoneEnd.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneEnd.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_new_context( ___tracy_gpu_new_context_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuNewContext ); + tracy::MemWrite( &item->gpuNewContext.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuNewContext.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuNewContext.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuNewContext.period, data.period ); + tracy::MemWrite( &item->gpuNewContext.context, data.context ); + tracy::MemWrite( &item->gpuNewContext.flags, data.flags ); + tracy::MemWrite( &item->gpuNewContext.type, data.type ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_context_name( const struct ___tracy_gpu_context_name_data data ) +{ + auto ptr = (char*)tracy::tracy_malloc( data.len ); + memcpy( ptr, data.name, data.len ); + + TracyLfqPrepareC( tracy::QueueType::GpuContextName ); + tracy::MemWrite( &item->gpuContextNameFat.context, data.context ); + tracy::MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + tracy::MemWrite( &item->gpuContextNameFat.size, data.len ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_calibration( const struct ___tracy_gpu_calibration_data data ) +{ + TracyLfqPrepareC( tracy::QueueType::GpuCalibration ); + tracy::MemWrite( &item->gpuCalibration.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuCalibration.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuCalibration.cpuDelta, data.cpuDelta ); + tracy::MemWrite( &item->gpuCalibration.context, data.context ); + TracyLfqCommitC; +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_serial( const struct ___tracy_gpu_zone_begin_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuZoneBeginSerial ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data data ) +{ + auto item = tracy::Profiler::QueueSerialCallstack( tracy::Callstack( data.depth ) ); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuZoneBeginCallstackSerial ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_serial( const struct ___tracy_gpu_zone_begin_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuZoneBeginAllocSrcLocSerial ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data data ) +{ + auto item = tracy::Profiler::QueueSerialCallstack( tracy::Callstack( data.depth ) ); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuZoneBeginAllocSrcLocCallstackSerial ); + tracy::MemWrite( &item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuZoneBegin.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuZoneBegin.srcloc, data.srcloc ); + tracy::MemWrite( &item->gpuZoneBegin.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneBegin.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_time_serial( const struct ___tracy_gpu_time_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuTime ); + tracy::MemWrite( &item->gpuTime.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuTime.queryId, data.queryId ); + tracy::MemWrite( &item->gpuTime.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_zone_end_serial( const struct ___tracy_gpu_zone_end_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuZoneEndSerial ); + tracy::MemWrite( &item->gpuZoneEnd.cpuTime, tracy::Profiler::GetTime() ); + memset( &item->gpuZoneEnd.thread, 0, sizeof( item->gpuZoneEnd.thread ) ); + tracy::MemWrite( &item->gpuZoneEnd.queryId, data.queryId ); + tracy::MemWrite( &item->gpuZoneEnd.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_new_context_serial( ___tracy_gpu_new_context_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuNewContext ); + tracy::MemWrite( &item->gpuNewContext.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuNewContext.thread, tracy::GetThreadHandle() ); + tracy::MemWrite( &item->gpuNewContext.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuNewContext.period, data.period ); + tracy::MemWrite( &item->gpuNewContext.context, data.context ); + tracy::MemWrite( &item->gpuNewContext.flags, data.flags ); + tracy::MemWrite( &item->gpuNewContext.type, data.type ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_context_name_serial( const struct ___tracy_gpu_context_name_data data ) +{ + auto ptr = (char*)tracy::tracy_malloc( data.len ); + memcpy( ptr, data.name, data.len ); + + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuContextName ); + tracy::MemWrite( &item->gpuContextNameFat.context, data.context ); + tracy::MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + tracy::MemWrite( &item->gpuContextNameFat.size, data.len ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API void ___tracy_emit_gpu_calibration_serial( const struct ___tracy_gpu_calibration_data data ) +{ + auto item = tracy::Profiler::QueueSerial(); + tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuCalibration ); + tracy::MemWrite( &item->gpuCalibration.cpuTime, tracy::Profiler::GetTime() ); + tracy::MemWrite( &item->gpuCalibration.gpuTime, data.gpuTime ); + tracy::MemWrite( &item->gpuCalibration.cpuDelta, data.cpuDelta ); + tracy::MemWrite( &item->gpuCalibration.context, data.context ); + tracy::Profiler::QueueSerialFinish(); +} + +TRACY_API int ___tracy_connected( void ) +{ + return tracy::GetProfiler().IsConnected(); +} + +#ifdef TRACY_FIBERS +TRACY_API void ___tracy_fiber_enter( const char* fiber ){ tracy::Profiler::EnterFiber( fiber ); } +TRACY_API void ___tracy_fiber_leave( void ){ tracy::Profiler::LeaveFiber(); } +#endif + +# ifdef TRACY_MANUAL_LIFETIME +TRACY_API void ___tracy_startup_profiler( void ) +{ + tracy::StartupProfiler(); +} + +TRACY_API void ___tracy_shutdown_profiler( void ) +{ + tracy::ShutdownProfiler(); +} +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyProfiler.hpp b/Externals/tracy/public/client/TracyProfiler.hpp new file mode 100644 index 00000000000..e3b256dfa63 --- /dev/null +++ b/Externals/tracy/public/client/TracyProfiler.hpp @@ -0,0 +1,1002 @@ +#ifndef __TRACYPROFILER_HPP__ +#define __TRACYPROFILER_HPP__ + +#include +#include +#include +#include +#include + +#include "tracy_concurrentqueue.h" +#include "tracy_SPSCQueue.h" +#include "TracyCallstack.hpp" +#include "TracySysPower.hpp" +#include "TracySysTime.hpp" +#include "TracyFastVector.hpp" +#include "../common/TracyQueue.hpp" +#include "../common/TracyAlign.hpp" +#include "../common/TracyAlloc.hpp" +#include "../common/TracyMutex.hpp" +#include "../common/TracyProtocol.hpp" + +#if defined _WIN32 +# include +#endif +#ifdef __APPLE__ +# include +# include +#endif + +#if ( defined _WIN32 || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) ) +# define TRACY_HW_TIMER +#endif + +#ifdef __linux__ +# include +#endif + +#if defined TRACY_TIMER_FALLBACK || !defined TRACY_HW_TIMER +# include +#endif + +#ifndef TracyConcat +# define TracyConcat(x,y) TracyConcatIndirect(x,y) +#endif +#ifndef TracyConcatIndirect +# define TracyConcatIndirect(x,y) x##y +#endif + +namespace tracy +{ +#if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME) +TRACY_API void StartupProfiler(); +TRACY_API void ShutdownProfiler(); +#endif + +class GpuCtx; +class Profiler; +class Socket; +class UdpBroadcast; + +struct GpuCtxWrapper +{ + GpuCtx* ptr; +}; + +TRACY_API moodycamel::ConcurrentQueue::ExplicitProducer* GetToken(); +TRACY_API Profiler& GetProfiler(); +TRACY_API std::atomic& GetLockCounter(); +TRACY_API std::atomic& GetGpuCtxCounter(); +TRACY_API GpuCtxWrapper& GetGpuCtx(); +TRACY_API uint32_t GetThreadHandle(); +TRACY_API bool ProfilerAvailable(); +TRACY_API bool ProfilerAllocatorAvailable(); +TRACY_API int64_t GetFrequencyQpc(); + +#if defined TRACY_TIMER_FALLBACK && defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) +TRACY_API bool HardwareSupportsInvariantTSC(); // check, if we need fallback scenario +#else +# if defined TRACY_HW_TIMER +tracy_force_inline bool HardwareSupportsInvariantTSC() +{ + return true; // this is checked at startup +} +# else +tracy_force_inline bool HardwareSupportsInvariantTSC() +{ + return false; +} +# endif +#endif + + +struct SourceLocationData +{ + const char* name; + const char* function; + const char* file; + uint32_t line; + uint32_t color; +}; + +#ifdef TRACY_ON_DEMAND +struct LuaZoneState +{ + uint32_t counter; + bool active; +}; +#endif + + +#define TracyLfqPrepare( _type ) \ + moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ + auto __token = GetToken(); \ + auto& __tail = __token->get_tail_index(); \ + auto item = __token->enqueue_begin( __magic ); \ + MemWrite( &item->hdr.type, _type ); + +#define TracyLfqCommit \ + __tail.store( __magic + 1, std::memory_order_release ); + +#define TracyLfqPrepareC( _type ) \ + tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ + auto __token = tracy::GetToken(); \ + auto& __tail = __token->get_tail_index(); \ + auto item = __token->enqueue_begin( __magic ); \ + tracy::MemWrite( &item->hdr.type, _type ); + +#define TracyLfqCommitC \ + __tail.store( __magic + 1, std::memory_order_release ); + + +#ifdef TRACY_FIBERS +# define TracyQueuePrepare( _type ) \ + auto item = Profiler::QueueSerial(); \ + MemWrite( &item->hdr.type, _type ); +# define TracyQueueCommit( _name ) \ + MemWrite( &item->_name.thread, GetThreadHandle() ); \ + Profiler::QueueSerialFinish(); +# define TracyQueuePrepareC( _type ) \ + auto item = tracy::Profiler::QueueSerial(); \ + tracy::MemWrite( &item->hdr.type, _type ); +# define TracyQueueCommitC( _name ) \ + tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \ + tracy::Profiler::QueueSerialFinish(); +#else +# define TracyQueuePrepare( _type ) TracyLfqPrepare( _type ) +# define TracyQueueCommit( _name ) TracyLfqCommit +# define TracyQueuePrepareC( _type ) TracyLfqPrepareC( _type ) +# define TracyQueueCommitC( _name ) TracyLfqCommitC +#endif + + +typedef void(*ParameterCallback)( void* data, uint32_t idx, int32_t val ); +typedef char*(*SourceContentsCallback)( void* data, const char* filename, size_t& size ); + +class Profiler +{ + struct FrameImageQueueItem + { + void* image; + uint32_t frame; + uint16_t w; + uint16_t h; + bool flip; + }; + + enum class SymbolQueueItemType + { + CallstackFrame, + SymbolQuery, + ExternalName, + KernelCode, + SourceCode + }; + + struct SymbolQueueItem + { + SymbolQueueItemType type; + uint64_t ptr; + uint64_t extra; + uint32_t id; + }; + +public: + Profiler(); + ~Profiler(); + + void SpawnWorkerThreads(); + + static tracy_force_inline int64_t GetTime() + { +#ifdef TRACY_HW_TIMER +# if defined TARGET_OS_IOS && TARGET_OS_IOS == 1 + if( HardwareSupportsInvariantTSC() ) return mach_absolute_time(); +# elif defined _WIN32 +# ifdef TRACY_TIMER_QPC + return GetTimeQpc(); +# else + if( HardwareSupportsInvariantTSC() ) return int64_t( __rdtsc() ); +# endif +# elif defined __i386 || defined _M_IX86 + if( HardwareSupportsInvariantTSC() ) + { + uint32_t eax, edx; + asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) ); + return ( uint64_t( edx ) << 32 ) + uint64_t( eax ); + } +# elif defined __x86_64__ || defined _M_X64 + if( HardwareSupportsInvariantTSC() ) + { + uint64_t rax, rdx; +#ifdef TRACY_PATCHABLE_NOPSLEDS + // Some external tooling (such as rr) wants to patch our rdtsc and replace it by a + // branch to control the external input seen by a program. This kind of patching is + // not generally possible depending on the surrounding code and can lead to significant + // slowdowns if the compiler generated unlucky code and rr and tracy are used together. + // To avoid this, use the rr-safe `nopl 0(%rax, %rax, 1); rdtsc` instruction sequence, + // which rr promises will be patchable independent of the surrounding code. + asm volatile ( + // This is nopl 0(%rax, %rax, 1), but assemblers are inconsistent about whether + // they emit that as a 4 or 5 byte sequence and we need to be guaranteed to use + // the 5 byte one. + ".byte 0x0f, 0x1f, 0x44, 0x00, 0x00\n\t" + "rdtsc" : "=a" (rax), "=d" (rdx) ); +#else + asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) ); +#endif + return (int64_t)(( rdx << 32 ) + rax); + } +# else +# error "TRACY_HW_TIMER detection logic needs fixing" +# endif +#endif + +#if !defined TRACY_HW_TIMER || defined TRACY_TIMER_FALLBACK +# if defined __linux__ && defined CLOCK_MONOTONIC_RAW + struct timespec ts; + clock_gettime( CLOCK_MONOTONIC_RAW, &ts ); + return int64_t( ts.tv_sec ) * 1000000000ll + int64_t( ts.tv_nsec ); +# else + return std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); +# endif +#endif + +#if !defined TRACY_TIMER_FALLBACK + return 0; // unreachable branch +#endif + } + + tracy_force_inline uint32_t GetNextZoneId() + { + return m_zoneId.fetch_add( 1, std::memory_order_relaxed ); + } + + static tracy_force_inline QueueItem* QueueSerial() + { + auto& p = GetProfiler(); + p.m_serialLock.lock(); + return p.m_serialQueue.prepare_next(); + } + + static tracy_force_inline QueueItem* QueueSerialCallstack( void* ptr ) + { + auto& p = GetProfiler(); + p.m_serialLock.lock(); + p.SendCallstackSerial( ptr ); + return p.m_serialQueue.prepare_next(); + } + + static tracy_force_inline void QueueSerialFinish() + { + auto& p = GetProfiler(); + p.m_serialQueue.commit_next(); + p.m_serialLock.unlock(); + } + + static tracy_force_inline void SendFrameMark( const char* name ) + { + if( !name ) GetProfiler().m_frameCount.fetch_add( 1, std::memory_order_relaxed ); +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + auto item = QueueSerial(); + MemWrite( &item->hdr.type, QueueType::FrameMarkMsg ); + MemWrite( &item->frameMark.time, GetTime() ); + MemWrite( &item->frameMark.name, uint64_t( name ) ); + QueueSerialFinish(); + } + + static tracy_force_inline void SendFrameMark( const char* name, QueueType type ) + { + assert( type == QueueType::FrameMarkMsgStart || type == QueueType::FrameMarkMsgEnd ); +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + auto item = QueueSerial(); + MemWrite( &item->hdr.type, type ); + MemWrite( &item->frameMark.time, GetTime() ); + MemWrite( &item->frameMark.name, uint64_t( name ) ); + QueueSerialFinish(); + } + + static tracy_force_inline void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip ) + { +#ifndef TRACY_NO_FRAME_IMAGE + auto& profiler = GetProfiler(); + assert( profiler.m_frameCount.load( std::memory_order_relaxed ) < (std::numeric_limits::max)() ); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto sz = size_t( w ) * size_t( h ) * 4; + auto ptr = (char*)tracy_malloc( sz ); + memcpy( ptr, image, sz ); + + profiler.m_fiLock.lock(); + auto fi = profiler.m_fiQueue.prepare_next(); + fi->image = ptr; + fi->frame = uint32_t( profiler.m_frameCount.load( std::memory_order_relaxed ) - offset ); + fi->w = w; + fi->h = h; + fi->flip = flip; + profiler.m_fiQueue.commit_next(); + profiler.m_fiLock.unlock(); +#else + static_cast(image); // unused + static_cast(w); // unused + static_cast(h); // unused + static_cast(offset); // unused + static_cast(flip); // unused +#endif + } + + static tracy_force_inline void PlotData( const char* name, int64_t val ) + { +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + TracyLfqPrepare( QueueType::PlotDataInt ); + MemWrite( &item->plotDataInt.name, (uint64_t)name ); + MemWrite( &item->plotDataInt.time, GetTime() ); + MemWrite( &item->plotDataInt.val, val ); + TracyLfqCommit; + } + + static tracy_force_inline void PlotData( const char* name, float val ) + { +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + TracyLfqPrepare( QueueType::PlotDataFloat ); + MemWrite( &item->plotDataFloat.name, (uint64_t)name ); + MemWrite( &item->plotDataFloat.time, GetTime() ); + MemWrite( &item->plotDataFloat.val, val ); + TracyLfqCommit; + } + + static tracy_force_inline void PlotData( const char* name, double val ) + { +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + TracyLfqPrepare( QueueType::PlotDataDouble ); + MemWrite( &item->plotDataDouble.name, (uint64_t)name ); + MemWrite( &item->plotDataDouble.time, GetTime() ); + MemWrite( &item->plotDataDouble.val, val ); + TracyLfqCommit; + } + + static tracy_force_inline void ConfigurePlot( const char* name, PlotFormatType type, bool step, bool fill, uint32_t color ) + { + TracyLfqPrepare( QueueType::PlotConfig ); + MemWrite( &item->plotConfig.name, (uint64_t)name ); + MemWrite( &item->plotConfig.type, (uint8_t)type ); + MemWrite( &item->plotConfig.step, (uint8_t)step ); + MemWrite( &item->plotConfig.fill, (uint8_t)fill ); + MemWrite( &item->plotConfig.color, color ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + static tracy_force_inline void Message( const char* txt, size_t size, int callstack ) + { + assert( size < (std::numeric_limits::max)() ); +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + if( callstack != 0 ) + { + tracy::GetProfiler().SendCallstack( callstack ); + } + + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + + TracyQueuePrepare( callstack == 0 ? QueueType::Message : QueueType::MessageCallstack ); + MemWrite( &item->messageFat.time, GetTime() ); + MemWrite( &item->messageFat.text, (uint64_t)ptr ); + MemWrite( &item->messageFat.size, (uint16_t)size ); + TracyQueueCommit( messageFatThread ); + } + + static tracy_force_inline void Message( const char* txt, int callstack ) + { +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + if( callstack != 0 ) + { + tracy::GetProfiler().SendCallstack( callstack ); + } + + TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack ); + MemWrite( &item->messageLiteral.time, GetTime() ); + MemWrite( &item->messageLiteral.text, (uint64_t)txt ); + TracyQueueCommit( messageLiteralThread ); + } + + static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int callstack ) + { + assert( size < (std::numeric_limits::max)() ); +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + if( callstack != 0 ) + { + tracy::GetProfiler().SendCallstack( callstack ); + } + + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + + TracyQueuePrepare( callstack == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack ); + MemWrite( &item->messageColorFat.time, GetTime() ); + MemWrite( &item->messageColorFat.text, (uint64_t)ptr ); + MemWrite( &item->messageColorFat.b, uint8_t( ( color ) & 0xFF ) ); + MemWrite( &item->messageColorFat.g, uint8_t( ( color >> 8 ) & 0xFF ) ); + MemWrite( &item->messageColorFat.r, uint8_t( ( color >> 16 ) & 0xFF ) ); + MemWrite( &item->messageColorFat.size, (uint16_t)size ); + TracyQueueCommit( messageColorFatThread ); + } + + static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int callstack ) + { +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + if( callstack != 0 ) + { + tracy::GetProfiler().SendCallstack( callstack ); + } + + TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack ); + MemWrite( &item->messageColorLiteral.time, GetTime() ); + MemWrite( &item->messageColorLiteral.text, (uint64_t)txt ); + MemWrite( &item->messageColorLiteral.b, uint8_t( ( color ) & 0xFF ) ); + MemWrite( &item->messageColorLiteral.g, uint8_t( ( color >> 8 ) & 0xFF ) ); + MemWrite( &item->messageColorLiteral.r, uint8_t( ( color >> 16 ) & 0xFF ) ); + TracyQueueCommit( messageColorLiteralThread ); + } + + static tracy_force_inline void MessageAppInfo( const char* txt, size_t size ) + { + assert( size < (std::numeric_limits::max)() ); + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + TracyLfqPrepare( QueueType::MessageAppInfo ); + MemWrite( &item->messageFat.time, GetTime() ); + MemWrite( &item->messageFat.text, (uint64_t)ptr ); + MemWrite( &item->messageFat.size, (uint16_t)size ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + static tracy_force_inline void MemAlloc( const void* ptr, size_t size, bool secure ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemAlloc( QueueType::MemAlloc, thread, ptr, size ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemFree( const void* ptr, bool secure ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemFree( QueueType::MemFree, thread, ptr ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int depth, bool secure ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendCallstackSerial( callstack ); + SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size ); + profiler.m_serialLock.unlock(); +#else + static_cast(depth); // unused + MemAlloc( ptr, size, secure ); +#endif + } + + static tracy_force_inline void MemFreeCallstack( const void* ptr, int depth, bool secure ) + { + if( secure && !ProfilerAvailable() ) return; + if( !ProfilerAllocatorAvailable() ) + { + MemFree( ptr, secure ); + return; + } +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendCallstackSerial( callstack ); + SendMemFree( QueueType::MemFreeCallstack, thread, ptr ); + profiler.m_serialLock.unlock(); +#else + static_cast(depth); // unused + MemFree( ptr, secure ); +#endif + } + + static tracy_force_inline void MemAllocNamed( const void* ptr, size_t size, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemName( name ); + SendMemAlloc( QueueType::MemAllocNamed, thread, ptr, size ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemFreeNamed( const void* ptr, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemName( name ); + SendMemFree( QueueType::MemFreeNamed, thread, ptr ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendCallstackSerial( callstack ); + SendMemName( name ); + SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size ); + profiler.m_serialLock.unlock(); +#else + static_cast(depth); // unused + static_cast(name); // unused + MemAlloc( ptr, size, secure ); +#endif + } + + static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendCallstackSerial( callstack ); + SendMemName( name ); + SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr ); + profiler.m_serialLock.unlock(); +#else + static_cast(depth); // unused + static_cast(name); // unused + MemFree( ptr, secure ); +#endif + } + + static tracy_force_inline void SendCallstack( int depth ) + { +#ifdef TRACY_HAS_CALLSTACK + auto ptr = Callstack( depth ); + TracyQueuePrepare( QueueType::Callstack ); + MemWrite( &item->callstackFat.ptr, (uint64_t)ptr ); + TracyQueueCommit( callstackFatThread ); +#else + static_cast(depth); // unused +#endif + } + + static tracy_force_inline void ParameterRegister( ParameterCallback cb, void* data ) + { + auto& profiler = GetProfiler(); + profiler.m_paramCallback = cb; + profiler.m_paramCallbackData = data; + } + + static tracy_force_inline void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val ) + { + TracyLfqPrepare( QueueType::ParamSetup ); + tracy::MemWrite( &item->paramSetup.idx, idx ); + tracy::MemWrite( &item->paramSetup.name, (uint64_t)name ); + tracy::MemWrite( &item->paramSetup.isBool, (uint8_t)isBool ); + tracy::MemWrite( &item->paramSetup.val, val ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + static tracy_force_inline void SourceCallbackRegister( SourceContentsCallback cb, void* data ) + { + auto& profiler = GetProfiler(); + profiler.m_sourceCallback = cb; + profiler.m_sourceCallbackData = data; + } + +#ifdef TRACY_FIBERS + static tracy_force_inline void EnterFiber( const char* fiber ) + { + TracyQueuePrepare( QueueType::FiberEnter ); + MemWrite( &item->fiberEnter.time, GetTime() ); + MemWrite( &item->fiberEnter.fiber, (uint64_t)fiber ); + TracyQueueCommit( fiberEnter ); + } + + static tracy_force_inline void LeaveFiber() + { + TracyQueuePrepare( QueueType::FiberLeave ); + MemWrite( &item->fiberLeave.time, GetTime() ); + TracyQueueCommit( fiberLeave ); + } +#endif + + void SendCallstack( int depth, const char* skipBefore ); + static void CutCallstack( void* callstack, const char* skipBefore ); + + static bool ShouldExit(); + + tracy_force_inline bool IsConnected() const + { + return m_isConnected.load( std::memory_order_acquire ); + } + + tracy_force_inline void SetProgramName( const char* name ) + { + m_programNameLock.lock(); + m_programName = name; + m_programNameLock.unlock(); + } + +#ifdef TRACY_ON_DEMAND + tracy_force_inline uint64_t ConnectionId() const + { + return m_connectionId.load( std::memory_order_acquire ); + } + + tracy_force_inline void DeferItem( const QueueItem& item ) + { + m_deferredLock.lock(); + auto dst = m_deferredQueue.push_next(); + memcpy( dst, &item, sizeof( item ) ); + m_deferredLock.unlock(); + } +#endif + + void RequestShutdown() { m_shutdown.store( true, std::memory_order_relaxed ); m_shutdownManual.store( true, std::memory_order_relaxed ); } + bool HasShutdownFinished() const { return m_shutdownFinished.load( std::memory_order_relaxed ); } + + void SendString( uint64_t str, const char* ptr, QueueType type ) { SendString( str, ptr, strlen( ptr ), type ); } + void SendString( uint64_t str, const char* ptr, size_t len, QueueType type ); + void SendSingleString( const char* ptr ) { SendSingleString( ptr, strlen( ptr ) ); } + void SendSingleString( const char* ptr, size_t len ); + void SendSecondString( const char* ptr ) { SendSecondString( ptr, strlen( ptr ) ); } + void SendSecondString( const char* ptr, size_t len ); + + + // Allocated source location data layout: + // 2b payload size + // 4b color + // 4b source line + // fsz function name + // 1b null terminator + // ssz source file name + // 1b null terminator + // nsz zone name (optional) + + static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function ) + { + return AllocSourceLocation( line, source, function, nullptr, 0 ); + } + + static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz ) + { + return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz ); + } + + static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz ) + { + return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 ); + } + + static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz ) + { + const auto sz32 = uint32_t( 2 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz ); + assert( sz32 <= (std::numeric_limits::max)() ); + const auto sz = uint16_t( sz32 ); + auto ptr = (char*)tracy_malloc( sz ); + memcpy( ptr, &sz, 2 ); + memset( ptr + 2, 0, 4 ); + memcpy( ptr + 6, &line, 4 ); + memcpy( ptr + 10, function, functionSz ); + ptr[10 + functionSz] = '\0'; + memcpy( ptr + 10 + functionSz + 1, source, sourceSz ); + ptr[10 + functionSz + 1 + sourceSz] = '\0'; + if( nameSz != 0 ) + { + memcpy( ptr + 10 + functionSz + 1 + sourceSz + 1, name, nameSz ); + } + return uint64_t( ptr ); + } + +private: + enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty }; + enum class ThreadCtxStatus { Same, Changed, ConnectionLost }; + + static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); } + void Worker(); + +#ifndef TRACY_NO_FRAME_IMAGE + static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); } + void CompressWorker(); +#endif + +#ifdef TRACY_HAS_CALLSTACK + static void LaunchSymbolWorker( void* ptr ) { ((Profiler*)ptr)->SymbolWorker(); } + void SymbolWorker(); + void HandleSymbolQueueItem( const SymbolQueueItem& si ); +#endif + + void ClearQueues( tracy::moodycamel::ConsumerToken& token ); + void ClearSerial(); + DequeueStatus Dequeue( tracy::moodycamel::ConsumerToken& token ); + DequeueStatus DequeueContextSwitches( tracy::moodycamel::ConsumerToken& token, int64_t& timeStop ); + DequeueStatus DequeueSerial(); + ThreadCtxStatus ThreadCtxCheck( uint32_t threadId ); + bool CommitData(); + + tracy_force_inline bool AppendData( const void* data, size_t len ) + { + const auto ret = NeedDataSize( len ); + AppendDataUnsafe( data, len ); + return ret; + } + + tracy_force_inline bool NeedDataSize( size_t len ) + { + assert( len <= TargetFrameSize ); + bool ret = true; + if( m_bufferOffset - m_bufferStart + (int)len > TargetFrameSize ) + { + ret = CommitData(); + } + return ret; + } + + tracy_force_inline void AppendDataUnsafe( const void* data, size_t len ) + { + memcpy( m_buffer + m_bufferOffset, data, len ); + m_bufferOffset += int( len ); + } + + bool SendData( const char* data, size_t len ); + void SendLongString( uint64_t ptr, const char* str, size_t len, QueueType type ); + void SendSourceLocation( uint64_t ptr ); + void SendSourceLocationPayload( uint64_t ptr ); + void SendCallstackPayload( uint64_t ptr ); + void SendCallstackPayload64( uint64_t ptr ); + void SendCallstackAlloc( uint64_t ptr ); + + void QueueCallstackFrame( uint64_t ptr ); + void QueueSymbolQuery( uint64_t symbol ); + void QueueExternalName( uint64_t ptr ); + void QueueKernelCode( uint64_t symbol, uint32_t size ); + void QueueSourceCodeQuery( uint32_t id ); + + bool HandleServerQuery(); + void HandleDisconnect(); + void HandleParameter( uint64_t payload ); + void HandleSymbolCodeQuery( uint64_t symbol, uint32_t size ); + void HandleSourceCodeQuery( char* data, char* image, uint32_t id ); + + void AckServerQuery(); + void AckSymbolCodeNotAvailable(); + + void CalibrateTimer(); + void CalibrateDelay(); + void ReportTopology(); + + static tracy_force_inline void SendCallstackSerial( void* ptr ) + { +#ifdef TRACY_HAS_CALLSTACK + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, QueueType::CallstackSerial ); + MemWrite( &item->callstackFat.ptr, (uint64_t)ptr ); + GetProfiler().m_serialQueue.commit_next(); +#else + static_cast(ptr); // unused +#endif + } + + static tracy_force_inline void SendMemAlloc( QueueType type, const uint32_t thread, const void* ptr, size_t size ) + { + assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack || type == QueueType::MemAllocNamed || type == QueueType::MemAllocCallstackNamed ); + + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, type ); + MemWrite( &item->memAlloc.time, GetTime() ); + MemWrite( &item->memAlloc.thread, thread ); + MemWrite( &item->memAlloc.ptr, (uint64_t)ptr ); + if( compile_time_condition::value ) + { + memcpy( &item->memAlloc.size, &size, 4 ); + memset( &item->memAlloc.size + 4, 0, 2 ); + } + else + { + assert( sizeof( size ) == 8 ); + memcpy( &item->memAlloc.size, &size, 4 ); + memcpy( ((char*)&item->memAlloc.size)+4, ((char*)&size)+4, 2 ); + } + GetProfiler().m_serialQueue.commit_next(); + } + + static tracy_force_inline void SendMemFree( QueueType type, const uint32_t thread, const void* ptr ) + { + assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack || type == QueueType::MemFreeNamed || type == QueueType::MemFreeCallstackNamed ); + + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, type ); + MemWrite( &item->memFree.time, GetTime() ); + MemWrite( &item->memFree.thread, thread ); + MemWrite( &item->memFree.ptr, (uint64_t)ptr ); + GetProfiler().m_serialQueue.commit_next(); + } + + static tracy_force_inline void SendMemName( const char* name ) + { + assert( name ); + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, QueueType::MemNamePayload ); + MemWrite( &item->memName.name, (uint64_t)name ); + GetProfiler().m_serialQueue.commit_next(); + } + +#if defined _WIN32 && defined TRACY_TIMER_QPC + static int64_t GetTimeQpc(); +#endif + + double m_timerMul; + uint64_t m_resolution; + uint64_t m_delay; + std::atomic m_timeBegin; + uint32_t m_mainThread; + uint64_t m_epoch, m_exectime; + std::atomic m_shutdown; + std::atomic m_shutdownManual; + std::atomic m_shutdownFinished; + Socket* m_sock; + UdpBroadcast* m_broadcast; + bool m_noExit; + uint32_t m_userPort; + std::atomic m_zoneId; + int64_t m_samplingPeriod; + + uint32_t m_threadCtx; + int64_t m_refTimeThread; + int64_t m_refTimeSerial; + int64_t m_refTimeCtx; + int64_t m_refTimeGpu; + + void* m_stream; // LZ4_stream_t* + char* m_buffer; + int m_bufferOffset; + int m_bufferStart; + + char* m_lz4Buf; + + FastVector m_serialQueue, m_serialDequeue; + TracyMutex m_serialLock; + +#ifndef TRACY_NO_FRAME_IMAGE + FastVector m_fiQueue, m_fiDequeue; + TracyMutex m_fiLock; +#endif + + SPSCQueue m_symbolQueue; + + std::atomic m_frameCount; + std::atomic m_isConnected; +#ifdef TRACY_ON_DEMAND + std::atomic m_connectionId; + + TracyMutex m_deferredLock; + FastVector m_deferredQueue; +#endif + +#ifdef TRACY_HAS_SYSTIME + void ProcessSysTime(); + + SysTime m_sysTime; + uint64_t m_sysTimeLast = 0; +#else + void ProcessSysTime() {} +#endif + +#ifdef TRACY_HAS_SYSPOWER + SysPower m_sysPower; +#endif + + ParameterCallback m_paramCallback; + void* m_paramCallbackData; + SourceContentsCallback m_sourceCallback; + void* m_sourceCallbackData; + + char* m_queryImage; + char* m_queryData; + char* m_queryDataPtr; + +#if defined _WIN32 + void* m_exceptionHandler; +#endif +#ifdef __linux__ + struct { + struct sigaction pwr, ill, fpe, segv, pipe, bus, abrt; + } m_prevSignal; +#endif + bool m_crashHandlerInstalled; + + const char* m_programName; + TracyMutex m_programNameLock; +}; + +} + +#endif diff --git a/Externals/tracy/public/client/TracyRingBuffer.hpp b/Externals/tracy/public/client/TracyRingBuffer.hpp new file mode 100644 index 00000000000..e9100e2d8b7 --- /dev/null +++ b/Externals/tracy/public/client/TracyRingBuffer.hpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TracyDebug.hpp" + +namespace tracy +{ + +class RingBuffer +{ +public: + RingBuffer( unsigned int size, int fd, int id, int cpu = -1 ) + : m_size( size ) + , m_id( id ) + , m_cpu( cpu ) + , m_fd( fd ) + { + const auto pageSize = uint32_t( getpagesize() ); + assert( size >= pageSize ); + assert( __builtin_popcount( size ) == 1 ); + m_mapSize = size + pageSize; + auto mapAddr = mmap( nullptr, m_mapSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); + if( mapAddr == MAP_FAILED ) + { + TracyDebug( "mmap failed: errno %i (%s)\n", errno, strerror( errno ) ); + m_fd = 0; + m_metadata = nullptr; + close( fd ); + return; + } + m_metadata = (perf_event_mmap_page*)mapAddr; + assert( m_metadata->data_offset == pageSize ); + m_buffer = ((char*)mapAddr) + pageSize; + m_tail = m_metadata->data_tail; + } + + ~RingBuffer() + { + if( m_metadata ) munmap( m_metadata, m_mapSize ); + if( m_fd ) close( m_fd ); + } + + RingBuffer( const RingBuffer& ) = delete; + RingBuffer& operator=( const RingBuffer& ) = delete; + + RingBuffer( RingBuffer&& other ) + { + memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) ); + m_metadata = nullptr; + m_fd = 0; + } + + RingBuffer& operator=( RingBuffer&& other ) + { + memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) ); + m_metadata = nullptr; + m_fd = 0; + return *this; + } + + bool IsValid() const { return m_metadata != nullptr; } + int GetId() const { return m_id; } + int GetCpu() const { return m_cpu; } + + void Enable() + { + ioctl( m_fd, PERF_EVENT_IOC_ENABLE, 0 ); + } + + void Read( void* dst, uint64_t offset, uint64_t cnt ) + { + const auto size = m_size; + auto src = ( m_tail + offset ) % size; + if( src + cnt <= size ) + { + memcpy( dst, m_buffer + src, cnt ); + } + else + { + const auto s0 = size - src; + const auto buf = m_buffer; + memcpy( dst, buf + src, s0 ); + memcpy( (char*)dst + s0, buf, cnt - s0 ); + } + } + + void Advance( uint64_t cnt ) + { + m_tail += cnt; + StoreTail(); + } + + bool CheckTscCaps() const + { + return m_metadata->cap_user_time_zero; + } + + int64_t ConvertTimeToTsc( int64_t timestamp ) const + { + if( !m_metadata->cap_user_time_zero ) return 0; + const auto time = timestamp - m_metadata->time_zero; + const auto quot = time / m_metadata->time_mult; + const auto rem = time % m_metadata->time_mult; + return ( quot << m_metadata->time_shift ) + ( rem << m_metadata->time_shift ) / m_metadata->time_mult; + } + + uint64_t LoadHead() const + { + return std::atomic_load_explicit( (const volatile std::atomic*)&m_metadata->data_head, std::memory_order_acquire ); + } + + uint64_t GetTail() const + { + return m_tail; + } + +private: + void StoreTail() + { + std::atomic_store_explicit( (volatile std::atomic*)&m_metadata->data_tail, m_tail, std::memory_order_release ); + } + + unsigned int m_size; + uint64_t m_tail; + char* m_buffer; + int m_id; + int m_cpu; + perf_event_mmap_page* m_metadata; + + size_t m_mapSize; + int m_fd; +}; + +} diff --git a/Externals/tracy/public/client/TracyScoped.hpp b/Externals/tracy/public/client/TracyScoped.hpp new file mode 100644 index 00000000000..d2274e40b0b --- /dev/null +++ b/Externals/tracy/public/client/TracyScoped.hpp @@ -0,0 +1,175 @@ +#ifndef __TRACYSCOPED_HPP__ +#define __TRACYSCOPED_HPP__ + +#include +#include +#include + +#include "../common/TracySystem.hpp" +#include "../common/TracyAlign.hpp" +#include "../common/TracyAlloc.hpp" +#include "TracyProfiler.hpp" + +namespace tracy +{ + +class ScopedZone +{ +public: + ScopedZone( const ScopedZone& ) = delete; + ScopedZone( ScopedZone&& ) = delete; + ScopedZone& operator=( const ScopedZone& ) = delete; + ScopedZone& operator=( ScopedZone&& ) = delete; + + tracy_force_inline ScopedZone( const SourceLocationData* srcloc, bool is_active = true ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + m_connectionId = GetProfiler().ConnectionId(); +#endif + TracyQueuePrepare( QueueType::ZoneBegin ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc ); + TracyQueueCommit( zoneBeginThread ); + } + + tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + m_connectionId = GetProfiler().ConnectionId(); +#endif + GetProfiler().SendCallstack( depth ); + + TracyQueuePrepare( QueueType::ZoneBeginCallstack ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc ); + TracyQueueCommit( zoneBeginThread ); + } + + tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active = true ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + m_connectionId = GetProfiler().ConnectionId(); +#endif + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc ); + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + } + + tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active = true ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + m_connectionId = GetProfiler().ConnectionId(); +#endif + GetProfiler().SendCallstack( depth ); + + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack ); + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + } + + tracy_force_inline ~ScopedZone() + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + if( GetProfiler().ConnectionId() != m_connectionId ) return; +#endif + TracyQueuePrepare( QueueType::ZoneEnd ); + MemWrite( &item->zoneEnd.time, Profiler::GetTime() ); + TracyQueueCommit( zoneEndThread ); + } + + tracy_force_inline void Text( const char* txt, size_t size ) + { + assert( size < (std::numeric_limits::max)() ); + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + if( GetProfiler().ConnectionId() != m_connectionId ) return; +#endif + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + TracyQueuePrepare( QueueType::ZoneText ); + MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommit( zoneTextFatThread ); + } + + tracy_force_inline void Name( const char* txt, size_t size ) + { + assert( size < (std::numeric_limits::max)() ); + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + if( GetProfiler().ConnectionId() != m_connectionId ) return; +#endif + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + TracyQueuePrepare( QueueType::ZoneName ); + MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommit( zoneTextFatThread ); + } + + tracy_force_inline void Color( uint32_t color ) + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + if( GetProfiler().ConnectionId() != m_connectionId ) return; +#endif + TracyQueuePrepare( QueueType::ZoneColor ); + MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) ); + MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) ); + MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) ); + TracyQueueCommit( zoneColorThread ); + } + + tracy_force_inline void Value( uint64_t value ) + { + if( !m_active ) return; +#ifdef TRACY_ON_DEMAND + if( GetProfiler().ConnectionId() != m_connectionId ) return; +#endif + TracyQueuePrepare( QueueType::ZoneValue ); + MemWrite( &item->zoneValue.value, value ); + TracyQueueCommit( zoneValueThread ); + } + + tracy_force_inline bool IsActive() const { return m_active; } + +private: + const bool m_active; + +#ifdef TRACY_ON_DEMAND + uint64_t m_connectionId = 0; +#endif +}; + +} + +#endif diff --git a/Externals/tracy/public/client/TracyStringHelpers.hpp b/Externals/tracy/public/client/TracyStringHelpers.hpp new file mode 100644 index 00000000000..977be6a3e9c --- /dev/null +++ b/Externals/tracy/public/client/TracyStringHelpers.hpp @@ -0,0 +1,41 @@ +#ifndef __TRACYSTRINGHELPERS_HPP__ +#define __TRACYSTRINGHELPERS_HPP__ + +#include +#include + +#include "../common/TracyAlloc.hpp" +#include "../common/TracyForceInline.hpp" + +namespace tracy +{ + +static tracy_force_inline char* CopyString( const char* src, size_t sz ) +{ + auto dst = (char*)tracy_malloc( sz + 1 ); + memcpy( dst, src, sz ); + dst[sz] = '\0'; + return dst; +} + +static tracy_force_inline char* CopyString( const char* src ) +{ + return CopyString( src, strlen( src ) ); +} + +static tracy_force_inline char* CopyStringFast( const char* src, size_t sz ) +{ + auto dst = (char*)tracy_malloc_fast( sz + 1 ); + memcpy( dst, src, sz ); + dst[sz] = '\0'; + return dst; +} + +static tracy_force_inline char* CopyStringFast( const char* src ) +{ + return CopyStringFast( src, strlen( src ) ); +} + +} + +#endif diff --git a/Externals/tracy/public/client/TracySysPower.cpp b/Externals/tracy/public/client/TracySysPower.cpp new file mode 100644 index 00000000000..bd5939da2b4 --- /dev/null +++ b/Externals/tracy/public/client/TracySysPower.cpp @@ -0,0 +1,164 @@ +#include "TracySysPower.hpp" + +#ifdef TRACY_HAS_SYSPOWER + +#include +#include +#include +#include +#include +#include + +#include "TracyDebug.hpp" +#include "TracyProfiler.hpp" +#include "../common/TracyAlloc.hpp" + +namespace tracy +{ + +SysPower::SysPower() + : m_domains( 4 ) + , m_lastTime( 0 ) +{ + ScanDirectory( "/sys/devices/virtual/powercap/intel-rapl", -1 ); +} + +SysPower::~SysPower() +{ + for( auto& v : m_domains ) + { + fclose( v.handle ); + // Do not release v.name, as it may be still needed + } +} + +void SysPower::Tick() +{ + auto t = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + if( t - m_lastTime > 10000000 ) // 10 ms + { + m_lastTime = t; + for( auto& v : m_domains ) + { + char tmp[32]; + if( fread( tmp, 1, 32, v.handle ) > 0 ) + { + rewind( v.handle ); + auto p = (uint64_t)atoll( tmp ); + uint64_t delta; + if( p >= v.value ) + { + delta = p - v.value; + } + else + { + delta = v.overflow - v.value + p; + } + v.value = p; + + TracyLfqPrepare( QueueType::SysPowerReport ); + MemWrite( &item->sysPower.time, Profiler::GetTime() ); + MemWrite( &item->sysPower.delta, delta ); + MemWrite( &item->sysPower.name, (uint64_t)v.name ); + TracyLfqCommit; + } + } + } +} + +void SysPower::ScanDirectory( const char* path, int parent ) +{ + DIR* dir = opendir( path ); + if( !dir ) return; + struct dirent* ent; + uint64_t maxRange = 0; + char* name = nullptr; + FILE* handle = nullptr; + while( ( ent = readdir( dir ) ) ) + { + if( ent->d_type == DT_REG ) + { + if( strcmp( ent->d_name, "max_energy_range_uj" ) == 0 ) + { + char tmp[PATH_MAX]; + snprintf( tmp, PATH_MAX, "%s/max_energy_range_uj", path ); + FILE* f = fopen( tmp, "r" ); + if( f ) + { + fscanf( f, "%" PRIu64, &maxRange ); + fclose( f ); + } + } + else if( strcmp( ent->d_name, "name" ) == 0 ) + { + char tmp[PATH_MAX]; + snprintf( tmp, PATH_MAX, "%s/name", path ); + FILE* f = fopen( tmp, "r" ); + if( f ) + { + char ntmp[128]; + if( fgets( ntmp, 128, f ) ) + { + // Last character is newline, skip it + const auto sz = strlen( ntmp ) - 1; + if( parent < 0 ) + { + name = (char*)tracy_malloc( sz + 1 ); + memcpy( name, ntmp, sz ); + name[sz] = '\0'; + } + else + { + const auto p = m_domains[parent]; + const auto psz = strlen( p.name ); + name = (char*)tracy_malloc( psz + sz + 2 ); + memcpy( name, p.name, psz ); + name[psz] = ':'; + memcpy( name+psz+1, ntmp, sz ); + name[psz+sz+1] = '\0'; + } + } + fclose( f ); + } + } + else if( strcmp( ent->d_name, "energy_uj" ) == 0 ) + { + char tmp[PATH_MAX]; + snprintf( tmp, PATH_MAX, "%s/energy_uj", path ); + handle = fopen( tmp, "r" ); + } + } + if( name && handle && maxRange > 0 ) break; + } + if( name && handle && maxRange > 0 ) + { + parent = (int)m_domains.size(); + Domain* domain = m_domains.push_next(); + domain->value = 0; + domain->overflow = maxRange; + domain->handle = handle; + domain->name = name; + TracyDebug( "Power domain id %i, %s found at %s\n", parent, name, path ); + } + else + { + if( name ) tracy_free( name ); + if( handle ) fclose( handle ); + } + + rewinddir( dir ); + while( ( ent = readdir( dir ) ) ) + { + if( ent->d_type == DT_DIR && strncmp( ent->d_name, "intel-rapl:", 11 ) == 0 ) + { + char tmp[PATH_MAX]; + snprintf( tmp, PATH_MAX, "%s/%s", path, ent->d_name ); + ScanDirectory( tmp, parent ); + } + } + closedir( dir ); +} + +} + +#endif diff --git a/Externals/tracy/public/client/TracySysPower.hpp b/Externals/tracy/public/client/TracySysPower.hpp new file mode 100644 index 00000000000..210123bce40 --- /dev/null +++ b/Externals/tracy/public/client/TracySysPower.hpp @@ -0,0 +1,44 @@ +#ifndef __TRACYSYSPOWER_HPP__ +#define __TRACYSYSPOWER_HPP__ + +#if defined __linux__ +# define TRACY_HAS_SYSPOWER +#endif + +#ifdef TRACY_HAS_SYSPOWER + +#include +#include + +#include "TracyFastVector.hpp" + +namespace tracy +{ + +class SysPower +{ + struct Domain + { + uint64_t value; + uint64_t overflow; + FILE* handle; + const char* name; + }; + +public: + SysPower(); + ~SysPower(); + + void Tick(); + +private: + void ScanDirectory( const char* path, int parent ); + + FastVector m_domains; + uint64_t m_lastTime; +}; + +} +#endif + +#endif diff --git a/Externals/tracy/public/client/TracySysTime.cpp b/Externals/tracy/public/client/TracySysTime.cpp new file mode 100644 index 00000000000..b690a911483 --- /dev/null +++ b/Externals/tracy/public/client/TracySysTime.cpp @@ -0,0 +1,108 @@ +#include "TracySysTime.hpp" + +#ifdef TRACY_HAS_SYSTIME + +# if defined _WIN32 +# include +# elif defined __linux__ +# include +# include +# elif defined __APPLE__ +# include +# include +# elif defined BSD +# include +# include +# endif + +namespace tracy +{ + +# if defined _WIN32 + +static inline uint64_t ConvertTime( const FILETIME& t ) +{ + return ( uint64_t( t.dwHighDateTime ) << 32 ) | uint64_t( t.dwLowDateTime ); +} + +void SysTime::ReadTimes() +{ + FILETIME idleTime; + FILETIME kernelTime; + FILETIME userTime; + + GetSystemTimes( &idleTime, &kernelTime, &userTime ); + + idle = ConvertTime( idleTime ); + const auto kernel = ConvertTime( kernelTime ); + const auto user = ConvertTime( userTime ); + used = kernel + user; +} + +# elif defined __linux__ + +void SysTime::ReadTimes() +{ + uint64_t user, nice, system; + FILE* f = fopen( "/proc/stat", "r" ); + if( f ) + { + int read = fscanf( f, "cpu %" PRIu64 " %" PRIu64 " %" PRIu64" %" PRIu64, &user, &nice, &system, &idle ); + fclose( f ); + if (read == 4) + { + used = user + nice + system; + } + } +} + +# elif defined __APPLE__ + +void SysTime::ReadTimes() +{ + host_cpu_load_info_data_t info; + mach_msg_type_number_t cnt = HOST_CPU_LOAD_INFO_COUNT; + host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast( &info ), &cnt ); + used = info.cpu_ticks[CPU_STATE_USER] + info.cpu_ticks[CPU_STATE_NICE] + info.cpu_ticks[CPU_STATE_SYSTEM]; + idle = info.cpu_ticks[CPU_STATE_IDLE]; +} + +# elif defined BSD + +void SysTime::ReadTimes() +{ + u_long data[5]; + size_t sz = sizeof( data ); + sysctlbyname( "kern.cp_time", &data, &sz, nullptr, 0 ); + used = data[0] + data[1] + data[2] + data[3]; + idle = data[4]; +} + +#endif + +SysTime::SysTime() +{ + ReadTimes(); +} + +float SysTime::Get() +{ + const auto oldUsed = used; + const auto oldIdle = idle; + + ReadTimes(); + + const auto diffIdle = idle - oldIdle; + const auto diffUsed = used - oldUsed; + +#if defined _WIN32 + return diffUsed == 0 ? -1 : ( diffUsed - diffIdle ) * 100.f / diffUsed; +#elif defined __linux__ || defined __APPLE__ || defined BSD + const auto total = diffUsed + diffIdle; + return total == 0 ? -1 : diffUsed * 100.f / total; +#endif +} + +} + +#endif diff --git a/Externals/tracy/public/client/TracySysTime.hpp b/Externals/tracy/public/client/TracySysTime.hpp new file mode 100644 index 00000000000..cb5ebe7361a --- /dev/null +++ b/Externals/tracy/public/client/TracySysTime.hpp @@ -0,0 +1,36 @@ +#ifndef __TRACYSYSTIME_HPP__ +#define __TRACYSYSTIME_HPP__ + +#if defined _WIN32 || defined __linux__ || defined __APPLE__ +# define TRACY_HAS_SYSTIME +#else +# include +#endif + +#ifdef BSD +# define TRACY_HAS_SYSTIME +#endif + +#ifdef TRACY_HAS_SYSTIME + +#include + +namespace tracy +{ + +class SysTime +{ +public: + SysTime(); + float Get(); + + void ReadTimes(); + +private: + uint64_t idle, used; +}; + +} +#endif + +#endif diff --git a/Externals/tracy/public/client/TracySysTrace.cpp b/Externals/tracy/public/client/TracySysTrace.cpp new file mode 100644 index 00000000000..af0641fef17 --- /dev/null +++ b/Externals/tracy/public/client/TracySysTrace.cpp @@ -0,0 +1,1602 @@ +#include "TracyDebug.hpp" +#include "TracyStringHelpers.hpp" +#include "TracySysTrace.hpp" +#include "../common/TracySystem.hpp" + +#ifdef TRACY_HAS_SYSTEM_TRACING + +#ifndef TRACY_SAMPLING_HZ +# if defined _WIN32 +# define TRACY_SAMPLING_HZ 8000 +# elif defined __linux__ +# define TRACY_SAMPLING_HZ 10000 +# endif +#endif + +namespace tracy +{ + +static constexpr int GetSamplingFrequency() +{ +#if defined _WIN32 + return TRACY_SAMPLING_HZ > 8000 ? 8000 : ( TRACY_SAMPLING_HZ < 1 ? 1 : TRACY_SAMPLING_HZ ); +#else + return TRACY_SAMPLING_HZ > 1000000 ? 1000000 : ( TRACY_SAMPLING_HZ < 1 ? 1 : TRACY_SAMPLING_HZ ); +#endif +} + +static constexpr int GetSamplingPeriod() +{ + return 1000000000 / GetSamplingFrequency(); +} + +} + +# if defined _WIN32 + +# ifndef NOMINMAX +# define NOMINMAX +# endif + +# define INITGUID +# include +# include +# include +# include +# include +# include +# include +# include + +# include "../common/TracyAlloc.hpp" +# include "../common/TracySystem.hpp" +# include "TracyProfiler.hpp" +# include "TracyThread.hpp" + +namespace tracy +{ + +static const GUID PerfInfoGuid = { 0xce1dbfb4, 0x137e, 0x4da6, { 0x87, 0xb0, 0x3f, 0x59, 0xaa, 0x10, 0x2c, 0xbc } }; +static const GUID DxgKrnlGuid = { 0x802ec45a, 0x1e99, 0x4b83, { 0x99, 0x20, 0x87, 0xc9, 0x82, 0x77, 0xba, 0x9d } }; +static const GUID ThreadV2Guid = { 0x3d6fa8d1, 0xfe05, 0x11d0, { 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c } }; + + +static TRACEHANDLE s_traceHandle; +static TRACEHANDLE s_traceHandle2; +static EVENT_TRACE_PROPERTIES* s_prop; +static DWORD s_pid; + +static EVENT_TRACE_PROPERTIES* s_propVsync; +static TRACEHANDLE s_traceHandleVsync; +static TRACEHANDLE s_traceHandleVsync2; +Thread* s_threadVsync = nullptr; + +struct CSwitch +{ + uint32_t newThreadId; + uint32_t oldThreadId; + int8_t newThreadPriority; + int8_t oldThreadPriority; + uint8_t previousCState; + int8_t spareByte; + int8_t oldThreadWaitReason; + int8_t oldThreadWaitMode; + int8_t oldThreadState; + int8_t oldThreadWaitIdealProcessor; + uint32_t newThreadWaitTime; + uint32_t reserved; +}; + +struct ReadyThread +{ + uint32_t threadId; + int8_t adjustReason; + int8_t adjustIncrement; + int8_t flag; + int8_t reserverd; +}; + +struct ThreadTrace +{ + uint32_t processId; + uint32_t threadId; + uint32_t stackBase; + uint32_t stackLimit; + uint32_t userStackBase; + uint32_t userStackLimit; + uint32_t startAddr; + uint32_t win32StartAddr; + uint32_t tebBase; + uint32_t subProcessTag; +}; + +struct StackWalkEvent +{ + uint64_t eventTimeStamp; + uint32_t stackProcess; + uint32_t stackThread; + uint64_t stack[192]; +}; + +struct VSyncInfo +{ + void* dxgAdapter; + uint32_t vidPnTargetId; + uint64_t scannedPhysicalAddress; + uint32_t vidPnSourceId; + uint32_t frameNumber; + int64_t frameQpcTime; + void* hFlipDevice; + uint32_t flipType; + uint64_t flipFenceId; +}; + +extern "C" typedef NTSTATUS (WINAPI *t_NtQueryInformationThread)( HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG ); +extern "C" typedef BOOL (WINAPI *t_EnumProcessModules)( HANDLE, HMODULE*, DWORD, LPDWORD ); +extern "C" typedef BOOL (WINAPI *t_GetModuleInformation)( HANDLE, HMODULE, LPMODULEINFO, DWORD ); +extern "C" typedef DWORD (WINAPI *t_GetModuleBaseNameA)( HANDLE, HMODULE, LPSTR, DWORD ); +extern "C" typedef HRESULT (WINAPI *t_GetThreadDescription)( HANDLE, PWSTR* ); + +t_NtQueryInformationThread NtQueryInformationThread = (t_NtQueryInformationThread)GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "NtQueryInformationThread" ); +t_EnumProcessModules _EnumProcessModules = (t_EnumProcessModules)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "K32EnumProcessModules" ); +t_GetModuleInformation _GetModuleInformation = (t_GetModuleInformation)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "K32GetModuleInformation" ); +t_GetModuleBaseNameA _GetModuleBaseNameA = (t_GetModuleBaseNameA)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "K32GetModuleBaseNameA" ); + +static t_GetThreadDescription _GetThreadDescription = 0; + + +void WINAPI EventRecordCallback( PEVENT_RECORD record ) +{ +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + + const auto& hdr = record->EventHeader; + switch( hdr.ProviderId.Data1 ) + { + case 0x3d6fa8d1: // Thread Guid + if( hdr.EventDescriptor.Opcode == 36 ) + { + const auto cswitch = (const CSwitch*)record->UserData; + + TracyLfqPrepare( QueueType::ContextSwitch ); + MemWrite( &item->contextSwitch.time, hdr.TimeStamp.QuadPart ); + MemWrite( &item->contextSwitch.oldThread, cswitch->oldThreadId ); + MemWrite( &item->contextSwitch.newThread, cswitch->newThreadId ); + MemWrite( &item->contextSwitch.cpu, record->BufferContext.ProcessorNumber ); + MemWrite( &item->contextSwitch.reason, cswitch->oldThreadWaitReason ); + MemWrite( &item->contextSwitch.state, cswitch->oldThreadState ); + TracyLfqCommit; + } + else if( hdr.EventDescriptor.Opcode == 50 ) + { + const auto rt = (const ReadyThread*)record->UserData; + + TracyLfqPrepare( QueueType::ThreadWakeup ); + MemWrite( &item->threadWakeup.time, hdr.TimeStamp.QuadPart ); + MemWrite( &item->threadWakeup.thread, rt->threadId ); + TracyLfqCommit; + } + else if( hdr.EventDescriptor.Opcode == 1 || hdr.EventDescriptor.Opcode == 3 ) + { + const auto tt = (const ThreadTrace*)record->UserData; + + uint64_t tid = tt->threadId; + if( tid == 0 ) return; + uint64_t pid = tt->processId; + TracyLfqPrepare( QueueType::TidToPid ); + MemWrite( &item->tidToPid.tid, tid ); + MemWrite( &item->tidToPid.pid, pid ); + TracyLfqCommit; + } + break; + case 0xdef2fe46: // StackWalk Guid + if( hdr.EventDescriptor.Opcode == 32 ) + { + const auto sw = (const StackWalkEvent*)record->UserData; + if( sw->stackProcess == s_pid ) + { + const uint64_t sz = ( record->UserDataLength - 16 ) / 8; + if( sz > 0 ) + { + auto trace = (uint64_t*)tracy_malloc( ( 1 + sz ) * sizeof( uint64_t ) ); + memcpy( trace, &sz, sizeof( uint64_t ) ); + memcpy( trace+1, sw->stack, sizeof( uint64_t ) * sz ); + TracyLfqPrepare( QueueType::CallstackSample ); + MemWrite( &item->callstackSampleFat.time, sw->eventTimeStamp ); + MemWrite( &item->callstackSampleFat.thread, sw->stackThread ); + MemWrite( &item->callstackSampleFat.ptr, (uint64_t)trace ); + TracyLfqCommit; + } + } + } + break; + default: + break; + } +} + +void WINAPI EventRecordCallbackVsync( PEVENT_RECORD record ) +{ +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + + const auto& hdr = record->EventHeader; + assert( hdr.ProviderId.Data1 == 0x802EC45A ); + assert( hdr.EventDescriptor.Id == 0x0011 ); + + const auto vs = (const VSyncInfo*)record->UserData; + + TracyLfqPrepare( QueueType::FrameVsync ); + MemWrite( &item->frameVsync.time, hdr.TimeStamp.QuadPart ); + MemWrite( &item->frameVsync.id, vs->vidPnTargetId ); + TracyLfqCommit; +} + +static void SetupVsync() +{ +#if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE && !defined(__MINGW32__) + const auto psz = sizeof( EVENT_TRACE_PROPERTIES ) + MAX_PATH; + s_propVsync = (EVENT_TRACE_PROPERTIES*)tracy_malloc( psz ); + memset( s_propVsync, 0, sizeof( EVENT_TRACE_PROPERTIES ) ); + s_propVsync->LogFileMode = EVENT_TRACE_REAL_TIME_MODE; + s_propVsync->Wnode.BufferSize = psz; +#ifdef TRACY_TIMER_QPC + s_propVsync->Wnode.ClientContext = 1; +#else + s_propVsync->Wnode.ClientContext = 3; +#endif + s_propVsync->LoggerNameOffset = sizeof( EVENT_TRACE_PROPERTIES ); + strcpy( ((char*)s_propVsync) + sizeof( EVENT_TRACE_PROPERTIES ), "TracyVsync" ); + + auto backup = tracy_malloc( psz ); + memcpy( backup, s_propVsync, psz ); + + const auto controlStatus = ControlTraceA( 0, "TracyVsync", s_propVsync, EVENT_TRACE_CONTROL_STOP ); + if( controlStatus != ERROR_SUCCESS && controlStatus != ERROR_WMI_INSTANCE_NOT_FOUND ) + { + tracy_free( backup ); + tracy_free( s_propVsync ); + return; + } + + memcpy( s_propVsync, backup, psz ); + tracy_free( backup ); + + const auto startStatus = StartTraceA( &s_traceHandleVsync, "TracyVsync", s_propVsync ); + if( startStatus != ERROR_SUCCESS ) + { + tracy_free( s_propVsync ); + return; + } + + EVENT_FILTER_EVENT_ID fe = {}; + fe.FilterIn = TRUE; + fe.Count = 1; + fe.Events[0] = 0x0011; // VSyncDPC_Info + + EVENT_FILTER_DESCRIPTOR desc = {}; + desc.Ptr = (ULONGLONG)&fe; + desc.Size = sizeof( fe ); + desc.Type = EVENT_FILTER_TYPE_EVENT_ID; + + ENABLE_TRACE_PARAMETERS params = {}; + params.Version = ENABLE_TRACE_PARAMETERS_VERSION_2; + params.EnableProperty = EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0; + params.SourceId = s_propVsync->Wnode.Guid; + params.EnableFilterDesc = &desc; + params.FilterDescCount = 1; + + uint64_t mask = 0x4000000000000001; // Microsoft_Windows_DxgKrnl_Performance | Base + if( EnableTraceEx2( s_traceHandleVsync, &DxgKrnlGuid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_INFORMATION, mask, mask, 0, ¶ms ) != ERROR_SUCCESS ) + { + tracy_free( s_propVsync ); + return; + } + + char loggerName[MAX_PATH]; + strcpy( loggerName, "TracyVsync" ); + + EVENT_TRACE_LOGFILEA log = {}; + log.LoggerName = loggerName; + log.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP; + log.EventRecordCallback = EventRecordCallbackVsync; + + s_traceHandleVsync2 = OpenTraceA( &log ); + if( s_traceHandleVsync2 == (TRACEHANDLE)INVALID_HANDLE_VALUE ) + { + CloseTrace( s_traceHandleVsync ); + tracy_free( s_propVsync ); + return; + } + + s_threadVsync = (Thread*)tracy_malloc( sizeof( Thread ) ); + new(s_threadVsync) Thread( [] (void*) { + ThreadExitHandler threadExitHandler; + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + SetThreadName( "Tracy Vsync" ); + ProcessTrace( &s_traceHandleVsync2, 1, nullptr, nullptr ); + }, nullptr ); +#endif +} + +static constexpr int GetSamplingInterval() +{ + return GetSamplingPeriod() / 100; +} + +bool SysTraceStart( int64_t& samplingPeriod ) +{ + if( !_GetThreadDescription ) _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" ); + + s_pid = GetCurrentProcessId(); + +#if defined _WIN64 + constexpr bool isOs64Bit = true; +#else + BOOL _iswow64; + IsWow64Process( GetCurrentProcess(), &_iswow64 ); + const bool isOs64Bit = _iswow64; +#endif + + TOKEN_PRIVILEGES priv = {}; + priv.PrivilegeCount = 1; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if( LookupPrivilegeValue( nullptr, SE_SYSTEM_PROFILE_NAME, &priv.Privileges[0].Luid ) == 0 ) return false; + + HANDLE pt; + if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &pt ) == 0 ) return false; + const auto adjust = AdjustTokenPrivileges( pt, FALSE, &priv, 0, nullptr, nullptr ); + CloseHandle( pt ); + if( adjust == 0 ) return false; + const auto status = GetLastError(); + if( status != ERROR_SUCCESS ) return false; + + if( isOs64Bit ) + { + TRACE_PROFILE_INTERVAL interval = {}; + interval.Interval = GetSamplingInterval(); + const auto intervalStatus = TraceSetInformation( 0, TraceSampledProfileIntervalInfo, &interval, sizeof( interval ) ); + if( intervalStatus != ERROR_SUCCESS ) return false; + samplingPeriod = GetSamplingPeriod(); + } + + const auto psz = sizeof( EVENT_TRACE_PROPERTIES ) + sizeof( KERNEL_LOGGER_NAME ); + s_prop = (EVENT_TRACE_PROPERTIES*)tracy_malloc( psz ); + memset( s_prop, 0, sizeof( EVENT_TRACE_PROPERTIES ) ); + ULONG flags = 0; +#ifndef TRACY_NO_CONTEXT_SWITCH + flags = EVENT_TRACE_FLAG_CSWITCH | EVENT_TRACE_FLAG_DISPATCHER | EVENT_TRACE_FLAG_THREAD; +#endif +#ifndef TRACY_NO_SAMPLING + if( isOs64Bit ) flags |= EVENT_TRACE_FLAG_PROFILE; +#endif + s_prop->EnableFlags = flags; + s_prop->LogFileMode = EVENT_TRACE_REAL_TIME_MODE; + s_prop->Wnode.BufferSize = psz; + s_prop->Wnode.Flags = WNODE_FLAG_TRACED_GUID; +#ifdef TRACY_TIMER_QPC + s_prop->Wnode.ClientContext = 1; +#else + s_prop->Wnode.ClientContext = 3; +#endif + s_prop->Wnode.Guid = SystemTraceControlGuid; + s_prop->BufferSize = 1024; + s_prop->MinimumBuffers = std::thread::hardware_concurrency() * 4; + s_prop->MaximumBuffers = std::thread::hardware_concurrency() * 6; + s_prop->LoggerNameOffset = sizeof( EVENT_TRACE_PROPERTIES ); + memcpy( ((char*)s_prop) + sizeof( EVENT_TRACE_PROPERTIES ), KERNEL_LOGGER_NAME, sizeof( KERNEL_LOGGER_NAME ) ); + + auto backup = tracy_malloc( psz ); + memcpy( backup, s_prop, psz ); + + const auto controlStatus = ControlTrace( 0, KERNEL_LOGGER_NAME, s_prop, EVENT_TRACE_CONTROL_STOP ); + if( controlStatus != ERROR_SUCCESS && controlStatus != ERROR_WMI_INSTANCE_NOT_FOUND ) + { + tracy_free( backup ); + tracy_free( s_prop ); + return false; + } + + memcpy( s_prop, backup, psz ); + tracy_free( backup ); + + const auto startStatus = StartTrace( &s_traceHandle, KERNEL_LOGGER_NAME, s_prop ); + if( startStatus != ERROR_SUCCESS ) + { + tracy_free( s_prop ); + return false; + } + +#ifndef TRACY_NO_SAMPLING + if( isOs64Bit ) + { + CLASSIC_EVENT_ID stackId[2] = {}; + stackId[0].EventGuid = PerfInfoGuid; + stackId[0].Type = 46; + stackId[1].EventGuid = ThreadV2Guid; + stackId[1].Type = 36; + const auto stackStatus = TraceSetInformation( s_traceHandle, TraceStackTracingInfo, &stackId, sizeof( stackId ) ); + if( stackStatus != ERROR_SUCCESS ) + { + tracy_free( s_prop ); + return false; + } + } +#endif + +#ifdef UNICODE + WCHAR KernelLoggerName[sizeof( KERNEL_LOGGER_NAME )]; +#else + char KernelLoggerName[sizeof( KERNEL_LOGGER_NAME )]; +#endif + memcpy( KernelLoggerName, KERNEL_LOGGER_NAME, sizeof( KERNEL_LOGGER_NAME ) ); + EVENT_TRACE_LOGFILE log = {}; + log.LoggerName = KernelLoggerName; + log.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP; + log.EventRecordCallback = EventRecordCallback; + + s_traceHandle2 = OpenTrace( &log ); + if( s_traceHandle2 == (TRACEHANDLE)INVALID_HANDLE_VALUE ) + { + CloseTrace( s_traceHandle ); + tracy_free( s_prop ); + return false; + } + +#ifndef TRACY_NO_VSYNC_CAPTURE + SetupVsync(); +#endif + + return true; +} + +void SysTraceStop() +{ + if( s_threadVsync ) + { + CloseTrace( s_traceHandleVsync2 ); + CloseTrace( s_traceHandleVsync ); + s_threadVsync->~Thread(); + tracy_free( s_threadVsync ); + } + + CloseTrace( s_traceHandle2 ); + CloseTrace( s_traceHandle ); +} + +void SysTraceWorker( void* ptr ) +{ + ThreadExitHandler threadExitHandler; + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + SetThreadName( "Tracy SysTrace" ); + ProcessTrace( &s_traceHandle2, 1, 0, 0 ); + ControlTrace( 0, KERNEL_LOGGER_NAME, s_prop, EVENT_TRACE_CONTROL_STOP ); + tracy_free( s_prop ); +} + +void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name ) +{ + bool threadSent = false; + auto hnd = OpenThread( THREAD_QUERY_INFORMATION, FALSE, DWORD( thread ) ); + if( hnd == 0 ) + { + hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, DWORD( thread ) ); + } + if( hnd != 0 ) + { + if( _GetThreadDescription ) + { + PWSTR tmp; + _GetThreadDescription( hnd, &tmp ); + char buf[256]; + if( tmp ) + { + auto ret = wcstombs( buf, tmp, 256 ); + if( ret != 0 ) + { + threadName = CopyString( buf, ret ); + threadSent = true; + } + } + } + const auto pid = GetProcessIdOfThread( hnd ); + if( !threadSent && NtQueryInformationThread && _EnumProcessModules && _GetModuleInformation && _GetModuleBaseNameA ) + { + void* ptr; + ULONG retlen; + auto status = NtQueryInformationThread( hnd, (THREADINFOCLASS)9 /*ThreadQuerySetWin32StartAddress*/, &ptr, sizeof( &ptr ), &retlen ); + if( status == 0 ) + { + const auto phnd = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if( phnd != INVALID_HANDLE_VALUE ) + { + HMODULE modules[1024]; + DWORD needed; + if( _EnumProcessModules( phnd, modules, 1024 * sizeof( HMODULE ), &needed ) != 0 ) + { + const auto sz = std::min( DWORD( needed / sizeof( HMODULE ) ), DWORD( 1024 ) ); + for( DWORD i=0; i= (uint64_t)info.lpBaseOfDll && (uint64_t)ptr <= (uint64_t)info.lpBaseOfDll + (uint64_t)info.SizeOfImage ) + { + char buf2[1024]; + const auto modlen = _GetModuleBaseNameA( phnd, modules[i], buf2, 1024 ); + if( modlen != 0 ) + { + threadName = CopyString( buf2, modlen ); + threadSent = true; + } + } + } + } + } + CloseHandle( phnd ); + } + } + } + CloseHandle( hnd ); + if( !threadSent ) + { + threadName = CopyString( "???", 3 ); + threadSent = true; + } + if( pid != 0 ) + { + { + uint64_t _pid = pid; + TracyLfqPrepare( QueueType::TidToPid ); + MemWrite( &item->tidToPid.tid, thread ); + MemWrite( &item->tidToPid.pid, _pid ); + TracyLfqCommit; + } + if( pid == 4 ) + { + name = CopyStringFast( "System", 6 ); + return; + } + else + { + const auto phnd = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid ); + if( phnd != INVALID_HANDLE_VALUE ) + { + char buf2[1024]; + const auto sz = GetProcessImageFileNameA( phnd, buf2, 1024 ); + CloseHandle( phnd ); + if( sz != 0 ) + { + auto ptr = buf2 + sz - 1; + while( ptr > buf2 && *ptr != '\\' ) ptr--; + if( *ptr == '\\' ) ptr++; + name = CopyStringFast( ptr ); + return; + } + } + } + } + } + + if( !threadSent ) + { + threadName = CopyString( "???", 3 ); + } + name = CopyStringFast( "???", 3 ); +} + +} + +# elif defined __linux__ + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# if defined __i386 || defined __x86_64__ +# include "TracyCpuid.hpp" +# endif + +# include "TracyProfiler.hpp" +# include "TracyRingBuffer.hpp" +# include "TracyThread.hpp" + +namespace tracy +{ + +static std::atomic traceActive { false }; +static int s_numCpus = 0; +static int s_numBuffers = 0; +static int s_ctxBufferIdx = 0; + +static RingBuffer* s_ring = nullptr; + +static const int ThreadHashSize = 4 * 1024; +static uint32_t s_threadHash[ThreadHashSize] = {}; + +static bool CurrentProcOwnsThread( uint32_t tid ) +{ + const auto hash = tid & ( ThreadHashSize-1 ); + const auto hv = s_threadHash[hash]; + if( hv == tid ) return true; + if( hv == -tid ) return false; + + char path[256]; + sprintf( path, "/proc/self/task/%d", tid ); + struct stat st; + if( stat( path, &st ) == 0 ) + { + s_threadHash[hash] = tid; + return true; + } + else + { + s_threadHash[hash] = -tid; + return false; + } +} + +static int perf_event_open( struct perf_event_attr* hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags ) +{ + return syscall( __NR_perf_event_open, hw_event, pid, cpu, group_fd, flags ); +} + +enum TraceEventId +{ + EventCallstack, + EventCpuCycles, + EventInstructionsRetired, + EventCacheReference, + EventCacheMiss, + EventBranchRetired, + EventBranchMiss, + EventVsync, + EventContextSwitch, + EventWakeup, +}; + +static void ProbePreciseIp( perf_event_attr& pe, unsigned long long config0, unsigned long long config1, pid_t pid ) +{ + pe.config = config1; + pe.precise_ip = 3; + while( pe.precise_ip != 0 ) + { + const int fd = perf_event_open( &pe, pid, 0, -1, PERF_FLAG_FD_CLOEXEC ); + if( fd != -1 ) + { + close( fd ); + break; + } + pe.precise_ip--; + } + pe.config = config0; + while( pe.precise_ip != 0 ) + { + const int fd = perf_event_open( &pe, pid, 0, -1, PERF_FLAG_FD_CLOEXEC ); + if( fd != -1 ) + { + close( fd ); + break; + } + pe.precise_ip--; + } + TracyDebug( " Probed precise_ip: %i\n", pe.precise_ip ); +} + +static void ProbePreciseIp( perf_event_attr& pe, pid_t pid ) +{ + pe.precise_ip = 3; + while( pe.precise_ip != 0 ) + { + const int fd = perf_event_open( &pe, pid, 0, -1, PERF_FLAG_FD_CLOEXEC ); + if( fd != -1 ) + { + close( fd ); + break; + } + pe.precise_ip--; + } + TracyDebug( " Probed precise_ip: %i\n", pe.precise_ip ); +} + +static bool IsGenuineIntel() +{ +#if defined __i386 || defined __x86_64__ + uint32_t regs[4] = {}; + __get_cpuid( 0, regs, regs+1, regs+2, regs+3 ); + char manufacturer[12]; + memcpy( manufacturer, regs+1, 4 ); + memcpy( manufacturer+4, regs+3, 4 ); + memcpy( manufacturer+8, regs+2, 4 ); + return memcmp( manufacturer, "GenuineIntel", 12 ) == 0; +#else + return false; +#endif +} + +static const char* ReadFile( const char* path ) +{ + int fd = open( path, O_RDONLY ); + if( fd < 0 ) return nullptr; + + static char tmp[64]; + const auto cnt = read( fd, tmp, 63 ); + close( fd ); + if( cnt < 0 ) return nullptr; + tmp[cnt] = '\0'; + return tmp; +} + +bool SysTraceStart( int64_t& samplingPeriod ) +{ +#ifndef CLOCK_MONOTONIC_RAW + return false; +#endif + + const auto paranoidLevelStr = ReadFile( "/proc/sys/kernel/perf_event_paranoid" ); + if( !paranoidLevelStr ) return false; +#ifdef TRACY_VERBOSE + int paranoidLevel = 2; + paranoidLevel = atoi( paranoidLevelStr ); + TracyDebug( "perf_event_paranoid: %i\n", paranoidLevel ); +#endif + + int switchId = -1, wakeupId = -1, vsyncId = -1; + const auto switchIdStr = ReadFile( "/sys/kernel/debug/tracing/events/sched/sched_switch/id" ); + if( switchIdStr ) switchId = atoi( switchIdStr ); + const auto wakeupIdStr = ReadFile( "/sys/kernel/debug/tracing/events/sched/sched_wakeup/id" ); + if( wakeupIdStr ) wakeupId = atoi( wakeupIdStr ); + const auto vsyncIdStr = ReadFile( "/sys/kernel/debug/tracing/events/drm/drm_vblank_event/id" ); + if( vsyncIdStr ) vsyncId = atoi( vsyncIdStr ); + + TracyDebug( "sched_switch id: %i\n", switchId ); + TracyDebug( "sched_wakeup id: %i\n", wakeupId ); + TracyDebug( "drm_vblank_event id: %i\n", vsyncId ); + +#ifdef TRACY_NO_SAMPLING + const bool noSoftwareSampling = true; +#else + const char* noSoftwareSamplingEnv = GetEnvVar( "TRACY_NO_SAMPLING" ); + const bool noSoftwareSampling = noSoftwareSamplingEnv && noSoftwareSamplingEnv[0] == '1'; +#endif + +#ifdef TRACY_NO_SAMPLE_RETIREMENT + const bool noRetirement = true; +#else + const char* noRetirementEnv = GetEnvVar( "TRACY_NO_SAMPLE_RETIREMENT" ); + const bool noRetirement = noRetirementEnv && noRetirementEnv[0] == '1'; +#endif + +#ifdef TRACY_NO_SAMPLE_CACHE + const bool noCache = true; +#else + const char* noCacheEnv = GetEnvVar( "TRACY_NO_SAMPLE_CACHE" ); + const bool noCache = noCacheEnv && noCacheEnv[0] == '1'; +#endif + +#ifdef TRACY_NO_SAMPLE_BRANCH + const bool noBranch = true; +#else + const char* noBranchEnv = GetEnvVar( "TRACY_NO_SAMPLE_BRANCH" ); + const bool noBranch = noBranchEnv && noBranchEnv[0] == '1'; +#endif + +#ifdef TRACY_NO_CONTEXT_SWITCH + const bool noCtxSwitch = true; +#else + const char* noCtxSwitchEnv = GetEnvVar( "TRACY_NO_CONTEXT_SWITCH" ); + const bool noCtxSwitch = noCtxSwitchEnv && noCtxSwitchEnv[0] == '1'; +#endif + +#ifdef TRACY_NO_VSYNC_CAPTURE + const bool noVsync = true; +#else + const char* noVsyncEnv = GetEnvVar( "TRACY_NO_VSYNC_CAPTURE" ); + const bool noVsync = noVsyncEnv && noVsyncEnv[0] == '1'; +#endif + + samplingPeriod = GetSamplingPeriod(); + uint32_t currentPid = (uint32_t)getpid(); + + s_numCpus = (int)std::thread::hardware_concurrency(); + + const auto maxNumBuffers = s_numCpus * ( + 1 + // software sampling + 2 + // CPU cycles + instructions retired + 2 + // cache reference + miss + 2 + // branch retired + miss + 2 + // context switches + wakeups + 1 // vsync + ); + s_ring = (RingBuffer*)tracy_malloc( sizeof( RingBuffer ) * maxNumBuffers ); + s_numBuffers = 0; + + // software sampling + perf_event_attr pe = {}; + pe.type = PERF_TYPE_SOFTWARE; + pe.size = sizeof( perf_event_attr ); + pe.config = PERF_COUNT_SW_CPU_CLOCK; + pe.sample_freq = GetSamplingFrequency(); + pe.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_CALLCHAIN; +#if LINUX_VERSION_CODE >= KERNEL_VERSION( 4, 8, 0 ) + pe.sample_max_stack = 127; +#endif + pe.disabled = 1; + pe.freq = 1; + pe.inherit = 1; +#if !defined TRACY_HW_TIMER || !( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) + pe.use_clockid = 1; + pe.clockid = CLOCK_MONOTONIC_RAW; +#endif + + if( !noSoftwareSampling ) + { + TracyDebug( "Setup software sampling\n" ); + ProbePreciseIp( pe, currentPid ); + for( int i=0; i= KERNEL_VERSION( 4, 8, 0 ) + pe.sample_max_stack = 127; +#endif + pe.disabled = 1; + pe.inherit = 1; + pe.config = switchId; +#if !defined TRACY_HW_TIMER || !( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) + pe.use_clockid = 1; + pe.clockid = CLOCK_MONOTONIC_RAW; +#endif + + TracyDebug( "Setup context switch capture\n" ); + for( int i=0; i> 63; + const auto m2 = test >> 47; + if( m1 == m2 ) break; + } + while( --cnt > 0 ); + for( uint64_t j=1; j> 63; + const auto m2 = test >> 47; + if( m1 != m2 ) trace[j] = 0; + } +#endif + + for( uint64_t j=1; j<=cnt; j++ ) + { + if( trace[j] >= (uint64_t)-4095 ) // PERF_CONTEXT_MAX + { + memmove( trace+j, trace+j+1, sizeof( uint64_t ) * ( cnt - j ) ); + cnt--; + } + } + + memcpy( trace, &cnt, sizeof( uint64_t ) ); + return trace; +} + +void SysTraceWorker( void* ptr ) +{ + ThreadExitHandler threadExitHandler; + SetThreadName( "Tracy Sampling" ); + InitRpmalloc(); + sched_param sp = { 99 }; + if( pthread_setschedparam( pthread_self(), SCHED_FIFO, &sp ) != 0 ) TracyDebug( "Failed to increase SysTraceWorker thread priority!\n" ); + auto ctxBufferIdx = s_ctxBufferIdx; + auto ringArray = s_ring; + auto numBuffers = s_numBuffers; + for( int i=0; i tail ); + hadData = true; + + const auto id = ring.GetId(); + assert( id != EventContextSwitch ); + const auto end = head - tail; + uint64_t pos = 0; + if( id == EventCallstack ) + { + while( pos < end ) + { + perf_event_header hdr; + ring.Read( &hdr, pos, sizeof( perf_event_header ) ); + if( hdr.type == PERF_RECORD_SAMPLE ) + { + auto offset = pos + sizeof( perf_event_header ); + + // Layout: + // u32 pid, tid + // u64 time + // u64 cnt + // u64 ip[cnt] + + uint32_t tid; + uint64_t t0; + uint64_t cnt; + + offset += sizeof( uint32_t ); + ring.Read( &tid, offset, sizeof( uint32_t ) ); + offset += sizeof( uint32_t ); + ring.Read( &t0, offset, sizeof( uint64_t ) ); + offset += sizeof( uint64_t ); + ring.Read( &cnt, offset, sizeof( uint64_t ) ); + offset += sizeof( uint64_t ); + + if( cnt > 0 ) + { +#if defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) + t0 = ring.ConvertTimeToTsc( t0 ); +#endif + auto trace = GetCallstackBlock( cnt, ring, offset ); + + TracyLfqPrepare( QueueType::CallstackSample ); + MemWrite( &item->callstackSampleFat.time, t0 ); + MemWrite( &item->callstackSampleFat.thread, tid ); + MemWrite( &item->callstackSampleFat.ptr, (uint64_t)trace ); + TracyLfqCommit; + } + } + pos += hdr.size; + } + } + else + { + while( pos < end ) + { + perf_event_header hdr; + ring.Read( &hdr, pos, sizeof( perf_event_header ) ); + if( hdr.type == PERF_RECORD_SAMPLE ) + { + auto offset = pos + sizeof( perf_event_header ); + + // Layout: + // u64 ip + // u64 time + + uint64_t ip, t0; + ring.Read( &ip, offset, sizeof( uint64_t ) ); + offset += sizeof( uint64_t ); + ring.Read( &t0, offset, sizeof( uint64_t ) ); + +#if defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) + t0 = ring.ConvertTimeToTsc( t0 ); +#endif + QueueType type; + switch( id ) + { + case EventCpuCycles: + type = QueueType::HwSampleCpuCycle; + break; + case EventInstructionsRetired: + type = QueueType::HwSampleInstructionRetired; + break; + case EventCacheReference: + type = QueueType::HwSampleCacheReference; + break; + case EventCacheMiss: + type = QueueType::HwSampleCacheMiss; + break; + case EventBranchRetired: + type = QueueType::HwSampleBranchRetired; + break; + case EventBranchMiss: + type = QueueType::HwSampleBranchMiss; + break; + default: + abort(); + } + + TracyLfqPrepare( type ); + MemWrite( &item->hwSample.ip, ip ); + MemWrite( &item->hwSample.time, t0 ); + TracyLfqCommit; + } + pos += hdr.size; + } + } + assert( pos == end ); + ring.Advance( end ); + } + if( !traceActive.load( std::memory_order_relaxed ) ) break; + + if( ctxBufferIdx != numBuffers ) + { + const auto ctxBufNum = numBuffers - ctxBufferIdx; + + int activeNum = 0; + uint16_t active[512]; + uint32_t end[512]; + uint32_t pos[512]; + for( int i=0; i 0 ) + { + hadData = true; + while( activeNum > 0 ) + { + int sel = -1; + int selPos; + int64_t t0 = std::numeric_limits::max(); + for( int i=0; i= 0 ) + { + auto& ring = ringArray[ctxBufferIdx + sel]; + auto rbPos = pos[sel]; + auto offset = rbPos; + perf_event_header hdr; + ring.Read( &hdr, offset, sizeof( perf_event_header ) ); + +#if defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) + t0 = ring.ConvertTimeToTsc( t0 ); +#endif + + const auto rid = ring.GetId(); + if( rid == EventContextSwitch ) + { + // Layout: + // u64 time + // u64 cnt + // u64 ip[cnt] + // u32 size + // u8 data[size] + // Data (not ABI stable, but has not changed since it was added, in 2009): + // u8 hdr[8] + // u8 prev_comm[16] + // u32 prev_pid + // u32 prev_prio + // lng prev_state + // u8 next_comm[16] + // u32 next_pid + // u32 next_prio + + offset += sizeof( perf_event_header ) + sizeof( uint64_t ); + + uint64_t cnt; + ring.Read( &cnt, offset, sizeof( uint64_t ) ); + offset += sizeof( uint64_t ); + const auto traceOffset = offset; + offset += sizeof( uint64_t ) * cnt + sizeof( uint32_t ) + 8 + 16; + + uint32_t prev_pid, next_pid; + long prev_state; + + ring.Read( &prev_pid, offset, sizeof( uint32_t ) ); + offset += sizeof( uint32_t ) + sizeof( uint32_t ); + ring.Read( &prev_state, offset, sizeof( long ) ); + offset += sizeof( long ) + 16; + ring.Read( &next_pid, offset, sizeof( uint32_t ) ); + + uint8_t reason = 100; + uint8_t state; + + if( prev_state & 0x0001 ) state = 104; + else if( prev_state & 0x0002 ) state = 101; + else if( prev_state & 0x0004 ) state = 105; + else if( prev_state & 0x0008 ) state = 106; + else if( prev_state & 0x0010 ) state = 108; + else if( prev_state & 0x0020 ) state = 109; + else if( prev_state & 0x0040 ) state = 110; + else if( prev_state & 0x0080 ) state = 102; + else state = 103; + + TracyLfqPrepare( QueueType::ContextSwitch ); + MemWrite( &item->contextSwitch.time, t0 ); + MemWrite( &item->contextSwitch.oldThread, prev_pid ); + MemWrite( &item->contextSwitch.newThread, next_pid ); + MemWrite( &item->contextSwitch.cpu, uint8_t( ring.GetCpu() ) ); + MemWrite( &item->contextSwitch.reason, reason ); + MemWrite( &item->contextSwitch.state, state ); + TracyLfqCommit; + + if( cnt > 0 && prev_pid != 0 && CurrentProcOwnsThread( prev_pid ) ) + { + auto trace = GetCallstackBlock( cnt, ring, traceOffset ); + + TracyLfqPrepare( QueueType::CallstackSampleContextSwitch ); + MemWrite( &item->callstackSampleFat.time, t0 ); + MemWrite( &item->callstackSampleFat.thread, prev_pid ); + MemWrite( &item->callstackSampleFat.ptr, (uint64_t)trace ); + TracyLfqCommit; + } + } + else if( rid == EventWakeup ) + { + // Layout: + // u64 time + // u32 size + // u8 data[size] + // Data: + // u8 hdr[8] + // u8 comm[16] + // u32 pid + // u32 prio + // u64 target_cpu + + offset += sizeof( perf_event_header ) + sizeof( uint64_t ) + sizeof( uint32_t ) + 8 + 16; + + uint32_t pid; + ring.Read( &pid, offset, sizeof( uint32_t ) ); + + TracyLfqPrepare( QueueType::ThreadWakeup ); + MemWrite( &item->threadWakeup.time, t0 ); + MemWrite( &item->threadWakeup.thread, pid ); + TracyLfqCommit; + } + else + { + assert( rid == EventVsync ); + // Layout: + // u64 time + // u32 size + // u8 data[size] + // Data (not ABI stable): + // u8 hdr[8] + // i32 crtc + // u32 seq + // i64 ktime + // u8 high precision + + offset += sizeof( perf_event_header ) + sizeof( uint64_t ) + sizeof( uint32_t ) + 8; + + int32_t crtc; + ring.Read( &crtc, offset, sizeof( int32_t ) ); + + // Note: The timestamp value t0 might be off by a number of microseconds from the + // true hardware vblank event. The ktime value should be used instead, but it is + // measured in CLOCK_MONOTONIC time. Tracy only supports the timestamp counter + // register (TSC) or CLOCK_MONOTONIC_RAW clock. +#if 0 + offset += sizeof( uint32_t ) * 2; + int64_t ktime; + ring.Read( &ktime, offset, sizeof( int64_t ) ); +#endif + + TracyLfqPrepare( QueueType::FrameVsync ); + MemWrite( &item->frameVsync.id, crtc ); + MemWrite( &item->frameVsync.time, t0 ); + TracyLfqCommit; + } + + rbPos += hdr.size; + if( rbPos == end[sel] ) + { + memmove( active+selPos, active+selPos+1, sizeof(*active) * ( activeNum - selPos - 1 ) ); + activeNum--; + } + else + { + pos[sel] = rbPos; + } + } + } + for( int i=0; i 0 && buf[sz-1] == '\n' ) buf[sz-1] = '\0'; + threadName = CopyString( buf ); + fclose( f ); + } + else + { + threadName = CopyString( "???", 3 ); + } + + sprintf( fn, "/proc/%" PRIu64 "/status", thread ); + f = fopen( fn, "rb" ); + if( f ) + { + char* tmp = (char*)tracy_malloc_fast( 8*1024 ); + const auto fsz = (ptrdiff_t)fread( tmp, 1, 8*1024, f ); + fclose( f ); + + int pid = -1; + auto line = tmp; + for(;;) + { + if( memcmp( "Tgid:\t", line, 6 ) == 0 ) + { + pid = atoi( line + 6 ); + break; + } + while( line - tmp < fsz && *line != '\n' ) line++; + if( *line != '\n' ) break; + line++; + } + tracy_free_fast( tmp ); + + if( pid >= 0 ) + { + { + uint64_t _pid = pid; + TracyLfqPrepare( QueueType::TidToPid ); + MemWrite( &item->tidToPid.tid, thread ); + MemWrite( &item->tidToPid.pid, _pid ); + TracyLfqCommit; + } + sprintf( fn, "/proc/%i/comm", pid ); + f = fopen( fn, "rb" ); + if( f ) + { + char buf[256]; + const auto sz = fread( buf, 1, 256, f ); + if( sz > 0 && buf[sz-1] == '\n' ) buf[sz-1] = '\0'; + name = CopyStringFast( buf ); + fclose( f ); + return; + } + } + } + name = CopyStringFast( "???", 3 ); +} + +} + +# endif + +#endif diff --git a/Externals/tracy/public/client/TracySysTrace.hpp b/Externals/tracy/public/client/TracySysTrace.hpp new file mode 100644 index 00000000000..8c663cd7a11 --- /dev/null +++ b/Externals/tracy/public/client/TracySysTrace.hpp @@ -0,0 +1,28 @@ +#ifndef __TRACYSYSTRACE_HPP__ +#define __TRACYSYSTRACE_HPP__ + +#if !defined TRACY_NO_SYSTEM_TRACING && ( defined _WIN32 || defined __linux__ ) +# include "../common/TracyUwp.hpp" +# ifndef TRACY_UWP +# define TRACY_HAS_SYSTEM_TRACING +# endif +#endif + +#ifdef TRACY_HAS_SYSTEM_TRACING + +#include + +namespace tracy +{ + +bool SysTraceStart( int64_t& samplingPeriod ); +void SysTraceStop(); +void SysTraceWorker( void* ptr ); + +void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name ); + +} + +#endif + +#endif diff --git a/Externals/tracy/public/client/TracyThread.hpp b/Externals/tracy/public/client/TracyThread.hpp new file mode 100644 index 00000000000..5638756acab --- /dev/null +++ b/Externals/tracy/public/client/TracyThread.hpp @@ -0,0 +1,90 @@ +#ifndef __TRACYTHREAD_HPP__ +#define __TRACYTHREAD_HPP__ + +#if defined _WIN32 +# include +#else +# include +#endif + +#ifdef TRACY_MANUAL_LIFETIME +# include "tracy_rpmalloc.hpp" +#endif + +namespace tracy +{ + +#ifdef TRACY_MANUAL_LIFETIME +extern thread_local bool RpThreadInitDone; +#endif + +class ThreadExitHandler +{ +public: + ~ThreadExitHandler() + { +#ifdef TRACY_MANUAL_LIFETIME + rpmalloc_thread_finalize( 1 ); + RpThreadInitDone = false; +#endif + } +}; + +#if defined _WIN32 + +class Thread +{ +public: + Thread( void(*func)( void* ptr ), void* ptr ) + : m_func( func ) + , m_ptr( ptr ) + , m_hnd( CreateThread( nullptr, 0, Launch, this, 0, nullptr ) ) + {} + + ~Thread() + { + WaitForSingleObject( m_hnd, INFINITE ); + CloseHandle( m_hnd ); + } + + HANDLE Handle() const { return m_hnd; } + +private: + static DWORD WINAPI Launch( void* ptr ) { ((Thread*)ptr)->m_func( ((Thread*)ptr)->m_ptr ); return 0; } + + void(*m_func)( void* ptr ); + void* m_ptr; + HANDLE m_hnd; +}; + +#else + +class Thread +{ +public: + Thread( void(*func)( void* ptr ), void* ptr ) + : m_func( func ) + , m_ptr( ptr ) + { + pthread_create( &m_thread, nullptr, Launch, this ); + } + + ~Thread() + { + pthread_join( m_thread, nullptr ); + } + + pthread_t Handle() const { return m_thread; } + +private: + static void* Launch( void* ptr ) { ((Thread*)ptr)->m_func( ((Thread*)ptr)->m_ptr ); return nullptr; } + void(*m_func)( void* ptr ); + void* m_ptr; + pthread_t m_thread; +}; + +#endif + +} + +#endif diff --git a/Externals/tracy/public/client/tracy_SPSCQueue.h b/Externals/tracy/public/client/tracy_SPSCQueue.h new file mode 100644 index 00000000000..7f1752b5686 --- /dev/null +++ b/Externals/tracy/public/client/tracy_SPSCQueue.h @@ -0,0 +1,148 @@ +/* +Copyright (c) 2020 Erik Rigtorp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include // std::enable_if, std::is_*_constructible + +#include "../common/TracyAlloc.hpp" + +#if defined (_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4324) +#endif + +namespace tracy { + +template class SPSCQueue { +public: + explicit SPSCQueue(const size_t capacity) + : capacity_(capacity) { + capacity_++; // Needs one slack element + slots_ = (T*)tracy_malloc(sizeof(T) * (capacity_ + 2 * kPadding)); + + static_assert(alignof(SPSCQueue) == kCacheLineSize, ""); + static_assert(sizeof(SPSCQueue) >= 3 * kCacheLineSize, ""); + assert(reinterpret_cast(&readIdx_) - + reinterpret_cast(&writeIdx_) >= + static_cast(kCacheLineSize)); + } + + ~SPSCQueue() { + while (front()) { + pop(); + } + tracy_free(slots_); + } + + // non-copyable and non-movable + SPSCQueue(const SPSCQueue &) = delete; + SPSCQueue &operator=(const SPSCQueue &) = delete; + + template + void emplace(Args &&...args) noexcept( + std::is_nothrow_constructible::value) { + static_assert(std::is_constructible::value, + "T must be constructible with Args&&..."); + auto const writeIdx = writeIdx_.load(std::memory_order_relaxed); + auto nextWriteIdx = writeIdx + 1; + if (nextWriteIdx == capacity_) { + nextWriteIdx = 0; + } + while (nextWriteIdx == readIdxCache_) { + readIdxCache_ = readIdx_.load(std::memory_order_acquire); + } + new (&slots_[writeIdx + kPadding]) T(std::forward(args)...); + writeIdx_.store(nextWriteIdx, std::memory_order_release); + } + + T *front() noexcept { + auto const readIdx = readIdx_.load(std::memory_order_relaxed); + if (readIdx == writeIdxCache_) { + writeIdxCache_ = writeIdx_.load(std::memory_order_acquire); + if (writeIdxCache_ == readIdx) { + return nullptr; + } + } + return &slots_[readIdx + kPadding]; + } + + void pop() noexcept { + static_assert(std::is_nothrow_destructible::value, + "T must be nothrow destructible"); + auto const readIdx = readIdx_.load(std::memory_order_relaxed); + assert(writeIdx_.load(std::memory_order_acquire) != readIdx); + slots_[readIdx + kPadding].~T(); + auto nextReadIdx = readIdx + 1; + if (nextReadIdx == capacity_) { + nextReadIdx = 0; + } + readIdx_.store(nextReadIdx, std::memory_order_release); + } + + size_t size() const noexcept { + std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) - + readIdx_.load(std::memory_order_acquire); + if (diff < 0) { + diff += capacity_; + } + return static_cast(diff); + } + + bool empty() const noexcept { + return writeIdx_.load(std::memory_order_acquire) == + readIdx_.load(std::memory_order_acquire); + } + + size_t capacity() const noexcept { return capacity_ - 1; } + +private: + static constexpr size_t kCacheLineSize = 64; + + // Padding to avoid false sharing between slots_ and adjacent allocations + static constexpr size_t kPadding = (kCacheLineSize - 1) / sizeof(T) + 1; + +private: + size_t capacity_; + T *slots_; + + // Align to cache line size in order to avoid false sharing + // readIdxCache_ and writeIdxCache_ is used to reduce the amount of cache + // coherency traffic + alignas(kCacheLineSize) std::atomic writeIdx_ = {0}; + alignas(kCacheLineSize) size_t readIdxCache_ = 0; + alignas(kCacheLineSize) std::atomic readIdx_ = {0}; + alignas(kCacheLineSize) size_t writeIdxCache_ = 0; + + // Padding to avoid adjacent allocations to share cache line with + // writeIdxCache_ + char padding_[kCacheLineSize - sizeof(SPSCQueue::writeIdxCache_)]; +}; +} // namespace rigtorp + +#if defined (_MSC_VER) +#pragma warning(pop) +#endif diff --git a/Externals/tracy/public/client/tracy_concurrentqueue.h b/Externals/tracy/public/client/tracy_concurrentqueue.h new file mode 100644 index 00000000000..4178d39eadf --- /dev/null +++ b/Externals/tracy/public/client/tracy_concurrentqueue.h @@ -0,0 +1,1441 @@ +// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue. +// An overview, including benchmark results, is provided here: +// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ +// The full design is also described in excruciating detail at: +// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue + +// Simplified BSD license: +// Copyright (c) 2013-2016, Cameron Desrochers. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#pragma once + +#include "../common/TracyAlloc.hpp" +#include "../common/TracyForceInline.hpp" +#include "../common/TracySystem.hpp" + +#if defined(__GNUC__) +// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and +// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings +// upon assigning any computed values) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +#if defined(__APPLE__) +#include "TargetConditionals.h" +#endif + +#include // Requires C++11. Sorry VS2010. +#include +#include // for max_align_t +#include +#include +#include +#include +#include +#include +#include // for CHAR_BIT +#include +#include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading + +namespace tracy +{ + +// Compiler-specific likely/unlikely hints +namespace moodycamel { namespace details { +#if defined(__GNUC__) + inline bool cqLikely(bool x) { return __builtin_expect((x), true); } + inline bool cqUnlikely(bool x) { return __builtin_expect((x), false); } +#else + inline bool cqLikely(bool x) { return x; } + inline bool cqUnlikely(bool x) { return x; } +#endif +} } + +namespace +{ + // to avoid MSVC warning 4127: conditional expression is constant + template + struct compile_time_condition + { + static const bool value = false; + }; + template <> + struct compile_time_condition + { + static const bool value = true; + }; +} + +namespace moodycamel { +namespace details { + template + struct const_numeric_max { + static_assert(std::is_integral::value, "const_numeric_max can only be used with integers"); + static const T value = std::numeric_limits::is_signed + ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1) + : static_cast(-1); + }; + +#if defined(__GLIBCXX__) + typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while +#else + typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std:: +#endif + + // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting + // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64. + typedef union { + std_max_align_t x; + long long y; + void* z; + } max_align_t; +} + +// Default traits for the ConcurrentQueue. To change some of the +// traits without re-implementing all of them, inherit from this +// struct and shadow the declarations you wish to be different; +// since the traits are used as a template type parameter, the +// shadowed declarations will be used where defined, and the defaults +// otherwise. +struct ConcurrentQueueDefaultTraits +{ + // General-purpose size type. std::size_t is strongly recommended. + typedef std::size_t size_t; + + // The type used for the enqueue and dequeue indices. Must be at least as + // large as size_t. Should be significantly larger than the number of elements + // you expect to hold at once, especially if you have a high turnover rate; + // for example, on 32-bit x86, if you expect to have over a hundred million + // elements or pump several million elements through your queue in a very + // short space of time, using a 32-bit type *may* trigger a race condition. + // A 64-bit int type is recommended in that case, and in practice will + // prevent a race condition no matter the usage of the queue. Note that + // whether the queue is lock-free with a 64-int type depends on the whether + // std::atomic is lock-free, which is platform-specific. + typedef std::size_t index_t; + + // Internally, all elements are enqueued and dequeued from multi-element + // blocks; this is the smallest controllable unit. If you expect few elements + // but many producers, a smaller block size should be favoured. For few producers + // and/or many elements, a larger block size is preferred. A sane default + // is provided. Must be a power of 2. + static const size_t BLOCK_SIZE = 64*1024; + + // For explicit producers (i.e. when using a producer token), the block is + // checked for being empty by iterating through a list of flags, one per element. + // For large block sizes, this is too inefficient, and switching to an atomic + // counter-based approach is faster. The switch is made for block sizes strictly + // larger than this threshold. + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32; + + // How many full blocks can be expected for a single explicit producer? This should + // reflect that number's maximum for optimal performance. Must be a power of 2. + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32; + + // Controls the number of items that an explicit consumer (i.e. one with a token) + // must consume before it causes all consumers to rotate and move on to the next + // internal queue. + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256; + + // The maximum number of elements (inclusive) that can be enqueued to a sub-queue. + // Enqueue operations that would cause this limit to be surpassed will fail. Note + // that this limit is enforced at the block level (for performance reasons), i.e. + // it's rounded up to the nearest block size. + static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value; + + + // Memory allocation can be customized if needed. + // malloc should return nullptr on failure, and handle alignment like std::malloc. +#if defined(malloc) || defined(free) + // Gah, this is 2015, stop defining macros that break standard code already! + // Work around malloc/free being special macros: + static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); } + static inline void WORKAROUND_free(void* ptr) { return free(ptr); } + static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); } + static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); } +#else + static inline void* malloc(size_t size) { return tracy::tracy_malloc(size); } + static inline void free(void* ptr) { return tracy::tracy_free(ptr); } +#endif +}; + + +// When producing or consuming many elements, the most efficient way is to: +// 1) Use one of the bulk-operation methods of the queue with a token +// 2) Failing that, use the bulk-operation methods without a token +// 3) Failing that, create a token and use that with the single-item methods +// 4) Failing that, use the single-parameter methods of the queue +// Having said that, don't create tokens willy-nilly -- ideally there should be +// a maximum of one token per thread (of each kind). +struct ProducerToken; +struct ConsumerToken; + +template class ConcurrentQueue; + + +namespace details +{ + struct ConcurrentQueueProducerTypelessBase + { + ConcurrentQueueProducerTypelessBase* next; + std::atomic inactive; + ProducerToken* token; + uint32_t threadId; + + ConcurrentQueueProducerTypelessBase() + : next(nullptr), inactive(false), token(nullptr), threadId(0) + { + } + }; + + template + static inline bool circular_less_than(T a, T b) + { + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types"); + return static_cast(a - b) > static_cast(static_cast(1) << (static_cast(sizeof(T) * CHAR_BIT - 1))); + // Note: extra parens around rhs of operator<< is MSVC bug: https://developercommunity2.visualstudio.com/t/C4554-triggers-when-both-lhs-and-rhs-is/10034931 + // silencing the bug requires #pragma warning(disable: 4554) around the calling code and has no effect when done here. + } + + template + static inline char* align_for(char* ptr) + { + const std::size_t alignment = std::alignment_of::value; + return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; + } + + template + static inline T ceil_to_pow_2(T x) + { + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types"); + + // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + for (std::size_t i = 1; i < sizeof(T); i <<= 1) { + x |= x >> (i << 3); + } + ++x; + return x; + } + + template + static inline void swap_relaxed(std::atomic& left, std::atomic& right) + { + T temp = std::move(left.load(std::memory_order_relaxed)); + left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed); + right.store(std::move(temp), std::memory_order_relaxed); + } + + template + static inline T const& nomove(T const& x) + { + return x; + } + + template + struct nomove_if + { + template + static inline T const& eval(T const& x) + { + return x; + } + }; + + template<> + struct nomove_if + { + template + static inline auto eval(U&& x) + -> decltype(std::forward(x)) + { + return std::forward(x); + } + }; + + template + static inline auto deref_noexcept(It& it) noexcept -> decltype(*it) + { + return *it; + } + +#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + template struct is_trivially_destructible : std::is_trivially_destructible { }; +#else + template struct is_trivially_destructible : std::has_trivial_destructor { }; +#endif + + template struct static_is_lock_free_num { enum { value = 0 }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; }; + template struct static_is_lock_free : static_is_lock_free_num::type> { }; + template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; }; + template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; }; +} + + +struct ProducerToken +{ + template + explicit ProducerToken(ConcurrentQueue& queue); + + ProducerToken(ProducerToken&& other) noexcept + : producer(other.producer) + { + other.producer = nullptr; + if (producer != nullptr) { + producer->token = this; + } + } + + inline ProducerToken& operator=(ProducerToken&& other) noexcept + { + swap(other); + return *this; + } + + void swap(ProducerToken& other) noexcept + { + std::swap(producer, other.producer); + if (producer != nullptr) { + producer->token = this; + } + if (other.producer != nullptr) { + other.producer->token = &other; + } + } + + // A token is always valid unless: + // 1) Memory allocation failed during construction + // 2) It was moved via the move constructor + // (Note: assignment does a swap, leaving both potentially valid) + // 3) The associated queue was destroyed + // Note that if valid() returns true, that only indicates + // that the token is valid for use with a specific queue, + // but not which one; that's up to the user to track. + inline bool valid() const { return producer != nullptr; } + + ~ProducerToken() + { + if (producer != nullptr) { + producer->token = nullptr; + producer->inactive.store(true, std::memory_order_release); + } + } + + // Disable copying and assignment + ProducerToken(ProducerToken const&) = delete; + ProducerToken& operator=(ProducerToken const&) = delete; + +private: + template friend class ConcurrentQueue; + +protected: + details::ConcurrentQueueProducerTypelessBase* producer; +}; + + +struct ConsumerToken +{ + template + explicit ConsumerToken(ConcurrentQueue& q); + + ConsumerToken(ConsumerToken&& other) noexcept + : initialOffset(other.initialOffset), lastKnownGlobalOffset(other.lastKnownGlobalOffset), itemsConsumedFromCurrent(other.itemsConsumedFromCurrent), currentProducer(other.currentProducer), desiredProducer(other.desiredProducer) + { + } + + inline ConsumerToken& operator=(ConsumerToken&& other) noexcept + { + swap(other); + return *this; + } + + void swap(ConsumerToken& other) noexcept + { + std::swap(initialOffset, other.initialOffset); + std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset); + std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent); + std::swap(currentProducer, other.currentProducer); + std::swap(desiredProducer, other.desiredProducer); + } + + // Disable copying and assignment + ConsumerToken(ConsumerToken const&) = delete; + ConsumerToken& operator=(ConsumerToken const&) = delete; + +private: + template friend class ConcurrentQueue; + +private: // but shared with ConcurrentQueue + std::uint32_t initialOffset; + std::uint32_t lastKnownGlobalOffset; + std::uint32_t itemsConsumedFromCurrent; + details::ConcurrentQueueProducerTypelessBase* currentProducer; + details::ConcurrentQueueProducerTypelessBase* desiredProducer; +}; + + +template +class ConcurrentQueue +{ +public: + struct ExplicitProducer; + + typedef moodycamel::ProducerToken producer_token_t; + typedef moodycamel::ConsumerToken consumer_token_t; + + typedef typename Traits::index_t index_t; + typedef typename Traits::size_t size_t; + + static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE); + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD); + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE); + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = static_cast(Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!) +#pragma warning(disable: 4309) // static_cast: Truncation of constant value +#endif + static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type"); + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type"); + static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t"); + static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)"); + static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)"); + static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); + +public: + // Creates a queue with at least `capacity` element slots; note that the + // actual number of elements that can be inserted without additional memory + // allocation depends on the number of producers and the block size (e.g. if + // the block size is equal to `capacity`, only a single block will be allocated + // up-front, which means only a single producer will be able to enqueue elements + // without an extra allocation -- blocks aren't shared between producers). + // This method is not thread safe -- it is up to the user to ensure that the + // queue is fully constructed before it starts being used by other threads (this + // includes making the memory effects of construction visible, possibly with a + // memory barrier). + explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1)); + } + + // Computes the correct amount of pre-allocated blocks for you based + // on the minimum number of elements you want available at any given + // time, and the maximum concurrent number of each type of producer. + ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers); + populate_initial_block_list(blocks); + } + + // Note: The queue should not be accessed concurrently while it's + // being deleted. It's up to the user to synchronize this. + // This method is not thread safe. + ~ConcurrentQueue() + { + // Destroy producers + auto ptr = producerListTail.load(std::memory_order_relaxed); + while (ptr != nullptr) { + auto next = ptr->next_prod(); + if (ptr->token != nullptr) { + ptr->token->producer = nullptr; + } + destroy(ptr); + ptr = next; + } + + // Destroy global free list + auto block = freeList.head_unsafe(); + while (block != nullptr) { + auto next = block->freeListNext.load(std::memory_order_relaxed); + if (block->dynamicallyAllocated) { + destroy(block); + } + block = next; + } + + // Destroy initial free list + destroy_array(initialBlockPool, initialBlockPoolSize); + } + + // Disable copying and copy assignment + ConcurrentQueue(ConcurrentQueue const&) = delete; + ConcurrentQueue(ConcurrentQueue&& other) = delete; + ConcurrentQueue& operator=(ConcurrentQueue const&) = delete; + ConcurrentQueue& operator=(ConcurrentQueue&& other) = delete; + +public: + tracy_force_inline T* enqueue_begin(producer_token_t const& token, index_t& currentTailIndex) + { + return static_cast(token.producer)->ConcurrentQueue::ExplicitProducer::enqueue_begin(currentTailIndex); + } + + template + size_t try_dequeue_bulk_single(consumer_token_t& token, NotifyThread notifyThread, ProcessData processData ) + { + if (token.desiredProducer == nullptr || token.lastKnownGlobalOffset != globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { + if (!update_current_producer_after_rotation(token)) { + return 0; + } + } + + size_t count = static_cast(token.currentProducer)->dequeue_bulk(notifyThread, processData); + token.itemsConsumedFromCurrent += static_cast(count); + + auto tail = producerListTail.load(std::memory_order_acquire); + auto ptr = static_cast(token.currentProducer)->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + if( count == 0 ) + { + while (ptr != static_cast(token.currentProducer)) { + auto dequeued = ptr->dequeue_bulk(notifyThread, processData); + if (dequeued != 0) { + token.currentProducer = ptr; + token.itemsConsumedFromCurrent = static_cast(dequeued); + return dequeued; + } + ptr = ptr->next_prod(); + if (ptr == nullptr) { + ptr = tail; + } + } + return 0; + } + else + { + token.currentProducer = ptr; + token.itemsConsumedFromCurrent = 0; + return count; + } + } + + + // Returns an estimate of the total number of elements currently in the queue. This + // estimate is only accurate if the queue has completely stabilized before it is called + // (i.e. all enqueue and dequeue operations have completed and their memory effects are + // visible on the calling thread, and no further operations start while this method is + // being called). + // Thread-safe. + size_t size_approx() const + { + size_t size = 0; + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + size += ptr->size_approx(); + } + return size; + } + + + // Returns true if the underlying atomic variables used by + // the queue are lock-free (they should be on most platforms). + // Thread-safe. + static bool is_lock_free() + { + return + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2 && + details::static_is_lock_free::value == 2; + } + + +private: + friend struct ProducerToken; + friend struct ConsumerToken; + friend struct ExplicitProducer; + + + /////////////////////////////// + // Queue methods + /////////////////////////////// + + inline bool update_current_producer_after_rotation(consumer_token_t& token) + { + // Ah, there's been a rotation, figure out where we should be! + auto tail = producerListTail.load(std::memory_order_acquire); + if (token.desiredProducer == nullptr && tail == nullptr) { + return false; + } + auto prodCount = producerCount.load(std::memory_order_relaxed); + auto globalOffset = globalExplicitConsumerOffset.load(std::memory_order_relaxed); + if (details::cqUnlikely(token.desiredProducer == nullptr)) { + // Aha, first time we're dequeueing anything. + // Figure out our local position + // Note: offset is from start, not end, but we're traversing from end -- subtract from count first + std::uint32_t offset = prodCount - 1 - (token.initialOffset % prodCount); + token.desiredProducer = tail; + for (std::uint32_t i = 0; i != offset; ++i) { + token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); + if (token.desiredProducer == nullptr) { + token.desiredProducer = tail; + } + } + } + + std::uint32_t delta = globalOffset - token.lastKnownGlobalOffset; + if (delta >= prodCount) { + delta = delta % prodCount; + } + for (std::uint32_t i = 0; i != delta; ++i) { + token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); + if (token.desiredProducer == nullptr) { + token.desiredProducer = tail; + } + } + + token.lastKnownGlobalOffset = globalOffset; + token.currentProducer = token.desiredProducer; + token.itemsConsumedFromCurrent = 0; + return true; + } + + + /////////////////////////// + // Free list + /////////////////////////// + + template + struct FreeListNode + { + FreeListNode() : freeListRefs(0), freeListNext(nullptr) { } + + std::atomic freeListRefs; + std::atomic freeListNext; + }; + + // A simple CAS-based lock-free free list. Not the fastest thing in the world under heavy contention, but + // simple and correct (assuming nodes are never freed until after the free list is destroyed), and fairly + // speedy under low contention. + template // N must inherit FreeListNode or have the same fields (and initialization of them) + struct FreeList + { + FreeList() : freeListHead(nullptr) { } + FreeList(FreeList&& other) : freeListHead(other.freeListHead.load(std::memory_order_relaxed)) { other.freeListHead.store(nullptr, std::memory_order_relaxed); } + void swap(FreeList& other) { details::swap_relaxed(freeListHead, other.freeListHead); } + + FreeList(FreeList const&) = delete; + FreeList& operator=(FreeList const&) = delete; + + inline void add(N* node) + { + // We know that the should-be-on-freelist bit is 0 at this point, so it's safe to + // set it using a fetch_add + if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST, std::memory_order_acq_rel) == 0) { + // Oh look! We were the last ones referencing this node, and we know + // we want to add it to the free list, so let's do it! + add_knowing_refcount_is_zero(node); + } + } + + inline N* try_get() + { + auto head = freeListHead.load(std::memory_order_acquire); + while (head != nullptr) { + auto prevHead = head; + auto refs = head->freeListRefs.load(std::memory_order_relaxed); + if ((refs & REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) { + head = freeListHead.load(std::memory_order_acquire); + continue; + } + + // Good, reference count has been incremented (it wasn't at zero), which means we can read the + // next and not worry about it changing between now and the time we do the CAS + auto next = head->freeListNext.load(std::memory_order_relaxed); + if (freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) { + // Yay, got the node. This means it was on the list, which means shouldBeOnFreeList must be false no + // matter the refcount (because nobody else knows it's been taken off yet, it can't have been put back on). + assert((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0); + + // Decrease refcount twice, once for our ref, and once for the list's ref + head->freeListRefs.fetch_sub(2, std::memory_order_release); + return head; + } + + // OK, the head must have changed on us, but we still need to decrease the refcount we increased. + // Note that we don't need to release any memory effects, but we do need to ensure that the reference + // count decrement happens-after the CAS on the head. + refs = prevHead->freeListRefs.fetch_sub(1, std::memory_order_acq_rel); + if (refs == SHOULD_BE_ON_FREELIST + 1) { + add_knowing_refcount_is_zero(prevHead); + } + } + + return nullptr; + } + + // Useful for traversing the list when there's no contention (e.g. to destroy remaining nodes) + N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); } + + private: + inline void add_knowing_refcount_is_zero(N* node) + { + // Since the refcount is zero, and nobody can increase it once it's zero (except us, and we run + // only one copy of this method per node at a time, i.e. the single thread case), then we know + // we can safely change the next pointer of the node; however, once the refcount is back above + // zero, then other threads could increase it (happens under heavy contention, when the refcount + // goes to zero in between a load and a refcount increment of a node in try_get, then back up to + // something non-zero, then the refcount increment is done by the other thread) -- so, if the CAS + // to add the node to the actual list fails, decrease the refcount and leave the add operation to + // the next thread who puts the refcount back at zero (which could be us, hence the loop). + auto head = freeListHead.load(std::memory_order_relaxed); + while (true) { + node->freeListNext.store(head, std::memory_order_relaxed); + node->freeListRefs.store(1, std::memory_order_release); + if (!freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) { + // Hmm, the add failed, but we can only try again when the refcount goes back to zero + if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1, std::memory_order_release) == 1) { + continue; + } + } + return; + } + } + + private: + // Implemented like a stack, but where node order doesn't matter (nodes are inserted out of order under contention) + std::atomic freeListHead; + + static const std::uint32_t REFS_MASK = 0x7FFFFFFF; + static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000; + }; + + + /////////////////////////// + // Block + /////////////////////////// + + struct Block + { + Block() + : next(nullptr), elementsCompletelyDequeued(0), freeListRefs(0), freeListNext(nullptr), shouldBeOnFreeList(false), dynamicallyAllocated(true) + { + } + + inline bool is_empty() const + { + if (compile_time_condition::value) { + // Check flags + for (size_t i = 0; i < BLOCK_SIZE; ++i) { + if (!emptyFlags[i].load(std::memory_order_relaxed)) { + return false; + } + } + + // Aha, empty; make sure we have all other memory effects that happened before the empty flags were set + std::atomic_thread_fence(std::memory_order_acquire); + return true; + } + else { + // Check counter + if (elementsCompletelyDequeued.load(std::memory_order_relaxed) == BLOCK_SIZE) { + std::atomic_thread_fence(std::memory_order_acquire); + return true; + } + assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <= BLOCK_SIZE); + return false; + } + } + + // Returns true if the block is now empty (does not apply in explicit context) + inline bool set_empty(index_t i) + { + if (BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Set flag + assert(!emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].load(std::memory_order_relaxed)); + emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].store(true, std::memory_order_release); + return false; + } + else { + // Increment counter + auto prevVal = elementsCompletelyDequeued.fetch_add(1, std::memory_order_release); + assert(prevVal < BLOCK_SIZE); + return prevVal == BLOCK_SIZE - 1; + } + } + + // Sets multiple contiguous item statuses to 'empty' (assumes no wrapping and count > 0). + // Returns true if the block is now empty (does not apply in explicit context). + inline bool set_many_empty(index_t i, size_t count) + { + if (compile_time_condition::value) { + // Set flags + std::atomic_thread_fence(std::memory_order_release); + i = BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1)) - count + 1; + for (size_t j = 0; j != count; ++j) { + assert(!emptyFlags[i + j].load(std::memory_order_relaxed)); + emptyFlags[i + j].store(true, std::memory_order_relaxed); + } + return false; + } + else { + // Increment counter + auto prevVal = elementsCompletelyDequeued.fetch_add(count, std::memory_order_release); + assert(prevVal + count <= BLOCK_SIZE); + return prevVal + count == BLOCK_SIZE; + } + } + + inline void set_all_empty() + { + if (BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { + // Set all flags + for (size_t i = 0; i != BLOCK_SIZE; ++i) { + emptyFlags[i].store(true, std::memory_order_relaxed); + } + } + else { + // Reset counter + elementsCompletelyDequeued.store(BLOCK_SIZE, std::memory_order_relaxed); + } + } + + inline void reset_empty() + { + if (compile_time_condition::value) { + // Reset flags + for (size_t i = 0; i != BLOCK_SIZE; ++i) { + emptyFlags[i].store(false, std::memory_order_relaxed); + } + } + else { + // Reset counter + elementsCompletelyDequeued.store(0, std::memory_order_relaxed); + } + } + + inline T* operator[](index_t idx) noexcept { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } + inline T const* operator[](index_t idx) const noexcept { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } + + private: + // IMPORTANT: This must be the first member in Block, so that if T depends on the alignment of + // addresses returned by malloc, that alignment will be preserved. Apparently clang actually + // generates code that uses this assumption for AVX instructions in some cases. Ideally, we + // should also align Block to the alignment of T in case it's higher than malloc's 16-byte + // alignment, but this is hard to do in a cross-platform way. Assert for this case: + static_assert(std::alignment_of::value <= std::alignment_of::value, "The queue does not support super-aligned types at this time"); + // Additionally, we need the alignment of Block itself to be a multiple of max_align_t since + // otherwise the appropriate padding will not be added at the end of Block in order to make + // arrays of Blocks all be properly aligned (not just the first one). We use a union to force + // this. + union { + char elements[sizeof(T) * BLOCK_SIZE]; + details::max_align_t dummy; + }; + public: + Block* next; + std::atomic elementsCompletelyDequeued; + std::atomic emptyFlags[BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE : 1]; + public: + std::atomic freeListRefs; + std::atomic freeListNext; + std::atomic shouldBeOnFreeList; + bool dynamicallyAllocated; // Perhaps a better name for this would be 'isNotPartOfInitialBlockPool' + }; + static_assert(std::alignment_of::value >= std::alignment_of::value, "Internal error: Blocks must be at least as aligned as the type they are wrapping"); + + + /////////////////////////// + // Producer base + /////////////////////////// + + struct ProducerBase : public details::ConcurrentQueueProducerTypelessBase + { + ProducerBase(ConcurrentQueue* parent_) : + tailIndex(0), + headIndex(0), + dequeueOptimisticCount(0), + dequeueOvercommit(0), + tailBlock(nullptr), + parent(parent_) + { + } + + virtual ~ProducerBase() { }; + + template + inline size_t dequeue_bulk(NotifyThread notifyThread, ProcessData processData) + { + return static_cast(this)->dequeue_bulk(notifyThread, processData); + } + + inline ProducerBase* next_prod() const { return static_cast(next); } + + inline size_t size_approx() const + { + auto tail = tailIndex.load(std::memory_order_relaxed); + auto head = headIndex.load(std::memory_order_relaxed); + return details::circular_less_than(head, tail) ? static_cast(tail - head) : 0; + } + + inline index_t getTail() const { return tailIndex.load(std::memory_order_relaxed); } + protected: + std::atomic tailIndex; // Where to enqueue to next + std::atomic headIndex; // Where to dequeue from next + + std::atomic dequeueOptimisticCount; + std::atomic dequeueOvercommit; + + Block* tailBlock; + + public: + ConcurrentQueue* parent; + }; + + + public: + /////////////////////////// + // Explicit queue + /////////////////////////// + struct ExplicitProducer : public ProducerBase + { + explicit ExplicitProducer(ConcurrentQueue* _parent) : + ProducerBase(_parent), + blockIndex(nullptr), + pr_blockIndexSlotsUsed(0), + pr_blockIndexSize(EXPLICIT_INITIAL_INDEX_SIZE >> 1), + pr_blockIndexFront(0), + pr_blockIndexEntries(nullptr), + pr_blockIndexRaw(nullptr) + { + size_t poolBasedIndexSize = details::ceil_to_pow_2(_parent->initialBlockPoolSize) >> 1; + if (poolBasedIndexSize > pr_blockIndexSize) { + pr_blockIndexSize = poolBasedIndexSize; + } + + new_block_index(0); // This creates an index with double the number of current entries, i.e. EXPLICIT_INITIAL_INDEX_SIZE + } + + ~ExplicitProducer() + { + // Destruct any elements not yet dequeued. + // Since we're in the destructor, we can assume all elements + // are either completely dequeued or completely not (no halfways). + if (this->tailBlock != nullptr) { // Note this means there must be a block index too + // First find the block that's partially dequeued, if any + Block* halfDequeuedBlock = nullptr; + if ((this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) != 0) { + // The head's not on a block boundary, meaning a block somewhere is partially dequeued + // (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary) + size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1); + while (details::circular_less_than(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) { + i = (i + 1) & (pr_blockIndexSize - 1); + } + assert(details::circular_less_than(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed))); + halfDequeuedBlock = pr_blockIndexEntries[i].block; + } + + // Start at the head block (note the first line in the loop gives us the head from the tail on the first iteration) + auto block = this->tailBlock; + do { + block = block->next; + if (block->ConcurrentQueue::Block::is_empty()) { + continue; + } + + size_t i = 0; // Offset into block + if (block == halfDequeuedBlock) { + i = static_cast(this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); + } + + // Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index + auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast(this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); + while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) { + (*block)[i++]->~T(); + } + } while (block != this->tailBlock); + } + + // Destroy all blocks that we own + if (this->tailBlock != nullptr) { + auto block = this->tailBlock; + do { + auto nextBlock = block->next; + if (block->dynamicallyAllocated) { + destroy(block); + } + else { + this->parent->add_block_to_free_list(block); + } + block = nextBlock; + } while (block != this->tailBlock); + } + + // Destroy the block indices + auto header = static_cast(pr_blockIndexRaw); + while (header != nullptr) { + auto prev = static_cast(header->prev); + header->~BlockIndexHeader(); + (Traits::free)(header); + header = prev; + } + } + + inline void enqueue_begin_alloc(index_t currentTailIndex) + { + // We reached the end of a block, start a new one + if (this->tailBlock != nullptr && this->tailBlock->next->ConcurrentQueue::Block::is_empty()) { + // We can re-use the block ahead of us, it's empty! + this->tailBlock = this->tailBlock->next; + this->tailBlock->ConcurrentQueue::Block::reset_empty(); + + // We'll put the block on the block index (guaranteed to be room since we're conceptually removing the + // last block from it first -- except instead of removing then adding, we can just overwrite). + // Note that there must be a valid block index here, since even if allocation failed in the ctor, + // it would have been re-attempted when adding the first block to the queue; since there is such + // a block, a block index must have been successfully allocated. + } + else { + // We're going to need a new block; check that the block index has room + if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize) { + // Hmm, the circular block index is already full -- we'll need + // to allocate a new index. Note pr_blockIndexRaw can only be nullptr if + // the initial allocation failed in the constructor. + new_block_index(pr_blockIndexSlotsUsed); + } + + // Insert a new block in the circular linked list + auto newBlock = this->parent->ConcurrentQueue::requisition_block(); + newBlock->ConcurrentQueue::Block::reset_empty(); + if (this->tailBlock == nullptr) { + newBlock->next = newBlock; + } + else { + newBlock->next = this->tailBlock->next; + this->tailBlock->next = newBlock; + } + this->tailBlock = newBlock; + ++pr_blockIndexSlotsUsed; + } + + // Add block to block index + auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; + entry.base = currentTailIndex; + entry.block = this->tailBlock; + blockIndex.load(std::memory_order_relaxed)->front.store(pr_blockIndexFront, std::memory_order_release); + pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); + } + + tracy_force_inline T* enqueue_begin(index_t& currentTailIndex) + { + currentTailIndex = this->tailIndex.load(std::memory_order_relaxed); + if (details::cqUnlikely((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0)) { + this->enqueue_begin_alloc(currentTailIndex); + } + return (*this->tailBlock)[currentTailIndex]; + } + + tracy_force_inline std::atomic& get_tail_index() + { + return this->tailIndex; + } + + template + size_t dequeue_bulk(NotifyThread notifyThread, ProcessData processData) + { + auto tail = this->tailIndex.load(std::memory_order_relaxed); + auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); + auto desiredCount = static_cast(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit)); + if (details::circular_less_than(0, desiredCount)) { + desiredCount = desiredCount < 8192 ? desiredCount : 8192; + std::atomic_thread_fence(std::memory_order_acquire); + + auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed); + assert(overcommit <= myDequeueCount); + + tail = this->tailIndex.load(std::memory_order_acquire); + auto actualCount = static_cast(tail - (myDequeueCount - overcommit)); + if (details::circular_less_than(0, actualCount)) { + actualCount = desiredCount < actualCount ? desiredCount : actualCount; + if (actualCount < desiredCount) { + this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release); + } + + // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this + // will never exceed tail. + auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel); + + // Determine which block the first element is in + auto localBlockIndex = blockIndex.load(std::memory_order_acquire); + auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire); + + auto headBase = localBlockIndex->entries[localBlockIndexHead].base; + auto firstBlockBaseIndex = firstIndex & ~static_cast(BLOCK_SIZE - 1); + auto offset = static_cast(static_cast::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE); + auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1); + + notifyThread( this->threadId ); + + // Iterate the blocks and dequeue + auto index = firstIndex; + do { + auto firstIndexInBlock = index; + auto endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); + endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; + auto block = localBlockIndex->entries[indexIndex].block; + + const auto sz = endIndex - index; + processData( (*block)[index], sz ); + index += sz; + + block->ConcurrentQueue::Block::set_many_empty(firstIndexInBlock, static_cast(endIndex - firstIndexInBlock)); + indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1); + } while (index != firstIndex + actualCount); + + return actualCount; + } + else { + // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent + this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release); + } + } + + return 0; + } + + private: + struct BlockIndexEntry + { + index_t base; + Block* block; + }; + + struct BlockIndexHeader + { + size_t size; + std::atomic front; // Current slot (not next, like pr_blockIndexFront) + BlockIndexEntry* entries; + void* prev; + }; + + + bool new_block_index(size_t numberOfFilledSlotsToExpose) + { + auto prevBlockSizeMask = pr_blockIndexSize - 1; + + // Create the new block + pr_blockIndexSize <<= 1; + auto newRawPtr = static_cast((Traits::malloc)(sizeof(BlockIndexHeader) + std::alignment_of::value - 1 + sizeof(BlockIndexEntry) * pr_blockIndexSize)); + if (newRawPtr == nullptr) { + pr_blockIndexSize >>= 1; // Reset to allow graceful retry + return false; + } + + auto newBlockIndexEntries = reinterpret_cast(details::align_for(newRawPtr + sizeof(BlockIndexHeader))); + + // Copy in all the old indices, if any + size_t j = 0; + if (pr_blockIndexSlotsUsed != 0) { + auto i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & prevBlockSizeMask; + do { + newBlockIndexEntries[j++] = pr_blockIndexEntries[i]; + i = (i + 1) & prevBlockSizeMask; + } while (i != pr_blockIndexFront); + } + + // Update everything + auto header = new (newRawPtr) BlockIndexHeader; + header->size = pr_blockIndexSize; + header->front.store(numberOfFilledSlotsToExpose - 1, std::memory_order_relaxed); + header->entries = newBlockIndexEntries; + header->prev = pr_blockIndexRaw; // we link the new block to the old one so we can free it later + + pr_blockIndexFront = j; + pr_blockIndexEntries = newBlockIndexEntries; + pr_blockIndexRaw = newRawPtr; + blockIndex.store(header, std::memory_order_release); + + return true; + } + + private: + std::atomic blockIndex; + + // To be used by producer only -- consumer must use the ones in referenced by blockIndex + size_t pr_blockIndexSlotsUsed; + size_t pr_blockIndexSize; + size_t pr_blockIndexFront; // Next slot (not current) + BlockIndexEntry* pr_blockIndexEntries; + void* pr_blockIndexRaw; + }; + + ExplicitProducer* get_explicit_producer(producer_token_t const& token) + { + return static_cast(token.producer); + } + + private: + + ////////////////////////////////// + // Block pool manipulation + ////////////////////////////////// + + void populate_initial_block_list(size_t blockCount) + { + initialBlockPoolSize = blockCount; + if (initialBlockPoolSize == 0) { + initialBlockPool = nullptr; + return; + } + + initialBlockPool = create_array(blockCount); + if (initialBlockPool == nullptr) { + initialBlockPoolSize = 0; + } + for (size_t i = 0; i < initialBlockPoolSize; ++i) { + initialBlockPool[i].dynamicallyAllocated = false; + } + } + + inline Block* try_get_block_from_initial_pool() + { + if (initialBlockPoolIndex.load(std::memory_order_relaxed) >= initialBlockPoolSize) { + return nullptr; + } + + auto index = initialBlockPoolIndex.fetch_add(1, std::memory_order_relaxed); + + return index < initialBlockPoolSize ? (initialBlockPool + index) : nullptr; + } + + inline void add_block_to_free_list(Block* block) + { + freeList.add(block); + } + + inline void add_blocks_to_free_list(Block* block) + { + while (block != nullptr) { + auto next = block->next; + add_block_to_free_list(block); + block = next; + } + } + + inline Block* try_get_block_from_free_list() + { + return freeList.try_get(); + } + + // Gets a free block from one of the memory pools, or allocates a new one (if applicable) + Block* requisition_block() + { + auto block = try_get_block_from_initial_pool(); + if (block != nullptr) { + return block; + } + + block = try_get_block_from_free_list(); + if (block != nullptr) { + return block; + } + + return create(); + } + + + ////////////////////////////////// + // Producer list manipulation + ////////////////////////////////// + + ProducerBase* recycle_or_create_producer() + { + bool recycled; + return recycle_or_create_producer(recycled); + } + + ProducerBase* recycle_or_create_producer(bool& recycled) + { + // Try to re-use one first + for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { + if (ptr->inactive.load(std::memory_order_relaxed)) { + if( ptr->size_approx() == 0 ) + { + bool expected = true; + if (ptr->inactive.compare_exchange_strong(expected, /* desired */ false, std::memory_order_acquire, std::memory_order_relaxed)) { + // We caught one! It's been marked as activated, the caller can have it + recycled = true; + return ptr; + } + } + } + } + + recycled = false; + return add_producer(static_cast(create(this))); + } + + ProducerBase* add_producer(ProducerBase* producer) + { + // Handle failed memory allocation + if (producer == nullptr) { + return nullptr; + } + + producerCount.fetch_add(1, std::memory_order_relaxed); + + // Add it to the lock-free list + auto prevTail = producerListTail.load(std::memory_order_relaxed); + do { + producer->next = prevTail; + } while (!producerListTail.compare_exchange_weak(prevTail, producer, std::memory_order_release, std::memory_order_relaxed)); + + return producer; + } + + void reown_producers() + { + // After another instance is moved-into/swapped-with this one, all the + // producers we stole still think their parents are the other queue. + // So fix them up! + for (auto ptr = producerListTail.load(std::memory_order_relaxed); ptr != nullptr; ptr = ptr->next_prod()) { + ptr->parent = this; + } + } + + ////////////////////////////////// + // Utility functions + ////////////////////////////////// + + template + static inline U* create_array(size_t count) + { + assert(count > 0); + return static_cast((Traits::malloc)(sizeof(U) * count)); + } + + template + static inline void destroy_array(U* p, size_t count) + { + ((void)count); + if (p != nullptr) { + assert(count > 0); + (Traits::free)(p); + } + } + + template + static inline U* create() + { + auto p = (Traits::malloc)(sizeof(U)); + return new (p) U; + } + + template + static inline U* create(A1&& a1) + { + auto p = (Traits::malloc)(sizeof(U)); + return new (p) U(std::forward(a1)); + } + + template + static inline void destroy(U* p) + { + if (p != nullptr) { + p->~U(); + } + (Traits::free)(p); + } + +private: + std::atomic producerListTail; + std::atomic producerCount; + + std::atomic initialBlockPoolIndex; + Block* initialBlockPool; + size_t initialBlockPoolSize; + + FreeList freeList; + + std::atomic nextExplicitConsumerId; + std::atomic globalExplicitConsumerOffset; +}; + + +template +ProducerToken::ProducerToken(ConcurrentQueue& queue) + : producer(queue.recycle_or_create_producer()) +{ + if (producer != nullptr) { + producer->token = this; + producer->threadId = detail::GetThreadHandleImpl(); + } +} + +template +ConsumerToken::ConsumerToken(ConcurrentQueue& queue) + : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr) +{ + initialOffset = queue.nextExplicitConsumerId.fetch_add(1, std::memory_order_release); + lastKnownGlobalOffset = static_cast(-1); +} + +template +inline void swap(ConcurrentQueue& a, ConcurrentQueue& b) noexcept +{ + a.swap(b); +} + +inline void swap(ProducerToken& a, ProducerToken& b) noexcept +{ + a.swap(b); +} + +inline void swap(ConsumerToken& a, ConsumerToken& b) noexcept +{ + a.swap(b); +} + +} + +} /* namespace tracy */ + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/Externals/tracy/public/client/tracy_rpmalloc.cpp b/Externals/tracy/public/client/tracy_rpmalloc.cpp new file mode 100644 index 00000000000..711505d21ac --- /dev/null +++ b/Externals/tracy/public/client/tracy_rpmalloc.cpp @@ -0,0 +1,3518 @@ +#ifdef TRACY_ENABLE + +/* rpmalloc.c - Memory allocator - Public Domain - 2016-2020 Mattias Jansson + * + * This library provides a cross-platform lock free thread caching malloc implementation in C11. + * The latest source code is always available at + * + * https://github.com/mjansson/rpmalloc + * + * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. + * + */ + +#include "tracy_rpmalloc.hpp" + +#define BUILD_DYNAMIC_LINK 1 + +//////////// +/// +/// Build time configurable limits +/// +////// + +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wunused-macros" +#pragma clang diagnostic ignored "-Wunused-function" +#if __has_warning("-Wreserved-identifier") +#pragma clang diagnostic ignored "-Wreserved-identifier" +#endif +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-macros" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + +#ifndef HEAP_ARRAY_SIZE +//! Size of heap hashmap +#define HEAP_ARRAY_SIZE 47 +#endif +#ifndef ENABLE_THREAD_CACHE +//! Enable per-thread cache +#define ENABLE_THREAD_CACHE 1 +#endif +#ifndef ENABLE_GLOBAL_CACHE +//! Enable global cache shared between all threads, requires thread cache +#define ENABLE_GLOBAL_CACHE 1 +#endif +#ifndef ENABLE_VALIDATE_ARGS +//! Enable validation of args to public entry points +#define ENABLE_VALIDATE_ARGS 0 +#endif +#ifndef ENABLE_STATISTICS +//! Enable statistics collection +#define ENABLE_STATISTICS 0 +#endif +#ifndef ENABLE_ASSERTS +//! Enable asserts +#define ENABLE_ASSERTS 0 +#endif +#ifndef ENABLE_OVERRIDE +//! Override standard library malloc/free and new/delete entry points +#define ENABLE_OVERRIDE 0 +#endif +#ifndef ENABLE_PRELOAD +//! Support preloading +#define ENABLE_PRELOAD 0 +#endif +#ifndef DISABLE_UNMAP +//! Disable unmapping memory pages (also enables unlimited cache) +#define DISABLE_UNMAP 0 +#endif +#ifndef ENABLE_UNLIMITED_CACHE +//! Enable unlimited global cache (no unmapping until finalization) +#define ENABLE_UNLIMITED_CACHE 0 +#endif +#ifndef ENABLE_ADAPTIVE_THREAD_CACHE +//! Enable adaptive thread cache size based on use heuristics +#define ENABLE_ADAPTIVE_THREAD_CACHE 0 +#endif +#ifndef DEFAULT_SPAN_MAP_COUNT +//! Default number of spans to map in call to map more virtual memory (default values yield 4MiB here) +#define DEFAULT_SPAN_MAP_COUNT 64 +#endif +#ifndef GLOBAL_CACHE_MULTIPLIER +//! Multiplier for global cache +#define GLOBAL_CACHE_MULTIPLIER 8 +#endif + +#if DISABLE_UNMAP && !ENABLE_GLOBAL_CACHE +#error Must use global cache if unmap is disabled +#endif + +#if DISABLE_UNMAP +#undef ENABLE_UNLIMITED_CACHE +#define ENABLE_UNLIMITED_CACHE 1 +#endif + +#if !ENABLE_GLOBAL_CACHE +#undef ENABLE_UNLIMITED_CACHE +#define ENABLE_UNLIMITED_CACHE 0 +#endif + +#if !ENABLE_THREAD_CACHE +#undef ENABLE_ADAPTIVE_THREAD_CACHE +#define ENABLE_ADAPTIVE_THREAD_CACHE 0 +#endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) +# define PLATFORM_WINDOWS 1 +# define PLATFORM_POSIX 0 +#else +# define PLATFORM_WINDOWS 0 +# define PLATFORM_POSIX 1 +#endif + +/// Platform and arch specifics +#if defined(_MSC_VER) && !defined(__clang__) +# pragma warning (disable: 5105) +# ifndef FORCEINLINE +# define FORCEINLINE inline __forceinline +# endif +#else +# ifndef FORCEINLINE +# define FORCEINLINE inline __attribute__((__always_inline__)) +# endif +#endif +#if PLATFORM_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# if ENABLE_VALIDATE_ARGS +# include +# endif +#else +# include +# include +# include +# include +# if defined(__linux__) || defined(__ANDROID__) +# include +# if !defined(PR_SET_VMA) +# define PR_SET_VMA 0x53564d41 +# define PR_SET_VMA_ANON_NAME 0 +# endif +# endif +# if defined(__APPLE__) +# include +# if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR +# include +# include +# endif +# include +# endif +# if defined(__HAIKU__) || defined(__TINYC__) +# include +# endif +#endif + +#include +#include +#include + +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) +#include +static DWORD fls_key; +#endif + +#if PLATFORM_POSIX +# include +# include +# ifdef __FreeBSD__ +# include +# define MAP_HUGETLB MAP_ALIGNED_SUPER +# ifndef PROT_MAX +# define PROT_MAX(f) 0 +# endif +# else +# define PROT_MAX(f) 0 +# endif +# ifdef __sun +extern int madvise(caddr_t, size_t, int); +# endif +# ifndef MAP_UNINITIALIZED +# define MAP_UNINITIALIZED 0 +# endif +#endif +#include + +#if ENABLE_ASSERTS +# undef NDEBUG +# if defined(_MSC_VER) && !defined(_DEBUG) +# define _DEBUG +# endif +# include +#define RPMALLOC_TOSTRING_M(x) #x +#define RPMALLOC_TOSTRING(x) RPMALLOC_TOSTRING_M(x) +#define rpmalloc_assert(truth, message) \ + do { \ + if (!(truth)) { \ + if (_memory_config.error_callback) { \ + _memory_config.error_callback( \ + message " (" RPMALLOC_TOSTRING(truth) ") at " __FILE__ ":" RPMALLOC_TOSTRING(__LINE__)); \ + } else { \ + assert((truth) && message); \ + } \ + } \ + } while (0) +#else +# define rpmalloc_assert(truth, message) do {} while(0) +#endif +#if ENABLE_STATISTICS +# include +#endif + +////// +/// +/// Atomic access abstraction (since MSVC does not do C11 yet) +/// +////// + +#include + +typedef std::atomic atomic32_t; +typedef std::atomic atomic64_t; +typedef std::atomic atomicptr_t; + +static FORCEINLINE int32_t atomic_load32(atomic32_t* src) { return std::atomic_load_explicit(src, std::memory_order_relaxed); } +static FORCEINLINE void atomic_store32(atomic32_t* dst, int32_t val) { std::atomic_store_explicit(dst, val, std::memory_order_relaxed); } +static FORCEINLINE int32_t atomic_incr32(atomic32_t* val) { return std::atomic_fetch_add_explicit(val, 1, std::memory_order_relaxed) + 1; } +static FORCEINLINE int32_t atomic_decr32(atomic32_t* val) { return std::atomic_fetch_add_explicit(val, -1, std::memory_order_relaxed) - 1; } +static FORCEINLINE int32_t atomic_add32(atomic32_t* val, int32_t add) { return std::atomic_fetch_add_explicit(val, add, std::memory_order_relaxed) + add; } +static FORCEINLINE int atomic_cas32_acquire(atomic32_t* dst, int32_t val, int32_t ref) { return std::atomic_compare_exchange_weak_explicit(dst, &ref, val, std::memory_order_acquire, std::memory_order_relaxed); } +static FORCEINLINE void atomic_store32_release(atomic32_t* dst, int32_t val) { std::atomic_store_explicit(dst, val, std::memory_order_release); } +static FORCEINLINE int64_t atomic_load64(atomic64_t* val) { return std::atomic_load_explicit(val, std::memory_order_relaxed); } +static FORCEINLINE int64_t atomic_add64(atomic64_t* val, int64_t add) { return std::atomic_fetch_add_explicit(val, add, std::memory_order_relaxed) + add; } +static FORCEINLINE void* atomic_load_ptr(atomicptr_t* src) { return std::atomic_load_explicit(src, std::memory_order_relaxed); } +static FORCEINLINE void atomic_store_ptr(atomicptr_t* dst, void* val) { std::atomic_store_explicit(dst, val, std::memory_order_relaxed); } +static FORCEINLINE void atomic_store_ptr_release(atomicptr_t* dst, void* val) { std::atomic_store_explicit(dst, val, std::memory_order_release); } +static FORCEINLINE void* atomic_exchange_ptr_acquire(atomicptr_t* dst, void* val) { return std::atomic_exchange_explicit(dst, val, std::memory_order_acquire); } +static FORCEINLINE int atomic_cas_ptr(atomicptr_t* dst, void* val, void* ref) { return std::atomic_compare_exchange_weak_explicit(dst, &ref, val, std::memory_order_relaxed, std::memory_order_relaxed); } + +#if defined(_MSC_VER) && !defined(__clang__) + +#define EXPECTED(x) (x) +#define UNEXPECTED(x) (x) + +#else + +#define EXPECTED(x) __builtin_expect((x), 1) +#define UNEXPECTED(x) __builtin_expect((x), 0) + +#endif + +//////////// +/// +/// Statistics related functions (evaluate to nothing when statistics not enabled) +/// +////// + +#if ENABLE_STATISTICS +# define _rpmalloc_stat_inc(counter) atomic_incr32(counter) +# define _rpmalloc_stat_dec(counter) atomic_decr32(counter) +# define _rpmalloc_stat_add(counter, value) atomic_add32(counter, (int32_t)(value)) +# define _rpmalloc_stat_add64(counter, value) atomic_add64(counter, (int64_t)(value)) +# define _rpmalloc_stat_add_peak(counter, value, peak) do { int32_t _cur_count = atomic_add32(counter, (int32_t)(value)); if (_cur_count > (peak)) peak = _cur_count; } while (0) +# define _rpmalloc_stat_sub(counter, value) atomic_add32(counter, -(int32_t)(value)) +# define _rpmalloc_stat_inc_alloc(heap, class_idx) do { \ + int32_t alloc_current = atomic_incr32(&heap->size_class_use[class_idx].alloc_current); \ + if (alloc_current > heap->size_class_use[class_idx].alloc_peak) \ + heap->size_class_use[class_idx].alloc_peak = alloc_current; \ + atomic_incr32(&heap->size_class_use[class_idx].alloc_total); \ +} while(0) +# define _rpmalloc_stat_inc_free(heap, class_idx) do { \ + atomic_decr32(&heap->size_class_use[class_idx].alloc_current); \ + atomic_incr32(&heap->size_class_use[class_idx].free_total); \ +} while(0) +#else +# define _rpmalloc_stat_inc(counter) do {} while(0) +# define _rpmalloc_stat_dec(counter) do {} while(0) +# define _rpmalloc_stat_add(counter, value) do {} while(0) +# define _rpmalloc_stat_add64(counter, value) do {} while(0) +# define _rpmalloc_stat_add_peak(counter, value, peak) do {} while (0) +# define _rpmalloc_stat_sub(counter, value) do {} while(0) +# define _rpmalloc_stat_inc_alloc(heap, class_idx) do {} while(0) +# define _rpmalloc_stat_inc_free(heap, class_idx) do {} while(0) +#endif + + +/// +/// Preconfigured limits and sizes +/// + +//! Granularity of a small allocation block (must be power of two) +#define SMALL_GRANULARITY 16 +//! Small granularity shift count +#define SMALL_GRANULARITY_SHIFT 4 +//! Number of small block size classes +#define SMALL_CLASS_COUNT 65 +//! Maximum size of a small block +#define SMALL_SIZE_LIMIT (SMALL_GRANULARITY * (SMALL_CLASS_COUNT - 1)) +//! Granularity of a medium allocation block +#define MEDIUM_GRANULARITY 512 +//! Medium granularity shift count +#define MEDIUM_GRANULARITY_SHIFT 9 +//! Number of medium block size classes +#define MEDIUM_CLASS_COUNT 61 +//! Total number of small + medium size classes +#define SIZE_CLASS_COUNT (SMALL_CLASS_COUNT + MEDIUM_CLASS_COUNT) +//! Number of large block size classes +#define LARGE_CLASS_COUNT 63 +//! Maximum size of a medium block +#define MEDIUM_SIZE_LIMIT (SMALL_SIZE_LIMIT + (MEDIUM_GRANULARITY * MEDIUM_CLASS_COUNT)) +//! Maximum size of a large block +#define LARGE_SIZE_LIMIT ((LARGE_CLASS_COUNT * _memory_span_size) - SPAN_HEADER_SIZE) +//! Size of a span header (must be a multiple of SMALL_GRANULARITY and a power of two) +#define SPAN_HEADER_SIZE 128 +//! Number of spans in thread cache +#define MAX_THREAD_SPAN_CACHE 400 +//! Number of spans to transfer between thread and global cache +#define THREAD_SPAN_CACHE_TRANSFER 64 +//! Number of spans in thread cache for large spans (must be greater than LARGE_CLASS_COUNT / 2) +#define MAX_THREAD_SPAN_LARGE_CACHE 100 +//! Number of spans to transfer between thread and global cache for large spans +#define THREAD_SPAN_LARGE_CACHE_TRANSFER 6 + +static_assert((SMALL_GRANULARITY & (SMALL_GRANULARITY - 1)) == 0, "Small granularity must be power of two"); +static_assert((SPAN_HEADER_SIZE & (SPAN_HEADER_SIZE - 1)) == 0, "Span header size must be power of two"); + +#if ENABLE_VALIDATE_ARGS +//! Maximum allocation size to avoid integer overflow +#undef MAX_ALLOC_SIZE +#define MAX_ALLOC_SIZE (((size_t)-1) - _memory_span_size) +#endif + +#define pointer_offset(ptr, ofs) (void*)((char*)(ptr) + (ptrdiff_t)(ofs)) +#define pointer_diff(first, second) (ptrdiff_t)((const char*)(first) - (const char*)(second)) + +#define INVALID_POINTER ((void*)((uintptr_t)-1)) + +#define SIZE_CLASS_LARGE SIZE_CLASS_COUNT +#define SIZE_CLASS_HUGE ((uint32_t)-1) + +//////////// +/// +/// Data types +/// +////// + +namespace tracy +{ + +//! A memory heap, per thread +typedef struct heap_t heap_t; +//! Span of memory pages +typedef struct span_t span_t; +//! Span list +typedef struct span_list_t span_list_t; +//! Span active data +typedef struct span_active_t span_active_t; +//! Size class definition +typedef struct size_class_t size_class_t; +//! Global cache +typedef struct global_cache_t global_cache_t; + +//! Flag indicating span is the first (master) span of a split superspan +#define SPAN_FLAG_MASTER 1U +//! Flag indicating span is a secondary (sub) span of a split superspan +#define SPAN_FLAG_SUBSPAN 2U +//! Flag indicating span has blocks with increased alignment +#define SPAN_FLAG_ALIGNED_BLOCKS 4U +//! Flag indicating an unmapped master span +#define SPAN_FLAG_UNMAPPED_MASTER 8U + +#if ENABLE_ADAPTIVE_THREAD_CACHE || ENABLE_STATISTICS +struct span_use_t { + //! Current number of spans used (actually used, not in cache) + atomic32_t current; + //! High water mark of spans used + atomic32_t high; +#if ENABLE_STATISTICS + //! Number of spans in deferred list + atomic32_t spans_deferred; + //! Number of spans transitioned to global cache + atomic32_t spans_to_global; + //! Number of spans transitioned from global cache + atomic32_t spans_from_global; + //! Number of spans transitioned to thread cache + atomic32_t spans_to_cache; + //! Number of spans transitioned from thread cache + atomic32_t spans_from_cache; + //! Number of spans transitioned to reserved state + atomic32_t spans_to_reserved; + //! Number of spans transitioned from reserved state + atomic32_t spans_from_reserved; + //! Number of raw memory map calls + atomic32_t spans_map_calls; +#endif +}; +typedef struct span_use_t span_use_t; +#endif + +#if ENABLE_STATISTICS +struct size_class_use_t { + //! Current number of allocations + atomic32_t alloc_current; + //! Peak number of allocations + int32_t alloc_peak; + //! Total number of allocations + atomic32_t alloc_total; + //! Total number of frees + atomic32_t free_total; + //! Number of spans in use + atomic32_t spans_current; + //! Number of spans transitioned to cache + int32_t spans_peak; + //! Number of spans transitioned to cache + atomic32_t spans_to_cache; + //! Number of spans transitioned from cache + atomic32_t spans_from_cache; + //! Number of spans transitioned from reserved state + atomic32_t spans_from_reserved; + //! Number of spans mapped + atomic32_t spans_map_calls; + int32_t unused; +}; +typedef struct size_class_use_t size_class_use_t; +#endif + +// A span can either represent a single span of memory pages with size declared by span_map_count configuration variable, +// or a set of spans in a continuous region, a super span. Any reference to the term "span" usually refers to both a single +// span or a super span. A super span can further be divided into multiple spans (or this, super spans), where the first +// (super)span is the master and subsequent (super)spans are subspans. The master span keeps track of how many subspans +// that are still alive and mapped in virtual memory, and once all subspans and master have been unmapped the entire +// superspan region is released and unmapped (on Windows for example, the entire superspan range has to be released +// in the same call to release the virtual memory range, but individual subranges can be decommitted individually +// to reduce physical memory use). +struct span_t { + //! Free list + void* free_list; + //! Total block count of size class + uint32_t block_count; + //! Size class + uint32_t size_class; + //! Index of last block initialized in free list + uint32_t free_list_limit; + //! Number of used blocks remaining when in partial state + uint32_t used_count; + //! Deferred free list + atomicptr_t free_list_deferred; + //! Size of deferred free list, or list of spans when part of a cache list + uint32_t list_size; + //! Size of a block + uint32_t block_size; + //! Flags and counters + uint32_t flags; + //! Number of spans + uint32_t span_count; + //! Total span counter for master spans + uint32_t total_spans; + //! Offset from master span for subspans + uint32_t offset_from_master; + //! Remaining span counter, for master spans + atomic32_t remaining_spans; + //! Alignment offset + uint32_t align_offset; + //! Owning heap + heap_t* heap; + //! Next span + span_t* next; + //! Previous span + span_t* prev; +}; +static_assert(sizeof(span_t) <= SPAN_HEADER_SIZE, "span size mismatch"); + +struct span_cache_t { + size_t count; + span_t* span[MAX_THREAD_SPAN_CACHE]; +}; +typedef struct span_cache_t span_cache_t; + +struct span_large_cache_t { + size_t count; + span_t* span[MAX_THREAD_SPAN_LARGE_CACHE]; +}; +typedef struct span_large_cache_t span_large_cache_t; + +struct heap_size_class_t { + //! Free list of active span + void* free_list; + //! Double linked list of partially used spans with free blocks. + // Previous span pointer in head points to tail span of list. + span_t* partial_span; + //! Early level cache of fully free spans + span_t* cache; +}; +typedef struct heap_size_class_t heap_size_class_t; + +// Control structure for a heap, either a thread heap or a first class heap if enabled +struct heap_t { + //! Owning thread ID + uintptr_t owner_thread; + //! Free lists for each size class + heap_size_class_t size_class[SIZE_CLASS_COUNT]; +#if ENABLE_THREAD_CACHE + //! Arrays of fully freed spans, single span + span_cache_t span_cache; +#endif + //! List of deferred free spans (single linked list) + atomicptr_t span_free_deferred; + //! Number of full spans + size_t full_span_count; + //! Mapped but unused spans + span_t* span_reserve; + //! Master span for mapped but unused spans + span_t* span_reserve_master; + //! Number of mapped but unused spans + uint32_t spans_reserved; + //! Child count + atomic32_t child_count; + //! Next heap in id list + heap_t* next_heap; + //! Next heap in orphan list + heap_t* next_orphan; + //! Heap ID + int32_t id; + //! Finalization state flag + int finalize; + //! Master heap owning the memory pages + heap_t* master_heap; +#if ENABLE_THREAD_CACHE + //! Arrays of fully freed spans, large spans with > 1 span count + span_large_cache_t span_large_cache[LARGE_CLASS_COUNT - 1]; +#endif +#if RPMALLOC_FIRST_CLASS_HEAPS + //! Double linked list of fully utilized spans with free blocks for each size class. + // Previous span pointer in head points to tail span of list. + span_t* full_span[SIZE_CLASS_COUNT]; + //! Double linked list of large and huge spans allocated by this heap + span_t* large_huge_span; +#endif +#if ENABLE_ADAPTIVE_THREAD_CACHE || ENABLE_STATISTICS + //! Current and high water mark of spans used per span count + span_use_t span_use[LARGE_CLASS_COUNT]; +#endif +#if ENABLE_STATISTICS + //! Allocation stats per size class + size_class_use_t size_class_use[SIZE_CLASS_COUNT + 1]; + //! Number of bytes transitioned thread -> global + atomic64_t thread_to_global; + //! Number of bytes transitioned global -> thread + atomic64_t global_to_thread; +#endif +}; + +// Size class for defining a block size bucket +struct size_class_t { + //! Size of blocks in this class + uint32_t block_size; + //! Number of blocks in each chunk + uint16_t block_count; + //! Class index this class is merged with + uint16_t class_idx; +}; +static_assert(sizeof(size_class_t) == 8, "Size class size mismatch"); + +struct global_cache_t { + //! Cache lock + atomic32_t lock; + //! Cache count + uint32_t count; +#if ENABLE_STATISTICS + //! Insert count + size_t insert_count; + //! Extract count + size_t extract_count; +#endif + //! Cached spans + span_t* span[GLOBAL_CACHE_MULTIPLIER * MAX_THREAD_SPAN_CACHE]; + //! Unlimited cache overflow + span_t* overflow; +}; + +//////////// +/// +/// Global data +/// +////// + +//! Default span size (64KiB) +#define _memory_default_span_size (64 * 1024) +#define _memory_default_span_size_shift 16 +#define _memory_default_span_mask (~((uintptr_t)(_memory_span_size - 1))) + +//! Initialized flag +static int _rpmalloc_initialized; +//! Main thread ID +static uintptr_t _rpmalloc_main_thread_id; +//! Configuration +static rpmalloc_config_t _memory_config; +//! Memory page size +static size_t _memory_page_size; +//! Shift to divide by page size +static size_t _memory_page_size_shift; +//! Granularity at which memory pages are mapped by OS +static size_t _memory_map_granularity; +#if RPMALLOC_CONFIGURABLE +//! Size of a span of memory pages +static size_t _memory_span_size; +//! Shift to divide by span size +static size_t _memory_span_size_shift; +//! Mask to get to start of a memory span +static uintptr_t _memory_span_mask; +#else +//! Hardwired span size +#define _memory_span_size _memory_default_span_size +#define _memory_span_size_shift _memory_default_span_size_shift +#define _memory_span_mask _memory_default_span_mask +#endif +//! Number of spans to map in each map call +static size_t _memory_span_map_count; +//! Number of spans to keep reserved in each heap +static size_t _memory_heap_reserve_count; +//! Global size classes +static size_class_t _memory_size_class[SIZE_CLASS_COUNT]; +//! Run-time size limit of medium blocks +static size_t _memory_medium_size_limit; +//! Heap ID counter +static atomic32_t _memory_heap_id; +//! Huge page support +static int _memory_huge_pages; +#if ENABLE_GLOBAL_CACHE +//! Global span cache +static global_cache_t _memory_span_cache[LARGE_CLASS_COUNT]; +#endif +//! Global reserved spans +static span_t* _memory_global_reserve; +//! Global reserved count +static size_t _memory_global_reserve_count; +//! Global reserved master +static span_t* _memory_global_reserve_master; +//! All heaps +static heap_t* _memory_heaps[HEAP_ARRAY_SIZE]; +//! Used to restrict access to mapping memory for huge pages +static atomic32_t _memory_global_lock; +//! Orphaned heaps +static heap_t* _memory_orphan_heaps; +#if RPMALLOC_FIRST_CLASS_HEAPS +//! Orphaned heaps (first class heaps) +static heap_t* _memory_first_class_orphan_heaps; +#endif +#if ENABLE_STATISTICS +//! Allocations counter +static atomic64_t _allocation_counter; +//! Deallocations counter +static atomic64_t _deallocation_counter; +//! Active heap count +static atomic32_t _memory_active_heaps; +//! Number of currently mapped memory pages +static atomic32_t _mapped_pages; +//! Peak number of concurrently mapped memory pages +static int32_t _mapped_pages_peak; +//! Number of mapped master spans +static atomic32_t _master_spans; +//! Number of unmapped dangling master spans +static atomic32_t _unmapped_master_spans; +//! Running counter of total number of mapped memory pages since start +static atomic32_t _mapped_total; +//! Running counter of total number of unmapped memory pages since start +static atomic32_t _unmapped_total; +//! Number of currently mapped memory pages in OS calls +static atomic32_t _mapped_pages_os; +//! Number of currently allocated pages in huge allocations +static atomic32_t _huge_pages_current; +//! Peak number of currently allocated pages in huge allocations +static int32_t _huge_pages_peak; +#endif + +//////////// +/// +/// Thread local heap and ID +/// +////// + +//! Current thread heap +#if ((defined(__APPLE__) || defined(__HAIKU__)) && ENABLE_PRELOAD) || defined(__TINYC__) +static pthread_key_t _memory_thread_heap; +#else +# ifdef _MSC_VER +# define _Thread_local __declspec(thread) +# define TLS_MODEL +# else +# ifndef __HAIKU__ +# define TLS_MODEL __attribute__((tls_model("initial-exec"))) +# else +# define TLS_MODEL +# endif +# if !defined(__clang__) && defined(__GNUC__) +# define _Thread_local __thread +# endif +# endif +static _Thread_local heap_t* _memory_thread_heap TLS_MODEL; +#endif + +static inline heap_t* +get_thread_heap_raw(void) { +#if (defined(__APPLE__) || defined(__HAIKU__)) && ENABLE_PRELOAD + return pthread_getspecific(_memory_thread_heap); +#else + return _memory_thread_heap; +#endif +} + +//! Get the current thread heap +static inline heap_t* +get_thread_heap(void) { + heap_t* heap = get_thread_heap_raw(); +#if ENABLE_PRELOAD + if (EXPECTED(heap != 0)) + return heap; + rpmalloc_initialize(); + return get_thread_heap_raw(); +#else + return heap; +#endif +} + +//! Fast thread ID +static inline uintptr_t +get_thread_id(void) { +#if defined(_WIN32) + return (uintptr_t)((void*)NtCurrentTeb()); +#elif (defined(__GNUC__) || defined(__clang__)) && !defined(__CYGWIN__) + uintptr_t tid; +# if defined(__i386__) + __asm__("movl %%gs:0, %0" : "=r" (tid) : : ); +# elif defined(__x86_64__) +# if defined(__MACH__) + __asm__("movq %%gs:0, %0" : "=r" (tid) : : ); +# else + __asm__("movq %%fs:0, %0" : "=r" (tid) : : ); +# endif +# elif defined(__arm__) + __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3" : "=r" (tid)); +# elif defined(__aarch64__) +# if defined(__MACH__) + // tpidr_el0 likely unused, always return 0 on iOS + __asm__ volatile ("mrs %0, tpidrro_el0" : "=r" (tid)); +# else + __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tid)); +# endif +# else + tid = (uintptr_t)((void*)get_thread_heap_raw()); +# endif + return tid; +#else + return (uintptr_t)((void*)get_thread_heap_raw()); +#endif +} + +//! Set the current thread heap +static void +set_thread_heap(heap_t* heap) { +#if ((defined(__APPLE__) || defined(__HAIKU__)) && ENABLE_PRELOAD) || defined(__TINYC__) + pthread_setspecific(_memory_thread_heap, heap); +#else + _memory_thread_heap = heap; +#endif + if (heap) + heap->owner_thread = get_thread_id(); +} + +//! Set main thread ID +extern void +rpmalloc_set_main_thread(void); + +void +rpmalloc_set_main_thread(void) { + _rpmalloc_main_thread_id = get_thread_id(); +} + +static void +_rpmalloc_spin(void) { +#if defined(_MSC_VER) + _mm_pause(); +#elif defined(__x86_64__) || defined(__i386__) + __asm__ volatile("pause" ::: "memory"); +#elif defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH >= 7) + __asm__ volatile("yield" ::: "memory"); +#elif defined(__powerpc__) || defined(__powerpc64__) + // No idea if ever been compiled in such archs but ... as precaution + __asm__ volatile("or 27,27,27"); +#elif defined(__sparc__) + __asm__ volatile("rd %ccr, %g0 \n\trd %ccr, %g0 \n\trd %ccr, %g0"); +#else + struct timespec ts = {0}; + nanosleep(&ts, 0); +#endif +} + +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) +static void NTAPI +_rpmalloc_thread_destructor(void* value) { +#if ENABLE_OVERRIDE + // If this is called on main thread it means rpmalloc_finalize + // has not been called and shutdown is forced (through _exit) or unclean + if (get_thread_id() == _rpmalloc_main_thread_id) + return; +#endif + if (value) + rpmalloc_thread_finalize(1); +} +#endif + + +//////////// +/// +/// Low level memory map/unmap +/// +////// + +static void +_rpmalloc_set_name(void* address, size_t size) { +#if defined(__linux__) || defined(__ANDROID__) + const char *name = _memory_huge_pages ? _memory_config.huge_page_name : _memory_config.page_name; + if (address == MAP_FAILED || !name) + return; + // If the kernel does not support CONFIG_ANON_VMA_NAME or if the call fails + // (e.g. invalid name) it is a no-op basically. + (void)prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)address, size, (uintptr_t)name); +#else + (void)sizeof(size); + (void)sizeof(address); +#endif +} + + +//! Map more virtual memory +// size is number of bytes to map +// offset receives the offset in bytes from start of mapped region +// returns address to start of mapped region to use +static void* +_rpmalloc_mmap(size_t size, size_t* offset) { + rpmalloc_assert(!(size % _memory_page_size), "Invalid mmap size"); + rpmalloc_assert(size >= _memory_page_size, "Invalid mmap size"); + void* address = _memory_config.memory_map(size, offset); + if (EXPECTED(address != 0)) { + _rpmalloc_stat_add_peak(&_mapped_pages, (size >> _memory_page_size_shift), _mapped_pages_peak); + _rpmalloc_stat_add(&_mapped_total, (size >> _memory_page_size_shift)); + } + return address; +} + +//! Unmap virtual memory +// address is the memory address to unmap, as returned from _memory_map +// size is the number of bytes to unmap, which might be less than full region for a partial unmap +// offset is the offset in bytes to the actual mapped region, as set by _memory_map +// release is set to 0 for partial unmap, or size of entire range for a full unmap +static void +_rpmalloc_unmap(void* address, size_t size, size_t offset, size_t release) { + rpmalloc_assert(!release || (release >= size), "Invalid unmap size"); + rpmalloc_assert(!release || (release >= _memory_page_size), "Invalid unmap size"); + if (release) { + rpmalloc_assert(!(release % _memory_page_size), "Invalid unmap size"); + _rpmalloc_stat_sub(&_mapped_pages, (release >> _memory_page_size_shift)); + _rpmalloc_stat_add(&_unmapped_total, (release >> _memory_page_size_shift)); + } + _memory_config.memory_unmap(address, size, offset, release); +} + +//! Default implementation to map new pages to virtual memory +static void* +_rpmalloc_mmap_os(size_t size, size_t* offset) { + //Either size is a heap (a single page) or a (multiple) span - we only need to align spans, and only if larger than map granularity + size_t padding = ((size >= _memory_span_size) && (_memory_span_size > _memory_map_granularity)) ? _memory_span_size : 0; + rpmalloc_assert(size >= _memory_page_size, "Invalid mmap size"); +#if PLATFORM_WINDOWS + //Ok to MEM_COMMIT - according to MSDN, "actual physical pages are not allocated unless/until the virtual addresses are actually accessed" + void* ptr = VirtualAlloc(0, size + padding, (_memory_huge_pages ? MEM_LARGE_PAGES : 0) | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (!ptr) { + if (_memory_config.map_fail_callback) { + if (_memory_config.map_fail_callback(size + padding)) + return _rpmalloc_mmap_os(size, offset); + } else { + rpmalloc_assert(ptr, "Failed to map virtual memory block"); + } + return 0; + } +#else + int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED; +# if defined(__APPLE__) && !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + int fd = (int)VM_MAKE_TAG(240U); + if (_memory_huge_pages) + fd |= VM_FLAGS_SUPERPAGE_SIZE_2MB; + void* ptr = mmap(0, size + padding, PROT_READ | PROT_WRITE, flags, fd, 0); +# elif defined(MAP_HUGETLB) + void* ptr = mmap(0, size + padding, PROT_READ | PROT_WRITE | PROT_MAX(PROT_READ | PROT_WRITE), (_memory_huge_pages ? MAP_HUGETLB : 0) | flags, -1, 0); +# if defined(MADV_HUGEPAGE) + // In some configurations, huge pages allocations might fail thus + // we fallback to normal allocations and promote the region as transparent huge page + if ((ptr == MAP_FAILED || !ptr) && _memory_huge_pages) { + ptr = mmap(0, size + padding, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr && ptr != MAP_FAILED) { + int prm = madvise(ptr, size + padding, MADV_HUGEPAGE); + (void)prm; + rpmalloc_assert((prm == 0), "Failed to promote the page to THP"); + } + } +# endif + _rpmalloc_set_name(ptr, size + padding); +# elif defined(MAP_ALIGNED) + const size_t align = (sizeof(size_t) * 8) - (size_t)(__builtin_clzl(size - 1)); + void* ptr = mmap(0, size + padding, PROT_READ | PROT_WRITE, (_memory_huge_pages ? MAP_ALIGNED(align) : 0) | flags, -1, 0); +# elif defined(MAP_ALIGN) + caddr_t base = (_memory_huge_pages ? (caddr_t)(4 << 20) : 0); + void* ptr = mmap(base, size + padding, PROT_READ | PROT_WRITE, (_memory_huge_pages ? MAP_ALIGN : 0) | flags, -1, 0); +# else + void* ptr = mmap(0, size + padding, PROT_READ | PROT_WRITE, flags, -1, 0); +# endif + if ((ptr == MAP_FAILED) || !ptr) { + if (_memory_config.map_fail_callback) { + if (_memory_config.map_fail_callback(size + padding)) + return _rpmalloc_mmap_os(size, offset); + } else if (errno != ENOMEM) { + rpmalloc_assert((ptr != MAP_FAILED) && ptr, "Failed to map virtual memory block"); + } + return 0; + } +#endif + _rpmalloc_stat_add(&_mapped_pages_os, (int32_t)((size + padding) >> _memory_page_size_shift)); + if (padding) { + size_t final_padding = padding - ((uintptr_t)ptr & ~_memory_span_mask); + rpmalloc_assert(final_padding <= _memory_span_size, "Internal failure in padding"); + rpmalloc_assert(final_padding <= padding, "Internal failure in padding"); + rpmalloc_assert(!(final_padding % 8), "Internal failure in padding"); + ptr = pointer_offset(ptr, final_padding); + *offset = final_padding >> 3; + } + rpmalloc_assert((size < _memory_span_size) || !((uintptr_t)ptr & ~_memory_span_mask), "Internal failure in padding"); + return ptr; +} + +//! Default implementation to unmap pages from virtual memory +static void +_rpmalloc_unmap_os(void* address, size_t size, size_t offset, size_t release) { + rpmalloc_assert(release || (offset == 0), "Invalid unmap size"); + rpmalloc_assert(!release || (release >= _memory_page_size), "Invalid unmap size"); + rpmalloc_assert(size >= _memory_page_size, "Invalid unmap size"); + if (release && offset) { + offset <<= 3; + address = pointer_offset(address, -(int32_t)offset); + if ((release >= _memory_span_size) && (_memory_span_size > _memory_map_granularity)) { + //Padding is always one span size + release += _memory_span_size; + } + } +#if !DISABLE_UNMAP +#if PLATFORM_WINDOWS + if (!VirtualFree(address, release ? 0 : size, release ? MEM_RELEASE : MEM_DECOMMIT)) { + rpmalloc_assert(0, "Failed to unmap virtual memory block"); + } +#else + if (release) { + if (munmap(address, release)) { + rpmalloc_assert(0, "Failed to unmap virtual memory block"); + } + } else { +#if defined(MADV_FREE_REUSABLE) + int ret; + while ((ret = madvise(address, size, MADV_FREE_REUSABLE)) == -1 && (errno == EAGAIN)) + errno = 0; + if ((ret == -1) && (errno != 0)) { +#elif defined(MADV_DONTNEED) + if (madvise(address, size, MADV_DONTNEED)) { +#elif defined(MADV_PAGEOUT) + if (madvise(address, size, MADV_PAGEOUT)) { +#elif defined(MADV_FREE) + if (madvise(address, size, MADV_FREE)) { +#else + if (posix_madvise(address, size, POSIX_MADV_DONTNEED)) { +#endif + rpmalloc_assert(0, "Failed to madvise virtual memory block as free"); + } + } +#endif +#endif + if (release) + _rpmalloc_stat_sub(&_mapped_pages_os, release >> _memory_page_size_shift); +} + +static void +_rpmalloc_span_mark_as_subspan_unless_master(span_t* master, span_t* subspan, size_t span_count); + +//! Use global reserved spans to fulfill a memory map request (reserve size must be checked by caller) +static span_t* +_rpmalloc_global_get_reserved_spans(size_t span_count) { + span_t* span = _memory_global_reserve; + _rpmalloc_span_mark_as_subspan_unless_master(_memory_global_reserve_master, span, span_count); + _memory_global_reserve_count -= span_count; + if (_memory_global_reserve_count) + _memory_global_reserve = (span_t*)pointer_offset(span, span_count << _memory_span_size_shift); + else + _memory_global_reserve = 0; + return span; +} + +//! Store the given spans as global reserve (must only be called from within new heap allocation, not thread safe) +static void +_rpmalloc_global_set_reserved_spans(span_t* master, span_t* reserve, size_t reserve_span_count) { + _memory_global_reserve_master = master; + _memory_global_reserve_count = reserve_span_count; + _memory_global_reserve = reserve; +} + + +//////////// +/// +/// Span linked list management +/// +////// + +//! Add a span to double linked list at the head +static void +_rpmalloc_span_double_link_list_add(span_t** head, span_t* span) { + if (*head) + (*head)->prev = span; + span->next = *head; + *head = span; +} + +//! Pop head span from double linked list +static void +_rpmalloc_span_double_link_list_pop_head(span_t** head, span_t* span) { + rpmalloc_assert(*head == span, "Linked list corrupted"); + span = *head; + *head = span->next; +} + +//! Remove a span from double linked list +static void +_rpmalloc_span_double_link_list_remove(span_t** head, span_t* span) { + rpmalloc_assert(*head, "Linked list corrupted"); + if (*head == span) { + *head = span->next; + } else { + span_t* next_span = span->next; + span_t* prev_span = span->prev; + prev_span->next = next_span; + if (EXPECTED(next_span != 0)) + next_span->prev = prev_span; + } +} + + +//////////// +/// +/// Span control +/// +////// + +static void +_rpmalloc_heap_cache_insert(heap_t* heap, span_t* span); + +static void +_rpmalloc_heap_finalize(heap_t* heap); + +static void +_rpmalloc_heap_set_reserved_spans(heap_t* heap, span_t* master, span_t* reserve, size_t reserve_span_count); + +//! Declare the span to be a subspan and store distance from master span and span count +static void +_rpmalloc_span_mark_as_subspan_unless_master(span_t* master, span_t* subspan, size_t span_count) { + rpmalloc_assert((subspan != master) || (subspan->flags & SPAN_FLAG_MASTER), "Span master pointer and/or flag mismatch"); + if (subspan != master) { + subspan->flags = SPAN_FLAG_SUBSPAN; + subspan->offset_from_master = (uint32_t)((uintptr_t)pointer_diff(subspan, master) >> _memory_span_size_shift); + subspan->align_offset = 0; + } + subspan->span_count = (uint32_t)span_count; +} + +//! Use reserved spans to fulfill a memory map request (reserve size must be checked by caller) +static span_t* +_rpmalloc_span_map_from_reserve(heap_t* heap, size_t span_count) { + //Update the heap span reserve + span_t* span = heap->span_reserve; + heap->span_reserve = (span_t*)pointer_offset(span, span_count * _memory_span_size); + heap->spans_reserved -= (uint32_t)span_count; + + _rpmalloc_span_mark_as_subspan_unless_master(heap->span_reserve_master, span, span_count); + if (span_count <= LARGE_CLASS_COUNT) + _rpmalloc_stat_inc(&heap->span_use[span_count - 1].spans_from_reserved); + + return span; +} + +//! Get the aligned number of spans to map in based on wanted count, configured mapping granularity and the page size +static size_t +_rpmalloc_span_align_count(size_t span_count) { + size_t request_count = (span_count > _memory_span_map_count) ? span_count : _memory_span_map_count; + if ((_memory_page_size > _memory_span_size) && ((request_count * _memory_span_size) % _memory_page_size)) + request_count += _memory_span_map_count - (request_count % _memory_span_map_count); + return request_count; +} + +//! Setup a newly mapped span +static void +_rpmalloc_span_initialize(span_t* span, size_t total_span_count, size_t span_count, size_t align_offset) { + span->total_spans = (uint32_t)total_span_count; + span->span_count = (uint32_t)span_count; + span->align_offset = (uint32_t)align_offset; + span->flags = SPAN_FLAG_MASTER; + atomic_store32(&span->remaining_spans, (int32_t)total_span_count); +} + +static void +_rpmalloc_span_unmap(span_t* span); + +//! Map an aligned set of spans, taking configured mapping granularity and the page size into account +static span_t* +_rpmalloc_span_map_aligned_count(heap_t* heap, size_t span_count) { + //If we already have some, but not enough, reserved spans, release those to heap cache and map a new + //full set of spans. Otherwise we would waste memory if page size > span size (huge pages) + size_t aligned_span_count = _rpmalloc_span_align_count(span_count); + size_t align_offset = 0; + span_t* span = (span_t*)_rpmalloc_mmap(aligned_span_count * _memory_span_size, &align_offset); + if (!span) + return 0; + _rpmalloc_span_initialize(span, aligned_span_count, span_count, align_offset); + _rpmalloc_stat_inc(&_master_spans); + if (span_count <= LARGE_CLASS_COUNT) + _rpmalloc_stat_inc(&heap->span_use[span_count - 1].spans_map_calls); + if (aligned_span_count > span_count) { + span_t* reserved_spans = (span_t*)pointer_offset(span, span_count * _memory_span_size); + size_t reserved_count = aligned_span_count - span_count; + if (heap->spans_reserved) { + _rpmalloc_span_mark_as_subspan_unless_master(heap->span_reserve_master, heap->span_reserve, heap->spans_reserved); + _rpmalloc_heap_cache_insert(heap, heap->span_reserve); + } + if (reserved_count > _memory_heap_reserve_count) { + // If huge pages or eager spam map count, the global reserve spin lock is held by caller, _rpmalloc_span_map + rpmalloc_assert(atomic_load32(&_memory_global_lock) == 1, "Global spin lock not held as expected"); + size_t remain_count = reserved_count - _memory_heap_reserve_count; + reserved_count = _memory_heap_reserve_count; + span_t* remain_span = (span_t*)pointer_offset(reserved_spans, reserved_count * _memory_span_size); + if (_memory_global_reserve) { + _rpmalloc_span_mark_as_subspan_unless_master(_memory_global_reserve_master, _memory_global_reserve, _memory_global_reserve_count); + _rpmalloc_span_unmap(_memory_global_reserve); + } + _rpmalloc_global_set_reserved_spans(span, remain_span, remain_count); + } + _rpmalloc_heap_set_reserved_spans(heap, span, reserved_spans, reserved_count); + } + return span; +} + +//! Map in memory pages for the given number of spans (or use previously reserved pages) +static span_t* +_rpmalloc_span_map(heap_t* heap, size_t span_count) { + if (span_count <= heap->spans_reserved) + return _rpmalloc_span_map_from_reserve(heap, span_count); + span_t* span = 0; + int use_global_reserve = (_memory_page_size > _memory_span_size) || (_memory_span_map_count > _memory_heap_reserve_count); + if (use_global_reserve) { + // If huge pages, make sure only one thread maps more memory to avoid bloat + while (!atomic_cas32_acquire(&_memory_global_lock, 1, 0)) + _rpmalloc_spin(); + if (_memory_global_reserve_count >= span_count) { + size_t reserve_count = (!heap->spans_reserved ? _memory_heap_reserve_count : span_count); + if (_memory_global_reserve_count < reserve_count) + reserve_count = _memory_global_reserve_count; + span = _rpmalloc_global_get_reserved_spans(reserve_count); + if (span) { + if (reserve_count > span_count) { + span_t* reserved_span = (span_t*)pointer_offset(span, span_count << _memory_span_size_shift); + _rpmalloc_heap_set_reserved_spans(heap, _memory_global_reserve_master, reserved_span, reserve_count - span_count); + } + // Already marked as subspan in _rpmalloc_global_get_reserved_spans + span->span_count = (uint32_t)span_count; + } + } + } + if (!span) + span = _rpmalloc_span_map_aligned_count(heap, span_count); + if (use_global_reserve) + atomic_store32_release(&_memory_global_lock, 0); + return span; +} + +//! Unmap memory pages for the given number of spans (or mark as unused if no partial unmappings) +static void +_rpmalloc_span_unmap(span_t* span) { + rpmalloc_assert((span->flags & SPAN_FLAG_MASTER) || (span->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + rpmalloc_assert(!(span->flags & SPAN_FLAG_MASTER) || !(span->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + + int is_master = !!(span->flags & SPAN_FLAG_MASTER); + span_t* master = is_master ? span : ((span_t*)pointer_offset(span, -(intptr_t)((uintptr_t)span->offset_from_master * _memory_span_size))); + rpmalloc_assert(is_master || (span->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + rpmalloc_assert(master->flags & SPAN_FLAG_MASTER, "Span flag corrupted"); + + size_t span_count = span->span_count; + if (!is_master) { + //Directly unmap subspans (unless huge pages, in which case we defer and unmap entire page range with master) + rpmalloc_assert(span->align_offset == 0, "Span align offset corrupted"); + if (_memory_span_size >= _memory_page_size) + _rpmalloc_unmap(span, span_count * _memory_span_size, 0, 0); + } else { + //Special double flag to denote an unmapped master + //It must be kept in memory since span header must be used + span->flags |= SPAN_FLAG_MASTER | SPAN_FLAG_SUBSPAN | SPAN_FLAG_UNMAPPED_MASTER; + _rpmalloc_stat_add(&_unmapped_master_spans, 1); + } + + if (atomic_add32(&master->remaining_spans, -(int32_t)span_count) <= 0) { + //Everything unmapped, unmap the master span with release flag to unmap the entire range of the super span + rpmalloc_assert(!!(master->flags & SPAN_FLAG_MASTER) && !!(master->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + size_t unmap_count = master->span_count; + if (_memory_span_size < _memory_page_size) + unmap_count = master->total_spans; + _rpmalloc_stat_sub(&_master_spans, 1); + _rpmalloc_stat_sub(&_unmapped_master_spans, 1); + _rpmalloc_unmap(master, unmap_count * _memory_span_size, master->align_offset, (size_t)master->total_spans * _memory_span_size); + } +} + +//! Move the span (used for small or medium allocations) to the heap thread cache +static void +_rpmalloc_span_release_to_cache(heap_t* heap, span_t* span) { + rpmalloc_assert(heap == span->heap, "Span heap pointer corrupted"); + rpmalloc_assert(span->size_class < SIZE_CLASS_COUNT, "Invalid span size class"); + rpmalloc_assert(span->span_count == 1, "Invalid span count"); +#if ENABLE_ADAPTIVE_THREAD_CACHE || ENABLE_STATISTICS + atomic_decr32(&heap->span_use[0].current); +#endif + _rpmalloc_stat_dec(&heap->size_class_use[span->size_class].spans_current); + if (!heap->finalize) { + _rpmalloc_stat_inc(&heap->span_use[0].spans_to_cache); + _rpmalloc_stat_inc(&heap->size_class_use[span->size_class].spans_to_cache); + if (heap->size_class[span->size_class].cache) + _rpmalloc_heap_cache_insert(heap, heap->size_class[span->size_class].cache); + heap->size_class[span->size_class].cache = span; + } else { + _rpmalloc_span_unmap(span); + } +} + +//! Initialize a (partial) free list up to next system memory page, while reserving the first block +//! as allocated, returning number of blocks in list +static uint32_t +free_list_partial_init(void** list, void** first_block, void* page_start, void* block_start, uint32_t block_count, uint32_t block_size) { + rpmalloc_assert(block_count, "Internal failure"); + *first_block = block_start; + if (block_count > 1) { + void* free_block = pointer_offset(block_start, block_size); + void* block_end = pointer_offset(block_start, (size_t)block_size * block_count); + //If block size is less than half a memory page, bound init to next memory page boundary + if (block_size < (_memory_page_size >> 1)) { + void* page_end = pointer_offset(page_start, _memory_page_size); + if (page_end < block_end) + block_end = page_end; + } + *list = free_block; + block_count = 2; + void* next_block = pointer_offset(free_block, block_size); + while (next_block < block_end) { + *((void**)free_block) = next_block; + free_block = next_block; + ++block_count; + next_block = pointer_offset(next_block, block_size); + } + *((void**)free_block) = 0; + } else { + *list = 0; + } + return block_count; +} + +//! Initialize an unused span (from cache or mapped) to be new active span, putting the initial free list in heap class free list +static void* +_rpmalloc_span_initialize_new(heap_t* heap, heap_size_class_t* heap_size_class, span_t* span, uint32_t class_idx) { + rpmalloc_assert(span->span_count == 1, "Internal failure"); + size_class_t* size_class = _memory_size_class + class_idx; + span->size_class = class_idx; + span->heap = heap; + span->flags &= ~SPAN_FLAG_ALIGNED_BLOCKS; + span->block_size = size_class->block_size; + span->block_count = size_class->block_count; + span->free_list = 0; + span->list_size = 0; + atomic_store_ptr_release(&span->free_list_deferred, 0); + + //Setup free list. Only initialize one system page worth of free blocks in list + void* block; + span->free_list_limit = free_list_partial_init(&heap_size_class->free_list, &block, + span, pointer_offset(span, SPAN_HEADER_SIZE), size_class->block_count, size_class->block_size); + //Link span as partial if there remains blocks to be initialized as free list, or full if fully initialized + if (span->free_list_limit < span->block_count) { + _rpmalloc_span_double_link_list_add(&heap_size_class->partial_span, span); + span->used_count = span->free_list_limit; + } else { +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_add(&heap->full_span[class_idx], span); +#endif + ++heap->full_span_count; + span->used_count = span->block_count; + } + return block; +} + +static void +_rpmalloc_span_extract_free_list_deferred(span_t* span) { + // We need acquire semantics on the CAS operation since we are interested in the list size + // Refer to _rpmalloc_deallocate_defer_small_or_medium for further comments on this dependency + do { + span->free_list = atomic_exchange_ptr_acquire(&span->free_list_deferred, INVALID_POINTER); + } while (span->free_list == INVALID_POINTER); + span->used_count -= span->list_size; + span->list_size = 0; + atomic_store_ptr_release(&span->free_list_deferred, 0); +} + +static int +_rpmalloc_span_is_fully_utilized(span_t* span) { + rpmalloc_assert(span->free_list_limit <= span->block_count, "Span free list corrupted"); + return !span->free_list && (span->free_list_limit >= span->block_count); +} + +static int +_rpmalloc_span_finalize(heap_t* heap, size_t iclass, span_t* span, span_t** list_head) { + void* free_list = heap->size_class[iclass].free_list; + span_t* class_span = (span_t*)((uintptr_t)free_list & _memory_span_mask); + if (span == class_span) { + // Adopt the heap class free list back into the span free list + void* block = span->free_list; + void* last_block = 0; + while (block) { + last_block = block; + block = *((void**)block); + } + uint32_t free_count = 0; + block = free_list; + while (block) { + ++free_count; + block = *((void**)block); + } + if (last_block) { + *((void**)last_block) = free_list; + } else { + span->free_list = free_list; + } + heap->size_class[iclass].free_list = 0; + span->used_count -= free_count; + } + //If this assert triggers you have memory leaks + rpmalloc_assert(span->list_size == span->used_count, "Memory leak detected"); + if (span->list_size == span->used_count) { + _rpmalloc_stat_dec(&heap->span_use[0].current); + _rpmalloc_stat_dec(&heap->size_class_use[iclass].spans_current); + // This function only used for spans in double linked lists + if (list_head) + _rpmalloc_span_double_link_list_remove(list_head, span); + _rpmalloc_span_unmap(span); + return 1; + } + return 0; +} + + +//////////// +/// +/// Global cache +/// +////// + +#if ENABLE_GLOBAL_CACHE + +//! Finalize a global cache +static void +_rpmalloc_global_cache_finalize(global_cache_t* cache) { + while (!atomic_cas32_acquire(&cache->lock, 1, 0)) + _rpmalloc_spin(); + + for (size_t ispan = 0; ispan < cache->count; ++ispan) + _rpmalloc_span_unmap(cache->span[ispan]); + cache->count = 0; + + while (cache->overflow) { + span_t* span = cache->overflow; + cache->overflow = span->next; + _rpmalloc_span_unmap(span); + } + + atomic_store32_release(&cache->lock, 0); +} + +static void +_rpmalloc_global_cache_insert_spans(span_t** span, size_t span_count, size_t count) { + const size_t cache_limit = (span_count == 1) ? + GLOBAL_CACHE_MULTIPLIER * MAX_THREAD_SPAN_CACHE : + GLOBAL_CACHE_MULTIPLIER * (MAX_THREAD_SPAN_LARGE_CACHE - (span_count >> 1)); + + global_cache_t* cache = &_memory_span_cache[span_count - 1]; + + size_t insert_count = count; + while (!atomic_cas32_acquire(&cache->lock, 1, 0)) + _rpmalloc_spin(); + +#if ENABLE_STATISTICS + cache->insert_count += count; +#endif + if ((cache->count + insert_count) > cache_limit) + insert_count = cache_limit - cache->count; + + memcpy(cache->span + cache->count, span, sizeof(span_t*) * insert_count); + cache->count += (uint32_t)insert_count; + +#if ENABLE_UNLIMITED_CACHE + while (insert_count < count) { +#else + // Enable unlimited cache if huge pages, or we will leak since it is unlikely that an entire huge page + // will be unmapped, and we're unable to partially decommit a huge page + while ((_memory_page_size > _memory_span_size) && (insert_count < count)) { +#endif + span_t* current_span = span[insert_count++]; + current_span->next = cache->overflow; + cache->overflow = current_span; + } + atomic_store32_release(&cache->lock, 0); + + span_t* keep = 0; + for (size_t ispan = insert_count; ispan < count; ++ispan) { + span_t* current_span = span[ispan]; + // Keep master spans that has remaining subspans to avoid dangling them + if ((current_span->flags & SPAN_FLAG_MASTER) && + (atomic_load32(¤t_span->remaining_spans) > (int32_t)current_span->span_count)) { + current_span->next = keep; + keep = current_span; + } else { + _rpmalloc_span_unmap(current_span); + } + } + + if (keep) { + while (!atomic_cas32_acquire(&cache->lock, 1, 0)) + _rpmalloc_spin(); + + size_t islot = 0; + while (keep) { + for (; islot < cache->count; ++islot) { + span_t* current_span = cache->span[islot]; + if (!(current_span->flags & SPAN_FLAG_MASTER) || ((current_span->flags & SPAN_FLAG_MASTER) && + (atomic_load32(¤t_span->remaining_spans) <= (int32_t)current_span->span_count))) { + _rpmalloc_span_unmap(current_span); + cache->span[islot] = keep; + break; + } + } + if (islot == cache->count) + break; + keep = keep->next; + } + + if (keep) { + span_t* tail = keep; + while (tail->next) + tail = tail->next; + tail->next = cache->overflow; + cache->overflow = keep; + } + + atomic_store32_release(&cache->lock, 0); + } +} + +static size_t +_rpmalloc_global_cache_extract_spans(span_t** span, size_t span_count, size_t count) { + global_cache_t* cache = &_memory_span_cache[span_count - 1]; + + size_t extract_count = 0; + while (!atomic_cas32_acquire(&cache->lock, 1, 0)) + _rpmalloc_spin(); + +#if ENABLE_STATISTICS + cache->extract_count += count; +#endif + size_t want = count - extract_count; + if (want > cache->count) + want = cache->count; + + memcpy(span + extract_count, cache->span + (cache->count - want), sizeof(span_t*) * want); + cache->count -= (uint32_t)want; + extract_count += want; + + while ((extract_count < count) && cache->overflow) { + span_t* current_span = cache->overflow; + span[extract_count++] = current_span; + cache->overflow = current_span->next; + } + +#if ENABLE_ASSERTS + for (size_t ispan = 0; ispan < extract_count; ++ispan) { + assert(span[ispan]->span_count == span_count); + } +#endif + + atomic_store32_release(&cache->lock, 0); + + return extract_count; +} + +#endif + +//////////// +/// +/// Heap control +/// +////// + +static void _rpmalloc_deallocate_huge(span_t*); + +//! Store the given spans as reserve in the given heap +static void +_rpmalloc_heap_set_reserved_spans(heap_t* heap, span_t* master, span_t* reserve, size_t reserve_span_count) { + heap->span_reserve_master = master; + heap->span_reserve = reserve; + heap->spans_reserved = (uint32_t)reserve_span_count; +} + +//! Adopt the deferred span cache list, optionally extracting the first single span for immediate re-use +static void +_rpmalloc_heap_cache_adopt_deferred(heap_t* heap, span_t** single_span) { + span_t* span = (span_t*)((void*)atomic_exchange_ptr_acquire(&heap->span_free_deferred, 0)); + while (span) { + span_t* next_span = (span_t*)span->free_list; + rpmalloc_assert(span->heap == heap, "Span heap pointer corrupted"); + if (EXPECTED(span->size_class < SIZE_CLASS_COUNT)) { + rpmalloc_assert(heap->full_span_count, "Heap span counter corrupted"); + --heap->full_span_count; + _rpmalloc_stat_dec(&heap->span_use[0].spans_deferred); +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_remove(&heap->full_span[span->size_class], span); +#endif + _rpmalloc_stat_dec(&heap->span_use[0].current); + _rpmalloc_stat_dec(&heap->size_class_use[span->size_class].spans_current); + if (single_span && !*single_span) + *single_span = span; + else + _rpmalloc_heap_cache_insert(heap, span); + } else { + if (span->size_class == SIZE_CLASS_HUGE) { + _rpmalloc_deallocate_huge(span); + } else { + rpmalloc_assert(span->size_class == SIZE_CLASS_LARGE, "Span size class invalid"); + rpmalloc_assert(heap->full_span_count, "Heap span counter corrupted"); + --heap->full_span_count; +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_remove(&heap->large_huge_span, span); +#endif + uint32_t idx = span->span_count - 1; + _rpmalloc_stat_dec(&heap->span_use[idx].spans_deferred); + _rpmalloc_stat_dec(&heap->span_use[idx].current); + if (!idx && single_span && !*single_span) + *single_span = span; + else + _rpmalloc_heap_cache_insert(heap, span); + } + } + span = next_span; + } +} + +static void +_rpmalloc_heap_unmap(heap_t* heap) { + if (!heap->master_heap) { + if ((heap->finalize > 1) && !atomic_load32(&heap->child_count)) { + span_t* span = (span_t*)((uintptr_t)heap & _memory_span_mask); + _rpmalloc_span_unmap(span); + } + } else { + if (atomic_decr32(&heap->master_heap->child_count) == 0) { + _rpmalloc_heap_unmap(heap->master_heap); + } + } +} + +static void +_rpmalloc_heap_global_finalize(heap_t* heap) { + if (heap->finalize++ > 1) { + --heap->finalize; + return; + } + + _rpmalloc_heap_finalize(heap); + +#if ENABLE_THREAD_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + span_cache_t* span_cache; + if (!iclass) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (iclass - 1)); + for (size_t ispan = 0; ispan < span_cache->count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[ispan]); + span_cache->count = 0; + } +#endif + + if (heap->full_span_count) { + --heap->finalize; + return; + } + + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + if (heap->size_class[iclass].free_list || heap->size_class[iclass].partial_span) { + --heap->finalize; + return; + } + } + //Heap is now completely free, unmap and remove from heap list + size_t list_idx = (size_t)heap->id % HEAP_ARRAY_SIZE; + heap_t* list_heap = _memory_heaps[list_idx]; + if (list_heap == heap) { + _memory_heaps[list_idx] = heap->next_heap; + } else { + while (list_heap->next_heap != heap) + list_heap = list_heap->next_heap; + list_heap->next_heap = heap->next_heap; + } + + _rpmalloc_heap_unmap(heap); +} + +//! Insert a single span into thread heap cache, releasing to global cache if overflow +static void +_rpmalloc_heap_cache_insert(heap_t* heap, span_t* span) { + if (UNEXPECTED(heap->finalize != 0)) { + _rpmalloc_span_unmap(span); + _rpmalloc_heap_global_finalize(heap); + return; + } +#if ENABLE_THREAD_CACHE + size_t span_count = span->span_count; + _rpmalloc_stat_inc(&heap->span_use[span_count - 1].spans_to_cache); + if (span_count == 1) { + span_cache_t* span_cache = &heap->span_cache; + span_cache->span[span_cache->count++] = span; + if (span_cache->count == MAX_THREAD_SPAN_CACHE) { + const size_t remain_count = MAX_THREAD_SPAN_CACHE - THREAD_SPAN_CACHE_TRANSFER; +#if ENABLE_GLOBAL_CACHE + _rpmalloc_stat_add64(&heap->thread_to_global, THREAD_SPAN_CACHE_TRANSFER * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[span_count - 1].spans_to_global, THREAD_SPAN_CACHE_TRANSFER); + _rpmalloc_global_cache_insert_spans(span_cache->span + remain_count, span_count, THREAD_SPAN_CACHE_TRANSFER); +#else + for (size_t ispan = 0; ispan < THREAD_SPAN_CACHE_TRANSFER; ++ispan) + _rpmalloc_span_unmap(span_cache->span[remain_count + ispan]); +#endif + span_cache->count = remain_count; + } + } else { + size_t cache_idx = span_count - 2; + span_large_cache_t* span_cache = heap->span_large_cache + cache_idx; + span_cache->span[span_cache->count++] = span; + const size_t cache_limit = (MAX_THREAD_SPAN_LARGE_CACHE - (span_count >> 1)); + if (span_cache->count == cache_limit) { + const size_t transfer_limit = 2 + (cache_limit >> 2); + const size_t transfer_count = (THREAD_SPAN_LARGE_CACHE_TRANSFER <= transfer_limit ? THREAD_SPAN_LARGE_CACHE_TRANSFER : transfer_limit); + const size_t remain_count = cache_limit - transfer_count; +#if ENABLE_GLOBAL_CACHE + _rpmalloc_stat_add64(&heap->thread_to_global, transfer_count * span_count * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[span_count - 1].spans_to_global, transfer_count); + _rpmalloc_global_cache_insert_spans(span_cache->span + remain_count, span_count, transfer_count); +#else + for (size_t ispan = 0; ispan < transfer_count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[remain_count + ispan]); +#endif + span_cache->count = remain_count; + } + } +#else + (void)sizeof(heap); + _rpmalloc_span_unmap(span); +#endif +} + +//! Extract the given number of spans from the different cache levels +static span_t* +_rpmalloc_heap_thread_cache_extract(heap_t* heap, size_t span_count) { + span_t* span = 0; +#if ENABLE_THREAD_CACHE + span_cache_t* span_cache; + if (span_count == 1) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (span_count - 2)); + if (span_cache->count) { + _rpmalloc_stat_inc(&heap->span_use[span_count - 1].spans_from_cache); + return span_cache->span[--span_cache->count]; + } +#endif + return span; +} + +static span_t* +_rpmalloc_heap_thread_cache_deferred_extract(heap_t* heap, size_t span_count) { + span_t* span = 0; + if (span_count == 1) { + _rpmalloc_heap_cache_adopt_deferred(heap, &span); + } else { + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + span = _rpmalloc_heap_thread_cache_extract(heap, span_count); + } + return span; +} + +static span_t* +_rpmalloc_heap_reserved_extract(heap_t* heap, size_t span_count) { + if (heap->spans_reserved >= span_count) + return _rpmalloc_span_map(heap, span_count); + return 0; +} + +//! Extract a span from the global cache +static span_t* +_rpmalloc_heap_global_cache_extract(heap_t* heap, size_t span_count) { +#if ENABLE_GLOBAL_CACHE +#if ENABLE_THREAD_CACHE + span_cache_t* span_cache; + size_t wanted_count; + if (span_count == 1) { + span_cache = &heap->span_cache; + wanted_count = THREAD_SPAN_CACHE_TRANSFER; + } else { + span_cache = (span_cache_t*)(heap->span_large_cache + (span_count - 2)); + wanted_count = THREAD_SPAN_LARGE_CACHE_TRANSFER; + } + span_cache->count = _rpmalloc_global_cache_extract_spans(span_cache->span, span_count, wanted_count); + if (span_cache->count) { + _rpmalloc_stat_add64(&heap->global_to_thread, span_count * span_cache->count * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[span_count - 1].spans_from_global, span_cache->count); + return span_cache->span[--span_cache->count]; + } +#else + span_t* span = 0; + size_t count = _rpmalloc_global_cache_extract_spans(&span, span_count, 1); + if (count) { + _rpmalloc_stat_add64(&heap->global_to_thread, span_count * count * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[span_count - 1].spans_from_global, count); + return span; + } +#endif +#endif + (void)sizeof(heap); + (void)sizeof(span_count); + return 0; +} + +static void +_rpmalloc_inc_span_statistics(heap_t* heap, size_t span_count, uint32_t class_idx) { + (void)sizeof(heap); + (void)sizeof(span_count); + (void)sizeof(class_idx); +#if ENABLE_ADAPTIVE_THREAD_CACHE || ENABLE_STATISTICS + uint32_t idx = (uint32_t)span_count - 1; + uint32_t current_count = (uint32_t)atomic_incr32(&heap->span_use[idx].current); + if (current_count > (uint32_t)atomic_load32(&heap->span_use[idx].high)) + atomic_store32(&heap->span_use[idx].high, (int32_t)current_count); + _rpmalloc_stat_add_peak(&heap->size_class_use[class_idx].spans_current, 1, heap->size_class_use[class_idx].spans_peak); +#endif +} + +//! Get a span from one of the cache levels (thread cache, reserved, global cache) or fallback to mapping more memory +static span_t* +_rpmalloc_heap_extract_new_span(heap_t* heap, heap_size_class_t* heap_size_class, size_t span_count, uint32_t class_idx) { + span_t* span; +#if ENABLE_THREAD_CACHE + if (heap_size_class && heap_size_class->cache) { + span = heap_size_class->cache; + heap_size_class->cache = (heap->span_cache.count ? heap->span_cache.span[--heap->span_cache.count] : 0); + _rpmalloc_inc_span_statistics(heap, span_count, class_idx); + return span; + } +#endif + (void)sizeof(class_idx); + // Allow 50% overhead to increase cache hits + size_t base_span_count = span_count; + size_t limit_span_count = (span_count > 2) ? (span_count + (span_count >> 1)) : span_count; + if (limit_span_count > LARGE_CLASS_COUNT) + limit_span_count = LARGE_CLASS_COUNT; + do { + span = _rpmalloc_heap_thread_cache_extract(heap, span_count); + if (EXPECTED(span != 0)) { + _rpmalloc_stat_inc(&heap->size_class_use[class_idx].spans_from_cache); + _rpmalloc_inc_span_statistics(heap, span_count, class_idx); + return span; + } + span = _rpmalloc_heap_thread_cache_deferred_extract(heap, span_count); + if (EXPECTED(span != 0)) { + _rpmalloc_stat_inc(&heap->size_class_use[class_idx].spans_from_cache); + _rpmalloc_inc_span_statistics(heap, span_count, class_idx); + return span; + } + span = _rpmalloc_heap_reserved_extract(heap, span_count); + if (EXPECTED(span != 0)) { + _rpmalloc_stat_inc(&heap->size_class_use[class_idx].spans_from_reserved); + _rpmalloc_inc_span_statistics(heap, span_count, class_idx); + return span; + } + span = _rpmalloc_heap_global_cache_extract(heap, span_count); + if (EXPECTED(span != 0)) { + _rpmalloc_stat_inc(&heap->size_class_use[class_idx].spans_from_cache); + _rpmalloc_inc_span_statistics(heap, span_count, class_idx); + return span; + } + ++span_count; + } while (span_count <= limit_span_count); + //Final fallback, map in more virtual memory + span = _rpmalloc_span_map(heap, base_span_count); + _rpmalloc_inc_span_statistics(heap, base_span_count, class_idx); + _rpmalloc_stat_inc(&heap->size_class_use[class_idx].spans_map_calls); + return span; +} + +static void +_rpmalloc_heap_initialize(heap_t* heap) { + memset((void*)heap, 0, sizeof(heap_t)); + //Get a new heap ID + heap->id = 1 + atomic_incr32(&_memory_heap_id); + + //Link in heap in heap ID map + size_t list_idx = (size_t)heap->id % HEAP_ARRAY_SIZE; + heap->next_heap = _memory_heaps[list_idx]; + _memory_heaps[list_idx] = heap; +} + +static void +_rpmalloc_heap_orphan(heap_t* heap, int first_class) { + heap->owner_thread = (uintptr_t)-1; +#if RPMALLOC_FIRST_CLASS_HEAPS + heap_t** heap_list = (first_class ? &_memory_first_class_orphan_heaps : &_memory_orphan_heaps); +#else + (void)sizeof(first_class); + heap_t** heap_list = &_memory_orphan_heaps; +#endif + heap->next_orphan = *heap_list; + *heap_list = heap; +} + +//! Allocate a new heap from newly mapped memory pages +static heap_t* +_rpmalloc_heap_allocate_new(void) { + // Map in pages for a 16 heaps. If page size is greater than required size for this, map a page and + // use first part for heaps and remaining part for spans for allocations. Adds a lot of complexity, + // but saves a lot of memory on systems where page size > 64 spans (4MiB) + size_t heap_size = sizeof(heap_t); + size_t aligned_heap_size = 16 * ((heap_size + 15) / 16); + size_t request_heap_count = 16; + size_t heap_span_count = ((aligned_heap_size * request_heap_count) + sizeof(span_t) + _memory_span_size - 1) / _memory_span_size; + size_t block_size = _memory_span_size * heap_span_count; + size_t span_count = heap_span_count; + span_t* span = 0; + // If there are global reserved spans, use these first + if (_memory_global_reserve_count >= heap_span_count) { + span = _rpmalloc_global_get_reserved_spans(heap_span_count); + } + if (!span) { + if (_memory_page_size > block_size) { + span_count = _memory_page_size / _memory_span_size; + block_size = _memory_page_size; + // If using huge pages, make sure to grab enough heaps to avoid reallocating a huge page just to serve new heaps + size_t possible_heap_count = (block_size - sizeof(span_t)) / aligned_heap_size; + if (possible_heap_count >= (request_heap_count * 16)) + request_heap_count *= 16; + else if (possible_heap_count < request_heap_count) + request_heap_count = possible_heap_count; + heap_span_count = ((aligned_heap_size * request_heap_count) + sizeof(span_t) + _memory_span_size - 1) / _memory_span_size; + } + + size_t align_offset = 0; + span = (span_t*)_rpmalloc_mmap(block_size, &align_offset); + if (!span) + return 0; + + // Master span will contain the heaps + _rpmalloc_stat_inc(&_master_spans); + _rpmalloc_span_initialize(span, span_count, heap_span_count, align_offset); + } + + size_t remain_size = _memory_span_size - sizeof(span_t); + heap_t* heap = (heap_t*)pointer_offset(span, sizeof(span_t)); + _rpmalloc_heap_initialize(heap); + + // Put extra heaps as orphans + size_t num_heaps = remain_size / aligned_heap_size; + if (num_heaps < request_heap_count) + num_heaps = request_heap_count; + atomic_store32(&heap->child_count, (int32_t)num_heaps - 1); + heap_t* extra_heap = (heap_t*)pointer_offset(heap, aligned_heap_size); + while (num_heaps > 1) { + _rpmalloc_heap_initialize(extra_heap); + extra_heap->master_heap = heap; + _rpmalloc_heap_orphan(extra_heap, 1); + extra_heap = (heap_t*)pointer_offset(extra_heap, aligned_heap_size); + --num_heaps; + } + + if (span_count > heap_span_count) { + // Cap reserved spans + size_t remain_count = span_count - heap_span_count; + size_t reserve_count = (remain_count > _memory_heap_reserve_count ? _memory_heap_reserve_count : remain_count); + span_t* remain_span = (span_t*)pointer_offset(span, heap_span_count * _memory_span_size); + _rpmalloc_heap_set_reserved_spans(heap, span, remain_span, reserve_count); + + if (remain_count > reserve_count) { + // Set to global reserved spans + remain_span = (span_t*)pointer_offset(remain_span, reserve_count * _memory_span_size); + reserve_count = remain_count - reserve_count; + _rpmalloc_global_set_reserved_spans(span, remain_span, reserve_count); + } + } + + return heap; +} + +static heap_t* +_rpmalloc_heap_extract_orphan(heap_t** heap_list) { + heap_t* heap = *heap_list; + *heap_list = (heap ? heap->next_orphan : 0); + return heap; +} + +//! Allocate a new heap, potentially reusing a previously orphaned heap +static heap_t* +_rpmalloc_heap_allocate(int first_class) { + heap_t* heap = 0; + while (!atomic_cas32_acquire(&_memory_global_lock, 1, 0)) + _rpmalloc_spin(); + if (first_class == 0) + heap = _rpmalloc_heap_extract_orphan(&_memory_orphan_heaps); +#if RPMALLOC_FIRST_CLASS_HEAPS + if (!heap) + heap = _rpmalloc_heap_extract_orphan(&_memory_first_class_orphan_heaps); +#endif + if (!heap) + heap = _rpmalloc_heap_allocate_new(); + atomic_store32_release(&_memory_global_lock, 0); + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + return heap; +} + +extern thread_local bool RpThreadShutdown; + +static void +_rpmalloc_heap_release(void* heapptr, int first_class, int release_cache) { + heap_t* heap = (heap_t*)heapptr; + if (!heap) + return; + RpThreadShutdown = true; + //Release thread cache spans back to global cache + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + if (release_cache || heap->finalize) { +#if ENABLE_THREAD_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + span_cache_t* span_cache; + if (!iclass) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (iclass - 1)); + if (!span_cache->count) + continue; +#if ENABLE_GLOBAL_CACHE + if (heap->finalize) { + for (size_t ispan = 0; ispan < span_cache->count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[ispan]); + } else { + _rpmalloc_stat_add64(&heap->thread_to_global, span_cache->count * (iclass + 1) * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[iclass].spans_to_global, span_cache->count); + _rpmalloc_global_cache_insert_spans(span_cache->span, iclass + 1, span_cache->count); + } +#else + for (size_t ispan = 0; ispan < span_cache->count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[ispan]); +#endif + span_cache->count = 0; + } +#endif + } + + if (get_thread_heap_raw() == heap) + set_thread_heap(0); + +#if ENABLE_STATISTICS + atomic_decr32(&_memory_active_heaps); + rpmalloc_assert(atomic_load32(&_memory_active_heaps) >= 0, "Still active heaps during finalization"); +#endif + + // If we are forcibly terminating with _exit the state of the + // lock atomic is unknown and it's best to just go ahead and exit + if (get_thread_id() != _rpmalloc_main_thread_id) { + while (!atomic_cas32_acquire(&_memory_global_lock, 1, 0)) + _rpmalloc_spin(); + } + _rpmalloc_heap_orphan(heap, first_class); + atomic_store32_release(&_memory_global_lock, 0); +} + +static void +_rpmalloc_heap_release_raw(void* heapptr, int release_cache) { + _rpmalloc_heap_release(heapptr, 0, release_cache); +} + +static void +_rpmalloc_heap_release_raw_fc(void* heapptr) { + _rpmalloc_heap_release_raw(heapptr, 1); +} + +static void +_rpmalloc_heap_finalize(heap_t* heap) { + if (heap->spans_reserved) { + span_t* span = _rpmalloc_span_map(heap, heap->spans_reserved); + _rpmalloc_span_unmap(span); + heap->spans_reserved = 0; + } + + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + if (heap->size_class[iclass].cache) + _rpmalloc_span_unmap(heap->size_class[iclass].cache); + heap->size_class[iclass].cache = 0; + span_t* span = heap->size_class[iclass].partial_span; + while (span) { + span_t* next = span->next; + _rpmalloc_span_finalize(heap, iclass, span, &heap->size_class[iclass].partial_span); + span = next; + } + // If class still has a free list it must be a full span + if (heap->size_class[iclass].free_list) { + span_t* class_span = (span_t*)((uintptr_t)heap->size_class[iclass].free_list & _memory_span_mask); + span_t** list = 0; +#if RPMALLOC_FIRST_CLASS_HEAPS + list = &heap->full_span[iclass]; +#endif + --heap->full_span_count; + if (!_rpmalloc_span_finalize(heap, iclass, class_span, list)) { + if (list) + _rpmalloc_span_double_link_list_remove(list, class_span); + _rpmalloc_span_double_link_list_add(&heap->size_class[iclass].partial_span, class_span); + } + } + } + +#if ENABLE_THREAD_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + span_cache_t* span_cache; + if (!iclass) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (iclass - 1)); + for (size_t ispan = 0; ispan < span_cache->count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[ispan]); + span_cache->count = 0; + } +#endif + rpmalloc_assert(!atomic_load_ptr(&heap->span_free_deferred), "Heaps still active during finalization"); +} + + +//////////// +/// +/// Allocation entry points +/// +////// + +//! Pop first block from a free list +static void* +free_list_pop(void** list) { + void* block = *list; + *list = *((void**)block); + return block; +} + +//! Allocate a small/medium sized memory block from the given heap +static void* +_rpmalloc_allocate_from_heap_fallback(heap_t* heap, heap_size_class_t* heap_size_class, uint32_t class_idx) { + span_t* span = heap_size_class->partial_span; + if (EXPECTED(span != 0)) { + rpmalloc_assert(span->block_count == _memory_size_class[span->size_class].block_count, "Span block count corrupted"); + rpmalloc_assert(!_rpmalloc_span_is_fully_utilized(span), "Internal failure"); + void* block; + if (span->free_list) { + //Span local free list is not empty, swap to size class free list + block = free_list_pop(&span->free_list); + heap_size_class->free_list = span->free_list; + span->free_list = 0; + } else { + //If the span did not fully initialize free list, link up another page worth of blocks + void* block_start = pointer_offset(span, SPAN_HEADER_SIZE + ((size_t)span->free_list_limit * span->block_size)); + span->free_list_limit += free_list_partial_init(&heap_size_class->free_list, &block, + (void*)((uintptr_t)block_start & ~(_memory_page_size - 1)), block_start, + span->block_count - span->free_list_limit, span->block_size); + } + rpmalloc_assert(span->free_list_limit <= span->block_count, "Span block count corrupted"); + span->used_count = span->free_list_limit; + + //Swap in deferred free list if present + if (atomic_load_ptr(&span->free_list_deferred)) + _rpmalloc_span_extract_free_list_deferred(span); + + //If span is still not fully utilized keep it in partial list and early return block + if (!_rpmalloc_span_is_fully_utilized(span)) + return block; + + //The span is fully utilized, unlink from partial list and add to fully utilized list + _rpmalloc_span_double_link_list_pop_head(&heap_size_class->partial_span, span); +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_add(&heap->full_span[class_idx], span); +#endif + ++heap->full_span_count; + return block; + } + + //Find a span in one of the cache levels + span = _rpmalloc_heap_extract_new_span(heap, heap_size_class, 1, class_idx); + if (EXPECTED(span != 0)) { + //Mark span as owned by this heap and set base data, return first block + return _rpmalloc_span_initialize_new(heap, heap_size_class, span, class_idx); + } + + return 0; +} + +//! Allocate a small sized memory block from the given heap +static void* +_rpmalloc_allocate_small(heap_t* heap, size_t size) { + rpmalloc_assert(heap, "No thread heap"); + //Small sizes have unique size classes + const uint32_t class_idx = (uint32_t)((size + (SMALL_GRANULARITY - 1)) >> SMALL_GRANULARITY_SHIFT); + heap_size_class_t* heap_size_class = heap->size_class + class_idx; + _rpmalloc_stat_inc_alloc(heap, class_idx); + if (EXPECTED(heap_size_class->free_list != 0)) + return free_list_pop(&heap_size_class->free_list); + return _rpmalloc_allocate_from_heap_fallback(heap, heap_size_class, class_idx); +} + +//! Allocate a medium sized memory block from the given heap +static void* +_rpmalloc_allocate_medium(heap_t* heap, size_t size) { + rpmalloc_assert(heap, "No thread heap"); + //Calculate the size class index and do a dependent lookup of the final class index (in case of merged classes) + const uint32_t base_idx = (uint32_t)(SMALL_CLASS_COUNT + ((size - (SMALL_SIZE_LIMIT + 1)) >> MEDIUM_GRANULARITY_SHIFT)); + const uint32_t class_idx = _memory_size_class[base_idx].class_idx; + heap_size_class_t* heap_size_class = heap->size_class + class_idx; + _rpmalloc_stat_inc_alloc(heap, class_idx); + if (EXPECTED(heap_size_class->free_list != 0)) + return free_list_pop(&heap_size_class->free_list); + return _rpmalloc_allocate_from_heap_fallback(heap, heap_size_class, class_idx); +} + +//! Allocate a large sized memory block from the given heap +static void* +_rpmalloc_allocate_large(heap_t* heap, size_t size) { + rpmalloc_assert(heap, "No thread heap"); + //Calculate number of needed max sized spans (including header) + //Since this function is never called if size > LARGE_SIZE_LIMIT + //the span_count is guaranteed to be <= LARGE_CLASS_COUNT + size += SPAN_HEADER_SIZE; + size_t span_count = size >> _memory_span_size_shift; + if (size & (_memory_span_size - 1)) + ++span_count; + + //Find a span in one of the cache levels + span_t* span = _rpmalloc_heap_extract_new_span(heap, 0, span_count, SIZE_CLASS_LARGE); + if (!span) + return span; + + //Mark span as owned by this heap and set base data + rpmalloc_assert(span->span_count >= span_count, "Internal failure"); + span->size_class = SIZE_CLASS_LARGE; + span->heap = heap; + +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_add(&heap->large_huge_span, span); +#endif + ++heap->full_span_count; + + return pointer_offset(span, SPAN_HEADER_SIZE); +} + +//! Allocate a huge block by mapping memory pages directly +static void* +_rpmalloc_allocate_huge(heap_t* heap, size_t size) { + rpmalloc_assert(heap, "No thread heap"); + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + size += SPAN_HEADER_SIZE; + size_t num_pages = size >> _memory_page_size_shift; + if (size & (_memory_page_size - 1)) + ++num_pages; + size_t align_offset = 0; + span_t* span = (span_t*)_rpmalloc_mmap(num_pages * _memory_page_size, &align_offset); + if (!span) + return span; + + //Store page count in span_count + span->size_class = SIZE_CLASS_HUGE; + span->span_count = (uint32_t)num_pages; + span->align_offset = (uint32_t)align_offset; + span->heap = heap; + _rpmalloc_stat_add_peak(&_huge_pages_current, num_pages, _huge_pages_peak); + +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_add(&heap->large_huge_span, span); +#endif + ++heap->full_span_count; + + return pointer_offset(span, SPAN_HEADER_SIZE); +} + +//! Allocate a block of the given size +static void* +_rpmalloc_allocate(heap_t* heap, size_t size) { + _rpmalloc_stat_add64(&_allocation_counter, 1); + if (EXPECTED(size <= SMALL_SIZE_LIMIT)) + return _rpmalloc_allocate_small(heap, size); + else if (size <= _memory_medium_size_limit) + return _rpmalloc_allocate_medium(heap, size); + else if (size <= LARGE_SIZE_LIMIT) + return _rpmalloc_allocate_large(heap, size); + return _rpmalloc_allocate_huge(heap, size); +} + +static void* +_rpmalloc_aligned_allocate(heap_t* heap, size_t alignment, size_t size) { + if (alignment <= SMALL_GRANULARITY) + return _rpmalloc_allocate(heap, size); + +#if ENABLE_VALIDATE_ARGS + if ((size + alignment) < size) { + errno = EINVAL; + return 0; + } + if (alignment & (alignment - 1)) { + errno = EINVAL; + return 0; + } +#endif + + if ((alignment <= SPAN_HEADER_SIZE) && (size < _memory_medium_size_limit)) { + // If alignment is less or equal to span header size (which is power of two), + // and size aligned to span header size multiples is less than size + alignment, + // then use natural alignment of blocks to provide alignment + size_t multiple_size = size ? (size + (SPAN_HEADER_SIZE - 1)) & ~(uintptr_t)(SPAN_HEADER_SIZE - 1) : SPAN_HEADER_SIZE; + rpmalloc_assert(!(multiple_size % SPAN_HEADER_SIZE), "Failed alignment calculation"); + if (multiple_size <= (size + alignment)) + return _rpmalloc_allocate(heap, multiple_size); + } + + void* ptr = 0; + size_t align_mask = alignment - 1; + if (alignment <= _memory_page_size) { + ptr = _rpmalloc_allocate(heap, size + alignment); + if ((uintptr_t)ptr & align_mask) { + ptr = (void*)(((uintptr_t)ptr & ~(uintptr_t)align_mask) + alignment); + //Mark as having aligned blocks + span_t* span = (span_t*)((uintptr_t)ptr & _memory_span_mask); + span->flags |= SPAN_FLAG_ALIGNED_BLOCKS; + } + return ptr; + } + + // Fallback to mapping new pages for this request. Since pointers passed + // to rpfree must be able to reach the start of the span by bitmasking of + // the address with the span size, the returned aligned pointer from this + // function must be with a span size of the start of the mapped area. + // In worst case this requires us to loop and map pages until we get a + // suitable memory address. It also means we can never align to span size + // or greater, since the span header will push alignment more than one + // span size away from span start (thus causing pointer mask to give us + // an invalid span start on free) + if (alignment & align_mask) { + errno = EINVAL; + return 0; + } + if (alignment >= _memory_span_size) { + errno = EINVAL; + return 0; + } + + size_t extra_pages = alignment / _memory_page_size; + + // Since each span has a header, we will at least need one extra memory page + size_t num_pages = 1 + (size / _memory_page_size); + if (size & (_memory_page_size - 1)) + ++num_pages; + + if (extra_pages > num_pages) + num_pages = 1 + extra_pages; + + size_t original_pages = num_pages; + size_t limit_pages = (_memory_span_size / _memory_page_size) * 2; + if (limit_pages < (original_pages * 2)) + limit_pages = original_pages * 2; + + size_t mapped_size, align_offset; + span_t* span; + +retry: + align_offset = 0; + mapped_size = num_pages * _memory_page_size; + + span = (span_t*)_rpmalloc_mmap(mapped_size, &align_offset); + if (!span) { + errno = ENOMEM; + return 0; + } + ptr = pointer_offset(span, SPAN_HEADER_SIZE); + + if ((uintptr_t)ptr & align_mask) + ptr = (void*)(((uintptr_t)ptr & ~(uintptr_t)align_mask) + alignment); + + if (((size_t)pointer_diff(ptr, span) >= _memory_span_size) || + (pointer_offset(ptr, size) > pointer_offset(span, mapped_size)) || + (((uintptr_t)ptr & _memory_span_mask) != (uintptr_t)span)) { + _rpmalloc_unmap(span, mapped_size, align_offset, mapped_size); + ++num_pages; + if (num_pages > limit_pages) { + errno = EINVAL; + return 0; + } + goto retry; + } + + //Store page count in span_count + span->size_class = SIZE_CLASS_HUGE; + span->span_count = (uint32_t)num_pages; + span->align_offset = (uint32_t)align_offset; + span->heap = heap; + _rpmalloc_stat_add_peak(&_huge_pages_current, num_pages, _huge_pages_peak); + +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_add(&heap->large_huge_span, span); +#endif + ++heap->full_span_count; + + _rpmalloc_stat_add64(&_allocation_counter, 1); + + return ptr; +} + + +//////////// +/// +/// Deallocation entry points +/// +////// + +//! Deallocate the given small/medium memory block in the current thread local heap +static void +_rpmalloc_deallocate_direct_small_or_medium(span_t* span, void* block) { + heap_t* heap = span->heap; + rpmalloc_assert(heap->owner_thread == get_thread_id() || !heap->owner_thread || heap->finalize, "Internal failure"); + //Add block to free list + if (UNEXPECTED(_rpmalloc_span_is_fully_utilized(span))) { + span->used_count = span->block_count; +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_remove(&heap->full_span[span->size_class], span); +#endif + _rpmalloc_span_double_link_list_add(&heap->size_class[span->size_class].partial_span, span); + --heap->full_span_count; + } + *((void**)block) = span->free_list; + --span->used_count; + span->free_list = block; + if (UNEXPECTED(span->used_count == span->list_size)) { + // If there are no used blocks it is guaranteed that no other external thread is accessing the span + if (span->used_count) { + // Make sure we have synchronized the deferred list and list size by using acquire semantics + // and guarantee that no external thread is accessing span concurrently + void* free_list; + do { + free_list = atomic_exchange_ptr_acquire(&span->free_list_deferred, INVALID_POINTER); + } while (free_list == INVALID_POINTER); + atomic_store_ptr_release(&span->free_list_deferred, free_list); + } + _rpmalloc_span_double_link_list_remove(&heap->size_class[span->size_class].partial_span, span); + _rpmalloc_span_release_to_cache(heap, span); + } +} + +static void +_rpmalloc_deallocate_defer_free_span(heap_t* heap, span_t* span) { + if (span->size_class != SIZE_CLASS_HUGE) + _rpmalloc_stat_inc(&heap->span_use[span->span_count - 1].spans_deferred); + //This list does not need ABA protection, no mutable side state + do { + span->free_list = (void*)atomic_load_ptr(&heap->span_free_deferred); + } while (!atomic_cas_ptr(&heap->span_free_deferred, span, span->free_list)); +} + +//! Put the block in the deferred free list of the owning span +static void +_rpmalloc_deallocate_defer_small_or_medium(span_t* span, void* block) { + // The memory ordering here is a bit tricky, to avoid having to ABA protect + // the deferred free list to avoid desynchronization of list and list size + // we need to have acquire semantics on successful CAS of the pointer to + // guarantee the list_size variable validity + release semantics on pointer store + void* free_list; + do { + free_list = atomic_exchange_ptr_acquire(&span->free_list_deferred, INVALID_POINTER); + } while (free_list == INVALID_POINTER); + *((void**)block) = free_list; + uint32_t free_count = ++span->list_size; + int all_deferred_free = (free_count == span->block_count); + atomic_store_ptr_release(&span->free_list_deferred, block); + if (all_deferred_free) { + // Span was completely freed by this block. Due to the INVALID_POINTER spin lock + // no other thread can reach this state simultaneously on this span. + // Safe to move to owner heap deferred cache + _rpmalloc_deallocate_defer_free_span(span->heap, span); + } +} + +static void +_rpmalloc_deallocate_small_or_medium(span_t* span, void* p) { + _rpmalloc_stat_inc_free(span->heap, span->size_class); + if (span->flags & SPAN_FLAG_ALIGNED_BLOCKS) { + //Realign pointer to block start + void* blocks_start = pointer_offset(span, SPAN_HEADER_SIZE); + uint32_t block_offset = (uint32_t)pointer_diff(p, blocks_start); + p = pointer_offset(p, -(int32_t)(block_offset % span->block_size)); + } + //Check if block belongs to this heap or if deallocation should be deferred +#if RPMALLOC_FIRST_CLASS_HEAPS + int defer = (span->heap->owner_thread && (span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#else + int defer = ((span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#endif + if (!defer) + _rpmalloc_deallocate_direct_small_or_medium(span, p); + else + _rpmalloc_deallocate_defer_small_or_medium(span, p); +} + +//! Deallocate the given large memory block to the current heap +static void +_rpmalloc_deallocate_large(span_t* span) { + rpmalloc_assert(span->size_class == SIZE_CLASS_LARGE, "Bad span size class"); + rpmalloc_assert(!(span->flags & SPAN_FLAG_MASTER) || !(span->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + rpmalloc_assert((span->flags & SPAN_FLAG_MASTER) || (span->flags & SPAN_FLAG_SUBSPAN), "Span flag corrupted"); + //We must always defer (unless finalizing) if from another heap since we cannot touch the list or counters of another heap +#if RPMALLOC_FIRST_CLASS_HEAPS + int defer = (span->heap->owner_thread && (span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#else + int defer = ((span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#endif + if (defer) { + _rpmalloc_deallocate_defer_free_span(span->heap, span); + return; + } + rpmalloc_assert(span->heap->full_span_count, "Heap span counter corrupted"); + --span->heap->full_span_count; +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_remove(&span->heap->large_huge_span, span); +#endif +#if ENABLE_ADAPTIVE_THREAD_CACHE || ENABLE_STATISTICS + //Decrease counter + size_t idx = span->span_count - 1; + atomic_decr32(&span->heap->span_use[idx].current); +#endif + heap_t* heap = span->heap; + rpmalloc_assert(heap, "No thread heap"); +#if ENABLE_THREAD_CACHE + const int set_as_reserved = ((span->span_count > 1) && (heap->span_cache.count == 0) && !heap->finalize && !heap->spans_reserved); +#else + const int set_as_reserved = ((span->span_count > 1) && !heap->finalize && !heap->spans_reserved); +#endif + if (set_as_reserved) { + heap->span_reserve = span; + heap->spans_reserved = span->span_count; + if (span->flags & SPAN_FLAG_MASTER) { + heap->span_reserve_master = span; + } else { //SPAN_FLAG_SUBSPAN + span_t* master = (span_t*)pointer_offset(span, -(intptr_t)((size_t)span->offset_from_master * _memory_span_size)); + heap->span_reserve_master = master; + rpmalloc_assert(master->flags & SPAN_FLAG_MASTER, "Span flag corrupted"); + rpmalloc_assert(atomic_load32(&master->remaining_spans) >= (int32_t)span->span_count, "Master span count corrupted"); + } + _rpmalloc_stat_inc(&heap->span_use[idx].spans_to_reserved); + } else { + //Insert into cache list + _rpmalloc_heap_cache_insert(heap, span); + } +} + +//! Deallocate the given huge span +static void +_rpmalloc_deallocate_huge(span_t* span) { + rpmalloc_assert(span->heap, "No span heap"); +#if RPMALLOC_FIRST_CLASS_HEAPS + int defer = (span->heap->owner_thread && (span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#else + int defer = ((span->heap->owner_thread != get_thread_id()) && !span->heap->finalize); +#endif + if (defer) { + _rpmalloc_deallocate_defer_free_span(span->heap, span); + return; + } + rpmalloc_assert(span->heap->full_span_count, "Heap span counter corrupted"); + --span->heap->full_span_count; +#if RPMALLOC_FIRST_CLASS_HEAPS + _rpmalloc_span_double_link_list_remove(&span->heap->large_huge_span, span); +#endif + + //Oversized allocation, page count is stored in span_count + size_t num_pages = span->span_count; + _rpmalloc_unmap(span, num_pages * _memory_page_size, span->align_offset, num_pages * _memory_page_size); + _rpmalloc_stat_sub(&_huge_pages_current, num_pages); +} + +//! Deallocate the given block +static void +_rpmalloc_deallocate(void* p) { + _rpmalloc_stat_add64(&_deallocation_counter, 1); + //Grab the span (always at start of span, using span alignment) + span_t* span = (span_t*)((uintptr_t)p & _memory_span_mask); + if (UNEXPECTED(!span)) + return; + if (EXPECTED(span->size_class < SIZE_CLASS_COUNT)) + _rpmalloc_deallocate_small_or_medium(span, p); + else if (span->size_class == SIZE_CLASS_LARGE) + _rpmalloc_deallocate_large(span); + else + _rpmalloc_deallocate_huge(span); +} + +//////////// +/// +/// Reallocation entry points +/// +////// + +static size_t +_rpmalloc_usable_size(void* p); + +//! Reallocate the given block to the given size +static void* +_rpmalloc_reallocate(heap_t* heap, void* p, size_t size, size_t oldsize, unsigned int flags) { + if (p) { + //Grab the span using guaranteed span alignment + span_t* span = (span_t*)((uintptr_t)p & _memory_span_mask); + if (EXPECTED(span->size_class < SIZE_CLASS_COUNT)) { + //Small/medium sized block + rpmalloc_assert(span->span_count == 1, "Span counter corrupted"); + void* blocks_start = pointer_offset(span, SPAN_HEADER_SIZE); + uint32_t block_offset = (uint32_t)pointer_diff(p, blocks_start); + uint32_t block_idx = block_offset / span->block_size; + void* block = pointer_offset(blocks_start, (size_t)block_idx * span->block_size); + if (!oldsize) + oldsize = (size_t)((ptrdiff_t)span->block_size - pointer_diff(p, block)); + if ((size_t)span->block_size >= size) { + //Still fits in block, never mind trying to save memory, but preserve data if alignment changed + if ((p != block) && !(flags & RPMALLOC_NO_PRESERVE)) + memmove(block, p, oldsize); + return block; + } + } else if (span->size_class == SIZE_CLASS_LARGE) { + //Large block + size_t total_size = size + SPAN_HEADER_SIZE; + size_t num_spans = total_size >> _memory_span_size_shift; + if (total_size & (_memory_span_mask - 1)) + ++num_spans; + size_t current_spans = span->span_count; + void* block = pointer_offset(span, SPAN_HEADER_SIZE); + if (!oldsize) + oldsize = (current_spans * _memory_span_size) - (size_t)pointer_diff(p, block) - SPAN_HEADER_SIZE; + if ((current_spans >= num_spans) && (total_size >= (oldsize / 2))) { + //Still fits in block, never mind trying to save memory, but preserve data if alignment changed + if ((p != block) && !(flags & RPMALLOC_NO_PRESERVE)) + memmove(block, p, oldsize); + return block; + } + } else { + //Oversized block + size_t total_size = size + SPAN_HEADER_SIZE; + size_t num_pages = total_size >> _memory_page_size_shift; + if (total_size & (_memory_page_size - 1)) + ++num_pages; + //Page count is stored in span_count + size_t current_pages = span->span_count; + void* block = pointer_offset(span, SPAN_HEADER_SIZE); + if (!oldsize) + oldsize = (current_pages * _memory_page_size) - (size_t)pointer_diff(p, block) - SPAN_HEADER_SIZE; + if ((current_pages >= num_pages) && (num_pages >= (current_pages / 2))) { + //Still fits in block, never mind trying to save memory, but preserve data if alignment changed + if ((p != block) && !(flags & RPMALLOC_NO_PRESERVE)) + memmove(block, p, oldsize); + return block; + } + } + } else { + oldsize = 0; + } + + if (!!(flags & RPMALLOC_GROW_OR_FAIL)) + return 0; + + //Size is greater than block size, need to allocate a new block and deallocate the old + //Avoid hysteresis by overallocating if increase is small (below 37%) + size_t lower_bound = oldsize + (oldsize >> 2) + (oldsize >> 3); + size_t new_size = (size > lower_bound) ? size : ((size > oldsize) ? lower_bound : size); + void* block = _rpmalloc_allocate(heap, new_size); + if (p && block) { + if (!(flags & RPMALLOC_NO_PRESERVE)) + memcpy(block, p, oldsize < new_size ? oldsize : new_size); + _rpmalloc_deallocate(p); + } + + return block; +} + +static void* +_rpmalloc_aligned_reallocate(heap_t* heap, void* ptr, size_t alignment, size_t size, size_t oldsize, + unsigned int flags) { + if (alignment <= SMALL_GRANULARITY) + return _rpmalloc_reallocate(heap, ptr, size, oldsize, flags); + + int no_alloc = !!(flags & RPMALLOC_GROW_OR_FAIL); + size_t usablesize = (ptr ? _rpmalloc_usable_size(ptr) : 0); + if ((usablesize >= size) && !((uintptr_t)ptr & (alignment - 1))) { + if (no_alloc || (size >= (usablesize / 2))) + return ptr; + } + // Aligned alloc marks span as having aligned blocks + void* block = (!no_alloc ? _rpmalloc_aligned_allocate(heap, alignment, size) : 0); + if (EXPECTED(block != 0)) { + if (!(flags & RPMALLOC_NO_PRESERVE) && ptr) { + if (!oldsize) + oldsize = usablesize; + memcpy(block, ptr, oldsize < size ? oldsize : size); + } + _rpmalloc_deallocate(ptr); + } + return block; +} + + +//////////// +/// +/// Initialization, finalization and utility +/// +////// + +//! Get the usable size of the given block +static size_t +_rpmalloc_usable_size(void* p) { + //Grab the span using guaranteed span alignment + span_t* span = (span_t*)((uintptr_t)p & _memory_span_mask); + if (span->size_class < SIZE_CLASS_COUNT) { + //Small/medium block + void* blocks_start = pointer_offset(span, SPAN_HEADER_SIZE); + return span->block_size - ((size_t)pointer_diff(p, blocks_start) % span->block_size); + } + if (span->size_class == SIZE_CLASS_LARGE) { + //Large block + size_t current_spans = span->span_count; + return (current_spans * _memory_span_size) - (size_t)pointer_diff(p, span); + } + //Oversized block, page count is stored in span_count + size_t current_pages = span->span_count; + return (current_pages * _memory_page_size) - (size_t)pointer_diff(p, span); +} + +//! Adjust and optimize the size class properties for the given class +static void +_rpmalloc_adjust_size_class(size_t iclass) { + size_t block_size = _memory_size_class[iclass].block_size; + size_t block_count = (_memory_span_size - SPAN_HEADER_SIZE) / block_size; + + _memory_size_class[iclass].block_count = (uint16_t)block_count; + _memory_size_class[iclass].class_idx = (uint16_t)iclass; + + //Check if previous size classes can be merged + if (iclass >= SMALL_CLASS_COUNT) { + size_t prevclass = iclass; + while (prevclass > 0) { + --prevclass; + //A class can be merged if number of pages and number of blocks are equal + if (_memory_size_class[prevclass].block_count == _memory_size_class[iclass].block_count) + memcpy(_memory_size_class + prevclass, _memory_size_class + iclass, sizeof(_memory_size_class[iclass])); + else + break; + } + } +} + +//! Initialize the allocator and setup global data +TRACY_API int +rpmalloc_initialize(void) { + if (_rpmalloc_initialized) { + rpmalloc_thread_initialize(); + return 0; + } + return rpmalloc_initialize_config(0); +} + +int +rpmalloc_initialize_config(const rpmalloc_config_t* config) { + if (_rpmalloc_initialized) { + rpmalloc_thread_initialize(); + return 0; + } + _rpmalloc_initialized = 1; + + if (config) + memcpy(&_memory_config, config, sizeof(rpmalloc_config_t)); + else + memset(&_memory_config, 0, sizeof(rpmalloc_config_t)); + + if (!_memory_config.memory_map || !_memory_config.memory_unmap) { + _memory_config.memory_map = _rpmalloc_mmap_os; + _memory_config.memory_unmap = _rpmalloc_unmap_os; + } + +#if PLATFORM_WINDOWS + SYSTEM_INFO system_info; + memset(&system_info, 0, sizeof(system_info)); + GetSystemInfo(&system_info); + _memory_map_granularity = system_info.dwAllocationGranularity; +#else + _memory_map_granularity = (size_t)sysconf(_SC_PAGESIZE); +#endif + +#if RPMALLOC_CONFIGURABLE + _memory_page_size = _memory_config.page_size; +#else + _memory_page_size = 0; +#endif + _memory_huge_pages = 0; + if (!_memory_page_size) { +#if PLATFORM_WINDOWS + _memory_page_size = system_info.dwPageSize; +#else + _memory_page_size = _memory_map_granularity; + if (_memory_config.enable_huge_pages) { +#if defined(__linux__) + size_t huge_page_size = 0; + FILE* meminfo = fopen("/proc/meminfo", "r"); + if (meminfo) { + char line[128]; + while (!huge_page_size && fgets(line, sizeof(line) - 1, meminfo)) { + line[sizeof(line) - 1] = 0; + if (strstr(line, "Hugepagesize:")) + huge_page_size = (size_t)strtol(line + 13, 0, 10) * 1024; + } + fclose(meminfo); + } + if (huge_page_size) { + _memory_huge_pages = 1; + _memory_page_size = huge_page_size; + _memory_map_granularity = huge_page_size; + } +#elif defined(__FreeBSD__) + int rc; + size_t sz = sizeof(rc); + + if (sysctlbyname("vm.pmap.pg_ps_enabled", &rc, &sz, NULL, 0) == 0 && rc == 1) { + _memory_huge_pages = 1; + _memory_page_size = 2 * 1024 * 1024; + _memory_map_granularity = _memory_page_size; + } +#elif defined(__APPLE__) || defined(__NetBSD__) + _memory_huge_pages = 1; + _memory_page_size = 2 * 1024 * 1024; + _memory_map_granularity = _memory_page_size; +#endif + } +#endif + } else { + if (_memory_config.enable_huge_pages) + _memory_huge_pages = 1; + } + +#if PLATFORM_WINDOWS + if (_memory_config.enable_huge_pages) { + HANDLE token = 0; + size_t large_page_minimum = GetLargePageMinimum(); + if (large_page_minimum) + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); + if (token) { + LUID luid; + if (LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) { + TOKEN_PRIVILEGES token_privileges; + memset(&token_privileges, 0, sizeof(token_privileges)); + token_privileges.PrivilegeCount = 1; + token_privileges.Privileges[0].Luid = luid; + token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (AdjustTokenPrivileges(token, FALSE, &token_privileges, 0, 0, 0)) { + if (GetLastError() == ERROR_SUCCESS) + _memory_huge_pages = 1; + } + } + CloseHandle(token); + } + if (_memory_huge_pages) { + if (large_page_minimum > _memory_page_size) + _memory_page_size = large_page_minimum; + if (large_page_minimum > _memory_map_granularity) + _memory_map_granularity = large_page_minimum; + } + } +#endif + + size_t min_span_size = 256; + size_t max_page_size; +#if UINTPTR_MAX > 0xFFFFFFFF + max_page_size = 4096ULL * 1024ULL * 1024ULL; +#else + max_page_size = 4 * 1024 * 1024; +#endif + if (_memory_page_size < min_span_size) + _memory_page_size = min_span_size; + if (_memory_page_size > max_page_size) + _memory_page_size = max_page_size; + _memory_page_size_shift = 0; + size_t page_size_bit = _memory_page_size; + while (page_size_bit != 1) { + ++_memory_page_size_shift; + page_size_bit >>= 1; + } + _memory_page_size = ((size_t)1 << _memory_page_size_shift); + +#if RPMALLOC_CONFIGURABLE + if (!_memory_config.span_size) { + _memory_span_size = _memory_default_span_size; + _memory_span_size_shift = _memory_default_span_size_shift; + _memory_span_mask = _memory_default_span_mask; + } else { + size_t span_size = _memory_config.span_size; + if (span_size > (256 * 1024)) + span_size = (256 * 1024); + _memory_span_size = 4096; + _memory_span_size_shift = 12; + while (_memory_span_size < span_size) { + _memory_span_size <<= 1; + ++_memory_span_size_shift; + } + _memory_span_mask = ~(uintptr_t)(_memory_span_size - 1); + } +#endif + + _memory_span_map_count = ( _memory_config.span_map_count ? _memory_config.span_map_count : DEFAULT_SPAN_MAP_COUNT); + if ((_memory_span_size * _memory_span_map_count) < _memory_page_size) + _memory_span_map_count = (_memory_page_size / _memory_span_size); + if ((_memory_page_size >= _memory_span_size) && ((_memory_span_map_count * _memory_span_size) % _memory_page_size)) + _memory_span_map_count = (_memory_page_size / _memory_span_size); + _memory_heap_reserve_count = (_memory_span_map_count > DEFAULT_SPAN_MAP_COUNT) ? DEFAULT_SPAN_MAP_COUNT : _memory_span_map_count; + + _memory_config.page_size = _memory_page_size; + _memory_config.span_size = _memory_span_size; + _memory_config.span_map_count = _memory_span_map_count; + _memory_config.enable_huge_pages = _memory_huge_pages; + +#if ((defined(__APPLE__) || defined(__HAIKU__)) && ENABLE_PRELOAD) || defined(__TINYC__) + if (pthread_key_create(&_memory_thread_heap, _rpmalloc_heap_release_raw_fc)) + return -1; +#endif +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) + fls_key = FlsAlloc(&_rpmalloc_thread_destructor); +#endif + + //Setup all small and medium size classes + size_t iclass = 0; + _memory_size_class[iclass].block_size = SMALL_GRANULARITY; + _rpmalloc_adjust_size_class(iclass); + for (iclass = 1; iclass < SMALL_CLASS_COUNT; ++iclass) { + size_t size = iclass * SMALL_GRANULARITY; + _memory_size_class[iclass].block_size = (uint32_t)size; + _rpmalloc_adjust_size_class(iclass); + } + //At least two blocks per span, then fall back to large allocations + _memory_medium_size_limit = (_memory_span_size - SPAN_HEADER_SIZE) >> 1; + if (_memory_medium_size_limit > MEDIUM_SIZE_LIMIT) + _memory_medium_size_limit = MEDIUM_SIZE_LIMIT; + for (iclass = 0; iclass < MEDIUM_CLASS_COUNT; ++iclass) { + size_t size = SMALL_SIZE_LIMIT + ((iclass + 1) * MEDIUM_GRANULARITY); + if (size > _memory_medium_size_limit) + break; + _memory_size_class[SMALL_CLASS_COUNT + iclass].block_size = (uint32_t)size; + _rpmalloc_adjust_size_class(SMALL_CLASS_COUNT + iclass); + } + + _memory_orphan_heaps = 0; +#if RPMALLOC_FIRST_CLASS_HEAPS + _memory_first_class_orphan_heaps = 0; +#endif +#if ENABLE_STATISTICS + atomic_store32(&_memory_active_heaps, 0); + atomic_store32(&_mapped_pages, 0); + _mapped_pages_peak = 0; + atomic_store32(&_master_spans, 0); + atomic_store32(&_mapped_total, 0); + atomic_store32(&_unmapped_total, 0); + atomic_store32(&_mapped_pages_os, 0); + atomic_store32(&_huge_pages_current, 0); + _huge_pages_peak = 0; +#endif + memset(_memory_heaps, 0, sizeof(_memory_heaps)); + atomic_store32_release(&_memory_global_lock, 0); + + //Initialize this thread + rpmalloc_thread_initialize(); + return 0; +} + +//! Finalize the allocator +TRACY_API void +rpmalloc_finalize(void) { + rpmalloc_thread_finalize(1); + //rpmalloc_dump_statistics(stdout); + + if (_memory_global_reserve) { + atomic_add32(&_memory_global_reserve_master->remaining_spans, -(int32_t)_memory_global_reserve_count); + _memory_global_reserve_master = 0; + _memory_global_reserve_count = 0; + _memory_global_reserve = 0; + } + atomic_store32_release(&_memory_global_lock, 0); + + //Free all thread caches and fully free spans + for (size_t list_idx = 0; list_idx < HEAP_ARRAY_SIZE; ++list_idx) { + heap_t* heap = _memory_heaps[list_idx]; + while (heap) { + heap_t* next_heap = heap->next_heap; + heap->finalize = 1; + _rpmalloc_heap_global_finalize(heap); + heap = next_heap; + } + } + +#if ENABLE_GLOBAL_CACHE + //Free global caches + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) + _rpmalloc_global_cache_finalize(&_memory_span_cache[iclass]); +#endif + +#if (defined(__APPLE__) || defined(__HAIKU__)) && ENABLE_PRELOAD + pthread_key_delete(_memory_thread_heap); +#endif +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) + FlsFree(fls_key); + fls_key = 0; +#endif +#if ENABLE_STATISTICS + //If you hit these asserts you probably have memory leaks (perhaps global scope data doing dynamic allocations) or double frees in your code + rpmalloc_assert(atomic_load32(&_mapped_pages) == 0, "Memory leak detected"); + rpmalloc_assert(atomic_load32(&_mapped_pages_os) == 0, "Memory leak detected"); +#endif + + _rpmalloc_initialized = 0; +} + +//! Initialize thread, assign heap +TRACY_API void +rpmalloc_thread_initialize(void) { + if (!get_thread_heap_raw()) { + heap_t* heap = _rpmalloc_heap_allocate(0); + if (heap) { + _rpmalloc_stat_inc(&_memory_active_heaps); + set_thread_heap(heap); +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) + FlsSetValue(fls_key, heap); +#endif + } + } +} + +//! Finalize thread, orphan heap +TRACY_API void +rpmalloc_thread_finalize(int release_caches) { + heap_t* heap = get_thread_heap_raw(); + if (heap) + _rpmalloc_heap_release_raw(heap, release_caches); + set_thread_heap(0); +#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK) + FlsSetValue(fls_key, 0); +#endif +} + +int +rpmalloc_is_thread_initialized(void) { + return (get_thread_heap_raw() != 0) ? 1 : 0; +} + +const rpmalloc_config_t* +rpmalloc_config(void) { + return &_memory_config; +} + +// Extern interface + +TRACY_API RPMALLOC_ALLOCATOR void* +rpmalloc(size_t size) { +#if ENABLE_VALIDATE_ARGS + if (size >= MAX_ALLOC_SIZE) { + errno = EINVAL; + return 0; + } +#endif + heap_t* heap = get_thread_heap(); + return _rpmalloc_allocate(heap, size); +} + +TRACY_API void +rpfree(void* ptr) { + _rpmalloc_deallocate(ptr); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpcalloc(size_t num, size_t size) { + size_t total; +#if ENABLE_VALIDATE_ARGS +#if PLATFORM_WINDOWS + int err = SizeTMult(num, size, &total); + if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#else + int err = __builtin_umull_overflow(num, size, &total); + if (err || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#endif +#else + total = num * size; +#endif + heap_t* heap = get_thread_heap(); + void* block = _rpmalloc_allocate(heap, total); + if (block) + memset(block, 0, total); + return block; +} + +TRACY_API RPMALLOC_ALLOCATOR void* +rprealloc(void* ptr, size_t size) { +#if ENABLE_VALIDATE_ARGS + if (size >= MAX_ALLOC_SIZE) { + errno = EINVAL; + return ptr; + } +#endif + heap_t* heap = get_thread_heap(); + return _rpmalloc_reallocate(heap, ptr, size, 0, 0); +} + +extern RPMALLOC_ALLOCATOR void* +rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, + unsigned int flags) { +#if ENABLE_VALIDATE_ARGS + if ((size + alignment < size) || (alignment > _memory_page_size)) { + errno = EINVAL; + return 0; + } +#endif + heap_t* heap = get_thread_heap(); + return _rpmalloc_aligned_reallocate(heap, ptr, alignment, size, oldsize, flags); +} + +extern RPMALLOC_ALLOCATOR void* +rpaligned_alloc(size_t alignment, size_t size) { + heap_t* heap = get_thread_heap(); + return _rpmalloc_aligned_allocate(heap, alignment, size); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpaligned_calloc(size_t alignment, size_t num, size_t size) { + size_t total; +#if ENABLE_VALIDATE_ARGS +#if PLATFORM_WINDOWS + int err = SizeTMult(num, size, &total); + if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#else + int err = __builtin_umull_overflow(num, size, &total); + if (err || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#endif +#else + total = num * size; +#endif + void* block = rpaligned_alloc(alignment, total); + if (block) + memset(block, 0, total); + return block; +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmemalign(size_t alignment, size_t size) { + return rpaligned_alloc(alignment, size); +} + +extern inline int +rpposix_memalign(void **memptr, size_t alignment, size_t size) { + if (memptr) + *memptr = rpaligned_alloc(alignment, size); + else + return EINVAL; + return *memptr ? 0 : ENOMEM; +} + +extern inline size_t +rpmalloc_usable_size(void* ptr) { + return (ptr ? _rpmalloc_usable_size(ptr) : 0); +} + +extern inline void +rpmalloc_thread_collect(void) { +} + +void +rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats) { + memset(stats, 0, sizeof(rpmalloc_thread_statistics_t)); + heap_t* heap = get_thread_heap_raw(); + if (!heap) + return; + + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + size_class_t* size_class = _memory_size_class + iclass; + span_t* span = heap->size_class[iclass].partial_span; + while (span) { + size_t free_count = span->list_size; + size_t block_count = size_class->block_count; + if (span->free_list_limit < block_count) + block_count = span->free_list_limit; + free_count += (block_count - span->used_count); + stats->sizecache = free_count * size_class->block_size; + span = span->next; + } + } + +#if ENABLE_THREAD_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + span_cache_t* span_cache; + if (!iclass) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (iclass - 1)); + stats->spancache = span_cache->count * (iclass + 1) * _memory_span_size; + } +#endif + + span_t* deferred = (span_t*)atomic_load_ptr(&heap->span_free_deferred); + while (deferred) { + if (deferred->size_class != SIZE_CLASS_HUGE) + stats->spancache = (size_t)deferred->span_count * _memory_span_size; + deferred = (span_t*)deferred->free_list; + } + +#if ENABLE_STATISTICS + stats->thread_to_global = (size_t)atomic_load64(&heap->thread_to_global); + stats->global_to_thread = (size_t)atomic_load64(&heap->global_to_thread); + + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + stats->span_use[iclass].current = (size_t)atomic_load32(&heap->span_use[iclass].current); + stats->span_use[iclass].peak = (size_t)atomic_load32(&heap->span_use[iclass].high); + stats->span_use[iclass].to_global = (size_t)atomic_load32(&heap->span_use[iclass].spans_to_global); + stats->span_use[iclass].from_global = (size_t)atomic_load32(&heap->span_use[iclass].spans_from_global); + stats->span_use[iclass].to_cache = (size_t)atomic_load32(&heap->span_use[iclass].spans_to_cache); + stats->span_use[iclass].from_cache = (size_t)atomic_load32(&heap->span_use[iclass].spans_from_cache); + stats->span_use[iclass].to_reserved = (size_t)atomic_load32(&heap->span_use[iclass].spans_to_reserved); + stats->span_use[iclass].from_reserved = (size_t)atomic_load32(&heap->span_use[iclass].spans_from_reserved); + stats->span_use[iclass].map_calls = (size_t)atomic_load32(&heap->span_use[iclass].spans_map_calls); + } + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + stats->size_use[iclass].alloc_current = (size_t)atomic_load32(&heap->size_class_use[iclass].alloc_current); + stats->size_use[iclass].alloc_peak = (size_t)heap->size_class_use[iclass].alloc_peak; + stats->size_use[iclass].alloc_total = (size_t)atomic_load32(&heap->size_class_use[iclass].alloc_total); + stats->size_use[iclass].free_total = (size_t)atomic_load32(&heap->size_class_use[iclass].free_total); + stats->size_use[iclass].spans_to_cache = (size_t)atomic_load32(&heap->size_class_use[iclass].spans_to_cache); + stats->size_use[iclass].spans_from_cache = (size_t)atomic_load32(&heap->size_class_use[iclass].spans_from_cache); + stats->size_use[iclass].spans_from_reserved = (size_t)atomic_load32(&heap->size_class_use[iclass].spans_from_reserved); + stats->size_use[iclass].map_calls = (size_t)atomic_load32(&heap->size_class_use[iclass].spans_map_calls); + } +#endif +} + +void +rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats) { + memset(stats, 0, sizeof(rpmalloc_global_statistics_t)); +#if ENABLE_STATISTICS + stats->mapped = (size_t)atomic_load32(&_mapped_pages) * _memory_page_size; + stats->mapped_peak = (size_t)_mapped_pages_peak * _memory_page_size; + stats->mapped_total = (size_t)atomic_load32(&_mapped_total) * _memory_page_size; + stats->unmapped_total = (size_t)atomic_load32(&_unmapped_total) * _memory_page_size; + stats->huge_alloc = (size_t)atomic_load32(&_huge_pages_current) * _memory_page_size; + stats->huge_alloc_peak = (size_t)_huge_pages_peak * _memory_page_size; +#endif +#if ENABLE_GLOBAL_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) + stats->cached += _memory_span_cache[iclass].count * (iclass + 1) * _memory_span_size; +#endif +} + +#if ENABLE_STATISTICS + +static void +_memory_heap_dump_statistics(heap_t* heap, void* file) { + fprintf(file, "Heap %d stats:\n", heap->id); + fprintf(file, "Class CurAlloc PeakAlloc TotAlloc TotFree BlkSize BlkCount SpansCur SpansPeak PeakAllocMiB ToCacheMiB FromCacheMiB FromReserveMiB MmapCalls\n"); + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + if (!atomic_load32(&heap->size_class_use[iclass].alloc_total)) + continue; + fprintf(file, "%3u: %10u %10u %10u %10u %8u %8u %8d %9d %13zu %11zu %12zu %14zu %9u\n", (uint32_t)iclass, + atomic_load32(&heap->size_class_use[iclass].alloc_current), + heap->size_class_use[iclass].alloc_peak, + atomic_load32(&heap->size_class_use[iclass].alloc_total), + atomic_load32(&heap->size_class_use[iclass].free_total), + _memory_size_class[iclass].block_size, + _memory_size_class[iclass].block_count, + atomic_load32(&heap->size_class_use[iclass].spans_current), + heap->size_class_use[iclass].spans_peak, + ((size_t)heap->size_class_use[iclass].alloc_peak * (size_t)_memory_size_class[iclass].block_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->size_class_use[iclass].spans_to_cache) * _memory_span_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->size_class_use[iclass].spans_from_cache) * _memory_span_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->size_class_use[iclass].spans_from_reserved) * _memory_span_size) / (size_t)(1024 * 1024), + atomic_load32(&heap->size_class_use[iclass].spans_map_calls)); + } + fprintf(file, "Spans Current Peak Deferred PeakMiB Cached ToCacheMiB FromCacheMiB ToReserveMiB FromReserveMiB ToGlobalMiB FromGlobalMiB MmapCalls\n"); + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + if (!atomic_load32(&heap->span_use[iclass].high) && !atomic_load32(&heap->span_use[iclass].spans_map_calls)) + continue; + fprintf(file, "%4u: %8d %8u %8u %8zu %7u %11zu %12zu %12zu %14zu %11zu %13zu %10u\n", (uint32_t)(iclass + 1), + atomic_load32(&heap->span_use[iclass].current), + atomic_load32(&heap->span_use[iclass].high), + atomic_load32(&heap->span_use[iclass].spans_deferred), + ((size_t)atomic_load32(&heap->span_use[iclass].high) * (size_t)_memory_span_size * (iclass + 1)) / (size_t)(1024 * 1024), +#if ENABLE_THREAD_CACHE + (unsigned int)(!iclass ? heap->span_cache.count : heap->span_large_cache[iclass - 1].count), + ((size_t)atomic_load32(&heap->span_use[iclass].spans_to_cache) * (iclass + 1) * _memory_span_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->span_use[iclass].spans_from_cache) * (iclass + 1) * _memory_span_size) / (size_t)(1024 * 1024), +#else + 0, (size_t)0, (size_t)0, +#endif + ((size_t)atomic_load32(&heap->span_use[iclass].spans_to_reserved) * (iclass + 1) * _memory_span_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->span_use[iclass].spans_from_reserved) * (iclass + 1) * _memory_span_size) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->span_use[iclass].spans_to_global) * (size_t)_memory_span_size * (iclass + 1)) / (size_t)(1024 * 1024), + ((size_t)atomic_load32(&heap->span_use[iclass].spans_from_global) * (size_t)_memory_span_size * (iclass + 1)) / (size_t)(1024 * 1024), + atomic_load32(&heap->span_use[iclass].spans_map_calls)); + } + fprintf(file, "Full spans: %zu\n", heap->full_span_count); + fprintf(file, "ThreadToGlobalMiB GlobalToThreadMiB\n"); + fprintf(file, "%17zu %17zu\n", (size_t)atomic_load64(&heap->thread_to_global) / (size_t)(1024 * 1024), (size_t)atomic_load64(&heap->global_to_thread) / (size_t)(1024 * 1024)); +} + +#endif + +void +rpmalloc_dump_statistics(void* file) { +#if ENABLE_STATISTICS + for (size_t list_idx = 0; list_idx < HEAP_ARRAY_SIZE; ++list_idx) { + heap_t* heap = _memory_heaps[list_idx]; + while (heap) { + int need_dump = 0; + for (size_t iclass = 0; !need_dump && (iclass < SIZE_CLASS_COUNT); ++iclass) { + if (!atomic_load32(&heap->size_class_use[iclass].alloc_total)) { + rpmalloc_assert(!atomic_load32(&heap->size_class_use[iclass].free_total), "Heap statistics counter mismatch"); + rpmalloc_assert(!atomic_load32(&heap->size_class_use[iclass].spans_map_calls), "Heap statistics counter mismatch"); + continue; + } + need_dump = 1; + } + for (size_t iclass = 0; !need_dump && (iclass < LARGE_CLASS_COUNT); ++iclass) { + if (!atomic_load32(&heap->span_use[iclass].high) && !atomic_load32(&heap->span_use[iclass].spans_map_calls)) + continue; + need_dump = 1; + } + if (need_dump) + _memory_heap_dump_statistics(heap, file); + heap = heap->next_heap; + } + } + fprintf(file, "Global stats:\n"); + size_t huge_current = (size_t)atomic_load32(&_huge_pages_current) * _memory_page_size; + size_t huge_peak = (size_t)_huge_pages_peak * _memory_page_size; + fprintf(file, "HugeCurrentMiB HugePeakMiB\n"); + fprintf(file, "%14zu %11zu\n", huge_current / (size_t)(1024 * 1024), huge_peak / (size_t)(1024 * 1024)); + + fprintf(file, "GlobalCacheMiB\n"); + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + global_cache_t* cache = _memory_span_cache + iclass; + size_t global_cache = (size_t)cache->count * iclass * _memory_span_size; + + size_t global_overflow_cache = 0; + span_t* span = cache->overflow; + while (span) { + global_overflow_cache += iclass * _memory_span_size; + span = span->next; + } + if (global_cache || global_overflow_cache || cache->insert_count || cache->extract_count) + fprintf(file, "%4zu: %8zuMiB (%8zuMiB overflow) %14zu insert %14zu extract\n", iclass + 1, global_cache / (size_t)(1024 * 1024), global_overflow_cache / (size_t)(1024 * 1024), cache->insert_count, cache->extract_count); + } + + size_t mapped = (size_t)atomic_load32(&_mapped_pages) * _memory_page_size; + size_t mapped_os = (size_t)atomic_load32(&_mapped_pages_os) * _memory_page_size; + size_t mapped_peak = (size_t)_mapped_pages_peak * _memory_page_size; + size_t mapped_total = (size_t)atomic_load32(&_mapped_total) * _memory_page_size; + size_t unmapped_total = (size_t)atomic_load32(&_unmapped_total) * _memory_page_size; + fprintf(file, "MappedMiB MappedOSMiB MappedPeakMiB MappedTotalMiB UnmappedTotalMiB\n"); + fprintf(file, "%9zu %11zu %13zu %14zu %16zu\n", + mapped / (size_t)(1024 * 1024), + mapped_os / (size_t)(1024 * 1024), + mapped_peak / (size_t)(1024 * 1024), + mapped_total / (size_t)(1024 * 1024), + unmapped_total / (size_t)(1024 * 1024)); + + fprintf(file, "\n"); +#if 0 + int64_t allocated = atomic_load64(&_allocation_counter); + int64_t deallocated = atomic_load64(&_deallocation_counter); + fprintf(file, "Allocation count: %lli\n", allocated); + fprintf(file, "Deallocation count: %lli\n", deallocated); + fprintf(file, "Current allocations: %lli\n", (allocated - deallocated)); + fprintf(file, "Master spans: %d\n", atomic_load32(&_master_spans)); + fprintf(file, "Dangling master spans: %d\n", atomic_load32(&_unmapped_master_spans)); +#endif +#endif + (void)sizeof(file); +} + +#if RPMALLOC_FIRST_CLASS_HEAPS + +extern inline rpmalloc_heap_t* +rpmalloc_heap_acquire(void) { + // Must be a pristine heap from newly mapped memory pages, or else memory blocks + // could already be allocated from the heap which would (wrongly) be released when + // heap is cleared with rpmalloc_heap_free_all(). Also heaps guaranteed to be + // pristine from the dedicated orphan list can be used. + heap_t* heap = _rpmalloc_heap_allocate(1); + heap->owner_thread = 0; + _rpmalloc_stat_inc(&_memory_active_heaps); + return heap; +} + +extern inline void +rpmalloc_heap_release(rpmalloc_heap_t* heap) { + if (heap) + _rpmalloc_heap_release(heap, 1, 1); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) { +#if ENABLE_VALIDATE_ARGS + if (size >= MAX_ALLOC_SIZE) { + errno = EINVAL; + return 0; + } +#endif + return _rpmalloc_allocate(heap, size); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) { +#if ENABLE_VALIDATE_ARGS + if (size >= MAX_ALLOC_SIZE) { + errno = EINVAL; + return 0; + } +#endif + return _rpmalloc_aligned_allocate(heap, alignment, size); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) { + return rpmalloc_heap_aligned_calloc(heap, 0, num, size); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) { + size_t total; +#if ENABLE_VALIDATE_ARGS +#if PLATFORM_WINDOWS + int err = SizeTMult(num, size, &total); + if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#else + int err = __builtin_umull_overflow(num, size, &total); + if (err || (total >= MAX_ALLOC_SIZE)) { + errno = EINVAL; + return 0; + } +#endif +#else + total = num * size; +#endif + void* block = _rpmalloc_aligned_allocate(heap, alignment, total); + if (block) + memset(block, 0, total); + return block; +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) { +#if ENABLE_VALIDATE_ARGS + if (size >= MAX_ALLOC_SIZE) { + errno = EINVAL; + return ptr; + } +#endif + return _rpmalloc_reallocate(heap, ptr, size, 0, flags); +} + +extern inline RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) { +#if ENABLE_VALIDATE_ARGS + if ((size + alignment < size) || (alignment > _memory_page_size)) { + errno = EINVAL; + return 0; + } +#endif + return _rpmalloc_aligned_reallocate(heap, ptr, alignment, size, 0, flags); +} + +extern inline void +rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr) { + (void)sizeof(heap); + _rpmalloc_deallocate(ptr); +} + +extern inline void +rpmalloc_heap_free_all(rpmalloc_heap_t* heap) { + span_t* span; + span_t* next_span; + + _rpmalloc_heap_cache_adopt_deferred(heap, 0); + + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + span = heap->size_class[iclass].partial_span; + while (span) { + next_span = span->next; + _rpmalloc_heap_cache_insert(heap, span); + span = next_span; + } + heap->size_class[iclass].partial_span = 0; + span = heap->full_span[iclass]; + while (span) { + next_span = span->next; + _rpmalloc_heap_cache_insert(heap, span); + span = next_span; + } + } + memset(heap->size_class, 0, sizeof(heap->size_class)); + memset(heap->full_span, 0, sizeof(heap->full_span)); + + span = heap->large_huge_span; + while (span) { + next_span = span->next; + if (UNEXPECTED(span->size_class == SIZE_CLASS_HUGE)) + _rpmalloc_deallocate_huge(span); + else + _rpmalloc_heap_cache_insert(heap, span); + span = next_span; + } + heap->large_huge_span = 0; + heap->full_span_count = 0; + +#if ENABLE_THREAD_CACHE + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + span_cache_t* span_cache; + if (!iclass) + span_cache = &heap->span_cache; + else + span_cache = (span_cache_t*)(heap->span_large_cache + (iclass - 1)); + if (!span_cache->count) + continue; +#if ENABLE_GLOBAL_CACHE + _rpmalloc_stat_add64(&heap->thread_to_global, span_cache->count * (iclass + 1) * _memory_span_size); + _rpmalloc_stat_add(&heap->span_use[iclass].spans_to_global, span_cache->count); + _rpmalloc_global_cache_insert_spans(span_cache->span, iclass + 1, span_cache->count); +#else + for (size_t ispan = 0; ispan < span_cache->count; ++ispan) + _rpmalloc_span_unmap(span_cache->span[ispan]); +#endif + span_cache->count = 0; + } +#endif + +#if ENABLE_STATISTICS + for (size_t iclass = 0; iclass < SIZE_CLASS_COUNT; ++iclass) { + atomic_store32(&heap->size_class_use[iclass].alloc_current, 0); + atomic_store32(&heap->size_class_use[iclass].spans_current, 0); + } + for (size_t iclass = 0; iclass < LARGE_CLASS_COUNT; ++iclass) { + atomic_store32(&heap->span_use[iclass].current, 0); + } +#endif +} + +extern inline void +rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap) { + heap_t* prev_heap = get_thread_heap_raw(); + if (prev_heap != heap) { + set_thread_heap(heap); + if (prev_heap) + rpmalloc_heap_release(prev_heap); + } +} + +#endif + +} + +#endif diff --git a/Externals/tracy/public/client/tracy_rpmalloc.hpp b/Externals/tracy/public/client/tracy_rpmalloc.hpp new file mode 100644 index 00000000000..51216a21b70 --- /dev/null +++ b/Externals/tracy/public/client/tracy_rpmalloc.hpp @@ -0,0 +1,363 @@ +/* rpmalloc.h - Memory allocator - Public Domain - 2016 Mattias Jansson + * + * This library provides a cross-platform lock free thread caching malloc implementation in C11. + * The latest source code is always available at + * + * https://github.com/mjansson/rpmalloc + * + * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. + * + */ + +#pragma once + +#include +#include "../common/TracyApi.h" + +namespace tracy +{ + +#if defined(__clang__) || defined(__GNUC__) +# define RPMALLOC_EXPORT __attribute__((visibility("default"))) +# define RPMALLOC_ALLOCATOR +# if (defined(__clang_major__) && (__clang_major__ < 4)) || (defined(__GNUC__) && defined(ENABLE_PRELOAD) && ENABLE_PRELOAD) +# define RPMALLOC_ATTRIB_MALLOC +# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) +# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size) +# else +# define RPMALLOC_ATTRIB_MALLOC __attribute__((__malloc__)) +# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) __attribute__((alloc_size(size))) +# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size) __attribute__((alloc_size(count, size))) +# endif +# define RPMALLOC_CDECL +#elif defined(_MSC_VER) +# define RPMALLOC_EXPORT +# define RPMALLOC_ALLOCATOR __declspec(allocator) __declspec(restrict) +# define RPMALLOC_ATTRIB_MALLOC +# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) +# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count,size) +# define RPMALLOC_CDECL __cdecl +#else +# define RPMALLOC_EXPORT +# define RPMALLOC_ALLOCATOR +# define RPMALLOC_ATTRIB_MALLOC +# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) +# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count,size) +# define RPMALLOC_CDECL +#endif + +//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes. Will introduce +// a very small overhead due to some size calculations not being compile time constants +#ifndef RPMALLOC_CONFIGURABLE +#define RPMALLOC_CONFIGURABLE 0 +#endif + +//! Define RPMALLOC_FIRST_CLASS_HEAPS to enable heap based API (rpmalloc_heap_* functions). +// Will introduce a very small overhead to track fully allocated spans in heaps +#ifndef RPMALLOC_FIRST_CLASS_HEAPS +#define RPMALLOC_FIRST_CLASS_HEAPS 0 +#endif + +//! Flag to rpaligned_realloc to not preserve content in reallocation +#define RPMALLOC_NO_PRESERVE 1 +//! Flag to rpaligned_realloc to fail and return null pointer if grow cannot be done in-place, +// in which case the original pointer is still valid (just like a call to realloc which failes to allocate +// a new block). +#define RPMALLOC_GROW_OR_FAIL 2 + +typedef struct rpmalloc_global_statistics_t { + //! Current amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1) + size_t mapped; + //! Peak amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1) + size_t mapped_peak; + //! Current amount of memory in global caches for small and medium sizes (<32KiB) + size_t cached; + //! Current amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1) + size_t huge_alloc; + //! Peak amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1) + size_t huge_alloc_peak; + //! Total amount of memory mapped since initialization (only if ENABLE_STATISTICS=1) + size_t mapped_total; + //! Total amount of memory unmapped since initialization (only if ENABLE_STATISTICS=1) + size_t unmapped_total; +} rpmalloc_global_statistics_t; + +typedef struct rpmalloc_thread_statistics_t { + //! Current number of bytes available in thread size class caches for small and medium sizes (<32KiB) + size_t sizecache; + //! Current number of bytes available in thread span caches for small and medium sizes (<32KiB) + size_t spancache; + //! Total number of bytes transitioned from thread cache to global cache (only if ENABLE_STATISTICS=1) + size_t thread_to_global; + //! Total number of bytes transitioned from global cache to thread cache (only if ENABLE_STATISTICS=1) + size_t global_to_thread; + //! Per span count statistics (only if ENABLE_STATISTICS=1) + struct { + //! Currently used number of spans + size_t current; + //! High water mark of spans used + size_t peak; + //! Number of spans transitioned to global cache + size_t to_global; + //! Number of spans transitioned from global cache + size_t from_global; + //! Number of spans transitioned to thread cache + size_t to_cache; + //! Number of spans transitioned from thread cache + size_t from_cache; + //! Number of spans transitioned to reserved state + size_t to_reserved; + //! Number of spans transitioned from reserved state + size_t from_reserved; + //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls) + size_t map_calls; + } span_use[64]; + //! Per size class statistics (only if ENABLE_STATISTICS=1) + struct { + //! Current number of allocations + size_t alloc_current; + //! Peak number of allocations + size_t alloc_peak; + //! Total number of allocations + size_t alloc_total; + //! Total number of frees + size_t free_total; + //! Number of spans transitioned to cache + size_t spans_to_cache; + //! Number of spans transitioned from cache + size_t spans_from_cache; + //! Number of spans transitioned from reserved state + size_t spans_from_reserved; + //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls) + size_t map_calls; + } size_use[128]; +} rpmalloc_thread_statistics_t; + +typedef struct rpmalloc_config_t { + //! Map memory pages for the given number of bytes. The returned address MUST be + // aligned to the rpmalloc span size, which will always be a power of two. + // Optionally the function can store an alignment offset in the offset variable + // in case it performs alignment and the returned pointer is offset from the + // actual start of the memory region due to this alignment. The alignment offset + // will be passed to the memory unmap function. The alignment offset MUST NOT be + // larger than 65535 (storable in an uint16_t), if it is you must use natural + // alignment to shift it into 16 bits. If you set a memory_map function, you + // must also set a memory_unmap function or else the default implementation will + // be used for both. This function must be thread safe, it can be called by + // multiple threads simultaneously. + void* (*memory_map)(size_t size, size_t* offset); + //! Unmap the memory pages starting at address and spanning the given number of bytes. + // If release is set to non-zero, the unmap is for an entire span range as returned by + // a previous call to memory_map and that the entire range should be released. The + // release argument holds the size of the entire span range. If release is set to 0, + // the unmap is a partial decommit of a subset of the mapped memory range. + // If you set a memory_unmap function, you must also set a memory_map function or + // else the default implementation will be used for both. This function must be thread + // safe, it can be called by multiple threads simultaneously. + void (*memory_unmap)(void* address, size_t size, size_t offset, size_t release); + //! Called when an assert fails, if asserts are enabled. Will use the standard assert() + // if this is not set. + void (*error_callback)(const char* message); + //! Called when a call to map memory pages fails (out of memory). If this callback is + // not set or returns zero the library will return a null pointer in the allocation + // call. If this callback returns non-zero the map call will be retried. The argument + // passed is the number of bytes that was requested in the map call. Only used if + // the default system memory map function is used (memory_map callback is not set). + int (*map_fail_callback)(size_t size); + //! Size of memory pages. The page size MUST be a power of two. All memory mapping + // requests to memory_map will be made with size set to a multiple of the page size. + // Used if RPMALLOC_CONFIGURABLE is defined to 1, otherwise system page size is used. + size_t page_size; + //! Size of a span of memory blocks. MUST be a power of two, and in [4096,262144] + // range (unless 0 - set to 0 to use the default span size). Used if RPMALLOC_CONFIGURABLE + // is defined to 1. + size_t span_size; + //! Number of spans to map at each request to map new virtual memory blocks. This can + // be used to minimize the system call overhead at the cost of virtual memory address + // space. The extra mapped pages will not be written until actually used, so physical + // committed memory should not be affected in the default implementation. Will be + // aligned to a multiple of spans that match memory page size in case of huge pages. + size_t span_map_count; + //! Enable use of large/huge pages. If this flag is set to non-zero and page size is + // zero, the allocator will try to enable huge pages and auto detect the configuration. + // If this is set to non-zero and page_size is also non-zero, the allocator will + // assume huge pages have been configured and enabled prior to initializing the + // allocator. + // For Windows, see https://docs.microsoft.com/en-us/windows/desktop/memory/large-page-support + // For Linux, see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt + int enable_huge_pages; + //! Respectively allocated pages and huge allocated pages names for systems + // supporting it to be able to distinguish among anonymous regions. + const char *page_name; + const char *huge_page_name; +} rpmalloc_config_t; + +//! Initialize allocator with default configuration +TRACY_API int +rpmalloc_initialize(void); + +//! Initialize allocator with given configuration +RPMALLOC_EXPORT int +rpmalloc_initialize_config(const rpmalloc_config_t* config); + +//! Get allocator configuration +RPMALLOC_EXPORT const rpmalloc_config_t* +rpmalloc_config(void); + +//! Finalize allocator +TRACY_API void +rpmalloc_finalize(void); + +//! Initialize allocator for calling thread +TRACY_API void +rpmalloc_thread_initialize(void); + +//! Finalize allocator for calling thread +TRACY_API void +rpmalloc_thread_finalize(int release_caches); + +//! Perform deferred deallocations pending for the calling thread heap +RPMALLOC_EXPORT void +rpmalloc_thread_collect(void); + +//! Query if allocator is initialized for calling thread +RPMALLOC_EXPORT int +rpmalloc_is_thread_initialized(void); + +//! Get per-thread statistics +RPMALLOC_EXPORT void +rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats); + +//! Get global statistics +RPMALLOC_EXPORT void +rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats); + +//! Dump all statistics in human readable format to file (should be a FILE*) +RPMALLOC_EXPORT void +rpmalloc_dump_statistics(void* file); + +//! Allocate a memory block of at least the given size +TRACY_API RPMALLOC_ALLOCATOR void* +rpmalloc(size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(1); + +//! Free the given memory block +TRACY_API void +rpfree(void* ptr); + +//! Allocate a memory block of at least the given size and zero initialize it +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpcalloc(size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(1, 2); + +//! Reallocate the given block to at least the given size +TRACY_API RPMALLOC_ALLOCATOR void* +rprealloc(void* ptr, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2); + +//! Reallocate the given block to at least the given size and alignment, +// with optional control flags (see RPMALLOC_NO_PRESERVE). +// Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB) +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3); + +//! Allocate a memory block of at least the given size and alignment. +// Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB) +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2); + +//! Allocate a memory block of at least the given size and alignment, and zero initialize it. +// Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB) +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpaligned_calloc(size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3); + +//! Allocate a memory block of at least the given size and alignment. +// Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB) +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2); + +//! Allocate a memory block of at least the given size and alignment. +// Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB) +RPMALLOC_EXPORT int +rpposix_memalign(void** memptr, size_t alignment, size_t size); + +//! Query the usable size of the given memory block (from given pointer to the end of block) +RPMALLOC_EXPORT size_t +rpmalloc_usable_size(void* ptr); + +#if RPMALLOC_FIRST_CLASS_HEAPS + +//! Heap type +typedef struct heap_t rpmalloc_heap_t; + +//! Acquire a new heap. Will reuse existing released heaps or allocate memory for a new heap +// if none available. Heap API is implemented with the strict assumption that only one single +// thread will call heap functions for a given heap at any given time, no functions are thread safe. +RPMALLOC_EXPORT rpmalloc_heap_t* +rpmalloc_heap_acquire(void); + +//! Release a heap (does NOT free the memory allocated by the heap, use rpmalloc_heap_free_all before destroying the heap). +// Releasing a heap will enable it to be reused by other threads. Safe to pass a null pointer. +RPMALLOC_EXPORT void +rpmalloc_heap_release(rpmalloc_heap_t* heap); + +//! Allocate a memory block of at least the given size using the given heap. +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2); + +//! Allocate a memory block of at least the given size using the given heap. The returned +// block will have the requested alignment. Alignment must be a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB). +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3); + +//! Allocate a memory block of at least the given size using the given heap and zero initialize it. +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3); + +//! Allocate a memory block of at least the given size using the given heap and zero initialize it. The returned +// block will have the requested alignment. Alignment must either be zero, or a power of two and a multiple of sizeof(void*), +// and should ideally be less than memory page size. A caveat of rpmalloc +// internals is that this must also be strictly less than the span size (default 64KiB). +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3); + +//! Reallocate the given block to at least the given size. The memory block MUST be allocated +// by the same heap given to this function. +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3); + +//! Reallocate the given block to at least the given size. The memory block MUST be allocated +// by the same heap given to this function. The returned block will have the requested alignment. +// Alignment must be either zero, or a power of two and a multiple of sizeof(void*), and should ideally be +// less than memory page size. A caveat of rpmalloc internals is that this must also be strictly less than +// the span size (default 64KiB). +RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void* +rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(4); + +//! Free the given memory block from the given heap. The memory block MUST be allocated +// by the same heap given to this function. +RPMALLOC_EXPORT void +rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr); + +//! Free all memory allocated by the heap +RPMALLOC_EXPORT void +rpmalloc_heap_free_all(rpmalloc_heap_t* heap); + +//! Set the given heap as the current heap for the calling thread. A heap MUST only be current heap +// for a single thread, a heap can never be shared between multiple threads. The previous +// current heap for the calling thread is released to be reused by other threads. +RPMALLOC_EXPORT void +rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap); + +#endif + +} diff --git a/Externals/tracy/public/common/TracyAlign.hpp b/Externals/tracy/public/common/TracyAlign.hpp new file mode 100644 index 00000000000..c3531ba0dd1 --- /dev/null +++ b/Externals/tracy/public/common/TracyAlign.hpp @@ -0,0 +1,27 @@ +#ifndef __TRACYALIGN_HPP__ +#define __TRACYALIGN_HPP__ + +#include + +#include "TracyForceInline.hpp" + +namespace tracy +{ + +template +tracy_force_inline T MemRead( const void* ptr ) +{ + T val; + memcpy( &val, ptr, sizeof( T ) ); + return val; +} + +template +tracy_force_inline void MemWrite( void* ptr, T val ) +{ + memcpy( ptr, &val, sizeof( T ) ); +} + +} + +#endif diff --git a/Externals/tracy/public/common/TracyAlloc.hpp b/Externals/tracy/public/common/TracyAlloc.hpp new file mode 100644 index 00000000000..ddb0e5df65b --- /dev/null +++ b/Externals/tracy/public/common/TracyAlloc.hpp @@ -0,0 +1,72 @@ +#ifndef __TRACYALLOC_HPP__ +#define __TRACYALLOC_HPP__ + +#include + +#if defined TRACY_ENABLE && !defined __EMSCRIPTEN__ +# include "TracyApi.h" +# include "TracyForceInline.hpp" +# include "../client/tracy_rpmalloc.hpp" +# define TRACY_USE_RPMALLOC +#endif + +namespace tracy +{ + +#ifdef TRACY_USE_RPMALLOC +TRACY_API void InitRpmalloc(); +#else +static inline void InitRpmalloc() {} +#endif + +static inline void* tracy_malloc( size_t size ) +{ +#ifdef TRACY_USE_RPMALLOC + InitRpmalloc(); + return rpmalloc( size ); +#else + return malloc( size ); +#endif +} + +static inline void* tracy_malloc_fast( size_t size ) +{ +#ifdef TRACY_USE_RPMALLOC + return rpmalloc( size ); +#else + return malloc( size ); +#endif +} + +static inline void tracy_free( void* ptr ) +{ +#ifdef TRACY_USE_RPMALLOC + InitRpmalloc(); + rpfree( ptr ); +#else + free( ptr ); +#endif +} + +static inline void tracy_free_fast( void* ptr ) +{ +#ifdef TRACY_USE_RPMALLOC + rpfree( ptr ); +#else + free( ptr ); +#endif +} + +static inline void* tracy_realloc( void* ptr, size_t size ) +{ +#ifdef TRACY_USE_RPMALLOC + InitRpmalloc(); + return rprealloc( ptr, size ); +#else + return realloc( ptr, size ); +#endif +} + +} + +#endif diff --git a/Externals/tracy/public/common/TracyApi.h b/Externals/tracy/public/common/TracyApi.h new file mode 100644 index 00000000000..f396ce0c68d --- /dev/null +++ b/Externals/tracy/public/common/TracyApi.h @@ -0,0 +1,16 @@ +#ifndef __TRACYAPI_H__ +#define __TRACYAPI_H__ + +#if defined _WIN32 +# if defined TRACY_EXPORTS +# define TRACY_API __declspec(dllexport) +# elif defined TRACY_IMPORTS +# define TRACY_API __declspec(dllimport) +# else +# define TRACY_API +# endif +#else +# define TRACY_API __attribute__((visibility("default"))) +#endif + +#endif // __TRACYAPI_H__ diff --git a/Externals/tracy/public/common/TracyColor.hpp b/Externals/tracy/public/common/TracyColor.hpp new file mode 100644 index 00000000000..4825c0fba20 --- /dev/null +++ b/Externals/tracy/public/common/TracyColor.hpp @@ -0,0 +1,690 @@ +#ifndef __TRACYCOLOR_HPP__ +#define __TRACYCOLOR_HPP__ + +namespace tracy +{ +struct Color +{ +enum ColorType +{ + Snow = 0xfffafa, + GhostWhite = 0xf8f8ff, + WhiteSmoke = 0xf5f5f5, + Gainsboro = 0xdcdcdc, + FloralWhite = 0xfffaf0, + OldLace = 0xfdf5e6, + Linen = 0xfaf0e6, + AntiqueWhite = 0xfaebd7, + PapayaWhip = 0xffefd5, + BlanchedAlmond = 0xffebcd, + Bisque = 0xffe4c4, + PeachPuff = 0xffdab9, + NavajoWhite = 0xffdead, + Moccasin = 0xffe4b5, + Cornsilk = 0xfff8dc, + Ivory = 0xfffff0, + LemonChiffon = 0xfffacd, + Seashell = 0xfff5ee, + Honeydew = 0xf0fff0, + MintCream = 0xf5fffa, + Azure = 0xf0ffff, + AliceBlue = 0xf0f8ff, + Lavender = 0xe6e6fa, + LavenderBlush = 0xfff0f5, + MistyRose = 0xffe4e1, + White = 0xffffff, + Black = 0x000000, + DarkSlateGray = 0x2f4f4f, + DarkSlateGrey = 0x2f4f4f, + DimGray = 0x696969, + DimGrey = 0x696969, + SlateGray = 0x708090, + SlateGrey = 0x708090, + LightSlateGray = 0x778899, + LightSlateGrey = 0x778899, + Gray = 0xbebebe, + Grey = 0xbebebe, + X11Gray = 0xbebebe, + X11Grey = 0xbebebe, + WebGray = 0x808080, + WebGrey = 0x808080, + LightGrey = 0xd3d3d3, + LightGray = 0xd3d3d3, + MidnightBlue = 0x191970, + Navy = 0x000080, + NavyBlue = 0x000080, + CornflowerBlue = 0x6495ed, + DarkSlateBlue = 0x483d8b, + SlateBlue = 0x6a5acd, + MediumSlateBlue = 0x7b68ee, + LightSlateBlue = 0x8470ff, + MediumBlue = 0x0000cd, + RoyalBlue = 0x4169e1, + Blue = 0x0000ff, + DodgerBlue = 0x1e90ff, + DeepSkyBlue = 0x00bfff, + SkyBlue = 0x87ceeb, + LightSkyBlue = 0x87cefa, + SteelBlue = 0x4682b4, + LightSteelBlue = 0xb0c4de, + LightBlue = 0xadd8e6, + PowderBlue = 0xb0e0e6, + PaleTurquoise = 0xafeeee, + DarkTurquoise = 0x00ced1, + MediumTurquoise = 0x48d1cc, + Turquoise = 0x40e0d0, + Cyan = 0x00ffff, + Aqua = 0x00ffff, + LightCyan = 0xe0ffff, + CadetBlue = 0x5f9ea0, + MediumAquamarine = 0x66cdaa, + Aquamarine = 0x7fffd4, + DarkGreen = 0x006400, + DarkOliveGreen = 0x556b2f, + DarkSeaGreen = 0x8fbc8f, + SeaGreen = 0x2e8b57, + MediumSeaGreen = 0x3cb371, + LightSeaGreen = 0x20b2aa, + PaleGreen = 0x98fb98, + SpringGreen = 0x00ff7f, + LawnGreen = 0x7cfc00, + Green = 0x00ff00, + Lime = 0x00ff00, + X11Green = 0x00ff00, + WebGreen = 0x008000, + Chartreuse = 0x7fff00, + MediumSpringGreen = 0x00fa9a, + GreenYellow = 0xadff2f, + LimeGreen = 0x32cd32, + YellowGreen = 0x9acd32, + ForestGreen = 0x228b22, + OliveDrab = 0x6b8e23, + DarkKhaki = 0xbdb76b, + Khaki = 0xf0e68c, + PaleGoldenrod = 0xeee8aa, + LightGoldenrodYellow = 0xfafad2, + LightYellow = 0xffffe0, + Yellow = 0xffff00, + Gold = 0xffd700, + LightGoldenrod = 0xeedd82, + Goldenrod = 0xdaa520, + DarkGoldenrod = 0xb8860b, + RosyBrown = 0xbc8f8f, + IndianRed = 0xcd5c5c, + SaddleBrown = 0x8b4513, + Sienna = 0xa0522d, + Peru = 0xcd853f, + Burlywood = 0xdeb887, + Beige = 0xf5f5dc, + Wheat = 0xf5deb3, + SandyBrown = 0xf4a460, + Tan = 0xd2b48c, + Chocolate = 0xd2691e, + Firebrick = 0xb22222, + Brown = 0xa52a2a, + DarkSalmon = 0xe9967a, + Salmon = 0xfa8072, + LightSalmon = 0xffa07a, + Orange = 0xffa500, + DarkOrange = 0xff8c00, + Coral = 0xff7f50, + LightCoral = 0xf08080, + Tomato = 0xff6347, + OrangeRed = 0xff4500, + Red = 0xff0000, + HotPink = 0xff69b4, + DeepPink = 0xff1493, + Pink = 0xffc0cb, + LightPink = 0xffb6c1, + PaleVioletRed = 0xdb7093, + Maroon = 0xb03060, + X11Maroon = 0xb03060, + WebMaroon = 0x800000, + MediumVioletRed = 0xc71585, + VioletRed = 0xd02090, + Magenta = 0xff00ff, + Fuchsia = 0xff00ff, + Violet = 0xee82ee, + Plum = 0xdda0dd, + Orchid = 0xda70d6, + MediumOrchid = 0xba55d3, + DarkOrchid = 0x9932cc, + DarkViolet = 0x9400d3, + BlueViolet = 0x8a2be2, + Purple = 0xa020f0, + X11Purple = 0xa020f0, + WebPurple = 0x800080, + MediumPurple = 0x9370db, + Thistle = 0xd8bfd8, + Snow1 = 0xfffafa, + Snow2 = 0xeee9e9, + Snow3 = 0xcdc9c9, + Snow4 = 0x8b8989, + Seashell1 = 0xfff5ee, + Seashell2 = 0xeee5de, + Seashell3 = 0xcdc5bf, + Seashell4 = 0x8b8682, + AntiqueWhite1 = 0xffefdb, + AntiqueWhite2 = 0xeedfcc, + AntiqueWhite3 = 0xcdc0b0, + AntiqueWhite4 = 0x8b8378, + Bisque1 = 0xffe4c4, + Bisque2 = 0xeed5b7, + Bisque3 = 0xcdb79e, + Bisque4 = 0x8b7d6b, + PeachPuff1 = 0xffdab9, + PeachPuff2 = 0xeecbad, + PeachPuff3 = 0xcdaf95, + PeachPuff4 = 0x8b7765, + NavajoWhite1 = 0xffdead, + NavajoWhite2 = 0xeecfa1, + NavajoWhite3 = 0xcdb38b, + NavajoWhite4 = 0x8b795e, + LemonChiffon1 = 0xfffacd, + LemonChiffon2 = 0xeee9bf, + LemonChiffon3 = 0xcdc9a5, + LemonChiffon4 = 0x8b8970, + Cornsilk1 = 0xfff8dc, + Cornsilk2 = 0xeee8cd, + Cornsilk3 = 0xcdc8b1, + Cornsilk4 = 0x8b8878, + Ivory1 = 0xfffff0, + Ivory2 = 0xeeeee0, + Ivory3 = 0xcdcdc1, + Ivory4 = 0x8b8b83, + Honeydew1 = 0xf0fff0, + Honeydew2 = 0xe0eee0, + Honeydew3 = 0xc1cdc1, + Honeydew4 = 0x838b83, + LavenderBlush1 = 0xfff0f5, + LavenderBlush2 = 0xeee0e5, + LavenderBlush3 = 0xcdc1c5, + LavenderBlush4 = 0x8b8386, + MistyRose1 = 0xffe4e1, + MistyRose2 = 0xeed5d2, + MistyRose3 = 0xcdb7b5, + MistyRose4 = 0x8b7d7b, + Azure1 = 0xf0ffff, + Azure2 = 0xe0eeee, + Azure3 = 0xc1cdcd, + Azure4 = 0x838b8b, + SlateBlue1 = 0x836fff, + SlateBlue2 = 0x7a67ee, + SlateBlue3 = 0x6959cd, + SlateBlue4 = 0x473c8b, + RoyalBlue1 = 0x4876ff, + RoyalBlue2 = 0x436eee, + RoyalBlue3 = 0x3a5fcd, + RoyalBlue4 = 0x27408b, + Blue1 = 0x0000ff, + Blue2 = 0x0000ee, + Blue3 = 0x0000cd, + Blue4 = 0x00008b, + DodgerBlue1 = 0x1e90ff, + DodgerBlue2 = 0x1c86ee, + DodgerBlue3 = 0x1874cd, + DodgerBlue4 = 0x104e8b, + SteelBlue1 = 0x63b8ff, + SteelBlue2 = 0x5cacee, + SteelBlue3 = 0x4f94cd, + SteelBlue4 = 0x36648b, + DeepSkyBlue1 = 0x00bfff, + DeepSkyBlue2 = 0x00b2ee, + DeepSkyBlue3 = 0x009acd, + DeepSkyBlue4 = 0x00688b, + SkyBlue1 = 0x87ceff, + SkyBlue2 = 0x7ec0ee, + SkyBlue3 = 0x6ca6cd, + SkyBlue4 = 0x4a708b, + LightSkyBlue1 = 0xb0e2ff, + LightSkyBlue2 = 0xa4d3ee, + LightSkyBlue3 = 0x8db6cd, + LightSkyBlue4 = 0x607b8b, + SlateGray1 = 0xc6e2ff, + SlateGray2 = 0xb9d3ee, + SlateGray3 = 0x9fb6cd, + SlateGray4 = 0x6c7b8b, + LightSteelBlue1 = 0xcae1ff, + LightSteelBlue2 = 0xbcd2ee, + LightSteelBlue3 = 0xa2b5cd, + LightSteelBlue4 = 0x6e7b8b, + LightBlue1 = 0xbfefff, + LightBlue2 = 0xb2dfee, + LightBlue3 = 0x9ac0cd, + LightBlue4 = 0x68838b, + LightCyan1 = 0xe0ffff, + LightCyan2 = 0xd1eeee, + LightCyan3 = 0xb4cdcd, + LightCyan4 = 0x7a8b8b, + PaleTurquoise1 = 0xbbffff, + PaleTurquoise2 = 0xaeeeee, + PaleTurquoise3 = 0x96cdcd, + PaleTurquoise4 = 0x668b8b, + CadetBlue1 = 0x98f5ff, + CadetBlue2 = 0x8ee5ee, + CadetBlue3 = 0x7ac5cd, + CadetBlue4 = 0x53868b, + Turquoise1 = 0x00f5ff, + Turquoise2 = 0x00e5ee, + Turquoise3 = 0x00c5cd, + Turquoise4 = 0x00868b, + Cyan1 = 0x00ffff, + Cyan2 = 0x00eeee, + Cyan3 = 0x00cdcd, + Cyan4 = 0x008b8b, + DarkSlateGray1 = 0x97ffff, + DarkSlateGray2 = 0x8deeee, + DarkSlateGray3 = 0x79cdcd, + DarkSlateGray4 = 0x528b8b, + Aquamarine1 = 0x7fffd4, + Aquamarine2 = 0x76eec6, + Aquamarine3 = 0x66cdaa, + Aquamarine4 = 0x458b74, + DarkSeaGreen1 = 0xc1ffc1, + DarkSeaGreen2 = 0xb4eeb4, + DarkSeaGreen3 = 0x9bcd9b, + DarkSeaGreen4 = 0x698b69, + SeaGreen1 = 0x54ff9f, + SeaGreen2 = 0x4eee94, + SeaGreen3 = 0x43cd80, + SeaGreen4 = 0x2e8b57, + PaleGreen1 = 0x9aff9a, + PaleGreen2 = 0x90ee90, + PaleGreen3 = 0x7ccd7c, + PaleGreen4 = 0x548b54, + SpringGreen1 = 0x00ff7f, + SpringGreen2 = 0x00ee76, + SpringGreen3 = 0x00cd66, + SpringGreen4 = 0x008b45, + Green1 = 0x00ff00, + Green2 = 0x00ee00, + Green3 = 0x00cd00, + Green4 = 0x008b00, + Chartreuse1 = 0x7fff00, + Chartreuse2 = 0x76ee00, + Chartreuse3 = 0x66cd00, + Chartreuse4 = 0x458b00, + OliveDrab1 = 0xc0ff3e, + OliveDrab2 = 0xb3ee3a, + OliveDrab3 = 0x9acd32, + OliveDrab4 = 0x698b22, + DarkOliveGreen1 = 0xcaff70, + DarkOliveGreen2 = 0xbcee68, + DarkOliveGreen3 = 0xa2cd5a, + DarkOliveGreen4 = 0x6e8b3d, + Khaki1 = 0xfff68f, + Khaki2 = 0xeee685, + Khaki3 = 0xcdc673, + Khaki4 = 0x8b864e, + LightGoldenrod1 = 0xffec8b, + LightGoldenrod2 = 0xeedc82, + LightGoldenrod3 = 0xcdbe70, + LightGoldenrod4 = 0x8b814c, + LightYellow1 = 0xffffe0, + LightYellow2 = 0xeeeed1, + LightYellow3 = 0xcdcdb4, + LightYellow4 = 0x8b8b7a, + Yellow1 = 0xffff00, + Yellow2 = 0xeeee00, + Yellow3 = 0xcdcd00, + Yellow4 = 0x8b8b00, + Gold1 = 0xffd700, + Gold2 = 0xeec900, + Gold3 = 0xcdad00, + Gold4 = 0x8b7500, + Goldenrod1 = 0xffc125, + Goldenrod2 = 0xeeb422, + Goldenrod3 = 0xcd9b1d, + Goldenrod4 = 0x8b6914, + DarkGoldenrod1 = 0xffb90f, + DarkGoldenrod2 = 0xeead0e, + DarkGoldenrod3 = 0xcd950c, + DarkGoldenrod4 = 0x8b6508, + RosyBrown1 = 0xffc1c1, + RosyBrown2 = 0xeeb4b4, + RosyBrown3 = 0xcd9b9b, + RosyBrown4 = 0x8b6969, + IndianRed1 = 0xff6a6a, + IndianRed2 = 0xee6363, + IndianRed3 = 0xcd5555, + IndianRed4 = 0x8b3a3a, + Sienna1 = 0xff8247, + Sienna2 = 0xee7942, + Sienna3 = 0xcd6839, + Sienna4 = 0x8b4726, + Burlywood1 = 0xffd39b, + Burlywood2 = 0xeec591, + Burlywood3 = 0xcdaa7d, + Burlywood4 = 0x8b7355, + Wheat1 = 0xffe7ba, + Wheat2 = 0xeed8ae, + Wheat3 = 0xcdba96, + Wheat4 = 0x8b7e66, + Tan1 = 0xffa54f, + Tan2 = 0xee9a49, + Tan3 = 0xcd853f, + Tan4 = 0x8b5a2b, + Chocolate1 = 0xff7f24, + Chocolate2 = 0xee7621, + Chocolate3 = 0xcd661d, + Chocolate4 = 0x8b4513, + Firebrick1 = 0xff3030, + Firebrick2 = 0xee2c2c, + Firebrick3 = 0xcd2626, + Firebrick4 = 0x8b1a1a, + Brown1 = 0xff4040, + Brown2 = 0xee3b3b, + Brown3 = 0xcd3333, + Brown4 = 0x8b2323, + Salmon1 = 0xff8c69, + Salmon2 = 0xee8262, + Salmon3 = 0xcd7054, + Salmon4 = 0x8b4c39, + LightSalmon1 = 0xffa07a, + LightSalmon2 = 0xee9572, + LightSalmon3 = 0xcd8162, + LightSalmon4 = 0x8b5742, + Orange1 = 0xffa500, + Orange2 = 0xee9a00, + Orange3 = 0xcd8500, + Orange4 = 0x8b5a00, + DarkOrange1 = 0xff7f00, + DarkOrange2 = 0xee7600, + DarkOrange3 = 0xcd6600, + DarkOrange4 = 0x8b4500, + Coral1 = 0xff7256, + Coral2 = 0xee6a50, + Coral3 = 0xcd5b45, + Coral4 = 0x8b3e2f, + Tomato1 = 0xff6347, + Tomato2 = 0xee5c42, + Tomato3 = 0xcd4f39, + Tomato4 = 0x8b3626, + OrangeRed1 = 0xff4500, + OrangeRed2 = 0xee4000, + OrangeRed3 = 0xcd3700, + OrangeRed4 = 0x8b2500, + Red1 = 0xff0000, + Red2 = 0xee0000, + Red3 = 0xcd0000, + Red4 = 0x8b0000, + DeepPink1 = 0xff1493, + DeepPink2 = 0xee1289, + DeepPink3 = 0xcd1076, + DeepPink4 = 0x8b0a50, + HotPink1 = 0xff6eb4, + HotPink2 = 0xee6aa7, + HotPink3 = 0xcd6090, + HotPink4 = 0x8b3a62, + Pink1 = 0xffb5c5, + Pink2 = 0xeea9b8, + Pink3 = 0xcd919e, + Pink4 = 0x8b636c, + LightPink1 = 0xffaeb9, + LightPink2 = 0xeea2ad, + LightPink3 = 0xcd8c95, + LightPink4 = 0x8b5f65, + PaleVioletRed1 = 0xff82ab, + PaleVioletRed2 = 0xee799f, + PaleVioletRed3 = 0xcd6889, + PaleVioletRed4 = 0x8b475d, + Maroon1 = 0xff34b3, + Maroon2 = 0xee30a7, + Maroon3 = 0xcd2990, + Maroon4 = 0x8b1c62, + VioletRed1 = 0xff3e96, + VioletRed2 = 0xee3a8c, + VioletRed3 = 0xcd3278, + VioletRed4 = 0x8b2252, + Magenta1 = 0xff00ff, + Magenta2 = 0xee00ee, + Magenta3 = 0xcd00cd, + Magenta4 = 0x8b008b, + Orchid1 = 0xff83fa, + Orchid2 = 0xee7ae9, + Orchid3 = 0xcd69c9, + Orchid4 = 0x8b4789, + Plum1 = 0xffbbff, + Plum2 = 0xeeaeee, + Plum3 = 0xcd96cd, + Plum4 = 0x8b668b, + MediumOrchid1 = 0xe066ff, + MediumOrchid2 = 0xd15fee, + MediumOrchid3 = 0xb452cd, + MediumOrchid4 = 0x7a378b, + DarkOrchid1 = 0xbf3eff, + DarkOrchid2 = 0xb23aee, + DarkOrchid3 = 0x9a32cd, + DarkOrchid4 = 0x68228b, + Purple1 = 0x9b30ff, + Purple2 = 0x912cee, + Purple3 = 0x7d26cd, + Purple4 = 0x551a8b, + MediumPurple1 = 0xab82ff, + MediumPurple2 = 0x9f79ee, + MediumPurple3 = 0x8968cd, + MediumPurple4 = 0x5d478b, + Thistle1 = 0xffe1ff, + Thistle2 = 0xeed2ee, + Thistle3 = 0xcdb5cd, + Thistle4 = 0x8b7b8b, + Gray0 = 0x000000, + Grey0 = 0x000000, + Gray1 = 0x030303, + Grey1 = 0x030303, + Gray2 = 0x050505, + Grey2 = 0x050505, + Gray3 = 0x080808, + Grey3 = 0x080808, + Gray4 = 0x0a0a0a, + Grey4 = 0x0a0a0a, + Gray5 = 0x0d0d0d, + Grey5 = 0x0d0d0d, + Gray6 = 0x0f0f0f, + Grey6 = 0x0f0f0f, + Gray7 = 0x121212, + Grey7 = 0x121212, + Gray8 = 0x141414, + Grey8 = 0x141414, + Gray9 = 0x171717, + Grey9 = 0x171717, + Gray10 = 0x1a1a1a, + Grey10 = 0x1a1a1a, + Gray11 = 0x1c1c1c, + Grey11 = 0x1c1c1c, + Gray12 = 0x1f1f1f, + Grey12 = 0x1f1f1f, + Gray13 = 0x212121, + Grey13 = 0x212121, + Gray14 = 0x242424, + Grey14 = 0x242424, + Gray15 = 0x262626, + Grey15 = 0x262626, + Gray16 = 0x292929, + Grey16 = 0x292929, + Gray17 = 0x2b2b2b, + Grey17 = 0x2b2b2b, + Gray18 = 0x2e2e2e, + Grey18 = 0x2e2e2e, + Gray19 = 0x303030, + Grey19 = 0x303030, + Gray20 = 0x333333, + Grey20 = 0x333333, + Gray21 = 0x363636, + Grey21 = 0x363636, + Gray22 = 0x383838, + Grey22 = 0x383838, + Gray23 = 0x3b3b3b, + Grey23 = 0x3b3b3b, + Gray24 = 0x3d3d3d, + Grey24 = 0x3d3d3d, + Gray25 = 0x404040, + Grey25 = 0x404040, + Gray26 = 0x424242, + Grey26 = 0x424242, + Gray27 = 0x454545, + Grey27 = 0x454545, + Gray28 = 0x474747, + Grey28 = 0x474747, + Gray29 = 0x4a4a4a, + Grey29 = 0x4a4a4a, + Gray30 = 0x4d4d4d, + Grey30 = 0x4d4d4d, + Gray31 = 0x4f4f4f, + Grey31 = 0x4f4f4f, + Gray32 = 0x525252, + Grey32 = 0x525252, + Gray33 = 0x545454, + Grey33 = 0x545454, + Gray34 = 0x575757, + Grey34 = 0x575757, + Gray35 = 0x595959, + Grey35 = 0x595959, + Gray36 = 0x5c5c5c, + Grey36 = 0x5c5c5c, + Gray37 = 0x5e5e5e, + Grey37 = 0x5e5e5e, + Gray38 = 0x616161, + Grey38 = 0x616161, + Gray39 = 0x636363, + Grey39 = 0x636363, + Gray40 = 0x666666, + Grey40 = 0x666666, + Gray41 = 0x696969, + Grey41 = 0x696969, + Gray42 = 0x6b6b6b, + Grey42 = 0x6b6b6b, + Gray43 = 0x6e6e6e, + Grey43 = 0x6e6e6e, + Gray44 = 0x707070, + Grey44 = 0x707070, + Gray45 = 0x737373, + Grey45 = 0x737373, + Gray46 = 0x757575, + Grey46 = 0x757575, + Gray47 = 0x787878, + Grey47 = 0x787878, + Gray48 = 0x7a7a7a, + Grey48 = 0x7a7a7a, + Gray49 = 0x7d7d7d, + Grey49 = 0x7d7d7d, + Gray50 = 0x7f7f7f, + Grey50 = 0x7f7f7f, + Gray51 = 0x828282, + Grey51 = 0x828282, + Gray52 = 0x858585, + Grey52 = 0x858585, + Gray53 = 0x878787, + Grey53 = 0x878787, + Gray54 = 0x8a8a8a, + Grey54 = 0x8a8a8a, + Gray55 = 0x8c8c8c, + Grey55 = 0x8c8c8c, + Gray56 = 0x8f8f8f, + Grey56 = 0x8f8f8f, + Gray57 = 0x919191, + Grey57 = 0x919191, + Gray58 = 0x949494, + Grey58 = 0x949494, + Gray59 = 0x969696, + Grey59 = 0x969696, + Gray60 = 0x999999, + Grey60 = 0x999999, + Gray61 = 0x9c9c9c, + Grey61 = 0x9c9c9c, + Gray62 = 0x9e9e9e, + Grey62 = 0x9e9e9e, + Gray63 = 0xa1a1a1, + Grey63 = 0xa1a1a1, + Gray64 = 0xa3a3a3, + Grey64 = 0xa3a3a3, + Gray65 = 0xa6a6a6, + Grey65 = 0xa6a6a6, + Gray66 = 0xa8a8a8, + Grey66 = 0xa8a8a8, + Gray67 = 0xababab, + Grey67 = 0xababab, + Gray68 = 0xadadad, + Grey68 = 0xadadad, + Gray69 = 0xb0b0b0, + Grey69 = 0xb0b0b0, + Gray70 = 0xb3b3b3, + Grey70 = 0xb3b3b3, + Gray71 = 0xb5b5b5, + Grey71 = 0xb5b5b5, + Gray72 = 0xb8b8b8, + Grey72 = 0xb8b8b8, + Gray73 = 0xbababa, + Grey73 = 0xbababa, + Gray74 = 0xbdbdbd, + Grey74 = 0xbdbdbd, + Gray75 = 0xbfbfbf, + Grey75 = 0xbfbfbf, + Gray76 = 0xc2c2c2, + Grey76 = 0xc2c2c2, + Gray77 = 0xc4c4c4, + Grey77 = 0xc4c4c4, + Gray78 = 0xc7c7c7, + Grey78 = 0xc7c7c7, + Gray79 = 0xc9c9c9, + Grey79 = 0xc9c9c9, + Gray80 = 0xcccccc, + Grey80 = 0xcccccc, + Gray81 = 0xcfcfcf, + Grey81 = 0xcfcfcf, + Gray82 = 0xd1d1d1, + Grey82 = 0xd1d1d1, + Gray83 = 0xd4d4d4, + Grey83 = 0xd4d4d4, + Gray84 = 0xd6d6d6, + Grey84 = 0xd6d6d6, + Gray85 = 0xd9d9d9, + Grey85 = 0xd9d9d9, + Gray86 = 0xdbdbdb, + Grey86 = 0xdbdbdb, + Gray87 = 0xdedede, + Grey87 = 0xdedede, + Gray88 = 0xe0e0e0, + Grey88 = 0xe0e0e0, + Gray89 = 0xe3e3e3, + Grey89 = 0xe3e3e3, + Gray90 = 0xe5e5e5, + Grey90 = 0xe5e5e5, + Gray91 = 0xe8e8e8, + Grey91 = 0xe8e8e8, + Gray92 = 0xebebeb, + Grey92 = 0xebebeb, + Gray93 = 0xededed, + Grey93 = 0xededed, + Gray94 = 0xf0f0f0, + Grey94 = 0xf0f0f0, + Gray95 = 0xf2f2f2, + Grey95 = 0xf2f2f2, + Gray96 = 0xf5f5f5, + Grey96 = 0xf5f5f5, + Gray97 = 0xf7f7f7, + Grey97 = 0xf7f7f7, + Gray98 = 0xfafafa, + Grey98 = 0xfafafa, + Gray99 = 0xfcfcfc, + Grey99 = 0xfcfcfc, + Gray100 = 0xffffff, + Grey100 = 0xffffff, + DarkGrey = 0xa9a9a9, + DarkGray = 0xa9a9a9, + DarkBlue = 0x00008b, + DarkCyan = 0x008b8b, + DarkMagenta = 0x8b008b, + DarkRed = 0x8b0000, + LightGreen = 0x90ee90, + Crimson = 0xdc143c, + Indigo = 0x4b0082, + Olive = 0x808000, + RebeccaPurple = 0x663399, + Silver = 0xc0c0c0, + Teal = 0x008080, +}; +}; +} + +#endif diff --git a/Externals/tracy/public/common/TracyForceInline.hpp b/Externals/tracy/public/common/TracyForceInline.hpp new file mode 100644 index 00000000000..b6a5833e586 --- /dev/null +++ b/Externals/tracy/public/common/TracyForceInline.hpp @@ -0,0 +1,20 @@ +#ifndef __TRACYFORCEINLINE_HPP__ +#define __TRACYFORCEINLINE_HPP__ + +#if defined(__GNUC__) +# define tracy_force_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +# define tracy_force_inline __forceinline +#else +# define tracy_force_inline inline +#endif + +#if defined(__GNUC__) +# define tracy_no_inline __attribute__((noinline)) +#elif defined(_MSC_VER) +# define tracy_no_inline __declspec(noinline) +#else +# define tracy_no_inline +#endif + +#endif diff --git a/Externals/tracy/public/common/TracyMutex.hpp b/Externals/tracy/public/common/TracyMutex.hpp new file mode 100644 index 00000000000..57fb01a0c32 --- /dev/null +++ b/Externals/tracy/public/common/TracyMutex.hpp @@ -0,0 +1,24 @@ +#ifndef __TRACYMUTEX_HPP__ +#define __TRACYMUTEX_HPP__ + +#if defined _MSC_VER + +# include + +namespace tracy +{ +using TracyMutex = std::shared_mutex; +} + +#else + +#include + +namespace tracy +{ +using TracyMutex = std::mutex; +} + +#endif + +#endif diff --git a/Externals/tracy/public/common/TracyProtocol.hpp b/Externals/tracy/public/common/TracyProtocol.hpp new file mode 100644 index 00000000000..5eb1639db3f --- /dev/null +++ b/Externals/tracy/public/common/TracyProtocol.hpp @@ -0,0 +1,169 @@ +#ifndef __TRACYPROTOCOL_HPP__ +#define __TRACYPROTOCOL_HPP__ + +#include +#include + +namespace tracy +{ + +constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; } + +enum : uint32_t { ProtocolVersion = 64 }; +enum : uint16_t { BroadcastVersion = 3 }; + +using lz4sz_t = uint32_t; + +enum { TargetFrameSize = 256 * 1024 }; +enum { LZ4Size = Lz4CompressBound( TargetFrameSize ) }; +static_assert( LZ4Size <= (std::numeric_limits::max)(), "LZ4Size greater than lz4sz_t" ); +static_assert( TargetFrameSize * 2 >= 64 * 1024, "Not enough space for LZ4 stream buffer" ); + +enum { HandshakeShibbolethSize = 8 }; +static const char HandshakeShibboleth[HandshakeShibbolethSize] = { 'T', 'r', 'a', 'c', 'y', 'P', 'r', 'f' }; + +enum HandshakeStatus : uint8_t +{ + HandshakePending, + HandshakeWelcome, + HandshakeProtocolMismatch, + HandshakeNotAvailable, + HandshakeDropped +}; + +enum { WelcomeMessageProgramNameSize = 64 }; +enum { WelcomeMessageHostInfoSize = 1024 }; + +#pragma pack( push, 1 ) + +// Must increase left query space after handling! +enum ServerQuery : uint8_t +{ + ServerQueryTerminate, + ServerQueryString, + ServerQueryThreadString, + ServerQuerySourceLocation, + ServerQueryPlotName, + ServerQueryFrameName, + ServerQueryParameter, + ServerQueryFiberName, + // Items above are high priority. Split order must be preserved. See IsQueryPrio(). + ServerQueryDisconnect, + ServerQueryCallstackFrame, + ServerQueryExternalName, + ServerQuerySymbol, + ServerQuerySymbolCode, + ServerQuerySourceCode, + ServerQueryDataTransfer, + ServerQueryDataTransferPart +}; + +struct ServerQueryPacket +{ + ServerQuery type; + uint64_t ptr; + uint32_t extra; +}; + +enum { ServerQueryPacketSize = sizeof( ServerQueryPacket ) }; + + +enum CpuArchitecture : uint8_t +{ + CpuArchUnknown, + CpuArchX86, + CpuArchX64, + CpuArchArm32, + CpuArchArm64 +}; + + +struct WelcomeFlag +{ + enum _t : uint8_t + { + OnDemand = 1 << 0, + IsApple = 1 << 1, + CodeTransfer = 1 << 2, + CombineSamples = 1 << 3, + IdentifySamples = 1 << 4, + }; +}; + +struct WelcomeMessage +{ + double timerMul; + int64_t initBegin; + int64_t initEnd; + uint64_t delay; + uint64_t resolution; + uint64_t epoch; + uint64_t exectime; + uint64_t pid; + int64_t samplingPeriod; + uint8_t flags; + uint8_t cpuArch; + char cpuManufacturer[12]; + uint32_t cpuId; + char programName[WelcomeMessageProgramNameSize]; + char hostInfo[WelcomeMessageHostInfoSize]; +}; + +enum { WelcomeMessageSize = sizeof( WelcomeMessage ) }; + + +struct OnDemandPayloadMessage +{ + uint64_t frames; + uint64_t currentTime; +}; + +enum { OnDemandPayloadMessageSize = sizeof( OnDemandPayloadMessage ) }; + + +struct BroadcastMessage +{ + uint16_t broadcastVersion; + uint16_t listenPort; + uint32_t protocolVersion; + uint64_t pid; + int32_t activeTime; // in seconds + char programName[WelcomeMessageProgramNameSize]; +}; + +struct BroadcastMessage_v2 +{ + uint16_t broadcastVersion; + uint16_t listenPort; + uint32_t protocolVersion; + int32_t activeTime; + char programName[WelcomeMessageProgramNameSize]; +}; + +struct BroadcastMessage_v1 +{ + uint32_t broadcastVersion; + uint32_t protocolVersion; + uint32_t listenPort; + uint32_t activeTime; + char programName[WelcomeMessageProgramNameSize]; +}; + +struct BroadcastMessage_v0 +{ + uint32_t broadcastVersion; + uint32_t protocolVersion; + uint32_t activeTime; + char programName[WelcomeMessageProgramNameSize]; +}; + +enum { BroadcastMessageSize = sizeof( BroadcastMessage ) }; +enum { BroadcastMessageSize_v2 = sizeof( BroadcastMessage_v2 ) }; +enum { BroadcastMessageSize_v1 = sizeof( BroadcastMessage_v1 ) }; +enum { BroadcastMessageSize_v0 = sizeof( BroadcastMessage_v0 ) }; + +#pragma pack( pop ) + +} + +#endif diff --git a/Externals/tracy/public/common/TracyQueue.hpp b/Externals/tracy/public/common/TracyQueue.hpp new file mode 100644 index 00000000000..051d412abfb --- /dev/null +++ b/Externals/tracy/public/common/TracyQueue.hpp @@ -0,0 +1,884 @@ +#ifndef __TRACYQUEUE_HPP__ +#define __TRACYQUEUE_HPP__ + +#include +#include + +namespace tracy +{ + +enum class QueueType : uint8_t +{ + ZoneText, + ZoneName, + Message, + MessageColor, + MessageCallstack, + MessageColorCallstack, + MessageAppInfo, + ZoneBeginAllocSrcLoc, + ZoneBeginAllocSrcLocCallstack, + CallstackSerial, + Callstack, + CallstackAlloc, + CallstackSample, + CallstackSampleContextSwitch, + FrameImage, + ZoneBegin, + ZoneBeginCallstack, + ZoneEnd, + LockWait, + LockObtain, + LockRelease, + LockSharedWait, + LockSharedObtain, + LockSharedRelease, + LockName, + MemAlloc, + MemAllocNamed, + MemFree, + MemFreeNamed, + MemAllocCallstack, + MemAllocCallstackNamed, + MemFreeCallstack, + MemFreeCallstackNamed, + GpuZoneBegin, + GpuZoneBeginCallstack, + GpuZoneBeginAllocSrcLoc, + GpuZoneBeginAllocSrcLocCallstack, + GpuZoneEnd, + GpuZoneBeginSerial, + GpuZoneBeginCallstackSerial, + GpuZoneBeginAllocSrcLocSerial, + GpuZoneBeginAllocSrcLocCallstackSerial, + GpuZoneEndSerial, + PlotDataInt, + PlotDataFloat, + PlotDataDouble, + ContextSwitch, + ThreadWakeup, + GpuTime, + GpuContextName, + CallstackFrameSize, + SymbolInformation, + ExternalNameMetadata, + SymbolCodeMetadata, + SourceCodeMetadata, + FiberEnter, + FiberLeave, + Terminate, + KeepAlive, + ThreadContext, + GpuCalibration, + Crash, + CrashReport, + ZoneValidation, + ZoneColor, + ZoneValue, + FrameMarkMsg, + FrameMarkMsgStart, + FrameMarkMsgEnd, + FrameVsync, + SourceLocation, + LockAnnounce, + LockTerminate, + LockMark, + MessageLiteral, + MessageLiteralColor, + MessageLiteralCallstack, + MessageLiteralColorCallstack, + GpuNewContext, + CallstackFrame, + SysTimeReport, + SysPowerReport, + TidToPid, + HwSampleCpuCycle, + HwSampleInstructionRetired, + HwSampleCacheReference, + HwSampleCacheMiss, + HwSampleBranchRetired, + HwSampleBranchMiss, + PlotConfig, + ParamSetup, + AckServerQueryNoop, + AckSourceCodeNotAvailable, + AckSymbolCodeNotAvailable, + CpuTopology, + SingleStringData, + SecondStringData, + MemNamePayload, + StringData, + ThreadName, + PlotName, + SourceLocationPayload, + CallstackPayload, + CallstackAllocPayload, + FrameName, + FrameImageData, + ExternalName, + ExternalThreadName, + SymbolCode, + SourceCode, + FiberName, + NUM_TYPES +}; + +#pragma pack( push, 1 ) + +struct QueueThreadContext +{ + uint32_t thread; +}; + +struct QueueZoneBeginLean +{ + int64_t time; +}; + +struct QueueZoneBegin : public QueueZoneBeginLean +{ + uint64_t srcloc; // ptr +}; + +struct QueueZoneBeginThread : public QueueZoneBegin +{ + uint32_t thread; +}; + +struct QueueZoneEnd +{ + int64_t time; +}; + +struct QueueZoneEndThread : public QueueZoneEnd +{ + uint32_t thread; +}; + +struct QueueZoneValidation +{ + uint32_t id; +}; + +struct QueueZoneValidationThread : public QueueZoneValidation +{ + uint32_t thread; +}; + +struct QueueZoneColor +{ + uint8_t b; + uint8_t g; + uint8_t r; +}; + +struct QueueZoneColorThread : public QueueZoneColor +{ + uint32_t thread; +}; + +struct QueueZoneValue +{ + uint64_t value; +}; + +struct QueueZoneValueThread : public QueueZoneValue +{ + uint32_t thread; +}; + +struct QueueStringTransfer +{ + uint64_t ptr; +}; + +struct QueueFrameMark +{ + int64_t time; + uint64_t name; // ptr +}; + +struct QueueFrameVsync +{ + int64_t time; + uint32_t id; +}; + +struct QueueFrameImage +{ + uint32_t frame; + uint16_t w; + uint16_t h; + uint8_t flip; +}; + +struct QueueFrameImageFat : public QueueFrameImage +{ + uint64_t image; // ptr +}; + +struct QueueSourceLocation +{ + uint64_t name; + uint64_t function; // ptr + uint64_t file; // ptr + uint32_t line; + uint8_t b; + uint8_t g; + uint8_t r; +}; + +struct QueueZoneTextFat +{ + uint64_t text; // ptr + uint16_t size; +}; + +struct QueueZoneTextFatThread : public QueueZoneTextFat +{ + uint32_t thread; +}; + +enum class LockType : uint8_t +{ + Lockable, + SharedLockable +}; + +struct QueueLockAnnounce +{ + uint32_t id; + int64_t time; + uint64_t lckloc; // ptr + LockType type; +}; + +struct QueueFiberEnter +{ + int64_t time; + uint64_t fiber; // ptr + uint32_t thread; +}; + +struct QueueFiberLeave +{ + int64_t time; + uint32_t thread; +}; + +struct QueueLockTerminate +{ + uint32_t id; + int64_t time; +}; + +struct QueueLockWait +{ + uint32_t thread; + uint32_t id; + int64_t time; +}; + +struct QueueLockObtain +{ + uint32_t thread; + uint32_t id; + int64_t time; +}; + +struct QueueLockRelease +{ + uint32_t id; + int64_t time; +}; + +struct QueueLockReleaseShared : public QueueLockRelease +{ + uint32_t thread; +}; + +struct QueueLockMark +{ + uint32_t thread; + uint32_t id; + uint64_t srcloc; // ptr +}; + +struct QueueLockName +{ + uint32_t id; +}; + +struct QueueLockNameFat : public QueueLockName +{ + uint64_t name; // ptr + uint16_t size; +}; + +struct QueuePlotDataBase +{ + uint64_t name; // ptr + int64_t time; +}; + +struct QueuePlotDataInt : public QueuePlotDataBase +{ + int64_t val; +}; + +struct QueuePlotDataFloat : public QueuePlotDataBase +{ + float val; +}; + +struct QueuePlotDataDouble : public QueuePlotDataBase +{ + double val; +}; + +struct QueueMessage +{ + int64_t time; +}; + +struct QueueMessageColor : public QueueMessage +{ + uint8_t b; + uint8_t g; + uint8_t r; +}; + +struct QueueMessageLiteral : public QueueMessage +{ + uint64_t text; // ptr +}; + +struct QueueMessageLiteralThread : public QueueMessageLiteral +{ + uint32_t thread; +}; + +struct QueueMessageColorLiteral : public QueueMessageColor +{ + uint64_t text; // ptr +}; + +struct QueueMessageColorLiteralThread : public QueueMessageColorLiteral +{ + uint32_t thread; +}; + +struct QueueMessageFat : public QueueMessage +{ + uint64_t text; // ptr + uint16_t size; +}; + +struct QueueMessageFatThread : public QueueMessageFat +{ + uint32_t thread; +}; + +struct QueueMessageColorFat : public QueueMessageColor +{ + uint64_t text; // ptr + uint16_t size; +}; + +struct QueueMessageColorFatThread : public QueueMessageColorFat +{ + uint32_t thread; +}; + +// Don't change order, only add new entries at the end, this is also used on trace dumps! +enum class GpuContextType : uint8_t +{ + Invalid, + OpenGl, + Vulkan, + OpenCL, + Direct3D12, + Direct3D11 +}; + +enum GpuContextFlags : uint8_t +{ + GpuContextCalibration = 1 << 0 +}; + +struct QueueGpuNewContext +{ + int64_t cpuTime; + int64_t gpuTime; + uint32_t thread; + float period; + uint8_t context; + GpuContextFlags flags; + GpuContextType type; +}; + +struct QueueGpuZoneBeginLean +{ + int64_t cpuTime; + uint32_t thread; + uint16_t queryId; + uint8_t context; +}; + +struct QueueGpuZoneBegin : public QueueGpuZoneBeginLean +{ + uint64_t srcloc; +}; + +struct QueueGpuZoneEnd +{ + int64_t cpuTime; + uint32_t thread; + uint16_t queryId; + uint8_t context; +}; + +struct QueueGpuTime +{ + int64_t gpuTime; + uint16_t queryId; + uint8_t context; +}; + +struct QueueGpuCalibration +{ + int64_t gpuTime; + int64_t cpuTime; + int64_t cpuDelta; + uint8_t context; +}; + +struct QueueGpuContextName +{ + uint8_t context; +}; + +struct QueueGpuContextNameFat : public QueueGpuContextName +{ + uint64_t ptr; + uint16_t size; +}; + +struct QueueMemNamePayload +{ + uint64_t name; +}; + +struct QueueMemAlloc +{ + int64_t time; + uint32_t thread; + uint64_t ptr; + char size[6]; +}; + +struct QueueMemFree +{ + int64_t time; + uint32_t thread; + uint64_t ptr; +}; + +struct QueueCallstackFat +{ + uint64_t ptr; +}; + +struct QueueCallstackFatThread : public QueueCallstackFat +{ + uint32_t thread; +}; + +struct QueueCallstackAllocFat +{ + uint64_t ptr; + uint64_t nativePtr; +}; + +struct QueueCallstackAllocFatThread : public QueueCallstackAllocFat +{ + uint32_t thread; +}; + +struct QueueCallstackSample +{ + int64_t time; + uint32_t thread; +}; + +struct QueueCallstackSampleFat : public QueueCallstackSample +{ + uint64_t ptr; +}; + +struct QueueCallstackFrameSize +{ + uint64_t ptr; + uint8_t size; +}; + +struct QueueCallstackFrameSizeFat : public QueueCallstackFrameSize +{ + uint64_t data; + uint64_t imageName; +}; + +struct QueueCallstackFrame +{ + uint32_t line; + uint64_t symAddr; + uint32_t symLen; +}; + +struct QueueSymbolInformation +{ + uint32_t line; + uint64_t symAddr; +}; + +struct QueueSymbolInformationFat : public QueueSymbolInformation +{ + uint64_t fileString; + uint8_t needFree; +}; + +struct QueueCrashReport +{ + int64_t time; + uint64_t text; // ptr +}; + +struct QueueCrashReportThread +{ + uint32_t thread; +}; + +struct QueueSysTime +{ + int64_t time; + float sysTime; +}; + +struct QueueSysPower +{ + int64_t time; + uint64_t delta; + uint64_t name; // ptr +}; + +struct QueueContextSwitch +{ + int64_t time; + uint32_t oldThread; + uint32_t newThread; + uint8_t cpu; + uint8_t reason; + uint8_t state; +}; + +struct QueueThreadWakeup +{ + int64_t time; + uint32_t thread; +}; + +struct QueueTidToPid +{ + uint64_t tid; + uint64_t pid; +}; + +struct QueueHwSample +{ + uint64_t ip; + int64_t time; +}; + +enum class PlotFormatType : uint8_t +{ + Number, + Memory, + Percentage +}; + +struct QueuePlotConfig +{ + uint64_t name; // ptr + uint8_t type; + uint8_t step; + uint8_t fill; + uint32_t color; +}; + +struct QueueParamSetup +{ + uint32_t idx; + uint64_t name; // ptr + uint8_t isBool; + int32_t val; +}; + +struct QueueSourceCodeNotAvailable +{ + uint32_t id; +}; + +struct QueueCpuTopology +{ + uint32_t package; + uint32_t core; + uint32_t thread; +}; + +struct QueueExternalNameMetadata +{ + uint64_t thread; + uint64_t name; + uint64_t threadName; +}; + +struct QueueSymbolCodeMetadata +{ + uint64_t symbol; + uint64_t ptr; + uint32_t size; +}; + +struct QueueSourceCodeMetadata +{ + uint64_t ptr; + uint32_t size; + uint32_t id; +}; + +struct QueueHeader +{ + union + { + QueueType type; + uint8_t idx; + }; +}; + +struct QueueItem +{ + QueueHeader hdr; + union + { + QueueThreadContext threadCtx; + QueueZoneBegin zoneBegin; + QueueZoneBeginLean zoneBeginLean; + QueueZoneBeginThread zoneBeginThread; + QueueZoneEnd zoneEnd; + QueueZoneEndThread zoneEndThread; + QueueZoneValidation zoneValidation; + QueueZoneValidationThread zoneValidationThread; + QueueZoneColor zoneColor; + QueueZoneColorThread zoneColorThread; + QueueZoneValue zoneValue; + QueueZoneValueThread zoneValueThread; + QueueStringTransfer stringTransfer; + QueueFrameMark frameMark; + QueueFrameVsync frameVsync; + QueueFrameImage frameImage; + QueueFrameImageFat frameImageFat; + QueueSourceLocation srcloc; + QueueZoneTextFat zoneTextFat; + QueueZoneTextFatThread zoneTextFatThread; + QueueLockAnnounce lockAnnounce; + QueueLockTerminate lockTerminate; + QueueLockWait lockWait; + QueueLockObtain lockObtain; + QueueLockRelease lockRelease; + QueueLockReleaseShared lockReleaseShared; + QueueLockMark lockMark; + QueueLockName lockName; + QueueLockNameFat lockNameFat; + QueuePlotDataInt plotDataInt; + QueuePlotDataFloat plotDataFloat; + QueuePlotDataDouble plotDataDouble; + QueueMessage message; + QueueMessageColor messageColor; + QueueMessageLiteral messageLiteral; + QueueMessageLiteralThread messageLiteralThread; + QueueMessageColorLiteral messageColorLiteral; + QueueMessageColorLiteralThread messageColorLiteralThread; + QueueMessageFat messageFat; + QueueMessageFatThread messageFatThread; + QueueMessageColorFat messageColorFat; + QueueMessageColorFatThread messageColorFatThread; + QueueGpuNewContext gpuNewContext; + QueueGpuZoneBegin gpuZoneBegin; + QueueGpuZoneBeginLean gpuZoneBeginLean; + QueueGpuZoneEnd gpuZoneEnd; + QueueGpuTime gpuTime; + QueueGpuCalibration gpuCalibration; + QueueGpuContextName gpuContextName; + QueueGpuContextNameFat gpuContextNameFat; + QueueMemAlloc memAlloc; + QueueMemFree memFree; + QueueMemNamePayload memName; + QueueCallstackFat callstackFat; + QueueCallstackFatThread callstackFatThread; + QueueCallstackAllocFat callstackAllocFat; + QueueCallstackAllocFatThread callstackAllocFatThread; + QueueCallstackSample callstackSample; + QueueCallstackSampleFat callstackSampleFat; + QueueCallstackFrameSize callstackFrameSize; + QueueCallstackFrameSizeFat callstackFrameSizeFat; + QueueCallstackFrame callstackFrame; + QueueSymbolInformation symbolInformation; + QueueSymbolInformationFat symbolInformationFat; + QueueCrashReport crashReport; + QueueCrashReportThread crashReportThread; + QueueSysTime sysTime; + QueueSysPower sysPower; + QueueContextSwitch contextSwitch; + QueueThreadWakeup threadWakeup; + QueueTidToPid tidToPid; + QueueHwSample hwSample; + QueuePlotConfig plotConfig; + QueueParamSetup paramSetup; + QueueCpuTopology cpuTopology; + QueueExternalNameMetadata externalNameMetadata; + QueueSymbolCodeMetadata symbolCodeMetadata; + QueueSourceCodeMetadata sourceCodeMetadata; + QueueSourceCodeNotAvailable sourceCodeNotAvailable; + QueueFiberEnter fiberEnter; + QueueFiberLeave fiberLeave; + }; +}; +#pragma pack( pop ) + + +enum { QueueItemSize = sizeof( QueueItem ) }; + +static constexpr size_t QueueDataSize[] = { + sizeof( QueueHeader ), // zone text + sizeof( QueueHeader ), // zone name + sizeof( QueueHeader ) + sizeof( QueueMessage ), + sizeof( QueueHeader ) + sizeof( QueueMessageColor ), + sizeof( QueueHeader ) + sizeof( QueueMessage ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMessageColor ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMessage ), // app info + sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location + sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location, callstack + sizeof( QueueHeader ), // callstack memory + sizeof( QueueHeader ), // callstack + sizeof( QueueHeader ), // callstack alloc + sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), + sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), // context switch + sizeof( QueueHeader ) + sizeof( QueueFrameImage ), + sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), + sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack + sizeof( QueueHeader ) + sizeof( QueueZoneEnd ), + sizeof( QueueHeader ) + sizeof( QueueLockWait ), + sizeof( QueueHeader ) + sizeof( QueueLockObtain ), + sizeof( QueueHeader ) + sizeof( QueueLockRelease ), + sizeof( QueueHeader ) + sizeof( QueueLockWait ), // shared + sizeof( QueueHeader ) + sizeof( QueueLockObtain ), // shared + sizeof( QueueHeader ) + sizeof( QueueLockReleaseShared ), + sizeof( QueueHeader ) + sizeof( QueueLockName ), + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named + sizeof( QueueHeader ) + sizeof( QueueMemFree ), + sizeof( QueueHeader ) + sizeof( QueueMemFree ), // named + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named + sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location, callstack + sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial, callstack + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location + sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location, callstack + sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), // serial + sizeof( QueueHeader ) + sizeof( QueuePlotDataInt ), + sizeof( QueueHeader ) + sizeof( QueuePlotDataFloat ), + sizeof( QueueHeader ) + sizeof( QueuePlotDataDouble ), + sizeof( QueueHeader ) + sizeof( QueueContextSwitch ), + sizeof( QueueHeader ) + sizeof( QueueThreadWakeup ), + sizeof( QueueHeader ) + sizeof( QueueGpuTime ), + sizeof( QueueHeader ) + sizeof( QueueGpuContextName ), + sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ), + sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ), + sizeof( QueueHeader ), // ExternalNameMetadata - not for wire transfer + sizeof( QueueHeader ), // SymbolCodeMetadata - not for wire transfer + sizeof( QueueHeader ), // SourceCodeMetadata - not for wire transfer + sizeof( QueueHeader ) + sizeof( QueueFiberEnter ), + sizeof( QueueHeader ) + sizeof( QueueFiberLeave ), + // above items must be first + sizeof( QueueHeader ), // terminate + sizeof( QueueHeader ), // keep alive + sizeof( QueueHeader ) + sizeof( QueueThreadContext ), + sizeof( QueueHeader ) + sizeof( QueueGpuCalibration ), + sizeof( QueueHeader ), // crash + sizeof( QueueHeader ) + sizeof( QueueCrashReport ), + sizeof( QueueHeader ) + sizeof( QueueZoneValidation ), + sizeof( QueueHeader ) + sizeof( QueueZoneColor ), + sizeof( QueueHeader ) + sizeof( QueueZoneValue ), + sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // continuous frames + sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // start + sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // end + sizeof( QueueHeader ) + sizeof( QueueFrameVsync ), + sizeof( QueueHeader ) + sizeof( QueueSourceLocation ), + sizeof( QueueHeader ) + sizeof( QueueLockAnnounce ), + sizeof( QueueHeader ) + sizeof( QueueLockTerminate ), + sizeof( QueueHeader ) + sizeof( QueueLockMark ), + sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ), + sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ), + sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ), // callstack + sizeof( QueueHeader ) + sizeof( QueueGpuNewContext ), + sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ), + sizeof( QueueHeader ) + sizeof( QueueSysTime ), + sizeof( QueueHeader ) + sizeof( QueueSysPower ), + sizeof( QueueHeader ) + sizeof( QueueTidToPid ), + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cpu cycle + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // instruction retired + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache reference + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache miss + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch retired + sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch miss + sizeof( QueueHeader ) + sizeof( QueuePlotConfig ), + sizeof( QueueHeader ) + sizeof( QueueParamSetup ), + sizeof( QueueHeader ), // server query acknowledgement + sizeof( QueueHeader ) + sizeof( QueueSourceCodeNotAvailable ), + sizeof( QueueHeader ), // symbol code not available + sizeof( QueueHeader ) + sizeof( QueueCpuTopology ), + sizeof( QueueHeader ), // single string data + sizeof( QueueHeader ), // second string data + sizeof( QueueHeader ) + sizeof( QueueMemNamePayload ), + // keep all QueueStringTransfer below + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // plot name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // symbol code + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // source code + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // fiber name +}; + +static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" ); +static_assert( sizeof( QueueDataSize ) / sizeof( size_t ) == (uint8_t)QueueType::NUM_TYPES, "QueueDataSize mismatch" ); +static_assert( sizeof( void* ) <= sizeof( uint64_t ), "Pointer size > 8 bytes" ); +static_assert( sizeof( void* ) == sizeof( uintptr_t ), "Pointer size != uintptr_t" ); + +} + +#endif diff --git a/Externals/tracy/public/common/TracySocket.cpp b/Externals/tracy/public/common/TracySocket.cpp new file mode 100644 index 00000000000..259678989e8 --- /dev/null +++ b/Externals/tracy/public/common/TracySocket.cpp @@ -0,0 +1,749 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "TracyAlloc.hpp" +#include "TracySocket.hpp" +#include "TracySystem.hpp" + +#ifdef _WIN32 +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# include +# ifdef _MSC_VER +# pragma warning(disable:4244) +# pragma warning(disable:4267) +# endif +# define poll WSAPoll +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#ifndef MSG_NOSIGNAL +# define MSG_NOSIGNAL 0 +#endif + +namespace tracy +{ + +#ifdef _WIN32 +typedef SOCKET socket_t; +#else +typedef int socket_t; +#endif + +#ifdef _WIN32 +struct __wsinit +{ + __wsinit() + { + WSADATA wsaData; + if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 ) + { + fprintf( stderr, "Cannot init winsock.\n" ); + exit( 1 ); + } + } +}; + +void InitWinSock() +{ + static __wsinit init; +} +#endif + + +enum { BufSize = 128 * 1024 }; + +Socket::Socket() + : m_buf( (char*)tracy_malloc( BufSize ) ) + , m_bufPtr( nullptr ) + , m_sock( -1 ) + , m_bufLeft( 0 ) + , m_ptr( nullptr ) +{ +#ifdef _WIN32 + InitWinSock(); +#endif +} + +Socket::Socket( int sock ) + : m_buf( (char*)tracy_malloc( BufSize ) ) + , m_bufPtr( nullptr ) + , m_sock( sock ) + , m_bufLeft( 0 ) + , m_ptr( nullptr ) +{ +} + +Socket::~Socket() +{ + tracy_free( m_buf ); + if( m_sock.load( std::memory_order_relaxed ) != -1 ) + { + Close(); + } + if( m_ptr ) + { + freeaddrinfo( m_res ); +#ifdef _WIN32 + closesocket( m_connSock ); +#else + close( m_connSock ); +#endif + } +} + +bool Socket::Connect( const char* addr, uint16_t port ) +{ + assert( !IsValid() ); + + if( m_ptr ) + { + const auto c = connect( m_connSock, m_ptr->ai_addr, m_ptr->ai_addrlen ); + if( c == -1 ) + { +#if defined _WIN32 + const auto err = WSAGetLastError(); + if( err == WSAEALREADY || err == WSAEINPROGRESS ) return false; + if( err != WSAEISCONN ) + { + freeaddrinfo( m_res ); + closesocket( m_connSock ); + m_ptr = nullptr; + return false; + } +#else + const auto err = errno; + if( err == EALREADY || err == EINPROGRESS ) return false; + if( err != EISCONN ) + { + freeaddrinfo( m_res ); + close( m_connSock ); + m_ptr = nullptr; + return false; + } +#endif + } + +#if defined _WIN32 + u_long nonblocking = 0; + ioctlsocket( m_connSock, FIONBIO, &nonblocking ); +#else + int flags = fcntl( m_connSock, F_GETFL, 0 ); + fcntl( m_connSock, F_SETFL, flags & ~O_NONBLOCK ); +#endif + m_sock.store( m_connSock, std::memory_order_relaxed ); + freeaddrinfo( m_res ); + m_ptr = nullptr; + return true; + } + + struct addrinfo hints; + struct addrinfo *res, *ptr; + + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + char portbuf[32]; + sprintf( portbuf, "%" PRIu16, port ); + + if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false; + int sock = 0; + for( ptr = res; ptr; ptr = ptr->ai_next ) + { + if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue; +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif +#if defined _WIN32 + u_long nonblocking = 1; + ioctlsocket( sock, FIONBIO, &nonblocking ); +#else + int flags = fcntl( sock, F_GETFL, 0 ); + fcntl( sock, F_SETFL, flags | O_NONBLOCK ); +#endif + if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == 0 ) + { + break; + } + else + { +#if defined _WIN32 + const auto err = WSAGetLastError(); + if( err != WSAEWOULDBLOCK ) + { + closesocket( sock ); + continue; + } +#else + if( errno != EINPROGRESS ) + { + close( sock ); + continue; + } +#endif + } + m_res = res; + m_ptr = ptr; + m_connSock = sock; + return false; + } + freeaddrinfo( res ); + if( !ptr ) return false; + +#if defined _WIN32 + u_long nonblocking = 0; + ioctlsocket( sock, FIONBIO, &nonblocking ); +#else + int flags = fcntl( sock, F_GETFL, 0 ); + fcntl( sock, F_SETFL, flags & ~O_NONBLOCK ); +#endif + + m_sock.store( sock, std::memory_order_relaxed ); + return true; +} + +bool Socket::ConnectBlocking( const char* addr, uint16_t port ) +{ + assert( !IsValid() ); + assert( !m_ptr ); + + struct addrinfo hints; + struct addrinfo *res, *ptr; + + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + char portbuf[32]; + sprintf( portbuf, "%" PRIu16, port ); + + if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false; + int sock = 0; + for( ptr = res; ptr; ptr = ptr->ai_next ) + { + if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue; +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif + if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == -1 ) + { +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + continue; + } + break; + } + freeaddrinfo( res ); + if( !ptr ) return false; + + m_sock.store( sock, std::memory_order_relaxed ); + return true; +} + +void Socket::Close() +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + assert( sock != -1 ); +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + m_sock.store( -1, std::memory_order_relaxed ); +} + +int Socket::Send( const void* _buf, int len ) +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + auto buf = (const char*)_buf; + assert( sock != -1 ); + auto start = buf; + while( len > 0 ) + { + auto ret = send( sock, buf, len, MSG_NOSIGNAL ); + if( ret == -1 ) return -1; + len -= ret; + buf += ret; + } + return int( buf - start ); +} + +int Socket::GetSendBufSize() +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + int bufSize; +#if defined _WIN32 + int sz = sizeof( bufSize ); + getsockopt( sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufSize, &sz ); +#else + socklen_t sz = sizeof( bufSize ); + getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &bufSize, &sz ); +#endif + return bufSize; +} + +int Socket::RecvBuffered( void* buf, int len, int timeout ) +{ + if( len <= m_bufLeft ) + { + memcpy( buf, m_bufPtr, len ); + m_bufPtr += len; + m_bufLeft -= len; + return len; + } + + if( m_bufLeft > 0 ) + { + memcpy( buf, m_bufPtr, m_bufLeft ); + const auto ret = m_bufLeft; + m_bufLeft = 0; + return ret; + } + + if( len >= BufSize ) return Recv( buf, len, timeout ); + + m_bufLeft = Recv( m_buf, BufSize, timeout ); + if( m_bufLeft <= 0 ) return m_bufLeft; + + const auto sz = len < m_bufLeft ? len : m_bufLeft; + memcpy( buf, m_buf, sz ); + m_bufPtr = m_buf + sz; + m_bufLeft -= sz; + return sz; +} + +int Socket::Recv( void* _buf, int len, int timeout ) +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + auto buf = (char*)_buf; + + struct pollfd fd; + fd.fd = (socket_t)sock; + fd.events = POLLIN; + + if( poll( &fd, 1, timeout ) > 0 ) + { + return recv( sock, buf, len, 0 ); + } + else + { + return -1; + } +} + +int Socket::ReadUpTo( void* _buf, int len ) +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + auto buf = (char*)_buf; + + int rd = 0; + while( len > 0 ) + { + const auto res = recv( sock, buf, len, 0 ); + if( res == 0 ) break; + if( res == -1 ) return -1; + len -= res; + rd += res; + buf += res; + } + return rd; +} + +bool Socket::Read( void* buf, int len, int timeout ) +{ + auto cbuf = (char*)buf; + while( len > 0 ) + { + if( !ReadImpl( cbuf, len, timeout ) ) return false; + } + return true; +} + +bool Socket::ReadImpl( char*& buf, int& len, int timeout ) +{ + const auto sz = RecvBuffered( buf, len, timeout ); + switch( sz ) + { + case 0: + return false; + case -1: +#ifdef _WIN32 + { + auto err = WSAGetLastError(); + if( err == WSAECONNABORTED || err == WSAECONNRESET ) return false; + } +#endif + break; + default: + len -= sz; + buf += sz; + break; + } + return true; +} + +bool Socket::ReadRaw( void* _buf, int len, int timeout ) +{ + auto buf = (char*)_buf; + while( len > 0 ) + { + const auto sz = Recv( buf, len, timeout ); + if( sz <= 0 ) return false; + len -= sz; + buf += sz; + } + return true; +} + +bool Socket::HasData() +{ + const auto sock = m_sock.load( std::memory_order_relaxed ); + if( m_bufLeft > 0 ) return true; + + struct pollfd fd; + fd.fd = (socket_t)sock; + fd.events = POLLIN; + + return poll( &fd, 1, 0 ) > 0; +} + +bool Socket::IsValid() const +{ + return m_sock.load( std::memory_order_relaxed ) >= 0; +} + + +ListenSocket::ListenSocket() + : m_sock( -1 ) +{ +#ifdef _WIN32 + InitWinSock(); +#endif +} + +ListenSocket::~ListenSocket() +{ + if( m_sock != -1 ) Close(); +} + +static int addrinfo_and_socket_for_family( uint16_t port, int ai_family, struct addrinfo** res ) +{ + struct addrinfo hints; + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = ai_family; + hints.ai_socktype = SOCK_STREAM; +#ifndef TRACY_ONLY_LOCALHOST + const char* onlyLocalhost = GetEnvVar( "TRACY_ONLY_LOCALHOST" ); + if( !onlyLocalhost || onlyLocalhost[0] != '1' ) + { + hints.ai_flags = AI_PASSIVE; + } +#endif + char portbuf[32]; + sprintf( portbuf, "%" PRIu16, port ); + if( getaddrinfo( nullptr, portbuf, &hints, res ) != 0 ) return -1; + int sock = socket( (*res)->ai_family, (*res)->ai_socktype, (*res)->ai_protocol ); + if (sock == -1) freeaddrinfo( *res ); + return sock; +} + +bool ListenSocket::Listen( uint16_t port, int backlog ) +{ + assert( m_sock == -1 ); + + struct addrinfo* res = nullptr; + +#if !defined TRACY_ONLY_IPV4 && !defined TRACY_ONLY_LOCALHOST + const char* onlyIPv4 = GetEnvVar( "TRACY_ONLY_IPV4" ); + if( !onlyIPv4 || onlyIPv4[0] != '1' ) + { + m_sock = addrinfo_and_socket_for_family( port, AF_INET6, &res ); + } +#endif + if (m_sock == -1) + { + // IPV6 protocol may not be available/is disabled. Try to create a socket + // with the IPV4 protocol + m_sock = addrinfo_and_socket_for_family( port, AF_INET, &res ); + if( m_sock == -1 ) return false; + } +#if defined _WIN32 + unsigned long val = 0; + setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) ); +#elif defined BSD + int val = 0; + setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) ); + val = 1; + setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) ); +#else + int val = 1; + setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) ); +#endif + if( bind( m_sock, res->ai_addr, res->ai_addrlen ) == -1 ) { freeaddrinfo( res ); Close(); return false; } + if( listen( m_sock, backlog ) == -1 ) { freeaddrinfo( res ); Close(); return false; } + freeaddrinfo( res ); + return true; +} + +Socket* ListenSocket::Accept() +{ + struct sockaddr_storage remote; + socklen_t sz = sizeof( remote ); + + struct pollfd fd; + fd.fd = (socket_t)m_sock; + fd.events = POLLIN; + + if( poll( &fd, 1, 10 ) > 0 ) + { + int sock = accept( m_sock, (sockaddr*)&remote, &sz); + if( sock == -1 ) return nullptr; + +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif + + auto ptr = (Socket*)tracy_malloc( sizeof( Socket ) ); + new(ptr) Socket( sock ); + return ptr; + } + else + { + return nullptr; + } +} + +void ListenSocket::Close() +{ + assert( m_sock != -1 ); +#ifdef _WIN32 + closesocket( m_sock ); +#else + close( m_sock ); +#endif + m_sock = -1; +} + +UdpBroadcast::UdpBroadcast() + : m_sock( -1 ) +{ +#ifdef _WIN32 + InitWinSock(); +#endif +} + +UdpBroadcast::~UdpBroadcast() +{ + if( m_sock != -1 ) Close(); +} + +bool UdpBroadcast::Open( const char* addr, uint16_t port ) +{ + assert( m_sock == -1 ); + + struct addrinfo hints; + struct addrinfo *res, *ptr; + + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + char portbuf[32]; + sprintf( portbuf, "%" PRIu16, port ); + + if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false; + int sock = 0; + for( ptr = res; ptr; ptr = ptr->ai_next ) + { + if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue; +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif +#if defined _WIN32 + unsigned long broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 ) +#else + int broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 ) +#endif + { +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + continue; + } + break; + } + freeaddrinfo( res ); + if( !ptr ) return false; + + m_sock = sock; + inet_pton( AF_INET, addr, &m_addr ); + return true; +} + +void UdpBroadcast::Close() +{ + assert( m_sock != -1 ); +#ifdef _WIN32 + closesocket( m_sock ); +#else + close( m_sock ); +#endif + m_sock = -1; +} + +int UdpBroadcast::Send( uint16_t port, const void* data, int len ) +{ + assert( m_sock != -1 ); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons( port ); + addr.sin_addr.s_addr = m_addr; + return sendto( m_sock, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&addr, sizeof( addr ) ); +} + +IpAddress::IpAddress() + : m_number( 0 ) +{ + *m_text = '\0'; +} + +IpAddress::~IpAddress() +{ +} + +void IpAddress::Set( const struct sockaddr& addr ) +{ +#if defined _WIN32 && ( !defined NTDDI_WIN10 || NTDDI_VERSION < NTDDI_WIN10 ) + struct sockaddr_in tmp; + memcpy( &tmp, &addr, sizeof( tmp ) ); + auto ai = &tmp; +#else + auto ai = (const struct sockaddr_in*)&addr; +#endif + inet_ntop( AF_INET, &ai->sin_addr, m_text, 17 ); + m_number = ai->sin_addr.s_addr; +} + +UdpListen::UdpListen() + : m_sock( -1 ) +{ +#ifdef _WIN32 + InitWinSock(); +#endif +} + +UdpListen::~UdpListen() +{ + if( m_sock != -1 ) Close(); +} + +bool UdpListen::Listen( uint16_t port ) +{ + assert( m_sock == -1 ); + + int sock; + if( ( sock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) return false; + +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif +#if defined _WIN32 + unsigned long reuse = 1; + setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof( reuse ) ); +#else + int reuse = 1; + setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) ); +#endif +#if defined _WIN32 + unsigned long broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 ) +#else + int broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 ) +#endif + { +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + return false; + } + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons( port ); + addr.sin_addr.s_addr = INADDR_ANY; + + if( bind( sock, (sockaddr*)&addr, sizeof( addr ) ) == -1 ) + { +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + return false; + } + + m_sock = sock; + return true; +} + +void UdpListen::Close() +{ + assert( m_sock != -1 ); +#ifdef _WIN32 + closesocket( m_sock ); +#else + close( m_sock ); +#endif + m_sock = -1; +} + +const char* UdpListen::Read( size_t& len, IpAddress& addr, int timeout ) +{ + static char buf[2048]; + + struct pollfd fd; + fd.fd = (socket_t)m_sock; + fd.events = POLLIN; + if( poll( &fd, 1, timeout ) <= 0 ) return nullptr; + + sockaddr sa; + socklen_t salen = sizeof( struct sockaddr ); + len = (size_t)recvfrom( m_sock, buf, 2048, 0, &sa, &salen ); + addr.Set( sa ); + + return buf; +} + +} diff --git a/Externals/tracy/public/common/TracySocket.hpp b/Externals/tracy/public/common/TracySocket.hpp new file mode 100644 index 00000000000..f7713aac663 --- /dev/null +++ b/Externals/tracy/public/common/TracySocket.hpp @@ -0,0 +1,155 @@ +#ifndef __TRACYSOCKET_HPP__ +#define __TRACYSOCKET_HPP__ + +#include +#include +#include + +struct addrinfo; +struct sockaddr; + +namespace tracy +{ + +#ifdef _WIN32 +void InitWinSock(); +#endif + +class Socket +{ +public: + Socket(); + Socket( int sock ); + ~Socket(); + + bool Connect( const char* addr, uint16_t port ); + bool ConnectBlocking( const char* addr, uint16_t port ); + void Close(); + + int Send( const void* buf, int len ); + int GetSendBufSize(); + + int ReadUpTo( void* buf, int len ); + bool Read( void* buf, int len, int timeout ); + + template + bool Read( void* buf, int len, int timeout, ShouldExit exitCb ) + { + auto cbuf = (char*)buf; + while( len > 0 ) + { + if( exitCb() ) return false; + if( !ReadImpl( cbuf, len, timeout ) ) return false; + } + return true; + } + + bool ReadRaw( void* buf, int len, int timeout ); + bool HasData(); + bool IsValid() const; + + Socket( const Socket& ) = delete; + Socket( Socket&& ) = delete; + Socket& operator=( const Socket& ) = delete; + Socket& operator=( Socket&& ) = delete; + +private: + int RecvBuffered( void* buf, int len, int timeout ); + int Recv( void* buf, int len, int timeout ); + + bool ReadImpl( char*& buf, int& len, int timeout ); + + char* m_buf; + char* m_bufPtr; + std::atomic m_sock; + int m_bufLeft; + + struct addrinfo *m_res; + struct addrinfo *m_ptr; + int m_connSock; +}; + +class ListenSocket +{ +public: + ListenSocket(); + ~ListenSocket(); + + bool Listen( uint16_t port, int backlog ); + Socket* Accept(); + void Close(); + + ListenSocket( const ListenSocket& ) = delete; + ListenSocket( ListenSocket&& ) = delete; + ListenSocket& operator=( const ListenSocket& ) = delete; + ListenSocket& operator=( ListenSocket&& ) = delete; + +private: + int m_sock; +}; + +class UdpBroadcast +{ +public: + UdpBroadcast(); + ~UdpBroadcast(); + + bool Open( const char* addr, uint16_t port ); + void Close(); + + int Send( uint16_t port, const void* data, int len ); + + UdpBroadcast( const UdpBroadcast& ) = delete; + UdpBroadcast( UdpBroadcast&& ) = delete; + UdpBroadcast& operator=( const UdpBroadcast& ) = delete; + UdpBroadcast& operator=( UdpBroadcast&& ) = delete; + +private: + int m_sock; + uint32_t m_addr; +}; + +class IpAddress +{ +public: + IpAddress(); + ~IpAddress(); + + void Set( const struct sockaddr& addr ); + + uint32_t GetNumber() const { return m_number; } + const char* GetText() const { return m_text; } + + IpAddress( const IpAddress& ) = delete; + IpAddress( IpAddress&& ) = delete; + IpAddress& operator=( const IpAddress& ) = delete; + IpAddress& operator=( IpAddress&& ) = delete; + +private: + uint32_t m_number; + char m_text[17]; +}; + +class UdpListen +{ +public: + UdpListen(); + ~UdpListen(); + + bool Listen( uint16_t port ); + void Close(); + + const char* Read( size_t& len, IpAddress& addr, int timeout ); + + UdpListen( const UdpListen& ) = delete; + UdpListen( UdpListen&& ) = delete; + UdpListen& operator=( const UdpListen& ) = delete; + UdpListen& operator=( UdpListen&& ) = delete; + +private: + int m_sock; +}; + +} + +#endif diff --git a/Externals/tracy/public/common/TracyStackFrames.cpp b/Externals/tracy/public/common/TracyStackFrames.cpp new file mode 100644 index 00000000000..7b0abace377 --- /dev/null +++ b/Externals/tracy/public/common/TracyStackFrames.cpp @@ -0,0 +1,122 @@ +#include "TracyStackFrames.hpp" + +namespace tracy +{ + +const char* s_tracyStackFrames_[] = { + "tracy::Callstack", + "tracy::Callstack(int)", + "tracy::GpuCtxScope::{ctor}", + "tracy::Profiler::SendCallstack", + "tracy::Profiler::SendCallstack(int)", + "tracy::Profiler::SendCallstack(int, unsigned long)", + "tracy::Profiler::MemAllocCallstack", + "tracy::Profiler::MemAllocCallstack(void const*, unsigned long, int)", + "tracy::Profiler::MemFreeCallstack", + "tracy::Profiler::MemFreeCallstack(void const*, int)", + "tracy::ScopedZone::{ctor}", + "tracy::ScopedZone::ScopedZone(tracy::SourceLocationData const*, int, bool)", + "tracy::Profiler::Message", + nullptr +}; + +const char** s_tracyStackFrames = s_tracyStackFrames_; + +const StringMatch s_tracySkipSubframes_[] = { + { "/include/arm_neon.h", 19 }, + { "/include/adxintrin.h", 20 }, + { "/include/ammintrin.h", 20 }, + { "/include/amxbf16intrin.h", 24 }, + { "/include/amxint8intrin.h", 24 }, + { "/include/amxtileintrin.h", 24 }, + { "/include/avx2intrin.h", 21 }, + { "/include/avx5124fmapsintrin.h", 29 }, + { "/include/avx5124vnniwintrin.h", 29 }, + { "/include/avx512bf16intrin.h", 27 }, + { "/include/avx512bf16vlintrin.h", 29 }, + { "/include/avx512bitalgintrin.h", 29 }, + { "/include/avx512bwintrin.h", 25 }, + { "/include/avx512cdintrin.h", 25 }, + { "/include/avx512dqintrin.h", 25 }, + { "/include/avx512erintrin.h", 25 }, + { "/include/avx512fintrin.h", 24 }, + { "/include/avx512ifmaintrin.h", 27 }, + { "/include/avx512ifmavlintrin.h", 29 }, + { "/include/avx512pfintrin.h", 25 }, + { "/include/avx512vbmi2intrin.h", 28 }, + { "/include/avx512vbmi2vlintrin.h", 30 }, + { "/include/avx512vbmiintrin.h", 27 }, + { "/include/avx512vbmivlintrin.h", 29 }, + { "/include/avx512vlbwintrin.h", 27 }, + { "/include/avx512vldqintrin.h", 27 }, + { "/include/avx512vlintrin.h", 25 }, + { "/include/avx512vnniintrin.h", 27 }, + { "/include/avx512vnnivlintrin.h", 29 }, + { "/include/avx512vp2intersectintrin.h", 35 }, + { "/include/avx512vp2intersectvlintrin.h", 37 }, + { "/include/avx512vpopcntdqintrin.h", 32 }, + { "/include/avx512vpopcntdqvlintrin.h", 34 }, + { "/include/avxintrin.h", 20 }, + { "/include/avxvnniintrin.h", 24 }, + { "/include/bmi2intrin.h", 21 }, + { "/include/bmiintrin.h", 20 }, + { "/include/bmmintrin.h", 20 }, + { "/include/cetintrin.h", 20 }, + { "/include/cldemoteintrin.h", 25 }, + { "/include/clflushoptintrin.h", 27 }, + { "/include/clwbintrin.h", 21 }, + { "/include/clzerointrin.h", 23 }, + { "/include/emmintrin.h", 20 }, + { "/include/enqcmdintrin.h", 23 }, + { "/include/f16cintrin.h", 21 }, + { "/include/fma4intrin.h", 21 }, + { "/include/fmaintrin.h", 20 }, + { "/include/fxsrintrin.h", 21 }, + { "/include/gfniintrin.h", 21 }, + { "/include/hresetintrin.h", 23 }, + { "/include/ia32intrin.h", 21 }, + { "/include/immintrin.h", 20 }, + { "/include/keylockerintrin.h", 26 }, + { "/include/lwpintrin.h", 20 }, + { "/include/lzcntintrin.h", 22 }, + { "/include/mmintrin.h", 19 }, + { "/include/movdirintrin.h", 23 }, + { "/include/mwaitxintrin.h", 23 }, + { "/include/nmmintrin.h", 20 }, + { "/include/pconfigintrin.h", 24 }, + { "/include/pkuintrin.h", 20 }, + { "/include/pmmintrin.h", 20 }, + { "/include/popcntintrin.h", 23 }, + { "/include/prfchwintrin.h", 23 }, + { "/include/rdseedintrin.h", 23 }, + { "/include/rtmintrin.h", 20 }, + { "/include/serializeintrin.h", 26 }, + { "/include/sgxintrin.h", 20 }, + { "/include/shaintrin.h", 20 }, + { "/include/smmintrin.h", 20 }, + { "/include/tbmintrin.h", 20 }, + { "/include/tmmintrin.h", 20 }, + { "/include/tsxldtrkintrin.h", 25 }, + { "/include/uintrintrin.h", 22 }, + { "/include/vaesintrin.h", 21 }, + { "/include/vpclmulqdqintrin.h", 27 }, + { "/include/waitpkgintrin.h", 24 }, + { "/include/wbnoinvdintrin.h", 25 }, + { "/include/wmmintrin.h", 20 }, + { "/include/x86gprintrin.h", 23 }, + { "/include/x86intrin.h", 20 }, + { "/include/xmmintrin.h", 20 }, + { "/include/xopintrin.h", 20 }, + { "/include/xsavecintrin.h", 23 }, + { "/include/xsaveintrin.h", 22 }, + { "/include/xsaveoptintrin.h", 25 }, + { "/include/xsavesintrin.h", 23 }, + { "/include/xtestintrin.h", 22 }, + { "/bits/atomic_base.h", 19 }, + { "/atomic", 7 }, + {} +}; + +const StringMatch* s_tracySkipSubframes = s_tracySkipSubframes_; + +} diff --git a/Externals/tracy/public/common/TracyStackFrames.hpp b/Externals/tracy/public/common/TracyStackFrames.hpp new file mode 100644 index 00000000000..9d4262c00a1 --- /dev/null +++ b/Externals/tracy/public/common/TracyStackFrames.hpp @@ -0,0 +1,22 @@ +#ifndef __TRACYSTACKFRAMES_HPP__ +#define __TRACYSTACKFRAMES_HPP__ + +#include + +namespace tracy +{ + +struct StringMatch +{ + const char* str; + size_t len; +}; + +extern const char** s_tracyStackFrames; +extern const StringMatch* s_tracySkipSubframes; + +static constexpr int s_tracySkipSubframesMinLen = 7; + +} + +#endif diff --git a/Externals/tracy/public/common/TracySystem.cpp b/Externals/tracy/public/common/TracySystem.cpp new file mode 100644 index 00000000000..9a477aa310c --- /dev/null +++ b/Externals/tracy/public/common/TracySystem.cpp @@ -0,0 +1,306 @@ +#ifdef _MSC_VER +# pragma warning(disable:4996) +#endif +#if defined _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# include +# include "TracyUwp.hpp" +#else +# include +# include +# include +#endif + +#ifdef __linux__ +# ifdef __ANDROID__ +# include +# else +# include +# endif +# include +#elif defined __FreeBSD__ +# include +#elif defined __NetBSD__ || defined __DragonFly__ +# include +#endif + +#ifdef __MINGW32__ +# define __STDC_FORMAT_MACROS +#endif +#include +#include +#include + +#include "TracySystem.hpp" + +#if defined _WIN32 +extern "C" typedef HRESULT (WINAPI *t_SetThreadDescription)( HANDLE, PCWSTR ); +extern "C" typedef HRESULT (WINAPI *t_GetThreadDescription)( HANDLE, PWSTR* ); +#endif + +#ifdef TRACY_ENABLE +# include +# include "TracyAlloc.hpp" +#endif + +namespace tracy +{ + +namespace detail +{ + +TRACY_API uint32_t GetThreadHandleImpl() +{ +#if defined _WIN32 + static_assert( sizeof( decltype( GetCurrentThreadId() ) ) <= sizeof( uint32_t ), "Thread handle too big to fit in protocol" ); + return uint32_t( GetCurrentThreadId() ); +#elif defined __APPLE__ + uint64_t id; + pthread_threadid_np( pthread_self(), &id ); + return uint32_t( id ); +#elif defined __ANDROID__ + return (uint32_t)gettid(); +#elif defined __linux__ + return (uint32_t)syscall( SYS_gettid ); +#elif defined __FreeBSD__ + long id; + thr_self( &id ); + return id; +#elif defined __NetBSD__ + return _lwp_self(); +#elif defined __DragonFly__ + return lwp_gettid(); +#elif defined __OpenBSD__ + return getthrid(); +#elif defined __EMSCRIPTEN__ + // Not supported, but let it compile. + return 0; +#else + // To add support for a platform, retrieve and return the kernel thread identifier here. + // + // Note that pthread_t (as for example returned by pthread_self()) is *not* a kernel + // thread identifier. It is a pointer to a library-allocated data structure instead. + // Such pointers will be reused heavily, making the pthread_t non-unique. Additionally + // a 64-bit pointer cannot be reliably truncated to 32 bits. + #error "Unsupported platform!" +#endif + +} + +} + +#ifdef TRACY_ENABLE +struct ThreadNameData +{ + uint32_t id; + const char* name; + ThreadNameData* next; +}; +std::atomic& GetThreadNameData(); +#endif + +#ifdef _MSC_VER +# pragma pack( push, 8 ) +struct THREADNAME_INFO +{ + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; +}; +# pragma pack( pop ) + +void ThreadNameMsvcMagic( const THREADNAME_INFO& info ) +{ + __try + { + RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +} +#endif + +TRACY_API void SetThreadName( const char* name ) +{ +#if defined _WIN32 +# ifdef TRACY_UWP + static auto _SetThreadDescription = &::SetThreadDescription; +# else + static auto _SetThreadDescription = (t_SetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "SetThreadDescription" ); +# endif + if( _SetThreadDescription ) + { + wchar_t buf[256]; + mbstowcs( buf, name, 256 ); + _SetThreadDescription( GetCurrentThread(), buf ); + } + else + { +# if defined _MSC_VER + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; + ThreadNameMsvcMagic( info ); +# endif + } +#elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__ + { + const auto sz = strlen( name ); + if( sz <= 15 ) + { +#if defined __APPLE__ + pthread_setname_np( name ); +#else + pthread_setname_np( pthread_self(), name ); +#endif + } + else + { + char buf[16]; + memcpy( buf, name, 15 ); + buf[15] = '\0'; +#if defined __APPLE__ + pthread_setname_np( buf ); +#else + pthread_setname_np( pthread_self(), buf ); +#endif + } + } +#endif +#ifdef TRACY_ENABLE + { + const auto sz = strlen( name ); + char* buf = (char*)tracy_malloc( sz+1 ); + memcpy( buf, name, sz ); + buf[sz] = '\0'; + auto data = (ThreadNameData*)tracy_malloc_fast( sizeof( ThreadNameData ) ); + data->id = detail::GetThreadHandleImpl(); + data->name = buf; + data->next = GetThreadNameData().load( std::memory_order_relaxed ); + while( !GetThreadNameData().compare_exchange_weak( data->next, data, std::memory_order_release, std::memory_order_relaxed ) ) {} + } +#endif +} + +TRACY_API const char* GetThreadName( uint32_t id ) +{ + static char buf[256]; +#ifdef TRACY_ENABLE + auto ptr = GetThreadNameData().load( std::memory_order_relaxed ); + while( ptr ) + { + if( ptr->id == id ) + { + return ptr->name; + } + ptr = ptr->next; + } +#endif + +#if defined _WIN32 +# ifdef TRACY_UWP + static auto _GetThreadDescription = &::GetThreadDescription; +# else + static auto _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" ); +# endif + if( _GetThreadDescription ) + { + auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)id ); + if( hnd != 0 ) + { + PWSTR tmp; + if( SUCCEEDED( _GetThreadDescription( hnd, &tmp ) ) ) + { + auto ret = wcstombs( buf, tmp, 256 ); + CloseHandle( hnd ); + LocalFree( tmp ); + if( ret != static_cast( -1 ) ) + { + return buf; + } + } + } + } +#elif defined __linux__ + int cs, fd; + char path[32]; + snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", id ); + sprintf( buf, "%" PRIu32, id ); +# ifndef __ANDROID__ + pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs ); +# endif + if ( ( fd = open( path, O_RDONLY ) ) > 0) { + int len = read( fd, buf, 255 ); + if( len > 0 ) + { + buf[len] = 0; + if( len > 1 && buf[len-1] == '\n' ) + { + buf[len-1] = 0; + } + } + close( fd ); + } +# ifndef __ANDROID__ + pthread_setcancelstate( cs, 0 ); +# endif + return buf; +#endif + + sprintf( buf, "%" PRIu32, id ); + return buf; +} + +TRACY_API const char* GetEnvVar( const char* name ) +{ +#if defined _WIN32 + // unfortunately getenv() on Windows is just fundamentally broken. It caches the entire + // environment block once on startup, then never refreshes it again. If any environment + // strings are added or modified after startup of the CRT, those changes will not be + // seen by getenv(). This removes the possibility of an app using this SDK from + // programmatically setting any of the behaviour controlling envvars here. + // + // To work around this, we'll instead go directly to the Win32 environment strings APIs + // to get the current value. + static char buffer[1024]; + DWORD const kBufferSize = DWORD(sizeof(buffer) / sizeof(buffer[0])); + DWORD count = GetEnvironmentVariableA(name, buffer, kBufferSize); + + if( count == 0 ) + return nullptr; + + if( count >= kBufferSize ) + { + char* buf = reinterpret_cast(_alloca(count + 1)); + count = GetEnvironmentVariableA(name, buf, count + 1); + memcpy(buffer, buf, kBufferSize); + buffer[kBufferSize - 1] = 0; + } + + return buffer; +#else + return getenv(name); +#endif +} + +} + +#ifdef __cplusplus +extern "C" { +#endif + +TRACY_API void ___tracy_set_thread_name( const char* name ) { tracy::SetThreadName( name ); } + +#ifdef __cplusplus +} +#endif diff --git a/Externals/tracy/public/common/TracySystem.hpp b/Externals/tracy/public/common/TracySystem.hpp new file mode 100644 index 00000000000..e0040e95c69 --- /dev/null +++ b/Externals/tracy/public/common/TracySystem.hpp @@ -0,0 +1,32 @@ +#ifndef __TRACYSYSTEM_HPP__ +#define __TRACYSYSTEM_HPP__ + +#include + +#include "TracyApi.h" + +namespace tracy +{ + +namespace detail +{ +TRACY_API uint32_t GetThreadHandleImpl(); +} + +#ifdef TRACY_ENABLE +TRACY_API uint32_t GetThreadHandle(); +#else +static inline uint32_t GetThreadHandle() +{ + return detail::GetThreadHandleImpl(); +} +#endif + +TRACY_API void SetThreadName( const char* name ); +TRACY_API const char* GetThreadName( uint32_t id ); + +TRACY_API const char* GetEnvVar(const char* name); + +} + +#endif diff --git a/Externals/tracy/public/common/TracyUwp.hpp b/Externals/tracy/public/common/TracyUwp.hpp new file mode 100644 index 00000000000..7dce96b960e --- /dev/null +++ b/Externals/tracy/public/common/TracyUwp.hpp @@ -0,0 +1,11 @@ +#ifndef __TRACYUWP_HPP__ +#define __TRACYUWP_HPP__ + +#ifdef _WIN32 +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define TRACY_UWP +# endif +#endif + +#endif diff --git a/Externals/tracy/public/common/TracyVersion.hpp b/Externals/tracy/public/common/TracyVersion.hpp new file mode 100644 index 00000000000..2355279f721 --- /dev/null +++ b/Externals/tracy/public/common/TracyVersion.hpp @@ -0,0 +1,14 @@ +#ifndef __TRACYVERSION_HPP__ +#define __TRACYVERSION_HPP__ + +namespace tracy +{ +namespace Version +{ +enum { Major = 0 }; +enum { Minor = 10 }; +enum { Patch = 0 }; +} +} + +#endif diff --git a/Externals/tracy/public/common/TracyYield.hpp b/Externals/tracy/public/common/TracyYield.hpp new file mode 100644 index 00000000000..035836cdb9f --- /dev/null +++ b/Externals/tracy/public/common/TracyYield.hpp @@ -0,0 +1,28 @@ +#ifndef __TRACYYIELD_HPP__ +#define __TRACYYIELD_HPP__ + +#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2) +# include +#else +# include +#endif + +#include "TracyForceInline.hpp" + +namespace tracy +{ + +static tracy_force_inline void YieldThread() +{ +#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2) + _mm_pause(); +#elif defined __aarch64__ + asm volatile( "isb" : : ); +#else + std::this_thread::yield(); +#endif +} + +} + +#endif diff --git a/Externals/tracy/public/common/tracy_lz4.cpp b/Externals/tracy/public/common/tracy_lz4.cpp new file mode 100644 index 00000000000..6c26639c572 --- /dev/null +++ b/Externals/tracy/public/common/tracy_lz4.cpp @@ -0,0 +1,2720 @@ +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-2020, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 +*/ + +/*-************************************ +* Tuning parameters +**************************************/ +/* + * LZ4_HEAPMODE : + * Select how default compression functions will allocate memory for their hash table, + * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). + */ +#ifndef LZ4_HEAPMODE +# define LZ4_HEAPMODE 0 +#endif + +/* + * LZ4_ACCELERATION_DEFAULT : + * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 + */ +#define LZ4_ACCELERATION_DEFAULT 1 +/* + * LZ4_ACCELERATION_MAX : + * Any "acceleration" value higher than this threshold + * get treated as LZ4_ACCELERATION_MAX instead (fix #876) + */ +#define LZ4_ACCELERATION_MAX 65537 + + +/*-************************************ +* CPU Feature Detection +**************************************/ +/* LZ4_FORCE_MEMORY_ACCESS + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets which assembly generation depends on alignment. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ +# if defined(__GNUC__) && \ + ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define LZ4_FORCE_MEMORY_ACCESS 2 +# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) +# define LZ4_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/* + * LZ4_FORCE_SW_BITCOUNT + * Define this parameter if your target system or compiler does not support hardware bit count + */ +#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for WinCE doesn't support Hardware bit count */ +# undef LZ4_FORCE_SW_BITCOUNT /* avoid double def */ +# define LZ4_FORCE_SW_BITCOUNT +#endif + + + +/*-************************************ +* Dependency +**************************************/ +/* + * LZ4_SRC_INCLUDED: + * Amalgamation flag, whether lz4.c is included + */ +#ifndef LZ4_SRC_INCLUDED +# define LZ4_SRC_INCLUDED 1 +#endif + +#ifndef LZ4_STATIC_LINKING_ONLY +#define LZ4_STATIC_LINKING_ONLY +#endif + +#ifndef LZ4_DISABLE_DEPRECATE_WARNINGS +#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ +#endif + +#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */ +#include "tracy_lz4.hpp" +/* see also "memory routines" below */ + + +/*-************************************ +* Compiler Options +**************************************/ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Visual Studio 2005+ */ +# include /* only present in VS2005+ */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */ +#endif /* _MSC_VER */ + +#ifndef LZ4_FORCE_INLINE +# ifdef _MSC_VER /* Visual Studio */ +# define LZ4_FORCE_INLINE static __forceinline +# else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define LZ4_FORCE_INLINE static inline +# endif +# else +# define LZ4_FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +# endif /* _MSC_VER */ +#endif /* LZ4_FORCE_INLINE */ + +/* LZ4_FORCE_O2 and LZ4_FORCE_INLINE + * gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8, + * together with a simple 8-byte copy loop as a fall-back path. + * However, this optimization hurts the decompression speed by >30%, + * because the execution does not go to the optimized loop + * for typical compressible data, and all of the preamble checks + * before going to the fall-back path become useless overhead. + * This optimization happens only with the -O3 flag, and -O2 generates + * a simple 8-byte copy loop. + * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8 + * functions are annotated with __attribute__((optimize("O2"))), + * and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute + * of LZ4_wildCopy8 does not affect the compression speed. + */ +#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__) +# define LZ4_FORCE_O2 __attribute__((optimize("O2"))) +# undef LZ4_FORCE_INLINE +# define LZ4_FORCE_INLINE static __inline __attribute__((optimize("O2"),always_inline)) +#else +# define LZ4_FORCE_O2 +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#ifndef likely +#define likely(expr) expect((expr) != 0, 1) +#endif +#ifndef unlikely +#define unlikely(expr) expect((expr) != 0, 0) +#endif + +/* Should the alignment test prove unreliable, for some reason, + * it can be disabled by setting LZ4_ALIGN_TEST to 0 */ +#ifndef LZ4_ALIGN_TEST /* can be externally provided */ +# define LZ4_ALIGN_TEST 1 +#endif + + +/*-************************************ +* Memory routines +**************************************/ + +/*! LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION : + * Disable relatively high-level LZ4/HC functions that use dynamic memory + * allocation functions (malloc(), calloc(), free()). + * + * Note that this is a compile-time switch. And since it disables + * public/stable LZ4 v1 API functions, we don't recommend using this + * symbol to generate a library for distribution. + * + * The following public functions are removed when this symbol is defined. + * - lz4 : LZ4_createStream, LZ4_freeStream, + * LZ4_createStreamDecode, LZ4_freeStreamDecode, LZ4_create (deprecated) + * - lz4hc : LZ4_createStreamHC, LZ4_freeStreamHC, + * LZ4_createHC (deprecated), LZ4_freeHC (deprecated) + * - lz4frame, lz4file : All LZ4F_* functions + */ +#if defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +# define ALLOC(s) lz4_error_memory_allocation_is_disabled +# define ALLOC_AND_ZERO(s) lz4_error_memory_allocation_is_disabled +# define FREEMEM(p) lz4_error_memory_allocation_is_disabled +#elif defined(LZ4_USER_MEMORY_FUNCTIONS) +/* memory management functions can be customized by user project. + * Below functions must exist somewhere in the Project + * and be available at link time */ +void* LZ4_malloc(size_t s); +void* LZ4_calloc(size_t n, size_t s); +void LZ4_free(void* p); +# define ALLOC(s) LZ4_malloc(s) +# define ALLOC_AND_ZERO(s) LZ4_calloc(1,s) +# define FREEMEM(p) LZ4_free(p) +#else +# include /* malloc, calloc, free */ +# define ALLOC(s) malloc(s) +# define ALLOC_AND_ZERO(s) calloc(1,s) +# define FREEMEM(p) free(p) +#endif + +#if ! LZ4_FREESTANDING +# include /* memset, memcpy */ +#endif +#if !defined(LZ4_memset) +# define LZ4_memset(p,v,s) memset((p),(v),(s)) +#endif +#define MEM_INIT(p,v,s) LZ4_memset((p),(v),(s)) + + +/*-************************************ +* Common Constants +**************************************/ +#define MINMATCH 4 + +#define WILDCOPYLENGTH 8 +#define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ +#define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ +#define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */ +#define FASTLOOP_SAFE_DISTANCE 64 +static const int LZ4_minLength = (MFLIMIT+1); + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define LZ4_DISTANCE_ABSOLUTE_MAX 65535 +#if (LZ4_DISTANCE_MAX > LZ4_DISTANCE_ABSOLUTE_MAX) /* max supported by LZ4 format */ +# error "LZ4_DISTANCE_MAX is too big : must be <= 65535" +#endif + +#define ML_BITS 4 +#define ML_MASK ((1U<=1) +# include +#else +# ifndef assert +# define assert(condition) ((void)0) +# endif +#endif + +#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */ + +#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) +# include + static int g_debuglog_enable = 1; +# define DEBUGLOG(l, ...) { \ + if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ + fprintf(stderr, __FILE__ ": "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } +#else +# define DEBUGLOG(l, ...) {} /* disabled */ +#endif + +static int LZ4_isAligned(const void* ptr, size_t alignment) +{ + return ((size_t)ptr & (alignment -1)) == 0; +} + + +/*-************************************ +* Types +**************************************/ +#include +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef uintptr_t uptrval; +#else +# if UINT_MAX != 4294967295UL +# error "LZ4 code (when not C++ or C99) assumes that sizeof(int) == 4" +# endif + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; + typedef size_t uptrval; /* generally true, except OpenVMS-64 */ +#endif + +#if defined(__x86_64__) + typedef U64 reg_t; /* 64-bits in x32 mode */ +#else + typedef size_t reg_t; /* 32-bits in x32 mode */ +#endif + +typedef enum { + notLimited = 0, + limitedOutput = 1, + fillOutput = 2 +} limitedOutput_directive; + +namespace tracy +{ + +/*-************************************ +* Reading and writing into memory +**************************************/ + +/** + * LZ4 relies on memcpy with a constant size being inlined. In freestanding + * environments, the compiler can't assume the implementation of memcpy() is + * standard compliant, so it can't apply its specialized memcpy() inlining + * logic. When possible, use __builtin_memcpy() to tell the compiler to analyze + * memcpy() as if it were standard compliant, so it can inline it in freestanding + * environments. This is needed when decompressing the Linux Kernel, for example. + */ +#if !defined(LZ4_memcpy) +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) +# else +# define LZ4_memcpy(dst, src, size) memcpy(dst, src, size) +# endif +#endif + +#if !defined(LZ4_memmove) +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4_memmove __builtin_memmove +# else +# define LZ4_memmove memmove +# endif +#endif + +static unsigned LZ4_isLittleEndian(void) +{ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + + +#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) +/* lie to the compiler about data alignment; use with caution */ + +static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } +static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } +static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } + +static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } + +#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) LZ4_unalign; + +static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign*)ptr)->u16; } +static U32 LZ4_read32(const void* ptr) { return ((const LZ4_unalign*)ptr)->u32; } +static reg_t LZ4_read_ARCH(const void* ptr) { return ((const LZ4_unalign*)ptr)->uArch; } + +static void LZ4_write16(void* memPtr, U16 value) { ((LZ4_unalign*)memPtr)->u16 = value; } +static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign*)memPtr)->u32 = value; } + +#else /* safe and portable access using memcpy() */ + +static U16 LZ4_read16(const void* memPtr) +{ + U16 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; +} + +static U32 LZ4_read32(const void* memPtr) +{ + U32 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; +} + +static reg_t LZ4_read_ARCH(const void* memPtr) +{ + reg_t val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; +} + +static void LZ4_write16(void* memPtr, U16 value) +{ + LZ4_memcpy(memPtr, &value, sizeof(value)); +} + +static void LZ4_write32(void* memPtr, U32 value) +{ + LZ4_memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* LZ4_FORCE_MEMORY_ACCESS */ + + +static U16 LZ4_readLE16(const void* memPtr) +{ + if (LZ4_isLittleEndian()) { + return LZ4_read16(memPtr); + } else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)((U16)p[0] + (p[1]<<8)); + } +} + +static void LZ4_writeLE16(void* memPtr, U16 value) +{ + if (LZ4_isLittleEndian()) { + LZ4_write16(memPtr, value); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE) value; + p[1] = (BYTE)(value>>8); + } +} + +/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ +LZ4_FORCE_INLINE +void LZ4_wildCopy8(void* dstPtr, const void* srcPtr, void* dstEnd) +{ + BYTE* d = (BYTE*)dstPtr; + const BYTE* s = (const BYTE*)srcPtr; + BYTE* const e = (BYTE*)dstEnd; + + do { LZ4_memcpy(d,s,8); d+=8; s+=8; } while (d= 16. */ +LZ4_FORCE_INLINE void +LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd) +{ + BYTE* d = (BYTE*)dstPtr; + const BYTE* s = (const BYTE*)srcPtr; + BYTE* const e = (BYTE*)dstEnd; + + do { LZ4_memcpy(d,s,16); LZ4_memcpy(d+16,s+16,16); d+=32; s+=32; } while (d= dstPtr + MINMATCH + * - there is at least 8 bytes available to write after dstEnd */ +LZ4_FORCE_INLINE void +LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) +{ + BYTE v[8]; + + assert(dstEnd >= dstPtr + MINMATCH); + + switch(offset) { + case 1: + MEM_INIT(v, *srcPtr, 8); + break; + case 2: + LZ4_memcpy(v, srcPtr, 2); + LZ4_memcpy(&v[2], srcPtr, 2); +#if defined(_MSC_VER) && (_MSC_VER <= 1933) /* MSVC 2022 ver 17.3 or earlier */ +# pragma warning(push) +# pragma warning(disable : 6385) /* warning C6385: Reading invalid data from 'v'. */ +#endif + LZ4_memcpy(&v[4], v, 4); +#if defined(_MSC_VER) && (_MSC_VER <= 1933) /* MSVC 2022 ver 17.3 or earlier */ +# pragma warning(pop) +#endif + break; + case 4: + LZ4_memcpy(v, srcPtr, 4); + LZ4_memcpy(&v[4], srcPtr, 4); + break; + default: + LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset); + return; + } + + LZ4_memcpy(dstPtr, v, 8); + dstPtr += 8; + while (dstPtr < dstEnd) { + LZ4_memcpy(dstPtr, v, 8); + dstPtr += 8; + } +} +#endif + + +/*-************************************ +* Common functions +**************************************/ +LZ4_FORCE_INLINE unsigned LZ4_NbCommonBytes (reg_t val) +{ + assert(val != 0); + if (LZ4_isLittleEndian()) { + if (sizeof(val) == 8) { +# if defined(_MSC_VER) && (_MSC_VER >= 1800) && (defined(_M_AMD64) && !defined(_M_ARM64EC)) && !defined(LZ4_FORCE_SW_BITCOUNT) +/*-************************************************************************************************* +* ARM64EC is a Microsoft-designed ARM64 ABI compatible with AMD64 applications on ARM64 Windows 11. +* The ARM64EC ABI does not support AVX/AVX2/AVX512 instructions, nor their relevant intrinsics +* including _tzcnt_u64. Therefore, we need to neuter the _tzcnt_u64 code path for ARM64EC. +****************************************************************************************************/ +# if defined(__clang__) && (__clang_major__ < 10) + /* Avoid undefined clang-cl intrinsics issue. + * See https://github.com/lz4/lz4/pull/1017 for details. */ + return (unsigned)__builtin_ia32_tzcnt_u64(val) >> 3; +# else + /* x64 CPUS without BMI support interpret `TZCNT` as `REP BSF` */ + return (unsigned)_tzcnt_u64(val) >> 3; +# endif +# elif defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanForward64(&r, (U64)val); + return (unsigned)r >> 3; +# elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ + !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_ctzll((U64)val) >> 3; +# else + const U64 m = 0x0101010101010101ULL; + val ^= val - 1; + return (unsigned)(((U64)((val & (m - 1)) * m)) >> 56); +# endif + } else /* 32 bits */ { +# if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r; + _BitScanForward(&r, (U32)val); + return (unsigned)r >> 3; +# elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ + !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_ctz((U32)val) >> 3; +# else + const U32 m = 0x01010101; + return (unsigned)((((val - 1) ^ val) & (m - 1)) * m) >> 24; +# endif + } + } else /* Big Endian CPU */ { + if (sizeof(val)==8) { +# if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ + !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_clzll((U64)val) >> 3; +# else +#if 1 + /* this method is probably faster, + * but adds a 128 bytes lookup table */ + static const unsigned char ctz7_tab[128] = { + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + }; + U64 const mask = 0x0101010101010101ULL; + U64 const t = (((val >> 8) - mask) | val) & mask; + return ctz7_tab[(t * 0x0080402010080402ULL) >> 57]; +#else + /* this method doesn't consume memory space like the previous one, + * but it contains several branches, + * that may end up slowing execution */ + static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits. + Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. + Note that this code path is never triggered in 32-bits mode. */ + unsigned r; + if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; } + if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } + r += (!val); + return r; +#endif +# endif + } else /* 32 bits */ { +# if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ + !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_clz((U32)val) >> 3; +# else + val >>= 8; + val = ((((val + 0x00FFFF00) | 0x00FFFFFF) + val) | + (val + 0x00FF0000)) >> 24; + return (unsigned)val ^ 3; +# endif + } + } +} + + +#define STEPSIZE sizeof(reg_t) +LZ4_FORCE_INLINE +unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) +{ + const BYTE* const pStart = pIn; + + if (likely(pIn < pInLimit-(STEPSIZE-1))) { + reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); + if (!diff) { + pIn+=STEPSIZE; pMatch+=STEPSIZE; + } else { + return LZ4_NbCommonBytes(diff); + } } + + while (likely(pIn < pInLimit-(STEPSIZE-1))) { + reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); + if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; } + pIn += LZ4_NbCommonBytes(diff); + return (unsigned)(pIn - pStart); + } + + if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } + if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; } + if ((pIn compression run slower on incompressible data */ + + +/*-************************************ +* Local Structures and types +**************************************/ +typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t; + +/** + * This enum distinguishes several different modes of accessing previous + * content in the stream. + * + * - noDict : There is no preceding content. + * - withPrefix64k : Table entries up to ctx->dictSize before the current blob + * blob being compressed are valid and refer to the preceding + * content (of length ctx->dictSize), which is available + * contiguously preceding in memory the content currently + * being compressed. + * - usingExtDict : Like withPrefix64k, but the preceding content is somewhere + * else in memory, starting at ctx->dictionary with length + * ctx->dictSize. + * - usingDictCtx : Everything concerning the preceding content is + * in a separate context, pointed to by ctx->dictCtx. + * ctx->dictionary, ctx->dictSize, and table entries + * in the current context that refer to positions + * preceding the beginning of the current compression are + * ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx + * ->dictSize describe the location and size of the preceding + * content, and matches are found by looking in the ctx + * ->dictCtx->hashTable. + */ +typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive; +typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; + + +/*-************************************ +* Local Utils +**************************************/ +int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } +const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } +int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } +int LZ4_sizeofState(void) { return sizeof(LZ4_stream_t); } + + +/*-**************************************** +* Internal Definitions, used only in Tests +*******************************************/ + +int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize); + +int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, + int compressedSize, int maxOutputSize, + const void* dictStart, size_t dictSize); +int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, + int compressedSize, int targetOutputSize, int dstCapacity, + const void* dictStart, size_t dictSize); + +/*-****************************** +* Compression functions +********************************/ +LZ4_FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType) +{ + if (tableType == byU16) + return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + else + return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); +} + +LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType) +{ + const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; + if (LZ4_isLittleEndian()) { + const U64 prime5bytes = 889523592379ULL; + return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); + } else { + const U64 prime8bytes = 11400714785074694791ULL; + return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); + } +} + +LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) +{ + if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); + return LZ4_hash4(LZ4_read32(p), tableType); +} + +LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) +{ + switch (tableType) + { + default: /* fallthrough */ + case clearedTable: { /* illegal! */ assert(0); return; } + case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = NULL; return; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 0; return; } + case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 0; return; } + } +} + +LZ4_FORCE_INLINE void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) +{ + switch (tableType) + { + default: /* fallthrough */ + case clearedTable: /* fallthrough */ + case byPtr: { /* illegal! */ assert(0); return; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = idx; return; } + case byU16: { U16* hashTable = (U16*) tableBase; assert(idx < 65536); hashTable[h] = (U16)idx; return; } + } +} + +LZ4_FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, + void* tableBase, tableType_t const tableType, + const BYTE* srcBase) +{ + switch (tableType) + { + case clearedTable: { /* illegal! */ assert(0); return; } + case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } + case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } + } +} + +LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + U32 const h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); +} + +/* LZ4_getIndexOnHash() : + * Index of match position registered in hash table. + * hash position must be calculated by using base+index, or dictBase+index. + * Assumption 1 : only valid if tableType == byU32 or byU16. + * Assumption 2 : h is presumed valid (within limits of hash table) + */ +LZ4_FORCE_INLINE U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType) +{ + LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2); + if (tableType == byU32) { + const U32* const hashTable = (const U32*) tableBase; + assert(h < (1U << (LZ4_MEMORY_USAGE-2))); + return hashTable[h]; + } + if (tableType == byU16) { + const U16* const hashTable = (const U16*) tableBase; + assert(h < (1U << (LZ4_MEMORY_USAGE-1))); + return hashTable[h]; + } + assert(0); return 0; /* forbidden case */ +} + +static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + if (tableType == byPtr) { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; } + if (tableType == byU32) { const U32* const hashTable = (const U32*) tableBase; return hashTable[h] + srcBase; } + { const U16* const hashTable = (const U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ +} + +LZ4_FORCE_INLINE const BYTE* +LZ4_getPosition(const BYTE* p, + const void* tableBase, tableType_t tableType, + const BYTE* srcBase) +{ + U32 const h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); +} + +LZ4_FORCE_INLINE void +LZ4_prepareTable(LZ4_stream_t_internal* const cctx, + const int inputSize, + const tableType_t tableType) { + /* If the table hasn't been used, it's guaranteed to be zeroed out, and is + * therefore safe to use no matter what mode we're in. Otherwise, we figure + * out if it's safe to leave as is or whether it needs to be reset. + */ + if ((tableType_t)cctx->tableType != clearedTable) { + assert(inputSize >= 0); + if ((tableType_t)cctx->tableType != tableType + || ((tableType == byU16) && cctx->currentOffset + (unsigned)inputSize >= 0xFFFFU) + || ((tableType == byU32) && cctx->currentOffset > 1 GB) + || tableType == byPtr + || inputSize >= 4 KB) + { + DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx); + MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE); + cctx->currentOffset = 0; + cctx->tableType = (U32)clearedTable; + } else { + DEBUGLOG(4, "LZ4_prepareTable: Re-use hash table (no reset)"); + } + } + + /* Adding a gap, so all previous entries are > LZ4_DISTANCE_MAX back, + * is faster than compressing without a gap. + * However, compressing with currentOffset == 0 is faster still, + * so we preserve that case. + */ + if (cctx->currentOffset != 0 && tableType == byU32) { + DEBUGLOG(5, "LZ4_prepareTable: adding 64KB to currentOffset"); + cctx->currentOffset += 64 KB; + } + + /* Finally, clear history */ + cctx->dictCtx = NULL; + cctx->dictionary = NULL; + cctx->dictSize = 0; +} + +/** LZ4_compress_generic() : + * inlined, to ensure branches are decided at compilation time. + * Presumed already validated at this stage: + * - source != NULL + * - inputSize > 0 + */ +LZ4_FORCE_INLINE int LZ4_compress_generic_validated( + LZ4_stream_t_internal* const cctx, + const char* const source, + char* const dest, + const int inputSize, + int* inputConsumed, /* only written when outputDirective == fillOutput */ + const int maxOutputSize, + const limitedOutput_directive outputDirective, + const tableType_t tableType, + const dict_directive dictDirective, + const dictIssue_directive dictIssue, + const int acceleration) +{ + int result; + const BYTE* ip = (const BYTE*) source; + + U32 const startIndex = cctx->currentOffset; + const BYTE* base = (const BYTE*) source - startIndex; + const BYTE* lowLimit; + + const LZ4_stream_t_internal* dictCtx = (const LZ4_stream_t_internal*) cctx->dictCtx; + const BYTE* const dictionary = + dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary; + const U32 dictSize = + dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize; + const U32 dictDelta = (dictDirective == usingDictCtx) ? startIndex - dictCtx->currentOffset : 0; /* make indexes in dictCtx comparable with index in current context */ + + int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx); + U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */ + const BYTE* const dictEnd = dictionary ? dictionary + dictSize : dictionary; + const BYTE* anchor = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1; + const BYTE* const matchlimit = iend - LASTLITERALS; + + /* the dictCtx currentOffset is indexed on the start of the dictionary, + * while a dictionary in the current context precedes the currentOffset */ + const BYTE* dictBase = (dictionary == NULL) ? NULL : + (dictDirective == usingDictCtx) ? + dictionary + dictSize - dictCtx->currentOffset : + dictionary + dictSize - startIndex; + + BYTE* op = (BYTE*) dest; + BYTE* const olimit = op + maxOutputSize; + + U32 offset = 0; + U32 forwardH; + + DEBUGLOG(5, "LZ4_compress_generic_validated: srcSize=%i, tableType=%u", inputSize, tableType); + assert(ip != NULL); + /* If init conditions are not met, we don't have to mark stream + * as having dirty context, since no action was taken yet */ + if (outputDirective == fillOutput && maxOutputSize < 1) { return 0; } /* Impossible to store anything */ + if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) { return 0; } /* Size too large (not within 64K limit) */ + if (tableType==byPtr) assert(dictDirective==noDict); /* only supported use case with byPtr */ + assert(acceleration >= 1); + + lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0); + + /* Update context state */ + if (dictDirective == usingDictCtx) { + /* Subsequent linked blocks can't use the dictionary. */ + /* Instead, they use the block we just compressed. */ + cctx->dictCtx = NULL; + cctx->dictSize = (U32)inputSize; + } else { + cctx->dictSize += (U32)inputSize; + } + cctx->currentOffset += (U32)inputSize; + cctx->tableType = (U32)tableType; + + if (inputSizehashTable, tableType, base); + ip++; forwardH = LZ4_hashPosition(ip, tableType); + + /* Main Loop */ + for ( ; ; ) { + const BYTE* match; + BYTE* token; + const BYTE* filledIp; + + /* Find a match */ + if (tableType == byPtr) { + const BYTE* forwardIp = ip; + int step = 1; + int searchMatchNb = acceleration << LZ4_skipTrigger; + do { + U32 const h = forwardH; + ip = forwardIp; + forwardIp += step; + step = (searchMatchNb++ >> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; + assert(ip < mflimitPlusOne); + + match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base); + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); + + } while ( (match+LZ4_DISTANCE_MAX < ip) + || (LZ4_read32(match) != LZ4_read32(ip)) ); + + } else { /* byU32, byU16 */ + + const BYTE* forwardIp = ip; + int step = 1; + int searchMatchNb = acceleration << LZ4_skipTrigger; + do { + U32 const h = forwardH; + U32 const current = (U32)(forwardIp - base); + U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); + assert(matchIndex <= current); + assert(forwardIp - base < (ptrdiff_t)(2 GB - 1)); + ip = forwardIp; + forwardIp += step; + step = (searchMatchNb++ >> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; + assert(ip < mflimitPlusOne); + + if (dictDirective == usingDictCtx) { + if (matchIndex < startIndex) { + /* there was no match, try the dictionary */ + assert(tableType == byU32); + matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); + match = dictBase + matchIndex; + matchIndex += dictDelta; /* make dictCtx index comparable with current context */ + lowLimit = dictionary; + } else { + match = base + matchIndex; + lowLimit = (const BYTE*)source; + } + } else if (dictDirective == usingExtDict) { + if (matchIndex < startIndex) { + DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex); + assert(startIndex - matchIndex >= MINMATCH); + assert(dictBase); + match = dictBase + matchIndex; + lowLimit = dictionary; + } else { + match = base + matchIndex; + lowLimit = (const BYTE*)source; + } + } else { /* single continuous memory segment */ + match = base + matchIndex; + } + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); + + DEBUGLOG(7, "candidate at pos=%u (offset=%u \n", matchIndex, current - matchIndex); + if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) { continue; } /* match outside of valid area */ + assert(matchIndex < current); + if ( ((tableType != byU16) || (LZ4_DISTANCE_MAX < LZ4_DISTANCE_ABSOLUTE_MAX)) + && (matchIndex+LZ4_DISTANCE_MAX < current)) { + continue; + } /* too far */ + assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* match now expected within distance */ + + if (LZ4_read32(match) == LZ4_read32(ip)) { + if (maybe_extMem) offset = current - matchIndex; + break; /* match found */ + } + + } while(1); + } + + /* Catch up */ + filledIp = ip; + while (((ip>anchor) & (match > lowLimit)) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } + + /* Encode Literals */ + { unsigned const litLength = (unsigned)(ip - anchor); + token = op++; + if ((outputDirective == limitedOutput) && /* Check output buffer overflow */ + (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) ) { + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + if ((outputDirective == fillOutput) && + (unlikely(op + (litLength+240)/255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) { + op--; + goto _last_literals; + } + if (litLength >= RUN_MASK) { + int len = (int)(litLength - RUN_MASK); + *token = (RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(litLength< olimit)) { + /* the match was too close to the end, rewind and go to last literals */ + op = token; + goto _last_literals; + } + + /* Encode Offset */ + if (maybe_extMem) { /* static test */ + DEBUGLOG(6, " with offset=%u (ext if > %i)", offset, (int)(ip - (const BYTE*)source)); + assert(offset <= LZ4_DISTANCE_MAX && offset > 0); + LZ4_writeLE16(op, (U16)offset); op+=2; + } else { + DEBUGLOG(6, " with offset=%u (same segment)", (U32)(ip - match)); + assert(ip-match <= LZ4_DISTANCE_MAX); + LZ4_writeLE16(op, (U16)(ip - match)); op+=2; + } + + /* Encode MatchLength */ + { unsigned matchCode; + + if ( (dictDirective==usingExtDict || dictDirective==usingDictCtx) + && (lowLimit==dictionary) /* match within extDict */ ) { + const BYTE* limit = ip + (dictEnd-match); + assert(dictEnd > match); + if (limit > matchlimit) limit = matchlimit; + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + ip += (size_t)matchCode + MINMATCH; + if (ip==limit) { + unsigned const more = LZ4_count(limit, (const BYTE*)source, matchlimit); + matchCode += more; + ip += more; + } + DEBUGLOG(6, " with matchLength=%u starting in extDict", matchCode+MINMATCH); + } else { + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + ip += (size_t)matchCode + MINMATCH; + DEBUGLOG(6, " with matchLength=%u", matchCode+MINMATCH); + } + + if ((outputDirective) && /* Check output buffer overflow */ + (unlikely(op + (1 + LASTLITERALS) + (matchCode+240)/255 > olimit)) ) { + if (outputDirective == fillOutput) { + /* Match description too long : reduce it */ + U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; + ip -= matchCode - newMatchCode; + assert(newMatchCode < matchCode); + matchCode = newMatchCode; + if (unlikely(ip <= filledIp)) { + /* We have already filled up to filledIp so if ip ends up less than filledIp + * we have positions in the hash table beyond the current position. This is + * a problem if we reuse the hash table. So we have to remove these positions + * from the hash table. + */ + const BYTE* ptr; + DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip)); + for (ptr = ip; ptr <= filledIp; ++ptr) { + U32 const h = LZ4_hashPosition(ptr, tableType); + LZ4_clearHash(h, cctx->hashTable, tableType); + } + } + } else { + assert(outputDirective == limitedOutput); + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + } + if (matchCode >= ML_MASK) { + *token += ML_MASK; + matchCode -= ML_MASK; + LZ4_write32(op, 0xFFFFFFFF); + while (matchCode >= 4*255) { + op+=4; + LZ4_write32(op, 0xFFFFFFFF); + matchCode -= 4*255; + } + op += matchCode / 255; + *op++ = (BYTE)(matchCode % 255); + } else + *token += (BYTE)(matchCode); + } + /* Ensure we have enough space for the last literals. */ + assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit)); + + anchor = ip; + + /* Test end of chunk */ + if (ip >= mflimitPlusOne) break; + + /* Fill table */ + LZ4_putPosition(ip-2, cctx->hashTable, tableType, base); + + /* Test next position */ + if (tableType == byPtr) { + + match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); + LZ4_putPosition(ip, cctx->hashTable, tableType, base); + if ( (match+LZ4_DISTANCE_MAX >= ip) + && (LZ4_read32(match) == LZ4_read32(ip)) ) + { token=op++; *token=0; goto _next_match; } + + } else { /* byU32, byU16 */ + + U32 const h = LZ4_hashPosition(ip, tableType); + U32 const current = (U32)(ip-base); + U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); + assert(matchIndex < current); + if (dictDirective == usingDictCtx) { + if (matchIndex < startIndex) { + /* there was no match, try the dictionary */ + matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); + match = dictBase + matchIndex; + lowLimit = dictionary; /* required for match length counter */ + matchIndex += dictDelta; + } else { + match = base + matchIndex; + lowLimit = (const BYTE*)source; /* required for match length counter */ + } + } else if (dictDirective==usingExtDict) { + if (matchIndex < startIndex) { + assert(dictBase); + match = dictBase + matchIndex; + lowLimit = dictionary; /* required for match length counter */ + } else { + match = base + matchIndex; + lowLimit = (const BYTE*)source; /* required for match length counter */ + } + } else { /* single memory segment */ + match = base + matchIndex; + } + LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); + assert(matchIndex < current); + if ( ((dictIssue==dictSmall) ? (matchIndex >= prefixIdxLimit) : 1) + && (((tableType==byU16) && (LZ4_DISTANCE_MAX == LZ4_DISTANCE_ABSOLUTE_MAX)) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current)) + && (LZ4_read32(match) == LZ4_read32(ip)) ) { + token=op++; + *token=0; + if (maybe_extMem) offset = current - matchIndex; + DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", + (int)(anchor-(const BYTE*)source), 0, (int)(ip-(const BYTE*)source)); + goto _next_match; + } + } + + /* Prepare next loop */ + forwardH = LZ4_hashPosition(++ip, tableType); + + } + +_last_literals: + /* Encode Last Literals */ + { size_t lastRun = (size_t)(iend - anchor); + if ( (outputDirective) && /* Check output buffer overflow */ + (op + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > olimit)) { + if (outputDirective == fillOutput) { + /* adapt lastRun to fill 'dst' */ + assert(olimit >= op); + lastRun = (size_t)(olimit-op) - 1/*token*/; + lastRun -= (lastRun + 256 - RUN_MASK) / 256; /*additional length tokens*/ + } else { + assert(outputDirective == limitedOutput); + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + } + DEBUGLOG(6, "Final literal run : %i literals", (int)lastRun); + if (lastRun >= RUN_MASK) { + size_t accumulator = lastRun - RUN_MASK; + *op++ = RUN_MASK << ML_BITS; + for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRun< 0); + DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, result); + return result; +} + +/** LZ4_compress_generic() : + * inlined, to ensure branches are decided at compilation time; + * takes care of src == (NULL, 0) + * and forward the rest to LZ4_compress_generic_validated */ +LZ4_FORCE_INLINE int LZ4_compress_generic( + LZ4_stream_t_internal* const cctx, + const char* const src, + char* const dst, + const int srcSize, + int *inputConsumed, /* only written when outputDirective == fillOutput */ + const int dstCapacity, + const limitedOutput_directive outputDirective, + const tableType_t tableType, + const dict_directive dictDirective, + const dictIssue_directive dictIssue, + const int acceleration) +{ + DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, dstCapacity=%i", + srcSize, dstCapacity); + + if ((U32)srcSize > (U32)LZ4_MAX_INPUT_SIZE) { return 0; } /* Unsupported srcSize, too large (or negative) */ + if (srcSize == 0) { /* src == NULL supported if srcSize == 0 */ + if (outputDirective != notLimited && dstCapacity <= 0) return 0; /* no output, can't write anything */ + DEBUGLOG(5, "Generating an empty block"); + assert(outputDirective == notLimited || dstCapacity >= 1); + assert(dst != NULL); + dst[0] = 0; + if (outputDirective == fillOutput) { + assert (inputConsumed != NULL); + *inputConsumed = 0; + } + return 1; + } + assert(src != NULL); + + return LZ4_compress_generic_validated(cctx, src, dst, srcSize, + inputConsumed, /* only written into if outputDirective == fillOutput */ + dstCapacity, outputDirective, + tableType, dictDirective, dictIssue, acceleration); +} + + +int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) +{ + LZ4_stream_t_internal* const ctx = & LZ4_initStream(state, sizeof(LZ4_stream_t)) -> internal_donotuse; + assert(ctx != NULL); + if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; + if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; + if (maxOutputSize >= LZ4_compressBound(inputSize)) { + if (inputSize < LZ4_64Klimit) { + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, byU16, noDict, noDictIssue, acceleration); + } else { + const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + if (inputSize < LZ4_64Klimit) { + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + } else { + const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } +} + +/** + * LZ4_compress_fast_extState_fastReset() : + * A variant of LZ4_compress_fast_extState(). + * + * Using this variant avoids an expensive initialization step. It is only safe + * to call if the state buffer is known to be correctly initialized already + * (see comment in lz4.h on LZ4_resetStream_fast() for a definition of + * "correctly initialized"). + */ +int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration) +{ + LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse; + if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; + if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; + + if (dstCapacity >= LZ4_compressBound(srcSize)) { + if (srcSize < LZ4_64Klimit) { + const tableType_t tableType = byU16; + LZ4_prepareTable(ctx, srcSize, tableType); + if (ctx->currentOffset) { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, dictSmall, acceleration); + } else { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + LZ4_prepareTable(ctx, srcSize, tableType); + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + if (srcSize < LZ4_64Klimit) { + const tableType_t tableType = byU16; + LZ4_prepareTable(ctx, srcSize, tableType); + if (ctx->currentOffset) { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, dictSmall, acceleration); + } else { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } else { + const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + LZ4_prepareTable(ctx, srcSize, tableType); + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } +} + + +int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) +{ + int result; +#if (LZ4_HEAPMODE) + LZ4_stream_t* ctxPtr = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + if (ctxPtr == NULL) return 0; +#else + LZ4_stream_t ctx; + LZ4_stream_t* const ctxPtr = &ctx; +#endif + result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + +#if (LZ4_HEAPMODE) + FREEMEM(ctxPtr); +#endif + return result; +} + + +int LZ4_compress_default(const char* src, char* dst, int srcSize, int maxOutputSize) +{ + return LZ4_compress_fast(src, dst, srcSize, maxOutputSize, 1); +} + + +/* Note!: This function leaves the stream in an unclean/broken state! + * It is not safe to subsequently use the same state with a _fastReset() or + * _continue() call without resetting it. */ +static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) +{ + void* const s = LZ4_initStream(state, sizeof (*state)); + assert(s != NULL); (void)s; + + if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ + return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); + } else { + if (*srcSizePtr < LZ4_64Klimit) { + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, 1); + } else { + tableType_t const addrMode = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, 1); + } } +} + + +int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) +{ +#if (LZ4_HEAPMODE) + LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + if (ctx == NULL) return 0; +#else + LZ4_stream_t ctxBody; + LZ4_stream_t* ctx = &ctxBody; +#endif + + int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + +#if (LZ4_HEAPMODE) + FREEMEM(ctx); +#endif + return result; +} + + + +/*-****************************** +* Streaming functions +********************************/ + +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4_stream_t* LZ4_createStream(void) +{ + LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); + LZ4_STATIC_ASSERT(sizeof(LZ4_stream_t) >= sizeof(LZ4_stream_t_internal)); + DEBUGLOG(4, "LZ4_createStream %p", lz4s); + if (lz4s == NULL) return NULL; + LZ4_initStream(lz4s, sizeof(*lz4s)); + return lz4s; +} +#endif + +static size_t LZ4_stream_t_alignment(void) +{ +#if LZ4_ALIGN_TEST + typedef struct { char c; LZ4_stream_t t; } t_a; + return sizeof(t_a) - sizeof(LZ4_stream_t); +#else + return 1; /* effectively disabled */ +#endif +} + +LZ4_stream_t* LZ4_initStream (void* buffer, size_t size) +{ + DEBUGLOG(5, "LZ4_initStream"); + if (buffer == NULL) { return NULL; } + if (size < sizeof(LZ4_stream_t)) { return NULL; } + if (!LZ4_isAligned(buffer, LZ4_stream_t_alignment())) return NULL; + MEM_INIT(buffer, 0, sizeof(LZ4_stream_t_internal)); + return (LZ4_stream_t*)buffer; +} + +/* resetStream is now deprecated, + * prefer initStream() which is more general */ +void LZ4_resetStream (LZ4_stream_t* LZ4_stream) +{ + DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream); + MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t_internal)); +} + +void LZ4_resetStream_fast(LZ4_stream_t* ctx) { + LZ4_prepareTable(&(ctx->internal_donotuse), 0, byU32); +} + +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +int LZ4_freeStream (LZ4_stream_t* LZ4_stream) +{ + if (!LZ4_stream) return 0; /* support free on NULL */ + DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream); + FREEMEM(LZ4_stream); + return (0); +} +#endif + + +#define HASH_UNIT sizeof(reg_t) +int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +{ + LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse; + const tableType_t tableType = byU32; + const BYTE* p = (const BYTE*)dictionary; + const BYTE* const dictEnd = p + dictSize; + const BYTE* base; + + DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict); + + /* It's necessary to reset the context, + * and not just continue it with prepareTable() + * to avoid any risk of generating overflowing matchIndex + * when compressing using this dictionary */ + LZ4_resetStream(LZ4_dict); + + /* We always increment the offset by 64 KB, since, if the dict is longer, + * we truncate it to the last 64k, and if it's shorter, we still want to + * advance by a whole window length so we can provide the guarantee that + * there are only valid offsets in the window, which allows an optimization + * in LZ4_compress_fast_continue() where it uses noDictIssue even when the + * dictionary isn't a full 64k. */ + dict->currentOffset += 64 KB; + + if (dictSize < (int)HASH_UNIT) { + return 0; + } + + if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; + base = dictEnd - dict->currentOffset; + dict->dictionary = p; + dict->dictSize = (U32)(dictEnd - p); + dict->tableType = (U32)tableType; + + while (p <= dictEnd-HASH_UNIT) { + LZ4_putPosition(p, dict->hashTable, tableType, base); + p+=3; + } + + return (int)dict->dictSize; +} + +void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) +{ + const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL : + &(dictionaryStream->internal_donotuse); + + DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)", + workingStream, dictionaryStream, + dictCtx != NULL ? dictCtx->dictSize : 0); + + if (dictCtx != NULL) { + /* If the current offset is zero, we will never look in the + * external dictionary context, since there is no value a table + * entry can take that indicate a miss. In that case, we need + * to bump the offset to something non-zero. + */ + if (workingStream->internal_donotuse.currentOffset == 0) { + workingStream->internal_donotuse.currentOffset = 64 KB; + } + + /* Don't actually attach an empty dictionary. + */ + if (dictCtx->dictSize == 0) { + dictCtx = NULL; + } + } + workingStream->internal_donotuse.dictCtx = dictCtx; +} + + +static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, int nextSize) +{ + assert(nextSize >= 0); + if (LZ4_dict->currentOffset + (unsigned)nextSize > 0x80000000) { /* potential ptrdiff_t overflow (32-bits mode) */ + /* rescale hash table */ + U32 const delta = LZ4_dict->currentOffset - 64 KB; + const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; + int i; + DEBUGLOG(4, "LZ4_renormDictT"); + for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; + else LZ4_dict->hashTable[i] -= delta; + } + LZ4_dict->currentOffset = 64 KB; + if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; + LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; + } +} + + +int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, + const char* source, char* dest, + int inputSize, int maxOutputSize, + int acceleration) +{ + const tableType_t tableType = byU32; + LZ4_stream_t_internal* const streamPtr = &LZ4_stream->internal_donotuse; + const char* dictEnd = streamPtr->dictSize ? (const char*)streamPtr->dictionary + streamPtr->dictSize : NULL; + + DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i, dictSize=%u)", inputSize, streamPtr->dictSize); + + LZ4_renormDictT(streamPtr, inputSize); /* fix index overflow */ + if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; + if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; + + /* invalidate tiny dictionaries */ + if ( (streamPtr->dictSize < 4) /* tiny dictionary : not enough for a hash */ + && (dictEnd != source) /* prefix mode */ + && (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */ + && (streamPtr->dictCtx == NULL) /* usingDictCtx */ + ) { + DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary); + /* remove dictionary existence from history, to employ faster prefix mode */ + streamPtr->dictSize = 0; + streamPtr->dictionary = (const BYTE*)source; + dictEnd = source; + } + + /* Check overlapping input/dictionary space */ + { const char* const sourceEnd = source + inputSize; + if ((sourceEnd > (const char*)streamPtr->dictionary) && (sourceEnd < dictEnd)) { + streamPtr->dictSize = (U32)(dictEnd - sourceEnd); + if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; + if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; + streamPtr->dictionary = (const BYTE*)dictEnd - streamPtr->dictSize; + } + } + + /* prefix mode : source data follows dictionary */ + if (dictEnd == source) { + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration); + else + return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration); + } + + /* external dictionary mode */ + { int result; + if (streamPtr->dictCtx) { + /* We depend here on the fact that dictCtx'es (produced by + * LZ4_loadDict) guarantee that their tables contain no references + * to offsets between dictCtx->currentOffset - 64 KB and + * dictCtx->currentOffset - dictCtx->dictSize. This makes it safe + * to use noDictIssue even when the dict isn't a full 64 KB. + */ + if (inputSize > 4 KB) { + /* For compressing large blobs, it is faster to pay the setup + * cost to copy the dictionary's tables into the active context, + * so that the compression loop is only looking into one table. + */ + LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(*streamPtr)); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration); + } + } else { /* small data <= 4 KB */ + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); + } + } + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + return result; + } +} + + +/* Hidden debug function, to force-test external dictionary mode */ +int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize) +{ + LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse; + int result; + + LZ4_renormDictT(streamPtr, srcSize); + + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { + result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, dictSmall, 1); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + } + + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)srcSize; + + return result; +} + + +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its memory location, + * save it into a safer place (char* safeBuffer). + * Note : no need to call LZ4_loadDict() afterwards, dictionary is immediately usable, + * one can therefore call LZ4_compress_fast_continue() right after. + * @return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. + */ +int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) +{ + LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; + + DEBUGLOG(5, "LZ4_saveDict : dictSize=%i, safeBuffer=%p", dictSize, safeBuffer); + + if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */ + if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } + + if (safeBuffer == NULL) assert(dictSize == 0); + if (dictSize > 0) { + const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; + assert(dict->dictionary); + LZ4_memmove(safeBuffer, previousDictEnd - dictSize, (size_t)dictSize); + } + + dict->dictionary = (const BYTE*)safeBuffer; + dict->dictSize = (U32)dictSize; + + return dictSize; +} + + + +/*-******************************* + * Decompression functions + ********************************/ + +typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive; + +#undef MIN +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) + + +/* variant for decompress_unsafe() + * does not know end of input + * presumes input is well formed + * note : will consume at least one byte */ +size_t read_long_length_no_check(const BYTE** pp) +{ + size_t b, l = 0; + do { b = **pp; (*pp)++; l += b; } while (b==255); + DEBUGLOG(6, "read_long_length_no_check: +length=%zu using %zu input bytes", l, l/255 + 1) + return l; +} + +/* core decoder variant for LZ4_decompress_fast*() + * for legacy support only : these entry points are deprecated. + * - Presumes input is correctly formed (no defense vs malformed inputs) + * - Does not know input size (presume input buffer is "large enough") + * - Decompress a full block (only) + * @return : nb of bytes read from input. + * Note : this variant is not optimized for speed, just for maintenance. + * the goal is to remove support of decompress_fast*() variants by v2.0 +**/ +LZ4_FORCE_INLINE int +LZ4_decompress_unsafe_generic( + const BYTE* const istart, + BYTE* const ostart, + int decompressedSize, + + size_t prefixSize, + const BYTE* const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note: =0 if dictStart==NULL */ + ) +{ + const BYTE* ip = istart; + BYTE* op = (BYTE*)ostart; + BYTE* const oend = ostart + decompressedSize; + const BYTE* const prefixStart = ostart - prefixSize; + + DEBUGLOG(5, "LZ4_decompress_unsafe_generic"); + if (dictStart == NULL) assert(dictSize == 0); + + while (1) { + /* start new sequence */ + unsigned token = *ip++; + + /* literals */ + { size_t ll = token >> ML_BITS; + if (ll==15) { + /* long literal length */ + ll += read_long_length_no_check(&ip); + } + if ((size_t)(oend-op) < ll) return -1; /* output buffer overflow */ + LZ4_memmove(op, ip, ll); /* support in-place decompression */ + op += ll; + ip += ll; + if ((size_t)(oend-op) < MFLIMIT) { + if (op==oend) break; /* end of block */ + DEBUGLOG(5, "invalid: literals end at distance %zi from end of block", oend-op); + /* incorrect end of block : + * last match must start at least MFLIMIT==12 bytes before end of output block */ + return -1; + } } + + /* match */ + { size_t ml = token & 15; + size_t const offset = LZ4_readLE16(ip); + ip+=2; + + if (ml==15) { + /* long literal length */ + ml += read_long_length_no_check(&ip); + } + ml += MINMATCH; + + if ((size_t)(oend-op) < ml) return -1; /* output buffer overflow */ + + { const BYTE* match = op - offset; + + /* out of range */ + if (offset > (size_t)(op - prefixStart) + dictSize) { + DEBUGLOG(6, "offset out of range"); + return -1; + } + + /* check special case : extDict */ + if (offset > (size_t)(op - prefixStart)) { + /* extDict scenario */ + const BYTE* const dictEnd = dictStart + dictSize; + const BYTE* extMatch = dictEnd - (offset - (size_t)(op-prefixStart)); + size_t const extml = (size_t)(dictEnd - extMatch); + if (extml > ml) { + /* match entirely within extDict */ + LZ4_memmove(op, extMatch, ml); + op += ml; + ml = 0; + } else { + /* match split between extDict & prefix */ + LZ4_memmove(op, extMatch, extml); + op += extml; + ml -= extml; + } + match = prefixStart; + } + + /* match copy - slow variant, supporting overlap copy */ + { size_t u; + for (u=0; u= ipmax before start of loop. Returns initial_error if so. + * @error (output) - error code. Must be set to 0 before call. +**/ +typedef size_t Rvl_t; +static const Rvl_t rvl_error = (Rvl_t)(-1); +LZ4_FORCE_INLINE Rvl_t +read_variable_length(const BYTE** ip, const BYTE* ilimit, + int initial_check) +{ + Rvl_t s, length = 0; + assert(ip != NULL); + assert(*ip != NULL); + assert(ilimit != NULL); + if (initial_check && unlikely((*ip) >= ilimit)) { /* read limit reached */ + return rvl_error; + } + do { + s = **ip; + (*ip)++; + length += s; + if (unlikely((*ip) > ilimit)) { /* read limit reached */ + return rvl_error; + } + /* accumulator overflow detection (32-bit mode only) */ + if ((sizeof(length)<8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { + return rvl_error; + } + } while (s==255); + + return length; +} + +/*! LZ4_decompress_generic() : + * This generic decompression function covers all use cases. + * It shall be instantiated several times, using different sets of directives. + * Note that it is important for performance that this function really get inlined, + * in order to remove useless branches during compilation optimization. + */ +LZ4_FORCE_INLINE int +LZ4_decompress_generic( + const char* const src, + char* const dst, + int srcSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */ + + earlyEnd_directive partialDecoding, /* full, partial */ + dict_directive dict, /* noDict, withPrefix64k, usingExtDict */ + const BYTE* const lowPrefix, /* always <= dst, == dst when no prefix */ + const BYTE* const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note : = 0 if noDict */ + ) +{ + if ((src == NULL) || (outputSize < 0)) { return -1; } + + { const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + + BYTE* op = (BYTE*) dst; + BYTE* const oend = op + outputSize; + BYTE* cpy; + + const BYTE* const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize; + + const int checkOffset = (dictSize < (int)(64 KB)); + + + /* Set up the "end" pointers for the shortcut. */ + const BYTE* const shortiend = iend - 14 /*maxLL*/ - 2 /*offset*/; + const BYTE* const shortoend = oend - 14 /*maxLL*/ - 18 /*maxML*/; + + const BYTE* match; + size_t offset; + unsigned token; + size_t length; + + + DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize); + + /* Special cases */ + assert(lowPrefix <= op); + if (unlikely(outputSize==0)) { + /* Empty output buffer */ + if (partialDecoding) return 0; + return ((srcSize==1) && (*ip==0)) ? 0 : -1; + } + if (unlikely(srcSize==0)) { return -1; } + + /* LZ4_FAST_DEC_LOOP: + * designed for modern OoO performance cpus, + * where copying reliably 32-bytes is preferable to an unpredictable branch. + * note : fast loop may show a regression for some client arm chips. */ +#if LZ4_FAST_DEC_LOOP + if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { + DEBUGLOG(6, "skip fast decode loop"); + goto safe_decode; + } + + /* Fast loop : decode sequences as long as output < oend-FASTLOOP_SAFE_DISTANCE */ + while (1) { + /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */ + assert(oend - op >= FASTLOOP_SAFE_DISTANCE); + assert(ip < iend); + token = *ip++; + length = token >> ML_BITS; /* literal length */ + + /* decode literal length */ + if (length == RUN_MASK) { + size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); + if (addl == rvl_error) { goto _output_error; } + length += addl; + if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ + if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ + + /* copy literals */ + cpy = op+length; + LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); + if ((cpy>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; } + LZ4_wildCopy32(op, ip, cpy); + ip += length; op = cpy; + } else { + cpy = op+length; + DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length); + /* We don't need to check oend, since we check it once for each loop below */ + if (ip > iend-(16 + 1/*max lit + offset + nextToken*/)) { goto safe_literal_copy; } + /* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */ + LZ4_memcpy(op, ip, 16); + ip += length; op = cpy; + } + + /* get offset */ + offset = LZ4_readLE16(ip); ip+=2; + match = op - offset; + assert(match <= op); /* overflow check */ + + /* get matchlength */ + length = token & ML_MASK; + + if (length == ML_MASK) { + size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); + if (addl == rvl_error) { goto _output_error; } + length += addl; + length += MINMATCH; + if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { + goto safe_match_copy; + } + } else { + length += MINMATCH; + if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { + goto safe_match_copy; + } + + /* Fastpath check: skip LZ4_wildCopy32 when true */ + if ((dict == withPrefix64k) || (match >= lowPrefix)) { + if (offset >= 8) { + assert(match >= lowPrefix); + assert(match <= op); + assert(op + 18 <= oend); + + LZ4_memcpy(op, match, 8); + LZ4_memcpy(op+8, match+8, 8); + LZ4_memcpy(op+16, match+16, 2); + op += length; + continue; + } } } + + if (checkOffset && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + /* match starting within external dictionary */ + if ((dict==usingExtDict) && (match < lowPrefix)) { + assert(dictEnd != NULL); + if (unlikely(op+length > oend-LASTLITERALS)) { + if (partialDecoding) { + DEBUGLOG(7, "partialDecoding: dictionary match, close to dstEnd"); + length = MIN(length, (size_t)(oend-op)); + } else { + goto _output_error; /* end-of-block condition violated */ + } } + + if (length <= (size_t)(lowPrefix-match)) { + /* match fits entirely within external dictionary : just copy */ + LZ4_memmove(op, dictEnd - (lowPrefix-match), length); + op += length; + } else { + /* match stretches into both external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix - match); + size_t const restSize = length - copySize; + LZ4_memcpy(op, dictEnd - copySize, copySize); + op += copySize; + if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ + BYTE* const endOfMatch = op + restSize; + const BYTE* copyFrom = lowPrefix; + while (op < endOfMatch) { *op++ = *copyFrom++; } + } else { + LZ4_memcpy(op, lowPrefix, restSize); + op += restSize; + } } + continue; + } + + /* copy match within block */ + cpy = op + length; + + assert((op <= oend) && (oend-op >= 32)); + if (unlikely(offset<16)) { + LZ4_memcpy_using_offset(op, match, cpy, offset); + } else { + LZ4_wildCopy32(op, match, cpy); + } + + op = cpy; /* wildcopy correction */ + } + safe_decode: +#endif + + /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */ + while (1) { + assert(ip < iend); + token = *ip++; + length = token >> ML_BITS; /* literal length */ + + /* A two-stage shortcut for the most common case: + * 1) If the literal length is 0..14, and there is enough space, + * enter the shortcut and copy 16 bytes on behalf of the literals + * (in the fast mode, only 8 bytes can be safely copied this way). + * 2) Further if the match length is 4..18, copy 18 bytes in a similar + * manner; but we ensure that there's enough space in the output for + * those 18 bytes earlier, upon entering the shortcut (in other words, + * there is a combined check for both stages). + */ + if ( (length != RUN_MASK) + /* strictly "less than" on input, to re-enter the loop with at least one byte */ + && likely((ip < shortiend) & (op <= shortoend)) ) { + /* Copy the literals */ + LZ4_memcpy(op, ip, 16); + op += length; ip += length; + + /* The second stage: prepare for match copying, decode full info. + * If it doesn't work out, the info won't be wasted. */ + length = token & ML_MASK; /* match length */ + offset = LZ4_readLE16(ip); ip += 2; + match = op - offset; + assert(match <= op); /* check overflow */ + + /* Do not deal with overlapping matches. */ + if ( (length != ML_MASK) + && (offset >= 8) + && (dict==withPrefix64k || match >= lowPrefix) ) { + /* Copy the match. */ + LZ4_memcpy(op + 0, match + 0, 8); + LZ4_memcpy(op + 8, match + 8, 8); + LZ4_memcpy(op +16, match +16, 2); + op += length + MINMATCH; + /* Both stages worked, load the next token. */ + continue; + } + + /* The second stage didn't work out, but the info is ready. + * Propel it right to the point of match copying. */ + goto _copy_match; + } + + /* decode literal length */ + if (length == RUN_MASK) { + size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); + if (addl == rvl_error) { goto _output_error; } + length += addl; + if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ + if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ + } + + /* copy literals */ + cpy = op+length; +#if LZ4_FAST_DEC_LOOP + safe_literal_copy: +#endif + LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); + if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) { + /* We've either hit the input parsing restriction or the output parsing restriction. + * In the normal scenario, decoding a full block, it must be the last sequence, + * otherwise it's an error (invalid input or dimensions). + * In partialDecoding scenario, it's necessary to ensure there is no buffer overflow. + */ + if (partialDecoding) { + /* Since we are partial decoding we may be in this block because of the output parsing + * restriction, which is not valid since the output buffer is allowed to be undersized. + */ + DEBUGLOG(7, "partialDecoding: copying literals, close to input or output end") + DEBUGLOG(7, "partialDecoding: literal length = %u", (unsigned)length); + DEBUGLOG(7, "partialDecoding: remaining space in dstBuffer : %i", (int)(oend - op)); + DEBUGLOG(7, "partialDecoding: remaining space in srcBuffer : %i", (int)(iend - ip)); + /* Finishing in the middle of a literals segment, + * due to lack of input. + */ + if (ip+length > iend) { + length = (size_t)(iend-ip); + cpy = op + length; + } + /* Finishing in the middle of a literals segment, + * due to lack of output space. + */ + if (cpy > oend) { + cpy = oend; + assert(op<=oend); + length = (size_t)(oend-op); + } + } else { + /* We must be on the last sequence (or invalid) because of the parsing limitations + * so check that we exactly consume the input and don't overrun the output buffer. + */ + if ((ip+length != iend) || (cpy > oend)) { + DEBUGLOG(6, "should have been last run of literals") + DEBUGLOG(6, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); + DEBUGLOG(6, "or cpy(%p) > oend(%p)", cpy, oend); + goto _output_error; + } + } + LZ4_memmove(op, ip, length); /* supports overlapping memory regions, for in-place decompression scenarios */ + ip += length; + op += length; + /* Necessarily EOF when !partialDecoding. + * When partialDecoding, it is EOF if we've either + * filled the output buffer or + * can't proceed with reading an offset for following match. + */ + if (!partialDecoding || (cpy == oend) || (ip >= (iend-2))) { + break; + } + } else { + LZ4_wildCopy8(op, ip, cpy); /* can overwrite up to 8 bytes beyond cpy */ + ip += length; op = cpy; + } + + /* get offset */ + offset = LZ4_readLE16(ip); ip+=2; + match = op - offset; + + /* get matchlength */ + length = token & ML_MASK; + + _copy_match: + if (length == ML_MASK) { + size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); + if (addl == rvl_error) { goto _output_error; } + length += addl; + if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ + } + length += MINMATCH; + +#if LZ4_FAST_DEC_LOOP + safe_match_copy: +#endif + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ + /* match starting within external dictionary */ + if ((dict==usingExtDict) && (match < lowPrefix)) { + assert(dictEnd != NULL); + if (unlikely(op+length > oend-LASTLITERALS)) { + if (partialDecoding) length = MIN(length, (size_t)(oend-op)); + else goto _output_error; /* doesn't respect parsing restriction */ + } + + if (length <= (size_t)(lowPrefix-match)) { + /* match fits entirely within external dictionary : just copy */ + LZ4_memmove(op, dictEnd - (lowPrefix-match), length); + op += length; + } else { + /* match stretches into both external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix - match); + size_t const restSize = length - copySize; + LZ4_memcpy(op, dictEnd - copySize, copySize); + op += copySize; + if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ + BYTE* const endOfMatch = op + restSize; + const BYTE* copyFrom = lowPrefix; + while (op < endOfMatch) *op++ = *copyFrom++; + } else { + LZ4_memcpy(op, lowPrefix, restSize); + op += restSize; + } } + continue; + } + assert(match >= lowPrefix); + + /* copy match within block */ + cpy = op + length; + + /* partialDecoding : may end anywhere within the block */ + assert(op<=oend); + if (partialDecoding && (cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { + size_t const mlen = MIN(length, (size_t)(oend-op)); + const BYTE* const matchEnd = match + mlen; + BYTE* const copyEnd = op + mlen; + if (matchEnd > op) { /* overlap copy */ + while (op < copyEnd) { *op++ = *match++; } + } else { + LZ4_memcpy(op, match, mlen); + } + op = copyEnd; + if (op == oend) { break; } + continue; + } + + if (unlikely(offset<8)) { + LZ4_write32(op, 0); /* silence msan warning when offset==0 */ + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += inc32table[offset]; + LZ4_memcpy(op+4, match, 4); + match -= dec64table[offset]; + } else { + LZ4_memcpy(op, match, 8); + match += 8; + } + op += 8; + + if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { + BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1); + if (cpy > oend-LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ + if (op < oCopyLimit) { + LZ4_wildCopy8(op, match, oCopyLimit); + match += oCopyLimit - op; + op = oCopyLimit; + } + while (op < cpy) { *op++ = *match++; } + } else { + LZ4_memcpy(op, match, 8); + if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); } + } + op = cpy; /* wildcopy correction */ + } + + /* end of decoding */ + DEBUGLOG(5, "decoded %i bytes", (int) (((char*)op)-dst)); + return (int) (((char*)op)-dst); /* Nb of output bytes decoded */ + + /* Overflow error detected */ + _output_error: + return (int) (-(((const char*)ip)-src))-1; + } +} + + +/*===== Instantiate the API decoding functions. =====*/ + +LZ4_FORCE_O2 +int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, + decode_full_block, noDict, + (BYTE*)dest, NULL, 0); +} + +LZ4_FORCE_O2 +int LZ4_decompress_safe_partial(const char* src, char* dst, int compressedSize, int targetOutputSize, int dstCapacity) +{ + dstCapacity = MIN(targetOutputSize, dstCapacity); + return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity, + partial_decode, + noDict, (BYTE*)dst, NULL, 0); +} + +LZ4_FORCE_O2 +int LZ4_decompress_fast(const char* source, char* dest, int originalSize) +{ + DEBUGLOG(5, "LZ4_decompress_fast"); + return LZ4_decompress_unsafe_generic( + (const BYTE*)source, (BYTE*)dest, originalSize, + 0, NULL, 0); +} + +/*===== Instantiate a few more decoding cases, used more than once. =====*/ + +LZ4_FORCE_O2 /* Exported, an obsolete API function. */ +int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + decode_full_block, withPrefix64k, + (BYTE*)dest - 64 KB, NULL, 0); +} + +LZ4_FORCE_O2 +static int LZ4_decompress_safe_partial_withPrefix64k(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity) +{ + dstCapacity = MIN(targetOutputSize, dstCapacity); + return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, + partial_decode, withPrefix64k, + (BYTE*)dest - 64 KB, NULL, 0); +} + +/* Another obsolete API function, paired with the previous one. */ +int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) +{ + return LZ4_decompress_unsafe_generic( + (const BYTE*)source, (BYTE*)dest, originalSize, + 64 KB, NULL, 0); +} + +LZ4_FORCE_O2 +static int LZ4_decompress_safe_withSmallPrefix(const char* source, char* dest, int compressedSize, int maxOutputSize, + size_t prefixSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + decode_full_block, noDict, + (BYTE*)dest-prefixSize, NULL, 0); +} + +LZ4_FORCE_O2 +static int LZ4_decompress_safe_partial_withSmallPrefix(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, + size_t prefixSize) +{ + dstCapacity = MIN(targetOutputSize, dstCapacity); + return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, + partial_decode, noDict, + (BYTE*)dest-prefixSize, NULL, 0); +} + +LZ4_FORCE_O2 +int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, + int compressedSize, int maxOutputSize, + const void* dictStart, size_t dictSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + decode_full_block, usingExtDict, + (BYTE*)dest, (const BYTE*)dictStart, dictSize); +} + +LZ4_FORCE_O2 +int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, + int compressedSize, int targetOutputSize, int dstCapacity, + const void* dictStart, size_t dictSize) +{ + dstCapacity = MIN(targetOutputSize, dstCapacity); + return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, + partial_decode, usingExtDict, + (BYTE*)dest, (const BYTE*)dictStart, dictSize); +} + +LZ4_FORCE_O2 +static int LZ4_decompress_fast_extDict(const char* source, char* dest, int originalSize, + const void* dictStart, size_t dictSize) +{ + return LZ4_decompress_unsafe_generic( + (const BYTE*)source, (BYTE*)dest, originalSize, + 0, (const BYTE*)dictStart, dictSize); +} + +/* The "double dictionary" mode, for use with e.g. ring buffers: the first part + * of the dictionary is passed as prefix, and the second via dictStart + dictSize. + * These routines are used only once, in LZ4_decompress_*_continue(). + */ +LZ4_FORCE_INLINE +int LZ4_decompress_safe_doubleDict(const char* source, char* dest, int compressedSize, int maxOutputSize, + size_t prefixSize, const void* dictStart, size_t dictSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + decode_full_block, usingExtDict, + (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize); +} + +/*===== streaming decompression functions =====*/ + +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4_streamDecode_t* LZ4_createStreamDecode(void) +{ + LZ4_STATIC_ASSERT(sizeof(LZ4_streamDecode_t) >= sizeof(LZ4_streamDecode_t_internal)); + return (LZ4_streamDecode_t*) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t)); +} + +int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) +{ + if (LZ4_stream == NULL) { return 0; } /* support free on NULL */ + FREEMEM(LZ4_stream); + return 0; +} +#endif + +/*! LZ4_setStreamDecode() : + * Use this function to instruct where to find the dictionary. + * This function is not necessary if previous data is still available where it was decoded. + * Loading a size of 0 is allowed (same effect as no dictionary). + * @return : 1 if OK, 0 if error + */ +int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) +{ + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; + lz4sd->prefixSize = (size_t)dictSize; + if (dictSize) { + assert(dictionary != NULL); + lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; + } else { + lz4sd->prefixEnd = (const BYTE*) dictionary; + } + lz4sd->externalDict = NULL; + lz4sd->extDictSize = 0; + return 1; +} + +/*! LZ4_decoderRingBufferSize() : + * when setting a ring buffer for streaming decompression (optional scenario), + * provides the minimum size of this ring buffer + * to be compatible with any source respecting maxBlockSize condition. + * Note : in a ring buffer scenario, + * blocks are presumed decompressed next to each other. + * When not enough space remains for next block (remainingSize < maxBlockSize), + * decoding resumes from beginning of ring buffer. + * @return : minimum ring buffer size, + * or 0 if there is an error (invalid maxBlockSize). + */ +int LZ4_decoderRingBufferSize(int maxBlockSize) +{ + if (maxBlockSize < 0) return 0; + if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0; + if (maxBlockSize < 16) maxBlockSize = 16; + return LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize); +} + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks must still be available at the memory position where they were decoded. + If it's not possible, save the relevant part of decoded data into a safe buffer, + and indicate where it stands using LZ4_setStreamDecode() +*/ +LZ4_FORCE_O2 +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; + int result; + + if (lz4sd->prefixSize == 0) { + /* The first call, no dictionary yet. */ + assert(lz4sd->extDictSize == 0); + result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)result; + lz4sd->prefixEnd = (BYTE*)dest + result; + } else if (lz4sd->prefixEnd == (BYTE*)dest) { + /* They're rolling the current segment. */ + if (lz4sd->prefixSize >= 64 KB - 1) + result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); + else if (lz4sd->extDictSize == 0) + result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, + lz4sd->prefixSize); + else + result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize, + lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += (size_t)result; + lz4sd->prefixEnd += result; + } else { + /* The buffer wraps around, or they're switching to another buffer. */ + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, + lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)result; + lz4sd->prefixEnd = (BYTE*)dest + result; + } + + return result; +} + +LZ4_FORCE_O2 int +LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, + const char* source, char* dest, int originalSize) +{ + LZ4_streamDecode_t_internal* const lz4sd = + (assert(LZ4_streamDecode!=NULL), &LZ4_streamDecode->internal_donotuse); + int result; + + DEBUGLOG(5, "LZ4_decompress_fast_continue (toDecodeSize=%i)", originalSize); + assert(originalSize >= 0); + + if (lz4sd->prefixSize == 0) { + DEBUGLOG(5, "first invocation : no prefix nor extDict"); + assert(lz4sd->extDictSize == 0); + result = LZ4_decompress_fast(source, dest, originalSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)originalSize; + lz4sd->prefixEnd = (BYTE*)dest + originalSize; + } else if (lz4sd->prefixEnd == (BYTE*)dest) { + DEBUGLOG(5, "continue using existing prefix"); + result = LZ4_decompress_unsafe_generic( + (const BYTE*)source, (BYTE*)dest, originalSize, + lz4sd->prefixSize, + lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += (size_t)originalSize; + lz4sd->prefixEnd += originalSize; + } else { + DEBUGLOG(5, "prefix becomes extDict"); + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_fast_extDict(source, dest, originalSize, + lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)originalSize; + lz4sd->prefixEnd = (BYTE*)dest + originalSize; + } + + return result; +} + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as "_continue" ones, + the dictionary must be explicitly provided within parameters +*/ + +int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) +{ + if (dictSize==0) + return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); + if (dictStart+dictSize == dest) { + if (dictSize >= 64 KB - 1) { + return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (size_t)dictSize); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (size_t)dictSize); +} + +int LZ4_decompress_safe_partial_usingDict(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, const char* dictStart, int dictSize) +{ + if (dictSize==0) + return LZ4_decompress_safe_partial(source, dest, compressedSize, targetOutputSize, dstCapacity); + if (dictStart+dictSize == dest) { + if (dictSize >= 64 KB - 1) { + return LZ4_decompress_safe_partial_withPrefix64k(source, dest, compressedSize, targetOutputSize, dstCapacity); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_partial_withSmallPrefix(source, dest, compressedSize, targetOutputSize, dstCapacity, (size_t)dictSize); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_partial_forceExtDict(source, dest, compressedSize, targetOutputSize, dstCapacity, dictStart, (size_t)dictSize); +} + +int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) +{ + if (dictSize==0 || dictStart+dictSize == dest) + return LZ4_decompress_unsafe_generic( + (const BYTE*)source, (BYTE*)dest, originalSize, + (size_t)dictSize, NULL, 0); + assert(dictSize >= 0); + return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, (size_t)dictSize); +} + + +/*=************************************************* +* Obsolete Functions +***************************************************/ +/* obsolete compression functions */ +int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) +{ + return LZ4_compress_default(source, dest, inputSize, maxOutputSize); +} +int LZ4_compress(const char* src, char* dest, int srcSize) +{ + return LZ4_compress_default(src, dest, srcSize, LZ4_compressBound(srcSize)); +} +int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) +{ + return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); +} +int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) +{ + return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); +} +int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int dstCapacity) +{ + return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, dstCapacity, 1); +} +int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) +{ + return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); +} + +/* +These decompression functions are deprecated and should no longer be used. +They are only provided here for compatibility with older user programs. +- LZ4_uncompress is totally equivalent to LZ4_decompress_fast +- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe +*/ +int LZ4_uncompress (const char* source, char* dest, int outputSize) +{ + return LZ4_decompress_fast(source, dest, outputSize); +} +int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) +{ + return LZ4_decompress_safe(source, dest, isize, maxOutputSize); +} + +/* Obsolete Streaming functions */ + +int LZ4_sizeofStreamState(void) { return sizeof(LZ4_stream_t); } + +int LZ4_resetStreamState(void* state, char* inputBuffer) +{ + (void)inputBuffer; + LZ4_resetStream((LZ4_stream_t*)state); + return 0; +} + +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +void* LZ4_create (char* inputBuffer) +{ + (void)inputBuffer; + return LZ4_createStream(); +} +#endif + +char* LZ4_slideInputBuffer (void* state) +{ + /* avoid const char * -> char * conversion warning */ + return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary; +} + +#endif /* LZ4_COMMONDEFS_ONLY */ + +} diff --git a/Externals/tracy/public/common/tracy_lz4.hpp b/Externals/tracy/public/common/tracy_lz4.hpp new file mode 100644 index 00000000000..672c2feb247 --- /dev/null +++ b/Externals/tracy/public/common/tracy_lz4.hpp @@ -0,0 +1,847 @@ +/* + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-2020, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 +*/ + +#ifndef TRACY_LZ4_H_2983827168210 +#define TRACY_LZ4_H_2983827168210 + +/* --- Dependency --- */ +#include /* size_t */ +#include + + +/** + Introduction + + LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core, + scalable with multi-cores CPU. It features an extremely fast decoder, with speed in + multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. + + The LZ4 compression library provides in-memory compression and decompression functions. + It gives full buffer control to user. + Compression can be done in: + - a single step (described as Simple Functions) + - a single step, reusing a context (described in Advanced Functions) + - unbounded multiple steps (described as Streaming compression) + + lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md). + Decompressing such a compressed block requires additional metadata. + Exact metadata depends on exact decompression function. + For the typical case of LZ4_decompress_safe(), + metadata includes block's compressed size, and maximum bound of decompressed size. + Each application is free to encode and pass such metadata in whichever way it wants. + + lz4.h only handle blocks, it can not generate Frames. + + Blocks are different from Frames (doc/lz4_Frame_format.md). + Frames bundle both blocks and metadata in a specified manner. + Embedding metadata is required for compressed data to be self-contained and portable. + Frame format is delivered through a companion API, declared in lz4frame.h. + The `lz4` CLI can only manage frames. +*/ + +/*^*************************************************************** +* Export parameters +*****************************************************************/ +/* +* LZ4_DLL_EXPORT : +* Enable exporting of functions when building a Windows DLL +* LZ4LIB_VISIBILITY : +* Control library symbols visibility. +*/ +#ifndef LZ4LIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define LZ4LIB_VISIBILITY +# endif +#endif +#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) +# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY +#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) +# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define LZ4LIB_API LZ4LIB_VISIBILITY +#endif + +/*! LZ4_FREESTANDING : + * When this macro is set to 1, it enables "freestanding mode" that is + * suitable for typical freestanding environment which doesn't support + * standard C library. + * + * - LZ4_FREESTANDING is a compile-time switch. + * - It requires the following macros to be defined: + * LZ4_memcpy, LZ4_memmove, LZ4_memset. + * - It only enables LZ4/HC functions which don't use heap. + * All LZ4F_* functions are not supported. + * - See tests/freestanding.c to check its basic setup. + */ +#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1) +# define LZ4_HEAPMODE 0 +# define LZ4HC_HEAPMODE 0 +# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1 +# if !defined(LZ4_memcpy) +# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'." +# endif +# if !defined(LZ4_memset) +# error "LZ4_FREESTANDING requires macro 'LZ4_memset'." +# endif +# if !defined(LZ4_memmove) +# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'." +# endif +#elif ! defined(LZ4_FREESTANDING) +# define LZ4_FREESTANDING 0 +#endif + + +/*------ Version ------*/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */ + +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) + +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str +#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */ + +namespace tracy +{ + +LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */ +LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */ + + +/*-************************************ +* Tuning parameter +**************************************/ +#define LZ4_MEMORY_USAGE_MIN 10 +#define LZ4_MEMORY_USAGE_DEFAULT 14 +#define LZ4_MEMORY_USAGE_MAX 20 + +/*! + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; ) + * Increasing memory usage improves compression ratio, at the cost of speed. + * Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality. + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +#ifndef LZ4_MEMORY_USAGE +# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT +#endif + +#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN) +# error "LZ4_MEMORY_USAGE is too small !" +#endif + +#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX) +# error "LZ4_MEMORY_USAGE is too large !" +#endif + +/*-************************************ +* Simple Functions +**************************************/ +/*! LZ4_compress_default() : + * Compresses 'srcSize' bytes from buffer 'src' + * into already allocated 'dst' buffer of size 'dstCapacity'. + * Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). + * It also runs faster, so it's a recommended setting. + * If the function cannot compress 'src' into a more limited 'dst' budget, + * compression stops *immediately*, and the function result is zero. + * In which case, 'dst' content is undefined (invalid). + * srcSize : max supported value is LZ4_MAX_INPUT_SIZE. + * dstCapacity : size of buffer 'dst' (which must be already allocated) + * @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) + * or 0 if compression fails + * Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer). + */ +LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); + +/*! LZ4_decompress_safe() : + * compressedSize : is the exact complete size of the compressed block. + * dstCapacity : is the size of destination buffer (which must be already allocated), presumed an upper bound of decompressed size. + * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) + * If destination buffer is not large enough, decoding will stop and output an error code (negative value). + * If the source stream is detected malformed, the function will stop decoding and return a negative result. + * Note 1 : This function is protected against malicious data packets : + * it will never writes outside 'dst' buffer, nor read outside 'source' buffer, + * even if the compressed block is maliciously modified to order the decoder to do these actions. + * In such case, the decoder stops immediately, and considers the compressed block malformed. + * Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them. + * The implementation is free to send / store / derive this information in whichever way is most beneficial. + * If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead. + */ +LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity); + + +/*-************************************ +* Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/*! LZ4_compressBound() : + Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) + This function is primarily useful for memory allocation purposes (destination buffer size). + Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). + Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize) + inputSize : max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is incorrect (too large or negative) +*/ +LZ4LIB_API int LZ4_compressBound(int inputSize); + +/*! LZ4_compress_fast() : + Same as LZ4_compress_default(), but allows selection of "acceleration" factor. + The larger the acceleration value, the faster the algorithm, but also the lesser the compression. + It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. + An acceleration value of "1" is the same as regular LZ4_compress_default() + Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c). + Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c). +*/ +LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_fast_extState() : + * Same as LZ4_compress_fast(), using an externally allocated memory space for its state. + * Use LZ4_sizeofState() to know how much memory must be allocated, + * and allocate it on 8-bytes boundaries (using `malloc()` typically). + * Then, provide this buffer as `void* state` to compression function. + */ +LZ4LIB_API int LZ4_sizeofState(void); +LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_destSize() : + * Reverse the logic : compresses as much data as possible from 'src' buffer + * into already allocated buffer 'dst', of size >= 'targetDestSize'. + * This function either compresses the entire 'src' content into 'dst' if it's large enough, + * or fill 'dst' buffer completely with as much data as possible from 'src'. + * note: acceleration parameter is fixed to "default". + * + * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. + * New value is necessarily <= input value. + * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize) + * or 0 if compression fails. + * + * Note : from v1.8.2 to v1.9.1, this function had a bug (fixed un v1.9.2+): + * the produced compressed content could, in specific circumstances, + * require to be decompressed into a destination buffer larger + * by at least 1 byte than the content to decompress. + * If an application uses `LZ4_compress_destSize()`, + * it's highly recommended to update liblz4 to v1.9.2 or better. + * If this can't be done or ensured, + * the receiving decompression function should provide + * a dstCapacity which is > decompressedSize, by at least 1 byte. + * See https://github.com/lz4/lz4/issues/859 for details + */ +LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize); + + +/*! LZ4_decompress_safe_partial() : + * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', + * into destination buffer 'dst' of size 'dstCapacity'. + * Up to 'targetOutputSize' bytes will be decoded. + * The function stops decoding on reaching this objective. + * This can be useful to boost performance + * whenever only the beginning of a block is required. + * + * @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize) + * If source stream is detected malformed, function returns a negative result. + * + * Note 1 : @return can be < targetOutputSize, if compressed block contains less data. + * + * Note 2 : targetOutputSize must be <= dstCapacity + * + * Note 3 : this function effectively stops decoding on reaching targetOutputSize, + * so dstCapacity is kind of redundant. + * This is because in older versions of this function, + * decoding operation would still write complete sequences. + * Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize, + * it could write more bytes, though only up to dstCapacity. + * Some "margin" used to be required for this operation to work properly. + * Thankfully, this is no longer necessary. + * The function nonetheless keeps the same signature, in an effort to preserve API compatibility. + * + * Note 4 : If srcSize is the exact size of the block, + * then targetOutputSize can be any value, + * including larger than the block's decompressed size. + * The function will, at most, generate block's decompressed size. + * + * Note 5 : If srcSize is _larger_ than block's compressed size, + * then targetOutputSize **MUST** be <= block's decompressed size. + * Otherwise, *silent corruption will occur*. + */ +LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity); + + +/*-********************************************* +* Streaming Compression Functions +***********************************************/ +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ + +/** + Note about RC_INVOKED + + - RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio). + https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros + + - Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars) + and reports warning "RC4011: identifier truncated". + + - To eliminate the warning, we surround long preprocessor symbol with + "#if !defined(RC_INVOKED) ... #endif" block that means + "skip this block when rc.exe is trying to read it". +*/ +#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); +LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); +#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ +#endif + +/*! LZ4_resetStream_fast() : v1.9.0+ + * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks + * (e.g., LZ4_compress_fast_continue()). + * + * An LZ4_stream_t must be initialized once before usage. + * This is automatically done when created by LZ4_createStream(). + * However, should the LZ4_stream_t be simply declared on stack (for example), + * it's necessary to initialize it first, using LZ4_initStream(). + * + * After init, start any new stream with LZ4_resetStream_fast(). + * A same LZ4_stream_t can be re-used multiple times consecutively + * and compress multiple streams, + * provided that it starts each new stream with LZ4_resetStream_fast(). + * + * LZ4_resetStream_fast() is much faster than LZ4_initStream(), + * but is not compatible with memory regions containing garbage data. + * + * Note: it's only useful to call LZ4_resetStream_fast() + * in the context of streaming compression. + * The *extState* functions perform their own resets. + * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive. + */ +LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); + +/*! LZ4_loadDict() : + * Use this function to reference a static dictionary into LZ4_stream_t. + * The dictionary must remain available during compression. + * LZ4_loadDict() triggers a reset, so any previous data will be forgotten. + * The same dictionary will have to be loaded on decompression side for successful decoding. + * Dictionary are useful for better compression of small data (KB range). + * While LZ4 accept any input as dictionary, + * results are generally better when using Zstandard's Dictionary Builder. + * Loading a size of 0 is allowed, and is the same as reset. + * @return : loaded dictionary size, in bytes (necessarily <= 64 KB) + */ +LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); + +/*! LZ4_compress_fast_continue() : + * Compress 'src' content using data from previously compressed blocks, for better compression ratio. + * 'dst' buffer must be already allocated. + * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * + * @return : size of compressed block + * or 0 if there is an error (typically, cannot fit into 'dst'). + * + * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block. + * Each block has precise boundaries. + * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata. + * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together. + * + * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory ! + * + * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB. + * Make sure that buffers are separated, by at least one byte. + * This construction ensures that each block only depends on previous block. + * + * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. + * + * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed. + */ +LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_saveDict() : + * If last 64KB data cannot be guaranteed to remain available at its current memory location, + * save it into a safer place (char* safeBuffer). + * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(), + * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables. + * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error. + */ +LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize); + + +/*-********************************************** +* Streaming Decompression Functions +* Bufferless synchronous API +************************************************/ +typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */ + +/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : + * creation / destruction of streaming decompression tracking context. + * A tracking context can be re-used multiple times. + */ +#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); +LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); +#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ +#endif + +/*! LZ4_setStreamDecode() : + * An LZ4_streamDecode_t context can be allocated once and re-used multiple times. + * Use this function to start decompression of a new stream of blocks. + * A dictionary can optionally be set. Use NULL or size 0 for a reset order. + * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression. + * @return : 1 if OK, 0 if error + */ +LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); + +/*! LZ4_decoderRingBufferSize() : v1.8.2+ + * Note : in a ring buffer scenario (optional), + * blocks are presumed decompressed next to each other + * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize), + * at which stage it resumes from beginning of ring buffer. + * When setting such a ring buffer for streaming decompression, + * provides the minimum size of this ring buffer + * to be compatible with any source respecting maxBlockSize condition. + * @return : minimum ring buffer size, + * or 0 if there is an error (invalid maxBlockSize). + */ +LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize); +#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */ + +/*! LZ4_decompress_*_continue() : + * These decoding functions allow decompression of consecutive blocks in "streaming" mode. + * A block is an unsplittable entity, it must be presented entirely to a decompression function. + * Decompression functions only accepts one block at a time. + * The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded. + * If less than 64KB of data has been decoded, all the data must be present. + * + * Special : if decompression side sets a ring buffer, it must respect one of the following conditions : + * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize). + * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes. + * In which case, encoding and decoding buffers do not need to be synchronized. + * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize. + * - Synchronized mode : + * Decompression buffer size is _exactly_ the same as compression buffer size, + * and follows exactly same update rule (block boundaries at same positions), + * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream), + * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB). + * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes. + * In which case, encoding and decoding buffers do not need to be synchronized, + * and encoding ring buffer can have any size, including small ones ( < 64 KB). + * + * Whenever these conditions are not possible, + * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression, + * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block. +*/ +LZ4LIB_API int +LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, + const char* src, char* dst, + int srcSize, int dstCapacity); + + +/*! LZ4_decompress_*_usingDict() : + * These decoding functions work the same as + * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() + * They are stand-alone, and don't need an LZ4_streamDecode_t structure. + * Dictionary is presumed stable : it must remain accessible and unmodified during decompression. + * Performance tip : Decompression speed can be substantially increased + * when dst == dictStart + dictSize. + */ +LZ4LIB_API int +LZ4_decompress_safe_usingDict(const char* src, char* dst, + int srcSize, int dstCapacity, + const char* dictStart, int dictSize); + +LZ4LIB_API int +LZ4_decompress_safe_partial_usingDict(const char* src, char* dst, + int compressedSize, + int targetOutputSize, int maxOutputSize, + const char* dictStart, int dictSize); + +} + +#endif /* LZ4_H_2983827168210 */ + + +/*^************************************* + * !!!!!! STATIC LINKING ONLY !!!!!! + ***************************************/ + +/*-**************************************************************************** + * Experimental section + * + * Symbols declared in this section must be considered unstable. Their + * signatures or semantics may change, or they may be removed altogether in the + * future. They are therefore only safe to depend on when the caller is + * statically linked against the library. + * + * To protect against unsafe usage, not only are the declarations guarded, + * the definitions are hidden by default + * when building LZ4 as a shared/dynamic library. + * + * In order to access these declarations, + * define LZ4_STATIC_LINKING_ONLY in your application + * before including LZ4's headers. + * + * In order to make their implementations accessible dynamically, you must + * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library. + ******************************************************************************/ + +#ifdef LZ4_STATIC_LINKING_ONLY + +#ifndef TRACY_LZ4_STATIC_3504398509 +#define TRACY_LZ4_STATIC_3504398509 + +#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS +#define LZ4LIB_STATIC_API LZ4LIB_API +#else +#define LZ4LIB_STATIC_API +#endif + +namespace tracy +{ + +/*! LZ4_compress_fast_extState_fastReset() : + * A variant of LZ4_compress_fast_extState(). + * + * Using this variant avoids an expensive initialization step. + * It is only safe to call if the state buffer is known to be correctly initialized already + * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized"). + * From a high level, the difference is that + * this function initializes the provided state with a call to something like LZ4_resetStream_fast() + * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream(). + */ +LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_attach_dictionary() : + * This is an experimental API that allows + * efficient use of a static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a + * working LZ4_stream_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDict() should + * be expected to work. + * + * Alternatively, the provided dictionaryStream may be NULL, + * in which case any existing dictionary stream is unset. + * + * If a dictionary is provided, it replaces any pre-existing stream history. + * The dictionary contents are the only history that can be referenced and + * logically immediately precede the data compressed in the first subsequent + * compression call. + * + * The dictionary will only remain attached to the working stream through the + * first compression call, at the end of which it is cleared. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the completion of the first compression call on the stream. + */ +LZ4LIB_STATIC_API void +LZ4_attach_dictionary(LZ4_stream_t* workingStream, + const LZ4_stream_t* dictionaryStream); + + +/*! In-place compression and decompression + * + * It's possible to have input and output sharing the same buffer, + * for highly constrained memory environments. + * In both cases, it requires input to lay at the end of the buffer, + * and decompression to start at beginning of the buffer. + * Buffer size must feature some margin, hence be larger than final size. + * + * |<------------------------buffer--------------------------------->| + * |<-----------compressed data--------->| + * |<-----------decompressed size------------------>| + * |<----margin---->| + * + * This technique is more useful for decompression, + * since decompressed size is typically larger, + * and margin is short. + * + * In-place decompression will work inside any buffer + * which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize). + * This presumes that decompressedSize > compressedSize. + * Otherwise, it means compression actually expanded data, + * and it would be more efficient to store such data with a flag indicating it's not compressed. + * This can happen when data is not compressible (already compressed, or encrypted). + * + * For in-place compression, margin is larger, as it must be able to cope with both + * history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX, + * and data expansion, which can happen when input is not compressible. + * As a consequence, buffer size requirements are much higher, + * and memory savings offered by in-place compression are more limited. + * + * There are ways to limit this cost for compression : + * - Reduce history size, by modifying LZ4_DISTANCE_MAX. + * Note that it is a compile-time constant, so all compressions will apply this limit. + * Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX, + * so it's a reasonable trick when inputs are known to be small. + * - Require the compressor to deliver a "maximum compressed size". + * This is the `dstCapacity` parameter in `LZ4_compress*()`. + * When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail, + * in which case, the return code will be 0 (zero). + * The caller must be ready for these cases to happen, + * and typically design a backup scheme to send data uncompressed. + * The combination of both techniques can significantly reduce + * the amount of margin required for in-place compression. + * + * In-place compression can work in any buffer + * which size is >= (maxCompressedSize) + * with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success. + * LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX, + * so it's possible to reduce memory requirements by playing with them. + */ + +#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32) +#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */ + +#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */ +# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */ +#endif + +#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */ +#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */ + +} + +#endif /* LZ4_STATIC_3504398509 */ +#endif /* LZ4_STATIC_LINKING_ONLY */ + + + +#ifndef TRACY_LZ4_H_98237428734687 +#define TRACY_LZ4_H_98237428734687 + +namespace tracy +{ + +/*-************************************************************ + * Private Definitions + ************************************************************** + * Do not use these definitions directly. + * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. + * Accessing members will expose user code to API and/or ABI break in future versions of the library. + **************************************************************/ +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ + +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) + typedef int8_t LZ4_i8; + typedef uint8_t LZ4_byte; + typedef uint16_t LZ4_u16; + typedef uint32_t LZ4_u32; +#else + typedef signed char LZ4_i8; + typedef unsigned char LZ4_byte; + typedef unsigned short LZ4_u16; + typedef unsigned int LZ4_u32; +#endif + +/*! LZ4_stream_t : + * Never ever use below internal definitions directly ! + * These definitions are not API/ABI safe, and may change in future versions. + * If you need static allocation, declare or allocate an LZ4_stream_t object. +**/ + +typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; +struct LZ4_stream_t_internal { + LZ4_u32 hashTable[LZ4_HASH_SIZE_U32]; + const LZ4_byte* dictionary; + const LZ4_stream_t_internal* dictCtx; + LZ4_u32 currentOffset; + LZ4_u32 tableType; + LZ4_u32 dictSize; + /* Implicit padding to ensure structure is aligned */ +}; + +#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */ +union LZ4_stream_u { + char minStateSize[LZ4_STREAM_MINSIZE]; + LZ4_stream_t_internal internal_donotuse; +}; /* previously typedef'd to LZ4_stream_t */ + + +/*! LZ4_initStream() : v1.9.0+ + * An LZ4_stream_t structure must be initialized at least once. + * This is automatically done when invoking LZ4_createStream(), + * but it's not when the structure is simply declared on stack (for example). + * + * Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t. + * It can also initialize any arbitrary buffer of sufficient size, + * and will @return a pointer of proper type upon initialization. + * + * Note : initialization fails if size and alignment conditions are not respected. + * In which case, the function will @return NULL. + * Note2: An LZ4_stream_t structure guarantees correct alignment and size. + * Note3: Before v1.9.0, use LZ4_resetStream() instead +**/ +LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size); + + +/*! LZ4_streamDecode_t : + * Never ever use below internal definitions directly ! + * These definitions are not API/ABI safe, and may change in future versions. + * If you need static allocation, declare or allocate an LZ4_streamDecode_t object. +**/ +typedef struct { + const LZ4_byte* externalDict; + const LZ4_byte* prefixEnd; + size_t extDictSize; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#define LZ4_STREAMDECODE_MINSIZE 32 +union LZ4_streamDecode_u { + char minStateSize[LZ4_STREAMDECODE_MINSIZE]; + LZ4_streamDecode_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_streamDecode_t */ + + + +/*-************************************ +* Obsolete Functions +**************************************/ + +/*! Deprecation warnings + * + * Deprecated functions make the compiler generate a warning when invoked. + * This is meant to invite users to update their source code. + * Should deprecation warnings be a problem, it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc + * or _CRT_SECURE_NO_WARNINGS in Visual. + * + * Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS + * before including the header file. + */ +#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS +# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ +#else +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define LZ4_DEPRECATED(message) [[deprecated(message)]] +# elif defined(_MSC_VER) +# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) +# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 45)) +# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 31) +# define LZ4_DEPRECATED(message) __attribute__((deprecated)) +# else +# pragma message("WARNING: LZ4_DEPRECATED needs custom implementation for this compiler") +# define LZ4_DEPRECATED(message) /* disabled */ +# endif +#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ + +/*! Obsolete compression functions (since v1.7.3) */ +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize); +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); + +/*! Obsolete decompression functions (since v1.8.0) */ +LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize); +LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); + +/* Obsolete streaming functions (since v1.7.0) + * degraded functionality; do not use! + * + * In order to perform streaming compression, these functions depended on data + * that is no longer tracked in the state. They have been preserved as well as + * possible: using them will still produce a correct output. However, they don't + * actually retain any history between compression calls. The compression ratio + * achieved will therefore be no better than compressing each chunk + * independently. + */ +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer); +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void); +LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer); +LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state); + +/*! Obsolete streaming decoding functions (since v1.7.0) */ +LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); +LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); + +/*! Obsolete LZ4_decompress_fast variants (since v1.9.0) : + * These functions used to be faster than LZ4_decompress_safe(), + * but this is no longer the case. They are now slower. + * This is because LZ4_decompress_fast() doesn't know the input size, + * and therefore must progress more cautiously into the input buffer to not read beyond the end of block. + * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability. + * As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated. + * + * The last remaining LZ4_decompress_fast() specificity is that + * it can decompress a block without knowing its compressed size. + * Such functionality can be achieved in a more secure manner + * by employing LZ4_decompress_safe_partial(). + * + * Parameters: + * originalSize : is the uncompressed size to regenerate. + * `dst` must be already allocated, its size must be >= 'originalSize' bytes. + * @return : number of bytes read from source buffer (== compressed size). + * The function expects to finish at block's end exactly. + * If the source stream is detected malformed, the function stops decoding and returns a negative result. + * note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer. + * However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds. + * Also, since match offsets are not validated, match reads from 'src' may underflow too. + * These issues never happen if input (compressed) data is correct. + * But they may happen if input data is invalid (error or intentional tampering). + * As a consequence, use these functions in trusted environments with trusted data **only**. + */ +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead") +LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead") +LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead") +LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); + +/*! LZ4_resetStream() : + * An LZ4_stream_t structure must be initialized at least once. + * This is done with LZ4_initStream(), or LZ4_resetStream(). + * Consider switching to LZ4_initStream(), + * invoking LZ4_resetStream() will trigger deprecation warnings in the future. + */ +LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); + +} + +#endif /* LZ4_H_98237428734687 */ diff --git a/Externals/tracy/public/common/tracy_lz4hc.cpp b/Externals/tracy/public/common/tracy_lz4hc.cpp new file mode 100644 index 00000000000..eec7239e05b --- /dev/null +++ b/Externals/tracy/public/common/tracy_lz4hc.cpp @@ -0,0 +1,1636 @@ +/* + LZ4 HC - High Compression Mode of LZ4 + Copyright (C) 2011-2020, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/lz4/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */ + + +/* ************************************* +* Tuning Parameter +***************************************/ + +/*! HEAPMODE : + * Select how default compression function will allocate workplace memory, + * in stack (0:fastest), or in heap (1:requires malloc()). + * Since workplace is rather large, heap mode is recommended. +**/ +#ifndef LZ4HC_HEAPMODE +# define LZ4HC_HEAPMODE 1 +#endif + + +/*=== Dependency ===*/ +#define LZ4_HC_STATIC_LINKING_ONLY +#include "tracy_lz4hc.hpp" + + +/*=== Common definitions ===*/ +#if defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wunused-function" +#endif +#if defined (__clang__) +# pragma clang diagnostic ignored "-Wunused-function" +#endif + +#define LZ4_COMMONDEFS_ONLY +#ifndef LZ4_SRC_INCLUDED +#include "tracy_lz4.cpp" /* LZ4_count, constants, mem */ +#endif + + +/*=== Enums ===*/ +typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive; + + +/*=== Constants ===*/ +#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) +#define LZ4_OPT_NUM (1<<12) + + +/*=== Macros ===*/ +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) +#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG)) +#define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */ +#define DELTANEXTU16(table, pos) table[(U16)(pos)] /* faster */ +/* Make fields passed to, and updated by LZ4HC_encodeSequence explicit */ +#define UPDATABLE(ip, op, anchor) &ip, &op, &anchor + +namespace tracy +{ + +static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } + + +/************************************** +* HC Compression +**************************************/ +static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4) +{ + MEM_INIT(hc4->hashTable, 0, sizeof(hc4->hashTable)); + MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); +} + +static void LZ4HC_init_internal (LZ4HC_CCtx_internal* hc4, const BYTE* start) +{ + size_t const bufferSize = (size_t)(hc4->end - hc4->prefixStart); + size_t newStartingOffset = bufferSize + hc4->dictLimit; + assert(newStartingOffset >= bufferSize); /* check overflow */ + if (newStartingOffset > 1 GB) { + LZ4HC_clearTables(hc4); + newStartingOffset = 0; + } + newStartingOffset += 64 KB; + hc4->nextToUpdate = (U32)newStartingOffset; + hc4->prefixStart = start; + hc4->end = start; + hc4->dictStart = start; + hc4->dictLimit = (U32)newStartingOffset; + hc4->lowLimit = (U32)newStartingOffset; +} + + +/* Update chains up to ip (excluded) */ +LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip) +{ + U16* const chainTable = hc4->chainTable; + U32* const hashTable = hc4->hashTable; + const BYTE* const prefixPtr = hc4->prefixStart; + U32 const prefixIdx = hc4->dictLimit; + U32 const target = (U32)(ip - prefixPtr) + prefixIdx; + U32 idx = hc4->nextToUpdate; + assert(ip >= prefixPtr); + assert(target >= prefixIdx); + + while (idx < target) { + U32 const h = LZ4HC_hashPtr(prefixPtr+idx-prefixIdx); + size_t delta = idx - hashTable[h]; + if (delta>LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX; + DELTANEXTU16(chainTable, idx) = (U16)delta; + hashTable[h] = idx; + idx++; + } + + hc4->nextToUpdate = target; +} + +/** LZ4HC_countBack() : + * @return : negative value, nb of common bytes before ip/match */ +LZ4_FORCE_INLINE +int LZ4HC_countBack(const BYTE* const ip, const BYTE* const match, + const BYTE* const iMin, const BYTE* const mMin) +{ + int back = 0; + int const min = (int)MAX(iMin - ip, mMin - match); + assert(min <= 0); + assert(ip >= iMin); assert((size_t)(ip-iMin) < (1U<<31)); + assert(match >= mMin); assert((size_t)(match - mMin) < (1U<<31)); + while ( (back > min) + && (ip[back-1] == match[back-1]) ) + back--; + return back; +} + +#if defined(_MSC_VER) +# define LZ4HC_rotl32(x,r) _rotl(x,r) +#else +# define LZ4HC_rotl32(x,r) ((x << r) | (x >> (32 - r))) +#endif + + +static U32 LZ4HC_rotatePattern(size_t const rotate, U32 const pattern) +{ + size_t const bitsToRotate = (rotate & (sizeof(pattern) - 1)) << 3; + if (bitsToRotate == 0) return pattern; + return LZ4HC_rotl32(pattern, (int)bitsToRotate); +} + +/* LZ4HC_countPattern() : + * pattern32 must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) */ +static unsigned +LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32) +{ + const BYTE* const iStart = ip; + reg_t const pattern = (sizeof(pattern)==8) ? + (reg_t)pattern32 + (((reg_t)pattern32) << (sizeof(pattern)*4)) : pattern32; + + while (likely(ip < iEnd-(sizeof(pattern)-1))) { + reg_t const diff = LZ4_read_ARCH(ip) ^ pattern; + if (!diff) { ip+=sizeof(pattern); continue; } + ip += LZ4_NbCommonBytes(diff); + return (unsigned)(ip - iStart); + } + + if (LZ4_isLittleEndian()) { + reg_t patternByte = pattern; + while ((ip>= 8; + } + } else { /* big endian */ + U32 bitOffset = (sizeof(pattern)*8) - 8; + while (ip < iEnd) { + BYTE const byte = (BYTE)(pattern >> bitOffset); + if (*ip != byte) break; + ip ++; bitOffset -= 8; + } } + + return (unsigned)(ip - iStart); +} + +/* LZ4HC_reverseCountPattern() : + * pattern must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) + * read using natural platform endianness */ +static unsigned +LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern) +{ + const BYTE* const iStart = ip; + + while (likely(ip >= iLow+4)) { + if (LZ4_read32(ip-4) != pattern) break; + ip -= 4; + } + { const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianness */ + while (likely(ip>iLow)) { + if (ip[-1] != *bytePtr) break; + ip--; bytePtr--; + } } + return (unsigned)(iStart - ip); +} + +/* LZ4HC_protectDictEnd() : + * Checks if the match is in the last 3 bytes of the dictionary, so reading the + * 4 byte MINMATCH would overflow. + * @returns true if the match index is okay. + */ +static int LZ4HC_protectDictEnd(U32 const dictLimit, U32 const matchIndex) +{ + return ((U32)((dictLimit - 1) - matchIndex) >= 3); +} + +typedef enum { rep_untested, rep_not, rep_confirmed } repeat_state_e; +typedef enum { favorCompressionRatio=0, favorDecompressionSpeed } HCfavor_e; + +LZ4_FORCE_INLINE int +LZ4HC_InsertAndGetWiderMatch ( + LZ4HC_CCtx_internal* const hc4, + const BYTE* const ip, + const BYTE* const iLowLimit, const BYTE* const iHighLimit, + int longest, + const BYTE** matchpos, + const BYTE** startpos, + const int maxNbAttempts, + const int patternAnalysis, const int chainSwap, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) +{ + U16* const chainTable = hc4->chainTable; + U32* const HashTable = hc4->hashTable; + const LZ4HC_CCtx_internal * const dictCtx = hc4->dictCtx; + const BYTE* const prefixPtr = hc4->prefixStart; + const U32 prefixIdx = hc4->dictLimit; + const U32 ipIndex = (U32)(ip - prefixPtr) + prefixIdx; + const int withinStartDistance = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex); + const U32 lowestMatchIndex = (withinStartDistance) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX; + const BYTE* const dictStart = hc4->dictStart; + const U32 dictIdx = hc4->lowLimit; + const BYTE* const dictEnd = dictStart + prefixIdx - dictIdx; + int const lookBackLength = (int)(ip-iLowLimit); + int nbAttempts = maxNbAttempts; + U32 matchChainPos = 0; + U32 const pattern = LZ4_read32(ip); + U32 matchIndex; + repeat_state_e repeat = rep_untested; + size_t srcPatternLength = 0; + + DEBUGLOG(7, "LZ4HC_InsertAndGetWiderMatch"); + /* First Match */ + LZ4HC_Insert(hc4, ip); + matchIndex = HashTable[LZ4HC_hashPtr(ip)]; + DEBUGLOG(7, "First match at index %u / %u (lowestMatchIndex)", + matchIndex, lowestMatchIndex); + + while ((matchIndex>=lowestMatchIndex) && (nbAttempts>0)) { + int matchLength=0; + nbAttempts--; + assert(matchIndex < ipIndex); + if (favorDecSpeed && (ipIndex - matchIndex < 8)) { + /* do nothing */ + } else if (matchIndex >= prefixIdx) { /* within current Prefix */ + const BYTE* const matchPtr = prefixPtr + matchIndex - prefixIdx; + assert(matchPtr < ip); + assert(longest >= 1); + if (LZ4_read16(iLowLimit + longest - 1) == LZ4_read16(matchPtr - lookBackLength + longest - 1)) { + if (LZ4_read32(matchPtr) == pattern) { + int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, prefixPtr) : 0; + matchLength = MINMATCH + (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit); + matchLength -= back; + if (matchLength > longest) { + longest = matchLength; + *matchpos = matchPtr + back; + *startpos = ip + back; + } } } + } else { /* lowestMatchIndex <= matchIndex < dictLimit */ + const BYTE* const matchPtr = dictStart + (matchIndex - dictIdx); + assert(matchIndex >= dictIdx); + if ( likely(matchIndex <= prefixIdx - 4) + && (LZ4_read32(matchPtr) == pattern) ) { + int back = 0; + const BYTE* vLimit = ip + (prefixIdx - matchIndex); + if (vLimit > iHighLimit) vLimit = iHighLimit; + matchLength = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH; + if ((ip+matchLength == vLimit) && (vLimit < iHighLimit)) + matchLength += LZ4_count(ip+matchLength, prefixPtr, iHighLimit); + back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictStart) : 0; + matchLength -= back; + if (matchLength > longest) { + longest = matchLength; + *matchpos = prefixPtr - prefixIdx + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */ + *startpos = ip + back; + } } } + + if (chainSwap && matchLength==longest) { /* better match => select a better chain */ + assert(lookBackLength==0); /* search forward only */ + if (matchIndex + (U32)longest <= ipIndex) { + int const kTrigger = 4; + U32 distanceToNextMatch = 1; + int const end = longest - MINMATCH + 1; + int step = 1; + int accel = 1 << kTrigger; + int pos; + for (pos = 0; pos < end; pos += step) { + U32 const candidateDist = DELTANEXTU16(chainTable, matchIndex + (U32)pos); + step = (accel++ >> kTrigger); + if (candidateDist > distanceToNextMatch) { + distanceToNextMatch = candidateDist; + matchChainPos = (U32)pos; + accel = 1 << kTrigger; + } } + if (distanceToNextMatch > 1) { + if (distanceToNextMatch > matchIndex) break; /* avoid overflow */ + matchIndex -= distanceToNextMatch; + continue; + } } } + + { U32 const distNextMatch = DELTANEXTU16(chainTable, matchIndex); + if (patternAnalysis && distNextMatch==1 && matchChainPos==0) { + U32 const matchCandidateIdx = matchIndex-1; + /* may be a repeated pattern */ + if (repeat == rep_untested) { + if ( ((pattern & 0xFFFF) == (pattern >> 16)) + & ((pattern & 0xFF) == (pattern >> 24)) ) { + repeat = rep_confirmed; + srcPatternLength = LZ4HC_countPattern(ip+sizeof(pattern), iHighLimit, pattern) + sizeof(pattern); + } else { + repeat = rep_not; + } } + if ( (repeat == rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex) + && LZ4HC_protectDictEnd(prefixIdx, matchCandidateIdx) ) { + const int extDict = matchCandidateIdx < prefixIdx; + const BYTE* const matchPtr = (extDict ? dictStart - dictIdx : prefixPtr - prefixIdx) + matchCandidateIdx; + if (LZ4_read32(matchPtr) == pattern) { /* good candidate */ + const BYTE* const iLimit = extDict ? dictEnd : iHighLimit; + size_t forwardPatternLength = LZ4HC_countPattern(matchPtr+sizeof(pattern), iLimit, pattern) + sizeof(pattern); + if (extDict && matchPtr + forwardPatternLength == iLimit) { + U32 const rotatedPattern = LZ4HC_rotatePattern(forwardPatternLength, pattern); + forwardPatternLength += LZ4HC_countPattern(prefixPtr, iHighLimit, rotatedPattern); + } + { const BYTE* const lowestMatchPtr = extDict ? dictStart : prefixPtr; + size_t backLength = LZ4HC_reverseCountPattern(matchPtr, lowestMatchPtr, pattern); + size_t currentSegmentLength; + if (!extDict + && matchPtr - backLength == prefixPtr + && dictIdx < prefixIdx) { + U32 const rotatedPattern = LZ4HC_rotatePattern((U32)(-(int)backLength), pattern); + backLength += LZ4HC_reverseCountPattern(dictEnd, dictStart, rotatedPattern); + } + /* Limit backLength not go further than lowestMatchIndex */ + backLength = matchCandidateIdx - MAX(matchCandidateIdx - (U32)backLength, lowestMatchIndex); + assert(matchCandidateIdx - backLength >= lowestMatchIndex); + currentSegmentLength = backLength + forwardPatternLength; + /* Adjust to end of pattern if the source pattern fits, otherwise the beginning of the pattern */ + if ( (currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */ + && (forwardPatternLength <= srcPatternLength) ) { /* haven't reached this position yet */ + U32 const newMatchIndex = matchCandidateIdx + (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */ + if (LZ4HC_protectDictEnd(prefixIdx, newMatchIndex)) + matchIndex = newMatchIndex; + else { + /* Can only happen if started in the prefix */ + assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict); + matchIndex = prefixIdx; + } + } else { + U32 const newMatchIndex = matchCandidateIdx - (U32)backLength; /* farthest position in current segment, will find a match of length currentSegmentLength + maybe some back */ + if (!LZ4HC_protectDictEnd(prefixIdx, newMatchIndex)) { + assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict); + matchIndex = prefixIdx; + } else { + matchIndex = newMatchIndex; + if (lookBackLength==0) { /* no back possible */ + size_t const maxML = MIN(currentSegmentLength, srcPatternLength); + if ((size_t)longest < maxML) { + assert(prefixPtr - prefixIdx + matchIndex != ip); + if ((size_t)(ip - prefixPtr) + prefixIdx - matchIndex > LZ4_DISTANCE_MAX) break; + assert(maxML < 2 GB); + longest = (int)maxML; + *matchpos = prefixPtr - prefixIdx + matchIndex; /* virtual pos, relative to ip, to retrieve offset */ + *startpos = ip; + } + { U32 const distToNextPattern = DELTANEXTU16(chainTable, matchIndex); + if (distToNextPattern > matchIndex) break; /* avoid overflow */ + matchIndex -= distToNextPattern; + } } } } } + continue; + } } + } } /* PA optimization */ + + /* follow current chain */ + matchIndex -= DELTANEXTU16(chainTable, matchIndex + matchChainPos); + + } /* while ((matchIndex>=lowestMatchIndex) && (nbAttempts)) */ + + if ( dict == usingDictCtxHc + && nbAttempts > 0 + && ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) { + size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->prefixStart) + dictCtx->dictLimit; + U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)]; + assert(dictEndOffset <= 1 GB); + matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset; + while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) { + const BYTE* const matchPtr = dictCtx->prefixStart - dictCtx->dictLimit + dictMatchIndex; + + if (LZ4_read32(matchPtr) == pattern) { + int mlt; + int back = 0; + const BYTE* vLimit = ip + (dictEndOffset - dictMatchIndex); + if (vLimit > iHighLimit) vLimit = iHighLimit; + mlt = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH; + back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->prefixStart) : 0; + mlt -= back; + if (mlt > longest) { + longest = mlt; + *matchpos = prefixPtr - prefixIdx + matchIndex + back; + *startpos = ip + back; + } } + + { U32 const nextOffset = DELTANEXTU16(dictCtx->chainTable, dictMatchIndex); + dictMatchIndex -= nextOffset; + matchIndex -= nextOffset; + } } } + + return longest; +} + +LZ4_FORCE_INLINE int +LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */ + const BYTE* const ip, const BYTE* const iLimit, + const BYTE** matchpos, + const int maxNbAttempts, + const int patternAnalysis, + const dictCtx_directive dict) +{ + const BYTE* uselessPtr = ip; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + return LZ4HC_InsertAndGetWiderMatch(hc4, ip, ip, iLimit, MINMATCH-1, matchpos, &uselessPtr, maxNbAttempts, patternAnalysis, 0 /*chainSwap*/, dict, favorCompressionRatio); +} + +/* LZ4HC_encodeSequence() : + * @return : 0 if ok, + * 1 if buffer issue detected */ +LZ4_FORCE_INLINE int LZ4HC_encodeSequence ( + const BYTE** _ip, + BYTE** _op, + const BYTE** _anchor, + int matchLength, + const BYTE* const match, + limitedOutput_directive limit, + BYTE* oend) +{ +#define ip (*_ip) +#define op (*_op) +#define anchor (*_anchor) + + size_t length; + BYTE* const token = op++; + +#if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 6) + static const BYTE* start = NULL; + static U32 totalCost = 0; + U32 const pos = (start==NULL) ? 0 : (U32)(anchor - start); + U32 const ll = (U32)(ip - anchor); + U32 const llAdd = (ll>=15) ? ((ll-15) / 255) + 1 : 0; + U32 const mlAdd = (matchLength>=19) ? ((matchLength-19) / 255) + 1 : 0; + U32 const cost = 1 + llAdd + ll + 2 + mlAdd; + if (start==NULL) start = anchor; /* only works for single segment */ + /* g_debuglog_enable = (pos >= 2228) & (pos <= 2262); */ + DEBUGLOG(6, "pos:%7u -- literals:%4u, match:%4i, offset:%5u, cost:%4u + %5u", + pos, + (U32)(ip - anchor), matchLength, (U32)(ip-match), + cost, totalCost); + totalCost += cost; +#endif + + /* Encode Literal length */ + length = (size_t)(ip - anchor); + LZ4_STATIC_ASSERT(notLimited == 0); + /* Check output limit */ + if (limit && ((op + (length / 255) + length + (2 + 1 + LASTLITERALS)) > oend)) { + DEBUGLOG(6, "Not enough room to write %i literals (%i bytes remaining)", + (int)length, (int)(oend - op)); + return 1; + } + if (length >= RUN_MASK) { + size_t len = length - RUN_MASK; + *token = (RUN_MASK << ML_BITS); + for(; len >= 255 ; len -= 255) *op++ = 255; + *op++ = (BYTE)len; + } else { + *token = (BYTE)(length << ML_BITS); + } + + /* Copy Literals */ + LZ4_wildCopy8(op, anchor, op + length); + op += length; + + /* Encode Offset */ + assert( (ip - match) <= LZ4_DISTANCE_MAX ); /* note : consider providing offset as a value, rather than as a pointer difference */ + LZ4_writeLE16(op, (U16)(ip - match)); op += 2; + + /* Encode MatchLength */ + assert(matchLength >= MINMATCH); + length = (size_t)matchLength - MINMATCH; + if (limit && (op + (length / 255) + (1 + LASTLITERALS) > oend)) { + DEBUGLOG(6, "Not enough room to write match length"); + return 1; /* Check output limit */ + } + if (length >= ML_MASK) { + *token += ML_MASK; + length -= ML_MASK; + for(; length >= 510 ; length -= 510) { *op++ = 255; *op++ = 255; } + if (length >= 255) { length -= 255; *op++ = 255; } + *op++ = (BYTE)length; + } else { + *token += (BYTE)(length); + } + + /* Prepare next loop */ + ip += matchLength; + anchor = ip; + + return 0; +} +#undef ip +#undef op +#undef anchor + +LZ4_FORCE_INLINE int LZ4HC_compress_hashChain ( + LZ4HC_CCtx_internal* const ctx, + const char* const source, + char* const dest, + int* srcSizePtr, + int const maxOutputSize, + int maxNbAttempts, + const limitedOutput_directive limit, + const dictCtx_directive dict + ) +{ + const int inputSize = *srcSizePtr; + const int patternAnalysis = (maxNbAttempts > 128); /* levels 9+ */ + + const BYTE* ip = (const BYTE*) source; + const BYTE* anchor = ip; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = (iend - LASTLITERALS); + + BYTE* optr = (BYTE*) dest; + BYTE* op = (BYTE*) dest; + BYTE* oend = op + maxOutputSize; + + int ml0, ml, ml2, ml3; + const BYTE* start0; + const BYTE* ref0; + const BYTE* ref = NULL; + const BYTE* start2 = NULL; + const BYTE* ref2 = NULL; + const BYTE* start3 = NULL; + const BYTE* ref3 = NULL; + + /* init */ + *srcSizePtr = 0; + if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ + if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ + + /* Main Loop */ + while (ip <= mflimit) { + ml = LZ4HC_InsertAndFindBestMatch(ctx, ip, matchlimit, &ref, maxNbAttempts, patternAnalysis, dict); + if (ml encode ML1 */ + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + continue; + } + + if (start0 < ip) { /* first match was skipped at least once */ + if (start2 < ip + ml0) { /* squeezing ML1 between ML0(original ML1) and ML2 */ + ip = start0; ref = ref0; ml = ml0; /* restore initial ML1 */ + } } + + /* Here, start0==ip */ + if ((start2 - ip) < 3) { /* First Match too small : removed */ + ml = ml2; + ip = start2; + ref =ref2; + goto _Search2; + } + +_Search3: + /* At this stage, we have : + * ml2 > ml1, and + * ip1+3 <= ip2 (usually < ip1+ml1) */ + if ((start2 - ip) < OPTIMAL_ML) { + int correction; + int new_ml = ml; + if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; + if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; + correction = new_ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } + /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ + + if (start2 + ml2 <= mflimit) { + ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, + start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, + maxNbAttempts, patternAnalysis, 0, dict, favorCompressionRatio); + } else { + ml3 = ml2; + } + + if (ml3 == ml2) { /* No better match => encode ML1 and ML2 */ + /* ip & ref are known; Now for ml */ + if (start2 < ip+ml) ml = (int)(start2 - ip); + /* Now, encode 2 sequences */ + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + ip = start2; + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml2, ref2, limit, oend)) { + ml = ml2; + ref = ref2; + goto _dest_overflow; + } + continue; + } + + if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */ + if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ + if (start2 < ip+ml) { + int correction = (int)(ip+ml - start2); + start2 += correction; + ref2 += correction; + ml2 -= correction; + if (ml2 < MINMATCH) { + start2 = start3; + ref2 = ref3; + ml2 = ml3; + } + } + + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + ip = start3; + ref = ref3; + ml = ml3; + + start0 = start2; + ref0 = ref2; + ml0 = ml2; + goto _Search2; + } + + start2 = start3; + ref2 = ref3; + ml2 = ml3; + goto _Search3; + } + + /* + * OK, now we have 3 ascending matches; + * let's write the first one ML1. + * ip & ref are known; Now decide ml. + */ + if (start2 < ip+ml) { + if ((start2 - ip) < OPTIMAL_ML) { + int correction; + if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; + if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; + correction = ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } else { + ml = (int)(start2 - ip); + } + } + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + + /* ML2 becomes ML1 */ + ip = start2; ref = ref2; ml = ml2; + + /* ML3 becomes ML2 */ + start2 = start3; ref2 = ref3; ml2 = ml3; + + /* let's find a new ML3 */ + goto _Search3; + } + +_last_literals: + /* Encode Last Literals */ + { size_t lastRunSize = (size_t)(iend - anchor); /* literals */ + size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255; + size_t const totalSize = 1 + llAdd + lastRunSize; + if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */ + if (limit && (op + totalSize > oend)) { + if (limit == limitedOutput) return 0; + /* adapt lastRunSize to fill 'dest' */ + lastRunSize = (size_t)(oend - op) - 1 /*token*/; + llAdd = (lastRunSize + 256 - RUN_MASK) / 256; + lastRunSize -= llAdd; + } + DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize); + ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */ + + if (lastRunSize >= RUN_MASK) { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = (RUN_MASK << ML_BITS); + for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRunSize << ML_BITS); + } + LZ4_memcpy(op, anchor, lastRunSize); + op += lastRunSize; + } + + /* End */ + *srcSizePtr = (int) (((const char*)ip) - source); + return (int) (((char*)op)-dest); + +_dest_overflow: + if (limit == fillOutput) { + /* Assumption : ip, anchor, ml and ref must be set correctly */ + size_t const ll = (size_t)(ip - anchor); + size_t const ll_addbytes = (ll + 240) / 255; + size_t const ll_totalCost = 1 + ll_addbytes + ll; + BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */ + DEBUGLOG(6, "Last sequence overflowing"); + op = optr; /* restore correct out pointer */ + if (op + ll_totalCost <= maxLitPos) { + /* ll validated; now adjust match length */ + size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost)); + size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255); + assert(maxMlSize < INT_MAX); assert(ml >= 0); + if ((size_t)ml > maxMlSize) ml = (int)maxMlSize; + if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ml >= MFLIMIT) { + LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, notLimited, oend); + } } + goto _last_literals; + } + /* compression failed */ + return 0; +} + + +static int LZ4HC_compress_optimal( LZ4HC_CCtx_internal* ctx, + const char* const source, char* dst, + int* srcSizePtr, int dstCapacity, + int const nbSearches, size_t sufficient_len, + const limitedOutput_directive limit, int const fullUpdate, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed); + + +LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal ( + LZ4HC_CCtx_internal* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + int const dstCapacity, + int cLevel, + const limitedOutput_directive limit, + const dictCtx_directive dict + ) +{ + typedef enum { lz4hc, lz4opt } lz4hc_strat_e; + typedef struct { + lz4hc_strat_e strat; + int nbSearches; + U32 targetLength; + } cParams_t; + static const cParams_t clTable[LZ4HC_CLEVEL_MAX+1] = { + { lz4hc, 2, 16 }, /* 0, unused */ + { lz4hc, 2, 16 }, /* 1, unused */ + { lz4hc, 2, 16 }, /* 2, unused */ + { lz4hc, 4, 16 }, /* 3 */ + { lz4hc, 8, 16 }, /* 4 */ + { lz4hc, 16, 16 }, /* 5 */ + { lz4hc, 32, 16 }, /* 6 */ + { lz4hc, 64, 16 }, /* 7 */ + { lz4hc, 128, 16 }, /* 8 */ + { lz4hc, 256, 16 }, /* 9 */ + { lz4opt, 96, 64 }, /*10==LZ4HC_CLEVEL_OPT_MIN*/ + { lz4opt, 512,128 }, /*11 */ + { lz4opt,16384,LZ4_OPT_NUM }, /* 12==LZ4HC_CLEVEL_MAX */ + }; + + DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)", + ctx, src, *srcSizePtr, limit); + + if (limit == fillOutput && dstCapacity < 1) return 0; /* Impossible to store anything */ + if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size (too large or negative) */ + + ctx->end += *srcSizePtr; + if (cLevel < 1) cLevel = LZ4HC_CLEVEL_DEFAULT; /* note : convention is different from lz4frame, maybe something to review */ + cLevel = MIN(LZ4HC_CLEVEL_MAX, cLevel); + { cParams_t const cParam = clTable[cLevel]; + HCfavor_e const favor = ctx->favorDecSpeed ? favorDecompressionSpeed : favorCompressionRatio; + int result; + + if (cParam.strat == lz4hc) { + result = LZ4HC_compress_hashChain(ctx, + src, dst, srcSizePtr, dstCapacity, + cParam.nbSearches, limit, dict); + } else { + assert(cParam.strat == lz4opt); + result = LZ4HC_compress_optimal(ctx, + src, dst, srcSizePtr, dstCapacity, + cParam.nbSearches, cParam.targetLength, limit, + cLevel == LZ4HC_CLEVEL_MAX, /* ultra mode */ + dict, favor); + } + if (result <= 0) ctx->dirty = 1; + return result; + } +} + +static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock); + +static int +LZ4HC_compress_generic_noDictCtx ( + LZ4HC_CCtx_internal* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit + ) +{ + assert(ctx->dictCtx == NULL); + return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, noDictCtx); +} + +static int +LZ4HC_compress_generic_dictCtx ( + LZ4HC_CCtx_internal* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit + ) +{ + const size_t position = (size_t)(ctx->end - ctx->prefixStart) + (ctx->dictLimit - ctx->lowLimit); + assert(ctx->dictCtx != NULL); + if (position >= 64 KB) { + ctx->dictCtx = NULL; + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else if (position == 0 && *srcSizePtr > 4 KB) { + LZ4_memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal)); + LZ4HC_setExternalDict(ctx, (const BYTE *)src); + ctx->compressionLevel = (short)cLevel; + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else { + return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, usingDictCtxHc); + } +} + +static int +LZ4HC_compress_generic ( + LZ4HC_CCtx_internal* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit + ) +{ + if (ctx->dictCtx == NULL) { + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else { + return LZ4HC_compress_generic_dictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } +} + + +int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); } + +static size_t LZ4_streamHC_t_alignment(void) +{ +#if LZ4_ALIGN_TEST + typedef struct { char c; LZ4_streamHC_t t; } t_a; + return sizeof(t_a) - sizeof(LZ4_streamHC_t); +#else + return 1; /* effectively disabled */ +#endif +} + +/* state is presumed correctly initialized, + * in which case its size and alignment have already been validate */ +int LZ4_compress_HC_extStateHC_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) +{ + LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; + if (!LZ4_isAligned(state, LZ4_streamHC_t_alignment())) return 0; + LZ4_resetStreamHC_fast((LZ4_streamHC_t*)state, compressionLevel); + LZ4HC_init_internal (ctx, (const BYTE*)src); + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, limitedOutput); + else + return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, notLimited); +} + +int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) +{ + LZ4_streamHC_t* const ctx = LZ4_initStreamHC(state, sizeof(*ctx)); + if (ctx==NULL) return 0; /* init failure */ + return LZ4_compress_HC_extStateHC_fastReset(state, src, dst, srcSize, dstCapacity, compressionLevel); +} + +int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) +{ + int cSize; +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t)); + if (statePtr==NULL) return 0; +#else + LZ4_streamHC_t state; + LZ4_streamHC_t* const statePtr = &state; +#endif + cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel); +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + FREEMEM(statePtr); +#endif + return cSize; +} + +/* state is presumed sized correctly (>= sizeof(LZ4_streamHC_t)) */ +int LZ4_compress_HC_destSize(void* state, const char* source, char* dest, int* sourceSizePtr, int targetDestSize, int cLevel) +{ + LZ4_streamHC_t* const ctx = LZ4_initStreamHC(state, sizeof(*ctx)); + if (ctx==NULL) return 0; /* init failure */ + LZ4HC_init_internal(&ctx->internal_donotuse, (const BYTE*) source); + LZ4_setCompressionLevel(ctx, cLevel); + return LZ4HC_compress_generic(&ctx->internal_donotuse, source, dest, sourceSizePtr, targetDestSize, cLevel, fillOutput); +} + + + +/************************************** +* Streaming Functions +**************************************/ +/* allocation */ +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +LZ4_streamHC_t* LZ4_createStreamHC(void) +{ + LZ4_streamHC_t* const state = + (LZ4_streamHC_t*)ALLOC_AND_ZERO(sizeof(LZ4_streamHC_t)); + if (state == NULL) return NULL; + LZ4_setCompressionLevel(state, LZ4HC_CLEVEL_DEFAULT); + return state; +} + +int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) +{ + DEBUGLOG(4, "LZ4_freeStreamHC(%p)", LZ4_streamHCPtr); + if (!LZ4_streamHCPtr) return 0; /* support free on NULL */ + FREEMEM(LZ4_streamHCPtr); + return 0; +} +#endif + + +LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size) +{ + LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer; + DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size); + /* check conditions */ + if (buffer == NULL) return NULL; + if (size < sizeof(LZ4_streamHC_t)) return NULL; + if (!LZ4_isAligned(buffer, LZ4_streamHC_t_alignment())) return NULL; + /* init */ + { LZ4HC_CCtx_internal* const hcstate = &(LZ4_streamHCPtr->internal_donotuse); + MEM_INIT(hcstate, 0, sizeof(*hcstate)); } + LZ4_setCompressionLevel(LZ4_streamHCPtr, LZ4HC_CLEVEL_DEFAULT); + return LZ4_streamHCPtr; +} + +/* just a stub */ +void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) +{ + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel); +} + +void LZ4_resetStreamHC_fast (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) +{ + DEBUGLOG(4, "LZ4_resetStreamHC_fast(%p, %d)", LZ4_streamHCPtr, compressionLevel); + if (LZ4_streamHCPtr->internal_donotuse.dirty) { + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + } else { + /* preserve end - prefixStart : can trigger clearTable's threshold */ + if (LZ4_streamHCPtr->internal_donotuse.end != NULL) { + LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.prefixStart; + } else { + assert(LZ4_streamHCPtr->internal_donotuse.prefixStart == NULL); + } + LZ4_streamHCPtr->internal_donotuse.prefixStart = NULL; + LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL; + } + LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel); +} + +void LZ4_setCompressionLevel(LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) +{ + DEBUGLOG(5, "LZ4_setCompressionLevel(%p, %d)", LZ4_streamHCPtr, compressionLevel); + if (compressionLevel < 1) compressionLevel = LZ4HC_CLEVEL_DEFAULT; + if (compressionLevel > LZ4HC_CLEVEL_MAX) compressionLevel = LZ4HC_CLEVEL_MAX; + LZ4_streamHCPtr->internal_donotuse.compressionLevel = (short)compressionLevel; +} + +void LZ4_favorDecompressionSpeed(LZ4_streamHC_t* LZ4_streamHCPtr, int favor) +{ + LZ4_streamHCPtr->internal_donotuse.favorDecSpeed = (favor!=0); +} + +/* LZ4_loadDictHC() : + * LZ4_streamHCPtr is presumed properly initialized */ +int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, + const char* dictionary, int dictSize) +{ + LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; + DEBUGLOG(4, "LZ4_loadDictHC(ctx:%p, dict:%p, dictSize:%d)", LZ4_streamHCPtr, dictionary, dictSize); + assert(LZ4_streamHCPtr != NULL); + if (dictSize > 64 KB) { + dictionary += (size_t)dictSize - 64 KB; + dictSize = 64 KB; + } + /* need a full initialization, there are bad side-effects when using resetFast() */ + { int const cLevel = ctxPtr->compressionLevel; + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + LZ4_setCompressionLevel(LZ4_streamHCPtr, cLevel); + } + LZ4HC_init_internal (ctxPtr, (const BYTE*)dictionary); + ctxPtr->end = (const BYTE*)dictionary + dictSize; + if (dictSize >= 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); + return dictSize; +} + +void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream) { + working_stream->internal_donotuse.dictCtx = dictionary_stream != NULL ? &(dictionary_stream->internal_donotuse) : NULL; +} + +/* compression */ + +static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock) +{ + DEBUGLOG(4, "LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock); + if (ctxPtr->end >= ctxPtr->prefixStart + 4) + LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ + + /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ + ctxPtr->lowLimit = ctxPtr->dictLimit; + ctxPtr->dictStart = ctxPtr->prefixStart; + ctxPtr->dictLimit += (U32)(ctxPtr->end - ctxPtr->prefixStart); + ctxPtr->prefixStart = newBlock; + ctxPtr->end = newBlock; + ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ + + /* cannot reference an extDict and a dictCtx at the same time */ + ctxPtr->dictCtx = NULL; +} + +static int +LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr, + const char* src, char* dst, + int* srcSizePtr, int dstCapacity, + limitedOutput_directive limit) +{ + LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; + DEBUGLOG(5, "LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)", + LZ4_streamHCPtr, src, *srcSizePtr, limit); + assert(ctxPtr != NULL); + /* auto-init if forgotten */ + if (ctxPtr->prefixStart == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src); + + /* Check overflow */ + if ((size_t)(ctxPtr->end - ctxPtr->prefixStart) + ctxPtr->dictLimit > 2 GB) { + size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->prefixStart); + if (dictSize > 64 KB) dictSize = 64 KB; + LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); + } + + /* Check if blocks follow each other */ + if ((const BYTE*)src != ctxPtr->end) + LZ4HC_setExternalDict(ctxPtr, (const BYTE*)src); + + /* Check overlapping input/dictionary space */ + { const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr; + const BYTE* const dictBegin = ctxPtr->dictStart; + const BYTE* const dictEnd = ctxPtr->dictStart + (ctxPtr->dictLimit - ctxPtr->lowLimit); + if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) { + if (sourceEnd > dictEnd) sourceEnd = dictEnd; + ctxPtr->lowLimit += (U32)(sourceEnd - ctxPtr->dictStart); + ctxPtr->dictStart += (U32)(sourceEnd - ctxPtr->dictStart); + if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) { + ctxPtr->lowLimit = ctxPtr->dictLimit; + ctxPtr->dictStart = ctxPtr->prefixStart; + } } } + + return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit); +} + +int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int srcSize, int dstCapacity) +{ + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput); + else + return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, notLimited); +} + +int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int* srcSizePtr, int targetDestSize) +{ + return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, srcSizePtr, targetDestSize, fillOutput); +} + + + +/* LZ4_saveDictHC : + * save history content + * into a user-provided buffer + * which is then used to continue compression + */ +int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) +{ + LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse; + int const prefixSize = (int)(streamPtr->end - streamPtr->prefixStart); + DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize); + assert(prefixSize >= 0); + if (dictSize > 64 KB) dictSize = 64 KB; + if (dictSize < 4) dictSize = 0; + if (dictSize > prefixSize) dictSize = prefixSize; + if (safeBuffer == NULL) assert(dictSize == 0); + if (dictSize > 0) + LZ4_memmove(safeBuffer, streamPtr->end - dictSize, dictSize); + { U32 const endIndex = (U32)(streamPtr->end - streamPtr->prefixStart) + streamPtr->dictLimit; + streamPtr->end = (const BYTE*)safeBuffer + dictSize; + streamPtr->prefixStart = streamPtr->end - dictSize; + streamPtr->dictLimit = endIndex - (U32)dictSize; + streamPtr->lowLimit = endIndex - (U32)dictSize; + streamPtr->dictStart = streamPtr->prefixStart; + if (streamPtr->nextToUpdate < streamPtr->dictLimit) + streamPtr->nextToUpdate = streamPtr->dictLimit; + } + return dictSize; +} + + +/*************************************************** +* Deprecated Functions +***************************************************/ + +/* These functions currently generate deprecation warnings */ + +/* Wrappers for deprecated compression functions */ +int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } +int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } +int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } +int LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); } +int LZ4_compressHC_withStateHC (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, LZ4_compressBound(srcSize), 0); } +int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, maxDstSize, 0); } +int LZ4_compressHC2_withStateHC (void* state, const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } +int LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, cLevel); } +int LZ4_compressHC_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, LZ4_compressBound(srcSize)); } +int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, maxDstSize); } + + +/* Deprecated streaming functions */ +int LZ4_sizeofStreamStateHC(void) { return sizeof(LZ4_streamHC_t); } + +/* state is presumed correctly sized, aka >= sizeof(LZ4_streamHC_t) + * @return : 0 on success, !=0 if error */ +int LZ4_resetStreamStateHC(void* state, char* inputBuffer) +{ + LZ4_streamHC_t* const hc4 = LZ4_initStreamHC(state, sizeof(*hc4)); + if (hc4 == NULL) return 1; /* init failed */ + LZ4HC_init_internal (&hc4->internal_donotuse, (const BYTE*)inputBuffer); + return 0; +} + +#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) +void* LZ4_createHC (const char* inputBuffer) +{ + LZ4_streamHC_t* const hc4 = LZ4_createStreamHC(); + if (hc4 == NULL) return NULL; /* not enough memory */ + LZ4HC_init_internal (&hc4->internal_donotuse, (const BYTE*)inputBuffer); + return hc4; +} + +int LZ4_freeHC (void* LZ4HC_Data) +{ + if (!LZ4HC_Data) return 0; /* support free on NULL */ + FREEMEM(LZ4HC_Data); + return 0; +} +#endif + +int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int cLevel) +{ + return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, 0, cLevel, notLimited); +} + +int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int dstCapacity, int cLevel) +{ + return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, dstCapacity, cLevel, limitedOutput); +} + +char* LZ4_slideInputBufferHC(void* LZ4HC_Data) +{ + LZ4_streamHC_t* const ctx = (LZ4_streamHC_t*)LZ4HC_Data; + const BYTE* bufferStart = ctx->internal_donotuse.prefixStart - ctx->internal_donotuse.dictLimit + ctx->internal_donotuse.lowLimit; + LZ4_resetStreamHC_fast(ctx, ctx->internal_donotuse.compressionLevel); + /* avoid const char * -> char * conversion warning :( */ + return (char*)(uptrval)bufferStart; +} + + +/* ================================================ + * LZ4 Optimal parser (levels [LZ4HC_CLEVEL_OPT_MIN - LZ4HC_CLEVEL_MAX]) + * ===============================================*/ +typedef struct { + int price; + int off; + int mlen; + int litlen; +} LZ4HC_optimal_t; + +/* price in bytes */ +LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen) +{ + int price = litlen; + assert(litlen >= 0); + if (litlen >= (int)RUN_MASK) + price += 1 + ((litlen-(int)RUN_MASK) / 255); + return price; +} + + +/* requires mlen >= MINMATCH */ +LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen) +{ + int price = 1 + 2 ; /* token + 16-bit offset */ + assert(litlen >= 0); + assert(mlen >= MINMATCH); + + price += LZ4HC_literalsPrice(litlen); + + if (mlen >= (int)(ML_MASK+MINMATCH)) + price += 1 + ((mlen-(int)(ML_MASK+MINMATCH)) / 255); + + return price; +} + + +typedef struct { + int off; + int len; +} LZ4HC_match_t; + +LZ4_FORCE_INLINE LZ4HC_match_t +LZ4HC_FindLongerMatch(LZ4HC_CCtx_internal* const ctx, + const BYTE* ip, const BYTE* const iHighLimit, + int minLen, int nbSearches, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) +{ + LZ4HC_match_t match = { 0 , 0 }; + const BYTE* matchPtr = NULL; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + int matchLength = LZ4HC_InsertAndGetWiderMatch(ctx, ip, ip, iHighLimit, minLen, &matchPtr, &ip, nbSearches, 1 /*patternAnalysis*/, 1 /*chainSwap*/, dict, favorDecSpeed); + if (matchLength <= minLen) return match; + if (favorDecSpeed) { + if ((matchLength>18) & (matchLength<=36)) matchLength=18; /* favor shortcut */ + } + match.len = matchLength; + match.off = (int)(ip-matchPtr); + return match; +} + + +static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx, + const char* const source, + char* dst, + int* srcSizePtr, + int dstCapacity, + int const nbSearches, + size_t sufficient_len, + const limitedOutput_directive limit, + int const fullUpdate, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) +{ + int retval = 0; +#define TRAILING_LITERALS 3 +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)ALLOC(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS)); +#else + LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */ +#endif + + const BYTE* ip = (const BYTE*) source; + const BYTE* anchor = ip; + const BYTE* const iend = ip + *srcSizePtr; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = iend - LASTLITERALS; + BYTE* op = (BYTE*) dst; + BYTE* opSaved = (BYTE*) dst; + BYTE* oend = op + dstCapacity; + int ovml = MINMATCH; /* overflow - last sequence */ + const BYTE* ovref = NULL; + + /* init */ +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + if (opt == NULL) goto _return_label; +#endif + DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity); + *srcSizePtr = 0; + if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ + if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM-1; + + /* Main Loop */ + while (ip <= mflimit) { + int const llen = (int)(ip - anchor); + int best_mlen, best_off; + int cur, last_match_pos = 0; + + LZ4HC_match_t const firstMatch = LZ4HC_FindLongerMatch(ctx, ip, matchlimit, MINMATCH-1, nbSearches, dict, favorDecSpeed); + if (firstMatch.len==0) { ip++; continue; } + + if ((size_t)firstMatch.len > sufficient_len) { + /* good enough solution : immediate encoding */ + int const firstML = firstMatch.len; + const BYTE* const matchPos = ip - firstMatch.off; + opSaved = op; + if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), firstML, matchPos, limit, oend) ) { /* updates ip, op and anchor */ + ovml = firstML; + ovref = matchPos; + goto _dest_overflow; + } + continue; + } + + /* set prices for first positions (literals) */ + { int rPos; + for (rPos = 0 ; rPos < MINMATCH ; rPos++) { + int const cost = LZ4HC_literalsPrice(llen + rPos); + opt[rPos].mlen = 1; + opt[rPos].off = 0; + opt[rPos].litlen = llen + rPos; + opt[rPos].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + rPos, cost, opt[rPos].litlen); + } } + /* set prices using initial match */ + { int mlen = MINMATCH; + int const matchML = firstMatch.len; /* necessarily < sufficient_len < LZ4_OPT_NUM */ + int const offset = firstMatch.off; + assert(matchML < LZ4_OPT_NUM); + for ( ; mlen <= matchML ; mlen++) { + int const cost = LZ4HC_sequencePrice(llen, mlen); + opt[mlen].mlen = mlen; + opt[mlen].off = offset; + opt[mlen].litlen = llen; + opt[mlen].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i) -- initial setup", + mlen, cost, mlen); + } } + last_match_pos = firstMatch.len; + { int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos+addLit].mlen = 1; /* literal */ + opt[last_match_pos+addLit].off = 0; + opt[last_match_pos+addLit].litlen = addLit; + opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit); + } } + + /* check further positions */ + for (cur = 1; cur < last_match_pos; cur++) { + const BYTE* const curPtr = ip + cur; + LZ4HC_match_t newMatch; + + if (curPtr > mflimit) break; + DEBUGLOG(7, "rPos:%u[%u] vs [%u]%u", + cur, opt[cur].price, opt[cur+1].price, cur+1); + if (fullUpdate) { + /* not useful to search here if next position has same (or lower) cost */ + if ( (opt[cur+1].price <= opt[cur].price) + /* in some cases, next position has same cost, but cost rises sharply after, so a small match would still be beneficial */ + && (opt[cur+MINMATCH].price < opt[cur].price + 3/*min seq price*/) ) + continue; + } else { + /* not useful to search here if next position has same (or lower) cost */ + if (opt[cur+1].price <= opt[cur].price) continue; + } + + DEBUGLOG(7, "search at rPos:%u", cur); + if (fullUpdate) + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, MINMATCH-1, nbSearches, dict, favorDecSpeed); + else + /* only test matches of minimum length; slightly faster, but misses a few bytes */ + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches, dict, favorDecSpeed); + if (!newMatch.len) continue; + + if ( ((size_t)newMatch.len > sufficient_len) + || (newMatch.len + cur >= LZ4_OPT_NUM) ) { + /* immediate encoding */ + best_mlen = newMatch.len; + best_off = newMatch.off; + last_match_pos = cur + 1; + goto encode; + } + + /* before match : set price with literals at beginning */ + { int const baseLitlen = opt[cur].litlen; + int litlen; + for (litlen = 1; litlen < MINMATCH; litlen++) { + int const price = opt[cur].price - LZ4HC_literalsPrice(baseLitlen) + LZ4HC_literalsPrice(baseLitlen+litlen); + int const pos = cur + litlen; + if (price < opt[pos].price) { + opt[pos].mlen = 1; /* literal */ + opt[pos].off = 0; + opt[pos].litlen = baseLitlen+litlen; + opt[pos].price = price; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", + pos, price, opt[pos].litlen); + } } } + + /* set prices using match at position = cur */ + { int const matchML = newMatch.len; + int ml = MINMATCH; + + assert(cur + newMatch.len < LZ4_OPT_NUM); + for ( ; ml <= matchML ; ml++) { + int const pos = cur + ml; + int const offset = newMatch.off; + int price; + int ll; + DEBUGLOG(7, "testing price rPos %i (last_match_pos=%i)", + pos, last_match_pos); + if (opt[cur].mlen == 1) { + ll = opt[cur].litlen; + price = ((cur > ll) ? opt[cur - ll].price : 0) + + LZ4HC_sequencePrice(ll, ml); + } else { + ll = 0; + price = opt[cur].price + LZ4HC_sequencePrice(0, ml); + } + + assert((U32)favorDecSpeed <= 1); + if (pos > last_match_pos+TRAILING_LITERALS + || price <= opt[pos].price - (int)favorDecSpeed) { + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i)", + pos, price, ml); + assert(pos < LZ4_OPT_NUM); + if ( (ml == matchML) /* last pos of last match */ + && (last_match_pos < pos) ) + last_match_pos = pos; + opt[pos].mlen = ml; + opt[pos].off = offset; + opt[pos].litlen = ll; + opt[pos].price = price; + } } } + /* complete following positions with literals */ + { int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos+addLit].mlen = 1; /* literal */ + opt[last_match_pos+addLit].off = 0; + opt[last_match_pos+addLit].litlen = addLit; + opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit); + } } + } /* for (cur = 1; cur <= last_match_pos; cur++) */ + + assert(last_match_pos < LZ4_OPT_NUM + TRAILING_LITERALS); + best_mlen = opt[last_match_pos].mlen; + best_off = opt[last_match_pos].off; + cur = last_match_pos - best_mlen; + +encode: /* cur, last_match_pos, best_mlen, best_off must be set */ + assert(cur < LZ4_OPT_NUM); + assert(last_match_pos >= 1); /* == 1 when only one candidate */ + DEBUGLOG(6, "reverse traversal, looking for shortest path (last_match_pos=%i)", last_match_pos); + { int candidate_pos = cur; + int selected_matchLength = best_mlen; + int selected_offset = best_off; + while (1) { /* from end to beginning */ + int const next_matchLength = opt[candidate_pos].mlen; /* can be 1, means literal */ + int const next_offset = opt[candidate_pos].off; + DEBUGLOG(7, "pos %i: sequence length %i", candidate_pos, selected_matchLength); + opt[candidate_pos].mlen = selected_matchLength; + opt[candidate_pos].off = selected_offset; + selected_matchLength = next_matchLength; + selected_offset = next_offset; + if (next_matchLength > candidate_pos) break; /* last match elected, first match to encode */ + assert(next_matchLength > 0); /* can be 1, means literal */ + candidate_pos -= next_matchLength; + } } + + /* encode all recorded sequences in order */ + { int rPos = 0; /* relative position (to ip) */ + while (rPos < last_match_pos) { + int const ml = opt[rPos].mlen; + int const offset = opt[rPos].off; + if (ml == 1) { ip++; rPos++; continue; } /* literal; note: can end up with several literals, in which case, skip them */ + rPos += ml; + assert(ml >= MINMATCH); + assert((offset >= 1) && (offset <= LZ4_DISTANCE_MAX)); + opSaved = op; + if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ip - offset, limit, oend) ) { /* updates ip, op and anchor */ + ovml = ml; + ovref = ip - offset; + goto _dest_overflow; + } } } + } /* while (ip <= mflimit) */ + +_last_literals: + /* Encode Last Literals */ + { size_t lastRunSize = (size_t)(iend - anchor); /* literals */ + size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255; + size_t const totalSize = 1 + llAdd + lastRunSize; + if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */ + if (limit && (op + totalSize > oend)) { + if (limit == limitedOutput) { /* Check output limit */ + retval = 0; + goto _return_label; + } + /* adapt lastRunSize to fill 'dst' */ + lastRunSize = (size_t)(oend - op) - 1 /*token*/; + llAdd = (lastRunSize + 256 - RUN_MASK) / 256; + lastRunSize -= llAdd; + } + DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize); + ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */ + + if (lastRunSize >= RUN_MASK) { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = (RUN_MASK << ML_BITS); + for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRunSize << ML_BITS); + } + LZ4_memcpy(op, anchor, lastRunSize); + op += lastRunSize; + } + + /* End */ + *srcSizePtr = (int) (((const char*)ip) - source); + retval = (int) ((char*)op-dst); + goto _return_label; + +_dest_overflow: +if (limit == fillOutput) { + /* Assumption : ip, anchor, ovml and ovref must be set correctly */ + size_t const ll = (size_t)(ip - anchor); + size_t const ll_addbytes = (ll + 240) / 255; + size_t const ll_totalCost = 1 + ll_addbytes + ll; + BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */ + DEBUGLOG(6, "Last sequence overflowing (only %i bytes remaining)", (int)(oend-1-opSaved)); + op = opSaved; /* restore correct out pointer */ + if (op + ll_totalCost <= maxLitPos) { + /* ll validated; now adjust match length */ + size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost)); + size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255); + assert(maxMlSize < INT_MAX); assert(ovml >= 0); + if ((size_t)ovml > maxMlSize) ovml = (int)maxMlSize; + if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ovml >= MFLIMIT) { + DEBUGLOG(6, "Space to end : %i + ml (%i)", (int)((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1), ovml); + DEBUGLOG(6, "Before : ip = %p, anchor = %p", ip, anchor); + LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ovml, ovref, notLimited, oend); + DEBUGLOG(6, "After : ip = %p, anchor = %p", ip, anchor); + } } + goto _last_literals; +} +_return_label: +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + FREEMEM(opt); +#endif + return retval; +} + +} diff --git a/Externals/tracy/public/common/tracy_lz4hc.hpp b/Externals/tracy/public/common/tracy_lz4hc.hpp new file mode 100644 index 00000000000..460cbae7f04 --- /dev/null +++ b/Externals/tracy/public/common/tracy_lz4hc.hpp @@ -0,0 +1,405 @@ +/* + LZ4 HC - High Compression Mode of LZ4 + Header File + Copyright (C) 2011-2020, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/lz4/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +#ifndef TRACY_LZ4_HC_H_19834876238432 +#define TRACY_LZ4_HC_H_19834876238432 + +/* --- Dependency --- */ +/* note : lz4hc requires lz4.h/lz4.c for compilation */ +#include "tracy_lz4.hpp" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */ + + +/* --- Useful constants --- */ +#define LZ4HC_CLEVEL_MIN 3 +#define LZ4HC_CLEVEL_DEFAULT 9 +#define LZ4HC_CLEVEL_OPT_MIN 10 +#define LZ4HC_CLEVEL_MAX 12 + +namespace tracy +{ + +/*-************************************ + * Block Compression + **************************************/ +/*! LZ4_compress_HC() : + * Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm. + * `dst` must be already allocated. + * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h") + * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h") + * `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work. + * Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX. + * @return : the number of bytes written into 'dst' + * or 0 if compression fails. + */ +LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel); + + +/* Note : + * Decompression functions are provided within "lz4.h" (BSD license) + */ + + +/*! LZ4_compress_HC_extStateHC() : + * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`. + * `state` size is provided by LZ4_sizeofStateHC(). + * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly). + */ +LZ4LIB_API int LZ4_sizeofStateHC(void); +LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); + + +/*! LZ4_compress_HC_destSize() : v1.9.0+ + * Will compress as much data as possible from `src` + * to fit into `targetDstSize` budget. + * Result is provided in 2 parts : + * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize) + * or 0 if compression fails. + * `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src` + */ +LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC, + const char* src, char* dst, + int* srcSizePtr, int targetDstSize, + int compressionLevel); + + +/*-************************************ + * Streaming Compression + * Bufferless synchronous API + **************************************/ + typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */ + +/*! LZ4_createStreamHC() and LZ4_freeStreamHC() : + * These functions create and release memory for LZ4 HC streaming state. + * Newly created states are automatically initialized. + * A same state can be used multiple times consecutively, + * starting with LZ4_resetStreamHC_fast() to start a new stream of blocks. + */ +LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void); +LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr); + +/* + These functions compress data in successive blocks of any size, + using previous blocks as dictionary, to improve compression ratio. + One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks. + There is an exception for ring buffers, which can be smaller than 64 KB. + Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue(). + + Before starting compression, state must be allocated and properly initialized. + LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT. + + Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream) + or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental). + LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once, + which is automatically the case when state is created using LZ4_createStreamHC(). + + After reset, a first "fictional block" can be designated as initial dictionary, + using LZ4_loadDictHC() (Optional). + + Invoke LZ4_compress_HC_continue() to compress each successive block. + The number of blocks is unlimited. + Previous input blocks, including initial dictionary when present, + must remain accessible and unmodified during compression. + + It's allowed to update compression level anytime between blocks, + using LZ4_setCompressionLevel() (experimental). + + 'dst' buffer should be sized to handle worst case scenarios + (see LZ4_compressBound(), it ensures compression success). + In case of failure, the API does not guarantee recovery, + so the state _must_ be reset. + To ensure compression success + whenever `dst` buffer size cannot be made >= LZ4_compressBound(), + consider using LZ4_compress_HC_continue_destSize(). + + Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks, + it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC(). + Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB) + + After completing a streaming compression, + it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state, + just by resetting it, using LZ4_resetStreamHC_fast(). +*/ + +LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */ +LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize); + +LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, + const char* src, char* dst, + int srcSize, int maxDstSize); + +/*! LZ4_compress_HC_continue_destSize() : v1.9.0+ + * Similar to LZ4_compress_HC_continue(), + * but will read as much data as possible from `src` + * to fit into `targetDstSize` budget. + * Result is provided into 2 parts : + * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize) + * or 0 if compression fails. + * `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`. + * Note that this function may not consume the entire input. + */ +LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr, + const char* src, char* dst, + int* srcSizePtr, int targetDstSize); + +LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize); + + + +/*^********************************************** + * !!!!!! STATIC LINKING ONLY !!!!!! + ***********************************************/ + +/*-****************************************************************** + * PRIVATE DEFINITIONS : + * Do not use these definitions directly. + * They are merely exposed to allow static allocation of `LZ4_streamHC_t`. + * Declare an `LZ4_streamHC_t` directly, rather than any type below. + * Even then, only do so in the context of static linking, as definitions may change between versions. + ********************************************************************/ + +#define LZ4HC_DICTIONARY_LOGSIZE 16 +#define LZ4HC_MAXD (1<= LZ4HC_CLEVEL_OPT_MIN. + */ +LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed( + LZ4_streamHC_t* LZ4_streamHCPtr, int favor); + +/*! LZ4_resetStreamHC_fast() : v1.9.0+ + * When an LZ4_streamHC_t is known to be in a internally coherent state, + * it can often be prepared for a new compression with almost no work, only + * sometimes falling back to the full, expensive reset that is always required + * when the stream is in an indeterminate state (i.e., the reset performed by + * LZ4_resetStreamHC()). + * + * LZ4_streamHCs are guaranteed to be in a valid state when: + * - returned from LZ4_createStreamHC() + * - reset by LZ4_resetStreamHC() + * - memset(stream, 0, sizeof(LZ4_streamHC_t)) + * - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast() + * - the stream was in a valid state and was then used in any compression call + * that returned success + * - the stream was in an indeterminate state and was used in a compression + * call that fully reset the state (LZ4_compress_HC_extStateHC()) and that + * returned success + * + * Note: + * A stream that was last used in a compression call that returned an error + * may be passed to this function. However, it will be fully reset, which will + * clear any existing history and settings from the context. + */ +LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast( + LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); + +/*! LZ4_compress_HC_extStateHC_fastReset() : + * A variant of LZ4_compress_HC_extStateHC(). + * + * Using this variant avoids an expensive initialization step. It is only safe + * to call if the state buffer is known to be correctly initialized already + * (see above comment on LZ4_resetStreamHC_fast() for a definition of + * "correctly initialized"). From a high level, the difference is that this + * function initializes the provided state with a call to + * LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a + * call to LZ4_resetStreamHC(). + */ +LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset ( + void* state, + const char* src, char* dst, + int srcSize, int dstCapacity, + int compressionLevel); + +/*! LZ4_attach_HC_dictionary() : + * This is an experimental API that allows for the efficient use of a + * static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a + * working LZ4_streamHC_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDictHC() should + * be expected to work. + * + * Alternatively, the provided dictionary stream pointer may be NULL, in which + * case any existing dictionary stream is unset. + * + * A dictionary should only be attached to a stream without any history (i.e., + * a stream that has just been reset). + * + * The dictionary will remain attached to the working stream only for the + * current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the + * dictionary context association from the working stream. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the lifetime of the stream session. + */ +LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary( + LZ4_streamHC_t *working_stream, + const LZ4_streamHC_t *dictionary_stream); + +} + +#endif /* LZ4_HC_SLO_098092834 */ +#endif /* LZ4_HC_STATIC_LINKING_ONLY */ diff --git a/Externals/tracy/public/libbacktrace/LICENSE b/Externals/tracy/public/libbacktrace/LICENSE new file mode 100644 index 00000000000..097d2774e5d --- /dev/null +++ b/Externals/tracy/public/libbacktrace/LICENSE @@ -0,0 +1,29 @@ +# Copyright (C) 2012-2016 Free Software Foundation, Inc. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: + +# (1) Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# (2) Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. + +# (3) The name of the author may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. diff --git a/Externals/tracy/public/libbacktrace/alloc.cpp b/Externals/tracy/public/libbacktrace/alloc.cpp new file mode 100644 index 00000000000..a365a4860ac --- /dev/null +++ b/Externals/tracy/public/libbacktrace/alloc.cpp @@ -0,0 +1,174 @@ +/* alloc.c -- Memory allocation without mmap. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include + +#include "backtrace.hpp" +#include "internal.hpp" + +#include "../common/TracyAlloc.hpp" + +namespace tracy +{ + +/* Allocation routines to use on systems that do not support anonymous + mmap. This implementation just uses malloc, which means that the + backtrace functions may not be safely invoked from a signal + handler. */ + +/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't + report an error. */ + +void * +backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED, + size_t size, backtrace_error_callback error_callback, + void *data) +{ + void *ret; + + ret = tracy_malloc (size); + if (ret == NULL) + { + if (error_callback) + error_callback (data, "malloc", errno); + } + return ret; +} + +/* Free memory. */ + +void +backtrace_free (struct backtrace_state *state ATTRIBUTE_UNUSED, + void *p, size_t size ATTRIBUTE_UNUSED, + backtrace_error_callback error_callback ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + tracy_free (p); +} + +/* Grow VEC by SIZE bytes. */ + +void * +backtrace_vector_grow (struct backtrace_state *state ATTRIBUTE_UNUSED, + size_t size, backtrace_error_callback error_callback, + void *data, struct backtrace_vector *vec) +{ + void *ret; + + if (size > vec->alc) + { + size_t alc; + void *base; + + if (vec->size == 0) + alc = 32 * size; + else if (vec->size >= 4096) + alc = vec->size + 4096; + else + alc = 2 * vec->size; + + if (alc < vec->size + size) + alc = vec->size + size; + + base = tracy_realloc (vec->base, alc); + if (base == NULL) + { + error_callback (data, "realloc", errno); + return NULL; + } + + vec->base = base; + vec->alc = alc - vec->size; + } + + ret = (char *) vec->base + vec->size; + vec->size += size; + vec->alc -= size; + return ret; +} + +/* Finish the current allocation on VEC. */ + +void * +backtrace_vector_finish (struct backtrace_state *state, + struct backtrace_vector *vec, + backtrace_error_callback error_callback, + void *data) +{ + void *ret; + + /* With this allocator we call realloc in backtrace_vector_grow, + which means we can't easily reuse the memory here. So just + release it. */ + if (!backtrace_vector_release (state, vec, error_callback, data)) + return NULL; + ret = vec->base; + vec->base = NULL; + vec->size = 0; + vec->alc = 0; + return ret; +} + +/* Release any extra space allocated for VEC. */ + +int +backtrace_vector_release (struct backtrace_state *state ATTRIBUTE_UNUSED, + struct backtrace_vector *vec, + backtrace_error_callback error_callback, + void *data) +{ + vec->alc = 0; + + if (vec->size == 0) + { + /* As of C17, realloc with size 0 is marked as an obsolescent feature, use + free instead. */ + tracy_free (vec->base); + vec->base = NULL; + return 1; + } + + vec->base = tracy_realloc (vec->base, vec->size); + if (vec->base == NULL) + { + error_callback (data, "realloc", errno); + return 0; + } + + return 1; +} + +} diff --git a/Externals/tracy/public/libbacktrace/backtrace.hpp b/Externals/tracy/public/libbacktrace/backtrace.hpp new file mode 100644 index 00000000000..e4be297a9ed --- /dev/null +++ b/Externals/tracy/public/libbacktrace/backtrace.hpp @@ -0,0 +1,186 @@ +/* backtrace.h -- Public header file for stack backtrace library. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef BACKTRACE_H +#define BACKTRACE_H + +#include +#include +#include + +namespace tracy +{ + +/* The backtrace state. This struct is intentionally not defined in + the public interface. */ + +struct backtrace_state; + +/* The type of the error callback argument to backtrace functions. + This function, if not NULL, will be called for certain error cases. + The DATA argument is passed to the function that calls this one. + The MSG argument is an error message. The ERRNUM argument, if + greater than 0, holds an errno value. The MSG buffer may become + invalid after this function returns. + + As a special case, the ERRNUM argument will be passed as -1 if no + debug info can be found for the executable, or if the debug info + exists but has an unsupported version, but the function requires + debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in + this case will be something along the lines of "no debug info". + Similarly, ERRNUM will be passed as -1 if there is no symbol table, + but the function requires a symbol table (e.g., backtrace_syminfo). + This may be used as a signal that some other approach should be + tried. */ + +typedef void (*backtrace_error_callback) (void *data, const char *msg, + int errnum); + +/* Create state information for the backtrace routines. This must be + called before any of the other routines, and its return value must + be passed to all of the other routines. FILENAME is the path name + of the executable file; if it is NULL the library will try + system-specific path names. If not NULL, FILENAME must point to a + permanent buffer. If THREADED is non-zero the state may be + accessed by multiple threads simultaneously, and the library will + use appropriate atomic operations. If THREADED is zero the state + may only be accessed by one thread at a time. This returns a state + pointer on success, NULL on error. If an error occurs, this will + call the ERROR_CALLBACK routine. + + Calling this function allocates resources that cannot be freed. + There is no backtrace_free_state function. The state is used to + cache information that is expensive to recompute. Programs are + expected to call this function at most once and to save the return + value for all later calls to backtrace functions. */ + +extern struct backtrace_state *backtrace_create_state ( + const char *filename, int threaded, + backtrace_error_callback error_callback, void *data); + +/* The type of the callback argument to the backtrace_full function. + DATA is the argument passed to backtrace_full. PC is the program + counter. FILENAME is the name of the file containing PC, or NULL + if not available. LINENO is the line number in FILENAME containing + PC, or 0 if not available. FUNCTION is the name of the function + containing PC, or NULL if not available. This should return 0 to + continuing tracing. The FILENAME and FUNCTION buffers may become + invalid after this function returns. */ + +typedef int (*backtrace_full_callback) (void *data, uintptr_t pc, uintptr_t lowaddr, + const char *filename, int lineno, + const char *function); + +/* Get a full stack backtrace. SKIP is the number of frames to skip; + passing 0 will start the trace with the function calling + backtrace_full. DATA is passed to the callback routine. If any + call to CALLBACK returns a non-zero value, the stack backtrace + stops, and backtrace returns that value; this may be used to limit + the number of stack frames desired. If all calls to CALLBACK + return 0, backtrace returns 0. The backtrace_full function will + make at least one call to either CALLBACK or ERROR_CALLBACK. This + function requires debug info for the executable. */ + +extern int backtrace_full (struct backtrace_state *state, int skip, + backtrace_full_callback callback, + backtrace_error_callback error_callback, + void *data); + +/* The type of the callback argument to the backtrace_simple function. + DATA is the argument passed to simple_backtrace. PC is the program + counter. This should return 0 to continue tracing. */ + +typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc); + +/* Get a simple backtrace. SKIP is the number of frames to skip, as + in backtrace. DATA is passed to the callback routine. If any call + to CALLBACK returns a non-zero value, the stack backtrace stops, + and backtrace_simple returns that value. Otherwise + backtrace_simple returns 0. The backtrace_simple function will + make at least one call to either CALLBACK or ERROR_CALLBACK. This + function does not require any debug info for the executable. */ + +extern int backtrace_simple (struct backtrace_state *state, int skip, + backtrace_simple_callback callback, + backtrace_error_callback error_callback, + void *data); + +/* Print the current backtrace in a user readable format to a FILE. + SKIP is the number of frames to skip, as in backtrace_full. Any + error messages are printed to stderr. This function requires debug + info for the executable. */ + +extern void backtrace_print (struct backtrace_state *state, int skip, FILE *); + +/* Given PC, a program counter in the current program, call the + callback function with filename, line number, and function name + information. This will normally call the callback function exactly + once. However, if the PC happens to describe an inlined call, and + the debugging information contains the necessary information, then + this may call the callback function multiple times. This will make + at least one call to either CALLBACK or ERROR_CALLBACK. This + returns the first non-zero value returned by CALLBACK, or 0. */ + +extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, + void *data); + +/* The type of the callback argument to backtrace_syminfo. DATA and + PC are the arguments passed to backtrace_syminfo. SYMNAME is the + name of the symbol for the corresponding code. SYMVAL is the + value and SYMSIZE is the size of the symbol. SYMNAME will be NULL + if no error occurred but the symbol could not be found. */ + +typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc, + const char *symname, + uintptr_t symval, + uintptr_t symsize); + +/* Given ADDR, an address or program counter in the current program, + call the callback information with the symbol name and value + describing the function or variable in which ADDR may be found. + This will call either CALLBACK or ERROR_CALLBACK exactly once. + This returns 1 on success, 0 on failure. This function requires + the symbol table but does not require the debug info. Note that if + the symbol table is present but ADDR could not be found in the + table, CALLBACK will be called with a NULL SYMNAME argument. + Returns 1 on success, 0 on error. */ + +extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t addr, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback, + void *data); + +} + +#endif diff --git a/Externals/tracy/public/libbacktrace/config.h b/Externals/tracy/public/libbacktrace/config.h new file mode 100644 index 00000000000..87e38a95b58 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/config.h @@ -0,0 +1,26 @@ +#include +#if defined(__linux__) && !defined(__GLIBC__) && !defined(__WORDSIZE) +// include __WORDSIZE headers for musl +# include +#endif +#if __WORDSIZE == 64 +# define BACKTRACE_ELF_SIZE 64 +#else +# define BACKTRACE_ELF_SIZE 32 +#endif + +#define HAVE_DLFCN_H 1 +#define HAVE_FCNTL 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LSTAT 1 +#define HAVE_READLINK 1 +#define HAVE_DL_ITERATE_PHDR 1 +#define HAVE_ATOMIC_FUNCTIONS 1 +#define HAVE_DECL_STRNLEN 1 + +#ifdef __APPLE__ +# define HAVE_MACH_O_DYLD_H 1 +#elif defined BSD +# define HAVE_KERN_PROC 1 +# define HAVE_KERN_PROC_ARGS 1 +#endif diff --git a/Externals/tracy/public/libbacktrace/dwarf.cpp b/Externals/tracy/public/libbacktrace/dwarf.cpp new file mode 100644 index 00000000000..f3899cbce10 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/dwarf.cpp @@ -0,0 +1,4425 @@ +/* dwarf.c -- Get file/line information from DWARF for backtraces. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include + +#include "filenames.hpp" + +#include "backtrace.hpp" +#include "internal.hpp" + +namespace tracy +{ + +/* DWARF constants. */ + +enum dwarf_tag { + DW_TAG_entry_point = 0x3, + DW_TAG_compile_unit = 0x11, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_subprogram = 0x2e, + DW_TAG_skeleton_unit = 0x4a, +}; + +enum dwarf_form { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16, + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_ref_sig8 = 0x20, + DW_FORM_strx = 0x1a, + DW_FORM_addrx = 0x1b, + DW_FORM_ref_sup4 = 0x1c, + DW_FORM_strp_sup = 0x1d, + DW_FORM_data16 = 0x1e, + DW_FORM_line_strp = 0x1f, + DW_FORM_implicit_const = 0x21, + DW_FORM_loclistx = 0x22, + DW_FORM_rnglistx = 0x23, + DW_FORM_ref_sup8 = 0x24, + DW_FORM_strx1 = 0x25, + DW_FORM_strx2 = 0x26, + DW_FORM_strx3 = 0x27, + DW_FORM_strx4 = 0x28, + DW_FORM_addrx1 = 0x29, + DW_FORM_addrx2 = 0x2a, + DW_FORM_addrx3 = 0x2b, + DW_FORM_addrx4 = 0x2c, + DW_FORM_GNU_addr_index = 0x1f01, + DW_FORM_GNU_str_index = 0x1f02, + DW_FORM_GNU_ref_alt = 0x1f20, + DW_FORM_GNU_strp_alt = 0x1f21 +}; + +enum dwarf_attribute { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_subscr_data = 0x0a, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_element_list = 0x0f, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_member = 0x14, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_bit_stride = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_items = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_byte_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + DW_AT_description = 0x5a, + DW_AT_binary_scale = 0x5b, + DW_AT_decimal_scale = 0x5c, + DW_AT_small = 0x5d, + DW_AT_decimal_sign = 0x5e, + DW_AT_digit_count = 0x5f, + DW_AT_picture_string = 0x60, + DW_AT_mutable = 0x61, + DW_AT_threads_scaled = 0x62, + DW_AT_explicit = 0x63, + DW_AT_object_pointer = 0x64, + DW_AT_endianity = 0x65, + DW_AT_elemental = 0x66, + DW_AT_pure = 0x67, + DW_AT_recursive = 0x68, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + DW_AT_string_length_bit_size = 0x6f, + DW_AT_string_length_byte_size = 0x70, + DW_AT_rank = 0x71, + DW_AT_str_offsets_base = 0x72, + DW_AT_addr_base = 0x73, + DW_AT_rnglists_base = 0x74, + DW_AT_dwo_name = 0x76, + DW_AT_reference = 0x77, + DW_AT_rvalue_reference = 0x78, + DW_AT_macros = 0x79, + DW_AT_call_all_calls = 0x7a, + DW_AT_call_all_source_calls = 0x7b, + DW_AT_call_all_tail_calls = 0x7c, + DW_AT_call_return_pc = 0x7d, + DW_AT_call_value = 0x7e, + DW_AT_call_origin = 0x7f, + DW_AT_call_parameter = 0x80, + DW_AT_call_pc = 0x81, + DW_AT_call_tail_call = 0x82, + DW_AT_call_target = 0x83, + DW_AT_call_target_clobbered = 0x84, + DW_AT_call_data_location = 0x85, + DW_AT_call_data_value = 0x86, + DW_AT_noreturn = 0x87, + DW_AT_alignment = 0x88, + DW_AT_export_symbols = 0x89, + DW_AT_deleted = 0x8a, + DW_AT_defaulted = 0x8b, + DW_AT_loclists_base = 0x8c, + DW_AT_lo_user = 0x2000, + DW_AT_hi_user = 0x3fff, + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_HP_block_index = 0x2000, + DW_AT_HP_unmodifiable = 0x2001, + DW_AT_HP_prologue = 0x2005, + DW_AT_HP_epilogue = 0x2008, + DW_AT_HP_actuals_stmt_list = 0x2010, + DW_AT_HP_proc_per_section = 0x2011, + DW_AT_HP_raw_data_ptr = 0x2012, + DW_AT_HP_pass_by_reference = 0x2013, + DW_AT_HP_opt_level = 0x2014, + DW_AT_HP_prof_version_id = 0x2015, + DW_AT_HP_opt_flags = 0x2016, + DW_AT_HP_cold_region_low_pc = 0x2017, + DW_AT_HP_cold_region_high_pc = 0x2018, + DW_AT_HP_all_variables_modifiable = 0x2019, + DW_AT_HP_linkage_name = 0x201a, + DW_AT_HP_prof_flags = 0x201b, + DW_AT_HP_unit_name = 0x201f, + DW_AT_HP_unit_size = 0x2020, + DW_AT_HP_widened_byte_size = 0x2021, + DW_AT_HP_definition_points = 0x2022, + DW_AT_HP_default_location = 0x2023, + DW_AT_HP_is_result_param = 0x2029, + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106, + DW_AT_GNU_vector = 0x2107, + DW_AT_GNU_guarded_by = 0x2108, + DW_AT_GNU_pt_guarded_by = 0x2109, + DW_AT_GNU_guarded = 0x210a, + DW_AT_GNU_pt_guarded = 0x210b, + DW_AT_GNU_locks_excluded = 0x210c, + DW_AT_GNU_exclusive_locks_required = 0x210d, + DW_AT_GNU_shared_locks_required = 0x210e, + DW_AT_GNU_odr_signature = 0x210f, + DW_AT_GNU_template_name = 0x2110, + DW_AT_GNU_call_site_value = 0x2111, + DW_AT_GNU_call_site_data_value = 0x2112, + DW_AT_GNU_call_site_target = 0x2113, + DW_AT_GNU_call_site_target_clobbered = 0x2114, + DW_AT_GNU_tail_call = 0x2115, + DW_AT_GNU_all_tail_call_sites = 0x2116, + DW_AT_GNU_all_call_sites = 0x2117, + DW_AT_GNU_all_source_call_sites = 0x2118, + DW_AT_GNU_macros = 0x2119, + DW_AT_GNU_deleted = 0x211a, + DW_AT_GNU_dwo_name = 0x2130, + DW_AT_GNU_dwo_id = 0x2131, + DW_AT_GNU_ranges_base = 0x2132, + DW_AT_GNU_addr_base = 0x2133, + DW_AT_GNU_pubnames = 0x2134, + DW_AT_GNU_pubtypes = 0x2135, + DW_AT_GNU_discriminator = 0x2136, + DW_AT_GNU_locviews = 0x2137, + DW_AT_GNU_entry_view = 0x2138, + DW_AT_VMS_rtnbeg_pd_address = 0x2201, + DW_AT_use_GNAT_descriptive_type = 0x2301, + DW_AT_GNAT_descriptive_type = 0x2302, + DW_AT_GNU_numerator = 0x2303, + DW_AT_GNU_denominator = 0x2304, + DW_AT_GNU_bias = 0x2305, + DW_AT_upc_threads_scaled = 0x3210, + DW_AT_PGI_lbase = 0x3a00, + DW_AT_PGI_soffset = 0x3a01, + DW_AT_PGI_lstride = 0x3a02, + DW_AT_APPLE_optimized = 0x3fe1, + DW_AT_APPLE_flags = 0x3fe2, + DW_AT_APPLE_isa = 0x3fe3, + DW_AT_APPLE_block = 0x3fe4, + DW_AT_APPLE_major_runtime_vers = 0x3fe5, + DW_AT_APPLE_runtime_class = 0x3fe6, + DW_AT_APPLE_omit_frame_ptr = 0x3fe7, + DW_AT_APPLE_property_name = 0x3fe8, + DW_AT_APPLE_property_getter = 0x3fe9, + DW_AT_APPLE_property_setter = 0x3fea, + DW_AT_APPLE_property_attribute = 0x3feb, + DW_AT_APPLE_objc_complete_type = 0x3fec, + DW_AT_APPLE_property = 0x3fed +}; + +enum dwarf_line_number_op { + DW_LNS_extended_op = 0x0, + DW_LNS_copy = 0x1, + DW_LNS_advance_pc = 0x2, + DW_LNS_advance_line = 0x3, + DW_LNS_set_file = 0x4, + DW_LNS_set_column = 0x5, + DW_LNS_negate_stmt = 0x6, + DW_LNS_set_basic_block = 0x7, + DW_LNS_const_add_pc = 0x8, + DW_LNS_fixed_advance_pc = 0x9, + DW_LNS_set_prologue_end = 0xa, + DW_LNS_set_epilogue_begin = 0xb, + DW_LNS_set_isa = 0xc, +}; + +enum dwarf_extended_line_number_op { + DW_LNE_end_sequence = 0x1, + DW_LNE_set_address = 0x2, + DW_LNE_define_file = 0x3, + DW_LNE_set_discriminator = 0x4, +}; + +enum dwarf_line_number_content_type { + DW_LNCT_path = 0x1, + DW_LNCT_directory_index = 0x2, + DW_LNCT_timestamp = 0x3, + DW_LNCT_size = 0x4, + DW_LNCT_MD5 = 0x5, + DW_LNCT_lo_user = 0x2000, + DW_LNCT_hi_user = 0x3fff +}; + +enum dwarf_range_list_entry { + DW_RLE_end_of_list = 0x00, + DW_RLE_base_addressx = 0x01, + DW_RLE_startx_endx = 0x02, + DW_RLE_startx_length = 0x03, + DW_RLE_offset_pair = 0x04, + DW_RLE_base_address = 0x05, + DW_RLE_start_end = 0x06, + DW_RLE_start_length = 0x07 +}; + +enum dwarf_unit_type { + DW_UT_compile = 0x01, + DW_UT_type = 0x02, + DW_UT_partial = 0x03, + DW_UT_skeleton = 0x04, + DW_UT_split_compile = 0x05, + DW_UT_split_type = 0x06, + DW_UT_lo_user = 0x80, + DW_UT_hi_user = 0xff +}; + +#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN + +/* If strnlen is not declared, provide our own version. */ + +static size_t +xstrnlen (const char *s, size_t maxlen) +{ + size_t i; + + for (i = 0; i < maxlen; ++i) + if (s[i] == '\0') + break; + return i; +} + +#define strnlen xstrnlen + +#endif + +/* A buffer to read DWARF info. */ + +struct dwarf_buf +{ + /* Buffer name for error messages. */ + const char *name; + /* Start of the buffer. */ + const unsigned char *start; + /* Next byte to read. */ + const unsigned char *buf; + /* The number of bytes remaining. */ + size_t left; + /* Whether the data is big-endian. */ + int is_bigendian; + /* Error callback routine. */ + backtrace_error_callback error_callback; + /* Data for error_callback. */ + void *data; + /* Non-zero if we've reported an underflow error. */ + int reported_underflow; +}; + +/* A single attribute in a DWARF abbreviation. */ + +struct attr +{ + /* The attribute name. */ + enum dwarf_attribute name; + /* The attribute form. */ + enum dwarf_form form; + /* The attribute value, for DW_FORM_implicit_const. */ + int64_t val; +}; + +/* A single DWARF abbreviation. */ + +struct abbrev +{ + /* The abbrev code--the number used to refer to the abbrev. */ + uint64_t code; + /* The entry tag. */ + enum dwarf_tag tag; + /* Non-zero if this abbrev has child entries. */ + int has_children; + /* The number of attributes. */ + size_t num_attrs; + /* The attributes. */ + struct attr *attrs; +}; + +/* The DWARF abbreviations for a compilation unit. This structure + only exists while reading the compilation unit. Most DWARF readers + seem to a hash table to map abbrev ID's to abbrev entries. + However, we primarily care about GCC, and GCC simply issues ID's in + numerical order starting at 1. So we simply keep a sorted vector, + and try to just look up the code. */ + +struct abbrevs +{ + /* The number of abbrevs in the vector. */ + size_t num_abbrevs; + /* The abbrevs, sorted by the code field. */ + struct abbrev *abbrevs; +}; + +/* The different kinds of attribute values. */ + +enum attr_val_encoding +{ + /* No attribute value. */ + ATTR_VAL_NONE, + /* An address. */ + ATTR_VAL_ADDRESS, + /* An index into the .debug_addr section, whose value is relative to + the DW_AT_addr_base attribute of the compilation unit. */ + ATTR_VAL_ADDRESS_INDEX, + /* A unsigned integer. */ + ATTR_VAL_UINT, + /* A sigd integer. */ + ATTR_VAL_SINT, + /* A string. */ + ATTR_VAL_STRING, + /* An index into the .debug_str_offsets section. */ + ATTR_VAL_STRING_INDEX, + /* An offset to other data in the containing unit. */ + ATTR_VAL_REF_UNIT, + /* An offset to other data within the .debug_info section. */ + ATTR_VAL_REF_INFO, + /* An offset to other data within the alt .debug_info section. */ + ATTR_VAL_REF_ALT_INFO, + /* An offset to data in some other section. */ + ATTR_VAL_REF_SECTION, + /* A type signature. */ + ATTR_VAL_REF_TYPE, + /* An index into the .debug_rnglists section. */ + ATTR_VAL_RNGLISTS_INDEX, + /* A block of data (not represented). */ + ATTR_VAL_BLOCK, + /* An expression (not represented). */ + ATTR_VAL_EXPR, +}; + +/* An attribute value. */ + +struct attr_val +{ + /* How the value is stored in the field u. */ + enum attr_val_encoding encoding; + union + { + /* ATTR_VAL_ADDRESS*, ATTR_VAL_UINT, ATTR_VAL_REF*. */ + uint64_t uint; + /* ATTR_VAL_SINT. */ + int64_t sint; + /* ATTR_VAL_STRING. */ + const char *string; + /* ATTR_VAL_BLOCK not stored. */ + } u; +}; + +/* The line number program header. */ + +struct line_header +{ + /* The version of the line number information. */ + int version; + /* Address size. */ + int addrsize; + /* The minimum instruction length. */ + unsigned int min_insn_len; + /* The maximum number of ops per instruction. */ + unsigned int max_ops_per_insn; + /* The line base for special opcodes. */ + int line_base; + /* The line range for special opcodes. */ + unsigned int line_range; + /* The opcode base--the first special opcode. */ + unsigned int opcode_base; + /* Opcode lengths, indexed by opcode - 1. */ + const unsigned char *opcode_lengths; + /* The number of directory entries. */ + size_t dirs_count; + /* The directory entries. */ + const char **dirs; + /* The number of filenames. */ + size_t filenames_count; + /* The filenames. */ + const char **filenames; +}; + +/* A format description from a line header. */ + +struct line_header_format +{ + int lnct; /* LNCT code. */ + enum dwarf_form form; /* Form of entry data. */ +}; + +/* Map a single PC value to a file/line. We will keep a vector of + these sorted by PC value. Each file/line will be correct from the + PC up to the PC of the next entry if there is one. We allocate one + extra entry at the end so that we can use bsearch. */ + +struct line +{ + /* PC. */ + uintptr_t pc; + /* File name. Many entries in the array are expected to point to + the same file name. */ + const char *filename; + /* Line number. */ + int lineno; + /* Index of the object in the original array read from the DWARF + section, before it has been sorted. The index makes it possible + to use Quicksort and maintain stability. */ + int idx; +}; + +/* A growable vector of line number information. This is used while + reading the line numbers. */ + +struct line_vector +{ + /* Memory. This is an array of struct line. */ + struct backtrace_vector vec; + /* Number of valid mappings. */ + size_t count; +}; + +/* A function described in the debug info. */ + +struct function +{ + /* The name of the function. */ + const char *name; + /* If this is an inlined function, the filename of the call + site. */ + const char *caller_filename; + /* If this is an inlined function, the line number of the call + site. */ + int caller_lineno; + /* Map PC ranges to inlined functions. */ + struct function_addrs *function_addrs; + size_t function_addrs_count; +}; + +/* An address range for a function. This maps a PC value to a + specific function. */ + +struct function_addrs +{ + /* Range is LOW <= PC < HIGH. */ + uintptr_t low; + uintptr_t high; + /* Function for this address range. */ + struct function *function; +}; + +/* A growable vector of function address ranges. */ + +struct function_vector +{ + /* Memory. This is an array of struct function_addrs. */ + struct backtrace_vector vec; + /* Number of address ranges present. */ + size_t count; +}; + +/* A DWARF compilation unit. This only holds the information we need + to map a PC to a file and line. */ + +struct unit +{ + /* The first entry for this compilation unit. */ + const unsigned char *unit_data; + /* The length of the data for this compilation unit. */ + size_t unit_data_len; + /* The offset of UNIT_DATA from the start of the information for + this compilation unit. */ + size_t unit_data_offset; + /* Offset of the start of the compilation unit from the start of the + .debug_info section. */ + size_t low_offset; + /* Offset of the end of the compilation unit from the start of the + .debug_info section. */ + size_t high_offset; + /* DWARF version. */ + int version; + /* Whether unit is DWARF64. */ + int is_dwarf64; + /* Address size. */ + int addrsize; + /* Offset into line number information. */ + off_t lineoff; + /* Offset of compilation unit in .debug_str_offsets. */ + uint64_t str_offsets_base; + /* Offset of compilation unit in .debug_addr. */ + uint64_t addr_base; + /* Offset of compilation unit in .debug_rnglists. */ + uint64_t rnglists_base; + /* Primary source file. */ + const char *filename; + /* Compilation command working directory. */ + const char *comp_dir; + /* Absolute file name, only set if needed. */ + const char *abs_filename; + /* The abbreviations for this unit. */ + struct abbrevs abbrevs; + + /* The fields above this point are read in during initialization and + may be accessed freely. The fields below this point are read in + as needed, and therefore require care, as different threads may + try to initialize them simultaneously. */ + + /* PC to line number mapping. This is NULL if the values have not + been read. This is (struct line *) -1 if there was an error + reading the values. */ + struct line *lines; + /* Number of entries in lines. */ + size_t lines_count; + /* PC ranges to function. */ + struct function_addrs *function_addrs; + size_t function_addrs_count; +}; + +/* An address range for a compilation unit. This maps a PC value to a + specific compilation unit. Note that we invert the representation + in DWARF: instead of listing the units and attaching a list of + ranges, we list the ranges and have each one point to the unit. + This lets us do a binary search to find the unit. */ + +struct unit_addrs +{ + /* Range is LOW <= PC < HIGH. */ + uintptr_t low; + uintptr_t high; + /* Compilation unit for this address range. */ + struct unit *u; +}; + +/* A growable vector of compilation unit address ranges. */ + +struct unit_addrs_vector +{ + /* Memory. This is an array of struct unit_addrs. */ + struct backtrace_vector vec; + /* Number of address ranges present. */ + size_t count; +}; + +/* A growable vector of compilation unit pointer. */ + +struct unit_vector +{ + struct backtrace_vector vec; + size_t count; +}; + +/* The information we need to map a PC to a file and line. */ + +struct dwarf_data +{ + /* The data for the next file we know about. */ + struct dwarf_data *next; + /* The data for .gnu_debugaltlink. */ + struct dwarf_data *altlink; + /* The base address for this file. */ + uintptr_t base_address; + /* A sorted list of address ranges. */ + struct unit_addrs *addrs; + /* Number of address ranges in list. */ + size_t addrs_count; + /* A sorted list of units. */ + struct unit **units; + /* Number of units in the list. */ + size_t units_count; + /* The unparsed DWARF debug data. */ + struct dwarf_sections dwarf_sections; + /* Whether the data is big-endian or not. */ + int is_bigendian; + /* A vector used for function addresses. We keep this here so that + we can grow the vector as we read more functions. */ + struct function_vector fvec; +}; + +/* Report an error for a DWARF buffer. */ + +static void +dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum) +{ + char b[200]; + + snprintf (b, sizeof b, "%s in %s at %d", + msg, buf->name, (int) (buf->buf - buf->start)); + buf->error_callback (buf->data, b, errnum); +} + +/* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on + error. */ + +static int +require (struct dwarf_buf *buf, size_t count) +{ + if (buf->left >= count) + return 1; + + if (!buf->reported_underflow) + { + dwarf_buf_error (buf, "DWARF underflow", 0); + buf->reported_underflow = 1; + } + + return 0; +} + +/* Advance COUNT bytes in BUF. Return 1 if all is well, 0 on + error. */ + +static int +advance (struct dwarf_buf *buf, size_t count) +{ + if (!require (buf, count)) + return 0; + buf->buf += count; + buf->left -= count; + return 1; +} + +/* Read one zero-terminated string from BUF and advance past the string. */ + +static const char * +read_string (struct dwarf_buf *buf) +{ + const char *p = (const char *)buf->buf; + size_t len = strnlen (p, buf->left); + + /* - If len == left, we ran out of buffer before finding the zero terminator. + Generate an error by advancing len + 1. + - If len < left, advance by len + 1 to skip past the zero terminator. */ + size_t count = len + 1; + + if (!advance (buf, count)) + return NULL; + + return p; +} + +/* Read one byte from BUF and advance 1 byte. */ + +static unsigned char +read_byte (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 1)) + return 0; + return p[0]; +} + +/* Read a signed char from BUF and advance 1 byte. */ + +static signed char +read_sbyte (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 1)) + return 0; + return (*p ^ 0x80) - 0x80; +} + +/* Read a uint16 from BUF and advance 2 bytes. */ + +static uint16_t +read_uint16 (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 2)) + return 0; + if (buf->is_bigendian) + return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; + else + return ((uint16_t) p[1] << 8) | (uint16_t) p[0]; +} + +/* Read a 24 bit value from BUF and advance 3 bytes. */ + +static uint32_t +read_uint24 (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 3)) + return 0; + if (buf->is_bigendian) + return (((uint32_t) p[0] << 16) | ((uint32_t) p[1] << 8) + | (uint32_t) p[2]); + else + return (((uint32_t) p[2] << 16) | ((uint32_t) p[1] << 8) + | (uint32_t) p[0]); +} + +/* Read a uint32 from BUF and advance 4 bytes. */ + +static uint32_t +read_uint32 (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 4)) + return 0; + if (buf->is_bigendian) + return (((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16) + | ((uint32_t) p[2] << 8) | (uint32_t) p[3]); + else + return (((uint32_t) p[3] << 24) | ((uint32_t) p[2] << 16) + | ((uint32_t) p[1] << 8) | (uint32_t) p[0]); +} + +/* Read a uint64 from BUF and advance 8 bytes. */ + +static uint64_t +read_uint64 (struct dwarf_buf *buf) +{ + const unsigned char *p = buf->buf; + + if (!advance (buf, 8)) + return 0; + if (buf->is_bigendian) + return (((uint64_t) p[0] << 56) | ((uint64_t) p[1] << 48) + | ((uint64_t) p[2] << 40) | ((uint64_t) p[3] << 32) + | ((uint64_t) p[4] << 24) | ((uint64_t) p[5] << 16) + | ((uint64_t) p[6] << 8) | (uint64_t) p[7]); + else + return (((uint64_t) p[7] << 56) | ((uint64_t) p[6] << 48) + | ((uint64_t) p[5] << 40) | ((uint64_t) p[4] << 32) + | ((uint64_t) p[3] << 24) | ((uint64_t) p[2] << 16) + | ((uint64_t) p[1] << 8) | (uint64_t) p[0]); +} + +/* Read an offset from BUF and advance the appropriate number of + bytes. */ + +static uint64_t +read_offset (struct dwarf_buf *buf, int is_dwarf64) +{ + if (is_dwarf64) + return read_uint64 (buf); + else + return read_uint32 (buf); +} + +/* Read an address from BUF and advance the appropriate number of + bytes. */ + +static uint64_t +read_address (struct dwarf_buf *buf, int addrsize) +{ + switch (addrsize) + { + case 1: + return read_byte (buf); + case 2: + return read_uint16 (buf); + case 4: + return read_uint32 (buf); + case 8: + return read_uint64 (buf); + default: + dwarf_buf_error (buf, "unrecognized address size", 0); + return 0; + } +} + +/* Return whether a value is the highest possible address, given the + address size. */ + +static int +is_highest_address (uint64_t address, int addrsize) +{ + switch (addrsize) + { + case 1: + return address == (unsigned char) -1; + case 2: + return address == (uint16_t) -1; + case 4: + return address == (uint32_t) -1; + case 8: + return address == (uint64_t) -1; + default: + return 0; + } +} + +/* Read an unsigned LEB128 number. */ + +static uint64_t +read_uleb128 (struct dwarf_buf *buf) +{ + uint64_t ret; + unsigned int shift; + int overflow; + unsigned char b; + + ret = 0; + shift = 0; + overflow = 0; + do + { + const unsigned char *p; + + p = buf->buf; + if (!advance (buf, 1)) + return 0; + b = *p; + if (shift < 64) + ret |= ((uint64_t) (b & 0x7f)) << shift; + else if (!overflow) + { + dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0); + overflow = 1; + } + shift += 7; + } + while ((b & 0x80) != 0); + + return ret; +} + +/* Read a signed LEB128 number. */ + +static int64_t +read_sleb128 (struct dwarf_buf *buf) +{ + uint64_t val; + unsigned int shift; + int overflow; + unsigned char b; + + val = 0; + shift = 0; + overflow = 0; + do + { + const unsigned char *p; + + p = buf->buf; + if (!advance (buf, 1)) + return 0; + b = *p; + if (shift < 64) + val |= ((uint64_t) (b & 0x7f)) << shift; + else if (!overflow) + { + dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0); + overflow = 1; + } + shift += 7; + } + while ((b & 0x80) != 0); + + if ((b & 0x40) != 0 && shift < 64) + val |= ((uint64_t) -1) << shift; + + return (int64_t) val; +} + +/* Return the length of an LEB128 number. */ + +static size_t +leb128_len (const unsigned char *p) +{ + size_t ret; + + ret = 1; + while ((*p & 0x80) != 0) + { + ++p; + ++ret; + } + return ret; +} + +/* Read initial_length from BUF and advance the appropriate number of bytes. */ + +static uint64_t +read_initial_length (struct dwarf_buf *buf, int *is_dwarf64) +{ + uint64_t len; + + len = read_uint32 (buf); + if (len == 0xffffffff) + { + len = read_uint64 (buf); + *is_dwarf64 = 1; + } + else + *is_dwarf64 = 0; + + return len; +} + +/* Free an abbreviations structure. */ + +static void +free_abbrevs (struct backtrace_state *state, struct abbrevs *abbrevs, + backtrace_error_callback error_callback, void *data) +{ + size_t i; + + for (i = 0; i < abbrevs->num_abbrevs; ++i) + backtrace_free (state, abbrevs->abbrevs[i].attrs, + abbrevs->abbrevs[i].num_attrs * sizeof (struct attr), + error_callback, data); + backtrace_free (state, abbrevs->abbrevs, + abbrevs->num_abbrevs * sizeof (struct abbrev), + error_callback, data); + abbrevs->num_abbrevs = 0; + abbrevs->abbrevs = NULL; +} + +/* Read an attribute value. Returns 1 on success, 0 on failure. If + the value can be represented as a uint64_t, sets *VAL and sets + *IS_VALID to 1. We don't try to store the value of other attribute + forms, because we don't care about them. */ + +static int +read_attribute (enum dwarf_form form, uint64_t implicit_val, + struct dwarf_buf *buf, int is_dwarf64, int version, + int addrsize, const struct dwarf_sections *dwarf_sections, + struct dwarf_data *altlink, struct attr_val *val) +{ + /* Avoid warnings about val.u.FIELD may be used uninitialized if + this function is inlined. The warnings aren't valid but can + occur because the different fields are set and used + conditionally. */ + memset (val, 0, sizeof *val); + + switch (form) + { + case DW_FORM_addr: + val->encoding = ATTR_VAL_ADDRESS; + val->u.uint = read_address (buf, addrsize); + return 1; + case DW_FORM_block2: + val->encoding = ATTR_VAL_BLOCK; + return advance (buf, read_uint16 (buf)); + case DW_FORM_block4: + val->encoding = ATTR_VAL_BLOCK; + return advance (buf, read_uint32 (buf)); + case DW_FORM_data2: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_uint16 (buf); + return 1; + case DW_FORM_data4: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_uint32 (buf); + return 1; + case DW_FORM_data8: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_uint64 (buf); + return 1; + case DW_FORM_data16: + val->encoding = ATTR_VAL_BLOCK; + return advance (buf, 16); + case DW_FORM_string: + val->encoding = ATTR_VAL_STRING; + val->u.string = read_string (buf); + return val->u.string == NULL ? 0 : 1; + case DW_FORM_block: + val->encoding = ATTR_VAL_BLOCK; + return advance (buf, read_uleb128 (buf)); + case DW_FORM_block1: + val->encoding = ATTR_VAL_BLOCK; + return advance (buf, read_byte (buf)); + case DW_FORM_data1: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_byte (buf); + return 1; + case DW_FORM_flag: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_byte (buf); + return 1; + case DW_FORM_sdata: + val->encoding = ATTR_VAL_SINT; + val->u.sint = read_sleb128 (buf); + return 1; + case DW_FORM_strp: + { + uint64_t offset; + + offset = read_offset (buf, is_dwarf64); + if (offset >= dwarf_sections->size[DEBUG_STR]) + { + dwarf_buf_error (buf, "DW_FORM_strp out of range", 0); + return 0; + } + val->encoding = ATTR_VAL_STRING; + val->u.string = + (const char *) dwarf_sections->data[DEBUG_STR] + offset; + return 1; + } + case DW_FORM_line_strp: + { + uint64_t offset; + + offset = read_offset (buf, is_dwarf64); + if (offset >= dwarf_sections->size[DEBUG_LINE_STR]) + { + dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0); + return 0; + } + val->encoding = ATTR_VAL_STRING; + val->u.string = + (const char *) dwarf_sections->data[DEBUG_LINE_STR] + offset; + return 1; + } + case DW_FORM_udata: + val->encoding = ATTR_VAL_UINT; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_ref_addr: + val->encoding = ATTR_VAL_REF_INFO; + if (version == 2) + val->u.uint = read_address (buf, addrsize); + else + val->u.uint = read_offset (buf, is_dwarf64); + return 1; + case DW_FORM_ref1: + val->encoding = ATTR_VAL_REF_UNIT; + val->u.uint = read_byte (buf); + return 1; + case DW_FORM_ref2: + val->encoding = ATTR_VAL_REF_UNIT; + val->u.uint = read_uint16 (buf); + return 1; + case DW_FORM_ref4: + val->encoding = ATTR_VAL_REF_UNIT; + val->u.uint = read_uint32 (buf); + return 1; + case DW_FORM_ref8: + val->encoding = ATTR_VAL_REF_UNIT; + val->u.uint = read_uint64 (buf); + return 1; + case DW_FORM_ref_udata: + val->encoding = ATTR_VAL_REF_UNIT; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_indirect: + { + uint64_t form; + + form = read_uleb128 (buf); + if (form == DW_FORM_implicit_const) + { + dwarf_buf_error (buf, + "DW_FORM_indirect to DW_FORM_implicit_const", + 0); + return 0; + } + return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64, + version, addrsize, dwarf_sections, altlink, + val); + } + case DW_FORM_sec_offset: + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_offset (buf, is_dwarf64); + return 1; + case DW_FORM_exprloc: + val->encoding = ATTR_VAL_EXPR; + return advance (buf, read_uleb128 (buf)); + case DW_FORM_flag_present: + val->encoding = ATTR_VAL_UINT; + val->u.uint = 1; + return 1; + case DW_FORM_ref_sig8: + val->encoding = ATTR_VAL_REF_TYPE; + val->u.uint = read_uint64 (buf); + return 1; + case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: + case DW_FORM_strx3: case DW_FORM_strx4: + { + uint64_t offset; + + switch (form) + { + case DW_FORM_strx: + offset = read_uleb128 (buf); + break; + case DW_FORM_strx1: + offset = read_byte (buf); + break; + case DW_FORM_strx2: + offset = read_uint16 (buf); + break; + case DW_FORM_strx3: + offset = read_uint24 (buf); + break; + case DW_FORM_strx4: + offset = read_uint32 (buf); + break; + default: + /* This case can't happen. */ + return 0; + } + val->encoding = ATTR_VAL_STRING_INDEX; + val->u.uint = offset; + return 1; + } + case DW_FORM_addrx: case DW_FORM_addrx1: case DW_FORM_addrx2: + case DW_FORM_addrx3: case DW_FORM_addrx4: + { + uint64_t offset; + + switch (form) + { + case DW_FORM_addrx: + offset = read_uleb128 (buf); + break; + case DW_FORM_addrx1: + offset = read_byte (buf); + break; + case DW_FORM_addrx2: + offset = read_uint16 (buf); + break; + case DW_FORM_addrx3: + offset = read_uint24 (buf); + break; + case DW_FORM_addrx4: + offset = read_uint32 (buf); + break; + default: + /* This case can't happen. */ + return 0; + } + val->encoding = ATTR_VAL_ADDRESS_INDEX; + val->u.uint = offset; + return 1; + } + case DW_FORM_ref_sup4: + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_uint32 (buf); + return 1; + case DW_FORM_ref_sup8: + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_uint64 (buf); + return 1; + case DW_FORM_implicit_const: + val->encoding = ATTR_VAL_UINT; + val->u.uint = implicit_val; + return 1; + case DW_FORM_loclistx: + /* We don't distinguish this from DW_FORM_sec_offset. It + * shouldn't matter since we don't care about loclists. */ + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_rnglistx: + val->encoding = ATTR_VAL_RNGLISTS_INDEX; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_GNU_addr_index: + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_GNU_str_index: + val->encoding = ATTR_VAL_REF_SECTION; + val->u.uint = read_uleb128 (buf); + return 1; + case DW_FORM_GNU_ref_alt: + val->u.uint = read_offset (buf, is_dwarf64); + if (altlink == NULL) + { + val->encoding = ATTR_VAL_NONE; + return 1; + } + val->encoding = ATTR_VAL_REF_ALT_INFO; + return 1; + case DW_FORM_strp_sup: case DW_FORM_GNU_strp_alt: + { + uint64_t offset; + + offset = read_offset (buf, is_dwarf64); + if (altlink == NULL) + { + val->encoding = ATTR_VAL_NONE; + return 1; + } + if (offset >= altlink->dwarf_sections.size[DEBUG_STR]) + { + dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0); + return 0; + } + val->encoding = ATTR_VAL_STRING; + val->u.string = + (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset; + return 1; + } + default: + dwarf_buf_error (buf, "unrecognized DWARF form", -1); + return 0; + } +} + +/* If we can determine the value of a string attribute, set *STRING to + point to the string. Return 1 on success, 0 on error. If we don't + know the value, we consider that a success, and we don't change + *STRING. An error is only reported for some sort of out of range + offset. */ + +static int +resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64, + int is_bigendian, uint64_t str_offsets_base, + const struct attr_val *val, + backtrace_error_callback error_callback, void *data, + const char **string) +{ + switch (val->encoding) + { + case ATTR_VAL_STRING: + *string = val->u.string; + return 1; + + case ATTR_VAL_STRING_INDEX: + { + uint64_t offset; + struct dwarf_buf offset_buf; + + offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base; + if (offset + (is_dwarf64 ? 8 : 4) + > dwarf_sections->size[DEBUG_STR_OFFSETS]) + { + error_callback (data, "DW_FORM_strx value out of range", 0); + return 0; + } + + offset_buf.name = ".debug_str_offsets"; + offset_buf.start = dwarf_sections->data[DEBUG_STR_OFFSETS]; + offset_buf.buf = dwarf_sections->data[DEBUG_STR_OFFSETS] + offset; + offset_buf.left = dwarf_sections->size[DEBUG_STR_OFFSETS] - offset; + offset_buf.is_bigendian = is_bigendian; + offset_buf.error_callback = error_callback; + offset_buf.data = data; + offset_buf.reported_underflow = 0; + + offset = read_offset (&offset_buf, is_dwarf64); + if (offset >= dwarf_sections->size[DEBUG_STR]) + { + dwarf_buf_error (&offset_buf, + "DW_FORM_strx offset out of range", + 0); + return 0; + } + *string = (const char *) dwarf_sections->data[DEBUG_STR] + offset; + return 1; + } + + default: + return 1; + } +} + +/* Set *ADDRESS to the real address for a ATTR_VAL_ADDRESS_INDEX. + Return 1 on success, 0 on error. */ + +static int +resolve_addr_index (const struct dwarf_sections *dwarf_sections, + uint64_t addr_base, int addrsize, int is_bigendian, + uint64_t addr_index, + backtrace_error_callback error_callback, void *data, + uintptr_t *address) +{ + uint64_t offset; + struct dwarf_buf addr_buf; + + offset = addr_index * addrsize + addr_base; + if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR]) + { + error_callback (data, "DW_FORM_addrx value out of range", 0); + return 0; + } + + addr_buf.name = ".debug_addr"; + addr_buf.start = dwarf_sections->data[DEBUG_ADDR]; + addr_buf.buf = dwarf_sections->data[DEBUG_ADDR] + offset; + addr_buf.left = dwarf_sections->size[DEBUG_ADDR] - offset; + addr_buf.is_bigendian = is_bigendian; + addr_buf.error_callback = error_callback; + addr_buf.data = data; + addr_buf.reported_underflow = 0; + + *address = (uintptr_t) read_address (&addr_buf, addrsize); + return 1; +} + +/* Compare a unit offset against a unit for bsearch. */ + +static int +units_search (const void *vkey, const void *ventry) +{ + const size_t *key = (const size_t *) vkey; + const struct unit *entry = *((const struct unit *const *) ventry); + size_t offset; + + offset = *key; + if (offset < entry->low_offset) + return -1; + else if (offset >= entry->high_offset) + return 1; + else + return 0; +} + +/* Find a unit in PU containing OFFSET. */ + +static struct unit * +find_unit (struct unit **pu, size_t units_count, size_t offset) +{ + struct unit **u; + u = (struct unit**)bsearch (&offset, pu, units_count, sizeof (struct unit *), units_search); + return u == NULL ? NULL : *u; +} + +/* Compare function_addrs for qsort. When ranges are nested, make the + smallest one sort last. */ + +static int +function_addrs_compare (const void *v1, const void *v2) +{ + const struct function_addrs *a1 = (const struct function_addrs *) v1; + const struct function_addrs *a2 = (const struct function_addrs *) v2; + + if (a1->low < a2->low) + return -1; + if (a1->low > a2->low) + return 1; + if (a1->high < a2->high) + return 1; + if (a1->high > a2->high) + return -1; + return strcmp (a1->function->name, a2->function->name); +} + +/* Compare a PC against a function_addrs for bsearch. We always + allocate an entra entry at the end of the vector, so that this + routine can safely look at the next entry. Note that if there are + multiple ranges containing PC, which one will be returned is + unpredictable. We compensate for that in dwarf_fileline. */ + +static int +function_addrs_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct function_addrs *entry = (const struct function_addrs *) ventry; + uintptr_t pc; + + pc = *key; + if (pc < entry->low) + return -1; + else if (pc > (entry + 1)->low) + return 1; + else + return 0; +} + +/* Add a new compilation unit address range to a vector. This is + called via add_ranges. Returns 1 on success, 0 on failure. */ + +static int +add_unit_addr (struct backtrace_state *state, void *rdata, + uintptr_t lowpc, uintptr_t highpc, + backtrace_error_callback error_callback, void *data, + void *pvec) +{ + struct unit *u = (struct unit *) rdata; + struct unit_addrs_vector *vec = (struct unit_addrs_vector *) pvec; + struct unit_addrs *p; + + /* Try to merge with the last entry. */ + if (vec->count > 0) + { + p = (struct unit_addrs *) vec->vec.base + (vec->count - 1); + if ((lowpc == p->high || lowpc == p->high + 1) + && u == p->u) + { + if (highpc > p->high) + p->high = highpc; + return 1; + } + } + + p = ((struct unit_addrs *) + backtrace_vector_grow (state, sizeof (struct unit_addrs), + error_callback, data, &vec->vec)); + if (p == NULL) + return 0; + + p->low = lowpc; + p->high = highpc; + p->u = u; + + ++vec->count; + + return 1; +} + +/* Compare unit_addrs for qsort. When ranges are nested, make the + smallest one sort last. */ + +static int +unit_addrs_compare (const void *v1, const void *v2) +{ + const struct unit_addrs *a1 = (const struct unit_addrs *) v1; + const struct unit_addrs *a2 = (const struct unit_addrs *) v2; + + if (a1->low < a2->low) + return -1; + if (a1->low > a2->low) + return 1; + if (a1->high < a2->high) + return 1; + if (a1->high > a2->high) + return -1; + if (a1->u->lineoff < a2->u->lineoff) + return -1; + if (a1->u->lineoff > a2->u->lineoff) + return 1; + return 0; +} + +/* Compare a PC against a unit_addrs for bsearch. We always allocate + an entry entry at the end of the vector, so that this routine can + safely look at the next entry. Note that if there are multiple + ranges containing PC, which one will be returned is unpredictable. + We compensate for that in dwarf_fileline. */ + +static int +unit_addrs_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct unit_addrs *entry = (const struct unit_addrs *) ventry; + uintptr_t pc; + + pc = *key; + if (pc < entry->low) + return -1; + else if (pc > (entry + 1)->low) + return 1; + else + return 0; +} + +/* Sort the line vector by PC. We want a stable sort here to maintain + the order of lines for the same PC values. Since the sequence is + being sorted in place, their addresses cannot be relied on to + maintain stability. That is the purpose of the index member. */ + +static int +line_compare (const void *v1, const void *v2) +{ + const struct line *ln1 = (const struct line *) v1; + const struct line *ln2 = (const struct line *) v2; + + if (ln1->pc < ln2->pc) + return -1; + else if (ln1->pc > ln2->pc) + return 1; + else if (ln1->idx < ln2->idx) + return -1; + else if (ln1->idx > ln2->idx) + return 1; + else + return 0; +} + +/* Find a PC in a line vector. We always allocate an extra entry at + the end of the lines vector, so that this routine can safely look + at the next entry. Note that when there are multiple mappings for + the same PC value, this will return the last one. */ + +static int +line_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct line *entry = (const struct line *) ventry; + uintptr_t pc; + + pc = *key; + if (pc < entry->pc) + return -1; + else if (pc >= (entry + 1)->pc) + return 1; + else + return 0; +} + +/* Sort the abbrevs by the abbrev code. This function is passed to + both qsort and bsearch. */ + +static int +abbrev_compare (const void *v1, const void *v2) +{ + const struct abbrev *a1 = (const struct abbrev *) v1; + const struct abbrev *a2 = (const struct abbrev *) v2; + + if (a1->code < a2->code) + return -1; + else if (a1->code > a2->code) + return 1; + else + { + /* This really shouldn't happen. It means there are two + different abbrevs with the same code, and that means we don't + know which one lookup_abbrev should return. */ + return 0; + } +} + +/* Read the abbreviation table for a compilation unit. Returns 1 on + success, 0 on failure. */ + +static int +read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset, + const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size, + int is_bigendian, backtrace_error_callback error_callback, + void *data, struct abbrevs *abbrevs) +{ + struct dwarf_buf abbrev_buf; + struct dwarf_buf count_buf; + size_t num_abbrevs; + + abbrevs->num_abbrevs = 0; + abbrevs->abbrevs = NULL; + + if (abbrev_offset >= dwarf_abbrev_size) + { + error_callback (data, "abbrev offset out of range", 0); + return 0; + } + + abbrev_buf.name = ".debug_abbrev"; + abbrev_buf.start = dwarf_abbrev; + abbrev_buf.buf = dwarf_abbrev + abbrev_offset; + abbrev_buf.left = dwarf_abbrev_size - abbrev_offset; + abbrev_buf.is_bigendian = is_bigendian; + abbrev_buf.error_callback = error_callback; + abbrev_buf.data = data; + abbrev_buf.reported_underflow = 0; + + /* Count the number of abbrevs in this list. */ + + count_buf = abbrev_buf; + num_abbrevs = 0; + while (read_uleb128 (&count_buf) != 0) + { + if (count_buf.reported_underflow) + return 0; + ++num_abbrevs; + // Skip tag. + read_uleb128 (&count_buf); + // Skip has_children. + read_byte (&count_buf); + // Skip attributes. + while (read_uleb128 (&count_buf) != 0) + { + uint64_t form; + + form = read_uleb128 (&count_buf); + if ((enum dwarf_form) form == DW_FORM_implicit_const) + read_sleb128 (&count_buf); + } + // Skip form of last attribute. + read_uleb128 (&count_buf); + } + + if (count_buf.reported_underflow) + return 0; + + if (num_abbrevs == 0) + return 1; + + abbrevs->abbrevs = ((struct abbrev *) + backtrace_alloc (state, + num_abbrevs * sizeof (struct abbrev), + error_callback, data)); + if (abbrevs->abbrevs == NULL) + return 0; + abbrevs->num_abbrevs = num_abbrevs; + memset (abbrevs->abbrevs, 0, num_abbrevs * sizeof (struct abbrev)); + + num_abbrevs = 0; + while (1) + { + uint64_t code; + struct abbrev a; + size_t num_attrs; + struct attr *attrs; + + if (abbrev_buf.reported_underflow) + goto fail; + + code = read_uleb128 (&abbrev_buf); + if (code == 0) + break; + + a.code = code; + a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf); + a.has_children = read_byte (&abbrev_buf); + + count_buf = abbrev_buf; + num_attrs = 0; + while (read_uleb128 (&count_buf) != 0) + { + uint64_t form; + + ++num_attrs; + form = read_uleb128 (&count_buf); + if ((enum dwarf_form) form == DW_FORM_implicit_const) + read_sleb128 (&count_buf); + } + + if (num_attrs == 0) + { + attrs = NULL; + read_uleb128 (&abbrev_buf); + read_uleb128 (&abbrev_buf); + } + else + { + attrs = ((struct attr *) + backtrace_alloc (state, num_attrs * sizeof *attrs, + error_callback, data)); + if (attrs == NULL) + goto fail; + num_attrs = 0; + while (1) + { + uint64_t name; + uint64_t form; + + name = read_uleb128 (&abbrev_buf); + form = read_uleb128 (&abbrev_buf); + if (name == 0) + break; + attrs[num_attrs].name = (enum dwarf_attribute) name; + attrs[num_attrs].form = (enum dwarf_form) form; + if ((enum dwarf_form) form == DW_FORM_implicit_const) + attrs[num_attrs].val = read_sleb128 (&abbrev_buf); + else + attrs[num_attrs].val = 0; + ++num_attrs; + } + } + + a.num_attrs = num_attrs; + a.attrs = attrs; + + abbrevs->abbrevs[num_abbrevs] = a; + ++num_abbrevs; + } + + backtrace_qsort (abbrevs->abbrevs, abbrevs->num_abbrevs, + sizeof (struct abbrev), abbrev_compare); + + return 1; + + fail: + free_abbrevs (state, abbrevs, error_callback, data); + return 0; +} + +/* Return the abbrev information for an abbrev code. */ + +static const struct abbrev * +lookup_abbrev (struct abbrevs *abbrevs, uint64_t code, + backtrace_error_callback error_callback, void *data) +{ + struct abbrev key; + void *p; + + /* With GCC, where abbrevs are simply numbered in order, we should + be able to just look up the entry. */ + if (code - 1 < abbrevs->num_abbrevs + && abbrevs->abbrevs[code - 1].code == code) + return &abbrevs->abbrevs[code - 1]; + + /* Otherwise we have to search. */ + memset (&key, 0, sizeof key); + key.code = code; + p = bsearch (&key, abbrevs->abbrevs, abbrevs->num_abbrevs, + sizeof (struct abbrev), abbrev_compare); + if (p == NULL) + { + error_callback (data, "invalid abbreviation code", 0); + return NULL; + } + return (const struct abbrev *) p; +} + +/* This struct is used to gather address range information while + reading attributes. We use this while building a mapping from + address ranges to compilation units and then again while mapping + from address ranges to function entries. Normally either + lowpc/highpc is set or ranges is set. */ + +struct pcrange { + uintptr_t lowpc; /* The low PC value. */ + int have_lowpc; /* Whether a low PC value was found. */ + int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */ + uintptr_t highpc; /* The high PC value. */ + int have_highpc; /* Whether a high PC value was found. */ + int highpc_is_relative; /* Whether highpc is relative to lowpc. */ + int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */ + uint64_t ranges; /* Offset in ranges section. */ + int have_ranges; /* Whether ranges is valid. */ + int ranges_is_index; /* Whether ranges is DW_FORM_rnglistx. */ +}; + +/* Update PCRANGE from an attribute value. */ + +static void +update_pcrange (const struct attr* attr, const struct attr_val* val, + struct pcrange *pcrange) +{ + switch (attr->name) + { + case DW_AT_low_pc: + if (val->encoding == ATTR_VAL_ADDRESS) + { + pcrange->lowpc = (uintptr_t) val->u.uint; + pcrange->have_lowpc = 1; + } + else if (val->encoding == ATTR_VAL_ADDRESS_INDEX) + { + pcrange->lowpc = (uintptr_t) val->u.uint; + pcrange->have_lowpc = 1; + pcrange->lowpc_is_addr_index = 1; + } + break; + + case DW_AT_high_pc: + if (val->encoding == ATTR_VAL_ADDRESS) + { + pcrange->highpc = (uintptr_t) val->u.uint; + pcrange->have_highpc = 1; + } + else if (val->encoding == ATTR_VAL_UINT) + { + pcrange->highpc = (uintptr_t) val->u.uint; + pcrange->have_highpc = 1; + pcrange->highpc_is_relative = 1; + } + else if (val->encoding == ATTR_VAL_ADDRESS_INDEX) + { + pcrange->highpc = (uintptr_t) val->u.uint; + pcrange->have_highpc = 1; + pcrange->highpc_is_addr_index = 1; + } + break; + + case DW_AT_ranges: + if (val->encoding == ATTR_VAL_UINT + || val->encoding == ATTR_VAL_REF_SECTION) + { + pcrange->ranges = val->u.uint; + pcrange->have_ranges = 1; + } + else if (val->encoding == ATTR_VAL_RNGLISTS_INDEX) + { + pcrange->ranges = val->u.uint; + pcrange->have_ranges = 1; + pcrange->ranges_is_index = 1; + } + break; + + default: + break; + } +} + +/* Call ADD_RANGE for a low/high PC pair. Returns 1 on success, 0 on + error. */ + +static int +add_low_high_range (struct backtrace_state *state, + const struct dwarf_sections *dwarf_sections, + uintptr_t base_address, int is_bigendian, + struct unit *u, const struct pcrange *pcrange, + int (*add_range) (struct backtrace_state *state, + void *rdata, uintptr_t lowpc, + uintptr_t highpc, + backtrace_error_callback error_callback, + void *data, void *vec), + void *rdata, + backtrace_error_callback error_callback, void *data, + void *vec) +{ + uintptr_t lowpc; + uintptr_t highpc; + + lowpc = pcrange->lowpc; + if (pcrange->lowpc_is_addr_index) + { + if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize, + is_bigendian, lowpc, error_callback, data, + &lowpc)) + return 0; + } + + highpc = pcrange->highpc; + if (pcrange->highpc_is_addr_index) + { + if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize, + is_bigendian, highpc, error_callback, data, + &highpc)) + return 0; + } + if (pcrange->highpc_is_relative) + highpc += lowpc; + + /* Add in the base address of the module when recording PC values, + so that we can look up the PC directly. */ + lowpc += base_address; + highpc += base_address; + + return add_range (state, rdata, lowpc, highpc, error_callback, data, vec); +} + +/* Call ADD_RANGE for each range read from .debug_ranges, as used in + DWARF versions 2 through 4. */ + +static int +add_ranges_from_ranges ( + struct backtrace_state *state, + const struct dwarf_sections *dwarf_sections, + uintptr_t base_address, int is_bigendian, + struct unit *u, uintptr_t base, + const struct pcrange *pcrange, + int (*add_range) (struct backtrace_state *state, void *rdata, + uintptr_t lowpc, uintptr_t highpc, + backtrace_error_callback error_callback, void *data, + void *vec), + void *rdata, + backtrace_error_callback error_callback, void *data, + void *vec) +{ + struct dwarf_buf ranges_buf; + + if (pcrange->ranges >= dwarf_sections->size[DEBUG_RANGES]) + { + error_callback (data, "ranges offset out of range", 0); + return 0; + } + + ranges_buf.name = ".debug_ranges"; + ranges_buf.start = dwarf_sections->data[DEBUG_RANGES]; + ranges_buf.buf = dwarf_sections->data[DEBUG_RANGES] + pcrange->ranges; + ranges_buf.left = dwarf_sections->size[DEBUG_RANGES] - pcrange->ranges; + ranges_buf.is_bigendian = is_bigendian; + ranges_buf.error_callback = error_callback; + ranges_buf.data = data; + ranges_buf.reported_underflow = 0; + + while (1) + { + uint64_t low; + uint64_t high; + + if (ranges_buf.reported_underflow) + return 0; + + low = read_address (&ranges_buf, u->addrsize); + high = read_address (&ranges_buf, u->addrsize); + + if (low == 0 && high == 0) + break; + + if (is_highest_address (low, u->addrsize)) + base = (uintptr_t) high; + else + { + if (!add_range (state, rdata, + (uintptr_t) low + base + base_address, + (uintptr_t) high + base + base_address, + error_callback, data, vec)) + return 0; + } + } + + if (ranges_buf.reported_underflow) + return 0; + + return 1; +} + +/* Call ADD_RANGE for each range read from .debug_rnglists, as used in + DWARF version 5. */ + +static int +add_ranges_from_rnglists ( + struct backtrace_state *state, + const struct dwarf_sections *dwarf_sections, + uintptr_t base_address, int is_bigendian, + struct unit *u, uintptr_t base, + const struct pcrange *pcrange, + int (*add_range) (struct backtrace_state *state, void *rdata, + uintptr_t lowpc, uintptr_t highpc, + backtrace_error_callback error_callback, void *data, + void *vec), + void *rdata, + backtrace_error_callback error_callback, void *data, + void *vec) +{ + uint64_t offset; + struct dwarf_buf rnglists_buf; + + if (!pcrange->ranges_is_index) + offset = pcrange->ranges; + else + offset = u->rnglists_base + pcrange->ranges * (u->is_dwarf64 ? 8 : 4); + if (offset >= dwarf_sections->size[DEBUG_RNGLISTS]) + { + error_callback (data, "rnglists offset out of range", 0); + return 0; + } + + rnglists_buf.name = ".debug_rnglists"; + rnglists_buf.start = dwarf_sections->data[DEBUG_RNGLISTS]; + rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset; + rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset; + rnglists_buf.is_bigendian = is_bigendian; + rnglists_buf.error_callback = error_callback; + rnglists_buf.data = data; + rnglists_buf.reported_underflow = 0; + + if (pcrange->ranges_is_index) + { + offset = read_offset (&rnglists_buf, u->is_dwarf64); + offset += u->rnglists_base; + if (offset >= dwarf_sections->size[DEBUG_RNGLISTS]) + { + error_callback (data, "rnglists index offset out of range", 0); + return 0; + } + rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset; + rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset; + } + + while (1) + { + unsigned char rle; + + rle = read_byte (&rnglists_buf); + if (rle == DW_RLE_end_of_list) + break; + switch (rle) + { + case DW_RLE_base_addressx: + { + uint64_t index; + + index = read_uleb128 (&rnglists_buf); + if (!resolve_addr_index (dwarf_sections, u->addr_base, + u->addrsize, is_bigendian, index, + error_callback, data, &base)) + return 0; + } + break; + + case DW_RLE_startx_endx: + { + uint64_t index; + uintptr_t low; + uintptr_t high; + + index = read_uleb128 (&rnglists_buf); + if (!resolve_addr_index (dwarf_sections, u->addr_base, + u->addrsize, is_bigendian, index, + error_callback, data, &low)) + return 0; + index = read_uleb128 (&rnglists_buf); + if (!resolve_addr_index (dwarf_sections, u->addr_base, + u->addrsize, is_bigendian, index, + error_callback, data, &high)) + return 0; + if (!add_range (state, rdata, low + base_address, + high + base_address, error_callback, data, + vec)) + return 0; + } + break; + + case DW_RLE_startx_length: + { + uint64_t index; + uintptr_t low; + uintptr_t length; + + index = read_uleb128 (&rnglists_buf); + if (!resolve_addr_index (dwarf_sections, u->addr_base, + u->addrsize, is_bigendian, index, + error_callback, data, &low)) + return 0; + length = read_uleb128 (&rnglists_buf); + low += base_address; + if (!add_range (state, rdata, low, low + length, + error_callback, data, vec)) + return 0; + } + break; + + case DW_RLE_offset_pair: + { + uint64_t low; + uint64_t high; + + low = read_uleb128 (&rnglists_buf); + high = read_uleb128 (&rnglists_buf); + if (!add_range (state, rdata, low + base + base_address, + high + base + base_address, + error_callback, data, vec)) + return 0; + } + break; + + case DW_RLE_base_address: + base = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + break; + + case DW_RLE_start_end: + { + uintptr_t low; + uintptr_t high; + + low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + high = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + if (!add_range (state, rdata, low + base_address, + high + base_address, error_callback, data, + vec)) + return 0; + } + break; + + case DW_RLE_start_length: + { + uintptr_t low; + uintptr_t length; + + low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + length = (uintptr_t) read_uleb128 (&rnglists_buf); + low += base_address; + if (!add_range (state, rdata, low, low + length, + error_callback, data, vec)) + return 0; + } + break; + + default: + dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1); + return 0; + } + } + + if (rnglists_buf.reported_underflow) + return 0; + + return 1; +} + +/* Call ADD_RANGE for each lowpc/highpc pair in PCRANGE. RDATA is + passed to ADD_RANGE, and is either a struct unit * or a struct + function *. VEC is the vector we are adding ranges to, and is + either a struct unit_addrs_vector * or a struct function_vector *. + Returns 1 on success, 0 on error. */ + +static int +add_ranges (struct backtrace_state *state, + const struct dwarf_sections *dwarf_sections, + uintptr_t base_address, int is_bigendian, + struct unit *u, uintptr_t base, const struct pcrange *pcrange, + int (*add_range) (struct backtrace_state *state, void *rdata, + uintptr_t lowpc, uintptr_t highpc, + backtrace_error_callback error_callback, + void *data, void *vec), + void *rdata, + backtrace_error_callback error_callback, void *data, + void *vec) +{ + if (pcrange->have_lowpc && pcrange->have_highpc) + return add_low_high_range (state, dwarf_sections, base_address, + is_bigendian, u, pcrange, add_range, rdata, + error_callback, data, vec); + + if (!pcrange->have_ranges) + { + /* Did not find any address ranges to add. */ + return 1; + } + + if (u->version < 5) + return add_ranges_from_ranges (state, dwarf_sections, base_address, + is_bigendian, u, base, pcrange, add_range, + rdata, error_callback, data, vec); + else + return add_ranges_from_rnglists (state, dwarf_sections, base_address, + is_bigendian, u, base, pcrange, add_range, + rdata, error_callback, data, vec); +} + +/* Find the address range covered by a compilation unit, reading from + UNIT_BUF and adding values to U. Returns 1 if all data could be + read, 0 if there is some error. */ + +static int +find_address_ranges (struct backtrace_state *state, uintptr_t base_address, + struct dwarf_buf *unit_buf, + const struct dwarf_sections *dwarf_sections, + int is_bigendian, struct dwarf_data *altlink, + backtrace_error_callback error_callback, void *data, + struct unit *u, struct unit_addrs_vector *addrs, + enum dwarf_tag *unit_tag) +{ + while (unit_buf->left > 0) + { + uint64_t code; + const struct abbrev *abbrev; + struct pcrange pcrange; + struct attr_val name_val; + int have_name_val; + struct attr_val comp_dir_val; + int have_comp_dir_val; + size_t i; + + code = read_uleb128 (unit_buf); + if (code == 0) + return 1; + + abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data); + if (abbrev == NULL) + return 0; + + if (unit_tag != NULL) + *unit_tag = abbrev->tag; + + memset (&pcrange, 0, sizeof pcrange); + memset (&name_val, 0, sizeof name_val); + have_name_val = 0; + memset (&comp_dir_val, 0, sizeof comp_dir_val); + have_comp_dir_val = 0; + for (i = 0; i < abbrev->num_attrs; ++i) + { + struct attr_val val; + + if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val, + unit_buf, u->is_dwarf64, u->version, + u->addrsize, dwarf_sections, altlink, &val)) + return 0; + + switch (abbrev->attrs[i].name) + { + case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges: + update_pcrange (&abbrev->attrs[i], &val, &pcrange); + break; + + case DW_AT_stmt_list: + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && (val.encoding == ATTR_VAL_UINT + || val.encoding == ATTR_VAL_REF_SECTION)) + u->lineoff = val.u.uint; + break; + + case DW_AT_name: + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + { + name_val = val; + have_name_val = 1; + } + break; + + case DW_AT_comp_dir: + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + { + comp_dir_val = val; + have_comp_dir_val = 1; + } + break; + + case DW_AT_str_offsets_base: + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && val.encoding == ATTR_VAL_REF_SECTION) + u->str_offsets_base = val.u.uint; + break; + + case DW_AT_addr_base: + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && val.encoding == ATTR_VAL_REF_SECTION) + u->addr_base = val.u.uint; + break; + + case DW_AT_rnglists_base: + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && val.encoding == ATTR_VAL_REF_SECTION) + u->rnglists_base = val.u.uint; + break; + + default: + break; + } + } + + // Resolve strings after we're sure that we have seen + // DW_AT_str_offsets_base. + if (have_name_val) + { + if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian, + u->str_offsets_base, &name_val, + error_callback, data, &u->filename)) + return 0; + } + if (have_comp_dir_val) + { + if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian, + u->str_offsets_base, &comp_dir_val, + error_callback, data, &u->comp_dir)) + return 0; + } + + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_subprogram + || abbrev->tag == DW_TAG_skeleton_unit) + { + if (!add_ranges (state, dwarf_sections, base_address, + is_bigendian, u, pcrange.lowpc, &pcrange, + add_unit_addr, (void *) u, error_callback, data, + (void *) addrs)) + return 0; + + /* If we found the PC range in the DW_TAG_compile_unit or + DW_TAG_skeleton_unit, we can stop now. */ + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && (pcrange.have_ranges + || (pcrange.have_lowpc && pcrange.have_highpc))) + return 1; + } + + if (abbrev->has_children) + { + if (!find_address_ranges (state, base_address, unit_buf, + dwarf_sections, is_bigendian, altlink, + error_callback, data, u, addrs, NULL)) + return 0; + } + } + + return 1; +} + +/* Build a mapping from address ranges to the compilation units where + the line number information for that range can be found. Returns 1 + on success, 0 on failure. */ + +static int +build_address_map (struct backtrace_state *state, uintptr_t base_address, + const struct dwarf_sections *dwarf_sections, + int is_bigendian, struct dwarf_data *altlink, + backtrace_error_callback error_callback, void *data, + struct unit_addrs_vector *addrs, + struct unit_vector *unit_vec) +{ + struct dwarf_buf info; + struct backtrace_vector units; + size_t units_count; + size_t i; + struct unit **pu; + size_t unit_offset = 0; + struct unit_addrs *pa; + + memset (&addrs->vec, 0, sizeof addrs->vec); + memset (&unit_vec->vec, 0, sizeof unit_vec->vec); + addrs->count = 0; + unit_vec->count = 0; + + /* Read through the .debug_info section. FIXME: Should we use the + .debug_aranges section? gdb and addr2line don't use it, but I'm + not sure why. */ + + info.name = ".debug_info"; + info.start = dwarf_sections->data[DEBUG_INFO]; + info.buf = info.start; + info.left = dwarf_sections->size[DEBUG_INFO]; + info.is_bigendian = is_bigendian; + info.error_callback = error_callback; + info.data = data; + info.reported_underflow = 0; + + memset (&units, 0, sizeof units); + units_count = 0; + + while (info.left > 0) + { + const unsigned char *unit_data_start; + uint64_t len; + int is_dwarf64; + struct dwarf_buf unit_buf; + int version; + int unit_type; + uint64_t abbrev_offset; + int addrsize; + struct unit *u; + enum dwarf_tag unit_tag; + + if (info.reported_underflow) + goto fail; + + unit_data_start = info.buf; + + len = read_initial_length (&info, &is_dwarf64); + unit_buf = info; + unit_buf.left = len; + + if (!advance (&info, len)) + goto fail; + + version = read_uint16 (&unit_buf); + if (version < 2 || version > 5) + { + dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1); + goto fail; + } + + if (version < 5) + unit_type = 0; + else + { + unit_type = read_byte (&unit_buf); + if (unit_type == DW_UT_type || unit_type == DW_UT_split_type) + { + /* This unit doesn't have anything we need. */ + continue; + } + } + + pu = ((struct unit **) + backtrace_vector_grow (state, sizeof (struct unit *), + error_callback, data, &units)); + if (pu == NULL) + goto fail; + + u = ((struct unit *) + backtrace_alloc (state, sizeof *u, error_callback, data)); + if (u == NULL) + goto fail; + + *pu = u; + ++units_count; + + if (version < 5) + addrsize = 0; /* Set below. */ + else + addrsize = read_byte (&unit_buf); + + memset (&u->abbrevs, 0, sizeof u->abbrevs); + abbrev_offset = read_offset (&unit_buf, is_dwarf64); + if (!read_abbrevs (state, abbrev_offset, + dwarf_sections->data[DEBUG_ABBREV], + dwarf_sections->size[DEBUG_ABBREV], + is_bigendian, error_callback, data, &u->abbrevs)) + goto fail; + + if (version < 5) + addrsize = read_byte (&unit_buf); + + switch (unit_type) + { + case 0: + break; + case DW_UT_compile: case DW_UT_partial: + break; + case DW_UT_skeleton: case DW_UT_split_compile: + read_uint64 (&unit_buf); /* dwo_id */ + break; + default: + break; + } + + u->low_offset = unit_offset; + unit_offset += len + (is_dwarf64 ? 12 : 4); + u->high_offset = unit_offset; + u->unit_data = unit_buf.buf; + u->unit_data_len = unit_buf.left; + u->unit_data_offset = unit_buf.buf - unit_data_start; + u->version = version; + u->is_dwarf64 = is_dwarf64; + u->addrsize = addrsize; + u->filename = NULL; + u->comp_dir = NULL; + u->abs_filename = NULL; + u->lineoff = 0; + u->str_offsets_base = 0; + u->addr_base = 0; + u->rnglists_base = 0; + + /* The actual line number mappings will be read as needed. */ + u->lines = NULL; + u->lines_count = 0; + u->function_addrs = NULL; + u->function_addrs_count = 0; + + if (!find_address_ranges (state, base_address, &unit_buf, dwarf_sections, + is_bigendian, altlink, error_callback, data, + u, addrs, &unit_tag)) + goto fail; + + if (unit_buf.reported_underflow) + goto fail; + } + if (info.reported_underflow) + goto fail; + + /* Add a trailing addrs entry, but don't include it in addrs->count. */ + pa = ((struct unit_addrs *) + backtrace_vector_grow (state, sizeof (struct unit_addrs), + error_callback, data, &addrs->vec)); + if (pa == NULL) + goto fail; + pa->low = 0; + --pa->low; + pa->high = pa->low; + pa->u = NULL; + + unit_vec->vec = units; + unit_vec->count = units_count; + return 1; + + fail: + if (units_count > 0) + { + pu = (struct unit **) units.base; + for (i = 0; i < units_count; i++) + { + free_abbrevs (state, &pu[i]->abbrevs, error_callback, data); + backtrace_free (state, pu[i], sizeof **pu, error_callback, data); + } + backtrace_vector_free (state, &units, error_callback, data); + } + if (addrs->count > 0) + { + backtrace_vector_free (state, &addrs->vec, error_callback, data); + addrs->count = 0; + } + return 0; +} + +/* Add a new mapping to the vector of line mappings that we are + building. Returns 1 on success, 0 on failure. */ + +static int +add_line (struct backtrace_state *state, struct dwarf_data *ddata, + uintptr_t pc, const char *filename, int lineno, + backtrace_error_callback error_callback, void *data, + struct line_vector *vec) +{ + struct line *ln; + + /* If we are adding the same mapping, ignore it. This can happen + when using discriminators. */ + if (vec->count > 0) + { + ln = (struct line *) vec->vec.base + (vec->count - 1); + if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno) + return 1; + } + + ln = ((struct line *) + backtrace_vector_grow (state, sizeof (struct line), error_callback, + data, &vec->vec)); + if (ln == NULL) + return 0; + + /* Add in the base address here, so that we can look up the PC + directly. */ + ln->pc = pc + ddata->base_address; + + ln->filename = filename; + ln->lineno = lineno; + ln->idx = vec->count; + + ++vec->count; + + return 1; +} + +/* Free the line header information. */ + +static void +free_line_header (struct backtrace_state *state, struct line_header *hdr, + backtrace_error_callback error_callback, void *data) +{ + if (hdr->dirs_count != 0) + backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *), + error_callback, data); + backtrace_free (state, hdr->filenames, + hdr->filenames_count * sizeof (char *), + error_callback, data); +} + +/* Read the directories and file names for a line header for version + 2, setting fields in HDR. Return 1 on success, 0 on failure. */ + +static int +read_v2_paths (struct backtrace_state *state, struct unit *u, + struct dwarf_buf *hdr_buf, struct line_header *hdr) +{ + const unsigned char *p; + const unsigned char *pend; + size_t i; + + /* Count the number of directory entries. */ + hdr->dirs_count = 0; + p = hdr_buf->buf; + pend = p + hdr_buf->left; + while (p < pend && *p != '\0') + { + p += strnlen((const char *) p, pend - p) + 1; + ++hdr->dirs_count; + } + + /* The index of the first entry in the list of directories is 1. Index 0 is + used for the current directory of the compilation. To simplify index + handling, we set entry 0 to the compilation unit directory. */ + ++hdr->dirs_count; + hdr->dirs = ((const char **) + backtrace_alloc (state, + hdr->dirs_count * sizeof (const char *), + hdr_buf->error_callback, + hdr_buf->data)); + if (hdr->dirs == NULL) + return 0; + + hdr->dirs[0] = u->comp_dir; + i = 1; + while (*hdr_buf->buf != '\0') + { + if (hdr_buf->reported_underflow) + return 0; + + hdr->dirs[i] = read_string (hdr_buf); + if (hdr->dirs[i] == NULL) + return 0; + ++i; + } + if (!advance (hdr_buf, 1)) + return 0; + + /* Count the number of file entries. */ + hdr->filenames_count = 0; + p = hdr_buf->buf; + pend = p + hdr_buf->left; + while (p < pend && *p != '\0') + { + p += strnlen ((const char *) p, pend - p) + 1; + p += leb128_len (p); + p += leb128_len (p); + p += leb128_len (p); + ++hdr->filenames_count; + } + + /* The index of the first entry in the list of file names is 1. Index 0 is + used for the DW_AT_name of the compilation unit. To simplify index + handling, we set entry 0 to the compilation unit file name. */ + ++hdr->filenames_count; + hdr->filenames = ((const char **) + backtrace_alloc (state, + hdr->filenames_count * sizeof (char *), + hdr_buf->error_callback, + hdr_buf->data)); + if (hdr->filenames == NULL) + return 0; + hdr->filenames[0] = u->filename; + i = 1; + while (*hdr_buf->buf != '\0') + { + const char *filename; + uint64_t dir_index; + + if (hdr_buf->reported_underflow) + return 0; + + filename = read_string (hdr_buf); + if (filename == NULL) + return 0; + dir_index = read_uleb128 (hdr_buf); + if (IS_ABSOLUTE_PATH (filename) + || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL)) + hdr->filenames[i] = filename; + else + { + const char *dir; + size_t dir_len; + size_t filename_len; + char *s; + + if (dir_index < hdr->dirs_count) + dir = hdr->dirs[dir_index]; + else + { + dwarf_buf_error (hdr_buf, + ("invalid directory index in " + "line number program header"), + 0); + return 0; + } + dir_len = strlen (dir); + filename_len = strlen (filename); + s = ((char *) backtrace_alloc (state, dir_len + filename_len + 2, + hdr_buf->error_callback, + hdr_buf->data)); + if (s == NULL) + return 0; + memcpy (s, dir, dir_len); + /* FIXME: If we are on a DOS-based file system, and the + directory or the file name use backslashes, then we + should use a backslash here. */ + s[dir_len] = '/'; + memcpy (s + dir_len + 1, filename, filename_len + 1); + hdr->filenames[i] = s; + } + + /* Ignore the modification time and size. */ + read_uleb128 (hdr_buf); + read_uleb128 (hdr_buf); + + ++i; + } + + return 1; +} + +/* Read a single version 5 LNCT entry for a directory or file name in a + line header. Sets *STRING to the resulting name, ignoring other + data. Return 1 on success, 0 on failure. */ + +static int +read_lnct (struct backtrace_state *state, struct dwarf_data *ddata, + struct unit *u, struct dwarf_buf *hdr_buf, + const struct line_header *hdr, size_t formats_count, + const struct line_header_format *formats, const char **string) +{ + size_t i; + const char *dir; + const char *path; + + dir = NULL; + path = NULL; + for (i = 0; i < formats_count; i++) + { + struct attr_val val; + + if (!read_attribute (formats[i].form, 0, hdr_buf, u->is_dwarf64, + u->version, hdr->addrsize, &ddata->dwarf_sections, + ddata->altlink, &val)) + return 0; + switch (formats[i].lnct) + { + case DW_LNCT_path: + if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64, + ddata->is_bigendian, u->str_offsets_base, + &val, hdr_buf->error_callback, hdr_buf->data, + &path)) + return 0; + break; + case DW_LNCT_directory_index: + if (val.encoding == ATTR_VAL_UINT) + { + if (val.u.uint >= hdr->dirs_count) + { + dwarf_buf_error (hdr_buf, + ("invalid directory index in " + "line number program header"), + 0); + return 0; + } + dir = hdr->dirs[val.u.uint]; + } + break; + default: + /* We don't care about timestamps or sizes or hashes. */ + break; + } + } + + if (path == NULL) + { + dwarf_buf_error (hdr_buf, + "missing file name in line number program header", + 0); + return 0; + } + + if (dir == NULL) + *string = path; + else + { + size_t dir_len; + size_t path_len; + char *s; + + dir_len = strlen (dir); + path_len = strlen (path); + s = (char *) backtrace_alloc (state, dir_len + path_len + 2, + hdr_buf->error_callback, hdr_buf->data); + if (s == NULL) + return 0; + memcpy (s, dir, dir_len); + /* FIXME: If we are on a DOS-based file system, and the + directory or the path name use backslashes, then we should + use a backslash here. */ + s[dir_len] = '/'; + memcpy (s + dir_len + 1, path, path_len + 1); + *string = s; + } + + return 1; +} + +/* Read a set of DWARF 5 line header format entries, setting *PCOUNT + and *PPATHS. Return 1 on success, 0 on failure. */ + +static int +read_line_header_format_entries (struct backtrace_state *state, + struct dwarf_data *ddata, + struct unit *u, + struct dwarf_buf *hdr_buf, + struct line_header *hdr, + size_t *pcount, + const char ***ppaths) +{ + size_t formats_count; + struct line_header_format *formats; + size_t paths_count; + const char **paths; + size_t i; + int ret; + + formats_count = read_byte (hdr_buf); + if (formats_count == 0) + formats = NULL; + else + { + formats = ((struct line_header_format *) + backtrace_alloc (state, + (formats_count + * sizeof (struct line_header_format)), + hdr_buf->error_callback, + hdr_buf->data)); + if (formats == NULL) + return 0; + + for (i = 0; i < formats_count; i++) + { + formats[i].lnct = (int) read_uleb128(hdr_buf); + formats[i].form = (enum dwarf_form) read_uleb128 (hdr_buf); + } + } + + paths_count = read_uleb128 (hdr_buf); + if (paths_count == 0) + { + *pcount = 0; + *ppaths = NULL; + ret = 1; + goto exit; + } + + paths = ((const char **) + backtrace_alloc (state, paths_count * sizeof (const char *), + hdr_buf->error_callback, hdr_buf->data)); + if (paths == NULL) + { + ret = 0; + goto exit; + } + for (i = 0; i < paths_count; i++) + { + if (!read_lnct (state, ddata, u, hdr_buf, hdr, formats_count, + formats, &paths[i])) + { + backtrace_free (state, paths, + paths_count * sizeof (const char *), + hdr_buf->error_callback, hdr_buf->data); + ret = 0; + goto exit; + } + } + + *pcount = paths_count; + *ppaths = paths; + + ret = 1; + + exit: + if (formats != NULL) + backtrace_free (state, formats, + formats_count * sizeof (struct line_header_format), + hdr_buf->error_callback, hdr_buf->data); + + return ret; +} + +/* Read the line header. Return 1 on success, 0 on failure. */ + +static int +read_line_header (struct backtrace_state *state, struct dwarf_data *ddata, + struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf, + struct line_header *hdr) +{ + uint64_t hdrlen; + struct dwarf_buf hdr_buf; + + hdr->version = read_uint16 (line_buf); + if (hdr->version < 2 || hdr->version > 5) + { + dwarf_buf_error (line_buf, "unsupported line number version", -1); + return 0; + } + + if (hdr->version < 5) + hdr->addrsize = u->addrsize; + else + { + hdr->addrsize = read_byte (line_buf); + /* We could support a non-zero segment_selector_size but I doubt + we'll ever see it. */ + if (read_byte (line_buf) != 0) + { + dwarf_buf_error (line_buf, + "non-zero segment_selector_size not supported", + -1); + return 0; + } + } + + hdrlen = read_offset (line_buf, is_dwarf64); + + hdr_buf = *line_buf; + hdr_buf.left = hdrlen; + + if (!advance (line_buf, hdrlen)) + return 0; + + hdr->min_insn_len = read_byte (&hdr_buf); + if (hdr->version < 4) + hdr->max_ops_per_insn = 1; + else + hdr->max_ops_per_insn = read_byte (&hdr_buf); + + /* We don't care about default_is_stmt. */ + read_byte (&hdr_buf); + + hdr->line_base = read_sbyte (&hdr_buf); + hdr->line_range = read_byte (&hdr_buf); + + hdr->opcode_base = read_byte (&hdr_buf); + hdr->opcode_lengths = hdr_buf.buf; + if (!advance (&hdr_buf, hdr->opcode_base - 1)) + return 0; + + if (hdr->version < 5) + { + if (!read_v2_paths (state, u, &hdr_buf, hdr)) + return 0; + } + else + { + if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr, + &hdr->dirs_count, + &hdr->dirs)) + return 0; + if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr, + &hdr->filenames_count, + &hdr->filenames)) + return 0; + } + + if (hdr_buf.reported_underflow) + return 0; + + return 1; +} + +/* Read the line program, adding line mappings to VEC. Return 1 on + success, 0 on failure. */ + +static int +read_line_program (struct backtrace_state *state, struct dwarf_data *ddata, + const struct line_header *hdr, struct dwarf_buf *line_buf, + struct line_vector *vec) +{ + uint64_t address; + unsigned int op_index; + const char *reset_filename; + const char *filename; + int lineno; + + address = 0; + op_index = 0; + if (hdr->filenames_count > 1) + reset_filename = hdr->filenames[1]; + else + reset_filename = ""; + filename = reset_filename; + lineno = 1; + while (line_buf->left > 0) + { + unsigned int op; + + op = read_byte (line_buf); + if (op >= hdr->opcode_base) + { + unsigned int advance; + + /* Special opcode. */ + op -= hdr->opcode_base; + advance = op / hdr->line_range; + address += (hdr->min_insn_len * (op_index + advance) + / hdr->max_ops_per_insn); + op_index = (op_index + advance) % hdr->max_ops_per_insn; + lineno += hdr->line_base + (int) (op % hdr->line_range); + add_line (state, ddata, address, filename, lineno, + line_buf->error_callback, line_buf->data, vec); + } + else if (op == DW_LNS_extended_op) + { + uint64_t len; + + len = read_uleb128 (line_buf); + op = read_byte (line_buf); + switch (op) + { + case DW_LNE_end_sequence: + /* FIXME: Should we mark the high PC here? It seems + that we already have that information from the + compilation unit. */ + address = 0; + op_index = 0; + filename = reset_filename; + lineno = 1; + break; + case DW_LNE_set_address: + address = read_address (line_buf, hdr->addrsize); + break; + case DW_LNE_define_file: + { + const char *f; + unsigned int dir_index; + + f = read_string (line_buf); + if (f == NULL) + return 0; + dir_index = read_uleb128 (line_buf); + /* Ignore that time and length. */ + read_uleb128 (line_buf); + read_uleb128 (line_buf); + if (IS_ABSOLUTE_PATH (f)) + filename = f; + else + { + const char *dir; + size_t dir_len; + size_t f_len; + char *p; + + if (dir_index < hdr->dirs_count) + dir = hdr->dirs[dir_index]; + else + { + dwarf_buf_error (line_buf, + ("invalid directory index " + "in line number program"), + 0); + return 0; + } + dir_len = strlen (dir); + f_len = strlen (f); + p = ((char *) + backtrace_alloc (state, dir_len + f_len + 2, + line_buf->error_callback, + line_buf->data)); + if (p == NULL) + return 0; + memcpy (p, dir, dir_len); + /* FIXME: If we are on a DOS-based file system, + and the directory or the file name use + backslashes, then we should use a backslash + here. */ + p[dir_len] = '/'; + memcpy (p + dir_len + 1, f, f_len + 1); + filename = p; + } + } + break; + case DW_LNE_set_discriminator: + /* We don't care about discriminators. */ + read_uleb128 (line_buf); + break; + default: + if (!advance (line_buf, len - 1)) + return 0; + break; + } + } + else + { + switch (op) + { + case DW_LNS_copy: + add_line (state, ddata, address, filename, lineno, + line_buf->error_callback, line_buf->data, vec); + break; + case DW_LNS_advance_pc: + { + uint64_t advance; + + advance = read_uleb128 (line_buf); + address += (hdr->min_insn_len * (op_index + advance) + / hdr->max_ops_per_insn); + op_index = (op_index + advance) % hdr->max_ops_per_insn; + } + break; + case DW_LNS_advance_line: + lineno += (int) read_sleb128 (line_buf); + break; + case DW_LNS_set_file: + { + uint64_t fileno; + + fileno = read_uleb128 (line_buf); + if (fileno >= hdr->filenames_count) + { + dwarf_buf_error (line_buf, + ("invalid file number in " + "line number program"), + 0); + return 0; + } + filename = hdr->filenames[fileno]; + } + break; + case DW_LNS_set_column: + read_uleb128 (line_buf); + break; + case DW_LNS_negate_stmt: + break; + case DW_LNS_set_basic_block: + break; + case DW_LNS_const_add_pc: + { + unsigned int advance; + + op = 255 - hdr->opcode_base; + advance = op / hdr->line_range; + address += (hdr->min_insn_len * (op_index + advance) + / hdr->max_ops_per_insn); + op_index = (op_index + advance) % hdr->max_ops_per_insn; + } + break; + case DW_LNS_fixed_advance_pc: + address += read_uint16 (line_buf); + op_index = 0; + break; + case DW_LNS_set_prologue_end: + break; + case DW_LNS_set_epilogue_begin: + break; + case DW_LNS_set_isa: + read_uleb128 (line_buf); + break; + default: + { + unsigned int i; + + for (i = hdr->opcode_lengths[op - 1]; i > 0; --i) + read_uleb128 (line_buf); + } + break; + } + } + } + + return 1; +} + +/* Read the line number information for a compilation unit. Returns 1 + on success, 0 on failure. */ + +static int +read_line_info (struct backtrace_state *state, struct dwarf_data *ddata, + backtrace_error_callback error_callback, void *data, + struct unit *u, struct line_header *hdr, struct line **lines, + size_t *lines_count) +{ + struct line_vector vec; + struct dwarf_buf line_buf; + uint64_t len; + int is_dwarf64; + struct line *ln; + + memset (&vec.vec, 0, sizeof vec.vec); + vec.count = 0; + + memset (hdr, 0, sizeof *hdr); + + if (u->lineoff != (off_t) (size_t) u->lineoff + || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE]) + { + error_callback (data, "unit line offset out of range", 0); + goto fail; + } + + line_buf.name = ".debug_line"; + line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE]; + line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff; + line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff; + line_buf.is_bigendian = ddata->is_bigendian; + line_buf.error_callback = error_callback; + line_buf.data = data; + line_buf.reported_underflow = 0; + + len = read_initial_length (&line_buf, &is_dwarf64); + line_buf.left = len; + + if (!read_line_header (state, ddata, u, is_dwarf64, &line_buf, hdr)) + goto fail; + + if (!read_line_program (state, ddata, hdr, &line_buf, &vec)) + goto fail; + + if (line_buf.reported_underflow) + goto fail; + + if (vec.count == 0) + { + /* This is not a failure in the sense of a generating an error, + but it is a failure in that sense that we have no useful + information. */ + goto fail; + } + + /* Allocate one extra entry at the end. */ + ln = ((struct line *) + backtrace_vector_grow (state, sizeof (struct line), error_callback, + data, &vec.vec)); + if (ln == NULL) + goto fail; + ln->pc = (uintptr_t) -1; + ln->filename = NULL; + ln->lineno = 0; + ln->idx = 0; + + if (!backtrace_vector_release (state, &vec.vec, error_callback, data)) + goto fail; + + ln = (struct line *) vec.vec.base; + backtrace_qsort (ln, vec.count, sizeof (struct line), line_compare); + + *lines = ln; + *lines_count = vec.count; + + return 1; + + fail: + backtrace_vector_free (state, &vec.vec, error_callback, data); + free_line_header (state, hdr, error_callback, data); + *lines = (struct line *) (uintptr_t) -1; + *lines_count = 0; + return 0; +} + +static const char *read_referenced_name (struct dwarf_data *, struct unit *, + uint64_t, backtrace_error_callback, + void *); + +/* Read the name of a function from a DIE referenced by ATTR with VAL. */ + +static const char * +read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u, + struct attr *attr, struct attr_val *val, + backtrace_error_callback error_callback, + void *data) +{ + switch (attr->name) + { + case DW_AT_abstract_origin: + case DW_AT_specification: + break; + default: + return NULL; + } + + if (attr->form == DW_FORM_ref_sig8) + return NULL; + + if (val->encoding == ATTR_VAL_REF_INFO) + { + struct unit *unit + = find_unit (ddata->units, ddata->units_count, + val->u.uint); + if (unit == NULL) + return NULL; + + uint64_t offset = val->u.uint - unit->low_offset; + return read_referenced_name (ddata, unit, offset, error_callback, data); + } + + if (val->encoding == ATTR_VAL_UINT + || val->encoding == ATTR_VAL_REF_UNIT) + return read_referenced_name (ddata, u, val->u.uint, error_callback, data); + + if (val->encoding == ATTR_VAL_REF_ALT_INFO) + { + struct unit *alt_unit + = find_unit (ddata->altlink->units, ddata->altlink->units_count, + val->u.uint); + if (alt_unit == NULL) + return NULL; + + uint64_t offset = val->u.uint - alt_unit->low_offset; + return read_referenced_name (ddata->altlink, alt_unit, offset, + error_callback, data); + } + + return NULL; +} + +/* Read the name of a function from a DIE referenced by a + DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within + the same compilation unit. */ + +static const char * +read_referenced_name (struct dwarf_data *ddata, struct unit *u, + uint64_t offset, backtrace_error_callback error_callback, + void *data) +{ + struct dwarf_buf unit_buf; + uint64_t code; + const struct abbrev *abbrev; + const char *ret; + size_t i; + + /* OFFSET is from the start of the data for this compilation unit. + U->unit_data is the data, but it starts U->unit_data_offset bytes + from the beginning. */ + + if (offset < u->unit_data_offset + || offset - u->unit_data_offset >= u->unit_data_len) + { + error_callback (data, + "abstract origin or specification out of range", + 0); + return NULL; + } + + offset -= u->unit_data_offset; + + unit_buf.name = ".debug_info"; + unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO]; + unit_buf.buf = u->unit_data + offset; + unit_buf.left = u->unit_data_len - offset; + unit_buf.is_bigendian = ddata->is_bigendian; + unit_buf.error_callback = error_callback; + unit_buf.data = data; + unit_buf.reported_underflow = 0; + + code = read_uleb128 (&unit_buf); + if (code == 0) + { + dwarf_buf_error (&unit_buf, + "invalid abstract origin or specification", + 0); + return NULL; + } + + abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data); + if (abbrev == NULL) + return NULL; + + ret = NULL; + for (i = 0; i < abbrev->num_attrs; ++i) + { + struct attr_val val; + + if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val, + &unit_buf, u->is_dwarf64, u->version, u->addrsize, + &ddata->dwarf_sections, ddata->altlink, &val)) + return NULL; + + switch (abbrev->attrs[i].name) + { + case DW_AT_name: + /* Third name preference: don't override. A name we found in some + other way, will normally be more useful -- e.g., this name is + normally not mangled. */ + if (ret != NULL) + break; + if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64, + ddata->is_bigendian, u->str_offsets_base, + &val, error_callback, data, &ret)) + return NULL; + break; + + case DW_AT_linkage_name: + case DW_AT_MIPS_linkage_name: + /* First name preference: override all. */ + { + const char *s; + + s = NULL; + if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64, + ddata->is_bigendian, u->str_offsets_base, + &val, error_callback, data, &s)) + return NULL; + if (s != NULL) + return s; + } + break; + + case DW_AT_specification: + /* Second name preference: override DW_AT_name, don't override + DW_AT_linkage_name. */ + { + const char *name; + + name = read_referenced_name_from_attr (ddata, u, &abbrev->attrs[i], + &val, error_callback, data); + if (name != NULL) + ret = name; + } + break; + + default: + break; + } + } + + return ret; +} + +/* Add a range to a unit that maps to a function. This is called via + add_ranges. Returns 1 on success, 0 on error. */ + +static int +add_function_range (struct backtrace_state *state, void *rdata, + uintptr_t lowpc, uintptr_t highpc, + backtrace_error_callback error_callback, void *data, + void *pvec) +{ + struct function *function = (struct function *) rdata; + struct function_vector *vec = (struct function_vector *) pvec; + struct function_addrs *p; + + if (vec->count > 0) + { + p = (struct function_addrs *) vec->vec.base + (vec->count - 1); + if ((lowpc == p->high || lowpc == p->high + 1) + && function == p->function) + { + if (highpc > p->high) + p->high = highpc; + return 1; + } + } + + p = ((struct function_addrs *) + backtrace_vector_grow (state, sizeof (struct function_addrs), + error_callback, data, &vec->vec)); + if (p == NULL) + return 0; + + p->low = lowpc; + p->high = highpc; + p->function = function; + + ++vec->count; + + return 1; +} + +/* Read one entry plus all its children. Add function addresses to + VEC. Returns 1 on success, 0 on error. */ + +static int +read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, + struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf, + const struct line_header *lhdr, + backtrace_error_callback error_callback, void *data, + struct function_vector *vec_function, + struct function_vector *vec_inlined) +{ + while (unit_buf->left > 0) + { + uint64_t code; + const struct abbrev *abbrev; + int is_function; + struct function *function; + struct function_vector *vec; + size_t i; + struct pcrange pcrange; + int have_linkage_name; + + code = read_uleb128 (unit_buf); + if (code == 0) + return 1; + + abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data); + if (abbrev == NULL) + return 0; + + is_function = (abbrev->tag == DW_TAG_subprogram + || abbrev->tag == DW_TAG_entry_point + || abbrev->tag == DW_TAG_inlined_subroutine); + + if (abbrev->tag == DW_TAG_inlined_subroutine) + vec = vec_inlined; + else + vec = vec_function; + + function = NULL; + if (is_function) + { + function = ((struct function *) + backtrace_alloc (state, sizeof *function, + error_callback, data)); + if (function == NULL) + return 0; + memset (function, 0, sizeof *function); + } + + memset (&pcrange, 0, sizeof pcrange); + have_linkage_name = 0; + for (i = 0; i < abbrev->num_attrs; ++i) + { + struct attr_val val; + + if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val, + unit_buf, u->is_dwarf64, u->version, + u->addrsize, &ddata->dwarf_sections, + ddata->altlink, &val)) + return 0; + + /* The compile unit sets the base address for any address + ranges in the function entries. */ + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) + && abbrev->attrs[i].name == DW_AT_low_pc) + { + if (val.encoding == ATTR_VAL_ADDRESS) + base = (uintptr_t) val.u.uint; + else if (val.encoding == ATTR_VAL_ADDRESS_INDEX) + { + if (!resolve_addr_index (&ddata->dwarf_sections, + u->addr_base, u->addrsize, + ddata->is_bigendian, val.u.uint, + error_callback, data, &base)) + return 0; + } + } + + if (is_function) + { + switch (abbrev->attrs[i].name) + { + case DW_AT_call_file: + if (val.encoding == ATTR_VAL_UINT) + { + if (val.u.uint >= lhdr->filenames_count) + { + dwarf_buf_error (unit_buf, + ("invalid file number in " + "DW_AT_call_file attribute"), + 0); + return 0; + } + function->caller_filename = lhdr->filenames[val.u.uint]; + } + break; + + case DW_AT_call_line: + if (val.encoding == ATTR_VAL_UINT) + function->caller_lineno = val.u.uint; + break; + + case DW_AT_abstract_origin: + case DW_AT_specification: + /* Second name preference: override DW_AT_name, don't override + DW_AT_linkage_name. */ + if (have_linkage_name) + break; + { + const char *name; + + name + = read_referenced_name_from_attr (ddata, u, + &abbrev->attrs[i], &val, + error_callback, data); + if (name != NULL) + function->name = name; + } + break; + + case DW_AT_name: + /* Third name preference: don't override. */ + if (function->name != NULL) + break; + if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64, + ddata->is_bigendian, + u->str_offsets_base, &val, + error_callback, data, &function->name)) + return 0; + break; + + case DW_AT_linkage_name: + case DW_AT_MIPS_linkage_name: + /* First name preference: override all. */ + { + const char *s; + + s = NULL; + if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64, + ddata->is_bigendian, + u->str_offsets_base, &val, + error_callback, data, &s)) + return 0; + if (s != NULL) + { + function->name = s; + have_linkage_name = 1; + } + } + break; + + case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges: + update_pcrange (&abbrev->attrs[i], &val, &pcrange); + break; + + default: + break; + } + } + } + + /* If we couldn't find a name for the function, we have no use + for it. */ + if (is_function && function->name == NULL) + { + backtrace_free (state, function, sizeof *function, + error_callback, data); + is_function = 0; + } + + if (is_function) + { + if (pcrange.have_ranges + || (pcrange.have_lowpc && pcrange.have_highpc)) + { + if (!add_ranges (state, &ddata->dwarf_sections, + ddata->base_address, ddata->is_bigendian, + u, base, &pcrange, add_function_range, + (void *) function, error_callback, data, + (void *) vec)) + return 0; + } + else + { + backtrace_free (state, function, sizeof *function, + error_callback, data); + is_function = 0; + } + } + + if (abbrev->has_children) + { + if (!is_function) + { + if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr, + error_callback, data, vec_function, + vec_inlined)) + return 0; + } + else + { + struct function_vector fvec; + + /* Gather any information for inlined functions in + FVEC. */ + + memset (&fvec, 0, sizeof fvec); + + if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr, + error_callback, data, vec_function, + &fvec)) + return 0; + + if (fvec.count > 0) + { + struct function_addrs *p; + struct function_addrs *faddrs; + + /* Allocate a trailing entry, but don't include it + in fvec.count. */ + p = ((struct function_addrs *) + backtrace_vector_grow (state, + sizeof (struct function_addrs), + error_callback, data, + &fvec.vec)); + if (p == NULL) + return 0; + p->low = 0; + --p->low; + p->high = p->low; + p->function = NULL; + + if (!backtrace_vector_release (state, &fvec.vec, + error_callback, data)) + return 0; + + faddrs = (struct function_addrs *) fvec.vec.base; + backtrace_qsort (faddrs, fvec.count, + sizeof (struct function_addrs), + function_addrs_compare); + + function->function_addrs = faddrs; + function->function_addrs_count = fvec.count; + } + } + } + } + + return 1; +} + +/* Read function name information for a compilation unit. We look + through the whole unit looking for function tags. */ + +static void +read_function_info (struct backtrace_state *state, struct dwarf_data *ddata, + const struct line_header *lhdr, + backtrace_error_callback error_callback, void *data, + struct unit *u, struct function_vector *fvec, + struct function_addrs **ret_addrs, + size_t *ret_addrs_count) +{ + struct function_vector lvec; + struct function_vector *pfvec; + struct dwarf_buf unit_buf; + struct function_addrs *p; + struct function_addrs *addrs; + size_t addrs_count; + + /* Use FVEC if it is not NULL. Otherwise use our own vector. */ + if (fvec != NULL) + pfvec = fvec; + else + { + memset (&lvec, 0, sizeof lvec); + pfvec = &lvec; + } + + unit_buf.name = ".debug_info"; + unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO]; + unit_buf.buf = u->unit_data; + unit_buf.left = u->unit_data_len; + unit_buf.is_bigendian = ddata->is_bigendian; + unit_buf.error_callback = error_callback; + unit_buf.data = data; + unit_buf.reported_underflow = 0; + + while (unit_buf.left > 0) + { + if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr, + error_callback, data, pfvec, pfvec)) + return; + } + + if (pfvec->count == 0) + return; + + /* Allocate a trailing entry, but don't include it in + pfvec->count. */ + p = ((struct function_addrs *) + backtrace_vector_grow (state, sizeof (struct function_addrs), + error_callback, data, &pfvec->vec)); + if (p == NULL) + return; + p->low = 0; + --p->low; + p->high = p->low; + p->function = NULL; + + addrs_count = pfvec->count; + + if (fvec == NULL) + { + if (!backtrace_vector_release (state, &lvec.vec, error_callback, data)) + return; + addrs = (struct function_addrs *) pfvec->vec.base; + } + else + { + /* Finish this list of addresses, but leave the remaining space in + the vector available for the next function unit. */ + addrs = ((struct function_addrs *) + backtrace_vector_finish (state, &fvec->vec, + error_callback, data)); + if (addrs == NULL) + return; + fvec->count = 0; + } + + backtrace_qsort (addrs, addrs_count, sizeof (struct function_addrs), + function_addrs_compare); + + *ret_addrs = addrs; + *ret_addrs_count = addrs_count; +} + +/* See if PC is inlined in FUNCTION. If it is, print out the inlined + information, and update FILENAME and LINENO for the caller. + Returns whatever CALLBACK returns, or 0 to keep going. */ + +static int +report_inlined_functions (uintptr_t pc, struct function *function, const char* comp_dir, + backtrace_full_callback callback, void *data, + const char **filename, int *lineno) +{ + struct function_addrs *p; + struct function_addrs *match; + struct function *inlined; + int ret; + + if (function->function_addrs_count == 0) + return 0; + + /* Our search isn't safe if pc == -1, as that is the sentinel + value. */ + if (pc + 1 == 0) + return 0; + + p = ((struct function_addrs *) + bsearch (&pc, function->function_addrs, + function->function_addrs_count, + sizeof (struct function_addrs), + function_addrs_search)); + if (p == NULL) + return 0; + + /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are + sorted by low, so if pc > p->low we are at the end of a range of + function_addrs with the same low value. If pc == p->low walk + forward to the end of the range with that low value. Then walk + backward and use the first range that includes pc. */ + while (pc == (p + 1)->low) + ++p; + match = NULL; + while (1) + { + if (pc < p->high) + { + match = p; + break; + } + if (p == function->function_addrs) + break; + if ((p - 1)->low < p->low) + break; + --p; + } + if (match == NULL) + return 0; + + /* We found an inlined call. */ + + inlined = match->function; + + /* Report any calls inlined into this one. */ + ret = report_inlined_functions (pc, inlined, comp_dir, callback, data, + filename, lineno); + if (ret != 0) + return ret; + + /* Report this inlined call. */ + if (*filename[0] != '/' && comp_dir) + { + char buf[1024]; + snprintf (buf, 1024, "%s/%s", comp_dir, *filename); + ret = callback (data, pc, match->low, buf, *lineno, inlined->name); + } + else + { + ret = callback (data, pc, match->low, *filename, *lineno, inlined->name); + } + if (ret != 0) + return ret; + + /* Our caller will report the caller of the inlined function; tell + it the appropriate filename and line number. */ + *filename = inlined->caller_filename; + *lineno = inlined->caller_lineno; + + return 0; +} + +/* Look for a PC in the DWARF mapping for one module. On success, + call CALLBACK and return whatever it returns. On error, call + ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found, + 0 if not. */ + +static int +dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata, + uintptr_t pc, backtrace_full_callback callback, + backtrace_error_callback error_callback, void *data, + int *found) +{ + struct unit_addrs *entry; + int found_entry; + struct unit *u; + int new_data; + struct line *lines; + struct line *ln; + struct function_addrs *p; + struct function_addrs *fmatch; + struct function *function; + const char *filename; + int lineno; + int ret; + + *found = 1; + + /* Find an address range that includes PC. Our search isn't safe if + PC == -1, as we use that as a sentinel value, so skip the search + in that case. */ + entry = (ddata->addrs_count == 0 || pc + 1 == 0 + ? NULL + : (struct unit_addrs*)bsearch (&pc, ddata->addrs, ddata->addrs_count, + sizeof (struct unit_addrs), unit_addrs_search)); + + if (entry == NULL) + { + *found = 0; + return 0; + } + + /* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs + are sorted by low, so if pc > p->low we are at the end of a range + of unit_addrs with the same low value. If pc == p->low walk + forward to the end of the range with that low value. Then walk + backward and use the first range that includes pc. */ + while (pc == (entry + 1)->low) + ++entry; + found_entry = 0; + while (1) + { + if (pc < entry->high) + { + found_entry = 1; + break; + } + if (entry == ddata->addrs) + break; + if ((entry - 1)->low < entry->low) + break; + --entry; + } + if (!found_entry) + { + *found = 0; + return 0; + } + + /* We need the lines, lines_count, function_addrs, + function_addrs_count fields of u. If they are not set, we need + to set them. When running in threaded mode, we need to allow for + the possibility that some other thread is setting them + simultaneously. */ + + u = entry->u; + lines = u->lines; + + /* Skip units with no useful line number information by walking + backward. Useless line number information is marked by setting + lines == -1. */ + while (entry > ddata->addrs + && pc >= (entry - 1)->low + && pc < (entry - 1)->high) + { + if (state->threaded) + lines = (struct line *) backtrace_atomic_load_pointer (&u->lines); + + if (lines != (struct line *) (uintptr_t) -1) + break; + + --entry; + + u = entry->u; + lines = u->lines; + } + + if (state->threaded) + lines = backtrace_atomic_load_pointer (&u->lines); + + new_data = 0; + if (lines == NULL) + { + struct function_addrs *function_addrs; + size_t function_addrs_count; + struct line_header lhdr; + size_t count; + + /* We have never read the line information for this unit. Read + it now. */ + + function_addrs = NULL; + function_addrs_count = 0; + if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr, + &lines, &count)) + { + struct function_vector *pfvec; + + /* If not threaded, reuse DDATA->FVEC for better memory + consumption. */ + if (state->threaded) + pfvec = NULL; + else + pfvec = &ddata->fvec; + read_function_info (state, ddata, &lhdr, error_callback, data, + entry->u, pfvec, &function_addrs, + &function_addrs_count); + free_line_header (state, &lhdr, error_callback, data); + new_data = 1; + } + + /* Atomically store the information we just read into the unit. + If another thread is simultaneously writing, it presumably + read the same information, and we don't care which one we + wind up with; we just leak the other one. We do have to + write the lines field last, so that the acquire-loads above + ensure that the other fields are set. */ + + if (!state->threaded) + { + u->lines_count = count; + u->function_addrs = function_addrs; + u->function_addrs_count = function_addrs_count; + u->lines = lines; + } + else + { + backtrace_atomic_store_size_t (&u->lines_count, count); + backtrace_atomic_store_pointer (&u->function_addrs, function_addrs); + backtrace_atomic_store_size_t (&u->function_addrs_count, + function_addrs_count); + backtrace_atomic_store_pointer (&u->lines, lines); + } + } + + /* Now all fields of U have been initialized. */ + + if (lines == (struct line *) (uintptr_t) -1) + { + /* If reading the line number information failed in some way, + try again to see if there is a better compilation unit for + this PC. */ + if (new_data) + return dwarf_lookup_pc (state, ddata, pc, callback, error_callback, + data, found); + return callback (data, pc, 0, NULL, 0, NULL); + } + + /* Search for PC within this unit. */ + + ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count, + sizeof (struct line), line_search); + if (ln == NULL) + { + /* The PC is between the low_pc and high_pc attributes of the + compilation unit, but no entry in the line table covers it. + This implies that the start of the compilation unit has no + line number information. */ + + if (entry->u->abs_filename == NULL) + { + const char *filename; + + filename = entry->u->filename; + if (filename != NULL + && !IS_ABSOLUTE_PATH (filename) + && entry->u->comp_dir != NULL) + { + size_t filename_len; + const char *dir; + size_t dir_len; + char *s; + + filename_len = strlen (filename); + dir = entry->u->comp_dir; + dir_len = strlen (dir); + s = (char *) backtrace_alloc (state, dir_len + filename_len + 2, + error_callback, data); + if (s == NULL) + { + *found = 0; + return 0; + } + memcpy (s, dir, dir_len); + /* FIXME: Should use backslash if DOS file system. */ + s[dir_len] = '/'; + memcpy (s + dir_len + 1, filename, filename_len + 1); + filename = s; + } + entry->u->abs_filename = filename; + } + + return callback (data, pc, 0, entry->u->abs_filename, 0, NULL); + } + + /* Search for function name within this unit. */ + + if (entry->u->function_addrs_count == 0) + return callback (data, pc, 0, ln->filename, ln->lineno, NULL); + + p = ((struct function_addrs *) + bsearch (&pc, entry->u->function_addrs, + entry->u->function_addrs_count, + sizeof (struct function_addrs), + function_addrs_search)); + if (p == NULL) + return callback (data, pc, 0, ln->filename, ln->lineno, NULL); + + /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are + sorted by low, so if pc > p->low we are at the end of a range of + function_addrs with the same low value. If pc == p->low walk + forward to the end of the range with that low value. Then walk + backward and use the first range that includes pc. */ + while (pc == (p + 1)->low) + ++p; + fmatch = NULL; + while (1) + { + if (pc < p->high) + { + fmatch = p; + break; + } + if (p == entry->u->function_addrs) + break; + if ((p - 1)->low < p->low) + break; + --p; + } + if (fmatch == NULL) + return callback (data, pc, 0, ln->filename, ln->lineno, NULL); + + function = fmatch->function; + + filename = ln->filename; + lineno = ln->lineno; + + ret = report_inlined_functions (pc, function, entry->u->comp_dir, callback, data, + &filename, &lineno); + if (ret != 0) + return ret; + + if (filename[0] != '/' && entry->u->comp_dir) + { + char buf[1024]; + snprintf (buf, 1024, "%s/%s", entry->u->comp_dir, filename); + return callback (data, pc, fmatch->low, buf, lineno, function->name); + } + else + { + return callback (data, pc, fmatch->low, filename, lineno, function->name); + } +} + + +/* Return the file/line information for a PC using the DWARF mapping + we built earlier. */ + +static int +dwarf_fileline (struct backtrace_state *state, uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, void *data) +{ + struct dwarf_data *ddata; + int found; + int ret; + + if (!state->threaded) + { + for (ddata = (struct dwarf_data *) state->fileline_data; + ddata != NULL; + ddata = ddata->next) + { + ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback, + data, &found); + if (ret != 0 || found) + return ret; + } + } + else + { + struct dwarf_data **pp; + + pp = (struct dwarf_data **) (void *) &state->fileline_data; + while (1) + { + ddata = backtrace_atomic_load_pointer (pp); + if (ddata == NULL) + break; + + ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback, + data, &found); + if (ret != 0 || found) + return ret; + + pp = &ddata->next; + } + } + + /* FIXME: See if any libraries have been dlopen'ed. */ + + return callback (data, pc, 0, NULL, 0, NULL); +} + +/* Initialize our data structures from the DWARF debug info for a + file. Return NULL on failure. */ + +static struct dwarf_data * +build_dwarf_data (struct backtrace_state *state, + uintptr_t base_address, + const struct dwarf_sections *dwarf_sections, + int is_bigendian, + struct dwarf_data *altlink, + backtrace_error_callback error_callback, + void *data) +{ + struct unit_addrs_vector addrs_vec; + struct unit_addrs *addrs; + size_t addrs_count; + struct unit_vector units_vec; + struct unit **units; + size_t units_count; + struct dwarf_data *fdata; + + if (!build_address_map (state, base_address, dwarf_sections, is_bigendian, + altlink, error_callback, data, &addrs_vec, + &units_vec)) + return NULL; + + if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data)) + return NULL; + if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data)) + return NULL; + addrs = (struct unit_addrs *) addrs_vec.vec.base; + units = (struct unit **) units_vec.vec.base; + addrs_count = addrs_vec.count; + units_count = units_vec.count; + backtrace_qsort (addrs, addrs_count, sizeof (struct unit_addrs), + unit_addrs_compare); + /* No qsort for units required, already sorted. */ + + fdata = ((struct dwarf_data *) + backtrace_alloc (state, sizeof (struct dwarf_data), + error_callback, data)); + if (fdata == NULL) + return NULL; + + fdata->next = NULL; + fdata->altlink = altlink; + fdata->base_address = base_address; + fdata->addrs = addrs; + fdata->addrs_count = addrs_count; + fdata->units = units; + fdata->units_count = units_count; + fdata->dwarf_sections = *dwarf_sections; + fdata->is_bigendian = is_bigendian; + memset (&fdata->fvec, 0, sizeof fdata->fvec); + + return fdata; +} + +/* Build our data structures from the DWARF sections for a module. + Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0 + on failure. */ + +int +backtrace_dwarf_add (struct backtrace_state *state, + uintptr_t base_address, + const struct dwarf_sections *dwarf_sections, + int is_bigendian, + struct dwarf_data *fileline_altlink, + backtrace_error_callback error_callback, + void *data, fileline *fileline_fn, + struct dwarf_data **fileline_entry) +{ + struct dwarf_data *fdata; + + fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian, + fileline_altlink, error_callback, data); + if (fdata == NULL) + return 0; + + if (fileline_entry != NULL) + *fileline_entry = fdata; + + if (!state->threaded) + { + struct dwarf_data **pp; + + for (pp = (struct dwarf_data **) (void *) &state->fileline_data; + *pp != NULL; + pp = &(*pp)->next) + ; + *pp = fdata; + } + else + { + while (1) + { + struct dwarf_data **pp; + + pp = (struct dwarf_data **) (void *) &state->fileline_data; + + while (1) + { + struct dwarf_data *p; + + p = backtrace_atomic_load_pointer (pp); + + if (p == NULL) + break; + + pp = &p->next; + } + + if (__sync_bool_compare_and_swap (pp, NULL, fdata)) + break; + } + } + + *fileline_fn = dwarf_fileline; + + return 1; +} + +} diff --git a/Externals/tracy/public/libbacktrace/elf.cpp b/Externals/tracy/public/libbacktrace/elf.cpp new file mode 100644 index 00000000000..c65bc4e768a --- /dev/null +++ b/Externals/tracy/public/libbacktrace/elf.cpp @@ -0,0 +1,7491 @@ +/* elf.c -- Get debug data from an ELF file for backtraces. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_DL_ITERATE_PHDR +#include +#endif + +#include "backtrace.hpp" +#include "internal.hpp" + +#include "../client/TracyFastVector.hpp" +#include "../common/TracyAlloc.hpp" + +#ifndef S_ISLNK + #ifndef S_IFLNK + #define S_IFLNK 0120000 + #endif + #ifndef S_IFMT + #define S_IFMT 0170000 + #endif + #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif + +#ifndef __GNUC__ +#define __builtin_prefetch(p, r, l) +#ifndef unlikely +#define unlikely(x) (x) +#endif +#else +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#endif + +namespace tracy +{ + +#ifdef TRACY_DEBUGINFOD +int GetDebugInfoDescriptor( const char* buildid_data, size_t buildid_size ); +#endif + +#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN + +/* If strnlen is not declared, provide our own version. */ + +static size_t +xstrnlen (const char *s, size_t maxlen) +{ + size_t i; + + for (i = 0; i < maxlen; ++i) + if (s[i] == '\0') + break; + return i; +} + +#define strnlen xstrnlen + +#endif + +#ifndef HAVE_LSTAT + +/* Dummy version of lstat for systems that don't have it. */ + +static int +xlstat (const char *path ATTRIBUTE_UNUSED, struct stat *st ATTRIBUTE_UNUSED) +{ + return -1; +} + +#define lstat xlstat + +#endif + +#ifndef HAVE_READLINK + +/* Dummy version of readlink for systems that don't have it. */ + +static ssize_t +xreadlink (const char *path ATTRIBUTE_UNUSED, char *buf ATTRIBUTE_UNUSED, + size_t bufsz ATTRIBUTE_UNUSED) +{ + return -1; +} + +#define readlink xreadlink + +#endif + +#ifndef HAVE_DL_ITERATE_PHDR + +/* Dummy version of dl_iterate_phdr for systems that don't have it. */ + +#define dl_phdr_info x_dl_phdr_info +#define dl_iterate_phdr x_dl_iterate_phdr + +struct dl_phdr_info +{ + uintptr_t dlpi_addr; + const char *dlpi_name; +}; + +static int +dl_iterate_phdr (int (*callback) (struct dl_phdr_info *, + size_t, void *) ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + return 0; +} + +#endif /* ! defined (HAVE_DL_ITERATE_PHDR) */ + +/* The configure script must tell us whether we are 32-bit or 64-bit + ELF. We could make this code test and support either possibility, + but there is no point. This code only works for the currently + running executable, which means that we know the ELF mode at + configure time. */ + +#if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64 +#error "Unknown BACKTRACE_ELF_SIZE" +#endif + +/* might #include which might define our constants + with slightly different values. Undefine them to be safe. */ + +#undef EI_NIDENT +#undef EI_MAG0 +#undef EI_MAG1 +#undef EI_MAG2 +#undef EI_MAG3 +#undef EI_CLASS +#undef EI_DATA +#undef EI_VERSION +#undef ELF_MAG0 +#undef ELF_MAG1 +#undef ELF_MAG2 +#undef ELF_MAG3 +#undef ELFCLASS32 +#undef ELFCLASS64 +#undef ELFDATA2LSB +#undef ELFDATA2MSB +#undef EV_CURRENT +#undef ET_DYN +#undef EM_PPC64 +#undef EF_PPC64_ABI +#undef SHN_LORESERVE +#undef SHN_XINDEX +#undef SHN_UNDEF +#undef SHT_PROGBITS +#undef SHT_SYMTAB +#undef SHT_STRTAB +#undef SHT_DYNSYM +#undef SHF_COMPRESSED +#undef STT_OBJECT +#undef STT_FUNC +#undef NT_GNU_BUILD_ID +#undef ELFCOMPRESS_ZLIB +#undef ELFCOMPRESS_ZSTD + +/* Basic types. */ + +typedef uint16_t b_elf_half; /* Elf_Half. */ +typedef uint32_t b_elf_word; /* Elf_Word. */ +typedef int32_t b_elf_sword; /* Elf_Sword. */ + +#if BACKTRACE_ELF_SIZE == 32 + +typedef uint32_t b_elf_addr; /* Elf_Addr. */ +typedef uint32_t b_elf_off; /* Elf_Off. */ + +typedef uint32_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */ + +#else + +typedef uint64_t b_elf_addr; /* Elf_Addr. */ +typedef uint64_t b_elf_off; /* Elf_Off. */ +typedef uint64_t b_elf_xword; /* Elf_Xword. */ +typedef int64_t b_elf_sxword; /* Elf_Sxword. */ + +typedef uint64_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */ + +#endif + +/* Data structures and associated constants. */ + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ + b_elf_half e_type; /* Identifies object file type */ + b_elf_half e_machine; /* Specifies required architecture */ + b_elf_word e_version; /* Identifies object file version */ + b_elf_addr e_entry; /* Entry point virtual address */ + b_elf_off e_phoff; /* Program header table file offset */ + b_elf_off e_shoff; /* Section header table file offset */ + b_elf_word e_flags; /* Processor-specific flags */ + b_elf_half e_ehsize; /* ELF header size in bytes */ + b_elf_half e_phentsize; /* Program header table entry size */ + b_elf_half e_phnum; /* Program header table entry count */ + b_elf_half e_shentsize; /* Section header table entry size */ + b_elf_half e_shnum; /* Section header table entry count */ + b_elf_half e_shstrndx; /* Section header string table index */ +} b_elf_ehdr; /* Elf_Ehdr. */ + +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_CURRENT 1 + +#define ET_DYN 3 + +#define EM_PPC64 21 +#define EF_PPC64_ABI 3 + +typedef struct { + b_elf_word sh_name; /* Section name, index in string tbl */ + b_elf_word sh_type; /* Type of section */ + b_elf_wxword sh_flags; /* Miscellaneous section attributes */ + b_elf_addr sh_addr; /* Section virtual addr at execution */ + b_elf_off sh_offset; /* Section file offset */ + b_elf_wxword sh_size; /* Size of section in bytes */ + b_elf_word sh_link; /* Index of another section */ + b_elf_word sh_info; /* Additional section information */ + b_elf_wxword sh_addralign; /* Section alignment */ + b_elf_wxword sh_entsize; /* Entry size if section holds table */ +} b_elf_shdr; /* Elf_Shdr. */ + +#define SHN_UNDEF 0x0000 /* Undefined section */ +#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ +#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ + +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_DYNSYM 11 + +#define SHF_COMPRESSED 0x800 + +#if BACKTRACE_ELF_SIZE == 32 + +typedef struct +{ + b_elf_word st_name; /* Symbol name, index in string tbl */ + b_elf_addr st_value; /* Symbol value */ + b_elf_word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol binding and type */ + unsigned char st_other; /* Visibility and other data */ + b_elf_half st_shndx; /* Symbol section index */ +} b_elf_sym; /* Elf_Sym. */ + +#else /* BACKTRACE_ELF_SIZE != 32 */ + +typedef struct +{ + b_elf_word st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Symbol binding and type */ + unsigned char st_other; /* Visibility and other data */ + b_elf_half st_shndx; /* Symbol section index */ + b_elf_addr st_value; /* Symbol value */ + b_elf_xword st_size; /* Symbol size */ +} b_elf_sym; /* Elf_Sym. */ + +#endif /* BACKTRACE_ELF_SIZE != 32 */ + +#define STT_OBJECT 1 +#define STT_FUNC 2 + +typedef struct +{ + uint32_t namesz; + uint32_t descsz; + uint32_t type; + char name[1]; +} b_elf_note; + +#define NT_GNU_BUILD_ID 3 + +#if BACKTRACE_ELF_SIZE == 32 + +typedef struct +{ + b_elf_word ch_type; /* Compresstion algorithm */ + b_elf_word ch_size; /* Uncompressed size */ + b_elf_word ch_addralign; /* Alignment for uncompressed data */ +} b_elf_chdr; /* Elf_Chdr */ + +#else /* BACKTRACE_ELF_SIZE != 32 */ + +typedef struct +{ + b_elf_word ch_type; /* Compression algorithm */ + b_elf_word ch_reserved; /* Reserved */ + b_elf_xword ch_size; /* Uncompressed size */ + b_elf_xword ch_addralign; /* Alignment for uncompressed data */ +} b_elf_chdr; /* Elf_Chdr */ + +#endif /* BACKTRACE_ELF_SIZE != 32 */ + +#define ELFCOMPRESS_ZLIB 1 +#define ELFCOMPRESS_ZSTD 2 + +/* Names of sections, indexed by enum dwarf_section in internal.h. */ + +static const char * const dwarf_section_names[DEBUG_MAX] = +{ + ".debug_info", + ".debug_line", + ".debug_abbrev", + ".debug_ranges", + ".debug_str", + ".debug_addr", + ".debug_str_offsets", + ".debug_line_str", + ".debug_rnglists" +}; + +/* Information we gather for the sections we care about. */ + +struct debug_section_info +{ + /* Section file offset. */ + off_t offset; + /* Section size. */ + size_t size; + /* Section contents, after read from file. */ + const unsigned char *data; + /* Whether the SHF_COMPRESSED flag is set for the section. */ + int compressed; +}; + +/* Information we keep for an ELF symbol. */ + +struct elf_symbol +{ + /* The name of the symbol. */ + const char *name; + /* The address of the symbol. */ + uintptr_t address; + /* The size of the symbol. */ + size_t size; +}; + +/* Information to pass to elf_syminfo. */ + +struct elf_syminfo_data +{ + /* Symbols for the next module. */ + struct elf_syminfo_data *next; + /* The ELF symbols, sorted by address. */ + struct elf_symbol *symbols; + /* The number of symbols. */ + size_t count; +}; + +/* A view that works for either a file or memory. */ + +struct elf_view +{ + struct backtrace_view view; + int release; /* If non-zero, must call backtrace_release_view. */ +}; + +/* Information about PowerPC64 ELFv1 .opd section. */ + +struct elf_ppc64_opd_data +{ + /* Address of the .opd section. */ + b_elf_addr addr; + /* Section data. */ + const char *data; + /* Size of the .opd section. */ + size_t size; + /* Corresponding section view. */ + struct elf_view view; +}; + +/* Create a view of SIZE bytes from DESCRIPTOR/MEMORY at OFFSET. */ + +static int +elf_get_view (struct backtrace_state *state, int descriptor, + const unsigned char *memory, size_t memory_size, off_t offset, + uint64_t size, backtrace_error_callback error_callback, + void *data, struct elf_view *view) +{ + if (memory == NULL) + { + view->release = 1; + return backtrace_get_view (state, descriptor, offset, size, + error_callback, data, &view->view); + } + else + { + if ((uint64_t) offset + size > (uint64_t) memory_size) + { + error_callback (data, "out of range for in-memory file", 0); + return 0; + } + view->view.data = (const void *) (memory + offset); + view->view.base = NULL; + view->view.len = size; + view->release = 0; + return 1; + } +} + +/* Release a view read by elf_get_view. */ + +static void +elf_release_view (struct backtrace_state *state, struct elf_view *view, + backtrace_error_callback error_callback, void *data) +{ + if (view->release) + backtrace_release_view (state, &view->view, error_callback, data); +} + +/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for + .gnu_debuglink files. */ + +static uint32_t +elf_crc32 (uint32_t crc, const unsigned char *buf, size_t len) +{ + static const uint32_t crc32_table[256] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + }; + const unsigned char *end; + + crc = ~crc; + for (end = buf + len; buf < end; ++ buf) + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); + return ~crc; +} + +/* Return the CRC-32 of the entire file open at DESCRIPTOR. */ + +static uint32_t +elf_crc32_file (struct backtrace_state *state, int descriptor, + backtrace_error_callback error_callback, void *data) +{ + struct stat st; + struct backtrace_view file_view; + uint32_t ret; + + if (fstat (descriptor, &st) < 0) + { + error_callback (data, "fstat", errno); + return 0; + } + + if (!backtrace_get_view (state, descriptor, 0, st.st_size, error_callback, + data, &file_view)) + return 0; + + ret = elf_crc32 (0, (const unsigned char *) file_view.data, st.st_size); + + backtrace_release_view (state, &file_view, error_callback, data); + + return ret; +} + +/* A dummy callback function used when we can't find a symbol + table. */ + +static void +elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED, + uintptr_t addr ATTRIBUTE_UNUSED, + backtrace_syminfo_callback callback ATTRIBUTE_UNUSED, + backtrace_error_callback error_callback, void *data) +{ + error_callback (data, "no symbol table in ELF executable", -1); +} + +/* A callback function used when we can't find any debug info. */ + +static int +elf_nodebug (struct backtrace_state *state, uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, void *data) +{ + if (state->syminfo_fn != NULL && state->syminfo_fn != elf_nosyms) + { + struct backtrace_call_full bdata; + + /* Fetch symbol information so that we can least get the + function name. */ + + bdata.full_callback = callback; + bdata.full_error_callback = error_callback; + bdata.full_data = data; + bdata.ret = 0; + state->syminfo_fn (state, pc, backtrace_syminfo_to_full_callback, + backtrace_syminfo_to_full_error_callback, &bdata); + return bdata.ret; + } + + error_callback (data, "no debug info in ELF executable", -1); + return 0; +} + +/* Compare struct elf_symbol for qsort. */ + +static int +elf_symbol_compare (const void *v1, const void *v2) +{ + const struct elf_symbol *e1 = (const struct elf_symbol *) v1; + const struct elf_symbol *e2 = (const struct elf_symbol *) v2; + + if (e1->address < e2->address) + return -1; + else if (e1->address > e2->address) + return 1; + else + return 0; +} + +/* Compare an ADDR against an elf_symbol for bsearch. We allocate one + extra entry in the array so that this can look safely at the next + entry. */ + +static int +elf_symbol_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct elf_symbol *entry = (const struct elf_symbol *) ventry; + uintptr_t addr; + + addr = *key; + if (addr < entry->address) + return -1; + else if (addr >= entry->address + entry->size) + return 1; + else + return 0; +} + +/* Initialize the symbol table info for elf_syminfo. */ + +static int +elf_initialize_syminfo (struct backtrace_state *state, + uintptr_t base_address, + const unsigned char *symtab_data, size_t symtab_size, + const unsigned char *strtab, size_t strtab_size, + backtrace_error_callback error_callback, + void *data, struct elf_syminfo_data *sdata, + struct elf_ppc64_opd_data *opd) +{ + size_t sym_count; + const b_elf_sym *sym; + size_t elf_symbol_count; + size_t elf_symbol_size; + struct elf_symbol *elf_symbols; + size_t i; + unsigned int j; + + sym_count = symtab_size / sizeof (b_elf_sym); + + /* We only care about function symbols. Count them. */ + sym = (const b_elf_sym *) symtab_data; + elf_symbol_count = 0; + for (i = 0; i < sym_count; ++i, ++sym) + { + int info; + + info = sym->st_info & 0xf; + if ((info == STT_FUNC || info == STT_OBJECT) + && sym->st_shndx != SHN_UNDEF) + ++elf_symbol_count; + } + + elf_symbol_size = elf_symbol_count * sizeof (struct elf_symbol); + elf_symbols = ((struct elf_symbol *) + backtrace_alloc (state, elf_symbol_size, error_callback, + data)); + if (elf_symbols == NULL) + return 0; + + sym = (const b_elf_sym *) symtab_data; + j = 0; + for (i = 0; i < sym_count; ++i, ++sym) + { + int info; + + info = sym->st_info & 0xf; + if (info != STT_FUNC && info != STT_OBJECT) + continue; + if (sym->st_shndx == SHN_UNDEF) + continue; + if (sym->st_name >= strtab_size) + { + error_callback (data, "symbol string index out of range", 0); + backtrace_free (state, elf_symbols, elf_symbol_size, error_callback, + data); + return 0; + } + elf_symbols[j].name = (const char *) strtab + sym->st_name; + /* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol + is a function descriptor, read the actual code address from the + descriptor. */ + if (opd + && sym->st_value >= opd->addr + && sym->st_value < opd->addr + opd->size) + elf_symbols[j].address + = *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr)); + else + elf_symbols[j].address = sym->st_value; + elf_symbols[j].address += base_address; + elf_symbols[j].size = sym->st_size; + ++j; + } + + backtrace_qsort (elf_symbols, elf_symbol_count, sizeof (struct elf_symbol), + elf_symbol_compare); + + sdata->next = NULL; + sdata->symbols = elf_symbols; + sdata->count = elf_symbol_count; + + return 1; +} + +/* Add EDATA to the list in STATE. */ + +static void +elf_add_syminfo_data (struct backtrace_state *state, + struct elf_syminfo_data *edata) +{ + if (!state->threaded) + { + struct elf_syminfo_data **pp; + + for (pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data; + *pp != NULL; + pp = &(*pp)->next) + ; + *pp = edata; + } + else + { + while (1) + { + struct elf_syminfo_data **pp; + + pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data; + + while (1) + { + struct elf_syminfo_data *p; + + p = backtrace_atomic_load_pointer (pp); + + if (p == NULL) + break; + + pp = &p->next; + } + + if (__sync_bool_compare_and_swap (pp, NULL, edata)) + break; + } + } +} + +/* Return the symbol name and value for an ADDR. */ + +static void +elf_syminfo (struct backtrace_state *state, uintptr_t addr, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback ATTRIBUTE_UNUSED, + void *data) +{ + struct elf_syminfo_data *edata; + struct elf_symbol *sym = NULL; + + if (!state->threaded) + { + for (edata = (struct elf_syminfo_data *) state->syminfo_data; + edata != NULL; + edata = edata->next) + { + sym = ((struct elf_symbol *) + bsearch (&addr, edata->symbols, edata->count, + sizeof (struct elf_symbol), elf_symbol_search)); + if (sym != NULL) + break; + } + } + else + { + struct elf_syminfo_data **pp; + + pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data; + while (1) + { + edata = backtrace_atomic_load_pointer (pp); + if (edata == NULL) + break; + + sym = ((struct elf_symbol *) + bsearch (&addr, edata->symbols, edata->count, + sizeof (struct elf_symbol), elf_symbol_search)); + if (sym != NULL) + break; + + pp = &edata->next; + } + } + + if (sym == NULL) + callback (data, addr, NULL, 0, 0); + else + callback (data, addr, sym->name, sym->address, sym->size); +} + +/* Return whether FILENAME is a symlink. */ + +static int +elf_is_symlink (const char *filename) +{ + struct stat st; + + if (lstat (filename, &st) < 0) + return 0; + return S_ISLNK (st.st_mode); +} + +/* Return the results of reading the symlink FILENAME in a buffer + allocated by backtrace_alloc. Return the length of the buffer in + *LEN. */ + +static char * +elf_readlink (struct backtrace_state *state, const char *filename, + backtrace_error_callback error_callback, void *data, + size_t *plen) +{ + size_t len; + char *buf; + + len = 128; + while (1) + { + ssize_t rl; + + buf = (char*)backtrace_alloc (state, len, error_callback, data); + if (buf == NULL) + return NULL; + rl = readlink (filename, buf, len); + if (rl < 0) + { + backtrace_free (state, buf, len, error_callback, data); + return NULL; + } + if ((size_t) rl < len - 1) + { + buf[rl] = '\0'; + *plen = len; + return buf; + } + backtrace_free (state, buf, len, error_callback, data); + len *= 2; + } +} + +#define SYSTEM_BUILD_ID_DIR "/usr/lib/debug/.build-id/" + +/* Open a separate debug info file, using the build ID to find it. + Returns an open file descriptor, or -1. + + The GDB manual says that the only place gdb looks for a debug file + when the build ID is known is in /usr/lib/debug/.build-id. */ + +static int +elf_open_debugfile_by_buildid (struct backtrace_state *state, + const char *buildid_data, size_t buildid_size, + const char *filename, + backtrace_error_callback error_callback, + void *data) +{ + const char * const prefix = SYSTEM_BUILD_ID_DIR; + const size_t prefix_len = strlen (prefix); + const char * const suffix = ".debug"; + const size_t suffix_len = strlen (suffix); + size_t len; + char *bd_filename; + char *t; + size_t i; + int ret; + int does_not_exist; + + len = prefix_len + buildid_size * 2 + suffix_len + 2; + bd_filename = (char*)backtrace_alloc (state, len, error_callback, data); + if (bd_filename == NULL) + return -1; + + t = bd_filename; + memcpy (t, prefix, prefix_len); + t += prefix_len; + for (i = 0; i < buildid_size; i++) + { + unsigned char b; + unsigned char nib; + + b = (unsigned char) buildid_data[i]; + nib = (b & 0xf0) >> 4; + *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10; + nib = b & 0x0f; + *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10; + if (i == 0) + *t++ = '/'; + } + memcpy (t, suffix, suffix_len); + t[suffix_len] = '\0'; + + ret = backtrace_open (bd_filename, error_callback, data, &does_not_exist); + + backtrace_free (state, bd_filename, len, error_callback, data); + + /* gdb checks that the debuginfo file has the same build ID note. + That seems kind of pointless to me--why would it have the right + name but not the right build ID?--so skipping the check. */ + +#ifdef TRACY_DEBUGINFOD + if (ret == -1) + return GetDebugInfoDescriptor( buildid_data, buildid_size, filename ); + else + return ret; +#else + return ret; +#endif +} + +/* Try to open a file whose name is PREFIX (length PREFIX_LEN) + concatenated with PREFIX2 (length PREFIX2_LEN) concatenated with + DEBUGLINK_NAME. Returns an open file descriptor, or -1. */ + +static int +elf_try_debugfile (struct backtrace_state *state, const char *prefix, + size_t prefix_len, const char *prefix2, size_t prefix2_len, + const char *debuglink_name, + backtrace_error_callback error_callback, void *data) +{ + size_t debuglink_len; + size_t try_len; + char *Try; + int does_not_exist; + int ret; + + debuglink_len = strlen (debuglink_name); + try_len = prefix_len + prefix2_len + debuglink_len + 1; + Try = (char*)backtrace_alloc (state, try_len, error_callback, data); + if (Try == NULL) + return -1; + + memcpy (Try, prefix, prefix_len); + memcpy (Try + prefix_len, prefix2, prefix2_len); + memcpy (Try + prefix_len + prefix2_len, debuglink_name, debuglink_len); + Try[prefix_len + prefix2_len + debuglink_len] = '\0'; + + ret = backtrace_open (Try, error_callback, data, &does_not_exist); + + backtrace_free (state, Try, try_len, error_callback, data); + + return ret; +} + +/* Find a separate debug info file, using the debuglink section data + to find it. Returns an open file descriptor, or -1. */ + +static int +elf_find_debugfile_by_debuglink (struct backtrace_state *state, + const char *filename, + const char *debuglink_name, + backtrace_error_callback error_callback, + void *data) +{ + int ret; + char *alc; + size_t alc_len; + const char *slash; + int ddescriptor; + const char *prefix; + size_t prefix_len; + + /* Resolve symlinks in FILENAME. Since FILENAME is fairly likely to + be /proc/self/exe, symlinks are common. We don't try to resolve + the whole path name, just the base name. */ + ret = -1; + alc = NULL; + alc_len = 0; + while (elf_is_symlink (filename)) + { + char *new_buf; + size_t new_len; + + new_buf = elf_readlink (state, filename, error_callback, data, &new_len); + if (new_buf == NULL) + break; + + if (new_buf[0] == '/') + filename = new_buf; + else + { + slash = strrchr (filename, '/'); + if (slash == NULL) + filename = new_buf; + else + { + size_t clen; + char *c; + + slash++; + clen = slash - filename + strlen (new_buf) + 1; + c = (char*)backtrace_alloc (state, clen, error_callback, data); + if (c == NULL) + goto done; + + memcpy (c, filename, slash - filename); + memcpy (c + (slash - filename), new_buf, strlen (new_buf)); + c[slash - filename + strlen (new_buf)] = '\0'; + backtrace_free (state, new_buf, new_len, error_callback, data); + filename = c; + new_buf = c; + new_len = clen; + } + } + + if (alc != NULL) + backtrace_free (state, alc, alc_len, error_callback, data); + alc = new_buf; + alc_len = new_len; + } + + /* Look for DEBUGLINK_NAME in the same directory as FILENAME. */ + + slash = strrchr (filename, '/'); + if (slash == NULL) + { + prefix = ""; + prefix_len = 0; + } + else + { + slash++; + prefix = filename; + prefix_len = slash - filename; + } + + ddescriptor = elf_try_debugfile (state, prefix, prefix_len, "", 0, + debuglink_name, error_callback, data); + if (ddescriptor >= 0) + { + ret = ddescriptor; + goto done; + } + + /* Look for DEBUGLINK_NAME in a .debug subdirectory of FILENAME. */ + + ddescriptor = elf_try_debugfile (state, prefix, prefix_len, ".debug/", + strlen (".debug/"), debuglink_name, + error_callback, data); + if (ddescriptor >= 0) + { + ret = ddescriptor; + goto done; + } + + /* Look for DEBUGLINK_NAME in /usr/lib/debug. */ + + ddescriptor = elf_try_debugfile (state, "/usr/lib/debug/", + strlen ("/usr/lib/debug/"), prefix, + prefix_len, debuglink_name, + error_callback, data); + if (ddescriptor >= 0) + ret = ddescriptor; + + done: + if (alc != NULL && alc_len > 0) + backtrace_free (state, alc, alc_len, error_callback, data); + return ret; +} + +/* Open a separate debug info file, using the debuglink section data + to find it. Returns an open file descriptor, or -1. */ + +static int +elf_open_debugfile_by_debuglink (struct backtrace_state *state, + const char *filename, + const char *debuglink_name, + uint32_t debuglink_crc, + backtrace_error_callback error_callback, + void *data) +{ + int ddescriptor; + + ddescriptor = elf_find_debugfile_by_debuglink (state, filename, + debuglink_name, + error_callback, data); + if (ddescriptor < 0) + return -1; + + if (debuglink_crc != 0) + { + uint32_t got_crc; + + got_crc = elf_crc32_file (state, ddescriptor, error_callback, data); + if (got_crc != debuglink_crc) + { + backtrace_close (ddescriptor, error_callback, data); + return -1; + } + } + + return ddescriptor; +} + +/* A function useful for setting a breakpoint for an inflation failure + when this code is compiled with -g. */ + +static void +elf_uncompress_failed(void) +{ +} + +/* *PVAL is the current value being read from the stream, and *PBITS + is the number of valid bits. Ensure that *PVAL holds at least 15 + bits by reading additional bits from *PPIN, up to PINEND, as + needed. Updates *PPIN, *PVAL and *PBITS. Returns 1 on success, 0 + on error. */ + +static int +elf_fetch_bits (const unsigned char **ppin, const unsigned char *pinend, + uint64_t *pval, unsigned int *pbits) +{ + unsigned int bits; + const unsigned char *pin; + uint64_t val; + uint32_t next; + + bits = *pbits; + if (bits >= 15) + return 1; + pin = *ppin; + val = *pval; + + if (unlikely (pinend - pin < 4)) + { + elf_uncompress_failed (); + return 0; + } + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \ + && defined(__ORDER_BIG_ENDIAN__) \ + && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \ + || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + /* We've ensured that PIN is aligned. */ + next = *(const uint32_t *)pin; + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + next = __builtin_bswap32 (next); +#endif +#else + next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24); +#endif + + val |= (uint64_t)next << bits; + bits += 32; + pin += 4; + + /* We will need the next four bytes soon. */ + __builtin_prefetch (pin, 0, 0); + + *ppin = pin; + *pval = val; + *pbits = bits; + return 1; +} + +/* This is like elf_fetch_bits, but it fetchs the bits backward, and ensures at + least 16 bits. This is for zstd. */ + +static int +elf_fetch_bits_backward (const unsigned char **ppin, + const unsigned char *pinend, + uint64_t *pval, unsigned int *pbits) +{ + unsigned int bits; + const unsigned char *pin; + uint64_t val; + uint32_t next; + + bits = *pbits; + if (bits >= 16) + return 1; + pin = *ppin; + val = *pval; + + if (unlikely (pin <= pinend)) + { + if (bits == 0) + { + elf_uncompress_failed (); + return 0; + } + return 1; + } + + pin -= 4; + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \ + && defined(__ORDER_BIG_ENDIAN__) \ + && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \ + || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + /* We've ensured that PIN is aligned. */ + next = *(const uint32_t *)pin; + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + next = __builtin_bswap32 (next); +#endif +#else + next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24); +#endif + + val <<= 32; + val |= next; + bits += 32; + + if (unlikely (pin < pinend)) + { + val >>= (pinend - pin) * 8; + bits -= (pinend - pin) * 8; + } + + *ppin = pin; + *pval = val; + *pbits = bits; + return 1; +} + +/* Initialize backward fetching when the bitstream starts with a 1 bit in the + last byte in memory (which is the first one that we read). This is used by + zstd decompression. Returns 1 on success, 0 on error. */ + +static int +elf_fetch_backward_init (const unsigned char **ppin, + const unsigned char *pinend, + uint64_t *pval, unsigned int *pbits) +{ + const unsigned char *pin; + unsigned int stream_start; + uint64_t val; + unsigned int bits; + + pin = *ppin; + stream_start = (unsigned int)*pin; + if (unlikely (stream_start == 0)) + { + elf_uncompress_failed (); + return 0; + } + val = 0; + bits = 0; + + /* Align to a 32-bit boundary. */ + while ((((uintptr_t)pin) & 3) != 0) + { + val <<= 8; + val |= (uint64_t)*pin; + bits += 8; + --pin; + } + + val <<= 8; + val |= (uint64_t)*pin; + bits += 8; + + *ppin = pin; + *pval = val; + *pbits = bits; + if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits)) + return 0; + + *pbits -= __builtin_clz (stream_start) - (sizeof (unsigned int) - 1) * 8 + 1; + + if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits)) + return 0; + + return 1; +} + +/* Huffman code tables, like the rest of the zlib format, are defined + by RFC 1951. We store a Huffman code table as a series of tables + stored sequentially in memory. Each entry in a table is 16 bits. + The first, main, table has 256 entries. It is followed by a set of + secondary tables of length 2 to 128 entries. The maximum length of + a code sequence in the deflate format is 15 bits, so that is all we + need. Each secondary table has an index, which is the offset of + the table in the overall memory storage. + + The deflate format says that all codes of a given bit length are + lexicographically consecutive. Perhaps we could have 130 values + that require a 15-bit code, perhaps requiring three secondary + tables of size 128. I don't know if this is actually possible, but + it suggests that the maximum size required for secondary tables is + 3 * 128 + 3 * 64 ... == 768. The zlib enough program reports 660 + as the maximum. We permit 768, since in addition to the 256 for + the primary table, with two bytes per entry, and with the two + tables we need, that gives us a page. + + A single table entry needs to store a value or (for the main table + only) the index and size of a secondary table. Values range from 0 + to 285, inclusive. Secondary table indexes, per above, range from + 0 to 510. For a value we need to store the number of bits we need + to determine that value (one value may appear multiple times in the + table), which is 1 to 8. For a secondary table we need to store + the number of bits used to index into the table, which is 1 to 7. + And of course we need 1 bit to decide whether we have a value or a + secondary table index. So each entry needs 9 bits for value/table + index, 3 bits for size, 1 bit what it is. For simplicity we use 16 + bits per entry. */ + +/* Number of entries we allocate to for one code table. We get a page + for the two code tables we need. */ + +#define ZLIB_HUFFMAN_TABLE_SIZE (1024) + +/* Bit masks and shifts for the values in the table. */ + +#define ZLIB_HUFFMAN_VALUE_MASK 0x01ff +#define ZLIB_HUFFMAN_BITS_SHIFT 9 +#define ZLIB_HUFFMAN_BITS_MASK 0x7 +#define ZLIB_HUFFMAN_SECONDARY_SHIFT 12 + +/* For working memory while inflating we need two code tables, we need + an array of code lengths (max value 15, so we use unsigned char), + and an array of unsigned shorts used while building a table. The + latter two arrays must be large enough to hold the maximum number + of code lengths, which RFC 1951 defines as 286 + 30. */ + +#define ZLIB_TABLE_SIZE \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ + + (286 + 30) * sizeof (uint16_t) \ + + (286 + 30) * sizeof (unsigned char)) + +#define ZLIB_TABLE_CODELEN_OFFSET \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ + + (286 + 30) * sizeof (uint16_t)) + +#define ZLIB_TABLE_WORK_OFFSET \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t)) + +#ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE + +/* Used by the main function that generates the fixed table to learn + the table size. */ +static size_t final_next_secondary; + +#endif + +/* Build a Huffman code table from an array of lengths in CODES of + length CODES_LEN. The table is stored into *TABLE. ZDEBUG_TABLE + is the same as for elf_zlib_inflate, used to find some work space. + Returns 1 on success, 0 on error. */ + +static int +elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, + uint16_t *zdebug_table, uint16_t *table) +{ + uint16_t count[16]; + uint16_t start[16]; + uint16_t prev[16]; + uint16_t firstcode[7]; + uint16_t *next; + size_t i; + size_t j; + unsigned int code; + size_t next_secondary; + + /* Count the number of code of each length. Set NEXT[val] to be the + next value after VAL with the same bit length. */ + + next = (uint16_t *) (((unsigned char *) zdebug_table) + + ZLIB_TABLE_WORK_OFFSET); + + memset (&count[0], 0, 16 * sizeof (uint16_t)); + for (i = 0; i < codes_len; ++i) + { + if (unlikely (codes[i] >= 16)) + { + elf_uncompress_failed (); + return 0; + } + + if (count[codes[i]] == 0) + { + start[codes[i]] = i; + prev[codes[i]] = i; + } + else + { + next[prev[codes[i]]] = i; + prev[codes[i]] = i; + } + + ++count[codes[i]]; + } + + /* For each length, fill in the table for the codes of that + length. */ + + memset (table, 0, ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t)); + + /* Handle the values that do not require a secondary table. */ + + code = 0; + for (j = 1; j <= 8; ++j) + { + unsigned int jcnt; + unsigned int val; + + jcnt = count[j]; + if (jcnt == 0) + continue; + + if (unlikely (jcnt > (1U << j))) + { + elf_uncompress_failed (); + return 0; + } + + /* There are JCNT values that have this length, the values + starting from START[j] continuing through NEXT[VAL]. Those + values are assigned consecutive values starting at CODE. */ + + val = start[j]; + for (i = 0; i < jcnt; ++i) + { + uint16_t tval; + size_t ind; + unsigned int incr; + + /* In the compressed bit stream, the value VAL is encoded as + J bits with the value C. */ + + if (unlikely ((val & ~ZLIB_HUFFMAN_VALUE_MASK) != 0)) + { + elf_uncompress_failed (); + return 0; + } + + tval = val | ((j - 1) << ZLIB_HUFFMAN_BITS_SHIFT); + + /* The table lookup uses 8 bits. If J is less than 8, we + don't know what the other bits will be. We need to fill + in all possibilities in the table. Since the Huffman + code is unambiguous, those entries can't be used for any + other code. */ + + for (ind = code; ind < 0x100; ind += 1 << j) + { + if (unlikely (table[ind] != 0)) + { + elf_uncompress_failed (); + return 0; + } + table[ind] = tval; + } + + /* Advance to the next value with this length. */ + if (i + 1 < jcnt) + val = next[val]; + + /* The Huffman codes are stored in the bitstream with the + most significant bit first, as is required to make them + unambiguous. The effect is that when we read them from + the bitstream we see the bit sequence in reverse order: + the most significant bit of the Huffman code is the least + significant bit of the value we read from the bitstream. + That means that to make our table lookups work, we need + to reverse the bits of CODE. Since reversing bits is + tedious and in general requires using a table, we instead + increment CODE in reverse order. That is, if the number + of bits we are currently using, here named J, is 3, we + count as 000, 100, 010, 110, 001, 101, 011, 111, which is + to say the numbers from 0 to 7 but with the bits + reversed. Going to more bits, aka incrementing J, + effectively just adds more zero bits as the beginning, + and as such does not change the numeric value of CODE. + + To increment CODE of length J in reverse order, find the + most significant zero bit and set it to one while + clearing all higher bits. In other words, add 1 modulo + 2^J, only reversed. */ + + incr = 1U << (j - 1); + while ((code & incr) != 0) + incr >>= 1; + if (incr == 0) + code = 0; + else + { + code &= incr - 1; + code += incr; + } + } + } + + /* Handle the values that require a secondary table. */ + + /* Set FIRSTCODE, the number at which the codes start, for each + length. */ + + for (j = 9; j < 16; j++) + { + unsigned int jcnt; + unsigned int k; + + jcnt = count[j]; + if (jcnt == 0) + continue; + + /* There are JCNT values that have this length, the values + starting from START[j]. Those values are assigned + consecutive values starting at CODE. */ + + firstcode[j - 9] = code; + + /* Reverse add JCNT to CODE modulo 2^J. */ + for (k = 0; k < j; ++k) + { + if ((jcnt & (1U << k)) != 0) + { + unsigned int m; + unsigned int bit; + + bit = 1U << (j - k - 1); + for (m = 0; m < j - k; ++m, bit >>= 1) + { + if ((code & bit) == 0) + { + code += bit; + break; + } + code &= ~bit; + } + jcnt &= ~(1U << k); + } + } + if (unlikely (jcnt != 0)) + { + elf_uncompress_failed (); + return 0; + } + } + + /* For J from 9 to 15, inclusive, we store COUNT[J] consecutive + values starting at START[J] with consecutive codes starting at + FIRSTCODE[J - 9]. In the primary table we need to point to the + secondary table, and the secondary table will be indexed by J - 9 + bits. We count down from 15 so that we install the larger + secondary tables first, as the smaller ones may be embedded in + the larger ones. */ + + next_secondary = 0; /* Index of next secondary table (after primary). */ + for (j = 15; j >= 9; j--) + { + unsigned int jcnt; + unsigned int val; + size_t primary; /* Current primary index. */ + size_t secondary; /* Offset to current secondary table. */ + size_t secondary_bits; /* Bit size of current secondary table. */ + + jcnt = count[j]; + if (jcnt == 0) + continue; + + val = start[j]; + code = firstcode[j - 9]; + primary = 0x100; + secondary = 0; + secondary_bits = 0; + for (i = 0; i < jcnt; ++i) + { + uint16_t tval; + size_t ind; + unsigned int incr; + + if ((code & 0xff) != primary) + { + uint16_t tprimary; + + /* Fill in a new primary table entry. */ + + primary = code & 0xff; + + tprimary = table[primary]; + if (tprimary == 0) + { + /* Start a new secondary table. */ + + if (unlikely ((next_secondary & ZLIB_HUFFMAN_VALUE_MASK) + != next_secondary)) + { + elf_uncompress_failed (); + return 0; + } + + secondary = next_secondary; + secondary_bits = j - 8; + next_secondary += 1 << secondary_bits; + table[primary] = (secondary + + ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT) + + (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)); + } + else + { + /* There is an existing entry. It had better be a + secondary table with enough bits. */ + if (unlikely ((tprimary + & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) + == 0)) + { + elf_uncompress_failed (); + return 0; + } + secondary = tprimary & ZLIB_HUFFMAN_VALUE_MASK; + secondary_bits = ((tprimary >> ZLIB_HUFFMAN_BITS_SHIFT) + & ZLIB_HUFFMAN_BITS_MASK); + if (unlikely (secondary_bits < j - 8)) + { + elf_uncompress_failed (); + return 0; + } + } + } + + /* Fill in secondary table entries. */ + + tval = val | ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT); + + for (ind = code >> 8; + ind < (1U << secondary_bits); + ind += 1U << (j - 8)) + { + if (unlikely (table[secondary + 0x100 + ind] != 0)) + { + elf_uncompress_failed (); + return 0; + } + table[secondary + 0x100 + ind] = tval; + } + + if (i + 1 < jcnt) + val = next[val]; + + incr = 1U << (j - 1); + while ((code & incr) != 0) + incr >>= 1; + if (incr == 0) + code = 0; + else + { + code &= incr - 1; + code += incr; + } + } + } + +#ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE + final_next_secondary = next_secondary; +#endif + + return 1; +} + +#ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE + +/* Used to generate the fixed Huffman table for block type 1. */ + +#include + +static uint16_t table[ZLIB_TABLE_SIZE]; +static unsigned char codes[288]; + +int +main () +{ + size_t i; + + for (i = 0; i <= 143; ++i) + codes[i] = 8; + for (i = 144; i <= 255; ++i) + codes[i] = 9; + for (i = 256; i <= 279; ++i) + codes[i] = 7; + for (i = 280; i <= 287; ++i) + codes[i] = 8; + if (!elf_zlib_inflate_table (&codes[0], 288, &table[0], &table[0])) + { + fprintf (stderr, "elf_zlib_inflate_table failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const uint16_t elf_zlib_default_table[%#zx] =\n", + final_next_secondary + 0x100); + printf ("{\n"); + for (i = 0; i < final_next_secondary + 0x100; i += 8) + { + size_t j; + + printf (" "); + for (j = i; j < final_next_secondary + 0x100 && j < i + 8; ++j) + printf (" %#x,", table[j]); + printf ("\n"); + } + printf ("};\n"); + printf ("\n"); + + for (i = 0; i < 32; ++i) + codes[i] = 5; + if (!elf_zlib_inflate_table (&codes[0], 32, &table[0], &table[0])) + { + fprintf (stderr, "elf_zlib_inflate_table failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const uint16_t elf_zlib_default_dist_table[%#zx] =\n", + final_next_secondary + 0x100); + printf ("{\n"); + for (i = 0; i < final_next_secondary + 0x100; i += 8) + { + size_t j; + + printf (" "); + for (j = i; j < final_next_secondary + 0x100 && j < i + 8; ++j) + printf (" %#x,", table[j]); + printf ("\n"); + } + printf ("};\n"); + + return 0; +} + +#endif + +/* The fixed tables generated by the #ifdef'ed out main function + above. */ + +static const uint16_t elf_zlib_default_table[0x170] = +{ + 0xd00, 0xe50, 0xe10, 0xf18, 0xd10, 0xe70, 0xe30, 0x1230, + 0xd08, 0xe60, 0xe20, 0x1210, 0xe00, 0xe80, 0xe40, 0x1250, + 0xd04, 0xe58, 0xe18, 0x1200, 0xd14, 0xe78, 0xe38, 0x1240, + 0xd0c, 0xe68, 0xe28, 0x1220, 0xe08, 0xe88, 0xe48, 0x1260, + 0xd02, 0xe54, 0xe14, 0xf1c, 0xd12, 0xe74, 0xe34, 0x1238, + 0xd0a, 0xe64, 0xe24, 0x1218, 0xe04, 0xe84, 0xe44, 0x1258, + 0xd06, 0xe5c, 0xe1c, 0x1208, 0xd16, 0xe7c, 0xe3c, 0x1248, + 0xd0e, 0xe6c, 0xe2c, 0x1228, 0xe0c, 0xe8c, 0xe4c, 0x1268, + 0xd01, 0xe52, 0xe12, 0xf1a, 0xd11, 0xe72, 0xe32, 0x1234, + 0xd09, 0xe62, 0xe22, 0x1214, 0xe02, 0xe82, 0xe42, 0x1254, + 0xd05, 0xe5a, 0xe1a, 0x1204, 0xd15, 0xe7a, 0xe3a, 0x1244, + 0xd0d, 0xe6a, 0xe2a, 0x1224, 0xe0a, 0xe8a, 0xe4a, 0x1264, + 0xd03, 0xe56, 0xe16, 0xf1e, 0xd13, 0xe76, 0xe36, 0x123c, + 0xd0b, 0xe66, 0xe26, 0x121c, 0xe06, 0xe86, 0xe46, 0x125c, + 0xd07, 0xe5e, 0xe1e, 0x120c, 0xd17, 0xe7e, 0xe3e, 0x124c, + 0xd0f, 0xe6e, 0xe2e, 0x122c, 0xe0e, 0xe8e, 0xe4e, 0x126c, + 0xd00, 0xe51, 0xe11, 0xf19, 0xd10, 0xe71, 0xe31, 0x1232, + 0xd08, 0xe61, 0xe21, 0x1212, 0xe01, 0xe81, 0xe41, 0x1252, + 0xd04, 0xe59, 0xe19, 0x1202, 0xd14, 0xe79, 0xe39, 0x1242, + 0xd0c, 0xe69, 0xe29, 0x1222, 0xe09, 0xe89, 0xe49, 0x1262, + 0xd02, 0xe55, 0xe15, 0xf1d, 0xd12, 0xe75, 0xe35, 0x123a, + 0xd0a, 0xe65, 0xe25, 0x121a, 0xe05, 0xe85, 0xe45, 0x125a, + 0xd06, 0xe5d, 0xe1d, 0x120a, 0xd16, 0xe7d, 0xe3d, 0x124a, + 0xd0e, 0xe6d, 0xe2d, 0x122a, 0xe0d, 0xe8d, 0xe4d, 0x126a, + 0xd01, 0xe53, 0xe13, 0xf1b, 0xd11, 0xe73, 0xe33, 0x1236, + 0xd09, 0xe63, 0xe23, 0x1216, 0xe03, 0xe83, 0xe43, 0x1256, + 0xd05, 0xe5b, 0xe1b, 0x1206, 0xd15, 0xe7b, 0xe3b, 0x1246, + 0xd0d, 0xe6b, 0xe2b, 0x1226, 0xe0b, 0xe8b, 0xe4b, 0x1266, + 0xd03, 0xe57, 0xe17, 0xf1f, 0xd13, 0xe77, 0xe37, 0x123e, + 0xd0b, 0xe67, 0xe27, 0x121e, 0xe07, 0xe87, 0xe47, 0x125e, + 0xd07, 0xe5f, 0xe1f, 0x120e, 0xd17, 0xe7f, 0xe3f, 0x124e, + 0xd0f, 0xe6f, 0xe2f, 0x122e, 0xe0f, 0xe8f, 0xe4f, 0x126e, + 0x290, 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, + 0x298, 0x299, 0x29a, 0x29b, 0x29c, 0x29d, 0x29e, 0x29f, + 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a6, 0x2a7, + 0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ac, 0x2ad, 0x2ae, 0x2af, + 0x2b0, 0x2b1, 0x2b2, 0x2b3, 0x2b4, 0x2b5, 0x2b6, 0x2b7, + 0x2b8, 0x2b9, 0x2ba, 0x2bb, 0x2bc, 0x2bd, 0x2be, 0x2bf, + 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c5, 0x2c6, 0x2c7, + 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc, 0x2cd, 0x2ce, 0x2cf, + 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d7, + 0x2d8, 0x2d9, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2de, 0x2df, + 0x2e0, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, + 0x2e8, 0x2e9, 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef, + 0x2f0, 0x2f1, 0x2f2, 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, + 0x2f8, 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fe, 0x2ff, +}; + +static const uint16_t elf_zlib_default_dist_table[0x100] = +{ + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, + 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, + 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, + 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, + 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, +}; + +/* Inflate a zlib stream from PIN/SIN to POUT/SOUT. Return 1 on + success, 0 on some error parsing the stream. */ + +static int +elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, + unsigned char *pout, size_t sout) +{ + unsigned char *porigout; + const unsigned char *pinend; + unsigned char *poutend; + + /* We can apparently see multiple zlib streams concatenated + together, so keep going as long as there is something to read. + The last 4 bytes are the checksum. */ + porigout = pout; + pinend = pin + sin; + poutend = pout + sout; + while ((pinend - pin) > 4) + { + uint64_t val; + unsigned int bits; + int last; + + /* Read the two byte zlib header. */ + + if (unlikely ((pin[0] & 0xf) != 8)) /* 8 is zlib encoding. */ + { + /* Unknown compression method. */ + elf_uncompress_failed (); + return 0; + } + if (unlikely ((pin[0] >> 4) > 7)) + { + /* Window size too large. Other than this check, we don't + care about the window size. */ + elf_uncompress_failed (); + return 0; + } + if (unlikely ((pin[1] & 0x20) != 0)) + { + /* Stream expects a predefined dictionary, but we have no + dictionary. */ + elf_uncompress_failed (); + return 0; + } + val = (pin[0] << 8) | pin[1]; + if (unlikely (val % 31 != 0)) + { + /* Header check failure. */ + elf_uncompress_failed (); + return 0; + } + pin += 2; + + /* Align PIN to a 32-bit boundary. */ + + val = 0; + bits = 0; + while ((((uintptr_t) pin) & 3) != 0) + { + val |= (uint64_t)*pin << bits; + bits += 8; + ++pin; + } + + /* Read blocks until one is marked last. */ + + last = 0; + + while (!last) + { + unsigned int type; + const uint16_t *tlit; + const uint16_t *tdist; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + last = val & 1; + type = (val >> 1) & 3; + val >>= 3; + bits -= 3; + + if (unlikely (type == 3)) + { + /* Invalid block type. */ + elf_uncompress_failed (); + return 0; + } + + if (type == 0) + { + uint16_t len; + uint16_t lenc; + + /* An uncompressed block. */ + + /* If we've read ahead more than a byte, back up. */ + while (bits >= 8) + { + --pin; + bits -= 8; + } + + val = 0; + bits = 0; + if (unlikely ((pinend - pin) < 4)) + { + /* Missing length. */ + elf_uncompress_failed (); + return 0; + } + len = pin[0] | (pin[1] << 8); + lenc = pin[2] | (pin[3] << 8); + pin += 4; + lenc = ~lenc; + if (unlikely (len != lenc)) + { + /* Corrupt data. */ + elf_uncompress_failed (); + return 0; + } + if (unlikely (len > (unsigned int) (pinend - pin) + || len > (unsigned int) (poutend - pout))) + { + /* Not enough space in buffers. */ + elf_uncompress_failed (); + return 0; + } + memcpy (pout, pin, len); + pout += len; + pin += len; + + /* Align PIN. */ + while ((((uintptr_t) pin) & 3) != 0) + { + val |= (uint64_t)*pin << bits; + bits += 8; + ++pin; + } + + /* Go around to read the next block. */ + continue; + } + + if (type == 1) + { + tlit = elf_zlib_default_table; + tdist = elf_zlib_default_dist_table; + } + else + { + unsigned int nlit; + unsigned int ndist; + unsigned int nclen; + unsigned char codebits[19]; + unsigned char *plenbase; + unsigned char *plen; + unsigned char *plenend; + + /* Read a Huffman encoding table. The various magic + numbers here are from RFC 1951. */ + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + nlit = (val & 0x1f) + 257; + val >>= 5; + ndist = (val & 0x1f) + 1; + val >>= 5; + nclen = (val & 0xf) + 4; + val >>= 4; + bits -= 14; + if (unlikely (nlit > 286 || ndist > 30)) + { + /* Values out of range. */ + elf_uncompress_failed (); + return 0; + } + + /* Read and build the table used to compress the + literal, length, and distance codes. */ + + memset(&codebits[0], 0, 19); + + /* There are always at least 4 elements in the + table. */ + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + codebits[16] = val & 7; + codebits[17] = (val >> 3) & 7; + codebits[18] = (val >> 6) & 7; + codebits[0] = (val >> 9) & 7; + val >>= 12; + bits -= 12; + + if (nclen == 4) + goto codebitsdone; + + codebits[8] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 5) + goto codebitsdone; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + codebits[7] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 6) + goto codebitsdone; + + codebits[9] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 7) + goto codebitsdone; + + codebits[6] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 8) + goto codebitsdone; + + codebits[10] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 9) + goto codebitsdone; + + codebits[5] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 10) + goto codebitsdone; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + codebits[11] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 11) + goto codebitsdone; + + codebits[4] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 12) + goto codebitsdone; + + codebits[12] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 13) + goto codebitsdone; + + codebits[3] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 14) + goto codebitsdone; + + codebits[13] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 15) + goto codebitsdone; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + codebits[2] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 16) + goto codebitsdone; + + codebits[14] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 17) + goto codebitsdone; + + codebits[1] = val & 7; + val >>= 3; + bits -= 3; + + if (nclen == 18) + goto codebitsdone; + + codebits[15] = val & 7; + val >>= 3; + bits -= 3; + + codebitsdone: + + if (!elf_zlib_inflate_table (codebits, 19, zdebug_table, + zdebug_table)) + return 0; + + /* Read the compressed bit lengths of the literal, + length, and distance codes. We have allocated space + at the end of zdebug_table to hold them. */ + + plenbase = (((unsigned char *) zdebug_table) + + ZLIB_TABLE_CODELEN_OFFSET); + plen = plenbase; + plenend = plen + nlit + ndist; + while (plen < plenend) + { + uint16_t t; + unsigned int b; + uint16_t v; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + t = zdebug_table[val & 0xff]; + + /* The compression here uses bit lengths up to 7, so + a secondary table is never necessary. */ + if (unlikely ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) + != 0)) + { + elf_uncompress_failed (); + return 0; + } + + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + val >>= b + 1; + bits -= b + 1; + + v = t & ZLIB_HUFFMAN_VALUE_MASK; + if (v < 16) + *plen++ = v; + else if (v == 16) + { + unsigned int c; + unsigned int prev; + + /* Copy previous entry 3 to 6 times. */ + + if (unlikely (plen == plenbase)) + { + elf_uncompress_failed (); + return 0; + } + + /* We used up to 7 bits since the last + elf_fetch_bits, so we have at least 8 bits + available here. */ + + c = 3 + (val & 0x3); + val >>= 2; + bits -= 2; + if (unlikely ((unsigned int) (plenend - plen) < c)) + { + elf_uncompress_failed (); + return 0; + } + + prev = plen[-1]; + switch (c) + { + case 6: + *plen++ = prev; + ATTRIBUTE_FALLTHROUGH; + case 5: + *plen++ = prev; + ATTRIBUTE_FALLTHROUGH; + case 4: + *plen++ = prev; + } + *plen++ = prev; + *plen++ = prev; + *plen++ = prev; + } + else if (v == 17) + { + unsigned int c; + + /* Store zero 3 to 10 times. */ + + /* We used up to 7 bits since the last + elf_fetch_bits, so we have at least 8 bits + available here. */ + + c = 3 + (val & 0x7); + val >>= 3; + bits -= 3; + if (unlikely ((unsigned int) (plenend - plen) < c)) + { + elf_uncompress_failed (); + return 0; + } + + switch (c) + { + case 10: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 9: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 8: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 7: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 6: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 5: + *plen++ = 0; + ATTRIBUTE_FALLTHROUGH; + case 4: + *plen++ = 0; + } + *plen++ = 0; + *plen++ = 0; + *plen++ = 0; + } + else if (v == 18) + { + unsigned int c; + + /* Store zero 11 to 138 times. */ + + /* We used up to 7 bits since the last + elf_fetch_bits, so we have at least 8 bits + available here. */ + + c = 11 + (val & 0x7f); + val >>= 7; + bits -= 7; + if (unlikely ((unsigned int) (plenend - plen) < c)) + { + elf_uncompress_failed (); + return 0; + } + + memset (plen, 0, c); + plen += c; + } + else + { + elf_uncompress_failed (); + return 0; + } + } + + /* Make sure that the stop code can appear. */ + + plen = plenbase; + if (unlikely (plen[256] == 0)) + { + elf_uncompress_failed (); + return 0; + } + + /* Build the decompression tables. */ + + if (!elf_zlib_inflate_table (plen, nlit, zdebug_table, + zdebug_table)) + return 0; + if (!elf_zlib_inflate_table (plen + nlit, ndist, zdebug_table, + (zdebug_table + + ZLIB_HUFFMAN_TABLE_SIZE))) + return 0; + tlit = zdebug_table; + tdist = zdebug_table + ZLIB_HUFFMAN_TABLE_SIZE; + } + + /* Inflate values until the end of the block. This is the + main loop of the inflation code. */ + + while (1) + { + uint16_t t; + unsigned int b; + uint16_t v; + unsigned int lit; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + t = tlit[val & 0xff]; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + v = t & ZLIB_HUFFMAN_VALUE_MASK; + + if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0) + { + lit = v; + val >>= b + 1; + bits -= b + 1; + } + else + { + t = tlit[v + 0x100 + ((val >> 8) & ((1U << b) - 1))]; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + lit = t & ZLIB_HUFFMAN_VALUE_MASK; + val >>= b + 8; + bits -= b + 8; + } + + if (lit < 256) + { + if (unlikely (pout == poutend)) + { + elf_uncompress_failed (); + return 0; + } + + *pout++ = lit; + + /* We will need to write the next byte soon. We ask + for high temporal locality because we will write + to the whole cache line soon. */ + __builtin_prefetch (pout, 1, 3); + } + else if (lit == 256) + { + /* The end of the block. */ + break; + } + else + { + unsigned int dist; + unsigned int len; + + /* Convert lit into a length. */ + + if (lit < 265) + len = lit - 257 + 3; + else if (lit == 285) + len = 258; + else if (unlikely (lit > 285)) + { + elf_uncompress_failed (); + return 0; + } + else + { + unsigned int extra; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + /* This is an expression for the table of length + codes in RFC 1951 3.2.5. */ + lit -= 265; + extra = (lit >> 2) + 1; + len = (lit & 3) << extra; + len += 11; + len += ((1U << (extra - 1)) - 1) << 3; + len += val & ((1U << extra) - 1); + val >>= extra; + bits -= extra; + } + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + t = tdist[val & 0xff]; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + v = t & ZLIB_HUFFMAN_VALUE_MASK; + + if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0) + { + dist = v; + val >>= b + 1; + bits -= b + 1; + } + else + { + t = tdist[v + 0x100 + ((val >> 8) & ((1U << b) - 1))]; + b = ((t >> ZLIB_HUFFMAN_BITS_SHIFT) + & ZLIB_HUFFMAN_BITS_MASK); + dist = t & ZLIB_HUFFMAN_VALUE_MASK; + val >>= b + 8; + bits -= b + 8; + } + + /* Convert dist to a distance. */ + + if (dist == 0) + { + /* A distance of 1. A common case, meaning + repeat the last character LEN times. */ + + if (unlikely (pout == porigout)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((unsigned int) (poutend - pout) < len)) + { + elf_uncompress_failed (); + return 0; + } + + memset (pout, pout[-1], len); + pout += len; + } + else if (unlikely (dist > 29)) + { + elf_uncompress_failed (); + return 0; + } + else + { + if (dist < 4) + dist = dist + 1; + else + { + unsigned int extra; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + /* This is an expression for the table of + distance codes in RFC 1951 3.2.5. */ + dist -= 4; + extra = (dist >> 1) + 1; + dist = (dist & 1) << extra; + dist += 5; + dist += ((1U << (extra - 1)) - 1) << 2; + dist += val & ((1U << extra) - 1); + val >>= extra; + bits -= extra; + } + + /* Go back dist bytes, and copy len bytes from + there. */ + + if (unlikely ((unsigned int) (pout - porigout) < dist)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((unsigned int) (poutend - pout) < len)) + { + elf_uncompress_failed (); + return 0; + } + + if (dist >= len) + { + memcpy (pout, pout - dist, len); + pout += len; + } + else + { + while (len > 0) + { + unsigned int copy; + + copy = len < dist ? len : dist; + memcpy (pout, pout - dist, copy); + len -= copy; + pout += copy; + } + } + } + } + } + } + } + + /* We should have filled the output buffer. */ + if (unlikely (pout != poutend)) + { + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +/* Verify the zlib checksum. The checksum is in the 4 bytes at + CHECKBYTES, and the uncompressed data is at UNCOMPRESSED / + UNCOMPRESSED_SIZE. Returns 1 on success, 0 on failure. */ + +static int +elf_zlib_verify_checksum (const unsigned char *checkbytes, + const unsigned char *uncompressed, + size_t uncompressed_size) +{ + unsigned int i; + unsigned int cksum; + const unsigned char *p; + uint32_t s1; + uint32_t s2; + size_t hsz; + + cksum = 0; + for (i = 0; i < 4; i++) + cksum = (cksum << 8) | checkbytes[i]; + + s1 = 1; + s2 = 0; + + /* Minimize modulo operations. */ + + p = uncompressed; + hsz = uncompressed_size; + while (hsz >= 5552) + { + for (i = 0; i < 5552; i += 16) + { + /* Manually unroll loop 16 times. */ + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + } + hsz -= 5552; + s1 %= 65521; + s2 %= 65521; + } + + while (hsz >= 16) + { + /* Manually unroll loop 16 times. */ + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + s1 = s1 + *p++; + s2 = s2 + s1; + + hsz -= 16; + } + + for (i = 0; i < hsz; ++i) + { + s1 = s1 + *p++; + s2 = s2 + s1; + } + + s1 %= 65521; + s2 %= 65521; + + if (unlikely ((s2 << 16) + s1 != cksum)) + { + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +/* Inflate a zlib stream from PIN/SIN to POUT/SOUT, and verify the + checksum. Return 1 on success, 0 on error. */ + +static int +elf_zlib_inflate_and_verify (const unsigned char *pin, size_t sin, + uint16_t *zdebug_table, unsigned char *pout, + size_t sout) +{ + if (!elf_zlib_inflate (pin, sin, zdebug_table, pout, sout)) + return 0; + if (!elf_zlib_verify_checksum (pin + sin - 4, pout, sout)) + return 0; + return 1; +} + +/* For working memory during zstd compression, we need + - a literal length FSE table: 512 64-bit values == 4096 bytes + - a match length FSE table: 512 64-bit values == 4096 bytes + - a offset FSE table: 256 64-bit values == 2048 bytes + - a Huffman tree: 2048 uint16_t values == 4096 bytes + - scratch space, one of + - to build an FSE table: 512 uint16_t values == 1024 bytes + - to build a Huffman tree: 512 uint16_t + 256 uint32_t == 2048 bytes +*/ + +#define ZSTD_TABLE_SIZE \ + (2 * 512 * sizeof (struct elf_zstd_fse_baseline_entry) \ + + 256 * sizeof (struct elf_zstd_fse_baseline_entry) \ + + 2048 * sizeof (uint16_t) \ + + 512 * sizeof (uint16_t) + 256 * sizeof (uint32_t)) + +#define ZSTD_TABLE_LITERAL_FSE_OFFSET (0) + +#define ZSTD_TABLE_MATCH_FSE_OFFSET \ + (512 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_OFFSET_FSE_OFFSET \ + (ZSTD_TABLE_MATCH_FSE_OFFSET \ + + 512 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_HUFFMAN_OFFSET \ + (ZSTD_TABLE_OFFSET_FSE_OFFSET \ + + 256 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_WORK_OFFSET \ + (ZSTD_TABLE_HUFFMAN_OFFSET + 2048 * sizeof (uint16_t)) + +/* An entry in a zstd FSE table. */ + +struct elf_zstd_fse_entry +{ + /* The value that this FSE entry represents. */ + unsigned char symbol; + /* The number of bits to read to determine the next state. */ + unsigned char bits; + /* Add the bits to this base to get the next state. */ + uint16_t base; +}; + +static int +elf_zstd_build_fse (const int16_t *, int, uint16_t *, int, + struct elf_zstd_fse_entry *); + +/* Read a zstd FSE table and build the decoding table in *TABLE, updating *PPIN + as it reads. ZDEBUG_TABLE is scratch space; it must be enough for 512 + uint16_t values (1024 bytes). MAXIDX is the maximum number of symbols + permitted. *TABLE_BITS is the maximum number of bits for symbols in the + table: the size of *TABLE is at least 1 << *TABLE_BITS. This updates + *TABLE_BITS to the actual number of bits. Returns 1 on success, 0 on + error. */ + +static int +elf_zstd_read_fse (const unsigned char **ppin, const unsigned char *pinend, + uint16_t *zdebug_table, int maxidx, + struct elf_zstd_fse_entry *table, int *table_bits) +{ + const unsigned char *pin; + int16_t *norm; + uint16_t *next; + uint64_t val; + unsigned int bits; + int accuracy_log; + uint32_t remaining; + uint32_t threshold; + int bits_needed; + int idx; + int prev0; + + pin = *ppin; + + norm = (int16_t *) zdebug_table; + next = zdebug_table + 256; + + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* Align PIN to a 32-bit boundary. */ + + val = 0; + bits = 0; + while ((((uintptr_t) pin) & 3) != 0) + { + val |= (uint64_t)*pin << bits; + bits += 8; + ++pin; + } + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + accuracy_log = (val & 0xf) + 5; + if (accuracy_log > *table_bits) + { + elf_uncompress_failed (); + return 0; + } + *table_bits = accuracy_log; + val >>= 4; + bits -= 4; + + /* This code is mostly copied from the reference implementation. */ + + /* The number of remaining probabilities, plus 1. This sets the number of + bits that need to be read for the next value. */ + remaining = (1 << accuracy_log) + 1; + + /* The current difference between small and large values, which depends on + the number of remaining values. Small values use one less bit. */ + threshold = 1 << accuracy_log; + + /* The number of bits used to compute threshold. */ + bits_needed = accuracy_log + 1; + + /* The next character value. */ + idx = 0; + + /* Whether the last count was 0. */ + prev0 = 0; + + while (remaining > 1 && idx <= maxidx) + { + uint32_t max; + int32_t count; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + if (prev0) + { + int zidx; + + /* Previous count was 0, so there is a 2-bit repeat flag. If the + 2-bit flag is 0b11, it adds 3 and then there is another repeat + flag. */ + zidx = idx; + while ((val & 0xfff) == 0xfff) + { + zidx += 3 * 6; + val >>= 12; + bits -= 12; + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + } + while ((val & 3) == 3) + { + zidx += 3; + val >>= 2; + bits -= 2; + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + } + /* We have at least 13 bits here, don't need to fetch. */ + zidx += val & 3; + val >>= 2; + bits -= 2; + + if (unlikely (zidx > maxidx)) + { + elf_uncompress_failed (); + return 0; + } + + for (; idx < zidx; idx++) + norm[idx] = 0; + + prev0 = 0; + continue; + } + + max = (2 * threshold - 1) - remaining; + if ((val & (threshold - 1)) < max) + { + /* A small value. */ + count = (int32_t) ((uint32_t) val & (threshold - 1)); + val >>= bits_needed - 1; + bits -= bits_needed - 1; + } + else + { + /* A large value. */ + count = (int32_t) ((uint32_t) val & (2 * threshold - 1)); + if (count >= (int32_t) threshold) + count -= (int32_t) max; + val >>= bits_needed; + bits -= bits_needed; + } + + count--; + if (count >= 0) + remaining -= count; + else + remaining--; + if (unlikely (idx >= 256)) + { + elf_uncompress_failed (); + return 0; + } + norm[idx] = (int16_t) count; + ++idx; + + prev0 = count == 0; + + while (remaining < threshold) + { + bits_needed--; + threshold >>= 1; + } + } + + if (unlikely (remaining != 1)) + { + elf_uncompress_failed (); + return 0; + } + + /* If we've read ahead more than a byte, back up. */ + while (bits >= 8) + { + --pin; + bits -= 8; + } + + *ppin = pin; + + for (; idx <= maxidx; idx++) + norm[idx] = 0; + + return elf_zstd_build_fse (norm, idx, next, *table_bits, table); +} + +/* Build the FSE decoding table from a list of probabilities. This reads from + NORM of length IDX, uses NEXT as scratch space, and writes to *TABLE, whose + size is TABLE_BITS. */ + +static int +elf_zstd_build_fse (const int16_t *norm, int idx, uint16_t *next, + int table_bits, struct elf_zstd_fse_entry *table) +{ + int table_size; + int high_threshold; + int i; + int pos; + int step; + int mask; + + table_size = 1 << table_bits; + high_threshold = table_size - 1; + for (i = 0; i < idx; i++) + { + int16_t n; + + n = norm[i]; + if (n >= 0) + next[i] = (uint16_t) n; + else + { + table[high_threshold].symbol = (unsigned char) i; + high_threshold--; + next[i] = 1; + } + } + + pos = 0; + step = (table_size >> 1) + (table_size >> 3) + 3; + mask = table_size - 1; + for (i = 0; i < idx; i++) + { + int n; + int j; + + n = (int) norm[i]; + for (j = 0; j < n; j++) + { + table[pos].symbol = (unsigned char) i; + pos = (pos + step) & mask; + while (unlikely (pos > high_threshold)) + pos = (pos + step) & mask; + } + } + if (unlikely (pos != 0)) + { + elf_uncompress_failed (); + return 0; + } + + for (i = 0; i < table_size; i++) + { + unsigned char sym; + uint16_t next_state; + int high_bit; + int bits; + + sym = table[i].symbol; + next_state = next[sym]; + ++next[sym]; + + if (next_state == 0) + { + elf_uncompress_failed (); + return 0; + } + high_bit = 31 - __builtin_clz (next_state); + + bits = table_bits - high_bit; + table[i].bits = (unsigned char) bits; + table[i].base = (uint16_t) ((next_state << bits) - table_size); + } + + return 1; +} + +/* Encode the baseline and bits into a single 32-bit value. */ + +#define ZSTD_ENCODE_BASELINE_BITS(baseline, basebits) \ + ((uint32_t)(baseline) | ((uint32_t)(basebits) << 24)) + +#define ZSTD_DECODE_BASELINE(baseline_basebits) \ + ((uint32_t)(baseline_basebits) & 0xffffff) + +#define ZSTD_DECODE_BASEBITS(baseline_basebits) \ + ((uint32_t)(baseline_basebits) >> 24) + +/* Given a literal length code, we need to read a number of bits and add that + to a baseline. For states 0 to 15 the baseline is the state and the number + of bits is zero. */ + +#define ZSTD_LITERAL_LENGTH_BASELINE_OFFSET (16) + +static const uint32_t elf_zstd_literal_length_base[] = +{ + ZSTD_ENCODE_BASELINE_BITS(16, 1), + ZSTD_ENCODE_BASELINE_BITS(18, 1), + ZSTD_ENCODE_BASELINE_BITS(20, 1), + ZSTD_ENCODE_BASELINE_BITS(22, 1), + ZSTD_ENCODE_BASELINE_BITS(24, 2), + ZSTD_ENCODE_BASELINE_BITS(28, 2), + ZSTD_ENCODE_BASELINE_BITS(32, 3), + ZSTD_ENCODE_BASELINE_BITS(40, 3), + ZSTD_ENCODE_BASELINE_BITS(48, 4), + ZSTD_ENCODE_BASELINE_BITS(64, 6), + ZSTD_ENCODE_BASELINE_BITS(128, 7), + ZSTD_ENCODE_BASELINE_BITS(256, 8), + ZSTD_ENCODE_BASELINE_BITS(512, 9), + ZSTD_ENCODE_BASELINE_BITS(1024, 10), + ZSTD_ENCODE_BASELINE_BITS(2048, 11), + ZSTD_ENCODE_BASELINE_BITS(4096, 12), + ZSTD_ENCODE_BASELINE_BITS(8192, 13), + ZSTD_ENCODE_BASELINE_BITS(16384, 14), + ZSTD_ENCODE_BASELINE_BITS(32768, 15), + ZSTD_ENCODE_BASELINE_BITS(65536, 16) +}; + +/* The same applies to match length codes. For states 0 to 31 the baseline is + the state + 3 and the number of bits is zero. */ + +#define ZSTD_MATCH_LENGTH_BASELINE_OFFSET (32) + +static const uint32_t elf_zstd_match_length_base[] = +{ + ZSTD_ENCODE_BASELINE_BITS(35, 1), + ZSTD_ENCODE_BASELINE_BITS(37, 1), + ZSTD_ENCODE_BASELINE_BITS(39, 1), + ZSTD_ENCODE_BASELINE_BITS(41, 1), + ZSTD_ENCODE_BASELINE_BITS(43, 2), + ZSTD_ENCODE_BASELINE_BITS(47, 2), + ZSTD_ENCODE_BASELINE_BITS(51, 3), + ZSTD_ENCODE_BASELINE_BITS(59, 3), + ZSTD_ENCODE_BASELINE_BITS(67, 4), + ZSTD_ENCODE_BASELINE_BITS(83, 4), + ZSTD_ENCODE_BASELINE_BITS(99, 5), + ZSTD_ENCODE_BASELINE_BITS(131, 7), + ZSTD_ENCODE_BASELINE_BITS(259, 8), + ZSTD_ENCODE_BASELINE_BITS(515, 9), + ZSTD_ENCODE_BASELINE_BITS(1027, 10), + ZSTD_ENCODE_BASELINE_BITS(2051, 11), + ZSTD_ENCODE_BASELINE_BITS(4099, 12), + ZSTD_ENCODE_BASELINE_BITS(8195, 13), + ZSTD_ENCODE_BASELINE_BITS(16387, 14), + ZSTD_ENCODE_BASELINE_BITS(32771, 15), + ZSTD_ENCODE_BASELINE_BITS(65539, 16) +}; + +/* An entry in an FSE table used for literal/match/length values. For these we + have to map the symbol to a baseline value, and we have to read zero or more + bits and add that value to the baseline value. Rather than look the values + up in a separate table, we grow the FSE table so that we get better memory + caching. */ + +struct elf_zstd_fse_baseline_entry +{ + /* The baseline for the value that this FSE entry represents.. */ + uint32_t baseline; + /* The number of bits to read to add to the baseline. */ + unsigned char basebits; + /* The number of bits to read to determine the next state. */ + unsigned char bits; + /* Add the bits to this base to get the next state. */ + uint16_t base; +}; + +/* Convert the literal length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_literal_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (symbol < ZSTD_LITERAL_LENGTH_BASELINE_OFFSET) + { + pbaseline->baseline = (uint32_t)symbol; + pbaseline->basebits = 0; + } + else + { + unsigned int idx; + uint32_t basebits; + + if (unlikely (symbol > 35)) + { + elf_uncompress_failed (); + return 0; + } + idx = symbol - ZSTD_LITERAL_LENGTH_BASELINE_OFFSET; + basebits = elf_zstd_literal_length_base[idx]; + pbaseline->baseline = ZSTD_DECODE_BASELINE(basebits); + pbaseline->basebits = ZSTD_DECODE_BASEBITS(basebits); + } + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +/* Convert the offset length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_offset_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (unlikely (symbol > 31)) + { + elf_uncompress_failed (); + return 0; + } + + /* The simple way to write this is + + pbaseline->baseline = (uint32_t)1 << symbol; + pbaseline->basebits = symbol; + + That will give us an offset value that corresponds to the one + described in the RFC. However, for offset values > 3, we have to + subtract 3. And for offset values 1, 2, 3 we use a repeated offset. + The baseline is always a power of 2, and is never 0, so for these low + values we will see one entry that is baseline 1, basebits 0, and one + entry that is baseline 2, basebits 1. All other entries will have + baseline >= 4 and basebits >= 2. + + So we can check for RFC offset <= 3 by checking for basebits <= 1. + And that means that we can subtract 3 here and not worry about doing + it in the hot loop. */ + + pbaseline->baseline = (uint32_t)1 << symbol; + if (symbol >= 2) + pbaseline->baseline -= 3; + pbaseline->basebits = symbol; + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +/* Convert the match length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_match_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (symbol < ZSTD_MATCH_LENGTH_BASELINE_OFFSET) + { + pbaseline->baseline = (uint32_t)symbol + 3; + pbaseline->basebits = 0; + } + else + { + unsigned int idx; + uint32_t basebits; + + if (unlikely (symbol > 52)) + { + elf_uncompress_failed (); + return 0; + } + idx = symbol - ZSTD_MATCH_LENGTH_BASELINE_OFFSET; + basebits = elf_zstd_match_length_base[idx]; + pbaseline->baseline = ZSTD_DECODE_BASELINE(basebits); + pbaseline->basebits = ZSTD_DECODE_BASEBITS(basebits); + } + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +#ifdef BACKTRACE_GENERATE_ZSTD_FSE_TABLES + +/* Used to generate the predefined FSE decoding tables for zstd. */ + +#include + +/* These values are straight from RFC 8878. */ + +static int16_t lit[36] = +{ + 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 +}; + +static int16_t match[53] = +{ + 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 +}; + +static int16_t offset[29] = +{ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 +}; + +static uint16_t next[256]; + +static void +print_table (const struct elf_zstd_fse_baseline_entry *table, size_t size) +{ + size_t i; + + printf ("{\n"); + for (i = 0; i < size; i += 3) + { + int j; + + printf (" "); + for (j = 0; j < 3 && i + j < size; ++j) + printf (" { %u, %d, %d, %d },", table[i + j].baseline, + table[i + j].basebits, table[i + j].bits, + table[i + j].base); + printf ("\n"); + } + printf ("};\n"); +} + +int +main () +{ + struct elf_zstd_fse_entry lit_table[64]; + struct elf_zstd_fse_baseline_entry lit_baseline[64]; + struct elf_zstd_fse_entry match_table[64]; + struct elf_zstd_fse_baseline_entry match_baseline[64]; + struct elf_zstd_fse_entry offset_table[32]; + struct elf_zstd_fse_baseline_entry offset_baseline[32]; + + if (!elf_zstd_build_fse (lit, sizeof lit / sizeof lit[0], next, + 6, lit_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_literal_baseline_fse (lit_table, 6, lit_baseline)) + { + fprintf (stderr, "elf_zstd_make_literal_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_lit_table[64] =\n"); + print_table (lit_baseline, + sizeof lit_baseline / sizeof lit_baseline[0]); + printf ("\n"); + + if (!elf_zstd_build_fse (match, sizeof match / sizeof match[0], next, + 6, match_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_match_baseline_fse (match_table, 6, match_baseline)) + { + fprintf (stderr, "elf_zstd_make_match_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_match_table[64] =\n"); + print_table (match_baseline, + sizeof match_baseline / sizeof match_baseline[0]); + printf ("\n"); + + if (!elf_zstd_build_fse (offset, sizeof offset / sizeof offset[0], next, + 5, offset_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_offset_baseline_fse (offset_table, 5, offset_baseline)) + { + fprintf (stderr, "elf_zstd_make_offset_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_offset_table[32] =\n"); + print_table (offset_baseline, + sizeof offset_baseline / sizeof offset_baseline[0]); + printf ("\n"); + + return 0; +} + +#endif + +/* The fixed tables generated by the #ifdef'ed out main function + above. */ + +static const struct elf_zstd_fse_baseline_entry elf_zstd_lit_table[64] = +{ + { 0, 0, 4, 0 }, { 0, 0, 4, 16 }, { 1, 0, 5, 32 }, + { 3, 0, 5, 0 }, { 4, 0, 5, 0 }, { 6, 0, 5, 0 }, + { 7, 0, 5, 0 }, { 9, 0, 5, 0 }, { 10, 0, 5, 0 }, + { 12, 0, 5, 0 }, { 14, 0, 6, 0 }, { 16, 1, 5, 0 }, + { 20, 1, 5, 0 }, { 22, 1, 5, 0 }, { 28, 2, 5, 0 }, + { 32, 3, 5, 0 }, { 48, 4, 5, 0 }, { 64, 6, 5, 32 }, + { 128, 7, 5, 0 }, { 256, 8, 6, 0 }, { 1024, 10, 6, 0 }, + { 4096, 12, 6, 0 }, { 0, 0, 4, 32 }, { 1, 0, 4, 0 }, + { 2, 0, 5, 0 }, { 4, 0, 5, 32 }, { 5, 0, 5, 0 }, + { 7, 0, 5, 32 }, { 8, 0, 5, 0 }, { 10, 0, 5, 32 }, + { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 1, 5, 32 }, + { 18, 1, 5, 0 }, { 22, 1, 5, 32 }, { 24, 2, 5, 0 }, + { 32, 3, 5, 32 }, { 40, 3, 5, 0 }, { 64, 6, 4, 0 }, + { 64, 6, 4, 16 }, { 128, 7, 5, 32 }, { 512, 9, 6, 0 }, + { 2048, 11, 6, 0 }, { 0, 0, 4, 48 }, { 1, 0, 4, 16 }, + { 2, 0, 5, 32 }, { 3, 0, 5, 32 }, { 5, 0, 5, 32 }, + { 6, 0, 5, 32 }, { 8, 0, 5, 32 }, { 9, 0, 5, 32 }, + { 11, 0, 5, 32 }, { 12, 0, 5, 32 }, { 15, 0, 6, 0 }, + { 18, 1, 5, 32 }, { 20, 1, 5, 32 }, { 24, 2, 5, 32 }, + { 28, 2, 5, 32 }, { 40, 3, 5, 32 }, { 48, 4, 5, 32 }, + { 65536, 16, 6, 0 }, { 32768, 15, 6, 0 }, { 16384, 14, 6, 0 }, + { 8192, 13, 6, 0 }, +}; + +static const struct elf_zstd_fse_baseline_entry elf_zstd_match_table[64] = +{ + { 3, 0, 6, 0 }, { 4, 0, 4, 0 }, { 5, 0, 5, 32 }, + { 6, 0, 5, 0 }, { 8, 0, 5, 0 }, { 9, 0, 5, 0 }, + { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 0, 6, 0 }, + { 19, 0, 6, 0 }, { 22, 0, 6, 0 }, { 25, 0, 6, 0 }, + { 28, 0, 6, 0 }, { 31, 0, 6, 0 }, { 34, 0, 6, 0 }, + { 37, 1, 6, 0 }, { 41, 1, 6, 0 }, { 47, 2, 6, 0 }, + { 59, 3, 6, 0 }, { 83, 4, 6, 0 }, { 131, 7, 6, 0 }, + { 515, 9, 6, 0 }, { 4, 0, 4, 16 }, { 5, 0, 4, 0 }, + { 6, 0, 5, 32 }, { 7, 0, 5, 0 }, { 9, 0, 5, 32 }, + { 10, 0, 5, 0 }, { 12, 0, 6, 0 }, { 15, 0, 6, 0 }, + { 18, 0, 6, 0 }, { 21, 0, 6, 0 }, { 24, 0, 6, 0 }, + { 27, 0, 6, 0 }, { 30, 0, 6, 0 }, { 33, 0, 6, 0 }, + { 35, 1, 6, 0 }, { 39, 1, 6, 0 }, { 43, 2, 6, 0 }, + { 51, 3, 6, 0 }, { 67, 4, 6, 0 }, { 99, 5, 6, 0 }, + { 259, 8, 6, 0 }, { 4, 0, 4, 32 }, { 4, 0, 4, 48 }, + { 5, 0, 4, 16 }, { 7, 0, 5, 32 }, { 8, 0, 5, 32 }, + { 10, 0, 5, 32 }, { 11, 0, 5, 32 }, { 14, 0, 6, 0 }, + { 17, 0, 6, 0 }, { 20, 0, 6, 0 }, { 23, 0, 6, 0 }, + { 26, 0, 6, 0 }, { 29, 0, 6, 0 }, { 32, 0, 6, 0 }, + { 65539, 16, 6, 0 }, { 32771, 15, 6, 0 }, { 16387, 14, 6, 0 }, + { 8195, 13, 6, 0 }, { 4099, 12, 6, 0 }, { 2051, 11, 6, 0 }, + { 1027, 10, 6, 0 }, +}; + +static const struct elf_zstd_fse_baseline_entry elf_zstd_offset_table[32] = +{ + { 1, 0, 5, 0 }, { 61, 6, 4, 0 }, { 509, 9, 5, 0 }, + { 32765, 15, 5, 0 }, { 2097149, 21, 5, 0 }, { 5, 3, 5, 0 }, + { 125, 7, 4, 0 }, { 4093, 12, 5, 0 }, { 262141, 18, 5, 0 }, + { 8388605, 23, 5, 0 }, { 29, 5, 5, 0 }, { 253, 8, 4, 0 }, + { 16381, 14, 5, 0 }, { 1048573, 20, 5, 0 }, { 1, 2, 5, 0 }, + { 125, 7, 4, 16 }, { 2045, 11, 5, 0 }, { 131069, 17, 5, 0 }, + { 4194301, 22, 5, 0 }, { 13, 4, 5, 0 }, { 253, 8, 4, 16 }, + { 8189, 13, 5, 0 }, { 524285, 19, 5, 0 }, { 2, 1, 5, 0 }, + { 61, 6, 4, 16 }, { 1021, 10, 5, 0 }, { 65533, 16, 5, 0 }, + { 268435453, 28, 5, 0 }, { 134217725, 27, 5, 0 }, { 67108861, 26, 5, 0 }, + { 33554429, 25, 5, 0 }, { 16777213, 24, 5, 0 }, +}; + +/* Read a zstd Huffman table and build the decoding table in *TABLE, reading + and updating *PPIN. This sets *PTABLE_BITS to the number of bits of the + table, such that the table length is 1 << *TABLE_BITS. ZDEBUG_TABLE is + scratch space; it must be enough for 512 uint16_t values + 256 32-bit values + (2048 bytes). Returns 1 on success, 0 on error. */ + +static int +elf_zstd_read_huff (const unsigned char **ppin, const unsigned char *pinend, + uint16_t *zdebug_table, uint16_t *table, int *ptable_bits) +{ + const unsigned char *pin; + unsigned char hdr; + unsigned char *weights; + size_t count; + uint32_t *weight_mark; + size_t i; + uint32_t weight_mask; + size_t table_bits; + + pin = *ppin; + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + hdr = *pin; + ++pin; + + weights = (unsigned char *) zdebug_table; + + if (hdr < 128) + { + /* Table is compressed using FSE. */ + + struct elf_zstd_fse_entry *fse_table; + int fse_table_bits; + uint16_t *scratch; + const unsigned char *pfse; + const unsigned char *pback; + uint64_t val; + unsigned int bits; + unsigned int state1, state2; + + /* SCRATCH is used temporarily by elf_zstd_read_fse. It overlaps + WEIGHTS. */ + scratch = zdebug_table; + fse_table = (struct elf_zstd_fse_entry *) (scratch + 512); + fse_table_bits = 6; + + pfse = pin; + if (!elf_zstd_read_fse (&pfse, pinend, scratch, 255, fse_table, + &fse_table_bits)) + return 0; + + if (unlikely (pin + hdr > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* We no longer need SCRATCH. Start recording weights. We need up to + 256 bytes of weights and 64 bytes of rank counts, so it won't overlap + FSE_TABLE. */ + + pback = pin + hdr - 1; + + if (!elf_fetch_backward_init (&pback, pfse, &val, &bits)) + return 0; + + bits -= fse_table_bits; + state1 = (val >> bits) & ((1U << fse_table_bits) - 1); + bits -= fse_table_bits; + state2 = (val >> bits) & ((1U << fse_table_bits) - 1); + + /* There are two independent FSE streams, tracked by STATE1 and STATE2. + We decode them alternately. */ + + count = 0; + while (1) + { + struct elf_zstd_fse_entry *pt; + uint64_t v; + + pt = &fse_table[state1]; + + if (unlikely (pin < pinend) && bits < pt->bits) + { + if (unlikely (count >= 254)) + { + elf_uncompress_failed (); + return 0; + } + weights[count] = (unsigned char) pt->symbol; + weights[count + 1] = (unsigned char) fse_table[state2].symbol; + count += 2; + break; + } + + if (unlikely (pt->bits == 0)) + v = 0; + else + { + if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits)) + return 0; + + bits -= pt->bits; + v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1); + } + + state1 = pt->base + v; + + if (unlikely (count >= 255)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = pt->symbol; + ++count; + + pt = &fse_table[state2]; + + if (unlikely (pin < pinend && bits < pt->bits)) + { + if (unlikely (count >= 254)) + { + elf_uncompress_failed (); + return 0; + } + weights[count] = (unsigned char) pt->symbol; + weights[count + 1] = (unsigned char) fse_table[state1].symbol; + count += 2; + break; + } + + if (unlikely (pt->bits == 0)) + v = 0; + else + { + if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits)) + return 0; + + bits -= pt->bits; + v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1); + } + + state2 = pt->base + v; + + if (unlikely (count >= 255)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = pt->symbol; + ++count; + } + + pin += hdr; + } + else + { + /* Table is not compressed. Each weight is 4 bits. */ + + count = hdr - 127; + if (unlikely (pin + ((count + 1) / 2) >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + for (i = 0; i < count; i += 2) + { + unsigned char b; + + b = *pin; + ++pin; + weights[i] = b >> 4; + weights[i + 1] = b & 0xf; + } + } + + weight_mark = (uint32_t *) (weights + 256); + memset (weight_mark, 0, 13 * sizeof (uint32_t)); + weight_mask = 0; + for (i = 0; i < count; ++i) + { + unsigned char w; + + w = weights[i]; + if (unlikely (w > 12)) + { + elf_uncompress_failed (); + return 0; + } + ++weight_mark[w]; + if (w > 0) + weight_mask += 1U << (w - 1); + } + if (unlikely (weight_mask == 0)) + { + elf_uncompress_failed (); + return 0; + } + + table_bits = 32 - __builtin_clz (weight_mask); + if (unlikely (table_bits > 11)) + { + elf_uncompress_failed (); + return 0; + } + + /* Work out the last weight value, which is omitted because the weights must + sum to a power of two. */ + { + uint32_t left; + uint32_t high_bit; + + left = ((uint32_t)1 << table_bits) - weight_mask; + if (left == 0) + { + elf_uncompress_failed (); + return 0; + } + high_bit = 31 - __builtin_clz (left); + if (((uint32_t)1 << high_bit) != left) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely (count >= 256)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = high_bit + 1; + ++count; + ++weight_mark[high_bit + 1]; + } + + if (weight_mark[1] < 2 || (weight_mark[1] & 1) != 0) + { + elf_uncompress_failed (); + return 0; + } + + /* Change WEIGHT_MARK from a count of weights to the index of the first + symbol for that weight. We shift the indexes to also store how many we + have seen so far, below. */ + { + uint32_t next; + + next = 0; + for (i = 0; i < table_bits; ++i) + { + uint32_t cur; + + cur = next; + next += weight_mark[i + 1] << i; + weight_mark[i + 1] = cur; + } + } + + for (i = 0; i < count; ++i) + { + unsigned char weight; + uint32_t length; + uint16_t tval; + size_t start; + uint32_t j; + + weight = weights[i]; + if (weight == 0) + continue; + + length = 1U << (weight - 1); + tval = (i << 8) | (table_bits + 1 - weight); + start = weight_mark[weight]; + for (j = 0; j < length; ++j) + table[start + j] = tval; + weight_mark[weight] += length; + } + + *ppin = pin; + *ptable_bits = (int)table_bits; + + return 1; +} + +/* Read and decompress the literals and store them ending at POUTEND. This + works because we are going to use all the literals in the output, so they + must fit into the output buffer. HUFFMAN_TABLE, and PHUFFMAN_TABLE_BITS + store the Huffman table across calls. SCRATCH is used to read a Huffman + table. Store the start of the decompressed literals in *PPLIT. Update + *PPIN. Return 1 on success, 0 on error. */ + +static int +elf_zstd_read_literals (const unsigned char **ppin, + const unsigned char *pinend, + unsigned char *pout, + unsigned char *poutend, + uint16_t *scratch, + uint16_t *huffman_table, + int *phuffman_table_bits, + unsigned char **pplit) +{ + const unsigned char *pin; + unsigned char *plit; + unsigned char hdr; + uint32_t regenerated_size; + uint32_t compressed_size; + int streams; + uint32_t total_streams_size; + unsigned int huffman_table_bits; + uint64_t huffman_mask; + + pin = *ppin; + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + hdr = *pin; + ++pin; + + if ((hdr & 3) == 0 || (hdr & 3) == 1) + { + int raw; + + /* Raw_Literals_Block or RLE_Literals_Block */ + + raw = (hdr & 3) == 0; + + switch ((hdr >> 2) & 3) + { + case 0: case 2: + regenerated_size = hdr >> 3; + break; + case 1: + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (hdr >> 4) + ((uint32_t)(*pin) << 4); + ++pin; + break; + case 3: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = ((hdr >> 4) + + ((uint32_t)*pin << 4) + + ((uint32_t)pin[1] << 12)); + pin += 2; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((size_t)(poutend - pout) < regenerated_size)) + { + elf_uncompress_failed (); + return 0; + } + + plit = poutend - regenerated_size; + + if (raw) + { + if (unlikely (pin + regenerated_size >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + memcpy (plit, pin, regenerated_size); + pin += regenerated_size; + } + else + { + if (pin >= pinend) + { + elf_uncompress_failed (); + return 0; + } + memset (plit, *pin, regenerated_size); + ++pin; + } + + *ppin = pin; + *pplit = plit; + + return 1; + } + + /* Compressed_Literals_Block or Treeless_Literals_Block */ + + switch ((hdr >> 2) & 3) + { + case 0: case 1: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (hdr >> 4) | ((uint32_t)(*pin & 0x3f) << 4); + compressed_size = (uint32_t)*pin >> 6 | ((uint32_t)pin[1] << 2); + pin += 2; + streams = ((hdr >> 2) & 3) == 0 ? 1 : 4; + break; + case 2: + if (unlikely (pin + 2 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (((uint32_t)hdr >> 4) + | ((uint32_t)*pin << 4) + | (((uint32_t)pin[1] & 3) << 12)); + compressed_size = (((uint32_t)pin[1] >> 2) + | ((uint32_t)pin[2] << 6)); + pin += 3; + streams = 4; + break; + case 3: + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (((uint32_t)hdr >> 4) + | ((uint32_t)*pin << 4) + | (((uint32_t)pin[1] & 0x3f) << 12)); + compressed_size = (((uint32_t)pin[1] >> 6) + | ((uint32_t)pin[2] << 2) + | ((uint32_t)pin[3] << 10)); + pin += 4; + streams = 4; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely (pin + compressed_size > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + pinend = pin + compressed_size; + *ppin = pinend; + + if (unlikely ((size_t)(poutend - pout) < regenerated_size)) + { + elf_uncompress_failed (); + return 0; + } + + plit = poutend - regenerated_size; + + *pplit = plit; + + total_streams_size = compressed_size; + if ((hdr & 3) == 2) + { + const unsigned char *ptable; + + /* Compressed_Literals_Block. Read Huffman tree. */ + + ptable = pin; + if (!elf_zstd_read_huff (&ptable, pinend, scratch, huffman_table, + phuffman_table_bits)) + return 0; + + if (unlikely (total_streams_size < (size_t)(ptable - pin))) + { + elf_uncompress_failed (); + return 0; + } + + total_streams_size -= ptable - pin; + pin = ptable; + } + else + { + /* Treeless_Literals_Block. Reuse previous Huffman tree. */ + if (unlikely (*phuffman_table_bits == 0)) + { + elf_uncompress_failed (); + return 0; + } + } + + /* Decompress COMPRESSED_SIZE bytes of data at PIN using the huffman table, + storing REGENERATED_SIZE bytes of decompressed data at PLIT. */ + + huffman_table_bits = (unsigned int)*phuffman_table_bits; + huffman_mask = ((uint64_t)1 << huffman_table_bits) - 1; + + if (streams == 1) + { + const unsigned char *pback; + const unsigned char *pbackend; + uint64_t val; + unsigned int bits; + uint32_t i; + + pback = pin + total_streams_size - 1; + pbackend = pin; + if (!elf_fetch_backward_init (&pback, pbackend, &val, &bits)) + return 0; + + /* This is one of the inner loops of the decompression algorithm, so we + put some effort into optimization. We can't get more than 64 bytes + from a single call to elf_fetch_bits_backward, and we can't subtract + more than 11 bits at a time. */ + + if (regenerated_size >= 64) + { + unsigned char *plitstart; + unsigned char *plitstop; + + plitstart = plit; + plitstop = plit + regenerated_size - 64; + while (plit < plitstop) + { + uint16_t t; + + if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits)) + return 0; + + if (bits < 16) + break; + + while (bits >= 33) + { + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + + while (bits > 11) + { + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + } + + regenerated_size -= plit - plitstart; + } + + for (i = 0; i < regenerated_size; ++i) + { + uint16_t t; + + if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits)) + return 0; + + if (unlikely (bits < huffman_table_bits)) + { + t = huffman_table[(val << (huffman_table_bits - bits)) + & huffman_mask]; + if (unlikely (bits < (t & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + + return 1; + } + + { + uint32_t stream_size1, stream_size2, stream_size3, stream_size4; + uint32_t tot; + const unsigned char *pback1, *pback2, *pback3, *pback4; + const unsigned char *pbackend1, *pbackend2, *pbackend3, *pbackend4; + uint64_t val1, val2, val3, val4; + unsigned int bits1, bits2, bits3, bits4; + unsigned char *plit1, *plit2, *plit3, *plit4; + uint32_t regenerated_stream_size; + uint32_t regenerated_stream_size4; + uint16_t t1, t2, t3, t4; + uint32_t i; + uint32_t limit; + + /* Read jump table. */ + if (unlikely (pin + 5 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + stream_size1 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + stream_size2 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + stream_size3 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + tot = stream_size1 + stream_size2 + stream_size3; + if (unlikely (tot > total_streams_size - 6)) + { + elf_uncompress_failed (); + return 0; + } + stream_size4 = total_streams_size - 6 - tot; + + pback1 = pin + stream_size1 - 1; + pbackend1 = pin; + + pback2 = pback1 + stream_size2; + pbackend2 = pback1 + 1; + + pback3 = pback2 + stream_size3; + pbackend3 = pback2 + 1; + + pback4 = pback3 + stream_size4; + pbackend4 = pback3 + 1; + + if (!elf_fetch_backward_init (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_backward_init (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_backward_init (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (!elf_fetch_backward_init (&pback4, pbackend4, &val4, &bits4)) + return 0; + + regenerated_stream_size = (regenerated_size + 3) / 4; + + plit1 = plit; + plit2 = plit1 + regenerated_stream_size; + plit3 = plit2 + regenerated_stream_size; + plit4 = plit3 + regenerated_stream_size; + + regenerated_stream_size4 = regenerated_size - regenerated_stream_size * 3; + + /* We can't get more than 64 literal bytes from a single call to + elf_fetch_bits_backward. The fourth stream can be up to 3 bytes less, + so use as the limit. */ + + limit = regenerated_stream_size4 <= 64 ? 0 : regenerated_stream_size4 - 64; + i = 0; + while (i < limit) + { + if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4)) + return 0; + + /* We can't subtract more than 11 bits at a time. */ + + do + { + t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits)) + & huffman_mask]; + t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits)) + & huffman_mask]; + t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits)) + & huffman_mask]; + t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits)) + & huffman_mask]; + + *plit1 = t1 >> 8; + ++plit1; + bits1 -= t1 & 0xff; + + *plit2 = t2 >> 8; + ++plit2; + bits2 -= t2 & 0xff; + + *plit3 = t3 >> 8; + ++plit3; + bits3 -= t3 & 0xff; + + *plit4 = t4 >> 8; + ++plit4; + bits4 -= t4 & 0xff; + + ++i; + } + while (bits1 > 11 && bits2 > 11 && bits3 > 11 && bits4 > 11); + } + + while (i < regenerated_stream_size) + { + int use4; + + use4 = i < regenerated_stream_size4; + + if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (use4) + { + if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4)) + return 0; + } + + if (unlikely (bits1 < huffman_table_bits)) + { + t1 = huffman_table[(val1 << (huffman_table_bits - bits1)) + & huffman_mask]; + if (unlikely (bits1 < (t1 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits)) + & huffman_mask]; + + if (unlikely (bits2 < huffman_table_bits)) + { + t2 = huffman_table[(val2 << (huffman_table_bits - bits2)) + & huffman_mask]; + if (unlikely (bits2 < (t2 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits)) + & huffman_mask]; + + if (unlikely (bits3 < huffman_table_bits)) + { + t3 = huffman_table[(val3 << (huffman_table_bits - bits3)) + & huffman_mask]; + if (unlikely (bits3 < (t3 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits)) + & huffman_mask]; + + if (use4) + { + if (unlikely (bits4 < huffman_table_bits)) + { + t4 = huffman_table[(val4 << (huffman_table_bits - bits4)) + & huffman_mask]; + if (unlikely (bits4 < (t4 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits)) + & huffman_mask]; + + *plit4 = t4 >> 8; + ++plit4; + bits4 -= t4 & 0xff; + } + + *plit1 = t1 >> 8; + ++plit1; + bits1 -= t1 & 0xff; + + *plit2 = t2 >> 8; + ++plit2; + bits2 -= t2 & 0xff; + + *plit3 = t3 >> 8; + ++plit3; + bits3 -= t3 & 0xff; + + ++i; + } + } + + return 1; +} + +/* The information used to decompress a sequence code, which can be a literal + length, an offset, or a match length. */ + +struct elf_zstd_seq_decode +{ + const struct elf_zstd_fse_baseline_entry *table; + int table_bits; +}; + +/* Unpack a sequence code compression mode. */ + +static int +elf_zstd_unpack_seq_decode (int mode, + const unsigned char **ppin, + const unsigned char *pinend, + const struct elf_zstd_fse_baseline_entry *predef, + int predef_bits, + uint16_t *scratch, + int maxidx, + struct elf_zstd_fse_baseline_entry *table, + int table_bits, + int (*conv)(const struct elf_zstd_fse_entry *, + int, + struct elf_zstd_fse_baseline_entry *), + struct elf_zstd_seq_decode *decode) +{ + switch (mode) + { + case 0: + decode->table = predef; + decode->table_bits = predef_bits; + break; + + case 1: + { + struct elf_zstd_fse_entry entry; + + if (unlikely (*ppin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + entry.symbol = **ppin; + ++*ppin; + entry.bits = 0; + entry.base = 0; + decode->table_bits = 0; + if (!conv (&entry, 0, table)) + return 0; + } + break; + + case 2: + { + struct elf_zstd_fse_entry *fse_table; + + /* We use the same space for the simple FSE table and the baseline + table. */ + fse_table = (struct elf_zstd_fse_entry *)table; + decode->table_bits = table_bits; + if (!elf_zstd_read_fse (ppin, pinend, scratch, maxidx, fse_table, + &decode->table_bits)) + return 0; + if (!conv (fse_table, decode->table_bits, table)) + return 0; + decode->table = table; + } + break; + + case 3: + if (unlikely (decode->table_bits == -1)) + { + elf_uncompress_failed (); + return 0; + } + break; + + default: + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +/* Decompress a zstd stream from PIN/SIN to POUT/SOUT. Code based on RFC 8878. + Return 1 on success, 0 on error. */ + +static int +elf_zstd_decompress (const unsigned char *pin, size_t sin, + unsigned char *zdebug_table, unsigned char *pout, + size_t sout) +{ + const unsigned char *pinend; + unsigned char *poutstart; + unsigned char *poutend; + struct elf_zstd_seq_decode literal_decode; + struct elf_zstd_fse_baseline_entry *literal_fse_table; + struct elf_zstd_seq_decode match_decode; + struct elf_zstd_fse_baseline_entry *match_fse_table; + struct elf_zstd_seq_decode offset_decode; + struct elf_zstd_fse_baseline_entry *offset_fse_table; + uint16_t *huffman_table; + int huffman_table_bits; + uint32_t repeated_offset1; + uint32_t repeated_offset2; + uint32_t repeated_offset3; + uint16_t *scratch; + unsigned char hdr; + int has_checksum; + uint64_t content_size; + int last_block; + + pinend = pin + sin; + poutstart = pout; + poutend = pout + sout; + + literal_decode.table = NULL; + literal_decode.table_bits = -1; + literal_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_LITERAL_FSE_OFFSET)); + + match_decode.table = NULL; + match_decode.table_bits = -1; + match_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_MATCH_FSE_OFFSET)); + + offset_decode.table = NULL; + offset_decode.table_bits = -1; + offset_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_OFFSET_FSE_OFFSET)); + huffman_table = ((uint16_t *) + (zdebug_table + ZSTD_TABLE_HUFFMAN_OFFSET)); + huffman_table_bits = 0; + scratch = ((uint16_t *) + (zdebug_table + ZSTD_TABLE_WORK_OFFSET)); + + repeated_offset1 = 1; + repeated_offset2 = 4; + repeated_offset3 = 8; + + if (unlikely (sin < 4)) + { + elf_uncompress_failed (); + return 0; + } + + /* These values are the zstd magic number. */ + if (unlikely (pin[0] != 0x28 + || pin[1] != 0xb5 + || pin[2] != 0x2f + || pin[3] != 0xfd)) + { + elf_uncompress_failed (); + return 0; + } + + pin += 4; + + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + + hdr = *pin++; + + /* We expect a single frame. */ + if (unlikely ((hdr & (1 << 5)) == 0)) + { + elf_uncompress_failed (); + return 0; + } + /* Reserved bit must be zero. */ + if (unlikely ((hdr & (1 << 3)) != 0)) + { + elf_uncompress_failed (); + return 0; + } + /* We do not expect a dictionary. */ + if (unlikely ((hdr & 3) != 0)) + { + elf_uncompress_failed (); + return 0; + } + has_checksum = (hdr & (1 << 2)) != 0; + switch (hdr >> 6) + { + case 0: + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = (uint64_t) *pin++; + break; + case 1: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = (((uint64_t) pin[0]) | (((uint64_t) pin[1]) << 8)) + 256; + pin += 2; + break; + case 2: + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = ((uint64_t) pin[0] + | (((uint64_t) pin[1]) << 8) + | (((uint64_t) pin[2]) << 16) + | (((uint64_t) pin[3]) << 24)); + pin += 4; + break; + case 3: + if (unlikely (pin + 7 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = ((uint64_t) pin[0] + | (((uint64_t) pin[1]) << 8) + | (((uint64_t) pin[2]) << 16) + | (((uint64_t) pin[3]) << 24) + | (((uint64_t) pin[4]) << 32) + | (((uint64_t) pin[5]) << 40) + | (((uint64_t) pin[6]) << 48) + | (((uint64_t) pin[7]) << 56)); + pin += 8; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely (content_size != (size_t) content_size + || (size_t) content_size != sout)) + { + elf_uncompress_failed (); + return 0; + } + + last_block = 0; + while (!last_block) + { + uint32_t block_hdr; + int block_type; + uint32_t block_size; + + if (unlikely (pin + 2 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + block_hdr = ((uint32_t) pin[0] + | (((uint32_t) pin[1]) << 8) + | (((uint32_t) pin[2]) << 16)); + pin += 3; + + last_block = block_hdr & 1; + block_type = (block_hdr >> 1) & 3; + block_size = block_hdr >> 3; + + switch (block_type) + { + case 0: + /* Raw_Block */ + if (unlikely ((size_t) block_size > (size_t) (pinend - pin))) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely ((size_t) block_size > (size_t) (poutend - pout))) + { + elf_uncompress_failed (); + return 0; + } + memcpy (pout, pin, block_size); + pout += block_size; + pin += block_size; + break; + + case 1: + /* RLE_Block */ + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely ((size_t) block_size > (size_t) (poutend - pout))) + { + elf_uncompress_failed (); + return 0; + } + memset (pout, *pin, block_size); + pout += block_size; + pin++; + break; + + case 2: + { + const unsigned char *pblockend; + unsigned char *plitstack; + unsigned char *plit; + uint32_t literal_count; + unsigned char seq_hdr; + size_t seq_count; + size_t seq; + const unsigned char *pback; + uint64_t val; + unsigned int bits; + unsigned int literal_state; + unsigned int offset_state; + unsigned int match_state; + + /* Compressed_Block */ + if (unlikely ((size_t) block_size > (size_t) (pinend - pin))) + { + elf_uncompress_failed (); + return 0; + } + + pblockend = pin + block_size; + + /* Read the literals into the end of the output space, and leave + PLIT pointing at them. */ + + if (!elf_zstd_read_literals (&pin, pblockend, pout, poutend, + scratch, huffman_table, + &huffman_table_bits, + &plitstack)) + return 0; + plit = plitstack; + literal_count = poutend - plit; + + seq_hdr = *pin; + pin++; + if (seq_hdr < 128) + seq_count = seq_hdr; + else if (seq_hdr < 255) + { + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_count = ((seq_hdr - 128) << 8) + *pin; + pin++; + } + else + { + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_count = *pin + (pin[1] << 8) + 0x7f00; + pin += 2; + } + + if (seq_count > 0) + { + int (*pfn)(const struct elf_zstd_fse_entry *, + int, struct elf_zstd_fse_baseline_entry *); + + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_hdr = *pin; + ++pin; + + pfn = elf_zstd_make_literal_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 6) & 3, + &pin, pinend, + &elf_zstd_lit_table[0], 6, + scratch, 35, + literal_fse_table, 9, pfn, + &literal_decode)) + return 0; + + pfn = elf_zstd_make_offset_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 4) & 3, + &pin, pinend, + &elf_zstd_offset_table[0], 5, + scratch, 31, + offset_fse_table, 8, pfn, + &offset_decode)) + return 0; + + pfn = elf_zstd_make_match_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 2) & 3, + &pin, pinend, + &elf_zstd_match_table[0], 6, + scratch, 52, + match_fse_table, 9, pfn, + &match_decode)) + return 0; + } + + pback = pblockend - 1; + if (!elf_fetch_backward_init (&pback, pin, &val, &bits)) + return 0; + + bits -= literal_decode.table_bits; + literal_state = ((val >> bits) + & ((1U << literal_decode.table_bits) - 1)); + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= offset_decode.table_bits; + offset_state = ((val >> bits) + & ((1U << offset_decode.table_bits) - 1)); + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= match_decode.table_bits; + match_state = ((val >> bits) + & ((1U << match_decode.table_bits) - 1)); + + seq = 0; + while (1) + { + const struct elf_zstd_fse_baseline_entry *pt; + uint32_t offset_basebits; + uint32_t offset_baseline; + uint32_t offset_bits; + uint32_t offset_base; + uint32_t offset; + uint32_t match_baseline; + uint32_t match_bits; + uint32_t match_base; + uint32_t match; + uint32_t literal_baseline; + uint32_t literal_bits; + uint32_t literal_base; + uint32_t literal; + uint32_t need; + uint32_t add; + + pt = &offset_decode.table[offset_state]; + offset_basebits = pt->basebits; + offset_baseline = pt->baseline; + offset_bits = pt->bits; + offset_base = pt->base; + + /* This case can be more than 16 bits, which is all that + elf_fetch_bits_backward promises. */ + need = offset_basebits; + add = 0; + if (unlikely (need > 16)) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= 16; + add = (val >> bits) & ((1U << 16) - 1); + need -= 16; + add <<= need; + } + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add += (val >> bits) & ((1U << need) - 1); + } + + offset = offset_baseline + add; + + pt = &match_decode.table[match_state]; + need = pt->basebits; + match_baseline = pt->baseline; + match_bits = pt->bits; + match_base = pt->base; + + add = 0; + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add = (val >> bits) & ((1U << need) - 1); + } + + match = match_baseline + add; + + pt = &literal_decode.table[literal_state]; + need = pt->basebits; + literal_baseline = pt->baseline; + literal_bits = pt->bits; + literal_base = pt->base; + + add = 0; + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add = (val >> bits) & ((1U << need) - 1); + } + + literal = literal_baseline + add; + + /* See the comment in elf_zstd_make_offset_baseline_fse. */ + if (offset_basebits > 1) + { + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + } + else + { + if (unlikely (literal == 0)) + ++offset; + switch (offset) + { + case 1: + offset = repeated_offset1; + break; + case 2: + offset = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + case 3: + offset = repeated_offset3; + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + case 4: + offset = repeated_offset1 - 1; + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + } + } + + ++seq; + if (seq < seq_count) + { + uint32_t v; + + /* Update the three states. */ + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = literal_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + literal_state = literal_base + v; + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = match_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + match_state = match_base + v; + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = offset_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + offset_state = offset_base + v; + } + + /* The next sequence is now in LITERAL, OFFSET, MATCH. */ + + /* Copy LITERAL bytes from the literals. */ + + if (unlikely ((size_t)(poutend - pout) < literal)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely (literal_count < literal)) + { + elf_uncompress_failed (); + return 0; + } + + literal_count -= literal; + + /* Often LITERAL is small, so handle small cases quickly. */ + switch (literal) + { + case 8: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 7: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 6: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 5: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 4: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 3: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 2: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 1: + *pout++ = *plit++; + break; + + case 0: + break; + + default: + if (unlikely ((size_t)(plit - pout) < literal)) + { + uint32_t move; + + move = plit - pout; + while (literal > move) + { + memcpy (pout, plit, move); + pout += move; + plit += move; + literal -= move; + } + } + + memcpy (pout, plit, literal); + pout += literal; + plit += literal; + } + + if (match > 0) + { + /* Copy MATCH bytes from the decoded output at OFFSET. */ + + if (unlikely ((size_t)(poutend - pout) < match)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((size_t)(pout - poutstart) < offset)) + { + elf_uncompress_failed (); + return 0; + } + + if (offset >= match) + { + memcpy (pout, pout - offset, match); + pout += match; + } + else + { + while (match > 0) + { + uint32_t copy; + + copy = match < offset ? match : offset; + memcpy (pout, pout - offset, copy); + match -= copy; + pout += copy; + } + } + } + + if (unlikely (seq >= seq_count)) + { + /* Copy remaining literals. */ + if (literal_count > 0 && plit != pout) + { + if (unlikely ((size_t)(poutend - pout) + < literal_count)) + { + elf_uncompress_failed (); + return 0; + } + + if ((size_t)(plit - pout) < literal_count) + { + uint32_t move; + + move = plit - pout; + while (literal_count > move) + { + memcpy (pout, plit, move); + pout += move; + plit += move; + literal_count -= move; + } + } + + memcpy (pout, plit, literal_count); + } + + pout += literal_count; + + break; + } + } + + pin = pblockend; + } + break; + + case 3: + default: + elf_uncompress_failed (); + return 0; + } + } + + if (has_checksum) + { + if (unlikely (pin + 4 > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* We don't currently verify the checksum. Currently running GNU ld with + --compress-debug-sections=zstd does not seem to generate a + checksum. */ + + pin += 4; + } + + if (pin != pinend) + { + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +#define ZDEBUG_TABLE_SIZE \ + (ZLIB_TABLE_SIZE > ZSTD_TABLE_SIZE ? ZLIB_TABLE_SIZE : ZSTD_TABLE_SIZE) + +/* Uncompress the old compressed debug format, the one emitted by + --compress-debug-sections=zlib-gnu. The compressed data is in + COMPRESSED / COMPRESSED_SIZE, and the function writes to + *UNCOMPRESSED / *UNCOMPRESSED_SIZE. ZDEBUG_TABLE is work space to + hold Huffman tables. Returns 0 on error, 1 on successful + decompression or if something goes wrong. In general we try to + carry on, by returning 1, even if we can't decompress. */ + +static int +elf_uncompress_zdebug (struct backtrace_state *state, + const unsigned char *compressed, size_t compressed_size, + uint16_t *zdebug_table, + backtrace_error_callback error_callback, void *data, + unsigned char **uncompressed, size_t *uncompressed_size) +{ + size_t sz; + size_t i; + unsigned char *po; + + *uncompressed = NULL; + *uncompressed_size = 0; + + /* The format starts with the four bytes ZLIB, followed by the 8 + byte length of the uncompressed data in big-endian order, + followed by a zlib stream. */ + + if (compressed_size < 12 || memcmp (compressed, "ZLIB", 4) != 0) + return 1; + + sz = 0; + for (i = 0; i < 8; i++) + sz = (sz << 8) | compressed[i + 4]; + + if (*uncompressed != NULL && *uncompressed_size >= sz) + po = *uncompressed; + else + { + po = (unsigned char *) backtrace_alloc (state, sz, error_callback, data); + if (po == NULL) + return 0; + } + + if (!elf_zlib_inflate_and_verify (compressed + 12, compressed_size - 12, + zdebug_table, po, sz)) + return 1; + + *uncompressed = po; + *uncompressed_size = sz; + + return 1; +} + +/* Uncompress the new compressed debug format, the official standard + ELF approach emitted by --compress-debug-sections=zlib-gabi. The + compressed data is in COMPRESSED / COMPRESSED_SIZE, and the + function writes to *UNCOMPRESSED / *UNCOMPRESSED_SIZE. + ZDEBUG_TABLE is work space as for elf_uncompress_zdebug. Returns 0 + on error, 1 on successful decompression or if something goes wrong. + In general we try to carry on, by returning 1, even if we can't + decompress. */ + +static int +elf_uncompress_chdr (struct backtrace_state *state, + const unsigned char *compressed, size_t compressed_size, + uint16_t *zdebug_table, + backtrace_error_callback error_callback, void *data, + unsigned char **uncompressed, size_t *uncompressed_size) +{ + const b_elf_chdr *chdr; + char *alc; + size_t alc_len; + unsigned char *po; + + *uncompressed = NULL; + *uncompressed_size = 0; + + /* The format starts with an ELF compression header. */ + if (compressed_size < sizeof (b_elf_chdr)) + return 1; + + chdr = (const b_elf_chdr *) compressed; + + alc = NULL; + alc_len = 0; + if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size) + po = *uncompressed; + else + { + alc_len = chdr->ch_size; + alc = (char*)backtrace_alloc (state, alc_len, error_callback, data); + if (alc == NULL) + return 0; + po = (unsigned char *) alc; + } + + switch (chdr->ch_type) + { + case ELFCOMPRESS_ZLIB: + if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr), + compressed_size - sizeof (b_elf_chdr), + zdebug_table, po, chdr->ch_size)) + goto skip; + break; + + case ELFCOMPRESS_ZSTD: + if (!elf_zstd_decompress (compressed + sizeof (b_elf_chdr), + compressed_size - sizeof (b_elf_chdr), + (unsigned char *)zdebug_table, po, + chdr->ch_size)) + goto skip; + break; + + default: + /* Unsupported compression algorithm. */ + goto skip; + } + + *uncompressed = po; + *uncompressed_size = chdr->ch_size; + + return 1; + + skip: + if (alc != NULL && alc_len > 0) + backtrace_free (state, alc, alc_len, error_callback, data); + return 1; +} + +/* This function is a hook for testing the zlib support. It is only + used by tests. */ + +int +backtrace_uncompress_zdebug (struct backtrace_state *state, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback error_callback, + void *data, unsigned char **uncompressed, + size_t *uncompressed_size) +{ + uint16_t *zdebug_table; + int ret; + + zdebug_table = ((uint16_t *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + return 0; + ret = elf_uncompress_zdebug (state, compressed, compressed_size, + zdebug_table, error_callback, data, + uncompressed, uncompressed_size); + backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, + error_callback, data); + return ret; +} + +/* This function is a hook for testing the zstd support. It is only used by + tests. */ + +int +backtrace_uncompress_zstd (struct backtrace_state *state, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback error_callback, + void *data, unsigned char *uncompressed, + size_t uncompressed_size) +{ + unsigned char *zdebug_table; + int ret; + + zdebug_table = ((unsigned char *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + return 0; + ret = elf_zstd_decompress (compressed, compressed_size, + zdebug_table, uncompressed, uncompressed_size); + backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, + error_callback, data); + return ret; +} + +/* Number of LZMA states. */ +#define LZMA_STATES (12) + +/* Number of LZMA position states. The pb value of the property byte + is the number of bits to include in these states, and the maximum + value of pb is 4. */ +#define LZMA_POS_STATES (16) + +/* Number of LZMA distance states. These are used match distances + with a short match length: up to 4 bytes. */ +#define LZMA_DIST_STATES (4) + +/* Number of LZMA distance slots. LZMA uses six bits to encode larger + match lengths, so 1 << 6 possible probabilities. */ +#define LZMA_DIST_SLOTS (64) + +/* LZMA distances 0 to 3 are encoded directly, larger values use a + probability model. */ +#define LZMA_DIST_MODEL_START (4) + +/* The LZMA probability model ends at 14. */ +#define LZMA_DIST_MODEL_END (14) + +/* LZMA distance slots for distances less than 127. */ +#define LZMA_FULL_DISTANCES (128) + +/* LZMA uses four alignment bits. */ +#define LZMA_ALIGN_SIZE (16) + +/* LZMA match length is encoded with 4, 5, or 10 bits, some of which + are already known. */ +#define LZMA_LEN_LOW_SYMBOLS (8) +#define LZMA_LEN_MID_SYMBOLS (8) +#define LZMA_LEN_HIGH_SYMBOLS (256) + +/* LZMA literal encoding. */ +#define LZMA_LITERAL_CODERS_MAX (16) +#define LZMA_LITERAL_CODER_SIZE (0x300) + +/* LZMA is based on a large set of probabilities, each managed + independently. Each probability is an 11 bit number that we store + in a uint16_t. We use a single large array of probabilities. */ + +/* Lengths of entries in the LZMA probabilities array. The names used + here are copied from the Linux kernel implementation. */ + +#define LZMA_PROB_IS_MATCH_LEN (LZMA_STATES * LZMA_POS_STATES) +#define LZMA_PROB_IS_REP_LEN LZMA_STATES +#define LZMA_PROB_IS_REP0_LEN LZMA_STATES +#define LZMA_PROB_IS_REP1_LEN LZMA_STATES +#define LZMA_PROB_IS_REP2_LEN LZMA_STATES +#define LZMA_PROB_IS_REP0_LONG_LEN (LZMA_STATES * LZMA_POS_STATES) +#define LZMA_PROB_DIST_SLOT_LEN (LZMA_DIST_STATES * LZMA_DIST_SLOTS) +#define LZMA_PROB_DIST_SPECIAL_LEN (LZMA_FULL_DISTANCES - LZMA_DIST_MODEL_END) +#define LZMA_PROB_DIST_ALIGN_LEN LZMA_ALIGN_SIZE +#define LZMA_PROB_MATCH_LEN_CHOICE_LEN 1 +#define LZMA_PROB_MATCH_LEN_CHOICE2_LEN 1 +#define LZMA_PROB_MATCH_LEN_LOW_LEN (LZMA_POS_STATES * LZMA_LEN_LOW_SYMBOLS) +#define LZMA_PROB_MATCH_LEN_MID_LEN (LZMA_POS_STATES * LZMA_LEN_MID_SYMBOLS) +#define LZMA_PROB_MATCH_LEN_HIGH_LEN LZMA_LEN_HIGH_SYMBOLS +#define LZMA_PROB_REP_LEN_CHOICE_LEN 1 +#define LZMA_PROB_REP_LEN_CHOICE2_LEN 1 +#define LZMA_PROB_REP_LEN_LOW_LEN (LZMA_POS_STATES * LZMA_LEN_LOW_SYMBOLS) +#define LZMA_PROB_REP_LEN_MID_LEN (LZMA_POS_STATES * LZMA_LEN_MID_SYMBOLS) +#define LZMA_PROB_REP_LEN_HIGH_LEN LZMA_LEN_HIGH_SYMBOLS +#define LZMA_PROB_LITERAL_LEN \ + (LZMA_LITERAL_CODERS_MAX * LZMA_LITERAL_CODER_SIZE) + +/* Offsets into the LZMA probabilities array. This is mechanically + generated from the above lengths. */ + +#define LZMA_PROB_IS_MATCH_OFFSET 0 +#define LZMA_PROB_IS_REP_OFFSET \ + (LZMA_PROB_IS_MATCH_OFFSET + LZMA_PROB_IS_MATCH_LEN) +#define LZMA_PROB_IS_REP0_OFFSET \ + (LZMA_PROB_IS_REP_OFFSET + LZMA_PROB_IS_REP_LEN) +#define LZMA_PROB_IS_REP1_OFFSET \ + (LZMA_PROB_IS_REP0_OFFSET + LZMA_PROB_IS_REP0_LEN) +#define LZMA_PROB_IS_REP2_OFFSET \ + (LZMA_PROB_IS_REP1_OFFSET + LZMA_PROB_IS_REP1_LEN) +#define LZMA_PROB_IS_REP0_LONG_OFFSET \ + (LZMA_PROB_IS_REP2_OFFSET + LZMA_PROB_IS_REP2_LEN) +#define LZMA_PROB_DIST_SLOT_OFFSET \ + (LZMA_PROB_IS_REP0_LONG_OFFSET + LZMA_PROB_IS_REP0_LONG_LEN) +#define LZMA_PROB_DIST_SPECIAL_OFFSET \ + (LZMA_PROB_DIST_SLOT_OFFSET + LZMA_PROB_DIST_SLOT_LEN) +#define LZMA_PROB_DIST_ALIGN_OFFSET \ + (LZMA_PROB_DIST_SPECIAL_OFFSET + LZMA_PROB_DIST_SPECIAL_LEN) +#define LZMA_PROB_MATCH_LEN_CHOICE_OFFSET \ + (LZMA_PROB_DIST_ALIGN_OFFSET + LZMA_PROB_DIST_ALIGN_LEN) +#define LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET \ + (LZMA_PROB_MATCH_LEN_CHOICE_OFFSET + LZMA_PROB_MATCH_LEN_CHOICE_LEN) +#define LZMA_PROB_MATCH_LEN_LOW_OFFSET \ + (LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET + LZMA_PROB_MATCH_LEN_CHOICE2_LEN) +#define LZMA_PROB_MATCH_LEN_MID_OFFSET \ + (LZMA_PROB_MATCH_LEN_LOW_OFFSET + LZMA_PROB_MATCH_LEN_LOW_LEN) +#define LZMA_PROB_MATCH_LEN_HIGH_OFFSET \ + (LZMA_PROB_MATCH_LEN_MID_OFFSET + LZMA_PROB_MATCH_LEN_MID_LEN) +#define LZMA_PROB_REP_LEN_CHOICE_OFFSET \ + (LZMA_PROB_MATCH_LEN_HIGH_OFFSET + LZMA_PROB_MATCH_LEN_HIGH_LEN) +#define LZMA_PROB_REP_LEN_CHOICE2_OFFSET \ + (LZMA_PROB_REP_LEN_CHOICE_OFFSET + LZMA_PROB_REP_LEN_CHOICE_LEN) +#define LZMA_PROB_REP_LEN_LOW_OFFSET \ + (LZMA_PROB_REP_LEN_CHOICE2_OFFSET + LZMA_PROB_REP_LEN_CHOICE2_LEN) +#define LZMA_PROB_REP_LEN_MID_OFFSET \ + (LZMA_PROB_REP_LEN_LOW_OFFSET + LZMA_PROB_REP_LEN_LOW_LEN) +#define LZMA_PROB_REP_LEN_HIGH_OFFSET \ + (LZMA_PROB_REP_LEN_MID_OFFSET + LZMA_PROB_REP_LEN_MID_LEN) +#define LZMA_PROB_LITERAL_OFFSET \ + (LZMA_PROB_REP_LEN_HIGH_OFFSET + LZMA_PROB_REP_LEN_HIGH_LEN) + +#define LZMA_PROB_TOTAL_COUNT \ + (LZMA_PROB_LITERAL_OFFSET + LZMA_PROB_LITERAL_LEN) + +/* Check that the number of LZMA probabilities is the same as the + Linux kernel implementation. */ + +#if LZMA_PROB_TOTAL_COUNT != 1846 + (1 << 4) * 0x300 + #error Wrong number of LZMA probabilities +#endif + +/* Expressions for the offset in the LZMA probabilities array of a + specific probability. */ + +#define LZMA_IS_MATCH(state, pos) \ + (LZMA_PROB_IS_MATCH_OFFSET + (state) * LZMA_POS_STATES + (pos)) +#define LZMA_IS_REP(state) \ + (LZMA_PROB_IS_REP_OFFSET + (state)) +#define LZMA_IS_REP0(state) \ + (LZMA_PROB_IS_REP0_OFFSET + (state)) +#define LZMA_IS_REP1(state) \ + (LZMA_PROB_IS_REP1_OFFSET + (state)) +#define LZMA_IS_REP2(state) \ + (LZMA_PROB_IS_REP2_OFFSET + (state)) +#define LZMA_IS_REP0_LONG(state, pos) \ + (LZMA_PROB_IS_REP0_LONG_OFFSET + (state) * LZMA_POS_STATES + (pos)) +#define LZMA_DIST_SLOT(dist, slot) \ + (LZMA_PROB_DIST_SLOT_OFFSET + (dist) * LZMA_DIST_SLOTS + (slot)) +#define LZMA_DIST_SPECIAL(dist) \ + (LZMA_PROB_DIST_SPECIAL_OFFSET + (dist)) +#define LZMA_DIST_ALIGN(dist) \ + (LZMA_PROB_DIST_ALIGN_OFFSET + (dist)) +#define LZMA_MATCH_LEN_CHOICE \ + LZMA_PROB_MATCH_LEN_CHOICE_OFFSET +#define LZMA_MATCH_LEN_CHOICE2 \ + LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET +#define LZMA_MATCH_LEN_LOW(pos, sym) \ + (LZMA_PROB_MATCH_LEN_LOW_OFFSET + (pos) * LZMA_LEN_LOW_SYMBOLS + (sym)) +#define LZMA_MATCH_LEN_MID(pos, sym) \ + (LZMA_PROB_MATCH_LEN_MID_OFFSET + (pos) * LZMA_LEN_MID_SYMBOLS + (sym)) +#define LZMA_MATCH_LEN_HIGH(sym) \ + (LZMA_PROB_MATCH_LEN_HIGH_OFFSET + (sym)) +#define LZMA_REP_LEN_CHOICE \ + LZMA_PROB_REP_LEN_CHOICE_OFFSET +#define LZMA_REP_LEN_CHOICE2 \ + LZMA_PROB_REP_LEN_CHOICE2_OFFSET +#define LZMA_REP_LEN_LOW(pos, sym) \ + (LZMA_PROB_REP_LEN_LOW_OFFSET + (pos) * LZMA_LEN_LOW_SYMBOLS + (sym)) +#define LZMA_REP_LEN_MID(pos, sym) \ + (LZMA_PROB_REP_LEN_MID_OFFSET + (pos) * LZMA_LEN_MID_SYMBOLS + (sym)) +#define LZMA_REP_LEN_HIGH(sym) \ + (LZMA_PROB_REP_LEN_HIGH_OFFSET + (sym)) +#define LZMA_LITERAL(code, size) \ + (LZMA_PROB_LITERAL_OFFSET + (code) * LZMA_LITERAL_CODER_SIZE + (size)) + +/* Read an LZMA varint from BUF, reading and updating *POFFSET, + setting *VAL. Returns 0 on error, 1 on success. */ + +static int +elf_lzma_varint (const unsigned char *compressed, size_t compressed_size, + size_t *poffset, uint64_t *val) +{ + size_t off; + int i; + uint64_t v; + unsigned char b; + + off = *poffset; + i = 0; + v = 0; + while (1) + { + if (unlikely (off >= compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + b = compressed[off]; + v |= (b & 0x7f) << (i * 7); + ++off; + if ((b & 0x80) == 0) + { + *poffset = off; + *val = v; + return 1; + } + ++i; + if (unlikely (i >= 9)) + { + elf_uncompress_failed (); + return 0; + } + } +} + +/* Normalize the LZMA range decoder, pulling in an extra input byte if + needed. */ + +static void +elf_lzma_range_normalize (const unsigned char *compressed, + size_t compressed_size, size_t *poffset, + uint32_t *prange, uint32_t *pcode) +{ + if (*prange < (1U << 24)) + { + if (unlikely (*poffset >= compressed_size)) + { + /* We assume this will be caught elsewhere. */ + elf_uncompress_failed (); + return; + } + *prange <<= 8; + *pcode <<= 8; + *pcode += compressed[*poffset]; + ++*poffset; + } +} + +/* Read and return a single bit from the LZMA stream, reading and + updating *PROB. Each bit comes from the range coder. */ + +static int +elf_lzma_bit (const unsigned char *compressed, size_t compressed_size, + uint16_t *prob, size_t *poffset, uint32_t *prange, + uint32_t *pcode) +{ + uint32_t bound; + + elf_lzma_range_normalize (compressed, compressed_size, poffset, + prange, pcode); + bound = (*prange >> 11) * (uint32_t) *prob; + if (*pcode < bound) + { + *prange = bound; + *prob += ((1U << 11) - *prob) >> 5; + return 0; + } + else + { + *prange -= bound; + *pcode -= bound; + *prob -= *prob >> 5; + return 1; + } +} + +/* Read an integer of size BITS from the LZMA stream, most significant + bit first. The bits are predicted using PROBS. */ + +static uint32_t +elf_lzma_integer (const unsigned char *compressed, size_t compressed_size, + uint16_t *probs, uint32_t bits, size_t *poffset, + uint32_t *prange, uint32_t *pcode) +{ + uint32_t sym; + uint32_t i; + + sym = 1; + for (i = 0; i < bits; i++) + { + int bit; + + bit = elf_lzma_bit (compressed, compressed_size, probs + sym, poffset, + prange, pcode); + sym <<= 1; + sym += bit; + } + return sym - (1 << bits); +} + +/* Read an integer of size BITS from the LZMA stream, least + significant bit first. The bits are predicted using PROBS. */ + +static uint32_t +elf_lzma_reverse_integer (const unsigned char *compressed, + size_t compressed_size, uint16_t *probs, + uint32_t bits, size_t *poffset, uint32_t *prange, + uint32_t *pcode) +{ + uint32_t sym; + uint32_t val; + uint32_t i; + + sym = 1; + val = 0; + for (i = 0; i < bits; i++) + { + int bit; + + bit = elf_lzma_bit (compressed, compressed_size, probs + sym, poffset, + prange, pcode); + sym <<= 1; + sym += bit; + val += bit << i; + } + return val; +} + +/* Read a length from the LZMA stream. IS_REP picks either LZMA_MATCH + or LZMA_REP probabilities. */ + +static uint32_t +elf_lzma_len (const unsigned char *compressed, size_t compressed_size, + uint16_t *probs, int is_rep, unsigned int pos_state, + size_t *poffset, uint32_t *prange, uint32_t *pcode) +{ + uint16_t *probs_choice; + uint16_t *probs_sym; + uint32_t bits; + uint32_t len; + + probs_choice = probs + (is_rep + ? LZMA_REP_LEN_CHOICE + : LZMA_MATCH_LEN_CHOICE); + if (elf_lzma_bit (compressed, compressed_size, probs_choice, poffset, + prange, pcode)) + { + probs_choice = probs + (is_rep + ? LZMA_REP_LEN_CHOICE2 + : LZMA_MATCH_LEN_CHOICE2); + if (elf_lzma_bit (compressed, compressed_size, probs_choice, + poffset, prange, pcode)) + { + probs_sym = probs + (is_rep + ? LZMA_REP_LEN_HIGH (0) + : LZMA_MATCH_LEN_HIGH (0)); + bits = 8; + len = 2 + 8 + 8; + } + else + { + probs_sym = probs + (is_rep + ? LZMA_REP_LEN_MID (pos_state, 0) + : LZMA_MATCH_LEN_MID (pos_state, 0)); + bits = 3; + len = 2 + 8; + } + } + else + { + probs_sym = probs + (is_rep + ? LZMA_REP_LEN_LOW (pos_state, 0) + : LZMA_MATCH_LEN_LOW (pos_state, 0)); + bits = 3; + len = 2; + } + + len += elf_lzma_integer (compressed, compressed_size, probs_sym, bits, + poffset, prange, pcode); + return len; +} + +/* Uncompress one LZMA block from a minidebug file. The compressed + data is at COMPRESSED + *POFFSET. Update *POFFSET. Store the data + into the memory at UNCOMPRESSED, size UNCOMPRESSED_SIZE. CHECK is + the stream flag from the xz header. Return 1 on successful + decompression. */ + +static int +elf_uncompress_lzma_block (const unsigned char *compressed, + size_t compressed_size, unsigned char check, + uint16_t *probs, unsigned char *uncompressed, + size_t uncompressed_size, size_t *poffset) +{ + size_t off; + size_t block_header_offset; + size_t block_header_size; + unsigned char block_flags; + uint64_t header_compressed_size; + uint64_t header_uncompressed_size; + unsigned char lzma2_properties; + uint32_t computed_crc; + uint32_t stream_crc; + size_t uncompressed_offset; + size_t dict_start_offset; + unsigned int lc; + unsigned int lp; + unsigned int pb; + uint32_t range; + uint32_t code; + uint32_t lstate; + uint32_t dist[4]; + + off = *poffset; + block_header_offset = off; + + /* Block header size is a single byte. */ + if (unlikely (off >= compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + block_header_size = (compressed[off] + 1) * 4; + if (unlikely (off + block_header_size > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + /* Block flags. */ + block_flags = compressed[off + 1]; + if (unlikely ((block_flags & 0x3c) != 0)) + { + elf_uncompress_failed (); + return 0; + } + + off += 2; + + /* Optional compressed size. */ + header_compressed_size = 0; + if ((block_flags & 0x40) != 0) + { + *poffset = off; + if (!elf_lzma_varint (compressed, compressed_size, poffset, + &header_compressed_size)) + return 0; + off = *poffset; + } + + /* Optional uncompressed size. */ + header_uncompressed_size = 0; + if ((block_flags & 0x80) != 0) + { + *poffset = off; + if (!elf_lzma_varint (compressed, compressed_size, poffset, + &header_uncompressed_size)) + return 0; + off = *poffset; + } + + /* The recipe for creating a minidebug file is to run the xz program + with no arguments, so we expect exactly one filter: lzma2. */ + + if (unlikely ((block_flags & 0x3) != 0)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely (off + 2 >= block_header_offset + block_header_size)) + { + elf_uncompress_failed (); + return 0; + } + + /* The filter ID for LZMA2 is 0x21. */ + if (unlikely (compressed[off] != 0x21)) + { + elf_uncompress_failed (); + return 0; + } + ++off; + + /* The size of the filter properties for LZMA2 is 1. */ + if (unlikely (compressed[off] != 1)) + { + elf_uncompress_failed (); + return 0; + } + ++off; + + lzma2_properties = compressed[off]; + ++off; + + if (unlikely (lzma2_properties > 40)) + { + elf_uncompress_failed (); + return 0; + } + + /* The properties describe the dictionary size, but we don't care + what that is. */ + + /* Block header padding. */ + if (unlikely (off + 4 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + off = (off + 3) &~ (size_t) 3; + + if (unlikely (off + 4 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + /* Block header CRC. */ + computed_crc = elf_crc32 (0, compressed + block_header_offset, + block_header_size - 4); + stream_crc = (compressed[off] + | (compressed[off + 1] << 8) + | (compressed[off + 2] << 16) + | (compressed[off + 3] << 24)); + if (unlikely (computed_crc != stream_crc)) + { + elf_uncompress_failed (); + return 0; + } + off += 4; + + /* Read a sequence of LZMA2 packets. */ + + uncompressed_offset = 0; + dict_start_offset = 0; + lc = 0; + lp = 0; + pb = 0; + lstate = 0; + while (off < compressed_size) + { + unsigned char control; + + range = 0xffffffff; + code = 0; + + control = compressed[off]; + ++off; + if (unlikely (control == 0)) + { + /* End of packets. */ + break; + } + + if (control == 1 || control >= 0xe0) + { + /* Reset dictionary to empty. */ + dict_start_offset = uncompressed_offset; + } + + if (control < 0x80) + { + size_t chunk_size; + + /* The only valid values here are 1 or 2. A 1 means to + reset the dictionary (done above). Then we see an + uncompressed chunk. */ + + if (unlikely (control > 2)) + { + elf_uncompress_failed (); + return 0; + } + + /* An uncompressed chunk is a two byte size followed by + data. */ + + if (unlikely (off + 2 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + chunk_size = compressed[off] << 8; + chunk_size += compressed[off + 1]; + ++chunk_size; + + off += 2; + + if (unlikely (off + chunk_size > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely (uncompressed_offset + chunk_size > uncompressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + memcpy (uncompressed + uncompressed_offset, compressed + off, + chunk_size); + uncompressed_offset += chunk_size; + off += chunk_size; + } + else + { + size_t uncompressed_chunk_start; + size_t uncompressed_chunk_size; + size_t compressed_chunk_size; + size_t limit; + + /* An LZMA chunk. This starts with an uncompressed size and + a compressed size. */ + + if (unlikely (off + 4 >= compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + uncompressed_chunk_start = uncompressed_offset; + + uncompressed_chunk_size = (control & 0x1f) << 16; + uncompressed_chunk_size += compressed[off] << 8; + uncompressed_chunk_size += compressed[off + 1]; + ++uncompressed_chunk_size; + + compressed_chunk_size = compressed[off + 2] << 8; + compressed_chunk_size += compressed[off + 3]; + ++compressed_chunk_size; + + off += 4; + + /* Bit 7 (0x80) is set. + Bits 6 and 5 (0x40 and 0x20) are as follows: + 0: don't reset anything + 1: reset state + 2: reset state, read properties + 3: reset state, read properties, reset dictionary (done above) */ + + if (control >= 0xc0) + { + unsigned char props; + + /* Bit 6 is set, read properties. */ + + if (unlikely (off >= compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + props = compressed[off]; + ++off; + if (unlikely (props > (4 * 5 + 4) * 9 + 8)) + { + elf_uncompress_failed (); + return 0; + } + pb = 0; + while (props >= 9 * 5) + { + props -= 9 * 5; + ++pb; + } + lp = 0; + while (props > 9) + { + props -= 9; + ++lp; + } + lc = props; + if (unlikely (lc + lp > 4)) + { + elf_uncompress_failed (); + return 0; + } + } + + if (control >= 0xa0) + { + size_t i; + + /* Bit 5 or 6 is set, reset LZMA state. */ + + lstate = 0; + memset (&dist, 0, sizeof dist); + for (i = 0; i < LZMA_PROB_TOTAL_COUNT; i++) + probs[i] = 1 << 10; + range = 0xffffffff; + code = 0; + } + + /* Read the range code. */ + + if (unlikely (off + 5 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + /* The byte at compressed[off] is ignored for some + reason. */ + + code = ((compressed[off + 1] << 24) + + (compressed[off + 2] << 16) + + (compressed[off + 3] << 8) + + compressed[off + 4]); + off += 5; + + /* This is the main LZMA decode loop. */ + + limit = off + compressed_chunk_size; + *poffset = off; + while (*poffset < limit) + { + unsigned int pos_state; + + if (unlikely (uncompressed_offset + == (uncompressed_chunk_start + + uncompressed_chunk_size))) + { + /* We've decompressed all the expected bytes. */ + break; + } + + pos_state = ((uncompressed_offset - dict_start_offset) + & ((1 << pb) - 1)); + + if (elf_lzma_bit (compressed, compressed_size, + probs + LZMA_IS_MATCH (lstate, pos_state), + poffset, &range, &code)) + { + uint32_t len; + + if (elf_lzma_bit (compressed, compressed_size, + probs + LZMA_IS_REP (lstate), + poffset, &range, &code)) + { + int short_rep; + uint32_t next_dist; + + /* Repeated match. */ + + short_rep = 0; + if (elf_lzma_bit (compressed, compressed_size, + probs + LZMA_IS_REP0 (lstate), + poffset, &range, &code)) + { + if (elf_lzma_bit (compressed, compressed_size, + probs + LZMA_IS_REP1 (lstate), + poffset, &range, &code)) + { + if (elf_lzma_bit (compressed, compressed_size, + probs + LZMA_IS_REP2 (lstate), + poffset, &range, &code)) + { + next_dist = dist[3]; + dist[3] = dist[2]; + } + else + { + next_dist = dist[2]; + } + dist[2] = dist[1]; + } + else + { + next_dist = dist[1]; + } + + dist[1] = dist[0]; + dist[0] = next_dist; + } + else + { + if (!elf_lzma_bit (compressed, compressed_size, + (probs + + LZMA_IS_REP0_LONG (lstate, + pos_state)), + poffset, &range, &code)) + short_rep = 1; + } + + if (lstate < 7) + lstate = short_rep ? 9 : 8; + else + lstate = 11; + + if (short_rep) + len = 1; + else + len = elf_lzma_len (compressed, compressed_size, + probs, 1, pos_state, poffset, + &range, &code); + } + else + { + uint32_t dist_state; + uint32_t dist_slot; + uint16_t *probs_dist; + + /* Match. */ + + if (lstate < 7) + lstate = 7; + else + lstate = 10; + dist[3] = dist[2]; + dist[2] = dist[1]; + dist[1] = dist[0]; + len = elf_lzma_len (compressed, compressed_size, + probs, 0, pos_state, poffset, + &range, &code); + + if (len < 4 + 2) + dist_state = len - 2; + else + dist_state = 3; + probs_dist = probs + LZMA_DIST_SLOT (dist_state, 0); + dist_slot = elf_lzma_integer (compressed, + compressed_size, + probs_dist, 6, + poffset, &range, + &code); + if (dist_slot < LZMA_DIST_MODEL_START) + dist[0] = dist_slot; + else + { + uint32_t limit; + + limit = (dist_slot >> 1) - 1; + dist[0] = 2 + (dist_slot & 1); + if (dist_slot < LZMA_DIST_MODEL_END) + { + dist[0] <<= limit; + probs_dist = (probs + + LZMA_DIST_SPECIAL(dist[0] + - dist_slot + - 1)); + dist[0] += + elf_lzma_reverse_integer (compressed, + compressed_size, + probs_dist, + limit, poffset, + &range, &code); + } + else + { + uint32_t dist0; + uint32_t i; + + dist0 = dist[0]; + for (i = 0; i < limit - 4; i++) + { + uint32_t mask; + + elf_lzma_range_normalize (compressed, + compressed_size, + poffset, + &range, &code); + range >>= 1; + code -= range; + mask = -(code >> 31); + code += range & mask; + dist0 <<= 1; + dist0 += mask + 1; + } + dist0 <<= 4; + probs_dist = probs + LZMA_DIST_ALIGN (0); + dist0 += + elf_lzma_reverse_integer (compressed, + compressed_size, + probs_dist, 4, + poffset, + &range, &code); + dist[0] = dist0; + } + } + } + + if (unlikely (uncompressed_offset + - dict_start_offset < dist[0] + 1)) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely (uncompressed_offset + len > uncompressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + if (dist[0] == 0) + { + /* A common case, meaning repeat the last + character LEN times. */ + memset (uncompressed + uncompressed_offset, + uncompressed[uncompressed_offset - 1], + len); + uncompressed_offset += len; + } + else if (dist[0] + 1 >= len) + { + memcpy (uncompressed + uncompressed_offset, + uncompressed + uncompressed_offset - dist[0] - 1, + len); + uncompressed_offset += len; + } + else + { + while (len > 0) + { + uint32_t copy; + + copy = len < dist[0] + 1 ? len : dist[0] + 1; + memcpy (uncompressed + uncompressed_offset, + (uncompressed + uncompressed_offset + - dist[0] - 1), + copy); + len -= copy; + uncompressed_offset += copy; + } + } + } + else + { + unsigned char prev; + unsigned char low; + size_t high; + uint16_t *lit_probs; + unsigned int sym; + + /* Literal value. */ + + if (uncompressed_offset > 0) + prev = uncompressed[uncompressed_offset - 1]; + else + prev = 0; + low = prev >> (8 - lc); + high = (((uncompressed_offset - dict_start_offset) + & ((1 << lp) - 1)) + << lc); + lit_probs = probs + LZMA_LITERAL (low + high, 0); + if (lstate < 7) + sym = elf_lzma_integer (compressed, compressed_size, + lit_probs, 8, poffset, &range, + &code); + else + { + unsigned int match; + unsigned int bit; + unsigned int match_bit; + unsigned int idx; + + sym = 1; + if (uncompressed_offset >= dist[0] + 1) + match = uncompressed[uncompressed_offset - dist[0] - 1]; + else + match = 0; + match <<= 1; + bit = 0x100; + do + { + match_bit = match & bit; + match <<= 1; + idx = bit + match_bit + sym; + sym <<= 1; + if (elf_lzma_bit (compressed, compressed_size, + lit_probs + idx, poffset, + &range, &code)) + { + ++sym; + bit &= match_bit; + } + else + { + bit &= ~ match_bit; + } + } + while (sym < 0x100); + } + + if (unlikely (uncompressed_offset >= uncompressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + uncompressed[uncompressed_offset] = (unsigned char) sym; + ++uncompressed_offset; + if (lstate <= 3) + lstate = 0; + else if (lstate <= 9) + lstate -= 3; + else + lstate -= 6; + } + } + + elf_lzma_range_normalize (compressed, compressed_size, poffset, + &range, &code); + + off = *poffset; + } + } + + /* We have reached the end of the block. Pad to four byte + boundary. */ + off = (off + 3) &~ (size_t) 3; + if (unlikely (off > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + + switch (check) + { + case 0: + /* No check. */ + break; + + case 1: + /* CRC32 */ + if (unlikely (off + 4 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + computed_crc = elf_crc32 (0, uncompressed, uncompressed_offset); + stream_crc = (compressed[off] + | (compressed[off + 1] << 8) + | (compressed[off + 2] << 16) + | (compressed[off + 3] << 24)); + if (computed_crc != stream_crc) + { + elf_uncompress_failed (); + return 0; + } + off += 4; + break; + + case 4: + /* CRC64. We don't bother computing a CRC64 checksum. */ + if (unlikely (off + 8 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + off += 8; + break; + + case 10: + /* SHA. We don't bother computing a SHA checksum. */ + if (unlikely (off + 32 > compressed_size)) + { + elf_uncompress_failed (); + return 0; + } + off += 32; + break; + + default: + elf_uncompress_failed (); + return 0; + } + + *poffset = off; + + return 1; +} + +/* Uncompress LZMA data found in a minidebug file. The minidebug + format is described at + https://sourceware.org/gdb/current/onlinedocs/gdb/MiniDebugInfo.html. + Returns 0 on error, 1 on successful decompression. For this + function we return 0 on failure to decompress, as the calling code + will carry on in that case. */ + +static int +elf_uncompress_lzma (struct backtrace_state *state, + const unsigned char *compressed, size_t compressed_size, + backtrace_error_callback error_callback, void *data, + unsigned char **uncompressed, size_t *uncompressed_size) +{ + size_t header_size; + size_t footer_size; + unsigned char check; + uint32_t computed_crc; + uint32_t stream_crc; + size_t offset; + size_t index_size; + size_t footer_offset; + size_t index_offset; + uint64_t index_compressed_size; + uint64_t index_uncompressed_size; + unsigned char *mem; + uint16_t *probs; + size_t compressed_block_size; + + /* The format starts with a stream header and ends with a stream + footer. */ + header_size = 12; + footer_size = 12; + if (unlikely (compressed_size < header_size + footer_size)) + { + elf_uncompress_failed (); + return 0; + } + + /* The stream header starts with a magic string. */ + if (unlikely (memcmp (compressed, "\375" "7zXZ\0", 6) != 0)) + { + elf_uncompress_failed (); + return 0; + } + + /* Next come stream flags. The first byte is zero, the second byte + is the check. */ + if (unlikely (compressed[6] != 0)) + { + elf_uncompress_failed (); + return 0; + } + check = compressed[7]; + if (unlikely ((check & 0xf8) != 0)) + { + elf_uncompress_failed (); + return 0; + } + + /* Next comes a CRC of the stream flags. */ + computed_crc = elf_crc32 (0, compressed + 6, 2); + stream_crc = (compressed[8] + | (compressed[9] << 8) + | (compressed[10] << 16) + | (compressed[11] << 24)); + if (unlikely (computed_crc != stream_crc)) + { + elf_uncompress_failed (); + return 0; + } + + /* Now that we've parsed the header, parse the footer, so that we + can get the uncompressed size. */ + + /* The footer ends with two magic bytes. */ + + offset = compressed_size; + if (unlikely (memcmp (compressed + offset - 2, "YZ", 2) != 0)) + { + elf_uncompress_failed (); + return 0; + } + offset -= 2; + + /* Before that are the stream flags, which should be the same as the + flags in the header. */ + if (unlikely (compressed[offset - 2] != 0 + || compressed[offset - 1] != check)) + { + elf_uncompress_failed (); + return 0; + } + offset -= 2; + + /* Before that is the size of the index field, which precedes the + footer. */ + index_size = (compressed[offset - 4] + | (compressed[offset - 3] << 8) + | (compressed[offset - 2] << 16) + | (compressed[offset - 1] << 24)); + index_size = (index_size + 1) * 4; + offset -= 4; + + /* Before that is a footer CRC. */ + computed_crc = elf_crc32 (0, compressed + offset, 6); + stream_crc = (compressed[offset - 4] + | (compressed[offset - 3] << 8) + | (compressed[offset - 2] << 16) + | (compressed[offset - 1] << 24)); + if (unlikely (computed_crc != stream_crc)) + { + elf_uncompress_failed (); + return 0; + } + offset -= 4; + + /* The index comes just before the footer. */ + if (unlikely (offset < index_size + header_size)) + { + elf_uncompress_failed (); + return 0; + } + + footer_offset = offset; + offset -= index_size; + index_offset = offset; + + /* The index starts with a zero byte. */ + if (unlikely (compressed[offset] != 0)) + { + elf_uncompress_failed (); + return 0; + } + ++offset; + + /* Next is the number of blocks. We expect zero blocks for an empty + stream, and otherwise a single block. */ + if (unlikely (compressed[offset] == 0)) + { + *uncompressed = NULL; + *uncompressed_size = 0; + return 1; + } + if (unlikely (compressed[offset] != 1)) + { + elf_uncompress_failed (); + return 0; + } + ++offset; + + /* Next is the compressed size and the uncompressed size. */ + if (!elf_lzma_varint (compressed, compressed_size, &offset, + &index_compressed_size)) + return 0; + if (!elf_lzma_varint (compressed, compressed_size, &offset, + &index_uncompressed_size)) + return 0; + + /* Pad to a four byte boundary. */ + offset = (offset + 3) &~ (size_t) 3; + + /* Next is a CRC of the index. */ + computed_crc = elf_crc32 (0, compressed + index_offset, + offset - index_offset); + stream_crc = (compressed[offset] + | (compressed[offset + 1] << 8) + | (compressed[offset + 2] << 16) + | (compressed[offset + 3] << 24)); + if (unlikely (computed_crc != stream_crc)) + { + elf_uncompress_failed (); + return 0; + } + offset += 4; + + /* We should now be back at the footer. */ + if (unlikely (offset != footer_offset)) + { + elf_uncompress_failed (); + return 0; + } + + /* Allocate space to hold the uncompressed data. If we succeed in + uncompressing the LZMA data, we never free this memory. */ + mem = (unsigned char *) backtrace_alloc (state, index_uncompressed_size, + error_callback, data); + if (unlikely (mem == NULL)) + return 0; + *uncompressed = mem; + *uncompressed_size = index_uncompressed_size; + + /* Allocate space for probabilities. */ + probs = ((uint16_t *) + backtrace_alloc (state, + LZMA_PROB_TOTAL_COUNT * sizeof (uint16_t), + error_callback, data)); + if (unlikely (probs == NULL)) + { + backtrace_free (state, mem, index_uncompressed_size, error_callback, + data); + return 0; + } + + /* Uncompress the block, which follows the header. */ + offset = 12; + if (!elf_uncompress_lzma_block (compressed, compressed_size, check, probs, + mem, index_uncompressed_size, &offset)) + { + backtrace_free (state, mem, index_uncompressed_size, error_callback, + data); + return 0; + } + + compressed_block_size = offset - 12; + if (unlikely (compressed_block_size + != ((index_compressed_size + 3) &~ (size_t) 3))) + { + elf_uncompress_failed (); + backtrace_free (state, mem, index_uncompressed_size, error_callback, + data); + return 0; + } + + offset = (offset + 3) &~ (size_t) 3; + if (unlikely (offset != index_offset)) + { + elf_uncompress_failed (); + backtrace_free (state, mem, index_uncompressed_size, error_callback, + data); + return 0; + } + + return 1; +} + +/* This function is a hook for testing the LZMA support. It is only + used by tests. */ + +int +backtrace_uncompress_lzma (struct backtrace_state *state, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback error_callback, + void *data, unsigned char **uncompressed, + size_t *uncompressed_size) +{ + return elf_uncompress_lzma (state, compressed, compressed_size, + error_callback, data, uncompressed, + uncompressed_size); +} + +/* Add the backtrace data for one ELF file. Returns 1 on success, + 0 on failure (in both cases descriptor is closed) or -1 if exe + is non-zero and the ELF file is ET_DYN, which tells the caller that + elf_add will need to be called on the descriptor again after + base_address is determined. */ + +static int +elf_add (struct backtrace_state *state, const char *filename, int descriptor, + const unsigned char *memory, size_t memory_size, + uintptr_t base_address, backtrace_error_callback error_callback, + void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf, + struct dwarf_data **fileline_entry, int exe, int debuginfo, + const char *with_buildid_data, uint32_t with_buildid_size) +{ + struct elf_view ehdr_view; + b_elf_ehdr ehdr; + off_t shoff; + unsigned int shnum; + unsigned int shstrndx; + struct elf_view shdrs_view; + int shdrs_view_valid; + const b_elf_shdr *shdrs; + const b_elf_shdr *shstrhdr; + size_t shstr_size; + off_t shstr_off; + struct elf_view names_view; + int names_view_valid; + const char *names; + unsigned int symtab_shndx; + unsigned int dynsym_shndx; + unsigned int i; + struct debug_section_info sections[DEBUG_MAX]; + struct debug_section_info zsections[DEBUG_MAX]; + struct elf_view symtab_view; + int symtab_view_valid; + struct elf_view strtab_view; + int strtab_view_valid; + struct elf_view buildid_view; + int buildid_view_valid; + const char *buildid_data; + uint32_t buildid_size; + struct elf_view debuglink_view; + int debuglink_view_valid; + const char *debuglink_name; + uint32_t debuglink_crc; + struct elf_view debugaltlink_view; + int debugaltlink_view_valid; + const char *debugaltlink_name; + const char *debugaltlink_buildid_data; + uint32_t debugaltlink_buildid_size; + struct elf_view gnu_debugdata_view; + int gnu_debugdata_view_valid; + size_t gnu_debugdata_size; + unsigned char *gnu_debugdata_uncompressed; + size_t gnu_debugdata_uncompressed_size; + off_t min_offset; + off_t max_offset; + off_t debug_size; + struct elf_view debug_view; + int debug_view_valid; + unsigned int using_debug_view; + uint16_t *zdebug_table; + struct elf_view split_debug_view[DEBUG_MAX]; + unsigned char split_debug_view_valid[DEBUG_MAX]; + struct elf_ppc64_opd_data opd_data, *opd; + struct dwarf_sections dwarf_sections; + struct dwarf_data *fileline_altlink = NULL; + + if (!debuginfo) + { + *found_sym = 0; + *found_dwarf = 0; + } + + shdrs_view_valid = 0; + names_view_valid = 0; + symtab_view_valid = 0; + strtab_view_valid = 0; + buildid_view_valid = 0; + buildid_data = NULL; + buildid_size = 0; + debuglink_view_valid = 0; + debuglink_name = NULL; + debuglink_crc = 0; + debugaltlink_view_valid = 0; + debugaltlink_name = NULL; + debugaltlink_buildid_data = NULL; + debugaltlink_buildid_size = 0; + gnu_debugdata_view_valid = 0; + gnu_debugdata_size = 0; + debug_view_valid = 0; + memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid); + opd = NULL; + + if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr, + error_callback, data, &ehdr_view)) + goto fail; + + memcpy (&ehdr, ehdr_view.view.data, sizeof ehdr); + + elf_release_view (state, &ehdr_view, error_callback, data); + + if (ehdr.e_ident[EI_MAG0] != ELFMAG0 + || ehdr.e_ident[EI_MAG1] != ELFMAG1 + || ehdr.e_ident[EI_MAG2] != ELFMAG2 + || ehdr.e_ident[EI_MAG3] != ELFMAG3) + { + error_callback (data, "executable file is not ELF", 0); + goto fail; + } + if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) + { + error_callback (data, "executable file is unrecognized ELF version", 0); + goto fail; + } + +#if BACKTRACE_ELF_SIZE == 32 +#define BACKTRACE_ELFCLASS ELFCLASS32 +#else +#define BACKTRACE_ELFCLASS ELFCLASS64 +#endif + + if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS) + { + error_callback (data, "executable file is unexpected ELF class", 0); + goto fail; + } + + if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB + && ehdr.e_ident[EI_DATA] != ELFDATA2MSB) + { + error_callback (data, "executable file has unknown endianness", 0); + goto fail; + } + + /* If the executable is ET_DYN, it is either a PIE, or we are running + directly a shared library with .interp. We need to wait for + dl_iterate_phdr in that case to determine the actual base_address. */ + if (exe && ehdr.e_type == ET_DYN) + return -1; + + shoff = ehdr.e_shoff; + shnum = ehdr.e_shnum; + shstrndx = ehdr.e_shstrndx; + + if ((shnum == 0 || shstrndx == SHN_XINDEX) + && shoff != 0) + { + struct elf_view shdr_view; + const b_elf_shdr *shdr; + + if (!elf_get_view (state, descriptor, memory, memory_size, shoff, + sizeof shdr, error_callback, data, &shdr_view)) + goto fail; + + shdr = (const b_elf_shdr *) shdr_view.view.data; + + if (shnum == 0) + shnum = shdr->sh_size; + + if (shstrndx == SHN_XINDEX) + { + shstrndx = shdr->sh_link; + + /* Versions of the GNU binutils between 2.12 and 2.18 did + not handle objects with more than SHN_LORESERVE sections + correctly. All large section indexes were offset by + 0x100. There is more information at + http://sourceware.org/bugzilla/show_bug.cgi?id-5900 . + Fortunately these object files are easy to detect, as the + GNU binutils always put the section header string table + near the end of the list of sections. Thus if the + section header string table index is larger than the + number of sections, then we know we have to subtract + 0x100 to get the real section index. */ + if (shstrndx >= shnum && shstrndx >= SHN_LORESERVE + 0x100) + shstrndx -= 0x100; + } + + elf_release_view (state, &shdr_view, error_callback, data); + } + + if (shnum == 0 || shstrndx == 0) + goto fail; + + /* To translate PC to file/line when using DWARF, we need to find + the .debug_info and .debug_line sections. */ + + /* Read the section headers, skipping the first one. */ + + if (!elf_get_view (state, descriptor, memory, memory_size, + shoff + sizeof (b_elf_shdr), + (shnum - 1) * sizeof (b_elf_shdr), + error_callback, data, &shdrs_view)) + goto fail; + shdrs_view_valid = 1; + shdrs = (const b_elf_shdr *) shdrs_view.view.data; + + /* Read the section names. */ + + shstrhdr = &shdrs[shstrndx - 1]; + shstr_size = shstrhdr->sh_size; + shstr_off = shstrhdr->sh_offset; + + if (!elf_get_view (state, descriptor, memory, memory_size, shstr_off, + shstrhdr->sh_size, error_callback, data, &names_view)) + goto fail; + names_view_valid = 1; + names = (const char *) names_view.view.data; + + symtab_shndx = 0; + dynsym_shndx = 0; + + memset (sections, 0, sizeof sections); + memset (zsections, 0, sizeof zsections); + + /* Look for the symbol table. */ + for (i = 1; i < shnum; ++i) + { + const b_elf_shdr *shdr; + unsigned int sh_name; + const char *name; + int j; + + shdr = &shdrs[i - 1]; + + if (shdr->sh_type == SHT_SYMTAB) + symtab_shndx = i; + else if (shdr->sh_type == SHT_DYNSYM) + dynsym_shndx = i; + + sh_name = shdr->sh_name; + if (sh_name >= shstr_size) + { + error_callback (data, "ELF section name out of range", 0); + goto fail; + } + + name = names + sh_name; + + for (j = 0; j < (int) DEBUG_MAX; ++j) + { + if (strcmp (name, dwarf_section_names[j]) == 0) + { + sections[j].offset = shdr->sh_offset; + sections[j].size = shdr->sh_size; + sections[j].compressed = (shdr->sh_flags & SHF_COMPRESSED) != 0; + break; + } + } + + if (name[0] == '.' && name[1] == 'z') + { + for (j = 0; j < (int) DEBUG_MAX; ++j) + { + if (strcmp (name + 2, dwarf_section_names[j] + 1) == 0) + { + zsections[j].offset = shdr->sh_offset; + zsections[j].size = shdr->sh_size; + break; + } + } + } + + /* Read the build ID if present. This could check for any + SHT_NOTE section with the right note name and type, but gdb + looks for a specific section name. */ + if ((!debuginfo || with_buildid_data != NULL) + && !buildid_view_valid + && strcmp (name, ".note.gnu.build-id") == 0) + { + const b_elf_note *note; + + if (!elf_get_view (state, descriptor, memory, memory_size, + shdr->sh_offset, shdr->sh_size, error_callback, + data, &buildid_view)) + goto fail; + + buildid_view_valid = 1; + note = (const b_elf_note *) buildid_view.view.data; + if (note->type == NT_GNU_BUILD_ID + && note->namesz == 4 + && strncmp (note->name, "GNU", 4) == 0 + && shdr->sh_size <= 12 + ((note->namesz + 3) & ~ 3) + note->descsz) + { + buildid_data = ¬e->name[0] + ((note->namesz + 3) & ~ 3); + buildid_size = note->descsz; + } + + if (with_buildid_size != 0) + { + if (buildid_size != with_buildid_size) + goto fail; + + if (memcmp (buildid_data, with_buildid_data, buildid_size) != 0) + goto fail; + } + } + + /* Read the debuglink file if present. */ + if (!debuginfo + && !debuglink_view_valid + && strcmp (name, ".gnu_debuglink") == 0) + { + const char *debuglink_data; + size_t crc_offset; + + if (!elf_get_view (state, descriptor, memory, memory_size, + shdr->sh_offset, shdr->sh_size, error_callback, + data, &debuglink_view)) + goto fail; + + debuglink_view_valid = 1; + debuglink_data = (const char *) debuglink_view.view.data; + crc_offset = strnlen (debuglink_data, shdr->sh_size); + crc_offset = (crc_offset + 3) & ~3; + if (crc_offset + 4 <= shdr->sh_size) + { + debuglink_name = debuglink_data; + debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset); + } + } + + if (!debugaltlink_view_valid + && strcmp (name, ".gnu_debugaltlink") == 0) + { + const char *debugaltlink_data; + size_t debugaltlink_name_len; + + if (!elf_get_view (state, descriptor, memory, memory_size, + shdr->sh_offset, shdr->sh_size, error_callback, + data, &debugaltlink_view)) + goto fail; + + debugaltlink_view_valid = 1; + debugaltlink_data = (const char *) debugaltlink_view.view.data; + debugaltlink_name = debugaltlink_data; + debugaltlink_name_len = strnlen (debugaltlink_data, shdr->sh_size); + if (debugaltlink_name_len < shdr->sh_size) + { + /* Include terminating zero. */ + debugaltlink_name_len += 1; + + debugaltlink_buildid_data + = debugaltlink_data + debugaltlink_name_len; + debugaltlink_buildid_size = shdr->sh_size - debugaltlink_name_len; + } + } + + if (!gnu_debugdata_view_valid + && strcmp (name, ".gnu_debugdata") == 0) + { + if (!elf_get_view (state, descriptor, memory, memory_size, + shdr->sh_offset, shdr->sh_size, error_callback, + data, &gnu_debugdata_view)) + goto fail; + + gnu_debugdata_size = shdr->sh_size; + gnu_debugdata_view_valid = 1; + } + + /* Read the .opd section on PowerPC64 ELFv1. */ + if (ehdr.e_machine == EM_PPC64 + && (ehdr.e_flags & EF_PPC64_ABI) < 2 + && shdr->sh_type == SHT_PROGBITS + && strcmp (name, ".opd") == 0) + { + if (!elf_get_view (state, descriptor, memory, memory_size, + shdr->sh_offset, shdr->sh_size, error_callback, + data, &opd_data.view)) + goto fail; + + opd = &opd_data; + opd->addr = shdr->sh_addr; + opd->data = (const char *) opd_data.view.view.data; + opd->size = shdr->sh_size; + } + } + + if (symtab_shndx == 0) + symtab_shndx = dynsym_shndx; + if (symtab_shndx != 0 && !debuginfo) + { + const b_elf_shdr *symtab_shdr; + unsigned int strtab_shndx; + const b_elf_shdr *strtab_shdr; + struct elf_syminfo_data *sdata; + + symtab_shdr = &shdrs[symtab_shndx - 1]; + strtab_shndx = symtab_shdr->sh_link; + if (strtab_shndx >= shnum) + { + error_callback (data, + "ELF symbol table strtab link out of range", 0); + goto fail; + } + strtab_shdr = &shdrs[strtab_shndx - 1]; + + if (!elf_get_view (state, descriptor, memory, memory_size, + symtab_shdr->sh_offset, symtab_shdr->sh_size, + error_callback, data, &symtab_view)) + goto fail; + symtab_view_valid = 1; + + if (!elf_get_view (state, descriptor, memory, memory_size, + strtab_shdr->sh_offset, strtab_shdr->sh_size, + error_callback, data, &strtab_view)) + goto fail; + strtab_view_valid = 1; + + sdata = ((struct elf_syminfo_data *) + backtrace_alloc (state, sizeof *sdata, error_callback, data)); + if (sdata == NULL) + goto fail; + + if (!elf_initialize_syminfo (state, base_address, + (const unsigned char*)symtab_view.view.data, symtab_shdr->sh_size, + (const unsigned char*)strtab_view.view.data, strtab_shdr->sh_size, + error_callback, data, sdata, opd)) + { + backtrace_free (state, sdata, sizeof *sdata, error_callback, data); + goto fail; + } + + /* We no longer need the symbol table, but we hold on to the + string table permanently. */ + elf_release_view (state, &symtab_view, error_callback, data); + symtab_view_valid = 0; + strtab_view_valid = 0; + + *found_sym = 1; + + elf_add_syminfo_data (state, sdata); + } + + elf_release_view (state, &shdrs_view, error_callback, data); + shdrs_view_valid = 0; + elf_release_view (state, &names_view, error_callback, data); + names_view_valid = 0; + + /* If the debug info is in a separate file, read that one instead. */ + + if (buildid_data != NULL) + { + int d; + + d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size, + filename, error_callback, data); + if (d >= 0) + { + int ret; + + elf_release_view (state, &buildid_view, error_callback, data); + if (debuglink_view_valid) + elf_release_view (state, &debuglink_view, error_callback, data); + if (debugaltlink_view_valid) + elf_release_view (state, &debugaltlink_view, error_callback, data); + ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, + data, fileline_fn, found_sym, found_dwarf, NULL, 0, + 1, NULL, 0); + if (ret < 0) + backtrace_close (d, error_callback, data); + else if (descriptor >= 0) + backtrace_close (descriptor, error_callback, data); + return ret; + } + } + + if (buildid_view_valid) + { + elf_release_view (state, &buildid_view, error_callback, data); + buildid_view_valid = 0; + } + + if (opd) + { + elf_release_view (state, &opd->view, error_callback, data); + opd = NULL; + } + + if (debuglink_name != NULL) + { + int d; + + d = elf_open_debugfile_by_debuglink (state, filename, debuglink_name, + debuglink_crc, error_callback, + data); + if (d >= 0) + { + int ret; + + elf_release_view (state, &debuglink_view, error_callback, data); + if (debugaltlink_view_valid) + elf_release_view (state, &debugaltlink_view, error_callback, data); + ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, + data, fileline_fn, found_sym, found_dwarf, NULL, 0, + 1, NULL, 0); + if (ret < 0) + backtrace_close (d, error_callback, data); + else if (descriptor >= 0) + backtrace_close(descriptor, error_callback, data); + return ret; + } + } + + if (debuglink_view_valid) + { + elf_release_view (state, &debuglink_view, error_callback, data); + debuglink_view_valid = 0; + } + + if (debugaltlink_name != NULL) + { + int d; + + d = elf_open_debugfile_by_debuglink (state, filename, debugaltlink_name, + 0, error_callback, data); + if (d >= 0) + { + int ret; + + ret = elf_add (state, filename, d, NULL, 0, base_address, + error_callback, data, fileline_fn, found_sym, + found_dwarf, &fileline_altlink, 0, 1, + debugaltlink_buildid_data, debugaltlink_buildid_size); + elf_release_view (state, &debugaltlink_view, error_callback, data); + debugaltlink_view_valid = 0; + if (ret < 0) + { + backtrace_close (d, error_callback, data); + return ret; + } + } + } + + if (debugaltlink_view_valid) + { + elf_release_view (state, &debugaltlink_view, error_callback, data); + debugaltlink_view_valid = 0; + } + + if (gnu_debugdata_view_valid) + { + int ret; + + ret = elf_uncompress_lzma (state, + ((const unsigned char *) + gnu_debugdata_view.view.data), + gnu_debugdata_size, error_callback, data, + &gnu_debugdata_uncompressed, + &gnu_debugdata_uncompressed_size); + + elf_release_view (state, &gnu_debugdata_view, error_callback, data); + gnu_debugdata_view_valid = 0; + + if (ret) + { + ret = elf_add (state, filename, -1, gnu_debugdata_uncompressed, + gnu_debugdata_uncompressed_size, base_address, + error_callback, data, fileline_fn, found_sym, + found_dwarf, NULL, 0, 0, NULL, 0); + if (ret >= 0 && descriptor >= 0) + backtrace_close(descriptor, error_callback, data); + return ret; + } + } + + /* Read all the debug sections in a single view, since they are + probably adjacent in the file. If any of sections are + uncompressed, we never release this view. */ + + min_offset = 0; + max_offset = 0; + debug_size = 0; + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + off_t end; + + if (sections[i].size != 0) + { + if (min_offset == 0 || sections[i].offset < min_offset) + min_offset = sections[i].offset; + end = sections[i].offset + sections[i].size; + if (end > max_offset) + max_offset = end; + debug_size += sections[i].size; + } + if (zsections[i].size != 0) + { + if (min_offset == 0 || zsections[i].offset < min_offset) + min_offset = zsections[i].offset; + end = zsections[i].offset + zsections[i].size; + if (end > max_offset) + max_offset = end; + debug_size += zsections[i].size; + } + } + if (min_offset == 0 || max_offset == 0) + { + if (descriptor >= 0) + { + if (!backtrace_close (descriptor, error_callback, data)) + goto fail; + } + return 1; + } + + /* If the total debug section size is large, assume that there are + gaps between the sections, and read them individually. */ + + if (max_offset - min_offset < 0x20000000 + || max_offset - min_offset < debug_size + 0x10000) + { + if (!elf_get_view (state, descriptor, memory, memory_size, min_offset, + max_offset - min_offset, error_callback, data, + &debug_view)) + goto fail; + debug_view_valid = 1; + } + else + { + memset (&split_debug_view[0], 0, sizeof split_debug_view); + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + struct debug_section_info *dsec; + + if (sections[i].size != 0) + dsec = §ions[i]; + else if (zsections[i].size != 0) + dsec = &zsections[i]; + else + continue; + + if (!elf_get_view (state, descriptor, memory, memory_size, + dsec->offset, dsec->size, error_callback, data, + &split_debug_view[i])) + goto fail; + split_debug_view_valid[i] = 1; + + if (sections[i].size != 0) + sections[i].data = ((const unsigned char *) + split_debug_view[i].view.data); + else + zsections[i].data = ((const unsigned char *) + split_debug_view[i].view.data); + } + } + + /* We've read all we need from the executable. */ + if (descriptor >= 0) + { + if (!backtrace_close (descriptor, error_callback, data)) + goto fail; + descriptor = -1; + } + + using_debug_view = 0; + if (debug_view_valid) + { + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + if (sections[i].size == 0) + sections[i].data = NULL; + else + { + sections[i].data = ((const unsigned char *) debug_view.view.data + + (sections[i].offset - min_offset)); + ++using_debug_view; + } + + if (zsections[i].size == 0) + zsections[i].data = NULL; + else + zsections[i].data = ((const unsigned char *) debug_view.view.data + + (zsections[i].offset - min_offset)); + } + } + + /* Uncompress the old format (--compress-debug-sections=zlib-gnu). */ + + zdebug_table = NULL; + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + if (sections[i].size == 0 && zsections[i].size > 0) + { + unsigned char *uncompressed_data; + size_t uncompressed_size; + + if (zdebug_table == NULL) + { + zdebug_table = ((uint16_t *) + backtrace_alloc (state, ZLIB_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + goto fail; + } + + uncompressed_data = NULL; + uncompressed_size = 0; + if (!elf_uncompress_zdebug (state, zsections[i].data, + zsections[i].size, zdebug_table, + error_callback, data, + &uncompressed_data, &uncompressed_size)) + goto fail; + sections[i].data = uncompressed_data; + sections[i].size = uncompressed_size; + sections[i].compressed = 0; + + if (split_debug_view_valid[i]) + { + elf_release_view (state, &split_debug_view[i], + error_callback, data); + split_debug_view_valid[i] = 0; + } + } + } + + if (zdebug_table != NULL) + { + backtrace_free (state, zdebug_table, ZLIB_TABLE_SIZE, + error_callback, data); + zdebug_table = NULL; + } + + /* Uncompress the official ELF format + (--compress-debug-sections=zlib-gabi, --compress-debug-sections=zstd). */ + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + unsigned char *uncompressed_data; + size_t uncompressed_size; + + if (sections[i].size == 0 || !sections[i].compressed) + continue; + + if (zdebug_table == NULL) + { + zdebug_table = ((uint16_t *) + backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + goto fail; + } + + uncompressed_data = NULL; + uncompressed_size = 0; + if (!elf_uncompress_chdr (state, sections[i].data, sections[i].size, + zdebug_table, error_callback, data, + &uncompressed_data, &uncompressed_size)) + goto fail; + sections[i].data = uncompressed_data; + sections[i].size = uncompressed_size; + sections[i].compressed = 0; + + if (debug_view_valid) + --using_debug_view; + else if (split_debug_view_valid[i]) + { + elf_release_view (state, &split_debug_view[i], error_callback, data); + split_debug_view_valid[i] = 0; + } + } + + if (zdebug_table != NULL) + backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, + error_callback, data); + + if (debug_view_valid && using_debug_view == 0) + { + elf_release_view (state, &debug_view, error_callback, data); + debug_view_valid = 0; + } + + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + dwarf_sections.data[i] = sections[i].data; + dwarf_sections.size[i] = sections[i].size; + } + + if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, + ehdr.e_ident[EI_DATA] == ELFDATA2MSB, + fileline_altlink, + error_callback, data, fileline_fn, + fileline_entry)) + goto fail; + + *found_dwarf = 1; + + return 1; + + fail: + if (shdrs_view_valid) + elf_release_view (state, &shdrs_view, error_callback, data); + if (names_view_valid) + elf_release_view (state, &names_view, error_callback, data); + if (symtab_view_valid) + elf_release_view (state, &symtab_view, error_callback, data); + if (strtab_view_valid) + elf_release_view (state, &strtab_view, error_callback, data); + if (debuglink_view_valid) + elf_release_view (state, &debuglink_view, error_callback, data); + if (debugaltlink_view_valid) + elf_release_view (state, &debugaltlink_view, error_callback, data); + if (gnu_debugdata_view_valid) + elf_release_view (state, &gnu_debugdata_view, error_callback, data); + if (buildid_view_valid) + elf_release_view (state, &buildid_view, error_callback, data); + if (debug_view_valid) + elf_release_view (state, &debug_view, error_callback, data); + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + if (split_debug_view_valid[i]) + elf_release_view (state, &split_debug_view[i], error_callback, data); + } + if (opd) + elf_release_view (state, &opd->view, error_callback, data); + if (descriptor >= 0) + backtrace_close (descriptor, error_callback, data); + return 0; +} + +/* Data passed to phdr_callback. */ + +struct phdr_data +{ + struct backtrace_state *state; + backtrace_error_callback error_callback; + void *data; + fileline *fileline_fn; + int *found_sym; + int *found_dwarf; + const char *exe_filename; + int exe_descriptor; +}; + +/* Callback passed to dl_iterate_phdr. Load debug info from shared + libraries. */ + +struct PhdrIterate +{ + char* dlpi_name; + ElfW(Addr) dlpi_addr; +}; +FastVector s_phdrData(16); + +static int +phdr_callback_mock (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED, + void *pdata) +{ + auto ptr = s_phdrData.push_next(); + if (info->dlpi_name) + { + size_t sz = strlen (info->dlpi_name) + 1; + ptr->dlpi_name = (char*)tracy_malloc (sz); + memcpy (ptr->dlpi_name, info->dlpi_name, sz); + } + else ptr->dlpi_name = nullptr; + ptr->dlpi_addr = info->dlpi_addr; + return 0; +} + +static int +#ifdef __i386__ +__attribute__ ((__force_align_arg_pointer__)) +#endif +phdr_callback (struct PhdrIterate *info, void *pdata) +{ + struct phdr_data *pd = (struct phdr_data *) pdata; + const char *filename; + int descriptor; + int does_not_exist; + fileline elf_fileline_fn; + int found_dwarf; + + /* There is not much we can do if we don't have the module name, + unless executable is ET_DYN, where we expect the very first + phdr_callback to be for the PIE. */ + if (info->dlpi_name == NULL || info->dlpi_name[0] == '\0') + { + if (pd->exe_descriptor == -1) + return 0; + filename = pd->exe_filename; + descriptor = pd->exe_descriptor; + pd->exe_descriptor = -1; + } + else + { + if (pd->exe_descriptor != -1) + { + backtrace_close (pd->exe_descriptor, pd->error_callback, pd->data); + pd->exe_descriptor = -1; + } + + filename = info->dlpi_name; + descriptor = backtrace_open (info->dlpi_name, pd->error_callback, + pd->data, &does_not_exist); + if (descriptor < 0) + return 0; + } + + if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr, + pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym, + &found_dwarf, NULL, 0, 0, NULL, 0)) + { + if (found_dwarf) + { + *pd->found_dwarf = 1; + *pd->fileline_fn = elf_fileline_fn; + } + } + + return 0; +} + +/* Initialize the backtrace data we need from an ELF executable. At + the ELF level, all we need to do is find the debug info + sections. */ + +int +backtrace_initialize (struct backtrace_state *state, const char *filename, + int descriptor, backtrace_error_callback error_callback, + void *data, fileline *fileline_fn) +{ + int ret; + int found_sym; + int found_dwarf; + fileline elf_fileline_fn = elf_nodebug; + struct phdr_data pd; + + ret = elf_add (state, filename, descriptor, NULL, 0, 0, error_callback, data, + &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL, + 0); + if (!ret) + return 0; + + pd.state = state; + pd.error_callback = error_callback; + pd.data = data; + pd.fileline_fn = &elf_fileline_fn; + pd.found_sym = &found_sym; + pd.found_dwarf = &found_dwarf; + pd.exe_filename = filename; + pd.exe_descriptor = ret < 0 ? descriptor : -1; + + assert (s_phdrData.empty()); + dl_iterate_phdr (phdr_callback_mock, nullptr); + for (auto& v : s_phdrData) + { + phdr_callback (&v, (void *) &pd); + tracy_free (v.dlpi_name); + } + s_phdrData.clear(); + + if (!state->threaded) + { + if (found_sym) + state->syminfo_fn = elf_syminfo; + else if (state->syminfo_fn == NULL) + state->syminfo_fn = elf_nosyms; + } + else + { + if (found_sym) + backtrace_atomic_store_pointer (&state->syminfo_fn, &elf_syminfo); + else + (void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL, + elf_nosyms); + } + + if (!state->threaded) + *fileline_fn = state->fileline_fn; + else + *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn); + + if (*fileline_fn == NULL || *fileline_fn == elf_nodebug) + *fileline_fn = elf_fileline_fn; + + return 1; +} + +} diff --git a/Externals/tracy/public/libbacktrace/fileline.cpp b/Externals/tracy/public/libbacktrace/fileline.cpp new file mode 100644 index 00000000000..8645d754af8 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/fileline.cpp @@ -0,0 +1,351 @@ +/* fileline.c -- Get file and line number information in a backtrace. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC) +#include +#endif + +#ifdef HAVE_MACH_O_DYLD_H +#include +#endif + +#include "backtrace.hpp" +#include "internal.hpp" + +#ifndef HAVE_GETEXECNAME +#define getexecname() NULL +#endif + +namespace tracy +{ + +#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC) + +#define sysctl_exec_name1(state, error_callback, data) NULL +#define sysctl_exec_name2(state, error_callback, data) NULL + +#else /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */ + +static char * +sysctl_exec_name (struct backtrace_state *state, + int mib0, int mib1, int mib2, int mib3, + backtrace_error_callback error_callback, void *data) +{ + int mib[4]; + size_t len; + char *name; + size_t rlen; + + mib[0] = mib0; + mib[1] = mib1; + mib[2] = mib2; + mib[3] = mib3; + + if (sysctl (mib, 4, NULL, &len, NULL, 0) < 0) + return NULL; + name = (char *) backtrace_alloc (state, len, error_callback, data); + if (name == NULL) + return NULL; + rlen = len; + if (sysctl (mib, 4, name, &rlen, NULL, 0) < 0) + { + backtrace_free (state, name, len, error_callback, data); + return NULL; + } + return name; +} + +#ifdef HAVE_KERN_PROC_ARGS + +static char * +sysctl_exec_name1 (struct backtrace_state *state, + backtrace_error_callback error_callback, void *data) +{ + /* This variant is used on NetBSD. */ + return sysctl_exec_name (state, CTL_KERN, KERN_PROC_ARGS, -1, + KERN_PROC_PATHNAME, error_callback, data); +} + +#else + +#define sysctl_exec_name1(state, error_callback, data) NULL + +#endif + +#ifdef HAVE_KERN_PROC + +static char * +sysctl_exec_name2 (struct backtrace_state *state, + backtrace_error_callback error_callback, void *data) +{ + /* This variant is used on FreeBSD. */ + return sysctl_exec_name (state, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1, + error_callback, data); +} + +#else + +#define sysctl_exec_name2(state, error_callback, data) NULL + +#endif + +#endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */ + +#ifdef HAVE_MACH_O_DYLD_H + +static char * +macho_get_executable_path (struct backtrace_state *state, + backtrace_error_callback error_callback, void *data) +{ + uint32_t len; + char *name; + + len = 0; + if (_NSGetExecutablePath (NULL, &len) == 0) + return NULL; + name = (char *) backtrace_alloc (state, len, error_callback, data); + if (name == NULL) + return NULL; + if (_NSGetExecutablePath (name, &len) != 0) + { + backtrace_free (state, name, len, error_callback, data); + return NULL; + } + return name; +} + +#else /* !defined (HAVE_MACH_O_DYLD_H) */ + +#define macho_get_executable_path(state, error_callback, data) NULL + +#endif /* !defined (HAVE_MACH_O_DYLD_H) */ + +/* Initialize the fileline information from the executable. Returns 1 + on success, 0 on failure. */ + +static int +fileline_initialize (struct backtrace_state *state, + backtrace_error_callback error_callback, void *data) +{ + int failed; + fileline fileline_fn; + int pass; + int called_error_callback; + int descriptor; + const char *filename; + char buf[64]; + + if (!state->threaded) + failed = state->fileline_initialization_failed; + else + failed = backtrace_atomic_load_int (&state->fileline_initialization_failed); + + if (failed) + { + error_callback (data, "failed to read executable information", -1); + return 0; + } + + if (!state->threaded) + fileline_fn = state->fileline_fn; + else + fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn); + if (fileline_fn != NULL) + return 1; + + /* We have not initialized the information. Do it now. */ + + descriptor = -1; + called_error_callback = 0; + for (pass = 0; pass < 8; ++pass) + { + int does_not_exist; + + switch (pass) + { + case 0: + filename = state->filename; + break; + case 1: + filename = getexecname (); + break; + case 2: + filename = "/proc/self/exe"; + break; + case 3: + filename = "/proc/curproc/file"; + break; + case 4: + snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out", + (long) getpid ()); + filename = buf; + break; + case 5: + filename = sysctl_exec_name1 (state, error_callback, data); + break; + case 6: + filename = sysctl_exec_name2 (state, error_callback, data); + break; + case 7: + filename = macho_get_executable_path (state, error_callback, data); + break; + default: + abort (); + } + + if (filename == NULL) + continue; + + descriptor = backtrace_open (filename, error_callback, data, + &does_not_exist); + if (descriptor < 0 && !does_not_exist) + { + called_error_callback = 1; + break; + } + if (descriptor >= 0) + break; + } + + if (descriptor < 0) + { + if (!called_error_callback) + { + if (state->filename != NULL) + error_callback (data, state->filename, ENOENT); + else + error_callback (data, + "libbacktrace could not find executable to open", + 0); + } + failed = 1; + } + + if (!failed) + { + if (!backtrace_initialize (state, filename, descriptor, error_callback, + data, &fileline_fn)) + failed = 1; + } + + if (failed) + { + if (!state->threaded) + state->fileline_initialization_failed = 1; + else + backtrace_atomic_store_int (&state->fileline_initialization_failed, 1); + return 0; + } + + if (!state->threaded) + state->fileline_fn = fileline_fn; + else + { + backtrace_atomic_store_pointer (&state->fileline_fn, fileline_fn); + + /* Note that if two threads initialize at once, one of the data + sets may be leaked. */ + } + + return 1; +} + +/* Given a PC, find the file name, line number, and function name. */ + +int +backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, void *data) +{ + if (!fileline_initialize (state, error_callback, data)) + return 0; + + if (state->fileline_initialization_failed) + return 0; + + return state->fileline_fn (state, pc, callback, error_callback, data); +} + +/* Given a PC, find the symbol for it, and its value. */ + +int +backtrace_syminfo (struct backtrace_state *state, uintptr_t pc, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback, void *data) +{ + if (!fileline_initialize (state, error_callback, data)) + return 0; + + if (state->fileline_initialization_failed) + return 0; + + state->syminfo_fn (state, pc, callback, error_callback, data); + return 1; +} + +/* A backtrace_syminfo_callback that can call into a + backtrace_full_callback, used when we have a symbol table but no + debug info. */ + +void +backtrace_syminfo_to_full_callback (void *data, uintptr_t pc, + const char *symname, + uintptr_t symval ATTRIBUTE_UNUSED, + uintptr_t symsize ATTRIBUTE_UNUSED) +{ + struct backtrace_call_full *bdata = (struct backtrace_call_full *) data; + + bdata->ret = bdata->full_callback (bdata->full_data, pc, 0, NULL, 0, symname); +} + +/* An error callback that corresponds to + backtrace_syminfo_to_full_callback. */ + +void +backtrace_syminfo_to_full_error_callback (void *data, const char *msg, + int errnum) +{ + struct backtrace_call_full *bdata = (struct backtrace_call_full *) data; + + bdata->full_error_callback (bdata->full_data, msg, errnum); +} + +} diff --git a/Externals/tracy/public/libbacktrace/filenames.hpp b/Externals/tracy/public/libbacktrace/filenames.hpp new file mode 100644 index 00000000000..aa7bd7adff5 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/filenames.hpp @@ -0,0 +1,52 @@ +/* btest.c -- Filename header for libbacktrace library + Copyright (C) 2012-2018 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef GCC_VERSION +# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#endif + +#if (GCC_VERSION < 2007) +# define __attribute__(x) +#endif + +#ifndef ATTRIBUTE_UNUSED +# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif + +#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) +# define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') +# define HAS_DRIVE_SPEC(f) ((f)[0] != '\0' && (f)[1] == ':') +# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || HAS_DRIVE_SPEC(f)) +#else +# define IS_DIR_SEPARATOR(c) ((c) == '/') +# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) +#endif diff --git a/Externals/tracy/public/libbacktrace/internal.hpp b/Externals/tracy/public/libbacktrace/internal.hpp new file mode 100644 index 00000000000..f871844b62d --- /dev/null +++ b/Externals/tracy/public/libbacktrace/internal.hpp @@ -0,0 +1,394 @@ +/* internal.h -- Internal header file for stack backtrace library. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef BACKTRACE_INTERNAL_H +#define BACKTRACE_INTERNAL_H + +/* We assume that and "backtrace.h" have already been + included. */ + +#ifndef GCC_VERSION +# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#endif + +#if (GCC_VERSION < 2007) +# define __attribute__(x) +#endif + +#ifndef ATTRIBUTE_UNUSED +# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif + +#ifndef ATTRIBUTE_MALLOC +# if (GCC_VERSION >= 2096) +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define ATTRIBUTE_MALLOC +# endif +#endif + +#ifndef ATTRIBUTE_FALLTHROUGH +# if (GCC_VERSION >= 7000) +# define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__)) +# else +# define ATTRIBUTE_FALLTHROUGH +# endif +#endif + +#ifndef HAVE_SYNC_FUNCTIONS + +/* Define out the sync functions. These should never be called if + they are not available. */ + +#define __sync_bool_compare_and_swap(A, B, C) (abort(), 1) +#define __sync_lock_test_and_set(A, B) (abort(), 0) +#define __sync_lock_release(A) abort() + +#endif /* !defined (HAVE_SYNC_FUNCTIONS) */ + +#ifdef HAVE_ATOMIC_FUNCTIONS + +/* We have the atomic builtin functions. */ + +#define backtrace_atomic_load_pointer(p) \ + __atomic_load_n ((p), __ATOMIC_ACQUIRE) +#define backtrace_atomic_load_int(p) \ + __atomic_load_n ((p), __ATOMIC_ACQUIRE) +#define backtrace_atomic_store_pointer(p, v) \ + __atomic_store_n ((p), (v), __ATOMIC_RELEASE) +#define backtrace_atomic_store_size_t(p, v) \ + __atomic_store_n ((p), (v), __ATOMIC_RELEASE) +#define backtrace_atomic_store_int(p, v) \ + __atomic_store_n ((p), (v), __ATOMIC_RELEASE) + +#else /* !defined (HAVE_ATOMIC_FUNCTIONS) */ +#ifdef HAVE_SYNC_FUNCTIONS + +/* We have the sync functions but not the atomic functions. Define + the atomic ones in terms of the sync ones. */ + +extern void *backtrace_atomic_load_pointer (void *); +extern int backtrace_atomic_load_int (int *); +extern void backtrace_atomic_store_pointer (void *, void *); +extern void backtrace_atomic_store_size_t (size_t *, size_t); +extern void backtrace_atomic_store_int (int *, int); + +#else /* !defined (HAVE_SYNC_FUNCTIONS) */ + +/* We have neither the sync nor the atomic functions. These will + never be called. */ + +#define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL) +#define backtrace_atomic_load_int(p) (abort(), 0) +#define backtrace_atomic_store_pointer(p, v) abort() +#define backtrace_atomic_store_size_t(p, v) abort() +#define backtrace_atomic_store_int(p, v) abort() + +#endif /* !defined (HAVE_SYNC_FUNCTIONS) */ +#endif /* !defined (HAVE_ATOMIC_FUNCTIONS) */ + +namespace tracy +{ + +/* The type of the function that collects file/line information. This + is like backtrace_pcinfo. */ + +typedef int (*fileline) (struct backtrace_state *state, uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, void *data); + +/* The type of the function that collects symbol information. This is + like backtrace_syminfo. */ + +typedef void (*syminfo) (struct backtrace_state *state, uintptr_t pc, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback, void *data); + +/* What the backtrace state pointer points to. */ + +struct backtrace_state +{ + /* The name of the executable. */ + const char *filename; + /* Non-zero if threaded. */ + int threaded; + /* The master lock for fileline_fn, fileline_data, syminfo_fn, + syminfo_data, fileline_initialization_failed and everything the + data pointers point to. */ + void *lock; + /* The function that returns file/line information. */ + fileline fileline_fn; + /* The data to pass to FILELINE_FN. */ + void *fileline_data; + /* The function that returns symbol information. */ + syminfo syminfo_fn; + /* The data to pass to SYMINFO_FN. */ + void *syminfo_data; + /* Whether initializing the file/line information failed. */ + int fileline_initialization_failed; + /* The lock for the freelist. */ + int lock_alloc; + /* The freelist when using mmap. */ + struct backtrace_freelist_struct *freelist; +}; + +/* Open a file for reading. Returns -1 on error. If DOES_NOT_EXIST + is not NULL, *DOES_NOT_EXIST will be set to 0 normally and set to 1 + if the file does not exist. If the file does not exist and + DOES_NOT_EXIST is not NULL, the function will return -1 and will + not call ERROR_CALLBACK. On other errors, or if DOES_NOT_EXIST is + NULL, the function will call ERROR_CALLBACK before returning. */ +extern int backtrace_open (const char *filename, + backtrace_error_callback error_callback, + void *data, + int *does_not_exist); + +/* A view of the contents of a file. This supports mmap when + available. A view will remain in memory even after backtrace_close + is called on the file descriptor from which the view was + obtained. */ + +struct backtrace_view +{ + /* The data that the caller requested. */ + const void *data; + /* The base of the view. */ + void *base; + /* The total length of the view. */ + size_t len; +}; + +/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the + result in *VIEW. Returns 1 on success, 0 on error. */ +extern int backtrace_get_view (struct backtrace_state *state, int descriptor, + off_t offset, uint64_t size, + backtrace_error_callback error_callback, + void *data, struct backtrace_view *view); + +/* Release a view created by backtrace_get_view. */ +extern void backtrace_release_view (struct backtrace_state *state, + struct backtrace_view *view, + backtrace_error_callback error_callback, + void *data); + +/* Close a file opened by backtrace_open. Returns 1 on success, 0 on + error. */ + +extern int backtrace_close (int descriptor, + backtrace_error_callback error_callback, + void *data); + +/* Sort without using memory. */ + +extern void backtrace_qsort (void *base, size_t count, size_t size, + int (*compar) (const void *, const void *)); + +/* Allocate memory. This is like malloc. If ERROR_CALLBACK is NULL, + this does not report an error, it just returns NULL. */ + +extern void *backtrace_alloc (struct backtrace_state *state, size_t size, + backtrace_error_callback error_callback, + void *data) ATTRIBUTE_MALLOC; + +/* Free memory allocated by backtrace_alloc. If ERROR_CALLBACK is + NULL, this does not report an error. */ + +extern void backtrace_free (struct backtrace_state *state, void *mem, + size_t size, + backtrace_error_callback error_callback, + void *data); + +/* A growable vector of some struct. This is used for more efficient + allocation when we don't know the final size of some group of data + that we want to represent as an array. */ + +struct backtrace_vector +{ + /* The base of the vector. */ + void *base; + /* The number of bytes in the vector. */ + size_t size; + /* The number of bytes available at the current allocation. */ + size_t alc; +}; + +/* Grow VEC by SIZE bytes. Return a pointer to the newly allocated + bytes. Note that this may move the entire vector to a new memory + location. Returns NULL on failure. */ + +extern void *backtrace_vector_grow (struct backtrace_state *state, size_t size, + backtrace_error_callback error_callback, + void *data, + struct backtrace_vector *vec); + +/* Finish the current allocation on VEC. Prepare to start a new + allocation. The finished allocation will never be freed. Returns + a pointer to the base of the finished entries, or NULL on + failure. */ + +extern void* backtrace_vector_finish (struct backtrace_state *state, + struct backtrace_vector *vec, + backtrace_error_callback error_callback, + void *data); + +/* Release any extra space allocated for VEC. This may change + VEC->base. Returns 1 on success, 0 on failure. */ + +extern int backtrace_vector_release (struct backtrace_state *state, + struct backtrace_vector *vec, + backtrace_error_callback error_callback, + void *data); + +/* Free the space managed by VEC. This will reset VEC. */ + +static inline void +backtrace_vector_free (struct backtrace_state *state, + struct backtrace_vector *vec, + backtrace_error_callback error_callback, void *data) +{ + vec->alc += vec->size; + vec->size = 0; + backtrace_vector_release (state, vec, error_callback, data); +} + +/* Read initial debug data from a descriptor, and set the + fileline_data, syminfo_fn, and syminfo_data fields of STATE. + Return the fileln_fn field in *FILELN_FN--this is done this way so + that the synchronization code is only implemented once. This is + called after the descriptor has first been opened. It will close + the descriptor if it is no longer needed. Returns 1 on success, 0 + on error. There will be multiple implementations of this function, + for different file formats. Each system will compile the + appropriate one. */ + +extern int backtrace_initialize (struct backtrace_state *state, + const char *filename, + int descriptor, + backtrace_error_callback error_callback, + void *data, + fileline *fileline_fn); + +/* An enum for the DWARF sections we care about. */ + +enum dwarf_section +{ + DEBUG_INFO, + DEBUG_LINE, + DEBUG_ABBREV, + DEBUG_RANGES, + DEBUG_STR, + DEBUG_ADDR, + DEBUG_STR_OFFSETS, + DEBUG_LINE_STR, + DEBUG_RNGLISTS, + + DEBUG_MAX +}; + +/* Data for the DWARF sections we care about. */ + +struct dwarf_sections +{ + const unsigned char *data[DEBUG_MAX]; + size_t size[DEBUG_MAX]; +}; + +/* DWARF data read from a file, used for .gnu_debugaltlink. */ + +struct dwarf_data; + +/* Add file/line information for a DWARF module. */ + +extern int backtrace_dwarf_add (struct backtrace_state *state, + uintptr_t base_address, + const struct dwarf_sections *dwarf_sections, + int is_bigendian, + struct dwarf_data *fileline_altlink, + backtrace_error_callback error_callback, + void *data, fileline *fileline_fn, + struct dwarf_data **fileline_entry); + +/* A data structure to pass to backtrace_syminfo_to_full. */ + +struct backtrace_call_full +{ + backtrace_full_callback full_callback; + backtrace_error_callback full_error_callback; + void *full_data; + int ret; +}; + +/* A backtrace_syminfo_callback that can call into a + backtrace_full_callback, used when we have a symbol table but no + debug info. */ + +extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc, + const char *symname, + uintptr_t symval, + uintptr_t symsize); + +/* An error callback that corresponds to + backtrace_syminfo_to_full_callback. */ + +extern void backtrace_syminfo_to_full_error_callback (void *, const char *, + int); + +/* A test-only hook for elf_uncompress_zdebug. */ + +extern int backtrace_uncompress_zdebug (struct backtrace_state *, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback, void *data, + unsigned char **uncompressed, + size_t *uncompressed_size); + +/* A test-only hook for elf_zstd_decompress. */ + +extern int backtrace_uncompress_zstd (struct backtrace_state *, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback, void *data, + unsigned char *uncompressed, + size_t uncompressed_size); + +/* A test-only hook for elf_uncompress_lzma. */ + +extern int backtrace_uncompress_lzma (struct backtrace_state *, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback, void *data, + unsigned char **uncompressed, + size_t *uncompressed_size); + +} + +#endif diff --git a/Externals/tracy/public/libbacktrace/macho.cpp b/Externals/tracy/public/libbacktrace/macho.cpp new file mode 100644 index 00000000000..6cccdabaa08 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/macho.cpp @@ -0,0 +1,1360 @@ +/* elf.c -- Get debug data from a Mach-O file for backtraces. + Copyright (C) 2020-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include + +#ifdef HAVE_MACH_O_DYLD_H +#include +#endif + +#include "backtrace.hpp" +#include "internal.hpp" + +namespace tracy +{ + +/* Mach-O file header for a 32-bit executable. */ + +struct macho_header_32 +{ + uint32_t magic; /* Magic number (MACH_O_MAGIC_32) */ + uint32_t cputype; /* CPU type */ + uint32_t cpusubtype; /* CPU subtype */ + uint32_t filetype; /* Type of file (object, executable) */ + uint32_t ncmds; /* Number of load commands */ + uint32_t sizeofcmds; /* Total size of load commands */ + uint32_t flags; /* Flags for special features */ +}; + +/* Mach-O file header for a 64-bit executable. */ + +struct macho_header_64 +{ + uint32_t magic; /* Magic number (MACH_O_MAGIC_64) */ + uint32_t cputype; /* CPU type */ + uint32_t cpusubtype; /* CPU subtype */ + uint32_t filetype; /* Type of file (object, executable) */ + uint32_t ncmds; /* Number of load commands */ + uint32_t sizeofcmds; /* Total size of load commands */ + uint32_t flags; /* Flags for special features */ + uint32_t reserved; /* Reserved */ +}; + +/* Mach-O file header for a fat executable. */ + +struct macho_header_fat +{ + uint32_t magic; /* Magic number (MACH_O_MH_(MAGIC|CIGAM)_FAT(_64)?) */ + uint32_t nfat_arch; /* Number of components */ +}; + +/* Values for the header magic field. */ + +#define MACH_O_MH_MAGIC_32 0xfeedface +#define MACH_O_MH_MAGIC_64 0xfeedfacf +#define MACH_O_MH_MAGIC_FAT 0xcafebabe +#define MACH_O_MH_CIGAM_FAT 0xbebafeca +#define MACH_O_MH_MAGIC_FAT_64 0xcafebabf +#define MACH_O_MH_CIGAM_FAT_64 0xbfbafeca + +/* Value for the header filetype field. */ + +#define MACH_O_MH_EXECUTE 0x02 +#define MACH_O_MH_DYLIB 0x06 +#define MACH_O_MH_DSYM 0x0a + +/* A component of a fat file. A fat file starts with a + macho_header_fat followed by nfat_arch instances of this + struct. */ + +struct macho_fat_arch +{ + uint32_t cputype; /* CPU type */ + uint32_t cpusubtype; /* CPU subtype */ + uint32_t offset; /* File offset of this entry */ + uint32_t size; /* Size of this entry */ + uint32_t align; /* Alignment of this entry */ +}; + +/* A component of a 64-bit fat file. This is used if the magic field + is MAGIC_FAT_64. This is only used when some file size or file + offset is too large to represent in the 32-bit format. */ + +struct macho_fat_arch_64 +{ + uint32_t cputype; /* CPU type */ + uint32_t cpusubtype; /* CPU subtype */ + uint64_t offset; /* File offset of this entry */ + uint64_t size; /* Size of this entry */ + uint32_t align; /* Alignment of this entry */ + uint32_t reserved; /* Reserved */ +}; + +/* Values for the fat_arch cputype field (and the header cputype + field). */ + +#define MACH_O_CPU_ARCH_ABI64 0x01000000 + +#define MACH_O_CPU_TYPE_X86 7 +#define MACH_O_CPU_TYPE_ARM 12 +#define MACH_O_CPU_TYPE_PPC 18 + +#define MACH_O_CPU_TYPE_X86_64 (MACH_O_CPU_TYPE_X86 | MACH_O_CPU_ARCH_ABI64) +#define MACH_O_CPU_TYPE_ARM64 (MACH_O_CPU_TYPE_ARM | MACH_O_CPU_ARCH_ABI64) +#define MACH_O_CPU_TYPE_PPC64 (MACH_O_CPU_TYPE_PPC | MACH_O_CPU_ARCH_ABI64) + +/* The header of a load command. */ + +struct macho_load_command +{ + uint32_t cmd; /* The type of load command */ + uint32_t cmdsize; /* Size in bytes of the entire command */ +}; + +/* Values for the load_command cmd field. */ + +#define MACH_O_LC_SEGMENT 0x01 +#define MACH_O_LC_SYMTAB 0x02 +#define MACH_O_LC_SEGMENT_64 0x19 +#define MACH_O_LC_UUID 0x1b + +/* The length of a section of segment name. */ + +#define MACH_O_NAMELEN (16) + +/* LC_SEGMENT load command. */ + +struct macho_segment_command +{ + uint32_t cmd; /* The type of load command (LC_SEGMENT) */ + uint32_t cmdsize; /* Size in bytes of the entire command */ + char segname[MACH_O_NAMELEN]; /* Segment name */ + uint32_t vmaddr; /* Virtual memory address */ + uint32_t vmsize; /* Virtual memory size */ + uint32_t fileoff; /* Offset of data to be mapped */ + uint32_t filesize; /* Size of data in file */ + uint32_t maxprot; /* Maximum permitted virtual protection */ + uint32_t initprot; /* Initial virtual memory protection */ + uint32_t nsects; /* Number of sections in this segment */ + uint32_t flags; /* Flags */ +}; + +/* LC_SEGMENT_64 load command. */ + +struct macho_segment_64_command +{ + uint32_t cmd; /* The type of load command (LC_SEGMENT) */ + uint32_t cmdsize; /* Size in bytes of the entire command */ + char segname[MACH_O_NAMELEN]; /* Segment name */ + uint64_t vmaddr; /* Virtual memory address */ + uint64_t vmsize; /* Virtual memory size */ + uint64_t fileoff; /* Offset of data to be mapped */ + uint64_t filesize; /* Size of data in file */ + uint32_t maxprot; /* Maximum permitted virtual protection */ + uint32_t initprot; /* Initial virtual memory protection */ + uint32_t nsects; /* Number of sections in this segment */ + uint32_t flags; /* Flags */ +}; + +/* LC_SYMTAB load command. */ + +struct macho_symtab_command +{ + uint32_t cmd; /* The type of load command (LC_SEGMENT) */ + uint32_t cmdsize; /* Size in bytes of the entire command */ + uint32_t symoff; /* File offset of symbol table */ + uint32_t nsyms; /* Number of symbols */ + uint32_t stroff; /* File offset of string table */ + uint32_t strsize; /* String table size */ +}; + +/* The length of a Mach-O uuid. */ + +#define MACH_O_UUID_LEN (16) + +/* LC_UUID load command. */ + +struct macho_uuid_command +{ + uint32_t cmd; /* Type of load command (LC_UUID) */ + uint32_t cmdsize; /* Size in bytes of command */ + unsigned char uuid[MACH_O_UUID_LEN]; /* UUID */ +}; + +/* 32-bit section header within a LC_SEGMENT segment. */ + +struct macho_section +{ + char sectname[MACH_O_NAMELEN]; /* Section name */ + char segment[MACH_O_NAMELEN]; /* Segment of this section */ + uint32_t addr; /* Address in memory */ + uint32_t size; /* Section size */ + uint32_t offset; /* File offset */ + uint32_t align; /* Log2 of section alignment */ + uint32_t reloff; /* File offset of relocations */ + uint32_t nreloc; /* Number of relocs for this section */ + uint32_t flags; /* Flags */ + uint32_t reserved1; + uint32_t reserved2; +}; + +/* 64-bit section header within a LC_SEGMENT_64 segment. */ + +struct macho_section_64 +{ + char sectname[MACH_O_NAMELEN]; /* Section name */ + char segment[MACH_O_NAMELEN]; /* Segment of this section */ + uint64_t addr; /* Address in memory */ + uint64_t size; /* Section size */ + uint32_t offset; /* File offset */ + uint32_t align; /* Log2 of section alignment */ + uint32_t reloff; /* File offset of section relocations */ + uint32_t nreloc; /* Number of relocs for this section */ + uint32_t flags; /* Flags */ + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +}; + +/* 32-bit symbol data. */ + +struct macho_nlist +{ + uint32_t n_strx; /* Index of name in string table */ + uint8_t n_type; /* Type flag */ + uint8_t n_sect; /* Section number */ + uint16_t n_desc; /* Stabs description field */ + uint32_t n_value; /* Value */ +}; + +/* 64-bit symbol data. */ + +struct macho_nlist_64 +{ + uint32_t n_strx; /* Index of name in string table */ + uint8_t n_type; /* Type flag */ + uint8_t n_sect; /* Section number */ + uint16_t n_desc; /* Stabs description field */ + uint64_t n_value; /* Value */ +}; + +/* Value found in nlist n_type field. */ + +#define MACH_O_N_EXT 0x01 /* Extern symbol */ +#define MACH_O_N_ABS 0x02 /* Absolute symbol */ +#define MACH_O_N_SECT 0x0e /* Defined in section */ + +#define MACH_O_N_TYPE 0x0e /* Mask for type bits */ +#define MACH_O_N_STAB 0xe0 /* Stabs debugging symbol */ + +/* Information we keep for a Mach-O symbol. */ + +struct macho_symbol +{ + const char *name; /* Symbol name */ + uintptr_t address; /* Symbol address */ +}; + +/* Information to pass to macho_syminfo. */ + +struct macho_syminfo_data +{ + struct macho_syminfo_data *next; /* Next module */ + struct macho_symbol *symbols; /* Symbols sorted by address */ + size_t count; /* Number of symbols */ +}; + +/* Names of sections, indexed by enum dwarf_section in internal.h. */ + +static const char * const dwarf_section_names[DEBUG_MAX] = +{ + "__debug_info", + "__debug_line", + "__debug_abbrev", + "__debug_ranges", + "__debug_str", + "", /* DEBUG_ADDR */ + "__debug_str_offs", + "", /* DEBUG_LINE_STR */ + "__debug_rnglists" +}; + +/* Forward declaration. */ + +static int macho_add (struct backtrace_state *, const char *, int, off_t, + const unsigned char *, uintptr_t, int, + backtrace_error_callback, void *, fileline *, int *); + +/* A dummy callback function used when we can't find any debug info. */ + +static int +macho_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED, + uintptr_t pc ATTRIBUTE_UNUSED, + backtrace_full_callback callback ATTRIBUTE_UNUSED, + backtrace_error_callback error_callback, void *data) +{ + error_callback (data, "no debug info in Mach-O executable", -1); + return 0; +} + +/* A dummy callback function used when we can't find a symbol + table. */ + +static void +macho_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED, + uintptr_t addr ATTRIBUTE_UNUSED, + backtrace_syminfo_callback callback ATTRIBUTE_UNUSED, + backtrace_error_callback error_callback, void *data) +{ + error_callback (data, "no symbol table in Mach-O executable", -1); +} + +/* Add a single DWARF section to DWARF_SECTIONS, if we need the + section. Returns 1 on success, 0 on failure. */ + +static int +macho_add_dwarf_section (struct backtrace_state *state, int descriptor, + const char *sectname, uint32_t offset, uint64_t size, + backtrace_error_callback error_callback, void *data, + struct dwarf_sections *dwarf_sections) +{ + int i; + + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + if (dwarf_section_names[i][0] != '\0' + && strncmp (sectname, dwarf_section_names[i], MACH_O_NAMELEN) == 0) + { + struct backtrace_view section_view; + + /* FIXME: Perhaps it would be better to try to use a single + view to read all the DWARF data, as we try to do for + ELF. */ + + if (!backtrace_get_view (state, descriptor, offset, size, + error_callback, data, §ion_view)) + return 0; + dwarf_sections->data[i] = (const unsigned char *) section_view.data; + dwarf_sections->size[i] = size; + break; + } + } + return 1; +} + +/* Collect DWARF sections from a DWARF segment. Returns 1 on success, + 0 on failure. */ + +static int +macho_add_dwarf_segment (struct backtrace_state *state, int descriptor, + off_t offset, unsigned int cmd, const char *psecs, + size_t sizesecs, unsigned int nsects, + backtrace_error_callback error_callback, void *data, + struct dwarf_sections *dwarf_sections) +{ + size_t sec_header_size; + size_t secoffset; + unsigned int i; + + switch (cmd) + { + case MACH_O_LC_SEGMENT: + sec_header_size = sizeof (struct macho_section); + break; + case MACH_O_LC_SEGMENT_64: + sec_header_size = sizeof (struct macho_section_64); + break; + default: + abort (); + } + + secoffset = 0; + for (i = 0; i < nsects; ++i) + { + if (secoffset + sec_header_size > sizesecs) + { + error_callback (data, "section overflow withing segment", 0); + return 0; + } + + switch (cmd) + { + case MACH_O_LC_SEGMENT: + { + struct macho_section section; + + memcpy (§ion, psecs + secoffset, sizeof section); + macho_add_dwarf_section (state, descriptor, section.sectname, + offset + section.offset, section.size, + error_callback, data, dwarf_sections); + } + break; + + case MACH_O_LC_SEGMENT_64: + { + struct macho_section_64 section; + + memcpy (§ion, psecs + secoffset, sizeof section); + macho_add_dwarf_section (state, descriptor, section.sectname, + offset + section.offset, section.size, + error_callback, data, dwarf_sections); + } + break; + + default: + abort (); + } + + secoffset += sec_header_size; + } + + return 1; +} + +/* Compare struct macho_symbol for qsort. */ + +static int +macho_symbol_compare (const void *v1, const void *v2) +{ + const struct macho_symbol *m1 = (const struct macho_symbol *) v1; + const struct macho_symbol *m2 = (const struct macho_symbol *) v2; + + if (m1->address < m2->address) + return -1; + else if (m1->address > m2->address) + return 1; + else + return 0; +} + +/* Compare an address against a macho_symbol for bsearch. We allocate + one extra entry in the array so that this can safely look at the + next entry. */ + +static int +macho_symbol_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct macho_symbol *entry = (const struct macho_symbol *) ventry; + uintptr_t addr; + + addr = *key; + if (addr < entry->address) + return -1; + else if (entry->name[0] == '\0' + && entry->address == ~(uintptr_t) 0) + return -1; + else if ((entry + 1)->name[0] == '\0' + && (entry + 1)->address == ~(uintptr_t) 0) + return -1; + else if (addr >= (entry + 1)->address) + return 1; + else + return 0; +} + +/* Return whether the symbol type field indicates a symbol table entry + that we care about: a function or data symbol. */ + +static int +macho_defined_symbol (uint8_t type) +{ + if ((type & MACH_O_N_STAB) != 0) + return 0; + if ((type & MACH_O_N_EXT) != 0) + return 0; + switch (type & MACH_O_N_TYPE) + { + case MACH_O_N_ABS: + return 1; + case MACH_O_N_SECT: + return 1; + default: + return 0; + } +} + +/* Add symbol table information for a Mach-O file. */ + +static int +macho_add_symtab (struct backtrace_state *state, int descriptor, + uintptr_t base_address, int is_64, + off_t symoff, unsigned int nsyms, off_t stroff, + unsigned int strsize, + backtrace_error_callback error_callback, void *data) +{ + size_t symsize; + struct backtrace_view sym_view; + int sym_view_valid; + struct backtrace_view str_view; + int str_view_valid; + size_t ndefs; + size_t symtaboff; + unsigned int i; + size_t macho_symbol_size; + struct macho_symbol *macho_symbols; + unsigned int j; + struct macho_syminfo_data *sdata; + + sym_view_valid = 0; + str_view_valid = 0; + macho_symbol_size = 0; + macho_symbols = NULL; + + if (is_64) + symsize = sizeof (struct macho_nlist_64); + else + symsize = sizeof (struct macho_nlist); + + if (!backtrace_get_view (state, descriptor, symoff, nsyms * symsize, + error_callback, data, &sym_view)) + goto fail; + sym_view_valid = 1; + + if (!backtrace_get_view (state, descriptor, stroff, strsize, + error_callback, data, &str_view)) + return 0; + str_view_valid = 1; + + ndefs = 0; + symtaboff = 0; + for (i = 0; i < nsyms; ++i, symtaboff += symsize) + { + if (is_64) + { + struct macho_nlist_64 nlist; + + memcpy (&nlist, (const char *) sym_view.data + symtaboff, + sizeof nlist); + if (macho_defined_symbol (nlist.n_type)) + ++ndefs; + } + else + { + struct macho_nlist nlist; + + memcpy (&nlist, (const char *) sym_view.data + symtaboff, + sizeof nlist); + if (macho_defined_symbol (nlist.n_type)) + ++ndefs; + } + } + + /* Add 1 to ndefs to make room for a sentinel. */ + macho_symbol_size = (ndefs + 1) * sizeof (struct macho_symbol); + macho_symbols = ((struct macho_symbol *) + backtrace_alloc (state, macho_symbol_size, error_callback, + data)); + if (macho_symbols == NULL) + goto fail; + + j = 0; + symtaboff = 0; + for (i = 0; i < nsyms; ++i, symtaboff += symsize) + { + uint32_t strx; + uint64_t value; + const char *name; + + strx = 0; + value = 0; + if (is_64) + { + struct macho_nlist_64 nlist; + + memcpy (&nlist, (const char *) sym_view.data + symtaboff, + sizeof nlist); + if (!macho_defined_symbol (nlist.n_type)) + continue; + + strx = nlist.n_strx; + value = nlist.n_value; + } + else + { + struct macho_nlist nlist; + + memcpy (&nlist, (const char *) sym_view.data + symtaboff, + sizeof nlist); + if (!macho_defined_symbol (nlist.n_type)) + continue; + + strx = nlist.n_strx; + value = nlist.n_value; + } + + if (strx >= strsize) + { + error_callback (data, "symbol string index out of range", 0); + goto fail; + } + + name = (const char *) str_view.data + strx; + if (name[0] == '_') + ++name; + macho_symbols[j].name = name; + macho_symbols[j].address = value + base_address; + ++j; + } + + sdata = ((struct macho_syminfo_data *) + backtrace_alloc (state, sizeof *sdata, error_callback, data)); + if (sdata == NULL) + goto fail; + + /* We need to keep the string table since it holds the names, but we + can release the symbol table. */ + + backtrace_release_view (state, &sym_view, error_callback, data); + sym_view_valid = 0; + str_view_valid = 0; + + /* Add a trailing sentinel symbol. */ + macho_symbols[j].name = ""; + macho_symbols[j].address = ~(uintptr_t) 0; + + backtrace_qsort (macho_symbols, ndefs + 1, sizeof (struct macho_symbol), + macho_symbol_compare); + + sdata->next = NULL; + sdata->symbols = macho_symbols; + sdata->count = ndefs; + + if (!state->threaded) + { + struct macho_syminfo_data **pp; + + for (pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data; + *pp != NULL; + pp = &(*pp)->next) + ; + *pp = sdata; + } + else + { + while (1) + { + struct macho_syminfo_data **pp; + + pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data; + + while (1) + { + struct macho_syminfo_data *p; + + p = backtrace_atomic_load_pointer (pp); + + if (p == NULL) + break; + + pp = &p->next; + } + + if (__sync_bool_compare_and_swap (pp, NULL, sdata)) + break; + } + } + + return 1; + + fail: + if (macho_symbols != NULL) + backtrace_free (state, macho_symbols, macho_symbol_size, + error_callback, data); + if (sym_view_valid) + backtrace_release_view (state, &sym_view, error_callback, data); + if (str_view_valid) + backtrace_release_view (state, &str_view, error_callback, data); + return 0; +} + +/* Return the symbol name and value for an ADDR. */ + +static void +macho_syminfo (struct backtrace_state *state, uintptr_t addr, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback ATTRIBUTE_UNUSED, + void *data) +{ + struct macho_syminfo_data *sdata; + struct macho_symbol *sym; + + sym = NULL; + if (!state->threaded) + { + for (sdata = (struct macho_syminfo_data *) state->syminfo_data; + sdata != NULL; + sdata = sdata->next) + { + sym = ((struct macho_symbol *) + bsearch (&addr, sdata->symbols, sdata->count, + sizeof (struct macho_symbol), macho_symbol_search)); + if (sym != NULL) + break; + } + } + else + { + struct macho_syminfo_data **pp; + + pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data; + while (1) + { + sdata = backtrace_atomic_load_pointer (pp); + if (sdata == NULL) + break; + + sym = ((struct macho_symbol *) + bsearch (&addr, sdata->symbols, sdata->count, + sizeof (struct macho_symbol), macho_symbol_search)); + if (sym != NULL) + break; + + pp = &sdata->next; + } + } + + if (sym == NULL) + callback (data, addr, NULL, 0, 0); + else + callback (data, addr, sym->name, sym->address, 0); +} + +/* Look through a fat file to find the relevant executable. Returns 1 + on success, 0 on failure (in both cases descriptor is closed). */ + +static int +macho_add_fat (struct backtrace_state *state, const char *filename, + int descriptor, int swapped, off_t offset, + const unsigned char *match_uuid, uintptr_t base_address, + int skip_symtab, uint32_t nfat_arch, int is_64, + backtrace_error_callback error_callback, void *data, + fileline *fileline_fn, int *found_sym) +{ + int arch_view_valid; + unsigned int cputype; + size_t arch_size; + struct backtrace_view arch_view; + unsigned int i; + + arch_view_valid = 0; + +#if defined (__x86_64__) + cputype = MACH_O_CPU_TYPE_X86_64; +#elif defined (__i386__) + cputype = MACH_O_CPU_TYPE_X86; +#elif defined (__aarch64__) + cputype = MACH_O_CPU_TYPE_ARM64; +#elif defined (__arm__) + cputype = MACH_O_CPU_TYPE_ARM; +#elif defined (__ppc__) + cputype = MACH_O_CPU_TYPE_PPC; +#elif defined (__ppc64__) + cputype = MACH_O_CPU_TYPE_PPC64; +#else + error_callback (data, "unknown Mach-O architecture", 0); + goto fail; +#endif + + if (is_64) + arch_size = sizeof (struct macho_fat_arch_64); + else + arch_size = sizeof (struct macho_fat_arch); + + if (!backtrace_get_view (state, descriptor, offset, + nfat_arch * arch_size, + error_callback, data, &arch_view)) + goto fail; + + for (i = 0; i < nfat_arch; ++i) + { + uint32_t fcputype; + uint64_t foffset; + + if (is_64) + { + struct macho_fat_arch_64 fat_arch_64; + + memcpy (&fat_arch_64, + (const char *) arch_view.data + i * arch_size, + arch_size); + fcputype = fat_arch_64.cputype; + foffset = fat_arch_64.offset; + if (swapped) + { + fcputype = __builtin_bswap32 (fcputype); + foffset = __builtin_bswap64 (foffset); + } + } + else + { + struct macho_fat_arch fat_arch_32; + + memcpy (&fat_arch_32, + (const char *) arch_view.data + i * arch_size, + arch_size); + fcputype = fat_arch_32.cputype; + foffset = (uint64_t) fat_arch_32.offset; + if (swapped) + { + fcputype = __builtin_bswap32 (fcputype); + foffset = (uint64_t) __builtin_bswap32 ((uint32_t) foffset); + } + } + + if (fcputype == cputype) + { + /* FIXME: What about cpusubtype? */ + backtrace_release_view (state, &arch_view, error_callback, data); + return macho_add (state, filename, descriptor, foffset, match_uuid, + base_address, skip_symtab, error_callback, data, + fileline_fn, found_sym); + } + } + + error_callback (data, "could not find executable in fat file", 0); + + fail: + if (arch_view_valid) + backtrace_release_view (state, &arch_view, error_callback, data); + if (descriptor != -1) + backtrace_close (descriptor, error_callback, data); + return 0; +} + +/* Look for the dsym file for FILENAME. This is called if FILENAME + does not have debug info or a symbol table. Returns 1 on success, + 0 on failure. */ + +static int +macho_add_dsym (struct backtrace_state *state, const char *filename, + uintptr_t base_address, const unsigned char *uuid, + backtrace_error_callback error_callback, void *data, + fileline* fileline_fn) +{ + const char *p; + const char *dirname; + char *diralc; + size_t dirnamelen; + const char *basename; + size_t basenamelen; + const char *dsymsuffixdir; + size_t dsymsuffixdirlen; + size_t dsymlen; + char *dsym; + char *ps; + int d; + int does_not_exist; + int dummy_found_sym; + + diralc = NULL; + dirnamelen = 0; + dsym = NULL; + dsymlen = 0; + + p = strrchr (filename, '/'); + if (p == NULL) + { + dirname = "."; + dirnamelen = 1; + basename = filename; + basenamelen = strlen (basename); + diralc = NULL; + } + else + { + dirnamelen = p - filename; + diralc = (char*)backtrace_alloc (state, dirnamelen + 1, error_callback, data); + if (diralc == NULL) + goto fail; + memcpy (diralc, filename, dirnamelen); + diralc[dirnamelen] = '\0'; + dirname = diralc; + basename = p + 1; + basenamelen = strlen (basename); + } + + dsymsuffixdir = ".dSYM/Contents/Resources/DWARF/"; + dsymsuffixdirlen = strlen (dsymsuffixdir); + + dsymlen = (dirnamelen + + 1 + + basenamelen + + dsymsuffixdirlen + + basenamelen + + 1); + dsym = (char*)backtrace_alloc (state, dsymlen, error_callback, data); + if (dsym == NULL) + goto fail; + + ps = dsym; + memcpy (ps, dirname, dirnamelen); + ps += dirnamelen; + *ps++ = '/'; + memcpy (ps, basename, basenamelen); + ps += basenamelen; + memcpy (ps, dsymsuffixdir, dsymsuffixdirlen); + ps += dsymsuffixdirlen; + memcpy (ps, basename, basenamelen); + ps += basenamelen; + *ps = '\0'; + + if (diralc != NULL) + { + backtrace_free (state, diralc, dirnamelen + 1, error_callback, data); + diralc = NULL; + } + + d = backtrace_open (dsym, error_callback, data, &does_not_exist); + if (d < 0) + { + /* The file does not exist, so we can't read the debug info. + Just return success. */ + backtrace_free (state, dsym, dsymlen, error_callback, data); + return 1; + } + + if (!macho_add (state, dsym, d, 0, uuid, base_address, 1, + error_callback, data, fileline_fn, &dummy_found_sym)) + goto fail; + + backtrace_free (state, dsym, dsymlen, error_callback, data); + + return 1; + + fail: + if (dsym != NULL) + backtrace_free (state, dsym, dsymlen, error_callback, data); + if (diralc != NULL) + backtrace_free (state, diralc, dirnamelen, error_callback, data); + return 0; +} + +/* Add the backtrace data for a Macho-O file. Returns 1 on success, 0 + on failure (in both cases descriptor is closed). + + FILENAME: the name of the executable. + DESCRIPTOR: an open descriptor for the executable, closed here. + OFFSET: the offset within the file of this executable, for fat files. + MATCH_UUID: if not NULL, UUID that must match. + BASE_ADDRESS: the load address of the executable. + SKIP_SYMTAB: if non-zero, ignore the symbol table; used for dSYM files. + FILELINE_FN: set to the fileline function, by backtrace_dwarf_add. + FOUND_SYM: set to non-zero if we found the symbol table. +*/ + +static int +macho_add (struct backtrace_state *state, const char *filename, int descriptor, + off_t offset, const unsigned char *match_uuid, + uintptr_t base_address, int skip_symtab, + backtrace_error_callback error_callback, void *data, + fileline *fileline_fn, int *found_sym) +{ + struct backtrace_view header_view; + struct macho_header_32 header; + off_t hdroffset; + int is_64; + struct backtrace_view cmds_view; + int cmds_view_valid; + struct dwarf_sections dwarf_sections; + int have_dwarf; + unsigned char uuid[MACH_O_UUID_LEN]; + int have_uuid; + size_t cmdoffset; + unsigned int i; + + *found_sym = 0; + + cmds_view_valid = 0; + + /* The 32-bit and 64-bit file headers start out the same, so we can + just always read the 32-bit version. A fat header is shorter but + it will always be followed by data, so it's OK to read extra. */ + + if (!backtrace_get_view (state, descriptor, offset, + sizeof (struct macho_header_32), + error_callback, data, &header_view)) + goto fail; + + memcpy (&header, header_view.data, sizeof header); + + backtrace_release_view (state, &header_view, error_callback, data); + + switch (header.magic) + { + case MACH_O_MH_MAGIC_32: + is_64 = 0; + hdroffset = offset + sizeof (struct macho_header_32); + break; + case MACH_O_MH_MAGIC_64: + is_64 = 1; + hdroffset = offset + sizeof (struct macho_header_64); + break; + case MACH_O_MH_MAGIC_FAT: + case MACH_O_MH_MAGIC_FAT_64: + { + struct macho_header_fat fat_header; + + hdroffset = offset + sizeof (struct macho_header_fat); + memcpy (&fat_header, &header, sizeof fat_header); + return macho_add_fat (state, filename, descriptor, 0, hdroffset, + match_uuid, base_address, skip_symtab, + fat_header.nfat_arch, + header.magic == MACH_O_MH_MAGIC_FAT_64, + error_callback, data, fileline_fn, found_sym); + } + case MACH_O_MH_CIGAM_FAT: + case MACH_O_MH_CIGAM_FAT_64: + { + struct macho_header_fat fat_header; + uint32_t nfat_arch; + + hdroffset = offset + sizeof (struct macho_header_fat); + memcpy (&fat_header, &header, sizeof fat_header); + nfat_arch = __builtin_bswap32 (fat_header.nfat_arch); + return macho_add_fat (state, filename, descriptor, 1, hdroffset, + match_uuid, base_address, skip_symtab, + nfat_arch, + header.magic == MACH_O_MH_CIGAM_FAT_64, + error_callback, data, fileline_fn, found_sym); + } + default: + error_callback (data, "executable file is not in Mach-O format", 0); + goto fail; + } + + switch (header.filetype) + { + case MACH_O_MH_EXECUTE: + case MACH_O_MH_DYLIB: + case MACH_O_MH_DSYM: + break; + default: + error_callback (data, "executable file is not an executable", 0); + goto fail; + } + + if (!backtrace_get_view (state, descriptor, hdroffset, header.sizeofcmds, + error_callback, data, &cmds_view)) + goto fail; + cmds_view_valid = 1; + + memset (&dwarf_sections, 0, sizeof dwarf_sections); + have_dwarf = 0; + memset (&uuid, 0, sizeof uuid); + have_uuid = 0; + + cmdoffset = 0; + for (i = 0; i < header.ncmds; ++i) + { + const char *pcmd; + struct macho_load_command load_command; + + if (cmdoffset + sizeof load_command > header.sizeofcmds) + break; + + pcmd = (const char *) cmds_view.data + cmdoffset; + memcpy (&load_command, pcmd, sizeof load_command); + + switch (load_command.cmd) + { + case MACH_O_LC_SEGMENT: + { + struct macho_segment_command segcmd; + + memcpy (&segcmd, pcmd, sizeof segcmd); + if (memcmp (segcmd.segname, + "__DWARF\0\0\0\0\0\0\0\0\0", + MACH_O_NAMELEN) == 0) + { + if (!macho_add_dwarf_segment (state, descriptor, offset, + load_command.cmd, + pcmd + sizeof segcmd, + (load_command.cmdsize + - sizeof segcmd), + segcmd.nsects, error_callback, + data, &dwarf_sections)) + goto fail; + have_dwarf = 1; + } + } + break; + + case MACH_O_LC_SEGMENT_64: + { + struct macho_segment_64_command segcmd; + + memcpy (&segcmd, pcmd, sizeof segcmd); + if (memcmp (segcmd.segname, + "__DWARF\0\0\0\0\0\0\0\0\0", + MACH_O_NAMELEN) == 0) + { + if (!macho_add_dwarf_segment (state, descriptor, offset, + load_command.cmd, + pcmd + sizeof segcmd, + (load_command.cmdsize + - sizeof segcmd), + segcmd.nsects, error_callback, + data, &dwarf_sections)) + goto fail; + have_dwarf = 1; + } + } + break; + + case MACH_O_LC_SYMTAB: + if (!skip_symtab) + { + struct macho_symtab_command symcmd; + + memcpy (&symcmd, pcmd, sizeof symcmd); + if (!macho_add_symtab (state, descriptor, base_address, is_64, + offset + symcmd.symoff, symcmd.nsyms, + offset + symcmd.stroff, symcmd.strsize, + error_callback, data)) + goto fail; + + *found_sym = 1; + } + break; + + case MACH_O_LC_UUID: + { + struct macho_uuid_command uuidcmd; + + memcpy (&uuidcmd, pcmd, sizeof uuidcmd); + memcpy (&uuid[0], &uuidcmd.uuid[0], MACH_O_UUID_LEN); + have_uuid = 1; + } + break; + + default: + break; + } + + cmdoffset += load_command.cmdsize; + } + + if (!backtrace_close (descriptor, error_callback, data)) + goto fail; + descriptor = -1; + + backtrace_release_view (state, &cmds_view, error_callback, data); + cmds_view_valid = 0; + + if (match_uuid != NULL) + { + /* If we don't have a UUID, or it doesn't match, just ignore + this file. */ + if (!have_uuid + || memcmp (match_uuid, &uuid[0], MACH_O_UUID_LEN) != 0) + return 1; + } + + if (have_dwarf) + { + int is_big_endian; + + is_big_endian = 0; +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + is_big_endian = 1; +#endif +#endif + + if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, + is_big_endian, NULL, error_callback, data, + fileline_fn, NULL)) + goto fail; + } + + if (!have_dwarf && have_uuid) + { + if (!macho_add_dsym (state, filename, base_address, &uuid[0], + error_callback, data, fileline_fn)) + goto fail; + } + + return 1; + + fail: + if (cmds_view_valid) + backtrace_release_view (state, &cmds_view, error_callback, data); + if (descriptor != -1) + backtrace_close (descriptor, error_callback, data); + return 0; +} + +#ifdef HAVE_MACH_O_DYLD_H + +/* Initialize the backtrace data we need from a Mach-O executable + using the dyld support functions. This closes descriptor. */ + +int +backtrace_initialize (struct backtrace_state *state, const char *filename, + int descriptor, backtrace_error_callback error_callback, + void *data, fileline *fileline_fn) +{ + uint32_t c; + uint32_t i; + int closed_descriptor; + int found_sym; + fileline macho_fileline_fn; + + closed_descriptor = 0; + found_sym = 0; + macho_fileline_fn = macho_nodebug; + + c = _dyld_image_count (); + for (i = 0; i < c; ++i) + { + uintptr_t base_address; + const char *name; + int d; + fileline mff; + int mfs; + + name = _dyld_get_image_name (i); + if (name == NULL) + continue; + + if (strcmp (name, filename) == 0 && !closed_descriptor) + { + d = descriptor; + closed_descriptor = 1; + } + else + { + int does_not_exist; + + d = backtrace_open (name, error_callback, data, &does_not_exist); + if (d < 0) + continue; + } + + base_address = _dyld_get_image_vmaddr_slide (i); + + mff = macho_nodebug; + if (!macho_add (state, name, d, 0, NULL, base_address, 0, + error_callback, data, &mff, &mfs)) + continue; + + if (mff != macho_nodebug) + macho_fileline_fn = mff; + if (mfs) + found_sym = 1; + } + + if (!closed_descriptor) + backtrace_close (descriptor, error_callback, data); + + if (!state->threaded) + { + if (found_sym) + state->syminfo_fn = macho_syminfo; + else if (state->syminfo_fn == NULL) + state->syminfo_fn = macho_nosyms; + } + else + { + if (found_sym) + backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo); + else + (void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL, + macho_nosyms); + } + + if (!state->threaded) + *fileline_fn = state->fileline_fn; + else + *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn); + + if (*fileline_fn == NULL || *fileline_fn == macho_nodebug) + *fileline_fn = macho_fileline_fn; + + return 1; +} + +#else /* !defined (HAVE_MACH_O_DYLD_H) */ + +/* Initialize the backtrace data we need from a Mach-O executable + without using the dyld support functions. This closes + descriptor. */ + +int +backtrace_initialize (struct backtrace_state *state, const char *filename, + int descriptor, backtrace_error_callback error_callback, + void *data, fileline *fileline_fn) +{ + fileline macho_fileline_fn; + int found_sym; + + macho_fileline_fn = macho_nodebug; + if (!macho_add (state, filename, descriptor, 0, NULL, 0, 0, + error_callback, data, &macho_fileline_fn, &found_sym)) + return 0; + + if (!state->threaded) + { + if (found_sym) + state->syminfo_fn = macho_syminfo; + else if (state->syminfo_fn == NULL) + state->syminfo_fn = macho_nosyms; + } + else + { + if (found_sym) + backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo); + else + (void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL, + macho_nosyms); + } + + if (!state->threaded) + *fileline_fn = state->fileline_fn; + else + *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn); + + if (*fileline_fn == NULL || *fileline_fn == macho_nodebug) + *fileline_fn = macho_fileline_fn; + + return 1; +} + +#endif /* !defined (HAVE_MACH_O_DYLD_H) */ + +} diff --git a/Externals/tracy/public/libbacktrace/mmapio.cpp b/Externals/tracy/public/libbacktrace/mmapio.cpp new file mode 100644 index 00000000000..0e8f599bb82 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/mmapio.cpp @@ -0,0 +1,115 @@ +/* mmapio.c -- File views using mmap. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include + +#include "backtrace.hpp" +#include "internal.hpp" + +#ifndef HAVE_DECL_GETPAGESIZE +extern int getpagesize (void); +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +namespace tracy +{ + +/* This file implements file views and memory allocation when mmap is + available. */ + +/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */ + +int +backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED, + int descriptor, off_t offset, uint64_t size, + backtrace_error_callback error_callback, + void *data, struct backtrace_view *view) +{ + size_t pagesize; + unsigned int inpage; + off_t pageoff; + void *map; + + if ((uint64_t) (size_t) size != size) + { + error_callback (data, "file size too large", 0); + return 0; + } + + pagesize = getpagesize (); + inpage = offset % pagesize; + pageoff = offset - inpage; + + size += inpage; + size = (size + (pagesize - 1)) & ~ (pagesize - 1); + + map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff); + if (map == MAP_FAILED) + { + error_callback (data, "mmap", errno); + return 0; + } + + view->data = (char *) map + inpage; + view->base = map; + view->len = size; + + return 1; +} + +/* Release a view read by backtrace_get_view. */ + +void +backtrace_release_view (struct backtrace_state *state ATTRIBUTE_UNUSED, + struct backtrace_view *view, + backtrace_error_callback error_callback, + void *data) +{ + union { + const void *cv; + void *v; + } cc; + + cc.cv = view->base; + if (munmap (cc.v, view->len) < 0) + error_callback (data, "munmap", errno); +} + +} diff --git a/Externals/tracy/public/libbacktrace/posix.cpp b/Externals/tracy/public/libbacktrace/posix.cpp new file mode 100644 index 00000000000..8233a8ea324 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/posix.cpp @@ -0,0 +1,109 @@ +/* posix.c -- POSIX file I/O routines for the backtrace library. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "backtrace.hpp" +#include "internal.hpp" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 +#endif + +namespace tracy +{ + +/* Open a file for reading. */ + +int +backtrace_open (const char *filename, backtrace_error_callback error_callback, + void *data, int *does_not_exist) +{ + int descriptor; + + if (does_not_exist != NULL) + *does_not_exist = 0; + + descriptor = open (filename, (int) (O_RDONLY | O_BINARY | O_CLOEXEC)); + if (descriptor < 0) + { + /* If DOES_NOT_EXIST is not NULL, then don't call ERROR_CALLBACK + if the file does not exist. We treat lacking permission to + open the file as the file not existing; this case arises when + running the libgo syscall package tests as root. */ + if (does_not_exist != NULL && (errno == ENOENT || errno == EACCES)) + *does_not_exist = 1; + else + error_callback (data, filename, errno); + return -1; + } + +#ifdef HAVE_FCNTL + /* Set FD_CLOEXEC just in case the kernel does not support + O_CLOEXEC. It doesn't matter if this fails for some reason. + FIXME: At some point it should be safe to only do this if + O_CLOEXEC == 0. */ + fcntl (descriptor, F_SETFD, FD_CLOEXEC); +#endif + + return descriptor; +} + +/* Close DESCRIPTOR. */ + +int +backtrace_close (int descriptor, backtrace_error_callback error_callback, + void *data) +{ + if (close (descriptor) < 0) + { + error_callback (data, "close", errno); + return 0; + } + return 1; +} + +} diff --git a/Externals/tracy/public/libbacktrace/sort.cpp b/Externals/tracy/public/libbacktrace/sort.cpp new file mode 100644 index 00000000000..6daee0a64fd --- /dev/null +++ b/Externals/tracy/public/libbacktrace/sort.cpp @@ -0,0 +1,113 @@ +/* sort.c -- Sort without allocating memory + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include + +#include "backtrace.hpp" +#include "internal.hpp" + +namespace tracy +{ + +/* The GNU glibc version of qsort allocates memory, which we must not + do if we are invoked by a signal handler. So provide our own + sort. */ + +static void +swap (char *a, char *b, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++, a++, b++) + { + char t; + + t = *a; + *a = *b; + *b = t; + } +} + +void +backtrace_qsort (void *basearg, size_t count, size_t size, + int (*compar) (const void *, const void *)) +{ + char *base = (char *) basearg; + size_t i; + size_t mid; + + tail_recurse: + if (count < 2) + return; + + /* The symbol table and DWARF tables, which is all we use this + routine for, tend to be roughly sorted. Pick the middle element + in the array as our pivot point, so that we are more likely to + cut the array in half for each recursion step. */ + swap (base, base + (count / 2) * size, size); + + mid = 0; + for (i = 1; i < count; i++) + { + if ((*compar) (base, base + i * size) > 0) + { + ++mid; + if (i != mid) + swap (base + mid * size, base + i * size, size); + } + } + + if (mid > 0) + swap (base, base + mid * size, size); + + /* Recurse with the smaller array, loop with the larger one. That + ensures that our maximum stack depth is log count. */ + if (2 * mid < count) + { + backtrace_qsort (base, mid, size, compar); + base += (mid + 1) * size; + count -= mid + 1; + goto tail_recurse; + } + else + { + backtrace_qsort (base + (mid + 1) * size, count - (mid + 1), + size, compar); + count = mid; + goto tail_recurse; + } +} + +} diff --git a/Externals/tracy/public/libbacktrace/state.cpp b/Externals/tracy/public/libbacktrace/state.cpp new file mode 100644 index 00000000000..ea3c137c5d5 --- /dev/null +++ b/Externals/tracy/public/libbacktrace/state.cpp @@ -0,0 +1,76 @@ +/* state.c -- Create the backtrace state. + Copyright (C) 2012-2021 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include +#include + +#include "backtrace.hpp" +#include "internal.hpp" + +namespace tracy +{ + +/* Create the backtrace state. This will then be passed to all the + other routines. */ + +struct backtrace_state * +backtrace_create_state (const char *filename, int threaded, + backtrace_error_callback error_callback, + void *data) +{ + struct backtrace_state init_state; + struct backtrace_state *state; + +#ifndef HAVE_SYNC_FUNCTIONS + if (threaded) + { + error_callback (data, "backtrace library does not support threads", 0); + return NULL; + } +#endif + + memset (&init_state, 0, sizeof init_state); + init_state.filename = filename; + init_state.threaded = threaded; + + state = ((struct backtrace_state *) + backtrace_alloc (&init_state, sizeof *state, error_callback, data)); + if (state == NULL) + return NULL; + *state = init_state; + + return state; +} + +} diff --git a/Externals/tracy/public/tracy/Tracy.hpp b/Externals/tracy/public/tracy/Tracy.hpp new file mode 100644 index 00000000000..978eb5ef15c --- /dev/null +++ b/Externals/tracy/public/tracy/Tracy.hpp @@ -0,0 +1,283 @@ +#ifndef __TRACY_HPP__ +#define __TRACY_HPP__ + +#include "../common/TracyColor.hpp" +#include "../common/TracySystem.hpp" + +#ifndef TracyFunction +# define TracyFunction __FUNCTION__ +#endif + +#ifndef TracyFile +# define TracyFile __FILE__ +#endif + +#ifndef TracyLine +# define TracyLine __LINE__ +#endif + +#ifndef TRACY_ENABLE + +#define ZoneNamed(x,y) +#define ZoneNamedN(x,y,z) +#define ZoneNamedC(x,y,z) +#define ZoneNamedNC(x,y,z,w) + +#define ZoneTransient(x,y) +#define ZoneTransientN(x,y,z) + +#define ZoneScoped +#define ZoneScopedN(x) +#define ZoneScopedC(x) +#define ZoneScopedNC(x,y) + +#define ZoneText(x,y) +#define ZoneTextV(x,y,z) +#define ZoneName(x,y) +#define ZoneNameV(x,y,z) +#define ZoneColor(x) +#define ZoneColorV(x,y) +#define ZoneValue(x) +#define ZoneValueV(x,y) +#define ZoneIsActive false +#define ZoneIsActiveV(x) false + +#define FrameMark +#define FrameMarkNamed(x) +#define FrameMarkStart(x) +#define FrameMarkEnd(x) + +#define FrameImage(x,y,z,w,a) + +#define TracyLockable( type, varname ) type varname +#define TracyLockableN( type, varname, desc ) type varname +#define TracySharedLockable( type, varname ) type varname +#define TracySharedLockableN( type, varname, desc ) type varname +#define LockableBase( type ) type +#define SharedLockableBase( type ) type +#define LockMark(x) (void)x +#define LockableName(x,y,z) + +#define TracyPlot(x,y) +#define TracyPlotConfig(x,y,z,w,a) + +#define TracyMessage(x,y) +#define TracyMessageL(x) +#define TracyMessageC(x,y,z) +#define TracyMessageLC(x,y) +#define TracyAppInfo(x,y) + +#define TracyAlloc(x,y) +#define TracyFree(x) +#define TracySecureAlloc(x,y) +#define TracySecureFree(x) + +#define TracyAllocN(x,y,z) +#define TracyFreeN(x,y) +#define TracySecureAllocN(x,y,z) +#define TracySecureFreeN(x,y) + +#define ZoneNamedS(x,y,z) +#define ZoneNamedNS(x,y,z,w) +#define ZoneNamedCS(x,y,z,w) +#define ZoneNamedNCS(x,y,z,w,a) + +#define ZoneTransientS(x,y,z) +#define ZoneTransientNS(x,y,z,w) + +#define ZoneScopedS(x) +#define ZoneScopedNS(x,y) +#define ZoneScopedCS(x,y) +#define ZoneScopedNCS(x,y,z) + +#define TracyAllocS(x,y,z) +#define TracyFreeS(x,y) +#define TracySecureAllocS(x,y,z) +#define TracySecureFreeS(x,y) + +#define TracyAllocNS(x,y,z,w) +#define TracyFreeNS(x,y,z) +#define TracySecureAllocNS(x,y,z,w) +#define TracySecureFreeNS(x,y,z) + +#define TracyMessageS(x,y,z) +#define TracyMessageLS(x,y) +#define TracyMessageCS(x,y,z,w) +#define TracyMessageLCS(x,y,z) + +#define TracySourceCallbackRegister(x,y) +#define TracyParameterRegister(x,y) +#define TracyParameterSetup(x,y,z,w) +#define TracyIsConnected false +#define TracySetProgramName(x) + +#define TracyFiberEnter(x) +#define TracyFiberLeave + +#else + +#include + +#include "../client/TracyLock.hpp" +#include "../client/TracyProfiler.hpp" +#include "../client/TracyScoped.hpp" + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ) +# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ) +# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ) +# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ) + +# define ZoneTransient( varname, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, TRACY_CALLSTACK, active ) +# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active ) +#else +# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active ) +# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active ) +# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active ) +# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active ) + +# define ZoneTransient( varname, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, active ) +# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active ) +#endif + +#define ZoneScoped ZoneNamed( ___tracy_scoped_zone, true ) +#define ZoneScopedN( name ) ZoneNamedN( ___tracy_scoped_zone, name, true ) +#define ZoneScopedC( color ) ZoneNamedC( ___tracy_scoped_zone, color, true ) +#define ZoneScopedNC( name, color ) ZoneNamedNC( ___tracy_scoped_zone, name, color, true ) + +#define ZoneText( txt, size ) ___tracy_scoped_zone.Text( txt, size ) +#define ZoneTextV( varname, txt, size ) varname.Text( txt, size ) +#define ZoneName( txt, size ) ___tracy_scoped_zone.Name( txt, size ) +#define ZoneNameV( varname, txt, size ) varname.Name( txt, size ) +#define ZoneColor( color ) ___tracy_scoped_zone.Color( color ) +#define ZoneColorV( varname, color ) varname.Color( color ) +#define ZoneValue( value ) ___tracy_scoped_zone.Value( value ) +#define ZoneValueV( varname, value ) varname.Value( value ) +#define ZoneIsActive ___tracy_scoped_zone.IsActive() +#define ZoneIsActiveV( varname ) varname.IsActive() + +#define FrameMark tracy::Profiler::SendFrameMark( nullptr ) +#define FrameMarkNamed( name ) tracy::Profiler::SendFrameMark( name ) +#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart ) +#define FrameMarkEnd( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd ) + +#define FrameImage( image, width, height, offset, flip ) tracy::Profiler::SendFrameImage( image, width, height, offset, flip ) + +#define TracyLockable( type, varname ) tracy::Lockable varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, TracyFile, TracyLine, 0 }; return &srcloc; }() } +#define TracyLockableN( type, varname, desc ) tracy::Lockable varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, TracyFile, TracyLine, 0 }; return &srcloc; }() } +#define TracySharedLockable( type, varname ) tracy::SharedLockable varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, TracyFile, TracyLine, 0 }; return &srcloc; }() } +#define TracySharedLockableN( type, varname, desc ) tracy::SharedLockable varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, TracyFile, TracyLine, 0 }; return &srcloc; }() } +#define LockableBase( type ) tracy::Lockable +#define SharedLockableBase( type ) tracy::SharedLockable +#define LockMark( varname ) static constexpr tracy::SourceLocationData __tracy_lock_location_##varname { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; varname.Mark( &__tracy_lock_location_##varname ) +#define LockableName( varname, txt, size ) varname.CustomName( txt, size ) + +#define TracyPlot( name, val ) tracy::Profiler::PlotData( name, val ) +#define TracyPlotConfig( name, type, step, fill, color ) tracy::Profiler::ConfigurePlot( name, type, step, fill, color ) + +#define TracyAppInfo( txt, size ) tracy::Profiler::MessageAppInfo( txt, size ) + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, TRACY_CALLSTACK ) +# define TracyMessageL( txt ) tracy::Profiler::Message( txt, TRACY_CALLSTACK ) +# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, TRACY_CALLSTACK ) +# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK ) + +# define TracyAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, false ) +# define TracyFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, false ) +# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, true ) +# define TracySecureFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, true ) + +# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name ) +# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name ) +# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name ) +# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name ) +#else +# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 ) +# define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 ) +# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, 0 ) +# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, 0 ) + +# define TracyAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, false ) +# define TracyFree( ptr ) tracy::Profiler::MemFree( ptr, false ) +# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, true ) +# define TracySecureFree( ptr ) tracy::Profiler::MemFree( ptr, true ) + +# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name ) +# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name ) +# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name ) +# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name ) +#endif + +#ifdef TRACY_HAS_CALLSTACK +# define ZoneNamedS( varname, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active ) +# define ZoneNamedNS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active ) +# define ZoneNamedCS( varname, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active ) +# define ZoneNamedNCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active ) + +# define ZoneTransientS( varname, depth, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, depth, active ) +# define ZoneTransientNS( varname, name, depth, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active ) + +# define ZoneScopedS( depth ) ZoneNamedS( ___tracy_scoped_zone, depth, true ) +# define ZoneScopedNS( name, depth ) ZoneNamedNS( ___tracy_scoped_zone, name, depth, true ) +# define ZoneScopedCS( color, depth ) ZoneNamedCS( ___tracy_scoped_zone, color, depth, true ) +# define ZoneScopedNCS( name, color, depth ) ZoneNamedNCS( ___tracy_scoped_zone, name, color, depth, true ) + +# define TracyAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, false ) +# define TracyFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, false ) +# define TracySecureAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, true ) +# define TracySecureFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, true ) + +# define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name ) +# define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name ) +# define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name ) +# define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name ) + +# define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth ) +# define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth ) +# define TracyMessageCS( txt, size, color, depth ) tracy::Profiler::MessageColor( txt, size, color, depth ) +# define TracyMessageLCS( txt, color, depth ) tracy::Profiler::MessageColor( txt, color, depth ) +#else +# define ZoneNamedS( varname, depth, active ) ZoneNamed( varname, active ) +# define ZoneNamedNS( varname, name, depth, active ) ZoneNamedN( varname, name, active ) +# define ZoneNamedCS( varname, color, depth, active ) ZoneNamedC( varname, color, active ) +# define ZoneNamedNCS( varname, name, color, depth, active ) ZoneNamedNC( varname, name, color, active ) + +# define ZoneTransientS( varname, depth, active ) ZoneTransient( varname, active ) +# define ZoneTransientNS( varname, name, depth, active ) ZoneTransientN( varname, name, active ) + +# define ZoneScopedS( depth ) ZoneScoped +# define ZoneScopedNS( name, depth ) ZoneScopedN( name ) +# define ZoneScopedCS( color, depth ) ZoneScopedC( color ) +# define ZoneScopedNCS( name, color, depth ) ZoneScopedNC( name, color ) + +# define TracyAllocS( ptr, size, depth ) TracyAlloc( ptr, size ) +# define TracyFreeS( ptr, depth ) TracyFree( ptr ) +# define TracySecureAllocS( ptr, size, depth ) TracySecureAlloc( ptr, size ) +# define TracySecureFreeS( ptr, depth ) TracySecureFree( ptr ) + +# define TracyAllocNS( ptr, size, depth, name ) TracyAllocN( ptr, size, name ) +# define TracyFreeNS( ptr, depth, name ) TracyFreeN( ptr, name ) +# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAllocN( ptr, size, name ) +# define TracySecureFreeNS( ptr, depth, name ) TracySecureFreeN( ptr, name ) + +# define TracyMessageS( txt, size, depth ) TracyMessage( txt, size ) +# define TracyMessageLS( txt, depth ) TracyMessageL( txt ) +# define TracyMessageCS( txt, size, color, depth ) TracyMessageC( txt, size, color ) +# define TracyMessageLCS( txt, color, depth ) TracyMessageLC( txt, color ) +#endif + +#define TracySourceCallbackRegister( cb, data ) tracy::Profiler::SourceCallbackRegister( cb, data ) +#define TracyParameterRegister( cb, data ) tracy::Profiler::ParameterRegister( cb, data ) +#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val ) +#define TracyIsConnected tracy::GetProfiler().IsConnected() +#define TracySetProgramName( name ) tracy::GetProfiler().SetProgramName( name ); + +#ifdef TRACY_FIBERS +# define TracyFiberEnter( fiber ) tracy::Profiler::EnterFiber( fiber ) +# define TracyFiberLeave tracy::Profiler::LeaveFiber() +#endif + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyC.h b/Externals/tracy/public/tracy/TracyC.h new file mode 100644 index 00000000000..996889c40f8 --- /dev/null +++ b/Externals/tracy/public/tracy/TracyC.h @@ -0,0 +1,370 @@ +#ifndef __TRACYC_HPP__ +#define __TRACYC_HPP__ + +#include +#include + +#include "../client/TracyCallstack.h" +#include "../common/TracyApi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum TracyPlotFormatEnum +{ + TracyPlotFormatNumber, + TracyPlotFormatMemory, + TracyPlotFormatPercentage, + TracyPlotFormatWatt +}; + +TRACY_API void ___tracy_set_thread_name( const char* name ); + +#define TracyCSetThreadName( name ) ___tracy_set_thread_name( name ); + +#ifndef TracyFunction +# define TracyFunction __FUNCTION__ +#endif + +#ifndef TracyFile +# define TracyFile __FILE__ +#endif + +#ifndef TracyLine +# define TracyLine __LINE__ +#endif + +#ifndef TRACY_ENABLE + +typedef const void* TracyCZoneCtx; + +#define TracyCZone(c,x) +#define TracyCZoneN(c,x,y) +#define TracyCZoneC(c,x,y) +#define TracyCZoneNC(c,x,y,z) +#define TracyCZoneEnd(c) +#define TracyCZoneText(c,x,y) +#define TracyCZoneName(c,x,y) +#define TracyCZoneColor(c,x) +#define TracyCZoneValue(c,x) + +#define TracyCAlloc(x,y) +#define TracyCFree(x) +#define TracyCSecureAlloc(x,y) +#define TracyCSecureFree(x) + +#define TracyCAllocN(x,y,z) +#define TracyCFreeN(x,y) +#define TracyCSecureAllocN(x,y,z) +#define TracyCSecureFreeN(x,y) + +#define TracyCFrameMark +#define TracyCFrameMarkNamed(x) +#define TracyCFrameMarkStart(x) +#define TracyCFrameMarkEnd(x) +#define TracyCFrameImage(x,y,z,w,a) + +#define TracyCPlot(x,y) +#define TracyCPlotF(x,y) +#define TracyCPlotI(x,y) +#define TracyCPlotConfig(x,y,z,w,a) + +#define TracyCMessage(x,y) +#define TracyCMessageL(x) +#define TracyCMessageC(x,y,z) +#define TracyCMessageLC(x,y) +#define TracyCAppInfo(x,y) + +#define TracyCZoneS(x,y,z) +#define TracyCZoneNS(x,y,z,w) +#define TracyCZoneCS(x,y,z,w) +#define TracyCZoneNCS(x,y,z,w,a) + +#define TracyCAllocS(x,y,z) +#define TracyCFreeS(x,y) +#define TracyCSecureAllocS(x,y,z) +#define TracyCSecureFreeS(x,y) + +#define TracyCAllocNS(x,y,z,w) +#define TracyCFreeNS(x,y,z) +#define TracyCSecureAllocNS(x,y,z,w) +#define TracyCSecureFreeNS(x,y,z) + +#define TracyCMessageS(x,y,z) +#define TracyCMessageLS(x,y) +#define TracyCMessageCS(x,y,z,w) +#define TracyCMessageLCS(x,y,z) + +#define TracyCIsConnected 0 + +#ifdef TRACY_FIBERS +# define TracyCFiberEnter(fiber) +# define TracyCFiberLeave +#endif + +#else + +#ifndef TracyConcat +# define TracyConcat(x,y) TracyConcatIndirect(x,y) +#endif +#ifndef TracyConcatIndirect +# define TracyConcatIndirect(x,y) x##y +#endif + +struct ___tracy_source_location_data +{ + const char* name; + const char* function; + const char* file; + uint32_t line; + uint32_t color; +}; + +struct ___tracy_c_zone_context +{ + uint32_t id; + int active; +}; + +struct ___tracy_gpu_time_data +{ + int64_t gpuTime; + uint16_t queryId; + uint8_t context; +}; + +struct ___tracy_gpu_zone_begin_data { + uint64_t srcloc; + uint16_t queryId; + uint8_t context; +}; + +struct ___tracy_gpu_zone_begin_callstack_data { + uint64_t srcloc; + int depth; + uint16_t queryId; + uint8_t context; +}; + +struct ___tracy_gpu_zone_end_data { + uint16_t queryId; + uint8_t context; +}; + +struct ___tracy_gpu_new_context_data { + int64_t gpuTime; + float period; + uint8_t context; + uint8_t flags; + uint8_t type; +}; + +struct ___tracy_gpu_context_name_data { + uint8_t context; + const char* name; + uint16_t len; +}; + +struct ___tracy_gpu_calibration_data { + int64_t gpuTime; + int64_t cpuDelta; + uint8_t context; +}; + +// Some containers don't support storing const types. +// This struct, as visible to user, is immutable, so treat it as if const was declared here. +typedef /*const*/ struct ___tracy_c_zone_context TracyCZoneCtx; + + +#ifdef TRACY_MANUAL_LIFETIME +TRACY_API void ___tracy_startup_profiler(void); +TRACY_API void ___tracy_shutdown_profiler(void); +#endif + +TRACY_API uint64_t ___tracy_alloc_srcloc( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz ); +TRACY_API uint64_t ___tracy_alloc_srcloc_name( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz ); + +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin( const struct ___tracy_source_location_data* srcloc, int active ); +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_callstack( const struct ___tracy_source_location_data* srcloc, int depth, int active ); +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc( uint64_t srcloc, int active ); +TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc_callstack( uint64_t srcloc, int depth, int active ); +TRACY_API void ___tracy_emit_zone_end( TracyCZoneCtx ctx ); +TRACY_API void ___tracy_emit_zone_text( TracyCZoneCtx ctx, const char* txt, size_t size ); +TRACY_API void ___tracy_emit_zone_name( TracyCZoneCtx ctx, const char* txt, size_t size ); +TRACY_API void ___tracy_emit_zone_color( TracyCZoneCtx ctx, uint32_t color ); +TRACY_API void ___tracy_emit_zone_value( TracyCZoneCtx ctx, uint64_t value ); + +TRACY_API void ___tracy_emit_gpu_zone_begin( const struct ___tracy_gpu_zone_begin_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_callstack( const struct ___tracy_gpu_zone_begin_callstack_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc( const struct ___tracy_gpu_zone_begin_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack( const struct ___tracy_gpu_zone_begin_callstack_data ); +TRACY_API void ___tracy_emit_gpu_zone_end( const struct ___tracy_gpu_zone_end_data data ); +TRACY_API void ___tracy_emit_gpu_time( const struct ___tracy_gpu_time_data ); +TRACY_API void ___tracy_emit_gpu_new_context( const struct ___tracy_gpu_new_context_data ); +TRACY_API void ___tracy_emit_gpu_context_name( const struct ___tracy_gpu_context_name_data ); +TRACY_API void ___tracy_emit_gpu_calibration( const struct ___tracy_gpu_calibration_data ); + +TRACY_API void ___tracy_emit_gpu_zone_begin_serial( const struct ___tracy_gpu_zone_begin_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_serial( const struct ___tracy_gpu_zone_begin_data ); +TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data ); +TRACY_API void ___tracy_emit_gpu_zone_end_serial( const struct ___tracy_gpu_zone_end_data data ); +TRACY_API void ___tracy_emit_gpu_time_serial( const struct ___tracy_gpu_time_data ); +TRACY_API void ___tracy_emit_gpu_new_context_serial( const struct ___tracy_gpu_new_context_data ); +TRACY_API void ___tracy_emit_gpu_context_name_serial( const struct ___tracy_gpu_context_name_data ); +TRACY_API void ___tracy_emit_gpu_calibration_serial( const struct ___tracy_gpu_calibration_data ); + +TRACY_API int ___tracy_connected(void); + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyCZone( ctx, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active ); +#else +# define TracyCZone( ctx, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active ); +# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active ); +# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active ); +# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active ); +#endif + +#define TracyCZoneEnd( ctx ) ___tracy_emit_zone_end( ctx ); + +#define TracyCZoneText( ctx, txt, size ) ___tracy_emit_zone_text( ctx, txt, size ); +#define TracyCZoneName( ctx, txt, size ) ___tracy_emit_zone_name( ctx, txt, size ); +#define TracyCZoneColor( ctx, color ) ___tracy_emit_zone_color( ctx, color ); +#define TracyCZoneValue( ctx, value ) ___tracy_emit_zone_value( ctx, value ); + + +TRACY_API void ___tracy_emit_memory_alloc( const void* ptr, size_t size, int secure ); +TRACY_API void ___tracy_emit_memory_alloc_callstack( const void* ptr, size_t size, int depth, int secure ); +TRACY_API void ___tracy_emit_memory_free( const void* ptr, int secure ); +TRACY_API void ___tracy_emit_memory_free_callstack( const void* ptr, int depth, int secure ); +TRACY_API void ___tracy_emit_memory_alloc_named( const void* ptr, size_t size, int secure, const char* name ); +TRACY_API void ___tracy_emit_memory_alloc_callstack_named( const void* ptr, size_t size, int depth, int secure, const char* name ); +TRACY_API void ___tracy_emit_memory_free_named( const void* ptr, int secure, const char* name ); +TRACY_API void ___tracy_emit_memory_free_callstack_named( const void* ptr, int depth, int secure, const char* name ); + +TRACY_API void ___tracy_emit_message( const char* txt, size_t size, int callstack ); +TRACY_API void ___tracy_emit_messageL( const char* txt, int callstack ); +TRACY_API void ___tracy_emit_messageC( const char* txt, size_t size, uint32_t color, int callstack ); +TRACY_API void ___tracy_emit_messageLC( const char* txt, uint32_t color, int callstack ); + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyCAlloc( ptr, size ) ___tracy_emit_memory_alloc_callstack( ptr, size, TRACY_CALLSTACK, 0 ) +# define TracyCFree( ptr ) ___tracy_emit_memory_free_callstack( ptr, TRACY_CALLSTACK, 0 ) +# define TracyCSecureAlloc( ptr, size ) ___tracy_emit_memory_alloc_callstack( ptr, size, TRACY_CALLSTACK, 1 ) +# define TracyCSecureFree( ptr ) ___tracy_emit_memory_free_callstack( ptr, TRACY_CALLSTACK, 1 ) + +# define TracyCAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, TRACY_CALLSTACK, 0, name ) +# define TracyCFreeN( ptr, name ) ___tracy_emit_memory_free_callstack_named( ptr, TRACY_CALLSTACK, 0, name ) +# define TracyCSecureAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, TRACY_CALLSTACK, 1, name ) +# define TracyCSecureFreeN( ptr, name ) ___tracy_emit_memory_free_callstack_named( ptr, TRACY_CALLSTACK, 1, name ) + +# define TracyCMessage( txt, size ) ___tracy_emit_message( txt, size, TRACY_CALLSTACK ); +# define TracyCMessageL( txt ) ___tracy_emit_messageL( txt, TRACY_CALLSTACK ); +# define TracyCMessageC( txt, size, color ) ___tracy_emit_messageC( txt, size, color, TRACY_CALLSTACK ); +# define TracyCMessageLC( txt, color ) ___tracy_emit_messageLC( txt, color, TRACY_CALLSTACK ); +#else +# define TracyCAlloc( ptr, size ) ___tracy_emit_memory_alloc( ptr, size, 0 ); +# define TracyCFree( ptr ) ___tracy_emit_memory_free( ptr, 0 ); +# define TracyCSecureAlloc( ptr, size ) ___tracy_emit_memory_alloc( ptr, size, 1 ); +# define TracyCSecureFree( ptr ) ___tracy_emit_memory_free( ptr, 1 ); + +# define TracyCAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_named( ptr, size, 0, name ); +# define TracyCFreeN( ptr, name ) ___tracy_emit_memory_free_named( ptr, 0, name ); +# define TracyCSecureAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_named( ptr, size, 1, name ); +# define TracyCSecureFreeN( ptr, name ) ___tracy_emit_memory_free_named( ptr, 1, name ); + +# define TracyCMessage( txt, size ) ___tracy_emit_message( txt, size, 0 ); +# define TracyCMessageL( txt ) ___tracy_emit_messageL( txt, 0 ); +# define TracyCMessageC( txt, size, color ) ___tracy_emit_messageC( txt, size, color, 0 ); +# define TracyCMessageLC( txt, color ) ___tracy_emit_messageLC( txt, color, 0 ); +#endif + + +TRACY_API void ___tracy_emit_frame_mark( const char* name ); +TRACY_API void ___tracy_emit_frame_mark_start( const char* name ); +TRACY_API void ___tracy_emit_frame_mark_end( const char* name ); +TRACY_API void ___tracy_emit_frame_image( const void* image, uint16_t w, uint16_t h, uint8_t offset, int flip ); + +#define TracyCFrameMark ___tracy_emit_frame_mark( 0 ); +#define TracyCFrameMarkNamed( name ) ___tracy_emit_frame_mark( name ); +#define TracyCFrameMarkStart( name ) ___tracy_emit_frame_mark_start( name ); +#define TracyCFrameMarkEnd( name ) ___tracy_emit_frame_mark_end( name ); +#define TracyCFrameImage( image, width, height, offset, flip ) ___tracy_emit_frame_image( image, width, height, offset, flip ); + + +TRACY_API void ___tracy_emit_plot( const char* name, double val ); +TRACY_API void ___tracy_emit_plot_float( const char* name, float val ); +TRACY_API void ___tracy_emit_plot_int( const char* name, int64_t val ); +TRACY_API void ___tracy_emit_plot_config( const char* name, int type, int step, int fill, uint32_t color ); +TRACY_API void ___tracy_emit_message_appinfo( const char* txt, size_t size ); + +#define TracyCPlot( name, val ) ___tracy_emit_plot( name, val ); +#define TracyCPlotF( name, val ) ___tracy_emit_plot_float( name, val ); +#define TracyCPlotI( name, val ) ___tracy_emit_plot_int( name, val ); +#define TracyCPlotConfig( name, type, step, fill, color ) ___tracy_emit_plot_config( name, type, step, fill, color ); +#define TracyCAppInfo( txt, size ) ___tracy_emit_message_appinfo( txt, size ); + + +#ifdef TRACY_HAS_CALLSTACK +# define TracyCZoneS( ctx, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active ); +# define TracyCZoneNS( ctx, name, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active ); +# define TracyCZoneCS( ctx, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active ); +# define TracyCZoneNCS( ctx, name, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active ); + +# define TracyCAllocS( ptr, size, depth ) ___tracy_emit_memory_alloc_callstack( ptr, size, depth, 0 ) +# define TracyCFreeS( ptr, depth ) ___tracy_emit_memory_free_callstack( ptr, depth, 0 ) +# define TracyCSecureAllocS( ptr, size, depth ) ___tracy_emit_memory_alloc_callstack( ptr, size, depth, 1 ) +# define TracyCSecureFreeS( ptr, depth ) ___tracy_emit_memory_free_callstack( ptr, depth, 1 ) + +# define TracyCAllocNS( ptr, size, depth, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, depth, 0, name ) +# define TracyCFreeNS( ptr, depth, name ) ___tracy_emit_memory_free_callstack_named( ptr, depth, 0, name ) +# define TracyCSecureAllocNS( ptr, size, depth, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, depth, 1, name ) +# define TracyCSecureFreeNS( ptr, depth, name ) ___tracy_emit_memory_free_callstack_named( ptr, depth, 1, name ) + +# define TracyCMessageS( txt, size, depth ) ___tracy_emit_message( txt, size, depth ); +# define TracyCMessageLS( txt, depth ) ___tracy_emit_messageL( txt, depth ); +# define TracyCMessageCS( txt, size, color, depth ) ___tracy_emit_messageC( txt, size, color, depth ); +# define TracyCMessageLCS( txt, color, depth ) ___tracy_emit_messageLC( txt, color, depth ); +#else +# define TracyCZoneS( ctx, depth, active ) TracyCZone( ctx, active ) +# define TracyCZoneNS( ctx, name, depth, active ) TracyCZoneN( ctx, name, active ) +# define TracyCZoneCS( ctx, color, depth, active ) TracyCZoneC( ctx, color, active ) +# define TracyCZoneNCS( ctx, name, color, depth, active ) TracyCZoneNC( ctx, name, color, active ) + +# define TracyCAllocS( ptr, size, depth ) TracyCAlloc( ptr, size ) +# define TracyCFreeS( ptr, depth ) TracyCFree( ptr ) +# define TracyCSecureAllocS( ptr, size, depth ) TracyCSecureAlloc( ptr, size ) +# define TracyCSecureFreeS( ptr, depth ) TracyCSecureFree( ptr ) + +# define TracyCAllocNS( ptr, size, depth, name ) TracyCAllocN( ptr, size, name ) +# define TracyCFreeNS( ptr, depth, name ) TracyCFreeN( ptr, name ) +# define TracyCSecureAllocNS( ptr, size, depth, name ) TracyCSecureAllocN( ptr, size, name ) +# define TracyCSecureFreeNS( ptr, depth, name ) TracyCSecureFreeN( ptr, name ) + +# define TracyCMessageS( txt, size, depth ) TracyCMessage( txt, size ) +# define TracyCMessageLS( txt, depth ) TracyCMessageL( txt ) +# define TracyCMessageCS( txt, size, color, depth ) TracyCMessageC( txt, size, color ) +# define TracyCMessageLCS( txt, color, depth ) TracyCMessageLC( txt, color ) +#endif + +#define TracyCIsConnected ___tracy_connected() + +#ifdef TRACY_FIBERS +TRACY_API void ___tracy_fiber_enter( const char* fiber ); +TRACY_API void ___tracy_fiber_leave( void ); + +# define TracyCFiberEnter( fiber ) ___tracy_fiber_enter( fiber ); +# define TracyCFiberLeave ___tracy_fiber_leave(); +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyD3D11.hpp b/Externals/tracy/public/tracy/TracyD3D11.hpp new file mode 100644 index 00000000000..8aebdb26532 --- /dev/null +++ b/Externals/tracy/public/tracy/TracyD3D11.hpp @@ -0,0 +1,446 @@ +#ifndef __TRACYD3D11_HPP__ +#define __TRACYD3D11_HPP__ + +#ifndef TRACY_ENABLE + +#define TracyD3D11Context(device,queue) nullptr +#define TracyD3D11Destroy(ctx) +#define TracyD3D11ContextName(ctx, name, size) + +#define TracyD3D11NewFrame(ctx) + +#define TracyD3D11Zone(ctx, name) +#define TracyD3D11ZoneC(ctx, name, color) +#define TracyD3D11NamedZone(ctx, varname, name, active) +#define TracyD3D11NamedZoneC(ctx, varname, name, color, active) +#define TracyD3D11ZoneTransient(ctx, varname, name, active) + +#define TracyD3D11ZoneS(ctx, name, depth) +#define TracyD3D11ZoneCS(ctx, name, color, depth) +#define TracyD3D11NamedZoneS(ctx, varname, name, depth, active) +#define TracyD3D11NamedZoneCS(ctx, varname, name, color, depth, active) +#define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) + +#define TracyD3D11Collect(ctx) + +namespace tracy +{ +class D3D11ZoneScope {}; +} + +using TracyD3D11Ctx = void*; + +#else + +#include +#include +#include + +#include "Tracy.hpp" +#include "../client/TracyProfiler.hpp" +#include "../client/TracyCallstack.hpp" +#include "../common/TracyYield.hpp" + +#include + +#define TracyD3D11Panic(msg, ...) do { assert(false && "TracyD3D11: " msg); TracyMessageLC("TracyD3D11: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false); + +namespace tracy +{ + +class D3D11Ctx +{ + friend class D3D11ZoneScope; + + static constexpr uint32_t MaxQueries = 64 * 1024; + + enum CollectMode { POLL, BLOCK }; + +public: + D3D11Ctx( ID3D11Device* device, ID3D11DeviceContext* devicectx ) + { + // TODO: consider calling ID3D11Device::GetImmediateContext() instead of passing it as an argument + m_device = device; + device->AddRef(); + m_immediateDevCtx = devicectx; + devicectx->AddRef(); + + { + D3D11_QUERY_DESC desc = { }; + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + if (FAILED(m_device->CreateQuery(&desc, &m_disjointQuery))) + { + TracyD3D11Panic("unable to create disjoint timestamp query.", return); + } + } + + for (ID3D11Query*& query : m_queries) + { + D3D11_QUERY_DESC desc = { }; + desc.Query = D3D11_QUERY_TIMESTAMP; + if (FAILED(m_device->CreateQuery(&desc, &query))) + { + TracyD3D11Panic("unable to create timestamp query.", return); + } + } + + // Calibrate CPU and GPU timestamps + int64_t tcpu = 0; + int64_t tgpu = 0; + for (int attempts = 0; attempts < 50; attempts++) + { + m_immediateDevCtx->Begin(m_disjointQuery); + m_immediateDevCtx->End(m_queries[0]); + m_immediateDevCtx->End(m_disjointQuery); + + int64_t tcpu0 = Profiler::GetTime(); + WaitForQuery(m_disjointQuery); + int64_t tcpu1 = Profiler::GetTime(); + + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { }; + if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), 0) != S_OK) + { + TracyMessageLC("TracyD3D11: unable to query GPU timestamp; retrying...", tracy::Color::Tomato); + continue; + } + + if (disjoint.Disjoint) + continue; + + UINT64 timestamp = 0; + if (m_immediateDevCtx->GetData(m_queries[0], ×tamp, sizeof(timestamp), 0) != S_OK) + continue; // this should never happen, since the enclosing disjoint query succeeded + + tcpu = tcpu0 + (tcpu1 - tcpu0) * 1 / 2; + tgpu = timestamp * (1000000000 / disjoint.Frequency); + break; + } + + // ready to roll + m_contextId = GetGpuCtxCounter().fetch_add(1); + m_immediateDevCtx->Begin(m_disjointQuery); + m_previousCheckpoint = m_nextCheckpoint = 0; + + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuNewContext ); + MemWrite( &item->gpuNewContext.cpuTime, tcpu ); + MemWrite( &item->gpuNewContext.gpuTime, tgpu ); + MemWrite( &item->gpuNewContext.thread, uint32_t(0) ); // #TODO: why not GetThreadHandle()? + MemWrite( &item->gpuNewContext.period, 1.0f ); + MemWrite( &item->gpuNewContext.context, m_contextId); + MemWrite( &item->gpuNewContext.flags, uint8_t(0) ); + MemWrite( &item->gpuNewContext.type, GpuContextType::Direct3D11 ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + Profiler::QueueSerialFinish(); + } + + ~D3D11Ctx() + { + // collect all pending timestamps before destroying everything + do + { + Collect(BLOCK); + } while (m_previousCheckpoint != m_queryCounter); + + for (ID3D11Query* query : m_queries) + { + query->Release(); + } + m_immediateDevCtx->End(m_disjointQuery); + m_disjointQuery->Release(); + m_immediateDevCtx->Release(); + m_device->Release(); + } + + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, m_contextId ); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + void Collect(CollectMode mode = POLL) + { + ZoneScopedC( Color::Red4 ); + +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) + { + m_previousCheckpoint = m_nextCheckpoint = m_queryCounter; + return; + } +#endif + + if (m_previousCheckpoint == m_nextCheckpoint) + { + uintptr_t nextCheckpoint = m_queryCounter; + if (nextCheckpoint == m_nextCheckpoint) + { + return; + } + m_nextCheckpoint = nextCheckpoint; + m_immediateDevCtx->End(m_disjointQuery); + } + + if (mode == CollectMode::BLOCK) + { + WaitForQuery(m_disjointQuery); + } + + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { }; + if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), D3D11_ASYNC_GETDATA_DONOTFLUSH) != S_OK) + { + return; + } + + if (disjoint.Disjoint == TRUE) + { + m_previousCheckpoint = m_nextCheckpoint; + TracyD3D11Panic("disjoint timestamps detected; dropping."); + return; + } + + auto begin = m_previousCheckpoint; + auto end = m_nextCheckpoint; + for (auto i = begin; i != end; ++i) + { + uint32_t k = RingIndex(i); + UINT64 timestamp = 0; + if (m_immediateDevCtx->GetData(m_queries[k], ×tamp, sizeof(timestamp), 0) != S_OK) + { + TracyD3D11Panic("timestamp expected to be ready, but it was not!"); + break; + } + timestamp *= (1000000000ull / disjoint.Frequency); + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuTime); + MemWrite(&item->gpuTime.gpuTime, static_cast(timestamp)); + MemWrite(&item->gpuTime.queryId, static_cast(k)); + MemWrite(&item->gpuTime.context, m_contextId); + Profiler::QueueSerialFinish(); + } + + // disjoint timestamp queries should only be invoked once per frame or less + // https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_query + m_immediateDevCtx->Begin(m_disjointQuery); + m_previousCheckpoint = m_nextCheckpoint; + } + +private: + tracy_force_inline uint32_t RingIndex(uintptr_t index) + { + index %= MaxQueries; + return static_cast(index); + } + + tracy_force_inline uint32_t RingCount(uintptr_t begin, uintptr_t end) + { + // wrap-around safe: all unsigned + uintptr_t count = end - begin; + return static_cast(count); + } + + tracy_force_inline uint32_t NextQueryId() + { + auto id = m_queryCounter++; + if (RingCount(m_previousCheckpoint, id) >= MaxQueries) + { + TracyD3D11Panic("too many pending timestamp queries."); + // #TODO: return some sentinel value; ideally a "hidden" query index + } + return RingIndex(id); + } + + tracy_force_inline ID3D11Query* GetQueryObjectFromId(uint32_t id) + { + return m_queries[id]; + } + + tracy_force_inline void WaitForQuery(ID3D11Query* query) + { + m_immediateDevCtx->Flush(); + while (m_immediateDevCtx->GetData(query, nullptr, 0, 0) != S_OK) + YieldThread(); // busy-wait :-( attempt to reduce power usage with _mm_pause() & friends... + } + + tracy_force_inline uint8_t GetContextId() const + { + return m_contextId; + } + + ID3D11Device* m_device = nullptr; + ID3D11DeviceContext* m_immediateDevCtx = nullptr; + + ID3D11Query* m_queries[MaxQueries]; + ID3D11Query* m_disjointQuery = nullptr; + + uint8_t m_contextId = 255; // NOTE: apparently, 255 means invalid id; is this documented anywhere? + + uintptr_t m_queryCounter = 0; + + uintptr_t m_previousCheckpoint = 0; + uintptr_t m_nextCheckpoint = 0; +}; + +class D3D11ZoneScope +{ +public: + tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool active ) + : D3D11ZoneScope(ctx, active) + { + if( !m_active ) return; + + auto* item = Profiler::QueueSerial(); + WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast(srcloc)); + } + + tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int depth, bool active ) + : D3D11ZoneScope(ctx, active) + { + if( !m_active ) return; + + auto* item = Profiler::QueueSerialCallstack(Callstack(depth)); + WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast(srcloc)); + } + + tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool active) + : D3D11ZoneScope(ctx, active) + { + if( !m_active ) return; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerial(); + WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation); + } + + tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool active) + : D3D11ZoneScope(ctx, active) + { + if( !m_active ) return; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerialCallstack(Callstack(depth)); + WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation); + } + + tracy_force_inline ~D3D11ZoneScope() + { + if( !m_active ) return; + + const auto queryId = m_ctx->NextQueryId(); + m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId)); + + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial ); + MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneEnd.context, m_ctx->GetContextId() ); + Profiler::QueueSerialFinish(); + } + +private: + tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, bool active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( active ) +#endif + { + if( !m_active ) return; + m_ctx = ctx; + } + + void WriteQueueItem(tracy::QueueItem* item, tracy::QueueType queueItemType, uint64_t sourceLocation) + { + const auto queryId = m_ctx->NextQueryId(); + m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId)); + + MemWrite( &item->hdr.type, queueItemType); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, sourceLocation ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, m_ctx->GetContextId() ); + Profiler::QueueSerialFinish(); + } + + const bool m_active; + + D3D11Ctx* m_ctx; +}; + +static inline D3D11Ctx* CreateD3D11Context( ID3D11Device* device, ID3D11DeviceContext* devicectx ) +{ + auto ctx = (D3D11Ctx*)tracy_malloc( sizeof( D3D11Ctx ) ); + new(ctx) D3D11Ctx( device, devicectx ); + return ctx; +} + +static inline void DestroyD3D11Context( D3D11Ctx* ctx ) +{ + ctx->~D3D11Ctx(); + tracy_free( ctx ); +} +} + +#undef TracyD3D11Panic + +using TracyD3D11Ctx = tracy::D3D11Ctx*; + +#define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( device, devicectx ); +#define TracyD3D11Destroy(ctx) tracy::DestroyD3D11Context(ctx); +#define TracyD3D11ContextName(ctx, name, size) ctx->Name(name, size); + +#define TracyD3D11UnnamedZone ___tracy_gpu_d3d11_zone +#define TracyD3D11SrcLocSymbol TracyConcat(__tracy_gpu_d3d11_source_location,TracyLine) +#define TracyD3D11SrcLocObject(name, color) static constexpr tracy::SourceLocationData TracyD3D11SrcLocSymbol { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZoneS( ctx, TracyD3D11UnnamedZone, name, TRACY_CALLSTACK, true ) +# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneCS( ctx, TracyD3D11UnnamedZone, name, color, TRACY_CALLSTACK, true ) +# define TracyD3D11NamedZone( ctx, varname, name, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, TRACY_CALLSTACK, active ); +# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, TRACY_CALLSTACK, active ); +# define TracyD3D11ZoneTransient(ctx, varname, name, active) TracyD3D11ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active) +#else +# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, TracyD3D11UnnamedZone, name, true ) +# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, TracyD3D11UnnamedZone, name, color, true ) +# define TracyD3D11NamedZone( ctx, varname, name, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, active ); +# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, active ); +# define TracyD3D11ZoneTransient(ctx, varname, name, active) tracy::D3D11ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), active }; +#endif + +#ifdef TRACY_HAS_CALLSTACK +# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, TracyD3D11UnnamedZone, name, depth, true ) +# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, TracyD3D11UnnamedZone, name, color, depth, true ) +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, depth, active ); +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, depth, active ); +# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) tracy::D3D11ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), depth, active }; +#else +# define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name ) +# define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color ) +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name, active ) +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color, active ) +# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) TracyD3D11ZoneTransient(ctx, varname, name, active) +#endif + +#define TracyD3D11Collect( ctx ) ctx->Collect(); + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyD3D12.hpp b/Externals/tracy/public/tracy/TracyD3D12.hpp new file mode 100644 index 00000000000..41567937e83 --- /dev/null +++ b/Externals/tracy/public/tracy/TracyD3D12.hpp @@ -0,0 +1,500 @@ +#ifndef __TRACYD3D12_HPP__ +#define __TRACYD3D12_HPP__ + +#ifndef TRACY_ENABLE + +#define TracyD3D12Context(device, queue) nullptr +#define TracyD3D12Destroy(ctx) +#define TracyD3D12ContextName(ctx, name, size) + +#define TracyD3D12NewFrame(ctx) + +#define TracyD3D12Zone(ctx, cmdList, name) +#define TracyD3D12ZoneC(ctx, cmdList, name, color) +#define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) +#define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) +#define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) + +#define TracyD3D12ZoneS(ctx, cmdList, name, depth) +#define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) +#define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) +#define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) +#define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) + +#define TracyD3D12Collect(ctx) + +namespace tracy +{ + class D3D12ZoneScope {}; +} + +using TracyD3D12Ctx = void*; + +#else + +#include "Tracy.hpp" +#include "../client/TracyProfiler.hpp" +#include "../client/TracyCallstack.hpp" + +#include +#include +#include +#include +#include + +#define TracyD3D12Panic(msg, ...) do { assert(false && "TracyD3D12: " msg); TracyMessageLC("TracyD3D12: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false); + +namespace tracy +{ + + struct D3D12QueryPayload + { + uint32_t m_queryIdStart = 0; + uint32_t m_queryCount = 0; + }; + + // Command queue context. + class D3D12QueueCtx + { + friend class D3D12ZoneScope; + + ID3D12Device* m_device = nullptr; + ID3D12CommandQueue* m_queue = nullptr; + uint8_t m_contextId = 255; // TODO: apparently, 255 means "invalid id"; is this documented somewhere? + ID3D12QueryHeap* m_queryHeap = nullptr; + ID3D12Resource* m_readbackBuffer = nullptr; + + // In-progress payload. + uint32_t m_queryLimit = 0; + std::atomic m_queryCounter = 0; + uint32_t m_previousQueryCounter = 0; + + uint32_t m_activePayload = 0; + ID3D12Fence* m_payloadFence = nullptr; + std::queue m_payloadQueue; + + UINT64 m_prevCalibrationTicksCPU = 0; + + void RecalibrateClocks() + { + UINT64 cpuTimestamp; + UINT64 gpuTimestamp; + if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp))) + { + TracyD3D12Panic("failed to obtain queue clock calibration counters.", return); + } + + int64_t cpuDeltaTicks = cpuTimestamp - m_prevCalibrationTicksCPU; + if (cpuDeltaTicks > 0) + { + static const int64_t nanosecodsPerTick = int64_t(1000000000) / GetFrequencyQpc(); + int64_t cpuDeltaNS = cpuDeltaTicks * nanosecodsPerTick; + // Save the device cpu timestamp, not the Tracy profiler timestamp: + m_prevCalibrationTicksCPU = cpuTimestamp; + + cpuTimestamp = Profiler::GetTime(); + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuCalibration); + MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp); + MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp); + MemWrite(&item->gpuCalibration.cpuDelta, cpuDeltaNS); + MemWrite(&item->gpuCalibration.context, GetId()); + SubmitQueueItem(item); + } + } + + tracy_force_inline void SubmitQueueItem(tracy::QueueItem* item) + { +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem(*item); +#endif + Profiler::QueueSerialFinish(); + } + + public: + D3D12QueueCtx(ID3D12Device* device, ID3D12CommandQueue* queue) + : m_device(device) + , m_queue(queue) + { + // Verify we support timestamp queries on this queue. + + if (queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY) + { + D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureData{}; + + HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureData, sizeof(featureData)); + if (FAILED(hr) || (featureData.CopyQueueTimestampQueriesSupported == FALSE)) + { + TracyD3D12Panic("Platform does not support profiling of copy queues.", return); + } + } + + static constexpr uint32_t MaxQueries = 64 * 1024; // Must be even, because queries are (begin, end) pairs + m_queryLimit = MaxQueries; + + D3D12_QUERY_HEAP_DESC heapDesc{}; + heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP; + heapDesc.Count = m_queryLimit; + heapDesc.NodeMask = 0; // #TODO: Support multiple adapters. + + while (FAILED(device->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(&m_queryHeap)))) + { + m_queryLimit /= 2; + heapDesc.Count = m_queryLimit; + } + + // Create a readback buffer, which will be used as a destination for the query data. + + D3D12_RESOURCE_DESC readbackBufferDesc{}; + readbackBufferDesc.Alignment = 0; + readbackBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + readbackBufferDesc.Width = m_queryLimit * sizeof(uint64_t); + readbackBufferDesc.Height = 1; + readbackBufferDesc.DepthOrArraySize = 1; + readbackBufferDesc.Format = DXGI_FORMAT_UNKNOWN; + readbackBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Buffers are always row major. + readbackBufferDesc.MipLevels = 1; + readbackBufferDesc.SampleDesc.Count = 1; + readbackBufferDesc.SampleDesc.Quality = 0; + readbackBufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + D3D12_HEAP_PROPERTIES readbackHeapProps{}; + readbackHeapProps.Type = D3D12_HEAP_TYPE_READBACK; + readbackHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + readbackHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + readbackHeapProps.CreationNodeMask = 0; + readbackHeapProps.VisibleNodeMask = 0; // #TODO: Support multiple adapters. + + if (FAILED(device->CreateCommittedResource(&readbackHeapProps, D3D12_HEAP_FLAG_NONE, &readbackBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_readbackBuffer)))) + { + TracyD3D12Panic("Failed to create query readback buffer.", return); + } + + if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_payloadFence)))) + { + TracyD3D12Panic("Failed to create payload fence.", return); + } + + float period = [queue]() + { + uint64_t timestampFrequency; + if (FAILED(queue->GetTimestampFrequency(×tampFrequency))) + { + return 0.0f; + } + return static_cast( 1E+09 / static_cast(timestampFrequency) ); + }(); + + if (period == 0.0f) + { + TracyD3D12Panic("Failed to get timestamp frequency.", return); + } + + uint64_t cpuTimestamp; + uint64_t gpuTimestamp; + if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp))) + { + TracyD3D12Panic("Failed to get queue clock calibration.", return); + } + + // Save the device cpu timestamp, not the profiler's timestamp. + m_prevCalibrationTicksCPU = cpuTimestamp; + + cpuTimestamp = Profiler::GetTime(); + + // all checked: ready to roll + m_contextId = GetGpuCtxCounter().fetch_add(1); + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuNewContext); + MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp); + MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp); + MemWrite(&item->gpuNewContext.thread, decltype(item->gpuNewContext.thread)(0)); // #TODO: why 0 instead of GetThreadHandle()? + MemWrite(&item->gpuNewContext.period, period); + MemWrite(&item->gpuNewContext.context, GetId()); + MemWrite(&item->gpuNewContext.flags, GpuContextCalibration); + MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12); + SubmitQueueItem(item); + } + + ~D3D12QueueCtx() + { + ZoneScopedC(Color::Red4); + // collect all pending timestamps + while (m_payloadFence->GetCompletedValue() != m_activePayload) + /* busy-wait ... */; + Collect(); + m_payloadFence->Release(); + m_readbackBuffer->Release(); + m_queryHeap->Release(); + } + + + void NewFrame() + { + uint32_t queryCounter = m_queryCounter.exchange(0); + m_payloadQueue.emplace(D3D12QueryPayload{ m_previousQueryCounter, queryCounter }); + m_previousQueryCounter += queryCounter; + + if (m_previousQueryCounter >= m_queryLimit) + { + m_previousQueryCounter -= m_queryLimit; + } + + m_queue->Signal(m_payloadFence, ++m_activePayload); + } + + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, GetId()); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); + SubmitQueueItem(item); + } + + void Collect() + { + ZoneScopedC(Color::Red4); + +#ifdef TRACY_ON_DEMAND + if (!GetProfiler().IsConnected()) + { + m_queryCounter = 0; + + return; + } +#endif + + // Find out what payloads are available. + const auto newestReadyPayload = m_payloadFence->GetCompletedValue(); + const auto payloadCount = m_payloadQueue.size() - (m_activePayload - newestReadyPayload); + + if (!payloadCount) + { + return; // No payloads are available yet, exit out. + } + + D3D12_RANGE mapRange{ 0, m_queryLimit * sizeof(uint64_t) }; + + // Map the readback buffer so we can fetch the query data from the GPU. + void* readbackBufferMapping = nullptr; + + if (FAILED(m_readbackBuffer->Map(0, &mapRange, &readbackBufferMapping))) + { + TracyD3D12Panic("Failed to map readback buffer.", return); + } + + auto* timestampData = static_cast(readbackBufferMapping); + + for (uint32_t i = 0; i < payloadCount; ++i) + { + const auto& payload = m_payloadQueue.front(); + + for (uint32_t j = 0; j < payload.m_queryCount; ++j) + { + const auto counter = (payload.m_queryIdStart + j) % m_queryLimit; + const auto timestamp = timestampData[counter]; + const auto queryId = counter; + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuTime); + MemWrite(&item->gpuTime.gpuTime, timestamp); + MemWrite(&item->gpuTime.queryId, static_cast(queryId)); + MemWrite(&item->gpuTime.context, GetId()); + + Profiler::QueueSerialFinish(); + } + + m_payloadQueue.pop(); + } + + m_readbackBuffer->Unmap(0, nullptr); + + // Recalibrate to account for drift. + RecalibrateClocks(); + } + + private: + tracy_force_inline uint32_t NextQueryId() + { + uint32_t queryCounter = m_queryCounter.fetch_add(2); + if (queryCounter >= m_queryLimit) + { + TracyD3D12Panic("Submitted too many GPU queries! Consider increasing MaxQueries."); + // #TODO: consider returning an invalid id or sentinel value here + } + + const uint32_t id = (m_previousQueryCounter + queryCounter) % m_queryLimit; + + return id; + } + + tracy_force_inline uint8_t GetId() const + { + return m_contextId; + } + }; + + class D3D12ZoneScope + { + const bool m_active; + D3D12QueueCtx* m_ctx = nullptr; + ID3D12GraphicsCommandList* m_cmdList = nullptr; + uint32_t m_queryId = 0; // Used for tracking in nested zones. + + tracy_force_inline void WriteQueueItem(QueueItem* item, QueueType type, uint64_t srcLocation) + { + MemWrite(&item->hdr.type, type); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, srcLocation); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, static_cast(m_queryId)); + MemWrite(&item->gpuZoneBegin.context, m_ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, bool active) +#ifdef TRACY_ON_DEMAND + : m_active(active&& GetProfiler().IsConnected()) +#else + : m_active(active) +#endif + { + if (!m_active) return; + + m_ctx = ctx; + m_cmdList = cmdList; + + m_queryId = m_ctx->NextQueryId(); + m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId); + } + + public: + tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, bool active) + : D3D12ZoneScope(ctx, cmdList, active) + { + if (!m_active) return; + + auto* item = Profiler::QueueSerial(); + WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast(srcLocation)); + } + + tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, int depth, bool active) + : D3D12ZoneScope(ctx, cmdList, active) + { + if (!m_active) return; + + auto* item = Profiler::QueueSerialCallstack(Callstack(depth)); + WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast(srcLocation)); + } + + tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, bool active) + : D3D12ZoneScope(ctx, cmdList, active) + { + if (!m_active) return; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerial(); + WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation); + } + + tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, int depth, bool active) + : D3D12ZoneScope(ctx, cmdList, active) + { + if (!m_active) return; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerialCallstack(Callstack(depth)); + WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation); + } + + tracy_force_inline ~D3D12ZoneScope() + { + if (!m_active) return; + + const auto queryId = m_queryId + 1; // Our end query slot is immediately after the begin slot. + m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, queryId); + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial); + MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneEnd.queryId, static_cast(queryId)); + MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId()); + Profiler::QueueSerialFinish(); + + m_cmdList->ResolveQueryData(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId, 2, m_ctx->m_readbackBuffer, m_queryId * sizeof(uint64_t)); + } + }; + + static inline D3D12QueueCtx* CreateD3D12Context(ID3D12Device* device, ID3D12CommandQueue* queue) + { + auto* ctx = static_cast(tracy_malloc(sizeof(D3D12QueueCtx))); + new (ctx) D3D12QueueCtx{ device, queue }; + + return ctx; + } + + static inline void DestroyD3D12Context(D3D12QueueCtx* ctx) + { + ctx->~D3D12QueueCtx(); + tracy_free(ctx); + } + +} + +#undef TracyD3D12Panic + +using TracyD3D12Ctx = tracy::D3D12QueueCtx*; + +#define TracyD3D12Context(device, queue) tracy::CreateD3D12Context(device, queue); +#define TracyD3D12Destroy(ctx) tracy::DestroyD3D12Context(ctx); +#define TracyD3D12ContextName(ctx, name, size) ctx->Name(name, size); + +#define TracyD3D12NewFrame(ctx) ctx->NewFrame(); + +#define TracyD3D12UnnamedZone ___tracy_gpu_d3d12_zone +#define TracyD3D12SrcLocSymbol TracyConcat(__tracy_d3d12_source_location,TracyLine) +#define TracyD3D12SrcLocObject(name, color) static constexpr tracy::SourceLocationData TracyD3D12SrcLocSymbol { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, TRACY_CALLSTACK, true) +# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, TRACY_CALLSTACK, true) +# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active }; +# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active }; +# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active) +#else +# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZone(ctx, TracyD3D12UnnamedZone, cmdList, name, true) +# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneC(ctx, TracyD3D12UnnamedZone, cmdList, name, color, true) +# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active }; +# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active }; +# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, active }; +#endif + +#ifdef TRACY_HAS_CALLSTACK +# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, depth, true) +# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, depth, true) +# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active }; +# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active }; +# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, depth, active }; +#else +# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12Zone(ctx, cmdList, name) +# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12Zone(ctx, cmdList, name, color) +# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12NamedZone(ctx, varname, cmdList, name, active) +# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) +# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) +#endif + +#define TracyD3D12Collect(ctx) ctx->Collect(); + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyLua.hpp b/Externals/tracy/public/tracy/TracyLua.hpp new file mode 100644 index 00000000000..c972ffb26da --- /dev/null +++ b/Externals/tracy/public/tracy/TracyLua.hpp @@ -0,0 +1,431 @@ +#ifndef __TRACYLUA_HPP__ +#define __TRACYLUA_HPP__ + +// Include this file after you include lua headers. + +#ifndef TRACY_ENABLE + +#include + +namespace tracy +{ + +namespace detail +{ +static inline int noop( lua_State* L ) { return 0; } +} + +static inline void LuaRegister( lua_State* L ) +{ + lua_newtable( L ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBegin" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBeginN" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBeginS" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBeginNS" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneEnd" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneText" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneName" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "Message" ); + lua_setglobal( L, "tracy" ); +} + +static inline char* FindEnd( char* ptr ) +{ + unsigned int cnt = 1; + while( cnt != 0 ) + { + if( *ptr == '(' ) cnt++; + else if( *ptr == ')' ) cnt--; + ptr++; + } + return ptr; +} + +static inline void LuaRemove( char* script ) +{ + while( *script ) + { + if( strncmp( script, "tracy.", 6 ) == 0 ) + { + if( strncmp( script + 6, "Zone", 4 ) == 0 ) + { + if( strncmp( script + 10, "End()", 5 ) == 0 ) + { + memset( script, ' ', 15 ); + script += 15; + } + else if( strncmp( script + 10, "Begin()", 7 ) == 0 ) + { + memset( script, ' ', 17 ); + script += 17; + } + else if( strncmp( script + 10, "Text(", 5 ) == 0 ) + { + auto end = FindEnd( script + 15 ); + memset( script, ' ', end - script ); + script = end; + } + else if( strncmp( script + 10, "Name(", 5 ) == 0 ) + { + auto end = FindEnd( script + 15 ); + memset( script, ' ', end - script ); + script = end; + } + else if( strncmp( script + 10, "BeginN(", 7 ) == 0 ) + { + auto end = FindEnd( script + 17 ); + memset( script, ' ', end - script ); + script = end; + } + else if( strncmp( script + 10, "BeginS(", 7 ) == 0 ) + { + auto end = FindEnd( script + 17 ); + memset( script, ' ', end - script ); + script = end; + } + else if( strncmp( script + 10, "BeginNS(", 8 ) == 0 ) + { + auto end = FindEnd( script + 18 ); + memset( script, ' ', end - script ); + script = end; + } + else + { + script += 10; + } + } + else if( strncmp( script + 6, "Message(", 8 ) == 0 ) + { + auto end = FindEnd( script + 14 ); + memset( script, ' ', end - script ); + script = end; + } + else + { + script += 6; + } + } + else + { + script++; + } + } +} + +} + +#else + +#include +#include + +#include "../common/TracyColor.hpp" +#include "../common/TracyAlign.hpp" +#include "../common/TracyForceInline.hpp" +#include "../common/TracySystem.hpp" +#include "../client/TracyProfiler.hpp" + +namespace tracy +{ + +#ifdef TRACY_ON_DEMAND +TRACY_API LuaZoneState& GetLuaZoneState(); +#endif + +namespace detail +{ + +#ifdef TRACY_HAS_CALLSTACK +static tracy_force_inline void SendLuaCallstack( lua_State* L, uint32_t depth ) +{ + assert( depth <= 64 ); + lua_Debug dbg[64]; + const char* func[64]; + uint32_t fsz[64]; + uint32_t ssz[64]; + + uint8_t cnt; + uint16_t spaceNeeded = sizeof( cnt ); + for( cnt=0; cnt::max)() ); + memcpy( dst, fsz+i, 2 ); dst += 2; + memcpy( dst, func[i], fsz[i] ); dst += fsz[i]; + assert( ssz[i] <= (std::numeric_limits::max)() ); + memcpy( dst, ssz+i, 2 ); dst += 2; + memcpy( dst, dbg[i].source, ssz[i] ), dst += ssz[i]; + } + assert( dst - ptr == spaceNeeded + 2 ); + + TracyQueuePrepare( QueueType::CallstackAlloc ); + MemWrite( &item->callstackAllocFat.ptr, (uint64_t)ptr ); + MemWrite( &item->callstackAllocFat.nativePtr, (uint64_t)Callstack( depth ) ); + TracyQueueCommit( callstackAllocFatThread ); +} + +static inline int LuaZoneBeginS( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + +#ifdef TRACY_CALLSTACK + const uint32_t depth = TRACY_CALLSTACK; +#else + const auto depth = uint32_t( lua_tointeger( L, 1 ) ); +#endif + SendLuaCallstack( L, depth ); + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src ); + + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + + return 0; +} + +static inline int LuaZoneBeginNS( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + +#ifdef TRACY_CALLSTACK + const uint32_t depth = TRACY_CALLSTACK; +#else + const auto depth = uint32_t( lua_tointeger( L, 2 ) ); +#endif + SendLuaCallstack( L, depth ); + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + size_t nsz; + const auto name = lua_tolstring( L, 1, &nsz ); + const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz ); + + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + + return 0; +} +#endif + +static inline int LuaZoneBegin( lua_State* L ) +{ +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK + return LuaZoneBeginS( L ); +#else +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src ); + + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + return 0; +#endif +} + +static inline int LuaZoneBeginN( lua_State* L ) +{ +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK + return LuaZoneBeginNS( L ); +#else +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + size_t nsz; + const auto name = lua_tolstring( L, 1, &nsz ); + const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz ); + + TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, srcloc ); + TracyQueueCommit( zoneBeginThread ); + return 0; +#endif +} + +static inline int LuaZoneEnd( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + assert( GetLuaZoneState().counter != 0 ); + GetLuaZoneState().counter--; + if( !GetLuaZoneState().active ) return 0; + if( !GetProfiler().IsConnected() ) + { + GetLuaZoneState().active = false; + return 0; + } +#endif + + TracyQueuePrepare( QueueType::ZoneEnd ); + MemWrite( &item->zoneEnd.time, Profiler::GetTime() ); + TracyQueueCommit( zoneEndThread ); + return 0; +} + +static inline int LuaZoneText( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + if( !GetLuaZoneState().active ) return 0; + if( !GetProfiler().IsConnected() ) + { + GetLuaZoneState().active = false; + return 0; + } +#endif + + auto txt = lua_tostring( L, 1 ); + const auto size = strlen( txt ); + assert( size < (std::numeric_limits::max)() ); + + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + + TracyQueuePrepare( QueueType::ZoneText ); + MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommit( zoneTextFatThread ); + return 0; +} + +static inline int LuaZoneName( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + if( !GetLuaZoneState().active ) return 0; + if( !GetProfiler().IsConnected() ) + { + GetLuaZoneState().active = false; + return 0; + } +#endif + + auto txt = lua_tostring( L, 1 ); + const auto size = strlen( txt ); + assert( size < (std::numeric_limits::max)() ); + + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + + TracyQueuePrepare( QueueType::ZoneName ); + MemWrite( &item->zoneTextFat.text, (uint64_t)ptr ); + MemWrite( &item->zoneTextFat.size, (uint16_t)size ); + TracyQueueCommit( zoneTextFatThread ); + return 0; +} + +static inline int LuaMessage( lua_State* L ) +{ +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return 0; +#endif + + auto txt = lua_tostring( L, 1 ); + const auto size = strlen( txt ); + assert( size < (std::numeric_limits::max)() ); + + auto ptr = (char*)tracy_malloc( size ); + memcpy( ptr, txt, size ); + + TracyQueuePrepare( QueueType::Message ); + MemWrite( &item->messageFat.time, Profiler::GetTime() ); + MemWrite( &item->messageFat.text, (uint64_t)ptr ); + MemWrite( &item->messageFat.size, (uint16_t)size ); + TracyQueueCommit( messageFatThread ); + return 0; +} + +} + +static inline void LuaRegister( lua_State* L ) +{ + lua_newtable( L ); + lua_pushcfunction( L, detail::LuaZoneBegin ); + lua_setfield( L, -2, "ZoneBegin" ); + lua_pushcfunction( L, detail::LuaZoneBeginN ); + lua_setfield( L, -2, "ZoneBeginN" ); +#ifdef TRACY_HAS_CALLSTACK + lua_pushcfunction( L, detail::LuaZoneBeginS ); + lua_setfield( L, -2, "ZoneBeginS" ); + lua_pushcfunction( L, detail::LuaZoneBeginNS ); + lua_setfield( L, -2, "ZoneBeginNS" ); +#else + lua_pushcfunction( L, detail::LuaZoneBegin ); + lua_setfield( L, -2, "ZoneBeginS" ); + lua_pushcfunction( L, detail::LuaZoneBeginN ); + lua_setfield( L, -2, "ZoneBeginNS" ); +#endif + lua_pushcfunction( L, detail::LuaZoneEnd ); + lua_setfield( L, -2, "ZoneEnd" ); + lua_pushcfunction( L, detail::LuaZoneText ); + lua_setfield( L, -2, "ZoneText" ); + lua_pushcfunction( L, detail::LuaZoneName ); + lua_setfield( L, -2, "ZoneName" ); + lua_pushcfunction( L, detail::LuaMessage ); + lua_setfield( L, -2, "Message" ); + lua_setglobal( L, "tracy" ); +} + +static inline void LuaRemove( char* script ) {} + +} + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyOpenCL.hpp b/Externals/tracy/public/tracy/TracyOpenCL.hpp new file mode 100644 index 00000000000..34466ccc97f --- /dev/null +++ b/Externals/tracy/public/tracy/TracyOpenCL.hpp @@ -0,0 +1,414 @@ +#ifndef __TRACYOPENCL_HPP__ +#define __TRACYOPENCL_HPP__ + +#if !defined TRACY_ENABLE + +#define TracyCLContext(c, x) nullptr +#define TracyCLDestroy(c) +#define TracyCLContextName(c, x, y) + +#define TracyCLNamedZone(c, x, y, z) +#define TracyCLNamedZoneC(c, x, y, z, w) +#define TracyCLZone(c, x) +#define TracyCLZoneC(c, x, y) +#define TracyCLZoneTransient(c,x,y,z) + +#define TracyCLNamedZoneS(c, x, y, z, w) +#define TracyCLNamedZoneCS(c, x, y, z, w, v) +#define TracyCLZoneS(c, x, y) +#define TracyCLZoneCS(c, x, y, z) +#define TracyCLZoneTransientS(c,x,y,z,w) + +#define TracyCLNamedZoneSetEvent(x, e) +#define TracyCLZoneSetEvent(e) + +#define TracyCLCollect(c) + +namespace tracy +{ + class OpenCLCtxScope {}; +} + +using TracyCLCtx = void*; + +#else + +#include + +#include +#include +#include + +#include "Tracy.hpp" +#include "../client/TracyCallstack.hpp" +#include "../client/TracyProfiler.hpp" +#include "../common/TracyAlloc.hpp" + +#define TRACY_CL_TO_STRING_INDIRECT(T) #T +#define TRACY_CL_TO_STRING(T) TRACY_CL_TO_STRING_INDIRECT(T) +#define TRACY_CL_ASSERT(p) if(!(p)) { \ + TracyMessageL( "TRACY_CL_ASSERT failed on " TracyFile ":" TRACY_CL_TO_STRING(TracyLine) ); \ + assert(false && "TRACY_CL_ASSERT failed"); \ +} +#define TRACY_CL_CHECK_ERROR(err) if(err != CL_SUCCESS) { \ + std::ostringstream oss; \ + oss << "TRACY_CL_CHECK_ERROR failed on " << TracyFile << ":" << TracyLine \ + << ": error code " << err; \ + auto msg = oss.str(); \ + TracyMessage(msg.data(), msg.size()); \ + assert(false && "TRACY_CL_CHECK_ERROR failed"); \ +} + +namespace tracy { + + enum class EventPhase : uint8_t + { + Begin, + End + }; + + struct EventInfo + { + cl_event event; + EventPhase phase; + }; + + class OpenCLCtx + { + public: + enum { QueryCount = 64 * 1024 }; + + OpenCLCtx(cl_context context, cl_device_id device) + : m_contextId(GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed)) + , m_head(0) + , m_tail(0) + { + int64_t tcpu, tgpu; + TRACY_CL_ASSERT(m_contextId != 255); + + cl_int err = CL_SUCCESS; + cl_command_queue queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err); + TRACY_CL_CHECK_ERROR(err) + uint32_t dummyValue = 42; + cl_mem dummyBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(uint32_t), nullptr, &err); + TRACY_CL_CHECK_ERROR(err) + cl_event writeBufferEvent; + TRACY_CL_CHECK_ERROR(clEnqueueWriteBuffer(queue, dummyBuffer, CL_FALSE, 0, sizeof(uint32_t), &dummyValue, 0, nullptr, &writeBufferEvent)); + TRACY_CL_CHECK_ERROR(clWaitForEvents(1, &writeBufferEvent)); + + tcpu = Profiler::GetTime(); + + cl_int eventStatus; + TRACY_CL_CHECK_ERROR(clGetEventInfo(writeBufferEvent, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &eventStatus, nullptr)); + TRACY_CL_ASSERT(eventStatus == CL_COMPLETE); + TRACY_CL_CHECK_ERROR(clGetEventProfilingInfo(writeBufferEvent, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &tgpu, nullptr)); + TRACY_CL_CHECK_ERROR(clReleaseEvent(writeBufferEvent)); + TRACY_CL_CHECK_ERROR(clReleaseMemObject(dummyBuffer)); + TRACY_CL_CHECK_ERROR(clReleaseCommandQueue(queue)); + + auto item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuNewContext); + MemWrite(&item->gpuNewContext.cpuTime, tcpu); + MemWrite(&item->gpuNewContext.gpuTime, tgpu); + memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread)); + MemWrite(&item->gpuNewContext.period, 1.0f); + MemWrite(&item->gpuNewContext.type, GpuContextType::OpenCL); + MemWrite(&item->gpuNewContext.context, (uint8_t) m_contextId); + MemWrite(&item->gpuNewContext.flags, (uint8_t)0); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem(*item); +#endif + Profiler::QueueSerialFinish(); + } + + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, (uint8_t)m_contextId ); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + void Collect() + { + ZoneScopedC(Color::Red4); + + if (m_tail == m_head) return; + +#ifdef TRACY_ON_DEMAND + if (!GetProfiler().IsConnected()) + { + m_head = m_tail = 0; + } +#endif + + for (; m_tail != m_head; m_tail = (m_tail + 1) % QueryCount) + { + EventInfo eventInfo = GetQuery(m_tail); + cl_int eventStatus; + cl_int err = clGetEventInfo(eventInfo.event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &eventStatus, nullptr); + if (err != CL_SUCCESS) + { + std::ostringstream oss; + oss << "clGetEventInfo falied with error code " << err << ", on event " << eventInfo.event << ", skipping..."; + auto msg = oss.str(); + TracyMessage(msg.data(), msg.size()); + if (eventInfo.event == nullptr) { + TracyMessageL("A TracyCLZone must be paird with a TracyCLZoneSetEvent, check your code!"); + } + assert(false && "clGetEventInfo failed, maybe a TracyCLZone is not paired with TracyCLZoneSetEvent"); + continue; + } + if (eventStatus != CL_COMPLETE) return; + + cl_int eventInfoQuery = (eventInfo.phase == EventPhase::Begin) + ? CL_PROFILING_COMMAND_START + : CL_PROFILING_COMMAND_END; + + cl_ulong eventTimeStamp = 0; + err = clGetEventProfilingInfo(eventInfo.event, eventInfoQuery, sizeof(cl_ulong), &eventTimeStamp, nullptr); + if (err == CL_PROFILING_INFO_NOT_AVAILABLE) + { + TracyMessageL("command queue is not created with CL_QUEUE_PROFILING_ENABLE flag, check your code!"); + assert(false && "command queue is not created with CL_QUEUE_PROFILING_ENABLE flag"); + } + else + TRACY_CL_CHECK_ERROR(err); + + TRACY_CL_ASSERT(eventTimeStamp != 0); + + auto item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuTime); + MemWrite(&item->gpuTime.gpuTime, (int64_t)eventTimeStamp); + MemWrite(&item->gpuTime.queryId, (uint16_t)m_tail); + MemWrite(&item->gpuTime.context, m_contextId); + Profiler::QueueSerialFinish(); + + if (eventInfo.phase == EventPhase::End) + { + // Done with the event, so release it + TRACY_CL_CHECK_ERROR(clReleaseEvent(eventInfo.event)); + } + } + } + + tracy_force_inline uint8_t GetId() const + { + return m_contextId; + } + + tracy_force_inline unsigned int NextQueryId(EventInfo eventInfo) + { + const auto id = m_head; + m_head = (m_head + 1) % QueryCount; + TRACY_CL_ASSERT(m_head != m_tail); + m_query[id] = eventInfo; + return id; + } + + tracy_force_inline EventInfo& GetQuery(unsigned int id) + { + TRACY_CL_ASSERT(id < QueryCount); + return m_query[id]; + } + + private: + + unsigned int m_contextId; + + EventInfo m_query[QueryCount]; + unsigned int m_head; // index at which a new event should be inserted + unsigned int m_tail; // oldest event + + }; + + class OpenCLCtxScope { + public: + tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, const SourceLocationData* srcLoc, bool is_active) +#ifdef TRACY_ON_DEMAND + : m_active(is_active&& GetProfiler().IsConnected()) +#else + : m_active(is_active) +#endif + , m_ctx(ctx) + , m_event(nullptr) + { + if (!m_active) return; + + m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin }); + + auto item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuZoneBeginSerial); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)srcLoc); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, const SourceLocationData* srcLoc, int depth, bool is_active) +#ifdef TRACY_ON_DEMAND + : m_active(is_active&& GetProfiler().IsConnected()) +#else + : m_active(is_active) +#endif + , m_ctx(ctx) + , m_event(nullptr) + { + if (!m_active) return; + + m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin }); + + GetProfiler().SendCallstack(depth); + + auto item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuZoneBeginCallstackSerial); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)srcLoc); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active) +#ifdef TRACY_ON_DEMAND + : m_active(is_active && GetProfiler().IsConnected()) +#else + : m_active(is_active) +#endif + , m_ctx(ctx) + , m_event(nullptr) + { + if (!m_active) return; + + m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin }); + + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial ); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, srcloc); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active) +#ifdef TRACY_ON_DEMAND + : m_active(is_active && GetProfiler().IsConnected()) +#else + : m_active(is_active) +#endif + , m_ctx(ctx) + , m_event(nullptr) + { + if (!m_active) return; + + m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin }); + + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + auto item = Profiler::QueueSerialCallstack( Callstack( depth ) ); + MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, srcloc); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline void SetEvent(cl_event event) + { + if (!m_active) return; + m_event = event; + TRACY_CL_CHECK_ERROR(clRetainEvent(m_event)); + m_ctx->GetQuery(m_beginQueryId).event = m_event; + } + + tracy_force_inline ~OpenCLCtxScope() + { + if (!m_active) return; + const auto queryId = m_ctx->NextQueryId(EventInfo{ m_event, EventPhase::End }); + + auto item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial); + MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneEnd.queryId, (uint16_t)queryId); + MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId()); + Profiler::QueueSerialFinish(); + } + + const bool m_active; + OpenCLCtx* m_ctx; + cl_event m_event; + unsigned int m_beginQueryId; + }; + + static inline OpenCLCtx* CreateCLContext(cl_context context, cl_device_id device) + { + auto ctx = (OpenCLCtx*)tracy_malloc(sizeof(OpenCLCtx)); + new (ctx) OpenCLCtx(context, device); + return ctx; + } + + static inline void DestroyCLContext(OpenCLCtx* ctx) + { + ctx->~OpenCLCtx(); + tracy_free(ctx); + } + +} // namespace tracy + +using TracyCLCtx = tracy::OpenCLCtx*; + +#define TracyCLContext(context, device) tracy::CreateCLContext(context, device); +#define TracyCLDestroy(ctx) tracy::DestroyCLContext(ctx); +#define TracyCLContextName(context, name, size) ctx->Name(name, size); +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyCLZone(ctx, name) TracyCLNamedZoneS(ctx, __tracy_gpu_zone, name, TRACY_CALLSTACK, true) +# define TracyCLZoneC(ctx, name, color) TracyCLNamedZoneCS(ctx, __tracy_gpu_zone, name, color, TRACY_CALLSTACK, true) +# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active ); +#else +# define TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), active); +# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), active); +# define TracyCLZone(ctx, name) TracyCLNamedZone(ctx, __tracy_gpu_zone, name, true) +# define TracyCLZoneC(ctx, name, color) TracyCLNamedZoneC(ctx, __tracy_gpu_zone, name, color, true ) +# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active ); +#endif + +#ifdef TRACY_HAS_CALLSTACK +# define TracyCLNamedZoneS(ctx, varname, name, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active); +# define TracyCLNamedZoneCS(ctx, varname, name, color, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active); +# define TracyCLZoneS(ctx, name, depth) TracyCLNamedZoneS(ctx, __tracy_gpu_zone, name, depth, true) +# define TracyCLZoneCS(ctx, name, color, depth) TracyCLNamedZoneCS(ctx, __tracy_gpu_zone, name, color, depth, true) +# define TracyCLZoneTransientS( ctx, varname, name, depth, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active ); +#else +# define TracyCLNamedZoneS(ctx, varname, name, depth, active) TracyCLNamedZone(ctx, varname, name, active) +# define TracyCLNamedZoneCS(ctx, varname, name, color, depth, active) TracyCLNamedZoneC(ctx, varname, name, color, active) +# define TracyCLZoneS(ctx, name, depth) TracyCLZone(ctx, name) +# define TracyCLZoneCS(ctx, name, color, depth) TracyCLZoneC(ctx, name, color) +# define TracyCLZoneTransientS( ctx, varname, name, depth, active ) TracyCLZoneTransient( ctx, varname, name, active ) +#endif + +#define TracyCLNamedZoneSetEvent(varname, event) varname.SetEvent(event) +#define TracyCLZoneSetEvent(event) __tracy_gpu_zone.SetEvent(event) + +#define TracyCLCollect(ctx) ctx->Collect() + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyOpenGL.hpp b/Externals/tracy/public/tracy/TracyOpenGL.hpp new file mode 100644 index 00000000000..3bdadccee58 --- /dev/null +++ b/Externals/tracy/public/tracy/TracyOpenGL.hpp @@ -0,0 +1,325 @@ +#ifndef __TRACYOPENGL_HPP__ +#define __TRACYOPENGL_HPP__ + +#if !defined TRACY_ENABLE || defined __APPLE__ + +#define TracyGpuContext +#define TracyGpuContextName(x,y) +#define TracyGpuNamedZone(x,y,z) +#define TracyGpuNamedZoneC(x,y,z,w) +#define TracyGpuZone(x) +#define TracyGpuZoneC(x,y) +#define TracyGpuZoneTransient(x,y,z) +#define TracyGpuCollect + +#define TracyGpuNamedZoneS(x,y,z,w) +#define TracyGpuNamedZoneCS(x,y,z,w,a) +#define TracyGpuZoneS(x,y) +#define TracyGpuZoneCS(x,y,z) +#define TracyGpuZoneTransientS(x,y,z,w) + +namespace tracy +{ +struct SourceLocationData; +class GpuCtxScope +{ +public: + GpuCtxScope( const SourceLocationData*, bool ) {} + GpuCtxScope( const SourceLocationData*, int, bool ) {} +}; +} + +#else + +#include +#include +#include + +#include "Tracy.hpp" +#include "../client/TracyProfiler.hpp" +#include "../client/TracyCallstack.hpp" +#include "../common/TracyAlign.hpp" +#include "../common/TracyAlloc.hpp" + +#if !defined GL_TIMESTAMP && defined GL_TIMESTAMP_EXT +# define GL_TIMESTAMP GL_TIMESTAMP_EXT +# define GL_QUERY_COUNTER_BITS GL_QUERY_COUNTER_BITS_EXT +# define glGetQueryObjectiv glGetQueryObjectivEXT +# define glGetQueryObjectui64v glGetQueryObjectui64vEXT +# define glQueryCounter glQueryCounterEXT +#endif + +#define TracyGpuContext tracy::GetGpuCtx().ptr = (tracy::GpuCtx*)tracy::tracy_malloc( sizeof( tracy::GpuCtx ) ); new(tracy::GetGpuCtx().ptr) tracy::GpuCtx; +#define TracyGpuContextName( name, size ) tracy::GetGpuCtx().ptr->Name( name, size ); +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active ); +# define TracyGpuZone( name ) TracyGpuNamedZoneS( ___tracy_gpu_zone, name, TRACY_CALLSTACK, true ) +# define TracyGpuZoneC( name, color ) TracyGpuNamedZoneCS( ___tracy_gpu_zone, name, color, TRACY_CALLSTACK, true ) +# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active ); +#else +# define TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), active ); +# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), active ); +# define TracyGpuZone( name ) TracyGpuNamedZone( ___tracy_gpu_zone, name, true ) +# define TracyGpuZoneC( name, color ) TracyGpuNamedZoneC( ___tracy_gpu_zone, name, color, true ) +# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active ); +#endif +#define TracyGpuCollect tracy::GetGpuCtx().ptr->Collect(); + +#ifdef TRACY_HAS_CALLSTACK +# define TracyGpuNamedZoneS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active ); +# define TracyGpuNamedZoneCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active ); +# define TracyGpuZoneS( name, depth ) TracyGpuNamedZoneS( ___tracy_gpu_zone, name, depth, true ) +# define TracyGpuZoneCS( name, color, depth ) TracyGpuNamedZoneCS( ___tracy_gpu_zone, name, color, depth, true ) +# define TracyGpuZoneTransientS( varname, name, depth, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active ); +#else +# define TracyGpuNamedZoneS( varname, name, depth, active ) TracyGpuNamedZone( varname, name, active ) +# define TracyGpuNamedZoneCS( varname, name, color, depth, active ) TracyGpuNamedZoneC( varname, name, color, active ) +# define TracyGpuZoneS( name, depth ) TracyGpuZone( name ) +# define TracyGpuZoneCS( name, color, depth ) TracyGpuZoneC( name, color ) +# define TracyGpuZoneTransientS( varname, name, depth, active ) TracyGpuZoneTransient( varname, name, active ) +#endif + +namespace tracy +{ + +class GpuCtx +{ + friend class GpuCtxScope; + + enum { QueryCount = 64 * 1024 }; + +public: + GpuCtx() + : m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) ) + , m_head( 0 ) + , m_tail( 0 ) + { + assert( m_context != 255 ); + + glGenQueries( QueryCount, m_query ); + + int64_t tgpu; + glGetInteger64v( GL_TIMESTAMP, &tgpu ); + int64_t tcpu = Profiler::GetTime(); + + GLint bits; + glGetQueryiv( GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &bits ); + + const float period = 1.f; + const auto thread = GetThreadHandle(); + TracyLfqPrepare( QueueType::GpuNewContext ); + MemWrite( &item->gpuNewContext.cpuTime, tcpu ); + MemWrite( &item->gpuNewContext.gpuTime, tgpu ); + MemWrite( &item->gpuNewContext.thread, thread ); + MemWrite( &item->gpuNewContext.period, period ); + MemWrite( &item->gpuNewContext.context, m_context ); + MemWrite( &item->gpuNewContext.flags, uint8_t( 0 ) ); + MemWrite( &item->gpuNewContext.type, GpuContextType::OpenGl ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + TracyLfqCommit; + } + + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + TracyLfqPrepare( QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, m_context ); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + TracyLfqCommit; + } + + void Collect() + { + ZoneScopedC( Color::Red4 ); + + if( m_tail == m_head ) return; + +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) + { + m_head = m_tail = 0; + return; + } +#endif + + while( m_tail != m_head ) + { + GLint available; + glGetQueryObjectiv( m_query[m_tail], GL_QUERY_RESULT_AVAILABLE, &available ); + if( !available ) return; + + uint64_t time; + glGetQueryObjectui64v( m_query[m_tail], GL_QUERY_RESULT, &time ); + + TracyLfqPrepare( QueueType::GpuTime ); + MemWrite( &item->gpuTime.gpuTime, (int64_t)time ); + MemWrite( &item->gpuTime.queryId, (uint16_t)m_tail ); + MemWrite( &item->gpuTime.context, m_context ); + TracyLfqCommit; + + m_tail = ( m_tail + 1 ) % QueryCount; + } + } + +private: + tracy_force_inline unsigned int NextQueryId() + { + const auto id = m_head; + m_head = ( m_head + 1 ) % QueryCount; + assert( m_head != m_tail ); + return id; + } + + tracy_force_inline unsigned int TranslateOpenGlQueryId( unsigned int id ) + { + return m_query[id]; + } + + tracy_force_inline uint8_t GetId() const + { + return m_context; + } + + unsigned int m_query[QueryCount]; + uint8_t m_context; + + unsigned int m_head; + unsigned int m_tail; +}; + +class GpuCtxScope +{ +public: + tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + + const auto queryId = GetGpuCtx().ptr->NextQueryId(); + glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP ); + + TracyLfqPrepare( QueueType::GpuZoneBegin ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + TracyLfqCommit; + } + + tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, int depth, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + + const auto queryId = GetGpuCtx().ptr->NextQueryId(); + glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP ); + +#ifdef TRACY_FIBERS + TracyLfqPrepare( QueueType::GpuZoneBegin ); + memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) ); +#else + GetProfiler().SendCallstack( depth ); + TracyLfqPrepare( QueueType::GpuZoneBeginCallstack ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); +#endif + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + TracyLfqCommit; + } + + tracy_force_inline GpuCtxScope( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + + const auto queryId = GetGpuCtx().ptr->NextQueryId(); + glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP ); + + TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLoc ); + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + TracyLfqCommit; + } + + tracy_force_inline GpuCtxScope( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + + const auto queryId = GetGpuCtx().ptr->NextQueryId(); + glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP ); + +#ifdef TRACY_FIBERS + TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLoc ); + memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) ); +#else + GetProfiler().SendCallstack( depth ); + TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLocCallstack ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); +#endif + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + TracyLfqCommit; + } + + tracy_force_inline ~GpuCtxScope() + { + if( !m_active ) return; + + const auto queryId = GetGpuCtx().ptr->NextQueryId(); + glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP ); + + TracyLfqPrepare( QueueType::GpuZoneEnd ); + MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() ); + memset( &item->gpuZoneEnd.thread, 0, sizeof( item->gpuZoneEnd.thread ) ); + MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneEnd.context, GetGpuCtx().ptr->GetId() ); + TracyLfqCommit; + } + +private: + const bool m_active; +}; + +} + +#endif + +#endif diff --git a/Externals/tracy/public/tracy/TracyVulkan.hpp b/Externals/tracy/public/tracy/TracyVulkan.hpp new file mode 100644 index 00000000000..2d079f7b5af --- /dev/null +++ b/Externals/tracy/public/tracy/TracyVulkan.hpp @@ -0,0 +1,705 @@ +#ifndef __TRACYVULKAN_HPP__ +#define __TRACYVULKAN_HPP__ + +#if !defined TRACY_ENABLE + +#define TracyVkContext(x,y,z,w) nullptr +#define TracyVkContextCalibrated(x,y,z,w,a,b) nullptr +#if defined VK_EXT_host_query_reset +#define TracyVkContextHostCalibrated(x,y,z,w,a) nullptr +#endif +#define TracyVkDestroy(x) +#define TracyVkContextName(c,x,y) +#define TracyVkNamedZone(c,x,y,z,w) +#define TracyVkNamedZoneC(c,x,y,z,w,a) +#define TracyVkZone(c,x,y) +#define TracyVkZoneC(c,x,y,z) +#define TracyVkZoneTransient(c,x,y,z,w) +#define TracyVkCollect(c,x) + +#define TracyVkNamedZoneS(c,x,y,z,w,a) +#define TracyVkNamedZoneCS(c,x,y,z,w,v,a) +#define TracyVkZoneS(c,x,y,z) +#define TracyVkZoneCS(c,x,y,z,w) +#define TracyVkZoneTransientS(c,x,y,z,w,a) + +namespace tracy +{ +class VkCtxScope {}; +} + +using TracyVkCtx = void*; + +#else + +#if !defined VK_NULL_HANDLE +# error "You must include Vulkan headers before including TracyVulkan.hpp" +#endif + +#include +#include +#include "Tracy.hpp" +#include "../client/TracyProfiler.hpp" +#include "../client/TracyCallstack.hpp" + +#include + +namespace tracy +{ + +#if defined TRACY_VK_USE_SYMBOL_TABLE +#define LoadVkDeviceCoreSymbols(Operation) \ + Operation(vkBeginCommandBuffer) \ + Operation(vkCmdResetQueryPool) \ + Operation(vkCmdWriteTimestamp) \ + Operation(vkCreateQueryPool) \ + Operation(vkDestroyQueryPool) \ + Operation(vkEndCommandBuffer) \ + Operation(vkGetQueryPoolResults) \ + Operation(vkQueueSubmit) \ + Operation(vkQueueWaitIdle) \ + Operation(vkResetQueryPool) + +#define LoadVkDeviceExtensionSymbols(Operation) \ + Operation(vkGetCalibratedTimestampsEXT) \ + Operation(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT) + +#define LoadVkInstanceCoreSymbols(Operation) \ + Operation(vkGetPhysicalDeviceProperties) + +struct VkSymbolTable +{ +#define MAKE_PFN(name) PFN_##name name; + LoadVkDeviceCoreSymbols(MAKE_PFN) + LoadVkDeviceExtensionSymbols(MAKE_PFN) + LoadVkInstanceCoreSymbols(MAKE_PFN) +#undef MAKE_PFN +}; + +#define VK_FUNCTION_WRAPPER(callSignature) m_symbols.callSignature +#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) m_ctx->m_symbols.callSignature +#else +#define VK_FUNCTION_WRAPPER(callSignature) callSignature +#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) callSignature +#endif + +class VkCtx +{ + friend class VkCtxScope; + + enum { QueryCount = 64 * 1024 }; + +public: +#if defined TRACY_VK_USE_SYMBOL_TABLE + VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr, bool calibrated ) +#else + VkCtx( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT) +#endif + : m_device( device ) + , m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT ) + , m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) ) + , m_head( 0 ) + , m_tail( 0 ) + , m_oldCnt( 0 ) + , m_queryCount( QueryCount ) +#if !defined TRACY_VK_USE_SYMBOL_TABLE + , m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT ) +#endif + { + assert( m_context != 255 ); + +#if defined TRACY_VK_USE_SYMBOL_TABLE + PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr); + if ( calibrated ) + { + m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT; + } + +#endif + + if( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) && m_vkGetCalibratedTimestampsEXT ) + { + FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) ); + } + + CreateQueryPool(); + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &cmdbuf; + + VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) ); + VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) ); + VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) ); + VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) ); + VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) ); + + int64_t tcpu, tgpu; + if( m_timeDomain == VK_TIME_DOMAIN_DEVICE_EXT ) + { + VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) ); + VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_query, 0 ) ); + VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) ); + VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) ); + VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) ); + + tcpu = Profiler::GetTime(); + VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( device, m_query, 0, 1, sizeof( tgpu ), &tgpu, sizeof( tgpu ), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT ) ); + + VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) ); + VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, 1 ) ); + VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) ); + VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) ); + VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) ); + } + else + { + FindCalibratedTimestampDeviation(); + Calibrate( device, m_prevCalibration, tgpu ); + tcpu = Profiler::GetTime(); + } + + WriteInitialItem( physdev, tcpu, tgpu ); + + m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount ); + } + +#if defined VK_EXT_host_query_reset + /** + * This alternative constructor does not use command buffers and instead uses functionality from + * VK_EXT_host_query_reset (core with 1.2 and non-optional) and VK_EXT_calibrated_timestamps. This requires + * the physical device to have another time domain apart from DEVICE to be calibrateable. + */ +#if defined TRACY_VK_USE_SYMBOL_TABLE + VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr ) +#else + VkCtx( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT vkResetQueryPool, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT ) +#endif + : m_device( device ) + , m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT ) + , m_context( GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed) ) + , m_head( 0 ) + , m_tail( 0 ) + , m_oldCnt( 0 ) + , m_queryCount( QueryCount ) +#if !defined TRACY_VK_USE_SYMBOL_TABLE + , m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT ) +#endif + { + assert( m_context != 255); + +#if defined TRACY_VK_USE_SYMBOL_TABLE + PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr); + m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT; +#endif + + assert( VK_FUNCTION_WRAPPER( vkResetQueryPool ) != nullptr ); + assert( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) != nullptr ); + assert( VK_FUNCTION_WRAPPER( vkGetCalibratedTimestampsEXT ) != nullptr ); + + FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) ); + + // We require a host time domain to be available to properly calibrate. + FindCalibratedTimestampDeviation(); + int64_t tgpu; + Calibrate( device, m_prevCalibration, tgpu ); + int64_t tcpu = Profiler::GetTime(); + + CreateQueryPool(); + VK_FUNCTION_WRAPPER( vkResetQueryPool( device, m_query, 0, m_queryCount ) ); + + WriteInitialItem( physdev, tcpu, tgpu ); + + m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount ); + } +#endif + + ~VkCtx() + { + tracy_free( m_res ); + VK_FUNCTION_WRAPPER( vkDestroyQueryPool( m_device, m_query, nullptr ) ); + } + + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, m_context ); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + + void Collect( VkCommandBuffer cmdbuf ) + { + ZoneScopedC( Color::Red4 ); + + const uint64_t head = m_head.load(std::memory_order_relaxed); + if( m_tail == head ) return; + +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) + { + VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) ); + m_tail = head; + m_oldCnt = 0; + int64_t tgpu; + if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) Calibrate( m_device, m_prevCalibration, tgpu ); + return; + } +#endif + assert( head > m_tail ); + + const unsigned int wrappedTail = (unsigned int)( m_tail % m_queryCount ); + + unsigned int cnt; + if( m_oldCnt != 0 ) + { + cnt = m_oldCnt; + m_oldCnt = 0; + } + else + { + cnt = (unsigned int)( head - m_tail ); + assert( cnt <= m_queryCount ); + if( wrappedTail + cnt > m_queryCount ) + { + cnt = m_queryCount - wrappedTail; + } + } + + + if( VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( m_device, m_query, wrappedTail, cnt, sizeof( int64_t ) * m_queryCount, m_res, sizeof( int64_t ), VK_QUERY_RESULT_64_BIT ) == VK_NOT_READY ) ) + { + m_oldCnt = cnt; + return; + } + + for( unsigned int idx=0; idxhdr.type, QueueType::GpuTime ); + MemWrite( &item->gpuTime.gpuTime, m_res[idx] ); + MemWrite( &item->gpuTime.queryId, uint16_t( wrappedTail + idx ) ); + MemWrite( &item->gpuTime.context, m_context ); + Profiler::QueueSerialFinish(); + } + + if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) + { + int64_t tgpu, tcpu; + Calibrate( m_device, tcpu, tgpu ); + const auto refCpu = Profiler::GetTime(); + const auto delta = tcpu - m_prevCalibration; + if( delta > 0 ) + { + m_prevCalibration = tcpu; + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuCalibration ); + MemWrite( &item->gpuCalibration.gpuTime, tgpu ); + MemWrite( &item->gpuCalibration.cpuTime, refCpu ); + MemWrite( &item->gpuCalibration.cpuDelta, delta ); + MemWrite( &item->gpuCalibration.context, m_context ); + Profiler::QueueSerialFinish(); + } + } + + VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, wrappedTail, cnt ) ); + + m_tail += cnt; + } + +private: + tracy_force_inline unsigned int NextQueryId() + { + const uint64_t id = m_head.fetch_add(1, std::memory_order_relaxed); + return id % m_queryCount; + } + + tracy_force_inline uint8_t GetId() const + { + return m_context; + } + + tracy_force_inline void Calibrate( VkDevice device, int64_t& tCpu, int64_t& tGpu ) + { + assert( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ); + VkCalibratedTimestampInfoEXT spec[2] = { + { VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, VK_TIME_DOMAIN_DEVICE_EXT }, + { VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, m_timeDomain }, + }; + uint64_t ts[2]; + uint64_t deviation; + do + { + m_vkGetCalibratedTimestampsEXT( device, 2, spec, ts, &deviation ); + } + while( deviation > m_deviation ); + +#if defined _WIN32 + tGpu = ts[0]; + tCpu = ts[1] * m_qpcToNs; +#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW + tGpu = ts[0]; + tCpu = ts[1]; +#else + assert( false ); +#endif + } + + tracy_force_inline void CreateQueryPool() + { + VkQueryPoolCreateInfo poolInfo = {}; + poolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; + poolInfo.queryCount = m_queryCount; + poolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP; + while ( VK_FUNCTION_WRAPPER( vkCreateQueryPool( m_device, &poolInfo, nullptr, &m_query ) != VK_SUCCESS ) ) + { + m_queryCount /= 2; + poolInfo.queryCount = m_queryCount; + } + } + + tracy_force_inline void FindAvailableTimeDomains( VkPhysicalDevice physicalDevice, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) + { + uint32_t num; + _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, nullptr ); + if(num > 4) num = 4; + VkTimeDomainEXT data[4]; + _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, data ); + VkTimeDomainEXT supportedDomain = (VkTimeDomainEXT)-1; +#if defined _WIN32 + supportedDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT; +#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW + supportedDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT; +#endif + for( uint32_t i=0; i deviation[i] ) { + minDeviation = deviation[i]; + } + } + m_deviation = minDeviation * 3 / 2; + +#if defined _WIN32 + m_qpcToNs = int64_t( 1000000000. / GetFrequencyQpc() ); +#endif + } + + tracy_force_inline void WriteInitialItem( VkPhysicalDevice physdev, int64_t tcpu, int64_t tgpu ) + { + uint8_t flags = 0; + if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) flags |= GpuContextCalibration; + + VkPhysicalDeviceProperties prop; + VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceProperties( physdev, &prop ) ); + const float period = prop.limits.timestampPeriod; + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuNewContext ); + MemWrite( &item->gpuNewContext.cpuTime, tcpu ); + MemWrite( &item->gpuNewContext.gpuTime, tgpu ); + memset( &item->gpuNewContext.thread, 0, sizeof( item->gpuNewContext.thread ) ); + MemWrite( &item->gpuNewContext.period, period ); + MemWrite( &item->gpuNewContext.context, m_context ); + MemWrite( &item->gpuNewContext.flags, flags ); + MemWrite( &item->gpuNewContext.type, GpuContextType::Vulkan ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + +#if defined TRACY_VK_USE_SYMBOL_TABLE + void PopulateSymbolTable( VkInstance instance, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr ) + { +#define VK_GET_DEVICE_SYMBOL( name ) \ + (PFN_##name)deviceProcAddr( m_device, #name ); +#define VK_LOAD_DEVICE_SYMBOL( name ) \ + m_symbols.name = VK_GET_DEVICE_SYMBOL( name ); +#define VK_GET_INSTANCE_SYMBOL( name ) \ + (PFN_##name)instanceProcAddr( instance, #name ); +#define VK_LOAD_INSTANCE_SYMBOL( name ) \ + m_symbols.name = VK_GET_INSTANCE_SYMBOL( name ); + + LoadVkDeviceCoreSymbols( VK_LOAD_DEVICE_SYMBOL ) + LoadVkDeviceExtensionSymbols( VK_LOAD_DEVICE_SYMBOL ) + LoadVkInstanceCoreSymbols( VK_LOAD_INSTANCE_SYMBOL ) +#undef VK_GET_DEVICE_SYMBOL +#undef VK_LOAD_DEVICE_SYMBOL +#undef VK_GET_INSTANCE_SYMBOL +#undef VK_LOAD_INSTANCE_SYMBOL + } +#endif + + VkDevice m_device; + VkQueryPool m_query; + VkTimeDomainEXT m_timeDomain; +#if defined TRACY_VK_USE_SYMBOL_TABLE + VkSymbolTable m_symbols; +#endif + uint64_t m_deviation; + int64_t m_qpcToNs; + int64_t m_prevCalibration; + uint8_t m_context; + + std::atomic m_head; + uint64_t m_tail; + unsigned int m_oldCnt; + unsigned int m_queryCount; + + int64_t* m_res; + + PFN_vkGetCalibratedTimestampsEXT m_vkGetCalibratedTimestampsEXT; +}; + +class VkCtxScope +{ +public: + tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_cmdbuf = cmdbuf; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, int depth, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_cmdbuf = cmdbuf; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) ); + + auto item = Profiler::QueueSerialCallstack( Callstack( depth ) ); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginCallstackSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_cmdbuf = cmdbuf; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) ); + + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, srcloc ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, int depth, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_cmdbuf = cmdbuf; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) ); + + const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); + auto item = Profiler::QueueSerialCallstack( Callstack( depth ) ); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, srcloc ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + Profiler::QueueSerialFinish(); + } + + tracy_force_inline ~VkCtxScope() + { + if( !m_active ) return; + + const auto queryId = m_ctx->NextQueryId(); + CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( m_cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_ctx->m_query, queryId ) ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial ); + MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneEnd.context, m_ctx->GetId() ); + Profiler::QueueSerialFinish(); + } + +private: + const bool m_active; + + VkCommandBuffer m_cmdbuf; + VkCtx* m_ctx; +}; + +#if defined TRACY_VK_USE_SYMBOL_TABLE +static inline VkCtx* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr, bool calibrated = false ) +#else +static inline VkCtx* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct ) +#endif +{ + auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) ); +#if defined TRACY_VK_USE_SYMBOL_TABLE + new(ctx) VkCtx( instance, physdev, device, queue, cmdbuf, instanceProcAddr, getDeviceProcAddr, calibrated ); +#else + new(ctx) VkCtx( physdev, device, queue, cmdbuf, gpdctd, gct ); +#endif + return ctx; +} + +#if defined VK_EXT_host_query_reset +#if defined TRACY_VK_USE_SYMBOL_TABLE +static inline VkCtx* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr ) +#else +static inline VkCtx* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT qpreset, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct ) +#endif +{ + auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) ); +#if defined TRACY_VK_USE_SYMBOL_TABLE + new(ctx) VkCtx( instance, physdev, device, instanceProcAddr, getDeviceProcAddr ); +#else + new(ctx) VkCtx( physdev, device, qpreset, gpdctd, gct ); +#endif + return ctx; +} +#endif + +static inline void DestroyVkContext( VkCtx* ctx ) +{ + ctx->~VkCtx(); + tracy_free( ctx ); +} + +} + +using TracyVkCtx = tracy::VkCtx*; + +#if defined TRACY_VK_USE_SYMBOL_TABLE +#define TracyVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ); +#else +#define TracyVkContext( physdev, device, queue, cmdbuf ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, nullptr, nullptr ); +#endif +#if defined TRACY_VK_USE_SYMBOL_TABLE +#define TracyVkContextCalibrated( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr, true ); +#else +#define TracyVkContextCalibrated( physdev, device, queue, cmdbuf, gpdctd, gct ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, gpdctd, gct ); +#endif +#if defined VK_EXT_host_query_reset +#if defined TRACY_VK_USE_SYMBOL_TABLE +#define TracyVkContextHostCalibrated( instance, physdev, device, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, instanceProcAddr, deviceProcAddr ); +#else +#define TracyVkContextHostCalibrated( physdev, device, qpreset, gpdctd, gct ) tracy::CreateVkContext( physdev, device, qpreset, gpdctd, gct ); +#endif +#endif +#define TracyVkDestroy( ctx ) tracy::DestroyVkContext( ctx ); +#define TracyVkContextName( ctx, name, size ) ctx->Name( name, size ); +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active ); +# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active ); +# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, TRACY_CALLSTACK, true ) +# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, TRACY_CALLSTACK, true ) +# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) TracyVkZoneTransientS( ctx, varname, cmdbuf, name, TRACY_CALLSTACK, active ) +#else +# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active ); +# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active ); +# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZone( ctx, ___tracy_gpu_zone, cmdbuf, name, true ) +# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneC( ctx, ___tracy_gpu_zone, cmdbuf, name, color, true ) +# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, active ); +#endif +#define TracyVkCollect( ctx, cmdbuf ) ctx->Collect( cmdbuf ); + +#ifdef TRACY_HAS_CALLSTACK +# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active ); +# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active ); +# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, depth, true ) +# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, depth, true ) +# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, depth, active ); +#else +# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) +# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) +# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkZone( ctx, cmdbuf, name ) +# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkZoneC( ctx, cmdbuf, name, color ) +# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) +#endif + +#endif + +#endif diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index a2846135a25..be96f833173 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -212,6 +212,9 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) _SHOW_REF("* CREATE: DeviceREF:", pDevice); + // Register immediate context in profiler + profiler_ctx = TracyD3D11Context(pDevice, pContext); + // Create deferred contexts for (int id = 0; id < R__NUM_PARALLEL_CONTEXTS; ++id) { @@ -411,6 +414,8 @@ void CHW::DestroyDevice() _SHOW_REF("refCount:m_pSwapChain", m_pSwapChain); _RELEASE(m_pSwapChain); + TracyD3D11Destroy(profiler_ctx); + _RELEASE(pContext1); for (int id = 0; id < R__NUM_CONTEXTS; ++id) { @@ -506,6 +511,8 @@ void CHW::Present() } CurrentBackBuffer = (CurrentBackBuffer + 1) % BackBufferCount; + + TracyD3D11Collect(profiler_ctx); } DeviceState CHW::GetDeviceState() diff --git a/src/Layers/xrRenderDX11/dx11HW.h b/src/Layers/xrRenderDX11/dx11HW.h index 9faac490c2d..dd476bff932 100644 --- a/src/Layers/xrRenderDX11/dx11HW.h +++ b/src/Layers/xrRenderDX11/dx11HW.h @@ -98,6 +98,7 @@ class CHW #if !defined(_MAYA_EXPORT) stats_manager stats_manager; #endif + TracyD3D11Ctx profiler_ctx{}; // TODO: this should be one per d3d11 context private: DXGI_SWAP_CHAIN_DESC m_ChainDesc; // DevPP equivalent bool doPresentTest{}; diff --git a/src/Layers/xrRenderPC_R4/stdafx.h b/src/Layers/xrRenderPC_R4/stdafx.h index 1517620b19e..dc02089dc33 100644 --- a/src/Layers/xrRenderPC_R4/stdafx.h +++ b/src/Layers/xrRenderPC_R4/stdafx.h @@ -33,6 +33,8 @@ #define HAS_DX11_3 #endif +#include + #include "Layers/xrRenderDX11/CommonTypes.h" #include "Layers/xrRenderDX11/dx11HW.h" diff --git a/src/Layers/xrRender_R2/r2_R_calculate.cpp b/src/Layers/xrRender_R2/r2_R_calculate.cpp index 03536b4eddb..987be7666b4 100644 --- a/src/Layers/xrRender_R2/r2_R_calculate.cpp +++ b/src/Layers/xrRender_R2/r2_R_calculate.cpp @@ -27,6 +27,8 @@ void render_main::init() void render_main::calculate() { + ZoneScoped; + auto& dsgraph_main = RImplementation.get_imm_context(); dsgraph_main.o.phase = CRender::PHASE_NORMAL; @@ -61,6 +63,8 @@ void render_main::render() void CRender::Calculate() { + ZoneScopedN("r2_calculate"); + // Transfer to global space to avoid deep pointer access IRender_Target* T = getTarget(); float fov_factor = _sqr(90.f / Device.fFOV); diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index 55f374b0290..017e90a04d5 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -10,6 +10,9 @@ void CRender::RenderMenu() { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_menu"); +#endif PIX_EVENT(render_menu); // Globals RCache.set_CullMode(CULL_CCW); @@ -72,6 +75,9 @@ void CRender::RenderMenu() extern u32 g_r; void CRender::Render() { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "Render"); +#endif PIX_EVENT(CRender_Render); g_r = 1; diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 55ec3bfdce7..65a48e46417 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -436,6 +436,9 @@ target_sources_grouped( ) target_include_directories(xrCore + PUBLIC + "${CMAKE_SOURCE_DIR}/Externals/tracy/public" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src" diff --git a/src/xrCore/Threading/ThreadUtil.h b/src/xrCore/Threading/ThreadUtil.h index 3c4e2becc03..978306206d1 100644 --- a/src/xrCore/Threading/ThreadUtil.h +++ b/src/xrCore/Threading/ThreadUtil.h @@ -44,6 +44,9 @@ template [name](Invocable&& invocable2, Args&&... args2) { SetCurrentThreadName(name); +#ifdef TRACY_ENABLE + tracy::SetThreadName(name); +#endif _initialize_cpu_thread(); std::invoke(std::move(invocable2), std::move(args2)...); }, diff --git a/src/xrCore/xrCore.h b/src/xrCore/xrCore.h index 0ced1370128..befe0ba578d 100644 --- a/src/xrCore/xrCore.h +++ b/src/xrCore/xrCore.h @@ -28,9 +28,12 @@ # define XRCORE_API XR_EXPORT # else # define XRCORE_API XR_IMPORT +# define TRACY_IMPORTS # endif #endif +#include + #include "xrDebug.h" //#include "vector.h" diff --git a/src/xrCore/xrCore.vcxproj b/src/xrCore/xrCore.vcxproj index 0c67bcea4ab..51a7ef8bf42 100644 --- a/src/xrCore/xrCore.vcxproj +++ b/src/xrCore/xrCore.vcxproj @@ -23,7 +23,7 @@ $(xrExternals)lzo\include;$(xrSdkDir)include\mimalloc;%(AdditionalIncludeDirectories) - _USRDLL;XRCORE_EXPORTS;CRYPTO_BUILD;CI=$(CI);APPVEYOR=$(APPVEYOR);APPVEYOR_BUILD_ID="$(APPVEYOR_BUILD_ID)";APPVEYOR_BUILD_VERSION="$(APPVEYOR_BUILD_VERSION)";APPVEYOR_ACCOUNT_NAME="$(APPVEYOR_ACCOUNT_NAME)";GITHUB_ACTIONS=$(GITHUB_ACTIONS);GITHUB_RUN_ID="$(GITHUB_RUN_ID)";GITHUB_RUN_NUMBER="$(GITHUB_RUN_NUMBER)";GITHUB_REPOSITORY="$(GITHUB_REPOSITORY)";%(PreprocessorDefinitions) + _USRDLL;XRCORE_EXPORTS;CRYPTO_BUILD;CI=$(CI);APPVEYOR=$(APPVEYOR);APPVEYOR_BUILD_ID="$(APPVEYOR_BUILD_ID)";APPVEYOR_BUILD_VERSION="$(APPVEYOR_BUILD_VERSION)";APPVEYOR_ACCOUNT_NAME="$(APPVEYOR_ACCOUNT_NAME)";GITHUB_ACTIONS=$(GITHUB_ACTIONS);GITHUB_RUN_ID="$(GITHUB_RUN_ID)";GITHUB_RUN_NUMBER="$(GITHUB_RUN_NUMBER)";GITHUB_REPOSITORY="$(GITHUB_REPOSITORY)";TRACY_EXPORTS;%(PreprocessorDefinitions) DbgHelp.lib;FaultRep.lib;jpeg-static.lib;%(AdditionalDependencies) @@ -41,6 +41,9 @@ call .GitInfo.cmd + + NotUsing + diff --git a/src/xrCore/xrCore.vcxproj.filters b/src/xrCore/xrCore.vcxproj.filters index e086469be15..7dbe6b5aef3 100644 --- a/src/xrCore/xrCore.vcxproj.filters +++ b/src/xrCore/xrCore.vcxproj.filters @@ -118,6 +118,9 @@ {14c94737-f2c7-482d-9033-775a3da068cb} + + {ea7e41e5-3ae4-44a3-8b2a-21337befa3c0} + @@ -330,6 +333,9 @@ Math\RNG + + Profiler + diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 3d7eef3664a..c85559a27fc 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -240,6 +240,8 @@ static void UpdateViewports() void CRenderDevice::DoRender() { + ZoneScoped; + if (GEnv.isDedicatedServer) return; @@ -290,6 +292,8 @@ void CRenderDevice::SecondaryThreadProc() void CRenderDevice::ProcessFrame() { + ZoneScoped; + if (!BeforeFrame()) return; @@ -324,6 +328,8 @@ void CRenderDevice::ProcessFrame() if (!b_is_Active) Sleep(1); + + FrameMark; } void CRenderDevice::ProcessEvent(const SDL_Event& event) diff --git a/src/xray_build.props b/src/xray_build.props index 48fbf15fb76..9c00d64d654 100644 --- a/src/xray_build.props +++ b/src/xray_build.props @@ -94,7 +94,13 @@ - DEBUG;MIXED;%(PreprocessorDefinitions) + + DEBUG; + MIXED; + TRACY_ENABLE; + TRACY_NO_FRAME_IMAGE; + %(PreprocessorDefinitions) + Disabled diff --git a/src/xray_input.props b/src/xray_input.props index 4ec550f4da8..75c44603ca4 100644 --- a/src/xray_input.props +++ b/src/xray_input.props @@ -11,6 +11,7 @@ $(xrExternals)luajit\src; $(xrExternals)luabind; $(xrExternals)imgui; + $(xrExternals)tracy\public; %(AdditionalIncludeDirectories) From 740a382cda642b5187059ead29ac81b954e1de5a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 07:13:25 +0500 Subject: [PATCH 318/497] Removed xrMemory alloc/free calls counter It's not that useful, and in multithreaded environment it's not guaranteed to be precise. --- src/xrCore/xrMemory.cpp | 12 ------------ src/xrCore/xrMemory.h | 2 -- src/xrEngine/Stats.cpp | 8 -------- src/xrEngine/Stats.h | 1 - 4 files changed, 23 deletions(-) diff --git a/src/xrCore/xrMemory.cpp b/src/xrCore/xrMemory.cpp index efe68a972f0..e734443a287 100644 --- a/src/xrCore/xrMemory.cpp +++ b/src/xrCore/xrMemory.cpp @@ -91,8 +91,6 @@ bool shared_str_initialized = false; void xrMemory::_initialize() { - stat_calls = 0; - g_pStringContainer = xr_new(); shared_str_initialized = true; g_pSharedMemoryContainer = xr_new(); @@ -182,61 +180,51 @@ void xrMemory::mem_compact() void* xrMemory::mem_alloc(size_t size) { - stat_calls++; return xr_internal_malloc(size); } void* xrMemory::mem_alloc(size_t size, size_t alignment) { - stat_calls++; return xr_internal_malloc_aligned(size, alignment); } void* xrMemory::mem_alloc(size_t size, const std::nothrow_t&) noexcept { - stat_calls++; return xr_internal_malloc_nothrow(size); } void* xrMemory::mem_alloc(size_t size, size_t alignment, const std::nothrow_t&) noexcept { - stat_calls++; return xr_internal_malloc_nothrow_aligned(size, alignment); } void* xrMemory::small_alloc(size_t size) noexcept { - stat_calls++; return xr_internal_small_alloc(size); } void xrMemory::small_free(void* ptr) noexcept { - stat_calls++; xr_internal_small_free(ptr); } void* xrMemory::mem_realloc(void* ptr, size_t size) { - stat_calls++; return xr_internal_realloc(ptr, size); } void* xrMemory::mem_realloc(void* ptr, size_t size, size_t alignment) { - stat_calls++; return xr_internal_realloc_aligned(ptr, size, alignment); } void xrMemory::mem_free(void* ptr) { - stat_calls++; xr_internal_free(ptr); } void xrMemory::mem_free(void* ptr, size_t alignment) { - stat_calls++; xr_internal_free_aligned(ptr, alignment); } diff --git a/src/xrCore/xrMemory.h b/src/xrCore/xrMemory.h index 0d649855a99..c622c0d61dd 100644 --- a/src/xrCore/xrMemory.h +++ b/src/xrCore/xrMemory.h @@ -11,8 +11,6 @@ class XRCORE_API xrMemory void _initialize(); void _destroy(); - u32 stat_calls; - public: size_t mem_usage(); void mem_compact(); diff --git a/src/xrEngine/Stats.cpp b/src/xrEngine/Stats.cpp index 5fde2fb3c16..5eefd0d54c9 100644 --- a/src/xrEngine/Stats.cpp +++ b/src/xrEngine/Stats.cpp @@ -31,7 +31,6 @@ CStats::CStats() { statsFont = nullptr; fpsFont = nullptr; - fMem_calls = 0; Device.seqRender.Add(this, REG_PRIORITY_LOW - 1000); } @@ -91,12 +90,6 @@ void CStats::Show() gTestTimer2.FrameEnd(); gTestTimer3.FrameEnd(); - float memCalls = float(Memory.stat_calls); - if (memCalls > fMem_calls) - fMem_calls = memCalls; - else - fMem_calls = 0.9f * fMem_calls + 0.1f * memCalls; - Memory.stat_calls = 0; if (GEnv.isDedicatedServer) return; auto& font = *statsFont; @@ -113,7 +106,6 @@ void CStats::Show() font.OutNext("Mapped: %d", g_file_mapped_memory); #endif Device.DumpStatistics(font, alertPtr); - font.OutNext("Memory: %2.2f", fMem_calls); if (g_pGameLevel) g_pGameLevel->DumpStatistics(font, alertPtr); Engine.Sheduler.DumpStatistics(font, alertPtr); diff --git a/src/xrEngine/Stats.h b/src/xrEngine/Stats.h index 6f5597315c7..2fcfa7d473f 100644 --- a/src/xrEngine/Stats.h +++ b/src/xrEngine/Stats.h @@ -18,7 +18,6 @@ class ENGINE_API CStats : public pureRender CGameFont* statsFont; CGameFont* fpsFont; xr_unique_ptr fpsGraph; - float fMem_calls; xr_vector errors; public: From 68a356198100bbd537ad10565d80332734c08a12 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 07:17:34 +0500 Subject: [PATCH 319/497] xrCore/xrMemory.cpp: add tracy memory profiling stubs --- src/xrCore/xrMemory.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/xrCore/xrMemory.cpp b/src/xrCore/xrMemory.cpp index e734443a287..e551ea07888 100644 --- a/src/xrCore/xrMemory.cpp +++ b/src/xrCore/xrMemory.cpp @@ -180,51 +180,70 @@ void xrMemory::mem_compact() void* xrMemory::mem_alloc(size_t size) { - return xr_internal_malloc(size); + const auto result = xr_internal_malloc(size); + //TracyAlloc(result, size); + return result; } void* xrMemory::mem_alloc(size_t size, size_t alignment) { - return xr_internal_malloc_aligned(size, alignment); + const auto result = xr_internal_malloc_aligned(size, alignment); + //TracyAlloc(result, size); + return result; } void* xrMemory::mem_alloc(size_t size, const std::nothrow_t&) noexcept { - return xr_internal_malloc_nothrow(size); + const auto result = xr_internal_malloc_nothrow(size); + //TracyAlloc(result, size); + return result; } void* xrMemory::mem_alloc(size_t size, size_t alignment, const std::nothrow_t&) noexcept { - return xr_internal_malloc_nothrow_aligned(size, alignment); + const auto result = xr_internal_malloc_nothrow_aligned(size, alignment); + //TracyAlloc(result, size); + return result; } void* xrMemory::small_alloc(size_t size) noexcept { - return xr_internal_small_alloc(size); + const auto result = xr_internal_small_alloc(size); + //TracyAllocN(result, size, "small alloc"); + return result; } void xrMemory::small_free(void* ptr) noexcept { + //TracyFree(ptr); xr_internal_small_free(ptr); } void* xrMemory::mem_realloc(void* ptr, size_t size) { - return xr_internal_realloc(ptr, size); + //TracyFree(ptr); + const auto result = xr_internal_realloc(ptr, size); + //TracyAllocN(result, size, "realloc"); + return result; } void* xrMemory::mem_realloc(void* ptr, size_t size, size_t alignment) { - return xr_internal_realloc_aligned(ptr, size, alignment); + //TracyFree(ptr); + const auto result = xr_internal_realloc_aligned(ptr, size, alignment); + //TracyAllocN(result, size, "realloc"); + return result; } void xrMemory::mem_free(void* ptr) { + //TracyFree(ptr); xr_internal_free(ptr); } void xrMemory::mem_free(void* ptr, size_t alignment) { + //TracyFree(ptr); xr_internal_free_aligned(ptr, alignment); } From fa6637af291ca60898a21ede082c685b9ee176c1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 07:31:43 +0500 Subject: [PATCH 320/497] xrScriptEngine/script_engine.cpp: support tracy usage in Lua --- src/xrScriptEngine/script_engine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xrScriptEngine/script_engine.cpp b/src/xrScriptEngine/script_engine.cpp index 0f859179cf1..cd25e2c69a6 100644 --- a/src/xrScriptEngine/script_engine.cpp +++ b/src/xrScriptEngine/script_engine.cpp @@ -21,6 +21,8 @@ #include "xrLuaFix/xrLuaFix.h" #include "luabind/class_info.hpp" +#include + Flags32 g_LuaDebug; #define SCRIPT_GLOBAL_NAMESPACE "_G" @@ -985,6 +987,8 @@ void CScriptEngine::init(ExporterFunc exporterFunc, bool loadGlobalNamespace) luaopen_xrluafix(lua()); + tracy::LuaRegister(lua()); + // Game scripts doesn't call randomize but use random // So, we should randomize in the engine. { From 340db995b3b7d8371c4edd08e1930590ef6d6634 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 07:36:35 +0500 Subject: [PATCH 321/497] xrEngine/Device_Initialize.cpp: set program name in tracy --- src/xrEngine/Device_Initialize.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index 7881e09c877..f41d0b3c614 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -76,6 +76,8 @@ void CRenderDevice::Initialize() SDL_SetWindowMinimumSize(m_sdlWnd, 256, 192); xrDebug::SetWindowHandler(this); ExtractAndSetWindowIcon(m_sdlWnd, icon); + + TracySetProgramName(title); } #ifdef IMGUI_ENABLE_VIEWPORTS From 94872a9eab40e8fcb198850612a6abca19ce318c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 08:47:11 +0500 Subject: [PATCH 322/497] Added many tracy scoped zones --- src/Layers/xrRender/D3DXRenderBase.cpp | 1 + src/Layers/xrRender/DetailManager.cpp | 11 +++ src/Layers/xrRender/DetailManager_CACHE.cpp | 2 + src/Layers/xrRender/HOM.cpp | 6 ++ src/Layers/xrRender/LightTrack.cpp | 2 + .../Light_Render_Direct_ComputeXFS.cpp | 2 + src/Layers/xrRender/ParticleEffect.cpp | 12 ++- src/Layers/xrRender/ResourceManager.cpp | 4 + src/Layers/xrRender/SkeletonAnimated.cpp | 3 + src/Layers/xrRender/SkeletonCustom.cpp | 8 ++ src/Layers/xrRender/SkeletonRigid.cpp | 12 +++ src/Layers/xrRender/TextureDescrManager.cpp | 8 ++ src/Layers/xrRender/light.cpp | 1 + src/Layers/xrRender/light_gi.cpp | 2 + src/Layers/xrRender/occRasterizer.cpp | 2 + src/Layers/xrRender/occRasterizer_core.cpp | 2 + src/Layers/xrRender/r__dsgraph_build.cpp | 14 +++ src/Layers/xrRender/r__sector_traversal.cpp | 2 + src/Layers/xrRender_R2/r2.cpp | 4 + src/Layers/xrRender_R2/r2_loader.cpp | 22 +++++ src/Layers/xrRender_R2/r3_R_rain.cpp | 2 + src/Layers/xrRender_R2/render_phase_sun.cpp | 2 + src/xrAICore/AISpaceBase.cpp | 2 + .../PatrolPath/patrol_path_storage.cpp | 4 + src/xrCDB/ISpatial.cpp | 4 + src/xrCDB/ISpatial_q_box.cpp | 2 + src/xrCDB/ISpatial_q_frustum.cpp | 1 + src/xrCDB/ISpatial_q_ray.cpp | 1 + src/xrCDB/xrCDB.cpp | 8 ++ src/xrCDB/xrCDB_Collector.cpp | 1 + src/xrCDB/xrCDB_box.cpp | 1 + src/xrCDB/xrCDB_frustum.cpp | 1 + src/xrCDB/xrCDB_ray.cpp | 1 + src/xrCDB/xr_area.cpp | 6 ++ src/xrCDB/xr_area_query.cpp | 2 + src/xrCDB/xr_area_raypick.cpp | 8 ++ src/xrCore/Containers/FixedMap.h | 22 +++++ src/xrCore/LocatorAPI.cpp | 17 ++++ src/xrCore/Threading/TaskManager.cpp | 6 ++ src/xrCore/_compressed_normal.cpp | 2 + src/xrCore/_math.cpp | 2 + src/xrCore/log.cpp | 2 + src/xrCore/xrCore.cpp | 2 + src/xrCore/xrDebug.cpp | 1 + src/xrCore/xrMemory.cpp | 2 + src/xrCore/xr_ini.cpp | 4 + src/xrEngine/Device_Initialize.cpp | 1 + src/xrEngine/Device_create.cpp | 1 + src/xrEngine/Device_destroy.cpp | 4 + src/xrEngine/Device_imgui.cpp | 4 + src/xrEngine/Device_mode.cpp | 6 ++ src/xrEngine/Engine.cpp | 3 + src/xrEngine/EngineAPI.cpp | 2 + src/xrEngine/Environment.cpp | 2 + src/xrEngine/Environment_misc.cpp | 25 ++++++ src/xrEngine/EventAPI.cpp | 2 + src/xrEngine/IGame_Level.cpp | 25 +++--- src/xrEngine/IGame_Persistent.cpp | 35 ++++++++ src/xrEngine/LightAnimLibrary.cpp | 6 ++ src/xrEngine/PS_instance.cpp | 2 + src/xrEngine/Rain.cpp | 6 ++ src/xrEngine/XR_IOConsole.cpp | 8 ++ src/xrEngine/cf_dynamic_mesh.cpp | 2 + src/xrEngine/device.cpp | 31 +++++-- src/xrEngine/editor_base.cpp | 2 + src/xrEngine/embedded_resources_management.h | 10 +++ src/xrEngine/thunderbolt.cpp | 6 ++ src/xrEngine/tntQAVI.cpp | 2 + src/xrEngine/x_ray.cpp | 85 +++++++++++++------ src/xrEngine/xrSheduler.cpp | 4 + src/xrEngine/xrTheora_Stream.cpp | 2 + src/xrEngine/xrTheora_Surface.cpp | 2 + src/xrEngine/xr_collide_form.cpp | 6 ++ src/xrEngine/xr_efflensflare.cpp | 2 + src/xrEngine/xr_input.cpp | 12 +++ src/xrEngine/xr_object_list.cpp | 4 + src/xrGame/GamePersistent.cpp | 12 +++ src/xrGame/HUDManager.cpp | 19 +++++ src/xrGame/HudSound.cpp | 14 +++ src/xrGame/Level.cpp | 24 +++++- src/xrGame/Level_Bullet_Manager.cpp | 8 ++ src/xrGame/Level_load.cpp | 11 +++ src/xrGame/Level_network.cpp | 2 + .../Level_network_compressed_updates.cpp | 2 + src/xrGame/Level_network_map_sync.cpp | 6 ++ src/xrGame/Level_network_messages.cpp | 2 + src/xrGame/Level_network_spawn.cpp | 8 ++ src/xrGame/Level_network_start_client.cpp | 13 +++ src/xrGame/Level_start.cpp | 14 +++ src/xrGame/MainMenu.cpp | 8 ++ src/xrGame/PHCommander.cpp | 2 + src/xrGame/UIDialogHolder.cpp | 4 + src/xrGame/UIGameCustom.cpp | 3 + src/xrGame/UIZoneMap.cpp | 2 + src/xrGame/ai_space.cpp | 17 ++++ src/xrGame/debug_renderer_inline.h | 2 +- src/xrGame/level_debug.cpp | 2 + src/xrGame/level_sounds.cpp | 4 + src/xrGame/ui/UIGameTutorial.cpp | 4 + src/xrGame/ui/UIHudStatesWnd.cpp | 2 + src/xrGame/ui/UIMainIngameWnd.cpp | 10 +++ src/xrGame/xrServer.cpp | 7 ++ src/xrGame/xrServer_perform_GameExport.cpp | 2 + src/xrGame/xrServer_process_spawn.cpp | 2 + src/xrGame/xrgame_dll_detach.cpp | 4 + src/xrMaterialSystem/GameMtlLib.cpp | 2 + src/xrNetServer/NET_Client.cpp | 2 + src/xrNetServer/NET_Server.cpp | 4 + .../particle_actions_collection.cpp | 11 +-- src/xrParticles/particle_manager.cpp | 2 + src/xrPhysics/PHWorld.cpp | 7 ++ src/xrScriptEngine/BindingsDumper.cpp | 1 + src/xrScriptEngine/ScriptExporter.cpp | 5 ++ src/xrScriptEngine/script_engine.cpp | 3 + src/xrServerEntities/object_factory_inline.h | 2 + .../object_factory_register.cpp | 2 + .../object_factory_script.cpp | 6 ++ src/xrSound/Sound.cpp | 6 ++ src/xrSound/SoundRender_CoreA.cpp | 2 + src/xrSound/SoundRender_Core_Processor.cpp | 4 + src/xrSound/SoundRender_Emitter.cpp | 2 + src/xrSound/SoundRender_Emitter_FSM.cpp | 2 + src/xrSound/SoundRender_Scene.cpp | 14 +++ src/xrSound/SoundRender_Source.cpp | 3 + src/xrUICore/ui_base.cpp | 7 +- 125 files changed, 765 insertions(+), 60 deletions(-) diff --git a/src/Layers/xrRender/D3DXRenderBase.cpp b/src/Layers/xrRender/D3DXRenderBase.cpp index 574840706dc..8a52497f8c9 100644 --- a/src/Layers/xrRender/D3DXRenderBase.cpp +++ b/src/Layers/xrRender/D3DXRenderBase.cpp @@ -339,6 +339,7 @@ bool D3DXRenderBase::HWSupportsShaderYUV2RGB() void D3DXRenderBase::OnAssetsChanged() { + ZoneScoped; Resources->m_textures_description.UnLoad(); Resources->m_textures_description.Load(); } diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index cb18a982c49..53a3a3ddc39 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -82,6 +82,8 @@ void CDetailManager::SSwingValue::lerp(const SSwingValue& A, const SSwingValue& // XXX stats: add to statistics CDetailManager::CDetailManager() : xrc("detail manager") { + ZoneScoped; + dtFS = nullptr; dtSlots = nullptr; soft_Geom = nullptr; @@ -124,6 +126,8 @@ CDetailManager::CDetailManager() : xrc("detail manager") CDetailManager::~CDetailManager() { + ZoneScoped; + for (u32 i = 0; i < dm_cache_size; ++i) cache_pool[i].~Slot(); xr_free(cache_pool); @@ -154,6 +158,8 @@ void dump(CDetailManager::vis_list& lst) */ void CDetailManager::Load() { + ZoneScoped; + // Open file stream if (!FS.exist("$level$", "level.details")) { @@ -219,6 +225,7 @@ void CDetailManager::Load() #endif void CDetailManager::Unload() { + ZoneScoped; if (UseVS()) hw_Unload(); else @@ -241,6 +248,8 @@ extern ECORE_API float r_ssaDISCARD; void CDetailManager::UpdateVisibleM() { + ZoneScoped; + for (int i = 0; i != 3; ++i) for (auto& vis : m_visibles[i]) vis.clear(); @@ -430,6 +439,8 @@ void CDetailManager::MT_CALC() return; #endif + ZoneScoped; + EYE = Device.vCameraPosition; MT.Enter(); diff --git a/src/Layers/xrRender/DetailManager_CACHE.cpp b/src/Layers/xrRender/DetailManager_CACHE.cpp index 10b831b7217..7902b6bb848 100644 --- a/src/Layers/xrRender/DetailManager_CACHE.cpp +++ b/src/Layers/xrRender/DetailManager_CACHE.cpp @@ -98,6 +98,8 @@ BOOL CDetailManager::cache_Validate() void CDetailManager::cache_Update(int v_x, int v_z, Fvector& view, int limit) { + ZoneScoped; + bool bNeedMegaUpdate = (cache_cx != v_x) || (cache_cz != v_z); // ***** Cache shift while (cache_cx != v_x) diff --git a/src/Layers/xrRender/HOM.cpp b/src/Layers/xrRender/HOM.cpp index 3319e1884a8..929f2d7cb89 100644 --- a/src/Layers/xrRender/HOM.cpp +++ b/src/Layers/xrRender/HOM.cpp @@ -57,6 +57,8 @@ void CHOM::Load() if (strstr(Core.Params, "-no_hom") ) return; + ZoneScoped; + // Find and open file string_path fName; FS.update_path(fName, "$level$", "level.hom"); @@ -145,6 +147,7 @@ void CHOM::Load() void CHOM::Unload() { + ZoneScoped; xr_delete(m_pModel); xr_free(m_pTris); bEnabled = FALSE; @@ -152,6 +155,8 @@ void CHOM::Unload() void CHOM::Render_DB(CFrustum& base) { + ZoneScoped; + // Update projection matrices on every frame to ensure valid HOM culling float view_dim = occ_dim_0; #if defined(USE_DX11) @@ -253,6 +258,7 @@ void CHOM::Render(CFrustum& base) if (!bEnabled) return; + ZoneScoped; stats.Total.Begin(); Raster.clear(); Render_DB(base); diff --git a/src/Layers/xrRender/LightTrack.cpp b/src/Layers/xrRender/LightTrack.cpp index ba691e9e4d6..7e18b3005ab 100644 --- a/src/Layers/xrRender/LightTrack.cpp +++ b/src/Layers/xrRender/LightTrack.cpp @@ -159,6 +159,8 @@ inline void CROS_impl::accum_hemi(float* hemi_cube, Fvector3& dir, float scale) ////////////////////////////////////////////////////////////////////////// void CROS_impl::update(IRenderable* O) { + ZoneScoped; + // clip & verify if (dwFrame == Device.dwFrame) return; diff --git a/src/Layers/xrRender/Light_Render_Direct_ComputeXFS.cpp b/src/Layers/xrRender/Light_Render_Direct_ComputeXFS.cpp index 3673d27970b..14192e84353 100644 --- a/src/Layers/xrRender/Light_Render_Direct_ComputeXFS.cpp +++ b/src/Layers/xrRender/Light_Render_Direct_ComputeXFS.cpp @@ -3,6 +3,8 @@ void CLight_Compute_XFORM_and_VIS::compute_xf_spot(light* L) { + ZoneScoped; + // Build EYE-space xform Fvector L_dir, L_up, L_right, L_pos; L_dir.set(L->direction); diff --git a/src/Layers/xrRender/ParticleEffect.cpp b/src/Layers/xrRender/ParticleEffect.cpp index 036bb18a2e1..6a5995042ae 100644 --- a/src/Layers/xrRender/ParticleEffect.cpp +++ b/src/Layers/xrRender/ParticleEffect.cpp @@ -137,6 +137,8 @@ void CParticleEffect::UpdateParent(const Fmatrix& m, const Fvector& velocity, BO void CParticleEffect::OnFrame(u32 frame_dt) { + ZoneScoped; + if (m_Def && m_RT_Flags.is(flRT_Playing)) { m_MemDT += frame_dt; @@ -272,6 +274,8 @@ void CParticleEffect::OnDeviceDestroy() IC void FillSprite_fpu(FVF::LIT*& pv, const Fvector& T, const Fvector& R, const Fvector& pos, const Fvector2& lt, const Fvector2& rb, float r1, float r2, u32 clr, float sina, float cosa) { + ZoneScoped; + Fvector Vr, Vt; Vr.x = T.x * r1 * sina + R.x * r1 * cosa; @@ -303,6 +307,8 @@ IC void FillSprite_fpu(FVF::LIT*& pv, const Fvector& T, const Fvector& R, const IC void FillSprite_fpu(FVF::LIT*& pv, const Fvector& pos, const Fvector& dir, const Fvector2& lt, const Fvector2& rb, float r1, float r2, u32 clr, float sina, float cosa) { + ZoneScoped; + const Fvector& T = dir; Fvector R; @@ -344,6 +350,8 @@ Lock m_sprite_section; IC void FillSprite(FVF::LIT*& pv, const Fvector& T, const Fvector& R, const Fvector& pos, const Fvector2& lt, const Fvector2& rb, float r1, float r2, u32 clr, float sina, float cosa) { + ZoneScoped; + m_sprite_section.Enter(); __m128 Vr, Vt, T_, R_, _pos, _zz, _sa, _ca, a, b, c, d; @@ -404,9 +412,7 @@ IC void FillSprite(FVF::LIT*& pv, const Fvector& T, const Fvector& R, const Fvec IC void FillSprite(FVF::LIT*& pv, const Fvector& pos, const Fvector& dir, const Fvector2& lt, const Fvector2& rb, float r1, float r2, u32 clr, float sina, float cosa) { -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("FillSpriteTransform()"); -#endif // _GPA_ENABLED + ZoneScoped; const Fvector& T = dir; Fvector R; diff --git a/src/Layers/xrRender/ResourceManager.cpp b/src/Layers/xrRender/ResourceManager.cpp index b03cc4939f3..f4f08abafc0 100644 --- a/src/Layers/xrRender/ResourceManager.cpp +++ b/src/Layers/xrRender/ResourceManager.cpp @@ -364,6 +364,8 @@ void CResourceManager::DeferredUpload() if (!Device.b_is_Ready) return; + ZoneScoped; + #if defined(USE_DX11) xr_parallel_for_each(m_textures, [&](auto m_tex) { m_tex.second->Load(); }); #elif defined(USE_OGL) // XXX: OGL: Set additional contexts for all worker threads? @@ -379,6 +381,8 @@ void CResourceManager::DeferredUnload() if (!Device.b_is_Ready) return; + ZoneScoped; + #if defined(USE_DX11) xr_parallel_for_each(m_textures, [&](auto m_tex) { m_tex.second->Unload(); }); #elif defined(USE_OGL) // XXX: OGL: Set additional contexts for all worker threads? diff --git a/src/Layers/xrRender/SkeletonAnimated.cpp b/src/Layers/xrRender/SkeletonAnimated.cpp index 9adc61f7256..7a3ad92b001 100644 --- a/src/Layers/xrRender/SkeletonAnimated.cpp +++ b/src/Layers/xrRender/SkeletonAnimated.cpp @@ -599,6 +599,9 @@ void CKinematicsAnimated::UpdateTracks() _DBG_SINGLE_USE_MARKER; if (Update_LastTime == Device.dwTimeGlobal) return; + + ZoneScoped; + u32 DT = Device.dwTimeGlobal - Update_LastTime; if (DT > 66) DT = 66; diff --git a/src/Layers/xrRender/SkeletonCustom.cpp b/src/Layers/xrRender/SkeletonCustom.cpp index 59492892ab8..c33af6aa5bf 100644 --- a/src/Layers/xrRender/SkeletonCustom.cpp +++ b/src/Layers/xrRender/SkeletonCustom.cpp @@ -535,6 +535,8 @@ void CKinematics::LL_SetBonesVisible(u64 mask) void CKinematics::Visibility_Update() { + ZoneScoped; + Update_Visibility = FALSE; // check visible for (u32 c_it = 0; c_it < children.size(); c_it++) @@ -629,6 +631,8 @@ bool CKinematics::PickBone(const Fmatrix& parent_xform, IKinematics::pick_result void CKinematics::AddWallmark( const Fmatrix* parent_xform, const Fvector3& start, const Fvector3& dir, ref_shader shader, float size) { + ZoneScoped; + Fvector S, D, normal = {0, 0, 0}; // transform ray from world to model Fmatrix P; @@ -730,6 +734,8 @@ void CKinematics::AddWallmark( void CKinematics::CalculateWallmarks(bool hud) { + ZoneScoped; + if (!wallmarks.empty() && (wm_frame != Device.dwFrame)) { wm_frame = Device.dwFrame; @@ -763,6 +769,8 @@ void CKinematics::CalculateWallmarks(bool hud) void CKinematics::RenderWallmark(intrusive_ptr wm, FVF::LIT*& V) { + ZoneScoped; + VERIFY(wm); VERIFY(V); VERIFY2(bones, "Invalid visual. Bones already released."); diff --git a/src/Layers/xrRender/SkeletonRigid.cpp b/src/Layers/xrRender/SkeletonRigid.cpp index b04c093742c..35d6e38912d 100644 --- a/src/Layers/xrRender/SkeletonRigid.cpp +++ b/src/Layers/xrRender/SkeletonRigid.cpp @@ -12,6 +12,8 @@ void check_kinematics(CKinematics* _k, LPCSTR s); void CKinematics::CalculateBones(BOOL bForceExact) { + ZoneScoped; + // early out. // check if the info is still relevant // skip all the computations - assume nothing changes in a small period of time :) @@ -46,6 +48,8 @@ void CKinematics::CalculateBones(BOOL bForceExact) UCalc_Visibox++; if (UCalc_Visibox >= psSkeletonUpdate) { + ZoneScopedN("Skeleton update"); + // mark UCalc_Visibox = -(::Random.randI(psSkeletonUpdate - 1)); @@ -195,6 +199,8 @@ void CKinematics::CalculateBonesAdditionalTransforms( void CKinematics::CLBone(const CBoneData* bd, CBoneInstance& bi, const Fmatrix* parent, u8 channel_mask /*= (1<<0)*/) { + ZoneScoped; + u16 SelfID = bd->GetSelfID(); if (LL_GetBoneVisible(SelfID)) @@ -224,6 +230,8 @@ void CKinematics::CLBone(const CBoneData* bd, CBoneInstance& bi, const Fmatrix* void CKinematics::Bone_GetAnimPos(Fmatrix& pos, u16 id, u8 mask_channel, bool ignore_callbacks) { + ZoneScoped; + R_ASSERT(id < LL_BoneCount()); CBoneInstance bi = LL_GetBoneInstance(id); BoneChain_Calculate(&LL_GetData(id), bi, mask_channel, ignore_callbacks); @@ -235,6 +243,8 @@ void CKinematics::Bone_GetAnimPos(Fmatrix& pos, u16 id, u8 mask_channel, bool ig void CKinematics::Bone_Calculate(CBoneData* bd, Fmatrix* parent) { + ZoneScoped; + u16 SelfID = bd->GetSelfID(); CBoneInstance& BONE_INST = LL_GetBoneInstance(SelfID); CLBone(bd, BONE_INST, parent, u8(-1)); @@ -245,6 +255,8 @@ void CKinematics::Bone_Calculate(CBoneData* bd, Fmatrix* parent) void CKinematics::BoneChain_Calculate(const CBoneData* bd, CBoneInstance& bi, u8 mask_channel, bool ignore_callbacks) { + ZoneScoped; + u16 SelfID = bd->GetSelfID(); // CBlendInstance& BLEND_INST = LL_GetBlendInstance(SelfID); // CBlendInstance::BlendSVec &Blend = BLEND_INST.blend_vector(); diff --git a/src/Layers/xrRender/TextureDescrManager.cpp b/src/Layers/xrRender/TextureDescrManager.cpp index af96de9fac8..3831b644642 100644 --- a/src/Layers/xrRender/TextureDescrManager.cpp +++ b/src/Layers/xrRender/TextureDescrManager.cpp @@ -28,6 +28,8 @@ void fix_texture_thm_name(pstr fn) void CTextureDescrMngr::LoadLTX(pcstr initial, bool listTHM) { + ZoneScoped; + string_path fname; FS.update_path(fname, initial, "textures.ltx"); @@ -124,6 +126,8 @@ void CTextureDescrMngr::LoadLTX(pcstr initial, bool listTHM) void CTextureDescrMngr::LoadTHM(LPCSTR initial, bool listTHM) { + ZoneScoped; + FS_FileSet flist; FS.file_list(flist, initial, FS_ListFiles, "*.thm"); @@ -216,6 +220,7 @@ void CTextureDescrMngr::LoadTHM(LPCSTR initial, bool listTHM) void CTextureDescrMngr::Load() { + ZoneScoped; #ifndef MASTER_GOLD CTimer timer; timer.Start(); @@ -236,6 +241,7 @@ void CTextureDescrMngr::Load() void CTextureDescrMngr::UnLoad() { + ZoneScoped; for (auto& it : m_texture_details) { xr_delete(it.second.m_assoc); @@ -246,6 +252,8 @@ void CTextureDescrMngr::UnLoad() CTextureDescrMngr::~CTextureDescrMngr() { + ZoneScoped; + for (auto& it : m_detail_scalers) xr_delete(it.second); diff --git a/src/Layers/xrRender/light.cpp b/src/Layers/xrRender/light.cpp index dd82bd03e46..ebf01da9d4f 100644 --- a/src/Layers/xrRender/light.cpp +++ b/src/Layers/xrRender/light.cpp @@ -232,6 +232,7 @@ Fvector light::spatial_sector_point() { return position; } // Xforms void light::xform_calc() { + ZoneScoped; if (Device.dwFrame == m_xform_frame) return; m_xform_frame = Device.dwFrame; diff --git a/src/Layers/xrRender/light_gi.cpp b/src/Layers/xrRender/light_gi.cpp index c4f53a88ab8..db44ba5b421 100644 --- a/src/Layers/xrRender/light_gi.cpp +++ b/src/Layers/xrRender/light_gi.cpp @@ -3,6 +3,8 @@ void light::gi_generate() { + ZoneScoped; + indirect.clear(); indirect_photons = ps_r2_ls_flags.test(R2FLAG_GI) ? ps_r2_GI_photons : 0; diff --git a/src/Layers/xrRender/occRasterizer.cpp b/src/Layers/xrRender/occRasterizer.cpp index 5d9c6e2ba62..0427e7dfe65 100644 --- a/src/Layers/xrRender/occRasterizer.cpp +++ b/src/Layers/xrRender/occRasterizer.cpp @@ -68,6 +68,8 @@ BOOL shared(occTri* T1, occTri* T2); void occRasterizer::propagade() { + ZoneScoped; + // Clip-and-propagade zero level occTri** pFrame = get_frame(); float* pDepth = get_depth(); diff --git a/src/Layers/xrRender/occRasterizer_core.cpp b/src/Layers/xrRender/occRasterizer_core.cpp index e1dd8d22d00..106a2fa9cf3 100644 --- a/src/Layers/xrRender/occRasterizer_core.cpp +++ b/src/Layers/xrRender/occRasterizer_core.cpp @@ -409,6 +409,8 @@ void __stdcall i_section_t0() { i_section(TOP, 0); } void __stdcall i_section_t1() { i_section(TOP, 1); } u32 occRasterizer::rasterize(occTri* T) { + ZoneScoped; + // Order the vertices by Y currentTri = T; dwPixels = 0; diff --git a/src/Layers/xrRender/r__dsgraph_build.cpp b/src/Layers/xrRender/r__dsgraph_build.cpp index 06e5b5d5a1e..bc226a5b609 100644 --- a/src/Layers/xrRender/r__dsgraph_build.cpp +++ b/src/Layers/xrRender/r__dsgraph_build.cpp @@ -37,6 +37,8 @@ ICF float CalcSSA(float& distSQ, Fvector& C, float R) void R_dsgraph_structure::insert_dynamic(IRenderable* root, dxRender_Visual* pVisual, Fmatrix& xform, Fvector& Center) { + ZoneScoped; + CRender& RI = RImplementation; if (pVisual->vis.marker[context_id] == marker) @@ -152,6 +154,8 @@ void R_dsgraph_structure::insert_dynamic(IRenderable* root, dxRender_Visual* pVi void R_dsgraph_structure::insert_static(dxRender_Visual* pVisual) { + ZoneScoped; + CRender& RI = RImplementation; if (pVisual->vis.marker[context_id] == marker) @@ -249,6 +253,8 @@ void R_dsgraph_structure::insert_static(dxRender_Visual* pVisual) //////////////////////////////////////////////////////////////////////////////////////////////////// void R_dsgraph_structure::add_leafs_dynamic(IRenderable* root, dxRender_Visual* pVisual, Fmatrix& xform) { + ZoneScoped; + if (nullptr == pVisual) return; @@ -333,6 +339,8 @@ void R_dsgraph_structure::add_leafs_dynamic(IRenderable* root, dxRender_Visual* void R_dsgraph_structure::add_leafs_static(dxRender_Visual* pVisual) { + ZoneScoped; + if (o.use_hom && !RImplementation.HOM.visible(pVisual->vis)) return; @@ -534,6 +542,8 @@ BOOL R_dsgraph_structure::add_Dynamic(dxRender_Visual* pVisual, u32 planes) // n void R_dsgraph_structure::add_static(dxRender_Visual* pVisual, const CFrustum& view, u32 planes) { + ZoneScoped; + vis_data& vis = pVisual->vis; // Check frustum visibility and calculate distance to visual's center @@ -657,6 +667,8 @@ void R_dsgraph_structure::add_static(dxRender_Visual* pVisual, const CFrustum& v void R_dsgraph_structure::load(const xr_vector& sectors_data, const xr_vector& portals_data) { + ZoneScoped; + const auto portals_count = portals_data.size(); const auto sectors_count = sectors_data.size(); @@ -701,6 +713,8 @@ void R_dsgraph_structure::unload() // sub-space rendering - main procedure void R_dsgraph_structure::build_subspace() { + ZoneScoped; + marker++; // !!! critical here if (o.precise_portals && RImplementation.rmPortals) diff --git a/src/Layers/xrRender/r__sector_traversal.cpp b/src/Layers/xrRender/r__sector_traversal.cpp index 1130299f619..6a2f27b5200 100644 --- a/src/Layers/xrRender/r__sector_traversal.cpp +++ b/src/Layers/xrRender/r__sector_traversal.cpp @@ -10,6 +10,8 @@ xr_vector dbg_sectors; void CPortalTraverser::traverse(IRender_Sector* start, CFrustum& F, Fvector& vBase, Fmatrix& mXFORM, u32 options) { + ZoneScoped; + Fmatrix m_viewport_01 = {1.f / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, -1.f / 2.f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.f / 2.f + 0 + 0, 1.f / 2.f + 0 + 0, 0.0f, 1.0f}; diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 57b6e90b30f..36f71cce56a 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -640,6 +640,8 @@ void CRender::reset_end() void CRender::BeforeRender() { + ZoneScoped; + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; @@ -648,6 +650,8 @@ void CRender::BeforeRender() void CRender::OnFrame() { + ZoneScoped; + Models->DeleteQueue(); if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index e9fadbb20f7..29359f5ac16 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -14,6 +14,8 @@ void CRender::level_Load(IReader* fs) { + ZoneScoped; + R_ASSERT(g_pGameLevel); R_ASSERT(!b_loaded); @@ -25,6 +27,7 @@ void CRender::level_Load(IReader* fs) // Shaders g_pGamePersistent->LoadTitle("st_loading_shaders"); { + ZoneScopedN("Load shaders"); chunk = fs->open_chunk(fsL_SHADERS); R_ASSERT2(chunk, "Level doesn't builded correctly."); u32 count = chunk->r_u32(); @@ -105,6 +108,8 @@ void CRender::level_Load(IReader* fs) void CRender::level_Unload() { + ZoneScoped; + if (!g_pGameLevel) return; if (!b_loaded) @@ -188,10 +193,13 @@ void CRender::level_Unload() void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) { + ZoneScoped; + R_ASSERT2(base_fs, "Could not load geometry. File not found."); Resources->Evict(); // Vertex buffers { + ZoneScopedN("Load VBs"); xr_vector& decls = alternative ? xDC : nDC; xr_vector& vbuffers = alternative ? xVB : nVB; @@ -237,6 +245,7 @@ void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) // Index buffers { + ZoneScopedN("Load IBs"); xr_vector& ibuffers = alternative ? xIB : nIB; CStreamReader* fs = base_fs->open_chunk(fsL_IB); @@ -268,6 +277,8 @@ void CRender::LoadVisuals(IReader* fs) u32 index = 0; IReader* chunk = nullptr; + ZoneScoped; + while ((chunk = fs->open_chunk(index)) != 0) { ogf_header H; @@ -284,6 +295,7 @@ void CRender::LoadVisuals(IReader* fs) void CRender::LoadLights(IReader* fs) { + ZoneScoped; // lights Lights.Load(fs); Lights.LoadHemi(); @@ -291,6 +303,8 @@ void CRender::LoadLights(IReader* fs) void CRender::LoadSectors(IReader* fs) { + ZoneScoped; + // allocate memory for portals const u32 size = fs->find_chunk(fsL_PORTALS); R_ASSERT(0 == size % sizeof(CPortal::level_portal_data_t)); @@ -309,6 +323,7 @@ void CRender::LoadSectors(IReader* fs) if (!P) break; + ZoneScopedN("Load sector"); auto& sector_data = sectors_data.emplace_back(); { u32 size = P->find_chunk(fsP_Portals); @@ -344,6 +359,8 @@ void CRender::LoadSectors(IReader* fs) // load portals if (portals_count) { + ZoneScopedN("Load portals"); + bool do_rebuild = true; const bool use_cache = !strstr(Core.Params, "-no_cdb_cache"); const bool checkCrc32 = !strstr(Core.Params, "-skip_cdb_cache_crc32_check"); @@ -374,6 +391,7 @@ void CRender::LoadSectors(IReader* fs) fs->find_chunk(fsL_PORTALS); for (u32 i = 0; i < portals_count; i++) { + ZoneScopedN("Build portal from chunk"); auto &P = portals_data[i]; fs->r(&P, sizeof(P)); @@ -421,6 +439,8 @@ void CRender::LoadSectors(IReader* fs) void CRender::LoadSWIs(CStreamReader* base_fs) { + ZoneScoped; + // allocate memory for portals if (base_fs->find_chunk(fsL_SWIS)) { @@ -452,6 +472,8 @@ void CRender::LoadSWIs(CStreamReader* base_fs) #if defined(USE_DX11) void CRender::Load3DFluid() { + ZoneScoped; + // if (strstr(Core.Params,"-no_volumetric_fog")) if (!o.volumetricfog) return; diff --git a/src/Layers/xrRender_R2/r3_R_rain.cpp b/src/Layers/xrRender_R2/r3_R_rain.cpp index b8d9d6c1235..d3dc0fb2ac3 100644 --- a/src/Layers/xrRender_R2/r3_R_rain.cpp +++ b/src/Layers/xrRender_R2/r3_R_rain.cpp @@ -68,6 +68,8 @@ void render_rain::init() ////////////////////////////////////////////////////////////////////////// void render_rain::calculate() { + ZoneScoped; + // static const float source_offset = 40.f; static const float source_offset = 10000.f; diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index 93c1beaedbb..611aae55ea0 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -61,6 +61,8 @@ void render_sun::init() void render_sun::calculate() { + ZoneScoped; + need_to_render_sunshafts = RImplementation.Target->need_to_render_sunshafts(); last_cascade_chain_mode = m_sun_cascades[R__NUM_SUN_CASCADES - 1].reset_chain; if (need_to_render_sunshafts) diff --git a/src/xrAICore/AISpaceBase.cpp b/src/xrAICore/AISpaceBase.cpp index c40983be80e..38bcbfd39ed 100644 --- a/src/xrAICore/AISpaceBase.cpp +++ b/src/xrAICore/AISpaceBase.cpp @@ -88,6 +88,7 @@ void AISpaceBase::patrol_path_storage_raw(IReader& stream) { if (GEnv.isDedicatedServer) return; + ZoneScoped; xr_delete(m_patrol_path_storage); m_patrol_path_storage = xr_new(); m_patrol_path_storage->load_raw(get_level_graph(), get_cross_table(), get_game_graph(), stream); @@ -97,6 +98,7 @@ void AISpaceBase::patrol_path_storage(IReader& stream) { if (GEnv.isDedicatedServer) return; + ZoneScoped; xr_delete(m_patrol_path_storage); m_patrol_path_storage = xr_new(); m_patrol_path_storage->load(stream); diff --git a/src/xrAICore/Navigation/PatrolPath/patrol_path_storage.cpp b/src/xrAICore/Navigation/PatrolPath/patrol_path_storage.cpp index c1f6e3cec08..48ca11aa511 100644 --- a/src/xrAICore/Navigation/PatrolPath/patrol_path_storage.cpp +++ b/src/xrAICore/Navigation/PatrolPath/patrol_path_storage.cpp @@ -16,6 +16,8 @@ CPatrolPathStorage::~CPatrolPathStorage() { delete_data(m_registry); } void CPatrolPathStorage::load_raw( const CLevelGraph* level_graph, const CGameLevelCrossTable* cross, const CGameGraph* game_graph, IReader& stream) { + ZoneScoped; + IReader* chunk = stream.open_chunk(WAY_PATROLPATH_CHUNK); if (!chunk) @@ -42,6 +44,8 @@ void CPatrolPathStorage::load_raw( void CPatrolPathStorage::load(IReader& stream) { + ZoneScoped; + IReader* chunk = stream.open_chunk(0); const u32 size = chunk->r_u32(); chunk->close(); diff --git a/src/xrCDB/ISpatial.cpp b/src/xrCDB/ISpatial.cpp index edecc987167..65140adf26b 100644 --- a/src/xrCDB/ISpatial.cpp +++ b/src/xrCDB/ISpatial.cpp @@ -96,6 +96,7 @@ void SpatialBase::spatial_unregister() void SpatialBase::spatial_move() { + ZoneScoped; if (spatial.node_ptr) { //*** somehow it was determined that object has been moved @@ -116,6 +117,7 @@ void SpatialBase::spatial_move() void SpatialBase::spatial_updatesector_internal(IRender_Sector::sector_id_t sector_id) { + ZoneScoped; spatial.type &= ~STYPEFLAG_INVALIDSECTOR; if (sector_id != IRender_Sector::INVALID_SECTOR_ID) spatial.sector_id = sector_id; @@ -173,6 +175,8 @@ ISpatial_DB::~ISpatial_DB() void ISpatial_DB::initialize(const Fbox& BB) { + ZoneScoped; + // initialize Fvector bbc, bbd; BB.get_CD(bbc, bbd); diff --git a/src/xrCDB/ISpatial_q_box.cpp b/src/xrCDB/ISpatial_q_box.cpp index 8b19c0bdd26..4ffad4539ca 100644 --- a/src/xrCDB/ISpatial_q_box.cpp +++ b/src/xrCDB/ISpatial_q_box.cpp @@ -74,6 +74,7 @@ class box_walker void ISpatial_DB::q_box(xr_vector& R, u32 _o, u32 _mask, const Fvector& _center, const Fvector& _size) { + ZoneScoped; ScopeLock scope(&cs); Stats.Query.Begin(); q_result = &R; @@ -93,6 +94,7 @@ void ISpatial_DB::q_box(xr_vector& R, u32 _o, u32 _mask, const Fvecto void ISpatial_DB::q_sphere(xr_vector& R, u32 _o, u32 _mask, const Fvector& _center, const float _radius) { + ZoneScoped; Fvector _size = {_radius, _radius, _radius}; q_box(R, _o, _mask, _center, _size); } diff --git a/src/xrCDB/ISpatial_q_frustum.cpp b/src/xrCDB/ISpatial_q_frustum.cpp index 6ef63ff1161..2328da3bc01 100644 --- a/src/xrCDB/ISpatial_q_frustum.cpp +++ b/src/xrCDB/ISpatial_q_frustum.cpp @@ -61,6 +61,7 @@ class walker void ISpatial_DB::q_frustum(xr_vector& R, u32 _o, u32 _mask, const CFrustum& _frustum) { + ZoneScoped; ScopeLock scope(&cs); Stats.Query.Begin(); q_result = &R; diff --git a/src/xrCDB/ISpatial_q_ray.cpp b/src/xrCDB/ISpatial_q_ray.cpp index 98f09b70566..73fbc72994c 100644 --- a/src/xrCDB/ISpatial_q_ray.cpp +++ b/src/xrCDB/ISpatial_q_ray.cpp @@ -351,6 +351,7 @@ void ISpatial_DB::q_ray( { using namespace Spatial; + ZoneScoped; ScopeLock scope(&cs); Stats.Query.Begin(); q_result = &R; diff --git a/src/xrCDB/xrCDB.cpp b/src/xrCDB/xrCDB.cpp index bdbbe3161ae..65f5d4ea563 100644 --- a/src/xrCDB/xrCDB.cpp +++ b/src/xrCDB/xrCDB.cpp @@ -51,6 +51,8 @@ void MODEL::syncronize_impl() const void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, void* bcp) { + ZoneScoped; + R_ASSERT(S_INIT == status); R_ASSERT((Vcnt >= 4) && (Tcnt >= 2)); @@ -84,6 +86,8 @@ void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, vo void MODEL::build_internal(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, void* bcp) { + ZoneScoped; + // verts verts_count = Vcnt; verts = xr_alloc(verts_count); @@ -155,6 +159,8 @@ u32 MODEL::memory() bool MODEL::serialize(pcstr fileName, serialize_callback callback /*= nullptr*/) const { + ZoneScoped; + IWriter* wstream = FS.w_open(fileName); if (!wstream) return false; @@ -184,6 +190,8 @@ bool MODEL::serialize(pcstr fileName, serialize_callback callback /*= nullptr*/) bool MODEL::deserialize(pcstr fileName, bool checkCrc32 /*= true*/, deserialize_callback callback /*= nullptr*/) { + ZoneScoped; + IReader* rstream = FS.r_open(fileName); if (!rstream) return false; diff --git a/src/xrCDB/xrCDB_Collector.cpp b/src/xrCDB/xrCDB_Collector.cpp index 0942370b050..0d83674c681 100644 --- a/src/xrCDB/xrCDB_Collector.cpp +++ b/src/xrCDB/xrCDB_Collector.cpp @@ -87,6 +87,7 @@ struct edge void Collector::calc_adjacency(xr_vector& dest) const { + ZoneScoped; #if 1 const auto edge_count = faces.size() * 3; diff --git a/src/xrCDB/xrCDB_box.cpp b/src/xrCDB/xrCDB_box.cpp index 06cc38744f9..5f85a890b6d 100644 --- a/src/xrCDB/xrCDB_box.cpp +++ b/src/xrCDB/xrCDB_box.cpp @@ -297,6 +297,7 @@ class box_collider void COLLIDER::box_query(u32 box_mode, const MODEL* m_def, const Fvector& b_center, const Fvector& b_dim) { + ZoneScoped; m_def->syncronize(); // Get nodes diff --git a/src/xrCDB/xrCDB_frustum.cpp b/src/xrCDB/xrCDB_frustum.cpp index ff1cbff9f1e..8116ce3864f 100644 --- a/src/xrCDB/xrCDB_frustum.cpp +++ b/src/xrCDB/xrCDB_frustum.cpp @@ -91,6 +91,7 @@ class frustum_collider void COLLIDER::frustum_query(u32 frustum_mode, const MODEL* m_def, const CFrustum& F) { + ZoneScoped; m_def->syncronize(); // Get nodes diff --git a/src/xrCDB/xrCDB_ray.cpp b/src/xrCDB/xrCDB_ray.cpp index 51e20d10ce9..efa6c8e86ab 100644 --- a/src/xrCDB/xrCDB_ray.cpp +++ b/src/xrCDB/xrCDB_ray.cpp @@ -435,6 +435,7 @@ class alignas(16) ray_collider void COLLIDER::ray_query(u32 ray_mode, const MODEL* m_def, const Fvector& r_start, const Fvector& r_dir, float r_range) { + ZoneScoped; m_def->syncronize(); // Get nodes diff --git a/src/xrCDB/xr_area.cpp b/src/xrCDB/xr_area.cpp index cfff6b93d34..e24faca0d8d 100644 --- a/src/xrCDB/xr_area.cpp +++ b/src/xrCDB/xr_area.cpp @@ -42,6 +42,8 @@ CObjectSpace::~CObjectSpace() int CObjectSpace::GetNearest(xr_vector& q_spatial, xr_vector& q_nearest, const Fvector& point, float range, IGameObject* ignore_object) { + ZoneScoped; + q_spatial.clear(); // Query objects q_nearest.clear(); @@ -105,6 +107,8 @@ void CObjectSpace::Load(IReader* F, CDB::serialize_callback serialize_callback, CDB::deserialize_callback deserialize_callback) { + ZoneScoped; + hdrCFORM H; F->r(&H, sizeof(hdrCFORM)); Fvector* verts = (Fvector*)F->pointer(); @@ -119,6 +123,8 @@ void CObjectSpace::Create(Fvector* verts, CDB::TRI* tris, const hdrCFORM& H, CDB::serialize_callback serialize_callback, CDB::deserialize_callback deserialize_callback) { + ZoneScoped; + R_ASSERT(CFORM_CURRENT_VERSION == H.version); string_path fName; diff --git a/src/xrCDB/xr_area_query.cpp b/src/xrCDB/xr_area_query.cpp index ec9a86b428a..011f91baf5e 100644 --- a/src/xrCDB/xr_area_query.cpp +++ b/src/xrCDB/xr_area_query.cpp @@ -9,6 +9,8 @@ using namespace collide; bool CObjectSpace::BoxQuery(Fvector const& box_center, Fvector const& box_z_axis, Fvector const& box_y_axis, Fvector const& box_sizes, xr_vector* out_tris) { + ZoneScoped; + Fvector z_axis = box_z_axis; z_axis.normalize(); Fvector y_axis = box_y_axis; diff --git a/src/xrCDB/xr_area_raypick.cpp b/src/xrCDB/xr_area_raypick.cpp index 8a08fe0de4f..65b957074e0 100644 --- a/src/xrCDB/xr_area_raypick.cpp +++ b/src/xrCDB/xr_area_raypick.cpp @@ -25,6 +25,8 @@ bool CObjectSpace::RayTest(const Fvector& start, const Fvector& dir, float range bool CObjectSpace::_RayTest(const Fvector& start, const Fvector& dir, float range, collide::rq_target tgt, collide::ray_cache* cache, IGameObject* ignore_object) { + ZoneScoped; + VERIFY(_abs(dir.magnitude() - 1) < EPS); r_temp.r_clear(); @@ -107,6 +109,8 @@ bool CObjectSpace::_RayTest(const Fvector& start, const Fvector& dir, float rang bool CObjectSpace::RayPick( const Fvector& start, const Fvector& dir, float range, rq_target tgt, rq_result& R, IGameObject* ignore_object) { + ZoneScoped; + bool _res = _RayPick(start, dir, range, tgt, R, ignore_object); r_spatial.clear(); return _res; @@ -177,6 +181,8 @@ bool CObjectSpace::_RayPick( bool CObjectSpace::RayQuery(collide::rq_results& dest, const collide::ray_defs& R, collide::rq_callback* CB, LPVOID user_data, collide::test_callback* tb, IGameObject* ignore_object) { + ZoneScoped; + bool _res = _RayQuery2(dest, R, CB, user_data, tb, ignore_object); r_spatial.clear(); return (_res); @@ -481,6 +487,8 @@ bool CObjectSpace::_RayQuery(collide::rq_results& r_dest, const collide::ray_def bool CObjectSpace::RayQuery(collide::rq_results& r_dest, ICollisionForm* target, const collide::ray_defs& R) { + ZoneScoped; + VERIFY(target); r_dest.r_clear(); return target->_RayQuery(R, r_dest); diff --git a/src/xrCore/Containers/FixedMap.h b/src/xrCore/Containers/FixedMap.h index 1cfee30f844..1ba6f72193d 100644 --- a/src/xrCore/Containers/FixedMap.h +++ b/src/xrCore/Containers/FixedMap.h @@ -77,6 +77,8 @@ class xr_fixed_map void resize() { + ZoneScoped; + size_t newLimit; if constexpr (TGrowMultiplier > 1) @@ -238,6 +240,8 @@ class xr_fixed_map value_type* insert(const K& key) { + ZoneScoped; + if (!pool) return add(key); @@ -278,6 +282,8 @@ class xr_fixed_map value_type* insert_anyway(const K& key) { + ZoneScoped; + if (!pool) return add(key); @@ -363,18 +369,24 @@ class xr_fixed_map void traverse_left_right(u32 id, callback CB) { + ZoneScoped; + if (pool) recurse_left_right(id, nodes, CB); } void traverse_right_left(u32 id, callback CB) { + ZoneScoped; + if (pool) recurse_right_left(id, nodes, CB); } void traverse_any(callback CB) { + ZoneScoped; + value_type* _end = end(); for (value_type* cur = begin(); cur != _end; ++cur) CB(*cur); @@ -382,30 +394,40 @@ class xr_fixed_map void get_left_right(xr_vector>& D) { + ZoneScoped; + if (pool) get_left_right(nodes, D); } void get_left_right_p(xr_vector>& D) { + ZoneScoped; + if (pool) get_left_right_p(nodes, D); } void get_right_left(xr_vector>& D) { + ZoneScoped; + if (pool) get_right_left(nodes, D); } void get_right_left_p(xr_vector>& D) { + ZoneScoped; + if (pool) get_right_left_p(nodes, D); } void get_any_p(xr_vector>& D) { + ZoneScoped; + if (empty()) return; D.resize(size()); diff --git a/src/xrCore/LocatorAPI.cpp b/src/xrCore/LocatorAPI.cpp index 4e960b2778e..cf25221b4f5 100644 --- a/src/xrCore/LocatorAPI.cpp +++ b/src/xrCore/LocatorAPI.cpp @@ -197,6 +197,8 @@ const CLocatorAPI::file* CLocatorAPI::RegisterExternal(pcstr name) const CLocatorAPI::file* CLocatorAPI::Register( pcstr name, size_t vfs, u32 crc, u32 ptr, u32 size_real, u32 size_compressed, u32 modif) { + ZoneScoped; + string256 temp_file_name; xr_strcpy(temp_file_name, sizeof temp_file_name, name); xr_fs_strlwr(temp_file_name); @@ -393,6 +395,8 @@ IReader* open_chunk(int fd, u32 ID, pcstr archiveName, size_t archiveSize, bool void CLocatorAPI::LoadArchive(archive& A, pcstr entrypoint) { + ZoneScoped; + // Create base path string_path fs_entry_point; bool shouldDecrypt = false; @@ -520,6 +524,8 @@ void CLocatorAPI::archive::close() void CLocatorAPI::ProcessArchive(pcstr _path) { + ZoneScoped; + // find existing archive shared_str path = _path; @@ -600,6 +606,8 @@ bool ignore_name(const char* _name) void CLocatorAPI::ProcessOne(pcstr path, const _finddata_t& entry) { + ZoneScoped; + string_path N; #if defined(XR_PLATFORM_WINDOWS) xr_strcpy(N, sizeof N, path); @@ -676,6 +684,8 @@ bool ignore_path(pcstr _path) bool CLocatorAPI::Recurse(pcstr path) { + ZoneScoped; + string_path scanPath = { 0 }; xr_strcpy(scanPath, sizeof scanPath, path); xr_strcat(scanPath, ".xrignore"); @@ -932,6 +942,8 @@ IReader* CLocatorAPI::setup_fs_ltx(pcstr fs_name) void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) { + ZoneScoped; + char _delimiter = '|'; //',' if (m_Flags.is(flReady)) return; @@ -958,6 +970,7 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) } else { + ZoneScopedN("Process FS ltx"); IReader* pFSltx = setup_fs_ltx(fs_name); // append all pathes @@ -968,6 +981,8 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) while (!pFSltx->eof()) { + ZoneScopedN("Read string"); + pFSltx->r_string(buf, sizeof buf); if (buf[0] == ';') continue; @@ -1051,6 +1066,8 @@ void CLocatorAPI::_initialize(u32 flags, pcstr target_folder, pcstr fs_name) void CLocatorAPI::_destroy() { + ZoneScoped; + for (auto& it : m_files) { auto str = pstr(it.name); diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 85858b92f4c..85416688031 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -191,6 +191,7 @@ void CalcIterations() TaskManager::TaskManager() { + ZoneScoped; CalcIterations(); workers.reserve(std::thread::hardware_concurrency()); @@ -207,6 +208,7 @@ TaskManager::TaskManager() TaskManager::~TaskManager() { + ZoneScoped; shouldStop.store(true, std::memory_order_release); // Finish all pending tasks @@ -230,6 +232,7 @@ TaskManager::~TaskManager() void TaskManager::RegisterThisThreadAsWorker() { + ZoneScoped; R_ASSERT2(workers.size() < std::thread::hardware_concurrency(), "You must change OTHER_THREADS_COUNT if you want to register more custom threads."); @@ -240,6 +243,7 @@ void TaskManager::RegisterThisThreadAsWorker() void TaskManager::UnregisterThisThreadAsWorker() { + ZoneScoped; std::lock_guard guard{ workersLock }; shouldPause.store(true, std::memory_order_release); @@ -393,6 +397,7 @@ void TaskManager::RunTask(Task& task) void TaskManager::Wait(const Task& task) const { + ZoneScoped; while (!task.IsFinished()) { ExecuteOneTask(); @@ -403,6 +408,7 @@ void TaskManager::Wait(const Task& task) const void TaskManager::WaitForChildren(const Task& task) const { + ZoneScoped; while (!task.HasChildren()) { ExecuteOneTask(); diff --git a/src/xrCore/_compressed_normal.cpp b/src/xrCore/_compressed_normal.cpp index 4d03e4e90c1..fe74bd5d7a1 100644 --- a/src/xrCore/_compressed_normal.cpp +++ b/src/xrCore/_compressed_normal.cpp @@ -18,6 +18,8 @@ float pvUVAdjustment[0x2000]; void pvInitializeStatics(void) { + ZoneScoped; + for (int idx = 0; idx < 0x2000; idx++) { long xbits = idx >> 7; diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 01cbe55f581..c774c3684d8 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -232,6 +232,8 @@ bool g_initialize_cpu_called = false; //------------------------------------------------------------------------------------ void _initialize_cpu() { + ZoneScoped; + // General CPU identification string256 features{}; diff --git a/src/xrCore/log.cpp b/src/xrCore/log.cpp index 6010cd02d8c..409da72389e 100644 --- a/src/xrCore/log.cpp +++ b/src/xrCore/log.cpp @@ -228,6 +228,7 @@ pcstr log_name() { return (log_file_name); } void CreateLog(bool nl) { + ZoneScoped; LogFile.reserve(1000); no_log = nl; @@ -275,6 +276,7 @@ void CreateLog(bool nl) void CloseLog(void) { + ZoneScoped; FlushLog(); if (LogWriter) FS.w_close(LogWriter); diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index a30d15bdf54..4d365c97bf2 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -173,6 +173,7 @@ void xrCore::PrintBuildInfo() void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback cb, bool init_fs, pcstr fs_fname, bool plugin) { + ZoneScoped; Threading::SetCurrentThreadName("Primary thread"); xr_strcpy(ApplicationName, _ApplicationName); PrintBuildInfo(); @@ -325,6 +326,7 @@ void xrCore::_destroy() --init_counter; if (0 == init_counter) { + ZoneScoped; FS._destroy(); EFS._destroy(); xr_FS = nullptr; diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 04708228347..8c7810a7c48 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -938,6 +938,7 @@ void xrDebug::OnThreadSpawn() void xrDebug::Initialize(pcstr commandLine) { + ZoneScoped; *BugReportFile = 0; OnThreadSpawn(); SetupExceptionHandler(); diff --git a/src/xrCore/xrMemory.cpp b/src/xrCore/xrMemory.cpp index e551ea07888..84c679c4db7 100644 --- a/src/xrCore/xrMemory.cpp +++ b/src/xrCore/xrMemory.cpp @@ -91,6 +91,7 @@ bool shared_str_initialized = false; void xrMemory::_initialize() { + ZoneScoped; g_pStringContainer = xr_new(); shared_str_initialized = true; g_pSharedMemoryContainer = xr_new(); @@ -98,6 +99,7 @@ void xrMemory::_initialize() void xrMemory::_destroy() { + ZoneScoped; xr_delete(g_pSharedMemoryContainer); xr_delete(g_pStringContainer); } diff --git a/src/xrCore/xr_ini.cpp b/src/xrCore/xr_ini.cpp index 263959f5099..1286e131ea2 100644 --- a/src/xrCore/xr_ini.cpp +++ b/src/xrCore/xr_ini.cpp @@ -365,6 +365,8 @@ CInifile::CInifile(pcstr fileName, bool readOnly, bool loadAtStart, bool saveAtE CInifile::~CInifile() { + ZoneScoped; + if (!m_flags.test(eReadOnly) && m_flags.test(eSaveAtEnd) && !save_as()) Log("!Can't save inifile:", m_file_name); @@ -400,6 +402,8 @@ IC bool is_empty_line_now(IReader* F) void CInifile::Load(IReader* F, pcstr path, allow_include_func_t allow_include_func) { + ZoneScoped; + R_ASSERT(F); Sect* Current = nullptr; string4096 str; diff --git a/src/xrEngine/Device_Initialize.cpp b/src/xrEngine/Device_Initialize.cpp index f41d0b3c614..3a96717e8e7 100644 --- a/src/xrEngine/Device_Initialize.cpp +++ b/src/xrEngine/Device_Initialize.cpp @@ -39,6 +39,7 @@ void SetSDLSettings(pcstr title) void CRenderDevice::Initialize() { + ZoneScoped; Log("Initializing Engine..."); TimerGlobal.Start(); TimerMM.Start(); diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index 667fd3b5a03..c2c02ee87a3 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -21,6 +21,7 @@ void CRenderDevice::Create() if (b_is_Ready) return; // prevent double call + ZoneScoped; secondaryThread = Threading::RunThread("Secondary thread", &CRenderDevice::SecondaryThreadProc, this); Statistic = xr_new(); diff --git a/src/xrEngine/Device_destroy.cpp b/src/xrEngine/Device_destroy.cpp index 0bcb6f67436..52fe376fffc 100644 --- a/src/xrEngine/Device_destroy.cpp +++ b/src/xrEngine/Device_destroy.cpp @@ -7,6 +7,8 @@ void CRenderDevice::Destroy() { if (!b_is_Ready) return; + + ZoneScoped; Log("Destroying Render..."); b_is_Ready = false; Statistic->OnDeviceDestroy(); @@ -29,6 +31,8 @@ void CRenderDevice::Destroy() void CRenderDevice::Reset(bool precache /*= true*/) { + ZoneScoped; + const auto dwWidth_before = dwWidth; const auto dwHeight_before = dwHeight; pInput->GrabInput(false); diff --git a/src/xrEngine/Device_imgui.cpp b/src/xrEngine/Device_imgui.cpp index 39ccedc3b8b..73de207ace6 100644 --- a/src/xrEngine/Device_imgui.cpp +++ b/src/xrEngine/Device_imgui.cpp @@ -9,6 +9,8 @@ void CRenderDevice::InitializeImGui() if (m_imgui_context) return; + ZoneScoped; + ImGui::SetAllocatorFunctions( [](size_t size, void* /*user_data*/) { @@ -210,6 +212,8 @@ void CRenderDevice::DestroyImGui() if (!m_imgui_context) return; + ZoneScoped; + m_imgui_render->OnDeviceDestroy(); GEnv.RenderFactory->DestroyImGuiRender(m_imgui_render); m_imgui_render = nullptr; diff --git a/src/xrEngine/Device_mode.cpp b/src/xrEngine/Device_mode.cpp index e6e6261f2b3..29899e10bc0 100644 --- a/src/xrEngine/Device_mode.cpp +++ b/src/xrEngine/Device_mode.cpp @@ -58,6 +58,8 @@ void FillImGuiMonitorData(const int monitorID) void CRenderDevice::FillVideoModes() { + ZoneScoped; + const int displayCount = SDL_GetNumVideoDisplays(); R_ASSERT3(displayCount > 0, "Failed to find display", SDL_GetError()); @@ -75,6 +77,8 @@ void CRenderDevice::FillVideoModes() void CRenderDevice::CleanupVideoModes() { + ZoneScoped; + for (auto& [monitor_id, tokens] : vid_mode_token) { for (auto& token : tokens) @@ -110,6 +114,8 @@ void CRenderDevice::SetWindowDraggable(bool draggable) void CRenderDevice::UpdateWindowProps() { + ZoneScoped; + const bool windowed = psDeviceMode.WindowStyle != rsFullscreen; SelectResolution(windowed); diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 43f0be16114..3c15417d941 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -63,6 +63,7 @@ extern void msCreate(pcstr name); void CEngine::Initialize(void) { + ZoneScoped; #ifdef DEBUG msCreate("game"); #endif @@ -83,6 +84,8 @@ void CEngine::Initialize(void) void CEngine::Destroy() { + ZoneScoped; + Sheduler.Destroy(); External.Destroy(); Event._destroy(); diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index ec1838880ac..b3f69f1a2c2 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -151,6 +151,8 @@ void CEngineAPI::CreateRendererList() if (!VidQualityToken.empty()) return; + ZoneScoped; + const auto loadLibrary = [&](pcstr library) -> bool { auto handle = XRay::LoadModule(library); diff --git a/src/xrEngine/Environment.cpp b/src/xrEngine/Environment.cpp index dba4fda6e8f..faf86780855 100644 --- a/src/xrEngine/Environment.cpp +++ b/src/xrEngine/Environment.cpp @@ -417,6 +417,8 @@ void CEnvironment::lerp() void CEnvironment::OnFrame() { + ZoneScoped; + if (!g_pGameLevel) return; diff --git a/src/xrEngine/Environment_misc.cpp b/src/xrEngine/Environment_misc.cpp index 7c7b499003b..3bf8b658cc2 100644 --- a/src/xrEngine/Environment_misc.cpp +++ b/src/xrEngine/Environment_misc.cpp @@ -188,6 +188,8 @@ void CEnvAmbient::destroy() void CEnvAmbient::load( const CInifile& ambients_config, const CInifile& sound_channels_config, const CInifile& effects_config, const shared_str& sect) { + ZoneScoped; + m_ambients_config_filename = ambients_config.fname(); m_load_section = sect; string_path tmp; @@ -302,6 +304,8 @@ CEnvDescriptor::CEnvDescriptor(shared_str const& identifier) : m_identifier(iden void CEnvDescriptor::load(CEnvironment& environment, const CInifile& config, pcstr section /*= nullptr*/) { + ZoneScoped; + const bool old_style = section; cpcstr ambient_name = old_style ? "env_ambient" : "ambient"; @@ -422,6 +426,8 @@ void CEnvDescriptor::save(CInifile& config, pcstr section /*= nullptr*/) const if (dont_save) return; + ZoneScoped; + const bool old_style = section; cpcstr ambient_name = old_style ? "env_ambient" : "ambient"; @@ -730,6 +736,8 @@ CEnvAmbient* CEnvironment::AppendEnvAmb(const shared_str& sect, CInifile const* void CEnvironment::mods_load() { + ZoneScoped; + Modifiers.clear(); string_path path; if (FS.exist(path, "$level$", "level.env_mod")) @@ -761,6 +769,8 @@ void CEnvironment::mods_load() void CEnvironment::mods_unload() { Modifiers.clear(); } void CEnvironment::load_level_specific_ambients() { + ZoneScoped; + const shared_str level_name = g_pGameLevel->name(); string_path path; @@ -820,6 +830,8 @@ void CEnvironment::load_weathers() if (!WeatherCycles.empty()) return; + ZoneScoped; + FS_FileSet weathers; FS.file_list(weathers, "$game_weathers$", FS_ListFiles, "*.ltx"); @@ -892,6 +904,8 @@ void CEnvironment::load_weather_effects() if (!WeatherFXs.empty()) return; + ZoneScoped; + FS_FileSet weathersEffects; FS.file_list(weathersEffects, "$game_weather_effects$", FS_ListFiles, "*.ltx"); @@ -967,6 +981,8 @@ void CEnvironment::load_weather_effects() void CEnvironment::load() { + ZoneScoped; + if (!eff_Rain) eff_Rain = xr_new(); if (!eff_LensFlare) @@ -980,6 +996,8 @@ void CEnvironment::load() void CEnvironment::unload() { + ZoneScoped; + // clear weathers for (auto& cycle : WeatherCycles) for (auto& env : cycle.second) @@ -1011,6 +1029,7 @@ void CEnvironment::unload() void CEnvironment::ED_Reload() { + ZoneScoped; unload(); load(); OnFrame(); @@ -1018,6 +1037,8 @@ void CEnvironment::ED_Reload() void CEnvironment::save() const { + ZoneScoped; + string_path environment_config_path; FS.update_path(environment_config_path, "$game_config$", "weathers\\environment.ltx"); @@ -1031,6 +1052,8 @@ void CEnvironment::save() const void CEnvironment::save_weathers(CInifile* environment_config /*= nullptr*/) const { + ZoneScoped; + string_path weathers_path; if (!FS.update_path(weathers_path, "$game_weathers$", "", false)) FS.update_path(weathers_path, "$game_config$", "environment\\weathers"); @@ -1080,6 +1103,8 @@ void CEnvironment::save_weathers(CInifile* environment_config /*= nullptr*/) con void CEnvironment::save_weather_effects(CInifile* environment_config /*= nullptr*/) const { + ZoneScoped; + string_path effects_path; if (!FS.update_path(effects_path, "$game_weather_effects$", "", false)) FS.update_path(effects_path, "$game_config$", "environment\\weather_effects"); diff --git a/src/xrEngine/EventAPI.cpp b/src/xrEngine/EventAPI.cpp index 1e905acacad..fde8c172d25 100644 --- a/src/xrEngine/EventAPI.cpp +++ b/src/xrEngine/EventAPI.cpp @@ -160,6 +160,8 @@ void msParse(pcstr c) void CEventAPI::OnFrame() { + ZoneScoped; + #ifdef DEBUG msRead(); #endif diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 93b1c27d6db..d2eede00dff 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -16,6 +16,8 @@ extern bool g_bLoaded; IGame_Level::IGame_Level() : ObjectSpace(&g_pGamePersistent->SpatialSpace) { + ZoneScoped; + m_pCameras = xr_new(true); g_pGameLevel = this; pLevel = NULL; @@ -31,6 +33,8 @@ IGame_Level::IGame_Level() IGame_Level::~IGame_Level() { + ZoneScoped; + if (strstr(Core.Params, "-nes_texture_storing")) GEnv.Render->ResourcesStoreNecessaryTextures(); xr_delete(pLevel); @@ -58,6 +62,8 @@ IGame_Level::~IGame_Level() void IGame_Level::net_Stop() { + ZoneScoped; + // XXX: why update 6 times? for (int i = 0; i < 6; i++) Objects.Update(false); @@ -88,6 +94,8 @@ static bool deserialize_callback(IReader& reader) bool IGame_Level::Load(u32 dwNum) { + ZoneScoped; + // Initialize level data g_pGamePersistent->Level_Set(dwNum); string_path temp; @@ -147,6 +155,8 @@ bool IGame_Level::Load(u32 dwNum) int psNET_DedicatedSleep = 5; void IGame_Level::OnRender() { + ZoneScoped; + if (GEnv.isDedicatedServer) { Sleep(psNET_DedicatedSleep); @@ -155,22 +165,10 @@ void IGame_Level::OnRender() // if (_abs(Device.fTimeDelta)Calculate(); GEnv.Render->Render(); -#ifdef _GPA_ENABLED - TAL_RetireID(rtID); -#endif // _GPA_ENABLED - // Font // pApp->pFontSystem->SetSizeI(0.023f); // pApp->pFontSystem->OnRender(); @@ -178,6 +176,8 @@ void IGame_Level::OnRender() void IGame_Level::OnFrame() { + ZoneScoped; + SoundEvent_Dispatch(); // Log ("- level:on-frame: ",u32(Device.dwFrame)); @@ -322,6 +322,7 @@ void IGame_Level::SoundEvent_Register(const ref_sound& S, float range) void IGame_Level::SoundEvent_Dispatch() { + ZoneScoped; while (!snd_Events.empty()) { _esound_delegate& D = snd_Events.back(); diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 8d3359295a9..6aca063b3eb 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -23,6 +23,8 @@ ENGINE_API IGame_Persistent* g_pGamePersistent = nullptr; IGame_Persistent::IGame_Persistent() { + ZoneScoped; + eStart = Engine.Event.Handler_Attach("KERNEL:start", this); eStartLoad = Engine.Event.Handler_Attach("KERNEL:load", this); eDisconnect = Engine.Event.Handler_Attach("KERNEL:disconnect", this); @@ -48,6 +50,8 @@ IGame_Persistent::IGame_Persistent() IGame_Persistent::~IGame_Persistent() { + ZoneScoped; + GEnv.Sound->destroy_scene(m_pSound); DefaultSoundScene = nullptr; @@ -74,6 +78,8 @@ void IGame_Persistent::OnAppDeactivate() {} void IGame_Persistent::OnAppStart() { + ZoneScoped; + #ifndef _EDITOR Environment().load(); #endif @@ -83,6 +89,8 @@ void IGame_Persistent::OnAppStart() void IGame_Persistent::OnAppEnd() { + ZoneScoped; + #ifndef _EDITOR Environment().unload(); #endif @@ -98,6 +106,7 @@ void IGame_Persistent::OnAppEnd() void IGame_Persistent::Level_Append(pcstr folder) { + ZoneScoped; string_path N1, N2, N3, N4; strconcat(N1, folder, "level"); @@ -116,6 +125,8 @@ void IGame_Persistent::Level_Append(pcstr folder) void IGame_Persistent::Level_Scan() { + ZoneScoped; + for (auto& level : Levels) { xr_free(level.folder); @@ -163,6 +174,8 @@ bool set_logo_path(string_path& path, pcstr levelName, int count = -1) void IGame_Persistent::Level_Set(u32 id) { + ZoneScoped; + if (id >= Levels.size()) return; FS.get_path("$level$")->_set(Levels[id].folder); @@ -197,6 +210,8 @@ void IGame_Persistent::Level_Set(u32 id) int IGame_Persistent::Level_ID(pcstr name, pcstr ver, bool bSet) { + ZoneScoped; + int result = -1; bool arch_res = false; @@ -255,6 +270,8 @@ CInifile* IGame_Persistent::GetArchiveHeader(pcstr name, pcstr ver) void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) { + ZoneScoped; + if (E == eStart) { pstr op_server = pstr(P1); @@ -326,6 +343,8 @@ void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) void IGame_Persistent::PreStart(pcstr op) { + ZoneScoped; + string256 prev_type; params new_game_params; xr_strcpy(prev_type, m_game_params.m_game_type); @@ -339,6 +358,8 @@ void IGame_Persistent::PreStart(pcstr op) } void IGame_Persistent::Start(pcstr op) { + ZoneScoped; + string256 prev_type; xr_strcpy(prev_type, m_game_params.m_game_type); m_game_params.parse_cmd_line(op); @@ -356,6 +377,7 @@ void IGame_Persistent::Start(pcstr op) void IGame_Persistent::Disconnect() { + ZoneScoped; #ifndef _EDITOR // clear "need to play" particles destroy_particles(true); @@ -364,6 +386,7 @@ void IGame_Persistent::Disconnect() void IGame_Persistent::OnGameStart() { + ZoneScoped; #ifndef _EDITOR LoadTitle("st_prefetching_objects"); if (!strstr(Core.Params, "-noprefetch")) @@ -374,6 +397,8 @@ void IGame_Persistent::OnGameStart() #ifndef _EDITOR void IGame_Persistent::Prefetch() { + ZoneScoped; + // prefetch game objects & models CTimer timer; timer.Start(); @@ -403,6 +428,8 @@ void IGame_Persistent::Prefetch() void IGame_Persistent::OnGameEnd() { + ZoneScoped; + #ifndef _EDITOR ObjectPool.clear(); GEnv.Render->models_Clear(true); @@ -434,6 +461,8 @@ void IGame_Persistent::LoadEnd() void IGame_Persistent::LoadTitle(pcstr ls_title, bool change_tip, shared_str map_name) { + ZoneScoped; + if (ls_title) { string256 buff; @@ -445,6 +474,8 @@ void IGame_Persistent::LoadTitle(pcstr ls_title, bool change_tip, shared_str map if (change_tip) { + ZoneScopedN("Change tip"); + bool noTips = false; string512 buff; u8 tip_num; @@ -536,6 +567,8 @@ void IGame_Persistent::ShowLoadingScreen(bool show) const void IGame_Persistent::OnFrame() { + ZoneScoped; + SpatialSpace.update(); SpatialSpacePhysic.update(); @@ -576,6 +609,8 @@ void IGame_Persistent::OnFrame() void IGame_Persistent::destroy_particles(const bool& all_particles) { + ZoneScoped; + #ifndef _EDITOR ps_needtoplay.clear(); diff --git a/src/xrEngine/LightAnimLibrary.cpp b/src/xrEngine/LightAnimLibrary.cpp index dd040e68832..27ba559dd2e 100644 --- a/src/xrEngine/LightAnimLibrary.cpp +++ b/src/xrEngine/LightAnimLibrary.cpp @@ -196,6 +196,8 @@ void ELightAnimLibrary::OnCreate() { Load(); } void ELightAnimLibrary::OnDestroy() { Unload(); } void ELightAnimLibrary::Unload() { + ZoneScoped; + for (auto& la : Items) xr_delete(la); Items.clear(); @@ -203,6 +205,8 @@ void ELightAnimLibrary::Unload() void ELightAnimLibrary::Load() { + ZoneScoped; + string_path fn; FS.update_path(fn, _game_data_, "lanims.xr"); IReader* fs = FS.r_open(fn); @@ -239,6 +243,8 @@ void ELightAnimLibrary::Load() void ELightAnimLibrary::Save() { + ZoneScoped; + CMemoryWriter F; F.open_chunk(CHUNK_VERSION); F.w_u16(LANIM_VERSION); diff --git a/src/xrEngine/PS_instance.cpp b/src/xrEngine/PS_instance.cpp index d4fb8a472cd..42e52c42126 100644 --- a/src/xrEngine/PS_instance.cpp +++ b/src/xrEngine/PS_instance.cpp @@ -36,6 +36,8 @@ CPS_Instance::~CPS_Instance() //---------------------------------------------------- void CPS_Instance::shedule_Update(u32 dt) { + ZoneScoped; + if (renderable.pROS) GEnv.Render->ros_destroy(renderable.pROS); //. particles doesn't need ROS diff --git a/src/xrEngine/Rain.cpp b/src/xrEngine/Rain.cpp index 53a9f677d63..1274990642b 100644 --- a/src/xrEngine/Rain.cpp +++ b/src/xrEngine/Rain.cpp @@ -55,6 +55,8 @@ CEffect_Rain::~CEffect_Rain() // Born void CEffect_Rain::Born(Item& dest, float radius, float speed) { + ZoneScoped; + Fvector axis; axis.set(0, -1, 0); float gust = g_pGamePersistent->Environment().wind_strength_factor / 10.f; @@ -80,6 +82,8 @@ void CEffect_Rain::Born(Item& dest, float radius, float speed) bool CEffect_Rain::RayPick(const Fvector& s, const Fvector& d, float& range, collide::rq_target tgt) { + ZoneScoped; + bool bRes = true; #ifdef _EDITOR Tools->RayPick(s, d, range); @@ -112,6 +116,8 @@ void CEffect_Rain::RenewItem(Item& dest, float height, bool bHit) void CEffect_Rain::OnFrame() { + ZoneScoped; + #ifndef _EDITOR if (!g_pGameLevel) return; diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index b8d3114f959..ce3d5328913 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -100,6 +100,8 @@ CConsole::CConsole() void CConsole::Initialize() { + ZoneScoped; + scroll_delta = 0; bVisible = false; pFont = NULL; @@ -138,6 +140,8 @@ CConsole::~CConsole() void CConsole::Destroy() { + ZoneScoped; + xr_delete(pFont); xr_delete(pFont2); Commands.clear(); @@ -156,6 +160,8 @@ void CConsole::RemoveCommand(IConsole_Command* cc) void CConsole::OnFrame() { + ZoneScoped; + m_editor->on_frame(); if (Device.dwFrame % 10 == 0) @@ -219,6 +225,8 @@ void CConsole::OnUIReset() void CConsole::OnRender() { + ZoneScoped; + if (!bVisible) { return; diff --git a/src/xrEngine/cf_dynamic_mesh.cpp b/src/xrEngine/cf_dynamic_mesh.cpp index 6ebb5e59c69..f418ea93373 100644 --- a/src/xrEngine/cf_dynamic_mesh.cpp +++ b/src/xrEngine/cf_dynamic_mesh.cpp @@ -13,6 +13,8 @@ bool CCF_DynamicMesh::_RayQuery(const collide::ray_defs& Q, collide::rq_results& R) { + ZoneScoped; + int s_count = R.r_count(); bool res = inherited::_RayQuery(Q, R); if (!res) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index c85559a27fc..26b84fae55a 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -35,6 +35,8 @@ bool CRenderDevice::RenderBegin() if (GEnv.isDedicatedServer) return true; + ZoneScoped; + switch (GEnv.Render->GetDeviceState()) { case DeviceState::Normal: break; @@ -91,6 +93,7 @@ void CRenderDevice::RenderEnd(void) if (GEnv.isDedicatedServer) return; + ZoneScoped; if (dwPrecacheFrame) { GEnv.Sound->set_master_volume(0.f); @@ -184,6 +187,8 @@ ENGINE_API xr_list g_loading_events; bool CRenderDevice::BeforeFrame() { + ZoneScoped; + if (!b_is_Ready) { Sleep(100); @@ -208,6 +213,8 @@ bool CRenderDevice::BeforeFrame() void CRenderDevice::BeforeRender() { + ZoneScoped; + // Precache if (dwPrecacheFrame) { @@ -240,18 +247,20 @@ static void UpdateViewports() void CRenderDevice::DoRender() { - ZoneScoped; - if (GEnv.isDedicatedServer) return; + ZoneScoped; + CStatTimer renderTotalReal; renderTotalReal.FrameStart(); renderTotalReal.Begin(); if (b_is_Active && RenderBegin()) { - // all rendering is done here - seqRender.Process(); + { + ZoneScopedN("Render process"); + seqRender.Process(); // all rendering is done here + } CalcFrameStats(); Statistic->Show(); @@ -271,6 +280,8 @@ void CRenderDevice::DoRender() stats.RenderTotal.accum = renderTotalReal.accum; } +constexpr pcstr SECONDARY_THREAD_MARK = "Secondary thread"; + void CRenderDevice::SecondaryThreadProc() { TaskScheduler->RegisterThisThreadAsWorker(); @@ -278,12 +289,14 @@ void CRenderDevice::SecondaryThreadProc() { if (executeSecondaryTasks.load(std::memory_order_acquire)) { + FrameMarkStart(SECONDARY_THREAD_MARK); for (u32 pit = 0; pit < seqParallel.size(); pit++) seqParallel[pit](); seqParallel.clear(); seqFrameMT.Process(); executeSecondaryTasks.store(false, std::memory_order_relaxed); secondaryTasksExecuted.store(true, std::memory_order_release); + FrameMarkEnd(SECONDARY_THREAD_MARK); } TaskScheduler->ExecuteOneTask(); } @@ -328,12 +341,12 @@ void CRenderDevice::ProcessFrame() if (!b_is_Active) Sleep(1); - - FrameMark; } void CRenderDevice::ProcessEvent(const SDL_Event& event) { + ZoneScoped; + switch (event.type) { #if SDL_VERSION_ATLEAST(2, 0, 9) @@ -439,6 +452,8 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) void CRenderDevice::Run() { + ZoneScoped; + g_bLoaded = false; Log("Starting engine..."); @@ -479,6 +494,8 @@ u32 app_inactive_time_start = 0; void CRenderDevice::FrameMove() { + ZoneScoped; + dwFrame++; Core.dwFrame = dwFrame; dwTimeContinual = TimerMM.GetElapsed_ms() - app_inactive_time; @@ -594,6 +611,8 @@ bool CRenderDevice::Paused() { return g_pauseMngr().Paused(); } void CRenderDevice::OnWindowActivate(SDL_Window* window, bool activated) { + ZoneScoped; + if (editor().GetState() == editor::ide::visible_state::full) { if (window != m_sdlWnd) diff --git a/src/xrEngine/editor_base.cpp b/src/xrEngine/editor_base.cpp index f77edc5e8c6..7eabd56e7f5 100644 --- a/src/xrEngine/editor_base.cpp +++ b/src/xrEngine/editor_base.cpp @@ -48,6 +48,8 @@ void ide::OnAppEnd() void ide::OnFrame() { + ZoneScoped; + switch (m_state) { case visible_state::full: diff --git a/src/xrEngine/embedded_resources_management.h b/src/xrEngine/embedded_resources_management.h index 7aa74e00a04..d6acb7c4aea 100644 --- a/src/xrEngine/embedded_resources_management.h +++ b/src/xrEngine/embedded_resources_management.h @@ -8,6 +8,7 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) { + ZoneScoped; const size_t pitch = source->pitch; const size_t size = pitch * source->h; @@ -33,12 +34,14 @@ inline SDL_Surface* XRSDL_SurfaceVerticalFlip(SDL_Surface*& source) #ifdef XR_PLATFORM_WINDOWS inline HANDLE ExtractImage(int idx, UINT type) { + ZoneScoped; return LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(idx), type, 0, 0, LR_CREATEDIBSECTION); } inline SDL_Surface* CreateSurfaceFromBitmap(HBITMAP bitmapHandle) { + ZoneScoped; BITMAP bitmap; const int bitmapSize = GetObject(bitmapHandle, sizeof(BITMAP), &bitmap); @@ -80,6 +83,8 @@ inline SDL_Surface* ExtractBitmap(int idx) inline xr_vector ExtractSplashScreen() { + ZoneScoped; + // XXX: that's the place, where splash frames can be added // Animated splash screen! SDL_Surface* surface = ExtractBitmap(IDB_SPLASH); @@ -92,6 +97,8 @@ inline xr_vector ExtractSplashScreen() inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) { + ZoneScoped; + const HICON icon = (HICON)ExtractImage(iconIdx, IMAGE_ICON); SDL_SysWMinfo info; @@ -105,6 +112,8 @@ inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) #else inline xr_vector ExtractSplashScreen() { + ZoneScoped; + // You need to place logo.bmp beside fsgame.ltx SDL_Surface* surface = SDL_LoadBMP("logo.bmp"); @@ -116,6 +125,7 @@ inline xr_vector ExtractSplashScreen() inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) { + ZoneScoped; SDL_Surface* surface = nullptr; switch (iconIdx) { diff --git a/src/xrEngine/thunderbolt.cpp b/src/xrEngine/thunderbolt.cpp index e2512083296..31167677791 100644 --- a/src/xrEngine/thunderbolt.cpp +++ b/src/xrEngine/thunderbolt.cpp @@ -160,6 +160,8 @@ SThunderboltCollection* CEffect_Thunderbolt::AppendDef(shared_str sect) bool CEffect_Thunderbolt::RayPick(const Fvector& s, const Fvector& d, float& range) { + ZoneScoped; + bool bRes = true; #ifdef _EDITOR bRes = Tools->RayPick(s, d, range, 0, 0); @@ -190,6 +192,8 @@ bool CEffect_Thunderbolt::RayPick(const Fvector& s, const Fvector& d, float& ran void CEffect_Thunderbolt::Bolt(const CEnvDescriptorMixer& currentEnv) { + ZoneScoped; + VERIFY(currentEnv.thunderbolt); state = stWorking; const float lt = currentEnv.bolt_duration; @@ -244,6 +248,8 @@ void CEffect_Thunderbolt::Bolt(const CEnvDescriptorMixer& currentEnv) void CEffect_Thunderbolt::OnFrame(CEnvDescriptorMixer& currentEnv) { + ZoneScoped; + const bool enabled = currentEnv.thunderbolt; if (bEnabled != enabled) { diff --git a/src/xrEngine/tntQAVI.cpp b/src/xrEngine/tntQAVI.cpp index 565d5ea0578..f8684acc655 100644 --- a/src/xrEngine/tntQAVI.cpp +++ b/src/xrEngine/tntQAVI.cpp @@ -326,6 +326,8 @@ GetFrame */ bool CAviPlayerCustom::GetFrame(u8** pDest) { + ZoneScoped; + R_ASSERT(pDest); u32 dwCurrFrame; diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index ef63421a4c2..6528251de4c 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -124,6 +124,8 @@ void set_free_mode() void InitSettings() { + ZoneScoped; + xr_auth_strings_t ignoredPaths, checkedPaths; fill_auth_check_params(ignoredPaths, checkedPaths); //TODO port xrNetServer to Linux PathIncludePred includePred(&ignoredPaths); @@ -159,6 +161,8 @@ void InitSettings() void InitConsole() { + ZoneScoped; + if (GEnv.isDedicatedServer) Console = xr_new(); else @@ -186,6 +190,7 @@ void InitSound() { Engine.Sound.Create(); } void destroySound() { Engine.Sound.Destroy(); } void destroySettings() { + ZoneScoped; auto s = const_cast(&pSettings); xr_delete(*s); @@ -200,6 +205,7 @@ void destroySettings() void destroyConsole() { + ZoneScoped; Console->Execute("cfg_save"); Console->Destroy(); xr_delete(Console); @@ -207,14 +213,23 @@ void destroyConsole() void execUserScript() { + ZoneScoped; Console->Execute("default_controls"); Console->ExecuteScript(Console->ConfigFile); } +constexpr pcstr APPLICATION_STARTUP = "Application startup"; +constexpr pcstr APPLICATION_SHUTDOWN = "Application shutdown"; + CApplication::CApplication(pcstr commandLine) { + FrameMarkStart(APPLICATION_STARTUP); + xrDebug::Initialize(commandLine); - R_ASSERT3(SDL_Init(SDL_INIT_VIDEO) == 0, "Unable to initialize SDL", SDL_GetError()); + { + ZoneScopedN("SDL_Init"); + R_ASSERT3(SDL_Init(SDL_INIT_VIDEO) == 0, "Unable to initialize SDL", SDL_GetError()); + } #ifdef XR_PLATFORM_WINDOWS AccessibilityShortcuts shortcuts; @@ -223,34 +238,37 @@ CApplication::CApplication(pcstr commandLine) #endif #ifdef USE_DISCORD_INTEGRATION - discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &m_discord_core); + discord::Activity activity{}; + { + ZoneScopedN("Init Discord"); + discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &m_discord_core); # ifndef MASTER_GOLD - if (m_discord_core) - { - const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; - m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) + if (m_discord_core) { - switch (level) + const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; + m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) { - case discord::LogLevel::Error: Log("!", message); break; - case discord::LogLevel::Warn: Log("~", message); break; - case discord::LogLevel::Info: Log("*", message); break; - case discord::LogLevel::Debug: Log("#", message); break; - } - }); - } + switch (level) + { + case discord::LogLevel::Error: Log("!", message); break; + case discord::LogLevel::Warn: Log("~", message); break; + case discord::LogLevel::Info: Log("*", message); break; + case discord::LogLevel::Debug: Log("#", message); break; + } + }); + } # endif - discord::Activity activity{}; - activity.SetType(discord::ActivityType::Playing); - activity.SetApplicationId(DISCORD_APP_ID); - activity.SetState("Starting engine..."); - activity.GetAssets().SetLargeImage("logo"); - if (m_discord_core) - { - std::lock_guard guard{ m_discord_lock }; - m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); + activity.SetType(discord::ActivityType::Playing); + activity.SetApplicationId(DISCORD_APP_ID); + activity.SetState("Starting engine..."); + activity.GetAssets().SetLargeImage("logo"); + if (m_discord_core) + { + std::lock_guard guard{ m_discord_lock }; + m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); + } } #endif @@ -322,6 +340,7 @@ CApplication::CApplication(pcstr commandLine) Device.Initialize(); Console->OnDeviceInitialize(); + #ifdef USE_DISCORD_INTEGRATION const std::locale locale(""); activity.SetState(StringToUTF8(Core.ApplicationTitle, locale).c_str()); @@ -357,10 +376,14 @@ CApplication::CApplication(pcstr commandLine) R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); if (!g_pGamePersistent) Console->Show(); + + FrameMarkEnd(APPLICATION_STARTUP); } CApplication::~CApplication() { + FrameMarkStart(APPLICATION_SHUTDOWN); + #ifndef PROFILE_TASK_SYSTEM // Destroy APP DEL_INSTANCE(g_pGamePersistent); @@ -401,7 +424,11 @@ CApplication::~CApplication() #endif // PROFILE_TASK_SYSTEM Core._destroy(); - SDL_Quit(); + { + ZoneScopedN("SDL_Quit"); + SDL_Quit(); + } + FrameMarkEnd(APPLICATION_SHUTDOWN); } int CApplication::Run() @@ -409,13 +436,13 @@ int CApplication::Run() #ifdef PROFILE_TASK_SYSTEM return 0; #endif - - // Main cycle HideSplash(); Device.Run(); while (!SDL_QuitRequested()) // SDL_PumpEvents is here { + ZoneScopedN("Main cycle"); + bool canCallActivate = false; bool shouldActivate = false; @@ -477,6 +504,7 @@ int CApplication::Run() Device.ProcessFrame(); UpdateDiscordStatus(); + FrameMarkNamed("Primary thread"); } // while (!SDL_QuitRequested()) Device.Shutdown(); @@ -489,6 +517,8 @@ void CApplication::ShowSplash(bool topmost) if (m_window) return; + ZoneScoped; + m_surfaces = std::move(ExtractSplashScreen()); if (m_surfaces.empty()) @@ -542,6 +572,8 @@ void CApplication::HideSplash() if (!m_window) return; + ZoneScoped; + m_should_exit.Set(); m_splash_thread.join(); @@ -559,6 +591,7 @@ void CApplication::UpdateDiscordStatus() if (!m_discord_core) return; + ZoneScoped; std::lock_guard guard{ m_discord_lock }; m_discord_core->RunCallbacks(); #endif diff --git a/src/xrEngine/xrSheduler.cpp b/src/xrEngine/xrSheduler.cpp index 95b002f712b..ca9ce79ef95 100644 --- a/src/xrEngine/xrSheduler.cpp +++ b/src/xrEngine/xrSheduler.cpp @@ -317,6 +317,8 @@ void CSheduler::Pop() void CSheduler::ProcessStep() { + ZoneScoped; + // Normal priority const u32 dwTime = Device.dwTimeGlobal; @@ -422,6 +424,8 @@ void CSheduler::ProcessStep() void CSheduler::Update() { + ZoneScoped; + // Initialize stats.Update.Begin(); cycles_start = CPU::QPC(); diff --git a/src/xrEngine/xrTheora_Stream.cpp b/src/xrEngine/xrTheora_Stream.cpp index ad0213ce97f..fdb8c898d4e 100644 --- a/src/xrEngine/xrTheora_Stream.cpp +++ b/src/xrEngine/xrTheora_Stream.cpp @@ -178,6 +178,8 @@ bool CTheoraStream::ParseHeaders() bool CTheoraStream::Decode(u32 in_tm_play) { + ZoneScoped; + VERIFY(in_tm_play < tm_total); ogg_int64_t t_frame; t_frame = iFloor(in_tm_play * fpms); diff --git a/src/xrEngine/xrTheora_Surface.cpp b/src/xrEngine/xrTheora_Surface.cpp index e03b4cecd6f..b9ad39b0083 100644 --- a/src/xrEngine/xrTheora_Surface.cpp +++ b/src/xrEngine/xrTheora_Surface.cpp @@ -52,6 +52,8 @@ void CTheoraSurface::Play(bool _looped, u32 _time) bool CTheoraSurface::Update(u32 _time) { + ZoneScoped; + VERIFY(Valid()); bool redraw = false; diff --git a/src/xrEngine/xr_collide_form.cpp b/src/xrEngine/xr_collide_form.cpp index 97f901b5392..ed72ebc0ec1 100644 --- a/src/xrEngine/xr_collide_form.cpp +++ b/src/xrEngine/xr_collide_form.cpp @@ -205,6 +205,8 @@ void CCF_Skeleton::BuildTopLevel() bool CCF_Skeleton::_RayQuery(const collide::ray_defs& Q, collide::rq_results& R) { + ZoneScoped; + if (dwFrameTL != Device.dwFrame) BuildTopLevel(); @@ -326,6 +328,8 @@ void CCF_EventBox::_BoxQuery(const Fbox& B, const Fmatrix& M, u32 flags) CCF_Shape::CCF_Shape(IGameObject* _owner) : ICollisionForm(_owner, cftShape) {} bool CCF_Shape::_RayQuery(const collide::ray_defs& Q, collide::rq_results& R) { + ZoneScoped; + // Convert ray into local model space Fvector dS, dD; Fmatrix temp; @@ -468,6 +472,8 @@ void CCF_Shape::ComputeBounds() bool CCF_Shape::Contact(IGameObject* O) { + ZoneScoped; + // Build object-sphere in World-Space Fsphere S; if (O->Visual()) diff --git a/src/xrEngine/xr_efflensflare.cpp b/src/xrEngine/xr_efflensflare.cpp index ca9b005065d..a32bbf16d0d 100644 --- a/src/xrEngine/xr_efflensflare.cpp +++ b/src/xrEngine/xr_efflensflare.cpp @@ -294,6 +294,8 @@ void CLensFlare::OnFrame(const CEnvDescriptorMixer& currentEnv, float time_facto if (!g_pGameLevel) return; #endif + ZoneScoped; + dwFrame = Device.dwFrame; R_ASSERT(_valid(currentEnv.sun_dir)); diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index e75931096d6..66ff750a3d2 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -35,6 +35,8 @@ constexpr size_t MAX_CONTROLLER_EVENTS = 64; CInput::CInput(const bool exclusive) { + ZoneScoped; + exclusiveInput = exclusive; Log("Starting INPUT device..."); @@ -69,6 +71,8 @@ CInput::CInput(const bool exclusive) CInput::~CInput() { + ZoneScoped; + GrabInput(false); for (auto& controller : controllers) @@ -121,6 +125,8 @@ void CInput::SetCurrentInputType(InputType type) void CInput::MouseUpdate() { + ZoneScoped; + // Mouse2 is a middle button in SDL, // but in X-Ray this is a right button constexpr int RemapIdx[] = { 0, 2, 1, 3, 4 }; @@ -197,6 +203,8 @@ void CInput::MouseUpdate() void CInput::KeyUpdate() { + ZoneScoped; + SDL_Event events[MAX_KEYBOARD_EVENTS]; const auto count = SDL_PeepEvents(events, MAX_KEYBOARD_EVENTS, SDL_GETEVENT, SDL_KEYDOWN, SDL_KEYMAPCHANGED); @@ -273,6 +281,8 @@ void CInput::KeyUpdate() void CInput::ControllerUpdate() { + ZoneScoped; + constexpr int ControllerButtonToKey[] = { XR_CONTROLLER_BUTTON_A, @@ -677,6 +687,8 @@ void CInput::OnAppDeactivate(void) void CInput::OnFrame(void) { + ZoneScoped; + if (AltF4Pressed) return; diff --git a/src/xrEngine/xr_object_list.cpp b/src/xrEngine/xr_object_list.cpp index aacfa149cff..90514b9d6b0 100644 --- a/src/xrEngine/xr_object_list.cpp +++ b/src/xrEngine/xr_object_list.cpp @@ -216,6 +216,8 @@ void CObjectList::clear_crow_vec(Objects& o) void CObjectList::Update(bool bForce) { + ZoneScoped; + if (statsFrame != Device.dwFrame) { statsFrame = Device.dwFrame; @@ -459,6 +461,8 @@ void CObjectList::Load() void CObjectList::Unload() { + ZoneScoped; + if (objects_sleeping.size() || objects_active.size()) Msg("! objects-leaked: %d", objects_sleeping.size() + objects_active.size()); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 092c0984131..9c35726da96 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -48,6 +48,8 @@ CGamePersistent::CGamePersistent() { + ZoneScoped; + m_game_params.m_e_game_type = eGameIDNoGame; ambient_sound_next_time.reserve(32); @@ -73,6 +75,8 @@ CGamePersistent::CGamePersistent() CGamePersistent::~CGamePersistent() { + ZoneScoped; + FS.r_close(pDemoFile); Device.seqFrame.Remove(this); Engine.Event.Handler_Detach(eDemoStart, this); @@ -89,6 +93,8 @@ extern void init_game_globals(); void CGamePersistent::OnAppStart() { + ZoneScoped; + // load game materials GMLib.Load(); // XXX: not ready to be loaded in parallel. Crashes on Linux, rare crashes on Windows and bugs with water became mercury on Windows. @@ -207,6 +213,8 @@ void CGamePersistent::OnGameEnd() void CGamePersistent::WeathersUpdate() { + ZoneScoped; + if (g_pGameLevel && !GEnv.isDedicatedServer) { CActor* actor = smart_cast(Level().CurrentViewEntity()); @@ -459,6 +467,8 @@ extern CUISequencer* g_tutorial2; void CGamePersistent::OnFrame() { + ZoneScoped; + if (Device.dwPrecacheFrame == 5 && m_intro_event.empty()) { LoadTitle(); @@ -637,6 +647,8 @@ void CGamePersistent::OnFrame() void CGamePersistent::OnEvent(EVENT E, u64 P1, u64 P2) { + ZoneScoped; + if (E == eQuickLoad) { if (Device.Paused()) diff --git a/src/xrGame/HUDManager.cpp b/src/xrGame/HUDManager.cpp index bb8a6ea0475..8ea804c207c 100644 --- a/src/xrGame/HUDManager.cpp +++ b/src/xrGame/HUDManager.cpp @@ -35,6 +35,8 @@ CHUDManager::~CHUDManager() //-------------------------------------------------------------------- void CHUDManager::OnFrame() { + ZoneScoped; + if (!psHUD_Flags.is(HUD_DRAW_RT2)) return; @@ -50,6 +52,8 @@ void CHUDManager::OnFrame() void CHUDManager::Render_First(u32 context_id) { + ZoneScoped; + if (!psHUD_Flags.is(HUD_WEAPON | HUD_WEAPON_RT | HUD_WEAPON_RT2 | HUD_DRAW_RT2)) return; if (0 == pUIGame) @@ -93,6 +97,8 @@ bool need_render_hud() void CHUDManager::Render_Last(u32 context_id) { + ZoneScoped; + if (!psHUD_Flags.is(HUD_WEAPON | HUD_WEAPON_RT | HUD_WEAPON_RT2 | HUD_DRAW_RT2)) return; if (0 == pUIGame) @@ -139,6 +145,8 @@ extern ENGINE_API bool bShowPauseString; //отрисовка элементов интерфейса void CHUDManager::RenderUI() { + ZoneScoped; + if (!psHUD_Flags.is(HUD_DRAW_RT2)) return; @@ -199,6 +207,8 @@ void CHUDManager::SetGrenadeMarkType(LPCSTR tex_name) { HitMarker.InitShader_Gre void CHUDManager::Load() { + ZoneScoped; + if (!pUIGame) { pUIGame = Game().createGameUI(); @@ -211,6 +221,8 @@ void CHUDManager::Load() void CHUDManager::OnUIReset() { + ZoneScoped; + pUIGame->HideShownDialogs(); pUIGame->UnLoad(); @@ -221,6 +233,8 @@ void CHUDManager::OnUIReset() void CHUDManager::OnDisconnected() { + ZoneScoped; + b_online = false; if (pUIGame) Device.seqFrame.Remove(pUIGame); @@ -230,6 +244,9 @@ void CHUDManager::OnConnected() { if (b_online) return; + + ZoneScoped; + b_online = true; if (pUIGame) Device.seqFrame.Add(pUIGame, REG_PRIORITY_LOW - 1000); @@ -237,6 +254,8 @@ void CHUDManager::OnConnected() void CHUDManager::net_Relcase(IGameObject* obj) { + ZoneScoped; + HitMarker.net_Relcase(obj); VERIFY(m_pHUDTarget); diff --git a/src/xrGame/HudSound.cpp b/src/xrGame/HudSound.cpp index be1d48cc176..a8a14a4189d 100644 --- a/src/xrGame/HudSound.cpp +++ b/src/xrGame/HudSound.cpp @@ -13,6 +13,8 @@ void InitHudSoundSettings() void HUD_SOUND_ITEM::LoadSound(LPCSTR section, LPCSTR line, HUD_SOUND_ITEM& hud_snd, int type) { + ZoneScoped; + hud_snd.m_activeSnd = nullptr; hud_snd.sounds.clear(); @@ -31,6 +33,8 @@ void HUD_SOUND_ITEM::LoadSound(LPCSTR section, LPCSTR line, HUD_SOUND_ITEM& hud_ void HUD_SOUND_ITEM::LoadSound(LPCSTR section, LPCSTR line, ref_sound& snd, int type, float* volume, float* delay) { + ZoneScoped; + LPCSTR str = pSettings->r_string(section, line); string256 buf_str; @@ -65,6 +69,8 @@ void HUD_SOUND_ITEM::LoadSound(LPCSTR section, LPCSTR line, ref_sound& snd, int void HUD_SOUND_ITEM::DestroySound(HUD_SOUND_ITEM& hud_snd) { + ZoneScoped; + for (auto& sound : hud_snd.sounds) sound.snd.destroy(); @@ -110,6 +116,8 @@ void HUD_SOUND_ITEM::StopSound(HUD_SOUND_ITEM& hud_snd) //---------------------------------------------------------- HUD_SOUND_COLLECTION::~HUD_SOUND_COLLECTION() { + ZoneScoped; + for (auto& sound_item : m_sound_items) { HUD_SOUND_ITEM::StopSound(sound_item); @@ -162,6 +170,8 @@ void HUD_SOUND_COLLECTION::StopAllSounds() void HUD_SOUND_COLLECTION::LoadSound(LPCSTR section, LPCSTR line, LPCSTR alias, bool exclusive, int type) { + ZoneScoped; + R_ASSERT(NULL == FindSoundItem(alias, false)); m_sound_items.resize(m_sound_items.size() + 1); HUD_SOUND_ITEM& snd_item = m_sound_items.back(); @@ -216,6 +226,8 @@ HUD_SOUND_ITEM* HUD_SOUND_COLLECTION_LAYERED::FindSoundItem(pcstr alias, bool b_ void HUD_SOUND_COLLECTION_LAYERED::LoadSound(pcstr section, pcstr line, pcstr alias, bool exclusive, int type) { + ZoneScoped; + pcstr str = pSettings->r_string(section, line); string256 buf_str; @@ -249,6 +261,8 @@ void HUD_SOUND_COLLECTION_LAYERED::LoadSound(pcstr section, pcstr line, pcstr al void HUD_SOUND_COLLECTION_LAYERED::LoadSound(CInifile const *ini, pcstr section, pcstr line, pcstr alias, bool exclusive, int type) { + ZoneScoped; + pcstr str = ini->r_string(section, line); string256 buf_str; diff --git a/src/xrGame/Level.cpp b/src/xrGame/Level.cpp index 2f34fdfa841..cca72d6f845 100644 --- a/src/xrGame/Level.cpp +++ b/src/xrGame/Level.cpp @@ -74,6 +74,8 @@ CLevel::CLevel() DemoCS(MUTEX_PROFILE_ID(DemoCS)) #endif { + ZoneScoped; + g_bDebugEvents = strstr(Core.Params, "-debug_ge") != nullptr; game_events = xr_new(); eChangeRP = Engine.Event.Handler_Attach("LEVEL:ChangeRP", this); @@ -112,6 +114,8 @@ CLevel::CLevel() CLevel::~CLevel() { + ZoneScoped; + xr_delete(g_player_hud); xr_delete(pHUD); delete_data(hud_zones_list); @@ -245,6 +249,8 @@ bool g_bDebugEvents = false; void CLevel::cl_Process_Event(u16 dest, u16 type, NET_Packet& P) { + ZoneScoped; + // Msg("--- event[%d] for [%d]",type,dest); IGameObject* O = Objects.net_Find(dest); if (0 == O) @@ -304,6 +310,8 @@ void CLevel::cl_Process_Event(u16 dest, u16 type, NET_Packet& P) void CLevel::ProcessGameEvents() { + ZoneScoped; + // Game events { NET_Packet P; @@ -403,6 +411,8 @@ void CLevel::MakeReconnect() void CLevel::OnFrame() { + ZoneScoped; + #ifdef DEBUG DBG_RenderUpdate(); #endif @@ -578,7 +588,13 @@ void CLevel::OnFrame() } int psLUA_GCSTEP = 100; // 10 -void CLevel::script_gc() { lua_gc(GEnv.ScriptEngine->lua(), LUA_GCSTEP, psLUA_GCSTEP); } + +void CLevel::script_gc() +{ + ZoneScoped; + lua_gc(GEnv.ScriptEngine->lua(), LUA_GCSTEP, psLUA_GCSTEP); +} + #ifdef DEBUG_PRECISE_PATH void test_precise_path(); #endif @@ -589,6 +605,8 @@ extern Flags32 dbg_net_Draw_Flags; void CLevel::OnRender() { + ZoneScoped; + GEnv.Render->BeforeWorldRender(); //--#SM+#-- +SecondVP+ #ifdef DEBUG @@ -723,6 +741,8 @@ void CLevel::OnRender() void CLevel::OnEvent(EVENT E, u64 P1, u64 /**P2**/) { + ZoneScoped; + if (E == eEntitySpawn) { char Name[128]; @@ -821,6 +841,8 @@ void CLevel::RemoveObject_From_4CrPr(CGameObject* pObj) void CLevel::make_NetCorrectionPrediction() { + ZoneScoped; + m_bNeed_CrPr = false; m_bIn_CrPr = true; u64 NumPhSteps = physics_world()->StepsNum(); diff --git a/src/xrGame/Level_Bullet_Manager.cpp b/src/xrGame/Level_Bullet_Manager.cpp index 29d83ac61ab..29872c6fd09 100644 --- a/src/xrGame/Level_Bullet_Manager.cpp +++ b/src/xrGame/Level_Bullet_Manager.cpp @@ -101,6 +101,8 @@ CBulletManager::~CBulletManager() void CBulletManager::Load() { + ZoneScoped; + char const* bullet_manager_sect = "bullet_manager"; if (!IsGameTypeSingle()) { @@ -202,6 +204,8 @@ void CBulletManager::AddBullet(const Fvector& position, const Fvector& direction void CBulletManager::UpdateWorkload() { + ZoneScoped; + #ifdef DEBUG VERIFY(g_mt_config.test(mtBullets) || m_thread_id == std::this_thread::get_id()); #endif @@ -790,6 +794,8 @@ float SqrDistancePointToSegment(const Fvector& pt, const Fvector& orig, const Fv void CBulletManager::Render() { + ZoneScoped; + #ifdef DEBUG if (g_bDrawBulletHit && !m_bullet_points.empty()) { @@ -912,6 +918,8 @@ void CBulletManager::CommitRenderSet() // @ the end of frame } void CBulletManager::CommitEvents() // @ the start of frame { + ZoneScoped; + if (m_Events.size() > 1000) Msg("! too many bullets during single frame: %d", m_Events.size()); diff --git a/src/xrGame/Level_load.cpp b/src/xrGame/Level_load.cpp index b7a879f4309..b23ad124fb9 100644 --- a/src/xrGame/Level_load.cpp +++ b/src/xrGame/Level_load.cpp @@ -13,6 +13,8 @@ bool CLevel::Load_GameSpecific_Before() { + ZoneScoped; + // AI space g_pGamePersistent->LoadTitle("st_loading_ai_objects"); string_path fn_game; @@ -33,11 +35,15 @@ bool CLevel::Load_GameSpecific_Before() bool CLevel::Load_GameSpecific_After() { + ZoneScoped; + R_ASSERT(m_StaticParticles.empty()); // loading static particles string_path fn_game; if (FS.exist(fn_game, "$level$", "level.ps_static")) { + ZoneScopedN("Load static particles"); + IReader* F = FS.r_open(fn_game); CParticlesObject* pStaticParticles; u32 chunk = 0; @@ -102,6 +108,8 @@ bool CLevel::Load_GameSpecific_After() // loading random (around player) sounds if (pSettings->section_exist("sounds_random")) { + ZoneScopedN("Load random sounds"); + CInifile::Sect& S = pSettings->r_section("sounds_random"); Sounds_Random.reserve(S.Data.size()); for (const auto& I : S.Data) @@ -114,6 +122,7 @@ bool CLevel::Load_GameSpecific_After() if (FS.exist(fn_game, "$level$", "level.fog_vol")) { + ZoneScopedN("Load fog volume"); IReader* F = FS.r_open(fn_game); u16 version = F->r_u16(); if (version == 2) @@ -185,6 +194,8 @@ bool CLevel::Load_GameSpecific_CFORM_Deserialize(IReader& reader) void CLevel::Load_GameSpecific_CFORM(CDB::TRI* tris, u32 count) { + ZoneScoped; + typedef xr_vector ID_INDEX_PAIRS; ID_INDEX_PAIRS translator; translator.reserve(GMLib.CountMaterial()); diff --git a/src/xrGame/Level_network.cpp b/src/xrGame/Level_network.cpp index d42b07475da..07f3ae30157 100644 --- a/src/xrGame/Level_network.cpp +++ b/src/xrGame/Level_network.cpp @@ -319,6 +319,8 @@ void CLevel::Send(NET_Packet& P, u32 dwFlags, u32 dwTimeout) void CLevel::net_Update() { + ZoneScoped; + if (game_configured) { // If we have enought bandwidth - replicate client data on to server diff --git a/src/xrGame/Level_network_compressed_updates.cpp b/src/xrGame/Level_network_compressed_updates.cpp index ec9b5f189b6..84b35e1c39f 100644 --- a/src/xrGame/Level_network_compressed_updates.cpp +++ b/src/xrGame/Level_network_compressed_updates.cpp @@ -60,6 +60,7 @@ void CLevel::ProcessCompressedUpdate(NET_Packet& P, const Flags8& compress_type) void CLevel::init_compression() { + ZoneScoped; compression::init_ppmd_trained_stream(m_trained_stream); compression::init_lzo(m_lzo_working_memory, m_lzo_working_buffer, m_lzo_dictionary); // XXX: if client doesn't support compression, server should know about that @@ -69,6 +70,7 @@ void CLevel::init_compression() void CLevel::deinit_compression() { + ZoneScoped; if (m_trained_stream) { compression::deinit_ppmd_trained_stream(m_trained_stream); diff --git a/src/xrGame/Level_network_map_sync.cpp b/src/xrGame/Level_network_map_sync.cpp index a526635785c..528b5e83de2 100644 --- a/src/xrGame/Level_network_map_sync.cpp +++ b/src/xrGame/Level_network_map_sync.cpp @@ -9,6 +9,8 @@ static const u32 r_buffer_size = 131072; // 128 Kb void CLevel::CalculateLevelCrc32() { + ZoneScoped; + void* read_buffer = xr_alloca(r_buffer_size); Msg("* calculating checksum of level.geom"); CStreamReader* geom = FS.rs_open("$level$", "level.geom"); @@ -32,6 +34,8 @@ void CLevel::CalculateLevelCrc32() bool CLevel::IsChecksumsEqual(u32 check_sum) const { return check_sum == map_data.m_level_geom_crc32; } bool CLevel::synchronize_map_data() { + ZoneScoped; + if (!OnClient() && !IsDemoSave()) { deny_m_spawn = FALSE; @@ -82,6 +86,8 @@ bool CLevel::synchronize_map_data() bool CLevel::synchronize_client() { + ZoneScoped; + //--------------------------------------------------------------------------- if (!sended_request_connection_data) { diff --git a/src/xrGame/Level_network_messages.cpp b/src/xrGame/Level_network_messages.cpp index acc52de8d5b..392e097a0f2 100644 --- a/src/xrGame/Level_network_messages.cpp +++ b/src/xrGame/Level_network_messages.cpp @@ -57,6 +57,8 @@ static bool SimmulateNetworkLag() void CLevel::ClientReceive() { + ZoneScoped; + m_dwRPC = 0; m_dwRPS = 0; diff --git a/src/xrGame/Level_network_spawn.cpp b/src/xrGame/Level_network_spawn.cpp index 6952de7e7b5..c6ebc36599e 100644 --- a/src/xrGame/Level_network_spawn.cpp +++ b/src/xrGame/Level_network_spawn.cpp @@ -51,6 +51,8 @@ void CLevel::cl_Process_Spawn(NET_Packet& P) void CLevel::g_cl_Spawn(LPCSTR name, u8 rp, u16 flags, Fvector pos) { + ZoneScoped; + // Create CSE_Abstract* E = F_entity_Create(name); VERIFY(E); @@ -84,6 +86,8 @@ extern float debug_on_frame_gather_stats_frequency; void CLevel::g_sv_Spawn(CSE_Abstract* E) { + ZoneScoped; + // CTimer T(false); #ifdef DEBUG @@ -179,6 +183,8 @@ void CLevel::g_sv_Spawn(CSE_Abstract* E) CSE_Abstract* CLevel::spawn_item( LPCSTR section, const Fvector& position, u32 level_vertex_id, u16 parent_id, bool return_item) { + ZoneScoped; + CSE_Abstract* abstract = F_entity_Create(section); R_ASSERT3(abstract, "Cannot find item with section", section); CSE_ALifeDynamicObject* dynamic_object = smart_cast(abstract); @@ -220,6 +226,8 @@ CSE_Abstract* CLevel::spawn_item( void CLevel::ProcessGameSpawns() { + ZoneScoped; + while (!game_spawn_queue.empty()) { CSE_Abstract* E = game_spawn_queue.front(); diff --git a/src/xrGame/Level_network_start_client.cpp b/src/xrGame/Level_network_start_client.cpp index 76252367f92..c932b29f3e6 100644 --- a/src/xrGame/Level_network_start_client.cpp +++ b/src/xrGame/Level_network_start_client.cpp @@ -20,6 +20,8 @@ bool CLevel::net_Start_client(const char* options) { return false; } bool CLevel::net_start_client1() { + ZoneScoped; + g_pGamePersistent->LoadBegin(); // name_of_server string64 name_of_server = ""; @@ -44,6 +46,8 @@ bool CLevel::net_start_client1() bool CLevel::net_start_client2() { + ZoneScoped; + if (psNET_direct_connect) { Server->create_direct_client(); @@ -62,6 +66,7 @@ bool CLevel::net_start_client2() } void rescan_mp_archives() { + ZoneScoped; FS_Path* mp_archs_path = FS.get_path("$game_arch_mp$"); FS.rescan_path(mp_archs_path->m_Path, mp_archs_path->m_Flags.is(FS_Path::flRecurse)); } @@ -70,6 +75,8 @@ bool CLevel::net_start_client3() { if (connected_to_server) { + ZoneScoped; + LPCSTR level_name = NULL; LPCSTR level_ver = NULL; LPCSTR download_url = NULL; @@ -124,6 +131,8 @@ bool CLevel::net_start_client4() { if (connected_to_server) { + ZoneScoped; + // Begin spawn g_pGamePersistent->LoadTitle("st_client_spawning"); @@ -202,6 +211,8 @@ bool CLevel::net_start_client5() { if (connected_to_server) { + ZoneScoped; + // HUD // Textures @@ -222,6 +233,8 @@ bool CLevel::net_start_client6() { if (connected_to_server) { + ZoneScoped; + // Sync if (!synchronize_map_data()) return false; diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index 986554d4755..2e808fdcd6b 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -23,6 +23,8 @@ shared_str CLevel::OpenDemoFile(const char* demo_file_name) void CLevel::net_StartPlayDemo() { net_Start(m_demo_server_options.c_str(), "localhost"); } bool CLevel::net_Start(const char* op_server, const char* op_client) { + ZoneScoped; + net_start_result_total = TRUE; g_pGamePersistent->LoadBegin(); @@ -98,6 +100,8 @@ shared_str level_version(const shared_str& server_options); shared_str level_name(const shared_str& server_options); bool CLevel::net_start1() { + ZoneScoped; + // Start client and server if need it if (m_caServerOptions.size()) { @@ -142,6 +146,7 @@ bool CLevel::net_start2() { if (net_start_result_total && m_caServerOptions.size()) { + ZoneScoped; GameDescriptionData game_descr; if ((m_connect_server_err = Server->Connect(m_caServerOptions, game_descr)) != xrServer::ErrNoError) { @@ -161,6 +166,9 @@ bool CLevel::net_start3() { if (!net_start_result_total) return true; + + ZoneScoped; + // add server port if don't have one in options if (!strstr(m_caClientOptions.c_str(), "port=") && Server) { @@ -208,6 +216,7 @@ bool CLevel::net_start4() if (!net_start_result_total) return true; + ZoneScoped; g_loading_events.pop_front(); g_loading_events.push_front(LOADING_EVENT(this, &CLevel::net_start_client6)); @@ -224,6 +233,7 @@ bool CLevel::net_start5() { if (net_start_result_total) { + ZoneScoped; NET_Packet NP; NP.w_begin(M_CLIENTREADY); Game().local_player->net_Export(NP, TRUE); @@ -238,6 +248,8 @@ bool CLevel::net_start5() } bool CLevel::net_start6() { + ZoneScoped; + // init bullet manager BulletManager().Clear(); BulletManager().Load(); @@ -331,6 +343,8 @@ bool CLevel::net_start6() void CLevel::InitializeClientGame(NET_Packet& P) { + ZoneScoped; + string256 game_type_name; P.r_stringZ(game_type_name); if (game && !xr_strcmp(game_type_name, game->type_name())) diff --git a/src/xrGame/MainMenu.cpp b/src/xrGame/MainMenu.cpp index c44a2531aeb..d461016b5c9 100644 --- a/src/xrGame/MainMenu.cpp +++ b/src/xrGame/MainMenu.cpp @@ -74,6 +74,8 @@ CMainMenu* MainMenu() { return (CMainMenu*)g_pGamePersistent->m_pMainMenu; }; CMainMenu::CMainMenu() { + ZoneScoped; + class CResetEventCb : public CEventNotifierCallbackWithCid { CMainMenu* m_mainmenu; @@ -170,6 +172,8 @@ CMainMenu::CMainMenu() CMainMenu::~CMainMenu() { + ZoneScoped; + Device.seqFrame.Remove(this); xr_delete(g_btnHint); @@ -494,6 +498,8 @@ bool CMainMenu::OnRenderPPUI_query() { return IsActive() && !m_Flags.test(flGame void CMainMenu::OnRender() { + ZoneScoped; + if (m_Flags.test(flGameSaveScreenshot)) return; @@ -549,6 +555,8 @@ void CMainMenu::StartStopMenu(CUIDialogWnd* pDialog, bool bDoHideIndicators) // pureFrame void CMainMenu::OnFrame() { + ZoneScoped; + if (m_Flags.test(flNeedChangeCapture)) { m_Flags.set(flNeedChangeCapture, FALSE); diff --git a/src/xrGame/PHCommander.cpp b/src/xrGame/PHCommander.cpp index 874f725a31e..d8f44201b8f 100644 --- a/src/xrGame/PHCommander.cpp +++ b/src/xrGame/PHCommander.cpp @@ -95,6 +95,8 @@ void CPHCommander::UpdateDeferred() void CPHCommander::update() { + ZoneScoped; + UpdateDeferred(); // One by one, using old style index-based cycle, diff --git a/src/xrGame/UIDialogHolder.cpp b/src/xrGame/UIDialogHolder.cpp index 2db02981009..139ce9de3bb 100644 --- a/src/xrGame/UIDialogHolder.cpp +++ b/src/xrGame/UIDialogHolder.cpp @@ -139,6 +139,8 @@ void CDialogHolder::RemoveDialogToRender(CUIWindow* pDialog) void CDialogHolder::DoRenderDialogs() { + ZoneScoped; + xr_vector::iterator it = m_dialogsToRender.begin(); for (; it != m_dialogsToRender.end(); ++it) { @@ -223,6 +225,8 @@ void CDialogHolder::StartStopMenu(CUIDialogWnd* pDialog, bool bDoHideIndicators) void CDialogHolder::OnFrame() { + ZoneScoped; + m_b_in_update = true; if (!GEnv.isDedicatedServer && GetUICursor().IsVisible() && pInput->IsCurrentInputTypeController()) diff --git a/src/xrGame/UIGameCustom.cpp b/src/xrGame/UIGameCustom.cpp index 619f532468b..6ecbbb3b687 100644 --- a/src/xrGame/UIGameCustom.cpp +++ b/src/xrGame/UIGameCustom.cpp @@ -252,6 +252,9 @@ void CUIGameCustom::Load() { if (!g_pGameLevel) return; + + ZoneScoped; + R_ASSERT(!MsgConfig); MsgConfig = xr_new(); MsgConfig->Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "ui_custom_msgs.xml"); diff --git a/src/xrGame/UIZoneMap.cpp b/src/xrGame/UIZoneMap.cpp index 8dfd304b005..71f643d0b69 100644 --- a/src/xrGame/UIZoneMap.cpp +++ b/src/xrGame/UIZoneMap.cpp @@ -20,6 +20,8 @@ void CUIZoneMap::Init(bool motionIconAttached) { + ZoneScoped; + CUIXml uiXml; uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "zone_map.xml"); diff --git a/src/xrGame/ai_space.cpp b/src/xrGame/ai_space.cpp index 5d5556e12a4..a6c1aded2df 100644 --- a/src/xrGame/ai_space.cpp +++ b/src/xrGame/ai_space.cpp @@ -36,6 +36,8 @@ CAI_Space& CAI_Space::GetInstance() void CAI_Space::init() { + ZoneScoped; + R_ASSERT(!m_inited); if (!GEnv.isDedicatedServer) @@ -56,6 +58,8 @@ void CAI_Space::init() CAI_Space::~CAI_Space() { + ZoneScoped; + if (GEnv.ScriptEngine != nullptr) { m_events_notifier.FireEvent(EVENT_SCRIPT_ENGINE_RESET); @@ -67,6 +71,8 @@ CAI_Space::~CAI_Space() void CAI_Space::RegisterScriptClasses() { + ZoneScoped; + #ifdef DBG_DISABLE_SCRIPTS return; #else @@ -99,6 +105,8 @@ void CAI_Space::RegisterScriptClasses() void CAI_Space::LoadCommonScripts() { + ZoneScoped; + #ifdef DBG_DISABLE_SCRIPTS return; #else @@ -128,6 +136,8 @@ void CAI_Space::LoadCommonScripts() void CAI_Space::SetupScriptEngine() { + ZoneScoped; + XRay::ScriptExporter::Reset(); // mark all nodes as undone GEnv.ScriptEngine->init(XRay::ScriptExporter::Export, true); RegisterScriptClasses(); @@ -137,6 +147,8 @@ void CAI_Space::SetupScriptEngine() void CAI_Space::RestartScriptEngine() { + ZoneScoped; + if (GEnv.ScriptEngine != nullptr) { m_events_notifier.FireEvent(EVENT_SCRIPT_ENGINE_RESET); @@ -155,6 +167,8 @@ void CAI_Space::RestartScriptEngine() void CAI_Space::load(LPCSTR level_name) { + ZoneScoped; + VERIFY(m_game_graph); unload(true); @@ -181,6 +195,9 @@ void CAI_Space::unload(bool reload) { if (GEnv.isDedicatedServer) return; + + ZoneScoped; + GEnv.ScriptEngine->unload(); m_doors_manager.reset(nullptr); AISpaceBase::Unload(reload); diff --git a/src/xrGame/debug_renderer_inline.h b/src/xrGame/debug_renderer_inline.h index 778ae82af62..61c0c95319c 100644 --- a/src/xrGame/debug_renderer_inline.h +++ b/src/xrGame/debug_renderer_inline.h @@ -8,7 +8,7 @@ #pragma once -IC void CDebugRenderer::render() { GEnv.DRender->Render(); } +IC void CDebugRenderer::render() { ZoneScoped; GEnv.DRender->Render(); } IC void CDebugRenderer::draw_line( const Fmatrix& matrix, const Fvector& vertex0, const Fvector& vertex1, const u32& color) { diff --git a/src/xrGame/level_debug.cpp b/src/xrGame/level_debug.cpp index 8ff9dfa3227..914410d7e01 100644 --- a/src/xrGame/level_debug.cpp +++ b/src/xrGame/level_debug.cpp @@ -36,6 +36,8 @@ void CLevelDebug::debug_info_up() void CLevelDebug::debug_info_down() { m_texttree_offs++; } void CLevelDebug::draw_debug_text() { + ZoneScoped; + int column_size = 1024 / 3; int y_start = 50; int x_start = 5; diff --git a/src/xrGame/level_sounds.cpp b/src/xrGame/level_sounds.cpp index 68fcd0ebd78..bfc7a3d505f 100644 --- a/src/xrGame/level_sounds.cpp +++ b/src/xrGame/level_sounds.cpp @@ -166,6 +166,8 @@ CLevelSoundManager::CLevelSoundManager() : m_CurrentTrack(0) { m_NextTrackTime = void CLevelSoundManager::Load() { + ZoneScoped; + // static level sounds VERIFY(m_StaticSounds.empty()); string_path fn; @@ -219,6 +221,8 @@ void CLevelSoundManager::Unload() void CLevelSoundManager::Update() { + ZoneScoped; + if (Device.Paused()) return; if (Device.dwPrecacheFrame != 0) diff --git a/src/xrGame/ui/UIGameTutorial.cpp b/src/xrGame/ui/UIGameTutorial.cpp index 2e5fbbb8e49..651a975f759 100644 --- a/src/xrGame/ui/UIGameTutorial.cpp +++ b/src/xrGame/ui/UIGameTutorial.cpp @@ -293,6 +293,8 @@ void CUISequencer::Stop() void CUISequencer::OnFrame() { + ZoneScoped; + if (!Device.b_is_Active) return; if (!IsActive()) @@ -323,6 +325,8 @@ void CUISequencer::OnFrame() void CUISequencer::OnRender() { + ZoneScoped; + if (m_UIWindow->IsShown()) m_UIWindow->Draw(); diff --git a/src/xrGame/ui/UIHudStatesWnd.cpp b/src/xrGame/ui/UIHudStatesWnd.cpp index 8376d301380..9cfcb6307e1 100644 --- a/src/xrGame/ui/UIHudStatesWnd.cpp +++ b/src/xrGame/ui/UIHudStatesWnd.cpp @@ -76,6 +76,8 @@ ALife::EInfluenceType CUIHudStatesWnd::get_indik_type(ALife::EHitType hit_type) void CUIHudStatesWnd::InitFromXml(CUIXml& xml, LPCSTR path) { + ZoneScoped; + CUIXmlInit::InitWindow(xml, path, 0, this); XML_NODE stored_root = xml.GetLocalRoot(); diff --git a/src/xrGame/ui/UIMainIngameWnd.cpp b/src/xrGame/ui/UIMainIngameWnd.cpp index 7eb7074cf35..ce485230f4d 100644 --- a/src/xrGame/ui/UIMainIngameWnd.cpp +++ b/src/xrGame/ui/UIMainIngameWnd.cpp @@ -71,6 +71,8 @@ CUIMainIngameWnd::~CUIMainIngameWnd() void CUIMainIngameWnd::Init() { + ZoneScoped; + CUIXml uiXml; uiXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, MAININGAME_XML); @@ -259,6 +261,8 @@ void CUIMainIngameWnd::Init() float UIStaticDiskIO_start_time = 0.0f; void CUIMainIngameWnd::Draw() { + ZoneScoped; + CActor* pActor = smart_cast(Level().CurrentViewEntity()); // show IO icon @@ -312,6 +316,8 @@ void CUIMainIngameWnd::SetMPChatLog(CUIWindow* pChat, CUIWindow* pLog) void CUIMainIngameWnd::Update() { + ZoneScoped; + CUIWindow::Update(); CActor* pActor = smart_cast(Level().CurrentViewEntity()); @@ -499,6 +505,8 @@ void CUIMainIngameWnd::SetFlashIconState_(EFlashingIcons type, bool enable) void CUIMainIngameWnd::InitFlashingIcons(CUIXml* node) { + ZoneScoped; + const char* const flashingIconNodeName = "flashing_icon"; int staticsCount = node->GetNodesNum("", 0, flashingIconNodeName); @@ -602,6 +610,7 @@ void CUIMainIngameWnd::UpdatePickUpItem() void CUIMainIngameWnd::OnConnected() { + ZoneScoped; UIZoneMap->SetupCurrentMap(); if (m_ui_hud_states) { @@ -612,6 +621,7 @@ void CUIMainIngameWnd::OnConnected() void CUIMainIngameWnd::OnSectorChanged(IRender_Sector::sector_id_t sector) { UIZoneMap->OnSectorChanged(sector); } void CUIMainIngameWnd::reset_ui() { + ZoneScoped; m_pPickUpItem = NULL; UIMotionIcon->ResetVisibility(); if (m_ui_hud_states) diff --git a/src/xrGame/xrServer.cpp b/src/xrGame/xrServer.cpp index d5369e3f919..f7278340b6f 100644 --- a/src/xrGame/xrServer.cpp +++ b/src/xrGame/xrServer.cpp @@ -193,6 +193,8 @@ bool g_sv_SendUpdate = false; void xrServer::Update() { + ZoneScoped; + if (Level().IsDemoPlayStarted() || Level().IsDemoPlayFinished()) return; // diabling server when demo is playing stats.Update.Begin(); @@ -335,6 +337,8 @@ void xrServer::SendUpdatePacketsToAll() void xrServer::SendUpdatesToAll() { + ZoneScoped; + if (IsGameTypeSingle()) return; @@ -1023,6 +1027,7 @@ void xrServer::create_direct_client() void xrServer::ProceedDelayedPackets() { + ZoneScoped; DelayedPackestCS.Enter(); while (!m_aDelayedPackets.empty()) { @@ -1052,6 +1057,8 @@ u8 g_sv_maxPingWarningsCount = 5; void xrServer::PerformCheckClientsForMaxPing() { + ZoneScoped; + struct MaxPingClientDisconnector { xrServer* m_owner; diff --git a/src/xrGame/xrServer_perform_GameExport.cpp b/src/xrGame/xrServer_perform_GameExport.cpp index 3c5bc81e7b4..2385b089bea 100644 --- a/src/xrGame/xrServer_perform_GameExport.cpp +++ b/src/xrGame/xrServer_perform_GameExport.cpp @@ -5,6 +5,8 @@ void xrServer::Perform_game_export() { + ZoneScoped; + struct NetExportToClientFunctor { xrServer* server_ptr; diff --git a/src/xrGame/xrServer_process_spawn.cpp b/src/xrGame/xrServer_process_spawn.cpp index 03ec8416eaf..a4cf8657944 100644 --- a/src/xrGame/xrServer_process_spawn.cpp +++ b/src/xrGame/xrServer_process_spawn.cpp @@ -12,6 +12,8 @@ CSE_Abstract* xrServer::Process_spawn( NET_Packet& P, ClientID sender, bool bSpawnWithClientsMainEntityAsParent, CSE_Abstract* tpExistedEntity) { + ZoneScoped; + // create server entity xrClientData* CL = ID_to_client(sender); CSE_Abstract* E = tpExistedEntity; diff --git a/src/xrGame/xrgame_dll_detach.cpp b/src/xrGame/xrgame_dll_detach.cpp index 7ee0b4324e5..4bb2d0b3268 100644 --- a/src/xrGame/xrgame_dll_detach.cpp +++ b/src/xrGame/xrgame_dll_detach.cpp @@ -35,6 +35,8 @@ extern void InitHudSoundSettings(); #include "xrEngine/IGame_Persistent.h" void init_game_globals() { + ZoneScoped; + InitHudSoundSettings(); if (!GEnv.isDedicatedServer) { @@ -52,6 +54,8 @@ void init_game_globals() void clean_game_globals() { + ZoneScoped; + // destroy ai space xr_delete(g_ai_space); // destroy object factory diff --git a/src/xrMaterialSystem/GameMtlLib.cpp b/src/xrMaterialSystem/GameMtlLib.cpp index 7c2ad6c795a..1e6a865bf3d 100644 --- a/src/xrMaterialSystem/GameMtlLib.cpp +++ b/src/xrMaterialSystem/GameMtlLib.cpp @@ -157,6 +157,8 @@ CGameMtlLibrary::CGameMtlLibrary() void CGameMtlLibrary::Load() { + ZoneScoped; + string_path name; if (!FS.exist(name, _game_data_, GAMEMTL_FILENAME)) { diff --git a/src/xrNetServer/NET_Client.cpp b/src/xrNetServer/NET_Client.cpp index e6dd6a5bef2..4e015344ec4 100644 --- a/src/xrNetServer/NET_Client.cpp +++ b/src/xrNetServer/NET_Client.cpp @@ -658,6 +658,8 @@ bool IPureClient::Connect(pcstr options) void IPureClient::Disconnect() { + ZoneScoped; + if (NET) NET->Close(0); diff --git a/src/xrNetServer/NET_Server.cpp b/src/xrNetServer/NET_Server.cpp index 6c500d6b5b3..9f78c70198f 100644 --- a/src/xrNetServer/NET_Server.cpp +++ b/src/xrNetServer/NET_Server.cpp @@ -612,6 +612,8 @@ HRESULT IPureServer::net_Handler(u32 dwMessageType, PVOID pMessage) void IPureServer::Flush_Clients_Buffers() { + ZoneScoped; + #if NET_LOG_PACKETS Msg("# flush server send-buf"); #endif @@ -1029,6 +1031,8 @@ bool banned_client_comparer(IBannedClient* C1, IBannedClient* C2) void IPureServer::UpdateBannedList() { + ZoneScoped; + if (!BannedAddresses.size()) return; std::sort(BannedAddresses.begin(), BannedAddresses.end(), banned_client_comparer); diff --git a/src/xrParticles/particle_actions_collection.cpp b/src/xrParticles/particle_actions_collection.cpp index 3150dcfbdf7..413df325b23 100644 --- a/src/xrParticles/particle_actions_collection.cpp +++ b/src/xrParticles/particle_actions_collection.cpp @@ -1651,10 +1651,6 @@ ICF void _mm_store_fvector(Fvector& v, const __m128 R1) void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max) { -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("PATurbulence::Execute()"); -#endif // _GPA_ENABLED - if (noise_start) { noise_start = 0; @@ -1668,12 +1664,7 @@ void PATurbulence::Execute(ParticleEffect* effect, const float dt, float& tm_max if (!p_cnt) return; -#ifdef _GPA_ENABLED - TAL_SCOPED_TASK_NAMED("PATurbulenceExecuteStream()"); - - TAL_ID rtID = TAL_MakeID(1, Core.dwFrame, 0); - TAL_AddRelationThis(TAL_RELATION_IS_CHILD_OF, rtID); -#endif // _GPA_ENABLED + ZoneScoped; pVector pV; pVector vX; diff --git a/src/xrParticles/particle_manager.cpp b/src/xrParticles/particle_manager.cpp index 491e829330e..7bdbe30badc 100644 --- a/src/xrParticles/particle_manager.cpp +++ b/src/xrParticles/particle_manager.cpp @@ -148,6 +148,8 @@ void CParticleManager::StopEffect(int effect_id, int alist_id, bool deffered) // update&render void CParticleManager::Update(int effect_id, int alist_id, float dt) { + ZoneScoped; + ParticleEffect* pe = GetEffectPtr(effect_id); ParticleActions* pa = GetActionListPtr(alist_id); diff --git a/src/xrPhysics/PHWorld.cpp b/src/xrPhysics/PHWorld.cpp index 50199c5eb10..f755d1aacd0 100644 --- a/src/xrPhysics/PHWorld.cpp +++ b/src/xrPhysics/PHWorld.cpp @@ -44,6 +44,7 @@ IPHWorld* physics_world() { return ph_world; } void create_physics_world( bool mt, CObjectSpace* os, CObjectList* lo) // IPHWorldUpdateCallbck &commander, { + ZoneScoped; ph_world = xr_new(); //&commander VERIFY(os); // VERIFY( lo ); @@ -52,6 +53,7 @@ void create_physics_world( void destroy_physics_world() { + ZoneScoped; ph_world->Destroy(); xr_delete(ph_world); } @@ -131,6 +133,8 @@ void CPHWorld::SetStep(float s) } void CPHWorld::Create(bool mt, CObjectSpace* os, CObjectList* lo) { + ZoneScoped; + LoadParams(); dWorldID phWorld = 0; m_object_space = os; @@ -184,6 +188,8 @@ dVector3 center = {level_center.x,0.f,level_center.z}; void CPHWorld::Destroy() { + ZoneScoped; + r_spatial.clear(); // xr_delete(m_commander); Mesh.Destroy(); @@ -213,6 +219,7 @@ void CPHWorld::SetGravity(float g) void CPHWorld::OnFrame() { + ZoneScoped; stats.FrameStart(); // Msg ("------------- physics: %d / %d",u32(Device.dwFrame),u32(m_steps_num)); //calculate the flight of bullets diff --git a/src/xrScriptEngine/BindingsDumper.cpp b/src/xrScriptEngine/BindingsDumper.cpp index 44859015343..b2861220340 100644 --- a/src/xrScriptEngine/BindingsDumper.cpp +++ b/src/xrScriptEngine/BindingsDumper.cpp @@ -373,6 +373,7 @@ BindingsDumper::BindingsDumper() void BindingsDumper::Dump(lua_State* luaState, IWriter* outStream, const Options& opt) { + ZoneScoped; ls = luaState; options = opt; shiftLevel = 0; diff --git a/src/xrScriptEngine/ScriptExporter.cpp b/src/xrScriptEngine/ScriptExporter.cpp index 08b30209735..17d3a29fdbf 100644 --- a/src/xrScriptEngine/ScriptExporter.cpp +++ b/src/xrScriptEngine/ScriptExporter.cpp @@ -52,6 +52,9 @@ void ScriptExporter::Node::Export(lua_State* luaState) #endif return; } + + ZoneScoped; + // export dependencies recursively for (size_t i = 0; i < depCount; i++) { @@ -120,6 +123,7 @@ void ScriptExporter::Node::InsertAfter(Node* target, Node* node) void ScriptExporter::Export(lua_State* luaState) { + ZoneScoped; #ifdef CONFIG_SCRIPT_ENGINE_LOG_EXPORTS Msg("* ScriptExporter: total nodes: %zu", Node::GetCount()); for (auto node = Node::GetFirst(); node; node = node->GetNext()) @@ -137,6 +141,7 @@ void ScriptExporter::Export(lua_State* luaState) void ScriptExporter::Reset() { + ZoneScoped; for (auto node = Node::GetFirst(); node; node = node->GetNext()) node->Reset(); } diff --git a/src/xrScriptEngine/script_engine.cpp b/src/xrScriptEngine/script_engine.cpp index cd25e2c69a6..efd51f1494a 100644 --- a/src/xrScriptEngine/script_engine.cpp +++ b/src/xrScriptEngine/script_engine.cpp @@ -108,6 +108,7 @@ string4096 CScriptEngine::g_ca_stdout; void CScriptEngine::reinit() { + ZoneScoped; stateMapLock.Enter(); stateMap.reserve(32); // 32 lua states should be enough stateMapLock.Leave(); @@ -930,6 +931,8 @@ struct luajit void CScriptEngine::init(ExporterFunc exporterFunc, bool loadGlobalNamespace) { + ZoneScoped; + #ifdef USE_LUA_STUDIO bool lua_studio_connected = !!m_lua_studio_world; if (lua_studio_connected) diff --git a/src/xrServerEntities/object_factory_inline.h b/src/xrServerEntities/object_factory_inline.h index 4708b98e5f9..2d3f043adfb 100644 --- a/src/xrServerEntities/object_factory_inline.h +++ b/src/xrServerEntities/object_factory_inline.h @@ -142,6 +142,8 @@ IC void CObjectFactory::actualize() const if (m_actual) return; + ZoneScoped; + m_actual = true; std::sort(m_clsids.begin(), m_clsids.end(), CObjectItemPredicate()); } diff --git a/src/xrServerEntities/object_factory_register.cpp b/src/xrServerEntities/object_factory_register.cpp index 7f7fb541c2a..93505a3e9f9 100644 --- a/src/xrServerEntities/object_factory_register.cpp +++ b/src/xrServerEntities/object_factory_register.cpp @@ -189,6 +189,8 @@ void CObjectFactory::register_classes() { + ZoneScoped; + #ifndef NO_XR_GAME // client entities add(CLSID_GAME_LEVEL, "level"); diff --git a/src/xrServerEntities/object_factory_script.cpp b/src/xrServerEntities/object_factory_script.cpp index 7277d2574dd..82f0f5e22e4 100644 --- a/src/xrServerEntities/object_factory_script.cpp +++ b/src/xrServerEntities/object_factory_script.cpp @@ -15,6 +15,8 @@ void CObjectFactory::register_script_class(LPCSTR client_class, LPCSTR server_class, LPCSTR clsid, LPCSTR script_clsid) { + ZoneScoped; + #ifdef CONFIG_OBJECT_FACTORY_LOG_REGISTER Msg("* CObjectFactory: registering script class '%s'", clsid); #endif @@ -37,6 +39,8 @@ void CObjectFactory::register_script_class(LPCSTR client_class, LPCSTR server_cl void CObjectFactory::register_script_class(LPCSTR unknown_class, LPCSTR clsid, LPCSTR script_clsid) { + ZoneScoped; + #ifdef CONFIG_OBJECT_FACTORY_LOG_REGISTER Msg("* CObjectFactory: registering script class '%s'", clsid); #endif @@ -61,6 +65,8 @@ struct CInternal void CObjectFactory::register_script() const { + ZoneScoped; + actualize(); luabind::class_ instance("clsid"); diff --git a/src/xrSound/Sound.cpp b/src/xrSound/Sound.cpp index b4707943095..1b057ee2f40 100644 --- a/src/xrSound/Sound.cpp +++ b/src/xrSound/Sound.cpp @@ -8,6 +8,8 @@ ISoundScene* DefaultSoundScene{}; void CSoundManager::CreateDevicesList() { + ZoneScoped; + static bool noSound = strstr(Core.Params, "-nosound"); SoundRender = xr_new(*this); @@ -23,6 +25,8 @@ void CSoundManager::CreateDevicesList() void CSoundManager::Create() { + ZoneScoped; + if (SoundRender->bPresent) { env_load(); @@ -32,6 +36,8 @@ void CSoundManager::Create() void CSoundManager::Destroy() { + ZoneScoped; + GEnv.Sound = nullptr; SoundRender->_clear(); diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 1eda9d81324..99167e7a9fd 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -32,6 +32,8 @@ void CSoundRender_CoreA::_initialize_devices_list() void CSoundRender_CoreA::_initialize() { + ZoneScoped; + if (!pDeviceList) { VERIFY2(pDeviceList, "Probably incorrect initialization order. Make sure to call _initialize_devices_list() first."); diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index e735dae9431..91095ee1085 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -11,6 +11,8 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector& N, const Fvector& R) { + ZoneScoped; + if (0 == bReady) return; Stats.Update.Begin(); @@ -80,6 +82,8 @@ void CSoundRender_Core::update(const Fvector& P, const Fvector& D, const Fvector void CSoundRender_Core::render() { + ZoneScoped; + isLocked = true; Stats.Render.Begin(); diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 9826a3c446f..1207f472721 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -147,6 +147,8 @@ void CSoundRender_Emitter::fill_data(void* dest, u32 offset, u32 size) const void CSoundRender_Emitter::fill_block(void* ptr, u32 size) { + ZoneScoped; + // Msg ("stream: %10s - [%X]:%d, p=%d, t=%d",*source->fname,ptr,size,position,source->dwBytesTotal); u8* dest = (u8*)(ptr); const u32 dwBytesTotal = get_bytes_total(); diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index f98d7f5d431..a71118d004d 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -23,6 +23,8 @@ inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTi void CSoundRender_Emitter::update(float fTime, float dt) { + ZoneScoped; + VERIFY2(!!(owner_data) || (!(owner_data) && (m_current_state == stStopped)), "owner"); VERIFY2(owner_data ? *(int*)(&owner_data->feedback) : 1, "owner"); diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index ee08ce00485..8cdb6c3d107 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -10,6 +10,8 @@ CSoundRender_Scene::~CSoundRender_Scene() { + ZoneScoped; + stop_emitters(); set_geometry_occ(nullptr, {}); @@ -51,6 +53,8 @@ void CSoundRender_Scene::set_geometry_occ(CDB::MODEL* M, const Fbox& /*aabb*/) void CSoundRender_Scene::set_geometry_som(IReader* I) { + ZoneScoped; + xr_delete(geom_SOM); if (nullptr == I) return; @@ -96,6 +100,8 @@ void CSoundRender_Scene::set_geometry_som(IReader* I) void CSoundRender_Scene::set_geometry_env(IReader* I) { + ZoneScoped; + xr_delete(geom_ENV); if (nullptr == I) return; @@ -224,6 +230,8 @@ CSoundRender_Emitter* CSoundRender_Scene::i_play(ref_sound& S, u32 flags, float void CSoundRender_Scene::update() { + ZoneScoped; + s_events_prev_count = s_events.size(); for (auto& [sound, range] : s_events) @@ -234,6 +242,8 @@ void CSoundRender_Scene::update() void CSoundRender_Scene::object_relcase(IGameObject* obj) { + ZoneScoped; + if (obj) { for (const auto& emit : s_emitters) @@ -248,6 +258,8 @@ void CSoundRender_Scene::object_relcase(IGameObject* obj) float CSoundRender_Scene::get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion) { + ZoneScoped; + float occ_value = 1.f; if (nullptr != geom_SOM) @@ -278,6 +290,8 @@ float CSoundRender_Scene::get_occlusion_to(const Fvector& hear_pt, const Fvector float CSoundRender_Scene::get_occlusion(const Fvector& P, float R, Fvector* occ) { + ZoneScoped; + float occ_value = 1.f; // Calculate RAY params diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 4648822232d..814ac28f234 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -45,6 +45,7 @@ void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) if (!wave) attach(); + ZoneScoped; std::lock_guard guard{ read_lock }; // seek @@ -162,6 +163,8 @@ void CSoundRender_Source::detach() bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) { + ZoneScoped; + pname = pName; attach(); diff --git a/src/xrUICore/ui_base.cpp b/src/xrUICore/ui_base.cpp index 6a7dd599d06..783b3731fad 100644 --- a/src/xrUICore/ui_base.cpp +++ b/src/xrUICore/ui_base.cpp @@ -314,7 +314,12 @@ void UICore::pp_stop() g_current_font_scale.set(1.0f, 1.0f); } -void UICore::RenderFont() { Font().Render(); } +void UICore::RenderFont() +{ + ZoneScoped; + Font().Render(); +} + bool UICore::is_widescreen() { return (Device.dwWidth) / float(Device.dwHeight) > (UI_BASE_WIDTH / UI_BASE_HEIGHT + 0.01f); From 43caec7a090c01c0ce15333b343687ef37ddfbb2 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 10:11:29 +0500 Subject: [PATCH 323/497] Layers/xrRenderPC_R4/stdafx.h: use more generic tracy include path --- src/Layers/xrRenderPC_R4/stdafx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Layers/xrRenderPC_R4/stdafx.h b/src/Layers/xrRenderPC_R4/stdafx.h index dc02089dc33..2b463b7d579 100644 --- a/src/Layers/xrRenderPC_R4/stdafx.h +++ b/src/Layers/xrRenderPC_R4/stdafx.h @@ -33,7 +33,7 @@ #define HAS_DX11_3 #endif -#include +#include #include "Layers/xrRenderDX11/CommonTypes.h" From 1b1ede18d84f08c5f43dee2c8ece52bc0579cc1f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 10:39:31 +0500 Subject: [PATCH 324/497] xrRender_R4: Added more tracy GPU events --- src/Layers/xrRender_R2/r3_R_rain.cpp | 12 ++++++++++++ src/Layers/xrRender_R2/render_phase_sun.cpp | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Layers/xrRender_R2/r3_R_rain.cpp b/src/Layers/xrRender_R2/r3_R_rain.cpp index d3dc0fb2ac3..455245d3129 100644 --- a/src/Layers/xrRender_R2/r3_R_rain.cpp +++ b/src/Layers/xrRender_R2/r3_R_rain.cpp @@ -297,6 +297,10 @@ void render_rain::render() { if (o.active) { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_rain::render"); +#endif + auto& dsgraph = RImplementation.get_context(context_id); // Render shadow-map @@ -320,6 +324,9 @@ void render_rain::flush() { if (o.active) { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - submit and release"); +#endif auto& dsgraph = RImplementation.get_context(context_id); dsgraph.cmd_list.submit(); @@ -327,6 +334,11 @@ void render_rain::flush() } auto& cmd_list_imm = RImplementation.get_imm_context().cmd_list; + +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - accumulate"); +#endif + cmd_list_imm.Invalidate(); // Restore XForms diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index 611aae55ea0..835975b4256 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -315,6 +315,10 @@ void render_sun::render() { for (u32 cascade_ind = range.begin(); cascade_ind != range.end(); ++cascade_ind) { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_sun::render_cascade"); +#endif + auto& dsgraph = RImplementation.get_context(contexts_ids[cascade_ind]); bool bNormal = !dsgraph.mapNormalPasses[0][0].empty() || !dsgraph.mapMatrixPasses[0][0].empty(); @@ -394,6 +398,10 @@ void render_sun::flush() void render_sun::accumulate_cascade(u32 cascade_ind) { +#if defined(USE_DX11) + TracyD3D11Zone(HW.profiler_ctx, "render_sun::accumulate_cascade"); +#endif + auto& dsgraph = RImplementation.get_context(contexts_ids[cascade_ind]); if ((cascade_ind == SE_SUN_NEAR) && RImplementation.Target->use_minmax_sm_this_frame()) From f82addb44434f4acc0f215f11f6012105c7e56e0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 13:36:28 +0500 Subject: [PATCH 325/497] A bit improve splash screen startup times --- src/xrEngine/x_ray.cpp | 17 ++++++----------- src/xrEngine/x_ray.h | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 6528251de4c..1137367ffdb 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -534,13 +534,9 @@ void CApplication::ShowSplash(bool topmost) flags |= SDL_WINDOW_ALWAYS_ON_TOP; #endif - SDL_Surface* surface = m_surfaces.front(); + const SDL_Surface* surface = m_surfaces.front(); m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, surface->w, surface->h, flags); - - const auto current = SDL_GetWindowSurface(m_window); - SDL_BlitSurface(surface, nullptr, current, nullptr); SDL_ShowWindow(m_window); - SDL_UpdateWindowSurface(m_window); m_splash_thread = Threading::RunThread("Splash Thread", &CApplication::SplashProc, this); SDL_PumpEvents(); @@ -548,23 +544,22 @@ void CApplication::ShowSplash(bool topmost) void CApplication::SplashProc() { - while (true) + do { - if (m_should_exit.Wait(SPLASH_FRAMERATE)) - break; - - if (m_surfaces.size() > 1) + if (m_surfaces.size() > 1 || m_current_surface_idx == size_t(-1)) { if (m_current_surface_idx >= m_surfaces.size()) m_current_surface_idx = 0; + ZoneScopedN("Update splash image"); const auto current = SDL_GetWindowSurface(m_window); const auto next = m_surfaces[m_current_surface_idx++]; // It's important to have postfix increment! SDL_BlitSurface(next, nullptr, current, nullptr); SDL_UpdateWindowSurface(m_window); + //SDL_PumpEvents(); } UpdateDiscordStatus(); - } + } while (!m_should_exit.Wait(SPLASH_FRAMERATE)); } void CApplication::HideSplash() diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index f573164c98b..5a720b26781 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -20,7 +20,7 @@ class ENGINE_API CApplication final std::thread m_splash_thread; Event m_should_exit; - size_t m_current_surface_idx{}; + size_t m_current_surface_idx{ size_t(-1) }; xr_vector m_surfaces; private: From d381f457b4251442ce7c1551c303b8239b997aba Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 13:38:38 +0500 Subject: [PATCH 326/497] xrEngine/device.cpp: execute all tasks, and only then it's allowed to sleep --- src/xrEngine/device.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 26b84fae55a..fc531ed80ef 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -320,6 +320,11 @@ void CRenderDevice::ProcessFrame() DoRender(); + while (!secondaryTasksExecuted.load(std::memory_order_acquire)) + TaskScheduler->ExecuteOneTask(); + + secondaryTasksExecuted.store(false, std::memory_order_relaxed); + const u64 frameEndTime = TimerGlobal.GetElapsed_ms(); const u64 frameTime = frameEndTime - frameStartTime; @@ -334,10 +339,6 @@ void CRenderDevice::ProcessFrame() if (frameTime < updateDelta) Sleep(updateDelta - frameTime); - while (!secondaryTasksExecuted.load(std::memory_order_acquire)) - TaskScheduler->ExecuteOneTask(); - - secondaryTasksExecuted.store(false, std::memory_order_relaxed); if (!b_is_Active) Sleep(1); From 6446f1f87dd3a5411e5fffc248a1f8e8e1fa87c7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 14:52:43 +0500 Subject: [PATCH 327/497] xrCore/log.cpp: removed unused log timing --- src/xrCore/log.cpp | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/src/xrCore/log.cpp b/src/xrCore/log.cpp index 409da72389e..8af10032561 100644 --- a/src/xrCore/log.cpp +++ b/src/xrCore/log.cpp @@ -20,7 +20,6 @@ LogCallback LogCB = nullptr; bool ForceFlushLog = false; IWriter* LogWriter = nullptr; -//size_t CachedLog = 0; void FlushLog() { @@ -29,7 +28,6 @@ void FlushLog() logCS.Enter(); if (LogWriter) LogWriter->flush(); - //CachedLog = 0; logCS.Leave(); } } @@ -49,29 +47,10 @@ void AddOne(pcstr split) if (LogWriter) { -#ifdef USE_LOG_TIMING - char buf[64]; - char curTime[64]; - - auto now = std::chrono::system_clock::now(); - auto time = std::chrono::system_clock::to_time_t(now); - auto ms = std::chrono::duration_cast(now.time_since_epoch()) - - std::chrono::duration_cast(now.time_since_epoch()); - - std::strftime(buf, sizeof(buf), "%H:%M:%S", std::localtime(&time)); - int len = xr_sprintf(curTime, 64, "[%s.%03lld] ", buf, ms.count()); - - LogWriter->w_printf("%s%s\r\n", curTime, split); - CachedLog += len; -#else LogWriter->w_printf("%s\r\n", split); -#endif - //CachedLog += xr_strlen(split) + 2; - if (ForceFlushLog /*|| CachedLog >= 32768*/) + if (ForceFlushLog) FlushLog(); - - //-RvP } logCS.Leave(); @@ -251,21 +230,10 @@ void CreateLog(bool nl) abort(); } -#ifdef USE_LOG_TIMING - time_t t = time(nullptr); - tm* ti = localtime(&t); - char buf[64]; - strftime(buf, 64, "[%x %X]\t", ti); -#endif - for (u32 it = 0; it < LogFile.size(); it++) { pcstr s = LogFile[it].c_str(); -#ifdef USE_LOG_TIMING - LogWriter->w_printf("%s%s\r\n", buf, s ? s : ""); -#else LogWriter->w_printf("%s\r\n", s ? s : ""); -#endif } LogWriter->flush(); } From 89afdaa101c9030934b0d3ad04c4913fe64d56c7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 15:10:48 +0500 Subject: [PATCH 328/497] xrCore/log.cpp: improve mutex locking with RAII --- src/xrCore/log.cpp | 52 ++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/xrCore/log.cpp b/src/xrCore/log.cpp index 8af10032561..280fc186ca7 100644 --- a/src/xrCore/log.cpp +++ b/src/xrCore/log.cpp @@ -23,18 +23,17 @@ IWriter* LogWriter = nullptr; void FlushLog() { - if (!no_log) - { - logCS.Enter(); - if (LogWriter) - LogWriter->flush(); - logCS.Leave(); - } + if (no_log) + return; + + ScopeLock scope{ &logCS }; + if (LogWriter) + LogWriter->flush(); } void AddOne(pcstr split) { - logCS.Enter(); + ScopeLock scope{ &logCS }; OutputDebugString(split); OutputDebugString("\n"); @@ -52,8 +51,6 @@ void AddOne(pcstr split) if (ForceFlushLog) FlushLog(); } - - logCS.Leave(); } void Log(pcstr s) @@ -198,6 +195,7 @@ void Log(pcstr msg, const Fmatrix& dop) void LogWinErr(pcstr msg, long err_code) { Msg("%s: %s", msg, xrDebug::ErrorToString(err_code)); } LogCallback SetLogCB(const LogCallback& cb) { + ScopeLock scope{ &logCS }; const LogCallback result = LogCB; LogCB = cb; return (result); @@ -214,28 +212,26 @@ void CreateLog(bool nl) strconcat(sizeof(log_file_name), log_file_name, Core.ApplicationName, "_", Core.UserName, ".log"); if (FS.path_exist("$logs$")) FS.update_path(logFName, "$logs$", log_file_name); - if (!no_log) - { - // Alun: Backup existing log - const xr_string backup_logFName = EFS.ChangeFileExt(logFName, ".bkp"); - FS.file_rename(logFName, backup_logFName.c_str(), true); - //-Alun - LogWriter = FS.w_open(logFName); - if (LogWriter == nullptr) - { -#if defined(XR_PLATFORM_WINDOWS) - MessageBox(nullptr, "Can't create log file.", "Error", MB_ICONERROR); -#endif - abort(); - } + if (no_log) + return; + + // Alun: Backup existing log + const xr_string backup_logFName = EFS.ChangeFileExt(logFName, ".bkp"); + FS.file_rename(logFName, backup_logFName.c_str(), true); + //-Alun + if (const auto w = FS.w_open(logFName)) + { for (u32 it = 0; it < LogFile.size(); it++) { - pcstr s = LogFile[it].c_str(); - LogWriter->w_printf("%s\r\n", s ? s : ""); + cpcstr s = LogFile[it].c_str(); + w->w_printf("%s\r\n", s ? s : ""); } - LogWriter->flush(); + w->flush(); + + ScopeLock scope{ &logCS }; + LogWriter = w; } if (strstr(Core.Params, "-force_flushlog")) @@ -246,6 +242,8 @@ void CloseLog(void) { ZoneScoped; FlushLog(); + + ScopeLock scope{ &logCS }; if (LogWriter) FS.w_close(LogWriter); From 83cbe25d1d3288407334520dc5c8c82b62239423 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 15:11:22 +0500 Subject: [PATCH 329/497] xrCore: set log callback explicitly and separately from Core initialization --- src/utils/mp_balancer/entry_point.cpp | 2 +- src/utils/mp_configs_verifyer/entry_point.cpp | 3 ++- src/utils/mp_screenshots_info/entry_point.cpp | 3 ++- src/utils/xrCompress/main.cpp | 2 +- src/xrCore/xrCore.cpp | 3 +-- src/xrCore/xrCore.h | 2 +- src/xrEngine/x_ray.cpp | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/utils/mp_balancer/entry_point.cpp b/src/utils/mp_balancer/entry_point.cpp index 5ac616eecc2..8a4578f0aa5 100644 --- a/src/utils/mp_balancer/entry_point.cpp +++ b/src/utils/mp_balancer/entry_point.cpp @@ -5,7 +5,7 @@ void main(int argc, char* argv[]) { xrDebug::Initialize(false); - Core.Initialize("mp_ballancer", nullptr, NULL, TRUE, "fsgame.ltx"); + Core.Initialize("mp_balancer", nullptr, true, "fsgame.ltx"); SetConsoleOutputCP(1251); diff --git a/src/utils/mp_configs_verifyer/entry_point.cpp b/src/utils/mp_configs_verifyer/entry_point.cpp index 60f8d7442a0..35f5d142298 100644 --- a/src/utils/mp_configs_verifyer/entry_point.cpp +++ b/src/utils/mp_configs_verifyer/entry_point.cpp @@ -146,7 +146,8 @@ void run_configs_verifyer_server() void initialize_core() { - Core.Initialize("mp_configs_info", nullptr, LogCallback(xrcore_log_cb, nullptr), TRUE, "fsgame4mpu.ltx"); + Core.Initialize("mp_configs_info", nullptr, true, "fsgame4mpu.ltx"); + SetLogCB({ xrcore_log_cb, nullptr }); string_path fname; FS.update_path(fname, "$game_config$", "system.ltx"); diff --git a/src/utils/mp_screenshots_info/entry_point.cpp b/src/utils/mp_screenshots_info/entry_point.cpp index 2c0abb10119..dc9e517c49a 100644 --- a/src/utils/mp_screenshots_info/entry_point.cpp +++ b/src/utils/mp_screenshots_info/entry_point.cpp @@ -67,7 +67,8 @@ int main(int argc, char** argv) return EXIT_FAILURE; } printf("Initializing core...\n"); - Core.Initialize("mp_screenshots_info", nullptr, LogCallback(xrcore_log_cb, nullptr), TRUE, "fsgame4mpu.ltx"); + Core.Initialize("mp_screenshots_info", nullptr, true, "fsgame4mpu.ltx"); + SetLogCB({ xrcore_log_cb, nullptr }); #ifdef DEBUG if (strstr(argv[1], "--gen_params")) diff --git a/src/utils/xrCompress/main.cpp b/src/utils/xrCompress/main.cpp index f137a26a713..ad57a582f74 100644 --- a/src/utils/xrCompress/main.cpp +++ b/src/utils/xrCompress/main.cpp @@ -8,7 +8,7 @@ int __cdecl main(int argc, char* argv[]) cpcstr params = GetCommandLine(); xrDebug::Initialize(params); - Core.Initialize("xrCompress", nullptr, nullptr, false); + Core.Initialize("xrCompress", nullptr, false); printf("\n\n"); diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 4d365c97bf2..0c4faf001a0 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -171,7 +171,7 @@ void xrCore::PrintBuildInfo() Log(buf); // "%s build %s from commit[%s] branch[%s] (built by %s)" } -void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback cb, bool init_fs, pcstr fs_fname, bool plugin) +void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, pcstr fs_fname, bool plugin) { ZoneScoped; Threading::SetCurrentThreadName("Primary thread"); @@ -317,7 +317,6 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, LogCallback c FS._initialize(flags, nullptr, fs_fname); EFS._initialize(); } - SetLogCB(cb); init_counter++; } diff --git a/src/xrCore/xrCore.h b/src/xrCore/xrCore.h index befe0ba578d..69b0a73f5ae 100644 --- a/src/xrCore/xrCore.h +++ b/src/xrCore/xrCore.h @@ -123,7 +123,7 @@ class XRCORE_API xrCore bool PluginMode; void Initialize( - pcstr ApplicationName, pcstr commandLine = nullptr, LogCallback cb = nullptr, bool init_fs = true, pcstr fs_fname = nullptr, bool plugin = false); + pcstr ApplicationName, pcstr commandLine = nullptr, bool init_fs = true, pcstr fs_fname = nullptr, bool plugin = false); void _destroy(); u32 GetBuildId() const { return buildId; } diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 1137367ffdb..5399986767f 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -288,7 +288,7 @@ CApplication::CApplication(pcstr commandLine) sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); } - Core.Initialize("OpenXRay", commandLine, nullptr, true, *fsgame ? fsgame : nullptr); + Core.Initialize("OpenXRay", commandLine, true, *fsgame ? fsgame : nullptr); #ifdef PROFILE_TASK_SYSTEM const auto task = [](const TaskRange&){}; From 336a64b68d3979f362936521db00a0888854c6b0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 1 May 2024 15:16:25 +0500 Subject: [PATCH 330/497] Set primary thread name in the CApplication constructor --- src/xrCore/xrCore.cpp | 1 - src/xrEngine/x_ray.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 0c4faf001a0..afb168a0e47 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -174,7 +174,6 @@ void xrCore::PrintBuildInfo() void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, pcstr fs_fname, bool plugin) { ZoneScoped; - Threading::SetCurrentThreadName("Primary thread"); xr_strcpy(ApplicationName, _ApplicationName); PrintBuildInfo(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 5399986767f..b1ff4689cfc 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -223,6 +223,7 @@ constexpr pcstr APPLICATION_SHUTDOWN = "Application shutdown"; CApplication::CApplication(pcstr commandLine) { + Threading::SetCurrentThreadName("Primary thread"); FrameMarkStart(APPLICATION_STARTUP); xrDebug::Initialize(commandLine); From 1b11c58a01d5f7f580679d5ff60e967872282f97 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 08:34:33 +0500 Subject: [PATCH 331/497] During initialization, initialize input and sound devices in parallel --- src/xrEngine/x_ray.cpp | 35 ++++++++++++++++++++--------------- src/xrEngine/xr_input.cpp | 1 - 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index b1ff4689cfc..da634673732 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -178,16 +178,6 @@ void InitConsole() } } -void InitInput() -{ - bool captureInput = !strstr(Core.Params, "-i"); - pInput = xr_new(captureInput); -} - -void destroyInput() { xr_delete(pInput); } -void InitSoundDeviceList() { Engine.Sound.CreateDevicesList(); } -void InitSound() { Engine.Sound.Create(); } -void destroySound() { Engine.Sound.Destroy(); } void destroySettings() { ZoneScoped; @@ -319,6 +309,18 @@ CApplication::CApplication(pcstr commandLine) return; #endif + + const auto& inputTask = TaskScheduler->AddTask("InitInput", [](Task&, void*) + { + const bool captureInput = !strstr(Core.Params, "-i"); + pInput = xr_new(captureInput); + }); + + const auto& createSoundDevicesList = TaskScheduler->AddTask("CSoundManager::CreateDevicesList()", [](Task&, void*) + { + Engine.Sound.CreateDevicesList(); + }); + *g_sLaunchOnExit_app = 0; *g_sLaunchOnExit_params = 0; @@ -334,7 +336,7 @@ CApplication::CApplication(pcstr commandLine) Device.InitializeImGui(); Device.FillVideoModes(); - InitInput(); + TaskScheduler->Wait(inputTask); InitConsole(); Engine.Initialize(); @@ -352,9 +354,8 @@ CApplication::CApplication(pcstr commandLine) } #endif - InitSoundDeviceList(); execUserScript(); - InitSound(); + Engine.Sound.Create(); // ...command line for auto start pcstr startArgs = strstr(Core.Params, "-start "); @@ -378,6 +379,10 @@ CApplication::CApplication(pcstr commandLine) if (!g_pGamePersistent) Console->Show(); + // Wait for tasks just for sanity, + // e.g. in case of singlethreaded CPU + TaskScheduler->Wait(createSoundDevicesList); + FrameMarkEnd(APPLICATION_STARTUP); } @@ -391,7 +396,7 @@ CApplication::~CApplication() Engine.Event.Dump(); // Destroying - destroyInput(); + xr_delete(pInput); destroySettings(); LALib.OnDestroy(); @@ -400,7 +405,7 @@ CApplication::~CApplication() Device.CleanupVideoModes(); Device.DestroyImGui(); - destroySound(); + Engine.Sound.Destroy(); Device.Destroy(); Engine.Destroy(); diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index 66ff750a3d2..9b91893cbef 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -52,7 +52,6 @@ CInput::CInput(const bool exclusive) //===================== Dummy pack iCapture(&dummyController); - SDL_StopTextInput(); // sanity SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); // We need to handle it manually Device.seqAppActivate.Add(this); From 94c7c1281900d000312fd437310bfa8d5fc7fe74 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 08:49:57 +0500 Subject: [PATCH 332/497] Removed names from task manager tasks They were unused anyway and we can use tracy zones to determine names. Without tracy, we can use debug symbols and stack traces in the debugger. --- src/Layers/xrRender/HOM.cpp | 1 + src/Layers/xrRender_R2/r2.cpp | 2 +- src/Layers/xrRender_R2/r2.h | 4 ++-- src/Layers/xrRender_R2/r2_R_lights.cpp | 4 +++- src/xrCore/Threading/ParallelFor.hpp | 8 +++---- src/xrCore/Threading/Task.cpp | 16 ++++++------- src/xrCore/Threading/Task.hpp | 13 ++++++----- src/xrCore/Threading/TaskManager.cpp | 32 +++++++++++++------------- src/xrCore/Threading/TaskManager.hpp | 16 ++++++------- src/xrEngine/x_ray.cpp | 6 ++--- src/xrGame/GamePersistent.cpp | 2 +- src/xrSound/SoundRender_Target.cpp | 4 ++-- 12 files changed, 56 insertions(+), 52 deletions(-) diff --git a/src/Layers/xrRender/HOM.cpp b/src/Layers/xrRender/HOM.cpp index 929f2d7cb89..215dc2e3d4b 100644 --- a/src/Layers/xrRender/HOM.cpp +++ b/src/Layers/xrRender/HOM.cpp @@ -268,6 +268,7 @@ void CHOM::Render(CFrustum& base) void CHOM::MT_RENDER(Task& /*thisTask*/, void* /*data*/) { + ZoneScoped; CFrustum ViewBase; ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB + FRUSTUM_P_FAR); Enable(); diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 36f71cce56a..eb9ede2fa9b 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -645,7 +645,7 @@ void CRender::BeforeRender() if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; - ProcessHOMTask = &TaskScheduler->AddTask("MT-HOM", { &HOM, &CHOM::MT_RENDER }); + ProcessHOMTask = &TaskScheduler->AddTask({ &HOM, &CHOM::MT_RENDER }); } void CRender::OnFrame() diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index 2d3f2ee680a..527b9e495b2 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -44,7 +44,7 @@ struct i_render_phase if (!o.active) return; - main_task = &TaskScheduler->CreateTask("phase_calculate", { this, &i_render_phase::calculate_task }); + main_task = &TaskScheduler->CreateTask({ this, &i_render_phase::calculate_task }); if (o.mt_calc_enabled) { @@ -84,7 +84,7 @@ struct i_render_phase if (o.mt_draw_enabled) { - draw_task = &TaskScheduler->AddTask(*main_task, "phase_render", { this, &i_render_phase::render_task }); + draw_task = &TaskScheduler->AddTask(*main_task, { this, &i_render_phase::render_task }); } } diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 4e8b413619d..c9dd5f63e86 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -111,6 +111,7 @@ void CRender::render_lights(light_Package& LP) const auto &calc_lights = [](Task &, void* data) { + ZoneScopedN("calc lights"); const auto* task_data = static_cast(data); auto& dsgraph = RImplementation.get_context(task_data->batch_id); { @@ -131,6 +132,7 @@ void CRender::render_lights(light_Package& LP) const auto& flush_lights = [&]() { + ZoneScopedN("flush lights"); for (const auto& [L, task, batch_id] : lights_queue) { VERIFY(task); @@ -217,7 +219,7 @@ void CRender::render_lights(light_Package& LP) task_data_t data; data.batch_id = batch_id; data.L = L; - data.task = &TaskScheduler->CreateTask("slight_calc", calc_lights, sizeof(data), (void*)&data); + data.task = &TaskScheduler->CreateTask(calc_lights, sizeof(data), (void*)&data); if (o.mt_calculate) { TaskScheduler->PushTask(*data.task); diff --git a/src/xrCore/Threading/ParallelFor.hpp b/src/xrCore/Threading/ParallelFor.hpp index 95488a00ef8..29e13a5ab66 100644 --- a/src/xrCore/Threading/ParallelFor.hpp +++ b/src/xrCore/Threading/ParallelFor.hpp @@ -135,7 +135,7 @@ class ParallelForTask { TaskData taskData{ range, function }; - auto& task = TaskScheduler->AddTask(__FUNCTION__, task_func, sizeof(TaskData), &taskData); + auto& task = TaskScheduler->AddTask(task_func, sizeof(TaskData), &taskData); if (wait) TaskScheduler->Wait(task); return task; @@ -146,7 +146,7 @@ class ParallelForTask { TaskData taskData{ range, function }; - auto& task = TaskScheduler->AddTask(__FUNCTION__, callback, task_func, sizeof(TaskData), &taskData); + auto& task = TaskScheduler->AddTask(callback, task_func, sizeof(TaskData), &taskData); if (wait) TaskScheduler->Wait(task); return task; @@ -161,8 +161,8 @@ class ParallelForTask if (range.is_splittable()) { TaskData leftData{ TaskRange(range, SplitTaskRange()), data.function }; - TaskScheduler->AddTask(thisTask, __FUNCTION__, task_func, sizeof(TaskData), &leftData); - TaskScheduler->AddTask(thisTask, __FUNCTION__, task_func, sizeof(TaskData), &data); + TaskScheduler->AddTask(thisTask, task_func, sizeof(TaskData), &leftData); + TaskScheduler->AddTask(thisTask, task_func, sizeof(TaskData), &data); } else { diff --git a/src/xrCore/Threading/Task.cpp b/src/xrCore/Threading/Task.cpp index 2724e382801..7c0bcda7a09 100644 --- a/src/xrCore/Threading/Task.cpp +++ b/src/xrCore/Threading/Task.cpp @@ -17,14 +17,14 @@ #include "Task.hpp" -Task::Data::Data(pcstr name, const TaskFunc& task, Task* parent) - : task_func(task), on_finish_callback(nullptr), name(name), parent(parent), jobs(1) {} +Task::Data::Data(const TaskFunc& task, Task* parent) + : task_func(task), on_finish_callback(nullptr), parent(parent), jobs(1) {} -Task::Data::Data(pcstr name, const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent) - : task_func(task), on_finish_callback(onFinishCallback), name(name), parent(parent), jobs(1) {} +Task::Data::Data(const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent) + : task_func(task), on_finish_callback(onFinishCallback), parent(parent), jobs(1) {} -Task::Task(pcstr name, const TaskFunc& task, void* data, size_t dataSize, Task* parent /*= nullptr*/) - : m_data(name, task, parent) +Task::Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent /*= nullptr*/) + : m_data(task, parent) { VERIFY2(dataSize <= sizeof(m_user_data), "Cannot fit your data in the task"); if (data && dataSize) @@ -33,8 +33,8 @@ Task::Task(pcstr name, const TaskFunc& task, void* data, size_t dataSize, Task* } } -Task::Task(pcstr name, const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent /*= nullptr*/) - : m_data(name, task, onFinishCallback, parent) +Task::Task(const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent /*= nullptr*/) + : m_data(task, onFinishCallback, parent) { VERIFY2(dataSize <= sizeof(m_user_data), "Cannot fit your data in the task"); if (data && dataSize) diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 9b4fd253dc6..61a1c765f6e 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -50,26 +50,27 @@ class XRCORE_API Task final : Noncopyable { TaskFunc task_func{}; OnFinishFunc on_finish_callback{}; - pcstr name{}; Task* parent{}; std::atomic_int16_t jobs{}; // at least 1 (task itself), zero means task is done. Data() = default; - Data(pcstr name, const TaskFunc& task, Task* parent); - Data(pcstr name, const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent); + Data(const TaskFunc& task, Task* parent); + Data(const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent); } m_data; - u8 m_user_data[TASK_SIZE - sizeof(m_data)]; + static constexpr size_t USER_DATA_SIZE = TASK_SIZE - sizeof(m_data); + + std::byte m_user_data[USER_DATA_SIZE]; private: // Used by TaskAllocator as Task initial state Task() = default; // Will just execute - Task(pcstr name, const TaskFunc& task, void* data, size_t dataSize, Task* parent = nullptr); + Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent = nullptr); // Will execute and call back - Task(pcstr name, const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent = nullptr); + Task(const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent = nullptr); public: static constexpr size_t GetAvailableDataStorageSize() diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 85416688031..a2b37544a0c 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -431,52 +431,52 @@ bool TaskManager::ExecuteOneTask() const return false; } -Task& TaskManager::CreateTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - return *new (AllocateTask()) Task(name, taskFunc, data, dataSize); + return *new (AllocateTask()) Task(taskFunc, data, dataSize); } -Task& TaskManager::CreateTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::CreateTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - return *new (AllocateTask()) Task(name, taskFunc, onFinishCallback, data, dataSize); + return *new (AllocateTask()) Task(taskFunc, onFinishCallback, data, dataSize); } -Task& TaskManager::CreateTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { IncrementTaskJobsCounter(parent); - return *new (AllocateTask()) Task(name, taskFunc, data, dataSize, &parent); + return *new (AllocateTask()) Task(taskFunc, data, dataSize, &parent); } -Task& TaskManager::CreateTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::CreateTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { IncrementTaskJobsCounter(parent); - return *new (AllocateTask()) Task(name, taskFunc, onFinishCallback, data, dataSize, &parent); + return *new (AllocateTask()) Task(taskFunc, onFinishCallback, data, dataSize, &parent); } -Task& TaskManager::AddTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::AddTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - auto& task = CreateTask(name, taskFunc, dataSize, data); + auto& task = CreateTask(taskFunc, dataSize, data); PushTask(task); return task; } -Task& TaskManager::AddTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::AddTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - auto& task = CreateTask(name, onFinishCallback, taskFunc, dataSize, data); + auto& task = CreateTask(onFinishCallback, taskFunc, dataSize, data); PushTask(task); return task; } -Task& TaskManager::AddTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - auto& task = CreateTask(parent, name, taskFunc, dataSize, data); + auto& task = CreateTask(parent, taskFunc, dataSize, data); PushTask(task); return task; } -Task& TaskManager::AddTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) +Task& TaskManager::AddTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { - auto& task = CreateTask(parent, name, onFinishCallback, taskFunc, dataSize, data); + auto& task = CreateTask(parent, onFinishCallback, taskFunc, dataSize, data); PushTask(task); return task; } diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 70a3d1103ef..f5dd29da8b9 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -54,12 +54,12 @@ class XRCORE_API TaskManager final public: // TaskFunc is at the end for fancy in-place lambdas // Create a task, but don't run it yet - [[nodiscard]] static Task& CreateTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] static Task& CreateTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Create a task as child, but don't run it yet - [[nodiscard]] static Task& CreateTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] static Task& CreateTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + [[nodiscard]] static Task& CreateTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Run task in parallel static void PushTask(Task& task); @@ -68,12 +68,12 @@ class XRCORE_API TaskManager final static void RunTask(Task& task); // Shortcut: create a task and run it immediately - static Task& AddTask(pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - static Task& AddTask(pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Shortcut: create task and run it immediately - static Task& AddTask(Task& parent, pcstr name, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - static Task& AddTask(Task& parent, pcstr name, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + static Task& AddTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); public: void RegisterThisThreadAsWorker(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index da634673732..e3631f23b87 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -310,13 +310,13 @@ CApplication::CApplication(pcstr commandLine) return; #endif - const auto& inputTask = TaskScheduler->AddTask("InitInput", [](Task&, void*) + const auto& inputTask = TaskScheduler->AddTask([](Task&, void*) { const bool captureInput = !strstr(Core.Params, "-i"); pInput = xr_new(captureInput); }); - const auto& createSoundDevicesList = TaskScheduler->AddTask("CSoundManager::CreateDevicesList()", [](Task&, void*) + const auto& createSoundDevicesList = TaskScheduler->AddTask([](Task&, void*) { Engine.Sound.CreateDevicesList(); }); @@ -366,7 +366,7 @@ CApplication::CApplication(pcstr commandLine) Console->Execute(loadArgs + 1); // Initialize APP - const auto& createLightAnim = TaskScheduler->AddTask("LALib.OnCreate()", [](Task&, void*) + const auto& createLightAnim = TaskScheduler->AddTask([](Task&, void*) { LALib.OnCreate(); }); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 9c35726da96..cc8c6197667 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -102,7 +102,7 @@ void CGamePersistent::OnAppStart() #ifndef XR_PLATFORM_WINDOWS init_game_globals(); #else - const auto& initializeGlobals = TaskScheduler->AddTask("init_game_globals()", [](Task&, void*) + const auto& initializeGlobals = TaskScheduler->AddTask([](Task&, void*) { init_game_globals(); }); diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 8c2db63b6e7..a760f5db491 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -105,13 +105,13 @@ void CSoundRender_Target::wait_prefill() const void CSoundRender_Target::dispatch_prefill() { wait_prefill(); - const auto task = &TaskScheduler->AddTask("CSoundRender_Target::dispatch_prefill()", { this, &CSoundRender_Target::prefill_blocks }); + const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Target::prefill_blocks }); prefill_task.store(task, std::memory_order_release); } void CSoundRender_Target::dispatch_prefill_all() { wait_prefill(); - const auto task = &TaskScheduler->AddTask("CSoundRender_Target::dispatch_prefill_all()", { this, &CSoundRender_Target::prefill_all_blocks }); + const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Target::prefill_all_blocks }); prefill_task.store(task, std::memory_order_release); } From 7899c6bd3783b93b1bbdba2458a293833b977af0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 09:54:44 +0500 Subject: [PATCH 333/497] More tracy zones on engine startup Removed some zones to sanitize crashes when DLLs are unloaded --- src/Layers/xrRender/D3DUtils.cpp | 1 + src/Layers/xrRender/D3DXRenderBase.cpp | 5 +++++ src/Layers/xrRender/HOM.cpp | 1 + src/Layers/xrRender/PSLibrary.cpp | 8 +++++++- src/Layers/xrRender/R_Backend.cpp | 2 ++ src/Layers/xrRender/R_Backend_Runtime.cpp | 2 ++ src/Layers/xrRender/R_DStreams.cpp | 2 ++ src/Layers/xrRender/ResourceManager.cpp | 2 ++ src/Layers/xrRender/ResourceManager_Loader.cpp | 6 ++++++ src/Layers/xrRender/ResourceManager_Reset.cpp | 2 ++ src/Layers/xrRender/TextureDescrManager.cpp | 3 ++- src/Layers/xrRender/r__occlusion.cpp | 1 + src/Layers/xrRender/xrRender_console.cpp | 2 ++ src/Layers/xrRenderDX11/dx11HW.cpp | 11 +++++++++++ src/Layers/xrRenderDX11/dx11SH_Texture.cpp | 3 +++ src/Layers/xrRenderGL/glHW.cpp | 4 ++++ src/Layers/xrRenderGL/glSH_Texture.cpp | 3 +++ src/Layers/xrRenderPC_GL/r2_test_hw.cpp | 9 ++++++++- src/Layers/xrRenderPC_GL/xrRender_GL.cpp | 4 ++++ src/Layers/xrRenderPC_R4/r2_test_hw.cpp | 2 ++ src/Layers/xrRenderPC_R4/xrRender_R4.cpp | 4 ++++ src/Layers/xrRender_R2/r2.cpp | 4 ++++ src/Layers/xrRender_R2/r2_rendertarget.cpp | 2 ++ src/xrAICore/AISpaceBase.cpp | 1 + src/xrCore/ModuleLookup.cpp | 4 ++++ src/xrEngine/EngineAPI.cpp | 8 ++++++++ src/xrEngine/StringTable/StringTable.cpp | 6 ++++++ src/xrEngine/xr_level_controller.cpp | 2 ++ src/xrGame/GamePersistent.cpp | 2 ++ src/xrGame/MainMenu.cpp | 2 -- src/xrGame/console_commands.cpp | 2 ++ src/xrGame/console_commands_mp.cpp | 2 ++ src/xrGame/cover_manager.cpp | 2 ++ src/xrGame/xrGame.cpp | 2 ++ src/xrGame/xrgame_dll_detach.cpp | 2 -- src/xrSound/SoundRender_Core_SourceManager.cpp | 2 ++ src/xrUICore/ui_styles.cpp | 2 ++ 37 files changed, 115 insertions(+), 7 deletions(-) diff --git a/src/Layers/xrRender/D3DUtils.cpp b/src/Layers/xrRender/D3DUtils.cpp index e02e73b1c6c..d20cedef435 100644 --- a/src/Layers/xrRender/D3DUtils.cpp +++ b/src/Layers/xrRender/D3DUtils.cpp @@ -194,6 +194,7 @@ void CDrawUtilities::UpdateGrid(int number_of_cell, float square_size, int subdi void CDrawUtilities::OnDeviceCreate() { + ZoneScoped; Device.seqRender.Add(this, REG_PRIORITY_LOW - 1000); m_SolidBox.CreateFromData(D3DPT_TRIANGLELIST, DU_BOX_NUMFACES, D3DFVF_XYZ | D3DFVF_DIFFUSE, du_box_vertices, diff --git a/src/Layers/xrRender/D3DXRenderBase.cpp b/src/Layers/xrRender/D3DXRenderBase.cpp index 8a52497f8c9..ce8a0818b68 100644 --- a/src/Layers/xrRender/D3DXRenderBase.cpp +++ b/src/Layers/xrRender/D3DXRenderBase.cpp @@ -76,6 +76,7 @@ void D3DXRenderBase::Destroy() void D3DXRenderBase::Reset(SDL_Window* hWnd, u32& dwWidth, u32& dwHeight, float& fWidth_2, float& fHeight_2) { + ZoneScoped; #if defined(DEBUG) && defined(USE_DX11) _SHOW_REF("*ref -CRenderDevice::ResetTotal: DeviceREF:", HW.pDevice); #endif // DEBUG @@ -123,6 +124,8 @@ void D3DXRenderBase::SetupStates() void D3DXRenderBase::OnDeviceCreate(const char* shName) { + ZoneScoped; + // Signal everyone - device created // streams @@ -157,6 +160,8 @@ void D3DXRenderBase::OnDeviceCreate(const char* shName) void D3DXRenderBase::Create(SDL_Window* hWnd, u32& dwWidth, u32& dwHeight, float& fWidth_2, float& fHeight_2) { + ZoneScoped; + #if defined(USE_RENDERDOC) && defined(USE_DX11) if (!g_renderdoc_api) { diff --git a/src/Layers/xrRender/HOM.cpp b/src/Layers/xrRender/HOM.cpp index 215dc2e3d4b..93f8fe24e00 100644 --- a/src/Layers/xrRender/HOM.cpp +++ b/src/Layers/xrRender/HOM.cpp @@ -93,6 +93,7 @@ void CHOM::Load() xr_parallel_for(TaskRange(0, CL.getTS()), [&](const TaskRange& range) { + ZoneScopedN("Process triangles"); for (size_t it = range.begin(); it != range.end(); ++it) { const CDB::TRI& clT = CL.getT()[it]; diff --git a/src/Layers/xrRender/PSLibrary.cpp b/src/Layers/xrRender/PSLibrary.cpp index d4897ab8b3f..5cb91111db1 100644 --- a/src/Layers/xrRender/PSLibrary.cpp +++ b/src/Layers/xrRender/PSLibrary.cpp @@ -13,6 +13,7 @@ bool pgd_sort_pred(const PS::CPGDef* a, const PS::CPGDef* b) { return xr_strcmp( //---------------------------------------------------- void CPSLibrary::OnCreate() { + ZoneScoped; #ifdef _EDITOR if (pCreateEAction) { @@ -201,17 +202,21 @@ bool CPSLibrary::Load(const char* nm) return false; } + ZoneScoped; + IReader* F = FS.r_open(nm); bool bRes = true; R_ASSERT(F->find_chunk(PS_CHUNK_VERSION)); u16 ver = F->r_u16(); if (ver != PS_VERSION) return false; + // second generation IReader* OBJ; OBJ = F->open_chunk(PS_CHUNK_SECONDGEN); if (OBJ) { + ZoneScopedN("Second generation"); IReader* O = OBJ->open_chunk(0); for (int count = 1; O; count++) { @@ -230,10 +235,11 @@ bool CPSLibrary::Load(const char* nm) } OBJ->close(); } - // second generation + // third generation OBJ = F->open_chunk(PS_CHUNK_THIRDGEN); if (OBJ) { + ZoneScopedN("Third generation"); IReader* O = OBJ->open_chunk(0); for (int count = 1; O; count++) { diff --git a/src/Layers/xrRender/R_Backend.cpp b/src/Layers/xrRender/R_Backend.cpp index 2c7fab159c2..d746390a483 100644 --- a/src/Layers/xrRender/R_Backend.cpp +++ b/src/Layers/xrRender/R_Backend.cpp @@ -3,6 +3,8 @@ void D3DXRenderBase::CreateQuadIB() { + ZoneScoped; + constexpr auto triCount = 4 * 1024; constexpr auto idxCount = triCount * 2 * 3; constexpr auto idxSize = idxCount * sizeof(u16); diff --git a/src/Layers/xrRender/R_Backend_Runtime.cpp b/src/Layers/xrRender/R_Backend_Runtime.cpp index e1a66552195..0ed2e3ed367 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.cpp +++ b/src/Layers/xrRender/R_Backend_Runtime.cpp @@ -454,6 +454,8 @@ void CBackend::SetupStates() // Device dependance void CBackend::OnDeviceCreate() { + ZoneScoped; + #if defined(USE_DX11) HW.get_context(context_id)->QueryInterface(__uuidof(ID3DUserDefinedAnnotation), reinterpret_cast(&pAnnotation)); #endif diff --git a/src/Layers/xrRender/R_DStreams.cpp b/src/Layers/xrRender/R_DStreams.cpp index 4eb06452065..ee5ad836584 100644 --- a/src/Layers/xrRender/R_DStreams.cpp +++ b/src/Layers/xrRender/R_DStreams.cpp @@ -11,6 +11,8 @@ int rsDIB_Size = 512; void _VertexStream::Create() { + ZoneScoped; + RImplementation.Resources->Evict(); mSize = rsDVB_Size * 1024; diff --git a/src/Layers/xrRender/ResourceManager.cpp b/src/Layers/xrRender/ResourceManager.cpp index f4f08abafc0..f7898ed8df5 100644 --- a/src/Layers/xrRender/ResourceManager.cpp +++ b/src/Layers/xrRender/ResourceManager.cpp @@ -268,6 +268,8 @@ IReader* open_shader(pcstr shader) void CResourceManager::CompatibilityCheck() { + ZoneScoped; + // Check Shoker HQ Geometry Fix support { IReader* skinh = open_shader("skin.h"); diff --git a/src/Layers/xrRender/ResourceManager_Loader.cpp b/src/Layers/xrRender/ResourceManager_Loader.cpp index b19acb0cdc4..f1a1e4ae58b 100644 --- a/src/Layers/xrRender/ResourceManager_Loader.cpp +++ b/src/Layers/xrRender/ResourceManager_Loader.cpp @@ -52,6 +52,7 @@ void CResourceManager::OnDeviceCreate(IReader* F) if (!Device.b_is_Ready) return; + ZoneScoped; string256 name; #ifndef _EDITOR @@ -63,6 +64,7 @@ void CResourceManager::OnDeviceCreate(IReader* F) fs = F->open_chunk(0); if (fs) { + ZoneScopedN("Load constants"); while (!fs->eof()) { fs->r_stringZ(name, sizeof(name)); @@ -76,6 +78,7 @@ void CResourceManager::OnDeviceCreate(IReader* F) fs = F->open_chunk(1); if (fs) { + ZoneScopedN("Load matrices"); while (!fs->eof()) { fs->r_stringZ(name, sizeof(name)); @@ -89,6 +92,7 @@ void CResourceManager::OnDeviceCreate(IReader* F) fs = F->open_chunk(2); if (fs) { + ZoneScopedN("Load blenders"); IReader* chunk = nullptr; int chunk_id = 0; @@ -125,6 +129,8 @@ void CResourceManager::OnDeviceCreate(IReader* F) void CResourceManager::OnDeviceCreate(LPCSTR shName) { + ZoneScoped; + #ifdef _EDITOR if (!FS.exist(shName)) return; diff --git a/src/Layers/xrRender/ResourceManager_Reset.cpp b/src/Layers/xrRender/ResourceManager_Reset.cpp index 90eecce1257..11e8b83b789 100644 --- a/src/Layers/xrRender/ResourceManager_Reset.cpp +++ b/src/Layers/xrRender/ResourceManager_Reset.cpp @@ -10,6 +10,7 @@ void CResourceManager::reset_begin() { + ZoneScoped; // destroy state-blocks for (SState* sstate : v_states) _RELEASE(sstate->state); @@ -33,6 +34,7 @@ bool cmp_rt(const CRT* A, const CRT* B) { return A->_order < B->_order; } void CResourceManager::reset_end() { + ZoneScoped; // create RDStreams RImplementation.Vertex.reset_end(); RImplementation.Index.reset_end(); diff --git a/src/Layers/xrRender/TextureDescrManager.cpp b/src/Layers/xrRender/TextureDescrManager.cpp index 3831b644642..8b7116abe0f 100644 --- a/src/Layers/xrRender/TextureDescrManager.cpp +++ b/src/Layers/xrRender/TextureDescrManager.cpp @@ -54,6 +54,7 @@ void CTextureDescrMngr::LoadLTX(pcstr initial, bool listTHM) const auto processAssociation = [&](const CInifile::Item& item) { + ZoneScopedN("Process association"); if (listTHM) Msg("\t\t%s = %s", item.first.c_str(), item.second.c_str()); @@ -145,6 +146,7 @@ void CTextureDescrMngr::LoadTHM(LPCSTR initial, bool listTHM) Lock lock; const auto processFile = [&](const FS_File& it) { + ZoneScopedN("Process file"); // Alundaio: Print list of *.thm to find bad .thms! if (listTHM) Log("\t", it.name.c_str()); @@ -241,7 +243,6 @@ void CTextureDescrMngr::Load() void CTextureDescrMngr::UnLoad() { - ZoneScoped; for (auto& it : m_texture_details) { xr_delete(it.second.m_assoc); diff --git a/src/Layers/xrRender/r__occlusion.cpp b/src/Layers/xrRender/r__occlusion.cpp index 765f9635b2c..9343454c176 100644 --- a/src/Layers/xrRender/r__occlusion.cpp +++ b/src/Layers/xrRender/r__occlusion.cpp @@ -7,6 +7,7 @@ R_occlusion::R_occlusion(void) { enabled = strstr(Core.Params, "-no_occq") ? fal R_occlusion::~R_occlusion(void) { occq_destroy(); } void R_occlusion::occq_create(u32 limit) { + ZoneScoped; pool.reserve(limit); used.reserve(limit); fids.reserve(limit); diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index 3c3ede2b782..b342d7bb7b0 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -843,6 +843,8 @@ class CCC_Fog_Reload : public IConsole_Command //----------------------------------------------------------------------- void xrRender_initconsole() { + ZoneScoped; + CMD3(CCC_Preset, "_preset", &ps_Preset, qpreset_token); CMD3(CCC_Shader_Preset, "_shader_preset", &ps_ShaderPreset, qshader_preset_token); CMD3(CCC_ColorGrading_Preset, "_colorgrading_preset", &ps_ColorGradingPreset, qcolorgrading_preset_token); diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index be96f833173..426bce05b6f 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -51,6 +51,8 @@ void CHW::OnAppDeactivate() ////////////////////////////////////////////////////////////////////// void CHW::CreateD3D() { + ZoneScoped; + hDXGI = XRay::LoadModule("dxgi"); hD3D = XRay::LoadModule("d3d11"); if (!hD3D->IsLoaded() || !hDXGI->IsLoaded()) @@ -90,6 +92,8 @@ void CHW::DestroyD3D() void CHW::CreateDevice(SDL_Window* sdlWnd) { + ZoneScoped; + CreateD3D(); if (!Valid) return; @@ -144,6 +148,8 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) const auto createDevice = [&](const D3D_FEATURE_LEVEL* level, const u32 levels) { + ZoneScopedN("Create device"); + static const auto d3d11CreateDevice = static_cast(hD3D->GetProcAddress("D3D11CreateDevice")); return d3d11CreateDevice(m_pAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, createDeviceFlags, level, levels, @@ -265,6 +271,8 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) bool CHW::CreateSwapChain(HWND hwnd) { + ZoneScoped; + // Set up the presentation parameters DXGI_SWAP_CHAIN_DESC& sd = m_ChainDesc; ZeroMemory(&sd, sizeof(sd)); @@ -319,6 +327,8 @@ bool CHW::CreateSwapChain2(HWND hwnd) if (strstr(Core.Params, "-no_dx11_2")) return false; + ZoneScoped; + #ifdef HAS_DX11_2 IDXGIFactory2* pFactory2{}; m_pAdapter->GetParent(__uuidof(IDXGIFactory2), (void**)&pFactory2); @@ -436,6 +446,7 @@ void CHW::DestroyDevice() ////////////////////////////////////////////////////////////////////// void CHW::Reset() { + ZoneScoped; DXGI_SWAP_CHAIN_DESC& cd = m_ChainDesc; const bool bWindowed = ThisInstanceIsGlobal() ? psDeviceMode.WindowStyle != rsFullscreen : true; cd.Windowed = bWindowed; diff --git a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp index 9e70f5b8d73..ab61d8dede9 100644 --- a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp +++ b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp @@ -341,6 +341,8 @@ void CTexture::Load() return; } + ZoneScoped; + Preload(); bool bCreateView = true; @@ -513,6 +515,7 @@ void CTexture::Load() void CTexture::Unload() { + ZoneScoped; #ifdef DEBUG string_path msg_buff; xr_sprintf(msg_buff, sizeof(msg_buff), "* Unloading texture [%s] pSurface RefCount =", cName.c_str()); diff --git a/src/Layers/xrRenderGL/glHW.cpp b/src/Layers/xrRenderGL/glHW.cpp index 4d1f53c057f..b085bbe49fe 100644 --- a/src/Layers/xrRenderGL/glHW.cpp +++ b/src/Layers/xrRenderGL/glHW.cpp @@ -72,6 +72,8 @@ void CHW::OnAppDeactivate() ////////////////////////////////////////////////////////////////////// void CHW::CreateDevice(SDL_Window* hWnd) { + ZoneScoped; + m_window = hWnd; R_ASSERT(m_window); @@ -184,6 +186,8 @@ void CHW::DestroyDevice() ////////////////////////////////////////////////////////////////////// void CHW::Reset() { + ZoneScoped; + CHK_GL(glDeleteFramebuffers(1, &pFB)); UpdateViews(); UpdateVSync(); diff --git a/src/Layers/xrRenderGL/glSH_Texture.cpp b/src/Layers/xrRenderGL/glSH_Texture.cpp index 3739a72baa9..aa8a1991c51 100644 --- a/src/Layers/xrRenderGL/glSH_Texture.cpp +++ b/src/Layers/xrRenderGL/glSH_Texture.cpp @@ -167,6 +167,8 @@ void CTexture::Load() return; } + ZoneScoped; + Preload(); // Check for OGM @@ -304,6 +306,7 @@ void CTexture::Load() void CTexture::Unload() { + ZoneScoped; #ifdef DEBUG string_path msg_buff; sprintf_s(msg_buff, sizeof(msg_buff), "* Unloading texture [%s] pSurface ID=%d", cName.c_str(), pSurface); diff --git a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp index cf8e9b4b46b..4109596b9f1 100644 --- a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp +++ b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp @@ -8,6 +8,7 @@ class sdl_window_test_helper public: sdl_window_test_helper() { + ZoneScoped; u32 flags{}; HW.SetPrimaryAttributes(flags); m_window = SDL_CreateWindow("TestOpenGLWindow", 0, 0, 1, 1, SDL_WINDOW_HIDDEN | flags); @@ -40,12 +41,18 @@ class sdl_window_test_helper BOOL xrRender_test_hw() { + ZoneScoped; + // Check if minimal required OpenGL features are available const sdl_window_test_helper windowTest; if (!windowTest.successful()) return FALSE; - GLenum err = glewInit(); + GLenum err; + { + ZoneScopedN("glewInit()"); + err = glewInit(); + } if (GLEW_OK != err) { Log("~ Could not initialize glew:", (pcstr)glewGetErrorString(err)); diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp index 1d721f7d395..63c5e38d44a 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp @@ -29,6 +29,8 @@ class RGLRendererModule final : public RendererModule const xr_vector& ObtainSupportedModes() override { + ZoneScoped; + if (CheckCanAddMode()) { modes.emplace_back(RENDERER_RGL_MODE); @@ -44,6 +46,8 @@ class RGLRendererModule final : public RendererModule void SetupEnv(pcstr mode) override { + ZoneScoped; + CheckModeConsistency(mode); ps_r2_sun_static = false; ps_r2_advanced_pp = true; diff --git a/src/Layers/xrRenderPC_R4/r2_test_hw.cpp b/src/Layers/xrRenderPC_R4/r2_test_hw.cpp index ad48dee36e6..3926008c1a4 100644 --- a/src/Layers/xrRenderPC_R4/r2_test_hw.cpp +++ b/src/Layers/xrRenderPC_R4/r2_test_hw.cpp @@ -34,6 +34,8 @@ class DX11TestHelper BOOL xrRender_test_hw() { + ZoneScoped; + const DX11TestHelper helper; if (!helper.Successful()) return FALSE; diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index 5476335200b..e9b13f15c86 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -35,6 +35,8 @@ class R4RendererModule final : public RendererModule const xr_vector& ObtainSupportedModes() override { + ZoneScoped; + const BOOL result = CheckCanAddMode(); if (result != FALSE) { @@ -59,6 +61,8 @@ class R4RendererModule final : public RendererModule void SetupEnv(pcstr mode) override { + ZoneScoped; + ps_r2_sun_static = false; switch (strhash(mode)) diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index eb9ede2fa9b..3166e51579c 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -216,6 +216,8 @@ void CRender::OnDeviceCreate(pcstr shName) // Just two static storage void CRender::create() { + ZoneScoped; + Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 0x12345678); m_skinning = -1; @@ -564,6 +566,7 @@ void CRender::destroy() void CRender::reset_begin() { + ZoneScoped; // Wait for tasks to be done r_main.sync(); r_sun.sync(); @@ -612,6 +615,7 @@ void CRender::reset_begin() void CRender::reset_end() { + ZoneScoped; q_sync_point.Create(); HWOCC.occq_create(occq_size); diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index 71b4a2829c2..3c194a63bf7 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -206,6 +206,8 @@ void manually_assign_texture(ref_shader& shader, pcstr textureName, pcstr render CRenderTarget::CRenderTarget() { + ZoneScoped; + static constexpr pcstr SAMPLE_DEFS[] = { "0", "1", "2", "3", "4", "5", "6", "7" }; const auto& options = RImplementation.o; diff --git a/src/xrAICore/AISpaceBase.cpp b/src/xrAICore/AISpaceBase.cpp index 38bcbfd39ed..9f656a36324 100644 --- a/src/xrAICore/AISpaceBase.cpp +++ b/src/xrAICore/AISpaceBase.cpp @@ -16,6 +16,7 @@ AISpaceBase::~AISpaceBase() void AISpaceBase::Load(const char* levelName) { + ZoneScoped; const CGameGraph::SLevel& currentLevel = game_graph().header().level(levelName); m_level_graph = xr_new(); game_graph().set_current_level(currentLevel.id()); diff --git a/src/xrCore/ModuleLookup.cpp b/src/xrCore/ModuleLookup.cpp index 0600a59abc3..eb32d99425c 100644 --- a/src/xrCore/ModuleLookup.cpp +++ b/src/xrCore/ModuleLookup.cpp @@ -24,6 +24,8 @@ ModuleHandle::~ModuleHandle() void* ModuleHandle::Open(pcstr moduleName) { + ZoneScoped; + if (IsLoaded()) Close(); @@ -64,6 +66,8 @@ void* ModuleHandle::Open(pcstr moduleName) void ModuleHandle::Close() { + ZoneScoped; + if (dontUnload || !handle) return; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index b3f69f1a2c2..997200d5991 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -60,6 +60,8 @@ bool is_enough_address_space_available() pcstr CEngineAPI::SelectRenderer() { + ZoneScoped; + cpcstr selected_mode = Console->GetString("renderer"); const auto it = renderModes.find(selected_mode); if (it != renderModes.end()) @@ -71,6 +73,8 @@ pcstr CEngineAPI::SelectRenderer() void CEngineAPI::InitializeRenderers() { + ZoneScoped; + pcstr selected_mode = SelectRenderer(); if (selectedRenderer == nullptr @@ -96,6 +100,8 @@ void CEngineAPI::InitializeRenderers() void CEngineAPI::Initialize(void) { + ZoneScoped; + InitializeRenderers(); hGame = XRay::LoadModule("xrGame"); @@ -123,6 +129,7 @@ void CEngineAPI::Initialize(void) void CEngineAPI::Destroy(void) { + ZoneScoped; if (pFinalizeGame) pFinalizeGame(); @@ -139,6 +146,7 @@ void CEngineAPI::Destroy(void) void CEngineAPI::CloseUnusedLibraries() { + ZoneScoped; for (RendererDesc& desc : renderers) { if (desc.module != selectedRenderer) diff --git a/src/xrEngine/StringTable/StringTable.cpp b/src/xrEngine/StringTable/StringTable.cpp index d709c17c2a0..73f17429f62 100644 --- a/src/xrEngine/StringTable/StringTable.cpp +++ b/src/xrEngine/StringTable/StringTable.cpp @@ -45,6 +45,8 @@ void CStringTable::Init() if (pData) return; + ZoneScoped; + pData = xr_make_unique(); FillLanguageToken(); @@ -72,6 +74,8 @@ void CStringTable::Init() void CStringTable::FillLanguageToken() { + ZoneScoped; + languagesToken.clear(); string_path path; @@ -187,6 +191,8 @@ xr_token* CStringTable::GetLanguagesToken() const { return languagesToken.data() void CStringTable::Load(LPCSTR xml_file_full) { + ZoneScoped; + XMLDocument uiXml; string_path _s; strconcat(sizeof(_s), _s, "text" DELIMITER, pData->m_sLanguage.c_str()); diff --git a/src/xrEngine/xr_level_controller.cpp b/src/xrEngine/xr_level_controller.cpp index 7185aab3245..ac5cb441f74 100644 --- a/src/xrEngine/xr_level_controller.cpp +++ b/src/xrEngine/xr_level_controller.cpp @@ -1155,6 +1155,8 @@ void ConsoleBindCmds::save(IWriter* f) void CCC_RegisterInput() { + ZoneScoped; + initialize_bindings(); CMD2(CCC_Bind, "bind", 0); CMD2(CCC_Bind, "bind_sec", 1); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index cc8c6197667..32ac9ec1667 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -151,6 +151,8 @@ void CGamePersistent::OnAppEnd() void CGamePersistent::Start(LPCSTR op) { inherited::Start(op); } void CGamePersistent::Disconnect() { + ZoneScoped; + // destroy ambient particles CParticlesObject::Destroy(ambient_particles); diff --git a/src/xrGame/MainMenu.cpp b/src/xrGame/MainMenu.cpp index d461016b5c9..69e8feb5c2c 100644 --- a/src/xrGame/MainMenu.cpp +++ b/src/xrGame/MainMenu.cpp @@ -172,8 +172,6 @@ CMainMenu::CMainMenu() CMainMenu::~CMainMenu() { - ZoneScoped; - Device.seqFrame.Remove(this); xr_delete(g_btnHint); diff --git a/src/xrGame/console_commands.cpp b/src/xrGame/console_commands.cpp index 1589788fcd4..680dd543bbe 100644 --- a/src/xrGame/console_commands.cpp +++ b/src/xrGame/console_commands.cpp @@ -2010,6 +2010,8 @@ class CCC_UI_Time_Factor : public IConsole_Command void CCC_RegisterCommands() { + ZoneScoped; + // options g_OptConCom.Init(); diff --git a/src/xrGame/console_commands_mp.cpp b/src/xrGame/console_commands_mp.cpp index 66ec198f0bc..615f775a094 100644 --- a/src/xrGame/console_commands_mp.cpp +++ b/src/xrGame/console_commands_mp.cpp @@ -2052,6 +2052,8 @@ class CCC_TrafficOptimizationLevel : public CCC_Integer void register_mp_console_commands() { + ZoneScoped; + CMD1(CCC_Restart, "g_restart"); CMD1(CCC_RestartFast, "g_restart_fast"); CMD1(CCC_Kill, "g_kill"); diff --git a/src/xrGame/cover_manager.cpp b/src/xrGame/cover_manager.cpp index 3eafe6685d7..cad1ab97036 100644 --- a/src/xrGame/cover_manager.cpp +++ b/src/xrGame/cover_manager.cpp @@ -72,6 +72,7 @@ IC bool CCoverManager::critical_cover(u32 index) const void CCoverManager::compute_static_cover() { + ZoneScoped; clear(); xr_delete(m_covers); m_covers = xr_new( @@ -83,6 +84,7 @@ void CCoverManager::compute_static_cover() xr_parallel_for(TaskRange(0, levelVertexCount), [&](const TaskRange& range) { + ZoneScopedN("Process vertices"); for (u32 i = range.begin(); i != range.end(); ++i) { const CLevelGraph::CLevelVertex& vertex = *graph.vertex(i); diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index 1694b14801e..0749bde2866 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -38,6 +38,8 @@ extern "C" XR_EXPORT void initialize_library() { + ZoneScoped; + g_fTimeFactor = pSettings->r_float("alife", "time_factor"); // XXX: find a better place // Fill ui style token diff --git a/src/xrGame/xrgame_dll_detach.cpp b/src/xrGame/xrgame_dll_detach.cpp index 4bb2d0b3268..7eb004cd731 100644 --- a/src/xrGame/xrgame_dll_detach.cpp +++ b/src/xrGame/xrgame_dll_detach.cpp @@ -54,8 +54,6 @@ void init_game_globals() void clean_game_globals() { - ZoneScoped; - // destroy ai space xr_delete(g_ai_space); // destroy object factory diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index 9f721a73769..a8426a65905 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -65,6 +65,7 @@ void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) void CSoundRender_Core::i_create_all_sources() { + ZoneScoped; #ifndef MASTER_GOLD CTimer T; T.Start(); @@ -75,6 +76,7 @@ void CSoundRender_Core::i_create_all_sources() const auto processFile = [&](const FS_File& file) { + ZoneScopedN("Process file"); string256 id; xr_strcpy(id, file.name.c_str()); diff --git a/src/xrUICore/ui_styles.cpp b/src/xrUICore/ui_styles.cpp index 8dd623681ac..2cf6b92e4a7 100644 --- a/src/xrUICore/ui_styles.cpp +++ b/src/xrUICore/ui_styles.cpp @@ -10,6 +10,8 @@ UIStyleManager* UIStyles = nullptr; UIStyleManager::UIStyleManager() { + ZoneScoped; + m_token.emplace_back(DEFAULT_UI_STYLE_NAME, DEFAULT_STYLE_ID); string_path path; From 0940146973e9e2fd12891f81173b6596bbae778f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 10:26:17 +0500 Subject: [PATCH 334/497] xrRender: create tracy d3d11 context and deferred contexts only for global HW instance Speeds up engine startup times --- src/Layers/xrRenderDX11/dx11HW.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index 426bce05b6f..55965b0e532 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -219,13 +219,21 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) _SHOW_REF("* CREATE: DeviceREF:", pDevice); // Register immediate context in profiler - profiler_ctx = TracyD3D11Context(pDevice, pContext); + if (ThisInstanceIsGlobal()) + { + ZoneScopedN("TracyD3D11Context"); + profiler_ctx = TracyD3D11Context(pDevice, pContext); + } // Create deferred contexts - for (int id = 0; id < R__NUM_PARALLEL_CONTEXTS; ++id) + if (ThisInstanceIsGlobal()) { - R = pDevice->CreateDeferredContext(0, &d3d_contexts_pool[id]); - VERIFY(SUCCEEDED(R)); + ZoneScopedN("Create deferred contexts"); + for (int id = 0; id < R__NUM_PARALLEL_CONTEXTS; ++id) + { + R = pDevice->CreateDeferredContext(0, &d3d_contexts_pool[id]); + VERIFY(SUCCEEDED(R)); + } } SDL_SysWMinfo info; @@ -424,7 +432,8 @@ void CHW::DestroyDevice() _SHOW_REF("refCount:m_pSwapChain", m_pSwapChain); _RELEASE(m_pSwapChain); - TracyD3D11Destroy(profiler_ctx); + if (profiler_ctx) + TracyD3D11Destroy(profiler_ctx); _RELEASE(pContext1); for (int id = 0; id < R__NUM_CONTEXTS; ++id) From e5fa7b90ea8950a2f1da2961d690bbde6f0de0c6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 10:36:47 +0500 Subject: [PATCH 335/497] xrRender: create tracy d3d11 context in parallel --- src/Layers/xrRenderDX11/dx11HW.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index 55965b0e532..011d8d4d0a8 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -221,8 +221,11 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) // Register immediate context in profiler if (ThisInstanceIsGlobal()) { - ZoneScopedN("TracyD3D11Context"); - profiler_ctx = TracyD3D11Context(pDevice, pContext); + TaskScheduler->AddTask([](Task&, void*) + { + ZoneScopedN("TracyD3D11Context"); + HW.profiler_ctx = TracyD3D11Context(HW.pDevice, HW.get_context(CHW::IMM_CTX_ID)); + }); } // Create deferred contexts From 5673c5568b54c175371d83771a6bc2fdf86192e4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 10:50:01 +0500 Subject: [PATCH 336/497] xrEngine: Create renderer list in parallel Engine.External.CreateRendererList() was called outside of CEngine::Initialize in the original engine too, so no worries. But someday we will refactor that to eliminate dynamic DLL loading. --- src/xrEngine/Engine.cpp | 1 - src/xrEngine/x_ray.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index 3c15417d941..aea781905d0 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -75,7 +75,6 @@ void CEngine::Initialize(void) Device.seqFrame.Add(&g_sound_processor, REG_PRIORITY_NORMAL - 1000); // Place it after Level update Device.seqFrameMT.Add(&g_sound_renderer); - External.CreateRendererList(); CheckAndSetupRenderer(); External.Initialize(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index e3631f23b87..0b28d1a4ac0 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -321,6 +321,11 @@ CApplication::CApplication(pcstr commandLine) Engine.Sound.CreateDevicesList(); }); + const auto& createRendererList = TaskScheduler->AddTask([](Task&, void*) + { + Engine.External.CreateRendererList(); + }); + *g_sLaunchOnExit_app = 0; *g_sLaunchOnExit_params = 0; @@ -340,6 +345,7 @@ CApplication::CApplication(pcstr commandLine) InitConsole(); Engine.Initialize(); + TaskScheduler->Wait(createRendererList); Device.Initialize(); Console->OnDeviceInitialize(); From 8c32226fda740e8e0c302ac669ef988fc765a451 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:00:36 +0500 Subject: [PATCH 337/497] xrEngine/x_ray.h|cpp: simplify splash screen code Abandon the idea of animated BMP splash screen. It never was implemented and BMP is too big: embedding several images would result in big executable file. Not a concern in 2024, but still. --- src/xrEngine/embedded_resources_management.h | 21 +++---------- src/xrEngine/x_ray.cpp | 32 +++++++------------- src/xrEngine/x_ray.h | 3 +- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/xrEngine/embedded_resources_management.h b/src/xrEngine/embedded_resources_management.h index d6acb7c4aea..1c7e94e0862 100644 --- a/src/xrEngine/embedded_resources_management.h +++ b/src/xrEngine/embedded_resources_management.h @@ -81,18 +81,10 @@ inline SDL_Surface* ExtractBitmap(int idx) return CreateSurfaceFromBitmap(bitmap); } -inline xr_vector ExtractSplashScreen() +inline SDL_Surface* ExtractSplashScreen() { ZoneScoped; - - // XXX: that's the place, where splash frames can be added - // Animated splash screen! - SDL_Surface* surface = ExtractBitmap(IDB_SPLASH); - - if (surface) - return { surface }; - - return {}; + return ExtractBitmap(IDB_SPLASH); } inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) @@ -110,17 +102,12 @@ inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon); } #else -inline xr_vector ExtractSplashScreen() +inline SDL_Surface* ExtractSplashScreen() { ZoneScoped; // You need to place logo.bmp beside fsgame.ltx - SDL_Surface* surface = SDL_LoadBMP("logo.bmp"); - - if (surface) - return { surface }; - - return {}; + return SDL_LoadBMP("logo.bmp"); } inline void ExtractAndSetWindowIcon(SDL_Window* wnd, int iconIdx) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 0b28d1a4ac0..cdaa510e78f 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -531,11 +531,10 @@ void CApplication::ShowSplash(bool topmost) ZoneScoped; - m_surfaces = std::move(ExtractSplashScreen()); - - if (m_surfaces.empty()) + m_surface = std::move(ExtractSplashScreen()); + if (!m_surface) { - Log("! Couldn't create surface from image:", SDL_GetError()); + Log("~ Couldn't create surface from image:", SDL_GetError()); return; } @@ -546,8 +545,7 @@ void CApplication::ShowSplash(bool topmost) flags |= SDL_WINDOW_ALWAYS_ON_TOP; #endif - const SDL_Surface* surface = m_surfaces.front(); - m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, surface->w, surface->h, flags); + m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_surface->w, m_surface->h, flags); SDL_ShowWindow(m_window); m_splash_thread = Threading::RunThread("Splash Thread", &CApplication::SplashProc, this); @@ -556,20 +554,14 @@ void CApplication::ShowSplash(bool topmost) void CApplication::SplashProc() { + { + ZoneScopedN("Update splash image"); + const auto current = SDL_GetWindowSurface(m_window); + SDL_BlitSurface(m_surface, nullptr, current, nullptr); + SDL_UpdateWindowSurface(m_window); + } do { - if (m_surfaces.size() > 1 || m_current_surface_idx == size_t(-1)) - { - if (m_current_surface_idx >= m_surfaces.size()) - m_current_surface_idx = 0; - - ZoneScopedN("Update splash image"); - const auto current = SDL_GetWindowSurface(m_window); - const auto next = m_surfaces[m_current_surface_idx++]; // It's important to have postfix increment! - SDL_BlitSurface(next, nullptr, current, nullptr); - SDL_UpdateWindowSurface(m_window); - //SDL_PumpEvents(); - } UpdateDiscordStatus(); } while (!m_should_exit.Wait(SPLASH_FRAMERATE)); } @@ -587,9 +579,7 @@ void CApplication::HideSplash() SDL_DestroyWindow(m_window); m_window = nullptr; - for (SDL_Surface* surface : m_surfaces) - SDL_FreeSurface(surface); - m_surfaces.clear(); + SDL_FreeSurface(m_surface); } void CApplication::UpdateDiscordStatus() diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 5a720b26781..92b0da929da 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -20,8 +20,7 @@ class ENGINE_API CApplication final std::thread m_splash_thread; Event m_should_exit; - size_t m_current_surface_idx{ size_t(-1) }; - xr_vector m_surfaces; + SDL_Surface* m_surface; private: std::mutex m_discord_lock; From d8659c0667ba32a740fa623fe22c199d8b8fd026 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:07:07 +0500 Subject: [PATCH 338/497] xrCore/Threading/ThreadUtil.h: moved tracy thread name to SetCurrentThreadName This will set thread names for all threads, not only those created by RunThread helper --- src/xrCore/Threading/ThreadUtil.cpp | 6 ++++++ src/xrCore/Threading/ThreadUtil.h | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 0ff7e5887d2..35cf6d3ef5a 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -64,6 +64,9 @@ void SetThreadNameImpl(DWORD threadId, pcstr name) void SetCurrentThreadName(cpcstr name) { SetThreadNameImpl(-1, name); +#ifdef TRACY_ENABLE + tracy::SetThreadName(name); +#endif } priority_level GetCurrentThreadPriorityLevel() @@ -134,6 +137,9 @@ void SetCurrentThreadName(cpcstr name) { Msg("SetCurrentThreadName: failed to set thread name to '%s'. Errno: '%d'", name, error); } +#ifdef TRACY_ENABLE + tracy::SetThreadName(name); +#endif } priority_level GetCurrentThreadPriorityLevel() diff --git a/src/xrCore/Threading/ThreadUtil.h b/src/xrCore/Threading/ThreadUtil.h index 978306206d1..3c4e2becc03 100644 --- a/src/xrCore/Threading/ThreadUtil.h +++ b/src/xrCore/Threading/ThreadUtil.h @@ -44,9 +44,6 @@ template [name](Invocable&& invocable2, Args&&... args2) { SetCurrentThreadName(name); -#ifdef TRACY_ENABLE - tracy::SetThreadName(name); -#endif _initialize_cpu_thread(); std::invoke(std::move(invocable2), std::move(args2)...); }, From cc18897ea52cb0934de0588800d05d874872fb6f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:12:15 +0500 Subject: [PATCH 339/497] xrEngine/x_ray.cpp: wait for renderer list creation before calling Engine.Initialize() --- src/xrEngine/x_ray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index cdaa510e78f..f0c7558e76d 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -344,8 +344,8 @@ CApplication::CApplication(pcstr commandLine) TaskScheduler->Wait(inputTask); InitConsole(); - Engine.Initialize(); TaskScheduler->Wait(createRendererList); + Engine.Initialize(); Device.Initialize(); Console->OnDeviceInitialize(); From 483aac7e588f418004ba9d53bf3f36c0f580c443 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:17:35 +0500 Subject: [PATCH 340/497] Make splashscreen thread execute tasks too --- src/xrEngine/x_ray.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index f0c7558e76d..5d25667a987 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -563,6 +563,8 @@ void CApplication::SplashProc() do { UpdateDiscordStatus(); + if (TaskScheduler) + TaskScheduler->ExecuteOneTask(); } while (!m_should_exit.Wait(SPLASH_FRAMERATE)); } From e8173476442fa4e40d634d4fcf823a31d7c983c9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:24:34 +0500 Subject: [PATCH 341/497] Eliminate thread spinning in the splash screen thread --- src/xrEngine/x_ray.cpp | 11 ++++++----- src/xrEngine/x_ray.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 5d25667a987..29a4e40be59 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -43,8 +43,6 @@ #endif // global variables -constexpr u32 SPLASH_FRAMERATE = 30; - constexpr size_t MAX_WINDOW_EVENTS = 32; #ifdef USE_DISCORD_INTEGRATION @@ -552,6 +550,8 @@ void CApplication::ShowSplash(bool topmost) SDL_PumpEvents(); } +constexpr u32 SPLASH_FRAMERATE = 30; + void CApplication::SplashProc() { { @@ -560,12 +560,13 @@ void CApplication::SplashProc() SDL_BlitSurface(m_surface, nullptr, current, nullptr); SDL_UpdateWindowSurface(m_window); } - do + while (!m_should_exit.load(std::memory_order_acquire)) { UpdateDiscordStatus(); if (TaskScheduler) TaskScheduler->ExecuteOneTask(); - } while (!m_should_exit.Wait(SPLASH_FRAMERATE)); + Sleep(SPLASH_FRAMERATE); + } } void CApplication::HideSplash() @@ -575,7 +576,7 @@ void CApplication::HideSplash() ZoneScoped; - m_should_exit.Set(); + m_should_exit.store(true, std::memory_order_release); m_splash_thread.join(); SDL_DestroyWindow(m_window); diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 92b0da929da..8a9651cb4b6 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -18,7 +18,7 @@ class ENGINE_API CApplication final { SDL_Window* m_window{}; std::thread m_splash_thread; - Event m_should_exit; + std::atomic_bool m_should_exit; SDL_Surface* m_surface; From a0d5f091739248c21a710dca442f30d3d3677ee5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:26:53 +0500 Subject: [PATCH 342/497] Enumerate supported renderer modes in parallel --- src/xrEngine/EngineAPI.cpp | 40 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 997200d5991..49064bd8a7d 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -9,6 +9,7 @@ #include "xrCore/ModuleLookup.hpp" #include "xrCore/xr_token.h" +#include "xrCore/Threading/ParallelForEach.hpp" #include "xrScriptEngine/ScriptExporter.hpp" @@ -193,34 +194,31 @@ void CEngineAPI::CreateRendererList() } int modeIndex{}; - const auto obtainModes = [&](RendererModule* module) + const auto obtainModes = [&](const RendererDesc& desc) { - if (module) + if (!desc.module) + return; + + const auto& modes = desc.module->ObtainSupportedModes(); + for (pcstr mode : modes) { - const auto& modes = module->ObtainSupportedModes(); - for (pcstr mode : modes) + const auto it = std::find_if(renderModes.begin(), renderModes.end(), [&](auto& pair) + { + return 0 == xr_strcmp(mode, pair.first.c_str()); + }); + string256 temp; + if (it != renderModes.end()) { - const auto it = std::find_if(renderModes.begin(), renderModes.end(), [&](auto& pair) - { - return 0 == xr_strcmp(mode, pair.first.c_str()); - }); - string256 temp; - if (it != renderModes.end()) - { - xr_sprintf(temp, "%s__dup%d", mode, modeIndex); - mode = temp; - } - shared_str copiedMode = mode; - renderModes[copiedMode] = module; - VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! + xr_sprintf(temp, "%s__dup%d", mode, modeIndex); + mode = temp; } + shared_str copiedMode = mode; + renderModes[copiedMode] = desc.module; + VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! } }; - for (RendererDesc& desc : renderers) - { - obtainModes(desc.module); - } + xr_parallel_for_each(renderers, obtainModes); auto& modes = VidQualityToken; Msg("Available render modes[%d]:", modes.size()); From 7cb71cb15714efc4bc2c16cf7df6105f82283d9c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 11:30:44 +0500 Subject: [PATCH 343/497] Revert "Make splashscreen thread execute tasks too" This reverts commit 483aac7e588f418004ba9d53bf3f36c0f580c443. --- src/xrEngine/x_ray.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 29a4e40be59..b194c9b0d9b 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -563,8 +563,6 @@ void CApplication::SplashProc() while (!m_should_exit.load(std::memory_order_acquire)) { UpdateDiscordStatus(); - if (TaskScheduler) - TaskScheduler->ExecuteOneTask(); Sleep(SPLASH_FRAMERATE); } } From 65078c74607c9411c8edbd7c9412be4131cdb77c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 12:45:32 +0500 Subject: [PATCH 344/497] Fix crash on start --- src/xrEngine/x_ray.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index b194c9b0d9b..51bf524f318 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -377,16 +377,13 @@ CApplication::CApplication(pcstr commandLine) Device.Create(); TaskScheduler->Wait(createLightAnim); + TaskScheduler->Wait(createSoundDevicesList); g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); if (!g_pGamePersistent) Console->Show(); - // Wait for tasks just for sanity, - // e.g. in case of singlethreaded CPU - TaskScheduler->Wait(createSoundDevicesList); - FrameMarkEnd(APPLICATION_STARTUP); } From ab80948292a6400031f12cce9967ced3a92b3803 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 13:27:47 +0500 Subject: [PATCH 345/497] xrEngine/x_ray.cpp: remove PROFILE_TASK_SYSTEM facility [skip ci] It will interfere with further startup process parallelization --- src/xrEngine/x_ray.cpp | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 51bf524f318..1164edb3308 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -36,12 +36,6 @@ #include "xrCore/Text/StringConversion.hpp" #endif -//#define PROFILE_TASK_SYSTEM - -#ifdef PROFILE_TASK_SYSTEM -#include "xrCore/Threading/ParallelForEach.hpp" -#endif - // global variables constexpr size_t MAX_WINDOW_EVENTS = 32; @@ -264,9 +258,7 @@ CApplication::CApplication(pcstr commandLine) if (!strstr(commandLine, "-nosplash")) { const bool topmost = !strstr(commandLine, "-splashnotop"); -#ifndef PROFILE_TASK_SYSTEM ShowSplash(topmost); -#endif } pcstr fsltx = "-fsltx "; @@ -279,35 +271,6 @@ CApplication::CApplication(pcstr commandLine) Core.Initialize("OpenXRay", commandLine, true, *fsgame ? fsgame : nullptr); -#ifdef PROFILE_TASK_SYSTEM - const auto task = [](const TaskRange&){}; - - constexpr int task_count = 1048576; - constexpr int iterations = 250; - u64 results[iterations]; - - CTimer timer; - for (int i = 0; i < iterations; ++i) - { - timer.Start(); - xr_parallel_for(TaskRange(0, task_count, 1), task); - results[i] = timer.GetElapsed_ns(); - } - - u64 min = std::numeric_limits::max(); - u64 average{}; - for (int i = 0; i < iterations; ++i) - { - min = std::min(min, results[i]); - average += results[i] / 1000; - Log("Time:", results[i]); - } - Msg("Time min: %f microseconds", float(min) / 1000.f); - Msg("Time average: %f microseconds", float(average) / float(iterations)); - - return; -#endif - const auto& inputTask = TaskScheduler->AddTask([](Task&, void*) { const bool captureInput = !strstr(Core.Params, "-i"); @@ -391,7 +354,6 @@ CApplication::~CApplication() { FrameMarkStart(APPLICATION_SHUTDOWN); -#ifndef PROFILE_TASK_SYSTEM // Destroy APP DEL_INSTANCE(g_pGamePersistent); Engine.Event.Dump(); @@ -428,7 +390,6 @@ CApplication::~CApplication() CreateProcess(g_sLaunchOnExit_app, g_sLaunchOnExit_params, nullptr, nullptr, FALSE, 0, nullptr, tempDir, &si, &pi); #endif } -#endif // PROFILE_TASK_SYSTEM Core._destroy(); { @@ -440,9 +401,6 @@ CApplication::~CApplication() int CApplication::Run() { -#ifdef PROFILE_TASK_SYSTEM - return 0; -#endif HideSplash(); Device.Run(); From 2f5a1af848fcecca6f92aabdc0c6c40fcc06d5c8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 14:24:11 +0500 Subject: [PATCH 346/497] xrCore/xrCore.h: move CoInitializeEx call to _initialize() Unfortunately, this can't be removed completely, as OpenAL uses Windows interfaces to initialize sound devices and they are based on COM. If we remove it, OpenAL will call CoInitializeEx itself and then it'll call CoUninitialize each time we enumerate the device, making the xrSound initialization process twice as slow --- src/xrCore/xrCore.cpp | 17 +++++------------ src/xrCore/xrCore.h | 2 -- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index afb168a0e47..6ae0f00e21a 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -180,16 +180,14 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, if (0 == init_counter) { PluginMode = plugin; - // Init COM so we can use CoCreateInstance - // HRESULT co_res = if (commandLine) Params = xr_strdup(commandLine); else Params = xr_strdup(""); - CoInitializeMultithreaded(); - #if defined(XR_PLATFORM_WINDOWS) + CoInitializeEx(nullptr, COINIT_MULTITHREADED); // needed for OpenAL initialization + string_path fn, dr, di; // application path @@ -339,15 +337,10 @@ void xrCore::_destroy() TaskScheduler = nullptr; xr_free(Params); Memory._destroy(); - } -} - -void xrCore::CoInitializeMultithreaded() const -{ -#if defined(XR_PLATFORM_WINDOWS) - if (!strstr(Params, "-weather")) - CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#ifdef XR_PLATFORM_WINDOWS + CoUninitialize(); #endif + } } #if defined(XR_PLATFORM_WINDOWS) diff --git a/src/xrCore/xrCore.h b/src/xrCore/xrCore.h index 69b0a73f5ae..85df6e7f606 100644 --- a/src/xrCore/xrCore.h +++ b/src/xrCore/xrCore.h @@ -131,8 +131,6 @@ class XRCORE_API xrCore static pcstr GetBuildCommit() { return buildCommit; } static pcstr GetBuildBranch() { return buildBranch; } - void CoInitializeMultithreaded() const; - private: void CalculateBuildId(); void PrintBuildInfo(); From b2a42cb4185cfdd0f7d7bd903486cc1659d0056e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 14:29:10 +0500 Subject: [PATCH 347/497] xrEngine/x_ray.cpp: load LTX configs in parallel --- src/xrEngine/x_ray.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 1164edb3308..2de9c09c24f 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -118,16 +118,7 @@ void InitSettings() { ZoneScoped; - xr_auth_strings_t ignoredPaths, checkedPaths; - fill_auth_check_params(ignoredPaths, checkedPaths); //TODO port xrNetServer to Linux - PathIncludePred includePred(&ignoredPaths); - CInifile::allow_include_func_t includeFilter; - includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); - - InitConfig(pSettings, "system.ltx"); - InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); InitConfig(pSettingsOpenXRay, "openxray.ltx", false, true, true, false); - InitConfig(pGameIni, "game.ltx"); if (strstr(Core.Params, "-shoc") || strstr(Core.Params, "-soc")) set_shoc_mode(); @@ -149,6 +140,31 @@ void InitSettings() else if (xr_strcmpi("unlock", gameMode) == 0) set_free_mode(); } + + const auto& initSettings = TaskScheduler->AddTask([](Task&, void*) + { + InitConfig(pSettings, "system.ltx"); + }); + + const auto& initSettingsAuth = TaskScheduler->AddTask([](Task&, void*) + { + xr_auth_strings_t ignoredPaths, checkedPaths; + fill_auth_check_params(ignoredPaths, checkedPaths); + PathIncludePred includePred(&ignoredPaths); + CInifile::allow_include_func_t includeFilter; + includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); + + InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); + }); + + const auto& initGameSettings = TaskScheduler->AddTask([](Task&, void*) + { + InitConfig(pGameIni, "game.ltx"); + }); + + TaskScheduler->Wait(initSettings); + TaskScheduler->Wait(initSettingsAuth); + TaskScheduler->Wait(initGameSettings); } void InitConsole() From 6471c2c46c25fa231381a2e0d08ed3f2e89b131b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 15:09:53 +0500 Subject: [PATCH 348/497] xrEngine.cpp: default initialize g_sLaunch* variables --- src/xrEngine/x_ray.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 2de9c09c24f..53900493dec 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -48,9 +48,9 @@ ENGINE_API bool CallOfPripyatMode = false; ENGINE_API bool ClearSkyMode = false; ENGINE_API bool ShadowOfChernobylMode = false; -ENGINE_API string512 g_sLaunchOnExit_params; -ENGINE_API string512 g_sLaunchOnExit_app; -ENGINE_API string_path g_sLaunchWorkingFolder; +ENGINE_API string512 g_sLaunchOnExit_params{}; +ENGINE_API string512 g_sLaunchOnExit_app{}; +ENGINE_API string_path g_sLaunchWorkingFolder{}; namespace { @@ -303,9 +303,6 @@ CApplication::CApplication(pcstr commandLine) Engine.External.CreateRendererList(); }); - *g_sLaunchOnExit_app = 0; - *g_sLaunchOnExit_params = 0; - InitSettings(); // Adjust player & computer name for Asian if (pSettings->line_exist("string_table", "no_native_input")) From 345f193984f316546647e2f47e5844d49cb37468 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 15:29:11 +0500 Subject: [PATCH 349/497] Separate rendering hardware capabilities check from shaders existance check This allows us to check renderers in parallel --- src/Layers/xrRenderPC_GL/xrRender_GL.cpp | 17 +++++---- src/Layers/xrRenderPC_R4/xrRender_R4.cpp | 17 +++++---- src/xrEngine/EngineAPI.cpp | 46 ++++++++++++------------ src/xrEngine/EngineAPI.h | 4 +-- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp index 63c5e38d44a..1524f72a591 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp @@ -18,12 +18,6 @@ class RGLRendererModule final : public RendererModule { return false; } - // Check if shaders are available - if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) - { - Log("~ No shaders found for OpenGL"); - return false; - } return xrRender_test_hw(); } @@ -38,6 +32,17 @@ class RGLRendererModule final : public RendererModule return modes; } + bool CheckGameRequirements() override + { + // Check if shaders are available + if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) + { + Log("~ No shaders found for OpenGL"); + return false; + } + return true; + } + void CheckModeConsistency(pcstr mode) const { R_ASSERT3(0 == xr_strcmp(mode, RENDERER_RGL_MODE), diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index e9b13f15c86..b68691348c0 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -24,12 +24,6 @@ class R4RendererModule final : public RendererModule { return FALSE; } - // Check if shaders are available - if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) - { - Log("~ No shaders found for xrRender_R4"); - return FALSE; - } return xrRender_test_hw(); } @@ -59,6 +53,17 @@ class R4RendererModule final : public RendererModule return modes; } + bool CheckGameRequirements() override + { + // Check if shaders are available + if (!FS.exist("$game_shaders$", RImplementation.getShaderPath())) + { + Log("~ No shaders found for xrRender_R4"); + return false; + } + return true; + } + void SetupEnv(pcstr mode) override { ZoneScoped; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 49064bd8a7d..2b4d6991c3f 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -59,37 +59,37 @@ bool is_enough_address_space_available() #endif } -pcstr CEngineAPI::SelectRenderer() +void CEngineAPI::SelectRenderer() { ZoneScoped; - cpcstr selected_mode = Console->GetString("renderer"); + // User has some renderer selected + // Find it and check if we can use it + pcstr selected_mode = Console->GetString("renderer"); const auto it = renderModes.find(selected_mode); if (it != renderModes.end()) { - selectedRenderer = it->second; + if (it->second->CheckGameRequirements()) + selectedRenderer = it->second; } - return selected_mode; -} - -void CEngineAPI::InitializeRenderers() -{ - ZoneScoped; - - pcstr selected_mode = SelectRenderer(); - if (selectedRenderer == nullptr - && VidQualityToken[0].id != -1) + // Renderer is either fully unsupported (hardware) + // or we don't comply with it requirements (e.g. shaders missing) + if (!selectedRenderer) { - // if engine failed to load renderer - // but there is at least one available - // then try again - string64 buf; - xr_sprintf(buf, "renderer %s", VidQualityToken[0].name); - Console->Execute(buf); - - // Second attempt - selected_mode = SelectRenderer(); + // Select any suitable + for (const auto& [mode, renderer] : renderModes) + { + if (renderer->CheckGameRequirements()) + { + selectedRenderer = renderer; + selected_mode = mode.c_str(); + string64 buf; + xr_sprintf(buf, "renderer %s", selected_mode); + Console->Execute(buf); + break; + } + } } // Ask current renderer to setup GEnv @@ -103,7 +103,7 @@ void CEngineAPI::Initialize(void) { ZoneScoped; - InitializeRenderers(); + SelectRenderer(); hGame = XRay::LoadModule("xrGame"); if (!CanSkipGameModuleLoading()) diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index 4c2b26499fc..826238ce336 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -44,6 +44,7 @@ class XR_NOVTABLE RendererModule public: virtual ~RendererModule() = default; virtual const xr_vector& ObtainSupportedModes() = 0; + virtual bool CheckGameRequirements() = 0; virtual void SetupEnv(pcstr mode) = 0; }; @@ -77,8 +78,7 @@ class ENGINE_API CEngineAPI void Initialize(); - void InitializeRenderers(); - pcstr SelectRenderer(); + void SelectRenderer(); void CloseUnusedLibraries(); void Destroy(); From ad382bd59f65875b3bb4fa6b2f09767f7ba0206b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 15:40:58 +0500 Subject: [PATCH 350/497] xrEngine/EngineAPI.cpp: protect VidQualityToken with mutex --- src/xrEngine/EngineAPI.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 2b4d6991c3f..2285a87497b 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -193,6 +193,8 @@ void CEngineAPI::CreateRendererList() } } + std::mutex mutex; + int modeIndex{}; const auto obtainModes = [&](const RendererDesc& desc) { @@ -214,6 +216,7 @@ void CEngineAPI::CreateRendererList() } shared_str copiedMode = mode; renderModes[copiedMode] = desc.module; + std::lock_guard guard{ mutex }; VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! } }; From 77b34509f9fca882c16119cddd5125c7b5d4fb5e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 16:37:14 +0500 Subject: [PATCH 351/497] Create sound devices, renderers list and input earlier --- src/xrEngine/x_ray.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 53900493dec..81768dac9ce 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -285,24 +285,24 @@ CApplication::CApplication(pcstr commandLine) sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); } - Core.Initialize("OpenXRay", commandLine, true, *fsgame ? fsgame : nullptr); - - const auto& inputTask = TaskScheduler->AddTask([](Task&, void*) + const auto& inputTask = TaskManager::AddTask([](Task&, void*) { const bool captureInput = !strstr(Core.Params, "-i"); pInput = xr_new(captureInput); }); - const auto& createSoundDevicesList = TaskScheduler->AddTask([](Task&, void*) + const auto& createSoundDevicesList = TaskManager::AddTask([](Task&, void*) { Engine.Sound.CreateDevicesList(); }); - const auto& createRendererList = TaskScheduler->AddTask([](Task&, void*) + const auto& createRendererList = TaskManager::AddTask([](Task&, void*) { Engine.External.CreateRendererList(); }); + Core.Initialize("OpenXRay", commandLine, true, *fsgame ? fsgame : nullptr); + InitSettings(); // Adjust player & computer name for Asian if (pSettings->line_exist("string_table", "no_native_input")) From fb9da1cf792d7d365577bf8f27ffa0062d74a4b7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 2 May 2024 16:37:32 +0500 Subject: [PATCH 352/497] Wait for the sounds devices list in the correct place --- src/xrEngine/x_ray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 81768dac9ce..7a02cf31e84 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -335,6 +335,7 @@ CApplication::CApplication(pcstr commandLine) #endif execUserScript(); + TaskScheduler->Wait(createSoundDevicesList); Engine.Sound.Create(); // ...command line for auto start @@ -353,7 +354,6 @@ CApplication::CApplication(pcstr commandLine) Device.Create(); TaskScheduler->Wait(createLightAnim); - TaskScheduler->Wait(createSoundDevicesList); g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); From 873a2ce40fc3f49d304b7cf4b07b524bed577878 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 03:42:22 +0500 Subject: [PATCH 353/497] xrGame/map_location.h|cpp: modernize and cleanup CMapLocation class --- src/xrGame/map_location.cpp | 68 +++++++++++++------------------------ src/xrGame/map_location.h | 68 ++++++++++++++++++------------------- 2 files changed, 57 insertions(+), 79 deletions(-) diff --git a/src/xrGame/map_location.cpp b/src/xrGame/map_location.cpp index b62aaa4464c..8c0d6fb40d8 100644 --- a/src/xrGame/map_location.cpp +++ b/src/xrGame/map_location.cpp @@ -65,42 +65,21 @@ static class CUISpotXmlManager : public CUIResetNotifier, public pureAppEnd } } g_uiSpotXml; -CMapLocation::CMapLocation(LPCSTR type, u16 object_id) +CMapLocation::CMapLocation(pcstr type, u16 object_id) + : m_objectID(object_id), + m_owner_se_object(ai().get_alife() ? ai().alife().objects().object(m_objectID, true) : nullptr) { m_flags.zero(); + m_flags.set(eHintEnabled, true); - m_level_spot = NULL; - m_level_spot_pointer = NULL; - m_minimap_spot = NULL; - m_minimap_spot_pointer = NULL; - m_complex_spot = NULL; - m_complex_spot_pointer = NULL; - - m_level_map_spot_border = NULL; - m_mini_map_spot_border = NULL; - m_complex_spot_border = NULL; - - m_level_map_spot_border_na = NULL; - m_mini_map_spot_border_na = NULL; - m_complex_spot_border_na = NULL; - - m_objectID = object_id; - m_actual_time = 0; - m_owner_se_object = (ai().get_alife()) ? ai().alife().objects().object(m_objectID, true) : NULL; - m_flags.set(eHintEnabled, TRUE); LoadSpot(type); - DisablePointer(); - EnableSpot(); - m_cached.m_Position.set(10000, 10000); - m_cached.m_updatedFrame = u32(-1); - m_cached.m_graphID = GameGraph::_GRAPH_ID(-1); + if (!IsGameTypeSingle()) m_cached.m_LevelName = Level().name(); } -CMapLocation::~CMapLocation() {} void CMapLocation::destroy() { delete_data(m_level_spot); @@ -119,46 +98,46 @@ void CMapLocation::destroy() delete_data(m_complex_spot_border_na); } -void CMapLocation::LoadSpot(LPCSTR type) +void CMapLocation::LoadSpot(pcstr type) { g_uiSpotXml.Load(); string512 path_base, path; xr_strcpy(path_base, type); R_ASSERT3(g_uiSpotXml->NavigateToNode(path_base, 0), "XML node not found in file map_spots.xml", path_base); - LPCSTR s = g_uiSpotXml->ReadAttrib(path_base, 0, "hint", "no hint"); + pcstr s = g_uiSpotXml->ReadAttrib(path_base, 0, "hint", "no hint"); SetHint(s); - s = g_uiSpotXml->ReadAttrib(path_base, 0, "store", NULL); + s = g_uiSpotXml->ReadAttrib(path_base, 0, "store", nullptr); if (s) { - m_flags.set(eSerailizable, TRUE); + m_flags.set(eSerailizable, true); } - s = g_uiSpotXml->ReadAttrib(path_base, 0, "no_offline", NULL); + s = g_uiSpotXml->ReadAttrib(path_base, 0, "no_offline", nullptr); if (s) { - m_flags.set(eHideInOffline, TRUE); + m_flags.set(eHideInOffline, true); } m_ttl = g_uiSpotXml->ReadAttribInt(path_base, 0, "ttl", 0); if (m_ttl > 0) { - m_flags.set(eTTL, TRUE); + m_flags.set(eTTL, true); UpdateTTL(); } - s = g_uiSpotXml->ReadAttrib(path_base, 0, "pos_to_actor", NULL); + s = g_uiSpotXml->ReadAttrib(path_base, 0, "pos_to_actor", nullptr); if (s) { - m_flags.set(ePosToActor, TRUE); + m_flags.set(ePosToActor, true); } - strconcat(sizeof(path), path, path_base, ":level_map"); + strconcat(path, path_base, ":level_map"); XML_NODE node = g_uiSpotXml->NavigateToNode(path, 0); if (node) { - LPCSTR str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_level_spot) @@ -195,11 +174,11 @@ void CMapLocation::LoadSpot(LPCSTR type) xr_delete(m_level_spot_pointer); } - strconcat(sizeof(path), path, path_base, ":mini_map"); + strconcat(path, path_base, ":mini_map"); node = g_uiSpotXml->NavigateToNode(path, 0); if (node) { - LPCSTR str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_minimap_spot) @@ -235,11 +214,11 @@ void CMapLocation::LoadSpot(LPCSTR type) xr_delete(m_minimap_spot_pointer); } - strconcat(sizeof(path), path, path_base, ":complex_spot"); + strconcat(path, path_base, ":complex_spot"); node = g_uiSpotXml->NavigateToNode(path, 0); if (node) { - LPCSTR str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_complex_spot) @@ -275,7 +254,7 @@ void CMapLocation::LoadSpot(LPCSTR type) xr_delete(m_complex_spot_pointer); } - if (m_minimap_spot == NULL && m_level_spot == NULL && m_complex_spot == NULL) + if (m_minimap_spot == nullptr && m_level_spot == nullptr && m_complex_spot == nullptr) { DisableSpot(); } @@ -721,11 +700,11 @@ void CMapLocation::SetHint(const shared_str& hint) m_hint = hint; }; -LPCSTR CMapLocation::GetHint() +pcstr CMapLocation::GetHint() const { if (!HintEnabled()) { - return NULL; + return nullptr; } return StringTable().translate(m_hint).c_str(); }; @@ -835,7 +814,6 @@ CRelationMapLocation::CRelationMapLocation(const shared_str& type, u16 object_id m_b_levelmap_visible = true; } -CRelationMapLocation::~CRelationMapLocation() {} xr_vector find_locations_res; bool CRelationMapLocation::Update() diff --git a/src/xrGame/map_location.h b/src/xrGame/map_location.h index f3d2c759d3f..eaf6e5c1bb7 100644 --- a/src/xrGame/map_location.h +++ b/src/xrGame/map_location.h @@ -28,43 +28,41 @@ class CMapLocation : public IPureDestroyableObject }; protected: - flags32 m_flags; + flags32 m_flags{}; shared_str m_hint; - CMapSpot* m_level_spot; - CMapSpotPointer* m_level_spot_pointer; - CMiniMapSpot* m_minimap_spot; - CMapSpotPointer* m_minimap_spot_pointer; - CComplexMapSpot* m_complex_spot; - CMapSpotPointer* m_complex_spot_pointer; + CMapSpot* m_level_spot{}; + CMapSpotPointer* m_level_spot_pointer{}; + CMiniMapSpot* m_minimap_spot{}; + CMapSpotPointer* m_minimap_spot_pointer{}; + CComplexMapSpot* m_complex_spot{}; + CMapSpotPointer* m_complex_spot_pointer{}; shared_str m_spot_border_names[6]; - CMapSpot* m_level_map_spot_border; - CMapSpot* m_mini_map_spot_border; - CMapSpot* m_complex_spot_border; + CMapSpot* m_level_map_spot_border{}; + CMapSpot* m_mini_map_spot_border{}; + CMapSpot* m_complex_spot_border{}; - CMapSpot* m_level_map_spot_border_na; - CMapSpot* m_mini_map_spot_border_na; - CMapSpot* m_complex_spot_border_na; + CMapSpot* m_level_map_spot_border_na{}; + CMapSpot* m_mini_map_spot_border_na{}; + CMapSpot* m_complex_spot_border_na{}; u16 m_objectID; - CSE_ALifeDynamicObject* m_owner_se_object; + CSE_ALifeDynamicObject* m_owner_se_object{}; int m_ttl; - u32 m_actual_time; + u32 m_actual_time{}; Fvector m_position_global; // last global position, actual time only current frame Fvector2 m_position_on_map; // last position on parent map, actual time only current frame struct SCachedValues { - u32 m_updatedFrame; - GameGraph::_GRAPH_ID m_graphID; - Fvector2 m_Position; + u32 m_updatedFrame{ u32(-1) }; + GameGraph::_GRAPH_ID m_graphID{ GameGraph::_GRAPH_ID(-1) }; + Fvector2 m_Position{ 10000, 10000 }; Fvector2 m_Direction; shared_str m_LevelName; bool m_Actuality; }; SCachedValues m_cached; -private: - CMapLocation(const CMapLocation&) { R_ASSERT(0); } // disable copy ctor protected: void UpdateSpot(CUICustomMap* map, CMapSpot* sp); void UpdateSpotPointer(CUICustomMap* map, CMapSpotPointer* sp); @@ -73,28 +71,30 @@ class CMapLocation : public IPureDestroyableObject CMapSpot* GetSpotBorder(CMapSpot* sp); public: - CMapLocation(LPCSTR type, u16 object_id); - virtual ~CMapLocation(); - virtual void destroy(); + CMapLocation(pcstr type, u16 object_id); - void LoadSpot(LPCSTR type); + CMapLocation(const CMapLocation&) = delete; - IC bool HintEnabled() { return !!m_flags.test(eHintEnabled); } - LPCSTR GetHint(); + void destroy() override; + + void LoadSpot(pcstr type); + + IC bool HintEnabled() const { return !!m_flags.test(eHintEnabled); } + pcstr GetHint() const; void SetHint(const shared_str& hint); - CComplexMapSpot* complex_spot() { return m_complex_spot; } - const CMapSpot* LevelMapSpot() { return m_level_spot; } - const CMiniMapSpot* MiniMapSpot() { return m_minimap_spot; } + CComplexMapSpot* complex_spot() const { return m_complex_spot; } + const CMapSpot* LevelMapSpot() const { return m_level_spot; } + const CMiniMapSpot* MiniMapSpot() const { return m_minimap_spot; } Fvector2 SpotSize(); void InitUserSpot(const shared_str& level_name, const Fvector& pos); void HighlightSpot(bool state, const Fcolor& color); IC bool IsUserDefined() const { return !!m_flags.test(eUserDefined); } IC void SetUserDefinedFlag(BOOL state) { m_flags.set(eUserDefined, state); } - IC bool PointerEnabled() { return SpotEnabled() && !!m_flags.test(ePointerEnabled); }; + IC bool PointerEnabled() const { return SpotEnabled() && !!m_flags.test(ePointerEnabled); } IC void EnablePointer() { m_flags.set(ePointerEnabled, TRUE); }; IC void DisablePointer() { m_flags.set(ePointerEnabled, FALSE); }; IC bool Collidable() const { return !!m_flags.test(eCollidable); } - IC bool SpotEnabled() { return !!m_flags.test(eSpotEnabled); }; + IC bool SpotEnabled() const { return !!m_flags.test(eSpotEnabled); } void EnableSpot() { m_flags.set(eSpotEnabled, TRUE); }; void DisableSpot() { m_flags.set(eSpotEnabled, FALSE); }; virtual void UpdateMiniMap(CUICustomMap* map); @@ -103,12 +103,12 @@ class CMapLocation : public IPureDestroyableObject void CalcPosition(); const Fvector2& CalcDirection(); IC const shared_str& GetLevelName() { return m_cached.m_LevelName; } - const Fvector2& GetPosition() { return m_cached.m_Position; } + const Fvector2& GetPosition() const { return m_cached.m_Position; } u16 ObjectID() { return m_objectID; } virtual bool Update(); void UpdateTTL(); - Fvector GetLastPosition() { return m_position_global; }; + Fvector GetLastPosition() const { return m_position_global; } bool Serializable() const { return !!m_flags.test(eSerailizable); } void SetSerializable(bool b) { m_flags.set(eSerailizable, b); } @@ -136,7 +136,7 @@ class CRelationMapLocation : public CMapLocation bool IsVisible() const { return m_b_visible; }; public: CRelationMapLocation(const shared_str& type, u16 object_id, u16 pInvOwnerActorID); - virtual ~CRelationMapLocation(); + virtual bool Update(); virtual void UpdateMiniMap(CUICustomMap* map); From 6071af74724d11ecbc505a39ad1177ca60a17383 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 06:49:12 +0500 Subject: [PATCH 354/497] xrCore/XML/XMLDocument.hpp: ability to get error state --- src/xrCore/XML/XMLDocument.cpp | 10 ++++++++++ src/xrCore/XML/XMLDocument.hpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/xrCore/XML/XMLDocument.cpp b/src/xrCore/XML/XMLDocument.cpp index 4a43a765672..95c7c6b55eb 100644 --- a/src/xrCore/XML/XMLDocument.cpp +++ b/src/xrCore/XML/XMLDocument.cpp @@ -201,6 +201,16 @@ bool XMLDocument::Set(pcstr text, bool fatal) return true; } +bool XMLDocument::IsErrored() const +{ + return m_Doc.Error(); +} + +pcstr XMLDocument::GetErrorDesc() const +{ + return m_Doc.ErrorDesc(); +} + XML_NODE XMLDocument::NavigateToNode(CONST_XML_NODE start_node, pcstr path, const size_t node_index) const { R_ASSERT3(start_node && path, "NavigateToNode failed in XML file ", m_xml_file_name); diff --git a/src/xrCore/XML/XMLDocument.hpp b/src/xrCore/XML/XMLDocument.hpp index 1dd4f88540e..097d66a649c 100644 --- a/src/xrCore/XML/XMLDocument.hpp +++ b/src/xrCore/XML/XMLDocument.hpp @@ -34,6 +34,9 @@ class XRCORE_API XMLDocument : public Noncopyable // Set XML directly. Doesn't support #include directive bool Set(pcstr text, bool fatal = true); + bool IsErrored() const; + pcstr GetErrorDesc() const; + //чтение элементов pcstr Read(pcstr path, const size_t index, pcstr default_str_val) const; pcstr Read(CONST_XML_NODE start_node, pcstr path, const size_t index, pcstr default_str_val) const; From fb41974c53fbb601525c483149cfa49e559ea4bc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 04:10:57 +0500 Subject: [PATCH 355/497] Remove global static g_uiSpotXml variable --- src/xrGame/map_location.cpp | 106 ++++++++++++------------------------ src/xrGame/map_manager.cpp | 4 ++ src/xrGame/map_manager.h | 2 + src/xrGame/map_spot.cpp | 76 +++++++++++++------------- src/xrGame/map_spot.h | 6 +- 5 files changed, 82 insertions(+), 112 deletions(-) diff --git a/src/xrGame/map_location.cpp b/src/xrGame/map_location.cpp index 8c0d6fb40d8..f59115257b1 100644 --- a/src/xrGame/map_location.cpp +++ b/src/xrGame/map_location.cpp @@ -28,43 +28,6 @@ #include "ActorHelmet.h" #include "Inventory.h" -static class CUISpotXmlManager : public CUIResetNotifier, public pureAppEnd -{ - CUIXml m_xml; - bool m_loaded{}; - -public: - void Load() - { - if (m_loaded) - return; - m_loaded = m_xml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "map_spots.xml"); - } - - void OnAppEnd() override - { - m_xml.ClearInternal(); - m_loaded = false; - } - - void OnUIReset() override - { - OnAppEnd(); - if (g_pGameLevel) - Load(); - } - - operator CUIXml*() - { - return &m_xml; - } - - CUIXml* operator->() - { - return &m_xml; - } -} g_uiSpotXml; - CMapLocation::CMapLocation(pcstr type, u16 object_id) : m_objectID(object_id), m_owner_se_object(ai().get_alife() ? ai().alife().objects().object(m_objectID, true) : nullptr) @@ -100,68 +63,68 @@ void CMapLocation::destroy() void CMapLocation::LoadSpot(pcstr type) { - g_uiSpotXml.Load(); + auto& uiXml = CMapManager::m_uiSpotXml; string512 path_base, path; xr_strcpy(path_base, type); - R_ASSERT3(g_uiSpotXml->NavigateToNode(path_base, 0), "XML node not found in file map_spots.xml", path_base); - pcstr s = g_uiSpotXml->ReadAttrib(path_base, 0, "hint", "no hint"); + R_ASSERT3(uiXml.NavigateToNode(path_base, 0), "XML node not found in file map_spots.xml", path_base); + pcstr s = uiXml.ReadAttrib(path_base, 0, "hint", "no hint"); SetHint(s); - s = g_uiSpotXml->ReadAttrib(path_base, 0, "store", nullptr); + s = uiXml.ReadAttrib(path_base, 0, "store", nullptr); if (s) { m_flags.set(eSerailizable, true); } - s = g_uiSpotXml->ReadAttrib(path_base, 0, "no_offline", nullptr); + s = uiXml.ReadAttrib(path_base, 0, "no_offline", nullptr); if (s) { m_flags.set(eHideInOffline, true); } - m_ttl = g_uiSpotXml->ReadAttribInt(path_base, 0, "ttl", 0); + m_ttl = uiXml.ReadAttribInt(path_base, 0, "ttl", 0); if (m_ttl > 0) { m_flags.set(eTTL, true); UpdateTTL(); } - s = g_uiSpotXml->ReadAttrib(path_base, 0, "pos_to_actor", nullptr); + s = uiXml.ReadAttrib(path_base, 0, "pos_to_actor", nullptr); if (s) { m_flags.set(ePosToActor, true); } strconcat(path, path_base, ":level_map"); - XML_NODE node = g_uiSpotXml->NavigateToNode(path, 0); + XML_NODE node = uiXml.NavigateToNode(path, 0); if (node) { - pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = uiXml.ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_level_spot) { m_level_spot = xr_new(this); } - m_level_spot->Load(g_uiSpotXml, str); + m_level_spot->Load(uiXml, str); } else { xr_delete(m_level_spot); } - m_spot_border_names[0] = g_uiSpotXml->ReadAttrib(path, 0, "spot_a", "level_map_spot_border"); - m_spot_border_names[1] = g_uiSpotXml->ReadAttrib(path, 0, "spot_na", ""); + m_spot_border_names[0] = uiXml.ReadAttrib(path, 0, "spot_a", "level_map_spot_border"); + m_spot_border_names[1] = uiXml.ReadAttrib(path, 0, "spot_na", ""); - str = g_uiSpotXml->ReadAttrib(path, 0, "pointer", ""); + str = uiXml.ReadAttrib(path, 0, "pointer", ""); if (xr_strlen(str)) { if (!m_level_spot_pointer) { m_level_spot_pointer = xr_new(this); } - m_level_spot_pointer->Load(g_uiSpotXml, str); + m_level_spot_pointer->Load(uiXml, str); } else { @@ -175,33 +138,33 @@ void CMapLocation::LoadSpot(pcstr type) } strconcat(path, path_base, ":mini_map"); - node = g_uiSpotXml->NavigateToNode(path, 0); + node = uiXml.NavigateToNode(path, 0); if (node) { - pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = uiXml.ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_minimap_spot) { m_minimap_spot = xr_new(this); } - m_minimap_spot->Load(g_uiSpotXml, str); + m_minimap_spot->Load(uiXml, str); } else { xr_delete(m_minimap_spot); } - m_spot_border_names[2] = g_uiSpotXml->ReadAttrib(path, 0, "spot_a", "mini_map_spot_border"); - m_spot_border_names[3] = g_uiSpotXml->ReadAttrib(path, 0, "spot_na", ""); + m_spot_border_names[2] = uiXml.ReadAttrib(path, 0, "spot_a", "mini_map_spot_border"); + m_spot_border_names[3] = uiXml.ReadAttrib(path, 0, "spot_na", ""); - str = g_uiSpotXml->ReadAttrib(path, 0, "pointer", ""); + str = uiXml.ReadAttrib(path, 0, "pointer", ""); if (xr_strlen(str)) { if (!m_minimap_spot_pointer) { m_minimap_spot_pointer = xr_new(this); } - m_minimap_spot_pointer->Load(g_uiSpotXml, str); + m_minimap_spot_pointer->Load(uiXml, str); } else { @@ -215,33 +178,33 @@ void CMapLocation::LoadSpot(pcstr type) } strconcat(path, path_base, ":complex_spot"); - node = g_uiSpotXml->NavigateToNode(path, 0); + node = uiXml.NavigateToNode(path, 0); if (node) { - pcstr str = g_uiSpotXml->ReadAttrib(path, 0, "spot", ""); + pcstr str = uiXml.ReadAttrib(path, 0, "spot", ""); if (xr_strlen(str)) { if (!m_complex_spot) { m_complex_spot = xr_new(this); } - m_complex_spot->Load(g_uiSpotXml, str); + m_complex_spot->Load(uiXml, str); } else { xr_delete(m_complex_spot); } - m_spot_border_names[4] = g_uiSpotXml->ReadAttrib(path, 0, "spot_a", "complex_map_spot_border"); - m_spot_border_names[5] = g_uiSpotXml->ReadAttrib(path, 0, "spot_na", ""); + m_spot_border_names[4] = uiXml.ReadAttrib(path, 0, "spot_a", "complex_map_spot_border"); + m_spot_border_names[5] = uiXml.ReadAttrib(path, 0, "spot_na", ""); - str = g_uiSpotXml->ReadAttrib(path, 0, "pointer", ""); + str = uiXml.ReadAttrib(path, 0, "pointer", ""); if (xr_strlen(str)) { if (!m_complex_spot_pointer) { m_complex_spot_pointer = xr_new(this); } - m_complex_spot_pointer->Load(g_uiSpotXml, str); + m_complex_spot_pointer->Load(uiXml, str); } else { @@ -735,6 +698,7 @@ CMapSpotPointer* CMapLocation::GetSpotPointer(CMapSpot* sp) CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) { R_ASSERT(sp); + auto& uiXml = CMapManager::m_uiSpotXml; if (PointerEnabled()) { if (sp == m_level_spot) @@ -742,7 +706,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_level_map_spot_border) { m_level_map_spot_border = xr_new(this); - m_level_map_spot_border->Load(g_uiSpotXml, m_spot_border_names[0].c_str()); + m_level_map_spot_border->Load(uiXml, m_spot_border_names[0].c_str()); } return m_level_map_spot_border; } @@ -751,7 +715,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_mini_map_spot_border) { m_mini_map_spot_border = xr_new(this); - m_mini_map_spot_border->Load(g_uiSpotXml, m_spot_border_names[2].c_str()); + m_mini_map_spot_border->Load(uiXml, m_spot_border_names[2].c_str()); } return m_mini_map_spot_border; } @@ -760,7 +724,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_complex_spot_border) { m_complex_spot_border = xr_new(this); - m_complex_spot_border->Load(g_uiSpotXml, m_spot_border_names[4].c_str()); + m_complex_spot_border->Load(uiXml, m_spot_border_names[4].c_str()); } return m_complex_spot_border; } @@ -772,7 +736,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_level_map_spot_border_na && m_spot_border_names[1].size()) { m_level_map_spot_border_na = xr_new(this); - m_level_map_spot_border_na->Load(g_uiSpotXml, m_spot_border_names[1].c_str()); + m_level_map_spot_border_na->Load(uiXml, m_spot_border_names[1].c_str()); } return m_level_map_spot_border_na; } @@ -781,7 +745,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_mini_map_spot_border_na && m_spot_border_names[3].size()) { m_mini_map_spot_border_na = xr_new(this); - m_mini_map_spot_border_na->Load(g_uiSpotXml, m_spot_border_names[3].c_str()); + m_mini_map_spot_border_na->Load(uiXml, m_spot_border_names[3].c_str()); } return m_mini_map_spot_border_na; } @@ -790,7 +754,7 @@ CMapSpot* CMapLocation::GetSpotBorder(CMapSpot* sp) if (NULL == m_complex_spot_border_na && m_spot_border_names[5].size()) { m_complex_spot_border_na = xr_new(this); - m_complex_spot_border_na->Load(g_uiSpotXml, m_spot_border_names[5].c_str()); + m_complex_spot_border_na->Load(uiXml, m_spot_border_names[5].c_str()); } return m_complex_spot_border_na; } diff --git a/src/xrGame/map_manager.cpp b/src/xrGame/map_manager.cpp index d59a048b233..c88d76b55f2 100644 --- a/src/xrGame/map_manager.cpp +++ b/src/xrGame/map_manager.cpp @@ -82,6 +82,7 @@ void CMapLocationRegistry::save(IWriter& stream) CMapManager::CMapManager() { + m_uiSpotXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "map_spots.xml"); m_locations_wrapper = xr_new(); m_locations_wrapper->registry().init(1); m_locations = NULL; @@ -91,6 +92,7 @@ CMapManager::~CMapManager() { delete_data(m_deffered_destroy_queue); // from prev frame delete_data(m_locations_wrapper); + m_uiSpotXml.ClearInternal(); } CMapLocation* CMapManager::AddMapLocation(const shared_str& spot_type, u16 id) @@ -138,6 +140,8 @@ void CMapManager::Destroy(CMapLocation* ml) { m_deffered_destroy_queue.push_back void CMapManager::OnUIReset() { + m_uiSpotXml.ClearInternal(); + m_uiSpotXml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "map_spots.xml"); for (const SLocationKey& locationKey : Locations()) { locationKey.location->LoadSpot(locationKey.spot_type.c_str()); diff --git a/src/xrGame/map_manager.h b/src/xrGame/map_manager.h index 2eb7d0fd4f3..7313df07f1b 100644 --- a/src/xrGame/map_manager.h +++ b/src/xrGame/map_manager.h @@ -35,4 +35,6 @@ class CMapManager : public CUIResetNotifier void Destroy(CMapLocation*); void OnUIReset() override; + + inline static CUIXml m_uiSpotXml; }; diff --git a/src/xrGame/map_spot.cpp b/src/xrGame/map_spot.cpp index 5c85956575d..df5d65b313b 100644 --- a/src/xrGame/map_spot.cpp +++ b/src/xrGame/map_spot.cpp @@ -23,32 +23,32 @@ CMapSpot::CMapSpot(CMapLocation* ml) : CUIStatic("Map Spot"), m_map_location(ml) m_scale_bounds.set(-1.0f, -1.0f); } -void CMapSpot::Load(CUIXml* xml, LPCSTR path) +void CMapSpot::Load(CUIXml& xml, LPCSTR path) { - CUIXmlInit::InitStatic(*xml, path, 0, this); + CUIXmlInit::InitStatic(xml, path, 0, this); if (!Heading()) { SetWidth(GetWidth() * UI().get_current_kx()); SetStretchTexture(true); } - int i = xml->ReadAttribInt(path, 0, "scale", 0); + int i = xml.ReadAttribInt(path, 0, "scale", 0); m_bScale = (i == 1); - m_scale_bounds.x = xml->ReadAttribFlt(path, 0, "scale_min", -1.0f); + m_scale_bounds.x = xml.ReadAttribFlt(path, 0, "scale_min", -1.0f); if (m_bScale) { - m_scale_bounds.y = xml->ReadAttribFlt(path, 0, "scale_max", -1.0f); + m_scale_bounds.y = xml.ReadAttribFlt(path, 0, "scale_max", -1.0f); R_ASSERT2((m_scale_bounds.x > 0 && m_scale_bounds.y > 0) || ShadowOfChernobylMode, path); } - m_location_level = xml->ReadAttribInt(path, 0, "location_level", 0); + m_location_level = xml.ReadAttribInt(path, 0, "location_level", 0); m_originSize = GetWndSize(); string512 str; strconcat(sizeof(str), str, path, ":static_border"); - if (xml->NavigateToNode(str)) + if (xml.NavigateToNode(str)) { - m_border_static = UIHelper::CreateStatic(*xml, str, this); + m_border_static = UIHelper::CreateStatic(xml, str, this); m_border_static->Show(false); if (!Heading()) { @@ -120,7 +120,7 @@ LPCSTR CMapSpotPointer::GetHint() { return NULL; } ////////////////////////////////////////////////// CMiniMapSpot::CMiniMapSpot(CMapLocation* ml) : inherited(ml) {} CMiniMapSpot::~CMiniMapSpot() {} -void CMiniMapSpot::Load(CUIXml* xml, LPCSTR path) +void CMiniMapSpot::Load(CUIXml& xml, LPCSTR path) { inherited::Load(xml, path); @@ -129,23 +129,23 @@ void CMiniMapSpot::Load(CUIXml* xml, LPCSTR path) Frect base_rect; base_rect.x1 = 0; base_rect.y1 = 0; - base_rect.x2 = xml->ReadAttribFlt(path, 0, "width", 0); - base_rect.y2 = xml->ReadAttribFlt(path, 0, "height", 0); + base_rect.x2 = xml.ReadAttribFlt(path, 0, "width", 0); + base_rect.y2 = xml.ReadAttribFlt(path, 0, "height", 0); Frect _stored_rect = m_UIStaticItem.GetTextureRect(); strconcat(sizeof(buf), buf, path, ":texture_above"); - XML_NODE n = xml->NavigateToNode(buf, 0); + XML_NODE n = xml.NavigateToNode(buf, 0); if (n) { - LPCSTR texture = xml->Read(buf, 0, NULL); + LPCSTR texture = xml.Read(buf, 0, NULL); CUITextureMaster::InitTexture(texture, &m_UIStaticItem); if (strchr(texture, _DELIMITER)) { - float x = xml->ReadAttribFlt(buf, 0, "x", base_rect.x1); - float y = xml->ReadAttribFlt(buf, 0, "y", base_rect.y1); - float width = xml->ReadAttribFlt(buf, 0, "width", base_rect.width()); - float height = xml->ReadAttribFlt(buf, 0, "height", base_rect.height()); + float x = xml.ReadAttribFlt(buf, 0, "x", base_rect.x1); + float y = xml.ReadAttribFlt(buf, 0, "y", base_rect.y1); + float width = xml.ReadAttribFlt(buf, 0, "width", base_rect.width()); + float height = xml.ReadAttribFlt(buf, 0, "height", base_rect.height()); m_tex_rect_above.set(x, y, x + width, y + height); } else @@ -155,17 +155,17 @@ void CMiniMapSpot::Load(CUIXml* xml, LPCSTR path) } strconcat(sizeof(buf), buf, path, ":texture_below"); - n = xml->NavigateToNode(buf, 0); + n = xml.NavigateToNode(buf, 0); if (n) { - LPCSTR texture = xml->Read(buf, 0, NULL); + LPCSTR texture = xml.Read(buf, 0, NULL); CUITextureMaster::InitTexture(texture, &m_UIStaticItem); if (strchr(texture, _DELIMITER)) { - float x = xml->ReadAttribFlt(buf, 0, "x", base_rect.x1); - float y = xml->ReadAttribFlt(buf, 0, "y", base_rect.y1); - float width = xml->ReadAttribFlt(buf, 0, "width", base_rect.width()); - float height = xml->ReadAttribFlt(buf, 0, "height", base_rect.height()); + float x = xml.ReadAttribFlt(buf, 0, "x", base_rect.x1); + float y = xml.ReadAttribFlt(buf, 0, "y", base_rect.y1); + float width = xml.ReadAttribFlt(buf, 0, "width", base_rect.width()); + float height = xml.ReadAttribFlt(buf, 0, "height", base_rect.height()); m_tex_rect_below.set(x, y, x + width, y + height); } else @@ -174,17 +174,17 @@ void CMiniMapSpot::Load(CUIXml* xml, LPCSTR path) m_icon_below = m_UIStaticItem.GetShader(); } strconcat(sizeof(buf), buf, path, ":texture"); - n = xml->NavigateToNode(buf, 0); + n = xml.NavigateToNode(buf, 0); if (n) { - LPCSTR texture = xml->Read(buf, 0, NULL); + LPCSTR texture = xml.Read(buf, 0, NULL); CUITextureMaster::InitTexture(texture, &m_UIStaticItem); if (strchr(texture, _DELIMITER)) { - float x = xml->ReadAttribFlt(buf, 0, "x", base_rect.x1); - float y = xml->ReadAttribFlt(buf, 0, "y", base_rect.y1); - float width = xml->ReadAttribFlt(buf, 0, "width", base_rect.width()); - float height = xml->ReadAttribFlt(buf, 0, "height", base_rect.height()); + float x = xml.ReadAttribFlt(buf, 0, "x", base_rect.x1); + float y = xml.ReadAttribFlt(buf, 0, "y", base_rect.y1); + float width = xml.ReadAttribFlt(buf, 0, "width", base_rect.width()); + float height = xml.ReadAttribFlt(buf, 0, "height", base_rect.height()); m_tex_rect_normal.set(x, y, x + width, y + height); } else @@ -259,20 +259,20 @@ CUIStaticOrig* CComplexMapSpot::CreateStaticOrig(CUIXml& xml, LPCSTR ui_path) return ui; } -void CComplexMapSpot::Load(CUIXml* xml, LPCSTR path) // complex_spot_template +void CComplexMapSpot::Load(CUIXml& xml, LPCSTR path) // complex_spot_template { inherited::Load(xml, path); - XML_NODE stored_root = xml->GetLocalRoot(); - XML_NODE node = xml->NavigateToNode(path, 0); - xml->SetLocalRoot(node); + XML_NODE stored_root = xml.GetLocalRoot(); + XML_NODE node = xml.NavigateToNode(path, 0); + xml.SetLocalRoot(node); - m_left_icon = CreateStaticOrig(*xml, "left_icon"); - m_right_icon = CreateStaticOrig(*xml, "right_icon"); - m_top_icon = CreateStaticOrig(*xml, "top_icon"); - m_timer = CreateStaticOrig(*xml, "timer"); + m_left_icon = CreateStaticOrig(xml, "left_icon"); + m_right_icon = CreateStaticOrig(xml, "right_icon"); + m_top_icon = CreateStaticOrig(xml, "top_icon"); + m_timer = CreateStaticOrig(xml, "timer"); - xml->SetLocalRoot(stored_root); + xml.SetLocalRoot(stored_root); } void CComplexMapSpot::SetTimerFinish(ALife::_TIME_ID time) // ms diff --git a/src/xrGame/map_spot.h b/src/xrGame/map_spot.h index 92250b78d0c..f1bc4bd304d 100644 --- a/src/xrGame/map_spot.h +++ b/src/xrGame/map_spot.h @@ -25,7 +25,7 @@ class CMapSpot : public CUIStatic public: CMapSpot(CMapLocation*); - virtual void Load(CUIXml* xml, LPCSTR path); + virtual void Load(CUIXml& xml, LPCSTR path); CMapLocation* MapLocation() { return m_map_location; } int get_location_level() { return m_location_level; } virtual LPCSTR GetHint(); @@ -61,7 +61,7 @@ class CMiniMapSpot final : public CMapSpot public: CMiniMapSpot(CMapLocation*); virtual ~CMiniMapSpot(); - virtual void Load(CUIXml* xml, LPCSTR path); + virtual void Load(CUIXml& xml, LPCSTR path) override; virtual void Draw(); pcstr GetDebugType() override { return "CMiniMapSpot"; } }; @@ -101,7 +101,7 @@ class CComplexMapSpot final : public CMapSpot public: CComplexMapSpot(CMapLocation*); virtual ~CComplexMapSpot(); - virtual void Load(CUIXml* xml, LPCSTR path); + virtual void Load(CUIXml& xml, LPCSTR path) override; virtual void Update(); virtual void SetWndSize(const Fvector2& size); From f4a9f48ed46679df1845774423eeea36eccba278 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 06:07:28 +0500 Subject: [PATCH 356/497] Remove global static g_gameTaskXml variable --- src/xrGame/GameTask.cpp | 89 ++++++++++++++++------------------ src/xrGame/GametaskManager.cpp | 3 ++ src/xrGame/GametaskManager.h | 3 ++ 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/xrGame/GameTask.cpp b/src/xrGame/GameTask.cpp index f21f19771a7..2d2dab98c2e 100644 --- a/src/xrGame/GameTask.cpp +++ b/src/xrGame/GameTask.cpp @@ -16,12 +16,11 @@ #include "alife_registry_wrappers.h" #include "alife_simulator.h" #include "alife_story_registry.h" +#include "GametaskManager.h" #include "game_object_space.h" #include "Common/object_broker.h" #include "xrUICore/XML/UITextureMaster.h" -CUIXml* g_gameTaskXml = nullptr; - ALife::_STORY_ID story_id(cpcstr story_id) { using namespace luabind; @@ -77,24 +76,20 @@ CGameTask::CGameTask(const TASK_ID& id) void CGameTask::Load(const TASK_ID& id) { m_ID = id; - static bool successfulLoading = false; - if (!g_gameTaskXml) - { - g_gameTaskXml = new CUIXml(); - successfulLoading = g_gameTaskXml->Load(CONFIG_PATH, "gameplay", "game_tasks.xml", false); - } - if (!successfulLoading) + + auto& gameTaskXml = CGameTaskManager::m_gameTaskXml; // not multithread friendly + if (gameTaskXml.IsErrored()) { - Msg("Trying to load task [%s], but failed to load gameplay/game_tasks.xml", m_ID.c_str()); + Msg("! Trying to load task [%s], but failed to load gameplay/game_tasks.xml", m_ID.c_str()); return; } - const XML_NODE task_node = g_gameTaskXml->NavigateToNodeWithAttribute("game_task", "id", *id); + const XML_NODE task_node = gameTaskXml.NavigateToNodeWithAttribute("game_task", "id", *id); THROW3(task_node, "game task id = ", id.c_str()); - g_gameTaskXml->SetLocalRoot(task_node); - m_Title = g_gameTaskXml->Read(g_gameTaskXml->GetLocalRoot(), "title", 0, nullptr); - m_priority = g_gameTaskXml->ReadAttribInt(g_gameTaskXml->GetLocalRoot(), "prio", -1); + gameTaskXml.SetLocalRoot(task_node); + m_Title = gameTaskXml.Read(gameTaskXml.GetLocalRoot(), "title", 0, nullptr); + m_priority = gameTaskXml.ReadAttribInt(gameTaskXml.GetLocalRoot(), "prio", -1); #ifdef DEBUG if (m_priority == u32(-1)) @@ -103,35 +98,35 @@ void CGameTask::Load(const TASK_ID& id) } #endif - const int tag_num = g_gameTaskXml->GetNodesNum(g_gameTaskXml->GetLocalRoot(), "objective"); + const int tag_num = gameTaskXml.GetNodesNum(gameTaskXml.GetLocalRoot(), "objective"); m_Objectives.clear(); for (int i = 0; i < tag_num; i++) { - const XML_NODE l_root = g_gameTaskXml->NavigateToNode("objective", i); - g_gameTaskXml->SetLocalRoot(l_root); + const XML_NODE l_root = gameTaskXml.NavigateToNode("objective", i); + gameTaskXml.SetLocalRoot(l_root); SGameTaskObjective& objective = (i == ROOT_TASK_OBJECTIVE) ? *this : m_Objectives.emplace_back(this, i); //. - pcstr tag_text = g_gameTaskXml->Read(l_root, "text", 0, nullptr); + pcstr tag_text = gameTaskXml.Read(l_root, "text", 0, nullptr); objective.m_Description = tag_text; //. - tag_text = g_gameTaskXml->Read(l_root, "article", 0, nullptr); + tag_text = gameTaskXml.Read(l_root, "article", 0, nullptr); if (tag_text) objective.m_article_id = tag_text; //. - tag_text = g_gameTaskXml->ReadAttrib(l_root, "key", nullptr); + tag_text = gameTaskXml.ReadAttrib(l_root, "key", nullptr); if (tag_text) objective.m_article_key = tag_text; //. if (i == ROOT_TASK_OBJECTIVE) { - objective.m_icon_texture_name = g_gameTaskXml->Read(g_gameTaskXml->GetLocalRoot(), "icon", 0, nullptr); + objective.m_icon_texture_name = gameTaskXml.Read(gameTaskXml.GetLocalRoot(), "icon", 0, nullptr); if (objective.m_icon_texture_name.size() && 0 != xr_stricmp(*objective.m_icon_texture_name, "ui\\ui_icons_task")) { @@ -141,19 +136,19 @@ void CGameTask::Load(const TASK_ID& id) } else if (objective.m_icon_texture_name.size()) { - objective.m_icon_rect.x1 = g_gameTaskXml->ReadAttribFlt(l_root, "icon", 0, "x"); - objective.m_icon_rect.y1 = g_gameTaskXml->ReadAttribFlt(l_root, "icon", 0, "y"); - objective.m_icon_rect.x2 = g_gameTaskXml->ReadAttribFlt(l_root, "icon", 0, "width"); - objective.m_icon_rect.y2 = g_gameTaskXml->ReadAttribFlt(l_root, "icon", 0, "height"); + objective.m_icon_rect.x1 = gameTaskXml.ReadAttribFlt(l_root, "icon", 0, "x"); + objective.m_icon_rect.y1 = gameTaskXml.ReadAttribFlt(l_root, "icon", 0, "y"); + objective.m_icon_rect.x2 = gameTaskXml.ReadAttribFlt(l_root, "icon", 0, "width"); + objective.m_icon_rect.y2 = gameTaskXml.ReadAttribFlt(l_root, "icon", 0, "height"); } } //. - objective.m_map_location = g_gameTaskXml->Read(l_root, "map_location_type", 0, nullptr); + objective.m_map_location = gameTaskXml.Read(l_root, "map_location_type", 0, nullptr); - cpcstr object_story_id = g_gameTaskXml->Read(l_root, "object_story_id", 0, nullptr); + cpcstr object_story_id = gameTaskXml.Read(l_root, "object_story_id", 0, nullptr); //* - objective.m_def_location_enabled = !g_gameTaskXml->ReadInt(l_root, "map_location_hidden", 0, 0); + objective.m_def_location_enabled = !gameTaskXml.ReadInt(l_root, "map_location_hidden", 0, 0); [[maybe_unused]] const bool b1 = (0 == objective.m_map_location.size()); [[maybe_unused]] const bool b2 = (nullptr == object_story_id); @@ -164,7 +159,7 @@ void CGameTask::Load(const TASK_ID& id) objective.m_map_object_id = u16(-1); //. - objective.m_map_hint = g_gameTaskXml->ReadAttrib(l_root, "map_location_type", 0, "hint", nullptr); + objective.m_map_hint = gameTaskXml.ReadAttrib(l_root, "map_location_type", 0, "hint", nullptr); if (object_story_id) { @@ -174,53 +169,53 @@ void CGameTask::Load(const TASK_ID& id) //------infoportion_complete { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "infoportion_complete"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "infoportion_complete"); objective.m_completeInfos.resize(info_num); for (int j = 0; j < info_num; ++j) { - objective.m_completeInfos[j] = g_gameTaskXml->Read(l_root, "infoportion_complete", j, nullptr); + objective.m_completeInfos[j] = gameTaskXml.Read(l_root, "infoportion_complete", j, nullptr); } } //------infoportion_fail { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "infoportion_fail"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "infoportion_fail"); objective.m_failInfos.resize(info_num); for (int j = 0; j < info_num; ++j) { - objective.m_failInfos[j] = g_gameTaskXml->Read(l_root, "infoportion_fail", j, nullptr); + objective.m_failInfos[j] = gameTaskXml.Read(l_root, "infoportion_fail", j, nullptr); } } //------infoportion_set_complete { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "infoportion_set_complete"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "infoportion_set_complete"); objective.m_infos_on_complete.resize(info_num); for (int j = 0; j < info_num; ++j) { - objective.m_infos_on_complete[j] = g_gameTaskXml->Read(l_root, "infoportion_set_complete", j, nullptr); + objective.m_infos_on_complete[j] = gameTaskXml.Read(l_root, "infoportion_set_complete", j, nullptr); } } //------infoportion_set_fail { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "infoportion_set_fail"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "infoportion_set_fail"); objective.m_infos_on_fail.resize(info_num); for (int j = 0; j < info_num; ++j) { - objective.m_infos_on_fail[j] = g_gameTaskXml->Read(l_root, "infoportion_set_fail", j, nullptr); + objective.m_infos_on_fail[j] = gameTaskXml.Read(l_root, "infoportion_set_fail", j, nullptr); } } //------function_complete { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "function_complete"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "function_complete"); objective.m_complete_lua_functions.resize(info_num); for (int j = 0; j < info_num; ++j) { - cpcstr str = g_gameTaskXml->Read(l_root, "function_complete", j, nullptr); + cpcstr str = gameTaskXml.Read(l_root, "function_complete", j, nullptr); [[maybe_unused]] const bool functor_exists = GEnv.ScriptEngine->functor(str, objective.m_complete_lua_functions[j]); THROW3(functor_exists, "Cannot find script function described in task objective ", str); } @@ -228,11 +223,11 @@ void CGameTask::Load(const TASK_ID& id) //------function_fail { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "function_fail"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "function_fail"); objective.m_fail_lua_functions.resize(info_num); for (int j = 0; j < info_num; ++j) { - cpcstr str = g_gameTaskXml->Read(l_root, "function_fail", j, nullptr); + cpcstr str = gameTaskXml.Read(l_root, "function_fail", j, nullptr); [[maybe_unused]] const bool functor_exists = GEnv.ScriptEngine->functor(str, objective.m_fail_lua_functions[j]); THROW3(functor_exists, "Cannot find script function described in task objective ", str); } @@ -240,11 +235,11 @@ void CGameTask::Load(const TASK_ID& id) //------function_on_complete { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "function_call_complete"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "function_call_complete"); objective.m_lua_functions_on_complete.resize(info_num); for (int i = 0; i < info_num; ++i) { - cpcstr str = g_gameTaskXml->Read(l_root, "function_call_complete", i, nullptr); + cpcstr str = gameTaskXml.Read(l_root, "function_call_complete", i, nullptr); [[maybe_unused]] const bool functor_exists = GEnv.ScriptEngine->functor(str, objective.m_lua_functions_on_complete[i]); THROW3(functor_exists, "Cannot find script function described in task objective ", str); } @@ -252,19 +247,19 @@ void CGameTask::Load(const TASK_ID& id) //------function_on_fail { - const int info_num = g_gameTaskXml->GetNodesNum(l_root, "function_call_fail"); + const int info_num = gameTaskXml.GetNodesNum(l_root, "function_call_fail"); objective.m_lua_functions_on_fail.resize(info_num); for (int j = 0; j < info_num; ++j) { - cpcstr str = g_gameTaskXml->Read(l_root, "function_call_fail", j, nullptr); + cpcstr str = gameTaskXml.Read(l_root, "function_call_fail", j, nullptr); [[maybe_unused]] const bool functor_exists = GEnv.ScriptEngine->functor(str, objective.m_lua_functions_on_fail[j]); THROW3(functor_exists, "Cannot find script function described in task objective ", str); } } - g_gameTaskXml->SetLocalRoot(task_node); + gameTaskXml.SetLocalRoot(task_node); } - g_gameTaskXml->SetLocalRoot(g_gameTaskXml->GetRoot()); + gameTaskXml.SetLocalRoot(gameTaskXml.GetRoot()); } void SGameTaskObjective::SetTaskState(ETaskState state) diff --git a/src/xrGame/GametaskManager.cpp b/src/xrGame/GametaskManager.cpp index 434c56c1ea2..fc075de71da 100644 --- a/src/xrGame/GametaskManager.cpp +++ b/src/xrGame/GametaskManager.cpp @@ -36,6 +36,8 @@ bool task_prio_pred(const SGameTaskKey& k1, const SGameTaskKey& k2) CGameTaskManager::CGameTaskManager() { + m_gameTaskXml.Load(CONFIG_PATH, "gameplay", "game_tasks.xml", false); + m_gametasks_wrapper = xr_new(); m_gametasks_wrapper->registry().init(0); // actor's id m_flags.zero(); @@ -60,6 +62,7 @@ CGameTaskManager::~CGameTaskManager() delete_data(m_gametasks_wrapper); for (auto& taskId : g_active_task_id) taskId = nullptr; + m_gameTaskXml.ClearInternal(); } vGameTasks& CGameTaskManager::GetGameTasks() diff --git a/src/xrGame/GametaskManager.h b/src/xrGame/GametaskManager.h index ab416dc72e4..0e407c8e953 100644 --- a/src/xrGame/GametaskManager.h +++ b/src/xrGame/GametaskManager.h @@ -56,4 +56,7 @@ class CGameTaskManager void ResetStorage() { m_gametasks = NULL; }; void DumpTasks(); + +public: + inline static CUIXml m_gameTaskXml; }; From 396ce1dbbdd369214a381c1dcc7f8b2ab2158ec0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 07:17:03 +0500 Subject: [PATCH 357/497] xrGame/Weapon.cpp: don't autoinitialize UIReset event If pWpnScopeXml gets initialized earlier than Device, it's UB. --- src/xrGame/Weapon.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/xrGame/Weapon.cpp b/src/xrGame/Weapon.cpp index e571052d4d1..e3754af5b5b 100644 --- a/src/xrGame/Weapon.cpp +++ b/src/xrGame/Weapon.cpp @@ -33,7 +33,7 @@ BOOL b_toggle_weapon_aim = FALSE; -static class CUIWpnScopeXmlManager : public CUIResetNotifier, public pureAppEnd +static class CUIWpnScopeXmlManager : public pureUIReset, public pureAppEnd { CUIXml m_xml; bool m_loaded{}; @@ -44,12 +44,14 @@ static class CUIWpnScopeXmlManager : public CUIResetNotifier, public pureAppEnd if (m_loaded) return; m_loaded = m_xml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "scopes.xml"); + Device.seqUIReset.Add(this); } - void OnAppEnd() + void OnAppEnd() override { m_xml.ClearInternal(); m_loaded = false; + Device.seqUIReset.Remove(this); } void OnUIReset() override From e4090017b651d31b2258be379b0d63d09270dabd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 07:32:13 +0500 Subject: [PATCH 358/497] Create game level instance through game persistent No need to use object factory --- src/xrEngine/IGame_Persistent.cpp | 6 +++--- src/xrEngine/IGame_Persistent.h | 4 ++++ src/xrEngine/std_classes.h | 1 - src/xrGame/GamePersistent.cpp | 10 ++++++++++ src/xrGame/GamePersistent.h | 5 ++++- src/xrGame/Level_start.cpp | 10 +++++----- src/xrServerEntities/object_factory_register.cpp | 1 - 7 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 6aca063b3eb..b9977501a8d 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -283,7 +283,7 @@ void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) //----------------------------------------------------------- PreStart(op_server); //----------------------------------------------------------- - g_pGameLevel = dynamic_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); + g_pGameLevel = CreateLevel(); R_ASSERT(g_pGameLevel); LoadBegin(); Start(op_server); @@ -302,7 +302,7 @@ void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) const bool show = Console->bVisible; Console->Hide(); g_pGameLevel->net_Stop(); - DEL_INSTANCE(g_pGameLevel); + DestroyLevel(g_pGameLevel); if (show) Console->Show(); @@ -324,7 +324,7 @@ void IGame_Persistent::OnEvent(EVENT E, u64 P1, u64 P2) Console->Hide(); Device.Reset(false); - g_pGameLevel = dynamic_cast(NEW_INSTANCE(CLSID_GAME_LEVEL)); + g_pGameLevel = CreateLevel(); VERIFY(g_pGameLevel); const shared_str server_options = g_pGameLevel->OpenDemoFile(demo_file); diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index befccdef1c7..79134275955 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -19,6 +19,7 @@ #endif #include "ShadersExternalData.h" //--#SM+#-- +class IGame_Level; class IRenderVisual; class ILoadingScreen; class IMainMenu; @@ -168,6 +169,9 @@ class ENGINE_API IGame_Persistent : static CInifile* GetArchiveHeader(pcstr name, pcstr ver); public: + virtual IGame_Level* CreateLevel() { return nullptr; } + virtual void DestroyLevel(IGame_Level* lvl) { VERIFY(lvl == nullptr); } + virtual void PreStart(pcstr op); virtual void Start(pcstr op); virtual void Disconnect(); diff --git a/src/xrEngine/std_classes.h b/src/xrEngine/std_classes.h index 2bcaf4196c5..7bc392ca75f 100644 --- a/src/xrEngine/std_classes.h +++ b/src/xrEngine/std_classes.h @@ -1,6 +1,5 @@ #pragma once //***** Standart extension classes -constexpr CLASS_ID CLSID_GAME_LEVEL = MK_CLSID('G', '_', 'L', 'E', 'V', 'E', 'L', ' '); constexpr CLASS_ID CLSID_GAME_PERSISTANT = MK_CLSID('G', '_', 'P', 'E', 'R', 'S', 'I', 'S'); constexpr CLASS_ID CLSID_OBJECT = MK_CLSID('O', 'B', 'J', 'E', 'C', 'T', ' ', ' '); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 32ac9ec1667..6b1c353e541 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -83,6 +83,16 @@ CGamePersistent::~CGamePersistent() Engine.Event.Handler_Detach(eQuickLoad, this); } +IGame_Level* CGamePersistent::CreateLevel() +{ + return xr_new(); +} + +void CGamePersistent::DestroyLevel(IGame_Level* lvl) +{ + xr_delete(lvl); +} + void CGamePersistent::PreStart(LPCSTR op) { inherited::PreStart(op); diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index b2f3a8caed7..fc6ac22e8a9 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -63,7 +63,10 @@ class CGamePersistent : public IGame_Persistent EVENT eDemoStart{}; CGamePersistent(); - virtual ~CGamePersistent(); + ~CGamePersistent() override; + + IGame_Level* CreateLevel() override; + void DestroyLevel(IGame_Level* lvl) override; void PreStart(LPCSTR op) override; virtual void Start(LPCSTR op); diff --git a/src/xrGame/Level_start.cpp b/src/xrGame/Level_start.cpp index 2e808fdcd6b..fb1259b7ea9 100644 --- a/src/xrGame/Level_start.cpp +++ b/src/xrGame/Level_start.cpp @@ -279,7 +279,7 @@ bool CLevel::net_start6() if (m_connect_server_err == xrServer::ErrConnect && !psNET_direct_connect && !GEnv.isDedicatedServer) { - DEL_INSTANCE(g_pGameLevel); + g_pGamePersistent->DestroyLevel(g_pGameLevel); // XXX: level destroying itself!!! Console->Execute("main_menu on"); MainMenu()->SwitchToMultiplayerMenu(); @@ -295,7 +295,7 @@ bool CLevel::net_start6() STRCONCAT(level_id_string, StringTable().translate("st_level"), ":", map_data.m_name.c_str(), "(", tmp_map_ver, "). "); STRCONCAT(dialog_string, level_id_string, StringTable().translate("ui_st_map_not_found")); - DEL_INSTANCE(g_pGameLevel); + g_pGamePersistent->DestroyLevel(g_pGameLevel); // XXX: level destroying itself!!! Console->Execute("main_menu on"); if (!GEnv.isDedicatedServer) @@ -314,8 +314,8 @@ bool CLevel::net_start6() STRCONCAT(level_id_string, StringTable().translate("st_level"), ":", map_data.m_name.c_str(), "(", tmp_map_ver, "). "); STRCONCAT(dialog_string, level_id_string, StringTable().translate("ui_st_map_data_corrupted")); - g_pGameLevel->net_Stop(); - DEL_INSTANCE(g_pGameLevel); + net_Stop(); + g_pGamePersistent->DestroyLevel(g_pGameLevel); // XXX: level destroying itself!!! Console->Execute("main_menu on"); if (!GEnv.isDedicatedServer) { @@ -325,7 +325,7 @@ bool CLevel::net_start6() } else { - DEL_INSTANCE(g_pGameLevel); + g_pGamePersistent->DestroyLevel(g_pGameLevel); // XXX: level destroying itself!!! Console->Execute("main_menu on"); } diff --git a/src/xrServerEntities/object_factory_register.cpp b/src/xrServerEntities/object_factory_register.cpp index 93505a3e9f9..267a1e9ec94 100644 --- a/src/xrServerEntities/object_factory_register.cpp +++ b/src/xrServerEntities/object_factory_register.cpp @@ -193,7 +193,6 @@ void CObjectFactory::register_classes() #ifndef NO_XR_GAME // client entities - add(CLSID_GAME_LEVEL, "level"); add(CLSID_GAME_PERSISTANT, "game"); // Server Game type add(CLSID_SV_GAME_SINGLE, "game_sv_single"); From a914f65531becd5e0b42fa5979fcd5ef78ecdd57 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 05:54:58 +0500 Subject: [PATCH 359/497] Cleanup global variables in xrGame That change in UIStatsIcon looks somewhat ugly and can cause questions for other peers that would look at that code. This and previous commits in a row are needed to make xrGame work when it's linked directly to xr_3da (originally it was loaded dynamically). --- src/xrGame/Level_bullet_manager_firetrace.cpp | 2 +- src/xrGame/Weapon.cpp | 19 ++++-- src/xrGame/ai/stalker/ai_stalker_debug.cpp | 5 -- src/xrGame/alife_storage_manager.cpp | 1 - src/xrGame/ui/Restrictions.cpp | 7 --- src/xrGame/ui/Restrictions.h | 8 +-- src/xrGame/ui/UIOptConCom.cpp | 1 - src/xrGame/ui/UIOptConCom.h | 22 +++---- src/xrGame/ui/UIStatsIcon.cpp | 59 ++++++++++--------- src/xrGame/ui/UIStatsIcon.h | 5 +- 10 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/xrGame/Level_bullet_manager_firetrace.cpp b/src/xrGame/Level_bullet_manager_firetrace.cpp index f5d79488e81..6bbcfede7e4 100644 --- a/src/xrGame/Level_bullet_manager_firetrace.cpp +++ b/src/xrGame/Level_bullet_manager_firetrace.cpp @@ -364,7 +364,7 @@ void CBulletManager::DynamicObjectHit(CBulletManager::_event& E) } #ifdef DEBUG -xr_vector g_hit[3]; // XXX: can cause crash on launch (if build statically) and exit +xr_vector g_hit[3]; #endif extern void random_dir(Fvector& tgt_dir, const Fvector& src_dir, float dispersion); diff --git a/src/xrGame/Weapon.cpp b/src/xrGame/Weapon.cpp index e3754af5b5b..5785f471522 100644 --- a/src/xrGame/Weapon.cpp +++ b/src/xrGame/Weapon.cpp @@ -31,6 +31,10 @@ #define WEAPON_REMOVE_TIME 60000 #define ROTATION_TIME 0.25f +constexpr pcstr WPN_SCOPE = "wpn_scope"; +constexpr pcstr WPN_SILENCER = "wpn_silencer"; +constexpr pcstr WPN_GRENADE_LAUNCHER = "wpn_launcher"; + BOOL b_toggle_weapon_aim = FALSE; static class CUIWpnScopeXmlManager : public pureUIReset, public pureAppEnd @@ -1278,12 +1282,15 @@ bool CWeapon::IsSilencerAttached() const bool CWeapon::GrenadeLauncherAttachable() { return (ALife::eAddonAttachable == m_eGrenadeLauncherStatus); } bool CWeapon::ScopeAttachable() { return (ALife::eAddonAttachable == m_eScopeStatus); } bool CWeapon::SilencerAttachable() { return (ALife::eAddonAttachable == m_eSilencerStatus); } -shared_str wpn_scope = "wpn_scope"; -shared_str wpn_silencer = "wpn_silencer"; -shared_str wpn_grenade_launcher = "wpn_launcher"; + void CWeapon::UpdateHUDAddonsVisibility() -{ // actor only +{ + static shared_str wpn_scope = WPN_SCOPE; + static shared_str wpn_silencer = WPN_SILENCER; + static shared_str wpn_grenade_launcher = WPN_GRENADE_LAUNCHER; + + // actor only if (!GetHUDmode()) return; @@ -1326,6 +1333,10 @@ void CWeapon::UpdateHUDAddonsVisibility() void CWeapon::UpdateAddonsVisibility() { + static shared_str wpn_scope = WPN_SCOPE; + static shared_str wpn_silencer = WPN_SILENCER; + static shared_str wpn_grenade_launcher = WPN_GRENADE_LAUNCHER; + IKinematics* pWeaponVisual = smart_cast(Visual()); R_ASSERT(pWeaponVisual); diff --git a/src/xrGame/ai/stalker/ai_stalker_debug.cpp b/src/xrGame/ai/stalker/ai_stalker_debug.cpp index 7fe81a7ecb6..861ee17491d 100644 --- a/src/xrGame/ai/stalker/ai_stalker_debug.cpp +++ b/src/xrGame/ai/stalker/ai_stalker_debug.cpp @@ -1594,11 +1594,6 @@ static void draw_animation_bones( #endif // #ifdef DEBUG_RENDER } -Fvector g_debug_position_0 = Fvector().set(0.f, 0.f, 0.f); -Fvector g_debug_position_1 = Fvector().set(0.f, 0.f, 0.f); -Fvector g_debug_position_2 = Fvector().set(0.f, 0.f, 0.f); -Fvector g_debug_position_3 = Fvector().set(0.f, 0.f, 0.f); - void CAI_Stalker::OnRender() { #if 0 diff --git a/src/xrGame/alife_storage_manager.cpp b/src/xrGame/alife_storage_manager.cpp index 611d898f161..0c10232c4ef 100644 --- a/src/xrGame/alife_storage_manager.cpp +++ b/src/xrGame/alife_storage_manager.cpp @@ -20,7 +20,6 @@ #include "saved_game_wrapper.h" #include "xrEngine/IGame_Persistent.h" #include "autosave_manager.h" -XRCORE_API string_path g_bug_report_file; using namespace ALife; diff --git a/src/xrGame/ui/Restrictions.cpp b/src/xrGame/ui/Restrictions.cpp index 1cedebf90b0..e975af7e93e 100644 --- a/src/xrGame/ui/Restrictions.cpp +++ b/src/xrGame/ui/Restrictions.cpp @@ -41,13 +41,6 @@ u32 get_rank(const shared_str& section) return res; } -CRestrictions::CRestrictions() -{ - m_rank = 0; - m_bInited = false; -} - -CRestrictions::~CRestrictions() {} void CRestrictions::InitGroups() { if (m_bInited) diff --git a/src/xrGame/ui/Restrictions.h b/src/xrGame/ui/Restrictions.h index 0643aa3ad70..d1b53ce89e6 100644 --- a/src/xrGame/ui/Restrictions.h +++ b/src/xrGame/ui/Restrictions.h @@ -13,8 +13,8 @@ typedef struct class CRestrictions { public: - CRestrictions(); - ~CRestrictions(); + CRestrictions() = default; + ~CRestrictions() = default; void InitGroups(); const u32 GetRank() const { return m_rank; } @@ -38,8 +38,8 @@ class CRestrictions void AddRestriction4rank(u32 rank, const shared_str& lst); RESTR GetRestr(const shared_str& item); - u32 m_rank; - bool m_bInited; + u32 m_rank{}; + bool m_bInited{}; using group_items = xr_vector; using Groups = xr_map; diff --git a/src/xrGame/ui/UIOptConCom.cpp b/src/xrGame/ui/UIOptConCom.cpp index 9a82e117a28..b289673f490 100644 --- a/src/xrGame/ui/UIOptConCom.cpp +++ b/src/xrGame/ui/UIOptConCom.cpp @@ -12,7 +12,6 @@ xr_token g_GameModes[] = {{"st_deathmatch", eGameIDDeathmatch}, {"st_team_deathmatch", eGameIDTeamDeathmatch}, {"st_artefacthunt", eGameIDArtefactHunt}, {"st_capture_the_artefact", eGameIDCaptureTheArtefact}, {0, 0}}; -CUIOptConCom::CUIOptConCom() { xr_strcpy(m_playerName, ""); } class CCC_UserName : public CCC_String { public: diff --git a/src/xrGame/ui/UIOptConCom.h b/src/xrGame/ui/UIOptConCom.h index dfa0e3f2a69..3944d950fd5 100644 --- a/src/xrGame/ui/UIOptConCom.h +++ b/src/xrGame/ui/UIOptConCom.h @@ -2,12 +2,12 @@ class CUIOptConCom { -private: - string64 reinforcementType; + string64 reinforcementType{}; public: + CUIOptConCom() = default; + void Init(); - CUIOptConCom(); protected: enum @@ -25,14 +25,14 @@ class CUIOptConCom fl_wo_ff = (1 << 4), fl_listen = (1 << 5), }; - int m_iMaxPlayers; - Flags32 m_uNetSrvParams; - Flags32 m_uNetFilter; - u32 m_curGameMode; - string64 m_playerName; - string64 m_serverName; - int m_iNetConSpectator; - float m_fNetWeatherRate; + int m_iMaxPlayers{}; + Flags32 m_uNetSrvParams{}; + Flags32 m_uNetFilter{}; + u32 m_curGameMode{}; + string64 m_playerName{}; + string64 m_serverName{}; + int m_iNetConSpectator{}; + float m_fNetWeatherRate{}; void ReadPlayerNameFromRegistry(); void WritePlayerNameToRegistry(); diff --git a/src/xrGame/ui/UIStatsIcon.cpp b/src/xrGame/ui/UIStatsIcon.cpp index 3561c9b603a..bb1ce419449 100644 --- a/src/xrGame/ui/UIStatsIcon.cpp +++ b/src/xrGame/ui/UIStatsIcon.cpp @@ -5,8 +5,6 @@ #include "Include/xrRender/UIShader.h" -CUIStatsIcon::TEX_INFO CUIStatsIcon::m_tex_info[MAX_DEF_TEX][2]; - CUIStatsIcon::CUIStatsIcon() : CUIStatic("CUIStatsIcon") { @@ -16,19 +14,22 @@ CUIStatsIcon::CUIStatsIcon() void CUIStatsIcon::InitTexInfo() { - if (m_tex_info[RANK_0][0].sh->inited()) + if (m_tex_info) return; + + m_tex_info = xr_new(); + // ranks string128 rank_tex; for (int i = RANK_0; i <= RANK_4; i++) { xr_sprintf(rank_tex, "ui_hud_status_green_0%d", i + 1); - CUITextureMaster::GetTextureShader(rank_tex, m_tex_info[i][0].sh); - m_tex_info[i][0].rect = CUITextureMaster::GetTextureRect(rank_tex); + CUITextureMaster::GetTextureShader(rank_tex, (*m_tex_info)[i][0].sh); + (*m_tex_info)[i][0].rect = CUITextureMaster::GetTextureRect(rank_tex); xr_sprintf(rank_tex, "ui_hud_status_blue_0%d", i + 1); - CUITextureMaster::GetTextureShader(rank_tex, m_tex_info[i][1].sh); - m_tex_info[i][1].rect = CUITextureMaster::GetTextureRect(rank_tex); + CUITextureMaster::GetTextureShader(rank_tex, (*m_tex_info)[i][1].sh); + (*m_tex_info)[i][1].rect = CUITextureMaster::GetTextureRect(rank_tex); } // artefact @@ -38,19 +39,19 @@ void CUIStatsIcon::InitTexInfo() float fXPos = pSettings->r_float(artefact_name, "inv_grid_x"); float fYPos = pSettings->r_float(artefact_name, "inv_grid_y"); - m_tex_info[ARTEFACT][0].sh = InventoryUtilities::GetEquipmentIconsShader(); - m_tex_info[ARTEFACT][0].rect.set(fXPos * INV_GRID_WIDTH, fYPos * INV_GRID_HEIGHT, + (*m_tex_info)[ARTEFACT][0].sh = InventoryUtilities::GetEquipmentIconsShader(); + (*m_tex_info)[ARTEFACT][0].rect.set(fXPos * INV_GRID_WIDTH, fYPos * INV_GRID_HEIGHT, fXPos * INV_GRID_WIDTH + fGridWidth * INV_GRID_WIDTH, fYPos * INV_GRID_HEIGHT + fGridHeight * INV_GRID_HEIGHT); - m_tex_info[ARTEFACT][1] = m_tex_info[ARTEFACT][0]; + (*m_tex_info)[ARTEFACT][1] = (*m_tex_info)[ARTEFACT][0]; // death - m_tex_info[DEATH][0].sh->create("hud" DELIMITER "default", "ui" DELIMITER "ui_mp_icon_kill"); - m_tex_info[DEATH][1] = m_tex_info[DEATH][0]; - m_tex_info[DEATH][0].rect.x1 = 32; - m_tex_info[DEATH][0].rect.y1 = 202; - m_tex_info[DEATH][0].rect.x2 = m_tex_info[DEATH][0].rect.x1 + 30; - m_tex_info[DEATH][0].rect.y2 = m_tex_info[DEATH][0].rect.y1 + 30; + (*m_tex_info)[DEATH][0].sh->create("hud" DELIMITER "default", "ui" DELIMITER "ui_mp_icon_kill"); + (*m_tex_info)[DEATH][1] = (*m_tex_info)[DEATH][0]; + (*m_tex_info)[DEATH][0].rect.x1 = 32; + (*m_tex_info)[DEATH][0].rect.y1 = 202; + (*m_tex_info)[DEATH][0].rect.x2 = (*m_tex_info)[DEATH][0].rect.x1 + 30; + (*m_tex_info)[DEATH][0].rect.y2 = (*m_tex_info)[DEATH][0].rect.y1 + 30; } void CUIStatsIcon::FreeTexInfo() @@ -58,13 +59,15 @@ void CUIStatsIcon::FreeTexInfo() // ranks for (int i = RANK_0; i <= RANK_4; i++) { - m_tex_info[i][0].sh->destroy(); - m_tex_info[i][1].sh->destroy(); + (*m_tex_info)[i][0].sh->destroy(); + (*m_tex_info)[i][1].sh->destroy(); } - m_tex_info[ARTEFACT][0].sh->destroy(); - m_tex_info[ARTEFACT][1].sh->destroy(); - m_tex_info[DEATH][0].sh->destroy(); - m_tex_info[DEATH][1].sh->destroy(); + (*m_tex_info)[ARTEFACT][0].sh->destroy(); + (*m_tex_info)[ARTEFACT][1].sh->destroy(); + (*m_tex_info)[DEATH][0].sh->destroy(); + (*m_tex_info)[DEATH][1].sh->destroy(); + + xr_delete(m_tex_info); } void CUIStatsIcon::SetValue(LPCSTR str) @@ -85,18 +88,18 @@ void CUIStatsIcon::SetValue(LPCSTR str) const int rank = atoi(strchr(str, '0')) - 1; - SetShader(m_tex_info[rank][team].sh); - SetTextureRect(m_tex_info[rank][team].rect); + SetShader((*m_tex_info)[rank][team].sh); + SetTextureRect((*m_tex_info)[rank][team].rect); } else if (0 == xr_strcmp(str, "death")) { - SetShader(m_tex_info[DEATH][0].sh); - SetTextureRect(m_tex_info[DEATH][0].rect); + SetShader((*m_tex_info)[DEATH][0].sh); + SetTextureRect((*m_tex_info)[DEATH][0].rect); } else if (0 == xr_strcmp(str, "artefact")) { - SetShader(m_tex_info[ARTEFACT][0].sh); - SetTextureRect(m_tex_info[ARTEFACT][0].rect); + SetShader((*m_tex_info)[ARTEFACT][0].sh); + SetTextureRect((*m_tex_info)[ARTEFACT][0].rect); } else { diff --git a/src/xrGame/ui/UIStatsIcon.h b/src/xrGame/ui/UIStatsIcon.h index 765481e29aa..bcf6f6714dd 100644 --- a/src/xrGame/ui/UIStatsIcon.h +++ b/src/xrGame/ui/UIStatsIcon.h @@ -34,5 +34,8 @@ class CUIStatsIcon final : public CUIStatic static void InitTexInfo(); static void FreeTexInfo(); - static TEX_INFO m_tex_info[MAX_DEF_TEX][2]; + + using tex_info_data = std::array; + + inline static tex_info_data* m_tex_info; }; From 655e7abc041bfa702c6785c90d9ebe740ca81893 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 07:50:09 +0500 Subject: [PATCH 360/497] xrGame/xrGame.cpp: formatting --- src/xrGame/xrGame.cpp | 72 +++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index 0749bde2866..e6ea87dd1a2 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -22,59 +22,59 @@ extern float g_fTimeFactor; extern "C" { - XR_EXPORT IFactoryObject* __cdecl xrFactory_Create(CLASS_ID clsid) - { - IFactoryObject* object = object_factory().client_object(clsid); +XR_EXPORT IFactoryObject* __cdecl xrFactory_Create(CLASS_ID clsid) +{ + IFactoryObject* object = object_factory().client_object(clsid); #ifdef DEBUG - if (!object) - return (0); + if (!object) + return (0); #endif - // XXX nitrocaster XRFACTORY: set clsid during factory initialization - object->GetClassId() = clsid; - return (object); - } + // XXX nitrocaster XRFACTORY: set clsid during factory initialization + object->GetClassId() = clsid; + return (object); +} - XR_EXPORT void __cdecl xrFactory_Destroy(IFactoryObject* O) { xr_delete(O); } +XR_EXPORT void __cdecl xrFactory_Destroy(IFactoryObject* O) { xr_delete(O); } - XR_EXPORT void initialize_library() - { - ZoneScoped; +XR_EXPORT void initialize_library() +{ + ZoneScoped; - g_fTimeFactor = pSettings->r_float("alife", "time_factor"); // XXX: find a better place + g_fTimeFactor = pSettings->r_float("alife", "time_factor"); // XXX: find a better place - // Fill ui style token - UIStyles = xr_new(); - // register console commands - CCC_RegisterCommands(); - // register localization - StringTable().Init(); - // keyboard binding - CCC_RegisterInput(); // XXX: Move to xrEngine + // Fill ui style token + UIStyles = xr_new(); + // register console commands + CCC_RegisterCommands(); + // register localization + StringTable().Init(); + // keyboard binding + CCC_RegisterInput(); // XXX: Move to xrEngine #ifdef DEBUG - g_profiler = xr_new(); + g_profiler = xr_new(); #endif - ImGui::SetAllocatorFunctions( - [](size_t size, void* /*user_data*/) + ImGui::SetAllocatorFunctions( + [](size_t size, void* /*user_data*/) { return xr_malloc(size); }, - [](void* ptr, void* /*user_data*/) + [](void* ptr, void* /*user_data*/) { xr_free(ptr); } - ); - ImGui::SetCurrentContext(Device.GetImGuiContext()); - } + ); + ImGui::SetCurrentContext(Device.GetImGuiContext()); +} - XR_EXPORT void finalize_library() - { - xr_delete(UIStyles); - StringTable().Destroy(); - CCC_DeregisterInput(); // XXX: Remove if possible +XR_EXPORT void finalize_library() +{ + xr_delete(UIStyles); + StringTable().Destroy(); + CCC_DeregisterInput(); // XXX: Remove if possible #ifdef DEBUG - xr_delete(g_profiler); + xr_delete(g_profiler); #endif - } +} } From 6fffce97dc4cc827edbfbbf6f4ba5b279a8cb639 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 3 May 2024 08:10:32 +0500 Subject: [PATCH 361/497] Link xrGame to xr_3da directly --- src/xrEngine/Engine.cpp | 4 +- src/xrEngine/Engine.h | 2 +- src/xrEngine/EngineAPI.cpp | 75 +++++++++++++------------------ src/xrEngine/EngineAPI.h | 44 +++++++----------- src/xrEngine/x_ray.cpp | 4 +- src/xrEngine/x_ray.h | 4 +- src/xrGame/CMakeLists.txt | 1 + src/xrGame/xrGame.cpp | 12 +++-- src/xrGame/xrGame.h | 29 ++++++++++++ src/xrGame/xrGame.vcxproj | 1 + src/xrGame/xrGame.vcxproj.filters | 3 ++ src/xr_3da/CMakeLists.txt | 1 + src/xr_3da/entry_point.cpp | 3 +- src/xr_3da/xr_3da.vcxproj | 3 ++ 14 files changed, 103 insertions(+), 83 deletions(-) create mode 100644 src/xrGame/xrGame.h diff --git a/src/xrEngine/Engine.cpp b/src/xrEngine/Engine.cpp index aea781905d0..277b90bba4c 100644 --- a/src/xrEngine/Engine.cpp +++ b/src/xrEngine/Engine.cpp @@ -61,7 +61,7 @@ void CheckAndSetupRenderer() extern void msCreate(pcstr name); -void CEngine::Initialize(void) +void CEngine::Initialize(GameModule* game) { ZoneScoped; #ifdef DEBUG @@ -77,7 +77,7 @@ void CEngine::Initialize(void) CheckAndSetupRenderer(); - External.Initialize(); + External.Initialize(game); Sheduler.Initialize(); } diff --git a/src/xrEngine/Engine.h b/src/xrEngine/Engine.h index fd67507acb5..753904dd7d6 100644 --- a/src/xrEngine/Engine.h +++ b/src/xrEngine/Engine.h @@ -33,7 +33,7 @@ class ENGINE_API CEngine final : public pureFrame, public IEventReceiver CSheduler Sheduler; CSoundManager Sound; - void Initialize(); + void Initialize(GameModule* game); void Destroy(); void OnEvent(EVENT E, u64 P1, u64 P2) override; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 2285a87497b..58f1b8cdc7d 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -4,28 +4,37 @@ ////////////////////////////////////////////////////////////////////// #include "stdafx.h" + #include "EngineAPI.h" #include "XR_IOConsole.h" -#include "xrCore/ModuleLookup.hpp" #include "xrCore/xr_token.h" +#include "xrCore/ModuleLookup.hpp" #include "xrCore/Threading/ParallelForEach.hpp" #include "xrScriptEngine/ScriptExporter.hpp" +#include + extern xr_vector VidQualityToken; constexpr pcstr GET_RENDERER_MODULE_FUNC = "GetRendererModule"; -constexpr pcstr r4_library = "xrRender_R4"; -constexpr pcstr gl_library = "xrRender_GL"; +using GetRendererModule = RendererModule*(); -constexpr pcstr RENDER_LIBRARIES[] = +struct RendererDesc { - r4_library, - gl_library + pcstr libraryName; + XRay::Module handle; + RendererModule* module; }; +std::array g_render_modules = +{{ + { "xrRender_R4", nullptr, nullptr }, + { "xrRender_GL", nullptr, nullptr }, +}}; + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -99,56 +108,40 @@ void CEngineAPI::SelectRenderer() Log("Selected renderer:", selected_mode); } -void CEngineAPI::Initialize(void) +void CEngineAPI::Initialize(GameModule* game) { ZoneScoped; SelectRenderer(); - hGame = XRay::LoadModule("xrGame"); if (!CanSkipGameModuleLoading()) { - R_ASSERT2(hGame->IsLoaded(), "! Game DLL raised exception during loading or there is no game DLL at all"); - - pCreate = (Factory_Create*)hGame->GetProcAddress("xrFactory_Create"); + gameModule = game; + gameModule->initialize(pCreate, pDestroy); R_ASSERT(pCreate); - - pDestroy = (Factory_Destroy*)hGame->GetProcAddress("xrFactory_Destroy"); R_ASSERT(pDestroy); - - pInitializeGame = (InitializeGameLibraryProc)hGame->GetProcAddress("initialize_library"); - R_ASSERT(pInitializeGame); - - pFinalizeGame = (FinalizeGameLibraryProc)hGame->GetProcAddress("finalize_library"); - R_ASSERT(pFinalizeGame); - - pInitializeGame(); } CloseUnusedLibraries(); } -void CEngineAPI::Destroy(void) +void CEngineAPI::Destroy() { ZoneScoped; - if (pFinalizeGame) - pFinalizeGame(); - pInitializeGame = nullptr; - pFinalizeGame = nullptr; + if (gameModule) + gameModule->finalize(); + pCreate = nullptr; pDestroy = nullptr; - hGame = nullptr; - - renderers.clear(); XRC.r_clear_compact(); } void CEngineAPI::CloseUnusedLibraries() { ZoneScoped; - for (RendererDesc& desc : renderers) + for (RendererDesc& desc : g_render_modules) { if (desc.module != selectedRenderer) desc.handle = nullptr; @@ -162,35 +155,29 @@ void CEngineAPI::CreateRendererList() ZoneScoped; - const auto loadLibrary = [&](pcstr library) -> bool + const auto loadLibrary = [&](RendererDesc& desc) -> bool { - auto handle = XRay::LoadModule(library); + auto handle = XRay::LoadModule(desc.libraryName); if (!handle->IsLoaded()) return false; - const auto getModule = (GetRendererModule)handle->GetProcAddress(GET_RENDERER_MODULE_FUNC); + const auto getModule = reinterpret_cast(handle->GetProcAddress(GET_RENDERER_MODULE_FUNC)); RendererModule* module = getModule ? getModule() : nullptr; if (!module) return false; - renderers.emplace_back(RendererDesc({ library, std::move(handle), module })); + desc.handle = std::move(handle); + desc.module = module; return true; }; if (GEnv.isDedicatedServer) { -#if defined(XR_PLATFORM_WINDOWS) - R_ASSERT2(loadLibrary(r4_library), "Dedicated server needs xrRender_R1 to work"); -#else - R_ASSERT2(loadLibrary(gl_library), "Dedicated server needs xrRender_GL to work"); -#endif + R_ASSERT2(loadLibrary(g_render_modules[0]), "Dedicated server needs xrRender to work"); } else { - for (cpcstr library : RENDER_LIBRARIES) - { - loadLibrary(library); - } + std::for_each(std::begin(g_render_modules), std::end(g_render_modules), loadLibrary); } std::mutex mutex; @@ -221,7 +208,7 @@ void CEngineAPI::CreateRendererList() } }; - xr_parallel_for_each(renderers, obtainModes); + xr_parallel_for_each(g_render_modules, obtainModes); auto& modes = VidQualityToken; Msg("Available render modes[%d]:", modes.size()); diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index 826238ce336..5a472088b52 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -6,11 +6,8 @@ #pragma once #include "xrEngine/Engine.h" -#include "xrCore/ModuleLookup.hpp" #include "xrCore/clsid.h" -#include - class XR_NOVTABLE IFactoryObject { public: @@ -39,6 +36,14 @@ using Factory_Create = IFactoryObject* __cdecl(CLASS_ID CLS_ID); using Factory_Destroy = void __cdecl(IFactoryObject* O); } +class XR_NOVTABLE GameModule +{ +public: + virtual ~GameModule() = default; + virtual void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) = 0; + virtual void finalize() = 0; +}; + class XR_NOVTABLE RendererModule { public: @@ -50,44 +55,27 @@ class XR_NOVTABLE RendererModule class ENGINE_API CEngineAPI { - using InitializeGameLibraryProc = void(*)(); - using FinalizeGameLibraryProc = void(*)(); - - using GetRendererModule = RendererModule*(*)(); - - struct RendererDesc - { - pcstr libraryName; - XRay::Module handle; - RendererModule* module; - }; - - xr_vector renderers; xr_map renderModes; + GameModule* gameModule; RendererModule* selectedRenderer{}; - XRay::Module hGame; - - InitializeGameLibraryProc pInitializeGame{}; - FinalizeGameLibraryProc pFinalizeGame{}; + void SelectRenderer(); + void CloseUnusedLibraries(); public: Factory_Create* pCreate; Factory_Destroy* pDestroy; - void Initialize(); - - void SelectRenderer(); - void CloseUnusedLibraries(); +public: + CEngineAPI(); + ~CEngineAPI(); + void CreateRendererList(); + void Initialize(GameModule* game); void Destroy(); - void CreateRendererList(); bool CanSkipGameModuleLoading() const { return !!strstr(Core.Params, "-nogame"); } - - CEngineAPI(); - ~CEngineAPI(); }; ENGINE_API bool is_enough_address_space_available(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 7a02cf31e84..75914e8b8ae 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -219,7 +219,7 @@ void execUserScript() constexpr pcstr APPLICATION_STARTUP = "Application startup"; constexpr pcstr APPLICATION_SHUTDOWN = "Application shutdown"; -CApplication::CApplication(pcstr commandLine) +CApplication::CApplication(pcstr commandLine, GameModule* game) { Threading::SetCurrentThreadName("Primary thread"); FrameMarkStart(APPLICATION_STARTUP); @@ -319,7 +319,7 @@ CApplication::CApplication(pcstr commandLine) InitConsole(); TaskScheduler->Wait(createRendererList); - Engine.Initialize(); + Engine.Initialize(game); Device.Initialize(); Console->OnDeviceInitialize(); diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 8a9651cb4b6..1ab9d457d3b 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -3,7 +3,7 @@ #include -#include "xrCore/Threading/Event.hpp" +#include "xrEngine/Engine.h" struct SDL_Window; struct SDL_Surface; @@ -36,7 +36,7 @@ class ENGINE_API CApplication final public: // Other - CApplication(pcstr commandLine); + CApplication(pcstr commandLine, GameModule* game); ~CApplication(); int Run(); diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 2121a29d0e8..355aa83eae5 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -1682,6 +1682,7 @@ target_sources(xrGame PRIVATE xrClientsPool.cpp xrClientsPool.h xrGame.cpp + xrGame.h xrgame_dll_detach.cpp xrGameSpy_GameSpyFuncs.cpp xrGameSpyServer_callbacks.cpp diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index e6ea87dd1a2..73a488827b6 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -7,6 +7,7 @@ //////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" +#include "xrGame.h" #include "object_factory.h" @@ -16,6 +17,8 @@ #include "xrUICore/XML/xrUIXmlParser.h" #include "xrUICore/ui_styles.h" +xrGameModule xrGame; + void CCC_RegisterCommands(); extern float g_fTimeFactor; @@ -35,11 +38,15 @@ XR_EXPORT IFactoryObject* __cdecl xrFactory_Create(CLASS_ID clsid) } XR_EXPORT void __cdecl xrFactory_Destroy(IFactoryObject* O) { xr_delete(O); } +} -XR_EXPORT void initialize_library() +void xrGameModule::initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) { ZoneScoped; + pCreate = &xrFactory_Create; + pDestroy = &xrFactory_Destroy; + g_fTimeFactor = pSettings->r_float("alife", "time_factor"); // XXX: find a better place // Fill ui style token @@ -67,7 +74,7 @@ XR_EXPORT void initialize_library() ImGui::SetCurrentContext(Device.GetImGuiContext()); } -XR_EXPORT void finalize_library() +void xrGameModule::finalize() { xr_delete(UIStyles); StringTable().Destroy(); @@ -77,4 +84,3 @@ XR_EXPORT void finalize_library() xr_delete(g_profiler); #endif } -} diff --git a/src/xrGame/xrGame.h b/src/xrGame/xrGame.h new file mode 100644 index 00000000000..dbc068e6612 --- /dev/null +++ b/src/xrGame/xrGame.h @@ -0,0 +1,29 @@ +#pragma once + +#include "xrCore/clsid.h" +#include "xrEngine/EngineAPI.h" + +#ifdef XRAY_STATIC_BUILD +# define XRGAME_API +#else +# ifdef XRGAME_EXPORTS +# define XRGAME_API XR_EXPORT +# else +# define XRGAME_API XR_IMPORT +# endif +#endif + +extern "C" +{ +XRGAME_API IFactoryObject* __cdecl xrFactory_Create(CLASS_ID clsid); +XRGAME_API void __cdecl xrFactory_Destroy(IFactoryObject* O); +} + +class xrGameModule final : public GameModule +{ +public: + void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) override; + void finalize() override; +}; + +extern XRGAME_API xrGameModule xrGame; diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index 5b856169444..4117babe5e1 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -1443,6 +1443,7 @@ + diff --git a/src/xrGame/xrGame.vcxproj.filters b/src/xrGame/xrGame.vcxproj.filters index 794e6c8653e..064a21b7c5e 100644 --- a/src/xrGame/xrGame.vcxproj.filters +++ b/src/xrGame/xrGame.vcxproj.filters @@ -6501,6 +6501,9 @@ UI\Common\PDA\Tasks + + Core\Server + diff --git a/src/xr_3da/CMakeLists.txt b/src/xr_3da/CMakeLists.txt index 7fbdf10f7c1..52ecca693f9 100644 --- a/src/xr_3da/CMakeLists.txt +++ b/src/xr_3da/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(xr_3da xrCore xrAPI xrEngine + xrGame ) set_target_properties(xr_3da PROPERTIES diff --git a/src/xr_3da/entry_point.cpp b/src/xr_3da/entry_point.cpp index 0d5f7e0240a..e59f3b191a1 100644 --- a/src/xr_3da/entry_point.cpp +++ b/src/xr_3da/entry_point.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "xrEngine/x_ray.h" +#include "xrGame/xrGame.h" #if defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) #include @@ -24,7 +25,7 @@ int entry_point(pcstr commandLine) if (strstr(commandLine, "-dedicated")) GEnv.isDedicatedServer = true; - CApplication app{ commandLine }; + CApplication app{ commandLine, &xrGame }; return app.Run(); } diff --git a/src/xr_3da/xr_3da.vcxproj b/src/xr_3da/xr_3da.vcxproj index fccddc4fccb..d55a87b8c5c 100644 --- a/src/xr_3da/xr_3da.vcxproj +++ b/src/xr_3da/xr_3da.vcxproj @@ -59,6 +59,9 @@ {1daec516-e52c-4a3c-a4da-ae3553e6e0f8} + + {200652a6-043e-4634-8837-87983b3bd5e0} + From c35db908f38c907be42cdb9d048e8f764571b992 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 08:57:00 +0500 Subject: [PATCH 362/497] Moved -nogame key check to xr_3da/entry_point.cpp And small accompanying refactoring --- src/xrEngine/EngineAPI.cpp | 2 +- src/xrEngine/EngineAPI.h | 4 +--- src/xrEngine/x_ray.cpp | 10 ++++++++-- src/xr_3da/entry_point.cpp | 5 ++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 58f1b8cdc7d..b599d2205a0 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -114,7 +114,7 @@ void CEngineAPI::Initialize(GameModule* game) SelectRenderer(); - if (!CanSkipGameModuleLoading()) + if (game) { gameModule = game; gameModule->initialize(pCreate, pDestroy); diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index 5a472088b52..f4dbed8c1e8 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -57,7 +57,7 @@ class ENGINE_API CEngineAPI { xr_map renderModes; - GameModule* gameModule; + GameModule* gameModule{}; RendererModule* selectedRenderer{}; void SelectRenderer(); @@ -74,8 +74,6 @@ class ENGINE_API CEngineAPI void CreateRendererList(); void Initialize(GameModule* game); void Destroy(); - - bool CanSkipGameModuleLoading() const { return !!strstr(Core.Params, "-nogame"); } }; ENGINE_API bool is_enough_address_space_available(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 75914e8b8ae..60d8b2a8754 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -224,6 +224,9 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Threading::SetCurrentThreadName("Primary thread"); FrameMarkStart(APPLICATION_STARTUP); + if (strstr(commandLine, "-dedicated")) + GEnv.isDedicatedServer = true; + xrDebug::Initialize(commandLine); { ZoneScopedN("SDL_Init"); @@ -355,8 +358,11 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Device.Create(); TaskScheduler->Wait(createLightAnim); - g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); - R_ASSERT(g_pGamePersistent || Engine.External.CanSkipGameModuleLoading()); + if (game) + { + g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); + R_ASSERT(g_pGamePersistent); + } if (!g_pGamePersistent) Console->Show(); diff --git a/src/xr_3da/entry_point.cpp b/src/xr_3da/entry_point.cpp index e59f3b191a1..0b81b8380c3 100644 --- a/src/xr_3da/entry_point.cpp +++ b/src/xr_3da/entry_point.cpp @@ -22,10 +22,9 @@ XR_EXPORT u32 AmdPowerXpressRequestHighPerformance = 0x00000001; // PowerXpress int entry_point(pcstr commandLine) { - if (strstr(commandLine, "-dedicated")) - GEnv.isDedicatedServer = true; + auto* game = strstr(commandLine, "-nogame") ? nullptr : &xrGame; - CApplication app{ commandLine, &xrGame }; + CApplication app{ commandLine, game }; return app.Run(); } From af7fe40791bf736f1d016837e296ddf189edf536 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 09:45:10 +0500 Subject: [PATCH 363/497] xrEngine/x_ray.cpp: removed excessive tracy scoped zone --- src/xrEngine/x_ray.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 60d8b2a8754..4c60b94f653 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -425,8 +425,6 @@ int CApplication::Run() while (!SDL_QuitRequested()) // SDL_PumpEvents is here { - ZoneScopedN("Main cycle"); - bool canCallActivate = false; bool shouldActivate = false; From 8a507d9d1c702695907606daa16885b27c6ab4a8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 12:00:12 +0500 Subject: [PATCH 364/497] xrRender: Comment out tracy d3d11 zones due to crashes --- src/Layers/xrRender_R2/r3_R_rain.cpp | 6 +++--- src/Layers/xrRender_R2/render_phase_sun.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Layers/xrRender_R2/r3_R_rain.cpp b/src/Layers/xrRender_R2/r3_R_rain.cpp index 455245d3129..8caf2d932d3 100644 --- a/src/Layers/xrRender_R2/r3_R_rain.cpp +++ b/src/Layers/xrRender_R2/r3_R_rain.cpp @@ -298,7 +298,7 @@ void render_rain::render() if (o.active) { #if defined(USE_DX11) - TracyD3D11Zone(HW.profiler_ctx, "render_rain::render"); + //TracyD3D11Zone(HW.profiler_ctx, "render_rain::render"); #endif auto& dsgraph = RImplementation.get_context(context_id); @@ -325,7 +325,7 @@ void render_rain::flush() if (o.active) { #if defined(USE_DX11) - TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - submit and release"); + //TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - submit and release"); #endif auto& dsgraph = RImplementation.get_context(context_id); @@ -336,7 +336,7 @@ void render_rain::flush() auto& cmd_list_imm = RImplementation.get_imm_context().cmd_list; #if defined(USE_DX11) - TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - accumulate"); + //TracyD3D11Zone(HW.profiler_ctx, "render_rain::flush - accumulate"); #endif cmd_list_imm.Invalidate(); diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index 835975b4256..cff5e998805 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -316,7 +316,7 @@ void render_sun::render() for (u32 cascade_ind = range.begin(); cascade_ind != range.end(); ++cascade_ind) { #if defined(USE_DX11) - TracyD3D11Zone(HW.profiler_ctx, "render_sun::render_cascade"); + //TracyD3D11Zone(HW.profiler_ctx, "render_sun::render_cascade"); #endif auto& dsgraph = RImplementation.get_context(contexts_ids[cascade_ind]); @@ -399,7 +399,7 @@ void render_sun::flush() void render_sun::accumulate_cascade(u32 cascade_ind) { #if defined(USE_DX11) - TracyD3D11Zone(HW.profiler_ctx, "render_sun::accumulate_cascade"); + //TracyD3D11Zone(HW.profiler_ctx, "render_sun::accumulate_cascade"); #endif auto& dsgraph = RImplementation.get_context(contexts_ids[cascade_ind]); From 118aaa85d4ccd4ad069b7b704c23025542e346c5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 12:29:11 +0500 Subject: [PATCH 365/497] xrEngine/IGame_Level.h: removed inheritance from FactoryObjectBase I forgot to do this in e4090017b651d31b2258be379b0d63d09270dabd --- src/xrEngine/IGame_Level.h | 3 +-- src/xrServerEntities/object_factory_register.cpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 6de9655221a..13e6b4d28f7 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -52,8 +52,7 @@ class ENGINE_API CServerInfo }; //----------------------------------------------------------------------------------------------------------- -class ENGINE_API IGame_Level : public FactoryObjectBase, - public IInputReceiver, +class ENGINE_API IGame_Level : public IInputReceiver, public pureRender, public pureFrame, public IEventReceiver diff --git a/src/xrServerEntities/object_factory_register.cpp b/src/xrServerEntities/object_factory_register.cpp index 267a1e9ec94..1407845b924 100644 --- a/src/xrServerEntities/object_factory_register.cpp +++ b/src/xrServerEntities/object_factory_register.cpp @@ -19,7 +19,6 @@ // client entities includes #ifndef NO_XR_GAME #include "xrEngine/std_classes.h" -#include "Level.h" #include "GamePersistent.h" #include "Actor.h" #include "Spectator.h" From 09cc90f7aa0d0db0807999e7c7b2ba2793ef10d5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 12:41:14 +0500 Subject: [PATCH 366/497] Create game persistent instance through game module No need to use object factory --- src/xrEngine/EngineAPI.h | 4 ++++ src/xrEngine/IGame_Persistent.h | 5 +---- src/xrEngine/std_classes.h | 1 - src/xrEngine/x_ray.cpp | 8 +++++--- src/xrEngine/x_ray.h | 3 +++ src/xrGame/xrGame.cpp | 12 ++++++++++++ src/xrGame/xrGame.h | 2 ++ src/xrServerEntities/object_factory_register.cpp | 4 ---- 8 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index f4dbed8c1e8..3006b3a1d1b 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -8,6 +8,8 @@ #include "xrEngine/Engine.h" #include "xrCore/clsid.h" +class IGame_Persistent; + class XR_NOVTABLE IFactoryObject { public: @@ -42,6 +44,8 @@ class XR_NOVTABLE GameModule virtual ~GameModule() = default; virtual void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) = 0; virtual void finalize() = 0; + virtual IGame_Persistent* create_persistent() = 0; + virtual void destroy_persistent(IGame_Persistent* persistent) = 0; }; class XR_NOVTABLE RendererModule diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 79134275955..65c639aae92 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -26,14 +26,11 @@ class IMainMenu; class ENGINE_API CPS_Instance; //----------------------------------------------------------------------------------------------------------- class ENGINE_API IGame_Persistent : -#ifndef _EDITOR - public FactoryObjectBase, -#endif + public pureFrame, public pureAppStart, public pureAppEnd, public pureAppActivate, public pureAppDeactivate, - public pureFrame, public IEventReceiver { public: diff --git a/src/xrEngine/std_classes.h b/src/xrEngine/std_classes.h index 7bc392ca75f..a245030a561 100644 --- a/src/xrEngine/std_classes.h +++ b/src/xrEngine/std_classes.h @@ -1,5 +1,4 @@ #pragma once //***** Standart extension classes -constexpr CLASS_ID CLSID_GAME_PERSISTANT = MK_CLSID('G', '_', 'P', 'E', 'R', 'S', 'I', 'S'); constexpr CLASS_ID CLSID_OBJECT = MK_CLSID('O', 'B', 'J', 'E', 'C', 'T', ' ', ' '); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 4c60b94f653..95b5fb878b3 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -14,7 +14,6 @@ #include "xrCore/Threading/TaskManager.hpp" #include "xrNetServer/NET_AuthCheck.h" -#include "std_classes.h" #include "IGame_Persistent.h" #include "LightAnimLibrary.h" #include "XR_IOConsole.h" @@ -360,7 +359,8 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) if (game) { - g_pGamePersistent = dynamic_cast(NEW_INSTANCE(CLSID_GAME_PERSISTANT)); + m_game_module = game; + g_pGamePersistent = game->create_persistent(); R_ASSERT(g_pGamePersistent); } if (!g_pGamePersistent) @@ -374,7 +374,9 @@ CApplication::~CApplication() FrameMarkStart(APPLICATION_SHUTDOWN); // Destroy APP - DEL_INSTANCE(g_pGamePersistent); + if (m_game_module) + m_game_module->destroy_persistent(g_pGamePersistent); + Engine.Event.Dump(); // Destroying diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index 1ab9d457d3b..d7bc129faba 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -26,6 +26,9 @@ class ENGINE_API CApplication final std::mutex m_discord_lock; discord::Core* m_discord_core{}; +private: + GameModule* m_game_module{}; + private: void SplashProc(); diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index 73a488827b6..927cee3eb48 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -9,6 +9,7 @@ #include "StdAfx.h" #include "xrGame.h" +#include "GamePersistent.h" #include "object_factory.h" #include "xrEngine/xr_level_controller.h" @@ -84,3 +85,14 @@ void xrGameModule::finalize() xr_delete(g_profiler); #endif } + +IGame_Persistent* xrGameModule::create_persistent() +{ + object_factory(); // XXX: remove this call + return xr_new(); +} + +void xrGameModule::destroy_persistent(IGame_Persistent* persistent) +{ + xr_delete(persistent); +} diff --git a/src/xrGame/xrGame.h b/src/xrGame/xrGame.h index dbc068e6612..b5f2a2050d1 100644 --- a/src/xrGame/xrGame.h +++ b/src/xrGame/xrGame.h @@ -24,6 +24,8 @@ class xrGameModule final : public GameModule public: void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) override; void finalize() override; + IGame_Persistent* create_persistent() override; + void destroy_persistent(IGame_Persistent* persistent) override; }; extern XRGAME_API xrGameModule xrGame; diff --git a/src/xrServerEntities/object_factory_register.cpp b/src/xrServerEntities/object_factory_register.cpp index 1407845b924..c78cbeff712 100644 --- a/src/xrServerEntities/object_factory_register.cpp +++ b/src/xrServerEntities/object_factory_register.cpp @@ -18,8 +18,6 @@ // client entities includes #ifndef NO_XR_GAME -#include "xrEngine/std_classes.h" -#include "GamePersistent.h" #include "Actor.h" #include "Spectator.h" @@ -191,8 +189,6 @@ void CObjectFactory::register_classes() ZoneScoped; #ifndef NO_XR_GAME - // client entities - add(CLSID_GAME_PERSISTANT, "game"); // Server Game type add(CLSID_SV_GAME_SINGLE, "game_sv_single"); add(CLSID_SV_GAME_DEATHMATCH, "game_sv_deathmatch"); From d1f65eee654db2157a2cbd9f465b46b24efa2442 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 12:42:54 +0500 Subject: [PATCH 367/497] xrEngine: delete std_classes.h Not needed anymore --- src/xrEngine/CMakeLists.txt | 1 - src/xrEngine/IGame_Persistent.cpp | 1 - src/xrEngine/std_classes.h | 4 ---- src/xrEngine/xrEngine.vcxproj | 1 - src/xrEngine/xrEngine.vcxproj.filters | 3 --- src/xrEngine/xr_object_list.cpp | 1 - 6 files changed, 11 deletions(-) delete mode 100644 src/xrEngine/std_classes.h diff --git a/src/xrEngine/CMakeLists.txt b/src/xrEngine/CMakeLists.txt index 3bc9c26b077..3dd4e355554 100644 --- a/src/xrEngine/CMakeLists.txt +++ b/src/xrEngine/CMakeLists.txt @@ -19,7 +19,6 @@ target_sources_grouped( Properties.h pure.cpp pure.h - std_classes.h ) target_sources_grouped( diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index b9977501a8d..691ad705ca1 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -5,7 +5,6 @@ #include "GameFont.h" #include "ILoadingScreen.h" #include "PerformanceAlert.hpp" -#include "std_classes.h" #include "StringTable/StringTable.h" #include "xrScriptEngine/script_engine.hpp" diff --git a/src/xrEngine/std_classes.h b/src/xrEngine/std_classes.h deleted file mode 100644 index a245030a561..00000000000 --- a/src/xrEngine/std_classes.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -//***** Standart extension classes -constexpr CLASS_ID CLSID_OBJECT = MK_CLSID('O', 'B', 'J', 'E', 'C', 'T', ' ', ' '); diff --git a/src/xrEngine/xrEngine.vcxproj b/src/xrEngine/xrEngine.vcxproj index ebce9a5f093..2d81b9a5471 100644 --- a/src/xrEngine/xrEngine.vcxproj +++ b/src/xrEngine/xrEngine.vcxproj @@ -88,7 +88,6 @@ - diff --git a/src/xrEngine/xrEngine.vcxproj.filters b/src/xrEngine/xrEngine.vcxproj.filters index 58867d8bba0..7f2a1575169 100644 --- a/src/xrEngine/xrEngine.vcxproj.filters +++ b/src/xrEngine/xrEngine.vcxproj.filters @@ -303,9 +303,6 @@ Engine - - Engine - Engine\Console diff --git a/src/xrEngine/xr_object_list.cpp b/src/xrEngine/xr_object_list.cpp index 90514b9d6b0..488c12921cf 100644 --- a/src/xrEngine/xr_object_list.cpp +++ b/src/xrEngine/xr_object_list.cpp @@ -4,7 +4,6 @@ #include "xrSheduler.h" #include "xr_object_list.h" -#include "std_classes.h" #include "xr_object.h" #include "xrCore/net_utils.h" From 76ca227d3e8c1813d94cc53523e008f81efee550 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 4 May 2024 14:15:25 +0500 Subject: [PATCH 368/497] xrCore/Media/ImageJPEG.cpp: make xr_jpeg_error_mgr constructor explicit And formatting --- src/xrCore/Media/ImageJPEG.cpp | 62 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/xrCore/Media/ImageJPEG.cpp b/src/xrCore/Media/ImageJPEG.cpp index f6140ac9c7f..24e98373405 100644 --- a/src/xrCore/Media/ImageJPEG.cpp +++ b/src/xrCore/Media/ImageJPEG.cpp @@ -16,9 +16,9 @@ class xr_jpeg_error_mgr final : public jpeg_error_mgr jmp_buf setjmp_buffer; // for return to caller public: - xr_jpeg_error_mgr(jpeg_compress_struct& cinfo) + explicit xr_jpeg_error_mgr(jpeg_compress_struct& info) { - cinfo.err = jpeg_std_error(this); + info.err = jpeg_std_error(this); this->error_exit = on_error_exit; } @@ -28,12 +28,12 @@ class xr_jpeg_error_mgr final : public jpeg_error_mgr } private: - static void on_error_exit(j_common_ptr cinfo) + static void on_error_exit(j_common_ptr info) { - auto& self = *reinterpret_cast(cinfo->err); + auto& self = *reinterpret_cast(info->err); char buffer[JMSG_LENGTH_MAX]; - self.format_message(cinfo, buffer); + self.format_message(info, buffer); Msg("! JPEG fail: %s", buffer); longjmp(self.setjmp_buffer, 1); @@ -48,7 +48,7 @@ class xr_jpeg_destination_mgr final : public jpeg_destination_mgr IWriter& m_writer; public: - xr_jpeg_destination_mgr(jpeg_compress_struct& cinfo, IWriter& writer) : m_writer(writer) + xr_jpeg_destination_mgr(jpeg_compress_struct& info, IWriter& writer) : m_writer(writer) { next_output_byte = nullptr; free_in_buffer = 0; @@ -57,20 +57,20 @@ class xr_jpeg_destination_mgr final : public jpeg_destination_mgr empty_output_buffer = write_buffer; term_destination = finalize_destination; - cinfo.dest = this; + info.dest = this; } private: - static void initialize_destination(j_compress_ptr cinfo) + static void initialize_destination(j_compress_ptr info) { - auto& self = *reinterpret_cast(cinfo->dest); + auto& self = *reinterpret_cast(info->dest); self.next_output_byte = self.m_buffer; self.free_in_buffer = OUT_BUFFER_SIZE; } - static boolean write_buffer(j_compress_ptr cinfo) + static boolean write_buffer(j_compress_ptr info) { - auto& self = *reinterpret_cast(cinfo->dest); + auto& self = *reinterpret_cast(info->dest); self.m_writer.w(self.m_buffer, OUT_BUFFER_SIZE); @@ -80,9 +80,9 @@ class xr_jpeg_destination_mgr final : public jpeg_destination_mgr return TRUE; } - static void finalize_destination(j_compress_ptr cinfo) + static void finalize_destination(j_compress_ptr info) { - auto& self = *reinterpret_cast(cinfo->dest); + const auto& self = *reinterpret_cast(info->dest); const size_t data_left = OUT_BUFFER_SIZE - self.free_in_buffer; @@ -106,47 +106,47 @@ bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) } #ifdef JPEGLIB_H - jpeg_compress_struct cinfo; - xr_jpeg_error_mgr jerr(cinfo); + jpeg_compress_struct info; + xr_jpeg_error_mgr jerr(info); // Setup error handling if (setjmp(jerr.get_jmp_buffer())) { // If we get here, the JPEG code has signaled an error. - jpeg_destroy_compress(&cinfo); + jpeg_destroy_compress(&info); return false; } /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - xr_jpeg_destination_mgr cdest(cinfo, writer); + jpeg_create_compress(&info); + xr_jpeg_destination_mgr cdest(info, writer); { - cinfo.image_width = width; - cinfo.image_height = height; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; + info.image_width = width; + info.image_height = height; + info.input_components = 3; + info.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_set_defaults(&info); + jpeg_set_quality(&info, quality, TRUE); - jpeg_start_compress(&cinfo, TRUE); + jpeg_start_compress(&info, TRUE); { JSAMPLE* image_data = static_cast(data); const auto row_stride = width * 3; /* JSAMPLEs per row in image_buffer */ - while (cinfo.next_scanline < cinfo.image_height) + while (info.next_scanline < info.image_height) { - const auto scanline = invert ? cinfo.image_height - 1 - cinfo.next_scanline : cinfo.next_scanline; + const auto scanline = invert ? info.image_height - 1 - info.next_scanline : info.next_scanline; auto row_pointer = &image_data[scanline * row_stride]; - (void)jpeg_write_scanlines(&cinfo, &row_pointer, 1); + (void)jpeg_write_scanlines(&info, &row_pointer, 1); } } - jpeg_finish_compress(&cinfo); + jpeg_finish_compress(&info); } - jpeg_destroy_compress(&cinfo); + jpeg_destroy_compress(&info); return true; #else - Msg("~ %s: Engine was build without libjpeg.", __FUNCTION__); + Msg("~ %s: Engine was built without libjpeg.", __FUNCTION__); return false; #endif // JPEGLIB_H } From 1bdaada93ce0ef3ca09c1a09f3c1269413a8e8a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Sobiecki Date: Sat, 4 May 2024 21:58:11 +0200 Subject: [PATCH 369/497] debian/: Update *.install files and changelog (#1664) --- debian/changelog | 6 ++ debian/openxray-data.install | 112 ++++++++++++++++++++++++++++++++++- debian/openxray.install | 5 +- debian/rules | 1 + 4 files changed, 120 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 8a7fbd7a7df..7ae1b413f3b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openxray (1.6.02-14) experimental; urgency=medium + + * Update *.install files + + -- Krzysztof Sobiecki Sat, 04 May 2024 20:15:57 +0200 + openxray (1.6.02-13) experimental; urgency=medium * Update debian build infrastructure diff --git a/debian/openxray-data.install b/debian/openxray-data.install index d62864d674b..80fb1c217bf 100644 --- a/debian/openxray-data.install +++ b/debian/openxray-data.install @@ -198,7 +198,6 @@ usr/share/openxray/gamedata/shaders/gl/accum_volumetric_sun_nomsaa.ps usr/share/openxray/gamedata/shaders/gl/accum_spot_normal_nomsaa.ps usr/share/openxray/gamedata/shaders/gl/accum_sun_mask_msaa.ps usr/share/openxray/gamedata/shaders/gl/accum_sun_far_msaa.ps -usr/share/openxray/gamedata/shaders/gl/_sh.vs usr/share/openxray/gamedata/shaders/gl/effects_sun.s usr/share/openxray/gamedata/shaders/gl/ssao.ps usr/share/openxray/gamedata/shaders/gl/accum_volumetric_sun_msaa5.ps @@ -216,7 +215,6 @@ usr/share/openxray/gamedata/shaders/gl/lmape.vs usr/share/openxray/gamedata/shaders/gl/deffer_base_lmh_flat.ps usr/share/openxray/gamedata/shaders/gl/stub_notransform.vs usr/share/openxray/gamedata/shaders/gl/water_soft.ps -usr/share/openxray/gamedata/shaders/gl/_sh.ps usr/share/openxray/gamedata/shaders/gl/wmark.vs usr/share/openxray/gamedata/shaders/gl/effects_water.s usr/share/openxray/gamedata/shaders/gl/combine_1.vs @@ -753,6 +751,116 @@ usr/share/openxray/gamedata/scripts/.gitattributes usr/share/openxray/gamedata/scripts/ui_mm_opt_gameplay.script usr/share/openxray/gamedata/scripts/ui_mm_opt_controls.script usr/share/openxray/gamedata/scripts/ui_sleep_dialog.script +usr/share/openxray/gamedata/textures/de/de_cache_bricks_wall_04_normal.dds +usr/share/openxray/gamedata/textures/de/de_cache_rollup_door_01_grungy_bump.dds +usr/share/openxray/gamedata/textures/door/door_electricunit_01.thm +usr/share/openxray/gamedata/textures/fx/blue_noise.dds +usr/share/openxray/gamedata/textures/fx/hud_rain.dds +usr/share/openxray/gamedata/textures/fx/puddles_perlin.dds +usr/share/openxray/gamedata/textures/fx/rain_drop.dds +usr/share/openxray/gamedata/textures/fx/rain_splash.dds +usr/share/openxray/gamedata/textures/fx/water_caustics.dds +usr/share/openxray/gamedata/textures/fx/water_normal.dds +usr/share/openxray/gamedata/textures/fx/water_sbumpvolume.dds +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves.thm +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_00.thm +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_01.thm +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_02.thm +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_03.thm +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_bump.dds +usr/share/openxray/gamedata/textures/lfo/lfo_details/plants/water_leaves_full.thm +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_droplets.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_1.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_10.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_2.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_3.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_4.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_5.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_6.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_7.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_8.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_nm_9.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_v_1.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_v_2.dds +usr/share/openxray/gamedata/textures/shaders/gasmasks/mask_v_3.dds +usr/share/openxray/gamedata/textures/sunmask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_agroprom_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_darkcape_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_darkvalley_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_frodo_gen_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_garbage_new_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_jupiter_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_limansk_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_marsh_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_military_1_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_pripyat_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_red_forest_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_yantar_puddles_mask.dds +usr/share/openxray/gamedata/textures/terrain/terrain_zaton_puddles_mask.dds +usr/share/openxray/gamedata/textures/trees/trees_dub.thm +usr/share/openxray/gamedata/textures/trees/trees_dub_red.thm +usr/share/openxray/gamedata/textures/trees/trees_elka.thm +usr/share/openxray/gamedata/textures/trees/trees_elka_sux.thm +usr/share/openxray/gamedata/textures/trees/trees_kamish_big_01.thm +usr/share/openxray/gamedata/textures/trees/trees_kamish_big_02.thm +usr/share/openxray/gamedata/textures/trees/trees_kamish_sux.thm +usr/share/openxray/gamedata/textures/trees/trees_vetkabig.thm +usr/share/openxray/gamedata/textures/trees/trees_vetkagreen1.thm +usr/share/openxray/gamedata/textures/trees/trees_vetkagreen3.thm +usr/share/openxray/gamedata/textures/trees/trees_vetkagreen5.thm +usr/share/openxray/gamedata/textures/trees/trees_vetkasux2.thm +usr/share/openxray/gamedata/textures/water/pure_waters_3.dds +usr/share/openxray/gamedata/textures/water/water_dudv.dds +usr/share/openxray/gamedata/textures/water/water_dudv.seq +usr/share/openxray/gamedata/textures/water/water_flowing_nmap.dds +usr/share/openxray/gamedata/textures/water/water_flowing_spec.dds +usr/share/openxray/gamedata/textures/water/water_foam.dds +usr/share/openxray/gamedata/textures/water/water_normal.dds +usr/share/openxray/gamedata/textures/water/water_normal.seq +usr/share/openxray/gamedata/textures/water/water_normal_0.dds +usr/share/openxray/gamedata/textures/water/water_normal_1.dds +usr/share/openxray/gamedata/textures/water/water_normal_10.dds +usr/share/openxray/gamedata/textures/water/water_normal_11.dds +usr/share/openxray/gamedata/textures/water/water_normal_12.dds +usr/share/openxray/gamedata/textures/water/water_normal_13.dds +usr/share/openxray/gamedata/textures/water/water_normal_14.dds +usr/share/openxray/gamedata/textures/water/water_normal_15.dds +usr/share/openxray/gamedata/textures/water/water_normal_16.dds +usr/share/openxray/gamedata/textures/water/water_normal_17.dds +usr/share/openxray/gamedata/textures/water/water_normal_18.dds +usr/share/openxray/gamedata/textures/water/water_normal_19.dds +usr/share/openxray/gamedata/textures/water/water_normal_2.dds +usr/share/openxray/gamedata/textures/water/water_normal_20.dds +usr/share/openxray/gamedata/textures/water/water_normal_21.dds +usr/share/openxray/gamedata/textures/water/water_normal_22.dds +usr/share/openxray/gamedata/textures/water/water_normal_23.dds +usr/share/openxray/gamedata/textures/water/water_normal_24.dds +usr/share/openxray/gamedata/textures/water/water_normal_25.dds +usr/share/openxray/gamedata/textures/water/water_normal_26.dds +usr/share/openxray/gamedata/textures/water/water_normal_27.dds +usr/share/openxray/gamedata/textures/water/water_normal_28.dds +usr/share/openxray/gamedata/textures/water/water_normal_3.dds +usr/share/openxray/gamedata/textures/water/water_normal_4.dds +usr/share/openxray/gamedata/textures/water/water_normal_5.dds +usr/share/openxray/gamedata/textures/water/water_normal_6.dds +usr/share/openxray/gamedata/textures/water/water_normal_7.dds +usr/share/openxray/gamedata/textures/water/water_normal_8.dds +usr/share/openxray/gamedata/textures/water/water_normal_9.dds +usr/share/openxray/gamedata/textures/water/water_pool1.dds +usr/share/openxray/gamedata/textures/water/water_pool2.dds +usr/share/openxray/gamedata/textures/water/water_ryaska1.dds +usr/share/openxray/gamedata/textures/water/water_ryaska1_bump#.dds +usr/share/openxray/gamedata/textures/water/water_ryaska1_bump.dds +usr/share/openxray/gamedata/textures/water/water_ryaska2.dds +usr/share/openxray/gamedata/textures/water/water_ryska.dds +usr/share/openxray/gamedata/textures/water/water_sbumpvolume.dds +usr/share/openxray/gamedata/textures/water/water_sdiffusevolume.dds +usr/share/openxray/gamedata/textures/water/water_studen.dds +usr/share/openxray/gamedata/textures/water/water_studen_bump#.dds +usr/share/openxray/gamedata/textures/water/water_studen_bump.dds +usr/share/openxray/gamedata/textures/water/water_studen_green.dds +usr/share/openxray/gamedata/textures/water/water_water.dds +usr/share/openxray/gamedata/textures/water/water_water_r1.dds usr/share/bash-completion/completions usr/share/bash-completion/completions/xr_3da usr/share/icons/hicolor/16x16/apps/openxray_cop.png diff --git a/debian/openxray.install b/debian/openxray.install index bc35489fd69..13685d10600 100644 --- a/debian/openxray.install +++ b/debian/openxray.install @@ -1,9 +1,7 @@ usr/lib/*/xrRender_GL.so usr/lib/*/xrCDB.so -usr/lib/*/xrLuabind.so usr/lib/*/xrAICore.so usr/lib/*/xrAPI.so -usr/lib/*/xrLuajit.so usr/lib/*/xrScriptEngine.so usr/lib/*/xrEngine.so usr/lib/*/xrCore.so @@ -12,6 +10,9 @@ usr/lib/*/xrSound.so usr/lib/*/xrGame.so usr/lib/*/xrUICore.so usr/lib/*/xrParticles.so +usr/lib/*/xrLuaJIT.so +usr/lib/*/xrLuabind.so +usr/lib/*/xrMaterialSystem.so usr/games/xr_3da usr/share/applications/openxray_cop.desktop usr/share/applications/openxray_soc.desktop diff --git a/debian/rules b/debian/rules index fdd336a3242..150146fcf1a 100755 --- a/debian/rules +++ b/debian/rules @@ -14,6 +14,7 @@ extra_flags += \ -DCMAKE_INSTALL_BINDIR="/usr/games" \ -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=FALSE \ -DALLOW_RPATH=FALSE \ +-DLUABIND_BUILD_SHARED=TRUE \ -DDISABLE_PORTABLE_MODE=TRUE override_dh_auto_configure: From bf77ac1af0715a6a2aac62a48f2aea1c6bb8d23c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 14:28:56 +0500 Subject: [PATCH 370/497] xrCore/Media/Image.hpp: use u32 for width and height, replace Create() with constructor --- src/Layers/xrRenderDX11/dx11r_screenshot.cpp | 3 +-- src/Layers/xrRenderGL/glr_screenshot.cpp | 3 +-- src/xrCore/Media/Image.cpp | 13 ++++--------- src/xrCore/Media/Image.hpp | 10 +++++----- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11r_screenshot.cpp b/src/Layers/xrRenderDX11/dx11r_screenshot.cpp index 03b701ab624..cbe4577ae16 100644 --- a/src/Layers/xrRenderDX11/dx11r_screenshot.cpp +++ b/src/Layers/xrRenderDX11/dx11r_screenshot.cpp @@ -126,8 +126,7 @@ void CRender::Screenshot(ScreenshotMode mode /*= SM_NORMAL*/, pcstr name /*= nul if (IWriter* fs = FS.w_open("$screenshots$", buf)) { - XRay::Media::Image img; - img.Create(u16(Device.dwHeight), u16(Device.dwHeight), data, XRay::Media::ImageDataFormat::RGBA8); + XRay::Media::Image img{ Device.dwHeight, Device.dwHeight, data, XRay::Media::ImageDataFormat::RGBA8 }; img.SaveTGA(*fs, true); FS.w_close(fs); } diff --git a/src/Layers/xrRenderGL/glr_screenshot.cpp b/src/Layers/xrRenderGL/glr_screenshot.cpp index bc4ffc5c30c..02ee4749cd5 100644 --- a/src/Layers/xrRenderGL/glr_screenshot.cpp +++ b/src/Layers/xrRenderGL/glr_screenshot.cpp @@ -32,8 +32,7 @@ void CRender::Screenshot(ScreenshotMode mode /*= SM_NORMAL*/, pcstr name /*= nul glReadPixels(0, 0, Device.dwWidth, Device.dwHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels.data()); - Image img; - img.Create(u16(Device.dwWidth), u16(Device.dwHeight), pixels.data(), ImageDataFormat::RGB8); + Image img{ Device.dwWidth, Device.dwHeight, pixels.data(), ImageDataFormat::RGB8 }; if (!img.SaveJPEG(*fs, 100, true)) Log("! Failed to make a screenshot."); diff --git a/src/xrCore/Media/Image.cpp b/src/xrCore/Media/Image.cpp index 639a75a7773..42f709c7830 100644 --- a/src/xrCore/Media/Image.cpp +++ b/src/xrCore/Media/Image.cpp @@ -5,15 +5,10 @@ using namespace XRay::Media; -Image& Image::Create(u16 width, u16 height, void* data, ImageDataFormat format) -{ - this->width = width; - this->height = height; - this->data = data; - this->format = format; - channelCount = format == ImageDataFormat::RGB8 ? 3 : 4; - return *this; -} +Image::Image(u32 w, u32 h, void* dataPtr, ImageDataFormat fmt) + : format(fmt), + channelCount(format == ImageDataFormat::RGB8 ? 3 : 4), + width(w), height(h), data(dataPtr) {} void Image::SaveTGA(const char* name, ImageDataFormat format, bool align) { diff --git a/src/xrCore/Media/Image.hpp b/src/xrCore/Media/Image.hpp index 12159e5056e..40c5474a735 100644 --- a/src/xrCore/Media/Image.hpp +++ b/src/xrCore/Media/Image.hpp @@ -34,16 +34,16 @@ class XRCORE_API Image final }; #pragma pack(pop) - ImageDataFormat format; - int channelCount; - u16 width, height; - void* data; + ImageDataFormat format{}; + int channelCount{}; + u32 width{}, height{}; + void* data{}; public: Image() = default; + Image(u32 w, u32 h, void* dataPtr, ImageDataFormat fmt); ~Image() = default; - Image& Create(u16 width, u16 height, void* data, ImageDataFormat format); void SaveTGA(IWriter& writer, bool align); void SaveTGA(IWriter& writer, ImageDataFormat format, bool align); From 828c7f4d42c8c9a0c1ef8006de4fbdd71d6c0f57 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:07:37 +0500 Subject: [PATCH 371/497] xrCore/Media/ImageJPEG.cpp: support RGBA8 in SaveJPEG() Only supported if engine is built with jpeg-turbo --- src/xrCore/Media/ImageJPEG.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/xrCore/Media/ImageJPEG.cpp b/src/xrCore/Media/ImageJPEG.cpp index 24e98373405..f9fb7d01218 100644 --- a/src/xrCore/Media/ImageJPEG.cpp +++ b/src/xrCore/Media/ImageJPEG.cpp @@ -99,13 +99,15 @@ bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) { clamp(quality, 0, 100); - if (format == ImageDataFormat::RGBA8) +#ifdef JPEGLIB_H +# if !defined(JCS_EXTENSIONS) && !defined(JCS_ALPHA_EXTENSIONS) + if (format != ImageDataFormat::RGB8) { Msg("! %s: Unsupported data format", __FUNCTION__); return false; } +# endif -#ifdef JPEGLIB_H jpeg_compress_struct info; xr_jpeg_error_mgr jerr(info); @@ -123,8 +125,17 @@ bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) { info.image_width = width; info.image_height = height; - info.input_components = 3; - info.in_color_space = JCS_RGB; + info.input_components = channelCount; + + switch (channelCount) + { + default: + case 3: info.in_color_space = JCS_RGB; break; + +# if defined(JCS_EXTENSIONS) && defined(JCS_ALPHA_EXTENSIONS) + case 4: info.in_color_space = JCS_EXT_RGBA; break; +# endif + } jpeg_set_defaults(&info); jpeg_set_quality(&info, quality, TRUE); @@ -132,7 +143,7 @@ bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) jpeg_start_compress(&info, TRUE); { JSAMPLE* image_data = static_cast(data); - const auto row_stride = width * 3; /* JSAMPLEs per row in image_buffer */ + const auto row_stride = width * channelCount; /* JSAMPLEs per row in image_buffer */ while (info.next_scanline < info.image_height) { From 4d9842e1555d3bcc94882f6dbd7475096d6cce2e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:08:06 +0500 Subject: [PATCH 372/497] xrCore/Media/ImageJPEG.cpp: ignore unused variables --- src/xrCore/Media/ImageJPEG.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xrCore/Media/ImageJPEG.cpp b/src/xrCore/Media/ImageJPEG.cpp index f9fb7d01218..63a35edc130 100644 --- a/src/xrCore/Media/ImageJPEG.cpp +++ b/src/xrCore/Media/ImageJPEG.cpp @@ -157,6 +157,9 @@ bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) jpeg_destroy_compress(&info); return true; #else + std::ignore = writer; + std::ignore = invert; + Msg("~ %s: Engine was built without libjpeg.", __FUNCTION__); return false; #endif // JPEGLIB_H From 4694a00577d07b684c428d65b8d97dd8002e68dd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:13:06 +0500 Subject: [PATCH 373/497] xrCore/Media/Image.hpp|cpp: support reading JPEG --- src/xrCore/Media/Image.cpp | 6 ++++ src/xrCore/Media/Image.hpp | 5 ++- src/xrCore/Media/ImageJPEG.cpp | 65 ++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/xrCore/Media/Image.cpp b/src/xrCore/Media/Image.cpp index 42f709c7830..b64b4b4220b 100644 --- a/src/xrCore/Media/Image.cpp +++ b/src/xrCore/Media/Image.cpp @@ -10,6 +10,12 @@ Image::Image(u32 w, u32 h, void* dataPtr, ImageDataFormat fmt) channelCount(format == ImageDataFormat::RGB8 ? 3 : 4), width(w), height(h), data(dataPtr) {} +Image::~Image() +{ + if (ownsData) + xr_free(data); +} + void Image::SaveTGA(const char* name, ImageDataFormat format, bool align) { FILE* file = std::fopen(name, "wb"); diff --git a/src/xrCore/Media/Image.hpp b/src/xrCore/Media/Image.hpp index 40c5474a735..fd2906b5ef6 100644 --- a/src/xrCore/Media/Image.hpp +++ b/src/xrCore/Media/Image.hpp @@ -38,12 +38,15 @@ class XRCORE_API Image final int channelCount{}; u32 width{}, height{}; void* data{}; + bool ownsData{}; public: Image() = default; Image(u32 w, u32 h, void* dataPtr, ImageDataFormat fmt); - ~Image() = default; + ~Image(); + bool OpenJPEG(const IReader& reader); + bool OpenJPEG(const u8* dataPtr, u32 dataSize); void SaveTGA(IWriter& writer, bool align); void SaveTGA(IWriter& writer, ImageDataFormat format, bool align); diff --git a/src/xrCore/Media/ImageJPEG.cpp b/src/xrCore/Media/ImageJPEG.cpp index 63a35edc130..4c9836d6324 100644 --- a/src/xrCore/Media/ImageJPEG.cpp +++ b/src/xrCore/Media/ImageJPEG.cpp @@ -22,6 +22,12 @@ class xr_jpeg_error_mgr final : public jpeg_error_mgr this->error_exit = on_error_exit; } + explicit xr_jpeg_error_mgr(jpeg_decompress_struct& info) + { + info.err = jpeg_std_error(this); + this->error_exit = on_error_exit; + } + auto get_jmp_buffer() { return setjmp_buffer; @@ -94,6 +100,65 @@ class xr_jpeg_destination_mgr final : public jpeg_destination_mgr }; #endif // JPEGLIB_H +bool Image::OpenJPEG(const IReader& reader) +{ + return OpenJPEG(static_cast(reader.pointer()), static_cast(reader.elapsed())); +} + +bool Image::OpenJPEG(const u8* dataPtr, u32 dataSize) +{ +#ifdef JPEGLIB_H + jpeg_decompress_struct info; + xr_jpeg_error_mgr jerr(info); + + // Setup error handling + if (setjmp(jerr.get_jmp_buffer())) + { + // If we get here, the JPEG code has signaled an error. + jpeg_destroy_decompress(&info); + return false; + } + + jpeg_create_decompress(&info); + { + jpeg_mem_src(&info, dataPtr, dataSize); + jpeg_read_header(&info, true); + + width = info.image_width; + height = info.image_height; + channelCount = info.num_components; + + switch (channelCount) + { + case 3: format = ImageDataFormat::RGB8; break; + case 4: format = ImageDataFormat::RGBA8; break; + } + + info.out_color_space = JCS_RGB; + + jpeg_start_decompress(&info); + { + const auto size = width * height * channelCount; + data = xr_malloc(size); + ownsData = true; + + JSAMPROW buf[1]; + + while (info.output_scanline < info.output_height) + { + buf[0] = JSAMPROW(&((u8*)data)[channelCount * info.output_width * info.output_scanline]); + jpeg_read_scanlines(&info, buf, 1); + } + } + jpeg_finish_decompress(&info); + } + jpeg_destroy_decompress(&info); + return true; +#else + Msg("~ %s: Engine was built without libjpeg.", __FUNCTION__); + return false; +#endif +} bool Image::SaveJPEG(IWriter& writer, int quality, bool invert /*= false*/) { From 26a3c0b02438b18054a12b6749f070647b01d8d4 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 16:06:09 +0500 Subject: [PATCH 374/497] xrCore/Media/ImageJPEG.cpp: fix compilation --- src/xrCore/Media/ImageJPEG.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xrCore/Media/ImageJPEG.cpp b/src/xrCore/Media/ImageJPEG.cpp index 4c9836d6324..a3039c47ea0 100644 --- a/src/xrCore/Media/ImageJPEG.cpp +++ b/src/xrCore/Media/ImageJPEG.cpp @@ -121,7 +121,9 @@ bool Image::OpenJPEG(const u8* dataPtr, u32 dataSize) jpeg_create_decompress(&info); { - jpeg_mem_src(&info, dataPtr, dataSize); + // don't remove const_cast, + // it's needed to fix compilation on older version of libjpeg + jpeg_mem_src(&info, const_cast(dataPtr), dataSize); jpeg_read_header(&info, true); width = info.image_width; From a69e494f001d574332bff8941a82cef702df3533 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:32:28 +0500 Subject: [PATCH 375/497] xrGame/UIServerInfo.cpp: replace CxImage with own JPEG reader --- src/xrGame/ui/UIServerInfo.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/xrGame/ui/UIServerInfo.cpp b/src/xrGame/ui/UIServerInfo.cpp index bd755bf5f05..d1fc54c1772 100644 --- a/src/xrGame/ui/UIServerInfo.cpp +++ b/src/xrGame/ui/UIServerInfo.cpp @@ -9,10 +9,7 @@ #include "Level.h" #include "game_cl_mp.h" -#if __has_include("ximage.h") -# include "ximage.h" -# include "xmemfile.h" -#endif +#include "xrCore/Media/Image.hpp" CUIServerInfo::CUIServerInfo() : CUIDialogWnd(CUIServerInfo::GetDebugType()) @@ -94,12 +91,10 @@ void CUIServerInfo::InitCallbacks() char const* CUIServerInfo::tmp_logo_file_name = "tmp_sv_logo.dds"; void CUIServerInfo::SetServerLogo(u8 const* data_ptr, u32 const data_size) { -#if __has_include("ximage.h") - CxMemFile tmp_memfile(const_cast(data_ptr), data_size); - CxImage tmp_image; - if (!tmp_image.Decode(&tmp_memfile, CXIMAGE_FORMAT_JPG)) + XRay::Media::Image img; + if (!img.OpenJPEG(data_ptr, data_size)) { - Msg("! ERROR: Failed to decode server logo image as JPEG formated."); + Msg("! ERROR: Failed to decode server logo image as JPEG."); return; } @@ -109,14 +104,12 @@ void CUIServerInfo::SetServerLogo(u8 const* data_ptr, u32 const data_size) Msg("! ERROR: failed to create temporary dds file"); return; } + // XXX: real convert jpg to dds tmp_writer->w((void*)data_ptr, data_size); // sorry :( FS.w_close(tmp_writer); m_dds_file_created = true; m_image->InitTexture(tmp_logo_file_name); FS.file_delete("$game_saves$", tmp_logo_file_name); -#else - VERIFY(!"Not implemented."); -#endif } void CUIServerInfo::SetServerRules(u8 const* data_ptr, u32 const data_size) From 8b50194543a9b7849efe70c322d4c739e5ba0685 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:49:46 +0500 Subject: [PATCH 376/497] Removed MP anti-cheater screenshot functionality Sorry, there are reasons to remove this. We can reimplement it in future if needed. --- src/Layers/xrRender/D3DXRenderBase.cpp | 3 - src/Layers/xrRender/r__screenshot.cpp | 9 - src/Layers/xrRenderDX11/dx11r_screenshot.cpp | 28 -- src/Layers/xrRenderGL/glr_screenshot.cpp | 6 - src/Layers/xrRenderPC_GL/CMakeLists.txt | 1 - src/Layers/xrRenderPC_GL/gl_rendertarget.h | 5 - .../gl_rendertarget_build_textures.cpp | 18 - .../gl_rendertarget_phase_combine.cpp | 27 +- src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj | 1 - .../xrRenderPC_GL/xrRender_GL.vcxproj.filters | 3 - src/Layers/xrRenderPC_R4/r4_rendertarget.h | 2 - .../r4_rendertarget_phase_combine.cpp | 28 +- src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj | 1 - .../xrRenderPC_R4/xrRender_R4.vcxproj.filters | 3 - src/Layers/xrRender_R2/r2.cpp | 3 - src/Layers/xrRender_R2/r2.h | 3 - src/Layers/xrRender_R2/r2_rendertarget.cpp | 2 - src/engine.sln | 35 -- src/utils/mp_screenshots_info/entry_point.cpp | 114 ------- .../mp_screenshots_info.vcxproj | 67 ---- .../mp_screenshots_info.vcxproj.filters | 28 -- src/utils/mp_screenshots_info/pch.cpp | 1 - src/utils/mp_screenshots_info/pch.h | 7 - .../screenshots_common.cpp | 52 --- .../mp_screenshots_info/screenshots_common.h | 21 -- .../screenshots_reader.cpp | 105 ------ .../mp_screenshots_info/screenshots_reader.h | 43 --- .../screenshots_writer.cpp | 106 ------ .../mp_screenshots_info/screenshots_writer.h | 44 --- src/xrEngine/Render.h | 2 - src/xrGame/CMakeLists.txt | 6 - src/xrGame/game_cl_mp.cpp | 7 +- src/xrGame/game_cl_mp.h | 2 - src/xrGame/screenshot_manager.cpp | 320 ------------------ src/xrGame/screenshot_manager.h | 72 ---- src/xrGame/screenshots_common.cpp | 39 --- src/xrGame/screenshots_common.h | 15 - src/xrGame/screenshots_writer.cpp | 99 ------ src/xrGame/screenshots_writer.h | 51 --- src/xrGame/xrGame.vcxproj | 6 - src/xrGame/xrGame.vcxproj.filters | 21 -- src/xrGame/xrServer.cpp | 2 + 42 files changed, 7 insertions(+), 1401 deletions(-) delete mode 100644 src/Layers/xrRender/r__screenshot.cpp delete mode 100644 src/utils/mp_screenshots_info/entry_point.cpp delete mode 100644 src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj delete mode 100644 src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj.filters delete mode 100644 src/utils/mp_screenshots_info/pch.cpp delete mode 100644 src/utils/mp_screenshots_info/pch.h delete mode 100644 src/utils/mp_screenshots_info/screenshots_common.cpp delete mode 100644 src/utils/mp_screenshots_info/screenshots_common.h delete mode 100644 src/utils/mp_screenshots_info/screenshots_reader.cpp delete mode 100644 src/utils/mp_screenshots_info/screenshots_reader.h delete mode 100644 src/utils/mp_screenshots_info/screenshots_writer.cpp delete mode 100644 src/utils/mp_screenshots_info/screenshots_writer.h delete mode 100644 src/xrGame/screenshot_manager.cpp delete mode 100644 src/xrGame/screenshot_manager.h delete mode 100644 src/xrGame/screenshots_common.cpp delete mode 100644 src/xrGame/screenshots_common.h delete mode 100644 src/xrGame/screenshots_writer.cpp delete mode 100644 src/xrGame/screenshots_writer.h diff --git a/src/Layers/xrRender/D3DXRenderBase.cpp b/src/Layers/xrRender/D3DXRenderBase.cpp index ce8a0818b68..09a46881024 100644 --- a/src/Layers/xrRender/D3DXRenderBase.cpp +++ b/src/Layers/xrRender/D3DXRenderBase.cpp @@ -289,8 +289,6 @@ void D3DXRenderBase::Clear() } } -void DoAsyncScreenshot(); - void D3DXRenderBase::End() { if (HW.Caps.SceneMode) @@ -303,7 +301,6 @@ void D3DXRenderBase::End() #else RCache.OnFrameEnd(); #endif - DoAsyncScreenshot(); // we're done with rendering cleanup_contexts(); diff --git a/src/Layers/xrRender/r__screenshot.cpp b/src/Layers/xrRender/r__screenshot.cpp deleted file mode 100644 index 32aa851c5de..00000000000 --- a/src/Layers/xrRender/r__screenshot.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "stdafx.h" - -void CRender::ScreenshotAsyncBegin() -{ - VERIFY(!m_bMakeAsyncSS); - m_bMakeAsyncSS = true; -} - -void DoAsyncScreenshot() { RImplementation.Target->DoAsyncScreenshot(); } diff --git a/src/Layers/xrRenderDX11/dx11r_screenshot.cpp b/src/Layers/xrRenderDX11/dx11r_screenshot.cpp index cbe4577ae16..fa5d65c2d68 100644 --- a/src/Layers/xrRenderDX11/dx11r_screenshot.cpp +++ b/src/Layers/xrRenderDX11/dx11r_screenshot.cpp @@ -138,31 +138,3 @@ void CRender::Screenshot(ScreenshotMode mode /*= SM_NORMAL*/, pcstr name /*= nul _end_: _RELEASE(pSrcTexture); } - -void CRender::ScreenshotAsyncEnd(CMemoryWriter& memory_writer) -{ - VERIFY(!m_bMakeAsyncSS); - - // Don't own. No need to release. - ID3DTexture2D* pTex = Target->t_ss_async; - - D3D_MAPPED_TEXTURE2D MappedData; - - HW.get_context(CHW::IMM_CTX_ID)->Map(pTex, 0, D3D_MAP_READ, 0, &MappedData); - { - u32* pPixel = (u32*)MappedData.pData; - u32* pEnd = pPixel + (Device.dwWidth * Device.dwHeight); - - // Kill alpha and swap r and b. - for (; pPixel != pEnd; pPixel++) - { - u32 p = *pPixel; - *pPixel = color_xrgb(color_get_B(p), color_get_G(p), color_get_R(p)); - } - - memory_writer.w(&Device.dwWidth, sizeof(Device.dwWidth)); - memory_writer.w(&Device.dwHeight, sizeof(Device.dwHeight)); - memory_writer.w(MappedData.pData, (Device.dwWidth * Device.dwHeight) * 4); - } - HW.get_context(CHW::IMM_CTX_ID)->Unmap(pTex, 0); -} diff --git a/src/Layers/xrRenderGL/glr_screenshot.cpp b/src/Layers/xrRenderGL/glr_screenshot.cpp index 02ee4749cd5..233676426d7 100644 --- a/src/Layers/xrRenderGL/glr_screenshot.cpp +++ b/src/Layers/xrRenderGL/glr_screenshot.cpp @@ -48,9 +48,3 @@ void CRender::Screenshot(ScreenshotMode mode /*= SM_NORMAL*/, pcstr name /*= nul VERIFY(!"CRender::Screenshot. This screenshot type is not supported for OGL."); } } - -void CRender::ScreenshotAsyncEnd(CMemoryWriter &memory_writer) -{ - // TODO: OGL: Implement screenshot feature. - VERIFY(!"CRender::ScreenshotAsyncEnd not implemented."); -} diff --git a/src/Layers/xrRenderPC_GL/CMakeLists.txt b/src/Layers/xrRenderPC_GL/CMakeLists.txt index 1ac1c5a1a94..a61c0f09d5b 100644 --- a/src/Layers/xrRenderPC_GL/CMakeLists.txt +++ b/src/Layers/xrRenderPC_GL/CMakeLists.txt @@ -169,7 +169,6 @@ target_sources(xrRender_GL PRIVATE ../xrRender/r__occlusion.h ../xrRender/r__pixel_calculator.cpp ../xrRender/r__pixel_calculator.h - ../xrRender/r__screenshot.cpp ../xrRender/r__sector.cpp ../xrRender/r__sector.h ../xrRender/r__sector_detect.cpp diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget.h b/src/Layers/xrRenderPC_GL/gl_rendertarget.h index c6167b5b216..d0c9842678f 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget.h +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget.h @@ -77,9 +77,6 @@ class CRenderTarget : public IRender_Target ref_rt rt_smap_rain; ref_rt rt_smap_depth_minmax; // is used for min/max sm - // Igor: for async screenshots - GLuint t_ss_async; // 32bit (r,g,b,a) is situated in the system memory - // Textures GLuint t_material_surf; ref_texture t_material; @@ -325,8 +322,6 @@ class CRenderTarget : public IRender_Target void reset_light_marker(CBackend& cmd_list, bool bResetStencil = false); void increment_light_marker(CBackend& cmd_list); - void DoAsyncScreenshot(); - #ifdef DEBUG void dbg_addline(const Fvector& P0, const Fvector& P1, u32 c) { diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp index 1ed576c977e..68def07bc5b 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp @@ -30,24 +30,6 @@ static void generate_jitter(u32* dest, u32 elem_count) } void CRenderTarget::build_textures() { - // Texture for async sreenshots - /* TODO: OGL: Implement screenshots - { - D3D_TEXTURE2D_DESC desc; - desc.Width = Device.dwWidth; - desc.Height = Device.dwHeight; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; - desc.Usage = D3D_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D_CPU_ACCESS_READ; - desc.MiscFlags = 0; - - R_CHK(HW.pDevice->CreateTexture2D(&desc, 0, &t_ss_async)); - }*/ // Build material(s) { #ifdef XR_PLATFORM_BSD diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp index c07df7d53ed..061d88d0f3b 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp @@ -5,31 +5,6 @@ #define STENCIL_CULL 0 -void CRenderTarget::DoAsyncScreenshot() -{ - // Igor: screenshot will not have postprocess applied. - // TODO: fix that later - if (RImplementation.m_bMakeAsyncSS) - { - // HACK: unbind RT. CopyResourcess needs src and targetr to be unbound. - // u_setrt ( Device.dwWidth,Device.dwHeight,get_base_rt(),nullptr,nullptr,get_base_zb()); - - // ID3DTexture2D *pTex = 0; - // if (RImplementation.o.msaa) - // pTex = rt_Generic->pSurface; - // else - // pTex = rt_Color->pSurface; - - - //HW.pDevice->CopyResource( t_ss_async, pTex ); - glBindTexture(GL_TEXTURE_2D, t_ss_async); - CHK_GL(glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, Device.dwWidth, Device.dwHeight, 0)); - - - RImplementation.m_bMakeAsyncSS = false; - } -} - float hclip(float v, float dim) { return 2.f * v / dim - 1.f; } void CRenderTarget::phase_combine() @@ -296,7 +271,7 @@ void CRenderTarget::phase_combine() // PP enabled ? // Render to RT texture to be able to copy RT even in windowed mode. - BOOL PP_Complex = u_need_PP() || (BOOL)RImplementation.m_bMakeAsyncSS; + BOOL PP_Complex = u_need_PP(); if (_menu_pp) PP_Complex = FALSE; diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj index 65400ac586b..2aafb423ec4 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj @@ -95,7 +95,6 @@ - diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters index 467e542f2b6..141f1e0f08e 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters @@ -525,9 +525,6 @@ Core_Target - - Core - Refactored\Execution & 3D\Shaders\Blender diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget.h b/src/Layers/xrRenderPC_R4/r4_rendertarget.h index a0cde0c26fc..3c326b5e6e8 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget.h +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget.h @@ -357,8 +357,6 @@ class CRenderTarget : public IRender_Target void reset_light_marker(CBackend& cmd_list, bool bResetStencil = false); void increment_light_marker(CBackend& cmd_list); - void DoAsyncScreenshot(); - #ifdef DEBUG void dbg_addline(const Fvector& P0, const Fvector& P1, u32 c) { diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp index f7163af4143..00fff809480 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp @@ -5,32 +5,6 @@ #define STENCIL_CULL 0 -void CRenderTarget::DoAsyncScreenshot() -{ - // Igor: screenshot will not have postprocess applied. - // TODO: fix that later - if (RImplementation.m_bMakeAsyncSS) - { - HRESULT hr; - - // HACK: unbind RT. CopyResourcess needs src and targetr to be unbound. - // u_setrt ( Device.dwWidth,Device.dwHeight,get_base_rt(),NULL,NULL,get_base_zb()); - - // ID3DTexture2D *pTex = 0; - // if (RImplementation.o.msaa) - // pTex = rt_Generic->pSurface; - // else - // pTex = rt_Color->pSurface; - - // HW.pDevice->CopyResource( t_ss_async, pTex ); - ID3DTexture2D* pBuffer; - hr = HW.m_pSwapChain->GetBuffer(0, __uuidof(ID3DTexture2D), (LPVOID*)&pBuffer); - HW.get_context(CHW::IMM_CTX_ID)->CopyResource(t_ss_async, pBuffer); - - RImplementation.m_bMakeAsyncSS = false; - } -} - float hclip(float v, float dim) { return 2.f * v / dim - 1.f; } void CRenderTarget::phase_combine() @@ -332,7 +306,7 @@ void CRenderTarget::phase_combine() // PP enabled ? // Render to RT texture to be able to copy RT even in windowed mode. - BOOL PP_Complex = u_need_PP() | (BOOL)RImplementation.m_bMakeAsyncSS; + BOOL PP_Complex = u_need_PP(); if (_menu_pp) PP_Complex = FALSE; diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj index 8c818bc2ea6..0e36e14574d 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj @@ -353,7 +353,6 @@ - diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters index be0ffd38b06..2ccc307a713 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters @@ -779,9 +779,6 @@ Core - - Core - Details diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 3166e51579c..e4bd09d51d3 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -531,8 +531,6 @@ void CRender::create() Resources->RegisterConstantSetup("triLOD", &binder_LOD); #endif - m_bMakeAsyncSS = false; - Target = xr_new(); // Main target Models = xr_new(); @@ -552,7 +550,6 @@ void CRender::create() void CRender::destroy() { - m_bMakeAsyncSS = false; #if defined(USE_DX11) FluidManager.Destroy(); #endif diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index 527b9e495b2..98ae6f5dc18 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -344,7 +344,6 @@ class CRender final : public D3DXRenderBase R_sync_point q_sync_point; - bool m_bMakeAsyncSS; bool m_bFirstFrameAfterReset{}; // Determines weather the frame is the first after resetting device. private: @@ -496,8 +495,6 @@ class CRender final : public D3DXRenderBase void RenderMenu() override; void Screenshot(ScreenshotMode mode = SM_NORMAL, pcstr name = nullptr) override; - void ScreenshotAsyncBegin() override; - void ScreenshotAsyncEnd(CMemoryWriter& memory_writer) override; void OnFrame() override; void BeforeWorldRender() override; //--#SM+#-- +SecondVP+ Procedure is called before world render and post-effects diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index 3c194a63bf7..7972f2afad7 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -745,8 +745,6 @@ CRenderTarget::~CRenderTarget() #if defined(USE_DX11) _RELEASE(t_ss_async); #elif defined(USE_OGL) - glDeleteTextures(1, &t_ss_async); - // Textures t_material->surface_set(GL_TEXTURE_3D, 0); glDeleteTextures(1, &t_material_surf); diff --git a/src/engine.sln b/src/engine.sln index bdd2654fe27..9507ebc6c10 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -45,8 +45,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrPhysics", "xrPhysics\xrPh EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrRender_R4", "Layers\xrRenderPC_R4\xrRender_R4.vcxproj", "{AC9B12ED-A2D7-4337-A981-5BD8430E96D8}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp_screenshots_info", "utils\mp_screenshots_info\mp_screenshots_info.vcxproj", "{032A10AB-E44C-4751-A290-001EF99E664A}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp_configs_verifyer", "utils\mp_configs_verifyer\mp_configs_verifyer.vcxproj", "{1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CxImage", "..\Externals\cximage\cximage.vcxproj", "{880CD250-BA77-4DAF-A8D4-552F12DD3AE4}" @@ -646,38 +644,6 @@ Global {AC9B12ED-A2D7-4337-A981-5BD8430E96D8}.Release|x64.Build.0 = Release|x64 {AC9B12ED-A2D7-4337-A981-5BD8430E96D8}.Release|x86.ActiveCfg = Release|Win32 {AC9B12ED-A2D7-4337-A981-5BD8430E96D8}.Release|x86.Build.0 = Release|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|ARM.ActiveCfg = Debug|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|ARM.Build.0 = Debug|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|ARM64.ActiveCfg = Debug|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|ARM64.Build.0 = Debug|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|x64.ActiveCfg = Debug|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|x64.Build.0 = Debug|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|x86.ActiveCfg = Debug|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Debug|x86.Build.0 = Debug|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|ARM.ActiveCfg = Mixed|ARM - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|ARM.Build.0 = Mixed|ARM - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|x64.ActiveCfg = Mixed|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|x64.Build.0 = Mixed|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|x86.ActiveCfg = Mixed|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Mixed|x86.Build.0 = Mixed|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|ARM.ActiveCfg = Release|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|ARM.Build.0 = Release|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|ARM64.ActiveCfg = Release|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|ARM64.Build.0 = Release|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|x64.ActiveCfg = Release|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|x64.Build.0 = Release|x64 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|x86.ActiveCfg = Release|Win32 - {032A10AB-E44C-4751-A290-001EF99E664A}.Release|x86.Build.0 = Release|Win32 {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Debug|ARM.ActiveCfg = Debug|Win32 {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Debug|ARM.Build.0 = Debug|Win32 {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1551,7 +1517,6 @@ Global {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {3FC858CB-4888-42FF-ABC5-82DAECB59C2C} {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {032A10AB-E44C-4751-A290-001EF99E664A} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {880CD250-BA77-4DAF-A8D4-552F12DD3AE4} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {492D3DFE-9068-4E7E-A008-7C2420A651C0} = {CB0C814D-FB4E-453B-B7A0-716F4A1EACA4} diff --git a/src/utils/mp_screenshots_info/entry_point.cpp b/src/utils/mp_screenshots_info/entry_point.cpp deleted file mode 100644 index dc9e517c49a..00000000000 --- a/src/utils/mp_screenshots_info/entry_point.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "pch.h" -#include "screenshots_writer.h" -#include "screenshots_reader.h" - -void print_format() { printf("Format: mp_screenshots_info.exe [screenshot_file_name]\n"); }; -void xrcore_log_cb(void* context, LPCSTR log_string) { printf("%s\n", log_string); }; -u8* ss_buffer = NULL; -u32 ss_buffer_size = 0; -/*#ifdef DEBUG -void debug_sign_screenshot(IReader* screenshot) -{ - using namespace screenshots; //for writer - int tmp_jpeg_size = screenshot->elapsed(); - if (tmp_jpeg_size < 0) - return; - u32 tmp_buff_size = tmp_jpeg_size + writer::info_max_size; - u8* tmp_buff = static_cast(xr_malloc(tmp_buff_size)); - - screenshot->r (tmp_buff, tmp_jpeg_size); - - writer tmp_writer (tmp_buff, tmp_jpeg_size, tmp_buff_size); - - tmp_writer.set_player_name ("some_cheater"); - tmp_writer.set_player_cdkey_digest ("238940293847298374982734"); - u32 final_ss_size = tmp_writer.write_info(); - - IWriter* result_writer = FS.w_open("$screenshots$", "result.jpg"); - VERIFY (result_writer); - result_writer->w (tmp_buff, final_ss_size); - FS.w_close (result_writer); - - xr_free (tmp_buff); - Msg ("Screenshot signed successfully !"); -}; -#endif*/ - -void screenshot_info(IReader* screenshot) -{ - using namespace screenshots; // for reader - reader tmp_reader(screenshot); - if (!tmp_reader.is_valid()) - { - Msg("ERROR: screenshot not valid or corrupted."); - return; - } - Msg("Verifying screenshot digital sign..."); - bool verify_res = tmp_reader.verify(); - Msg("Screenshot verification: %s", verify_res ? "Succeeded" : "FAILED"); - if (!verify_res) - { - return; - } - Msg("Screenshot info:"); - Msg(" Player name: %s", tmp_reader.player_name().c_str()); - Msg(" Player cdkey digest: %s", tmp_reader.player_cdkey_digest().c_str()); - // Msg(" Admin name: %s", tmp_reader.admin_name().c_str()); - Msg(" Creation date: %s", tmp_reader.creation_date().c_str()); -} - -int main(int argc, char** argv) -{ - printf("Copyright (C) GSC Game World 2009\n"); - if (argc < 2) - { - printf("ERROR: bad parameters.\n"); - print_format(); - return EXIT_FAILURE; - } - printf("Initializing core...\n"); - Core.Initialize("mp_screenshots_info", nullptr, true, "fsgame4mpu.ltx"); - SetLogCB({ xrcore_log_cb, nullptr }); - -#ifdef DEBUG - if (strstr(argv[1], "--gen_params")) - { - crypto::xr_dsa::generate_params(); - Core._destroy(); - return EXIT_SUCCESS; - } -#endif - if (argc < 3) - { - printf("ERROR: screenshot file not specified.\n"); - print_format(); - return EXIT_FAILURE; - } - const char* ss_file = argv[2]; - IReader* tmp_jpg = FS.r_open("$screenshots$", ss_file); - if (!tmp_jpg) - { - tmp_jpg = FS.r_open(ss_file); - if (!tmp_jpg) - { - printf("ERROR: can't open file: %s", ss_file); - Core._destroy(); - return EXIT_FAILURE; - } - } - /*#ifdef DEBUG - if (strstr(argv[1], "--sign")) - { - debug_sign_screenshot (tmp_jpg); - } else if (strstr(argv[1], "--info")) - { - screenshot_info (tmp_jpg); - } - #else*/ - screenshot_info(tmp_jpg); - - FS.r_close(tmp_jpg); - xr_free(ss_buffer); - Core._destroy(); - return EXIT_SUCCESS; -} diff --git a/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj b/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj deleted file mode 100644 index d8ef9f78300..00000000000 --- a/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - {032A10AB-E44C-4751-A290-001EF99E664A} - mp_screenshots_info - - - - - - - Application - - - - - - - - - - - $(xrBinDir)utils\ - - - true - - - - pch.h - - - Console - - - - - - Create - - - - - true - - - - - - - - - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - - - - - - - \ No newline at end of file diff --git a/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj.filters b/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj.filters deleted file mode 100644 index 6807cbb1d1b..00000000000 --- a/src/utils/mp_screenshots_info/mp_screenshots_info.vcxproj.filters +++ /dev/null @@ -1,28 +0,0 @@ - - - - - {8baeba25-10f7-4a0a-ac1f-647cb6a2789b} - - - - - core - - - - - - - - - core - - - - - - - - - \ No newline at end of file diff --git a/src/utils/mp_screenshots_info/pch.cpp b/src/utils/mp_screenshots_info/pch.cpp deleted file mode 100644 index 1d9f38c57d6..00000000000 --- a/src/utils/mp_screenshots_info/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/src/utils/mp_screenshots_info/pch.h b/src/utils/mp_screenshots_info/pch.h deleted file mode 100644 index 008937e6545..00000000000 --- a/src/utils/mp_screenshots_info/pch.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "Common/Common.hpp" -#include "xrCore/xrCore.h" -#include "xrCore/LocatorAPI.h" - -#include diff --git a/src/utils/mp_screenshots_info/screenshots_common.cpp b/src/utils/mp_screenshots_info/screenshots_common.cpp deleted file mode 100644 index 6dc50f1eb89..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_common.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pch.h" -#include "screenshots_common.h" - -namespace screenshots -{ -char const* ss_info_secion = "screenshot_info"; -char const* ss_player_name_key = "player_name"; -char const* ss_player_digest_key = "player_digest"; -// char const* ss_admin_name_key = "admin_name"; -char const* ss_digital_sign_key = "digital_sign"; -char const* ss_creation_date = "creation_date"; - -// DSA params -u8 const p_number[crypto::xr_dsa::public_key_length] = -{ - 0xe0, 0xc7, 0x56, 0xaa, 0x69, 0xc8, 0x34, 0x75, 0xe2, 0x41, 0x5d, 0x33, 0xd2, 0x4e, 0x91, 0x09, 0xd9, 0x65, 0xbb, - 0x4c, 0x1d, 0xb9, 0xb8, 0x07, 0x9b, 0x05, 0x32, 0xa3, 0x72, 0x6e, 0x76, 0x24, 0x04, 0xb1, 0x4f, 0x3b, 0x58, 0xfa, - 0x05, 0x4c, 0x54, 0x95, 0x5d, 0xc3, 0x2b, 0xdd, 0x13, 0xe9, 0xd4, 0xe0, 0xa8, 0x8c, 0xd1, 0x9d, 0x11, 0xa1, 0x31, - 0x1b, 0x00, 0xa2, 0x82, 0xb7, 0xc9, 0x46, 0x01, 0x22, 0x9d, 0xa7, 0xb0, 0xe1, 0x4a, 0x10, 0x39, 0xd5, 0x92, 0xd4, - 0xcd, 0x02, 0x37, 0xa0, 0xda, 0x6a, 0xfe, 0x02, 0x82, 0x54, 0x9b, 0x5d, 0xcd, 0x71, 0xbf, 0x69, 0xc8, 0x77, 0x4c, - 0x7e, 0x5e, 0x4e, 0x7a, 0xff, 0x0f, 0x12, 0x62, 0xd5, 0xf5, 0xca, 0x0a, 0x76, 0x26, 0x6d, 0x16, 0x0b, 0x4f, 0x09, - 0x3b, 0x41, 0x09, 0x80, 0xff, 0x65, 0x15, 0xce, 0x29, 0x0f, 0x04, 0x45, 0xb0, 0xb1, -}; // p_number - -u8 const q_number[crypto::xr_dsa::private_key_length] = -{ - 0xfb, 0xe4, 0x9a, 0x95, 0x31, 0x49, 0xcb, 0xda, 0xf1, 0x91, 0x36, 0x82, 0xa8, 0x80, 0xfd, 0xcb, 0x4e, 0x38, 0x85, - 0x45, -}; // q_number - -u8 const g_number[crypto::xr_dsa::public_key_length] = -{ - 0xdc, 0x38, 0x96, 0xb4, 0x81, 0xf2, 0x2d, 0x60, 0x20, 0x7e, 0x9a, 0xe5, 0x74, 0x45, 0x7f, 0xa4, 0x9d, 0x71, 0xb8, - 0x94, 0x0a, 0xc5, 0xfb, 0x50, 0x71, 0xd9, 0xae, 0xb4, 0x74, 0xeb, 0x09, 0x93, 0x41, 0xd3, 0x70, 0x00, 0x60, 0x4b, - 0x0e, 0x95, 0xb8, 0x31, 0x3d, 0x50, 0x84, 0x60, 0x6e, 0x16, 0xba, 0x7b, 0xc4, 0x8e, 0x25, 0xe0, 0x39, 0x10, 0x7e, - 0xb9, 0x2a, 0xaf, 0x4b, 0x40, 0xd7, 0xc4, 0xa0, 0x2a, 0x19, 0xfe, 0x1f, 0x77, 0x04, 0x8f, 0x73, 0xe1, 0x6e, 0xfe, - 0x8f, 0xbc, 0xcc, 0x8b, 0xdd, 0x12, 0x21, 0x86, 0xa6, 0x4d, 0x90, 0x9a, 0xbd, 0xfe, 0x8a, 0x05, 0x39, 0xad, 0xb4, - 0x45, 0xf6, 0xf9, 0x0f, 0xe5, 0x91, 0x5c, 0x2c, 0x19, 0xa0, 0xf1, 0x2e, 0x06, 0x02, 0x92, 0x68, 0xaa, 0xbc, 0x7c, - 0xf4, 0x4c, 0x85, 0x8b, 0x8c, 0x0b, 0x09, 0x83, 0xe6, 0x15, 0x24, 0xe3, 0x10, 0xa9, -}; // g_number - -u8 const public_key[crypto::xr_dsa::public_key_length] = -{ - 0x0a, 0x0b, 0xe5, 0x02, 0x1c, 0xc6, 0x6c, 0xeb, 0xbd, 0xa2, 0xe6, 0xcd, 0x6d, 0x96, 0x64, 0xa9, 0x19, 0xe7, 0x81, - 0x94, 0x0c, 0xb2, 0x98, 0x5c, 0x7c, 0x3c, 0x68, 0xb6, 0xb6, 0x20, 0xa9, 0xab, 0x0f, 0xc0, 0xb9, 0x5a, 0xe5, 0xe7, - 0x35, 0x2e, 0xfd, 0xc2, 0x52, 0x64, 0x15, 0x98, 0x44, 0x88, 0x21, 0x4e, 0x8d, 0xf1, 0x04, 0x4f, 0xa5, 0x7a, 0x54, - 0x7f, 0xc5, 0xeb, 0x9b, 0x39, 0x4a, 0x36, 0x3a, 0x79, 0xf1, 0xce, 0xd2, 0xaf, 0x47, 0xe5, 0x26, 0x0f, 0x56, 0xe2, - 0x29, 0xd2, 0x60, 0x3d, 0x68, 0x23, 0xf1, 0x34, 0xea, 0xbf, 0x4e, 0x38, 0x66, 0x72, 0x0d, 0xf1, 0xc7, 0x33, 0x35, - 0xf7, 0xc5, 0xe0, 0x59, 0x57, 0x42, 0x36, 0x83, 0x20, 0xff, 0x14, 0x03, 0xea, 0x2f, 0x0b, 0x0c, 0xa6, 0x98, 0x11, - 0xd5, 0xb2, 0x96, 0x51, 0x6b, 0x08, 0x38, 0x98, 0x3a, 0xb6, 0x96, 0xa7, 0xad, 0xe3, -}; // public_key -} // namespace screenshots diff --git a/src/utils/mp_screenshots_info/screenshots_common.h b/src/utils/mp_screenshots_info/screenshots_common.h deleted file mode 100644 index 42090bbd884..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_common.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SCREENSHOTS_COMMON_INCLUDED -#define SCREENSHOTS_COMMON_INCLUDED - -#include "xrCore/Crypto/xr_dsa.h" - -namespace screenshots -{ -extern char const* ss_info_secion; -extern char const* ss_player_name_key; -extern char const* ss_player_digest_key; -// extern char const * ss_admin_name_key; -extern char const* ss_digital_sign_key; -extern char const* ss_creation_date; - -extern u8 const p_number[crypto::xr_dsa::public_key_length]; -extern u8 const q_number[crypto::xr_dsa::private_key_length]; -extern u8 const g_number[crypto::xr_dsa::public_key_length]; -extern u8 const public_key[crypto::xr_dsa::public_key_length]; -} // namespace screenshots - -#endif //#ifndef SCREENSHOTS_COMMON_INCLUDED diff --git a/src/utils/mp_screenshots_info/screenshots_reader.cpp b/src/utils/mp_screenshots_info/screenshots_reader.cpp deleted file mode 100644 index 610a6830965..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_reader.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "pch.h" -#include "screenshots_common.h" -#include "screenshots_reader.h" - -namespace screenshots -{ -sign_verifyer::sign_verifyer() : xr_dsa_verifyer(p_number, q_number, g_number, public_key) {} -sign_verifyer::~sign_verifyer() {} -static char* search_info_section(u8* buffer, size_t buffer_size) -{ - const size_t sstr_size = xr_strlen(ss_info_secion); - VERIFY(buffer_size >= sstr_size); - u8* rbegin = buffer + (buffer_size - sstr_size); - int r_size = static_cast(buffer_size - sstr_size); - do - { - if (!memcmp(rbegin, ss_info_secion, sstr_size)) - { - return static_cast((void*)rbegin); - } - --rbegin; - --r_size; - } while (r_size > 0); - return NULL; -} - -reader::reader(IReader* freader) -{ - m_info_section = NULL; - m_jpeg_data = NULL; - VERIFY(freader); - - const size_t file_size = freader->elapsed(); - VERIFY(file_size); - m_jpeg_data = static_cast(xr_malloc(file_size + 1)); - m_jpeg_data_size = file_size; - freader->r(m_jpeg_data, m_jpeg_data_size); - m_jpeg_data[file_size] = 0; - - char* tmp_info_begin = search_info_section(m_jpeg_data, m_jpeg_data_size); - - if (!tmp_info_begin) - { - Msg("Can't find info section"); - return; - } - --tmp_info_begin; //- '[' - m_info_size = xr_strlen(tmp_info_begin); - m_info_pos = static_cast((u8*)tmp_info_begin - m_jpeg_data); - - IReader tmp_reader(tmp_info_begin, m_info_size); - m_info_section = xr_new(&tmp_reader); -} - -reader::~reader() -{ - xr_free(m_jpeg_data); - xr_delete(m_info_section); -} - -shared_str const reader::player_name() -{ - VERIFY(is_valid()); - return m_info_section->r_string(ss_info_secion, ss_player_name_key); -} - -shared_str const reader::player_cdkey_digest() -{ - VERIFY(is_valid()); - return m_info_section->r_string(ss_info_secion, ss_player_digest_key); -} - -/*shared_str const reader::admin_name () -{ - VERIFY(is_valid()); - return m_info_section->r_string(ss_info_secion, ss_admin_name_key); -}*/ - -shared_str const reader::creation_date() -{ - VERIFY(is_valid()); - return m_info_section->r_string(ss_info_secion, ss_creation_date); -} - -bool const reader::verify() -{ - VERIFY(is_valid()); - - shared_str const tmp_sign = m_info_section->r_string(ss_info_secion, ss_digital_sign_key); - - char* jpeg_info_start = static_cast((void*)(m_jpeg_data + m_info_pos)); - jpeg_info_start[0] = 0; - - xr_strcat(jpeg_info_start, m_info_size, player_name().c_str()); - xr_strcat(jpeg_info_start, m_info_size, player_cdkey_digest().c_str()); - // xr_strcat(jpeg_info_start, m_info_size, admin_name().c_str()); - xr_strcat(jpeg_info_start, m_info_size, creation_date().c_str()); - - const size_t jpeg_info_size = xr_strlen(jpeg_info_start) + 1; // ending zero - const size_t jpeg_full_size = m_info_pos + jpeg_info_size; - - return m_verifyer.verify(m_jpeg_data, jpeg_full_size, tmp_sign).has_value(); -} - -} // namespace screenshots diff --git a/src/utils/mp_screenshots_info/screenshots_reader.h b/src/utils/mp_screenshots_info/screenshots_reader.h deleted file mode 100644 index 58020c117bb..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_reader.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SCREENSHOT_READER_INCLUDED -#define SCREENSHOT_READER_INCLUDED - -#include "xrCore/Crypto/xr_dsa_verifyer.h" - -namespace screenshots -{ -class sign_verifyer : public xr_dsa_verifyer -{ -public: - sign_verifyer(); - ~sign_verifyer(); -}; - -class reader -{ -public: - reader(IReader* freader); - ~reader(); - - shared_str const player_name(); - shared_str const player_cdkey_digest(); - // shared_str const admin_name (); - shared_str const creation_date(); - - bool const verify(); - bool const is_valid() const { return m_info_section != NULL; }; -private: - reader() = default; - u8* m_jpeg_data; - size_t m_jpeg_data_size; - - size_t m_info_pos; - size_t m_info_size; - - CInifile* m_info_section; - sign_verifyer m_verifyer; - -}; // class reader - -} // namespace screenshots - -#endif //#ifndef SCREENSHOT_READER_INCLUDED diff --git a/src/utils/mp_screenshots_info/screenshots_writer.cpp b/src/utils/mp_screenshots_info/screenshots_writer.cpp deleted file mode 100644 index c4ec5403610..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_writer.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "pch.h" -#include "screenshots_writer.h" -#include "screenshots_common.h" - -namespace screenshots -{ -writer::writer(u8* jpeg_data, u32 jpeg_size, u32 jpeg_buffer_size) : m_info_data(NULL, FALSE, FALSE, FALSE) -{ - VERIFY(jpeg_buffer_size - jpeg_size >= info_max_size); - m_buffer = jpeg_data; - m_buffer_size = jpeg_buffer_size; - m_buffer_info_pos = jpeg_size; -} - -writer::~writer() {} - -void writer::set_player_name(shared_str const& pname) -{ - m_info_data.w_string(ss_info_secion, ss_player_name_key, pname.c_str()); -} -void writer::set_player_cdkey_digest(shared_str const& cdkeydigest) -{ - m_info_data.w_string(ss_info_secion, ss_player_digest_key, cdkeydigest.c_str()); -} -/*void writer::set_admin_name (shared_str const & admin_name) -{ - m_info_data.w_string(ss_info_secion, ss_admin_name_key, admin_name.c_str()); -}*/ - -static char const* current_time(string64& dest_time) -{ - time_t tmp_curr_time; - - dest_time[0] = 0; - _time64(&tmp_curr_time); - tm* tmp_tm = _localtime64(&tmp_curr_time); - - xr_sprintf(dest_time, sizeof(dest_time), "%02d.%02d.%d_%02d:%02d:%02d", tmp_tm->tm_mday, tmp_tm->tm_mon + 1, - tmp_tm->tm_year + 1900, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec); - return dest_time; -} - -u32 const writer::write_info(crypto::yielder_t* yielder) -{ - string64 time_string; - m_info_data.w_string(ss_info_secion, ss_creation_date, current_time(time_string)); - - char* info_start = static_cast((void*)(m_buffer + m_buffer_info_pos)); - - info_start[0] = 0; - xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_player_name_key)); - xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_player_digest_key)); - // xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_admin_name_key)); - xr_strcat(info_start, info_max_size, time_string); - - u32 info_size = xr_strlen(info_start) + 1; - u32 jpeg_data_size = m_buffer_info_pos + info_size; - - shared_str tmp_sign_res; - if (yielder && *yielder) - { - tmp_sign_res = m_signer.sign_mt(m_buffer, jpeg_data_size, *yielder); - } - else - { - tmp_sign_res = m_signer.sign(m_buffer, jpeg_data_size); - } - - m_info_data.w_string(ss_info_secion, ss_digital_sign_key, tmp_sign_res.c_str()); - - CMemoryWriter tmp_writer; - m_info_data.save_as(tmp_writer); - CopyMemory(m_buffer + m_buffer_info_pos, tmp_writer.pointer(), tmp_writer.size()); - - return m_buffer_info_pos + tmp_writer.size(); -} - -// signer - -signer::signer() : xr_dsa_signer(p_number, q_number, g_number) { feel_private_dsa_key(); } -signer::~signer() {} -void signer::feel_private_dsa_key() -{ - // Private key: - m_private_key.m_value[0] = 0xa6; - m_private_key.m_value[1] = 0x07; - m_private_key.m_value[2] = 0x3b; - m_private_key.m_value[3] = 0x2b; - m_private_key.m_value[4] = 0x1d; - m_private_key.m_value[5] = 0xfe; - m_private_key.m_value[6] = 0xdf; - m_private_key.m_value[7] = 0x48; - m_private_key.m_value[8] = 0x36; - m_private_key.m_value[9] = 0x8e; - m_private_key.m_value[10] = 0xad; - m_private_key.m_value[11] = 0x95; - m_private_key.m_value[12] = 0xf8; - m_private_key.m_value[13] = 0x4e; - m_private_key.m_value[14] = 0x9a; - m_private_key.m_value[15] = 0xd0; - m_private_key.m_value[16] = 0x55; - m_private_key.m_value[17] = 0xbb; - m_private_key.m_value[18] = 0xa2; - m_private_key.m_value[19] = 0x3a; -} -} diff --git a/src/utils/mp_screenshots_info/screenshots_writer.h b/src/utils/mp_screenshots_info/screenshots_writer.h deleted file mode 100644 index 2d8f83bfafc..00000000000 --- a/src/utils/mp_screenshots_info/screenshots_writer.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef SCREENSHOT_WRITER_INCLUDED -#define SCREENSHOT_WRITER_INCLUDED - -#include "xrCore/Crypto/xr_dsa_signer.h" - -namespace screenshots -{ -class signer : public xr_dsa_signer -{ -public: - signer(); - ~signer(); - -private: - void feel_private_dsa_key(); -}; - -class writer -{ -public: - writer(u8* jpeg_data, u32 jpeg_size, u32 jpeg_buffer_size); - ~writer(); - - static u32 const info_max_size = 1024; - void set_player_name(shared_str const& pname); - void set_player_cdkey_digest(shared_str const& cdkeydigest); - // void set_admin_name (shared_str const & admin_name); - - u32 const write_info(crypto::yielder_t* yielder = NULL); - -private: - writer() : m_info_data(NULL, FALSE, FALSE, FALSE){}; - - u8* m_buffer; - u32 m_buffer_size; - u32 m_buffer_info_pos; - - CInifile m_info_data; - signer m_signer; -}; // class writer - -} // namespace screenshots - -#endif //#ifndef SCREENSHOT_WRITER_INCLUDED diff --git a/src/xrEngine/Render.h b/src/xrEngine/Render.h index 13e7f4764f9..25f72e19d67 100644 --- a/src/xrEngine/Render.h +++ b/src/xrEngine/Render.h @@ -364,8 +364,6 @@ class ENGINE_API IRender virtual void AfterWorldRender() = 0; //--#SM+#-- После рендеринга мира (до UI) virtual void Screenshot(ScreenshotMode mode = SM_NORMAL, pcstr name = nullptr) = 0; - virtual void ScreenshotAsyncBegin() = 0; - virtual void ScreenshotAsyncEnd(CMemoryWriter& memory_writer) = 0; // Render mode virtual void rmNear(CBackend& cmd_list) = 0; diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 355aa83eae5..6d7ca9b4ae0 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -1128,14 +1128,8 @@ target_sources(xrGame PRIVATE ScientificOutfit.h Scope.cpp Scope.h - screenshot_manager.cpp - screenshot_manager.h - screenshots_common.cpp - screenshots_common.h screenshot_server.cpp screenshot_server.h - screenshots_writer.cpp - screenshots_writer.h script_abstract_action.h script_action_condition.h script_action_condition_inline.h diff --git a/src/xrGame/game_cl_mp.cpp b/src/xrGame/game_cl_mp.cpp index 73c823b3180..5bdbf64fb82 100644 --- a/src/xrGame/game_cl_mp.cpp +++ b/src/xrGame/game_cl_mp.cpp @@ -432,9 +432,7 @@ void game_cl_mp::TranslateGameMessage(u32 msg, NET_Packet& P) clientdata_event_t etype = static_cast(P.r_u8()); if (etype == e_screenshot_request) { - screenshot_manager::complete_callback_t compl_cb = - fastdelegate::MakeDelegate(this, &game_cl_mp::SendCollectedData); - ss_manager.make_screenshot(compl_cb); + // XXX: removed, should be reimplemented } else if (etype == e_configs_request) { @@ -1868,7 +1866,8 @@ void game_cl_mp::draw_all_active_binder_states() m_detected_cheaters.end()); } -void game_cl_mp::draw_downloads(bool draw) { ss_manager.set_draw_downloads(draw); } +void game_cl_mp::draw_downloads(bool /*draw*/) {} + void game_cl_mp::extract_server_info(u8* data_ptr, u32 data_size) { UIGameMP* tmp_ui_mp_game = smart_cast(m_game_ui_custom); diff --git a/src/xrGame/game_cl_mp.h b/src/xrGame/game_cl_mp.h index 3db08694e58..e68c9ae2a00 100644 --- a/src/xrGame/game_cl_mp.h +++ b/src/xrGame/game_cl_mp.h @@ -4,7 +4,6 @@ #include "xrUICore/ui_defs.h" #include "Spectator.h" #include "file_transfer.h" -#include "screenshot_manager.h" #include "configs_dumper.h" #include "configs_dump_verifyer.h" #include "screenshot_server.h" @@ -255,7 +254,6 @@ class game_cl_mp : public game_cl_GameState virtual void OnConnected(); virtual LPCSTR GetGameScore(string32& score_dest) { return score_dest; } - screenshot_manager ss_manager; mp_anticheat::configs_dumper cd_manager; mp_anticheat::configs_verifyer cd_verifyer; diff --git a/src/xrGame/screenshot_manager.cpp b/src/xrGame/screenshot_manager.cpp deleted file mode 100644 index 61d8580564e..00000000000 --- a/src/xrGame/screenshot_manager.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#include "StdAfx.h" -#include "screenshot_manager.h" -#include "Level.h" -#include "game_cl_mp.h" -#include "xrCore/Compression/ppmd_compressor.h" -#include "screenshots_writer.h" - -#if __has_include("ximage.h") -# include "ximage.h" -# include "xmemfile.h" -#endif - -screenshot_manager::screenshot_manager() -{ - m_state = 0; - - m_jpeg_buffer = NULL; - m_jpeg_buffer_capacity = 0; - - m_buffer_for_compress = NULL; - m_buffer_for_compress_capacity = 0; - - m_make_start_event = NULL; - m_make_done_event = NULL; -} -screenshot_manager::~screenshot_manager() -{ - if (is_active()) - { - Engine.Sheduler.Unregister(this); - m_state = 0; - } - xr_free(m_jpeg_buffer); - xr_free(m_buffer_for_compress); - if (m_make_start_event) - { -#ifdef XR_PLATFORM_WINDOWS // FIXME!!! - SetEvent(m_make_start_event); - WaitForSingleObject(m_make_done_event, INFINITE); // thread stoped - CloseHandle(m_make_done_event); - CloseHandle(m_make_start_event); -#endif - } -} - -void screenshot_manager::realloc_jpeg_buffer(u32 new_size) -{ - if (m_jpeg_buffer_capacity >= new_size) - return; - void* new_buffer = xr_realloc(m_jpeg_buffer, new_size); - m_jpeg_buffer = static_cast(new_buffer); - m_jpeg_buffer_capacity = new_size; -} - -#define RESULT_PIXEL_SIZE 3 -#define STRING_SIZE (RESULT_PIXEL_SIZE * RESULT_WIDTH) -// method get the pixel -void screenshot_manager::prepare_image() -{ -#pragma pack(push, 1) - struct rgb24color - { - u8 r, g, b; - }; -#pragma pack(pop) - typedef rgb24color rgb24map[RESULT_HEIGHT][RESULT_WIDTH]; - u32* sizes = reinterpret_cast(m_result_writer.pointer()); - u32* width = sizes; // first dword is width - u32* height = ++sizes; // second dword is height - u32* rgba = reinterpret_cast(++sizes); // then RGBA data - rgb24map* dest = reinterpret_cast(rgba); // WARNING sorce and dest stored in one place ... - - float dx = float(*width) / RESULT_WIDTH; - float dy = float(*height) / RESULT_HEIGHT; - - // removin alfa byte with resize(first pixel) - for (int y = 0; y < RESULT_HEIGHT; ++y) - { - for (int x = 0; x < RESULT_WIDTH; ++x) - { - int rgba_index = (u32(dy * y) * (*width)) + u32(dx * x); - (*dest)[y][x].r = *reinterpret_cast(&rgba[rgba_index]); - (*dest)[y][x].g = *(reinterpret_cast(&rgba[rgba_index]) + 1); - (*dest)[y][x].b = *(reinterpret_cast(&rgba[rgba_index]) + 2); - } - } - *width = RESULT_WIDTH; - *height = RESULT_HEIGHT; -} - -void screenshot_manager::make_jpeg_file() -{ -#if __has_include("ximage.h") - u32* sizes = reinterpret_cast(m_result_writer.pointer()); - u32 width = *sizes; - u32 height = *(++sizes); - u8* rgb24data = reinterpret_cast(m_result_writer.pointer() + 2 * sizeof(u32)); - - CxImage jpg_image; - - jpg_image.CreateFromArray(rgb24data, - width, // width - height, // height - 24, width * 3, true); - - jpg_image.SetJpegQuality(30); - - realloc_jpeg_buffer(m_result_writer.size() + screenshots::writer::info_max_size); - - CxMemFile tmp_mem_file(m_jpeg_buffer, m_jpeg_buffer_capacity); - jpg_image.Encode(&tmp_mem_file, CXIMAGE_FORMAT_JPG); - - m_jpeg_buffer_size = static_cast(tmp_mem_file.Tell()); - -# ifdef DEBUG - Msg("* JPEG encoded to %d bytes", m_jpeg_buffer_size); -# endif -#else - m_jpeg_buffer = nullptr; - m_jpeg_buffer_size = 0; - VERIFY(!"Not implemented."); -#endif -} - -void screenshot_manager::sign_jpeg_file() -{ - screenshots::writer tmp_writer(m_jpeg_buffer, m_jpeg_buffer_size, m_jpeg_buffer_capacity); - game_cl_mp* tmp_cl_game = smart_cast(&Game()); - tmp_writer.set_player_name(tmp_cl_game->local_player->getName()); - shared_str tmp_cdkey_digest = Level().get_cdkey_digest(); - if (tmp_cdkey_digest.size() == 0) - tmp_cdkey_digest = "null"; - tmp_writer.set_player_cdkey_digest(tmp_cdkey_digest); - m_jpeg_buffer_size = tmp_writer.write_info(); -} - -void screenshot_manager::shedule_Update(u32 dt) -{ - R_ASSERT(m_state & making_screenshot || m_state & drawing_download_states); - bool is_make_in_progress = is_making_screenshot(); - if (is_make_in_progress && (m_defered_ssframe_counter == 0)) - { - if (!m_make_done_event) - { - prepare_image(); - make_jpeg_file(); - sign_jpeg_file(); - compress_image(); - m_complete_callback(m_buffer_for_compress, m_buffer_for_compress_size, m_jpeg_buffer_size); - m_state &= ~making_screenshot; - } - else - { -#ifdef XR_PLATFORM_WINDOWS // FIXME!!! - u32 thread_result = WaitForSingleObject(m_make_done_event, 0); - R_ASSERT((thread_result != WAIT_ABANDONED) && (thread_result != WAIT_FAILED)); - if (thread_result == WAIT_OBJECT_0) - { - m_complete_callback(m_buffer_for_compress, m_buffer_for_compress_size, m_jpeg_buffer_size); - m_state &= ~making_screenshot; - } -#endif - } - if (!is_making_screenshot() && !is_drawing_downloads()) - { - Engine.Sheduler.Unregister(this); - } - } - else if (is_make_in_progress && (--m_defered_ssframe_counter == 0)) - { - GEnv.Render->ScreenshotAsyncEnd(m_result_writer); - /* //--------- - #ifdef DEBUG - if (!m_result_writer.size()) - { - string_path screen_shot_path; - FS.update_path(screen_shot_path, "$screenshots$", "tmp_response.dds"); - IReader* tmp_reader = FS.r_open(screen_shot_path); - if (tmp_reader) - { - m_result_writer.w(tmp_reader->pointer(), tmp_reader->length()); - FS.r_close(tmp_reader); - } - } - #endif //#ifdef DEBUG*/ -#ifdef XR_PLATFORM_WINDOWS // FIXME!!! - ULONG_PTR process_affinity_mask, tmp_dword; - GetProcessAffinityMask(GetCurrentProcess(), &process_affinity_mask, &tmp_dword); - process_screenshot(btwCount1(static_cast(process_affinity_mask)) == 1); -#endif - } - if (is_drawing_downloads()) - { - static_cast(Level().game)->draw_all_active_binder_states(); - } -} - -void screenshot_manager::make_screenshot(complete_callback_t cb) -{ - if (is_making_screenshot()) - { -#ifdef DEBUG - Msg("! ERROR: CL: screenshot making in progress..."); -#endif - return; - } - if (m_result_writer.size()) - m_result_writer.clear(); - - m_complete_callback = cb; - if (!is_drawing_downloads()) - { - Engine.Sheduler.Register(this, TRUE); - } - m_state |= making_screenshot; - m_defered_ssframe_counter = defer_framescount; - - GEnv.Render->ScreenshotAsyncBegin(); -} - -void screenshot_manager::set_draw_downloads(bool draw) -{ - if (draw) - { - if (!is_active()) - { - Engine.Sheduler.Register(this, TRUE); - } - m_state |= drawing_download_states; - } - else - { - if (!is_making_screenshot() && is_drawing_downloads()) - { - Engine.Sheduler.Unregister(this); - } - m_state &= ~drawing_download_states; - } -} - -void screenshot_manager::process_screenshot(bool singlecore) -{ -#ifdef XR_PLATFORM_WINDOWS // FIXME!!! - if (m_make_start_event) - { - SetEvent(m_make_start_event); - return; - } - m_make_start_event = CreateEvent(NULL, FALSE, TRUE, NULL); - m_make_done_event = CreateEvent(NULL, FALSE, FALSE, NULL); - - Threading::SpawnThread("screenshot_maker", [this] - { - u32 wait_result = WaitForSingleObject(m_make_start_event, INFINITE); - while ((wait_result != WAIT_ABANDONED) || (wait_result != WAIT_FAILED)) - { - if (!is_active()) - break; - timer_begin("preparing image"); - prepare_image(); - timer_end(); - timer_begin("making jpeg"); - make_jpeg_file(); - timer_end(); - timer_begin("signing jpeg data"); - sign_jpeg_file(); - timer_end(); - timer_begin("compressing_image"); - compress_image(); - timer_end(); - SetEvent(m_make_done_event); - wait_result = WaitForSingleObject(m_make_start_event, INFINITE); - } - SetEvent(m_make_done_event); - - }); -#endif -} -void screenshot_manager::jpeg_compress_cb(long progress) -{ - /*#ifdef DEBUG - Msg("* JPEG encoding progress : %d%%", progress); - #endif*/ - if (progress % 5 == 0) - { - if (!SwitchToThread()) - Sleep(10); - } -} - -void screenshot_manager::realloc_compress_buffer(u32 need_size) -{ - if (m_buffer_for_compress && (need_size <= m_buffer_for_compress_capacity)) - return; -#ifdef DEBUG - Msg("* reallocing compression buffer."); -#endif - m_buffer_for_compress_capacity = need_size * 2; - void* new_buffer = xr_realloc(m_buffer_for_compress, m_buffer_for_compress_capacity); - m_buffer_for_compress = static_cast(new_buffer); -} - -void screenshot_manager::compress_image() -{ - realloc_compress_buffer(m_jpeg_buffer_size); - - m_buffer_for_compress_size = - ppmd_compress(m_buffer_for_compress, m_buffer_for_compress_capacity, m_jpeg_buffer, m_jpeg_buffer_size); -} - -#ifdef DEBUG - -void screenshot_manager::timer_begin(LPCSTR comment) -{ - m_timer_comment = comment; - m_debug_timer.Start(); -} - -void screenshot_manager::timer_end() { Msg("* %s : %u ms", m_timer_comment.c_str(), m_debug_timer.GetElapsed_ms()); } -#endif diff --git a/src/xrGame/screenshot_manager.h b/src/xrGame/screenshot_manager.h deleted file mode 100644 index f53b2368d07..00000000000 --- a/src/xrGame/screenshot_manager.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#ifndef SCREENSHOT_MANAGER_FOR_MP -#define SCREENSHOT_MANAGER_FOR_MP -#include "xrEngine/ISheduled.h" - -#define RESULT_WIDTH 640 -#define RESULT_HEIGHT 480 - -class screenshot_manager : public ScheduledBase -{ -public: - enum ss_manager_state_mask_t - { - making_screenshot = 0x01, - drawing_download_states = 0x02 - }; - typedef fastdelegate::FastDelegate3 complete_callback_t; - - screenshot_manager(); - virtual ~screenshot_manager(); - - virtual float shedule_Scale() const { return 1.0f; }; - virtual void shedule_Update(u32 dt); - virtual shared_str shedule_Name() const { return shared_str("screenshot_manager"); }; - virtual bool shedule_Needed() { return true; }; - void make_screenshot(complete_callback_t cb); - void set_draw_downloads(bool draw); - void jpeg_compress_cb(long progress); - -private: - CMemoryWriter m_result_writer; - void make_jpeg_file(); - void sign_jpeg_file(); - void prepare_image(); - void compress_image(); - u32 m_state; - - void realloc_compress_buffer(u32 need_size); - u8* m_buffer_for_compress; - u32 m_buffer_for_compress_size; - u32 m_buffer_for_compress_capacity; - - void realloc_jpeg_buffer(u32 new_size); - u8* m_jpeg_buffer; - u32 m_jpeg_buffer_size; - u32 m_jpeg_buffer_capacity; - - u32 m_defered_ssframe_counter; - static u32 const defer_framescount = 30; // count of frames to defer, must be > 1 - - inline bool is_making_screenshot() const { return !!(m_state & making_screenshot); }; - inline bool is_drawing_downloads() const { return !!(m_state & drawing_download_states); }; - inline bool is_active() const { return (is_making_screenshot() || is_drawing_downloads()); }; - complete_callback_t m_complete_callback; - - void process_screenshot(bool in_other_thread); - HANDLE m_make_start_event; - HANDLE m_make_done_event; - -#ifdef DEBUG - CTimer m_debug_timer; - u32 m_start_time; - shared_str m_timer_comment; - void timer_begin(LPCSTR comment); - void timer_end(); -#else - inline void timer_begin(LPCSTR comment) {} - inline void timer_end() {} -#endif -}; // class screenshot_manager - -#endif //#ifndef SCREENSHOT_MANAGER_FOR_MP diff --git a/src/xrGame/screenshots_common.cpp b/src/xrGame/screenshots_common.cpp deleted file mode 100644 index 0e741795db7..00000000000 --- a/src/xrGame/screenshots_common.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "StdAfx.h" -#include "screenshots_common.h" - -namespace screenshots -{ -// DSA params -u8 const p_number[crypto::xr_dsa::public_key_length] = { - 0xe0, 0xc7, 0x56, 0xaa, 0x69, 0xc8, 0x34, 0x75, 0xe2, 0x41, 0x5d, 0x33, 0xd2, 0x4e, 0x91, 0x09, 0xd9, 0x65, 0xbb, - 0x4c, 0x1d, 0xb9, 0xb8, 0x07, 0x9b, 0x05, 0x32, 0xa3, 0x72, 0x6e, 0x76, 0x24, 0x04, 0xb1, 0x4f, 0x3b, 0x58, 0xfa, - 0x05, 0x4c, 0x54, 0x95, 0x5d, 0xc3, 0x2b, 0xdd, 0x13, 0xe9, 0xd4, 0xe0, 0xa8, 0x8c, 0xd1, 0x9d, 0x11, 0xa1, 0x31, - 0x1b, 0x00, 0xa2, 0x82, 0xb7, 0xc9, 0x46, 0x01, 0x22, 0x9d, 0xa7, 0xb0, 0xe1, 0x4a, 0x10, 0x39, 0xd5, 0x92, 0xd4, - 0xcd, 0x02, 0x37, 0xa0, 0xda, 0x6a, 0xfe, 0x02, 0x82, 0x54, 0x9b, 0x5d, 0xcd, 0x71, 0xbf, 0x69, 0xc8, 0x77, 0x4c, - 0x7e, 0x5e, 0x4e, 0x7a, 0xff, 0x0f, 0x12, 0x62, 0xd5, 0xf5, 0xca, 0x0a, 0x76, 0x26, 0x6d, 0x16, 0x0b, 0x4f, 0x09, - 0x3b, 0x41, 0x09, 0x80, 0xff, 0x65, 0x15, 0xce, 0x29, 0x0f, 0x04, 0x45, 0xb0, 0xb1, -}; // p_number -u8 const q_number[crypto::xr_dsa::private_key_length] = { - 0xfb, 0xe4, 0x9a, 0x95, 0x31, 0x49, 0xcb, 0xda, 0xf1, 0x91, 0x36, 0x82, 0xa8, 0x80, 0xfd, 0xcb, 0x4e, 0x38, 0x85, - 0x45, -}; // q_number -u8 const g_number[crypto::xr_dsa::public_key_length] = { - 0xdc, 0x38, 0x96, 0xb4, 0x81, 0xf2, 0x2d, 0x60, 0x20, 0x7e, 0x9a, 0xe5, 0x74, 0x45, 0x7f, 0xa4, 0x9d, 0x71, 0xb8, - 0x94, 0x0a, 0xc5, 0xfb, 0x50, 0x71, 0xd9, 0xae, 0xb4, 0x74, 0xeb, 0x09, 0x93, 0x41, 0xd3, 0x70, 0x00, 0x60, 0x4b, - 0x0e, 0x95, 0xb8, 0x31, 0x3d, 0x50, 0x84, 0x60, 0x6e, 0x16, 0xba, 0x7b, 0xc4, 0x8e, 0x25, 0xe0, 0x39, 0x10, 0x7e, - 0xb9, 0x2a, 0xaf, 0x4b, 0x40, 0xd7, 0xc4, 0xa0, 0x2a, 0x19, 0xfe, 0x1f, 0x77, 0x04, 0x8f, 0x73, 0xe1, 0x6e, 0xfe, - 0x8f, 0xbc, 0xcc, 0x8b, 0xdd, 0x12, 0x21, 0x86, 0xa6, 0x4d, 0x90, 0x9a, 0xbd, 0xfe, 0x8a, 0x05, 0x39, 0xad, 0xb4, - 0x45, 0xf6, 0xf9, 0x0f, 0xe5, 0x91, 0x5c, 0x2c, 0x19, 0xa0, 0xf1, 0x2e, 0x06, 0x02, 0x92, 0x68, 0xaa, 0xbc, 0x7c, - 0xf4, 0x4c, 0x85, 0x8b, 0x8c, 0x0b, 0x09, 0x83, 0xe6, 0x15, 0x24, 0xe3, 0x10, 0xa9, -}; // g_number -u8 const public_key[crypto::xr_dsa::public_key_length] = { - 0x0a, 0x0b, 0xe5, 0x02, 0x1c, 0xc6, 0x6c, 0xeb, 0xbd, 0xa2, 0xe6, 0xcd, 0x6d, 0x96, 0x64, 0xa9, 0x19, 0xe7, 0x81, - 0x94, 0x0c, 0xb2, 0x98, 0x5c, 0x7c, 0x3c, 0x68, 0xb6, 0xb6, 0x20, 0xa9, 0xab, 0x0f, 0xc0, 0xb9, 0x5a, 0xe5, 0xe7, - 0x35, 0x2e, 0xfd, 0xc2, 0x52, 0x64, 0x15, 0x98, 0x44, 0x88, 0x21, 0x4e, 0x8d, 0xf1, 0x04, 0x4f, 0xa5, 0x7a, 0x54, - 0x7f, 0xc5, 0xeb, 0x9b, 0x39, 0x4a, 0x36, 0x3a, 0x79, 0xf1, 0xce, 0xd2, 0xaf, 0x47, 0xe5, 0x26, 0x0f, 0x56, 0xe2, - 0x29, 0xd2, 0x60, 0x3d, 0x68, 0x23, 0xf1, 0x34, 0xea, 0xbf, 0x4e, 0x38, 0x66, 0x72, 0x0d, 0xf1, 0xc7, 0x33, 0x35, - 0xf7, 0xc5, 0xe0, 0x59, 0x57, 0x42, 0x36, 0x83, 0x20, 0xff, 0x14, 0x03, 0xea, 0x2f, 0x0b, 0x0c, 0xa6, 0x98, 0x11, - 0xd5, 0xb2, 0x96, 0x51, 0x6b, 0x08, 0x38, 0x98, 0x3a, 0xb6, 0x96, 0xa7, 0xad, 0xe3, -}; // public_key - -} // namespace screenshots diff --git a/src/xrGame/screenshots_common.h b/src/xrGame/screenshots_common.h deleted file mode 100644 index 56032871a8e..00000000000 --- a/src/xrGame/screenshots_common.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SCREENSHOTS_COMMON_INCLUDED -#define SCREENSHOTS_COMMON_INCLUDED - -#include "xrCore/Crypto/xr_dsa.h" - -namespace screenshots -{ -extern u8 const p_number[crypto::xr_dsa::public_key_length]; -extern u8 const q_number[crypto::xr_dsa::private_key_length]; -extern u8 const g_number[crypto::xr_dsa::public_key_length]; -extern u8 const public_key[crypto::xr_dsa::public_key_length]; - -} // namespace screenshots - -#endif //#ifndef SCREENSHOTS_COMMON_INCLUDED diff --git a/src/xrGame/screenshots_writer.cpp b/src/xrGame/screenshots_writer.cpp deleted file mode 100644 index a0b72709979..00000000000 --- a/src/xrGame/screenshots_writer.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "StdAfx.h" -#include "screenshots_writer.h" -#include "screenshots_common.h" - -namespace screenshots -{ -writer::writer(u8* jpeg_data, u32 jpeg_size, u32 jpeg_buffer_size) : m_info_data(NULL, FALSE, FALSE, FALSE) -{ - VERIFY(jpeg_buffer_size - jpeg_size >= info_max_size); - m_buffer = jpeg_data; - m_buffer_size = jpeg_buffer_size; - m_buffer_info_pos = jpeg_size; -} - -writer::~writer() {} -char const* ss_info_secion = "screenshot_info"; -char const* ss_player_name_key = "player_name"; -char const* ss_player_digest_key = "player_digest"; -char const* ss_admin_name_key = "admin_name"; -char const* ss_digital_sign_key = "digital_sign"; -char const* ss_creation_date = "creation_date"; - -void writer::set_player_name(shared_str const& pname) -{ - m_info_data.w_string(ss_info_secion, ss_player_name_key, pname.c_str()); -} -void writer::set_player_cdkey_digest(shared_str const& cdkeydigest) -{ - m_info_data.w_string(ss_info_secion, ss_player_digest_key, cdkeydigest.c_str()); -} -/*void writer::set_admin_name (shared_str const & admin_name) -{ - m_info_data.w_string(ss_info_secion, ss_admin_name_key, admin_name.c_str()); -}*/ - -u32 writer::write_info(crypto::yielder_t* yielder) -{ - string64 time_string; - m_info_data.w_string(ss_info_secion, ss_creation_date, current_time(time_string)); - - char* info_start = static_cast((void*)(m_buffer + m_buffer_info_pos)); - - info_start[0] = 0; - xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_player_name_key)); - xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_player_digest_key)); - // xr_strcat(info_start, info_max_size, m_info_data.r_string(ss_info_secion, ss_admin_name_key)); - xr_strcat(info_start, info_max_size, time_string); - - u32 info_size = xr_strlen(info_start) + 1; - u32 jpeg_data_size = m_buffer_info_pos + info_size; - - shared_str tmp_sign_res; - if (yielder && *yielder) - { - tmp_sign_res = m_signer.sign_mt(m_buffer, jpeg_data_size, *yielder); - } - else - { - tmp_sign_res = m_signer.sign(m_buffer, jpeg_data_size); - } - - m_info_data.w_string(ss_info_secion, ss_digital_sign_key, tmp_sign_res.c_str()); - - CMemoryWriter tmp_writer; - m_info_data.save_as(tmp_writer); - CopyMemory(m_buffer + m_buffer_info_pos, tmp_writer.pointer(), tmp_writer.size()); - - return m_buffer_info_pos + tmp_writer.size(); -} - -// signer - -signer::signer() : xr_dsa_signer(p_number, q_number, g_number) { feel_private_dsa_key(); } -signer::~signer() {} -void signer::feel_private_dsa_key() -{ - // Private key: - m_private_key.m_value[0] = 0xa6; - m_private_key.m_value[1] = 0x07; - m_private_key.m_value[2] = 0x3b; - m_private_key.m_value[3] = 0x2b; - m_private_key.m_value[4] = 0x1d; - m_private_key.m_value[5] = 0xfe; - m_private_key.m_value[6] = 0xdf; - m_private_key.m_value[7] = 0x48; - m_private_key.m_value[8] = 0x36; - m_private_key.m_value[9] = 0x8e; - m_private_key.m_value[10] = 0xad; - m_private_key.m_value[11] = 0x95; - m_private_key.m_value[12] = 0xf8; - m_private_key.m_value[13] = 0x4e; - m_private_key.m_value[14] = 0x9a; - m_private_key.m_value[15] = 0xd0; - m_private_key.m_value[16] = 0x55; - m_private_key.m_value[17] = 0xbb; - m_private_key.m_value[18] = 0xa2; - m_private_key.m_value[19] = 0x3a; -} -} diff --git a/src/xrGame/screenshots_writer.h b/src/xrGame/screenshots_writer.h deleted file mode 100644 index 44ce3534d3a..00000000000 --- a/src/xrGame/screenshots_writer.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef SCREENSHOT_WRITER_INCLUDED -#define SCREENSHOT_WRITER_INCLUDED - -#include "xrCore/Crypto/xr_dsa_signer.h" - -namespace screenshots -{ -class signer : public xr_dsa_signer -{ -public: - signer(); - ~signer(); - -private: - void feel_private_dsa_key(); -}; - -extern char const* ss_info_secion; -extern char const* ss_player_name_key; -extern char const* ss_player_digest_key; -// extern char const * ss_admin_name_key; -extern char const* ss_digital_sign_key; -extern char const* ss_creation_date; - -class writer -{ -public: - writer(u8* jpeg_data, u32 jpeg_size, u32 jpeg_buffer_size); - ~writer(); - - static u32 const info_max_size = 1024; - void set_player_name(shared_str const& pname); - void set_player_cdkey_digest(shared_str const& cdkeydigest); - // void set_admin_name (shared_str const & admin_name); - - u32 write_info(crypto::yielder_t* yielder = NULL); - -private: - writer() : m_info_data(NULL, FALSE, FALSE, FALSE){}; - - u8* m_buffer; - u32 m_buffer_size; - u32 m_buffer_info_pos; - - CInifile m_info_data; - signer m_signer; -}; // class writer - -} // namespace screenshots - -#endif //#ifndef SCREENSHOT_WRITER_INCLUDED diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index 4117babe5e1..7ed3020f2df 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -1038,9 +1038,6 @@ - - - @@ -2720,9 +2717,6 @@ pch_script.h $(IntDir)$(ProjectName)_script.pch - - - pch_script.h diff --git a/src/xrGame/xrGame.vcxproj.filters b/src/xrGame/xrGame.vcxproj.filters index 064a21b7c5e..541aba9c67d 100644 --- a/src/xrGame/xrGame.vcxproj.filters +++ b/src/xrGame/xrGame.vcxproj.filters @@ -1771,9 +1771,6 @@ {0d87a81d-98e6-455c-99bd-e046d405955e} - - {083893c7-5148-4c4f-8b0d-e28d55dc5ef7} - {05fd45d5-e228-4cf4-b0ba-95c70c241d32} @@ -5556,15 +5553,6 @@ Core\Server\Games\client\mp - - Core\Server\Games\client\mp\screenshots - - - Core\Server\Games\client\mp\screenshots - - - Core\Server\Games\client\mp\screenshots - Core\Server\Games\client\mp\anticheat @@ -8810,15 +8798,6 @@ Core\Server\Games\client\mp - - Core\Server\Games\client\mp\screenshots - - - Core\Server\Games\client\mp\screenshots - - - Core\Server\Games\client\mp\screenshots - Core\Server\Games\client\mp\anticheat diff --git a/src/xrGame/xrServer.cpp b/src/xrGame/xrServer.cpp index f7278340b6f..38f9a71c88d 100644 --- a/src/xrGame/xrServer.cpp +++ b/src/xrGame/xrServer.cpp @@ -1202,6 +1202,8 @@ void xrServer::KickCheaters() void xrServer::MakeScreenshot(ClientID const& admin_id, ClientID const& cheater_id) { + Log("~ Server screenshot request is not supported."); + return; if ((cheater_id == SV_Client->ID) && GEnv.isDedicatedServer) { return; From d781a386be1acabce62b28de3ba3a19912c46d77 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 15:57:15 +0500 Subject: [PATCH 377/497] Removed CxImage --- CMakeLists.txt | 3 - Externals/CMakeLists.txt | 5 - Externals/cximage/CMakeLists.txt | 52 - Externals/cximage/cximage.vcxproj | 72 -- Externals/cximage/cximage.vcxproj.filters | 86 -- Externals/cximage/license.txt | 48 - Externals/cximage/xfile.h | 79 -- Externals/cximage/ximacfg.cpp | 21 - Externals/cximage/ximacfg.h | 77 -- Externals/cximage/ximadef.h | 175 ---- Externals/cximage/ximaenc.cpp | 1008 -------------------- Externals/cximage/ximaexif.cpp | 878 ----------------- Externals/cximage/ximage.cpp | 537 ----------- Externals/cximage/ximage.h | 735 -------------- Externals/cximage/ximainfo.cpp | 929 ------------------ Externals/cximage/ximaint.cpp | 1056 --------------------- Externals/cximage/ximaiter.h | 253 ----- Externals/cximage/ximajpg.cpp | 524 ---------- Externals/cximage/ximajpg.h | 315 ------ Externals/cximage/ximalpha.cpp | 365 ------- Externals/cximage/ximalyr.cpp | 116 --- Externals/cximage/ximapal.cpp | 834 ---------------- Externals/cximage/ximasel.cpp | 697 -------------- Externals/cximage/ximath.cpp | 95 -- Externals/cximage/ximath.h | 39 - Externals/cximage/xiofile.cpp | 24 - Externals/cximage/xiofile.h | 115 --- Externals/cximage/xmemfile.cpp | 202 ---- Externals/cximage/xmemfile.h | 41 - misc/windows/xrbinup.cmd | 4 - src/engine.sln | 35 - src/xrGame/CMakeLists.txt | 2 - src/xrGame/xrGame.vcxproj | 5 +- 33 files changed, 1 insertion(+), 9426 deletions(-) delete mode 100644 Externals/cximage/CMakeLists.txt delete mode 100644 Externals/cximage/cximage.vcxproj delete mode 100644 Externals/cximage/cximage.vcxproj.filters delete mode 100644 Externals/cximage/license.txt delete mode 100644 Externals/cximage/xfile.h delete mode 100644 Externals/cximage/ximacfg.cpp delete mode 100644 Externals/cximage/ximacfg.h delete mode 100644 Externals/cximage/ximadef.h delete mode 100644 Externals/cximage/ximaenc.cpp delete mode 100644 Externals/cximage/ximaexif.cpp delete mode 100644 Externals/cximage/ximage.cpp delete mode 100644 Externals/cximage/ximage.h delete mode 100644 Externals/cximage/ximainfo.cpp delete mode 100644 Externals/cximage/ximaint.cpp delete mode 100644 Externals/cximage/ximaiter.h delete mode 100644 Externals/cximage/ximajpg.cpp delete mode 100644 Externals/cximage/ximajpg.h delete mode 100644 Externals/cximage/ximalpha.cpp delete mode 100644 Externals/cximage/ximalyr.cpp delete mode 100644 Externals/cximage/ximapal.cpp delete mode 100644 Externals/cximage/ximasel.cpp delete mode 100644 Externals/cximage/ximath.cpp delete mode 100644 Externals/cximage/ximath.h delete mode 100644 Externals/cximage/xiofile.cpp delete mode 100644 Externals/cximage/xiofile.h delete mode 100644 Externals/cximage/xmemfile.cpp delete mode 100644 Externals/cximage/xmemfile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 07d6ee477f9..750c006e7bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,9 +245,6 @@ if (NOT WIN32) find_package(GLEW REQUIRED) find_package(OpenAL REQUIRED) find_package(JPEG) - if (JPEG_FOUND) - set(USE_CXIMAGE TRUE) - endif() find_package(Ogg REQUIRED) find_package(Vorbis REQUIRED) find_package(Theora REQUIRED) diff --git a/Externals/CMakeLists.txt b/Externals/CMakeLists.txt index a634c9b4c70..2e9d979b018 100644 --- a/Externals/CMakeLists.txt +++ b/Externals/CMakeLists.txt @@ -6,11 +6,6 @@ endif() add_subdirectory(xrLuaFix) add_subdirectory(luabind) - -if (USE_CXIMAGE) - add_subdirectory(cximage) -endif() - add_subdirectory(GameSpy) add_subdirectory(OPCODE) add_subdirectory(ode) diff --git a/Externals/cximage/CMakeLists.txt b/Externals/cximage/CMakeLists.txt deleted file mode 100644 index 5d60d8345bc..00000000000 --- a/Externals/cximage/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -add_library(cximage STATIC) - -target_sources(cximage PRIVATE - xfile.h - ximacfg.cpp - ximacfg.h - ximadef.h - ximaenc.cpp - ximaexif.cpp - ximage.cpp - ximage.h - ximainfo.cpp - ximaint.cpp - ximaiter.h - ximajpg.cpp - ximajpg.h - ximalpha.cpp - ximalyr.cpp - ximapal.cpp - ximasel.cpp - ximath.cpp - ximath.h - xiofile.h - xiofile.cpp - xmemfile.cpp - xmemfile.h -) - -target_include_directories(cximage - PRIVATE - "${CMAKE_SOURCE_DIR}/src" -) - -target_link_libraries(cximage - PRIVATE - $<$:JPEG::JPEG> -) - -target_compile_definitions(cximage - PRIVATE - CXIMAGE_BUILD -) - -# XXX: Clang-9 internal error in function GetPixelColorInterpolated during optimization -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION MATCHES "9.0.0" OR CMAKE_CXX_COMPILER_VERSION MATCHES "10.0.0")) - set_property(SOURCE ximaint.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION TRUE) -endif() - -set_target_properties(cximage PROPERTIES - PREFIX "" - POSITION_INDEPENDENT_CODE ON -) diff --git a/Externals/cximage/cximage.vcxproj b/Externals/cximage/cximage.vcxproj deleted file mode 100644 index f928fbf03ff..00000000000 --- a/Externals/cximage/cximage.vcxproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - CxImage - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4} - - - - - - - StaticLibrary - - - - - - - - - - - - $(xrExternals);%(AdditionalIncludeDirectories) - JAS_WIN_MSVC_BUILD;CXIMAGE_BUILD;%(PreprocessorDefinitions) - false - 4100;4611;4702;%(DisableSpecificWarnings) - NotUsing - - - jpeg-static.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {a0f7d1fb-59a7-4717-a7e4-96f37e91998e} - - - - - - \ No newline at end of file diff --git a/Externals/cximage/cximage.vcxproj.filters b/Externals/cximage/cximage.vcxproj.filters deleted file mode 100644 index c933de1b2ca..00000000000 --- a/Externals/cximage/cximage.vcxproj.filters +++ /dev/null @@ -1,86 +0,0 @@ - - - - - {809204d4-54e2-4efc-8562-d4d26b493cb0} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {9ef7aa3b-52be-4021-835b-decbb0f3b1f9} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Externals/cximage/license.txt b/Externals/cximage/license.txt deleted file mode 100644 index 8cc0197bbfb..00000000000 --- a/Externals/cximage/license.txt +++ /dev/null @@ -1,48 +0,0 @@ -This copy of the CxImage notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file ximage.h that is -included in the CxImage distribution, the latter shall prevail. - -If you modify CxImage you may insert additional notices immediately following -this sentence. - --------------------------------------------------------------------------------- - -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - -CxImage version 6.0.0 02/Feb/2008 - -CxImage : Copyright (C) 2001 - 2008, Davide Pizzolato - -Original CImage and CImageIterator implementation are: -Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx) - -Covered code is provided under this license on an "as is" basis, without warranty -of any kind, either expressed or implied, including, without limitation, warranties -that the covered code is free of defects, merchantable, fit for a particular purpose -or non-infringing. The entire risk as to the quality and performance of the covered -code is with you. Should any covered code prove defective in any respect, you (not -the initial developer or any other contributor) assume the cost of any necessary -servicing, repair or correction. This disclaimer of warranty constitutes an essential -part of this license. No use of any covered code is authorized hereunder except under -this disclaimer. - -Permission is hereby granted to use, copy, modify, and distribute this -source code, or portions hereof, for any purpose, including commercial applications, -freely and without fee, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - --------------------------------------------------------------------------------- - -Other information: about CxImage, and the latest version, can be found at the -CxImage home page: http://www.xdp.it - --------------------------------------------------------------------------------- diff --git a/Externals/cximage/xfile.h b/Externals/cximage/xfile.h deleted file mode 100644 index b64594ee97b..00000000000 --- a/Externals/cximage/xfile.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * File: xfile.h - * Purpose: General Purpose File Class - */ -/* - -------------------------------------------------------------------------------- - - COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - - CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it - CxFile version 2.00 23/Aug/2002 - CxFile version 2.10 16/Dec/2007 - - Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes - - Covered code is provided under this license on an "as is" basis, without warranty - of any kind, either expressed or implied, including, without limitation, warranties - that the covered code is free of defects, merchantable, fit for a particular purpose - or non-infringing. The entire risk as to the quality and performance of the covered - code is with you. Should any covered code prove defective in any respect, you (not - the initial developer or any other contributor) assume the cost of any necessary - servicing, repair or correction. This disclaimer of warranty constitutes an essential - part of this license. No use of any covered code is authorized hereunder except under - this disclaimer. - - Permission is hereby granted to use, copy, modify, and distribute this - source code, or portions hereof, for any purpose, including commercial applications, - freely and without fee, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - -------------------------------------------------------------------------------- - */ -#if !defined(__xfile_h) -#define __xfile_h - -#if defined (WIN32) || defined (_WIN32_WCE) - #include -#endif - -#include -#include - -#include "ximadef.h" - -class DLL_EXP CxFile -{ -public: - CxFile(void) { }; - virtual ~CxFile() { }; - - virtual bool Close() = 0; - virtual size_t Read(void *buffer, size_t size, size_t count) = 0; - virtual size_t Write(const void *buffer, size_t size, size_t count) = 0; - virtual bool Seek(long offset, int origin) = 0; - virtual long Tell() = 0; - virtual long Size() = 0; - virtual bool Flush() = 0; - virtual bool Eof() = 0; - virtual long Error() = 0; - virtual bool PutC(unsigned char c) - { - // Default implementation - size_t nWrote = Write(&c, 1, 1); - return (bool)(nWrote == 1); - } - virtual long GetC() = 0; - virtual char * GetS(char *string, int n) = 0; - virtual long Scanf(const char *format, void* output) = 0; -}; - -#endif //__xfile_h diff --git a/Externals/cximage/ximacfg.cpp b/Externals/cximage/ximacfg.cpp deleted file mode 100644 index 81e70574954..00000000000 --- a/Externals/cximage/ximacfg.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "ximacfg.h" - -#define XRCORE_API XR_IMPORT -#include "xrCore/xrMemory.h" - -void* cxalloc(size_t size) -{ - return xr_malloc(size); -} - -void cxfree(void* ptr) -{ - return xr_free(ptr); -} - -void* cxrealloc(void* ptr, size_t size) -{ - return xr_realloc(ptr, size); -} - -#undef XRCORE_API diff --git a/Externals/cximage/ximacfg.h b/Externals/cximage/ximacfg.h deleted file mode 100644 index 245fde4dfe9..00000000000 --- a/Externals/cximage/ximacfg.h +++ /dev/null @@ -1,77 +0,0 @@ -#if !defined(__ximaCFG_h) -#define __ximaCFG_h -#if !defined(WIN32) -#include -#endif - -#include "Common/Common.hpp" -#include "Common/Platform.hpp" - -extern "C" void* cxalloc(size_t size); -extern "C" void cxfree(void* ptr); -extern "C" void* cxrealloc(void* ptr, size_t size); - -#ifdef CXIMAGE_AS_SHARED_LIBRARY //must be defined in Release_Shared configuration -#ifdef CXIMAGE_BUILD -#define CXIMAGE_API XR_EXPORT -#else -#define CXIMAGE_API XR_IMPORT -#endif //#ifdef CXIMAGE_BUILD -#else //if CXIMAGE_AS_SHARED_LIBRARY linking as static library ... -#define CXIMAGE_API -#endif //CXIMAGE_AS_SHARED_LIBRARY - -///////////////////////////////////////////////////////////////////////////// -// CxImage supported features -#define CXIMAGE_SUPPORT_ALPHA 1 -#define CXIMAGE_SUPPORT_SELECTION 1 -#define CXIMAGE_SUPPORT_TRANSFORMATION 1 -#define CXIMAGE_SUPPORT_DSP 1 -#define CXIMAGE_SUPPORT_LAYERS 1 -#define CXIMAGE_SUPPORT_INTERPOLATION 1 - -#define CXIMAGE_SUPPORT_DECODE 1 -#define CXIMAGE_SUPPORT_ENCODE 1 // -#define CXIMAGE_SUPPORT_WINDOWS 1 - -///////////////////////////////////////////////////////////////////////////// -// CxImage supported formats -#define CXIMAGE_SUPPORT_BMP 0 -#define CXIMAGE_SUPPORT_GIF 0 -#define CXIMAGE_SUPPORT_JPG 1 -#define CXIMAGE_SUPPORT_PNG 0 -#define CXIMAGE_SUPPORT_ICO 0 -#define CXIMAGE_SUPPORT_TIF 0 -#define CXIMAGE_SUPPORT_TGA 0 -#define CXIMAGE_SUPPORT_PCX 0 -#define CXIMAGE_SUPPORT_WBMP 0 -#define CXIMAGE_SUPPORT_WMF 0 - -#define CXIMAGE_SUPPORT_JP2 0 -#define CXIMAGE_SUPPORT_JPC 0 -#define CXIMAGE_SUPPORT_PGX 0 -#define CXIMAGE_SUPPORT_PNM 0 -#define CXIMAGE_SUPPORT_RAS 0 - -#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm - -#define CXIMAGE_SUPPORT_MNG 0 -#define CXIMAGE_SUPPORT_SKA 0 -#define CXIMAGE_SUPPORT_RAW 0 - -///////////////////////////////////////////////////////////////////////////// -#define CXIMAGE_MAX_MEMORY 268435456 - -#define CXIMAGE_DEFAULT_DPI 96 - -#define CXIMAGE_ERR_NOFILE "null file handler" -#define CXIMAGE_ERR_NOIMAGE "null image!!!" - -#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 0 - -///////////////////////////////////////////////////////////////////////////// -//color to grey mapping -//#define RGB2GRAY(r,g,b) (((b)*114 + (g)*587 + (r)*299)/1000) -#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10) - -#endif diff --git a/Externals/cximage/ximadef.h b/Externals/cximage/ximadef.h deleted file mode 100644 index 4d3660621fe..00000000000 --- a/Externals/cximage/ximadef.h +++ /dev/null @@ -1,175 +0,0 @@ -#if !defined(__ximadefs_h) -#define __ximadefs_h - -#include "ximacfg.h" - -#if defined(_AFXDLL)||defined(_USRDLL) - #define DLL_EXP __declspec(dllexport) -#elif defined(_MSC_VER)&&(_MSC_VER<1200) - #define DLL_EXP __declspec(dllimport) -#else - #define DLL_EXP -#endif - - -#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - #define cx_try try - #define cx_throw(message) throw(message) - #define cx_catch catch (const char *message) -#else - #define cx_try bool cx_error=false; - #define cx_throw(message) {cx_error=true; if(strcmp(message,"")) strncpy(info.szLastError,message,255); goto cx_error_catch;} - #define cx_catch cx_error_catch: char message[]=""; if(cx_error) -#endif - - -#if CXIMAGE_SUPPORT_JP2 || CXIMAGE_SUPPORT_JPC || CXIMAGE_SUPPORT_PGX || CXIMAGE_SUPPORT_PNM || CXIMAGE_SUPPORT_RAS - #define CXIMAGE_SUPPORT_JASPER 1 -#else - #define CXIMAGE_SUPPORT_JASPER 0 -#endif - -#if CXIMAGE_SUPPORT_DSP -#undef CXIMAGE_SUPPORT_TRANSFORMATION - #define CXIMAGE_SUPPORT_TRANSFORMATION 1 -#endif - -#if CXIMAGE_SUPPORT_TRANSFORMATION || CXIMAGE_SUPPORT_TIF || CXIMAGE_SUPPORT_TGA || CXIMAGE_SUPPORT_BMP || CXIMAGE_SUPPORT_WINDOWS - #define CXIMAGE_SUPPORT_BASICTRANSFORMATIONS 1 -#endif - -#if CXIMAGE_SUPPORT_DSP || CXIMAGE_SUPPORT_TRANSFORMATION -#undef CXIMAGE_SUPPORT_INTERPOLATION - #define CXIMAGE_SUPPORT_INTERPOLATION 1 -#endif - -#if defined (_WIN32_WCE) - #undef CXIMAGE_SUPPORT_WMF - #define CXIMAGE_SUPPORT_WMF 0 -#endif - -#if !defined(WIN32) && !defined(_WIN32_WCE) - #undef CXIMAGE_SUPPORT_WINDOWS - #define CXIMAGE_SUPPORT_WINDOWS 0 -#endif - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -#ifndef PI - #define PI 3.141592653589793f -#endif - - -#if defined(WIN32) || defined(_WIN32_WCE) -#include -#endif - -#include -#include - -#ifdef __BORLANDC__ - -#ifndef _COMPLEX_DEFINED - -typedef struct tagcomplex { - double x,y; -} _complex; - -#endif - -#define _cabs(c) sqrt(c.x*c.x+c.y*c.y) - -#endif - - -#if !defined(WIN32) && !defined(_WIN32_WCE) - -#include -#include -#include - -typedef uint8_t BYTE; -typedef DWORD COLORREF; -typedef void* HRGN; -typedef void* HDC; - -typedef int boolean; - -#ifndef TCHAR -#define TCHAR char -#endif - -typedef struct tagRGBQUAD { - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; - BYTE rgbReserved; -} RGBQUAD; - -#pragma pack(push, 1) - -typedef struct tagBITMAPINFOHEADER{ - DWORD biSize; - long biWidth; - long biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - long biXPelsPerMeter; - long biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -} BITMAPINFOHEADER; - -typedef struct tagBITMAPFILEHEADER { - WORD bfType; - DWORD bfSize; - WORD bfReserved1; - WORD bfReserved2; - DWORD bfOffBits; -} BITMAPFILEHEADER; - -typedef struct tagBITMAPCOREHEADER { - DWORD bcSize; - WORD bcWidth; - WORD bcHeight; - WORD bcPlanes; - WORD bcBitCount; -} BITMAPCOREHEADER; - -typedef struct tagRGBTRIPLE { - BYTE rgbtBlue; - BYTE rgbtGreen; - BYTE rgbtRed; -} RGBTRIPLE; - -#pragma pack(pop) - -#define BI_RGB 0L -#define BI_RLE8 1L -#define BI_RLE4 2L -#define BI_BITFIELDS 3L - -#define GetRValue(rgb) ((BYTE)(rgb)) -#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8)) -#define GetBValue(rgb) ((BYTE)((rgb)>>16)) - -#ifndef _COMPLEX_DEFINED - -typedef struct tagcomplex { - double x,y; -} _complex; - -#endif - -#define _cabs(c) sqrt(c.x*c.x+c.y*c.y) - -#endif - -#endif //__ximadefs diff --git a/Externals/cximage/ximaenc.cpp b/Externals/cximage/ximaenc.cpp deleted file mode 100644 index 0b944031d0f..00000000000 --- a/Externals/cximage/ximaenc.cpp +++ /dev/null @@ -1,1008 +0,0 @@ -// xImaCodec.cpp : Encode Decode functions -/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -#if defined(WIN32) || defined(_WIN32_WCE) -#include -#else -#define _tfopen fopen -#define _T(x) x -#endif - -#if CXIMAGE_SUPPORT_JPG -#include "ximajpg.h" -#endif - -#if CXIMAGE_SUPPORT_GIF -#include "ximagif.h" -#endif - -#if CXIMAGE_SUPPORT_PNG -#include "ximapng.h" -#endif - -#if CXIMAGE_SUPPORT_MNG -#include "ximamng.h" -#endif - -#if CXIMAGE_SUPPORT_BMP -#include "ximabmp.h" -#endif - -#if CXIMAGE_SUPPORT_ICO -#include "ximaico.h" -#endif - -#if CXIMAGE_SUPPORT_TIF -#include "ximatif.h" -#endif - -#if CXIMAGE_SUPPORT_TGA -#include "ximatga.h" -#endif - -#if CXIMAGE_SUPPORT_PCX -#include "ximapcx.h" -#endif - -#if CXIMAGE_SUPPORT_WBMP -#include "ximawbmp.h" -#endif - -#if CXIMAGE_SUPPORT_WMF -#include "ximawmf.h" // - WMF/EMF support -#endif - -#if CXIMAGE_SUPPORT_JBG -#include "ximajbg.h" -#endif - -#if CXIMAGE_SUPPORT_JASPER -#include "ximajas.h" -#endif - -#if CXIMAGE_SUPPORT_SKA -#include "ximaska.h" -#endif - -#if CXIMAGE_SUPPORT_RAW -#include "ximaraw.h" -#endif - -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_ENCODE -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::EncodeSafeCheck(CxFile *hFile) -{ - if (hFile==NULL) { - strcpy(info.szLastError,CXIMAGE_ERR_NOFILE); - return true; - } - - if (pDib==NULL){ - strcpy(info.szLastError,CXIMAGE_ERR_NOIMAGE); - return true; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -//#ifdef WIN32 -//bool CxImage::Save(LPCWSTR filename, DWORD imagetype) -//{ -// FILE* hFile; //file handle to write the image -// if ((hFile=_wfopen(filename,L"wb"))==NULL) return false; -// bool bOK = Encode(hFile,imagetype); -// fclose(hFile); -// return bOK; -//} -//#endif //WIN32 -//////////////////////////////////////////////////////////////////////////////// -// For UNICODE support: char -> TCHAR -/** - * Saves to disk the image in a specific format. - * \param filename: file name - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Save(const TCHAR * filename, DWORD imagetype) -{ - FILE* hFile; //file handle to write the image - - if ((hFile=_tfopen(filename,_T("wb")))==NULL) return false; // For UNICODE support - - bool bOK = Encode(hFile,imagetype); - fclose(hFile); - return bOK; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Saves to disk the image in a specific format. - * \param hFile: file handle, open and enabled for writing. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Encode(FILE *hFile, DWORD imagetype) -{ - CxIOFile file(hFile); - return Encode(&file,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Saves to memory buffer the image in a specific format. - * \param buffer: output memory buffer pointer. Must be NULL, - * the function allocates and fill the memory, - * the application must free the buffer, see also FreeMemory(). - * \param size: output memory buffer size. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Encode(BYTE * &buffer, long &size, DWORD imagetype) -{ - if (buffer!=NULL){ - strcpy(info.szLastError,"the buffer must be empty"); - return false; - } - CxMemFile file; - file.Open(); - if(Encode(&file,imagetype)){ - buffer=file.GetBuffer(); - size=file.Size(); - return true; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Saves to disk the image in a specific format. - * \param hFile: file handle (CxMemFile or CxIOFile), with write access. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - * \sa ENUM_CXIMAGE_FORMATS - */ -bool CxImage::Encode(CxFile *hFile, DWORD imagetype) -{ - -#if CXIMAGE_SUPPORT_BMP - - if (imagetype==CXIMAGE_FORMAT_BMP){ - CxImageBMP newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_ICO - if (imagetype==CXIMAGE_FORMAT_ICO){ - CxImageICO newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_TIF - if (imagetype==CXIMAGE_FORMAT_TIF){ - CxImageTIF newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JPG - if (imagetype==CXIMAGE_FORMAT_JPG){ - CxImageJPG newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_GIF - if (imagetype==CXIMAGE_FORMAT_GIF){ - CxImageGIF newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_PNG - if (imagetype==CXIMAGE_FORMAT_PNG){ - CxImagePNG newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_MNG - if (imagetype==CXIMAGE_FORMAT_MNG){ - CxImageMNG newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_TGA - if (imagetype==CXIMAGE_FORMAT_TGA){ - CxImageTGA newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_PCX - if (imagetype==CXIMAGE_FORMAT_PCX){ - CxImagePCX newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_WBMP - if (imagetype==CXIMAGE_FORMAT_WBMP){ - CxImageWBMP newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // - WMF/EMF support - if (imagetype==CXIMAGE_FORMAT_WMF){ - CxImageWMF newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JBG - if (imagetype==CXIMAGE_FORMAT_JBG){ - CxImageJBG newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JASPER - if ( - #if CXIMAGE_SUPPORT_JP2 - imagetype==CXIMAGE_FORMAT_JP2 || - #endif - #if CXIMAGE_SUPPORT_JPC - imagetype==CXIMAGE_FORMAT_JPC || - #endif - #if CXIMAGE_SUPPORT_PGX - imagetype==CXIMAGE_FORMAT_PGX || - #endif - #if CXIMAGE_SUPPORT_PNM - imagetype==CXIMAGE_FORMAT_PNM || - #endif - #if CXIMAGE_SUPPORT_RAS - imagetype==CXIMAGE_FORMAT_RAS || - #endif - false ){ - CxImageJAS newima; - newima.Ghost(this); - if (newima.Encode(hFile,imagetype)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - -#if CXIMAGE_SUPPORT_SKA - if (imagetype==CXIMAGE_FORMAT_SKA){ - CxImageSKA newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - -#if CXIMAGE_SUPPORT_RAW - if (imagetype==CXIMAGE_FORMAT_RAW){ - CxImageRAW newima; - newima.Ghost(this); - if (newima.Encode(hFile)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - - strcpy(info.szLastError,"Encode: Unknown format"); - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Saves to disk or memory pagecount images, referenced by an array of CxImage pointers. - * \param hFile: file handle. - * \param pImages: array of CxImage pointers. - * \param pagecount: number of images. - * \param imagetype: can be CXIMAGE_FORMAT_TIF or CXIMAGE_FORMAT_GIF. - * \return true if everything is ok - */ -bool CxImage::Encode(FILE * hFile, CxImage ** pImages, int pagecount, DWORD imagetype) -{ - CxIOFile file(hFile); - return Encode(&file, pImages, pagecount,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Saves to disk or memory pagecount images, referenced by an array of CxImage pointers. - * \param hFile: file handle (CxMemFile or CxIOFile), with write access. - * \param pImages: array of CxImage pointers. - * \param pagecount: number of images. - * \param imagetype: can be CXIMAGE_FORMAT_TIF, CXIMAGE_FORMAT_GIF or CXIMAGE_FORMAT_ICO. - * \return true if everything is ok - */ -bool CxImage::Encode(CxFile * hFile, CxImage ** pImages, int pagecount, DWORD imagetype) -{ -#if CXIMAGE_SUPPORT_TIF - if (imagetype==CXIMAGE_FORMAT_TIF){ - CxImageTIF newima; - newima.Ghost(this); - if (newima.Encode(hFile,pImages,pagecount)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_GIF - if (imagetype==CXIMAGE_FORMAT_GIF){ - CxImageGIF newima; - newima.Ghost(this); - if (newima.Encode(hFile,pImages,pagecount)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_ICO - if (imagetype==CXIMAGE_FORMAT_ICO){ - CxImageICO newima; - newima.Ghost(this); - if (newima.Encode(hFile,pImages,pagecount)){ - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - strcpy(info.szLastError,"Multipage Encode, Unsupported operation for this format"); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * exports the image into a RGBA buffer, Useful for OpenGL applications. - * \param buffer: output memory buffer pointer. Must be NULL, - * the function allocates and fill the memory, - * the application must free the buffer, see also FreeMemory(). - * \param size: output memory buffer size. - * \param bFlipY: direction of Y axis. default = false. - * \return true if everything is ok - */ -bool CxImage::Encode2RGBA(BYTE * &buffer, long &size, bool bFlipY) -{ - if (buffer!=NULL){ - strcpy(info.szLastError,"the buffer must be empty"); - return false; - } - CxMemFile file; - file.Open(); - if(Encode2RGBA(&file,bFlipY)){ - buffer=file.GetBuffer(); - size=file.Size(); - return true; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * exports the image into a RGBA buffer, Useful for OpenGL applications. - * \param hFile: file handle (CxMemFile or CxIOFile), with write access. - * \param bFlipY: direction of Y axis. default = false. - * \return true if everything is ok - */ -bool CxImage::Encode2RGBA(CxFile *hFile, bool bFlipY) -{ - if (EncodeSafeCheck(hFile)) return false; - - for (long y1 = 0; y1 < head.biHeight; y1++) { - long y = bFlipY ? head.biHeight - 1 - y1 : y1; - for(long x = 0; x < head.biWidth; x++) { - RGBQUAD color = BlindGetPixelColor(x,y); - hFile->PutC(color.rgbRed); - hFile->PutC(color.rgbGreen); - hFile->PutC(color.rgbBlue); - hFile->PutC(color.rgbReserved); - } - } - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_ENCODE -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// -// For UNICODE support: char -> TCHAR -/** - * Reads from disk the image in a specific format. - * - If decoding fails using the specified image format, - * the function will try the automatic file format recognition. - * - * \param filename: file name - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Load(const TCHAR * filename, DWORD imagetype) -//bool CxImage::Load(const char * filename, DWORD imagetype) -{ - /*FILE* hFile; //file handle to read the image - if ((hFile=fopen(filename,"rb"))==NULL) return false; - bool bOK = Decode(hFile,imagetype); - fclose(hFile);*/ - - /* automatic file type recognition */ - bool bOK = false; - if ( GetTypeIndexFromId(imagetype) ){ - FILE* hFile; //file handle to read the image - - if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support - - bOK = Decode(hFile,imagetype); - fclose(hFile); - if (bOK) return bOK; - } - - char szError[256]; - strcpy(szError,info.szLastError); //save the first error - - // if failed, try automatic recognition of the file... - FILE* hFile; - - if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support - - bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN); - fclose(hFile); - - if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error - - return bOK; -} -//////////////////////////////////////////////////////////////////////////////// -#ifdef WIN32 -//bool CxImage::Load(LPCWSTR filename, DWORD imagetype) -//{ -// /*FILE* hFile; //file handle to read the image -// if ((hFile=_wfopen(filename, L"rb"))==NULL) return false; -// bool bOK = Decode(hFile,imagetype); -// fclose(hFile);*/ -// -// /* automatic file type recognition */ -// bool bOK = false; -// if ( GetTypeIndexFromId(imagetype) ){ -// FILE* hFile; //file handle to read the image -// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false; -// bOK = Decode(hFile,imagetype); -// fclose(hFile); -// if (bOK) return bOK; -// } -// -// char szError[256]; -// strcpy(szError,info.szLastError); //save the first error -// -// // if failed, try automatic recognition of the file... -// FILE* hFile; //file handle to read the image -// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false; -// bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN); -// fclose(hFile); -// -// if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error -// -// return bOK; -//} -//////////////////////////////////////////////////////////////////////////////// -/** - * Loads an image from the application resources. - * \param hRes: the resource handle returned by FindResource(). - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS. - * \param hModule: NULL for internal resource, or external application/DLL hinstance returned by LoadLibray. - * \return true if everything is ok - */ -bool CxImage::LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule) -{ - DWORD rsize=SizeofResource(hModule,hRes); - HGLOBAL hMem=::LoadResource(hModule,hRes); - if (hMem){ - char* lpVoid=(char*)LockResource(hMem); - if (lpVoid){ - // FILE* fTmp=tmpfile(); doesn't work with network - /*char tmpPath[MAX_PATH] = {0}; - char tmpFile[MAX_PATH] = {0}; - GetTempPath(MAX_PATH,tmpPath); - GetTempFileName(tmpPath,"IMG",0,tmpFile); - FILE* fTmp=fopen(tmpFile,"w+b"); - if (fTmp){ - fwrite(lpVoid,rsize,1,fTmp); - fseek(fTmp,0,SEEK_SET); - bool bOK = Decode(fTmp,imagetype); - fclose(fTmp); - DeleteFile(tmpFile); - return bOK; - }*/ - - CxMemFile fTmp((BYTE*)lpVoid,rsize); - return Decode(&fTmp,imagetype); - } - } else strcpy(info.szLastError,"Unable to load resource!"); - return false; -} -#endif //WIN32 -//////////////////////////////////////////////////////////////////////////////// -/** - * Constructor from file name, see Load() - * \param filename: file name - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - */ -// -// > filename: file name -// > imagetype: specify the image format (CXIMAGE_FORMAT_BMP,...) -// For UNICODE support: char -> TCHAR -CxImage::CxImage(const TCHAR * filename, DWORD imagetype) -//CxImage::CxImage(const char * filename, DWORD imagetype) -{ - Startup(imagetype); - Load(filename,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Constructor from file handle, see Decode() - * \param stream: file handle, with read access. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - */ -CxImage::CxImage(FILE * stream, DWORD imagetype) -{ - Startup(imagetype); - Decode(stream,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Constructor from CxFile object, see Decode() - * \param stream: file handle (CxMemFile or CxIOFile), with read access. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - */ -CxImage::CxImage(CxFile * stream, DWORD imagetype) -{ - Startup(imagetype); - Decode(stream,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Constructor from memory buffer, see Decode() - * \param buffer: memory buffer - * \param size: size of buffer - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - */ -CxImage::CxImage(BYTE * buffer, DWORD size, DWORD imagetype) -{ - Startup(imagetype); - CxMemFile stream(buffer,size); - Decode(&stream,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Loads an image from memory buffer - * \param buffer: memory buffer - * \param size: size of buffer - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Decode(BYTE * buffer, DWORD size, DWORD imagetype) -{ - CxMemFile file(buffer,size); - return Decode(&file,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Loads an image from file handle. - * \param hFile: file handle, with read access. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - */ -bool CxImage::Decode(FILE *hFile, DWORD imagetype) -{ - CxIOFile file(hFile); - return Decode(&file,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Loads an image from CxFile object - * \param hFile: file handle (CxMemFile or CxIOFile), with read access. - * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS - * \return true if everything is ok - * \sa ENUM_CXIMAGE_FORMATS - */ -bool CxImage::Decode(CxFile *hFile, DWORD imagetype) -{ - if (hFile == NULL){ - strcpy(info.szLastError,CXIMAGE_ERR_NOFILE); - return false; - } - - if (imagetype==CXIMAGE_FORMAT_UNKNOWN){ - DWORD pos = hFile->Tell(); -#if CXIMAGE_SUPPORT_BMP - { CxImageBMP newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_JPG - { CxImageJPG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_ICO - { CxImageICO newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_GIF - { CxImageGIF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_PNG - { CxImagePNG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_TIF - { CxImageTIF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_MNG - { CxImageMNG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_TGA - { CxImageTGA newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_PCX - { CxImagePCX newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_WBMP - { CxImageWBMP newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS - { CxImageWMF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_JBG - { CxImageJBG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_JASPER - { CxImageJAS newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_SKA - { CxImageSKA newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif -#if CXIMAGE_SUPPORT_RAW - { CxImageRAW newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); } -#endif - } - -#if CXIMAGE_SUPPORT_BMP - if (imagetype==CXIMAGE_FORMAT_BMP){ - CxImageBMP newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JPG - if (imagetype==CXIMAGE_FORMAT_JPG){ - CxImageJPG newima; - newima.CopyInfo(*this); // - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_ICO - if (imagetype==CXIMAGE_FORMAT_ICO){ - CxImageICO newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - info.nNumFrames = newima.info.nNumFrames; - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_GIF - if (imagetype==CXIMAGE_FORMAT_GIF){ - CxImageGIF newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - info.nNumFrames = newima.info.nNumFrames; - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_PNG - if (imagetype==CXIMAGE_FORMAT_PNG){ - CxImagePNG newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_TIF - if (imagetype==CXIMAGE_FORMAT_TIF){ - CxImageTIF newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - info.nNumFrames = newima.info.nNumFrames; - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_MNG - if (imagetype==CXIMAGE_FORMAT_MNG){ - CxImageMNG newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - info.nNumFrames = newima.info.nNumFrames; - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_TGA - if (imagetype==CXIMAGE_FORMAT_TGA){ - CxImageTGA newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_PCX - if (imagetype==CXIMAGE_FORMAT_PCX){ - CxImagePCX newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_WBMP - if (imagetype==CXIMAGE_FORMAT_WBMP){ - CxImageWBMP newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // vho - WMF support - if (imagetype == CXIMAGE_FORMAT_WMF){ - CxImageWMF newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JBG - if (imagetype==CXIMAGE_FORMAT_JBG){ - CxImageJBG newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_JASPER - if ( - #if CXIMAGE_SUPPORT_JP2 - imagetype==CXIMAGE_FORMAT_JP2 || - #endif - #if CXIMAGE_SUPPORT_JPC - imagetype==CXIMAGE_FORMAT_JPC || - #endif - #if CXIMAGE_SUPPORT_PGX - imagetype==CXIMAGE_FORMAT_PGX || - #endif - #if CXIMAGE_SUPPORT_PNM - imagetype==CXIMAGE_FORMAT_PNM || - #endif - #if CXIMAGE_SUPPORT_RAS - imagetype==CXIMAGE_FORMAT_RAS || - #endif - false ){ - CxImageJAS newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile,imagetype)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif -#if CXIMAGE_SUPPORT_SKA - if (imagetype==CXIMAGE_FORMAT_SKA){ - CxImageSKA newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - -#if CXIMAGE_SUPPORT_RAW - if (imagetype==CXIMAGE_FORMAT_RAW){ - CxImageRAW newima; - newima.CopyInfo(*this); - if (newima.Decode(hFile)){ - Transfer(newima); - return true; - } else { - strcpy(info.szLastError,newima.GetLastError()); - return false; - } - } -#endif - - strcpy(info.szLastError,"Decode: Unknown or wrong format"); - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Loads an image from CxFile object - * \param hFile: file handle (CxMemFile or CxIOFile), with read access. - * \param imagetype: file format, default = 0 (CXIMAGE_FORMAT_UNKNOWN) - * \return : if imagetype is not 0, the function returns true when imagetype - * matches the file image format. If imagetype is 0, the function returns true - * when the file image format is recognized as a supported format. - * If the returned value is true, use GetHeight(), GetWidth() or GetType() - * to retrieve the basic image information. - * \sa ENUM_CXIMAGE_FORMATS - */ -bool CxImage::CheckFormat(CxFile * hFile, DWORD imagetype) -{ - SetType(CXIMAGE_FORMAT_UNKNOWN); - SetEscape(-1); - - if (!Decode(hFile,imagetype)) - return false; - - if (GetType() == CXIMAGE_FORMAT_UNKNOWN || GetType() != imagetype) - return false; - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::CheckFormat(BYTE * buffer, DWORD size, DWORD imagetype) -{ - if (buffer==NULL || size==0){ - strcpy(info.szLastError,"invalid or empty buffer"); - return false; - } - CxMemFile file(buffer,size); - return CheckFormat(&file,imagetype); -} -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#undef _tfopen -#undef _T -#endif diff --git a/Externals/cximage/ximaexif.cpp b/Externals/cximage/ximaexif.cpp deleted file mode 100644 index db7650d8907..00000000000 --- a/Externals/cximage/ximaexif.cpp +++ /dev/null @@ -1,878 +0,0 @@ -/* - * File: ximaexif.cpp - * Purpose: EXIF reader - * 18/Aug/2002 Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - * based on jhead-1.8 by Matthias Wandel - */ - -#include "ximajpg.h" - -#if CXIMAGEJPG_SUPPORT_EXIF - -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::CxExifInfo::CxExifInfo(EXIFINFO* info) -{ - if (info) { - m_exifinfo = info; - freeinfo = false; - } else { - m_exifinfo = new EXIFINFO; - memset(m_exifinfo,0,sizeof(EXIFINFO)); - freeinfo = true; - } - - m_szLastError[0]='\0'; - ExifImageWidth = MotorolaOrder = 0; - SectionsRead=0; - memset(&Sections, 0, MAX_SECTIONS * sizeof(Section_t)); -} -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::CxExifInfo::~CxExifInfo() -{ - for(int i=0;iGetC(); - - if (a != 0xff || hFile->GetC() != M_SOI){ - return false; - } - - for(;;){ - int itemlen; - int marker = 0; - int ll,lh, got; - BYTE * Data; - - if (SectionsRead >= MAX_SECTIONS){ - strcpy(m_szLastError,"Too many sections in jpg file"); - return false; - } - - for (a=0;a<7;a++){ - marker = hFile->GetC(); - if (marker != 0xff) break; - - if (a >= 6){ - printf("too many padding bytes\n"); - return false; - } - } - - if (marker == 0xff){ - // 0xff is legal padding, but if we get that many, something's wrong. - strcpy(m_szLastError,"too many padding bytes!"); - return false; - } - - Sections[SectionsRead].Type = marker; - - // Read the length of the section. - lh = hFile->GetC(); - ll = hFile->GetC(); - - itemlen = (lh << 8) | ll; - - if (itemlen < 2){ - strcpy(m_szLastError,"invalid marker"); - return false; - } - - Sections[SectionsRead].Size = itemlen; - - Data = (BYTE *)cxalloc(itemlen);//malloc(itemlen); - if (Data == NULL){ - strcpy(m_szLastError,"Could not allocate memory"); - return false; - } - Sections[SectionsRead].Data = Data; - - // Store first two pre-read bytes. - Data[0] = (BYTE)lh; - Data[1] = (BYTE)ll; - - got = hFile->Read(Data+2, 1, itemlen-2); // Read the whole section. - if (got != itemlen-2){ - strcpy(m_szLastError,"Premature end of file?"); - return false; - } - SectionsRead += 1; - - switch(marker){ - - case M_SOS: // stop before hitting compressed data - // If reading entire image is requested, read the rest of the data. - if (nReadMode & EXIF_READ_IMAGE){ - int cp, ep, size; - // Determine how much file is left. - cp = hFile->Tell(); - hFile->Seek(0, SEEK_END); - ep = hFile->Tell(); - hFile->Seek(cp, SEEK_SET); - - size = ep-cp; - Data = (BYTE *)cxalloc(size);//malloc(size); - if (Data == NULL){ - strcpy(m_szLastError,"could not allocate data for entire image"); - return false; - } - - got = hFile->Read(Data, 1, size); - if (got != size){ - strcpy(m_szLastError,"could not read the rest of the image"); - return false; - } - - Sections[SectionsRead].Data = Data; - Sections[SectionsRead].Size = size; - Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER; - SectionsRead ++; - } - return true; - - case M_EOI: // in case it's a tables-only JPEG stream - printf("No image in jpeg!\n"); - return false; - - case M_COM: // Comment section - if (HaveCom || ((nReadMode & EXIF_READ_EXIF) == 0)){ - // Discard this section. - cxfree(Sections[--SectionsRead].Data);//free(Sections[--SectionsRead].Data); - Sections[SectionsRead].Data=0; - }else{ - process_COM(Data, itemlen); - HaveCom = true; - } - break; - - case M_JFIF: - // Regular jpegs always have this tag, exif images have the exif - // marker instead, althogh ACDsee will write images with both markers. - // this program will re-create this marker on absence of exif marker. - // hence no need to keep the copy from the file. - cxfree(Sections[--SectionsRead].Data);//free(Sections[--SectionsRead].Data); - Sections[SectionsRead].Data=0; - break; - - case M_EXIF: - // Seen files from some 'U-lead' software with Vivitar scanner - // that uses marker 31 for non exif stuff. Thus make sure - // it says 'Exif' in the section before treating it as exif. - if ((nReadMode & EXIF_READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){ - m_exifinfo->IsExif = process_EXIF((BYTE *)Data+2, itemlen); - }else{ - // Discard this section. - cxfree(Sections[--SectionsRead].Data);//free(Sections[--SectionsRead].Data); - Sections[SectionsRead].Data=0; - } - break; - - case M_SOF0: - case M_SOF1: - case M_SOF2: - case M_SOF3: - case M_SOF5: - case M_SOF6: - case M_SOF7: - case M_SOF9: - case M_SOF10: - case M_SOF11: - case M_SOF13: - case M_SOF14: - case M_SOF15: - process_SOFn(Data, marker); - break; - default: - // Skip any other sections. - //if (ShowTags) printf("Jpeg section marker 0x%02x size %d\n",marker, itemlen); - break; - } - } - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------------------------------------------- - Process a EXIF marker - Describes all the drivel that most digital cameras include... ---------------------------------------------------------------------------*/ -bool CxImageJPG::CxExifInfo::process_EXIF(unsigned char * CharBuf, unsigned int length) -{ - m_exifinfo->FlashUsed = 0; - /* If it's from a digicam, and it used flash, it says so. */ - m_exifinfo->Comments[0] = '\0'; /* Initial value - null string */ - - ExifImageWidth = 0; - - { /* Check the EXIF header component */ - static const unsigned char ExifHeader[] = "Exif\0\0"; - if (memcmp(CharBuf+0, ExifHeader,6)){ - strcpy(m_szLastError,"Incorrect Exif header"); - return false; - } - } - - if (memcmp(CharBuf+6,"II",2) == 0){ - MotorolaOrder = 0; - }else{ - if (memcmp(CharBuf+6,"MM",2) == 0){ - MotorolaOrder = 1; - }else{ - strcpy(m_szLastError,"Invalid Exif alignment marker."); - return false; - } - } - - /* Check the next two values for correctness. */ - if (Get16u(CharBuf+8) != 0x2a){ - strcpy(m_szLastError,"Invalid Exif start (1)"); - return false; - } - - int FirstOffset = Get32u(CharBuf+10); - /* - if (FirstOffset < 8 || FirstOffset > 16){ - // I used to ensure this was set to 8 (website I used indicated its 8) - // but PENTAX Optio 230 has it set differently, and uses it as offset. (Sept 11 2002) - strcpy(m_szLastError,"Suspicious offset of first IFD value"); - return false; - }*/ - - unsigned char * LastExifRefd = CharBuf; - - /* First directory starts 16 bytes in. Offsets start at 8 bytes in. */ - if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd)) - return false; - - /* give a chance for a second directory */ - if (FirstOffset > 8) { - if (!ProcessExifDir(CharBuf+14+FirstOffset-8, CharBuf+6, length-6, m_exifinfo, &LastExifRefd)) - return false; - } - - /* This is how far the interesting (non thumbnail) part of the exif went. */ - // int ExifSettingsLength = LastExifRefd - CharBuf; - - /* Compute the CCD width, in milimeters. */ - if (m_exifinfo->FocalplaneXRes != 0){ - m_exifinfo->CCDWidth = (float)(ExifImageWidth * m_exifinfo->FocalplaneUnits / m_exifinfo->FocalplaneXRes); - } - - return true; -} -//-------------------------------------------------------------------------- -// Get 16 bits motorola order (always) for jpeg header stuff. -//-------------------------------------------------------------------------- -int CxImageJPG::CxExifInfo::Get16m(void * Short) -{ - return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1]; -} -//////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------------------------------------------- - Convert a 16 bit unsigned value from file's native byte order ---------------------------------------------------------------------------*/ -int CxImageJPG::CxExifInfo::Get16u(void * Short) -{ - if (MotorolaOrder){ - return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1]; - }else{ - return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0]; - } -} -//////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------------------------------------------- - Convert a 32 bit signed value from file's native byte order ---------------------------------------------------------------------------*/ -long CxImageJPG::CxExifInfo::Get32s(void * Long) -{ - if (MotorolaOrder){ - return ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16) - | (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 ); - }else{ - return ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16) - | (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 ); - } -} -//////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------------------------------------------- - Convert a 32 bit unsigned value from file's native byte order ---------------------------------------------------------------------------*/ -unsigned long CxImageJPG::CxExifInfo::Get32u(void * Long) -{ - return (unsigned long)Get32s(Long) & 0xffffffff; -} -//////////////////////////////////////////////////////////////////////////////// - -/* Describes format descriptor */ -static const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8}; -#define NUM_FORMATS 12 - -#define FMT_BYTE 1 -#define FMT_STRING 2 -#define FMT_USHORT 3 -#define FMT_ULONG 4 -#define FMT_URATIONAL 5 -#define FMT_SBYTE 6 -#define FMT_UNDEFINED 7 -#define FMT_SSHORT 8 -#define FMT_SLONG 9 -#define FMT_SRATIONAL 10 -#define FMT_SINGLE 11 -#define FMT_DOUBLE 12 - -/* Describes tag values */ - -#define TAG_EXIF_VERSION 0x9000 -#define TAG_EXIF_OFFSET 0x8769 -#define TAG_INTEROP_OFFSET 0xa005 - -#define TAG_MAKE 0x010F -#define TAG_MODEL 0x0110 - -#define TAG_ORIENTATION 0x0112 -#define TAG_XRESOLUTION 0x011A -#define TAG_YRESOLUTION 0x011B -#define TAG_RESOLUTIONUNIT 0x0128 - -#define TAG_EXPOSURETIME 0x829A -#define TAG_FNUMBER 0x829D - -#define TAG_SHUTTERSPEED 0x9201 -#define TAG_APERTURE 0x9202 -#define TAG_BRIGHTNESS 0x9203 -#define TAG_MAXAPERTURE 0x9205 -#define TAG_FOCALLENGTH 0x920A - -#define TAG_DATETIME_ORIGINAL 0x9003 -#define TAG_USERCOMMENT 0x9286 - -#define TAG_SUBJECT_DISTANCE 0x9206 -#define TAG_FLASH 0x9209 - -#define TAG_FOCALPLANEXRES 0xa20E -#define TAG_FOCALPLANEYRES 0xa20F -#define TAG_FOCALPLANEUNITS 0xa210 -#define TAG_EXIF_IMAGEWIDTH 0xA002 -#define TAG_EXIF_IMAGELENGTH 0xA003 - -/* the following is added 05-jan-2001 vcs */ -#define TAG_EXPOSURE_BIAS 0x9204 -#define TAG_WHITEBALANCE 0x9208 -#define TAG_METERING_MODE 0x9207 -#define TAG_EXPOSURE_PROGRAM 0x8822 -#define TAG_ISO_EQUIVALENT 0x8827 -#define TAG_COMPRESSION_LEVEL 0x9102 - -#define TAG_THUMBNAIL_OFFSET 0x0201 -#define TAG_THUMBNAIL_LENGTH 0x0202 - - -/*-------------------------------------------------------------------------- - Process one of the nested EXIF directories. ---------------------------------------------------------------------------*/ -bool CxImageJPG::CxExifInfo::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, - EXIFINFO * const m_exifinfo, unsigned char ** const LastExifRefdP, int NestingLevel) -{ - int de; - int a; - int NumDirEntries; - unsigned ThumbnailOffset = 0; - unsigned ThumbnailSize = 0; - - if (NestingLevel > 4){ - strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)"); - return false; - } - - NumDirEntries = Get16u(DirStart); - - if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength)){ - strcpy(m_szLastError,"Illegally sized directory"); - return false; - } - - for (de=0;de= NUM_FORMATS) { - /* (-1) catches illegal zero case as unsigned underflows to positive large */ - strcpy(m_szLastError,"Illegal format code in EXIF dir"); - return false; - } - - ByteCount = Components * BytesPerFormat[Format]; - - if (ByteCount > 4){ - unsigned OffsetVal; - OffsetVal = Get32u(DirEntry+8); - /* If its bigger than 4 bytes, the dir entry contains an offset.*/ - if (OffsetVal+ByteCount > ExifLength){ - /* Bogus pointer offset and / or bytecount value */ - strcpy(m_szLastError,"Illegal pointer offset value in EXIF."); - return false; - } - ValuePtr = OffsetBase+OffsetVal; - }else{ - /* 4 bytes or less and value is in the dir entry itself */ - ValuePtr = DirEntry+8; - } - - if (*LastExifRefdP < ValuePtr+ByteCount){ - /* Keep track of last byte in the exif header that was - actually referenced. That way, we know where the - discardable thumbnail data begins. - */ - *LastExifRefdP = ValuePtr+ByteCount; - } - - /* Extract useful components of tag */ - switch(Tag){ - - case TAG_MAKE: - strncpy(m_exifinfo->CameraMake, (char*)ValuePtr, 31); - break; - - case TAG_MODEL: - strncpy(m_exifinfo->CameraModel, (char*)ValuePtr, 39); - break; - - case TAG_EXIF_VERSION: - strncpy(m_exifinfo->Version,(char*)ValuePtr, 4); - break; - - case TAG_DATETIME_ORIGINAL: - strncpy(m_exifinfo->DateTime, (char*)ValuePtr, 19); - break; - - case TAG_USERCOMMENT: - // Olympus has this padded with trailing spaces. Remove these first. - for (a=ByteCount;;){ - a--; - if (((char*)ValuePtr)[a] == ' '){ - ((char*)ValuePtr)[a] = '\0'; - }else{ - break; - } - if (a == 0) break; - } - - /* Copy the comment */ - if (memcmp(ValuePtr, "ASCII",5) == 0){ - for (a=5;a<10;a++){ - char c; - c = ((char*)ValuePtr)[a]; - if (c != '\0' && c != ' '){ - strncpy(m_exifinfo->Comments, (char*)ValuePtr+a, 199); - break; - } - } - - }else{ - strncpy(m_exifinfo->Comments, (char*)ValuePtr, 199); - } - break; - - case TAG_FNUMBER: - /* Simplest way of expressing aperture, so I trust it the most. - (overwrite previously computd value if there is one) - */ - m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_APERTURE: - case TAG_MAXAPERTURE: - /* More relevant info always comes earlier, so only - use this field if we don't have appropriate aperture - information yet. - */ - if (m_exifinfo->ApertureFNumber == 0){ - m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)*0.5); - } - break; - - case TAG_BRIGHTNESS: - m_exifinfo->Brightness = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_FOCALLENGTH: - /* Nice digital cameras actually save the focal length - as a function of how farthey are zoomed in. - */ - - m_exifinfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_SUBJECT_DISTANCE: - /* Inidcates the distacne the autofocus camera is focused to. - Tends to be less accurate as distance increases. - */ - m_exifinfo->Distance = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_EXPOSURETIME: - /* Simplest way of expressing exposure time, so I - trust it most. (overwrite previously computd value - if there is one) - */ - m_exifinfo->ExposureTime = - (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_SHUTTERSPEED: - /* More complicated way of expressing exposure time, - so only use this value if we don't already have it - from somewhere else. - */ - if (m_exifinfo->ExposureTime == 0){ - m_exifinfo->ExposureTime = (float) - (1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f))); - } - break; - - case TAG_FLASH: - if ((int)ConvertAnyFormat(ValuePtr, Format) & 7){ - m_exifinfo->FlashUsed = 1; - }else{ - m_exifinfo->FlashUsed = 0; - } - break; - - case TAG_ORIENTATION: - m_exifinfo->Orientation = (int)ConvertAnyFormat(ValuePtr, Format); - if (m_exifinfo->Orientation < 1 || m_exifinfo->Orientation > 8){ - strcpy(m_szLastError,"Undefined rotation value"); - m_exifinfo->Orientation = 0; - } - break; - - case TAG_EXIF_IMAGELENGTH: - case TAG_EXIF_IMAGEWIDTH: - /* Use largest of height and width to deal with images - that have been rotated to portrait format. - */ - a = (int)ConvertAnyFormat(ValuePtr, Format); - if (ExifImageWidth < a) ExifImageWidth = a; - break; - - case TAG_FOCALPLANEXRES: - m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_FOCALPLANEYRES: - m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_RESOLUTIONUNIT: - switch((int)ConvertAnyFormat(ValuePtr, Format)){ - case 1: m_exifinfo->ResolutionUnit = 1.0f; break; /* 1 inch */ - case 2: m_exifinfo->ResolutionUnit = 1.0f; break; - case 3: m_exifinfo->ResolutionUnit = 0.3937007874f; break; /* 1 centimeter*/ - case 4: m_exifinfo->ResolutionUnit = 0.03937007874f; break; /* 1 millimeter*/ - case 5: m_exifinfo->ResolutionUnit = 0.00003937007874f; /* 1 micrometer*/ - } - break; - - case TAG_FOCALPLANEUNITS: - switch((int)ConvertAnyFormat(ValuePtr, Format)){ - case 1: m_exifinfo->FocalplaneUnits = 1.0f; break; /* 1 inch */ - case 2: m_exifinfo->FocalplaneUnits = 1.0f; break; - case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break; /* 1 centimeter*/ - case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break; /* 1 millimeter*/ - case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f; /* 1 micrometer*/ - } - break; - - // Remaining cases contributed by: Volker C. Schoech - - case TAG_EXPOSURE_BIAS: - m_exifinfo->ExposureBias = (float) ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_WHITEBALANCE: - m_exifinfo->Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_METERING_MODE: - m_exifinfo->MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_EXPOSURE_PROGRAM: - m_exifinfo->ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_ISO_EQUIVALENT: - m_exifinfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format); - if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200; - break; - - case TAG_COMPRESSION_LEVEL: - m_exifinfo->CompressionLevel = (int)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_XRESOLUTION: - m_exifinfo->Xresolution = (float)ConvertAnyFormat(ValuePtr, Format); - break; - case TAG_YRESOLUTION: - m_exifinfo->Yresolution = (float)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_THUMBNAIL_OFFSET: - ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format); - break; - - case TAG_THUMBNAIL_LENGTH: - ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format); - break; - - } - - if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){ - unsigned char * SubdirStart; - unsigned Offset = Get32u(ValuePtr); - if (Offset>8){ - SubdirStart = OffsetBase + Offset; - if (SubdirStart < OffsetBase || - SubdirStart > OffsetBase+ExifLength){ - strcpy(m_szLastError,"Illegal subdirectory link"); - return false; - } - ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1); - } - continue; - } - } - - - { - /* In addition to linking to subdirectories via exif tags, - there's also a potential link to another directory at the end - of each directory. This has got to be the result of a - committee! - */ - unsigned char * SubdirStart; - unsigned Offset; - Offset = Get16u(DirStart+2+12*NumDirEntries); - if (Offset){ - SubdirStart = OffsetBase + Offset; - if (SubdirStart < OffsetBase - || SubdirStart > OffsetBase+ExifLength){ - strcpy(m_szLastError,"Illegal subdirectory link"); - return false; - } - ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1); - } - } - - - if (ThumbnailSize && ThumbnailOffset){ - if (ThumbnailSize + ThumbnailOffset <= ExifLength){ - /* The thumbnail pointer appears to be valid. Store it. */ - m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset; - m_exifinfo->ThumbnailSize = ThumbnailSize; - } - } - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------------------------------------------- - Evaluate number, be it int, rational, or float from directory. ---------------------------------------------------------------------------*/ -double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int Format) -{ - double Value; - Value = 0; - - switch(Format){ - case FMT_SBYTE: Value = *(signed char *)ValuePtr; break; - case FMT_BYTE: Value = *(unsigned char *)ValuePtr; break; - - case FMT_USHORT: Value = Get16u(ValuePtr); break; - case FMT_ULONG: Value = Get32u(ValuePtr); break; - - case FMT_URATIONAL: - case FMT_SRATIONAL: - { - int Num,Den; - Num = Get32s(ValuePtr); - Den = Get32s(4+(char *)ValuePtr); - if (Den == 0){ - Value = 0; - }else{ - Value = (double)Num/Den; - } - break; - } - - case FMT_SSHORT: Value = (signed short)Get16u(ValuePtr); break; - case FMT_SLONG: Value = Get32s(ValuePtr); break; - - /* Not sure if this is correct (never seen float used in Exif format) - */ - case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break; - case FMT_DOUBLE: Value = *(double *)ValuePtr; break; - } - return Value; -} -//////////////////////////////////////////////////////////////////////////////// -void CxImageJPG::CxExifInfo::process_COM (const BYTE * Data, int length) -{ - int ch; - char Comment[MAX_COMMENT+1]; - int nch; - int a; - - nch = 0; - - if (length > MAX_COMMENT) length = MAX_COMMENT; // Truncate if it won't fit in our structure. - - for (a=2;aComments,Comment); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImageJPG::CxExifInfo::process_SOFn (const BYTE * Data, int marker) -{ - int data_precision, num_components; - - data_precision = Data[2]; - m_exifinfo->Height = Get16m((void*)(Data+3)); - m_exifinfo->Width = Get16m((void*)(Data+5)); - num_components = Data[7]; - - if (num_components == 3){ - m_exifinfo->IsColor = 1; - }else{ - m_exifinfo->IsColor = 0; - } - - m_exifinfo->Process = marker; - - //if (ShowTags) printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n", - // ImageInfo.Width, ImageInfo.Height, num_components, data_precision); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * this will work only on a CxImageJPG object, if the image originally has valid EXIF data - \verbatim - CxImageJPG jpg; - CxIOFile in,out; - in.Open("D:\\exif_in.jpg","rb"); - out.Open("D:\\exif_out.jpg","w+b"); - jpg.Decode(&in); - if (jpg.IsValid()){ - jpg.RotateLeft(); - jpg.Encode(&out); - } - \endverbatim -*/ -bool CxImageJPG::CxExifInfo::EncodeExif(CxFile * hFile) -{ - int a; - - if (FindSection(M_SOS)==NULL){ - strcpy(m_szLastError,"Can't write exif : didn't read all"); - return false; - } - - // Initial static jpeg marker. - hFile->PutC(0xff); - hFile->PutC(0xd8); - - if (Sections[0].Type != M_EXIF && Sections[0].Type != M_JFIF){ - // The image must start with an exif or jfif marker. If we threw those away, create one. - static BYTE JfifHead[18] = { - 0xff, M_JFIF, - 0x00, 0x10, 'J' , 'F' , 'I' , 'F' , 0x00, 0x01, - 0x01, 0x01, 0x01, 0x2C, 0x01, 0x2C, 0x00, 0x00 - }; - hFile->Write(JfifHead, 18, 1); - } - - // Write all the misc sections - for (a=0;aPutC(0xff); - hFile->PutC((unsigned char)(Sections[a].Type)); - hFile->Write(Sections[a].Data, Sections[a].Size, 1); - } - - // Write the remaining image data. - hFile->Write(Sections[a].Data, Sections[a].Size, 1); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -void CxImageJPG::CxExifInfo::DiscardAllButExif() -{ - Section_t ExifKeeper; - Section_t CommentKeeper; - int a; - - memset(&ExifKeeper, 0, sizeof(ExifKeeper)); - memset(&CommentKeeper, 0, sizeof(ExifKeeper)); - - for (a=0;a Use it before Create() - */ -void CxImage::CopyInfo(const CxImage &src) -{ - if (pDib==NULL) memcpy(&info,&src.info,sizeof(CXIMAGEINFO)); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa Copy - */ -CxImage& CxImage::operator = (const CxImage& isrc) -{ - if (this != &isrc) Copy(isrc); - return *this; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Initializes or rebuilds the image. - * \param dwWidth: width - * \param dwHeight: height - * \param wBpp: bit per pixel, can be 1, 4, 8, 24 - * \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS - * \return pointer to the internal pDib object; NULL if an error occurs. - */ -void* CxImage::Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype) -{ - // destroy the existing image (if any) - if (!Destroy()) - return NULL; - - // prevent further actions if width or height are not vaild - if ((dwWidth == 0) || (dwHeight == 0)){ - strcpy(info.szLastError,"CxImage::Create : width and height must be greater than zero"); - return NULL; - } - - // Make sure bits per pixel is valid - if (wBpp <= 1) wBpp = 1; - else if (wBpp <= 4) wBpp = 4; - else if (wBpp <= 8) wBpp = 8; - else wBpp = 24; - - // limit memory requirements (and also a check for bad parameters) - if (((dwWidth*dwHeight*wBpp)>>3) > CXIMAGE_MAX_MEMORY || - ((dwWidth*dwHeight*wBpp)/wBpp) != (dwWidth*dwHeight)) - { - strcpy(info.szLastError,"CXIMAGE_MAX_MEMORY exceeded"); - return NULL; - } - - // set the correct bpp value - switch (wBpp){ - case 1: - head.biClrUsed = 2; break; - case 4: - head.biClrUsed = 16; break; - case 8: - head.biClrUsed = 256; break; - default: - head.biClrUsed = 0; - } - - //set the common image informations - info.dwEffWidth = ((((wBpp * dwWidth) + 31) / 32) * 4); - info.dwType = imagetype; - - // initialize BITMAPINFOHEADER - head.biSize = sizeof(BITMAPINFOHEADER); // - head.biWidth = dwWidth; // fill in width from parameter - head.biHeight = dwHeight; // fill in height from parameter - head.biPlanes = 1; // must be 1 - head.biBitCount = (WORD)wBpp; // from parameter - head.biCompression = BI_RGB; - head.biSizeImage = info.dwEffWidth * dwHeight; -// head.biXPelsPerMeter = 0; See SetXDPI -// head.biYPelsPerMeter = 0; See SetYDPI -// head.biClrImportant = 0; See SetClrImportant - - pDib = cxalloc(GetSize());//malloc(GetSize()); // alloc memory block to store our bitmap - if (!pDib){ - strcpy(info.szLastError,"CxImage::Create can't allocate memory"); - return NULL; - } - - //clear the palette - RGBQUAD* pal=GetPalette(); - if (pal) memset(pal,0,GetPaletteSize()); - //Destroy the existing selection -#if CXIMAGE_SUPPORT_SELECTION - if (pSelection) SelectionDelete(); -#endif //CXIMAGE_SUPPORT_SELECTION - //Destroy the existing alpha channel -#if CXIMAGE_SUPPORT_ALPHA - if (pAlpha) AlphaDelete(); -#endif //CXIMAGE_SUPPORT_ALPHA - - // use our bitmap info structure to fill in first part of - // our DIB with the BITMAPINFOHEADER - BITMAPINFOHEADER* lpbi; - lpbi = (BITMAPINFOHEADER*)(pDib); - *lpbi = head; - - info.pImage=GetBits(); - - return pDib; //return handle to the DIB -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return pointer to the image pixels. USE CAREFULLY - */ -BYTE* CxImage::GetBits(DWORD row) -{ - if (pDib){ - if (row) { - if (row<(DWORD)head.biHeight){ - return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize() + (info.dwEffWidth * row)); - } else { - return NULL; - } - } else { - return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize()); - } - } - return NULL; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return the size in bytes of the internal pDib object - */ -long CxImage::GetSize() -{ - return head.biSize + head.biSizeImage + GetPaletteSize(); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the coordinates are inside the image - * \return true if x and y are both inside the image - */ -bool CxImage::IsInside(long x, long y) -{ - return (0<=y && y 0) bval = 255; - } - if (GetBpp() == 4){ - bval = (BYTE)(17*(0x0F & bval)); - } - - memset(info.pImage,bval,head.biSizeImage); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Transfers the image from an existing source image. The source becomes empty. - * \return true if everything is ok - */ -bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/) -{ - if (!Destroy()) - return false; - - memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER)); - memcpy(&info,&from.info,sizeof(CXIMAGEINFO)); - - pDib = from.pDib; - pSelection = from.pSelection; - pAlpha = from.pAlpha; - ppLayers = from.ppLayers; - - memset(&from.head,0,sizeof(BITMAPINFOHEADER)); - memset(&from.info,0,sizeof(CXIMAGEINFO)); - from.pDib = from.pSelection = from.pAlpha = NULL; - from.ppLayers = NULL; - - if (bTransferFrames){ - DestroyFrames(); - ppFrames = from.ppFrames; - from.ppFrames = NULL; - } - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * (this) points to the same pDib owned by (*from), the image remains in (*from) - * but (this) has the access to the pixels. Use carefully !!! - */ -void CxImage::Ghost(const CxImage *from) -{ - if (from){ - memcpy(&head,&from->head,sizeof(BITMAPINFOHEADER)); - memcpy(&info,&from->info,sizeof(CXIMAGEINFO)); - pDib = from->pDib; - pSelection = from->pSelection; - pAlpha = from->pAlpha; - ppLayers = from->ppLayers; - ppFrames = from->ppFrames; - info.pGhost=(CxImage *)from; - } -} -//////////////////////////////////////////////////////////////////////////////// -/** - * turns a 16 or 32 bit bitfield image into a RGB image - */ -void CxImage::Bitfield2RGB(BYTE *src, DWORD redmask, DWORD greenmask, DWORD bluemask, BYTE bpp) -{ - switch (bpp){ - case 16: - { - DWORD ns[3]={0,0,0}; - // compute the number of shift for each mask - for (int i=0;i<16;i++){ - if ((redmask>>i)&0x01) ns[0]++; - if ((greenmask>>i)&0x01) ns[1]++; - if ((bluemask>>i)&0x01) ns[2]++; - } - ns[1]+=ns[0]; ns[2]+=ns[1]; ns[0]=8-ns[0]; ns[1]-=8; ns[2]-=8; - // dword aligned width for 16 bit image - long effwidth2=(((head.biWidth + 1) / 2) * 4); - WORD w; - long y2,y3,x2,x3; - BYTE *p=info.pImage; - // scan the buffer in reverse direction to avoid reallocations - for (long y=head.biHeight-1; y>=0; y--){ - y2=effwidth2*y; - y3=info.dwEffWidth*y; - for (long x=head.biWidth-1; x>=0; x--){ - x2 = 2*x+y2; - x3 = 3*x+y3; - w = (WORD)(src[x2]+256*src[1+x2]); - p[ x3]=(BYTE)((w & bluemask)<>ns[1]); - p[2+x3]=(BYTE)((w & redmask)>>ns[2]); - } - } - break; - } - case 32: - { - DWORD ns[3]={0,0,0}; - // compute the number of shift for each mask - for (int i=8;i<32;i+=8){ - if (redmask>>i) ns[0]++; - if (greenmask>>i) ns[1]++; - if (bluemask>>i) ns[2]++; - } - // dword aligned width for 32 bit image - long effwidth4 = head.biWidth * 4; - long y4,y3,x4,x3; - BYTE *p=info.pImage; - // scan the buffer in reverse direction to avoid reallocations - for (long y=head.biHeight-1; y>=0; y--){ - y4=effwidth4*y; - y3=info.dwEffWidth*y; - for (long x=head.biWidth-1; x>=0; x--){ - x4 = 4*x+y4; - x3 = 3*x+y3; - p[ x3]=src[ns[2]+x4]; - p[1+x3]=src[ns[1]+x4]; - p[2+x3]=src[ns[0]+x4]; - } - } - } - - } - return; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Creates an image from a generic buffer - * \param pArray: source memory buffer - * \param dwWidth: image width - * \param dwHeight: image height - * \param dwBitsperpixel: can be 1,4,8,24,32 - * \param dwBytesperline: line alignment, in bytes, for a single row stored in pArray - * \param bFlipImage: tune this parameter if the image is upsidedown - * \return true if everything is ok - */ -bool CxImage::CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage) -{ - if (pArray==NULL) return false; - if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)|| - (dwBitsperpixel==24)||(dwBitsperpixel==32))) return false; - - if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false; - - if (dwBitsperpixel<24) SetGrayPalette(); - -#if CXIMAGE_SUPPORT_ALPHA - if (dwBitsperpixel==32) AlphaCreate(); -#endif //CXIMAGE_SUPPORT_ALPHA - - BYTE *dst,*src; - - for (DWORD y = 0; yrgbRed,c1->rgbGreen,c1->rgbBlue); - int g2 = (int)RGB2GRAY(c2->rgbRed,c2->rgbGreen,c2->rgbBlue); - - return (g1-g2); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * simply calls "if (memblock) free(memblock);". - * Useful when calling Encode for a memory buffer, - * from a DLL compiled with different memory management options. - * CxImage::FreeMemory will use the same memory environment used by Encode. - * \author [livecn] - */ -void CxImage::FreeMemory(void* memblock) -{ - if (memblock) - cxfree(memblock);//free(memblock); -} -//////////////////////////////////////////////////////////////////////////////// -//EOF diff --git a/Externals/cximage/ximage.h b/Externals/cximage/ximage.h deleted file mode 100644 index 52c3617258c..00000000000 --- a/Externals/cximage/ximage.h +++ /dev/null @@ -1,735 +0,0 @@ -/* - * File: ximage.h - * Purpose: General Purpose Image Class - */ -/* - -------------------------------------------------------------------------------- - - COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - - CxImage version 6.0.0 02/Feb/2008 - - CxImage : Copyright (C) 2001 - 2008, Davide Pizzolato - - Original CImage and CImageIterator implementation are: - Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx) - - Covered code is provided under this license on an "as is" basis, without warranty - of any kind, either expressed or implied, including, without limitation, warranties - that the covered code is free of defects, merchantable, fit for a particular purpose - or non-infringing. The entire risk as to the quality and performance of the covered - code is with you. Should any covered code prove defective in any respect, you (not - the initial developer or any other contributor) assume the cost of any necessary - servicing, repair or correction. This disclaimer of warranty constitutes an essential - part of this license. No use of any covered code is authorized hereunder except under - this disclaimer. - - Permission is hereby granted to use, copy, modify, and distribute this - source code, or portions hereof, for any purpose, including commercial applications, - freely and without fee, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - - -------------------------------------------------------------------------------- - - Other information about CxImage, and the latest version, can be found at the - CxImage home page: http://www.xdp.it/cximage/ - - -------------------------------------------------------------------------------- - */ -#if !defined(__CXIMAGE_H) -#define __CXIMAGE_H - -#if _MSC_VER > 1000 -#pragma once -#endif - -///////////////////////////////////////////////////////////////////////////// -#include "xfile.h" -#include "xiofile.h" -#include "xmemfile.h" -#include "ximadef.h" // adjust some #define - -/* see "ximacfg.h" for CxImage configuration options */ - -///////////////////////////////////////////////////////////////////////////// -// CxImage formats enumerator -enum ENUM_CXIMAGE_FORMATS{ -CXIMAGE_FORMAT_UNKNOWN = 0, -#if CXIMAGE_SUPPORT_BMP -CXIMAGE_FORMAT_BMP = 1, -#endif -#if CXIMAGE_SUPPORT_GIF -CXIMAGE_FORMAT_GIF = 2, -#endif -#if CXIMAGE_SUPPORT_JPG -CXIMAGE_FORMAT_JPG = 3, -#endif -#if CXIMAGE_SUPPORT_PNG -CXIMAGE_FORMAT_PNG = 4, -#endif -#if CXIMAGE_SUPPORT_ICO -CXIMAGE_FORMAT_ICO = 5, -#endif -#if CXIMAGE_SUPPORT_TIF -CXIMAGE_FORMAT_TIF = 6, -#endif -#if CXIMAGE_SUPPORT_TGA -CXIMAGE_FORMAT_TGA = 7, -#endif -#if CXIMAGE_SUPPORT_PCX -CXIMAGE_FORMAT_PCX = 8, -#endif -#if CXIMAGE_SUPPORT_WBMP -CXIMAGE_FORMAT_WBMP = 9, -#endif -#if CXIMAGE_SUPPORT_WMF -CXIMAGE_FORMAT_WMF = 10, -#endif -#if CXIMAGE_SUPPORT_JP2 -CXIMAGE_FORMAT_JP2 = 11, -#endif -#if CXIMAGE_SUPPORT_JPC -CXIMAGE_FORMAT_JPC = 12, -#endif -#if CXIMAGE_SUPPORT_PGX -CXIMAGE_FORMAT_PGX = 13, -#endif -#if CXIMAGE_SUPPORT_PNM -CXIMAGE_FORMAT_PNM = 14, -#endif -#if CXIMAGE_SUPPORT_RAS -CXIMAGE_FORMAT_RAS = 15, -#endif -#if CXIMAGE_SUPPORT_JBG -CXIMAGE_FORMAT_JBG = 16, -#endif -#if CXIMAGE_SUPPORT_MNG -CXIMAGE_FORMAT_MNG = 17, -#endif -#if CXIMAGE_SUPPORT_SKA -CXIMAGE_FORMAT_SKA = 18, -#endif -#if CXIMAGE_SUPPORT_RAW -CXIMAGE_FORMAT_RAW = 19, -#endif -CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG + - CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO + - CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX + - CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF + - CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC + - CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS + - CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + 1 -}; - -///////////////////////////////////////////////////////////////////////////// -// CxImage class -///////////////////////////////////////////////////////////////////////////// -class DLL_EXP CxImage -{ -//extensible information collector -typedef struct tagCxImageInfo { - DWORD dwEffWidth; ///< DWORD aligned scan line width - BYTE* pImage; ///< THE IMAGE BITS - CxImage* pGhost; ///< if this is a ghost, pGhost points to the body - CxImage* pParent; ///< if this is a layer, pParent points to the body - DWORD dwType; ///< original image format - char szLastError[256]; ///< debugging - long nProgress; ///< monitor - long nEscape; ///< escape - long nBkgndIndex; ///< used for GIF, PNG, MNG - RGBQUAD nBkgndColor; ///< used for RGB transparency - float fQuality; ///< used for JPEG, JPEG2000 (0.0f ... 100.0f) - BYTE nJpegScale; ///< used for JPEG [ignacio] - long nFrame; ///< used for TIF, GIF, MNG : actual frame - long nNumFrames; ///< used for TIF, GIF, MNG : total number of frames - DWORD dwFrameDelay; ///< used for GIF, MNG - long xDPI; ///< horizontal resolution - long yDPI; ///< vertical resolution - RECT rSelectionBox; ///< bounding rectangle - BYTE nAlphaMax; ///< max opacity (fade) - bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled. - bool bEnabled; ///< enables the painting functions - long xOffset; - long yOffset; - DWORD dwCodecOpt[CMAX_IMAGE_FORMATS]; ///< for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg - RGBQUAD last_c; ///< for GetNearestIndex optimization - BYTE last_c_index; - bool last_c_isvalid; - long nNumLayers; - DWORD dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags - BYTE dispmeth; - bool bGetAllFrames; - bool bLittleEndianHost; - -} CXIMAGEINFO; - -public: - //public structures -struct rgb_color { BYTE r,g,b; }; - -#if CXIMAGE_SUPPORT_WINDOWS -// text placement data -// members must be initialized with the InitTextInfo(&this) function. -typedef struct tagCxTextInfo -{ -#if defined (_WIN32_WCE) - TCHAR text[256]; ///< text for windows CE -#else - TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M]) -#endif - LOGFONT lfont; ///< font and codepage data - COLORREF fcolor; ///< foreground color - long align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text - BYTE smooth; ///< text smoothing option. Default is false. - BYTE opaque; ///< text has background or hasn't. Default is true. - ///< data for background (ignored if .opaque==FALSE) - COLORREF bcolor; ///< background color - float b_opacity; ///< opacity value for background between 0.0-1.0 Default is 0. (opaque) - BYTE b_outline; ///< outline width for background (zero: no outline) - BYTE b_round; ///< rounding radius for background rectangle. % of the height, between 0-50. Default is 10. - ///< (backgr. always has a frame: width = 3 pixel + 10% of height by default.) -} CXTEXTINFO; -#endif - -public: -/** \addtogroup Constructors */ //@{ - CxImage(DWORD imagetype = 0); - CxImage(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0); - CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true); - CxImage(const TCHAR * filename, DWORD imagetype); // For UNICODE support: char -> TCHAR - CxImage(FILE * stream, DWORD imagetype); - CxImage(CxFile * stream, DWORD imagetype); - CxImage(BYTE * buffer, DWORD size, DWORD imagetype); - virtual ~CxImage() { DestroyFrames(); Destroy(); }; - CxImage& operator = (const CxImage&); -//@} - -/** \addtogroup Initialization */ //@{ - void* Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0); - bool Destroy(); - bool DestroyFrames(); - void Clear(BYTE bval=0); - void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true); - bool Transfer(CxImage &from, bool bTransferFrames = true); - bool CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage); - bool CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage); - void FreeMemory(void* memblock); - - DWORD Dump(BYTE * dst); - DWORD UnDump(const BYTE * src); - DWORD DumpSize(); - -//@} - -/** \addtogroup Attributes */ //@{ - long GetSize(); - BYTE* GetBits(DWORD row = 0); - BYTE GetColorType(); - void* GetDIB() const; - DWORD GetHeight() const; - DWORD GetWidth() const; - DWORD GetEffWidth() const; - DWORD GetNumColors() const; - WORD GetBpp() const; - DWORD GetType() const; - const char* GetLastError(); - static const TCHAR* GetVersion(); - static const float GetVersionNumber(); - - DWORD GetFrameDelay() const; - void SetFrameDelay(DWORD d); - - void GetOffset(long *x,long *y); - void SetOffset(long x,long y); - - BYTE GetJpegQuality() const; - void SetJpegQuality(BYTE q); - float GetJpegQualityF() const; - void SetJpegQualityF(float q); - - BYTE GetJpegScale() const; - void SetJpegScale(BYTE q); - - long GetXDPI() const; - long GetYDPI() const; - void SetXDPI(long dpi); - void SetYDPI(long dpi); - - DWORD GetClrImportant() const; - void SetClrImportant(DWORD ncolors = 0); - - long GetProgress() const; - long GetEscape() const; - void SetProgress(long p); - void SetEscape(long i); - - long GetTransIndex() const; - RGBQUAD GetTransColor(); - void SetTransIndex(long idx); - void SetTransColor(RGBQUAD rgb); - bool IsTransparent() const; - - DWORD GetCodecOption(DWORD imagetype = 0); - bool SetCodecOption(DWORD opt, DWORD imagetype = 0); - - DWORD GetFlags() const; - void SetFlags(DWORD flags, bool bLockReservedFlags = true); - - BYTE GetDisposalMethod() const; - void SetDisposalMethod(BYTE dm); - - bool SetType(DWORD type); - - static DWORD GetNumTypes(); - static DWORD GetTypeIdFromName(const TCHAR* ext); - static DWORD GetTypeIdFromIndex(const DWORD index); - static DWORD GetTypeIndexFromId(const DWORD id); - - bool GetRetreiveAllFrames() const; - void SetRetreiveAllFrames(bool flag); - CxImage * GetFrame(long nFrame) const; - - //void* GetUserData() const {return info.pUserData;} - //void SetUserData(void* pUserData) {info.pUserData = pUserData;} -//@} - -/** \addtogroup Palette - * These functions have no effects on RGB images and in this case the returned value is always 0. - * @{ */ - bool IsGrayScale(); - bool IsIndexed() const; - bool IsSamePalette(CxImage &img, bool bCheckAlpha = true); - DWORD GetPaletteSize(); - RGBQUAD* GetPalette() const; - RGBQUAD GetPaletteColor(BYTE idx); - bool GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b); - BYTE GetNearestIndex(RGBQUAD c); - void BlendPalette(COLORREF cr,long perc); - void SetGrayPalette(); - void SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b); - void SetPalette(RGBQUAD* pPal,DWORD nColors=256); - void SetPalette(rgb_color *rgb,DWORD nColors=256); - void SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha=0); - void SetPaletteColor(BYTE idx, RGBQUAD c); - void SetPaletteColor(BYTE idx, COLORREF cr); - void SwapIndex(BYTE idx1, BYTE idx2); - void SwapRGB2BGR(); - void SetStdPalette(); -//@} - -/** \addtogroup Pixel */ //@{ - bool IsInside(long x, long y); - bool IsTransparent(long x,long y); - bool GetTransparentMask(CxImage* iDst = 0); - RGBQUAD GetPixelColor(long x,long y, bool bGetAlpha = true); - BYTE GetPixelIndex(long x,long y); - BYTE GetPixelGray(long x, long y); - void SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false); - void SetPixelColor(long x,long y,COLORREF cr); - void SetPixelIndex(long x,long y,BYTE i); - void DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha=false); - void DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr); - void BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha = false); -//@} - -protected: -/** \addtogroup Protected */ //@{ - BYTE BlindGetPixelIndex(const long x,const long y); - RGBQUAD BlindGetPixelColor(const long x,const long y, bool bGetAlpha = true); - void *BlindGetPixelPointer(const long x,const long y); - void BlindSetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false); - void BlindSetPixelIndex(long x,long y,BYTE i); -//@} - -public: - -#if CXIMAGE_SUPPORT_INTERPOLATION -/** \addtogroup Interpolation */ //@{ - //overflow methods: - enum OverflowMethod { - OM_COLOR=1, - OM_BACKGROUND=2, - OM_TRANSPARENT=3, - OM_WRAP=4, - OM_REPEAT=5, - OM_MIRROR=6 - }; - void OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod); - void OverflowCoordinates(long &x, long &y, OverflowMethod const ofMethod); - RGBQUAD GetPixelColorWithOverflow(long x, long y, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); - //interpolation methods: - enum InterpolationMethod { - IM_NEAREST_NEIGHBOUR=1, - IM_BILINEAR =2, - IM_BSPLINE =3, - IM_BICUBIC =4, - IM_BICUBIC2 =5, - IM_LANCZOS =6, - IM_BOX =7, - IM_HERMITE =8, - IM_HAMMING =9, - IM_SINC =10, - IM_BLACKMAN =11, - IM_BESSEL =12, - IM_GAUSSIAN =13, - IM_QUADRATIC =14, - IM_MITCHELL =15, - IM_CATROM =16, - IM_HANNING =17, - IM_POWER =18 - }; - RGBQUAD GetPixelColorInterpolated(float x,float y, InterpolationMethod const inMethod=IM_BILINEAR, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); - RGBQUAD GetAreaColorInterpolated(float const xc, float const yc, float const w, float const h, InterpolationMethod const inMethod, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); -//@} - -protected: -/** \addtogroup Protected */ //@{ - void AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa); -//@} - -/** \addtogroup Kernels */ //@{ -public: - static float KernelBSpline(const float x); - static float KernelLinear(const float t); - static float KernelCubic(const float t); - static float KernelGeneralizedCubic(const float t, const float a=-1); - static float KernelLanczosSinc(const float t, const float r = 3); - static float KernelBox(const float x); - static float KernelHermite(const float x); - static float KernelHamming(const float x); - static float KernelSinc(const float x); - static float KernelBlackman(const float x); - static float KernelBessel_J1(const float x); - static float KernelBessel_P1(const float x); - static float KernelBessel_Q1(const float x); - static float KernelBessel_Order1(float x); - static float KernelBessel(const float x); - static float KernelGaussian(const float x); - static float KernelQuadratic(const float x); - static float KernelMitchell(const float x); - static float KernelCatrom(const float x); - static float KernelHanning(const float x); - static float KernelPower(const float x, const float a = 2); -//@} -#endif //CXIMAGE_SUPPORT_INTERPOLATION - -/** \addtogroup Painting */ //@{ -#if CXIMAGE_SUPPORT_WINDOWS - long Blt(HDC pDC, long x=0, long y=0); - HBITMAP MakeBitmap(HDC hdc = NULL); - HANDLE CopyToHandle(); - bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard) - bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0); //Windows resource - bool CreateFromHICON(HICON hico); - long Draw(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false); - long Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false); - long Stretch(HDC hdc, long xoffset, long yoffset, long xsize, long ysize, DWORD dwRop = SRCCOPY); - long Stretch(HDC hdc, const RECT& rect, DWORD dwRop = SRCCOPY); - long Tile(HDC hdc, RECT *rc); - long Draw2(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1); - long Draw2(HDC hdc, const RECT& rect); - //long DrawString(HDC hdc, long x, long y, const char* text, RGBQUAD color, const char* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false); - long DrawString(HDC hdc, long x, long y, const TCHAR* text, RGBQUAD color, const TCHAR* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false); - // extensions - long DrawStringEx(HDC hdc, long x, long y, CXTEXTINFO *pTextType, bool bSetAlpha=false ); - void InitTextInfo( CXTEXTINFO *txt ); -#endif //CXIMAGE_SUPPORT_WINDOWS -//@} - - // file operations -#if CXIMAGE_SUPPORT_DECODE -/** \addtogroup Decode */ //@{ -#ifdef WIN32 - //bool Load(LPCWSTR filename, DWORD imagetype=0); - bool LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule=NULL); -#endif - // For UNICODE support: char -> TCHAR - bool Load(const TCHAR* filename, DWORD imagetype=0); - //bool Load(const char * filename, DWORD imagetype=0); - bool Decode(FILE * hFile, DWORD imagetype); - bool Decode(CxFile * hFile, DWORD imagetype); - bool Decode(BYTE * buffer, DWORD size, DWORD imagetype); - - bool CheckFormat(CxFile * hFile, DWORD imagetype = 0); - bool CheckFormat(BYTE * buffer, DWORD size, DWORD imagetype = 0); -//@} -#endif //CXIMAGE_SUPPORT_DECODE - -#if CXIMAGE_SUPPORT_ENCODE -protected: -/** \addtogroup Protected */ //@{ - bool EncodeSafeCheck(CxFile *hFile); -//@} - -public: -/** \addtogroup Encode */ //@{ -#ifdef WIN32 - //bool Save(LPCWSTR filename, DWORD imagetype=0); -#endif - // For UNICODE support: char -> TCHAR - bool Save(const TCHAR* filename, DWORD imagetype); - //bool Save(const char * filename, DWORD imagetype=0); - bool Encode(FILE * hFile, DWORD imagetype); - bool Encode(CxFile * hFile, DWORD imagetype); - bool Encode(CxFile * hFile, CxImage ** pImages, int pagecount, DWORD imagetype); - bool Encode(FILE *hFile, CxImage ** pImages, int pagecount, DWORD imagetype); - bool Encode(BYTE * &buffer, long &size, DWORD imagetype); - - bool Encode2RGBA(CxFile *hFile, bool bFlipY = false); - bool Encode2RGBA(BYTE * &buffer, long &size, bool bFlipY = false); -//@} -#endif //CXIMAGE_SUPPORT_ENCODE - -/** \addtogroup Attributes */ //@{ - //misc. - bool IsValid() const; - bool IsEnabled() const; - void Enable(bool enable=true); - - // frame operations - long GetNumFrames() const; - long GetFrame() const; - void SetFrame(long nFrame); -//@} - -#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS -/** \addtogroup BasicTransformations */ //@{ - bool GrayScale(); - bool Flip(bool bFlipSelection = false, bool bFlipAlpha = true); - bool Mirror(bool bMirrorSelection = false, bool bMirrorAlpha = true); - bool Negative(); - bool RotateLeft(CxImage* iDst = NULL); - bool RotateRight(CxImage* iDst = NULL); -//@} -#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS - -#if CXIMAGE_SUPPORT_TRANSFORMATION -/** \addtogroup Transformations */ //@{ - // image operations - bool Rotate(float angle, CxImage* iDst = NULL); - bool Rotate2(float angle, CxImage *iDst = NULL, InterpolationMethod inMethod=IM_BILINEAR, - OverflowMethod ofMethod=OM_BACKGROUND, RGBQUAD *replColor=0, - bool const optimizeRightAngles=true, bool const bKeepOriginalSize=false); - bool Rotate180(CxImage* iDst = NULL); - bool Resample(long newx, long newy, int mode = 1, CxImage* iDst = NULL); - bool Resample2(long newx, long newy, InterpolationMethod const inMethod=IM_BICUBIC2, - OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL, - bool const disableAveraging=false); - bool DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal = 0, DWORD clrimportant = 0); - bool IncreaseBpp(DWORD nbit); - bool Dither(long method = 0); - bool Crop(long left, long top, long right, long bottom, CxImage* iDst = NULL); - bool Crop(const RECT& rect, CxImage* iDst = NULL); - bool CropRotatedRectangle( long topx, long topy, long width, long height, float angle, CxImage* iDst = NULL); - bool Skew(float xgain, float ygain, long xpivot=0, long ypivot=0, bool bEnableInterpolation = false); - bool Expand(long left, long top, long right, long bottom, RGBQUAD canvascolor, CxImage* iDst = 0); - bool Expand(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0); - bool Thumbnail(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0); - bool CircleTransform(int type,long rmax=0,float Koeff=1.0f); - bool RedEyeRemove(float strength = 0.8f); - bool QIShrink(long newx, long newy, CxImage* const iDst = NULL, bool bChangeBpp = false); - -//@} -#endif //CXIMAGE_SUPPORT_TRANSFORMATION - -#if CXIMAGE_SUPPORT_DSP -/** \addtogroup DSP */ //@{ - bool Contour(); - bool HistogramStretch(long method = 0, double threshold = 0); - bool HistogramEqualize(); - bool HistogramNormalize(); - bool HistogramRoot(); - bool HistogramLog(); - long Histogram(long* red, long* green = 0, long* blue = 0, long* gray = 0, long colorspace = 0); - bool Jitter(long radius=2); - bool Repair(float radius = 0.25f, long niterations = 1, long colorspace = 0); - bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, long colorspace = 0); - bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, long direction = 1, bool bForceFFT = true, bool bMagnitude = true); - bool Noise(long level); - bool Median(long Ksize=3); - bool Gamma(float gamma); - bool GammaRGB(float gammaR, float gammaG, float gammaB); - bool ShiftRGB(long r, long g, long b); - bool Threshold(BYTE level); - bool Threshold(CxImage* pThresholdMask); - bool Threshold2(BYTE level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha = false); - bool Colorize(BYTE hue, BYTE sat, float blend = 1.0f); - bool Light(long brightness, long contrast = 0); - float Mean(); - bool Filter(long* kernel, long Ksize, long Kfactor, long Koffset); - bool Erode(long Ksize=2); - bool Dilate(long Ksize=2); - bool Edge(long Ksize=2); - void HuePalette(float correction=1); - enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen, OpAvg }; - void Mix(CxImage & imgsrc2, ImageOpType op, long lXOffset = 0, long lYOffset = 0, bool bMixAlpha = false); - void MixFrom(CxImage & imagesrc2, long lXOffset, long lYOffset); - bool UnsharpMask(float radius = 5.0f, float amount = 0.5f, int threshold = 0); - bool Lut(BYTE* pLut); - bool Lut(BYTE* pLutR, BYTE* pLutG, BYTE* pLutB, BYTE* pLutA = 0); - bool GaussianBlur(float radius = 1.0f, CxImage* iDst = 0); - bool TextBlur(BYTE threshold = 100, BYTE decay = 2, BYTE max_depth = 5, bool bBlurHorizontal = true, bool bBlurVertical = true, CxImage* iDst = 0); - bool SelectiveBlur(float radius = 1.0f, BYTE threshold = 25, CxImage* iDst = 0); - bool Solarize(BYTE level = 128, bool bLinkedChannels = true); - bool FloodFill(const long xStart, const long yStart, const RGBQUAD cFillColor, const BYTE tolerance = 0, - BYTE nOpacity = 255, const bool bSelectFilledArea = false, const BYTE nSelectionLevel = 255); - bool Saturate(const long saturation, const long colorspace = 1); - bool ConvertColorSpace(const long dstColorSpace, const long srcColorSpace); - int OptimalThreshold(long method = 0, RECT * pBox = 0, CxImage* pContrastMask = 0); - bool AdaptiveThreshold(long method = 0, long nBoxSize = 64, CxImage* pContrastMask = 0, long nBias = 0, float fGlobalLocalBalance = 0.5f); - -//@} - -protected: -/** \addtogroup Protected */ //@{ - bool IsPowerof2(long x); - bool FFT(int dir,int m,double *x,double *y); - bool DFT(int dir,long m,double *x1,double *y1,double *x2,double *y2); - bool RepairChannel(CxImage *ch, float radius); - // - int gen_convolve_matrix (float radius, float **cmatrix_p); - float* gen_lookup_table (float *cmatrix, int cmatrix_length); - void blur_line (float *ctable, float *cmatrix, int cmatrix_length, BYTE* cur_col, BYTE* dest_col, int y, long bytes); - void blur_text (BYTE threshold, BYTE decay, BYTE max_depth, CxImage* iSrc, CxImage* iDst, BYTE bytes); -//@} - -public: -/** \addtogroup ColorSpace */ //@{ - bool SplitRGB(CxImage* r,CxImage* g,CxImage* b); - bool SplitYUV(CxImage* y,CxImage* u,CxImage* v); - bool SplitHSL(CxImage* h,CxImage* s,CxImage* l); - bool SplitYIQ(CxImage* y,CxImage* i,CxImage* q); - bool SplitXYZ(CxImage* x,CxImage* y,CxImage* z); - bool SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k); - static RGBQUAD HSLtoRGB(COLORREF cHSLColor); - static RGBQUAD RGBtoHSL(RGBQUAD lRGBColor); - static RGBQUAD HSLtoRGB(RGBQUAD lHSLColor); - static RGBQUAD YUVtoRGB(RGBQUAD lYUVColor); - static RGBQUAD RGBtoYUV(RGBQUAD lRGBColor); - static RGBQUAD YIQtoRGB(RGBQUAD lYIQColor); - static RGBQUAD RGBtoYIQ(RGBQUAD lRGBColor); - static RGBQUAD XYZtoRGB(RGBQUAD lXYZColor); - static RGBQUAD RGBtoXYZ(RGBQUAD lRGBColor); -#endif //CXIMAGE_SUPPORT_DSP - static RGBQUAD RGBtoRGBQUAD(COLORREF cr); - static COLORREF RGBQUADtoRGB (RGBQUAD c); -//@} - -#if CXIMAGE_SUPPORT_SELECTION -/** \addtogroup Selection */ //@{ - bool SelectionClear(BYTE level = 0); - bool SelectionCreate(); - bool SelectionDelete(); - bool SelectionInvert(); - bool SelectionMirror(); - bool SelectionFlip(); - bool SelectionAddRect(RECT r, BYTE level = 255); - bool SelectionAddEllipse(RECT r, BYTE level = 255); - bool SelectionAddPolygon(POINT *points, long npoints, BYTE level = 255); - bool SelectionAddColor(RGBQUAD c, BYTE level = 255); - bool SelectionAddPixel(long x, long y, BYTE level = 255); - bool SelectionCopy(CxImage &from); - bool SelectionIsInside(long x, long y); - bool SelectionIsValid(); - void SelectionGetBox(RECT& r); - bool SelectionToHRGN(HRGN& region); - bool SelectionSplit(CxImage *dest); - BYTE SelectionGet(const long x,const long y); - bool SelectionSet(CxImage &from); - void SelectionRebuildBox(); - BYTE* SelectionGetPointer(const long x = 0,const long y = 0); -//@} - -protected: -/** \addtogroup Protected */ //@{ - bool BlindSelectionIsInside(long x, long y); - BYTE BlindSelectionGet(const long x,const long y); - void SelectionSet(const long x,const long y,const BYTE level); -//@} - -public: - -#endif //CXIMAGE_SUPPORT_SELECTION - -#if CXIMAGE_SUPPORT_ALPHA -/** \addtogroup Alpha */ //@{ - void AlphaClear(); - bool AlphaCreate(); - void AlphaDelete(); - void AlphaInvert(); - bool AlphaMirror(); - bool AlphaFlip(); - bool AlphaCopy(CxImage &from); - bool AlphaSplit(CxImage *dest); - void AlphaStrip(); - void AlphaSet(BYTE level); - bool AlphaSet(CxImage &from); - void AlphaSet(const long x,const long y,const BYTE level); - BYTE AlphaGet(const long x,const long y); - BYTE AlphaGetMax() const; - void AlphaSetMax(BYTE nAlphaMax); - bool AlphaIsValid(); - BYTE* AlphaGetPointer(const long x = 0,const long y = 0); - bool AlphaFromTransparency(); - - void AlphaPaletteClear(); - void AlphaPaletteEnable(bool enable=true); - bool AlphaPaletteIsEnabled(); - bool AlphaPaletteIsValid(); - bool AlphaPaletteSplit(CxImage *dest); -//@} - -protected: -/** \addtogroup Protected */ //@{ - BYTE BlindAlphaGet(const long x,const long y); -//@} -#endif //CXIMAGE_SUPPORT_ALPHA - -public: -#if CXIMAGE_SUPPORT_LAYERS -/** \addtogroup Layers */ //@{ - bool LayerCreate(long position = -1); - bool LayerDelete(long position = -1); - void LayerDeleteAll(); - CxImage* GetLayer(long position); - CxImage* GetParent() const; - long GetNumLayers() const; - long LayerDrawAll(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false); - long LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false); -//@} -#endif //CXIMAGE_SUPPORT_LAYERS - -protected: -/** \addtogroup Protected */ //@{ - void Startup(DWORD imagetype = 0); - void CopyInfo(const CxImage &src); - void Ghost(const CxImage *src); - void RGBtoBGR(BYTE *buffer, int length); - static float HueToRGB(float n1,float n2, float hue); - void Bitfield2RGB(BYTE *src, DWORD redmask, DWORD greenmask, DWORD bluemask, BYTE bpp); - static int CompareColors(const void *elem1, const void *elem2); - short cx_ntohs(const short word); - long cx_ntohl(const long dword); - void cx_bihtoh(BITMAPINFOHEADER* bih); - - void* pDib; //contains the header, the palette, the pixels - BITMAPINFOHEADER head; //standard header - CXIMAGEINFO info; //extended information - BYTE* pSelection; //selected region - BYTE* pAlpha; //alpha channel - CxImage** ppLayers; //generic layers - CxImage** ppFrames; -//@} -}; - -//////////////////////////////////////////////////////////////////////////// -#endif // !defined(__CXIMAGE_H) diff --git a/Externals/cximage/ximainfo.cpp b/Externals/cximage/ximainfo.cpp deleted file mode 100644 index 3b6c20b031e..00000000000 --- a/Externals/cximage/ximainfo.cpp +++ /dev/null @@ -1,929 +0,0 @@ -// ximainfo.cpp : main attributes -/* 03/10/2004 v1.00 - Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -#if defined(WIN32) || defined(_WIN32_WCE) -#include -#else -#define _tcsnicmp(a,b,c) strcasecmp(a,b) -#define _T(x) x -#endif - -//////////////////////////////////////////////////////////////////////////////// -/** - * \return the color used for transparency, and/or for background color - */ -RGBQUAD CxImage::GetTransColor() -{ - if (head.biBitCount<24 && info.nBkgndIndex>=0) return GetPaletteColor((BYTE)info.nBkgndIndex); - return info.nBkgndColor; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Gets the index used for transparency. Returns -1 for no transparancy. - */ -long CxImage::GetTransIndex() const -{ - return info.nBkgndIndex; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the index used for transparency with 1, 4 and 8 bpp images. Set to -1 to remove the effect. - */ -void CxImage::SetTransIndex(long idx) -{ - if (idx<(long)head.biClrUsed) - info.nBkgndIndex = idx; - else - info.nBkgndIndex = 0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the color used for transparency with 24 bpp images. - * You must call SetTransIndex(0) to enable the effect, SetTransIndex(-1) to disable it. - */ -void CxImage::SetTransColor(RGBQUAD rgb) -{ - rgb.rgbReserved=0; - info.nBkgndColor = rgb; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::IsTransparent() const -{ - return info.nBkgndIndex>=0; // -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Returns true if the image has 256 colors or less. - */ -bool CxImage::IsIndexed() const -{ - return head.biClrUsed!=0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return 1 = indexed, 2 = RGB, 4 = RGBA - */ -BYTE CxImage::GetColorType() -{ - BYTE b = (BYTE)((head.biBitCount>8) ? 2 /*COLORTYPE_COLOR*/ : 1 /*COLORTYPE_PALETTE*/); -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) b = 4 /*COLORTYPE_ALPHA*/; -#endif //CXIMAGE_SUPPORT_ALPHA - return b; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return Resolution for TIFF, JPEG, PNG and BMP formats. - */ -long CxImage::GetXDPI() const -{ - return info.xDPI; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return Resolution for TIFF, JPEG, PNG and BMP formats. - */ -long CxImage::GetYDPI() const -{ - return info.yDPI; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Set resolution for TIFF, JPEG, PNG and BMP formats. - */ -void CxImage::SetXDPI(long dpi) -{ - if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI; - info.xDPI = dpi; - head.biXPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5); - if (pDib) ((BITMAPINFOHEADER*)pDib)->biXPelsPerMeter = head.biXPelsPerMeter; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Set resolution for TIFF, JPEG, PNG and BMP formats. - */ -void CxImage::SetYDPI(long dpi) -{ - if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI; - info.yDPI = dpi; - head.biYPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5); - if (pDib) ((BITMAPINFOHEADER*)pDib)->biYPelsPerMeter = head.biYPelsPerMeter; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa SetFlags - */ -DWORD CxImage::GetFlags() const -{ - return info.dwFlags; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Image flags, for future use - * \param flags - * - 0x??00000 = reserved for 16 bit, CMYK, multilayer - * - 0x00??0000 = blend modes - * - 0x0000???? = layer id or user flags - * - * \param bLockReservedFlags protects the "reserved" and "blend modes" flags - */ -void CxImage::SetFlags(DWORD flags, bool bLockReservedFlags) -{ - if (bLockReservedFlags) info.dwFlags = flags & 0x0000ffff; - else info.dwFlags = flags; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa SetCodecOption - */ -DWORD CxImage::GetCodecOption(DWORD imagetype) -{ - imagetype = GetTypeIndexFromId(imagetype); - if (imagetype==0){ - imagetype = GetTypeIndexFromId(GetType()); - } - return info.dwCodecOpt[imagetype]; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Encode option for GIF, TIF and JPG. - * - GIF : 0 = LZW (default), 1 = none, 2 = RLE. - * - TIF : 0 = automatic (default), or a valid compression code as defined in "tiff.h" (COMPRESSION_NONE = 1, COMPRESSION_CCITTRLE = 2, ...) - * - JPG : valid values stored in enum CODEC_OPTION ( ENCODE_BASELINE = 0x01, ENCODE_PROGRESSIVE = 0x10, ...) - * - RAW : valid values stored in enum CODEC_OPTION ( DECODE_QUALITY_LIN = 0x00, DECODE_QUALITY_VNG = 0x01, ...) - * - * \return true if everything is ok - */ -bool CxImage::SetCodecOption(DWORD opt, DWORD imagetype) -{ - imagetype = GetTypeIndexFromId(imagetype); - if (imagetype==0){ - imagetype = GetTypeIndexFromId(GetType()); - } - info.dwCodecOpt[imagetype] = opt; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return internal hDib object.. - */ -void* CxImage::GetDIB() const -{ - return pDib; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetHeight() const -{ - return head.biHeight; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetWidth() const -{ - return head.biWidth; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return DWORD aligned width of the image. - */ -DWORD CxImage::GetEffWidth() const -{ - return info.dwEffWidth; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return 2, 16, 256; 0 for RGB images. - */ -DWORD CxImage::GetNumColors() const -{ - return head.biClrUsed; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return: 1, 4, 8, 24. - */ -WORD CxImage::GetBpp() const -{ - return head.biBitCount; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return original image format - * \sa ENUM_CXIMAGE_FORMATS. - */ -DWORD CxImage::GetType() const -{ - return info.dwType; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * change image format identifier - * \sa ENUM_CXIMAGE_FORMATS. - */ -bool CxImage::SetType(DWORD type) -{ - switch (type){ -#if CXIMAGE_SUPPORT_BMP - case CXIMAGE_FORMAT_BMP: -#endif -#if CXIMAGE_SUPPORT_GIF - case CXIMAGE_FORMAT_GIF: -#endif -#if CXIMAGE_SUPPORT_JPG - case CXIMAGE_FORMAT_JPG: -#endif -#if CXIMAGE_SUPPORT_PNG - case CXIMAGE_FORMAT_PNG: -#endif -#if CXIMAGE_SUPPORT_MNG - case CXIMAGE_FORMAT_MNG: -#endif -#if CXIMAGE_SUPPORT_ICO - case CXIMAGE_FORMAT_ICO: -#endif -#if CXIMAGE_SUPPORT_TIF - case CXIMAGE_FORMAT_TIF: -#endif -#if CXIMAGE_SUPPORT_TGA - case CXIMAGE_FORMAT_TGA: -#endif -#if CXIMAGE_SUPPORT_PCX - case CXIMAGE_FORMAT_PCX: -#endif -#if CXIMAGE_SUPPORT_WBMP - case CXIMAGE_FORMAT_WBMP: -#endif -#if CXIMAGE_SUPPORT_WMF - case CXIMAGE_FORMAT_WMF: -#endif -#if CXIMAGE_SUPPORT_JBG - case CXIMAGE_FORMAT_JBG: -#endif -#if CXIMAGE_SUPPORT_JP2 - case CXIMAGE_FORMAT_JP2: -#endif -#if CXIMAGE_SUPPORT_JPC - case CXIMAGE_FORMAT_JPC: -#endif -#if CXIMAGE_SUPPORT_PGX - case CXIMAGE_FORMAT_PGX: -#endif -#if CXIMAGE_SUPPORT_PNM - case CXIMAGE_FORMAT_PNM: -#endif -#if CXIMAGE_SUPPORT_RAS - case CXIMAGE_FORMAT_RAS: -#endif -#if CXIMAGE_SUPPORT_SKA - case CXIMAGE_FORMAT_SKA: -#endif -#if CXIMAGE_SUPPORT_RAW - case CXIMAGE_FORMAT_RAW: -#endif - info.dwType = type; - return true; - } - info.dwType = CXIMAGE_FORMAT_UNKNOWN; - return false; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetNumTypes() -{ - return CMAX_IMAGE_FORMATS-1; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetTypeIdFromName(const TCHAR* ext) -{ -#if CXIMAGE_SUPPORT_BMP - if (_tcsnicmp(ext,_T("bmp"),3)==0 ) return CXIMAGE_FORMAT_BMP; -#endif -#if CXIMAGE_SUPPORT_JPG - if (_tcsnicmp(ext,_T("jpg"),3)==0 || - _tcsnicmp(ext,_T("jpe"),3)==0 || - _tcsnicmp(ext,_T("jfi"),3)==0 ) return CXIMAGE_FORMAT_JPG; -#endif -#if CXIMAGE_SUPPORT_GIF - if (_tcsnicmp(ext,_T("gif"),3)==0 ) return CXIMAGE_FORMAT_GIF; -#endif -#if CXIMAGE_SUPPORT_PNG - if (_tcsnicmp(ext,_T("png"),3)==0 ) return CXIMAGE_FORMAT_PNG; -#endif -#if CXIMAGE_SUPPORT_ICO - if (_tcsnicmp(ext,_T("ico"),3)==0 || - _tcsnicmp(ext,_T("cur"),3)==0 ) return CXIMAGE_FORMAT_ICO; -#endif -#if CXIMAGE_SUPPORT_TIF - if (_tcsnicmp(ext,_T("tif"),3)==0 ) return CXIMAGE_FORMAT_TIF; -#endif -#if CXIMAGE_SUPPORT_TGA - if (_tcsnicmp(ext,_T("tga"),3)==0 ) return CXIMAGE_FORMAT_TGA; -#endif -#if CXIMAGE_SUPPORT_PCX - if (_tcsnicmp(ext,_T("pcx"),3)==0 ) return CXIMAGE_FORMAT_PCX; -#endif -#if CXIMAGE_SUPPORT_WBMP - if (_tcsnicmp(ext,_T("wbm"),3)==0 ) return CXIMAGE_FORMAT_WBMP; -#endif -#if CXIMAGE_SUPPORT_WMF - if (_tcsnicmp(ext,_T("wmf"),3)==0 || - _tcsnicmp(ext,_T("emf"),3)==0 ) return CXIMAGE_FORMAT_WMF; -#endif -#if CXIMAGE_SUPPORT_JP2 - if (_tcsnicmp(ext,_T("jp2"),3)==0 || - _tcsnicmp(ext,_T("j2k"),3)==0 ) return CXIMAGE_FORMAT_JP2; -#endif -#if CXIMAGE_SUPPORT_JPC - if (_tcsnicmp(ext,_T("jpc"),3)==0 || - _tcsnicmp(ext,_T("j2c"),3)==0 ) return CXIMAGE_FORMAT_JPC; -#endif -#if CXIMAGE_SUPPORT_PGX - if (_tcsnicmp(ext,_T("pgx"),3)==0 ) return CXIMAGE_FORMAT_PGX; -#endif -#if CXIMAGE_SUPPORT_RAS - if (_tcsnicmp(ext,_T("ras"),3)==0 ) return CXIMAGE_FORMAT_RAS; -#endif -#if CXIMAGE_SUPPORT_PNM - if (_tcsnicmp(ext,_T("pnm"),3)==0 || - _tcsnicmp(ext,_T("pgm"),3)==0 || - _tcsnicmp(ext,_T("ppm"),3)==0 ) return CXIMAGE_FORMAT_PNM; -#endif -#if CXIMAGE_SUPPORT_JBG - if (_tcsnicmp(ext,_T("jbg"),3)==0 ) return CXIMAGE_FORMAT_JBG; -#endif -#if CXIMAGE_SUPPORT_MNG - if (_tcsnicmp(ext,_T("mng"),3)==0 || - _tcsnicmp(ext,_T("jng"),3)==0 ) return CXIMAGE_FORMAT_MNG; -#endif -#if CXIMAGE_SUPPORT_SKA - if (_tcsnicmp(ext,_T("ska"),3)==0 ) return CXIMAGE_FORMAT_SKA; -#endif -#if CXIMAGE_SUPPORT_RAW - if (_tcsnicmp(ext,_T("nef"),3)==0 || - _tcsnicmp(ext,_T("crw"),3)==0 || - _tcsnicmp(ext,_T("cr2"),3)==0 || - _tcsnicmp(ext,_T("dng"),3)==0 || - _tcsnicmp(ext,_T("arw"),3)==0 || - _tcsnicmp(ext,_T("erf"),3)==0 || - _tcsnicmp(ext,_T("3fr"),3)==0 || - _tcsnicmp(ext,_T("dcr"),3)==0 || - _tcsnicmp(ext,_T("raw"),3)==0 || - _tcsnicmp(ext,_T("x3f"),3)==0 || - _tcsnicmp(ext,_T("mef"),3)==0 || - _tcsnicmp(ext,_T("raf"),3)==0 || - _tcsnicmp(ext,_T("mrw"),3)==0 || - _tcsnicmp(ext,_T("pef"),3)==0 || - _tcsnicmp(ext,_T("sr2"),3)==0 || - _tcsnicmp(ext,_T("orf"),3)==0 ) return CXIMAGE_FORMAT_RAW; -#endif - - return CXIMAGE_FORMAT_UNKNOWN; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetTypeIdFromIndex(const DWORD index) -{ - DWORD n; - - n=0; if (index == n) return CXIMAGE_FORMAT_UNKNOWN; -#if CXIMAGE_SUPPORT_BMP - n++; if (index == n) return CXIMAGE_FORMAT_BMP; -#endif -#if CXIMAGE_SUPPORT_GIF - n++; if (index == n) return CXIMAGE_FORMAT_GIF; -#endif -#if CXIMAGE_SUPPORT_JPG - n++; if (index == n) return CXIMAGE_FORMAT_JPG; -#endif -#if CXIMAGE_SUPPORT_PNG - n++; if (index == n) return CXIMAGE_FORMAT_PNG; -#endif -#if CXIMAGE_SUPPORT_ICO - n++; if (index == n) return CXIMAGE_FORMAT_ICO; -#endif -#if CXIMAGE_SUPPORT_TIF - n++; if (index == n) return CXIMAGE_FORMAT_TIF; -#endif -#if CXIMAGE_SUPPORT_TGA - n++; if (index == n) return CXIMAGE_FORMAT_TGA; -#endif -#if CXIMAGE_SUPPORT_PCX - n++; if (index == n) return CXIMAGE_FORMAT_PCX; -#endif -#if CXIMAGE_SUPPORT_WBMP - n++; if (index == n) return CXIMAGE_FORMAT_WBMP; -#endif -#if CXIMAGE_SUPPORT_WMF - n++; if (index == n) return CXIMAGE_FORMAT_WMF; -#endif -#if CXIMAGE_SUPPORT_JP2 - n++; if (index == n) return CXIMAGE_FORMAT_JP2; -#endif -#if CXIMAGE_SUPPORT_JPC - n++; if (index == n) return CXIMAGE_FORMAT_JPC; -#endif -#if CXIMAGE_SUPPORT_PGX - n++; if (index == n) return CXIMAGE_FORMAT_PGX; -#endif -#if CXIMAGE_SUPPORT_PNM - n++; if (index == n) return CXIMAGE_FORMAT_PNM; -#endif -#if CXIMAGE_SUPPORT_RAS - n++; if (index == n) return CXIMAGE_FORMAT_RAS; -#endif -#if CXIMAGE_SUPPORT_JBG - n++; if (index == n) return CXIMAGE_FORMAT_JBG; -#endif -#if CXIMAGE_SUPPORT_MNG - n++; if (index == n) return CXIMAGE_FORMAT_MNG; -#endif -#if CXIMAGE_SUPPORT_SKA - n++; if (index == n) return CXIMAGE_FORMAT_SKA; -#endif -#if CXIMAGE_SUPPORT_RAW - n++; if (index == n) return CXIMAGE_FORMAT_RAW; -#endif - - return CXIMAGE_FORMAT_UNKNOWN; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::GetTypeIndexFromId(const DWORD id) -{ - DWORD n; - - n=0; if (id == CXIMAGE_FORMAT_UNKNOWN) return n; -#if CXIMAGE_SUPPORT_BMP - n++; if (id == CXIMAGE_FORMAT_BMP) return n; -#endif -#if CXIMAGE_SUPPORT_GIF - n++; if (id == CXIMAGE_FORMAT_GIF) return n; -#endif -#if CXIMAGE_SUPPORT_JPG - n++; if (id == CXIMAGE_FORMAT_JPG) return n; -#endif -#if CXIMAGE_SUPPORT_PNG - n++; if (id == CXIMAGE_FORMAT_PNG) return n; -#endif -#if CXIMAGE_SUPPORT_ICO - n++; if (id == CXIMAGE_FORMAT_ICO) return n; -#endif -#if CXIMAGE_SUPPORT_TIF - n++; if (id == CXIMAGE_FORMAT_TIF) return n; -#endif -#if CXIMAGE_SUPPORT_TGA - n++; if (id == CXIMAGE_FORMAT_TGA) return n; -#endif -#if CXIMAGE_SUPPORT_PCX - n++; if (id == CXIMAGE_FORMAT_PCX) return n; -#endif -#if CXIMAGE_SUPPORT_WBMP - n++; if (id == CXIMAGE_FORMAT_WBMP) return n; -#endif -#if CXIMAGE_SUPPORT_WMF - n++; if (id == CXIMAGE_FORMAT_WMF) return n; -#endif -#if CXIMAGE_SUPPORT_JP2 - n++; if (id == CXIMAGE_FORMAT_JP2) return n; -#endif -#if CXIMAGE_SUPPORT_JPC - n++; if (id == CXIMAGE_FORMAT_JPC) return n; -#endif -#if CXIMAGE_SUPPORT_PGX - n++; if (id == CXIMAGE_FORMAT_PGX) return n; -#endif -#if CXIMAGE_SUPPORT_PNM - n++; if (id == CXIMAGE_FORMAT_PNM) return n; -#endif -#if CXIMAGE_SUPPORT_RAS - n++; if (id == CXIMAGE_FORMAT_RAS) return n; -#endif -#if CXIMAGE_SUPPORT_JBG - n++; if (id == CXIMAGE_FORMAT_JBG) return n; -#endif -#if CXIMAGE_SUPPORT_MNG - n++; if (id == CXIMAGE_FORMAT_MNG) return n; -#endif -#if CXIMAGE_SUPPORT_SKA - n++; if (id == CXIMAGE_FORMAT_SKA) return n; -#endif -#if CXIMAGE_SUPPORT_RAW - n++; if (id == CXIMAGE_FORMAT_RAW) return n; -#endif - - return 0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return current frame delay in milliseconds. Only for GIF and MNG formats. - */ -DWORD CxImage::GetFrameDelay() const -{ - return info.dwFrameDelay; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets current frame delay. Only for GIF format. - * \param d = delay in milliseconds - */ -void CxImage::SetFrameDelay(DWORD d) -{ - info.dwFrameDelay=d; -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::GetOffset(long *x,long *y) -{ - *x=info.xOffset; - *y=info.yOffset; -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::SetOffset(long x,long y) -{ - info.xOffset=x; - info.yOffset=y; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa SetJpegQuality, GetJpegQualityF - * \author [DP]; changes [Stefan Schürmans] - */ -BYTE CxImage::GetJpegQuality() const -{ - return (BYTE)(info.fQuality + 0.5f); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa SetJpegQuality, GetJpegQuality - * \author [Stefan Schürmans] - */ -float CxImage::GetJpegQualityF() const -{ - return info.fQuality; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * quality level for JPEG and JPEG2000 - * \param q: can be from 0 to 100 - * \author [DP]; changes [Stefan Schürmans] - */ -void CxImage::SetJpegQuality(BYTE q){ - info.fQuality = (float)q; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * quality level for JPEG and JPEG2000 - * necessary for JPEG2000 when quality is between 0.0 and 1.0 - * \param q: can be from 0.0 to 100.0 - * \author [Stefan Schürmans] - */ -void CxImage::SetJpegQualityF(float q){ - if (q>0) info.fQuality = q; - else info.fQuality = 0.0f; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa SetJpegScale - */ -BYTE CxImage::GetJpegScale() const -{ - return info.nJpegScale; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * scaling down during JPEG decoding valid numbers are 1, 2, 4, 8 - * \author [ignacio] - */ -void CxImage::SetJpegScale(BYTE q){ - info.nJpegScale = q; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Used to monitor the slow loops. - * \return value is from 0 to 100. - * \sa SetProgress - */ -long CxImage::GetProgress() const -{ - return info.nProgress; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return the escape code. - * \sa SetEscape - */ -long CxImage::GetEscape() const -{ - return info.nEscape; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Forces the value of the internal progress variable. - * \param p should be from 0 to 100. - * \sa GetProgress - */ -void CxImage::SetProgress(long p) -{ - info.nProgress = p; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Used to quit the slow loops or the codecs. - * - SetEscape(-1) before Decode forces the function to exit, right after - * the image width and height are available ( for bmp, jpg, gif, tif ) - */ -void CxImage::SetEscape(long i) -{ - info.nEscape = i; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the image is correctly initializated. - */ -bool CxImage::IsValid() const -{ - return pDib!=0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * True if the image is enabled for painting. - */ -bool CxImage::IsEnabled() const -{ - return info.bEnabled; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Enables/disables the image. - */ -void CxImage::Enable(bool enable) -{ - info.bEnabled=enable; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * This function must be used after a Decode() / Load() call. - * Use the sequence SetFrame(-1); Load(...); GetNumFrames(); - * to get the number of images without loading the first image. - * \return the number of images in the file. - */ -long CxImage::GetNumFrames() const -{ - return info.nNumFrames; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return the current selected image (zero-based index). - */ -long CxImage::GetFrame() const -{ - return info.nFrame; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the image number that the next Decode() / Load() call will load - */ -void CxImage::SetFrame(long nFrame){ - info.nFrame=nFrame; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the method for drawing the frame related to others - * \sa GetDisposalMethod - */ -void CxImage::SetDisposalMethod(BYTE dm) -{ info.dispmeth=dm; } -//////////////////////////////////////////////////////////////////////////////// -/** - * Gets the method for drawing the frame related to others - * Values : 0 - No disposal specified. The decoder is - * not required to take any action. - * 1 - Do not dispose. The graphic is to be left - * in place. - * 2 - Restore to background color. The area used by the - * graphic must be restored to the background color. - * 3 - Restore to previous. The decoder is required to - * restore the area overwritten by the graphic with - * what was there prior to rendering the graphic. - * 4-7 - To be defined. - */ -BYTE CxImage::GetDisposalMethod() const -{ return info.dispmeth; } -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::GetRetreiveAllFrames() const -{ return info.bGetAllFrames; } -//////////////////////////////////////////////////////////////////////////////// -void CxImage::SetRetreiveAllFrames(bool flag) -{ info.bGetAllFrames = flag; } -//////////////////////////////////////////////////////////////////////////////// -CxImage * CxImage::GetFrame(long nFrame) const -{ - if ( ppFrames == NULL) return NULL; - if ( info.nNumFrames == 0) return NULL; - if ( nFrame >= info.nNumFrames ) return NULL; - if ( nFrame < 0) nFrame = info.nNumFrames - 1; - return ppFrames[nFrame]; -} -//////////////////////////////////////////////////////////////////////////////// -short CxImage::cx_ntohs(const short word) -{ - if (info.bLittleEndianHost) return word; - return ( (word & 0xff) << 8 ) | ( (word >> 8) & 0xff ); -} -//////////////////////////////////////////////////////////////////////////////// -long CxImage::cx_ntohl(const long dword) -{ - if (info.bLittleEndianHost) return dword; - return ((dword & 0xff) << 24 ) | ((dword & 0xff00) << 8 ) | - ((dword >> 8) & 0xff00) | ((dword >> 24) & 0xff); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::cx_bihtoh(BITMAPINFOHEADER* bih) -{ - bih->biSize = cx_ntohl(bih->biSize); - bih->biWidth = cx_ntohl(bih->biWidth); - bih->biHeight = cx_ntohl(bih->biHeight); - bih->biPlanes = cx_ntohs(bih->biPlanes); - bih->biBitCount = cx_ntohs(bih->biBitCount); - bih->biCompression = cx_ntohl(bih->biCompression); - bih->biSizeImage = cx_ntohl(bih->biSizeImage); - bih->biXPelsPerMeter = cx_ntohl(bih->biXPelsPerMeter); - bih->biYPelsPerMeter = cx_ntohl(bih->biYPelsPerMeter); - bih->biClrUsed = cx_ntohl(bih->biClrUsed); - bih->biClrImportant = cx_ntohl(bih->biClrImportant); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Returns the last reported error. - */ -const char* CxImage::GetLastError() -{ - return info.szLastError; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::DumpSize() -{ - DWORD n; - n = sizeof(BITMAPINFOHEADER) + sizeof(CXIMAGEINFO) + GetSize(); - - if (pAlpha){ - n += 1 + head.biWidth * head.biHeight; - } else n++; - - if (pSelection){ - n += 1 + head.biWidth * head.biHeight; - } else n++; - - if (ppLayers){ - for (long m=0; mDumpSize(); - } - } - } else n++; - - if (ppFrames){ - for (long m=0; mDumpSize(); - } - } - } else n++; - - return n; -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::Dump(BYTE * dst) -{ - if (!dst) return 0; - - memcpy(dst,&head,sizeof(BITMAPINFOHEADER)); - dst += sizeof(BITMAPINFOHEADER); - - memcpy(dst,&info,sizeof(CXIMAGEINFO)); - dst += sizeof(CXIMAGEINFO); - - memcpy(dst,pDib,GetSize()); - dst += GetSize(); - - if (pAlpha){ - memset(dst++, 1, 1); - memcpy(dst,pAlpha,head.biWidth * head.biHeight); - dst += head.biWidth * head.biHeight; - } else { - memset(dst++, 0, 1); - } - - if (pSelection){ - memset(dst++, 1, 1); - memcpy(dst,pSelection,head.biWidth * head.biHeight); - dst += head.biWidth * head.biHeight; - } else { - memset(dst++, 0, 1); - } - - if (ppLayers){ - memset(dst++, 1, 1); - for (long m=0; mDump(dst); - } - } - } else { - memset(dst++, 0, 1); - } - - if (ppFrames){ - memset(dst++, 1, 1); - for (long m=0; mDump(dst); - } - } - } else { - memset(dst++, 0, 1); - } - - return DumpSize(); -} -//////////////////////////////////////////////////////////////////////////////// -DWORD CxImage::UnDump(const BYTE * src) -{ - if (!src) - return 0; - if (!Destroy()) - return 0; - if (!DestroyFrames()) - return 0; - - DWORD n = 0; - - memcpy(&head,src,sizeof(BITMAPINFOHEADER)); - n += sizeof(BITMAPINFOHEADER); - - memcpy(&info,&src[n],sizeof(CXIMAGEINFO)); - n += sizeof(CXIMAGEINFO); - - if (!Create(head.biWidth, head.biHeight, head.biBitCount, info.dwType)) - return 0; - - memcpy(pDib,&src[n],GetSize()); - n += GetSize(); - - if (src[n++]){ - if (AlphaCreate()){ - memcpy(pAlpha, &src[n], head.biWidth * head.biHeight); - } - n += head.biWidth * head.biHeight; - } - - if (src[n++]){ - RECT box = info.rSelectionBox; - if (SelectionCreate()){ - info.rSelectionBox = box; - memcpy(pSelection, &src[n], head.biWidth * head.biHeight); - } - n += head.biWidth * head.biHeight; - } - - if (src[n++]){ - ppLayers = new CxImage*[info.nNumLayers]; - for (long m=0; mUnDump(&src[n]); - } - } - - if (src[n++]){ - ppFrames = new CxImage*[info.nNumFrames]; - for (long m=0; mUnDump(&src[n]); - } - } - - return n; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * \return A.BBCCCDDDD - * - A = main version - * - BB = main revision - * - CCC = minor revision (letter) - * - DDDD = experimental revision - */ -const float CxImage::GetVersionNumber() -{ - return 6.000000015f; -} -//////////////////////////////////////////////////////////////////////////////// -const TCHAR* CxImage::GetVersion() -{ - static const TCHAR CxImageVersion[] = _T("CxImage 6.0.0"); - return (CxImageVersion); -} -//////////////////////////////////////////////////////////////////////////////// - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#undef _tcsnicmp -#undef _T -#endif diff --git a/Externals/cximage/ximaint.cpp b/Externals/cximage/ximaint.cpp deleted file mode 100644 index 6814d5e2d39..00000000000 --- a/Externals/cximage/ximaint.cpp +++ /dev/null @@ -1,1056 +0,0 @@ -// xImaInt.cpp : interpolation functions -/* 02/2004 - Branko Brevensek - * CxImage version 6.0.0 02/Feb/2008 - Davide Pizzolato - www.xdp.it - */ - -#include "ximage.h" -#include "ximath.h" - -#if CXIMAGE_SUPPORT_INTERPOLATION - -//////////////////////////////////////////////////////////////////////////////// -/** - * Recalculates coordinates according to specified overflow method. - * If pixel (x,y) lies within image, nothing changes. - * - * \param x, y - coordinates of pixel - * \param ofMethod - overflow method - * - * \return x, y - new coordinates (pixel (x,y) now lies inside image) - * - * \author ***bd*** 2.2004 - */ -void CxImage::OverflowCoordinates(long &x, long &y, OverflowMethod const ofMethod) -{ - if (IsInside(x,y)) return; //if pixel is within bounds, no change - switch (ofMethod) { - case OM_REPEAT: - //clip coordinates - x=MAX(x,0); x=MIN(x, head.biWidth-1); - y=MAX(y,0); y=MIN(y, head.biHeight-1); - break; - case OM_WRAP: - //wrap coordinates - x = x % head.biWidth; - y = y % head.biHeight; - if (x<0) x = head.biWidth + x; - if (y<0) y = head.biHeight + y; - break; - case OM_MIRROR: - //mirror pixels near border - if (x<0) x=((-x) % head.biWidth); - else if (x>=head.biWidth) x=head.biWidth-(x % head.biWidth + 1); - if (y<0) y=((-y) % head.biHeight); - else if (y>=head.biHeight) y=head.biHeight-(y % head.biHeight + 1); - break; - default: - return; - }//switch -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * See OverflowCoordinates for integer version - * \author ***bd*** 2.2004 - */ -void CxImage::OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod) -{ - if (x>=0 && x=0 && y=head.biWidth) x=head.biWidth-((float)fmod(x, (float) head.biWidth) + 1); - if (y<0) y=(float)fmod(-y, (float) head.biHeight); - else if (y>=head.biHeight) y=head.biHeight-((float)fmod(y, (float) head.biHeight) + 1); - break; - default: - return; - }//switch -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * Method return pixel color. Different methods are implemented for out of bounds pixels. - * If an image has alpha channel, alpha value is returned in .RGBReserved. - * - * \param x,y : pixel coordinates - * \param ofMethod : out-of-bounds method: - * - OF_WRAP - wrap over to pixels on other side of the image - * - OF_REPEAT - repeat last pixel on the edge - * - OF_COLOR - return input value of color - * - OF_BACKGROUND - return background color (if not set, return input color) - * - OF_TRANSPARENT - return transparent pixel - * - * \param rplColor : input color (returned for out-of-bound coordinates in OF_COLOR mode and if other mode is not applicable) - * - * \return color : color of pixel - * \author ***bd*** 2.2004 - */ -RGBQUAD CxImage::GetPixelColorWithOverflow(long x, long y, OverflowMethod const ofMethod, RGBQUAD* const rplColor) -{ - RGBQUAD color; //color to return - if ((!IsInside(x,y)) || pDib==NULL) { //is pixel within bouns?: - //pixel is out of bounds or no DIB - if (rplColor!=NULL) - color=*rplColor; - else { - color.rgbRed=color.rgbGreen=color.rgbBlue=255; color.rgbReserved=0; //default replacement colour: white transparent - }//if - if (pDib==NULL) return color; - //pixel is out of bounds: - switch (ofMethod) { - case OM_TRANSPARENT: -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) { - //alpha transparency is supported and image has alpha layer - color.rgbReserved=0; - } else { -#endif //CXIMAGE_SUPPORT_ALPHA - //no alpha transparency - if (GetTransIndex()>=0) { - color=GetTransColor(); //single color transparency enabled (return transparent color) - }//if -#if CXIMAGE_SUPPORT_ALPHA - }//if -#endif //CXIMAGE_SUPPORT_ALPHA - return color; - case OM_BACKGROUND: - //return background color (if it exists, otherwise input value) - if (info.nBkgndIndex >= 0) { - if (head.biBitCount<24) color = GetPaletteColor((BYTE)info.nBkgndIndex); - else color = info.nBkgndColor; - }//if - return color; - case OM_REPEAT: - case OM_WRAP: - case OM_MIRROR: - OverflowCoordinates(x,y,ofMethod); - break; - default: - //simply return replacement color (OM_COLOR and others) - return color; - }//switch - }//if - //just return specified pixel (it's within bounds) - return BlindGetPixelColor(x,y); -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * This method reconstructs image according to chosen interpolation method and then returns pixel (x,y). - * (x,y) can lie between actual image pixels. If (x,y) lies outside of image, method returns value - * according to overflow method. - * This method is very useful for geometrical image transformations, where destination pixel - * can often assume color value lying between source pixels. - * - * \param (x,y) - coordinates of pixel to return - * GPCI method recreates "analogue" image back from digital data, so x and y - * are float values and color value of point (1.1,1) will generally not be same - * as (1,1). Center of first pixel is at (0,0) and center of pixel right to it is (1,0). - * (0.5,0) is half way between these two pixels. - * \param inMethod - interpolation (reconstruction) method (kernel) to use: - * - IM_NEAREST_NEIGHBOUR - returns colour of nearest lying pixel (causes stairy look of - * processed images) - * - IM_BILINEAR - interpolates colour from four neighbouring pixels (softens image a bit) - * - IM_BICUBIC - interpolates from 16 neighbouring pixels (can produce "halo" artifacts) - * - IM_BICUBIC2 - interpolates from 16 neighbouring pixels (perhaps a bit less halo artifacts - than IM_BICUBIC) - * - IM_BSPLINE - interpolates from 16 neighbouring pixels (softens image, washes colours) - * (As far as I know, image should be prefiltered for this method to give - * good results... some other time :) ) - * This method uses bicubic interpolation kernel from CXImage 5.99a and older - * versions. - * - IM_LANCZOS - interpolates from 12*12 pixels (slow, ringing artifacts) - * - * \param ofMethod - overflow method (see comments at GetPixelColorWithOverflow) - * \param rplColor - pointer to color used for out of borders pixels in OM_COLOR mode - * (and other modes if colour can't calculated in a specified way) - * - * \return interpolated color value (including interpolated alpha value, if image has alpha layer) - * - * \author ***bd*** 2.2004 - */ -RGBQUAD CxImage::GetPixelColorInterpolated( - float x,float y, - InterpolationMethod const inMethod, - OverflowMethod const ofMethod, - RGBQUAD* const rplColor) -{ - //calculate nearest pixel - int xi=(int)(x); if (x<0) xi--; //these replace (incredibly slow) floor (Visual c++ 2003, AMD Athlon) - int yi=(int)(y); if (y<0) yi--; - RGBQUAD color; //calculated colour - - switch (inMethod) { - case IM_NEAREST_NEIGHBOUR: - return GetPixelColorWithOverflow((long)(x+0.5f), (long)(y+0.5f), ofMethod, rplColor); - default: { - //IM_BILINEAR: bilinear interpolation - if (xi<-1 || xi>=head.biWidth || yi<-1 || yi>=head.biHeight) { //all 4 points are outside bounds?: - switch (ofMethod) { - case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND: - //we don't need to interpolate anything with all points outside in this case - return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor); - default: - //recalculate coordinates and use faster method later on - OverflowCoordinates(x,y,ofMethod); - xi=(int)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi - yi=(int)(y); if (y<0) yi--; - }//switch - }//if - //get four neighbouring pixels - if ((xi+1)=0 && (yi+1)=0 && head.biClrUsed==0) { - //all pixels are inside RGB24 image... optimize reading (and use fixed point arithmetic) - WORD wt1=(WORD)((x-xi)*256.0f), wt2=(WORD)((y-yi)*256.0f); - WORD wd=wt1*wt2>>8; - WORD wb=wt1-wd; - WORD wc=wt2-wd; - WORD wa=256-wt1-wc; - WORD wrr,wgg,wbb; - BYTE *pxptr=(BYTE*)info.pImage+yi*info.dwEffWidth+xi*3; - wbb=wa*(*pxptr++); wgg=wa*(*pxptr++); wrr=wa*(*pxptr++); - wbb+=wb*(*pxptr++); wgg+=wb*(*pxptr++); wrr+=wb*(*pxptr); - pxptr+=(info.dwEffWidth-5); //move to next row - wbb+=wc*(*pxptr++); wgg+=wc*(*pxptr++); wrr+=wc*(*pxptr++); - wbb+=wd*(*pxptr++); wgg+=wd*(*pxptr++); wrr+=wd*(*pxptr); - color.rgbRed=(BYTE) (wrr>>8); color.rgbGreen=(BYTE) (wgg>>8); color.rgbBlue=(BYTE) (wbb>>8); -#if CXIMAGE_SUPPORT_ALPHA - if (pAlpha) { - WORD waa; - //image has alpha layer... we have to do the same for alpha data - pxptr=AlphaGetPointer(xi,yi); //pointer to first byte - waa=wa*(*pxptr++); waa+=wb*(*pxptr); //first two pixels - pxptr+=(head.biWidth-1); //move to next row - waa+=wc*(*pxptr++); waa+=wd*(*pxptr); //and second row pixels - color.rgbReserved=(BYTE) (waa>>8); - } else -#endif - { //Alpha not supported or no alpha at all - color.rgbReserved = 0; - } - return color; - } else { - //default (slower) way to get pixels (not RGB24 or some pixels out of borders) - float t1=x-xi, t2=y-yi; - float d=t1*t2; - float b=t1-d; - float c=t2-d; - float a=1-t1-c; - RGBQUAD rgb11,rgb21,rgb12,rgb22; - rgb11=GetPixelColorWithOverflow(xi, yi, ofMethod, rplColor); - rgb21=GetPixelColorWithOverflow(xi+1, yi, ofMethod, rplColor); - rgb12=GetPixelColorWithOverflow(xi, yi+1, ofMethod, rplColor); - rgb22=GetPixelColorWithOverflow(xi+1, yi+1, ofMethod, rplColor); - //calculate linear interpolation - color.rgbRed=(BYTE) (a*rgb11.rgbRed+b*rgb21.rgbRed+c*rgb12.rgbRed+d*rgb22.rgbRed); - color.rgbGreen=(BYTE) (a*rgb11.rgbGreen+b*rgb21.rgbGreen+c*rgb12.rgbGreen+d*rgb22.rgbGreen); - color.rgbBlue=(BYTE) (a*rgb11.rgbBlue+b*rgb21.rgbBlue+c*rgb12.rgbBlue+d*rgb22.rgbBlue); -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) - color.rgbReserved=(BYTE) (a*rgb11.rgbReserved+b*rgb21.rgbReserved+c*rgb12.rgbReserved+d*rgb22.rgbReserved); - else -#endif - { //Alpha not supported or no alpha at all - color.rgbReserved = 0; - } - return color; - }//if - }//default - case IM_BICUBIC: - case IM_BICUBIC2: - case IM_BSPLINE: - case IM_BOX: - case IM_HERMITE: - case IM_HAMMING: - case IM_SINC: - case IM_BLACKMAN: - case IM_BESSEL: - case IM_GAUSSIAN: - case IM_QUADRATIC: - case IM_MITCHELL: - case IM_CATROM: - case IM_HANNING: - case IM_POWER: - //bicubic interpolation(s) - if (((xi+2)<0) || ((xi-1)>=head.biWidth) || ((yi+2)<0) || ((yi-1)>=head.biHeight)) { //all points are outside bounds?: - switch (ofMethod) { - case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND: - //we don't need to interpolate anything with all points outside in this case - return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor); - break; - default: - //recalculate coordinates and use faster method later on - OverflowCoordinates(x,y,ofMethod); - xi=(int)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi - yi=(int)(y); if (y<0) yi--; - }//switch - }//if - - //some variables needed from here on - int xii,yii; //x any y integer indexes for loops - float kernel, kernelyc; //kernel cache - float kernelx[12], kernely[4]; //precalculated kernel values - float rr,gg,bb,aa; //accumulated color values - //calculate multiplication factors for all pixels - int i; - switch (inMethod) { - case IM_BICUBIC: - for (i=0; i<4; i++) { - kernelx[i]=KernelCubic((float)(xi+i-1-x)); - kernely[i]=KernelCubic((float)(yi+i-1-y)); - }//for i - break; - case IM_BICUBIC2: - for (i=0; i<4; i++) { - kernelx[i]=KernelGeneralizedCubic((float)(xi+i-1-x), -0.5); - kernely[i]=KernelGeneralizedCubic((float)(yi+i-1-y), -0.5); - }//for i - break; - case IM_BSPLINE: - for (i=0; i<4; i++) { - kernelx[i]=KernelBSpline((float)(xi+i-1-x)); - kernely[i]=KernelBSpline((float)(yi+i-1-y)); - }//for i - break; - case IM_BOX: - for (i=0; i<4; i++) { - kernelx[i]=KernelBox((float)(xi+i-1-x)); - kernely[i]=KernelBox((float)(yi+i-1-y)); - }//for i - break; - case IM_HERMITE: - for (i=0; i<4; i++) { - kernelx[i]=KernelHermite((float)(xi+i-1-x)); - kernely[i]=KernelHermite((float)(yi+i-1-y)); - }//for i - break; - case IM_HAMMING: - for (i=0; i<4; i++) { - kernelx[i]=KernelHamming((float)(xi+i-1-x)); - kernely[i]=KernelHamming((float)(yi+i-1-y)); - }//for i - break; - case IM_SINC: - for (i=0; i<4; i++) { - kernelx[i]=KernelSinc((float)(xi+i-1-x)); - kernely[i]=KernelSinc((float)(yi+i-1-y)); - }//for i - break; - case IM_BLACKMAN: - for (i=0; i<4; i++) { - kernelx[i]=KernelBlackman((float)(xi+i-1-x)); - kernely[i]=KernelBlackman((float)(yi+i-1-y)); - }//for i - break; - case IM_BESSEL: - for (i=0; i<4; i++) { - kernelx[i]=KernelBessel((float)(xi+i-1-x)); - kernely[i]=KernelBessel((float)(yi+i-1-y)); - }//for i - break; - case IM_GAUSSIAN: - for (i=0; i<4; i++) { - kernelx[i]=KernelGaussian((float)(xi+i-1-x)); - kernely[i]=KernelGaussian((float)(yi+i-1-y)); - }//for i - break; - case IM_QUADRATIC: - for (i=0; i<4; i++) { - kernelx[i]=KernelQuadratic((float)(xi+i-1-x)); - kernely[i]=KernelQuadratic((float)(yi+i-1-y)); - }//for i - break; - case IM_MITCHELL: - for (i=0; i<4; i++) { - kernelx[i]=KernelMitchell((float)(xi+i-1-x)); - kernely[i]=KernelMitchell((float)(yi+i-1-y)); - }//for i - break; - case IM_CATROM: - for (i=0; i<4; i++) { - kernelx[i]=KernelCatrom((float)(xi+i-1-x)); - kernely[i]=KernelCatrom((float)(yi+i-1-y)); - }//for i - break; - case IM_HANNING: - for (i=0; i<4; i++) { - kernelx[i]=KernelHanning((float)(xi+i-1-x)); - kernely[i]=KernelHanning((float)(yi+i-1-y)); - }//for i - break; - case IM_POWER: - for (i=0; i<4; i++) { - kernelx[i]=KernelPower((float)(xi+i-1-x)); - kernely[i]=KernelPower((float)(yi+i-1-y)); - }//for i - break; - }//switch - rr=gg=bb=aa=0; - if (((xi+2)=1 && ((yi+2)=1) && !IsIndexed()) { - //optimized interpolation (faster pixel reads) for RGB24 images with all pixels inside bounds - BYTE *pxptr, *pxptra; - for (yii=yi-1; yii255) rr=255; if (rr<0) rr=0; color.rgbRed=(BYTE) rr; - if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(BYTE) gg; - if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(BYTE) bb; -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) { - if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(BYTE) aa; - } else -#endif - { //Alpha not supported or no alpha at all - color.rgbReserved = 0; - } - return color; - case IM_LANCZOS: - //lanczos window (16*16) sinc interpolation - if (((xi+6)<0) || ((xi-5)>=head.biWidth) || ((yi+6)<0) || ((yi-5)>=head.biHeight)) { - //all points are outside bounds - switch (ofMethod) { - case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND: - //we don't need to interpolate anything with all points outside in this case - return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor); - break; - default: - //recalculate coordinates and use faster method later on - OverflowCoordinates(x,y,ofMethod); - xi=(int)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi - yi=(int)(y); if (y<0) yi--; - }//switch - }//if - - for (xii=xi-5; xii=0) && ((yi+6)=0) && !IsIndexed()) { - //optimized interpolation (faster pixel reads) for RGB24 images with all pixels inside bounds - BYTE *pxptr, *pxptra; - for (yii=yi-5; yii255) rr=255; if (rr<0) rr=0; color.rgbRed=(BYTE) rr; - if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(BYTE) gg; - if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(BYTE) bb; -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) { - if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(BYTE) aa; - } else -#endif - { //Alpha not supported or no alpha at all - color.rgbReserved = 0; - } - return color; - }//switch -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Helper function for GetAreaColorInterpolated. - * Adds 'surf' portion of image pixel with color 'color' to (rr,gg,bb,aa). - */ -void CxImage::AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa) -{ - rr+=color.rgbRed*surf; - gg+=color.rgbGreen*surf; - bb+=color.rgbBlue*surf; -#if CXIMAGE_SUPPORT_ALPHA - aa+=color.rgbReserved*surf; -#endif -} -//////////////////////////////////////////////////////////////////////////////// -/** - * This method is similar to GetPixelColorInterpolated, but this method also properly handles - * subsampling. - * If you need to sample original image with interval of more than 1 pixel (as when shrinking an image), - * you should use this method instead of GetPixelColorInterpolated or aliasing will occur. - * When area width and height are both less than pixel, this method gets pixel color by interpolating - * color of frame center with selected (inMethod) interpolation by calling GetPixelColorInterpolated. - * If width and height are more than 1, method calculates color by averaging color of pixels within area. - * Interpolation method is not used in this case. Pixel color is interpolated by averaging instead. - * If only one of both is more than 1, method uses combination of interpolation and averaging. - * Chosen interpolation method is used, but since it is averaged later on, there is little difference - * between IM_BILINEAR (perhaps best for this case) and better methods. IM_NEAREST_NEIGHBOUR again - * leads to aliasing artifacts. - * This method is a bit slower than GetPixelColorInterpolated and when aliasing is not a problem, you should - * simply use the later. - * - * \param xc, yc - center of (rectangular) area - * \param w, h - width and height of area - * \param inMethod - interpolation method that is used, when interpolation is used (see above) - * \param ofMethod - overflow method used when retrieving individual pixel colors - * \param rplColor - replacement colour to use, in OM_COLOR - * - * \author ***bd*** 2.2004 - */ -RGBQUAD CxImage::GetAreaColorInterpolated( - float const xc, float const yc, float const w, float const h, - InterpolationMethod const inMethod, - OverflowMethod const ofMethod, - RGBQUAD* const rplColor) -{ - RGBQUAD color; //calculated colour - - if (h<=1 && w<=1) { - //both width and height are less than one... we will use interpolation of center point - return GetPixelColorInterpolated(xc, yc, inMethod, ofMethod, rplColor); - } else { - //area is wider and/or taller than one pixel: - CxRect2 area(xc-w/2.0f, yc-h/2.0f, xc+w/2.0f, yc+h/2.0f); //area - int xi1=(int)(area.botLeft.x+0.49999999f); //low x - int yi1=(int)(area.botLeft.y+0.49999999f); //low y - - - int xi2=(int)(area.topRight.x+0.5f); //top x - int yi2=(int)(area.topRight.y+0.5f); //top y (for loops) - - float rr,gg,bb,aa; //red, green, blue and alpha components - rr=gg=bb=aa=0; - int x,y; //loop counters - float s=0; //surface of all pixels - float cps; //surface of current crosssection - if (h>1 && w>1) { - //width and height of area are greater than one pixel, so we can employ "ordinary" averaging - CxRect2 intBL, intTR; //bottom left and top right intersection - intBL=area.CrossSection(CxRect2(((float)xi1)-0.5f, ((float)yi1)-0.5f, ((float)xi1)+0.5f, ((float)yi1)+0.5f)); - intTR=area.CrossSection(CxRect2(((float)xi2)-0.5f, ((float)yi2)-0.5f, ((float)xi2)+0.5f, ((float)yi2)+0.5f)); - float wBL, wTR, hBL, hTR; - wBL=intBL.Width(); //width of bottom left pixel-area intersection - hBL=intBL.Height(); //height of bottom left... - wTR=intTR.Width(); //width of top right... - hTR=intTR.Height(); //height of top right... - - AddAveragingCont(GetPixelColorWithOverflow(xi1,yi1,ofMethod,rplColor), wBL*hBL, rr, gg, bb, aa); //bottom left pixel - AddAveragingCont(GetPixelColorWithOverflow(xi2,yi1,ofMethod,rplColor), wTR*hBL, rr, gg, bb, aa); //bottom right pixel - AddAveragingCont(GetPixelColorWithOverflow(xi1,yi2,ofMethod,rplColor), wBL*hTR, rr, gg, bb, aa); //top left pixel - AddAveragingCont(GetPixelColorWithOverflow(xi2,yi2,ofMethod,rplColor), wTR*hTR, rr, gg, bb, aa); //top right pixel - //bottom and top row - for (x=xi1+1; x255) rr=255; if (rr<0) rr=0; color.rgbRed=(BYTE) rr; - if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(BYTE) gg; - if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(BYTE) bb; -#if CXIMAGE_SUPPORT_ALPHA - if (AlphaIsValid()) { - if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(BYTE) aa; - }//if -#endif - }//if - return color; -} - -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBSpline(const float x) -{ - if (x>2.0f) return 0.0f; - // thanks to Kristian Kratzenstein - float a, b, c, d; - float xm1 = x - 1.0f; // Was calculatet anyway cause the "if((x-1.0f) < 0)" - float xp1 = x + 1.0f; - float xp2 = x + 2.0f; - - if ((xp2) <= 0.0f) a = 0.0f; else a = xp2*xp2*xp2; // Only float, not float -> double -> float - if ((xp1) <= 0.0f) b = 0.0f; else b = xp1*xp1*xp1; - if (x <= 0) c = 0.0f; else c = x*x*x; - if ((xm1) <= 0.0f) d = 0.0f; else d = xm1*xm1*xm1; - - return (0.16666666666666666667f * (a - (4.0f * b) + (6.0f * c) - (4.0f * d))); - - /* equivalent - if (x < -2.0) - return(0.0f); - if (x < -1.0) - return((2.0f+x)*(2.0f+x)*(2.0f+x)*0.16666666666666666667f); - if (x < 0.0) - return((4.0f+x*x*(-6.0f-3.0f*x))*0.16666666666666666667f); - if (x < 1.0) - return((4.0f+x*x*(-6.0f+3.0f*x))*0.16666666666666666667f); - if (x < 2.0) - return((2.0f-x)*(2.0f-x)*(2.0f-x)*0.16666666666666666667f); - return(0.0f); - */ -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * Bilinear interpolation kernel: - \verbatim - / - | 1-t , if 0 <= t <= 1 - h(t) = | t+1 , if -1 <= t < 0 - | 0 , otherwise - \ - \endverbatim - * ***bd*** 2.2004 - */ -float CxImage::KernelLinear(const float t) -{ -// if (0<=t && t<=1) return 1-t; -// if (-1<=t && t<0) return 1+t; -// return 0; - - // - if (t < -1.0f) - return 0.0f; - if (t < 0.0f) - return 1.0f+t; - if (t < 1.0f) - return 1.0f-t; - return 0.0f; -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * Bicubic interpolation kernel (a=-1): - \verbatim - / - | 1-2|t|**2+|t|**3 , if |t| < 1 - h(t) = | 4-8|t|+5|t|**2-|t|**3 , if 1<=|t|<2 - | 0 , otherwise - \ - \endverbatim - * ***bd*** 2.2004 - */ -float CxImage::KernelCubic(const float t) -{ - float abs_t = (float)fabs(t); - float abs_t_sq = abs_t * abs_t; - if (abs_t<1) return 1-2*abs_t_sq+abs_t_sq*abs_t; - if (abs_t<2) return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t; - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * Bicubic kernel (for a=-1 it is the same as BicubicKernel): - \verbatim - / - | (a+2)|t|**3 - (a+3)|t|**2 + 1 , |t| <= 1 - h(t) = | a|t|**3 - 5a|t|**2 + 8a|t| - 4a , 1 < |t| <= 2 - | 0 , otherwise - \ - \endverbatim - * Often used values for a are -1 and -1/2. - */ -float CxImage::KernelGeneralizedCubic(const float t, const float a) -{ - float abs_t = (float)fabs(t); - float abs_t_sq = abs_t * abs_t; - if (abs_t<1) return (a+2)*abs_t_sq*abs_t - (a+3)*abs_t_sq + 1; - if (abs_t<2) return a*abs_t_sq*abs_t - 5*a*abs_t_sq + 8*a*abs_t - 4*a; - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -/** - * Lanczos windowed sinc interpolation kernel with radius r. - \verbatim - / - h(t) = | sinc(t)*sinc(t/r) , if |t| r) return 0; - if (t==0) return 1; - float pit=PI*t; - float pitd=pit/r; - return (float)((sin(pit)/pit) * (sin(pitd)/pitd)); -} - -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBox(const float x) -{ - if (x < -0.5f) - return 0.0f; - if (x < 0.5f) - return 1.0f; - return 0.0f; -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelHermite(const float x) -{ - if (x < -1.0f) - return 0.0f; - if (x < 0.0f) - return (-2.0f*x-3.0f)*x*x+1.0f; - if (x < 1.0f) - return (2.0f*x-3.0f)*x*x+1.0f; - return 0.0f; -// if (fabs(x)>1) return 0.0f; -// return(0.5f+0.5f*(float)cos(PI*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelHanning(const float x) -{ - if (fabs(x)>1) return 0.0f; - return (0.5f+0.5f*(float)cos(PI*x))*((float)sin(PI*x)/(PI*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelHamming(const float x) -{ - if (x < -1.0f) - return 0.0f; - if (x < 0.0f) - return 0.92f*(-2.0f*x-3.0f)*x*x+1.0f; - if (x < 1.0f) - return 0.92f*(2.0f*x-3.0f)*x*x+1.0f; - return 0.0f; -// if (fabs(x)>1) return 0.0f; -// return(0.54f+0.46f*(float)cos(PI*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelSinc(const float x) -{ - if (x == 0.0) - return(1.0); - return((float)sin(PI*x)/(PI*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBlackman(const float x) -{ - //if (fabs(x)>1) return 0.0f; - return (0.42f+0.5f*(float)cos(PI*x)+0.08f*(float)cos(2.0f*PI*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBessel_J1(const float x) -{ - double p, q; - - long i; - - static const double - Pone[] = - { - 0.581199354001606143928050809e+21, - -0.6672106568924916298020941484e+20, - 0.2316433580634002297931815435e+19, - -0.3588817569910106050743641413e+17, - 0.2908795263834775409737601689e+15, - -0.1322983480332126453125473247e+13, - 0.3413234182301700539091292655e+10, - -0.4695753530642995859767162166e+7, - 0.270112271089232341485679099e+4 - }, - Qone[] = - { - 0.11623987080032122878585294e+22, - 0.1185770712190320999837113348e+20, - 0.6092061398917521746105196863e+17, - 0.2081661221307607351240184229e+15, - 0.5243710262167649715406728642e+12, - 0.1013863514358673989967045588e+10, - 0.1501793594998585505921097578e+7, - 0.1606931573481487801970916749e+4, - 0.1e+1 - }; - - p = Pone[8]; - q = Qone[8]; - for (i=7; i >= 0; i--) - { - p = p*x*x+Pone[i]; - q = q*x*x+Qone[i]; - } - return (float)(p/q); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBessel_P1(const float x) -{ - double p, q; - - long i; - - static const double - Pone[] = - { - 0.352246649133679798341724373e+5, - 0.62758845247161281269005675e+5, - 0.313539631109159574238669888e+5, - 0.49854832060594338434500455e+4, - 0.2111529182853962382105718e+3, - 0.12571716929145341558495e+1 - }, - Qone[] = - { - 0.352246649133679798068390431e+5, - 0.626943469593560511888833731e+5, - 0.312404063819041039923015703e+5, - 0.4930396490181088979386097e+4, - 0.2030775189134759322293574e+3, - 0.1e+1 - }; - - p = Pone[5]; - q = Qone[5]; - for (i=4; i >= 0; i--) - { - p = p*(8.0/x)*(8.0/x)+Pone[i]; - q = q*(8.0/x)*(8.0/x)+Qone[i]; - } - return (float)(p/q); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBessel_Q1(const float x) -{ - double p, q; - - long i; - - static const double - Pone[] = - { - 0.3511751914303552822533318e+3, - 0.7210391804904475039280863e+3, - 0.4259873011654442389886993e+3, - 0.831898957673850827325226e+2, - 0.45681716295512267064405e+1, - 0.3532840052740123642735e-1 - }, - Qone[] = - { - 0.74917374171809127714519505e+4, - 0.154141773392650970499848051e+5, - 0.91522317015169922705904727e+4, - 0.18111867005523513506724158e+4, - 0.1038187585462133728776636e+3, - 0.1e+1 - }; - - p = Pone[5]; - q = Qone[5]; - for (i=4; i >= 0; i--) - { - p = p*(8.0/x)*(8.0/x)+Pone[i]; - q = q*(8.0/x)*(8.0/x)+Qone[i]; - } - return (float)(p/q); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBessel_Order1(float x) -{ - float p, q; - - if (x == 0.0) - return (0.0f); - p = x; - if (x < 0.0) - x=(-x); - if (x < 8.0) - return(p*KernelBessel_J1(x)); - q = (float)sqrt(2.0f/(PI*x))*(float)(KernelBessel_P1(x)*(1.0f/sqrt(2.0f)*(sin(x)-cos(x)))-8.0f/x*KernelBessel_Q1(x)* - (-1.0f/sqrt(2.0f)*(sin(x)+cos(x)))); - if (p < 0.0f) - q = (-q); - return (q); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelBessel(const float x) -{ - if (x == 0.0f) - return(PI/4.0f); - return(KernelBessel_Order1(PI*x)/(2.0f*x)); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelGaussian(const float x) -{ - return (float)(exp(-2.0f*x*x)*0.79788456080287f/*sqrt(2.0f/PI)*/); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelQuadratic(const float x) -{ - if (x < -1.5f) - return(0.0f); - if (x < -0.5f) - return(0.5f*(x+1.5f)*(x+1.5f)); - if (x < 0.5f) - return(0.75f-x*x); - if (x < 1.5f) - return(0.5f*(x-1.5f)*(x-1.5f)); - return(0.0f); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelMitchell(const float x) -{ - constexpr float KM_B = (1.0f / 3.0f); - constexpr float KM_C = (1.0f / 3.0f); - constexpr float KM_P0 = (( 6.0f - 2.0f * KM_B ) / 6.0f); - constexpr float KM_P2 = ((-18.0f + 12.0f * KM_B + 6.0f * KM_C) / 6.0f); - constexpr float KM_P3 = (( 12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f); - constexpr float KM_Q0 = (( 8.0f * KM_B + 24.0f * KM_C) / 6.0f); - constexpr float KM_Q1 = ((-12.0f * KM_B - 48.0f * KM_C) / 6.0f); - constexpr float KM_Q2 = (( 6.0f * KM_B + 30.0f * KM_C) / 6.0f); - constexpr float KM_Q3 = (( -1.0f * KM_B - 6.0f * KM_C) / 6.0f); - - if (x < -2.0) - return(0.0f); - if (x < -1.0) - return(KM_Q0-x*(KM_Q1-x*(KM_Q2-x*KM_Q3))); - if (x < 0.0f) - return(KM_P0+x*x*(KM_P2-x*KM_P3)); - if (x < 1.0f) - return(KM_P0+x*x*(KM_P2+x*KM_P3)); - if (x < 2.0f) - return(KM_Q0+x*(KM_Q1+x*(KM_Q2+x*KM_Q3))); - return(0.0f); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelCatrom(const float x) -{ - if (x < -2.0) - return(0.0f); - if (x < -1.0) - return(0.5f*(4.0f+x*(8.0f+x*(5.0f+x)))); - if (x < 0.0) - return(0.5f*(2.0f+x*x*(-5.0f-3.0f*x))); - if (x < 1.0) - return(0.5f*(2.0f+x*x*(-5.0f+3.0f*x))); - if (x < 2.0) - return(0.5f*(4.0f+x*(-8.0f+x*(5.0f-x)))); - return(0.0f); -} -//////////////////////////////////////////////////////////////////////////////// -float CxImage::KernelPower(const float x, const float a) -{ - if (fabs(x)>1) return 0.0f; - return (1.0f - (float)fabs(pow(x,a))); -} -//////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/Externals/cximage/ximaiter.h b/Externals/cximage/ximaiter.h deleted file mode 100644 index 9628ea55a62..00000000000 --- a/Externals/cximage/ximaiter.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * File: ImaIter.h - * Purpose: Declaration of the Platform Independent Image Base Class - * Author: Alejandro Aguilar Sierra - * Created: 1995 - * Copyright: (c) 1995, Alejandro Aguilar Sierra - * - * 07/08/2001 Davide Pizzolato - www.xdp.it - * - removed slow loops - * - added safe checks - * - * Permission is given by the author to freely redistribute and include - * this code in any program as long as this credit is given where due. - * - * COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY - * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES - * THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE - * OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED - * CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT - * THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY - * SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL - * PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER - * THIS DISCLAIMER. - * - * Use at your own risk! - * ========================================================== - */ - -#if !defined(__ImaIter_h) -#define __ImaIter_h - -#include "ximage.h" -#include "ximadef.h" - -class CImageIterator -{ -friend class CxImage; -protected: - int Itx, Ity; // Counters - int Stepx, Stepy; - BYTE* IterImage; // Image pointer - CxImage *ima; -public: - // Constructors - CImageIterator ( void ); - CImageIterator ( CxImage *image ); - operator CxImage* (); - - // Iterators - bool ItOK (); - void Reset (); - void Upset (); - void SetRow(BYTE *buf, int n); - void GetRow(BYTE *buf, int n); - BYTE GetByte( ) { return IterImage[Itx]; } - void SetByte(BYTE b) { IterImage[Itx] = b; } - BYTE* GetRow(void); - BYTE* GetRow(int n); - bool NextRow(); - bool PrevRow(); - bool NextByte(); - bool PrevByte(); - - void SetSteps(int x, int y=0) { Stepx = x; Stepy = y; } - void GetSteps(int *x, int *y) { *x = Stepx; *y = Stepy; } - bool NextStep(); - bool PrevStep(); - - void SetY(int y); /* AD - for interlace */ - int GetY() {return Ity;} - bool GetCol(BYTE* pCol, DWORD x); - bool SetCol(BYTE* pCol, DWORD x); -}; - -///////////////////////////////////////////////////////////////////// -inline -CImageIterator::CImageIterator(void) -{ - ima = 0; - IterImage = 0; - Itx = Ity = 0; - Stepx = Stepy = 0; -} -///////////////////////////////////////////////////////////////////// -inline -CImageIterator::CImageIterator(CxImage *imageImpl): ima(imageImpl) -{ - if (ima) IterImage = ima->GetBits(); - Itx = Ity = 0; - Stepx = Stepy = 0; -} -///////////////////////////////////////////////////////////////////// -inline -CImageIterator::operator CxImage* () -{ - return ima; -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::ItOK () -{ - if (ima) return ima->IsInside(Itx, Ity); - else return false; -} -///////////////////////////////////////////////////////////////////// -inline void CImageIterator::Reset() -{ - if (ima) IterImage = ima->GetBits(); - else IterImage=0; - Itx = Ity = 0; -} -///////////////////////////////////////////////////////////////////// -inline void CImageIterator::Upset() -{ - Itx = 0; - Ity = ima->GetHeight()-1; - IterImage = ima->GetBits() + ima->GetEffWidth()*(ima->GetHeight()-1); -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::NextRow() -{ - if (++Ity >= (int)ima->GetHeight()) return false; - IterImage += ima->GetEffWidth(); - return true; -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::PrevRow() -{ - if (--Ity < 0) return false; - IterImage -= ima->GetEffWidth(); - return true; -} -/* AD - for interlace */ -inline void CImageIterator::SetY(int y) -{ - if ((y < 0) || (y > (int)ima->GetHeight())) return; - Ity = y; - IterImage = ima->GetBits() + ima->GetEffWidth()*y; -} -///////////////////////////////////////////////////////////////////// -inline void CImageIterator::SetRow(BYTE *buf, int n) -{ - if (n<0) n = (int)ima->GetEffWidth(); - else n = MIN(n,(int)ima->GetEffWidth()); - - if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n); -} -///////////////////////////////////////////////////////////////////// -inline void CImageIterator::GetRow(BYTE *buf, int n) -{ - if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) - memcpy(buf,IterImage,MIN(n,(int)ima->GetEffWidth())); -} -///////////////////////////////////////////////////////////////////// -inline BYTE* CImageIterator::GetRow() -{ - return IterImage; -} -///////////////////////////////////////////////////////////////////// -inline BYTE* CImageIterator::GetRow(int n) -{ - SetY(n); - return IterImage; -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::NextByte() -{ - if (++Itx < (int)ima->GetEffWidth()) return true; - else - if (++Ity < (int)ima->GetHeight()){ - IterImage += ima->GetEffWidth(); - Itx = 0; - return true; - } else - return false; -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::PrevByte() -{ - if (--Itx >= 0) return true; - else - if (--Ity >= 0){ - IterImage -= ima->GetEffWidth(); - Itx = 0; - return true; - } else - return false; -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::NextStep() -{ - Itx += Stepx; - if (Itx < (int)ima->GetEffWidth()) return true; - else { - Ity += Stepy; - if (Ity < (int)ima->GetHeight()){ - IterImage += ima->GetEffWidth(); - Itx = 0; - return true; - } else - return false; - } -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::PrevStep() -{ - Itx -= Stepx; - if (Itx >= 0) return true; - else { - Ity -= Stepy; - if (Ity >= 0 && Ity < (int)ima->GetHeight()) { - IterImage -= ima->GetEffWidth(); - Itx = 0; - return true; - } else - return false; - } -} -///////////////////////////////////////////////////////////////////// -inline bool CImageIterator::GetCol(BYTE* pCol, DWORD x) -{ - if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth())) - return false; - DWORD h = ima->GetHeight(); - //DWORD line = ima->GetEffWidth(); - BYTE bytes = (BYTE)(ima->GetBpp()>>3); - BYTE* pSrc; - for (DWORD y=0;yGetBits(y) + x*bytes; - for (BYTE w=0;wGetBpp()<8)||(x>=ima->GetWidth())) - return false; - DWORD h = ima->GetHeight(); - //DWORD line = ima->GetEffWidth(); - BYTE bytes = (BYTE)(ima->GetBpp()>>3); - BYTE* pSrc; - for (DWORD y=0;yGetBits(y) + x*bytes; - for (BYTE w=0;w - -struct jpg_error_mgr { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ - char* buffer; /* error message */ -}; -typedef jpg_error_mgr *jpg_error_ptr; - -//////////////////////////////////////////////////////////////////////////////// -// Here's the routine that will replace the standard error_exit method: -//////////////////////////////////////////////////////////////////////////////// -static void -ima_jpeg_error_exit (j_common_ptr cinfo) -{ - /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ - jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err; - /* Create the message */ - myerr->pub.format_message (cinfo, myerr->buffer); - /* Send it to stderr, adding a newline */ - /* Return control to the setjmp point */ - longjmp(myerr->setjmp_buffer, 1); -} -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::CxImageJPG(): CxImage(CXIMAGE_FORMAT_JPG) -{ -#if CXIMAGEJPG_SUPPORT_EXIF - m_exif = NULL; - memset(&m_exifinfo, 0, sizeof(EXIFINFO)); -#endif -} -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::~CxImageJPG() -{ -#if CXIMAGEJPG_SUPPORT_EXIF - if (m_exif) delete m_exif; -#endif -} -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGEJPG_SUPPORT_EXIF -bool CxImageJPG::DecodeExif(CxFile * hFile) -{ - m_exif = new CxExifInfo(&m_exifinfo); - if (m_exif){ - long pos=hFile->Tell(); - m_exif->DecodeExif(hFile); - hFile->Seek(pos,SEEK_SET); - return m_exif->m_exifinfo->IsExif; - } else { - return false; - } -} -#endif //CXIMAGEJPG_SUPPORT_EXIF -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// -bool CxImageJPG::Decode(CxFile * hFile) -{ - - bool is_exif = false; -#if CXIMAGEJPG_SUPPORT_EXIF - is_exif = DecodeExif(hFile); -#endif - - CImageIterator iter(this); - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. */ - struct jpg_error_mgr jerr; - jerr.buffer=info.szLastError; - /* More stuff */ - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - /* Step 1: allocate and initialize JPEG decompression object */ - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = ima_jpeg_error_exit; - - /* Establish the setjmp return context for my_error_exit to use. */ -#pragma warning(push) -#pragma warning(disable:4611) - if (setjmp(jerr.setjmp_buffer)) { -#pragma warning(pop) - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - jpeg_destroy_decompress(&cinfo); - return 0; - } - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - /* Step 2: specify data source (eg, a file) */ - //jpeg_stdio_src(&cinfo, infile); - CxFileJpg src(hFile); - cinfo.src = &src; - - /* Step 3: read file parameters with jpeg_read_header() */ - (void) jpeg_read_header(&cinfo, true); - - /* Step 4 handle decoder options*/ - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_GRAYSCALE) != 0) - cinfo.out_color_space = JCS_GRAYSCALE; - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_QUANTIZE) != 0) { - cinfo.quantize_colors = true; - cinfo.desired_number_of_colors = GetJpegQuality(); - } - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_DITHER) != 0) - cinfo.dither_mode = m_nDither; - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_ONEPASS) != 0) - cinfo.two_pass_quantize = false; - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_NOSMOOTH) != 0) - cinfo.do_fancy_upsampling = false; - -//: Load true color images as RGB (no quantize) -/* Step 4: set parameters for decompression */ -/* if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) { - * cinfo.quantize_colors = true; - * cinfo.desired_number_of_colors = 128; - *} - */ // - - // Set the scale - cinfo.scale_denom = GetJpegScale(); - - // Borrowed the idea from GIF implementation - if (info.nEscape == -1) { - // Return output dimensions only - jpeg_calc_output_dimensions(&cinfo); - head.biWidth = cinfo.output_width; - head.biHeight = cinfo.output_height; - info.dwType = CXIMAGE_FORMAT_JPG; - jpeg_destroy_decompress(&cinfo); - return true; - } - - /* Step 5: Start decompressor */ - jpeg_start_decompress(&cinfo); - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - */ - //Create the image using output dimensions - //Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG); - Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG); - - if (!pDib) longjmp(jerr.setjmp_buffer, 1); // check if the image has been created - - if (is_exif){ -#if CXIMAGEJPG_SUPPORT_EXIF - if ((m_exifinfo.Xresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0)) - SetXDPI((long)(m_exifinfo.Xresolution/m_exifinfo.ResolutionUnit)); - if ((m_exifinfo.Yresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0)) - SetYDPI((long)(m_exifinfo.Yresolution/m_exifinfo.ResolutionUnit)); -#endif - } else { - switch (cinfo.density_unit) { - case 0: // [andy] fix for aspect ratio... - if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){ - SetYDPI((long)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density)))); - } - break; - case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter - SetXDPI((long)floor(cinfo.X_density * 2.54 + 0.5)); - SetYDPI((long)floor(cinfo.Y_density * 2.54 + 0.5)); - break; - default: - SetXDPI(cinfo.X_density); - SetYDPI(cinfo.Y_density); - } - } - - if (cinfo.out_color_space==JCS_GRAYSCALE){ - SetGrayPalette(); - head.biClrUsed =256; - } else { - if (cinfo.quantize_colors){ - SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]); - head.biClrUsed=cinfo.actual_number_of_colors; - } else { - head.biClrUsed=0; - } - } - - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components; - - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - /* Step 6: while (scan lines remain to be read) */ - /* jpeg_read_scanlines(...); */ - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - iter.Upset(); - while (cinfo.output_scanline < cinfo.output_height) { - - if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // - cancel decoding - - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - // info.nProgress = (long)(100*cinfo.output_scanline/cinfo.output_height); - // Step 6a: CMYK->RGB */ - if ((cinfo.num_components==4)&&(cinfo.quantize_colors==false)){ - BYTE k,*dst,*src; - dst=iter.GetRow(); - src=buffer[0]; - for(long x3=0,x4=0; x3<(long)info.dwEffWidth && x4 Step 7A: Swap red and blue components - // not necessary if swapped red and blue definition in jmorecfg.h;ln322 - if ((cinfo.num_components==3)&&(cinfo.quantize_colors==false)){ - BYTE* r0=GetBits(); - for(long y=0;y - cancel decoding - RGBtoBGR(r0,3*head.biWidth); - r0+=info.dwEffWidth; - } - } - - /* Step 8: Release JPEG decompression object */ - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&cinfo); - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_ENCODE - -#ifdef DEBUG -// XXX: dirty hack. -#undef max -#undef min -#define XRCORE_API XR_IMPORT -#include "xrCore/xrDebug_macros.h" // needed for VERIFY in FTimer.h -#include "xrCommon/math_funcs_inline.h" // needed for fis_zero() in FTimer.h -#include "xrCore/FTimer.h" -#include "xrCore/log.h" -#undef XRCORE_API -#endif - -//////////////////////////////////////////////////////////////////////////////// -bool CxImageJPG::Encode(CxFile * hFile) -{ - if (EncodeSafeCheck(hFile)) return false; - - if (head.biClrUsed!=0 && !IsGrayScale()){ - strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images"); - return false; - } - - // necessary for EXIF, and for roll backs - long pos=hFile->Tell(); - - /* This struct contains the JPEG compression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - * It is possible to have several such structures, representing multiple - * compression/decompression processes, in existence at once. We refer - * to any one struct (and its associated working data) as a "JPEG object". - */ - struct jpeg_compress_struct cinfo; - /* This struct represents a JPEG error handler. It is declared separately - * because applications often want to supply a specialized error handler - * (see the second half of this file for an example). But here we just - * take the easy way out and use the standard error handler, which will - * print a message on stderr and call exit() if compression fails. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - //struct jpeg_error_mgr jerr; - /* We use our private extension JPEG error handler. */ - struct jpg_error_mgr jerr; - jerr.buffer=info.szLastError; - /* More stuff */ - int row_stride; /* physical row width in image buffer */ - JSAMPARRAY buffer; /* Output row buffer */ - - /* Step 1: allocate and initialize JPEG compression object */ - /* We have to set up the error handler first, in case the initialization - * step fails. (Unlikely, but it could happen if you are out of memory.) - * This routine fills in the contents of struct jerr, and returns jerr's - * address which we place into the link field in cinfo. - */ - //cinfo.err = jpeg_std_error(&jerr); - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = ima_jpeg_error_exit; - - /* Establish the setjmp return context for my_error_exit to use. */ -#pragma warning(push) -#pragma warning(disable:4611) - if (setjmp(jerr.setjmp_buffer)) { -#pragma warning(pop) - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - strcpy(info.szLastError, jerr.buffer); // - jpeg_destroy_compress(&cinfo); - return 0; - } - - /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - /* Step 2: specify data destination (eg, a file) */ - /* Note: steps 2 and 3 can be done in either order. */ - /* Here we use the library-supplied code to send compressed data to a - * stdio stream. You can also write your own code to do something else. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to write binary files. - */ - - //jpeg_stdio_dest(&cinfo, outfile); - CxFileJpg dest(hFile); - cinfo.dest = &dest; - - /* Step 3: set parameters for compression */ - /* First we supply a description of the input image. - * Four fields of the cinfo struct must be filled in: - */ - cinfo.image_width = GetWidth(); // image width and height, in pixels - cinfo.image_height = GetHeight(); - - if (IsGrayScale()){ - cinfo.input_components = 1; // # of color components per pixel - cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */ - } else { - cinfo.input_components = 3; // # of color components per pixel - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - } - - /* Now use the library's routine to set default compression parameters. - * (You must set at least cinfo.in_color_space before calling this, - * since the defaults depend on the source color space.) - */ - jpeg_set_defaults(&cinfo); - /* Now you can set any non-default parameters you wish to. - * Here we just illustrate the use of quality (quantization table) scaling: - */ - -//#ifdef C_ARITH_CODING_SUPPORTED - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_ARITHMETIC) != 0) - cinfo.arith_code = true; -//#endif - -//#ifdef ENTROPY_OPT_SUPPORTED - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_OPTIMIZE) != 0) - cinfo.optimize_coding = true; -//#endif - - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_GRAYSCALE) != 0) - jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); - - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SMOOTHING) != 0) - cinfo.smoothing_factor = m_nSmoothing; - - jpeg_set_quality(&cinfo, GetJpegQuality(), (GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_BASELINE) != 0); - -//#ifdef C_PROGRESSIVE_SUPPORTED - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_PROGRESSIVE) != 0) - jpeg_simple_progression(&cinfo); -//#endif - -#ifdef C_LOSSLESS_SUPPORTED - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_LOSSLESS) != 0) - jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform); -#endif - - //SetCodecOption(ENCODE_SUBSAMPLE_444 | GetCodecOption(CXIMAGE_FORMAT_JPG),CXIMAGE_FORMAT_JPG); - - // 2x2, 1x1, 1x1 (4:1:1) : High (default sub sampling) - cinfo.comp_info[0].h_samp_factor = 2; - cinfo.comp_info[0].v_samp_factor = 2; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SUBSAMPLE_422) != 0){ - // 2x1, 1x1, 1x1 (4:2:2) : Medium - cinfo.comp_info[0].h_samp_factor = 2; - cinfo.comp_info[0].v_samp_factor = 1; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - } - - if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SUBSAMPLE_444) != 0){ - // 1x1 1x1 1x1 (4:4:4) : None - cinfo.comp_info[0].h_samp_factor = 1; - cinfo.comp_info[0].v_samp_factor = 1; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - } - - cinfo.density_unit=1; - cinfo.X_density=(unsigned short)GetXDPI(); - cinfo.Y_density=(unsigned short)GetYDPI(); - - /* Step 4: Start compressor */ - /* true ensures that we will write a complete interchange-JPEG file. - * Pass true unless you are very sure of what you're doing. - */ - jpeg_start_compress(&cinfo, true); - - /* Step 5: while (scan lines remain to be written) */ - /* jpeg_write_scanlines(...); */ - /* Here we use the library's state variable cinfo.next_scanline as the - * loop counter, so that we don't have to keep track ourselves. - * To keep things simple, we pass one scanline per call; you can pass - * more if you wish, though. - */ - row_stride = info.dwEffWidth; /* JSAMPLEs per row in image_buffer */ - - // "8+row_stride" fix heap deallocation problem during debug??? - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1); - - CImageIterator iter(this); - -#ifdef DEBUG - CTimer tmp_dbg_timer; - tmp_dbg_timer.Start(); -#endif //#ifdef DEBUG - - iter.Upset(); - while (cinfo.next_scanline < cinfo.image_height) { - // info.nProgress = (long)(100*cinfo.next_scanline/cinfo.image_height); - iter.GetRow(buffer[0], row_stride); - // not necessary if swapped red and blue definition in jmorecfg.h;ln322 - if (head.biClrUsed==0){ // swap R & B for RGB images - RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9 - } - iter.PrevRow(); - (void) jpeg_write_scanlines(&cinfo, buffer, 1); - } - -#ifdef DEBUG - Msg("JPEG compressing cycle time : %u ms", tmp_dbg_timer.GetElapsed_ms()); -#endif - - - /* Step 6: Finish compression */ - jpeg_finish_compress(&cinfo); - - /* Step 7: release JPEG compression object */ - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_compress(&cinfo); - - -#if CXIMAGEJPG_SUPPORT_EXIF - if (m_exif && m_exif->m_exifinfo->IsExif){ - // discard useless sections (if any) read from original image - m_exif->DiscardAllButExif(); - // read new created image, to split the sections - hFile->Seek(pos,SEEK_SET); - m_exif->DecodeExif(hFile,EXIF_READ_IMAGE); - // save back the image, adding EXIF section - hFile->Seek(pos,SEEK_SET); - m_exif->EncodeExif(hFile); - } -#endif - - - /* And we're done! */ - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#endif // CXIMAGE_SUPPORT_ENCODE -//////////////////////////////////////////////////////////////////////////////// -#endif // CXIMAGE_SUPPORT_JPG - diff --git a/Externals/cximage/ximajpg.h b/Externals/cximage/ximajpg.h deleted file mode 100644 index 900c1cf4b02..00000000000 --- a/Externals/cximage/ximajpg.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * File: ximajpg.h - * Purpose: JPG Image Class Loader and Writer - */ -/* ========================================================== - * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it - * For conditions of distribution and use, see copyright notice in ximage.h - * - * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes - * - * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code - * - * EXIF support based on jhead-1.8 by Matthias Wandel - * - * original CImageJPG and CImageIterator implementation are: - * Copyright: (c) 1995, Alejandro Aguilar Sierra - * - * This software is based in part on the work of the Independent JPEG Group. - * Copyright (C) 1991-1998, Thomas G. Lane. - * ========================================================== - */ -#if !defined(__ximaJPEG_h) -#define __ximaJPEG_h - -#include "ximage.h" - -#if CXIMAGE_SUPPORT_JPG - -#include -#include - -#define CXIMAGEJPG_SUPPORT_EXIF 1 - -class DLL_EXP CxImageJPG: public CxImage -{ -public: - CxImageJPG(); - ~CxImageJPG(); - -// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);} -// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);} - bool Decode(CxFile * hFile); - bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } - -#if CXIMAGE_SUPPORT_ENCODE - bool Encode(CxFile * hFile); - bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } -#endif // CXIMAGE_SUPPORT_ENCODE - -/* - * EXIF support based on jhead-1.8 by Matthias Wandel - */ - -#if CXIMAGEJPG_SUPPORT_EXIF - -#define MAX_COMMENT 1000 -#define MAX_SECTIONS 20 - -typedef struct tag_ExifInfo { - char Version [5]; - char CameraMake [32]; - char CameraModel [40]; - char DateTime [20]; - int Height, Width; - int Orientation; - int IsColor; - int Process; - int FlashUsed; - float FocalLength; - float ExposureTime; - float ApertureFNumber; - float Distance; - float CCDWidth; - float ExposureBias; - int Whitebalance; - int MeteringMode; - int ExposureProgram; - int ISOequivalent; - int CompressionLevel; - float FocalplaneXRes; - float FocalplaneYRes; - float FocalplaneUnits; - float Xresolution; - float Yresolution; - float ResolutionUnit; - float Brightness; - char Comments[MAX_COMMENT]; - - unsigned char * ThumbnailPointer; /* Pointer at the thumbnail */ - unsigned ThumbnailSize; /* Size of thumbnail. */ - - bool IsExif; -} EXIFINFO; - -//-------------------------------------------------------------------------- -// JPEG markers consist of one or more 0xFF bytes, followed by a marker -// code byte (which is not an FF). Here are the marker codes of interest -// in this program. (See jdmarker.c for a more complete list.) -//-------------------------------------------------------------------------- - -#define M_SOF0 0xC0 // Start Of Frame N -#define M_SOF1 0xC1 // N indicates which compression process -#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use -#define M_SOF3 0xC3 -#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers -#define M_SOF6 0xC6 -#define M_SOF7 0xC7 -#define M_SOF9 0xC9 -#define M_SOF10 0xCA -#define M_SOF11 0xCB -#define M_SOF13 0xCD -#define M_SOF14 0xCE -#define M_SOF15 0xCF -#define M_SOI 0xD8 // Start Of Image (beginning of datastream) -#define M_EOI 0xD9 // End Of Image (end of datastream) -#define M_SOS 0xDA // Start Of Scan (begins compressed data) -#define M_JFIF 0xE0 // Jfif marker -#define M_EXIF 0xE1 // Exif marker -#define M_COM 0xFE // COMment - -#define PSEUDO_IMAGE_MARKER 0x123; // Extra value. - -#define EXIF_READ_EXIF 0x01 -#define EXIF_READ_IMAGE 0x02 -#define EXIF_READ_ALL 0x03 - -class DLL_EXP CxExifInfo -{ - -typedef struct tag_Section_t{ - BYTE* Data; - int Type; - unsigned Size; -} Section_t; - -public: - EXIFINFO* m_exifinfo; - char m_szLastError[256]; - CxExifInfo(EXIFINFO* info = NULL); - ~CxExifInfo(); - bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF); - bool EncodeExif(CxFile * hFile); - void DiscardAllButExif(); -protected: - bool process_EXIF(unsigned char * CharBuf, unsigned int length); - void process_COM (const BYTE * Data, int length); - void process_SOFn (const BYTE * Data, int marker); - int Get16u(void * Short); - int Get16m(void * Short); - long Get32s(void * Long); - unsigned long Get32u(void * Long); - double ConvertAnyFormat(void * ValuePtr, int Format); - void* FindSection(int SectionType); - bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, - EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP, int NestingLevel=0); - int ExifImageWidth; - int MotorolaOrder; - Section_t Sections[MAX_SECTIONS]; - int SectionsRead; - bool freeinfo; -}; - - CxExifInfo* m_exif; - EXIFINFO m_exifinfo; - bool DecodeExif(CxFile * hFile); - bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); } - -#endif //CXIMAGEJPG_SUPPORT_EXIF - -//////////////////////////////////////////////////////////////////////////////////////// -////////////////////// C x F i l e J p g //////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -// thanks to Chris Shearer Cooper -class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr - { -public: - enum { eBufSize = 4096 }; - - CxFileJpg(CxFile* pFile) - { - m_pFile = pFile; - - init_destination = InitDestination; - empty_output_buffer = EmptyOutputBuffer; - term_destination = TermDestination; - - init_source = InitSource; - fill_input_buffer = FillInputBuffer; - skip_input_data = SkipInputData; - resync_to_restart = jpeg_resync_to_restart; // use default method - term_source = TermSource; - next_input_byte = NULL; //* => next byte to read from buffer - bytes_in_buffer = 0; //* # of bytes remaining in buffer - - m_pBuffer = new unsigned char[eBufSize]; - } - ~CxFileJpg() - { - delete [] m_pBuffer; - } - - static void InitDestination(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - pDest->next_output_byte = pDest->m_pBuffer; - pDest->free_in_buffer = eBufSize; - } - - static boolean EmptyOutputBuffer(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize) - ERREXIT(cinfo, JERR_FILE_WRITE); - pDest->next_output_byte = pDest->m_pBuffer; - pDest->free_in_buffer = eBufSize; - return true; - } - - static void TermDestination(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - size_t datacount = eBufSize - pDest->free_in_buffer; - /* Write any data remaining in the buffer */ - if (datacount > 0) { - if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount)) - ERREXIT(cinfo, JERR_FILE_WRITE); - } - pDest->m_pFile->Flush(); - /* Make sure we wrote the output file OK */ - if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE); - return; - } - - static void InitSource(j_decompress_ptr cinfo) - { - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - pSource->m_bStartOfFile = true; - } - - static boolean FillInputBuffer(j_decompress_ptr cinfo) - { - size_t nbytes; - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize); - if (nbytes <= 0){ - if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error - ERREXIT(cinfo, JERR_INPUT_EMPTY); - WARNMS(cinfo, JWRN_JPEG_EOF); - // Insert a fake EOI marker - pSource->m_pBuffer[0] = (JOCTET) 0xFF; - pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } - pSource->next_input_byte = pSource->m_pBuffer; - pSource->bytes_in_buffer = nbytes; - pSource->m_bStartOfFile = false; - return true; - } - - static void SkipInputData(j_decompress_ptr cinfo, long num_bytes) - { - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - if (num_bytes > 0){ - while (num_bytes > (long)pSource->bytes_in_buffer){ - num_bytes -= (long)pSource->bytes_in_buffer; - FillInputBuffer(cinfo); - // note we assume that fill_input_buffer will never return false, - // so suspension need not be handled. - } - pSource->next_input_byte += (size_t) num_bytes; - pSource->bytes_in_buffer -= (size_t) num_bytes; - } - } - - static void TermSource(j_decompress_ptr /*cinfo*/) - { - return; - } -protected: - CxFile *m_pFile; - unsigned char *m_pBuffer; - bool m_bStartOfFile; -}; - -public: - enum CODEC_OPTION - { - ENCODE_BASELINE = 0x1, - ENCODE_ARITHMETIC = 0x2, - ENCODE_GRAYSCALE = 0x4, - ENCODE_OPTIMIZE = 0x8, - ENCODE_PROGRESSIVE = 0x10, - ENCODE_LOSSLESS = 0x20, - ENCODE_SMOOTHING = 0x40, - DECODE_GRAYSCALE = 0x80, - DECODE_QUANTIZE = 0x100, - DECODE_DITHER = 0x200, - DECODE_ONEPASS = 0x400, - DECODE_NOSMOOTH = 0x800, - ENCODE_SUBSAMPLE_422 = 0x1000, - ENCODE_SUBSAMPLE_444 = 0x2000 - }; - - int m_nPredictor; - int m_nPointTransform; - int m_nSmoothing; - int m_nQuantize; - J_DITHER_MODE m_nDither; - -}; - -#endif - -#endif diff --git a/Externals/cximage/ximalpha.cpp b/Externals/cximage/ximalpha.cpp deleted file mode 100644 index e595c0bbbcf..00000000000 --- a/Externals/cximage/ximalpha.cpp +++ /dev/null @@ -1,365 +0,0 @@ -// xImalpha.cpp : Alpha channel functions -/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -#if CXIMAGE_SUPPORT_ALPHA - -//////////////////////////////////////////////////////////////////////////////// -/** - * \sa AlphaSetMax - */ -BYTE CxImage::AlphaGetMax() const -{ - return info.nAlphaMax; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets global Alpha (opacity) value applied to the whole image, - * valid only for painting functions. - * \param nAlphaMax: can be from 0 to 255 - */ -void CxImage::AlphaSetMax(BYTE nAlphaMax) -{ - info.nAlphaMax=nAlphaMax; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the image has a valid alpha channel. - */ -bool CxImage::AlphaIsValid() -{ - return pAlpha!=0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Enables the alpha palette, so the Draw() function changes its behavior. - */ -void CxImage::AlphaPaletteEnable(bool enable) -{ - info.bAlphaPaletteEnabled=enable; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * True if the alpha palette is enabled for painting. - */ -bool CxImage::AlphaPaletteIsEnabled() -{ - return info.bAlphaPaletteEnabled; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the alpha channel to full transparent. AlphaSet(0) has the same effect - */ -void CxImage::AlphaClear() -{ - if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets the alpha level for the whole image. - * \param level : from 0 (transparent) to 255 (opaque) - */ -void CxImage::AlphaSet(BYTE level) -{ - if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Allocates an empty (opaque) alpha channel. - */ -bool CxImage::AlphaCreate() -{ - if (pAlpha==NULL) { - pAlpha = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight); - } - return (pAlpha!=0); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::AlphaDelete() -{ - if (pAlpha) { cxfree(pAlpha);/*free(pAlpha);*/ pAlpha=0; } -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::AlphaInvert() -{ - if (pAlpha) { - BYTE *iSrc=pAlpha; - long n=head.biHeight*head.biWidth; - for(long i=0; i < n; i++){ - *iSrc=(BYTE)~(*(iSrc)); - iSrc++; - } - } -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Imports an existing alpa channel from another image with the same width and height. - */ -bool CxImage::AlphaCopy(CxImage &from) -{ - if (from.pAlpha == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false; - if (pAlpha==NULL) pAlpha = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - if (pAlpha==NULL) return false; - memcpy(pAlpha,from.pAlpha,head.biWidth * head.biHeight); - info.nAlphaMax=from.info.nAlphaMax; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Creates the alpha channel from a gray scale image. - */ -bool CxImage::AlphaSet(CxImage &from) -{ - if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false; - if (pAlpha==NULL) pAlpha = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - BYTE* src = from.info.pImage; - BYTE* dst = pAlpha; - if (src==NULL || dst==NULL) return false; - for (long y=0; y>8); - c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8); - c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8); - BlindSetPixelColor(x,y,c); - } - } - AlphaDelete(); - } else { - CxImage tmp(head.biWidth,head.biHeight,24); - if (!tmp.IsValid()){ - strcpy(info.szLastError,tmp.GetLastError()); - return; - } - - for(long y=0; y>8); - c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8); - c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8); - tmp.BlindSetPixelColor(x,y,c); - } - } - Transfer(tmp); - } - return; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::AlphaFlip() -{ - if (!pAlpha) return false; - - BYTE *buff = (BYTE*)cxalloc(head.biWidth);//malloc(head.biWidth); - if (!buff) return false; - - BYTE *iSrc,*iDst; - iSrc = pAlpha + (head.biHeight-1)*head.biWidth; - iDst = pAlpha; - for (long i=0; i<(head.biHeight/2); ++i) - { - memcpy(buff, iSrc, head.biWidth); - memcpy(iSrc, iDst, head.biWidth); - memcpy(iDst, buff, head.biWidth); - iSrc-=head.biWidth; - iDst+=head.biWidth; - } - - cxfree(buff);//free(buff); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::AlphaMirror() -{ - if (!pAlpha) return false; - BYTE* pAlpha2 = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - if (!pAlpha2) return false; - BYTE *iSrc,*iDst; - long wdt=head.biWidth-1; - iSrc=pAlpha + wdt; - iDst=pAlpha2; - for(long y=0; y < head.biHeight; y++){ - for(long x=0; x <= wdt; x++) - *(iDst+x)=*(iSrc-x); - iSrc+=head.biWidth; - iDst+=head.biWidth; - } - cxfree(pAlpha);//free(pAlpha); - pAlpha=pAlpha2; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Exports the alpha channel in a 8bpp grayscale image. - */ -bool CxImage::AlphaSplit(CxImage *dest) -{ - if (!pAlpha || !dest) return false; - - CxImage tmp(head.biWidth,head.biHeight,8); - if (!tmp.IsValid()){ - strcpy(info.szLastError,tmp.GetLastError()); - return false; - } - - for(long y=0; yTransfer(tmp); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Exports the alpha palette channel in a 8bpp grayscale image. - */ -bool CxImage::AlphaPaletteSplit(CxImage *dest) -{ - if (!AlphaPaletteIsValid() || !dest) return false; - - CxImage tmp(head.biWidth,head.biHeight,8); - if (!tmp.IsValid()){ - strcpy(info.szLastError,tmp.GetLastError()); - return false; - } - - for(long y=0; yTransfer(tmp); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Merge in the alpha layer the transparent color mask - * (previously set with SetTransColor or SetTransIndex) - */ -bool CxImage::AlphaFromTransparency() -{ - if (!IsValid() || !IsTransparent()) - return false; - - AlphaCreate(); - - for(long y=0; y info.nNumLayers ) position = info.nNumLayers; - - CxImage** ptmp = new CxImage*[info.nNumLayers + 1]; - if (ptmp==0) return false; - - int i=0; - for (int n=0; ninfo.pParent = this; - } else { - cxfree(ptmp);//free(ptmp); - return false; - } - - info.nNumLayers++; - delete [] ppLayers; - ppLayers = ptmp; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Deletes a layer. If position is less than 0, the last layer will be deleted - */ -bool CxImage::LayerDelete(long position) -{ - if ( position >= info.nNumLayers ) return false; - if ( position < 0) position = info.nNumLayers - 1; - if ( position < 0) return false; - - if (info.nNumLayers>1){ - - CxImage** ptmp = new CxImage*[info.nNumLayers - 1]; - if (ptmp==0) return false; - - int i=0; - for (int n=0; n= info.nNumLayers ) return NULL; - if ( position < 0) position = info.nNumLayers - 1; - return ppLayers[position]; -} -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_LAYERS diff --git a/Externals/cximage/ximapal.cpp b/Externals/cximage/ximapal.cpp deleted file mode 100644 index 97f0d9aeaa0..00000000000 --- a/Externals/cximage/ximapal.cpp +++ /dev/null @@ -1,834 +0,0 @@ -// xImaPal.cpp : Palette and Pixel functions -/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -//////////////////////////////////////////////////////////////////////////////// -/** - * returns the palette dimension in byte - */ -DWORD CxImage::GetPaletteSize() -{ - return (head.biClrUsed * sizeof(RGBQUAD)); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha) -{ - if ((pDib)&&(head.biClrUsed)){ - BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER); - if (idx=head.biWidth)||(y>=head.biHeight)) { - if (info.nBkgndIndex >= 0) return (BYTE)info.nBkgndIndex; - else return *info.pImage; - } - if (head.biBitCount==8){ - return info.pImage[y*info.dwEffWidth + x]; - } else { - BYTE pos; - BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)]; - if (head.biBitCount==4){ - pos = (BYTE)(4*(1-x%2)); - iDst &= (0x0F<> pos); - } else if (head.biBitCount==1){ - pos = (BYTE)(7-x%8); - iDst &= (0x01<> pos); - } - } - return 0; -} -//////////////////////////////////////////////////////////////////////////////// -BYTE CxImage::BlindGetPixelIndex(const long x,const long y) -{ -#ifdef _DEBUG - if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return 0; - #endif -#endif - - if (head.biBitCount==8){ - return info.pImage[y*info.dwEffWidth + x]; - } else { - BYTE pos; - BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)]; - if (head.biBitCount==4){ - pos = (BYTE)(4*(1-x%2)); - iDst &= (0x0F<> pos); - } else if (head.biBitCount==1){ - pos = (BYTE)(7-x%8); - iDst &= (0x01<> pos); - } - } - return 0; -} -//////////////////////////////////////////////////////////////////////////////// -RGBQUAD CxImage::GetPixelColor(long x,long y, bool bGetAlpha) -{ -// RGBQUAD rgb={0,0,0,0}; - RGBQUAD rgb=info.nBkgndColor; // - if ((pDib==NULL)||(x<0)||(y<0)|| - (x>=head.biWidth)||(y>=head.biHeight)){ - if (info.nBkgndIndex >= 0){ - if (head.biBitCount<24) return GetPaletteColor((BYTE)info.nBkgndIndex); - else return info.nBkgndColor; - } else if (pDib) return GetPixelColor(0,0); - return rgb; - } - - if (head.biClrUsed){ - rgb = GetPaletteColor(BlindGetPixelIndex(x,y)); - } else { - BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3; - rgb.rgbBlue = *iDst++; - rgb.rgbGreen= *iDst++; - rgb.rgbRed = *iDst; - } -#if CXIMAGE_SUPPORT_ALPHA - if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y); -#else - rgb.rgbReserved = 0; -#endif //CXIMAGE_SUPPORT_ALPHA - return rgb; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * This is (a bit) faster version of GetPixelColor. - * It tests bounds only in debug mode (_DEBUG defined). - * - * It is an error to request out-of-borders pixel with this method. - * In DEBUG mode an exception will be thrown, and data will be violated in non-DEBUG mode. - * \author ***bd*** 2.2004 - */ -RGBQUAD CxImage::BlindGetPixelColor(const long x,const long y, bool bGetAlpha) -{ - RGBQUAD rgb; -#ifdef _DEBUG - if ((pDib==NULL) || !IsInside(x,y)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - {rgb.rgbReserved = 0; return rgb;} - #endif -#endif - - if (head.biClrUsed){ - rgb = GetPaletteColor(BlindGetPixelIndex(x,y)); - } else { - BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3; - rgb.rgbBlue = *iDst++; - rgb.rgbGreen= *iDst++; - rgb.rgbRed = *iDst; - rgb.rgbReserved = 0; //needed for images without alpha layer - } -#if CXIMAGE_SUPPORT_ALPHA - if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y); -#else - rgb.rgbReserved = 0; -#endif //CXIMAGE_SUPPORT_ALPHA - return rgb; -} -//////////////////////////////////////////////////////////////////////////////// -BYTE CxImage::GetPixelGray(long x, long y) -{ - RGBQUAD color = GetPixelColor(x,y); - return (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::BlindSetPixelIndex(long x,long y,BYTE i) -{ -#ifdef _DEBUG - if ((pDib==NULL)||(head.biClrUsed==0)|| - (x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return; - #endif -#endif - - if (head.biBitCount==8){ - info.pImage[y*info.dwEffWidth + x]=i; - return; - } else { - BYTE pos; - BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3); - if (head.biBitCount==4){ - pos = (BYTE)(4*(1-x%2)); - *iDst &= ~(0x0F<=head.biWidth)||(y>=head.biHeight)) return ; - - if (head.biBitCount==8){ - info.pImage[y*info.dwEffWidth + x]=i; - return; - } else { - BYTE pos; - BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3); - if (head.biBitCount==4){ - pos = (BYTE)(4*(1-x%2)); - *iDst &= ~(0x0F<=head.biWidth)||(y>=head.biHeight)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return; - #endif -#endif - if (head.biClrUsed) - BlindSetPixelIndex(x,y,GetNearestIndex(c)); - else { - BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3; - *iDst++ = c.rgbBlue; - *iDst++ = c.rgbGreen; - *iDst = c.rgbRed; - } -#if CXIMAGE_SUPPORT_ALPHA - if (bSetAlpha) AlphaSet(x,y,c.rgbReserved); -#endif //CXIMAGE_SUPPORT_ALPHA -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha) -{ - if ((pDib==NULL)||(x<0)||(y<0)|| - (x>=head.biWidth)||(y>=head.biHeight)) return; - if (head.biClrUsed) - BlindSetPixelIndex(x,y,GetNearestIndex(c)); - else { - BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3; - *iDst++ = c.rgbBlue; - *iDst++ = c.rgbGreen; - *iDst = c.rgbRed; - } -#if CXIMAGE_SUPPORT_ALPHA - if (bSetAlpha) AlphaSet(x,y,c.rgbReserved); -#endif //CXIMAGE_SUPPORT_ALPHA -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Blends the current pixel color with a new color. - * \param x,y = pixel - * \param c = new color - * \param blend = can be from 0 (no effect) to 1 (full effect). - * \param bSetAlpha = if true, blends also the alpha component stored in c.rgbReserved - */ -void CxImage::BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha) -{ - if ((pDib==NULL)||(x<0)||(y<0)|| - (x>=head.biWidth)||(y>=head.biHeight)) return; - - int a0 = (int)(256*blend); - int a1 = 256 - a0; - - RGBQUAD c0 = BlindGetPixelColor(x,y); - c.rgbRed = (BYTE)((c.rgbRed * a0 + c0.rgbRed * a1)>>8); - c.rgbBlue = (BYTE)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8); - c.rgbGreen = (BYTE)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8); - - if (head.biClrUsed) - BlindSetPixelIndex(x,y,GetNearestIndex(c)); - else { - BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3; - *iDst++ = c.rgbBlue; - *iDst++ = c.rgbGreen; - *iDst = c.rgbRed; -#if CXIMAGE_SUPPORT_ALPHA - if (bSetAlpha) AlphaSet(x,y,c.rgbReserved); -#endif //CXIMAGE_SUPPORT_ALPHA - } -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Returns the best palette index that matches a specified color. - */ -BYTE CxImage::GetNearestIndex(RGBQUAD c) -{ - if ((pDib==NULL)||(head.biClrUsed==0)) return 0; - - // check matching with the previous result - if (info.last_c_isvalid && (*(long*)&info.last_c == *(long*)&c)) return info.last_c_index; - info.last_c = c; - info.last_c_isvalid = true; - - BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER); - long distance=200000; - int i,j = 0; - long k,l; - int m = (int)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant); - for(i=0,l=0;i100) perc=100; - for(i=0;i=0){ - if (head.biClrUsed){ - if (GetPixelIndex(x,y) == info.nBkgndIndex) return true; - } else { - RGBQUAD ct = info.nBkgndColor; - RGBQUAD c = GetPixelColor(x,y,false); - if (*(long*)&c==*(long*)&ct) return true; - } - } - -#if CXIMAGE_SUPPORT_ALPHA - if (pAlpha) return AlphaGet(x,y)==0; -#endif - - return false; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::GetTransparentMask(CxImage* iDst) -{ - if (!pDib) return false; - - CxImage tmp; - tmp.Create(head.biWidth, head.biHeight, 1, GetType()); - tmp.SetStdPalette(); - tmp.Clear(0); - - for(long y=0; yTransfer(tmp); - else Transfer(tmp); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if image has the same palette, if any. - * \param img = image to compare. - * \param bCheckAlpha = check also the rgbReserved field. - */ -bool CxImage::IsSamePalette(CxImage &img, bool bCheckAlpha) -{ - if (head.biClrUsed != img.head.biClrUsed) - return false; - if (head.biClrUsed == 0) - return false; - - RGBQUAD c1,c2; - for (DWORD n=0; n256) { - head.biClrImportant = 0; - return; - } - - switch(head.biBitCount){ - case 1: - head.biClrImportant = MIN(ncolors,2); - break; - case 4: - head.biClrImportant = MIN(ncolors,16); - break; - case 8: - head.biClrImportant = ncolors; - break; - } - return; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Returns pointer to pixel. Currently implemented only for truecolor images. - * - * \param x,y - coordinates - * - * \return pointer to first byte of pixel data - * - * \author ***bd*** 2.2004 - */ -void* CxImage::BlindGetPixelPointer(const long x, const long y) -{ -#ifdef _DEBUG - if ((pDib==NULL) || !IsInside(x,y)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return 0; - #endif -#endif - if (!IsIndexed()) - return info.pImage + y*info.dwEffWidth + x*3; - else - return 0; -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr) -{ - DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr)); -} -//////////////////////////////////////////////////////////////////////////////// -void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha) -{ - if (!pDib) return; - ////////////////////////////////////////////////////// - // Draws a line using the Bresenham line algorithm - // Thanks to Jordan DeLozier - ////////////////////////////////////////////////////// - int x1 = StartX; - int y1 = StartY; - int x = x1; // Start x off at the first pixel - int y = y1; // Start y off at the first pixel - int x2 = EndX; - int y2 = EndY; - - int xinc1,xinc2,yinc1,yinc2; // Increasing values - int den, num, numadd,numpixels; - int deltax = abs(x2 - x1); // The difference between the x's - int deltay = abs(y2 - y1); // The difference between the y's - - // Get Increasing Values - if (x2 >= x1) { // The x-values are increasing - xinc1 = 1; - xinc2 = 1; - } else { // The x-values are decreasing - xinc1 = -1; - xinc2 = -1; - } - - if (y2 >= y1) { // The y-values are increasing - yinc1 = 1; - yinc2 = 1; - } else { // The y-values are decreasing - yinc1 = -1; - yinc2 = -1; - } - - // Actually draw the line - if (deltax >= deltay) // There is at least one x-value for every y-value - { - xinc1 = 0; // Don't change the x when numerator >= denominator - yinc2 = 0; // Don't change the y for every iteration - den = deltax; - num = deltax / 2; - numadd = deltay; - numpixels = deltax; // There are more x-values than y-values - } - else // There is at least one y-value for every x-value - { - xinc2 = 0; // Don't change the x for every iteration - yinc1 = 0; // Don't change the y when numerator >= denominator - den = deltay; - num = deltay / 2; - numadd = deltax; - numpixels = deltay; // There are more y-values than x-values - } - - for (int curpixel = 0; curpixel <= numpixels; curpixel++) - { - // Draw the current pixel - SetPixelColor(x,y,color,bSetAlpha); - - num += numadd; // Increase the numerator by the top of the fraction - if (num >= den) // Check if numerator >= denominator - { - num -= den; // Calculate the new numerator value - x += xinc1; // Change the x as appropriate - y += yinc1; // Change the y as appropriate - } - x += xinc2; // Change the x as appropriate - y += yinc2; // Change the y as appropriate - } -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Sets a palette with standard colors for 1, 4 and 8 bpp images. - */ -void CxImage::SetStdPalette() -{ - if (!pDib) return; - switch (head.biBitCount){ - case 8: - { - const BYTE pal256[1024] = {0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0, - 192,220,192,0,240,202,166,0,212,240,255,0,177,226,255,0,142,212,255,0,107,198,255,0, - 72,184,255,0,37,170,255,0,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0, - 50,80,0,212,227,255,0,177,199,255,0,142,171,255,0,107,143,255,0,72,115,255,0,37,87,255,0,0, - 85,255,0,0,73,220,0,0,61,185,0,0,49,150,0,0,37,115,0,0,25,80,0,212,212,255,0,177,177,255,0, - 142,142,255,0,107,107,255,0,72,72,255,0,37,37,255,0,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0, - 0,0,115,0,0,0,80,0,227,212,255,0,199,177,255,0,171,142,255,0,143,107,255,0,115,72,255,0, - 87,37,255,0,85,0,255,0,73,0,220,0,61,0,185,0,49,0,150,0,37,0,115,0,25,0,80,0,240,212,255,0, - 226,177,255,0,212,142,255,0,198,107,255,0,184,72,255,0,170,37,255,0,170,0,255,0,146,0,220,0, - 122,0,185,0,98,0,150,0,74,0,115,0,50,0,80,0,255,212,255,0,255,177,255,0,255,142,255,0,255,107,255,0, - 255,72,255,0,255,37,255,0,254,0,254,0,220,0,220,0,185,0,185,0,150,0,150,0,115,0,115,0,80,0,80,0, - 255,212,240,0,255,177,226,0,255,142,212,0,255,107,198,0,255,72,184,0,255,37,170,0,255,0,170,0, - 220,0,146,0,185,0,122,0,150,0,98,0,115,0,74,0,80,0,50,0,255,212,227,0,255,177,199,0,255,142,171,0, - 255,107,143,0,255,72,115,0,255,37,87,0,255,0,85,0,220,0,73,0,185,0,61,0,150,0,49,0,115,0,37,0, - 80,0,25,0,255,212,212,0,255,177,177,0,255,142,142,0,255,107,107,0,255,72,72,0,255,37,37,0,254,0, - 0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,0,255,227,212,0,255,199,177,0,255,171,142,0, - 255,143,107,0,255,115,72,0,255,87,37,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,115,37,0, - 0,80,25,0,0,255,240,212,0,255,226,177,0,255,212,142,0,255,198,107,0,255,184,72,0,255,170,37,0, - 255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,0,255,255,212,0,255,255,177,0, - 255,255,142,0,255,255,107,0,255,255,72,0,255,255,37,0,254,254,0,0,220,220,0,0,185,185,0,0,150,150,0, - 0,115,115,0,0,80,80,0,0,240,255,212,0,226,255,177,0,212,255,142,0,198,255,107,0,184,255,72,0, - 170,255,37,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,50,80,0,0,227,255,212,0, - 199,255,177,0,171,255,142,0,143,255,107,0,115,255,72,0,87,255,37,0,85,255,0,0,73,220,0,0,61,185,0, - 0,49,150,0,0,37,115,0,0,25,80,0,0,212,255,212,0,177,255,177,0,142,255,142,0,107,255,107,0,72,255,72,0, - 37,255,37,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,212,255,227,0,177,255,199,0, - 142,255,171,0,107,255,143,0,72,255,115,0,37,255,87,0,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0, - 115,37,0,0,80,25,0,212,255,240,0,177,255,226,0,142,255,212,0,107,255,198,0,72,255,184,0,37,255,170,0, - 0,255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,212,255,255,0,177,255,255,0, - 142,255,255,0,107,255,255,0,72,255,255,0,37,255,255,0,0,254,254,0,0,220,220,0,0,185,185,0,0, - 150,150,0,0,115,115,0,0,80,80,0,242,242,242,0,230,230,230,0,218,218,218,0,206,206,206,0,194,194,194,0, - 182,182,182,0,170,170,170,0,158,158,158,0,146,146,146,0,134,134,134,0,122,122,122,0,110,110,110,0, - 98,98,98,0,86,86,86,0,74,74,74,0,62,62,62,0,50,50,50,0,38,38,38,0,26,26,26,0,14,14,14,0,240,251,255,0, - 164,160,160,0,128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0}; - memcpy(GetPalette(),pal256,1024); - break; - } - case 4: - { - const BYTE pal16[64]={0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0, - 128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0}; - memcpy(GetPalette(),pal16,64); - break; - } - case 1: - { - const BYTE pal2[8]={0,0,0,0,255,255,255,0}; - memcpy(GetPalette(),pal2,8); - break; - } - } - info.last_c_isvalid = false; - return; -} -//////////////////////////////////////////////////////////////////////////////// diff --git a/Externals/cximage/ximasel.cpp b/Externals/cximage/ximasel.cpp deleted file mode 100644 index 8831eba081a..00000000000 --- a/Externals/cximage/ximasel.cpp +++ /dev/null @@ -1,697 +0,0 @@ -// xImaSel.cpp : Selection functions -/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -#if CXIMAGE_SUPPORT_SELECTION - -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the image has a valid selection. - */ -bool CxImage::SelectionIsValid() -{ - return pSelection!=0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Gets the smallest rectangle that contains the selection - */ -void CxImage::SelectionGetBox(RECT& r) -{ - memcpy(&r,&info.rSelectionBox,sizeof(RECT)); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Empties the selection. - */ -bool CxImage::SelectionClear(BYTE level) -{ - if (pSelection){ - if (level==0){ - memset(pSelection,0,head.biWidth * head.biHeight); - info.rSelectionBox.left = head.biWidth; - info.rSelectionBox.bottom = head.biHeight; - info.rSelectionBox.right = info.rSelectionBox.top = 0; - } else { - memset(pSelection,level,head.biWidth * head.biHeight); - info.rSelectionBox.right = head.biWidth; - info.rSelectionBox.top = head.biHeight; - info.rSelectionBox.left = info.rSelectionBox.bottom = 0; - } - return true; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Allocates an empty selection. - */ -bool CxImage::SelectionCreate() -{ - SelectionDelete(); - pSelection = (BYTE*)calloc(head.biWidth * head.biHeight, 1); - return (pSelection!=0); -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Deallocates the selction. - */ -bool CxImage::SelectionDelete() -{ - if (pSelection){ - cxfree(pSelection);//free(pSelection); - pSelection=NULL; - } - info.rSelectionBox.left = head.biWidth; - info.rSelectionBox.bottom = head.biHeight; - info.rSelectionBox.right = info.rSelectionBox.top = 0; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the coordinates are inside the selection. - */ -bool CxImage::SelectionIsInside(long x, long y) -{ - if (IsInside(x,y)){ - if (pSelection==NULL) return true; - return pSelection[x+y*head.biWidth]!=0; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Checks if the coordinates are inside the selection. - * "blind" version assumes that (x,y) is inside to the image. - */ -bool CxImage::BlindSelectionIsInside(long x, long y) -{ -#ifdef _DEBUG - if (!IsInside(x,y)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return 0; - #endif -#endif - if (pSelection==NULL) return true; - return pSelection[x+y*head.biWidth]!=0; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Adds a rectangle to the existing selection. - */ -bool CxImage::SelectionAddRect(RECT r, BYTE level) -{ - if (pSelection==NULL) SelectionCreate(); - if (pSelection==NULL) return false; - - RECT r2; - if (r.left r2.left) info.rSelectionBox.left = MAX(0L,MIN(head.biWidth,r2.left)); - if (info.rSelectionBox.right <= r2.right) info.rSelectionBox.right = MAX(0L,MIN(head.biWidth,r2.right+1)); - if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = MAX(0L,MIN(head.biHeight,r2.bottom)); - - long ymin = MAX(0L,MIN(head.biHeight,r2.bottom)); - long ymax = MAX(0L,MIN(head.biHeight,r2.top+1)); - long xmin = MAX(0L,MIN(head.biWidth,r2.left)); - long xmax = MAX(0L,MIN(head.biWidth,r2.right+1)); - - for (long y=ymin; y (xcenter - xradius)) info.rSelectionBox.left = MAX(0L,MIN(head.biWidth,(xcenter - xradius))); - if (info.rSelectionBox.right <= (xcenter + xradius)) info.rSelectionBox.right = MAX(0L,MIN(head.biWidth,(xcenter + xradius + 1))); - if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = MAX(0L,MIN(head.biHeight,(ycenter - yradius))); - if (info.rSelectionBox.top <= (ycenter + yradius)) info.rSelectionBox.top = MAX(0L,MIN(head.biHeight,(ycenter + yradius + 1))); - - long xmin = MAX(0L,MIN(head.biWidth,xcenter - xradius)); - long xmax = MAX(0L,MIN(head.biWidth,xcenter + xradius + 1)); - long ymin = MAX(0L,MIN(head.biHeight,ycenter - yradius)); - long ymax = MAX(0L,MIN(head.biHeight,ycenter + yradius + 1)); - - long y,yo; - for (y=ymin; yy) pSelection[x + y * head.biWidth] = level; - } - } - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Inverts the selection. - * Note: the SelectionBox is set to "full image", call SelectionGetBox before (if necessary) - */ -bool CxImage::SelectionInvert() -{ - if (pSelection) { - BYTE *iSrc=pSelection; - long n=head.biHeight*head.biWidth; - for(long i=0; i < n; i++){ - *iSrc=(BYTE)~(*(iSrc)); - iSrc++; - } - - SelectionRebuildBox(); - - return true; - } - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Imports an existing region from another image with the same width and height. - */ -bool CxImage::SelectionCopy(CxImage &from) -{ - if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false; - if (pSelection==NULL) pSelection = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - if (pSelection==NULL) return false; - memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight); - memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT)); - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Adds a polygonal region to the existing selection. points points to an array of POINT structures. - * Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon. - * npoints specifies the number of POINT structures in the array pointed to by points. - */ -bool CxImage::SelectionAddPolygon(POINT *points, long npoints, BYTE level) -{ - if (points==NULL || npoints<3) return false; - - if (pSelection==NULL) SelectionCreate(); - if (pSelection==NULL) return false; - - BYTE* plocal = (BYTE*)calloc(head.biWidth*head.biHeight, 1); - RECT localbox = {head.biWidth,0,0,head.biHeight}; - - long x,y,i=0; - POINT *current; - POINT *next = NULL; - POINT *start = NULL; - //trace contour - while (i < npoints){ - current = &points[i]; - if (current->x!=-1){ - if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i]; - - if ((i+1)==npoints || points[i+1].x==-1) - next = start; - else - next = &points[i+1]; - - float beta; - if (current->x != next->x){ - beta = (float)(next->y - current->y)/(float)(next->x - current->x); - if (current->x < next->x){ - for (x=current->x; x<=next->x; x++){ - y = (long)(current->y + (x - current->x) * beta); - if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; - } - } else { - for (x=current->x; x>=next->x; x--){ - y = (long)(current->y + (x - current->x) * beta); - if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; - } - } - } - if (current->y != next->y){ - beta = (float)(next->x - current->x)/(float)(next->y - current->y); - if (current->y < next->y){ - for (y=current->y; y<=next->y; y++){ - x = (long)(current->x + (y - current->y) * beta); - if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; - } - } else { - for (y=current->y; y>=next->y; y--){ - x = (long)(current->x + (y - current->y) * beta); - if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; - } - } - } - } - - RECT r2; - if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; } - if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; } - if (localbox.top < r2.top) localbox.top = MAX(0L,MIN(head.biHeight-1,r2.top+1)); - if (localbox.left > r2.left) localbox.left = MAX(0L,MIN(head.biWidth-1,r2.left-1)); - if (localbox.right < r2.right) localbox.right = MAX(0L,MIN(head.biWidth-1,r2.right+1)); - if (localbox.bottom > r2.bottom) localbox.bottom = MAX(0L,MIN(head.biHeight-1,r2.bottom-1)); - - i++; - } - - //fill the outer region - long npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom); - POINT* pix = (POINT*)calloc(npix,sizeof(POINT)); - BYTE back=0, mark=1; - long fx, fy, fxx, fyy, first, last; - long xmin = 0; - long xmax = 0; - long ymin = 0; - long ymax = 0; - - for (int side=0; side<4; side++){ - switch(side){ - case 0: - xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.bottom+1; - break; - case 1: - xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top+1; - break; - case 2: - xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.top; ymax=localbox.top+1; - break; - case 3: - xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top+1; - break; - } - //fill from the border points - for(y=ymin;y=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top ) - { - plocal[fxx + fyy*head.biWidth] = mark; - if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){ - pix[last].x = fx; - pix[last].y = fy - 1; - last++; - if (last == npix) last = 0; - } - if ((fyy + 1)=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top ) - { - plocal[fxx + (y + fy)*head.biWidth] = mark; - if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){ - pix[last].x = fx; - pix[last].y = fy - 1; - last++; - if (last == npix) last = 0; - } - if ((fyy + 1) localbox.left) info.rSelectionBox.left = MIN(head.biWidth,localbox.left); - if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = MIN(head.biWidth,localbox.right + 1); - if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = MIN(head.biHeight,localbox.bottom); - - cxfree(plocal);//free(plocal); - cxfree(pix);//free(pix); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Adds to the selection all the pixels matching the specified color. - */ -bool CxImage::SelectionAddColor(RGBQUAD c, BYTE level) -{ - if (pSelection==NULL) SelectionCreate(); - if (pSelection==NULL) return false; - - RECT localbox = {head.biWidth,0,0,head.biHeight}; - - for (long y = 0; y < head.biHeight; y++){ - for (long x = 0; x < head.biWidth; x++){ - RGBQUAD color = BlindGetPixelColor(x, y); - if (color.rgbRed == c.rgbRed && - color.rgbGreen == c.rgbGreen && - color.rgbBlue == c.rgbBlue) - { - pSelection[x + y * head.biWidth] = level; - - if (localbox.top < y) localbox.top = y; - if (localbox.left > x) localbox.left = x; - if (localbox.right < x) localbox.right = x; - if (localbox.bottom > y) localbox.bottom = y; - } - } - } - - if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1; - if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left; - if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1; - if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom; - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Adds a single pixel to the existing selection. - */ -bool CxImage::SelectionAddPixel(long x, long y, BYTE level) -{ - if (pSelection==NULL) SelectionCreate(); - if (pSelection==NULL) return false; - - if (IsInside(x,y)) { - pSelection[x + y * head.biWidth] = level; // set the correct mask bit - - if (info.rSelectionBox.top <= y) info.rSelectionBox.top = y+1; - if (info.rSelectionBox.left > x) info.rSelectionBox.left = x; - if (info.rSelectionBox.right <= x) info.rSelectionBox.right = x+1; - if (info.rSelectionBox.bottom > y) info.rSelectionBox.bottom = y; - - return true; - } - - return false; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Exports the selection channel in a 8bpp grayscale image. - */ -bool CxImage::SelectionSplit(CxImage *dest) -{ - if (!pSelection || !dest) return false; - - CxImage tmp(head.biWidth,head.biHeight,8); - if (!tmp.IsValid()){ - strcpy(info.szLastError,tmp.GetLastError()); - return false; - } - - for(long y=0; yTransfer(tmp); - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Creates the selection channel from a gray scale image. - * black = unselected - */ -bool CxImage::SelectionSet(CxImage &from) -{ - if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight){ - strcpy(info.szLastError,"CxImage::SelectionSet: wrong width or height, or image is not gray scale"); - return false; - } - - if (pSelection==NULL) pSelection = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - - BYTE* src = from.info.pImage; - BYTE* dst = pSelection; - if (src==NULL || dst==NULL){ - strcpy(info.szLastError,"CxImage::SelectionSet: null pointer"); - return false; - } - - for (long y=0; y=info.rSelectionBox.right; x--){ - if (pSelection[x+y*head.biWidth]){ - info.rSelectionBox.right = x+1; - continue; - } - } - } - - for (x=0; x=info.rSelectionBox.top; y--){ - if (pSelection[x+y*head.biWidth]){ - info.rSelectionBox.top = y+1; - continue; - } - } - } - -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Gets the Selection level for a single pixel - * "blind" version assumes that (x,y) is inside to the image. - */ -BYTE CxImage::BlindSelectionGet(const long x,const long y) -{ -#ifdef _DEBUG - if (!IsInside(x,y) || (pSelection==0)) - #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING - throw 0; - #else - return 0; - #endif -#endif - return pSelection[x+y*head.biWidth]; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * Returns pointer to selection data for pixel (x,y). - */ -BYTE* CxImage::SelectionGetPointer(const long x,const long y) -{ - if (pSelection && IsInside(x,y)) return pSelection+x+y*head.biWidth; - return 0; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::SelectionFlip() -{ - if (!pSelection) return false; - - BYTE *buff = (BYTE*)cxalloc(head.biWidth);//malloc(head.biWidth); - if (!buff) return false; - - BYTE *iSrc,*iDst; - iSrc = pSelection + (head.biHeight-1)*head.biWidth; - iDst = pSelection; - for (long i=0; i<(head.biHeight/2); ++i) - { - memcpy(buff, iSrc, head.biWidth); - memcpy(iSrc, iDst, head.biWidth); - memcpy(iDst, buff, head.biWidth); - iSrc-=head.biWidth; - iDst+=head.biWidth; - } - - cxfree(buff);//free(buff); - - long top = info.rSelectionBox.top; - info.rSelectionBox.top = head.biHeight - info.rSelectionBox.bottom; - info.rSelectionBox.bottom = head.biHeight - top; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImage::SelectionMirror() -{ - if (!pSelection) return false; - BYTE* pSelection2 = (BYTE*)cxalloc(head.biWidth * head.biHeight);//malloc(head.biWidth * head.biHeight); - if (!pSelection2) return false; - - BYTE *iSrc,*iDst; - long wdt=head.biWidth-1; - iSrc=pSelection + wdt; - iDst=pSelection2; - for(long y=0; y < head.biHeight; y++){ - for(long x=0; x <= wdt; x++) - *(iDst+x)=*(iSrc-x); - iSrc+=head.biWidth; - iDst+=head.biWidth; - } - cxfree(pSelection);//free(pSelection); - pSelection=pSelection2; - - long left = info.rSelectionBox.left; - info.rSelectionBox.left = head.biWidth - info.rSelectionBox.right; - info.rSelectionBox.right = head.biWidth - left; - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_WINDOWS -/** - * Converts the selection in a HRGN object. - */ -bool CxImage::SelectionToHRGN(HRGN& region) -{ - if (pSelection && region){ - for(int y = 0; y < head.biHeight; y++){ - HRGN hTemp = NULL; - int iStart = -1; - int x = 0; - for(; x < head.biWidth; x++){ - if (pSelection[x + y * head.biWidth] != 0){ - if (iStart == -1) iStart = x; - continue; - }else{ - if (iStart >= 0){ - hTemp = CreateRectRgn(iStart, y, x, y + 1); - CombineRgn(region, hTemp, region, RGN_OR); - DeleteObject(hTemp); - iStart = -1; - } - } - } - if (iStart >= 0){ - hTemp = CreateRectRgn(iStart, y, x, y + 1); - CombineRgn(region, hTemp, region, RGN_OR); - DeleteObject(hTemp); - iStart = -1; - } - } - return true; - } - return false; -} -#endif //CXIMAGE_SUPPORT_WINDOWS -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_SELECTION diff --git a/Externals/cximage/ximath.cpp b/Externals/cximage/ximath.cpp deleted file mode 100644 index 67070d8f8de..00000000000 --- a/Externals/cximage/ximath.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "ximage.h" -#include "ximath.h" -#include - -//this module should contain some classes for geometrical transformations -//usable with selections, etc... once it's done, that is. :) - -CxPoint2::CxPoint2() -{ - x=y=0.0f; -} - -CxPoint2::CxPoint2(float const x_, float const y_) -{ - x=x_; - y=y_; -} - -CxPoint2::CxPoint2(CxPoint2 const &p) -{ - x=p.x; - y=p.y; -} - -float CxPoint2::Distance(CxPoint2 const p2) -{ - return (float)sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y)); -} - -float CxPoint2::Distance(float const x_, float const y_) -{ - return (float)sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_)); -} - -CxRect2::CxRect2() -{ -} - -CxRect2::CxRect2(float const x1_, float const y1_, float const x2_, float const y2_) -{ - botLeft.x=x1_; - botLeft.y=y1_; - topRight.x=x2_; - topRight.y=y2_; -} - -CxRect2::CxRect2(CxRect2 const &p) : botLeft(p.botLeft), topRight(p.topRight) -{ -} - -float CxRect2::Surface() const -/* - * Returns the surface of rectangle. - */ -{ - return (topRight.x-botLeft.x)*(topRight.y-botLeft.y); -} - -CxRect2 CxRect2::CrossSection(CxRect2 const &r2) const -/* - * Returns crossection with another rectangle. - */ -{ - CxRect2 cs; - cs.botLeft.x=MAX(botLeft.x, r2.botLeft.x); - cs.botLeft.y=MAX(botLeft.y, r2.botLeft.y); - cs.topRight.x=MIN(topRight.x, r2.topRight.x); - cs.topRight.y=MIN(topRight.y, r2.topRight.y); - if (cs.botLeft.x<=cs.topRight.x && cs.botLeft.y<=cs.topRight.y) { - return cs; - } else { - return CxRect2(0,0,0,0); - }//if -} - -CxPoint2 CxRect2::Center() const -/* - * Returns the center point of rectangle. - */ -{ - return CxPoint2((topRight.x+botLeft.x)/2.0f, (topRight.y+botLeft.y)/2.0f); -} - -float CxRect2::Width() const -//returns rectangle width -{ - return topRight.x-botLeft.x; -} - -float CxRect2::Height() const -//returns rectangle height -{ - return topRight.y-botLeft.y; -} - diff --git a/Externals/cximage/ximath.h b/Externals/cximage/ximath.h deleted file mode 100644 index 10b98984e4f..00000000000 --- a/Externals/cximage/ximath.h +++ /dev/null @@ -1,39 +0,0 @@ -#if !defined(__ximath_h) -#define __ximath_h - -#include "ximadef.h" - -//***bd*** simple floating point point -class DLL_EXP CxPoint2 -{ -public: - CxPoint2(); - CxPoint2(float const x_, float const y_); - CxPoint2(CxPoint2 const &p); - - float Distance(CxPoint2 const p2); - float Distance(float const x_, float const y_); - - float x,y; -}; - -//and simple rectangle -class DLL_EXP CxRect2 -{ -public: - CxRect2(); - CxRect2(float const x1_, float const y1_, float const x2_, float const y2_); - CxRect2(CxPoint2 const &bl, CxPoint2 const &tr); - CxRect2(CxRect2 const &p); - - float Surface() const; - CxRect2 CrossSection(CxRect2 const &r2) const; - CxPoint2 Center() const; - float Width() const; - float Height() const; - - CxPoint2 botLeft; - CxPoint2 topRight; -}; - -#endif diff --git a/Externals/cximage/xiofile.cpp b/Externals/cximage/xiofile.cpp deleted file mode 100644 index 78bfc820a2b..00000000000 --- a/Externals/cximage/xiofile.cpp +++ /dev/null @@ -1,24 +0,0 @@ - -#include "xiofile.h" - -#if defined(WIN32) || defined(_WIN32_WCE) -#include -#else -#define _tfopen fopen -#endif - -bool CxIOFile::Open(LPCTSTR filename, LPCTSTR mode) -{ - if (m_fp) return false; // Can't re-open without closing first - - m_fp = _tfopen(filename, mode); - if (!m_fp) return false; - - m_bCloseFile = true; - - return true; -} - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#undef _tfopen -#endif diff --git a/Externals/cximage/xiofile.h b/Externals/cximage/xiofile.h deleted file mode 100644 index 890d05204ce..00000000000 --- a/Externals/cximage/xiofile.h +++ /dev/null @@ -1,115 +0,0 @@ -#if !defined(__xiofile_h) -#define __xiofile_h - -#include "xfile.h" - - -class DLL_EXP CxIOFile : public CxFile - { -public: - CxIOFile(FILE* fp = NULL) - { - m_fp = fp; - m_bCloseFile = (bool)(fp==0); - } - - ~CxIOFile() - { - Close(); - } -////////////////////////////////////////////////////////// - bool Open(LPCTSTR filename, LPCTSTR mode); -////////////////////////////////////////////////////////// - virtual bool Close() - { - int iErr = 0; - if ( (m_fp) && (m_bCloseFile) ){ - iErr = fclose(m_fp); - m_fp = NULL; - } - return (bool)(iErr==0); - } -////////////////////////////////////////////////////////// - virtual size_t Read(void *buffer, size_t size, size_t count) - { - if (!m_fp) return 0; - return fread(buffer, size, count, m_fp); - } -////////////////////////////////////////////////////////// - virtual size_t Write(const void *buffer, size_t size, size_t count) - { - if (!m_fp) return 0; - return fwrite(buffer, size, count, m_fp); - } -////////////////////////////////////////////////////////// - virtual bool Seek(long offset, int origin) - { - if (!m_fp) return false; - return (bool)(fseek(m_fp, offset, origin) == 0); - } -////////////////////////////////////////////////////////// - virtual long Tell() - { - if (!m_fp) return 0; - return ftell(m_fp); - } -////////////////////////////////////////////////////////// - virtual long Size() - { - if (!m_fp) return -1; - long pos,size; - pos = ftell(m_fp); - fseek(m_fp, 0, SEEK_END); - size = ftell(m_fp); - fseek(m_fp, pos,SEEK_SET); - return size; - } -////////////////////////////////////////////////////////// - virtual bool Flush() - { - if (!m_fp) return false; - return (bool)(fflush(m_fp) == 0); - } -////////////////////////////////////////////////////////// - virtual bool Eof() - { - if (!m_fp) return true; - return (bool)(feof(m_fp) != 0); - } -////////////////////////////////////////////////////////// - virtual long Error() - { - if (!m_fp) return -1; - return ferror(m_fp); - } -////////////////////////////////////////////////////////// - virtual bool PutC(unsigned char c) - { - if (!m_fp) return false; - return (bool)(fputc(c, m_fp) == c); - } -////////////////////////////////////////////////////////// - virtual long GetC() - { - if (!m_fp) return EOF; - return getc(m_fp); - } -////////////////////////////////////////////////////////// - virtual char * GetS(char *string, int n) - { - if (!m_fp) return NULL; - return fgets(string,n,m_fp); - } -////////////////////////////////////////////////////////// - virtual long Scanf(const char *format, void* output) - { - if (!m_fp) return EOF; - return fscanf(m_fp, format, output); - } -////////////////////////////////////////////////////////// -protected: - FILE *m_fp; - bool m_bCloseFile; - }; - -#endif diff --git a/Externals/cximage/xmemfile.cpp b/Externals/cximage/xmemfile.cpp deleted file mode 100644 index e50b08e0dd7..00000000000 --- a/Externals/cximage/xmemfile.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "xmemfile.h" - -////////////////////////////////////////////////////////// -CxMemFile::CxMemFile(BYTE* pBuffer, DWORD size) -{ - m_pBuffer = pBuffer; - m_Position = 0; - m_Size = m_Edge = size; - m_bFreeOnClose = (bool)(pBuffer==0); -} -////////////////////////////////////////////////////////// -CxMemFile::~CxMemFile() -{ - Close(); -} -////////////////////////////////////////////////////////// -bool CxMemFile::Close() -{ - if ( (m_pBuffer) && (m_bFreeOnClose) ){ - cxfree(m_pBuffer);//free(m_pBuffer); - m_pBuffer = NULL; - m_Size = 0; - } - return true; -} -////////////////////////////////////////////////////////// -bool CxMemFile::Open() -{ - if (m_pBuffer) return false; // Can't re-open without closing first - - m_Position = m_Size = m_Edge = 0; - m_pBuffer=(BYTE*)cxalloc(1);//malloc(1); - m_bFreeOnClose = true; - - return (m_pBuffer!=0); -} -////////////////////////////////////////////////////////// -BYTE* CxMemFile::GetBuffer(bool bDetachBuffer) -{ - //can only detach, avoid inadvertantly attaching to - // memory that may not be ours [Jason De Arte] - if( bDetachBuffer ) - m_bFreeOnClose = false; - return m_pBuffer; -} -////////////////////////////////////////////////////////// -size_t CxMemFile::Read(void *buffer, size_t size, size_t count) -{ - if (buffer==NULL) return 0; - - if (m_pBuffer==NULL) return 0; - if (m_Position >= (long)m_Size) return 0; - - long nCount = (long)(count*size); - if (nCount == 0) return 0; - - long nRead; - if (m_Position + nCount > (long)m_Size) - nRead = (m_Size - m_Position); - else - nRead = nCount; - - memcpy(buffer, m_pBuffer + m_Position, nRead); - m_Position += nRead; - - return (size_t)(nRead/size); -} -////////////////////////////////////////////////////////// -size_t CxMemFile::Write(const void *buffer, size_t size, size_t count) -{ - if (m_pBuffer==NULL) return 0; - if (buffer==NULL) return 0; - - long nCount = (long)(count*size); - if (nCount == 0) return 0; - - if (m_Position + nCount > m_Edge){ - if (!Alloc(m_Position + nCount)){ - return false; - } - } - - memcpy(m_pBuffer + m_Position, buffer, nCount); - - m_Position += nCount; - - if (m_Position > (long)m_Size) m_Size = m_Position; - - return count; -} -////////////////////////////////////////////////////////// -bool CxMemFile::Seek(long offset, int origin) -{ - if (m_pBuffer==NULL) return false; - long lNewPos = m_Position; - - if (origin == SEEK_SET) lNewPos = offset; - else if (origin == SEEK_CUR) lNewPos += offset; - else if (origin == SEEK_END) lNewPos = m_Size + offset; - else return false; - - if (lNewPos < 0) lNewPos = 0; - - m_Position = lNewPos; - return true; -} -////////////////////////////////////////////////////////// -long CxMemFile::Tell() -{ - if (m_pBuffer==NULL) return -1; - return m_Position; -} -////////////////////////////////////////////////////////// -long CxMemFile::Size() -{ - if (m_pBuffer==NULL) return -1; - return m_Size; -} -////////////////////////////////////////////////////////// -bool CxMemFile::Flush() -{ - if (m_pBuffer==NULL) return false; - return true; -} -////////////////////////////////////////////////////////// -bool CxMemFile::Eof() -{ - if (m_pBuffer==NULL) return true; - return (m_Position >= (long)m_Size); -} -////////////////////////////////////////////////////////// -long CxMemFile::Error() -{ - if (m_pBuffer==NULL) return -1; - return (m_Position > (long)m_Size); -} -////////////////////////////////////////////////////////// -bool CxMemFile::PutC(unsigned char c) -{ - if (m_pBuffer==NULL) return false; - - if (m_Position >= m_Edge){ - if (!Alloc(m_Position + 1)){ - return false; - } - } - - m_pBuffer[m_Position++] = c; - - if (m_Position > (long)m_Size) m_Size = m_Position; - - return true; -} -////////////////////////////////////////////////////////// -long CxMemFile::GetC() -{ - if (Eof()) return EOF; - return *(BYTE*)((BYTE*)m_pBuffer + m_Position++); -} -////////////////////////////////////////////////////////// -char * CxMemFile::GetS(char *string, int n) -{ - n--; - long c,i=0; - while (i (DWORD)m_Edge) - { - // find new buffer size - DWORD dwNewBufferSize = (DWORD)(((dwNewLen>>16)+1)<<16); - - // allocate new buffer - if (m_pBuffer == NULL) m_pBuffer = (BYTE*)cxalloc(dwNewBufferSize);//malloc(dwNewBufferSize); - else m_pBuffer = (BYTE*)cxrealloc(m_pBuffer, dwNewBufferSize);//realloc(m_pBuffer, dwNewBufferSize); - // I own this buffer now (caller knows nothing about it) - m_bFreeOnClose = true; - - m_Edge = dwNewBufferSize; - } - return (m_pBuffer!=0); -} -////////////////////////////////////////////////////////// -void CxMemFile::Free() -{ - Close(); -} -////////////////////////////////////////////////////////// diff --git a/Externals/cximage/xmemfile.h b/Externals/cximage/xmemfile.h deleted file mode 100644 index f87e4f9b110..00000000000 --- a/Externals/cximage/xmemfile.h +++ /dev/null @@ -1,41 +0,0 @@ -#if !defined(__xmemfile_h) -#define __xmemfile_h - -#include "xfile.h" - -////////////////////////////////////////////////////////// -class DLL_EXP CxMemFile : public CxFile -{ -public: - CxMemFile(BYTE* pBuffer = NULL, DWORD size = 0); - ~CxMemFile(); - - bool Open(); - BYTE* GetBuffer(bool bDetachBuffer = true); - - virtual bool Close(); - virtual size_t Read(void *buffer, size_t size, size_t count); - virtual size_t Write(const void *buffer, size_t size, size_t count); - virtual bool Seek(long offset, int origin); - virtual long Tell(); - virtual long Size(); - virtual bool Flush(); - virtual bool Eof(); - virtual long Error(); - virtual bool PutC(unsigned char c); - virtual long GetC(); - virtual char * GetS(char *string, int n); - virtual long Scanf(const char *format, void* output); - -protected: - bool Alloc(DWORD nBytes); - void Free(); - - BYTE* m_pBuffer; - DWORD m_Size; - bool m_bFreeOnClose; - long m_Position; //current position - long m_Edge; //buffer size -}; - -#endif diff --git a/misc/windows/xrbinup.cmd b/misc/windows/xrbinup.cmd index 72735a0ef5a..232d03db15e 100644 --- a/misc/windows/xrbinup.cmd +++ b/misc/windows/xrbinup.cmd @@ -86,10 +86,6 @@ if %platform%==Win32 ( if %platform%==Win64 ( call :COPY_FILE amd_ags_x64.dll ) -rem CxImage is compiled as DLLs only in debug configuration -if %cfg%==Debug ( - call :COPY_FILE CxImage.dll -) call :COPY_FILE LuaJIT.dll call :COPY_FILE luabind.dll call :COPY_FILE ODE.dll diff --git a/src/engine.sln b/src/engine.sln index 9507ebc6c10..f669f1db4f1 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -47,8 +47,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrRender_R4", "Layers\xrRen EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp_configs_verifyer", "utils\mp_configs_verifyer\mp_configs_verifyer.vcxproj", "{1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CxImage", "..\Externals\cximage\cximage.vcxproj", "{880CD250-BA77-4DAF-A8D4-552F12DD3AE4}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "editors", "editors", "{CB0C814D-FB4E-453B-B7A0-716F4A1EACA4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrWeatherEditor", "editors\xrWeatherEditor\xrWeatherEditor.vcxproj", "{492D3DFE-9068-4E7E-A008-7C2420A651C0}" @@ -676,38 +674,6 @@ Global {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Release|x64.Build.0 = Release|x64 {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Release|x86.ActiveCfg = Release|Win32 {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B}.Release|x86.Build.0 = Release|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|ARM.ActiveCfg = Debug|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|ARM.Build.0 = Debug|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|ARM64.ActiveCfg = Debug|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|ARM64.Build.0 = Debug|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|x64.ActiveCfg = Debug|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|x64.Build.0 = Debug|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|x86.ActiveCfg = Debug|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Debug|x86.Build.0 = Debug|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|ARM.ActiveCfg = Mixed|ARM - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|ARM.Build.0 = Mixed|ARM - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|x64.ActiveCfg = Mixed|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|x64.Build.0 = Mixed|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|x86.ActiveCfg = Mixed|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Mixed|x86.Build.0 = Mixed|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|ARM.ActiveCfg = Release|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|ARM.Build.0 = Release|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|ARM64.ActiveCfg = Release|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|ARM64.Build.0 = Release|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x64.ActiveCfg = Release|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x64.Build.0 = Release|x64 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x86.ActiveCfg = Release|Win32 - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4}.Release|x86.Build.0 = Release|Win32 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|ARM.ActiveCfg = Debug|Win32 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|ARM64.ActiveCfg = Debug|x64 {492D3DFE-9068-4E7E-A008-7C2420A651C0}.Debug|x64.ActiveCfg = Debug|x64 @@ -1518,7 +1484,6 @@ Global {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} - {880CD250-BA77-4DAF-A8D4-552F12DD3AE4} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {492D3DFE-9068-4E7E-A008-7C2420A651C0} = {CB0C814D-FB4E-453B-B7A0-716F4A1EACA4} {CCD4AFAE-AA10-42C6-A452-FDEE497CCDF1} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} {67FF193E-2C20-402A-9026-9F5F6327503C} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 6d7ca9b4ae0..02b4ec50002 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -2600,7 +2600,6 @@ target_include_directories(xrGame "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src" "${CMAKE_SOURCE_DIR}/src/xrServerEntities" - "$<$:${CMAKE_SOURCE_DIR}/Externals/cximage>" "${CMAKE_SOURCE_DIR}/Externals/GameSpy/src" "${CMAKE_SOURCE_DIR}/Externals/ode/include" "${CMAKE_SOURCE_DIR}/Externals/OpenAutomate/inc" @@ -2619,7 +2618,6 @@ target_link_libraries(xrGame xrUICore xrSound xrScriptEngine - $<$:cximage> xrGameSpy xrCDB xrPhysics diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index 7ed3020f2df..54ee5a81250 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -24,7 +24,7 @@ - $(SolutionDir)xrServerEntities;$(xrExternals)ode/include;$(xrExternals)GameSpy\src;$(xrExternals)OpenAutomate\inc;$(xrExternals)CxImage;%(AdditionalIncludeDirectories) + $(SolutionDir)xrServerEntities;$(xrExternals)ode/include;$(xrExternals)GameSpy\src;$(xrExternals)OpenAutomate\inc;%(AdditionalIncludeDirectories) _USRDLL;XRGAME_EXPORTS;%(PreprocessorDefinitions) 4237;4250;%(DisableSpecificWarnings) @@ -3487,9 +3487,6 @@ {435bac9a-b225-457d-ab40-c9bd0cc8838c} - - {880cd250-ba77-4daf-a8d4-552f12dd3ae4} - {5cb057d8-4464-40a6-af10-c26b826d1d90} From f97fedda4db7661128cf0fae2098391d499e5366 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 17:33:38 +0500 Subject: [PATCH 378/497] Add mechanism to finalize xrDebug facility --- src/xrCore/xrDebug.cpp | 80 +++++++++++++++++++++++------------------- src/xrCore/xrDebug.h | 3 +- src/xrEngine/x_ray.cpp | 2 ++ 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 8c7810a7c48..219fbca32f1 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -32,8 +32,6 @@ # define USE_BUG_TRAP # ifdef USE_BUG_TRAP # include -# else -# include # endif # include "Debug/dxerr.h" @@ -840,7 +838,7 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs) #ifndef USE_BUG_TRAP [[noreturn]] -void _terminate() +void xr_terminate() { #if defined(XR_PLATFORM_WINDOWS) if (strstr(GetCommandLine(), "-silent_error_mode")) @@ -890,50 +888,50 @@ static void invalid_parameter_handler(const wchar_t* expression, const wchar_t* } #endif -#if defined(XR_PLATFORM_WINDOWS) -static void pure_call_handler() { handler_base("pure virtual function call"); } -#endif - -#ifdef XRAY_USE_EXCEPTIONS -static void unexpected_handler() { handler_base("unexpected program termination"); } -#endif - -static void abort_handler(int signal) { handler_base("application is aborting"); } -static void floating_point_handler(int signal) { handler_base("floating point error"); } -static void illegal_instruction_handler(int signal) { handler_base("illegal instruction"); } -static void segmentation_fault_handler(int signal) { handler_base("segmentation fault"); } -static void termination_handler(int signal) { handler_base("termination with exit code 3"); } - void xrDebug::OnThreadSpawn() { + std::signal(SIGINT, nullptr); + std::signal(SIGILL, +[](int signal) { handler_base("illegal instruction"); }); + std::signal(SIGFPE, +[](int signal) { handler_base("floating point error"); }); + std::signal(SIGSEGV, +[](int signal) { handler_base("segmentation fault"); }); + std::signal(SIGABRT, +[](int signal) { handler_base("application is aborting"); }); + std::signal(SIGTERM, +[](int signal) { handler_base("termination with exit code 3"); }); + #if defined(XR_PLATFORM_WINDOWS) #ifdef USE_BUG_TRAP BT_SetTerminate(); -#else - // std::set_terminate(_terminate); #endif + std::signal(SIGABRT_COMPAT, +[](int signal) { handler_base("application is aborting"); }); _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - std::signal(SIGABRT, abort_handler); - std::signal(SIGABRT_COMPAT, abort_handler); - std::signal(SIGFPE, floating_point_handler); - std::signal(SIGILL, illegal_instruction_handler); - std::signal(SIGINT, 0); - std::signal(SIGTERM, termination_handler); _set_invalid_parameter_handler(&invalid_parameter_handler); _set_new_mode(1); _set_new_handler(&out_of_memory_handler); - _set_purecall_handler(&pure_call_handler); -#if 0 // should be if we use exceptions - std::set_unexpected(_terminate); + _set_purecall_handler(+[] { handler_base("pure virtual function call"); }); +#else + std::set_terminate(xr_terminate); #endif -#else //XR_PLATFORM_WINDOWS - std::signal(SIGABRT, abort_handler); - std::signal(SIGFPE, floating_point_handler); - std::signal(SIGILL, illegal_instruction_handler); - std::signal(SIGINT, 0); - std::signal(SIGTERM, termination_handler); - std::signal(SIGSEGV, segmentation_fault_handler); +} + +void xrDebug::OnThreadExit() +{ + std::signal(SIGINT, nullptr); + std::signal(SIGILL, nullptr); + std::signal(SIGFPE, nullptr); + std::signal(SIGSEGV, nullptr); + std::signal(SIGABRT, nullptr); + std::signal(SIGTERM, nullptr); + +#if defined(XR_PLATFORM_WINDOWS) + std::signal(SIGABRT_COMPAT, nullptr); + _set_abort_behavior(0, 0); + _set_invalid_parameter_handler(nullptr); + _set_new_mode(1); + _set_new_handler(nullptr); + _set_purecall_handler(nullptr); +#else + std::set_terminate(nullptr); #endif + } void xrDebug::Initialize(pcstr commandLine) @@ -945,7 +943,7 @@ void xrDebug::Initialize(pcstr commandLine) SDL_SetAssertionHandler(SDLAssertionHandler, nullptr); // exception handler to all "unhandled" exceptions #if defined(XR_PLATFORM_WINDOWS) - PrevFilter = ::SetUnhandledExceptionFilter(UnhandledFilter); + PrevFilter = SetUnhandledExceptionFilter(UnhandledFilter); #endif #ifdef DEBUG ShowErrorMessage = true; @@ -953,3 +951,13 @@ void xrDebug::Initialize(pcstr commandLine) ShowErrorMessage = commandLine ? !!strstr(commandLine, "-show_error_window") : false; #endif } + +void xrDebug::Finalize() +{ + OnThreadExit(); + SDL_SetAssertionHandler(nullptr, nullptr); +#if defined(XR_PLATFORM_WINDOWS) + SetUnhandledExceptionFilter(nullptr); +#endif + ShowErrorMessage = false; +} diff --git a/src/xrCore/xrDebug.h b/src/xrCore/xrDebug.h index 0c7d0645c07..ceb6a6698b3 100644 --- a/src/xrCore/xrDebug.h +++ b/src/xrCore/xrDebug.h @@ -89,8 +89,9 @@ class XRCORE_API xrDebug public: xrDebug() = delete; static void Initialize(pcstr commandLine); - static void Destroy(); + static void Finalize(); static void OnThreadSpawn(); + static void OnThreadExit(); static void OnFilesystemInitialized(); static bool DebuggerIsPresent(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 95b5fb878b3..04fe1e1e06e 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -417,6 +417,8 @@ CApplication::~CApplication() ZoneScopedN("SDL_Quit"); SDL_Quit(); } + + xrDebug::Finalize(); FrameMarkEnd(APPLICATION_SHUTDOWN); } From e47e4fe057c4f3c7a56266c4666107c5b8edc4e1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 18:06:52 +0500 Subject: [PATCH 379/497] Removed FPU control functions They are only usable on x86 and with SSE disabled. We have SSE2 enabled even on x86. Cleaned up xrCore/_math.cpp --- src/Layers/xrRender/r__sector.cpp | 2 - .../gl_rendertarget_accum_direct.cpp | 6 - src/Layers/xrRenderPC_GL/r2_R_sun.cpp | 9 - .../r4_rendertarget_accum_direct.cpp | 6 - src/Layers/xrRender_R2/r3_R_rain.cpp | 2 - .../xrRender_R2/r3_rendertarget_draw_rain.cpp | 3 - src/Layers/xrRender_R2/render_phase_sun.cpp | 3 - .../xrRender_R2/render_phase_sun_old.cpp | 9 - src/xrCDB/xrCDB.cpp | 2 - src/xrCore/_math.cpp | 193 +----------------- src/xrCore/_math.h | 10 - src/xrEngine/device.cpp | 1 - src/xrEngine/x_ray.cpp | 2 - 13 files changed, 3 insertions(+), 245 deletions(-) diff --git a/src/Layers/xrRender/r__sector.cpp b/src/Layers/xrRender/r__sector.cpp index f268b01ea95..458c6f7d47a 100644 --- a/src/Layers/xrRender/r__sector.cpp +++ b/src/Layers/xrRender/r__sector.cpp @@ -110,7 +110,6 @@ void CPortal::setup(const level_portal_data_t& data, const xr_vector& Fvector N, T; N.set(0, 0, 0); - FPU::m64r(); u32 _cnt = 0; for (int i = 2; i < vcnt; i++) { @@ -125,7 +124,6 @@ void CPortal::setup(const level_portal_data_t& data, const xr_vector& R_ASSERT2(_cnt, "Invalid portal detected"); N.div(float(_cnt)); P.build(poly[0], N); - FPU::m24r(); /* if (_abs(1-P.n.magnitude())X.D[0].combine); m_shadow.mul(xf_project, Device.mInvView); @@ -899,7 +894,6 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) bias_t.translate(bias); m_shadow.mulB_44(bias_t); } - FPU::m24r(); } // Make jitter texture diff --git a/src/Layers/xrRenderPC_GL/r2_R_sun.cpp b/src/Layers/xrRenderPC_GL/r2_R_sun.cpp index fe3dee8fec4..ace9e11a8dc 100644 --- a/src/Layers/xrRenderPC_GL/r2_R_sun.cpp +++ b/src/Layers/xrRenderPC_GL/r2_R_sun.cpp @@ -349,7 +349,6 @@ void render_sun_old::render_sun() const Fvector3 cull_COP; glm::mat4 cull_xform; { - FPU::m64r(); // Lets begin from base frustum DumbConvexVolume hull; { @@ -407,7 +406,6 @@ void render_sun_old::render_sun() const // full-xform cull_xform = mdir_Project * mdir_View; - FPU::m24r(); } // Begin SMAP-render @@ -453,7 +451,6 @@ void render_sun_old::render_sun() const float m_fTSM_Delta = ps_r2_sun_tsm_projection; // Compute REAL sheared xform based on receivers/casters information - FPU::m64r(); if (_abs(m_fCosGamma) < 0.99f && ps_r2_ls_flags.test(R2FLAG_SUN_TSM)) { // get the near and the far plane (points) in eye space. @@ -663,13 +660,10 @@ void render_sun_old::render_sun() const { m_LightViewProj = cull_xform; } - FPU::m24r(); // perform "refit" or "focusing" on relevant if (ps_r2_ls_flags.test(R2FLAG_SUN_FOCUS)) { - FPU::m64r(); - // create clipper DumbClipper view_clipper; glm::mat4 xform = m_LightViewProj; @@ -754,7 +748,6 @@ void render_sun_old::render_sun() const -2.f * boxX / boxWidth, -2.f * boxY / boxHeight, 0.f, 1.f); m_LightViewProj *= trapezoidUnitCube; //XRMatrixMultiply( &trapezoid_space, &trapezoid_space, &trapezoidUnitCube ); - FPU::m24r(); } // Finalize & Cleanup @@ -826,7 +819,6 @@ void render_sun_old::render_sun_near() Fvector3 cull_COP; glm::mat4 cull_xform; { - FPU::m64r(); // Lets begin from base frustum #ifdef _DEBUG using t_volume = DumbConvexVolume; @@ -931,7 +923,6 @@ void render_sun_old::render_sun_near() sun->X.D[0].maxY = clampr(iCeil(scissor.vMax.y), 0, limit); // full-xform - FPU::m24r(); } // Begin SMAP-render diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp b/src/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp index 9ff12528599..4fee884b391 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget_accum_direct.cpp @@ -182,7 +182,6 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) }; // compute xforms - FPU::m64r(); // shadow xform Fmatrix m_shadow; @@ -200,7 +199,6 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) bias_t.translate(bias); m_shadow.mulB_44(bias_t); } - FPU::m24r(); } // clouds xform @@ -499,7 +497,6 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat }; // compute xforms - FPU::m64r(); // shadow xform Fmatrix m_shadow; @@ -517,7 +514,6 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat bias_t.translate(bias); m_shadow.mulB_44(bias_t); } - FPU::m24r(); } // clouds xform @@ -952,7 +948,6 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) // compute xforms Fmatrix m_shadow; { - FPU::m64r(); Fmatrix xf_project; xf_project.mul(m_TexelAdjust, fuckingsun->X.D[0].combine); m_shadow.mul(xf_project, Device.mInvView); @@ -966,7 +961,6 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) bias_t.translate(bias); m_shadow.mulB_44(bias_t); } - FPU::m24r(); } // Make jitter texture diff --git a/src/Layers/xrRender_R2/r3_R_rain.cpp b/src/Layers/xrRender_R2/r3_R_rain.cpp index 8caf2d932d3..fe32084abde 100644 --- a/src/Layers/xrRender_R2/r3_R_rain.cpp +++ b/src/Layers/xrRender_R2/r3_R_rain.cpp @@ -116,7 +116,6 @@ void render_rain::calculate() Fvector3 cull_COP; Fmatrix cull_xform; { - FPU::m64r(); // Lets begin from base frustum Fmatrix fullxform_inv = ex_full_inverse; #ifdef _DEBUG @@ -271,7 +270,6 @@ void render_rain::calculate() RainLight.X.D[0].maxY = limit; // full-xform - FPU::m24r(); } // Begin SMAP-render diff --git a/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp b/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp index 7033d88cfa3..0a2fd8dee05 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp @@ -76,7 +76,6 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) #endif // compute xforms - FPU::m64r(); // shadow xform Fmatrix m_shadow; @@ -84,8 +83,6 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) Fmatrix xf_project; xf_project.mul(m_TexelAdjust, RainSetup.X.D[0].combine); m_shadow.mul(xf_project, Device.mInvView); - - FPU::m24r(); } /* diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index cff5e998805..06ee60bae33 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -118,8 +118,6 @@ void render_sun::calculate() { cull_planes.clear(); - FPU::m64r(); - //******************************* Need to be placed after cuboid built ************************** // COP - 100 km away cull_COP[cascade_ind].mad(Device.vCameraPosition, sun->direction, -tweak_COP_initial_offs); @@ -268,7 +266,6 @@ void render_sun::calculate() sun->X.D[cascade_ind].combine = cull_xform[cascade_ind]; // full-xform - FPU::m24r(); } const auto process_cascade = [&, this](const TaskRange& range) diff --git a/src/Layers/xrRender_R2/render_phase_sun_old.cpp b/src/Layers/xrRender_R2/render_phase_sun_old.cpp index 0a2f72f2756..63732c8da77 100644 --- a/src/Layers/xrRender_R2/render_phase_sun_old.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun_old.cpp @@ -316,7 +316,6 @@ void render_sun_old::render_sun() const Fvector3 cull_COP; Fmatrix cull_xform; { - FPU::m64r(); // Lets begin from base frustum Fmatrix fullxform_inv; XMStoreFloat4x4((XMFLOAT4X4*)&fullxform_inv, ex_full_inverse); @@ -376,7 +375,6 @@ void render_sun_old::render_sun() const // full-xform cull_xform.mul(mdir_Project, mdir_View); - FPU::m24r(); } // Begin SMAP-render @@ -421,7 +419,6 @@ void render_sun_old::render_sun() const float m_fTSM_Delta = ps_r2_sun_tsm_projection; // Compute REAL sheared xform based on receivers/casters information - FPU::m64r(); if (_abs(m_fCosGamma) < 0.99f && ps_r2_ls_flags.test(R2FLAG_SUN_TSM)) { // get the near and the far plane (points) in eye space. @@ -597,13 +594,10 @@ void render_sun_old::render_sun() const { m_LightViewProj = XMLoadFloat4x4((XMFLOAT4X4*)(&cull_xform)); } - FPU::m24r(); // perform "refit" or "focusing" on relevant if (ps_r2_ls_flags.test(R2FLAG_SUN_FOCUS)) { - FPU::m64r(); - // create clipper DumbClipper view_clipper; Fmatrix xform; @@ -688,7 +682,6 @@ void render_sun_old::render_sun() const -2.f * boxX / boxWidth, -2.f * boxY / boxHeight, 0.f, 1.f); m_LightViewProj = XMMatrixMultiply(m_LightViewProj, trapezoidUnitCube); // D3DXMatrixMultiply( &trapezoid_space, &trapezoid_space, &trapezoidUnitCube ); - FPU::m24r(); } // Finalize & Cleanup @@ -757,7 +750,6 @@ void render_sun_old::render_sun_near() Fvector3 cull_COP; Fmatrix cull_xform; { - FPU::m64r(); // Lets begin from base frustum Fmatrix fullxform_inv; XMStoreFloat4x4((XMFLOAT4X4*)&fullxform_inv, ex_full_inverse); @@ -901,7 +893,6 @@ void render_sun_old::render_sun_near() sun->X.D[0].combine = cull_xform; // full-xform - FPU::m24r(); } // Begin SMAP-render diff --git a/src/xrCDB/xrCDB.cpp b/src/xrCDB/xrCDB.cpp index 65f5d4ea563..527f2de03d0 100644 --- a/src/xrCDB/xrCDB.cpp +++ b/src/xrCDB/xrCDB.cpp @@ -68,10 +68,8 @@ void MODEL::build(Fvector* V, int Vcnt, TRI* T, int Tcnt, build_callback* bc, vo Threading::SpawnThread("CDB-construction", [&, this] { ScopeLock lock{ pcs }; - FPU::m64r(); build_internal(V, Vcnt, T, Tcnt, bc, bcp); status = S_READY; - FPU::m24r(); // Msg("* xrCDB: cform build completed, memory usage: %d K", memory() / 1024); }); diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index c774c3684d8..b17e5761aee 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -1,36 +1,5 @@ #include "stdafx.h" -#if defined(XR_PLATFORM_WINDOWS) -# include // _controlfp -# if defined(_M_FP_PRECISE) -# pragma fenv_access(on) -# endif -#elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) -// XXX: check if these includes needed -#include -#include -#include -#include -#include - -// It's reasonable to use special functions only if we have precision control. - -# if __has_include() && defined(XR_ARCHITECTURE_X86) -// Check for _FPU_EXTENDED, _FPU_DOUBLE, _FPU_SINGLE macros availability here: -// https://elixir.bootlin.com/glibc/glibc-2.38.9000/A/ident/_FPU_SETCW -# include -# define USE_GLIBC_FPU_CONTROL - -# elif defined(XR_PLATFORM_FREEBSD) -// Check for fpsetprec availability -# include -# define USE_BSD_FP -# endif - -# include -# pragma STDC FENV_ACCESS on -#endif - #include #include @@ -39,154 +8,6 @@ XRCORE_API Fmatrix Fidentity; XRCORE_API Dmatrix Didentity; XRCORE_API CRandom Random; -/* -Функции управления точностью вычислений с плавающей точкой. -Более подробную информацию можно получить здесь: -https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/control87-controlfp-control87-2 -Число 24, 53 и 64 - определяют ограничение точности в битах. -Наличие 'r' - включает округление результатов. -Реально в движке используются только m24r и m64r. И один раз m64 - возможно ошибка? -*/ -namespace FPU -{ -XRCORE_API void m24() -{ -#if defined(XR_PLATFORM_WINDOWS) -# ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_24, MCW_PC); -# endif - _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RZ); - fpsetprec(FP_PS); -#else - std::fesetround(FE_TOWARDZERO); -#endif -} - -XRCORE_API void m24r() -{ -#if defined(XR_PLATFORM_WINDOWS) -# ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_24, MCW_PC); -# endif - _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE | _FPU_RC_NEAREST; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RN); - fpsetprec(FP_PS); -#else - std::fesetround(FE_TONEAREST); -#endif -} - -XRCORE_API void m53() -{ -#if defined(XR_PLATFORM_WINDOWS) -# ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_53, MCW_PC); -# endif - _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RZ); - fpsetprec(FP_PD); -#else - std::fesetround(FE_TOWARDZERO); -#endif -} - -XRCORE_API void m53r() -{ -#if defined(XR_PLATFORM_WINDOWS) -# ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_53, MCW_PC); -# endif - _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE | _FPU_RC_NEAREST; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RN); - fpsetprec(FP_PD); -#else - std::fesetround(FE_TONEAREST); -#endif -} - -XRCORE_API void m64() -{ -#if defined(XR_PLATFORM_WINDOWS) -# ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_64, MCW_PC); -# endif - _controlfp(_RC_CHOP, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_DOUBLE & ~_FPU_SINGLE) | _FPU_EXTENDED; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RZ); - fpsetprec(FP_PE); -#else - std::fesetround(FE_TOWARDZERO); -#endif -} - -XRCORE_API void m64r() -{ -#if defined(XR_PLATFORM_WINDOWS) -#ifdef XR_ARCHITECTURE_X86 - _controlfp(_PC_64, MCW_PC); -#endif - _controlfp(_RC_NEAR, MCW_RC); -#elif defined(USE_GLIBC_FPU_CONTROL) - fpu_control_t fpu_cw; - _FPU_GETCW(fpu_cw); - fpu_cw = (fpu_cw & ~_FPU_DOUBLE & ~_FPU_SINGLE) | _FPU_EXTENDED | _FPU_RC_NEAREST; - _FPU_SETCW(fpu_cw); -#elif defined(USE_BSD_FP) - fpsetround(FP_RN); - fpsetprec(FP_PE); -#else - std::fesetround(FE_TONEAREST); -#endif -} - -void initialize() -{ -#if defined(XR_PLATFORM_WINDOWS) - _clearfp(); -#else - std::ignore = std::feclearexcept(FE_ALL_EXCEPT); -#endif - - // По-умолчанию для плагинов экспорта из 3D-редакторов включена высокая точность вычислений с плавающей точкой - if (Core.PluginMode) - m64r(); - else - m24r(); - - ::Random.seed(u32(CPU::QPC() % (s64(1) << s32(32)))); -} -}; - namespace CPU { XRCORE_API bool HasSSE = SDL_HasSSE(); @@ -227,8 +48,6 @@ XRCORE_API u32 GetTicks() } } // namespace CPU -bool g_initialize_cpu_called = false; - //------------------------------------------------------------------------------------ void _initialize_cpu() { @@ -285,11 +104,11 @@ void _initialize_cpu() Log(""); Fidentity.identity(); // Identity matrix Didentity.identity(); // Identity matrix + Random.seed(u32(CPU::QPC() % (s64(1) << s32(32)))); + pvInitializeStatics(); // Lookup table for compressed normals - FPU::initialize(); - _initialize_cpu_thread(); - g_initialize_cpu_called = true; + _initialize_cpu_thread(); } // per-thread initialization @@ -307,12 +126,6 @@ void _initialize_cpu_thread() { xrDebug::OnThreadSpawn(); - // По-умолчанию для плагинов экспорта из 3D-редакторов включена высокая точность вычислений с плавающей точкой - if (Core.PluginMode) - FPU::m64r(); - else - FPU::m24r(); - if (SDL_HasSSE()) { //_mm_setcsr ( _mm_getcsr() | (_MM_FLUSH_ZERO_ON+_MM_DENORMALS_ZERO_ON) ); diff --git a/src/xrCore/_math.h b/src/xrCore/_math.h index 6aca8395bec..1f3141d19ce 100644 --- a/src/xrCore/_math.h +++ b/src/xrCore/_math.h @@ -2,16 +2,6 @@ #include "xr_types.h" -namespace FPU -{ -XRCORE_API void m24(); -XRCORE_API void m24r(); -XRCORE_API void m53(); -XRCORE_API void m53r(); -XRCORE_API void m64(); -XRCORE_API void m64r(); -} - namespace CPU { XRCORE_API extern bool HasSSE; diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index fc531ed80ef..f9dfad57805 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -53,7 +53,6 @@ bool CRenderDevice::RenderBegin() default: R_ASSERT(0); } GEnv.Render->Begin(); - FPU::m24r(); g_bRendering = true; return true; diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 04fe1e1e06e..4bb7c097589 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -313,8 +313,6 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) xr_strcpy(Core.CompName, sizeof(Core.CompName), "Computer"); } - FPU::m24r(); - Device.InitializeImGui(); Device.FillVideoModes(); TaskScheduler->Wait(inputTask); From f08be1a7ecfe2db65d7143c18ee601e84768e993 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 18:28:40 +0500 Subject: [PATCH 380/497] xrCore/_math.h|cpp: for SteamAudio, we need to check for SSE2 and SSE4.2 --- src/xrCore/_math.cpp | 11 +++++------ src/xrCore/_math.h | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index b17e5761aee..91130d58571 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -11,7 +11,8 @@ XRCORE_API CRandom Random; namespace CPU { XRCORE_API bool HasSSE = SDL_HasSSE(); -XRCORE_API bool HasSSE41 = SDL_HasSSE41(); +XRCORE_API bool HasSSE2 = SDL_HasSSE2(); +XRCORE_API bool HasSSE42 = SDL_HasSSE42(); #if SDL_VERSION_ATLEAST(2, 0, 6) XRCORE_API bool HasAVX = SDL_HasAVX(); @@ -75,10 +76,10 @@ void _initialize_cpu() listFeature("MMX", SDL_HasMMX()); listFeature("3DNow!", SDL_Has3DNow()); listFeature("SSE", SDL_HasSSE()); - listFeature("SSE2", SDL_HasSSE2()); + listFeature("SSE2", CPU::HasSSE2); listFeature("SSE3", SDL_HasSSE3()); listFeature("SSE41", SDL_HasSSE41()); - listFeature("SSE42", SDL_HasSSE42()); + listFeature("SSE42", CPU::HasSSE42); listFeature("AVX", CPU::HasAVX); listFeature("AVX2", CPU::HasAVX2); listFeature("AVX512F", CPU::HasAVX512F); @@ -99,8 +100,6 @@ void _initialize_cpu() Msg("* CPU features: %s", features); Msg("* CPU threads: %d", std::thread::hardware_concurrency()); - CPU::HasSSE = SDL_HasSSE(); // just in case, not sure if needed - Log(""); Fidentity.identity(); // Identity matrix Didentity.identity(); // Identity matrix @@ -126,7 +125,7 @@ void _initialize_cpu_thread() { xrDebug::OnThreadSpawn(); - if (SDL_HasSSE()) + if (CPU::HasSSE) { //_mm_setcsr ( _mm_getcsr() | (_MM_FLUSH_ZERO_ON+_MM_DENORMALS_ZERO_ON) ); _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); diff --git a/src/xrCore/_math.h b/src/xrCore/_math.h index 1f3141d19ce..b009dcd140f 100644 --- a/src/xrCore/_math.h +++ b/src/xrCore/_math.h @@ -5,7 +5,8 @@ namespace CPU { XRCORE_API extern bool HasSSE; -XRCORE_API extern bool HasSSE41; +XRCORE_API extern bool HasSSE2; +XRCORE_API extern bool HasSSE42; XRCORE_API extern bool HasAVX; XRCORE_API extern bool HasAVX2; XRCORE_API extern bool HasAVX512F; From 646047042a2d48b15fdaa6d1937730b1f09ba2e0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 18:41:10 +0500 Subject: [PATCH 381/497] xrCore/xrCore.cpp: move SSE check earlier Also, I've changed the check accordingly to a minimal SSE2 requirement we had since Sep 26, 2014 (b5fa8cdab0c9e46602eb6df6e4df8c0979bc2eec). --- src/xrCore/xrCore.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 6ae0f00e21a..11505088a72 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -179,6 +179,10 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, if (0 == init_counter) { +#if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) + R_ASSERT2(CPU::HasSSE2, "Your CPU must support SSE2."); +#endif + PluginMode = plugin; if (commandLine) Params = xr_strdup(commandLine); @@ -269,9 +273,6 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, SDL_LogSetOutputFunction(SDLLogOutput, nullptr); Msg("\ncommand line %s\n", Params); _initialize_cpu(); -#if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) - R_ASSERT(SDL_HasSSE()); -#endif TaskScheduler = xr_make_unique(); // xrDebug::Initialize (); From 0c5e010c4eac804e69c6f036ddcdb1c464626f76 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 19:04:58 +0500 Subject: [PATCH 382/497] xrCore/Threading/ThreadUtil.cpp: support SetThreadDescription on Windows Cleanup and simplification --- src/xrCore/Threading/ThreadUtil.cpp | 55 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/xrCore/Threading/ThreadUtil.cpp b/src/xrCore/Threading/ThreadUtil.cpp index 35cf6d3ef5a..fee18149e1c 100644 --- a/src/xrCore/Threading/ThreadUtil.cpp +++ b/src/xrCore/Threading/ThreadUtil.cpp @@ -28,42 +28,45 @@ static int pthread_setname_np(pthread_t /*threadId*/, const char* name) namespace Threading { #if defined(XR_PLATFORM_WINDOWS) -void SetThreadNameImpl(DWORD threadId, pcstr name) +void SetThreadNameImpl(pcstr name) { - const DWORD MSVC_EXCEPTION = 0x406D1388; + string256 fullName; + strconcat(fullName, "X-Ray ", name); - struct SThreadNameInfo - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - }; - - constexpr char namePrefix[] = "X-Ray "; - constexpr auto namePrefixSize = std::size(namePrefix); // includes null-character intentionally - auto fullNameSize = xr_strlen(name) + namePrefixSize; - auto fullName = static_cast(xr_alloca(fullNameSize)); - strconcat(fullNameSize, fullName, namePrefix, name); - - SThreadNameInfo info; - info.dwType = 0x1000; - info.szName = fullName; - info.dwThreadID = threadId; - info.dwFlags = 0; - - __try + using SetThreadDescriptionProc = decltype(&SetThreadDescription); + static auto kernelHandle = GetModuleHandleA("kernel32.dll"); + static auto setThreadDescription = reinterpret_cast(GetProcAddress(kernelHandle, "SetThreadDescription")); + + if (setThreadDescription) { - RaiseException(MSVC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info); + wchar_t buf[256]; + mbstowcs(buf, fullName, 256); + + setThreadDescription(GetCurrentThread(), buf); } - __except (EXCEPTION_CONTINUE_EXECUTION) + else __try { + constexpr DWORD MSVC_EXCEPTION = 0x406D1388; + + struct SThreadNameInfo + { + DWORD dwType{ 0x1000 }; + LPCSTR szName{}; + DWORD dwThreadID{ DWORD(-1) }; + DWORD dwFlags{}; + }; + + SThreadNameInfo info; + info.szName = fullName; + + RaiseException(MSVC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); } + __except (EXCEPTION_CONTINUE_EXECUTION) {} } void SetCurrentThreadName(cpcstr name) { - SetThreadNameImpl(-1, name); + SetThreadNameImpl(name); #ifdef TRACY_ENABLE tracy::SetThreadName(name); #endif From 5770e20cff04b3f96f972b7eb08dd0f8c72b6b0c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 22:15:54 +0500 Subject: [PATCH 383/497] Fix crash on level unloading --- src/xrEngine/IGame_Persistent.h | 2 +- src/xrGame/GamePersistent.cpp | 2 +- src/xrGame/GamePersistent.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 65c639aae92..3c5200b06e3 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -167,7 +167,7 @@ class ENGINE_API IGame_Persistent : public: virtual IGame_Level* CreateLevel() { return nullptr; } - virtual void DestroyLevel(IGame_Level* lvl) { VERIFY(lvl == nullptr); } + virtual void DestroyLevel(IGame_Level*& lvl) { VERIFY(lvl == nullptr); } virtual void PreStart(pcstr op); virtual void Start(pcstr op); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 6b1c353e541..57280a32b2d 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -88,7 +88,7 @@ IGame_Level* CGamePersistent::CreateLevel() return xr_new(); } -void CGamePersistent::DestroyLevel(IGame_Level* lvl) +void CGamePersistent::DestroyLevel(IGame_Level*& lvl) { xr_delete(lvl); } diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index fc6ac22e8a9..8ed8431e976 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -66,7 +66,7 @@ class CGamePersistent : public IGame_Persistent ~CGamePersistent() override; IGame_Level* CreateLevel() override; - void DestroyLevel(IGame_Level* lvl) override; + void DestroyLevel(IGame_Level*& lvl) override; void PreStart(LPCSTR op) override; virtual void Start(LPCSTR op); From c2e25c972fa10a0d04ad55a8f91943d0cf229fe6 Mon Sep 17 00:00:00 2001 From: Krzysztof Sobiecki Date: Tue, 7 May 2024 09:06:04 +0200 Subject: [PATCH 384/497] Fix crash during TaskScheduler creation (#1667) --- src/xrCore/Threading/TaskManager.cpp | 12 ++++++++---- src/xrCore/Threading/TaskManager.hpp | 1 + src/xrCore/xrCore.cpp | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index a2b37544a0c..1de8f519b69 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -192,14 +192,18 @@ void CalcIterations() TaskManager::TaskManager() { ZoneScoped; - CalcIterations(); - workers.reserve(std::thread::hardware_concurrency()); - RegisterThisThreadAsWorker(); +} - const u32 threads = std::thread::hardware_concurrency() - OTHER_THREADS_COUNT; +void TaskManager::SpawnThreads() +{ + ZoneScoped; + CalcIterations(); + + const u32 threads = workers.capacity() - OTHER_THREADS_COUNT; workerThreads.reserve(threads); + for (u32 i = 0; i < threads; ++i) { workerThreads.emplace_back(Threading::RunThread("Task Worker", &TaskManager::TaskWorkerStart, this)); diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index f5dd29da8b9..c210c8934b7 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -50,6 +50,7 @@ class XRCORE_API TaskManager final public: TaskManager(); ~TaskManager(); + void SpawnThreads(); public: // TaskFunc is at the end for fancy in-place lambdas diff --git a/src/xrCore/xrCore.cpp b/src/xrCore/xrCore.cpp index 11505088a72..0f95ad699b8 100644 --- a/src/xrCore/xrCore.cpp +++ b/src/xrCore/xrCore.cpp @@ -274,6 +274,7 @@ void xrCore::Initialize(pcstr _ApplicationName, pcstr commandLine, bool init_fs, Msg("\ncommand line %s\n", Params); _initialize_cpu(); TaskScheduler = xr_make_unique(); + TaskScheduler->SpawnThreads(); // xrDebug::Initialize (); rtc_initialize(); From 85e682ec6c16e63e1180ca6248e0eca22eff1502 Mon Sep 17 00:00:00 2001 From: Krzysztof Sobiecki Date: Thu, 9 May 2024 12:03:35 +0200 Subject: [PATCH 385/497] debian/: Switch to use gcc-14 (#1668) --- debian/changelog | 6 ++++++ debian/control | 4 ++-- debian/rules | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 7ae1b413f3b..b90e10de4a9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openxray (1.6.02-15) UNRELEASED; urgency=medium + + * Move to use gcc-14 + + -- Krzysztof Sobiecki Tue, 07 May 2024 01:12:42 +0200 + openxray (1.6.02-14) experimental; urgency=medium * Update *.install files diff --git a/debian/control b/debian/control index 45ad9ed33d6..a8cde174a8d 100644 --- a/debian/control +++ b/debian/control @@ -18,10 +18,10 @@ Build-Depends: liblzo2-dev, libjpeg-dev, libncurses5-dev, - gcc-10, + gcc-14, libpcre3-dev, libsdl2-dev, - g++-10, + g++-14, debhelper, Build-Conflicts: libmimalloc-dev, diff --git a/debian/rules b/debian/rules index 150146fcf1a..6960da78e1c 100755 --- a/debian/rules +++ b/debian/rules @@ -8,8 +8,8 @@ endif dh $@ --buildsystem=cmake --parallel extra_flags += \ --DCMAKE_C_COMPILER=gcc-10 \ --DCMAKE_CXX_COMPILER=g++-10 \ +-DCMAKE_C_COMPILER=gcc-14 \ +-DCMAKE_CXX_COMPILER=g++-14 \ -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ -DCMAKE_INSTALL_BINDIR="/usr/games" \ -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=FALSE \ From 26c6f737a699e33e67e18ee5627da22e7a3a84de Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 22:39:56 +0500 Subject: [PATCH 386/497] Prevent crashes after game persistent destroy --- src/xrEngine/EngineAPI.h | 2 +- src/xrGame/xrGame.cpp | 2 +- src/xrGame/xrGame.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index 3006b3a1d1b..f2207f41d69 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -45,7 +45,7 @@ class XR_NOVTABLE GameModule virtual void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) = 0; virtual void finalize() = 0; virtual IGame_Persistent* create_persistent() = 0; - virtual void destroy_persistent(IGame_Persistent* persistent) = 0; + virtual void destroy_persistent(IGame_Persistent*& persistent) = 0; }; class XR_NOVTABLE RendererModule diff --git a/src/xrGame/xrGame.cpp b/src/xrGame/xrGame.cpp index 927cee3eb48..5df8cb25593 100644 --- a/src/xrGame/xrGame.cpp +++ b/src/xrGame/xrGame.cpp @@ -92,7 +92,7 @@ IGame_Persistent* xrGameModule::create_persistent() return xr_new(); } -void xrGameModule::destroy_persistent(IGame_Persistent* persistent) +void xrGameModule::destroy_persistent(IGame_Persistent*& persistent) { xr_delete(persistent); } diff --git a/src/xrGame/xrGame.h b/src/xrGame/xrGame.h index b5f2a2050d1..412cd15d58a 100644 --- a/src/xrGame/xrGame.h +++ b/src/xrGame/xrGame.h @@ -25,7 +25,7 @@ class xrGameModule final : public GameModule void initialize(Factory_Create*& pCreate, Factory_Destroy*& pDestroy) override; void finalize() override; IGame_Persistent* create_persistent() override; - void destroy_persistent(IGame_Persistent* persistent) override; + void destroy_persistent(IGame_Persistent*& persistent) override; }; extern XRGAME_API xrGameModule xrGame; From 606d5fba2f8b23a88488fbcd37a1680bd9e4fa02 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 22:45:46 +0500 Subject: [PATCH 387/497] xrEngine/x_ray.cpp: move -fsltx key check lower --- src/xrEngine/x_ray.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 4bb7c097589..baf9f5ec3af 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -279,14 +279,6 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) ShowSplash(topmost); } - pcstr fsltx = "-fsltx "; - string_path fsgame = ""; - if (strstr(commandLine, fsltx)) - { - const size_t sz = xr_strlen(fsltx); - sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); - } - const auto& inputTask = TaskManager::AddTask([](Task&, void*) { const bool captureInput = !strstr(Core.Params, "-i"); @@ -303,6 +295,14 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Engine.External.CreateRendererList(); }); + pcstr fsltx = "-fsltx "; + string_path fsgame = ""; + if (strstr(commandLine, fsltx)) + { + const size_t sz = xr_strlen(fsltx); + sscanf(strstr(commandLine, fsltx) + sz, "%[^ ] ", fsgame); + } + Core.Initialize("OpenXRay", commandLine, true, *fsgame ? fsgame : nullptr); InitSettings(); From 15832424cc32960100ba7d6dc370900b24390cd1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 5 May 2024 23:02:36 +0500 Subject: [PATCH 388/497] Initialize Discord later, when user settings are loaded So that we can check if a user has disabled Discord status display and not initialize Discord in this case. This also speeds up splash screen showing --- src/xrEngine/x_ray.cpp | 88 +++++++++++++++++++++--------------------- src/xrEngine/x_ray.h | 1 + 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index baf9f5ec3af..f0f7a93c190 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -238,41 +238,6 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) shortcuts.Disable(); #endif -#ifdef USE_DISCORD_INTEGRATION - discord::Activity activity{}; - { - ZoneScopedN("Init Discord"); - discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &m_discord_core); - -# ifndef MASTER_GOLD - if (m_discord_core) - { - const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; - m_discord_core->SetLogHook(level, [](discord::LogLevel level, pcstr message) - { - switch (level) - { - case discord::LogLevel::Error: Log("!", message); break; - case discord::LogLevel::Warn: Log("~", message); break; - case discord::LogLevel::Info: Log("*", message); break; - case discord::LogLevel::Debug: Log("#", message); break; - } - }); - } -# endif - - activity.SetType(discord::ActivityType::Playing); - activity.SetApplicationId(DISCORD_APP_ID); - activity.SetState("Starting engine..."); - activity.GetAssets().SetLargeImage("logo"); - if (m_discord_core) - { - std::lock_guard guard{ m_discord_lock }; - m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); - } - } -#endif - if (!strstr(commandLine, "-nosplash")) { const bool topmost = !strstr(commandLine, "-splashnotop"); @@ -324,17 +289,9 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Console->OnDeviceInitialize(); -#ifdef USE_DISCORD_INTEGRATION - const std::locale locale(""); - activity.SetState(StringToUTF8(Core.ApplicationTitle, locale).c_str()); - if (m_discord_core) - { - std::lock_guard guard{ m_discord_lock }; - m_discord_core->ActivityManager().UpdateActivity(activity, nullptr); - } -#endif - execUserScript(); + InitializeDiscord(); + TaskScheduler->Wait(createSoundDevicesList); Engine.Sound.Create(); @@ -557,6 +514,47 @@ void CApplication::HideSplash() SDL_FreeSurface(m_surface); } +void CApplication::InitializeDiscord() +{ +#ifdef USE_DISCORD_INTEGRATION + ZoneScoped; + discord::Core* core; + discord::Core::Create(DISCORD_APP_ID, discord::CreateFlags::NoRequireDiscord, &core); + +# ifndef MASTER_GOLD + if (core) + { + const auto level = xrDebug::DebuggerIsPresent() ? discord::LogLevel::Debug : discord::LogLevel::Info; + core->SetLogHook(level, [](discord::LogLevel level, pcstr message) + { + switch (level) + { + case discord::LogLevel::Error: Log("!", message); break; + case discord::LogLevel::Warn: Log("~", message); break; + case discord::LogLevel::Info: Log("*", message); break; + case discord::LogLevel::Debug: Log("#", message); break; + } + }); + } +# endif + + if (core) + { + const std::locale locale(""); + + discord::Activity activity{}; + activity.SetType(discord::ActivityType::Playing); + activity.SetApplicationId(DISCORD_APP_ID); + activity.SetState(StringToUTF8(Core.ApplicationTitle, locale).c_str()); + activity.GetAssets().SetLargeImage("logo"); + core->ActivityManager().UpdateActivity(activity, nullptr); + + std::lock_guard guard{ m_discord_lock }; + m_discord_core = core; + } +#endif +} + void CApplication::UpdateDiscordStatus() { #ifdef USE_DISCORD_INTEGRATION diff --git a/src/xrEngine/x_ray.h b/src/xrEngine/x_ray.h index d7bc129faba..2a698f6c420 100644 --- a/src/xrEngine/x_ray.h +++ b/src/xrEngine/x_ray.h @@ -35,6 +35,7 @@ class ENGINE_API CApplication final void ShowSplash(bool topmost); void HideSplash(); + void InitializeDiscord(); void UpdateDiscordStatus(); public: From 489686106de5d2210a36c2a3200e3d8e9308ea20 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 16:33:39 +0500 Subject: [PATCH 389/497] Add renderer finalization mechanism (similar to 810692a400ad17bc1d0123dd0ebc33e6cc9c899c and #804) Should help a bit with #1651. --- src/Layers/xrRenderPC_GL/xrRender_GL.cpp | 14 ++++++++++++++ src/Layers/xrRenderPC_R4/xrRender_R4.cpp | 14 ++++++++++++++ src/xrEngine/EngineAPI.cpp | 23 ++++++++++++++++------- src/xrEngine/EngineAPI.h | 3 ++- src/xrEngine/Render.cpp | 12 ++++++++++-- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp index 1524f72a591..698475ef628 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp @@ -65,6 +65,20 @@ class RGLRendererModule final : public RendererModule #endif xrRender_initconsole(); } + + void ClearEnv() override + { + modes.clear(); + + if (GEnv.Render == &RImplementation) + { + GEnv.Render = nullptr; + GEnv.RenderFactory = nullptr; + GEnv.DU = nullptr; + GEnv.UIRender = nullptr; + GEnv.DRender = nullptr; + } + } } static s_rgl_module; extern "C" diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index b68691348c0..4ba5a90d49a 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -101,6 +101,20 @@ class R4RendererModule final : public RendererModule #endif xrRender_initconsole(); } + + void ClearEnv() override + { + modes.clear(); + + if (GEnv.Render == &RImplementation) + { + GEnv.Render = nullptr; + GEnv.RenderFactory = nullptr; + GEnv.DU = nullptr; + GEnv.UIRender = nullptr; + GEnv.DRender = nullptr; + } + } } static s_r4_module; extern "C" diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index b599d2205a0..2b0b3ee1b28 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -101,8 +101,10 @@ void CEngineAPI::SelectRenderer() } } - // Ask current renderer to setup GEnv + CloseUnusedLibraries(); R_ASSERT2(selectedRenderer, "Can't setup renderer"); + + // Ask current renderer to setup GEnv selectedRenderer->SetupEnv(selected_mode); Log("Selected renderer:", selected_mode); @@ -121,8 +123,6 @@ void CEngineAPI::Initialize(GameModule* game) R_ASSERT(pCreate); R_ASSERT(pDestroy); } - - CloseUnusedLibraries(); } void CEngineAPI::Destroy() @@ -132,19 +132,28 @@ void CEngineAPI::Destroy() if (gameModule) gameModule->finalize(); + selectedRenderer = nullptr; + CloseUnusedLibraries(); + pCreate = nullptr; pDestroy = nullptr; XRC.r_clear_compact(); } -void CEngineAPI::CloseUnusedLibraries() +void CEngineAPI::CloseUnusedLibraries() const { ZoneScoped; - for (RendererDesc& desc : g_render_modules) + for (auto& [_, handle, module] : g_render_modules) { - if (desc.module != selectedRenderer) - desc.handle = nullptr; + if (!handle) + continue; + if (module == selectedRenderer) + continue; + + module->ClearEnv(); + module = nullptr; + handle = nullptr; } } diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index f2207f41d69..790a72b1455 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -55,6 +55,7 @@ class XR_NOVTABLE RendererModule virtual const xr_vector& ObtainSupportedModes() = 0; virtual bool CheckGameRequirements() = 0; virtual void SetupEnv(pcstr mode) = 0; + virtual void ClearEnv() = 0; }; class ENGINE_API CEngineAPI @@ -65,7 +66,7 @@ class ENGINE_API CEngineAPI RendererModule* selectedRenderer{}; void SelectRenderer(); - void CloseUnusedLibraries(); + void CloseUnusedLibraries() const; public: Factory_Create* pCreate; diff --git a/src/xrEngine/Render.cpp b/src/xrEngine/Render.cpp index 27248ae10d7..605aed454fc 100644 --- a/src/xrEngine/Render.cpp +++ b/src/xrEngine/Render.cpp @@ -2,8 +2,16 @@ #include "Render.h" // resources -IRender_Light::~IRender_Light() { GEnv.Render->light_destroy(this); } -IRender_Glow::~IRender_Glow() { GEnv.Render->glow_destroy(this); } +IRender_Light::~IRender_Light() +{ + if (GEnv.Render) + GEnv.Render->light_destroy(this); +} +IRender_Glow::~IRender_Glow() +{ + if (GEnv.Render) + GEnv.Render->glow_destroy(this); +} IRender::ScopedContext::ScopedContext(RenderContext context) { From 2a10896ca99e2b0ac1b64eccb71b6fae26643ea1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 16:34:09 +0500 Subject: [PATCH 390/497] xrEngine/EngineAPI.cpp: protect renderModes with lock --- src/xrEngine/EngineAPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 2b0b3ee1b28..ba03a6749e6 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -211,8 +211,8 @@ void CEngineAPI::CreateRendererList() mode = temp; } shared_str copiedMode = mode; - renderModes[copiedMode] = desc.module; std::lock_guard guard{ mutex }; + renderModes[copiedMode] = desc.module; VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! } }; From 4c169651433837f45a5af9aefcedaccc121737b1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 19:06:51 +0500 Subject: [PATCH 391/497] xrSound/SoundRender_Emitter_FSM.cpp: formatting --- src/xrSound/SoundRender_Emitter_FSM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index a71118d004d..502eb1c857b 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -214,7 +214,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) break; } - //--#SM+# Begin-- + //--#SM+# Begin-- // hard rewind switch (m_current_state) { From 9f9a117dc44c93ed15a63ea50a2e0b5e6110fbee Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 19:19:43 +0500 Subject: [PATCH 392/497] xrSound/SoundRender_Emitter_FSM.cpp: removed check for target existence The target MUST exist when an emitter is in stPlaying or stPlayingLooped state. If it doesn't exist, then the assert in stop_target() should be triggered. --- src/xrSound/SoundRender_Emitter_FSM.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 502eb1c857b..a26a0035279 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -107,11 +107,8 @@ void CSoundRender_Emitter::update(float fTime, float dt) case stPlaying: if (iPaused) { - if (target) - { - stop_target(); - m_current_state = stSimulating; - } + stop_target(); + m_current_state = stSimulating; fTimeStarted += dt; fTimeToStop += dt; fTimeToPropagade += dt; @@ -174,11 +171,8 @@ void CSoundRender_Emitter::update(float fTime, float dt) case stPlayingLooped: if (iPaused) { - if (target) - { - stop_target(); - m_current_state = stSimulatingLooped; - } + stop_target(); + m_current_state = stSimulatingLooped; fTimeStarted += dt; fTimeToPropagade += dt; break; From d7c4d3047cb422d5433036d25bffd16273fdc12b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:35:38 +0500 Subject: [PATCH 393/497] Removed EFX It was unfinished and SteamAudio provides more features. --- src/xrSound/CMakeLists.txt | 2 - src/xrSound/SoundRender_CoreA.cpp | 17 +-- src/xrSound/SoundRender_EffectsA_EFX.cpp | 158 ----------------------- src/xrSound/SoundRender_EffectsA_EFX.h | 47 ------- src/xrSound/SoundRender_Environment.cpp | 91 ------------- src/xrSound/SoundRender_Environment.h | 11 -- src/xrSound/SoundRender_TargetA.cpp | 13 +- src/xrSound/SoundRender_TargetA.h | 3 +- src/xrSound/xrSound.vcxproj | 2 - src/xrSound/xrSound.vcxproj.filters | 6 - 10 files changed, 5 insertions(+), 345 deletions(-) delete mode 100644 src/xrSound/SoundRender_EffectsA_EFX.cpp delete mode 100644 src/xrSound/SoundRender_EffectsA_EFX.h diff --git a/src/xrSound/CMakeLists.txt b/src/xrSound/CMakeLists.txt index e37cdfca483..8d27602eb22 100644 --- a/src/xrSound/CMakeLists.txt +++ b/src/xrSound/CMakeLists.txt @@ -34,8 +34,6 @@ target_sources_grouped( FILES SoundRender_EffectsA_EAX.cpp SoundRender_EffectsA_EAX.h - SoundRender_EffectsA_EFX.cpp - SoundRender_EffectsA_EFX.h ) target_sources_grouped( diff --git a/src/xrSound/SoundRender_CoreA.cpp b/src/xrSound/SoundRender_CoreA.cpp index 99167e7a9fd..3ada373ac8a 100644 --- a/src/xrSound/SoundRender_CoreA.cpp +++ b/src/xrSound/SoundRender_CoreA.cpp @@ -5,7 +5,6 @@ #include "SoundRender_TargetA.h" #include "OpenALDeviceList.h" #include "SoundRender_EffectsA_EAX.h" -#include "SoundRender_EffectsA_EFX.h" CSoundRender_CoreA::CSoundRender_CoreA(CSoundManager& p) : CSoundRender_Core(p) @@ -87,7 +86,6 @@ void CSoundRender_CoreA::_initialize() supports_float_pcm &= psSoundFlags.test(ss_UseFloat32); - auto auxSlot = ALuint(-1); #if defined(XR_HAS_EAX) // Check for EAX extension if (deviceDesc.props.eax && !m_effects) @@ -99,19 +97,6 @@ void CSoundRender_CoreA::_initialize() xr_delete(m_effects); } } -#elif defined(XR_HAS_EFX) - // Check for EFX extension - if (deviceDesc.props.efx && !m_effects) - { - m_effects = xr_new(); - if (m_effects->initialized()) - auxSlot = ((CSoundRender_EffectsA_EFX*)m_effects)->get_slot(); - else - { - Log("SOUND: OpenAL: Failed to initialize EFX."); - xr_delete(m_effects); - } - } #endif inherited::_initialize(); @@ -119,7 +104,7 @@ void CSoundRender_CoreA::_initialize() CSoundRender_Target* T = nullptr; for (u32 tit = 0; tit < u32(psSoundTargets); tit++) { - T = xr_new(auxSlot); + T = xr_new(); if (T->_initialize()) { s_targets.emplace_back(T); diff --git a/src/xrSound/SoundRender_EffectsA_EFX.cpp b/src/xrSound/SoundRender_EffectsA_EFX.cpp deleted file mode 100644 index 102dbcb06ff..00000000000 --- a/src/xrSound/SoundRender_EffectsA_EFX.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "stdafx.h" - -#include "SoundRender_EffectsA_EFX.h" - -#ifdef XR_HAS_EFX -# include "SoundRender_CoreA.h" -# include "SoundRender_Environment.h" - -#define LOAD_PROC(x, type) \ - do \ - { \ - ((x) = (type)alGetProcAddress(#x)); \ - if (!(x)) \ - return; \ - } while (false) - -CSoundRender_EffectsA_EFX::CSoundRender_EffectsA_EFX() -{ - LOAD_PROC(alGenEffects, LPALGENEFFECTS); - LOAD_PROC(alDeleteEffects, LPALDELETEEFFECTS); - LOAD_PROC(alIsEffect, LPALISEFFECT); - LOAD_PROC(alEffecti, LPALEFFECTI); - LOAD_PROC(alEffectf, LPALEFFECTF); - LOAD_PROC(alEffectfv, LPALEFFECTFV); - LOAD_PROC(alGetEffectf, LPALGETEFFECTF); - LOAD_PROC(alGetEffectfv, LPALGETEFFECTFV); - LOAD_PROC(alGetEffecti, LPALGETEFFECTI); - LOAD_PROC(alGenAuxiliaryEffectSlots, LPALGENAUXILIARYEFFECTSLOTS); - LOAD_PROC(alDeleteAuxiliaryEffectSlots, LPALDELETEAUXILIARYEFFECTSLOTS); - LOAD_PROC(alAuxiliaryEffectSloti, LPALAUXILIARYEFFECTSLOTI); - LOAD_PROC(alAuxiliaryEffectSlotf, LPALAUXILIARYEFFECTSLOTF); - LOAD_PROC(alIsAuxiliaryEffectSlot, LPALISAUXILIARYEFFECTSLOT); - - alGenEffects(1, &effect); - - constexpr ALfloat f3[3] = { 0.f, 0.f, 0.f }; - alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); - alEffectf(effect, AL_EAXREVERB_DENSITY, AL_EAXREVERB_DEFAULT_DENSITY); - alEffectf(effect, AL_EAXREVERB_DIFFUSION, AL_EAXREVERB_DEFAULT_DIFFUSION); - alEffectf(effect, AL_EAXREVERB_GAIN, AL_EAXREVERB_DEFAULT_GAIN); - alEffectf(effect, AL_EAXREVERB_GAINHF, AL_EAXREVERB_DEFAULT_GAINHF); - alEffectf(effect, AL_EAXREVERB_GAINLF, AL_EAXREVERB_DEFAULT_GAINLF); - alEffectf(effect, AL_EAXREVERB_DECAY_TIME, AL_EAXREVERB_DEFAULT_DECAY_TIME); - alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, AL_EAXREVERB_DEFAULT_DECAY_HFRATIO); - alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, AL_EAXREVERB_DEFAULT_DECAY_LFRATIO); - alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN); - alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY); - alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, f3); - alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN); - alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY); - alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, f3); - alEffectf(effect, AL_EAXREVERB_ECHO_TIME, AL_EAXREVERB_DEFAULT_ECHO_TIME); - alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, AL_EAXREVERB_DEFAULT_ECHO_DEPTH); - alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, AL_EAXREVERB_DEFAULT_MODULATION_TIME); - alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, AL_EAXREVERB_DEFAULT_MODULATION_DEPTH); - alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF); - alEffectf(effect, AL_EAXREVERB_HFREFERENCE, AL_EAXREVERB_DEFAULT_HFREFERENCE); - alEffectf(effect, AL_EAXREVERB_LFREFERENCE, AL_EAXREVERB_DEFAULT_LFREFERENCE); - alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR); - alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT); - - /* Check if an error occured, and clean up if so. */ - if (const ALenum err = alGetError(); err == AL_NO_ERROR) - m_is_supported = true; - else - { - Log("SOUND: OpenAL: Failed to init EFX:", alGetString(err)); - if (alIsEffect(effect)) - alDeleteEffects(1, &effect); - } - - alGenAuxiliaryEffectSlots(1, &slot); - if (const ALenum err = alGetError(); err != AL_NO_ERROR) - Log("! SOUND: OpenAL: failed to generate auxiliary slot:", alGetString(err)); - - Log("* SOUND: EFX extension:", m_is_supported ? "present" : "absent"); -} - -#undef LOAD_PROC - -CSoundRender_EffectsA_EFX::~CSoundRender_EffectsA_EFX() -{ - if (m_is_supported) - { - alDeleteEffects(1, &effect); - if (alIsAuxiliaryEffectSlot(slot)) - alDeleteAuxiliaryEffectSlots(1, &slot); - } -} - -bool CSoundRender_EffectsA_EFX::initialized() -{ - return m_is_supported; -} - -void CSoundRender_EffectsA_EFX::set_listener(const CSoundRender_Environment& env) -{ - A_CHK(alEffectf(effect, AL_EAXREVERB_DENSITY, env.Density)); - A_CHK(alEffectf(effect, AL_EAXREVERB_DIFFUSION, env.EnvironmentDiffusion)); - A_CHK(alEffectf(effect, AL_EAXREVERB_GAIN, env.Room)); - A_CHK(alEffectf(effect, AL_EAXREVERB_GAINHF, env.RoomHF)); - A_CHK(alEffectf(effect, AL_EAXREVERB_DECAY_TIME, env.DecayTime)); - A_CHK(alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, env.DecayHFRatio)); - A_CHK(alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, env.DecayLFRatio)); - A_CHK(alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, env.Reflections)); - A_CHK(alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, env.ReflectionsDelay)); - //A_CHK(alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, &env.ReflectionsPan[0])); - A_CHK(alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, env.Reverb)); - A_CHK(alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, env.ReverbDelay)); - //A_CHK(alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, &env.ReverbPan[0])); - A_CHK(alEffectf(effect, AL_EAXREVERB_ECHO_TIME, env.EchoTime)); - A_CHK(alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, env.EchoDepth)); - A_CHK(alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, env.ModulationTime)); - A_CHK(alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, env.ModulationDepth)); - A_CHK(alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, env.AirAbsorptionHF)); - A_CHK(alEffectf(effect, AL_EAXREVERB_HFREFERENCE, env.HFReference)); - A_CHK(alEffectf(effect, AL_EAXREVERB_LFREFERENCE, env.LFReference)); - A_CHK(alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, env.RoomRolloffFactor)); - A_CHK(alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, env.DecayHFLimit)); -} - -void CSoundRender_EffectsA_EFX::get_listener(CSoundRender_Environment& env) -{ - A_CHK(alGetEffectf(effect, AL_EAXREVERB_DENSITY, &env.Density)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_DIFFUSION, &env.EnvironmentDiffusion)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_GAIN, &env.Room)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_GAINHF, &env.RoomHF)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_DECAY_TIME, &env.DecayTime)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, &env.DecayHFRatio)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, &env.DecayLFRatio)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, &env.Reflections)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, &env.ReflectionsDelay)); - //A_CHK(alGetEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, (float*)&env.ReflectionsPan)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, &env.Reverb)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, &env.ReverbDelay)); - //A_CHK(alGetEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, (float*)&env.ReverbPan)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_ECHO_TIME, &env.EchoTime)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, &env.EchoDepth)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_MODULATION_TIME, &env.ModulationTime)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, &env.ModulationDepth)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, &env.AirAbsorptionHF)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_HFREFERENCE, &env.HFReference)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_LFREFERENCE, &env.LFReference)); - A_CHK(alGetEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, &env.RoomRolloffFactor)); - A_CHK(alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, (ALint)env.DecayHFLimit)); -} - -void CSoundRender_EffectsA_EFX::commit() -{ - /* Tell the effect slot to use the loaded effect object. Note that the this - * effectively copies the effect properties. You can modify or delete the - * effect object afterward without affecting the effect slot. - */ - A_CHK(alAuxiliaryEffectSlotf(slot, AL_EFFECTSLOT_GAIN, 1.f)); - A_CHK(alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, false)); - A_CHK(alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect)); -} -#endif // XR_HAS_EFX diff --git a/src/xrSound/SoundRender_EffectsA_EFX.h b/src/xrSound/SoundRender_EffectsA_EFX.h deleted file mode 100644 index 705daa0c4e1..00000000000 --- a/src/xrSound/SoundRender_EffectsA_EFX.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "SoundRender_Effects.h" - -#if __has_include() -# include -# include -# include -# define XR_HAS_EFX - -class CSoundRender_EffectsA_EFX : public CSoundRender_Effects -{ - LPALGENEFFECTS alGenEffects{}; - LPALDELETEEFFECTS alDeleteEffects{}; - LPALISEFFECT alIsEffect{}; - LPALEFFECTF alEffectf{}; - LPALEFFECTI alEffecti{}; - LPALEFFECTFV alEffectfv{}; - LPALGETEFFECTI alGetEffecti{}; - LPALGETEFFECTF alGetEffectf{}; - LPALGETEFFECTFV alGetEffectfv{}; - LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots{}; - LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots{}; - LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti{}; - LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf{}; - LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv{}; - LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot{}; - - ALuint effect{}; - ALuint effectfv{}; - ALuint slot{}; - - bool m_is_supported{}; // Boolean variable to indicate presence of EFX Extension - -public: - CSoundRender_EffectsA_EFX(); - ~CSoundRender_EffectsA_EFX() override; - - bool initialized() override; - - auto get_slot() const { return slot; } - void set_listener(const CSoundRender_Environment& env) override; - void get_listener(CSoundRender_Environment& env) override; - - void commit() override; -}; -#endif // #if __has_include() diff --git a/src/xrSound/SoundRender_Environment.cpp b/src/xrSound/SoundRender_Environment.cpp index d8b9d93abe8..79437ab8e5d 100644 --- a/src/xrSound/SoundRender_Environment.cpp +++ b/src/xrSound/SoundRender_Environment.cpp @@ -4,7 +4,6 @@ #include "SoundRender_Environment.h" #include "SoundRender_EffectsA_EAX.h" -#include "SoundRender_EffectsA_EFX.h" CSoundRender_Environment::CSoundRender_Environment() { @@ -29,33 +28,6 @@ void CSoundRender_Environment::set_default() EnvironmentSize = EAXLISTENER_DEFAULTENVIRONMENTSIZE; EnvironmentDiffusion = EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION; AirAbsorptionHF = EAXLISTENER_DEFAULTAIRABSORPTIONHF; -#elif defined(XR_HAS_EFX) - - EFXEAXREVERBPROPERTIES reverbs[1] = - { - EFX_REVERB_PRESET_GENERIC - }; - - Room = reverbs->flGain; - RoomHF = reverbs->flGainHF; - Density = reverbs->flDensity; - RoomRolloffFactor = reverbs->flRoomRolloffFactor; - DecayTime = reverbs->flDecayTime; - DecayHFRatio = reverbs->flDecayHFRatio; - DecayLFRatio = reverbs->flDecayLFRatio; - Reflections = reverbs->flReflectionsGain; - ReflectionsDelay = reverbs->flReflectionsDelay; - Reverb = reverbs->flLateReverbGain; - ReverbDelay = reverbs->flLateReverbDelay; - EnvironmentDiffusion = reverbs->flDiffusion; - AirAbsorptionHF = reverbs->flAirAbsorptionGainHF; - DecayHFLimit = reverbs->iDecayHFLimit; - EchoTime = reverbs->flEchoTime; - EchoDepth = reverbs->flEchoDepth; - ModulationTime = reverbs->flModulationTime; - ModulationDepth = reverbs->flModulationDepth; - HFReference = reverbs->flHFReference; - LFReference = reverbs->flLFReference; #endif } @@ -64,8 +36,6 @@ void CSoundRender_Environment::set_identity() set_default(); #if defined(XR_HAS_EAX) Room = EAXLISTENER_MINROOM; -#elif defined(XR_HAS_EFX) - Room = AL_EAXREVERB_MIN_GAIN; #endif clamp(); } @@ -86,16 +56,6 @@ void CSoundRender_Environment::lerp(CSoundRender_Environment& A, CSoundRender_En EnvironmentSize = fi * A.EnvironmentSize + f * B.EnvironmentSize; EnvironmentDiffusion = fi * A.EnvironmentDiffusion + f * B.EnvironmentDiffusion; AirAbsorptionHF = fi * A.AirAbsorptionHF + f * B.AirAbsorptionHF; -#if defined(XR_HAS_EFX) - DecayLFRatio = fi * A.DecayLFRatio + f * B.DecayLFRatio; - ModulationTime = fi * A.ModulationTime + f * B.ModulationTime; - ModulationDepth = fi * A.ModulationDepth + f * B.ModulationDepth; - Density = fi * A.Density + f * B.Density; - HFReference = fi * A.HFReference + f * B.HFReference; - LFReference = fi * A.LFReference + f * B.LFReference; - EchoTime = fi * A.EchoTime + f * B.EchoTime; - EchoDepth = fi * A.EchoDepth + f * B.EchoDepth; -#endif clamp(); } @@ -134,27 +94,6 @@ void CSoundRender_Environment::clamp() ::clamp(EnvironmentSize, EAXLISTENER_MINENVIRONMENTSIZE, EAXLISTENER_MAXENVIRONMENTSIZE); ::clamp(EnvironmentDiffusion, EAXLISTENER_MINENVIRONMENTDIFFUSION, EAXLISTENER_MAXENVIRONMENTDIFFUSION); ::clamp(AirAbsorptionHF, EAXLISTENER_MINAIRABSORPTIONHF, EAXLISTENER_MAXAIRABSORPTIONHF); -#elif defined(XR_HAS_EFX) - ::clamp(Room, (float)AL_EAXREVERB_MIN_GAIN, (float)AL_EAXREVERB_MAX_GAIN); - ::clamp(RoomHF, (float)AL_EAXREVERB_MIN_GAINHF, (float)AL_EAXREVERB_MAX_GAINHF); - ::clamp(RoomRolloffFactor,AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR, AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR); - ::clamp(DecayTime, AL_EAXREVERB_MIN_DECAY_TIME, AL_EAXREVERB_MAX_DECAY_TIME); - ::clamp(DecayHFRatio, AL_EAXREVERB_MIN_DECAY_HFRATIO, AL_EAXREVERB_MAX_DECAY_HFRATIO); - ::clamp(DecayLFRatio, AL_EAXREVERB_MIN_DECAY_LFRATIO, AL_EAXREVERB_MAX_DECAY_LFRATIO); - ::clamp(Reflections, (float)AL_EAXREVERB_MIN_REFLECTIONS_GAIN, (float)AL_EAXREVERB_MAX_REFLECTIONS_GAIN); - ::clamp(ReflectionsDelay, AL_EAXREVERB_MIN_REFLECTIONS_DELAY, (float)AL_EAXREVERB_MAX_REFLECTIONS_DELAY); - ::clamp(EchoTime, AL_EAXREVERB_MIN_ECHO_TIME, AL_EAXREVERB_MAX_ECHO_TIME); - ::clamp(EchoTime, AL_EAXREVERB_MIN_ECHO_DEPTH, AL_EAXREVERB_MAX_ECHO_DEPTH); - ::clamp(Reverb, (float)AL_EAXREVERB_MIN_LATE_REVERB_GAIN, (float)AL_EAXREVERB_MAX_LATE_REVERB_GAIN); - ::clamp(ReverbDelay, AL_EAXREVERB_MIN_LATE_REVERB_DELAY, AL_EAXREVERB_MAX_LATE_REVERB_DELAY); - ::clamp(EnvironmentDiffusion, AL_EAXREVERB_MIN_DIFFUSION, AL_EAXREVERB_MAX_DIFFUSION); - ::clamp(AirAbsorptionHF, AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF); - ::clamp(ModulationTime, AL_EAXREVERB_MIN_MODULATION_TIME, AL_EAXREVERB_MAX_MODULATION_TIME); - ::clamp(ModulationDepth, AL_EAXREVERB_MIN_MODULATION_DEPTH, AL_EAXREVERB_MAX_MODULATION_DEPTH); - ::clamp(Density, AL_EAXREVERB_MIN_DENSITY, AL_EAXREVERB_MAX_DENSITY); - ::clamp(HFReference, AL_EAXREVERB_MIN_HFREFERENCE, AL_EAXREVERB_MAX_HFREFERENCE); - ::clamp(LFReference, AL_EAXREVERB_MIN_LFREFERENCE, AL_EAXREVERB_MAX_LFREFERENCE); - ::clamp(DecayHFLimit, AL_EAXREVERB_MIN_DECAY_HFLIMIT, AL_EAXREVERB_MAX_DECAY_HFLIMIT); #endif } @@ -185,20 +124,6 @@ bool CSoundRender_Environment::load(IReader* fs) if (version >= 0x0004) Environment = fs->r_u32(); - if (version >= 0x0005) - { - DecayHFLimit = fs->r_u32(); - EchoTime = fs->r_float(); - EchoDepth = fs->r_float(); - ReverbDelay = fs->r_float(); - DecayLFRatio = fs->r_float(); - ModulationTime = fs->r_float(); - ModulationDepth = fs->r_float(); - HFReference = fs->r_float(); - LFReference = fs->r_float(); - Density = fs->r_float(); - } - return true; } @@ -222,22 +147,6 @@ void CSoundRender_Environment::save(IWriter* fs) if (sdef_env_version >= 0x0004) fs->w_u32(Environment); - - if (sdef_env_version >= 0x0005) - { - fs->w_u32(DecayHFLimit); - fs->w_float(EchoTime); - fs->w_float(EchoDepth); - //fs->w_fvector3(ReflectionsPan); - fs->w_float(ReverbDelay); - //fs->w_fvector3(ReverbPan); - fs->w_float(DecayLFRatio); - fs->w_float(ModulationTime); - fs->w_float(ModulationDepth); - fs->w_float(HFReference); - fs->w_float(LFReference); - fs->w_float(Density); - } } ////////////////////////////////////////////////////////////////////////// diff --git a/src/xrSound/SoundRender_Environment.h b/src/xrSound/SoundRender_Environment.h index e2a5cd22e24..3197c1b1ddf 100644 --- a/src/xrSound/SoundRender_Environment.h +++ b/src/xrSound/SoundRender_Environment.h @@ -13,24 +13,13 @@ class XRSOUND_API CSoundRender_Environment : public CSound_environment float RoomRolloffFactor; // like DS3D flRolloffFactor but for room effect float DecayTime; // reverberation decay time at low frequencies float DecayHFRatio; // high-frequency to low-frequency decay time ratio - float DecayLFRatio; // low-frequency to high-frequency decay time ratio - int DecayHFLimit; // high- frequency decay time limit set by air absorbtion gain float Reflections; // early reflections level relative to room effect float ReflectionsDelay; // initial reflection delay time - //Fvector3 ReflectionsPan; // reflections panning xyz - float EchoTime; // delay between the original sound and echo instance - float EchoDepth; // controls the amount of echo feedback signal in the loop - //Fvector3 ReverbPan; // reverb pan xyz float Reverb; // late reverberation level relative to room effect float ReverbDelay; // late reverberation delay time relative to initial reflection float EnvironmentSize; // environment size in meters float EnvironmentDiffusion; // controls the echo density in the reverberation decay float AirAbsorptionHF; // change in level per meter at 5 kHz - float ModulationTime; // modulation time for sound blending - float ModulationDepth; // modulation depth for sound blending - float Density; // controls the coloration of the late reverb - float HFReference; // frequency at which low frequency effects are measured - float LFReference; // frequency at which high frequency effects are measured CSoundRender_Environment(); ~CSoundRender_Environment(); diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 0067ded9262..2071d36b3a4 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -4,12 +4,9 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -#if __has_include() -# include -#endif - -CSoundRender_TargetA::CSoundRender_TargetA(ALuint slot) - : pAuxSlot(slot) {} +CSoundRender_TargetA::CSoundRender_TargetA() +{ +} bool CSoundRender_TargetA::_initialize() { @@ -23,10 +20,6 @@ bool CSoundRender_TargetA::_initialize() A_CHK(alSourcef(pSource, AL_MAX_GAIN, 1.f)); A_CHK(alSourcef(pSource, AL_GAIN, cache_gain)); A_CHK(alSourcef(pSource, AL_PITCH, cache_pitch)); -#if __has_include() - if (pAuxSlot != ALuint(-1)) - A_CHK(alSource3i(pSource, AL_AUXILIARY_SEND_FILTER, pAuxSlot, 0, AL_FILTER_NULL)); -#endif return true; } Msg("! sound: OpenAL: Can't create source. Error: %s.", static_cast(alGetString(error))); diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 9ede60b3f97..73c57bcd9b7 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -10,7 +10,6 @@ class CSoundRender_TargetA : public CSoundRender_Target // OpenAL ALuint pSource{}; ALuint pBuffers[sdef_target_count]{}; - ALuint pAuxSlot; // EFX float cache_gain{}; float cache_pitch{ 1.0f }; @@ -20,7 +19,7 @@ class CSoundRender_TargetA : public CSoundRender_Target void submit_all_buffers() const; public: - CSoundRender_TargetA(ALuint slot); + CSoundRender_TargetA(); bool _initialize() override; void _destroy() override; diff --git a/src/xrSound/xrSound.vcxproj b/src/xrSound/xrSound.vcxproj index 8e5163e104c..1b7f2fe4188 100644 --- a/src/xrSound/xrSound.vcxproj +++ b/src/xrSound/xrSound.vcxproj @@ -37,7 +37,6 @@ - @@ -59,7 +58,6 @@ - diff --git a/src/xrSound/xrSound.vcxproj.filters b/src/xrSound/xrSound.vcxproj.filters index e81e30def6d..04c1619480b 100644 --- a/src/xrSound/xrSound.vcxproj.filters +++ b/src/xrSound/xrSound.vcxproj.filters @@ -75,9 +75,6 @@ Effects\OpenAL - - Effects\OpenAL - Scene @@ -134,9 +131,6 @@ Effects\OpenAL - - Effects\OpenAL - Scene From 189a45187f682c7b23f393859ecd3029000522ba Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:37:38 +0500 Subject: [PATCH 394/497] xrCore/xrDebug.cpp: catch segmentation faults only on Debug (fixes #1666) This is a "fix" for Windows, but I wonder how it will change the game in the Linux/etc. world. --- src/xrCore/xrDebug.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 219fbca32f1..3e8b37bc50a 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -893,7 +893,9 @@ void xrDebug::OnThreadSpawn() std::signal(SIGINT, nullptr); std::signal(SIGILL, +[](int signal) { handler_base("illegal instruction"); }); std::signal(SIGFPE, +[](int signal) { handler_base("floating point error"); }); +#ifdef DEBUG std::signal(SIGSEGV, +[](int signal) { handler_base("segmentation fault"); }); +#endif std::signal(SIGABRT, +[](int signal) { handler_base("application is aborting"); }); std::signal(SIGTERM, +[](int signal) { handler_base("termination with exit code 3"); }); From 3f198975efeb07d0a300eef331185e56ae5b0952 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:39:25 +0500 Subject: [PATCH 395/497] xrCore/xrDebug.cpp: remove std::terminate handler on Windows too on thread exit --- src/xrCore/xrDebug.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 3e8b37bc50a..73862c7ff0f 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -922,6 +922,7 @@ void xrDebug::OnThreadExit() std::signal(SIGSEGV, nullptr); std::signal(SIGABRT, nullptr); std::signal(SIGTERM, nullptr); + std::set_terminate(nullptr); #if defined(XR_PLATFORM_WINDOWS) std::signal(SIGABRT_COMPAT, nullptr); @@ -930,10 +931,7 @@ void xrDebug::OnThreadExit() _set_new_mode(1); _set_new_handler(nullptr); _set_purecall_handler(nullptr); -#else - std::set_terminate(nullptr); #endif - } void xrDebug::Initialize(pcstr commandLine) From ceea31656e714bf0b33415bf863734cb3bb20f26 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:47:37 +0500 Subject: [PATCH 396/497] xrSound/SoundRender_TargetA.cpp: removed too many VERIFYs --- src/xrSound/SoundRender_TargetA.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 2071d36b3a4..28f8f9ec37f 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -138,28 +138,21 @@ void CSoundRender_TargetA::update() void CSoundRender_TargetA::fill_parameters() { - [[maybe_unused]] CSoundRender_Emitter* SE = m_pEmitter; - VERIFY(SE); - + R_ASSERT1_CURE(m_pEmitter, true, { return; }); inherited::fill_parameters(); // 3D params - VERIFY2(m_pEmitter, SE->source()->file_name()); A_CHK(alSourcef(pSource, AL_REFERENCE_DISTANCE, m_pEmitter->p_source.min_distance)); - VERIFY2(m_pEmitter, SE->source()->file_name()); A_CHK(alSourcef(pSource, AL_MAX_DISTANCE, m_pEmitter->p_source.max_distance)); - VERIFY2(m_pEmitter, SE->source()->file_name()); A_CHK(alSource3f(pSource, AL_POSITION, m_pEmitter->p_source.position.x, m_pEmitter->p_source.position.y, -m_pEmitter->p_source.position.z)); - VERIFY2(m_pEmitter, SE->source()->file_name()); A_CHK(alSourcei(pSource, AL_SOURCE_RELATIVE, m_pEmitter->b2D)); A_CHK(alSourcef(pSource, AL_ROLLOFF_FACTOR, psSoundRolloff)); - VERIFY2(m_pEmitter, SE->source()->file_name()); float _gain = m_pEmitter->smooth_volume; clamp(_gain, EPS_S, 1.f); if (!fsimilar(_gain, cache_gain, 0.01f)) @@ -168,8 +161,6 @@ void CSoundRender_TargetA::fill_parameters() A_CHK(alSourcef(pSource, AL_GAIN, _gain)); } - VERIFY2(m_pEmitter, SE->source()->file_name()); - float _pitch = m_pEmitter->p_source.freq; if (!m_pEmitter->bIgnoringTimeFactor) _pitch *= psSoundTimeFactor; //--#SM+#-- Correct sound "speed" by time factor @@ -180,7 +171,6 @@ void CSoundRender_TargetA::fill_parameters() cache_pitch = _pitch; A_CHK(alSourcef(pSource, AL_PITCH, _pitch)); } - VERIFY2(m_pEmitter, SE->source()->file_name()); } size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const From 5a08d4ed4085c7e380f36459ce5608d8d0fa7182 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:49:34 +0500 Subject: [PATCH 397/497] xrSound/SoundRender_TargetA.cpp: reduce code width And fancy formatting --- src/xrSound/SoundRender_TargetA.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 28f8f9ec37f..6ffaa25c130 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -142,16 +142,14 @@ void CSoundRender_TargetA::fill_parameters() inherited::fill_parameters(); // 3D params - A_CHK(alSourcef(pSource, AL_REFERENCE_DISTANCE, m_pEmitter->p_source.min_distance)); + const auto& src = m_pEmitter->p_source; + const auto& pos = src.position; - A_CHK(alSourcef(pSource, AL_MAX_DISTANCE, m_pEmitter->p_source.max_distance)); - - A_CHK(alSource3f(pSource, AL_POSITION, m_pEmitter->p_source.position.x, m_pEmitter->p_source.position.y, - -m_pEmitter->p_source.position.z)); - - A_CHK(alSourcei(pSource, AL_SOURCE_RELATIVE, m_pEmitter->b2D)); - - A_CHK(alSourcef(pSource, AL_ROLLOFF_FACTOR, psSoundRolloff)); + A_CHK(alSourcef (pSource, AL_REFERENCE_DISTANCE, src.min_distance)); + A_CHK(alSourcef (pSource, AL_MAX_DISTANCE, src.max_distance)); + A_CHK(alSource3f(pSource, AL_POSITION, pos.x, pos.y, -pos.z)); + A_CHK(alSourcei (pSource, AL_SOURCE_RELATIVE, m_pEmitter->b2D)); + A_CHK(alSourcef (pSource, AL_ROLLOFF_FACTOR, psSoundRolloff)); float _gain = m_pEmitter->smooth_volume; clamp(_gain, EPS_S, 1.f); @@ -161,7 +159,7 @@ void CSoundRender_TargetA::fill_parameters() A_CHK(alSourcef(pSource, AL_GAIN, _gain)); } - float _pitch = m_pEmitter->p_source.freq; + float _pitch = src.freq; if (!m_pEmitter->bIgnoringTimeFactor) _pitch *= psSoundTimeFactor; //--#SM+#-- Correct sound "speed" by time factor clamp(_pitch, EPS_L, 100.f); //--#SM+#-- Increase sound frequency (speed) limit From e804e1ce23d60fec725cfbcf8b6846a55dfe7717 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 6 May 2024 22:58:52 +0500 Subject: [PATCH 398/497] xrSound/SoundRender_TargetA.h|cpp: set data format once --- src/xrSound/SoundRender_TargetA.cpp | 29 ++++++++++++++++------------- src/xrSound/SoundRender_TargetA.h | 3 +++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 6ffaa25c130..d5abfb43af2 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -41,6 +41,21 @@ void CSoundRender_TargetA::_restart() _initialize(); } +void CSoundRender_TargetA::start(CSoundRender_Emitter* E) +{ + inherited::start(E); + + const auto& info = m_pEmitter->source()->data_info(); + const bool mono = info.channels == 1; + + if (info.format == SoundFormat::Float32) + dataFormat = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; + else + dataFormat = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + + sampleRate = info.samplesPerSec; +} + void CSoundRender_TargetA::render() { inherited::render(); @@ -180,19 +195,7 @@ size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const { R_ASSERT1_CURE(m_pEmitter, true, { return; }); - - const auto& info = m_pEmitter->source()->data_info(); - const bool mono = info.channels == 1; - - ALuint format; - if (info.format == SoundFormat::Float32) - format = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; - else - { - format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; - } - - A_CHK(alBufferData(BufferID, format, data, dataSize, info.samplesPerSec)); + A_CHK(alBufferData(BufferID, dataFormat, data, dataSize, sampleRate)); } void CSoundRender_TargetA::submit_all_buffers() const diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 73c57bcd9b7..700282fd702 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -10,6 +10,8 @@ class CSoundRender_TargetA : public CSoundRender_Target // OpenAL ALuint pSource{}; ALuint pBuffers[sdef_target_count]{}; + ALuint dataFormat; + ALsizei sampleRate; float cache_gain{}; float cache_pitch{ 1.0f }; @@ -25,6 +27,7 @@ class CSoundRender_TargetA : public CSoundRender_Target void _destroy() override; void _restart() override; + void start(CSoundRender_Emitter* E) override; void render() override; void rewind() override; void stop() override; From 6fd8f7517d1d9049f7578906c503a4c9119bee25 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 7 May 2024 11:27:50 +0500 Subject: [PATCH 399/497] xrCore/Threading/ParallelFor.hpp: make it possible to use xr_parallel_for when TaskScheduler is not created yet. Addresses crash found in #1667 (merged as c2e25c972fa10a0d04ad55a8f91943d0cf229fe6), this is a supplementary change. --- src/xrCore/Threading/ParallelFor.hpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/xrCore/Threading/ParallelFor.hpp b/src/xrCore/Threading/ParallelFor.hpp index 29e13a5ab66..c3e52fd9305 100644 --- a/src/xrCore/Threading/ParallelFor.hpp +++ b/src/xrCore/Threading/ParallelFor.hpp @@ -37,7 +37,8 @@ class TaskRange public: constexpr TaskRange() = default; - constexpr TaskRange(T begin, T end) : m_begin(begin), m_end(end), m_grain(size() / TaskScheduler->GetWorkersCount()) + constexpr TaskRange(T begin, T end) : m_begin(begin), m_end(end), + m_grain(size() / (TaskScheduler ? TaskScheduler->GetWorkersCount() : std::thread::hardware_concurrency())) { if (m_grain <= 0) m_grain = 1; @@ -135,9 +136,14 @@ class ParallelForTask { TaskData taskData{ range, function }; - auto& task = TaskScheduler->AddTask(task_func, sizeof(TaskData), &taskData); + auto& task = TaskManager::AddTask(task_func, sizeof(TaskData), &taskData); if (wait) - TaskScheduler->Wait(task); + { + VERIFY2(TaskScheduler, "Task scheduler is not yet created. " + "You should explicitly state that you know this by setting 'wait' param to false."); + if (TaskScheduler) + TaskScheduler->Wait(task); + } return task; } @@ -146,9 +152,14 @@ class ParallelForTask { TaskData taskData{ range, function }; - auto& task = TaskScheduler->AddTask(callback, task_func, sizeof(TaskData), &taskData); + auto& task = TaskManager::AddTask(callback, task_func, sizeof(TaskData), &taskData); if (wait) - TaskScheduler->Wait(task); + { + VERIFY2(TaskScheduler, "Task scheduler is not yet created. " + "You should explicitly state that you know this by setting 'wait' param to false."); + if (TaskScheduler) + TaskScheduler->Wait(task); + } return task; } @@ -161,8 +172,8 @@ class ParallelForTask if (range.is_splittable()) { TaskData leftData{ TaskRange(range, SplitTaskRange()), data.function }; - TaskScheduler->AddTask(thisTask, task_func, sizeof(TaskData), &leftData); - TaskScheduler->AddTask(thisTask, task_func, sizeof(TaskData), &data); + TaskManager::AddTask(thisTask, task_func, sizeof(TaskData), &leftData); + TaskManager::AddTask(thisTask, task_func, sizeof(TaskData), &data); } else { From 885e111d74c73f35a91c91ff343c80c259b2d570 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 11 May 2024 20:10:31 +0500 Subject: [PATCH 400/497] xrCore/Threading/ParallelForEach.hpp: allow non-const ranges and use range-based for --- src/xrCore/Threading/ParallelForEach.hpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/xrCore/Threading/ParallelForEach.hpp b/src/xrCore/Threading/ParallelForEach.hpp index 87550c2bacd..ac8f91aacb4 100644 --- a/src/xrCore/Threading/ParallelForEach.hpp +++ b/src/xrCore/Threading/ParallelForEach.hpp @@ -25,12 +25,11 @@ class ParallelForEachTask template static decltype(auto) Run(Iterator begin, Iterator end, ThirdArgument thirdArgument, const Function& function) { - return xr_parallel_for(TaskRange(begin, end), thirdArgument, [&](const TaskRange& range) + return xr_parallel_for(TaskRange(begin, end), thirdArgument, [&](TaskRange& range) { - const Iterator ite = range.end(); - for (Iterator it = range.begin(); it != ite; ++it) + for (auto& it : range) { - function(*it); + function(it); } }); } @@ -39,21 +38,21 @@ class ParallelForEachTask // User can specify if he wants caller thread to wait on the task finish template -decltype(auto) xr_parallel_for_each(const Range& range, bool wait, const Function& function) +decltype(auto) xr_parallel_for_each(Range& range, bool wait, const Function& function) { return details::ParallelForEachTask::Run(std::begin(range), std::end(range), wait, function); } // Caller thread will wait on the task finish template -decltype(auto) xr_parallel_for_each(const Range& range, const Function& function) +decltype(auto) xr_parallel_for_each(Range& range, const Function& function) { return details::ParallelForEachTask::Run(std::begin(range), std::end(range), true, function); } // User has a callback, he is responsible for waiting on the task finish (due to task management system limitation) template -decltype(auto) xr_parallel_for_each(const Range& range, const Task::OnFinishFunc& callback, const Function& function) +decltype(auto) xr_parallel_for_each(Range& range, const Task::OnFinishFunc& callback, const Function& function) { return details::ParallelForEachTask::Run(std::begin(range), std::end(range), callback, function); } From 8130b50b5ece14ee3825b30e57cd76e43e8d34a1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 7 May 2024 16:05:42 +0500 Subject: [PATCH 401/497] xrEngine/EngineAPI.cpp: unify renderer libraries loading process It was split into two functions, but it's not needed. --- src/xrEngine/EngineAPI.cpp | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index ba03a6749e6..2afaa389242 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -31,7 +31,9 @@ struct RendererDesc std::array g_render_modules = {{ +#ifdef XR_PLATFORM_WINDOWS { "xrRender_R4", nullptr, nullptr }, +#endif { "xrRender_GL", nullptr, nullptr }, }}; @@ -164,7 +166,9 @@ void CEngineAPI::CreateRendererList() ZoneScoped; - const auto loadLibrary = [&](RendererDesc& desc) -> bool + int modeIndex{}; + std::mutex mutex; + const auto loadRenderer = [&](RendererDesc& desc) -> bool { auto handle = XRay::LoadModule(desc.libraryName); if (!handle->IsLoaded()) @@ -175,29 +179,14 @@ void CEngineAPI::CreateRendererList() if (!module) return false; + const auto& modes = module->ObtainSupportedModes(); // Performs HW tests, may take time + if (modes.empty()) + return false; + desc.handle = std::move(handle); desc.module = module; - return true; - }; - if (GEnv.isDedicatedServer) - { - R_ASSERT2(loadLibrary(g_render_modules[0]), "Dedicated server needs xrRender to work"); - } - else - { - std::for_each(std::begin(g_render_modules), std::end(g_render_modules), loadLibrary); - } - - std::mutex mutex; - - int modeIndex{}; - const auto obtainModes = [&](const RendererDesc& desc) - { - if (!desc.module) - return; - - const auto& modes = desc.module->ObtainSupportedModes(); + std::lock_guard guard{ mutex }; for (pcstr mode : modes) { const auto it = std::find_if(renderModes.begin(), renderModes.end(), [&](auto& pair) @@ -211,13 +200,25 @@ void CEngineAPI::CreateRendererList() mode = temp; } shared_str copiedMode = mode; - std::lock_guard guard{ mutex }; renderModes[copiedMode] = desc.module; VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! } + + return true; }; - xr_parallel_for_each(g_render_modules, obtainModes); + if (GEnv.isDedicatedServer) + { + R_ASSERT2(loadRenderer(g_render_modules[0]), "Dedicated server needs xrRender to work"); + } + else + { +#ifdef XR_PLATFORM_WINDOWS + xr_parallel_for_each(g_render_modules, loadRenderer); +#else + std::for_each(std::begin(g_render_modules), std::end(g_render_modules), loadRenderer); +#endif + } auto& modes = VidQualityToken; Msg("Available render modes[%d]:", modes.size()); From 982685adf742d33945304c97ffdc6a4a6439bc20 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 7 May 2024 16:33:21 +0500 Subject: [PATCH 402/497] Manually specify renderer modes IDs during loading renderer modules OpenGL will now mimic R3 on non-Windows --- src/Layers/xrRenderPC_GL/xrRender_GL.cpp | 45 ++++++++++++++++++------ src/Layers/xrRenderPC_R4/xrRender_R4.cpp | 34 ++++++++---------- src/xrEngine/EngineAPI.cpp | 16 ++++----- src/xrEngine/EngineAPI.h | 2 +- 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp index 698475ef628..d1000a2d04d 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp @@ -4,11 +4,15 @@ #include "Layers/xrRender/dxDebugRender.h" #include "Layers/xrRender/D3DUtils.h" -constexpr pcstr RENDERER_RGL_MODE = "renderer_rgl"; +constexpr pcstr RENDERER_R2_MODE = "renderer_r2"; // id 2 +constexpr pcstr RENDERER_R2_5_MODE = "renderer_r2.5"; // id 3 +constexpr pcstr RENDERER_R3_MODE = "renderer_r3"; // id 4 +constexpr pcstr RENDERER_R4_MODE = "renderer_r4"; // id 5 +constexpr pcstr RENDERER_RGL_MODE = "renderer_rgl"; // id 6 class RGLRendererModule final : public RendererModule { - xr_vector modes; + xr_vector> modes; public: bool CheckCanAddMode() const @@ -21,13 +25,20 @@ class RGLRendererModule final : public RendererModule return xrRender_test_hw(); } - const xr_vector& ObtainSupportedModes() override + const xr_vector>& ObtainSupportedModes() override { ZoneScoped; if (CheckCanAddMode()) { - modes.emplace_back(RENDERER_RGL_MODE); +#ifdef XR_PLATFORM_WINDOWS + modes.emplace_back(RENDERER_RGL_MODE, 6); +#else + //modes.emplace_back(RENDERER_R2_MODE, 2); + //modes.emplace_back(RENDERER_R2_5_MODE, 3); + modes.emplace_back(RENDERER_R3_MODE, 4); + //modes.emplace_back(RENDERER_R4_MODE, 5); +#endif } return modes; } @@ -43,19 +54,31 @@ class RGLRendererModule final : public RendererModule return true; } - void CheckModeConsistency(pcstr mode) const - { - R_ASSERT3(0 == xr_strcmp(mode, RENDERER_RGL_MODE), - "Wrong mode passed to xrRender_GL", mode); - } - void SetupEnv(pcstr mode) override { ZoneScoped; - CheckModeConsistency(mode); ps_r2_sun_static = false; ps_r2_advanced_pp = true; + + switch (strhash(mode)) + { + //case strhash(RENDERER_R2A_MODE): + // //ps_r2_sun_static = true; + // [[fallthrough]]; + + case strhash(RENDERER_R2_MODE): + ps_r2_advanced_pp = false; + break; + + case strhash(RENDERER_R2_5_MODE): + case strhash(RENDERER_R3_MODE): + case strhash(RENDERER_R4_MODE): + case strhash(RENDERER_RGL_MODE): + ps_r2_advanced_pp = true; + break; + } + GEnv.Render = &RImplementation; GEnv.RenderFactory = &RenderFactoryImpl; GEnv.DU = &DUImpl; diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index 4ba5a90d49a..4d07c2efbb1 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -5,16 +5,15 @@ #include "Layers/xrRender/dxDebugRender.h" #include "Layers/xrRender/D3DUtils.h" -constexpr pcstr RENDERER_R1_MODE = "renderer_r1"; -constexpr pcstr RENDERER_R2A_MODE = "renderer_r2a"; -constexpr pcstr RENDERER_R2_MODE = "renderer_r2"; -constexpr pcstr RENDERER_R2_5_MODE = "renderer_r2.5"; -constexpr pcstr RENDERER_R3_MODE = "renderer_r3"; -constexpr pcstr RENDERER_R4_MODE = "renderer_r4"; +constexpr pcstr RENDERER_R2A_MODE = "renderer_r2a"; // id 1 +constexpr pcstr RENDERER_R2_MODE = "renderer_r2"; // id 2 +constexpr pcstr RENDERER_R2_5_MODE = "renderer_r2.5"; // id 3 +constexpr pcstr RENDERER_R3_MODE = "renderer_r3"; // id 4 +constexpr pcstr RENDERER_R4_MODE = "renderer_r4"; // id 5 class R4RendererModule final : public RendererModule { - xr_vector modes; + xr_vector> modes; public: BOOL CheckCanAddMode() const @@ -27,28 +26,25 @@ class R4RendererModule final : public RendererModule return xrRender_test_hw(); } - const xr_vector& ObtainSupportedModes() override + const xr_vector>& ObtainSupportedModes() override { ZoneScoped; const BOOL result = CheckCanAddMode(); if (result != FALSE) { - // Lie to game scripts to make options work correctly - // (so that we don't need to modify scripts) - modes.emplace_back(RENDERER_R1_MODE); - modes.emplace_back(RENDERER_R2A_MODE); - modes.emplace_back(RENDERER_R2_MODE); - modes.emplace_back(RENDERER_R2_5_MODE); + //modes.emplace_back(RENDERER_R2A_MODE, 1); + modes.emplace_back(RENDERER_R2_MODE, 2); + modes.emplace_back(RENDERER_R2_5_MODE, 3); } switch (result) { case TRUE: - modes.emplace_back(RENDERER_R3_MODE); + modes.emplace_back(RENDERER_R3_MODE, 4); break; case TRUE+TRUE: // XXX: remove hack - modes.emplace_back(RENDERER_R3_MODE); // don't optimize this switch with fallthrough, because - modes.emplace_back(RENDERER_R4_MODE); // order matters: R3 should be first, R4 should be second. + modes.emplace_back(RENDERER_R3_MODE, 4); // don't optimize this switch with fallthrough, because + modes.emplace_back(RENDERER_R4_MODE, 5); // order matters: R3 should be first, R4 should be second. } return modes; } @@ -72,13 +68,13 @@ class R4RendererModule final : public RendererModule switch (strhash(mode)) { - case strhash(RENDERER_R1_MODE): case strhash(RENDERER_R2A_MODE): // vanilla shaders fail to compile with static sun enabled - //ps_r2_sun_static = true; + ps_r2_sun_static = true; [[fallthrough]]; case strhash(RENDERER_R2_MODE): + HW.DX10Only = true; ps_r2_advanced_pp = false; break; diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 2afaa389242..3c8a4afd6b3 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -166,7 +166,6 @@ void CEngineAPI::CreateRendererList() ZoneScoped; - int modeIndex{}; std::mutex mutex; const auto loadRenderer = [&](RendererDesc& desc) -> bool { @@ -187,21 +186,18 @@ void CEngineAPI::CreateRendererList() desc.module = module; std::lock_guard guard{ mutex }; - for (pcstr mode : modes) + for (auto [mode, modeIndex] : modes) { - const auto it = std::find_if(renderModes.begin(), renderModes.end(), [&](auto& pair) - { - return 0 == xr_strcmp(mode, pair.first.c_str()); - }); - string256 temp; + const auto it = renderModes.find(mode); if (it != renderModes.end()) { - xr_sprintf(temp, "%s__dup%d", mode, modeIndex); - mode = temp; + VERIFY3(false, "Renderer mode duplicate. Skipping.", mode); + continue; } + // mode string will be freed after library unloading, copy. shared_str copiedMode = mode; renderModes[copiedMode] = desc.module; - VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex++); // It's important to have postfix increment! + VidQualityToken.emplace_back(copiedMode.c_str(), modeIndex); } return true; diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index 790a72b1455..d3e6416a9a5 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -52,7 +52,7 @@ class XR_NOVTABLE RendererModule { public: virtual ~RendererModule() = default; - virtual const xr_vector& ObtainSupportedModes() = 0; + virtual const xr_vector>& ObtainSupportedModes() = 0; virtual bool CheckGameRequirements() = 0; virtual void SetupEnv(pcstr mode) = 0; virtual void ClearEnv() = 0; From b40433b19278aeb42bc3f20037e999d57bef44eb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 11 May 2024 20:45:47 +0500 Subject: [PATCH 403/497] xrSound: moved sound streaming code to CSoundRender_Emitter --- src/xrSound/SoundRender_Core_Processor.cpp | 8 +-- src/xrSound/SoundRender_Emitter.cpp | 54 +++++++++++++++ src/xrSound/SoundRender_Emitter.h | 23 ++++++- src/xrSound/SoundRender_Emitter_FSM.cpp | 21 +++++- src/xrSound/SoundRender_Emitter_StartStop.cpp | 5 ++ src/xrSound/SoundRender_Target.cpp | 67 ------------------- src/xrSound/SoundRender_Target.h | 20 +----- src/xrSound/SoundRender_TargetA.cpp | 28 ++------ src/xrSound/SoundRender_TargetA.h | 3 +- 9 files changed, 110 insertions(+), 119 deletions(-) diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 91095ee1085..98db8840259 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -89,13 +89,9 @@ void CSoundRender_Core::render() for (CSoundRender_Target* T : s_targets) { - if (T->get_emitter()) + if (CSoundRender_Emitter* emitter = T->get_emitter()) { - T->fill_parameters(); - if (T->get_Rendering()) - T->update(); - else - T->render(); + emitter->render(); } } diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 1207f472721..048ee102a98 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -5,6 +5,8 @@ #include "SoundRender_Scene.h" #include "SoundRender_Source.h" +#include "xrCore/Threading/TaskManager.hpp" + extern u32 psSoundModel; extern float psSoundVEffects; @@ -47,6 +49,7 @@ CSoundRender_Emitter::~CSoundRender_Emitter() { // try to release dependencies, events, for example Event_ReleaseOwner(); + wait_prefill(); } ////////////////////////////////////////////////////////////////////// @@ -226,6 +229,57 @@ void CSoundRender_Emitter::fill_block(void* ptr, u32 size) } } +std::pair CSoundRender_Emitter::obtain_block() +{ + wait_prefill(); + const std::pair result = { temp_buf[current_block].data(), temp_buf[current_block].size() }; + ++current_block; + if (current_block >= sdef_target_count) + current_block = 0; + --filled_blocks; + return std::move(result); +} + +void CSoundRender_Emitter::fill_all_blocks() +{ + current_block = 0; + for (size_t i = 0; i < sdef_target_count; ++i) + fill_block(temp_buf[i].data(), temp_buf[i].size()); + filled_blocks = sdef_target_count; +} + +void CSoundRender_Emitter::prefill_blocks(Task&, void*) +{ + size_t next_block_to_fill = (current_block + filled_blocks) % sdef_target_count; + + while (filled_blocks < sdef_target_count) + { + auto& block = temp_buf[next_block_to_fill]; + + fill_block(block.data(), block.size()); + + next_block_to_fill = (next_block_to_fill + 1) % sdef_target_count; + filled_blocks++; + } + + prefill_task.store(nullptr, std::memory_order_release); +} + +void CSoundRender_Emitter::dispatch_prefill() +{ + wait_prefill(); + if (filled_blocks >= sdef_target_count) + return; + const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Emitter::prefill_blocks }); + prefill_task.store(task, std::memory_order_release); +} + +void CSoundRender_Emitter::wait_prefill() const +{ + if (const auto task = prefill_task.load(std::memory_order_acquire)) + TaskScheduler->Wait(*task); +} + u32 CSoundRender_Emitter::get_bytes_total() const { return owner_data->dwBytesTotal; diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 0b97158621f..bb1646c0c03 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -6,6 +6,8 @@ #include "SoundRender_Environment.h" #include "SoundRender_Scene.h" +class Task; + class CSoundRender_Emitter final : public CSound_emitter { public: @@ -74,6 +76,22 @@ class CSoundRender_Emitter final : public CSound_emitter void set_cursor(u32 p); void move_cursor(int offset); +private: + xr_vector temp_buf[sdef_target_count]; + std::atomic prefill_task{}; + + size_t current_block{}; + int filled_blocks{}; + + void fill_block(void* ptr, u32 size); + void fill_data(void* dest, u32 offset, u32 size) const; + + void fill_all_blocks(); + void prefill_blocks(Task&, void*); + void dispatch_prefill(); + + void wait_prefill() const; + public: void Event_Propagade(); void Event_ReleaseOwner(); @@ -102,13 +120,14 @@ class CSoundRender_Emitter final : public CSound_emitter void set_priority(float p) override { priority_scale = p; } void set_time(float t) override; //--#SM+#-- const CSound_params* get_params() override { return &p_source; } - void fill_block(void* ptr, u32 size); - void fill_data(void* dest, u32 offset, u32 size) const; + + std::pair obtain_block(); float priority() const; void start(const ref_sound& _owner, u32 flags, float delay); void cancel(); // manager forces out of rendering void update(float time, float dt); + void render(); bool update_culling(float dt); void update_environment(float dt); void rewind(); diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index a26a0035279..98c49a13bf0 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -30,8 +30,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) if (bRewind) { - if (target) - target->wait_prefill(); + wait_prefill(); const float time = bIgnoringTimeFactor ? SoundRender->TimerPersistent.GetElapsed_sec() : SoundRender->Timer.GetElapsed_sec(); const float diff = time - fTimeStarted; @@ -41,7 +40,11 @@ void CSoundRender_Emitter::update(float fTime, float dt) set_cursor(0); if (target) + { + fill_all_blocks(); target->rewind(); + dispatch_prefill(); + } bRewind = FALSE; } @@ -72,6 +75,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) m_current_state = stPlaying; set_cursor(0); SoundRender->i_start(this); + dispatch_prefill(); } else m_current_state = stSimulating; @@ -100,6 +104,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) m_current_state = stPlayingLooped; set_cursor(0); SoundRender->i_start(this); + dispatch_prefill(); } else m_current_state = stSimulatingLooped; @@ -165,6 +170,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) set_cursor (ptr); */ SoundRender->i_start(this); + dispatch_prefill(); } } break; @@ -204,6 +210,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) set_cursor(ptr); SoundRender->i_start(this); + dispatch_prefill(); } break; } @@ -362,3 +369,13 @@ void CSoundRender_Emitter::update_environment(float dt) e_target = *(CSoundRender_Environment*)scene->get_environment(p_source.position); e_current.lerp(e_current, e_target, dt); } + +void CSoundRender_Emitter::render() +{ + target->fill_parameters(); + if (target->get_Rendering()) + target->update(); + else + target->render(); + dispatch_prefill(); +} diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index 44901f87070..692d185420e 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -36,6 +36,10 @@ void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay } bStopping = FALSE; bRewind = FALSE; + + // Calc storage + for (auto& buf : temp_buf) + buf.resize(source()->data_info().bytesPerBuffer); } void CSoundRender_Emitter::i_stop() @@ -51,6 +55,7 @@ void CSoundRender_Emitter::i_stop() owner_data = NULL; } m_current_state = stStopped; + wait_prefill(); } void CSoundRender_Emitter::stop(bool isDeffered) diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index a760f5db491..5b000c906ba 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -1,20 +1,8 @@ #include "stdafx.h" #include "SoundRender_Target.h" -#include "SoundRender_Core.h" #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -#include "xrCore/Threading/TaskManager.hpp" - -CSoundRender_Target::CSoundRender_Target() -{ - buffers_to_prefill.reserve(sdef_target_count); -} - -void CSoundRender_Target::_destroy() -{ - wait_prefill(); -} void CSoundRender_Target::start(CSoundRender_Emitter* E) { @@ -28,24 +16,16 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) priority = E->priority(); rendering = false; //m_pEmitter->source()->attach(); - - // Calc storage - for (auto& buf : temp_buf) - buf.resize(E->source()->data_info().bytesPerBuffer); - - dispatch_prefill_all(); } void CSoundRender_Target::render() { VERIFY(!rendering); rendering = true; - wait_prefill(); } void CSoundRender_Target::stop() { - wait_prefill(); m_pEmitter->source()->detach(); m_pEmitter = nullptr; rendering = false; @@ -60,7 +40,6 @@ void CSoundRender_Target::rewind() void CSoundRender_Target::update() { R_ASSERT1_CURE(m_pEmitter, true, { return; }); - wait_prefill(); } void CSoundRender_Target::fill_parameters() @@ -69,49 +48,3 @@ void CSoundRender_Target::fill_parameters() //if (pEmitter->b2D) // pEmitter->set_position(SoundRender->listener_position()); } - -void CSoundRender_Target::fill_block(size_t idx) -{ - R_ASSERT1_CURE(m_pEmitter, true, { return; }); - m_pEmitter->fill_block(temp_buf[idx].data(), temp_buf[idx].size()); -} - -void CSoundRender_Target::fill_all_blocks() -{ - for (size_t i = 0; i < sdef_target_count; ++i) - fill_block(i); -} - -void CSoundRender_Target::prefill_blocks(Task&, void*) -{ - for (const size_t idx : buffers_to_prefill) - fill_block(idx); - buffers_to_prefill.clear(); - prefill_task.store(nullptr, std::memory_order_release); -} - -void CSoundRender_Target::prefill_all_blocks(Task&, void*) -{ - fill_all_blocks(); - prefill_task.store(nullptr, std::memory_order_release); -} - -void CSoundRender_Target::wait_prefill() const -{ - if (const auto task = prefill_task.load(std::memory_order_relaxed)) - TaskScheduler->Wait(*task); -} - -void CSoundRender_Target::dispatch_prefill() -{ - wait_prefill(); - const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Target::prefill_blocks }); - prefill_task.store(task, std::memory_order_release); -} - -void CSoundRender_Target::dispatch_prefill_all() -{ - wait_prefill(); - const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Target::prefill_all_blocks }); - prefill_task.store(task, std::memory_order_release); -} diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index c6c141eaf87..14d1d89d86d 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -2,8 +2,6 @@ #include "SoundRender.h" -class Task; - class CSoundRender_Target { protected: @@ -11,27 +9,15 @@ class CSoundRender_Target bool rendering{}; float priority{ -1 }; - xr_vector temp_buf[sdef_target_count]; - void fill_block(size_t idx); - void fill_all_blocks(); - - xr_vector buffers_to_prefill; - void prefill_blocks(Task&, void*); - void prefill_all_blocks(Task&, void*); - - std::atomic prefill_task{}; - void dispatch_prefill(); - void dispatch_prefill_all(); - public: - CSoundRender_Target(); + CSoundRender_Target() = default; virtual ~CSoundRender_Target() = default; CSoundRender_Emitter* get_emitter() const { return m_pEmitter; } bool get_Rendering() const { return rendering; } virtual bool _initialize() = 0; - virtual void _destroy(); + virtual void _destroy() = 0; virtual void _restart() = 0; virtual void start(CSoundRender_Emitter* E); @@ -43,6 +29,4 @@ class CSoundRender_Target ICF auto get_priority() const { return priority; } ICF void set_priority(const float p) { priority = p; } - - void wait_prefill() const; }; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index d5abfb43af2..54ee98d9ed6 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -28,7 +28,6 @@ bool CSoundRender_TargetA::_initialize() void CSoundRender_TargetA::_destroy() { - CSoundRender_Target::_destroy(); // clean up target if (alIsSource(pSource)) alDeleteSources(1, &pSource); @@ -64,8 +63,6 @@ void CSoundRender_TargetA::render() A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); - - dispatch_prefill_all(); } void CSoundRender_TargetA::stop() @@ -86,13 +83,10 @@ void CSoundRender_TargetA::rewind() A_CHK(alSourceStop(pSource)); A_CHK(alSourcei(pSource, AL_BUFFER, 0)); - fill_all_blocks(); submit_all_buffers(); A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); A_CHK(alSourcePlay(pSource)); - - dispatch_prefill_all(); } void CSoundRender_TargetA::update() @@ -116,8 +110,7 @@ void CSoundRender_TargetA::update() ALuint BufferID; A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); - const auto id = get_block_id(BufferID); - submit_buffer(BufferID, temp_buf[id].data(), temp_buf[id].size()); + submit_buffer(BufferID); A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; @@ -126,12 +119,8 @@ void CSoundRender_TargetA::update() Msg("! %s:: buffering data failed (0x%d)", __FUNCTION__, error); return; } - buffers_to_prefill.emplace_back(id); } - if (!buffers_to_prefill.empty()) - dispatch_prefill(); - /* Make sure the source hasn't underrun */ if (state != AL_PLAYING && state != AL_PAUSED) { @@ -186,20 +175,15 @@ void CSoundRender_TargetA::fill_parameters() } } -size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const -{ - const auto it = std::find(std::begin(pBuffers), std::end(pBuffers), BufferID); - return it - std::begin(pBuffers); -} - -void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const +void CSoundRender_TargetA::submit_buffer(ALuint BufferID) const { R_ASSERT1_CURE(m_pEmitter, true, { return; }); - A_CHK(alBufferData(BufferID, dataFormat, data, dataSize, sampleRate)); + const auto [data, dataSize] = m_pEmitter->obtain_block(); + A_CHK(alBufferData(BufferID, dataFormat, data, static_cast(dataSize), sampleRate)); } void CSoundRender_TargetA::submit_all_buffers() const { - for (size_t i = 0; i < sdef_target_count; ++i) - submit_buffer(pBuffers[i], temp_buf[i].data(), temp_buf[i].size()); + for (const auto buffer : pBuffers) + submit_buffer(buffer); } diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 700282fd702..78910ff3eee 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -16,8 +16,7 @@ class CSoundRender_TargetA : public CSoundRender_Target float cache_gain{}; float cache_pitch{ 1.0f }; - size_t get_block_id(ALuint BufferID) const; - void submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const; + void submit_buffer(ALuint BufferID) const; void submit_all_buffers() const; public: From 298599a59909b4ece8fce5d260789e5cee296c6c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 12 May 2024 15:05:45 +0500 Subject: [PATCH 404/497] Fix engine startup on Linux and macOS (closes #1670) --- src/xrEngine/x_ray.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index f0f7a93c190..ee1ee986ca3 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -255,10 +255,12 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Engine.Sound.CreateDevicesList(); }); +#ifdef XR_PLATFORM_WINDOWS const auto& createRendererList = TaskManager::AddTask([](Task&, void*) { Engine.External.CreateRendererList(); }); +#endif pcstr fsltx = "-fsltx "; string_path fsgame = ""; @@ -283,7 +285,11 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) TaskScheduler->Wait(inputTask); InitConsole(); +#ifdef XR_PLATFORM_WINDOWS TaskScheduler->Wait(createRendererList); +#else + Engine.External.CreateRendererList(); +#endif Engine.Initialize(game); Device.Initialize(); From a2d3889d00ca393448046fdb13fd9ef12a0b8620 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 13 May 2024 02:57:28 +0500 Subject: [PATCH 405/497] xrEngine/device.cpp: process system events while waiting for tasks Fixes process deadlock when other thread throws an ASSERT or VERIFY --- src/xrEngine/device.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index f9dfad57805..9bcfb2f4342 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -320,7 +320,10 @@ void CRenderDevice::ProcessFrame() DoRender(); while (!secondaryTasksExecuted.load(std::memory_order_acquire)) + { + SDL_PumpEvents(); TaskScheduler->ExecuteOneTask(); + } secondaryTasksExecuted.store(false, std::memory_order_relaxed); From 3c8f2a0cea9f42f65d8d4dc526c140a4411ac632 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 13 May 2024 03:19:31 +0500 Subject: [PATCH 406/497] Fixed game crashes due to invalid vertex IDs --- src/xrAICore/Navigation/graph_engine_inline.h | 6 ++++++ src/xrGame/CustomMonster.cpp | 15 ++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/xrAICore/Navigation/graph_engine_inline.h b/src/xrAICore/Navigation/graph_engine_inline.h index 57f72acbd1b..df93efe8b7f 100644 --- a/src/xrAICore/Navigation/graph_engine_inline.h +++ b/src/xrAICore/Navigation/graph_engine_inline.h @@ -37,6 +37,12 @@ template inline bool CGraphEngine::search(const _Graph& graph, const _index_type& start_node, const _index_type& dest_node, xr_vector<_index_type>* node_path, const _Parameters& parameters) { + const auto& level_graph = GEnv.AISpace->level_graph(); + const bool vertices_valid = level_graph.valid_vertex_id(start_node) && level_graph.valid_vertex_id(dest_node); + VERIFY2(vertices_valid, make_string("start_node: %u, dest_node: %u", start_node, dest_node)); + if (!vertices_valid) + return false; + //ScopeLock scope(&m_lock); START_PROFILE("graph_engine") START_PROFILE("graph_engine/search") diff --git a/src/xrGame/CustomMonster.cpp b/src/xrGame/CustomMonster.cpp index f6af388ef93..65bb52fc1f9 100644 --- a/src/xrGame/CustomMonster.cpp +++ b/src/xrGame/CustomMonster.cpp @@ -745,11 +745,16 @@ bool CCustomMonster::net_Spawn(CSE_Abstract* DC) else { Fvector dest_position; - u32 level_vertex_id; - level_vertex_id = movement().restrictions().accessible_nearest( - ai().level_graph().vertex_position(ai_location().level_vertex_id()), dest_position); - movement().set_level_dest_vertex(level_vertex_id); - movement().detail().set_dest_position(dest_position); + const Fvector vertex_pos = ai().level_graph().vertex_position(ai_location().level_vertex_id()); + const u32 level_vertex_id = movement().restrictions().accessible_nearest(vertex_pos, dest_position); + + const bool vertex_id_is_valid = ai().game_graph().valid_vertex_id(level_vertex_id); + VERIFY(vertex_id_is_valid); + if (vertex_id_is_valid) + { + movement().set_level_dest_vertex(level_vertex_id); + movement().detail().set_dest_position(dest_position); + } } } From 73338b342954b823c17196f19378682b5f14a6ab Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 13 May 2024 03:22:43 +0500 Subject: [PATCH 407/497] xrSound: wait for prefill task before stopping sound playback Fixes "SOUND: Invalid emitter state" crash. --- src/xrSound/SoundRender_Emitter_StartStop.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index 692d185420e..e066d6a23f2 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -105,6 +105,7 @@ void CSoundRender_Emitter::cancel() void CSoundRender_Emitter::stop_target() { + wait_prefill(); R_ASSERT1_CURE(target, true, { return; }); target->stop(); target = nullptr; From 8a88774bc7a6daeff37cf363044345d6faee0562 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 10:56:47 +0500 Subject: [PATCH 408/497] xrCore/xrDebug.cpp: don't set any debug handlers when ASAN is enabled --- src/xrCore/xrDebug.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/xrCore/xrDebug.cpp b/src/xrCore/xrDebug.cpp index 73862c7ff0f..e6491c86e75 100644 --- a/src/xrCore/xrDebug.cpp +++ b/src/xrCore/xrDebug.cpp @@ -890,32 +890,36 @@ static void invalid_parameter_handler(const wchar_t* expression, const wchar_t* void xrDebug::OnThreadSpawn() { +#ifndef __SANITIZE_ADDRESS__ std::signal(SIGINT, nullptr); std::signal(SIGILL, +[](int signal) { handler_base("illegal instruction"); }); std::signal(SIGFPE, +[](int signal) { handler_base("floating point error"); }); -#ifdef DEBUG +# ifdef DEBUG std::signal(SIGSEGV, +[](int signal) { handler_base("segmentation fault"); }); -#endif +# endif std::signal(SIGABRT, +[](int signal) { handler_base("application is aborting"); }); std::signal(SIGTERM, +[](int signal) { handler_base("termination with exit code 3"); }); -#if defined(XR_PLATFORM_WINDOWS) -#ifdef USE_BUG_TRAP - BT_SetTerminate(); -#endif +# if defined(XR_PLATFORM_WINDOWS) std::signal(SIGABRT_COMPAT, +[](int signal) { handler_base("application is aborting"); }); _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); _set_invalid_parameter_handler(&invalid_parameter_handler); _set_new_mode(1); _set_new_handler(&out_of_memory_handler); _set_purecall_handler(+[] { handler_base("pure virtual function call"); }); -#else +# endif + +# ifdef USE_BUG_TRAP + BT_SetTerminate(); +# else std::set_terminate(xr_terminate); +# endif #endif } void xrDebug::OnThreadExit() { +#ifndef __SANITIZE_ADDRESS__ std::signal(SIGINT, nullptr); std::signal(SIGILL, nullptr); std::signal(SIGFPE, nullptr); @@ -924,13 +928,14 @@ void xrDebug::OnThreadExit() std::signal(SIGTERM, nullptr); std::set_terminate(nullptr); -#if defined(XR_PLATFORM_WINDOWS) +# if defined(XR_PLATFORM_WINDOWS) std::signal(SIGABRT_COMPAT, nullptr); _set_abort_behavior(0, 0); _set_invalid_parameter_handler(nullptr); _set_new_mode(1); _set_new_handler(nullptr); _set_purecall_handler(nullptr); +# endif #endif } From 068226f68e54e7415377510f5182b470b3e59d08 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 18:37:24 +0500 Subject: [PATCH 409/497] xr_3da/entry_point.cpp: for sure, don't look at this commit. Terminate engine process on shutdown to hide crashes on exit that make the process hang. This is bad, but whatever, for now we should make it stable for players. After memory profiling and fixing the problems, we can remove that. --- src/xr_3da/entry_point.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xr_3da/entry_point.cpp b/src/xr_3da/entry_point.cpp index 0b81b8380c3..929483942bd 100644 --- a/src/xr_3da/entry_point.cpp +++ b/src/xr_3da/entry_point.cpp @@ -50,6 +50,9 @@ int APIENTRY WinMain(HINSTANCE inst, HINSTANCE prevInst, char* commandLine, int _resetstkoflw(); FATAL("stack overflow"); } + if (!xrDebug::DebuggerIsPresent()) + std::terminate(); // XXX: temporary to hide crashes on shutdown that make engine process hang + return result; } #elif defined(XR_PLATFORM_LINUX) || defined(XR_PLATFORM_BSD) || defined(XR_PLATFORM_APPLE) From 400539736e4c218bfd56f15ff4968745310463c8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 21:48:24 +0500 Subject: [PATCH 410/497] Optimize CPU resources consumption in TaskScheduler --- src/xrCore/Threading/TaskManager.cpp | 108 +++++---------------------- src/xrCore/Threading/TaskManager.hpp | 1 + 2 files changed, 21 insertions(+), 88 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 1de8f519b69..d67a76936f9 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -41,8 +41,6 @@ xr_unique_ptr TaskScheduler; static constexpr size_t OTHER_THREADS_COUNT = 2; // Primary and Secondary thread -static u32 ttapi_dwFastIter = 0; - class TaskStorageSize { template // XXX: remove Dummy workaround when gcc will finally match the standard @@ -140,54 +138,11 @@ struct TaskWorkerStats class TaskWorker : public TaskQueue, public TaskWorkerStats { public: - Event event; + std::mutex mutex; fast_lc16 random{ this }; size_t id { size_t(-1) }; - std::atomic_bool sleeps{}; - - void WakeUpIfNeeded() - { - if (!empty() && sleeps.load(std::memory_order_relaxed)) - event.Set(); // Wake up, we have work to do! - } } static thread_local s_tl_worker; -class ThreadPriorityHelper -{ - Threading::priority_class m_priority; - -public: - ThreadPriorityHelper() - : m_priority(Threading::GetCurrentProcessPriorityClass()) - { - Threading::SetCurrentProcessPriorityClass(Threading::priority_class::realtime); - } - - ~ThreadPriorityHelper() - { - Threading::SetCurrentProcessPriorityClass(m_priority); - } -}; - -// Get fast spin-loop timings -void CalcIterations() -{ - [[maybe_unused]] ThreadPriorityHelper priority; - - volatile bool dummy = false; - const u64 frequency = CPU::qpc_freq; - const u32 iterations = 100000000; // approximately 1 second - const u64 start = CPU::QPC(); - for (u32 i = 0; i < iterations; ++i) - { - if (dummy) - break; - _mm_pause(); - } - const u64 end = CPU::QPC(); - // We want 1/50000 (0.02ms) fast spin-loop - ttapi_dwFastIter = u32((iterations * frequency) / ((end - start) * 50000)); -} TaskManager::TaskManager() { @@ -199,7 +154,6 @@ TaskManager::TaskManager() void TaskManager::SpawnThreads() { ZoneScoped; - CalcIterations(); const u32 threads = workers.capacity() - OTHER_THREADS_COUNT; workerThreads.reserve(threads); @@ -222,11 +176,7 @@ TaskManager::~TaskManager() } UnregisterThisThreadAsWorker(); - { - std::lock_guard guard{ workersLock }; - for (TaskWorker* worker : workers) - worker->event.Set(); - } + newWorkArrived.notify_all(); for (auto& thread : workerThreads) { if (thread.joinable()) @@ -265,7 +215,6 @@ void TaskManager::UnregisterThisThreadAsWorker() void TaskManager::SetThreadStatus(bool active) { - s_tl_worker.sleeps.store(!active, std::memory_order_relaxed); if (active) activeWorkersCount.fetch_add(1, std::memory_order_relaxed); else @@ -277,50 +226,27 @@ void TaskManager::TaskWorkerStart() RegisterThisThreadAsWorker(); SetThreadStatus(true); - const u32 fastIterations = ttapi_dwFastIter; - - u32 iteration = 0; while (true) - { - get_task: { if (shouldStop.load(std::memory_order_consume)) break; - if (shouldPause.load(std::memory_order_consume)) - goto wait; - - Task* task = s_tl_worker.pop(); - if (!task) - task = TryToSteal(); - if (task) - { - ExecuteTask(*task); - iteration = 0; - goto get_task; - } - } - //count_spins: - { - ++iteration; - if (iteration < fastIterations) + if (!shouldPause.load(std::memory_order_consume)) { - _mm_pause(); - goto get_task; + if (ExecuteOneTask()) + continue; } - } - wait: - { + SetThreadStatus(false); - do { - s_tl_worker.event.Wait(1); - } while (shouldPause.load(std::memory_order_consume)); + std::unique_lock lck(s_tl_worker.mutex); + newWorkArrived.wait(lck, [&] + { + // spurious unlocks allowed + return !shouldPause.load(std::memory_order_consume); + }); + } SetThreadStatus(true); - - iteration = 0; - goto get_task; - } } // while (true) SetThreadStatus(false); @@ -348,7 +274,8 @@ Task* TaskManager::TryToSteal() const continue; if (auto* task = other->steal()) { - other->WakeUpIfNeeded(); + if (!other->empty()) + newWorkArrived.notify_all(); return task; } --steal_attempts; @@ -391,6 +318,7 @@ void TaskManager::IncrementTaskJobsCounter(Task& parent) void TaskManager::PushTask(Task& task) { s_tl_worker.push(&task); + newWorkArrived.notify_one(); ++s_tl_worker.pushedTasks; } @@ -424,6 +352,10 @@ void TaskManager::WaitForChildren(const Task& task) const bool TaskManager::ExecuteOneTask() const { Task* task = s_tl_worker.pop(); + + if (!task) + task = workers[0]->steal(); + if (!task) task = TryToSteal(); diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index c210c8934b7..fd294326df7 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -29,6 +29,7 @@ class XRCORE_API TaskManager final xr_vector workerThreads; std::mutex workersLock; + inline static std::condition_variable newWorkArrived; std::atomic_size_t activeWorkersCount{}; std::atomic_bool shouldPause{}; From fa38099fdfbfc86be09af82c3c5c276fc21c6bf0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 21:52:28 +0500 Subject: [PATCH 411/497] xrCore/Threading/TaskManager.hpp: removed WaitForChildren and corresponding code --- src/xrCore/Threading/Task.hpp | 7 +------ src/xrCore/Threading/TaskManager.cpp | 11 ----------- src/xrCore/Threading/TaskManager.hpp | 1 - 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 61a1c765f6e..6bee54fc699 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -88,14 +88,9 @@ class XRCORE_API Task final : Noncopyable return m_data.jobs.load(std::memory_order_relaxed); } - bool HasChildren() const - { - return GetJobsCount() > 1; - } - bool IsFinished() const { - return 0 == m_data.jobs.load(std::memory_order_relaxed); + return GetJobsCount() == 0; } private: diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index d67a76936f9..e3fb5bd7a55 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -338,17 +338,6 @@ void TaskManager::Wait(const Task& task) const } } -void TaskManager::WaitForChildren(const Task& task) const -{ - ZoneScoped; - while (!task.HasChildren()) - { - ExecuteOneTask(); - if (s_tl_worker.id == 0 && xrDebug::ProcessingFailure()) - SDL_PumpEvents(); // Necessary to prevent dead locks - } -} - bool TaskManager::ExecuteOneTask() const { Task* task = s_tl_worker.pop(); diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index fd294326df7..174de025b22 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -82,7 +82,6 @@ class XRCORE_API TaskManager final void UnregisterThisThreadAsWorker(); void Wait(const Task& task) const; - void WaitForChildren(const Task& task) const; bool ExecuteOneTask() const; void Pause(bool pause) { shouldPause.store(pause, std::memory_order_release); } From 8de19dfa31cb1718db6660950eff3312a358e5e9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 21:55:45 +0500 Subject: [PATCH 412/497] Revert "xrEngine/x_ray.cpp: load LTX configs in parallel" This reverts commit b2a42cb4185cfdd0f7d7bd903486cc1659d0056e. --- src/xrEngine/x_ray.cpp | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index ee1ee986ca3..342abc03ca3 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -117,7 +117,16 @@ void InitSettings() { ZoneScoped; + xr_auth_strings_t ignoredPaths, checkedPaths; + fill_auth_check_params(ignoredPaths, checkedPaths); //TODO port xrNetServer to Linux + PathIncludePred includePred(&ignoredPaths); + CInifile::allow_include_func_t includeFilter; + includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); + + InitConfig(pSettings, "system.ltx"); + InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); InitConfig(pSettingsOpenXRay, "openxray.ltx", false, true, true, false); + InitConfig(pGameIni, "game.ltx"); if (strstr(Core.Params, "-shoc") || strstr(Core.Params, "-soc")) set_shoc_mode(); @@ -139,31 +148,6 @@ void InitSettings() else if (xr_strcmpi("unlock", gameMode) == 0) set_free_mode(); } - - const auto& initSettings = TaskScheduler->AddTask([](Task&, void*) - { - InitConfig(pSettings, "system.ltx"); - }); - - const auto& initSettingsAuth = TaskScheduler->AddTask([](Task&, void*) - { - xr_auth_strings_t ignoredPaths, checkedPaths; - fill_auth_check_params(ignoredPaths, checkedPaths); - PathIncludePred includePred(&ignoredPaths); - CInifile::allow_include_func_t includeFilter; - includeFilter.bind(&includePred, &PathIncludePred::IsIncluded); - - InitConfig(pSettingsAuth, "system.ltx", true, true, true, false, 0, includeFilter); - }); - - const auto& initGameSettings = TaskScheduler->AddTask([](Task&, void*) - { - InitConfig(pGameIni, "game.ltx"); - }); - - TaskScheduler->Wait(initSettings); - TaskScheduler->Wait(initSettingsAuth); - TaskScheduler->Wait(initGameSettings); } void InitConsole() From 0983e11394e0d434d66cb7e2198b256e03e60698 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 14 May 2024 23:33:04 +0500 Subject: [PATCH 413/497] xrEngine/EngineAPI.cpp: replace std::array with plain C array We need to make the compiler determine the size of the array, so that we don't try to load NULL modules (which makes the engine crash, because libraryName is nullptr) --- src/xrEngine/EngineAPI.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index 3c8a4afd6b3..5b2b7abbed1 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -29,13 +29,13 @@ struct RendererDesc RendererModule* module; }; -std::array g_render_modules = -{{ +RendererDesc g_render_modules[] = +{ #ifdef XR_PLATFORM_WINDOWS { "xrRender_R4", nullptr, nullptr }, #endif { "xrRender_GL", nullptr, nullptr }, -}}; +}; ////////////////////////////////////////////////////////////////////// // Construction/Destruction From 18252b1558657578c1538ec914c2aa2926649bec Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 03:16:04 +0500 Subject: [PATCH 414/497] Work on tracy zones --- src/Layers/xrRender/DetailManager.cpp | 2 ++ src/Layers/xrRender/DetailManager_soft.cpp | 1 + src/Layers/xrRender/r__dsgraph_render.cpp | 8 ++++++++ .../xrRender/r__dsgraph_render_lods.cpp | 1 + src/Layers/xrRender/r__sync_point.cpp | 2 ++ .../xrRenderDX11/dx11DetailManager_VS.cpp | 3 +++ .../r4_rendertarget_phase_combine.cpp | 1 + src/Layers/xrRender_R2/r2_R_lights.cpp | 2 ++ src/Layers/xrRender_R2/r2_R_render.cpp | 2 ++ src/xrCore/Containers/FixedMap.h | 19 ------------------- src/xrEngine/CameraManager.cpp | 2 ++ src/xrGame/ActorCameras.cpp | 2 ++ src/xrGame/GametaskManager.cpp | 1 + src/xrGame/map_manager.cpp | 1 + 14 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index 53a3a3ddc39..d8b95f9a940 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -402,6 +402,8 @@ void CDetailManager::Render(CBackend& cmd_list) return; #endif + ZoneScoped; + // MT MT_SYNC(); diff --git a/src/Layers/xrRender/DetailManager_soft.cpp b/src/Layers/xrRender/DetailManager_soft.cpp index da412633f39..727466ae20d 100644 --- a/src/Layers/xrRender/DetailManager_soft.cpp +++ b/src/Layers/xrRender/DetailManager_soft.cpp @@ -16,6 +16,7 @@ void CDetailManager::soft_Load() void CDetailManager::soft_Unload() { soft_Geom.destroy(); } void CDetailManager::soft_Render() { + ZoneScoped; // Render itself // float fPhaseRange = PI/16; // float fPhaseX = _sin(RDEVICE.fTimeGlobal*0.1f) *fPhaseRange; diff --git a/src/Layers/xrRender/r__dsgraph_render.cpp b/src/Layers/xrRender/r__dsgraph_render.cpp index d6f33d8a7d4..5a5b21718a9 100644 --- a/src/Layers/xrRender/r__dsgraph_render.cpp +++ b/src/Layers/xrRender/r__dsgraph_render.cpp @@ -42,6 +42,7 @@ void R_dsgraph_structure::render_graph(u32 _priority) // Sorting by SSA and changes minimizations // Render several passes { + ZoneScopedN("dsgraph_render_static"); PIX_EVENT_CTX(cmd_list, dsgraph_render_static); for (u32 iPass = 0; iPass < SHADER_PASSES_MAX; ++iPass) @@ -83,6 +84,7 @@ void R_dsgraph_structure::render_graph(u32 _priority) // Sorting by SSA and changes minimizations // Render several passes { + ZoneScopedN("dsgraph_render_dynamic"); PIX_EVENT_CTX(cmd_list, dsgraph_render_dynamic); for (u32 iPass = 0; iPass < SHADER_PASSES_MAX; ++iPass) @@ -237,6 +239,7 @@ ICF void sort_back_to_front_render_and_clean(u32 context_id, T& vec) // HUD render void R_dsgraph_structure::render_hud() { + ZoneScoped; PIX_EVENT_CTX(cmd_list, dsgraph_render_hud); if (!mapHUD.empty()) @@ -253,6 +256,7 @@ void R_dsgraph_structure::render_hud() void R_dsgraph_structure::render_hud_ui() { + ZoneScoped; CCustomHUD* levelHud = g_pGameLevel->pHUD; VERIFY(levelHud && levelHud->RenderActiveItemUIQuery()); @@ -284,6 +288,7 @@ void R_dsgraph_structure::render_hud_ui() // strict-sorted render void R_dsgraph_structure::render_sorted() { + ZoneScoped; PIX_EVENT_CTX(cmd_list, dsgraph_render_sorted); sort_back_to_front_render_and_clean(context_id, mapSorted); @@ -300,6 +305,7 @@ void R_dsgraph_structure::render_sorted() void R_dsgraph_structure::render_emissive() { #if RENDER != R_R1 + ZoneScoped; PIX_EVENT_CTX(cmd_list, dsgraph_render_emissive); sort_front_to_back_render_and_clean(context_id, mapEmissive); @@ -317,6 +323,7 @@ void R_dsgraph_structure::render_emissive() void R_dsgraph_structure::render_wmarks() { #if RENDER != R_R1 + ZoneScoped; PIX_EVENT(dsgraph_render_wmarks); sort_front_to_back_render_and_clean(context_id, mapWmark); @@ -327,6 +334,7 @@ void R_dsgraph_structure::render_wmarks() // strict-sorted render void R_dsgraph_structure::render_distort() { + ZoneScoped; PIX_EVENT(dsgraph_render_distort); sort_back_to_front_render_and_clean(context_id, mapDistort); diff --git a/src/Layers/xrRender/r__dsgraph_render_lods.cpp b/src/Layers/xrRender/r__dsgraph_render_lods.cpp index 0f5b6b49de7..57edd13738f 100644 --- a/src/Layers/xrRender/r__dsgraph_render_lods.cpp +++ b/src/Layers/xrRender/r__dsgraph_render_lods.cpp @@ -18,6 +18,7 @@ template IC bool cmp_first_h(const T &lhs, const T &rhs) { return (lhs void R_dsgraph_structure::render_lods(bool _setup_zb, bool _clear) { + ZoneScoped; PIX_EVENT_CTX(cmd_list, dsgraph_render_lods); if (mapLOD.empty()) diff --git a/src/Layers/xrRender/r__sync_point.cpp b/src/Layers/xrRender/r__sync_point.cpp index 1f84ff2941a..db28dc49db5 100644 --- a/src/Layers/xrRender/r__sync_point.cpp +++ b/src/Layers/xrRender/r__sync_point.cpp @@ -12,6 +12,7 @@ void R_sync_point::Destroy() {} bool R_sync_point::Wait(u32 /*wait_sleep*/, u64 timeout) { + ZoneScoped; CHK_GL(q_sync_point[q_sync_count] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); const auto status = glClientWaitSync((GLsync)q_sync_point[q_sync_count], @@ -60,6 +61,7 @@ void R_sync_point::Destroy() bool R_sync_point::Wait(u32 wait_sleep, u64 timeout) { + ZoneScoped; CTimer T; T.Start(); BOOL result = FALSE; diff --git a/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp b/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp index e87cf83400e..b033cd46ba3 100644 --- a/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp +++ b/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp @@ -28,6 +28,7 @@ void CDetailManager::hw_Load_Shaders() void CDetailManager::hw_Render(CBackend& cmd_list) { + ZoneScoped; using namespace detail_manager; // Render-prepare @@ -90,6 +91,8 @@ void CDetailManager::hw_Render(CBackend& cmd_list) void CDetailManager::hw_Render_dump(CBackend& cmd_list, const Fvector4& consts, const Fvector4& wave, const Fvector4& wind, u32 var_id, u32 lod_id) { + ZoneScoped; + static shared_str strConsts("consts"); static shared_str strWave("wave"); static shared_str strDir2D("dir2D"); diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp index 00fff809480..82f3d1a9386 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp @@ -9,6 +9,7 @@ float hclip(float v, float dim) { return 2.f * v / dim - 1.f; } void CRenderTarget::phase_combine() { + ZoneScoped; PIX_EVENT(phase_combine); // TODO: DX11: Remove half pixel offset diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index c9dd5f63e86..c9792cbfc01 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -20,6 +20,8 @@ bool check_grass_shadow(light* L, CFrustum VB) void CRender::render_lights(light_Package& LP) { + ZoneScoped; + ////////////////////////////////////////////////////////////////////////// // Refactor order based on ability to pack shadow-maps // 1. calculate area + sort in descending order diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index 017e90a04d5..9443c3ee12b 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -75,6 +75,7 @@ void CRender::RenderMenu() extern u32 g_r; void CRender::Render() { + ZoneScoped; #if defined(USE_DX11) TracyD3D11Zone(HW.profiler_ctx, "Render"); #endif @@ -386,6 +387,7 @@ void CRender::Render() void CRender::render_forward() { + ZoneScoped; auto& dsgraph = get_imm_context(); //******* Main render - second order geometry (the one, that doesn't support deffering) diff --git a/src/xrCore/Containers/FixedMap.h b/src/xrCore/Containers/FixedMap.h index 1ba6f72193d..96c9b342ea9 100644 --- a/src/xrCore/Containers/FixedMap.h +++ b/src/xrCore/Containers/FixedMap.h @@ -240,8 +240,6 @@ class xr_fixed_map value_type* insert(const K& key) { - ZoneScoped; - if (!pool) return add(key); @@ -282,8 +280,6 @@ class xr_fixed_map value_type* insert_anyway(const K& key) { - ZoneScoped; - if (!pool) return add(key); @@ -369,7 +365,6 @@ class xr_fixed_map void traverse_left_right(u32 id, callback CB) { - ZoneScoped; if (pool) recurse_left_right(id, nodes, CB); @@ -377,16 +372,12 @@ class xr_fixed_map void traverse_right_left(u32 id, callback CB) { - ZoneScoped; - if (pool) recurse_right_left(id, nodes, CB); } void traverse_any(callback CB) { - ZoneScoped; - value_type* _end = end(); for (value_type* cur = begin(); cur != _end; ++cur) CB(*cur); @@ -394,40 +385,30 @@ class xr_fixed_map void get_left_right(xr_vector>& D) { - ZoneScoped; - if (pool) get_left_right(nodes, D); } void get_left_right_p(xr_vector>& D) { - ZoneScoped; - if (pool) get_left_right_p(nodes, D); } void get_right_left(xr_vector>& D) { - ZoneScoped; - if (pool) get_right_left(nodes, D); } void get_right_left_p(xr_vector>& D) { - ZoneScoped; - if (pool) get_right_left_p(nodes, D); } void get_any_p(xr_vector>& D) { - ZoneScoped; - if (empty()) return; D.resize(size()); diff --git a/src/xrEngine/CameraManager.cpp b/src/xrEngine/CameraManager.cpp index 3794bd691ec..b0b9990b833 100644 --- a/src/xrEngine/CameraManager.cpp +++ b/src/xrEngine/CameraManager.cpp @@ -169,6 +169,7 @@ void CCameraManager::UpdateFromCamera(const CCameraBase* C) void CCameraManager::Update(const Fvector& P, const Fvector& D, const Fvector& N, float fFOV_Dest, float fASPECT_Dest, float fFAR_Dest, u32 flags) { + ZoneScoped; #ifdef DEBUG if (!Device.Paused()) { @@ -313,6 +314,7 @@ void CCameraManager::UpdatePPEffectors() void CCameraManager::ApplyDevice() { + ZoneScoped; // Device params Device.mView.build_camera_dir(m_cam_info.p, m_cam_info.d, m_cam_info.n); diff --git a/src/xrGame/ActorCameras.cpp b/src/xrGame/ActorCameras.cpp index bfe103c60d0..705abd220a2 100644 --- a/src/xrGame/ActorCameras.cpp +++ b/src/xrGame/ActorCameras.cpp @@ -284,6 +284,8 @@ void CActor::cam_Update(float dt, float fFOV) if (m_holder) return; + ZoneScoped; + if ((mstate_real & mcClimb) && (cam_active != eacFreeLook)) camUpdateLadder(dt); on_weapon_shot_update(); diff --git a/src/xrGame/GametaskManager.cpp b/src/xrGame/GametaskManager.cpp index fc075de71da..db04ae4a1da 100644 --- a/src/xrGame/GametaskManager.cpp +++ b/src/xrGame/GametaskManager.cpp @@ -187,6 +187,7 @@ void CGameTaskManager::UpdateTasks() if (Device.Paused()) return; + ZoneScoped; Level().MapManager().DisableAllPointers(); u32 task_count = GetGameTasks().size(); diff --git a/src/xrGame/map_manager.cpp b/src/xrGame/map_manager.cpp index c88d76b55f2..132c09cd7f3 100644 --- a/src/xrGame/map_manager.cpp +++ b/src/xrGame/map_manager.cpp @@ -237,6 +237,7 @@ void CMapManager::GetMapLocations(const shared_str& spot_type, u16 id, xr_vector void CMapManager::Update() { + ZoneScoped; delete_data(m_deffered_destroy_queue); // from prev frame auto it = Locations().begin(); From 84f09c511d8d21535b47d3fe2e011abab9417d34 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 04:25:13 +0500 Subject: [PATCH 415/497] xrGame/ActorCameras.cpp: don't update same camera two times --- src/xrGame/ActorCameras.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/xrGame/ActorCameras.cpp b/src/xrGame/ActorCameras.cpp index 705abd220a2..fd6f485bb87 100644 --- a/src/xrGame/ActorCameras.cpp +++ b/src/xrGame/ActorCameras.cpp @@ -374,14 +374,7 @@ void CActor::cam_Update(float dt, float fFOV) { collide_camera(*cameras[eacFirstEye], _viewport_near, this); } - if (psActorFlags.test(AF_PSP)) - { - Cameras().UpdateFromCamera(C); - } - else - { - Cameras().UpdateFromCamera(cameras[eacFirstEye]); - } + Cameras().UpdateFromCamera(C); fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude() / Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; @@ -396,7 +389,6 @@ void CActor::cam_Update(float dt, float fFOV) if (Level().CurrentEntity() == this) { - Level().Cameras().UpdateFromCamera(C); const bool allow = !Level().Cameras().GetCamEffector(cefDemo) && !Level().Cameras().GetCamEffector(cefAnsel); if (eacFirstEye == cam_active && allow) { From 136bf5e3d01cee9f06402e8328ba519aa8fcfa02 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 04:59:19 +0500 Subject: [PATCH 416/497] Allow HOM update to be executed right after camera is updated --- src/Layers/xrRender_R2/r2.cpp | 5 ++++- src/Layers/xrRender_R2/r2.h | 2 +- src/Layers/xrRender_R2/r2_R_calculate.cpp | 4 ---- src/xrEngine/Render.h | 2 +- src/xrEngine/device.cpp | 12 +++++++++--- src/xrEngine/device.h | 2 +- src/xrGame/Actor.cpp | 2 ++ 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index e4bd09d51d3..5407b03d789 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -639,10 +639,13 @@ void CRender::reset_end() m_bFirstFrameAfterReset = true; } -void CRender::BeforeRender() +void CRender::OnCameraUpdated() { ZoneScoped; + // Frustum + ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB + FRUSTUM_P_FAR); + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index 98ae6f5dc18..a13e5152da5 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -488,7 +488,7 @@ class CRender final : public D3DXRenderBase bool occ_visible(sPoly& P) override; // Main - void BeforeRender() override; + void OnCameraUpdated() override; void Calculate() override; void Render() override; diff --git a/src/Layers/xrRender_R2/r2_R_calculate.cpp b/src/Layers/xrRender_R2/r2_R_calculate.cpp index 987be7666b4..0920e9a154f 100644 --- a/src/Layers/xrRender_R2/r2_R_calculate.cpp +++ b/src/Layers/xrRender_R2/r2_R_calculate.cpp @@ -122,10 +122,6 @@ void CRender::Calculate() Lights.add_light(L); } - - // Frustum - ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB + FRUSTUM_P_FAR); - TaskScheduler->Wait(*ProcessHOMTask); r_main.init(); diff --git a/src/xrEngine/Render.h b/src/xrEngine/Render.h index 25f72e19d67..a1195035a43 100644 --- a/src/xrEngine/Render.h +++ b/src/xrEngine/Render.h @@ -411,7 +411,7 @@ class ENGINE_API IRender virtual DeviceState GetDeviceState() = 0; virtual bool GetForceGPU_REF() = 0; virtual u32 GetCacheStatPolys() = 0; - virtual void BeforeRender() = 0; + virtual void OnCameraUpdated() = 0; virtual void Begin() = 0; virtual void Clear() = 0; virtual void End() = 0; diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 9bcfb2f4342..cf4c9e3e397 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -210,8 +210,12 @@ bool CRenderDevice::BeforeFrame() return true; } -void CRenderDevice::BeforeRender() +void CRenderDevice::OnCameraUpdated() { + static u32 frame{ u32(-1) }; + if (frame == dwFrame) + return; + ZoneScoped; // Precache @@ -230,8 +234,10 @@ void CRenderDevice::BeforeRender() mInvView.invert(mView); mFullTransform.mul(mProject, mView); mInvFullTransform.invert_44(mFullTransform); - GEnv.Render->BeforeRender(); + GEnv.Render->OnCameraUpdated(); GEnv.Render->SetCacheXform(mView, mProject); + + frame = dwFrame; } static void UpdateViewports() @@ -313,7 +319,7 @@ void CRenderDevice::ProcessFrame() FrameMove(); - BeforeRender(); + OnCameraUpdated(); executeSecondaryTasks.store(true, std::memory_order_release); diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 7d5a03d3ff1..7e9373c2304 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -175,7 +175,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler bool BeforeFrame(); void FrameMove(); - void BeforeRender(); + void OnCameraUpdated(); void DoRender(); bool RenderBegin(); void Clear(); diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 985642a8e37..1a954197823 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -1145,6 +1145,8 @@ void CActor::UpdateCL() cam_Update(float(Device.dwTimeDelta) / 1000.0f, currentFOV()); + Device.OnCameraUpdated(); + if (Level().CurrentEntity() && this->ID() == Level().CurrentEntity()->ID()) { psHUD_Flags.set(HUD_CROSSHAIR_RT2, true); From 2d5310ba10c1a73ccb65877e9d28091456c00ae1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 05:14:27 +0500 Subject: [PATCH 417/497] xrRender: dispatch Details calculation right after camera after --- src/Layers/xrRender/DetailManager.cpp | 33 +++++++++++++-------------- src/Layers/xrRender/DetailManager.h | 14 +++--------- src/Layers/xrRender_R2/r2.cpp | 9 +++----- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index d8b95f9a940..4186a3dec89 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -17,6 +17,9 @@ #else #include "xrEngine/IGame_Persistent.h" #include "xrEngine/Environment.h" + +#include "xrCore/Threading/TaskManager.hpp" + #if defined(XR_ARCHITECTURE_X86) || defined(XR_ARCHITECTURE_X64) || defined(XR_ARCHITECTURE_E2K) || defined(XR_ARCHITECTURE_PPC64) #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) @@ -404,8 +407,7 @@ void CDetailManager::Render(CBackend& cmd_list) ZoneScoped; - // MT - MT_SYNC(); + TaskScheduler->Wait(*m_calc_task); RImplementation.BasicStats.DetailRender.Begin(); g_pGamePersistent->m_pGShaderConstants->m_blender_mode.w = 1.0f; //--#SM+#-- Флаг начала рендера травы [begin of grass render] @@ -427,10 +429,9 @@ void CDetailManager::Render(CBackend& cmd_list) g_pGamePersistent->m_pGShaderConstants->m_blender_mode.w = 0.0f; //--#SM+#-- Флаг конца рендера травы [end of grass render] RImplementation.BasicStats.DetailRender.End(); - m_frame_rendered = Device.dwFrame; } -void CDetailManager::MT_CALC() +void CDetailManager::MT_CALC(Task&, void*) { #ifndef _EDITOR if (nullptr == RImplementation.Details) @@ -445,21 +446,19 @@ void CDetailManager::MT_CALC() EYE = Device.vCameraPosition; - MT.Enter(); - if (m_frame_calc != Device.dwFrame) - if ((m_frame_rendered + 1) == Device.dwFrame) // already rendered - { - int s_x = iFloor(EYE.x / dm_slot_size + .5f); - int s_z = iFloor(EYE.z / dm_slot_size + .5f); + const int s_x = iFloor(EYE.x / dm_slot_size + .5f); + const int s_z = iFloor(EYE.z / dm_slot_size + .5f); - RImplementation.BasicStats.DetailCache.Begin(); - cache_Update(s_x, s_z, EYE, dm_max_decompress); - RImplementation.BasicStats.DetailCache.End(); + RImplementation.BasicStats.DetailCache.Begin(); + cache_Update(s_x, s_z, EYE, dm_max_decompress); + RImplementation.BasicStats.DetailCache.End(); - UpdateVisibleM(); - m_frame_calc = Device.dwFrame; - } - MT.Leave(); + UpdateVisibleM(); +} + +void CDetailManager::DispatchMTCalc() +{ + m_calc_task = &TaskScheduler->AddTask({ this, &CDetailManager::MT_CALC }); } void CDetailManager::details_clear() diff --git a/src/Layers/xrRender/DetailManager.h b/src/Layers/xrRender/DetailManager.h index 0198125008e..69dcf2bd53e 100644 --- a/src/Layers/xrRender/DetailManager.h +++ b/src/Layers/xrRender/DetailManager.h @@ -225,18 +225,10 @@ class ECORE_API CDetailManager void Render(CBackend& cmd_list); /// MT stuff - Lock MT; - volatile u32 m_frame_calc; - volatile u32 m_frame_rendered; + Task* m_calc_task{}; - void MT_CALC(); - ICF void MT_SYNC() - { - if (m_frame_calc == Device.dwFrame) - return; - - MT_CALC(); - } + void MT_CALC(Task&, void*); + void DispatchMTCalc(); CDetailManager(); virtual ~CDetailManager(); diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 5407b03d789..b6196651f5c 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -650,6 +650,8 @@ void CRender::OnCameraUpdated() return; ProcessHOMTask = &TaskScheduler->AddTask({ &HOM, &CHOM::MT_RENDER }); + if (Details) + Details->DispatchMTCalc(); } void CRender::OnFrame() @@ -657,14 +659,9 @@ void CRender::OnFrame() ZoneScoped; Models->DeleteQueue(); + if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; - if (ps_r2_ls_flags.test(R2FLAG_EXP_MT_CALC)) - { - // MT-details (@front) - Device.seqParallel.insert( - Device.seqParallel.begin(), fastdelegate::FastDelegate0<>(Details, &CDetailManager::MT_CALC)); - } if (Details) g_pGamePersistent->GrassBendersUpdateAnimations(); From f02e8d80153edad013d6277ce089a8af12b6f22a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 05:34:33 +0500 Subject: [PATCH 418/497] Removed Secondary thread again CPU resources consumption optimization. --- src/xrCore/Threading/TaskManager.cpp | 2 +- src/xrEngine/Device_create.cpp | 1 - src/xrEngine/device.cpp | 38 ++++++---------------------- src/xrEngine/device.h | 6 +---- 4 files changed, 10 insertions(+), 37 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index e3fb5bd7a55..202acf14675 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -39,7 +39,7 @@ xr_unique_ptr TaskScheduler; -static constexpr size_t OTHER_THREADS_COUNT = 2; // Primary and Secondary thread +static constexpr size_t OTHER_THREADS_COUNT = 1; // Primary and Secondary thread class TaskStorageSize { diff --git a/src/xrEngine/Device_create.cpp b/src/xrEngine/Device_create.cpp index c2c02ee87a3..7f136b7f470 100644 --- a/src/xrEngine/Device_create.cpp +++ b/src/xrEngine/Device_create.cpp @@ -22,7 +22,6 @@ void CRenderDevice::Create() return; // prevent double call ZoneScoped; - secondaryThread = Threading::RunThread("Secondary thread", &CRenderDevice::SecondaryThreadProc, this); Statistic = xr_new(); Log("Starting RENDER device..."); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index cf4c9e3e397..208bd6918ca 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -285,27 +285,13 @@ void CRenderDevice::DoRender() stats.RenderTotal.accum = renderTotalReal.accum; } -constexpr pcstr SECONDARY_THREAD_MARK = "Secondary thread"; - -void CRenderDevice::SecondaryThreadProc() +void CRenderDevice::ProcessParallelSequence(Task&, void*) { - TaskScheduler->RegisterThisThreadAsWorker(); - while (!mt_bMustExit.load(std::memory_order_acquire)) - { - if (executeSecondaryTasks.load(std::memory_order_acquire)) - { - FrameMarkStart(SECONDARY_THREAD_MARK); - for (u32 pit = 0; pit < seqParallel.size(); pit++) - seqParallel[pit](); - seqParallel.clear(); - seqFrameMT.Process(); - executeSecondaryTasks.store(false, std::memory_order_relaxed); - secondaryTasksExecuted.store(true, std::memory_order_release); - FrameMarkEnd(SECONDARY_THREAD_MARK); - } - TaskScheduler->ExecuteOneTask(); - } - TaskScheduler->UnregisterThisThreadAsWorker(); + ZoneScoped; + for (u32 pit = 0; pit < seqParallel.size(); pit++) + seqParallel[pit](); + seqParallel.clear(); + seqFrameMT.Process(); } void CRenderDevice::ProcessFrame() @@ -321,17 +307,11 @@ void CRenderDevice::ProcessFrame() OnCameraUpdated(); - executeSecondaryTasks.store(true, std::memory_order_release); + const auto& processSeqParallel = TaskScheduler->AddTask({ this, &CRenderDevice::ProcessParallelSequence }); DoRender(); - while (!secondaryTasksExecuted.load(std::memory_order_acquire)) - { - SDL_PumpEvents(); - TaskScheduler->ExecuteOneTask(); - } - - secondaryTasksExecuted.store(false, std::memory_order_relaxed); + TaskScheduler->Wait(processSeqParallel); const u64 frameEndTime = TimerGlobal.GetElapsed_ms(); const u64 frameTime = frameEndTime - frameStartTime; @@ -347,7 +327,6 @@ void CRenderDevice::ProcessFrame() if (frameTime < updateDelta) Sleep(updateDelta - frameTime); - if (!b_is_Active) Sleep(1); } @@ -493,7 +472,6 @@ void CRenderDevice::Shutdown() { // Stop Balance-Thread mt_bMustExit.store(true, std::memory_order_release); - secondaryThread.join(); seqAppEnd.Process(); } diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 7e9373c2304..badb90d98d7 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -164,7 +164,7 @@ class ENGINE_API CRenderDevice : public IWindowHandler bool Paused(); private: - void SecondaryThreadProc(); + void ProcessParallelSequence(Task&, void*); public: // Scene control @@ -233,10 +233,6 @@ class ENGINE_API CRenderDevice : public IWindowHandler return (Timer.time_factor()); } -private: - std::thread secondaryThread; - std::atomic_bool executeSecondaryTasks{}, secondaryTasksExecuted{}, secondaryThreadFinished{}; - public: // Multi-threading Event PresentationFinished = nullptr; From 85f7a8f6c11f759ac3c4e91aed2bf0a43a076065 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 05:36:46 +0500 Subject: [PATCH 419/497] xrEngine/device.h|cpp: Removed mt_bMustExit and CheckPrivilegySlowdown --- src/xrEngine/device.cpp | 31 ------------------------------- src/xrEngine/device.h | 1 - 2 files changed, 32 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 208bd6918ca..9e5b846733a 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -60,33 +60,6 @@ bool CRenderDevice::RenderBegin() void CRenderDevice::Clear() { GEnv.Render->Clear(); } -namespace -{ -void CheckPrivilegySlowdown() -{ -#ifndef MASTER_GOLD - const auto slowdownthread = [] - { - for (;;) - { - if (Device.GetStats().fFPS < 30) - Sleep(1); - if (Device.mt_bMustExit.load(std::memory_order_acquire) || !pSettings || !Console || !pInput) - return; - } - }; - - if (strstr(Core.Params, "-slowdown")) - Threading::SpawnThread("slowdown", slowdownthread); - if (strstr(Core.Params, "-slowdown2x")) - { - Threading::SpawnThread("slowdown", slowdownthread); - Threading::SpawnThread("slowdown", slowdownthread); - } -#endif -} -} - void CRenderDevice::RenderEnd(void) { if (GEnv.isDedicatedServer) @@ -111,7 +84,6 @@ void CRenderDevice::RenderEnd(void) Msg("* MEMORY USAGE: %d K", Memory.mem_usage() / 1024); Msg("* End of synchronization A[%d] R[%d]", b_is_Active, b_is_Ready); FIND_CHUNK_COUNTER_FLUSH(); - CheckPrivilegySlowdown(); if (g_pGamePersistent->GameType() == 1 && !psDeviceFlags.test(rsAlwaysActive)) // haCk { const Uint32 flags = SDL_GetWindowFlags(m_sdlWnd); @@ -470,9 +442,6 @@ void CRenderDevice::Run() void CRenderDevice::Shutdown() { - // Stop Balance-Thread - mt_bMustExit.store(true, std::memory_order_release); - seqAppEnd.Process(); } diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index badb90d98d7..996a7b1cb3f 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -236,7 +236,6 @@ class ENGINE_API CRenderDevice : public IWindowHandler public: // Multi-threading Event PresentationFinished = nullptr; - std::atomic_bool mt_bMustExit{}; static constexpr u32 MaximalWaitTime = 16; // ms From 343d5cfffaa5b3b761f3e4edb89388fec77c2f4f Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 05:46:13 +0500 Subject: [PATCH 420/497] xrCore: removed task finish callback from the task manager --- src/xrCore/Threading/ParallelFor.hpp | 28 --------------------- src/xrCore/Threading/ParallelForEach.hpp | 13 +++------- src/xrCore/Threading/Task.cpp | 21 +--------------- src/xrCore/Threading/Task.hpp | 7 ------ src/xrCore/Threading/TaskManager.cpp | 31 +----------------------- src/xrCore/Threading/TaskManager.hpp | 5 ---- 6 files changed, 5 insertions(+), 100 deletions(-) diff --git a/src/xrCore/Threading/ParallelFor.hpp b/src/xrCore/Threading/ParallelFor.hpp index c3e52fd9305..a1664b3da1e 100644 --- a/src/xrCore/Threading/ParallelFor.hpp +++ b/src/xrCore/Threading/ParallelFor.hpp @@ -147,22 +147,6 @@ class ParallelForTask return task; } - // Doesn't wait until done - static decltype(auto) Run(const Range& range, bool wait, const Task::OnFinishFunc& callback, const Function& function) - { - TaskData taskData{ range, function }; - - auto& task = TaskManager::AddTask(callback, task_func, sizeof(TaskData), &taskData); - if (wait) - { - VERIFY2(TaskScheduler, "Task scheduler is not yet created. " - "You should explicitly state that you know this by setting 'wait' param to false."); - if (TaskScheduler) - TaskScheduler->Wait(task); - } - return task; - } - private: static void task_func(Task& thisTask, void* data_ptr) { @@ -204,15 +188,3 @@ decltype(auto) xr_parallel_for(const Range& range, const Function& function) return details::ParallelForTask::Run(range, true, function); } -template -decltype(auto) xr_parallel_for(const Range& range, bool wait, const Task::OnFinishFunc& callback, const Function& function) -{ - return details::ParallelForTask::Run(range, wait, callback, function); -} - -// Caller thread will wait on the task finish -template -decltype(auto) xr_parallel_for(const Range& range, const Task::OnFinishFunc& callback, const Function& function) -{ - return details::ParallelForTask::Run(range, true, callback, function); -} diff --git a/src/xrCore/Threading/ParallelForEach.hpp b/src/xrCore/Threading/ParallelForEach.hpp index ac8f91aacb4..0795ec04170 100644 --- a/src/xrCore/Threading/ParallelForEach.hpp +++ b/src/xrCore/Threading/ParallelForEach.hpp @@ -22,10 +22,10 @@ namespace details class ParallelForEachTask { public: - template - static decltype(auto) Run(Iterator begin, Iterator end, ThirdArgument thirdArgument, const Function& function) + template + static decltype(auto) Run(Iterator begin, Iterator end, bool wait, const Function& function) { - return xr_parallel_for(TaskRange(begin, end), thirdArgument, [&](TaskRange& range) + return xr_parallel_for(TaskRange(begin, end), wait, [&](TaskRange& range) { for (auto& it : range) { @@ -49,10 +49,3 @@ decltype(auto) xr_parallel_for_each(Range& range, const Function& function) { return details::ParallelForEachTask::Run(std::begin(range), std::end(range), true, function); } - -// User has a callback, he is responsible for waiting on the task finish (due to task management system limitation) -template -decltype(auto) xr_parallel_for_each(Range& range, const Task::OnFinishFunc& callback, const Function& function) -{ - return details::ParallelForEachTask::Run(std::begin(range), std::end(range), callback, function); -} diff --git a/src/xrCore/Threading/Task.cpp b/src/xrCore/Threading/Task.cpp index 7c0bcda7a09..b5e40ebb9c0 100644 --- a/src/xrCore/Threading/Task.cpp +++ b/src/xrCore/Threading/Task.cpp @@ -18,10 +18,7 @@ #include "Task.hpp" Task::Data::Data(const TaskFunc& task, Task* parent) - : task_func(task), on_finish_callback(nullptr), parent(parent), jobs(1) {} - -Task::Data::Data(const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent) - : task_func(task), on_finish_callback(onFinishCallback), parent(parent), jobs(1) {} + : task_func(task), parent(parent), jobs(1) {} Task::Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent /*= nullptr*/) : m_data(task, parent) @@ -33,23 +30,7 @@ Task::Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent /*= n } } -Task::Task(const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent /*= nullptr*/) - : m_data(task, onFinishCallback, parent) -{ - VERIFY2(dataSize <= sizeof(m_user_data), "Cannot fit your data in the task"); - if (data && dataSize) - { - CopyMemory(m_user_data, data, std::min(dataSize, sizeof(m_user_data))); - } -} - void Task::Execute() { m_data.task_func(*this, m_user_data); } - -void Task::Finish() -{ - if (m_data.on_finish_callback) - m_data.on_finish_callback(*this, m_user_data); -} diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 6bee54fc699..2dbf2a90290 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -42,20 +42,17 @@ class XRCORE_API Task final : Noncopyable public: using TaskFunc = fastdelegate::FastDelegate; - using OnFinishFunc = fastdelegate::FastDelegate; private: // ordered from biggest to smallest struct Data { TaskFunc task_func{}; - OnFinishFunc on_finish_callback{}; Task* parent{}; std::atomic_int16_t jobs{}; // at least 1 (task itself), zero means task is done. Data() = default; Data(const TaskFunc& task, Task* parent); - Data(const TaskFunc& task, const OnFinishFunc& onFinishCallback, Task* parent); } m_data; static constexpr size_t USER_DATA_SIZE = TASK_SIZE - sizeof(m_data); @@ -69,9 +66,6 @@ class XRCORE_API Task final : Noncopyable // Will just execute Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent = nullptr); - // Will execute and call back - Task(const TaskFunc& task, const OnFinishFunc& onFinishCallback, void* data, size_t dataSize, Task* parent = nullptr); - public: static constexpr size_t GetAvailableDataStorageSize() { @@ -96,5 +90,4 @@ class XRCORE_API Task final : Noncopyable private: // Called by TaskManager void Execute(); - void Finish(); }; diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 202acf14675..d1287bc18b4 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -286,16 +286,12 @@ Task* TaskManager::TryToSteal() const void TaskManager::ExecuteTask(Task& task) { task.Execute(); - FinalizeTask(task); -} -void TaskManager::FinalizeTask(Task& task) -{ + // Finalize for (Task* it = &task; ; it = it->m_data.parent) { const auto unfinishedJobs = it->m_data.jobs.fetch_sub(1, std::memory_order_acq_rel) - 1; // fetch_sub returns previous value VERIFY2(unfinishedJobs >= 0, "The same task was executed two times."); - it->Finish(); if (unfinishedJobs || !it->m_data.parent) break; } @@ -361,23 +357,12 @@ Task& TaskManager::CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize /* return *new (AllocateTask()) Task(taskFunc, data, dataSize); } -Task& TaskManager::CreateTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - return *new (AllocateTask()) Task(taskFunc, onFinishCallback, data, dataSize); -} - Task& TaskManager::CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { IncrementTaskJobsCounter(parent); return *new (AllocateTask()) Task(taskFunc, data, dataSize, &parent); } -Task& TaskManager::CreateTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - IncrementTaskJobsCounter(parent); - return *new (AllocateTask()) Task(taskFunc, onFinishCallback, data, dataSize, &parent); -} - Task& TaskManager::AddTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { auto& task = CreateTask(taskFunc, dataSize, data); @@ -385,13 +370,6 @@ Task& TaskManager::AddTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0 return task; } -Task& TaskManager::AddTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - auto& task = CreateTask(onFinishCallback, taskFunc, dataSize, data); - PushTask(task); - return task; -} - Task& TaskManager::AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) { auto& task = CreateTask(parent, taskFunc, dataSize, data); @@ -399,13 +377,6 @@ Task& TaskManager::AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t return task; } -Task& TaskManager::AddTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - auto& task = CreateTask(parent, onFinishCallback, taskFunc, dataSize, data); - PushTask(task); - return task; -} - size_t TaskManager::GetWorkersCount() const { return workers.size(); diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 174de025b22..4561d2692cb 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -41,7 +41,6 @@ class XRCORE_API TaskManager final [[nodiscard]] Task* TryToSteal() const; static void ExecuteTask(Task& task); - static void FinalizeTask(Task& task); [[nodiscard]] ICF static Task* AllocateTask(); static void ICF IncrementTaskJobsCounter(Task& parent); @@ -57,11 +56,9 @@ class XRCORE_API TaskManager final // TaskFunc is at the end for fancy in-place lambdas // Create a task, but don't run it yet [[nodiscard]] static Task& CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] static Task& CreateTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Create a task as child, but don't run it yet [[nodiscard]] static Task& CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - [[nodiscard]] static Task& CreateTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Run task in parallel static void PushTask(Task& task); @@ -71,11 +68,9 @@ class XRCORE_API TaskManager final // Shortcut: create a task and run it immediately static Task& AddTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - static Task& AddTask(const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); // Shortcut: create task and run it immediately static Task& AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); - static Task& AddTask(Task& parent, const Task::OnFinishFunc& onFinishCallback, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); public: void RegisterThisThreadAsWorker(); From b693218b45e92aecb14924beea30a55d8abd445c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 15 May 2024 21:31:10 +0500 Subject: [PATCH 421/497] Fix compilation on GCC --- src/xrCore/Threading/TaskManager.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index 4561d2692cb..da766d4a9ce 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -15,11 +15,12 @@ */ #pragma once -#include - -#include "Event.hpp" #include "Task.hpp" +#include +#include +#include + class TaskWorker; class XRCORE_API TaskManager final From bc9f5894c8a0396a5b29eaad6a745785b34f0167 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 17 May 2024 12:23:05 +0500 Subject: [PATCH 422/497] Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp: removed FreeBSD crash workaround (#1223) After e47e4fe057c4f3c7a56266c4666107c5b8edc4e1 the problem origin was removed, so we no longer need a workaround. --- .../xrRenderPC_GL/gl_rendertarget_build_textures.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp index 68def07bc5b..bc2619d88e3 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_build_textures.cpp @@ -1,9 +1,5 @@ #include "stdafx.h" -#ifdef XR_PLATFORM_BSD -#include // XXX: needed for workaround below -#endif - static void generate_jitter(u32* dest, u32 elem_count) { const int cmax = 8; @@ -32,9 +28,6 @@ void CRenderTarget::build_textures() { // Build material(s) { -#ifdef XR_PLATFORM_BSD - fedisableexcept(FE_UNDERFLOW | FE_INEXACT); // XXX: I really want to see a better solution -#endif // Surface glGenTextures(1, &t_material_surf); CHK_GL(glBindTexture(GL_TEXTURE_3D, t_material_surf)); From beecd8ca55994b4da958dc47258e21989170865e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 16 May 2024 22:56:57 +0500 Subject: [PATCH 423/497] xrCore/Threading/TaskManager.cpp: use acquire-release memory order to be 100% sane --- src/xrCore/Threading/TaskManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index d1287bc18b4..8a630595c46 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -307,7 +307,7 @@ Task* TaskManager::AllocateTask() void TaskManager::IncrementTaskJobsCounter(Task& parent) { VERIFY2(parent.m_data.jobs.load(std::memory_order_relaxed) > 0, "Adding child task to a parent that has already finished."); - [[maybe_unused]] const auto prev = parent.m_data.jobs.fetch_add(1, std::memory_order_relaxed); + [[maybe_unused]] const auto prev = parent.m_data.jobs.fetch_add(1, std::memory_order_acq_rel); VERIFY2(prev != std::numeric_limits::max(), "Max jobs overflow. (too much children)"); } From 4e8a4d63d7c0c3dae9e8a211ecf56d6f73727072 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 19 May 2024 19:06:54 +0500 Subject: [PATCH 424/497] Support lambda capture in the task manager --- src/Layers/xrRender/DetailManager.cpp | 38 ++++---- src/Layers/xrRender/DetailManager.h | 1 - src/Layers/xrRender/HOM.cpp | 15 +-- src/Layers/xrRender/HOM.h | 2 +- src/Layers/xrRenderDX11/dx11HW.cpp | 4 +- src/Layers/xrRender_R2/r2.cpp | 2 +- src/Layers/xrRender_R2/r2.h | 28 +++--- src/Layers/xrRender_R2/r2_R_lights.cpp | 46 ++++----- src/xrCore/CMakeLists.txt | 1 - src/xrCore/Threading/ParallelFor.hpp | 46 ++++----- src/xrCore/Threading/ParallelForEach.hpp | 10 +- src/xrCore/Threading/Task.cpp | 36 ------- src/xrCore/Threading/Task.hpp | 116 +++++++++++++++++++---- src/xrCore/Threading/TaskManager.cpp | 76 ++++----------- src/xrCore/Threading/TaskManager.hpp | 49 +++++++--- src/xrCore/xrCore.vcxproj | 1 - src/xrCore/xrCore.vcxproj.filters | 3 - src/xrEngine/device.cpp | 18 ++-- src/xrEngine/device.h | 3 - src/xrEngine/x_ray.cpp | 8 +- src/xrGame/GamePersistent.cpp | 5 +- src/xrSound/SoundRender_Emitter.cpp | 32 +++---- src/xrSound/SoundRender_Emitter.h | 1 - 23 files changed, 268 insertions(+), 273 deletions(-) delete mode 100644 src/xrCore/Threading/Task.cpp diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index 4186a3dec89..3e0c969a306 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -431,34 +431,32 @@ void CDetailManager::Render(CBackend& cmd_list) RImplementation.BasicStats.DetailRender.End(); } -void CDetailManager::MT_CALC(Task&, void*) +void CDetailManager::DispatchMTCalc() { + m_calc_task = &TaskScheduler->AddTask([this] + { #ifndef _EDITOR - if (nullptr == RImplementation.Details) - return; // possibly deleted - if (nullptr == dtFS) - return; - if (!psDeviceFlags.is(rsDrawDetails)) - return; + if (nullptr == RImplementation.Details) + return; // possibly deleted + if (nullptr == dtFS) + return; + if (!psDeviceFlags.is(rsDrawDetails)) + return; #endif - ZoneScoped; - - EYE = Device.vCameraPosition; + ZoneScoped; - const int s_x = iFloor(EYE.x / dm_slot_size + .5f); - const int s_z = iFloor(EYE.z / dm_slot_size + .5f); + EYE = Device.vCameraPosition; - RImplementation.BasicStats.DetailCache.Begin(); - cache_Update(s_x, s_z, EYE, dm_max_decompress); - RImplementation.BasicStats.DetailCache.End(); + const int s_x = iFloor(EYE.x / dm_slot_size + .5f); + const int s_z = iFloor(EYE.z / dm_slot_size + .5f); - UpdateVisibleM(); -} + RImplementation.BasicStats.DetailCache.Begin(); + cache_Update(s_x, s_z, EYE, dm_max_decompress); + RImplementation.BasicStats.DetailCache.End(); -void CDetailManager::DispatchMTCalc() -{ - m_calc_task = &TaskScheduler->AddTask({ this, &CDetailManager::MT_CALC }); + UpdateVisibleM(); + }); } void CDetailManager::details_clear() diff --git a/src/Layers/xrRender/DetailManager.h b/src/Layers/xrRender/DetailManager.h index 69dcf2bd53e..8c5df9f57b7 100644 --- a/src/Layers/xrRender/DetailManager.h +++ b/src/Layers/xrRender/DetailManager.h @@ -227,7 +227,6 @@ class ECORE_API CDetailManager /// MT stuff Task* m_calc_task{}; - void MT_CALC(Task&, void*); void DispatchMTCalc(); CDetailManager(); diff --git a/src/Layers/xrRender/HOM.cpp b/src/Layers/xrRender/HOM.cpp index 93f8fe24e00..4118dec5f60 100644 --- a/src/Layers/xrRender/HOM.cpp +++ b/src/Layers/xrRender/HOM.cpp @@ -267,13 +267,16 @@ void CHOM::Render(CFrustum& base) stats.Total.End(); } -void CHOM::MT_RENDER(Task& /*thisTask*/, void* /*data*/) +Task& CHOM::DispatchMTRender() { - ZoneScoped; - CFrustum ViewBase; - ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB + FRUSTUM_P_FAR); - Enable(); - Render(ViewBase); + return TaskManager::AddTask([this] + { + ZoneScoped; + CFrustum ViewBase; + ViewBase.CreateFromMatrix(Device.mFullTransform, FRUSTUM_P_LRTB + FRUSTUM_P_FAR); + Enable(); + Render(ViewBase); + }); } ICF BOOL xform_b0(Fvector2& min, Fvector2& max, float& minz, const Fmatrix& X, float _x, float _y, float _z) diff --git a/src/Layers/xrRender/HOM.h b/src/Layers/xrRender/HOM.h index 45dc4a0c37d..b02f295f6f5 100644 --- a/src/Layers/xrRender/HOM.h +++ b/src/Layers/xrRender/HOM.h @@ -51,7 +51,7 @@ class CHOM void Disable(); void Enable(); - void MT_RENDER(Task& /*thisTask*/, void* /*data*/); + Task& DispatchMTRender(); BOOL visible(vis_data& vis) const; BOOL visible(const Fbox3& B) const; diff --git a/src/Layers/xrRenderDX11/dx11HW.cpp b/src/Layers/xrRenderDX11/dx11HW.cpp index 011d8d4d0a8..fbc9caeace8 100644 --- a/src/Layers/xrRenderDX11/dx11HW.cpp +++ b/src/Layers/xrRenderDX11/dx11HW.cpp @@ -221,10 +221,10 @@ void CHW::CreateDevice(SDL_Window* sdlWnd) // Register immediate context in profiler if (ThisInstanceIsGlobal()) { - TaskScheduler->AddTask([](Task&, void*) + TaskScheduler->AddTask([this] { ZoneScopedN("TracyD3D11Context"); - HW.profiler_ctx = TracyD3D11Context(HW.pDevice, HW.get_context(CHW::IMM_CTX_ID)); + profiler_ctx = TracyD3D11Context(pDevice, get_context(CHW::IMM_CTX_ID)); }); } diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index b6196651f5c..196cb2f0015 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -649,7 +649,7 @@ void CRender::OnCameraUpdated() if (g_pGamePersistent->MainMenuActiveOrLevelNotExist()) return; - ProcessHOMTask = &TaskScheduler->AddTask({ &HOM, &CHOM::MT_RENDER }); + ProcessHOMTask = &HOM.DispatchMTRender(); if (Details) Details->DispatchMTCalc(); } diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index a13e5152da5..209d345390a 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -44,7 +44,18 @@ struct i_render_phase if (!o.active) return; - main_task = &TaskScheduler->CreateTask({ this, &i_render_phase::calculate_task }); + main_task = &TaskScheduler->CreateTask([this] + { + calculate(); + + if (o.mt_draw_enabled) + { + draw_task = &TaskScheduler->AddTask(*main_task, [this] + { + render(); + }); + } + }); if (o.mt_calc_enabled) { @@ -78,21 +89,6 @@ struct i_render_phase o.active = false; } - void calculate_task(Task&, void*) - { - calculate(); - - if (o.mt_draw_enabled) - { - draw_task = &TaskScheduler->AddTask(*main_task, { this, &i_render_phase::render_task }); - } - } - - void render_task(Task&, void*) - { - render(); - } - virtual void init() = 0; virtual void calculate() = 0; virtual void render() = 0; diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index c9792cbfc01..5b1f76a6ce8 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -111,27 +111,6 @@ void CRender::render_lights(light_Package& LP) static xr_vector lights_queue{}; lights_queue.reserve(R__NUM_SUN_CASCADES); - const auto &calc_lights = [](Task &, void* data) - { - ZoneScopedN("calc lights"); - const auto* task_data = static_cast(data); - auto& dsgraph = RImplementation.get_context(task_data->batch_id); - { - auto* L = task_data->L; - - L->svis[task_data->batch_id].begin(); - - dsgraph.o.phase = PHASE_SMAP; - dsgraph.r_pmask(true, RImplementation.o.Tshadows); - dsgraph.o.sector_id = L->spatial.sector_id; - dsgraph.o.view_pos = L->position; - dsgraph.o.xform = L->X.S.combine; - dsgraph.o.view_frustum.CreateFromMatrix(L->X.S.combine, FRUSTUM_P_ALL & (~FRUSTUM_P_NEAR)); - - dsgraph.build_subspace(); - } - }; - const auto& flush_lights = [&]() { ZoneScopedN("flush lights"); @@ -217,11 +196,32 @@ void CRender::render_lights(light_Package& LP) source.pop_back(); Lights_LastFrame.push_back(L); - // calculate task_data_t data; + + const auto& calc_lights = [&data] + { + ZoneScopedN("calc lights"); + auto& dsgraph = RImplementation.get_context(data.batch_id); + { + auto* L = data.L; + + L->svis[data.batch_id].begin(); + + dsgraph.o.phase = PHASE_SMAP; + dsgraph.r_pmask(true, RImplementation.o.Tshadows); + dsgraph.o.sector_id = L->spatial.sector_id; + dsgraph.o.view_pos = L->position; + dsgraph.o.xform = L->X.S.combine; + dsgraph.o.view_frustum.CreateFromMatrix(L->X.S.combine, FRUSTUM_P_ALL & (~FRUSTUM_P_NEAR)); + + dsgraph.build_subspace(); + } + }; + + // calculate data.batch_id = batch_id; data.L = L; - data.task = &TaskScheduler->CreateTask(calc_lights, sizeof(data), (void*)&data); + data.task = &TaskScheduler->CreateTask(calc_lights); if (o.mt_calculate) { TaskScheduler->PushTask(*data.task); diff --git a/src/xrCore/CMakeLists.txt b/src/xrCore/CMakeLists.txt index 65a48e46417..0b0b1253eba 100644 --- a/src/xrCore/CMakeLists.txt +++ b/src/xrCore/CMakeLists.txt @@ -401,7 +401,6 @@ target_sources_grouped( Threading/ParallelForEach.hpp Threading/ScopeLock.cpp Threading/ScopeLock.hpp - Threading/Task.cpp Threading/Task.hpp Threading/TaskManager.cpp Threading/TaskManager.hpp diff --git a/src/xrCore/Threading/ParallelFor.hpp b/src/xrCore/Threading/ParallelFor.hpp index a1664b3da1e..d6ced48c433 100644 --- a/src/xrCore/Threading/ParallelFor.hpp +++ b/src/xrCore/Threading/ParallelFor.hpp @@ -126,17 +126,15 @@ class TaskRange size_t m_grain{ 1 }; }; -namespace details +namespace detail { template -class ParallelForTask +class ParallelFor { public: static decltype(auto) Run(const Range& range, bool wait, const Function& function) { - TaskData taskData{ range, function }; - - auto& task = TaskManager::AddTask(task_func, sizeof(TaskData), &taskData); + auto& task = TaskManager::AddTask(Functor{ range, function }); if (wait) { VERIFY2(TaskScheduler, "Task scheduler is not yet created. " @@ -148,43 +146,39 @@ class ParallelForTask } private: - static void task_func(Task& thisTask, void* data_ptr) + struct Functor { - auto& data = *static_cast(data_ptr); - auto& range = data.range; + Range range; + Function function; - if (range.is_splittable()) - { - TaskData leftData{ TaskRange(range, SplitTaskRange()), data.function }; - TaskManager::AddTask(thisTask, task_func, sizeof(TaskData), &leftData); - TaskManager::AddTask(thisTask, task_func, sizeof(TaskData), &data); - } - else + void operator()(Task& task) { - data.function(range); + if (range.is_splittable()) + { + Functor left{ TaskRange(range, SplitTaskRange()), function }; + TaskManager::AddTask(task, left); + TaskManager::AddTask(task, *this); + } + else + { + function(range); + } } - } - -private: - struct TaskData - { - Range range; - const Function function; }; }; -} // namespace details +} // namespace detail // User can specify if he wants caller thread to wait on the task finish template decltype(auto) xr_parallel_for(const Range& range, bool wait, const Function& function) { - return details::ParallelForTask::Run(range, wait, function); + return detail::ParallelFor::Run(range, wait, function); } // Caller thread will wait on the task finish template decltype(auto) xr_parallel_for(const Range& range, const Function& function) { - return details::ParallelForTask::Run(range, true, function); + return detail::ParallelFor::Run(range, true, function); } diff --git a/src/xrCore/Threading/ParallelForEach.hpp b/src/xrCore/Threading/ParallelForEach.hpp index 0795ec04170..23b0a98ac75 100644 --- a/src/xrCore/Threading/ParallelForEach.hpp +++ b/src/xrCore/Threading/ParallelForEach.hpp @@ -17,9 +17,9 @@ #include "ParallelFor.hpp" -namespace details +namespace detail { -class ParallelForEachTask +class ParallelForEach { public: template @@ -34,18 +34,18 @@ class ParallelForEachTask }); } }; -} // namespace details +} // namespace detail // User can specify if he wants caller thread to wait on the task finish template decltype(auto) xr_parallel_for_each(Range& range, bool wait, const Function& function) { - return details::ParallelForEachTask::Run(std::begin(range), std::end(range), wait, function); + return detail::ParallelForEach::Run(std::begin(range), std::end(range), wait, function); } // Caller thread will wait on the task finish template decltype(auto) xr_parallel_for_each(Range& range, const Function& function) { - return details::ParallelForEachTask::Run(std::begin(range), std::end(range), true, function); + return detail::ParallelForEach::Run(std::begin(range), std::end(range), true, function); } diff --git a/src/xrCore/Threading/Task.cpp b/src/xrCore/Threading/Task.cpp deleted file mode 100644 index b5e40ebb9c0..00000000000 --- a/src/xrCore/Threading/Task.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (c) 2014-2021 OpenXRay - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -#include "stdafx.h" - -#include "Task.hpp" - -Task::Data::Data(const TaskFunc& task, Task* parent) - : task_func(task), parent(parent), jobs(1) {} - -Task::Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent /*= nullptr*/) - : m_data(task, parent) -{ - VERIFY2(dataSize <= sizeof(m_user_data), "Cannot fit your data in the task"); - if (data && dataSize) - { - CopyMemory(m_user_data, data, std::min(dataSize, sizeof(m_user_data))); - } -} - -void Task::Execute() -{ - m_data.task_func(*this, m_user_data); -} diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 2dbf2a90290..5d4fecd8f1f 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -38,56 +38,134 @@ class XRCORE_API Task final : Noncopyable { friend class TaskManager; friend class TaskAllocator; - friend class FallbackTaskAllocator; - -public: - using TaskFunc = fastdelegate::FastDelegate; private: + using CallFunc = void(Task&); + // ordered from biggest to smallest struct Data { - TaskFunc task_func{}; - Task* parent{}; - std::atomic_int16_t jobs{}; // at least 1 (task itself), zero means task is done. + Task* parent; + CallFunc* m_call; + std::atomic_int16_t jobs; // at least 1 (task itself), zero means task is done. + bool contains_result; Data() = default; - Data(const TaskFunc& task, Task* parent); - } m_data; + Data(CallFunc* call, Task* parent) + : parent(parent), m_call(call), jobs(1), contains_result(false) {} + }; - static constexpr size_t USER_DATA_SIZE = TASK_SIZE - sizeof(m_data); + static constexpr size_t USER_DATA_SIZE = TASK_SIZE - sizeof(Data); std::byte m_user_data[USER_DATA_SIZE]; + Data m_data; + + template > + struct Dispatcher + { + static constexpr bool task_unaware = std::is_invocable_v; + + static_assert(TaskAware || task_unaware, + "Provide callable with type: void() or void(Task&) or T() or T(Task&), " + "where T is any result of your function."); + }; + + template + struct Dispatcher + { + static void Call(Task& task) + { + auto& obj = *reinterpret_cast(task.m_user_data); + obj(task); + if constexpr (!std::is_trivially_copyable_v) + obj.~Invokable(); + } + }; + + template + struct Dispatcher + { + static void Call(Task& task) + { + auto& obj = *reinterpret_cast(task.m_user_data); + obj(); + if constexpr (!std::is_trivially_copyable_v) + obj.~Invokable(); + } + }; private: - // Used by TaskAllocator as Task initial state - Task() = default; + Task() = default; // used by TaskAllocator as Task initial state - // Will just execute - Task(const TaskFunc& task, void* data, size_t dataSize, Task* parent = nullptr); + template + Task(Invokable func, Task* parent = nullptr) + : m_data(&Dispatcher::Call, parent) + { + static_assert(sizeof(Invokable) <= USER_DATA_SIZE, + "Not enough storage to save your functor/lambda. Try to reduce its size."); + + if constexpr (!std::is_empty_v || !std::is_trivially_copyable_v) + { + ::new (m_user_data) Invokable(std::move(func)); + } + + if (parent) + { + VERIFY2(parent->m_data.jobs.load(std::memory_order_relaxed) > 0, "Adding child task to a parent that has already finished."); + [[maybe_unused]] const auto prev = parent->m_data.jobs.fetch_add(1, std::memory_order_acq_rel); + VERIFY2(prev != std::numeric_limits::max(), "Max jobs overflow. (too much children)"); + } + } public: - static constexpr size_t GetAvailableDataStorageSize() + Task(Task&&) = delete; + Task(const Task&) = delete; + Task& operator=(Task&&) = delete; + Task& operator=(const Task&) = delete; + + [[nodiscard]] + static constexpr size_t AvailableDataStorageSize() noexcept { return sizeof(m_user_data); } - Task* GetParent() const + [[nodiscard]] + auto GetParent() const noexcept { return m_data.parent; } - auto GetJobsCount() const + template + [[nodiscard]] + const T* GetData() const noexcept + { + return static_cast(m_user_data); + } + + [[nodiscard]] + auto GetJobsCount() const noexcept { return m_data.jobs.load(std::memory_order_relaxed); } - bool IsFinished() const + [[nodiscard]] + bool IsFinished() const noexcept { return GetJobsCount() == 0; } private: // Called by TaskManager - void Execute(); + void operator()() + { + m_data.m_call(*this); + + for (Task* it = this; ; it = it->m_data.parent) + { + const auto unfinishedJobs = it->m_data.jobs.fetch_sub(1, std::memory_order_acq_rel) - 1; // fetch_sub returns previous value + VERIFY2(unfinishedJobs >= 0, "The same task was executed two times."); + if (unfinishedJobs || !it->m_data.parent) + break; + } + } }; diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 8a630595c46..d58c23449fd 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -72,7 +72,7 @@ class TaskAllocator Task m_storage[TASK_STORAGE_SIZE]; public: - Task* allocate() + Task* allocate() noexcept { Task* task = &m_storage[m_allocated++ & TASK_STORAGE_MASK]; VERIFY(task->IsFinished()); @@ -89,14 +89,14 @@ class TaskQueue Task* m_storage[TASK_STORAGE_SIZE]{}; public: - void push(Task* task) + void push(Task* task) noexcept { const auto task_pos = m_tail_pos.fetch_add(1, std::memory_order_acq_rel); VERIFY2(task_pos - m_head_pos.load(std::memory_order_acquire) < TASK_STORAGE_SIZE, "Task queue overflow"); m_storage[task_pos & TASK_STORAGE_MASK] = task; } - Task* pop() + Task* pop() noexcept { size_t head_pos = m_head_pos.load(std::memory_order_acquire); Task* task = m_storage[head_pos & TASK_STORAGE_MASK]; @@ -112,17 +112,17 @@ class TaskQueue return nullptr; } - Task* steal() + Task* steal() noexcept { return pop(); } - size_t size() const + size_t size() const noexcept { return m_head_pos - m_tail_pos; } - bool empty() const + bool empty() const noexcept { return size() == 0; } @@ -143,7 +143,6 @@ class TaskWorker : public TaskQueue, public TaskWorkerStats size_t id { size_t(-1) }; } static thread_local s_tl_worker; - TaskManager::TaskManager() { ZoneScoped; @@ -213,7 +212,7 @@ void TaskManager::UnregisterThisThreadAsWorker() shouldPause.store(false, std::memory_order_release); } -void TaskManager::SetThreadStatus(bool active) +void TaskManager::SetThreadStatus(bool active) noexcept { if (active) activeWorkersCount.fetch_add(1, std::memory_order_relaxed); @@ -283,41 +282,25 @@ Task* TaskManager::TryToSteal() const return nullptr; } -void TaskManager::ExecuteTask(Task& task) -{ - task.Execute(); - - // Finalize - for (Task* it = &task; ; it = it->m_data.parent) - { - const auto unfinishedJobs = it->m_data.jobs.fetch_sub(1, std::memory_order_acq_rel) - 1; // fetch_sub returns previous value - VERIFY2(unfinishedJobs >= 0, "The same task was executed two times."); - if (unfinishedJobs || !it->m_data.parent) - break; - } - ++s_tl_worker.finishedTasks; -} - -Task* TaskManager::AllocateTask() +Task* TaskManager::AllocateTask() noexcept { ++s_tl_worker.allocatedTasks; return s_tl_allocator.allocate(); } -void TaskManager::IncrementTaskJobsCounter(Task& parent) -{ - VERIFY2(parent.m_data.jobs.load(std::memory_order_relaxed) > 0, "Adding child task to a parent that has already finished."); - [[maybe_unused]] const auto prev = parent.m_data.jobs.fetch_add(1, std::memory_order_acq_rel); - VERIFY2(prev != std::numeric_limits::max(), "Max jobs overflow. (too much children)"); -} - -void TaskManager::PushTask(Task& task) +void TaskManager::PushTask(Task& task) noexcept { s_tl_worker.push(&task); newWorkArrived.notify_one(); ++s_tl_worker.pushedTasks; } +void TaskManager::ExecuteTask(Task& task) +{ + task(); + ++s_tl_worker.finishedTasks; +} + void TaskManager::RunTask(Task& task) { ExecuteTask(task); @@ -352,37 +335,12 @@ bool TaskManager::ExecuteOneTask() const return false; } -Task& TaskManager::CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - return *new (AllocateTask()) Task(taskFunc, data, dataSize); -} - -Task& TaskManager::CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - IncrementTaskJobsCounter(parent); - return *new (AllocateTask()) Task(taskFunc, data, dataSize, &parent); -} - -Task& TaskManager::AddTask(const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - auto& task = CreateTask(taskFunc, dataSize, data); - PushTask(task); - return task; -} - -Task& TaskManager::AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize /*= 0*/, void* data /*= nullptr*/) -{ - auto& task = CreateTask(parent, taskFunc, dataSize, data); - PushTask(task); - return task; -} - -size_t TaskManager::GetWorkersCount() const +size_t TaskManager::GetWorkersCount() const noexcept { return workers.size(); } -size_t TaskManager::GetCurrentWorkerID() +size_t TaskManager::GetCurrentWorkerID() noexcept { return s_tl_worker.id; } diff --git a/src/xrCore/Threading/TaskManager.hpp b/src/xrCore/Threading/TaskManager.hpp index da766d4a9ce..8e2c18b1aed 100644 --- a/src/xrCore/Threading/TaskManager.hpp +++ b/src/xrCore/Threading/TaskManager.hpp @@ -41,50 +41,69 @@ class XRCORE_API TaskManager final [[nodiscard]] Task* TryToSteal() const; - static void ExecuteTask(Task& task); + [[nodiscard]] static Task* AllocateTask() noexcept; - [[nodiscard]] ICF static Task* AllocateTask(); - static void ICF IncrementTaskJobsCounter(Task& parent); + static void ExecuteTask(Task& task); - void SetThreadStatus(bool active); + void SetThreadStatus(bool active) noexcept; public: TaskManager(); ~TaskManager(); + void SpawnThreads(); + void RegisterThisThreadAsWorker(); + void UnregisterThisThreadAsWorker(); + public: - // TaskFunc is at the end for fancy in-place lambdas // Create a task, but don't run it yet - [[nodiscard]] static Task& CreateTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + template + [[nodiscard]] static Task& CreateTask(Invokable func) + { + return *new (AllocateTask()) Task(func); + } // Create a task as child, but don't run it yet - [[nodiscard]] static Task& CreateTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + template + [[nodiscard]] static Task& CreateTask(Task& parent, Invokable func) + { + return *new (AllocateTask()) Task(func, &parent); + } // Run task in parallel - static void PushTask(Task& task); + static void PushTask(Task& task) noexcept; // Run task immediately in this thread static void RunTask(Task& task); // Shortcut: create a task and run it immediately - static Task& AddTask(const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + template + static Task& AddTask(Invokable func) + { + Task& task = CreateTask(func); + PushTask(task); + return task; + } // Shortcut: create task and run it immediately - static Task& AddTask(Task& parent, const Task::TaskFunc& taskFunc, size_t dataSize = 0, void* data = nullptr); + template + static Task& AddTask(Task& parent, Invokable func) + { + Task& task = CreateTask(parent, func); + PushTask(task); + return task; + } public: - void RegisterThisThreadAsWorker(); - void UnregisterThisThreadAsWorker(); - void Wait(const Task& task) const; bool ExecuteOneTask() const; void Pause(bool pause) { shouldPause.store(pause, std::memory_order_release); } public: - [[nodiscard]] size_t GetWorkersCount() const; - [[nodiscard]] static size_t GetCurrentWorkerID(); + [[nodiscard]] size_t GetWorkersCount() const noexcept; + [[nodiscard]] static size_t GetCurrentWorkerID() noexcept; void GetStats(size_t& allocated, size_t& pushed, size_t& finished); }; diff --git a/src/xrCore/xrCore.vcxproj b/src/xrCore/xrCore.vcxproj index 51a7ef8bf42..ca65ec59d39 100644 --- a/src/xrCore/xrCore.vcxproj +++ b/src/xrCore/xrCore.vcxproj @@ -95,7 +95,6 @@ call .GitInfo.cmd - diff --git a/src/xrCore/xrCore.vcxproj.filters b/src/xrCore/xrCore.vcxproj.filters index 7dbe6b5aef3..fe36c775c15 100644 --- a/src/xrCore/xrCore.vcxproj.filters +++ b/src/xrCore/xrCore.vcxproj.filters @@ -309,9 +309,6 @@ Crypto - - Threading - Threading diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 9e5b846733a..bf583b70702 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -257,15 +257,6 @@ void CRenderDevice::DoRender() stats.RenderTotal.accum = renderTotalReal.accum; } -void CRenderDevice::ProcessParallelSequence(Task&, void*) -{ - ZoneScoped; - for (u32 pit = 0; pit < seqParallel.size(); pit++) - seqParallel[pit](); - seqParallel.clear(); - seqFrameMT.Process(); -} - void CRenderDevice::ProcessFrame() { ZoneScoped; @@ -279,7 +270,14 @@ void CRenderDevice::ProcessFrame() OnCameraUpdated(); - const auto& processSeqParallel = TaskScheduler->AddTask({ this, &CRenderDevice::ProcessParallelSequence }); + const auto& processSeqParallel = TaskScheduler->AddTask([this] + { + ZoneScopedN("ProcessParallelSequence"); + for (u32 pit = 0; pit < seqParallel.size(); pit++) + seqParallel[pit](); + seqParallel.clear(); + seqFrameMT.Process(); + }); DoRender(); diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 996a7b1cb3f..424386ab24c 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -163,9 +163,6 @@ class ENGINE_API CRenderDevice : public IWindowHandler void Pause(bool bOn, bool bTimer, bool bSound, pcstr reason); bool Paused(); -private: - void ProcessParallelSequence(Task&, void*); - public: // Scene control void ProcessFrame(); diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 342abc03ca3..35d2fa228c5 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -228,19 +228,19 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) ShowSplash(topmost); } - const auto& inputTask = TaskManager::AddTask([](Task&, void*) + const auto& inputTask = TaskManager::AddTask([] { const bool captureInput = !strstr(Core.Params, "-i"); pInput = xr_new(captureInput); }); - const auto& createSoundDevicesList = TaskManager::AddTask([](Task&, void*) + const auto& createSoundDevicesList = TaskManager::AddTask([] { Engine.Sound.CreateDevicesList(); }); #ifdef XR_PLATFORM_WINDOWS - const auto& createRendererList = TaskManager::AddTask([](Task&, void*) + const auto& createRendererList = TaskManager::AddTask([] { Engine.External.CreateRendererList(); }); @@ -294,7 +294,7 @@ CApplication::CApplication(pcstr commandLine, GameModule* game) Console->Execute(loadArgs + 1); // Initialize APP - const auto& createLightAnim = TaskScheduler->AddTask([](Task&, void*) + const auto& createLightAnim = TaskScheduler->AddTask([] { LALib.OnCreate(); }); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 57280a32b2d..ba091312b6a 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -112,10 +112,7 @@ void CGamePersistent::OnAppStart() #ifndef XR_PLATFORM_WINDOWS init_game_globals(); #else - const auto& initializeGlobals = TaskScheduler->AddTask([](Task&, void*) - { - init_game_globals(); - }); + const auto& initializeGlobals = TaskScheduler->AddTask(init_game_globals); #endif GEnv.UI = xr_new(); diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 048ee102a98..7452608e8c6 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -248,29 +248,29 @@ void CSoundRender_Emitter::fill_all_blocks() filled_blocks = sdef_target_count; } -void CSoundRender_Emitter::prefill_blocks(Task&, void*) +void CSoundRender_Emitter::dispatch_prefill() { - size_t next_block_to_fill = (current_block + filled_blocks) % sdef_target_count; + wait_prefill(); + if (filled_blocks >= sdef_target_count) + return; - while (filled_blocks < sdef_target_count) + const auto task = &TaskScheduler->AddTask([this] { - auto& block = temp_buf[next_block_to_fill]; + size_t next_block_to_fill = (current_block + filled_blocks) % sdef_target_count; - fill_block(block.data(), block.size()); + while (filled_blocks < sdef_target_count) + { + auto& block = temp_buf[next_block_to_fill]; - next_block_to_fill = (next_block_to_fill + 1) % sdef_target_count; - filled_blocks++; - } + fill_block(block.data(), block.size()); - prefill_task.store(nullptr, std::memory_order_release); -} + next_block_to_fill = (next_block_to_fill + 1) % sdef_target_count; + filled_blocks++; + } + + prefill_task.store(nullptr, std::memory_order_release); + }); -void CSoundRender_Emitter::dispatch_prefill() -{ - wait_prefill(); - if (filled_blocks >= sdef_target_count) - return; - const auto task = &TaskScheduler->AddTask({ this, &CSoundRender_Emitter::prefill_blocks }); prefill_task.store(task, std::memory_order_release); } diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index bb1646c0c03..e9954071253 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -87,7 +87,6 @@ class CSoundRender_Emitter final : public CSound_emitter void fill_data(void* dest, u32 offset, u32 size) const; void fill_all_blocks(); - void prefill_blocks(Task&, void*); void dispatch_prefill(); void wait_prefill() const; From 2495753ee47bff499ada7bc0e27e297a7b41ea03 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 20 May 2024 01:51:17 +0500 Subject: [PATCH 425/497] Fix crashes due to dangling reference --- src/Layers/xrRender_R2/r2_R_lights.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 5b1f76a6ce8..40d3bed7324 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -104,9 +104,9 @@ void CRender::render_lights(light_Package& LP) struct task_data_t { - light* L; - Task* task; - u32 batch_id; + light* L{}; + Task* task{}; + u32 batch_id{}; }; static xr_vector lights_queue{}; lights_queue.reserve(R__NUM_SUN_CASCADES); @@ -196,9 +196,11 @@ void CRender::render_lights(light_Package& LP) source.pop_back(); Lights_LastFrame.push_back(L); - task_data_t data; + task_data_t data{}; + data.batch_id = batch_id; + data.L = L; - const auto& calc_lights = [&data] + const auto& calc_lights = [data] { ZoneScopedN("calc lights"); auto& dsgraph = RImplementation.get_context(data.batch_id); @@ -219,8 +221,6 @@ void CRender::render_lights(light_Package& LP) }; // calculate - data.batch_id = batch_id; - data.L = L; data.task = &TaskScheduler->CreateTask(calc_lights); if (o.mt_calculate) { From f1d9682a231146d067f0a6464578520e43462f1e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 20 May 2024 01:52:54 +0500 Subject: [PATCH 426/497] Layers/xrRender_R2/r2_R_lights.cpp: call task function directly --- src/Layers/xrRender_R2/r2_R_lights.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 40d3bed7324..06903e21139 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -116,8 +116,8 @@ void CRender::render_lights(light_Package& LP) ZoneScopedN("flush lights"); for (const auto& [L, task, batch_id] : lights_queue) { - VERIFY(task); - TaskScheduler->Wait(*task); + if (task) + TaskScheduler->Wait(*task); auto& dsgraph = get_context(batch_id); @@ -221,14 +221,13 @@ void CRender::render_lights(light_Package& LP) }; // calculate - data.task = &TaskScheduler->CreateTask(calc_lights); if (o.mt_calculate) { - TaskScheduler->PushTask(*data.task); + data.task = &TaskScheduler->AddTask(calc_lights); } else { - TaskScheduler->RunTask(*data.task); + calc_lights(); } lights_queue.emplace_back(data); } From 20406503d0f80887c339d76a2cd604fb0fd47e02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 12:47:25 +0000 Subject: [PATCH 427/497] build(deps): bump Externals/sse2neon from `ab7a347` to `de0538f` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `ab7a347` to `de0538f`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/ab7a34794507332edfa93b824b256f41e43f9e31...de0538f21662353aadb74abd91634e3f8f5bbd85) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index ab7a3479450..de0538f2166 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit ab7a34794507332edfa93b824b256f41e43f9e31 +Subproject commit de0538f21662353aadb74abd91634e3f8f5bbd85 From 1dcf54608f46b17eed05862f3f875d769bfa1ed5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 23 May 2024 01:34:43 +0500 Subject: [PATCH 428/497] Add support for precise mouse scroll values from SDL 2.0.18 --- src/xrEngine/IInputReceiver.h | 2 +- src/xrEngine/editor_base.h | 2 +- src/xrEngine/editor_base_input.cpp | 4 ++-- src/xrEngine/xr_input.cpp | 15 +++++++++++++++ src/xrGame/Actor.h | 2 +- src/xrGame/ActorInput.cpp | 4 ++-- src/xrGame/Level.h | 2 +- src/xrGame/Level_input.cpp | 2 +- src/xrGame/MainMenu.cpp | 2 +- src/xrGame/MainMenu.h | 2 +- src/xrGame/UIDialogHolder.cpp | 5 ++--- src/xrGame/UIDialogHolder.h | 2 +- src/xrGame/ui/UIGameTutorial.cpp | 2 +- src/xrGame/ui/UIGameTutorial.h | 2 +- 14 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/xrEngine/IInputReceiver.h b/src/xrEngine/IInputReceiver.h index 8265f51639b..f839d73df41 100644 --- a/src/xrEngine/IInputReceiver.h +++ b/src/xrEngine/IInputReceiver.h @@ -31,7 +31,7 @@ class ENGINE_API IInputReceiver virtual void IR_OnMousePress(int /*btn*/) {} virtual void IR_OnMouseRelease(int /*btn*/) {} virtual void IR_OnMouseHold(int /*btn*/) {} - virtual void IR_OnMouseWheel(int /*x*/, int /*y*/) {} + virtual void IR_OnMouseWheel(float /*x*/, float /*y*/) {} virtual void IR_OnMouseMove(int /*x*/, int /*y*/) {} virtual void IR_OnKeyboardPress(int /*dik*/) {} diff --git a/src/xrEngine/editor_base.h b/src/xrEngine/editor_base.h index 3ca2f6f17f3..fbc728bea9c 100644 --- a/src/xrEngine/editor_base.h +++ b/src/xrEngine/editor_base.h @@ -74,7 +74,7 @@ class ENGINE_API ide final : void IR_OnMousePress(int key) override; void IR_OnMouseRelease(int key) override; void IR_OnMouseHold(int key) override; - void IR_OnMouseWheel(int x, int y) override; + void IR_OnMouseWheel(float x, float y) override; void IR_OnMouseMove(int x, int y) override; void IR_OnKeyboardPress(int key) override; diff --git a/src/xrEngine/editor_base_input.cpp b/src/xrEngine/editor_base_input.cpp index 57c0912e546..ddb00f51ae8 100644 --- a/src/xrEngine/editor_base_input.cpp +++ b/src/xrEngine/editor_base_input.cpp @@ -275,10 +275,10 @@ void ide::IR_OnMouseHold(int /*key*/) // ImGui handles hold state on its own } -void ide::IR_OnMouseWheel(int x, int y) +void ide::IR_OnMouseWheel(float x, float y) { ImGuiIO& io = ImGui::GetIO(); - io.AddMouseWheelEvent(static_cast(x), static_cast(y)); + io.AddMouseWheelEvent(x, y); } void ide::IR_OnMouseMove(int /*x*/, int /*y*/) diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index 9b91893cbef..52502204343 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -134,7 +134,12 @@ void CInput::MouseUpdate() static_assert(std::size(IdxToKey) == COUNT_MOUSE_BUTTONS); bool mouseMoved = false; +#if SDL_VERSION_ATLEAST(2, 0, 18) + int offs[2]{}; + float scroll[2]{}; +#else int offs[COUNT_MOUSE_AXIS]{}; +#endif const auto mousePrev = mouseState; mouseAxisState[2] = 0; mouseAxisState[3] = 0; @@ -177,8 +182,13 @@ void CInput::MouseUpdate() } case SDL_MOUSEWHEEL: mouseMoved = true; +#if SDL_VERSION_ATLEAST(2, 0, 18) + scroll[0] += event.wheel.preciseX; + scroll[1] += event.wheel.preciseY; +#else offs[2] += event.wheel.x; offs[3] += event.wheel.y; +#endif mouseAxisState[2] += event.wheel.x; mouseAxisState[3] += event.wheel.y; break; @@ -195,8 +205,13 @@ void CInput::MouseUpdate() { if (offs[0] || offs[1]) cbStack.back()->IR_OnMouseMove(offs[0], offs[1]); +#if SDL_VERSION_ATLEAST(2, 0, 18) + if (!fis_zero(scroll[0]) || !fis_zero(scroll[1])) + cbStack.back()->IR_OnMouseWheel(scroll[0], scroll[1]); +#else if (offs[2] || offs[3]) cbStack.back()->IR_OnMouseWheel(offs[2], offs[3]); +#endif } } diff --git a/src/xrGame/Actor.h b/src/xrGame/Actor.h index 31d5c73c418..627e7d9f8a5 100644 --- a/src/xrGame/Actor.h +++ b/src/xrGame/Actor.h @@ -446,7 +446,7 @@ class CActor : public CEntityAlive, public: void OnAxisMove(float x, float y, float scale, bool invert); virtual void IR_OnMouseMove(int x, int y); - virtual void IR_OnMouseWheel(int x, int y); + virtual void IR_OnMouseWheel(float x, float y); virtual void IR_OnKeyboardPress(int dik); virtual void IR_OnKeyboardRelease(int dik); diff --git a/src/xrGame/ActorInput.cpp b/src/xrGame/ActorInput.cpp index 8c71356e81f..3c71e5521a2 100644 --- a/src/xrGame/ActorInput.cpp +++ b/src/xrGame/ActorInput.cpp @@ -211,11 +211,11 @@ void CActor::IR_OnKeyboardPress(int cmd) } } -void CActor::IR_OnMouseWheel(int x, int y) +void CActor::IR_OnMouseWheel(float x, float y) { if (hud_adj_mode) { - g_player_hud->tune(Ivector().set(0, 0, y)); + g_player_hud->tune({ 0, 0, static_cast(std::round(y)) }); return; } diff --git a/src/xrGame/Level.h b/src/xrGame/Level.h index 40a7d5af8e6..7085be68127 100644 --- a/src/xrGame/Level.h +++ b/src/xrGame/Level.h @@ -314,7 +314,7 @@ class CLevel : public IGame_Level, public IPureClient void IR_OnMouseRelease(int btn) override; void IR_OnMouseHold(int btn) override; void IR_OnMouseMove(int, int) override; - void IR_OnMouseWheel(int x, int y) override; + void IR_OnMouseWheel(float x, float y) override; void IR_OnControllerPress(int key, float x, float y) override; void IR_OnControllerRelease(int key, float x, float y) override; diff --git a/src/xrGame/Level_input.cpp b/src/xrGame/Level_input.cpp index 373bef6fb30..051199fc076 100644 --- a/src/xrGame/Level_input.cpp +++ b/src/xrGame/Level_input.cpp @@ -43,7 +43,7 @@ extern float g_fTimeFactor; #define CURRENT_ENTITY() (game ? ((GameID() == eGameIDSingle) ? CurrentEntity() : CurrentControlEntity()) : NULL) -void CLevel::IR_OnMouseWheel(int x, int y) +void CLevel::IR_OnMouseWheel(float x, float y) { if (g_bDisableAllInput) return; diff --git a/src/xrGame/MainMenu.cpp b/src/xrGame/MainMenu.cpp index 69e8feb5c2c..8fcc0e06e6f 100644 --- a/src/xrGame/MainMenu.cpp +++ b/src/xrGame/MainMenu.cpp @@ -445,7 +445,7 @@ void CMainMenu::IR_OnTextInput(pcstr text) CDialogHolder::IR_UIOnTextInput(text); } -void CMainMenu::IR_OnMouseWheel(int x, int y) +void CMainMenu::IR_OnMouseWheel(float x, float y) { if (!IsActive()) return; diff --git a/src/xrGame/MainMenu.h b/src/xrGame/MainMenu.h index a2345895c87..86d9a49bbb3 100644 --- a/src/xrGame/MainMenu.h +++ b/src/xrGame/MainMenu.h @@ -149,7 +149,7 @@ class CMainMenu : public IMainMenu, void IR_OnMousePress(int btn) override; void IR_OnMouseRelease(int btn) override; void IR_OnMouseHold(int btn) override; - void IR_OnMouseWheel(int x, int y) override; + void IR_OnMouseWheel(float x, float y) override; void IR_OnMouseMove(int x, int y) override; void IR_OnKeyboardPress(int dik) override; diff --git a/src/xrGame/UIDialogHolder.cpp b/src/xrGame/UIDialogHolder.cpp index 139ce9de3bb..49a12b7d49f 100644 --- a/src/xrGame/UIDialogHolder.cpp +++ b/src/xrGame/UIDialogHolder.cpp @@ -377,7 +377,7 @@ bool CDialogHolder::IR_UIOnKeyboardHold(int dik) return true; } -bool CDialogHolder::IR_UIOnMouseWheel(int x, int y) +bool CDialogHolder::IR_UIOnMouseWheel(float x, float y) { CUIDialogWnd* TIR = TopInputReceiver(); if (!TIR) @@ -385,8 +385,6 @@ bool CDialogHolder::IR_UIOnMouseWheel(int x, int y) if (!TIR->IR_process()) return false; - Fvector2 pos = GetUICursor().GetCursorPosition(); - // Vertical scroll is in higher priority EUIMessages wheelMessage; if (y > 0) @@ -398,6 +396,7 @@ bool CDialogHolder::IR_UIOnMouseWheel(int x, int y) else wheelMessage = WINDOW_MOUSE_WHEEL_LEFT; + const Fvector2 pos = GetUICursor().GetCursorPosition(); TIR->OnMouseAction(pos.x, pos.y, wheelMessage); return true; } diff --git a/src/xrGame/UIDialogHolder.h b/src/xrGame/UIDialogHolder.h index 33d23ef1690..f227f3e5e6f 100644 --- a/src/xrGame/UIDialogHolder.h +++ b/src/xrGame/UIDialogHolder.h @@ -65,7 +65,7 @@ class CDialogHolder : public pureFrame, public CUIDebuggable virtual bool IgnorePause() { return false; } virtual bool IR_UIOnMouseMove(int dx, int dy); - virtual bool IR_UIOnMouseWheel(int x, int y); + virtual bool IR_UIOnMouseWheel(float x, float y); virtual bool IR_UIOnKeyboardPress(int dik); virtual bool IR_UIOnKeyboardRelease(int dik); diff --git a/src/xrGame/ui/UIGameTutorial.cpp b/src/xrGame/ui/UIGameTutorial.cpp index 651a975f759..b634a1273bd 100644 --- a/src/xrGame/ui/UIGameTutorial.cpp +++ b/src/xrGame/ui/UIGameTutorial.cpp @@ -399,7 +399,7 @@ void CUISequencer::IR_OnKeyboardHold(int dik) m_pStoredInputReceiver->IR_OnKeyboardHold(dik); } -void CUISequencer::IR_OnMouseWheel(int x, int y) +void CUISequencer::IR_OnMouseWheel(float x, float y) { if (!GrabInput() && m_pStoredInputReceiver) m_pStoredInputReceiver->IR_OnMouseWheel(x, y); diff --git a/src/xrGame/ui/UIGameTutorial.h b/src/xrGame/ui/UIGameTutorial.h index f897ddcfb18..0b0ba871d3e 100644 --- a/src/xrGame/ui/UIGameTutorial.h +++ b/src/xrGame/ui/UIGameTutorial.h @@ -54,7 +54,7 @@ class CUISequencer : public pureFrame, public pureRender, public IInputReceiver void IR_OnControllerRelease(int key, float x, float y) override; void IR_OnControllerHold(int key, float x, float y) override; - virtual void IR_OnMouseWheel(int x, int y); + virtual void IR_OnMouseWheel(float x, float y); virtual void IR_OnActivate(void); bool Persistent() { return !!m_flags.test(etsPersistent); } pcstr GetTutorName() { return m_name; } From 6e3a06938ee2d95a301ff870371951e4d92f4d89 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 23 May 2024 19:26:28 +0500 Subject: [PATCH 429/497] UI Focus system WIP (#943) --- res/gamedata/scripts/ui_main_menu.script | 6 +- src/xrGame/UIDialogHolder.cpp | 36 +++--- src/xrGame/UIDialogHolder.h | 3 +- src/xrGame/ui/UIDialogWnd.h | 13 +- src/xrGame/ui/UIMMShniaga.cpp | 1 + src/xrUICore/Buttons/UIButton.cpp | 1 + src/xrUICore/CMakeLists.txt | 2 + src/xrUICore/ComboBox/UIComboBox.cpp | 2 + src/xrUICore/Cursor/UICursor.cpp | 1 + src/xrUICore/EditBox/UICustomEdit.cpp | 2 + src/xrUICore/TrackBar/UITrackBar.cpp | 2 + src/xrUICore/Windows/UIWindow.cpp | 25 ++++ src/xrUICore/Windows/UIWindow.h | 29 +++++ src/xrUICore/Windows/UIWindow_script.cpp | 31 +++++ src/xrUICore/ui_focus.cpp | 153 +++++++++++++++++++++++ src/xrUICore/ui_focus.h | 72 +++++++++++ src/xrUICore/xrUICore.vcxproj | 2 + src/xrUICore/xrUICore.vcxproj.filters | 2 + 18 files changed, 364 insertions(+), 19 deletions(-) create mode 100644 src/xrUICore/ui_focus.cpp create mode 100644 src/xrUICore/ui_focus.h diff --git a/res/gamedata/scripts/ui_main_menu.script b/res/gamedata/scripts/ui_main_menu.script index 514b2af48c7..85b8b66b3fb 100644 --- a/res/gamedata/scripts/ui_main_menu.script +++ b/res/gamedata/scripts/ui_main_menu.script @@ -356,20 +356,22 @@ function main_menu:OnKeyboard(dik, keyboard_action) --virtual function ) then self.OnButton_return_game() --' xStream 02.2008 -- console:execute("main_menu off") --' xStream 02.2008 + return true end end -- if dik == DIK_keys.DIK_S then -- self:OnButton_load_spawn() - +-- return true -- else if dik == DIK_keys.DIK_Q then self:OnMessageQuitWin() + return true end end - return true + return false end function main_menu:OnMenuReloaded() diff --git a/src/xrGame/UIDialogHolder.cpp b/src/xrGame/UIDialogHolder.cpp index 49a12b7d49f..9732c081fe7 100644 --- a/src/xrGame/UIDialogHolder.cpp +++ b/src/xrGame/UIDialogHolder.cpp @@ -55,6 +55,7 @@ void CDialogHolder::StartMenu(CUIDialogWnd* pDialog, bool bDoHideIndicators) CurrentGameUI()->ShowGameIndicators(false); } } + SetFocused(nullptr); pDialog->SetHolder(this); if (pDialog->NeedCursor()) @@ -303,6 +304,25 @@ bool CDialogHolder::IR_UIOnKeyboardPress(int dik) return (false); } } + + /*if (const auto focused = GetFocused()) + { + CUIWindow* target{}; + switch (GetBindedAction(dik, EKeyContext::UI)) + { + case kUI_MOVE_LEFT: target = FindClosestFocusable(focused, FocusDirection::Left); break; + case kUI_MOVE_RIGHT: target = FindClosestFocusable(focused, FocusDirection::Right); break; + case kUI_MOVE_UP: target = FindClosestFocusable(focused, FocusDirection::Up); break; + case kUI_MOVE_DOWN: target = FindClosestFocusable(focused, FocusDirection::Down); break; + } + + if (target) + { + SetFocused(target); + GetUICursor().WarpToWindow(target, true); + } + }*/ + return true; } @@ -444,13 +464,7 @@ bool CDialogHolder::IR_UIOnControllerPress(int dik, float x, float y) if (TIR->OnControllerAction(dik, x, y, WINDOW_KEY_PRESSED)) return true; - if (GetUICursor().IsVisible() && IsBinded(kLOOK_AROUND, dik)) - { - GetUICursor().UpdateCursorPosition(int(std::round(x)), int(std::round(y))); - Fvector2 cPos = GetUICursor().GetCursorPosition(); - TIR->OnMouseAction(cPos.x, cPos.y, WINDOW_MOUSE_MOVE); - } - else if (!TIR->StopAnyMove() && g_pGameLevel) + if (!TIR->StopAnyMove() && g_pGameLevel) { IGameObject* O = Level().CurrentEntity(); if (O) @@ -510,13 +524,7 @@ bool CDialogHolder::IR_UIOnControllerHold(int dik, float x, float y) if (TIR->OnControllerAction(dik, x, y, WINDOW_KEY_HOLD)) return true; - if (GetUICursor().IsVisible() && IsBinded(kLOOK_AROUND, dik)) - { - GetUICursor().UpdateCursorPosition(int(std::round(x)), int(std::round(y))); - Fvector2 cPos = GetUICursor().GetCursorPosition(); - TIR->OnMouseAction(cPos.x, cPos.y, WINDOW_MOUSE_MOVE); - } - else if (!TIR->StopAnyMove() && g_pGameLevel) + if (!TIR->StopAnyMove() && g_pGameLevel) { IGameObject* O = Level().CurrentEntity(); if (O) diff --git a/src/xrGame/UIDialogHolder.h b/src/xrGame/UIDialogHolder.h index f227f3e5e6f..f4a46eca148 100644 --- a/src/xrGame/UIDialogHolder.h +++ b/src/xrGame/UIDialogHolder.h @@ -4,6 +4,7 @@ #include "xrCore/_flags.h" #include "xrEngine/pure.h" #include "xrUICore/ui_debug.h" +#include "xrUICore/ui_focus.h" #include @@ -32,7 +33,7 @@ class recvItem Flags8 m_flags; }; -class CDialogHolder : public pureFrame, public CUIDebuggable +class CDialogHolder : public pureFrame, public CUIDebuggable, public CUIFocusSystem { // dialogs xr_vector m_input_receivers; diff --git a/src/xrGame/ui/UIDialogWnd.h b/src/xrGame/ui/UIDialogWnd.h index 842d6069578..6568b21f0a0 100644 --- a/src/xrGame/ui/UIDialogWnd.h +++ b/src/xrGame/ui/UIDialogWnd.h @@ -21,8 +21,17 @@ class CUIDialogWnd : public CUIWindow bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override; - CDialogHolder* GetHolder() { return m_pParentHolder; } - void SetHolder(CDialogHolder* h) { m_pParentHolder = h; } + CDialogHolder* GetHolder() const { return m_pParentHolder; } + + void SetHolder(CDialogHolder* h) + { + if (m_pParentHolder) + m_pParentHolder->UnregisterFocusable(this); + m_pParentHolder = h; + } + + CUIFocusSystem* GetCurrentFocusSystem() const override { return GetHolder(); } + virtual bool StopAnyMove() { return true; } virtual bool NeedCursor() const { return true; } virtual bool NeedCenterCursor() const { return true; } diff --git a/src/xrGame/ui/UIMMShniaga.cpp b/src/xrGame/ui/UIMMShniaga.cpp index a166ae1b612..448776a0519 100644 --- a/src/xrGame/ui/UIMMShniaga.cpp +++ b/src/xrGame/ui/UIMMShniaga.cpp @@ -390,6 +390,7 @@ void CUIMMShniaga::OnBtnClick() bool CUIMMShniaga::OnKeyboardAction(int dik, EUIMessages keyboard_action) { + return false; if (IsBinded(kQUIT, dik)) { if (m_page != epi_main) diff --git a/src/xrUICore/Buttons/UIButton.cpp b/src/xrUICore/Buttons/UIButton.cpp index c0273d4c359..d88a60f578d 100644 --- a/src/xrUICore/Buttons/UIButton.cpp +++ b/src/xrUICore/Buttons/UIButton.cpp @@ -10,6 +10,7 @@ CUIButton::CUIButton() : CUIStatic("CUIButton") { + m_bFocusValuable = true; m_eButtonState = BUTTON_NORMAL; m_bIsSwitch = false; diff --git a/src/xrUICore/CMakeLists.txt b/src/xrUICore/CMakeLists.txt index ae8df434075..c40c79ad10b 100644 --- a/src/xrUICore/CMakeLists.txt +++ b/src/xrUICore/CMakeLists.txt @@ -8,6 +8,8 @@ target_sources(xrUICore PRIVATE ui_debug.cpp ui_debug.h ui_defs.h + ui_focus.cpp + ui_focus.h ui_styles.cpp ui_styles.h uiabstract.h diff --git a/src/xrUICore/ComboBox/UIComboBox.cpp b/src/xrUICore/ComboBox/UIComboBox.cpp index 245e279f00f..c081a788a7a 100644 --- a/src/xrUICore/ComboBox/UIComboBox.cpp +++ b/src/xrUICore/ComboBox/UIComboBox.cpp @@ -9,6 +9,8 @@ CUIComboBox::CUIComboBox() : CUIWindow("CUIComboBox") { + m_bFocusValuable = true; + AttachChild(&m_frameLine); AttachChild(&m_text); diff --git a/src/xrUICore/Cursor/UICursor.cpp b/src/xrUICore/Cursor/UICursor.cpp index 2aa53befb84..608c299ee60 100644 --- a/src/xrUICore/Cursor/UICursor.cpp +++ b/src/xrUICore/Cursor/UICursor.cpp @@ -49,6 +49,7 @@ void CUICursor::Show() void CUICursor::Hide() { + return; bVisible = false; m_become_visible_time = 0; m_pause_autohide = false; diff --git a/src/xrUICore/EditBox/UICustomEdit.cpp b/src/xrUICore/EditBox/UICustomEdit.cpp index fcc3aff7d62..03f7ea3e5e4 100644 --- a/src/xrUICore/EditBox/UICustomEdit.cpp +++ b/src/xrUICore/EditBox/UICustomEdit.cpp @@ -8,6 +8,8 @@ CUICustomEdit::CUICustomEdit() : CUIStatic("CUICustomEdit") { + m_bFocusValuable = true; + m_editor_control = xr_new(EDIT_BUF_SIZE); Init(EDIT_BUF_SIZE); diff --git a/src/xrUICore/TrackBar/UITrackBar.cpp b/src/xrUICore/TrackBar/UITrackBar.cpp index e131f5311e8..559c37cdaab 100644 --- a/src/xrUICore/TrackBar/UITrackBar.cpp +++ b/src/xrUICore/TrackBar/UITrackBar.cpp @@ -19,6 +19,8 @@ CUITrackBar::CUITrackBar() : m_b_invert(false), m_b_is_float(true), m_b_bound_already_set(false), m_f_val(0), m_f_max(1), m_f_min(0), m_f_step(0.01f), m_f_opt_backup_value(0) { + m_bFocusValuable = true; + m_pSlider = xr_new(); AttachChild(m_pSlider); m_pSlider->SetAutoDelete(true); diff --git a/src/xrUICore/Windows/UIWindow.cpp b/src/xrUICore/Windows/UIWindow.cpp index bec3de34805..8cf5608e73c 100644 --- a/src/xrUICore/Windows/UIWindow.cpp +++ b/src/xrUICore/Windows/UIWindow.cpp @@ -1,6 +1,8 @@ #include "pch.hpp" #include "UIWindow.h" + +#include "ui_focus.h" #include "Cursor/UICursor.h" CUIWindow::CUIWindow(pcstr window_name) : m_windowName(window_name) @@ -41,6 +43,25 @@ void CUIWindow::Draw(float x, float y) void CUIWindow::Update() { + /*if (auto* focusSystem = GetCurrentFocusSystem()) + { + const bool valuable = IsFocusValuable(); + const bool registered = focusSystem->IsRegistered(this); + if (valuable) + { + if (!registered) + focusSystem->RegisterFocusable(this); + if (!focusSystem->GetFocused()) + focusSystem->SetFocused(this); + } + else if (!valuable && registered) + { + if (focusSystem->GetFocused() == this) + focusSystem->SetFocused(nullptr); + focusSystem->UnregisterFocusable(this); + } + }*/ + bool cursor_on_window = false; if (GetUICursor().IsVisible()) { @@ -551,6 +572,10 @@ bool CUIWindow::FillDebugTree(const CUIDebugState& debugState) rnd.seed((s32)(intptr_t)this); color = color_rgba(rnd.randI(255), rnd.randI(255), rnd.randI(255), 255); } + else if (GetCurrentFocusSystem() && GetCurrentFocusSystem()->GetFocused() == this) + color = color_rgba(200, 150, 200, 255); + else if (IsFocusValuable()) + color = color_rgba(255, 0, 255, 255); const auto draw_list = hovered ? ImGui::GetForegroundDrawList() : ImGui::GetBackgroundDrawList(); draw_list->AddRect((const ImVec2&)rect.lt, (const ImVec2&)rect.rb, color); diff --git a/src/xrUICore/Windows/UIWindow.h b/src/xrUICore/Windows/UIWindow.h index 555669deb90..f6516f4423a 100644 --- a/src/xrUICore/Windows/UIWindow.h +++ b/src/xrUICore/Windows/UIWindow.h @@ -12,6 +12,8 @@ #include "xrUICore/uiabstract.h" #include "xrUICore/ui_debug.h" +class CUIFocusSystem; + class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable { public: @@ -81,9 +83,27 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable virtual void Enable(bool status) { m_bIsEnabled = status; } + void SetFocusValuable(bool valuable) { m_bFocusValuable = valuable; } + [[nodiscard]] bool IsEnabled() const { return m_bIsEnabled; } + [[nodiscard]] + bool IsFocusValuable() const + { + if (!m_bFocusValuable) + return false; + + bool ok; + for (auto it = this; ; it = it->GetParent()) + { + ok = it->IsShown() && it->IsEnabled(); + if (!ok || !it->GetParent()) + break; + } + return ok; + } + //убрать/показать окно и его дочерние окна virtual void Show(bool status) { @@ -91,6 +111,13 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable Enable(status); } + virtual CUIFocusSystem* GetCurrentFocusSystem() const + { + if (m_pParentWnd) + return m_pParentWnd->GetCurrentFocusSystem(); + return nullptr; + } + [[nodiscard]] virtual bool IsShown() const { return GetVisible(); } @@ -197,6 +224,8 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable // Если курсор над окном bool m_bCursorOverWindow{}; bool m_bCustomDraw{}; + + bool m_bFocusValuable{}; }; XRUICORE_API bool fit_in_rect(CUIWindow* w, Frect const& vis_rect, float border = 0.0f, float dx16pos = 0.0f); diff --git a/src/xrUICore/Windows/UIWindow_script.cpp b/src/xrUICore/Windows/UIWindow_script.cpp index 872e8ce0bb9..ea6bf6e6d07 100644 --- a/src/xrUICore/Windows/UIWindow_script.cpp +++ b/src/xrUICore/Windows/UIWindow_script.cpp @@ -9,6 +9,7 @@ #include "ScrollView/UIScrollView.h" #include "Hint/UIHint.h" #include "Cursor/UICursor.h" +#include "ui_focus.h" #include "ui_styles.h" #include "xrScriptEngine/ScriptExporter.hpp" @@ -69,6 +70,34 @@ SCRIPT_EXPORT(UIStyleManager, (), ]; }); +SCRIPT_EXPORT(CUIFocusSystem, (), +{ + using namespace luabind; + using namespace luabind::policy; + + module(luaState) + [ + class_("FocusDirection") + .enum_("direction") + [ + value("Same", (int)FocusDirection::Same), + value("Up", (int)FocusDirection::Up), + value("Down", (int)FocusDirection::Down), + value("Left", (int)FocusDirection::Left), + value("Right", (int)FocusDirection::Right), + value("UpperLeft", (int)FocusDirection::UpperLeft), + value("UpperRight", (int)FocusDirection::UpperRight), + value("LowerLeft", (int)FocusDirection::LowerLeft), + value("LowerRight", (int)FocusDirection::LowerRight) + ], + class_("CUIFocusSystem") + .def("RegisterFocusable", &CUIFocusSystem::RegisterFocusable) + .def("UnregisterFocusable", &CUIFocusSystem::UnregisterFocusable) + .def("IsRegistered", &CUIFocusSystem::IsRegistered) + .def("FindClosestFocusable", &CUIFocusSystem::FindClosestFocusable) + ]; +}); + SCRIPT_EXPORT(CUITextureMaster, (), { using namespace luabind; @@ -184,6 +213,8 @@ SCRIPT_EXPORT(CUIWindow, (), .def("SetFont", &CUIWindow::SetFont) .def("GetFont", &CUIWindow::GetFont) + .def("GetCurrentFocusSystem", &CUIWindow::GetCurrentFocusSystem) + .def("WindowName", +[](CUIWindow* self) -> pcstr { return self->WindowName().c_str(); }) .def("SetWindowName", &CUIWindow::SetWindowName), diff --git a/src/xrUICore/ui_focus.cpp b/src/xrUICore/ui_focus.cpp new file mode 100644 index 00000000000..62edbd030b3 --- /dev/null +++ b/src/xrUICore/ui_focus.cpp @@ -0,0 +1,153 @@ +/* +Copyright (c) 2014 OpenXRay + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "pch.hpp" + +#include "ui_focus.h" +#include "Windows/UIWindow.h" + +namespace +{ +float euclidean_distance(const CUIWindow* from, const CUIWindow* to) +{ + const auto& [aX, aY] = from->GetWndPos(); + const auto& [bX, bY] = to->GetWndPos(); + + const auto& [aWidth, aHeight] = from->GetWndSize(); + const auto& [bWidth, bHeight] = to->GetWndSize(); + + const Fvector2 centerA = { aX + aWidth / 2.0f, aY + aHeight / 2.0f }; + const Fvector2 centerB = { bX + bWidth / 2.0f, bY + bHeight / 2.0f }; + + return std::sqrtf(std::powf(centerB.x - centerA.x, 2) + std::powf(centerB.y - centerA.y, 2)); +} +} + +CUIFocusSystem::FocusData CUIFocusSystem::CalculateFocusData(const CUIWindow* from, const CUIWindow* to) +{ + const auto& fromPos = from->GetWndPos(); + const auto& toPos = to->GetWndPos(); + + const bool upper = fromPos.y > toPos.y; + const bool lower = fromPos.y < toPos.y; + const bool left = fromPos.x < toPos.x; + const bool right = fromPos.x > toPos.x; + + FocusDirection direction; + if (upper) + { + if (left) + direction = FocusDirection::UpperLeft; + else if (right) + direction = FocusDirection::UpperRight; + else + direction = FocusDirection::Up; + } + else if (lower) + { + if (left) + direction = FocusDirection::LowerLeft; + else if (right) + direction = FocusDirection::LowerRight; + else + direction = FocusDirection::Down; + } + else if (left) + { + direction = FocusDirection::Left; + } + else if (right) + { + direction = FocusDirection::Right; + } + else + { + direction = FocusDirection::Same; + } + + return + { + euclidean_distance(from, to), + direction + }; +} + +void CUIFocusSystem::RegisterFocusable(CUIWindow* focusable) +{ + ZoneScoped; + + auto& my_relates = m_structure[focusable]; + + // Split calculations to make it more CPU-cache friendly: + // 1. Calculate relations from focusable to all windows + for (auto& window : m_all_windows) + my_relates[window] = CalculateFocusData(focusable, window); + + // 2. Calculate relations from all windows to focusable + for (auto& window : m_all_windows) + m_structure[window][focusable] = CalculateFocusData(window, focusable); + + m_all_windows.emplace_back(focusable); +} + +void CUIFocusSystem::UnregisterFocusable(CUIWindow* focusable) +{ + if (const auto it = m_structure.find(focusable); + it != m_structure.end()) + { + it->second.clear(); + m_structure.erase(it); + } + + if (const auto it = std::find(m_all_windows.begin(), m_all_windows.end(), focusable); + it != m_all_windows.end()) + { + m_all_windows.erase(it); + } +} + +bool CUIFocusSystem::IsRegistered(const CUIWindow* focusable) const +{ + const auto& it = m_structure.find(const_cast(focusable)); + return it != m_structure.end(); +} + +CUIWindow* CUIFocusSystem::FindClosestFocusable(CUIWindow* target, FocusDirection direction) const +{ + const auto& it = m_structure.find(target); + if (it == m_structure.end()) + { + VERIFY2(false, "Target CUIWindow is not registered in the focus system."); + return nullptr; + } + + const auto& my_relates = it->second; + CUIWindow* closest = nullptr; + float minDistance = type_max; + + for (const auto& [window, data] : my_relates) + { + if (data.distance < minDistance && data.direction == direction) + { + minDistance = data.distance; + closest = window; + } + } + + // We hold const pointers to guarantee that we don't do anything. + // But the caller can do anything. + return closest; +} diff --git a/src/xrUICore/ui_focus.h b/src/xrUICore/ui_focus.h new file mode 100644 index 00000000000..08cb464aa0b --- /dev/null +++ b/src/xrUICore/ui_focus.h @@ -0,0 +1,72 @@ +/* +Copyright (c) 2014 OpenXRay + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "ui_defs.h" + +#include "xrCommon/xr_map.h" +#include "xrCommon/xr_unordered_map.h" + +class CUIWindow; + +enum class FocusDirection +{ + Same, // exactly same coordinates with the target + Up, + Down, + Left, + Right, + UpperLeft, + UpperRight, + LowerLeft, + LowerRight, +}; + +// 1. Doesn't own CUIWindow* pointers it holds +class XRUICORE_API CUIFocusSystem +{ + struct FocusData + { + float distance; + FocusDirection direction; + }; + + using relates_t = xr_map; + using targets_t = xr_unordered_map; + + targets_t m_structure; + + xr_list m_all_windows; // helper to make code simpler + + CUIWindow* m_current_focused{}; + +private: + static FocusData CalculateFocusData(const CUIWindow* from, const CUIWindow* to); + +public: + virtual ~CUIFocusSystem() = default; + + void RegisterFocusable(CUIWindow* focusable); + void UnregisterFocusable(CUIWindow* focusable); + + bool IsRegistered(const CUIWindow* focusable) const; + + CUIWindow* FindClosestFocusable(CUIWindow* target, FocusDirection direction) const; + + CUIWindow* GetFocused() const { return m_current_focused;} + void SetFocused(CUIWindow* window) { m_current_focused = window; } +}; diff --git a/src/xrUICore/xrUICore.vcxproj b/src/xrUICore/xrUICore.vcxproj index 94fc70434fe..6dfce1cb60d 100644 --- a/src/xrUICore/xrUICore.vcxproj +++ b/src/xrUICore/xrUICore.vcxproj @@ -110,6 +110,7 @@ + @@ -182,6 +183,7 @@ + diff --git a/src/xrUICore/xrUICore.vcxproj.filters b/src/xrUICore/xrUICore.vcxproj.filters index 9cfc696907c..39a9e661942 100644 --- a/src/xrUICore/xrUICore.vcxproj.filters +++ b/src/xrUICore/xrUICore.vcxproj.filters @@ -276,6 +276,7 @@ + @@ -458,6 +459,7 @@ + From b0b0131b0e9c6526ea1307c2f4ae0c31e3dbd915 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 25 May 2024 14:59:06 +0500 Subject: [PATCH 430/497] xr_parallel_for and xr_parallel_for_each can now have parent tasks (closes #1680) --- src/xrCore/Threading/ParallelFor.hpp | 26 +++++++++++++++++++++++ src/xrCore/Threading/ParallelForEach.hpp | 27 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/xrCore/Threading/ParallelFor.hpp b/src/xrCore/Threading/ParallelFor.hpp index d6ced48c433..7dfd42d1736 100644 --- a/src/xrCore/Threading/ParallelFor.hpp +++ b/src/xrCore/Threading/ParallelFor.hpp @@ -145,6 +145,19 @@ class ParallelFor return task; } + static decltype(auto) Run(Task& parent, const Range& range, bool wait, const Function& function) + { + auto& task = TaskManager::AddTask(parent, Functor{ range, function }); + if (wait) + { + VERIFY2(TaskScheduler, "Task scheduler is not yet created. " + "You should explicitly state that you know this by setting 'wait' param to false."); + if (TaskScheduler) + TaskScheduler->Wait(task); + } + return task; + } + private: struct Functor { @@ -182,3 +195,16 @@ decltype(auto) xr_parallel_for(const Range& range, const Function& function) return detail::ParallelFor::Run(range, true, function); } +// User can specify if he wants caller thread to wait on the task finish +template +decltype(auto) xr_parallel_for(Task& parent, const Range& range, bool wait, const Function& function) +{ + return detail::ParallelFor::Run(parent, range, wait, function); +} + +// Caller thread will wait on the task finish +template +decltype(auto) xr_parallel_for(Task& parent, const Range& range, const Function& function) +{ + return detail::ParallelFor::Run(parent, range, true, function); +} diff --git a/src/xrCore/Threading/ParallelForEach.hpp b/src/xrCore/Threading/ParallelForEach.hpp index 23b0a98ac75..9d2e9564be0 100644 --- a/src/xrCore/Threading/ParallelForEach.hpp +++ b/src/xrCore/Threading/ParallelForEach.hpp @@ -33,6 +33,19 @@ class ParallelForEach } }); } + + template + static decltype(auto) Run(Task& parent, Iterator begin, Iterator end, bool wait, const Function& function) + { + return xr_parallel_for(parent, TaskRange(begin, end), wait, [&](TaskRange& range) + { + for (auto& it : range) + { + function(it); + } + }); + } + }; } // namespace detail @@ -49,3 +62,17 @@ decltype(auto) xr_parallel_for_each(Range& range, const Function& function) { return detail::ParallelForEach::Run(std::begin(range), std::end(range), true, function); } + +// User can specify if he wants caller thread to wait on the task finish +template +decltype(auto) xr_parallel_for_each(Task& parent, Range& range, bool wait, const Function& function) +{ + return detail::ParallelForEach::Run(parent, std::begin(range), std::end(range), wait, function); +} + +// Caller thread will wait on the task finish +template +decltype(auto) xr_parallel_for_each(Task& parent, Range& range, const Function& function) +{ + return detail::ParallelForEach::Run(parent, std::begin(range), std::end(range), true, function); +} From a2c46b7cbaeb91790a8926909ee9ee92a52179cb Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Sat, 25 May 2024 15:39:27 +0500 Subject: [PATCH 431/497] Fix compilation with GCC --- src/xrUICore/ui_focus.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xrUICore/ui_focus.cpp b/src/xrUICore/ui_focus.cpp index 62edbd030b3..c54b7cbb38f 100644 --- a/src/xrUICore/ui_focus.cpp +++ b/src/xrUICore/ui_focus.cpp @@ -19,6 +19,8 @@ limitations under the License. #include "ui_focus.h" #include "Windows/UIWindow.h" +#include + namespace { float euclidean_distance(const CUIWindow* from, const CUIWindow* to) From a39e5f081c2ba57ea4e9320c65fd26327ee47fc2 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Sat, 25 May 2024 15:51:45 +0500 Subject: [PATCH 432/497] Another attempt to fix GCC compilation --- src/xrUICore/ui_focus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrUICore/ui_focus.cpp b/src/xrUICore/ui_focus.cpp index c54b7cbb38f..cafc2f087c9 100644 --- a/src/xrUICore/ui_focus.cpp +++ b/src/xrUICore/ui_focus.cpp @@ -34,7 +34,7 @@ float euclidean_distance(const CUIWindow* from, const CUIWindow* to) const Fvector2 centerA = { aX + aWidth / 2.0f, aY + aHeight / 2.0f }; const Fvector2 centerB = { bX + bWidth / 2.0f, bY + bHeight / 2.0f }; - return std::sqrtf(std::powf(centerB.x - centerA.x, 2) + std::powf(centerB.y - centerA.y, 2)); + return sqrtf(powf(centerB.x - centerA.x, 2) + powf(centerB.y - centerA.y, 2)); } } From 8c6b60e1deaa5b9fa1e345f830fe3824889d76b8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 25 May 2024 15:25:14 +0500 Subject: [PATCH 433/497] xrCore/Threading/Lock.cpp: use std::memory_order_acq_rel for lockCounter No need to use seq_cst --- src/xrCore/Threading/Lock.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xrCore/Threading/Lock.cpp b/src/xrCore/Threading/Lock.cpp index 782ca49c719..4bb3993f380 100644 --- a/src/xrCore/Threading/Lock.cpp +++ b/src/xrCore/Threading/Lock.cpp @@ -70,7 +70,7 @@ Lock::~Lock() { xr_delete(impl); } void Lock::Enter() { impl->Lock(); - ++lockCounter; + lockCounter.fetch_add(1, std::memory_order_acq_rel); } #endif // CONFIG_PROFILE_LOCKS @@ -78,14 +78,14 @@ bool Lock::TryEnter() { const bool locked = impl->TryLock(); if (locked) - ++lockCounter; + lockCounter.fetch_add(1, std::memory_order_acq_rel); return locked; } void Lock::Leave() { impl->Unlock(); - --lockCounter; + lockCounter.fetch_sub(1, std::memory_order_acq_rel); } #ifdef DEBUG From d127ae20922feee3c72391c188c17e8327545aa0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 25 May 2024 15:36:28 +0500 Subject: [PATCH 434/497] xrCore/Threading/Lock.hpp: add move constructor and move assign operator --- src/xrCore/Threading/Lock.cpp | 19 +++++++++++++++++++ src/xrCore/Threading/Lock.hpp | 11 +++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/xrCore/Threading/Lock.cpp b/src/xrCore/Threading/Lock.cpp index 4bb3993f380..45821a8cee7 100644 --- a/src/xrCore/Threading/Lock.cpp +++ b/src/xrCore/Threading/Lock.cpp @@ -67,6 +67,25 @@ Lock::Lock() : impl(xr_new()), lockCounter(0) {} Lock::~Lock() { xr_delete(impl); } +Lock::Lock(Lock&& other) noexcept(false) +{ + xr_delete(impl); + impl = other.impl; + lockCounter.store(other.lockCounter.load(std::memory_order_acquire), std::memory_order_release); + other.impl = xr_new(); + other.lockCounter.store(0, std::memory_order_release); +} + +Lock& Lock::operator=(Lock&& other) noexcept(false) +{ + xr_delete(impl); + impl = other.impl; + lockCounter.store(other.lockCounter.load(std::memory_order_acquire), std::memory_order_release); + other.impl = xr_new(); + other.lockCounter.store(0, std::memory_order_release); + return *this; +} + void Lock::Enter() { impl->Lock(); diff --git a/src/xrCore/Threading/Lock.hpp b/src/xrCore/Threading/Lock.hpp index 714fbf5635c..1c08e3d83b2 100644 --- a/src/xrCore/Threading/Lock.hpp +++ b/src/xrCore/Threading/Lock.hpp @@ -12,9 +12,10 @@ void XRCORE_API set_add_profile_portion(add_profile_portion_callback callback); #define MUTEX_PROFILE_ID(a) MACRO_TO_STRING(CONCATENIZE(MUTEX_PROFILE_PREFIX_ID, a)) #endif // CONFIG_PROFILE_LOCKS -class XRCORE_API Lock : Noncopyable +class XRCORE_API Lock { - struct LockImpl* impl; + struct LockImpl* impl{}; + public: #ifdef CONFIG_PROFILE_LOCKS Lock(const char* id); @@ -23,6 +24,12 @@ class XRCORE_API Lock : Noncopyable #endif ~Lock(); + Lock(Lock& other) = delete; + Lock& operator=(Lock& other) = delete; + + Lock(Lock&& other) noexcept(false); + Lock& operator=(Lock&& other) noexcept(false); + #ifdef CONFIG_PROFILE_LOCKS void Enter(); #else From 9847da0867d8f222291dec07b703c92eb64f8ccc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 15:03:59 +0500 Subject: [PATCH 435/497] Fix resolution changing problems (closes #1383) --- src/xrEngine/Device_destroy.cpp | 4 +--- src/xrEngine/Device_mode.cpp | 12 ++++++++++-- src/xrEngine/device.cpp | 12 +++++++----- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/xrEngine/Device_destroy.cpp b/src/xrEngine/Device_destroy.cpp index 52fe376fffc..ca8b7afcd44 100644 --- a/src/xrEngine/Device_destroy.cpp +++ b/src/xrEngine/Device_destroy.cpp @@ -46,9 +46,7 @@ void CRenderDevice::Reset(bool precache /*= true*/) m_imgui_render->OnDeviceResetEnd(); - // Update window props again for DX9 renderer - if (GEnv.Render->GetBackendAPI() == IRender::BackendAPI::D3D9) // XXX: I don't remember why this hack is needed, thus, I'm not sure if it is needed at all - UpdateWindowProps(); // hack + UpdateWindowProps(); // hack SetupStates(); diff --git a/src/xrEngine/Device_mode.cpp b/src/xrEngine/Device_mode.cpp index 29899e10bc0..c68a8a1107a 100644 --- a/src/xrEngine/Device_mode.cpp +++ b/src/xrEngine/Device_mode.cpp @@ -130,7 +130,15 @@ void CRenderDevice::UpdateWindowProps() SDL_SetWindowPosition(m_sdlWnd, rect.x, rect.y); } - SDL_SetWindowSize(m_sdlWnd, psDeviceMode.Width, psDeviceMode.Height); + if (psDeviceMode.WindowStyle != rsFullscreenBorderless) + SDL_SetWindowSize(m_sdlWnd, psDeviceMode.Width, psDeviceMode.Height); + else + { + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(psDeviceMode.Monitor, ¤t); + + SDL_SetWindowSize(m_sdlWnd, current.w, current.h); + } if (windowed) { @@ -154,8 +162,8 @@ void CRenderDevice::UpdateWindowProps() SDL_SetWindowDisplayMode(m_sdlWnd, &mode); } + SDL_PumpEvents(); UpdateWindowRects(); - SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT); ImGuiIO& io = ImGui::GetIO(); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index bf583b70702..4068e961797 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -366,14 +366,16 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) #endif case SDL_WINDOWEVENT_RESIZED: - if (viewport) - viewport->PlatformRequestResize = true; + if (window == m_sdlWnd) + UpdateWindowRects(); break; case SDL_WINDOWEVENT_SIZE_CHANGED: { - if (psDeviceMode.WindowStyle != rsFullscreen) + if (window == m_sdlWnd) { + UpdateWindowRects(); + if (static_cast(psDeviceMode.Width) == event.window.data1 && static_cast(psDeviceMode.Height) == event.window.data2) break; // we don't need to reset device if resolution wasn't really changed @@ -383,8 +385,8 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) Reset(); } - else - UpdateWindowRects(); + if (viewport) + viewport->PlatformRequestResize = true; break; } From cc6787d6e896a78a56709810872806223078d0a6 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 15:46:03 +0500 Subject: [PATCH 436/497] Removed center_screen console command It doesn't take in to account multi-monitor setup. It centers the window on the main system monitor, instead of the monitor where the window is. I'm lazy to make the code that would calculate positions for the current monitor. --- src/xrEngine/device.cpp | 2 -- src/xrEngine/xr_ioc_cmd.cpp | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index 4068e961797..e44da42edd1 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -436,8 +436,6 @@ void CRenderDevice::Run() UpdateWindowProps(); SDL_ShowWindow(m_sdlWnd); SDL_RaiseWindow(m_sdlWnd); - if (GEnv.isDedicatedServer || strstr(Core.Params, "-center_screen")) - SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } void CRenderDevice::Shutdown() diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index 20db9fcbfbe..e6c9f398007 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -754,16 +754,6 @@ class ENGINE_API CCC_HideConsole : public IConsole_Command virtual void Info(TInfo& I) { xr_sprintf(I, sizeof(I), "hide console"); } }; -class CCC_CenterScreen : public IConsole_Command -{ -public: - CCC_CenterScreen(pcstr name) : IConsole_Command(name) { bEmptyArgsHandled = true; } - void Execute(pcstr args) override - { - SDL_SetWindowPosition(Device.m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); - } -}; - class CCC_ControllerSensorEnable final : public CCC_Mask { public: @@ -937,8 +927,6 @@ void CCC_Register() CMD2(CCC_Float, "cam_inert", &psCamInert); CMD2(CCC_Float, "cam_slide_inert", &psCamSlideInert); - CMD1(CCC_CenterScreen, "center_screen"); - CMD1(CCC_renderer, "renderer"); if (!GEnv.isDedicatedServer) From 40d2d381547bffd7fca4017b3120a4c643f009ba Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 18:22:43 +0500 Subject: [PATCH 437/497] Fix cursor being shown in places where it should be hidden --- src/xrUICore/Cursor/UICursor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xrUICore/Cursor/UICursor.cpp b/src/xrUICore/Cursor/UICursor.cpp index 608c299ee60..2aa53befb84 100644 --- a/src/xrUICore/Cursor/UICursor.cpp +++ b/src/xrUICore/Cursor/UICursor.cpp @@ -49,7 +49,6 @@ void CUICursor::Show() void CUICursor::Hide() { - return; bVisible = false; m_become_visible_time = 0; m_pause_autohide = false; From 5668cbf3980e7f9bce2c59534efa066f04cf2c25 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 18:37:01 +0500 Subject: [PATCH 438/497] Fix process soft lock when changing resolution when level is loaded --- src/xrGame/Weapon.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/xrGame/Weapon.cpp b/src/xrGame/Weapon.cpp index 5785f471522..c8c48fdbe0c 100644 --- a/src/xrGame/Weapon.cpp +++ b/src/xrGame/Weapon.cpp @@ -42,25 +42,36 @@ static class CUIWpnScopeXmlManager : public pureUIReset, public pureAppEnd CUIXml m_xml; bool m_loaded{}; -public: void Load() + { + m_loaded = m_xml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "scopes.xml"); + } + + void Clear() + { + m_xml.ClearInternal(); + m_loaded = false; + } + +public: + void Init() { if (m_loaded) return; - m_loaded = m_xml.Load(CONFIG_PATH, UI_PATH, UI_PATH_DEFAULT, "scopes.xml"); + + Load(); Device.seqUIReset.Add(this); } void OnAppEnd() override { - m_xml.ClearInternal(); - m_loaded = false; + Clear(); Device.seqUIReset.Remove(this); } void OnUIReset() override { - OnAppEnd(); + Clear(); if (g_pGameLevel) Load(); } @@ -525,7 +536,7 @@ void CWeapon::LoadScope(const shared_str& section) { if (ShadowOfChernobylMode) // XXX: temporary check for SOC mode, to be removed return; - pWpnScopeXml.Load(); + pWpnScopeXml.Init(); R_ASSERT(m_UIScope); CUIXmlInit::InitWindow(*pWpnScopeXml, section.c_str(), 0, m_UIScope); } From 345a447c787a364cc22b887700d32cd3e0ece808 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 20:03:22 +0500 Subject: [PATCH 439/497] Fix too much CPU load in the task manager --- src/xrCore/Threading/TaskManager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index d58c23449fd..2fa6d042688 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -239,11 +239,10 @@ void TaskManager::TaskWorkerStart() SetThreadStatus(false); { std::unique_lock lck(s_tl_worker.mutex); - newWorkArrived.wait(lck, [&] + do { - // spurious unlocks allowed - return !shouldPause.load(std::memory_order_consume); - }); + newWorkArrived.wait(lck); // spurious wakeups allowed + } while (shouldPause.load(std::memory_order_consume)); } SetThreadStatus(true); } // while (true) From c0dc75561a55e2e12c6a0b62e08bd491a6068195 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 20:04:56 +0500 Subject: [PATCH 440/497] xrCore/Threading/TaskManager.cpp: move shouldStop check into while condition More convenient. --- src/xrCore/Threading/TaskManager.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 2fa6d042688..1fc3cdd2447 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -225,11 +225,8 @@ void TaskManager::TaskWorkerStart() RegisterThisThreadAsWorker(); SetThreadStatus(true); - while (true) + while (!shouldStop.load(std::memory_order_consume)) { - if (shouldStop.load(std::memory_order_consume)) - break; - if (!shouldPause.load(std::memory_order_consume)) { if (ExecuteOneTask()) From c112573913ae8f0cfafa4173afe648dacfa0ee7c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 26 May 2024 20:16:39 +0500 Subject: [PATCH 441/497] xrCore/Threading/TaskManager.cpp: removed comment [skip ci] --- src/xrCore/Threading/TaskManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 1fc3cdd2447..3dad17d9ed4 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -242,7 +242,7 @@ void TaskManager::TaskWorkerStart() } while (shouldPause.load(std::memory_order_consume)); } SetThreadStatus(true); - } // while (true) + } SetThreadStatus(false); From b9d0fb06956d3ba52903520deac52943c3fbbca5 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Sun, 26 May 2024 21:33:15 +0200 Subject: [PATCH 442/497] CMake: Fix `calculate_xray_build_id` breaking for dates before 31.01.1999 (#1615) --- cmake/utils.cmake | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index bcb7f46f4f1..5d45f55158c 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -58,6 +58,17 @@ function(calculate_xray_build_id output) list(GET current_date_list 1 CURRENT_DATE_MONTH) list(GET current_date_list 2 CURRENT_DATE_YEAR) + # Check if current date is before the start date + # See https://github.com/OpenXRay/xray-16/issues/1611 + if ( (CURRENT_DATE_YEAR LESS XRAY_START_YEAR) + OR ( (CURRENT_DATE_YEAR EQUAL XRAY_START_YEAR) + AND (CURRENT_DATE_MONTH LESS XRAY_START_MONTH) + OR ( (CURRENT_DATE_MONTH EQUAL XRAY_START_MONTH) + AND (CURRENT_DATE_DAY LESS XRAY_START_DAY) ) ) ) + set(${output} 0 PARENT_SCOPE) + return() + endif() + # Calculate XRAY build ID math(EXPR build_id "(${CURRENT_DATE_YEAR} - ${XRAY_START_YEAR}) * 365 + ${CURRENT_DATE_DAY} - ${XRAY_START_DAY}") From d14faeec8a8be21178c67257663398558294266b Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 27 May 2024 02:16:03 +0500 Subject: [PATCH 443/497] xrCore: simplify math library, remove doubles usage, we use floats mostly --- src/Include/xrRender/DebugRender.h | 3 +- src/Include/xrRender/DrawUtils.h | 4 +- src/Include/xrRender/Kinematics.h | 4 +- src/Include/xrRender/UIRender.h | 3 +- src/utils/xrMiscMath/matrix.cpp | 252 ++++++++++------------------ src/utils/xrMiscMath/quaternion.cpp | 13 +- src/utils/xrMiscMath/vector.cpp | 44 +---- src/xrCore/_math.cpp | 2 - src/xrCore/_matrix.h | 175 ++++++++++--------- src/xrCore/_matrix33.h | 73 ++++---- src/xrCore/_obb.h | 58 +++---- src/xrCore/_plane.h | 80 ++++----- src/xrCore/_plane2.h | 65 ++++--- src/xrCore/_quaternion.h | 107 ++++++------ src/xrCore/_rect.h | 5 +- src/xrCore/_vector2.h | 4 +- src/xrCore/_vector3d.h | 3 - src/xrCore/_vector4.h | 1 - src/xrCore/dump_string.h | 2 +- src/xrCore/log.h | 2 +- src/xrCore/vector.h | 3 +- src/xrEngine/IPhysicsShell.h | 3 +- src/xrPhysics/MathUtils.h | 3 +- src/xrPhysics/PhysicsShell.h | 4 +- src/xrPhysics/debug_output.h | 3 +- 25 files changed, 358 insertions(+), 558 deletions(-) diff --git a/src/Include/xrRender/DebugRender.h b/src/Include/xrRender/DebugRender.h index f7c68d28ca7..6d0b73b1171 100644 --- a/src/Include/xrRender/DebugRender.h +++ b/src/Include/xrRender/DebugRender.h @@ -8,8 +8,7 @@ // fwd. decl. template struct _vector3; using Fvector = _vector3; -template struct _matrix; -using Fmatrix = _matrix; +struct Fmatrix; class IDebugRender { diff --git a/src/Include/xrRender/DrawUtils.h b/src/Include/xrRender/DrawUtils.h index dd1dc3f0417..f0ae1acb01b 100644 --- a/src/Include/xrRender/DrawUtils.h +++ b/src/Include/xrRender/DrawUtils.h @@ -18,9 +18,7 @@ template struct _vector3; typedef _vector3 Fvector; -template -struct _obb; -typedef _obb Fobb; +struct Fobb; //---------------------------------------------------- // Utilities diff --git a/src/Include/xrRender/Kinematics.h b/src/Include/xrRender/Kinematics.h index 09f7a808c93..a3613bfd2bb 100644 --- a/src/Include/xrRender/Kinematics.h +++ b/src/Include/xrRender/Kinematics.h @@ -17,9 +17,7 @@ struct SEnumVerticesCallback; struct Fbox3; using Fbox = Fbox3; -template -struct _obb; -typedef _obb Fobb; +struct Fobb; // 100 ms = 10 fps #define UCalc_Interval (u32(100)) diff --git a/src/Include/xrRender/UIRender.h b/src/Include/xrRender/UIRender.h index e1ae310aa19..10ce2a10e7e 100644 --- a/src/Include/xrRender/UIRender.h +++ b/src/Include/xrRender/UIRender.h @@ -9,8 +9,7 @@ template struct _rect; using Irect = _rect; template struct _vector2; using Fvector2 = _vector2; -template struct _matrix; -using Fmatrix = _matrix; +struct Fmatrix; class IUIRender { diff --git a/src/utils/xrMiscMath/matrix.cpp b/src/utils/xrMiscMath/matrix.cpp index c5a2096bcc3..afecc19dd89 100644 --- a/src/utils/xrMiscMath/matrix.cpp +++ b/src/utils/xrMiscMath/matrix.cpp @@ -7,18 +7,17 @@ #include -template -_matrix& _matrix::rotation(const _quaternion& Q) +Fmatrix& Fmatrix::rotation(const Fquaternion& Q) { - T xx = Q.x*Q.x; - T yy = Q.y*Q.y; - T zz = Q.z*Q.z; - T xy = Q.x*Q.y; - T xz = Q.x*Q.z; - T yz = Q.y*Q.z; - T wx = Q.w*Q.x; - T wy = Q.w*Q.y; - T wz = Q.w*Q.z; + float xx = Q.x*Q.x; + float yy = Q.y*Q.y; + float zz = Q.z*Q.z; + float xy = Q.x*Q.y; + float xz = Q.x*Q.z; + float yz = Q.y*Q.z; + float wx = Q.w*Q.x; + float wy = Q.w*Q.y; + float wz = Q.w*Q.z; _11 = 1 - 2 * (yy + zz); _12 = 2 * (xy - wz); @@ -39,18 +38,17 @@ _matrix& _matrix::rotation(const _quaternion& Q) return *this; } -template -_matrix& _matrix::mk_xform(const _quaternion& Q, const Tvector& V) +Fmatrix& Fmatrix::mk_xform(const Fquaternion& Q, const Fvector& V) { - T xx = Q.x*Q.x; - T yy = Q.y*Q.y; - T zz = Q.z*Q.z; - T xy = Q.x*Q.y; - T xz = Q.x*Q.z; - T yz = Q.y*Q.z; - T wx = Q.w*Q.x; - T wy = Q.w*Q.y; - T wz = Q.w*Q.z; + float xx = Q.x*Q.x; + float yy = Q.y*Q.y; + float zz = Q.z*Q.z; + float xy = Q.x*Q.y; + float xz = Q.x*Q.z; + float yz = Q.y*Q.z; + float wx = Q.w*Q.x; + float wy = Q.w*Q.y; + float wz = Q.w*Q.z; _11 = 1 - 2 * (yy + zz); _12 = 2 * (xy - wz); @@ -71,8 +69,7 @@ _matrix& _matrix::mk_xform(const _quaternion& Q, const Tvector& V) return *this; } -template -_matrix& _matrix::identity() +Fmatrix& Fmatrix::identity() { _11 = 1; _12 = 0; @@ -94,8 +91,7 @@ _matrix& _matrix::identity() } // Multiply RES = A[4x4]*B[4x4] (WITH projection) -template -_matrix& _matrix::mul(const _matrix& A, const _matrix& B) +Fmatrix& Fmatrix::mul(const Fmatrix& A, const Fmatrix& B) { VERIFY((this != &A) && (this != &B)); m[0][0] = A.m[0][0] * B.m[0][0] + A.m[1][0] * B.m[0][1] + A.m[2][0] * B.m[0][2] + A.m[3][0] * B.m[0][3]; @@ -121,8 +117,7 @@ _matrix& _matrix::mul(const _matrix& A, const _matrix& B) } // Multiply RES = A[4x3]*B[4x3] (no projection), faster than ordinary multiply -template -_matrix& _matrix::mul_43(const _matrix& A, const _matrix& B) +Fmatrix& Fmatrix::mul_43(const Fmatrix& A, const Fmatrix& B) { VERIFY((this != &A) && (this != &B)); m[0][0] = A.m[0][0] * B.m[0][0] + A.m[1][0] * B.m[0][1] + A.m[2][0] * B.m[0][2]; @@ -147,11 +142,10 @@ _matrix& _matrix::mul_43(const _matrix& A, const _matrix& B) return *this; } -template -_matrix& _matrix::invert(const _matrix& a) // important: this is 4x3 invert, not the 4x4 one +Fmatrix& Fmatrix::invert(const Fmatrix& a) // important: this is 4x3 invert, not the 4x4 one { // faster than self-invert - T fDetInv = (a._11 * (a._22 * a._33 - a._23 * a._32) - + float fDetInv = (a._11 * (a._22 * a._33 - a._23 * a._32) - a._12 * (a._21 * a._33 - a._23 * a._31) + a._13 * (a._21 * a._32 - a._22 * a._31)); @@ -180,11 +174,10 @@ _matrix& _matrix::invert(const _matrix& a) // important: this is 4x3 return *this; } -template -bool _matrix::invert_b(const _matrix& a) // important: this is 4x3 invert, not the 4x4 one +bool Fmatrix::invert_b(const Fmatrix& a) // important: this is 4x3 invert, not the 4x4 one { // faster than self-invert - T fDetInv = (a._11 * (a._22 * a._33 - a._23 * a._32) - + float fDetInv = (a._11 * (a._22 * a._33 - a._23 * a._32) - a._12 * (a._21 * a._33 - a._23 * a._31) + a._13 * (a._21 * a._32 - a._22 * a._31)); @@ -213,27 +206,26 @@ bool _matrix::invert_b(const _matrix& a) // important: this is 4x3 inver return true; } -template -_matrix& _matrix::invert_44(const _matrix& a) +Fmatrix& Fmatrix::invert_44(const Fmatrix& a) { - const T &a11 = a._11, &a12 = a._12, &a13 = a._13, &a14 = a._14; - const T &a21 = a._21, &a22 = a._22, &a23 = a._23, &a24 = a._24; - const T &a31 = a._31, &a32 = a._32, &a33 = a._33, &a34 = a._34; - const T &a41 = a._41, &a42 = a._42, &a43 = a._43, &a44 = a._44; - - T mn1 = a33 * a44 - a34 * a43; - T mn2 = a32 * a44 - a34 * a42; - T mn3 = a32 * a43 - a33 * a42; - T mn4 = a31 * a44 - a34 * a41; - T mn5 = a31 * a43 - a33 * a41; - T mn6 = a31 * a42 - a32 * a41; - - T A11 = a22 * mn1 - a23 * mn2 + a24 * mn3; - T A12 = -(a21 * mn1 - a23 * mn4 + a24 * mn5); - T A13 = a21 * mn2 - a22 * mn4 + a24 * mn6; - T A14 = -(a21 * mn3 - a22 * mn5 + a23 * mn6); - - T detInv = a11 * A11 + a12 * A12 + a13 * A13 + a14 * A14; + const float &a11 = a._11, &a12 = a._12, &a13 = a._13, &a14 = a._14; + const float &a21 = a._21, &a22 = a._22, &a23 = a._23, &a24 = a._24; + const float &a31 = a._31, &a32 = a._32, &a33 = a._33, &a34 = a._34; + const float &a41 = a._41, &a42 = a._42, &a43 = a._43, &a44 = a._44; + + float mn1 = a33 * a44 - a34 * a43; + float mn2 = a32 * a44 - a34 * a42; + float mn3 = a32 * a43 - a33 * a42; + float mn4 = a31 * a44 - a34 * a41; + float mn5 = a31 * a43 - a33 * a41; + float mn6 = a31 * a42 - a32 * a41; + + float A11 = a22 * mn1 - a23 * mn2 + a24 * mn3; + float A12 = -(a21 * mn1 - a23 * mn4 + a24 * mn5); + float A13 = a21 * mn2 - a22 * mn4 + a24 * mn6; + float A14 = -(a21 * mn3 - a22 * mn5 + a23 * mn6); + + float detInv = a11 * A11 + a12 * A12 + a13 * A13 + a14 * A14; VERIFY(_abs(detInv) > flt_zero); detInv = 1.f / detInv; @@ -268,8 +260,7 @@ _matrix& _matrix::invert_44(const _matrix& a) return *this; } -template -_matrix& _matrix::transpose(const _matrix& matSource) +Fmatrix& Fmatrix::transpose(const Fmatrix& matSource) { _11 = matSource._11; _12 = matSource._21; @@ -290,11 +281,10 @@ _matrix& _matrix::transpose(const _matrix& matSource) return *this; } -template -_matrix& _matrix::rotateX(T Angle) // rotation about X axis +Fmatrix& Fmatrix::rotateX(float Angle) // rotation about X axis { - T cosa = _cos(Angle); - T sina = _sin(Angle); + float cosa = _cos(Angle); + float sina = _sin(Angle); i.set(1, 0, 0); _14 = 0; j.set(0, cosa, sina); @@ -306,11 +296,10 @@ _matrix& _matrix::rotateX(T Angle) // rotation about X axis return *this; } -template -_matrix& _matrix::rotateY(T Angle) // rotation about Y axis +Fmatrix& Fmatrix::rotateY(float Angle) // rotation about Y axis { - T cosa = _cos(Angle); - T sina = _sin(Angle); + float cosa = _cos(Angle); + float sina = _sin(Angle); i.set(cosa, 0, -sina); _14 = 0; j.set(0, 1, 0); @@ -322,11 +311,10 @@ _matrix& _matrix::rotateY(T Angle) // rotation about Y axis return *this; } -template -_matrix& _matrix::rotateZ(T Angle) // rotation about Z axis +Fmatrix& Fmatrix::rotateZ(float Angle) // rotation about Z axis { - T cosa = _cos(Angle); - T sina = _sin(Angle); + float cosa = _cos(Angle); + float sina = _sin(Angle); i.set(cosa, sina, 0); _14 = 0; j.set(-sina, cosa, 0); @@ -338,10 +326,9 @@ _matrix& _matrix::rotateZ(T Angle) // rotation about Z axis return *this; } -template -_matrix& _matrix::rotation(const Tvector& vdir, const Tvector& vnorm) +Fmatrix& Fmatrix::rotation(const Fvector& vdir, const Fvector& vnorm) { - Tvector vright; + Fvector vright; vright.crossproduct(vnorm, vdir).normalize(); m[0][0] = vright.x; m[0][1] = vright.y; @@ -362,11 +349,10 @@ _matrix& _matrix::rotation(const Tvector& vdir, const Tvector& vnorm) return *this; } -template -_matrix& _matrix::rotation(const Tvector& axis, T Angle) +Fmatrix& Fmatrix::rotation(const Fvector& axis, float Angle) { - T Cosine = _cos(Angle); - T Sine = _sin(Angle); + float Cosine = _cos(Angle); + float Sine = _sin(Angle); m[0][0] = axis.x * axis.x + (1 - axis.x * axis.x) * Cosine; m[0][1] = axis.x * axis.y * (1 - Cosine) + axis.z * Sine; m[0][2] = axis.x * axis.z * (1 - Cosine) - axis.y * Sine; @@ -386,21 +372,14 @@ _matrix& _matrix::rotation(const Tvector& axis, T Angle) return *this; } -template -_matrix& _matrix::mapXYZ() { i.set(1, 0, 0); _14 = 0; j.set(0, 1, 0); _24 = 0; k.set(0, 0, 1); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } -template -_matrix& _matrix::mapXZY() { i.set(1, 0, 0); _14 = 0; j.set(0, 0, 1); _24 = 0; k.set(0, 1, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } -template -_matrix& _matrix::mapYXZ() { i.set(0, 1, 0); _14 = 0; j.set(1, 0, 0); _24 = 0; k.set(0, 0, 1); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } -template -_matrix& _matrix::mapYZX() { i.set(0, 1, 0); _14 = 0; j.set(0, 0, 1); _24 = 0; k.set(1, 0, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } -template -_matrix& _matrix::mapZXY() { i.set(0, 0, 1); _14 = 0; j.set(1, 0, 0); _24 = 0; k.set(0, 1, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } -template -_matrix& _matrix::mapZYX() { i.set(0, 0, 1); _14 = 0; j.set(0, 1, 0); _24 = 0; k.set(1, 0, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } - -template -_matrix& _matrix::mul(const _matrix& A, T v) +Fmatrix& Fmatrix::mapXYZ() { i.set(1, 0, 0); _14 = 0; j.set(0, 1, 0); _24 = 0; k.set(0, 0, 1); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } +Fmatrix& Fmatrix::mapXZY() { i.set(1, 0, 0); _14 = 0; j.set(0, 0, 1); _24 = 0; k.set(0, 1, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } +Fmatrix& Fmatrix::mapYXZ() { i.set(0, 1, 0); _14 = 0; j.set(1, 0, 0); _24 = 0; k.set(0, 0, 1); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } +Fmatrix& Fmatrix::mapYZX() { i.set(0, 1, 0); _14 = 0; j.set(0, 0, 1); _24 = 0; k.set(1, 0, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } +Fmatrix& Fmatrix::mapZXY() { i.set(0, 0, 1); _14 = 0; j.set(1, 0, 0); _24 = 0; k.set(0, 1, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } +Fmatrix& Fmatrix::mapZYX() { i.set(0, 0, 1); _14 = 0; j.set(0, 1, 0); _24 = 0; k.set(1, 0, 0); _34 = 0; c.set(0, 0, 0); _44 = 1; return *this; } + +Fmatrix& Fmatrix::mul(const Fmatrix& A, float v) { m[0][0] = A.m[0][0] * v; m[0][1] = A.m[0][1] * v; @@ -420,8 +399,8 @@ _matrix& _matrix::mul(const _matrix& A, T v) m[3][3] = A.m[3][3] * v; return *this; } -template -_matrix& _matrix::mul(T v) + +Fmatrix& Fmatrix::mul(float v) { m[0][0] *= v; m[0][1] *= v; @@ -441,23 +420,23 @@ _matrix& _matrix::mul(T v) m[3][3] *= v; return *this; } -template -_matrix& _matrix::div(const _matrix& A, T v) + +Fmatrix& Fmatrix::div(const Fmatrix& A, float v) { VERIFY(_abs(v) > 0.000001f); return mul(A, 1.0f / v); } -template -_matrix& _matrix::div(T v) + +Fmatrix& Fmatrix::div(float v) { VERIFY(_abs(v) > 0.000001f); return mul(1.0f / v); } -template -_matrix& _matrix::setHPB(T h, T p, T b) + +Fmatrix& Fmatrix::setHPB(float h, float p, float b) { - T _ch, _cp, _cb, _sh, _sp, _sb, _cc, _cs, _sc, _ss; + float _ch, _cp, _cb, _sh, _sp, _sb, _cc, _cs, _sc, _ss; _sh = _sin(h); _ch = _cos(h); @@ -481,78 +460,19 @@ _matrix& _matrix::setHPB(T h, T p, T b) return *this; } -template -void _matrix::getHPB(T& h, T& p, T& b) const +void Fmatrix::getHPB(float& h, float& p, float& b) const { - T cy = _sqrt(j.y*j.y + i.y*i.y); - if (cy > 16.0f*type_epsilon) + float cy = _sqrt(j.y*j.y + i.y*i.y); + if (cy > 16.0f * type_epsilon) { - h = (T)-atan2(k.x, k.z); - p = (T)-atan2(-k.y, cy); - b = (T)-atan2(i.y, j.y); + h = -atan2(k.x, k.z); + p = -atan2(-k.y, cy); + b = -atan2(i.y, j.y); } else { - h = (T)-atan2(-i.z, i.x); - p = (T)-atan2(-k.y, cy); + h = -atan2(-i.z, i.x); + p = -atan2(-k.y, cy); b = 0; } } - -// explicit instantiations - -template Fmatrix& Fmatrix::rotation(const _quaternion& Q); -template Dmatrix& Dmatrix::rotation(const _quaternion& Q); -template Fmatrix& Fmatrix::mk_xform(const _quaternion& Q, const Tvector& V); -template Dmatrix& Dmatrix::mk_xform(const _quaternion& Q, const Tvector& V); -template Fmatrix& Fmatrix::identity(); -template Dmatrix& Dmatrix::identity(); -template Fmatrix& Fmatrix::mul(const Fmatrix& A, const Fmatrix& B); -template Dmatrix& Dmatrix::mul(const Dmatrix& A, const Dmatrix& B); -template Fmatrix& Fmatrix::mul_43(const Fmatrix& A, const Fmatrix& B); -template Dmatrix& Dmatrix::mul_43(const Dmatrix& A, const Dmatrix& B); -template Fmatrix& Fmatrix::invert(const Fmatrix& a); -template Dmatrix& Dmatrix::invert(const Dmatrix& a); -template bool Fmatrix::invert_b(const Fmatrix& a); -template bool Dmatrix::invert_b(const Dmatrix& a); -template Fmatrix& Fmatrix::invert_44(const Fmatrix& a); -template Dmatrix& Dmatrix::invert_44(const Dmatrix& a); -template Fmatrix& Fmatrix::transpose(const Fmatrix& matSource); -template Dmatrix& Dmatrix::transpose(const Dmatrix& matSource); -template Fmatrix& Fmatrix::rotateX(Fmatrix::TYPE Angle); -template Dmatrix& Dmatrix::rotateX(Dmatrix::TYPE Angle); -template Fmatrix& Fmatrix::rotateY(Fmatrix::TYPE Angle); -template Dmatrix& Dmatrix::rotateY(Dmatrix::TYPE Angle); -template Fmatrix& Fmatrix::rotateZ(Fmatrix::TYPE Angle); -template Dmatrix& Dmatrix::rotateZ(Dmatrix::TYPE Angle); -template Fmatrix& Fmatrix::rotation(const Tvector& vdir, const Tvector& vnorm); -template Dmatrix& Dmatrix::rotation(const Tvector& vdir, const Tvector& vnorm); -template Fmatrix& Fmatrix::rotation(const Tvector& axis, Fmatrix::TYPE Angle); -template Dmatrix& Dmatrix::rotation(const Tvector& axis, Dmatrix::TYPE Angle); - -template Fmatrix& Fmatrix::mapXYZ(); -template Fmatrix& Fmatrix::mapXZY(); -template Fmatrix& Fmatrix::mapYXZ(); -template Fmatrix& Fmatrix::mapYZX(); -template Fmatrix& Fmatrix::mapZXY(); -template Fmatrix& Fmatrix::mapZYX(); -template Dmatrix& Dmatrix::mapXYZ(); -template Dmatrix& Dmatrix::mapXZY(); -template Dmatrix& Dmatrix::mapYXZ(); -template Dmatrix& Dmatrix::mapYZX(); -template Dmatrix& Dmatrix::mapZXY(); -template Dmatrix& Dmatrix::mapZYX(); - -template Fmatrix& Fmatrix::mul(const Fmatrix& A, Fmatrix::TYPE v); -template Dmatrix& Dmatrix::mul(const Dmatrix& A, Dmatrix::TYPE v); -template Fmatrix& Fmatrix::mul(Fmatrix::TYPE v); -template Dmatrix& Dmatrix::mul(Dmatrix::TYPE v); -template Fmatrix& Fmatrix::div(const Fmatrix& A, Fmatrix::TYPE v); -template Dmatrix& Dmatrix::div(const Dmatrix& A, Dmatrix::TYPE v); -template Fmatrix& Fmatrix::div(Fmatrix::TYPE v); -template Dmatrix& Dmatrix::div(Dmatrix::TYPE v); - -template Fmatrix& Fmatrix::setHPB(Fmatrix::TYPE h, Fmatrix::TYPE p, Fmatrix::TYPE b); -template Dmatrix& Dmatrix::setHPB(Dmatrix::TYPE h, Dmatrix::TYPE p, Dmatrix::TYPE b); -template void Fmatrix::getHPB(Fmatrix::TYPE& h, Fmatrix::TYPE& p, Fmatrix::TYPE& b) const; -template void Dmatrix::getHPB(Dmatrix::TYPE& h, Dmatrix::TYPE& p, Dmatrix::TYPE& b) const; diff --git a/src/utils/xrMiscMath/quaternion.cpp b/src/utils/xrMiscMath/quaternion.cpp index a5f26cec029..cd6c7da3985 100644 --- a/src/utils/xrMiscMath/quaternion.cpp +++ b/src/utils/xrMiscMath/quaternion.cpp @@ -3,15 +3,11 @@ #include "xrCore/_quaternion.h" #include "xrCore/_matrix.h" -// -// _quaternion member functions -// - #define TRACE_QZERO_TOLERANCE 0.1f -template -_quaternion& _quaternion::set(const _matrix& M) + +Fquaternion& Fquaternion::set(const Fmatrix& M) { - auto s = T(0); + float s{}; float trace = M._11 + M._22 + M._33; if (trace > 0.0f) @@ -154,9 +150,6 @@ _quaternion& _quaternion::set(const _matrix& M) } -template Fquaternion& Fquaternion::set(const _matrix& M); -template Dquaternion& Dquaternion::set(const _matrix& M); - ////////////////////////////////////////////////////////////////// // quaternion non-member functions diff --git a/src/utils/xrMiscMath/vector.cpp b/src/utils/xrMiscMath/vector.cpp index cba68b9fe96..686a52ea0aa 100644 --- a/src/utils/xrMiscMath/vector.cpp +++ b/src/utils/xrMiscMath/vector.cpp @@ -589,98 +589,56 @@ _vector3& _vector3::mknormal(const _vector3& p0, const _vector3& p1, }; -// instantiations of the previous methods, for float and double +// instantiations of the previous methods, for float template Fvector& Fvector::set_length(Fvector::TYPE l); -template Dvector& Dvector::set_length(Dvector::TYPE l); template Fvector& Fvector::align(); -template Dvector& Dvector::align(); template Fvector& Fvector::squeeze(Fvector::TYPE Epsilon); -template Dvector& Dvector::squeeze(Dvector::TYPE Epsilon); template Fvector& Fvector::clamp(const Fvector& min, const Fvector& max); -template Dvector& Dvector::clamp(const Dvector& min, const Dvector& max); template Fvector& Fvector::clamp(const Fvector& _v); -template Dvector& Dvector::clamp(const Dvector& _v); template Fvector& Fvector::inertion(const Fvector& p, Fvector::TYPE v); -template Dvector& Dvector::inertion(const Dvector& p, Dvector::TYPE v); template Fvector& Fvector::average(const Fvector& p); -template Dvector& Dvector::average(const Dvector& p); template Fvector& Fvector::average(const Fvector& p1, const Fvector& p2); -template Dvector& Dvector::average(const Dvector& p1, const Dvector& p2); template Fvector& Fvector::lerp(const Fvector& p1, const Fvector& p2, Fvector::TYPE t); -template Dvector& Dvector::lerp(const Dvector& p1, const Dvector& p2, Dvector::TYPE t); template Fvector& Fvector::mad(const Fvector& d, Fvector::TYPE m); -template Dvector& Dvector::mad(const Dvector& d, Dvector::TYPE m); template Fvector& Fvector::mad(const Fvector& p, const Fvector& d, Fvector::TYPE m); -template Dvector& Dvector::mad(const Dvector& p, const Dvector& d, Dvector::TYPE m); template Fvector& Fvector::mad(const Fvector& d, const Fvector& s); -template Dvector& Dvector::mad(const Dvector& d, const Dvector& s); template Fvector& Fvector::mad(const Fvector& p, const Fvector& d, const Fvector& s); -template Dvector& Dvector::mad(const Dvector& p, const Dvector& d, const Dvector& s); template Fvector::TYPE Fvector::square_magnitude() const; -template Dvector::TYPE Dvector::square_magnitude() const; template Fvector::TYPE Fvector::magnitude() const; -template Dvector::TYPE Dvector::magnitude() const; template Fvector::TYPE Fvector::normalize_magn(); -template Dvector::TYPE Dvector::normalize_magn(); template Fvector& Fvector::normalize(); -template Dvector& Dvector::normalize(); template Fvector& Fvector::normalize_safe(); -template Dvector& Dvector::normalize_safe(); template Fvector& Fvector::normalize(const Fvector& v); -template Dvector& Dvector::normalize(const Dvector& v); template Fvector& Fvector::normalize_safe(const Fvector& v); -template Dvector& Dvector::normalize_safe(const Dvector& v); template Fvector& Fvector::random_dir(CRandom& R); -template Dvector& Dvector::random_dir(CRandom& R); template Fvector& Fvector::random_dir(const Fvector& ConeAxis, float ConeAngle, CRandom& R); -template Dvector& Dvector::random_dir(const Dvector& ConeAxis, float ConeAngle, CRandom& R); template Fvector& Fvector::random_point(const Fvector& BoxSize, CRandom& R); -template Dvector& Dvector::random_point(const Dvector& BoxSize, CRandom& R); template Fvector& Fvector::random_point(Fvector::TYPE r, CRandom& R); -template Dvector& Dvector::random_point(Dvector::TYPE r, CRandom& R); template Fvector& Fvector::crossproduct(const Fvector& v1, const Fvector& v2); -template Dvector& Dvector::crossproduct(const Dvector& v1, const Dvector& v2); template Fvector::TYPE Fvector::distance_to_xz(const Fvector& v) const; -template Dvector::TYPE Dvector::distance_to_xz(const Dvector& v) const; template Fvector::TYPE Fvector::distance_to_xz_sqr(const Fvector& v) const; -template Dvector::TYPE Dvector::distance_to_xz_sqr(const Dvector& v) const; template Fvector::TYPE Fvector::distance_to_sqr(const Fvector& v) const; -template Dvector::TYPE Dvector::distance_to_sqr(const Dvector& v) const; template Fvector::TYPE Fvector::distance_to(const Fvector& v) const; -template Dvector::TYPE Dvector::distance_to(const Dvector& v) const; template Fvector& Fvector::from_bary(const Fvector& V1, const Fvector& V2, const Fvector& V3, Fvector::TYPE u, Fvector::TYPE v, Fvector::TYPE w); -template Dvector& Dvector::from_bary(const Dvector& V1, const Dvector& V2, const Dvector& V3, Dvector::TYPE u, Dvector::TYPE v, Dvector::TYPE w); template Fvector& Fvector::from_bary(const Fvector& V1, const Fvector& V2, const Fvector& V3, const Fvector& B); -template Dvector& Dvector::from_bary(const Dvector& V1, const Dvector& V2, const Dvector& V3, const Dvector& B); template Fvector& Fvector::from_bary4(const Fvector& V1, const Fvector& V2, const Fvector& V3, const Fvector& V4, Fvector::TYPE u, Fvector::TYPE v, Fvector::TYPE w, Fvector::TYPE t); -template Dvector& Dvector::from_bary4(const Dvector& V1, const Dvector& V2, const Dvector& V3, const Dvector& V4, Dvector::TYPE u, Dvector::TYPE v, Dvector::TYPE w, Dvector::TYPE t); template Fvector& Fvector::mknormal_non_normalized(const Fvector& p0, const Fvector& p1, const Fvector& p2); -template Dvector& Dvector::mknormal_non_normalized(const Dvector& p0, const Dvector& p1, const Dvector& p2); template Fvector& Fvector::mknormal(const Fvector& p0, const Fvector& p1, const Fvector& p2); -template Dvector& Dvector::mknormal(const Dvector& p0, const Dvector& p1, const Dvector& p2); template Fvector& Fvector::setHP(Fvector::TYPE h, Fvector::TYPE p); -template Dvector& Dvector::setHP(Dvector::TYPE h, Dvector::TYPE p); template void Fvector::getHP(Fvector::TYPE& h, Fvector::TYPE& p) const; -template void Dvector::getHP(Dvector::TYPE& h, Dvector::TYPE& p) const; template float Fvector::getH() const; -template float Dvector::getH() const; template float Fvector::getP() const; -template float Dvector::getP() const; template Fvector& Fvector::reflect(const Fvector& dir, const Fvector& norm); -template Dvector& Dvector::reflect(const Dvector& dir, const Dvector& norm); template Fvector& Fvector::slide(const Fvector& dir, const Fvector& norm); -template Dvector& Dvector::slide(const Dvector& dir, const Dvector& norm); template void Fvector::generate_orthonormal_basis(const Fvector& dir, Fvector& up, Fvector& right); -template void Dvector::generate_orthonormal_basis(const Dvector& dir, Dvector& up, Dvector& right); template void Fvector::generate_orthonormal_basis_normalized(Fvector& dir, Fvector& up, Fvector& right); -template void Dvector::generate_orthonormal_basis_normalized(Dvector& dir, Dvector& up, Dvector& right); diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 91130d58571..976587c95ac 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -5,7 +5,6 @@ // Initialized on startup XRCORE_API Fmatrix Fidentity; -XRCORE_API Dmatrix Didentity; XRCORE_API CRandom Random; namespace CPU @@ -102,7 +101,6 @@ void _initialize_cpu() Log(""); Fidentity.identity(); // Identity matrix - Didentity.identity(); // Identity matrix Random.seed(u32(CPU::QPC() % (s64(1) << s32(32)))); pvInitializeStatics(); // Lookup table for compressed normals diff --git a/src/xrCore/_matrix.h b/src/xrCore/_matrix.h index 940ae48f586..f487f2f3ce2 100644 --- a/src/xrCore/_matrix.h +++ b/src/xrCore/_matrix.h @@ -30,39 +30,37 @@ // NOTE_3: I,J,K,C equals to R,N,D,T // NOTE_4: The rotation sequence is ZXY -template struct _quaternion; +struct Fquaternion; -template -struct _matrix +struct Fmatrix { - using TYPE = T; - using Self = _matrix; - using SelfRef = Self&; + using TYPE = float; + using Self = Fmatrix; + using SelfRef = Self&; using SelfCRef = const Self&; - using Tvector = _vector3; union { struct // Direct definition { - T _11, _12, _13, _14; - T _21, _22, _23, _24; - T _31, _32, _33, _34; - T _41, _42, _43, _44; + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; }; struct { - Tvector i; - T _14_; - Tvector j; - T _24_; - Tvector k; - T _34_; - Tvector c; - T _44_; + Fvector i; + float _14_; + Fvector j; + float _24_; + Fvector k; + float _34_; + Fvector c; + float _44_; }; - T m[4][4]; // Array + float m[4][4]; // Array }; // Class members @@ -79,7 +77,7 @@ struct _matrix return *this; } - ICF SelfRef set(const Tvector& R, const Tvector& N, const Tvector& D, const Tvector& C) + ICF SelfRef set(const Fvector& R, const Fvector& N, const Fvector& D, const Fvector& C) { i.set(R); _14_ = 0; @@ -93,8 +91,8 @@ struct _matrix } SelfRef identity(); - SelfRef rotation(const _quaternion& Q); - SelfRef mk_xform(const _quaternion& Q, const Tvector& V); + SelfRef rotation(const Fquaternion& Q); + SelfRef mk_xform(const Fquaternion& Q, const Fvector& V); // Multiply RES = A[4x4]*B[4x4] (WITH projection) SelfRef mul(const Self& A, const Self& B); @@ -154,39 +152,39 @@ struct _matrix return *this; } - IC SelfRef translate(const Tvector& Loc) // setup translation matrix + IC SelfRef translate(const Fvector& Loc) // setup translation matrix { identity(); c.set(Loc.x, Loc.y, Loc.z); return *this; } - IC SelfRef translate(T _x, T _y, T _z) // setup translation matrix + IC SelfRef translate(float _x, float _y, float _z) // setup translation matrix { identity(); c.set(_x, _y, _z); return *this; } - IC SelfRef translate_over(const Tvector& Loc) // modify only translation + IC SelfRef translate_over(const Fvector& Loc) // modify only translation { c.set(Loc.x, Loc.y, Loc.z); return *this; } - IC SelfRef translate_over(T _x, T _y, T _z) // modify only translation + IC SelfRef translate_over(float _x, float _y, float _z) // modify only translation { c.set(_x, _y, _z); return *this; } - IC SelfRef translate_add(const Tvector& Loc) // combine translation + IC SelfRef translate_add(const Fvector& Loc) // combine translation { c.add(Loc); return *this; } - IC SelfRef scale(T x, T y, T z) // setup scale matrix + IC SelfRef scale(float x, float y, float z) // setup scale matrix { identity(); m[0][0] = x; @@ -195,16 +193,16 @@ struct _matrix return *this; } - IC SelfRef scale(const Tvector& v) // setup scale matrix + IC SelfRef scale(const Fvector& v) // setup scale matrix { return scale(v.x, v.y, v.z); } - SelfRef rotateX(T Angle); // rotation about X axis - SelfRef rotateY(T Angle); // rotation about Y axis - SelfRef rotateZ(T Angle); // rotation about Z axis + SelfRef rotateX(float Angle); // rotation about X axis + SelfRef rotateY(float Angle); // rotation about Y axis + SelfRef rotateZ(float Angle); // rotation about Z axis - SelfRef rotation(const Tvector& vdir, const Tvector& vnorm); + SelfRef rotation(const Fvector& vdir, const Fvector& vnorm); SelfRef mapXYZ(); SelfRef mapXZY(); @@ -213,7 +211,7 @@ struct _matrix SelfRef mapZXY(); SelfRef mapZYX(); - SelfRef rotation(const Tvector& axis, T Angle); + SelfRef rotation(const Fvector& axis, float Angle); // mirror X IC SelfRef mirrorX() @@ -275,27 +273,27 @@ struct _matrix return *this; } - SelfRef mul(const Self& A, T v); - SelfRef mul(T v); - SelfRef div(const Self& A, T v); - SelfRef div(T v); + SelfRef mul(const Self& A, float v); + SelfRef mul(float v); + SelfRef div(const Self& A, float v); + SelfRef div(float v); // fov - IC SelfRef build_projection(T fFOV, T fAspect, T fNearPlane, T fFarPlane) + IC SelfRef build_projection(float fFOV, float fAspect, float fNearPlane, float fFarPlane) { return build_projection_HAT(tanf(fFOV / 2.f), fAspect, fNearPlane, fFarPlane); } // half_fov-angle-tangent - IC SelfRef build_projection_HAT(T HAT, T fAspect, T fNearPlane, T fFarPlane) + IC SelfRef build_projection_HAT(float HAT, float fAspect, float fNearPlane, float fFarPlane) { VERIFY(_abs(fFarPlane - fNearPlane) > EPS_S); VERIFY(_abs(HAT) > EPS_S); - T cot = T(1) / HAT; - T w = fAspect * cot; - T h = T(1) * cot; - T Q = fFarPlane / (fFarPlane - fNearPlane); + float cot = 1.0f / HAT; + float w = fAspect * cot; + float h = 1.0f * cot; + float Q = fFarPlane / (fFarPlane - fNearPlane); _11 = w; _12 = 0; @@ -316,44 +314,44 @@ struct _matrix return *this; } - IC SelfRef build_projection_ortho(T w, T h, T zn, T zf) + IC SelfRef build_projection_ortho(float w, float h, float zn, float zf) { - _11 = T(2) / w; + _11 = 2.0f / w; _12 = 0; _13 = 0; _14 = 0; _21 = 0; - _22 = T(2) / h; + _22 = 2.0f / h; _23 = 0; _24 = 0; _31 = 0; _32 = 0; - _33 = T(1) / (zf - zn); + _33 = 1.0f / (zf - zn); _34 = 0; _41 = 0; _42 = 0; _43 = zn / (zn - zf); - _44 = T(1); + _44 = 1.0f; return *this; } - IC SelfRef build_camera(const Tvector& vFrom, const Tvector& vAt, const Tvector& vWorldUp) + IC SelfRef build_camera(const Fvector& vFrom, const Fvector& vAt, const Fvector& vWorldUp) { // Get the z basis vector3, which points straight ahead. This is the // difference from the eyepoint to the lookat point. - Tvector vView; + Fvector vView; vView.sub(vAt, vFrom).normalize(); // Get the dot product, and calculate the projection of the z basis // vector3 onto the up vector3. The projection is the y basis vector3. - T fDotProduct = vWorldUp.dotproduct(vView); + float fDotProduct = vWorldUp.dotproduct(vView); - Tvector vUp; + Fvector vUp; vUp.mul(vView, -fDotProduct).add(vWorldUp).normalize(); // The x basis vector3 is found simply with the cross product of the y // and z basis vectors - Tvector vRight; + Fvector vRight; vRight.crossproduct(vUp, vView); // Start building the Device.mView. The first three rows contains the basis @@ -379,18 +377,18 @@ struct _matrix return *this; } - IC SelfRef build_camera_dir(const Tvector& vFrom, const Tvector& vView, const Tvector& vWorldUp) + IC SelfRef build_camera_dir(const Fvector& vFrom, const Fvector& vView, const Fvector& vWorldUp) { // Get the dot product, and calculate the projection of the z basis // vector3 onto the up vector3. The projection is the y basis vector3. - T fDotProduct = vWorldUp.dotproduct(vView); + float fDotProduct = vWorldUp.dotproduct(vView); - Tvector vUp; + Fvector vUp; vUp.mul(vView, -fDotProduct).add(vWorldUp).normalize(); // The x basis vector3 is found simply with the cross product of the y // and z basis vectors - Tvector vRight; + Fvector vRight; vRight.crossproduct(vUp, vView); // Start building the Device.mView. The first three rows contains the basis @@ -416,9 +414,9 @@ struct _matrix return *this; } - IC SelfRef inertion(const Self& mat, T v) + IC SelfRef inertion(const Self& mat, float v) { - T iv = 1.f - v; + float iv = 1.f - v; for (int i = 0; i < 4; i++) { m[i][0] = m[i][0] * v + mat.m[i][0] * iv; @@ -429,34 +427,34 @@ struct _matrix return *this; } - ICF void transform_tiny(Tvector& dest, const Tvector& v) const // preferred to use + ICF void transform_tiny(Fvector& dest, const Fvector& v) const // preferred to use { dest.x = v.x * _11 + v.y * _21 + v.z * _31 + _41; dest.y = v.x * _12 + v.y * _22 + v.z * _32 + _42; dest.z = v.x * _13 + v.y * _23 + v.z * _33 + _43; } - ICF void transform_tiny32(Fvector2& dest, const Tvector& v) const // preferred to use + ICF void transform_tiny32(Fvector2& dest, const Fvector& v) const // preferred to use { dest.x = v.x * _11 + v.y * _21 + v.z * _31 + _41; dest.y = v.x * _12 + v.y * _22 + v.z * _32 + _42; } - ICF void transform_tiny23(Tvector& dest, const Fvector2& v) const // preferred to use + ICF void transform_tiny23(Fvector& dest, const Fvector2& v) const // preferred to use { dest.x = v.x * _11 + v.y * _21 + _41; dest.y = v.x * _12 + v.y * _22 + _42; dest.z = v.x * _13 + v.y * _23 + _43; } - ICF void transform_dir(Tvector& dest, const Tvector& v) const // preferred to use + ICF void transform_dir(Fvector& dest, const Fvector& v) const // preferred to use { dest.x = v.x * _11 + v.y * _21 + v.z * _31; dest.y = v.x * _12 + v.y * _22 + v.z * _32; dest.z = v.x * _13 + v.y * _23 + v.z * _33; } - IC void transform(Fvector4& dest, const Tvector& v) const // preferred to use + IC void transform(Fvector4& dest, const Fvector& v) const // preferred to use { dest.w = v.x * _14 + v.y * _24 + v.z * _34 + _44; dest.x = (v.x * _11 + v.y * _21 + v.z * _31 + _41) / dest.w; @@ -464,9 +462,9 @@ struct _matrix dest.z = (v.x * _13 + v.y * _23 + v.z * _33 + _43) / dest.w; } - IC void transform(Tvector& dest, const Tvector& v) const // preferred to use + IC void transform(Fvector& dest, const Fvector& v) const // preferred to use { - T iw = 1.f / (v.x * _14 + v.y * _24 + v.z * _34 + _44); + float iw = 1.f / (v.x * _14 + v.y * _24 + v.z * _34 + _44); dest.x = (v.x * _11 + v.y * _21 + v.z * _31 + _41) * iw; dest.y = (v.x * _12 + v.y * _22 + v.z * _32 + _42) * iw; dest.z = (v.x * _13 + v.y * _23 + v.z * _33 + _43) * iw; @@ -480,38 +478,38 @@ struct _matrix dest.z = v.x * _13 + v.y * _23 + v.z * _33 + v.w * _43; } - ICF void transform_tiny(Tvector& v) const + ICF void transform_tiny(Fvector& v) const { - Tvector res; + Fvector res; transform_tiny(res, v); v.set(res); } - IC void transform(Tvector& v) const + IC void transform(Fvector& v) const { - Tvector res; + Fvector res; transform(res, v); v.set(res); } - ICF void transform_dir(Tvector& v) const + ICF void transform_dir(Fvector& v) const { - Tvector res; + Fvector res; transform_dir(res, v); v.set(res); } - SelfRef setHPB(T h, T p, T b); - IC SelfRef setXYZ(T x, T y, T z) { return setHPB(y, x, z); } - IC SelfRef setXYZ(Tvector const& xyz) { return setHPB(xyz.y, xyz.x, xyz.z); } - IC SelfRef setXYZi(T x, T y, T z) { return setHPB(-y, -x, -z); } - IC SelfRef setXYZi(Tvector const& xyz) { return setHPB(-xyz.y, -xyz.x, -xyz.z); } + SelfRef setHPB(float h, float p, float b); + IC SelfRef setXYZ(float x, float y, float z) { return setHPB(y, x, z); } + IC SelfRef setXYZ(Fvector const& xyz) { return setHPB(xyz.y, xyz.x, xyz.z); } + IC SelfRef setXYZi(float x, float y, float z) { return setHPB(-y, -x, -z); } + IC SelfRef setXYZi(Fvector const& xyz) { return setHPB(-xyz.y, -xyz.x, -xyz.z); } // - void getHPB(T& h, T& p, T& b) const; - IC void getHPB(Tvector& hpb) const { getHPB(hpb.x, hpb.y, hpb.z); } - IC void getXYZ(T& x, T& y, T& z) const { getHPB(y, x, z); } - IC void getXYZ(Tvector& xyz) const { getXYZ(xyz.x, xyz.y, xyz.z); } + void getHPB(float& h, float& p, float& b) const; + IC void getHPB(Fvector& hpb) const { getHPB(hpb.x, hpb.y, hpb.z); } + IC void getXYZ(float& x, float& y, float& z) const { getHPB(y, x, z); } + IC void getXYZ(Fvector& xyz) const { getXYZ(xyz.x, xyz.y, xyz.z); } - IC void getXYZi(T& x, T& y, T& z) const + IC void getXYZi(float& x, float& y, float& z) const { getHPB(y, x, z); x *= -1.f; @@ -519,24 +517,19 @@ struct _matrix z *= -1.f; } - IC void getXYZi(Tvector& xyz) const + IC void getXYZi(Fvector& xyz) const { getXYZ(xyz.x, xyz.y, xyz.z); xyz.mul(-1.f); } }; -using Fmatrix = _matrix; -using Dmatrix = _matrix; - -template -bool _valid(const _matrix& m) +inline bool _valid(const Fmatrix& m) { return _valid(m.i) && _valid(m._14_) && _valid(m.j) && _valid(m._24_) && _valid(m.k) && _valid(m._34_) && _valid(m.c) && _valid(m._44_); } extern XRCORE_API Fmatrix Fidentity; -extern XRCORE_API Dmatrix Didentity; #endif diff --git a/src/xrCore/_matrix33.h b/src/xrCore/_matrix33.h index c0fe2ad483b..cb812855cb0 100644 --- a/src/xrCore/_matrix33.h +++ b/src/xrCore/_matrix33.h @@ -1,37 +1,34 @@ #pragma once -#ifndef _matrix33H_ -#define _matrix33H_ + #include "_vector3d.h" #include "_matrix.h" -template -struct _matrix33 +struct Fmatrix33 { public: - typedef _matrix33 Self; + typedef Fmatrix33 Self; typedef Self& SelfRef; typedef const Self& SelfCRef; - typedef _vector3 Tvector; public: union { struct // Direct definition { - T _11, _12, _13; - T _21, _22, _23; - T _31, _32, _33; + float _11, _12, _13; + float _21, _22, _23; + float _31, _32, _33; }; struct { - Tvector i; - Tvector j; - Tvector k; + Fvector i; + Fvector j; + Fvector k; }; - T m[3][3]; // Array + float m[3][3]; // Array }; // Class members - IC SelfRef set_rapid(const _matrix& a) + IC SelfRef set_rapid(const Fmatrix& a) { m[0][0] = a.m[0][0]; m[0][1] = a.m[0][1]; @@ -49,7 +46,7 @@ struct _matrix33 CopyMemory(this, &a, 9 * sizeof(float)); return *this; } - IC SelfRef set(const _matrix& a) + IC SelfRef set(const Fmatrix& a) { _11 = a._11; _12 = a._12; @@ -89,7 +86,7 @@ struct _matrix33 _33 = matSource._33; return *this; } - IC SelfRef transpose(const _matrix& matSource) // faster version of transpose + IC SelfRef transpose(const Fmatrix& matSource) // faster version of transpose { _11 = matSource._11; _12 = matSource._21; @@ -104,7 +101,7 @@ struct _matrix33 } IC SelfRef transpose(void) // self transpose - slower { - _matrix33 a; + Fmatrix33 a; CopyMemory(&a, this, 9 * sizeof(float)); // save matrix transpose(a); return *this; @@ -144,15 +141,15 @@ struct _matrix33 a.m[i][j] = g - s * (h + g * tau); \ a.m[k][l] = h + s * (g - h * tau); - int IC Meigen(Tvector& dout, SelfRef a) + int IC Meigen(Fvector& dout, SelfRef a) { int i; float tresh, theta, tau, t, sm, s, h, g, c; int nrot; - Tvector b; - Tvector z; - _matrix33 v; - Tvector d; + Fvector b; + Fvector z; + Fmatrix33 v; + Fvector d; v.identity(); @@ -294,7 +291,7 @@ struct _matrix33 return *this; } - IC SelfRef MxMpV(SelfCRef M1, SelfCRef M2, const Tvector& V) + IC SelfRef MxMpV(SelfCRef M1, SelfCRef M2, const Fvector& V) { m[0][0] = (M1.m[0][0] * M2.m[0][0] + M1.m[0][1] * M2.m[1][0] + M1.m[0][2] * M2.m[2][0] + V.x); m[1][0] = (M1.m[1][0] * M2.m[0][0] + M1.m[1][1] * M2.m[1][0] + M1.m[1][2] * M2.m[2][0] + V.y); @@ -338,7 +335,7 @@ struct _matrix33 return *this; } - IC SelfRef MskewV(const Tvector& v) + IC SelfRef MskewV(const Fvector& v) { m[0][0] = m[1][1] = m[2][2] = 0.0; m[1][0] = v.z; @@ -349,59 +346,59 @@ struct _matrix33 m[2][1] = v.x; return *this; } - IC SelfRef sMxVpV(Tvector& R, float s1, const Tvector& V1, const Tvector& V2) const + IC SelfCRef sMxVpV(Fvector& R, float s1, const Fvector& V1, const Fvector& V2) const { R.x = s1 * (m[0][0] * V1.x + m[0][1] * V1.y + m[0][2] * V1.z) + V2.x; R.y = s1 * (m[1][0] * V1.x + m[1][1] * V1.y + m[1][2] * V1.z) + V2.y; R.z = s1 * (m[2][0] * V1.x + m[2][1] * V1.y + m[2][2] * V1.z) + V2.z; return *this; } - IC void MTxV(Tvector& R, const Tvector& V1) const + IC void MTxV(Fvector& R, const Fvector& V1) const { R.x = (m[0][0] * V1.x + m[1][0] * V1.y + m[2][0] * V1.z); R.y = (m[0][1] * V1.x + m[1][1] * V1.y + m[2][1] * V1.z); R.z = (m[0][2] * V1.x + m[1][2] * V1.y + m[2][2] * V1.z); } - IC void MTxVpV(Tvector& R, const Tvector& V1, const Tvector& V2) const + IC void MTxVpV(Fvector& R, const Fvector& V1, const Fvector& V2) const { R.x = (m[0][0] * V1.x + m[1][0] * V1.y + m[2][0] * V1.z + V2.x); R.y = (m[0][1] * V1.x + m[1][1] * V1.y + m[2][1] * V1.z + V2.y); R.z = (m[0][2] * V1.x + m[1][2] * V1.y + m[2][2] * V1.z + V2.z); } - IC SelfRef MTxVmV(Tvector& R, const Tvector& V1, const Tvector& V2) const + IC SelfCRef MTxVmV(Fvector& R, const Fvector& V1, const Fvector& V2) const { R.x = (m[0][0] * V1.x + m[1][0] * V1.y + m[2][0] * V1.z - V2.x); R.y = (m[0][1] * V1.x + m[1][1] * V1.y + m[2][1] * V1.z - V2.y); R.z = (m[0][2] * V1.x + m[1][2] * V1.y + m[2][2] * V1.z - V2.z); return *this; } - IC SelfRef sMTxV(Tvector& R, float s1, const Tvector& V1) const + IC SelfCRef sMTxV(Fvector& R, float s1, const Fvector& V1) const { R.x = s1 * (m[0][0] * V1.x + m[1][0] * V1.y + m[2][0] * V1.z); R.y = s1 * (m[0][1] * V1.x + m[1][1] * V1.y + m[2][1] * V1.z); R.z = s1 * (m[0][2] * V1.x + m[1][2] * V1.y + m[2][2] * V1.z); return *this; } - IC SelfRef MxV(Tvector& R, const Tvector& V1) const + IC SelfCRef MxV(Fvector& R, const Fvector& V1) const { R.x = (m[0][0] * V1.x + m[0][1] * V1.y + m[0][2] * V1.z); R.y = (m[1][0] * V1.x + m[1][1] * V1.y + m[1][2] * V1.z); R.z = (m[2][0] * V1.x + m[2][1] * V1.y + m[2][2] * V1.z); return *this; } - IC void transform_dir(_vector2& dest, const _vector2& v) const // preferred to use + IC void transform_dir(Fvector3& dest, const Fvector3& v) const // preferred to use { dest.x = v.x * _11 + v.y * _21; dest.y = v.x * _12 + v.y * _22; dest.z = v.x * _13 + v.y * _23; } - IC void transform_dir(_vector2& v) const + IC void transform_dir(Fvector3& v) const { - _vector2 res; + Fvector3 res; transform_dir(res, v); v.set(res); } - IC SelfRef MxVpV(Tvector& R, const Tvector& V1, const Tvector& V2) const + IC SelfCRef MxVpV(Fvector& R, const Fvector& V1, const Fvector& V2) const { R.x = (m[0][0] * V1.x + m[0][1] * V1.y + m[0][2] * V1.z + V2.x); R.y = (m[1][0] * V1.x + m[1][1] * V1.y + m[1][2] * V1.z + V2.y); @@ -410,13 +407,7 @@ struct _matrix33 } }; -typedef _matrix33 Fmatrix33; -typedef _matrix33 Dmatrix33; - -template -bool _valid(const _matrix33& m) +inline bool _valid(const Fmatrix33& m) { return _valid(m.i) && _valid(m.j) && _valid(m.k); } - -#endif diff --git a/src/xrCore/_obb.h b/src/xrCore/_obb.h index 8d427a14558..b19dd8b22e3 100644 --- a/src/xrCore/_obb.h +++ b/src/xrCore/_obb.h @@ -1,20 +1,16 @@ #pragma once -#ifndef FOBB_H -#define FOBB_H + #include "_matrix33.h" -template -struct _obb +struct Fobb { public: - typedef _obb Self; - typedef Self& SelfRef; - typedef const Self& SelfCRef; - typedef _vector3 Tvector; - typedef _matrix Tmatrix; + using Self = Fobb; + using SelfRef = Self&; + using SelfCRef = const Self&; protected: - static bool clip(T fDenom, T fNumer, T& rfT0, T& rfT1) + static bool clip(float fDenom, float fNumer, float& rfT0, float& rfT1) { // Return value is 'true' if line segment intersects the current test // plane. Otherwise 'false' is returned in which case the line segment @@ -41,9 +37,9 @@ struct _obb return fNumer <= 0.0f; } } - static bool intersect(const Tvector& start, const Tvector& dir, const Tvector& extent, T& rfT0, T& rfT1) + static bool intersect(const Fvector& start, const Fvector& dir, const Fvector& extent, float& rfT0, float& rfT1) { - T fSaveT0 = rfT0, fSaveT1 = rfT1; + float fSaveT0 = rfT0, fSaveT1 = rfT1; bool bNotEntirelyClipped = clip(+dir.x, -start.x - extent[0], rfT0, rfT1) && clip(-dir.x, +start.x - extent[0], rfT0, rfT1) && clip(+dir.y, -start.y - extent[1], rfT0, rfT1) && @@ -54,9 +50,9 @@ struct _obb } public: - _matrix33 m_rotate; - Tvector m_translate; - Tvector m_halfsize; + Fmatrix33 m_rotate; + Fvector m_translate; + Fvector m_halfsize; IC SelfRef invalidate() { @@ -68,10 +64,10 @@ struct _obb IC SelfRef identity() { invalidate(); - m_halfsize.set(T(0.5), T(0.5), T(0.5)); + m_halfsize.set(0.5f, 0.5f, 0.5f); return *this; } - IC void xform_get(Tmatrix& D) const + IC void xform_get(Fmatrix& D) const { D.i.set(m_rotate.i); D._14_ = 0; @@ -82,7 +78,7 @@ struct _obb D.c.set(m_translate); D._44_ = 1; } - IC SelfRef xform_set(const Tmatrix& S) + IC SelfRef xform_set(const Fmatrix& S) { m_rotate.i.set(S.i); m_rotate.j.set(S.j); @@ -90,18 +86,18 @@ struct _obb m_translate.set(S.c); return *this; } - IC void xform_full(Tmatrix& D) const + IC void xform_full(Fmatrix& D) const { - Tmatrix R, S; + Fmatrix R, S; xform_get(R); S.scale(m_halfsize); D.mul_43(R, S); } // NOTE: Unoptimized - IC SelfRef transform(SelfCRef src, const Tmatrix& M) + IC SelfRef transform(SelfCRef src, const Fmatrix& M) { - Tmatrix srcR, destR; + Fmatrix srcR, destR; src.xform_get(srcR); destR.mul_43(M, srcR); @@ -110,17 +106,17 @@ struct _obb return *this; } - IC bool intersect(const Tvector& start, const Tvector& dir, T& dist) const + IC bool intersect(const Fvector& start, const Fvector& dir, float& dist) const { // convert ray to box coordinates - Tvector kDiff; + Fvector kDiff; kDiff.sub(start, m_translate); - Tvector kOrigin; + Fvector kOrigin; kOrigin.set(kDiff.dotproduct(m_rotate.i), kDiff.dotproduct(m_rotate.j), kDiff.dotproduct(m_rotate.k)); - Tvector kDirection; + Fvector kDirection; kDirection.set(dir.dotproduct(m_rotate.i), dir.dotproduct(m_rotate.j), dir.dotproduct(m_rotate.k)); - T fT0 = 0.0f, fT1 = type_max; + float fT0 = 0.0f, fT1 = type_max; if (intersect(kOrigin, kDirection, m_halfsize, fT0, fT1)) { bool bPick = false; @@ -151,13 +147,7 @@ struct _obb } }; -typedef _obb Fobb; -typedef _obb Dobb; - -template -bool _valid(const _obb& m) +inline bool _valid(const Fobb& m) { return _valid(m.m_rotate) && _valid(m.m_translate) && _valid(m.m_halfsize); } - -#endif diff --git a/src/xrCore/_plane.h b/src/xrCore/_plane.h index bad3c8f91ed..0878ed74396 100644 --- a/src/xrCore/_plane.h +++ b/src/xrCore/_plane.h @@ -1,21 +1,19 @@ #pragma once -#ifndef _PLANE -#define _PLANE + #include "_vector3d.h" #include "_matrix.h" -template -class _plane +class Fplane { public: - typedef T TYPE; - typedef _plane Self; - typedef Self& SelfRef; - typedef const Self& SelfCRef; + using TYPE = float; + using Self = Fplane; + using SelfRef = Self&; + using SelfCRef = const Self&; public: - _vector3 n; - T d; + Fvector3 n; + float d; public: IC SelfRef set(Self& P) @@ -24,59 +22,59 @@ class _plane d = P.d; return *this; } - IC BOOL similar(Self& P, T eps_n = EPS, T eps_d = EPS) + IC BOOL similar(Self& P, float eps_n = EPS, float eps_d = EPS) { return (n.similar(P.n, eps_n) && (_abs(d - P.d) < eps_d)); } - ICF SelfRef build(const _vector3& v1, const _vector3& v2, const _vector3& v3) + ICF SelfRef build(const Fvector3& v1, const Fvector3& v2, const Fvector3& v3) { - _vector3 t1, t2; + Fvector3 t1, t2; n.crossproduct(t1.sub(v1, v2), t2.sub(v1, v3)).normalize(); d = -n.dotproduct(v1); return *this; } - ICF SelfRef build_precise(const _vector3& v1, const _vector3& v2, const _vector3& v3) + ICF SelfRef build_precise(const Fvector3& v1, const Fvector3& v2, const Fvector3& v3) { - _vector3 t1, t2; + Fvector3 t1, t2; n.crossproduct(t1.sub(v1, v2), t2.sub(v1, v3)); exact_normalize(n); d = -n.dotproduct(v1); return *this; } - ICF SelfRef build(const _vector3& _p, const _vector3& _n) + ICF SelfRef build(const Fvector3& _p, const Fvector3& _n) { d = -n.normalize(_n).dotproduct(_p); return *this; } - ICF SelfRef build_unit_normal(const _vector3& _p, const _vector3& _n) + ICF SelfRef build_unit_normal(const Fvector3& _p, const Fvector3& _n) { VERIFY(fsimilar(_n.magnitude(), 1, EPS)); d = -n.set(_n).dotproduct(_p); return *this; } - IC SelfCRef project(_vector3& pdest, _vector3 const& psrc) const + IC SelfCRef project(Fvector3& pdest, Fvector3 const& psrc) const { pdest.mad(psrc, n, -classify(psrc)); return *this; } - IC SelfRef project(_vector3& pdest, _vector3 const& psrc) + IC SelfRef project(Fvector3& pdest, Fvector3 const& psrc) { pdest.mad(psrc, n, -classify(psrc)); return *this; } - ICF T classify(const _vector3& v) const { return n.dotproduct(v) + d; } + ICF float classify(const Fvector3& v) const { return n.dotproduct(v) + d; } IC SelfRef normalize() { - T denom = 1.f / n.magnitude(); + float denom = 1.f / n.magnitude(); n.mul(denom); d *= denom; return *this; } - IC T distance(const _vector3& v) { return _abs(classify(v)); } - IC BOOL intersectRayDist(const _vector3& P, const _vector3& D, T& dist) + IC float distance(const Fvector3& v) { return _abs(classify(v)); } + IC BOOL intersectRayDist(const Fvector3& P, const Fvector3& D, float& dist) { - T numer = classify(P); - T denom = n.dotproduct(D); + float numer = classify(P); + float denom = n.dotproduct(D); if (_abs(denom) < EPS_S) // normal is orthogonal to vector3, cant intersect return FALSE; @@ -84,10 +82,10 @@ class _plane dist = -(numer / denom); return ((dist > 0.f) || fis_zero(dist)); } - ICF BOOL intersectRayPoint(const _vector3& P, const _vector3& D, _vector3& dest) + ICF BOOL intersectRayPoint(const Fvector3& P, const Fvector3& D, Fvector3& dest) { - T numer = classify(P); - T denom = n.dotproduct(D); + float numer = classify(P); + float denom = n.dotproduct(D); if (_abs(denom) < EPS_S) return FALSE; // normal is orthogonal to vector3, cant intersect @@ -98,11 +96,11 @@ class _plane return ((dist > 0.f) || fis_zero(dist)); } } - IC BOOL intersect(const _vector3& u, const _vector3& v, // segment - _vector3& isect) // intersection point + IC BOOL intersect(const Fvector3& u, const Fvector3& v, // segment + Fvector3& isect) // intersection point { - T denom, dist; - _vector3 t; + float denom, dist; + Fvector3 t; t.sub(v, u); denom = n.dotproduct(t); @@ -116,11 +114,11 @@ class _plane return true; } - IC BOOL intersect_2(const _vector3& u, const _vector3& v, // segment - _vector3& isect) // intersection point + IC BOOL intersect_2(const Fvector3& u, const Fvector3& v, // segment + Fvector3& isect) // intersection point { - T dist1, dist2; - _vector3 t; + float dist1, dist2; + Fvector3 t; dist1 = n.dotproduct(u) + d; dist2 = n.dotproduct(v) + d; @@ -133,7 +131,7 @@ class _plane return true; } - IC SelfRef transform(_matrix& M) + IC SelfRef transform(Fmatrix& M) { // rotate the normal M.transform_dir(n); @@ -143,13 +141,7 @@ class _plane } }; -typedef _plane Fplane; -typedef _plane Dplane; - -template -bool _valid(const _plane& s) +inline bool _valid(const Fplane& s) { return _valid(s.n) && _valid(s.d); } - -#endif diff --git a/src/xrCore/_plane2.h b/src/xrCore/_plane2.h index f33f5f2f36e..e5a2ff9920d 100644 --- a/src/xrCore/_plane2.h +++ b/src/xrCore/_plane2.h @@ -1,19 +1,16 @@ #pragma once -#ifndef _PLANE2 -#define _PLANE2 -template -class _plane2 +class Fplane2 { public: - typedef T TYPE; - typedef _plane2 Self; - typedef Self& SelfRef; - typedef const Self& SelfCRef; + using TYPE = float; + using Self = Fplane2; + using SelfRef = Self&; + using SelfCRef = const Self&; public: - _vector2 n; - T d; + Fvector2 n; + float d; public: IC SelfRef set(Self& P) @@ -22,33 +19,33 @@ class _plane2 d = P.d; return *this; } - IC BOOL similar(Self& P, T eps_n = EPS, T eps_d = EPS) + IC BOOL similar(Self& P, float eps_n = EPS, float eps_d = EPS) { return (n.similar(P.n, eps_n) && (_abs(d - P.d) < eps_d)); } - IC SelfRef build(const _vector2& _p, const _vector2& _n) + IC SelfRef build(const Fvector2& _p, const Fvector2& _n) { d = -n.normalize(_n).dotproduct(_p); return *this; } - IC SelfRef project(_vector2& pdest, _vector2& psrc) + IC SelfRef project(Fvector2& pdest, Fvector2& psrc) { pdest.mad(psrc, n, -classify(psrc)); return *this; } - IC T classify(const _vector2& v) const { return n.dotproduct(v) + d; } + IC float classify(const Fvector2& v) const { return n.dotproduct(v) + d; } IC SelfRef normalize() { - T denom = 1.f / n.magnitude(); + float denom = 1.f / n.magnitude(); n.mul(denom); d *= denom; return *this; } - IC T distance(const _vector2& v) { return _abs(classify(v)); } - IC BOOL intersectRayDist(const _vector2& P, const _vector2& D, T& dist) + IC float distance(const Fvector2& v) { return _abs(classify(v)); } + IC BOOL intersectRayDist(const Fvector2& P, const Fvector2& D, float& dist) { - T numer = classify(P); - T denom = n.dotproduct(D); + float numer = classify(P); + float denom = n.dotproduct(D); if (_abs(denom) < EPS_S) // normal is orthogonal to vector3, cant intersect return FALSE; @@ -56,10 +53,10 @@ class _plane2 dist = -(numer / denom); return ((dist > 0.f) || fis_zero(dist)); } - IC BOOL intersectRayPoint(const _vector2& P, const _vector2& D, _vector2& dest) + IC BOOL intersectRayPoint(const Fvector2& P, const Fvector2& D, Fvector2& dest) { - T numer = classify(P); - T denom = n.dotproduct(D); + float numer = classify(P); + float denom = n.dotproduct(D); if (_abs(denom) < EPS_S) return FALSE; // normal is orthogonal to vector3, cant intersect @@ -70,11 +67,11 @@ class _plane2 return ((dist > 0.f) || fis_zero(dist)); } } - IC BOOL intersect(const _vector2& u, const _vector2& v, // segment - _vector2& isect) // intersection point + IC BOOL intersect(const Fvector2& u, const Fvector2& v, // segment + Fvector2& isect) // intersection point { - T denom, dist; - _vector2 t; + float denom, dist; + Fvector2 t; t.sub(v, u); denom = n.dotproduct(t); @@ -88,11 +85,11 @@ class _plane2 return true; } - IC BOOL intersect_2(const _vector2& u, const _vector2& v, // segment - _vector2& isect) // intersection point + IC BOOL intersect_2(const Fvector2& u, const Fvector2& v, // segment + Fvector2& isect) // intersection point { - T dist1, dist2; - _vector2 t; + float dist1, dist2; + Fvector2 t; dist1 = n.dotproduct(u) + d; dist2 = n.dotproduct(v) + d; @@ -107,13 +104,7 @@ class _plane2 } }; -typedef _plane2 Fplane2; -typedef _plane2 Dplane2; - -template -bool _valid(const _plane2& s) +inline bool _valid(const Fplane2& s) { return _valid(s.n) && _valid(s.d); } - -#endif diff --git a/src/xrCore/_quaternion.h b/src/xrCore/_quaternion.h index 880a7884c4a..fdfc3d55e5d 100644 --- a/src/xrCore/_quaternion.h +++ b/src/xrCore/_quaternion.h @@ -1,6 +1,5 @@ #pragma once -#ifndef __Q__ -#define __Q__ + #include "_vector3d.h" /*************************************************************************** @@ -141,37 +140,35 @@ #define AA_QZERO_TOLERANCE 0.0001f #define QEPSILON 0.00001f -template -struct _matrix; +struct Fmatrix; -template -struct _quaternion +struct Fquaternion { - using TYPE = T; - using Self = _quaternion; + using TYPE = float; + using Self = Fquaternion; using SelfRef = Self&; using SelfCRef = const Self&; private: - static T _asin_(T val) + static float _asin_(float val) { - const T c1 = 0.892399f; - const T c3 = 1.693204f; - const T c5 = -3.853735f; - const T c7 = 2.838933f; + const float c1 = 0.892399f; + const float c3 = 1.693204f; + const float c5 = -3.853735f; + const float c7 = 2.838933f; - const T x2 = val * val; - const T d = val * (c1 + x2 * (c3 + x2 * (c5 + x2 * c7))); + const float x2 = val * val; + const float d = val * (c1 + x2 * (c3 + x2 * (c5 + x2 * c7))); return d; } - static T _acos_(T val) { return PI_DIV_2 - _asin_(val); } + static float _acos_(float val) { return PI_DIV_2 - _asin_(val); } public: - T x, y, z, w; + float x, y, z, w; - SelfRef set(T W, T X, T Y, T Z) // don't normalize + SelfRef set(float W, float X, float Y, float Z) // don't normalize { x = X; y = Y; @@ -186,7 +183,7 @@ struct _quaternion return *this; } - SelfRef set(const _matrix& m); + SelfRef set(const Fmatrix& m); // multiplies q1 * q2, and places the result in *this. // no failure. renormalization not automatic @@ -266,7 +263,7 @@ struct _quaternion // checks for Unit-length quaternion bool isUnit() const { - T m = magnitude(); + float m = magnitude(); if ((m < 1.0 + UNIT_TOLERANCE) && (m > 1.0 - UNIT_TOLERANCE)) return true; @@ -276,12 +273,12 @@ struct _quaternion // normalizes Q to be a unit geQuaternion SelfRef normalize() { - T m = _sqrt(magnitude()); + float m = _sqrt(magnitude()); if ((m < QZERO_TOLERANCE) && (m > -QZERO_TOLERANCE)) return *this; - T one_over_magnitude = 1.0f / m; + float one_over_magnitude = 1.0f / m; w *= one_over_magnitude; x *= one_over_magnitude; @@ -300,17 +297,17 @@ struct _quaternion SelfRef identity() { return set(1.f, 0.f, 0.f, 0.f); } // square length - T magnitude() { return w * w + x * x + y * y + z * z; } + float magnitude() const { return w * w + x * x + y * y + z * z; } // makes unit rotation - SelfRef rotationYawPitchRoll(T _x, T _y, T _z) + SelfRef rotationYawPitchRoll(float _x, float _y, float _z) { - T fSinYaw = _sin(_x * .5f); - T fCosYaw = _cos(_x * .5f); - T fSinPitch = _sin(_y * .5f); - T fCosPitch = _cos(_y * .5f); - T fSinRoll = _sin(_z * .5f); - T fCosRoll = _cos(_z * .5f); + float fSinYaw = _sin(_x * .5f); + float fCosYaw = _cos(_x * .5f); + float fSinPitch = _sin(_y * .5f); + float fCosPitch = _cos(_y * .5f); + float fSinRoll = _sin(_z * .5f); + float fCosRoll = _cos(_z * .5f); x = fSinRoll * fCosPitch * fCosYaw - fCosRoll * fSinPitch * fSinYaw; y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw; @@ -323,12 +320,10 @@ struct _quaternion SelfRef rotationYawPitchRoll(const Fvector& ypr) { return rotationYawPitchRoll(ypr.x, ypr.y, ypr.z); } // set a quaternion from an axis and a rotation around the axis - SelfRef rotation(Fvector& axis, T angle) + SelfRef rotation(Fvector& axis, float angle) { - T sinTheta; - w = _cos(angle * 0.5f); - sinTheta = _sin(angle * 0.5f); + const float sinTheta = _sin(angle * 0.5f); x = sinTheta * axis.x; y = sinTheta * axis.y; z = sinTheta * axis.z; @@ -339,12 +334,12 @@ struct _quaternion // returns TRUE if there is an axis. // returns FALSE if there is no axis (and Axis is set to 0,0,0, and Theta is 0) - bool get_axis_angle(_vector3& axis, T& angle) + bool get_axis_angle(Fvector& axis, float& angle) { - T s = _sqrt(x * x + y * y + z * z); + float s = _sqrt(x * x + y * y + z * z); if (s > EPS_S) { - T OneOverSinTheta = 1.f / s; + float OneOverSinTheta = 1.f / s; axis.x = OneOverSinTheta * x; axis.y = OneOverSinTheta * y; axis.z = OneOverSinTheta * z; @@ -361,16 +356,16 @@ struct _quaternion // with t==0 being all q0, and t==1 being all q1. // returns a quaternion with a positive W - always takes shortest route // through the positive W domain. - ICF SelfRef slerp(SelfCRef Q0, SelfCRef Q1, T tm) + ICF SelfRef slerp(SelfCRef Q0, SelfCRef Q1, float tm) { - T Scale0, Scale1, sign; + float Scale0, Scale1, sign; #ifdef DEBUG - if (!((T(0) <= tm) && (tm <= T(1)))) + if (!(0.0f <= tm && tm <= 1.0f)) xrDebug::Fatal(DEBUG_INFO, "Quaternion::slerp - invalid 'tm' arrived: %f", tm); #endif - T cosom = (Q0.w * Q1.w) + (Q0.x * Q1.x) + (Q0.y * Q1.y) + (Q0.z * Q1.z); + float cosom = (Q0.w * Q1.w) + (Q0.x * Q1.x) + (Q0.y * Q1.y) + (Q0.z * Q1.z); if (cosom < 0) { @@ -384,9 +379,9 @@ struct _quaternion if ((1.0f - cosom) > EPS) { - T omega = _acos_(cosom); - T i_sinom = 1.f / _sin(omega); - T t_omega = tm * omega; + float omega = _acos_(cosom); + float i_sinom = 1.f / _sin(omega); + float t_omega = tm * omega; Scale0 = _sin(omega - t_omega) * i_sinom; Scale1 = _sin(t_omega) * i_sinom; } @@ -407,7 +402,7 @@ struct _quaternion } // return true if quaternions differ elementwise by less than Tolerance. - bool cmp(SelfCRef Q, T Tolerance = 0.0001f) + bool cmp(SelfCRef Q, float Tolerance = 0.0001f) { if (// they are the same but with opposite signs ((_abs(x + Q.x) <= Tolerance) && (_abs(y + Q.y) <= Tolerance) && (_abs(z + Q.z) <= Tolerance) && @@ -420,21 +415,21 @@ struct _quaternion SelfRef ln(SelfCRef Q) { - T n = Q.x * Q.x + Q.y * Q.y + Q.z * Q.z; - T r = _sqrt(n); - T t = (r > EPS_S) ? std::atan2(r, Q.w) / r : T(0); + float n = Q.x * Q.x + Q.y * Q.y + Q.z * Q.z; + float r = _sqrt(n); + float t = (r > EPS_S) ? std::atan2(r, Q.w) / r : float(0); x = t * Q.x; y = t * Q.y; z = t * Q.z; - w = .5f * _log(n + Q.w * Q.w); + w = .5f * std::log(n + Q.w * Q.w); return *this; } SelfRef exp(SelfCRef Q) { - T r = _sqrt(Q.x * Q.x + Q.y * Q.y + Q.z * Q.z); - T et = std::exp(Q.w); - T s = (r >= EPS_S) ? et * _sin(r) / r : 0.f; + float r = _sqrt(Q.x * Q.x + Q.y * Q.y + Q.z * Q.z); + float et = std::exp(Q.w); + float s = (r >= EPS_S) ? et * _sin(r) / r : 0.f; x = s * Q.x; y = s * Q.y; z = s * Q.z; @@ -443,11 +438,7 @@ struct _quaternion } }; -using Fquaternion = _quaternion; -using Dquaternion = _quaternion; - -template -bool _valid(const _quaternion& s) +inline bool _valid(const Fquaternion& s) { return _valid(s.x) && _valid(s.y) && _valid(s.z) && _valid(s.w); } @@ -457,5 +448,3 @@ bool _valid(const _quaternion& s) #undef TRACE_QZERO_TOLERANCE #undef AA_QZERO_TOLERANCE #undef QEPSILON - -#endif diff --git a/src/xrCore/_rect.h b/src/xrCore/_rect.h index 878b5362394..386ca964870 100644 --- a/src/xrCore/_rect.h +++ b/src/xrCore/_rect.h @@ -194,9 +194,8 @@ struct _rect } }; -typedef _rect Frect; -typedef _rect Drect; -typedef _rect Irect; +using Frect = _rect; +using Irect = _rect; template bool _valid(const _rect& m) diff --git a/src/xrCore/_vector2.h b/src/xrCore/_vector2.h index e6ac96433e4..72f26b10548 100644 --- a/src/xrCore/_vector2.h +++ b/src/xrCore/_vector2.h @@ -250,8 +250,8 @@ struct _vector2 } }; -typedef _vector2 Fvector2; -typedef _vector2 Ivector2; +using Fvector2 = _vector2; +using Ivector2 = _vector2; template bool _valid(const _vector2& v) diff --git a/src/xrCore/_vector3d.h b/src/xrCore/_vector3d.h index 9a26fe6995b..d6e7fc7aa46 100644 --- a/src/xrCore/_vector3d.h +++ b/src/xrCore/_vector3d.h @@ -344,9 +344,6 @@ struct _vector3 using Fvector = _vector3; using Fvector3 = _vector3; -using Dvector = _vector3; -using Dvector3 = _vector3; - using Ivector = _vector3; using Ivector3 = _vector3; diff --git a/src/xrCore/_vector4.h b/src/xrCore/_vector4.h index 733bba0216c..71460a0fe13 100644 --- a/src/xrCore/_vector4.h +++ b/src/xrCore/_vector4.h @@ -203,7 +203,6 @@ struct _vector4 }; typedef _vector4 Fvector4; -typedef _vector4 Dvector4; typedef _vector4 Ivector4; template diff --git a/src/xrCore/dump_string.h b/src/xrCore/dump_string.h index 6b0091545a8..d1101cb46f0 100644 --- a/src/xrCore/dump_string.h +++ b/src/xrCore/dump_string.h @@ -4,7 +4,7 @@ // fwd. decl. template struct _vector3; typedef _vector3 Fvector; -template struct _matrix; typedef _matrix Fmatrix; +struct Fmatrix; struct Fbox3; using Fbox = Fbox3; XRCORE_API std::string get_string(bool v); diff --git a/src/xrCore/log.h b/src/xrCore/log.h index f436fbd73c6..41edd74c596 100644 --- a/src/xrCore/log.h +++ b/src/xrCore/log.h @@ -6,7 +6,7 @@ // fwd. decl. template struct _vector3; typedef _vector3 Fvector; -template struct _matrix; typedef _matrix Fmatrix; +struct Fmatrix; #define VPUSH(a) ((a).x), ((a).y), ((a).z) diff --git a/src/xrCore/vector.h b/src/xrCore/vector.h index 0ea6de54b17..b3c206c82bc 100644 --- a/src/xrCore/vector.h +++ b/src/xrCore/vector.h @@ -12,8 +12,7 @@ #include "_std_extensions.h" #include "xrCommon/math_funcs_inline.h" -template -struct _quaternion; +struct Fquaternion; #pragma pack(push) #pragma pack(1) diff --git a/src/xrEngine/IPhysicsShell.h b/src/xrEngine/IPhysicsShell.h index 56c808e8729..11938e161f4 100644 --- a/src/xrEngine/IPhysicsShell.h +++ b/src/xrEngine/IPhysicsShell.h @@ -5,8 +5,7 @@ // fwd. decl. template struct _vector3; using Fvector = _vector3; -template struct _matrix; -using Fmatrix = _matrix; +struct Fmatrix; class IPhysicsGeometry; class IPhysicsElement diff --git a/src/xrPhysics/MathUtils.h b/src/xrPhysics/MathUtils.h index d06ca1ef7e2..e0ee4b26622 100644 --- a/src/xrPhysics/MathUtils.h +++ b/src/xrPhysics/MathUtils.h @@ -10,8 +10,7 @@ #endif constexpr float phInfinity = std::numeric_limits::infinity(); -template struct _quaternion; -typedef _quaternion Fquaternion; +struct Fquaternion; IC float* cast_fp(Fvector& fv) { return (float*)(&fv); } IC const float* cast_fp(const Fvector& fv) { return (const float*)(&fv); } diff --git a/src/xrPhysics/PhysicsShell.h b/src/xrPhysics/PhysicsShell.h index 086e1d52e61..6a700082da1 100644 --- a/src/xrPhysics/PhysicsShell.h +++ b/src/xrPhysics/PhysicsShell.h @@ -31,8 +31,8 @@ struct dMass; struct SAllDDOParams; struct Fcylinder; struct Fsphere; -template struct _obb; typedef _obb Fobb; -template struct _quaternion; typedef _quaternion Fquaternion; +struct Fobb; +struct Fquaternion; enum motion_history_state { diff --git a/src/xrPhysics/debug_output.h b/src/xrPhysics/debug_output.h index 9a6d9ae8d78..c23b655247b 100644 --- a/src/xrPhysics/debug_output.h +++ b/src/xrPhysics/debug_output.h @@ -7,8 +7,7 @@ // fwd. decl. template struct _vector3; using Fvector = _vector3; -template struct _matrix; -using Fmatrix = _matrix; +struct Fmatrix; namespace CDB { From cd00d9f0c38afe142a2d8a9bd53cd17e3ce61c08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 12:50:21 +0000 Subject: [PATCH 444/497] build(deps): bump Externals/sse2neon from `de0538f` to `42c7047` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `de0538f` to `42c7047`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/de0538f21662353aadb74abd91634e3f8f5bbd85...42c704755d3ec218ed9126a122f0a667beeb630a) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index de0538f2166..42c704755d3 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit de0538f21662353aadb74abd91634e3f8f5bbd85 +Subproject commit 42c704755d3ec218ed9126a122f0a667beeb630a From a29ea70aeaec4f51fae5315fbdce40c9bd97e785 Mon Sep 17 00:00:00 2001 From: Krzysztof Sobiecki Date: Mon, 27 May 2024 22:31:13 +0200 Subject: [PATCH 445/497] SDL 2.0.18 is now the required minimum (#1683) Remove redundant SDL_VERSION_ATLEAST for versions <= 2.0.18 --- CMakeLists.txt | 2 +- src/xrCore/_math.cpp | 16 ---------------- src/xrEngine/Device_imgui.cpp | 4 ---- src/xrEngine/Device_mode.cpp | 10 ---------- src/xrEngine/device.cpp | 15 --------------- src/xrEngine/x_ray.cpp | 2 -- src/xrEngine/xr_input.cpp | 30 ++---------------------------- src/xrEngine/xr_input.h | 2 +- 8 files changed, 4 insertions(+), 77 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 750c006e7bc..c10fdce44e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,7 +230,7 @@ add_compile_definitions( ) if (NOT WIN32) - find_package(SDL2 REQUIRED) + find_package(SDL2 2.0.18 REQUIRED) # Fix to support older SDL2 # https://github.com/OpenXRay/xray-16/issues/1595 if (NOT TARGET SDL2::SDL2 AND DEFINED SDL2_LIBRARIES) diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 976587c95ac..d8455de3746 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -13,23 +13,11 @@ XRCORE_API bool HasSSE = SDL_HasSSE(); XRCORE_API bool HasSSE2 = SDL_HasSSE2(); XRCORE_API bool HasSSE42 = SDL_HasSSE42(); -#if SDL_VERSION_ATLEAST(2, 0, 6) XRCORE_API bool HasAVX = SDL_HasAVX(); -#else -XRCORE_API bool HasAVX = false(); -#endif -#if SDL_VERSION_ATLEAST(2, 0, 9) XRCORE_API bool HasAVX2 = SDL_HasAVX2(); -#else -XRCORE_API bool HasAVX2 = false; -#endif -#if SDL_VERSION_ATLEAST(2, 0, 9) XRCORE_API bool HasAVX512F = SDL_HasAVX512F(); -#else -XRCORE_API bool HasAVX512F = false; -#endif XRCORE_API u64 qpc_freq = SDL_GetPerformanceFrequency(); @@ -85,12 +73,8 @@ void _initialize_cpu() // Other architectures listFeature("AltiVec", SDL_HasAltiVec()); -#if SDL_VERSION_ATLEAST(2, 0, 12) listFeature("ARMSIMD", SDL_HasARMSIMD()); -#endif -#if SDL_VERSION_ATLEAST(2, 0, 6) listFeature("NEON", SDL_HasNEON()); -#endif #if SDL_VERSION_ATLEAST(2, 24, 0) listFeature("LSX", SDL_HasLSX()); listFeature("LASX", SDL_HasLASX()); diff --git a/src/xrEngine/Device_imgui.cpp b/src/xrEngine/Device_imgui.cpp index 73de207ace6..e7f4d8dd490 100644 --- a/src/xrEngine/Device_imgui.cpp +++ b/src/xrEngine/Device_imgui.cpp @@ -72,9 +72,7 @@ void CRenderDevice::InitializeImGui() // See SDL hack in ImGui_ImplSDL2_ShowWindow(). sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; #endif -#if SDL_VERSION_ATLEAST(2, 0, 5) sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; -#endif const auto vd = IM_NEW(ImGuiViewportData) { @@ -192,13 +190,11 @@ void CRenderDevice::InitializeImGui() SDL_SetWindowTitle(vd->Window, title); }; -#if SDL_VERSION_ATLEAST(2, 0, 5) platform_io.Platform_SetWindowAlpha = [](ImGuiViewport* viewport, float alpha) { const auto vd = static_cast(viewport->PlatformUserData); SDL_SetWindowOpacity(vd->Window, alpha); }; -#endif #endif // IMGUI_ENABLE_VIEWPORTS editor().InitBackend(); diff --git a/src/xrEngine/Device_mode.cpp b/src/xrEngine/Device_mode.cpp index c68a8a1107a..7ef06408f76 100644 --- a/src/xrEngine/Device_mode.cpp +++ b/src/xrEngine/Device_mode.cpp @@ -38,19 +38,15 @@ void FillImGuiMonitorData(const int monitorID) monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); -#if SDL_VERSION_ATLEAST(2, 0, 5) SDL_GetDisplayUsableBounds(monitorID, &r); monitor.WorkPos = ImVec2((float)r.x, (float)r.y); monitor.WorkSize = ImVec2((float)r.w, (float)r.h); -#endif -#if SDL_VERSION_ATLEAST(2, 0, 4) // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set // DpiScale to cocoa_window.backingScaleFactor here. float dpi = 0.0f; if (!SDL_GetDisplayDPI(monitorID, &dpi, nullptr, nullptr)) monitor.DpiScale = dpi / 96.0f; -#endif monitor.PlatformHandle = (void*)(intptr_t)monitorID; platform_io.Monitors.push_back(monitor); @@ -107,9 +103,7 @@ void CRenderDevice::SetWindowDraggable(bool draggable) const bool resizable = SDL_GetWindowFlags(Device.m_sdlWnd) & SDL_WINDOW_RESIZABLE; m_allowWindowDrag = draggable && windowed && resizable; -#if SDL_VERSION_ATLEAST(2, 0, 5) SDL_SetWindowOpacity(Device.m_sdlWnd, m_allowWindowDrag ? 0.95f : 1.0f); -#endif } void CRenderDevice::UpdateWindowProps() @@ -180,14 +174,12 @@ void CRenderDevice::UpdateWindowRects() SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowBounds.x, &m_rcWindowBounds.y); SDL_GetWindowSize(m_sdlWnd, &m_rcWindowBounds.w, &m_rcWindowBounds.h); -#if SDL_VERSION_ATLEAST(2, 0, 5) int top, left, bottom, right; SDL_GetWindowBordersSize(m_sdlWnd, &top, &left, &bottom, &right); m_rcWindowBounds.x -= left; m_rcWindowBounds.y -= top; m_rcWindowBounds.w += right; m_rcWindowBounds.h += bottom; -#endif } void CRenderDevice::SelectResolution(const bool windowed) @@ -268,9 +260,7 @@ void CRenderDevice::OnFatalError() { // make it sure window will hide in any way SDL_SetWindowFullscreen(m_sdlWnd, SDL_FALSE); -#if SDL_VERSION_ATLEAST(2, 0, 16) SDL_SetWindowAlwaysOnTop(m_sdlWnd, SDL_FALSE); -#endif SDL_ShowWindow(m_sdlWnd); SDL_MinimizeWindow(m_sdlWnd); SDL_HideWindow(m_sdlWnd); diff --git a/src/xrEngine/device.cpp b/src/xrEngine/device.cpp index e44da42edd1..0ac30bdc92d 100644 --- a/src/xrEngine/device.cpp +++ b/src/xrEngine/device.cpp @@ -307,23 +307,16 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) switch (event.type) { -#if SDL_VERSION_ATLEAST(2, 0, 9) case SDL_DISPLAYEVENT: { switch (event.display.type) { case SDL_DISPLAYEVENT_ORIENTATION: -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_DISPLAYEVENT_CONNECTED: case SDL_DISPLAYEVENT_DISCONNECTED: -#endif CleanupVideoModes(); FillVideoModes(); -#if SDL_VERSION_ATLEAST(2, 0, 14) if (event.display.display == psDeviceMode.Monitor && event.display.type != SDL_DISPLAYEVENT_CONNECTED) -#else - if (event.display.display == psDeviceMode.Monitor) -#endif Reset(); else UpdateWindowProps(); @@ -331,7 +324,6 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) } // switch (event.display.type) break; } -#endif case SDL_WINDOWEVENT: { const auto window = SDL_GetWindowFromID(event.window.windowID); @@ -348,22 +340,15 @@ void CRenderDevice::ProcessEvent(const SDL_Event& event) if (window == m_sdlWnd) { UpdateWindowRects(); -#if !SDL_VERSION_ATLEAST(2, 0, 18) // without SDL_WINDOWEVENT_DISPLAY_CHANGED, let's detect monitor change ourselves - const int display = SDL_GetWindowDisplayIndex(window); - if (display != -1) - psDeviceMode.Monitor = display; -#endif } if (viewport) viewport->PlatformRequestMove = true; break; } -#if SDL_VERSION_ATLEAST(2, 0, 18) case SDL_WINDOWEVENT_DISPLAY_CHANGED: psDeviceMode.Monitor = event.window.data1; break; -#endif case SDL_WINDOWEVENT_RESIZED: if (window == m_sdlWnd) diff --git a/src/xrEngine/x_ray.cpp b/src/xrEngine/x_ray.cpp index 35d2fa228c5..b4301ea2952 100644 --- a/src/xrEngine/x_ray.cpp +++ b/src/xrEngine/x_ray.cpp @@ -459,10 +459,8 @@ void CApplication::ShowSplash(bool topmost) Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN; -#if SDL_VERSION_ATLEAST(2,0,5) if (topmost) flags |= SDL_WINDOW_ALWAYS_ON_TOP; -#endif m_window = SDL_CreateWindow("OpenXRay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_surface->w, m_surface->h, flags); SDL_ShowWindow(m_window); diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index 52502204343..34f7f829b56 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -92,19 +92,16 @@ void CInput::OpenController(int idx) if (!controller) return; -#if SDL_VERSION_ATLEAST(2, 0, 14) if (psControllerEnableSensors.test(1)) SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); -#endif + controllers.emplace_back(controller); } void CInput::EnableControllerSensors(bool enable) { -#if SDL_VERSION_ATLEAST(2, 0, 14) for (auto controller : controllers) SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, enable ? SDL_TRUE : SDL_FALSE); -#endif } //----------------------------------------------------------------------- @@ -134,12 +131,8 @@ void CInput::MouseUpdate() static_assert(std::size(IdxToKey) == COUNT_MOUSE_BUTTONS); bool mouseMoved = false; -#if SDL_VERSION_ATLEAST(2, 0, 18) int offs[2]{}; float scroll[2]{}; -#else - int offs[COUNT_MOUSE_AXIS]{}; -#endif const auto mousePrev = mouseState; mouseAxisState[2] = 0; mouseAxisState[3] = 0; @@ -182,13 +175,8 @@ void CInput::MouseUpdate() } case SDL_MOUSEWHEEL: mouseMoved = true; -#if SDL_VERSION_ATLEAST(2, 0, 18) scroll[0] += event.wheel.preciseX; scroll[1] += event.wheel.preciseY; -#else - offs[2] += event.wheel.x; - offs[3] += event.wheel.y; -#endif mouseAxisState[2] += event.wheel.x; mouseAxisState[3] += event.wheel.y; break; @@ -205,13 +193,9 @@ void CInput::MouseUpdate() { if (offs[0] || offs[1]) cbStack.back()->IR_OnMouseMove(offs[0], offs[1]); -#if SDL_VERSION_ATLEAST(2, 0, 18) + if (!fis_zero(scroll[0]) || !fis_zero(scroll[1])) cbStack.back()->IR_OnMouseWheel(scroll[0], scroll[1]); -#else - if (offs[2] || offs[3]) - cbStack.back()->IR_OnMouseWheel(offs[2], offs[3]); -#endif } } @@ -341,11 +325,7 @@ void CInput::ControllerUpdate() decltype(controllerAxisState) controllerAxisStatePrev; CopyMemory(controllerAxisStatePrev, controllerAxisState, sizeof(controllerAxisState)); -#if SDL_VERSION_ATLEAST(2, 0, 14) constexpr SDL_EventType MAX_EVENT = SDL_CONTROLLERSENSORUPDATE; -#else - constexpr SDL_EventType MAX_EVENT = SDL_CONTROLLERDEVICEREMAPPED; -#endif count = SDL_PeepEvents(events, MAX_CONTROLLER_EVENTS, SDL_GETEVENT, SDL_CONTROLLERAXISMOTION, MAX_EVENT); @@ -411,7 +391,6 @@ void CInput::ControllerUpdate() break; } -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERSENSORUPDATE: { if (last_input_controller != event.csensor.which) // only use data from the recently used controller @@ -424,7 +403,6 @@ void CInput::ControllerUpdate() cbStack.back()->IR_OnControllerAttitudeChange(gyro); break; } -#endif } // switch (event.type) } @@ -749,7 +727,6 @@ bool CInput::IsExclusiveMode() const void CInput::Feedback(FeedbackType type, float s1, float s2, float duration) { -#if SDL_VERSION_ATLEAST(2, 0, 9) const u16 s1_rumble = iFloor(u16(-1) * clampr(s1, 0.0f, 1.0f)); const u16 s2_rumble = iFloor(u16(-1) * clampr(s2, 0.0f, 1.0f)); const u32 duration_ms = duration < 0.f ? 0 : iFloor(duration * 1000.f); @@ -768,17 +745,14 @@ void CInput::Feedback(FeedbackType type, float s1, float s2, float duration) case FeedbackTriggers: { -#if SDL_VERSION_ATLEAST(2, 0, 14) if (last_input_controller != -1) { const auto controller = SDL_GameControllerFromInstanceID(last_input_controller); SDL_GameControllerRumbleTriggers(controller, s1_rumble, s2_rumble, duration_ms); } break; -#endif } default: NODEFAULT; } -#endif } diff --git a/src/xrEngine/xr_input.h b/src/xrEngine/xr_input.h index 75c6b00e9c1..af2a99d79bd 100644 --- a/src/xrEngine/xr_input.h +++ b/src/xrEngine/xr_input.h @@ -4,7 +4,7 @@ #include -#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) +#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) # define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 #else # define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 From 13d516081c107f236ea7507bfb2ea6ca0a1b72d1 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 29 May 2024 23:00:33 +0500 Subject: [PATCH 446/497] Remove sound precaching This commit reverts changes made in #407, they will be replaced with asynchronous sound loading. --- src/xrEngine/IGame_Persistent.cpp | 6 --- src/xrEngine/xr_ioc_cmd.cpp | 3 -- src/xrSound/Sound.h | 3 -- src/xrSound/SoundRender_Core.cpp | 1 - src/xrSound/SoundRender_Core.h | 8 --- .../SoundRender_Core_SourceManager.cpp | 49 ------------------- src/xrSound/SoundRender_Source.cpp | 10 ++-- src/xrSound/SoundRender_Source.h | 4 +- 8 files changed, 7 insertions(+), 77 deletions(-) diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 691ad705ca1..bf17012c70f 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -403,12 +403,6 @@ void IGame_Persistent::Prefetch() timer.Start(); const auto memoryBefore = Memory.mem_usage(); - if (psSoundPrecacheAll != 0) - { - Log("Loading sounds..."); - GEnv.Sound->prefetch(); - } - Log("Loading objects..."); ObjectPool.prefetch(); diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index e6c9f398007..0a8ec2eec5e 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -19,8 +19,6 @@ extern xr_map> vid_mode_token; const xr_token vid_bpp_token[] = {{"16", 16}, {"32", 32}, {0, 0}}; -const xr_token snd_precache_all_token[] = {{"off", 0}, {"on", 1}, {nullptr, 0}}; - void IConsole_Command::InvalidSyntax() { TInfo I; @@ -892,7 +890,6 @@ void CCC_Register() CMD3(CCC_Mask, "snd_use_float32", &psSoundFlags, ss_UseFloat32); CMD4(CCC_Integer, "snd_targets", &psSoundTargets, 4, 256); CMD4(CCC_Integer, "snd_cache_size", &psSoundCacheSizeMB, 4, 64); - CMD3(CCC_Token, "snd_precache_all", &psSoundPrecacheAll, snd_precache_all_token); #ifdef DEBUG CMD3(CCC_Mask, "snd_stats", &g_stats_flags, st_sound); diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 8b79b5b1751..71089dd8f31 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -50,7 +50,6 @@ XRSOUND_API extern float psSoundTimeFactor; //--#SM+#-- XRSOUND_API extern Flags32 psSoundFlags; XRSOUND_API extern int psSoundTargets; XRSOUND_API extern int psSoundCacheSizeMB; -XRSOUND_API extern u32 psSoundPrecacheAll; XRSOUND_API extern u32 snd_device_id; XRSOUND_API extern ISoundScene* DefaultSoundScene; @@ -222,8 +221,6 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void _restart() = 0; virtual bool i_locked() = 0; - virtual void prefetch() = 0; - virtual void stop_emitters() = 0; virtual int pause_emitters(bool pauseState) = 0; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 8541c4455f0..018684357b6 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -28,7 +28,6 @@ XRSOUND_API float psSoundVFactor = 1.0f; XRSOUND_API float psSoundVMusic = 1.f; XRSOUND_API int psSoundCacheSizeMB = 32; -XRSOUND_API u32 psSoundPrecacheAll = 1; CSoundRender_Core* SoundRender = nullptr; diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 35732afb6bb..3fe18ebbd16 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -100,13 +100,6 @@ class CSoundRender_Core : public ISoundManager void destroy(CSound& S) override; - void prefetch() override - { - if (!bPresent) - return; - i_create_all_sources(); - } - void stop_emitters() override; int pause_emitters(bool pauseState) override; @@ -128,7 +121,6 @@ class CSoundRender_Core : public ISoundManager bool i_create_source(CSound_source*& result, pcstr name, bool replaceWithNoSound = true); bool i_create_source(CSoundRender_Source*& result, pcstr name, bool replaceWithNoSound = true); CSoundRender_Source* i_create_source(pcstr name, bool replaceWithNoSound = true); - void i_create_all_sources(); void i_destroy_source(CSoundRender_Source* S); void i_start(CSoundRender_Emitter* E) const; diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index a8426a65905..fb19cc6be21 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -3,8 +3,6 @@ #include "SoundRender_Core.h" #include "SoundRender_Source.h" -#include "xrCore/Threading/ParallelForEach.hpp" - bool CSoundRender_Core::i_create_source(CSound_source*& result, pcstr name, bool replaceWithNoSound /*= true*/) { CSoundRender_Source* source = nullptr; @@ -62,50 +60,3 @@ void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) // No actual destroy at all S->detach(); } - -void CSoundRender_Core::i_create_all_sources() -{ - ZoneScoped; -#ifndef MASTER_GOLD - CTimer T; - T.Start(); - const size_t sizeBefore = s_sources.size(); -#endif - FS_FileSet flist; - FS.file_list(flist, "$game_sounds$", FS_ListFiles, "*.ogg"); - - const auto processFile = [&](const FS_File& file) - { - ZoneScopedN("Process file"); - string256 id; - xr_strcpy(id, file.name.c_str()); - - xr_strlwr(id); - if (strext(id)) - *strext(id) = 0; - - { - ScopeLock scope(&s_sources_lock); - const auto it = s_sources.find(id); - if (it != s_sources.end()) - return; - } - - CSoundRender_Source* S = xr_new(); - if (!S->load(id, false, false)) - { - xr_delete(S); - return; - } - - ScopeLock scope(&s_sources_lock); - s_sources.insert({ id, S }); - }; - - xr_parallel_for_each(flist, processFile); - -#ifndef MASTER_GOLD - Msg("Finished creating %d sound sources. Duration: %d ms", - s_sources.size() - sizeBefore, T.GetElapsed_ms()); -#endif -} diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 814ac28f234..53a68bb17d2 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -161,7 +161,7 @@ void CSoundRender_Source::detach() refs = 0; } -bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) +bool CSoundRender_Source::LoadWave(pcstr pName) { ZoneScoped; @@ -172,7 +172,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) const vorbis_info* ovi = ov_info(&ovf, -1); // verify - R_ASSERT3_CURE(ovi, "Invalid source info:", pName, !crashOnError, + R_ASSERT3_CURE(ovi, "Invalid source info:", pName, true, { detach(); return false; @@ -247,7 +247,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) #endif } - R_ASSERT3_CURE(m_info.maxAIDist >= 0.1f && m_info.maxDist >= 0.1f, "Invalid max distance.", pName, !crashOnError, + R_ASSERT3_CURE(m_info.maxAIDist >= 0.1f && m_info.maxDist >= 0.1f, "Invalid max distance.", pName, true, { detach(); return false; @@ -257,7 +257,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) return true; } -bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, bool crashOnError /*= true*/) +bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/) { string_path fn, N; xr_strcpy(N, name); @@ -284,7 +284,7 @@ bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/, b if (soundExist) { - if (!LoadWave(fn, crashOnError)) + if (!LoadWave(fn)) return false; } diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 786497a912c..701555c6b85 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -51,13 +51,13 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source void i_decompress(char* dest, u32 size); void i_decompress(float* dest, u32 size); - bool LoadWave(pcstr name, bool crashOnError); + bool LoadWave(pcstr name); public: CSoundRender_Source() = default; ~CSoundRender_Source() override; - bool load(pcstr name, bool replaceWithNoSound = true, bool crashOnError = true); + bool load(pcstr name, bool replaceWithNoSound = true); void unload(); void attach(); From fa7af012e08622961d1c8d3a5d2044757f3d2f56 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Wed, 29 May 2024 23:44:03 +0500 Subject: [PATCH 447/497] Simplify sound loading --- src/xrGame/level_sounds.cpp | 22 ++++++++------- src/xrGame/ui/MMSound.cpp | 26 ++++++++---------- src/xrGame/ui/UIGameTutorialVideoItem.cpp | 25 +++++------------ src/xrSound/Sound.h | 6 ++--- src/xrSound/SoundRender_Core.cpp | 15 +++++------ src/xrSound/SoundRender_Core.h | 6 ++--- .../SoundRender_Core_SourceManager.cpp | 27 ++++--------------- src/xrSound/SoundRender_Source.cpp | 22 ++++++++------- src/xrSound/SoundRender_Source.h | 2 +- 9 files changed, 58 insertions(+), 93 deletions(-) diff --git a/src/xrGame/level_sounds.cpp b/src/xrGame/level_sounds.cpp index bfc7a3d505f..2aed04981b0 100644 --- a/src/xrGame/level_sounds.cpp +++ b/src/xrGame/level_sounds.cpp @@ -87,13 +87,14 @@ void SMusicTrack::Load(LPCSTR fn, LPCSTR params) m_DbgName = fn; #endif // create source - string_path _l, _r; - strconcat(sizeof(_l), _l, fn, "_l"); - strconcat(sizeof(_r), _r, fn, "_r"); - const bool left = m_SourceLeft.create(_l, st_Music, sg_Undefined, false); - const bool right = m_SourceRight.create(_r, st_Music, sg_Undefined, false); - - m_SourceStereo.create(fn, st_Music, sg_Undefined, !left && !right); + if (!m_SourceStereo.create(fn, st_Music, sg_Undefined)) + { + string_path left, right; + strconcat(left, fn, "_l"); + strconcat(right, fn, "_r"); + m_SourceLeft.create(left, st_Music, sg_Undefined); + m_SourceRight.create(right, st_Music, sg_Undefined); + } // parse params [[maybe_unused]] auto cnt = _GetItemCount(params); @@ -148,9 +149,10 @@ bool SMusicTrack::IsPlaying() const void SMusicTrack::SetVolume(float volume) { - m_SourceStereo.set_volume(volume * m_Volume); - m_SourceLeft.set_volume(volume * m_Volume); - m_SourceRight.set_volume(volume * m_Volume); + const bool finalVolume = volume * m_Volume; + m_SourceStereo.set_volume(finalVolume); + m_SourceLeft.set_volume(finalVolume); + m_SourceRight.set_volume(finalVolume); } void SMusicTrack::Stop() { diff --git a/src/xrGame/ui/MMSound.cpp b/src/xrGame/ui/MMSound.cpp index e3e58d5a5b9..92181cb791a 100644 --- a/src/xrGame/ui/MMSound.cpp +++ b/src/xrGame/ui/MMSound.cpp @@ -60,29 +60,25 @@ void CMMSound::music_Play() const int i = Random.randI(m_play_list.size()); - string_path _stereo, _l, _r; - strconcat(sizeof(_stereo), _stereo, m_play_list[i].c_str(), ".ogg"); - strconcat(sizeof(_l), _l, m_play_list[i].c_str(), "_l.ogg"); - strconcat(sizeof(_r), _r, m_play_list[i].c_str(), "_r.ogg"); + string_path stereo; + strconcat(stereo, m_play_list[i].c_str(), ".ogg"); - bool found[channels_count + 1]; - ref_sound separated[channels_count]; - found[0] = separated[0].create(_l, st_Effect, sg_Undefined, false); - found[1] = separated[1].create(_r, st_Effect, sg_Undefined, false); - - ref_sound one; - found[channels_count] = one.create(_stereo, st_Music, sg_SourceType, !(found[0] && found[1])); + if (!m_music[0].create(stereo, st_Music, sg_SourceType)) + { + string_path left, right; + strconcat(left, m_play_list[i].c_str(), "_l.ogg"); + strconcat(right, m_play_list[i].c_str(), "_r.ogg"); + m_music[0].create(left, st_Effect, sg_Undefined); + m_music[1].create(right, st_Effect, sg_Undefined); + } - if (!found[channels_count] && found[0] && found[1]) + if (m_music[0] && m_music[1]) { - m_music[0] = separated[0]; - m_music[1] = separated[1]; m_music[0].play_at_pos(nullptr, Fvector().set(-0.5f, 0.f, 0.3f), sm_2D); m_music[1].play_at_pos(nullptr, Fvector().set(+0.5f, 0.f, 0.3f), sm_2D); } else { - m_music[0] = one; m_music[0].play(nullptr, sm_2D); m_music[1].destroy(); } diff --git a/src/xrGame/ui/UIGameTutorialVideoItem.cpp b/src/xrGame/ui/UIGameTutorialVideoItem.cpp index e076ca6a02b..20b72aa518a 100644 --- a/src/xrGame/ui/UIGameTutorialVideoItem.cpp +++ b/src/xrGame/ui/UIGameTutorialVideoItem.cpp @@ -94,26 +94,13 @@ void CUISequenceVideoItem::Load(CUIXml* xml, int idx) if (snd_name && snd_name[0]) { - string_path _l, _r; - strconcat(sizeof(_l), _l, snd_name, "_l"); - strconcat(sizeof(_r), _r, snd_name, "_r"); - - bool found[channels_count + 1]; - ref_sound separated[channels_count]; - found[0] = separated[0].create(_l, st_Effect, sg_Undefined, false); - found[1] = separated[1].create(_r, st_Effect, sg_Undefined, false); - - ref_sound one; - found[channels_count] = one.create(snd_name, st_Effect, sg_Undefined, !(found[0] && found[1])); - - if (!found[channels_count] && found[0] && found[1]) - { - m_sound[0] = separated[0]; - m_sound[1] = separated[1]; - } - else + if (!m_sound[0].create(snd_name, st_Effect, sg_Undefined)) { - m_sound[0] = one; + string_path left, right; + strconcat(left, snd_name, "_l"); + strconcat(right, snd_name, "_r"); + m_sound[0].create(left, st_Effect, sg_Undefined); + m_sound[1].create(right, st_Effect, sg_Undefined); } VERIFY(m_sound[0]._handle() || !Engine.Sound.IsSoundEnabled()); diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index 71089dd8f31..f2a8d53abe9 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -207,7 +207,7 @@ class XRSOUND_API XR_NOVTABLE ISoundManager friend struct CSound; friend struct resptrcode_sound; - virtual CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; + virtual CSound* create(pcstr fName, esound_type sound_type, int game_type) = 0; virtual void destroy(CSound& S) = 0; virtual void attach_tail(CSound& S, pcstr fName) = 0; @@ -317,10 +317,10 @@ struct resptrcode_sound : public resptr_base [[nodiscard]] ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; } - ICF bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) + ICF bool create(pcstr name, esound_type sound_type, int game_type) { VerSndUnlocked(); - _set(GEnv.Sound->create(name, sound_type, game_type, replaceWithNoSound)); + _set(GEnv.Sound->create(name, sound_type, game_type)); return _get(); } diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 018684357b6..2b5ddb917dd 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -98,21 +98,18 @@ void CSoundRender_Core::_restart() env_apply(); } -CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) +CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_type) { if (!bPresent) return nullptr; - CSound_source* handle{}; - string_path fn; xr_strcpy(fn, fName); if (strext(fn)) *strext(fn) = 0; - const bool found = i_create_source(handle, fn, replaceWithNoSound); - const bool handleAvailable = found || replaceWithNoSound; - if (!handleAvailable) + CSoundRender_Source* handle = i_create_source(fn); + if (!handle) return nullptr; auto* snd = xr_new(); @@ -120,13 +117,13 @@ CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_ snd->handle = handle; snd->g_type = game_type; - if (game_type == sg_SourceType && handleAvailable) + if (game_type == sg_SourceType) snd->g_type = snd->handle->game_type(); snd->s_type = sound_type; - snd->dwBytesTotal = handleAvailable ? snd->handle->bytes_total() : 0; - snd->fTimeTotal = handleAvailable ? snd->handle->length_sec() : 0.f; + snd->dwBytesTotal = snd->handle->bytes_total(); + snd->fTimeTotal = snd->handle->length_sec(); return snd; } diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index 3fe18ebbd16..149d864ee43 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -95,7 +95,7 @@ class CSoundRender_Core : public ISoundManager void _restart() override; // Sound interface - CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; + CSound* create(pcstr fName, esound_type sound_type, int game_type) override; void attach_tail(CSound& S, pcstr fName) override; void destroy(CSound& S) override; @@ -118,9 +118,7 @@ class CSoundRender_Core : public ISoundManager void refresh_sources() override; public: - bool i_create_source(CSound_source*& result, pcstr name, bool replaceWithNoSound = true); - bool i_create_source(CSoundRender_Source*& result, pcstr name, bool replaceWithNoSound = true); - CSoundRender_Source* i_create_source(pcstr name, bool replaceWithNoSound = true); + CSoundRender_Source* i_create_source(pcstr name); void i_destroy_source(CSoundRender_Source* S); void i_start(CSoundRender_Emitter* E) const; diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index fb19cc6be21..010fcd91919 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -3,15 +3,7 @@ #include "SoundRender_Core.h" #include "SoundRender_Source.h" -bool CSoundRender_Core::i_create_source(CSound_source*& result, pcstr name, bool replaceWithNoSound /*= true*/) -{ - CSoundRender_Source* source = nullptr; - const bool found = i_create_source(source, name, replaceWithNoSound); - result = source; - return found; -} - -bool CSoundRender_Core::i_create_source(CSoundRender_Source*& result, pcstr name, bool replaceWithNoSound /*= true*/) +CSoundRender_Source* CSoundRender_Core::i_create_source(pcstr name) { // Search string256 id; @@ -25,17 +17,16 @@ bool CSoundRender_Core::i_create_source(CSoundRender_Source*& result, pcstr name const auto it = s_sources.find(id); if (it != s_sources.end()) { - result = it->second; - return true; + return it->second; } } // Load a _new one CSoundRender_Source* S = xr_new(); - const bool itIsFound = S->load(id, replaceWithNoSound); - if (!itIsFound && !replaceWithNoSound) + if (!S->load(id)) { + // XXX: Make CSoundRender_Source movable and make allocation only if S->load succeeded. xr_delete(S); } else @@ -44,15 +35,7 @@ bool CSoundRender_Core::i_create_source(CSoundRender_Source*& result, pcstr name s_sources.insert({ id, S }); } - result = S; - return itIsFound; -} - -CSoundRender_Source* CSoundRender_Core::i_create_source(pcstr name, bool replaceWithNoSound /*= true*/) -{ - CSoundRender_Source* result = nullptr; - i_create_source(result, name, replaceWithNoSound); - return result; + return S; } void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 53a68bb17d2..690fa449c7a 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -257,7 +257,7 @@ bool CSoundRender_Source::LoadWave(pcstr pName) return true; } -bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/) +bool CSoundRender_Source::load(pcstr name) { string_path fn, N; xr_strcpy(N, name); @@ -270,25 +270,27 @@ bool CSoundRender_Source::load(pcstr name, bool replaceWithNoSound /*= true*/) fname = N; - strconcat(sizeof(fn), fn, N, ".ogg"); + strconcat(fn, N, ".ogg"); if (!FS.exist("$level$", fn)) FS.update_path(fn, "$game_sounds$", fn); - bool soundExist = FS.exist(fn); - if (!soundExist && replaceWithNoSound) +#ifndef MASTER_GOLD + if (!FS.exist(fn)) { - Msg("! Can't find sound '%s'", name); + Msg("~ %s: Can't find sound '%s'", __FUNCTION__, name); +# ifdef _EDITOR FS.update_path(fn, "$game_sounds$", "$no_sound.ogg"); - soundExist = FS.exist(fn); +# endif } +#endif - if (soundExist) + if (FS.exist(fn)) { - if (!LoadWave(fn)) - return false; + if (LoadWave(fn)) + return true; } - return soundExist; + return false; } void CSoundRender_Source::unload() diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 701555c6b85..1c85940aad8 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -57,7 +57,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source CSoundRender_Source() = default; ~CSoundRender_Source() override; - bool load(pcstr name, bool replaceWithNoSound = true); + bool load(pcstr name); void unload(); void attach(); From 4f3035f098caeda78df62860982b6cacc951be9c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 May 2024 00:07:56 +0500 Subject: [PATCH 448/497] xrSound: allow to create CSound instance only with handle supplied --- src/xrSound/Sound.h | 6 +++--- src/xrSound/SoundRender_Core.cpp | 4 +--- src/xrSound/SoundRender_Scene.cpp | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index f2a8d53abe9..42d3d32a40c 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -270,7 +270,7 @@ class CSound_UserData : public xr_resource using CSound_UserDataPtr = resptr_core>; -struct CSound : public xr_resource +struct CSound final : public xr_resource { public: //shared_str nm; @@ -287,6 +287,7 @@ struct CSound : public xr_resource u32 dwBytesTotal{}; float fTimeTotal{}; + CSound(CSound_source* src) : handle(src) { VERIFY(src); } ~CSound() override { GEnv.Sound->destroy(*this); } }; @@ -341,8 +342,7 @@ struct resptrcode_sound : public resptr_base { if (!from._get()) return; - _set(xr_new()); - p_->handle = from->handle; + _set(xr_new(from->handle)); p_->dwBytesTotal = from->dwBytesTotal; p_->fTimeTotal = from->fTimeTotal; p_->fn_attached[0] = from->fn_attached[0]; diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 2b5ddb917dd..15b14343c23 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -112,9 +112,7 @@ CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_ if (!handle) return nullptr; - auto* snd = xr_new(); - - snd->handle = handle; + auto* snd = xr_new(handle); snd->g_type = game_type; if (game_type == sg_SourceType) diff --git a/src/xrSound/SoundRender_Scene.cpp b/src/xrSound/SoundRender_Scene.cpp index 8cdb6c3d107..b3c470b02a1 100644 --- a/src/xrSound/SoundRender_Scene.cpp +++ b/src/xrSound/SoundRender_Scene.cpp @@ -176,8 +176,7 @@ void CSoundRender_Scene::play_no_feedback( if (!SoundRender->bPresent || !S._handle()) return; const ref_sound orig = S; - S._set(xr_new()); - S->handle = orig->handle; + S._set(xr_new(orig->handle)); S->g_type = orig->g_type; S->g_object = O; S->dwBytesTotal = orig->dwBytesTotal; From edfac348dbd2a04ddfc625e5d637b89d6b32a313 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 May 2024 03:23:33 +0500 Subject: [PATCH 449/497] TaskScheduler: tasks can now work as std::future --- src/xrCore/Threading/Task.hpp | 49 +++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 5d4fecd8f1f..50ccdde91bd 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -45,14 +45,13 @@ class XRCORE_API Task final : Noncopyable // ordered from biggest to smallest struct Data { + CallFunc* call; Task* parent; - CallFunc* m_call; std::atomic_int16_t jobs; // at least 1 (task itself), zero means task is done. - bool contains_result; Data() = default; Data(CallFunc* call, Task* parent) - : parent(parent), m_call(call), jobs(1), contains_result(false) {} + : call(call), parent(parent), jobs(1) {} }; static constexpr size_t USER_DATA_SIZE = TASK_SIZE - sizeof(Data); @@ -60,7 +59,10 @@ class XRCORE_API Task final : Noncopyable std::byte m_user_data[USER_DATA_SIZE]; Data m_data; - template > + template , + typename HasResult = void + > struct Dispatcher { static constexpr bool task_unaware = std::is_invocable_v; @@ -71,7 +73,7 @@ class XRCORE_API Task final : Noncopyable }; template - struct Dispatcher + struct Dispatcher>>> { static void Call(Task& task) { @@ -83,7 +85,7 @@ class XRCORE_API Task final : Noncopyable }; template - struct Dispatcher + struct Dispatcher>>> { static void Call(Task& task) { @@ -94,6 +96,33 @@ class XRCORE_API Task final : Noncopyable } }; + template + struct Dispatcher>>> + { + static void Call(Task& task) + { + auto& obj = *reinterpret_cast(task.m_user_data); + auto result = std::move(obj(task)); + if constexpr (!std::is_trivially_copyable_v) + obj.~Invokable(); + ::new (task.m_user_data) decltype(result)(std::move(result)); + } + }; + + template + struct Dispatcher>>> + { + static void Call(Task& task) + { + auto& obj = *reinterpret_cast(task.m_user_data); + auto result = std::move(obj()); + if constexpr (!std::is_trivially_copyable_v) + obj.~Invokable(); + + ::new (task.m_user_data) decltype(result)(std::move(result)); + } + }; + private: Task() = default; // used by TaskAllocator as Task initial state @@ -139,7 +168,9 @@ class XRCORE_API Task final : Noncopyable [[nodiscard]] const T* GetData() const noexcept { - return static_cast(m_user_data); + if (!IsFinished()) + return nullptr; + return reinterpret_cast(m_user_data); } [[nodiscard]] @@ -158,7 +189,7 @@ class XRCORE_API Task final : Noncopyable // Called by TaskManager void operator()() { - m_data.m_call(*this); + m_data.call(*this); for (Task* it = this; ; it = it->m_data.parent) { @@ -169,3 +200,5 @@ class XRCORE_API Task final : Noncopyable } } }; + +static_assert(sizeof(Task) == TASK_SIZE); From 03eb614c24d2ac9d4a75b3ac04b3aa6790ac122e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 May 2024 11:36:28 +0500 Subject: [PATCH 450/497] Task Scheduler: make sure that function result fits in the task storage --- src/xrCore/Threading/Task.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 50ccdde91bd..2a8fda6d6e0 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -99,6 +99,9 @@ class XRCORE_API Task final : Noncopyable template struct Dispatcher>>> { + static_assert(sizeof(std::invoke_result_t) <= USER_DATA_SIZE, + "Not enough storage to save result of your function. Try to reduce its size."); + static void Call(Task& task) { auto& obj = *reinterpret_cast(task.m_user_data); @@ -112,13 +115,15 @@ class XRCORE_API Task final : Noncopyable template struct Dispatcher>>> { + static_assert(sizeof(std::invoke_result_t) <= USER_DATA_SIZE, + "Not enough storage to save result of your function. Try to reduce its size."); + static void Call(Task& task) { auto& obj = *reinterpret_cast(task.m_user_data); auto result = std::move(obj()); if constexpr (!std::is_trivially_copyable_v) obj.~Invokable(); - ::new (task.m_user_data) decltype(result)(std::move(result)); } }; From d10ccd65d72b9f4cdbb767efd71deb475faeb7cd Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 May 2024 13:03:26 +0500 Subject: [PATCH 451/497] Task scheduler: more robust task result detection --- src/xrCore/Threading/Task.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/xrCore/Threading/Task.hpp b/src/xrCore/Threading/Task.hpp index 2a8fda6d6e0..55e0d79757b 100644 --- a/src/xrCore/Threading/Task.hpp +++ b/src/xrCore/Threading/Task.hpp @@ -48,6 +48,7 @@ class XRCORE_API Task final : Noncopyable CallFunc* call; Task* parent; std::atomic_int16_t jobs; // at least 1 (task itself), zero means task is done. + std::atomic_bool has_result{}; Data() = default; Data(CallFunc* call, Task* parent) @@ -109,6 +110,7 @@ class XRCORE_API Task final : Noncopyable if constexpr (!std::is_trivially_copyable_v) obj.~Invokable(); ::new (task.m_user_data) decltype(result)(std::move(result)); + task.m_data.has_result.store(true, std::memory_order_release); } }; @@ -125,6 +127,7 @@ class XRCORE_API Task final : Noncopyable if constexpr (!std::is_trivially_copyable_v) obj.~Invokable(); ::new (task.m_user_data) decltype(result)(std::move(result)); + task.m_data.has_result.store(true, std::memory_order_release); } }; @@ -173,7 +176,7 @@ class XRCORE_API Task final : Noncopyable [[nodiscard]] const T* GetData() const noexcept { - if (!IsFinished()) + if (!m_data.has_result.load(std::memory_order_consume)) return nullptr; return reinterpret_cast(m_user_data); } From 06f512a6b8ead4233f5df7f829fb13307dd581ed Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Thu, 30 May 2024 23:25:13 +0500 Subject: [PATCH 452/497] xrSound: move sound file handles to CSoundRender_Emitter Each emitter now has it's own handle, no need to wait for mutexes. --- .../SoundRender_Core_SourceManager.cpp | 1 - src/xrSound/SoundRender_Emitter.cpp | 2 +- src/xrSound/SoundRender_Emitter.h | 4 + src/xrSound/SoundRender_Emitter_StartStop.cpp | 6 +- src/xrSound/SoundRender_Source.cpp | 74 +++++++++---------- src/xrSound/SoundRender_Source.h | 19 ++--- src/xrSound/SoundRender_Target.cpp | 2 - 7 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index 010fcd91919..e82d7bb8834 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -41,5 +41,4 @@ CSoundRender_Source* CSoundRender_Core::i_create_source(pcstr name) void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) { // No actual destroy at all - S->detach(); } diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index 7452608e8c6..e7b181ebd85 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -145,7 +145,7 @@ void CSoundRender_Emitter::move_cursor(int offset) void CSoundRender_Emitter::fill_data(void* dest, u32 offset, u32 size) const { - source()->decompress(dest, offset, size); + source()->decompress(dest, offset, size, ovf); } void CSoundRender_Emitter::fill_block(void* ptr, u32 size) diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index e9954071253..110ca32dcf8 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -6,6 +6,8 @@ #include "SoundRender_Environment.h" #include "SoundRender_Scene.h" +struct OggVorbis_File; + class Task; class CSoundRender_Emitter final : public CSound_emitter @@ -77,6 +79,8 @@ class CSoundRender_Emitter final : public CSound_emitter void move_cursor(int offset); private: + OggVorbis_File* ovf{}; + xr_vector temp_buf[sdef_target_count]; std::atomic prefill_task{}; diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index e066d6a23f2..fe1746599a2 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -40,6 +40,8 @@ void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay // Calc storage for (auto& buf : temp_buf) buf.resize(source()->data_info().bytesPerBuffer); + + ovf = source()->open(); } void CSoundRender_Emitter::i_stop() @@ -47,15 +49,17 @@ void CSoundRender_Emitter::i_stop() bRewind = FALSE; if (target) stop_target(); + + wait_prefill(); if (owner_data) { + source()->close(ovf); Event_ReleaseOwner(); VERIFY(this == owner_data->feedback); owner_data->feedback = NULL; owner_data = NULL; } m_current_state = stStopped; - wait_prefill(); } void CSoundRender_Emitter::stop(bool isDeffered) diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index 690fa449c7a..a02ebd024fa 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -3,6 +3,8 @@ #include "SoundRender_Core.h" #include "SoundRender_Source.h" +#include + CSoundRender_Source::~CSoundRender_Source() { unload(); } namespace @@ -40,48 +42,44 @@ bool ov_can_continue_read(long res) } } -void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) +void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const { - if (!wave) - attach(); - ZoneScoped; - std::lock_guard guard{ read_lock }; // seek const auto sample_offset = ogg_int64_t(byte_offset / m_data_info.blockAlign); - const u32 cur_pos = u32(ov_pcm_tell(&ovf)); + const u32 cur_pos = u32(ov_pcm_tell(ovf)); if (cur_pos != sample_offset) - ov_pcm_seek(&ovf, sample_offset); + ov_pcm_seek(ovf, sample_offset); // decompress if (m_data_info.format == SoundFormat::Float32) - i_decompress(static_cast(dest), size); + i_decompress(ovf, static_cast(dest), size); else - i_decompress(static_cast(dest), size); + i_decompress(ovf, static_cast(dest), size); } -void CSoundRender_Source::i_decompress(char* _dest, u32 size) +void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, char* _dest, u32 size) const { long TotalRet = 0; // Read loop while (TotalRet < static_cast(size)) { - const auto ret = ov_read(&ovf, _dest + TotalRet, size - TotalRet, 0, 2, 1, nullptr); + const auto ret = ov_read(ovf, _dest + TotalRet, size - TotalRet, 0, 2, 1, nullptr); if (ret <= 0 && !ov_can_continue_read(ret)) break; TotalRet += ret; } } -void CSoundRender_Source::i_decompress(float* _dest, u32 size) +void CSoundRender_Source::i_decompress(OggVorbis_File* ovf, float* _dest, u32 size) const { s32 left = s32(size / m_data_info.blockAlign); while (left) { float** pcm; - long samples = ov_read_float(&ovf, &pcm, left, nullptr); + long samples = ov_read_float(ovf, &pcm, left, nullptr); if (samples <= 0 && !ov_can_continue_read(samples)) break; @@ -123,8 +121,10 @@ constexpr ov_callbacks g_ov_callbacks = return 0; }, // close - [](void* /*datasource*/) -> int + [](void* datasource) -> int { + auto* file = static_cast(datasource); + FS.r_close(file); return 0; }, // tell @@ -135,30 +135,21 @@ constexpr ov_callbacks g_ov_callbacks = }, }; -void CSoundRender_Source::attach() +OggVorbis_File* CSoundRender_Source::open() const { - std::lock_guard guard{ read_lock }; - ++refs; - VERIFY(refs > 0); - if (refs == 1) - { - wave = FS.r_open(pname.c_str()); - R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); - ov_open_callbacks(wave, &ovf, nullptr, 0, g_ov_callbacks); - } + const auto file = FS.r_open(pname.c_str()); + R_ASSERT3(file && file->length(), "Can't open wave file:", pname.c_str()); + + const auto ovf = xr_new(); + ov_open_callbacks(file, ovf, nullptr, 0, g_ov_callbacks); + + return ovf; } -void CSoundRender_Source::detach() +void CSoundRender_Source::close(OggVorbis_File*& ovf) const { - std::lock_guard guard{ read_lock }; - --refs; - if (refs == 0) - { - ov_clear(&ovf); - FS.r_close(wave); - } - if (refs < 0) - refs = 0; + ov_clear(ovf); + xr_delete(ovf); } bool CSoundRender_Source::LoadWave(pcstr pName) @@ -167,14 +158,20 @@ bool CSoundRender_Source::LoadWave(pcstr pName) pname = pName; - attach(); + // Load file into memory and parse WAV-format + OggVorbis_File ovf; + { + IReader* wave = FS.r_open(pname.c_str()); + R_ASSERT3(wave && wave->length(), "Can't open wave file:", pname.c_str()); + ov_open_callbacks(wave, &ovf, nullptr, 0, g_ov_callbacks); + } const vorbis_info* ovi = ov_info(&ovf, -1); // verify R_ASSERT3_CURE(ovi, "Invalid source info:", pName, true, { - detach(); + ov_clear(&ovf); return false; }); @@ -249,11 +246,11 @@ bool CSoundRender_Source::LoadWave(pcstr pName) R_ASSERT3_CURE(m_info.maxAIDist >= 0.1f && m_info.maxDist >= 0.1f, "Invalid max distance.", pName, true, { - detach(); + ov_clear(&ovf); return false; }); - detach(); + ov_clear(&ovf); return true; } @@ -297,5 +294,4 @@ void CSoundRender_Source::unload() { fTimeTotal = 0.0f; dwBytesTotal = 0; - detach(); } diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 1c85940aad8..484c3ce014f 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -1,8 +1,6 @@ #pragma once -#include - -#include +struct OggVorbis_File; enum class SoundFormat { @@ -33,11 +31,6 @@ struct SoundSourceInfo class XRSOUND_API CSoundRender_Source final : public CSound_source { - OggVorbis_File ovf{}; - IReader* wave{}; - int refs{}; - std::mutex read_lock; - shared_str pname; shared_str fname; @@ -48,8 +41,8 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source SoundSourceInfo m_info{}; private: - void i_decompress(char* dest, u32 size); - void i_decompress(float* dest, u32 size); + void i_decompress(OggVorbis_File* ovf, char* dest, u32 size) const; + void i_decompress(OggVorbis_File* ovf, float* dest, u32 size) const; bool LoadWave(pcstr name); @@ -60,10 +53,10 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source bool load(pcstr name); void unload(); - void attach(); - void detach(); + OggVorbis_File* open() const; + void close(OggVorbis_File*& ovf) const; - void decompress(void* dest, u32 byte_offset, u32 size); + void decompress(void* dest, u32 byte_offset, u32 size, OggVorbis_File* ovf) const; [[nodiscard]] const auto& data_info() const { return m_data_info; } [[nodiscard]] const auto& info() const { return m_info; } diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 5b000c906ba..cca7828247f 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -15,7 +15,6 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) m_pEmitter = E; priority = E->priority(); rendering = false; - //m_pEmitter->source()->attach(); } void CSoundRender_Target::render() @@ -26,7 +25,6 @@ void CSoundRender_Target::render() void CSoundRender_Target::stop() { - m_pEmitter->source()->detach(); m_pEmitter = nullptr; rendering = false; priority = -1; From 5c95c1071529550e4e0be87c1147e0a8d0d3f6a9 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Fri, 31 May 2024 14:27:30 +0500 Subject: [PATCH 453/497] xrSound: split count of buffers for submission and prefilling --- src/xrSound/SoundRender.h | 6 +++--- src/xrSound/SoundRender_Emitter.cpp | 14 +++++++------- src/xrSound/SoundRender_Emitter.h | 2 +- src/xrSound/SoundRender_TargetA.cpp | 8 ++++---- src/xrSound/SoundRender_TargetA.h | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/xrSound/SoundRender.h b/src/xrSound/SoundRender.h index 9c8f86aec43..7a2b22a178b 100644 --- a/src/xrSound/SoundRender.h +++ b/src/xrSound/SoundRender.h @@ -10,9 +10,9 @@ class CSoundRender_Target; class CSoundRender_Environment; class SoundEnvironment_LIB; -const u32 sdef_target_count = 5; // -const u32 sdef_target_block = 400; // ms -const u32 sdef_target_size = sdef_target_count * sdef_target_block; // ms +const u32 sdef_target_count_submit = 4; // amount of buffers should be submitted to API +const u32 sdef_target_count_prefill = 10; // +const u32 sdef_target_block = 100; // ms const u32 sdef_env_version = 4; // current version of env-def const u32 sdef_level_version = 1; // current version of level-def const float s_f_def_event_pulse = 0.5f; // sec diff --git a/src/xrSound/SoundRender_Emitter.cpp b/src/xrSound/SoundRender_Emitter.cpp index e7b181ebd85..fba33c11b81 100644 --- a/src/xrSound/SoundRender_Emitter.cpp +++ b/src/xrSound/SoundRender_Emitter.cpp @@ -234,7 +234,7 @@ std::pair CSoundRender_Emitter::obtain_block() wait_prefill(); const std::pair result = { temp_buf[current_block].data(), temp_buf[current_block].size() }; ++current_block; - if (current_block >= sdef_target_count) + if (current_block >= sdef_target_count_prefill) current_block = 0; --filled_blocks; return std::move(result); @@ -243,28 +243,28 @@ std::pair CSoundRender_Emitter::obtain_block() void CSoundRender_Emitter::fill_all_blocks() { current_block = 0; - for (size_t i = 0; i < sdef_target_count; ++i) + for (size_t i = 0; i < sdef_target_count_prefill; ++i) fill_block(temp_buf[i].data(), temp_buf[i].size()); - filled_blocks = sdef_target_count; + filled_blocks = sdef_target_count_prefill; } void CSoundRender_Emitter::dispatch_prefill() { wait_prefill(); - if (filled_blocks >= sdef_target_count) + if (filled_blocks >= sdef_target_count_prefill) return; const auto task = &TaskScheduler->AddTask([this] { - size_t next_block_to_fill = (current_block + filled_blocks) % sdef_target_count; + size_t next_block_to_fill = (current_block + filled_blocks) % sdef_target_count_prefill; - while (filled_blocks < sdef_target_count) + while (filled_blocks < sdef_target_count_prefill) { auto& block = temp_buf[next_block_to_fill]; fill_block(block.data(), block.size()); - next_block_to_fill = (next_block_to_fill + 1) % sdef_target_count; + next_block_to_fill = (next_block_to_fill + 1) % sdef_target_count_prefill; filled_blocks++; } diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 110ca32dcf8..dde498c0bf3 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -81,7 +81,7 @@ class CSoundRender_Emitter final : public CSound_emitter private: OggVorbis_File* ovf{}; - xr_vector temp_buf[sdef_target_count]; + xr_vector temp_buf[sdef_target_count_prefill]; std::atomic prefill_task{}; size_t current_block{}; diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 54ee98d9ed6..3b6ffd85693 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -10,7 +10,7 @@ CSoundRender_TargetA::CSoundRender_TargetA() bool CSoundRender_TargetA::_initialize() { - A_CHK(alGenBuffers(sdef_target_count, pBuffers)); + A_CHK(alGenBuffers(sdef_target_count_submit, pBuffers)); alGenSources(1, &pSource); const ALenum error = alGetError(); if (AL_NO_ERROR == error) @@ -31,7 +31,7 @@ void CSoundRender_TargetA::_destroy() // clean up target if (alIsSource(pSource)) alDeleteSources(1, &pSource); - A_CHK(alDeleteBuffers(sdef_target_count, pBuffers)); + A_CHK(alDeleteBuffers(sdef_target_count_submit, pBuffers)); } void CSoundRender_TargetA::_restart() @@ -61,7 +61,7 @@ void CSoundRender_TargetA::render() submit_all_buffers(); - A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); + A_CHK(alSourceQueueBuffers(pSource, sdef_target_count_submit, pBuffers)); A_CHK(alSourcePlay(pSource)); } @@ -85,7 +85,7 @@ void CSoundRender_TargetA::rewind() submit_all_buffers(); - A_CHK(alSourceQueueBuffers(pSource, sdef_target_count, pBuffers)); + A_CHK(alSourceQueueBuffers(pSource, sdef_target_count_submit, pBuffers)); A_CHK(alSourcePlay(pSource)); } diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 78910ff3eee..43be7fe61c7 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -9,7 +9,7 @@ class CSoundRender_TargetA : public CSoundRender_Target // OpenAL ALuint pSource{}; - ALuint pBuffers[sdef_target_count]{}; + ALuint pBuffers[sdef_target_count_submit]{}; ALuint dataFormat; ALsizei sampleRate; From 3195c332d7c92d600add02ff624930b41ce90e8d Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 31 May 2024 15:19:40 +0500 Subject: [PATCH 454/497] GitHub Actions: set 30 minutes timeout for Windows builds [skip ci] --- .github/workflows/cibuild.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index f4175021b3c..f21322d09d1 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -11,6 +11,7 @@ jobs: windows: name: Windows ${{ matrix.Configuration }} ${{ matrix.Platform }} (msvc) runs-on: windows-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: From 8623f5f8b469c3e4c496f5e6a19d7bb28ba7d084 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Sat, 1 Jun 2024 20:13:47 +0500 Subject: [PATCH 455/497] Replace GLEW with GLAD (#1684) --- .github/workflows/cibuild.yml | 13 +- CMakeLists.txt | 2 - Externals/gl/include/gl/glext.h | 11829 ------- Externals/gl/include/gl/wglext.h | 840 - misc/docker/image/install_deps.sh | 1 - sdk/include/GL/eglew.h | 3051 -- sdk/include/GL/glew.h | 26427 ---------------- sdk/include/GL/glxew.h | 1831 -- sdk/include/GL/wglew.h | 1468 - sdk/include/KHR/khrplatform.h | 311 + sdk/include/glad/gl.c | 13288 ++++++++ sdk/include/glad/gl.h | 17821 +++++++++++ sdk/libraries/x64/glew32s.lib | Bin 2845622 -> 0 bytes sdk/libraries/x86/glew32s.lib | Bin 2693038 -> 0 bytes src/Layers/xrRender/Blender_Recorder.cpp | 2 +- src/Layers/xrRender/Blender_Recorder_R2.cpp | 2 +- src/Layers/xrRender/R_Backend.h | 4 +- src/Layers/xrRender/SH_Atomic.cpp | 14 +- src/Layers/xrRender/ShaderResourceTraits.h | 10 +- src/Layers/xrRenderGL/Blender_Recorder_GL.cpp | 2 +- src/Layers/xrRenderGL/glBufferUtils.cpp | 2 +- src/Layers/xrRenderGL/glHW.cpp | 23 +- src/Layers/xrRenderGL/glHW.h | 3 - src/Layers/xrRenderGL/glHWCaps.cpp | 4 +- src/Layers/xrRenderGL/glR_Backend_Runtime.h | 6 +- .../glResourceManager_Resources.cpp | 2 +- src/Layers/xrRenderGL/glState.cpp | 4 +- src/Layers/xrRenderGL/glr_constants.cpp | 2 +- src/Layers/xrRenderGL/glr_constants_cache.h | 22 +- src/Layers/xrRenderPC_GL/CMakeLists.txt | 8 +- src/Layers/xrRenderPC_GL/r2_test_hw.cpp | 12 +- src/Layers/xrRenderPC_GL/rgl_shaders.cpp | 6 +- src/Layers/xrRenderPC_GL/stdafx.h | 3 +- src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj | 9 +- .../xrRenderPC_GL/xrRender_GL.vcxproj.filters | 15 + 35 files changed, 31504 insertions(+), 45533 deletions(-) delete mode 100644 Externals/gl/include/gl/glext.h delete mode 100644 Externals/gl/include/gl/wglext.h delete mode 100644 sdk/include/GL/eglew.h delete mode 100644 sdk/include/GL/glew.h delete mode 100644 sdk/include/GL/glxew.h delete mode 100644 sdk/include/GL/wglew.h create mode 100644 sdk/include/KHR/khrplatform.h create mode 100644 sdk/include/glad/gl.c create mode 100644 sdk/include/glad/gl.h delete mode 100644 sdk/libraries/x64/glew32s.lib delete mode 100644 sdk/libraries/x86/glew32s.lib diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index f21322d09d1..1c0ff89ee62 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -109,7 +109,7 @@ jobs: with: arch: ${{ matrix.platform.arch }} branch: 'latest-stable' - packages: build-base cmake git mold sdl2-dev glew-dev lzo-dev libjpeg-turbo-dev openal-soft-dev libogg-dev libtheora-dev libvorbis-dev + packages: build-base cmake git mold sdl2-dev lzo-dev libjpeg-turbo-dev openal-soft-dev libogg-dev libtheora-dev libvorbis-dev - name: Install Ubuntu packages if: ${{ matrix.platform.name == 'Ubuntu' }} @@ -118,7 +118,6 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq -y \ libsdl2-dev:${{ matrix.platform.arch }} \ - libglew-dev:${{ matrix.platform.arch }} \ liblzo2-dev:${{ matrix.platform.arch }} \ libjpeg-dev:${{ matrix.platform.arch }} \ libopenal-dev:${{ matrix.platform.arch }} \ @@ -130,11 +129,11 @@ jobs: if: ${{ matrix.platform.name == 'macOS' }} run: | brew update - brew install sdl2 glew lzo libogg libvorbis theora + brew install sdl2 lzo libogg libvorbis theora - name: Install Fedora packages if: ${{ matrix.platform.name == 'Fedora' }} - run: dnf install -y git gcc gcc-c++ rpmdevtools cmake SDL2-devel glew-devel lzo-devel libjpeg-turbo-devel openal-devel libogg-devel libtheora-devel libvorbis-devel + run: dnf install -y git gcc gcc-c++ rpmdevtools cmake SDL2-devel lzo-devel libjpeg-turbo-devel openal-devel libogg-devel libtheora-devel libvorbis-devel - name: Set environment variables if: ${{ matrix.platform.cc != '' && matrix.platform.cxx != '' }} @@ -181,13 +180,13 @@ jobs: matrix: platform: - { name: FreeBSD, os: freebsd, os-version: '14.0', arch: x86_64, - install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 glew lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" + install-cmd: "sudo pkg update && sudo pkg install -y cmake sdl2 lzo2 jpeg-turbo openal-soft libogg libtheora libvorbis" } - { name: OpenBSD, os: openbsd, os-version: '7.5', arch: x86_64, - install-cmd: "sudo pkg_add cmake SDL2 glew lzo2 jpeg openal libogg libtheora libvorbis", + install-cmd: "sudo pkg_add cmake SDL2 lzo2 jpeg openal libogg libtheora libvorbis", } - { name: NetBSD, os: netbsd, os-version: '10.0', arch: x86_64, - install-cmd: "sudo pkgin -y install cmake SDL2 glew lzo libjpeg-turbo openal-soft libogg libtheora libvorbis", + install-cmd: "sudo pkgin -y install cmake SDL2 lzo libjpeg-turbo openal-soft libogg libtheora libvorbis", } configuration: [Debug, Release] diff --git a/CMakeLists.txt b/CMakeLists.txt index c10fdce44e9..1888a72f324 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,8 +241,6 @@ if (NOT WIN32) INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}" ) endif() - find_package(OpenGL REQUIRED) - find_package(GLEW REQUIRED) find_package(OpenAL REQUIRED) find_package(JPEG) find_package(Ogg REQUIRED) diff --git a/Externals/gl/include/gl/glext.h b/Externals/gl/include/gl/glext.h deleted file mode 100644 index 0452fc4598d..00000000000 --- a/Externals/gl/include/gl/glext.h +++ /dev/null @@ -1,11829 +0,0 @@ -#ifndef __glext_h_ -#define __glext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2014 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 30346 $ on $Date: 2015-03-25 23:28:00 -0700 (Wed, 25 Mar 2015) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -#define GL_GLEXT_VERSION 20150325 - -/* Generated C header for: - * API: gl - * Profile: compatibility - * Versions considered: .* - * Versions emitted: 1\.[2-9]|[234]\.[0-9] - * Default extensions included: gl - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_RESCALE_NORMAL 0x803A -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif -#endif /* GL_VERSION_1_2 */ - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTexture (GLenum texture); -GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); -GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); -GLAPI void APIENTRY glClientActiveTexture (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); -#endif -#endif /* GL_VERSION_1_3 */ - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); -GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); -GLAPI void APIENTRY glFogCoordf (GLfloat coord); -GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); -GLAPI void APIENTRY glFogCoordd (GLdouble coord); -GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2iv (const GLint *v); -GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); -GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3iv (const GLint *v); -GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); -GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void APIENTRY glBlendEquation (GLenum mode); -#endif -#endif /* GL_VERSION_1_4 */ - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -#include -typedef ptrdiff_t GLsizeiptr; -typedef ptrdiff_t GLintptr; -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SRC1_ALPHA 0x8589 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_COORD 0x8451 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_RGB 0x8582 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC2_ALPHA 0x858A -typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); -typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQuery (GLuint id); -GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQuery (GLenum target); -GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); -GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); -GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); -GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_VERSION_1_5 */ - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -typedef char GLchar; -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_TEXTURE_COORDS 0x8871 -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); -GLAPI void APIENTRY glCompileShader (GLuint shader); -GLAPI GLuint APIENTRY glCreateProgram (void); -GLAPI GLuint APIENTRY glCreateShader (GLenum type); -GLAPI void APIENTRY glDeleteProgram (GLuint program); -GLAPI void APIENTRY glDeleteShader (GLuint shader); -GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); -GLAPI GLboolean APIENTRY glIsProgram (GLuint program); -GLAPI GLboolean APIENTRY glIsShader (GLuint shader); -GLAPI void APIENTRY glLinkProgram (GLuint program); -GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -GLAPI void APIENTRY glUseProgram (GLuint program); -GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glValidateProgram (GLuint program); -GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -#endif -#endif /* GL_VERSION_2_0 */ - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif -#endif /* GL_VERSION_2_1 */ - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -typedef unsigned short GLhalf; -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_ALPHA_INTEGER 0x8D97 -typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); -GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); -GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedback (void); -GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); -GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRender (void); -GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); -GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); -GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmap (GLenum target); -GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glBindVertexArray (GLuint array); -GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); -#endif -#endif /* GL_VERSION_3_0 */ - -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFFu -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); -GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); -GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#endif -#endif /* GL_VERSION_3_1 */ - -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -typedef struct __GLsync *GLsync; -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif -typedef uint64_t GLuint64; -typedef int64_t GLint64; -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_DEPTH_CLAMP 0x864F -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); -typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); -typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -GLAPI void APIENTRY glProvokingVertex (GLenum mode); -GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); -GLAPI GLboolean APIENTRY glIsSync (GLsync sync); -GLAPI void APIENTRY glDeleteSync (GLsync sync); -GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); -GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); -GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); -#endif -#endif /* GL_VERSION_3_2 */ - -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_SRC1_COLOR 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 -#define GL_INT_2_10_10_10_REV 0x8D9F -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); -GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); -GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); -GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); -GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); -GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); -GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); -GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); -GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); -GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); -GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); -GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); -#endif -#endif /* GL_VERSION_3_3 */ - -#ifndef GL_VERSION_4_0 -#define GL_VERSION_4_0 1 -#define GL_SAMPLE_SHADING 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D -#define GL_MAX_VERTEX_STREAMS 0x8E71 -#define GL_DOUBLE_VEC2 0x8FFC -#define GL_DOUBLE_VEC3 0x8FFD -#define GL_DOUBLE_VEC4 0x8FFE -#define GL_DOUBLE_MAT2 0x8F46 -#define GL_DOUBLE_MAT3 0x8F47 -#define GL_DOUBLE_MAT4 0x8F48 -#define GL_DOUBLE_MAT2x3 0x8F49 -#define GL_DOUBLE_MAT2x4 0x8F4A -#define GL_DOUBLE_MAT3x2 0x8F4B -#define GL_DOUBLE_MAT3x4 0x8F4C -#define GL_DOUBLE_MAT4x2 0x8F4D -#define GL_DOUBLE_MAT4x3 0x8F4E -#define GL_ACTIVE_SUBROUTINES 0x8DE5 -#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 -#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 -#define GL_MAX_SUBROUTINES 0x8DE7 -#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 -#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A -#define GL_COMPATIBLE_SUBROUTINES 0x8E4B -#define GL_PATCHES 0x000E -#define GL_PATCH_VERTICES 0x8E72 -#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 -#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 -#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 -#define GL_TESS_GEN_MODE 0x8E76 -#define GL_TESS_GEN_SPACING 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 -#define GL_TESS_GEN_POINT_MODE 0x8E79 -#define GL_ISOLINES 0x8E7A -#define GL_FRACTIONAL_ODD 0x8E7B -#define GL_FRACTIONAL_EVEN 0x8E7C -#define GL_MAX_PATCH_VERTICES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 -#define GL_TESS_EVALUATION_SHADER 0x8E87 -#define GL_TESS_CONTROL_SHADER 0x8E88 -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); -typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); -typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); -typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); -typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); -typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShading (GLfloat value); -GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); -GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); -GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); -GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); -GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); -GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); -GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); -GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); -GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedback (void); -GLAPI void APIENTRY glResumeTransformFeedback (void); -GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); -GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); -GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); -GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); -GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); -#endif -#endif /* GL_VERSION_4_0 */ - -#ifndef GL_VERSION_4_1 -#define GL_VERSION_4_1 1 -#define GL_FIXED 0x140C -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_RGB565 0x8D62 -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#define GL_ALL_SHADER_BITS 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#define GL_MAX_VIEWPORTS 0x825B -#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C -#define GL_VIEWPORT_BOUNDS_RANGE 0x825D -#define GL_LAYER_PROVOKING_VERTEX 0x825E -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F -#define GL_UNDEFINED_VERTEX 0x8260 -typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); -typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); -typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); -typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); -typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); -typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); -typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); -typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); -typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReleaseShaderCompiler (void); -GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); -GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); -GLAPI void APIENTRY glClearDepthf (GLfloat d); -GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); -GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); -GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); -GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); -GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); -GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); -GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); -GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); -GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); -GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); -GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); -GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); -#endif -#endif /* GL_VERSION_4_1 */ - -#ifndef GL_VERSION_4_2 -#define GL_VERSION_4_2 1 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 -#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 -#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 -#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A -#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B -#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C -#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D -#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E -#define GL_NUM_SAMPLE_COUNTS 0x9380 -#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 -#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 -#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 -#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB -#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF -#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 -#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 -#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 -#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 -#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC -#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 -#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#define GL_MAX_IMAGE_UNITS 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 -#define GL_IMAGE_BINDING_NAME 0x8F3A -#define GL_IMAGE_BINDING_LEVEL 0x8F3B -#define GL_IMAGE_BINDING_LAYERED 0x8F3C -#define GL_IMAGE_BINDING_LAYER 0x8F3D -#define GL_IMAGE_BINDING_ACCESS 0x8F3E -#define GL_IMAGE_1D 0x904C -#define GL_IMAGE_2D 0x904D -#define GL_IMAGE_3D 0x904E -#define GL_IMAGE_2D_RECT 0x904F -#define GL_IMAGE_CUBE 0x9050 -#define GL_IMAGE_BUFFER 0x9051 -#define GL_IMAGE_1D_ARRAY 0x9052 -#define GL_IMAGE_2D_ARRAY 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 -#define GL_INT_IMAGE_1D 0x9057 -#define GL_INT_IMAGE_2D 0x9058 -#define GL_INT_IMAGE_3D 0x9059 -#define GL_INT_IMAGE_2D_RECT 0x905A -#define GL_INT_IMAGE_CUBE 0x905B -#define GL_INT_IMAGE_BUFFER 0x905C -#define GL_INT_IMAGE_1D_ARRAY 0x905D -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C -#define GL_MAX_IMAGE_SAMPLES 0x906D -#define GL_IMAGE_BINDING_FORMAT 0x906E -#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 -#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD -#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE -#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF -#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); -typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); -GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); -GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); -GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); -#endif -#endif /* GL_VERSION_4_2 */ - -#ifndef GL_VERSION_4_3 -#define GL_VERSION_4_3 1 -typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 -#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_COMPUTE_SHADER 0x91B9 -#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB -#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC -#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 -#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 -#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 -#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 -#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 -#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB -#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE -#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF -#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED -#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE -#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_COMPUTE_SHADER_BIT 0x00000020 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_BUFFER 0x82E0 -#define GL_SHADER 0x82E1 -#define GL_PROGRAM 0x82E2 -#define GL_QUERY 0x82E3 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_SAMPLER 0x82E6 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_MAX_UNIFORM_LOCATIONS 0x826E -#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 -#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 -#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 -#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 -#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 -#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 -#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 -#define GL_INTERNALFORMAT_SUPPORTED 0x826F -#define GL_INTERNALFORMAT_PREFERRED 0x8270 -#define GL_INTERNALFORMAT_RED_SIZE 0x8271 -#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 -#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 -#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 -#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 -#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 -#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 -#define GL_INTERNALFORMAT_RED_TYPE 0x8278 -#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 -#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A -#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B -#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C -#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D -#define GL_MAX_WIDTH 0x827E -#define GL_MAX_HEIGHT 0x827F -#define GL_MAX_DEPTH 0x8280 -#define GL_MAX_LAYERS 0x8281 -#define GL_MAX_COMBINED_DIMENSIONS 0x8282 -#define GL_COLOR_COMPONENTS 0x8283 -#define GL_DEPTH_COMPONENTS 0x8284 -#define GL_STENCIL_COMPONENTS 0x8285 -#define GL_COLOR_RENDERABLE 0x8286 -#define GL_DEPTH_RENDERABLE 0x8287 -#define GL_STENCIL_RENDERABLE 0x8288 -#define GL_FRAMEBUFFER_RENDERABLE 0x8289 -#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A -#define GL_FRAMEBUFFER_BLEND 0x828B -#define GL_READ_PIXELS 0x828C -#define GL_READ_PIXELS_FORMAT 0x828D -#define GL_READ_PIXELS_TYPE 0x828E -#define GL_TEXTURE_IMAGE_FORMAT 0x828F -#define GL_TEXTURE_IMAGE_TYPE 0x8290 -#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 -#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 -#define GL_MIPMAP 0x8293 -#define GL_MANUAL_GENERATE_MIPMAP 0x8294 -#define GL_AUTO_GENERATE_MIPMAP 0x8295 -#define GL_COLOR_ENCODING 0x8296 -#define GL_SRGB_READ 0x8297 -#define GL_SRGB_WRITE 0x8298 -#define GL_FILTER 0x829A -#define GL_VERTEX_TEXTURE 0x829B -#define GL_TESS_CONTROL_TEXTURE 0x829C -#define GL_TESS_EVALUATION_TEXTURE 0x829D -#define GL_GEOMETRY_TEXTURE 0x829E -#define GL_FRAGMENT_TEXTURE 0x829F -#define GL_COMPUTE_TEXTURE 0x82A0 -#define GL_TEXTURE_SHADOW 0x82A1 -#define GL_TEXTURE_GATHER 0x82A2 -#define GL_TEXTURE_GATHER_SHADOW 0x82A3 -#define GL_SHADER_IMAGE_LOAD 0x82A4 -#define GL_SHADER_IMAGE_STORE 0x82A5 -#define GL_SHADER_IMAGE_ATOMIC 0x82A6 -#define GL_IMAGE_TEXEL_SIZE 0x82A7 -#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 -#define GL_IMAGE_PIXEL_FORMAT 0x82A9 -#define GL_IMAGE_PIXEL_TYPE 0x82AA -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF -#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 -#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 -#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 -#define GL_CLEAR_BUFFER 0x82B4 -#define GL_TEXTURE_VIEW 0x82B5 -#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 -#define GL_FULL_SUPPORT 0x82B7 -#define GL_CAVEAT_SUPPORT 0x82B8 -#define GL_IMAGE_CLASS_4_X_32 0x82B9 -#define GL_IMAGE_CLASS_2_X_32 0x82BA -#define GL_IMAGE_CLASS_1_X_32 0x82BB -#define GL_IMAGE_CLASS_4_X_16 0x82BC -#define GL_IMAGE_CLASS_2_X_16 0x82BD -#define GL_IMAGE_CLASS_1_X_16 0x82BE -#define GL_IMAGE_CLASS_4_X_8 0x82BF -#define GL_IMAGE_CLASS_2_X_8 0x82C0 -#define GL_IMAGE_CLASS_1_X_8 0x82C1 -#define GL_IMAGE_CLASS_11_11_10 0x82C2 -#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 -#define GL_VIEW_CLASS_128_BITS 0x82C4 -#define GL_VIEW_CLASS_96_BITS 0x82C5 -#define GL_VIEW_CLASS_64_BITS 0x82C6 -#define GL_VIEW_CLASS_48_BITS 0x82C7 -#define GL_VIEW_CLASS_32_BITS 0x82C8 -#define GL_VIEW_CLASS_24_BITS 0x82C9 -#define GL_VIEW_CLASS_16_BITS 0x82CA -#define GL_VIEW_CLASS_8_BITS 0x82CB -#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC -#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD -#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE -#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF -#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 -#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 -#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 -#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 -#define GL_UNIFORM 0x92E1 -#define GL_UNIFORM_BLOCK 0x92E2 -#define GL_PROGRAM_INPUT 0x92E3 -#define GL_PROGRAM_OUTPUT 0x92E4 -#define GL_BUFFER_VARIABLE 0x92E5 -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#define GL_VERTEX_SUBROUTINE 0x92E8 -#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 -#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA -#define GL_GEOMETRY_SUBROUTINE 0x92EB -#define GL_FRAGMENT_SUBROUTINE 0x92EC -#define GL_COMPUTE_SUBROUTINE 0x92ED -#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE -#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF -#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 -#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 -#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 -#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 -#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 -#define GL_ACTIVE_RESOURCES 0x92F5 -#define GL_MAX_NAME_LENGTH 0x92F6 -#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 -#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 -#define GL_NAME_LENGTH 0x92F9 -#define GL_TYPE 0x92FA -#define GL_ARRAY_SIZE 0x92FB -#define GL_OFFSET 0x92FC -#define GL_BLOCK_INDEX 0x92FD -#define GL_ARRAY_STRIDE 0x92FE -#define GL_MATRIX_STRIDE 0x92FF -#define GL_IS_ROW_MAJOR 0x9300 -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_ACTIVE_VARIABLES 0x9305 -#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 -#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 -#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A -#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B -#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C -#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D -#define GL_LOCATION 0x930E -#define GL_LOCATION_INDEX 0x930F -#define GL_IS_PER_PATCH 0x92E7 -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 -#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 -#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 -#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA -#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB -#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC -#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD -#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE -#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 -#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA -#define GL_TEXTURE_BUFFER_OFFSET 0x919D -#define GL_TEXTURE_BUFFER_SIZE 0x919E -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F -#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB -#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC -#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD -#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF -#define GL_VERTEX_ATTRIB_BINDING 0x82D4 -#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 -#define GL_VERTEX_BINDING_DIVISOR 0x82D6 -#define GL_VERTEX_BINDING_OFFSET 0x82D7 -#define GL_VERTEX_BINDING_STRIDE 0x82D8 -#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 -#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA -#define GL_VERTEX_BINDING_BUFFER 0x8F4F -#define GL_DISPLAY_LIST 0x82E7 -typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); -typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); -typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); -typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); -typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); -typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); -typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); -typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); -typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); -GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); -GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); -GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); -GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); -GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); -GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); -GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); -GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); -GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); -GLAPI void APIENTRY glPopDebugGroup (void); -GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif -#endif /* GL_VERSION_4_3 */ - -#ifndef GL_VERSION_4_4 -#define GL_VERSION_4_4 1 -#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_TEXTURE_BUFFER_BINDING 0x8C2A -#define GL_MAP_PERSISTENT_BIT 0x0040 -#define GL_MAP_COHERENT_BIT 0x0080 -#define GL_DYNAMIC_STORAGE_BIT 0x0100 -#define GL_CLIENT_STORAGE_BIT 0x0200 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 -#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F -#define GL_BUFFER_STORAGE_FLAGS 0x8220 -#define GL_CLEAR_TEXTURE 0x9365 -#define GL_LOCATION_COMPONENT 0x934A -#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B -#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C -#define GL_QUERY_BUFFER 0x9192 -#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 -#define GL_QUERY_BUFFER_BINDING 0x9193 -#define GL_QUERY_RESULT_NO_WAIT 0x9194 -#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 -typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); -typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); -typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); -typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); -typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); -typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); -GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); -GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); -GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); -GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); -GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -#endif -#endif /* GL_VERSION_4_4 */ - -#ifndef GL_VERSION_4_5 -#define GL_VERSION_4_5 1 -#define GL_CONTEXT_LOST 0x0507 -#define GL_NEGATIVE_ONE_TO_ONE 0x935E -#define GL_ZERO_TO_ONE 0x935F -#define GL_CLIP_ORIGIN 0x935C -#define GL_CLIP_DEPTH_MODE 0x935D -#define GL_QUERY_WAIT_INVERTED 0x8E17 -#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 -#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 -#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A -#define GL_MAX_CULL_DISTANCES 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA -#define GL_TEXTURE_TARGET 0x1006 -#define GL_QUERY_TARGET 0x82EA -#define GL_GUILTY_CONTEXT_RESET 0x8253 -#define GL_INNOCENT_CONTEXT_RESET 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET 0x8252 -#define GL_NO_RESET_NOTIFICATION 0x8261 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC -typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); -typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); -typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); -typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); -typedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (APIENTRYP PFNGLGETNMAPDVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLGETNMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); -GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); -GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); -GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); -GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); -GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); -GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); -GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); -GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); -GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); -GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); -GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); -GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); -GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); -GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); -GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); -GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); -GLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); -GLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); -GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GLAPI void APIENTRY glGetnMapdv (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfv (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapiv (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfv (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuiv (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusv (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStipple (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTable (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -GLAPI void APIENTRY glGetnConvolutionFilter (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -GLAPI void APIENTRY glGetnSeparableFilter (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -GLAPI void APIENTRY glGetnHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glGetnMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glTextureBarrier (void); -#endif -#endif /* GL_VERSION_4_5 */ - -#ifndef GL_ARB_ES2_compatibility -#define GL_ARB_ES2_compatibility 1 -#endif /* GL_ARB_ES2_compatibility */ - -#ifndef GL_ARB_ES3_1_compatibility -#define GL_ARB_ES3_1_compatibility 1 -#endif /* GL_ARB_ES3_1_compatibility */ - -#ifndef GL_ARB_ES3_compatibility -#define GL_ARB_ES3_compatibility 1 -#endif /* GL_ARB_ES3_compatibility */ - -#ifndef GL_ARB_arrays_of_arrays -#define GL_ARB_arrays_of_arrays 1 -#endif /* GL_ARB_arrays_of_arrays */ - -#ifndef GL_ARB_base_instance -#define GL_ARB_base_instance 1 -#endif /* GL_ARB_base_instance */ - -#ifndef GL_ARB_bindless_texture -#define GL_ARB_bindless_texture 1 -typedef uint64_t GLuint64EXT; -#define GL_UNSIGNED_INT64_ARB 0x140F -typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); -typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); -GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); -GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); -GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); -GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); -GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); -GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); -GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); -GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); -GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); -GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); -GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); -#endif -#endif /* GL_ARB_bindless_texture */ - -#ifndef GL_ARB_blend_func_extended -#define GL_ARB_blend_func_extended 1 -#endif /* GL_ARB_blend_func_extended */ - -#ifndef GL_ARB_buffer_storage -#define GL_ARB_buffer_storage 1 -#endif /* GL_ARB_buffer_storage */ - -#ifndef GL_ARB_cl_event -#define GL_ARB_cl_event 1 -struct _cl_context; -struct _cl_event; -#define GL_SYNC_CL_EVENT_ARB 0x8240 -#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 -typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); -#endif -#endif /* GL_ARB_cl_event */ - -#ifndef GL_ARB_clear_buffer_object -#define GL_ARB_clear_buffer_object 1 -#endif /* GL_ARB_clear_buffer_object */ - -#ifndef GL_ARB_clear_texture -#define GL_ARB_clear_texture 1 -#endif /* GL_ARB_clear_texture */ - -#ifndef GL_ARB_clip_control -#define GL_ARB_clip_control 1 -#endif /* GL_ARB_clip_control */ - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D -typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); -#endif -#endif /* GL_ARB_color_buffer_float */ - -#ifndef GL_ARB_compatibility -#define GL_ARB_compatibility 1 -#endif /* GL_ARB_compatibility */ - -#ifndef GL_ARB_compressed_texture_pixel_storage -#define GL_ARB_compressed_texture_pixel_storage 1 -#endif /* GL_ARB_compressed_texture_pixel_storage */ - -#ifndef GL_ARB_compute_shader -#define GL_ARB_compute_shader 1 -#endif /* GL_ARB_compute_shader */ - -#ifndef GL_ARB_compute_variable_group_size -#define GL_ARB_compute_variable_group_size 1 -#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 -#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB -#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 -#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); -#endif -#endif /* GL_ARB_compute_variable_group_size */ - -#ifndef GL_ARB_conditional_render_inverted -#define GL_ARB_conditional_render_inverted 1 -#endif /* GL_ARB_conditional_render_inverted */ - -#ifndef GL_ARB_conservative_depth -#define GL_ARB_conservative_depth 1 -#endif /* GL_ARB_conservative_depth */ - -#ifndef GL_ARB_copy_buffer -#define GL_ARB_copy_buffer 1 -#endif /* GL_ARB_copy_buffer */ - -#ifndef GL_ARB_copy_image -#define GL_ARB_copy_image 1 -#endif /* GL_ARB_copy_image */ - -#ifndef GL_ARB_cull_distance -#define GL_ARB_cull_distance 1 -#endif /* GL_ARB_cull_distance */ - -#ifndef GL_ARB_debug_output -#define GL_ARB_debug_output 1 -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#endif -#endif /* GL_ARB_debug_output */ - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 -#endif /* GL_ARB_depth_buffer_float */ - -#ifndef GL_ARB_depth_clamp -#define GL_ARB_depth_clamp 1 -#endif /* GL_ARB_depth_clamp */ - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif /* GL_ARB_depth_texture */ - -#ifndef GL_ARB_derivative_control -#define GL_ARB_derivative_control 1 -#endif /* GL_ARB_derivative_control */ - -#ifndef GL_ARB_direct_state_access -#define GL_ARB_direct_state_access 1 -#endif /* GL_ARB_direct_state_access */ - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 -typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); -#endif -#endif /* GL_ARB_draw_buffers */ - -#ifndef GL_ARB_draw_buffers_blend -#define GL_ARB_draw_buffers_blend 1 -typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif -#endif /* GL_ARB_draw_buffers_blend */ - -#ifndef GL_ARB_draw_elements_base_vertex -#define GL_ARB_draw_elements_base_vertex 1 -#endif /* GL_ARB_draw_elements_base_vertex */ - -#ifndef GL_ARB_draw_indirect -#define GL_ARB_draw_indirect 1 -#endif /* GL_ARB_draw_indirect */ - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#endif -#endif /* GL_ARB_draw_instanced */ - -#ifndef GL_ARB_enhanced_layouts -#define GL_ARB_enhanced_layouts 1 -#endif /* GL_ARB_enhanced_layouts */ - -#ifndef GL_ARB_explicit_attrib_location -#define GL_ARB_explicit_attrib_location 1 -#endif /* GL_ARB_explicit_attrib_location */ - -#ifndef GL_ARB_explicit_uniform_location -#define GL_ARB_explicit_uniform_location 1 -#endif /* GL_ARB_explicit_uniform_location */ - -#ifndef GL_ARB_fragment_coord_conventions -#define GL_ARB_fragment_coord_conventions 1 -#endif /* GL_ARB_fragment_coord_conventions */ - -#ifndef GL_ARB_fragment_layer_viewport -#define GL_ARB_fragment_layer_viewport 1 -#endif /* GL_ARB_fragment_layer_viewport */ - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const void *string); -GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); -GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, void *string); -GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); -#endif -#endif /* GL_ARB_fragment_program */ - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 -#endif /* GL_ARB_fragment_program_shadow */ - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif /* GL_ARB_fragment_shader */ - -#ifndef GL_ARB_framebuffer_no_attachments -#define GL_ARB_framebuffer_no_attachments 1 -#endif /* GL_ARB_framebuffer_no_attachments */ - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 -#endif /* GL_ARB_framebuffer_object */ - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 -#endif /* GL_ARB_framebuffer_sRGB */ - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 -#define GL_LINES_ADJACENCY_ARB 0x000A -#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B -#define GL_TRIANGLES_ADJACENCY_ARB 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); -GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif -#endif /* GL_ARB_geometry_shader4 */ - -#ifndef GL_ARB_get_program_binary -#define GL_ARB_get_program_binary 1 -#endif /* GL_ARB_get_program_binary */ - -#ifndef GL_ARB_get_texture_sub_image -#define GL_ARB_get_texture_sub_image 1 -#endif /* GL_ARB_get_texture_sub_image */ - -#ifndef GL_ARB_gpu_shader5 -#define GL_ARB_gpu_shader5 1 -#endif /* GL_ARB_gpu_shader5 */ - -#ifndef GL_ARB_gpu_shader_fp64 -#define GL_ARB_gpu_shader_fp64 1 -#endif /* GL_ARB_gpu_shader_fp64 */ - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 -typedef unsigned short GLhalfARB; -#define GL_HALF_FLOAT_ARB 0x140B -#endif /* GL_ARB_half_float_pixel */ - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 -#endif /* GL_ARB_half_float_vertex */ - -#ifndef GL_ARB_imaging -#define GL_ARB_imaging 1 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_EQUATION 0x8009 -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, void *table); -GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, void *image); -GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogram (GLenum target); -GLAPI void APIENTRY glResetMinmax (GLenum target); -#endif -#endif /* GL_ARB_imaging */ - -#ifndef GL_ARB_indirect_parameters -#define GL_ARB_indirect_parameters 1 -#define GL_PARAMETER_BUFFER_ARB 0x80EE -#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -#endif -#endif /* GL_ARB_indirect_parameters */ - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); -#endif -#endif /* GL_ARB_instanced_arrays */ - -#ifndef GL_ARB_internalformat_query -#define GL_ARB_internalformat_query 1 -#endif /* GL_ARB_internalformat_query */ - -#ifndef GL_ARB_internalformat_query2 -#define GL_ARB_internalformat_query2 1 -#define GL_SRGB_DECODE_ARB 0x8299 -#endif /* GL_ARB_internalformat_query2 */ - -#ifndef GL_ARB_invalidate_subdata -#define GL_ARB_invalidate_subdata 1 -#endif /* GL_ARB_invalidate_subdata */ - -#ifndef GL_ARB_map_buffer_alignment -#define GL_ARB_map_buffer_alignment 1 -#endif /* GL_ARB_map_buffer_alignment */ - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 -#endif /* GL_ARB_map_buffer_range */ - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); -GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); -GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); -GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_ARB_matrix_palette */ - -#ifndef GL_ARB_multi_bind -#define GL_ARB_multi_bind 1 -#endif /* GL_ARB_multi_bind */ - -#ifndef GL_ARB_multi_draw_indirect -#define GL_ARB_multi_draw_indirect 1 -#endif /* GL_ARB_multi_draw_indirect */ - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); -#endif -#endif /* GL_ARB_multisample */ - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); -#endif -#endif /* GL_ARB_multitexture */ - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 -typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); -GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQueryARB (GLenum target); -GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); -#endif -#endif /* GL_ARB_occlusion_query */ - -#ifndef GL_ARB_occlusion_query2 -#define GL_ARB_occlusion_query2 1 -#endif /* GL_ARB_occlusion_query2 */ - -#ifndef GL_ARB_pipeline_statistics_query -#define GL_ARB_pipeline_statistics_query 1 -#define GL_VERTICES_SUBMITTED_ARB 0x82EE -#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF -#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 -#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 -#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 -#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 -#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 -#endif /* GL_ARB_pipeline_statistics_query */ - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#endif /* GL_ARB_pixel_buffer_object */ - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_ARB_point_parameters */ - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 -#endif /* GL_ARB_point_sprite */ - -#ifndef GL_ARB_program_interface_query -#define GL_ARB_program_interface_query 1 -#endif /* GL_ARB_program_interface_query */ - -#ifndef GL_ARB_provoking_vertex -#define GL_ARB_provoking_vertex 1 -#endif /* GL_ARB_provoking_vertex */ - -#ifndef GL_ARB_query_buffer_object -#define GL_ARB_query_buffer_object 1 -#endif /* GL_ARB_query_buffer_object */ - -#ifndef GL_ARB_robust_buffer_access_behavior -#define GL_ARB_robust_buffer_access_behavior 1 -#endif /* GL_ARB_robust_buffer_access_behavior */ - -#ifndef GL_ARB_robustness -#define GL_ARB_robustness 1 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); -typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); -GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); -GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); -GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -#endif -#endif /* GL_ARB_robustness */ - -#ifndef GL_ARB_robustness_isolation -#define GL_ARB_robustness_isolation 1 -#endif /* GL_ARB_robustness_isolation */ - -#ifndef GL_ARB_sample_shading -#define GL_ARB_sample_shading 1 -#define GL_SAMPLE_SHADING_ARB 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); -#endif -#endif /* GL_ARB_sample_shading */ - -#ifndef GL_ARB_sampler_objects -#define GL_ARB_sampler_objects 1 -#endif /* GL_ARB_sampler_objects */ - -#ifndef GL_ARB_seamless_cube_map -#define GL_ARB_seamless_cube_map 1 -#endif /* GL_ARB_seamless_cube_map */ - -#ifndef GL_ARB_seamless_cubemap_per_texture -#define GL_ARB_seamless_cubemap_per_texture 1 -#endif /* GL_ARB_seamless_cubemap_per_texture */ - -#ifndef GL_ARB_separate_shader_objects -#define GL_ARB_separate_shader_objects 1 -#endif /* GL_ARB_separate_shader_objects */ - -#ifndef GL_ARB_shader_atomic_counters -#define GL_ARB_shader_atomic_counters 1 -#endif /* GL_ARB_shader_atomic_counters */ - -#ifndef GL_ARB_shader_bit_encoding -#define GL_ARB_shader_bit_encoding 1 -#endif /* GL_ARB_shader_bit_encoding */ - -#ifndef GL_ARB_shader_draw_parameters -#define GL_ARB_shader_draw_parameters 1 -#endif /* GL_ARB_shader_draw_parameters */ - -#ifndef GL_ARB_shader_group_vote -#define GL_ARB_shader_group_vote 1 -#endif /* GL_ARB_shader_group_vote */ - -#ifndef GL_ARB_shader_image_load_store -#define GL_ARB_shader_image_load_store 1 -#endif /* GL_ARB_shader_image_load_store */ - -#ifndef GL_ARB_shader_image_size -#define GL_ARB_shader_image_size 1 -#endif /* GL_ARB_shader_image_size */ - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif -typedef char GLcharARB; -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); -GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); -GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); -GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); -GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); -GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); -GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); -GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); -GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); -GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); -GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif -#endif /* GL_ARB_shader_objects */ - -#ifndef GL_ARB_shader_precision -#define GL_ARB_shader_precision 1 -#endif /* GL_ARB_shader_precision */ - -#ifndef GL_ARB_shader_stencil_export -#define GL_ARB_shader_stencil_export 1 -#endif /* GL_ARB_shader_stencil_export */ - -#ifndef GL_ARB_shader_storage_buffer_object -#define GL_ARB_shader_storage_buffer_object 1 -#endif /* GL_ARB_shader_storage_buffer_object */ - -#ifndef GL_ARB_shader_subroutine -#define GL_ARB_shader_subroutine 1 -#endif /* GL_ARB_shader_subroutine */ - -#ifndef GL_ARB_shader_texture_image_samples -#define GL_ARB_shader_texture_image_samples 1 -#endif /* GL_ARB_shader_texture_image_samples */ - -#ifndef GL_ARB_shader_texture_lod -#define GL_ARB_shader_texture_lod 1 -#endif /* GL_ARB_shader_texture_lod */ - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#endif /* GL_ARB_shading_language_100 */ - -#ifndef GL_ARB_shading_language_420pack -#define GL_ARB_shading_language_420pack 1 -#endif /* GL_ARB_shading_language_420pack */ - -#ifndef GL_ARB_shading_language_include -#define GL_ARB_shading_language_include 1 -#define GL_SHADER_INCLUDE_ARB 0x8DAE -#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 -#define GL_NAMED_STRING_TYPE_ARB 0x8DEA -typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); -typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); -GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#endif -#endif /* GL_ARB_shading_language_include */ - -#ifndef GL_ARB_shading_language_packing -#define GL_ARB_shading_language_packing 1 -#endif /* GL_ARB_shading_language_packing */ - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#endif /* GL_ARB_shadow */ - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#endif /* GL_ARB_shadow_ambient */ - -#ifndef GL_ARB_sparse_buffer -#define GL_ARB_sparse_buffer 1 -#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 -#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 -typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -#endif -#endif /* GL_ARB_sparse_buffer */ - -#ifndef GL_ARB_sparse_texture -#define GL_ARB_sparse_texture 1 -#define GL_TEXTURE_SPARSE_ARB 0x91A6 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA -#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 -#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -#endif -#endif /* GL_ARB_sparse_texture */ - -#ifndef GL_ARB_stencil_texturing -#define GL_ARB_stencil_texturing 1 -#endif /* GL_ARB_stencil_texturing */ - -#ifndef GL_ARB_sync -#define GL_ARB_sync 1 -#endif /* GL_ARB_sync */ - -#ifndef GL_ARB_tessellation_shader -#define GL_ARB_tessellation_shader 1 -#endif /* GL_ARB_tessellation_shader */ - -#ifndef GL_ARB_texture_barrier -#define GL_ARB_texture_barrier 1 -#endif /* GL_ARB_texture_barrier */ - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif /* GL_ARB_texture_border_clamp */ - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E -typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); -#endif -#endif /* GL_ARB_texture_buffer_object */ - -#ifndef GL_ARB_texture_buffer_object_rgb32 -#define GL_ARB_texture_buffer_object_rgb32 1 -#endif /* GL_ARB_texture_buffer_object_rgb32 */ - -#ifndef GL_ARB_texture_buffer_range -#define GL_ARB_texture_buffer_range 1 -#endif /* GL_ARB_texture_buffer_range */ - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void *img); -#endif -#endif /* GL_ARB_texture_compression */ - -#ifndef GL_ARB_texture_compression_bptc -#define GL_ARB_texture_compression_bptc 1 -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F -#endif /* GL_ARB_texture_compression_bptc */ - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 -#endif /* GL_ARB_texture_compression_rgtc */ - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif /* GL_ARB_texture_cube_map */ - -#ifndef GL_ARB_texture_cube_map_array -#define GL_ARB_texture_cube_map_array 1 -#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F -#endif /* GL_ARB_texture_cube_map_array */ - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 -#endif /* GL_ARB_texture_env_add */ - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#endif /* GL_ARB_texture_env_combine */ - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 -#endif /* GL_ARB_texture_env_crossbar */ - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF -#endif /* GL_ARB_texture_env_dot3 */ - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif /* GL_ARB_texture_float */ - -#ifndef GL_ARB_texture_gather -#define GL_ARB_texture_gather 1 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F -#endif /* GL_ARB_texture_gather */ - -#ifndef GL_ARB_texture_mirror_clamp_to_edge -#define GL_ARB_texture_mirror_clamp_to_edge 1 -#endif /* GL_ARB_texture_mirror_clamp_to_edge */ - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#endif /* GL_ARB_texture_mirrored_repeat */ - -#ifndef GL_ARB_texture_multisample -#define GL_ARB_texture_multisample 1 -#endif /* GL_ARB_texture_multisample */ - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 -#endif /* GL_ARB_texture_non_power_of_two */ - -#ifndef GL_ARB_texture_query_levels -#define GL_ARB_texture_query_levels 1 -#endif /* GL_ARB_texture_query_levels */ - -#ifndef GL_ARB_texture_query_lod -#define GL_ARB_texture_query_lod 1 -#endif /* GL_ARB_texture_query_lod */ - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#endif /* GL_ARB_texture_rectangle */ - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 -#endif /* GL_ARB_texture_rg */ - -#ifndef GL_ARB_texture_rgb10_a2ui -#define GL_ARB_texture_rgb10_a2ui 1 -#endif /* GL_ARB_texture_rgb10_a2ui */ - -#ifndef GL_ARB_texture_stencil8 -#define GL_ARB_texture_stencil8 1 -#endif /* GL_ARB_texture_stencil8 */ - -#ifndef GL_ARB_texture_storage -#define GL_ARB_texture_storage 1 -#endif /* GL_ARB_texture_storage */ - -#ifndef GL_ARB_texture_storage_multisample -#define GL_ARB_texture_storage_multisample 1 -#endif /* GL_ARB_texture_storage_multisample */ - -#ifndef GL_ARB_texture_swizzle -#define GL_ARB_texture_swizzle 1 -#endif /* GL_ARB_texture_swizzle */ - -#ifndef GL_ARB_texture_view -#define GL_ARB_texture_view 1 -#endif /* GL_ARB_texture_view */ - -#ifndef GL_ARB_timer_query -#define GL_ARB_timer_query 1 -#endif /* GL_ARB_timer_query */ - -#ifndef GL_ARB_transform_feedback2 -#define GL_ARB_transform_feedback2 1 -#endif /* GL_ARB_transform_feedback2 */ - -#ifndef GL_ARB_transform_feedback3 -#define GL_ARB_transform_feedback3 1 -#endif /* GL_ARB_transform_feedback3 */ - -#ifndef GL_ARB_transform_feedback_instanced -#define GL_ARB_transform_feedback_instanced 1 -#endif /* GL_ARB_transform_feedback_instanced */ - -#ifndef GL_ARB_transform_feedback_overflow_query -#define GL_ARB_transform_feedback_overflow_query 1 -#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED -#endif /* GL_ARB_transform_feedback_overflow_query */ - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); -#endif -#endif /* GL_ARB_transpose_matrix */ - -#ifndef GL_ARB_uniform_buffer_object -#define GL_ARB_uniform_buffer_object 1 -#endif /* GL_ARB_uniform_buffer_object */ - -#ifndef GL_ARB_vertex_array_bgra -#define GL_ARB_vertex_array_bgra 1 -#endif /* GL_ARB_vertex_array_bgra */ - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 -#endif /* GL_ARB_vertex_array_object */ - -#ifndef GL_ARB_vertex_attrib_64bit -#define GL_ARB_vertex_attrib_64bit 1 -#endif /* GL_ARB_vertex_attrib_64bit */ - -#ifndef GL_ARB_vertex_attrib_binding -#define GL_ARB_vertex_attrib_binding 1 -#endif /* GL_ARB_vertex_attrib_binding */ - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); -typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); -typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); -typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); -typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); -typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); -typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); -GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); -GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); -GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); -GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); -GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); -GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); -GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); -GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glVertexBlendARB (GLint count); -#endif -#endif /* GL_ARB_vertex_blend */ - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 -typedef ptrdiff_t GLsizeiptrARB; -typedef ptrdiff_t GLintptrARB; -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); -typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); -GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); -GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); -GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_ARB_vertex_buffer_object */ - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, void **pointer); -#endif -#endif /* GL_ARB_vertex_program */ - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); -#endif -#endif /* GL_ARB_vertex_shader */ - -#ifndef GL_ARB_vertex_type_10f_11f_11f_rev -#define GL_ARB_vertex_type_10f_11f_11f_rev 1 -#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ - -#ifndef GL_ARB_vertex_type_2_10_10_10_rev -#define GL_ARB_vertex_type_2_10_10_10_rev 1 -#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ - -#ifndef GL_ARB_viewport_array -#define GL_ARB_viewport_array 1 -#endif /* GL_ARB_viewport_array */ - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 -typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); -#endif -#endif /* GL_ARB_window_pos */ - -#ifndef GL_KHR_blend_equation_advanced -#define GL_KHR_blend_equation_advanced 1 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_SCREEN_KHR 0x9295 -#define GL_OVERLAY_KHR 0x9296 -#define GL_DARKEN_KHR 0x9297 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORBURN_KHR 0x929A -#define GL_HARDLIGHT_KHR 0x929B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_DIFFERENCE_KHR 0x929E -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_LUMINOSITY_KHR 0x92B0 -typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendBarrierKHR (void); -#endif -#endif /* GL_KHR_blend_equation_advanced */ - -#ifndef GL_KHR_blend_equation_advanced_coherent -#define GL_KHR_blend_equation_advanced_coherent 1 -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#endif /* GL_KHR_blend_equation_advanced_coherent */ - -#ifndef GL_KHR_context_flush_control -#define GL_KHR_context_flush_control 1 -#endif /* GL_KHR_context_flush_control */ - -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -#endif /* GL_KHR_debug */ - -#ifndef GL_KHR_robust_buffer_access_behavior -#define GL_KHR_robust_buffer_access_behavior 1 -#endif /* GL_KHR_robust_buffer_access_behavior */ - -#ifndef GL_KHR_robustness -#define GL_KHR_robustness 1 -#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 -#endif /* GL_KHR_robustness */ - -#ifndef GL_KHR_texture_compression_astc_hdr -#define GL_KHR_texture_compression_astc_hdr 1 -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#endif /* GL_KHR_texture_compression_astc_hdr */ - -#ifndef GL_KHR_texture_compression_astc_ldr -#define GL_KHR_texture_compression_astc_ldr 1 -#endif /* GL_KHR_texture_compression_astc_ldr */ - -#ifndef GL_OES_byte_coordinates -#define GL_OES_byte_coordinates 1 -typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD1BOESPROC) (GLbyte s); -typedef void (APIENTRYP PFNGLTEXCOORD1BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); -typedef void (APIENTRYP PFNGLTEXCOORD2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); -typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); -typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x, GLbyte y); -typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y, GLbyte z); -typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z, GLbyte w); -typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); -GLAPI void APIENTRY glMultiTexCoord1bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord2bOES (GLenum texture, GLbyte s, GLbyte t); -GLAPI void APIENTRY glMultiTexCoord2bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord3bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r); -GLAPI void APIENTRY glMultiTexCoord3bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord4bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); -GLAPI void APIENTRY glMultiTexCoord4bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glTexCoord1bOES (GLbyte s); -GLAPI void APIENTRY glTexCoord1bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord2bOES (GLbyte s, GLbyte t); -GLAPI void APIENTRY glTexCoord2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); -GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); -GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex2bOES (GLbyte x, GLbyte y); -GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y, GLbyte z); -GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z, GLbyte w); -GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); -#endif -#endif /* GL_OES_byte_coordinates */ - -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#endif /* GL_OES_compressed_paletted_texture */ - -#ifndef GL_OES_fixed_point -#define GL_OES_fixed_point 1 -typedef GLint GLfixed; -#define GL_FIXED_OES 0x140C -typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); -typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth); -typedef void (APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); -typedef void (APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); -typedef void (APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width); -typedef void (APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); -typedef void (APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); -typedef void (APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); -typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); -typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); -typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLACCUMXOESPROC) (GLenum op, GLfixed value); -typedef void (APIENTRYP PFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); -typedef void (APIENTRYP PFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); -typedef void (APIENTRYP PFNGLCOLOR3XVOESPROC) (const GLfixed *components); -typedef void (APIENTRYP PFNGLCOLOR4XVOESPROC) (const GLfixed *components); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLEVALCOORD1XOESPROC) (GLfixed u); -typedef void (APIENTRYP PFNGLEVALCOORD1XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); -typedef void (APIENTRYP PFNGLEVALCOORD2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); -typedef void (APIENTRYP PFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); -typedef void (APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLINDEXXOESPROC) (GLfixed component); -typedef void (APIENTRYP PFNGLINDEXXVOESPROC) (const GLfixed *component); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); -typedef void (APIENTRYP PFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); -typedef void (APIENTRYP PFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); -typedef void (APIENTRYP PFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLNORMAL3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLPASSTHROUGHXOESPROC) (GLfixed token); -typedef void (APIENTRYP PFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); -typedef void (APIENTRYP PFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); -typedef void (APIENTRYP PFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); -typedef void (APIENTRYP PFNGLRASTERPOS2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLRASTERPOS3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); -typedef void (APIENTRYP PFNGLRASTERPOS4XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); -typedef void (APIENTRYP PFNGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); -typedef void (APIENTRYP PFNGLTEXCOORD1XOESPROC) (GLfixed s); -typedef void (APIENTRYP PFNGLTEXCOORD1XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); -typedef void (APIENTRYP PFNGLTEXCOORD2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); -typedef void (APIENTRYP PFNGLTEXCOORD3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); -typedef void (APIENTRYP PFNGLTEXCOORD4XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLVERTEX2XOESPROC) (GLfixed x); -typedef void (APIENTRYP PFNGLVERTEX2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); -typedef void (APIENTRYP PFNGLVERTEX3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLVERTEX4XVOESPROC) (const GLfixed *coords); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref); -GLAPI void APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glClearDepthxOES (GLfixed depth); -GLAPI void APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation); -GLAPI void APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glDepthRangexOES (GLfixed n, GLfixed f); -GLAPI void APIENTRY glFogxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glFogxvOES (GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -GLAPI void APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation); -GLAPI void APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glLightModelxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param); -GLAPI void APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glLineWidthxOES (GLfixed width); -GLAPI void APIENTRY glLoadMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param); -GLAPI void APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glMultMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); -GLAPI void APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz); -GLAPI void APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glPointSizexOES (GLfixed size); -GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); -GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); -GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glAccumxOES (GLenum op, GLfixed value); -GLAPI void APIENTRY glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); -GLAPI void APIENTRY glBlendColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glColor3xOES (GLfixed red, GLfixed green, GLfixed blue); -GLAPI void APIENTRY glColor3xvOES (const GLfixed *components); -GLAPI void APIENTRY glColor4xvOES (const GLfixed *components); -GLAPI void APIENTRY glConvolutionParameterxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glConvolutionParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glEvalCoord1xOES (GLfixed u); -GLAPI void APIENTRY glEvalCoord1xvOES (const GLfixed *coords); -GLAPI void APIENTRY glEvalCoord2xOES (GLfixed u, GLfixed v); -GLAPI void APIENTRY glEvalCoord2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glFeedbackBufferxOES (GLsizei n, GLenum type, const GLfixed *buffer); -GLAPI void APIENTRY glGetConvolutionParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetHistogramParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetLightxOES (GLenum light, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetMapxvOES (GLenum target, GLenum query, GLfixed *v); -GLAPI void APIENTRY glGetMaterialxOES (GLenum face, GLenum pname, GLfixed param); -GLAPI void APIENTRY glGetPixelMapxv (GLenum map, GLint size, GLfixed *values); -GLAPI void APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexLevelParameterxvOES (GLenum target, GLint level, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glIndexxOES (GLfixed component); -GLAPI void APIENTRY glIndexxvOES (const GLfixed *component); -GLAPI void APIENTRY glLoadTransposeMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMap1xOES (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); -GLAPI void APIENTRY glMap2xOES (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); -GLAPI void APIENTRY glMapGrid1xOES (GLint n, GLfixed u1, GLfixed u2); -GLAPI void APIENTRY glMapGrid2xOES (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); -GLAPI void APIENTRY glMultTransposeMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMultiTexCoord1xOES (GLenum texture, GLfixed s); -GLAPI void APIENTRY glMultiTexCoord1xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord2xOES (GLenum texture, GLfixed s, GLfixed t); -GLAPI void APIENTRY glMultiTexCoord2xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord3xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r); -GLAPI void APIENTRY glMultiTexCoord3xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord4xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glNormal3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glPassThroughxOES (GLfixed token); -GLAPI void APIENTRY glPixelMapx (GLenum map, GLint size, const GLfixed *values); -GLAPI void APIENTRY glPixelStorex (GLenum pname, GLfixed param); -GLAPI void APIENTRY glPixelTransferxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glPixelZoomxOES (GLfixed xfactor, GLfixed yfactor); -GLAPI void APIENTRY glPrioritizeTexturesxOES (GLsizei n, const GLuint *textures, const GLfixed *priorities); -GLAPI void APIENTRY glRasterPos2xOES (GLfixed x, GLfixed y); -GLAPI void APIENTRY glRasterPos2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRasterPos3xOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glRasterPos3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRasterPos4xOES (GLfixed x, GLfixed y, GLfixed z, GLfixed w); -GLAPI void APIENTRY glRasterPos4xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRectxOES (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); -GLAPI void APIENTRY glRectxvOES (const GLfixed *v1, const GLfixed *v2); -GLAPI void APIENTRY glTexCoord1xOES (GLfixed s); -GLAPI void APIENTRY glTexCoord1xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord2xOES (GLfixed s, GLfixed t); -GLAPI void APIENTRY glTexCoord2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord3xOES (GLfixed s, GLfixed t, GLfixed r); -GLAPI void APIENTRY glTexCoord3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord4xOES (GLfixed s, GLfixed t, GLfixed r, GLfixed q); -GLAPI void APIENTRY glTexCoord4xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glVertex2xOES (GLfixed x); -GLAPI void APIENTRY glVertex2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glVertex3xOES (GLfixed x, GLfixed y); -GLAPI void APIENTRY glVertex3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glVertex4xOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glVertex4xvOES (const GLfixed *coords); -#endif -#endif /* GL_OES_fixed_point */ - -#ifndef GL_OES_query_matrix -#define GL_OES_query_matrix 1 -typedef GLbitfield (APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLbitfield APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent); -#endif -#endif /* GL_OES_query_matrix */ - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#endif /* GL_OES_read_format */ - -#ifndef GL_OES_single_precision -#define GL_OES_single_precision 1 -typedef void (APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); -typedef void (APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); -typedef void (APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); -typedef void (APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -typedef void (APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); -typedef void (APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClearDepthfOES (GLclampf depth); -GLAPI void APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation); -GLAPI void APIENTRY glDepthRangefOES (GLclampf n, GLclampf f); -GLAPI void APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -GLAPI void APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation); -GLAPI void APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -#endif -#endif /* GL_OES_single_precision */ - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#endif /* GL_3DFX_multisample */ - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 -typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); -#endif -#endif /* GL_3DFX_tbuffer */ - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#endif /* GL_3DFX_texture_compression_FXT1 */ - -#ifndef GL_AMD_blend_minmax_factor -#define GL_AMD_blend_minmax_factor 1 -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FACTOR_MAX_AMD 0x901D -#endif /* GL_AMD_blend_minmax_factor */ - -#ifndef GL_AMD_conservative_depth -#define GL_AMD_conservative_depth 1 -#endif /* GL_AMD_conservative_depth */ - -#ifndef GL_AMD_debug_output -#define GL_AMD_debug_output 1 -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 -#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 -#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 -#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A -#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B -#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C -#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D -#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E -#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F -#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 -typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#endif -#endif /* GL_AMD_debug_output */ - -#ifndef GL_AMD_depth_clamp_separate -#define GL_AMD_depth_clamp_separate 1 -#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E -#define GL_DEPTH_CLAMP_FAR_AMD 0x901F -#endif /* GL_AMD_depth_clamp_separate */ - -#ifndef GL_AMD_draw_buffers_blend -#define GL_AMD_draw_buffers_blend 1 -typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#endif -#endif /* GL_AMD_draw_buffers_blend */ - -#ifndef GL_AMD_gcn_shader -#define GL_AMD_gcn_shader 1 -#endif /* GL_AMD_gcn_shader */ - -#ifndef GL_AMD_gpu_shader_int64 -#define GL_AMD_gpu_shader_int64 1 -typedef int64_t GLint64EXT; -#define GL_INT64_NV 0x140E -#define GL_UNSIGNED_INT64_NV 0x140F -#define GL_INT8_NV 0x8FE0 -#define GL_INT8_VEC2_NV 0x8FE1 -#define GL_INT8_VEC3_NV 0x8FE2 -#define GL_INT8_VEC4_NV 0x8FE3 -#define GL_INT16_NV 0x8FE4 -#define GL_INT16_VEC2_NV 0x8FE5 -#define GL_INT16_VEC3_NV 0x8FE6 -#define GL_INT16_VEC4_NV 0x8FE7 -#define GL_INT64_VEC2_NV 0x8FE9 -#define GL_INT64_VEC3_NV 0x8FEA -#define GL_INT64_VEC4_NV 0x8FEB -#define GL_UNSIGNED_INT8_NV 0x8FEC -#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED -#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE -#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF -#define GL_UNSIGNED_INT16_NV 0x8FF0 -#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 -#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 -#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 -#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB -typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); -GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); -GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); -GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); -GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); -GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); -GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif -#endif /* GL_AMD_gpu_shader_int64 */ - -#ifndef GL_AMD_interleaved_elements -#define GL_AMD_interleaved_elements 1 -#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 -#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 -typedef void (APIENTRYP PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribParameteriAMD (GLuint index, GLenum pname, GLint param); -#endif -#endif /* GL_AMD_interleaved_elements */ - -#ifndef GL_AMD_multi_draw_indirect -#define GL_AMD_multi_draw_indirect 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); -#endif -#endif /* GL_AMD_multi_draw_indirect */ - -#ifndef GL_AMD_name_gen_delete -#define GL_AMD_name_gen_delete 1 -#define GL_DATA_BUFFER_AMD 0x9151 -#define GL_PERFORMANCE_MONITOR_AMD 0x9152 -#define GL_QUERY_OBJECT_AMD 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 -#define GL_SAMPLER_OBJECT_AMD 0x9155 -typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); -typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); -typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); -GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); -GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); -#endif -#endif /* GL_AMD_name_gen_delete */ - -#ifndef GL_AMD_occlusion_query_event -#define GL_AMD_occlusion_query_event 1 -#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F -#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 -#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 -#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 -#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 -#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF -typedef void (APIENTRYP PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glQueryObjectParameteruiAMD (GLenum target, GLuint id, GLenum pname, GLuint param); -#endif -#endif /* GL_AMD_occlusion_query_event */ - -#ifndef GL_AMD_performance_monitor -#define GL_AMD_performance_monitor 1 -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); -typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); -GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif -#endif /* GL_AMD_performance_monitor */ - -#ifndef GL_AMD_pinned_memory -#define GL_AMD_pinned_memory 1 -#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 -#endif /* GL_AMD_pinned_memory */ - -#ifndef GL_AMD_query_buffer_object -#define GL_AMD_query_buffer_object 1 -#define GL_QUERY_BUFFER_AMD 0x9192 -#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 -#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 -#endif /* GL_AMD_query_buffer_object */ - -#ifndef GL_AMD_sample_positions -#define GL_AMD_sample_positions 1 -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F -typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); -#endif -#endif /* GL_AMD_sample_positions */ - -#ifndef GL_AMD_seamless_cubemap_per_texture -#define GL_AMD_seamless_cubemap_per_texture 1 -#endif /* GL_AMD_seamless_cubemap_per_texture */ - -#ifndef GL_AMD_shader_atomic_counter_ops -#define GL_AMD_shader_atomic_counter_ops 1 -#endif /* GL_AMD_shader_atomic_counter_ops */ - -#ifndef GL_AMD_shader_stencil_export -#define GL_AMD_shader_stencil_export 1 -#endif /* GL_AMD_shader_stencil_export */ - -#ifndef GL_AMD_shader_trinary_minmax -#define GL_AMD_shader_trinary_minmax 1 -#endif /* GL_AMD_shader_trinary_minmax */ - -#ifndef GL_AMD_sparse_texture -#define GL_AMD_sparse_texture 1 -#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A -#define GL_MIN_SPARSE_LEVEL_AMD 0x919B -#define GL_MIN_LOD_WARNING_AMD 0x919C -#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 -typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -#endif -#endif /* GL_AMD_sparse_texture */ - -#ifndef GL_AMD_stencil_operation_extended -#define GL_AMD_stencil_operation_extended 1 -#define GL_SET_AMD 0x874A -#define GL_REPLACE_VALUE_AMD 0x874B -#define GL_STENCIL_OP_VALUE_AMD 0x874C -#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D -typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); -#endif -#endif /* GL_AMD_stencil_operation_extended */ - -#ifndef GL_AMD_texture_texture4 -#define GL_AMD_texture_texture4 1 -#endif /* GL_AMD_texture_texture4 */ - -#ifndef GL_AMD_transform_feedback3_lines_triangles -#define GL_AMD_transform_feedback3_lines_triangles 1 -#endif /* GL_AMD_transform_feedback3_lines_triangles */ - -#ifndef GL_AMD_transform_feedback4 -#define GL_AMD_transform_feedback4 1 -#define GL_STREAM_RASTERIZATION_AMD 0x91A0 -#endif /* GL_AMD_transform_feedback4 */ - -#ifndef GL_AMD_vertex_shader_layer -#define GL_AMD_vertex_shader_layer 1 -#endif /* GL_AMD_vertex_shader_layer */ - -#ifndef GL_AMD_vertex_shader_tessellator -#define GL_AMD_vertex_shader_tessellator 1 -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#define GL_DISCRETE_AMD 0x9006 -#define GL_CONTINUOUS_AMD 0x9007 -typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); -GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); -#endif -#endif /* GL_AMD_vertex_shader_tessellator */ - -#ifndef GL_AMD_vertex_shader_viewport_index -#define GL_AMD_vertex_shader_viewport_index 1 -#endif /* GL_AMD_vertex_shader_viewport_index */ - -#ifndef GL_APPLE_aux_depth_stencil -#define GL_APPLE_aux_depth_stencil 1 -#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 -#endif /* GL_APPLE_aux_depth_stencil */ - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#endif /* GL_APPLE_client_storage */ - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 -#define GL_ELEMENT_ARRAY_APPLE 0x8A0C -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E -typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const void *pointer); -GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif -#endif /* GL_APPLE_element_array */ - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B -typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); -typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); -typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); -GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); -GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); -GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); -#endif -#endif /* GL_APPLE_fence */ - -#ifndef GL_APPLE_float_pixels -#define GL_APPLE_float_pixels 1 -#define GL_HALF_APPLE 0x140B -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_COLOR_FLOAT_APPLE 0x8A0F -#endif /* GL_APPLE_float_pixels */ - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); -#endif -#endif /* GL_APPLE_flush_buffer_range */ - -#ifndef GL_APPLE_object_purgeable -#define GL_APPLE_object_purgeable 1 -#define GL_BUFFER_OBJECT_APPLE 0x85B3 -#define GL_RELEASED_APPLE 0x8A19 -#define GL_VOLATILE_APPLE 0x8A1A -#define GL_RETAINED_APPLE 0x8A1B -#define GL_UNDEFINED_APPLE 0x8A1C -#define GL_PURGEABLE_APPLE 0x8A1D -typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#endif -#endif /* GL_APPLE_object_purgeable */ - -#ifndef GL_APPLE_rgb_422 -#define GL_APPLE_rgb_422 1 -#define GL_RGB_422_APPLE 0x8A1F -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#define GL_RGB_RAW_422_APPLE 0x8A51 -#endif /* GL_APPLE_rgb_422 */ - -#ifndef GL_APPLE_row_bytes -#define GL_APPLE_row_bytes 1 -#define GL_PACK_ROW_BYTES_APPLE 0x8A15 -#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 -#endif /* GL_APPLE_row_bytes */ - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#endif /* GL_APPLE_specular_vector */ - -#ifndef GL_APPLE_texture_range -#define GL_APPLE_texture_range 1 -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF -typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const void *pointer); -GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_APPLE_texture_range */ - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#endif /* GL_APPLE_transform_hint */ - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); -GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); -#endif -#endif /* GL_APPLE_vertex_array_object */ - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CLIENT_APPLE 0x85B4 -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); -typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, void *pointer); -GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, void *pointer); -GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); -#endif -#endif /* GL_APPLE_vertex_array_range */ - -#ifndef GL_APPLE_vertex_program_evaluators -#define GL_APPLE_vertex_program_evaluators 1 -#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 -#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 -#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 -#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 -#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 -#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 -#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 -#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 -#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 -#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#endif -#endif /* GL_APPLE_vertex_program_evaluators */ - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 -#define GL_YCBCR_422_APPLE 0x85B9 -#endif /* GL_APPLE_ycbcr_422 */ - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 -typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); -#endif -#endif /* GL_ATI_draw_buffers */ - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerATI (GLenum type, const void *pointer); -GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif -#endif /* GL_ATI_element_array */ - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); -GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); -#endif -#endif /* GL_ATI_envmap_bumpmap */ - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_RED_BIT_ATI 0x00000001 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); -GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glBeginFragmentShaderATI (void); -GLAPI void APIENTRY glEndFragmentShaderATI (void); -GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); -GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); -GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); -#endif -#endif /* GL_ATI_fragment_shader */ - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 -typedef void *(APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void *APIENTRY glMapObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); -#endif -#endif /* GL_ATI_map_object_buffer */ - -#ifndef GL_ATI_meminfo -#define GL_ATI_meminfo 1 -#define GL_VBO_FREE_MEMORY_ATI 0x87FB -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC -#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD -#endif /* GL_ATI_meminfo */ - -#ifndef GL_ATI_pixel_format_float -#define GL_ATI_pixel_format_float 1 -#define GL_RGBA_FLOAT_MODE_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#endif /* GL_ATI_pixel_format_float */ - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); -GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); -#endif -#endif /* GL_ATI_pn_triangles */ - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif -#endif /* GL_ATI_separate_stencil */ - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#endif /* GL_ATI_text_fragment_shader */ - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#endif /* GL_ATI_texture_env_combine3 */ - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#endif /* GL_ATI_texture_float */ - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#endif /* GL_ATI_texture_mirror_once */ - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); -typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const void *pointer, GLenum usage); -GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); -GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); -GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); -#endif -#endif /* GL_ATI_vertex_array_object */ - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 -typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); -#endif -#endif /* GL_ATI_vertex_attrib_array_object */ - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SOURCE_ATI 0x8774 -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); -GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); -GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); -GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); -GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); -GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); -GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); -GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); -GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); -GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); -#endif -#endif /* GL_ATI_vertex_streams */ - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF -#endif /* GL_EXT_422_pixels */ - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 -#define GL_ABGR_EXT 0x8000 -#endif /* GL_EXT_abgr */ - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 -#endif /* GL_EXT_bgra */ - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); -typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); -GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); -GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); -#endif -#endif /* GL_EXT_bindable_uniform */ - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 -typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -#endif -#endif /* GL_EXT_blend_color */ - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); -#endif -#endif /* GL_EXT_blend_equation_separate */ - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif -#endif /* GL_EXT_blend_func_separate */ - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 -#endif /* GL_EXT_blend_logic_op */ - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_BLEND_EQUATION_EXT 0x8009 -typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); -#endif -#endif /* GL_EXT_blend_minmax */ - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#endif /* GL_EXT_blend_subtract */ - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#endif /* GL_EXT_clip_volume_hint */ - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#endif /* GL_EXT_cmyka */ - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 -typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif -#endif /* GL_EXT_color_subtable */ - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); -GLAPI void APIENTRY glUnlockArraysEXT (void); -#endif -#endif /* GL_EXT_compiled_vertex_array */ - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, void *image); -GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -#endif -#endif /* GL_EXT_convolution */ - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 -typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); -typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); -typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); -typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); -typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); -typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); -typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); -typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); -typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); -typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); -typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); -GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); -GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); -GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); -GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); -GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); -GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); -GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); -GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); -GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); -GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); -GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); -GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); -GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); -GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_coordinate_frame */ - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif -#endif /* GL_EXT_copy_texture */ - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); -GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_cull_vertex */ - -#ifndef GL_EXT_debug_label -#define GL_EXT_debug_label 1 -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -typedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif -#endif /* GL_EXT_debug_label */ - -#ifndef GL_EXT_debug_marker -#define GL_EXT_debug_marker 1 -typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); -GLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); -GLAPI void APIENTRY glPopGroupMarkerEXT (void); -#endif -#endif /* GL_EXT_debug_marker */ - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); -#endif -#endif /* GL_EXT_depth_bounds_test */ - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F -typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); -typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data); -typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); -GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); -GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); -GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); -GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); -GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data); -GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); -GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); -GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img); -GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img); -GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); -GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); -GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params); -GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params); -GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); -GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string); -GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); -GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); -GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array); -GLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array); -GLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param); -GLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param); -GLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); -GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); -GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); -#endif -#endif /* GL_EXT_direct_state_access */ - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 -typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -#endif -#endif /* GL_EXT_draw_buffers2 */ - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#endif -#endif /* GL_EXT_draw_instanced */ - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -#endif -#endif /* GL_EXT_draw_range_elements */ - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); -GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); -GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); -GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_fog_coord */ - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -#endif /* GL_EXT_framebuffer_blit */ - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -#endif /* GL_EXT_framebuffer_multisample */ - -#ifndef GL_EXT_framebuffer_multisample_blit_scaled -#define GL_EXT_framebuffer_multisample_blit_scaled 1 -#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA -#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB -#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); -#endif -#endif /* GL_EXT_framebuffer_object */ - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#endif /* GL_EXT_framebuffer_sRGB */ - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_LINES_ADJACENCY_EXT 0x000A -#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); -#endif -#endif /* GL_EXT_geometry_shader4 */ - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif -#endif /* GL_EXT_gpu_program_parameters */ - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 -typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); -#endif -#endif /* GL_EXT_gpu_shader4 */ - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogramEXT (GLenum target); -GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); -#endif -#endif /* GL_EXT_histogram */ - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#endif /* GL_EXT_index_array_formats */ - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); -#endif -#endif /* GL_EXT_index_func */ - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); -#endif -#endif /* GL_EXT_index_material */ - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 -#endif /* GL_EXT_index_texture */ - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); -GLAPI void APIENTRY glTextureLightEXT (GLenum pname); -GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); -#endif -#endif /* GL_EXT_light_texture */ - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 -#endif /* GL_EXT_misc_attribute */ - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); -#endif -#endif /* GL_EXT_multi_draw_arrays */ - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); -#endif -#endif /* GL_EXT_multisample */ - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#endif /* GL_EXT_packed_depth_stencil */ - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#endif /* GL_EXT_packed_float */ - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#endif /* GL_EXT_packed_pixels */ - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, void *data); -GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_paletted_texture */ - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#endif /* GL_EXT_pixel_buffer_object */ - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_pixel_transform */ - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 -#endif /* GL_EXT_pixel_transform_color_table */ - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_EXT_point_parameters */ - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); -#endif -#endif /* GL_EXT_polygon_offset */ - -#ifndef GL_EXT_polygon_offset_clamp -#define GL_EXT_polygon_offset_clamp 1 -#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B -typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp); -#endif -#endif /* GL_EXT_polygon_offset_clamp */ - -#ifndef GL_EXT_post_depth_coverage -#define GL_EXT_post_depth_coverage 1 -#endif /* GL_EXT_post_depth_coverage */ - -#ifndef GL_EXT_provoking_vertex -#define GL_EXT_provoking_vertex 1 -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_PROVOKING_VERTEX_EXT 0x8E4F -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); -#endif -#endif /* GL_EXT_provoking_vertex */ - -#ifndef GL_EXT_raster_multisample -#define GL_EXT_raster_multisample 1 -#define GL_RASTER_MULTISAMPLE_EXT 0x9327 -#define GL_RASTER_SAMPLES_EXT 0x9328 -#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 -#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A -#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B -#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C -typedef void (APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations); -#endif -#endif /* GL_EXT_raster_multisample */ - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 -#define GL_RESCALE_NORMAL_EXT 0x803A -#endif /* GL_EXT_rescale_normal */ - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_secondary_color */ - -#ifndef GL_EXT_separate_shader_objects -#define GL_EXT_separate_shader_objects 1 -#define GL_ACTIVE_PROGRAM_EXT 0x8B8D -typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); -typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); -GLAPI void APIENTRY glActiveProgramEXT (GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); -#endif -#endif /* GL_EXT_separate_shader_objects */ - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif /* GL_EXT_separate_specular_color */ - -#ifndef GL_EXT_shader_image_load_formatted -#define GL_EXT_shader_image_load_formatted 1 -#endif /* GL_EXT_shader_image_load_formatted */ - -#ifndef GL_EXT_shader_image_load_store -#define GL_EXT_shader_image_load_store 1 -#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 -#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A -#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B -#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C -#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D -#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E -#define GL_IMAGE_1D_EXT 0x904C -#define GL_IMAGE_2D_EXT 0x904D -#define GL_IMAGE_3D_EXT 0x904E -#define GL_IMAGE_2D_RECT_EXT 0x904F -#define GL_IMAGE_CUBE_EXT 0x9050 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_IMAGE_1D_ARRAY_EXT 0x9052 -#define GL_IMAGE_2D_ARRAY_EXT 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 -#define GL_INT_IMAGE_1D_EXT 0x9057 -#define GL_INT_IMAGE_2D_EXT 0x9058 -#define GL_INT_IMAGE_3D_EXT 0x9059 -#define GL_INT_IMAGE_2D_RECT_EXT 0x905A -#define GL_INT_IMAGE_CUBE_EXT 0x905B -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D -#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C -#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D -#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 -#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 -#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); -#endif -#endif /* GL_EXT_shader_image_load_store */ - -#ifndef GL_EXT_shader_integer_mix -#define GL_EXT_shader_integer_mix 1 -#endif /* GL_EXT_shader_integer_mix */ - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 -#endif /* GL_EXT_shadow_funcs */ - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#endif /* GL_EXT_shared_texture_palette */ - -#ifndef GL_EXT_sparse_texture2 -#define GL_EXT_sparse_texture2 1 -#endif /* GL_EXT_sparse_texture2 */ - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif -#endif /* GL_EXT_stencil_clear_tag */ - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); -#endif -#endif /* GL_EXT_stencil_two_side */ - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 -#endif /* GL_EXT_stencil_wrap */ - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_EXT_subtexture */ - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#endif /* GL_EXT_texture */ - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_EXT_texture3D */ - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif -#endif /* GL_EXT_texture_array */ - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); -#endif -#endif /* GL_EXT_texture_buffer_object */ - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#endif /* GL_EXT_texture_compression_latc */ - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#endif /* GL_EXT_texture_compression_rgtc */ - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_EXT_texture_compression_s3tc 1 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif /* GL_EXT_texture_compression_s3tc */ - -#ifndef GL_EXT_texture_cube_map -#define GL_EXT_texture_cube_map 1 -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif /* GL_EXT_texture_cube_map */ - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 -#endif /* GL_EXT_texture_env_add */ - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A -#endif /* GL_EXT_texture_env_combine */ - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 -#endif /* GL_EXT_texture_env_dot3 */ - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif /* GL_EXT_texture_filter_anisotropic */ - -#ifndef GL_EXT_texture_filter_minmax -#define GL_EXT_texture_filter_minmax 1 -#endif /* GL_EXT_texture_filter_minmax */ - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); -GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif -#endif /* GL_EXT_texture_integer */ - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#endif /* GL_EXT_texture_lod_bias */ - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#endif /* GL_EXT_texture_mirror_clamp */ - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); -typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); -GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); -GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); -GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); -GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif -#endif /* GL_EXT_texture_object */ - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF -typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); -#endif -#endif /* GL_EXT_texture_perturb_normal */ - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#endif /* GL_EXT_texture_sRGB */ - -#ifndef GL_EXT_texture_sRGB_decode -#define GL_EXT_texture_sRGB_decode 1 -#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define GL_DECODE_EXT 0x8A49 -#define GL_SKIP_DECODE_EXT 0x8A4A -#endif /* GL_EXT_texture_sRGB_decode */ - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#endif /* GL_EXT_texture_shared_exponent */ - -#ifndef GL_EXT_texture_snorm -#define GL_EXT_texture_snorm 1 -#define GL_ALPHA_SNORM 0x9010 -#define GL_LUMINANCE_SNORM 0x9011 -#define GL_LUMINANCE_ALPHA_SNORM 0x9012 -#define GL_INTENSITY_SNORM 0x9013 -#define GL_ALPHA8_SNORM 0x9014 -#define GL_LUMINANCE8_SNORM 0x9015 -#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 -#define GL_INTENSITY8_SNORM 0x9017 -#define GL_ALPHA16_SNORM 0x9018 -#define GL_LUMINANCE16_SNORM 0x9019 -#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A -#define GL_INTENSITY16_SNORM 0x901B -#define GL_RED_SNORM 0x8F90 -#define GL_RG_SNORM 0x8F91 -#define GL_RGB_SNORM 0x8F92 -#define GL_RGBA_SNORM 0x8F93 -#endif /* GL_EXT_texture_snorm */ - -#ifndef GL_EXT_texture_swizzle -#define GL_EXT_texture_swizzle 1 -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 -#endif /* GL_EXT_texture_swizzle */ - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 -#define GL_TIME_ELAPSED_EXT 0x88BF -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); -#endif -#endif /* GL_EXT_timer_query */ - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackEXT (void); -GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#endif -#endif /* GL_EXT_transform_feedback */ - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); -typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, void **params); -typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glArrayElementEXT (GLint i); -GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); -GLAPI void APIENTRY glGetPointervEXT (GLenum pname, void **params); -GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -#endif -#endif /* GL_EXT_vertex_array */ - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 -#endif /* GL_EXT_vertex_array_bgra */ - -#ifndef GL_EXT_vertex_attrib_64bit -#define GL_EXT_vertex_attrib_64bit 1 -#define GL_DOUBLE_VEC2_EXT 0x8FFC -#define GL_DOUBLE_VEC3_EXT 0x8FFD -#define GL_DOUBLE_VEC4_EXT 0x8FFE -#define GL_DOUBLE_MAT2_EXT 0x8F46 -#define GL_DOUBLE_MAT3_EXT 0x8F47 -#define GL_DOUBLE_MAT4_EXT 0x8F48 -#define GL_DOUBLE_MAT2x3_EXT 0x8F49 -#define GL_DOUBLE_MAT2x4_EXT 0x8F4A -#define GL_DOUBLE_MAT3x2_EXT 0x8F4B -#define GL_DOUBLE_MAT3x4_EXT 0x8F4C -#define GL_DOUBLE_MAT4x2_EXT 0x8F4D -#define GL_DOUBLE_MAT4x3_EXT 0x8F4E -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); -#endif -#endif /* GL_EXT_vertex_attrib_64bit */ - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const void *addr); -typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const void *addr); -typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); -typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); -typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); -typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); -typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); -typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); -typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); -typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); -typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const void *addr); -typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); -typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVertexShaderEXT (void); -GLAPI void APIENTRY glEndVertexShaderEXT (void); -GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); -GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); -GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); -GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); -GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const void *addr); -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const void *addr); -GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); -GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); -GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); -GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); -GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); -GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); -GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); -GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); -GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const void *addr); -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); -GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); -GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); -GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); -GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); -GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); -GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); -GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, void **data); -GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -#endif -#endif /* GL_EXT_vertex_shader */ - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 -#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW0_EXT 0x1700 -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); -GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_vertex_weighting */ - -#ifndef GL_EXT_x11_sync_object -#define GL_EXT_x11_sync_object 1 -#define GL_SYNC_X11_FENCE_EXT 0x90E1 -typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); -#endif -#endif /* GL_EXT_x11_sync_object */ - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 -typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); -#endif -#endif /* GL_GREMEDY_frame_terminator */ - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 -typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const void *string); -#endif -#endif /* GL_GREMEDY_string_marker */ - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#endif /* GL_HP_convolution_border_modes */ - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_CUBIC_HP 0x815F -#define GL_AVERAGE_HP 0x8160 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_HP_image_transform */ - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#endif /* GL_HP_occlusion_test */ - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#endif /* GL_HP_texture_lighting */ - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 -#define GL_CULL_VERTEX_IBM 103050 -#endif /* GL_IBM_cull_vertex */ - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 -typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); -#endif -#endif /* GL_IBM_multimode_draw_arrays */ - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#endif /* GL_IBM_rasterpos_clip */ - -#ifndef GL_IBM_static_data -#define GL_IBM_static_data 1 -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 -typedef void (APIENTRYP PFNGLFLUSHSTATICDATAIBMPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushStaticDataIBM (GLenum target); -#endif -#endif /* GL_IBM_static_data */ - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_IBM_texture_mirrored_repeat 1 -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif /* GL_IBM_texture_mirrored_repeat */ - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean **pointer, GLint ptrstride); -GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -#endif -#endif /* GL_IBM_vertex_array_lists */ - -#ifndef GL_INGR_blend_func_separate -#define GL_INGR_blend_func_separate 1 -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif -#endif /* GL_INGR_blend_func_separate */ - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#endif /* GL_INGR_color_clamp */ - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 -#define GL_INTERLACE_READ_INGR 0x8568 -#endif /* GL_INGR_interlace_read */ - -#ifndef GL_INTEL_fragment_shader_ordering -#define GL_INTEL_fragment_shader_ordering 1 -#endif /* GL_INTEL_fragment_shader_ordering */ - -#ifndef GL_INTEL_map_texture -#define GL_INTEL_map_texture 1 -#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF -#define GL_LAYOUT_DEFAULT_INTEL 0 -#define GL_LAYOUT_LINEAR_INTEL 1 -#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 -typedef void (APIENTRYP PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); -typedef void *(APIENTRYP PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSyncTextureINTEL (GLuint texture); -GLAPI void APIENTRY glUnmapTexture2DINTEL (GLuint texture, GLint level); -GLAPI void *APIENTRY glMapTexture2DINTEL (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); -#endif -#endif /* GL_INTEL_map_texture */ - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const void **pointer); -GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const void **pointer); -GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const void **pointer); -GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const void **pointer); -#endif -#endif /* GL_INTEL_parallel_arrays */ - -#ifndef GL_INTEL_performance_query -#define GL_INTEL_performance_query 1 -#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 -#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 -#define GL_PERFQUERY_WAIT_INTEL 0x83FB -#define GL_PERFQUERY_FLUSH_INTEL 0x83FA -#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 -#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 -#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 -#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 -#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 -#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 -#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 -#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 -#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 -#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA -#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB -#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC -#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD -#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE -#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF -#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 -typedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); -typedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); -typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); -typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); -typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); -typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); -GLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); -GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); -GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); -GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); -GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); -#endif -#endif /* GL_INTEL_performance_query */ - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#endif /* GL_MESAX_texture_stack */ - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 -#define GL_PACK_INVERT_MESA 0x8758 -#endif /* GL_MESA_pack_invert */ - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 -typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glResizeBuffersMESA (void); -#endif -#endif /* GL_MESA_resize_buffers */ - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 -typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); -#endif -#endif /* GL_MESA_window_pos */ - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 -#endif /* GL_MESA_ycbcr_texture */ - -#ifndef GL_NVX_conditional_render -#define GL_NVX_conditional_render 1 -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNVX (GLuint id); -GLAPI void APIENTRY glEndConditionalRenderNVX (void); -#endif -#endif /* GL_NVX_conditional_render */ - -#ifndef GL_NVX_gpu_memory_info -#define GL_NVX_gpu_memory_info 1 -#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 -#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 -#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 -#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A -#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B -#endif /* GL_NVX_gpu_memory_info */ - -#ifndef GL_NV_bindless_multi_draw_indirect -#define GL_NV_bindless_multi_draw_indirect 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -#endif -#endif /* GL_NV_bindless_multi_draw_indirect */ - -#ifndef GL_NV_bindless_multi_draw_indirect_count -#define GL_NV_bindless_multi_draw_indirect_count 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#endif -#endif /* GL_NV_bindless_multi_draw_indirect_count */ - -#ifndef GL_NV_bindless_texture -#define GL_NV_bindless_texture 1 -typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); -typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); -GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); -GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); -GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); -GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); -GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); -GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); -GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); -GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); -GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); -#endif -#endif /* GL_NV_bindless_texture */ - -#ifndef GL_NV_blend_equation_advanced -#define GL_NV_blend_equation_advanced 1 -#define GL_BLEND_OVERLAP_NV 0x9281 -#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 -#define GL_BLUE_NV 0x1905 -#define GL_COLORBURN_NV 0x929A -#define GL_COLORDODGE_NV 0x9299 -#define GL_CONJOINT_NV 0x9284 -#define GL_CONTRAST_NV 0x92A1 -#define GL_DARKEN_NV 0x9297 -#define GL_DIFFERENCE_NV 0x929E -#define GL_DISJOINT_NV 0x9283 -#define GL_DST_ATOP_NV 0x928F -#define GL_DST_IN_NV 0x928B -#define GL_DST_NV 0x9287 -#define GL_DST_OUT_NV 0x928D -#define GL_DST_OVER_NV 0x9289 -#define GL_EXCLUSION_NV 0x92A0 -#define GL_GREEN_NV 0x1904 -#define GL_HARDLIGHT_NV 0x929B -#define GL_HARDMIX_NV 0x92A9 -#define GL_HSL_COLOR_NV 0x92AF -#define GL_HSL_HUE_NV 0x92AD -#define GL_HSL_LUMINOSITY_NV 0x92B0 -#define GL_HSL_SATURATION_NV 0x92AE -#define GL_INVERT_OVG_NV 0x92B4 -#define GL_INVERT_RGB_NV 0x92A3 -#define GL_LIGHTEN_NV 0x9298 -#define GL_LINEARBURN_NV 0x92A5 -#define GL_LINEARDODGE_NV 0x92A4 -#define GL_LINEARLIGHT_NV 0x92A7 -#define GL_MINUS_CLAMPED_NV 0x92B3 -#define GL_MINUS_NV 0x929F -#define GL_MULTIPLY_NV 0x9294 -#define GL_OVERLAY_NV 0x9296 -#define GL_PINLIGHT_NV 0x92A8 -#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 -#define GL_PLUS_CLAMPED_NV 0x92B1 -#define GL_PLUS_DARKER_NV 0x9292 -#define GL_PLUS_NV 0x9291 -#define GL_RED_NV 0x1903 -#define GL_SCREEN_NV 0x9295 -#define GL_SOFTLIGHT_NV 0x929C -#define GL_SRC_ATOP_NV 0x928E -#define GL_SRC_IN_NV 0x928A -#define GL_SRC_NV 0x9286 -#define GL_SRC_OUT_NV 0x928C -#define GL_SRC_OVER_NV 0x9288 -#define GL_UNCORRELATED_NV 0x9282 -#define GL_VIVIDLIGHT_NV 0x92A6 -#define GL_XOR_NV 0x1506 -typedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value); -GLAPI void APIENTRY glBlendBarrierNV (void); -#endif -#endif /* GL_NV_blend_equation_advanced */ - -#ifndef GL_NV_blend_equation_advanced_coherent -#define GL_NV_blend_equation_advanced_coherent 1 -#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 -#endif /* GL_NV_blend_equation_advanced_coherent */ - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 -#endif /* GL_NV_blend_square */ - -#ifndef GL_NV_command_list -#define GL_NV_command_list 1 -#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 -#define GL_NOP_COMMAND_NV 0x0001 -#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 -#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 -#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 -#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 -#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 -#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 -#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 -#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 -#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A -#define GL_BLEND_COLOR_COMMAND_NV 0x000B -#define GL_STENCIL_REF_COMMAND_NV 0x000C -#define GL_LINE_WIDTH_COMMAND_NV 0x000D -#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E -#define GL_ALPHA_REF_COMMAND_NV 0x000F -#define GL_VIEWPORT_COMMAND_NV 0x0010 -#define GL_SCISSOR_COMMAND_NV 0x0011 -#define GL_FRONT_FACE_COMMAND_NV 0x0012 -typedef void (APIENTRYP PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint *states); -typedef void (APIENTRYP PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint *states); -typedef GLboolean (APIENTRYP PFNGLISSTATENVPROC) (GLuint state); -typedef void (APIENTRYP PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode); -typedef GLuint (APIENTRYP PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size); -typedef GLushort (APIENTRYP PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint *lists); -typedef void (APIENTRYP PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint *lists); -typedef GLboolean (APIENTRYP PFNGLISCOMMANDLISTNVPROC) (GLuint list); -typedef void (APIENTRYP PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void **indirects, const size_t *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments); -typedef void (APIENTRYP PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list); -typedef void (APIENTRYP PFNGLCALLCOMMANDLISTNVPROC) (GLuint list); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCreateStatesNV (GLsizei n, GLuint *states); -GLAPI void APIENTRY glDeleteStatesNV (GLsizei n, const GLuint *states); -GLAPI GLboolean APIENTRY glIsStateNV (GLuint state); -GLAPI void APIENTRY glStateCaptureNV (GLuint state, GLenum mode); -GLAPI GLuint APIENTRY glGetCommandHeaderNV (GLenum tokenID, GLuint size); -GLAPI GLushort APIENTRY glGetStageIndexNV (GLenum shadertype); -GLAPI void APIENTRY glDrawCommandsNV (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); -GLAPI void APIENTRY glDrawCommandsAddressNV (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); -GLAPI void APIENTRY glDrawCommandsStatesNV (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glDrawCommandsStatesAddressNV (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glCreateCommandListsNV (GLsizei n, GLuint *lists); -GLAPI void APIENTRY glDeleteCommandListsNV (GLsizei n, const GLuint *lists); -GLAPI GLboolean APIENTRY glIsCommandListNV (GLuint list); -GLAPI void APIENTRY glListDrawCommandsStatesClientNV (GLuint list, GLuint segment, const void **indirects, const size_t *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glCommandListSegmentsNV (GLuint list, GLuint segments); -GLAPI void APIENTRY glCompileCommandListNV (GLuint list); -GLAPI void APIENTRY glCallCommandListNV (GLuint list); -#endif -#endif /* GL_NV_command_list */ - -#ifndef GL_NV_compute_program5 -#define GL_NV_compute_program5 1 -#define GL_COMPUTE_PROGRAM_NV 0x90FB -#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC -#endif /* GL_NV_compute_program5 */ - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRenderNV (void); -#endif -#endif /* GL_NV_conditional_render */ - -#ifndef GL_NV_conservative_raster -#define GL_NV_conservative_raster 1 -#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 -#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 -#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 -#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 -typedef void (APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits); -#endif -#endif /* GL_NV_conservative_raster */ - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#endif /* GL_NV_copy_depth_to_color */ - -#ifndef GL_NV_copy_image -#define GL_NV_copy_image 1 -typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* GL_NV_copy_image */ - -#ifndef GL_NV_deep_texture3D -#define GL_NV_deep_texture3D 1 -#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 -#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 -#endif /* GL_NV_deep_texture3D */ - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); -GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); -#endif -#endif /* GL_NV_depth_buffer_float */ - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 -#define GL_DEPTH_CLAMP_NV 0x864F -#endif /* GL_NV_depth_clamp */ - -#ifndef GL_NV_draw_texture -#define GL_NV_draw_texture 1 -typedef void (APIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); -#endif -#endif /* GL_NV_draw_texture */ - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); -typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); -GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); -GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); -#endif -#endif /* GL_NV_evaluators */ - -#ifndef GL_NV_explicit_multisample -#define GL_NV_explicit_multisample 1 -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); -typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); -GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); -#endif -#endif /* GL_NV_explicit_multisample */ - -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); -GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); -GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); -GLAPI void APIENTRY glFinishFenceNV (GLuint fence); -GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); -#endif -#endif /* GL_NV_fence */ - -#ifndef GL_NV_fill_rectangle -#define GL_NV_fill_rectangle 1 -#define GL_FILL_RECTANGLE_NV 0x933C -#endif /* GL_NV_fill_rectangle */ - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#endif /* GL_NV_float_buffer */ - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -#endif /* GL_NV_fog_distance */ - -#ifndef GL_NV_fragment_coverage_to_color -#define GL_NV_fragment_coverage_to_color 1 -#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD -#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE -typedef void (APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentCoverageColorNV (GLuint color); -#endif -#endif /* GL_NV_fragment_coverage_to_color */ - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif -#endif /* GL_NV_fragment_program */ - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#endif /* GL_NV_fragment_program2 */ - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 -#endif /* GL_NV_fragment_program4 */ - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 -#endif /* GL_NV_fragment_program_option */ - -#ifndef GL_NV_fragment_shader_interlock -#define GL_NV_fragment_shader_interlock 1 -#endif /* GL_NV_fragment_shader_interlock */ - -#ifndef GL_NV_framebuffer_mixed_samples -#define GL_NV_framebuffer_mixed_samples 1 -#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 -#define GL_COLOR_SAMPLES_NV 0x8E20 -#define GL_DEPTH_SAMPLES_NV 0x932D -#define GL_STENCIL_SAMPLES_NV 0x932E -#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F -#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 -#define GL_COVERAGE_MODULATION_NV 0x9332 -#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 -typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); -typedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v); -typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); -GLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v); -GLAPI void APIENTRY glCoverageModulationNV (GLenum components); -#endif -#endif /* GL_NV_framebuffer_mixed_samples */ - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -#endif /* GL_NV_framebuffer_multisample_coverage */ - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); -GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif -#endif /* GL_NV_geometry_program4 */ - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 -#endif /* GL_NV_geometry_shader4 */ - -#ifndef GL_NV_geometry_shader_passthrough -#define GL_NV_geometry_shader_passthrough 1 -#endif /* GL_NV_geometry_shader_passthrough */ - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); -#endif -#endif /* GL_NV_gpu_program4 */ - -#ifndef GL_NV_gpu_program5 -#define GL_NV_gpu_program5 1 -#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C -#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F -#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 -#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 -typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); -#endif -#endif /* GL_NV_gpu_program5 */ - -#ifndef GL_NV_gpu_program5_mem_extended -#define GL_NV_gpu_program5_mem_extended 1 -#endif /* GL_NV_gpu_program5_mem_extended */ - -#ifndef GL_NV_gpu_shader5 -#define GL_NV_gpu_shader5 1 -#endif /* GL_NV_gpu_shader5 */ - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 -typedef unsigned short GLhalfNV; -#define GL_HALF_FLOAT_NV 0x140B -typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); -typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); -GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); -GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); -GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); -GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -#endif -#endif /* GL_NV_half_float */ - -#ifndef GL_NV_internalformat_sample_query -#define GL_NV_internalformat_sample_query 1 -#define GL_MULTISAMPLES_NV 0x9371 -#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 -#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 -#define GL_CONFORMANT_NV 0x9374 -typedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); -#endif -#endif /* GL_NV_internalformat_sample_query */ - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#endif /* GL_NV_light_max_exponent */ - -#ifndef GL_NV_multisample_coverage -#define GL_NV_multisample_coverage 1 -#endif /* GL_NV_multisample_coverage */ - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#endif /* GL_NV_multisample_filter_hint */ - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glEndOcclusionQueryNV (void); -GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); -#endif -#endif /* GL_NV_occlusion_query */ - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#endif /* GL_NV_packed_depth_stencil */ - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); -#endif -#endif /* GL_NV_parameter_buffer_object */ - -#ifndef GL_NV_parameter_buffer_object2 -#define GL_NV_parameter_buffer_object2 1 -#endif /* GL_NV_parameter_buffer_object2 */ - -#ifndef GL_NV_path_rendering -#define GL_NV_path_rendering 1 -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_CLOSE_PATH_NV 0x00 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_BOLD_BIT_NV 0x01 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_2_BYTES_NV 0x1407 -#define GL_3_BYTES_NV 0x1408 -#define GL_4_BYTES_NV 0x1409 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_CONSTANT_NV 0x8576 -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_FRAGMENT_INPUT_NV 0x936D -typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); -typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); -typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); -typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); -typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); -typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); -typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); -typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); -typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); -typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); -typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); -typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); -typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); -typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); -typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); -typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); -typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); -typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); -typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); -GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); -GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); -GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); -GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); -GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); -GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); -GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); -GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); -GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); -GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); -GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); -GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); -GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); -GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); -GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); -GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); -GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); -GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); -GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); -GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); -GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); -GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); -GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); -GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); -GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); -GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -GLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); -GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); -GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); -#endif -#endif /* GL_NV_path_rendering */ - -#ifndef GL_NV_path_rendering_shared_edge -#define GL_NV_path_rendering_shared_edge 1 -#define GL_SHARED_EDGE_NV 0xC0 -#endif /* GL_NV_path_rendering_shared_edge */ - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const void *pointer); -GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); -#endif -#endif /* GL_NV_pixel_data_range */ - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); -#endif -#endif /* GL_NV_point_sprite */ - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B -typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#endif -#endif /* GL_NV_present_video */ - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveRestartNV (void); -GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); -#endif -#endif /* GL_NV_primitive_restart */ - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); -GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); -GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); -#endif -#endif /* GL_NV_register_combiners */ - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); -#endif -#endif /* GL_NV_register_combiners2 */ - -#ifndef GL_NV_sample_locations -#define GL_NV_sample_locations 1 -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 -#define GL_SAMPLE_LOCATION_NV 0x8E50 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 -typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glResolveDepthValuesNV (void); -#endif -#endif /* GL_NV_sample_locations */ - -#ifndef GL_NV_sample_mask_override_coverage -#define GL_NV_sample_mask_override_coverage 1 -#endif /* GL_NV_sample_mask_override_coverage */ - -#ifndef GL_NV_shader_atomic_counters -#define GL_NV_shader_atomic_counters 1 -#endif /* GL_NV_shader_atomic_counters */ - -#ifndef GL_NV_shader_atomic_float -#define GL_NV_shader_atomic_float 1 -#endif /* GL_NV_shader_atomic_float */ - -#ifndef GL_NV_shader_atomic_fp16_vector -#define GL_NV_shader_atomic_fp16_vector 1 -#endif /* GL_NV_shader_atomic_fp16_vector */ - -#ifndef GL_NV_shader_atomic_int64 -#define GL_NV_shader_atomic_int64 1 -#endif /* GL_NV_shader_atomic_int64 */ - -#ifndef GL_NV_shader_buffer_load -#define GL_NV_shader_buffer_load 1 -#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D -#define GL_GPU_ADDRESS_NV 0x8F34 -#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 -typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); -typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); -typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); -typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); -typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); -GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); -GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); -GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); -GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); -GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); -GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); -GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); -GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); -GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif -#endif /* GL_NV_shader_buffer_load */ - -#ifndef GL_NV_shader_buffer_store -#define GL_NV_shader_buffer_store 1 -#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 -#endif /* GL_NV_shader_buffer_store */ - -#ifndef GL_NV_shader_storage_buffer_object -#define GL_NV_shader_storage_buffer_object 1 -#endif /* GL_NV_shader_storage_buffer_object */ - -#ifndef GL_NV_shader_thread_group -#define GL_NV_shader_thread_group 1 -#define GL_WARP_SIZE_NV 0x9339 -#define GL_WARPS_PER_SM_NV 0x933A -#define GL_SM_COUNT_NV 0x933B -#endif /* GL_NV_shader_thread_group */ - -#ifndef GL_NV_shader_thread_shuffle -#define GL_NV_shader_thread_shuffle 1 -#endif /* GL_NV_shader_thread_shuffle */ - -#ifndef GL_NV_tessellation_program5 -#define GL_NV_tessellation_program5 1 -#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 -#define GL_TESS_CONTROL_PROGRAM_NV 0x891E -#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F -#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 -#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 -#endif /* GL_NV_tessellation_program5 */ - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F -#endif /* GL_NV_texgen_emboss */ - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 -#endif /* GL_NV_texgen_reflection */ - -#ifndef GL_NV_texture_barrier -#define GL_NV_texture_barrier 1 -typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureBarrierNV (void); -#endif -#endif /* GL_NV_texture_barrier */ - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 -#endif /* GL_NV_texture_compression_vtc */ - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B -#endif /* GL_NV_texture_env_combine4 */ - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#endif /* GL_NV_texture_expand_normal */ - -#ifndef GL_NV_texture_multisample -#define GL_NV_texture_multisample 1 -#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 -#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#endif -#endif /* GL_NV_texture_multisample */ - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#endif /* GL_NV_texture_rectangle */ - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#endif /* GL_NV_texture_shader */ - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#endif /* GL_NV_texture_shader2 */ - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#endif /* GL_NV_texture_shader3 */ - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#define GL_LAYER_NV 0x8DAA -#define GL_NEXT_BUFFER_NV -2 -#define GL_SKIP_COMPONENTS4_NV -3 -#define GL_SKIP_COMPONENTS3_NV -4 -#define GL_SKIP_COMPONENTS2_NV -5 -#define GL_SKIP_COMPONENTS1_NV -6 -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLenum bufferMode); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLsizei count, const GLint *attribs, GLenum bufferMode); -GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); -GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); -GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#endif -#endif /* GL_NV_transform_feedback */ - -#ifndef GL_NV_transform_feedback2 -#define GL_NV_transform_feedback2 1 -#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedbackNV (void); -GLAPI void APIENTRY glResumeTransformFeedbackNV (void); -GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); -#endif -#endif /* GL_NV_transform_feedback2 */ - -#ifndef GL_NV_uniform_buffer_unified_memory -#define GL_NV_uniform_buffer_unified_memory 1 -#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E -#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F -#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 -#endif /* GL_NV_uniform_buffer_unified_memory */ - -#ifndef GL_NV_vdpau_interop -#define GL_NV_vdpau_interop 1 -typedef GLintptr GLvdpauSurfaceNV; -#define GL_SURFACE_STATE_NV 0x86EB -#define GL_SURFACE_REGISTERED_NV 0x86FD -#define GL_SURFACE_MAPPED_NV 0x8700 -#define GL_WRITE_DISCARD_NV 0x88BE -typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const void *vdpDevice, const void *getProcAddress); -typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); -typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVDPAUInitNV (const void *vdpDevice, const void *getProcAddress); -GLAPI void APIENTRY glVDPAUFiniNV (void); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); -GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#endif -#endif /* GL_NV_vdpau_interop */ - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); -GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const void *pointer); -#endif -#endif /* GL_NV_vertex_array_range */ - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#endif /* GL_NV_vertex_array_range2 */ - -#ifndef GL_NV_vertex_attrib_integer_64bit -#define GL_NV_vertex_attrib_integer_64bit 1 -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); -GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); -GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -#endif -#endif /* GL_NV_vertex_attrib_integer_64bit */ - -#ifndef GL_NV_vertex_buffer_unified_memory -#define GL_NV_vertex_buffer_unified_memory 1 -#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E -#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F -#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 -#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 -#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 -#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 -#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 -#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 -#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 -#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 -#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 -#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 -#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A -#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B -#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C -#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D -#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E -#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F -#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 -#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 -#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 -#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 -#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 -#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 -#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 -typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); -GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); -#endif -#endif /* GL_NV_vertex_buffer_unified_memory */ - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); -typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); -typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void **pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); -GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); -GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); -GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, void **pointer); -GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); -GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); -GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); -GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); -GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); -#endif -#endif /* GL_NV_vertex_program */ - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 -#endif /* GL_NV_vertex_program1_1 */ - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 -#endif /* GL_NV_vertex_program2 */ - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 -#endif /* GL_NV_vertex_program2_option */ - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 -#endif /* GL_NV_vertex_program3 */ - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); -#endif -#endif /* GL_NV_vertex_program4 */ - -#ifndef GL_NV_video_capture -#define GL_NV_video_capture 1 -#define GL_VIDEO_BUFFER_NV 0x9020 -#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 -#define GL_FIELD_UPPER_NV 0x9022 -#define GL_FIELD_LOWER_NV 0x9023 -#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 -#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 -#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 -#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 -#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 -#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 -#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A -#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B -#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C -#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D -#define GL_PARTIAL_SUCCESS_NV 0x902E -#define GL_SUCCESS_NV 0x902F -#define GL_FAILURE_NV 0x9030 -#define GL_YCBYCR8_422_NV 0x9031 -#define GL_YCBAYCR8A_4224_NV 0x9032 -#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 -#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 -#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 -#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 -#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 -#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 -#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 -#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A -#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B -#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C -typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#endif -#endif /* GL_NV_video_capture */ - -#ifndef GL_NV_viewport_array2 -#define GL_NV_viewport_array2 1 -#endif /* GL_NV_viewport_array2 */ - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 -#endif /* GL_OML_interlace */ - -#ifndef GL_OML_resample -#define GL_OML_resample 1 -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#endif /* GL_OML_resample */ - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#endif /* GL_OML_subsample */ - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); -#endif -#endif /* GL_PGI_misc_hints */ - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#endif /* GL_PGI_vertex_hints */ - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#endif /* GL_REND_screen_coordinates */ - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#define GL_RGBA_DXT5_S3TC 0x83A4 -#define GL_RGBA4_DXT5_S3TC 0x83A5 -#endif /* GL_S3_s3tc */ - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); -#endif -#endif /* GL_SGIS_detail_texture */ - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); -#endif -#endif /* GL_SGIS_fog_function */ - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif /* GL_SGIS_generate_mipmap */ - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); -#endif -#endif /* GL_SGIS_multisample */ - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); -GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); -#endif -#endif /* GL_SGIS_pixel_texture */ - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#endif /* GL_SGIS_point_line_texgen */ - -#ifndef GL_SGIS_point_parameters -#define GL_SGIS_point_parameters 1 -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_SGIS_point_parameters */ - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); -#endif -#endif /* GL_SGIS_sharpen_texture */ - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_SGIS_texture4D */ - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#endif /* GL_SGIS_texture_border_clamp */ - -#ifndef GL_SGIS_texture_color_mask -#define GL_SGIS_texture_color_mask 1 -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif -#endif /* GL_SGIS_texture_color_mask */ - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#endif /* GL_SGIS_texture_edge_clamp */ - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 -#define GL_FILTER4_SGIS 0x8146 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); -typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); -GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif -#endif /* GL_SGIS_texture_filter4 */ - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#endif /* GL_SGIS_texture_lod */ - -#ifndef GL_SGIS_texture_select -#define GL_SGIS_texture_select 1 -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#endif /* GL_SGIS_texture_select */ - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 -#define GL_ASYNC_MARKER_SGIX 0x8329 -typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); -typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); -typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); -GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); -GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); -GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); -GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); -GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); -#endif -#endif /* GL_SGIX_async */ - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#endif /* GL_SGIX_async_histogram */ - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#endif /* GL_SGIX_async_pixel */ - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 -#endif /* GL_SGIX_blend_alpha_minmax */ - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#endif /* GL_SGIX_calligraphic_fragment */ - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#endif /* GL_SGIX_clipmap */ - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#endif /* GL_SGIX_convolution_accuracy */ - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 -#endif /* GL_SGIX_depth_pass_instrument */ - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#endif /* GL_SGIX_depth_texture */ - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 -typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushRasterSGIX (void); -#endif -#endif /* GL_SGIX_flush_raster */ - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#endif /* GL_SGIX_fog_offset */ - -#ifndef GL_SGIX_fragment_lighting -#define GL_SGIX_fragment_lighting 1 -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); -GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); -GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); -#endif -#endif /* GL_SGIX_fragment_lighting */ - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); -#endif -#endif /* GL_SGIX_framezoom */ - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 -typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const void *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const void *params); -#endif -#endif /* GL_SGIX_igloo_interface */ - -#ifndef GL_SGIX_instruments -#define GL_SGIX_instruments 1 -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); -typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); -typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); -typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); -GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); -GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); -GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); -GLAPI void APIENTRY glStartInstrumentsSGIX (void); -GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); -#endif -#endif /* GL_SGIX_instruments */ - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 -#define GL_INTERLACE_SGIX 0x8094 -#endif /* GL_SGIX_interlace */ - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#endif /* GL_SGIX_ir_instrument1 */ - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 -#define GL_LIST_PRIORITY_SGIX 0x8182 -typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); -GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); -GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); -GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); -#endif -#endif /* GL_SGIX_list_priority */ - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); -#endif -#endif /* GL_SGIX_pixel_texture */ - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#endif /* GL_SGIX_pixel_tiles */ - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); -GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); -#endif -#endif /* GL_SGIX_polynomial_ffd */ - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); -#endif -#endif /* GL_SGIX_reference_plane */ - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 -#define GL_PACK_RESAMPLE_SGIX 0x842E -#define GL_UNPACK_RESAMPLE_SGIX 0x842F -#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#endif /* GL_SGIX_resample */ - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#endif /* GL_SGIX_scalebias_hint */ - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#endif /* GL_SGIX_shadow */ - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#endif /* GL_SGIX_shadow_ambient */ - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); -#endif -#endif /* GL_SGIX_sprite */ - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#endif /* GL_SGIX_subsample */ - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 -typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTagSampleBufferSGIX (void); -#endif -#endif /* GL_SGIX_tag_sample_buffer */ - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#endif /* GL_SGIX_texture_add_env */ - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#endif /* GL_SGIX_texture_coordinate_clamp */ - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#endif /* GL_SGIX_texture_lod_bias */ - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#endif /* GL_SGIX_texture_multi_buffer */ - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#endif /* GL_SGIX_texture_scale_bias */ - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#endif /* GL_SGIX_vertex_preclip */ - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#endif /* GL_SGIX_ycrcb */ - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 -#endif /* GL_SGIX_ycrcb_subsample */ - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 -#endif /* GL_SGIX_ycrcba */ - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#endif /* GL_SGI_color_matrix */ - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, void *table); -GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); -#endif -#endif /* GL_SGI_color_table */ - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#endif /* GL_SGI_texture_color_table */ - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFinishTextureSUNX (void); -#endif -#endif /* GL_SUNX_constant_data */ - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 -#define GL_WRAP_BORDER_SUN 0x81D4 -#endif /* GL_SUN_convolution_border_modes */ - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); -GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); -GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); -GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); -GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); -GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); -#endif -#endif /* GL_SUN_global_alpha */ - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 -typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif -#endif /* GL_SUN_mesh_array */ - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 -#define GL_SLICE_ACCUM_SUN 0x85CC -#endif /* GL_SUN_slice_accum */ - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 -#define GL_RESTART_SUN 0x0001 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); -GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); -GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); -GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); -GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); -GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); -GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const void **pointer); -#endif -#endif /* GL_SUN_triangle_list */ - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif -#endif /* GL_SUN_vertex */ - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB -#endif /* GL_WIN_phong_shading */ - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#endif /* GL_WIN_specular_fog */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Externals/gl/include/gl/wglext.h b/Externals/gl/include/gl/wglext.h deleted file mode 100644 index fc956612163..00000000000 --- a/Externals/gl/include/gl/wglext.h +++ /dev/null @@ -1,840 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2014 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 30082 $ on $Date: 2015-03-11 09:18:46 -0700 (Wed, 11 Mar 2015) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#define WGL_WGLEXT_VERSION 20150311 - -/* Generated C header for: - * API: wgl - * Versions considered: .* - * Versions emitted: _nomatch_^ - * Default extensions included: wgl - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#ifdef WGL_WGLEXT_PROTOTYPES -HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); -VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); -BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); -BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif -#endif /* WGL_ARB_buffer_region */ - -#ifndef WGL_ARB_context_flush_control -#define WGL_ARB_context_flush_control 1 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 -#endif /* WGL_ARB_context_flush_control */ - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define ERROR_INVALID_VERSION_ARB 0x2095 -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); -#ifdef WGL_WGLEXT_PROTOTYPES -HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); -#endif -#endif /* WGL_ARB_create_context */ - -#ifndef WGL_ARB_create_context_profile -#define WGL_ARB_create_context_profile 1 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#endif /* WGL_ARB_create_context_profile */ - -#ifndef WGL_ARB_create_context_robustness -#define WGL_ARB_create_context_robustness 1 -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif /* WGL_ARB_create_context_robustness */ - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringARB (HDC hdc); -#endif -#endif /* WGL_ARB_extensions_string */ - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 -#endif /* WGL_ARB_framebuffer_sRGB */ - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCARB (void); -#endif -#endif /* WGL_ARB_make_current_read */ - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif /* WGL_ARB_multisample */ - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -DECLARE_HANDLE(HPBUFFERARB); -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); -int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); -BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_ARB_pbuffer */ - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_ARB_pixel_format */ - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 -#endif /* WGL_ARB_pixel_format_float */ - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif -#endif /* WGL_ARB_render_texture */ - -#ifndef WGL_ARB_robustness_application_isolation -#define WGL_ARB_robustness_application_isolation 1 -#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 -#endif /* WGL_ARB_robustness_application_isolation */ - -#ifndef WGL_ARB_robustness_share_group_isolation -#define WGL_ARB_robustness_share_group_isolation 1 -#endif /* WGL_ARB_robustness_share_group_isolation */ - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif /* WGL_3DFX_multisample */ - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); -#endif -#endif /* WGL_3DL_stereo_control */ - -#ifndef WGL_AMD_gpu_association -#define WGL_AMD_gpu_association 1 -#define WGL_GPU_VENDOR_AMD 0x1F00 -#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 -#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define WGL_GPU_RAM_AMD 0x21A3 -#define WGL_GPU_CLOCK_AMD 0x21A4 -#define WGL_GPU_NUM_PIPES_AMD 0x21A5 -#define WGL_GPU_NUM_SIMD_AMD 0x21A6 -#define WGL_GPU_NUM_RB_AMD 0x21A7 -#define WGL_GPU_NUM_SPI_AMD 0x21A8 -typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); -typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); -typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); -typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); -typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#ifdef WGL_WGLEXT_PROTOTYPES -UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); -INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); -UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); -HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); -HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); -BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); -BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); -HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); -VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -#endif /* WGL_AMD_gpu_association */ - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#endif /* WGL_ATI_pixel_format_float */ - -#ifndef WGL_EXT_create_context_es2_profile -#define WGL_EXT_create_context_es2_profile 1 -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es2_profile */ - -#ifndef WGL_EXT_create_context_es_profile -#define WGL_EXT_create_context_es_profile 1 -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es_profile */ - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif /* WGL_EXT_depth_float */ - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#ifdef WGL_WGLEXT_PROTOTYPES -GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); -GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); -GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); -VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); -#endif -#endif /* WGL_EXT_display_color_table */ - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringEXT (void); -#endif -#endif /* WGL_EXT_extensions_string */ - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 -#endif /* WGL_EXT_framebuffer_sRGB */ - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif -#endif /* WGL_EXT_make_current_read */ - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif /* WGL_EXT_multisample */ - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -DECLARE_HANDLE(HPBUFFEREXT); -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); -int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); -BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_EXT_pbuffer */ - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_EXT_pixel_format */ - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 -#endif /* WGL_EXT_pixel_format_packed_float */ - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSwapIntervalEXT (int interval); -int WINAPI wglGetSwapIntervalEXT (void); -#endif -#endif /* WGL_EXT_swap_control */ - -#ifndef WGL_EXT_swap_control_tear -#define WGL_EXT_swap_control_tear 1 -#endif /* WGL_EXT_swap_control_tear */ - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); -#endif -#endif /* WGL_I3D_digital_video_control */ - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); -BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif -#endif /* WGL_I3D_gamma */ - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableGenlockI3D (HDC hDC); -BOOL WINAPI wglDisableGenlockI3D (HDC hDC); -BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); -BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); -BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); -BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); -BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); -BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); -BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); -BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); -BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); -BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif -#endif /* WGL_I3D_genlock */ - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#ifdef WGL_WGLEXT_PROTOTYPES -LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); -BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); -BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); -#endif -#endif /* WGL_I3D_image_buffer */ - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableFrameLockI3D (void); -BOOL WINAPI wglDisableFrameLockI3D (void); -BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); -BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); -#endif -#endif /* WGL_I3D_swap_frame_lock */ - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); -BOOL WINAPI wglBeginFrameTrackingI3D (void); -BOOL WINAPI wglEndFrameTrackingI3D (void); -BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif -#endif /* WGL_I3D_swap_frame_usage */ - -#ifndef WGL_NV_DX_interop -#define WGL_NV_DX_interop 1 -#define WGL_ACCESS_READ_ONLY_NV 0x00000000 -#define WGL_ACCESS_READ_WRITE_NV 0x00000001 -#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 -typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); -typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); -typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); -typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); -typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); -HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); -BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); -HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); -BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); -BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -#endif -#endif /* WGL_NV_DX_interop */ - -#ifndef WGL_NV_DX_interop2 -#define WGL_NV_DX_interop2 1 -#endif /* WGL_NV_DX_interop2 */ - -#ifndef WGL_NV_copy_image -#define WGL_NV_copy_image 1 -typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* WGL_NV_copy_image */ - -#ifndef WGL_NV_delay_before_swap -#define WGL_NV_delay_before_swap 1 -typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds); -#endif -#endif /* WGL_NV_delay_before_swap */ - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif /* WGL_NV_float_buffer */ - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 -DECLARE_HANDLE(HGPUNV); -struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -}; -typedef struct _GPU_DEVICE *PGPU_DEVICE; -#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); -BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); -BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -BOOL WINAPI wglDeleteDCNV (HDC hdc); -#endif -#endif /* WGL_NV_gpu_affinity */ - -#ifndef WGL_NV_multisample_coverage -#define WGL_NV_multisample_coverage 1 -#define WGL_COVERAGE_SAMPLES_NV 0x2042 -#define WGL_COLOR_SAMPLES_NV 0x20B9 -#endif /* WGL_NV_multisample_coverage */ - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); -#endif -#endif /* WGL_NV_present_video */ - -#ifndef WGL_NV_render_depth_texture -#define WGL_NV_render_depth_texture 1 -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif /* WGL_NV_render_depth_texture */ - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_NV_render_texture_rectangle 1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif /* WGL_NV_render_texture_rectangle */ - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); -BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); -BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); -BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); -BOOL WINAPI wglResetFrameCountNV (HDC hDC); -#endif -#endif /* WGL_NV_swap_group */ - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#ifdef WGL_WGLEXT_PROTOTYPES -void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -void WINAPI wglFreeMemoryNV (void *pointer); -#endif -#endif /* WGL_NV_vertex_array_range */ - -#ifndef WGL_NV_video_capture -#define WGL_NV_video_capture 1 -DECLARE_HANDLE(HVIDEOINPUTDEVICENV); -#define WGL_UNIQUE_ID_NV 0x20CE -#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF -typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#endif -#endif /* WGL_NV_video_capture */ - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 -DECLARE_HANDLE(HPVIDEODEV); -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); -BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif -#endif /* WGL_NV_video_output */ - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); -INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif -#endif /* WGL_OML_sync_control */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/misc/docker/image/install_deps.sh b/misc/docker/image/install_deps.sh index adfc67fd8da..90fd8080453 100644 --- a/misc/docker/image/install_deps.sh +++ b/misc/docker/image/install_deps.sh @@ -30,7 +30,6 @@ apt-get install -y \ gdb \ wget \ autoconf \ - libglew-dev \ libjpeg-dev \ libopenal-dev \ libcrypto++-dev \ diff --git a/sdk/include/GL/eglew.h b/sdk/include/GL/eglew.h deleted file mode 100644 index e9e5a0b297a..00000000000 --- a/sdk/include/GL/eglew.h +++ /dev/null @@ -1,3051 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2008-2019, Nigel Stewart -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __eglew_h__ -#define __eglew_h__ -#define __EGLEW_H__ - -#ifdef __eglext_h_ -#error eglext.h included before eglew.h -#endif - -#if defined(__egl_h_) -#error egl.h included before eglew.h -#endif - -#define __eglext_h_ - -#define __egl_h_ - -#ifndef EGLAPIENTRY -#define EGLAPIENTRY -#endif -#ifndef EGLAPI -#define EGLAPI extern -#endif - -/* EGL Types */ -#include - -#include -#include - -#ifndef GLEW_INCLUDE -# include -#else -# include GLEW_INCLUDE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int32_t EGLint; - -typedef unsigned int EGLBoolean; -typedef void *EGLDisplay; -typedef void *EGLConfig; -typedef void *EGLSurface; -typedef void *EGLContext; -typedef void (*__eglMustCastToProperFunctionPointerType)(void); - -typedef unsigned int EGLenum; -typedef void *EGLClientBuffer; - -typedef void *EGLSync; -typedef intptr_t EGLAttrib; -typedef khronos_utime_nanoseconds_t EGLTime; -typedef void *EGLImage; - -typedef void *EGLSyncKHR; -typedef intptr_t EGLAttribKHR; -typedef void *EGLLabelKHR; -typedef void *EGLObjectKHR; -typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); -typedef khronos_utime_nanoseconds_t EGLTimeKHR; -typedef void *EGLImageKHR; -typedef void *EGLStreamKHR; -typedef khronos_uint64_t EGLuint64KHR; -typedef int EGLNativeFileDescriptorKHR; -typedef khronos_ssize_t EGLsizeiANDROID; -typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); -typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); -typedef void *EGLDeviceEXT; -typedef void *EGLOutputLayerEXT; -typedef void *EGLOutputPortEXT; -typedef void *EGLSyncNV; -typedef khronos_utime_nanoseconds_t EGLTimeNV; -typedef khronos_utime_nanoseconds_t EGLuint64NV; -typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; - -struct EGLClientPixmapHI; -struct AHardwareBuffer; - -#define EGL_DONT_CARE ((EGLint)-1) - -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_IMAGE ((EGLImage)0) -#define EGL_NO_SURFACE ((EGLSurface)0) -#define EGL_NO_SYNC ((EGLSync)0) - -#define EGL_UNKNOWN ((EGLint)-1) - -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) - -EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); -/* ---------------------------- EGL_VERSION_1_0 ---------------------------- */ - -#ifndef EGL_VERSION_1_0 -#define EGL_VERSION_1_0 1 - -#define EGL_FALSE 0 -#define EGL_PBUFFER_BIT 0x0001 -#define EGL_TRUE 1 -#define EGL_PIXMAP_BIT 0x0002 -#define EGL_WINDOW_BIT 0x0004 -#define EGL_SUCCESS 0x3000 -#define EGL_NOT_INITIALIZED 0x3001 -#define EGL_BAD_ACCESS 0x3002 -#define EGL_BAD_ALLOC 0x3003 -#define EGL_BAD_ATTRIBUTE 0x3004 -#define EGL_BAD_CONFIG 0x3005 -#define EGL_BAD_CONTEXT 0x3006 -#define EGL_BAD_CURRENT_SURFACE 0x3007 -#define EGL_BAD_DISPLAY 0x3008 -#define EGL_BAD_MATCH 0x3009 -#define EGL_BAD_NATIVE_PIXMAP 0x300A -#define EGL_BAD_NATIVE_WINDOW 0x300B -#define EGL_BAD_PARAMETER 0x300C -#define EGL_BAD_SURFACE 0x300D -#define EGL_BUFFER_SIZE 0x3020 -#define EGL_ALPHA_SIZE 0x3021 -#define EGL_BLUE_SIZE 0x3022 -#define EGL_GREEN_SIZE 0x3023 -#define EGL_RED_SIZE 0x3024 -#define EGL_DEPTH_SIZE 0x3025 -#define EGL_STENCIL_SIZE 0x3026 -#define EGL_CONFIG_CAVEAT 0x3027 -#define EGL_CONFIG_ID 0x3028 -#define EGL_LEVEL 0x3029 -#define EGL_MAX_PBUFFER_HEIGHT 0x302A -#define EGL_MAX_PBUFFER_PIXELS 0x302B -#define EGL_MAX_PBUFFER_WIDTH 0x302C -#define EGL_NATIVE_RENDERABLE 0x302D -#define EGL_NATIVE_VISUAL_ID 0x302E -#define EGL_NATIVE_VISUAL_TYPE 0x302F -#define EGL_SAMPLES 0x3031 -#define EGL_SAMPLE_BUFFERS 0x3032 -#define EGL_SURFACE_TYPE 0x3033 -#define EGL_TRANSPARENT_TYPE 0x3034 -#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 -#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 -#define EGL_TRANSPARENT_RED_VALUE 0x3037 -#define EGL_NONE 0x3038 -#define EGL_SLOW_CONFIG 0x3050 -#define EGL_NON_CONFORMANT_CONFIG 0x3051 -#define EGL_TRANSPARENT_RGB 0x3052 -#define EGL_VENDOR 0x3053 -#define EGL_VERSION 0x3054 -#define EGL_EXTENSIONS 0x3055 -#define EGL_HEIGHT 0x3056 -#define EGL_WIDTH 0x3057 -#define EGL_LARGEST_PBUFFER 0x3058 -#define EGL_DRAW 0x3059 -#define EGL_READ 0x305A -#define EGL_CORE_NATIVE_ENGINE 0x305B - -typedef EGLBoolean ( * PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config); -typedef EGLBoolean ( * PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); -typedef EGLContext ( * PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list); -typedef EGLSurface ( * PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); -typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); -typedef EGLSurface ( * PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); -typedef EGLBoolean ( * PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); -typedef EGLBoolean ( * PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value); -typedef EGLBoolean ( * PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config); -typedef EGLDisplay ( * PFNEGLGETCURRENTDISPLAYPROC) ( void ); -typedef EGLSurface ( * PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); -typedef EGLDisplay ( * PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); -typedef EGLint ( * PFNEGLGETERRORPROC) ( void ); -typedef EGLBoolean ( * PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint * major, EGLint * minor); -typedef EGLBoolean ( * PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); -typedef EGLBoolean ( * PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value); -typedef const char * ( * PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); -typedef EGLBoolean ( * PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value); -typedef EGLBoolean ( * PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); -typedef EGLBoolean ( * PFNEGLTERMINATEPROC) (EGLDisplay dpy); -typedef EGLBoolean ( * PFNEGLWAITGLPROC) ( void ); -typedef EGLBoolean ( * PFNEGLWAITNATIVEPROC) (EGLint engine); - -#define eglChooseConfig EGLEW_GET_FUN(__eglewChooseConfig) -#define eglCopyBuffers EGLEW_GET_FUN(__eglewCopyBuffers) -#define eglCreateContext EGLEW_GET_FUN(__eglewCreateContext) -#define eglCreatePbufferSurface EGLEW_GET_FUN(__eglewCreatePbufferSurface) -#define eglCreatePixmapSurface EGLEW_GET_FUN(__eglewCreatePixmapSurface) -#define eglCreateWindowSurface EGLEW_GET_FUN(__eglewCreateWindowSurface) -#define eglDestroyContext EGLEW_GET_FUN(__eglewDestroyContext) -#define eglDestroySurface EGLEW_GET_FUN(__eglewDestroySurface) -#define eglGetConfigAttrib EGLEW_GET_FUN(__eglewGetConfigAttrib) -#define eglGetConfigs EGLEW_GET_FUN(__eglewGetConfigs) -#define eglGetCurrentDisplay EGLEW_GET_FUN(__eglewGetCurrentDisplay) -#define eglGetCurrentSurface EGLEW_GET_FUN(__eglewGetCurrentSurface) -#define eglGetDisplay EGLEW_GET_FUN(__eglewGetDisplay) -#define eglGetError EGLEW_GET_FUN(__eglewGetError) -#define eglInitialize EGLEW_GET_FUN(__eglewInitialize) -#define eglMakeCurrent EGLEW_GET_FUN(__eglewMakeCurrent) -#define eglQueryContext EGLEW_GET_FUN(__eglewQueryContext) -#define eglQueryString EGLEW_GET_FUN(__eglewQueryString) -#define eglQuerySurface EGLEW_GET_FUN(__eglewQuerySurface) -#define eglSwapBuffers EGLEW_GET_FUN(__eglewSwapBuffers) -#define eglTerminate EGLEW_GET_FUN(__eglewTerminate) -#define eglWaitGL EGLEW_GET_FUN(__eglewWaitGL) -#define eglWaitNative EGLEW_GET_FUN(__eglewWaitNative) - -#define EGLEW_VERSION_1_0 EGLEW_GET_VAR(__EGLEW_VERSION_1_0) - -#endif /* EGL_VERSION_1_0 */ - -/* ---------------------------- EGL_VERSION_1_1 ---------------------------- */ - -#ifndef EGL_VERSION_1_1 -#define EGL_VERSION_1_1 1 - -#define EGL_CONTEXT_LOST 0x300E -#define EGL_BIND_TO_TEXTURE_RGB 0x3039 -#define EGL_BIND_TO_TEXTURE_RGBA 0x303A -#define EGL_MIN_SWAP_INTERVAL 0x303B -#define EGL_MAX_SWAP_INTERVAL 0x303C -#define EGL_NO_TEXTURE 0x305C -#define EGL_TEXTURE_RGB 0x305D -#define EGL_TEXTURE_RGBA 0x305E -#define EGL_TEXTURE_2D 0x305F -#define EGL_TEXTURE_FORMAT 0x3080 -#define EGL_TEXTURE_TARGET 0x3081 -#define EGL_MIPMAP_TEXTURE 0x3082 -#define EGL_MIPMAP_LEVEL 0x3083 -#define EGL_BACK_BUFFER 0x3084 - -typedef EGLBoolean ( * PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLBoolean ( * PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLBoolean ( * PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); -typedef EGLBoolean ( * PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); - -#define eglBindTexImage EGLEW_GET_FUN(__eglewBindTexImage) -#define eglReleaseTexImage EGLEW_GET_FUN(__eglewReleaseTexImage) -#define eglSurfaceAttrib EGLEW_GET_FUN(__eglewSurfaceAttrib) -#define eglSwapInterval EGLEW_GET_FUN(__eglewSwapInterval) - -#define EGLEW_VERSION_1_1 EGLEW_GET_VAR(__EGLEW_VERSION_1_1) - -#endif /* EGL_VERSION_1_1 */ - -/* ---------------------------- EGL_VERSION_1_2 ---------------------------- */ - -#ifndef EGL_VERSION_1_2 -#define EGL_VERSION_1_2 1 - -#define EGL_OPENGL_ES_BIT 0x0001 -#define EGL_OPENVG_BIT 0x0002 -#define EGL_LUMINANCE_SIZE 0x303D -#define EGL_ALPHA_MASK_SIZE 0x303E -#define EGL_COLOR_BUFFER_TYPE 0x303F -#define EGL_RENDERABLE_TYPE 0x3040 -#define EGL_SINGLE_BUFFER 0x3085 -#define EGL_RENDER_BUFFER 0x3086 -#define EGL_COLORSPACE 0x3087 -#define EGL_ALPHA_FORMAT 0x3088 -#define EGL_COLORSPACE_LINEAR 0x308A -#define EGL_ALPHA_FORMAT_NONPRE 0x308B -#define EGL_ALPHA_FORMAT_PRE 0x308C -#define EGL_CLIENT_APIS 0x308D -#define EGL_RGB_BUFFER 0x308E -#define EGL_LUMINANCE_BUFFER 0x308F -#define EGL_HORIZONTAL_RESOLUTION 0x3090 -#define EGL_VERTICAL_RESOLUTION 0x3091 -#define EGL_PIXEL_ASPECT_RATIO 0x3092 -#define EGL_SWAP_BEHAVIOR 0x3093 -#define EGL_BUFFER_PRESERVED 0x3094 -#define EGL_BUFFER_DESTROYED 0x3095 -#define EGL_OPENVG_IMAGE 0x3096 -#define EGL_CONTEXT_CLIENT_TYPE 0x3097 -#define EGL_OPENGL_ES_API 0x30A0 -#define EGL_OPENVG_API 0x30A1 -#define EGL_DISPLAY_SCALING 10000 - -typedef EGLBoolean ( * PFNEGLBINDAPIPROC) (EGLenum api); -typedef EGLSurface ( * PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list); -typedef EGLenum ( * PFNEGLQUERYAPIPROC) ( void ); -typedef EGLBoolean ( * PFNEGLRELEASETHREADPROC) ( void ); -typedef EGLBoolean ( * PFNEGLWAITCLIENTPROC) ( void ); - -#define eglBindAPI EGLEW_GET_FUN(__eglewBindAPI) -#define eglCreatePbufferFromClientBuffer EGLEW_GET_FUN(__eglewCreatePbufferFromClientBuffer) -#define eglQueryAPI EGLEW_GET_FUN(__eglewQueryAPI) -#define eglReleaseThread EGLEW_GET_FUN(__eglewReleaseThread) -#define eglWaitClient EGLEW_GET_FUN(__eglewWaitClient) - -#define EGLEW_VERSION_1_2 EGLEW_GET_VAR(__EGLEW_VERSION_1_2) - -#endif /* EGL_VERSION_1_2 */ - -/* ---------------------------- EGL_VERSION_1_3 ---------------------------- */ - -#ifndef EGL_VERSION_1_3 -#define EGL_VERSION_1_3 1 - -#define EGL_OPENGL_ES2_BIT 0x0004 -#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 -#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 -#define EGL_MATCH_NATIVE_PIXMAP 0x3041 -#define EGL_CONFORMANT 0x3042 -#define EGL_VG_COLORSPACE 0x3087 -#define EGL_VG_ALPHA_FORMAT 0x3088 -#define EGL_VG_COLORSPACE_LINEAR 0x308A -#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B -#define EGL_VG_ALPHA_FORMAT_PRE 0x308C -#define EGL_CONTEXT_CLIENT_VERSION 0x3098 - -#define EGLEW_VERSION_1_3 EGLEW_GET_VAR(__EGLEW_VERSION_1_3) - -#endif /* EGL_VERSION_1_3 */ - -/* ---------------------------- EGL_VERSION_1_4 ---------------------------- */ - -#ifndef EGL_VERSION_1_4 -#define EGL_VERSION_1_4 1 - -#define EGL_OPENGL_BIT 0x0008 -#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 -#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 -#define EGL_MULTISAMPLE_RESOLVE 0x3099 -#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A -#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B -#define EGL_OPENGL_API 0x30A2 - -typedef EGLContext ( * PFNEGLGETCURRENTCONTEXTPROC) ( void ); - -#define eglGetCurrentContext EGLEW_GET_FUN(__eglewGetCurrentContext) - -#define EGLEW_VERSION_1_4 EGLEW_GET_VAR(__EGLEW_VERSION_1_4) - -#endif /* EGL_VERSION_1_4 */ - -/* ---------------------------- EGL_VERSION_1_5 ---------------------------- */ - -#ifndef EGL_VERSION_1_5 -#define EGL_VERSION_1_5 1 - -#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 -#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 -#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define EGL_OPENGL_ES3_BIT 0x00000040 -#define EGL_GL_COLORSPACE_SRGB 0x3089 -#define EGL_GL_COLORSPACE_LINEAR 0x308A -#define EGL_CONTEXT_MAJOR_VERSION 0x3098 -#define EGL_CL_EVENT_HANDLE 0x309C -#define EGL_GL_COLORSPACE 0x309D -#define EGL_GL_TEXTURE_2D 0x30B1 -#define EGL_GL_TEXTURE_3D 0x30B2 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 -#define EGL_GL_RENDERBUFFER 0x30B9 -#define EGL_GL_TEXTURE_LEVEL 0x30BC -#define EGL_GL_TEXTURE_ZOFFSET 0x30BD -#define EGL_IMAGE_PRESERVED 0x30D2 -#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 -#define EGL_SYNC_STATUS 0x30F1 -#define EGL_SIGNALED 0x30F2 -#define EGL_UNSIGNALED 0x30F3 -#define EGL_TIMEOUT_EXPIRED 0x30F5 -#define EGL_CONDITION_SATISFIED 0x30F6 -#define EGL_SYNC_TYPE 0x30F7 -#define EGL_SYNC_CONDITION 0x30F8 -#define EGL_SYNC_FENCE 0x30F9 -#define EGL_CONTEXT_MINOR_VERSION 0x30FB -#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD -#define EGL_SYNC_CL_EVENT 0x30FE -#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF -#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 -#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD -#define EGL_NO_RESET_NOTIFICATION 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF -#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF - -typedef EGLint ( * PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); -typedef EGLImage ( * PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list); -typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); -typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); -typedef EGLSync ( * PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); -typedef EGLBoolean ( * PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); -typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void * native_display, const EGLAttrib * attrib_list); -typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); -typedef EGLBoolean ( * PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); - -#define eglClientWaitSync EGLEW_GET_FUN(__eglewClientWaitSync) -#define eglCreateImage EGLEW_GET_FUN(__eglewCreateImage) -#define eglCreatePlatformPixmapSurface EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurface) -#define eglCreatePlatformWindowSurface EGLEW_GET_FUN(__eglewCreatePlatformWindowSurface) -#define eglCreateSync EGLEW_GET_FUN(__eglewCreateSync) -#define eglDestroyImage EGLEW_GET_FUN(__eglewDestroyImage) -#define eglDestroySync EGLEW_GET_FUN(__eglewDestroySync) -#define eglGetPlatformDisplay EGLEW_GET_FUN(__eglewGetPlatformDisplay) -#define eglGetSyncAttrib EGLEW_GET_FUN(__eglewGetSyncAttrib) -#define eglWaitSync EGLEW_GET_FUN(__eglewWaitSync) - -#define EGLEW_VERSION_1_5 EGLEW_GET_VAR(__EGLEW_VERSION_1_5) - -#endif /* EGL_VERSION_1_5 */ - -/* ------------------------ EGL_ANDROID_GLES_layers ------------------------ */ - -#ifndef EGL_ANDROID_GLES_layers -#define EGL_ANDROID_GLES_layers 1 - -#define EGLEW_ANDROID_GLES_layers EGLEW_GET_VAR(__EGLEW_ANDROID_GLES_layers) - -#endif /* EGL_ANDROID_GLES_layers */ - -/* ------------------------- EGL_ANDROID_blob_cache ------------------------ */ - -#ifndef EGL_ANDROID_blob_cache -#define EGL_ANDROID_blob_cache 1 - -typedef void ( * PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); - -#define eglSetBlobCacheFuncsANDROID EGLEW_GET_FUN(__eglewSetBlobCacheFuncsANDROID) - -#define EGLEW_ANDROID_blob_cache EGLEW_GET_VAR(__EGLEW_ANDROID_blob_cache) - -#endif /* EGL_ANDROID_blob_cache */ - -/* ---------------- EGL_ANDROID_create_native_client_buffer ---------------- */ - -#ifndef EGL_ANDROID_create_native_client_buffer -#define EGL_ANDROID_create_native_client_buffer 1 - -#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 -#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 -#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 -#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 - -typedef EGLClientBuffer ( * PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint* attrib_list); - -#define eglCreateNativeClientBufferANDROID EGLEW_GET_FUN(__eglewCreateNativeClientBufferANDROID) - -#define EGLEW_ANDROID_create_native_client_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_create_native_client_buffer) - -#endif /* EGL_ANDROID_create_native_client_buffer */ - -/* --------------------- EGL_ANDROID_framebuffer_target -------------------- */ - -#ifndef EGL_ANDROID_framebuffer_target -#define EGL_ANDROID_framebuffer_target 1 - -#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 - -#define EGLEW_ANDROID_framebuffer_target EGLEW_GET_VAR(__EGLEW_ANDROID_framebuffer_target) - -#endif /* EGL_ANDROID_framebuffer_target */ - -/* ----------------- EGL_ANDROID_front_buffer_auto_refresh ----------------- */ - -#ifndef EGL_ANDROID_front_buffer_auto_refresh -#define EGL_ANDROID_front_buffer_auto_refresh 1 - -#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C - -#define EGLEW_ANDROID_front_buffer_auto_refresh EGLEW_GET_VAR(__EGLEW_ANDROID_front_buffer_auto_refresh) - -#endif /* EGL_ANDROID_front_buffer_auto_refresh */ - -/* -------------------- EGL_ANDROID_get_frame_timestamps ------------------- */ - -#ifndef EGL_ANDROID_get_frame_timestamps -#define EGL_ANDROID_get_frame_timestamps 1 - -#define EGL_TIMESTAMPS_ANDROID 0x3430 -#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 -#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 -#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 -#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 -#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 -#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 -#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 -#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 -#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 -#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A -#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B -#define EGL_READS_DONE_TIME_ANDROID 0x343C - -typedef EGLBoolean ( * PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint* names, EGLnsecsANDROID* values); -typedef EGLBoolean ( * PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); -typedef EGLBoolean ( * PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); -typedef EGLBoolean ( * PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint* timestamps, EGLnsecsANDROID* values); -typedef EGLBoolean ( * PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR* frameId); - -#define eglGetCompositorTimingANDROID EGLEW_GET_FUN(__eglewGetCompositorTimingANDROID) -#define eglGetCompositorTimingSupportedANDROID EGLEW_GET_FUN(__eglewGetCompositorTimingSupportedANDROID) -#define eglGetFrameTimestampSupportedANDROID EGLEW_GET_FUN(__eglewGetFrameTimestampSupportedANDROID) -#define eglGetFrameTimestampsANDROID EGLEW_GET_FUN(__eglewGetFrameTimestampsANDROID) -#define eglGetNextFrameIdANDROID EGLEW_GET_FUN(__eglewGetNextFrameIdANDROID) - -#define EGLEW_ANDROID_get_frame_timestamps EGLEW_GET_VAR(__EGLEW_ANDROID_get_frame_timestamps) - -#endif /* EGL_ANDROID_get_frame_timestamps */ - -/* ------------------ EGL_ANDROID_get_native_client_buffer ----------------- */ - -#ifndef EGL_ANDROID_get_native_client_buffer -#define EGL_ANDROID_get_native_client_buffer 1 - -typedef EGLClientBuffer ( * PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer* buffer); - -#define eglGetNativeClientBufferANDROID EGLEW_GET_FUN(__eglewGetNativeClientBufferANDROID) - -#define EGLEW_ANDROID_get_native_client_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_get_native_client_buffer) - -#endif /* EGL_ANDROID_get_native_client_buffer */ - -/* -------------------- EGL_ANDROID_image_native_buffer -------------------- */ - -#ifndef EGL_ANDROID_image_native_buffer -#define EGL_ANDROID_image_native_buffer 1 - -#define EGL_NATIVE_BUFFER_ANDROID 0x3140 - -#define EGLEW_ANDROID_image_native_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_image_native_buffer) - -#endif /* EGL_ANDROID_image_native_buffer */ - -/* --------------------- EGL_ANDROID_native_fence_sync --------------------- */ - -#ifndef EGL_ANDROID_native_fence_sync -#define EGL_ANDROID_native_fence_sync 1 - -#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 -#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 -#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 - -typedef EGLint ( * PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); - -#define eglDupNativeFenceFDANDROID EGLEW_GET_FUN(__eglewDupNativeFenceFDANDROID) - -#define EGLEW_ANDROID_native_fence_sync EGLEW_GET_VAR(__EGLEW_ANDROID_native_fence_sync) - -#endif /* EGL_ANDROID_native_fence_sync */ - -/* --------------------- EGL_ANDROID_presentation_time --------------------- */ - -#ifndef EGL_ANDROID_presentation_time -#define EGL_ANDROID_presentation_time 1 - -typedef EGLBoolean ( * PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); - -#define eglPresentationTimeANDROID EGLEW_GET_FUN(__eglewPresentationTimeANDROID) - -#define EGLEW_ANDROID_presentation_time EGLEW_GET_VAR(__EGLEW_ANDROID_presentation_time) - -#endif /* EGL_ANDROID_presentation_time */ - -/* ------------------------- EGL_ANDROID_recordable ------------------------ */ - -#ifndef EGL_ANDROID_recordable -#define EGL_ANDROID_recordable 1 - -#define EGL_RECORDABLE_ANDROID 0x3142 - -#define EGLEW_ANDROID_recordable EGLEW_GET_VAR(__EGLEW_ANDROID_recordable) - -#endif /* EGL_ANDROID_recordable */ - -/* ---------------- EGL_ANGLE_d3d_share_handle_client_buffer --------------- */ - -#ifndef EGL_ANGLE_d3d_share_handle_client_buffer -#define EGL_ANGLE_d3d_share_handle_client_buffer 1 - -#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 - -#define EGLEW_ANGLE_d3d_share_handle_client_buffer EGLEW_GET_VAR(__EGLEW_ANGLE_d3d_share_handle_client_buffer) - -#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ - -/* -------------------------- EGL_ANGLE_device_d3d ------------------------- */ - -#ifndef EGL_ANGLE_device_d3d -#define EGL_ANGLE_device_d3d 1 - -#define EGL_D3D9_DEVICE_ANGLE 0x33A0 -#define EGL_D3D11_DEVICE_ANGLE 0x33A1 - -#define EGLEW_ANGLE_device_d3d EGLEW_GET_VAR(__EGLEW_ANGLE_device_d3d) - -#endif /* EGL_ANGLE_device_d3d */ - -/* -------------------- EGL_ANGLE_query_surface_pointer -------------------- */ - -#ifndef EGL_ANGLE_query_surface_pointer -#define EGL_ANGLE_query_surface_pointer 1 - -typedef EGLBoolean ( * PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value); - -#define eglQuerySurfacePointerANGLE EGLEW_GET_FUN(__eglewQuerySurfacePointerANGLE) - -#define EGLEW_ANGLE_query_surface_pointer EGLEW_GET_VAR(__EGLEW_ANGLE_query_surface_pointer) - -#endif /* EGL_ANGLE_query_surface_pointer */ - -/* ------------- EGL_ANGLE_surface_d3d_texture_2d_share_handle ------------- */ - -#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle -#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 - -#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 - -#define EGLEW_ANGLE_surface_d3d_texture_2d_share_handle EGLEW_GET_VAR(__EGLEW_ANGLE_surface_d3d_texture_2d_share_handle) - -#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ - -/* ---------------------- EGL_ANGLE_window_fixed_size ---------------------- */ - -#ifndef EGL_ANGLE_window_fixed_size -#define EGL_ANGLE_window_fixed_size 1 - -#define EGL_FIXED_SIZE_ANGLE 0x3201 - -#define EGLEW_ANGLE_window_fixed_size EGLEW_GET_VAR(__EGLEW_ANGLE_window_fixed_size) - -#endif /* EGL_ANGLE_window_fixed_size */ - -/* -------------------------- EGL_ARM_image_format ------------------------- */ - -#ifndef EGL_ARM_image_format -#define EGL_ARM_image_format 1 - -#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 -#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 - -#define EGLEW_ARM_image_format EGLEW_GET_VAR(__EGLEW_ARM_image_format) - -#endif /* EGL_ARM_image_format */ - -/* --------------------- EGL_ARM_implicit_external_sync -------------------- */ - -#ifndef EGL_ARM_implicit_external_sync -#define EGL_ARM_implicit_external_sync 1 - -#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A - -#define EGLEW_ARM_implicit_external_sync EGLEW_GET_VAR(__EGLEW_ARM_implicit_external_sync) - -#endif /* EGL_ARM_implicit_external_sync */ - -/* ------------------- EGL_ARM_pixmap_multisample_discard ------------------ */ - -#ifndef EGL_ARM_pixmap_multisample_discard -#define EGL_ARM_pixmap_multisample_discard 1 - -#define EGL_DISCARD_SAMPLES_ARM 0x3286 - -#define EGLEW_ARM_pixmap_multisample_discard EGLEW_GET_VAR(__EGLEW_ARM_pixmap_multisample_discard) - -#endif /* EGL_ARM_pixmap_multisample_discard */ - -/* ------------------------- EGL_EXT_bind_to_front ------------------------- */ - -#ifndef EGL_EXT_bind_to_front -#define EGL_EXT_bind_to_front 1 - -#define EGL_FRONT_BUFFER_EXT 0x3464 - -#define EGLEW_EXT_bind_to_front EGLEW_GET_VAR(__EGLEW_EXT_bind_to_front) - -#endif /* EGL_EXT_bind_to_front */ - -/* --------------------------- EGL_EXT_buffer_age -------------------------- */ - -#ifndef EGL_EXT_buffer_age -#define EGL_EXT_buffer_age 1 - -#define EGL_BUFFER_AGE_EXT 0x313D - -#define EGLEW_EXT_buffer_age EGLEW_GET_VAR(__EGLEW_EXT_buffer_age) - -#endif /* EGL_EXT_buffer_age */ - -/* ----------------------- EGL_EXT_client_extensions ----------------------- */ - -#ifndef EGL_EXT_client_extensions -#define EGL_EXT_client_extensions 1 - -#define EGLEW_EXT_client_extensions EGLEW_GET_VAR(__EGLEW_EXT_client_extensions) - -#endif /* EGL_EXT_client_extensions */ - -/* -------------------------- EGL_EXT_client_sync -------------------------- */ - -#ifndef EGL_EXT_client_sync -#define EGL_EXT_client_sync 1 - -#define EGL_SYNC_CLIENT_EXT 0x3364 -#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 - -typedef EGLBoolean ( * PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib* attrib_list); - -#define eglClientSignalSyncEXT EGLEW_GET_FUN(__eglewClientSignalSyncEXT) - -#define EGLEW_EXT_client_sync EGLEW_GET_VAR(__EGLEW_EXT_client_sync) - -#endif /* EGL_EXT_client_sync */ - -/* --------------------------- EGL_EXT_compositor -------------------------- */ - -#ifndef EGL_EXT_compositor -#define EGL_EXT_compositor 1 - -#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 -#define EGL_EXTERNAL_REF_ID_EXT 0x3461 -#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462 -#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463 - -typedef EGLBoolean ( * PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint* context_attributes, EGLint num_entries); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint* external_ref_ids, EGLint num_entries); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint* window_attributes, EGLint num_entries); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint* external_win_ids, EGLint num_entries); -typedef EGLBoolean ( * PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy); - -#define eglCompositorBindTexWindowEXT EGLEW_GET_FUN(__eglewCompositorBindTexWindowEXT) -#define eglCompositorSetContextAttributesEXT EGLEW_GET_FUN(__eglewCompositorSetContextAttributesEXT) -#define eglCompositorSetContextListEXT EGLEW_GET_FUN(__eglewCompositorSetContextListEXT) -#define eglCompositorSetSizeEXT EGLEW_GET_FUN(__eglewCompositorSetSizeEXT) -#define eglCompositorSetWindowAttributesEXT EGLEW_GET_FUN(__eglewCompositorSetWindowAttributesEXT) -#define eglCompositorSetWindowListEXT EGLEW_GET_FUN(__eglewCompositorSetWindowListEXT) -#define eglCompositorSwapPolicyEXT EGLEW_GET_FUN(__eglewCompositorSwapPolicyEXT) - -#define EGLEW_EXT_compositor EGLEW_GET_VAR(__EGLEW_EXT_compositor) - -#endif /* EGL_EXT_compositor */ - -/* ------------------- EGL_EXT_create_context_robustness ------------------- */ - -#ifndef EGL_EXT_create_context_robustness -#define EGL_EXT_create_context_robustness 1 - -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 -#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF - -#define EGLEW_EXT_create_context_robustness EGLEW_GET_VAR(__EGLEW_EXT_create_context_robustness) - -#endif /* EGL_EXT_create_context_robustness */ - -/* -------------------------- EGL_EXT_device_base -------------------------- */ - -#ifndef EGL_EXT_device_base -#define EGL_EXT_device_base 1 - -#define EGL_BAD_DEVICE_EXT 0x322B -#define EGL_DEVICE_EXT 0x322C - -#define EGLEW_EXT_device_base EGLEW_GET_VAR(__EGLEW_EXT_device_base) - -#endif /* EGL_EXT_device_base */ - -/* --------------------------- EGL_EXT_device_drm -------------------------- */ - -#ifndef EGL_EXT_device_drm -#define EGL_EXT_device_drm 1 - -#define EGL_DRM_DEVICE_FILE_EXT 0x3233 -#define EGL_DRM_MASTER_FD_EXT 0x333C - -#define EGLEW_EXT_device_drm EGLEW_GET_VAR(__EGLEW_EXT_device_drm) - -#endif /* EGL_EXT_device_drm */ - -/* ----------------------- EGL_EXT_device_enumeration ---------------------- */ - -#ifndef EGL_EXT_device_enumeration -#define EGL_EXT_device_enumeration 1 - -typedef EGLBoolean ( * PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT* devices, EGLint* num_devices); - -#define eglQueryDevicesEXT EGLEW_GET_FUN(__eglewQueryDevicesEXT) - -#define EGLEW_EXT_device_enumeration EGLEW_GET_VAR(__EGLEW_EXT_device_enumeration) - -#endif /* EGL_EXT_device_enumeration */ - -/* ------------------------- EGL_EXT_device_openwf ------------------------- */ - -#ifndef EGL_EXT_device_openwf -#define EGL_EXT_device_openwf 1 - -#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 - -#define EGLEW_EXT_device_openwf EGLEW_GET_VAR(__EGLEW_EXT_device_openwf) - -#endif /* EGL_EXT_device_openwf */ - -/* -------------------------- EGL_EXT_device_query ------------------------- */ - -#ifndef EGL_EXT_device_query -#define EGL_EXT_device_query 1 - -#define EGL_BAD_DEVICE_EXT 0x322B -#define EGL_DEVICE_EXT 0x322C - -typedef EGLBoolean ( * PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib* value); -typedef const char* ( * PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); -typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib* value); - -#define eglQueryDeviceAttribEXT EGLEW_GET_FUN(__eglewQueryDeviceAttribEXT) -#define eglQueryDeviceStringEXT EGLEW_GET_FUN(__eglewQueryDeviceStringEXT) -#define eglQueryDisplayAttribEXT EGLEW_GET_FUN(__eglewQueryDisplayAttribEXT) - -#define EGLEW_EXT_device_query EGLEW_GET_VAR(__EGLEW_EXT_device_query) - -#endif /* EGL_EXT_device_query */ - -/* ------------------ EGL_EXT_gl_colorspace_bt2020_linear ------------------ */ - -#ifndef EGL_EXT_gl_colorspace_bt2020_linear -#define EGL_EXT_gl_colorspace_bt2020_linear 1 - -#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F - -#define EGLEW_EXT_gl_colorspace_bt2020_linear EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_bt2020_linear) - -#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ - -/* -------------------- EGL_EXT_gl_colorspace_bt2020_pq -------------------- */ - -#ifndef EGL_EXT_gl_colorspace_bt2020_pq -#define EGL_EXT_gl_colorspace_bt2020_pq 1 - -#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 - -#define EGLEW_EXT_gl_colorspace_bt2020_pq EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_bt2020_pq) - -#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ - -/* -------------------- EGL_EXT_gl_colorspace_display_p3 ------------------- */ - -#ifndef EGL_EXT_gl_colorspace_display_p3 -#define EGL_EXT_gl_colorspace_display_p3 1 - -#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363 - -#define EGLEW_EXT_gl_colorspace_display_p3 EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_display_p3) - -#endif /* EGL_EXT_gl_colorspace_display_p3 */ - -/* ---------------- EGL_EXT_gl_colorspace_display_p3_linear ---------------- */ - -#ifndef EGL_EXT_gl_colorspace_display_p3_linear -#define EGL_EXT_gl_colorspace_display_p3_linear 1 - -#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 - -#define EGLEW_EXT_gl_colorspace_display_p3_linear EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_display_p3_linear) - -#endif /* EGL_EXT_gl_colorspace_display_p3_linear */ - -/* -------------- EGL_EXT_gl_colorspace_display_p3_passthrough ------------- */ - -#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough -#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 - -#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 - -#define EGLEW_EXT_gl_colorspace_display_p3_passthrough EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_display_p3_passthrough) - -#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ - -/* ---------------------- EGL_EXT_gl_colorspace_scrgb ---------------------- */ - -#ifndef EGL_EXT_gl_colorspace_scrgb -#define EGL_EXT_gl_colorspace_scrgb 1 - -#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 - -#define EGLEW_EXT_gl_colorspace_scrgb EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_scrgb) - -#endif /* EGL_EXT_gl_colorspace_scrgb */ - -/* ------------------- EGL_EXT_gl_colorspace_scrgb_linear ------------------ */ - -#ifndef EGL_EXT_gl_colorspace_scrgb_linear -#define EGL_EXT_gl_colorspace_scrgb_linear 1 - -#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 - -#define EGLEW_EXT_gl_colorspace_scrgb_linear EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_scrgb_linear) - -#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ - -/* ---------------------- EGL_EXT_image_dma_buf_import --------------------- */ - -#ifndef EGL_EXT_image_dma_buf_import -#define EGL_EXT_image_dma_buf_import 1 - -#define EGL_LINUX_DMA_BUF_EXT 0x3270 -#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 -#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 -#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 -#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 -#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 -#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 -#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 -#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 -#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 -#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A -#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B -#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C -#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D -#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E -#define EGL_ITU_REC601_EXT 0x327F -#define EGL_ITU_REC709_EXT 0x3280 -#define EGL_ITU_REC2020_EXT 0x3281 -#define EGL_YUV_FULL_RANGE_EXT 0x3282 -#define EGL_YUV_NARROW_RANGE_EXT 0x3283 -#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 -#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 - -#define EGLEW_EXT_image_dma_buf_import EGLEW_GET_VAR(__EGLEW_EXT_image_dma_buf_import) - -#endif /* EGL_EXT_image_dma_buf_import */ - -/* ----------------- EGL_EXT_image_dma_buf_import_modifiers ---------------- */ - -#ifndef EGL_EXT_image_dma_buf_import_modifiers -#define EGL_EXT_image_dma_buf_import_modifiers 1 - -#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 -#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 -#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 -#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 -#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 -#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 -#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 -#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 -#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 -#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 -#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A - -typedef EGLBoolean ( * PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint* formats, EGLint* num_formats); -typedef EGLBoolean ( * PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR* modifiers, EGLBoolean* external_only, EGLint* num_modifiers); - -#define eglQueryDmaBufFormatsEXT EGLEW_GET_FUN(__eglewQueryDmaBufFormatsEXT) -#define eglQueryDmaBufModifiersEXT EGLEW_GET_FUN(__eglewQueryDmaBufModifiersEXT) - -#define EGLEW_EXT_image_dma_buf_import_modifiers EGLEW_GET_VAR(__EGLEW_EXT_image_dma_buf_import_modifiers) - -#endif /* EGL_EXT_image_dma_buf_import_modifiers */ - -/* ---------------------- EGL_EXT_image_gl_colorspace ---------------------- */ - -#ifndef EGL_EXT_image_gl_colorspace -#define EGL_EXT_image_gl_colorspace 1 - -#define EGL_GL_COLORSPACE 0x309D -#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D - -#define EGLEW_EXT_image_gl_colorspace EGLEW_GET_VAR(__EGLEW_EXT_image_gl_colorspace) - -#endif /* EGL_EXT_image_gl_colorspace */ - -/* ------------------ EGL_EXT_image_implicit_sync_control ------------------ */ - -#ifndef EGL_EXT_image_implicit_sync_control -#define EGL_EXT_image_implicit_sync_control 1 - -#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 -#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471 -#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472 - -#define EGLEW_EXT_image_implicit_sync_control EGLEW_GET_VAR(__EGLEW_EXT_image_implicit_sync_control) - -#endif /* EGL_EXT_image_implicit_sync_control */ - -/* ------------------------ EGL_EXT_multiview_window ----------------------- */ - -#ifndef EGL_EXT_multiview_window -#define EGL_EXT_multiview_window 1 - -#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 - -#define EGLEW_EXT_multiview_window EGLEW_GET_VAR(__EGLEW_EXT_multiview_window) - -#endif /* EGL_EXT_multiview_window */ - -/* -------------------------- EGL_EXT_output_base -------------------------- */ - -#ifndef EGL_EXT_output_base -#define EGL_EXT_output_base 1 - -#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D -#define EGL_BAD_OUTPUT_PORT_EXT 0x322E -#define EGL_SWAP_INTERVAL_EXT 0x322F - -typedef EGLBoolean ( * PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib* attrib_list, EGLOutputLayerEXT* layers, EGLint max_layers, EGLint* num_layers); -typedef EGLBoolean ( * PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib* attrib_list, EGLOutputPortEXT* ports, EGLint max_ports, EGLint* num_ports); -typedef EGLBoolean ( * PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); -typedef EGLBoolean ( * PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); -typedef EGLBoolean ( * PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib* value); -typedef const char* ( * PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); -typedef EGLBoolean ( * PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib* value); -typedef const char* ( * PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); - -#define eglGetOutputLayersEXT EGLEW_GET_FUN(__eglewGetOutputLayersEXT) -#define eglGetOutputPortsEXT EGLEW_GET_FUN(__eglewGetOutputPortsEXT) -#define eglOutputLayerAttribEXT EGLEW_GET_FUN(__eglewOutputLayerAttribEXT) -#define eglOutputPortAttribEXT EGLEW_GET_FUN(__eglewOutputPortAttribEXT) -#define eglQueryOutputLayerAttribEXT EGLEW_GET_FUN(__eglewQueryOutputLayerAttribEXT) -#define eglQueryOutputLayerStringEXT EGLEW_GET_FUN(__eglewQueryOutputLayerStringEXT) -#define eglQueryOutputPortAttribEXT EGLEW_GET_FUN(__eglewQueryOutputPortAttribEXT) -#define eglQueryOutputPortStringEXT EGLEW_GET_FUN(__eglewQueryOutputPortStringEXT) - -#define EGLEW_EXT_output_base EGLEW_GET_VAR(__EGLEW_EXT_output_base) - -#endif /* EGL_EXT_output_base */ - -/* --------------------------- EGL_EXT_output_drm -------------------------- */ - -#ifndef EGL_EXT_output_drm -#define EGL_EXT_output_drm 1 - -#define EGL_DRM_CRTC_EXT 0x3234 -#define EGL_DRM_PLANE_EXT 0x3235 -#define EGL_DRM_CONNECTOR_EXT 0x3236 - -#define EGLEW_EXT_output_drm EGLEW_GET_VAR(__EGLEW_EXT_output_drm) - -#endif /* EGL_EXT_output_drm */ - -/* ------------------------- EGL_EXT_output_openwf ------------------------- */ - -#ifndef EGL_EXT_output_openwf -#define EGL_EXT_output_openwf 1 - -#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 -#define EGL_OPENWF_PORT_ID_EXT 0x3239 - -#define EGLEW_EXT_output_openwf EGLEW_GET_VAR(__EGLEW_EXT_output_openwf) - -#endif /* EGL_EXT_output_openwf */ - -/* ----------------------- EGL_EXT_pixel_format_float ---------------------- */ - -#ifndef EGL_EXT_pixel_format_float -#define EGL_EXT_pixel_format_float 1 - -#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 -#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A -#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B - -#define EGLEW_EXT_pixel_format_float EGLEW_GET_VAR(__EGLEW_EXT_pixel_format_float) - -#endif /* EGL_EXT_pixel_format_float */ - -/* ------------------------- EGL_EXT_platform_base ------------------------- */ - -#ifndef EGL_EXT_platform_base -#define EGL_EXT_platform_base 1 - -typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void* native_pixmap, const EGLint* attrib_list); -typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void* native_window, const EGLint* attrib_list); -typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void* native_display, const EGLint* attrib_list); - -#define eglCreatePlatformPixmapSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurfaceEXT) -#define eglCreatePlatformWindowSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformWindowSurfaceEXT) -#define eglGetPlatformDisplayEXT EGLEW_GET_FUN(__eglewGetPlatformDisplayEXT) - -#define EGLEW_EXT_platform_base EGLEW_GET_VAR(__EGLEW_EXT_platform_base) - -#endif /* EGL_EXT_platform_base */ - -/* ------------------------ EGL_EXT_platform_device ------------------------ */ - -#ifndef EGL_EXT_platform_device -#define EGL_EXT_platform_device 1 - -#define EGL_PLATFORM_DEVICE_EXT 0x313F - -#define EGLEW_EXT_platform_device EGLEW_GET_VAR(__EGLEW_EXT_platform_device) - -#endif /* EGL_EXT_platform_device */ - -/* ------------------------ EGL_EXT_platform_wayland ----------------------- */ - -#ifndef EGL_EXT_platform_wayland -#define EGL_EXT_platform_wayland 1 - -#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 - -#define EGLEW_EXT_platform_wayland EGLEW_GET_VAR(__EGLEW_EXT_platform_wayland) - -#endif /* EGL_EXT_platform_wayland */ - -/* -------------------------- EGL_EXT_platform_x11 ------------------------- */ - -#ifndef EGL_EXT_platform_x11 -#define EGL_EXT_platform_x11 1 - -#define EGL_PLATFORM_X11_EXT 0x31D5 -#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 - -#define EGLEW_EXT_platform_x11 EGLEW_GET_VAR(__EGLEW_EXT_platform_x11) - -#endif /* EGL_EXT_platform_x11 */ - -/* ----------------------- EGL_EXT_protected_content ----------------------- */ - -#ifndef EGL_EXT_protected_content -#define EGL_EXT_protected_content 1 - -#define EGL_PROTECTED_CONTENT_EXT 0x32C0 - -#define EGLEW_EXT_protected_content EGLEW_GET_VAR(__EGLEW_EXT_protected_content) - -#endif /* EGL_EXT_protected_content */ - -/* ----------------------- EGL_EXT_protected_surface ----------------------- */ - -#ifndef EGL_EXT_protected_surface -#define EGL_EXT_protected_surface 1 - -#define EGL_PROTECTED_CONTENT_EXT 0x32C0 - -#define EGLEW_EXT_protected_surface EGLEW_GET_VAR(__EGLEW_EXT_protected_surface) - -#endif /* EGL_EXT_protected_surface */ - -/* ------------------- EGL_EXT_stream_consumer_egloutput ------------------- */ - -#ifndef EGL_EXT_stream_consumer_egloutput -#define EGL_EXT_stream_consumer_egloutput 1 - -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); - -#define eglStreamConsumerOutputEXT EGLEW_GET_FUN(__eglewStreamConsumerOutputEXT) - -#define EGLEW_EXT_stream_consumer_egloutput EGLEW_GET_VAR(__EGLEW_EXT_stream_consumer_egloutput) - -#endif /* EGL_EXT_stream_consumer_egloutput */ - -/* ------------------- EGL_EXT_surface_CTA861_3_metadata ------------------- */ - -#ifndef EGL_EXT_surface_CTA861_3_metadata -#define EGL_EXT_surface_CTA861_3_metadata 1 - -#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360 -#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361 - -#define EGLEW_EXT_surface_CTA861_3_metadata EGLEW_GET_VAR(__EGLEW_EXT_surface_CTA861_3_metadata) - -#endif /* EGL_EXT_surface_CTA861_3_metadata */ - -/* ------------------- EGL_EXT_surface_SMPTE2086_metadata ------------------ */ - -#ifndef EGL_EXT_surface_SMPTE2086_metadata -#define EGL_EXT_surface_SMPTE2086_metadata 1 - -#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 -#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 -#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 -#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 -#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 -#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 -#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 -#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 -#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 -#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A -#define EGL_METADATA_SCALING_EXT 50000 - -#define EGLEW_EXT_surface_SMPTE2086_metadata EGLEW_GET_VAR(__EGLEW_EXT_surface_SMPTE2086_metadata) - -#endif /* EGL_EXT_surface_SMPTE2086_metadata */ - -/* -------------------- EGL_EXT_swap_buffers_with_damage ------------------- */ - -#ifndef EGL_EXT_swap_buffers_with_damage -#define EGL_EXT_swap_buffers_with_damage 1 - -typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint* rects, EGLint n_rects); - -#define eglSwapBuffersWithDamageEXT EGLEW_GET_FUN(__eglewSwapBuffersWithDamageEXT) - -#define EGLEW_EXT_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_EXT_swap_buffers_with_damage) - -#endif /* EGL_EXT_swap_buffers_with_damage */ - -/* --------------------------- EGL_EXT_sync_reuse -------------------------- */ - -#ifndef EGL_EXT_sync_reuse -#define EGL_EXT_sync_reuse 1 - -typedef EGLBoolean ( * PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib* attrib_list); - -#define eglUnsignalSyncEXT EGLEW_GET_FUN(__eglewUnsignalSyncEXT) - -#define EGLEW_EXT_sync_reuse EGLEW_GET_VAR(__EGLEW_EXT_sync_reuse) - -#endif /* EGL_EXT_sync_reuse */ - -/* -------------------------- EGL_EXT_yuv_surface -------------------------- */ - -#ifndef EGL_EXT_yuv_surface -#define EGL_EXT_yuv_surface 1 - -#define EGL_YUV_BUFFER_EXT 0x3300 -#define EGL_YUV_ORDER_EXT 0x3301 -#define EGL_YUV_ORDER_YUV_EXT 0x3302 -#define EGL_YUV_ORDER_YVU_EXT 0x3303 -#define EGL_YUV_ORDER_YUYV_EXT 0x3304 -#define EGL_YUV_ORDER_UYVY_EXT 0x3305 -#define EGL_YUV_ORDER_YVYU_EXT 0x3306 -#define EGL_YUV_ORDER_VYUY_EXT 0x3307 -#define EGL_YUV_ORDER_AYUV_EXT 0x3308 -#define EGL_YUV_CSC_STANDARD_EXT 0x330A -#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B -#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C -#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D -#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 -#define EGL_YUV_SUBSAMPLE_EXT 0x3312 -#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 -#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 -#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 -#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 -#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 -#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 -#define EGL_YUV_PLANE_BPP_EXT 0x331A -#define EGL_YUV_PLANE_BPP_0_EXT 0x331B -#define EGL_YUV_PLANE_BPP_8_EXT 0x331C -#define EGL_YUV_PLANE_BPP_10_EXT 0x331D - -#define EGLEW_EXT_yuv_surface EGLEW_GET_VAR(__EGLEW_EXT_yuv_surface) - -#endif /* EGL_EXT_yuv_surface */ - -/* -------------------------- EGL_HI_clientpixmap -------------------------- */ - -#ifndef EGL_HI_clientpixmap -#define EGL_HI_clientpixmap 1 - -#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 - -typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); - -#define eglCreatePixmapSurfaceHI EGLEW_GET_FUN(__eglewCreatePixmapSurfaceHI) - -#define EGLEW_HI_clientpixmap EGLEW_GET_VAR(__EGLEW_HI_clientpixmap) - -#endif /* EGL_HI_clientpixmap */ - -/* -------------------------- EGL_HI_colorformats -------------------------- */ - -#ifndef EGL_HI_colorformats -#define EGL_HI_colorformats 1 - -#define EGL_COLOR_FORMAT_HI 0x8F70 -#define EGL_COLOR_RGB_HI 0x8F71 -#define EGL_COLOR_RGBA_HI 0x8F72 -#define EGL_COLOR_ARGB_HI 0x8F73 - -#define EGLEW_HI_colorformats EGLEW_GET_VAR(__EGLEW_HI_colorformats) - -#endif /* EGL_HI_colorformats */ - -/* ------------------------ EGL_IMG_context_priority ----------------------- */ - -#ifndef EGL_IMG_context_priority -#define EGL_IMG_context_priority 1 - -#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 -#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 -#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 -#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 - -#define EGLEW_IMG_context_priority EGLEW_GET_VAR(__EGLEW_IMG_context_priority) - -#endif /* EGL_IMG_context_priority */ - -/* ---------------------- EGL_IMG_image_plane_attribs ---------------------- */ - -#ifndef EGL_IMG_image_plane_attribs -#define EGL_IMG_image_plane_attribs 1 - -#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 -#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 - -#define EGLEW_IMG_image_plane_attribs EGLEW_GET_VAR(__EGLEW_IMG_image_plane_attribs) - -#endif /* EGL_IMG_image_plane_attribs */ - -/* ---------------------------- EGL_KHR_cl_event --------------------------- */ - -#ifndef EGL_KHR_cl_event -#define EGL_KHR_cl_event 1 - -#define EGL_CL_EVENT_HANDLE_KHR 0x309C -#define EGL_SYNC_CL_EVENT_KHR 0x30FE -#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF - -#define EGLEW_KHR_cl_event EGLEW_GET_VAR(__EGLEW_KHR_cl_event) - -#endif /* EGL_KHR_cl_event */ - -/* --------------------------- EGL_KHR_cl_event2 --------------------------- */ - -#ifndef EGL_KHR_cl_event2 -#define EGL_KHR_cl_event2 1 - -#define EGL_CL_EVENT_HANDLE_KHR 0x309C -#define EGL_SYNC_CL_EVENT_KHR 0x30FE -#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF - -typedef EGLSyncKHR ( * PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR* attrib_list); - -#define eglCreateSync64KHR EGLEW_GET_FUN(__eglewCreateSync64KHR) - -#define EGLEW_KHR_cl_event2 EGLEW_GET_VAR(__EGLEW_KHR_cl_event2) - -#endif /* EGL_KHR_cl_event2 */ - -/* ----------------- EGL_KHR_client_get_all_proc_addresses ----------------- */ - -#ifndef EGL_KHR_client_get_all_proc_addresses -#define EGL_KHR_client_get_all_proc_addresses 1 - -#define EGLEW_KHR_client_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_client_get_all_proc_addresses) - -#endif /* EGL_KHR_client_get_all_proc_addresses */ - -/* ------------------------- EGL_KHR_config_attribs ------------------------ */ - -#ifndef EGL_KHR_config_attribs -#define EGL_KHR_config_attribs 1 - -#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 -#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 -#define EGL_CONFORMANT_KHR 0x3042 - -#define EGLEW_KHR_config_attribs EGLEW_GET_VAR(__EGLEW_KHR_config_attribs) - -#endif /* EGL_KHR_config_attribs */ - -/* --------------------- EGL_KHR_context_flush_control --------------------- */ - -#ifndef EGL_KHR_context_flush_control -#define EGL_KHR_context_flush_control 1 - -#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 -#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 -#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 - -#define EGLEW_KHR_context_flush_control EGLEW_GET_VAR(__EGLEW_KHR_context_flush_control) - -#endif /* EGL_KHR_context_flush_control */ - -/* ------------------------- EGL_KHR_create_context ------------------------ */ - -#ifndef EGL_KHR_create_context -#define EGL_KHR_create_context 1 - -#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -#define EGL_OPENGL_ES3_BIT 0x00000040 -#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 -#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -#define EGL_CONTEXT_FLAGS_KHR 0x30FC -#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF - -#define EGLEW_KHR_create_context EGLEW_GET_VAR(__EGLEW_KHR_create_context) - -#endif /* EGL_KHR_create_context */ - -/* -------------------- EGL_KHR_create_context_no_error -------------------- */ - -#ifndef EGL_KHR_create_context_no_error -#define EGL_KHR_create_context_no_error 1 - -#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 - -#define EGLEW_KHR_create_context_no_error EGLEW_GET_VAR(__EGLEW_KHR_create_context_no_error) - -#endif /* EGL_KHR_create_context_no_error */ - -/* ----------------------------- EGL_KHR_debug ----------------------------- */ - -#ifndef EGL_KHR_debug -#define EGL_KHR_debug 1 - -#define EGL_OBJECT_THREAD_KHR 0x33B0 -#define EGL_OBJECT_DISPLAY_KHR 0x33B1 -#define EGL_OBJECT_CONTEXT_KHR 0x33B2 -#define EGL_OBJECT_SURFACE_KHR 0x33B3 -#define EGL_OBJECT_IMAGE_KHR 0x33B4 -#define EGL_OBJECT_SYNC_KHR 0x33B5 -#define EGL_OBJECT_STREAM_KHR 0x33B6 -#define EGL_DEBUG_CALLBACK_KHR 0x33B8 -#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 -#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA -#define EGL_DEBUG_MSG_WARN_KHR 0x33BB -#define EGL_DEBUG_MSG_INFO_KHR 0x33BC - -typedef EGLint ( * PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib* attrib_list); -typedef EGLint ( * PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); -typedef EGLBoolean ( * PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib* value); - -#define eglDebugMessageControlKHR EGLEW_GET_FUN(__eglewDebugMessageControlKHR) -#define eglLabelObjectKHR EGLEW_GET_FUN(__eglewLabelObjectKHR) -#define eglQueryDebugKHR EGLEW_GET_FUN(__eglewQueryDebugKHR) - -#define EGLEW_KHR_debug EGLEW_GET_VAR(__EGLEW_KHR_debug) - -#endif /* EGL_KHR_debug */ - -/* ----------------------- EGL_KHR_display_reference ----------------------- */ - -#ifndef EGL_KHR_display_reference -#define EGL_KHR_display_reference 1 - -#define EGL_TRACK_REFERENCES_KHR 0x3352 - -typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib* value); - -#define eglQueryDisplayAttribKHR EGLEW_GET_FUN(__eglewQueryDisplayAttribKHR) - -#define EGLEW_KHR_display_reference EGLEW_GET_VAR(__EGLEW_KHR_display_reference) - -#endif /* EGL_KHR_display_reference */ - -/* --------------------------- EGL_KHR_fence_sync -------------------------- */ - -#ifndef EGL_KHR_fence_sync -#define EGL_KHR_fence_sync 1 - -#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 -#define EGL_SYNC_CONDITION_KHR 0x30F8 -#define EGL_SYNC_FENCE_KHR 0x30F9 - -#define EGLEW_KHR_fence_sync EGLEW_GET_VAR(__EGLEW_KHR_fence_sync) - -#endif /* EGL_KHR_fence_sync */ - -/* --------------------- EGL_KHR_get_all_proc_addresses -------------------- */ - -#ifndef EGL_KHR_get_all_proc_addresses -#define EGL_KHR_get_all_proc_addresses 1 - -#define EGLEW_KHR_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_get_all_proc_addresses) - -#endif /* EGL_KHR_get_all_proc_addresses */ - -/* ------------------------- EGL_KHR_gl_colorspace ------------------------- */ - -#ifndef EGL_KHR_gl_colorspace -#define EGL_KHR_gl_colorspace 1 - -#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 -#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A -#define EGL_GL_COLORSPACE_KHR 0x309D - -#define EGLEW_KHR_gl_colorspace EGLEW_GET_VAR(__EGLEW_KHR_gl_colorspace) - -#endif /* EGL_KHR_gl_colorspace */ - -/* --------------------- EGL_KHR_gl_renderbuffer_image --------------------- */ - -#ifndef EGL_KHR_gl_renderbuffer_image -#define EGL_KHR_gl_renderbuffer_image 1 - -#define EGL_GL_RENDERBUFFER_KHR 0x30B9 - -#define EGLEW_KHR_gl_renderbuffer_image EGLEW_GET_VAR(__EGLEW_KHR_gl_renderbuffer_image) - -#endif /* EGL_KHR_gl_renderbuffer_image */ - -/* ---------------------- EGL_KHR_gl_texture_2D_image ---------------------- */ - -#ifndef EGL_KHR_gl_texture_2D_image -#define EGL_KHR_gl_texture_2D_image 1 - -#define EGL_GL_TEXTURE_2D_KHR 0x30B1 -#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC - -#define EGLEW_KHR_gl_texture_2D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_2D_image) - -#endif /* EGL_KHR_gl_texture_2D_image */ - -/* ---------------------- EGL_KHR_gl_texture_3D_image ---------------------- */ - -#ifndef EGL_KHR_gl_texture_3D_image -#define EGL_KHR_gl_texture_3D_image 1 - -#define EGL_GL_TEXTURE_3D_KHR 0x30B2 -#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD - -#define EGLEW_KHR_gl_texture_3D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_3D_image) - -#endif /* EGL_KHR_gl_texture_3D_image */ - -/* -------------------- EGL_KHR_gl_texture_cubemap_image ------------------- */ - -#ifndef EGL_KHR_gl_texture_cubemap_image -#define EGL_KHR_gl_texture_cubemap_image 1 - -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 - -#define EGLEW_KHR_gl_texture_cubemap_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_cubemap_image) - -#endif /* EGL_KHR_gl_texture_cubemap_image */ - -/* ----------------------------- EGL_KHR_image ----------------------------- */ - -#ifndef EGL_KHR_image -#define EGL_KHR_image 1 - -#define EGL_NATIVE_PIXMAP_KHR 0x30B0 - -typedef EGLImageKHR ( * PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); - -#define eglCreateImageKHR EGLEW_GET_FUN(__eglewCreateImageKHR) -#define eglDestroyImageKHR EGLEW_GET_FUN(__eglewDestroyImageKHR) - -#define EGLEW_KHR_image EGLEW_GET_VAR(__EGLEW_KHR_image) - -#endif /* EGL_KHR_image */ - -/* --------------------------- EGL_KHR_image_base -------------------------- */ - -#ifndef EGL_KHR_image_base -#define EGL_KHR_image_base 1 - -#define EGL_IMAGE_PRESERVED_KHR 0x30D2 - -#define EGLEW_KHR_image_base EGLEW_GET_VAR(__EGLEW_KHR_image_base) - -#endif /* EGL_KHR_image_base */ - -/* -------------------------- EGL_KHR_image_pixmap ------------------------- */ - -#ifndef EGL_KHR_image_pixmap -#define EGL_KHR_image_pixmap 1 - -#define EGL_NATIVE_PIXMAP_KHR 0x30B0 - -#define EGLEW_KHR_image_pixmap EGLEW_GET_VAR(__EGLEW_KHR_image_pixmap) - -#endif /* EGL_KHR_image_pixmap */ - -/* -------------------------- EGL_KHR_lock_surface ------------------------- */ - -#ifndef EGL_KHR_lock_surface -#define EGL_KHR_lock_surface 1 - -#define EGL_READ_SURFACE_BIT_KHR 0x0001 -#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 -#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 -#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 -#define EGL_MATCH_FORMAT_KHR 0x3043 -#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 -#define EGL_FORMAT_RGB_565_KHR 0x30C1 -#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 -#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 -#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 -#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 -#define EGL_BITMAP_POINTER_KHR 0x30C6 -#define EGL_BITMAP_PITCH_KHR 0x30C7 -#define EGL_BITMAP_ORIGIN_KHR 0x30C8 -#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 -#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA -#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB -#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC -#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD -#define EGL_LOWER_LEFT_KHR 0x30CE -#define EGL_UPPER_LEFT_KHR 0x30CF - -typedef EGLBoolean ( * PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); - -#define eglLockSurfaceKHR EGLEW_GET_FUN(__eglewLockSurfaceKHR) -#define eglUnlockSurfaceKHR EGLEW_GET_FUN(__eglewUnlockSurfaceKHR) - -#define EGLEW_KHR_lock_surface EGLEW_GET_VAR(__EGLEW_KHR_lock_surface) - -#endif /* EGL_KHR_lock_surface */ - -/* ------------------------- EGL_KHR_lock_surface2 ------------------------- */ - -#ifndef EGL_KHR_lock_surface2 -#define EGL_KHR_lock_surface2 1 - -#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 - -#define EGLEW_KHR_lock_surface2 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface2) - -#endif /* EGL_KHR_lock_surface2 */ - -/* ------------------------- EGL_KHR_lock_surface3 ------------------------- */ - -#ifndef EGL_KHR_lock_surface3 -#define EGL_KHR_lock_surface3 1 - -#define EGL_READ_SURFACE_BIT_KHR 0x0001 -#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 -#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 -#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 -#define EGL_MATCH_FORMAT_KHR 0x3043 -#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 -#define EGL_FORMAT_RGB_565_KHR 0x30C1 -#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 -#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 -#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 -#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 -#define EGL_BITMAP_POINTER_KHR 0x30C6 -#define EGL_BITMAP_PITCH_KHR 0x30C7 -#define EGL_BITMAP_ORIGIN_KHR 0x30C8 -#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 -#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA -#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB -#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC -#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD -#define EGL_LOWER_LEFT_KHR 0x30CE -#define EGL_UPPER_LEFT_KHR 0x30CF -#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 - -typedef EGLBoolean ( * PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR * value); - -#define eglQuerySurface64KHR EGLEW_GET_FUN(__eglewQuerySurface64KHR) - -#define EGLEW_KHR_lock_surface3 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface3) - -#endif /* EGL_KHR_lock_surface3 */ - -/* --------------------- EGL_KHR_mutable_render_buffer --------------------- */ - -#ifndef EGL_KHR_mutable_render_buffer -#define EGL_KHR_mutable_render_buffer 1 - -#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 - -#define EGLEW_KHR_mutable_render_buffer EGLEW_GET_VAR(__EGLEW_KHR_mutable_render_buffer) - -#endif /* EGL_KHR_mutable_render_buffer */ - -/* ----------------------- EGL_KHR_no_config_context ----------------------- */ - -#ifndef EGL_KHR_no_config_context -#define EGL_KHR_no_config_context 1 - -#define EGLEW_KHR_no_config_context EGLEW_GET_VAR(__EGLEW_KHR_no_config_context) - -#endif /* EGL_KHR_no_config_context */ - -/* ------------------------- EGL_KHR_partial_update ------------------------ */ - -#ifndef EGL_KHR_partial_update -#define EGL_KHR_partial_update 1 - -#define EGL_BUFFER_AGE_KHR 0x313D - -typedef EGLBoolean ( * PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint* rects, EGLint n_rects); - -#define eglSetDamageRegionKHR EGLEW_GET_FUN(__eglewSetDamageRegionKHR) - -#define EGLEW_KHR_partial_update EGLEW_GET_VAR(__EGLEW_KHR_partial_update) - -#endif /* EGL_KHR_partial_update */ - -/* ------------------------ EGL_KHR_platform_android ----------------------- */ - -#ifndef EGL_KHR_platform_android -#define EGL_KHR_platform_android 1 - -#define EGL_PLATFORM_ANDROID_KHR 0x3141 - -#define EGLEW_KHR_platform_android EGLEW_GET_VAR(__EGLEW_KHR_platform_android) - -#endif /* EGL_KHR_platform_android */ - -/* -------------------------- EGL_KHR_platform_gbm ------------------------- */ - -#ifndef EGL_KHR_platform_gbm -#define EGL_KHR_platform_gbm 1 - -#define EGL_PLATFORM_GBM_KHR 0x31D7 - -#define EGLEW_KHR_platform_gbm EGLEW_GET_VAR(__EGLEW_KHR_platform_gbm) - -#endif /* EGL_KHR_platform_gbm */ - -/* ------------------------ EGL_KHR_platform_wayland ----------------------- */ - -#ifndef EGL_KHR_platform_wayland -#define EGL_KHR_platform_wayland 1 - -#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 - -#define EGLEW_KHR_platform_wayland EGLEW_GET_VAR(__EGLEW_KHR_platform_wayland) - -#endif /* EGL_KHR_platform_wayland */ - -/* -------------------------- EGL_KHR_platform_x11 ------------------------- */ - -#ifndef EGL_KHR_platform_x11 -#define EGL_KHR_platform_x11 1 - -#define EGL_PLATFORM_X11_KHR 0x31D5 -#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 - -#define EGLEW_KHR_platform_x11 EGLEW_GET_VAR(__EGLEW_KHR_platform_x11) - -#endif /* EGL_KHR_platform_x11 */ - -/* ------------------------- EGL_KHR_reusable_sync ------------------------- */ - -#ifndef EGL_KHR_reusable_sync -#define EGL_KHR_reusable_sync 1 - -#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 -#define EGL_SYNC_STATUS_KHR 0x30F1 -#define EGL_SIGNALED_KHR 0x30F2 -#define EGL_UNSIGNALED_KHR 0x30F3 -#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 -#define EGL_CONDITION_SATISFIED_KHR 0x30F6 -#define EGL_SYNC_TYPE_KHR 0x30F7 -#define EGL_SYNC_REUSABLE_KHR 0x30FA -#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFF - -typedef EGLint ( * PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); -typedef EGLSyncKHR ( * PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); -typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint* value); -typedef EGLBoolean ( * PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); - -#define eglClientWaitSyncKHR EGLEW_GET_FUN(__eglewClientWaitSyncKHR) -#define eglCreateSyncKHR EGLEW_GET_FUN(__eglewCreateSyncKHR) -#define eglDestroySyncKHR EGLEW_GET_FUN(__eglewDestroySyncKHR) -#define eglGetSyncAttribKHR EGLEW_GET_FUN(__eglewGetSyncAttribKHR) -#define eglSignalSyncKHR EGLEW_GET_FUN(__eglewSignalSyncKHR) - -#define EGLEW_KHR_reusable_sync EGLEW_GET_VAR(__EGLEW_KHR_reusable_sync) - -#endif /* EGL_KHR_reusable_sync */ - -/* ----------------------------- EGL_KHR_stream ---------------------------- */ - -#ifndef EGL_KHR_stream -#define EGL_KHR_stream 1 - -#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 -#define EGL_PRODUCER_FRAME_KHR 0x3212 -#define EGL_CONSUMER_FRAME_KHR 0x3213 -#define EGL_STREAM_STATE_KHR 0x3214 -#define EGL_STREAM_STATE_CREATED_KHR 0x3215 -#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 -#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 -#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 -#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 -#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A -#define EGL_BAD_STREAM_KHR 0x321B -#define EGL_BAD_STATE_KHR 0x321C - -typedef EGLStreamKHR ( * PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean ( * PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint* value); -typedef EGLBoolean ( * PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR* value); -typedef EGLBoolean ( * PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); - -#define eglCreateStreamKHR EGLEW_GET_FUN(__eglewCreateStreamKHR) -#define eglDestroyStreamKHR EGLEW_GET_FUN(__eglewDestroyStreamKHR) -#define eglQueryStreamKHR EGLEW_GET_FUN(__eglewQueryStreamKHR) -#define eglQueryStreamu64KHR EGLEW_GET_FUN(__eglewQueryStreamu64KHR) -#define eglStreamAttribKHR EGLEW_GET_FUN(__eglewStreamAttribKHR) - -#define EGLEW_KHR_stream EGLEW_GET_VAR(__EGLEW_KHR_stream) - -#endif /* EGL_KHR_stream */ - -/* ------------------------- EGL_KHR_stream_attrib ------------------------- */ - -#ifndef EGL_KHR_stream_attrib -#define EGL_KHR_stream_attrib 1 - -#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 -#define EGL_STREAM_STATE_KHR 0x3214 -#define EGL_STREAM_STATE_CREATED_KHR 0x3215 -#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 - -typedef EGLStreamKHR ( * PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib* attrib_list); -typedef EGLBoolean ( * PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib* value); -typedef EGLBoolean ( * PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list); -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list); - -#define eglCreateStreamAttribKHR EGLEW_GET_FUN(__eglewCreateStreamAttribKHR) -#define eglQueryStreamAttribKHR EGLEW_GET_FUN(__eglewQueryStreamAttribKHR) -#define eglSetStreamAttribKHR EGLEW_GET_FUN(__eglewSetStreamAttribKHR) -#define eglStreamConsumerAcquireAttribKHR EGLEW_GET_FUN(__eglewStreamConsumerAcquireAttribKHR) -#define eglStreamConsumerReleaseAttribKHR EGLEW_GET_FUN(__eglewStreamConsumerReleaseAttribKHR) - -#define EGLEW_KHR_stream_attrib EGLEW_GET_VAR(__EGLEW_KHR_stream_attrib) - -#endif /* EGL_KHR_stream_attrib */ - -/* ------------------- EGL_KHR_stream_consumer_gltexture ------------------- */ - -#ifndef EGL_KHR_stream_consumer_gltexture -#define EGL_KHR_stream_consumer_gltexture 1 - -#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E - -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); - -#define eglStreamConsumerAcquireKHR EGLEW_GET_FUN(__eglewStreamConsumerAcquireKHR) -#define eglStreamConsumerGLTextureExternalKHR EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalKHR) -#define eglStreamConsumerReleaseKHR EGLEW_GET_FUN(__eglewStreamConsumerReleaseKHR) - -#define EGLEW_KHR_stream_consumer_gltexture EGLEW_GET_VAR(__EGLEW_KHR_stream_consumer_gltexture) - -#endif /* EGL_KHR_stream_consumer_gltexture */ - -/* -------------------- EGL_KHR_stream_cross_process_fd -------------------- */ - -#ifndef EGL_KHR_stream_cross_process_fd -#define EGL_KHR_stream_cross_process_fd 1 - -typedef EGLStreamKHR ( * PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); -typedef EGLNativeFileDescriptorKHR ( * PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); - -#define eglCreateStreamFromFileDescriptorKHR EGLEW_GET_FUN(__eglewCreateStreamFromFileDescriptorKHR) -#define eglGetStreamFileDescriptorKHR EGLEW_GET_FUN(__eglewGetStreamFileDescriptorKHR) - -#define EGLEW_KHR_stream_cross_process_fd EGLEW_GET_VAR(__EGLEW_KHR_stream_cross_process_fd) - -#endif /* EGL_KHR_stream_cross_process_fd */ - -/* -------------------------- EGL_KHR_stream_fifo -------------------------- */ - -#ifndef EGL_KHR_stream_fifo -#define EGL_KHR_stream_fifo 1 - -#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC -#define EGL_STREAM_TIME_NOW_KHR 0x31FD -#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE -#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF - -typedef EGLBoolean ( * PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR* value); - -#define eglQueryStreamTimeKHR EGLEW_GET_FUN(__eglewQueryStreamTimeKHR) - -#define EGLEW_KHR_stream_fifo EGLEW_GET_VAR(__EGLEW_KHR_stream_fifo) - -#endif /* EGL_KHR_stream_fifo */ - -/* ----------------- EGL_KHR_stream_producer_aldatalocator ----------------- */ - -#ifndef EGL_KHR_stream_producer_aldatalocator -#define EGL_KHR_stream_producer_aldatalocator 1 - -#define EGLEW_KHR_stream_producer_aldatalocator EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_aldatalocator) - -#endif /* EGL_KHR_stream_producer_aldatalocator */ - -/* ------------------- EGL_KHR_stream_producer_eglsurface ------------------ */ - -#ifndef EGL_KHR_stream_producer_eglsurface -#define EGL_KHR_stream_producer_eglsurface 1 - -#define EGL_STREAM_BIT_KHR 0x0800 - -typedef EGLSurface ( * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint* attrib_list); - -#define eglCreateStreamProducerSurfaceKHR EGLEW_GET_FUN(__eglewCreateStreamProducerSurfaceKHR) - -#define EGLEW_KHR_stream_producer_eglsurface EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_eglsurface) - -#endif /* EGL_KHR_stream_producer_eglsurface */ - -/* ---------------------- EGL_KHR_surfaceless_context ---------------------- */ - -#ifndef EGL_KHR_surfaceless_context -#define EGL_KHR_surfaceless_context 1 - -#define EGLEW_KHR_surfaceless_context EGLEW_GET_VAR(__EGLEW_KHR_surfaceless_context) - -#endif /* EGL_KHR_surfaceless_context */ - -/* -------------------- EGL_KHR_swap_buffers_with_damage ------------------- */ - -#ifndef EGL_KHR_swap_buffers_with_damage -#define EGL_KHR_swap_buffers_with_damage 1 - -typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint* rects, EGLint n_rects); - -#define eglSwapBuffersWithDamageKHR EGLEW_GET_FUN(__eglewSwapBuffersWithDamageKHR) - -#define EGLEW_KHR_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_KHR_swap_buffers_with_damage) - -#endif /* EGL_KHR_swap_buffers_with_damage */ - -/* ------------------------ EGL_KHR_vg_parent_image ------------------------ */ - -#ifndef EGL_KHR_vg_parent_image -#define EGL_KHR_vg_parent_image 1 - -#define EGL_VG_PARENT_IMAGE_KHR 0x30BA - -#define EGLEW_KHR_vg_parent_image EGLEW_GET_VAR(__EGLEW_KHR_vg_parent_image) - -#endif /* EGL_KHR_vg_parent_image */ - -/* --------------------------- EGL_KHR_wait_sync --------------------------- */ - -#ifndef EGL_KHR_wait_sync -#define EGL_KHR_wait_sync 1 - -typedef EGLint ( * PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); - -#define eglWaitSyncKHR EGLEW_GET_FUN(__eglewWaitSyncKHR) - -#define EGLEW_KHR_wait_sync EGLEW_GET_VAR(__EGLEW_KHR_wait_sync) - -#endif /* EGL_KHR_wait_sync */ - -/* --------------------------- EGL_MESA_drm_image -------------------------- */ - -#ifndef EGL_MESA_drm_image -#define EGL_MESA_drm_image 1 - -#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 -#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 -#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 -#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 -#define EGL_DRM_BUFFER_USE_MESA 0x31D1 -#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 -#define EGL_DRM_BUFFER_MESA 0x31D3 -#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 - -typedef EGLImageKHR ( * PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint* name, EGLint* handle, EGLint* stride); - -#define eglCreateDRMImageMESA EGLEW_GET_FUN(__eglewCreateDRMImageMESA) -#define eglExportDRMImageMESA EGLEW_GET_FUN(__eglewExportDRMImageMESA) - -#define EGLEW_MESA_drm_image EGLEW_GET_VAR(__EGLEW_MESA_drm_image) - -#endif /* EGL_MESA_drm_image */ - -/* --------------------- EGL_MESA_image_dma_buf_export --------------------- */ - -#ifndef EGL_MESA_image_dma_buf_export -#define EGL_MESA_image_dma_buf_export 1 - -typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int* fds, EGLint* strides, EGLint* offsets); -typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int* fourcc, int* num_planes, EGLuint64KHR* modifiers); - -#define eglExportDMABUFImageMESA EGLEW_GET_FUN(__eglewExportDMABUFImageMESA) -#define eglExportDMABUFImageQueryMESA EGLEW_GET_FUN(__eglewExportDMABUFImageQueryMESA) - -#define EGLEW_MESA_image_dma_buf_export EGLEW_GET_VAR(__EGLEW_MESA_image_dma_buf_export) - -#endif /* EGL_MESA_image_dma_buf_export */ - -/* ------------------------- EGL_MESA_platform_gbm ------------------------- */ - -#ifndef EGL_MESA_platform_gbm -#define EGL_MESA_platform_gbm 1 - -#define EGL_PLATFORM_GBM_MESA 0x31D7 - -#define EGLEW_MESA_platform_gbm EGLEW_GET_VAR(__EGLEW_MESA_platform_gbm) - -#endif /* EGL_MESA_platform_gbm */ - -/* --------------------- EGL_MESA_platform_surfaceless --------------------- */ - -#ifndef EGL_MESA_platform_surfaceless -#define EGL_MESA_platform_surfaceless 1 - -#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD - -#define EGLEW_MESA_platform_surfaceless EGLEW_GET_VAR(__EGLEW_MESA_platform_surfaceless) - -#endif /* EGL_MESA_platform_surfaceless */ - -/* ------------------------- EGL_MESA_query_driver ------------------------- */ - -#ifndef EGL_MESA_query_driver -#define EGL_MESA_query_driver 1 - -typedef char* ( * PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); -typedef const char* ( * PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); - -#define eglGetDisplayDriverConfig EGLEW_GET_FUN(__eglewGetDisplayDriverConfig) -#define eglGetDisplayDriverName EGLEW_GET_FUN(__eglewGetDisplayDriverName) - -#define EGLEW_MESA_query_driver EGLEW_GET_VAR(__EGLEW_MESA_query_driver) - -#endif /* EGL_MESA_query_driver */ - -/* -------------------------- EGL_NOK_swap_region -------------------------- */ - -#ifndef EGL_NOK_swap_region -#define EGL_NOK_swap_region 1 - -typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects); - -#define eglSwapBuffersRegionNOK EGLEW_GET_FUN(__eglewSwapBuffersRegionNOK) - -#define EGLEW_NOK_swap_region EGLEW_GET_VAR(__EGLEW_NOK_swap_region) - -#endif /* EGL_NOK_swap_region */ - -/* -------------------------- EGL_NOK_swap_region2 ------------------------- */ - -#ifndef EGL_NOK_swap_region2 -#define EGL_NOK_swap_region2 1 - -typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects); - -#define eglSwapBuffersRegion2NOK EGLEW_GET_FUN(__eglewSwapBuffersRegion2NOK) - -#define EGLEW_NOK_swap_region2 EGLEW_GET_VAR(__EGLEW_NOK_swap_region2) - -#endif /* EGL_NOK_swap_region2 */ - -/* ---------------------- EGL_NOK_texture_from_pixmap ---------------------- */ - -#ifndef EGL_NOK_texture_from_pixmap -#define EGL_NOK_texture_from_pixmap 1 - -#define EGL_Y_INVERTED_NOK 0x307F - -#define EGLEW_NOK_texture_from_pixmap EGLEW_GET_VAR(__EGLEW_NOK_texture_from_pixmap) - -#endif /* EGL_NOK_texture_from_pixmap */ - -/* ------------------------ EGL_NV_3dvision_surface ------------------------ */ - -#ifndef EGL_NV_3dvision_surface -#define EGL_NV_3dvision_surface 1 - -#define EGL_AUTO_STEREO_NV 0x3136 - -#define EGLEW_NV_3dvision_surface EGLEW_GET_VAR(__EGLEW_NV_3dvision_surface) - -#endif /* EGL_NV_3dvision_surface */ - -/* -------------------- EGL_NV_context_priority_realtime ------------------- */ - -#ifndef EGL_NV_context_priority_realtime -#define EGL_NV_context_priority_realtime 1 - -#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 - -#define EGLEW_NV_context_priority_realtime EGLEW_GET_VAR(__EGLEW_NV_context_priority_realtime) - -#endif /* EGL_NV_context_priority_realtime */ - -/* ------------------------- EGL_NV_coverage_sample ------------------------ */ - -#ifndef EGL_NV_coverage_sample -#define EGL_NV_coverage_sample 1 - -#define EGL_COVERAGE_BUFFERS_NV 0x30E0 -#define EGL_COVERAGE_SAMPLES_NV 0x30E1 - -#define EGLEW_NV_coverage_sample EGLEW_GET_VAR(__EGLEW_NV_coverage_sample) - -#endif /* EGL_NV_coverage_sample */ - -/* --------------------- EGL_NV_coverage_sample_resolve -------------------- */ - -#ifndef EGL_NV_coverage_sample_resolve -#define EGL_NV_coverage_sample_resolve 1 - -#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 -#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 -#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 - -#define EGLEW_NV_coverage_sample_resolve EGLEW_GET_VAR(__EGLEW_NV_coverage_sample_resolve) - -#endif /* EGL_NV_coverage_sample_resolve */ - -/* --------------------------- EGL_NV_cuda_event --------------------------- */ - -#ifndef EGL_NV_cuda_event -#define EGL_NV_cuda_event 1 - -#define EGL_CUDA_EVENT_HANDLE_NV 0x323B -#define EGL_SYNC_CUDA_EVENT_NV 0x323C -#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D - -#define EGLEW_NV_cuda_event EGLEW_GET_VAR(__EGLEW_NV_cuda_event) - -#endif /* EGL_NV_cuda_event */ - -/* ------------------------- EGL_NV_depth_nonlinear ------------------------ */ - -#ifndef EGL_NV_depth_nonlinear -#define EGL_NV_depth_nonlinear 1 - -#define EGL_DEPTH_ENCODING_NONE_NV 0 -#define EGL_DEPTH_ENCODING_NV 0x30E2 -#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 - -#define EGLEW_NV_depth_nonlinear EGLEW_GET_VAR(__EGLEW_NV_depth_nonlinear) - -#endif /* EGL_NV_depth_nonlinear */ - -/* --------------------------- EGL_NV_device_cuda -------------------------- */ - -#ifndef EGL_NV_device_cuda -#define EGL_NV_device_cuda 1 - -#define EGL_CUDA_DEVICE_NV 0x323A - -#define EGLEW_NV_device_cuda EGLEW_GET_VAR(__EGLEW_NV_device_cuda) - -#endif /* EGL_NV_device_cuda */ - -/* -------------------------- EGL_NV_native_query -------------------------- */ - -#ifndef EGL_NV_native_query -#define EGL_NV_native_query 1 - -typedef EGLBoolean ( * PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType* display_id); -typedef EGLBoolean ( * PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType* pixmap); -typedef EGLBoolean ( * PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType* window); - -#define eglQueryNativeDisplayNV EGLEW_GET_FUN(__eglewQueryNativeDisplayNV) -#define eglQueryNativePixmapNV EGLEW_GET_FUN(__eglewQueryNativePixmapNV) -#define eglQueryNativeWindowNV EGLEW_GET_FUN(__eglewQueryNativeWindowNV) - -#define EGLEW_NV_native_query EGLEW_GET_VAR(__EGLEW_NV_native_query) - -#endif /* EGL_NV_native_query */ - -/* ---------------------- EGL_NV_post_convert_rounding --------------------- */ - -#ifndef EGL_NV_post_convert_rounding -#define EGL_NV_post_convert_rounding 1 - -#define EGLEW_NV_post_convert_rounding EGLEW_GET_VAR(__EGLEW_NV_post_convert_rounding) - -#endif /* EGL_NV_post_convert_rounding */ - -/* ------------------------- EGL_NV_post_sub_buffer ------------------------ */ - -#ifndef EGL_NV_post_sub_buffer -#define EGL_NV_post_sub_buffer 1 - -#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE - -typedef EGLBoolean ( * PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); - -#define eglPostSubBufferNV EGLEW_GET_FUN(__eglewPostSubBufferNV) - -#define EGLEW_NV_post_sub_buffer EGLEW_GET_VAR(__EGLEW_NV_post_sub_buffer) - -#endif /* EGL_NV_post_sub_buffer */ - -/* ------------------------ EGL_NV_quadruple_buffer ------------------------ */ - -#ifndef EGL_NV_quadruple_buffer -#define EGL_NV_quadruple_buffer 1 - -#define EGL_QUADRUPLE_BUFFER_NV 0x3231 - -#define EGLEW_NV_quadruple_buffer EGLEW_GET_VAR(__EGLEW_NV_quadruple_buffer) - -#endif /* EGL_NV_quadruple_buffer */ - -/* ------------------ EGL_NV_robustness_video_memory_purge ----------------- */ - -#ifndef EGL_NV_robustness_video_memory_purge -#define EGL_NV_robustness_video_memory_purge 1 - -#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C - -#define EGLEW_NV_robustness_video_memory_purge EGLEW_GET_VAR(__EGLEW_NV_robustness_video_memory_purge) - -#endif /* EGL_NV_robustness_video_memory_purge */ - -/* ------------------ EGL_NV_stream_consumer_gltexture_yuv ----------------- */ - -#ifndef EGL_NV_stream_consumer_gltexture_yuv -#define EGL_NV_stream_consumer_gltexture_yuv 1 - -#define EGL_YUV_BUFFER_EXT 0x3300 -#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 -#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C -#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D -#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E - -typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list); - -#define eglStreamConsumerGLTextureExternalAttribsNV EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalAttribsNV) - -#define EGLEW_NV_stream_consumer_gltexture_yuv EGLEW_GET_VAR(__EGLEW_NV_stream_consumer_gltexture_yuv) - -#endif /* EGL_NV_stream_consumer_gltexture_yuv */ - -/* ---------------------- EGL_NV_stream_cross_display ---------------------- */ - -#ifndef EGL_NV_stream_cross_display -#define EGL_NV_stream_cross_display 1 - -#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E - -#define EGLEW_NV_stream_cross_display EGLEW_GET_VAR(__EGLEW_NV_stream_cross_display) - -#endif /* EGL_NV_stream_cross_display */ - -/* ----------------------- EGL_NV_stream_cross_object ---------------------- */ - -#ifndef EGL_NV_stream_cross_object -#define EGL_NV_stream_cross_object 1 - -#define EGL_STREAM_CROSS_OBJECT_NV 0x334D - -#define EGLEW_NV_stream_cross_object EGLEW_GET_VAR(__EGLEW_NV_stream_cross_object) - -#endif /* EGL_NV_stream_cross_object */ - -/* --------------------- EGL_NV_stream_cross_partition --------------------- */ - -#ifndef EGL_NV_stream_cross_partition -#define EGL_NV_stream_cross_partition 1 - -#define EGL_STREAM_CROSS_PARTITION_NV 0x323F - -#define EGLEW_NV_stream_cross_partition EGLEW_GET_VAR(__EGLEW_NV_stream_cross_partition) - -#endif /* EGL_NV_stream_cross_partition */ - -/* ---------------------- EGL_NV_stream_cross_process ---------------------- */ - -#ifndef EGL_NV_stream_cross_process -#define EGL_NV_stream_cross_process 1 - -#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 - -#define EGLEW_NV_stream_cross_process EGLEW_GET_VAR(__EGLEW_NV_stream_cross_process) - -#endif /* EGL_NV_stream_cross_process */ - -/* ----------------------- EGL_NV_stream_cross_system ---------------------- */ - -#ifndef EGL_NV_stream_cross_system -#define EGL_NV_stream_cross_system 1 - -#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F - -#define EGLEW_NV_stream_cross_system EGLEW_GET_VAR(__EGLEW_NV_stream_cross_system) - -#endif /* EGL_NV_stream_cross_system */ - -/* --------------------------- EGL_NV_stream_dma --------------------------- */ - -#ifndef EGL_NV_stream_dma -#define EGL_NV_stream_dma 1 - -#define EGL_STREAM_DMA_NV 0x3371 -#define EGL_STREAM_DMA_SERVER_NV 0x3372 - -#define EGLEW_NV_stream_dma EGLEW_GET_VAR(__EGLEW_NV_stream_dma) - -#endif /* EGL_NV_stream_dma */ - -/* ------------------------ EGL_NV_stream_fifo_next ------------------------ */ - -#ifndef EGL_NV_stream_fifo_next -#define EGL_NV_stream_fifo_next 1 - -#define EGL_PENDING_FRAME_NV 0x3329 -#define EGL_STREAM_TIME_PENDING_NV 0x332A - -#define EGLEW_NV_stream_fifo_next EGLEW_GET_VAR(__EGLEW_NV_stream_fifo_next) - -#endif /* EGL_NV_stream_fifo_next */ - -/* --------------------- EGL_NV_stream_fifo_synchronous -------------------- */ - -#ifndef EGL_NV_stream_fifo_synchronous -#define EGL_NV_stream_fifo_synchronous 1 - -#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 - -#define EGLEW_NV_stream_fifo_synchronous EGLEW_GET_VAR(__EGLEW_NV_stream_fifo_synchronous) - -#endif /* EGL_NV_stream_fifo_synchronous */ - -/* -------------------------- EGL_NV_stream_flush -------------------------- */ - -#ifndef EGL_NV_stream_flush -#define EGL_NV_stream_flush 1 - -typedef EGLBoolean ( * PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); - -#define eglStreamFlushNV EGLEW_GET_FUN(__eglewStreamFlushNV) - -#define EGLEW_NV_stream_flush EGLEW_GET_VAR(__EGLEW_NV_stream_flush) - -#endif /* EGL_NV_stream_flush */ - -/* ----------------------- EGL_NV_stream_frame_limits ---------------------- */ - -#ifndef EGL_NV_stream_frame_limits -#define EGL_NV_stream_frame_limits 1 - -#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 -#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 - -#define EGLEW_NV_stream_frame_limits EGLEW_GET_VAR(__EGLEW_NV_stream_frame_limits) - -#endif /* EGL_NV_stream_frame_limits */ - -/* ------------------------- EGL_NV_stream_metadata ------------------------ */ - -#ifndef EGL_NV_stream_metadata -#define EGL_NV_stream_metadata 1 - -#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 -#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 -#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 -#define EGL_PRODUCER_METADATA_NV 0x3253 -#define EGL_CONSUMER_METADATA_NV 0x3254 -#define EGL_METADATA0_SIZE_NV 0x3255 -#define EGL_METADATA1_SIZE_NV 0x3256 -#define EGL_METADATA2_SIZE_NV 0x3257 -#define EGL_METADATA3_SIZE_NV 0x3258 -#define EGL_METADATA0_TYPE_NV 0x3259 -#define EGL_METADATA1_TYPE_NV 0x325A -#define EGL_METADATA2_TYPE_NV 0x325B -#define EGL_METADATA3_TYPE_NV 0x325C -#define EGL_PENDING_METADATA_NV 0x3328 - -typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib* value); -typedef EGLBoolean ( * PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void* data); -typedef EGLBoolean ( * PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void* data); - -#define eglQueryDisplayAttribNV EGLEW_GET_FUN(__eglewQueryDisplayAttribNV) -#define eglQueryStreamMetadataNV EGLEW_GET_FUN(__eglewQueryStreamMetadataNV) -#define eglSetStreamMetadataNV EGLEW_GET_FUN(__eglewSetStreamMetadataNV) - -#define EGLEW_NV_stream_metadata EGLEW_GET_VAR(__EGLEW_NV_stream_metadata) - -#endif /* EGL_NV_stream_metadata */ - -/* -------------------------- EGL_NV_stream_origin ------------------------- */ - -#ifndef EGL_NV_stream_origin -#define EGL_NV_stream_origin 1 - -#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 -#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 -#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 -#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 -#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A -#define EGL_LEFT_NV 0x336B -#define EGL_RIGHT_NV 0x336C -#define EGL_TOP_NV 0x336D -#define EGL_BOTTOM_NV 0x336E -#define EGL_X_AXIS_NV 0x336F -#define EGL_Y_AXIS_NV 0x3370 - -#define EGLEW_NV_stream_origin EGLEW_GET_VAR(__EGLEW_NV_stream_origin) - -#endif /* EGL_NV_stream_origin */ - -/* -------------------------- EGL_NV_stream_remote ------------------------- */ - -#ifndef EGL_NV_stream_remote -#define EGL_NV_stream_remote 1 - -#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 -#define EGL_STREAM_TYPE_NV 0x3241 -#define EGL_STREAM_PROTOCOL_NV 0x3242 -#define EGL_STREAM_ENDPOINT_NV 0x3243 -#define EGL_STREAM_LOCAL_NV 0x3244 -#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 -#define EGL_STREAM_PRODUCER_NV 0x3247 -#define EGL_STREAM_CONSUMER_NV 0x3248 - -#define EGLEW_NV_stream_remote EGLEW_GET_VAR(__EGLEW_NV_stream_remote) - -#endif /* EGL_NV_stream_remote */ - -/* -------------------------- EGL_NV_stream_reset -------------------------- */ - -#ifndef EGL_NV_stream_reset -#define EGL_NV_stream_reset 1 - -#define EGL_SUPPORT_RESET_NV 0x3334 -#define EGL_SUPPORT_REUSE_NV 0x3335 - -typedef EGLBoolean ( * PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); - -#define eglResetStreamNV EGLEW_GET_FUN(__eglewResetStreamNV) - -#define EGLEW_NV_stream_reset EGLEW_GET_VAR(__EGLEW_NV_stream_reset) - -#endif /* EGL_NV_stream_reset */ - -/* -------------------------- EGL_NV_stream_socket ------------------------- */ - -#ifndef EGL_NV_stream_socket -#define EGL_NV_stream_socket 1 - -#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B -#define EGL_SOCKET_HANDLE_NV 0x324C -#define EGL_SOCKET_TYPE_NV 0x324D - -#define EGLEW_NV_stream_socket EGLEW_GET_VAR(__EGLEW_NV_stream_socket) - -#endif /* EGL_NV_stream_socket */ - -/* ----------------------- EGL_NV_stream_socket_inet ----------------------- */ - -#ifndef EGL_NV_stream_socket_inet -#define EGL_NV_stream_socket_inet 1 - -#define EGL_SOCKET_TYPE_INET_NV 0x324F - -#define EGLEW_NV_stream_socket_inet EGLEW_GET_VAR(__EGLEW_NV_stream_socket_inet) - -#endif /* EGL_NV_stream_socket_inet */ - -/* ----------------------- EGL_NV_stream_socket_unix ----------------------- */ - -#ifndef EGL_NV_stream_socket_unix -#define EGL_NV_stream_socket_unix 1 - -#define EGL_SOCKET_TYPE_UNIX_NV 0x324E - -#define EGLEW_NV_stream_socket_unix EGLEW_GET_VAR(__EGLEW_NV_stream_socket_unix) - -#endif /* EGL_NV_stream_socket_unix */ - -/* --------------------------- EGL_NV_stream_sync -------------------------- */ - -#ifndef EGL_NV_stream_sync -#define EGL_NV_stream_sync 1 - -#define EGL_SYNC_TYPE_KHR 0x30F7 -#define EGL_SYNC_NEW_FRAME_NV 0x321F - -typedef EGLSyncKHR ( * PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint* attrib_list); - -#define eglCreateStreamSyncNV EGLEW_GET_FUN(__eglewCreateStreamSyncNV) - -#define EGLEW_NV_stream_sync EGLEW_GET_VAR(__EGLEW_NV_stream_sync) - -#endif /* EGL_NV_stream_sync */ - -/* ------------------------------ EGL_NV_sync ------------------------------ */ - -#ifndef EGL_NV_sync -#define EGL_NV_sync 1 - -#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 -#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 -#define EGL_SYNC_STATUS_NV 0x30E7 -#define EGL_SIGNALED_NV 0x30E8 -#define EGL_UNSIGNALED_NV 0x30E9 -#define EGL_ALREADY_SIGNALED_NV 0x30EA -#define EGL_TIMEOUT_EXPIRED_NV 0x30EB -#define EGL_CONDITION_SATISFIED_NV 0x30EC -#define EGL_SYNC_TYPE_NV 0x30ED -#define EGL_SYNC_CONDITION_NV 0x30EE -#define EGL_SYNC_FENCE_NV 0x30EF -#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFF - -typedef EGLint ( * PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); -typedef EGLSyncNV ( * PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint* attrib_list); -typedef EGLBoolean ( * PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); -typedef EGLBoolean ( * PFNEGLFENCENVPROC) (EGLSyncNV sync); -typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint* value); -typedef EGLBoolean ( * PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); - -#define eglClientWaitSyncNV EGLEW_GET_FUN(__eglewClientWaitSyncNV) -#define eglCreateFenceSyncNV EGLEW_GET_FUN(__eglewCreateFenceSyncNV) -#define eglDestroySyncNV EGLEW_GET_FUN(__eglewDestroySyncNV) -#define eglFenceNV EGLEW_GET_FUN(__eglewFenceNV) -#define eglGetSyncAttribNV EGLEW_GET_FUN(__eglewGetSyncAttribNV) -#define eglSignalSyncNV EGLEW_GET_FUN(__eglewSignalSyncNV) - -#define EGLEW_NV_sync EGLEW_GET_VAR(__EGLEW_NV_sync) - -#endif /* EGL_NV_sync */ - -/* --------------------------- EGL_NV_system_time -------------------------- */ - -#ifndef EGL_NV_system_time -#define EGL_NV_system_time 1 - -typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); -typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMENVPROC) (void); - -#define eglGetSystemTimeFrequencyNV EGLEW_GET_FUN(__eglewGetSystemTimeFrequencyNV) -#define eglGetSystemTimeNV EGLEW_GET_FUN(__eglewGetSystemTimeNV) - -#define EGLEW_NV_system_time EGLEW_GET_VAR(__EGLEW_NV_system_time) - -#endif /* EGL_NV_system_time */ - -/* -------------------------- EGL_NV_triple_buffer ------------------------- */ - -#ifndef EGL_NV_triple_buffer -#define EGL_NV_triple_buffer 1 - -#define EGL_TRIPLE_BUFFER_NV 0x3230 - -#define EGLEW_NV_triple_buffer EGLEW_GET_VAR(__EGLEW_NV_triple_buffer) - -#endif /* EGL_NV_triple_buffer */ - -/* --------------------- EGL_TIZEN_image_native_buffer --------------------- */ - -#ifndef EGL_TIZEN_image_native_buffer -#define EGL_TIZEN_image_native_buffer 1 - -#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 - -#define EGLEW_TIZEN_image_native_buffer EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_buffer) - -#endif /* EGL_TIZEN_image_native_buffer */ - -/* --------------------- EGL_TIZEN_image_native_surface -------------------- */ - -#ifndef EGL_TIZEN_image_native_surface -#define EGL_TIZEN_image_native_surface 1 - -#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 - -#define EGLEW_TIZEN_image_native_surface EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_surface) - -#endif /* EGL_TIZEN_image_native_surface */ - -/* ---------------------- EGL_WL_bind_wayland_display ---------------------- */ - -#ifndef EGL_WL_bind_wayland_display -#define EGL_WL_bind_wayland_display 1 - -#define EGL_WAYLAND_BUFFER_WL 0x31D5 -#define EGL_WAYLAND_PLANE_WL 0x31D6 -#define EGL_TEXTURE_Y_U_V_WL 0x31D7 -#define EGL_TEXTURE_Y_UV_WL 0x31D8 -#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 -#define EGL_TEXTURE_EXTERNAL_WL 0x31DA -#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB - -typedef EGLBoolean ( * PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display* display); -typedef EGLBoolean ( * PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource* buffer, EGLint attribute, EGLint* value); -typedef EGLBoolean ( * PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display* display); - -#define eglBindWaylandDisplayWL EGLEW_GET_FUN(__eglewBindWaylandDisplayWL) -#define eglQueryWaylandBufferWL EGLEW_GET_FUN(__eglewQueryWaylandBufferWL) -#define eglUnbindWaylandDisplayWL EGLEW_GET_FUN(__eglewUnbindWaylandDisplayWL) - -#define EGLEW_WL_bind_wayland_display EGLEW_GET_VAR(__EGLEW_WL_bind_wayland_display) - -#endif /* EGL_WL_bind_wayland_display */ - -/* ---------------- EGL_WL_create_wayland_buffer_from_image ---------------- */ - -#ifndef EGL_WL_create_wayland_buffer_from_image -#define EGL_WL_create_wayland_buffer_from_image 1 - -typedef struct wl_buffer* ( * PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); - -#define eglCreateWaylandBufferFromImageWL EGLEW_GET_FUN(__eglewCreateWaylandBufferFromImageWL) - -#define EGLEW_WL_create_wayland_buffer_from_image EGLEW_GET_VAR(__EGLEW_WL_create_wayland_buffer_from_image) - -#endif /* EGL_WL_create_wayland_buffer_from_image */ - -/* ------------------------------------------------------------------------- */ - -#define EGLEW_FUN_EXPORT GLEW_FUN_EXPORT -#define EGLEW_VAR_EXPORT GLEW_VAR_EXPORT - -EGLEW_FUN_EXPORT PFNEGLCHOOSECONFIGPROC __eglewChooseConfig; -EGLEW_FUN_EXPORT PFNEGLCOPYBUFFERSPROC __eglewCopyBuffers; -EGLEW_FUN_EXPORT PFNEGLCREATECONTEXTPROC __eglewCreateContext; -EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERSURFACEPROC __eglewCreatePbufferSurface; -EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEPROC __eglewCreatePixmapSurface; -EGLEW_FUN_EXPORT PFNEGLCREATEWINDOWSURFACEPROC __eglewCreateWindowSurface; -EGLEW_FUN_EXPORT PFNEGLDESTROYCONTEXTPROC __eglewDestroyContext; -EGLEW_FUN_EXPORT PFNEGLDESTROYSURFACEPROC __eglewDestroySurface; -EGLEW_FUN_EXPORT PFNEGLGETCONFIGATTRIBPROC __eglewGetConfigAttrib; -EGLEW_FUN_EXPORT PFNEGLGETCONFIGSPROC __eglewGetConfigs; -EGLEW_FUN_EXPORT PFNEGLGETCURRENTDISPLAYPROC __eglewGetCurrentDisplay; -EGLEW_FUN_EXPORT PFNEGLGETCURRENTSURFACEPROC __eglewGetCurrentSurface; -EGLEW_FUN_EXPORT PFNEGLGETDISPLAYPROC __eglewGetDisplay; -EGLEW_FUN_EXPORT PFNEGLGETERRORPROC __eglewGetError; -EGLEW_FUN_EXPORT PFNEGLINITIALIZEPROC __eglewInitialize; -EGLEW_FUN_EXPORT PFNEGLMAKECURRENTPROC __eglewMakeCurrent; -EGLEW_FUN_EXPORT PFNEGLQUERYCONTEXTPROC __eglewQueryContext; -EGLEW_FUN_EXPORT PFNEGLQUERYSTRINGPROC __eglewQueryString; -EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPROC __eglewQuerySurface; -EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSPROC __eglewSwapBuffers; -EGLEW_FUN_EXPORT PFNEGLTERMINATEPROC __eglewTerminate; -EGLEW_FUN_EXPORT PFNEGLWAITGLPROC __eglewWaitGL; -EGLEW_FUN_EXPORT PFNEGLWAITNATIVEPROC __eglewWaitNative; - -EGLEW_FUN_EXPORT PFNEGLBINDTEXIMAGEPROC __eglewBindTexImage; -EGLEW_FUN_EXPORT PFNEGLRELEASETEXIMAGEPROC __eglewReleaseTexImage; -EGLEW_FUN_EXPORT PFNEGLSURFACEATTRIBPROC __eglewSurfaceAttrib; -EGLEW_FUN_EXPORT PFNEGLSWAPINTERVALPROC __eglewSwapInterval; - -EGLEW_FUN_EXPORT PFNEGLBINDAPIPROC __eglewBindAPI; -EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC __eglewCreatePbufferFromClientBuffer; -EGLEW_FUN_EXPORT PFNEGLQUERYAPIPROC __eglewQueryAPI; -EGLEW_FUN_EXPORT PFNEGLRELEASETHREADPROC __eglewReleaseThread; -EGLEW_FUN_EXPORT PFNEGLWAITCLIENTPROC __eglewWaitClient; - -EGLEW_FUN_EXPORT PFNEGLGETCURRENTCONTEXTPROC __eglewGetCurrentContext; - -EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCPROC __eglewClientWaitSync; -EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEPROC __eglewCreateImage; -EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC __eglewCreatePlatformPixmapSurface; -EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEPROC __eglewCreatePlatformWindowSurface; -EGLEW_FUN_EXPORT PFNEGLCREATESYNCPROC __eglewCreateSync; -EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEPROC __eglewDestroyImage; -EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCPROC __eglewDestroySync; -EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYPROC __eglewGetPlatformDisplay; -EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBPROC __eglewGetSyncAttrib; -EGLEW_FUN_EXPORT PFNEGLWAITSYNCPROC __eglewWaitSync; - -EGLEW_FUN_EXPORT PFNEGLSETBLOBCACHEFUNCSANDROIDPROC __eglewSetBlobCacheFuncsANDROID; - -EGLEW_FUN_EXPORT PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC __eglewCreateNativeClientBufferANDROID; - -EGLEW_FUN_EXPORT PFNEGLGETCOMPOSITORTIMINGANDROIDPROC __eglewGetCompositorTimingANDROID; -EGLEW_FUN_EXPORT PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC __eglewGetCompositorTimingSupportedANDROID; -EGLEW_FUN_EXPORT PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC __eglewGetFrameTimestampSupportedANDROID; -EGLEW_FUN_EXPORT PFNEGLGETFRAMETIMESTAMPSANDROIDPROC __eglewGetFrameTimestampsANDROID; -EGLEW_FUN_EXPORT PFNEGLGETNEXTFRAMEIDANDROIDPROC __eglewGetNextFrameIdANDROID; - -EGLEW_FUN_EXPORT PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC __eglewGetNativeClientBufferANDROID; - -EGLEW_FUN_EXPORT PFNEGLDUPNATIVEFENCEFDANDROIDPROC __eglewDupNativeFenceFDANDROID; - -EGLEW_FUN_EXPORT PFNEGLPRESENTATIONTIMEANDROIDPROC __eglewPresentationTimeANDROID; - -EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPOINTERANGLEPROC __eglewQuerySurfacePointerANGLE; - -EGLEW_FUN_EXPORT PFNEGLCLIENTSIGNALSYNCEXTPROC __eglewClientSignalSyncEXT; - -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC __eglewCompositorBindTexWindowEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC __eglewCompositorSetContextAttributesEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC __eglewCompositorSetContextListEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSETSIZEEXTPROC __eglewCompositorSetSizeEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC __eglewCompositorSetWindowAttributesEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC __eglewCompositorSetWindowListEXT; -EGLEW_FUN_EXPORT PFNEGLCOMPOSITORSWAPPOLICYEXTPROC __eglewCompositorSwapPolicyEXT; - -EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESEXTPROC __eglewQueryDevicesEXT; - -EGLEW_FUN_EXPORT PFNEGLQUERYDEVICEATTRIBEXTPROC __eglewQueryDeviceAttribEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESTRINGEXTPROC __eglewQueryDeviceStringEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBEXTPROC __eglewQueryDisplayAttribEXT; - -EGLEW_FUN_EXPORT PFNEGLQUERYDMABUFFORMATSEXTPROC __eglewQueryDmaBufFormatsEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYDMABUFMODIFIERSEXTPROC __eglewQueryDmaBufModifiersEXT; - -EGLEW_FUN_EXPORT PFNEGLGETOUTPUTLAYERSEXTPROC __eglewGetOutputLayersEXT; -EGLEW_FUN_EXPORT PFNEGLGETOUTPUTPORTSEXTPROC __eglewGetOutputPortsEXT; -EGLEW_FUN_EXPORT PFNEGLOUTPUTLAYERATTRIBEXTPROC __eglewOutputLayerAttribEXT; -EGLEW_FUN_EXPORT PFNEGLOUTPUTPORTATTRIBEXTPROC __eglewOutputPortAttribEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC __eglewQueryOutputLayerAttribEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC __eglewQueryOutputLayerStringEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC __eglewQueryOutputPortAttribEXT; -EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC __eglewQueryOutputPortStringEXT; - -EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC __eglewCreatePlatformPixmapSurfaceEXT; -EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC __eglewCreatePlatformWindowSurfaceEXT; -EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYEXTPROC __eglewGetPlatformDisplayEXT; - -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMEROUTPUTEXTPROC __eglewStreamConsumerOutputEXT; - -EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC __eglewSwapBuffersWithDamageEXT; - -EGLEW_FUN_EXPORT PFNEGLUNSIGNALSYNCEXTPROC __eglewUnsignalSyncEXT; - -EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEHIPROC __eglewCreatePixmapSurfaceHI; - -EGLEW_FUN_EXPORT PFNEGLCREATESYNC64KHRPROC __eglewCreateSync64KHR; - -EGLEW_FUN_EXPORT PFNEGLDEBUGMESSAGECONTROLKHRPROC __eglewDebugMessageControlKHR; -EGLEW_FUN_EXPORT PFNEGLLABELOBJECTKHRPROC __eglewLabelObjectKHR; -EGLEW_FUN_EXPORT PFNEGLQUERYDEBUGKHRPROC __eglewQueryDebugKHR; - -EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBKHRPROC __eglewQueryDisplayAttribKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEKHRPROC __eglewCreateImageKHR; -EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEKHRPROC __eglewDestroyImageKHR; - -EGLEW_FUN_EXPORT PFNEGLLOCKSURFACEKHRPROC __eglewLockSurfaceKHR; -EGLEW_FUN_EXPORT PFNEGLUNLOCKSURFACEKHRPROC __eglewUnlockSurfaceKHR; - -EGLEW_FUN_EXPORT PFNEGLQUERYSURFACE64KHRPROC __eglewQuerySurface64KHR; - -EGLEW_FUN_EXPORT PFNEGLSETDAMAGEREGIONKHRPROC __eglewSetDamageRegionKHR; - -EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCKHRPROC __eglewClientWaitSyncKHR; -EGLEW_FUN_EXPORT PFNEGLCREATESYNCKHRPROC __eglewCreateSyncKHR; -EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCKHRPROC __eglewDestroySyncKHR; -EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBKHRPROC __eglewGetSyncAttribKHR; -EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCKHRPROC __eglewSignalSyncKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATESTREAMKHRPROC __eglewCreateStreamKHR; -EGLEW_FUN_EXPORT PFNEGLDESTROYSTREAMKHRPROC __eglewDestroyStreamKHR; -EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMKHRPROC __eglewQueryStreamKHR; -EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMU64KHRPROC __eglewQueryStreamu64KHR; -EGLEW_FUN_EXPORT PFNEGLSTREAMATTRIBKHRPROC __eglewStreamAttribKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATESTREAMATTRIBKHRPROC __eglewCreateStreamAttribKHR; -EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMATTRIBKHRPROC __eglewQueryStreamAttribKHR; -EGLEW_FUN_EXPORT PFNEGLSETSTREAMATTRIBKHRPROC __eglewSetStreamAttribKHR; -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC __eglewStreamConsumerAcquireAttribKHR; -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC __eglewStreamConsumerReleaseAttribKHR; - -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERACQUIREKHRPROC __eglewStreamConsumerAcquireKHR; -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC __eglewStreamConsumerGLTextureExternalKHR; -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERRELEASEKHRPROC __eglewStreamConsumerReleaseKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC __eglewCreateStreamFromFileDescriptorKHR; -EGLEW_FUN_EXPORT PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC __eglewGetStreamFileDescriptorKHR; - -EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMTIMEKHRPROC __eglewQueryStreamTimeKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC __eglewCreateStreamProducerSurfaceKHR; - -EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC __eglewSwapBuffersWithDamageKHR; - -EGLEW_FUN_EXPORT PFNEGLWAITSYNCKHRPROC __eglewWaitSyncKHR; - -EGLEW_FUN_EXPORT PFNEGLCREATEDRMIMAGEMESAPROC __eglewCreateDRMImageMESA; -EGLEW_FUN_EXPORT PFNEGLEXPORTDRMIMAGEMESAPROC __eglewExportDRMImageMESA; - -EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEMESAPROC __eglewExportDMABUFImageMESA; -EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC __eglewExportDMABUFImageQueryMESA; - -EGLEW_FUN_EXPORT PFNEGLGETDISPLAYDRIVERCONFIGPROC __eglewGetDisplayDriverConfig; -EGLEW_FUN_EXPORT PFNEGLGETDISPLAYDRIVERNAMEPROC __eglewGetDisplayDriverName; - -EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGIONNOKPROC __eglewSwapBuffersRegionNOK; - -EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGION2NOKPROC __eglewSwapBuffersRegion2NOK; - -EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEDISPLAYNVPROC __eglewQueryNativeDisplayNV; -EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEPIXMAPNVPROC __eglewQueryNativePixmapNV; -EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEWINDOWNVPROC __eglewQueryNativeWindowNV; - -EGLEW_FUN_EXPORT PFNEGLPOSTSUBBUFFERNVPROC __eglewPostSubBufferNV; - -EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC __eglewStreamConsumerGLTextureExternalAttribsNV; - -EGLEW_FUN_EXPORT PFNEGLSTREAMFLUSHNVPROC __eglewStreamFlushNV; - -EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBNVPROC __eglewQueryDisplayAttribNV; -EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMMETADATANVPROC __eglewQueryStreamMetadataNV; -EGLEW_FUN_EXPORT PFNEGLSETSTREAMMETADATANVPROC __eglewSetStreamMetadataNV; - -EGLEW_FUN_EXPORT PFNEGLRESETSTREAMNVPROC __eglewResetStreamNV; - -EGLEW_FUN_EXPORT PFNEGLCREATESTREAMSYNCNVPROC __eglewCreateStreamSyncNV; - -EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCNVPROC __eglewClientWaitSyncNV; -EGLEW_FUN_EXPORT PFNEGLCREATEFENCESYNCNVPROC __eglewCreateFenceSyncNV; -EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCNVPROC __eglewDestroySyncNV; -EGLEW_FUN_EXPORT PFNEGLFENCENVPROC __eglewFenceNV; -EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBNVPROC __eglewGetSyncAttribNV; -EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCNVPROC __eglewSignalSyncNV; - -EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC __eglewGetSystemTimeFrequencyNV; -EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMENVPROC __eglewGetSystemTimeNV; - -EGLEW_FUN_EXPORT PFNEGLBINDWAYLANDDISPLAYWLPROC __eglewBindWaylandDisplayWL; -EGLEW_FUN_EXPORT PFNEGLQUERYWAYLANDBUFFERWLPROC __eglewQueryWaylandBufferWL; -EGLEW_FUN_EXPORT PFNEGLUNBINDWAYLANDDISPLAYWLPROC __eglewUnbindWaylandDisplayWL; - -EGLEW_FUN_EXPORT PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC __eglewCreateWaylandBufferFromImageWL; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_0; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_1; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_2; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_3; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_4; -EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_5; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_GLES_layers; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_blob_cache; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_create_native_client_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_framebuffer_target; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_front_buffer_auto_refresh; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_get_frame_timestamps; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_get_native_client_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_image_native_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_native_fence_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_presentation_time; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_recordable; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_d3d_share_handle_client_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_device_d3d; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_query_surface_pointer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_surface_d3d_texture_2d_share_handle; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_window_fixed_size; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_image_format; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_implicit_external_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_pixmap_multisample_discard; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_bind_to_front; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_buffer_age; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_client_extensions; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_client_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_compositor; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_create_context_robustness; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_base; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_drm; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_enumeration; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_openwf; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_query; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_bt2020_linear; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_bt2020_pq; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_display_p3; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_display_p3_linear; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_display_p3_passthrough; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_scrgb; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_scrgb_linear; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_dma_buf_import; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_dma_buf_import_modifiers; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_gl_colorspace; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_implicit_sync_control; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_multiview_window; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_base; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_drm; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_openwf; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_pixel_format_float; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_base; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_device; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_wayland; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_x11; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_content; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_surface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_stream_consumer_egloutput; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_surface_CTA861_3_metadata; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_surface_SMPTE2086_metadata; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_swap_buffers_with_damage; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_sync_reuse; -EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_yuv_surface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_clientpixmap; -EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_colorformats; -EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_context_priority; -EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_image_plane_attribs; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event2; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_client_get_all_proc_addresses; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_config_attribs; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_context_flush_control; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context_no_error; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_debug; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_display_reference; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_fence_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_get_all_proc_addresses; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_colorspace; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_renderbuffer_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_2D_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_3D_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_cubemap_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_base; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_pixmap; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface2; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface3; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_mutable_render_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_no_config_context; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_partial_update; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_android; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_gbm; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_wayland; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_x11; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_reusable_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_attrib; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_consumer_gltexture; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_cross_process_fd; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_fifo; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_aldatalocator; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_eglsurface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_surfaceless_context; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_swap_buffers_with_damage; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_vg_parent_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_wait_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_drm_image; -EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_image_dma_buf_export; -EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_platform_gbm; -EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_platform_surfaceless; -EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_query_driver; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region2; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_texture_from_pixmap; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_3dvision_surface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_context_priority_realtime; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample_resolve; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_cuda_event; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_depth_nonlinear; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_device_cuda; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_native_query; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_convert_rounding; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_sub_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_quadruple_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_robustness_video_memory_purge; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_consumer_gltexture_yuv; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_display; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_object; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_partition; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_process; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_system; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_dma; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_fifo_next; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_fifo_synchronous; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_flush; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_frame_limits; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_metadata; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_origin; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_remote; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_reset; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket_inet; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket_unix; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_sync; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_system_time; -EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_triple_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_buffer; -EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_surface; -EGLEW_VAR_EXPORT GLboolean __EGLEW_WL_bind_wayland_display; -EGLEW_VAR_EXPORT GLboolean __EGLEW_WL_create_wayland_buffer_from_image; -/* ------------------------------------------------------------------------ */ - -GLEWAPI GLenum GLEWAPIENTRY eglewInit (EGLDisplay display); -GLEWAPI GLboolean GLEWAPIENTRY eglewIsSupported (const char *name); - -#define EGLEW_GET_VAR(x) (*(const GLboolean*)&x) -#define EGLEW_GET_FUN(x) x - -GLEWAPI GLboolean GLEWAPIENTRY eglewGetExtension (const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* __eglew_h__ */ diff --git a/sdk/include/GL/glew.h b/sdk/include/GL/glew.h deleted file mode 100644 index 234591bb599..00000000000 --- a/sdk/include/GL/glew.h +++ /dev/null @@ -1,26427 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2008-2019, Nigel Stewart -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __glew_h__ -#define __glew_h__ -#define __GLEW_H__ - -#if defined(__gl_h_) || defined(__GL_H__) || defined(_GL_H) || defined(__X_GL_H) -#error gl.h included before glew.h -#endif -#if defined(__gl2_h_) -#error gl2.h included before glew.h -#endif -#if defined(__gltypes_h_) -#error gltypes.h included before glew.h -#endif -#if defined(__REGAL_H__) -#error Regal.h included before glew.h -#endif -#if defined(__glext_h_) || defined(__GLEXT_H_) || defined(__gl_glext_h_) -#error glext.h included before glew.h -#endif -#if defined(__gl_ATI_h_) -#error glATI.h included before glew.h -#endif - -#define __gl_h_ -#define __gl2_h_ -#define __GL_H__ -#define _GL_H -#define __gltypes_h_ -#define __REGAL_H__ -#define __X_GL_H -#define __glext_h_ -#define __GLEXT_H_ -#define __gl_glext_h_ -#define __gl_ATI_h_ - -#if defined(_WIN32) - -/* - * GLEW does not include to avoid name space pollution. - * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t - * defined properly. - */ -/* and */ -#ifdef APIENTRY -# ifndef GLAPIENTRY -# define GLAPIENTRY APIENTRY -# endif -# ifndef GLEWAPIENTRY -# define GLEWAPIENTRY APIENTRY -# endif -#else -#define GLEW_APIENTRY_DEFINED -# if defined(__MINGW32__) || defined(__CYGWIN__) || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) -# define APIENTRY __stdcall -# ifndef GLAPIENTRY -# define GLAPIENTRY __stdcall -# endif -# ifndef GLEWAPIENTRY -# define GLEWAPIENTRY __stdcall -# endif -# else -# define APIENTRY -# endif -#endif -#ifndef GLAPI -# if defined(__MINGW32__) || defined(__CYGWIN__) -# define GLAPI extern -# endif -#endif -/* */ -#ifndef CALLBACK -#define GLEW_CALLBACK_DEFINED -# if defined(__MINGW32__) || defined(__CYGWIN__) -# define CALLBACK __attribute__ ((__stdcall__)) -# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) -# define CALLBACK __stdcall -# else -# define CALLBACK -# endif -#endif -/* and */ -#ifndef WINGDIAPI -#define GLEW_WINGDIAPI_DEFINED -#define WINGDIAPI __declspec(dllimport) -#endif -/* */ -#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) -typedef unsigned short wchar_t; -# define _WCHAR_T_DEFINED -#endif -/* */ -#if !defined(_W64) -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif -#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) && !defined(__MINGW64__) -# ifdef _WIN64 -typedef __int64 ptrdiff_t; -# else -typedef _W64 int ptrdiff_t; -# endif -# define _PTRDIFF_T_DEFINED -# define _PTRDIFF_T_ -#endif - -#ifndef GLAPI -# if defined(__MINGW32__) || defined(__CYGWIN__) -# define GLAPI extern -# else -# define GLAPI WINGDIAPI -# endif -#endif - -/* - * GLEW_STATIC is defined for static library. - * GLEW_BUILD is defined for building the DLL library. - */ - -#ifdef GLEW_STATIC -# define GLEWAPI extern -#else -# ifdef GLEW_BUILD -# define GLEWAPI extern __declspec(dllexport) -# else -# define GLEWAPI extern __declspec(dllimport) -# endif -#endif - -#else /* _UNIX */ - -/* - * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO - * C. On my system, this amounts to _3 lines_ of included code, all of - * them pretty much harmless. If you know of a way of detecting 32 vs - * 64 _targets_ at compile time you are free to replace this with - * something that's portable. For now, _this_ is the portable solution. - * (mem, 2004-01-04) - */ - -#if defined(__APPLE__) || defined(__linux__) -# if defined(__cplusplus) -# include -# include -# else -# include -# include -# endif -#else - -# include - -/* SGI MIPSPro doesn't like stdint.h in C++ mode */ -/* ID: 3376260 Solaris 9 has inttypes.h, but not stdint.h */ - -# if (defined(__sgi) || defined(__sun)) && !defined(__GNUC__) -# include -# else -# include -# endif -#endif - -#define GLEW_APIENTRY_DEFINED -#define APIENTRY - -/* - * GLEW_STATIC is defined for static library. - */ - -#ifdef GLEW_STATIC -# define GLEWAPI extern -#else -# if defined(__GNUC__) && __GNUC__>=4 -# define GLEWAPI extern __attribute__ ((visibility("default"))) -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define GLEWAPI extern __global -# else -# define GLEWAPI extern -# endif -#endif - -/* */ -#ifndef GLAPI -#define GLAPI extern -#endif - -#endif /* _WIN32 */ - -#ifndef GLAPIENTRY -#define GLAPIENTRY -#endif - -#ifndef GLEWAPIENTRY -#define GLEWAPIENTRY -#endif - -#define GLEW_VAR_EXPORT GLEWAPI -#define GLEW_FUN_EXPORT GLEWAPI - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ - -#ifndef GL_VERSION_1_1 -#define GL_VERSION_1_1 1 - -typedef unsigned int GLenum; -typedef unsigned int GLbitfield; -typedef unsigned int GLuint; -typedef int GLint; -typedef int GLsizei; -typedef unsigned char GLboolean; -typedef signed char GLbyte; -typedef short GLshort; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; -typedef unsigned long GLulong; -typedef float GLfloat; -typedef float GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void GLvoid; -#if defined(_MSC_VER) && _MSC_VER < 1400 -typedef __int64 GLint64EXT; -typedef unsigned __int64 GLuint64EXT; -#elif defined(_MSC_VER) || defined(__BORLANDC__) -typedef signed long long GLint64EXT; -typedef unsigned long long GLuint64EXT; -#else -# if defined(__MINGW32__) || defined(__CYGWIN__) -#include -# endif -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif -typedef GLint64EXT GLint64; -typedef GLuint64EXT GLuint64; -typedef struct __GLsync *GLsync; - -typedef char GLchar; - -typedef void *GLeglImageOES; /* GL_EXT_EGL_image_storage */ - -#define GL_ZERO 0 -#define GL_FALSE 0 -#define GL_LOGIC_OP 0x0BF1 -#define GL_NONE 0 -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_NO_ERROR 0 -#define GL_POINTS 0x0000 -#define GL_CURRENT_BIT 0x00000001 -#define GL_TRUE 1 -#define GL_ONE 1 -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_POINT_BIT 0x00000002 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_LINE_STRIP 0x0003 -#define GL_LINE_BIT 0x00000004 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON 0x0009 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_ACCUM 0x0100 -#define GL_LOAD 0x0101 -#define GL_RETURN 0x0102 -#define GL_MULT 0x0103 -#define GL_ADD 0x0104 -#define GL_NEVER 0x0200 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_EXP 0x0800 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_EXP2 0x0801 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LIST_MODE 0x0B30 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_SHADE_MODEL 0x0B54 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_FOG 0x0B60 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_COLOR 0x0B66 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_NORMALIZE 0x0BA1 -#define GL_VIEWPORT 0x0BA2 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_DITHER 0x0BD0 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND 0x0BE2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_READ_BUFFER 0x0C02 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_INDEX_MODE 0x0C30 -#define GL_RGBA_MODE 0x0C31 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_RENDER_MODE 0x0C40 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_FOG_HINT 0x0C54 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_INDEX_BITS 0x0D51 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_DOUBLE 0x140A -#define GL_CLEAR 0x1500 -#define GL_AND 0x1501 -#define GL_AND_REVERSE 0x1502 -#define GL_COPY 0x1503 -#define GL_AND_INVERTED 0x1504 -#define GL_NOOP 0x1505 -#define GL_XOR 0x1506 -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_EQUIV 0x1509 -#define GL_INVERT 0x150A -#define GL_OR_REVERSE 0x150B -#define GL_COPY_INVERTED 0x150C -#define GL_OR_INVERTED 0x150D -#define GL_NAND 0x150E -#define GL_SET 0x150F -#define GL_EMISSION 0x1600 -#define GL_SHININESS 0x1601 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_TEXTURE 0x1702 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_COLOR_INDEX 0x1900 -#define GL_STENCIL_INDEX 0x1901 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_BITMAP 0x1A00 -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_RENDER 0x1C00 -#define GL_FEEDBACK 0x1C01 -#define GL_SELECT 0x1C02 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_S 0x2000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_MODULATE 0x2100 -#define GL_DECAL 0x2101 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV 0x2300 -#define GL_EYE_LINEAR 0x2400 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_SPHERE_MAP 0x2402 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_PLANE 0x2502 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_CLAMP 0x2900 -#define GL_REPEAT 0x2901 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_R3_G3_B2 0x2A10 -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_LIGHT0 0x4000 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_HINT_BIT 0x00008000 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0x000fffff -#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff - -GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); -GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); -GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI void GLAPIENTRY glArrayElement (GLint i); -GLAPI void GLAPIENTRY glBegin (GLenum mode); -GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); -GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); -GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GLAPI void GLAPIENTRY glCallList (GLuint list); -GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const void *lists); -GLAPI void GLAPIENTRY glClear (GLbitfield mask); -GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); -GLAPI void GLAPIENTRY glClearIndex (GLfloat c); -GLAPI void GLAPIENTRY glClearStencil (GLint s); -GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); -GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); -GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); -GLAPI void GLAPIENTRY glColor3iv (const GLint *v); -GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); -GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); -GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); -GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); -GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); -GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); -GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); -GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); -GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); -GLAPI void GLAPIENTRY glColor4iv (const GLint *v); -GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); -GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); -GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); -GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); -GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); -GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); -GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); -GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); -GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void GLAPIENTRY glCullFace (GLenum mode); -GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); -GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); -GLAPI void GLAPIENTRY glDepthFunc (GLenum func); -GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); -GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); -GLAPI void GLAPIENTRY glDisable (GLenum cap); -GLAPI void GLAPIENTRY glDisableClientState (GLenum array); -GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); -GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); -GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); -GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); -GLAPI void GLAPIENTRY glEnable (GLenum cap); -GLAPI void GLAPIENTRY glEnableClientState (GLenum array); -GLAPI void GLAPIENTRY glEnd (void); -GLAPI void GLAPIENTRY glEndList (void); -GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); -GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); -GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); -GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); -GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); -GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); -GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); -GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); -GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); -GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); -GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); -GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); -GLAPI void GLAPIENTRY glFinish (void); -GLAPI void GLAPIENTRY glFlush (void); -GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glFrontFace (GLenum mode); -GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); -GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); -GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); -GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); -GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); -GLAPI GLenum GLAPIENTRY glGetError (void); -GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); -GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); -GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); -GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); -GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); -GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); -GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, void* *params); -GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); -GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); -GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); -GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); -GLAPI void GLAPIENTRY glIndexMask (GLuint mask); -GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glIndexd (GLdouble c); -GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); -GLAPI void GLAPIENTRY glIndexf (GLfloat c); -GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); -GLAPI void GLAPIENTRY glIndexi (GLint c); -GLAPI void GLAPIENTRY glIndexiv (const GLint *c); -GLAPI void GLAPIENTRY glIndexs (GLshort c); -GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); -GLAPI void GLAPIENTRY glIndexub (GLubyte c); -GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); -GLAPI void GLAPIENTRY glInitNames (void); -GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer); -GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); -GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); -GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); -GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); -GLAPI void GLAPIENTRY glLineWidth (GLfloat width); -GLAPI void GLAPIENTRY glListBase (GLuint base); -GLAPI void GLAPIENTRY glLoadIdentity (void); -GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); -GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); -GLAPI void GLAPIENTRY glLoadName (GLuint name); -GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); -GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); -GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); -GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); -GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); -GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); -GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); -GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); -GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); -GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); -GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); -GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); -GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void GLAPIENTRY glPassThrough (GLfloat token); -GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); -GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); -GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); -GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); -GLAPI void GLAPIENTRY glPointSize (GLfloat size); -GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); -GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); -GLAPI void GLAPIENTRY glPopAttrib (void); -GLAPI void GLAPIENTRY glPopClientAttrib (void); -GLAPI void GLAPIENTRY glPopMatrix (void); -GLAPI void GLAPIENTRY glPopName (void); -GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); -GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); -GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); -GLAPI void GLAPIENTRY glPushMatrix (void); -GLAPI void GLAPIENTRY glPushName (GLuint name); -GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); -GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); -GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); -GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); -GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); -GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); -GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); -GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); -GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); -GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); -GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); -GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); -GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); -GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); -GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); -GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); -GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); -GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); -GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); -GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); -GLAPI void GLAPIENTRY glShadeModel (GLenum mode); -GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GLAPI void GLAPIENTRY glStencilMask (GLuint mask); -GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); -GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); -GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord1i (GLint s); -GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); -GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); -GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); -GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); -GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); -GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); -GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); -GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); -GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); -GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); -GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); -GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); -GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); -GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); -GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); -GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); -GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); -GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); -GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); -GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - -#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) - -#endif /* GL_VERSION_1_1 */ - -/* ---------------------------------- GLU ---------------------------------- */ - -#ifndef GLEW_NO_GLU -# ifdef __APPLE__ -# include -# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -# define GLEW_NO_GLU -# endif -# endif -#endif - -#ifndef GLEW_NO_GLU -/* this is where we can safely include GLU */ -# if defined(__APPLE__) && defined(__MACH__) -# include -# else -# include -# endif -#endif - -/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 - -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_RESCALE_NORMAL 0x803A -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E - -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - -#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) -#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) -#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) -#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) - -#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) - -#endif /* GL_VERSION_1_2 */ - -/* ---------------------------- GL_VERSION_1_2_1 --------------------------- */ - -#ifndef GL_VERSION_1_2_1 -#define GL_VERSION_1_2_1 1 - -#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1) - -#endif /* GL_VERSION_1_2_1 */ - -/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 - -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_SUBTRACT 0x84E7 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_MULTISAMPLE_BIT 0x20000000 - -typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *img); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); - -#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) -#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) -#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) -#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) -#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) -#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) -#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) -#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) -#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) -#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) -#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) -#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) -#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) -#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) -#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) -#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) -#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) -#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) -#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) -#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) -#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) -#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) -#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) -#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) -#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) -#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) -#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) -#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) -#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) -#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) -#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) -#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) -#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) -#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) -#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) -#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) -#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) -#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) -#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) -#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) -#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) -#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) -#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) -#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) -#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) -#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) - -#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) - -#endif /* GL_VERSION_1_3 */ - -/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 - -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_COMPARE_R_TO_TEXTURE 0x884E - -typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); - -#define glBlendColor GLEW_GET_FUN(__glewBlendColor) -#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) -#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) -#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) -#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) -#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) -#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) -#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) -#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) -#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) -#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) -#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) -#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) -#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) -#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) -#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) -#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) -#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) -#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) -#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) -#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) -#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) -#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) -#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) -#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) -#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) -#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) -#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) -#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) -#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) -#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) -#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) -#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) -#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) -#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) -#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) -#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) -#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) -#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) -#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) -#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) -#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) -#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) -#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) -#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) -#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) -#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) - -#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) - -#endif /* GL_VERSION_1_4 */ - -/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 - -#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE -#define GL_FOG_COORD GL_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE -#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA -#define GL_SRC0_RGB GL_SOURCE0_RGB -#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA -#define GL_SRC1_RGB GL_SOURCE1_RGB -#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA -#define GL_SRC2_RGB GL_SOURCE2_RGB -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 - -typedef ptrdiff_t GLintptr; -typedef ptrdiff_t GLsizeiptr; - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void* data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* data); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); -typedef void* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); - -#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) -#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) -#define glBufferData GLEW_GET_FUN(__glewBufferData) -#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) -#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) -#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) -#define glEndQuery GLEW_GET_FUN(__glewEndQuery) -#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) -#define glGenQueries GLEW_GET_FUN(__glewGenQueries) -#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) -#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) -#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) -#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) -#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) -#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) -#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) -#define glIsQuery GLEW_GET_FUN(__glewIsQuery) -#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) -#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) - -#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) - -#endif /* GL_VERSION_1_5 */ - -/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 - -#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 - -typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); -typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); -typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source); -typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void** pointer); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); -typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length); -typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); - -#define glAttachShader GLEW_GET_FUN(__glewAttachShader) -#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) -#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) -#define glCompileShader GLEW_GET_FUN(__glewCompileShader) -#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) -#define glCreateShader GLEW_GET_FUN(__glewCreateShader) -#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) -#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) -#define glDetachShader GLEW_GET_FUN(__glewDetachShader) -#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) -#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) -#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) -#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) -#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) -#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) -#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) -#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) -#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) -#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) -#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) -#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) -#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) -#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) -#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) -#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) -#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) -#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) -#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) -#define glIsProgram GLEW_GET_FUN(__glewIsProgram) -#define glIsShader GLEW_GET_FUN(__glewIsShader) -#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) -#define glShaderSource GLEW_GET_FUN(__glewShaderSource) -#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) -#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) -#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) -#define glUniform1f GLEW_GET_FUN(__glewUniform1f) -#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) -#define glUniform1i GLEW_GET_FUN(__glewUniform1i) -#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) -#define glUniform2f GLEW_GET_FUN(__glewUniform2f) -#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) -#define glUniform2i GLEW_GET_FUN(__glewUniform2i) -#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) -#define glUniform3f GLEW_GET_FUN(__glewUniform3f) -#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) -#define glUniform3i GLEW_GET_FUN(__glewUniform3i) -#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) -#define glUniform4f GLEW_GET_FUN(__glewUniform4f) -#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) -#define glUniform4i GLEW_GET_FUN(__glewUniform4i) -#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) -#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) -#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) -#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) -#define glUseProgram GLEW_GET_FUN(__glewUseProgram) -#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) -#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) -#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) -#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) -#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) -#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) -#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) -#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) -#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) -#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) -#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) -#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) -#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) -#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) -#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) -#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) -#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) -#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) -#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) -#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) -#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) -#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) -#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) -#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) -#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) -#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) -#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) -#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) -#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) -#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) -#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) -#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) -#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) -#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) -#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) -#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) -#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) -#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) - -#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) - -#endif /* GL_VERSION_2_0 */ - -/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 - -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B - -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - -#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) -#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) -#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) -#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) -#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) -#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) - -#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) - -#endif /* GL_VERSION_2_1 */ - -/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 - -#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 -#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 -#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 -#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 -#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 -#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 -#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB -#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES -#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_DEPTH_BUFFER 0x8223 -#define GL_STENCIL_BUFFER 0x8224 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 - -typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawBuffer, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawBuffer, const GLint* value); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawBuffer, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum cap, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum cap, GLuint index); -typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum pname, GLuint index, GLboolean* data); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name); -typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum cap, GLuint index); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort* v0); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void*pointer); - -#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) -#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) -#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) -#define glClampColor GLEW_GET_FUN(__glewClampColor) -#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) -#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) -#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) -#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) -#define glColorMaski GLEW_GET_FUN(__glewColorMaski) -#define glDisablei GLEW_GET_FUN(__glewDisablei) -#define glEnablei GLEW_GET_FUN(__glewEnablei) -#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) -#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) -#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) -#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) -#define glGetStringi GLEW_GET_FUN(__glewGetStringi) -#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) -#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) -#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) -#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) -#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) -#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) -#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) -#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) -#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) -#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) -#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) -#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) -#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) -#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) -#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) -#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) -#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) -#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) -#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) -#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) -#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) -#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) -#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) -#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) -#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) -#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) -#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) -#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) -#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) -#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) -#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) -#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) -#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) -#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) -#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) -#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) -#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) -#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) -#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) - -#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) - -#endif /* GL_VERSION_3_0 */ - -/* ----------------------------- GL_VERSION_3_1 ---------------------------- */ - -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 - -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_RED_SNORM 0x8F90 -#define GL_RG_SNORM 0x8F91 -#define GL_RGB_SNORM 0x8F92 -#define GL_RGBA_SNORM 0x8F93 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalFormat, GLuint buffer); - -#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced) -#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced) -#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex) -#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer) - -#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1) - -#endif /* GL_VERSION_3_1 */ - -/* ----------------------------- GL_VERSION_3_2 ---------------------------- */ - -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 - -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum value, GLint64 * data); -typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum pname, GLuint index, GLint64 * data); - -#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture) -#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v) -#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v) - -#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2) - -#endif /* GL_VERSION_3_2 */ - -/* ----------------------------- GL_VERSION_3_3 ---------------------------- */ - -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_RGB10_A2UI 0x906F - -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); - -#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor) - -#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3) - -#endif /* GL_VERSION_3_3 */ - -/* ----------------------------- GL_VERSION_4_0 ---------------------------- */ - -#ifndef GL_VERSION_4_0 -#define GL_VERSION_4_0 1 - -#define GL_SAMPLE_SHADING 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F -#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); - -#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei) -#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi) -#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei) -#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci) -#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading) - -#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0) - -#endif /* GL_VERSION_4_0 */ - -/* ----------------------------- GL_VERSION_4_1 ---------------------------- */ - -#ifndef GL_VERSION_4_1 -#define GL_VERSION_4_1 1 - -#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1) - -#endif /* GL_VERSION_4_1 */ - -/* ----------------------------- GL_VERSION_4_2 ---------------------------- */ - -#ifndef GL_VERSION_4_2 -#define GL_VERSION_4_2 1 - -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 - -#define GLEW_VERSION_4_2 GLEW_GET_VAR(__GLEW_VERSION_4_2) - -#endif /* GL_VERSION_4_2 */ - -/* ----------------------------- GL_VERSION_4_3 ---------------------------- */ - -#ifndef GL_VERSION_4_3 -#define GL_VERSION_4_3 1 - -#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 -#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E - -#define GLEW_VERSION_4_3 GLEW_GET_VAR(__GLEW_VERSION_4_3) - -#endif /* GL_VERSION_4_3 */ - -/* ----------------------------- GL_VERSION_4_4 ---------------------------- */ - -#ifndef GL_VERSION_4_4 -#define GL_VERSION_4_4 1 - -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 -#define GL_TEXTURE_BUFFER_BINDING 0x8C2A - -#define GLEW_VERSION_4_4 GLEW_GET_VAR(__GLEW_VERSION_4_4) - -#endif /* GL_VERSION_4_4 */ - -/* ----------------------------- GL_VERSION_4_5 ---------------------------- */ - -#ifndef GL_VERSION_4_5 -#define GL_VERSION_4_5 1 - -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 - -typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *pixels); -typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEPROC) (GLenum tex, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); - -#define glGetGraphicsResetStatus GLEW_GET_FUN(__glewGetGraphicsResetStatus) -#define glGetnCompressedTexImage GLEW_GET_FUN(__glewGetnCompressedTexImage) -#define glGetnTexImage GLEW_GET_FUN(__glewGetnTexImage) -#define glGetnUniformdv GLEW_GET_FUN(__glewGetnUniformdv) - -#define GLEW_VERSION_4_5 GLEW_GET_VAR(__GLEW_VERSION_4_5) - -#endif /* GL_VERSION_4_5 */ - -/* ----------------------------- GL_VERSION_4_6 ---------------------------- */ - -#ifndef GL_VERSION_4_6 -#define GL_VERSION_4_6 1 - -#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 -#define GL_PARAMETER_BUFFER 0x80EE -#define GL_PARAMETER_BUFFER_BINDING 0x80EF -#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED -#define GL_VERTICES_SUBMITTED 0x82EE -#define GL_PRIMITIVES_SUBMITTED 0x82EF -#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 -#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 -#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 -#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 -#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 -#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF -#define GL_POLYGON_OFFSET_CLAMP 0x8E1B -#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 -#define GL_SPIR_V_BINARY 0x9552 -#define GL_SPIR_V_EXTENSIONS 0x9553 -#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); - -#define glMultiDrawArraysIndirectCount GLEW_GET_FUN(__glewMultiDrawArraysIndirectCount) -#define glMultiDrawElementsIndirectCount GLEW_GET_FUN(__glewMultiDrawElementsIndirectCount) -#define glSpecializeShader GLEW_GET_FUN(__glewSpecializeShader) - -#define GLEW_VERSION_4_6 GLEW_GET_VAR(__GLEW_VERSION_4_6) - -#endif /* GL_VERSION_4_6 */ - -/* -------------------------- GL_3DFX_multisample -------------------------- */ - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 - -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 - -#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) - -#endif /* GL_3DFX_multisample */ - -/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 - -typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); - -#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) - -#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) - -#endif /* GL_3DFX_tbuffer */ - -/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 - -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 - -#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) - -#endif /* GL_3DFX_texture_compression_FXT1 */ - -/* ----------------------- GL_AMD_blend_minmax_factor ---------------------- */ - -#ifndef GL_AMD_blend_minmax_factor -#define GL_AMD_blend_minmax_factor 1 - -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FACTOR_MAX_AMD 0x901D - -#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor) - -#endif /* GL_AMD_blend_minmax_factor */ - -/* --------------------- GL_AMD_compressed_3DC_texture --------------------- */ - -#ifndef GL_AMD_compressed_3DC_texture -#define GL_AMD_compressed_3DC_texture 1 - -#define GL_3DC_X_AMD 0x87F9 -#define GL_3DC_XY_AMD 0x87FA - -#define GLEW_AMD_compressed_3DC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_3DC_texture) - -#endif /* GL_AMD_compressed_3DC_texture */ - -/* --------------------- GL_AMD_compressed_ATC_texture --------------------- */ - -#ifndef GL_AMD_compressed_ATC_texture -#define GL_AMD_compressed_ATC_texture 1 - -#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#define GL_ATC_RGB_AMD 0x8C92 -#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 - -#define GLEW_AMD_compressed_ATC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_ATC_texture) - -#endif /* GL_AMD_compressed_ATC_texture */ - -/* ----------------------- GL_AMD_conservative_depth ----------------------- */ - -#ifndef GL_AMD_conservative_depth -#define GL_AMD_conservative_depth 1 - -#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth) - -#endif /* GL_AMD_conservative_depth */ - -/* -------------------------- GL_AMD_debug_output -------------------------- */ - -#ifndef GL_AMD_debug_output -#define GL_AMD_debug_output 1 - -#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 -#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 -#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 -#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A -#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B -#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C -#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D -#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E -#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F -#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 - -typedef void (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam); - -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf); -typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message); - -#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD) -#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD) -#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD) -#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD) - -#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output) - -#endif /* GL_AMD_debug_output */ - -/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */ - -#ifndef GL_AMD_depth_clamp_separate -#define GL_AMD_depth_clamp_separate 1 - -#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E -#define GL_DEPTH_CLAMP_FAR_AMD 0x901F - -#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate) - -#endif /* GL_AMD_depth_clamp_separate */ - -/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */ - -#ifndef GL_AMD_draw_buffers_blend -#define GL_AMD_draw_buffers_blend 1 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - -#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD) -#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD) -#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD) -#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD) - -#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend) - -#endif /* GL_AMD_draw_buffers_blend */ - -/* ---------------- GL_AMD_framebuffer_multisample_advanced ---------------- */ - -#ifndef GL_AMD_framebuffer_multisample_advanced -#define GL_AMD_framebuffer_multisample_advanced 1 - -#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 -#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 -#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 -#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 -#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 -#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 - -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glNamedRenderbufferStorageMultisampleAdvancedAMD GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleAdvancedAMD) -#define glRenderbufferStorageMultisampleAdvancedAMD GLEW_GET_FUN(__glewRenderbufferStorageMultisampleAdvancedAMD) - -#define GLEW_AMD_framebuffer_multisample_advanced GLEW_GET_VAR(__GLEW_AMD_framebuffer_multisample_advanced) - -#endif /* GL_AMD_framebuffer_multisample_advanced */ - -/* ------------------ GL_AMD_framebuffer_sample_positions ------------------ */ - -#ifndef GL_AMD_framebuffer_sample_positions -#define GL_AMD_framebuffer_sample_positions 1 - -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F -#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE -#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF -#define GL_ALL_PIXELS_AMD 0xFFFFFFFF - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat* values); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat* values); - -#define glFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewFramebufferSamplePositionsfvAMD) -#define glGetFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetFramebufferParameterfvAMD) -#define glGetNamedFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetNamedFramebufferParameterfvAMD) -#define glNamedFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewNamedFramebufferSamplePositionsfvAMD) - -#define GLEW_AMD_framebuffer_sample_positions GLEW_GET_VAR(__GLEW_AMD_framebuffer_sample_positions) - -#endif /* GL_AMD_framebuffer_sample_positions */ - -/* --------------------------- GL_AMD_gcn_shader --------------------------- */ - -#ifndef GL_AMD_gcn_shader -#define GL_AMD_gcn_shader 1 - -#define GLEW_AMD_gcn_shader GLEW_GET_VAR(__GLEW_AMD_gcn_shader) - -#endif /* GL_AMD_gcn_shader */ - -/* ---------------------- GL_AMD_gpu_shader_half_float --------------------- */ - -#ifndef GL_AMD_gpu_shader_half_float -#define GL_AMD_gpu_shader_half_float 1 - -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB -#define GL_FLOAT16_MAT2_AMD 0x91C5 -#define GL_FLOAT16_MAT3_AMD 0x91C6 -#define GL_FLOAT16_MAT4_AMD 0x91C7 -#define GL_FLOAT16_MAT2x3_AMD 0x91C8 -#define GL_FLOAT16_MAT2x4_AMD 0x91C9 -#define GL_FLOAT16_MAT3x2_AMD 0x91CA -#define GL_FLOAT16_MAT3x4_AMD 0x91CB -#define GL_FLOAT16_MAT4x2_AMD 0x91CC -#define GL_FLOAT16_MAT4x3_AMD 0x91CD - -#define GLEW_AMD_gpu_shader_half_float GLEW_GET_VAR(__GLEW_AMD_gpu_shader_half_float) - -#endif /* GL_AMD_gpu_shader_half_float */ - -/* ------------------- GL_AMD_gpu_shader_half_float_fetch ------------------ */ - -#ifndef GL_AMD_gpu_shader_half_float_fetch -#define GL_AMD_gpu_shader_half_float_fetch 1 - -#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE -#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF -#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0 -#define GL_FLOAT16_SAMPLER_CUBE_AMD 0x91D1 -#define GL_FLOAT16_SAMPLER_2D_RECT_AMD 0x91D2 -#define GL_FLOAT16_SAMPLER_1D_ARRAY_AMD 0x91D3 -#define GL_FLOAT16_SAMPLER_2D_ARRAY_AMD 0x91D4 -#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD 0x91D5 -#define GL_FLOAT16_SAMPLER_BUFFER_AMD 0x91D6 -#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD 0x91D7 -#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD 0x91D8 -#define GL_FLOAT16_SAMPLER_1D_SHADOW_AMD 0x91D9 -#define GL_FLOAT16_SAMPLER_2D_SHADOW_AMD 0x91DA -#define GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD 0x91DB -#define GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD 0x91DC -#define GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD 0x91DD -#define GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD 0x91DE -#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD 0x91DF -#define GL_FLOAT16_IMAGE_1D_AMD 0x91E0 -#define GL_FLOAT16_IMAGE_2D_AMD 0x91E1 -#define GL_FLOAT16_IMAGE_3D_AMD 0x91E2 -#define GL_FLOAT16_IMAGE_2D_RECT_AMD 0x91E3 -#define GL_FLOAT16_IMAGE_CUBE_AMD 0x91E4 -#define GL_FLOAT16_IMAGE_1D_ARRAY_AMD 0x91E5 -#define GL_FLOAT16_IMAGE_2D_ARRAY_AMD 0x91E6 -#define GL_FLOAT16_IMAGE_CUBE_MAP_ARRAY_AMD 0x91E7 -#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8 -#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9 -#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA - -#define GLEW_AMD_gpu_shader_half_float_fetch GLEW_GET_VAR(__GLEW_AMD_gpu_shader_half_float_fetch) - -#endif /* GL_AMD_gpu_shader_half_float_fetch */ - -/* ------------------------ GL_AMD_gpu_shader_int16 ------------------------ */ - -#ifndef GL_AMD_gpu_shader_int16 -#define GL_AMD_gpu_shader_int16 1 - -#define GLEW_AMD_gpu_shader_int16 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int16) - -#endif /* GL_AMD_gpu_shader_int16 */ - -/* ------------------------ GL_AMD_gpu_shader_int64 ------------------------ */ - -#ifndef GL_AMD_gpu_shader_int64 -#define GL_AMD_gpu_shader_int64 1 - -#define GLEW_AMD_gpu_shader_int64 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int64) - -#endif /* GL_AMD_gpu_shader_int64 */ - -/* ---------------------- GL_AMD_interleaved_elements ---------------------- */ - -#ifndef GL_AMD_interleaved_elements -#define GL_AMD_interleaved_elements 1 - -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RG8UI 0x8238 -#define GL_RG16UI 0x823A -#define GL_RGBA8UI 0x8D7C -#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 -#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 - -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); - -#define glVertexAttribParameteriAMD GLEW_GET_FUN(__glewVertexAttribParameteriAMD) - -#define GLEW_AMD_interleaved_elements GLEW_GET_VAR(__GLEW_AMD_interleaved_elements) - -#endif /* GL_AMD_interleaved_elements */ - -/* ----------------------- GL_AMD_multi_draw_indirect ---------------------- */ - -#ifndef GL_AMD_multi_draw_indirect -#define GL_AMD_multi_draw_indirect 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); - -#define glMultiDrawArraysIndirectAMD GLEW_GET_FUN(__glewMultiDrawArraysIndirectAMD) -#define glMultiDrawElementsIndirectAMD GLEW_GET_FUN(__glewMultiDrawElementsIndirectAMD) - -#define GLEW_AMD_multi_draw_indirect GLEW_GET_VAR(__GLEW_AMD_multi_draw_indirect) - -#endif /* GL_AMD_multi_draw_indirect */ - -/* ------------------------- GL_AMD_name_gen_delete ------------------------ */ - -#ifndef GL_AMD_name_gen_delete -#define GL_AMD_name_gen_delete 1 - -#define GL_DATA_BUFFER_AMD 0x9151 -#define GL_PERFORMANCE_MONITOR_AMD 0x9152 -#define GL_QUERY_OBJECT_AMD 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 -#define GL_SAMPLER_OBJECT_AMD 0x9155 - -typedef void (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names); -typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names); -typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); - -#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD) -#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD) -#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD) - -#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete) - -#endif /* GL_AMD_name_gen_delete */ - -/* ---------------------- GL_AMD_occlusion_query_event --------------------- */ - -#ifndef GL_AMD_occlusion_query_event -#define GL_AMD_occlusion_query_event 1 - -#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 -#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 -#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 -#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 -#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F -#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF - -typedef void (GLAPIENTRY * PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); - -#define glQueryObjectParameteruiAMD GLEW_GET_FUN(__glewQueryObjectParameteruiAMD) - -#define GLEW_AMD_occlusion_query_event GLEW_GET_VAR(__GLEW_AMD_occlusion_query_event) - -#endif /* GL_AMD_occlusion_query_event */ - -/* ----------------------- GL_AMD_performance_monitor ---------------------- */ - -#ifndef GL_AMD_performance_monitor -#define GL_AMD_performance_monitor 1 - -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 - -typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); -typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString); -typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); - -#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD) -#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD) -#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD) -#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD) -#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD) -#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD) -#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD) -#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD) -#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD) -#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD) -#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD) - -#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor) - -#endif /* GL_AMD_performance_monitor */ - -/* -------------------------- GL_AMD_pinned_memory ------------------------- */ - -#ifndef GL_AMD_pinned_memory -#define GL_AMD_pinned_memory 1 - -#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 - -#define GLEW_AMD_pinned_memory GLEW_GET_VAR(__GLEW_AMD_pinned_memory) - -#endif /* GL_AMD_pinned_memory */ - -/* ----------------------- GL_AMD_program_binary_Z400 ---------------------- */ - -#ifndef GL_AMD_program_binary_Z400 -#define GL_AMD_program_binary_Z400 1 - -#define GL_Z400_BINARY_AMD 0x8740 - -#define GLEW_AMD_program_binary_Z400 GLEW_GET_VAR(__GLEW_AMD_program_binary_Z400) - -#endif /* GL_AMD_program_binary_Z400 */ - -/* ----------------------- GL_AMD_query_buffer_object ---------------------- */ - -#ifndef GL_AMD_query_buffer_object -#define GL_AMD_query_buffer_object 1 - -#define GL_QUERY_BUFFER_AMD 0x9192 -#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 -#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 - -#define GLEW_AMD_query_buffer_object GLEW_GET_VAR(__GLEW_AMD_query_buffer_object) - -#endif /* GL_AMD_query_buffer_object */ - -/* ------------------------ GL_AMD_sample_positions ------------------------ */ - -#ifndef GL_AMD_sample_positions -#define GL_AMD_sample_positions 1 - -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F - -typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val); - -#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD) - -#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions) - -#endif /* GL_AMD_sample_positions */ - -/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */ - -#ifndef GL_AMD_seamless_cubemap_per_texture -#define GL_AMD_seamless_cubemap_per_texture 1 - -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F - -#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture) - -#endif /* GL_AMD_seamless_cubemap_per_texture */ - -/* -------------------- GL_AMD_shader_atomic_counter_ops ------------------- */ - -#ifndef GL_AMD_shader_atomic_counter_ops -#define GL_AMD_shader_atomic_counter_ops 1 - -#define GLEW_AMD_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_AMD_shader_atomic_counter_ops) - -#endif /* GL_AMD_shader_atomic_counter_ops */ - -/* -------------------------- GL_AMD_shader_ballot ------------------------- */ - -#ifndef GL_AMD_shader_ballot -#define GL_AMD_shader_ballot 1 - -#define GLEW_AMD_shader_ballot GLEW_GET_VAR(__GLEW_AMD_shader_ballot) - -#endif /* GL_AMD_shader_ballot */ - -/* ---------------- GL_AMD_shader_explicit_vertex_parameter ---------------- */ - -#ifndef GL_AMD_shader_explicit_vertex_parameter -#define GL_AMD_shader_explicit_vertex_parameter 1 - -#define GLEW_AMD_shader_explicit_vertex_parameter GLEW_GET_VAR(__GLEW_AMD_shader_explicit_vertex_parameter) - -#endif /* GL_AMD_shader_explicit_vertex_parameter */ - -/* ------------------- GL_AMD_shader_image_load_store_lod ------------------ */ - -#ifndef GL_AMD_shader_image_load_store_lod -#define GL_AMD_shader_image_load_store_lod 1 - -#define GLEW_AMD_shader_image_load_store_lod GLEW_GET_VAR(__GLEW_AMD_shader_image_load_store_lod) - -#endif /* GL_AMD_shader_image_load_store_lod */ - -/* ---------------------- GL_AMD_shader_stencil_export --------------------- */ - -#ifndef GL_AMD_shader_stencil_export -#define GL_AMD_shader_stencil_export 1 - -#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export) - -#endif /* GL_AMD_shader_stencil_export */ - -/* ------------------- GL_AMD_shader_stencil_value_export ------------------ */ - -#ifndef GL_AMD_shader_stencil_value_export -#define GL_AMD_shader_stencil_value_export 1 - -#define GLEW_AMD_shader_stencil_value_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_value_export) - -#endif /* GL_AMD_shader_stencil_value_export */ - -/* ---------------------- GL_AMD_shader_trinary_minmax --------------------- */ - -#ifndef GL_AMD_shader_trinary_minmax -#define GL_AMD_shader_trinary_minmax 1 - -#define GLEW_AMD_shader_trinary_minmax GLEW_GET_VAR(__GLEW_AMD_shader_trinary_minmax) - -#endif /* GL_AMD_shader_trinary_minmax */ - -/* ------------------------- GL_AMD_sparse_texture ------------------------- */ - -#ifndef GL_AMD_sparse_texture -#define GL_AMD_sparse_texture 1 - -#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 -#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A -#define GL_MIN_SPARSE_LEVEL_AMD 0x919B -#define GL_MIN_LOD_WARNING_AMD 0x919C - -typedef void (GLAPIENTRY * PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); - -#define glTexStorageSparseAMD GLEW_GET_FUN(__glewTexStorageSparseAMD) -#define glTextureStorageSparseAMD GLEW_GET_FUN(__glewTextureStorageSparseAMD) - -#define GLEW_AMD_sparse_texture GLEW_GET_VAR(__GLEW_AMD_sparse_texture) - -#endif /* GL_AMD_sparse_texture */ - -/* ------------------- GL_AMD_stencil_operation_extended ------------------- */ - -#ifndef GL_AMD_stencil_operation_extended -#define GL_AMD_stencil_operation_extended 1 - -#define GL_SET_AMD 0x874A -#define GL_REPLACE_VALUE_AMD 0x874B -#define GL_STENCIL_OP_VALUE_AMD 0x874C -#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D - -typedef void (GLAPIENTRY * PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); - -#define glStencilOpValueAMD GLEW_GET_FUN(__glewStencilOpValueAMD) - -#define GLEW_AMD_stencil_operation_extended GLEW_GET_VAR(__GLEW_AMD_stencil_operation_extended) - -#endif /* GL_AMD_stencil_operation_extended */ - -/* --------------------- GL_AMD_texture_gather_bias_lod -------------------- */ - -#ifndef GL_AMD_texture_gather_bias_lod -#define GL_AMD_texture_gather_bias_lod 1 - -#define GLEW_AMD_texture_gather_bias_lod GLEW_GET_VAR(__GLEW_AMD_texture_gather_bias_lod) - -#endif /* GL_AMD_texture_gather_bias_lod */ - -/* ------------------------ GL_AMD_texture_texture4 ------------------------ */ - -#ifndef GL_AMD_texture_texture4 -#define GL_AMD_texture_texture4 1 - -#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4) - -#endif /* GL_AMD_texture_texture4 */ - -/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */ - -#ifndef GL_AMD_transform_feedback3_lines_triangles -#define GL_AMD_transform_feedback3_lines_triangles 1 - -#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles) - -#endif /* GL_AMD_transform_feedback3_lines_triangles */ - -/* ----------------------- GL_AMD_transform_feedback4 ---------------------- */ - -#ifndef GL_AMD_transform_feedback4 -#define GL_AMD_transform_feedback4 1 - -#define GL_STREAM_RASTERIZATION_AMD 0x91A0 - -#define GLEW_AMD_transform_feedback4 GLEW_GET_VAR(__GLEW_AMD_transform_feedback4) - -#endif /* GL_AMD_transform_feedback4 */ - -/* ----------------------- GL_AMD_vertex_shader_layer ---------------------- */ - -#ifndef GL_AMD_vertex_shader_layer -#define GL_AMD_vertex_shader_layer 1 - -#define GLEW_AMD_vertex_shader_layer GLEW_GET_VAR(__GLEW_AMD_vertex_shader_layer) - -#endif /* GL_AMD_vertex_shader_layer */ - -/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */ - -#ifndef GL_AMD_vertex_shader_tessellator -#define GL_AMD_vertex_shader_tessellator 1 - -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#define GL_DISCRETE_AMD 0x9006 -#define GL_CONTINUOUS_AMD 0x9007 - -typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); -typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); - -#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD) -#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD) - -#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator) - -#endif /* GL_AMD_vertex_shader_tessellator */ - -/* ------------------ GL_AMD_vertex_shader_viewport_index ------------------ */ - -#ifndef GL_AMD_vertex_shader_viewport_index -#define GL_AMD_vertex_shader_viewport_index 1 - -#define GLEW_AMD_vertex_shader_viewport_index GLEW_GET_VAR(__GLEW_AMD_vertex_shader_viewport_index) - -#endif /* GL_AMD_vertex_shader_viewport_index */ - -/* -------------------- GL_ANDROID_extension_pack_es31a -------------------- */ - -#ifndef GL_ANDROID_extension_pack_es31a -#define GL_ANDROID_extension_pack_es31a 1 - -#define GLEW_ANDROID_extension_pack_es31a GLEW_GET_VAR(__GLEW_ANDROID_extension_pack_es31a) - -#endif /* GL_ANDROID_extension_pack_es31a */ - -/* ------------------------- GL_ANGLE_depth_texture ------------------------ */ - -#ifndef GL_ANGLE_depth_texture -#define GL_ANGLE_depth_texture 1 - -#define GLEW_ANGLE_depth_texture GLEW_GET_VAR(__GLEW_ANGLE_depth_texture) - -#endif /* GL_ANGLE_depth_texture */ - -/* ----------------------- GL_ANGLE_framebuffer_blit ----------------------- */ - -#ifndef GL_ANGLE_framebuffer_blit -#define GL_ANGLE_framebuffer_blit 1 - -#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA - -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - -#define glBlitFramebufferANGLE GLEW_GET_FUN(__glewBlitFramebufferANGLE) - -#define GLEW_ANGLE_framebuffer_blit GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_blit) - -#endif /* GL_ANGLE_framebuffer_blit */ - -/* -------------------- GL_ANGLE_framebuffer_multisample ------------------- */ - -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_ANGLE_framebuffer_multisample 1 - -#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 -#define GL_MAX_SAMPLES_ANGLE 0x8D57 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleANGLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleANGLE) - -#define GLEW_ANGLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_multisample) - -#endif /* GL_ANGLE_framebuffer_multisample */ - -/* ----------------------- GL_ANGLE_instanced_arrays ----------------------- */ - -#ifndef GL_ANGLE_instanced_arrays -#define GL_ANGLE_instanced_arrays 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); - -#define glDrawArraysInstancedANGLE GLEW_GET_FUN(__glewDrawArraysInstancedANGLE) -#define glDrawElementsInstancedANGLE GLEW_GET_FUN(__glewDrawElementsInstancedANGLE) -#define glVertexAttribDivisorANGLE GLEW_GET_FUN(__glewVertexAttribDivisorANGLE) - -#define GLEW_ANGLE_instanced_arrays GLEW_GET_VAR(__GLEW_ANGLE_instanced_arrays) - -#endif /* GL_ANGLE_instanced_arrays */ - -/* -------------------- GL_ANGLE_pack_reverse_row_order -------------------- */ - -#ifndef GL_ANGLE_pack_reverse_row_order -#define GL_ANGLE_pack_reverse_row_order 1 - -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 - -#define GLEW_ANGLE_pack_reverse_row_order GLEW_GET_VAR(__GLEW_ANGLE_pack_reverse_row_order) - -#endif /* GL_ANGLE_pack_reverse_row_order */ - -/* ------------------------ GL_ANGLE_program_binary ------------------------ */ - -#ifndef GL_ANGLE_program_binary -#define GL_ANGLE_program_binary 1 - -#define GL_PROGRAM_BINARY_ANGLE 0x93A6 - -#define GLEW_ANGLE_program_binary GLEW_GET_VAR(__GLEW_ANGLE_program_binary) - -#endif /* GL_ANGLE_program_binary */ - -/* ------------------- GL_ANGLE_texture_compression_dxt1 ------------------- */ - -#ifndef GL_ANGLE_texture_compression_dxt1 -#define GL_ANGLE_texture_compression_dxt1 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 - -#define GLEW_ANGLE_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt1) - -#endif /* GL_ANGLE_texture_compression_dxt1 */ - -/* ------------------- GL_ANGLE_texture_compression_dxt3 ------------------- */ - -#ifndef GL_ANGLE_texture_compression_dxt3 -#define GL_ANGLE_texture_compression_dxt3 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 - -#define GLEW_ANGLE_texture_compression_dxt3 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt3) - -#endif /* GL_ANGLE_texture_compression_dxt3 */ - -/* ------------------- GL_ANGLE_texture_compression_dxt5 ------------------- */ - -#ifndef GL_ANGLE_texture_compression_dxt5 -#define GL_ANGLE_texture_compression_dxt5 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 - -#define GLEW_ANGLE_texture_compression_dxt5 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt5) - -#endif /* GL_ANGLE_texture_compression_dxt5 */ - -/* ------------------------- GL_ANGLE_texture_usage ------------------------ */ - -#ifndef GL_ANGLE_texture_usage -#define GL_ANGLE_texture_usage 1 - -#define GL_TEXTURE_USAGE_ANGLE 0x93A2 -#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 - -#define GLEW_ANGLE_texture_usage GLEW_GET_VAR(__GLEW_ANGLE_texture_usage) - -#endif /* GL_ANGLE_texture_usage */ - -/* -------------------------- GL_ANGLE_timer_query ------------------------- */ - -#ifndef GL_ANGLE_timer_query -#define GL_ANGLE_timer_query 1 - -#define GL_QUERY_COUNTER_BITS_ANGLE 0x8864 -#define GL_CURRENT_QUERY_ANGLE 0x8865 -#define GL_QUERY_RESULT_ANGLE 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ANGLE 0x8867 -#define GL_TIME_ELAPSED_ANGLE 0x88BF -#define GL_TIMESTAMP_ANGLE 0x8E28 - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYANGLEPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESANGLEPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYANGLEPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENQUERIESANGLEPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VANGLEPROC) (GLuint id, GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVANGLEPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VANGLEPROC) (GLuint id, GLenum pname, GLuint64* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVANGLEPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVANGLEPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYANGLEPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERANGLEPROC) (GLuint id, GLenum target); - -#define glBeginQueryANGLE GLEW_GET_FUN(__glewBeginQueryANGLE) -#define glDeleteQueriesANGLE GLEW_GET_FUN(__glewDeleteQueriesANGLE) -#define glEndQueryANGLE GLEW_GET_FUN(__glewEndQueryANGLE) -#define glGenQueriesANGLE GLEW_GET_FUN(__glewGenQueriesANGLE) -#define glGetQueryObjecti64vANGLE GLEW_GET_FUN(__glewGetQueryObjecti64vANGLE) -#define glGetQueryObjectivANGLE GLEW_GET_FUN(__glewGetQueryObjectivANGLE) -#define glGetQueryObjectui64vANGLE GLEW_GET_FUN(__glewGetQueryObjectui64vANGLE) -#define glGetQueryObjectuivANGLE GLEW_GET_FUN(__glewGetQueryObjectuivANGLE) -#define glGetQueryivANGLE GLEW_GET_FUN(__glewGetQueryivANGLE) -#define glIsQueryANGLE GLEW_GET_FUN(__glewIsQueryANGLE) -#define glQueryCounterANGLE GLEW_GET_FUN(__glewQueryCounterANGLE) - -#define GLEW_ANGLE_timer_query GLEW_GET_VAR(__GLEW_ANGLE_timer_query) - -#endif /* GL_ANGLE_timer_query */ - -/* ------------------- GL_ANGLE_translated_shader_source ------------------- */ - -#ifndef GL_ANGLE_translated_shader_source -#define GL_ANGLE_translated_shader_source 1 - -#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 - -typedef void (GLAPIENTRY * PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); - -#define glGetTranslatedShaderSourceANGLE GLEW_GET_FUN(__glewGetTranslatedShaderSourceANGLE) - -#define GLEW_ANGLE_translated_shader_source GLEW_GET_VAR(__GLEW_ANGLE_translated_shader_source) - -#endif /* GL_ANGLE_translated_shader_source */ - -/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */ - -#ifndef GL_APPLE_aux_depth_stencil -#define GL_APPLE_aux_depth_stencil 1 - -#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 - -#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil) - -#endif /* GL_APPLE_aux_depth_stencil */ - -/* ------------------------ GL_APPLE_client_storage ------------------------ */ - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 - -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 - -#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) - -#endif /* GL_APPLE_client_storage */ - -/* ------------------------- GL_APPLE_clip_distance ------------------------ */ - -#ifndef GL_APPLE_clip_distance -#define GL_APPLE_clip_distance 1 - -#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 -#define GL_CLIP_DISTANCE0_APPLE 0x3000 -#define GL_CLIP_DISTANCE1_APPLE 0x3001 -#define GL_CLIP_DISTANCE2_APPLE 0x3002 -#define GL_CLIP_DISTANCE3_APPLE 0x3003 -#define GL_CLIP_DISTANCE4_APPLE 0x3004 -#define GL_CLIP_DISTANCE5_APPLE 0x3005 -#define GL_CLIP_DISTANCE6_APPLE 0x3006 -#define GL_CLIP_DISTANCE7_APPLE 0x3007 - -#define GLEW_APPLE_clip_distance GLEW_GET_VAR(__GLEW_APPLE_clip_distance) - -#endif /* GL_APPLE_clip_distance */ - -/* ------------------- GL_APPLE_color_buffer_packed_float ------------------ */ - -#ifndef GL_APPLE_color_buffer_packed_float -#define GL_APPLE_color_buffer_packed_float 1 - -#define GLEW_APPLE_color_buffer_packed_float GLEW_GET_VAR(__GLEW_APPLE_color_buffer_packed_float) - -#endif /* GL_APPLE_color_buffer_packed_float */ - -/* ---------------------- GL_APPLE_copy_texture_levels --------------------- */ - -#ifndef GL_APPLE_copy_texture_levels -#define GL_APPLE_copy_texture_levels 1 - -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); - -#define glCopyTextureLevelsAPPLE GLEW_GET_FUN(__glewCopyTextureLevelsAPPLE) - -#define GLEW_APPLE_copy_texture_levels GLEW_GET_VAR(__GLEW_APPLE_copy_texture_levels) - -#endif /* GL_APPLE_copy_texture_levels */ - -/* ------------------------- GL_APPLE_element_array ------------------------ */ - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 - -#define GL_ELEMENT_ARRAY_APPLE 0x8A0C -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); - -#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) -#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) -#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) -#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) -#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) - -#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) - -#endif /* GL_APPLE_element_array */ - -/* ----------------------------- GL_APPLE_fence ---------------------------- */ - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 - -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B - -typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); -typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); -typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); - -#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) -#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) -#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) -#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) -#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) -#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) -#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) -#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) - -#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) - -#endif /* GL_APPLE_fence */ - -/* ------------------------- GL_APPLE_float_pixels ------------------------- */ - -#ifndef GL_APPLE_float_pixels -#define GL_APPLE_float_pixels 1 - -#define GL_HALF_APPLE 0x140B -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_COLOR_FLOAT_APPLE 0x8A0F - -#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) - -#endif /* GL_APPLE_float_pixels */ - -/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 - -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 - -typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); - -#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) -#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) - -#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) - -#endif /* GL_APPLE_flush_buffer_range */ - -/* -------------------- GL_APPLE_framebuffer_multisample ------------------- */ - -#ifndef GL_APPLE_framebuffer_multisample -#define GL_APPLE_framebuffer_multisample 1 - -#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA -#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 -#define GL_MAX_SAMPLES_APPLE 0x8D57 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); - -#define glRenderbufferStorageMultisampleAPPLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleAPPLE) -#define glResolveMultisampleFramebufferAPPLE GLEW_GET_FUN(__glewResolveMultisampleFramebufferAPPLE) - -#define GLEW_APPLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_APPLE_framebuffer_multisample) - -#endif /* GL_APPLE_framebuffer_multisample */ - -/* ----------------------- GL_APPLE_object_purgeable ----------------------- */ - -#ifndef GL_APPLE_object_purgeable -#define GL_APPLE_object_purgeable 1 - -#define GL_BUFFER_OBJECT_APPLE 0x85B3 -#define GL_RELEASED_APPLE 0x8A19 -#define GL_VOLATILE_APPLE 0x8A1A -#define GL_RETAINED_APPLE 0x8A1B -#define GL_UNDEFINED_APPLE 0x8A1C -#define GL_PURGEABLE_APPLE 0x8A1D - -typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); -typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); - -#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE) -#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE) -#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE) - -#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable) - -#endif /* GL_APPLE_object_purgeable */ - -/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ - -#ifndef GL_APPLE_pixel_buffer -#define GL_APPLE_pixel_buffer 1 - -#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 - -#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) - -#endif /* GL_APPLE_pixel_buffer */ - -/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */ - -#ifndef GL_APPLE_rgb_422 -#define GL_APPLE_rgb_422 1 - -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#define GL_RGB_422_APPLE 0x8A1F -#define GL_RGB_RAW_422_APPLE 0x8A51 - -#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422) - -#endif /* GL_APPLE_rgb_422 */ - -/* --------------------------- GL_APPLE_row_bytes -------------------------- */ - -#ifndef GL_APPLE_row_bytes -#define GL_APPLE_row_bytes 1 - -#define GL_PACK_ROW_BYTES_APPLE 0x8A15 -#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 - -#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes) - -#endif /* GL_APPLE_row_bytes */ - -/* ------------------------ GL_APPLE_specular_vector ----------------------- */ - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 - -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 - -#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) - -#endif /* GL_APPLE_specular_vector */ - -/* ----------------------------- GL_APPLE_sync ----------------------------- */ - -#ifndef GL_APPLE_sync -#define GL_APPLE_sync 1 - -#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 -#define GL_SYNC_OBJECT_APPLE 0x8A53 -#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 -#define GL_OBJECT_TYPE_APPLE 0x9112 -#define GL_SYNC_CONDITION_APPLE 0x9113 -#define GL_SYNC_STATUS_APPLE 0x9114 -#define GL_SYNC_FLAGS_APPLE 0x9115 -#define GL_SYNC_FENCE_APPLE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 -#define GL_UNSIGNALED_APPLE 0x9118 -#define GL_SIGNALED_APPLE 0x9119 -#define GL_ALREADY_SIGNALED_APPLE 0x911A -#define GL_TIMEOUT_EXPIRED_APPLE 0x911B -#define GL_CONDITION_SATISFIED_APPLE 0x911C -#define GL_WAIT_FAILED_APPLE 0x911D -#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull - -typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout); -typedef void (GLAPIENTRY * PFNGLDELETESYNCAPPLEPROC) (GLsync GLsync); -typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETSYNCIVAPPLEPROC) (GLsync GLsync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); -typedef GLboolean (GLAPIENTRY * PFNGLISSYNCAPPLEPROC) (GLsync GLsync); -typedef void (GLAPIENTRY * PFNGLWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout); - -#define glClientWaitSyncAPPLE GLEW_GET_FUN(__glewClientWaitSyncAPPLE) -#define glDeleteSyncAPPLE GLEW_GET_FUN(__glewDeleteSyncAPPLE) -#define glFenceSyncAPPLE GLEW_GET_FUN(__glewFenceSyncAPPLE) -#define glGetInteger64vAPPLE GLEW_GET_FUN(__glewGetInteger64vAPPLE) -#define glGetSyncivAPPLE GLEW_GET_FUN(__glewGetSyncivAPPLE) -#define glIsSyncAPPLE GLEW_GET_FUN(__glewIsSyncAPPLE) -#define glWaitSyncAPPLE GLEW_GET_FUN(__glewWaitSyncAPPLE) - -#define GLEW_APPLE_sync GLEW_GET_VAR(__GLEW_APPLE_sync) - -#endif /* GL_APPLE_sync */ - -/* -------------------- GL_APPLE_texture_2D_limited_npot ------------------- */ - -#ifndef GL_APPLE_texture_2D_limited_npot -#define GL_APPLE_texture_2D_limited_npot 1 - -#define GLEW_APPLE_texture_2D_limited_npot GLEW_GET_VAR(__GLEW_APPLE_texture_2D_limited_npot) - -#endif /* GL_APPLE_texture_2D_limited_npot */ - -/* -------------------- GL_APPLE_texture_format_BGRA8888 ------------------- */ - -#ifndef GL_APPLE_texture_format_BGRA8888 -#define GL_APPLE_texture_format_BGRA8888 1 - -#define GL_BGRA_EXT 0x80E1 -#define GL_BGRA8_EXT 0x93A1 - -#define GLEW_APPLE_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_APPLE_texture_format_BGRA8888) - -#endif /* GL_APPLE_texture_format_BGRA8888 */ - -/* ----------------------- GL_APPLE_texture_max_level ---------------------- */ - -#ifndef GL_APPLE_texture_max_level -#define GL_APPLE_texture_max_level 1 - -#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D - -#define GLEW_APPLE_texture_max_level GLEW_GET_VAR(__GLEW_APPLE_texture_max_level) - -#endif /* GL_APPLE_texture_max_level */ - -/* --------------------- GL_APPLE_texture_packed_float --------------------- */ - -#ifndef GL_APPLE_texture_packed_float -#define GL_APPLE_texture_packed_float 1 - -#define GL_R11F_G11F_B10F_APPLE 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B -#define GL_RGB9_E5_APPLE 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E - -#define GLEW_APPLE_texture_packed_float GLEW_GET_VAR(__GLEW_APPLE_texture_packed_float) - -#endif /* GL_APPLE_texture_packed_float */ - -/* ------------------------- GL_APPLE_texture_range ------------------------ */ - -#ifndef GL_APPLE_texture_range -#define GL_APPLE_texture_range 1 - -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF - -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); -typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, void *pointer); - -#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) -#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) - -#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) - -#endif /* GL_APPLE_texture_range */ - -/* ------------------------ GL_APPLE_transform_hint ------------------------ */ - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 - -#define GL_TRANSFORM_HINT_APPLE 0x85B1 - -#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) - -#endif /* GL_APPLE_transform_hint */ - -/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 - -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); - -#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) -#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) -#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) -#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) - -#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) - -#endif /* GL_APPLE_vertex_array_object */ - -/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 - -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CLIENT_APPLE 0x85B4 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF - -typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); - -#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) -#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) -#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) - -#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) - -#endif /* GL_APPLE_vertex_array_range */ - -/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */ - -#ifndef GL_APPLE_vertex_program_evaluators -#define GL_APPLE_vertex_program_evaluators 1 - -#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 -#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 -#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 -#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 -#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 -#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 -#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 -#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 -#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 -#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 - -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); -typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); -typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); -typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); - -#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE) -#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE) -#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE) -#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE) -#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE) -#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE) -#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE) - -#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators) - -#endif /* GL_APPLE_vertex_program_evaluators */ - -/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 - -#define GL_YCBCR_422_APPLE 0x85B9 - -#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) - -#endif /* GL_APPLE_ycbcr_422 */ - -/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */ - -#ifndef GL_ARB_ES2_compatibility -#define GL_ARB_ES2_compatibility 1 - -#define GL_FIXED 0x140C -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_RGB565 0x8D62 -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD - -typedef int GLfixed; - -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); -typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); -typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); -typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length); - -#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf) -#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef) -#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat) -#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler) -#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary) - -#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility) - -#endif /* GL_ARB_ES2_compatibility */ - -/* ----------------------- GL_ARB_ES3_1_compatibility ---------------------- */ - -#ifndef GL_ARB_ES3_1_compatibility -#define GL_ARB_ES3_1_compatibility 1 - -typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); - -#define glMemoryBarrierByRegion GLEW_GET_FUN(__glewMemoryBarrierByRegion) - -#define GLEW_ARB_ES3_1_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_1_compatibility) - -#endif /* GL_ARB_ES3_1_compatibility */ - -/* ----------------------- GL_ARB_ES3_2_compatibility ---------------------- */ - -#ifndef GL_ARB_ES3_2_compatibility -#define GL_ARB_ES3_2_compatibility 1 - -#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE -#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 -#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 - -typedef void (GLAPIENTRY * PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); - -#define glPrimitiveBoundingBoxARB GLEW_GET_FUN(__glewPrimitiveBoundingBoxARB) - -#define GLEW_ARB_ES3_2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_2_compatibility) - -#endif /* GL_ARB_ES3_2_compatibility */ - -/* ------------------------ GL_ARB_ES3_compatibility ----------------------- */ - -#ifndef GL_ARB_ES3_compatibility -#define GL_ARB_ES3_compatibility 1 - -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 - -#define GLEW_ARB_ES3_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_compatibility) - -#endif /* GL_ARB_ES3_compatibility */ - -/* ------------------------ GL_ARB_arrays_of_arrays ------------------------ */ - -#ifndef GL_ARB_arrays_of_arrays -#define GL_ARB_arrays_of_arrays 1 - -#define GLEW_ARB_arrays_of_arrays GLEW_GET_VAR(__GLEW_ARB_arrays_of_arrays) - -#endif /* GL_ARB_arrays_of_arrays */ - -/* -------------------------- GL_ARB_base_instance ------------------------- */ - -#ifndef GL_ARB_base_instance -#define GL_ARB_base_instance 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); - -#define glDrawArraysInstancedBaseInstance GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstance) -#define glDrawElementsInstancedBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstance) -#define glDrawElementsInstancedBaseVertexBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstance) - -#define GLEW_ARB_base_instance GLEW_GET_VAR(__GLEW_ARB_base_instance) - -#endif /* GL_ARB_base_instance */ - -/* ------------------------ GL_ARB_bindless_texture ------------------------ */ - -#ifndef GL_ARB_bindless_texture -#define GL_ARB_bindless_texture 1 - -#define GL_UNSIGNED_INT64_ARB 0x140F - -typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT* params); -typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); -typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT* v); - -#define glGetImageHandleARB GLEW_GET_FUN(__glewGetImageHandleARB) -#define glGetTextureHandleARB GLEW_GET_FUN(__glewGetTextureHandleARB) -#define glGetTextureSamplerHandleARB GLEW_GET_FUN(__glewGetTextureSamplerHandleARB) -#define glGetVertexAttribLui64vARB GLEW_GET_FUN(__glewGetVertexAttribLui64vARB) -#define glIsImageHandleResidentARB GLEW_GET_FUN(__glewIsImageHandleResidentARB) -#define glIsTextureHandleResidentARB GLEW_GET_FUN(__glewIsTextureHandleResidentARB) -#define glMakeImageHandleNonResidentARB GLEW_GET_FUN(__glewMakeImageHandleNonResidentARB) -#define glMakeImageHandleResidentARB GLEW_GET_FUN(__glewMakeImageHandleResidentARB) -#define glMakeTextureHandleNonResidentARB GLEW_GET_FUN(__glewMakeTextureHandleNonResidentARB) -#define glMakeTextureHandleResidentARB GLEW_GET_FUN(__glewMakeTextureHandleResidentARB) -#define glProgramUniformHandleui64ARB GLEW_GET_FUN(__glewProgramUniformHandleui64ARB) -#define glProgramUniformHandleui64vARB GLEW_GET_FUN(__glewProgramUniformHandleui64vARB) -#define glUniformHandleui64ARB GLEW_GET_FUN(__glewUniformHandleui64ARB) -#define glUniformHandleui64vARB GLEW_GET_FUN(__glewUniformHandleui64vARB) -#define glVertexAttribL1ui64ARB GLEW_GET_FUN(__glewVertexAttribL1ui64ARB) -#define glVertexAttribL1ui64vARB GLEW_GET_FUN(__glewVertexAttribL1ui64vARB) - -#define GLEW_ARB_bindless_texture GLEW_GET_VAR(__GLEW_ARB_bindless_texture) - -#endif /* GL_ARB_bindless_texture */ - -/* ----------------------- GL_ARB_blend_func_extended ---------------------- */ - -#ifndef GL_ARB_blend_func_extended -#define GL_ARB_blend_func_extended 1 - -#define GL_SRC1_COLOR 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC - -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar * name); - -#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed) -#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex) - -#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended) - -#endif /* GL_ARB_blend_func_extended */ - -/* ------------------------- GL_ARB_buffer_storage ------------------------- */ - -#ifndef GL_ARB_buffer_storage -#define GL_ARB_buffer_storage 1 - -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_PERSISTENT_BIT 0x00000040 -#define GL_MAP_COHERENT_BIT 0x00000080 -#define GL_DYNAMIC_STORAGE_BIT 0x0100 -#define GL_CLIENT_STORAGE_BIT 0x0200 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 -#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F -#define GL_BUFFER_STORAGE_FLAGS 0x8220 - -typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); - -#define glBufferStorage GLEW_GET_FUN(__glewBufferStorage) - -#define GLEW_ARB_buffer_storage GLEW_GET_VAR(__GLEW_ARB_buffer_storage) - -#endif /* GL_ARB_buffer_storage */ - -/* ---------------------------- GL_ARB_cl_event ---------------------------- */ - -#ifndef GL_ARB_cl_event -#define GL_ARB_cl_event 1 - -#define GL_SYNC_CL_EVENT_ARB 0x8240 -#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 - -typedef struct _cl_context *cl_context; -typedef struct _cl_event *cl_event; - -typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags); - -#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB) - -#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event) - -#endif /* GL_ARB_cl_event */ - -/* ----------------------- GL_ARB_clear_buffer_object ---------------------- */ - -#ifndef GL_ARB_clear_buffer_object -#define GL_ARB_clear_buffer_object 1 - -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); - -#define glClearBufferData GLEW_GET_FUN(__glewClearBufferData) -#define glClearBufferSubData GLEW_GET_FUN(__glewClearBufferSubData) -#define glClearNamedBufferDataEXT GLEW_GET_FUN(__glewClearNamedBufferDataEXT) -#define glClearNamedBufferSubDataEXT GLEW_GET_FUN(__glewClearNamedBufferSubDataEXT) - -#define GLEW_ARB_clear_buffer_object GLEW_GET_VAR(__GLEW_ARB_clear_buffer_object) - -#endif /* GL_ARB_clear_buffer_object */ - -/* -------------------------- GL_ARB_clear_texture ------------------------- */ - -#ifndef GL_ARB_clear_texture -#define GL_ARB_clear_texture 1 - -#define GL_CLEAR_TEXTURE 0x9365 - -typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); - -#define glClearTexImage GLEW_GET_FUN(__glewClearTexImage) -#define glClearTexSubImage GLEW_GET_FUN(__glewClearTexSubImage) - -#define GLEW_ARB_clear_texture GLEW_GET_VAR(__GLEW_ARB_clear_texture) - -#endif /* GL_ARB_clear_texture */ - -/* -------------------------- GL_ARB_clip_control -------------------------- */ - -#ifndef GL_ARB_clip_control -#define GL_ARB_clip_control 1 - -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_CLIP_ORIGIN 0x935C -#define GL_CLIP_DEPTH_MODE 0x935D -#define GL_NEGATIVE_ONE_TO_ONE 0x935E -#define GL_ZERO_TO_ONE 0x935F - -typedef void (GLAPIENTRY * PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); - -#define glClipControl GLEW_GET_FUN(__glewClipControl) - -#define GLEW_ARB_clip_control GLEW_GET_VAR(__GLEW_ARB_clip_control) - -#endif /* GL_ARB_clip_control */ - -/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 - -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D - -typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); - -#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) - -#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) - -#endif /* GL_ARB_color_buffer_float */ - -/* -------------------------- GL_ARB_compatibility ------------------------- */ - -#ifndef GL_ARB_compatibility -#define GL_ARB_compatibility 1 - -#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility) - -#endif /* GL_ARB_compatibility */ - -/* ---------------- GL_ARB_compressed_texture_pixel_storage ---------------- */ - -#ifndef GL_ARB_compressed_texture_pixel_storage -#define GL_ARB_compressed_texture_pixel_storage 1 - -#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 -#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 -#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 -#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A -#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B -#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C -#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D -#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E - -#define GLEW_ARB_compressed_texture_pixel_storage GLEW_GET_VAR(__GLEW_ARB_compressed_texture_pixel_storage) - -#endif /* GL_ARB_compressed_texture_pixel_storage */ - -/* ------------------------- GL_ARB_compute_shader ------------------------- */ - -#ifndef GL_ARB_compute_shader -#define GL_ARB_compute_shader 1 - -#define GL_COMPUTE_SHADER_BIT 0x00000020 -#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 -#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 -#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 -#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 -#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 -#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 -#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB -#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED -#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE -#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_COMPUTE_SHADER 0x91B9 -#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB -#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC -#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE -#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF - -typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); - -#define glDispatchCompute GLEW_GET_FUN(__glewDispatchCompute) -#define glDispatchComputeIndirect GLEW_GET_FUN(__glewDispatchComputeIndirect) - -#define GLEW_ARB_compute_shader GLEW_GET_VAR(__GLEW_ARB_compute_shader) - -#endif /* GL_ARB_compute_shader */ - -/* ------------------- GL_ARB_compute_variable_group_size ------------------ */ - -#ifndef GL_ARB_compute_variable_group_size -#define GL_ARB_compute_variable_group_size 1 - -#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB -#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF -#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 -#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 - -typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); - -#define glDispatchComputeGroupSizeARB GLEW_GET_FUN(__glewDispatchComputeGroupSizeARB) - -#define GLEW_ARB_compute_variable_group_size GLEW_GET_VAR(__GLEW_ARB_compute_variable_group_size) - -#endif /* GL_ARB_compute_variable_group_size */ - -/* ------------------- GL_ARB_conditional_render_inverted ------------------ */ - -#ifndef GL_ARB_conditional_render_inverted -#define GL_ARB_conditional_render_inverted 1 - -#define GL_QUERY_WAIT_INVERTED 0x8E17 -#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 -#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 -#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A - -#define GLEW_ARB_conditional_render_inverted GLEW_GET_VAR(__GLEW_ARB_conditional_render_inverted) - -#endif /* GL_ARB_conditional_render_inverted */ - -/* ----------------------- GL_ARB_conservative_depth ----------------------- */ - -#ifndef GL_ARB_conservative_depth -#define GL_ARB_conservative_depth 1 - -#define GLEW_ARB_conservative_depth GLEW_GET_VAR(__GLEW_ARB_conservative_depth) - -#endif /* GL_ARB_conservative_depth */ - -/* --------------------------- GL_ARB_copy_buffer -------------------------- */ - -#ifndef GL_ARB_copy_buffer -#define GL_ARB_copy_buffer 1 - -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 - -typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); - -#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData) - -#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer) - -#endif /* GL_ARB_copy_buffer */ - -/* --------------------------- GL_ARB_copy_image --------------------------- */ - -#ifndef GL_ARB_copy_image -#define GL_ARB_copy_image 1 - -typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -#define glCopyImageSubData GLEW_GET_FUN(__glewCopyImageSubData) - -#define GLEW_ARB_copy_image GLEW_GET_VAR(__GLEW_ARB_copy_image) - -#endif /* GL_ARB_copy_image */ - -/* -------------------------- GL_ARB_cull_distance ------------------------- */ - -#ifndef GL_ARB_cull_distance -#define GL_ARB_cull_distance 1 - -#define GL_MAX_CULL_DISTANCES 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA - -#define GLEW_ARB_cull_distance GLEW_GET_VAR(__GLEW_ARB_cull_distance) - -#endif /* GL_ARB_cull_distance */ - -/* -------------------------- GL_ARB_debug_output -------------------------- */ - -#ifndef GL_ARB_debug_output -#define GL_ARB_debug_output 1 - -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 - -typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); - -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); -typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); - -#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB) -#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB) -#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB) -#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB) - -#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output) - -#endif /* GL_ARB_debug_output */ - -/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 - -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD - -#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) - -#endif /* GL_ARB_depth_buffer_float */ - -/* --------------------------- GL_ARB_depth_clamp -------------------------- */ - -#ifndef GL_ARB_depth_clamp -#define GL_ARB_depth_clamp 1 - -#define GL_DEPTH_CLAMP 0x864F - -#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp) - -#endif /* GL_ARB_depth_clamp */ - -/* -------------------------- GL_ARB_depth_texture ------------------------- */ - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 - -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B - -#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) - -#endif /* GL_ARB_depth_texture */ - -/* ----------------------- GL_ARB_derivative_control ----------------------- */ - -#ifndef GL_ARB_derivative_control -#define GL_ARB_derivative_control 1 - -#define GLEW_ARB_derivative_control GLEW_GET_VAR(__GLEW_ARB_derivative_control) - -#endif /* GL_ARB_derivative_control */ - -/* ----------------------- GL_ARB_direct_state_access ---------------------- */ - -#ifndef GL_ARB_direct_state_access -#define GL_ARB_direct_state_access 1 - -#define GL_TEXTURE_TARGET 0x1006 -#define GL_QUERY_TARGET 0x82EA - -typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); -typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value); -typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); -typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers); -typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* textures); -typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64* param); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64* param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments); -typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); -typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat* param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint* param); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); - -#define glBindTextureUnit GLEW_GET_FUN(__glewBindTextureUnit) -#define glBlitNamedFramebuffer GLEW_GET_FUN(__glewBlitNamedFramebuffer) -#define glCheckNamedFramebufferStatus GLEW_GET_FUN(__glewCheckNamedFramebufferStatus) -#define glClearNamedBufferData GLEW_GET_FUN(__glewClearNamedBufferData) -#define glClearNamedBufferSubData GLEW_GET_FUN(__glewClearNamedBufferSubData) -#define glClearNamedFramebufferfi GLEW_GET_FUN(__glewClearNamedFramebufferfi) -#define glClearNamedFramebufferfv GLEW_GET_FUN(__glewClearNamedFramebufferfv) -#define glClearNamedFramebufferiv GLEW_GET_FUN(__glewClearNamedFramebufferiv) -#define glClearNamedFramebufferuiv GLEW_GET_FUN(__glewClearNamedFramebufferuiv) -#define glCompressedTextureSubImage1D GLEW_GET_FUN(__glewCompressedTextureSubImage1D) -#define glCompressedTextureSubImage2D GLEW_GET_FUN(__glewCompressedTextureSubImage2D) -#define glCompressedTextureSubImage3D GLEW_GET_FUN(__glewCompressedTextureSubImage3D) -#define glCopyNamedBufferSubData GLEW_GET_FUN(__glewCopyNamedBufferSubData) -#define glCopyTextureSubImage1D GLEW_GET_FUN(__glewCopyTextureSubImage1D) -#define glCopyTextureSubImage2D GLEW_GET_FUN(__glewCopyTextureSubImage2D) -#define glCopyTextureSubImage3D GLEW_GET_FUN(__glewCopyTextureSubImage3D) -#define glCreateBuffers GLEW_GET_FUN(__glewCreateBuffers) -#define glCreateFramebuffers GLEW_GET_FUN(__glewCreateFramebuffers) -#define glCreateProgramPipelines GLEW_GET_FUN(__glewCreateProgramPipelines) -#define glCreateQueries GLEW_GET_FUN(__glewCreateQueries) -#define glCreateRenderbuffers GLEW_GET_FUN(__glewCreateRenderbuffers) -#define glCreateSamplers GLEW_GET_FUN(__glewCreateSamplers) -#define glCreateTextures GLEW_GET_FUN(__glewCreateTextures) -#define glCreateTransformFeedbacks GLEW_GET_FUN(__glewCreateTransformFeedbacks) -#define glCreateVertexArrays GLEW_GET_FUN(__glewCreateVertexArrays) -#define glDisableVertexArrayAttrib GLEW_GET_FUN(__glewDisableVertexArrayAttrib) -#define glEnableVertexArrayAttrib GLEW_GET_FUN(__glewEnableVertexArrayAttrib) -#define glFlushMappedNamedBufferRange GLEW_GET_FUN(__glewFlushMappedNamedBufferRange) -#define glGenerateTextureMipmap GLEW_GET_FUN(__glewGenerateTextureMipmap) -#define glGetCompressedTextureImage GLEW_GET_FUN(__glewGetCompressedTextureImage) -#define glGetNamedBufferParameteri64v GLEW_GET_FUN(__glewGetNamedBufferParameteri64v) -#define glGetNamedBufferParameteriv GLEW_GET_FUN(__glewGetNamedBufferParameteriv) -#define glGetNamedBufferPointerv GLEW_GET_FUN(__glewGetNamedBufferPointerv) -#define glGetNamedBufferSubData GLEW_GET_FUN(__glewGetNamedBufferSubData) -#define glGetNamedFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameteriv) -#define glGetNamedFramebufferParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferParameteriv) -#define glGetNamedRenderbufferParameteriv GLEW_GET_FUN(__glewGetNamedRenderbufferParameteriv) -#define glGetQueryBufferObjecti64v GLEW_GET_FUN(__glewGetQueryBufferObjecti64v) -#define glGetQueryBufferObjectiv GLEW_GET_FUN(__glewGetQueryBufferObjectiv) -#define glGetQueryBufferObjectui64v GLEW_GET_FUN(__glewGetQueryBufferObjectui64v) -#define glGetQueryBufferObjectuiv GLEW_GET_FUN(__glewGetQueryBufferObjectuiv) -#define glGetTextureImage GLEW_GET_FUN(__glewGetTextureImage) -#define glGetTextureLevelParameterfv GLEW_GET_FUN(__glewGetTextureLevelParameterfv) -#define glGetTextureLevelParameteriv GLEW_GET_FUN(__glewGetTextureLevelParameteriv) -#define glGetTextureParameterIiv GLEW_GET_FUN(__glewGetTextureParameterIiv) -#define glGetTextureParameterIuiv GLEW_GET_FUN(__glewGetTextureParameterIuiv) -#define glGetTextureParameterfv GLEW_GET_FUN(__glewGetTextureParameterfv) -#define glGetTextureParameteriv GLEW_GET_FUN(__glewGetTextureParameteriv) -#define glGetTransformFeedbacki64_v GLEW_GET_FUN(__glewGetTransformFeedbacki64_v) -#define glGetTransformFeedbacki_v GLEW_GET_FUN(__glewGetTransformFeedbacki_v) -#define glGetTransformFeedbackiv GLEW_GET_FUN(__glewGetTransformFeedbackiv) -#define glGetVertexArrayIndexed64iv GLEW_GET_FUN(__glewGetVertexArrayIndexed64iv) -#define glGetVertexArrayIndexediv GLEW_GET_FUN(__glewGetVertexArrayIndexediv) -#define glGetVertexArrayiv GLEW_GET_FUN(__glewGetVertexArrayiv) -#define glInvalidateNamedFramebufferData GLEW_GET_FUN(__glewInvalidateNamedFramebufferData) -#define glInvalidateNamedFramebufferSubData GLEW_GET_FUN(__glewInvalidateNamedFramebufferSubData) -#define glMapNamedBuffer GLEW_GET_FUN(__glewMapNamedBuffer) -#define glMapNamedBufferRange GLEW_GET_FUN(__glewMapNamedBufferRange) -#define glNamedBufferData GLEW_GET_FUN(__glewNamedBufferData) -#define glNamedBufferStorage GLEW_GET_FUN(__glewNamedBufferStorage) -#define glNamedBufferSubData GLEW_GET_FUN(__glewNamedBufferSubData) -#define glNamedFramebufferDrawBuffer GLEW_GET_FUN(__glewNamedFramebufferDrawBuffer) -#define glNamedFramebufferDrawBuffers GLEW_GET_FUN(__glewNamedFramebufferDrawBuffers) -#define glNamedFramebufferParameteri GLEW_GET_FUN(__glewNamedFramebufferParameteri) -#define glNamedFramebufferReadBuffer GLEW_GET_FUN(__glewNamedFramebufferReadBuffer) -#define glNamedFramebufferRenderbuffer GLEW_GET_FUN(__glewNamedFramebufferRenderbuffer) -#define glNamedFramebufferTexture GLEW_GET_FUN(__glewNamedFramebufferTexture) -#define glNamedFramebufferTextureLayer GLEW_GET_FUN(__glewNamedFramebufferTextureLayer) -#define glNamedRenderbufferStorage GLEW_GET_FUN(__glewNamedRenderbufferStorage) -#define glNamedRenderbufferStorageMultisample GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisample) -#define glTextureBuffer GLEW_GET_FUN(__glewTextureBuffer) -#define glTextureBufferRange GLEW_GET_FUN(__glewTextureBufferRange) -#define glTextureParameterIiv GLEW_GET_FUN(__glewTextureParameterIiv) -#define glTextureParameterIuiv GLEW_GET_FUN(__glewTextureParameterIuiv) -#define glTextureParameterf GLEW_GET_FUN(__glewTextureParameterf) -#define glTextureParameterfv GLEW_GET_FUN(__glewTextureParameterfv) -#define glTextureParameteri GLEW_GET_FUN(__glewTextureParameteri) -#define glTextureParameteriv GLEW_GET_FUN(__glewTextureParameteriv) -#define glTextureStorage1D GLEW_GET_FUN(__glewTextureStorage1D) -#define glTextureStorage2D GLEW_GET_FUN(__glewTextureStorage2D) -#define glTextureStorage2DMultisample GLEW_GET_FUN(__glewTextureStorage2DMultisample) -#define glTextureStorage3D GLEW_GET_FUN(__glewTextureStorage3D) -#define glTextureStorage3DMultisample GLEW_GET_FUN(__glewTextureStorage3DMultisample) -#define glTextureSubImage1D GLEW_GET_FUN(__glewTextureSubImage1D) -#define glTextureSubImage2D GLEW_GET_FUN(__glewTextureSubImage2D) -#define glTextureSubImage3D GLEW_GET_FUN(__glewTextureSubImage3D) -#define glTransformFeedbackBufferBase GLEW_GET_FUN(__glewTransformFeedbackBufferBase) -#define glTransformFeedbackBufferRange GLEW_GET_FUN(__glewTransformFeedbackBufferRange) -#define glUnmapNamedBuffer GLEW_GET_FUN(__glewUnmapNamedBuffer) -#define glVertexArrayAttribBinding GLEW_GET_FUN(__glewVertexArrayAttribBinding) -#define glVertexArrayAttribFormat GLEW_GET_FUN(__glewVertexArrayAttribFormat) -#define glVertexArrayAttribIFormat GLEW_GET_FUN(__glewVertexArrayAttribIFormat) -#define glVertexArrayAttribLFormat GLEW_GET_FUN(__glewVertexArrayAttribLFormat) -#define glVertexArrayBindingDivisor GLEW_GET_FUN(__glewVertexArrayBindingDivisor) -#define glVertexArrayElementBuffer GLEW_GET_FUN(__glewVertexArrayElementBuffer) -#define glVertexArrayVertexBuffer GLEW_GET_FUN(__glewVertexArrayVertexBuffer) -#define glVertexArrayVertexBuffers GLEW_GET_FUN(__glewVertexArrayVertexBuffers) - -#define GLEW_ARB_direct_state_access GLEW_GET_VAR(__GLEW_ARB_direct_state_access) - -#endif /* GL_ARB_direct_state_access */ - -/* -------------------------- GL_ARB_draw_buffers -------------------------- */ - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) - -#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) - -#endif /* GL_ARB_draw_buffers */ - -/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */ - -#ifndef GL_ARB_draw_buffers_blend -#define GL_ARB_draw_buffers_blend 1 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); - -#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB) -#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB) -#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB) -#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB) - -#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend) - -#endif /* GL_ARB_draw_buffers_blend */ - -/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */ - -#ifndef GL_ARB_draw_elements_base_vertex -#define GL_ARB_draw_elements_base_vertex 1 - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei* count, GLenum type, const void*const *indices, GLsizei drawcount, const GLint *basevertex); - -#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex) -#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex) -#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex) -#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex) - -#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex) - -#endif /* GL_ARB_draw_elements_base_vertex */ - -/* -------------------------- GL_ARB_draw_indirect ------------------------- */ - -#ifndef GL_ARB_draw_indirect -#define GL_ARB_draw_indirect 1 - -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); - -#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect) -#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect) - -#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect) - -#endif /* GL_ARB_draw_indirect */ - -/* ------------------------- GL_ARB_draw_instanced ------------------------- */ - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 - -#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) - -#endif /* GL_ARB_draw_instanced */ - -/* ------------------------ GL_ARB_enhanced_layouts ------------------------ */ - -#ifndef GL_ARB_enhanced_layouts -#define GL_ARB_enhanced_layouts 1 - -#define GL_LOCATION_COMPONENT 0x934A -#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B -#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C - -#define GLEW_ARB_enhanced_layouts GLEW_GET_VAR(__GLEW_ARB_enhanced_layouts) - -#endif /* GL_ARB_enhanced_layouts */ - -/* -------------------- GL_ARB_explicit_attrib_location -------------------- */ - -#ifndef GL_ARB_explicit_attrib_location -#define GL_ARB_explicit_attrib_location 1 - -#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location) - -#endif /* GL_ARB_explicit_attrib_location */ - -/* -------------------- GL_ARB_explicit_uniform_location ------------------- */ - -#ifndef GL_ARB_explicit_uniform_location -#define GL_ARB_explicit_uniform_location 1 - -#define GL_MAX_UNIFORM_LOCATIONS 0x826E - -#define GLEW_ARB_explicit_uniform_location GLEW_GET_VAR(__GLEW_ARB_explicit_uniform_location) - -#endif /* GL_ARB_explicit_uniform_location */ - -/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */ - -#ifndef GL_ARB_fragment_coord_conventions -#define GL_ARB_fragment_coord_conventions 1 - -#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions) - -#endif /* GL_ARB_fragment_coord_conventions */ - -/* --------------------- GL_ARB_fragment_layer_viewport -------------------- */ - -#ifndef GL_ARB_fragment_layer_viewport -#define GL_ARB_fragment_layer_viewport 1 - -#define GLEW_ARB_fragment_layer_viewport GLEW_GET_VAR(__GLEW_ARB_fragment_layer_viewport) - -#endif /* GL_ARB_fragment_layer_viewport */ - -/* ------------------------ GL_ARB_fragment_program ------------------------ */ - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 - -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 - -#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) - -#endif /* GL_ARB_fragment_program */ - -/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 - -#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) - -#endif /* GL_ARB_fragment_program_shadow */ - -/* ------------------------- GL_ARB_fragment_shader ------------------------ */ - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 - -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B - -#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) - -#endif /* GL_ARB_fragment_shader */ - -/* -------------------- GL_ARB_fragment_shader_interlock ------------------- */ - -#ifndef GL_ARB_fragment_shader_interlock -#define GL_ARB_fragment_shader_interlock 1 - -#define GLEW_ARB_fragment_shader_interlock GLEW_GET_VAR(__GLEW_ARB_fragment_shader_interlock) - -#endif /* GL_ARB_fragment_shader_interlock */ - -/* ------------------- GL_ARB_framebuffer_no_attachments ------------------- */ - -#ifndef GL_ARB_framebuffer_no_attachments -#define GL_ARB_framebuffer_no_attachments 1 - -#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 -#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 -#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 -#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 -#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 -#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 -#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); - -#define glFramebufferParameteri GLEW_GET_FUN(__glewFramebufferParameteri) -#define glGetFramebufferParameteriv GLEW_GET_FUN(__glewGetFramebufferParameteriv) -#define glGetNamedFramebufferParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferParameterivEXT) -#define glNamedFramebufferParameteriEXT GLEW_GET_FUN(__glewNamedFramebufferParameteriEXT) - -#define GLEW_ARB_framebuffer_no_attachments GLEW_GET_VAR(__GLEW_ARB_framebuffer_no_attachments) - -#endif /* GL_ARB_framebuffer_no_attachments */ - -/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_INDEX 0x8222 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_SRGB 0x8C40 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 - -typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); -typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) -#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) -#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) -#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) -#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) -#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) -#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) -#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) -#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) -#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) -#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) -#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) -#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) -#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) -#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) -#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) -#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) -#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) -#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) -#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) - -#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) - -#endif /* GL_ARB_framebuffer_object */ - -/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 - -#define GL_FRAMEBUFFER_SRGB 0x8DB9 - -#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) - -#endif /* GL_ARB_framebuffer_sRGB */ - -/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 - -#define GL_LINES_ADJACENCY_ARB 0xA -#define GL_LINE_STRIP_ADJACENCY_ARB 0xB -#define GL_TRIANGLES_ADJACENCY_ARB 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); - -#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) -#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) -#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) -#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) - -#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) - -#endif /* GL_ARB_geometry_shader4 */ - -/* ----------------------- GL_ARB_get_program_binary ----------------------- */ - -#ifndef GL_ARB_get_program_binary -#define GL_ARB_get_program_binary 1 - -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF - -typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, void*binary); -typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); - -#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary) -#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary) -#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri) - -#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary) - -#endif /* GL_ARB_get_program_binary */ - -/* ---------------------- GL_ARB_get_texture_sub_image --------------------- */ - -#ifndef GL_ARB_get_texture_sub_image -#define GL_ARB_get_texture_sub_image 1 - -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); - -#define glGetCompressedTextureSubImage GLEW_GET_FUN(__glewGetCompressedTextureSubImage) -#define glGetTextureSubImage GLEW_GET_FUN(__glewGetTextureSubImage) - -#define GLEW_ARB_get_texture_sub_image GLEW_GET_VAR(__GLEW_ARB_get_texture_sub_image) - -#endif /* GL_ARB_get_texture_sub_image */ - -/* ---------------------------- GL_ARB_gl_spirv ---------------------------- */ - -#ifndef GL_ARB_gl_spirv -#define GL_ARB_gl_spirv 1 - -#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551 -#define GL_SPIR_V_BINARY_ARB 0x9552 - -typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue); - -#define glSpecializeShaderARB GLEW_GET_FUN(__glewSpecializeShaderARB) - -#define GLEW_ARB_gl_spirv GLEW_GET_VAR(__GLEW_ARB_gl_spirv) - -#endif /* GL_ARB_gl_spirv */ - -/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */ - -#ifndef GL_ARB_gpu_shader5 -#define GL_ARB_gpu_shader5 1 - -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D -#define GL_MAX_VERTEX_STREAMS 0x8E71 - -#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5) - -#endif /* GL_ARB_gpu_shader5 */ - -/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */ - -#ifndef GL_ARB_gpu_shader_fp64 -#define GL_ARB_gpu_shader_fp64 1 - -#define GL_DOUBLE_MAT2 0x8F46 -#define GL_DOUBLE_MAT3 0x8F47 -#define GL_DOUBLE_MAT4 0x8F48 -#define GL_DOUBLE_MAT2x3 0x8F49 -#define GL_DOUBLE_MAT2x4 0x8F4A -#define GL_DOUBLE_MAT3x2 0x8F4B -#define GL_DOUBLE_MAT3x4 0x8F4C -#define GL_DOUBLE_MAT4x2 0x8F4D -#define GL_DOUBLE_MAT4x3 0x8F4E -#define GL_DOUBLE_VEC2 0x8FFC -#define GL_DOUBLE_VEC3 0x8FFD -#define GL_DOUBLE_VEC4 0x8FFE - -typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); -typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); - -#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv) -#define glUniform1d GLEW_GET_FUN(__glewUniform1d) -#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv) -#define glUniform2d GLEW_GET_FUN(__glewUniform2d) -#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv) -#define glUniform3d GLEW_GET_FUN(__glewUniform3d) -#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv) -#define glUniform4d GLEW_GET_FUN(__glewUniform4d) -#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv) -#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv) -#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv) -#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv) -#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv) -#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv) -#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv) -#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv) -#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv) -#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv) - -#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64) - -#endif /* GL_ARB_gpu_shader_fp64 */ - -/* ------------------------ GL_ARB_gpu_shader_int64 ------------------------ */ - -#ifndef GL_ARB_gpu_shader_int64 -#define GL_ARB_gpu_shader_int64 1 - -#define GL_INT64_ARB 0x140E -#define GL_UNSIGNED_INT64_ARB 0x140F -#define GL_INT64_VEC2_ARB 0x8FE9 -#define GL_INT64_VEC3_ARB 0x8FEA -#define GL_INT64_VEC4_ARB 0x8FEB -#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 - -typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x); -typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y); -typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z); -typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); - -#define glGetUniformi64vARB GLEW_GET_FUN(__glewGetUniformi64vARB) -#define glGetUniformui64vARB GLEW_GET_FUN(__glewGetUniformui64vARB) -#define glGetnUniformi64vARB GLEW_GET_FUN(__glewGetnUniformi64vARB) -#define glGetnUniformui64vARB GLEW_GET_FUN(__glewGetnUniformui64vARB) -#define glProgramUniform1i64ARB GLEW_GET_FUN(__glewProgramUniform1i64ARB) -#define glProgramUniform1i64vARB GLEW_GET_FUN(__glewProgramUniform1i64vARB) -#define glProgramUniform1ui64ARB GLEW_GET_FUN(__glewProgramUniform1ui64ARB) -#define glProgramUniform1ui64vARB GLEW_GET_FUN(__glewProgramUniform1ui64vARB) -#define glProgramUniform2i64ARB GLEW_GET_FUN(__glewProgramUniform2i64ARB) -#define glProgramUniform2i64vARB GLEW_GET_FUN(__glewProgramUniform2i64vARB) -#define glProgramUniform2ui64ARB GLEW_GET_FUN(__glewProgramUniform2ui64ARB) -#define glProgramUniform2ui64vARB GLEW_GET_FUN(__glewProgramUniform2ui64vARB) -#define glProgramUniform3i64ARB GLEW_GET_FUN(__glewProgramUniform3i64ARB) -#define glProgramUniform3i64vARB GLEW_GET_FUN(__glewProgramUniform3i64vARB) -#define glProgramUniform3ui64ARB GLEW_GET_FUN(__glewProgramUniform3ui64ARB) -#define glProgramUniform3ui64vARB GLEW_GET_FUN(__glewProgramUniform3ui64vARB) -#define glProgramUniform4i64ARB GLEW_GET_FUN(__glewProgramUniform4i64ARB) -#define glProgramUniform4i64vARB GLEW_GET_FUN(__glewProgramUniform4i64vARB) -#define glProgramUniform4ui64ARB GLEW_GET_FUN(__glewProgramUniform4ui64ARB) -#define glProgramUniform4ui64vARB GLEW_GET_FUN(__glewProgramUniform4ui64vARB) -#define glUniform1i64ARB GLEW_GET_FUN(__glewUniform1i64ARB) -#define glUniform1i64vARB GLEW_GET_FUN(__glewUniform1i64vARB) -#define glUniform1ui64ARB GLEW_GET_FUN(__glewUniform1ui64ARB) -#define glUniform1ui64vARB GLEW_GET_FUN(__glewUniform1ui64vARB) -#define glUniform2i64ARB GLEW_GET_FUN(__glewUniform2i64ARB) -#define glUniform2i64vARB GLEW_GET_FUN(__glewUniform2i64vARB) -#define glUniform2ui64ARB GLEW_GET_FUN(__glewUniform2ui64ARB) -#define glUniform2ui64vARB GLEW_GET_FUN(__glewUniform2ui64vARB) -#define glUniform3i64ARB GLEW_GET_FUN(__glewUniform3i64ARB) -#define glUniform3i64vARB GLEW_GET_FUN(__glewUniform3i64vARB) -#define glUniform3ui64ARB GLEW_GET_FUN(__glewUniform3ui64ARB) -#define glUniform3ui64vARB GLEW_GET_FUN(__glewUniform3ui64vARB) -#define glUniform4i64ARB GLEW_GET_FUN(__glewUniform4i64ARB) -#define glUniform4i64vARB GLEW_GET_FUN(__glewUniform4i64vARB) -#define glUniform4ui64ARB GLEW_GET_FUN(__glewUniform4ui64ARB) -#define glUniform4ui64vARB GLEW_GET_FUN(__glewUniform4ui64vARB) - -#define GLEW_ARB_gpu_shader_int64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_int64) - -#endif /* GL_ARB_gpu_shader_int64 */ - -/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 - -#define GL_HALF_FLOAT_ARB 0x140B - -#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) - -#endif /* GL_ARB_half_float_pixel */ - -/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 - -#define GL_HALF_FLOAT 0x140B - -#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) - -#endif /* GL_ARB_half_float_vertex */ - -/* ----------------------------- GL_ARB_imaging ---------------------------- */ - -#ifndef GL_ARB_imaging -#define GL_ARB_imaging 1 - -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_FUNC_ADD 0x8006 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BLEND_EQUATION 0x8009 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_IGNORE_BORDER 0x8150 -#define GL_CONSTANT_BORDER 0x8151 -#define GL_WRAP_BORDER 0x8152 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 - -typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, void *values); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); - -#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) -#define glColorTable GLEW_GET_FUN(__glewColorTable) -#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) -#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) -#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) -#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) -#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) -#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) -#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) -#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) -#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) -#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) -#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) -#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) -#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) -#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) -#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) -#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) -#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) -#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) -#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) -#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) -#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) -#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) -#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) -#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) -#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) -#define glHistogram GLEW_GET_FUN(__glewHistogram) -#define glMinmax GLEW_GET_FUN(__glewMinmax) -#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) -#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) -#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) - -#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) - -#endif /* GL_ARB_imaging */ - -/* ----------------------- GL_ARB_indirect_parameters ---------------------- */ - -#ifndef GL_ARB_indirect_parameters -#define GL_ARB_indirect_parameters 1 - -#define GL_PARAMETER_BUFFER_ARB 0x80EE -#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); - -#define glMultiDrawArraysIndirectCountARB GLEW_GET_FUN(__glewMultiDrawArraysIndirectCountARB) -#define glMultiDrawElementsIndirectCountARB GLEW_GET_FUN(__glewMultiDrawElementsIndirectCountARB) - -#define GLEW_ARB_indirect_parameters GLEW_GET_VAR(__GLEW_ARB_indirect_parameters) - -#endif /* GL_ARB_indirect_parameters */ - -/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); - -#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) -#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) -#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) - -#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) - -#endif /* GL_ARB_instanced_arrays */ - -/* ---------------------- GL_ARB_internalformat_query ---------------------- */ - -#ifndef GL_ARB_internalformat_query -#define GL_ARB_internalformat_query 1 - -#define GL_NUM_SAMPLE_COUNTS 0x9380 - -typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); - -#define glGetInternalformativ GLEW_GET_FUN(__glewGetInternalformativ) - -#define GLEW_ARB_internalformat_query GLEW_GET_VAR(__GLEW_ARB_internalformat_query) - -#endif /* GL_ARB_internalformat_query */ - -/* ---------------------- GL_ARB_internalformat_query2 --------------------- */ - -#ifndef GL_ARB_internalformat_query2 -#define GL_ARB_internalformat_query2 1 - -#define GL_INTERNALFORMAT_SUPPORTED 0x826F -#define GL_INTERNALFORMAT_PREFERRED 0x8270 -#define GL_INTERNALFORMAT_RED_SIZE 0x8271 -#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 -#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 -#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 -#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 -#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 -#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 -#define GL_INTERNALFORMAT_RED_TYPE 0x8278 -#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 -#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A -#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B -#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C -#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D -#define GL_MAX_WIDTH 0x827E -#define GL_MAX_HEIGHT 0x827F -#define GL_MAX_DEPTH 0x8280 -#define GL_MAX_LAYERS 0x8281 -#define GL_MAX_COMBINED_DIMENSIONS 0x8282 -#define GL_COLOR_COMPONENTS 0x8283 -#define GL_DEPTH_COMPONENTS 0x8284 -#define GL_STENCIL_COMPONENTS 0x8285 -#define GL_COLOR_RENDERABLE 0x8286 -#define GL_DEPTH_RENDERABLE 0x8287 -#define GL_STENCIL_RENDERABLE 0x8288 -#define GL_FRAMEBUFFER_RENDERABLE 0x8289 -#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A -#define GL_FRAMEBUFFER_BLEND 0x828B -#define GL_READ_PIXELS 0x828C -#define GL_READ_PIXELS_FORMAT 0x828D -#define GL_READ_PIXELS_TYPE 0x828E -#define GL_TEXTURE_IMAGE_FORMAT 0x828F -#define GL_TEXTURE_IMAGE_TYPE 0x8290 -#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 -#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 -#define GL_MIPMAP 0x8293 -#define GL_MANUAL_GENERATE_MIPMAP 0x8294 -#define GL_AUTO_GENERATE_MIPMAP 0x8295 -#define GL_COLOR_ENCODING 0x8296 -#define GL_SRGB_READ 0x8297 -#define GL_SRGB_WRITE 0x8298 -#define GL_SRGB_DECODE_ARB 0x8299 -#define GL_FILTER 0x829A -#define GL_VERTEX_TEXTURE 0x829B -#define GL_TESS_CONTROL_TEXTURE 0x829C -#define GL_TESS_EVALUATION_TEXTURE 0x829D -#define GL_GEOMETRY_TEXTURE 0x829E -#define GL_FRAGMENT_TEXTURE 0x829F -#define GL_COMPUTE_TEXTURE 0x82A0 -#define GL_TEXTURE_SHADOW 0x82A1 -#define GL_TEXTURE_GATHER 0x82A2 -#define GL_TEXTURE_GATHER_SHADOW 0x82A3 -#define GL_SHADER_IMAGE_LOAD 0x82A4 -#define GL_SHADER_IMAGE_STORE 0x82A5 -#define GL_SHADER_IMAGE_ATOMIC 0x82A6 -#define GL_IMAGE_TEXEL_SIZE 0x82A7 -#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 -#define GL_IMAGE_PIXEL_FORMAT 0x82A9 -#define GL_IMAGE_PIXEL_TYPE 0x82AA -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF -#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 -#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 -#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 -#define GL_CLEAR_BUFFER 0x82B4 -#define GL_TEXTURE_VIEW 0x82B5 -#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 -#define GL_FULL_SUPPORT 0x82B7 -#define GL_CAVEAT_SUPPORT 0x82B8 -#define GL_IMAGE_CLASS_4_X_32 0x82B9 -#define GL_IMAGE_CLASS_2_X_32 0x82BA -#define GL_IMAGE_CLASS_1_X_32 0x82BB -#define GL_IMAGE_CLASS_4_X_16 0x82BC -#define GL_IMAGE_CLASS_2_X_16 0x82BD -#define GL_IMAGE_CLASS_1_X_16 0x82BE -#define GL_IMAGE_CLASS_4_X_8 0x82BF -#define GL_IMAGE_CLASS_2_X_8 0x82C0 -#define GL_IMAGE_CLASS_1_X_8 0x82C1 -#define GL_IMAGE_CLASS_11_11_10 0x82C2 -#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 -#define GL_VIEW_CLASS_128_BITS 0x82C4 -#define GL_VIEW_CLASS_96_BITS 0x82C5 -#define GL_VIEW_CLASS_64_BITS 0x82C6 -#define GL_VIEW_CLASS_48_BITS 0x82C7 -#define GL_VIEW_CLASS_32_BITS 0x82C8 -#define GL_VIEW_CLASS_24_BITS 0x82C9 -#define GL_VIEW_CLASS_16_BITS 0x82CA -#define GL_VIEW_CLASS_8_BITS 0x82CB -#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC -#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD -#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE -#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF -#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 -#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 -#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 -#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 - -typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params); - -#define glGetInternalformati64v GLEW_GET_FUN(__glewGetInternalformati64v) - -#define GLEW_ARB_internalformat_query2 GLEW_GET_VAR(__GLEW_ARB_internalformat_query2) - -#endif /* GL_ARB_internalformat_query2 */ - -/* ----------------------- GL_ARB_invalidate_subdata ----------------------- */ - -#ifndef GL_ARB_invalidate_subdata -#define GL_ARB_invalidate_subdata 1 - -typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (GLAPIENTRY * PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments); -typedef void (GLAPIENTRY * PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - -#define glInvalidateBufferData GLEW_GET_FUN(__glewInvalidateBufferData) -#define glInvalidateBufferSubData GLEW_GET_FUN(__glewInvalidateBufferSubData) -#define glInvalidateFramebuffer GLEW_GET_FUN(__glewInvalidateFramebuffer) -#define glInvalidateSubFramebuffer GLEW_GET_FUN(__glewInvalidateSubFramebuffer) -#define glInvalidateTexImage GLEW_GET_FUN(__glewInvalidateTexImage) -#define glInvalidateTexSubImage GLEW_GET_FUN(__glewInvalidateTexSubImage) - -#define GLEW_ARB_invalidate_subdata GLEW_GET_VAR(__GLEW_ARB_invalidate_subdata) - -#endif /* GL_ARB_invalidate_subdata */ - -/* ---------------------- GL_ARB_map_buffer_alignment ---------------------- */ - -#ifndef GL_ARB_map_buffer_alignment -#define GL_ARB_map_buffer_alignment 1 - -#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC - -#define GLEW_ARB_map_buffer_alignment GLEW_GET_VAR(__GLEW_ARB_map_buffer_alignment) - -#endif /* GL_ARB_map_buffer_alignment */ - -/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 - -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 - -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); - -#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) -#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) - -#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) - -#endif /* GL_ARB_map_buffer_range */ - -/* ------------------------- GL_ARB_matrix_palette ------------------------- */ - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 - -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 - -typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); - -#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) -#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) -#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) -#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) -#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) - -#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) - -#endif /* GL_ARB_matrix_palette */ - -/* --------------------------- GL_ARB_multi_bind --------------------------- */ - -#ifndef GL_ARB_multi_bind -#define GL_ARB_multi_bind 1 - -typedef void (GLAPIENTRY * PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizeiptr *sizes); -typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); -typedef void (GLAPIENTRY * PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint* samplers); -typedef void (GLAPIENTRY * PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); -typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); - -#define glBindBuffersBase GLEW_GET_FUN(__glewBindBuffersBase) -#define glBindBuffersRange GLEW_GET_FUN(__glewBindBuffersRange) -#define glBindImageTextures GLEW_GET_FUN(__glewBindImageTextures) -#define glBindSamplers GLEW_GET_FUN(__glewBindSamplers) -#define glBindTextures GLEW_GET_FUN(__glewBindTextures) -#define glBindVertexBuffers GLEW_GET_FUN(__glewBindVertexBuffers) - -#define GLEW_ARB_multi_bind GLEW_GET_VAR(__GLEW_ARB_multi_bind) - -#endif /* GL_ARB_multi_bind */ - -/* ----------------------- GL_ARB_multi_draw_indirect ---------------------- */ - -#ifndef GL_ARB_multi_draw_indirect -#define GL_ARB_multi_draw_indirect 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); - -#define glMultiDrawArraysIndirect GLEW_GET_FUN(__glewMultiDrawArraysIndirect) -#define glMultiDrawElementsIndirect GLEW_GET_FUN(__glewMultiDrawElementsIndirect) - -#define GLEW_ARB_multi_draw_indirect GLEW_GET_VAR(__GLEW_ARB_multi_draw_indirect) - -#endif /* GL_ARB_multi_draw_indirect */ - -/* --------------------------- GL_ARB_multisample -------------------------- */ - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 - -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 - -typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); - -#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) - -#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) - -#endif /* GL_ARB_multisample */ - -/* -------------------------- GL_ARB_multitexture -------------------------- */ - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 - -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 - -typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); - -#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) -#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) -#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) -#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) -#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) -#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) -#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) -#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) -#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) -#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) -#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) -#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) -#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) -#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) -#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) -#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) -#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) -#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) -#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) -#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) -#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) -#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) -#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) -#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) -#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) -#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) -#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) -#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) -#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) -#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) -#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) -#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) -#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) -#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) - -#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) - -#endif /* GL_ARB_multitexture */ - -/* ------------------------- GL_ARB_occlusion_query ------------------------ */ - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 - -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); - -#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) -#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) -#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) -#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) -#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) -#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) -#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) -#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) - -#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) - -#endif /* GL_ARB_occlusion_query */ - -/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */ - -#ifndef GL_ARB_occlusion_query2 -#define GL_ARB_occlusion_query2 1 - -#define GL_ANY_SAMPLES_PASSED 0x8C2F - -#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2) - -#endif /* GL_ARB_occlusion_query2 */ - -/* --------------------- GL_ARB_parallel_shader_compile -------------------- */ - -#ifndef GL_ARB_parallel_shader_compile -#define GL_ARB_parallel_shader_compile 1 - -#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 -#define GL_COMPLETION_STATUS_ARB 0x91B1 - -typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count); - -#define glMaxShaderCompilerThreadsARB GLEW_GET_FUN(__glewMaxShaderCompilerThreadsARB) - -#define GLEW_ARB_parallel_shader_compile GLEW_GET_VAR(__GLEW_ARB_parallel_shader_compile) - -#endif /* GL_ARB_parallel_shader_compile */ - -/* -------------------- GL_ARB_pipeline_statistics_query ------------------- */ - -#ifndef GL_ARB_pipeline_statistics_query -#define GL_ARB_pipeline_statistics_query 1 - -#define GL_VERTICES_SUBMITTED_ARB 0x82EE -#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF -#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 -#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 -#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 -#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 -#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F - -#define GLEW_ARB_pipeline_statistics_query GLEW_GET_VAR(__GLEW_ARB_pipeline_statistics_query) - -#endif /* GL_ARB_pipeline_statistics_query */ - -/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 - -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF - -#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) - -#endif /* GL_ARB_pixel_buffer_object */ - -/* ------------------------ GL_ARB_point_parameters ------------------------ */ - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 - -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat* params); - -#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) -#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) - -#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) - -#endif /* GL_ARB_point_parameters */ - -/* -------------------------- GL_ARB_point_sprite -------------------------- */ - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 - -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 - -#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) - -#endif /* GL_ARB_point_sprite */ - -/* ---------------------- GL_ARB_polygon_offset_clamp ---------------------- */ - -#ifndef GL_ARB_polygon_offset_clamp -#define GL_ARB_polygon_offset_clamp 1 - -#define GL_POLYGON_OFFSET_CLAMP 0x8E1B - -typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp); - -#define glPolygonOffsetClamp GLEW_GET_FUN(__glewPolygonOffsetClamp) - -#define GLEW_ARB_polygon_offset_clamp GLEW_GET_VAR(__GLEW_ARB_polygon_offset_clamp) - -#endif /* GL_ARB_polygon_offset_clamp */ - -/* ----------------------- GL_ARB_post_depth_coverage ---------------------- */ - -#ifndef GL_ARB_post_depth_coverage -#define GL_ARB_post_depth_coverage 1 - -#define GLEW_ARB_post_depth_coverage GLEW_GET_VAR(__GLEW_ARB_post_depth_coverage) - -#endif /* GL_ARB_post_depth_coverage */ - -/* --------------------- GL_ARB_program_interface_query -------------------- */ - -#ifndef GL_ARB_program_interface_query -#define GL_ARB_program_interface_query 1 - -#define GL_UNIFORM 0x92E1 -#define GL_UNIFORM_BLOCK 0x92E2 -#define GL_PROGRAM_INPUT 0x92E3 -#define GL_PROGRAM_OUTPUT 0x92E4 -#define GL_BUFFER_VARIABLE 0x92E5 -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#define GL_IS_PER_PATCH 0x92E7 -#define GL_VERTEX_SUBROUTINE 0x92E8 -#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 -#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA -#define GL_GEOMETRY_SUBROUTINE 0x92EB -#define GL_FRAGMENT_SUBROUTINE 0x92EC -#define GL_COMPUTE_SUBROUTINE 0x92ED -#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE -#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF -#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 -#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 -#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 -#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 -#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 -#define GL_ACTIVE_RESOURCES 0x92F5 -#define GL_MAX_NAME_LENGTH 0x92F6 -#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 -#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 -#define GL_NAME_LENGTH 0x92F9 -#define GL_TYPE 0x92FA -#define GL_ARRAY_SIZE 0x92FB -#define GL_OFFSET 0x92FC -#define GL_BLOCK_INDEX 0x92FD -#define GL_ARRAY_STRIDE 0x92FE -#define GL_MATRIX_STRIDE 0x92FF -#define GL_IS_ROW_MAJOR 0x9300 -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_ACTIVE_VARIABLES 0x9305 -#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 -#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 -#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A -#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B -#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C -#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D -#define GL_LOCATION 0x930E -#define GL_LOCATION_INDEX 0x930F - -typedef void (GLAPIENTRY * PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params); -typedef GLuint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); -typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar* name); -typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params); - -#define glGetProgramInterfaceiv GLEW_GET_FUN(__glewGetProgramInterfaceiv) -#define glGetProgramResourceIndex GLEW_GET_FUN(__glewGetProgramResourceIndex) -#define glGetProgramResourceLocation GLEW_GET_FUN(__glewGetProgramResourceLocation) -#define glGetProgramResourceLocationIndex GLEW_GET_FUN(__glewGetProgramResourceLocationIndex) -#define glGetProgramResourceName GLEW_GET_FUN(__glewGetProgramResourceName) -#define glGetProgramResourceiv GLEW_GET_FUN(__glewGetProgramResourceiv) - -#define GLEW_ARB_program_interface_query GLEW_GET_VAR(__GLEW_ARB_program_interface_query) - -#endif /* GL_ARB_program_interface_query */ - -/* ------------------------ GL_ARB_provoking_vertex ------------------------ */ - -#ifndef GL_ARB_provoking_vertex -#define GL_ARB_provoking_vertex 1 - -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F - -typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode); - -#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex) - -#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex) - -#endif /* GL_ARB_provoking_vertex */ - -/* ----------------------- GL_ARB_query_buffer_object ---------------------- */ - -#ifndef GL_ARB_query_buffer_object -#define GL_ARB_query_buffer_object 1 - -#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 -#define GL_QUERY_BUFFER 0x9192 -#define GL_QUERY_BUFFER_BINDING 0x9193 -#define GL_QUERY_RESULT_NO_WAIT 0x9194 - -#define GLEW_ARB_query_buffer_object GLEW_GET_VAR(__GLEW_ARB_query_buffer_object) - -#endif /* GL_ARB_query_buffer_object */ - -/* ------------------ GL_ARB_robust_buffer_access_behavior ----------------- */ - -#ifndef GL_ARB_robust_buffer_access_behavior -#define GL_ARB_robust_buffer_access_behavior 1 - -#define GLEW_ARB_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_ARB_robust_buffer_access_behavior) - -#endif /* GL_ARB_robust_buffer_access_behavior */ - -/* --------------------------- GL_ARB_robustness --------------------------- */ - -#ifndef GL_ARB_robustness -#define GL_ARB_robustness 1 - -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 - -typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table); -typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img); -typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image); -typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); -typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v); -typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v); -typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v); -typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); -typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values); -typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values); -typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values); -typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern); -typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void*column, void*span); -typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); -typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data); - -#define glGetGraphicsResetStatusARB GLEW_GET_FUN(__glewGetGraphicsResetStatusARB) -#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB) -#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB) -#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB) -#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB) -#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB) -#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB) -#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB) -#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB) -#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB) -#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB) -#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB) -#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB) -#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB) -#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB) -#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB) -#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB) -#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB) -#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB) -#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB) - -#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness) - -#endif /* GL_ARB_robustness */ - -/* ---------------- GL_ARB_robustness_application_isolation ---------------- */ - -#ifndef GL_ARB_robustness_application_isolation -#define GL_ARB_robustness_application_isolation 1 - -#define GLEW_ARB_robustness_application_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_application_isolation) - -#endif /* GL_ARB_robustness_application_isolation */ - -/* ---------------- GL_ARB_robustness_share_group_isolation ---------------- */ - -#ifndef GL_ARB_robustness_share_group_isolation -#define GL_ARB_robustness_share_group_isolation 1 - -#define GLEW_ARB_robustness_share_group_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_share_group_isolation) - -#endif /* GL_ARB_robustness_share_group_isolation */ - -/* ------------------------ GL_ARB_sample_locations ------------------------ */ - -#ifndef GL_ARB_sample_locations -#define GL_ARB_sample_locations 1 - -#define GL_SAMPLE_LOCATION_ARB 0x8E50 -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); - -#define glFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewFramebufferSampleLocationsfvARB) -#define glNamedFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvARB) - -#define GLEW_ARB_sample_locations GLEW_GET_VAR(__GLEW_ARB_sample_locations) - -#endif /* GL_ARB_sample_locations */ - -/* ------------------------- GL_ARB_sample_shading ------------------------- */ - -#ifndef GL_ARB_sample_shading -#define GL_ARB_sample_shading 1 - -#define GL_SAMPLE_SHADING_ARB 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 - -typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); - -#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB) - -#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading) - -#endif /* GL_ARB_sample_shading */ - -/* ------------------------- GL_ARB_sampler_objects ------------------------ */ - -#ifndef GL_ARB_sampler_objects -#define GL_ARB_sampler_objects 1 - -#define GL_SAMPLER_BINDING 0x8919 - -typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); -typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers); -typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params); - -#define glBindSampler GLEW_GET_FUN(__glewBindSampler) -#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers) -#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers) -#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv) -#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv) -#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv) -#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv) -#define glIsSampler GLEW_GET_FUN(__glewIsSampler) -#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv) -#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv) -#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf) -#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv) -#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri) -#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv) - -#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects) - -#endif /* GL_ARB_sampler_objects */ - -/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */ - -#ifndef GL_ARB_seamless_cube_map -#define GL_ARB_seamless_cube_map 1 - -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F - -#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map) - -#endif /* GL_ARB_seamless_cube_map */ - -/* ------------------ GL_ARB_seamless_cubemap_per_texture ------------------ */ - -#ifndef GL_ARB_seamless_cubemap_per_texture -#define GL_ARB_seamless_cubemap_per_texture 1 - -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F - -#define GLEW_ARB_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_ARB_seamless_cubemap_per_texture) - -#endif /* GL_ARB_seamless_cubemap_per_texture */ - -/* --------------------- GL_ARB_separate_shader_objects -------------------- */ - -#ifndef GL_ARB_separate_shader_objects -#define GL_ARB_separate_shader_objects 1 - -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#define GL_ALL_SHADER_BITS 0xFFFFFFFF - -typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); -typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar * const * strings); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines); -typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar *infoLog); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); - -#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram) -#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline) -#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv) -#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines) -#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines) -#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog) -#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv) -#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline) -#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d) -#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv) -#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f) -#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv) -#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i) -#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv) -#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui) -#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv) -#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d) -#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv) -#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f) -#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv) -#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i) -#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv) -#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui) -#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv) -#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d) -#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv) -#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f) -#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv) -#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i) -#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv) -#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui) -#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv) -#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d) -#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv) -#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f) -#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv) -#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i) -#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv) -#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui) -#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv) -#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv) -#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv) -#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv) -#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv) -#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv) -#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv) -#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv) -#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv) -#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv) -#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv) -#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv) -#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv) -#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv) -#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv) -#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv) -#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv) -#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv) -#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv) -#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages) -#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline) - -#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects) - -#endif /* GL_ARB_separate_shader_objects */ - -/* -------------------- GL_ARB_shader_atomic_counter_ops ------------------- */ - -#ifndef GL_ARB_shader_atomic_counter_ops -#define GL_ARB_shader_atomic_counter_ops 1 - -#define GLEW_ARB_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counter_ops) - -#endif /* GL_ARB_shader_atomic_counter_ops */ - -/* --------------------- GL_ARB_shader_atomic_counters --------------------- */ - -#ifndef GL_ARB_shader_atomic_counters -#define GL_ARB_shader_atomic_counters 1 - -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 -#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 -#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 -#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB -#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF -#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 -#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 -#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 -#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 -#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 -#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 -#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC - -typedef void (GLAPIENTRY * PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint* params); - -#define glGetActiveAtomicCounterBufferiv GLEW_GET_FUN(__glewGetActiveAtomicCounterBufferiv) - -#define GLEW_ARB_shader_atomic_counters GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counters) - -#endif /* GL_ARB_shader_atomic_counters */ - -/* -------------------------- GL_ARB_shader_ballot ------------------------- */ - -#ifndef GL_ARB_shader_ballot -#define GL_ARB_shader_ballot 1 - -#define GLEW_ARB_shader_ballot GLEW_GET_VAR(__GLEW_ARB_shader_ballot) - -#endif /* GL_ARB_shader_ballot */ - -/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */ - -#ifndef GL_ARB_shader_bit_encoding -#define GL_ARB_shader_bit_encoding 1 - -#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding) - -#endif /* GL_ARB_shader_bit_encoding */ - -/* -------------------------- GL_ARB_shader_clock -------------------------- */ - -#ifndef GL_ARB_shader_clock -#define GL_ARB_shader_clock 1 - -#define GLEW_ARB_shader_clock GLEW_GET_VAR(__GLEW_ARB_shader_clock) - -#endif /* GL_ARB_shader_clock */ - -/* --------------------- GL_ARB_shader_draw_parameters --------------------- */ - -#ifndef GL_ARB_shader_draw_parameters -#define GL_ARB_shader_draw_parameters 1 - -#define GLEW_ARB_shader_draw_parameters GLEW_GET_VAR(__GLEW_ARB_shader_draw_parameters) - -#endif /* GL_ARB_shader_draw_parameters */ - -/* ------------------------ GL_ARB_shader_group_vote ----------------------- */ - -#ifndef GL_ARB_shader_group_vote -#define GL_ARB_shader_group_vote 1 - -#define GLEW_ARB_shader_group_vote GLEW_GET_VAR(__GLEW_ARB_shader_group_vote) - -#endif /* GL_ARB_shader_group_vote */ - -/* --------------------- GL_ARB_shader_image_load_store -------------------- */ - -#ifndef GL_ARB_shader_image_load_store -#define GL_ARB_shader_image_load_store 1 - -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_MAX_IMAGE_UNITS 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 -#define GL_IMAGE_BINDING_NAME 0x8F3A -#define GL_IMAGE_BINDING_LEVEL 0x8F3B -#define GL_IMAGE_BINDING_LAYERED 0x8F3C -#define GL_IMAGE_BINDING_LAYER 0x8F3D -#define GL_IMAGE_BINDING_ACCESS 0x8F3E -#define GL_IMAGE_1D 0x904C -#define GL_IMAGE_2D 0x904D -#define GL_IMAGE_3D 0x904E -#define GL_IMAGE_2D_RECT 0x904F -#define GL_IMAGE_CUBE 0x9050 -#define GL_IMAGE_BUFFER 0x9051 -#define GL_IMAGE_1D_ARRAY 0x9052 -#define GL_IMAGE_2D_ARRAY 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 -#define GL_INT_IMAGE_1D 0x9057 -#define GL_INT_IMAGE_2D 0x9058 -#define GL_INT_IMAGE_3D 0x9059 -#define GL_INT_IMAGE_2D_RECT 0x905A -#define GL_INT_IMAGE_CUBE 0x905B -#define GL_INT_IMAGE_BUFFER 0x905C -#define GL_INT_IMAGE_1D_ARRAY 0x905D -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C -#define GL_MAX_IMAGE_SAMPLES 0x906D -#define GL_IMAGE_BINDING_FORMAT 0x906E -#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 -#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD -#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE -#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF - -typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); - -#define glBindImageTexture GLEW_GET_FUN(__glewBindImageTexture) -#define glMemoryBarrier GLEW_GET_FUN(__glewMemoryBarrier) - -#define GLEW_ARB_shader_image_load_store GLEW_GET_VAR(__GLEW_ARB_shader_image_load_store) - -#endif /* GL_ARB_shader_image_load_store */ - -/* ------------------------ GL_ARB_shader_image_size ----------------------- */ - -#ifndef GL_ARB_shader_image_size -#define GL_ARB_shader_image_size 1 - -#define GLEW_ARB_shader_image_size GLEW_GET_VAR(__GLEW_ARB_shader_image_size) - -#endif /* GL_ARB_shader_image_size */ - -/* ------------------------- GL_ARB_shader_objects ------------------------- */ - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 - -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 - -typedef char GLcharARB; -typedef unsigned int GLhandleARB; - -typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); -typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); -typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); -typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); - -#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) -#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) -#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) -#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) -#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) -#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) -#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) -#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) -#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) -#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) -#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) -#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) -#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) -#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) -#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) -#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) -#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) -#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) -#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) -#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) -#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) -#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) -#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) -#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) -#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) -#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) -#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) -#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) -#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) -#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) -#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) -#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) -#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) -#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) -#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) -#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) -#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) -#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) -#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) - -#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) - -#endif /* GL_ARB_shader_objects */ - -/* ------------------------ GL_ARB_shader_precision ------------------------ */ - -#ifndef GL_ARB_shader_precision -#define GL_ARB_shader_precision 1 - -#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision) - -#endif /* GL_ARB_shader_precision */ - -/* ---------------------- GL_ARB_shader_stencil_export --------------------- */ - -#ifndef GL_ARB_shader_stencil_export -#define GL_ARB_shader_stencil_export 1 - -#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export) - -#endif /* GL_ARB_shader_stencil_export */ - -/* ------------------ GL_ARB_shader_storage_buffer_object ------------------ */ - -#ifndef GL_ARB_shader_storage_buffer_object -#define GL_ARB_shader_storage_buffer_object 1 - -#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 -#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 -#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 -#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 -#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA -#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB -#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC -#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD -#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE -#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF - -typedef void (GLAPIENTRY * PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); - -#define glShaderStorageBlockBinding GLEW_GET_FUN(__glewShaderStorageBlockBinding) - -#define GLEW_ARB_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_ARB_shader_storage_buffer_object) - -#endif /* GL_ARB_shader_storage_buffer_object */ - -/* ------------------------ GL_ARB_shader_subroutine ----------------------- */ - -#ifndef GL_ARB_shader_subroutine -#define GL_ARB_shader_subroutine 1 - -#define GL_ACTIVE_SUBROUTINES 0x8DE5 -#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 -#define GL_MAX_SUBROUTINES 0x8DE7 -#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 -#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 -#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A -#define GL_COMPATIBLE_SUBROUTINES 0x8E4B - -typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values); -typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar* name); -typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params); -typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices); - -#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName) -#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName) -#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv) -#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv) -#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex) -#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation) -#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv) -#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv) - -#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine) - -#endif /* GL_ARB_shader_subroutine */ - -/* ------------------ GL_ARB_shader_texture_image_samples ------------------ */ - -#ifndef GL_ARB_shader_texture_image_samples -#define GL_ARB_shader_texture_image_samples 1 - -#define GLEW_ARB_shader_texture_image_samples GLEW_GET_VAR(__GLEW_ARB_shader_texture_image_samples) - -#endif /* GL_ARB_shader_texture_image_samples */ - -/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */ - -#ifndef GL_ARB_shader_texture_lod -#define GL_ARB_shader_texture_lod 1 - -#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod) - -#endif /* GL_ARB_shader_texture_lod */ - -/* ------------------- GL_ARB_shader_viewport_layer_array ------------------ */ - -#ifndef GL_ARB_shader_viewport_layer_array -#define GL_ARB_shader_viewport_layer_array 1 - -#define GLEW_ARB_shader_viewport_layer_array GLEW_GET_VAR(__GLEW_ARB_shader_viewport_layer_array) - -#endif /* GL_ARB_shader_viewport_layer_array */ - -/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 - -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C - -#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) - -#endif /* GL_ARB_shading_language_100 */ - -/* -------------------- GL_ARB_shading_language_420pack -------------------- */ - -#ifndef GL_ARB_shading_language_420pack -#define GL_ARB_shading_language_420pack 1 - -#define GLEW_ARB_shading_language_420pack GLEW_GET_VAR(__GLEW_ARB_shading_language_420pack) - -#endif /* GL_ARB_shading_language_420pack */ - -/* -------------------- GL_ARB_shading_language_include -------------------- */ - -#ifndef GL_ARB_shading_language_include -#define GL_ARB_shading_language_include 1 - -#define GL_SHADER_INCLUDE_ARB 0x8DAE -#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 -#define GL_NAMED_STRING_TYPE_ARB 0x8DEA - -typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* const *path, const GLint *length); -typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name, GLsizei bufSize, GLint *stringlen, GLchar *string); -typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar* name, GLenum pname, GLint *params); -typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar* name, GLint stringlen, const GLchar *string); - -#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB) -#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB) -#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB) -#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB) -#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB) -#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB) - -#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include) - -#endif /* GL_ARB_shading_language_include */ - -/* -------------------- GL_ARB_shading_language_packing -------------------- */ - -#ifndef GL_ARB_shading_language_packing -#define GL_ARB_shading_language_packing 1 - -#define GLEW_ARB_shading_language_packing GLEW_GET_VAR(__GLEW_ARB_shading_language_packing) - -#endif /* GL_ARB_shading_language_packing */ - -/* ----------------------------- GL_ARB_shadow ----------------------------- */ - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 - -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E - -#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) - -#endif /* GL_ARB_shadow */ - -/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 - -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF - -#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) - -#endif /* GL_ARB_shadow_ambient */ - -/* -------------------------- GL_ARB_sparse_buffer ------------------------- */ - -#ifndef GL_ARB_sparse_buffer -#define GL_ARB_sparse_buffer 1 - -#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 -#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 - -typedef void (GLAPIENTRY * PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); - -#define glBufferPageCommitmentARB GLEW_GET_FUN(__glewBufferPageCommitmentARB) - -#define GLEW_ARB_sparse_buffer GLEW_GET_VAR(__GLEW_ARB_sparse_buffer) - -#endif /* GL_ARB_sparse_buffer */ - -/* ------------------------- GL_ARB_sparse_texture ------------------------- */ - -#ifndef GL_ARB_sparse_texture -#define GL_ARB_sparse_texture 1 - -#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A -#define GL_TEXTURE_SPARSE_ARB 0x91A6 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA - -typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); - -#define glTexPageCommitmentARB GLEW_GET_FUN(__glewTexPageCommitmentARB) - -#define GLEW_ARB_sparse_texture GLEW_GET_VAR(__GLEW_ARB_sparse_texture) - -#endif /* GL_ARB_sparse_texture */ - -/* ------------------------- GL_ARB_sparse_texture2 ------------------------ */ - -#ifndef GL_ARB_sparse_texture2 -#define GL_ARB_sparse_texture2 1 - -#define GLEW_ARB_sparse_texture2 GLEW_GET_VAR(__GLEW_ARB_sparse_texture2) - -#endif /* GL_ARB_sparse_texture2 */ - -/* ---------------------- GL_ARB_sparse_texture_clamp ---------------------- */ - -#ifndef GL_ARB_sparse_texture_clamp -#define GL_ARB_sparse_texture_clamp 1 - -#define GLEW_ARB_sparse_texture_clamp GLEW_GET_VAR(__GLEW_ARB_sparse_texture_clamp) - -#endif /* GL_ARB_sparse_texture_clamp */ - -/* ------------------------ GL_ARB_spirv_extensions ------------------------ */ - -#ifndef GL_ARB_spirv_extensions -#define GL_ARB_spirv_extensions 1 - -#define GL_SPIR_V_EXTENSIONS 0x9553 -#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 - -#define GLEW_ARB_spirv_extensions GLEW_GET_VAR(__GLEW_ARB_spirv_extensions) - -#endif /* GL_ARB_spirv_extensions */ - -/* ------------------------ GL_ARB_stencil_texturing ----------------------- */ - -#ifndef GL_ARB_stencil_texturing -#define GL_ARB_stencil_texturing 1 - -#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA - -#define GLEW_ARB_stencil_texturing GLEW_GET_VAR(__GLEW_ARB_stencil_texturing) - -#endif /* GL_ARB_stencil_texturing */ - -/* ------------------------------ GL_ARB_sync ------------------------------ */ - -#ifndef GL_ARB_sync -#define GL_ARB_sync 1 - -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull - -typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); -typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync); -typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values); -typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync); -typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); - -#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync) -#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync) -#define glFenceSync GLEW_GET_FUN(__glewFenceSync) -#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v) -#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv) -#define glIsSync GLEW_GET_FUN(__glewIsSync) -#define glWaitSync GLEW_GET_FUN(__glewWaitSync) - -#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync) - -#endif /* GL_ARB_sync */ - -/* ----------------------- GL_ARB_tessellation_shader ---------------------- */ - -#ifndef GL_ARB_tessellation_shader -#define GL_ARB_tessellation_shader 1 - -#define GL_PATCHES 0xE -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F -#define GL_PATCH_VERTICES 0x8E72 -#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 -#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 -#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 -#define GL_TESS_GEN_MODE 0x8E76 -#define GL_TESS_GEN_SPACING 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 -#define GL_TESS_GEN_POINT_MODE 0x8E79 -#define GL_ISOLINES 0x8E7A -#define GL_FRACTIONAL_ODD 0x8E7B -#define GL_FRACTIONAL_EVEN 0x8E7C -#define GL_MAX_PATCH_VERTICES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 -#define GL_TESS_EVALUATION_SHADER 0x8E87 -#define GL_TESS_CONTROL_SHADER 0x8E88 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A - -typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values); -typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); - -#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv) -#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri) - -#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader) - -#endif /* GL_ARB_tessellation_shader */ - -/* ------------------------- GL_ARB_texture_barrier ------------------------ */ - -#ifndef GL_ARB_texture_barrier -#define GL_ARB_texture_barrier 1 - -typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERPROC) (void); - -#define glTextureBarrier GLEW_GET_FUN(__glewTextureBarrier) - -#define GLEW_ARB_texture_barrier GLEW_GET_VAR(__GLEW_ARB_texture_barrier) - -#endif /* GL_ARB_texture_barrier */ - -/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 - -#define GL_CLAMP_TO_BORDER_ARB 0x812D - -#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) - -#endif /* GL_ARB_texture_border_clamp */ - -/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 - -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E - -typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); - -#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) - -#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) - -#endif /* GL_ARB_texture_buffer_object */ - -/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */ - -#ifndef GL_ARB_texture_buffer_object_rgb32 -#define GL_ARB_texture_buffer_object_rgb32 1 - -#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32) - -#endif /* GL_ARB_texture_buffer_object_rgb32 */ - -/* ---------------------- GL_ARB_texture_buffer_range ---------------------- */ - -#ifndef GL_ARB_texture_buffer_range -#define GL_ARB_texture_buffer_range 1 - -#define GL_TEXTURE_BUFFER_OFFSET 0x919D -#define GL_TEXTURE_BUFFER_SIZE 0x919E -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F - -typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); - -#define glTexBufferRange GLEW_GET_FUN(__glewTexBufferRange) -#define glTextureBufferRangeEXT GLEW_GET_FUN(__glewTextureBufferRangeEXT) - -#define GLEW_ARB_texture_buffer_range GLEW_GET_VAR(__GLEW_ARB_texture_buffer_range) - -#endif /* GL_ARB_texture_buffer_range */ - -/* ----------------------- GL_ARB_texture_compression ---------------------- */ - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 - -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 - -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void *img); - -#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) -#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) -#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) -#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) -#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) -#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) -#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) - -#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) - -#endif /* GL_ARB_texture_compression */ - -/* -------------------- GL_ARB_texture_compression_bptc -------------------- */ - -#ifndef GL_ARB_texture_compression_bptc -#define GL_ARB_texture_compression_bptc 1 - -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F - -#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc) - -#endif /* GL_ARB_texture_compression_bptc */ - -/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 - -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE - -#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) - -#endif /* GL_ARB_texture_compression_rgtc */ - -/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 - -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C - -#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) - -#endif /* GL_ARB_texture_cube_map */ - -/* --------------------- GL_ARB_texture_cube_map_array --------------------- */ - -#ifndef GL_ARB_texture_cube_map_array -#define GL_ARB_texture_cube_map_array 1 - -#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F - -#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array) - -#endif /* GL_ARB_texture_cube_map_array */ - -/* ------------------------- GL_ARB_texture_env_add ------------------------ */ - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 - -#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) - -#endif /* GL_ARB_texture_env_add */ - -/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 - -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A - -#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) - -#endif /* GL_ARB_texture_env_combine */ - -/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 - -#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) - -#endif /* GL_ARB_texture_env_crossbar */ - -/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 - -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF - -#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) - -#endif /* GL_ARB_texture_env_dot3 */ - -/* ------------------- GL_ARB_texture_filter_anisotropic ------------------- */ - -#ifndef GL_ARB_texture_filter_anisotropic -#define GL_ARB_texture_filter_anisotropic 1 - -#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF - -#define GLEW_ARB_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_ARB_texture_filter_anisotropic) - -#endif /* GL_ARB_texture_filter_anisotropic */ - -/* ---------------------- GL_ARB_texture_filter_minmax --------------------- */ - -#ifndef GL_ARB_texture_filter_minmax -#define GL_ARB_texture_filter_minmax 1 - -#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 -#define GL_WEIGHTED_AVERAGE_ARB 0x9367 - -#define GLEW_ARB_texture_filter_minmax GLEW_GET_VAR(__GLEW_ARB_texture_filter_minmax) - -#endif /* GL_ARB_texture_filter_minmax */ - -/* -------------------------- GL_ARB_texture_float ------------------------- */ - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 - -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 - -#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) - -#endif /* GL_ARB_texture_float */ - -/* ------------------------- GL_ARB_texture_gather ------------------------- */ - -#ifndef GL_ARB_texture_gather -#define GL_ARB_texture_gather 1 - -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F - -#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather) - -#endif /* GL_ARB_texture_gather */ - -/* ------------------ GL_ARB_texture_mirror_clamp_to_edge ------------------ */ - -#ifndef GL_ARB_texture_mirror_clamp_to_edge -#define GL_ARB_texture_mirror_clamp_to_edge 1 - -#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 - -#define GLEW_ARB_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_ARB_texture_mirror_clamp_to_edge) - -#endif /* GL_ARB_texture_mirror_clamp_to_edge */ - -/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 - -#define GL_MIRRORED_REPEAT_ARB 0x8370 - -#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) - -#endif /* GL_ARB_texture_mirrored_repeat */ - -/* ----------------------- GL_ARB_texture_multisample ---------------------- */ - -#ifndef GL_ARB_texture_multisample -#define GL_ARB_texture_multisample 1 - -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 - -typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - -#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv) -#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski) -#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample) -#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample) - -#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample) - -#endif /* GL_ARB_texture_multisample */ - -/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 - -#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) - -#endif /* GL_ARB_texture_non_power_of_two */ - -/* ---------------------- GL_ARB_texture_query_levels ---------------------- */ - -#ifndef GL_ARB_texture_query_levels -#define GL_ARB_texture_query_levels 1 - -#define GLEW_ARB_texture_query_levels GLEW_GET_VAR(__GLEW_ARB_texture_query_levels) - -#endif /* GL_ARB_texture_query_levels */ - -/* ------------------------ GL_ARB_texture_query_lod ----------------------- */ - -#ifndef GL_ARB_texture_query_lod -#define GL_ARB_texture_query_lod 1 - -#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod) - -#endif /* GL_ARB_texture_query_lod */ - -/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 - -#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) - -#endif /* GL_ARB_texture_rectangle */ - -/* --------------------------- GL_ARB_texture_rg --------------------------- */ - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 - -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C - -#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) - -#endif /* GL_ARB_texture_rg */ - -/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */ - -#ifndef GL_ARB_texture_rgb10_a2ui -#define GL_ARB_texture_rgb10_a2ui 1 - -#define GL_RGB10_A2UI 0x906F - -#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui) - -#endif /* GL_ARB_texture_rgb10_a2ui */ - -/* ------------------------ GL_ARB_texture_stencil8 ------------------------ */ - -#ifndef GL_ARB_texture_stencil8 -#define GL_ARB_texture_stencil8 1 - -#define GL_STENCIL_INDEX 0x1901 -#define GL_STENCIL_INDEX8 0x8D48 - -#define GLEW_ARB_texture_stencil8 GLEW_GET_VAR(__GLEW_ARB_texture_stencil8) - -#endif /* GL_ARB_texture_stencil8 */ - -/* ------------------------- GL_ARB_texture_storage ------------------------ */ - -#ifndef GL_ARB_texture_storage -#define GL_ARB_texture_storage 1 - -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F - -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - -#define glTexStorage1D GLEW_GET_FUN(__glewTexStorage1D) -#define glTexStorage2D GLEW_GET_FUN(__glewTexStorage2D) -#define glTexStorage3D GLEW_GET_FUN(__glewTexStorage3D) - -#define GLEW_ARB_texture_storage GLEW_GET_VAR(__GLEW_ARB_texture_storage) - -#endif /* GL_ARB_texture_storage */ - -/* ------------------- GL_ARB_texture_storage_multisample ------------------ */ - -#ifndef GL_ARB_texture_storage_multisample -#define GL_ARB_texture_storage_multisample 1 - -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - -#define glTexStorage2DMultisample GLEW_GET_FUN(__glewTexStorage2DMultisample) -#define glTexStorage3DMultisample GLEW_GET_FUN(__glewTexStorage3DMultisample) -#define glTextureStorage2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage2DMultisampleEXT) -#define glTextureStorage3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage3DMultisampleEXT) - -#define GLEW_ARB_texture_storage_multisample GLEW_GET_VAR(__GLEW_ARB_texture_storage_multisample) - -#endif /* GL_ARB_texture_storage_multisample */ - -/* ------------------------- GL_ARB_texture_swizzle ------------------------ */ - -#ifndef GL_ARB_texture_swizzle -#define GL_ARB_texture_swizzle 1 - -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 - -#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle) - -#endif /* GL_ARB_texture_swizzle */ - -/* -------------------------- GL_ARB_texture_view -------------------------- */ - -#ifndef GL_ARB_texture_view -#define GL_ARB_texture_view 1 - -#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB -#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC -#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD -#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF - -typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); - -#define glTextureView GLEW_GET_FUN(__glewTextureView) - -#define GLEW_ARB_texture_view GLEW_GET_VAR(__GLEW_ARB_texture_view) - -#endif /* GL_ARB_texture_view */ - -/* --------------------------- GL_ARB_timer_query -------------------------- */ - -#ifndef GL_ARB_timer_query -#define GL_ARB_timer_query 1 - -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 - -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); -typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); - -#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v) -#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v) -#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter) - -#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query) - -#endif /* GL_ARB_timer_query */ - -/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */ - -#ifndef GL_ARB_transform_feedback2 -#define GL_ARB_transform_feedback2 1 - -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 - -typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); -typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); -typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); -typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); - -#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback) -#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks) -#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback) -#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks) -#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback) -#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback) -#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback) - -#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2) - -#endif /* GL_ARB_transform_feedback2 */ - -/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */ - -#ifndef GL_ARB_transform_feedback3 -#define GL_ARB_transform_feedback3 1 - -#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 -#define GL_MAX_VERTEX_STREAMS 0x8E71 - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); -typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); - -#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed) -#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream) -#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed) -#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv) - -#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3) - -#endif /* GL_ARB_transform_feedback3 */ - -/* ------------------ GL_ARB_transform_feedback_instanced ------------------ */ - -#ifndef GL_ARB_transform_feedback_instanced -#define GL_ARB_transform_feedback_instanced 1 - -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); - -#define glDrawTransformFeedbackInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackInstanced) -#define glDrawTransformFeedbackStreamInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackStreamInstanced) - -#define GLEW_ARB_transform_feedback_instanced GLEW_GET_VAR(__GLEW_ARB_transform_feedback_instanced) - -#endif /* GL_ARB_transform_feedback_instanced */ - -/* ---------------- GL_ARB_transform_feedback_overflow_query --------------- */ - -#ifndef GL_ARB_transform_feedback_overflow_query -#define GL_ARB_transform_feedback_overflow_query 1 - -#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED - -#define GLEW_ARB_transform_feedback_overflow_query GLEW_GET_VAR(__GLEW_ARB_transform_feedback_overflow_query) - -#endif /* GL_ARB_transform_feedback_overflow_query */ - -/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 - -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 - -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); - -#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) -#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) -#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) -#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) - -#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) - -#endif /* GL_ARB_transpose_matrix */ - -/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */ - -#ifndef GL_ARB_uniform_buffer_object -#define GL_ARB_uniform_buffer_object 1 - -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFFu - -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); -typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint* uniformIndices); -typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); - -#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) -#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) -#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName) -#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv) -#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName) -#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv) -#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) -#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex) -#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices) -#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding) - -#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object) - -#endif /* GL_ARB_uniform_buffer_object */ - -/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */ - -#ifndef GL_ARB_vertex_array_bgra -#define GL_ARB_vertex_array_bgra 1 - -#define GL_BGRA 0x80E1 - -#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra) - -#endif /* GL_ARB_vertex_array_bgra */ - -/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 - -#define GL_VERTEX_ARRAY_BINDING 0x85B5 - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); - -#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) -#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) -#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) -#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) - -#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) - -#endif /* GL_ARB_vertex_array_object */ - -/* ----------------------- GL_ARB_vertex_attrib_64bit ---------------------- */ - -#ifndef GL_ARB_vertex_attrib_64bit -#define GL_ARB_vertex_attrib_64bit 1 - -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); - -#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv) -#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d) -#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv) -#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d) -#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv) -#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d) -#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv) -#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d) -#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv) -#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer) - -#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit) - -#endif /* GL_ARB_vertex_attrib_64bit */ - -/* ---------------------- GL_ARB_vertex_attrib_binding --------------------- */ - -#ifndef GL_ARB_vertex_attrib_binding -#define GL_ARB_vertex_attrib_binding 1 - -#define GL_VERTEX_ATTRIB_BINDING 0x82D4 -#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 -#define GL_VERTEX_BINDING_DIVISOR 0x82D6 -#define GL_VERTEX_BINDING_OFFSET 0x82D7 -#define GL_VERTEX_BINDING_STRIDE 0x82D8 -#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 -#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA -#define GL_VERTEX_BINDING_BUFFER 0x8F4F - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); - -#define glBindVertexBuffer GLEW_GET_FUN(__glewBindVertexBuffer) -#define glVertexArrayBindVertexBufferEXT GLEW_GET_FUN(__glewVertexArrayBindVertexBufferEXT) -#define glVertexArrayVertexAttribBindingEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribBindingEXT) -#define glVertexArrayVertexAttribFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribFormatEXT) -#define glVertexArrayVertexAttribIFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIFormatEXT) -#define glVertexArrayVertexAttribLFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLFormatEXT) -#define glVertexArrayVertexBindingDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexBindingDivisorEXT) -#define glVertexAttribBinding GLEW_GET_FUN(__glewVertexAttribBinding) -#define glVertexAttribFormat GLEW_GET_FUN(__glewVertexAttribFormat) -#define glVertexAttribIFormat GLEW_GET_FUN(__glewVertexAttribIFormat) -#define glVertexAttribLFormat GLEW_GET_FUN(__glewVertexAttribLFormat) -#define glVertexBindingDivisor GLEW_GET_FUN(__glewVertexBindingDivisor) - -#define GLEW_ARB_vertex_attrib_binding GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_binding) - -#endif /* GL_ARB_vertex_attrib_binding */ - -/* -------------------------- GL_ARB_vertex_blend -------------------------- */ - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 - -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F - -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); -typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); -typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); - -#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) -#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) -#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) -#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) -#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) -#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) -#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) -#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) -#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) -#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) - -#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) - -#endif /* GL_ARB_vertex_blend */ - -/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 - -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA - -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; - -typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); -typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); - -#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) -#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) -#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) -#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) -#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) -#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) -#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) -#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) -#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) -#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) -#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) - -#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) - -#endif /* GL_ARB_vertex_buffer_object */ - -/* ------------------------- GL_ARB_vertex_program ------------------------- */ - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 - -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF - -typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void** pointer); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); - -#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) -#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) -#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) -#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) -#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) -#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) -#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) -#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) -#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) -#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) -#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) -#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) -#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) -#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) -#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) -#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) -#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) -#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) -#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) -#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) -#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) -#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) -#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) -#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) -#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) -#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) -#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) -#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) -#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) -#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) -#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) -#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) -#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) -#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) -#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) -#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) -#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) -#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) -#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) -#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) -#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) -#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) -#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) -#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) -#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) -#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) -#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) -#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) -#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) -#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) -#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) -#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) -#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) -#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) -#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) -#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) -#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) -#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) -#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) -#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) -#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) -#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) - -#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) - -#endif /* GL_ARB_vertex_program */ - -/* -------------------------- GL_ARB_vertex_shader ------------------------- */ - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 - -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A - -typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); -typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); - -#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) -#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) -#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) - -#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) - -#endif /* GL_ARB_vertex_shader */ - -/* ------------------- GL_ARB_vertex_type_10f_11f_11f_rev ------------------ */ - -#ifndef GL_ARB_vertex_type_10f_11f_11f_rev -#define GL_ARB_vertex_type_10f_11f_11f_rev 1 - -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B - -#define GLEW_ARB_vertex_type_10f_11f_11f_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_10f_11f_11f_rev) - -#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ - -/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */ - -#ifndef GL_ARB_vertex_type_2_10_10_10_rev -#define GL_ARB_vertex_type_2_10_10_10_rev 1 - -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_INT_2_10_10_10_REV 0x8D9F - -typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color); -typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); -typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); -typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); -typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value); - -#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui) -#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv) -#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui) -#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv) -#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui) -#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv) -#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui) -#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv) -#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui) -#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv) -#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui) -#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv) -#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui) -#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv) -#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui) -#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv) -#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui) -#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv) -#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui) -#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv) -#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui) -#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv) -#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui) -#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv) -#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui) -#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv) -#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui) -#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv) -#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui) -#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv) -#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui) -#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv) -#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui) -#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv) -#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui) -#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv) -#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui) -#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv) - -#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev) - -#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ - -/* ------------------------- GL_ARB_viewport_array ------------------------- */ - -#ifndef GL_ARB_viewport_array -#define GL_ARB_viewport_array 1 - -#define GL_DEPTH_RANGE 0x0B70 -#define GL_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_MAX_VIEWPORTS 0x825B -#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C -#define GL_VIEWPORT_BOUNDS_RANGE 0x825D -#define GL_LAYER_PROVOKING_VERTEX 0x825E -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F -#define GL_UNDEFINED_VERTEX 0x8260 -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F - -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); -typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data); -typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data); -typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v); -typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v); -typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v); -typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v); - -#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv) -#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed) -#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v) -#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v) -#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv) -#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed) -#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv) -#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv) -#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf) -#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv) - -#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array) - -#endif /* GL_ARB_viewport_array */ - -/* --------------------------- GL_ARB_window_pos --------------------------- */ - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 - -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); - -#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) -#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) -#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) -#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) -#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) -#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) -#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) -#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) -#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) -#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) -#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) -#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) -#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) -#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) -#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) -#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) - -#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) - -#endif /* GL_ARB_window_pos */ - -/* ----------------------- GL_ARM_mali_program_binary ---------------------- */ - -#ifndef GL_ARM_mali_program_binary -#define GL_ARM_mali_program_binary 1 - -#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 - -#define GLEW_ARM_mali_program_binary GLEW_GET_VAR(__GLEW_ARM_mali_program_binary) - -#endif /* GL_ARM_mali_program_binary */ - -/* ----------------------- GL_ARM_mali_shader_binary ----------------------- */ - -#ifndef GL_ARM_mali_shader_binary -#define GL_ARM_mali_shader_binary 1 - -#define GL_MALI_SHADER_BINARY_ARM 0x8F60 - -#define GLEW_ARM_mali_shader_binary GLEW_GET_VAR(__GLEW_ARM_mali_shader_binary) - -#endif /* GL_ARM_mali_shader_binary */ - -/* ------------------------------ GL_ARM_rgba8 ----------------------------- */ - -#ifndef GL_ARM_rgba8 -#define GL_ARM_rgba8 1 - -#define GL_RGBA8_OES 0x8058 - -#define GLEW_ARM_rgba8 GLEW_GET_VAR(__GLEW_ARM_rgba8) - -#endif /* GL_ARM_rgba8 */ - -/* -------------------- GL_ARM_shader_framebuffer_fetch -------------------- */ - -#ifndef GL_ARM_shader_framebuffer_fetch -#define GL_ARM_shader_framebuffer_fetch 1 - -#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 -#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 - -#define GLEW_ARM_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch) - -#endif /* GL_ARM_shader_framebuffer_fetch */ - -/* ------------- GL_ARM_shader_framebuffer_fetch_depth_stencil ------------- */ - -#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil -#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 - -#define GLEW_ARM_shader_framebuffer_fetch_depth_stencil GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch_depth_stencil) - -#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */ - -/* ---------------- GL_ARM_texture_unnormalized_coordinates ---------------- */ - -#ifndef GL_ARM_texture_unnormalized_coordinates -#define GL_ARM_texture_unnormalized_coordinates 1 - -#define GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM 0x8F6A - -#define GLEW_ARM_texture_unnormalized_coordinates GLEW_GET_VAR(__GLEW_ARM_texture_unnormalized_coordinates) - -#endif /* GL_ARM_texture_unnormalized_coordinates */ - -/* ------------------------- GL_ATIX_point_sprites ------------------------- */ - -#ifndef GL_ATIX_point_sprites -#define GL_ATIX_point_sprites 1 - -#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 -#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 -#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 -#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 -#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 -#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 - -#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) - -#endif /* GL_ATIX_point_sprites */ - -/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ - -#ifndef GL_ATIX_texture_env_combine3 -#define GL_ATIX_texture_env_combine3 1 - -#define GL_MODULATE_ADD_ATIX 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 -#define GL_MODULATE_SUBTRACT_ATIX 0x8746 - -#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) - -#endif /* GL_ATIX_texture_env_combine3 */ - -/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ - -#ifndef GL_ATIX_texture_env_route -#define GL_ATIX_texture_env_route 1 - -#define GL_SECONDARY_COLOR_ATIX 0x8747 -#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 -#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 - -#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) - -#endif /* GL_ATIX_texture_env_route */ - -/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ - -#ifndef GL_ATIX_vertex_shader_output_point_size -#define GL_ATIX_vertex_shader_output_point_size 1 - -#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E - -#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) - -#endif /* GL_ATIX_vertex_shader_output_point_size */ - -/* -------------------------- GL_ATI_draw_buffers -------------------------- */ - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) - -#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) - -#endif /* GL_ATI_draw_buffers */ - -/* -------------------------- GL_ATI_element_array ------------------------- */ - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 - -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); - -#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) -#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) -#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) - -#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) - -#endif /* GL_ATI_element_array */ - -/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 - -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C - -typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); - -#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) -#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) -#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) -#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) - -#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) - -#endif /* GL_ATI_envmap_bumpmap */ - -/* ------------------------- GL_ATI_fragment_shader ------------------------ */ - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 - -#define GL_2X_BIT_ATI 0x00000001 -#define GL_RED_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B - -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); - -#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) -#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) -#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) -#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) -#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) -#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) -#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) -#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) -#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) -#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) -#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) -#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) -#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) -#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) - -#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) - -#endif /* GL_ATI_fragment_shader */ - -/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 - -typedef void * (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); - -#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) -#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) - -#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) - -#endif /* GL_ATI_map_object_buffer */ - -/* ----------------------------- GL_ATI_meminfo ---------------------------- */ - -#ifndef GL_ATI_meminfo -#define GL_ATI_meminfo 1 - -#define GL_VBO_FREE_MEMORY_ATI 0x87FB -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC -#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD - -#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo) - -#endif /* GL_ATI_meminfo */ - -/* -------------------------- GL_ATI_pn_triangles -------------------------- */ - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 - -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 - -typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); - -#define glPNTrianglesfATI GLEW_GET_FUN(__glewPNTrianglesfATI) -#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI) - -#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) - -#endif /* GL_ATI_pn_triangles */ - -/* ------------------------ GL_ATI_separate_stencil ------------------------ */ - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 - -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 - -typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); - -#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) -#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) - -#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) - -#endif /* GL_ATI_separate_stencil */ - -/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ - -#ifndef GL_ATI_shader_texture_lod -#define GL_ATI_shader_texture_lod 1 - -#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) - -#endif /* GL_ATI_shader_texture_lod */ - -/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 - -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 - -#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) - -#endif /* GL_ATI_text_fragment_shader */ - -/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ - -#ifndef GL_ATI_texture_compression_3dc -#define GL_ATI_texture_compression_3dc 1 - -#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 - -#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) - -#endif /* GL_ATI_texture_compression_3dc */ - -/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 - -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 - -#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) - -#endif /* GL_ATI_texture_env_combine3 */ - -/* -------------------------- GL_ATI_texture_float ------------------------- */ - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 - -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F - -#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) - -#endif /* GL_ATI_texture_float */ - -/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 - -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 - -#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) - -#endif /* GL_ATI_texture_mirror_once */ - -/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 - -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 - -typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); -typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); -typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); - -#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) -#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) -#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) -#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) -#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) -#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) -#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) -#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) -#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) -#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) -#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) -#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) - -#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) - -#endif /* GL_ATI_vertex_array_object */ - -/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 - -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); - -#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) -#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) -#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) - -#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) - -#endif /* GL_ATI_vertex_attrib_array_object */ - -/* ------------------------- GL_ATI_vertex_streams ------------------------- */ - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 - -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_SOURCE_ATI 0x876C -#define GL_VERTEX_STREAM0_ATI 0x876D -#define GL_VERTEX_STREAM1_ATI 0x876E -#define GL_VERTEX_STREAM2_ATI 0x876F -#define GL_VERTEX_STREAM3_ATI 0x8770 -#define GL_VERTEX_STREAM4_ATI 0x8771 -#define GL_VERTEX_STREAM5_ATI 0x8772 -#define GL_VERTEX_STREAM6_ATI 0x8773 -#define GL_VERTEX_STREAM7_ATI 0x8774 - -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); - -#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) -#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) -#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) -#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) -#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) -#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) -#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) -#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) -#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) -#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) -#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) -#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) -#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) -#define glVertexStream1dATI GLEW_GET_FUN(__glewVertexStream1dATI) -#define glVertexStream1dvATI GLEW_GET_FUN(__glewVertexStream1dvATI) -#define glVertexStream1fATI GLEW_GET_FUN(__glewVertexStream1fATI) -#define glVertexStream1fvATI GLEW_GET_FUN(__glewVertexStream1fvATI) -#define glVertexStream1iATI GLEW_GET_FUN(__glewVertexStream1iATI) -#define glVertexStream1ivATI GLEW_GET_FUN(__glewVertexStream1ivATI) -#define glVertexStream1sATI GLEW_GET_FUN(__glewVertexStream1sATI) -#define glVertexStream1svATI GLEW_GET_FUN(__glewVertexStream1svATI) -#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) -#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) -#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) -#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) -#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) -#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) -#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) -#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) -#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) -#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) -#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) -#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) -#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) -#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) -#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) -#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) -#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) -#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) -#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) -#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) -#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) -#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) -#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) -#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) - -#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) - -#endif /* GL_ATI_vertex_streams */ - -/* ------------------------- GL_DMP_program_binary ------------------------- */ - -#ifndef GL_DMP_program_binary -#define GL_DMP_program_binary 1 - -#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 -#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 -#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 - -#define GLEW_DMP_program_binary GLEW_GET_VAR(__GLEW_DMP_program_binary) - -#endif /* GL_DMP_program_binary */ - -/* -------------------------- GL_DMP_shader_binary ------------------------- */ - -#ifndef GL_DMP_shader_binary -#define GL_DMP_shader_binary 1 - -#define GL_SHADER_BINARY_DMP 0x9250 - -#define GLEW_DMP_shader_binary GLEW_GET_VAR(__GLEW_DMP_shader_binary) - -#endif /* GL_DMP_shader_binary */ - -/* --------------------------- GL_EXT_422_pixels --------------------------- */ - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 - -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF - -#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) - -#endif /* GL_EXT_422_pixels */ - -/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ - -#ifndef GL_EXT_Cg_shader -#define GL_EXT_Cg_shader 1 - -#define GL_CG_VERTEX_SHADER_EXT 0x890E -#define GL_CG_FRAGMENT_SHADER_EXT 0x890F - -#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) - -#endif /* GL_EXT_Cg_shader */ - -/* ------------------------- GL_EXT_EGL_image_array ------------------------ */ - -#ifndef GL_EXT_EGL_image_array -#define GL_EXT_EGL_image_array 1 - -#define GLEW_EXT_EGL_image_array GLEW_GET_VAR(__GLEW_EXT_EGL_image_array) - -#endif /* GL_EXT_EGL_image_array */ - -/* ------------------ GL_EXT_EGL_image_external_wrap_modes ----------------- */ - -#ifndef GL_EXT_EGL_image_external_wrap_modes -#define GL_EXT_EGL_image_external_wrap_modes 1 - -#define GLEW_EXT_EGL_image_external_wrap_modes GLEW_GET_VAR(__GLEW_EXT_EGL_image_external_wrap_modes) - -#endif /* GL_EXT_EGL_image_external_wrap_modes */ - -/* ------------------------ GL_EXT_EGL_image_storage ----------------------- */ - -#ifndef GL_EXT_EGL_image_storage -#define GL_EXT_EGL_image_storage 1 - -typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list); -typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list); - -#define glEGLImageTargetTexStorageEXT GLEW_GET_FUN(__glewEGLImageTargetTexStorageEXT) -#define glEGLImageTargetTextureStorageEXT GLEW_GET_FUN(__glewEGLImageTargetTextureStorageEXT) - -#define GLEW_EXT_EGL_image_storage GLEW_GET_VAR(__GLEW_EXT_EGL_image_storage) - -#endif /* GL_EXT_EGL_image_storage */ - -/* ---------------------------- GL_EXT_EGL_sync ---------------------------- */ - -#ifndef GL_EXT_EGL_sync -#define GL_EXT_EGL_sync 1 - -#define GLEW_EXT_EGL_sync GLEW_GET_VAR(__GLEW_EXT_EGL_sync) - -#endif /* GL_EXT_EGL_sync */ - -/* --------------------------- GL_EXT_YUV_target --------------------------- */ - -#ifndef GL_EXT_YUV_target -#define GL_EXT_YUV_target 1 - -#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 - -#define GLEW_EXT_YUV_target GLEW_GET_VAR(__GLEW_EXT_YUV_target) - -#endif /* GL_EXT_YUV_target */ - -/* ------------------------------ GL_EXT_abgr ------------------------------ */ - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 - -#define GL_ABGR_EXT 0x8000 - -#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) - -#endif /* GL_EXT_abgr */ - -/* -------------------------- GL_EXT_base_instance ------------------------- */ - -#ifndef GL_EXT_base_instance -#define GL_EXT_base_instance 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); - -#define glDrawArraysInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstanceEXT) -#define glDrawElementsInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstanceEXT) -#define glDrawElementsInstancedBaseVertexBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstanceEXT) - -#define GLEW_EXT_base_instance GLEW_GET_VAR(__GLEW_EXT_base_instance) - -#endif /* GL_EXT_base_instance */ - -/* ------------------------------ GL_EXT_bgra ------------------------------ */ - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 - -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 - -#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) - -#endif /* GL_EXT_bgra */ - -/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 - -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF - -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); - -#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) -#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) -#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) - -#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) - -#endif /* GL_EXT_bindable_uniform */ - -/* --------------------------- GL_EXT_blend_color -------------------------- */ - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 - -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 - -typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - -#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) - -#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) - -#endif /* GL_EXT_blend_color */ - -/* --------------------- GL_EXT_blend_equation_separate -------------------- */ - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 - -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); - -#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) - -#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) - -#endif /* GL_EXT_blend_equation_separate */ - -/* ----------------------- GL_EXT_blend_func_extended ---------------------- */ - -#ifndef GL_EXT_blend_func_extended -#define GL_EXT_blend_func_extended 1 - -#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 -#define GL_SRC1_ALPHA_EXT 0x8589 -#define GL_SRC1_COLOR_EXT 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC -#define GL_LOCATION_INDEX_EXT 0x930F - -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar * name); -typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar* name); - -#define glBindFragDataLocationIndexedEXT GLEW_GET_FUN(__glewBindFragDataLocationIndexedEXT) -#define glGetFragDataIndexEXT GLEW_GET_FUN(__glewGetFragDataIndexEXT) -#define glGetProgramResourceLocationIndexEXT GLEW_GET_FUN(__glewGetProgramResourceLocationIndexEXT) - -#define GLEW_EXT_blend_func_extended GLEW_GET_VAR(__GLEW_EXT_blend_func_extended) - -#endif /* GL_EXT_blend_func_extended */ - -/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 - -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB - -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - -#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) - -#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) - -#endif /* GL_EXT_blend_func_separate */ - -/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 - -#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) - -#endif /* GL_EXT_blend_logic_op */ - -/* -------------------------- GL_EXT_blend_minmax -------------------------- */ - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 - -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_BLEND_EQUATION_EXT 0x8009 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); - -#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) - -#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) - -#endif /* GL_EXT_blend_minmax */ - -/* ------------------------- GL_EXT_blend_subtract ------------------------- */ - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 - -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B - -#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) - -#endif /* GL_EXT_blend_subtract */ - -/* ------------------------- GL_EXT_buffer_storage ------------------------- */ - -#ifndef GL_EXT_buffer_storage -#define GL_EXT_buffer_storage 1 - -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 -#define GL_MAP_COHERENT_BIT_EXT 0x0080 -#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 -#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 -#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F -#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 - -typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); - -#define glBufferStorageEXT GLEW_GET_FUN(__glewBufferStorageEXT) -#define glNamedBufferStorageEXT GLEW_GET_FUN(__glewNamedBufferStorageEXT) - -#define GLEW_EXT_buffer_storage GLEW_GET_VAR(__GLEW_EXT_buffer_storage) - -#endif /* GL_EXT_buffer_storage */ - -/* -------------------------- GL_EXT_clear_texture ------------------------- */ - -#ifndef GL_EXT_clear_texture -#define GL_EXT_clear_texture 1 - -typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); - -#define glClearTexImageEXT GLEW_GET_FUN(__glewClearTexImageEXT) -#define glClearTexSubImageEXT GLEW_GET_FUN(__glewClearTexSubImageEXT) - -#define GLEW_EXT_clear_texture GLEW_GET_VAR(__GLEW_EXT_clear_texture) - -#endif /* GL_EXT_clear_texture */ - -/* -------------------------- GL_EXT_clip_control -------------------------- */ - -#ifndef GL_EXT_clip_control -#define GL_EXT_clip_control 1 - -#define GL_LOWER_LEFT_EXT 0x8CA1 -#define GL_UPPER_LEFT_EXT 0x8CA2 -#define GL_CLIP_ORIGIN_EXT 0x935C -#define GL_CLIP_DEPTH_MODE_EXT 0x935D -#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E -#define GL_ZERO_TO_ONE_EXT 0x935F - -typedef void (GLAPIENTRY * PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth); - -#define glClipControlEXT GLEW_GET_FUN(__glewClipControlEXT) - -#define GLEW_EXT_clip_control GLEW_GET_VAR(__GLEW_EXT_clip_control) - -#endif /* GL_EXT_clip_control */ - -/* ----------------------- GL_EXT_clip_cull_distance ----------------------- */ - -#ifndef GL_EXT_clip_cull_distance -#define GL_EXT_clip_cull_distance 1 - -#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 -#define GL_CLIP_DISTANCE0_EXT 0x3000 -#define GL_CLIP_DISTANCE1_EXT 0x3001 -#define GL_CLIP_DISTANCE2_EXT 0x3002 -#define GL_CLIP_DISTANCE3_EXT 0x3003 -#define GL_CLIP_DISTANCE4_EXT 0x3004 -#define GL_CLIP_DISTANCE5_EXT 0x3005 -#define GL_CLIP_DISTANCE6_EXT 0x3006 -#define GL_CLIP_DISTANCE7_EXT 0x3007 -#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA - -#define GLEW_EXT_clip_cull_distance GLEW_GET_VAR(__GLEW_EXT_clip_cull_distance) - -#endif /* GL_EXT_clip_cull_distance */ - -/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 - -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 - -#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) - -#endif /* GL_EXT_clip_volume_hint */ - -/* ------------------------------ GL_EXT_cmyka ----------------------------- */ - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 - -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F - -#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) - -#endif /* GL_EXT_cmyka */ - -/* ----------------------- GL_EXT_color_buffer_float ----------------------- */ - -#ifndef GL_EXT_color_buffer_float -#define GL_EXT_color_buffer_float 1 - -#define GLEW_EXT_color_buffer_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_float) - -#endif /* GL_EXT_color_buffer_float */ - -/* --------------------- GL_EXT_color_buffer_half_float -------------------- */ - -#ifndef GL_EXT_color_buffer_half_float -#define GL_EXT_color_buffer_half_float 1 - -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 -#define GL_R16F_EXT 0x822D -#define GL_RG16F_EXT 0x822F -#define GL_RGBA16F_EXT 0x881A -#define GL_RGB16F_EXT 0x881B -#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 - -#define GLEW_EXT_color_buffer_half_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_half_float) - -#endif /* GL_EXT_color_buffer_half_float */ - -/* ------------------------- GL_EXT_color_subtable ------------------------- */ - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 - -typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); - -#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) -#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) - -#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) - -#endif /* GL_EXT_color_subtable */ - -/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 - -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 - -typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); - -#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) -#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) - -#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) - -#endif /* GL_EXT_compiled_vertex_array */ - -/* ---------------- GL_EXT_compressed_ETC1_RGB8_sub_texture ---------------- */ - -#ifndef GL_EXT_compressed_ETC1_RGB8_sub_texture -#define GL_EXT_compressed_ETC1_RGB8_sub_texture 1 - -#define GLEW_EXT_compressed_ETC1_RGB8_sub_texture GLEW_GET_VAR(__GLEW_EXT_compressed_ETC1_RGB8_sub_texture) - -#endif /* GL_EXT_compressed_ETC1_RGB8_sub_texture */ - -/* ----------------------- GL_EXT_conservative_depth ----------------------- */ - -#ifndef GL_EXT_conservative_depth -#define GL_EXT_conservative_depth 1 - -#define GLEW_EXT_conservative_depth GLEW_GET_VAR(__GLEW_EXT_conservative_depth) - -#endif /* GL_EXT_conservative_depth */ - -/* --------------------------- GL_EXT_convolution -------------------------- */ - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 - -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 - -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); - -#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) -#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) -#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) -#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) -#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) -#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) -#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) -#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) -#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) -#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) -#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) -#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) -#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) - -#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) - -#endif /* GL_EXT_convolution */ - -/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 - -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 - -typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer); -typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer); - -#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) -#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) - -#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) - -#endif /* GL_EXT_coordinate_frame */ - -/* --------------------------- GL_EXT_copy_image --------------------------- */ - -#ifndef GL_EXT_copy_image -#define GL_EXT_copy_image 1 - -typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -#define glCopyImageSubDataEXT GLEW_GET_FUN(__glewCopyImageSubDataEXT) - -#define GLEW_EXT_copy_image GLEW_GET_VAR(__GLEW_EXT_copy_image) - -#endif /* GL_EXT_copy_image */ - -/* -------------------------- GL_EXT_copy_texture -------------------------- */ - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 - -typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - -#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) -#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) -#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) -#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) -#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) - -#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) - -#endif /* GL_EXT_copy_texture */ - -/* --------------------------- GL_EXT_cull_vertex -------------------------- */ - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 - -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC - -typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); - -#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) -#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) - -#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) - -#endif /* GL_EXT_cull_vertex */ - -/* --------------------------- GL_EXT_debug_label -------------------------- */ - -#ifndef GL_EXT_debug_label -#define GL_EXT_debug_label 1 - -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 - -typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei* length, GLchar *label); -typedef void (GLAPIENTRY * PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar* label); - -#define glGetObjectLabelEXT GLEW_GET_FUN(__glewGetObjectLabelEXT) -#define glLabelObjectEXT GLEW_GET_FUN(__glewLabelObjectEXT) - -#define GLEW_EXT_debug_label GLEW_GET_VAR(__GLEW_EXT_debug_label) - -#endif /* GL_EXT_debug_label */ - -/* -------------------------- GL_EXT_debug_marker -------------------------- */ - -#ifndef GL_EXT_debug_marker -#define GL_EXT_debug_marker 1 - -typedef void (GLAPIENTRY * PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar* marker); -typedef void (GLAPIENTRY * PFNGLPOPGROUPMARKEREXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar* marker); - -#define glInsertEventMarkerEXT GLEW_GET_FUN(__glewInsertEventMarkerEXT) -#define glPopGroupMarkerEXT GLEW_GET_FUN(__glewPopGroupMarkerEXT) -#define glPushGroupMarkerEXT GLEW_GET_FUN(__glewPushGroupMarkerEXT) - -#define GLEW_EXT_debug_marker GLEW_GET_VAR(__GLEW_EXT_debug_marker) - -#endif /* GL_EXT_debug_marker */ - -/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 - -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 - -typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); - -#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) - -#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) - -#endif /* GL_EXT_depth_bounds_test */ - -/* --------------------------- GL_EXT_depth_clamp -------------------------- */ - -#ifndef GL_EXT_depth_clamp -#define GL_EXT_depth_clamp 1 - -#define GL_DEPTH_CLAMP_EXT 0x864F - -#define GLEW_EXT_depth_clamp GLEW_GET_VAR(__GLEW_EXT_depth_clamp) - -#endif /* GL_EXT_depth_clamp */ - -/* ----------------------- GL_EXT_direct_state_access ---------------------- */ - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 - -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F - -typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void *img); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void *img); -typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void** params); -typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void** params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void** param); -typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void** param); -typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); -typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); -typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); -typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); - -#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) -#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) -#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) -#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) -#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) -#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) -#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) -#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) -#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) -#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) -#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) -#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) -#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) -#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) -#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) -#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) -#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) -#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) -#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) -#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) -#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) -#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) -#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) -#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) -#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) -#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) -#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT) -#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT) -#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT) -#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) -#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT) -#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT) -#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT) -#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT) -#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) -#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) -#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) -#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) -#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) -#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) -#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) -#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) -#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT) -#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) -#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT) -#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) -#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) -#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) -#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) -#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) -#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) -#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) -#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) -#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) -#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) -#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) -#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) -#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) -#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) -#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) -#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) -#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) -#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) -#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) -#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) -#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) -#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) -#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) -#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) -#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) -#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT) -#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) -#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) -#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) -#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) -#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) -#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) -#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) -#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT) -#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT) -#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT) -#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT) -#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) -#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT) -#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) -#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) -#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) -#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) -#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) -#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) -#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) -#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) -#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) -#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) -#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) -#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) -#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) -#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) -#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) -#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) -#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) -#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) -#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) -#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) -#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) -#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) -#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) -#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) -#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) -#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) -#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) -#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) -#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) -#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) -#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) -#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) -#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) -#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) -#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) -#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) -#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) -#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) -#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) -#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) -#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) -#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) -#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) -#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) -#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) -#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) -#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT) -#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) -#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) -#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) -#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) -#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) -#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) -#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) -#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) -#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) -#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) -#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) -#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) -#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) -#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) -#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) -#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) -#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) -#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) -#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) -#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) -#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) -#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) -#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) -#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) -#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) -#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) -#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) -#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) -#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) -#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) -#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) -#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) -#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) -#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) -#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) -#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) -#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) -#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) -#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) -#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) -#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) -#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) -#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) -#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) -#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) -#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) -#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) -#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) -#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) -#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) -#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) -#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) -#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) -#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) -#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) -#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) -#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) -#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) -#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) -#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) -#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) -#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) -#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) -#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) -#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) -#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) -#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) -#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) -#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) -#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) -#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) -#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT) -#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT) -#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT) -#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT) -#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT) -#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT) -#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT) -#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT) -#define glVertexArrayVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribDivisorEXT) -#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT) -#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT) -#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT) - -#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) - -#endif /* GL_EXT_direct_state_access */ - -/* ----------------------- GL_EXT_discard_framebuffer ---------------------- */ - -#ifndef GL_EXT_discard_framebuffer -#define GL_EXT_discard_framebuffer 1 - -#define GL_COLOR_EXT 0x1800 -#define GL_DEPTH_EXT 0x1801 -#define GL_STENCIL_EXT 0x1802 - -typedef void (GLAPIENTRY * PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments); - -#define glDiscardFramebufferEXT GLEW_GET_FUN(__glewDiscardFramebufferEXT) - -#define GLEW_EXT_discard_framebuffer GLEW_GET_VAR(__GLEW_EXT_discard_framebuffer) - -#endif /* GL_EXT_discard_framebuffer */ - -/* ---------------------- GL_EXT_disjoint_timer_query ---------------------- */ - -#ifndef GL_EXT_disjoint_timer_query -#define GL_EXT_disjoint_timer_query 1 - -#define GL_QUERY_COUNTER_BITS_EXT 0x8864 -#define GL_CURRENT_QUERY_EXT 0x8865 -#define GL_QUERY_RESULT_EXT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 -#define GL_TIME_ELAPSED_EXT 0x88BF -#define GL_TIMESTAMP_EXT 0x8E28 -#define GL_GPU_DISJOINT_EXT 0x8FBB - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64* data); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYEXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); - -#define glBeginQueryEXT GLEW_GET_FUN(__glewBeginQueryEXT) -#define glDeleteQueriesEXT GLEW_GET_FUN(__glewDeleteQueriesEXT) -#define glEndQueryEXT GLEW_GET_FUN(__glewEndQueryEXT) -#define glGenQueriesEXT GLEW_GET_FUN(__glewGenQueriesEXT) -#define glGetInteger64vEXT GLEW_GET_FUN(__glewGetInteger64vEXT) -#define glGetQueryObjectivEXT GLEW_GET_FUN(__glewGetQueryObjectivEXT) -#define glGetQueryObjectuivEXT GLEW_GET_FUN(__glewGetQueryObjectuivEXT) -#define glGetQueryivEXT GLEW_GET_FUN(__glewGetQueryivEXT) -#define glIsQueryEXT GLEW_GET_FUN(__glewIsQueryEXT) -#define glQueryCounterEXT GLEW_GET_FUN(__glewQueryCounterEXT) - -#define GLEW_EXT_disjoint_timer_query GLEW_GET_VAR(__GLEW_EXT_disjoint_timer_query) - -#endif /* GL_EXT_disjoint_timer_query */ - -/* -------------------------- GL_EXT_draw_buffers -------------------------- */ - -#ifndef GL_EXT_draw_buffers -#define GL_EXT_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 -#define GL_DRAW_BUFFER0_EXT 0x8825 -#define GL_DRAW_BUFFER1_EXT 0x8826 -#define GL_DRAW_BUFFER2_EXT 0x8827 -#define GL_DRAW_BUFFER3_EXT 0x8828 -#define GL_DRAW_BUFFER4_EXT 0x8829 -#define GL_DRAW_BUFFER5_EXT 0x882A -#define GL_DRAW_BUFFER6_EXT 0x882B -#define GL_DRAW_BUFFER7_EXT 0x882C -#define GL_DRAW_BUFFER8_EXT 0x882D -#define GL_DRAW_BUFFER9_EXT 0x882E -#define GL_DRAW_BUFFER10_EXT 0x882F -#define GL_DRAW_BUFFER11_EXT 0x8830 -#define GL_DRAW_BUFFER12_EXT 0x8831 -#define GL_DRAW_BUFFER13_EXT 0x8832 -#define GL_DRAW_BUFFER14_EXT 0x8833 -#define GL_DRAW_BUFFER15_EXT 0x8834 -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersEXT GLEW_GET_FUN(__glewDrawBuffersEXT) - -#define GLEW_EXT_draw_buffers GLEW_GET_VAR(__GLEW_EXT_draw_buffers) - -#endif /* GL_EXT_draw_buffers */ - -/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 - -typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); -typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); - -#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) -#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) -#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) -#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) -#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) -#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) - -#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) - -#endif /* GL_EXT_draw_buffers2 */ - -/* ---------------------- GL_EXT_draw_buffers_indexed ---------------------- */ - -#ifndef GL_EXT_draw_buffers_indexed -#define GL_EXT_draw_buffers_indexed 1 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (GLAPIENTRY * PFNGLCOLORMASKIEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAPIENTRY * PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEIEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index); - -#define glBlendEquationSeparateiEXT GLEW_GET_FUN(__glewBlendEquationSeparateiEXT) -#define glBlendEquationiEXT GLEW_GET_FUN(__glewBlendEquationiEXT) -#define glBlendFuncSeparateiEXT GLEW_GET_FUN(__glewBlendFuncSeparateiEXT) -#define glBlendFunciEXT GLEW_GET_FUN(__glewBlendFunciEXT) -#define glColorMaskiEXT GLEW_GET_FUN(__glewColorMaskiEXT) -#define glDisableiEXT GLEW_GET_FUN(__glewDisableiEXT) -#define glEnableiEXT GLEW_GET_FUN(__glewEnableiEXT) -#define glIsEnablediEXT GLEW_GET_FUN(__glewIsEnablediEXT) - -#define GLEW_EXT_draw_buffers_indexed GLEW_GET_VAR(__GLEW_EXT_draw_buffers_indexed) - -#endif /* GL_EXT_draw_buffers_indexed */ - -/* -------------------- GL_EXT_draw_elements_base_vertex ------------------- */ - -#ifndef GL_EXT_draw_elements_base_vertex -#define GL_EXT_draw_elements_base_vertex 1 - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex); - -#define glDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsBaseVertexEXT) -#define glDrawElementsInstancedBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexEXT) -#define glDrawRangeElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawRangeElementsBaseVertexEXT) -#define glMultiDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewMultiDrawElementsBaseVertexEXT) - -#define GLEW_EXT_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_EXT_draw_elements_base_vertex) - -#endif /* GL_EXT_draw_elements_base_vertex */ - -/* ------------------------- GL_EXT_draw_instanced ------------------------- */ - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); - -#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) -#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) - -#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) - -#endif /* GL_EXT_draw_instanced */ - -/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 - -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 - -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); - -#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) - -#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) - -#endif /* GL_EXT_draw_range_elements */ - -/* --------------------- GL_EXT_draw_transform_feedback -------------------- */ - -#ifndef GL_EXT_draw_transform_feedback -#define GL_EXT_draw_transform_feedback 1 - -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) (GLenum mode, GLuint id); -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) (GLenum mode, GLuint id, GLsizei instancecount); - -#define glDrawTransformFeedbackEXT GLEW_GET_FUN(__glewDrawTransformFeedbackEXT) -#define glDrawTransformFeedbackInstancedEXT GLEW_GET_FUN(__glewDrawTransformFeedbackInstancedEXT) - -#define GLEW_EXT_draw_transform_feedback GLEW_GET_VAR(__GLEW_EXT_draw_transform_feedback) - -#endif /* GL_EXT_draw_transform_feedback */ - -/* ------------------------- GL_EXT_external_buffer ------------------------ */ - -#ifndef GL_EXT_external_buffer -#define GL_EXT_external_buffer 1 - -typedef void* GLeglClientBufferEXT; - -typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); - -#define glBufferStorageExternalEXT GLEW_GET_FUN(__glewBufferStorageExternalEXT) -#define glNamedBufferStorageExternalEXT GLEW_GET_FUN(__glewNamedBufferStorageExternalEXT) - -#define GLEW_EXT_external_buffer GLEW_GET_VAR(__GLEW_EXT_external_buffer) - -#endif /* GL_EXT_external_buffer */ - -/* --------------------------- GL_EXT_float_blend -------------------------- */ - -#ifndef GL_EXT_float_blend -#define GL_EXT_float_blend 1 - -#define GLEW_EXT_float_blend GLEW_GET_VAR(__GLEW_EXT_float_blend) - -#endif /* GL_EXT_float_blend */ - -/* ---------------------------- GL_EXT_fog_coord --------------------------- */ - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 - -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 - -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); - -#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) -#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) -#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) -#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) -#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) - -#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) - -#endif /* GL_EXT_fog_coord */ - -/* --------------------------- GL_EXT_frag_depth --------------------------- */ - -#ifndef GL_EXT_frag_depth -#define GL_EXT_frag_depth 1 - -#define GLEW_EXT_frag_depth GLEW_GET_VAR(__GLEW_EXT_frag_depth) - -#endif /* GL_EXT_frag_depth */ - -/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ - -#ifndef GL_EXT_fragment_lighting -#define GL_EXT_fragment_lighting 1 - -#define GL_FRAGMENT_LIGHTING_EXT 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 -#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 -#define GL_LIGHT_ENV_MODE_EXT 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B -#define GL_FRAGMENT_LIGHT0_EXT 0x840C -#define GL_FRAGMENT_LIGHT7_EXT 0x8413 - -typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); - -#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) -#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) -#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) -#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) -#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) -#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) -#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) -#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) -#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) -#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) -#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) -#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) -#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) -#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) -#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) -#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) -#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) -#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) - -#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) - -#endif /* GL_EXT_fragment_lighting */ - -/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 - -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA - -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - -#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) - -#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) - -#endif /* GL_EXT_framebuffer_blit */ - -/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 - -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) - -#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) - -#endif /* GL_EXT_framebuffer_multisample */ - -/* --------------- GL_EXT_framebuffer_multisample_blit_scaled -------------- */ - -#ifndef GL_EXT_framebuffer_multisample_blit_scaled -#define GL_EXT_framebuffer_multisample_blit_scaled 1 - -#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA -#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB - -#define GLEW_EXT_framebuffer_multisample_blit_scaled GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample_blit_scaled) - -#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ - -/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 - -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 - -typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - -#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) -#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) -#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) -#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) -#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) -#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) -#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) -#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) -#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) -#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) -#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) -#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) -#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) -#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) -#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) -#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) -#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) - -#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) - -#endif /* GL_EXT_framebuffer_object */ - -/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 - -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA - -#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) - -#endif /* GL_EXT_framebuffer_sRGB */ - -/* ----------------------- GL_EXT_geometry_point_size ---------------------- */ - -#ifndef GL_EXT_geometry_point_size -#define GL_EXT_geometry_point_size 1 - -#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E -#define GL_UNDEFINED_VERTEX_EXT 0x8260 -#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F -#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 -#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 -#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 - -#define GLEW_EXT_geometry_point_size GLEW_GET_VAR(__GLEW_EXT_geometry_point_size) - -#endif /* GL_EXT_geometry_point_size */ - -/* ------------------------- GL_EXT_geometry_shader ------------------------ */ - -#ifndef GL_EXT_geometry_shader -#define GL_EXT_geometry_shader 1 - -#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E -#define GL_UNDEFINED_VERTEX_EXT 0x8260 -#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F -#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 -#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 -#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 - -#define GLEW_EXT_geometry_shader GLEW_GET_VAR(__GLEW_EXT_geometry_shader) - -#endif /* GL_EXT_geometry_shader */ - -/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 - -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); - -#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) -#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) -#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) - -#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) - -#endif /* GL_EXT_geometry_shader4 */ - -/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 - -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); - -#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) -#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) - -#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) - -#endif /* GL_EXT_gpu_program_parameters */ - -/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 - -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 - -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); - -#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) -#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) -#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) -#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) -#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) -#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) -#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) -#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) -#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) -#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) -#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) -#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) -#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) -#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) -#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) -#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) -#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) -#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) -#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) -#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) -#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) -#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) -#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) -#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) -#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) -#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) -#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) -#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) -#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) -#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) -#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) -#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) -#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) -#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) - -#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) - -#endif /* GL_EXT_gpu_shader4 */ - -/* --------------------------- GL_EXT_gpu_shader5 -------------------------- */ - -#ifndef GL_EXT_gpu_shader5 -#define GL_EXT_gpu_shader5 1 - -#define GLEW_EXT_gpu_shader5 GLEW_GET_VAR(__GLEW_EXT_gpu_shader5) - -#endif /* GL_EXT_gpu_shader5 */ - -/* ---------------------------- GL_EXT_histogram --------------------------- */ - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 - -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 - -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); - -#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) -#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) -#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) -#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) -#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) -#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) -#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) -#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) -#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) -#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) - -#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) - -#endif /* GL_EXT_histogram */ - -/* ----------------------- GL_EXT_index_array_formats ---------------------- */ - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 - -#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) - -#endif /* GL_EXT_index_array_formats */ - -/* --------------------------- GL_EXT_index_func --------------------------- */ - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 - -typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); - -#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) - -#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) - -#endif /* GL_EXT_index_func */ - -/* ------------------------- GL_EXT_index_material ------------------------- */ - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 - -typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); - -#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) - -#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) - -#endif /* GL_EXT_index_material */ - -/* -------------------------- GL_EXT_index_texture ------------------------- */ - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 - -#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) - -#endif /* GL_EXT_index_texture */ - -/* ------------------------ GL_EXT_instanced_arrays ------------------------ */ - -#ifndef GL_EXT_instanced_arrays -#define GL_EXT_instanced_arrays 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE - -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); - -#define glVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexAttribDivisorEXT) - -#define GLEW_EXT_instanced_arrays GLEW_GET_VAR(__GLEW_EXT_instanced_arrays) - -#endif /* GL_EXT_instanced_arrays */ - -/* -------------------------- GL_EXT_light_texture ------------------------- */ - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 - -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 - -typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); - -#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) -#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) -#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) - -#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) - -#endif /* GL_EXT_light_texture */ - -/* ------------------------ GL_EXT_map_buffer_range ------------------------ */ - -#ifndef GL_EXT_map_buffer_range -#define GL_EXT_map_buffer_range 1 - -#define GL_MAP_READ_BIT_EXT 0x0001 -#define GL_MAP_WRITE_BIT_EXT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 - -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); - -#define glFlushMappedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedBufferRangeEXT) -#define glMapBufferRangeEXT GLEW_GET_FUN(__glewMapBufferRangeEXT) - -#define GLEW_EXT_map_buffer_range GLEW_GET_VAR(__GLEW_EXT_map_buffer_range) - -#endif /* GL_EXT_map_buffer_range */ - -/* -------------------------- GL_EXT_memory_object ------------------------- */ - -#ifndef GL_EXT_memory_object -#define GL_EXT_memory_object 1 - -#define GL_UUID_SIZE_EXT 16 -#define GL_TEXTURE_TILING_EXT 0x9580 -#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 -#define GL_NUM_TILING_TYPES_EXT 0x9582 -#define GL_TILING_TYPES_EXT 0x9583 -#define GL_OPTIMAL_TILING_EXT 0x9584 -#define GL_LINEAR_TILING_EXT 0x9585 -#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 -#define GL_DEVICE_UUID_EXT 0x9597 -#define GL_DRIVER_UUID_EXT 0x9598 -#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B - -typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint* memoryObjects); -typedef void (GLAPIENTRY * PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint* memoryObjects); -typedef void (GLAPIENTRY * PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte* data); -typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte* data); -typedef GLboolean (GLAPIENTRY * PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); -typedef void (GLAPIENTRY * PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); - -#define glBufferStorageMemEXT GLEW_GET_FUN(__glewBufferStorageMemEXT) -#define glCreateMemoryObjectsEXT GLEW_GET_FUN(__glewCreateMemoryObjectsEXT) -#define glDeleteMemoryObjectsEXT GLEW_GET_FUN(__glewDeleteMemoryObjectsEXT) -#define glGetMemoryObjectParameterivEXT GLEW_GET_FUN(__glewGetMemoryObjectParameterivEXT) -#define glGetUnsignedBytei_vEXT GLEW_GET_FUN(__glewGetUnsignedBytei_vEXT) -#define glGetUnsignedBytevEXT GLEW_GET_FUN(__glewGetUnsignedBytevEXT) -#define glIsMemoryObjectEXT GLEW_GET_FUN(__glewIsMemoryObjectEXT) -#define glMemoryObjectParameterivEXT GLEW_GET_FUN(__glewMemoryObjectParameterivEXT) -#define glNamedBufferStorageMemEXT GLEW_GET_FUN(__glewNamedBufferStorageMemEXT) -#define glTexStorageMem1DEXT GLEW_GET_FUN(__glewTexStorageMem1DEXT) -#define glTexStorageMem2DEXT GLEW_GET_FUN(__glewTexStorageMem2DEXT) -#define glTexStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem2DMultisampleEXT) -#define glTexStorageMem3DEXT GLEW_GET_FUN(__glewTexStorageMem3DEXT) -#define glTexStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem3DMultisampleEXT) -#define glTextureStorageMem1DEXT GLEW_GET_FUN(__glewTextureStorageMem1DEXT) -#define glTextureStorageMem2DEXT GLEW_GET_FUN(__glewTextureStorageMem2DEXT) -#define glTextureStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem2DMultisampleEXT) -#define glTextureStorageMem3DEXT GLEW_GET_FUN(__glewTextureStorageMem3DEXT) -#define glTextureStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem3DMultisampleEXT) - -#define GLEW_EXT_memory_object GLEW_GET_VAR(__GLEW_EXT_memory_object) - -#endif /* GL_EXT_memory_object */ - -/* ------------------------ GL_EXT_memory_object_fd ------------------------ */ - -#ifndef GL_EXT_memory_object_fd -#define GL_EXT_memory_object_fd 1 - -#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 - -typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); - -#define glImportMemoryFdEXT GLEW_GET_FUN(__glewImportMemoryFdEXT) - -#define GLEW_EXT_memory_object_fd GLEW_GET_VAR(__GLEW_EXT_memory_object_fd) - -#endif /* GL_EXT_memory_object_fd */ - -/* ----------------------- GL_EXT_memory_object_win32 ---------------------- */ - -#ifndef GL_EXT_memory_object_win32 -#define GL_EXT_memory_object_win32 1 - -#define GL_LUID_SIZE_EXT 8 -#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 -#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 -#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 -#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A -#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B -#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C -#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 -#define GL_D3D12_FENCE_VALUE_EXT 0x9595 -#define GL_DEVICE_LUID_EXT 0x9599 -#define GL_DEVICE_NODE_MASK_EXT 0x959A - -typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); -typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); - -#define glImportMemoryWin32HandleEXT GLEW_GET_FUN(__glewImportMemoryWin32HandleEXT) -#define glImportMemoryWin32NameEXT GLEW_GET_FUN(__glewImportMemoryWin32NameEXT) - -#define GLEW_EXT_memory_object_win32 GLEW_GET_VAR(__GLEW_EXT_memory_object_win32) - -#endif /* GL_EXT_memory_object_win32 */ - -/* ------------------------- GL_EXT_misc_attribute ------------------------- */ - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 - -#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) - -#endif /* GL_EXT_misc_attribute */ - -/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount); - -#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) -#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) - -#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) - -#endif /* GL_EXT_multi_draw_arrays */ - -/* ----------------------- GL_EXT_multi_draw_indirect ---------------------- */ - -#ifndef GL_EXT_multi_draw_indirect -#define GL_EXT_multi_draw_indirect 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); - -#define glMultiDrawArraysIndirectEXT GLEW_GET_FUN(__glewMultiDrawArraysIndirectEXT) -#define glMultiDrawElementsIndirectEXT GLEW_GET_FUN(__glewMultiDrawElementsIndirectEXT) - -#define GLEW_EXT_multi_draw_indirect GLEW_GET_VAR(__GLEW_EXT_multi_draw_indirect) - -#endif /* GL_EXT_multi_draw_indirect */ - -/* ------------------------ GL_EXT_multiple_textures ----------------------- */ - -#ifndef GL_EXT_multiple_textures -#define GL_EXT_multiple_textures 1 - -#define GLEW_EXT_multiple_textures GLEW_GET_VAR(__GLEW_EXT_multiple_textures) - -#endif /* GL_EXT_multiple_textures */ - -/* --------------------------- GL_EXT_multisample -------------------------- */ - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 - -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 - -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); - -#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) -#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) - -#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) - -#endif /* GL_EXT_multisample */ - -/* -------------------- GL_EXT_multisample_compatibility ------------------- */ - -#ifndef GL_EXT_multisample_compatibility -#define GL_EXT_multisample_compatibility 1 - -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F - -#define GLEW_EXT_multisample_compatibility GLEW_GET_VAR(__GLEW_EXT_multisample_compatibility) - -#endif /* GL_EXT_multisample_compatibility */ - -/* ----------------- GL_EXT_multisampled_render_to_texture ----------------- */ - -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_EXT_multisampled_render_to_texture 1 - -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); - -#define glFramebufferTexture2DMultisampleEXT GLEW_GET_FUN(__glewFramebufferTexture2DMultisampleEXT) - -#define GLEW_EXT_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture) - -#endif /* GL_EXT_multisampled_render_to_texture */ - -/* ----------------- GL_EXT_multisampled_render_to_texture2 ---------------- */ - -#ifndef GL_EXT_multisampled_render_to_texture2 -#define GL_EXT_multisampled_render_to_texture2 1 - -#define GLEW_EXT_multisampled_render_to_texture2 GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture2) - -#endif /* GL_EXT_multisampled_render_to_texture2 */ - -/* --------------------- GL_EXT_multiview_draw_buffers --------------------- */ - -#ifndef GL_EXT_multiview_draw_buffers -#define GL_EXT_multiview_draw_buffers 1 - -#define GL_DRAW_BUFFER_EXT 0x0C01 -#define GL_READ_BUFFER_EXT 0x0C02 -#define GL_COLOR_ATTACHMENT_EXT 0x90F0 -#define GL_MULTIVIEW_EXT 0x90F1 -#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum* location, const GLint *indices); -typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint* data); -typedef void (GLAPIENTRY * PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); - -#define glDrawBuffersIndexedEXT GLEW_GET_FUN(__glewDrawBuffersIndexedEXT) -#define glGetIntegeri_vEXT GLEW_GET_FUN(__glewGetIntegeri_vEXT) -#define glReadBufferIndexedEXT GLEW_GET_FUN(__glewReadBufferIndexedEXT) - -#define GLEW_EXT_multiview_draw_buffers GLEW_GET_VAR(__GLEW_EXT_multiview_draw_buffers) - -#endif /* GL_EXT_multiview_draw_buffers */ - -/* ------------- GL_EXT_multiview_tessellation_geometry_shader ------------- */ - -#ifndef GL_EXT_multiview_tessellation_geometry_shader -#define GL_EXT_multiview_tessellation_geometry_shader 1 - -#define GLEW_EXT_multiview_tessellation_geometry_shader GLEW_GET_VAR(__GLEW_EXT_multiview_tessellation_geometry_shader) - -#endif /* GL_EXT_multiview_tessellation_geometry_shader */ - -/* ------------------ GL_EXT_multiview_texture_multisample ----------------- */ - -#ifndef GL_EXT_multiview_texture_multisample -#define GL_EXT_multiview_texture_multisample 1 - -#define GLEW_EXT_multiview_texture_multisample GLEW_GET_VAR(__GLEW_EXT_multiview_texture_multisample) - -#endif /* GL_EXT_multiview_texture_multisample */ - -/* ---------------------- GL_EXT_multiview_timer_query --------------------- */ - -#ifndef GL_EXT_multiview_timer_query -#define GL_EXT_multiview_timer_query 1 - -#define GLEW_EXT_multiview_timer_query GLEW_GET_VAR(__GLEW_EXT_multiview_timer_query) - -#endif /* GL_EXT_multiview_timer_query */ - -/* --------------------- GL_EXT_occlusion_query_boolean -------------------- */ - -#ifndef GL_EXT_occlusion_query_boolean -#define GL_EXT_occlusion_query_boolean 1 - -#define GL_CURRENT_QUERY_EXT 0x8865 -#define GL_QUERY_RESULT_EXT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 -#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A - -#define GLEW_EXT_occlusion_query_boolean GLEW_GET_VAR(__GLEW_EXT_occlusion_query_boolean) - -#endif /* GL_EXT_occlusion_query_boolean */ - -/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 - -#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) - -#endif /* GL_EXT_packed_depth_stencil */ - -/* -------------------------- GL_EXT_packed_float -------------------------- */ - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 - -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C - -#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) - -#endif /* GL_EXT_packed_float */ - -/* -------------------------- GL_EXT_packed_pixels ------------------------- */ - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 - -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 - -#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) - -#endif /* GL_EXT_packed_pixels */ - -/* ------------------------ GL_EXT_paletted_texture ------------------------ */ - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 - -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 -#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B - -typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *data); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); - -#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) -#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) -#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) -#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) - -#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) - -#endif /* GL_EXT_paletted_texture */ - -/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 - -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF - -#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) - -#endif /* GL_EXT_pixel_buffer_object */ - -/* ------------------------- GL_EXT_pixel_transform ------------------------ */ - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 - -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 - -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) -#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) -#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) -#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) -#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) -#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) - -#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) - -#endif /* GL_EXT_pixel_transform */ - -/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 - -#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) - -#endif /* GL_EXT_pixel_transform_color_table */ - -/* ------------------------ GL_EXT_point_parameters ------------------------ */ - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 - -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat* params); - -#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) -#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) - -#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) - -#endif /* GL_EXT_point_parameters */ - -/* ------------------------- GL_EXT_polygon_offset ------------------------- */ - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 - -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 - -typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); - -#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) - -#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) - -#endif /* GL_EXT_polygon_offset */ - -/* ---------------------- GL_EXT_polygon_offset_clamp ---------------------- */ - -#ifndef GL_EXT_polygon_offset_clamp -#define GL_EXT_polygon_offset_clamp 1 - -#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B - -typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); - -#define glPolygonOffsetClampEXT GLEW_GET_FUN(__glewPolygonOffsetClampEXT) - -#define GLEW_EXT_polygon_offset_clamp GLEW_GET_VAR(__GLEW_EXT_polygon_offset_clamp) - -#endif /* GL_EXT_polygon_offset_clamp */ - -/* ----------------------- GL_EXT_post_depth_coverage ---------------------- */ - -#ifndef GL_EXT_post_depth_coverage -#define GL_EXT_post_depth_coverage 1 - -#define GLEW_EXT_post_depth_coverage GLEW_GET_VAR(__GLEW_EXT_post_depth_coverage) - -#endif /* GL_EXT_post_depth_coverage */ - -/* --------------------- GL_EXT_primitive_bounding_box --------------------- */ - -#ifndef GL_EXT_primitive_bounding_box -#define GL_EXT_primitive_bounding_box 1 - -#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE - -typedef void (GLAPIENTRY * PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); - -#define glPrimitiveBoundingBoxEXT GLEW_GET_FUN(__glewPrimitiveBoundingBoxEXT) - -#define GLEW_EXT_primitive_bounding_box GLEW_GET_VAR(__GLEW_EXT_primitive_bounding_box) - -#endif /* GL_EXT_primitive_bounding_box */ - -/* ----------------------- GL_EXT_protected_textures ----------------------- */ - -#ifndef GL_EXT_protected_textures -#define GL_EXT_protected_textures 1 - -#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010 -#define GL_TEXTURE_PROTECTED_EXT 0x8BFA - -#define GLEW_EXT_protected_textures GLEW_GET_VAR(__GLEW_EXT_protected_textures) - -#endif /* GL_EXT_protected_textures */ - -/* ------------------------ GL_EXT_provoking_vertex ------------------------ */ - -#ifndef GL_EXT_provoking_vertex -#define GL_EXT_provoking_vertex 1 - -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_PROVOKING_VERTEX_EXT 0x8E4F - -typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); - -#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT) - -#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex) - -#endif /* GL_EXT_provoking_vertex */ - -/* --------------------------- GL_EXT_pvrtc_sRGB --------------------------- */ - -#ifndef GL_EXT_pvrtc_sRGB -#define GL_EXT_pvrtc_sRGB 1 - -#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 -#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 - -#define GLEW_EXT_pvrtc_sRGB GLEW_GET_VAR(__GLEW_EXT_pvrtc_sRGB) - -#endif /* GL_EXT_pvrtc_sRGB */ - -/* ----------------------- GL_EXT_raster_multisample ----------------------- */ - -#ifndef GL_EXT_raster_multisample -#define GL_EXT_raster_multisample 1 - -#define GL_COLOR_SAMPLES_NV 0x8E20 -#define GL_RASTER_MULTISAMPLE_EXT 0x9327 -#define GL_RASTER_SAMPLES_EXT 0x9328 -#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 -#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A -#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B -#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C -#define GL_DEPTH_SAMPLES_NV 0x932D -#define GL_STENCIL_SAMPLES_NV 0x932E -#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F -#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 -#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 -#define GL_COVERAGE_MODULATION_NV 0x9332 -#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 - -typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); -typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat* v); -typedef void (GLAPIENTRY * PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); - -#define glCoverageModulationNV GLEW_GET_FUN(__glewCoverageModulationNV) -#define glCoverageModulationTableNV GLEW_GET_FUN(__glewCoverageModulationTableNV) -#define glGetCoverageModulationTableNV GLEW_GET_FUN(__glewGetCoverageModulationTableNV) -#define glRasterSamplesEXT GLEW_GET_FUN(__glewRasterSamplesEXT) - -#define GLEW_EXT_raster_multisample GLEW_GET_VAR(__GLEW_EXT_raster_multisample) - -#endif /* GL_EXT_raster_multisample */ - -/* ------------------------ GL_EXT_read_format_bgra ------------------------ */ - -#ifndef GL_EXT_read_format_bgra -#define GL_EXT_read_format_bgra 1 - -#define GL_BGRA_EXT 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 - -#define GLEW_EXT_read_format_bgra GLEW_GET_VAR(__GLEW_EXT_read_format_bgra) - -#endif /* GL_EXT_read_format_bgra */ - -/* -------------------------- GL_EXT_render_snorm -------------------------- */ - -#ifndef GL_EXT_render_snorm -#define GL_EXT_render_snorm 1 - -#define GL_BYTE 0x1400 -#define GL_SHORT 0x1402 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM_EXT 0x8F98 -#define GL_RG16_SNORM_EXT 0x8F99 -#define GL_RGBA16_SNORM_EXT 0x8F9B - -#define GLEW_EXT_render_snorm GLEW_GET_VAR(__GLEW_EXT_render_snorm) - -#endif /* GL_EXT_render_snorm */ - -/* ------------------------- GL_EXT_rescale_normal ------------------------- */ - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 - -#define GL_RESCALE_NORMAL_EXT 0x803A - -#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) - -#endif /* GL_EXT_rescale_normal */ - -/* --------------------------- GL_EXT_robustness --------------------------- */ - -#ifndef GL_EXT_robustness -#define GL_EXT_robustness 1 - -#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 -#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 -#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 -#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 - -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); -typedef void (GLAPIENTRY * PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); - -#define glGetnUniformfvEXT GLEW_GET_FUN(__glewGetnUniformfvEXT) -#define glGetnUniformivEXT GLEW_GET_FUN(__glewGetnUniformivEXT) -#define glReadnPixelsEXT GLEW_GET_FUN(__glewReadnPixelsEXT) - -#define GLEW_EXT_robustness GLEW_GET_VAR(__GLEW_EXT_robustness) - -#endif /* GL_EXT_robustness */ - -/* ------------------------------ GL_EXT_sRGB ------------------------------ */ - -#ifndef GL_EXT_sRGB -#define GL_EXT_sRGB 1 - -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 - -#define GLEW_EXT_sRGB GLEW_GET_VAR(__GLEW_EXT_sRGB) - -#endif /* GL_EXT_sRGB */ - -/* ----------------------- GL_EXT_sRGB_write_control ----------------------- */ - -#ifndef GL_EXT_sRGB_write_control -#define GL_EXT_sRGB_write_control 1 - -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 - -#define GLEW_EXT_sRGB_write_control GLEW_GET_VAR(__GLEW_EXT_sRGB_write_control) - -#endif /* GL_EXT_sRGB_write_control */ - -/* -------------------------- GL_EXT_scene_marker -------------------------- */ - -#ifndef GL_EXT_scene_marker -#define GL_EXT_scene_marker 1 - -typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); - -#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) -#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) - -#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) - -#endif /* GL_EXT_scene_marker */ - -/* ------------------------- GL_EXT_secondary_color ------------------------ */ - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 - -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E - -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); - -#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) -#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) -#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) -#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) -#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) -#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) -#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) -#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) -#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) -#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) -#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) -#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) -#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) -#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) -#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) -#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) -#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) - -#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) - -#endif /* GL_EXT_secondary_color */ - -/* ---------------------------- GL_EXT_semaphore --------------------------- */ - -#ifndef GL_EXT_semaphore -#define GL_EXT_semaphore 1 - -#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 -#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 -#define GL_LAYOUT_GENERAL_EXT 0x958D -#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E -#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F -#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 -#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 -#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 -#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 - -typedef void (GLAPIENTRY * PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint* semaphores); -typedef void (GLAPIENTRY * PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint* semaphores); -typedef void (GLAPIENTRY * PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64* params); -typedef GLboolean (GLAPIENTRY * PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); -typedef void (GLAPIENTRY * PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64* params); -typedef void (GLAPIENTRY * PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); -typedef void (GLAPIENTRY * PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); - -#define glDeleteSemaphoresEXT GLEW_GET_FUN(__glewDeleteSemaphoresEXT) -#define glGenSemaphoresEXT GLEW_GET_FUN(__glewGenSemaphoresEXT) -#define glGetSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewGetSemaphoreParameterui64vEXT) -#define glIsSemaphoreEXT GLEW_GET_FUN(__glewIsSemaphoreEXT) -#define glSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewSemaphoreParameterui64vEXT) -#define glSignalSemaphoreEXT GLEW_GET_FUN(__glewSignalSemaphoreEXT) -#define glWaitSemaphoreEXT GLEW_GET_FUN(__glewWaitSemaphoreEXT) - -#define GLEW_EXT_semaphore GLEW_GET_VAR(__GLEW_EXT_semaphore) - -#endif /* GL_EXT_semaphore */ - -/* -------------------------- GL_EXT_semaphore_fd -------------------------- */ - -#ifndef GL_EXT_semaphore_fd -#define GL_EXT_semaphore_fd 1 - -typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); - -#define glImportSemaphoreFdEXT GLEW_GET_FUN(__glewImportSemaphoreFdEXT) - -#define GLEW_EXT_semaphore_fd GLEW_GET_VAR(__GLEW_EXT_semaphore_fd) - -#endif /* GL_EXT_semaphore_fd */ - -/* ------------------------- GL_EXT_semaphore_win32 ------------------------ */ - -#ifndef GL_EXT_semaphore_win32 -#define GL_EXT_semaphore_win32 1 - -typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); -typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); - -#define glImportSemaphoreWin32HandleEXT GLEW_GET_FUN(__glewImportSemaphoreWin32HandleEXT) -#define glImportSemaphoreWin32NameEXT GLEW_GET_FUN(__glewImportSemaphoreWin32NameEXT) - -#define GLEW_EXT_semaphore_win32 GLEW_GET_VAR(__GLEW_EXT_semaphore_win32) - -#endif /* GL_EXT_semaphore_win32 */ - -/* --------------------- GL_EXT_separate_shader_objects -------------------- */ - -#ifndef GL_EXT_separate_shader_objects -#define GL_EXT_separate_shader_objects 1 - -#define GL_ACTIVE_PROGRAM_EXT 0x8B8D - -typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); -typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar* string); -typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); - -#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT) -#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT) -#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT) - -#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects) - -#endif /* GL_EXT_separate_shader_objects */ - -/* --------------------- GL_EXT_separate_specular_color -------------------- */ - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 - -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA - -#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) - -#endif /* GL_EXT_separate_specular_color */ - -/* -------------------- GL_EXT_shader_framebuffer_fetch -------------------- */ - -#ifndef GL_EXT_shader_framebuffer_fetch -#define GL_EXT_shader_framebuffer_fetch 1 - -#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void); - -#define glFramebufferFetchBarrierEXT GLEW_GET_FUN(__glewFramebufferFetchBarrierEXT) - -#define GLEW_EXT_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_EXT_shader_framebuffer_fetch) - -#endif /* GL_EXT_shader_framebuffer_fetch */ - -/* -------------- GL_EXT_shader_framebuffer_fetch_non_coherent ------------- */ - -#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent -#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 - -#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 - -#define GLEW_EXT_shader_framebuffer_fetch_non_coherent GLEW_GET_VAR(__GLEW_EXT_shader_framebuffer_fetch_non_coherent) - -#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */ - -/* ------------------------ GL_EXT_shader_group_vote ----------------------- */ - -#ifndef GL_EXT_shader_group_vote -#define GL_EXT_shader_group_vote 1 - -#define GLEW_EXT_shader_group_vote GLEW_GET_VAR(__GLEW_EXT_shader_group_vote) - -#endif /* GL_EXT_shader_group_vote */ - -/* ------------------- GL_EXT_shader_image_load_formatted ------------------ */ - -#ifndef GL_EXT_shader_image_load_formatted -#define GL_EXT_shader_image_load_formatted 1 - -#define GLEW_EXT_shader_image_load_formatted GLEW_GET_VAR(__GLEW_EXT_shader_image_load_formatted) - -#endif /* GL_EXT_shader_image_load_formatted */ - -/* --------------------- GL_EXT_shader_image_load_store -------------------- */ - -#ifndef GL_EXT_shader_image_load_store -#define GL_EXT_shader_image_load_store 1 - -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 -#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 -#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 -#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A -#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B -#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C -#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D -#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E -#define GL_IMAGE_1D_EXT 0x904C -#define GL_IMAGE_2D_EXT 0x904D -#define GL_IMAGE_3D_EXT 0x904E -#define GL_IMAGE_2D_RECT_EXT 0x904F -#define GL_IMAGE_CUBE_EXT 0x9050 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_IMAGE_1D_ARRAY_EXT 0x9052 -#define GL_IMAGE_2D_ARRAY_EXT 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 -#define GL_INT_IMAGE_1D_EXT 0x9057 -#define GL_INT_IMAGE_2D_EXT 0x9058 -#define GL_INT_IMAGE_3D_EXT 0x9059 -#define GL_INT_IMAGE_2D_RECT_EXT 0x905A -#define GL_INT_IMAGE_CUBE_EXT 0x905B -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D -#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C -#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D -#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E -#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF - -typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); - -#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT) -#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT) - -#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store) - -#endif /* GL_EXT_shader_image_load_store */ - -/* ------------------- GL_EXT_shader_implicit_conversions ------------------ */ - -#ifndef GL_EXT_shader_implicit_conversions -#define GL_EXT_shader_implicit_conversions 1 - -#define GLEW_EXT_shader_implicit_conversions GLEW_GET_VAR(__GLEW_EXT_shader_implicit_conversions) - -#endif /* GL_EXT_shader_implicit_conversions */ - -/* ----------------------- GL_EXT_shader_integer_mix ----------------------- */ - -#ifndef GL_EXT_shader_integer_mix -#define GL_EXT_shader_integer_mix 1 - -#define GLEW_EXT_shader_integer_mix GLEW_GET_VAR(__GLEW_EXT_shader_integer_mix) - -#endif /* GL_EXT_shader_integer_mix */ - -/* ------------------------ GL_EXT_shader_io_blocks ------------------------ */ - -#ifndef GL_EXT_shader_io_blocks -#define GL_EXT_shader_io_blocks 1 - -#define GLEW_EXT_shader_io_blocks GLEW_GET_VAR(__GLEW_EXT_shader_io_blocks) - -#endif /* GL_EXT_shader_io_blocks */ - -/* ------------- GL_EXT_shader_non_constant_global_initializers ------------ */ - -#ifndef GL_EXT_shader_non_constant_global_initializers -#define GL_EXT_shader_non_constant_global_initializers 1 - -#define GLEW_EXT_shader_non_constant_global_initializers GLEW_GET_VAR(__GLEW_EXT_shader_non_constant_global_initializers) - -#endif /* GL_EXT_shader_non_constant_global_initializers */ - -/* ------------------- GL_EXT_shader_pixel_local_storage ------------------- */ - -#ifndef GL_EXT_shader_pixel_local_storage -#define GL_EXT_shader_pixel_local_storage 1 - -#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 -#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 -#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 - -#define GLEW_EXT_shader_pixel_local_storage GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage) - -#endif /* GL_EXT_shader_pixel_local_storage */ - -/* ------------------- GL_EXT_shader_pixel_local_storage2 ------------------ */ - -#ifndef GL_EXT_shader_pixel_local_storage2 -#define GL_EXT_shader_pixel_local_storage2 1 - -#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 -#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 -#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 - -typedef void (GLAPIENTRY * PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint* values); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size); -typedef GLsizei (GLAPIENTRY * PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target); - -#define glClearPixelLocalStorageuiEXT GLEW_GET_FUN(__glewClearPixelLocalStorageuiEXT) -#define glFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewFramebufferPixelLocalStorageSizeEXT) -#define glGetFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewGetFramebufferPixelLocalStorageSizeEXT) - -#define GLEW_EXT_shader_pixel_local_storage2 GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage2) - -#endif /* GL_EXT_shader_pixel_local_storage2 */ - -/* ----------------------- GL_EXT_shader_texture_lod ----------------------- */ - -#ifndef GL_EXT_shader_texture_lod -#define GL_EXT_shader_texture_lod 1 - -#define GLEW_EXT_shader_texture_lod GLEW_GET_VAR(__GLEW_EXT_shader_texture_lod) - -#endif /* GL_EXT_shader_texture_lod */ - -/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 - -#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) - -#endif /* GL_EXT_shadow_funcs */ - -/* ------------------------- GL_EXT_shadow_samplers ------------------------ */ - -#ifndef GL_EXT_shadow_samplers -#define GL_EXT_shadow_samplers 1 - -#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C -#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D -#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E -#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 - -#define GLEW_EXT_shadow_samplers GLEW_GET_VAR(__GLEW_EXT_shadow_samplers) - -#endif /* GL_EXT_shadow_samplers */ - -/* --------------------- GL_EXT_shared_texture_palette --------------------- */ - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 - -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB - -#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) - -#endif /* GL_EXT_shared_texture_palette */ - -/* ------------------------- GL_EXT_sparse_texture ------------------------- */ - -#ifndef GL_EXT_sparse_texture -#define GL_EXT_sparse_texture 1 - -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 -#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A -#define GL_TEXTURE_SPARSE_EXT 0x91A6 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 -#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 -#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA - -typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); -typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); - -#define glTexPageCommitmentEXT GLEW_GET_FUN(__glewTexPageCommitmentEXT) -#define glTexturePageCommitmentEXT GLEW_GET_FUN(__glewTexturePageCommitmentEXT) - -#define GLEW_EXT_sparse_texture GLEW_GET_VAR(__GLEW_EXT_sparse_texture) - -#endif /* GL_EXT_sparse_texture */ - -/* ------------------------- GL_EXT_sparse_texture2 ------------------------ */ - -#ifndef GL_EXT_sparse_texture2 -#define GL_EXT_sparse_texture2 1 - -#define GLEW_EXT_sparse_texture2 GLEW_GET_VAR(__GLEW_EXT_sparse_texture2) - -#endif /* GL_EXT_sparse_texture2 */ - -/* ----------------------- GL_EXT_static_vertex_array ---------------------- */ - -#ifndef GL_EXT_static_vertex_array -#define GL_EXT_static_vertex_array 1 - -#define GLEW_EXT_static_vertex_array GLEW_GET_VAR(__GLEW_EXT_static_vertex_array) - -#endif /* GL_EXT_static_vertex_array */ - -/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 - -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 - -#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) - -#endif /* GL_EXT_stencil_clear_tag */ - -/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 - -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 - -typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); - -#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) - -#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) - -#endif /* GL_EXT_stencil_two_side */ - -/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 - -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 - -#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) - -#endif /* GL_EXT_stencil_wrap */ - -/* --------------------------- GL_EXT_subtexture --------------------------- */ - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 - -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - -#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) -#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) -#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) - -#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) - -#endif /* GL_EXT_subtexture */ - -/* --------------------- GL_EXT_tessellation_point_size -------------------- */ - -#ifndef GL_EXT_tessellation_point_size -#define GL_EXT_tessellation_point_size 1 - -#define GL_QUADS_EXT 0x0007 -#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 -#define GL_PATCHES_EXT 0xE -#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F -#define GL_PATCH_VERTICES_EXT 0x8E72 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 -#define GL_TESS_GEN_MODE_EXT 0x8E76 -#define GL_TESS_GEN_SPACING_EXT 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 -#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 -#define GL_ISOLINES_EXT 0x8E7A -#define GL_FRACTIONAL_ODD_EXT 0x8E7B -#define GL_FRACTIONAL_EVEN_EXT 0x8E7C -#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 -#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 -#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 -#define GL_IS_PER_PATCH_EXT 0x92E7 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 - -typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value); - -#define glPatchParameteriEXT GLEW_GET_FUN(__glewPatchParameteriEXT) - -#define GLEW_EXT_tessellation_point_size GLEW_GET_VAR(__GLEW_EXT_tessellation_point_size) - -#endif /* GL_EXT_tessellation_point_size */ - -/* ----------------------- GL_EXT_tessellation_shader ---------------------- */ - -#ifndef GL_EXT_tessellation_shader -#define GL_EXT_tessellation_shader 1 - -#define GL_QUADS_EXT 0x0007 -#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 -#define GL_PATCHES_EXT 0xE -#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F -#define GL_PATCH_VERTICES_EXT 0x8E72 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 -#define GL_TESS_GEN_MODE_EXT 0x8E76 -#define GL_TESS_GEN_SPACING_EXT 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 -#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 -#define GL_ISOLINES_EXT 0x8E7A -#define GL_FRACTIONAL_ODD_EXT 0x8E7B -#define GL_FRACTIONAL_EVEN_EXT 0x8E7C -#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 -#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 -#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 -#define GL_IS_PER_PATCH_EXT 0x92E7 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 - -#define GLEW_EXT_tessellation_shader GLEW_GET_VAR(__GLEW_EXT_tessellation_shader) - -#endif /* GL_EXT_tessellation_shader */ - -/* ----------------------------- GL_EXT_texture ---------------------------- */ - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 - -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 - -#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) - -#endif /* GL_EXT_texture */ - -/* ---------------------------- GL_EXT_texture3D --------------------------- */ - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 - -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 - -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); - -#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) - -#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) - -#endif /* GL_EXT_texture3D */ - -/* -------------------------- GL_EXT_texture_array ------------------------- */ - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 - -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); - -#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) - -#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) - -#endif /* GL_EXT_texture_array */ - -/* ---------------------- GL_EXT_texture_border_clamp ---------------------- */ - -#ifndef GL_EXT_texture_border_clamp -#define GL_EXT_texture_border_clamp 1 - -#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 -#define GL_CLAMP_TO_BORDER_EXT 0x812D - -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint* params); - -#define glGetSamplerParameterIivEXT GLEW_GET_FUN(__glewGetSamplerParameterIivEXT) -#define glGetSamplerParameterIuivEXT GLEW_GET_FUN(__glewGetSamplerParameterIuivEXT) -#define glSamplerParameterIivEXT GLEW_GET_FUN(__glewSamplerParameterIivEXT) -#define glSamplerParameterIuivEXT GLEW_GET_FUN(__glewSamplerParameterIuivEXT) - -#define GLEW_EXT_texture_border_clamp GLEW_GET_VAR(__GLEW_EXT_texture_border_clamp) - -#endif /* GL_EXT_texture_border_clamp */ - -/* ------------------------- GL_EXT_texture_buffer ------------------------- */ - -#ifndef GL_EXT_texture_buffer -#define GL_EXT_texture_buffer 1 - -#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D -#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F - -#define GLEW_EXT_texture_buffer GLEW_GET_VAR(__GLEW_EXT_texture_buffer) - -#endif /* GL_EXT_texture_buffer */ - -/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 - -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E - -typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); - -#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) - -#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) - -#endif /* GL_EXT_texture_buffer_object */ - -/* -------------- GL_EXT_texture_compression_astc_decode_mode -------------- */ - -#ifndef GL_EXT_texture_compression_astc_decode_mode -#define GL_EXT_texture_compression_astc_decode_mode 1 - -#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 - -#define GLEW_EXT_texture_compression_astc_decode_mode GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode) - -#endif /* GL_EXT_texture_compression_astc_decode_mode */ - -/* ----------- GL_EXT_texture_compression_astc_decode_mode_rgb9e5 ---------- */ - -#ifndef GL_EXT_texture_compression_astc_decode_mode_rgb9e5 -#define GL_EXT_texture_compression_astc_decode_mode_rgb9e5 1 - -#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 - -#define GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5 GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5) - -#endif /* GL_EXT_texture_compression_astc_decode_mode_rgb9e5 */ - -/* -------------------- GL_EXT_texture_compression_bptc -------------------- */ - -#ifndef GL_EXT_texture_compression_bptc -#define GL_EXT_texture_compression_bptc 1 - -#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F - -#define GLEW_EXT_texture_compression_bptc GLEW_GET_VAR(__GLEW_EXT_texture_compression_bptc) - -#endif /* GL_EXT_texture_compression_bptc */ - -/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ - -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_EXT_texture_compression_dxt1 1 - -#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) - -#endif /* GL_EXT_texture_compression_dxt1 */ - -/* -------------------- GL_EXT_texture_compression_latc -------------------- */ - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 - -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 - -#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) - -#endif /* GL_EXT_texture_compression_latc */ - -/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 - -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE - -#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) - -#endif /* GL_EXT_texture_compression_rgtc */ - -/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_EXT_texture_compression_s3tc 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - -#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) - -#endif /* GL_EXT_texture_compression_s3tc */ - -/* ------------------ GL_EXT_texture_compression_s3tc_srgb ----------------- */ - -#ifndef GL_EXT_texture_compression_s3tc_srgb -#define GL_EXT_texture_compression_s3tc_srgb 1 - -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F - -#define GLEW_EXT_texture_compression_s3tc_srgb GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc_srgb) - -#endif /* GL_EXT_texture_compression_s3tc_srgb */ - -/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ - -#ifndef GL_EXT_texture_cube_map -#define GL_EXT_texture_cube_map 1 - -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C - -#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) - -#endif /* GL_EXT_texture_cube_map */ - -/* --------------------- GL_EXT_texture_cube_map_array --------------------- */ - -#ifndef GL_EXT_texture_cube_map_array -#define GL_EXT_texture_cube_map_array 1 - -#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A -#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A - -#define GLEW_EXT_texture_cube_map_array GLEW_GET_VAR(__GLEW_EXT_texture_cube_map_array) - -#endif /* GL_EXT_texture_cube_map_array */ - -/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ - -#ifndef GL_EXT_texture_edge_clamp -#define GL_EXT_texture_edge_clamp 1 - -#define GL_CLAMP_TO_EDGE_EXT 0x812F - -#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) - -#endif /* GL_EXT_texture_edge_clamp */ - -/* --------------------------- GL_EXT_texture_env -------------------------- */ - -#ifndef GL_EXT_texture_env -#define GL_EXT_texture_env 1 - -#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) - -#endif /* GL_EXT_texture_env */ - -/* ------------------------- GL_EXT_texture_env_add ------------------------ */ - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 - -#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) - -#endif /* GL_EXT_texture_env_add */ - -/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 - -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A - -#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) - -#endif /* GL_EXT_texture_env_combine */ - -/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 - -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 - -#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) - -#endif /* GL_EXT_texture_env_dot3 */ - -/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 - -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF - -#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) - -#endif /* GL_EXT_texture_filter_anisotropic */ - -/* ---------------------- GL_EXT_texture_filter_minmax --------------------- */ - -#ifndef GL_EXT_texture_filter_minmax -#define GL_EXT_texture_filter_minmax 1 - -#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 -#define GL_WEIGHTED_AVERAGE_EXT 0x9367 - -#define GLEW_EXT_texture_filter_minmax GLEW_GET_VAR(__GLEW_EXT_texture_filter_minmax) - -#endif /* GL_EXT_texture_filter_minmax */ - -/* --------------------- GL_EXT_texture_format_BGRA8888 -------------------- */ - -#ifndef GL_EXT_texture_format_BGRA8888 -#define GL_EXT_texture_format_BGRA8888 1 - -#define GL_BGRA_EXT 0x80E1 - -#define GLEW_EXT_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_EXT_texture_format_BGRA8888) - -#endif /* GL_EXT_texture_format_BGRA8888 */ - -/* ------------------ GL_EXT_texture_format_sRGB_override ------------------ */ - -#ifndef GL_EXT_texture_format_sRGB_override -#define GL_EXT_texture_format_sRGB_override 1 - -#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF - -#define GLEW_EXT_texture_format_sRGB_override GLEW_GET_VAR(__GLEW_EXT_texture_format_sRGB_override) - -#endif /* GL_EXT_texture_format_sRGB_override */ - -/* ------------------------- GL_EXT_texture_integer ------------------------ */ - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 - -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E - -typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); - -#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) -#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) -#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) -#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) -#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) -#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) - -#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) - -#endif /* GL_EXT_texture_integer */ - -/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 - -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 - -#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) - -#endif /* GL_EXT_texture_lod_bias */ - -/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 - -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 - -#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) - -#endif /* GL_EXT_texture_mirror_clamp */ - -/* ------------------ GL_EXT_texture_mirror_clamp_to_edge ------------------ */ - -#ifndef GL_EXT_texture_mirror_clamp_to_edge -#define GL_EXT_texture_mirror_clamp_to_edge 1 - -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 - -#define GLEW_EXT_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp_to_edge) - -#endif /* GL_EXT_texture_mirror_clamp_to_edge */ - -/* ------------------------- GL_EXT_texture_norm16 ------------------------- */ - -#ifndef GL_EXT_texture_norm16 -#define GL_EXT_texture_norm16 1 - -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA16_EXT 0x805B -#define GL_R16_EXT 0x822A -#define GL_RG16_EXT 0x822C -#define GL_R16_SNORM_EXT 0x8F98 -#define GL_RG16_SNORM_EXT 0x8F99 -#define GL_RGB16_SNORM_EXT 0x8F9A -#define GL_RGBA16_SNORM_EXT 0x8F9B - -#define GLEW_EXT_texture_norm16 GLEW_GET_VAR(__GLEW_EXT_texture_norm16) - -#endif /* GL_EXT_texture_norm16 */ - -/* ------------------------- GL_EXT_texture_object ------------------------- */ - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 - -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A - -typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); -typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); -typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); -typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); - -#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) -#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) -#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) -#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) -#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) -#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) - -#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) - -#endif /* GL_EXT_texture_object */ - -/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 - -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF - -typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); - -#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) - -#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) - -#endif /* GL_EXT_texture_perturb_normal */ - -/* ------------------------ GL_EXT_texture_query_lod ----------------------- */ - -#ifndef GL_EXT_texture_query_lod -#define GL_EXT_texture_query_lod 1 - -#define GLEW_EXT_texture_query_lod GLEW_GET_VAR(__GLEW_EXT_texture_query_lod) - -#endif /* GL_EXT_texture_query_lod */ - -/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ - -#ifndef GL_EXT_texture_rectangle -#define GL_EXT_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 - -#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) - -#endif /* GL_EXT_texture_rectangle */ - -/* --------------------------- GL_EXT_texture_rg --------------------------- */ - -#ifndef GL_EXT_texture_rg -#define GL_EXT_texture_rg 1 - -#define GL_RED_EXT 0x1903 -#define GL_RG_EXT 0x8227 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B - -#define GLEW_EXT_texture_rg GLEW_GET_VAR(__GLEW_EXT_texture_rg) - -#endif /* GL_EXT_texture_rg */ - -/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 - -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F - -#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) - -#endif /* GL_EXT_texture_sRGB */ - -/* ------------------------- GL_EXT_texture_sRGB_R8 ------------------------ */ - -#ifndef GL_EXT_texture_sRGB_R8 -#define GL_EXT_texture_sRGB_R8 1 - -#define GL_SR8_EXT 0x8FBD - -#define GLEW_EXT_texture_sRGB_R8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_R8) - -#endif /* GL_EXT_texture_sRGB_R8 */ - -/* ------------------------ GL_EXT_texture_sRGB_RG8 ------------------------ */ - -#ifndef GL_EXT_texture_sRGB_RG8 -#define GL_EXT_texture_sRGB_RG8 1 - -#define GL_SRG8_EXT 0x8FBE - -#define GLEW_EXT_texture_sRGB_RG8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_RG8) - -#endif /* GL_EXT_texture_sRGB_RG8 */ - -/* ----------------------- GL_EXT_texture_sRGB_decode ---------------------- */ - -#ifndef GL_EXT_texture_sRGB_decode -#define GL_EXT_texture_sRGB_decode 1 - -#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define GL_DECODE_EXT 0x8A49 -#define GL_SKIP_DECODE_EXT 0x8A4A - -#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode) - -#endif /* GL_EXT_texture_sRGB_decode */ - -/* ----------------------- GL_EXT_texture_shadow_lod ----------------------- */ - -#ifndef GL_EXT_texture_shadow_lod -#define GL_EXT_texture_shadow_lod 1 - -#define GLEW_EXT_texture_shadow_lod GLEW_GET_VAR(__GLEW_EXT_texture_shadow_lod) - -#endif /* GL_EXT_texture_shadow_lod */ - -/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 - -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F - -#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) - -#endif /* GL_EXT_texture_shared_exponent */ - -/* -------------------------- GL_EXT_texture_snorm ------------------------- */ - -#ifndef GL_EXT_texture_snorm -#define GL_EXT_texture_snorm 1 - -#define GL_RED_SNORM 0x8F90 -#define GL_RG_SNORM 0x8F91 -#define GL_RGB_SNORM 0x8F92 -#define GL_RGBA_SNORM 0x8F93 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_ALPHA_SNORM 0x9010 -#define GL_LUMINANCE_SNORM 0x9011 -#define GL_LUMINANCE_ALPHA_SNORM 0x9012 -#define GL_INTENSITY_SNORM 0x9013 -#define GL_ALPHA8_SNORM 0x9014 -#define GL_LUMINANCE8_SNORM 0x9015 -#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 -#define GL_INTENSITY8_SNORM 0x9017 -#define GL_ALPHA16_SNORM 0x9018 -#define GL_LUMINANCE16_SNORM 0x9019 -#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A -#define GL_INTENSITY16_SNORM 0x901B - -#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm) - -#endif /* GL_EXT_texture_snorm */ - -/* ------------------------- GL_EXT_texture_storage ------------------------ */ - -#ifndef GL_EXT_texture_storage -#define GL_EXT_texture_storage 1 - -#define GL_ALPHA8_EXT 0x803C -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B -#define GL_R16F_EXT 0x822D -#define GL_R32F_EXT 0x822E -#define GL_RG16F_EXT 0x822F -#define GL_RG32F_EXT 0x8230 -#define GL_RGBA32F_EXT 0x8814 -#define GL_RGB32F_EXT 0x8815 -#define GL_ALPHA32F_EXT 0x8816 -#define GL_LUMINANCE32F_EXT 0x8818 -#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 -#define GL_RGBA16F_EXT 0x881A -#define GL_RGB16F_EXT 0x881B -#define GL_ALPHA16F_EXT 0x881C -#define GL_LUMINANCE16F_EXT 0x881E -#define GL_LUMINANCE_ALPHA16F_EXT 0x881F -#define GL_RGB_RAW_422_APPLE 0x8A51 -#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F -#define GL_BGRA8_EXT 0x93A1 - -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - -#define glTexStorage1DEXT GLEW_GET_FUN(__glewTexStorage1DEXT) -#define glTexStorage2DEXT GLEW_GET_FUN(__glewTexStorage2DEXT) -#define glTexStorage3DEXT GLEW_GET_FUN(__glewTexStorage3DEXT) -#define glTextureStorage1DEXT GLEW_GET_FUN(__glewTextureStorage1DEXT) -#define glTextureStorage2DEXT GLEW_GET_FUN(__glewTextureStorage2DEXT) -#define glTextureStorage3DEXT GLEW_GET_FUN(__glewTextureStorage3DEXT) - -#define GLEW_EXT_texture_storage GLEW_GET_VAR(__GLEW_EXT_texture_storage) - -#endif /* GL_EXT_texture_storage */ - -/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ - -#ifndef GL_EXT_texture_swizzle -#define GL_EXT_texture_swizzle 1 - -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 - -#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) - -#endif /* GL_EXT_texture_swizzle */ - -/* ------------------- GL_EXT_texture_type_2_10_10_10_REV ------------------ */ - -#ifndef GL_EXT_texture_type_2_10_10_10_REV -#define GL_EXT_texture_type_2_10_10_10_REV 1 - -#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 - -#define GLEW_EXT_texture_type_2_10_10_10_REV GLEW_GET_VAR(__GLEW_EXT_texture_type_2_10_10_10_REV) - -#endif /* GL_EXT_texture_type_2_10_10_10_REV */ - -/* -------------------------- GL_EXT_texture_view -------------------------- */ - -#ifndef GL_EXT_texture_view -#define GL_EXT_texture_view 1 - -#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB -#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC -#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD -#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF - -typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); - -#define glTextureViewEXT GLEW_GET_FUN(__glewTextureViewEXT) - -#define GLEW_EXT_texture_view GLEW_GET_VAR(__GLEW_EXT_texture_view) - -#endif /* GL_EXT_texture_view */ - -/* --------------------------- GL_EXT_timer_query -------------------------- */ - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 - -#define GL_TIME_ELAPSED_EXT 0x88BF - -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); - -#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) -#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) - -#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) - -#endif /* GL_EXT_timer_query */ - -/* ----------------------- GL_EXT_transform_feedback ----------------------- */ - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 - -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F - -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar * const* varyings, GLenum bufferMode); - -#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) -#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) -#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) -#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) -#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) -#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) -#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) - -#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) - -#endif /* GL_EXT_transform_feedback */ - -/* ------------------------- GL_EXT_unpack_subimage ------------------------ */ - -#ifndef GL_EXT_unpack_subimage -#define GL_EXT_unpack_subimage 1 - -#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 -#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 - -#define GLEW_EXT_unpack_subimage GLEW_GET_VAR(__GLEW_EXT_unpack_subimage) - -#endif /* GL_EXT_unpack_subimage */ - -/* -------------------------- GL_EXT_vertex_array -------------------------- */ - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 - -#define GL_DOUBLE_EXT 0x140A -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 - -typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); -typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); - -#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) -#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) -#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) -#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) -#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) -#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) -#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) -#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) - -#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) - -#endif /* GL_EXT_vertex_array */ - -/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 - -#define GL_BGRA 0x80E1 - -#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) - -#endif /* GL_EXT_vertex_array_bgra */ - -/* ----------------------- GL_EXT_vertex_array_setXXX ---------------------- */ - -#ifndef GL_EXT_vertex_array_setXXX -#define GL_EXT_vertex_array_setXXX 1 - -typedef void (GLAPIENTRY * PFNGLBINDARRAYSETEXTPROC) (const void *arrayset); -typedef const void * (GLAPIENTRY * PFNGLCREATEARRAYSETEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLDELETEARRAYSETSEXTPROC) (GLsizei n, const void *arrayset[]); - -#define glBindArraySetEXT GLEW_GET_FUN(__glewBindArraySetEXT) -#define glCreateArraySetExt GLEW_GET_FUN(__glewCreateArraySetExt) -#define glDeleteArraySetsEXT GLEW_GET_FUN(__glewDeleteArraySetsEXT) - -#define GLEW_EXT_vertex_array_setXXX GLEW_GET_VAR(__GLEW_EXT_vertex_array_setXXX) - -#endif /* GL_EXT_vertex_array_setXXX */ - -/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */ - -#ifndef GL_EXT_vertex_attrib_64bit -#define GL_EXT_vertex_attrib_64bit 1 - -#define GL_DOUBLE_MAT2_EXT 0x8F46 -#define GL_DOUBLE_MAT3_EXT 0x8F47 -#define GL_DOUBLE_MAT4_EXT 0x8F48 -#define GL_DOUBLE_MAT2x3_EXT 0x8F49 -#define GL_DOUBLE_MAT2x4_EXT 0x8F4A -#define GL_DOUBLE_MAT3x2_EXT 0x8F4B -#define GL_DOUBLE_MAT3x4_EXT 0x8F4C -#define GL_DOUBLE_MAT4x2_EXT 0x8F4D -#define GL_DOUBLE_MAT4x3_EXT 0x8F4E -#define GL_DOUBLE_VEC2_EXT 0x8FFC -#define GL_DOUBLE_VEC3_EXT 0x8FFD -#define GL_DOUBLE_VEC4_EXT 0x8FFE - -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); - -#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT) -#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT) -#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT) -#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT) -#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT) -#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT) -#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT) -#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT) -#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT) -#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT) -#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT) - -#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit) - -#endif /* GL_EXT_vertex_attrib_64bit */ - -/* -------------------------- GL_EXT_vertex_shader ------------------------- */ - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 - -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED - -typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); -typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); -typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, void *addr); -typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, void *addr); -typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, void *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); -typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); - -#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) -#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) -#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) -#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) -#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) -#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) -#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) -#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) -#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) -#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) -#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) -#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) -#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) -#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) -#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) -#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) -#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) -#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) -#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) -#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) -#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) -#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) -#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) -#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) -#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) -#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) -#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) -#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) -#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) -#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) -#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) -#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) -#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) -#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) -#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) -#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) -#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) -#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) -#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) -#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) -#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) -#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) - -#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) - -#endif /* GL_EXT_vertex_shader */ - -/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 - -#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 -#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 -#define GL_MODELVIEW0_EXT 0x1700 -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 - -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); - -#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) -#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) -#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) - -#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) - -#endif /* GL_EXT_vertex_weighting */ - -/* ------------------------ GL_EXT_win32_keyed_mutex ----------------------- */ - -#ifndef GL_EXT_win32_keyed_mutex -#define GL_EXT_win32_keyed_mutex 1 - -typedef GLboolean (GLAPIENTRY * PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); -typedef GLboolean (GLAPIENTRY * PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); - -#define glAcquireKeyedMutexWin32EXT GLEW_GET_FUN(__glewAcquireKeyedMutexWin32EXT) -#define glReleaseKeyedMutexWin32EXT GLEW_GET_FUN(__glewReleaseKeyedMutexWin32EXT) - -#define GLEW_EXT_win32_keyed_mutex GLEW_GET_VAR(__GLEW_EXT_win32_keyed_mutex) - -#endif /* GL_EXT_win32_keyed_mutex */ - -/* ------------------------ GL_EXT_window_rectangles ----------------------- */ - -#ifndef GL_EXT_window_rectangles -#define GL_EXT_window_rectangles 1 - -#define GL_INCLUSIVE_EXT 0x8F10 -#define GL_EXCLUSIVE_EXT 0x8F11 -#define GL_WINDOW_RECTANGLE_EXT 0x8F12 -#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 -#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 -#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 - -typedef void (GLAPIENTRY * PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint box[]); - -#define glWindowRectanglesEXT GLEW_GET_FUN(__glewWindowRectanglesEXT) - -#define GLEW_EXT_window_rectangles GLEW_GET_VAR(__GLEW_EXT_window_rectangles) - -#endif /* GL_EXT_window_rectangles */ - -/* ------------------------- GL_EXT_x11_sync_object ------------------------ */ - -#ifndef GL_EXT_x11_sync_object -#define GL_EXT_x11_sync_object 1 - -#define GL_SYNC_X11_FENCE_EXT 0x90E1 - -typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); - -#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT) - -#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object) - -#endif /* GL_EXT_x11_sync_object */ - -/* ----------------------- GL_FJ_shader_binary_GCCSO ----------------------- */ - -#ifndef GL_FJ_shader_binary_GCCSO -#define GL_FJ_shader_binary_GCCSO 1 - -#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 - -#define GLEW_FJ_shader_binary_GCCSO GLEW_GET_VAR(__GLEW_FJ_shader_binary_GCCSO) - -#endif /* GL_FJ_shader_binary_GCCSO */ - -/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 - -typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); - -#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) - -#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) - -#endif /* GL_GREMEDY_frame_terminator */ - -/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 - -typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); - -#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) - -#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) - -#endif /* GL_GREMEDY_string_marker */ - -/* --------------------- GL_HP_convolution_border_modes -------------------- */ - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 - -#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) - -#endif /* GL_HP_convolution_border_modes */ - -/* ------------------------- GL_HP_image_transform ------------------------- */ - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 - -typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) -#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) -#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) -#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) -#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) -#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) - -#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) - -#endif /* GL_HP_image_transform */ - -/* -------------------------- GL_HP_occlusion_test ------------------------- */ - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 - -#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) - -#endif /* GL_HP_occlusion_test */ - -/* ------------------------- GL_HP_texture_lighting ------------------------ */ - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 - -#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) - -#endif /* GL_HP_texture_lighting */ - -/* --------------------------- GL_IBM_cull_vertex -------------------------- */ - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 - -#define GL_CULL_VERTEX_IBM 103050 - -#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) - -#endif /* GL_IBM_cull_vertex */ - -/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 - -typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount, GLint modestride); - -#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) -#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) - -#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) - -#endif /* GL_IBM_multimode_draw_arrays */ - -/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 - -#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 - -#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) - -#endif /* GL_IBM_rasterpos_clip */ - -/* --------------------------- GL_IBM_static_data -------------------------- */ - -#ifndef GL_IBM_static_data -#define GL_IBM_static_data 1 - -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 - -#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) - -#endif /* GL_IBM_static_data */ - -/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_IBM_texture_mirrored_repeat 1 - -#define GL_MIRRORED_REPEAT_IBM 0x8370 - -#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) - -#endif /* GL_IBM_texture_mirrored_repeat */ - -/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 - -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 - -typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); - -#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) -#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) -#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) -#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) -#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) -#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) -#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) -#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) - -#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) - -#endif /* GL_IBM_vertex_array_lists */ - -/* ------------------------ GL_IMG_bindless_texture ------------------------ */ - -#ifndef GL_IMG_bindless_texture -#define GL_IMG_bindless_texture 1 - -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture); -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) (GLuint texture, GLuint sampler); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64IMGPROC) (GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VIMGPROC) (GLint location, GLsizei count, const GLuint64* value); - -#define glGetTextureHandleIMG GLEW_GET_FUN(__glewGetTextureHandleIMG) -#define glGetTextureSamplerHandleIMG GLEW_GET_FUN(__glewGetTextureSamplerHandleIMG) -#define glProgramUniformHandleui64IMG GLEW_GET_FUN(__glewProgramUniformHandleui64IMG) -#define glProgramUniformHandleui64vIMG GLEW_GET_FUN(__glewProgramUniformHandleui64vIMG) -#define glUniformHandleui64IMG GLEW_GET_FUN(__glewUniformHandleui64IMG) -#define glUniformHandleui64vIMG GLEW_GET_FUN(__glewUniformHandleui64vIMG) - -#define GLEW_IMG_bindless_texture GLEW_GET_VAR(__GLEW_IMG_bindless_texture) - -#endif /* GL_IMG_bindless_texture */ - -/* --------------------- GL_IMG_framebuffer_downsample --------------------- */ - -#ifndef GL_IMG_framebuffer_downsample -#define GL_IMG_framebuffer_downsample 1 - -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C -#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D -#define GL_DOWNSAMPLE_SCALES_IMG 0x913E -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); - -#define glFramebufferTexture2DDownsampleIMG GLEW_GET_FUN(__glewFramebufferTexture2DDownsampleIMG) -#define glFramebufferTextureLayerDownsampleIMG GLEW_GET_FUN(__glewFramebufferTextureLayerDownsampleIMG) - -#define GLEW_IMG_framebuffer_downsample GLEW_GET_VAR(__GLEW_IMG_framebuffer_downsample) - -#endif /* GL_IMG_framebuffer_downsample */ - -/* ----------------- GL_IMG_multisampled_render_to_texture ----------------- */ - -#ifndef GL_IMG_multisampled_render_to_texture -#define GL_IMG_multisampled_render_to_texture 1 - -#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 -#define GL_MAX_SAMPLES_IMG 0x9135 -#define GL_TEXTURE_SAMPLES_IMG 0x9136 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glFramebufferTexture2DMultisampleIMG GLEW_GET_FUN(__glewFramebufferTexture2DMultisampleIMG) -#define glRenderbufferStorageMultisampleIMG GLEW_GET_FUN(__glewRenderbufferStorageMultisampleIMG) - -#define GLEW_IMG_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_IMG_multisampled_render_to_texture) - -#endif /* GL_IMG_multisampled_render_to_texture */ - -/* ------------------------- GL_IMG_program_binary ------------------------- */ - -#ifndef GL_IMG_program_binary -#define GL_IMG_program_binary 1 - -#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 - -#define GLEW_IMG_program_binary GLEW_GET_VAR(__GLEW_IMG_program_binary) - -#endif /* GL_IMG_program_binary */ - -/* --------------------------- GL_IMG_read_format -------------------------- */ - -#ifndef GL_IMG_read_format -#define GL_IMG_read_format 1 - -#define GL_BGRA_IMG 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 - -#define GLEW_IMG_read_format GLEW_GET_VAR(__GLEW_IMG_read_format) - -#endif /* GL_IMG_read_format */ - -/* -------------------------- GL_IMG_shader_binary ------------------------- */ - -#ifndef GL_IMG_shader_binary -#define GL_IMG_shader_binary 1 - -#define GL_SGX_BINARY_IMG 0x8C0A - -#define GLEW_IMG_shader_binary GLEW_GET_VAR(__GLEW_IMG_shader_binary) - -#endif /* GL_IMG_shader_binary */ - -/* -------------------- GL_IMG_texture_compression_pvrtc ------------------- */ - -#ifndef GL_IMG_texture_compression_pvrtc -#define GL_IMG_texture_compression_pvrtc 1 - -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 - -#define GLEW_IMG_texture_compression_pvrtc GLEW_GET_VAR(__GLEW_IMG_texture_compression_pvrtc) - -#endif /* GL_IMG_texture_compression_pvrtc */ - -/* ------------------- GL_IMG_texture_compression_pvrtc2 ------------------- */ - -#ifndef GL_IMG_texture_compression_pvrtc2 -#define GL_IMG_texture_compression_pvrtc2 1 - -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 - -#define GLEW_IMG_texture_compression_pvrtc2 GLEW_GET_VAR(__GLEW_IMG_texture_compression_pvrtc2) - -#endif /* GL_IMG_texture_compression_pvrtc2 */ - -/* --------------- GL_IMG_texture_env_enhanced_fixed_function -------------- */ - -#ifndef GL_IMG_texture_env_enhanced_fixed_function -#define GL_IMG_texture_env_enhanced_fixed_function 1 - -#define GL_DOT3_RGBA_IMG 0x86AF -#define GL_MODULATE_COLOR_IMG 0x8C04 -#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05 -#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06 -#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07 -#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08 -#define GL_ADD_BLEND_IMG 0x8C09 - -#define GLEW_IMG_texture_env_enhanced_fixed_function GLEW_GET_VAR(__GLEW_IMG_texture_env_enhanced_fixed_function) - -#endif /* GL_IMG_texture_env_enhanced_fixed_function */ - -/* ---------------------- GL_IMG_texture_filter_cubic ---------------------- */ - -#ifndef GL_IMG_texture_filter_cubic -#define GL_IMG_texture_filter_cubic 1 - -#define GL_CUBIC_IMG 0x9139 -#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A -#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B - -#define GLEW_IMG_texture_filter_cubic GLEW_GET_VAR(__GLEW_IMG_texture_filter_cubic) - -#endif /* GL_IMG_texture_filter_cubic */ - -/* -------------------------- GL_INGR_color_clamp -------------------------- */ - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 - -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 - -#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) - -#endif /* GL_INGR_color_clamp */ - -/* ------------------------- GL_INGR_interlace_read ------------------------ */ - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 - -#define GL_INTERLACE_READ_INGR 0x8568 - -#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) - -#endif /* GL_INGR_interlace_read */ - -/* ----------------------- GL_INTEL_blackhole_render ----------------------- */ - -#ifndef GL_INTEL_blackhole_render -#define GL_INTEL_blackhole_render 1 - -#define GL_BLACKHOLE_RENDER_INTEL 0x83FC - -#define GLEW_INTEL_blackhole_render GLEW_GET_VAR(__GLEW_INTEL_blackhole_render) - -#endif /* GL_INTEL_blackhole_render */ - -/* ------------------ GL_INTEL_conservative_rasterization ------------------ */ - -#ifndef GL_INTEL_conservative_rasterization -#define GL_INTEL_conservative_rasterization 1 - -#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE - -#define GLEW_INTEL_conservative_rasterization GLEW_GET_VAR(__GLEW_INTEL_conservative_rasterization) - -#endif /* GL_INTEL_conservative_rasterization */ - -/* ------------------- GL_INTEL_fragment_shader_ordering ------------------- */ - -#ifndef GL_INTEL_fragment_shader_ordering -#define GL_INTEL_fragment_shader_ordering 1 - -#define GLEW_INTEL_fragment_shader_ordering GLEW_GET_VAR(__GLEW_INTEL_fragment_shader_ordering) - -#endif /* GL_INTEL_fragment_shader_ordering */ - -/* ----------------------- GL_INTEL_framebuffer_CMAA ----------------------- */ - -#ifndef GL_INTEL_framebuffer_CMAA -#define GL_INTEL_framebuffer_CMAA 1 - -#define GLEW_INTEL_framebuffer_CMAA GLEW_GET_VAR(__GLEW_INTEL_framebuffer_CMAA) - -#endif /* GL_INTEL_framebuffer_CMAA */ - -/* -------------------------- GL_INTEL_map_texture ------------------------- */ - -#ifndef GL_INTEL_map_texture -#define GL_INTEL_map_texture 1 - -#define GL_LAYOUT_DEFAULT_INTEL 0 -#define GL_LAYOUT_LINEAR_INTEL 1 -#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 -#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF - -typedef void * (GLAPIENTRY * PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint* stride, GLenum *layout); -typedef void (GLAPIENTRY * PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); -typedef void (GLAPIENTRY * PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); - -#define glMapTexture2DINTEL GLEW_GET_FUN(__glewMapTexture2DINTEL) -#define glSyncTextureINTEL GLEW_GET_FUN(__glewSyncTextureINTEL) -#define glUnmapTexture2DINTEL GLEW_GET_FUN(__glewUnmapTexture2DINTEL) - -#define GLEW_INTEL_map_texture GLEW_GET_VAR(__GLEW_INTEL_map_texture) - -#endif /* GL_INTEL_map_texture */ - -/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 - -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 - -typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); - -#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) -#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) -#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) -#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) - -#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) - -#endif /* GL_INTEL_parallel_arrays */ - -/* ----------------------- GL_INTEL_performance_query ---------------------- */ - -#ifndef GL_INTEL_performance_query -#define GL_INTEL_performance_query 1 - -#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x0000 -#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x0001 -#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 -#define GL_PERFQUERY_FLUSH_INTEL 0x83FA -#define GL_PERFQUERY_WAIT_INTEL 0x83FB -#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 -#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 -#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 -#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 -#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 -#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 -#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 -#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 -#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA -#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB -#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC -#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD -#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE -#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF -#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 - -typedef void (GLAPIENTRY * PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (GLAPIENTRY * PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint* queryHandle); -typedef void (GLAPIENTRY * PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (GLAPIENTRY * PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (GLAPIENTRY * PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint* queryId); -typedef void (GLAPIENTRY * PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint* nextQueryId); -typedef void (GLAPIENTRY * PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar* counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (GLAPIENTRY * PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); -typedef void (GLAPIENTRY * PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar* queryName, GLuint *queryId); -typedef void (GLAPIENTRY * PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar* queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); - -#define glBeginPerfQueryINTEL GLEW_GET_FUN(__glewBeginPerfQueryINTEL) -#define glCreatePerfQueryINTEL GLEW_GET_FUN(__glewCreatePerfQueryINTEL) -#define glDeletePerfQueryINTEL GLEW_GET_FUN(__glewDeletePerfQueryINTEL) -#define glEndPerfQueryINTEL GLEW_GET_FUN(__glewEndPerfQueryINTEL) -#define glGetFirstPerfQueryIdINTEL GLEW_GET_FUN(__glewGetFirstPerfQueryIdINTEL) -#define glGetNextPerfQueryIdINTEL GLEW_GET_FUN(__glewGetNextPerfQueryIdINTEL) -#define glGetPerfCounterInfoINTEL GLEW_GET_FUN(__glewGetPerfCounterInfoINTEL) -#define glGetPerfQueryDataINTEL GLEW_GET_FUN(__glewGetPerfQueryDataINTEL) -#define glGetPerfQueryIdByNameINTEL GLEW_GET_FUN(__glewGetPerfQueryIdByNameINTEL) -#define glGetPerfQueryInfoINTEL GLEW_GET_FUN(__glewGetPerfQueryInfoINTEL) - -#define GLEW_INTEL_performance_query GLEW_GET_VAR(__GLEW_INTEL_performance_query) - -#endif /* GL_INTEL_performance_query */ - -/* ------------------- GL_INTEL_shader_integer_functions2 ------------------ */ - -#ifndef GL_INTEL_shader_integer_functions2 -#define GL_INTEL_shader_integer_functions2 1 - -#define GLEW_INTEL_shader_integer_functions2 GLEW_GET_VAR(__GLEW_INTEL_shader_integer_functions2) - -#endif /* GL_INTEL_shader_integer_functions2 */ - -/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ - -#ifndef GL_INTEL_texture_scissor -#define GL_INTEL_texture_scissor 1 - -typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); -typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); - -#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) -#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) - -#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) - -#endif /* GL_INTEL_texture_scissor */ - -/* --------------------- GL_KHR_blend_equation_advanced -------------------- */ - -#ifndef GL_KHR_blend_equation_advanced -#define GL_KHR_blend_equation_advanced 1 - -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_SCREEN_KHR 0x9295 -#define GL_OVERLAY_KHR 0x9296 -#define GL_DARKEN_KHR 0x9297 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORBURN_KHR 0x929A -#define GL_HARDLIGHT_KHR 0x929B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_DIFFERENCE_KHR 0x929E -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_LUMINOSITY_KHR 0x92B0 - -typedef void (GLAPIENTRY * PFNGLBLENDBARRIERKHRPROC) (void); - -#define glBlendBarrierKHR GLEW_GET_FUN(__glewBlendBarrierKHR) - -#define GLEW_KHR_blend_equation_advanced GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced) - -#endif /* GL_KHR_blend_equation_advanced */ - -/* ---------------- GL_KHR_blend_equation_advanced_coherent ---------------- */ - -#ifndef GL_KHR_blend_equation_advanced_coherent -#define GL_KHR_blend_equation_advanced_coherent 1 - -#define GLEW_KHR_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced_coherent) - -#endif /* GL_KHR_blend_equation_advanced_coherent */ - -/* ---------------------- GL_KHR_context_flush_control --------------------- */ - -#ifndef GL_KHR_context_flush_control -#define GL_KHR_context_flush_control 1 - -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC - -#define GLEW_KHR_context_flush_control GLEW_GET_VAR(__GLEW_KHR_context_flush_control) - -#endif /* GL_KHR_context_flush_control */ - -/* ------------------------------ GL_KHR_debug ----------------------------- */ - -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 - -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_BUFFER 0x82E0 -#define GL_SHADER 0x82E1 -#define GL_PROGRAM 0x82E2 -#define GL_QUERY 0x82E3 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_SAMPLER 0x82E6 -#define GL_DISPLAY_LIST 0x82E7 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_OUTPUT 0x92E0 - -typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); - -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); -typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); -typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); -typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label); -typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (void* ptr, GLsizei bufSize, GLsizei* length, GLchar *label); -typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label); -typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (void* ptr, GLsizei length, const GLchar* label); -typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void); -typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); - -#define glDebugMessageCallback GLEW_GET_FUN(__glewDebugMessageCallback) -#define glDebugMessageControl GLEW_GET_FUN(__glewDebugMessageControl) -#define glDebugMessageInsert GLEW_GET_FUN(__glewDebugMessageInsert) -#define glGetDebugMessageLog GLEW_GET_FUN(__glewGetDebugMessageLog) -#define glGetObjectLabel GLEW_GET_FUN(__glewGetObjectLabel) -#define glGetObjectPtrLabel GLEW_GET_FUN(__glewGetObjectPtrLabel) -#define glObjectLabel GLEW_GET_FUN(__glewObjectLabel) -#define glObjectPtrLabel GLEW_GET_FUN(__glewObjectPtrLabel) -#define glPopDebugGroup GLEW_GET_FUN(__glewPopDebugGroup) -#define glPushDebugGroup GLEW_GET_FUN(__glewPushDebugGroup) - -#define GLEW_KHR_debug GLEW_GET_VAR(__GLEW_KHR_debug) - -#endif /* GL_KHR_debug */ - -/* ---------------------------- GL_KHR_no_error ---------------------------- */ - -#ifndef GL_KHR_no_error -#define GL_KHR_no_error 1 - -#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 - -#define GLEW_KHR_no_error GLEW_GET_VAR(__GLEW_KHR_no_error) - -#endif /* GL_KHR_no_error */ - -/* --------------------- GL_KHR_parallel_shader_compile -------------------- */ - -#ifndef GL_KHR_parallel_shader_compile -#define GL_KHR_parallel_shader_compile 1 - -#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 -#define GL_COMPLETION_STATUS_KHR 0x91B1 - -typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count); - -#define glMaxShaderCompilerThreadsKHR GLEW_GET_FUN(__glewMaxShaderCompilerThreadsKHR) - -#define GLEW_KHR_parallel_shader_compile GLEW_GET_VAR(__GLEW_KHR_parallel_shader_compile) - -#endif /* GL_KHR_parallel_shader_compile */ - -/* ------------------ GL_KHR_robust_buffer_access_behavior ----------------- */ - -#ifndef GL_KHR_robust_buffer_access_behavior -#define GL_KHR_robust_buffer_access_behavior 1 - -#define GLEW_KHR_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_KHR_robust_buffer_access_behavior) - -#endif /* GL_KHR_robust_buffer_access_behavior */ - -/* --------------------------- GL_KHR_robustness --------------------------- */ - -#ifndef GL_KHR_robustness -#define GL_KHR_robustness 1 - -#define GL_CONTEXT_LOST 0x0507 -#define GL_LOSE_CONTEXT_ON_RESET 0x8252 -#define GL_GUILTY_CONTEXT_RESET 0x8253 -#define GL_INNOCENT_CONTEXT_RESET 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 -#define GL_NO_RESET_NOTIFICATION 0x8261 -#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 - -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); -typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); - -#define glGetnUniformfv GLEW_GET_FUN(__glewGetnUniformfv) -#define glGetnUniformiv GLEW_GET_FUN(__glewGetnUniformiv) -#define glGetnUniformuiv GLEW_GET_FUN(__glewGetnUniformuiv) -#define glReadnPixels GLEW_GET_FUN(__glewReadnPixels) - -#define GLEW_KHR_robustness GLEW_GET_VAR(__GLEW_KHR_robustness) - -#endif /* GL_KHR_robustness */ - -/* ------------------------- GL_KHR_shader_subgroup ------------------------ */ - -#ifndef GL_KHR_shader_subgroup -#define GL_KHR_shader_subgroup 1 - -#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001 -#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002 -#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004 -#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008 -#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010 -#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020 -#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040 -#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080 -#define GL_SUBGROUP_SIZE_KHR 0x9532 -#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533 -#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534 -#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535 - -#define GLEW_KHR_shader_subgroup GLEW_GET_VAR(__GLEW_KHR_shader_subgroup) - -#endif /* GL_KHR_shader_subgroup */ - -/* ------------------ GL_KHR_texture_compression_astc_hdr ------------------ */ - -#ifndef GL_KHR_texture_compression_astc_hdr -#define GL_KHR_texture_compression_astc_hdr 1 - -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 -#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 -#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 -#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 -#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 -#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 -#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 -#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 -#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 -#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 - -#define GLEW_KHR_texture_compression_astc_hdr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_hdr) - -#endif /* GL_KHR_texture_compression_astc_hdr */ - -/* ------------------ GL_KHR_texture_compression_astc_ldr ------------------ */ - -#ifndef GL_KHR_texture_compression_astc_ldr -#define GL_KHR_texture_compression_astc_ldr 1 - -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 -#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 -#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 -#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 -#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 -#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 -#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 -#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 -#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 -#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 - -#define GLEW_KHR_texture_compression_astc_ldr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_ldr) - -#endif /* GL_KHR_texture_compression_astc_ldr */ - -/* --------------- GL_KHR_texture_compression_astc_sliced_3d --------------- */ - -#ifndef GL_KHR_texture_compression_astc_sliced_3d -#define GL_KHR_texture_compression_astc_sliced_3d 1 - -#define GLEW_KHR_texture_compression_astc_sliced_3d GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_sliced_3d) - -#endif /* GL_KHR_texture_compression_astc_sliced_3d */ - -/* -------------------------- GL_KTX_buffer_region ------------------------- */ - -#ifndef GL_KTX_buffer_region -#define GL_KTX_buffer_region 1 - -#define GL_KTX_FRONT_REGION 0x0 -#define GL_KTX_BACK_REGION 0x1 -#define GL_KTX_Z_REGION 0x2 -#define GL_KTX_STENCIL_REGION 0x3 - -typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDPROC) (void); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONPROC) (GLenum region); -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); -typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONPROC) (GLenum region); -typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); - -#define glBufferRegionEnabled GLEW_GET_FUN(__glewBufferRegionEnabled) -#define glDeleteBufferRegion GLEW_GET_FUN(__glewDeleteBufferRegion) -#define glDrawBufferRegion GLEW_GET_FUN(__glewDrawBufferRegion) -#define glNewBufferRegion GLEW_GET_FUN(__glewNewBufferRegion) -#define glReadBufferRegion GLEW_GET_FUN(__glewReadBufferRegion) - -#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) - -#endif /* GL_KTX_buffer_region */ - -/* ------------------------- GL_MESAX_texture_stack ------------------------ */ - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 - -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E - -#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) - -#endif /* GL_MESAX_texture_stack */ - -/* ----------------------- GL_MESA_framebuffer_flip_y ---------------------- */ - -#ifndef GL_MESA_framebuffer_flip_y -#define GL_MESA_framebuffer_flip_y 1 - -#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint* params); - -#define glFramebufferParameteriMESA GLEW_GET_FUN(__glewFramebufferParameteriMESA) -#define glGetFramebufferParameterivMESA GLEW_GET_FUN(__glewGetFramebufferParameterivMESA) - -#define GLEW_MESA_framebuffer_flip_y GLEW_GET_VAR(__GLEW_MESA_framebuffer_flip_y) - -#endif /* GL_MESA_framebuffer_flip_y */ - -/* -------------------------- GL_MESA_pack_invert -------------------------- */ - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 - -#define GL_PACK_INVERT_MESA 0x8758 - -#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) - -#endif /* GL_MESA_pack_invert */ - -/* --------------------- GL_MESA_program_binary_formats -------------------- */ - -#ifndef GL_MESA_program_binary_formats -#define GL_MESA_program_binary_formats 1 - -#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F - -#define GLEW_MESA_program_binary_formats GLEW_GET_VAR(__GLEW_MESA_program_binary_formats) - -#endif /* GL_MESA_program_binary_formats */ - -/* ------------------------- GL_MESA_resize_buffers ------------------------ */ - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 - -typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); - -#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) - -#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) - -#endif /* GL_MESA_resize_buffers */ - -/* -------------------- GL_MESA_shader_integer_functions ------------------- */ - -#ifndef GL_MESA_shader_integer_functions -#define GL_MESA_shader_integer_functions 1 - -#define GLEW_MESA_shader_integer_functions GLEW_GET_VAR(__GLEW_MESA_shader_integer_functions) - -#endif /* GL_MESA_shader_integer_functions */ - -/* ----------------------- GL_MESA_tile_raster_order ----------------------- */ - -#ifndef GL_MESA_tile_raster_order -#define GL_MESA_tile_raster_order 1 - -#define GLEW_MESA_tile_raster_order GLEW_GET_VAR(__GLEW_MESA_tile_raster_order) - -#endif /* GL_MESA_tile_raster_order */ - -/* --------------------------- GL_MESA_window_pos -------------------------- */ - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 - -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); - -#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) -#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) -#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) -#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) -#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) -#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) -#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) -#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) -#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) -#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) -#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) -#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) -#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) -#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) -#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) -#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) -#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) -#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) -#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) -#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) -#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) -#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) -#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) -#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) - -#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) - -#endif /* GL_MESA_window_pos */ - -/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 - -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 - -#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) - -#endif /* GL_MESA_ycbcr_texture */ - -/* ----------- GL_NVX_blend_equation_advanced_multi_draw_buffers ----------- */ - -#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers -#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 - -#define GLEW_NVX_blend_equation_advanced_multi_draw_buffers GLEW_GET_VAR(__GLEW_NVX_blend_equation_advanced_multi_draw_buffers) - -#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ - -/* ----------------------- GL_NVX_conditional_render ----------------------- */ - -#ifndef GL_NVX_conditional_render -#define GL_NVX_conditional_render 1 - -typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void); - -#define glBeginConditionalRenderNVX GLEW_GET_FUN(__glewBeginConditionalRenderNVX) -#define glEndConditionalRenderNVX GLEW_GET_FUN(__glewEndConditionalRenderNVX) - -#define GLEW_NVX_conditional_render GLEW_GET_VAR(__GLEW_NVX_conditional_render) - -#endif /* GL_NVX_conditional_render */ - -/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */ - -#ifndef GL_NVX_gpu_memory_info -#define GL_NVX_gpu_memory_info 1 - -#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 -#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 -#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 -#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A -#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B - -#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info) - -#endif /* GL_NVX_gpu_memory_info */ - -/* ------------------------- GL_NVX_gpu_multicast2 ------------------------- */ - -#ifndef GL_NVX_gpu_multicast2 -#define GL_NVX_gpu_multicast2 1 - -#define GL_UPLOAD_GPU_MASK_NVX 0x954A - -typedef GLsync (GLAPIENTRY * PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint* waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); -typedef GLuint (GLAPIENTRY * PFNGLASYNCCOPYIMAGESUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint* waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); -typedef void (GLAPIENTRY * PFNGLMULTICASTSCISSORARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLint* v); -typedef void (GLAPIENTRY * PFNGLMULTICASTVIEWPORTARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC) (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); -typedef void (GLAPIENTRY * PFNGLUPLOADGPUMASKNVXPROC) (GLbitfield mask); - -#define glAsyncCopyBufferSubDataNVX GLEW_GET_FUN(__glewAsyncCopyBufferSubDataNVX) -#define glAsyncCopyImageSubDataNVX GLEW_GET_FUN(__glewAsyncCopyImageSubDataNVX) -#define glMulticastScissorArrayvNVX GLEW_GET_FUN(__glewMulticastScissorArrayvNVX) -#define glMulticastViewportArrayvNVX GLEW_GET_FUN(__glewMulticastViewportArrayvNVX) -#define glMulticastViewportPositionWScaleNVX GLEW_GET_FUN(__glewMulticastViewportPositionWScaleNVX) -#define glUploadGpuMaskNVX GLEW_GET_FUN(__glewUploadGpuMaskNVX) - -#define GLEW_NVX_gpu_multicast2 GLEW_GET_VAR(__GLEW_NVX_gpu_multicast2) - -#endif /* GL_NVX_gpu_multicast2 */ - -/* ---------------------- GL_NVX_linked_gpu_multicast ---------------------- */ - -#ifndef GL_NVX_linked_gpu_multicast -#define GL_NVX_linked_gpu_multicast 1 - -#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 -#define GL_MAX_LGPU_GPUS_NVX 0x92BA - -typedef void (GLAPIENTRY * PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAPIENTRY * PFNGLLGPUINTERLOCKNVXPROC) (void); -typedef void (GLAPIENTRY * PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); - -#define glLGPUCopyImageSubDataNVX GLEW_GET_FUN(__glewLGPUCopyImageSubDataNVX) -#define glLGPUInterlockNVX GLEW_GET_FUN(__glewLGPUInterlockNVX) -#define glLGPUNamedBufferSubDataNVX GLEW_GET_FUN(__glewLGPUNamedBufferSubDataNVX) - -#define GLEW_NVX_linked_gpu_multicast GLEW_GET_VAR(__GLEW_NVX_linked_gpu_multicast) - -#endif /* GL_NVX_linked_gpu_multicast */ - -/* ------------------------- GL_NVX_progress_fence ------------------------- */ - -#ifndef GL_NVX_progress_fence -#define GL_NVX_progress_fence 1 - -typedef void (GLAPIENTRY * PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC) (GLsizei fenceObjectCount, const GLuint* semaphoreArray, const GLuint64 *fenceValueArray); -typedef void (GLAPIENTRY * PFNGLSIGNALSEMAPHOREUI64NVXPROC) (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint* semaphoreArray, const GLuint64 *fenceValueArray); -typedef void (GLAPIENTRY * PFNGLWAITSEMAPHOREUI64NVXPROC) (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint* semaphoreArray, const GLuint64 *fenceValueArray); - -#define glClientWaitSemaphoreui64NVX GLEW_GET_FUN(__glewClientWaitSemaphoreui64NVX) -#define glSignalSemaphoreui64NVX GLEW_GET_FUN(__glewSignalSemaphoreui64NVX) -#define glWaitSemaphoreui64NVX GLEW_GET_FUN(__glewWaitSemaphoreui64NVX) - -#define GLEW_NVX_progress_fence GLEW_GET_VAR(__GLEW_NVX_progress_fence) - -#endif /* GL_NVX_progress_fence */ - -/* ------------------------ GL_NV_3dvision_settings ------------------------ */ - -#ifndef GL_NV_3dvision_settings -#define GL_NV_3dvision_settings 1 - -#define GL_3DVISION_STEREO_NV 0x90F4 -#define GL_STEREO_SEPARATION_NV 0x90F5 -#define GL_STEREO_CONVERGENCE_NV 0x90F6 -#define GL_STEREO_CUTOFF_NV 0x90F7 -#define GL_STEREO_PROJECTION_NV 0x90F8 -#define GL_STEREO_PROJECTION_PERSPECTIVE_NV 0x90F9 -#define GL_STEREO_PROJECTION_ORTHO_NV 0x90FA - -typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERINVPROC) (GLenum pname, GLint param); - -#define glStereoParameterfNV GLEW_GET_FUN(__glewStereoParameterfNV) -#define glStereoParameteriNV GLEW_GET_FUN(__glewStereoParameteriNV) - -#define GLEW_NV_3dvision_settings GLEW_GET_VAR(__GLEW_NV_3dvision_settings) - -#endif /* GL_NV_3dvision_settings */ - -/* ------------------- GL_NV_EGL_stream_consumer_external ------------------ */ - -#ifndef GL_NV_EGL_stream_consumer_external -#define GL_NV_EGL_stream_consumer_external 1 - -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 - -#define GLEW_NV_EGL_stream_consumer_external GLEW_GET_VAR(__GLEW_NV_EGL_stream_consumer_external) - -#endif /* GL_NV_EGL_stream_consumer_external */ - -/* ----------------- GL_NV_alpha_to_coverage_dither_control ---------------- */ - -#ifndef GL_NV_alpha_to_coverage_dither_control -#define GL_NV_alpha_to_coverage_dither_control 1 - -#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF -#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D -#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E -#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F - -typedef void (GLAPIENTRY * PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC) (GLenum mode); - -#define glAlphaToCoverageDitherControlNV GLEW_GET_FUN(__glewAlphaToCoverageDitherControlNV) - -#define GLEW_NV_alpha_to_coverage_dither_control GLEW_GET_VAR(__GLEW_NV_alpha_to_coverage_dither_control) - -#endif /* GL_NV_alpha_to_coverage_dither_control */ - -/* ------------------------------- GL_NV_bgr ------------------------------- */ - -#ifndef GL_NV_bgr -#define GL_NV_bgr 1 - -#define GL_BGR_NV 0x80E0 - -#define GLEW_NV_bgr GLEW_GET_VAR(__GLEW_NV_bgr) - -#endif /* GL_NV_bgr */ - -/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */ - -#ifndef GL_NV_bindless_multi_draw_indirect -#define GL_NV_bindless_multi_draw_indirect 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); - -#define glMultiDrawArraysIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessNV) -#define glMultiDrawElementsIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessNV) - -#define GLEW_NV_bindless_multi_draw_indirect GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect) - -#endif /* GL_NV_bindless_multi_draw_indirect */ - -/* ---------------- GL_NV_bindless_multi_draw_indirect_count --------------- */ - -#ifndef GL_NV_bindless_multi_draw_indirect_count -#define GL_NV_bindless_multi_draw_indirect_count 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); - -#define glMultiDrawArraysIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessCountNV) -#define glMultiDrawElementsIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessCountNV) - -#define GLEW_NV_bindless_multi_draw_indirect_count GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect_count) - -#endif /* GL_NV_bindless_multi_draw_indirect_count */ - -/* ------------------------- GL_NV_bindless_texture ------------------------ */ - -#ifndef GL_NV_bindless_texture -#define GL_NV_bindless_texture 1 - -typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); -typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); -typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); -typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); -typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64* value); - -#define glGetImageHandleNV GLEW_GET_FUN(__glewGetImageHandleNV) -#define glGetTextureHandleNV GLEW_GET_FUN(__glewGetTextureHandleNV) -#define glGetTextureSamplerHandleNV GLEW_GET_FUN(__glewGetTextureSamplerHandleNV) -#define glIsImageHandleResidentNV GLEW_GET_FUN(__glewIsImageHandleResidentNV) -#define glIsTextureHandleResidentNV GLEW_GET_FUN(__glewIsTextureHandleResidentNV) -#define glMakeImageHandleNonResidentNV GLEW_GET_FUN(__glewMakeImageHandleNonResidentNV) -#define glMakeImageHandleResidentNV GLEW_GET_FUN(__glewMakeImageHandleResidentNV) -#define glMakeTextureHandleNonResidentNV GLEW_GET_FUN(__glewMakeTextureHandleNonResidentNV) -#define glMakeTextureHandleResidentNV GLEW_GET_FUN(__glewMakeTextureHandleResidentNV) -#define glProgramUniformHandleui64NV GLEW_GET_FUN(__glewProgramUniformHandleui64NV) -#define glProgramUniformHandleui64vNV GLEW_GET_FUN(__glewProgramUniformHandleui64vNV) -#define glUniformHandleui64NV GLEW_GET_FUN(__glewUniformHandleui64NV) -#define glUniformHandleui64vNV GLEW_GET_FUN(__glewUniformHandleui64vNV) - -#define GLEW_NV_bindless_texture GLEW_GET_VAR(__GLEW_NV_bindless_texture) - -#endif /* GL_NV_bindless_texture */ - -/* --------------------- GL_NV_blend_equation_advanced --------------------- */ - -#ifndef GL_NV_blend_equation_advanced -#define GL_NV_blend_equation_advanced 1 - -#define GL_XOR_NV 0x1506 -#define GL_RED_NV 0x1903 -#define GL_GREEN_NV 0x1904 -#define GL_BLUE_NV 0x1905 -#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 -#define GL_BLEND_OVERLAP_NV 0x9281 -#define GL_UNCORRELATED_NV 0x9282 -#define GL_DISJOINT_NV 0x9283 -#define GL_CONJOINT_NV 0x9284 -#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 -#define GL_SRC_NV 0x9286 -#define GL_DST_NV 0x9287 -#define GL_SRC_OVER_NV 0x9288 -#define GL_DST_OVER_NV 0x9289 -#define GL_SRC_IN_NV 0x928A -#define GL_DST_IN_NV 0x928B -#define GL_SRC_OUT_NV 0x928C -#define GL_DST_OUT_NV 0x928D -#define GL_SRC_ATOP_NV 0x928E -#define GL_DST_ATOP_NV 0x928F -#define GL_PLUS_NV 0x9291 -#define GL_PLUS_DARKER_NV 0x9292 -#define GL_MULTIPLY_NV 0x9294 -#define GL_SCREEN_NV 0x9295 -#define GL_OVERLAY_NV 0x9296 -#define GL_DARKEN_NV 0x9297 -#define GL_LIGHTEN_NV 0x9298 -#define GL_COLORDODGE_NV 0x9299 -#define GL_COLORBURN_NV 0x929A -#define GL_HARDLIGHT_NV 0x929B -#define GL_SOFTLIGHT_NV 0x929C -#define GL_DIFFERENCE_NV 0x929E -#define GL_MINUS_NV 0x929F -#define GL_EXCLUSION_NV 0x92A0 -#define GL_CONTRAST_NV 0x92A1 -#define GL_INVERT_RGB_NV 0x92A3 -#define GL_LINEARDODGE_NV 0x92A4 -#define GL_LINEARBURN_NV 0x92A5 -#define GL_VIVIDLIGHT_NV 0x92A6 -#define GL_LINEARLIGHT_NV 0x92A7 -#define GL_PINLIGHT_NV 0x92A8 -#define GL_HARDMIX_NV 0x92A9 -#define GL_HSL_HUE_NV 0x92AD -#define GL_HSL_SATURATION_NV 0x92AE -#define GL_HSL_COLOR_NV 0x92AF -#define GL_HSL_LUMINOSITY_NV 0x92B0 -#define GL_PLUS_CLAMPED_NV 0x92B1 -#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 -#define GL_MINUS_CLAMPED_NV 0x92B3 -#define GL_INVERT_OVG_NV 0x92B4 - -typedef void (GLAPIENTRY * PFNGLBLENDBARRIERNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); - -#define glBlendBarrierNV GLEW_GET_FUN(__glewBlendBarrierNV) -#define glBlendParameteriNV GLEW_GET_FUN(__glewBlendParameteriNV) - -#define GLEW_NV_blend_equation_advanced GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced) - -#endif /* GL_NV_blend_equation_advanced */ - -/* ----------------- GL_NV_blend_equation_advanced_coherent ---------------- */ - -#ifndef GL_NV_blend_equation_advanced_coherent -#define GL_NV_blend_equation_advanced_coherent 1 - -#define GLEW_NV_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced_coherent) - -#endif /* GL_NV_blend_equation_advanced_coherent */ - -/* ----------------------- GL_NV_blend_minmax_factor ----------------------- */ - -#ifndef GL_NV_blend_minmax_factor -#define GL_NV_blend_minmax_factor 1 - -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FACTOR_MAX_AMD 0x901D - -#define GLEW_NV_blend_minmax_factor GLEW_GET_VAR(__GLEW_NV_blend_minmax_factor) - -#endif /* GL_NV_blend_minmax_factor */ - -/* --------------------------- GL_NV_blend_square -------------------------- */ - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 - -#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) - -#endif /* GL_NV_blend_square */ - -/* ----------------------- GL_NV_clip_space_w_scaling ---------------------- */ - -#ifndef GL_NV_clip_space_w_scaling -#define GL_NV_clip_space_w_scaling 1 - -#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C -#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D -#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E - -typedef void (GLAPIENTRY * PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); - -#define glViewportPositionWScaleNV GLEW_GET_FUN(__glewViewportPositionWScaleNV) - -#define GLEW_NV_clip_space_w_scaling GLEW_GET_VAR(__GLEW_NV_clip_space_w_scaling) - -#endif /* GL_NV_clip_space_w_scaling */ - -/* --------------------------- GL_NV_command_list -------------------------- */ - -#ifndef GL_NV_command_list -#define GL_NV_command_list 1 - -#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 -#define GL_NOP_COMMAND_NV 0x0001 -#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 -#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 -#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 -#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 -#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 -#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 -#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 -#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 -#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000a -#define GL_BLEND_COLOR_COMMAND_NV 0x000b -#define GL_STENCIL_REF_COMMAND_NV 0x000c -#define GL_LINE_WIDTH_COMMAND_NV 0x000d -#define GL_POLYGON_OFFSET_COMMAND_NV 0x000e -#define GL_ALPHA_REF_COMMAND_NV 0x000f -#define GL_VIEWPORT_COMMAND_NV 0x0010 -#define GL_SCISSOR_COMMAND_NV 0x0011 -#define GL_FRONT_FACE_COMMAND_NV 0x0012 - -typedef void (GLAPIENTRY * PFNGLCALLCOMMANDLISTNVPROC) (GLuint list); -typedef void (GLAPIENTRY * PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments); -typedef void (GLAPIENTRY * PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list); -typedef void (GLAPIENTRY * PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint* lists); -typedef void (GLAPIENTRY * PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint* states); -typedef void (GLAPIENTRY * PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint* lists); -typedef void (GLAPIENTRY * PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint* states); -typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64* indirects, const GLsizei* sizes, GLuint count); -typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, GLuint count); -typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); -typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); -typedef GLuint (GLAPIENTRY * PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size); -typedef GLushort (GLAPIENTRY * PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype); -typedef GLboolean (GLAPIENTRY * PFNGLISCOMMANDLISTNVPROC) (GLuint list); -typedef GLboolean (GLAPIENTRY * PFNGLISSTATENVPROC) (GLuint state); -typedef void (GLAPIENTRY * PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void** indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); -typedef void (GLAPIENTRY * PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode); - -#define glCallCommandListNV GLEW_GET_FUN(__glewCallCommandListNV) -#define glCommandListSegmentsNV GLEW_GET_FUN(__glewCommandListSegmentsNV) -#define glCompileCommandListNV GLEW_GET_FUN(__glewCompileCommandListNV) -#define glCreateCommandListsNV GLEW_GET_FUN(__glewCreateCommandListsNV) -#define glCreateStatesNV GLEW_GET_FUN(__glewCreateStatesNV) -#define glDeleteCommandListsNV GLEW_GET_FUN(__glewDeleteCommandListsNV) -#define glDeleteStatesNV GLEW_GET_FUN(__glewDeleteStatesNV) -#define glDrawCommandsAddressNV GLEW_GET_FUN(__glewDrawCommandsAddressNV) -#define glDrawCommandsNV GLEW_GET_FUN(__glewDrawCommandsNV) -#define glDrawCommandsStatesAddressNV GLEW_GET_FUN(__glewDrawCommandsStatesAddressNV) -#define glDrawCommandsStatesNV GLEW_GET_FUN(__glewDrawCommandsStatesNV) -#define glGetCommandHeaderNV GLEW_GET_FUN(__glewGetCommandHeaderNV) -#define glGetStageIndexNV GLEW_GET_FUN(__glewGetStageIndexNV) -#define glIsCommandListNV GLEW_GET_FUN(__glewIsCommandListNV) -#define glIsStateNV GLEW_GET_FUN(__glewIsStateNV) -#define glListDrawCommandsStatesClientNV GLEW_GET_FUN(__glewListDrawCommandsStatesClientNV) -#define glStateCaptureNV GLEW_GET_FUN(__glewStateCaptureNV) - -#define GLEW_NV_command_list GLEW_GET_VAR(__GLEW_NV_command_list) - -#endif /* GL_NV_command_list */ - -/* ------------------------- GL_NV_compute_program5 ------------------------ */ - -#ifndef GL_NV_compute_program5 -#define GL_NV_compute_program5 1 - -#define GL_COMPUTE_PROGRAM_NV 0x90FB -#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC - -#define GLEW_NV_compute_program5 GLEW_GET_VAR(__GLEW_NV_compute_program5) - -#endif /* GL_NV_compute_program5 */ - -/* -------------------- GL_NV_compute_shader_derivatives ------------------- */ - -#ifndef GL_NV_compute_shader_derivatives -#define GL_NV_compute_shader_derivatives 1 - -#define GLEW_NV_compute_shader_derivatives GLEW_GET_VAR(__GLEW_NV_compute_shader_derivatives) - -#endif /* GL_NV_compute_shader_derivatives */ - -/* ------------------------ GL_NV_conditional_render ----------------------- */ - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 - -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 - -typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); - -#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) -#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) - -#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) - -#endif /* GL_NV_conditional_render */ - -/* ----------------------- GL_NV_conservative_raster ----------------------- */ - -#ifndef GL_NV_conservative_raster -#define GL_NV_conservative_raster 1 - -#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 -#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 -#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 -#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 - -typedef void (GLAPIENTRY * PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); - -#define glSubpixelPrecisionBiasNV GLEW_GET_FUN(__glewSubpixelPrecisionBiasNV) - -#define GLEW_NV_conservative_raster GLEW_GET_VAR(__GLEW_NV_conservative_raster) - -#endif /* GL_NV_conservative_raster */ - -/* -------------------- GL_NV_conservative_raster_dilate ------------------- */ - -#ifndef GL_NV_conservative_raster_dilate -#define GL_NV_conservative_raster_dilate 1 - -#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 -#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A -#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B - -typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value); - -#define glConservativeRasterParameterfNV GLEW_GET_FUN(__glewConservativeRasterParameterfNV) - -#define GLEW_NV_conservative_raster_dilate GLEW_GET_VAR(__GLEW_NV_conservative_raster_dilate) - -#endif /* GL_NV_conservative_raster_dilate */ - -/* ------------------- GL_NV_conservative_raster_pre_snap ------------------ */ - -#ifndef GL_NV_conservative_raster_pre_snap -#define GL_NV_conservative_raster_pre_snap 1 - -#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 - -#define GLEW_NV_conservative_raster_pre_snap GLEW_GET_VAR(__GLEW_NV_conservative_raster_pre_snap) - -#endif /* GL_NV_conservative_raster_pre_snap */ - -/* -------------- GL_NV_conservative_raster_pre_snap_triangles ------------- */ - -#ifndef GL_NV_conservative_raster_pre_snap_triangles -#define GL_NV_conservative_raster_pre_snap_triangles 1 - -#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D -#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E -#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F - -typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); - -#define glConservativeRasterParameteriNV GLEW_GET_FUN(__glewConservativeRasterParameteriNV) - -#define GLEW_NV_conservative_raster_pre_snap_triangles GLEW_GET_VAR(__GLEW_NV_conservative_raster_pre_snap_triangles) - -#endif /* GL_NV_conservative_raster_pre_snap_triangles */ - -/* --------------- GL_NV_conservative_raster_underestimation --------------- */ - -#ifndef GL_NV_conservative_raster_underestimation -#define GL_NV_conservative_raster_underestimation 1 - -#define GLEW_NV_conservative_raster_underestimation GLEW_GET_VAR(__GLEW_NV_conservative_raster_underestimation) - -#endif /* GL_NV_conservative_raster_underestimation */ - -/* --------------------------- GL_NV_copy_buffer --------------------------- */ - -#ifndef GL_NV_copy_buffer -#define GL_NV_copy_buffer 1 - -#define GL_COPY_READ_BUFFER_NV 0x8F36 -#define GL_COPY_WRITE_BUFFER_NV 0x8F37 - -typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); - -#define glCopyBufferSubDataNV GLEW_GET_FUN(__glewCopyBufferSubDataNV) - -#define GLEW_NV_copy_buffer GLEW_GET_VAR(__GLEW_NV_copy_buffer) - -#endif /* GL_NV_copy_buffer */ - -/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 - -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F - -#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) - -#endif /* GL_NV_copy_depth_to_color */ - -/* ---------------------------- GL_NV_copy_image --------------------------- */ - -#ifndef GL_NV_copy_image -#define GL_NV_copy_image 1 - -typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - -#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV) - -#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image) - -#endif /* GL_NV_copy_image */ - -/* -------------------------- GL_NV_deep_texture3D ------------------------- */ - -#ifndef GL_NV_deep_texture3D -#define GL_NV_deep_texture3D 1 - -#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 -#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 - -#define GLEW_NV_deep_texture3D GLEW_GET_VAR(__GLEW_NV_deep_texture3D) - -#endif /* GL_NV_deep_texture3D */ - -/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 - -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF - -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); - -#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) -#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) -#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) - -#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) - -#endif /* GL_NV_depth_buffer_float */ - -/* --------------------------- GL_NV_depth_clamp --------------------------- */ - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 - -#define GL_DEPTH_CLAMP_NV 0x864F - -#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) - -#endif /* GL_NV_depth_clamp */ - -/* ------------------------- GL_NV_depth_nonlinear ------------------------- */ - -#ifndef GL_NV_depth_nonlinear -#define GL_NV_depth_nonlinear 1 - -#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C - -#define GLEW_NV_depth_nonlinear GLEW_GET_VAR(__GLEW_NV_depth_nonlinear) - -#endif /* GL_NV_depth_nonlinear */ - -/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ - -#ifndef GL_NV_depth_range_unclamped -#define GL_NV_depth_range_unclamped 1 - -#define GL_SAMPLE_COUNT_BITS_NV 0x8864 -#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 -#define GL_QUERY_RESULT_NV 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 -#define GL_SAMPLE_COUNT_NV 0x8914 - -#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) - -#endif /* GL_NV_depth_range_unclamped */ - -/* --------------------------- GL_NV_draw_buffers -------------------------- */ - -#ifndef GL_NV_draw_buffers -#define GL_NV_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_NV 0x8824 -#define GL_DRAW_BUFFER0_NV 0x8825 -#define GL_DRAW_BUFFER1_NV 0x8826 -#define GL_DRAW_BUFFER2_NV 0x8827 -#define GL_DRAW_BUFFER3_NV 0x8828 -#define GL_DRAW_BUFFER4_NV 0x8829 -#define GL_DRAW_BUFFER5_NV 0x882A -#define GL_DRAW_BUFFER6_NV 0x882B -#define GL_DRAW_BUFFER7_NV 0x882C -#define GL_DRAW_BUFFER8_NV 0x882D -#define GL_DRAW_BUFFER9_NV 0x882E -#define GL_DRAW_BUFFER10_NV 0x882F -#define GL_DRAW_BUFFER11_NV 0x8830 -#define GL_DRAW_BUFFER12_NV 0x8831 -#define GL_DRAW_BUFFER13_NV 0x8832 -#define GL_DRAW_BUFFER14_NV 0x8833 -#define GL_DRAW_BUFFER15_NV 0x8834 -#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 -#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 -#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 -#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 -#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 -#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 -#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 -#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 -#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 -#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 -#define GL_COLOR_ATTACHMENT10_NV 0x8CEA -#define GL_COLOR_ATTACHMENT11_NV 0x8CEB -#define GL_COLOR_ATTACHMENT12_NV 0x8CEC -#define GL_COLOR_ATTACHMENT13_NV 0x8CED -#define GL_COLOR_ATTACHMENT14_NV 0x8CEE -#define GL_COLOR_ATTACHMENT15_NV 0x8CEF - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersNV GLEW_GET_FUN(__glewDrawBuffersNV) - -#define GLEW_NV_draw_buffers GLEW_GET_VAR(__GLEW_NV_draw_buffers) - -#endif /* GL_NV_draw_buffers */ - -/* -------------------------- GL_NV_draw_instanced ------------------------- */ - -#ifndef GL_NV_draw_instanced -#define GL_NV_draw_instanced 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); - -#define glDrawArraysInstancedNV GLEW_GET_FUN(__glewDrawArraysInstancedNV) -#define glDrawElementsInstancedNV GLEW_GET_FUN(__glewDrawElementsInstancedNV) - -#define GLEW_NV_draw_instanced GLEW_GET_VAR(__GLEW_NV_draw_instanced) - -#endif /* GL_NV_draw_instanced */ - -/* --------------------------- GL_NV_draw_texture -------------------------- */ - -#ifndef GL_NV_draw_texture -#define GL_NV_draw_texture 1 - -typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); - -#define glDrawTextureNV GLEW_GET_FUN(__glewDrawTextureNV) - -#define GLEW_NV_draw_texture GLEW_GET_VAR(__GLEW_NV_draw_texture) - -#endif /* GL_NV_draw_texture */ - -/* ------------------------ GL_NV_draw_vulkan_image ------------------------ */ - -#ifndef GL_NV_draw_vulkan_image -#define GL_NV_draw_vulkan_image 1 - -typedef void (APIENTRY *GLVULKANPROCNV)(void); - -typedef void (GLAPIENTRY * PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); -typedef GLVULKANPROCNV (GLAPIENTRY * PFNGLGETVKPROCADDRNVPROC) (const GLchar* name); -typedef void (GLAPIENTRY * PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); -typedef void (GLAPIENTRY * PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); -typedef void (GLAPIENTRY * PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); - -#define glDrawVkImageNV GLEW_GET_FUN(__glewDrawVkImageNV) -#define glGetVkProcAddrNV GLEW_GET_FUN(__glewGetVkProcAddrNV) -#define glSignalVkFenceNV GLEW_GET_FUN(__glewSignalVkFenceNV) -#define glSignalVkSemaphoreNV GLEW_GET_FUN(__glewSignalVkSemaphoreNV) -#define glWaitVkSemaphoreNV GLEW_GET_FUN(__glewWaitVkSemaphoreNV) - -#define GLEW_NV_draw_vulkan_image GLEW_GET_VAR(__GLEW_NV_draw_vulkan_image) - -#endif /* GL_NV_draw_vulkan_image */ - -/* ---------------------------- GL_NV_evaluators --------------------------- */ - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 - -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 - -typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); -typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); -typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) -#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) -#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) -#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) -#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) -#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) -#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) -#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) -#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) - -#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) - -#endif /* GL_NV_evaluators */ - -/* --------------------- GL_NV_explicit_attrib_location -------------------- */ - -#ifndef GL_NV_explicit_attrib_location -#define GL_NV_explicit_attrib_location 1 - -#define GLEW_NV_explicit_attrib_location GLEW_GET_VAR(__GLEW_NV_explicit_attrib_location) - -#endif /* GL_NV_explicit_attrib_location */ - -/* ----------------------- GL_NV_explicit_multisample ---------------------- */ - -#ifndef GL_NV_explicit_multisample -#define GL_NV_explicit_multisample 1 - -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 - -typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); - -#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) -#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) -#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) - -#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) - -#endif /* GL_NV_explicit_multisample */ - -/* ---------------------- GL_NV_fbo_color_attachments ---------------------- */ - -#ifndef GL_NV_fbo_color_attachments -#define GL_NV_fbo_color_attachments 1 - -#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF -#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 -#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 -#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 -#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 -#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 -#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 -#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 -#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 -#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 -#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 -#define GL_COLOR_ATTACHMENT10_NV 0x8CEA -#define GL_COLOR_ATTACHMENT11_NV 0x8CEB -#define GL_COLOR_ATTACHMENT12_NV 0x8CEC -#define GL_COLOR_ATTACHMENT13_NV 0x8CED -#define GL_COLOR_ATTACHMENT14_NV 0x8CEE -#define GL_COLOR_ATTACHMENT15_NV 0x8CEF - -#define GLEW_NV_fbo_color_attachments GLEW_GET_VAR(__GLEW_NV_fbo_color_attachments) - -#endif /* GL_NV_fbo_color_attachments */ - -/* ------------------------------ GL_NV_fence ------------------------------ */ - -#ifndef GL_NV_fence -#define GL_NV_fence 1 - -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 - -typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); -typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); -typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); - -#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) -#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) -#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) -#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) -#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) -#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) -#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) - -#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) - -#endif /* GL_NV_fence */ - -/* -------------------------- GL_NV_fill_rectangle ------------------------- */ - -#ifndef GL_NV_fill_rectangle -#define GL_NV_fill_rectangle 1 - -#define GL_FILL_RECTANGLE_NV 0x933C - -#define GLEW_NV_fill_rectangle GLEW_GET_VAR(__GLEW_NV_fill_rectangle) - -#endif /* GL_NV_fill_rectangle */ - -/* --------------------------- GL_NV_float_buffer -------------------------- */ - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 - -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E - -#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) - -#endif /* GL_NV_float_buffer */ - -/* --------------------------- GL_NV_fog_distance -------------------------- */ - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 - -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C - -#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) - -#endif /* GL_NV_fog_distance */ - -/* -------------------- GL_NV_fragment_coverage_to_color ------------------- */ - -#ifndef GL_NV_fragment_coverage_to_color -#define GL_NV_fragment_coverage_to_color 1 - -#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD -#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE - -typedef void (GLAPIENTRY * PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); - -#define glFragmentCoverageColorNV GLEW_GET_FUN(__glewFragmentCoverageColorNV) - -#define GLEW_NV_fragment_coverage_to_color GLEW_GET_VAR(__GLEW_NV_fragment_coverage_to_color) - -#endif /* GL_NV_fragment_coverage_to_color */ - -/* ------------------------- GL_NV_fragment_program ------------------------ */ - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 - -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 - -typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); - -#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) -#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) -#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) -#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) -#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) -#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) - -#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) - -#endif /* GL_NV_fragment_program */ - -/* ------------------------ GL_NV_fragment_program2 ------------------------ */ - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 - -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 - -#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) - -#endif /* GL_NV_fragment_program2 */ - -/* ------------------------ GL_NV_fragment_program4 ------------------------ */ - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 - -#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) - -#endif /* GL_NV_fragment_program4 */ - -/* --------------------- GL_NV_fragment_program_option --------------------- */ - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 - -#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) - -#endif /* GL_NV_fragment_program_option */ - -/* ------------------- GL_NV_fragment_shader_barycentric ------------------- */ - -#ifndef GL_NV_fragment_shader_barycentric -#define GL_NV_fragment_shader_barycentric 1 - -#define GLEW_NV_fragment_shader_barycentric GLEW_GET_VAR(__GLEW_NV_fragment_shader_barycentric) - -#endif /* GL_NV_fragment_shader_barycentric */ - -/* -------------------- GL_NV_fragment_shader_interlock -------------------- */ - -#ifndef GL_NV_fragment_shader_interlock -#define GL_NV_fragment_shader_interlock 1 - -#define GLEW_NV_fragment_shader_interlock GLEW_GET_VAR(__GLEW_NV_fragment_shader_interlock) - -#endif /* GL_NV_fragment_shader_interlock */ - -/* ------------------------- GL_NV_framebuffer_blit ------------------------ */ - -#ifndef GL_NV_framebuffer_blit -#define GL_NV_framebuffer_blit 1 - -#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 -#define GL_READ_FRAMEBUFFER_NV 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA - -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - -#define glBlitFramebufferNV GLEW_GET_FUN(__glewBlitFramebufferNV) - -#define GLEW_NV_framebuffer_blit GLEW_GET_VAR(__GLEW_NV_framebuffer_blit) - -#endif /* GL_NV_framebuffer_blit */ - -/* -------------------- GL_NV_framebuffer_mixed_samples -------------------- */ - -#ifndef GL_NV_framebuffer_mixed_samples -#define GL_NV_framebuffer_mixed_samples 1 - -#define GL_COLOR_SAMPLES_NV 0x8E20 -#define GL_RASTER_MULTISAMPLE_EXT 0x9327 -#define GL_RASTER_SAMPLES_EXT 0x9328 -#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 -#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A -#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B -#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C -#define GL_DEPTH_SAMPLES_NV 0x932D -#define GL_STENCIL_SAMPLES_NV 0x932E -#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F -#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 -#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 -#define GL_COVERAGE_MODULATION_NV 0x9332 -#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 - -#define GLEW_NV_framebuffer_mixed_samples GLEW_GET_VAR(__GLEW_NV_framebuffer_mixed_samples) - -#endif /* GL_NV_framebuffer_mixed_samples */ - -/* --------------------- GL_NV_framebuffer_multisample --------------------- */ - -#ifndef GL_NV_framebuffer_multisample -#define GL_NV_framebuffer_multisample 1 - -#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 -#define GL_MAX_SAMPLES_NV 0x8D57 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleNV) - -#define GLEW_NV_framebuffer_multisample GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample) - -#endif /* GL_NV_framebuffer_multisample */ - -/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 - -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) - -#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) - -#endif /* GL_NV_framebuffer_multisample_coverage */ - -/* ----------------------- GL_NV_generate_mipmap_sRGB ---------------------- */ - -#ifndef GL_NV_generate_mipmap_sRGB -#define GL_NV_generate_mipmap_sRGB 1 - -#define GLEW_NV_generate_mipmap_sRGB GLEW_GET_VAR(__GLEW_NV_generate_mipmap_sRGB) - -#endif /* GL_NV_generate_mipmap_sRGB */ - -/* ------------------------ GL_NV_geometry_program4 ------------------------ */ - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 - -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 - -typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); - -#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) - -#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) - -#endif /* GL_NV_geometry_program4 */ - -/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 - -#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) - -#endif /* GL_NV_geometry_shader4 */ - -/* ------------------- GL_NV_geometry_shader_passthrough ------------------- */ - -#ifndef GL_NV_geometry_shader_passthrough -#define GL_NV_geometry_shader_passthrough 1 - -#define GLEW_NV_geometry_shader_passthrough GLEW_GET_VAR(__GLEW_NV_geometry_shader_passthrough) - -#endif /* GL_NV_geometry_shader_passthrough */ - -/* -------------------------- GL_NV_gpu_multicast -------------------------- */ - -#ifndef GL_NV_gpu_multicast -#define GL_NV_gpu_multicast 1 - -#define GL_PER_GPU_STORAGE_BIT_NV 0x0800 -#define GL_MULTICAST_GPUS_NV 0x92BA -#define GL_PER_GPU_STORAGE_NV 0x9548 -#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 -#define GL_RENDER_GPU_MASK_NV 0x9558 - -typedef void (GLAPIENTRY * PFNGLMULTICASTBARRIERNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (GLAPIENTRY * PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -typedef void (GLAPIENTRY * PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64* params); -typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64* params); -typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask); -typedef void (GLAPIENTRY * PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask); - -#define glMulticastBarrierNV GLEW_GET_FUN(__glewMulticastBarrierNV) -#define glMulticastBlitFramebufferNV GLEW_GET_FUN(__glewMulticastBlitFramebufferNV) -#define glMulticastBufferSubDataNV GLEW_GET_FUN(__glewMulticastBufferSubDataNV) -#define glMulticastCopyBufferSubDataNV GLEW_GET_FUN(__glewMulticastCopyBufferSubDataNV) -#define glMulticastCopyImageSubDataNV GLEW_GET_FUN(__glewMulticastCopyImageSubDataNV) -#define glMulticastFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewMulticastFramebufferSampleLocationsfvNV) -#define glMulticastGetQueryObjecti64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjecti64vNV) -#define glMulticastGetQueryObjectivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectivNV) -#define glMulticastGetQueryObjectui64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjectui64vNV) -#define glMulticastGetQueryObjectuivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectuivNV) -#define glMulticastWaitSyncNV GLEW_GET_FUN(__glewMulticastWaitSyncNV) -#define glRenderGpuMaskNV GLEW_GET_FUN(__glewRenderGpuMaskNV) - -#define GLEW_NV_gpu_multicast GLEW_GET_VAR(__GLEW_NV_gpu_multicast) - -#endif /* GL_NV_gpu_multicast */ - -/* --------------------------- GL_NV_gpu_program4 -------------------------- */ - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 - -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 - -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); - -#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) -#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) -#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) -#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) -#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) -#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) -#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) -#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) -#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) -#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) -#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) -#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) - -#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) - -#endif /* GL_NV_gpu_program4 */ - -/* --------------------------- GL_NV_gpu_program5 -------------------------- */ - -#ifndef GL_NV_gpu_program5 -#define GL_NV_gpu_program5 1 - -#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C -#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F - -#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5) - -#endif /* GL_NV_gpu_program5 */ - -/* -------------------- GL_NV_gpu_program5_mem_extended -------------------- */ - -#ifndef GL_NV_gpu_program5_mem_extended -#define GL_NV_gpu_program5_mem_extended 1 - -#define GLEW_NV_gpu_program5_mem_extended GLEW_GET_VAR(__GLEW_NV_gpu_program5_mem_extended) - -#endif /* GL_NV_gpu_program5_mem_extended */ - -/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */ - -#ifndef GL_NV_gpu_program_fp64 -#define GL_NV_gpu_program_fp64 1 - -#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64) - -#endif /* GL_NV_gpu_program_fp64 */ - -/* --------------------------- GL_NV_gpu_shader5 --------------------------- */ - -#ifndef GL_NV_gpu_shader5 -#define GL_NV_gpu_shader5 1 - -#define GL_INT64_NV 0x140E -#define GL_UNSIGNED_INT64_NV 0x140F -#define GL_INT8_NV 0x8FE0 -#define GL_INT8_VEC2_NV 0x8FE1 -#define GL_INT8_VEC3_NV 0x8FE2 -#define GL_INT8_VEC4_NV 0x8FE3 -#define GL_INT16_NV 0x8FE4 -#define GL_INT16_VEC2_NV 0x8FE5 -#define GL_INT16_VEC3_NV 0x8FE6 -#define GL_INT16_VEC4_NV 0x8FE7 -#define GL_INT64_VEC2_NV 0x8FE9 -#define GL_INT64_VEC3_NV 0x8FEA -#define GL_INT64_VEC4_NV 0x8FEB -#define GL_UNSIGNED_INT8_NV 0x8FEC -#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED -#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE -#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF -#define GL_UNSIGNED_INT16_NV 0x8FF0 -#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 -#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 -#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 -#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB - -typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); -typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); -typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); - -#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV) -#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV) -#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV) -#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV) -#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV) -#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV) -#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV) -#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV) -#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV) -#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV) -#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV) -#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV) -#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV) -#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV) -#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV) -#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV) -#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV) -#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV) -#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV) -#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV) -#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV) -#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV) -#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV) -#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV) -#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV) -#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV) -#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV) -#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV) -#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV) -#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV) -#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV) -#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV) -#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV) -#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV) - -#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5) - -#endif /* GL_NV_gpu_shader5 */ - -/* ---------------------------- GL_NV_half_float --------------------------- */ - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 - -#define GL_HALF_FLOAT_NV 0x140B - -typedef unsigned short GLhalf; - -typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); -typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); -typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); -typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); -typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); -typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); -typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); -typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); -typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); -typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); - -#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) -#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) -#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) -#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) -#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) -#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) -#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) -#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) -#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) -#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) -#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) -#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) -#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) -#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) -#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) -#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) -#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) -#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) -#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) -#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) -#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) -#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) -#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) -#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) -#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) -#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) -#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) -#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) -#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) -#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) -#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) -#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) -#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) -#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) -#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) -#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) -#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) -#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) -#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) -#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) -#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) -#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) -#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) -#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) -#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) -#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) - -#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) - -#endif /* GL_NV_half_float */ - -/* -------------------------- GL_NV_image_formats -------------------------- */ - -#ifndef GL_NV_image_formats -#define GL_NV_image_formats 1 - -#define GLEW_NV_image_formats GLEW_GET_VAR(__GLEW_NV_image_formats) - -#endif /* GL_NV_image_formats */ - -/* ------------------------- GL_NV_instanced_arrays ------------------------ */ - -#ifndef GL_NV_instanced_arrays -#define GL_NV_instanced_arrays 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE - -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); - -#define glVertexAttribDivisorNV GLEW_GET_FUN(__glewVertexAttribDivisorNV) - -#define GLEW_NV_instanced_arrays GLEW_GET_VAR(__GLEW_NV_instanced_arrays) - -#endif /* GL_NV_instanced_arrays */ - -/* ------------------- GL_NV_internalformat_sample_query ------------------- */ - -#ifndef GL_NV_internalformat_sample_query -#define GL_NV_internalformat_sample_query 1 - -#define GL_MULTISAMPLES_NV 0x9371 -#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 -#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 -#define GL_CONFORMANT_NV 0x9374 - -typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint* params); - -#define glGetInternalformatSampleivNV GLEW_GET_FUN(__glewGetInternalformatSampleivNV) - -#define GLEW_NV_internalformat_sample_query GLEW_GET_VAR(__GLEW_NV_internalformat_sample_query) - -#endif /* GL_NV_internalformat_sample_query */ - -/* ------------------------ GL_NV_light_max_exponent ----------------------- */ - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 - -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 - -#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) - -#endif /* GL_NV_light_max_exponent */ - -/* ------------------------ GL_NV_memory_attachment ------------------------ */ - -#ifndef GL_NV_memory_attachment -#define GL_NV_memory_attachment 1 - -#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4 -#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5 -#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6 -#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7 -#define GL_MEMORY_ATTACHABLE_NV 0x95A8 -#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9 -#define GL_DETACHED_TEXTURES_NV 0x95AA -#define GL_DETACHED_BUFFERS_NV 0x95AB -#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC -#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD - -typedef void (GLAPIENTRY * PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname); -typedef void (GLAPIENTRY * PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); -typedef void (GLAPIENTRY * PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset); - -#define glBufferAttachMemoryNV GLEW_GET_FUN(__glewBufferAttachMemoryNV) -#define glGetMemoryObjectDetachedResourcesuivNV GLEW_GET_FUN(__glewGetMemoryObjectDetachedResourcesuivNV) -#define glNamedBufferAttachMemoryNV GLEW_GET_FUN(__glewNamedBufferAttachMemoryNV) -#define glResetMemoryObjectParameterNV GLEW_GET_FUN(__glewResetMemoryObjectParameterNV) -#define glTexAttachMemoryNV GLEW_GET_FUN(__glewTexAttachMemoryNV) -#define glTextureAttachMemoryNV GLEW_GET_FUN(__glewTextureAttachMemoryNV) - -#define GLEW_NV_memory_attachment GLEW_GET_VAR(__GLEW_NV_memory_attachment) - -#endif /* GL_NV_memory_attachment */ - -/* --------------------------- GL_NV_mesh_shader --------------------------- */ - -#ifndef GL_NV_mesh_shader -#define GL_NV_mesh_shader 1 - -#define GL_MESH_SHADER_BIT_NV 0x00000040 -#define GL_TASK_SHADER_BIT_NV 0x00000080 -#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60 -#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61 -#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62 -#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63 -#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64 -#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65 -#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66 -#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67 -#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68 -#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69 -#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A -#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B -#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C -#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D -#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E -#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F -#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF -#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536 -#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537 -#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538 -#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539 -#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A -#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B -#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C -#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D -#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E -#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F -#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543 -#define GL_MAX_MESH_VIEWS_NV 0x9557 -#define GL_MESH_SHADER_NV 0x9559 -#define GL_TASK_SHADER_NV 0x955A -#define GL_MESH_VERTICES_OUT_NV 0x9579 -#define GL_MESH_PRIMITIVES_OUT_NV 0x957A -#define GL_MESH_OUTPUT_TYPE_NV 0x957B -#define GL_MESH_SUBROUTINE_NV 0x957C -#define GL_TASK_SUBROUTINE_NV 0x957D -#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E -#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F -#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F -#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0 -#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1 -#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2 -#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3 - -typedef void (GLAPIENTRY * PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect); -typedef void (GLAPIENTRY * PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); - -#define glDrawMeshTasksIndirectNV GLEW_GET_FUN(__glewDrawMeshTasksIndirectNV) -#define glDrawMeshTasksNV GLEW_GET_FUN(__glewDrawMeshTasksNV) -#define glMultiDrawMeshTasksIndirectCountNV GLEW_GET_FUN(__glewMultiDrawMeshTasksIndirectCountNV) -#define glMultiDrawMeshTasksIndirectNV GLEW_GET_FUN(__glewMultiDrawMeshTasksIndirectNV) - -#define GLEW_NV_mesh_shader GLEW_GET_VAR(__GLEW_NV_mesh_shader) - -#endif /* GL_NV_mesh_shader */ - -/* ----------------------- GL_NV_multisample_coverage ---------------------- */ - -#ifndef GL_NV_multisample_coverage -#define GL_NV_multisample_coverage 1 - -#define GL_COLOR_SAMPLES_NV 0x8E20 - -#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage) - -#endif /* GL_NV_multisample_coverage */ - -/* --------------------- GL_NV_multisample_filter_hint --------------------- */ - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 - -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 - -#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) - -#endif /* GL_NV_multisample_filter_hint */ - -/* ----------------------- GL_NV_non_square_matrices ----------------------- */ - -#ifndef GL_NV_non_square_matrices -#define GL_NV_non_square_matrices 1 - -#define GL_FLOAT_MAT2x3_NV 0x8B65 -#define GL_FLOAT_MAT2x4_NV 0x8B66 -#define GL_FLOAT_MAT3x2_NV 0x8B67 -#define GL_FLOAT_MAT3x4_NV 0x8B68 -#define GL_FLOAT_MAT4x2_NV 0x8B69 -#define GL_FLOAT_MAT4x3_NV 0x8B6A - -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - -#define glUniformMatrix2x3fvNV GLEW_GET_FUN(__glewUniformMatrix2x3fvNV) -#define glUniformMatrix2x4fvNV GLEW_GET_FUN(__glewUniformMatrix2x4fvNV) -#define glUniformMatrix3x2fvNV GLEW_GET_FUN(__glewUniformMatrix3x2fvNV) -#define glUniformMatrix3x4fvNV GLEW_GET_FUN(__glewUniformMatrix3x4fvNV) -#define glUniformMatrix4x2fvNV GLEW_GET_FUN(__glewUniformMatrix4x2fvNV) -#define glUniformMatrix4x3fvNV GLEW_GET_FUN(__glewUniformMatrix4x3fvNV) - -#define GLEW_NV_non_square_matrices GLEW_GET_VAR(__GLEW_NV_non_square_matrices) - -#endif /* GL_NV_non_square_matrices */ - -/* ------------------------- GL_NV_occlusion_query ------------------------- */ - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 - -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 - -typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); - -#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) -#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) -#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) -#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) -#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) -#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) -#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) - -#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) - -#endif /* GL_NV_occlusion_query */ - -/* -------------------------- GL_NV_pack_subimage -------------------------- */ - -#ifndef GL_NV_pack_subimage -#define GL_NV_pack_subimage 1 - -#define GL_PACK_ROW_LENGTH_NV 0x0D02 -#define GL_PACK_SKIP_ROWS_NV 0x0D03 -#define GL_PACK_SKIP_PIXELS_NV 0x0D04 - -#define GLEW_NV_pack_subimage GLEW_GET_VAR(__GLEW_NV_pack_subimage) - -#endif /* GL_NV_pack_subimage */ - -/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA - -#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) - -#endif /* GL_NV_packed_depth_stencil */ - -/* --------------------------- GL_NV_packed_float -------------------------- */ - -#ifndef GL_NV_packed_float -#define GL_NV_packed_float 1 - -#define GL_R11F_G11F_B10F_NV 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B - -#define GLEW_NV_packed_float GLEW_GET_VAR(__GLEW_NV_packed_float) - -#endif /* GL_NV_packed_float */ - -/* ----------------------- GL_NV_packed_float_linear ----------------------- */ - -#ifndef GL_NV_packed_float_linear -#define GL_NV_packed_float_linear 1 - -#define GL_R11F_G11F_B10F_NV 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B - -#define GLEW_NV_packed_float_linear GLEW_GET_VAR(__GLEW_NV_packed_float_linear) - -#endif /* GL_NV_packed_float_linear */ - -/* --------------------- GL_NV_parameter_buffer_object --------------------- */ - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 - -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 - -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); - -#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) -#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) -#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) - -#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) - -#endif /* GL_NV_parameter_buffer_object */ - -/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */ - -#ifndef GL_NV_parameter_buffer_object2 -#define GL_NV_parameter_buffer_object2 1 - -#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2) - -#endif /* GL_NV_parameter_buffer_object2 */ - -/* -------------------------- GL_NV_path_rendering ------------------------- */ - -#ifndef GL_NV_path_rendering -#define GL_NV_path_rendering 1 - -#define GL_CLOSE_PATH_NV 0x00 -#define GL_BOLD_BIT_NV 0x01 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_PATH_STROKE_BOUND_NV 0x9086 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_FRAGMENT_INPUT_NV 0x936D -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 - -typedef void (GLAPIENTRY * PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); -typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (GLAPIENTRY * PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); -typedef GLuint (GLAPIENTRY * PFNGLGENPATHSNVPROC) (GLsizei range); -typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat* value); -typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint* value); -typedef void (GLAPIENTRY * PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte* commands); -typedef void (GLAPIENTRY * PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat* coords); -typedef void (GLAPIENTRY * PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat* dashArray); -typedef GLfloat (GLAPIENTRY * PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); -typedef void (GLAPIENTRY * PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat* metrics); -typedef void (GLAPIENTRY * PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat* value); -typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint* value); -typedef void (GLAPIENTRY * PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat* value); -typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint* value); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -typedef GLboolean (GLAPIENTRY * PFNGLISPATHNVPROC) (GLuint path); -typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); -typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat* coeffs); -typedef void (GLAPIENTRY * PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); -typedef void (GLAPIENTRY * PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (GLAPIENTRY * PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum zfunc); -typedef void (GLAPIENTRY * PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat* dashArray); -typedef void (GLAPIENTRY * PFNGLPATHFOGGENNVPROC) (GLenum genMode); -typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -typedef void (GLAPIENTRY * PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (GLAPIENTRY * PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void*charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (GLAPIENTRY * PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); -typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); -typedef void (GLAPIENTRY * PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); -typedef void (GLAPIENTRY * PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); -typedef void (GLAPIENTRY * PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); -typedef void (GLAPIENTRY * PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); -typedef void (GLAPIENTRY * PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (GLAPIENTRY * PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat* coeffs); -typedef GLboolean (GLAPIENTRY * PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat* x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -typedef void (GLAPIENTRY * PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat* coeffs); -typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -typedef void (GLAPIENTRY * PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat* transformValues); -typedef void (GLAPIENTRY * PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint paths[], const GLfloat weights[]); - -#define glCopyPathNV GLEW_GET_FUN(__glewCopyPathNV) -#define glCoverFillPathInstancedNV GLEW_GET_FUN(__glewCoverFillPathInstancedNV) -#define glCoverFillPathNV GLEW_GET_FUN(__glewCoverFillPathNV) -#define glCoverStrokePathInstancedNV GLEW_GET_FUN(__glewCoverStrokePathInstancedNV) -#define glCoverStrokePathNV GLEW_GET_FUN(__glewCoverStrokePathNV) -#define glDeletePathsNV GLEW_GET_FUN(__glewDeletePathsNV) -#define glGenPathsNV GLEW_GET_FUN(__glewGenPathsNV) -#define glGetPathColorGenfvNV GLEW_GET_FUN(__glewGetPathColorGenfvNV) -#define glGetPathColorGenivNV GLEW_GET_FUN(__glewGetPathColorGenivNV) -#define glGetPathCommandsNV GLEW_GET_FUN(__glewGetPathCommandsNV) -#define glGetPathCoordsNV GLEW_GET_FUN(__glewGetPathCoordsNV) -#define glGetPathDashArrayNV GLEW_GET_FUN(__glewGetPathDashArrayNV) -#define glGetPathLengthNV GLEW_GET_FUN(__glewGetPathLengthNV) -#define glGetPathMetricRangeNV GLEW_GET_FUN(__glewGetPathMetricRangeNV) -#define glGetPathMetricsNV GLEW_GET_FUN(__glewGetPathMetricsNV) -#define glGetPathParameterfvNV GLEW_GET_FUN(__glewGetPathParameterfvNV) -#define glGetPathParameterivNV GLEW_GET_FUN(__glewGetPathParameterivNV) -#define glGetPathSpacingNV GLEW_GET_FUN(__glewGetPathSpacingNV) -#define glGetPathTexGenfvNV GLEW_GET_FUN(__glewGetPathTexGenfvNV) -#define glGetPathTexGenivNV GLEW_GET_FUN(__glewGetPathTexGenivNV) -#define glGetProgramResourcefvNV GLEW_GET_FUN(__glewGetProgramResourcefvNV) -#define glInterpolatePathsNV GLEW_GET_FUN(__glewInterpolatePathsNV) -#define glIsPathNV GLEW_GET_FUN(__glewIsPathNV) -#define glIsPointInFillPathNV GLEW_GET_FUN(__glewIsPointInFillPathNV) -#define glIsPointInStrokePathNV GLEW_GET_FUN(__glewIsPointInStrokePathNV) -#define glMatrixLoad3x2fNV GLEW_GET_FUN(__glewMatrixLoad3x2fNV) -#define glMatrixLoad3x3fNV GLEW_GET_FUN(__glewMatrixLoad3x3fNV) -#define glMatrixLoadTranspose3x3fNV GLEW_GET_FUN(__glewMatrixLoadTranspose3x3fNV) -#define glMatrixMult3x2fNV GLEW_GET_FUN(__glewMatrixMult3x2fNV) -#define glMatrixMult3x3fNV GLEW_GET_FUN(__glewMatrixMult3x3fNV) -#define glMatrixMultTranspose3x3fNV GLEW_GET_FUN(__glewMatrixMultTranspose3x3fNV) -#define glPathColorGenNV GLEW_GET_FUN(__glewPathColorGenNV) -#define glPathCommandsNV GLEW_GET_FUN(__glewPathCommandsNV) -#define glPathCoordsNV GLEW_GET_FUN(__glewPathCoordsNV) -#define glPathCoverDepthFuncNV GLEW_GET_FUN(__glewPathCoverDepthFuncNV) -#define glPathDashArrayNV GLEW_GET_FUN(__glewPathDashArrayNV) -#define glPathFogGenNV GLEW_GET_FUN(__glewPathFogGenNV) -#define glPathGlyphIndexArrayNV GLEW_GET_FUN(__glewPathGlyphIndexArrayNV) -#define glPathGlyphIndexRangeNV GLEW_GET_FUN(__glewPathGlyphIndexRangeNV) -#define glPathGlyphRangeNV GLEW_GET_FUN(__glewPathGlyphRangeNV) -#define glPathGlyphsNV GLEW_GET_FUN(__glewPathGlyphsNV) -#define glPathMemoryGlyphIndexArrayNV GLEW_GET_FUN(__glewPathMemoryGlyphIndexArrayNV) -#define glPathParameterfNV GLEW_GET_FUN(__glewPathParameterfNV) -#define glPathParameterfvNV GLEW_GET_FUN(__glewPathParameterfvNV) -#define glPathParameteriNV GLEW_GET_FUN(__glewPathParameteriNV) -#define glPathParameterivNV GLEW_GET_FUN(__glewPathParameterivNV) -#define glPathStencilDepthOffsetNV GLEW_GET_FUN(__glewPathStencilDepthOffsetNV) -#define glPathStencilFuncNV GLEW_GET_FUN(__glewPathStencilFuncNV) -#define glPathStringNV GLEW_GET_FUN(__glewPathStringNV) -#define glPathSubCommandsNV GLEW_GET_FUN(__glewPathSubCommandsNV) -#define glPathSubCoordsNV GLEW_GET_FUN(__glewPathSubCoordsNV) -#define glPathTexGenNV GLEW_GET_FUN(__glewPathTexGenNV) -#define glPointAlongPathNV GLEW_GET_FUN(__glewPointAlongPathNV) -#define glProgramPathFragmentInputGenNV GLEW_GET_FUN(__glewProgramPathFragmentInputGenNV) -#define glStencilFillPathInstancedNV GLEW_GET_FUN(__glewStencilFillPathInstancedNV) -#define glStencilFillPathNV GLEW_GET_FUN(__glewStencilFillPathNV) -#define glStencilStrokePathInstancedNV GLEW_GET_FUN(__glewStencilStrokePathInstancedNV) -#define glStencilStrokePathNV GLEW_GET_FUN(__glewStencilStrokePathNV) -#define glStencilThenCoverFillPathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverFillPathInstancedNV) -#define glStencilThenCoverFillPathNV GLEW_GET_FUN(__glewStencilThenCoverFillPathNV) -#define glStencilThenCoverStrokePathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathInstancedNV) -#define glStencilThenCoverStrokePathNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathNV) -#define glTransformPathNV GLEW_GET_FUN(__glewTransformPathNV) -#define glWeightPathsNV GLEW_GET_FUN(__glewWeightPathsNV) - -#define GLEW_NV_path_rendering GLEW_GET_VAR(__GLEW_NV_path_rendering) - -#endif /* GL_NV_path_rendering */ - -/* -------------------- GL_NV_path_rendering_shared_edge ------------------- */ - -#ifndef GL_NV_path_rendering_shared_edge -#define GL_NV_path_rendering_shared_edge 1 - -#define GL_SHARED_EDGE_NV 0xC0 - -#define GLEW_NV_path_rendering_shared_edge GLEW_GET_VAR(__GLEW_NV_path_rendering_shared_edge) - -#endif /* GL_NV_path_rendering_shared_edge */ - -/* ----------------------- GL_NV_pixel_buffer_object ----------------------- */ - -#ifndef GL_NV_pixel_buffer_object -#define GL_NV_pixel_buffer_object 1 - -#define GL_PIXEL_PACK_BUFFER_NV 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF - -#define GLEW_NV_pixel_buffer_object GLEW_GET_VAR(__GLEW_NV_pixel_buffer_object) - -#endif /* GL_NV_pixel_buffer_object */ - -/* ------------------------- GL_NV_pixel_data_range ------------------------ */ - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 - -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D - -typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void *pointer); - -#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) -#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) - -#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) - -#endif /* GL_NV_pixel_data_range */ - -/* ------------------------- GL_NV_platform_binary ------------------------- */ - -#ifndef GL_NV_platform_binary -#define GL_NV_platform_binary 1 - -#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B - -#define GLEW_NV_platform_binary GLEW_GET_VAR(__GLEW_NV_platform_binary) - -#endif /* GL_NV_platform_binary */ - -/* --------------------------- GL_NV_point_sprite -------------------------- */ - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 - -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); - -#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) -#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) - -#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) - -#endif /* GL_NV_point_sprite */ - -/* --------------------------- GL_NV_polygon_mode -------------------------- */ - -#ifndef GL_NV_polygon_mode -#define GL_NV_polygon_mode 1 - -#define GL_POLYGON_MODE_NV 0x0B40 -#define GL_POINT_NV 0x1B00 -#define GL_LINE_NV 0x1B01 -#define GL_FILL_NV 0x1B02 -#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 -#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 - -typedef void (GLAPIENTRY * PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode); - -#define glPolygonModeNV GLEW_GET_FUN(__glewPolygonModeNV) - -#define GLEW_NV_polygon_mode GLEW_GET_VAR(__GLEW_NV_polygon_mode) - -#endif /* GL_NV_polygon_mode */ - -/* -------------------------- GL_NV_present_video -------------------------- */ - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 - -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B - -typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); - -#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) -#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) -#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) -#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) -#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) -#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) - -#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) - -#endif /* GL_NV_present_video */ - -/* ------------------------ GL_NV_primitive_restart ------------------------ */ - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 - -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 - -typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); - -#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) -#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) - -#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) - -#endif /* GL_NV_primitive_restart */ - -/* ------------------------ GL_NV_query_resource_tag ----------------------- */ - -#ifndef GL_NV_query_resource_tag -#define GL_NV_query_resource_tag 1 - -#define GLEW_NV_query_resource_tag GLEW_GET_VAR(__GLEW_NV_query_resource_tag) - -#endif /* GL_NV_query_resource_tag */ - -/* --------------------------- GL_NV_read_buffer --------------------------- */ - -#ifndef GL_NV_read_buffer -#define GL_NV_read_buffer 1 - -#define GL_READ_BUFFER_NV 0x0C02 - -typedef void (GLAPIENTRY * PFNGLREADBUFFERNVPROC) (GLenum mode); - -#define glReadBufferNV GLEW_GET_FUN(__glewReadBufferNV) - -#define GLEW_NV_read_buffer GLEW_GET_VAR(__GLEW_NV_read_buffer) - -#endif /* GL_NV_read_buffer */ - -/* ------------------------ GL_NV_read_buffer_front ------------------------ */ - -#ifndef GL_NV_read_buffer_front -#define GL_NV_read_buffer_front 1 - -#define GL_READ_BUFFER_NV 0x0C02 - -#define GLEW_NV_read_buffer_front GLEW_GET_VAR(__GLEW_NV_read_buffer_front) - -#endif /* GL_NV_read_buffer_front */ - -/* ---------------------------- GL_NV_read_depth --------------------------- */ - -#ifndef GL_NV_read_depth -#define GL_NV_read_depth 1 - -#define GLEW_NV_read_depth GLEW_GET_VAR(__GLEW_NV_read_depth) - -#endif /* GL_NV_read_depth */ - -/* ------------------------ GL_NV_read_depth_stencil ----------------------- */ - -#ifndef GL_NV_read_depth_stencil -#define GL_NV_read_depth_stencil 1 - -#define GLEW_NV_read_depth_stencil GLEW_GET_VAR(__GLEW_NV_read_depth_stencil) - -#endif /* GL_NV_read_depth_stencil */ - -/* --------------------------- GL_NV_read_stencil -------------------------- */ - -#ifndef GL_NV_read_stencil -#define GL_NV_read_stencil 1 - -#define GLEW_NV_read_stencil GLEW_GET_VAR(__GLEW_NV_read_stencil) - -#endif /* GL_NV_read_stencil */ - -/* ------------------------ GL_NV_register_combiners ----------------------- */ - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 - -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 - -typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); - -#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) -#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) -#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) -#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) -#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) -#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) -#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) -#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) -#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) -#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) -#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) -#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) -#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) - -#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) - -#endif /* GL_NV_register_combiners */ - -/* ----------------------- GL_NV_register_combiners2 ----------------------- */ - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 - -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 - -typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); - -#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) -#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) - -#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) - -#endif /* GL_NV_register_combiners2 */ - -/* ------------------- GL_NV_representative_fragment_test ------------------ */ - -#ifndef GL_NV_representative_fragment_test -#define GL_NV_representative_fragment_test 1 - -#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F - -#define GLEW_NV_representative_fragment_test GLEW_GET_VAR(__GLEW_NV_representative_fragment_test) - -#endif /* GL_NV_representative_fragment_test */ - -/* ------------------ GL_NV_robustness_video_memory_purge ------------------ */ - -#ifndef GL_NV_robustness_video_memory_purge -#define GL_NV_robustness_video_memory_purge 1 - -#define GL_PURGED_CONTEXT_RESET_NV 0x92BB - -#define GLEW_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_NV_robustness_video_memory_purge) - -#endif /* GL_NV_robustness_video_memory_purge */ - -/* --------------------------- GL_NV_sRGB_formats -------------------------- */ - -#ifndef GL_NV_sRGB_formats -#define GL_NV_sRGB_formats 1 - -#define GL_ETC1_SRGB8_NV 0x88EE -#define GL_SRGB8_NV 0x8C41 -#define GL_SLUMINANCE_ALPHA_NV 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 -#define GL_SLUMINANCE_NV 0x8C46 -#define GL_SLUMINANCE8_NV 0x8C47 -#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F - -#define GLEW_NV_sRGB_formats GLEW_GET_VAR(__GLEW_NV_sRGB_formats) - -#endif /* GL_NV_sRGB_formats */ - -/* ------------------------- GL_NV_sample_locations ------------------------ */ - -#ifndef GL_NV_sample_locations -#define GL_NV_sample_locations 1 - -#define GL_SAMPLE_LOCATION_NV 0x8E50 -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLRESOLVEDEPTHVALUESNVPROC) (void); - -#define glFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewFramebufferSampleLocationsfvNV) -#define glNamedFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvNV) -#define glResolveDepthValuesNV GLEW_GET_FUN(__glewResolveDepthValuesNV) - -#define GLEW_NV_sample_locations GLEW_GET_VAR(__GLEW_NV_sample_locations) - -#endif /* GL_NV_sample_locations */ - -/* ------------------ GL_NV_sample_mask_override_coverage ------------------ */ - -#ifndef GL_NV_sample_mask_override_coverage -#define GL_NV_sample_mask_override_coverage 1 - -#define GLEW_NV_sample_mask_override_coverage GLEW_GET_VAR(__GLEW_NV_sample_mask_override_coverage) - -#endif /* GL_NV_sample_mask_override_coverage */ - -/* ------------------------ GL_NV_scissor_exclusive ------------------------ */ - -#ifndef GL_NV_scissor_exclusive -#define GL_NV_scissor_exclusive 1 - -#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555 -#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556 - -typedef void (GLAPIENTRY * PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint* v); -typedef void (GLAPIENTRY * PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height); - -#define glScissorExclusiveArrayvNV GLEW_GET_FUN(__glewScissorExclusiveArrayvNV) -#define glScissorExclusiveNV GLEW_GET_FUN(__glewScissorExclusiveNV) - -#define GLEW_NV_scissor_exclusive GLEW_GET_VAR(__GLEW_NV_scissor_exclusive) - -#endif /* GL_NV_scissor_exclusive */ - -/* ---------------------- GL_NV_shader_atomic_counters --------------------- */ - -#ifndef GL_NV_shader_atomic_counters -#define GL_NV_shader_atomic_counters 1 - -#define GLEW_NV_shader_atomic_counters GLEW_GET_VAR(__GLEW_NV_shader_atomic_counters) - -#endif /* GL_NV_shader_atomic_counters */ - -/* ----------------------- GL_NV_shader_atomic_float ----------------------- */ - -#ifndef GL_NV_shader_atomic_float -#define GL_NV_shader_atomic_float 1 - -#define GLEW_NV_shader_atomic_float GLEW_GET_VAR(__GLEW_NV_shader_atomic_float) - -#endif /* GL_NV_shader_atomic_float */ - -/* ---------------------- GL_NV_shader_atomic_float64 ---------------------- */ - -#ifndef GL_NV_shader_atomic_float64 -#define GL_NV_shader_atomic_float64 1 - -#define GLEW_NV_shader_atomic_float64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_float64) - -#endif /* GL_NV_shader_atomic_float64 */ - -/* -------------------- GL_NV_shader_atomic_fp16_vector -------------------- */ - -#ifndef GL_NV_shader_atomic_fp16_vector -#define GL_NV_shader_atomic_fp16_vector 1 - -#define GLEW_NV_shader_atomic_fp16_vector GLEW_GET_VAR(__GLEW_NV_shader_atomic_fp16_vector) - -#endif /* GL_NV_shader_atomic_fp16_vector */ - -/* ----------------------- GL_NV_shader_atomic_int64 ----------------------- */ - -#ifndef GL_NV_shader_atomic_int64 -#define GL_NV_shader_atomic_int64 1 - -#define GLEW_NV_shader_atomic_int64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_int64) - -#endif /* GL_NV_shader_atomic_int64 */ - -/* ------------------------ GL_NV_shader_buffer_load ----------------------- */ - -#ifndef GL_NV_shader_buffer_load -#define GL_NV_shader_buffer_load 1 - -#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D -#define GL_GPU_ADDRESS_NV 0x8F34 -#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 - -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params); -typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); -typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); -typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); -typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); - -#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV) -#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV) -#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV) -#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV) -#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV) -#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV) -#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV) -#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV) -#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV) -#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV) -#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV) -#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV) -#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV) - -#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load) - -#endif /* GL_NV_shader_buffer_load */ - -/* ---------------- GL_NV_shader_noperspective_interpolation --------------- */ - -#ifndef GL_NV_shader_noperspective_interpolation -#define GL_NV_shader_noperspective_interpolation 1 - -#define GLEW_NV_shader_noperspective_interpolation GLEW_GET_VAR(__GLEW_NV_shader_noperspective_interpolation) - -#endif /* GL_NV_shader_noperspective_interpolation */ - -/* ------------------- GL_NV_shader_storage_buffer_object ------------------ */ - -#ifndef GL_NV_shader_storage_buffer_object -#define GL_NV_shader_storage_buffer_object 1 - -#define GLEW_NV_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_NV_shader_storage_buffer_object) - -#endif /* GL_NV_shader_storage_buffer_object */ - -/* ------------------- GL_NV_shader_subgroup_partitioned ------------------- */ - -#ifndef GL_NV_shader_subgroup_partitioned -#define GL_NV_shader_subgroup_partitioned 1 - -#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100 - -#define GLEW_NV_shader_subgroup_partitioned GLEW_GET_VAR(__GLEW_NV_shader_subgroup_partitioned) - -#endif /* GL_NV_shader_subgroup_partitioned */ - -/* --------------------- GL_NV_shader_texture_footprint -------------------- */ - -#ifndef GL_NV_shader_texture_footprint -#define GL_NV_shader_texture_footprint 1 - -#define GLEW_NV_shader_texture_footprint GLEW_GET_VAR(__GLEW_NV_shader_texture_footprint) - -#endif /* GL_NV_shader_texture_footprint */ - -/* ----------------------- GL_NV_shader_thread_group ----------------------- */ - -#ifndef GL_NV_shader_thread_group -#define GL_NV_shader_thread_group 1 - -#define GL_WARP_SIZE_NV 0x9339 -#define GL_WARPS_PER_SM_NV 0x933A -#define GL_SM_COUNT_NV 0x933B - -#define GLEW_NV_shader_thread_group GLEW_GET_VAR(__GLEW_NV_shader_thread_group) - -#endif /* GL_NV_shader_thread_group */ - -/* ---------------------- GL_NV_shader_thread_shuffle ---------------------- */ - -#ifndef GL_NV_shader_thread_shuffle -#define GL_NV_shader_thread_shuffle 1 - -#define GLEW_NV_shader_thread_shuffle GLEW_GET_VAR(__GLEW_NV_shader_thread_shuffle) - -#endif /* GL_NV_shader_thread_shuffle */ - -/* ------------------------ GL_NV_shading_rate_image ----------------------- */ - -#ifndef GL_NV_shading_rate_image -#define GL_NV_shading_rate_image 1 - -#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B -#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C -#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D -#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E -#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F -#define GL_SHADING_RATE_IMAGE_NV 0x9563 -#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564 -#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565 -#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566 -#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567 -#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568 -#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569 -#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A -#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B -#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C -#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D -#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E -#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F -#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE -#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF -#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0 - -typedef void (GLAPIENTRY * PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture); -typedef void (GLAPIENTRY * PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum* rate); -typedef void (GLAPIENTRY * PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint* location); -typedef void (GLAPIENTRY * PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLenum order); -typedef void (GLAPIENTRY * PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum* rates); -typedef void (GLAPIENTRY * PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint* locations); - -#define glBindShadingRateImageNV GLEW_GET_FUN(__glewBindShadingRateImageNV) -#define glGetShadingRateImagePaletteNV GLEW_GET_FUN(__glewGetShadingRateImagePaletteNV) -#define glGetShadingRateSampleLocationivNV GLEW_GET_FUN(__glewGetShadingRateSampleLocationivNV) -#define glShadingRateImageBarrierNV GLEW_GET_FUN(__glewShadingRateImageBarrierNV) -#define glShadingRateImagePaletteNV GLEW_GET_FUN(__glewShadingRateImagePaletteNV) -#define glShadingRateSampleOrderCustomNV GLEW_GET_FUN(__glewShadingRateSampleOrderCustomNV) - -#define GLEW_NV_shading_rate_image GLEW_GET_VAR(__GLEW_NV_shading_rate_image) - -#endif /* GL_NV_shading_rate_image */ - -/* ---------------------- GL_NV_shadow_samplers_array ---------------------- */ - -#ifndef GL_NV_shadow_samplers_array -#define GL_NV_shadow_samplers_array 1 - -#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 - -#define GLEW_NV_shadow_samplers_array GLEW_GET_VAR(__GLEW_NV_shadow_samplers_array) - -#endif /* GL_NV_shadow_samplers_array */ - -/* ----------------------- GL_NV_shadow_samplers_cube ---------------------- */ - -#ifndef GL_NV_shadow_samplers_cube -#define GL_NV_shadow_samplers_cube 1 - -#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 - -#define GLEW_NV_shadow_samplers_cube GLEW_GET_VAR(__GLEW_NV_shadow_samplers_cube) - -#endif /* GL_NV_shadow_samplers_cube */ - -/* ---------------------- GL_NV_stereo_view_rendering ---------------------- */ - -#ifndef GL_NV_stereo_view_rendering -#define GL_NV_stereo_view_rendering 1 - -#define GLEW_NV_stereo_view_rendering GLEW_GET_VAR(__GLEW_NV_stereo_view_rendering) - -#endif /* GL_NV_stereo_view_rendering */ - -/* ---------------------- GL_NV_tessellation_program5 ---------------------- */ - -#ifndef GL_NV_tessellation_program5 -#define GL_NV_tessellation_program5 1 - -#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 -#define GL_TESS_CONTROL_PROGRAM_NV 0x891E -#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F -#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 -#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 - -#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5) - -#endif /* GL_NV_tessellation_program5 */ - -/* -------------------------- GL_NV_texgen_emboss -------------------------- */ - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 - -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F - -#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) - -#endif /* GL_NV_texgen_emboss */ - -/* ------------------------ GL_NV_texgen_reflection ------------------------ */ - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 - -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 - -#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) - -#endif /* GL_NV_texgen_reflection */ - -/* -------------------------- GL_NV_texture_array -------------------------- */ - -#ifndef GL_NV_texture_array -#define GL_NV_texture_array 1 - -#define GL_UNPACK_SKIP_IMAGES_NV 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_NV 0x806E -#define GL_MAX_ARRAY_TEXTURE_LAYERS_NV 0x88FF -#define GL_TEXTURE_2D_ARRAY_NV 0x8C1A -#define GL_TEXTURE_BINDING_2D_ARRAY_NV 0x8C1D -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_NV 0x8CD4 -#define GL_SAMPLER_2D_ARRAY_NV 0x8DC1 - -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERNVPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - -#define glCompressedTexImage3DNV GLEW_GET_FUN(__glewCompressedTexImage3DNV) -#define glCompressedTexSubImage3DNV GLEW_GET_FUN(__glewCompressedTexSubImage3DNV) -#define glCopyTexSubImage3DNV GLEW_GET_FUN(__glewCopyTexSubImage3DNV) -#define glFramebufferTextureLayerNV GLEW_GET_FUN(__glewFramebufferTextureLayerNV) -#define glTexImage3DNV GLEW_GET_FUN(__glewTexImage3DNV) -#define glTexSubImage3DNV GLEW_GET_FUN(__glewTexSubImage3DNV) - -#define GLEW_NV_texture_array GLEW_GET_VAR(__GLEW_NV_texture_array) - -#endif /* GL_NV_texture_array */ - -/* ------------------------- GL_NV_texture_barrier ------------------------- */ - -#ifndef GL_NV_texture_barrier -#define GL_NV_texture_barrier 1 - -typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void); - -#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV) - -#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier) - -#endif /* GL_NV_texture_barrier */ - -/* ----------------------- GL_NV_texture_border_clamp ---------------------- */ - -#ifndef GL_NV_texture_border_clamp -#define GL_NV_texture_border_clamp 1 - -#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 -#define GL_CLAMP_TO_BORDER_NV 0x812D - -#define GLEW_NV_texture_border_clamp GLEW_GET_VAR(__GLEW_NV_texture_border_clamp) - -#endif /* GL_NV_texture_border_clamp */ - -/* --------------------- GL_NV_texture_compression_latc -------------------- */ - -#ifndef GL_NV_texture_compression_latc -#define GL_NV_texture_compression_latc 1 - -#define GL_COMPRESSED_LUMINANCE_LATC1_NV 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_NV 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_NV 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV 0x8C73 - -#define GLEW_NV_texture_compression_latc GLEW_GET_VAR(__GLEW_NV_texture_compression_latc) - -#endif /* GL_NV_texture_compression_latc */ - -/* --------------------- GL_NV_texture_compression_s3tc -------------------- */ - -#ifndef GL_NV_texture_compression_s3tc -#define GL_NV_texture_compression_s3tc 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_NV 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_NV 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_NV 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_NV 0x83F3 - -#define GLEW_NV_texture_compression_s3tc GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc) - -#endif /* GL_NV_texture_compression_s3tc */ - -/* ----------------- GL_NV_texture_compression_s3tc_update ----------------- */ - -#ifndef GL_NV_texture_compression_s3tc_update -#define GL_NV_texture_compression_s3tc_update 1 - -#define GLEW_NV_texture_compression_s3tc_update GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc_update) - -#endif /* GL_NV_texture_compression_s3tc_update */ - -/* --------------------- GL_NV_texture_compression_vtc --------------------- */ - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 - -#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) - -#endif /* GL_NV_texture_compression_vtc */ - -/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 - -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B - -#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) - -#endif /* GL_NV_texture_env_combine4 */ - -/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 - -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F - -#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) - -#endif /* GL_NV_texture_expand_normal */ - -/* ----------------------- GL_NV_texture_multisample ----------------------- */ - -#ifndef GL_NV_texture_multisample -#define GL_NV_texture_multisample 1 - -#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 -#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 - -typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); - -#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV) -#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV) -#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV) -#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV) -#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV) -#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV) - -#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample) - -#endif /* GL_NV_texture_multisample */ - -/* ---------------------- GL_NV_texture_npot_2D_mipmap --------------------- */ - -#ifndef GL_NV_texture_npot_2D_mipmap -#define GL_NV_texture_npot_2D_mipmap 1 - -#define GLEW_NV_texture_npot_2D_mipmap GLEW_GET_VAR(__GLEW_NV_texture_npot_2D_mipmap) - -#endif /* GL_NV_texture_npot_2D_mipmap */ - -/* ------------------------ GL_NV_texture_rectangle ------------------------ */ - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 - -#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) - -#endif /* GL_NV_texture_rectangle */ - -/* ------------------- GL_NV_texture_rectangle_compressed ------------------ */ - -#ifndef GL_NV_texture_rectangle_compressed -#define GL_NV_texture_rectangle_compressed 1 - -#define GLEW_NV_texture_rectangle_compressed GLEW_GET_VAR(__GLEW_NV_texture_rectangle_compressed) - -#endif /* GL_NV_texture_rectangle_compressed */ - -/* -------------------------- GL_NV_texture_shader ------------------------- */ - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 - -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F - -#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) - -#endif /* GL_NV_texture_shader */ - -/* ------------------------- GL_NV_texture_shader2 ------------------------- */ - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 - -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D - -#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) - -#endif /* GL_NV_texture_shader2 */ - -/* ------------------------- GL_NV_texture_shader3 ------------------------- */ - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 - -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 - -#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) - -#endif /* GL_NV_texture_shader3 */ - -/* ------------------------ GL_NV_transform_feedback ----------------------- */ - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 - -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F - -typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); - -#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) -#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) -#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) -#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) -#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) -#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) -#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) -#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) -#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) -#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) -#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) - -#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) - -#endif /* GL_NV_transform_feedback */ - -/* ----------------------- GL_NV_transform_feedback2 ----------------------- */ - -#ifndef GL_NV_transform_feedback2 -#define GL_NV_transform_feedback2 1 - -#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 - -typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); -typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids); -typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); - -#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV) -#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV) -#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV) -#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV) -#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV) -#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV) -#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV) - -#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2) - -#endif /* GL_NV_transform_feedback2 */ - -/* ------------------ GL_NV_uniform_buffer_unified_memory ------------------ */ - -#ifndef GL_NV_uniform_buffer_unified_memory -#define GL_NV_uniform_buffer_unified_memory 1 - -#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E -#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F -#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 - -#define GLEW_NV_uniform_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_uniform_buffer_unified_memory) - -#endif /* GL_NV_uniform_buffer_unified_memory */ - -/* -------------------------- GL_NV_vdpau_interop -------------------------- */ - -#ifndef GL_NV_vdpau_interop -#define GL_NV_vdpau_interop 1 - -#define GL_SURFACE_STATE_NV 0x86EB -#define GL_SURFACE_REGISTERED_NV 0x86FD -#define GL_SURFACE_MAPPED_NV 0x8700 -#define GL_WRITE_DISCARD_NV 0x88BE - -typedef GLintptr GLvdpauSurfaceNV; - -typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void); -typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); -typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const void*getProcAddress); -typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces); -typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); -typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces); -typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); - -#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV) -#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV) -#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV) -#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV) -#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV) -#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV) -#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV) -#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV) -#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV) -#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV) - -#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop) - -#endif /* GL_NV_vdpau_interop */ - -/* -------------------------- GL_NV_vdpau_interop2 ------------------------- */ - -#ifndef GL_NV_vdpau_interop2 -#define GL_NV_vdpau_interop2 1 - -typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure); - -#define glVDPAURegisterVideoSurfaceWithPictureStructureNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceWithPictureStructureNV) - -#define GLEW_NV_vdpau_interop2 GLEW_GET_VAR(__GLEW_NV_vdpau_interop2) - -#endif /* GL_NV_vdpau_interop2 */ - -/* ------------------------ GL_NV_vertex_array_range ----------------------- */ - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 - -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 - -typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void *pointer); - -#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) -#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) - -#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) - -#endif /* GL_NV_vertex_array_range */ - -/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 - -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 - -#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) - -#endif /* GL_NV_vertex_array_range2 */ - -/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */ - -#ifndef GL_NV_vertex_attrib_integer_64bit -#define GL_NV_vertex_attrib_integer_64bit 1 - -#define GL_INT64_NV 0x140E -#define GL_UNSIGNED_INT64_NV 0x140F - -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); - -#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV) -#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV) -#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV) -#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV) -#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV) -#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV) -#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV) -#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV) -#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV) -#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV) -#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV) -#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV) -#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV) -#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV) -#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV) -#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV) -#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV) -#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV) -#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV) - -#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit) - -#endif /* GL_NV_vertex_attrib_integer_64bit */ - -/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */ - -#ifndef GL_NV_vertex_buffer_unified_memory -#define GL_NV_vertex_buffer_unified_memory 1 - -#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E -#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F -#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 -#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 -#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 -#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 -#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 -#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 -#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 -#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 -#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 -#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 -#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A -#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B -#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C -#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D -#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E -#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F -#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 -#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 -#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 -#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 -#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 -#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 -#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 - -typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]); -typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); - -#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV) -#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV) -#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV) -#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV) -#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV) -#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV) -#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV) -#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV) -#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV) -#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV) -#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV) -#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV) - -#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory) - -#endif /* GL_NV_vertex_buffer_unified_memory */ - -/* -------------------------- GL_NV_vertex_program ------------------------- */ - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 - -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F - -typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); -typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void** pointer); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); - -#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) -#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) -#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) -#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) -#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) -#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) -#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) -#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) -#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) -#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) -#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) -#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) -#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) -#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) -#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) -#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) -#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) -#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) -#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) -#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) -#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) -#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) -#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) -#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) -#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) -#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) -#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) -#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) -#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) -#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) -#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) -#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) -#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) -#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) -#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) -#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) -#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) -#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) -#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) -#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) -#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) -#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) -#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) -#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) -#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) -#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) -#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) -#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) -#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) -#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) -#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) -#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) -#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) -#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) -#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) -#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) -#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) -#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) -#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) -#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) -#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) -#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) -#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) -#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) - -#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) - -#endif /* GL_NV_vertex_program */ - -/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 - -#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) - -#endif /* GL_NV_vertex_program1_1 */ - -/* ------------------------- GL_NV_vertex_program2 ------------------------- */ - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 - -#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) - -#endif /* GL_NV_vertex_program2 */ - -/* ---------------------- GL_NV_vertex_program2_option --------------------- */ - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 - -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 - -#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) - -#endif /* GL_NV_vertex_program2_option */ - -/* ------------------------- GL_NV_vertex_program3 ------------------------- */ - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 - -#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C - -#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) - -#endif /* GL_NV_vertex_program3 */ - -/* ------------------------- GL_NV_vertex_program4 ------------------------- */ - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 - -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD - -#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) - -#endif /* GL_NV_vertex_program4 */ - -/* -------------------------- GL_NV_video_capture -------------------------- */ - -#ifndef GL_NV_video_capture -#define GL_NV_video_capture 1 - -#define GL_VIDEO_BUFFER_NV 0x9020 -#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 -#define GL_FIELD_UPPER_NV 0x9022 -#define GL_FIELD_LOWER_NV 0x9023 -#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 -#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 -#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 -#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 -#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 -#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 -#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A -#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B -#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C -#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D -#define GL_PARTIAL_SUCCESS_NV 0x902E -#define GL_SUCCESS_NV 0x902F -#define GL_FAILURE_NV 0x9030 -#define GL_YCBYCR8_422_NV 0x9031 -#define GL_YCBAYCR8A_4224_NV 0x9032 -#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 -#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 -#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 -#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 -#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 -#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 -#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 -#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A -#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B -#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C - -typedef void (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params); -typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time); -typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params); - -#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV) -#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV) -#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV) -#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV) -#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV) -#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV) -#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV) -#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV) -#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV) -#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV) -#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV) -#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV) - -#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture) - -#endif /* GL_NV_video_capture */ - -/* -------------------------- GL_NV_viewport_array ------------------------- */ - -#ifndef GL_NV_viewport_array -#define GL_NV_viewport_array 1 - -#define GL_DEPTH_RANGE 0x0B70 -#define GL_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_MAX_VIEWPORTS_NV 0x825B -#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C -#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F - -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat * v); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f); -typedef void (GLAPIENTRY * PFNGLDISABLEINVPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEINVPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat* data); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINVPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint * v); -typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint * v); -typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat * v); -typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat * v); - -#define glDepthRangeArrayfvNV GLEW_GET_FUN(__glewDepthRangeArrayfvNV) -#define glDepthRangeIndexedfNV GLEW_GET_FUN(__glewDepthRangeIndexedfNV) -#define glDisableiNV GLEW_GET_FUN(__glewDisableiNV) -#define glEnableiNV GLEW_GET_FUN(__glewEnableiNV) -#define glGetFloati_vNV GLEW_GET_FUN(__glewGetFloati_vNV) -#define glIsEnablediNV GLEW_GET_FUN(__glewIsEnablediNV) -#define glScissorArrayvNV GLEW_GET_FUN(__glewScissorArrayvNV) -#define glScissorIndexedNV GLEW_GET_FUN(__glewScissorIndexedNV) -#define glScissorIndexedvNV GLEW_GET_FUN(__glewScissorIndexedvNV) -#define glViewportArrayvNV GLEW_GET_FUN(__glewViewportArrayvNV) -#define glViewportIndexedfNV GLEW_GET_FUN(__glewViewportIndexedfNV) -#define glViewportIndexedfvNV GLEW_GET_FUN(__glewViewportIndexedfvNV) - -#define GLEW_NV_viewport_array GLEW_GET_VAR(__GLEW_NV_viewport_array) - -#endif /* GL_NV_viewport_array */ - -/* ------------------------- GL_NV_viewport_array2 ------------------------- */ - -#ifndef GL_NV_viewport_array2 -#define GL_NV_viewport_array2 1 - -#define GLEW_NV_viewport_array2 GLEW_GET_VAR(__GLEW_NV_viewport_array2) - -#endif /* GL_NV_viewport_array2 */ - -/* ------------------------- GL_NV_viewport_swizzle ------------------------ */ - -#ifndef GL_NV_viewport_swizzle -#define GL_NV_viewport_swizzle 1 - -#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 -#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 -#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 -#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 -#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 -#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 -#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 -#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 -#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 -#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 -#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A -#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B - -typedef void (GLAPIENTRY * PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); - -#define glViewportSwizzleNV GLEW_GET_FUN(__glewViewportSwizzleNV) - -#define GLEW_NV_viewport_swizzle GLEW_GET_VAR(__GLEW_NV_viewport_swizzle) - -#endif /* GL_NV_viewport_swizzle */ - -/* ---------------------------- GL_OES_EGL_image --------------------------- */ - -#ifndef GL_OES_EGL_image -#define GL_OES_EGL_image 1 - -typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); -typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); - -#define glEGLImageTargetRenderbufferStorageOES GLEW_GET_FUN(__glewEGLImageTargetRenderbufferStorageOES) -#define glEGLImageTargetTexture2DOES GLEW_GET_FUN(__glewEGLImageTargetTexture2DOES) - -#define GLEW_OES_EGL_image GLEW_GET_VAR(__GLEW_OES_EGL_image) - -#endif /* GL_OES_EGL_image */ - -/* ----------------------- GL_OES_EGL_image_external ----------------------- */ - -#ifndef GL_OES_EGL_image_external -#define GL_OES_EGL_image_external 1 - -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 - -#define GLEW_OES_EGL_image_external GLEW_GET_VAR(__GLEW_OES_EGL_image_external) - -#endif /* GL_OES_EGL_image_external */ - -/* -------------------- GL_OES_EGL_image_external_essl3 -------------------- */ - -#ifndef GL_OES_EGL_image_external_essl3 -#define GL_OES_EGL_image_external_essl3 1 - -#define GLEW_OES_EGL_image_external_essl3 GLEW_GET_VAR(__GLEW_OES_EGL_image_external_essl3) - -#endif /* GL_OES_EGL_image_external_essl3 */ - -/* --------------------- GL_OES_blend_equation_separate -------------------- */ - -#ifndef GL_OES_blend_equation_separate -#define GL_OES_blend_equation_separate 1 - -#define GL_BLEND_EQUATION_RGB_OES 0x8009 -#define GL_BLEND_EQUATION_ALPHA_OES 0x883D - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEOESPROC) (GLenum modeRGB, GLenum modeAlpha); - -#define glBlendEquationSeparateOES GLEW_GET_FUN(__glewBlendEquationSeparateOES) - -#define GLEW_OES_blend_equation_separate GLEW_GET_VAR(__GLEW_OES_blend_equation_separate) - -#endif /* GL_OES_blend_equation_separate */ - -/* ----------------------- GL_OES_blend_func_separate ---------------------- */ - -#ifndef GL_OES_blend_func_separate -#define GL_OES_blend_func_separate 1 - -#define GL_BLEND_DST_RGB_OES 0x80C8 -#define GL_BLEND_SRC_RGB_OES 0x80C9 -#define GL_BLEND_DST_ALPHA_OES 0x80CA -#define GL_BLEND_SRC_ALPHA_OES 0x80CB - -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEOESPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - -#define glBlendFuncSeparateOES GLEW_GET_FUN(__glewBlendFuncSeparateOES) - -#define GLEW_OES_blend_func_separate GLEW_GET_VAR(__GLEW_OES_blend_func_separate) - -#endif /* GL_OES_blend_func_separate */ - -/* ------------------------- GL_OES_blend_subtract ------------------------- */ - -#ifndef GL_OES_blend_subtract -#define GL_OES_blend_subtract 1 - -#define GL_FUNC_ADD_OES 0x8006 -#define GL_BLEND_EQUATION_OES 0x8009 -#define GL_FUNC_SUBTRACT_OES 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONOESPROC) (GLenum mode); - -#define glBlendEquationOES GLEW_GET_FUN(__glewBlendEquationOES) - -#define GLEW_OES_blend_subtract GLEW_GET_VAR(__GLEW_OES_blend_subtract) - -#endif /* GL_OES_blend_subtract */ - -/* ------------------------ GL_OES_byte_coordinates ------------------------ */ - -#ifndef GL_OES_byte_coordinates -#define GL_OES_byte_coordinates 1 - -#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) - -#endif /* GL_OES_byte_coordinates */ - -/* ------------------ GL_OES_compressed_ETC1_RGB8_texture ------------------ */ - -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_OES_compressed_ETC1_RGB8_texture 1 - -#define GL_ETC1_RGB8_OES 0x8D64 - -#define GLEW_OES_compressed_ETC1_RGB8_texture GLEW_GET_VAR(__GLEW_OES_compressed_ETC1_RGB8_texture) - -#endif /* GL_OES_compressed_ETC1_RGB8_texture */ - -/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ - -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 - -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 - -#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) - -#endif /* GL_OES_compressed_paletted_texture */ - -/* --------------------------- GL_OES_copy_image --------------------------- */ - -#ifndef GL_OES_copy_image -#define GL_OES_copy_image 1 - -typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAOESPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -#define glCopyImageSubDataOES GLEW_GET_FUN(__glewCopyImageSubDataOES) - -#define GLEW_OES_copy_image GLEW_GET_VAR(__GLEW_OES_copy_image) - -#endif /* GL_OES_copy_image */ - -/* ----------------------------- GL_OES_depth24 ---------------------------- */ - -#ifndef GL_OES_depth24 -#define GL_OES_depth24 1 - -#define GL_DEPTH_COMPONENT24_OES 0x81A6 - -#define GLEW_OES_depth24 GLEW_GET_VAR(__GLEW_OES_depth24) - -#endif /* GL_OES_depth24 */ - -/* ----------------------------- GL_OES_depth32 ---------------------------- */ - -#ifndef GL_OES_depth32 -#define GL_OES_depth32 1 - -#define GL_DEPTH_COMPONENT32_OES 0x81A7 - -#define GLEW_OES_depth32 GLEW_GET_VAR(__GLEW_OES_depth32) - -#endif /* GL_OES_depth32 */ - -/* -------------------------- GL_OES_depth_texture ------------------------- */ - -#ifndef GL_OES_depth_texture -#define GL_OES_depth_texture 1 - -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_INT 0x1405 -#define GL_DEPTH_COMPONENT 0x1902 - -#define GLEW_OES_depth_texture GLEW_GET_VAR(__GLEW_OES_depth_texture) - -#endif /* GL_OES_depth_texture */ - -/* --------------------- GL_OES_depth_texture_cube_map --------------------- */ - -#ifndef GL_OES_depth_texture_cube_map -#define GL_OES_depth_texture_cube_map 1 - -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_INT 0x1405 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_DEPTH24_STENCIL8_OES 0x88F0 - -#define GLEW_OES_depth_texture_cube_map GLEW_GET_VAR(__GLEW_OES_depth_texture_cube_map) - -#endif /* GL_OES_depth_texture_cube_map */ - -/* ---------------------- GL_OES_draw_buffers_indexed ---------------------- */ - -#ifndef GL_OES_draw_buffers_indexed -#define GL_OES_draw_buffers_indexed 1 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (GLAPIENTRY * PFNGLCOLORMASKIOESPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAPIENTRY * PFNGLDISABLEIOESPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEIOESPROC) (GLenum target, GLuint index); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index); - -#define glBlendEquationSeparateiOES GLEW_GET_FUN(__glewBlendEquationSeparateiOES) -#define glBlendEquationiOES GLEW_GET_FUN(__glewBlendEquationiOES) -#define glBlendFuncSeparateiOES GLEW_GET_FUN(__glewBlendFuncSeparateiOES) -#define glBlendFunciOES GLEW_GET_FUN(__glewBlendFunciOES) -#define glColorMaskiOES GLEW_GET_FUN(__glewColorMaskiOES) -#define glDisableiOES GLEW_GET_FUN(__glewDisableiOES) -#define glEnableiOES GLEW_GET_FUN(__glewEnableiOES) -#define glIsEnablediOES GLEW_GET_FUN(__glewIsEnablediOES) - -#define GLEW_OES_draw_buffers_indexed GLEW_GET_VAR(__GLEW_OES_draw_buffers_indexed) - -#endif /* GL_OES_draw_buffers_indexed */ - -/* -------------------------- GL_OES_draw_texture -------------------------- */ - -#ifndef GL_OES_draw_texture -#define GL_OES_draw_texture 1 - -#define GL_TEXTURE_CROP_RECT_OES 0x8B9D - -#define GLEW_OES_draw_texture GLEW_GET_VAR(__GLEW_OES_draw_texture) - -#endif /* GL_OES_draw_texture */ - -/* ----------------------- GL_OES_element_index_uint ----------------------- */ - -#ifndef GL_OES_element_index_uint -#define GL_OES_element_index_uint 1 - -#define GL_UNSIGNED_INT 0x1405 - -#define GLEW_OES_element_index_uint GLEW_GET_VAR(__GLEW_OES_element_index_uint) - -#endif /* GL_OES_element_index_uint */ - -/* --------------------- GL_OES_extended_matrix_palette -------------------- */ - -#ifndef GL_OES_extended_matrix_palette -#define GL_OES_extended_matrix_palette 1 - -#define GLEW_OES_extended_matrix_palette GLEW_GET_VAR(__GLEW_OES_extended_matrix_palette) - -#endif /* GL_OES_extended_matrix_palette */ - -/* ------------------------ GL_OES_fbo_render_mipmap ----------------------- */ - -#ifndef GL_OES_fbo_render_mipmap -#define GL_OES_fbo_render_mipmap 1 - -#define GLEW_OES_fbo_render_mipmap GLEW_GET_VAR(__GLEW_OES_fbo_render_mipmap) - -#endif /* GL_OES_fbo_render_mipmap */ - -/* --------------------- GL_OES_fragment_precision_high -------------------- */ - -#ifndef GL_OES_fragment_precision_high -#define GL_OES_fragment_precision_high 1 - -#define GLEW_OES_fragment_precision_high GLEW_GET_VAR(__GLEW_OES_fragment_precision_high) - -#endif /* GL_OES_fragment_precision_high */ - -/* ----------------------- GL_OES_framebuffer_object ----------------------- */ - -#ifndef GL_OES_framebuffer_object -#define GL_OES_framebuffer_object 1 - -#define GL_NONE_OES 0 -#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 -#define GL_RGBA4_OES 0x8056 -#define GL_RGB5_A1_OES 0x8057 -#define GL_DEPTH_COMPONENT16_OES 0x81A5 -#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 -#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6 -#define GL_RENDERBUFFER_BINDING_OES 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD -#define GL_COLOR_ATTACHMENT0_OES 0x8CE0 -#define GL_DEPTH_ATTACHMENT_OES 0x8D00 -#define GL_STENCIL_ATTACHMENT_OES 0x8D20 -#define GL_FRAMEBUFFER_OES 0x8D40 -#define GL_RENDERBUFFER_OES 0x8D41 -#define GL_RENDERBUFFER_WIDTH_OES 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44 -#define GL_STENCIL_INDEX1_OES 0x8D46 -#define GL_STENCIL_INDEX4_OES 0x8D47 -#define GL_STENCIL_INDEX8_OES 0x8D48 -#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 -#define GL_RGB565_OES 0x8D62 - -typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEROESPROC) (GLenum target, GLuint framebuffer); -typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEROESPROC) (GLenum target, GLuint renderbuffer); -typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSOESPROC) (GLsizei n, const GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSOESPROC) (GLsizei n, const GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEROESPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSOESPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSOESPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPOESPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVOESPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEROESPROC) (GLuint framebuffer); -typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEROESPROC) (GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - -#define glBindFramebufferOES GLEW_GET_FUN(__glewBindFramebufferOES) -#define glBindRenderbufferOES GLEW_GET_FUN(__glewBindRenderbufferOES) -#define glCheckFramebufferStatusOES GLEW_GET_FUN(__glewCheckFramebufferStatusOES) -#define glDeleteFramebuffersOES GLEW_GET_FUN(__glewDeleteFramebuffersOES) -#define glDeleteRenderbuffersOES GLEW_GET_FUN(__glewDeleteRenderbuffersOES) -#define glFramebufferRenderbufferOES GLEW_GET_FUN(__glewFramebufferRenderbufferOES) -#define glFramebufferTexture2DOES GLEW_GET_FUN(__glewFramebufferTexture2DOES) -#define glGenFramebuffersOES GLEW_GET_FUN(__glewGenFramebuffersOES) -#define glGenRenderbuffersOES GLEW_GET_FUN(__glewGenRenderbuffersOES) -#define glGenerateMipmapOES GLEW_GET_FUN(__glewGenerateMipmapOES) -#define glGetFramebufferAttachmentParameterivOES GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivOES) -#define glGetRenderbufferParameterivOES GLEW_GET_FUN(__glewGetRenderbufferParameterivOES) -#define glIsFramebufferOES GLEW_GET_FUN(__glewIsFramebufferOES) -#define glIsRenderbufferOES GLEW_GET_FUN(__glewIsRenderbufferOES) -#define glRenderbufferStorageOES GLEW_GET_FUN(__glewRenderbufferStorageOES) - -#define GLEW_OES_framebuffer_object GLEW_GET_VAR(__GLEW_OES_framebuffer_object) - -#endif /* GL_OES_framebuffer_object */ - -/* ----------------------- GL_OES_geometry_point_size ---------------------- */ - -#ifndef GL_OES_geometry_point_size -#define GL_OES_geometry_point_size 1 - -#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 -#define GL_LINES_ADJACENCY_OES 0xA -#define GL_LINE_STRIP_ADJACENCY_OES 0xB -#define GL_TRIANGLES_ADJACENCY_OES 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0xD -#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E -#define GL_UNDEFINED_VERTEX_OES 0x8260 -#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F -#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 -#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 -#define GL_PRIMITIVES_GENERATED_OES 0x8C87 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 -#define GL_GEOMETRY_SHADER_OES 0x8DD9 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 -#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 -#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 - -#define GLEW_OES_geometry_point_size GLEW_GET_VAR(__GLEW_OES_geometry_point_size) - -#endif /* GL_OES_geometry_point_size */ - -/* ------------------------- GL_OES_geometry_shader ------------------------ */ - -#ifndef GL_OES_geometry_shader -#define GL_OES_geometry_shader 1 - -#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 -#define GL_LINES_ADJACENCY_OES 0xA -#define GL_LINE_STRIP_ADJACENCY_OES 0xB -#define GL_TRIANGLES_ADJACENCY_OES 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0xD -#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E -#define GL_UNDEFINED_VERTEX_OES 0x8260 -#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F -#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 -#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 -#define GL_PRIMITIVES_GENERATED_OES 0x8C87 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 -#define GL_GEOMETRY_SHADER_OES 0x8DD9 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 -#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 -#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 - -#define GLEW_OES_geometry_shader GLEW_GET_VAR(__GLEW_OES_geometry_shader) - -#endif /* GL_OES_geometry_shader */ - -/* ----------------------- GL_OES_get_program_binary ----------------------- */ - -#ifndef GL_OES_get_program_binary -#define GL_OES_get_program_binary 1 - -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE -#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF - -typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, void*binary); -typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); - -#define glGetProgramBinaryOES GLEW_GET_FUN(__glewGetProgramBinaryOES) -#define glProgramBinaryOES GLEW_GET_FUN(__glewProgramBinaryOES) - -#define GLEW_OES_get_program_binary GLEW_GET_VAR(__GLEW_OES_get_program_binary) - -#endif /* GL_OES_get_program_binary */ - -/* --------------------------- GL_OES_gpu_shader5 -------------------------- */ - -#ifndef GL_OES_gpu_shader5 -#define GL_OES_gpu_shader5 1 - -#define GLEW_OES_gpu_shader5 GLEW_GET_VAR(__GLEW_OES_gpu_shader5) - -#endif /* GL_OES_gpu_shader5 */ - -/* ---------------------------- GL_OES_mapbuffer --------------------------- */ - -#ifndef GL_OES_mapbuffer -#define GL_OES_mapbuffer 1 - -#define GL_WRITE_ONLY_OES 0x88B9 -#define GL_BUFFER_ACCESS_OES 0x88BB -#define GL_BUFFER_MAPPED_OES 0x88BC -#define GL_BUFFER_MAP_POINTER_OES 0x88BD - -typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params); -typedef void * (GLAPIENTRY * PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFEROESPROC) (GLenum target); - -#define glGetBufferPointervOES GLEW_GET_FUN(__glewGetBufferPointervOES) -#define glMapBufferOES GLEW_GET_FUN(__glewMapBufferOES) -#define glUnmapBufferOES GLEW_GET_FUN(__glewUnmapBufferOES) - -#define GLEW_OES_mapbuffer GLEW_GET_VAR(__GLEW_OES_mapbuffer) - -#endif /* GL_OES_mapbuffer */ - -/* --------------------------- GL_OES_matrix_get --------------------------- */ - -#ifndef GL_OES_matrix_get -#define GL_OES_matrix_get 1 - -#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898d -#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898e -#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898f - -#define GLEW_OES_matrix_get GLEW_GET_VAR(__GLEW_OES_matrix_get) - -#endif /* GL_OES_matrix_get */ - -/* ------------------------- GL_OES_matrix_palette ------------------------- */ - -#ifndef GL_OES_matrix_palette -#define GL_OES_matrix_palette 1 - -#define GL_MAX_VERTEX_UNITS_OES 0x86A4 -#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC -#define GL_WEIGHT_ARRAY_OES 0x86AD -#define GL_MATRIX_PALETTE_OES 0x8840 -#define GL_MAX_PALETTE_MATRICES_OES 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843 -#define GL_MATRIX_INDEX_ARRAY_OES 0x8844 -#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849 -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E -#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E - -typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXOESPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); -typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); - -#define glCurrentPaletteMatrixOES GLEW_GET_FUN(__glewCurrentPaletteMatrixOES) -#define glMatrixIndexPointerOES GLEW_GET_FUN(__glewMatrixIndexPointerOES) -#define glWeightPointerOES GLEW_GET_FUN(__glewWeightPointerOES) - -#define GLEW_OES_matrix_palette GLEW_GET_VAR(__GLEW_OES_matrix_palette) - -#endif /* GL_OES_matrix_palette */ - -/* ---------------------- GL_OES_packed_depth_stencil ---------------------- */ - -#ifndef GL_OES_packed_depth_stencil -#define GL_OES_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_UNSIGNED_INT_24_8_OES 0x84FA -#define GL_DEPTH24_STENCIL8_OES 0x88F0 - -#define GLEW_OES_packed_depth_stencil GLEW_GET_VAR(__GLEW_OES_packed_depth_stencil) - -#endif /* GL_OES_packed_depth_stencil */ - -/* ------------------------ GL_OES_point_size_array ------------------------ */ - -#ifndef GL_OES_point_size_array -#define GL_OES_point_size_array 1 - -#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A -#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B -#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C -#define GL_POINT_SIZE_ARRAY_OES 0x8B9C -#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F - -#define GLEW_OES_point_size_array GLEW_GET_VAR(__GLEW_OES_point_size_array) - -#endif /* GL_OES_point_size_array */ - -/* -------------------------- GL_OES_point_sprite -------------------------- */ - -#ifndef GL_OES_point_sprite -#define GL_OES_point_sprite 1 - -#define GL_POINT_SPRITE_OES 0x8861 -#define GL_COORD_REPLACE_OES 0x8862 - -#define GLEW_OES_point_sprite GLEW_GET_VAR(__GLEW_OES_point_sprite) - -#endif /* GL_OES_point_sprite */ - -/* --------------------------- GL_OES_read_format -------------------------- */ - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 - -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B - -#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) - -#endif /* GL_OES_read_format */ - -/* --------------------- GL_OES_required_internalformat -------------------- */ - -#ifndef GL_OES_required_internalformat -#define GL_OES_required_internalformat 1 - -#define GL_ALPHA8_OES 0x803C -#define GL_LUMINANCE8_OES 0x8040 -#define GL_LUMINANCE4_ALPHA4_OES 0x8043 -#define GL_LUMINANCE8_ALPHA8_OES 0x8045 -#define GL_RGB8_OES 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGBA4_OES 0x8056 -#define GL_RGB5_A1_OES 0x8057 -#define GL_RGBA8_OES 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_DEPTH_COMPONENT16_OES 0x81A5 -#define GL_DEPTH_COMPONENT24_OES 0x81A6 -#define GL_DEPTH_COMPONENT32_OES 0x81A7 -#define GL_DEPTH24_STENCIL8_OES 0x88F0 -#define GL_RGB565_OES 0x8D62 - -#define GLEW_OES_required_internalformat GLEW_GET_VAR(__GLEW_OES_required_internalformat) - -#endif /* GL_OES_required_internalformat */ - -/* --------------------------- GL_OES_rgb8_rgba8 --------------------------- */ - -#ifndef GL_OES_rgb8_rgba8 -#define GL_OES_rgb8_rgba8 1 - -#define GL_RGB8_OES 0x8051 -#define GL_RGBA8_OES 0x8058 - -#define GLEW_OES_rgb8_rgba8 GLEW_GET_VAR(__GLEW_OES_rgb8_rgba8) - -#endif /* GL_OES_rgb8_rgba8 */ - -/* ------------------------- GL_OES_sample_shading ------------------------- */ - -#ifndef GL_OES_sample_shading -#define GL_OES_sample_shading 1 - -#define GL_SAMPLE_SHADING_OES 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 - -typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value); - -#define glMinSampleShadingOES GLEW_GET_FUN(__glewMinSampleShadingOES) - -#define GLEW_OES_sample_shading GLEW_GET_VAR(__GLEW_OES_sample_shading) - -#endif /* GL_OES_sample_shading */ - -/* ------------------------ GL_OES_sample_variables ------------------------ */ - -#ifndef GL_OES_sample_variables -#define GL_OES_sample_variables 1 - -#define GLEW_OES_sample_variables GLEW_GET_VAR(__GLEW_OES_sample_variables) - -#endif /* GL_OES_sample_variables */ - -/* ----------------------- GL_OES_shader_image_atomic ---------------------- */ - -#ifndef GL_OES_shader_image_atomic -#define GL_OES_shader_image_atomic 1 - -#define GLEW_OES_shader_image_atomic GLEW_GET_VAR(__GLEW_OES_shader_image_atomic) - -#endif /* GL_OES_shader_image_atomic */ - -/* ------------------------ GL_OES_shader_io_blocks ------------------------ */ - -#ifndef GL_OES_shader_io_blocks -#define GL_OES_shader_io_blocks 1 - -#define GLEW_OES_shader_io_blocks GLEW_GET_VAR(__GLEW_OES_shader_io_blocks) - -#endif /* GL_OES_shader_io_blocks */ - -/* ---------------- GL_OES_shader_multisample_interpolation ---------------- */ - -#ifndef GL_OES_shader_multisample_interpolation -#define GL_OES_shader_multisample_interpolation 1 - -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D - -#define GLEW_OES_shader_multisample_interpolation GLEW_GET_VAR(__GLEW_OES_shader_multisample_interpolation) - -#endif /* GL_OES_shader_multisample_interpolation */ - -/* ------------------------ GL_OES_single_precision ------------------------ */ - -#ifndef GL_OES_single_precision -#define GL_OES_single_precision 1 - -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); -typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); -typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); -typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); - -#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) -#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) -#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) -#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) -#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) -#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) - -#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) - -#endif /* GL_OES_single_precision */ - -/* ---------------------- GL_OES_standard_derivatives ---------------------- */ - -#ifndef GL_OES_standard_derivatives -#define GL_OES_standard_derivatives 1 - -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B - -#define GLEW_OES_standard_derivatives GLEW_GET_VAR(__GLEW_OES_standard_derivatives) - -#endif /* GL_OES_standard_derivatives */ - -/* ---------------------------- GL_OES_stencil1 ---------------------------- */ - -#ifndef GL_OES_stencil1 -#define GL_OES_stencil1 1 - -#define GL_STENCIL_INDEX1_OES 0x8D46 - -#define GLEW_OES_stencil1 GLEW_GET_VAR(__GLEW_OES_stencil1) - -#endif /* GL_OES_stencil1 */ - -/* ---------------------------- GL_OES_stencil4 ---------------------------- */ - -#ifndef GL_OES_stencil4 -#define GL_OES_stencil4 1 - -#define GL_STENCIL_INDEX4_OES 0x8D47 - -#define GLEW_OES_stencil4 GLEW_GET_VAR(__GLEW_OES_stencil4) - -#endif /* GL_OES_stencil4 */ - -/* ---------------------------- GL_OES_stencil8 ---------------------------- */ - -#ifndef GL_OES_stencil8 -#define GL_OES_stencil8 1 - -#define GL_STENCIL_INDEX8_OES 0x8D48 - -#define GLEW_OES_stencil8 GLEW_GET_VAR(__GLEW_OES_stencil8) - -#endif /* GL_OES_stencil8 */ - -/* ----------------------- GL_OES_surfaceless_context ---------------------- */ - -#ifndef GL_OES_surfaceless_context -#define GL_OES_surfaceless_context 1 - -#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 - -#define GLEW_OES_surfaceless_context GLEW_GET_VAR(__GLEW_OES_surfaceless_context) - -#endif /* GL_OES_surfaceless_context */ - -/* --------------------- GL_OES_tessellation_point_size -------------------- */ - -#ifndef GL_OES_tessellation_point_size -#define GL_OES_tessellation_point_size 1 - -#define GL_QUADS_OES 0x0007 -#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 -#define GL_PATCHES_OES 0xE -#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F -#define GL_PATCH_VERTICES_OES 0x8E72 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 -#define GL_TESS_GEN_MODE_OES 0x8E76 -#define GL_TESS_GEN_SPACING_OES 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 -#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 -#define GL_ISOLINES_OES 0x8E7A -#define GL_FRACTIONAL_ODD_OES 0x8E7B -#define GL_FRACTIONAL_EVEN_OES 0x8E7C -#define GL_MAX_PATCH_VERTICES_OES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 -#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 -#define GL_TESS_CONTROL_SHADER_OES 0x8E88 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 -#define GL_IS_PER_PATCH_OES 0x92E7 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 - -#define GLEW_OES_tessellation_point_size GLEW_GET_VAR(__GLEW_OES_tessellation_point_size) - -#endif /* GL_OES_tessellation_point_size */ - -/* ----------------------- GL_OES_tessellation_shader ---------------------- */ - -#ifndef GL_OES_tessellation_shader -#define GL_OES_tessellation_shader 1 - -#define GL_QUADS_OES 0x0007 -#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 -#define GL_PATCHES_OES 0xE -#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F -#define GL_PATCH_VERTICES_OES 0x8E72 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 -#define GL_TESS_GEN_MODE_OES 0x8E76 -#define GL_TESS_GEN_SPACING_OES 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 -#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 -#define GL_ISOLINES_OES 0x8E7A -#define GL_FRACTIONAL_ODD_OES 0x8E7B -#define GL_FRACTIONAL_EVEN_OES 0x8E7C -#define GL_MAX_PATCH_VERTICES_OES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 -#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 -#define GL_TESS_CONTROL_SHADER_OES 0x8E88 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 -#define GL_IS_PER_PATCH_OES 0x92E7 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 - -#define GLEW_OES_tessellation_shader GLEW_GET_VAR(__GLEW_OES_tessellation_shader) - -#endif /* GL_OES_tessellation_shader */ - -/* --------------------------- GL_OES_texture_3D --------------------------- */ - -#ifndef GL_OES_texture_3D -#define GL_OES_texture_3D 1 - -#define GL_TEXTURE_BINDING_3D_OES 0x806A -#define GL_TEXTURE_3D_OES 0x806F -#define GL_TEXTURE_WRAP_R_OES 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 - -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - -#define glCompressedTexImage3DOES GLEW_GET_FUN(__glewCompressedTexImage3DOES) -#define glCompressedTexSubImage3DOES GLEW_GET_FUN(__glewCompressedTexSubImage3DOES) -#define glCopyTexSubImage3DOES GLEW_GET_FUN(__glewCopyTexSubImage3DOES) -#define glFramebufferTexture3DOES GLEW_GET_FUN(__glewFramebufferTexture3DOES) -#define glTexImage3DOES GLEW_GET_FUN(__glewTexImage3DOES) -#define glTexSubImage3DOES GLEW_GET_FUN(__glewTexSubImage3DOES) - -#define GLEW_OES_texture_3D GLEW_GET_VAR(__GLEW_OES_texture_3D) - -#endif /* GL_OES_texture_3D */ - -/* ---------------------- GL_OES_texture_border_clamp ---------------------- */ - -#ifndef GL_OES_texture_border_clamp -#define GL_OES_texture_border_clamp 1 - -#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 -#define GL_CLAMP_TO_BORDER_OES 0x812D - -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint* params); - -#define glGetSamplerParameterIivOES GLEW_GET_FUN(__glewGetSamplerParameterIivOES) -#define glGetSamplerParameterIuivOES GLEW_GET_FUN(__glewGetSamplerParameterIuivOES) -#define glGetTexParameterIivOES GLEW_GET_FUN(__glewGetTexParameterIivOES) -#define glGetTexParameterIuivOES GLEW_GET_FUN(__glewGetTexParameterIuivOES) -#define glSamplerParameterIivOES GLEW_GET_FUN(__glewSamplerParameterIivOES) -#define glSamplerParameterIuivOES GLEW_GET_FUN(__glewSamplerParameterIuivOES) -#define glTexParameterIivOES GLEW_GET_FUN(__glewTexParameterIivOES) -#define glTexParameterIuivOES GLEW_GET_FUN(__glewTexParameterIuivOES) - -#define GLEW_OES_texture_border_clamp GLEW_GET_VAR(__GLEW_OES_texture_border_clamp) - -#endif /* GL_OES_texture_border_clamp */ - -/* ------------------------- GL_OES_texture_buffer ------------------------- */ - -#ifndef GL_OES_texture_buffer -#define GL_OES_texture_buffer 1 - -#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A -#define GL_TEXTURE_BUFFER_OES 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D -#define GL_SAMPLER_BUFFER_OES 0x8DC2 -#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 -#define GL_IMAGE_BUFFER_OES 0x9051 -#define GL_INT_IMAGE_BUFFER_OES 0x905C -#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 -#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D -#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F - -typedef void (GLAPIENTRY * PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); - -#define glTexBufferOES GLEW_GET_FUN(__glewTexBufferOES) -#define glTexBufferRangeOES GLEW_GET_FUN(__glewTexBufferRangeOES) - -#define GLEW_OES_texture_buffer GLEW_GET_VAR(__GLEW_OES_texture_buffer) - -#endif /* GL_OES_texture_buffer */ - -/* -------------------- GL_OES_texture_compression_astc -------------------- */ - -#ifndef GL_OES_texture_compression_astc -#define GL_OES_texture_compression_astc 1 - -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 -#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 -#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 -#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 -#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 -#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 -#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 -#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 -#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 -#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 - -#define GLEW_OES_texture_compression_astc GLEW_GET_VAR(__GLEW_OES_texture_compression_astc) - -#endif /* GL_OES_texture_compression_astc */ - -/* ------------------------ GL_OES_texture_cube_map ------------------------ */ - -#ifndef GL_OES_texture_cube_map -#define GL_OES_texture_cube_map 1 - -#define GL_TEXTURE_GEN_MODE_OES 0x2500 -#define GL_NORMAL_MAP_OES 0x8511 -#define GL_REFLECTION_MAP_OES 0x8512 -#define GL_TEXTURE_CUBE_MAP_OES 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C -#define GL_TEXTURE_GEN_STR_OES 0x8D60 - -typedef void (GLAPIENTRY * PFNGLGETTEXGENFVOESPROC) (GLenum coord, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXGENIVOESPROC) (GLenum coord, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLTEXGENFOESPROC) (GLenum coord, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLTEXGENFVOESPROC) (GLenum coord, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLTEXGENIOESPROC) (GLenum coord, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLTEXGENIVOESPROC) (GLenum coord, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed* params); - -#define glGetTexGenfvOES GLEW_GET_FUN(__glewGetTexGenfvOES) -#define glGetTexGenivOES GLEW_GET_FUN(__glewGetTexGenivOES) -#define glGetTexGenxvOES GLEW_GET_FUN(__glewGetTexGenxvOES) -#define glTexGenfOES GLEW_GET_FUN(__glewTexGenfOES) -#define glTexGenfvOES GLEW_GET_FUN(__glewTexGenfvOES) -#define glTexGeniOES GLEW_GET_FUN(__glewTexGeniOES) -#define glTexGenivOES GLEW_GET_FUN(__glewTexGenivOES) -#define glTexGenxOES GLEW_GET_FUN(__glewTexGenxOES) -#define glTexGenxvOES GLEW_GET_FUN(__glewTexGenxvOES) - -#define GLEW_OES_texture_cube_map GLEW_GET_VAR(__GLEW_OES_texture_cube_map) - -#endif /* GL_OES_texture_cube_map */ - -/* --------------------- GL_OES_texture_cube_map_array --------------------- */ - -#ifndef GL_OES_texture_cube_map_array -#define GL_OES_texture_cube_map_array 1 - -#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A -#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F -#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A - -#define GLEW_OES_texture_cube_map_array GLEW_GET_VAR(__GLEW_OES_texture_cube_map_array) - -#endif /* GL_OES_texture_cube_map_array */ - -/* ---------------------- GL_OES_texture_env_crossbar ---------------------- */ - -#ifndef GL_OES_texture_env_crossbar -#define GL_OES_texture_env_crossbar 1 - -#define GLEW_OES_texture_env_crossbar GLEW_GET_VAR(__GLEW_OES_texture_env_crossbar) - -#endif /* GL_OES_texture_env_crossbar */ - -/* --------------------- GL_OES_texture_mirrored_repeat -------------------- */ - -#ifndef GL_OES_texture_mirrored_repeat -#define GL_OES_texture_mirrored_repeat 1 - -#define GL_MIRRORED_REPEAT 0x8370 - -#define GLEW_OES_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_OES_texture_mirrored_repeat) - -#endif /* GL_OES_texture_mirrored_repeat */ - -/* -------------------------- GL_OES_texture_npot -------------------------- */ - -#ifndef GL_OES_texture_npot -#define GL_OES_texture_npot 1 - -#define GLEW_OES_texture_npot GLEW_GET_VAR(__GLEW_OES_texture_npot) - -#endif /* GL_OES_texture_npot */ - -/* ------------------------ GL_OES_texture_stencil8 ------------------------ */ - -#ifndef GL_OES_texture_stencil8 -#define GL_OES_texture_stencil8 1 - -#define GL_STENCIL_INDEX 0x1901 -#define GL_STENCIL_INDEX8 0x8D48 - -#define GLEW_OES_texture_stencil8 GLEW_GET_VAR(__GLEW_OES_texture_stencil8) - -#endif /* GL_OES_texture_stencil8 */ - -/* -------------- GL_OES_texture_storage_multisample_2d_array -------------- */ - -#ifndef GL_OES_texture_storage_multisample_2d_array -#define GL_OES_texture_storage_multisample_2d_array 1 - -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D - -typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - -#define glTexStorage3DMultisampleOES GLEW_GET_FUN(__glewTexStorage3DMultisampleOES) - -#define GLEW_OES_texture_storage_multisample_2d_array GLEW_GET_VAR(__GLEW_OES_texture_storage_multisample_2d_array) - -#endif /* GL_OES_texture_storage_multisample_2d_array */ - -/* -------------------------- GL_OES_texture_view -------------------------- */ - -#ifndef GL_OES_texture_view -#define GL_OES_texture_view 1 - -#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB -#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC -#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD -#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF - -typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); - -#define glTextureViewOES GLEW_GET_FUN(__glewTextureViewOES) - -#define GLEW_OES_texture_view GLEW_GET_VAR(__GLEW_OES_texture_view) - -#endif /* GL_OES_texture_view */ - -/* ----------------------- GL_OES_vertex_array_object ---------------------- */ - -#ifndef GL_OES_vertex_array_object -#define GL_OES_vertex_array_object 1 - -#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYOESPROC) (GLuint array); - -#define glBindVertexArrayOES GLEW_GET_FUN(__glewBindVertexArrayOES) -#define glDeleteVertexArraysOES GLEW_GET_FUN(__glewDeleteVertexArraysOES) -#define glGenVertexArraysOES GLEW_GET_FUN(__glewGenVertexArraysOES) -#define glIsVertexArrayOES GLEW_GET_FUN(__glewIsVertexArrayOES) - -#define GLEW_OES_vertex_array_object GLEW_GET_VAR(__GLEW_OES_vertex_array_object) - -#endif /* GL_OES_vertex_array_object */ - -/* ------------------------ GL_OES_vertex_half_float ----------------------- */ - -#ifndef GL_OES_vertex_half_float -#define GL_OES_vertex_half_float 1 - -#define GL_HALF_FLOAT_OES 0x8D61 - -#define GLEW_OES_vertex_half_float GLEW_GET_VAR(__GLEW_OES_vertex_half_float) - -#endif /* GL_OES_vertex_half_float */ - -/* --------------------- GL_OES_vertex_type_10_10_10_2 --------------------- */ - -#ifndef GL_OES_vertex_type_10_10_10_2 -#define GL_OES_vertex_type_10_10_10_2 1 - -#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 -#define GL_INT_10_10_10_2_OES 0x8DF7 - -#define GLEW_OES_vertex_type_10_10_10_2 GLEW_GET_VAR(__GLEW_OES_vertex_type_10_10_10_2) - -#endif /* GL_OES_vertex_type_10_10_10_2 */ - -/* ---------------------------- GL_OML_interlace --------------------------- */ - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 - -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 - -#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) - -#endif /* GL_OML_interlace */ - -/* ---------------------------- GL_OML_resample ---------------------------- */ - -#ifndef GL_OML_resample -#define GL_OML_resample 1 - -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 - -#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) - -#endif /* GL_OML_resample */ - -/* ---------------------------- GL_OML_subsample --------------------------- */ - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 - -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 - -#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) - -#endif /* GL_OML_subsample */ - -/* ---------------------------- GL_OVR_multiview --------------------------- */ - -#ifndef GL_OVR_multiview -#define GL_OVR_multiview 1 - -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 -#define GL_MAX_VIEWS_OVR 0x9631 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 -#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); - -#define glFramebufferTextureMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultiviewOVR) -#define glNamedFramebufferTextureMultiviewOVR GLEW_GET_FUN(__glewNamedFramebufferTextureMultiviewOVR) - -#define GLEW_OVR_multiview GLEW_GET_VAR(__GLEW_OVR_multiview) - -#endif /* GL_OVR_multiview */ - -/* --------------------------- GL_OVR_multiview2 --------------------------- */ - -#ifndef GL_OVR_multiview2 -#define GL_OVR_multiview2 1 - -#define GLEW_OVR_multiview2 GLEW_GET_VAR(__GLEW_OVR_multiview2) - -#endif /* GL_OVR_multiview2 */ - -/* ------------ GL_OVR_multiview_multisampled_render_to_texture ------------ */ - -#ifndef GL_OVR_multiview_multisampled_render_to_texture -#define GL_OVR_multiview_multisampled_render_to_texture 1 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); - -#define glFramebufferTextureMultisampleMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultisampleMultiviewOVR) - -#define GLEW_OVR_multiview_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_OVR_multiview_multisampled_render_to_texture) - -#endif /* GL_OVR_multiview_multisampled_render_to_texture */ - -/* --------------------------- GL_PGI_misc_hints --------------------------- */ - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 - -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 -#define GL_CONSERVE_MEMORY_HINT_PGI 107005 -#define GL_RECLAIM_MEMORY_HINT_PGI 107006 -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 -#define GL_ALWAYS_FAST_HINT_PGI 107020 -#define GL_ALWAYS_SOFT_HINT_PGI 107021 -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 -#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 -#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 -#define GL_STRICT_LIGHTING_HINT_PGI 107031 -#define GL_STRICT_SCISSOR_HINT_PGI 107032 -#define GL_FULL_STIPPLE_HINT_PGI 107033 -#define GL_CLIP_NEAR_HINT_PGI 107040 -#define GL_CLIP_FAR_HINT_PGI 107041 -#define GL_WIDE_LINE_HINT_PGI 107042 -#define GL_BACK_NORMALS_HINT_PGI 107043 - -#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) - -#endif /* GL_PGI_misc_hints */ - -/* -------------------------- GL_PGI_vertex_hints -------------------------- */ - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 - -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_VERTEX_DATA_HINT_PGI 107050 -#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 -#define GL_MATERIAL_SIDE_HINT_PGI 107052 -#define GL_MAX_VERTEX_HINT_PGI 107053 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 - -#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) - -#endif /* GL_PGI_vertex_hints */ - -/* ----------------------- GL_QCOM_YUV_texture_gather ---------------------- */ - -#ifndef GL_QCOM_YUV_texture_gather -#define GL_QCOM_YUV_texture_gather 1 - -#define GLEW_QCOM_YUV_texture_gather GLEW_GET_VAR(__GLEW_QCOM_YUV_texture_gather) - -#endif /* GL_QCOM_YUV_texture_gather */ - -/* --------------------------- GL_QCOM_alpha_test -------------------------- */ - -#ifndef GL_QCOM_alpha_test -#define GL_QCOM_alpha_test 1 - -#define GL_ALPHA_TEST_QCOM 0x0BC0 -#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 -#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 - -typedef void (GLAPIENTRY * PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); - -#define glAlphaFuncQCOM GLEW_GET_FUN(__glewAlphaFuncQCOM) - -#define GLEW_QCOM_alpha_test GLEW_GET_VAR(__GLEW_QCOM_alpha_test) - -#endif /* GL_QCOM_alpha_test */ - -/* ------------------------ GL_QCOM_binning_control ------------------------ */ - -#ifndef GL_QCOM_binning_control -#define GL_QCOM_binning_control 1 - -#define GL_DONT_CARE 0x1100 -#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 -#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 -#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 -#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 - -#define GLEW_QCOM_binning_control GLEW_GET_VAR(__GLEW_QCOM_binning_control) - -#endif /* GL_QCOM_binning_control */ - -/* ------------------------- GL_QCOM_driver_control ------------------------ */ - -#ifndef GL_QCOM_driver_control -#define GL_QCOM_driver_control 1 - -typedef void (GLAPIENTRY * PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -typedef void (GLAPIENTRY * PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar *driverControlString); -typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint* num, GLsizei size, GLuint *driverControls); - -#define glDisableDriverControlQCOM GLEW_GET_FUN(__glewDisableDriverControlQCOM) -#define glEnableDriverControlQCOM GLEW_GET_FUN(__glewEnableDriverControlQCOM) -#define glGetDriverControlStringQCOM GLEW_GET_FUN(__glewGetDriverControlStringQCOM) -#define glGetDriverControlsQCOM GLEW_GET_FUN(__glewGetDriverControlsQCOM) - -#define GLEW_QCOM_driver_control GLEW_GET_VAR(__GLEW_QCOM_driver_control) - -#endif /* GL_QCOM_driver_control */ - -/* -------------------------- GL_QCOM_extended_get ------------------------- */ - -#ifndef GL_QCOM_extended_get -#define GL_QCOM_extended_get 1 - -#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 -#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 -#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 -#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 -#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 -#define GL_TEXTURE_TYPE_QCOM 0x8BD7 -#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 -#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 -#define GL_TEXTURE_TARGET_QCOM 0x8BDA -#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB -#define GL_STATE_RESTORE 0x8BDC - -typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void** params); -typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERSQCOMPROC) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers); -typedef void (GLAPIENTRY * PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers); -typedef void (GLAPIENTRY * PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers); -typedef void (GLAPIENTRY * PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); -typedef void (GLAPIENTRY * PFNGLEXTGETTEXTURESQCOMPROC) (GLuint* textures, GLint maxTextures, GLint* numTextures); -typedef void (GLAPIENTRY * PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); - -#define glExtGetBufferPointervQCOM GLEW_GET_FUN(__glewExtGetBufferPointervQCOM) -#define glExtGetBuffersQCOM GLEW_GET_FUN(__glewExtGetBuffersQCOM) -#define glExtGetFramebuffersQCOM GLEW_GET_FUN(__glewExtGetFramebuffersQCOM) -#define glExtGetRenderbuffersQCOM GLEW_GET_FUN(__glewExtGetRenderbuffersQCOM) -#define glExtGetTexLevelParameterivQCOM GLEW_GET_FUN(__glewExtGetTexLevelParameterivQCOM) -#define glExtGetTexSubImageQCOM GLEW_GET_FUN(__glewExtGetTexSubImageQCOM) -#define glExtGetTexturesQCOM GLEW_GET_FUN(__glewExtGetTexturesQCOM) -#define glExtTexObjectStateOverrideiQCOM GLEW_GET_FUN(__glewExtTexObjectStateOverrideiQCOM) - -#define GLEW_QCOM_extended_get GLEW_GET_VAR(__GLEW_QCOM_extended_get) - -#endif /* GL_QCOM_extended_get */ - -/* ------------------------- GL_QCOM_extended_get2 ------------------------- */ - -#ifndef GL_QCOM_extended_get2 -#define GL_QCOM_extended_get2 1 - -typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar* source, GLint* length); -typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint* programs, GLint maxPrograms, GLint* numPrograms); -typedef void (GLAPIENTRY * PFNGLEXTGETSHADERSQCOMPROC) (GLuint* shaders, GLint maxShaders, GLint* numShaders); -typedef GLboolean (GLAPIENTRY * PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); - -#define glExtGetProgramBinarySourceQCOM GLEW_GET_FUN(__glewExtGetProgramBinarySourceQCOM) -#define glExtGetProgramsQCOM GLEW_GET_FUN(__glewExtGetProgramsQCOM) -#define glExtGetShadersQCOM GLEW_GET_FUN(__glewExtGetShadersQCOM) -#define glExtIsProgramBinaryQCOM GLEW_GET_FUN(__glewExtIsProgramBinaryQCOM) - -#define GLEW_QCOM_extended_get2 GLEW_GET_VAR(__GLEW_QCOM_extended_get2) - -#endif /* GL_QCOM_extended_get2 */ - -/* ---------------------- GL_QCOM_framebuffer_foveated --------------------- */ - -#ifndef GL_QCOM_framebuffer_foveated -#define GL_QCOM_framebuffer_foveated 1 - -#define GL_FOVEATION_ENABLE_BIT_QCOM 0x1 -#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x2 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint fbo, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint* providedFeatures); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint fbo, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); - -#define glFramebufferFoveationConfigQCOM GLEW_GET_FUN(__glewFramebufferFoveationConfigQCOM) -#define glFramebufferFoveationParametersQCOM GLEW_GET_FUN(__glewFramebufferFoveationParametersQCOM) - -#define GLEW_QCOM_framebuffer_foveated GLEW_GET_VAR(__GLEW_QCOM_framebuffer_foveated) - -#endif /* GL_QCOM_framebuffer_foveated */ - -/* ---------------------- GL_QCOM_perfmon_global_mode ---------------------- */ - -#ifndef GL_QCOM_perfmon_global_mode -#define GL_QCOM_perfmon_global_mode 1 - -#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 - -#define GLEW_QCOM_perfmon_global_mode GLEW_GET_VAR(__GLEW_QCOM_perfmon_global_mode) - -#endif /* GL_QCOM_perfmon_global_mode */ - -/* -------------- GL_QCOM_shader_framebuffer_fetch_noncoherent ------------- */ - -#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent -#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 - -#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void); - -#define glFramebufferFetchBarrierQCOM GLEW_GET_FUN(__glewFramebufferFetchBarrierQCOM) - -#define GLEW_QCOM_shader_framebuffer_fetch_noncoherent GLEW_GET_VAR(__GLEW_QCOM_shader_framebuffer_fetch_noncoherent) - -#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ - -/* ----------------- GL_QCOM_shader_framebuffer_fetch_rate ----------------- */ - -#ifndef GL_QCOM_shader_framebuffer_fetch_rate -#define GL_QCOM_shader_framebuffer_fetch_rate 1 - -#define GLEW_QCOM_shader_framebuffer_fetch_rate GLEW_GET_VAR(__GLEW_QCOM_shader_framebuffer_fetch_rate) - -#endif /* GL_QCOM_shader_framebuffer_fetch_rate */ - -/* ------------------------ GL_QCOM_texture_foveated ----------------------- */ - -#ifndef GL_QCOM_texture_foveated -#define GL_QCOM_texture_foveated 1 - -#define GL_FOVEATION_ENABLE_BIT_QCOM 0x1 -#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x2 -#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB -#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC -#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD -#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE -#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF - -typedef void (GLAPIENTRY * PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); - -#define glTextureFoveationParametersQCOM GLEW_GET_FUN(__glewTextureFoveationParametersQCOM) - -#define GLEW_QCOM_texture_foveated GLEW_GET_VAR(__GLEW_QCOM_texture_foveated) - -#endif /* GL_QCOM_texture_foveated */ - -/* --------------- GL_QCOM_texture_foveated_subsampled_layout -------------- */ - -#ifndef GL_QCOM_texture_foveated_subsampled_layout -#define GL_QCOM_texture_foveated_subsampled_layout 1 - -#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x4 -#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1 - -#define GLEW_QCOM_texture_foveated_subsampled_layout GLEW_GET_VAR(__GLEW_QCOM_texture_foveated_subsampled_layout) - -#endif /* GL_QCOM_texture_foveated_subsampled_layout */ - -/* ------------------------ GL_QCOM_tiled_rendering ------------------------ */ - -#ifndef GL_QCOM_tiled_rendering -#define GL_QCOM_tiled_rendering 1 - -#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 -#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 -#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 -#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 -#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 -#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 -#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 -#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 -#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 -#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 -#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 -#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 -#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 -#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 -#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 -#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 -#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 -#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 -#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 -#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 -#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 -#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 -#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 -#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 -#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 -#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 -#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 -#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 -#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 -#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 -#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 -#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 - -typedef void (GLAPIENTRY * PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); -typedef void (GLAPIENTRY * PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); - -#define glEndTilingQCOM GLEW_GET_FUN(__glewEndTilingQCOM) -#define glStartTilingQCOM GLEW_GET_FUN(__glewStartTilingQCOM) - -#define GLEW_QCOM_tiled_rendering GLEW_GET_VAR(__GLEW_QCOM_tiled_rendering) - -#endif /* GL_QCOM_tiled_rendering */ - -/* ---------------------- GL_QCOM_writeonly_rendering ---------------------- */ - -#ifndef GL_QCOM_writeonly_rendering -#define GL_QCOM_writeonly_rendering 1 - -#define GL_WRITEONLY_RENDERING_QCOM 0x8823 - -#define GLEW_QCOM_writeonly_rendering GLEW_GET_VAR(__GLEW_QCOM_writeonly_rendering) - -#endif /* GL_QCOM_writeonly_rendering */ - -/* ---------------------- GL_REGAL_ES1_0_compatibility --------------------- */ - -#ifndef GL_REGAL_ES1_0_compatibility -#define GL_REGAL_ES1_0_compatibility 1 - -typedef int GLclampx; - -typedef void (GLAPIENTRY * PFNGLALPHAFUNCXPROC) (GLenum func, GLclampx ref); -typedef void (GLAPIENTRY * PFNGLCLEARCOLORXPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha); -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHXPROC) (GLclampx depth); -typedef void (GLAPIENTRY * PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEXPROC) (GLclampx zNear, GLclampx zFar); -typedef void (GLAPIENTRY * PFNGLFOGXPROC) (GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLFOGXVPROC) (GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLFRUSTUMFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); -typedef void (GLAPIENTRY * PFNGLFRUSTUMXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); -typedef void (GLAPIENTRY * PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLLINEWIDTHXPROC) (GLfixed width); -typedef void (GLAPIENTRY * PFNGLLOADMATRIXXPROC) (const GLfixed* m); -typedef void (GLAPIENTRY * PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLMULTMATRIXXPROC) (const GLfixed* m); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4XPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q); -typedef void (GLAPIENTRY * PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz); -typedef void (GLAPIENTRY * PFNGLORTHOFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); -typedef void (GLAPIENTRY * PFNGLORTHOXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); -typedef void (GLAPIENTRY * PFNGLPOINTSIZEXPROC) (GLfixed size); -typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units); -typedef void (GLAPIENTRY * PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert); -typedef void (GLAPIENTRY * PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (GLAPIENTRY * PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z); - -#define glAlphaFuncx GLEW_GET_FUN(__glewAlphaFuncx) -#define glClearColorx GLEW_GET_FUN(__glewClearColorx) -#define glClearDepthx GLEW_GET_FUN(__glewClearDepthx) -#define glColor4x GLEW_GET_FUN(__glewColor4x) -#define glDepthRangex GLEW_GET_FUN(__glewDepthRangex) -#define glFogx GLEW_GET_FUN(__glewFogx) -#define glFogxv GLEW_GET_FUN(__glewFogxv) -#define glFrustumf GLEW_GET_FUN(__glewFrustumf) -#define glFrustumx GLEW_GET_FUN(__glewFrustumx) -#define glLightModelx GLEW_GET_FUN(__glewLightModelx) -#define glLightModelxv GLEW_GET_FUN(__glewLightModelxv) -#define glLightx GLEW_GET_FUN(__glewLightx) -#define glLightxv GLEW_GET_FUN(__glewLightxv) -#define glLineWidthx GLEW_GET_FUN(__glewLineWidthx) -#define glLoadMatrixx GLEW_GET_FUN(__glewLoadMatrixx) -#define glMaterialx GLEW_GET_FUN(__glewMaterialx) -#define glMaterialxv GLEW_GET_FUN(__glewMaterialxv) -#define glMultMatrixx GLEW_GET_FUN(__glewMultMatrixx) -#define glMultiTexCoord4x GLEW_GET_FUN(__glewMultiTexCoord4x) -#define glNormal3x GLEW_GET_FUN(__glewNormal3x) -#define glOrthof GLEW_GET_FUN(__glewOrthof) -#define glOrthox GLEW_GET_FUN(__glewOrthox) -#define glPointSizex GLEW_GET_FUN(__glewPointSizex) -#define glPolygonOffsetx GLEW_GET_FUN(__glewPolygonOffsetx) -#define glRotatex GLEW_GET_FUN(__glewRotatex) -#define glSampleCoveragex GLEW_GET_FUN(__glewSampleCoveragex) -#define glScalex GLEW_GET_FUN(__glewScalex) -#define glTexEnvx GLEW_GET_FUN(__glewTexEnvx) -#define glTexEnvxv GLEW_GET_FUN(__glewTexEnvxv) -#define glTexParameterx GLEW_GET_FUN(__glewTexParameterx) -#define glTranslatex GLEW_GET_FUN(__glewTranslatex) - -#define GLEW_REGAL_ES1_0_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_0_compatibility) - -#endif /* GL_REGAL_ES1_0_compatibility */ - -/* ---------------------- GL_REGAL_ES1_1_compatibility --------------------- */ - -#ifndef GL_REGAL_ES1_1_compatibility -#define GL_REGAL_ES1_1_compatibility 1 - -typedef void (GLAPIENTRY * PFNGLCLIPPLANEFPROC) (GLenum plane, const GLfloat* equation); -typedef void (GLAPIENTRY * PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed* equation); -typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFPROC) (GLenum pname, GLfloat eqn[4]); -typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEXPROC) (GLenum pname, GLfixed eqn[4]); -typedef void (GLAPIENTRY * PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLGETTEXENVXVPROC) (GLenum env, GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed* params); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed* params); -typedef void (GLAPIENTRY * PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed* params); - -#define glClipPlanef GLEW_GET_FUN(__glewClipPlanef) -#define glClipPlanex GLEW_GET_FUN(__glewClipPlanex) -#define glGetClipPlanef GLEW_GET_FUN(__glewGetClipPlanef) -#define glGetClipPlanex GLEW_GET_FUN(__glewGetClipPlanex) -#define glGetFixedv GLEW_GET_FUN(__glewGetFixedv) -#define glGetLightxv GLEW_GET_FUN(__glewGetLightxv) -#define glGetMaterialxv GLEW_GET_FUN(__glewGetMaterialxv) -#define glGetTexEnvxv GLEW_GET_FUN(__glewGetTexEnvxv) -#define glGetTexParameterxv GLEW_GET_FUN(__glewGetTexParameterxv) -#define glPointParameterx GLEW_GET_FUN(__glewPointParameterx) -#define glPointParameterxv GLEW_GET_FUN(__glewPointParameterxv) -#define glPointSizePointerOES GLEW_GET_FUN(__glewPointSizePointerOES) -#define glTexParameterxv GLEW_GET_FUN(__glewTexParameterxv) - -#define GLEW_REGAL_ES1_1_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_1_compatibility) - -#endif /* GL_REGAL_ES1_1_compatibility */ - -/* ---------------------------- GL_REGAL_enable ---------------------------- */ - -#ifndef GL_REGAL_enable -#define GL_REGAL_enable 1 - -#define GL_ERROR_REGAL 0x9322 -#define GL_DEBUG_REGAL 0x9323 -#define GL_LOG_REGAL 0x9324 -#define GL_EMULATION_REGAL 0x9325 -#define GL_DRIVER_REGAL 0x9326 -#define GL_MISSING_REGAL 0x9360 -#define GL_TRACE_REGAL 0x9361 -#define GL_CACHE_REGAL 0x9362 -#define GL_CODE_REGAL 0x9363 -#define GL_STATISTICS_REGAL 0x9364 - -#define GLEW_REGAL_enable GLEW_GET_VAR(__GLEW_REGAL_enable) - -#endif /* GL_REGAL_enable */ - -/* ------------------------- GL_REGAL_error_string ------------------------- */ - -#ifndef GL_REGAL_error_string -#define GL_REGAL_error_string 1 - -typedef const GLchar* (GLAPIENTRY * PFNGLERRORSTRINGREGALPROC) (GLenum error); - -#define glErrorStringREGAL GLEW_GET_FUN(__glewErrorStringREGAL) - -#define GLEW_REGAL_error_string GLEW_GET_VAR(__GLEW_REGAL_error_string) - -#endif /* GL_REGAL_error_string */ - -/* ------------------------ GL_REGAL_extension_query ----------------------- */ - -#ifndef GL_REGAL_extension_query -#define GL_REGAL_extension_query 1 - -typedef GLboolean (GLAPIENTRY * PFNGLGETEXTENSIONREGALPROC) (const GLchar* ext); -typedef GLboolean (GLAPIENTRY * PFNGLISSUPPORTEDREGALPROC) (const GLchar* ext); - -#define glGetExtensionREGAL GLEW_GET_FUN(__glewGetExtensionREGAL) -#define glIsSupportedREGAL GLEW_GET_FUN(__glewIsSupportedREGAL) - -#define GLEW_REGAL_extension_query GLEW_GET_VAR(__GLEW_REGAL_extension_query) - -#endif /* GL_REGAL_extension_query */ - -/* ------------------------------ GL_REGAL_log ----------------------------- */ - -#ifndef GL_REGAL_log -#define GL_REGAL_log 1 - -#define GL_LOG_ERROR_REGAL 0x9319 -#define GL_LOG_WARNING_REGAL 0x931A -#define GL_LOG_INFO_REGAL 0x931B -#define GL_LOG_APP_REGAL 0x931C -#define GL_LOG_DRIVER_REGAL 0x931D -#define GL_LOG_INTERNAL_REGAL 0x931E -#define GL_LOG_DEBUG_REGAL 0x931F -#define GL_LOG_STATUS_REGAL 0x9320 -#define GL_LOG_HTTP_REGAL 0x9321 - -typedef void (APIENTRY *GLLOGPROCREGAL)(GLenum stream, GLsizei length, const GLchar *message, void *context); - -typedef void (GLAPIENTRY * PFNGLLOGMESSAGECALLBACKREGALPROC) (GLLOGPROCREGAL callback); - -#define glLogMessageCallbackREGAL GLEW_GET_FUN(__glewLogMessageCallbackREGAL) - -#define GLEW_REGAL_log GLEW_GET_VAR(__GLEW_REGAL_log) - -#endif /* GL_REGAL_log */ - -/* ------------------------- GL_REGAL_proc_address ------------------------- */ - -#ifndef GL_REGAL_proc_address -#define GL_REGAL_proc_address 1 - -typedef void * (GLAPIENTRY * PFNGLGETPROCADDRESSREGALPROC) (const GLchar *name); - -#define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL) - -#define GLEW_REGAL_proc_address GLEW_GET_VAR(__GLEW_REGAL_proc_address) - -#endif /* GL_REGAL_proc_address */ - -/* ----------------------- GL_REND_screen_coordinates ---------------------- */ - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 - -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 - -#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) - -#endif /* GL_REND_screen_coordinates */ - -/* ------------------------------- GL_S3_s3tc ------------------------------ */ - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 - -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#define GL_RGBA_DXT5_S3TC 0x83A4 -#define GL_RGBA4_DXT5_S3TC 0x83A5 - -#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) - -#endif /* GL_S3_s3tc */ - -/* ------------------------- GL_SGIS_clip_band_hint ------------------------ */ - -#ifndef GL_SGIS_clip_band_hint -#define GL_SGIS_clip_band_hint 1 - -#define GLEW_SGIS_clip_band_hint GLEW_GET_VAR(__GLEW_SGIS_clip_band_hint) - -#endif /* GL_SGIS_clip_band_hint */ - -/* -------------------------- GL_SGIS_color_range -------------------------- */ - -#ifndef GL_SGIS_color_range -#define GL_SGIS_color_range 1 - -#define GL_EXTENDED_RANGE_SGIS 0x85A5 -#define GL_MIN_RED_SGIS 0x85A6 -#define GL_MAX_RED_SGIS 0x85A7 -#define GL_MIN_GREEN_SGIS 0x85A8 -#define GL_MAX_GREEN_SGIS 0x85A9 -#define GL_MIN_BLUE_SGIS 0x85AA -#define GL_MAX_BLUE_SGIS 0x85AB -#define GL_MIN_ALPHA_SGIS 0x85AC -#define GL_MAX_ALPHA_SGIS 0x85AD - -#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) - -#endif /* GL_SGIS_color_range */ - -/* ------------------------- GL_SGIS_detail_texture ------------------------ */ - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 - -typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); - -#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) -#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) - -#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) - -#endif /* GL_SGIS_detail_texture */ - -/* -------------------------- GL_SGIS_fog_function ------------------------- */ - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 - -typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); - -#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) -#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) - -#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) - -#endif /* GL_SGIS_fog_function */ - -/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 - -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 - -#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) - -#endif /* GL_SGIS_generate_mipmap */ - -/* -------------------------- GL_SGIS_line_texgen -------------------------- */ - -#ifndef GL_SGIS_line_texgen -#define GL_SGIS_line_texgen 1 - -#define GLEW_SGIS_line_texgen GLEW_GET_VAR(__GLEW_SGIS_line_texgen) - -#endif /* GL_SGIS_line_texgen */ - -/* -------------------------- GL_SGIS_multisample -------------------------- */ - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 - -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC - -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); - -#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) -#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) - -#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) - -#endif /* GL_SGIS_multisample */ - -/* -------------------------- GL_SGIS_multitexture ------------------------- */ - -#ifndef GL_SGIS_multitexture -#define GL_SGIS_multitexture 1 - -#define GL_SELECTED_TEXTURE_SGIS 0x83C0 -#define GL_SELECTED_TEXTURE_COORD_SET_SGIS 0x83C1 -#define GL_SELECTED_TEXTURE_TRANSFORM_SGIS 0x83C2 -#define GL_MAX_TEXTURES_SGIS 0x83C3 -#define GL_MAX_TEXTURE_COORD_SETS_SGIS 0x83C4 -#define GL_TEXTURE_COORD_SET_INTERLEAVE_FACTOR_SGIS 0x83C5 -#define GL_TEXTURE_ENV_COORD_SET_SGIS 0x83C6 -#define GL_TEXTURE0_SGIS 0x83C7 -#define GL_TEXTURE1_SGIS 0x83C8 -#define GL_TEXTURE2_SGIS 0x83C9 -#define GL_TEXTURE3_SGIS 0x83CA - -typedef void (GLAPIENTRY * PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC) (GLint factor); -typedef void (GLAPIENTRY * PFNGLSELECTTEXTURECOORDSETSGISPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLSELECTTEXTURESGISPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLSELECTTEXTURETRANSFORMSGISPROC) (GLenum target); - -#define glInterleavedTextureCoordSetsSGIS GLEW_GET_FUN(__glewInterleavedTextureCoordSetsSGIS) -#define glSelectTextureCoordSetSGIS GLEW_GET_FUN(__glewSelectTextureCoordSetSGIS) -#define glSelectTextureSGIS GLEW_GET_FUN(__glewSelectTextureSGIS) -#define glSelectTextureTransformSGIS GLEW_GET_FUN(__glewSelectTextureTransformSGIS) - -#define GLEW_SGIS_multitexture GLEW_GET_VAR(__GLEW_SGIS_multitexture) - -#endif /* GL_SGIS_multitexture */ - -/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 - -#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) - -#endif /* GL_SGIS_pixel_texture */ - -/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 - -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 - -#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) - -#endif /* GL_SGIS_point_line_texgen */ - -/* ----------------------- GL_SGIS_shared_multisample ---------------------- */ - -#ifndef GL_SGIS_shared_multisample -#define GL_SGIS_shared_multisample 1 - -typedef void (GLAPIENTRY * PFNGLMULTISAMPLESUBRECTPOSSGISPROC) (GLint x, GLint y); - -#define glMultisampleSubRectPosSGIS GLEW_GET_FUN(__glewMultisampleSubRectPosSGIS) - -#define GLEW_SGIS_shared_multisample GLEW_GET_VAR(__GLEW_SGIS_shared_multisample) - -#endif /* GL_SGIS_shared_multisample */ - -/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 - -typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); -typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); - -#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) -#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) - -#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) - -#endif /* GL_SGIS_sharpen_texture */ - -/* --------------------------- GL_SGIS_texture4D --------------------------- */ - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 - -typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void *pixels); - -#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) -#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) - -#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) - -#endif /* GL_SGIS_texture4D */ - -/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 - -#define GL_CLAMP_TO_BORDER_SGIS 0x812D - -#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) - -#endif /* GL_SGIS_texture_border_clamp */ - -/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 - -#define GL_CLAMP_TO_EDGE_SGIS 0x812F - -#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) - -#endif /* GL_SGIS_texture_edge_clamp */ - -/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 - -typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); -typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); - -#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) -#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) - -#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) - -#endif /* GL_SGIS_texture_filter4 */ - -/* -------------------------- GL_SGIS_texture_lod -------------------------- */ - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 - -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D - -#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) - -#endif /* GL_SGIS_texture_lod */ - -/* ------------------------- GL_SGIS_texture_select ------------------------ */ - -#ifndef GL_SGIS_texture_select -#define GL_SGIS_texture_select 1 - -#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) - -#endif /* GL_SGIS_texture_select */ - -/* ----------------------------- GL_SGIX_async ----------------------------- */ - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 - -#define GL_ASYNC_MARKER_SGIX 0x8329 - -typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); -typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); - -#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) -#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) -#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) -#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) -#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) -#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) - -#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) - -#endif /* GL_SGIX_async */ - -/* ------------------------ GL_SGIX_async_histogram ------------------------ */ - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 - -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D - -#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) - -#endif /* GL_SGIX_async_histogram */ - -/* -------------------------- GL_SGIX_async_pixel -------------------------- */ - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 - -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 - -#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) - -#endif /* GL_SGIX_async_pixel */ - -/* ----------------------- GL_SGIX_bali_g_instruments ---------------------- */ - -#ifndef GL_SGIX_bali_g_instruments -#define GL_SGIX_bali_g_instruments 1 - -#define GL_BALI_NUM_TRIS_CULLED_INSTRUMENT 0x6080 -#define GL_BALI_NUM_PRIMS_CLIPPED_INSTRUMENT 0x6081 -#define GL_BALI_NUM_PRIMS_REJECT_INSTRUMENT 0x6082 -#define GL_BALI_NUM_PRIMS_CLIP_RESULT_INSTRUMENT 0x6083 - -#define GLEW_SGIX_bali_g_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_g_instruments) - -#endif /* GL_SGIX_bali_g_instruments */ - -/* ----------------------- GL_SGIX_bali_r_instruments ---------------------- */ - -#ifndef GL_SGIX_bali_r_instruments -#define GL_SGIX_bali_r_instruments 1 - -#define GL_BALI_FRAGMENTS_GENERATED_INSTRUMENT 0x6090 -#define GL_BALI_DEPTH_PASS_INSTRUMENT 0x6091 -#define GL_BALI_R_CHIP_COUNT 0x6092 - -#define GLEW_SGIX_bali_r_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_r_instruments) - -#endif /* GL_SGIX_bali_r_instruments */ - -/* --------------------- GL_SGIX_bali_timer_instruments -------------------- */ - -#ifndef GL_SGIX_bali_timer_instruments -#define GL_SGIX_bali_timer_instruments 1 - -#define GLEW_SGIX_bali_timer_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_timer_instruments) - -#endif /* GL_SGIX_bali_timer_instruments */ - -/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 - -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 - -#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) - -#endif /* GL_SGIX_blend_alpha_minmax */ - -/* --------------------------- GL_SGIX_blend_cadd -------------------------- */ - -#ifndef GL_SGIX_blend_cadd -#define GL_SGIX_blend_cadd 1 - -#define GL_FUNC_COMPLEX_ADD_EXT 0x601C - -#define GLEW_SGIX_blend_cadd GLEW_GET_VAR(__GLEW_SGIX_blend_cadd) - -#endif /* GL_SGIX_blend_cadd */ - -/* ------------------------ GL_SGIX_blend_cmultiply ------------------------ */ - -#ifndef GL_SGIX_blend_cmultiply -#define GL_SGIX_blend_cmultiply 1 - -#define GL_FUNC_COMPLEX_MULTIPLY_EXT 0x601B - -#define GLEW_SGIX_blend_cmultiply GLEW_GET_VAR(__GLEW_SGIX_blend_cmultiply) - -#endif /* GL_SGIX_blend_cmultiply */ - -/* --------------------- GL_SGIX_calligraphic_fragment --------------------- */ - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 - -#define GLEW_SGIX_calligraphic_fragment GLEW_GET_VAR(__GLEW_SGIX_calligraphic_fragment) - -#endif /* GL_SGIX_calligraphic_fragment */ - -/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 - -#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) - -#endif /* GL_SGIX_clipmap */ - -/* --------------------- GL_SGIX_color_matrix_accuracy --------------------- */ - -#ifndef GL_SGIX_color_matrix_accuracy -#define GL_SGIX_color_matrix_accuracy 1 - -#define GL_COLOR_MATRIX_HINT 0x8317 - -#define GLEW_SGIX_color_matrix_accuracy GLEW_GET_VAR(__GLEW_SGIX_color_matrix_accuracy) - -#endif /* GL_SGIX_color_matrix_accuracy */ - -/* --------------------- GL_SGIX_color_table_index_mode -------------------- */ - -#ifndef GL_SGIX_color_table_index_mode -#define GL_SGIX_color_table_index_mode 1 - -#define GLEW_SGIX_color_table_index_mode GLEW_GET_VAR(__GLEW_SGIX_color_table_index_mode) - -#endif /* GL_SGIX_color_table_index_mode */ - -/* ------------------------- GL_SGIX_complex_polar ------------------------- */ - -#ifndef GL_SGIX_complex_polar -#define GL_SGIX_complex_polar 1 - -#define GLEW_SGIX_complex_polar GLEW_GET_VAR(__GLEW_SGIX_complex_polar) - -#endif /* GL_SGIX_complex_polar */ - -/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 - -#define GL_CONVOLUTION_HINT_SGIX 0x8316 - -#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) - -#endif /* GL_SGIX_convolution_accuracy */ - -/* ---------------------------- GL_SGIX_cube_map --------------------------- */ - -#ifndef GL_SGIX_cube_map -#define GL_SGIX_cube_map 1 - -#define GL_ENV_MAP_SGIX 0x8340 -#define GL_CUBE_MAP_SGIX 0x8341 -#define GL_CUBE_MAP_ZP_SGIX 0x8342 -#define GL_CUBE_MAP_ZN_SGIX 0x8343 -#define GL_CUBE_MAP_XN_SGIX 0x8344 -#define GL_CUBE_MAP_XP_SGIX 0x8345 -#define GL_CUBE_MAP_YN_SGIX 0x8346 -#define GL_CUBE_MAP_YP_SGIX 0x8347 -#define GL_CUBE_MAP_BINDING_SGIX 0x8348 - -#define GLEW_SGIX_cube_map GLEW_GET_VAR(__GLEW_SGIX_cube_map) - -#endif /* GL_SGIX_cube_map */ - -/* ------------------------ GL_SGIX_cylinder_texgen ------------------------ */ - -#ifndef GL_SGIX_cylinder_texgen -#define GL_SGIX_cylinder_texgen 1 - -#define GLEW_SGIX_cylinder_texgen GLEW_GET_VAR(__GLEW_SGIX_cylinder_texgen) - -#endif /* GL_SGIX_cylinder_texgen */ - -/* ---------------------------- GL_SGIX_datapipe --------------------------- */ - -#ifndef GL_SGIX_datapipe -#define GL_SGIX_datapipe 1 - -#define GL_GEOMETRY_BIT 0x1 -#define GL_IMAGE_BIT 0x2 - -typedef void (GLAPIENTRY * PFNGLADDRESSSPACEPROC) (GLenum space, GLbitfield mask); -typedef GLint (GLAPIENTRY * PFNGLDATAPIPEPROC) (GLenum space); - -#define glAddressSpace GLEW_GET_FUN(__glewAddressSpace) -#define glDataPipe GLEW_GET_FUN(__glewDataPipe) - -#define GLEW_SGIX_datapipe GLEW_GET_VAR(__GLEW_SGIX_datapipe) - -#endif /* GL_SGIX_datapipe */ - -/* --------------------------- GL_SGIX_decimation -------------------------- */ - -#ifndef GL_SGIX_decimation -#define GL_SGIX_decimation 1 - -#define GLEW_SGIX_decimation GLEW_GET_VAR(__GLEW_SGIX_decimation) - -#endif /* GL_SGIX_decimation */ - -/* --------------------- GL_SGIX_depth_pass_instrument --------------------- */ - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 - -#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 -#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 -#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 - -#define GLEW_SGIX_depth_pass_instrument GLEW_GET_VAR(__GLEW_SGIX_depth_pass_instrument) - -#endif /* GL_SGIX_depth_pass_instrument */ - -/* ------------------------- GL_SGIX_depth_texture ------------------------- */ - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 - -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 - -#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) - -#endif /* GL_SGIX_depth_texture */ - -/* ------------------------------ GL_SGIX_dvc ------------------------------ */ - -#ifndef GL_SGIX_dvc -#define GL_SGIX_dvc 1 - -#define GLEW_SGIX_dvc GLEW_GET_VAR(__GLEW_SGIX_dvc) - -#endif /* GL_SGIX_dvc */ - -/* -------------------------- GL_SGIX_flush_raster ------------------------- */ - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 - -typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); - -#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) - -#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) - -#endif /* GL_SGIX_flush_raster */ - -/* --------------------------- GL_SGIX_fog_blend --------------------------- */ - -#ifndef GL_SGIX_fog_blend -#define GL_SGIX_fog_blend 1 - -#define GL_FOG_BLEND_ALPHA_SGIX 0x81FE -#define GL_FOG_BLEND_COLOR_SGIX 0x81FF - -#define GLEW_SGIX_fog_blend GLEW_GET_VAR(__GLEW_SGIX_fog_blend) - -#endif /* GL_SGIX_fog_blend */ - -/* ---------------------- GL_SGIX_fog_factor_to_alpha ---------------------- */ - -#ifndef GL_SGIX_fog_factor_to_alpha -#define GL_SGIX_fog_factor_to_alpha 1 - -#define GLEW_SGIX_fog_factor_to_alpha GLEW_GET_VAR(__GLEW_SGIX_fog_factor_to_alpha) - -#endif /* GL_SGIX_fog_factor_to_alpha */ - -/* --------------------------- GL_SGIX_fog_layers -------------------------- */ - -#ifndef GL_SGIX_fog_layers -#define GL_SGIX_fog_layers 1 - -#define GL_FOG_TYPE_SGIX 0x8323 -#define GL_UNIFORM_SGIX 0x8324 -#define GL_LAYERED_SGIX 0x8325 -#define GL_FOG_GROUND_PLANE_SGIX 0x8326 -#define GL_FOG_LAYERS_POINTS_SGIX 0x8327 -#define GL_MAX_FOG_LAYERS_POINTS_SGIX 0x8328 - -typedef void (GLAPIENTRY * PFNGLFOGLAYERSSGIXPROC) (GLsizei n, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLGETFOGLAYERSSGIXPROC) (GLfloat* points); - -#define glFogLayersSGIX GLEW_GET_FUN(__glewFogLayersSGIX) -#define glGetFogLayersSGIX GLEW_GET_FUN(__glewGetFogLayersSGIX) - -#define GLEW_SGIX_fog_layers GLEW_GET_VAR(__GLEW_SGIX_fog_layers) - -#endif /* GL_SGIX_fog_layers */ - -/* --------------------------- GL_SGIX_fog_offset -------------------------- */ - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 - -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 - -#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) - -#endif /* GL_SGIX_fog_offset */ - -/* --------------------------- GL_SGIX_fog_patchy -------------------------- */ - -#ifndef GL_SGIX_fog_patchy -#define GL_SGIX_fog_patchy 1 - -#define GLEW_SGIX_fog_patchy GLEW_GET_VAR(__GLEW_SGIX_fog_patchy) - -#endif /* GL_SGIX_fog_patchy */ - -/* --------------------------- GL_SGIX_fog_scale --------------------------- */ - -#ifndef GL_SGIX_fog_scale -#define GL_SGIX_fog_scale 1 - -#define GL_FOG_SCALE_SGIX 0x81FC -#define GL_FOG_SCALE_VALUE_SGIX 0x81FD - -#define GLEW_SGIX_fog_scale GLEW_GET_VAR(__GLEW_SGIX_fog_scale) - -#endif /* GL_SGIX_fog_scale */ - -/* -------------------------- GL_SGIX_fog_texture -------------------------- */ - -#ifndef GL_SGIX_fog_texture -#define GL_SGIX_fog_texture 1 - -typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); - -#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) - -#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) - -#endif /* GL_SGIX_fog_texture */ - -/* -------------------- GL_SGIX_fragment_lighting_space -------------------- */ - -#ifndef GL_SGIX_fragment_lighting_space -#define GL_SGIX_fragment_lighting_space 1 - -#define GL_EYE_SPACE_SGIX 0x8436 -#define GL_TANGENT_SPACE_SGIX 0x8437 -#define GL_OBJECT_SPACE_SGIX 0x8438 -#define GL_FRAGMENT_LIGHT_SPACE_SGIX 0x843D - -#define GLEW_SGIX_fragment_lighting_space GLEW_GET_VAR(__GLEW_SGIX_fragment_lighting_space) - -#endif /* GL_SGIX_fragment_lighting_space */ - -/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ - -#ifndef GL_SGIX_fragment_specular_lighting -#define GL_SGIX_fragment_specular_lighting 1 - -typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint* data); - -#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) -#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) -#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) -#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) -#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) -#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) -#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) -#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) -#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) -#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) -#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) -#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) -#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) -#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) -#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) -#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) -#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) - -#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) - -#endif /* GL_SGIX_fragment_specular_lighting */ - -/* ---------------------- GL_SGIX_fragments_instrument --------------------- */ - -#ifndef GL_SGIX_fragments_instrument -#define GL_SGIX_fragments_instrument 1 - -#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313 -#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314 -#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315 - -#define GLEW_SGIX_fragments_instrument GLEW_GET_VAR(__GLEW_SGIX_fragments_instrument) - -#endif /* GL_SGIX_fragments_instrument */ - -/* --------------------------- GL_SGIX_framezoom --------------------------- */ - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 - -typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); - -#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) - -#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) - -#endif /* GL_SGIX_framezoom */ - -/* -------------------------- GL_SGIX_icc_texture -------------------------- */ - -#ifndef GL_SGIX_icc_texture -#define GL_SGIX_icc_texture 1 - -#define GL_RGB_ICC_SGIX 0x8460 -#define GL_RGBA_ICC_SGIX 0x8461 -#define GL_ALPHA_ICC_SGIX 0x8462 -#define GL_LUMINANCE_ICC_SGIX 0x8463 -#define GL_INTENSITY_ICC_SGIX 0x8464 -#define GL_LUMINANCE_ALPHA_ICC_SGIX 0x8465 -#define GL_R5_G6_B5_ICC_SGIX 0x8466 -#define GL_R5_G6_B5_A8_ICC_SGIX 0x8467 -#define GL_ALPHA16_ICC_SGIX 0x8468 -#define GL_LUMINANCE16_ICC_SGIX 0x8469 -#define GL_INTENSITY16_ICC_SGIX 0x846A -#define GL_LUMINANCE16_ALPHA8_ICC_SGIX 0x846B - -#define GLEW_SGIX_icc_texture GLEW_GET_VAR(__GLEW_SGIX_icc_texture) - -#endif /* GL_SGIX_icc_texture */ - -/* ------------------------ GL_SGIX_igloo_interface ------------------------ */ - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 - -#define GL_IGLOO_FULLSCREEN_SGIX 0x819E -#define GL_IGLOO_VIEWPORT_OFFSET_SGIX 0x819F -#define GL_IGLOO_SWAPTMESH_SGIX 0x81A0 -#define GL_IGLOO_COLORNORMAL_SGIX 0x81A1 -#define GL_IGLOO_IRISGL_MODE_SGIX 0x81A2 -#define GL_IGLOO_LMC_COLOR_SGIX 0x81A3 -#define GL_IGLOO_TMESHMODE_SGIX 0x81A4 -#define GL_LIGHT31 0xBEAD - -typedef void (GLAPIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, void *param); - -#define glIglooInterfaceSGIX GLEW_GET_FUN(__glewIglooInterfaceSGIX) - -#define GLEW_SGIX_igloo_interface GLEW_GET_VAR(__GLEW_SGIX_igloo_interface) - -#endif /* GL_SGIX_igloo_interface */ - -/* ----------------------- GL_SGIX_image_compression ----------------------- */ - -#ifndef GL_SGIX_image_compression -#define GL_SGIX_image_compression 1 - -#define GLEW_SGIX_image_compression GLEW_GET_VAR(__GLEW_SGIX_image_compression) - -#endif /* GL_SGIX_image_compression */ - -/* ---------------------- GL_SGIX_impact_pixel_texture --------------------- */ - -#ifndef GL_SGIX_impact_pixel_texture -#define GL_SGIX_impact_pixel_texture 1 - -#define GLEW_SGIX_impact_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_impact_pixel_texture) - -#endif /* GL_SGIX_impact_pixel_texture */ - -/* ------------------------ GL_SGIX_instrument_error ----------------------- */ - -#ifndef GL_SGIX_instrument_error -#define GL_SGIX_instrument_error 1 - -#define GLEW_SGIX_instrument_error GLEW_GET_VAR(__GLEW_SGIX_instrument_error) - -#endif /* GL_SGIX_instrument_error */ - -/* --------------------------- GL_SGIX_interlace --------------------------- */ - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 - -#define GL_INTERLACE_SGIX 0x8094 - -#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) - -#endif /* GL_SGIX_interlace */ - -/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 - -#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) - -#endif /* GL_SGIX_ir_instrument1 */ - -/* ----------------------- GL_SGIX_line_quality_hint ----------------------- */ - -#ifndef GL_SGIX_line_quality_hint -#define GL_SGIX_line_quality_hint 1 - -#define GL_LINE_QUALITY_HINT_SGIX 0x835B - -#define GLEW_SGIX_line_quality_hint GLEW_GET_VAR(__GLEW_SGIX_line_quality_hint) - -#endif /* GL_SGIX_line_quality_hint */ - -/* ------------------------- GL_SGIX_list_priority ------------------------- */ - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 - -#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) - -#endif /* GL_SGIX_list_priority */ - -/* ----------------------------- GL_SGIX_mpeg1 ----------------------------- */ - -#ifndef GL_SGIX_mpeg1 -#define GL_SGIX_mpeg1 1 - -typedef void (GLAPIENTRY * PFNGLALLOCMPEGPREDICTORSSGIXPROC) (GLsizei width, GLsizei height, GLsizei n, GLuint* predictors); -typedef void (GLAPIENTRY * PFNGLDELETEMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors); -typedef void (GLAPIENTRY * PFNGLGENMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors); -typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERFVSGIXPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERIVSGIXPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels); -typedef void (GLAPIENTRY * PFNGLGETMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values); -typedef GLboolean (GLAPIENTRY * PFNGLISMPEGPREDICTORSGIXPROC) (GLuint predictor); -typedef void (GLAPIENTRY * PFNGLMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels); -typedef void (GLAPIENTRY * PFNGLMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values); -typedef void (GLAPIENTRY * PFNGLSWAPMPEGPREDICTORSSGIXPROC) (GLenum target0, GLenum target1); - -#define glAllocMPEGPredictorsSGIX GLEW_GET_FUN(__glewAllocMPEGPredictorsSGIX) -#define glDeleteMPEGPredictorsSGIX GLEW_GET_FUN(__glewDeleteMPEGPredictorsSGIX) -#define glGenMPEGPredictorsSGIX GLEW_GET_FUN(__glewGenMPEGPredictorsSGIX) -#define glGetMPEGParameterfvSGIX GLEW_GET_FUN(__glewGetMPEGParameterfvSGIX) -#define glGetMPEGParameterivSGIX GLEW_GET_FUN(__glewGetMPEGParameterivSGIX) -#define glGetMPEGPredictorSGIX GLEW_GET_FUN(__glewGetMPEGPredictorSGIX) -#define glGetMPEGQuantTableubv GLEW_GET_FUN(__glewGetMPEGQuantTableubv) -#define glIsMPEGPredictorSGIX GLEW_GET_FUN(__glewIsMPEGPredictorSGIX) -#define glMPEGPredictorSGIX GLEW_GET_FUN(__glewMPEGPredictorSGIX) -#define glMPEGQuantTableubv GLEW_GET_FUN(__glewMPEGQuantTableubv) -#define glSwapMPEGPredictorsSGIX GLEW_GET_FUN(__glewSwapMPEGPredictorsSGIX) - -#define GLEW_SGIX_mpeg1 GLEW_GET_VAR(__GLEW_SGIX_mpeg1) - -#endif /* GL_SGIX_mpeg1 */ - -/* ----------------------------- GL_SGIX_mpeg2 ----------------------------- */ - -#ifndef GL_SGIX_mpeg2 -#define GL_SGIX_mpeg2 1 - -#define GLEW_SGIX_mpeg2 GLEW_GET_VAR(__GLEW_SGIX_mpeg2) - -#endif /* GL_SGIX_mpeg2 */ - -/* ------------------ GL_SGIX_nonlinear_lighting_pervertex ----------------- */ - -#ifndef GL_SGIX_nonlinear_lighting_pervertex -#define GL_SGIX_nonlinear_lighting_pervertex 1 - -typedef void (GLAPIENTRY * PFNGLGETNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint* terms, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint* terms, const GLfloat *data); -typedef void (GLAPIENTRY * PFNGLNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint terms, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint terms, const GLfloat* params); - -#define glGetNonlinLightfvSGIX GLEW_GET_FUN(__glewGetNonlinLightfvSGIX) -#define glGetNonlinMaterialfvSGIX GLEW_GET_FUN(__glewGetNonlinMaterialfvSGIX) -#define glNonlinLightfvSGIX GLEW_GET_FUN(__glewNonlinLightfvSGIX) -#define glNonlinMaterialfvSGIX GLEW_GET_FUN(__glewNonlinMaterialfvSGIX) - -#define GLEW_SGIX_nonlinear_lighting_pervertex GLEW_GET_VAR(__GLEW_SGIX_nonlinear_lighting_pervertex) - -#endif /* GL_SGIX_nonlinear_lighting_pervertex */ - -/* --------------------------- GL_SGIX_nurbs_eval -------------------------- */ - -#ifndef GL_SGIX_nurbs_eval -#define GL_SGIX_nurbs_eval 1 - -#define GL_MAP1_VERTEX_3_NURBS_SGIX 0x81CB -#define GL_MAP1_VERTEX_4_NURBS_SGIX 0x81CC -#define GL_MAP1_INDEX_NURBS_SGIX 0x81CD -#define GL_MAP1_COLOR_4_NURBS_SGIX 0x81CE -#define GL_MAP1_NORMAL_NURBS_SGIX 0x81CF -#define GL_MAP1_TEXTURE_COORD_1_NURBS_SGIX 0x81E0 -#define GL_MAP1_TEXTURE_COORD_2_NURBS_SGIX 0x81E1 -#define GL_MAP1_TEXTURE_COORD_3_NURBS_SGIX 0x81E2 -#define GL_MAP1_TEXTURE_COORD_4_NURBS_SGIX 0x81E3 -#define GL_MAP2_VERTEX_3_NURBS_SGIX 0x81E4 -#define GL_MAP2_VERTEX_4_NURBS_SGIX 0x81E5 -#define GL_MAP2_INDEX_NURBS_SGIX 0x81E6 -#define GL_MAP2_COLOR_4_NURBS_SGIX 0x81E7 -#define GL_MAP2_NORMAL_NURBS_SGIX 0x81E8 -#define GL_MAP2_TEXTURE_COORD_1_NURBS_SGIX 0x81E9 -#define GL_MAP2_TEXTURE_COORD_2_NURBS_SGIX 0x81EA -#define GL_MAP2_TEXTURE_COORD_3_NURBS_SGIX 0x81EB -#define GL_MAP2_TEXTURE_COORD_4_NURBS_SGIX 0x81EC -#define GL_NURBS_KNOT_COUNT_SGIX 0x81ED -#define GL_NURBS_KNOT_VECTOR_SGIX 0x81EE - -#define GLEW_SGIX_nurbs_eval GLEW_GET_VAR(__GLEW_SGIX_nurbs_eval) - -#endif /* GL_SGIX_nurbs_eval */ - -/* ---------------------- GL_SGIX_occlusion_instrument --------------------- */ - -#ifndef GL_SGIX_occlusion_instrument -#define GL_SGIX_occlusion_instrument 1 - -#define GL_OCCLUSION_INSTRUMENT_SGIX 0x6060 - -#define GLEW_SGIX_occlusion_instrument GLEW_GET_VAR(__GLEW_SGIX_occlusion_instrument) - -#endif /* GL_SGIX_occlusion_instrument */ - -/* ------------------------- GL_SGIX_packed_6bytes ------------------------- */ - -#ifndef GL_SGIX_packed_6bytes -#define GL_SGIX_packed_6bytes 1 - -#define GLEW_SGIX_packed_6bytes GLEW_GET_VAR(__GLEW_SGIX_packed_6bytes) - -#endif /* GL_SGIX_packed_6bytes */ - -/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 - -typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); - -#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) - -#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) - -#endif /* GL_SGIX_pixel_texture */ - -/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ - -#ifndef GL_SGIX_pixel_texture_bits -#define GL_SGIX_pixel_texture_bits 1 - -#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) - -#endif /* GL_SGIX_pixel_texture_bits */ - -/* ----------------------- GL_SGIX_pixel_texture_lod ----------------------- */ - -#ifndef GL_SGIX_pixel_texture_lod -#define GL_SGIX_pixel_texture_lod 1 - -#define GLEW_SGIX_pixel_texture_lod GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_lod) - -#endif /* GL_SGIX_pixel_texture_lod */ - -/* -------------------------- GL_SGIX_pixel_tiles -------------------------- */ - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 - -#define GLEW_SGIX_pixel_tiles GLEW_GET_VAR(__GLEW_SGIX_pixel_tiles) - -#endif /* GL_SGIX_pixel_tiles */ - -/* ------------------------- GL_SGIX_polynomial_ffd ------------------------ */ - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 - -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x1 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x2 - -typedef void (GLAPIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); - -#define glDeformSGIX GLEW_GET_FUN(__glewDeformSGIX) -#define glLoadIdentityDeformationMapSGIX GLEW_GET_FUN(__glewLoadIdentityDeformationMapSGIX) - -#define GLEW_SGIX_polynomial_ffd GLEW_GET_VAR(__GLEW_SGIX_polynomial_ffd) - -#endif /* GL_SGIX_polynomial_ffd */ - -/* --------------------------- GL_SGIX_quad_mesh --------------------------- */ - -#ifndef GL_SGIX_quad_mesh -#define GL_SGIX_quad_mesh 1 - -typedef void (GLAPIENTRY * PFNGLMESHBREADTHSGIXPROC) (GLint breadth); -typedef void (GLAPIENTRY * PFNGLMESHSTRIDESGIXPROC) (GLint stride); - -#define glMeshBreadthSGIX GLEW_GET_FUN(__glewMeshBreadthSGIX) -#define glMeshStrideSGIX GLEW_GET_FUN(__glewMeshStrideSGIX) - -#define GLEW_SGIX_quad_mesh GLEW_GET_VAR(__GLEW_SGIX_quad_mesh) - -#endif /* GL_SGIX_quad_mesh */ - -/* ------------------------ GL_SGIX_reference_plane ------------------------ */ - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 - -typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); - -#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) - -#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) - -#endif /* GL_SGIX_reference_plane */ - -/* ---------------------------- GL_SGIX_resample --------------------------- */ - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 - -#define GL_PACK_RESAMPLE_SGIX 0x842E -#define GL_UNPACK_RESAMPLE_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 - -#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) - -#endif /* GL_SGIX_resample */ - -/* ------------------------- GL_SGIX_scalebias_hint ------------------------ */ - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 - -#define GL_SCALEBIAS_HINT_SGIX 0x8322 - -#define GLEW_SGIX_scalebias_hint GLEW_GET_VAR(__GLEW_SGIX_scalebias_hint) - -#endif /* GL_SGIX_scalebias_hint */ - -/* ----------------------------- GL_SGIX_shadow ---------------------------- */ - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 - -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D - -#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) - -#endif /* GL_SGIX_shadow */ - -/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 - -#define GL_SHADOW_AMBIENT_SGIX 0x80BF - -#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) - -#endif /* GL_SGIX_shadow_ambient */ - -/* ------------------------------ GL_SGIX_slim ----------------------------- */ - -#ifndef GL_SGIX_slim -#define GL_SGIX_slim 1 - -#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B -#define GL_SLIM8U_SGIX 0x831D -#define GL_SLIM10U_SGIX 0x831E -#define GL_SLIM12S_SGIX 0x831F - -#define GLEW_SGIX_slim GLEW_GET_VAR(__GLEW_SGIX_slim) - -#endif /* GL_SGIX_slim */ - -/* ------------------------ GL_SGIX_spotlight_cutoff ----------------------- */ - -#ifndef GL_SGIX_spotlight_cutoff -#define GL_SGIX_spotlight_cutoff 1 - -#define GL_SPOT_CUTOFF_DELTA_SGIX 0x8193 - -#define GLEW_SGIX_spotlight_cutoff GLEW_GET_VAR(__GLEW_SGIX_spotlight_cutoff) - -#endif /* GL_SGIX_spotlight_cutoff */ - -/* ----------------------------- GL_SGIX_sprite ---------------------------- */ - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 - -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); - -#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) -#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) -#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) -#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) - -#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) - -#endif /* GL_SGIX_sprite */ - -/* -------------------------- GL_SGIX_subdiv_patch ------------------------- */ - -#ifndef GL_SGIX_subdiv_patch -#define GL_SGIX_subdiv_patch 1 - -#define GLEW_SGIX_subdiv_patch GLEW_GET_VAR(__GLEW_SGIX_subdiv_patch) - -#endif /* GL_SGIX_subdiv_patch */ - -/* --------------------------- GL_SGIX_subsample --------------------------- */ - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 - -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 - -#define GLEW_SGIX_subsample GLEW_GET_VAR(__GLEW_SGIX_subsample) - -#endif /* GL_SGIX_subsample */ - -/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 - -typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); - -#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) - -#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) - -#endif /* GL_SGIX_tag_sample_buffer */ - -/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 - -#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) - -#endif /* GL_SGIX_texture_add_env */ - -/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 - -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B - -#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) - -#endif /* GL_SGIX_texture_coordinate_clamp */ - -/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 - -#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) - -#endif /* GL_SGIX_texture_lod_bias */ - -/* ------------------- GL_SGIX_texture_mipmap_anisotropic ------------------ */ - -#ifndef GL_SGIX_texture_mipmap_anisotropic -#define GL_SGIX_texture_mipmap_anisotropic 1 - -#define GL_TEXTURE_MIPMAP_ANISOTROPY_SGIX 0x832E -#define GL_MAX_MIPMAP_ANISOTROPY_SGIX 0x832F - -#define GLEW_SGIX_texture_mipmap_anisotropic GLEW_GET_VAR(__GLEW_SGIX_texture_mipmap_anisotropic) - -#endif /* GL_SGIX_texture_mipmap_anisotropic */ - -/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 - -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E - -#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) - -#endif /* GL_SGIX_texture_multi_buffer */ - -/* ------------------------- GL_SGIX_texture_phase ------------------------- */ - -#ifndef GL_SGIX_texture_phase -#define GL_SGIX_texture_phase 1 - -#define GL_PHASE_SGIX 0x832A - -#define GLEW_SGIX_texture_phase GLEW_GET_VAR(__GLEW_SGIX_texture_phase) - -#endif /* GL_SGIX_texture_phase */ - -/* ------------------------- GL_SGIX_texture_range ------------------------- */ - -#ifndef GL_SGIX_texture_range -#define GL_SGIX_texture_range 1 - -#define GL_RGB_SIGNED_SGIX 0x85E0 -#define GL_RGBA_SIGNED_SGIX 0x85E1 -#define GL_ALPHA_SIGNED_SGIX 0x85E2 -#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 -#define GL_INTENSITY_SIGNED_SGIX 0x85E4 -#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 -#define GL_RGB16_SIGNED_SGIX 0x85E6 -#define GL_RGBA16_SIGNED_SGIX 0x85E7 -#define GL_ALPHA16_SIGNED_SGIX 0x85E8 -#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 -#define GL_INTENSITY16_SIGNED_SGIX 0x85EA -#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB -#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC -#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED -#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE -#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF -#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 -#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 -#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 -#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 -#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 -#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 -#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 -#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 -#define GL_MIN_LUMINANCE_SGIS 0x85F8 -#define GL_MAX_LUMINANCE_SGIS 0x85F9 -#define GL_MIN_INTENSITY_SGIS 0x85FA -#define GL_MAX_INTENSITY_SGIS 0x85FB - -#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) - -#endif /* GL_SGIX_texture_range */ - -/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 - -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C - -#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) - -#endif /* GL_SGIX_texture_scale_bias */ - -/* ---------------------- GL_SGIX_texture_supersample ---------------------- */ - -#ifndef GL_SGIX_texture_supersample -#define GL_SGIX_texture_supersample 1 - -#define GLEW_SGIX_texture_supersample GLEW_GET_VAR(__GLEW_SGIX_texture_supersample) - -#endif /* GL_SGIX_texture_supersample */ - -/* --------------------------- GL_SGIX_vector_ops -------------------------- */ - -#ifndef GL_SGIX_vector_ops -#define GL_SGIX_vector_ops 1 - -typedef void (GLAPIENTRY * PFNGLGETVECTOROPERATIONSGIXPROC) (GLenum operation); -typedef void (GLAPIENTRY * PFNGLVECTOROPERATIONSGIXPROC) (GLenum operation); - -#define glGetVectorOperationSGIX GLEW_GET_FUN(__glewGetVectorOperationSGIX) -#define glVectorOperationSGIX GLEW_GET_FUN(__glewVectorOperationSGIX) - -#define GLEW_SGIX_vector_ops GLEW_GET_VAR(__GLEW_SGIX_vector_ops) - -#endif /* GL_SGIX_vector_ops */ - -/* ---------------------- GL_SGIX_vertex_array_object ---------------------- */ - -#ifndef GL_SGIX_vertex_array_object -#define GL_SGIX_vertex_array_object 1 - -typedef GLboolean (GLAPIENTRY * PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC) (GLsizei n, const GLuint* arrays, GLboolean* residences); -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYSGIXPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSSGIXPROC) (GLsizei n, GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYSGIXPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays, const GLclampf* priorities); - -#define glAreVertexArraysResidentSGIX GLEW_GET_FUN(__glewAreVertexArraysResidentSGIX) -#define glBindVertexArraySGIX GLEW_GET_FUN(__glewBindVertexArraySGIX) -#define glDeleteVertexArraysSGIX GLEW_GET_FUN(__glewDeleteVertexArraysSGIX) -#define glGenVertexArraysSGIX GLEW_GET_FUN(__glewGenVertexArraysSGIX) -#define glIsVertexArraySGIX GLEW_GET_FUN(__glewIsVertexArraySGIX) -#define glPrioritizeVertexArraysSGIX GLEW_GET_FUN(__glewPrioritizeVertexArraysSGIX) - -#define GLEW_SGIX_vertex_array_object GLEW_GET_VAR(__GLEW_SGIX_vertex_array_object) - -#endif /* GL_SGIX_vertex_array_object */ - -/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 - -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF - -#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) - -#endif /* GL_SGIX_vertex_preclip */ - -/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ - -#ifndef GL_SGIX_vertex_preclip_hint -#define GL_SGIX_vertex_preclip_hint 1 - -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF - -#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) - -#endif /* GL_SGIX_vertex_preclip_hint */ - -/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 - -#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) - -#endif /* GL_SGIX_ycrcb */ - -/* ------------------------ GL_SGIX_ycrcb_subsample ------------------------ */ - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 - -#define GLEW_SGIX_ycrcb_subsample GLEW_GET_VAR(__GLEW_SGIX_ycrcb_subsample) - -#endif /* GL_SGIX_ycrcb_subsample */ - -/* ----------------------------- GL_SGIX_ycrcba ---------------------------- */ - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 - -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 - -#define GLEW_SGIX_ycrcba GLEW_GET_VAR(__GLEW_SGIX_ycrcba) - -#endif /* GL_SGIX_ycrcba */ - -/* -------------------------- GL_SGI_color_matrix -------------------------- */ - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 - -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB - -#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) - -#endif /* GL_SGI_color_matrix */ - -/* --------------------------- GL_SGI_color_table -------------------------- */ - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 - -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF - -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); - -#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) -#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) -#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) -#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) -#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) -#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) -#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) - -#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) - -#endif /* GL_SGI_color_table */ - -/* ----------------------------- GL_SGI_complex ---------------------------- */ - -#ifndef GL_SGI_complex -#define GL_SGI_complex 1 - -#define GLEW_SGI_complex GLEW_GET_VAR(__GLEW_SGI_complex) - -#endif /* GL_SGI_complex */ - -/* -------------------------- GL_SGI_complex_type -------------------------- */ - -#ifndef GL_SGI_complex_type -#define GL_SGI_complex_type 1 - -#define GL_COMPLEX_UNSIGNED_BYTE_SGI 0x81BD -#define GL_COMPLEX_BYTE_SGI 0x81BE -#define GL_COMPLEX_UNSIGNED_SHORT_SGI 0x81BF -#define GL_COMPLEX_SHORT_SGI 0x81C0 -#define GL_COMPLEX_UNSIGNED_INT_SGI 0x81C1 -#define GL_COMPLEX_INT_SGI 0x81C2 -#define GL_COMPLEX_FLOAT_SGI 0x81C3 - -#define GLEW_SGI_complex_type GLEW_GET_VAR(__GLEW_SGI_complex_type) - -#endif /* GL_SGI_complex_type */ - -/* ------------------------------- GL_SGI_fft ------------------------------ */ - -#ifndef GL_SGI_fft -#define GL_SGI_fft 1 - -#define GL_PIXEL_TRANSFORM_OPERATOR_SGI 0x81C4 -#define GL_CONVOLUTION_SGI 0x81C5 -#define GL_FFT_1D_SGI 0x81C6 -#define GL_PIXEL_TRANSFORM_SGI 0x81C7 -#define GL_MAX_FFT_WIDTH_SGI 0x81C8 - -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFSGIPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERISGIPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMSGIPROC) (GLenum target); - -#define glGetPixelTransformParameterfvSGI GLEW_GET_FUN(__glewGetPixelTransformParameterfvSGI) -#define glGetPixelTransformParameterivSGI GLEW_GET_FUN(__glewGetPixelTransformParameterivSGI) -#define glPixelTransformParameterfSGI GLEW_GET_FUN(__glewPixelTransformParameterfSGI) -#define glPixelTransformParameterfvSGI GLEW_GET_FUN(__glewPixelTransformParameterfvSGI) -#define glPixelTransformParameteriSGI GLEW_GET_FUN(__glewPixelTransformParameteriSGI) -#define glPixelTransformParameterivSGI GLEW_GET_FUN(__glewPixelTransformParameterivSGI) -#define glPixelTransformSGI GLEW_GET_FUN(__glewPixelTransformSGI) - -#define GLEW_SGI_fft GLEW_GET_VAR(__GLEW_SGI_fft) - -#endif /* GL_SGI_fft */ - -/* ----------------------- GL_SGI_texture_color_table ---------------------- */ - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 - -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD - -#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) - -#endif /* GL_SGI_texture_color_table */ - -/* ------------------------- GL_SUNX_constant_data ------------------------- */ - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 - -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 - -typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); - -#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) - -#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) - -#endif /* GL_SUNX_constant_data */ - -/* -------------------- GL_SUN_convolution_border_modes -------------------- */ - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 - -#define GL_WRAP_BORDER_SUN 0x81D4 - -#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) - -#endif /* GL_SUN_convolution_border_modes */ - -/* -------------------------- GL_SUN_global_alpha -------------------------- */ - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 - -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA - -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); - -#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) -#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) -#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) -#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) -#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) -#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) -#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) -#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) - -#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) - -#endif /* GL_SUN_global_alpha */ - -/* --------------------------- GL_SUN_mesh_array --------------------------- */ - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 - -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 - -#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) - -#endif /* GL_SUN_mesh_array */ - -/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ - -#ifndef GL_SUN_read_video_pixels -#define GL_SUN_read_video_pixels 1 - -typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); - -#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) - -#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) - -#endif /* GL_SUN_read_video_pixels */ - -/* --------------------------- GL_SUN_slice_accum -------------------------- */ - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 - -#define GL_SLICE_ACCUM_SUN 0x85CC - -#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) - -#endif /* GL_SUN_slice_accum */ - -/* -------------------------- GL_SUN_triangle_list ------------------------- */ - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 - -#define GL_RESTART_SUN 0x01 -#define GL_REPLACE_MIDDLE_SUN 0x02 -#define GL_REPLACE_OLDEST_SUN 0x03 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB - -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); - -#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) -#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) -#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) -#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) -#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) -#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) -#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) - -#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) - -#endif /* GL_SUN_triangle_list */ - -/* ----------------------------- GL_SUN_vertex ----------------------------- */ - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 - -typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); - -#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) -#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) -#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) -#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) -#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) -#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) -#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) -#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) -#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) -#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) -#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) -#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) -#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) -#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) -#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) -#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) -#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) -#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) -#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) -#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) -#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) -#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) -#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) -#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) -#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) -#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) -#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) -#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) -#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) -#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) -#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) -#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) -#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) -#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) - -#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) - -#endif /* GL_SUN_vertex */ - -/* -------------------------- GL_VIV_shader_binary ------------------------- */ - -#ifndef GL_VIV_shader_binary -#define GL_VIV_shader_binary 1 - -#define GL_SHADER_BINARY_VIV 0x8FC4 - -#define GLEW_VIV_shader_binary GLEW_GET_VAR(__GLEW_VIV_shader_binary) - -#endif /* GL_VIV_shader_binary */ - -/* -------------------------- GL_WIN_phong_shading ------------------------- */ - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 - -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB - -#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) - -#endif /* GL_WIN_phong_shading */ - -/* ------------------------- GL_WIN_scene_markerXXX ------------------------ */ - -#ifndef GL_WIN_scene_markerXXX -#define GL_WIN_scene_markerXXX 1 - -#define GLEW_WIN_scene_markerXXX GLEW_GET_VAR(__GLEW_WIN_scene_markerXXX) - -#endif /* GL_WIN_scene_markerXXX */ - -/* -------------------------- GL_WIN_specular_fog -------------------------- */ - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 - -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC - -#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) - -#endif /* GL_WIN_specular_fog */ - -/* ---------------------------- GL_WIN_swap_hint --------------------------- */ - -#ifndef GL_WIN_swap_hint -#define GL_WIN_swap_hint 1 - -typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); - -#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) - -#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) - -#endif /* GL_WIN_swap_hint */ - -/* ------------------------------------------------------------------------- */ - - - -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; - -GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; -GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; -GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; - -GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; -GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; -GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; -GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; -GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; -GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; -GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; -GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; -GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; -GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; -GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; -GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; -GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; -GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; -GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; -GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; -GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; - -GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; -GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; -GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; -GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; -GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; -GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; -GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; -GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; -GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; -GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; -GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; -GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; -GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; -GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; -GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; -GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; -GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; -GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; -GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; -GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; -GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; -GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; -GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; -GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; -GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; -GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; -GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; -GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; -GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; -GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; -GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; -GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; -GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; -GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; -GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; -GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; -GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; -GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; -GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; -GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; -GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; -GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; - -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; - -GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; -GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; -GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; -GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; -GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; -GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; -GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; -GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; -GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; -GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced; -GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex; -GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture; -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v; -GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v; - -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei; -GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci; -GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading; - -GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSPROC __glewGetGraphicsResetStatus; -GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEPROC __glewGetnCompressedTexImage; -GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEPROC __glewGetnTexImage; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVPROC __glewGetnUniformdv; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC __glewMultiDrawArraysIndirectCount; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC __glewMultiDrawElementsIndirectCount; -GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERPROC __glewSpecializeShader; - -GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; - -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD; -GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD; -GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD; - -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC __glewNamedRenderbufferStorageMultisampleAdvancedAMD; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC __glewRenderbufferStorageMultisampleAdvancedAMD; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewFramebufferSamplePositionsfvAMD; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC __glewGetFramebufferParameterfvAMD; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC __glewGetNamedFramebufferParameterfvAMD; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewNamedFramebufferSamplePositionsfvAMD; - -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD; - -GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD; -GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD; -GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD; - -GLEW_FUN_EXPORT PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD; - -GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD; -GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD; -GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD; -GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD; -GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD; -GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD; - -GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD; - -GLEW_FUN_EXPORT PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD; - -GLEW_FUN_EXPORT PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD; - -GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD; -GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD; - -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE; -GLEW_FUN_EXPORT PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE; -GLEW_FUN_EXPORT PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE; -GLEW_FUN_EXPORT PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE; -GLEW_FUN_EXPORT PFNGLISQUERYANGLEPROC __glewIsQueryANGLE; -GLEW_FUN_EXPORT PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE; - -GLEW_FUN_EXPORT PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE; - -GLEW_FUN_EXPORT PFNGLCOPYTEXTURELEVELSAPPLEPROC __glewCopyTextureLevelsAPPLE; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; - -GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; -GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; -GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; -GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; -GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; -GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; -GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; -GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; - -GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC __glewRenderbufferStorageMultisampleAPPLE; -GLEW_FUN_EXPORT PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC __glewResolveMultisampleFramebufferAPPLE; - -GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE; -GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE; -GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE; - -GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCAPPLEPROC __glewClientWaitSyncAPPLE; -GLEW_FUN_EXPORT PFNGLDELETESYNCAPPLEPROC __glewDeleteSyncAPPLE; -GLEW_FUN_EXPORT PFNGLFENCESYNCAPPLEPROC __glewFenceSyncAPPLE; -GLEW_FUN_EXPORT PFNGLGETINTEGER64VAPPLEPROC __glewGetInteger64vAPPLE; -GLEW_FUN_EXPORT PFNGLGETSYNCIVAPPLEPROC __glewGetSyncivAPPLE; -GLEW_FUN_EXPORT PFNGLISSYNCAPPLEPROC __glewIsSyncAPPLE; -GLEW_FUN_EXPORT PFNGLWAITSYNCAPPLEPROC __glewWaitSyncAPPLE; - -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; -GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; - -GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE; -GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE; -GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE; -GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE; -GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE; -GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE; - -GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef; -GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat; -GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler; -GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary; - -GLEW_FUN_EXPORT PFNGLMEMORYBARRIERBYREGIONPROC __glewMemoryBarrierByRegion; - -GLEW_FUN_EXPORT PFNGLPRIMITIVEBOUNDINGBOXARBPROC __glewPrimitiveBoundingBoxARB; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance; - -GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB; -GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB; -GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB; -GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB; -GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB; -GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB; -GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB; -GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB; -GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB; - -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed; -GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex; - -GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEPROC __glewBufferStorage; - -GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB; - -GLEW_FUN_EXPORT PFNGLCLEARBUFFERDATAPROC __glewClearBufferData; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT; - -GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEPROC __glewClearTexImage; -GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage; - -GLEW_FUN_EXPORT PFNGLCLIPCONTROLPROC __glewClipControl; - -GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; - -GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute; -GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect; - -GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB; - -GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData; - -GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData; - -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB; -GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB; - -GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPROC __glewBindTextureUnit; -GLEW_FUN_EXPORT PFNGLBLITNAMEDFRAMEBUFFERPROC __glewBlitNamedFramebuffer; -GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC __glewCheckNamedFramebufferStatus; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAPROC __glewClearNamedBufferData; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAPROC __glewClearNamedBufferSubData; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFIPROC __glewClearNamedFramebufferfi; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFVPROC __glewClearNamedFramebufferfv; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERIVPROC __glewClearNamedFramebufferiv; -GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC __glewClearNamedFramebufferuiv; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC __glewCompressedTextureSubImage1D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC __glewCompressedTextureSubImage2D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC __glewCompressedTextureSubImage3D; -GLEW_FUN_EXPORT PFNGLCOPYNAMEDBUFFERSUBDATAPROC __glewCopyNamedBufferSubData; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DPROC __glewCopyTextureSubImage1D; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DPROC __glewCopyTextureSubImage2D; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DPROC __glewCopyTextureSubImage3D; -GLEW_FUN_EXPORT PFNGLCREATEBUFFERSPROC __glewCreateBuffers; -GLEW_FUN_EXPORT PFNGLCREATEFRAMEBUFFERSPROC __glewCreateFramebuffers; -GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPIPELINESPROC __glewCreateProgramPipelines; -GLEW_FUN_EXPORT PFNGLCREATEQUERIESPROC __glewCreateQueries; -GLEW_FUN_EXPORT PFNGLCREATERENDERBUFFERSPROC __glewCreateRenderbuffers; -GLEW_FUN_EXPORT PFNGLCREATESAMPLERSPROC __glewCreateSamplers; -GLEW_FUN_EXPORT PFNGLCREATETEXTURESPROC __glewCreateTextures; -GLEW_FUN_EXPORT PFNGLCREATETRANSFORMFEEDBACKSPROC __glewCreateTransformFeedbacks; -GLEW_FUN_EXPORT PFNGLCREATEVERTEXARRAYSPROC __glewCreateVertexArrays; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBPROC __glewDisableVertexArrayAttrib; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBPROC __glewEnableVertexArrayAttrib; -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC __glewFlushMappedNamedBufferRange; -GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPPROC __glewGenerateTextureMipmap; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC __glewGetCompressedTextureImage; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERI64VPROC __glewGetNamedBufferParameteri64v; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVPROC __glewGetNamedBufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVPROC __glewGetNamedBufferPointerv; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAPROC __glewGetNamedBufferSubData; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetNamedFramebufferAttachmentParameteriv; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC __glewGetNamedFramebufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC __glewGetNamedRenderbufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTI64VPROC __glewGetQueryBufferObjecti64v; -GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTIVPROC __glewGetQueryBufferObjectiv; -GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUI64VPROC __glewGetQueryBufferObjectui64v; -GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUIVPROC __glewGetQueryBufferObjectuiv; -GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEPROC __glewGetTextureImage; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVPROC __glewGetTextureLevelParameterfv; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVPROC __glewGetTextureLevelParameteriv; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVPROC __glewGetTextureParameterIiv; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVPROC __glewGetTextureParameterIuiv; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVPROC __glewGetTextureParameterfv; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVPROC __glewGetTextureParameteriv; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI64_VPROC __glewGetTransformFeedbacki64_v; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI_VPROC __glewGetTransformFeedbacki_v; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKIVPROC __glewGetTransformFeedbackiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXED64IVPROC __glewGetVertexArrayIndexed64iv; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXEDIVPROC __glewGetVertexArrayIndexediv; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYIVPROC __glewGetVertexArrayiv; -GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC __glewInvalidateNamedFramebufferData; -GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC __glewInvalidateNamedFramebufferSubData; -GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERPROC __glewMapNamedBuffer; -GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEPROC __glewMapNamedBufferRange; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAPROC __glewNamedBufferData; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEPROC __glewNamedBufferStorage; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAPROC __glewNamedBufferSubData; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC __glewNamedFramebufferDrawBuffer; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC __glewNamedFramebufferDrawBuffers; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC __glewNamedFramebufferParameteri; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC __glewNamedFramebufferReadBuffer; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC __glewNamedFramebufferRenderbuffer; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREPROC __glewNamedFramebufferTexture; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC __glewNamedFramebufferTextureLayer; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEPROC __glewNamedRenderbufferStorage; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewNamedRenderbufferStorageMultisample; -GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERPROC __glewTextureBuffer; -GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEPROC __glewTextureBufferRange; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVPROC __glewTextureParameterIiv; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVPROC __glewTextureParameterIuiv; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFPROC __glewTextureParameterf; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVPROC __glewTextureParameterfv; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIPROC __glewTextureParameteri; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVPROC __glewTextureParameteriv; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DPROC __glewTextureStorage1D; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DPROC __glewTextureStorage2D; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC __glewTextureStorage2DMultisample; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DPROC __glewTextureStorage3D; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC __glewTextureStorage3DMultisample; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DPROC __glewTextureSubImage1D; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DPROC __glewTextureSubImage2D; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DPROC __glewTextureSubImage3D; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC __glewTransformFeedbackBufferBase; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC __glewTransformFeedbackBufferRange; -GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFERPROC __glewUnmapNamedBuffer; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBBINDINGPROC __glewVertexArrayAttribBinding; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBFORMATPROC __glewVertexArrayAttribFormat; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBIFORMATPROC __glewVertexArrayAttribIFormat; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBLFORMATPROC __glewVertexArrayAttribLFormat; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDINGDIVISORPROC __glewVertexArrayBindingDivisor; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYELEMENTBUFFERPROC __glewVertexArrayElementBuffer; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERPROC __glewVertexArrayVertexBuffer; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERSPROC __glewVertexArrayVertexBuffers; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB; -GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; -GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; -GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; -GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; -GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; -GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; -GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; -GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; -GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; -GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; -GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; - -GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary; -GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri; - -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage; -GLEW_FUN_EXPORT PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage; - -GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB; - -GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv; -GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d; -GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv; -GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d; -GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv; -GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d; -GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv; -GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d; -GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv; - -GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VARBPROC __glewGetUniformi64vARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VARBPROC __glewGetUniformui64vARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMI64VARBPROC __glewGetnUniformi64vARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMUI64VARBPROC __glewGetnUniformui64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64ARBPROC __glewProgramUniform1i64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VARBPROC __glewProgramUniform1i64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64ARBPROC __glewProgramUniform1ui64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VARBPROC __glewProgramUniform1ui64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64ARBPROC __glewProgramUniform2i64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VARBPROC __glewProgramUniform2i64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64ARBPROC __glewProgramUniform2ui64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VARBPROC __glewProgramUniform2ui64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64ARBPROC __glewProgramUniform3i64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VARBPROC __glewProgramUniform3i64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64ARBPROC __glewProgramUniform3ui64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VARBPROC __glewProgramUniform3ui64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64ARBPROC __glewProgramUniform4i64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VARBPROC __glewProgramUniform4i64vARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64ARBPROC __glewProgramUniform4ui64ARB; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VARBPROC __glewProgramUniform4ui64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1I64ARBPROC __glewUniform1i64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1I64VARBPROC __glewUniform1i64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1UI64ARBPROC __glewUniform1ui64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VARBPROC __glewUniform1ui64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2I64ARBPROC __glewUniform2i64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2I64VARBPROC __glewUniform2i64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2UI64ARBPROC __glewUniform2ui64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VARBPROC __glewUniform2ui64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3I64ARBPROC __glewUniform3i64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3I64VARBPROC __glewUniform3i64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3UI64ARBPROC __glewUniform3ui64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VARBPROC __glewUniform3ui64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4I64ARBPROC __glewUniform4i64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4I64VARBPROC __glewUniform4i64vARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4UI64ARBPROC __glewUniform4ui64ARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VARBPROC __glewUniform4ui64vARB; - -GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; -GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; -GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; -GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; -GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; -GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; -GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; -GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; -GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; -GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; - -GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ; - -GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v; - -GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData; -GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData; -GLEW_FUN_EXPORT PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer; -GLEW_FUN_EXPORT PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer; -GLEW_FUN_EXPORT PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage; -GLEW_FUN_EXPORT PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage; - -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; -GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; - -GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; - -GLEW_FUN_EXPORT PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase; -GLEW_FUN_EXPORT PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange; -GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures; -GLEW_FUN_EXPORT PFNGLBINDSAMPLERSPROC __glewBindSamplers; -GLEW_FUN_EXPORT PFNGLBINDTEXTURESPROC __glewBindTextures; -GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect; - -GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; - -GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; -GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; -GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; -GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; -GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; -GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; - -GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSARBPROC __glewMaxShaderCompilerThreadsARB; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; - -GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPPROC __glewPolygonOffsetClamp; - -GLEW_FUN_EXPORT PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv; - -GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex; - -GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB; -GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB; -GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB; -GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB; -GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB; -GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB; -GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB; -GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB; -GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB; -GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB; -GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB; -GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB; -GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB; -GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB; -GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB; -GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewFramebufferSampleLocationsfvARB; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewNamedFramebufferSampleLocationsfvARB; - -GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB; - -GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler; -GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers; -GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv; -GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv; - -GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram; -GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline; -GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines; -GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv; -GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv; -GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages; -GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline; - -GLEW_FUN_EXPORT PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv; - -GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture; -GLEW_FUN_EXPORT PFNGLMEMORYBARRIERPROC __glewMemoryBarrier; - -GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; -GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; -GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; -GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; -GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; -GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; -GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; -GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; -GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; -GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; -GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; -GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; -GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; -GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; -GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; - -GLEW_FUN_EXPORT PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding; - -GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName; -GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName; -GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv; -GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv; -GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex; -GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation; -GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv; -GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv; - -GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB; -GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB; -GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB; -GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB; -GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB; -GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB; - -GLEW_FUN_EXPORT PFNGLBUFFERPAGECOMMITMENTARBPROC __glewBufferPageCommitmentARB; - -GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB; - -GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync; -GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync; -GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync; -GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v; -GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv; -GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync; -GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync; - -GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv; -GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri; - -GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERPROC __glewTextureBarrier; - -GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; - -GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange; -GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT; - -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; - -GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv; -GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski; -GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample; - -GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DPROC __glewTexStorage1D; -GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DPROC __glewTexStorage2D; -GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DPROC __glewTexStorage3D; - -GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample; -GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT; - -GLEW_FUN_EXPORT PFNGLTEXTUREVIEWPROC __glewTextureView; - -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v; -GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter; - -GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback; -GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks; -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback; -GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks; -GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback; -GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback; -GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed; -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream; -GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed; -GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv; - -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced; -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced; - -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; - -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv; -GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; -GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex; -GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices; -GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; - -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat; -GLEW_FUN_EXPORT PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor; - -GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; -GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; -GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; -GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; - -GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; -GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; -GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; -GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; -GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; -GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; -GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; - -GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; -GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; -GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; - -GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; -GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; -GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; - -GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui; -GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv; -GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui; -GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv; -GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui; -GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv; -GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui; -GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv; -GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui; -GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv; -GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui; -GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv; -GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui; -GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui; -GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv; -GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui; -GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv; -GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui; -GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv; - -GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed; -GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v; -GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v; -GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv; -GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed; -GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv; -GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv; -GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf; -GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv; - -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; -GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; - -GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; -GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; -GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; -GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; - -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; -GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; -GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; -GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; -GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; -GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; - -GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; -GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; - -GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI; -GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI; - -GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; -GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; - -GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; -GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; -GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; -GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; -GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; -GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; -GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; -GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; - -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; - -GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; -GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; -GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; - -GLEW_FUN_EXPORT PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC __glewEGLImageTargetTexStorageEXT; -GLEW_FUN_EXPORT PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC __glewEGLImageTargetTextureStorageEXT; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __glewDrawArraysInstancedBaseInstanceEXT; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseInstanceEXT; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseVertexBaseInstanceEXT; - -GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; -GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; -GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; - -GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __glewBindFragDataLocationIndexedEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXEXTPROC __glewGetFragDataIndexEXT; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __glewGetProgramResourceLocationIndexEXT; - -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; - -GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTPROC __glewBufferStorageEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT; - -GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEEXTPROC __glewClearTexImageEXT; -GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEEXTPROC __glewClearTexSubImageEXT; - -GLEW_FUN_EXPORT PFNGLCLIPCONTROLEXTPROC __glewClipControlEXT; - -GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; -GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; - -GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; -GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; - -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; -GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; - -GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; -GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; - -GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAEXTPROC __glewCopyImageSubDataEXT; - -GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; - -GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; -GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; - -GLEW_FUN_EXPORT PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT; -GLEW_FUN_EXPORT PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT; - -GLEW_FUN_EXPORT PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT; -GLEW_FUN_EXPORT PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT; -GLEW_FUN_EXPORT PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT; - -GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; - -GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; -GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; -GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; -GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT; -GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; -GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT; -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; -GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; -GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; -GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT; -GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT; -GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; -GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT; -GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; -GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; -GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; -GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; -GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; -GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; -GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; -GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; -GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT; - -GLEW_FUN_EXPORT PFNGLDISCARDFRAMEBUFFEREXTPROC __glewDiscardFramebufferEXT; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYEXTPROC __glewBeginQueryEXT; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESEXTPROC __glewDeleteQueriesEXT; -GLEW_FUN_EXPORT PFNGLENDQUERYEXTPROC __glewEndQueryEXT; -GLEW_FUN_EXPORT PFNGLGENQUERIESEXTPROC __glewGenQueriesEXT; -GLEW_FUN_EXPORT PFNGLGETINTEGER64VEXTPROC __glewGetInteger64vEXT; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVEXTPROC __glewGetQueryObjectivEXT; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVEXTPROC __glewGetQueryObjectuivEXT; -GLEW_FUN_EXPORT PFNGLGETQUERYIVEXTPROC __glewGetQueryivEXT; -GLEW_FUN_EXPORT PFNGLISQUERYEXTPROC __glewIsQueryEXT; -GLEW_FUN_EXPORT PFNGLQUERYCOUNTEREXTPROC __glewQueryCounterEXT; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSEXTPROC __glewDrawBuffersEXT; - -GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; -GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; -GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; -GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; -GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIEXTPROC __glewBlendEquationSeparateiEXT; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIEXTPROC __glewBlendEquationiEXT; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIEXTPROC __glewBlendFuncSeparateiEXT; -GLEW_FUN_EXPORT PFNGLBLENDFUNCIEXTPROC __glewBlendFunciEXT; -GLEW_FUN_EXPORT PFNGLCOLORMASKIEXTPROC __glewColorMaskiEXT; -GLEW_FUN_EXPORT PFNGLDISABLEIEXTPROC __glewDisableiEXT; -GLEW_FUN_EXPORT PFNGLENABLEIEXTPROC __glewEnableiEXT; -GLEW_FUN_EXPORT PFNGLISENABLEDIEXTPROC __glewIsEnablediEXT; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXEXTPROC __glewDrawElementsBaseVertexEXT; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __glewDrawElementsInstancedBaseVertexEXT; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __glewDrawRangeElementsBaseVertexEXT; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __glewMultiDrawElementsBaseVertexEXT; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; - -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; - -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKEXTPROC __glewDrawTransformFeedbackEXT; -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC __glewDrawTransformFeedbackInstancedEXT; - -GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTERNALEXTPROC __glewBufferStorageExternalEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC __glewNamedBufferStorageExternalEXT; - -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; - -GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; -GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; - -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; -GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; -GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; -GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; -GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; -GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; -GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; -GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; - -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; - -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; -GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; -GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; -GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; -GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; - -GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; - -GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; - -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISOREXTPROC __glewVertexAttribDivisorEXT; - -GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; -GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; - -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC __glewFlushMappedBufferRangeEXT; -GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEEXTPROC __glewMapBufferRangeEXT; - -GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEMEMEXTPROC __glewBufferStorageMemEXT; -GLEW_FUN_EXPORT PFNGLCREATEMEMORYOBJECTSEXTPROC __glewCreateMemoryObjectsEXT; -GLEW_FUN_EXPORT PFNGLDELETEMEMORYOBJECTSEXTPROC __glewDeleteMemoryObjectsEXT; -GLEW_FUN_EXPORT PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC __glewGetMemoryObjectParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEI_VEXTPROC __glewGetUnsignedBytei_vEXT; -GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEVEXTPROC __glewGetUnsignedBytevEXT; -GLEW_FUN_EXPORT PFNGLISMEMORYOBJECTEXTPROC __glewIsMemoryObjectEXT; -GLEW_FUN_EXPORT PFNGLMEMORYOBJECTPARAMETERIVEXTPROC __glewMemoryObjectParameterivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC __glewNamedBufferStorageMemEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM1DEXTPROC __glewTexStorageMem1DEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DEXTPROC __glewTexStorageMem2DEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC __glewTexStorageMem2DMultisampleEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DEXTPROC __glewTexStorageMem3DEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC __glewTexStorageMem3DMultisampleEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM1DEXTPROC __glewTextureStorageMem1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DEXTPROC __glewTextureStorageMem2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC __glewTextureStorageMem2DMultisampleEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DEXTPROC __glewTextureStorageMem3DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC __glewTextureStorageMem3DMultisampleEXT; - -GLEW_FUN_EXPORT PFNGLIMPORTMEMORYFDEXTPROC __glewImportMemoryFdEXT; - -GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC __glewImportMemoryWin32HandleEXT; -GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32NAMEEXTPROC __glewImportMemoryWin32NameEXT; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC __glewMultiDrawArraysIndirectEXT; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC __glewMultiDrawElementsIndirectEXT; - -GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; -GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __glewFramebufferTexture2DMultisampleEXT; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSINDEXEDEXTPROC __glewDrawBuffersIndexedEXT; -GLEW_FUN_EXPORT PFNGLGETINTEGERI_VEXTPROC __glewGetIntegeri_vEXT; -GLEW_FUN_EXPORT PFNGLREADBUFFERINDEXEDEXTPROC __glewReadBufferIndexedEXT; - -GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; - -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; - -GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; - -GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPEXTPROC __glewPolygonOffsetClampEXT; - -GLEW_FUN_EXPORT PFNGLPRIMITIVEBOUNDINGBOXEXTPROC __glewPrimitiveBoundingBoxEXT; - -GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT; - -GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONNVPROC __glewCoverageModulationNV; -GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONTABLENVPROC __glewCoverageModulationTableNV; -GLEW_FUN_EXPORT PFNGLGETCOVERAGEMODULATIONTABLENVPROC __glewGetCoverageModulationTableNV; -GLEW_FUN_EXPORT PFNGLRASTERSAMPLESEXTPROC __glewRasterSamplesEXT; - -GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVEXTPROC __glewGetnUniformfvEXT; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVEXTPROC __glewGetnUniformivEXT; -GLEW_FUN_EXPORT PFNGLREADNPIXELSEXTPROC __glewReadnPixelsEXT; - -GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; -GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; - -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; - -GLEW_FUN_EXPORT PFNGLDELETESEMAPHORESEXTPROC __glewDeleteSemaphoresEXT; -GLEW_FUN_EXPORT PFNGLGENSEMAPHORESEXTPROC __glewGenSemaphoresEXT; -GLEW_FUN_EXPORT PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC __glewGetSemaphoreParameterui64vEXT; -GLEW_FUN_EXPORT PFNGLISSEMAPHOREEXTPROC __glewIsSemaphoreEXT; -GLEW_FUN_EXPORT PFNGLSEMAPHOREPARAMETERUI64VEXTPROC __glewSemaphoreParameterui64vEXT; -GLEW_FUN_EXPORT PFNGLSIGNALSEMAPHOREEXTPROC __glewSignalSemaphoreEXT; -GLEW_FUN_EXPORT PFNGLWAITSEMAPHOREEXTPROC __glewWaitSemaphoreEXT; - -GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREFDEXTPROC __glewImportSemaphoreFdEXT; - -GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC __glewImportSemaphoreWin32HandleEXT; -GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC __glewImportSemaphoreWin32NameEXT; - -GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT; -GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT; -GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC __glewFramebufferFetchBarrierEXT; - -GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT; -GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT; - -GLEW_FUN_EXPORT PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC __glewClearPixelLocalStorageuiEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewFramebufferPixelLocalStorageSizeEXT; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewGetFramebufferPixelLocalStorageSizeEXT; - -GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTEXTPROC __glewTexPageCommitmentEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT; - -GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; - -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; - -GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIEXTPROC __glewPatchParameteriEXT; - -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; - -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVEXTPROC __glewGetSamplerParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVEXTPROC __glewGetSamplerParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVEXTPROC __glewSamplerParameterIivEXT; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVEXTPROC __glewSamplerParameterIuivEXT; - -GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; - -GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; -GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; - -GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; -GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; -GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; -GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; -GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; - -GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; - -GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DEXTPROC __glewTexStorage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DEXTPROC __glewTexStorage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DEXTPROC __glewTexStorage3DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT; - -GLEW_FUN_EXPORT PFNGLTEXTUREVIEWEXTPROC __glewTextureViewEXT; - -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; - -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; - -GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; -GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; -GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; -GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; -GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; -GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; - -GLEW_FUN_EXPORT PFNGLBINDARRAYSETEXTPROC __glewBindArraySetEXT; -GLEW_FUN_EXPORT PFNGLCREATEARRAYSETEXTPROC __glewCreateArraySetExt; -GLEW_FUN_EXPORT PFNGLDELETEARRAYSETSEXTPROC __glewDeleteArraySetsEXT; - -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT; - -GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; -GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; -GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; -GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; -GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; -GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; -GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; -GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; -GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; -GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; -GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; -GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; -GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; -GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; -GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; -GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; -GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; - -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; - -GLEW_FUN_EXPORT PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC __glewAcquireKeyedMutexWin32EXT; -GLEW_FUN_EXPORT PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC __glewReleaseKeyedMutexWin32EXT; - -GLEW_FUN_EXPORT PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT; - -GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT; - -GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; - -GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; - -GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; -GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; - -GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; -GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; - -GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; -GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; -GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; -GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; - -GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEIMGPROC __glewGetTextureHandleIMG; -GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEIMGPROC __glewGetTextureSamplerHandleIMG; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC __glewProgramUniformHandleui64IMG; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC __glewProgramUniformHandleui64vIMG; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64IMGPROC __glewUniformHandleui64IMG; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VIMGPROC __glewUniformHandleui64vIMG; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC __glewFramebufferTexture2DDownsampleIMG; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC __glewFramebufferTextureLayerDownsampleIMG; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC __glewFramebufferTexture2DMultisampleIMG; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC __glewRenderbufferStorageMultisampleIMG; - -GLEW_FUN_EXPORT PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL; -GLEW_FUN_EXPORT PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL; -GLEW_FUN_EXPORT PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL; - -GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; -GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; - -GLEW_FUN_EXPORT PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL; -GLEW_FUN_EXPORT PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL; -GLEW_FUN_EXPORT PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL; -GLEW_FUN_EXPORT PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL; -GLEW_FUN_EXPORT PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL; -GLEW_FUN_EXPORT PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL; -GLEW_FUN_EXPORT PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL; -GLEW_FUN_EXPORT PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL; -GLEW_FUN_EXPORT PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL; -GLEW_FUN_EXPORT PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL; - -GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; -GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; - -GLEW_FUN_EXPORT PFNGLBLENDBARRIERKHRPROC __glewBlendBarrierKHR; - -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl; -GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert; -GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog; -GLEW_FUN_EXPORT PFNGLGETOBJECTLABELPROC __glewGetObjectLabel; -GLEW_FUN_EXPORT PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel; -GLEW_FUN_EXPORT PFNGLOBJECTLABELPROC __glewObjectLabel; -GLEW_FUN_EXPORT PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel; -GLEW_FUN_EXPORT PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup; -GLEW_FUN_EXPORT PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup; - -GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSKHRPROC __glewMaxShaderCompilerThreadsKHR; - -GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVPROC __glewGetnUniformfv; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVPROC __glewGetnUniformiv; -GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVPROC __glewGetnUniformuiv; -GLEW_FUN_EXPORT PFNGLREADNPIXELSPROC __glewReadnPixels; - -GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion; -GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion; -GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion; -GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIMESAPROC __glewFramebufferParameteriMESA; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC __glewGetFramebufferParameterivMESA; - -GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; - -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; - -GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX; -GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX; - -GLEW_FUN_EXPORT PFNGLASYNCCOPYBUFFERSUBDATANVXPROC __glewAsyncCopyBufferSubDataNVX; -GLEW_FUN_EXPORT PFNGLASYNCCOPYIMAGESUBDATANVXPROC __glewAsyncCopyImageSubDataNVX; -GLEW_FUN_EXPORT PFNGLMULTICASTSCISSORARRAYVNVXPROC __glewMulticastScissorArrayvNVX; -GLEW_FUN_EXPORT PFNGLMULTICASTVIEWPORTARRAYVNVXPROC __glewMulticastViewportArrayvNVX; -GLEW_FUN_EXPORT PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC __glewMulticastViewportPositionWScaleNVX; -GLEW_FUN_EXPORT PFNGLUPLOADGPUMASKNVXPROC __glewUploadGpuMaskNVX; - -GLEW_FUN_EXPORT PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX; -GLEW_FUN_EXPORT PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX; -GLEW_FUN_EXPORT PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX; - -GLEW_FUN_EXPORT PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC __glewClientWaitSemaphoreui64NVX; -GLEW_FUN_EXPORT PFNGLSIGNALSEMAPHOREUI64NVXPROC __glewSignalSemaphoreui64NVX; -GLEW_FUN_EXPORT PFNGLWAITSEMAPHOREUI64NVXPROC __glewWaitSemaphoreui64NVX; - -GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERFNVPROC __glewStereoParameterfNV; -GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERINVPROC __glewStereoParameteriNV; - -GLEW_FUN_EXPORT PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC __glewAlphaToCoverageDitherControlNV; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawArraysIndirectBindlessCountNV; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawElementsIndirectBindlessCountNV; - -GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV; -GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV; -GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV; -GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV; -GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV; -GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV; -GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV; -GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV; -GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV; - -GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV; -GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV; - -GLEW_FUN_EXPORT PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV; - -GLEW_FUN_EXPORT PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV; -GLEW_FUN_EXPORT PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV; -GLEW_FUN_EXPORT PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV; -GLEW_FUN_EXPORT PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV; -GLEW_FUN_EXPORT PFNGLCREATESTATESNVPROC __glewCreateStatesNV; -GLEW_FUN_EXPORT PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV; -GLEW_FUN_EXPORT PFNGLDELETESTATESNVPROC __glewDeleteStatesNV; -GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV; -GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV; -GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV; -GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV; -GLEW_FUN_EXPORT PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV; -GLEW_FUN_EXPORT PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV; -GLEW_FUN_EXPORT PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV; -GLEW_FUN_EXPORT PFNGLISSTATENVPROC __glewIsStateNV; -GLEW_FUN_EXPORT PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV; -GLEW_FUN_EXPORT PFNGLSTATECAPTURENVPROC __glewStateCaptureNV; - -GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; -GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; - -GLEW_FUN_EXPORT PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV; - -GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV; - -GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV; - -GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATANVPROC __glewCopyBufferSubDataNV; - -GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV; - -GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; -GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSNVPROC __glewDrawBuffersNV; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDNVPROC __glewDrawArraysInstancedNV; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDNVPROC __glewDrawElementsInstancedNV; - -GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV; - -GLEW_FUN_EXPORT PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV; -GLEW_FUN_EXPORT PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV; -GLEW_FUN_EXPORT PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV; -GLEW_FUN_EXPORT PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV; -GLEW_FUN_EXPORT PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV; - -GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; -GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; -GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; -GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; -GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; -GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; -GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; - -GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; -GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; -GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; - -GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; -GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; -GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; -GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; -GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; -GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; -GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; - -GLEW_FUN_EXPORT PFNGLFRAGMENTCOVERAGECOLORNVPROC __glewFragmentCoverageColorNV; - -GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; - -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERNVPROC __glewBlitFramebufferNV; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC __glewRenderbufferStorageMultisampleNV; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; - -GLEW_FUN_EXPORT PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV; -GLEW_FUN_EXPORT PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV; -GLEW_FUN_EXPORT PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV; -GLEW_FUN_EXPORT PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV; -GLEW_FUN_EXPORT PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV; -GLEW_FUN_EXPORT PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV; -GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV; -GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV; -GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV; -GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV; -GLEW_FUN_EXPORT PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV; -GLEW_FUN_EXPORT PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; - -GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV; - -GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; -GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; -GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; -GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; -GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; -GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; -GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; -GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; -GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; -GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; -GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; - -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORNVPROC __glewVertexAttribDivisorNV; - -GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATSAMPLEIVNVPROC __glewGetInternalformatSampleivNV; - -GLEW_FUN_EXPORT PFNGLBUFFERATTACHMEMORYNVPROC __glewBufferAttachMemoryNV; -GLEW_FUN_EXPORT PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC __glewGetMemoryObjectDetachedResourcesuivNV; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERATTACHMEMORYNVPROC __glewNamedBufferAttachMemoryNV; -GLEW_FUN_EXPORT PFNGLRESETMEMORYOBJECTPARAMETERNVPROC __glewResetMemoryObjectParameterNV; -GLEW_FUN_EXPORT PFNGLTEXATTACHMEMORYNVPROC __glewTexAttachMemoryNV; -GLEW_FUN_EXPORT PFNGLTEXTUREATTACHMEMORYNVPROC __glewTextureAttachMemoryNV; - -GLEW_FUN_EXPORT PFNGLDRAWMESHTASKSINDIRECTNVPROC __glewDrawMeshTasksIndirectNV; -GLEW_FUN_EXPORT PFNGLDRAWMESHTASKSNVPROC __glewDrawMeshTasksNV; -GLEW_FUN_EXPORT PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC __glewMultiDrawMeshTasksIndirectCountNV; -GLEW_FUN_EXPORT PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC __glewMultiDrawMeshTasksIndirectNV; - -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVNVPROC __glewUniformMatrix2x3fvNV; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVNVPROC __glewUniformMatrix2x4fvNV; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVNVPROC __glewUniformMatrix3x2fvNV; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVNVPROC __glewUniformMatrix3x4fvNV; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVNVPROC __glewUniformMatrix4x2fvNV; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVNVPROC __glewUniformMatrix4x3fvNV; - -GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; -GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; -GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; -GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; -GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; -GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; -GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; - -GLEW_FUN_EXPORT PFNGLCOPYPATHNVPROC __glewCopyPathNV; -GLEW_FUN_EXPORT PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV; -GLEW_FUN_EXPORT PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV; -GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV; -GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV; -GLEW_FUN_EXPORT PFNGLDELETEPATHSNVPROC __glewDeletePathsNV; -GLEW_FUN_EXPORT PFNGLGENPATHSNVPROC __glewGenPathsNV; -GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV; -GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV; -GLEW_FUN_EXPORT PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV; -GLEW_FUN_EXPORT PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV; -GLEW_FUN_EXPORT PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV; -GLEW_FUN_EXPORT PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV; -GLEW_FUN_EXPORT PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV; -GLEW_FUN_EXPORT PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV; -GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV; -GLEW_FUN_EXPORT PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV; -GLEW_FUN_EXPORT PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV; -GLEW_FUN_EXPORT PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEFVNVPROC __glewGetProgramResourcefvNV; -GLEW_FUN_EXPORT PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV; -GLEW_FUN_EXPORT PFNGLISPATHNVPROC __glewIsPathNV; -GLEW_FUN_EXPORT PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV; -GLEW_FUN_EXPORT PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV; -GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X2FNVPROC __glewMatrixLoad3x2fNV; -GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X3FNVPROC __glewMatrixLoad3x3fNV; -GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC __glewMatrixLoadTranspose3x3fNV; -GLEW_FUN_EXPORT PFNGLMATRIXMULT3X2FNVPROC __glewMatrixMult3x2fNV; -GLEW_FUN_EXPORT PFNGLMATRIXMULT3X3FNVPROC __glewMatrixMult3x3fNV; -GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC __glewMatrixMultTranspose3x3fNV; -GLEW_FUN_EXPORT PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV; -GLEW_FUN_EXPORT PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV; -GLEW_FUN_EXPORT PFNGLPATHCOORDSNVPROC __glewPathCoordsNV; -GLEW_FUN_EXPORT PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV; -GLEW_FUN_EXPORT PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV; -GLEW_FUN_EXPORT PFNGLPATHFOGGENNVPROC __glewPathFogGenNV; -GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXARRAYNVPROC __glewPathGlyphIndexArrayNV; -GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXRANGENVPROC __glewPathGlyphIndexRangeNV; -GLEW_FUN_EXPORT PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV; -GLEW_FUN_EXPORT PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV; -GLEW_FUN_EXPORT PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC __glewPathMemoryGlyphIndexArrayNV; -GLEW_FUN_EXPORT PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV; -GLEW_FUN_EXPORT PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV; -GLEW_FUN_EXPORT PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV; -GLEW_FUN_EXPORT PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV; -GLEW_FUN_EXPORT PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV; -GLEW_FUN_EXPORT PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV; -GLEW_FUN_EXPORT PFNGLPATHSTRINGNVPROC __glewPathStringNV; -GLEW_FUN_EXPORT PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV; -GLEW_FUN_EXPORT PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV; -GLEW_FUN_EXPORT PFNGLPATHTEXGENNVPROC __glewPathTexGenNV; -GLEW_FUN_EXPORT PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC __glewProgramPathFragmentInputGenNV; -GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV; -GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV; -GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV; -GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV; -GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC __glewStencilThenCoverFillPathInstancedNV; -GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHNVPROC __glewStencilThenCoverFillPathNV; -GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC __glewStencilThenCoverStrokePathInstancedNV; -GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC __glewStencilThenCoverStrokePathNV; -GLEW_FUN_EXPORT PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV; -GLEW_FUN_EXPORT PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV; - -GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; -GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; - -GLEW_FUN_EXPORT PFNGLPOLYGONMODENVPROC __glewPolygonModeNV; - -GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; -GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; -GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; - -GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; -GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; - -GLEW_FUN_EXPORT PFNGLREADBUFFERNVPROC __glewReadBufferNV; - -GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; -GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; -GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; -GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; - -GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewFramebufferSampleLocationsfvNV; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewNamedFramebufferSampleLocationsfvNV; -GLEW_FUN_EXPORT PFNGLRESOLVEDEPTHVALUESNVPROC __glewResolveDepthValuesNV; - -GLEW_FUN_EXPORT PFNGLSCISSOREXCLUSIVEARRAYVNVPROC __glewScissorExclusiveArrayvNV; -GLEW_FUN_EXPORT PFNGLSCISSOREXCLUSIVENVPROC __glewScissorExclusiveNV; - -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV; -GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV; -GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV; -GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV; -GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV; -GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV; -GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV; -GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV; -GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV; -GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV; - -GLEW_FUN_EXPORT PFNGLBINDSHADINGRATEIMAGENVPROC __glewBindShadingRateImageNV; -GLEW_FUN_EXPORT PFNGLGETSHADINGRATEIMAGEPALETTENVPROC __glewGetShadingRateImagePaletteNV; -GLEW_FUN_EXPORT PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC __glewGetShadingRateSampleLocationivNV; -GLEW_FUN_EXPORT PFNGLSHADINGRATEIMAGEBARRIERNVPROC __glewShadingRateImageBarrierNV; -GLEW_FUN_EXPORT PFNGLSHADINGRATEIMAGEPALETTENVPROC __glewShadingRateImagePaletteNV; -GLEW_FUN_EXPORT PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC __glewShadingRateSampleOrderCustomNV; - -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DNVPROC __glewCompressedTexImage3DNV; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC __glewCompressedTexSubImage3DNV; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DNVPROC __glewCopyTexSubImage3DNV; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERNVPROC __glewFramebufferTextureLayerNV; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DNVPROC __glewTexImage3DNV; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DNVPROC __glewTexSubImage3DNV; - -GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV; - -GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV; - -GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; -GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; - -GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV; -GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV; -GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV; - -GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV; -GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV; -GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV; -GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV; -GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV; -GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV; -GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV; -GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV; -GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV; -GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV; - -GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC __glewVDPAURegisterVideoSurfaceWithPictureStructureNV; - -GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; - -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV; - -GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV; -GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV; -GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV; -GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV; -GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV; -GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV; -GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV; -GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV; -GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV; - -GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; -GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; -GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; -GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; -GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; -GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; -GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; -GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; -GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; - -GLEW_FUN_EXPORT PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV; -GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV; -GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV; -GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV; -GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV; -GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV; -GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV; -GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV; - -GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYFVNVPROC __glewDepthRangeArrayfvNV; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDFNVPROC __glewDepthRangeIndexedfNV; -GLEW_FUN_EXPORT PFNGLDISABLEINVPROC __glewDisableiNV; -GLEW_FUN_EXPORT PFNGLENABLEINVPROC __glewEnableiNV; -GLEW_FUN_EXPORT PFNGLGETFLOATI_VNVPROC __glewGetFloati_vNV; -GLEW_FUN_EXPORT PFNGLISENABLEDINVPROC __glewIsEnablediNV; -GLEW_FUN_EXPORT PFNGLSCISSORARRAYVNVPROC __glewScissorArrayvNV; -GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDNVPROC __glewScissorIndexedNV; -GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVNVPROC __glewScissorIndexedvNV; -GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVNVPROC __glewViewportArrayvNV; -GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFNVPROC __glewViewportIndexedfNV; -GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVNVPROC __glewViewportIndexedfvNV; - -GLEW_FUN_EXPORT PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV; - -GLEW_FUN_EXPORT PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __glewEGLImageTargetRenderbufferStorageOES; -GLEW_FUN_EXPORT PFNGLEGLIMAGETARGETTEXTURE2DOESPROC __glewEGLImageTargetTexture2DOES; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEOESPROC __glewBlendEquationSeparateOES; - -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEOESPROC __glewBlendFuncSeparateOES; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONOESPROC __glewBlendEquationOES; - -GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAOESPROC __glewCopyImageSubDataOES; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIOESPROC __glewBlendEquationSeparateiOES; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIOESPROC __glewBlendEquationiOES; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIOESPROC __glewBlendFuncSeparateiOES; -GLEW_FUN_EXPORT PFNGLBLENDFUNCIOESPROC __glewBlendFunciOES; -GLEW_FUN_EXPORT PFNGLCOLORMASKIOESPROC __glewColorMaskiOES; -GLEW_FUN_EXPORT PFNGLDISABLEIOESPROC __glewDisableiOES; -GLEW_FUN_EXPORT PFNGLENABLEIOESPROC __glewEnableiOES; -GLEW_FUN_EXPORT PFNGLISENABLEDIOESPROC __glewIsEnablediOES; - -GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEROESPROC __glewBindFramebufferOES; -GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEROESPROC __glewBindRenderbufferOES; -GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSOESPROC __glewCheckFramebufferStatusOES; -GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSOESPROC __glewDeleteFramebuffersOES; -GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSOESPROC __glewDeleteRenderbuffersOES; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEROESPROC __glewFramebufferRenderbufferOES; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DOESPROC __glewFramebufferTexture2DOES; -GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSOESPROC __glewGenFramebuffersOES; -GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSOESPROC __glewGenRenderbuffersOES; -GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPOESPROC __glewGenerateMipmapOES; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC __glewGetFramebufferAttachmentParameterivOES; -GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVOESPROC __glewGetRenderbufferParameterivOES; -GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEROESPROC __glewIsFramebufferOES; -GLEW_FUN_EXPORT PFNGLISRENDERBUFFEROESPROC __glewIsRenderbufferOES; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEOESPROC __glewRenderbufferStorageOES; - -GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYOESPROC __glewGetProgramBinaryOES; -GLEW_FUN_EXPORT PFNGLPROGRAMBINARYOESPROC __glewProgramBinaryOES; - -GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVOESPROC __glewGetBufferPointervOES; -GLEW_FUN_EXPORT PFNGLMAPBUFFEROESPROC __glewMapBufferOES; -GLEW_FUN_EXPORT PFNGLUNMAPBUFFEROESPROC __glewUnmapBufferOES; - -GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXOESPROC __glewCurrentPaletteMatrixOES; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTEROESPROC __glewMatrixIndexPointerOES; -GLEW_FUN_EXPORT PFNGLWEIGHTPOINTEROESPROC __glewWeightPointerOES; - -GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGOESPROC __glewMinSampleShadingOES; - -GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; -GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; -GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; -GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; -GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; - -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DOESPROC __glewCompressedTexImage3DOES; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __glewCompressedTexSubImage3DOES; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DOESPROC __glewCopyTexSubImage3DOES; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DOESPROC __glewFramebufferTexture3DOES; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DOESPROC __glewTexImage3DOES; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DOESPROC __glewTexSubImage3DOES; - -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVOESPROC __glewGetSamplerParameterIivOES; -GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVOESPROC __glewGetSamplerParameterIuivOES; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVOESPROC __glewGetTexParameterIivOES; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVOESPROC __glewGetTexParameterIuivOES; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVOESPROC __glewSamplerParameterIivOES; -GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVOESPROC __glewSamplerParameterIuivOES; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVOESPROC __glewTexParameterIivOES; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVOESPROC __glewTexParameterIuivOES; - -GLEW_FUN_EXPORT PFNGLTEXBUFFEROESPROC __glewTexBufferOES; -GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEOESPROC __glewTexBufferRangeOES; - -GLEW_FUN_EXPORT PFNGLGETTEXGENFVOESPROC __glewGetTexGenfvOES; -GLEW_FUN_EXPORT PFNGLGETTEXGENIVOESPROC __glewGetTexGenivOES; -GLEW_FUN_EXPORT PFNGLGETTEXGENXVOESPROC __glewGetTexGenxvOES; -GLEW_FUN_EXPORT PFNGLTEXGENFOESPROC __glewTexGenfOES; -GLEW_FUN_EXPORT PFNGLTEXGENFVOESPROC __glewTexGenfvOES; -GLEW_FUN_EXPORT PFNGLTEXGENIOESPROC __glewTexGeniOES; -GLEW_FUN_EXPORT PFNGLTEXGENIVOESPROC __glewTexGenivOES; -GLEW_FUN_EXPORT PFNGLTEXGENXOESPROC __glewTexGenxOES; -GLEW_FUN_EXPORT PFNGLTEXGENXVOESPROC __glewTexGenxvOES; - -GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC __glewTexStorage3DMultisampleOES; - -GLEW_FUN_EXPORT PFNGLTEXTUREVIEWOESPROC __glewTextureViewOES; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYOESPROC __glewBindVertexArrayOES; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSOESPROC __glewDeleteVertexArraysOES; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSOESPROC __glewGenVertexArraysOES; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYOESPROC __glewIsVertexArrayOES; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewFramebufferTextureMultiviewOVR; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewNamedFramebufferTextureMultiviewOVR; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __glewFramebufferTextureMultisampleMultiviewOVR; - -GLEW_FUN_EXPORT PFNGLALPHAFUNCQCOMPROC __glewAlphaFuncQCOM; - -GLEW_FUN_EXPORT PFNGLDISABLEDRIVERCONTROLQCOMPROC __glewDisableDriverControlQCOM; -GLEW_FUN_EXPORT PFNGLENABLEDRIVERCONTROLQCOMPROC __glewEnableDriverControlQCOM; -GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSTRINGQCOMPROC __glewGetDriverControlStringQCOM; -GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSQCOMPROC __glewGetDriverControlsQCOM; - -GLEW_FUN_EXPORT PFNGLEXTGETBUFFERPOINTERVQCOMPROC __glewExtGetBufferPointervQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETBUFFERSQCOMPROC __glewExtGetBuffersQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETFRAMEBUFFERSQCOMPROC __glewExtGetFramebuffersQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETRENDERBUFFERSQCOMPROC __glewExtGetRenderbuffersQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC __glewExtGetTexLevelParameterivQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETTEXSUBIMAGEQCOMPROC __glewExtGetTexSubImageQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETTEXTURESQCOMPROC __glewExtGetTexturesQCOM; -GLEW_FUN_EXPORT PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC __glewExtTexObjectStateOverrideiQCOM; - -GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC __glewExtGetProgramBinarySourceQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMSQCOMPROC __glewExtGetProgramsQCOM; -GLEW_FUN_EXPORT PFNGLEXTGETSHADERSQCOMPROC __glewExtGetShadersQCOM; -GLEW_FUN_EXPORT PFNGLEXTISPROGRAMBINARYQCOMPROC __glewExtIsProgramBinaryQCOM; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC __glewFramebufferFoveationConfigQCOM; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC __glewFramebufferFoveationParametersQCOM; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC __glewFramebufferFetchBarrierQCOM; - -GLEW_FUN_EXPORT PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC __glewTextureFoveationParametersQCOM; - -GLEW_FUN_EXPORT PFNGLENDTILINGQCOMPROC __glewEndTilingQCOM; -GLEW_FUN_EXPORT PFNGLSTARTTILINGQCOMPROC __glewStartTilingQCOM; - -GLEW_FUN_EXPORT PFNGLALPHAFUNCXPROC __glewAlphaFuncx; -GLEW_FUN_EXPORT PFNGLCLEARCOLORXPROC __glewClearColorx; -GLEW_FUN_EXPORT PFNGLCLEARDEPTHXPROC __glewClearDepthx; -GLEW_FUN_EXPORT PFNGLCOLOR4XPROC __glewColor4x; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEXPROC __glewDepthRangex; -GLEW_FUN_EXPORT PFNGLFOGXPROC __glewFogx; -GLEW_FUN_EXPORT PFNGLFOGXVPROC __glewFogxv; -GLEW_FUN_EXPORT PFNGLFRUSTUMFPROC __glewFrustumf; -GLEW_FUN_EXPORT PFNGLFRUSTUMXPROC __glewFrustumx; -GLEW_FUN_EXPORT PFNGLLIGHTMODELXPROC __glewLightModelx; -GLEW_FUN_EXPORT PFNGLLIGHTMODELXVPROC __glewLightModelxv; -GLEW_FUN_EXPORT PFNGLLIGHTXPROC __glewLightx; -GLEW_FUN_EXPORT PFNGLLIGHTXVPROC __glewLightxv; -GLEW_FUN_EXPORT PFNGLLINEWIDTHXPROC __glewLineWidthx; -GLEW_FUN_EXPORT PFNGLLOADMATRIXXPROC __glewLoadMatrixx; -GLEW_FUN_EXPORT PFNGLMATERIALXPROC __glewMaterialx; -GLEW_FUN_EXPORT PFNGLMATERIALXVPROC __glewMaterialxv; -GLEW_FUN_EXPORT PFNGLMULTMATRIXXPROC __glewMultMatrixx; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x; -GLEW_FUN_EXPORT PFNGLNORMAL3XPROC __glewNormal3x; -GLEW_FUN_EXPORT PFNGLORTHOFPROC __glewOrthof; -GLEW_FUN_EXPORT PFNGLORTHOXPROC __glewOrthox; -GLEW_FUN_EXPORT PFNGLPOINTSIZEXPROC __glewPointSizex; -GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx; -GLEW_FUN_EXPORT PFNGLROTATEXPROC __glewRotatex; -GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex; -GLEW_FUN_EXPORT PFNGLSCALEXPROC __glewScalex; -GLEW_FUN_EXPORT PFNGLTEXENVXPROC __glewTexEnvx; -GLEW_FUN_EXPORT PFNGLTEXENVXVPROC __glewTexEnvxv; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERXPROC __glewTexParameterx; -GLEW_FUN_EXPORT PFNGLTRANSLATEXPROC __glewTranslatex; - -GLEW_FUN_EXPORT PFNGLCLIPPLANEFPROC __glewClipPlanef; -GLEW_FUN_EXPORT PFNGLCLIPPLANEXPROC __glewClipPlanex; -GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef; -GLEW_FUN_EXPORT PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex; -GLEW_FUN_EXPORT PFNGLGETFIXEDVPROC __glewGetFixedv; -GLEW_FUN_EXPORT PFNGLGETLIGHTXVPROC __glewGetLightxv; -GLEW_FUN_EXPORT PFNGLGETMATERIALXVPROC __glewGetMaterialxv; -GLEW_FUN_EXPORT PFNGLGETTEXENVXVPROC __glewGetTexEnvxv; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXPROC __glewPointParameterx; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv; -GLEW_FUN_EXPORT PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERXVPROC __glewTexParameterxv; - -GLEW_FUN_EXPORT PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL; - -GLEW_FUN_EXPORT PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL; -GLEW_FUN_EXPORT PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL; - -GLEW_FUN_EXPORT PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL; - -GLEW_FUN_EXPORT PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL; - -GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; -GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; - -GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; -GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; - -GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; -GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; - -GLEW_FUN_EXPORT PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC __glewInterleavedTextureCoordSetsSGIS; -GLEW_FUN_EXPORT PFNGLSELECTTEXTURECOORDSETSGISPROC __glewSelectTextureCoordSetSGIS; -GLEW_FUN_EXPORT PFNGLSELECTTEXTURESGISPROC __glewSelectTextureSGIS; -GLEW_FUN_EXPORT PFNGLSELECTTEXTURETRANSFORMSGISPROC __glewSelectTextureTransformSGIS; - -GLEW_FUN_EXPORT PFNGLMULTISAMPLESUBRECTPOSSGISPROC __glewMultisampleSubRectPosSGIS; - -GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; -GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; - -GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; - -GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; -GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; - -GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; -GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; -GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; -GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; -GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; -GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; - -GLEW_FUN_EXPORT PFNGLADDRESSSPACEPROC __glewAddressSpace; -GLEW_FUN_EXPORT PFNGLDATAPIPEPROC __glewDataPipe; - -GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; - -GLEW_FUN_EXPORT PFNGLFOGLAYERSSGIXPROC __glewFogLayersSGIX; -GLEW_FUN_EXPORT PFNGLGETFOGLAYERSSGIXPROC __glewGetFogLayersSGIX; - -GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; - -GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; - -GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; - -GLEW_FUN_EXPORT PFNGLIGLOOINTERFACESGIXPROC __glewIglooInterfaceSGIX; - -GLEW_FUN_EXPORT PFNGLALLOCMPEGPREDICTORSSGIXPROC __glewAllocMPEGPredictorsSGIX; -GLEW_FUN_EXPORT PFNGLDELETEMPEGPREDICTORSSGIXPROC __glewDeleteMPEGPredictorsSGIX; -GLEW_FUN_EXPORT PFNGLGENMPEGPREDICTORSSGIXPROC __glewGenMPEGPredictorsSGIX; -GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERFVSGIXPROC __glewGetMPEGParameterfvSGIX; -GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERIVSGIXPROC __glewGetMPEGParameterivSGIX; -GLEW_FUN_EXPORT PFNGLGETMPEGPREDICTORSGIXPROC __glewGetMPEGPredictorSGIX; -GLEW_FUN_EXPORT PFNGLGETMPEGQUANTTABLEUBVPROC __glewGetMPEGQuantTableubv; -GLEW_FUN_EXPORT PFNGLISMPEGPREDICTORSGIXPROC __glewIsMPEGPredictorSGIX; -GLEW_FUN_EXPORT PFNGLMPEGPREDICTORSGIXPROC __glewMPEGPredictorSGIX; -GLEW_FUN_EXPORT PFNGLMPEGQUANTTABLEUBVPROC __glewMPEGQuantTableubv; -GLEW_FUN_EXPORT PFNGLSWAPMPEGPREDICTORSSGIXPROC __glewSwapMPEGPredictorsSGIX; - -GLEW_FUN_EXPORT PFNGLGETNONLINLIGHTFVSGIXPROC __glewGetNonlinLightfvSGIX; -GLEW_FUN_EXPORT PFNGLGETNONLINMATERIALFVSGIXPROC __glewGetNonlinMaterialfvSGIX; -GLEW_FUN_EXPORT PFNGLNONLINLIGHTFVSGIXPROC __glewNonlinLightfvSGIX; -GLEW_FUN_EXPORT PFNGLNONLINMATERIALFVSGIXPROC __glewNonlinMaterialfvSGIX; - -GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; - -GLEW_FUN_EXPORT PFNGLDEFORMSGIXPROC __glewDeformSGIX; -GLEW_FUN_EXPORT PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC __glewLoadIdentityDeformationMapSGIX; - -GLEW_FUN_EXPORT PFNGLMESHBREADTHSGIXPROC __glewMeshBreadthSGIX; -GLEW_FUN_EXPORT PFNGLMESHSTRIDESGIXPROC __glewMeshStrideSGIX; - -GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; - -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; - -GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; - -GLEW_FUN_EXPORT PFNGLGETVECTOROPERATIONSGIXPROC __glewGetVectorOperationSGIX; -GLEW_FUN_EXPORT PFNGLVECTOROPERATIONSGIXPROC __glewVectorOperationSGIX; - -GLEW_FUN_EXPORT PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC __glewAreVertexArraysResidentSGIX; -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYSGIXPROC __glewBindVertexArraySGIX; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSSGIXPROC __glewDeleteVertexArraysSGIX; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSSGIXPROC __glewGenVertexArraysSGIX; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYSGIXPROC __glewIsVertexArraySGIX; -GLEW_FUN_EXPORT PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC __glewPrioritizeVertexArraysSGIX; - -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; -GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; -GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; - -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC __glewGetPixelTransformParameterfvSGI; -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC __glewGetPixelTransformParameterivSGI; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFSGIPROC __glewPixelTransformParameterfSGI; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC __glewPixelTransformParameterfvSGI; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERISGIPROC __glewPixelTransformParameteriSGI; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC __glewPixelTransformParameterivSGI; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMSGIPROC __glewPixelTransformSGI; - -GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; - -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; - -GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; - -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; - -GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; - -GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_2; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_3; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_4; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_5; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_6; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_blend_minmax_factor; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_3DC_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_ATC_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_framebuffer_multisample_advanced; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_framebuffer_sample_positions; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gcn_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_half_float; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_half_float_fetch; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int16; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int64; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_interleaved_elements; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_multi_draw_indirect; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_occlusion_query_event; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_pinned_memory; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_program_binary_Z400; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_atomic_counter_ops; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_ballot; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_explicit_vertex_parameter; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_image_load_store_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_value_export; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sparse_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_stencil_operation_extended; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_gather_bias_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback4; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_layer; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator; -GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_viewport_index; -GLEW_VAR_EXPORT GLboolean __GLEW_ANDROID_extension_pack_es31a; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_blit; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_instanced_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_pack_reverse_row_order; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt1; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt3; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt5; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_usage; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_translated_shader_source; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_clip_distance; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_color_buffer_packed_float; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_copy_texture_levels; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_framebuffer_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_sync; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_2D_limited_npot; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_format_BGRA8888; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_max_level; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_packed_float; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_1_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_2_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_arrays_of_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_base_instance; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_bindless_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_buffer_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clip_control; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compressed_texture_pixel_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_variable_group_size; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conditional_render_inverted; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conservative_depth; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_image; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cull_distance; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_derivative_control; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_direct_state_access; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_enhanced_layouts; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_uniform_location; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_layer_viewport; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader_interlock; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_no_attachments; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_texture_sub_image; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gl_spirv; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_int64; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_indirect_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query2; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_invalidate_subdata; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_alignment; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_bind; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_draw_indirect; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_parallel_shader_compile; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pipeline_statistics_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_polygon_offset_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_post_depth_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_program_interface_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_query_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robust_buffer_access_behavior; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_application_isolation; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_share_group_isolation; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_locations; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cubemap_per_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counter_ops; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counters; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_ballot; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_clock; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_draw_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_group_vote; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_load_store; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_size; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_storage_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_image_samples; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_viewport_layer_array; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_420pack; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_packing; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture2; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_spirv_extensions; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_stencil_texturing; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_barrier; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_anisotropic; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_levels; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_stencil8; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_view; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_overflow_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_binding; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_shader_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_rgba8; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_ARM_texture_unnormalized_coordinates; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; -GLEW_VAR_EXPORT GLboolean __GLEW_DMP_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_DMP_shader_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_image_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_image_external_wrap_modes; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_image_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_sync; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_YUV_target; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_base_instance; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_extended; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_buffer_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clear_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_control; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_cull_distance; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_half_float; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compressed_ETC1_RGB8_sub_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_conservative_depth; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_image; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_label; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_marker; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_discard_framebuffer; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_disjoint_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers_indexed; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_elements_base_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_transform_feedback; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_external_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_float_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_frag_depth; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader5; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_instanced_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_map_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_fd; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_win32; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_indirect; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiple_textures; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture2; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_tessellation_geometry_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_texture_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_occlusion_query_boolean; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_post_depth_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_primitive_bounding_box; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_protected_textures; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pvrtc_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_raster_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_read_format_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_render_snorm; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_robustness; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB_write_control; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_fd; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_win32; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_framebuffer_fetch; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_framebuffer_fetch_non_coherent; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_group_vote; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_formatted; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_implicit_conversions; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_integer_mix; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_io_blocks; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_non_constant_global_initializers; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage2; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_samplers; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture2; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_static_vertex_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_tessellation_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_tessellation_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_bptc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc_srgb; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_format_BGRA8888; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_format_sRGB_override; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp_to_edge; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_norm16; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_query_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rg; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_R8; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_RG8; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_decode; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shadow_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_type_2_10_10_10_REV; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_view; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_unpack_subimage; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_setXXX; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_win32_keyed_mutex; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_window_rectangles; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object; -GLEW_VAR_EXPORT GLboolean __GLEW_FJ_shader_binary_GCCSO; -GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; -GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_bindless_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_framebuffer_downsample; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_multisampled_render_to_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_read_format; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_shader_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_texture_compression_pvrtc; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_texture_compression_pvrtc2; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_texture_env_enhanced_fixed_function; -GLEW_VAR_EXPORT GLboolean __GLEW_IMG_texture_filter_cubic; -GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_blackhole_render; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_conservative_rasterization; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_fragment_shader_ordering; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_framebuffer_CMAA; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_performance_query; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_shader_integer_functions2; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced_coherent; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_context_flush_control; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_debug; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_no_error; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_parallel_shader_compile; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robust_buffer_access_behavior; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robustness; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_shader_subgroup; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_hdr; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr; -GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d; -GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; -GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_framebuffer_flip_y; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_program_binary_formats; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_shader_integer_functions; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_tile_raster_order; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_conditional_render; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_multicast2; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_linked_gpu_multicast; -GLEW_VAR_EXPORT GLboolean __GLEW_NVX_progress_fence; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_3dvision_settings; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_EGL_stream_consumer_external; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_alpha_to_coverage_dither_control; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_bgr; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect_count; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_minmax_factor; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_clip_space_w_scaling; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_command_list; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_shader_derivatives; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_dilate; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_pre_snap; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_underestimation; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_nonlinear; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_vulkan_image; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_attrib_location; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fbo_color_attachments; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fill_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_coverage_to_color; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_shader_barycentric; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_shader_interlock; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_blit; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_mixed_samples; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_generate_mipmap_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader_passthrough; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_multicast; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_image_formats; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_instanced_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_internalformat_sample_query; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_memory_attachment; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_mesh_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_non_square_matrices; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_pack_subimage; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float_linear; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering_shared_edge; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_platform_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_polygon_mode; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_query_resource_tag; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_buffer_front; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_representative_fragment_test; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_robustness_video_memory_purge; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_sRGB_formats; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_locations; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_mask_override_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_scissor_exclusive; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_counters; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float64; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_fp16_vector; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_int64; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_noperspective_interpolation; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_subgroup_partitioned; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_texture_footprint; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_group; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_shuffle; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shading_rate_image; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_array; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_cube; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_stereo_view_rendering; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_array; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_latc; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc_update; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_npot_2D_mipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle_compressed; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_uniform_buffer_unified_memory; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_swizzle; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_EGL_image; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_EGL_image_external; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_EGL_image_external_essl3; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_blend_equation_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_blend_func_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_blend_subtract; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_ETC1_RGB8_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_copy_image; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_depth24; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_depth32; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_depth_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_draw_buffers_indexed; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_draw_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_element_index_uint; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_extended_matrix_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_fbo_render_mipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_fragment_precision_high; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_framebuffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_geometry_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_geometry_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_get_program_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_gpu_shader5; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_mapbuffer; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_matrix_get; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_matrix_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_packed_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_point_size_array; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_point_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_required_internalformat; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_rgb8_rgba8; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_sample_shading; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_sample_variables; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_shader_image_atomic; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_shader_io_blocks; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_shader_multisample_interpolation; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_standard_derivatives; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_stencil1; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_stencil4; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_stencil8; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_surfaceless_context; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_tessellation_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_tessellation_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_3D; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_compression_astc; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_cube_map_array; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_env_crossbar; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_mirrored_repeat; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_npot; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_stencil8; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_storage_multisample_2d_array; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_texture_view; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_vertex_half_float; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_vertex_type_10_10_10_2; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; -GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview; -GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview2; -GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview_multisampled_render_to_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; -GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_YUV_texture_gather; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_alpha_test; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_binning_control; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_driver_control; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get2; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_framebuffer_foveated; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_perfmon_global_mode; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_shader_framebuffer_fetch_noncoherent; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_shader_framebuffer_fetch_rate; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_texture_foveated; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_texture_foveated_subsampled_layout; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_tiled_rendering; -GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_writeonly_rendering; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_0_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_1_compatibility; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_enable; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_error_string; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_extension_query; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_log; -GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_proc_address; -GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; -GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_clip_band_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_line_texgen; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multitexture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_shared_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_g_instruments; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_r_instruments; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_timer_instruments; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cadd; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cmultiply; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_calligraphic_fragment; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_matrix_accuracy; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_table_index_mode; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_complex_polar; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cylinder_texgen; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_datapipe; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_decimation; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_pass_instrument; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_dvc; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_factor_to_alpha; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_layers; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_patchy; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_scale; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_lighting_space; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragments_instrument; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_icc_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_igloo_interface; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_image_compression; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_impact_pixel_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_instrument_error; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_line_quality_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg1; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg2; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nonlinear_lighting_pervertex; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nurbs_eval; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_occlusion_instrument; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_packed_6bytes; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_tiles; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_polynomial_ffd; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_quad_mesh; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_scalebias_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_slim; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_spotlight_cutoff; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subdiv_patch; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subsample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_mipmap_anisotropic; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_phase; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_supersample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vector_ops; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb_subsample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcba; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex_type; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_fft; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_VIV_shader_binary; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_scene_markerXXX; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; -/* ------------------------------------------------------------------------- */ - -/* error codes */ -#define GLEW_OK 0 -#define GLEW_NO_ERROR 0 -#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ -#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* Need at least OpenGL 1.1 */ -#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */ -#define GLEW_ERROR_NO_GLX_DISPLAY 4 /* Need GLX display for GLX support */ - -/* string codes */ -#define GLEW_VERSION 1 -#define GLEW_VERSION_MAJOR 2 -#define GLEW_VERSION_MINOR 3 -#define GLEW_VERSION_MICRO 4 - -/* ------------------------------------------------------------------------- */ - -/* GLEW version info */ - -/* -VERSION 2.2.0 -VERSION_MAJOR 2 -VERSION_MINOR 2 -VERSION_MICRO 0 -*/ - -/* API */ -GLEWAPI GLenum GLEWAPIENTRY glewInit (void); -GLEWAPI GLboolean GLEWAPIENTRY glewIsSupported (const char *name); -#define glewIsExtensionSupported(x) glewIsSupported(x) - -#ifndef GLEW_GET_VAR -#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) -#endif - -#ifndef GLEW_GET_FUN -#define GLEW_GET_FUN(x) x -#endif - -GLEWAPI GLboolean glewExperimental; -GLEWAPI GLboolean GLEWAPIENTRY glewGetExtension (const char *name); -GLEWAPI const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error); -GLEWAPI const GLubyte * GLEWAPIENTRY glewGetString (GLenum name); - -#ifdef __cplusplus -} -#endif - -#ifdef GLEW_APIENTRY_DEFINED -#undef GLEW_APIENTRY_DEFINED -#undef APIENTRY -#endif - -#ifdef GLEW_CALLBACK_DEFINED -#undef GLEW_CALLBACK_DEFINED -#undef CALLBACK -#endif - -#ifdef GLEW_WINGDIAPI_DEFINED -#undef GLEW_WINGDIAPI_DEFINED -#undef WINGDIAPI -#endif - -#undef GLAPI -/* #undef GLEWAPI */ - -#endif /* __glew_h__ */ diff --git a/sdk/include/GL/glxew.h b/sdk/include/GL/glxew.h deleted file mode 100644 index 0474ed5ed8c..00000000000 --- a/sdk/include/GL/glxew.h +++ /dev/null @@ -1,1831 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2008-2019, Nigel Stewart -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __glxew_h__ -#define __glxew_h__ -#define __GLXEW_H__ - -#ifdef __glxext_h_ -#error glxext.h included before glxew.h -#endif - -#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) -#error glx.h included before glxew.h -#endif - -#define __glxext_h_ - -#define GLX_H -#define __GLX_glx_h__ -#define __glx_h__ - -#include -#include -#include - -#ifndef GLEW_INCLUDE -# include -#else -# include GLEW_INCLUDE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ - -#ifndef GLX_VERSION_1_0 -#define GLX_VERSION_1_0 1 - -#define GLX_USE_GL 1 -#define GLX_BUFFER_SIZE 2 -#define GLX_LEVEL 3 -#define GLX_RGBA 4 -#define GLX_DOUBLEBUFFER 5 -#define GLX_STEREO 6 -#define GLX_AUX_BUFFERS 7 -#define GLX_RED_SIZE 8 -#define GLX_GREEN_SIZE 9 -#define GLX_BLUE_SIZE 10 -#define GLX_ALPHA_SIZE 11 -#define GLX_DEPTH_SIZE 12 -#define GLX_STENCIL_SIZE 13 -#define GLX_ACCUM_RED_SIZE 14 -#define GLX_ACCUM_GREEN_SIZE 15 -#define GLX_ACCUM_BLUE_SIZE 16 -#define GLX_ACCUM_ALPHA_SIZE 17 -#define GLX_BAD_SCREEN 1 -#define GLX_BAD_ATTRIBUTE 2 -#define GLX_NO_EXTENSION 3 -#define GLX_BAD_VISUAL 4 -#define GLX_BAD_CONTEXT 5 -#define GLX_BAD_VALUE 6 -#define GLX_BAD_ENUM 7 - -typedef XID GLXDrawable; -typedef XID GLXPixmap; -#ifdef __sun -typedef struct __glXContextRec *GLXContext; -#else -typedef struct __GLXcontextRec *GLXContext; -#endif - -typedef unsigned int GLXVideoDeviceNV; - -extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); -extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); -extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); -extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); -extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); -extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); -extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); -extern void glXDestroyContext (Display *dpy, GLXContext ctx); -extern Bool glXIsDirect (Display *dpy, GLXContext ctx); -extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); -extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); -extern GLXContext glXGetCurrentContext (void); -extern GLXDrawable glXGetCurrentDrawable (void); -extern void glXWaitGL (void); -extern void glXWaitX (void); -extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); -extern void glXUseXFont (Font font, int first, int count, int listBase); - -#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) - -#endif /* GLX_VERSION_1_0 */ - -/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ - -#ifndef GLX_VERSION_1_1 -#define GLX_VERSION_1_1 - -#define GLX_VENDOR 0x1 -#define GLX_VERSION 0x2 -#define GLX_EXTENSIONS 0x3 - -extern const char* glXQueryExtensionsString (Display *dpy, int screen); -extern const char* glXGetClientString (Display *dpy, int name); -extern const char* glXQueryServerString (Display *dpy, int screen, int name); - -#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) - -#endif /* GLX_VERSION_1_1 */ - -/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ - -#ifndef GLX_VERSION_1_2 -#define GLX_VERSION_1_2 1 - -typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); - -#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) - -#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) - -#endif /* GLX_VERSION_1_2 */ - -/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ - -#ifndef GLX_VERSION_1_3 -#define GLX_VERSION_1_3 1 - -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 -#define GLX_DONT_CARE 0xFFFFFFFF - -typedef XID GLXFBConfigID; -typedef XID GLXPbuffer; -typedef XID GLXWindow; -typedef struct __GLXFBConfigRec *GLXFBConfig; - -typedef struct { - int event_type; - int draw_type; - unsigned long serial; - Bool send_event; - Display *display; - GLXDrawable drawable; - unsigned int buffer_mask; - unsigned int aux_buffer; - int x, y; - int width, height; - int count; -} GLXPbufferClobberEvent; -typedef union __GLXEvent { - GLXPbufferClobberEvent glxpbufferclobber; - long pad[24]; -} GLXEvent; - -typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); -typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); -typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); -typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); -typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); -typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); -typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); -typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); -typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); -typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); -typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); -typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); -typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); -typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); - -#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) -#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) -#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) -#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) -#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) -#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) -#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) -#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) -#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) -#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) -#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) -#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) -#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) -#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) -#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) -#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) -#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) - -#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) - -#endif /* GLX_VERSION_1_3 */ - -/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ - -#ifndef GLX_VERSION_1_4 -#define GLX_VERSION_1_4 1 - -#define GLX_SAMPLE_BUFFERS 100000 -#define GLX_SAMPLES 100001 - -extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); - -#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) - -#endif /* GLX_VERSION_1_4 */ - -/* -------------------------- GLX_3DFX_multisample ------------------------- */ - -#ifndef GLX_3DFX_multisample -#define GLX_3DFX_multisample 1 - -#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 -#define GLX_SAMPLES_3DFX 0x8051 - -#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) - -#endif /* GLX_3DFX_multisample */ - -/* ------------------------ GLX_AMD_gpu_association ------------------------ */ - -#ifndef GLX_AMD_gpu_association -#define GLX_AMD_gpu_association 1 - -#define GLX_GPU_VENDOR_AMD 0x1F00 -#define GLX_GPU_RENDERER_STRING_AMD 0x1F01 -#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define GLX_GPU_RAM_AMD 0x21A3 -#define GLX_GPU_CLOCK_AMD 0x21A4 -#define GLX_GPU_NUM_PIPES_AMD 0x21A5 -#define GLX_GPU_NUM_SIMD_AMD 0x21A6 -#define GLX_GPU_NUM_RB_AMD 0x21A7 -#define GLX_GPU_NUM_SPI_AMD 0x21A8 - -typedef void ( * PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list); -typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int* attribList); -typedef Bool ( * PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx); -typedef unsigned int ( * PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx); -typedef GLXContext ( * PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef unsigned int ( * PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int* ids); -typedef int ( * PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void* data); -typedef Bool ( * PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx); - -#define glXBlitContextFramebufferAMD GLXEW_GET_FUN(__glewXBlitContextFramebufferAMD) -#define glXCreateAssociatedContextAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAMD) -#define glXCreateAssociatedContextAttribsAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAttribsAMD) -#define glXDeleteAssociatedContextAMD GLXEW_GET_FUN(__glewXDeleteAssociatedContextAMD) -#define glXGetContextGPUIDAMD GLXEW_GET_FUN(__glewXGetContextGPUIDAMD) -#define glXGetCurrentAssociatedContextAMD GLXEW_GET_FUN(__glewXGetCurrentAssociatedContextAMD) -#define glXGetGPUIDsAMD GLXEW_GET_FUN(__glewXGetGPUIDsAMD) -#define glXGetGPUInfoAMD GLXEW_GET_FUN(__glewXGetGPUInfoAMD) -#define glXMakeAssociatedContextCurrentAMD GLXEW_GET_FUN(__glewXMakeAssociatedContextCurrentAMD) - -#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association) - -#endif /* GLX_AMD_gpu_association */ - -/* --------------------- GLX_ARB_context_flush_control --------------------- */ - -#ifndef GLX_ARB_context_flush_control -#define GLX_ARB_context_flush_control 1 - -#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 - -#define GLXEW_ARB_context_flush_control GLXEW_GET_VAR(__GLXEW_ARB_context_flush_control) - -#endif /* GLX_ARB_context_flush_control */ - -/* ------------------------- GLX_ARB_create_context ------------------------ */ - -#ifndef GLX_ARB_create_context -#define GLX_ARB_create_context 1 - -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define GLX_CONTEXT_FLAGS_ARB 0x2094 - -typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list); - -#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) - -#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) - -#endif /* GLX_ARB_create_context */ - -/* -------------------- GLX_ARB_create_context_no_error -------------------- */ - -#ifndef GLX_ARB_create_context_no_error -#define GLX_ARB_create_context_no_error 1 - -#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 - -#define GLXEW_ARB_create_context_no_error GLXEW_GET_VAR(__GLXEW_ARB_create_context_no_error) - -#endif /* GLX_ARB_create_context_no_error */ - -/* --------------------- GLX_ARB_create_context_profile -------------------- */ - -#ifndef GLX_ARB_create_context_profile -#define GLX_ARB_create_context_profile 1 - -#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 - -#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile) - -#endif /* GLX_ARB_create_context_profile */ - -/* ------------------- GLX_ARB_create_context_robustness ------------------- */ - -#ifndef GLX_ARB_create_context_robustness -#define GLX_ARB_create_context_robustness 1 - -#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 - -#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness) - -#endif /* GLX_ARB_create_context_robustness */ - -/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ - -#ifndef GLX_ARB_fbconfig_float -#define GLX_ARB_fbconfig_float 1 - -#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 -#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 - -#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) - -#endif /* GLX_ARB_fbconfig_float */ - -/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ - -#ifndef GLX_ARB_framebuffer_sRGB -#define GLX_ARB_framebuffer_sRGB 1 - -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 - -#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) - -#endif /* GLX_ARB_framebuffer_sRGB */ - -/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ - -#ifndef GLX_ARB_get_proc_address -#define GLX_ARB_get_proc_address 1 - -extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); - -#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) - -#endif /* GLX_ARB_get_proc_address */ - -/* -------------------------- GLX_ARB_multisample -------------------------- */ - -#ifndef GLX_ARB_multisample -#define GLX_ARB_multisample 1 - -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 - -#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) - -#endif /* GLX_ARB_multisample */ - -/* ---------------- GLX_ARB_robustness_application_isolation --------------- */ - -#ifndef GLX_ARB_robustness_application_isolation -#define GLX_ARB_robustness_application_isolation 1 - -#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 - -#define GLXEW_ARB_robustness_application_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_application_isolation) - -#endif /* GLX_ARB_robustness_application_isolation */ - -/* ---------------- GLX_ARB_robustness_share_group_isolation --------------- */ - -#ifndef GLX_ARB_robustness_share_group_isolation -#define GLX_ARB_robustness_share_group_isolation 1 - -#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 - -#define GLXEW_ARB_robustness_share_group_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_share_group_isolation) - -#endif /* GLX_ARB_robustness_share_group_isolation */ - -/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */ - -#ifndef GLX_ARB_vertex_buffer_object -#define GLX_ARB_vertex_buffer_object 1 - -#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 - -#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object) - -#endif /* GLX_ARB_vertex_buffer_object */ - -/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ - -#ifndef GLX_ATI_pixel_format_float -#define GLX_ATI_pixel_format_float 1 - -#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 - -#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) - -#endif /* GLX_ATI_pixel_format_float */ - -/* ------------------------- GLX_ATI_render_texture ------------------------ */ - -#ifndef GLX_ATI_render_texture -#define GLX_ATI_render_texture 1 - -#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 -#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 -#define GLX_TEXTURE_FORMAT_ATI 0x9802 -#define GLX_TEXTURE_TARGET_ATI 0x9803 -#define GLX_MIPMAP_TEXTURE_ATI 0x9804 -#define GLX_TEXTURE_RGB_ATI 0x9805 -#define GLX_TEXTURE_RGBA_ATI 0x9806 -#define GLX_NO_TEXTURE_ATI 0x9807 -#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 -#define GLX_TEXTURE_1D_ATI 0x9809 -#define GLX_TEXTURE_2D_ATI 0x980A -#define GLX_MIPMAP_LEVEL_ATI 0x980B -#define GLX_CUBE_MAP_FACE_ATI 0x980C -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 -#define GLX_FRONT_LEFT_ATI 0x9813 -#define GLX_FRONT_RIGHT_ATI 0x9814 -#define GLX_BACK_LEFT_ATI 0x9815 -#define GLX_BACK_RIGHT_ATI 0x9816 -#define GLX_AUX0_ATI 0x9817 -#define GLX_AUX1_ATI 0x9818 -#define GLX_AUX2_ATI 0x9819 -#define GLX_AUX3_ATI 0x981A -#define GLX_AUX4_ATI 0x981B -#define GLX_AUX5_ATI 0x981C -#define GLX_AUX6_ATI 0x981D -#define GLX_AUX7_ATI 0x981E -#define GLX_AUX8_ATI 0x981F -#define GLX_AUX9_ATI 0x9820 -#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 -#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 - -typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); -typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); -typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); - -#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) -#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) -#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) - -#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) - -#endif /* GLX_ATI_render_texture */ - -/* --------------------------- GLX_EXT_buffer_age -------------------------- */ - -#ifndef GLX_EXT_buffer_age -#define GLX_EXT_buffer_age 1 - -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 - -#define GLXEW_EXT_buffer_age GLXEW_GET_VAR(__GLXEW_EXT_buffer_age) - -#endif /* GLX_EXT_buffer_age */ - -/* ------------------------ GLX_EXT_context_priority ----------------------- */ - -#ifndef GLX_EXT_context_priority -#define GLX_EXT_context_priority 1 - -#define GLX_CONTEXT_PRIORITY_LEVEL_EXT 0x3100 -#define GLX_CONTEXT_PRIORITY_HIGH_EXT 0x3101 -#define GLX_CONTEXT_PRIORITY_MEDIUM_EXT 0x3102 -#define GLX_CONTEXT_PRIORITY_LOW_EXT 0x3103 - -#define GLXEW_EXT_context_priority GLXEW_GET_VAR(__GLXEW_EXT_context_priority) - -#endif /* GLX_EXT_context_priority */ - -/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */ - -#ifndef GLX_EXT_create_context_es2_profile -#define GLX_EXT_create_context_es2_profile 1 - -#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 - -#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile) - -#endif /* GLX_EXT_create_context_es2_profile */ - -/* ------------------- GLX_EXT_create_context_es_profile ------------------- */ - -#ifndef GLX_EXT_create_context_es_profile -#define GLX_EXT_create_context_es_profile 1 - -#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 - -#define GLXEW_EXT_create_context_es_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es_profile) - -#endif /* GLX_EXT_create_context_es_profile */ - -/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_EXT_fbconfig_packed_float 1 - -#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 -#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 - -#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) - -#endif /* GLX_EXT_fbconfig_packed_float */ - -/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_EXT_framebuffer_sRGB 1 - -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 - -#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) - -#endif /* GLX_EXT_framebuffer_sRGB */ - -/* ------------------------- GLX_EXT_import_context ------------------------ */ - -#ifndef GLX_EXT_import_context -#define GLX_EXT_import_context 1 - -#define GLX_SHARE_CONTEXT_EXT 0x800A -#define GLX_VISUAL_ID_EXT 0x800B -#define GLX_SCREEN_EXT 0x800C - -typedef XID GLXContextID; - -typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); -typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); -typedef Display* ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void); -typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); -typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute, int* value); - -#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) -#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) -#define glXGetCurrentDisplayEXT GLXEW_GET_FUN(__glewXGetCurrentDisplayEXT) -#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) -#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) - -#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) - -#endif /* GLX_EXT_import_context */ - -/* ---------------------------- GLX_EXT_libglvnd --------------------------- */ - -#ifndef GLX_EXT_libglvnd -#define GLX_EXT_libglvnd 1 - -#define GLX_VENDOR_NAMES_EXT 0x20F6 - -#define GLXEW_EXT_libglvnd GLXEW_GET_VAR(__GLXEW_EXT_libglvnd) - -#endif /* GLX_EXT_libglvnd */ - -/* ----------------------- GLX_EXT_no_config_context ----------------------- */ - -#ifndef GLX_EXT_no_config_context -#define GLX_EXT_no_config_context 1 - -#define GLXEW_EXT_no_config_context GLXEW_GET_VAR(__GLXEW_EXT_no_config_context) - -#endif /* GLX_EXT_no_config_context */ - -/* -------------------------- GLX_EXT_scene_marker ------------------------- */ - -#ifndef GLX_EXT_scene_marker -#define GLX_EXT_scene_marker 1 - -#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) - -#endif /* GLX_EXT_scene_marker */ - -/* -------------------------- GLX_EXT_stereo_tree -------------------------- */ - -#ifndef GLX_EXT_stereo_tree -#define GLX_EXT_stereo_tree 1 - -#define GLX_STEREO_NOTIFY_EXT 0x00000000 -#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 -#define GLX_STEREO_TREE_EXT 0x20F5 - -#define GLXEW_EXT_stereo_tree GLXEW_GET_VAR(__GLXEW_EXT_stereo_tree) - -#endif /* GLX_EXT_stereo_tree */ - -/* -------------------------- GLX_EXT_swap_control ------------------------- */ - -#ifndef GLX_EXT_swap_control -#define GLX_EXT_swap_control 1 - -#define GLX_SWAP_INTERVAL_EXT 0x20F1 -#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 - -typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval); - -#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT) - -#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control) - -#endif /* GLX_EXT_swap_control */ - -/* ----------------------- GLX_EXT_swap_control_tear ----------------------- */ - -#ifndef GLX_EXT_swap_control_tear -#define GLX_EXT_swap_control_tear 1 - -#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 - -#define GLXEW_EXT_swap_control_tear GLXEW_GET_VAR(__GLXEW_EXT_swap_control_tear) - -#endif /* GLX_EXT_swap_control_tear */ - -/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_EXT_texture_from_pixmap 1 - -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD -#define GLX_FRONT_EXT 0x20DE -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_EXT 0x20E0 -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB - -typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* dpy, GLXDrawable drawable, int buffer, const int* attrib_list); -typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* dpy, GLXDrawable drawable, int buffer); - -#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) -#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) - -#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) - -#endif /* GLX_EXT_texture_from_pixmap */ - -/* -------------------------- GLX_EXT_visual_info -------------------------- */ - -#ifndef GLX_EXT_visual_info -#define GLX_EXT_visual_info 1 - -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_TRANSPARENT_TYPE_EXT 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 -#define GLX_NONE_EXT 0x8000 -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 - -#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) - -#endif /* GLX_EXT_visual_info */ - -/* ------------------------- GLX_EXT_visual_rating ------------------------- */ - -#ifndef GLX_EXT_visual_rating -#define GLX_EXT_visual_rating 1 - -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D - -#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) - -#endif /* GLX_EXT_visual_rating */ - -/* -------------------------- GLX_INTEL_swap_event ------------------------- */ - -#ifndef GLX_INTEL_swap_event -#define GLX_INTEL_swap_event 1 - -#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 -#define GLX_COPY_COMPLETE_INTEL 0x8181 -#define GLX_FLIP_COMPLETE_INTEL 0x8182 -#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 - -#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event) - -#endif /* GLX_INTEL_swap_event */ - -/* -------------------------- GLX_MESA_agp_offset -------------------------- */ - -#ifndef GLX_MESA_agp_offset -#define GLX_MESA_agp_offset 1 - -typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); - -#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) - -#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) - -#endif /* GLX_MESA_agp_offset */ - -/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ - -#ifndef GLX_MESA_copy_sub_buffer -#define GLX_MESA_copy_sub_buffer 1 - -typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); - -#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) - -#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) - -#endif /* GLX_MESA_copy_sub_buffer */ - -/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ - -#ifndef GLX_MESA_pixmap_colormap -#define GLX_MESA_pixmap_colormap 1 - -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo* visual, Pixmap pixmap, Colormap cmap); - -#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) - -#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) - -#endif /* GLX_MESA_pixmap_colormap */ - -/* ------------------------ GLX_MESA_query_renderer ------------------------ */ - -#ifndef GLX_MESA_query_renderer -#define GLX_MESA_query_renderer 1 - -#define GLX_RENDERER_VENDOR_ID_MESA 0x8183 -#define GLX_RENDERER_DEVICE_ID_MESA 0x8184 -#define GLX_RENDERER_VERSION_MESA 0x8185 -#define GLX_RENDERER_ACCELERATED_MESA 0x8186 -#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187 -#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188 -#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189 -#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A -#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B -#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C -#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D - -typedef Bool ( * PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int* value); -typedef const char* ( * PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute); -typedef Bool ( * PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display* dpy, int screen, int renderer, int attribute, unsigned int* value); -typedef const char* ( * PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display* dpy, int screen, int renderer, int attribute); - -#define glXQueryCurrentRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererIntegerMESA) -#define glXQueryCurrentRendererStringMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererStringMESA) -#define glXQueryRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryRendererIntegerMESA) -#define glXQueryRendererStringMESA GLXEW_GET_FUN(__glewXQueryRendererStringMESA) - -#define GLXEW_MESA_query_renderer GLXEW_GET_VAR(__GLXEW_MESA_query_renderer) - -#endif /* GLX_MESA_query_renderer */ - -/* ------------------------ GLX_MESA_release_buffers ----------------------- */ - -#ifndef GLX_MESA_release_buffers -#define GLX_MESA_release_buffers 1 - -typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable drawable); - -#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) - -#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) - -#endif /* GLX_MESA_release_buffers */ - -/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_MESA_set_3dfx_mode 1 - -#define GLX_3DFX_WINDOW_MODE_MESA 0x1 -#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 - -typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); - -#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) - -#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) - -#endif /* GLX_MESA_set_3dfx_mode */ - -/* ------------------------- GLX_MESA_swap_control ------------------------- */ - -#ifndef GLX_MESA_swap_control -#define GLX_MESA_swap_control 1 - -typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void); -typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); - -#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA) -#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA) - -#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control) - -#endif /* GLX_MESA_swap_control */ - -/* --------------------------- GLX_NV_copy_buffer -------------------------- */ - -#ifndef GLX_NV_copy_buffer -#define GLX_NV_copy_buffer 1 - -typedef void ( * PFNGLXCOPYBUFFERSUBDATANVPROC) (Display* dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void ( * PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display* dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); - -#define glXCopyBufferSubDataNV GLXEW_GET_FUN(__glewXCopyBufferSubDataNV) -#define glXNamedCopyBufferSubDataNV GLXEW_GET_FUN(__glewXNamedCopyBufferSubDataNV) - -#define GLXEW_NV_copy_buffer GLXEW_GET_VAR(__GLXEW_NV_copy_buffer) - -#endif /* GLX_NV_copy_buffer */ - -/* --------------------------- GLX_NV_copy_image --------------------------- */ - -#ifndef GLX_NV_copy_image -#define GLX_NV_copy_image 1 - -typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - -#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV) - -#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image) - -#endif /* GLX_NV_copy_image */ - -/* ------------------------ GLX_NV_delay_before_swap ----------------------- */ - -#ifndef GLX_NV_delay_before_swap -#define GLX_NV_delay_before_swap 1 - -typedef Bool ( * PFNGLXDELAYBEFORESWAPNVPROC) (Display* dpy, GLXDrawable drawable, GLfloat seconds); - -#define glXDelayBeforeSwapNV GLXEW_GET_FUN(__glewXDelayBeforeSwapNV) - -#define GLXEW_NV_delay_before_swap GLXEW_GET_VAR(__GLXEW_NV_delay_before_swap) - -#endif /* GLX_NV_delay_before_swap */ - -/* -------------------------- GLX_NV_float_buffer -------------------------- */ - -#ifndef GLX_NV_float_buffer -#define GLX_NV_float_buffer 1 - -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 - -#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) - -#endif /* GLX_NV_float_buffer */ - -/* ------------------------ GLX_NV_multigpu_context ------------------------ */ - -#ifndef GLX_NV_multigpu_context -#define GLX_NV_multigpu_context 1 - -#define GLX_CONTEXT_MULTIGPU_ATTRIB_NV 0x20AA -#define GLX_CONTEXT_MULTIGPU_ATTRIB_SINGLE_NV 0x20AB -#define GLX_CONTEXT_MULTIGPU_ATTRIB_AFR_NV 0x20AC -#define GLX_CONTEXT_MULTIGPU_ATTRIB_MULTICAST_NV 0x20AD -#define GLX_CONTEXT_MULTIGPU_ATTRIB_MULTI_DISPLAY_MULTICAST_NV 0x20AE - -#define GLXEW_NV_multigpu_context GLXEW_GET_VAR(__GLXEW_NV_multigpu_context) - -#endif /* GLX_NV_multigpu_context */ - -/* ---------------------- GLX_NV_multisample_coverage ---------------------- */ - -#ifndef GLX_NV_multisample_coverage -#define GLX_NV_multisample_coverage 1 - -#define GLX_COLOR_SAMPLES_NV 0x20B3 -#define GLX_COVERAGE_SAMPLES_NV 100001 - -#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage) - -#endif /* GLX_NV_multisample_coverage */ - -/* -------------------------- GLX_NV_present_video ------------------------- */ - -#ifndef GLX_NV_present_video -#define GLX_NV_present_video 1 - -#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 - -typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int* attrib_list); -typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display* dpy, int screen, int* nelements); - -#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) -#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) - -#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) - -#endif /* GLX_NV_present_video */ - -/* ------------------ GLX_NV_robustness_video_memory_purge ----------------- */ - -#ifndef GLX_NV_robustness_video_memory_purge -#define GLX_NV_robustness_video_memory_purge 1 - -#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 - -#define GLXEW_NV_robustness_video_memory_purge GLXEW_GET_VAR(__GLXEW_NV_robustness_video_memory_purge) - -#endif /* GLX_NV_robustness_video_memory_purge */ - -/* --------------------------- GLX_NV_swap_group --------------------------- */ - -#ifndef GLX_NV_swap_group -#define GLX_NV_swap_group 1 - -typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); -typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); -typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint* count); -typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint* maxGroups, GLuint* maxBarriers); -typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint* group, GLuint* barrier); -typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); - -#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) -#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) -#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) -#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) -#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) -#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) - -#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) - -#endif /* GLX_NV_swap_group */ - -/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ - -#ifndef GLX_NV_vertex_array_range -#define GLX_NV_vertex_array_range 1 - -typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); -typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); - -#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) -#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) - -#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) - -#endif /* GLX_NV_vertex_array_range */ - -/* -------------------------- GLX_NV_video_capture ------------------------- */ - -#ifndef GLX_NV_video_capture -#define GLX_NV_video_capture 1 - -#define GLX_DEVICE_ID_NV 0x20CD -#define GLX_UNIQUE_ID_NV 0x20CE -#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF - -typedef XID GLXVideoCaptureDeviceNV; - -typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); -typedef GLXVideoCaptureDeviceNV* ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display* dpy, int screen, int* nelements); -typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); -typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int* value); -typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); - -#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV) -#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV) -#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV) -#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV) -#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV) - -#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture) - -#endif /* GLX_NV_video_capture */ - -/* ---------------------------- GLX_NV_video_out --------------------------- */ - -#ifndef GLX_NV_video_out -#define GLX_NV_video_out 1 - -#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 -#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 -#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 -#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 -#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 -#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA -#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB -#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC - -typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); -typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV* pVideoDevice); -typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long* pulCounterOutputVideo); -typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); -typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); -typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long* pulCounterPbuffer, GLboolean bBlock); - -#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) -#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) -#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) -#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) -#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) -#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) - -#define GLXEW_NV_video_out GLXEW_GET_VAR(__GLXEW_NV_video_out) - -#endif /* GLX_NV_video_out */ - -/* -------------------------- GLX_OML_swap_method -------------------------- */ - -#ifndef GLX_OML_swap_method -#define GLX_OML_swap_method 1 - -#define GLX_SWAP_METHOD_OML 0x8060 -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 - -#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) - -#endif /* GLX_OML_swap_method */ - -/* -------------------------- GLX_OML_sync_control ------------------------- */ - -#ifndef GLX_OML_sync_control -#define GLX_OML_sync_control 1 - -typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); -typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); -typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); -typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); - -#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) -#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) -#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) -#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) -#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) - -#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) - -#endif /* GLX_OML_sync_control */ - -/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ - -#ifndef GLX_SGIS_blended_overlay -#define GLX_SGIS_blended_overlay 1 - -#define GLX_BLENDED_RGBA_SGIS 0x8025 - -#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) - -#endif /* GLX_SGIS_blended_overlay */ - -/* -------------------------- GLX_SGIS_color_range ------------------------- */ - -#ifndef GLX_SGIS_color_range -#define GLX_SGIS_color_range 1 - -#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) - -#endif /* GLX_SGIS_color_range */ - -/* -------------------------- GLX_SGIS_multisample ------------------------- */ - -#ifndef GLX_SGIS_multisample -#define GLX_SGIS_multisample 1 - -#define GLX_SAMPLE_BUFFERS_SGIS 100000 -#define GLX_SAMPLES_SGIS 100001 - -#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) - -#endif /* GLX_SGIS_multisample */ - -/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ - -#ifndef GLX_SGIS_shared_multisample -#define GLX_SGIS_shared_multisample 1 - -#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 -#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 - -#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) - -#endif /* GLX_SGIS_shared_multisample */ - -/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ - -#ifndef GLX_SGIX_fbconfig -#define GLX_SGIX_fbconfig 1 - -#define GLX_RGBA_BIT_SGIX 0x00000001 -#define GLX_WINDOW_BIT_SGIX 0x00000001 -#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 -#define GLX_PIXMAP_BIT_SGIX 0x00000002 -#define GLX_SCREEN_EXT 0x800C -#define GLX_DRAWABLE_TYPE_SGIX 0x8010 -#define GLX_RENDER_TYPE_SGIX 0x8011 -#define GLX_X_RENDERABLE_SGIX 0x8012 -#define GLX_FBCONFIG_ID_SGIX 0x8013 -#define GLX_RGBA_TYPE_SGIX 0x8014 -#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 - -typedef XID GLXFBConfigIDSGIX; -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; - -typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display* dpy, int screen, int* attrib_list, int* nelements); -typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, Pixmap pixmap); -typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int* value); -typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo* vis); -typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display* dpy, GLXFBConfigSGIX config); - -#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) -#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) -#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) -#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) -#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) -#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) - -#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) - -#endif /* GLX_SGIX_fbconfig */ - -/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ - -#ifndef GLX_SGIX_hyperpipe -#define GLX_SGIX_hyperpipe 1 - -#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 -#define GLX_PIPE_RECT_SGIX 0x00000001 -#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 -#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 -#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 -#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 -#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 -#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 -#define GLX_BAD_HYPERPIPE_SGIX 92 -#define GLX_HYPERPIPE_ID_SGIX 0x8030 - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int networkId; -} GLXHyperpipeNetworkSGIX; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int XOrigin; - int YOrigin; - int maxHeight; - int maxWidth; -} GLXPipeRectLimits; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int channel; - unsigned int participationType; - int timeSlice; -} GLXHyperpipeConfigSGIX; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int srcXOrigin; - int srcYOrigin; - int srcWidth; - int srcHeight; - int destXOrigin; - int destYOrigin; - int destWidth; - int destHeight; -} GLXPipeRect; - -typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); -typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); -typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); -typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); -typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); -typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); - -#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) -#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) -#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) -#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) -#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) -#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) -#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) -#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) - -#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) - -#endif /* GLX_SGIX_hyperpipe */ - -/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ - -#ifndef GLX_SGIX_pbuffer -#define GLX_SGIX_pbuffer 1 - -#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 -#define GLX_PBUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 -#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 -#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 -#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 -#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 -#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 -#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 -#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 -#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 -#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A -#define GLX_PRESERVED_CONTENTS_SGIX 0x801B -#define GLX_LARGEST_PBUFFER_SGIX 0x801C -#define GLX_WIDTH_SGIX 0x801D -#define GLX_HEIGHT_SGIX 0x801E -#define GLX_EVENT_MASK_SGIX 0x801F -#define GLX_DAMAGED_SGIX 0x8020 -#define GLX_SAVED_SGIX 0x8021 -#define GLX_WINDOW_SGIX 0x8022 -#define GLX_PBUFFER_SGIX 0x8023 -#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 - -typedef XID GLXPbufferSGIX; -typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; - -typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int* attrib_list); -typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbufferSGIX pbuf); -typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long* mask); -typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int* value); -typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); - -#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) -#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) -#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) -#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) -#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) - -#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) - -#endif /* GLX_SGIX_pbuffer */ - -/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ - -#ifndef GLX_SGIX_swap_barrier -#define GLX_SGIX_swap_barrier 1 - -typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display* dpy, GLXDrawable drawable, int barrier); -typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display* dpy, int screen, int* max); - -#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) -#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) - -#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) - -#endif /* GLX_SGIX_swap_barrier */ - -/* -------------------------- GLX_SGIX_swap_group -------------------------- */ - -#ifndef GLX_SGIX_swap_group -#define GLX_SGIX_swap_group 1 - -typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display* dpy, GLXDrawable drawable, GLXDrawable member); - -#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) - -#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) - -#endif /* GLX_SGIX_swap_group */ - -/* ------------------------- GLX_SGIX_video_resize ------------------------- */ - -#ifndef GLX_SGIX_video_resize -#define GLX_SGIX_video_resize 1 - -#define GLX_SYNC_FRAME_SGIX 0x00000000 -#define GLX_SYNC_SWAP_SGIX 0x00000001 - -typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); -typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); -typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); -typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int* x, int* y, int* w, int* h); -typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int* dx, int* dy, int* dw, int* dh); - -#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) -#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) -#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) -#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) -#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) - -#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) - -#endif /* GLX_SGIX_video_resize */ - -/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ - -#ifndef GLX_SGIX_visual_select_group -#define GLX_SGIX_visual_select_group 1 - -#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 - -#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) - -#endif /* GLX_SGIX_visual_select_group */ - -/* ---------------------------- GLX_SGI_cushion ---------------------------- */ - -#ifndef GLX_SGI_cushion -#define GLX_SGI_cushion 1 - -typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); - -#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) - -#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) - -#endif /* GLX_SGI_cushion */ - -/* ----------------------- GLX_SGI_make_current_read ----------------------- */ - -#ifndef GLX_SGI_make_current_read -#define GLX_SGI_make_current_read 1 - -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); -typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - -#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) -#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) - -#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) - -#endif /* GLX_SGI_make_current_read */ - -/* -------------------------- GLX_SGI_swap_control ------------------------- */ - -#ifndef GLX_SGI_swap_control -#define GLX_SGI_swap_control 1 - -typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); - -#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) - -#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) - -#endif /* GLX_SGI_swap_control */ - -/* --------------------------- GLX_SGI_video_sync -------------------------- */ - -#ifndef GLX_SGI_video_sync -#define GLX_SGI_video_sync 1 - -typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int* count); -typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); - -#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) -#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) - -#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) - -#endif /* GLX_SGI_video_sync */ - -/* --------------------- GLX_SUN_get_transparent_index --------------------- */ - -#ifndef GLX_SUN_get_transparent_index -#define GLX_SUN_get_transparent_index 1 - -typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long* pTransparentIndex); - -#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) - -#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) - -#endif /* GLX_SUN_get_transparent_index */ - -/* -------------------------- GLX_SUN_video_resize ------------------------- */ - -#ifndef GLX_SUN_video_resize -#define GLX_SUN_video_resize 1 - -#define GLX_VIDEO_RESIZE_SUN 0x8171 -#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD - -typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); -typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); - -#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) -#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) - -#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) - -#endif /* GLX_SUN_video_resize */ - -/* ------------------------------------------------------------------------- */ - -#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT -#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT - -GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; - -GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; -GLXEW_FUN_EXPORT PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; -GLXEW_FUN_EXPORT PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; -GLXEW_FUN_EXPORT PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; -GLXEW_FUN_EXPORT PFNGLXCREATEWINDOWPROC __glewXCreateWindow; -GLXEW_FUN_EXPORT PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; -GLXEW_FUN_EXPORT PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; -GLXEW_FUN_EXPORT PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; -GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; -GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; -GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; -GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; -GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; -GLXEW_FUN_EXPORT PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; -GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTPROC __glewXQueryContext; -GLXEW_FUN_EXPORT PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; -GLXEW_FUN_EXPORT PFNGLXSELECTEVENTPROC __glewXSelectEvent; - -GLXEW_FUN_EXPORT PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD; -GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD; -GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD; -GLXEW_FUN_EXPORT PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD; -GLXEW_FUN_EXPORT PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD; -GLXEW_FUN_EXPORT PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD; -GLXEW_FUN_EXPORT PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD; -GLXEW_FUN_EXPORT PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD; -GLXEW_FUN_EXPORT PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD; - -GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; - -GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; -GLXEW_FUN_EXPORT PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; -GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; - -GLXEW_FUN_EXPORT PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; -GLXEW_FUN_EXPORT PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; -GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYEXTPROC __glewXGetCurrentDisplayEXT; -GLXEW_FUN_EXPORT PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; -GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; - -GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT; - -GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; -GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; - -GLXEW_FUN_EXPORT PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; - -GLXEW_FUN_EXPORT PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; - -GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; - -GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA; -GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA; -GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA; -GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA; - -GLXEW_FUN_EXPORT PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; - -GLXEW_FUN_EXPORT PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; - -GLXEW_FUN_EXPORT PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA; -GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA; - -GLXEW_FUN_EXPORT PFNGLXCOPYBUFFERSUBDATANVPROC __glewXCopyBufferSubDataNV; -GLXEW_FUN_EXPORT PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC __glewXNamedCopyBufferSubDataNV; - -GLXEW_FUN_EXPORT PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV; - -GLXEW_FUN_EXPORT PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV; - -GLXEW_FUN_EXPORT PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; -GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; - -GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; -GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; -GLXEW_FUN_EXPORT PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; -GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; -GLXEW_FUN_EXPORT PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; -GLXEW_FUN_EXPORT PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; - -GLXEW_FUN_EXPORT PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; -GLXEW_FUN_EXPORT PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; - -GLXEW_FUN_EXPORT PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV; -GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV; -GLXEW_FUN_EXPORT PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV; -GLXEW_FUN_EXPORT PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV; -GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV; - -GLXEW_FUN_EXPORT PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; -GLXEW_FUN_EXPORT PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; -GLXEW_FUN_EXPORT PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; -GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; -GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; -GLXEW_FUN_EXPORT PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; - -GLXEW_FUN_EXPORT PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; -GLXEW_FUN_EXPORT PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; -GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; -GLXEW_FUN_EXPORT PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; -GLXEW_FUN_EXPORT PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; - -GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; -GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; -GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; - -GLXEW_FUN_EXPORT PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; -GLXEW_FUN_EXPORT PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; -GLXEW_FUN_EXPORT PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; - -GLXEW_FUN_EXPORT PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; -GLXEW_FUN_EXPORT PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; -GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; -GLXEW_FUN_EXPORT PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; - -GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; - -GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; - -GLXEW_FUN_EXPORT PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; -GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; -GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; -GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; - -GLXEW_FUN_EXPORT PFNGLXCUSHIONSGIPROC __glewXCushionSGI; - -GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; -GLXEW_FUN_EXPORT PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; - -GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; - -GLXEW_FUN_EXPORT PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; -GLXEW_FUN_EXPORT PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; - -GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; - -GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; -GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; -GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0; -GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1; -GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2; -GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_3; -GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_4; -GLXEW_VAR_EXPORT GLboolean __GLXEW_3DFX_multisample; -GLXEW_VAR_EXPORT GLboolean __GLXEW_AMD_gpu_association; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_context_flush_control; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_no_error; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_profile; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_robustness; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_get_proc_address; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_multisample; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_application_isolation; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_share_group_isolation; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; -GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_render_texture; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_buffer_age; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_context_priority; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_libglvnd; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_no_config_context; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_stereo_tree; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control_tear; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_info; -GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_rating; -GLXEW_VAR_EXPORT GLboolean __GLXEW_INTEL_swap_event; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_agp_offset; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_query_renderer; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_release_buffers; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; -GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_swap_control; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_buffer; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_image; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_delay_before_swap; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multigpu_context; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_robustness_video_memory_purge; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture; -GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_out; -GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_swap_method; -GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_sync_control; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_color_range; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_multisample; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_fbconfig; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_pbuffer; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_group; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_video_resize; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_cushion; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_make_current_read; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; -GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize; -/* ------------------------------------------------------------------------ */ - -GLEWAPI GLenum GLEWAPIENTRY glxewInit (); -GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name); - -#ifndef GLXEW_GET_VAR -#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) -#endif - -#ifndef GLXEW_GET_FUN -#define GLXEW_GET_FUN(x) x -#endif - -GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* __glxew_h__ */ diff --git a/sdk/include/GL/wglew.h b/sdk/include/GL/wglew.h deleted file mode 100644 index 7e2d0904cbd..00000000000 --- a/sdk/include/GL/wglew.h +++ /dev/null @@ -1,1468 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2008-2019, Nigel Stewart -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __wglew_h__ -#define __wglew_h__ -#define __WGLEW_H__ - -#ifdef __wglext_h_ -#error wglext.h included before wglew.h -#endif - -#define __wglext_h_ - -#if !defined(WINAPI) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -#include -# undef WIN32_LEAN_AND_MEAN -#endif - -/* - * GLEW_STATIC needs to be set when using the static version. - * GLEW_BUILD is set when building the DLL version. - */ -#ifdef GLEW_STATIC -# define GLEWAPI extern -#else -# ifdef GLEW_BUILD -# define GLEWAPI extern __declspec(dllexport) -# else -# define GLEWAPI extern __declspec(dllimport) -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* -------------------------- WGL_3DFX_multisample ------------------------- */ - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 - -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 - -#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) - -#endif /* WGL_3DFX_multisample */ - -/* ------------------------- WGL_3DL_stereo_control ------------------------ */ - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 - -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 - -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); - -#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) - -#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) - -#endif /* WGL_3DL_stereo_control */ - -/* ------------------------ WGL_AMD_gpu_association ------------------------ */ - -#ifndef WGL_AMD_gpu_association -#define WGL_AMD_gpu_association 1 - -#define WGL_GPU_VENDOR_AMD 0x1F00 -#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 -#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define WGL_GPU_RAM_AMD 0x21A3 -#define WGL_GPU_CLOCK_AMD 0x21A4 -#define WGL_GPU_NUM_PIPES_AMD 0x21A5 -#define WGL_GPU_NUM_SIMD_AMD 0x21A6 -#define WGL_GPU_NUM_RB_AMD 0x21A7 -#define WGL_GPU_NUM_SPI_AMD 0x21A8 - -typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList); -typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); -typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids); -typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data); -typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); - -#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD) -#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD) -#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD) -#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD) -#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD) -#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD) -#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD) -#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD) -#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD) - -#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association) - -#endif /* WGL_AMD_gpu_association */ - -/* ------------------------- WGL_ARB_buffer_region ------------------------- */ - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 - -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 - -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); - -#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) -#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) -#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) -#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) - -#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) - -#endif /* WGL_ARB_buffer_region */ - -/* --------------------- WGL_ARB_context_flush_control --------------------- */ - -#ifndef WGL_ARB_context_flush_control -#define WGL_ARB_context_flush_control 1 - -#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 - -#define WGLEW_ARB_context_flush_control WGLEW_GET_VAR(__WGLEW_ARB_context_flush_control) - -#endif /* WGL_ARB_context_flush_control */ - -/* ------------------------- WGL_ARB_create_context ------------------------ */ - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 - -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define ERROR_INVALID_VERSION_ARB 0x2095 - -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); - -#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) - -#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) - -#endif /* WGL_ARB_create_context */ - -/* -------------------- WGL_ARB_create_context_no_error -------------------- */ - -#ifndef WGL_ARB_create_context_no_error -#define WGL_ARB_create_context_no_error 1 - -#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 - -#define WGLEW_ARB_create_context_no_error WGLEW_GET_VAR(__WGLEW_ARB_create_context_no_error) - -#endif /* WGL_ARB_create_context_no_error */ - -/* --------------------- WGL_ARB_create_context_profile -------------------- */ - -#ifndef WGL_ARB_create_context_profile -#define WGL_ARB_create_context_profile 1 - -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 - -#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile) - -#endif /* WGL_ARB_create_context_profile */ - -/* ------------------- WGL_ARB_create_context_robustness ------------------- */ - -#ifndef WGL_ARB_create_context_robustness -#define WGL_ARB_create_context_robustness 1 - -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 - -#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness) - -#endif /* WGL_ARB_create_context_robustness */ - -/* ----------------------- WGL_ARB_extensions_string ----------------------- */ - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 - -typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); - -#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) - -#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) - -#endif /* WGL_ARB_extensions_string */ - -/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 - -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 - -#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) - -#endif /* WGL_ARB_framebuffer_sRGB */ - -/* ----------------------- WGL_ARB_make_current_read ----------------------- */ - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 - -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 - -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - -#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) -#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) - -#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) - -#endif /* WGL_ARB_make_current_read */ - -/* -------------------------- WGL_ARB_multisample -------------------------- */ - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 - -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 - -#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) - -#endif /* WGL_ARB_multisample */ - -/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 - -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 - -DECLARE_HANDLE(HPBUFFERARB); - -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); - -#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) -#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) -#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) -#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) -#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) - -#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) - -#endif /* WGL_ARB_pbuffer */ - -/* -------------------------- WGL_ARB_pixel_format ------------------------- */ - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 - -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B - -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT* pfValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int* piValues); - -#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) -#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) -#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) - -#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) - -#endif /* WGL_ARB_pixel_format */ - -/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 - -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 - -#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) - -#endif /* WGL_ARB_pixel_format_float */ - -/* ------------------------- WGL_ARB_render_texture ------------------------ */ - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 - -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 - -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); - -#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) -#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) -#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) - -#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) - -#endif /* WGL_ARB_render_texture */ - -/* ---------------- WGL_ARB_robustness_application_isolation --------------- */ - -#ifndef WGL_ARB_robustness_application_isolation -#define WGL_ARB_robustness_application_isolation 1 - -#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 - -#define WGLEW_ARB_robustness_application_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_application_isolation) - -#endif /* WGL_ARB_robustness_application_isolation */ - -/* ---------------- WGL_ARB_robustness_share_group_isolation --------------- */ - -#ifndef WGL_ARB_robustness_share_group_isolation -#define WGL_ARB_robustness_share_group_isolation 1 - -#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 - -#define WGLEW_ARB_robustness_share_group_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_share_group_isolation) - -#endif /* WGL_ARB_robustness_share_group_isolation */ - -/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 - -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#define GL_RGBA_FLOAT_MODE_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 - -#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) - -#endif /* WGL_ATI_pixel_format_float */ - -/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ - -#ifndef WGL_ATI_render_texture_rectangle -#define WGL_ATI_render_texture_rectangle 1 - -#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 - -#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) - -#endif /* WGL_ATI_render_texture_rectangle */ - -/* --------------------------- WGL_EXT_colorspace -------------------------- */ - -#ifndef WGL_EXT_colorspace -#define WGL_EXT_colorspace 1 - -#define WGL_COLORSPACE_SRGB_EXT 0x3089 -#define WGL_COLORSPACE_LINEAR_EXT 0x308A -#define WGL_COLORSPACE_EXT 0x309D - -#define WGLEW_EXT_colorspace WGLEW_GET_VAR(__WGLEW_EXT_colorspace) - -#endif /* WGL_EXT_colorspace */ - -/* ------------------- WGL_EXT_create_context_es2_profile ------------------ */ - -#ifndef WGL_EXT_create_context_es2_profile -#define WGL_EXT_create_context_es2_profile 1 - -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 - -#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile) - -#endif /* WGL_EXT_create_context_es2_profile */ - -/* ------------------- WGL_EXT_create_context_es_profile ------------------- */ - -#ifndef WGL_EXT_create_context_es_profile -#define WGL_EXT_create_context_es_profile 1 - -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 - -#define WGLEW_EXT_create_context_es_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es_profile) - -#endif /* WGL_EXT_create_context_es_profile */ - -/* -------------------------- WGL_EXT_depth_float -------------------------- */ - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 - -#define WGL_DEPTH_FLOAT_EXT 0x2040 - -#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) - -#endif /* WGL_EXT_depth_float */ - -/* ---------------------- WGL_EXT_display_color_table ---------------------- */ - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 - -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort* table, GLuint length); - -#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) -#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) -#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) -#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) - -#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) - -#endif /* WGL_EXT_display_color_table */ - -/* ----------------------- WGL_EXT_extensions_string ----------------------- */ - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 - -typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); - -#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) - -#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) - -#endif /* WGL_EXT_extensions_string */ - -/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 - -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 - -#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) - -#endif /* WGL_EXT_framebuffer_sRGB */ - -/* ----------------------- WGL_EXT_make_current_read ----------------------- */ - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 - -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 - -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - -#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) -#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) - -#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) - -#endif /* WGL_EXT_make_current_read */ - -/* -------------------------- WGL_EXT_multisample -------------------------- */ - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 - -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 - -#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) - -#endif /* WGL_EXT_multisample */ - -/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 - -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 - -DECLARE_HANDLE(HPBUFFEREXT); - -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); - -#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) -#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) -#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) -#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) -#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) - -#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) - -#endif /* WGL_EXT_pbuffer */ - -/* -------------------------- WGL_EXT_pixel_format ------------------------- */ - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 - -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C - -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT* pfValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int* piValues); - -#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) -#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) -#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) - -#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) - -#endif /* WGL_EXT_pixel_format */ - -/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 - -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 - -#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) - -#endif /* WGL_EXT_pixel_format_packed_float */ - -/* -------------------------- WGL_EXT_swap_control ------------------------- */ - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 - -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - -#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) -#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) - -#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) - -#endif /* WGL_EXT_swap_control */ - -/* ----------------------- WGL_EXT_swap_control_tear ----------------------- */ - -#ifndef WGL_EXT_swap_control_tear -#define WGL_EXT_swap_control_tear 1 - -#define WGLEW_EXT_swap_control_tear WGLEW_GET_VAR(__WGLEW_EXT_swap_control_tear) - -#endif /* WGL_EXT_swap_control_tear */ - -/* --------------------- WGL_I3D_digital_video_control --------------------- */ - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 - -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 - -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); - -#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) -#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) - -#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) - -#endif /* WGL_I3D_digital_video_control */ - -/* ----------------------------- WGL_I3D_gamma ----------------------------- */ - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 - -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F - -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT* puGreen, USHORT* puBlue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT* puGreen, const USHORT* puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); - -#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) -#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) -#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) -#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) - -#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) - -#endif /* WGL_I3D_gamma */ - -/* ---------------------------- WGL_I3D_genlock ---------------------------- */ - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 - -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C - -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT* uMaxPixelDelay); - -#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) -#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) -#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) -#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) -#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) -#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) -#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) -#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) -#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) -#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) -#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) -#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) - -#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) - -#endif /* WGL_I3D_genlock */ - -/* -------------------------- WGL_I3D_image_buffer ------------------------- */ - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 - -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 - -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE* pEvent, const LPVOID* pAddress, const DWORD* pSize, UINT count); -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID* pAddress, UINT count); - -#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) -#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) -#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) -#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) - -#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) - -#endif /* WGL_I3D_image_buffer */ - -/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 - -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); - -#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) -#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) -#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) -#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) - -#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) - -#endif /* WGL_I3D_swap_frame_lock */ - -/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 - -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD* pMissedFrames, float* pLastMissedUsage); - -#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) -#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) -#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) -#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) - -#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) - -#endif /* WGL_I3D_swap_frame_usage */ - -/* --------------------------- WGL_NV_DX_interop --------------------------- */ - -#ifndef WGL_NV_DX_interop -#define WGL_NV_DX_interop 1 - -#define WGL_ACCESS_READ_ONLY_NV 0x00000000 -#define WGL_ACCESS_READ_WRITE_NV 0x00000001 -#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 - -typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); -typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); -typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); -typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); -typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); -typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); -typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); - -#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV) -#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV) -#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV) -#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV) -#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV) -#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV) -#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV) -#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV) - -#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop) - -#endif /* WGL_NV_DX_interop */ - -/* --------------------------- WGL_NV_DX_interop2 -------------------------- */ - -#ifndef WGL_NV_DX_interop2 -#define WGL_NV_DX_interop2 1 - -#define WGLEW_NV_DX_interop2 WGLEW_GET_VAR(__WGLEW_NV_DX_interop2) - -#endif /* WGL_NV_DX_interop2 */ - -/* --------------------------- WGL_NV_copy_image --------------------------- */ - -#ifndef WGL_NV_copy_image -#define WGL_NV_copy_image 1 - -typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - -#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV) - -#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image) - -#endif /* WGL_NV_copy_image */ - -/* ------------------------ WGL_NV_delay_before_swap ----------------------- */ - -#ifndef WGL_NV_delay_before_swap -#define WGL_NV_delay_before_swap 1 - -typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); - -#define wglDelayBeforeSwapNV WGLEW_GET_FUN(__wglewDelayBeforeSwapNV) - -#define WGLEW_NV_delay_before_swap WGLEW_GET_VAR(__WGLEW_NV_delay_before_swap) - -#endif /* WGL_NV_delay_before_swap */ - -/* -------------------------- WGL_NV_float_buffer -------------------------- */ - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 - -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 - -#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) - -#endif /* WGL_NV_float_buffer */ - -/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 - -#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 - -DECLARE_HANDLE(HGPUNV); -typedef struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -} GPU_DEVICE, *PGPU_DEVICE; - -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); - -#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) -#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) -#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) -#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) -#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) - -#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) - -#endif /* WGL_NV_gpu_affinity */ - -/* ------------------------ WGL_NV_multigpu_context ------------------------ */ - -#ifndef WGL_NV_multigpu_context -#define WGL_NV_multigpu_context 1 - -#define WGL_CONTEXT_MULTIGPU_ATTRIB_NV 0x20AA -#define WGL_CONTEXT_MULTIGPU_ATTRIB_SINGLE_NV 0x20AB -#define WGL_CONTEXT_MULTIGPU_ATTRIB_AFR_NV 0x20AC -#define WGL_CONTEXT_MULTIGPU_ATTRIB_MULTICAST_NV 0x20AD -#define WGL_CONTEXT_MULTIGPU_ATTRIB_MULTI_DISPLAY_MULTICAST_NV 0x20AE - -#define WGLEW_NV_multigpu_context WGLEW_GET_VAR(__WGLEW_NV_multigpu_context) - -#endif /* WGL_NV_multigpu_context */ - -/* ---------------------- WGL_NV_multisample_coverage ---------------------- */ - -#ifndef WGL_NV_multisample_coverage -#define WGL_NV_multisample_coverage 1 - -#define WGL_COVERAGE_SAMPLES_NV 0x2042 -#define WGL_COLOR_SAMPLES_NV 0x20B9 - -#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage) - -#endif /* WGL_NV_multisample_coverage */ - -/* -------------------------- WGL_NV_present_video ------------------------- */ - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 - -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 - -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); - -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); - -#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) -#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) -#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) - -#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) - -#endif /* WGL_NV_present_video */ - -/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ - -#ifndef WGL_NV_render_depth_texture -#define WGL_NV_render_depth_texture 1 - -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 - -#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) - -#endif /* WGL_NV_render_depth_texture */ - -/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_NV_render_texture_rectangle 1 - -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 - -#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) - -#endif /* WGL_NV_render_texture_rectangle */ - -/* --------------------------- WGL_NV_swap_group --------------------------- */ - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 - -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint* maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint* barrier); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); - -#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) -#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) -#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) -#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) -#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) -#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) - -#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) - -#endif /* WGL_NV_swap_group */ - -/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 - -typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void* pointer); - -#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) -#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) - -#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) - -#endif /* WGL_NV_vertex_array_range */ - -/* -------------------------- WGL_NV_video_capture ------------------------- */ - -#ifndef WGL_NV_video_capture -#define WGL_NV_video_capture 1 - -#define WGL_UNIQUE_ID_NV 0x20CE -#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF - -DECLARE_HANDLE(HVIDEOINPUTDEVICENV); - -typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList); -typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int* piValue); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); - -#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV) -#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV) -#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV) -#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV) -#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV) - -#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture) - -#endif /* WGL_NV_video_capture */ - -/* -------------------------- WGL_NV_video_output -------------------------- */ - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 - -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC - -DECLARE_HANDLE(HPVIDEODEV); - -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long* pulCounterOutputVideo); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); - -#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) -#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) -#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) -#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) -#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) -#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) - -#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) - -#endif /* WGL_NV_video_output */ - -/* -------------------------- WGL_OML_sync_control ------------------------- */ - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 - -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32* denominator); -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64* msc, INT64* sbc); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64* msc, INT64* sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64* msc, INT64* sbc); - -#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) -#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) -#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) -#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) -#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) -#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) - -#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) - -#endif /* WGL_OML_sync_control */ - -/* ------------------------------------------------------------------------- */ - -#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT -#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT - -WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; - -WGLEW_FUN_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD; -WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD; -WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD; -WGLEW_FUN_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD; -WGLEW_FUN_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD; -WGLEW_FUN_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD; -WGLEW_FUN_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD; -WGLEW_FUN_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD; -WGLEW_FUN_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD; - -WGLEW_FUN_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; -WGLEW_FUN_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; -WGLEW_FUN_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; -WGLEW_FUN_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; - -WGLEW_FUN_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; - -WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; - -WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; -WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; - -WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; -WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; -WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; -WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; -WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; - -WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; -WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; -WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; - -WGLEW_FUN_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; -WGLEW_FUN_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; -WGLEW_FUN_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; - -WGLEW_FUN_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; -WGLEW_FUN_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; -WGLEW_FUN_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; -WGLEW_FUN_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; - -WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; - -WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; -WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; - -WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; -WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; -WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; -WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; -WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; - -WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; -WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; -WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; - -WGLEW_FUN_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; -WGLEW_FUN_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; - -WGLEW_FUN_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; -WGLEW_FUN_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; - -WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; -WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; -WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; -WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; - -WGLEW_FUN_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; -WGLEW_FUN_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; -WGLEW_FUN_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; -WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; -WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; -WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; -WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; -WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; -WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; -WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; -WGLEW_FUN_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; -WGLEW_FUN_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; - -WGLEW_FUN_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; -WGLEW_FUN_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; -WGLEW_FUN_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; -WGLEW_FUN_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; - -WGLEW_FUN_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; -WGLEW_FUN_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; -WGLEW_FUN_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; -WGLEW_FUN_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; - -WGLEW_FUN_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; -WGLEW_FUN_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; -WGLEW_FUN_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; -WGLEW_FUN_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; - -WGLEW_FUN_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV; -WGLEW_FUN_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV; -WGLEW_FUN_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV; -WGLEW_FUN_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV; -WGLEW_FUN_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV; -WGLEW_FUN_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV; -WGLEW_FUN_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV; -WGLEW_FUN_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV; - -WGLEW_FUN_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV; - -WGLEW_FUN_EXPORT PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV; - -WGLEW_FUN_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; -WGLEW_FUN_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; -WGLEW_FUN_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; -WGLEW_FUN_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; -WGLEW_FUN_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; - -WGLEW_FUN_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; -WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; -WGLEW_FUN_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; - -WGLEW_FUN_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; -WGLEW_FUN_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; -WGLEW_FUN_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; -WGLEW_FUN_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; -WGLEW_FUN_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; -WGLEW_FUN_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; - -WGLEW_FUN_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; -WGLEW_FUN_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; - -WGLEW_FUN_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV; -WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV; -WGLEW_FUN_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV; -WGLEW_FUN_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV; -WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV; - -WGLEW_FUN_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; -WGLEW_FUN_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; -WGLEW_FUN_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; -WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; -WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; -WGLEW_FUN_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; - -WGLEW_FUN_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; -WGLEW_FUN_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; -WGLEW_FUN_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; -WGLEW_FUN_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; -WGLEW_FUN_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; -WGLEW_FUN_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; -WGLEW_VAR_EXPORT GLboolean __WGLEW_3DFX_multisample; -WGLEW_VAR_EXPORT GLboolean __WGLEW_3DL_stereo_control; -WGLEW_VAR_EXPORT GLboolean __WGLEW_AMD_gpu_association; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_buffer_region; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_context_flush_control; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_no_error; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_profile; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_robustness; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_extensions_string; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_make_current_read; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_multisample; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pbuffer; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_render_texture; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_application_isolation; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_share_group_isolation; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; -WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_colorspace; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es_profile; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_depth_float; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_display_color_table; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_extensions_string; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_make_current_read; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_multisample; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pbuffer; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control; -WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control_tear; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_digital_video_control; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_gamma; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_genlock; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_image_buffer; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; -WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop2; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_copy_image; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_delay_before_swap; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_float_buffer; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_gpu_affinity; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multigpu_context; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multisample_coverage; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_present_video; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_depth_texture; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_swap_group; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture; -WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output; -WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control; -/* ------------------------------------------------------------------------- */ - -GLEWAPI GLenum GLEWAPIENTRY wglewInit (); -GLEWAPI GLboolean GLEWAPIENTRY wglewIsSupported (const char *name); - -#ifndef WGLEW_GET_VAR -#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) -#endif - -#ifndef WGLEW_GET_FUN -#define WGLEW_GET_FUN(x) x -#endif - -GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name); - -#ifdef __cplusplus -} -#endif - -#undef GLEWAPI - -#endif /* __wglew_h__ */ diff --git a/sdk/include/KHR/khrplatform.h b/sdk/include/KHR/khrplatform.h new file mode 100644 index 00000000000..01646449cae --- /dev/null +++ b/sdk/include/KHR/khrplatform.h @@ -0,0 +1,311 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/sdk/include/glad/gl.c b/sdk/include/glad/gl.c new file mode 100644 index 00000000000..19eb733855d --- /dev/null +++ b/sdk/include/glad/gl.c @@ -0,0 +1,13288 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include +#include +#include +#include + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GL_VERSION_1_0 = 0; +int GLAD_GL_VERSION_1_1 = 0; +int GLAD_GL_VERSION_1_2 = 0; +int GLAD_GL_VERSION_1_3 = 0; +int GLAD_GL_VERSION_1_4 = 0; +int GLAD_GL_VERSION_1_5 = 0; +int GLAD_GL_VERSION_2_0 = 0; +int GLAD_GL_VERSION_2_1 = 0; +int GLAD_GL_VERSION_3_0 = 0; +int GLAD_GL_VERSION_3_1 = 0; +int GLAD_GL_VERSION_3_2 = 0; +int GLAD_GL_VERSION_3_3 = 0; +int GLAD_GL_VERSION_4_0 = 0; +int GLAD_GL_VERSION_4_1 = 0; +int GLAD_GL_VERSION_4_2 = 0; +int GLAD_GL_VERSION_4_3 = 0; +int GLAD_GL_VERSION_4_4 = 0; +int GLAD_GL_VERSION_4_5 = 0; +int GLAD_GL_VERSION_4_6 = 0; +int GLAD_GL_VERSION_ES_CM_1_0 = 0; +int GLAD_GL_ES_VERSION_2_0 = 0; +int GLAD_GL_ES_VERSION_3_0 = 0; +int GLAD_GL_ES_VERSION_3_1 = 0; +int GLAD_GL_ES_VERSION_3_2 = 0; +int GLAD_GL_3DFX_multisample = 0; +int GLAD_GL_3DFX_tbuffer = 0; +int GLAD_GL_3DFX_texture_compression_FXT1 = 0; +int GLAD_GL_AMD_blend_minmax_factor = 0; +int GLAD_GL_AMD_conservative_depth = 0; +int GLAD_GL_AMD_debug_output = 0; +int GLAD_GL_AMD_depth_clamp_separate = 0; +int GLAD_GL_AMD_draw_buffers_blend = 0; +int GLAD_GL_AMD_framebuffer_multisample_advanced = 0; +int GLAD_GL_AMD_framebuffer_sample_positions = 0; +int GLAD_GL_AMD_gcn_shader = 0; +int GLAD_GL_AMD_gpu_shader_half_float = 0; +int GLAD_GL_AMD_gpu_shader_int16 = 0; +int GLAD_GL_AMD_gpu_shader_int64 = 0; +int GLAD_GL_AMD_interleaved_elements = 0; +int GLAD_GL_AMD_multi_draw_indirect = 0; +int GLAD_GL_AMD_name_gen_delete = 0; +int GLAD_GL_AMD_occlusion_query_event = 0; +int GLAD_GL_AMD_performance_monitor = 0; +int GLAD_GL_AMD_pinned_memory = 0; +int GLAD_GL_AMD_query_buffer_object = 0; +int GLAD_GL_AMD_sample_positions = 0; +int GLAD_GL_AMD_seamless_cubemap_per_texture = 0; +int GLAD_GL_AMD_shader_atomic_counter_ops = 0; +int GLAD_GL_AMD_shader_ballot = 0; +int GLAD_GL_AMD_shader_explicit_vertex_parameter = 0; +int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = 0; +int GLAD_GL_AMD_shader_image_load_store_lod = 0; +int GLAD_GL_AMD_shader_stencil_export = 0; +int GLAD_GL_AMD_shader_trinary_minmax = 0; +int GLAD_GL_AMD_sparse_texture = 0; +int GLAD_GL_AMD_stencil_operation_extended = 0; +int GLAD_GL_AMD_texture_gather_bias_lod = 0; +int GLAD_GL_AMD_texture_texture4 = 0; +int GLAD_GL_AMD_transform_feedback3_lines_triangles = 0; +int GLAD_GL_AMD_transform_feedback4 = 0; +int GLAD_GL_AMD_vertex_shader_layer = 0; +int GLAD_GL_AMD_vertex_shader_tessellator = 0; +int GLAD_GL_AMD_vertex_shader_viewport_index = 0; +int GLAD_GL_APPLE_aux_depth_stencil = 0; +int GLAD_GL_APPLE_client_storage = 0; +int GLAD_GL_APPLE_element_array = 0; +int GLAD_GL_APPLE_fence = 0; +int GLAD_GL_APPLE_float_pixels = 0; +int GLAD_GL_APPLE_flush_buffer_range = 0; +int GLAD_GL_APPLE_object_purgeable = 0; +int GLAD_GL_APPLE_rgb_422 = 0; +int GLAD_GL_APPLE_row_bytes = 0; +int GLAD_GL_APPLE_specular_vector = 0; +int GLAD_GL_APPLE_texture_range = 0; +int GLAD_GL_APPLE_transform_hint = 0; +int GLAD_GL_APPLE_vertex_array_object = 0; +int GLAD_GL_APPLE_vertex_array_range = 0; +int GLAD_GL_APPLE_vertex_program_evaluators = 0; +int GLAD_GL_APPLE_ycbcr_422 = 0; +int GLAD_GL_ARB_ES2_compatibility = 0; +int GLAD_GL_ARB_ES3_1_compatibility = 0; +int GLAD_GL_ARB_ES3_2_compatibility = 0; +int GLAD_GL_ARB_ES3_compatibility = 0; +int GLAD_GL_ARB_arrays_of_arrays = 0; +int GLAD_GL_ARB_base_instance = 0; +int GLAD_GL_ARB_bindless_texture = 0; +int GLAD_GL_ARB_blend_func_extended = 0; +int GLAD_GL_ARB_buffer_storage = 0; +int GLAD_GL_ARB_cl_event = 0; +int GLAD_GL_ARB_clear_buffer_object = 0; +int GLAD_GL_ARB_clear_texture = 0; +int GLAD_GL_ARB_clip_control = 0; +int GLAD_GL_ARB_color_buffer_float = 0; +int GLAD_GL_ARB_compatibility = 0; +int GLAD_GL_ARB_compressed_texture_pixel_storage = 0; +int GLAD_GL_ARB_compute_shader = 0; +int GLAD_GL_ARB_compute_variable_group_size = 0; +int GLAD_GL_ARB_conditional_render_inverted = 0; +int GLAD_GL_ARB_conservative_depth = 0; +int GLAD_GL_ARB_copy_buffer = 0; +int GLAD_GL_ARB_copy_image = 0; +int GLAD_GL_ARB_cull_distance = 0; +int GLAD_GL_ARB_debug_output = 0; +int GLAD_GL_ARB_depth_buffer_float = 0; +int GLAD_GL_ARB_depth_clamp = 0; +int GLAD_GL_ARB_depth_texture = 0; +int GLAD_GL_ARB_derivative_control = 0; +int GLAD_GL_ARB_direct_state_access = 0; +int GLAD_GL_ARB_draw_buffers = 0; +int GLAD_GL_ARB_draw_buffers_blend = 0; +int GLAD_GL_ARB_draw_elements_base_vertex = 0; +int GLAD_GL_ARB_draw_indirect = 0; +int GLAD_GL_ARB_draw_instanced = 0; +int GLAD_GL_ARB_enhanced_layouts = 0; +int GLAD_GL_ARB_explicit_attrib_location = 0; +int GLAD_GL_ARB_explicit_uniform_location = 0; +int GLAD_GL_ARB_fragment_coord_conventions = 0; +int GLAD_GL_ARB_fragment_layer_viewport = 0; +int GLAD_GL_ARB_fragment_program = 0; +int GLAD_GL_ARB_fragment_program_shadow = 0; +int GLAD_GL_ARB_fragment_shader = 0; +int GLAD_GL_ARB_fragment_shader_interlock = 0; +int GLAD_GL_ARB_framebuffer_no_attachments = 0; +int GLAD_GL_ARB_framebuffer_object = 0; +int GLAD_GL_ARB_framebuffer_sRGB = 0; +int GLAD_GL_ARB_geometry_shader4 = 0; +int GLAD_GL_ARB_get_program_binary = 0; +int GLAD_GL_ARB_get_texture_sub_image = 0; +int GLAD_GL_ARB_gl_spirv = 0; +int GLAD_GL_ARB_gpu_shader5 = 0; +int GLAD_GL_ARB_gpu_shader_fp64 = 0; +int GLAD_GL_ARB_gpu_shader_int64 = 0; +int GLAD_GL_ARB_half_float_pixel = 0; +int GLAD_GL_ARB_half_float_vertex = 0; +int GLAD_GL_ARB_imaging = 0; +int GLAD_GL_ARB_indirect_parameters = 0; +int GLAD_GL_ARB_instanced_arrays = 0; +int GLAD_GL_ARB_internalformat_query = 0; +int GLAD_GL_ARB_internalformat_query2 = 0; +int GLAD_GL_ARB_invalidate_subdata = 0; +int GLAD_GL_ARB_map_buffer_alignment = 0; +int GLAD_GL_ARB_map_buffer_range = 0; +int GLAD_GL_ARB_matrix_palette = 0; +int GLAD_GL_ARB_multi_bind = 0; +int GLAD_GL_ARB_multi_draw_indirect = 0; +int GLAD_GL_ARB_multisample = 0; +int GLAD_GL_ARB_multitexture = 0; +int GLAD_GL_ARB_occlusion_query = 0; +int GLAD_GL_ARB_occlusion_query2 = 0; +int GLAD_GL_ARB_parallel_shader_compile = 0; +int GLAD_GL_ARB_pipeline_statistics_query = 0; +int GLAD_GL_ARB_pixel_buffer_object = 0; +int GLAD_GL_ARB_point_parameters = 0; +int GLAD_GL_ARB_point_sprite = 0; +int GLAD_GL_ARB_polygon_offset_clamp = 0; +int GLAD_GL_ARB_post_depth_coverage = 0; +int GLAD_GL_ARB_program_interface_query = 0; +int GLAD_GL_ARB_provoking_vertex = 0; +int GLAD_GL_ARB_query_buffer_object = 0; +int GLAD_GL_ARB_robust_buffer_access_behavior = 0; +int GLAD_GL_ARB_robustness = 0; +int GLAD_GL_ARB_robustness_isolation = 0; +int GLAD_GL_ARB_sample_locations = 0; +int GLAD_GL_ARB_sample_shading = 0; +int GLAD_GL_ARB_sampler_objects = 0; +int GLAD_GL_ARB_seamless_cube_map = 0; +int GLAD_GL_ARB_seamless_cubemap_per_texture = 0; +int GLAD_GL_ARB_separate_shader_objects = 0; +int GLAD_GL_ARB_shader_atomic_counter_ops = 0; +int GLAD_GL_ARB_shader_atomic_counters = 0; +int GLAD_GL_ARB_shader_ballot = 0; +int GLAD_GL_ARB_shader_bit_encoding = 0; +int GLAD_GL_ARB_shader_clock = 0; +int GLAD_GL_ARB_shader_draw_parameters = 0; +int GLAD_GL_ARB_shader_group_vote = 0; +int GLAD_GL_ARB_shader_image_load_store = 0; +int GLAD_GL_ARB_shader_image_size = 0; +int GLAD_GL_ARB_shader_objects = 0; +int GLAD_GL_ARB_shader_precision = 0; +int GLAD_GL_ARB_shader_stencil_export = 0; +int GLAD_GL_ARB_shader_storage_buffer_object = 0; +int GLAD_GL_ARB_shader_subroutine = 0; +int GLAD_GL_ARB_shader_texture_image_samples = 0; +int GLAD_GL_ARB_shader_texture_lod = 0; +int GLAD_GL_ARB_shader_viewport_layer_array = 0; +int GLAD_GL_ARB_shading_language_100 = 0; +int GLAD_GL_ARB_shading_language_420pack = 0; +int GLAD_GL_ARB_shading_language_include = 0; +int GLAD_GL_ARB_shading_language_packing = 0; +int GLAD_GL_ARB_shadow = 0; +int GLAD_GL_ARB_shadow_ambient = 0; +int GLAD_GL_ARB_sparse_buffer = 0; +int GLAD_GL_ARB_sparse_texture = 0; +int GLAD_GL_ARB_sparse_texture2 = 0; +int GLAD_GL_ARB_sparse_texture_clamp = 0; +int GLAD_GL_ARB_spirv_extensions = 0; +int GLAD_GL_ARB_stencil_texturing = 0; +int GLAD_GL_ARB_sync = 0; +int GLAD_GL_ARB_tessellation_shader = 0; +int GLAD_GL_ARB_texture_barrier = 0; +int GLAD_GL_ARB_texture_border_clamp = 0; +int GLAD_GL_ARB_texture_buffer_object = 0; +int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0; +int GLAD_GL_ARB_texture_buffer_range = 0; +int GLAD_GL_ARB_texture_compression = 0; +int GLAD_GL_ARB_texture_compression_bptc = 0; +int GLAD_GL_ARB_texture_compression_rgtc = 0; +int GLAD_GL_ARB_texture_cube_map = 0; +int GLAD_GL_ARB_texture_cube_map_array = 0; +int GLAD_GL_ARB_texture_env_add = 0; +int GLAD_GL_ARB_texture_env_combine = 0; +int GLAD_GL_ARB_texture_env_crossbar = 0; +int GLAD_GL_ARB_texture_env_dot3 = 0; +int GLAD_GL_ARB_texture_filter_anisotropic = 0; +int GLAD_GL_ARB_texture_filter_minmax = 0; +int GLAD_GL_ARB_texture_float = 0; +int GLAD_GL_ARB_texture_gather = 0; +int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0; +int GLAD_GL_ARB_texture_mirrored_repeat = 0; +int GLAD_GL_ARB_texture_multisample = 0; +int GLAD_GL_ARB_texture_non_power_of_two = 0; +int GLAD_GL_ARB_texture_query_levels = 0; +int GLAD_GL_ARB_texture_query_lod = 0; +int GLAD_GL_ARB_texture_rectangle = 0; +int GLAD_GL_ARB_texture_rg = 0; +int GLAD_GL_ARB_texture_rgb10_a2ui = 0; +int GLAD_GL_ARB_texture_stencil8 = 0; +int GLAD_GL_ARB_texture_storage = 0; +int GLAD_GL_ARB_texture_storage_multisample = 0; +int GLAD_GL_ARB_texture_swizzle = 0; +int GLAD_GL_ARB_texture_view = 0; +int GLAD_GL_ARB_timer_query = 0; +int GLAD_GL_ARB_transform_feedback2 = 0; +int GLAD_GL_ARB_transform_feedback3 = 0; +int GLAD_GL_ARB_transform_feedback_instanced = 0; +int GLAD_GL_ARB_transform_feedback_overflow_query = 0; +int GLAD_GL_ARB_transpose_matrix = 0; +int GLAD_GL_ARB_uniform_buffer_object = 0; +int GLAD_GL_ARB_vertex_array_bgra = 0; +int GLAD_GL_ARB_vertex_array_object = 0; +int GLAD_GL_ARB_vertex_attrib_64bit = 0; +int GLAD_GL_ARB_vertex_attrib_binding = 0; +int GLAD_GL_ARB_vertex_blend = 0; +int GLAD_GL_ARB_vertex_buffer_object = 0; +int GLAD_GL_ARB_vertex_program = 0; +int GLAD_GL_ARB_vertex_shader = 0; +int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = 0; +int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0; +int GLAD_GL_ARB_viewport_array = 0; +int GLAD_GL_ARB_window_pos = 0; +int GLAD_GL_ATI_draw_buffers = 0; +int GLAD_GL_ATI_element_array = 0; +int GLAD_GL_ATI_envmap_bumpmap = 0; +int GLAD_GL_ATI_fragment_shader = 0; +int GLAD_GL_ATI_map_object_buffer = 0; +int GLAD_GL_ATI_meminfo = 0; +int GLAD_GL_ATI_pixel_format_float = 0; +int GLAD_GL_ATI_pn_triangles = 0; +int GLAD_GL_ATI_separate_stencil = 0; +int GLAD_GL_ATI_text_fragment_shader = 0; +int GLAD_GL_ATI_texture_env_combine3 = 0; +int GLAD_GL_ATI_texture_float = 0; +int GLAD_GL_ATI_texture_mirror_once = 0; +int GLAD_GL_ATI_vertex_array_object = 0; +int GLAD_GL_ATI_vertex_attrib_array_object = 0; +int GLAD_GL_ATI_vertex_streams = 0; +int GLAD_GL_EXT_422_pixels = 0; +int GLAD_GL_EXT_EGL_image_storage = 0; +int GLAD_GL_EXT_EGL_sync = 0; +int GLAD_GL_EXT_abgr = 0; +int GLAD_GL_EXT_bgra = 0; +int GLAD_GL_EXT_bindable_uniform = 0; +int GLAD_GL_EXT_blend_color = 0; +int GLAD_GL_EXT_blend_equation_separate = 0; +int GLAD_GL_EXT_blend_func_separate = 0; +int GLAD_GL_EXT_blend_logic_op = 0; +int GLAD_GL_EXT_blend_minmax = 0; +int GLAD_GL_EXT_blend_subtract = 0; +int GLAD_GL_EXT_clip_volume_hint = 0; +int GLAD_GL_EXT_cmyka = 0; +int GLAD_GL_EXT_color_subtable = 0; +int GLAD_GL_EXT_compiled_vertex_array = 0; +int GLAD_GL_EXT_convolution = 0; +int GLAD_GL_EXT_coordinate_frame = 0; +int GLAD_GL_EXT_copy_texture = 0; +int GLAD_GL_EXT_cull_vertex = 0; +int GLAD_GL_EXT_debug_label = 0; +int GLAD_GL_EXT_debug_marker = 0; +int GLAD_GL_EXT_depth_bounds_test = 0; +int GLAD_GL_EXT_direct_state_access = 0; +int GLAD_GL_EXT_draw_buffers2 = 0; +int GLAD_GL_EXT_draw_instanced = 0; +int GLAD_GL_EXT_draw_range_elements = 0; +int GLAD_GL_EXT_external_buffer = 0; +int GLAD_GL_EXT_fog_coord = 0; +int GLAD_GL_EXT_framebuffer_blit = 0; +int GLAD_GL_EXT_framebuffer_blit_layers = 0; +int GLAD_GL_EXT_framebuffer_multisample = 0; +int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0; +int GLAD_GL_EXT_framebuffer_object = 0; +int GLAD_GL_EXT_framebuffer_sRGB = 0; +int GLAD_GL_EXT_geometry_shader4 = 0; +int GLAD_GL_EXT_gpu_program_parameters = 0; +int GLAD_GL_EXT_gpu_shader4 = 0; +int GLAD_GL_EXT_histogram = 0; +int GLAD_GL_EXT_index_array_formats = 0; +int GLAD_GL_EXT_index_func = 0; +int GLAD_GL_EXT_index_material = 0; +int GLAD_GL_EXT_index_texture = 0; +int GLAD_GL_EXT_light_texture = 0; +int GLAD_GL_EXT_memory_object = 0; +int GLAD_GL_EXT_memory_object_fd = 0; +int GLAD_GL_EXT_memory_object_win32 = 0; +int GLAD_GL_EXT_misc_attribute = 0; +int GLAD_GL_EXT_multi_draw_arrays = 0; +int GLAD_GL_EXT_multisample = 0; +int GLAD_GL_EXT_multiview_tessellation_geometry_shader = 0; +int GLAD_GL_EXT_multiview_texture_multisample = 0; +int GLAD_GL_EXT_multiview_timer_query = 0; +int GLAD_GL_EXT_packed_depth_stencil = 0; +int GLAD_GL_EXT_packed_float = 0; +int GLAD_GL_EXT_packed_pixels = 0; +int GLAD_GL_EXT_paletted_texture = 0; +int GLAD_GL_EXT_pixel_buffer_object = 0; +int GLAD_GL_EXT_pixel_transform = 0; +int GLAD_GL_EXT_pixel_transform_color_table = 0; +int GLAD_GL_EXT_point_parameters = 0; +int GLAD_GL_EXT_polygon_offset = 0; +int GLAD_GL_EXT_polygon_offset_clamp = 0; +int GLAD_GL_EXT_post_depth_coverage = 0; +int GLAD_GL_EXT_provoking_vertex = 0; +int GLAD_GL_EXT_raster_multisample = 0; +int GLAD_GL_EXT_rescale_normal = 0; +int GLAD_GL_EXT_secondary_color = 0; +int GLAD_GL_EXT_semaphore = 0; +int GLAD_GL_EXT_semaphore_fd = 0; +int GLAD_GL_EXT_semaphore_win32 = 0; +int GLAD_GL_EXT_separate_specular_color = 0; +int GLAD_GL_EXT_shader_framebuffer_fetch = 0; +int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = 0; +int GLAD_GL_EXT_shader_image_load_formatted = 0; +int GLAD_GL_EXT_shader_image_load_store = 0; +int GLAD_GL_EXT_shader_integer_mix = 0; +int GLAD_GL_EXT_shader_samples_identical = 0; +int GLAD_GL_EXT_shadow_funcs = 0; +int GLAD_GL_EXT_shared_texture_palette = 0; +int GLAD_GL_EXT_sparse_texture2 = 0; +int GLAD_GL_EXT_stencil_clear_tag = 0; +int GLAD_GL_EXT_stencil_two_side = 0; +int GLAD_GL_EXT_stencil_wrap = 0; +int GLAD_GL_EXT_subtexture = 0; +int GLAD_GL_EXT_texture = 0; +int GLAD_GL_EXT_texture3D = 0; +int GLAD_GL_EXT_texture_array = 0; +int GLAD_GL_EXT_texture_buffer_object = 0; +int GLAD_GL_EXT_texture_compression_latc = 0; +int GLAD_GL_EXT_texture_compression_rgtc = 0; +int GLAD_GL_EXT_texture_compression_s3tc = 0; +int GLAD_GL_EXT_texture_cube_map = 0; +int GLAD_GL_EXT_texture_env_add = 0; +int GLAD_GL_EXT_texture_env_combine = 0; +int GLAD_GL_EXT_texture_env_dot3 = 0; +int GLAD_GL_EXT_texture_filter_anisotropic = 0; +int GLAD_GL_EXT_texture_filter_minmax = 0; +int GLAD_GL_EXT_texture_integer = 0; +int GLAD_GL_EXT_texture_lod_bias = 0; +int GLAD_GL_EXT_texture_mirror_clamp = 0; +int GLAD_GL_EXT_texture_object = 0; +int GLAD_GL_EXT_texture_perturb_normal = 0; +int GLAD_GL_EXT_texture_sRGB = 0; +int GLAD_GL_EXT_texture_sRGB_R8 = 0; +int GLAD_GL_EXT_texture_sRGB_RG8 = 0; +int GLAD_GL_EXT_texture_sRGB_decode = 0; +int GLAD_GL_EXT_texture_shadow_lod = 0; +int GLAD_GL_EXT_texture_shared_exponent = 0; +int GLAD_GL_EXT_texture_snorm = 0; +int GLAD_GL_EXT_texture_storage = 0; +int GLAD_GL_EXT_texture_swizzle = 0; +int GLAD_GL_EXT_timer_query = 0; +int GLAD_GL_EXT_transform_feedback = 0; +int GLAD_GL_EXT_vertex_array = 0; +int GLAD_GL_EXT_vertex_array_bgra = 0; +int GLAD_GL_EXT_vertex_attrib_64bit = 0; +int GLAD_GL_EXT_vertex_shader = 0; +int GLAD_GL_EXT_vertex_weighting = 0; +int GLAD_GL_EXT_win32_keyed_mutex = 0; +int GLAD_GL_EXT_window_rectangles = 0; +int GLAD_GL_EXT_x11_sync_object = 0; +int GLAD_GL_GREMEDY_frame_terminator = 0; +int GLAD_GL_GREMEDY_string_marker = 0; +int GLAD_GL_HP_convolution_border_modes = 0; +int GLAD_GL_HP_image_transform = 0; +int GLAD_GL_HP_occlusion_test = 0; +int GLAD_GL_HP_texture_lighting = 0; +int GLAD_GL_IBM_cull_vertex = 0; +int GLAD_GL_IBM_multimode_draw_arrays = 0; +int GLAD_GL_IBM_rasterpos_clip = 0; +int GLAD_GL_IBM_static_data = 0; +int GLAD_GL_IBM_texture_mirrored_repeat = 0; +int GLAD_GL_IBM_vertex_array_lists = 0; +int GLAD_GL_INGR_blend_func_separate = 0; +int GLAD_GL_INGR_color_clamp = 0; +int GLAD_GL_INGR_interlace_read = 0; +int GLAD_GL_INTEL_blackhole_render = 0; +int GLAD_GL_INTEL_conservative_rasterization = 0; +int GLAD_GL_INTEL_fragment_shader_ordering = 0; +int GLAD_GL_INTEL_framebuffer_CMAA = 0; +int GLAD_GL_INTEL_map_texture = 0; +int GLAD_GL_INTEL_parallel_arrays = 0; +int GLAD_GL_INTEL_performance_query = 0; +int GLAD_GL_KHR_blend_equation_advanced = 0; +int GLAD_GL_KHR_blend_equation_advanced_coherent = 0; +int GLAD_GL_KHR_context_flush_control = 0; +int GLAD_GL_KHR_debug = 0; +int GLAD_GL_KHR_no_error = 0; +int GLAD_GL_KHR_parallel_shader_compile = 0; +int GLAD_GL_KHR_robust_buffer_access_behavior = 0; +int GLAD_GL_KHR_robustness = 0; +int GLAD_GL_KHR_shader_subgroup = 0; +int GLAD_GL_KHR_texture_compression_astc_hdr = 0; +int GLAD_GL_KHR_texture_compression_astc_ldr = 0; +int GLAD_GL_KHR_texture_compression_astc_sliced_3d = 0; +int GLAD_GL_MESAX_texture_stack = 0; +int GLAD_GL_MESA_framebuffer_flip_x = 0; +int GLAD_GL_MESA_framebuffer_flip_y = 0; +int GLAD_GL_MESA_framebuffer_swap_xy = 0; +int GLAD_GL_MESA_pack_invert = 0; +int GLAD_GL_MESA_program_binary_formats = 0; +int GLAD_GL_MESA_resize_buffers = 0; +int GLAD_GL_MESA_shader_integer_functions = 0; +int GLAD_GL_MESA_tile_raster_order = 0; +int GLAD_GL_MESA_window_pos = 0; +int GLAD_GL_MESA_ycbcr_texture = 0; +int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = 0; +int GLAD_GL_NVX_conditional_render = 0; +int GLAD_GL_NVX_gpu_memory_info = 0; +int GLAD_GL_NVX_gpu_multicast2 = 0; +int GLAD_GL_NVX_linked_gpu_multicast = 0; +int GLAD_GL_NVX_progress_fence = 0; +int GLAD_GL_NV_alpha_to_coverage_dither_control = 0; +int GLAD_GL_NV_bindless_multi_draw_indirect = 0; +int GLAD_GL_NV_bindless_multi_draw_indirect_count = 0; +int GLAD_GL_NV_bindless_texture = 0; +int GLAD_GL_NV_blend_equation_advanced = 0; +int GLAD_GL_NV_blend_equation_advanced_coherent = 0; +int GLAD_GL_NV_blend_minmax_factor = 0; +int GLAD_GL_NV_blend_square = 0; +int GLAD_GL_NV_clip_space_w_scaling = 0; +int GLAD_GL_NV_command_list = 0; +int GLAD_GL_NV_compute_program5 = 0; +int GLAD_GL_NV_compute_shader_derivatives = 0; +int GLAD_GL_NV_conditional_render = 0; +int GLAD_GL_NV_conservative_raster = 0; +int GLAD_GL_NV_conservative_raster_dilate = 0; +int GLAD_GL_NV_conservative_raster_pre_snap = 0; +int GLAD_GL_NV_conservative_raster_pre_snap_triangles = 0; +int GLAD_GL_NV_conservative_raster_underestimation = 0; +int GLAD_GL_NV_copy_depth_to_color = 0; +int GLAD_GL_NV_copy_image = 0; +int GLAD_GL_NV_deep_texture3D = 0; +int GLAD_GL_NV_depth_buffer_float = 0; +int GLAD_GL_NV_depth_clamp = 0; +int GLAD_GL_NV_draw_texture = 0; +int GLAD_GL_NV_draw_vulkan_image = 0; +int GLAD_GL_NV_evaluators = 0; +int GLAD_GL_NV_explicit_multisample = 0; +int GLAD_GL_NV_fence = 0; +int GLAD_GL_NV_fill_rectangle = 0; +int GLAD_GL_NV_float_buffer = 0; +int GLAD_GL_NV_fog_distance = 0; +int GLAD_GL_NV_fragment_coverage_to_color = 0; +int GLAD_GL_NV_fragment_program = 0; +int GLAD_GL_NV_fragment_program2 = 0; +int GLAD_GL_NV_fragment_program4 = 0; +int GLAD_GL_NV_fragment_program_option = 0; +int GLAD_GL_NV_fragment_shader_barycentric = 0; +int GLAD_GL_NV_fragment_shader_interlock = 0; +int GLAD_GL_NV_framebuffer_mixed_samples = 0; +int GLAD_GL_NV_framebuffer_multisample_coverage = 0; +int GLAD_GL_NV_geometry_program4 = 0; +int GLAD_GL_NV_geometry_shader4 = 0; +int GLAD_GL_NV_geometry_shader_passthrough = 0; +int GLAD_GL_NV_gpu_multicast = 0; +int GLAD_GL_NV_gpu_program4 = 0; +int GLAD_GL_NV_gpu_program5 = 0; +int GLAD_GL_NV_gpu_program5_mem_extended = 0; +int GLAD_GL_NV_gpu_shader5 = 0; +int GLAD_GL_NV_half_float = 0; +int GLAD_GL_NV_internalformat_sample_query = 0; +int GLAD_GL_NV_light_max_exponent = 0; +int GLAD_GL_NV_memory_attachment = 0; +int GLAD_GL_NV_memory_object_sparse = 0; +int GLAD_GL_NV_mesh_shader = 0; +int GLAD_GL_NV_multisample_coverage = 0; +int GLAD_GL_NV_multisample_filter_hint = 0; +int GLAD_GL_NV_occlusion_query = 0; +int GLAD_GL_NV_packed_depth_stencil = 0; +int GLAD_GL_NV_parameter_buffer_object = 0; +int GLAD_GL_NV_parameter_buffer_object2 = 0; +int GLAD_GL_NV_path_rendering = 0; +int GLAD_GL_NV_path_rendering_shared_edge = 0; +int GLAD_GL_NV_pixel_data_range = 0; +int GLAD_GL_NV_point_sprite = 0; +int GLAD_GL_NV_present_video = 0; +int GLAD_GL_NV_primitive_restart = 0; +int GLAD_GL_NV_primitive_shading_rate = 0; +int GLAD_GL_NV_query_resource = 0; +int GLAD_GL_NV_query_resource_tag = 0; +int GLAD_GL_NV_register_combiners = 0; +int GLAD_GL_NV_register_combiners2 = 0; +int GLAD_GL_NV_representative_fragment_test = 0; +int GLAD_GL_NV_robustness_video_memory_purge = 0; +int GLAD_GL_NV_sample_locations = 0; +int GLAD_GL_NV_sample_mask_override_coverage = 0; +int GLAD_GL_NV_scissor_exclusive = 0; +int GLAD_GL_NV_shader_atomic_counters = 0; +int GLAD_GL_NV_shader_atomic_float = 0; +int GLAD_GL_NV_shader_atomic_float64 = 0; +int GLAD_GL_NV_shader_atomic_fp16_vector = 0; +int GLAD_GL_NV_shader_atomic_int64 = 0; +int GLAD_GL_NV_shader_buffer_load = 0; +int GLAD_GL_NV_shader_buffer_store = 0; +int GLAD_GL_NV_shader_storage_buffer_object = 0; +int GLAD_GL_NV_shader_subgroup_partitioned = 0; +int GLAD_GL_NV_shader_texture_footprint = 0; +int GLAD_GL_NV_shader_thread_group = 0; +int GLAD_GL_NV_shader_thread_shuffle = 0; +int GLAD_GL_NV_shading_rate_image = 0; +int GLAD_GL_NV_stereo_view_rendering = 0; +int GLAD_GL_NV_tessellation_program5 = 0; +int GLAD_GL_NV_texgen_emboss = 0; +int GLAD_GL_NV_texgen_reflection = 0; +int GLAD_GL_NV_texture_barrier = 0; +int GLAD_GL_NV_texture_compression_vtc = 0; +int GLAD_GL_NV_texture_env_combine4 = 0; +int GLAD_GL_NV_texture_expand_normal = 0; +int GLAD_GL_NV_texture_multisample = 0; +int GLAD_GL_NV_texture_rectangle = 0; +int GLAD_GL_NV_texture_rectangle_compressed = 0; +int GLAD_GL_NV_texture_shader = 0; +int GLAD_GL_NV_texture_shader2 = 0; +int GLAD_GL_NV_texture_shader3 = 0; +int GLAD_GL_NV_timeline_semaphore = 0; +int GLAD_GL_NV_transform_feedback = 0; +int GLAD_GL_NV_transform_feedback2 = 0; +int GLAD_GL_NV_uniform_buffer_std430_layout = 0; +int GLAD_GL_NV_uniform_buffer_unified_memory = 0; +int GLAD_GL_NV_vdpau_interop = 0; +int GLAD_GL_NV_vdpau_interop2 = 0; +int GLAD_GL_NV_vertex_array_range = 0; +int GLAD_GL_NV_vertex_array_range2 = 0; +int GLAD_GL_NV_vertex_attrib_integer_64bit = 0; +int GLAD_GL_NV_vertex_buffer_unified_memory = 0; +int GLAD_GL_NV_vertex_program = 0; +int GLAD_GL_NV_vertex_program1_1 = 0; +int GLAD_GL_NV_vertex_program2 = 0; +int GLAD_GL_NV_vertex_program2_option = 0; +int GLAD_GL_NV_vertex_program3 = 0; +int GLAD_GL_NV_vertex_program4 = 0; +int GLAD_GL_NV_video_capture = 0; +int GLAD_GL_NV_viewport_array2 = 0; +int GLAD_GL_NV_viewport_swizzle = 0; +int GLAD_GL_OES_byte_coordinates = 0; +int GLAD_GL_OES_compressed_paletted_texture = 0; +int GLAD_GL_OES_fixed_point = 0; +int GLAD_GL_OES_query_matrix = 0; +int GLAD_GL_OES_read_format = 0; +int GLAD_GL_OES_single_precision = 0; +int GLAD_GL_OML_interlace = 0; +int GLAD_GL_OML_resample = 0; +int GLAD_GL_OML_subsample = 0; +int GLAD_GL_OVR_multiview = 0; +int GLAD_GL_OVR_multiview2 = 0; +int GLAD_GL_PGI_misc_hints = 0; +int GLAD_GL_PGI_vertex_hints = 0; +int GLAD_GL_REND_screen_coordinates = 0; +int GLAD_GL_S3_s3tc = 0; +int GLAD_GL_SGIS_detail_texture = 0; +int GLAD_GL_SGIS_fog_function = 0; +int GLAD_GL_SGIS_generate_mipmap = 0; +int GLAD_GL_SGIS_multisample = 0; +int GLAD_GL_SGIS_pixel_texture = 0; +int GLAD_GL_SGIS_point_line_texgen = 0; +int GLAD_GL_SGIS_point_parameters = 0; +int GLAD_GL_SGIS_sharpen_texture = 0; +int GLAD_GL_SGIS_texture4D = 0; +int GLAD_GL_SGIS_texture_border_clamp = 0; +int GLAD_GL_SGIS_texture_color_mask = 0; +int GLAD_GL_SGIS_texture_edge_clamp = 0; +int GLAD_GL_SGIS_texture_filter4 = 0; +int GLAD_GL_SGIS_texture_lod = 0; +int GLAD_GL_SGIS_texture_select = 0; +int GLAD_GL_SGIX_async = 0; +int GLAD_GL_SGIX_async_histogram = 0; +int GLAD_GL_SGIX_async_pixel = 0; +int GLAD_GL_SGIX_blend_alpha_minmax = 0; +int GLAD_GL_SGIX_calligraphic_fragment = 0; +int GLAD_GL_SGIX_clipmap = 0; +int GLAD_GL_SGIX_convolution_accuracy = 0; +int GLAD_GL_SGIX_depth_pass_instrument = 0; +int GLAD_GL_SGIX_depth_texture = 0; +int GLAD_GL_SGIX_flush_raster = 0; +int GLAD_GL_SGIX_fog_offset = 0; +int GLAD_GL_SGIX_fragment_lighting = 0; +int GLAD_GL_SGIX_framezoom = 0; +int GLAD_GL_SGIX_igloo_interface = 0; +int GLAD_GL_SGIX_instruments = 0; +int GLAD_GL_SGIX_interlace = 0; +int GLAD_GL_SGIX_ir_instrument1 = 0; +int GLAD_GL_SGIX_list_priority = 0; +int GLAD_GL_SGIX_pixel_texture = 0; +int GLAD_GL_SGIX_pixel_tiles = 0; +int GLAD_GL_SGIX_polynomial_ffd = 0; +int GLAD_GL_SGIX_reference_plane = 0; +int GLAD_GL_SGIX_resample = 0; +int GLAD_GL_SGIX_scalebias_hint = 0; +int GLAD_GL_SGIX_shadow = 0; +int GLAD_GL_SGIX_shadow_ambient = 0; +int GLAD_GL_SGIX_sprite = 0; +int GLAD_GL_SGIX_subsample = 0; +int GLAD_GL_SGIX_tag_sample_buffer = 0; +int GLAD_GL_SGIX_texture_add_env = 0; +int GLAD_GL_SGIX_texture_coordinate_clamp = 0; +int GLAD_GL_SGIX_texture_lod_bias = 0; +int GLAD_GL_SGIX_texture_multi_buffer = 0; +int GLAD_GL_SGIX_texture_scale_bias = 0; +int GLAD_GL_SGIX_vertex_preclip = 0; +int GLAD_GL_SGIX_ycrcb = 0; +int GLAD_GL_SGIX_ycrcb_subsample = 0; +int GLAD_GL_SGIX_ycrcba = 0; +int GLAD_GL_SGI_color_matrix = 0; +int GLAD_GL_SGI_color_table = 0; +int GLAD_GL_SGI_texture_color_table = 0; +int GLAD_GL_SUNX_constant_data = 0; +int GLAD_GL_SUN_convolution_border_modes = 0; +int GLAD_GL_SUN_global_alpha = 0; +int GLAD_GL_SUN_mesh_array = 0; +int GLAD_GL_SUN_slice_accum = 0; +int GLAD_GL_SUN_triangle_list = 0; +int GLAD_GL_SUN_vertex = 0; +int GLAD_GL_WIN_phong_shading = 0; +int GLAD_GL_WIN_specular_fog = 0; +int GLAD_GL_AMD_compressed_3DC_texture = 0; +int GLAD_GL_AMD_compressed_ATC_texture = 0; +int GLAD_GL_APPLE_copy_texture_levels = 0; +int GLAD_GL_APPLE_framebuffer_multisample = 0; +int GLAD_GL_APPLE_sync = 0; +int GLAD_GL_APPLE_texture_2D_limited_npot = 0; +int GLAD_GL_APPLE_texture_format_BGRA8888 = 0; +int GLAD_GL_APPLE_texture_max_level = 0; +int GLAD_GL_ARM_rgba8 = 0; +int GLAD_GL_EXT_discard_framebuffer = 0; +int GLAD_GL_EXT_map_buffer_range = 0; +int GLAD_GL_EXT_multisampled_render_to_texture = 0; +int GLAD_GL_EXT_read_format_bgra = 0; +int GLAD_GL_EXT_robustness = 0; +int GLAD_GL_EXT_sRGB = 0; +int GLAD_GL_EXT_texture_compression_dxt1 = 0; +int GLAD_GL_EXT_texture_format_BGRA8888 = 0; +int GLAD_GL_IMG_multisampled_render_to_texture = 0; +int GLAD_GL_IMG_read_format = 0; +int GLAD_GL_IMG_texture_compression_pvrtc = 0; +int GLAD_GL_IMG_texture_env_enhanced_fixed_function = 0; +int GLAD_GL_IMG_user_clip_plane = 0; +int GLAD_GL_OES_EGL_image = 0; +int GLAD_GL_OES_EGL_image_external = 0; +int GLAD_GL_OES_blend_equation_separate = 0; +int GLAD_GL_OES_blend_func_separate = 0; +int GLAD_GL_OES_blend_subtract = 0; +int GLAD_GL_OES_compressed_ETC1_RGB8_sub_texture = 0; +int GLAD_GL_OES_compressed_ETC1_RGB8_texture = 0; +int GLAD_GL_OES_depth24 = 0; +int GLAD_GL_OES_depth32 = 0; +int GLAD_GL_OES_draw_texture = 0; +int GLAD_GL_OES_element_index_uint = 0; +int GLAD_GL_OES_extended_matrix_palette = 0; +int GLAD_GL_OES_fbo_render_mipmap = 0; +int GLAD_GL_OES_framebuffer_object = 0; +int GLAD_GL_OES_mapbuffer = 0; +int GLAD_GL_OES_matrix_get = 0; +int GLAD_GL_OES_matrix_palette = 0; +int GLAD_GL_OES_packed_depth_stencil = 0; +int GLAD_GL_OES_point_size_array = 0; +int GLAD_GL_OES_point_sprite = 0; +int GLAD_GL_OES_required_internalformat = 0; +int GLAD_GL_OES_rgb8_rgba8 = 0; +int GLAD_GL_OES_stencil1 = 0; +int GLAD_GL_OES_stencil4 = 0; +int GLAD_GL_OES_stencil8 = 0; +int GLAD_GL_OES_stencil_wrap = 0; +int GLAD_GL_OES_surfaceless_context = 0; +int GLAD_GL_OES_texture_cube_map = 0; +int GLAD_GL_OES_texture_env_crossbar = 0; +int GLAD_GL_OES_texture_mirrored_repeat = 0; +int GLAD_GL_OES_texture_npot = 0; +int GLAD_GL_OES_vertex_array_object = 0; +int GLAD_GL_QCOM_driver_control = 0; +int GLAD_GL_QCOM_extended_get = 0; +int GLAD_GL_QCOM_extended_get2 = 0; +int GLAD_GL_QCOM_perfmon_global_mode = 0; +int GLAD_GL_QCOM_tiled_rendering = 0; +int GLAD_GL_QCOM_writeonly_rendering = 0; +int GLAD_GL_AMD_program_binary_Z400 = 0; +int GLAD_GL_ANDROID_extension_pack_es31a = 0; +int GLAD_GL_ANGLE_depth_texture = 0; +int GLAD_GL_ANGLE_framebuffer_blit = 0; +int GLAD_GL_ANGLE_framebuffer_multisample = 0; +int GLAD_GL_ANGLE_instanced_arrays = 0; +int GLAD_GL_ANGLE_pack_reverse_row_order = 0; +int GLAD_GL_ANGLE_program_binary = 0; +int GLAD_GL_ANGLE_texture_compression_dxt3 = 0; +int GLAD_GL_ANGLE_texture_compression_dxt5 = 0; +int GLAD_GL_ANGLE_texture_usage = 0; +int GLAD_GL_ANGLE_translated_shader_source = 0; +int GLAD_GL_APPLE_clip_distance = 0; +int GLAD_GL_APPLE_color_buffer_packed_float = 0; +int GLAD_GL_APPLE_texture_packed_float = 0; +int GLAD_GL_ARM_mali_program_binary = 0; +int GLAD_GL_ARM_mali_shader_binary = 0; +int GLAD_GL_ARM_shader_core_properties = 0; +int GLAD_GL_ARM_shader_framebuffer_fetch = 0; +int GLAD_GL_ARM_shader_framebuffer_fetch_depth_stencil = 0; +int GLAD_GL_ARM_texture_unnormalized_coordinates = 0; +int GLAD_GL_DMP_program_binary = 0; +int GLAD_GL_DMP_shader_binary = 0; +int GLAD_GL_EXT_EGL_image_array = 0; +int GLAD_GL_EXT_EGL_image_storage_compression = 0; +int GLAD_GL_EXT_YUV_target = 0; +int GLAD_GL_EXT_base_instance = 0; +int GLAD_GL_EXT_blend_func_extended = 0; +int GLAD_GL_EXT_buffer_storage = 0; +int GLAD_GL_EXT_clear_texture = 0; +int GLAD_GL_EXT_clip_control = 0; +int GLAD_GL_EXT_clip_cull_distance = 0; +int GLAD_GL_EXT_color_buffer_float = 0; +int GLAD_GL_EXT_color_buffer_half_float = 0; +int GLAD_GL_EXT_conservative_depth = 0; +int GLAD_GL_EXT_copy_image = 0; +int GLAD_GL_EXT_depth_clamp = 0; +int GLAD_GL_EXT_disjoint_timer_query = 0; +int GLAD_GL_EXT_draw_buffers = 0; +int GLAD_GL_EXT_draw_buffers_indexed = 0; +int GLAD_GL_EXT_draw_elements_base_vertex = 0; +int GLAD_GL_EXT_draw_transform_feedback = 0; +int GLAD_GL_EXT_float_blend = 0; +int GLAD_GL_EXT_fragment_shading_rate = 0; +int GLAD_GL_EXT_geometry_point_size = 0; +int GLAD_GL_EXT_geometry_shader = 0; +int GLAD_GL_EXT_gpu_shader5 = 0; +int GLAD_GL_EXT_instanced_arrays = 0; +int GLAD_GL_EXT_multi_draw_indirect = 0; +int GLAD_GL_EXT_multisampled_compatibility = 0; +int GLAD_GL_EXT_multisampled_render_to_texture2 = 0; +int GLAD_GL_EXT_multiview_draw_buffers = 0; +int GLAD_GL_EXT_occlusion_query_boolean = 0; +int GLAD_GL_EXT_primitive_bounding_box = 0; +int GLAD_GL_EXT_protected_textures = 0; +int GLAD_GL_EXT_pvrtc_sRGB = 0; +int GLAD_GL_EXT_render_snorm = 0; +int GLAD_GL_EXT_sRGB_write_control = 0; +int GLAD_GL_EXT_separate_depth_stencil = 0; +int GLAD_GL_EXT_separate_shader_objects = 0; +int GLAD_GL_EXT_shader_group_vote = 0; +int GLAD_GL_EXT_shader_implicit_conversions = 0; +int GLAD_GL_EXT_shader_io_blocks = 0; +int GLAD_GL_EXT_shader_non_constant_global_initializers = 0; +int GLAD_GL_EXT_shader_pixel_local_storage = 0; +int GLAD_GL_EXT_shader_pixel_local_storage2 = 0; +int GLAD_GL_EXT_shader_texture_lod = 0; +int GLAD_GL_EXT_shadow_samplers = 0; +int GLAD_GL_EXT_sparse_texture = 0; +int GLAD_GL_EXT_tessellation_point_size = 0; +int GLAD_GL_EXT_tessellation_shader = 0; +int GLAD_GL_EXT_texture_border_clamp = 0; +int GLAD_GL_EXT_texture_buffer = 0; +int GLAD_GL_EXT_texture_compression_astc_decode_mode = 0; +int GLAD_GL_EXT_texture_compression_bptc = 0; +int GLAD_GL_EXT_texture_compression_s3tc_srgb = 0; +int GLAD_GL_EXT_texture_cube_map_array = 0; +int GLAD_GL_EXT_texture_format_sRGB_override = 0; +int GLAD_GL_EXT_texture_mirror_clamp_to_edge = 0; +int GLAD_GL_EXT_texture_norm16 = 0; +int GLAD_GL_EXT_texture_query_lod = 0; +int GLAD_GL_EXT_texture_rg = 0; +int GLAD_GL_EXT_texture_storage_compression = 0; +int GLAD_GL_EXT_texture_type_2_10_10_10_REV = 0; +int GLAD_GL_EXT_texture_view = 0; +int GLAD_GL_EXT_unpack_subimage = 0; +int GLAD_GL_FJ_shader_binary_GCCSO = 0; +int GLAD_GL_IMG_bindless_texture = 0; +int GLAD_GL_IMG_framebuffer_downsample = 0; +int GLAD_GL_IMG_program_binary = 0; +int GLAD_GL_IMG_shader_binary = 0; +int GLAD_GL_IMG_texture_compression_pvrtc2 = 0; +int GLAD_GL_IMG_texture_filter_cubic = 0; +int GLAD_GL_MESA_bgra = 0; +int GLAD_GL_MESA_sampler_objects = 0; +int GLAD_GL_NV_copy_buffer = 0; +int GLAD_GL_NV_coverage_sample = 0; +int GLAD_GL_NV_depth_nonlinear = 0; +int GLAD_GL_NV_draw_buffers = 0; +int GLAD_GL_NV_draw_instanced = 0; +int GLAD_GL_NV_explicit_attrib_location = 0; +int GLAD_GL_NV_fbo_color_attachments = 0; +int GLAD_GL_NV_framebuffer_blit = 0; +int GLAD_GL_NV_framebuffer_multisample = 0; +int GLAD_GL_NV_generate_mipmap_sRGB = 0; +int GLAD_GL_NV_image_formats = 0; +int GLAD_GL_NV_instanced_arrays = 0; +int GLAD_GL_NV_non_square_matrices = 0; +int GLAD_GL_NV_pack_subimage = 0; +int GLAD_GL_NV_pixel_buffer_object = 0; +int GLAD_GL_NV_polygon_mode = 0; +int GLAD_GL_NV_read_buffer = 0; +int GLAD_GL_NV_read_buffer_front = 0; +int GLAD_GL_NV_read_depth = 0; +int GLAD_GL_NV_read_depth_stencil = 0; +int GLAD_GL_NV_read_stencil = 0; +int GLAD_GL_NV_sRGB_formats = 0; +int GLAD_GL_NV_shader_noperspective_interpolation = 0; +int GLAD_GL_NV_shadow_samplers_array = 0; +int GLAD_GL_NV_shadow_samplers_cube = 0; +int GLAD_GL_NV_texture_border_clamp = 0; +int GLAD_GL_NV_texture_compression_s3tc_update = 0; +int GLAD_GL_NV_texture_npot_2D_mipmap = 0; +int GLAD_GL_NV_viewport_array = 0; +int GLAD_GL_OES_EGL_image_external_essl3 = 0; +int GLAD_GL_OES_copy_image = 0; +int GLAD_GL_OES_depth_texture = 0; +int GLAD_GL_OES_draw_buffers_indexed = 0; +int GLAD_GL_OES_draw_elements_base_vertex = 0; +int GLAD_GL_OES_fragment_precision_high = 0; +int GLAD_GL_OES_geometry_point_size = 0; +int GLAD_GL_OES_geometry_shader = 0; +int GLAD_GL_OES_get_program_binary = 0; +int GLAD_GL_OES_gpu_shader5 = 0; +int GLAD_GL_OES_primitive_bounding_box = 0; +int GLAD_GL_OES_sample_shading = 0; +int GLAD_GL_OES_sample_variables = 0; +int GLAD_GL_OES_shader_image_atomic = 0; +int GLAD_GL_OES_shader_io_blocks = 0; +int GLAD_GL_OES_shader_multisample_interpolation = 0; +int GLAD_GL_OES_standard_derivatives = 0; +int GLAD_GL_OES_tessellation_point_size = 0; +int GLAD_GL_OES_tessellation_shader = 0; +int GLAD_GL_OES_texture_3D = 0; +int GLAD_GL_OES_texture_border_clamp = 0; +int GLAD_GL_OES_texture_buffer = 0; +int GLAD_GL_OES_texture_compression_astc = 0; +int GLAD_GL_OES_texture_cube_map_array = 0; +int GLAD_GL_OES_texture_float = 0; +int GLAD_GL_OES_texture_float_linear = 0; +int GLAD_GL_OES_texture_half_float = 0; +int GLAD_GL_OES_texture_half_float_linear = 0; +int GLAD_GL_OES_texture_stencil8 = 0; +int GLAD_GL_OES_texture_storage_multisample_2d_array = 0; +int GLAD_GL_OES_texture_view = 0; +int GLAD_GL_OES_vertex_half_float = 0; +int GLAD_GL_OES_vertex_type_10_10_10_2 = 0; +int GLAD_GL_OES_viewport_array = 0; +int GLAD_GL_OVR_multiview_multisampled_render_to_texture = 0; +int GLAD_GL_QCOM_YUV_texture_gather = 0; +int GLAD_GL_QCOM_alpha_test = 0; +int GLAD_GL_QCOM_binning_control = 0; +int GLAD_GL_QCOM_frame_extrapolation = 0; +int GLAD_GL_QCOM_framebuffer_foveated = 0; +int GLAD_GL_QCOM_motion_estimation = 0; +int GLAD_GL_QCOM_render_sRGB_R8_RG8 = 0; +int GLAD_GL_QCOM_render_shared_exponent = 0; +int GLAD_GL_QCOM_shader_framebuffer_fetch_noncoherent = 0; +int GLAD_GL_QCOM_shader_framebuffer_fetch_rate = 0; +int GLAD_GL_QCOM_shading_rate = 0; +int GLAD_GL_QCOM_texture_foveated = 0; +int GLAD_GL_QCOM_texture_foveated2 = 0; +int GLAD_GL_QCOM_texture_foveated_subsampled_layout = 0; +int GLAD_GL_QCOM_texture_lod_bias = 0; +int GLAD_GL_QCOM_ycbcr_degamma = 0; +int GLAD_GL_VIV_shader_binary = 0; + + + +PFNGLACCUMPROC glad_glAccum = NULL; +PFNGLACCUMXOESPROC glad_glAccumxOES = NULL; +PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT = NULL; +PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; +PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB = NULL; +PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV = NULL; +PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI = NULL; +PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; +PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES = NULL; +PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV = NULL; +PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL = NULL; +PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT = NULL; +PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV = NULL; +PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; +PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT = NULL; +PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; +PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT = NULL; +PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI = NULL; +PFNGLASYNCCOPYBUFFERSUBDATANVXPROC glad_glAsyncCopyBufferSubDataNVX = NULL; +PFNGLASYNCCOPYIMAGESUBDATANVXPROC glad_glAsyncCopyImageSubDataNVX = NULL; +PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX = NULL; +PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINPROC glad_glBegin = NULL; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; +PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV = NULL; +PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI = NULL; +PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV = NULL; +PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD = NULL; +PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB = NULL; +PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT = NULL; +PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV = NULL; +PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT = NULL; +PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERARBPROC glad_glBindBufferARB = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT = NULL; +PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV = NULL; +PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT = NULL; +PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT = NULL; +PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV = NULL; +PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL; +PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; +PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL; +PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; +PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT = NULL; +PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT = NULL; +PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT = NULL; +PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT = NULL; +PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB = NULL; +PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV = NULL; +PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL; +PFNGLBINDSHADINGRATEIMAGENVPROC glad_glBindShadingRateImageNV = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT = NULL; +PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT = NULL; +PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL; +PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; +PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE = NULL; +PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; +PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; +PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT = NULL; +PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV = NULL; +PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT = NULL; +PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT = NULL; +PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT = NULL; +PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT = NULL; +PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT = NULL; +PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT = NULL; +PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT = NULL; +PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT = NULL; +PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT = NULL; +PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT = NULL; +PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT = NULL; +PFNGLBITMAPPROC glad_glBitmap = NULL; +PFNGLBITMAPXOESPROC glad_glBitmapxOES = NULL; +PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL; +PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT = NULL; +PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT = NULL; +PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT = NULL; +PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD = NULL; +PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei = NULL; +PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB = NULL; +PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi = NULL; +PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT = NULL; +PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR = NULL; +PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD = NULL; +PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei = NULL; +PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB = NULL; +PFNGLBLENDFUNCIPROC glad_glBlendFunci = NULL; +PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB = NULL; +PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL; +PFNGLBLITFRAMEBUFFERLAYEREXTPROC glad_glBlitFramebufferLayerEXT = NULL; +PFNGLBLITFRAMEBUFFERLAYERSEXTPROC glad_glBlitFramebufferLayersEXT = NULL; +PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; +PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV = NULL; +PFNGLBUFFERATTACHMEMORYNVPROC glad_glBufferAttachMemoryNV = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERDATAARBPROC glad_glBufferDataARB = NULL; +PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB = NULL; +PFNGLBUFFERPAGECOMMITMENTMEMNVPROC glad_glBufferPageCommitmentMemNV = NULL; +PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE = NULL; +PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; +PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT = NULL; +PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB = NULL; +PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV = NULL; +PFNGLCALLLISTPROC glad_glCallList = NULL; +PFNGLCALLLISTSPROC glad_glCallLists = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT = NULL; +PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; +PFNGLCLAMPCOLORARBPROC glad_glClampColorARB = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; +PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES = NULL; +PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL; +PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT = NULL; +PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT = NULL; +PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES = NULL; +PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; +PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES = NULL; +PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES = NULL; +PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; +PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; +PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL; +PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL; +PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB = NULL; +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI = NULL; +PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT = NULL; +PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC glad_glClientWaitSemaphoreui64NVX = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; +PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; +PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES = NULL; +PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES = NULL; +PFNGLCOLOR3BPROC glad_glColor3b = NULL; +PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; +PFNGLCOLOR3DPROC glad_glColor3d = NULL; +PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; +PFNGLCOLOR3FPROC glad_glColor3f = NULL; +PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN = NULL; +PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; +PFNGLCOLOR3HNVPROC glad_glColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC glad_glColor3hvNV = NULL; +PFNGLCOLOR3IPROC glad_glColor3i = NULL; +PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; +PFNGLCOLOR3SPROC glad_glColor3s = NULL; +PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; +PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; +PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; +PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; +PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; +PFNGLCOLOR3USPROC glad_glColor3us = NULL; +PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; +PFNGLCOLOR3XOESPROC glad_glColor3xOES = NULL; +PFNGLCOLOR3XVOESPROC glad_glColor3xvOES = NULL; +PFNGLCOLOR4BPROC glad_glColor4b = NULL; +PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; +PFNGLCOLOR4DPROC glad_glColor4d = NULL; +PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; +PFNGLCOLOR4FPROC glad_glColor4f = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; +PFNGLCOLOR4HNVPROC glad_glColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC glad_glColor4hvNV = NULL; +PFNGLCOLOR4IPROC glad_glColor4i = NULL; +PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; +PFNGLCOLOR4SPROC glad_glColor4s = NULL; +PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; +PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN = NULL; +PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; +PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; +PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; +PFNGLCOLOR4USPROC glad_glColor4us = NULL; +PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; +PFNGLCOLOR4XOESPROC glad_glColor4xOES = NULL; +PFNGLCOLOR4XVOESPROC glad_glColor4xvOES = NULL; +PFNGLCOLORFORMATNVPROC glad_glColorFormatNV = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT = NULL; +PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; +PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; +PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; +PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; +PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; +PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; +PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; +PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT = NULL; +PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM = NULL; +PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL = NULL; +PFNGLCOLORSUBTABLEPROC glad_glColorSubTable = NULL; +PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT = NULL; +PFNGLCOLORTABLEPROC glad_glColorTable = NULL; +PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI = NULL; +PFNGLCOLORTABLESGIPROC glad_glColorTableSGI = NULL; +PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV = NULL; +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV = NULL; +PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV = NULL; +PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB = NULL; +PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT = NULL; +PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV = NULL; +PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV = NULL; +PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT = NULL; +PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES = NULL; +PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT = NULL; +PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable = NULL; +PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT = NULL; +PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; +PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV = NULL; +PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT = NULL; +PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; +PFNGLCOPYPATHNVPROC glad_glCopyPathNV = NULL; +PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; +PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT = NULL; +PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV = NULL; +PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV = NULL; +PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV = NULL; +PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV = NULL; +PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV = NULL; +PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV = NULL; +PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL; +PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV = NULL; +PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL; +PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL; +PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB = NULL; +PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL; +PFNGLCREATEPROGRESSFENCENVXPROC glad_glCreateProgressFenceNVX = NULL; +PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL; +PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL; +PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL; +PFNGLCREATESEMAPHORESNVPROC glad_glCreateSemaphoresNV = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB = NULL; +PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; +PFNGLCREATESTATESNVPROC glad_glCreateStatesNV = NULL; +PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB = NULL; +PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL; +PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL; +PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT = NULL; +PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB = NULL; +PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; +PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD = NULL; +PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; +PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; +PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; +PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD = NULL; +PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; +PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD = NULL; +PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; +PFNGLDEFORMSGIXPROC glad_glDeformSGIX = NULL; +PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX = NULL; +PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB = NULL; +PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV = NULL; +PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE = NULL; +PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL; +PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; +PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL; +PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB = NULL; +PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD = NULL; +PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV = NULL; +PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV = NULL; +PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD = NULL; +PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; +PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB = NULL; +PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB = NULL; +PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; +PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT = NULL; +PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT = NULL; +PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; +PFNGLDEPTHRANGEARRAYDVNVPROC glad_glDepthRangeArraydvNV = NULL; +PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; +PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; +PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV = NULL; +PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV = NULL; +PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; +PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES = NULL; +PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES = NULL; +PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; +PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT = NULL; +PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT = NULL; +PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT = NULL; +PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT = NULL; +PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB = NULL; +PFNGLDISABLEIPROC glad_glDisablei = NULL; +PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT = NULL; +PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL; +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; +PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL; +PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI = NULL; +PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV = NULL; +PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV = NULL; +PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV = NULL; +PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV = NULL; +PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE = NULL; +PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL; +PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN = NULL; +PFNGLDRAWMESHTASKSINDIRECTNVPROC glad_glDrawMeshTasksIndirectNV = NULL; +PFNGLDRAWMESHTASKSNVPROC glad_glDrawMeshTasksNV = NULL; +PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; +PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT = NULL; +PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV = NULL; +PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; +PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; +PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV = NULL; +PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT = NULL; +PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT = NULL; +PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; +PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV = NULL; +PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM = NULL; +PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; +PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE = NULL; +PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT = NULL; +PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT = NULL; +PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT = NULL; +PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; +PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT = NULL; +PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT = NULL; +PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB = NULL; +PFNGLENABLEIPROC glad_glEnablei = NULL; +PFNGLENDPROC glad_glEnd = NULL; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; +PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX = NULL; +PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI = NULL; +PFNGLENDLISTPROC glad_glEndList = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV = NULL; +PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD = NULL; +PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDQUERYARBPROC glad_glEndQueryARB = NULL; +PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT = NULL; +PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV = NULL; +PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT = NULL; +PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV = NULL; +PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; +PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; +PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; +PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; +PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES = NULL; +PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES = NULL; +PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; +PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; +PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; +PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; +PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES = NULL; +PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES = NULL; +PFNGLEVALMAPSNVPROC glad_glEvalMapsNV = NULL; +PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; +PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; +PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; +PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; +PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB = NULL; +PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT = NULL; +PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; +PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX = NULL; +PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE = NULL; +PFNGLFINISHFENCENVPROC glad_glFinishFenceNV = NULL; +PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE = NULL; +PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT = NULL; +PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV = NULL; +PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX = NULL; +PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM = NULL; +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE = NULL; +PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV = NULL; +PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV = NULL; +PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; +PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM = NULL; +PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; +PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT = NULL; +PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; +PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT = NULL; +PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; +PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT = NULL; +PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; +PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT = NULL; +PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV = NULL; +PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS = NULL; +PFNGLFOGFPROC glad_glFogf = NULL; +PFNGLFOGFVPROC glad_glFogfv = NULL; +PFNGLFOGIPROC glad_glFogi = NULL; +PFNGLFOGIVPROC glad_glFogiv = NULL; +PFNGLFOGXOESPROC glad_glFogxOES = NULL; +PFNGLFOGXVOESPROC glad_glFogxvOES = NULL; +PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX = NULL; +PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY = NULL; +PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX = NULL; +PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT = NULL; +PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT = NULL; +PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; +PFNGLFRAMEBUFFERPARAMETERIMESAPROC glad_glFramebufferParameteriMESA = NULL; +PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB = NULL; +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV = NULL; +PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD = NULL; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB = NULL; +PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB = NULL; +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL; +PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLFRUSTUMPROC glad_glFrustum = NULL; +PFNGLFRUSTUMFOESPROC glad_glFrustumfOES = NULL; +PFNGLFRUSTUMXOESPROC glad_glFrustumxOES = NULL; +PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB = NULL; +PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE = NULL; +PFNGLGENFENCESNVPROC glad_glGenFencesNV = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL; +PFNGLGENLISTSPROC glad_glGenLists = NULL; +PFNGLGENNAMESAMDPROC glad_glGenNamesAMD = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV = NULL; +PFNGLGENPATHSNVPROC glad_glGenPathsNV = NULL; +PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD = NULL; +PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; +PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB = NULL; +PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENQUERIESARBPROC glad_glGenQueriesARB = NULL; +PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT = NULL; +PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; +PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE = NULL; +PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL; +PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT = NULL; +PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL; +PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT = NULL; +PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB = NULL; +PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV = NULL; +PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB = NULL; +PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB = NULL; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; +PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB = NULL; +PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; +PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES = NULL; +PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES = NULL; +PFNGLGETCOLORTABLEPROC glad_glGetColorTable = NULL; +PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI = NULL; +PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV = NULL; +PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV = NULL; +PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT = NULL; +PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; +PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES = NULL; +PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV = NULL; +PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; +PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD = NULL; +PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS = NULL; +PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT = NULL; +PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL; +PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT = NULL; +PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV = NULL; +PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL = NULL; +PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT = NULL; +PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL; +PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS = NULL; +PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC glad_glGetFramebufferParameterivMESA = NULL; +PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL; +PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL; +PFNGLGETHANDLEARBPROC glad_glGetHandleARB = NULL; +PFNGLGETHISTOGRAMPROC glad_glGetHistogram = NULL; +PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES = NULL; +PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB = NULL; +PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP = NULL; +PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB = NULL; +PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV = NULL; +PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV = NULL; +PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; +PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT = NULL; +PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; +PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; +PFNGLGETLIGHTXOESPROC glad_glGetLightxOES = NULL; +PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX = NULL; +PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV = NULL; +PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; +PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; +PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; +PFNGLGETMAPXVOESPROC glad_glGetMapxvOES = NULL; +PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; +PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; +PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES = NULL; +PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC glad_glGetMemoryObjectDetachedResourcesuivNV = NULL; +PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL; +PFNGLGETMINMAXPROC glad_glGetMinmax = NULL; +PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT = NULL; +PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT = NULL; +PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT = NULL; +PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT = NULL; +PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT = NULL; +PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT = NULL; +PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT = NULL; +PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT = NULL; +PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV = NULL; +PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV = NULL; +PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL; +PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT = NULL; +PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL; +PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT = NULL; +PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT = NULL; +PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT = NULL; +PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB = NULL; +PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI = NULL; +PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; +PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB = NULL; +PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV = NULL; +PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV = NULL; +PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV = NULL; +PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV = NULL; +PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV = NULL; +PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV = NULL; +PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV = NULL; +PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV = NULL; +PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV = NULL; +PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV = NULL; +PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV = NULL; +PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV = NULL; +PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV = NULL; +PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV = NULL; +PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL = NULL; +PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD = NULL; +PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD = NULL; +PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD = NULL; +PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD = NULL; +PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL = NULL; +PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL = NULL; +PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL = NULL; +PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; +PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; +PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; +PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv = NULL; +PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS = NULL; +PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT = NULL; +PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT = NULL; +PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT = NULL; +PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; +PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT = NULL; +PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; +PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; +PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV = NULL; +PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV = NULL; +PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; +PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL; +PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB = NULL; +PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV = NULL; +PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB = NULL; +PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV = NULL; +PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL; +PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL; +PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL; +PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL; +PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL; +PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT = NULL; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; +PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSEMAPHOREPARAMETERIVNVPROC glad_glGetSemaphoreParameterivNV = NULL; +PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT = NULL; +PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSHADINGRATEIMAGEPALETTENVPROC glad_glGetShadingRateImagePaletteNV = NULL; +PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC glad_glGetShadingRateSampleLocationivNV = NULL; +PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS = NULL; +PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; +PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI = NULL; +PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; +PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; +PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES = NULL; +PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS = NULL; +PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; +PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; +PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; +PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES = NULL; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES = NULL; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT = NULL; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; +PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT = NULL; +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES = NULL; +PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB = NULL; +PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV = NULL; +PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT = NULL; +PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB = NULL; +PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV = NULL; +PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL; +PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV = NULL; +PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL; +PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL; +PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB = NULL; +PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT = NULL; +PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL; +PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB = NULL; +PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB = NULL; +PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB = NULL; +PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB = NULL; +PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT = NULL; +PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL; +PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT = NULL; +PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV = NULL; +PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL; +PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL; +PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT = NULL; +PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT = NULL; +PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL; +PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT = NULL; +PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV = NULL; +PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB = NULL; +PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV = NULL; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV = NULL; +PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV = NULL; +PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV = NULL; +PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV = NULL; +PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV = NULL; +PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV = NULL; +PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV = NULL; +PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable = NULL; +PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL; +PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter = NULL; +PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL; +PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram = NULL; +PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL; +PFNGLGETNMAPDVPROC glad_glGetnMapdv = NULL; +PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL; +PFNGLGETNMAPFVPROC glad_glGetnMapfv = NULL; +PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL; +PFNGLGETNMAPIVPROC glad_glGetnMapiv = NULL; +PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL; +PFNGLGETNMINMAXPROC glad_glGetnMinmax = NULL; +PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL; +PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv = NULL; +PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL; +PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv = NULL; +PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL; +PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv = NULL; +PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL; +PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple = NULL; +PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL; +PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter = NULL; +PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL; +PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage = NULL; +PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL; +PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv = NULL; +PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL; +PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; +PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL; +PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB = NULL; +PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; +PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL; +PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB = NULL; +PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; +PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL; +PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLHINTPGIPROC glad_glHintPGI = NULL; +PFNGLHISTOGRAMPROC glad_glHistogram = NULL; +PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT = NULL; +PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP = NULL; +PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL; +PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT = NULL; +PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT = NULL; +PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT = NULL; +PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT = NULL; +PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT = NULL; +PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT = NULL; +PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV = NULL; +PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT = NULL; +PFNGLINDEXMASKPROC glad_glIndexMask = NULL; +PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT = NULL; +PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; +PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT = NULL; +PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM = NULL; +PFNGLINDEXDPROC glad_glIndexd = NULL; +PFNGLINDEXDVPROC glad_glIndexdv = NULL; +PFNGLINDEXFPROC glad_glIndexf = NULL; +PFNGLINDEXFVPROC glad_glIndexfv = NULL; +PFNGLINDEXIPROC glad_glIndexi = NULL; +PFNGLINDEXIVPROC glad_glIndexiv = NULL; +PFNGLINDEXSPROC glad_glIndexs = NULL; +PFNGLINDEXSVPROC glad_glIndexsv = NULL; +PFNGLINDEXUBPROC glad_glIndexub = NULL; +PFNGLINDEXUBVPROC glad_glIndexubv = NULL; +PFNGLINDEXXOESPROC glad_glIndexxOES = NULL; +PFNGLINDEXXVOESPROC glad_glIndexxvOES = NULL; +PFNGLINITNAMESPROC glad_glInitNames = NULL; +PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT = NULL; +PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT = NULL; +PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX = NULL; +PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; +PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV = NULL; +PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL; +PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL; +PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV = NULL; +PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT = NULL; +PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; +PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE = NULL; +PFNGLISFENCENVPROC glad_glIsFenceNV = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL; +PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB = NULL; +PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV = NULL; +PFNGLISLISTPROC glad_glIsList = NULL; +PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL; +PFNGLISNAMEAMDPROC glad_glIsNameAMD = NULL; +PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV = NULL; +PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB = NULL; +PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI = NULL; +PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV = NULL; +PFNGLISPATHNVPROC glad_glIsPathNV = NULL; +PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV = NULL; +PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISPROGRAMARBPROC glad_glIsProgramARB = NULL; +PFNGLISPROGRAMNVPROC glad_glIsProgramNV = NULL; +PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISQUERYARBPROC glad_glIsQueryARB = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSTATENVPROC glad_glIsStateNV = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT = NULL; +PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB = NULL; +PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV = NULL; +PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; +PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV = NULL; +PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE = NULL; +PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE = NULL; +PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX = NULL; +PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX = NULL; +PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX = NULL; +PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT = NULL; +PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX = NULL; +PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; +PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; +PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; +PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; +PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES = NULL; +PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES = NULL; +PFNGLLIGHTFPROC glad_glLightf = NULL; +PFNGLLIGHTFVPROC glad_glLightfv = NULL; +PFNGLLIGHTIPROC glad_glLighti = NULL; +PFNGLLIGHTIVPROC glad_glLightiv = NULL; +PFNGLLIGHTXOESPROC glad_glLightxOES = NULL; +PFNGLLIGHTXVOESPROC glad_glLightxvOES = NULL; +PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB = NULL; +PFNGLLISTBASEPROC glad_glListBase = NULL; +PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV = NULL; +PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX = NULL; +PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX = NULL; +PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX = NULL; +PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX = NULL; +PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; +PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX = NULL; +PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; +PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; +PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES = NULL; +PFNGLLOADNAMEPROC glad_glLoadName = NULL; +PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB = NULL; +PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES = NULL; +PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT = NULL; +PFNGLLOGICOPPROC glad_glLogicOp = NULL; +PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV = NULL; +PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV = NULL; +PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV = NULL; +PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV = NULL; +PFNGLMAP1DPROC glad_glMap1d = NULL; +PFNGLMAP1FPROC glad_glMap1f = NULL; +PFNGLMAP1XOESPROC glad_glMap1xOES = NULL; +PFNGLMAP2DPROC glad_glMap2d = NULL; +PFNGLMAP2FPROC glad_glMap2f = NULL; +PFNGLMAP2XOESPROC glad_glMap2xOES = NULL; +PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; +PFNGLMAPBUFFERARBPROC glad_glMapBufferARB = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV = NULL; +PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; +PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; +PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES = NULL; +PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; +PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; +PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES = NULL; +PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT = NULL; +PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; +PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT = NULL; +PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI = NULL; +PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV = NULL; +PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV = NULL; +PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL = NULL; +PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE = NULL; +PFNGLMATERIALFPROC glad_glMaterialf = NULL; +PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; +PFNGLMATERIALIPROC glad_glMateriali = NULL; +PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; +PFNGLMATERIALXOESPROC glad_glMaterialxOES = NULL; +PFNGLMATERIALXVOESPROC glad_glMaterialxvOES = NULL; +PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB = NULL; +PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV = NULL; +PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV = NULL; +PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT = NULL; +PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV = NULL; +PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT = NULL; +PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT = NULL; +PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT = NULL; +PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; +PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV = NULL; +PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV = NULL; +PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV = NULL; +PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT = NULL; +PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT = NULL; +PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT = NULL; +PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT = NULL; +PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT = NULL; +PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT = NULL; +PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT = NULL; +PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT = NULL; +PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT = NULL; +PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT = NULL; +PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT = NULL; +PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT = NULL; +PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB = NULL; +PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL; +PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; +PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; +PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT = NULL; +PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL; +PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL; +PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB = NULL; +PFNGLMINMAXPROC glad_glMinmax = NULL; +PFNGLMINMAXEXTPROC glad_glMinmaxEXT = NULL; +PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; +PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; +PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES = NULL; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; +PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB = NULL; +PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC glad_glMultiDrawMeshTasksIndirectCountNV = NULL; +PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC glad_glMultiDrawMeshTasksIndirectNV = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE = NULL; +PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM = NULL; +PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT = NULL; +PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES = NULL; +PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES = NULL; +PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES = NULL; +PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES = NULL; +PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES = NULL; +PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES = NULL; +PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES = NULL; +PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES = NULL; +PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES = NULL; +PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES = NULL; +PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES = NULL; +PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES = NULL; +PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES = NULL; +PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES = NULL; +PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV = NULL; +PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; +PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB = NULL; +PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES = NULL; +PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES = NULL; +PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; +PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; +PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; +PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; +PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; +PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; +PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; +PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; +PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT = NULL; +PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT = NULL; +PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT = NULL; +PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT = NULL; +PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT = NULL; +PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT = NULL; +PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT = NULL; +PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT = NULL; +PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT = NULL; +PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT = NULL; +PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT = NULL; +PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT = NULL; +PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT = NULL; +PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT = NULL; +PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT = NULL; +PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT = NULL; +PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT = NULL; +PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT = NULL; +PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT = NULL; +PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT = NULL; +PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT = NULL; +PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT = NULL; +PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT = NULL; +PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT = NULL; +PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV = NULL; +PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV = NULL; +PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV = NULL; +PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV = NULL; +PFNGLMULTICASTSCISSORARRAYVNVXPROC glad_glMulticastScissorArrayvNVX = NULL; +PFNGLMULTICASTVIEWPORTARRAYVNVXPROC glad_glMulticastViewportArrayvNVX = NULL; +PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC glad_glMulticastViewportPositionWScaleNVX = NULL; +PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV = NULL; +PFNGLNAMEDBUFFERATTACHMEMORYNVPROC glad_glNamedBufferAttachMemoryNV = NULL; +PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL; +PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT = NULL; +PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB = NULL; +PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT = NULL; +PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC glad_glNamedBufferPageCommitmentMemNV = NULL; +PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL; +PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL; +PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT = NULL; +PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT = NULL; +PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glNamedFramebufferTextureMultiviewOVR = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT = NULL; +PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT = NULL; +PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB = NULL; +PFNGLNEWLISTPROC glad_glNewList = NULL; +PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI = NULL; +PFNGLNORMAL3BPROC glad_glNormal3b = NULL; +PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; +PFNGLNORMAL3DPROC glad_glNormal3d = NULL; +PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; +PFNGLNORMAL3FPROC glad_glNormal3f = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN = NULL; +PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; +PFNGLNORMAL3HNVPROC glad_glNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV = NULL; +PFNGLNORMAL3IPROC glad_glNormal3i = NULL; +PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; +PFNGLNORMAL3SPROC glad_glNormal3s = NULL; +PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; +PFNGLNORMAL3XOESPROC glad_glNormal3xOES = NULL; +PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES = NULL; +PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV = NULL; +PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; +PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; +PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; +PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT = NULL; +PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM = NULL; +PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL = NULL; +PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI = NULL; +PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI = NULL; +PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; +PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; +PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE = NULL; +PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE = NULL; +PFNGLORTHOPROC glad_glOrtho = NULL; +PFNGLORTHOFOESPROC glad_glOrthofOES = NULL; +PFNGLORTHOXOESPROC glad_glOrthoxOES = NULL; +PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI = NULL; +PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI = NULL; +PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; +PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES = NULL; +PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; +PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; +PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV = NULL; +PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV = NULL; +PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV = NULL; +PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV = NULL; +PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV = NULL; +PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV = NULL; +PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV = NULL; +PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV = NULL; +PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV = NULL; +PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV = NULL; +PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV = NULL; +PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV = NULL; +PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV = NULL; +PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV = NULL; +PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV = NULL; +PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV = NULL; +PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV = NULL; +PFNGLPATHSTRINGNVPROC glad_glPathStringNV = NULL; +PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV = NULL; +PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV = NULL; +PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; +PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV = NULL; +PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV = NULL; +PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; +PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; +PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; +PFNGLPIXELMAPXPROC glad_glPixelMapx = NULL; +PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPIXELSTOREXPROC glad_glPixelStorex = NULL; +PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS = NULL; +PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX = NULL; +PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; +PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; +PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT = NULL; +PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; +PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES = NULL; +PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV = NULL; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; +PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS = NULL; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; +PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB = NULL; +PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT = NULL; +PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS = NULL; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; +PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; +PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV = NULL; +PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES = NULL; +PFNGLPOINTSIZEPROC glad_glPointSize = NULL; +PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES = NULL; +PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX = NULL; +PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX = NULL; +PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; +PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT = NULL; +PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT = NULL; +PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES = NULL; +PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; +PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; +PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; +PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; +PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT = NULL; +PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; +PFNGLPOPNAMEPROC glad_glPopName = NULL; +PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV = NULL; +PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV = NULL; +PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; +PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV = NULL; +PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT = NULL; +PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES = NULL; +PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV = NULL; +PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT = NULL; +PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; +PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB = NULL; +PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV = NULL; +PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV = NULL; +PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB = NULL; +PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV = NULL; +PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; +PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT = NULL; +PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL; +PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT = NULL; +PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT = NULL; +PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT = NULL; +PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB = NULL; +PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV = NULL; +PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB = NULL; +PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV = NULL; +PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT = NULL; +PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT = NULL; +PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB = NULL; +PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV = NULL; +PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB = NULL; +PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV = NULL; +PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT = NULL; +PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL; +PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT = NULL; +PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL; +PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT = NULL; +PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT = NULL; +PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT = NULL; +PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB = NULL; +PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV = NULL; +PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB = NULL; +PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV = NULL; +PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT = NULL; +PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT = NULL; +PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB = NULL; +PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV = NULL; +PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB = NULL; +PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV = NULL; +PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT = NULL; +PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL; +PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT = NULL; +PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL; +PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT = NULL; +PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT = NULL; +PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT = NULL; +PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB = NULL; +PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV = NULL; +PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB = NULL; +PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV = NULL; +PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT = NULL; +PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT = NULL; +PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB = NULL; +PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV = NULL; +PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB = NULL; +PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV = NULL; +PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT = NULL; +PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL; +PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT = NULL; +PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL; +PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT = NULL; +PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT = NULL; +PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT = NULL; +PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB = NULL; +PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV = NULL; +PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB = NULL; +PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV = NULL; +PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT = NULL; +PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT = NULL; +PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB = NULL; +PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV = NULL; +PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB = NULL; +PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV = NULL; +PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV = NULL; +PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV = NULL; +PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV = NULL; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; +PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT = NULL; +PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; +PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; +PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT = NULL; +PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; +PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT = NULL; +PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; +PFNGLPUSHNAMEPROC glad_glPushName = NULL; +PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; +PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES = NULL; +PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD = NULL; +PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV = NULL; +PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV = NULL; +PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; +PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; +PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; +PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; +PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; +PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; +PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; +PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; +PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES = NULL; +PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES = NULL; +PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; +PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; +PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; +PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; +PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; +PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; +PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; +PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; +PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES = NULL; +PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES = NULL; +PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; +PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; +PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; +PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; +PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; +PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; +PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; +PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; +PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES = NULL; +PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES = NULL; +PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL; +PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL; +PFNGLRECTDPROC glad_glRectd = NULL; +PFNGLRECTDVPROC glad_glRectdv = NULL; +PFNGLRECTFPROC glad_glRectf = NULL; +PFNGLRECTFVPROC glad_glRectfv = NULL; +PFNGLRECTIPROC glad_glRecti = NULL; +PFNGLRECTIVPROC glad_glRectiv = NULL; +PFNGLRECTSPROC glad_glRects = NULL; +PFNGLRECTSVPROC glad_glRectsv = NULL; +PFNGLRECTXOESPROC glad_glRectxOES = NULL; +PFNGLRECTXVOESPROC glad_glRectxvOES = NULL; +PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX = NULL; +PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV = NULL; +PFNGLRENDERMODEPROC glad_glRenderMode = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; +PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV = NULL; +PFNGLRESETHISTOGRAMPROC glad_glResetHistogram = NULL; +PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT = NULL; +PFNGLRESETMEMORYOBJECTPARAMETERNVPROC glad_glResetMemoryObjectParameterNV = NULL; +PFNGLRESETMINMAXPROC glad_glResetMinmax = NULL; +PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT = NULL; +PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA = NULL; +PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; +PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV = NULL; +PFNGLROTATEDPROC glad_glRotated = NULL; +PFNGLROTATEFPROC glad_glRotatef = NULL; +PFNGLROTATEXOESPROC glad_glRotatexOES = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL; +PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI = NULL; +PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT = NULL; +PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV = NULL; +PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT = NULL; +PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS = NULL; +PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLSCALEDPROC glad_glScaled = NULL; +PFNGLSCALEFPROC glad_glScalef = NULL; +PFNGLSCALEXOESPROC glad_glScalexOES = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; +PFNGLSCISSOREXCLUSIVEARRAYVNVPROC glad_glScissorExclusiveArrayvNV = NULL; +PFNGLSCISSOREXCLUSIVENVPROC glad_glScissorExclusiveNV = NULL; +PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; +PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; +PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV = NULL; +PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV = NULL; +PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; +PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM = NULL; +PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; +PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD = NULL; +PFNGLSEMAPHOREPARAMETERIVNVPROC glad_glSemaphoreParameterivNV = NULL; +PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT = NULL; +PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT = NULL; +PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE = NULL; +PFNGLSETFENCENVPROC glad_glSetFenceNV = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI = NULL; +PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT = NULL; +PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD = NULL; +PFNGLSHADEMODELPROC glad_glShadeModel = NULL; +PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; +PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB = NULL; +PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; +PFNGLSHADINGRATEIMAGEBARRIERNVPROC glad_glShadingRateImageBarrierNV = NULL; +PFNGLSHADINGRATEIMAGEPALETTENVPROC glad_glShadingRateImagePaletteNV = NULL; +PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC glad_glShadingRateSampleOrderCustomNV = NULL; +PFNGLSHADINGRATESAMPLEORDERNVPROC glad_glShadingRateSampleOrderNV = NULL; +PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS = NULL; +PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT = NULL; +PFNGLSIGNALSEMAPHOREUI64NVXPROC glad_glSignalSemaphoreui64NVX = NULL; +PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV = NULL; +PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV = NULL; +PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader = NULL; +PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB = NULL; +PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX = NULL; +PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX = NULL; +PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV = NULL; +PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT = NULL; +PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV = NULL; +PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI = NULL; +PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD = NULL; +PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV = NULL; +PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV = NULL; +PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX = NULL; +PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY = NULL; +PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV = NULL; +PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT = NULL; +PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL = NULL; +PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX = NULL; +PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT = NULL; +PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT = NULL; +PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT = NULL; +PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT = NULL; +PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT = NULL; +PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT = NULL; +PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT = NULL; +PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT = NULL; +PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT = NULL; +PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT = NULL; +PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX = NULL; +PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD = NULL; +PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD = NULL; +PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE = NULL; +PFNGLTESTFENCENVPROC glad_glTestFenceNV = NULL; +PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE = NULL; +PFNGLTEXATTACHMEMORYNVPROC glad_glTexAttachMemoryNV = NULL; +PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; +PFNGLTEXBUFFERARBPROC glad_glTexBufferARB = NULL; +PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT = NULL; +PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI = NULL; +PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES = NULL; +PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES = NULL; +PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; +PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; +PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; +PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; +PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV = NULL; +PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; +PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; +PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; +PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; +PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES = NULL; +PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES = NULL; +PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES = NULL; +PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES = NULL; +PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; +PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; +PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; +PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV = NULL; +PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; +PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; +PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; +PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; +PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES = NULL; +PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES = NULL; +PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES = NULL; +PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES = NULL; +PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; +PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; +PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; +PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; +PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV = NULL; +PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; +PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; +PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; +PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; +PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES = NULL; +PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES = NULL; +PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES = NULL; +PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES = NULL; +PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; +PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; +PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; +PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV = NULL; +PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; +PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; +PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; +PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; +PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES = NULL; +PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES = NULL; +PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV = NULL; +PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; +PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; +PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; +PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; +PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; +PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; +PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; +PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; +PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; +PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL = NULL; +PFNGLTEXENVFPROC glad_glTexEnvf = NULL; +PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; +PFNGLTEXENVIPROC glad_glTexEnvi = NULL; +PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; +PFNGLTEXENVXOESPROC glad_glTexEnvxOES = NULL; +PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES = NULL; +PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS = NULL; +PFNGLTEXGENDPROC glad_glTexGend = NULL; +PFNGLTEXGENDVPROC glad_glTexGendv = NULL; +PFNGLTEXGENFPROC glad_glTexGenf = NULL; +PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; +PFNGLTEXGENIPROC glad_glTexGeni = NULL; +PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; +PFNGLTEXGENXOESPROC glad_glTexGenxOES = NULL; +PFNGLTEXGENXVOESPROC glad_glTexGenxvOES = NULL; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; +PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; +PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV = NULL; +PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS = NULL; +PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB = NULL; +PFNGLTEXPAGECOMMITMENTMEMNVPROC glad_glTexPageCommitmentMemNV = NULL; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; +PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT = NULL; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; +PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES = NULL; +PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES = NULL; +PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV = NULL; +PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL; +PFNGLTEXSTORAGE1DEXTPROC glad_glTexStorage1DEXT = NULL; +PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; +PFNGLTEXSTORAGE2DEXTPROC glad_glTexStorage2DEXT = NULL; +PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; +PFNGLTEXSTORAGE3DEXTPROC glad_glTexStorage3DEXT = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL; +PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL; +PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL; +PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL; +PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL; +PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL; +PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD = NULL; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; +PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS = NULL; +PFNGLTEXTUREATTACHMEMORYNVPROC glad_glTextureAttachMemoryNV = NULL; +PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL; +PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV = NULL; +PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL; +PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT = NULL; +PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL; +PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT = NULL; +PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS = NULL; +PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT = NULL; +PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV = NULL; +PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV = NULL; +PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT = NULL; +PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT = NULL; +PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT = NULL; +PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC glad_glTexturePageCommitmentMemNV = NULL; +PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL; +PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT = NULL; +PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL; +PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT = NULL; +PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL; +PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT = NULL; +PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL; +PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT = NULL; +PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL; +PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT = NULL; +PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL; +PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT = NULL; +PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE = NULL; +PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT = NULL; +PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL; +PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL; +PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL; +PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL; +PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD = NULL; +PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL; +PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT = NULL; +PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL; +PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT = NULL; +PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL; +PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT = NULL; +PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; +PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV = NULL; +PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; +PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV = NULL; +PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV = NULL; +PFNGLTRANSLATEDPROC glad_glTranslated = NULL; +PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; +PFNGLTRANSLATEXOESPROC glad_glTranslatexOES = NULL; +PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; +PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FARBPROC glad_glUniform1fARB = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB = NULL; +PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV = NULL; +PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB = NULL; +PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV = NULL; +PFNGLUNIFORM1IARBPROC glad_glUniform1iARB = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB = NULL; +PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV = NULL; +PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB = NULL; +PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV = NULL; +PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT = NULL; +PFNGLUNIFORM2DPROC glad_glUniform2d = NULL; +PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FARBPROC glad_glUniform2fARB = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB = NULL; +PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV = NULL; +PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB = NULL; +PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV = NULL; +PFNGLUNIFORM2IARBPROC glad_glUniform2iARB = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB = NULL; +PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV = NULL; +PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB = NULL; +PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV = NULL; +PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT = NULL; +PFNGLUNIFORM3DPROC glad_glUniform3d = NULL; +PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FARBPROC glad_glUniform3fARB = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB = NULL; +PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV = NULL; +PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB = NULL; +PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV = NULL; +PFNGLUNIFORM3IARBPROC glad_glUniform3iARB = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB = NULL; +PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV = NULL; +PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB = NULL; +PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV = NULL; +PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT = NULL; +PFNGLUNIFORM4DPROC glad_glUniform4d = NULL; +PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FARBPROC glad_glUniform4fARB = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB = NULL; +PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV = NULL; +PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB = NULL; +PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV = NULL; +PFNGLUNIFORM4IARBPROC glad_glUniform4iARB = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB = NULL; +PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV = NULL; +PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB = NULL; +PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV = NULL; +PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT = NULL; +PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB = NULL; +PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV = NULL; +PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB = NULL; +PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV = NULL; +PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB = NULL; +PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL; +PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV = NULL; +PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV = NULL; +PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB = NULL; +PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL; +PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI = NULL; +PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI = NULL; +PFNGLUPLOADGPUMASKNVXPROC glad_glUploadGpuMaskNVX = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB = NULL; +PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; +PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV = NULL; +PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV = NULL; +PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV = NULL; +PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV = NULL; +PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV = NULL; +PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV = NULL; +PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV = NULL; +PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC glad_glVDPAURegisterVideoSurfaceWithPictureStructureNV = NULL; +PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV = NULL; +PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV = NULL; +PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI = NULL; +PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT = NULL; +PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT = NULL; +PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT = NULL; +PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT = NULL; +PFNGLVARIANTIVEXTPROC glad_glVariantivEXT = NULL; +PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT = NULL; +PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT = NULL; +PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT = NULL; +PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT = NULL; +PFNGLVERTEX2BOESPROC glad_glVertex2bOES = NULL; +PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES = NULL; +PFNGLVERTEX2DPROC glad_glVertex2d = NULL; +PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; +PFNGLVERTEX2FPROC glad_glVertex2f = NULL; +PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; +PFNGLVERTEX2HNVPROC glad_glVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV = NULL; +PFNGLVERTEX2IPROC glad_glVertex2i = NULL; +PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; +PFNGLVERTEX2SPROC glad_glVertex2s = NULL; +PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; +PFNGLVERTEX2XOESPROC glad_glVertex2xOES = NULL; +PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES = NULL; +PFNGLVERTEX3BOESPROC glad_glVertex3bOES = NULL; +PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES = NULL; +PFNGLVERTEX3DPROC glad_glVertex3d = NULL; +PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; +PFNGLVERTEX3FPROC glad_glVertex3f = NULL; +PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; +PFNGLVERTEX3HNVPROC glad_glVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV = NULL; +PFNGLVERTEX3IPROC glad_glVertex3i = NULL; +PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; +PFNGLVERTEX3SPROC glad_glVertex3s = NULL; +PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; +PFNGLVERTEX3XOESPROC glad_glVertex3xOES = NULL; +PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES = NULL; +PFNGLVERTEX4BOESPROC glad_glVertex4bOES = NULL; +PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES = NULL; +PFNGLVERTEX4DPROC glad_glVertex4d = NULL; +PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; +PFNGLVERTEX4FPROC glad_glVertex4f = NULL; +PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; +PFNGLVERTEX4HNVPROC glad_glVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV = NULL; +PFNGLVERTEX4IPROC glad_glVertex4i = NULL; +PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; +PFNGLVERTEX4SPROC glad_glVertex4s = NULL; +PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; +PFNGLVERTEX4XOESPROC glad_glVertex4xOES = NULL; +PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES = NULL; +PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; +PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; +PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; +PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL; +PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT = NULL; +PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL; +PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT = NULL; +PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT = NULL; +PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL; +PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT = NULL; +PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT = NULL; +PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL; +PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT = NULL; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI = NULL; +PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB = NULL; +PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV = NULL; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT = NULL; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT = NULL; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT = NULL; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT = NULL; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT = NULL; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT = NULL; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT = NULL; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT = NULL; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT = NULL; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT = NULL; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT = NULL; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT = NULL; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT = NULL; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT = NULL; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT = NULL; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT = NULL; +PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT = NULL; +PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL; +PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT = NULL; +PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL; +PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT = NULL; +PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV = NULL; +PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV = NULL; +PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB = NULL; +PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV = NULL; +PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB = NULL; +PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV = NULL; +PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL; +PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT = NULL; +PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL; +PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT = NULL; +PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV = NULL; +PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV = NULL; +PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV = NULL; +PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV = NULL; +PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL; +PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT = NULL; +PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL; +PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT = NULL; +PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV = NULL; +PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV = NULL; +PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV = NULL; +PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV = NULL; +PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL; +PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT = NULL; +PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL; +PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT = NULL; +PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV = NULL; +PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV = NULL; +PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV = NULL; +PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV = NULL; +PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL; +PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV = NULL; +PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL; +PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT = NULL; +PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; +PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV = NULL; +PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; +PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB = NULL; +PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI = NULL; +PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV = NULL; +PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; +PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; +PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; +PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; +PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; +PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; +PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; +PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM = NULL; +PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL = NULL; +PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI = NULL; +PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI = NULL; +PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI = NULL; +PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI = NULL; +PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI = NULL; +PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI = NULL; +PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI = NULL; +PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI = NULL; +PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT = NULL; +PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV = NULL; +PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; +PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; +PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; +PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV = NULL; +PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV = NULL; +PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT = NULL; +PFNGLWAITSEMAPHOREUI64NVXPROC glad_glWaitSemaphoreui64NVX = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV = NULL; +PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV = NULL; +PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB = NULL; +PFNGLWEIGHTBVARBPROC glad_glWeightbvARB = NULL; +PFNGLWEIGHTDVARBPROC glad_glWeightdvARB = NULL; +PFNGLWEIGHTFVARBPROC glad_glWeightfvARB = NULL; +PFNGLWEIGHTIVARBPROC glad_glWeightivARB = NULL; +PFNGLWEIGHTSVARBPROC glad_glWeightsvARB = NULL; +PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB = NULL; +PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB = NULL; +PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB = NULL; +PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; +PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; +PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; +PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; +PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; +PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; +PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; +PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; +PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB = NULL; +PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; +PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; +PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; +PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; +PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; +PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; +PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; +PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; +PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB = NULL; +PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA = NULL; +PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT = NULL; +PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT = NULL; +PFNGLALPHAFUNCXPROC glad_glAlphaFuncx = NULL; +PFNGLBINDFRAMEBUFFEROESPROC glad_glBindFramebufferOES = NULL; +PFNGLBINDRENDERBUFFEROESPROC glad_glBindRenderbufferOES = NULL; +PFNGLBINDVERTEXARRAYOESPROC glad_glBindVertexArrayOES = NULL; +PFNGLBLENDEQUATIONOESPROC glad_glBlendEquationOES = NULL; +PFNGLBLENDEQUATIONSEPARATEOESPROC glad_glBlendEquationSeparateOES = NULL; +PFNGLBLENDFUNCSEPARATEOESPROC glad_glBlendFuncSeparateOES = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSOESPROC glad_glCheckFramebufferStatusOES = NULL; +PFNGLCLEARCOLORXPROC glad_glClearColorx = NULL; +PFNGLCLEARDEPTHXPROC glad_glClearDepthx = NULL; +PFNGLCLIENTWAITSYNCAPPLEPROC glad_glClientWaitSyncAPPLE = NULL; +PFNGLCLIPPLANEFPROC glad_glClipPlanef = NULL; +PFNGLCLIPPLANEFIMGPROC glad_glClipPlanefIMG = NULL; +PFNGLCLIPPLANEXPROC glad_glClipPlanex = NULL; +PFNGLCLIPPLANEXIMGPROC glad_glClipPlanexIMG = NULL; +PFNGLCOLOR4XPROC glad_glColor4x = NULL; +PFNGLCOPYTEXTURELEVELSAPPLEPROC glad_glCopyTextureLevelsAPPLE = NULL; +PFNGLCURRENTPALETTEMATRIXOESPROC glad_glCurrentPaletteMatrixOES = NULL; +PFNGLDELETEFRAMEBUFFERSOESPROC glad_glDeleteFramebuffersOES = NULL; +PFNGLDELETERENDERBUFFERSOESPROC glad_glDeleteRenderbuffersOES = NULL; +PFNGLDELETESYNCAPPLEPROC glad_glDeleteSyncAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSOESPROC glad_glDeleteVertexArraysOES = NULL; +PFNGLDEPTHRANGEXPROC glad_glDepthRangex = NULL; +PFNGLDISABLEDRIVERCONTROLQCOMPROC glad_glDisableDriverControlQCOM = NULL; +PFNGLDISCARDFRAMEBUFFEREXTPROC glad_glDiscardFramebufferEXT = NULL; +PFNGLDRAWTEXFOESPROC glad_glDrawTexfOES = NULL; +PFNGLDRAWTEXFVOESPROC glad_glDrawTexfvOES = NULL; +PFNGLDRAWTEXIOESPROC glad_glDrawTexiOES = NULL; +PFNGLDRAWTEXIVOESPROC glad_glDrawTexivOES = NULL; +PFNGLDRAWTEXSOESPROC glad_glDrawTexsOES = NULL; +PFNGLDRAWTEXSVOESPROC glad_glDrawTexsvOES = NULL; +PFNGLDRAWTEXXOESPROC glad_glDrawTexxOES = NULL; +PFNGLDRAWTEXXVOESPROC glad_glDrawTexxvOES = NULL; +PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glad_glEGLImageTargetRenderbufferStorageOES = NULL; +PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glad_glEGLImageTargetTexture2DOES = NULL; +PFNGLENABLEDRIVERCONTROLQCOMPROC glad_glEnableDriverControlQCOM = NULL; +PFNGLENDTILINGQCOMPROC glad_glEndTilingQCOM = NULL; +PFNGLEXTGETBUFFERPOINTERVQCOMPROC glad_glExtGetBufferPointervQCOM = NULL; +PFNGLEXTGETBUFFERSQCOMPROC glad_glExtGetBuffersQCOM = NULL; +PFNGLEXTGETFRAMEBUFFERSQCOMPROC glad_glExtGetFramebuffersQCOM = NULL; +PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC glad_glExtGetProgramBinarySourceQCOM = NULL; +PFNGLEXTGETPROGRAMSQCOMPROC glad_glExtGetProgramsQCOM = NULL; +PFNGLEXTGETRENDERBUFFERSQCOMPROC glad_glExtGetRenderbuffersQCOM = NULL; +PFNGLEXTGETSHADERSQCOMPROC glad_glExtGetShadersQCOM = NULL; +PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC glad_glExtGetTexLevelParameterivQCOM = NULL; +PFNGLEXTGETTEXSUBIMAGEQCOMPROC glad_glExtGetTexSubImageQCOM = NULL; +PFNGLEXTGETTEXTURESQCOMPROC glad_glExtGetTexturesQCOM = NULL; +PFNGLEXTISPROGRAMBINARYQCOMPROC glad_glExtIsProgramBinaryQCOM = NULL; +PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC glad_glExtTexObjectStateOverrideiQCOM = NULL; +PFNGLFENCESYNCAPPLEPROC glad_glFenceSyncAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC glad_glFlushMappedBufferRangeEXT = NULL; +PFNGLFOGXPROC glad_glFogx = NULL; +PFNGLFOGXVPROC glad_glFogxv = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEROESPROC glad_glFramebufferRenderbufferOES = NULL; +PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC glad_glFramebufferTexture2DMultisampleIMG = NULL; +PFNGLFRAMEBUFFERTEXTURE2DOESPROC glad_glFramebufferTexture2DOES = NULL; +PFNGLFRUSTUMFPROC glad_glFrustumf = NULL; +PFNGLFRUSTUMXPROC glad_glFrustumx = NULL; +PFNGLGENFRAMEBUFFERSOESPROC glad_glGenFramebuffersOES = NULL; +PFNGLGENRENDERBUFFERSOESPROC glad_glGenRenderbuffersOES = NULL; +PFNGLGENVERTEXARRAYSOESPROC glad_glGenVertexArraysOES = NULL; +PFNGLGENERATEMIPMAPOESPROC glad_glGenerateMipmapOES = NULL; +PFNGLGETBUFFERPOINTERVOESPROC glad_glGetBufferPointervOES = NULL; +PFNGLGETCLIPPLANEFPROC glad_glGetClipPlanef = NULL; +PFNGLGETCLIPPLANEXPROC glad_glGetClipPlanex = NULL; +PFNGLGETDRIVERCONTROLSTRINGQCOMPROC glad_glGetDriverControlStringQCOM = NULL; +PFNGLGETDRIVERCONTROLSQCOMPROC glad_glGetDriverControlsQCOM = NULL; +PFNGLGETFIXEDVPROC glad_glGetFixedv = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC glad_glGetFramebufferAttachmentParameterivOES = NULL; +PFNGLGETGRAPHICSRESETSTATUSEXTPROC glad_glGetGraphicsResetStatusEXT = NULL; +PFNGLGETINTEGER64VAPPLEPROC glad_glGetInteger64vAPPLE = NULL; +PFNGLGETLIGHTXVPROC glad_glGetLightxv = NULL; +PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES = NULL; +PFNGLGETMATERIALXVPROC glad_glGetMaterialxv = NULL; +PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVOESPROC glad_glGetRenderbufferParameterivOES = NULL; +PFNGLGETSYNCIVAPPLEPROC glad_glGetSyncivAPPLE = NULL; +PFNGLGETTEXENVXVPROC glad_glGetTexEnvxv = NULL; +PFNGLGETTEXGENFVOESPROC glad_glGetTexGenfvOES = NULL; +PFNGLGETTEXGENIVOESPROC glad_glGetTexGenivOES = NULL; +PFNGLGETTEXPARAMETERXVPROC glad_glGetTexParameterxv = NULL; +PFNGLGETNUNIFORMFVEXTPROC glad_glGetnUniformfvEXT = NULL; +PFNGLGETNUNIFORMIVEXTPROC glad_glGetnUniformivEXT = NULL; +PFNGLISFRAMEBUFFEROESPROC glad_glIsFramebufferOES = NULL; +PFNGLISRENDERBUFFEROESPROC glad_glIsRenderbufferOES = NULL; +PFNGLISSYNCAPPLEPROC glad_glIsSyncAPPLE = NULL; +PFNGLISVERTEXARRAYOESPROC glad_glIsVertexArrayOES = NULL; +PFNGLLIGHTMODELXPROC glad_glLightModelx = NULL; +PFNGLLIGHTMODELXVPROC glad_glLightModelxv = NULL; +PFNGLLIGHTXPROC glad_glLightx = NULL; +PFNGLLIGHTXVPROC glad_glLightxv = NULL; +PFNGLLINEWIDTHXPROC glad_glLineWidthx = NULL; +PFNGLLOADMATRIXXPROC glad_glLoadMatrixx = NULL; +PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC glad_glLoadPaletteFromModelViewMatrixOES = NULL; +PFNGLMAPBUFFEROESPROC glad_glMapBufferOES = NULL; +PFNGLMAPBUFFERRANGEEXTPROC glad_glMapBufferRangeEXT = NULL; +PFNGLMATERIALXPROC glad_glMaterialx = NULL; +PFNGLMATERIALXVPROC glad_glMaterialxv = NULL; +PFNGLMATRIXINDEXPOINTEROESPROC glad_glMatrixIndexPointerOES = NULL; +PFNGLMULTMATRIXXPROC glad_glMultMatrixx = NULL; +PFNGLMULTITEXCOORD4XPROC glad_glMultiTexCoord4x = NULL; +PFNGLNORMAL3XPROC glad_glNormal3x = NULL; +PFNGLORTHOFPROC glad_glOrthof = NULL; +PFNGLORTHOXPROC glad_glOrthox = NULL; +PFNGLPOINTPARAMETERXPROC glad_glPointParameterx = NULL; +PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES = NULL; +PFNGLPOINTPARAMETERXVPROC glad_glPointParameterxv = NULL; +PFNGLPOINTSIZEPOINTEROESPROC glad_glPointSizePointerOES = NULL; +PFNGLPOINTSIZEXPROC glad_glPointSizex = NULL; +PFNGLPOLYGONOFFSETXPROC glad_glPolygonOffsetx = NULL; +PFNGLREADNPIXELSEXTPROC glad_glReadnPixelsEXT = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC glad_glRenderbufferStorageMultisampleAPPLE = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC glad_glRenderbufferStorageMultisampleIMG = NULL; +PFNGLRENDERBUFFERSTORAGEOESPROC glad_glRenderbufferStorageOES = NULL; +PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC glad_glResolveMultisampleFramebufferAPPLE = NULL; +PFNGLROTATEXPROC glad_glRotatex = NULL; +PFNGLSAMPLECOVERAGEXPROC glad_glSampleCoveragex = NULL; +PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES = NULL; +PFNGLSCALEXPROC glad_glScalex = NULL; +PFNGLSTARTTILINGQCOMPROC glad_glStartTilingQCOM = NULL; +PFNGLTEXENVXPROC glad_glTexEnvx = NULL; +PFNGLTEXENVXVPROC glad_glTexEnvxv = NULL; +PFNGLTEXGENFOESPROC glad_glTexGenfOES = NULL; +PFNGLTEXGENFVOESPROC glad_glTexGenfvOES = NULL; +PFNGLTEXGENIOESPROC glad_glTexGeniOES = NULL; +PFNGLTEXGENIVOESPROC glad_glTexGenivOES = NULL; +PFNGLTEXPARAMETERXPROC glad_glTexParameterx = NULL; +PFNGLTEXPARAMETERXVPROC glad_glTexParameterxv = NULL; +PFNGLTRANSLATEXPROC glad_glTranslatex = NULL; +PFNGLUNMAPBUFFEROESPROC glad_glUnmapBufferOES = NULL; +PFNGLWAITSYNCAPPLEPROC glad_glWaitSyncAPPLE = NULL; +PFNGLWEIGHTPOINTEROESPROC glad_glWeightPointerOES = NULL; +PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT = NULL; +PFNGLALPHAFUNCQCOMPROC glad_glAlphaFuncQCOM = NULL; +PFNGLBEGINQUERYEXTPROC glad_glBeginQueryEXT = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC glad_glBindFragDataLocationIndexedEXT = NULL; +PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT = NULL; +PFNGLBLENDBARRIERPROC glad_glBlendBarrier = NULL; +PFNGLBLENDEQUATIONSEPARATEIEXTPROC glad_glBlendEquationSeparateiEXT = NULL; +PFNGLBLENDEQUATIONSEPARATEIOESPROC glad_glBlendEquationSeparateiOES = NULL; +PFNGLBLENDEQUATIONIEXTPROC glad_glBlendEquationiEXT = NULL; +PFNGLBLENDEQUATIONIOESPROC glad_glBlendEquationiOES = NULL; +PFNGLBLENDFUNCSEPARATEIEXTPROC glad_glBlendFuncSeparateiEXT = NULL; +PFNGLBLENDFUNCSEPARATEIOESPROC glad_glBlendFuncSeparateiOES = NULL; +PFNGLBLENDFUNCIEXTPROC glad_glBlendFunciEXT = NULL; +PFNGLBLENDFUNCIOESPROC glad_glBlendFunciOES = NULL; +PFNGLBLITFRAMEBUFFERANGLEPROC glad_glBlitFramebufferANGLE = NULL; +PFNGLBLITFRAMEBUFFERNVPROC glad_glBlitFramebufferNV = NULL; +PFNGLBUFFERSTORAGEEXTPROC glad_glBufferStorageEXT = NULL; +PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC glad_glClearPixelLocalStorageuiEXT = NULL; +PFNGLCLEARTEXIMAGEEXTPROC glad_glClearTexImageEXT = NULL; +PFNGLCLEARTEXSUBIMAGEEXTPROC glad_glClearTexSubImageEXT = NULL; +PFNGLCLIPCONTROLEXTPROC glad_glClipControlEXT = NULL; +PFNGLCOLORMASKIEXTPROC glad_glColorMaskiEXT = NULL; +PFNGLCOLORMASKIOESPROC glad_glColorMaskiOES = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DOESPROC glad_glCompressedTexImage3DOES = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC glad_glCompressedTexSubImage3DOES = NULL; +PFNGLCOPYBUFFERSUBDATANVPROC glad_glCopyBufferSubDataNV = NULL; +PFNGLCOPYIMAGESUBDATAEXTPROC glad_glCopyImageSubDataEXT = NULL; +PFNGLCOPYIMAGESUBDATAOESPROC glad_glCopyImageSubDataOES = NULL; +PFNGLCOPYTEXSUBIMAGE3DOESPROC glad_glCopyTexSubImage3DOES = NULL; +PFNGLCOVERAGEMASKNVPROC glad_glCoverageMaskNV = NULL; +PFNGLCOVERAGEOPERATIONNVPROC glad_glCoverageOperationNV = NULL; +PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT = NULL; +PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; +PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; +PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; +PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT = NULL; +PFNGLDELETEQUERIESEXTPROC glad_glDeleteQueriesEXT = NULL; +PFNGLDEPTHRANGEARRAYFVNVPROC glad_glDepthRangeArrayfvNV = NULL; +PFNGLDEPTHRANGEARRAYFVOESPROC glad_glDepthRangeArrayfvOES = NULL; +PFNGLDEPTHRANGEINDEXEDFNVPROC glad_glDepthRangeIndexedfNV = NULL; +PFNGLDEPTHRANGEINDEXEDFOESPROC glad_glDepthRangeIndexedfOES = NULL; +PFNGLDISABLEIEXTPROC glad_glDisableiEXT = NULL; +PFNGLDISABLEINVPROC glad_glDisableiNV = NULL; +PFNGLDISABLEIOESPROC glad_glDisableiOES = NULL; +PFNGLDRAWARRAYSINSTANCEDANGLEPROC glad_glDrawArraysInstancedANGLE = NULL; +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT = NULL; +PFNGLDRAWARRAYSINSTANCEDNVPROC glad_glDrawArraysInstancedNV = NULL; +PFNGLDRAWBUFFERSEXTPROC glad_glDrawBuffersEXT = NULL; +PFNGLDRAWBUFFERSINDEXEDEXTPROC glad_glDrawBuffersIndexedEXT = NULL; +PFNGLDRAWBUFFERSNVPROC glad_glDrawBuffersNV = NULL; +PFNGLDRAWELEMENTSBASEVERTEXEXTPROC glad_glDrawElementsBaseVertexEXT = NULL; +PFNGLDRAWELEMENTSBASEVERTEXOESPROC glad_glDrawElementsBaseVertexOES = NULL; +PFNGLDRAWELEMENTSINSTANCEDANGLEPROC glad_glDrawElementsInstancedANGLE = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC glad_glDrawElementsInstancedBaseVertexEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC glad_glDrawElementsInstancedBaseVertexOES = NULL; +PFNGLDRAWELEMENTSINSTANCEDNVPROC glad_glDrawElementsInstancedNV = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC glad_glDrawRangeElementsBaseVertexEXT = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC glad_glDrawRangeElementsBaseVertexOES = NULL; +PFNGLDRAWTRANSFORMFEEDBACKEXTPROC glad_glDrawTransformFeedbackEXT = NULL; +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC glad_glDrawTransformFeedbackInstancedEXT = NULL; +PFNGLENABLEIEXTPROC glad_glEnableiEXT = NULL; +PFNGLENABLEINVPROC glad_glEnableiNV = NULL; +PFNGLENABLEIOESPROC glad_glEnableiOES = NULL; +PFNGLENDQUERYEXTPROC glad_glEndQueryEXT = NULL; +PFNGLEXTRAPOLATETEX2DQCOMPROC glad_glExtrapolateTex2DQCOM = NULL; +PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC glad_glFramebufferFetchBarrierQCOM = NULL; +PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC glad_glFramebufferFoveationConfigQCOM = NULL; +PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC glad_glFramebufferFoveationParametersQCOM = NULL; +PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC glad_glFramebufferPixelLocalStorageSizeEXT = NULL; +PFNGLFRAMEBUFFERSHADINGRATEEXTPROC glad_glFramebufferShadingRateEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC glad_glFramebufferTexture2DDownsampleIMG = NULL; +PFNGLFRAMEBUFFERTEXTURE3DOESPROC glad_glFramebufferTexture3DOES = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC glad_glFramebufferTextureLayerDownsampleIMG = NULL; +PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glad_glFramebufferTextureMultisampleMultiviewOVR = NULL; +PFNGLFRAMEBUFFERTEXTUREOESPROC glad_glFramebufferTextureOES = NULL; +PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT = NULL; +PFNGLGENQUERIESEXTPROC glad_glGenQueriesEXT = NULL; +PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; +PFNGLGETFLOATI_VNVPROC glad_glGetFloati_vNV = NULL; +PFNGLGETFLOATI_VOESPROC glad_glGetFloati_vOES = NULL; +PFNGLGETFRAGDATAINDEXEXTPROC glad_glGetFragDataIndexEXT = NULL; +PFNGLGETFRAGMENTSHADINGRATESEXTPROC glad_glGetFragmentShadingRatesEXT = NULL; +PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC glad_glGetFramebufferPixelLocalStorageSizeEXT = NULL; +PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR = NULL; +PFNGLGETINTEGER64VEXTPROC glad_glGetInteger64vEXT = NULL; +PFNGLGETINTEGERI_VEXTPROC glad_glGetIntegeri_vEXT = NULL; +PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; +PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; +PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; +PFNGLGETPROGRAMBINARYOESPROC glad_glGetProgramBinaryOES = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT = NULL; +PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC glad_glGetProgramResourceLocationIndexEXT = NULL; +PFNGLGETQUERYOBJECTIVEXTPROC glad_glGetQueryObjectivEXT = NULL; +PFNGLGETQUERYOBJECTUIVEXTPROC glad_glGetQueryObjectuivEXT = NULL; +PFNGLGETQUERYIVEXTPROC glad_glGetQueryivEXT = NULL; +PFNGLGETSAMPLERPARAMETERIIVEXTPROC glad_glGetSamplerParameterIivEXT = NULL; +PFNGLGETSAMPLERPARAMETERIIVOESPROC glad_glGetSamplerParameterIivOES = NULL; +PFNGLGETSAMPLERPARAMETERIUIVEXTPROC glad_glGetSamplerParameterIuivEXT = NULL; +PFNGLGETSAMPLERPARAMETERIUIVOESPROC glad_glGetSamplerParameterIuivOES = NULL; +PFNGLGETTEXPARAMETERIIVOESPROC glad_glGetTexParameterIivOES = NULL; +PFNGLGETTEXPARAMETERIUIVOESPROC glad_glGetTexParameterIuivOES = NULL; +PFNGLGETTEXTUREHANDLEIMGPROC glad_glGetTextureHandleIMG = NULL; +PFNGLGETTEXTURESAMPLERHANDLEIMGPROC glad_glGetTextureSamplerHandleIMG = NULL; +PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC glad_glGetTranslatedShaderSourceANGLE = NULL; +PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR = NULL; +PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR = NULL; +PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR = NULL; +PFNGLISENABLEDIEXTPROC glad_glIsEnablediEXT = NULL; +PFNGLISENABLEDINVPROC glad_glIsEnablediNV = NULL; +PFNGLISENABLEDIOESPROC glad_glIsEnablediOES = NULL; +PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT = NULL; +PFNGLISQUERYEXTPROC glad_glIsQueryEXT = NULL; +PFNGLMAXACTIVESHADERCORESARMPROC glad_glMaxActiveShaderCoresARM = NULL; +PFNGLMINSAMPLESHADINGOESPROC glad_glMinSampleShadingOES = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC glad_glMultiDrawArraysIndirectEXT = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC glad_glMultiDrawElementsBaseVertexEXT = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC glad_glMultiDrawElementsIndirectEXT = NULL; +PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; +PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; +PFNGLPATCHPARAMETERIEXTPROC glad_glPatchParameteriEXT = NULL; +PFNGLPATCHPARAMETERIOESPROC glad_glPatchParameteriOES = NULL; +PFNGLPOLYGONMODENVPROC glad_glPolygonModeNV = NULL; +PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; +PFNGLPRIMITIVEBOUNDINGBOXPROC glad_glPrimitiveBoundingBox = NULL; +PFNGLPRIMITIVEBOUNDINGBOXEXTPROC glad_glPrimitiveBoundingBoxEXT = NULL; +PFNGLPRIMITIVEBOUNDINGBOXOESPROC glad_glPrimitiveBoundingBoxOES = NULL; +PFNGLPROGRAMBINARYOESPROC glad_glProgramBinaryOES = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC glad_glProgramUniformHandleui64IMG = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC glad_glProgramUniformHandleui64vIMG = NULL; +PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; +PFNGLQUERYCOUNTEREXTPROC glad_glQueryCounterEXT = NULL; +PFNGLREADBUFFERINDEXEDEXTPROC glad_glReadBufferIndexedEXT = NULL; +PFNGLREADBUFFERNVPROC glad_glReadBufferNV = NULL; +PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC glad_glRenderbufferStorageMultisampleANGLE = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC glad_glRenderbufferStorageMultisampleNV = NULL; +PFNGLSAMPLERPARAMETERIIVEXTPROC glad_glSamplerParameterIivEXT = NULL; +PFNGLSAMPLERPARAMETERIIVOESPROC glad_glSamplerParameterIivOES = NULL; +PFNGLSAMPLERPARAMETERIUIVEXTPROC glad_glSamplerParameterIuivEXT = NULL; +PFNGLSAMPLERPARAMETERIUIVOESPROC glad_glSamplerParameterIuivOES = NULL; +PFNGLSCISSORARRAYVNVPROC glad_glScissorArrayvNV = NULL; +PFNGLSCISSORARRAYVOESPROC glad_glScissorArrayvOES = NULL; +PFNGLSCISSORINDEXEDNVPROC glad_glScissorIndexedNV = NULL; +PFNGLSCISSORINDEXEDOESPROC glad_glScissorIndexedOES = NULL; +PFNGLSCISSORINDEXEDVNVPROC glad_glScissorIndexedvNV = NULL; +PFNGLSCISSORINDEXEDVOESPROC glad_glScissorIndexedvOES = NULL; +PFNGLSHADINGRATECOMBINEROPSEXTPROC glad_glShadingRateCombinerOpsEXT = NULL; +PFNGLSHADINGRATEEXTPROC glad_glShadingRateEXT = NULL; +PFNGLSHADINGRATEQCOMPROC glad_glShadingRateQCOM = NULL; +PFNGLTEXBUFFEROESPROC glad_glTexBufferOES = NULL; +PFNGLTEXBUFFERRANGEEXTPROC glad_glTexBufferRangeEXT = NULL; +PFNGLTEXBUFFERRANGEOESPROC glad_glTexBufferRangeOES = NULL; +PFNGLTEXESTIMATEMOTIONQCOMPROC glad_glTexEstimateMotionQCOM = NULL; +PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC glad_glTexEstimateMotionRegionsQCOM = NULL; +PFNGLTEXIMAGE3DOESPROC glad_glTexImage3DOES = NULL; +PFNGLTEXPAGECOMMITMENTEXTPROC glad_glTexPageCommitmentEXT = NULL; +PFNGLTEXPARAMETERIIVOESPROC glad_glTexParameterIivOES = NULL; +PFNGLTEXPARAMETERIUIVOESPROC glad_glTexParameterIuivOES = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC glad_glTexStorage3DMultisampleOES = NULL; +PFNGLTEXSTORAGEATTRIBS2DEXTPROC glad_glTexStorageAttribs2DEXT = NULL; +PFNGLTEXSTORAGEATTRIBS3DEXTPROC glad_glTexStorageAttribs3DEXT = NULL; +PFNGLTEXSUBIMAGE3DOESPROC glad_glTexSubImage3DOES = NULL; +PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC glad_glTextureFoveationParametersQCOM = NULL; +PFNGLTEXTUREVIEWEXTPROC glad_glTextureViewEXT = NULL; +PFNGLTEXTUREVIEWOESPROC glad_glTextureViewOES = NULL; +PFNGLUNIFORMHANDLEUI64IMGPROC glad_glUniformHandleui64IMG = NULL; +PFNGLUNIFORMHANDLEUI64VIMGPROC glad_glUniformHandleui64vIMG = NULL; +PFNGLUNIFORMMATRIX2X3FVNVPROC glad_glUniformMatrix2x3fvNV = NULL; +PFNGLUNIFORMMATRIX2X4FVNVPROC glad_glUniformMatrix2x4fvNV = NULL; +PFNGLUNIFORMMATRIX3X2FVNVPROC glad_glUniformMatrix3x2fvNV = NULL; +PFNGLUNIFORMMATRIX3X4FVNVPROC glad_glUniformMatrix3x4fvNV = NULL; +PFNGLUNIFORMMATRIX4X2FVNVPROC glad_glUniformMatrix4x2fvNV = NULL; +PFNGLUNIFORMMATRIX4X3FVNVPROC glad_glUniformMatrix4x3fvNV = NULL; +PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT = NULL; +PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT = NULL; +PFNGLVERTEXATTRIBDIVISORANGLEPROC glad_glVertexAttribDivisorANGLE = NULL; +PFNGLVERTEXATTRIBDIVISOREXTPROC glad_glVertexAttribDivisorEXT = NULL; +PFNGLVERTEXATTRIBDIVISORNVPROC glad_glVertexAttribDivisorNV = NULL; +PFNGLVIEWPORTARRAYVNVPROC glad_glViewportArrayvNV = NULL; +PFNGLVIEWPORTARRAYVOESPROC glad_glViewportArrayvOES = NULL; +PFNGLVIEWPORTINDEXEDFNVPROC glad_glViewportIndexedfNV = NULL; +PFNGLVIEWPORTINDEXEDFOESPROC glad_glViewportIndexedfOES = NULL; +PFNGLVIEWPORTINDEXEDFVNVPROC glad_glViewportIndexedfvNV = NULL; +PFNGLVIEWPORTINDEXEDFVOESPROC glad_glViewportIndexedfvOES = NULL; + + +static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glAccum = (PFNGLACCUMPROC) load(userptr, "glAccum"); + glad_glAlphaFunc = (PFNGLALPHAFUNCPROC) load(userptr, "glAlphaFunc"); + glad_glBegin = (PFNGLBEGINPROC) load(userptr, "glBegin"); + glad_glBitmap = (PFNGLBITMAPPROC) load(userptr, "glBitmap"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glCallList = (PFNGLCALLLISTPROC) load(userptr, "glCallList"); + glad_glCallLists = (PFNGLCALLLISTSPROC) load(userptr, "glCallLists"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearAccum = (PFNGLCLEARACCUMPROC) load(userptr, "glClearAccum"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); + glad_glClearIndex = (PFNGLCLEARINDEXPROC) load(userptr, "glClearIndex"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glClipPlane = (PFNGLCLIPPLANEPROC) load(userptr, "glClipPlane"); + glad_glColor3b = (PFNGLCOLOR3BPROC) load(userptr, "glColor3b"); + glad_glColor3bv = (PFNGLCOLOR3BVPROC) load(userptr, "glColor3bv"); + glad_glColor3d = (PFNGLCOLOR3DPROC) load(userptr, "glColor3d"); + glad_glColor3dv = (PFNGLCOLOR3DVPROC) load(userptr, "glColor3dv"); + glad_glColor3f = (PFNGLCOLOR3FPROC) load(userptr, "glColor3f"); + glad_glColor3fv = (PFNGLCOLOR3FVPROC) load(userptr, "glColor3fv"); + glad_glColor3i = (PFNGLCOLOR3IPROC) load(userptr, "glColor3i"); + glad_glColor3iv = (PFNGLCOLOR3IVPROC) load(userptr, "glColor3iv"); + glad_glColor3s = (PFNGLCOLOR3SPROC) load(userptr, "glColor3s"); + glad_glColor3sv = (PFNGLCOLOR3SVPROC) load(userptr, "glColor3sv"); + glad_glColor3ub = (PFNGLCOLOR3UBPROC) load(userptr, "glColor3ub"); + glad_glColor3ubv = (PFNGLCOLOR3UBVPROC) load(userptr, "glColor3ubv"); + glad_glColor3ui = (PFNGLCOLOR3UIPROC) load(userptr, "glColor3ui"); + glad_glColor3uiv = (PFNGLCOLOR3UIVPROC) load(userptr, "glColor3uiv"); + glad_glColor3us = (PFNGLCOLOR3USPROC) load(userptr, "glColor3us"); + glad_glColor3usv = (PFNGLCOLOR3USVPROC) load(userptr, "glColor3usv"); + glad_glColor4b = (PFNGLCOLOR4BPROC) load(userptr, "glColor4b"); + glad_glColor4bv = (PFNGLCOLOR4BVPROC) load(userptr, "glColor4bv"); + glad_glColor4d = (PFNGLCOLOR4DPROC) load(userptr, "glColor4d"); + glad_glColor4dv = (PFNGLCOLOR4DVPROC) load(userptr, "glColor4dv"); + glad_glColor4f = (PFNGLCOLOR4FPROC) load(userptr, "glColor4f"); + glad_glColor4fv = (PFNGLCOLOR4FVPROC) load(userptr, "glColor4fv"); + glad_glColor4i = (PFNGLCOLOR4IPROC) load(userptr, "glColor4i"); + glad_glColor4iv = (PFNGLCOLOR4IVPROC) load(userptr, "glColor4iv"); + glad_glColor4s = (PFNGLCOLOR4SPROC) load(userptr, "glColor4s"); + glad_glColor4sv = (PFNGLCOLOR4SVPROC) load(userptr, "glColor4sv"); + glad_glColor4ub = (PFNGLCOLOR4UBPROC) load(userptr, "glColor4ub"); + glad_glColor4ubv = (PFNGLCOLOR4UBVPROC) load(userptr, "glColor4ubv"); + glad_glColor4ui = (PFNGLCOLOR4UIPROC) load(userptr, "glColor4ui"); + glad_glColor4uiv = (PFNGLCOLOR4UIVPROC) load(userptr, "glColor4uiv"); + glad_glColor4us = (PFNGLCOLOR4USPROC) load(userptr, "glColor4us"); + glad_glColor4usv = (PFNGLCOLOR4USVPROC) load(userptr, "glColor4usv"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glColorMaterial = (PFNGLCOLORMATERIALPROC) load(userptr, "glColorMaterial"); + glad_glCopyPixels = (PFNGLCOPYPIXELSPROC) load(userptr, "glCopyPixels"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteLists = (PFNGLDELETELISTSPROC) load(userptr, "glDeleteLists"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); + glad_glDrawPixels = (PFNGLDRAWPIXELSPROC) load(userptr, "glDrawPixels"); + glad_glEdgeFlag = (PFNGLEDGEFLAGPROC) load(userptr, "glEdgeFlag"); + glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC) load(userptr, "glEdgeFlagv"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnd = (PFNGLENDPROC) load(userptr, "glEnd"); + glad_glEndList = (PFNGLENDLISTPROC) load(userptr, "glEndList"); + glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC) load(userptr, "glEvalCoord1d"); + glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC) load(userptr, "glEvalCoord1dv"); + glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC) load(userptr, "glEvalCoord1f"); + glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC) load(userptr, "glEvalCoord1fv"); + glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC) load(userptr, "glEvalCoord2d"); + glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC) load(userptr, "glEvalCoord2dv"); + glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC) load(userptr, "glEvalCoord2f"); + glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC) load(userptr, "glEvalCoord2fv"); + glad_glEvalMesh1 = (PFNGLEVALMESH1PROC) load(userptr, "glEvalMesh1"); + glad_glEvalMesh2 = (PFNGLEVALMESH2PROC) load(userptr, "glEvalMesh2"); + glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC) load(userptr, "glEvalPoint1"); + glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC) load(userptr, "glEvalPoint2"); + glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) load(userptr, "glFeedbackBuffer"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFogf = (PFNGLFOGFPROC) load(userptr, "glFogf"); + glad_glFogfv = (PFNGLFOGFVPROC) load(userptr, "glFogfv"); + glad_glFogi = (PFNGLFOGIPROC) load(userptr, "glFogi"); + glad_glFogiv = (PFNGLFOGIVPROC) load(userptr, "glFogiv"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glFrustum = (PFNGLFRUSTUMPROC) load(userptr, "glFrustum"); + glad_glGenLists = (PFNGLGENLISTSPROC) load(userptr, "glGenLists"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC) load(userptr, "glGetClipPlane"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetLightfv = (PFNGLGETLIGHTFVPROC) load(userptr, "glGetLightfv"); + glad_glGetLightiv = (PFNGLGETLIGHTIVPROC) load(userptr, "glGetLightiv"); + glad_glGetMapdv = (PFNGLGETMAPDVPROC) load(userptr, "glGetMapdv"); + glad_glGetMapfv = (PFNGLGETMAPFVPROC) load(userptr, "glGetMapfv"); + glad_glGetMapiv = (PFNGLGETMAPIVPROC) load(userptr, "glGetMapiv"); + glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC) load(userptr, "glGetMaterialfv"); + glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC) load(userptr, "glGetMaterialiv"); + glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC) load(userptr, "glGetPixelMapfv"); + glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC) load(userptr, "glGetPixelMapuiv"); + glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC) load(userptr, "glGetPixelMapusv"); + glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC) load(userptr, "glGetPolygonStipple"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC) load(userptr, "glGetTexEnvfv"); + glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC) load(userptr, "glGetTexEnviv"); + glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC) load(userptr, "glGetTexGendv"); + glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC) load(userptr, "glGetTexGenfv"); + glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC) load(userptr, "glGetTexGeniv"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIndexMask = (PFNGLINDEXMASKPROC) load(userptr, "glIndexMask"); + glad_glIndexd = (PFNGLINDEXDPROC) load(userptr, "glIndexd"); + glad_glIndexdv = (PFNGLINDEXDVPROC) load(userptr, "glIndexdv"); + glad_glIndexf = (PFNGLINDEXFPROC) load(userptr, "glIndexf"); + glad_glIndexfv = (PFNGLINDEXFVPROC) load(userptr, "glIndexfv"); + glad_glIndexi = (PFNGLINDEXIPROC) load(userptr, "glIndexi"); + glad_glIndexiv = (PFNGLINDEXIVPROC) load(userptr, "glIndexiv"); + glad_glIndexs = (PFNGLINDEXSPROC) load(userptr, "glIndexs"); + glad_glIndexsv = (PFNGLINDEXSVPROC) load(userptr, "glIndexsv"); + glad_glInitNames = (PFNGLINITNAMESPROC) load(userptr, "glInitNames"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsList = (PFNGLISLISTPROC) load(userptr, "glIsList"); + glad_glLightModelf = (PFNGLLIGHTMODELFPROC) load(userptr, "glLightModelf"); + glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC) load(userptr, "glLightModelfv"); + glad_glLightModeli = (PFNGLLIGHTMODELIPROC) load(userptr, "glLightModeli"); + glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC) load(userptr, "glLightModeliv"); + glad_glLightf = (PFNGLLIGHTFPROC) load(userptr, "glLightf"); + glad_glLightfv = (PFNGLLIGHTFVPROC) load(userptr, "glLightfv"); + glad_glLighti = (PFNGLLIGHTIPROC) load(userptr, "glLighti"); + glad_glLightiv = (PFNGLLIGHTIVPROC) load(userptr, "glLightiv"); + glad_glLineStipple = (PFNGLLINESTIPPLEPROC) load(userptr, "glLineStipple"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glListBase = (PFNGLLISTBASEPROC) load(userptr, "glListBase"); + glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC) load(userptr, "glLoadIdentity"); + glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC) load(userptr, "glLoadMatrixd"); + glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC) load(userptr, "glLoadMatrixf"); + glad_glLoadName = (PFNGLLOADNAMEPROC) load(userptr, "glLoadName"); + glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + glad_glMap1d = (PFNGLMAP1DPROC) load(userptr, "glMap1d"); + glad_glMap1f = (PFNGLMAP1FPROC) load(userptr, "glMap1f"); + glad_glMap2d = (PFNGLMAP2DPROC) load(userptr, "glMap2d"); + glad_glMap2f = (PFNGLMAP2FPROC) load(userptr, "glMap2f"); + glad_glMapGrid1d = (PFNGLMAPGRID1DPROC) load(userptr, "glMapGrid1d"); + glad_glMapGrid1f = (PFNGLMAPGRID1FPROC) load(userptr, "glMapGrid1f"); + glad_glMapGrid2d = (PFNGLMAPGRID2DPROC) load(userptr, "glMapGrid2d"); + glad_glMapGrid2f = (PFNGLMAPGRID2FPROC) load(userptr, "glMapGrid2f"); + glad_glMaterialf = (PFNGLMATERIALFPROC) load(userptr, "glMaterialf"); + glad_glMaterialfv = (PFNGLMATERIALFVPROC) load(userptr, "glMaterialfv"); + glad_glMateriali = (PFNGLMATERIALIPROC) load(userptr, "glMateriali"); + glad_glMaterialiv = (PFNGLMATERIALIVPROC) load(userptr, "glMaterialiv"); + glad_glMatrixMode = (PFNGLMATRIXMODEPROC) load(userptr, "glMatrixMode"); + glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC) load(userptr, "glMultMatrixd"); + glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC) load(userptr, "glMultMatrixf"); + glad_glNewList = (PFNGLNEWLISTPROC) load(userptr, "glNewList"); + glad_glNormal3b = (PFNGLNORMAL3BPROC) load(userptr, "glNormal3b"); + glad_glNormal3bv = (PFNGLNORMAL3BVPROC) load(userptr, "glNormal3bv"); + glad_glNormal3d = (PFNGLNORMAL3DPROC) load(userptr, "glNormal3d"); + glad_glNormal3dv = (PFNGLNORMAL3DVPROC) load(userptr, "glNormal3dv"); + glad_glNormal3f = (PFNGLNORMAL3FPROC) load(userptr, "glNormal3f"); + glad_glNormal3fv = (PFNGLNORMAL3FVPROC) load(userptr, "glNormal3fv"); + glad_glNormal3i = (PFNGLNORMAL3IPROC) load(userptr, "glNormal3i"); + glad_glNormal3iv = (PFNGLNORMAL3IVPROC) load(userptr, "glNormal3iv"); + glad_glNormal3s = (PFNGLNORMAL3SPROC) load(userptr, "glNormal3s"); + glad_glNormal3sv = (PFNGLNORMAL3SVPROC) load(userptr, "glNormal3sv"); + glad_glOrtho = (PFNGLORTHOPROC) load(userptr, "glOrtho"); + glad_glPassThrough = (PFNGLPASSTHROUGHPROC) load(userptr, "glPassThrough"); + glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC) load(userptr, "glPixelMapfv"); + glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC) load(userptr, "glPixelMapuiv"); + glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC) load(userptr, "glPixelMapusv"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC) load(userptr, "glPixelTransferf"); + glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC) load(userptr, "glPixelTransferi"); + glad_glPixelZoom = (PFNGLPIXELZOOMPROC) load(userptr, "glPixelZoom"); + glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); + glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC) load(userptr, "glPolygonStipple"); + glad_glPopAttrib = (PFNGLPOPATTRIBPROC) load(userptr, "glPopAttrib"); + glad_glPopMatrix = (PFNGLPOPMATRIXPROC) load(userptr, "glPopMatrix"); + glad_glPopName = (PFNGLPOPNAMEPROC) load(userptr, "glPopName"); + glad_glPushAttrib = (PFNGLPUSHATTRIBPROC) load(userptr, "glPushAttrib"); + glad_glPushMatrix = (PFNGLPUSHMATRIXPROC) load(userptr, "glPushMatrix"); + glad_glPushName = (PFNGLPUSHNAMEPROC) load(userptr, "glPushName"); + glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC) load(userptr, "glRasterPos2d"); + glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC) load(userptr, "glRasterPos2dv"); + glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC) load(userptr, "glRasterPos2f"); + glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC) load(userptr, "glRasterPos2fv"); + glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC) load(userptr, "glRasterPos2i"); + glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC) load(userptr, "glRasterPos2iv"); + glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC) load(userptr, "glRasterPos2s"); + glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC) load(userptr, "glRasterPos2sv"); + glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC) load(userptr, "glRasterPos3d"); + glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC) load(userptr, "glRasterPos3dv"); + glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC) load(userptr, "glRasterPos3f"); + glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC) load(userptr, "glRasterPos3fv"); + glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC) load(userptr, "glRasterPos3i"); + glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC) load(userptr, "glRasterPos3iv"); + glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC) load(userptr, "glRasterPos3s"); + glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC) load(userptr, "glRasterPos3sv"); + glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC) load(userptr, "glRasterPos4d"); + glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC) load(userptr, "glRasterPos4dv"); + glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC) load(userptr, "glRasterPos4f"); + glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC) load(userptr, "glRasterPos4fv"); + glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC) load(userptr, "glRasterPos4i"); + glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC) load(userptr, "glRasterPos4iv"); + glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC) load(userptr, "glRasterPos4s"); + glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC) load(userptr, "glRasterPos4sv"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glRectd = (PFNGLRECTDPROC) load(userptr, "glRectd"); + glad_glRectdv = (PFNGLRECTDVPROC) load(userptr, "glRectdv"); + glad_glRectf = (PFNGLRECTFPROC) load(userptr, "glRectf"); + glad_glRectfv = (PFNGLRECTFVPROC) load(userptr, "glRectfv"); + glad_glRecti = (PFNGLRECTIPROC) load(userptr, "glRecti"); + glad_glRectiv = (PFNGLRECTIVPROC) load(userptr, "glRectiv"); + glad_glRects = (PFNGLRECTSPROC) load(userptr, "glRects"); + glad_glRectsv = (PFNGLRECTSVPROC) load(userptr, "glRectsv"); + glad_glRenderMode = (PFNGLRENDERMODEPROC) load(userptr, "glRenderMode"); + glad_glRotated = (PFNGLROTATEDPROC) load(userptr, "glRotated"); + glad_glRotatef = (PFNGLROTATEFPROC) load(userptr, "glRotatef"); + glad_glScaled = (PFNGLSCALEDPROC) load(userptr, "glScaled"); + glad_glScalef = (PFNGLSCALEFPROC) load(userptr, "glScalef"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC) load(userptr, "glSelectBuffer"); + glad_glShadeModel = (PFNGLSHADEMODELPROC) load(userptr, "glShadeModel"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC) load(userptr, "glTexCoord1d"); + glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC) load(userptr, "glTexCoord1dv"); + glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC) load(userptr, "glTexCoord1f"); + glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC) load(userptr, "glTexCoord1fv"); + glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC) load(userptr, "glTexCoord1i"); + glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC) load(userptr, "glTexCoord1iv"); + glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC) load(userptr, "glTexCoord1s"); + glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC) load(userptr, "glTexCoord1sv"); + glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC) load(userptr, "glTexCoord2d"); + glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC) load(userptr, "glTexCoord2dv"); + glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC) load(userptr, "glTexCoord2f"); + glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC) load(userptr, "glTexCoord2fv"); + glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC) load(userptr, "glTexCoord2i"); + glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC) load(userptr, "glTexCoord2iv"); + glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC) load(userptr, "glTexCoord2s"); + glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC) load(userptr, "glTexCoord2sv"); + glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC) load(userptr, "glTexCoord3d"); + glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC) load(userptr, "glTexCoord3dv"); + glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC) load(userptr, "glTexCoord3f"); + glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC) load(userptr, "glTexCoord3fv"); + glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC) load(userptr, "glTexCoord3i"); + glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC) load(userptr, "glTexCoord3iv"); + glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC) load(userptr, "glTexCoord3s"); + glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC) load(userptr, "glTexCoord3sv"); + glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC) load(userptr, "glTexCoord4d"); + glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC) load(userptr, "glTexCoord4dv"); + glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC) load(userptr, "glTexCoord4f"); + glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC) load(userptr, "glTexCoord4fv"); + glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC) load(userptr, "glTexCoord4i"); + glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC) load(userptr, "glTexCoord4iv"); + glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC) load(userptr, "glTexCoord4s"); + glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC) load(userptr, "glTexCoord4sv"); + glad_glTexEnvf = (PFNGLTEXENVFPROC) load(userptr, "glTexEnvf"); + glad_glTexEnvfv = (PFNGLTEXENVFVPROC) load(userptr, "glTexEnvfv"); + glad_glTexEnvi = (PFNGLTEXENVIPROC) load(userptr, "glTexEnvi"); + glad_glTexEnviv = (PFNGLTEXENVIVPROC) load(userptr, "glTexEnviv"); + glad_glTexGend = (PFNGLTEXGENDPROC) load(userptr, "glTexGend"); + glad_glTexGendv = (PFNGLTEXGENDVPROC) load(userptr, "glTexGendv"); + glad_glTexGenf = (PFNGLTEXGENFPROC) load(userptr, "glTexGenf"); + glad_glTexGenfv = (PFNGLTEXGENFVPROC) load(userptr, "glTexGenfv"); + glad_glTexGeni = (PFNGLTEXGENIPROC) load(userptr, "glTexGeni"); + glad_glTexGeniv = (PFNGLTEXGENIVPROC) load(userptr, "glTexGeniv"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTranslated = (PFNGLTRANSLATEDPROC) load(userptr, "glTranslated"); + glad_glTranslatef = (PFNGLTRANSLATEFPROC) load(userptr, "glTranslatef"); + glad_glVertex2d = (PFNGLVERTEX2DPROC) load(userptr, "glVertex2d"); + glad_glVertex2dv = (PFNGLVERTEX2DVPROC) load(userptr, "glVertex2dv"); + glad_glVertex2f = (PFNGLVERTEX2FPROC) load(userptr, "glVertex2f"); + glad_glVertex2fv = (PFNGLVERTEX2FVPROC) load(userptr, "glVertex2fv"); + glad_glVertex2i = (PFNGLVERTEX2IPROC) load(userptr, "glVertex2i"); + glad_glVertex2iv = (PFNGLVERTEX2IVPROC) load(userptr, "glVertex2iv"); + glad_glVertex2s = (PFNGLVERTEX2SPROC) load(userptr, "glVertex2s"); + glad_glVertex2sv = (PFNGLVERTEX2SVPROC) load(userptr, "glVertex2sv"); + glad_glVertex3d = (PFNGLVERTEX3DPROC) load(userptr, "glVertex3d"); + glad_glVertex3dv = (PFNGLVERTEX3DVPROC) load(userptr, "glVertex3dv"); + glad_glVertex3f = (PFNGLVERTEX3FPROC) load(userptr, "glVertex3f"); + glad_glVertex3fv = (PFNGLVERTEX3FVPROC) load(userptr, "glVertex3fv"); + glad_glVertex3i = (PFNGLVERTEX3IPROC) load(userptr, "glVertex3i"); + glad_glVertex3iv = (PFNGLVERTEX3IVPROC) load(userptr, "glVertex3iv"); + glad_glVertex3s = (PFNGLVERTEX3SPROC) load(userptr, "glVertex3s"); + glad_glVertex3sv = (PFNGLVERTEX3SVPROC) load(userptr, "glVertex3sv"); + glad_glVertex4d = (PFNGLVERTEX4DPROC) load(userptr, "glVertex4d"); + glad_glVertex4dv = (PFNGLVERTEX4DVPROC) load(userptr, "glVertex4dv"); + glad_glVertex4f = (PFNGLVERTEX4FPROC) load(userptr, "glVertex4f"); + glad_glVertex4fv = (PFNGLVERTEX4FVPROC) load(userptr, "glVertex4fv"); + glad_glVertex4i = (PFNGLVERTEX4IPROC) load(userptr, "glVertex4i"); + glad_glVertex4iv = (PFNGLVERTEX4IVPROC) load(userptr, "glVertex4iv"); + glad_glVertex4s = (PFNGLVERTEX4SPROC) load(userptr, "glVertex4s"); + glad_glVertex4sv = (PFNGLVERTEX4SVPROC) load(userptr, "glVertex4sv"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC) load(userptr, "glAreTexturesResident"); + glad_glArrayElement = (PFNGLARRAYELEMENTPROC) load(userptr, "glArrayElement"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glColorPointer = (PFNGLCOLORPOINTERPROC) load(userptr, "glColorPointer"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load(userptr, "glDisableClientState"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC) load(userptr, "glEdgeFlagPointer"); + glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC) load(userptr, "glEnableClientState"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glIndexPointer = (PFNGLINDEXPOINTERPROC) load(userptr, "glIndexPointer"); + glad_glIndexub = (PFNGLINDEXUBPROC) load(userptr, "glIndexub"); + glad_glIndexubv = (PFNGLINDEXUBVPROC) load(userptr, "glIndexubv"); + glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC) load(userptr, "glInterleavedArrays"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glNormalPointer = (PFNGLNORMALPOINTERPROC) load(userptr, "glNormalPointer"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC) load(userptr, "glPopClientAttrib"); + glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC) load(userptr, "glPrioritizeTextures"); + glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC) load(userptr, "glPushClientAttrib"); + glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load(userptr, "glTexCoordPointer"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC) load(userptr, "glVertexPointer"); +} +static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); +} +static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load(userptr, "glClientActiveTexture"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); + glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC) load(userptr, "glLoadTransposeMatrixd"); + glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC) load(userptr, "glLoadTransposeMatrixf"); + glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC) load(userptr, "glMultTransposeMatrixd"); + glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC) load(userptr, "glMultTransposeMatrixf"); + glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC) load(userptr, "glMultiTexCoord1d"); + glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC) load(userptr, "glMultiTexCoord1dv"); + glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC) load(userptr, "glMultiTexCoord1f"); + glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC) load(userptr, "glMultiTexCoord1fv"); + glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC) load(userptr, "glMultiTexCoord1i"); + glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC) load(userptr, "glMultiTexCoord1iv"); + glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC) load(userptr, "glMultiTexCoord1s"); + glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC) load(userptr, "glMultiTexCoord1sv"); + glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC) load(userptr, "glMultiTexCoord2d"); + glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC) load(userptr, "glMultiTexCoord2dv"); + glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) load(userptr, "glMultiTexCoord2f"); + glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) load(userptr, "glMultiTexCoord2fv"); + glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC) load(userptr, "glMultiTexCoord2i"); + glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC) load(userptr, "glMultiTexCoord2iv"); + glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC) load(userptr, "glMultiTexCoord2s"); + glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC) load(userptr, "glMultiTexCoord2sv"); + glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC) load(userptr, "glMultiTexCoord3d"); + glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC) load(userptr, "glMultiTexCoord3dv"); + glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC) load(userptr, "glMultiTexCoord3f"); + glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC) load(userptr, "glMultiTexCoord3fv"); + glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC) load(userptr, "glMultiTexCoord3i"); + glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC) load(userptr, "glMultiTexCoord3iv"); + glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC) load(userptr, "glMultiTexCoord3s"); + glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC) load(userptr, "glMultiTexCoord3sv"); + glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC) load(userptr, "glMultiTexCoord4d"); + glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC) load(userptr, "glMultiTexCoord4dv"); + glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load(userptr, "glMultiTexCoord4f"); + glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC) load(userptr, "glMultiTexCoord4fv"); + glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC) load(userptr, "glMultiTexCoord4i"); + glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC) load(userptr, "glMultiTexCoord4iv"); + glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC) load(userptr, "glMultiTexCoord4s"); + glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC) load(userptr, "glMultiTexCoord4sv"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); +} +static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC) load(userptr, "glFogCoordPointer"); + glad_glFogCoordd = (PFNGLFOGCOORDDPROC) load(userptr, "glFogCoordd"); + glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC) load(userptr, "glFogCoorddv"); + glad_glFogCoordf = (PFNGLFOGCOORDFPROC) load(userptr, "glFogCoordf"); + glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC) load(userptr, "glFogCoordfv"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); + glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC) load(userptr, "glSecondaryColor3b"); + glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC) load(userptr, "glSecondaryColor3bv"); + glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC) load(userptr, "glSecondaryColor3d"); + glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC) load(userptr, "glSecondaryColor3dv"); + glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC) load(userptr, "glSecondaryColor3f"); + glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC) load(userptr, "glSecondaryColor3fv"); + glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC) load(userptr, "glSecondaryColor3i"); + glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC) load(userptr, "glSecondaryColor3iv"); + glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC) load(userptr, "glSecondaryColor3s"); + glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC) load(userptr, "glSecondaryColor3sv"); + glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC) load(userptr, "glSecondaryColor3ub"); + glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC) load(userptr, "glSecondaryColor3ubv"); + glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC) load(userptr, "glSecondaryColor3ui"); + glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC) load(userptr, "glSecondaryColor3uiv"); + glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC) load(userptr, "glSecondaryColor3us"); + glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC) load(userptr, "glSecondaryColor3usv"); + glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC) load(userptr, "glSecondaryColorPointer"); + glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC) load(userptr, "glWindowPos2d"); + glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC) load(userptr, "glWindowPos2dv"); + glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC) load(userptr, "glWindowPos2f"); + glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC) load(userptr, "glWindowPos2fv"); + glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC) load(userptr, "glWindowPos2i"); + glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC) load(userptr, "glWindowPos2iv"); + glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC) load(userptr, "glWindowPos2s"); + glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC) load(userptr, "glWindowPos2sv"); + glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC) load(userptr, "glWindowPos3d"); + glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC) load(userptr, "glWindowPos3dv"); + glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC) load(userptr, "glWindowPos3f"); + glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC) load(userptr, "glWindowPos3fv"); + glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC) load(userptr, "glWindowPos3i"); + glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC) load(userptr, "glWindowPos3iv"); + glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC) load(userptr, "glWindowPos3s"); + glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC) load(userptr, "glWindowPos3sv"); +} +static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); +} +static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); +} +static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); +} +static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); +} +static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +} +static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_3) return; + glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glColorP3ui = (PFNGLCOLORP3UIPROC) load(userptr, "glColorP3ui"); + glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC) load(userptr, "glColorP3uiv"); + glad_glColorP4ui = (PFNGLCOLORP4UIPROC) load(userptr, "glColorP4ui"); + glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC) load(userptr, "glColorP4uiv"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); + glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load(userptr, "glMultiTexCoordP1ui"); + glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load(userptr, "glMultiTexCoordP1uiv"); + glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load(userptr, "glMultiTexCoordP2ui"); + glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load(userptr, "glMultiTexCoordP2uiv"); + glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load(userptr, "glMultiTexCoordP3ui"); + glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load(userptr, "glMultiTexCoordP3uiv"); + glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load(userptr, "glMultiTexCoordP4ui"); + glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load(userptr, "glMultiTexCoordP4uiv"); + glad_glNormalP3ui = (PFNGLNORMALP3UIPROC) load(userptr, "glNormalP3ui"); + glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC) load(userptr, "glNormalP3uiv"); + glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load(userptr, "glSecondaryColorP3ui"); + glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load(userptr, "glSecondaryColorP3uiv"); + glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load(userptr, "glTexCoordP1ui"); + glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load(userptr, "glTexCoordP1uiv"); + glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load(userptr, "glTexCoordP2ui"); + glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load(userptr, "glTexCoordP2uiv"); + glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load(userptr, "glTexCoordP3ui"); + glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load(userptr, "glTexCoordP3uiv"); + glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load(userptr, "glTexCoordP4ui"); + glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load(userptr, "glTexCoordP4uiv"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); + glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC) load(userptr, "glVertexP2ui"); + glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC) load(userptr, "glVertexP2uiv"); + glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC) load(userptr, "glVertexP3ui"); + glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC) load(userptr, "glVertexP3uiv"); + glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC) load(userptr, "glVertexP4ui"); + glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC) load(userptr, "glVertexP4uiv"); +} +static void glad_gl_load_GL_VERSION_4_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_0) return; + glad_glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load(userptr, "glBeginQueryIndexed"); + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load(userptr, "glBlendEquationSeparatei"); + glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load(userptr, "glBlendEquationi"); + glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load(userptr, "glBlendFuncSeparatei"); + glad_glBlendFunci = (PFNGLBLENDFUNCIPROC) load(userptr, "glBlendFunci"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); + glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load(userptr, "glDrawTransformFeedback"); + glad_glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load(userptr, "glDrawTransformFeedbackStream"); + glad_glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load(userptr, "glEndQueryIndexed"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load(userptr, "glGetActiveSubroutineName"); + glad_glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load(userptr, "glGetActiveSubroutineUniformName"); + glad_glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load(userptr, "glGetActiveSubroutineUniformiv"); + glad_glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load(userptr, "glGetProgramStageiv"); + glad_glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load(userptr, "glGetQueryIndexediv"); + glad_glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load(userptr, "glGetSubroutineIndex"); + glad_glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load(userptr, "glGetSubroutineUniformLocation"); + glad_glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load(userptr, "glGetUniformSubroutineuiv"); + glad_glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load(userptr, "glGetUniformdv"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load(userptr, "glMinSampleShading"); + glad_glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load(userptr, "glPatchParameterfv"); + glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + glad_glUniform1d = (PFNGLUNIFORM1DPROC) load(userptr, "glUniform1d"); + glad_glUniform1dv = (PFNGLUNIFORM1DVPROC) load(userptr, "glUniform1dv"); + glad_glUniform2d = (PFNGLUNIFORM2DPROC) load(userptr, "glUniform2d"); + glad_glUniform2dv = (PFNGLUNIFORM2DVPROC) load(userptr, "glUniform2dv"); + glad_glUniform3d = (PFNGLUNIFORM3DPROC) load(userptr, "glUniform3d"); + glad_glUniform3dv = (PFNGLUNIFORM3DVPROC) load(userptr, "glUniform3dv"); + glad_glUniform4d = (PFNGLUNIFORM4DPROC) load(userptr, "glUniform4d"); + glad_glUniform4dv = (PFNGLUNIFORM4DVPROC) load(userptr, "glUniform4dv"); + glad_glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load(userptr, "glUniformMatrix2dv"); + glad_glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load(userptr, "glUniformMatrix2x3dv"); + glad_glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load(userptr, "glUniformMatrix2x4dv"); + glad_glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load(userptr, "glUniformMatrix3dv"); + glad_glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load(userptr, "glUniformMatrix3x2dv"); + glad_glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load(userptr, "glUniformMatrix3x4dv"); + glad_glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load(userptr, "glUniformMatrix4dv"); + glad_glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load(userptr, "glUniformMatrix4x2dv"); + glad_glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load(userptr, "glUniformMatrix4x3dv"); + glad_glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load(userptr, "glUniformSubroutinesuiv"); +} +static void glad_gl_load_GL_VERSION_4_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_1) return; + glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + glad_glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load(userptr, "glDepthRangeArrayv"); + glad_glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load(userptr, "glDepthRangeIndexed"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load(userptr, "glGetDoublei_v"); + glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC) load(userptr, "glGetFloati_v"); + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load(userptr, "glGetVertexAttribLdv"); + glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load(userptr, "glProgramUniform1d"); + glad_glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load(userptr, "glProgramUniform1dv"); + glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + glad_glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load(userptr, "glProgramUniform2d"); + glad_glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load(userptr, "glProgramUniform2dv"); + glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + glad_glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load(userptr, "glProgramUniform3d"); + glad_glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load(userptr, "glProgramUniform3dv"); + glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + glad_glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load(userptr, "glProgramUniform4d"); + glad_glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load(userptr, "glProgramUniform4dv"); + glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + glad_glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load(userptr, "glProgramUniformMatrix2dv"); + glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + glad_glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load(userptr, "glProgramUniformMatrix2x3dv"); + glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + glad_glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load(userptr, "glProgramUniformMatrix2x4dv"); + glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + glad_glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load(userptr, "glProgramUniformMatrix3dv"); + glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + glad_glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load(userptr, "glProgramUniformMatrix3x2dv"); + glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + glad_glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load(userptr, "glProgramUniformMatrix3x4dv"); + glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + glad_glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load(userptr, "glProgramUniformMatrix4dv"); + glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + glad_glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load(userptr, "glProgramUniformMatrix4x2dv"); + glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + glad_glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load(userptr, "glProgramUniformMatrix4x3dv"); + glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load(userptr, "glScissorArrayv"); + glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load(userptr, "glScissorIndexed"); + glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load(userptr, "glScissorIndexedv"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); + glad_glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load(userptr, "glVertexAttribL1d"); + glad_glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load(userptr, "glVertexAttribL1dv"); + glad_glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load(userptr, "glVertexAttribL2d"); + glad_glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load(userptr, "glVertexAttribL2dv"); + glad_glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load(userptr, "glVertexAttribL3d"); + glad_glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load(userptr, "glVertexAttribL3dv"); + glad_glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load(userptr, "glVertexAttribL4d"); + glad_glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load(userptr, "glVertexAttribL4dv"); + glad_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load(userptr, "glVertexAttribLPointer"); + glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load(userptr, "glViewportArrayv"); + glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load(userptr, "glViewportIndexedf"); + glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load(userptr, "glViewportIndexedfv"); +} +static void glad_gl_load_GL_VERSION_4_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_2) return; + glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawArraysInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstance"); + glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackInstanced"); + glad_glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackStreamInstanced"); + glad_glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load(userptr, "glGetActiveAtomicCounterBufferiv"); + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); + glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load(userptr, "glTexStorage1D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); +} +static void glad_gl_load_GL_VERSION_4_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_3) return; + glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + glad_glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load(userptr, "glClearBufferData"); + glad_glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load(userptr, "glClearBufferSubData"); + glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData"); + glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); + glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); + glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); + glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); + glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); + glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); + glad_glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load(userptr, "glGetInternalformati64v"); + glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); + glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load(userptr, "glGetProgramResourceLocationIndex"); + glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); + glad_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData"); + glad_glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage"); + glad_glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage"); + glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load(userptr, "glMultiDrawArraysIndirect"); + glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load(userptr, "glMultiDrawElementsIndirect"); + glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); + glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); + glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); + glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); + glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding"); + glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange"); + glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample"); + glad_glTextureView = (PFNGLTEXTUREVIEWPROC) load(userptr, "glTextureView"); + glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + glad_glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load(userptr, "glVertexAttribLFormat"); + glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_VERSION_4_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_4) return; + glad_glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load(userptr, "glBindBuffersBase"); + glad_glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load(userptr, "glBindBuffersRange"); + glad_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load(userptr, "glBindImageTextures"); + glad_glBindSamplers = (PFNGLBINDSAMPLERSPROC) load(userptr, "glBindSamplers"); + glad_glBindTextures = (PFNGLBINDTEXTURESPROC) load(userptr, "glBindTextures"); + glad_glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load(userptr, "glBindVertexBuffers"); + glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load(userptr, "glBufferStorage"); + glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load(userptr, "glClearTexImage"); + glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load(userptr, "glClearTexSubImage"); +} +static void glad_gl_load_GL_VERSION_4_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_5) return; + glad_glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit"); + glad_glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer"); + glad_glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus"); + glad_glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData"); + glad_glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData"); + glad_glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi"); + glad_glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv"); + glad_glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv"); + glad_glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv"); + glad_glClipControl = (PFNGLCLIPCONTROLPROC) load(userptr, "glClipControl"); + glad_glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D"); + glad_glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D"); + glad_glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D"); + glad_glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData"); + glad_glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D"); + glad_glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D"); + glad_glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D"); + glad_glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers"); + glad_glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers"); + glad_glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines"); + glad_glCreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries"); + glad_glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers"); + glad_glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers"); + glad_glCreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures"); + glad_glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks"); + glad_glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays"); + glad_glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib"); + glad_glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib"); + glad_glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange"); + glad_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap"); + glad_glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage"); + glad_glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load(userptr, "glGetCompressedTextureSubImage"); + glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus"); + glad_glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v"); + glad_glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv"); + glad_glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv"); + glad_glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData"); + glad_glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv"); + glad_glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv"); + glad_glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv"); + glad_glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v"); + glad_glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv"); + glad_glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v"); + glad_glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv"); + glad_glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage"); + glad_glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv"); + glad_glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv"); + glad_glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv"); + glad_glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv"); + glad_glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv"); + glad_glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv"); + glad_glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load(userptr, "glGetTextureSubImage"); + glad_glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v"); + glad_glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v"); + glad_glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv"); + glad_glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv"); + glad_glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv"); + glad_glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv"); + glad_glGetnColorTable = (PFNGLGETNCOLORTABLEPROC) load(userptr, "glGetnColorTable"); + glad_glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetnCompressedTexImage"); + glad_glGetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC) load(userptr, "glGetnConvolutionFilter"); + glad_glGetnHistogram = (PFNGLGETNHISTOGRAMPROC) load(userptr, "glGetnHistogram"); + glad_glGetnMapdv = (PFNGLGETNMAPDVPROC) load(userptr, "glGetnMapdv"); + glad_glGetnMapfv = (PFNGLGETNMAPFVPROC) load(userptr, "glGetnMapfv"); + glad_glGetnMapiv = (PFNGLGETNMAPIVPROC) load(userptr, "glGetnMapiv"); + glad_glGetnMinmax = (PFNGLGETNMINMAXPROC) load(userptr, "glGetnMinmax"); + glad_glGetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC) load(userptr, "glGetnPixelMapfv"); + glad_glGetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC) load(userptr, "glGetnPixelMapuiv"); + glad_glGetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC) load(userptr, "glGetnPixelMapusv"); + glad_glGetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC) load(userptr, "glGetnPolygonStipple"); + glad_glGetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC) load(userptr, "glGetnSeparableFilter"); + glad_glGetnTexImage = (PFNGLGETNTEXIMAGEPROC) load(userptr, "glGetnTexImage"); + glad_glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load(userptr, "glGetnUniformdv"); + glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv"); + glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv"); + glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv"); + glad_glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData"); + glad_glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData"); + glad_glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer"); + glad_glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange"); + glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); + glad_glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData"); + glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage"); + glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData"); + glad_glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer"); + glad_glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers"); + glad_glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri"); + glad_glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer"); + glad_glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer"); + glad_glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture"); + glad_glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer"); + glad_glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage"); + glad_glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample"); + glad_glReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels"); + glad_glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load(userptr, "glTextureBarrier"); + glad_glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer"); + glad_glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange"); + glad_glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv"); + glad_glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv"); + glad_glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf"); + glad_glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv"); + glad_glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri"); + glad_glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv"); + glad_glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D"); + glad_glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D"); + glad_glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample"); + glad_glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D"); + glad_glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample"); + glad_glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D"); + glad_glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D"); + glad_glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D"); + glad_glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase"); + glad_glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange"); + glad_glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer"); + glad_glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding"); + glad_glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat"); + glad_glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat"); + glad_glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat"); + glad_glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor"); + glad_glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer"); + glad_glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer"); + glad_glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers"); +} +static void glad_gl_load_GL_VERSION_4_6( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_6) return; + glad_glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawArraysIndirectCount"); + glad_glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawElementsIndirectCount"); + glad_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load(userptr, "glPolygonOffsetClamp"); + glad_glSpecializeShader = (PFNGLSPECIALIZESHADERPROC) load(userptr, "glSpecializeShader"); +} +static void glad_gl_load_GL_VERSION_ES_CM_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_ES_CM_1_0) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glAlphaFunc = (PFNGLALPHAFUNCPROC) load(userptr, "glAlphaFunc"); + glad_glAlphaFuncx = (PFNGLALPHAFUNCXPROC) load(userptr, "glAlphaFuncx"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearColorx = (PFNGLCLEARCOLORXPROC) load(userptr, "glClearColorx"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glClearDepthx = (PFNGLCLEARDEPTHXPROC) load(userptr, "glClearDepthx"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load(userptr, "glClientActiveTexture"); + glad_glClipPlanef = (PFNGLCLIPPLANEFPROC) load(userptr, "glClipPlanef"); + glad_glClipPlanex = (PFNGLCLIPPLANEXPROC) load(userptr, "glClipPlanex"); + glad_glColor4f = (PFNGLCOLOR4FPROC) load(userptr, "glColor4f"); + glad_glColor4ub = (PFNGLCOLOR4UBPROC) load(userptr, "glColor4ub"); + glad_glColor4x = (PFNGLCOLOR4XPROC) load(userptr, "glColor4x"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glColorPointer = (PFNGLCOLORPOINTERPROC) load(userptr, "glColorPointer"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glDepthRangex = (PFNGLDEPTHRANGEXPROC) load(userptr, "glDepthRangex"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load(userptr, "glDisableClientState"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC) load(userptr, "glEnableClientState"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFogf = (PFNGLFOGFPROC) load(userptr, "glFogf"); + glad_glFogfv = (PFNGLFOGFVPROC) load(userptr, "glFogfv"); + glad_glFogx = (PFNGLFOGXPROC) load(userptr, "glFogx"); + glad_glFogxv = (PFNGLFOGXVPROC) load(userptr, "glFogxv"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glFrustumf = (PFNGLFRUSTUMFPROC) load(userptr, "glFrustumf"); + glad_glFrustumx = (PFNGLFRUSTUMXPROC) load(userptr, "glFrustumx"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetClipPlanef = (PFNGLGETCLIPPLANEFPROC) load(userptr, "glGetClipPlanef"); + glad_glGetClipPlanex = (PFNGLGETCLIPPLANEXPROC) load(userptr, "glGetClipPlanex"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFixedv = (PFNGLGETFIXEDVPROC) load(userptr, "glGetFixedv"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetLightfv = (PFNGLGETLIGHTFVPROC) load(userptr, "glGetLightfv"); + glad_glGetLightxv = (PFNGLGETLIGHTXVPROC) load(userptr, "glGetLightxv"); + glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC) load(userptr, "glGetMaterialfv"); + glad_glGetMaterialxv = (PFNGLGETMATERIALXVPROC) load(userptr, "glGetMaterialxv"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC) load(userptr, "glGetTexEnvfv"); + glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC) load(userptr, "glGetTexEnviv"); + glad_glGetTexEnvxv = (PFNGLGETTEXENVXVPROC) load(userptr, "glGetTexEnvxv"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glGetTexParameterxv = (PFNGLGETTEXPARAMETERXVPROC) load(userptr, "glGetTexParameterxv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glLightModelf = (PFNGLLIGHTMODELFPROC) load(userptr, "glLightModelf"); + glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC) load(userptr, "glLightModelfv"); + glad_glLightModelx = (PFNGLLIGHTMODELXPROC) load(userptr, "glLightModelx"); + glad_glLightModelxv = (PFNGLLIGHTMODELXVPROC) load(userptr, "glLightModelxv"); + glad_glLightf = (PFNGLLIGHTFPROC) load(userptr, "glLightf"); + glad_glLightfv = (PFNGLLIGHTFVPROC) load(userptr, "glLightfv"); + glad_glLightx = (PFNGLLIGHTXPROC) load(userptr, "glLightx"); + glad_glLightxv = (PFNGLLIGHTXVPROC) load(userptr, "glLightxv"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glLineWidthx = (PFNGLLINEWIDTHXPROC) load(userptr, "glLineWidthx"); + glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC) load(userptr, "glLoadIdentity"); + glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC) load(userptr, "glLoadMatrixf"); + glad_glLoadMatrixx = (PFNGLLOADMATRIXXPROC) load(userptr, "glLoadMatrixx"); + glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + glad_glMaterialf = (PFNGLMATERIALFPROC) load(userptr, "glMaterialf"); + glad_glMaterialfv = (PFNGLMATERIALFVPROC) load(userptr, "glMaterialfv"); + glad_glMaterialx = (PFNGLMATERIALXPROC) load(userptr, "glMaterialx"); + glad_glMaterialxv = (PFNGLMATERIALXVPROC) load(userptr, "glMaterialxv"); + glad_glMatrixMode = (PFNGLMATRIXMODEPROC) load(userptr, "glMatrixMode"); + glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC) load(userptr, "glMultMatrixf"); + glad_glMultMatrixx = (PFNGLMULTMATRIXXPROC) load(userptr, "glMultMatrixx"); + glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load(userptr, "glMultiTexCoord4f"); + glad_glMultiTexCoord4x = (PFNGLMULTITEXCOORD4XPROC) load(userptr, "glMultiTexCoord4x"); + glad_glNormal3f = (PFNGLNORMAL3FPROC) load(userptr, "glNormal3f"); + glad_glNormal3x = (PFNGLNORMAL3XPROC) load(userptr, "glNormal3x"); + glad_glNormalPointer = (PFNGLNORMALPOINTERPROC) load(userptr, "glNormalPointer"); + glad_glOrthof = (PFNGLORTHOFPROC) load(userptr, "glOrthof"); + glad_glOrthox = (PFNGLORTHOXPROC) load(userptr, "glOrthox"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + glad_glPointParameterx = (PFNGLPOINTPARAMETERXPROC) load(userptr, "glPointParameterx"); + glad_glPointParameterxv = (PFNGLPOINTPARAMETERXVPROC) load(userptr, "glPointParameterxv"); + glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + glad_glPointSizex = (PFNGLPOINTSIZEXPROC) load(userptr, "glPointSizex"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glPolygonOffsetx = (PFNGLPOLYGONOFFSETXPROC) load(userptr, "glPolygonOffsetx"); + glad_glPopMatrix = (PFNGLPOPMATRIXPROC) load(userptr, "glPopMatrix"); + glad_glPushMatrix = (PFNGLPUSHMATRIXPROC) load(userptr, "glPushMatrix"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glRotatef = (PFNGLROTATEFPROC) load(userptr, "glRotatef"); + glad_glRotatex = (PFNGLROTATEXPROC) load(userptr, "glRotatex"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); + glad_glSampleCoveragex = (PFNGLSAMPLECOVERAGEXPROC) load(userptr, "glSampleCoveragex"); + glad_glScalef = (PFNGLSCALEFPROC) load(userptr, "glScalef"); + glad_glScalex = (PFNGLSCALEXPROC) load(userptr, "glScalex"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glShadeModel = (PFNGLSHADEMODELPROC) load(userptr, "glShadeModel"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load(userptr, "glTexCoordPointer"); + glad_glTexEnvf = (PFNGLTEXENVFPROC) load(userptr, "glTexEnvf"); + glad_glTexEnvfv = (PFNGLTEXENVFVPROC) load(userptr, "glTexEnvfv"); + glad_glTexEnvi = (PFNGLTEXENVIPROC) load(userptr, "glTexEnvi"); + glad_glTexEnviv = (PFNGLTEXENVIVPROC) load(userptr, "glTexEnviv"); + glad_glTexEnvx = (PFNGLTEXENVXPROC) load(userptr, "glTexEnvx"); + glad_glTexEnvxv = (PFNGLTEXENVXVPROC) load(userptr, "glTexEnvxv"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTexParameterx = (PFNGLTEXPARAMETERXPROC) load(userptr, "glTexParameterx"); + glad_glTexParameterxv = (PFNGLTEXPARAMETERXVPROC) load(userptr, "glTexParameterxv"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glTranslatef = (PFNGLTRANSLATEFPROC) load(userptr, "glTranslatef"); + glad_glTranslatex = (PFNGLTRANSLATEXPROC) load(userptr, "glTranslatex"); + glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC) load(userptr, "glVertexPointer"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_ES_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_2_0) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_ES_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_0) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_ES_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_1) return; + glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); + glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); + glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); + glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); + glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); + glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_ES_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_2) return; + glad_glBlendBarrier = (PFNGLBLENDBARRIERPROC) load(userptr, "glBlendBarrier"); + glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load(userptr, "glBlendEquationSeparatei"); + glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load(userptr, "glBlendEquationi"); + glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load(userptr, "glBlendFuncSeparatei"); + glad_glBlendFunci = (PFNGLBLENDFUNCIPROC) load(userptr, "glBlendFunci"); + glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData"); + glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); + glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); + glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); + glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); + glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus"); + glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); + glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv"); + glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv"); + glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load(userptr, "glMinSampleShading"); + glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); + glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); + glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri"); + glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); + glad_glPrimitiveBoundingBox = (PFNGLPRIMITIVEBOUNDINGBOXPROC) load(userptr, "glPrimitiveBoundingBox"); + glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); + glad_glReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample"); +} +static void glad_gl_load_GL_3DFX_tbuffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_3DFX_tbuffer) return; + glad_glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC) load(userptr, "glTbufferMask3DFX"); +} +static void glad_gl_load_GL_AMD_debug_output( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_debug_output) return; + glad_glDebugMessageCallbackAMD = (PFNGLDEBUGMESSAGECALLBACKAMDPROC) load(userptr, "glDebugMessageCallbackAMD"); + glad_glDebugMessageEnableAMD = (PFNGLDEBUGMESSAGEENABLEAMDPROC) load(userptr, "glDebugMessageEnableAMD"); + glad_glDebugMessageInsertAMD = (PFNGLDEBUGMESSAGEINSERTAMDPROC) load(userptr, "glDebugMessageInsertAMD"); + glad_glGetDebugMessageLogAMD = (PFNGLGETDEBUGMESSAGELOGAMDPROC) load(userptr, "glGetDebugMessageLogAMD"); +} +static void glad_gl_load_GL_AMD_draw_buffers_blend( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_draw_buffers_blend) return; + glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC) load(userptr, "glBlendEquationIndexedAMD"); + glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) load(userptr, "glBlendEquationSeparateIndexedAMD"); + glad_glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC) load(userptr, "glBlendFuncIndexedAMD"); + glad_glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) load(userptr, "glBlendFuncSeparateIndexedAMD"); +} +static void glad_gl_load_GL_AMD_framebuffer_multisample_advanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_framebuffer_multisample_advanced) return; + glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) load(userptr, "glNamedRenderbufferStorageMultisampleAdvancedAMD"); + glad_glRenderbufferStorageMultisampleAdvancedAMD = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) load(userptr, "glRenderbufferStorageMultisampleAdvancedAMD"); +} +static void glad_gl_load_GL_AMD_framebuffer_sample_positions( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_framebuffer_sample_positions) return; + glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) load(userptr, "glFramebufferSamplePositionsfvAMD"); + glad_glGetFramebufferParameterfvAMD = (PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) load(userptr, "glGetFramebufferParameterfvAMD"); + glad_glGetNamedFramebufferParameterfvAMD = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) load(userptr, "glGetNamedFramebufferParameterfvAMD"); + glad_glNamedFramebufferSamplePositionsfvAMD = (PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) load(userptr, "glNamedFramebufferSamplePositionsfvAMD"); +} +static void glad_gl_load_GL_AMD_gpu_shader_int64( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_gpu_shader_int64) return; + glad_glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC) load(userptr, "glGetUniformi64vNV"); + glad_glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC) load(userptr, "glGetUniformui64vNV"); + glad_glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC) load(userptr, "glProgramUniform1i64NV"); + glad_glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC) load(userptr, "glProgramUniform1i64vNV"); + glad_glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC) load(userptr, "glProgramUniform1ui64NV"); + glad_glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC) load(userptr, "glProgramUniform1ui64vNV"); + glad_glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC) load(userptr, "glProgramUniform2i64NV"); + glad_glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC) load(userptr, "glProgramUniform2i64vNV"); + glad_glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC) load(userptr, "glProgramUniform2ui64NV"); + glad_glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC) load(userptr, "glProgramUniform2ui64vNV"); + glad_glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC) load(userptr, "glProgramUniform3i64NV"); + glad_glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC) load(userptr, "glProgramUniform3i64vNV"); + glad_glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC) load(userptr, "glProgramUniform3ui64NV"); + glad_glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC) load(userptr, "glProgramUniform3ui64vNV"); + glad_glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC) load(userptr, "glProgramUniform4i64NV"); + glad_glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC) load(userptr, "glProgramUniform4i64vNV"); + glad_glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC) load(userptr, "glProgramUniform4ui64NV"); + glad_glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC) load(userptr, "glProgramUniform4ui64vNV"); + glad_glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC) load(userptr, "glUniform1i64NV"); + glad_glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC) load(userptr, "glUniform1i64vNV"); + glad_glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC) load(userptr, "glUniform1ui64NV"); + glad_glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC) load(userptr, "glUniform1ui64vNV"); + glad_glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC) load(userptr, "glUniform2i64NV"); + glad_glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC) load(userptr, "glUniform2i64vNV"); + glad_glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC) load(userptr, "glUniform2ui64NV"); + glad_glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC) load(userptr, "glUniform2ui64vNV"); + glad_glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC) load(userptr, "glUniform3i64NV"); + glad_glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC) load(userptr, "glUniform3i64vNV"); + glad_glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC) load(userptr, "glUniform3ui64NV"); + glad_glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC) load(userptr, "glUniform3ui64vNV"); + glad_glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC) load(userptr, "glUniform4i64NV"); + glad_glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC) load(userptr, "glUniform4i64vNV"); + glad_glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC) load(userptr, "glUniform4ui64NV"); + glad_glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC) load(userptr, "glUniform4ui64vNV"); +} +static void glad_gl_load_GL_AMD_interleaved_elements( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_interleaved_elements) return; + glad_glVertexAttribParameteriAMD = (PFNGLVERTEXATTRIBPARAMETERIAMDPROC) load(userptr, "glVertexAttribParameteriAMD"); +} +static void glad_gl_load_GL_AMD_multi_draw_indirect( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_multi_draw_indirect) return; + glad_glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) load(userptr, "glMultiDrawArraysIndirectAMD"); + glad_glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) load(userptr, "glMultiDrawElementsIndirectAMD"); +} +static void glad_gl_load_GL_AMD_name_gen_delete( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_name_gen_delete) return; + glad_glDeleteNamesAMD = (PFNGLDELETENAMESAMDPROC) load(userptr, "glDeleteNamesAMD"); + glad_glGenNamesAMD = (PFNGLGENNAMESAMDPROC) load(userptr, "glGenNamesAMD"); + glad_glIsNameAMD = (PFNGLISNAMEAMDPROC) load(userptr, "glIsNameAMD"); +} +static void glad_gl_load_GL_AMD_occlusion_query_event( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_occlusion_query_event) return; + glad_glQueryObjectParameteruiAMD = (PFNGLQUERYOBJECTPARAMETERUIAMDPROC) load(userptr, "glQueryObjectParameteruiAMD"); +} +static void glad_gl_load_GL_AMD_performance_monitor( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_performance_monitor) return; + glad_glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC) load(userptr, "glBeginPerfMonitorAMD"); + glad_glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC) load(userptr, "glDeletePerfMonitorsAMD"); + glad_glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC) load(userptr, "glEndPerfMonitorAMD"); + glad_glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC) load(userptr, "glGenPerfMonitorsAMD"); + glad_glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) load(userptr, "glGetPerfMonitorCounterDataAMD"); + glad_glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) load(userptr, "glGetPerfMonitorCounterInfoAMD"); + glad_glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) load(userptr, "glGetPerfMonitorCounterStringAMD"); + glad_glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC) load(userptr, "glGetPerfMonitorCountersAMD"); + glad_glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) load(userptr, "glGetPerfMonitorGroupStringAMD"); + glad_glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC) load(userptr, "glGetPerfMonitorGroupsAMD"); + glad_glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) load(userptr, "glSelectPerfMonitorCountersAMD"); +} +static void glad_gl_load_GL_AMD_sample_positions( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_sample_positions) return; + glad_glSetMultisamplefvAMD = (PFNGLSETMULTISAMPLEFVAMDPROC) load(userptr, "glSetMultisamplefvAMD"); +} +static void glad_gl_load_GL_AMD_sparse_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_sparse_texture) return; + glad_glTexStorageSparseAMD = (PFNGLTEXSTORAGESPARSEAMDPROC) load(userptr, "glTexStorageSparseAMD"); + glad_glTextureStorageSparseAMD = (PFNGLTEXTURESTORAGESPARSEAMDPROC) load(userptr, "glTextureStorageSparseAMD"); +} +static void glad_gl_load_GL_AMD_stencil_operation_extended( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_stencil_operation_extended) return; + glad_glStencilOpValueAMD = (PFNGLSTENCILOPVALUEAMDPROC) load(userptr, "glStencilOpValueAMD"); +} +static void glad_gl_load_GL_AMD_vertex_shader_tessellator( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_AMD_vertex_shader_tessellator) return; + glad_glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC) load(userptr, "glTessellationFactorAMD"); + glad_glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC) load(userptr, "glTessellationModeAMD"); +} +static void glad_gl_load_GL_APPLE_element_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_element_array) return; + glad_glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC) load(userptr, "glDrawElementArrayAPPLE"); + glad_glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) load(userptr, "glDrawRangeElementArrayAPPLE"); + glad_glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC) load(userptr, "glElementPointerAPPLE"); + glad_glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) load(userptr, "glMultiDrawElementArrayAPPLE"); + glad_glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) load(userptr, "glMultiDrawRangeElementArrayAPPLE"); +} +static void glad_gl_load_GL_APPLE_fence( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_fence) return; + glad_glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC) load(userptr, "glDeleteFencesAPPLE"); + glad_glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC) load(userptr, "glFinishFenceAPPLE"); + glad_glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC) load(userptr, "glFinishObjectAPPLE"); + glad_glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC) load(userptr, "glGenFencesAPPLE"); + glad_glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC) load(userptr, "glIsFenceAPPLE"); + glad_glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC) load(userptr, "glSetFenceAPPLE"); + glad_glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC) load(userptr, "glTestFenceAPPLE"); + glad_glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC) load(userptr, "glTestObjectAPPLE"); +} +static void glad_gl_load_GL_APPLE_flush_buffer_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_flush_buffer_range) return; + glad_glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC) load(userptr, "glBufferParameteriAPPLE"); + glad_glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) load(userptr, "glFlushMappedBufferRangeAPPLE"); +} +static void glad_gl_load_GL_APPLE_object_purgeable( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_object_purgeable) return; + glad_glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC) load(userptr, "glGetObjectParameterivAPPLE"); + glad_glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC) load(userptr, "glObjectPurgeableAPPLE"); + glad_glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC) load(userptr, "glObjectUnpurgeableAPPLE"); +} +static void glad_gl_load_GL_APPLE_texture_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_texture_range) return; + glad_glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) load(userptr, "glGetTexParameterPointervAPPLE"); + glad_glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC) load(userptr, "glTextureRangeAPPLE"); +} +static void glad_gl_load_GL_APPLE_vertex_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_vertex_array_object) return; + glad_glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC) load(userptr, "glBindVertexArrayAPPLE"); + glad_glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC) load(userptr, "glDeleteVertexArraysAPPLE"); + glad_glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC) load(userptr, "glGenVertexArraysAPPLE"); + glad_glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC) load(userptr, "glIsVertexArrayAPPLE"); +} +static void glad_gl_load_GL_APPLE_vertex_array_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_vertex_array_range) return; + glad_glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) load(userptr, "glFlushVertexArrayRangeAPPLE"); + glad_glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) load(userptr, "glVertexArrayParameteriAPPLE"); + glad_glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC) load(userptr, "glVertexArrayRangeAPPLE"); +} +static void glad_gl_load_GL_APPLE_vertex_program_evaluators( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_vertex_program_evaluators) return; + glad_glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC) load(userptr, "glDisableVertexAttribAPPLE"); + glad_glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC) load(userptr, "glEnableVertexAttribAPPLE"); + glad_glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) load(userptr, "glIsVertexAttribEnabledAPPLE"); + glad_glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC) load(userptr, "glMapVertexAttrib1dAPPLE"); + glad_glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC) load(userptr, "glMapVertexAttrib1fAPPLE"); + glad_glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC) load(userptr, "glMapVertexAttrib2dAPPLE"); + glad_glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC) load(userptr, "glMapVertexAttrib2fAPPLE"); +} +static void glad_gl_load_GL_ARB_ES2_compatibility( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_ES2_compatibility) return; + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); +} +static void glad_gl_load_GL_ARB_ES3_1_compatibility( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_ES3_1_compatibility) return; + glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); +} +static void glad_gl_load_GL_ARB_ES3_2_compatibility( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_ES3_2_compatibility) return; + glad_glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC) load(userptr, "glPrimitiveBoundingBoxARB"); +} +static void glad_gl_load_GL_ARB_base_instance( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_base_instance) return; + glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawArraysInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstance"); +} +static void glad_gl_load_GL_ARB_bindless_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_bindless_texture) return; + glad_glGetImageHandleARB = (PFNGLGETIMAGEHANDLEARBPROC) load(userptr, "glGetImageHandleARB"); + glad_glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC) load(userptr, "glGetTextureHandleARB"); + glad_glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC) load(userptr, "glGetTextureSamplerHandleARB"); + glad_glGetVertexAttribLui64vARB = (PFNGLGETVERTEXATTRIBLUI64VARBPROC) load(userptr, "glGetVertexAttribLui64vARB"); + glad_glIsImageHandleResidentARB = (PFNGLISIMAGEHANDLERESIDENTARBPROC) load(userptr, "glIsImageHandleResidentARB"); + glad_glIsTextureHandleResidentARB = (PFNGLISTEXTUREHANDLERESIDENTARBPROC) load(userptr, "glIsTextureHandleResidentARB"); + glad_glMakeImageHandleNonResidentARB = (PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) load(userptr, "glMakeImageHandleNonResidentARB"); + glad_glMakeImageHandleResidentARB = (PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) load(userptr, "glMakeImageHandleResidentARB"); + glad_glMakeTextureHandleNonResidentARB = (PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) load(userptr, "glMakeTextureHandleNonResidentARB"); + glad_glMakeTextureHandleResidentARB = (PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) load(userptr, "glMakeTextureHandleResidentARB"); + glad_glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) load(userptr, "glProgramUniformHandleui64ARB"); + glad_glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) load(userptr, "glProgramUniformHandleui64vARB"); + glad_glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC) load(userptr, "glUniformHandleui64ARB"); + glad_glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC) load(userptr, "glUniformHandleui64vARB"); + glad_glVertexAttribL1ui64ARB = (PFNGLVERTEXATTRIBL1UI64ARBPROC) load(userptr, "glVertexAttribL1ui64ARB"); + glad_glVertexAttribL1ui64vARB = (PFNGLVERTEXATTRIBL1UI64VARBPROC) load(userptr, "glVertexAttribL1ui64vARB"); +} +static void glad_gl_load_GL_ARB_blend_func_extended( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_blend_func_extended) return; + glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); +} +static void glad_gl_load_GL_ARB_buffer_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_buffer_storage) return; + glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load(userptr, "glBufferStorage"); +} +static void glad_gl_load_GL_ARB_cl_event( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_cl_event) return; + glad_glCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC) load(userptr, "glCreateSyncFromCLeventARB"); +} +static void glad_gl_load_GL_ARB_clear_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_clear_buffer_object) return; + glad_glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load(userptr, "glClearBufferData"); + glad_glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load(userptr, "glClearBufferSubData"); +} +static void glad_gl_load_GL_ARB_clear_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_clear_texture) return; + glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load(userptr, "glClearTexImage"); + glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load(userptr, "glClearTexSubImage"); +} +static void glad_gl_load_GL_ARB_clip_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_clip_control) return; + glad_glClipControl = (PFNGLCLIPCONTROLPROC) load(userptr, "glClipControl"); +} +static void glad_gl_load_GL_ARB_color_buffer_float( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_color_buffer_float) return; + glad_glClampColorARB = (PFNGLCLAMPCOLORARBPROC) load(userptr, "glClampColorARB"); +} +static void glad_gl_load_GL_ARB_compute_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_compute_shader) return; + glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); +} +static void glad_gl_load_GL_ARB_compute_variable_group_size( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_compute_variable_group_size) return; + glad_glDispatchComputeGroupSizeARB = (PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) load(userptr, "glDispatchComputeGroupSizeARB"); +} +static void glad_gl_load_GL_ARB_copy_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_copy_buffer) return; + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); +} +static void glad_gl_load_GL_ARB_copy_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_copy_image) return; + glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData"); +} +static void glad_gl_load_GL_ARB_debug_output( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_debug_output) return; + glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) load(userptr, "glDebugMessageCallbackARB"); + glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) load(userptr, "glDebugMessageControlARB"); + glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) load(userptr, "glDebugMessageInsertARB"); + glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) load(userptr, "glGetDebugMessageLogARB"); +} +static void glad_gl_load_GL_ARB_direct_state_access( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_direct_state_access) return; + glad_glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit"); + glad_glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer"); + glad_glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus"); + glad_glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData"); + glad_glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData"); + glad_glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi"); + glad_glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv"); + glad_glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv"); + glad_glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv"); + glad_glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D"); + glad_glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D"); + glad_glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D"); + glad_glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData"); + glad_glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D"); + glad_glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D"); + glad_glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D"); + glad_glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers"); + glad_glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers"); + glad_glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines"); + glad_glCreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries"); + glad_glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers"); + glad_glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers"); + glad_glCreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures"); + glad_glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks"); + glad_glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays"); + glad_glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib"); + glad_glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib"); + glad_glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange"); + glad_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap"); + glad_glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage"); + glad_glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v"); + glad_glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv"); + glad_glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv"); + glad_glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData"); + glad_glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv"); + glad_glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv"); + glad_glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv"); + glad_glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v"); + glad_glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv"); + glad_glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v"); + glad_glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv"); + glad_glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage"); + glad_glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv"); + glad_glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv"); + glad_glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv"); + glad_glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv"); + glad_glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv"); + glad_glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv"); + glad_glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v"); + glad_glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v"); + glad_glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv"); + glad_glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv"); + glad_glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv"); + glad_glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv"); + glad_glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData"); + glad_glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData"); + glad_glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer"); + glad_glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange"); + glad_glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData"); + glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage"); + glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData"); + glad_glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer"); + glad_glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers"); + glad_glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri"); + glad_glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer"); + glad_glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer"); + glad_glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture"); + glad_glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer"); + glad_glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage"); + glad_glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample"); + glad_glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer"); + glad_glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange"); + glad_glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv"); + glad_glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv"); + glad_glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf"); + glad_glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv"); + glad_glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri"); + glad_glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv"); + glad_glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D"); + glad_glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D"); + glad_glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample"); + glad_glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D"); + glad_glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample"); + glad_glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D"); + glad_glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D"); + glad_glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D"); + glad_glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase"); + glad_glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange"); + glad_glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer"); + glad_glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding"); + glad_glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat"); + glad_glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat"); + glad_glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat"); + glad_glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor"); + glad_glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer"); + glad_glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer"); + glad_glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers"); +} +static void glad_gl_load_GL_ARB_draw_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_draw_buffers) return; + glad_glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) load(userptr, "glDrawBuffersARB"); +} +static void glad_gl_load_GL_ARB_draw_buffers_blend( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_draw_buffers_blend) return; + glad_glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC) load(userptr, "glBlendEquationSeparateiARB"); + glad_glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC) load(userptr, "glBlendEquationiARB"); + glad_glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC) load(userptr, "glBlendFuncSeparateiARB"); + glad_glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC) load(userptr, "glBlendFunciARB"); +} +static void glad_gl_load_GL_ARB_draw_elements_base_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_draw_elements_base_vertex) return; + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); +} +static void glad_gl_load_GL_ARB_draw_indirect( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_draw_indirect) return; + glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); +} +static void glad_gl_load_GL_ARB_draw_instanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_draw_instanced) return; + glad_glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC) load(userptr, "glDrawArraysInstancedARB"); + glad_glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC) load(userptr, "glDrawElementsInstancedARB"); +} +static void glad_gl_load_GL_ARB_fragment_program( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_fragment_program) return; + glad_glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) load(userptr, "glBindProgramARB"); + glad_glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) load(userptr, "glDeleteProgramsARB"); + glad_glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) load(userptr, "glGenProgramsARB"); + glad_glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) load(userptr, "glGetProgramEnvParameterdvARB"); + glad_glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) load(userptr, "glGetProgramEnvParameterfvARB"); + glad_glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) load(userptr, "glGetProgramLocalParameterdvARB"); + glad_glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) load(userptr, "glGetProgramLocalParameterfvARB"); + glad_glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) load(userptr, "glGetProgramStringARB"); + glad_glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) load(userptr, "glGetProgramivARB"); + glad_glIsProgramARB = (PFNGLISPROGRAMARBPROC) load(userptr, "glIsProgramARB"); + glad_glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) load(userptr, "glProgramEnvParameter4dARB"); + glad_glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) load(userptr, "glProgramEnvParameter4dvARB"); + glad_glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) load(userptr, "glProgramEnvParameter4fARB"); + glad_glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) load(userptr, "glProgramEnvParameter4fvARB"); + glad_glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) load(userptr, "glProgramLocalParameter4dARB"); + glad_glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) load(userptr, "glProgramLocalParameter4dvARB"); + glad_glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) load(userptr, "glProgramLocalParameter4fARB"); + glad_glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) load(userptr, "glProgramLocalParameter4fvARB"); + glad_glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) load(userptr, "glProgramStringARB"); +} +static void glad_gl_load_GL_ARB_framebuffer_no_attachments( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_framebuffer_no_attachments) return; + glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); +} +static void glad_gl_load_GL_ARB_framebuffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_framebuffer_object) return; + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); +} +static void glad_gl_load_GL_ARB_geometry_shader4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_geometry_shader4) return; + glad_glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC) load(userptr, "glFramebufferTextureARB"); + glad_glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) load(userptr, "glFramebufferTextureFaceARB"); + glad_glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) load(userptr, "glFramebufferTextureLayerARB"); + glad_glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC) load(userptr, "glProgramParameteriARB"); +} +static void glad_gl_load_GL_ARB_get_program_binary( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_get_program_binary) return; + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); +} +static void glad_gl_load_GL_ARB_get_texture_sub_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_get_texture_sub_image) return; + glad_glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load(userptr, "glGetCompressedTextureSubImage"); + glad_glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load(userptr, "glGetTextureSubImage"); +} +static void glad_gl_load_GL_ARB_gl_spirv( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_gl_spirv) return; + glad_glSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC) load(userptr, "glSpecializeShaderARB"); +} +static void glad_gl_load_GL_ARB_gpu_shader_fp64( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_gpu_shader_fp64) return; + glad_glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load(userptr, "glGetUniformdv"); + glad_glUniform1d = (PFNGLUNIFORM1DPROC) load(userptr, "glUniform1d"); + glad_glUniform1dv = (PFNGLUNIFORM1DVPROC) load(userptr, "glUniform1dv"); + glad_glUniform2d = (PFNGLUNIFORM2DPROC) load(userptr, "glUniform2d"); + glad_glUniform2dv = (PFNGLUNIFORM2DVPROC) load(userptr, "glUniform2dv"); + glad_glUniform3d = (PFNGLUNIFORM3DPROC) load(userptr, "glUniform3d"); + glad_glUniform3dv = (PFNGLUNIFORM3DVPROC) load(userptr, "glUniform3dv"); + glad_glUniform4d = (PFNGLUNIFORM4DPROC) load(userptr, "glUniform4d"); + glad_glUniform4dv = (PFNGLUNIFORM4DVPROC) load(userptr, "glUniform4dv"); + glad_glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load(userptr, "glUniformMatrix2dv"); + glad_glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load(userptr, "glUniformMatrix2x3dv"); + glad_glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load(userptr, "glUniformMatrix2x4dv"); + glad_glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load(userptr, "glUniformMatrix3dv"); + glad_glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load(userptr, "glUniformMatrix3x2dv"); + glad_glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load(userptr, "glUniformMatrix3x4dv"); + glad_glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load(userptr, "glUniformMatrix4dv"); + glad_glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load(userptr, "glUniformMatrix4x2dv"); + glad_glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load(userptr, "glUniformMatrix4x3dv"); +} +static void glad_gl_load_GL_ARB_gpu_shader_int64( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_gpu_shader_int64) return; + glad_glGetUniformi64vARB = (PFNGLGETUNIFORMI64VARBPROC) load(userptr, "glGetUniformi64vARB"); + glad_glGetUniformui64vARB = (PFNGLGETUNIFORMUI64VARBPROC) load(userptr, "glGetUniformui64vARB"); + glad_glGetnUniformi64vARB = (PFNGLGETNUNIFORMI64VARBPROC) load(userptr, "glGetnUniformi64vARB"); + glad_glGetnUniformui64vARB = (PFNGLGETNUNIFORMUI64VARBPROC) load(userptr, "glGetnUniformui64vARB"); + glad_glProgramUniform1i64ARB = (PFNGLPROGRAMUNIFORM1I64ARBPROC) load(userptr, "glProgramUniform1i64ARB"); + glad_glProgramUniform1i64vARB = (PFNGLPROGRAMUNIFORM1I64VARBPROC) load(userptr, "glProgramUniform1i64vARB"); + glad_glProgramUniform1ui64ARB = (PFNGLPROGRAMUNIFORM1UI64ARBPROC) load(userptr, "glProgramUniform1ui64ARB"); + glad_glProgramUniform1ui64vARB = (PFNGLPROGRAMUNIFORM1UI64VARBPROC) load(userptr, "glProgramUniform1ui64vARB"); + glad_glProgramUniform2i64ARB = (PFNGLPROGRAMUNIFORM2I64ARBPROC) load(userptr, "glProgramUniform2i64ARB"); + glad_glProgramUniform2i64vARB = (PFNGLPROGRAMUNIFORM2I64VARBPROC) load(userptr, "glProgramUniform2i64vARB"); + glad_glProgramUniform2ui64ARB = (PFNGLPROGRAMUNIFORM2UI64ARBPROC) load(userptr, "glProgramUniform2ui64ARB"); + glad_glProgramUniform2ui64vARB = (PFNGLPROGRAMUNIFORM2UI64VARBPROC) load(userptr, "glProgramUniform2ui64vARB"); + glad_glProgramUniform3i64ARB = (PFNGLPROGRAMUNIFORM3I64ARBPROC) load(userptr, "glProgramUniform3i64ARB"); + glad_glProgramUniform3i64vARB = (PFNGLPROGRAMUNIFORM3I64VARBPROC) load(userptr, "glProgramUniform3i64vARB"); + glad_glProgramUniform3ui64ARB = (PFNGLPROGRAMUNIFORM3UI64ARBPROC) load(userptr, "glProgramUniform3ui64ARB"); + glad_glProgramUniform3ui64vARB = (PFNGLPROGRAMUNIFORM3UI64VARBPROC) load(userptr, "glProgramUniform3ui64vARB"); + glad_glProgramUniform4i64ARB = (PFNGLPROGRAMUNIFORM4I64ARBPROC) load(userptr, "glProgramUniform4i64ARB"); + glad_glProgramUniform4i64vARB = (PFNGLPROGRAMUNIFORM4I64VARBPROC) load(userptr, "glProgramUniform4i64vARB"); + glad_glProgramUniform4ui64ARB = (PFNGLPROGRAMUNIFORM4UI64ARBPROC) load(userptr, "glProgramUniform4ui64ARB"); + glad_glProgramUniform4ui64vARB = (PFNGLPROGRAMUNIFORM4UI64VARBPROC) load(userptr, "glProgramUniform4ui64vARB"); + glad_glUniform1i64ARB = (PFNGLUNIFORM1I64ARBPROC) load(userptr, "glUniform1i64ARB"); + glad_glUniform1i64vARB = (PFNGLUNIFORM1I64VARBPROC) load(userptr, "glUniform1i64vARB"); + glad_glUniform1ui64ARB = (PFNGLUNIFORM1UI64ARBPROC) load(userptr, "glUniform1ui64ARB"); + glad_glUniform1ui64vARB = (PFNGLUNIFORM1UI64VARBPROC) load(userptr, "glUniform1ui64vARB"); + glad_glUniform2i64ARB = (PFNGLUNIFORM2I64ARBPROC) load(userptr, "glUniform2i64ARB"); + glad_glUniform2i64vARB = (PFNGLUNIFORM2I64VARBPROC) load(userptr, "glUniform2i64vARB"); + glad_glUniform2ui64ARB = (PFNGLUNIFORM2UI64ARBPROC) load(userptr, "glUniform2ui64ARB"); + glad_glUniform2ui64vARB = (PFNGLUNIFORM2UI64VARBPROC) load(userptr, "glUniform2ui64vARB"); + glad_glUniform3i64ARB = (PFNGLUNIFORM3I64ARBPROC) load(userptr, "glUniform3i64ARB"); + glad_glUniform3i64vARB = (PFNGLUNIFORM3I64VARBPROC) load(userptr, "glUniform3i64vARB"); + glad_glUniform3ui64ARB = (PFNGLUNIFORM3UI64ARBPROC) load(userptr, "glUniform3ui64ARB"); + glad_glUniform3ui64vARB = (PFNGLUNIFORM3UI64VARBPROC) load(userptr, "glUniform3ui64vARB"); + glad_glUniform4i64ARB = (PFNGLUNIFORM4I64ARBPROC) load(userptr, "glUniform4i64ARB"); + glad_glUniform4i64vARB = (PFNGLUNIFORM4I64VARBPROC) load(userptr, "glUniform4i64vARB"); + glad_glUniform4ui64ARB = (PFNGLUNIFORM4UI64ARBPROC) load(userptr, "glUniform4ui64ARB"); + glad_glUniform4ui64vARB = (PFNGLUNIFORM4UI64VARBPROC) load(userptr, "glUniform4ui64vARB"); +} +static void glad_gl_load_GL_ARB_imaging( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_imaging) return; + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glColorSubTable = (PFNGLCOLORSUBTABLEPROC) load(userptr, "glColorSubTable"); + glad_glColorTable = (PFNGLCOLORTABLEPROC) load(userptr, "glColorTable"); + glad_glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC) load(userptr, "glColorTableParameterfv"); + glad_glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC) load(userptr, "glColorTableParameteriv"); + glad_glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC) load(userptr, "glConvolutionFilter1D"); + glad_glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC) load(userptr, "glConvolutionFilter2D"); + glad_glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC) load(userptr, "glConvolutionParameterf"); + glad_glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC) load(userptr, "glConvolutionParameterfv"); + glad_glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC) load(userptr, "glConvolutionParameteri"); + glad_glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC) load(userptr, "glConvolutionParameteriv"); + glad_glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC) load(userptr, "glCopyColorSubTable"); + glad_glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC) load(userptr, "glCopyColorTable"); + glad_glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC) load(userptr, "glCopyConvolutionFilter1D"); + glad_glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC) load(userptr, "glCopyConvolutionFilter2D"); + glad_glGetColorTable = (PFNGLGETCOLORTABLEPROC) load(userptr, "glGetColorTable"); + glad_glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC) load(userptr, "glGetColorTableParameterfv"); + glad_glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC) load(userptr, "glGetColorTableParameteriv"); + glad_glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC) load(userptr, "glGetConvolutionFilter"); + glad_glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC) load(userptr, "glGetConvolutionParameterfv"); + glad_glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC) load(userptr, "glGetConvolutionParameteriv"); + glad_glGetHistogram = (PFNGLGETHISTOGRAMPROC) load(userptr, "glGetHistogram"); + glad_glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC) load(userptr, "glGetHistogramParameterfv"); + glad_glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC) load(userptr, "glGetHistogramParameteriv"); + glad_glGetMinmax = (PFNGLGETMINMAXPROC) load(userptr, "glGetMinmax"); + glad_glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC) load(userptr, "glGetMinmaxParameterfv"); + glad_glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC) load(userptr, "glGetMinmaxParameteriv"); + glad_glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC) load(userptr, "glGetSeparableFilter"); + glad_glHistogram = (PFNGLHISTOGRAMPROC) load(userptr, "glHistogram"); + glad_glMinmax = (PFNGLMINMAXPROC) load(userptr, "glMinmax"); + glad_glResetHistogram = (PFNGLRESETHISTOGRAMPROC) load(userptr, "glResetHistogram"); + glad_glResetMinmax = (PFNGLRESETMINMAXPROC) load(userptr, "glResetMinmax"); + glad_glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC) load(userptr, "glSeparableFilter2D"); +} +static void glad_gl_load_GL_ARB_indirect_parameters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_indirect_parameters) return; + glad_glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) load(userptr, "glMultiDrawArraysIndirectCountARB"); + glad_glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) load(userptr, "glMultiDrawElementsIndirectCountARB"); +} +static void glad_gl_load_GL_ARB_instanced_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_instanced_arrays) return; + glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC) load(userptr, "glVertexAttribDivisorARB"); +} +static void glad_gl_load_GL_ARB_internalformat_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_internalformat_query) return; + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); +} +static void glad_gl_load_GL_ARB_internalformat_query2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_internalformat_query2) return; + glad_glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load(userptr, "glGetInternalformati64v"); +} +static void glad_gl_load_GL_ARB_invalidate_subdata( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_invalidate_subdata) return; + glad_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData"); + glad_glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage"); + glad_glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage"); +} +static void glad_gl_load_GL_ARB_map_buffer_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_map_buffer_range) return; + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); +} +static void glad_gl_load_GL_ARB_matrix_palette( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_matrix_palette) return; + glad_glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC) load(userptr, "glCurrentPaletteMatrixARB"); + glad_glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC) load(userptr, "glMatrixIndexPointerARB"); + glad_glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC) load(userptr, "glMatrixIndexubvARB"); + glad_glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC) load(userptr, "glMatrixIndexuivARB"); + glad_glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC) load(userptr, "glMatrixIndexusvARB"); +} +static void glad_gl_load_GL_ARB_multi_bind( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_multi_bind) return; + glad_glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load(userptr, "glBindBuffersBase"); + glad_glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load(userptr, "glBindBuffersRange"); + glad_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load(userptr, "glBindImageTextures"); + glad_glBindSamplers = (PFNGLBINDSAMPLERSPROC) load(userptr, "glBindSamplers"); + glad_glBindTextures = (PFNGLBINDTEXTURESPROC) load(userptr, "glBindTextures"); + glad_glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load(userptr, "glBindVertexBuffers"); +} +static void glad_gl_load_GL_ARB_multi_draw_indirect( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_multi_draw_indirect) return; + glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load(userptr, "glMultiDrawArraysIndirect"); + glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load(userptr, "glMultiDrawElementsIndirect"); +} +static void glad_gl_load_GL_ARB_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_multisample) return; + glad_glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC) load(userptr, "glSampleCoverageARB"); +} +static void glad_gl_load_GL_ARB_multitexture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_multitexture) return; + glad_glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) load(userptr, "glActiveTextureARB"); + glad_glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) load(userptr, "glClientActiveTextureARB"); + glad_glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC) load(userptr, "glMultiTexCoord1dARB"); + glad_glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC) load(userptr, "glMultiTexCoord1dvARB"); + glad_glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) load(userptr, "glMultiTexCoord1fARB"); + glad_glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC) load(userptr, "glMultiTexCoord1fvARB"); + glad_glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC) load(userptr, "glMultiTexCoord1iARB"); + glad_glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC) load(userptr, "glMultiTexCoord1ivARB"); + glad_glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC) load(userptr, "glMultiTexCoord1sARB"); + glad_glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC) load(userptr, "glMultiTexCoord1svARB"); + glad_glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC) load(userptr, "glMultiTexCoord2dARB"); + glad_glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC) load(userptr, "glMultiTexCoord2dvARB"); + glad_glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) load(userptr, "glMultiTexCoord2fARB"); + glad_glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC) load(userptr, "glMultiTexCoord2fvARB"); + glad_glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC) load(userptr, "glMultiTexCoord2iARB"); + glad_glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC) load(userptr, "glMultiTexCoord2ivARB"); + glad_glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC) load(userptr, "glMultiTexCoord2sARB"); + glad_glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC) load(userptr, "glMultiTexCoord2svARB"); + glad_glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC) load(userptr, "glMultiTexCoord3dARB"); + glad_glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC) load(userptr, "glMultiTexCoord3dvARB"); + glad_glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) load(userptr, "glMultiTexCoord3fARB"); + glad_glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC) load(userptr, "glMultiTexCoord3fvARB"); + glad_glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC) load(userptr, "glMultiTexCoord3iARB"); + glad_glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC) load(userptr, "glMultiTexCoord3ivARB"); + glad_glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC) load(userptr, "glMultiTexCoord3sARB"); + glad_glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC) load(userptr, "glMultiTexCoord3svARB"); + glad_glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC) load(userptr, "glMultiTexCoord4dARB"); + glad_glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC) load(userptr, "glMultiTexCoord4dvARB"); + glad_glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) load(userptr, "glMultiTexCoord4fARB"); + glad_glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC) load(userptr, "glMultiTexCoord4fvARB"); + glad_glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC) load(userptr, "glMultiTexCoord4iARB"); + glad_glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC) load(userptr, "glMultiTexCoord4ivARB"); + glad_glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC) load(userptr, "glMultiTexCoord4sARB"); + glad_glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC) load(userptr, "glMultiTexCoord4svARB"); +} +static void glad_gl_load_GL_ARB_occlusion_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_occlusion_query) return; + glad_glBeginQueryARB = (PFNGLBEGINQUERYARBPROC) load(userptr, "glBeginQueryARB"); + glad_glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC) load(userptr, "glDeleteQueriesARB"); + glad_glEndQueryARB = (PFNGLENDQUERYARBPROC) load(userptr, "glEndQueryARB"); + glad_glGenQueriesARB = (PFNGLGENQUERIESARBPROC) load(userptr, "glGenQueriesARB"); + glad_glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC) load(userptr, "glGetQueryObjectivARB"); + glad_glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC) load(userptr, "glGetQueryObjectuivARB"); + glad_glGetQueryivARB = (PFNGLGETQUERYIVARBPROC) load(userptr, "glGetQueryivARB"); + glad_glIsQueryARB = (PFNGLISQUERYARBPROC) load(userptr, "glIsQueryARB"); +} +static void glad_gl_load_GL_ARB_parallel_shader_compile( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_parallel_shader_compile) return; + glad_glMaxShaderCompilerThreadsARB = (PFNGLMAXSHADERCOMPILERTHREADSARBPROC) load(userptr, "glMaxShaderCompilerThreadsARB"); +} +static void glad_gl_load_GL_ARB_point_parameters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_point_parameters) return; + glad_glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) load(userptr, "glPointParameterfARB"); + glad_glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) load(userptr, "glPointParameterfvARB"); +} +static void glad_gl_load_GL_ARB_polygon_offset_clamp( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_polygon_offset_clamp) return; + glad_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load(userptr, "glPolygonOffsetClamp"); +} +static void glad_gl_load_GL_ARB_program_interface_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_program_interface_query) return; + glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load(userptr, "glGetProgramResourceLocationIndex"); + glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); +} +static void glad_gl_load_GL_ARB_provoking_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_provoking_vertex) return; + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); +} +static void glad_gl_load_GL_ARB_robustness( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_robustness) return; + glad_glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC) load(userptr, "glGetGraphicsResetStatusARB"); + glad_glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC) load(userptr, "glGetnColorTableARB"); + glad_glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) load(userptr, "glGetnCompressedTexImageARB"); + glad_glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC) load(userptr, "glGetnConvolutionFilterARB"); + glad_glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC) load(userptr, "glGetnHistogramARB"); + glad_glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC) load(userptr, "glGetnMapdvARB"); + glad_glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC) load(userptr, "glGetnMapfvARB"); + glad_glGetnMapivARB = (PFNGLGETNMAPIVARBPROC) load(userptr, "glGetnMapivARB"); + glad_glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC) load(userptr, "glGetnMinmaxARB"); + glad_glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC) load(userptr, "glGetnPixelMapfvARB"); + glad_glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC) load(userptr, "glGetnPixelMapuivARB"); + glad_glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC) load(userptr, "glGetnPixelMapusvARB"); + glad_glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC) load(userptr, "glGetnPolygonStippleARB"); + glad_glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC) load(userptr, "glGetnSeparableFilterARB"); + glad_glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC) load(userptr, "glGetnTexImageARB"); + glad_glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC) load(userptr, "glGetnUniformdvARB"); + glad_glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC) load(userptr, "glGetnUniformfvARB"); + glad_glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC) load(userptr, "glGetnUniformivARB"); + glad_glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC) load(userptr, "glGetnUniformuivARB"); + glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC) load(userptr, "glReadnPixelsARB"); +} +static void glad_gl_load_GL_ARB_sample_locations( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sample_locations) return; + glad_glEvaluateDepthValuesARB = (PFNGLEVALUATEDEPTHVALUESARBPROC) load(userptr, "glEvaluateDepthValuesARB"); + glad_glFramebufferSampleLocationsfvARB = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) load(userptr, "glFramebufferSampleLocationsfvARB"); + glad_glNamedFramebufferSampleLocationsfvARB = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) load(userptr, "glNamedFramebufferSampleLocationsfvARB"); +} +static void glad_gl_load_GL_ARB_sample_shading( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sample_shading) return; + glad_glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC) load(userptr, "glMinSampleShadingARB"); +} +static void glad_gl_load_GL_ARB_sampler_objects( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sampler_objects) return; + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); +} +static void glad_gl_load_GL_ARB_separate_shader_objects( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_separate_shader_objects) return; + glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load(userptr, "glProgramUniform1d"); + glad_glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load(userptr, "glProgramUniform1dv"); + glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + glad_glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load(userptr, "glProgramUniform2d"); + glad_glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load(userptr, "glProgramUniform2dv"); + glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + glad_glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load(userptr, "glProgramUniform3d"); + glad_glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load(userptr, "glProgramUniform3dv"); + glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + glad_glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load(userptr, "glProgramUniform4d"); + glad_glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load(userptr, "glProgramUniform4dv"); + glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + glad_glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load(userptr, "glProgramUniformMatrix2dv"); + glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + glad_glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load(userptr, "glProgramUniformMatrix2x3dv"); + glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + glad_glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load(userptr, "glProgramUniformMatrix2x4dv"); + glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + glad_glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load(userptr, "glProgramUniformMatrix3dv"); + glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + glad_glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load(userptr, "glProgramUniformMatrix3x2dv"); + glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + glad_glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load(userptr, "glProgramUniformMatrix3x4dv"); + glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + glad_glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load(userptr, "glProgramUniformMatrix4dv"); + glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + glad_glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load(userptr, "glProgramUniformMatrix4x2dv"); + glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + glad_glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load(userptr, "glProgramUniformMatrix4x3dv"); + glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); +} +static void glad_gl_load_GL_ARB_shader_atomic_counters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shader_atomic_counters) return; + glad_glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load(userptr, "glGetActiveAtomicCounterBufferiv"); +} +static void glad_gl_load_GL_ARB_shader_image_load_store( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shader_image_load_store) return; + glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); +} +static void glad_gl_load_GL_ARB_shader_objects( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shader_objects) return; + glad_glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) load(userptr, "glAttachObjectARB"); + glad_glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) load(userptr, "glCompileShaderARB"); + glad_glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) load(userptr, "glCreateProgramObjectARB"); + glad_glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) load(userptr, "glCreateShaderObjectARB"); + glad_glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) load(userptr, "glDeleteObjectARB"); + glad_glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) load(userptr, "glDetachObjectARB"); + glad_glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) load(userptr, "glGetActiveUniformARB"); + glad_glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) load(userptr, "glGetAttachedObjectsARB"); + glad_glGetHandleARB = (PFNGLGETHANDLEARBPROC) load(userptr, "glGetHandleARB"); + glad_glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) load(userptr, "glGetInfoLogARB"); + glad_glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) load(userptr, "glGetObjectParameterfvARB"); + glad_glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) load(userptr, "glGetObjectParameterivARB"); + glad_glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) load(userptr, "glGetShaderSourceARB"); + glad_glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) load(userptr, "glGetUniformLocationARB"); + glad_glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) load(userptr, "glGetUniformfvARB"); + glad_glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) load(userptr, "glGetUniformivARB"); + glad_glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) load(userptr, "glLinkProgramARB"); + glad_glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) load(userptr, "glShaderSourceARB"); + glad_glUniform1fARB = (PFNGLUNIFORM1FARBPROC) load(userptr, "glUniform1fARB"); + glad_glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) load(userptr, "glUniform1fvARB"); + glad_glUniform1iARB = (PFNGLUNIFORM1IARBPROC) load(userptr, "glUniform1iARB"); + glad_glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) load(userptr, "glUniform1ivARB"); + glad_glUniform2fARB = (PFNGLUNIFORM2FARBPROC) load(userptr, "glUniform2fARB"); + glad_glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) load(userptr, "glUniform2fvARB"); + glad_glUniform2iARB = (PFNGLUNIFORM2IARBPROC) load(userptr, "glUniform2iARB"); + glad_glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) load(userptr, "glUniform2ivARB"); + glad_glUniform3fARB = (PFNGLUNIFORM3FARBPROC) load(userptr, "glUniform3fARB"); + glad_glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) load(userptr, "glUniform3fvARB"); + glad_glUniform3iARB = (PFNGLUNIFORM3IARBPROC) load(userptr, "glUniform3iARB"); + glad_glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) load(userptr, "glUniform3ivARB"); + glad_glUniform4fARB = (PFNGLUNIFORM4FARBPROC) load(userptr, "glUniform4fARB"); + glad_glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) load(userptr, "glUniform4fvARB"); + glad_glUniform4iARB = (PFNGLUNIFORM4IARBPROC) load(userptr, "glUniform4iARB"); + glad_glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) load(userptr, "glUniform4ivARB"); + glad_glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) load(userptr, "glUniformMatrix2fvARB"); + glad_glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) load(userptr, "glUniformMatrix3fvARB"); + glad_glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) load(userptr, "glUniformMatrix4fvARB"); + glad_glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) load(userptr, "glUseProgramObjectARB"); + glad_glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) load(userptr, "glValidateProgramARB"); +} +static void glad_gl_load_GL_ARB_shader_storage_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shader_storage_buffer_object) return; + glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding"); +} +static void glad_gl_load_GL_ARB_shader_subroutine( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shader_subroutine) return; + glad_glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load(userptr, "glGetActiveSubroutineName"); + glad_glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load(userptr, "glGetActiveSubroutineUniformName"); + glad_glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load(userptr, "glGetActiveSubroutineUniformiv"); + glad_glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load(userptr, "glGetProgramStageiv"); + glad_glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load(userptr, "glGetSubroutineIndex"); + glad_glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load(userptr, "glGetSubroutineUniformLocation"); + glad_glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load(userptr, "glGetUniformSubroutineuiv"); + glad_glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load(userptr, "glUniformSubroutinesuiv"); +} +static void glad_gl_load_GL_ARB_shading_language_include( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_shading_language_include) return; + glad_glCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC) load(userptr, "glCompileShaderIncludeARB"); + glad_glDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC) load(userptr, "glDeleteNamedStringARB"); + glad_glGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC) load(userptr, "glGetNamedStringARB"); + glad_glGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC) load(userptr, "glGetNamedStringivARB"); + glad_glIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC) load(userptr, "glIsNamedStringARB"); + glad_glNamedStringARB = (PFNGLNAMEDSTRINGARBPROC) load(userptr, "glNamedStringARB"); +} +static void glad_gl_load_GL_ARB_sparse_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sparse_buffer) return; + glad_glBufferPageCommitmentARB = (PFNGLBUFFERPAGECOMMITMENTARBPROC) load(userptr, "glBufferPageCommitmentARB"); + glad_glNamedBufferPageCommitmentARB = (PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) load(userptr, "glNamedBufferPageCommitmentARB"); + glad_glNamedBufferPageCommitmentEXT = (PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) load(userptr, "glNamedBufferPageCommitmentEXT"); +} +static void glad_gl_load_GL_ARB_sparse_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sparse_texture) return; + glad_glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC) load(userptr, "glTexPageCommitmentARB"); +} +static void glad_gl_load_GL_ARB_sync( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_sync) return; + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_ARB_tessellation_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_tessellation_shader) return; + glad_glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load(userptr, "glPatchParameterfv"); + glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri"); +} +static void glad_gl_load_GL_ARB_texture_barrier( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_barrier) return; + glad_glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load(userptr, "glTextureBarrier"); +} +static void glad_gl_load_GL_ARB_texture_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_buffer_object) return; + glad_glTexBufferARB = (PFNGLTEXBUFFERARBPROC) load(userptr, "glTexBufferARB"); +} +static void glad_gl_load_GL_ARB_texture_buffer_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_buffer_range) return; + glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange"); +} +static void glad_gl_load_GL_ARB_texture_compression( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_compression) return; + glad_glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) load(userptr, "glCompressedTexImage1DARB"); + glad_glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) load(userptr, "glCompressedTexImage2DARB"); + glad_glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) load(userptr, "glCompressedTexImage3DARB"); + glad_glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) load(userptr, "glCompressedTexSubImage1DARB"); + glad_glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) load(userptr, "glCompressedTexSubImage2DARB"); + glad_glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) load(userptr, "glCompressedTexSubImage3DARB"); + glad_glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) load(userptr, "glGetCompressedTexImageARB"); +} +static void glad_gl_load_GL_ARB_texture_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_multisample) return; + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); +} +static void glad_gl_load_GL_ARB_texture_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_storage) return; + glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load(userptr, "glTexStorage1D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); +} +static void glad_gl_load_GL_ARB_texture_storage_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_storage_multisample) return; + glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample"); +} +static void glad_gl_load_GL_ARB_texture_view( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_texture_view) return; + glad_glTextureView = (PFNGLTEXTUREVIEWPROC) load(userptr, "glTextureView"); +} +static void glad_gl_load_GL_ARB_timer_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_timer_query) return; + glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); +} +static void glad_gl_load_GL_ARB_transform_feedback2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_transform_feedback2) return; + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load(userptr, "glDrawTransformFeedback"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); +} +static void glad_gl_load_GL_ARB_transform_feedback3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_transform_feedback3) return; + glad_glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load(userptr, "glBeginQueryIndexed"); + glad_glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load(userptr, "glDrawTransformFeedbackStream"); + glad_glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load(userptr, "glEndQueryIndexed"); + glad_glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load(userptr, "glGetQueryIndexediv"); +} +static void glad_gl_load_GL_ARB_transform_feedback_instanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_transform_feedback_instanced) return; + glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackInstanced"); + glad_glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackStreamInstanced"); +} +static void glad_gl_load_GL_ARB_transpose_matrix( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_transpose_matrix) return; + glad_glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC) load(userptr, "glLoadTransposeMatrixdARB"); + glad_glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC) load(userptr, "glLoadTransposeMatrixfARB"); + glad_glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC) load(userptr, "glMultTransposeMatrixdARB"); + glad_glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC) load(userptr, "glMultTransposeMatrixfARB"); +} +static void glad_gl_load_GL_ARB_uniform_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_uniform_buffer_object) return; + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +} +static void glad_gl_load_GL_ARB_vertex_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_array_object) return; + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); +} +static void glad_gl_load_GL_ARB_vertex_attrib_64bit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_attrib_64bit) return; + glad_glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load(userptr, "glGetVertexAttribLdv"); + glad_glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load(userptr, "glVertexAttribL1d"); + glad_glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load(userptr, "glVertexAttribL1dv"); + glad_glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load(userptr, "glVertexAttribL2d"); + glad_glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load(userptr, "glVertexAttribL2dv"); + glad_glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load(userptr, "glVertexAttribL3d"); + glad_glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load(userptr, "glVertexAttribL3dv"); + glad_glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load(userptr, "glVertexAttribL4d"); + glad_glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load(userptr, "glVertexAttribL4dv"); + glad_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load(userptr, "glVertexAttribLPointer"); +} +static void glad_gl_load_GL_ARB_vertex_attrib_binding( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_attrib_binding) return; + glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + glad_glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load(userptr, "glVertexAttribLFormat"); + glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_ARB_vertex_blend( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_blend) return; + glad_glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC) load(userptr, "glVertexBlendARB"); + glad_glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC) load(userptr, "glWeightPointerARB"); + glad_glWeightbvARB = (PFNGLWEIGHTBVARBPROC) load(userptr, "glWeightbvARB"); + glad_glWeightdvARB = (PFNGLWEIGHTDVARBPROC) load(userptr, "glWeightdvARB"); + glad_glWeightfvARB = (PFNGLWEIGHTFVARBPROC) load(userptr, "glWeightfvARB"); + glad_glWeightivARB = (PFNGLWEIGHTIVARBPROC) load(userptr, "glWeightivARB"); + glad_glWeightsvARB = (PFNGLWEIGHTSVARBPROC) load(userptr, "glWeightsvARB"); + glad_glWeightubvARB = (PFNGLWEIGHTUBVARBPROC) load(userptr, "glWeightubvARB"); + glad_glWeightuivARB = (PFNGLWEIGHTUIVARBPROC) load(userptr, "glWeightuivARB"); + glad_glWeightusvARB = (PFNGLWEIGHTUSVARBPROC) load(userptr, "glWeightusvARB"); +} +static void glad_gl_load_GL_ARB_vertex_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_buffer_object) return; + glad_glBindBufferARB = (PFNGLBINDBUFFERARBPROC) load(userptr, "glBindBufferARB"); + glad_glBufferDataARB = (PFNGLBUFFERDATAARBPROC) load(userptr, "glBufferDataARB"); + glad_glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC) load(userptr, "glBufferSubDataARB"); + glad_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) load(userptr, "glDeleteBuffersARB"); + glad_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) load(userptr, "glGenBuffersARB"); + glad_glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC) load(userptr, "glGetBufferParameterivARB"); + glad_glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC) load(userptr, "glGetBufferPointervARB"); + glad_glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC) load(userptr, "glGetBufferSubDataARB"); + glad_glIsBufferARB = (PFNGLISBUFFERARBPROC) load(userptr, "glIsBufferARB"); + glad_glMapBufferARB = (PFNGLMAPBUFFERARBPROC) load(userptr, "glMapBufferARB"); + glad_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) load(userptr, "glUnmapBufferARB"); +} +static void glad_gl_load_GL_ARB_vertex_program( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_program) return; + glad_glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) load(userptr, "glBindProgramARB"); + glad_glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) load(userptr, "glDeleteProgramsARB"); + glad_glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) load(userptr, "glDisableVertexAttribArrayARB"); + glad_glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) load(userptr, "glEnableVertexAttribArrayARB"); + glad_glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) load(userptr, "glGenProgramsARB"); + glad_glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) load(userptr, "glGetProgramEnvParameterdvARB"); + glad_glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) load(userptr, "glGetProgramEnvParameterfvARB"); + glad_glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) load(userptr, "glGetProgramLocalParameterdvARB"); + glad_glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) load(userptr, "glGetProgramLocalParameterfvARB"); + glad_glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) load(userptr, "glGetProgramStringARB"); + glad_glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) load(userptr, "glGetProgramivARB"); + glad_glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) load(userptr, "glGetVertexAttribPointervARB"); + glad_glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) load(userptr, "glGetVertexAttribdvARB"); + glad_glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) load(userptr, "glGetVertexAttribfvARB"); + glad_glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) load(userptr, "glGetVertexAttribivARB"); + glad_glIsProgramARB = (PFNGLISPROGRAMARBPROC) load(userptr, "glIsProgramARB"); + glad_glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) load(userptr, "glProgramEnvParameter4dARB"); + glad_glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) load(userptr, "glProgramEnvParameter4dvARB"); + glad_glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) load(userptr, "glProgramEnvParameter4fARB"); + glad_glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) load(userptr, "glProgramEnvParameter4fvARB"); + glad_glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) load(userptr, "glProgramLocalParameter4dARB"); + glad_glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) load(userptr, "glProgramLocalParameter4dvARB"); + glad_glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) load(userptr, "glProgramLocalParameter4fARB"); + glad_glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) load(userptr, "glProgramLocalParameter4fvARB"); + glad_glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) load(userptr, "glProgramStringARB"); + glad_glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) load(userptr, "glVertexAttrib1dARB"); + glad_glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) load(userptr, "glVertexAttrib1dvARB"); + glad_glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) load(userptr, "glVertexAttrib1fARB"); + glad_glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) load(userptr, "glVertexAttrib1fvARB"); + glad_glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) load(userptr, "glVertexAttrib1sARB"); + glad_glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) load(userptr, "glVertexAttrib1svARB"); + glad_glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) load(userptr, "glVertexAttrib2dARB"); + glad_glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) load(userptr, "glVertexAttrib2dvARB"); + glad_glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) load(userptr, "glVertexAttrib2fARB"); + glad_glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) load(userptr, "glVertexAttrib2fvARB"); + glad_glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) load(userptr, "glVertexAttrib2sARB"); + glad_glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) load(userptr, "glVertexAttrib2svARB"); + glad_glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) load(userptr, "glVertexAttrib3dARB"); + glad_glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) load(userptr, "glVertexAttrib3dvARB"); + glad_glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) load(userptr, "glVertexAttrib3fARB"); + glad_glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) load(userptr, "glVertexAttrib3fvARB"); + glad_glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) load(userptr, "glVertexAttrib3sARB"); + glad_glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) load(userptr, "glVertexAttrib3svARB"); + glad_glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) load(userptr, "glVertexAttrib4NbvARB"); + glad_glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) load(userptr, "glVertexAttrib4NivARB"); + glad_glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) load(userptr, "glVertexAttrib4NsvARB"); + glad_glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) load(userptr, "glVertexAttrib4NubARB"); + glad_glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) load(userptr, "glVertexAttrib4NubvARB"); + glad_glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) load(userptr, "glVertexAttrib4NuivARB"); + glad_glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) load(userptr, "glVertexAttrib4NusvARB"); + glad_glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) load(userptr, "glVertexAttrib4bvARB"); + glad_glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) load(userptr, "glVertexAttrib4dARB"); + glad_glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) load(userptr, "glVertexAttrib4dvARB"); + glad_glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) load(userptr, "glVertexAttrib4fARB"); + glad_glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) load(userptr, "glVertexAttrib4fvARB"); + glad_glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) load(userptr, "glVertexAttrib4ivARB"); + glad_glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) load(userptr, "glVertexAttrib4sARB"); + glad_glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) load(userptr, "glVertexAttrib4svARB"); + glad_glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) load(userptr, "glVertexAttrib4ubvARB"); + glad_glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) load(userptr, "glVertexAttrib4uivARB"); + glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) load(userptr, "glVertexAttrib4usvARB"); + glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) load(userptr, "glVertexAttribPointerARB"); +} +static void glad_gl_load_GL_ARB_vertex_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_shader) return; + glad_glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) load(userptr, "glBindAttribLocationARB"); + glad_glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) load(userptr, "glDisableVertexAttribArrayARB"); + glad_glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) load(userptr, "glEnableVertexAttribArrayARB"); + glad_glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) load(userptr, "glGetActiveAttribARB"); + glad_glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) load(userptr, "glGetAttribLocationARB"); + glad_glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) load(userptr, "glGetVertexAttribPointervARB"); + glad_glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) load(userptr, "glGetVertexAttribdvARB"); + glad_glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) load(userptr, "glGetVertexAttribfvARB"); + glad_glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) load(userptr, "glGetVertexAttribivARB"); + glad_glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) load(userptr, "glVertexAttrib1dARB"); + glad_glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) load(userptr, "glVertexAttrib1dvARB"); + glad_glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) load(userptr, "glVertexAttrib1fARB"); + glad_glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) load(userptr, "glVertexAttrib1fvARB"); + glad_glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) load(userptr, "glVertexAttrib1sARB"); + glad_glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) load(userptr, "glVertexAttrib1svARB"); + glad_glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) load(userptr, "glVertexAttrib2dARB"); + glad_glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) load(userptr, "glVertexAttrib2dvARB"); + glad_glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) load(userptr, "glVertexAttrib2fARB"); + glad_glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) load(userptr, "glVertexAttrib2fvARB"); + glad_glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) load(userptr, "glVertexAttrib2sARB"); + glad_glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) load(userptr, "glVertexAttrib2svARB"); + glad_glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) load(userptr, "glVertexAttrib3dARB"); + glad_glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) load(userptr, "glVertexAttrib3dvARB"); + glad_glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) load(userptr, "glVertexAttrib3fARB"); + glad_glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) load(userptr, "glVertexAttrib3fvARB"); + glad_glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) load(userptr, "glVertexAttrib3sARB"); + glad_glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) load(userptr, "glVertexAttrib3svARB"); + glad_glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) load(userptr, "glVertexAttrib4NbvARB"); + glad_glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) load(userptr, "glVertexAttrib4NivARB"); + glad_glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) load(userptr, "glVertexAttrib4NsvARB"); + glad_glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) load(userptr, "glVertexAttrib4NubARB"); + glad_glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) load(userptr, "glVertexAttrib4NubvARB"); + glad_glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) load(userptr, "glVertexAttrib4NuivARB"); + glad_glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) load(userptr, "glVertexAttrib4NusvARB"); + glad_glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) load(userptr, "glVertexAttrib4bvARB"); + glad_glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) load(userptr, "glVertexAttrib4dARB"); + glad_glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) load(userptr, "glVertexAttrib4dvARB"); + glad_glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) load(userptr, "glVertexAttrib4fARB"); + glad_glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) load(userptr, "glVertexAttrib4fvARB"); + glad_glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) load(userptr, "glVertexAttrib4ivARB"); + glad_glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) load(userptr, "glVertexAttrib4sARB"); + glad_glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) load(userptr, "glVertexAttrib4svARB"); + glad_glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) load(userptr, "glVertexAttrib4ubvARB"); + glad_glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) load(userptr, "glVertexAttrib4uivARB"); + glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) load(userptr, "glVertexAttrib4usvARB"); + glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) load(userptr, "glVertexAttribPointerARB"); +} +static void glad_gl_load_GL_ARB_vertex_type_2_10_10_10_rev( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_vertex_type_2_10_10_10_rev) return; + glad_glColorP3ui = (PFNGLCOLORP3UIPROC) load(userptr, "glColorP3ui"); + glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC) load(userptr, "glColorP3uiv"); + glad_glColorP4ui = (PFNGLCOLORP4UIPROC) load(userptr, "glColorP4ui"); + glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC) load(userptr, "glColorP4uiv"); + glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load(userptr, "glMultiTexCoordP1ui"); + glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load(userptr, "glMultiTexCoordP1uiv"); + glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load(userptr, "glMultiTexCoordP2ui"); + glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load(userptr, "glMultiTexCoordP2uiv"); + glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load(userptr, "glMultiTexCoordP3ui"); + glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load(userptr, "glMultiTexCoordP3uiv"); + glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load(userptr, "glMultiTexCoordP4ui"); + glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load(userptr, "glMultiTexCoordP4uiv"); + glad_glNormalP3ui = (PFNGLNORMALP3UIPROC) load(userptr, "glNormalP3ui"); + glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC) load(userptr, "glNormalP3uiv"); + glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load(userptr, "glSecondaryColorP3ui"); + glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load(userptr, "glSecondaryColorP3uiv"); + glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load(userptr, "glTexCoordP1ui"); + glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load(userptr, "glTexCoordP1uiv"); + glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load(userptr, "glTexCoordP2ui"); + glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load(userptr, "glTexCoordP2uiv"); + glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load(userptr, "glTexCoordP3ui"); + glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load(userptr, "glTexCoordP3uiv"); + glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load(userptr, "glTexCoordP4ui"); + glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load(userptr, "glTexCoordP4uiv"); + glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); + glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC) load(userptr, "glVertexP2ui"); + glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC) load(userptr, "glVertexP2uiv"); + glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC) load(userptr, "glVertexP3ui"); + glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC) load(userptr, "glVertexP3uiv"); + glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC) load(userptr, "glVertexP4ui"); + glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC) load(userptr, "glVertexP4uiv"); +} +static void glad_gl_load_GL_ARB_viewport_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_viewport_array) return; + glad_glDepthRangeArraydvNV = (PFNGLDEPTHRANGEARRAYDVNVPROC) load(userptr, "glDepthRangeArraydvNV"); + glad_glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load(userptr, "glDepthRangeArrayv"); + glad_glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load(userptr, "glDepthRangeIndexed"); + glad_glDepthRangeIndexeddNV = (PFNGLDEPTHRANGEINDEXEDDNVPROC) load(userptr, "glDepthRangeIndexeddNV"); + glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load(userptr, "glGetDoublei_v"); + glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC) load(userptr, "glGetFloati_v"); + glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load(userptr, "glScissorArrayv"); + glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load(userptr, "glScissorIndexed"); + glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load(userptr, "glScissorIndexedv"); + glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load(userptr, "glViewportArrayv"); + glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load(userptr, "glViewportIndexedf"); + glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load(userptr, "glViewportIndexedfv"); +} +static void glad_gl_load_GL_ARB_window_pos( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_window_pos) return; + glad_glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC) load(userptr, "glWindowPos2dARB"); + glad_glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC) load(userptr, "glWindowPos2dvARB"); + glad_glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC) load(userptr, "glWindowPos2fARB"); + glad_glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC) load(userptr, "glWindowPos2fvARB"); + glad_glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC) load(userptr, "glWindowPos2iARB"); + glad_glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC) load(userptr, "glWindowPos2ivARB"); + glad_glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC) load(userptr, "glWindowPos2sARB"); + glad_glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC) load(userptr, "glWindowPos2svARB"); + glad_glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC) load(userptr, "glWindowPos3dARB"); + glad_glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC) load(userptr, "glWindowPos3dvARB"); + glad_glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC) load(userptr, "glWindowPos3fARB"); + glad_glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC) load(userptr, "glWindowPos3fvARB"); + glad_glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC) load(userptr, "glWindowPos3iARB"); + glad_glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC) load(userptr, "glWindowPos3ivARB"); + glad_glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC) load(userptr, "glWindowPos3sARB"); + glad_glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC) load(userptr, "glWindowPos3svARB"); +} +static void glad_gl_load_GL_ATI_draw_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_draw_buffers) return; + glad_glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC) load(userptr, "glDrawBuffersATI"); +} +static void glad_gl_load_GL_ATI_element_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_element_array) return; + glad_glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC) load(userptr, "glDrawElementArrayATI"); + glad_glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC) load(userptr, "glDrawRangeElementArrayATI"); + glad_glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC) load(userptr, "glElementPointerATI"); +} +static void glad_gl_load_GL_ATI_envmap_bumpmap( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_envmap_bumpmap) return; + glad_glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC) load(userptr, "glGetTexBumpParameterfvATI"); + glad_glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC) load(userptr, "glGetTexBumpParameterivATI"); + glad_glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC) load(userptr, "glTexBumpParameterfvATI"); + glad_glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC) load(userptr, "glTexBumpParameterivATI"); +} +static void glad_gl_load_GL_ATI_fragment_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_fragment_shader) return; + glad_glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC) load(userptr, "glAlphaFragmentOp1ATI"); + glad_glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC) load(userptr, "glAlphaFragmentOp2ATI"); + glad_glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC) load(userptr, "glAlphaFragmentOp3ATI"); + glad_glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC) load(userptr, "glBeginFragmentShaderATI"); + glad_glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC) load(userptr, "glBindFragmentShaderATI"); + glad_glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC) load(userptr, "glColorFragmentOp1ATI"); + glad_glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC) load(userptr, "glColorFragmentOp2ATI"); + glad_glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC) load(userptr, "glColorFragmentOp3ATI"); + glad_glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC) load(userptr, "glDeleteFragmentShaderATI"); + glad_glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC) load(userptr, "glEndFragmentShaderATI"); + glad_glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC) load(userptr, "glGenFragmentShadersATI"); + glad_glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC) load(userptr, "glPassTexCoordATI"); + glad_glSampleMapATI = (PFNGLSAMPLEMAPATIPROC) load(userptr, "glSampleMapATI"); + glad_glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) load(userptr, "glSetFragmentShaderConstantATI"); +} +static void glad_gl_load_GL_ATI_map_object_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_map_object_buffer) return; + glad_glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC) load(userptr, "glMapObjectBufferATI"); + glad_glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC) load(userptr, "glUnmapObjectBufferATI"); +} +static void glad_gl_load_GL_ATI_pn_triangles( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_pn_triangles) return; + glad_glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC) load(userptr, "glPNTrianglesfATI"); + glad_glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC) load(userptr, "glPNTrianglesiATI"); +} +static void glad_gl_load_GL_ATI_separate_stencil( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_separate_stencil) return; + glad_glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) load(userptr, "glStencilFuncSeparateATI"); + glad_glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC) load(userptr, "glStencilOpSeparateATI"); +} +static void glad_gl_load_GL_ATI_vertex_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_vertex_array_object) return; + glad_glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC) load(userptr, "glArrayObjectATI"); + glad_glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC) load(userptr, "glFreeObjectBufferATI"); + glad_glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC) load(userptr, "glGetArrayObjectfvATI"); + glad_glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC) load(userptr, "glGetArrayObjectivATI"); + glad_glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC) load(userptr, "glGetObjectBufferfvATI"); + glad_glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC) load(userptr, "glGetObjectBufferivATI"); + glad_glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC) load(userptr, "glGetVariantArrayObjectfvATI"); + glad_glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC) load(userptr, "glGetVariantArrayObjectivATI"); + glad_glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC) load(userptr, "glIsObjectBufferATI"); + glad_glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC) load(userptr, "glNewObjectBufferATI"); + glad_glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC) load(userptr, "glUpdateObjectBufferATI"); + glad_glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC) load(userptr, "glVariantArrayObjectATI"); +} +static void glad_gl_load_GL_ATI_vertex_attrib_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_vertex_attrib_array_object) return; + glad_glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) load(userptr, "glGetVertexAttribArrayObjectfvATI"); + glad_glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) load(userptr, "glGetVertexAttribArrayObjectivATI"); + glad_glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) load(userptr, "glVertexAttribArrayObjectATI"); +} +static void glad_gl_load_GL_ATI_vertex_streams( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ATI_vertex_streams) return; + glad_glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) load(userptr, "glClientActiveVertexStreamATI"); + glad_glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC) load(userptr, "glNormalStream3bATI"); + glad_glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC) load(userptr, "glNormalStream3bvATI"); + glad_glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC) load(userptr, "glNormalStream3dATI"); + glad_glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC) load(userptr, "glNormalStream3dvATI"); + glad_glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC) load(userptr, "glNormalStream3fATI"); + glad_glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC) load(userptr, "glNormalStream3fvATI"); + glad_glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC) load(userptr, "glNormalStream3iATI"); + glad_glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC) load(userptr, "glNormalStream3ivATI"); + glad_glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC) load(userptr, "glNormalStream3sATI"); + glad_glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC) load(userptr, "glNormalStream3svATI"); + glad_glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC) load(userptr, "glVertexBlendEnvfATI"); + glad_glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC) load(userptr, "glVertexBlendEnviATI"); + glad_glVertexStream1dATI = (PFNGLVERTEXSTREAM1DATIPROC) load(userptr, "glVertexStream1dATI"); + glad_glVertexStream1dvATI = (PFNGLVERTEXSTREAM1DVATIPROC) load(userptr, "glVertexStream1dvATI"); + glad_glVertexStream1fATI = (PFNGLVERTEXSTREAM1FATIPROC) load(userptr, "glVertexStream1fATI"); + glad_glVertexStream1fvATI = (PFNGLVERTEXSTREAM1FVATIPROC) load(userptr, "glVertexStream1fvATI"); + glad_glVertexStream1iATI = (PFNGLVERTEXSTREAM1IATIPROC) load(userptr, "glVertexStream1iATI"); + glad_glVertexStream1ivATI = (PFNGLVERTEXSTREAM1IVATIPROC) load(userptr, "glVertexStream1ivATI"); + glad_glVertexStream1sATI = (PFNGLVERTEXSTREAM1SATIPROC) load(userptr, "glVertexStream1sATI"); + glad_glVertexStream1svATI = (PFNGLVERTEXSTREAM1SVATIPROC) load(userptr, "glVertexStream1svATI"); + glad_glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC) load(userptr, "glVertexStream2dATI"); + glad_glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC) load(userptr, "glVertexStream2dvATI"); + glad_glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC) load(userptr, "glVertexStream2fATI"); + glad_glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC) load(userptr, "glVertexStream2fvATI"); + glad_glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC) load(userptr, "glVertexStream2iATI"); + glad_glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC) load(userptr, "glVertexStream2ivATI"); + glad_glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC) load(userptr, "glVertexStream2sATI"); + glad_glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC) load(userptr, "glVertexStream2svATI"); + glad_glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC) load(userptr, "glVertexStream3dATI"); + glad_glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC) load(userptr, "glVertexStream3dvATI"); + glad_glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC) load(userptr, "glVertexStream3fATI"); + glad_glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC) load(userptr, "glVertexStream3fvATI"); + glad_glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC) load(userptr, "glVertexStream3iATI"); + glad_glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC) load(userptr, "glVertexStream3ivATI"); + glad_glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC) load(userptr, "glVertexStream3sATI"); + glad_glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC) load(userptr, "glVertexStream3svATI"); + glad_glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC) load(userptr, "glVertexStream4dATI"); + glad_glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC) load(userptr, "glVertexStream4dvATI"); + glad_glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC) load(userptr, "glVertexStream4fATI"); + glad_glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC) load(userptr, "glVertexStream4fvATI"); + glad_glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC) load(userptr, "glVertexStream4iATI"); + glad_glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC) load(userptr, "glVertexStream4ivATI"); + glad_glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC) load(userptr, "glVertexStream4sATI"); + glad_glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC) load(userptr, "glVertexStream4svATI"); +} +static void glad_gl_load_GL_EXT_EGL_image_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_EGL_image_storage) return; + glad_glEGLImageTargetTexStorageEXT = (PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) load(userptr, "glEGLImageTargetTexStorageEXT"); + glad_glEGLImageTargetTextureStorageEXT = (PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) load(userptr, "glEGLImageTargetTextureStorageEXT"); +} +static void glad_gl_load_GL_EXT_bindable_uniform( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_bindable_uniform) return; + glad_glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC) load(userptr, "glGetUniformBufferSizeEXT"); + glad_glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC) load(userptr, "glGetUniformOffsetEXT"); + glad_glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC) load(userptr, "glUniformBufferEXT"); +} +static void glad_gl_load_GL_EXT_blend_color( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_blend_color) return; + glad_glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC) load(userptr, "glBlendColorEXT"); +} +static void glad_gl_load_GL_EXT_blend_equation_separate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_blend_equation_separate) return; + glad_glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC) load(userptr, "glBlendEquationSeparateEXT"); +} +static void glad_gl_load_GL_EXT_blend_func_separate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_blend_func_separate) return; + glad_glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) load(userptr, "glBlendFuncSeparateEXT"); +} +static void glad_gl_load_GL_EXT_blend_minmax( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_blend_minmax) return; + glad_glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) load(userptr, "glBlendEquationEXT"); +} +static void glad_gl_load_GL_EXT_color_subtable( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_color_subtable) return; + glad_glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC) load(userptr, "glColorSubTableEXT"); + glad_glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC) load(userptr, "glCopyColorSubTableEXT"); +} +static void glad_gl_load_GL_EXT_compiled_vertex_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_compiled_vertex_array) return; + glad_glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC) load(userptr, "glLockArraysEXT"); + glad_glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC) load(userptr, "glUnlockArraysEXT"); +} +static void glad_gl_load_GL_EXT_convolution( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_convolution) return; + glad_glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC) load(userptr, "glConvolutionFilter1DEXT"); + glad_glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC) load(userptr, "glConvolutionFilter2DEXT"); + glad_glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC) load(userptr, "glConvolutionParameterfEXT"); + glad_glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC) load(userptr, "glConvolutionParameterfvEXT"); + glad_glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC) load(userptr, "glConvolutionParameteriEXT"); + glad_glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC) load(userptr, "glConvolutionParameterivEXT"); + glad_glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) load(userptr, "glCopyConvolutionFilter1DEXT"); + glad_glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) load(userptr, "glCopyConvolutionFilter2DEXT"); + glad_glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC) load(userptr, "glGetConvolutionFilterEXT"); + glad_glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) load(userptr, "glGetConvolutionParameterfvEXT"); + glad_glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) load(userptr, "glGetConvolutionParameterivEXT"); + glad_glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC) load(userptr, "glGetSeparableFilterEXT"); + glad_glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC) load(userptr, "glSeparableFilter2DEXT"); +} +static void glad_gl_load_GL_EXT_coordinate_frame( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_coordinate_frame) return; + glad_glBinormal3bEXT = (PFNGLBINORMAL3BEXTPROC) load(userptr, "glBinormal3bEXT"); + glad_glBinormal3bvEXT = (PFNGLBINORMAL3BVEXTPROC) load(userptr, "glBinormal3bvEXT"); + glad_glBinormal3dEXT = (PFNGLBINORMAL3DEXTPROC) load(userptr, "glBinormal3dEXT"); + glad_glBinormal3dvEXT = (PFNGLBINORMAL3DVEXTPROC) load(userptr, "glBinormal3dvEXT"); + glad_glBinormal3fEXT = (PFNGLBINORMAL3FEXTPROC) load(userptr, "glBinormal3fEXT"); + glad_glBinormal3fvEXT = (PFNGLBINORMAL3FVEXTPROC) load(userptr, "glBinormal3fvEXT"); + glad_glBinormal3iEXT = (PFNGLBINORMAL3IEXTPROC) load(userptr, "glBinormal3iEXT"); + glad_glBinormal3ivEXT = (PFNGLBINORMAL3IVEXTPROC) load(userptr, "glBinormal3ivEXT"); + glad_glBinormal3sEXT = (PFNGLBINORMAL3SEXTPROC) load(userptr, "glBinormal3sEXT"); + glad_glBinormal3svEXT = (PFNGLBINORMAL3SVEXTPROC) load(userptr, "glBinormal3svEXT"); + glad_glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC) load(userptr, "glBinormalPointerEXT"); + glad_glTangent3bEXT = (PFNGLTANGENT3BEXTPROC) load(userptr, "glTangent3bEXT"); + glad_glTangent3bvEXT = (PFNGLTANGENT3BVEXTPROC) load(userptr, "glTangent3bvEXT"); + glad_glTangent3dEXT = (PFNGLTANGENT3DEXTPROC) load(userptr, "glTangent3dEXT"); + glad_glTangent3dvEXT = (PFNGLTANGENT3DVEXTPROC) load(userptr, "glTangent3dvEXT"); + glad_glTangent3fEXT = (PFNGLTANGENT3FEXTPROC) load(userptr, "glTangent3fEXT"); + glad_glTangent3fvEXT = (PFNGLTANGENT3FVEXTPROC) load(userptr, "glTangent3fvEXT"); + glad_glTangent3iEXT = (PFNGLTANGENT3IEXTPROC) load(userptr, "glTangent3iEXT"); + glad_glTangent3ivEXT = (PFNGLTANGENT3IVEXTPROC) load(userptr, "glTangent3ivEXT"); + glad_glTangent3sEXT = (PFNGLTANGENT3SEXTPROC) load(userptr, "glTangent3sEXT"); + glad_glTangent3svEXT = (PFNGLTANGENT3SVEXTPROC) load(userptr, "glTangent3svEXT"); + glad_glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC) load(userptr, "glTangentPointerEXT"); +} +static void glad_gl_load_GL_EXT_copy_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_copy_texture) return; + glad_glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC) load(userptr, "glCopyTexImage1DEXT"); + glad_glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC) load(userptr, "glCopyTexImage2DEXT"); + glad_glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC) load(userptr, "glCopyTexSubImage1DEXT"); + glad_glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC) load(userptr, "glCopyTexSubImage2DEXT"); + glad_glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC) load(userptr, "glCopyTexSubImage3DEXT"); +} +static void glad_gl_load_GL_EXT_cull_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_cull_vertex) return; + glad_glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC) load(userptr, "glCullParameterdvEXT"); + glad_glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC) load(userptr, "glCullParameterfvEXT"); +} +static void glad_gl_load_GL_EXT_debug_label( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_debug_label) return; + glad_glGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC) load(userptr, "glGetObjectLabelEXT"); + glad_glLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC) load(userptr, "glLabelObjectEXT"); +} +static void glad_gl_load_GL_EXT_debug_marker( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_debug_marker) return; + glad_glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC) load(userptr, "glInsertEventMarkerEXT"); + glad_glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC) load(userptr, "glPopGroupMarkerEXT"); + glad_glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC) load(userptr, "glPushGroupMarkerEXT"); +} +static void glad_gl_load_GL_EXT_depth_bounds_test( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_depth_bounds_test) return; + glad_glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC) load(userptr, "glDepthBoundsEXT"); +} +static void glad_gl_load_GL_EXT_direct_state_access( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_direct_state_access) return; + glad_glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC) load(userptr, "glBindMultiTextureEXT"); + glad_glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) load(userptr, "glCheckNamedFramebufferStatusEXT"); + glad_glClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC) load(userptr, "glClearNamedBufferDataEXT"); + glad_glClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) load(userptr, "glClearNamedBufferSubDataEXT"); + glad_glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC) load(userptr, "glClientAttribDefaultEXT"); + glad_glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) load(userptr, "glCompressedMultiTexImage1DEXT"); + glad_glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) load(userptr, "glCompressedMultiTexImage2DEXT"); + glad_glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) load(userptr, "glCompressedMultiTexImage3DEXT"); + glad_glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) load(userptr, "glCompressedMultiTexSubImage1DEXT"); + glad_glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) load(userptr, "glCompressedMultiTexSubImage2DEXT"); + glad_glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) load(userptr, "glCompressedMultiTexSubImage3DEXT"); + glad_glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) load(userptr, "glCompressedTextureImage1DEXT"); + glad_glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) load(userptr, "glCompressedTextureImage2DEXT"); + glad_glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) load(userptr, "glCompressedTextureImage3DEXT"); + glad_glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) load(userptr, "glCompressedTextureSubImage1DEXT"); + glad_glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) load(userptr, "glCompressedTextureSubImage2DEXT"); + glad_glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) load(userptr, "glCompressedTextureSubImage3DEXT"); + glad_glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC) load(userptr, "glCopyMultiTexImage1DEXT"); + glad_glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC) load(userptr, "glCopyMultiTexImage2DEXT"); + glad_glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) load(userptr, "glCopyMultiTexSubImage1DEXT"); + glad_glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) load(userptr, "glCopyMultiTexSubImage2DEXT"); + glad_glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) load(userptr, "glCopyMultiTexSubImage3DEXT"); + glad_glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC) load(userptr, "glCopyTextureImage1DEXT"); + glad_glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC) load(userptr, "glCopyTextureImage2DEXT"); + glad_glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) load(userptr, "glCopyTextureSubImage1DEXT"); + glad_glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) load(userptr, "glCopyTextureSubImage2DEXT"); + glad_glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) load(userptr, "glCopyTextureSubImage3DEXT"); + glad_glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) load(userptr, "glDisableClientStateIndexedEXT"); + glad_glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC) load(userptr, "glDisableClientStateiEXT"); + glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC) load(userptr, "glDisableIndexedEXT"); + glad_glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) load(userptr, "glDisableVertexArrayAttribEXT"); + glad_glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC) load(userptr, "glDisableVertexArrayEXT"); + glad_glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) load(userptr, "glEnableClientStateIndexedEXT"); + glad_glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC) load(userptr, "glEnableClientStateiEXT"); + glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC) load(userptr, "glEnableIndexedEXT"); + glad_glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) load(userptr, "glEnableVertexArrayAttribEXT"); + glad_glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC) load(userptr, "glEnableVertexArrayEXT"); + glad_glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) load(userptr, "glFlushMappedNamedBufferRangeEXT"); + glad_glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) load(userptr, "glFramebufferDrawBufferEXT"); + glad_glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) load(userptr, "glFramebufferDrawBuffersEXT"); + glad_glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC) load(userptr, "glFramebufferReadBufferEXT"); + glad_glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC) load(userptr, "glGenerateMultiTexMipmapEXT"); + glad_glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC) load(userptr, "glGenerateTextureMipmapEXT"); + glad_glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC) load(userptr, "glGetBooleanIndexedvEXT"); + glad_glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) load(userptr, "glGetCompressedMultiTexImageEXT"); + glad_glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) load(userptr, "glGetCompressedTextureImageEXT"); + glad_glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC) load(userptr, "glGetDoubleIndexedvEXT"); + glad_glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC) load(userptr, "glGetDoublei_vEXT"); + glad_glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC) load(userptr, "glGetFloatIndexedvEXT"); + glad_glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC) load(userptr, "glGetFloati_vEXT"); + glad_glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetFramebufferParameterivEXT"); + glad_glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC) load(userptr, "glGetIntegerIndexedvEXT"); + glad_glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC) load(userptr, "glGetMultiTexEnvfvEXT"); + glad_glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC) load(userptr, "glGetMultiTexEnvivEXT"); + glad_glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC) load(userptr, "glGetMultiTexGendvEXT"); + glad_glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC) load(userptr, "glGetMultiTexGenfvEXT"); + glad_glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC) load(userptr, "glGetMultiTexGenivEXT"); + glad_glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC) load(userptr, "glGetMultiTexImageEXT"); + glad_glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) load(userptr, "glGetMultiTexLevelParameterfvEXT"); + glad_glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) load(userptr, "glGetMultiTexLevelParameterivEXT"); + glad_glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC) load(userptr, "glGetMultiTexParameterIivEXT"); + glad_glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) load(userptr, "glGetMultiTexParameterIuivEXT"); + glad_glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC) load(userptr, "glGetMultiTexParameterfvEXT"); + glad_glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC) load(userptr, "glGetMultiTexParameterivEXT"); + glad_glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetNamedBufferParameterivEXT"); + glad_glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) load(userptr, "glGetNamedBufferPointervEXT"); + glad_glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) load(userptr, "glGetNamedBufferSubDataEXT"); + glad_glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) load(userptr, "glGetNamedFramebufferAttachmentParameterivEXT"); + glad_glGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetNamedFramebufferParameterivEXT"); + glad_glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) load(userptr, "glGetNamedProgramLocalParameterIivEXT"); + glad_glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) load(userptr, "glGetNamedProgramLocalParameterIuivEXT"); + glad_glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) load(userptr, "glGetNamedProgramLocalParameterdvEXT"); + glad_glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) load(userptr, "glGetNamedProgramLocalParameterfvEXT"); + glad_glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) load(userptr, "glGetNamedProgramStringEXT"); + glad_glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC) load(userptr, "glGetNamedProgramivEXT"); + glad_glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetNamedRenderbufferParameterivEXT"); + glad_glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC) load(userptr, "glGetPointerIndexedvEXT"); + glad_glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC) load(userptr, "glGetPointeri_vEXT"); + glad_glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC) load(userptr, "glGetTextureImageEXT"); + glad_glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) load(userptr, "glGetTextureLevelParameterfvEXT"); + glad_glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) load(userptr, "glGetTextureLevelParameterivEXT"); + glad_glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC) load(userptr, "glGetTextureParameterIivEXT"); + glad_glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) load(userptr, "glGetTextureParameterIuivEXT"); + glad_glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC) load(userptr, "glGetTextureParameterfvEXT"); + glad_glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC) load(userptr, "glGetTextureParameterivEXT"); + glad_glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) load(userptr, "glGetVertexArrayIntegeri_vEXT"); + glad_glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC) load(userptr, "glGetVertexArrayIntegervEXT"); + glad_glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) load(userptr, "glGetVertexArrayPointeri_vEXT"); + glad_glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC) load(userptr, "glGetVertexArrayPointervEXT"); + glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC) load(userptr, "glIsEnabledIndexedEXT"); + glad_glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC) load(userptr, "glMapNamedBufferEXT"); + glad_glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC) load(userptr, "glMapNamedBufferRangeEXT"); + glad_glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC) load(userptr, "glMatrixFrustumEXT"); + glad_glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC) load(userptr, "glMatrixLoadIdentityEXT"); + glad_glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC) load(userptr, "glMatrixLoadTransposedEXT"); + glad_glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC) load(userptr, "glMatrixLoadTransposefEXT"); + glad_glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC) load(userptr, "glMatrixLoaddEXT"); + glad_glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC) load(userptr, "glMatrixLoadfEXT"); + glad_glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC) load(userptr, "glMatrixMultTransposedEXT"); + glad_glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC) load(userptr, "glMatrixMultTransposefEXT"); + glad_glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC) load(userptr, "glMatrixMultdEXT"); + glad_glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC) load(userptr, "glMatrixMultfEXT"); + glad_glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC) load(userptr, "glMatrixOrthoEXT"); + glad_glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC) load(userptr, "glMatrixPopEXT"); + glad_glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC) load(userptr, "glMatrixPushEXT"); + glad_glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC) load(userptr, "glMatrixRotatedEXT"); + glad_glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC) load(userptr, "glMatrixRotatefEXT"); + glad_glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC) load(userptr, "glMatrixScaledEXT"); + glad_glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC) load(userptr, "glMatrixScalefEXT"); + glad_glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC) load(userptr, "glMatrixTranslatedEXT"); + glad_glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC) load(userptr, "glMatrixTranslatefEXT"); + glad_glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC) load(userptr, "glMultiTexBufferEXT"); + glad_glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC) load(userptr, "glMultiTexCoordPointerEXT"); + glad_glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC) load(userptr, "glMultiTexEnvfEXT"); + glad_glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC) load(userptr, "glMultiTexEnvfvEXT"); + glad_glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC) load(userptr, "glMultiTexEnviEXT"); + glad_glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC) load(userptr, "glMultiTexEnvivEXT"); + glad_glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC) load(userptr, "glMultiTexGendEXT"); + glad_glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC) load(userptr, "glMultiTexGendvEXT"); + glad_glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC) load(userptr, "glMultiTexGenfEXT"); + glad_glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC) load(userptr, "glMultiTexGenfvEXT"); + glad_glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC) load(userptr, "glMultiTexGeniEXT"); + glad_glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC) load(userptr, "glMultiTexGenivEXT"); + glad_glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC) load(userptr, "glMultiTexImage1DEXT"); + glad_glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC) load(userptr, "glMultiTexImage2DEXT"); + glad_glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC) load(userptr, "glMultiTexImage3DEXT"); + glad_glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC) load(userptr, "glMultiTexParameterIivEXT"); + glad_glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC) load(userptr, "glMultiTexParameterIuivEXT"); + glad_glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC) load(userptr, "glMultiTexParameterfEXT"); + glad_glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC) load(userptr, "glMultiTexParameterfvEXT"); + glad_glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC) load(userptr, "glMultiTexParameteriEXT"); + glad_glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC) load(userptr, "glMultiTexParameterivEXT"); + glad_glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC) load(userptr, "glMultiTexRenderbufferEXT"); + glad_glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC) load(userptr, "glMultiTexSubImage1DEXT"); + glad_glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC) load(userptr, "glMultiTexSubImage2DEXT"); + glad_glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC) load(userptr, "glMultiTexSubImage3DEXT"); + glad_glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC) load(userptr, "glNamedBufferDataEXT"); + glad_glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC) load(userptr, "glNamedBufferStorageEXT"); + glad_glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC) load(userptr, "glNamedBufferSubDataEXT"); + glad_glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) load(userptr, "glNamedCopyBufferSubDataEXT"); + glad_glNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) load(userptr, "glNamedFramebufferParameteriEXT"); + glad_glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) load(userptr, "glNamedFramebufferRenderbufferEXT"); + glad_glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) load(userptr, "glNamedFramebufferTexture1DEXT"); + glad_glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) load(userptr, "glNamedFramebufferTexture2DEXT"); + glad_glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) load(userptr, "glNamedFramebufferTexture3DEXT"); + glad_glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) load(userptr, "glNamedFramebufferTextureEXT"); + glad_glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) load(userptr, "glNamedFramebufferTextureFaceEXT"); + glad_glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) load(userptr, "glNamedFramebufferTextureLayerEXT"); + glad_glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) load(userptr, "glNamedProgramLocalParameter4dEXT"); + glad_glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) load(userptr, "glNamedProgramLocalParameter4dvEXT"); + glad_glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) load(userptr, "glNamedProgramLocalParameter4fEXT"); + glad_glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) load(userptr, "glNamedProgramLocalParameter4fvEXT"); + glad_glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) load(userptr, "glNamedProgramLocalParameterI4iEXT"); + glad_glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) load(userptr, "glNamedProgramLocalParameterI4ivEXT"); + glad_glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) load(userptr, "glNamedProgramLocalParameterI4uiEXT"); + glad_glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) load(userptr, "glNamedProgramLocalParameterI4uivEXT"); + glad_glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) load(userptr, "glNamedProgramLocalParameters4fvEXT"); + glad_glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) load(userptr, "glNamedProgramLocalParametersI4ivEXT"); + glad_glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) load(userptr, "glNamedProgramLocalParametersI4uivEXT"); + glad_glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC) load(userptr, "glNamedProgramStringEXT"); + glad_glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) load(userptr, "glNamedRenderbufferStorageEXT"); + glad_glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) load(userptr, "glNamedRenderbufferStorageMultisampleCoverageEXT"); + glad_glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glNamedRenderbufferStorageMultisampleEXT"); + glad_glProgramUniform1dEXT = (PFNGLPROGRAMUNIFORM1DEXTPROC) load(userptr, "glProgramUniform1dEXT"); + glad_glProgramUniform1dvEXT = (PFNGLPROGRAMUNIFORM1DVEXTPROC) load(userptr, "glProgramUniform1dvEXT"); + glad_glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) load(userptr, "glProgramUniform1fEXT"); + glad_glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) load(userptr, "glProgramUniform1fvEXT"); + glad_glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) load(userptr, "glProgramUniform1iEXT"); + glad_glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) load(userptr, "glProgramUniform1ivEXT"); + glad_glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC) load(userptr, "glProgramUniform1uiEXT"); + glad_glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC) load(userptr, "glProgramUniform1uivEXT"); + glad_glProgramUniform2dEXT = (PFNGLPROGRAMUNIFORM2DEXTPROC) load(userptr, "glProgramUniform2dEXT"); + glad_glProgramUniform2dvEXT = (PFNGLPROGRAMUNIFORM2DVEXTPROC) load(userptr, "glProgramUniform2dvEXT"); + glad_glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) load(userptr, "glProgramUniform2fEXT"); + glad_glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) load(userptr, "glProgramUniform2fvEXT"); + glad_glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) load(userptr, "glProgramUniform2iEXT"); + glad_glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) load(userptr, "glProgramUniform2ivEXT"); + glad_glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC) load(userptr, "glProgramUniform2uiEXT"); + glad_glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC) load(userptr, "glProgramUniform2uivEXT"); + glad_glProgramUniform3dEXT = (PFNGLPROGRAMUNIFORM3DEXTPROC) load(userptr, "glProgramUniform3dEXT"); + glad_glProgramUniform3dvEXT = (PFNGLPROGRAMUNIFORM3DVEXTPROC) load(userptr, "glProgramUniform3dvEXT"); + glad_glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) load(userptr, "glProgramUniform3fEXT"); + glad_glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) load(userptr, "glProgramUniform3fvEXT"); + glad_glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) load(userptr, "glProgramUniform3iEXT"); + glad_glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) load(userptr, "glProgramUniform3ivEXT"); + glad_glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC) load(userptr, "glProgramUniform3uiEXT"); + glad_glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC) load(userptr, "glProgramUniform3uivEXT"); + glad_glProgramUniform4dEXT = (PFNGLPROGRAMUNIFORM4DEXTPROC) load(userptr, "glProgramUniform4dEXT"); + glad_glProgramUniform4dvEXT = (PFNGLPROGRAMUNIFORM4DVEXTPROC) load(userptr, "glProgramUniform4dvEXT"); + glad_glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) load(userptr, "glProgramUniform4fEXT"); + glad_glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) load(userptr, "glProgramUniform4fvEXT"); + glad_glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) load(userptr, "glProgramUniform4iEXT"); + glad_glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) load(userptr, "glProgramUniform4ivEXT"); + glad_glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC) load(userptr, "glProgramUniform4uiEXT"); + glad_glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC) load(userptr, "glProgramUniform4uivEXT"); + glad_glProgramUniformMatrix2dvEXT = (PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) load(userptr, "glProgramUniformMatrix2dvEXT"); + glad_glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) load(userptr, "glProgramUniformMatrix2fvEXT"); + glad_glProgramUniformMatrix2x3dvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) load(userptr, "glProgramUniformMatrix2x3dvEXT"); + glad_glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) load(userptr, "glProgramUniformMatrix2x3fvEXT"); + glad_glProgramUniformMatrix2x4dvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) load(userptr, "glProgramUniformMatrix2x4dvEXT"); + glad_glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) load(userptr, "glProgramUniformMatrix2x4fvEXT"); + glad_glProgramUniformMatrix3dvEXT = (PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) load(userptr, "glProgramUniformMatrix3dvEXT"); + glad_glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) load(userptr, "glProgramUniformMatrix3fvEXT"); + glad_glProgramUniformMatrix3x2dvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) load(userptr, "glProgramUniformMatrix3x2dvEXT"); + glad_glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) load(userptr, "glProgramUniformMatrix3x2fvEXT"); + glad_glProgramUniformMatrix3x4dvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) load(userptr, "glProgramUniformMatrix3x4dvEXT"); + glad_glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) load(userptr, "glProgramUniformMatrix3x4fvEXT"); + glad_glProgramUniformMatrix4dvEXT = (PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) load(userptr, "glProgramUniformMatrix4dvEXT"); + glad_glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) load(userptr, "glProgramUniformMatrix4fvEXT"); + glad_glProgramUniformMatrix4x2dvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) load(userptr, "glProgramUniformMatrix4x2dvEXT"); + glad_glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) load(userptr, "glProgramUniformMatrix4x2fvEXT"); + glad_glProgramUniformMatrix4x3dvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) load(userptr, "glProgramUniformMatrix4x3dvEXT"); + glad_glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) load(userptr, "glProgramUniformMatrix4x3fvEXT"); + glad_glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) load(userptr, "glPushClientAttribDefaultEXT"); + glad_glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC) load(userptr, "glTextureBufferEXT"); + glad_glTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC) load(userptr, "glTextureBufferRangeEXT"); + glad_glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC) load(userptr, "glTextureImage1DEXT"); + glad_glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC) load(userptr, "glTextureImage2DEXT"); + glad_glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC) load(userptr, "glTextureImage3DEXT"); + glad_glTexturePageCommitmentEXT = (PFNGLTEXTUREPAGECOMMITMENTEXTPROC) load(userptr, "glTexturePageCommitmentEXT"); + glad_glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC) load(userptr, "glTextureParameterIivEXT"); + glad_glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC) load(userptr, "glTextureParameterIuivEXT"); + glad_glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC) load(userptr, "glTextureParameterfEXT"); + glad_glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC) load(userptr, "glTextureParameterfvEXT"); + glad_glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC) load(userptr, "glTextureParameteriEXT"); + glad_glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC) load(userptr, "glTextureParameterivEXT"); + glad_glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC) load(userptr, "glTextureRenderbufferEXT"); + glad_glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) load(userptr, "glTextureStorage1DEXT"); + glad_glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) load(userptr, "glTextureStorage2DEXT"); + glad_glTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) load(userptr, "glTextureStorage2DMultisampleEXT"); + glad_glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) load(userptr, "glTextureStorage3DEXT"); + glad_glTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) load(userptr, "glTextureStorage3DMultisampleEXT"); + glad_glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC) load(userptr, "glTextureSubImage1DEXT"); + glad_glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC) load(userptr, "glTextureSubImage2DEXT"); + glad_glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC) load(userptr, "glTextureSubImage3DEXT"); + glad_glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC) load(userptr, "glUnmapNamedBufferEXT"); + glad_glVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) load(userptr, "glVertexArrayBindVertexBufferEXT"); + glad_glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) load(userptr, "glVertexArrayColorOffsetEXT"); + glad_glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) load(userptr, "glVertexArrayEdgeFlagOffsetEXT"); + glad_glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) load(userptr, "glVertexArrayFogCoordOffsetEXT"); + glad_glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) load(userptr, "glVertexArrayIndexOffsetEXT"); + glad_glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) load(userptr, "glVertexArrayMultiTexCoordOffsetEXT"); + glad_glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) load(userptr, "glVertexArrayNormalOffsetEXT"); + glad_glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) load(userptr, "glVertexArraySecondaryColorOffsetEXT"); + glad_glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) load(userptr, "glVertexArrayTexCoordOffsetEXT"); + glad_glVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) load(userptr, "glVertexArrayVertexAttribBindingEXT"); + glad_glVertexArrayVertexAttribDivisorEXT = (PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) load(userptr, "glVertexArrayVertexAttribDivisorEXT"); + glad_glVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) load(userptr, "glVertexArrayVertexAttribFormatEXT"); + glad_glVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) load(userptr, "glVertexArrayVertexAttribIFormatEXT"); + glad_glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) load(userptr, "glVertexArrayVertexAttribIOffsetEXT"); + glad_glVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) load(userptr, "glVertexArrayVertexAttribLFormatEXT"); + glad_glVertexArrayVertexAttribLOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) load(userptr, "glVertexArrayVertexAttribLOffsetEXT"); + glad_glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) load(userptr, "glVertexArrayVertexAttribOffsetEXT"); + glad_glVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) load(userptr, "glVertexArrayVertexBindingDivisorEXT"); + glad_glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) load(userptr, "glVertexArrayVertexOffsetEXT"); +} +static void glad_gl_load_GL_EXT_draw_buffers2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_buffers2) return; + glad_glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC) load(userptr, "glColorMaskIndexedEXT"); + glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC) load(userptr, "glDisableIndexedEXT"); + glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC) load(userptr, "glEnableIndexedEXT"); + glad_glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC) load(userptr, "glGetBooleanIndexedvEXT"); + glad_glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC) load(userptr, "glGetIntegerIndexedvEXT"); + glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC) load(userptr, "glIsEnabledIndexedEXT"); +} +static void glad_gl_load_GL_EXT_draw_instanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_instanced) return; + glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) load(userptr, "glDrawArraysInstancedEXT"); + glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) load(userptr, "glDrawElementsInstancedEXT"); +} +static void glad_gl_load_GL_EXT_draw_range_elements( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_range_elements) return; + glad_glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC) load(userptr, "glDrawRangeElementsEXT"); +} +static void glad_gl_load_GL_EXT_external_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_external_buffer) return; + glad_glBufferStorageExternalEXT = (PFNGLBUFFERSTORAGEEXTERNALEXTPROC) load(userptr, "glBufferStorageExternalEXT"); + glad_glNamedBufferStorageExternalEXT = (PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) load(userptr, "glNamedBufferStorageExternalEXT"); +} +static void glad_gl_load_GL_EXT_fog_coord( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_fog_coord) return; + glad_glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC) load(userptr, "glFogCoordPointerEXT"); + glad_glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC) load(userptr, "glFogCoorddEXT"); + glad_glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC) load(userptr, "glFogCoorddvEXT"); + glad_glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC) load(userptr, "glFogCoordfEXT"); + glad_glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC) load(userptr, "glFogCoordfvEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_blit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_blit) return; + glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) load(userptr, "glBlitFramebufferEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_blit_layers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_blit_layers) return; + glad_glBlitFramebufferLayerEXT = (PFNGLBLITFRAMEBUFFERLAYEREXTPROC) load(userptr, "glBlitFramebufferLayerEXT"); + glad_glBlitFramebufferLayersEXT = (PFNGLBLITFRAMEBUFFERLAYERSEXTPROC) load(userptr, "glBlitFramebufferLayersEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_multisample) return; + glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT"); +} +static void glad_gl_load_GL_EXT_framebuffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_framebuffer_object) return; + glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) load(userptr, "glBindFramebufferEXT"); + glad_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) load(userptr, "glBindRenderbufferEXT"); + glad_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) load(userptr, "glCheckFramebufferStatusEXT"); + glad_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) load(userptr, "glDeleteFramebuffersEXT"); + glad_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) load(userptr, "glDeleteRenderbuffersEXT"); + glad_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) load(userptr, "glFramebufferRenderbufferEXT"); + glad_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) load(userptr, "glFramebufferTexture1DEXT"); + glad_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) load(userptr, "glFramebufferTexture2DEXT"); + glad_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) load(userptr, "glFramebufferTexture3DEXT"); + glad_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) load(userptr, "glGenFramebuffersEXT"); + glad_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) load(userptr, "glGenRenderbuffersEXT"); + glad_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) load(userptr, "glGenerateMipmapEXT"); + glad_glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) load(userptr, "glGetFramebufferAttachmentParameterivEXT"); + glad_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) load(userptr, "glGetRenderbufferParameterivEXT"); + glad_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) load(userptr, "glIsFramebufferEXT"); + glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) load(userptr, "glIsRenderbufferEXT"); + glad_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) load(userptr, "glRenderbufferStorageEXT"); +} +static void glad_gl_load_GL_EXT_geometry_shader4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_geometry_shader4) return; + glad_glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) load(userptr, "glProgramParameteriEXT"); +} +static void glad_gl_load_GL_EXT_gpu_program_parameters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_gpu_program_parameters) return; + glad_glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) load(userptr, "glProgramEnvParameters4fvEXT"); + glad_glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) load(userptr, "glProgramLocalParameters4fvEXT"); +} +static void glad_gl_load_GL_EXT_gpu_shader4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_gpu_shader4) return; + glad_glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC) load(userptr, "glBindFragDataLocationEXT"); + glad_glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC) load(userptr, "glGetFragDataLocationEXT"); + glad_glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC) load(userptr, "glGetUniformuivEXT"); + glad_glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC) load(userptr, "glGetVertexAttribIivEXT"); + glad_glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC) load(userptr, "glGetVertexAttribIuivEXT"); + glad_glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC) load(userptr, "glUniform1uiEXT"); + glad_glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC) load(userptr, "glUniform1uivEXT"); + glad_glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC) load(userptr, "glUniform2uiEXT"); + glad_glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC) load(userptr, "glUniform2uivEXT"); + glad_glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC) load(userptr, "glUniform3uiEXT"); + glad_glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC) load(userptr, "glUniform3uivEXT"); + glad_glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC) load(userptr, "glUniform4uiEXT"); + glad_glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC) load(userptr, "glUniform4uivEXT"); + glad_glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC) load(userptr, "glVertexAttribI1iEXT"); + glad_glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC) load(userptr, "glVertexAttribI1ivEXT"); + glad_glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC) load(userptr, "glVertexAttribI1uiEXT"); + glad_glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC) load(userptr, "glVertexAttribI1uivEXT"); + glad_glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC) load(userptr, "glVertexAttribI2iEXT"); + glad_glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC) load(userptr, "glVertexAttribI2ivEXT"); + glad_glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC) load(userptr, "glVertexAttribI2uiEXT"); + glad_glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC) load(userptr, "glVertexAttribI2uivEXT"); + glad_glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC) load(userptr, "glVertexAttribI3iEXT"); + glad_glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC) load(userptr, "glVertexAttribI3ivEXT"); + glad_glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC) load(userptr, "glVertexAttribI3uiEXT"); + glad_glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC) load(userptr, "glVertexAttribI3uivEXT"); + glad_glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC) load(userptr, "glVertexAttribI4bvEXT"); + glad_glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC) load(userptr, "glVertexAttribI4iEXT"); + glad_glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC) load(userptr, "glVertexAttribI4ivEXT"); + glad_glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC) load(userptr, "glVertexAttribI4svEXT"); + glad_glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC) load(userptr, "glVertexAttribI4ubvEXT"); + glad_glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC) load(userptr, "glVertexAttribI4uiEXT"); + glad_glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC) load(userptr, "glVertexAttribI4uivEXT"); + glad_glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC) load(userptr, "glVertexAttribI4usvEXT"); + glad_glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC) load(userptr, "glVertexAttribIPointerEXT"); +} +static void glad_gl_load_GL_EXT_histogram( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_histogram) return; + glad_glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC) load(userptr, "glGetHistogramEXT"); + glad_glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) load(userptr, "glGetHistogramParameterfvEXT"); + glad_glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) load(userptr, "glGetHistogramParameterivEXT"); + glad_glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC) load(userptr, "glGetMinmaxEXT"); + glad_glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC) load(userptr, "glGetMinmaxParameterfvEXT"); + glad_glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC) load(userptr, "glGetMinmaxParameterivEXT"); + glad_glHistogramEXT = (PFNGLHISTOGRAMEXTPROC) load(userptr, "glHistogramEXT"); + glad_glMinmaxEXT = (PFNGLMINMAXEXTPROC) load(userptr, "glMinmaxEXT"); + glad_glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC) load(userptr, "glResetHistogramEXT"); + glad_glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC) load(userptr, "glResetMinmaxEXT"); +} +static void glad_gl_load_GL_EXT_index_func( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_index_func) return; + glad_glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC) load(userptr, "glIndexFuncEXT"); +} +static void glad_gl_load_GL_EXT_index_material( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_index_material) return; + glad_glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC) load(userptr, "glIndexMaterialEXT"); +} +static void glad_gl_load_GL_EXT_light_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_light_texture) return; + glad_glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC) load(userptr, "glApplyTextureEXT"); + glad_glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC) load(userptr, "glTextureLightEXT"); + glad_glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC) load(userptr, "glTextureMaterialEXT"); +} +static void glad_gl_load_GL_EXT_memory_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_memory_object) return; + glad_glBufferStorageMemEXT = (PFNGLBUFFERSTORAGEMEMEXTPROC) load(userptr, "glBufferStorageMemEXT"); + glad_glCreateMemoryObjectsEXT = (PFNGLCREATEMEMORYOBJECTSEXTPROC) load(userptr, "glCreateMemoryObjectsEXT"); + glad_glDeleteMemoryObjectsEXT = (PFNGLDELETEMEMORYOBJECTSEXTPROC) load(userptr, "glDeleteMemoryObjectsEXT"); + glad_glGetMemoryObjectParameterivEXT = (PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) load(userptr, "glGetMemoryObjectParameterivEXT"); + glad_glGetUnsignedBytei_vEXT = (PFNGLGETUNSIGNEDBYTEI_VEXTPROC) load(userptr, "glGetUnsignedBytei_vEXT"); + glad_glGetUnsignedBytevEXT = (PFNGLGETUNSIGNEDBYTEVEXTPROC) load(userptr, "glGetUnsignedBytevEXT"); + glad_glIsMemoryObjectEXT = (PFNGLISMEMORYOBJECTEXTPROC) load(userptr, "glIsMemoryObjectEXT"); + glad_glMemoryObjectParameterivEXT = (PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) load(userptr, "glMemoryObjectParameterivEXT"); + glad_glNamedBufferStorageMemEXT = (PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) load(userptr, "glNamedBufferStorageMemEXT"); + glad_glTexStorageMem1DEXT = (PFNGLTEXSTORAGEMEM1DEXTPROC) load(userptr, "glTexStorageMem1DEXT"); + glad_glTexStorageMem2DEXT = (PFNGLTEXSTORAGEMEM2DEXTPROC) load(userptr, "glTexStorageMem2DEXT"); + glad_glTexStorageMem2DMultisampleEXT = (PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) load(userptr, "glTexStorageMem2DMultisampleEXT"); + glad_glTexStorageMem3DEXT = (PFNGLTEXSTORAGEMEM3DEXTPROC) load(userptr, "glTexStorageMem3DEXT"); + glad_glTexStorageMem3DMultisampleEXT = (PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) load(userptr, "glTexStorageMem3DMultisampleEXT"); + glad_glTextureStorageMem1DEXT = (PFNGLTEXTURESTORAGEMEM1DEXTPROC) load(userptr, "glTextureStorageMem1DEXT"); + glad_glTextureStorageMem2DEXT = (PFNGLTEXTURESTORAGEMEM2DEXTPROC) load(userptr, "glTextureStorageMem2DEXT"); + glad_glTextureStorageMem2DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) load(userptr, "glTextureStorageMem2DMultisampleEXT"); + glad_glTextureStorageMem3DEXT = (PFNGLTEXTURESTORAGEMEM3DEXTPROC) load(userptr, "glTextureStorageMem3DEXT"); + glad_glTextureStorageMem3DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) load(userptr, "glTextureStorageMem3DMultisampleEXT"); +} +static void glad_gl_load_GL_EXT_memory_object_fd( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_memory_object_fd) return; + glad_glImportMemoryFdEXT = (PFNGLIMPORTMEMORYFDEXTPROC) load(userptr, "glImportMemoryFdEXT"); +} +static void glad_gl_load_GL_EXT_memory_object_win32( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_memory_object_win32) return; + glad_glImportMemoryWin32HandleEXT = (PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) load(userptr, "glImportMemoryWin32HandleEXT"); + glad_glImportMemoryWin32NameEXT = (PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) load(userptr, "glImportMemoryWin32NameEXT"); +} +static void glad_gl_load_GL_EXT_multi_draw_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multi_draw_arrays) return; + glad_glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) load(userptr, "glMultiDrawArraysEXT"); + glad_glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC) load(userptr, "glMultiDrawElementsEXT"); +} +static void glad_gl_load_GL_EXT_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multisample) return; + glad_glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC) load(userptr, "glSampleMaskEXT"); + glad_glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC) load(userptr, "glSamplePatternEXT"); +} +static void glad_gl_load_GL_EXT_paletted_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_paletted_texture) return; + glad_glColorTableEXT = (PFNGLCOLORTABLEEXTPROC) load(userptr, "glColorTableEXT"); + glad_glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC) load(userptr, "glGetColorTableEXT"); + glad_glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) load(userptr, "glGetColorTableParameterfvEXT"); + glad_glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) load(userptr, "glGetColorTableParameterivEXT"); +} +static void glad_gl_load_GL_EXT_pixel_transform( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_pixel_transform) return; + glad_glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) load(userptr, "glGetPixelTransformParameterfvEXT"); + glad_glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) load(userptr, "glGetPixelTransformParameterivEXT"); + glad_glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) load(userptr, "glPixelTransformParameterfEXT"); + glad_glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) load(userptr, "glPixelTransformParameterfvEXT"); + glad_glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) load(userptr, "glPixelTransformParameteriEXT"); + glad_glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) load(userptr, "glPixelTransformParameterivEXT"); +} +static void glad_gl_load_GL_EXT_point_parameters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_point_parameters) return; + glad_glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC) load(userptr, "glPointParameterfEXT"); + glad_glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC) load(userptr, "glPointParameterfvEXT"); +} +static void glad_gl_load_GL_EXT_polygon_offset( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_polygon_offset) return; + glad_glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC) load(userptr, "glPolygonOffsetEXT"); +} +static void glad_gl_load_GL_EXT_polygon_offset_clamp( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_polygon_offset_clamp) return; + glad_glPolygonOffsetClampEXT = (PFNGLPOLYGONOFFSETCLAMPEXTPROC) load(userptr, "glPolygonOffsetClampEXT"); +} +static void glad_gl_load_GL_EXT_provoking_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_provoking_vertex) return; + glad_glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC) load(userptr, "glProvokingVertexEXT"); +} +static void glad_gl_load_GL_EXT_raster_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_raster_multisample) return; + glad_glRasterSamplesEXT = (PFNGLRASTERSAMPLESEXTPROC) load(userptr, "glRasterSamplesEXT"); +} +static void glad_gl_load_GL_EXT_secondary_color( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_secondary_color) return; + glad_glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC) load(userptr, "glSecondaryColor3bEXT"); + glad_glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC) load(userptr, "glSecondaryColor3bvEXT"); + glad_glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC) load(userptr, "glSecondaryColor3dEXT"); + glad_glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC) load(userptr, "glSecondaryColor3dvEXT"); + glad_glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC) load(userptr, "glSecondaryColor3fEXT"); + glad_glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC) load(userptr, "glSecondaryColor3fvEXT"); + glad_glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC) load(userptr, "glSecondaryColor3iEXT"); + glad_glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC) load(userptr, "glSecondaryColor3ivEXT"); + glad_glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC) load(userptr, "glSecondaryColor3sEXT"); + glad_glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC) load(userptr, "glSecondaryColor3svEXT"); + glad_glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC) load(userptr, "glSecondaryColor3ubEXT"); + glad_glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC) load(userptr, "glSecondaryColor3ubvEXT"); + glad_glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC) load(userptr, "glSecondaryColor3uiEXT"); + glad_glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC) load(userptr, "glSecondaryColor3uivEXT"); + glad_glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC) load(userptr, "glSecondaryColor3usEXT"); + glad_glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC) load(userptr, "glSecondaryColor3usvEXT"); + glad_glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC) load(userptr, "glSecondaryColorPointerEXT"); +} +static void glad_gl_load_GL_EXT_semaphore( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_semaphore) return; + glad_glDeleteSemaphoresEXT = (PFNGLDELETESEMAPHORESEXTPROC) load(userptr, "glDeleteSemaphoresEXT"); + glad_glGenSemaphoresEXT = (PFNGLGENSEMAPHORESEXTPROC) load(userptr, "glGenSemaphoresEXT"); + glad_glGetSemaphoreParameterui64vEXT = (PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) load(userptr, "glGetSemaphoreParameterui64vEXT"); + glad_glGetUnsignedBytei_vEXT = (PFNGLGETUNSIGNEDBYTEI_VEXTPROC) load(userptr, "glGetUnsignedBytei_vEXT"); + glad_glGetUnsignedBytevEXT = (PFNGLGETUNSIGNEDBYTEVEXTPROC) load(userptr, "glGetUnsignedBytevEXT"); + glad_glIsSemaphoreEXT = (PFNGLISSEMAPHOREEXTPROC) load(userptr, "glIsSemaphoreEXT"); + glad_glSemaphoreParameterui64vEXT = (PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) load(userptr, "glSemaphoreParameterui64vEXT"); + glad_glSignalSemaphoreEXT = (PFNGLSIGNALSEMAPHOREEXTPROC) load(userptr, "glSignalSemaphoreEXT"); + glad_glWaitSemaphoreEXT = (PFNGLWAITSEMAPHOREEXTPROC) load(userptr, "glWaitSemaphoreEXT"); +} +static void glad_gl_load_GL_EXT_semaphore_fd( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_semaphore_fd) return; + glad_glImportSemaphoreFdEXT = (PFNGLIMPORTSEMAPHOREFDEXTPROC) load(userptr, "glImportSemaphoreFdEXT"); +} +static void glad_gl_load_GL_EXT_semaphore_win32( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_semaphore_win32) return; + glad_glImportSemaphoreWin32HandleEXT = (PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) load(userptr, "glImportSemaphoreWin32HandleEXT"); + glad_glImportSemaphoreWin32NameEXT = (PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) load(userptr, "glImportSemaphoreWin32NameEXT"); +} +static void glad_gl_load_GL_EXT_shader_framebuffer_fetch_non_coherent( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent) return; + glad_glFramebufferFetchBarrierEXT = (PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) load(userptr, "glFramebufferFetchBarrierEXT"); +} +static void glad_gl_load_GL_EXT_shader_image_load_store( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_shader_image_load_store) return; + glad_glBindImageTextureEXT = (PFNGLBINDIMAGETEXTUREEXTPROC) load(userptr, "glBindImageTextureEXT"); + glad_glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC) load(userptr, "glMemoryBarrierEXT"); +} +static void glad_gl_load_GL_EXT_stencil_clear_tag( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_stencil_clear_tag) return; + glad_glStencilClearTagEXT = (PFNGLSTENCILCLEARTAGEXTPROC) load(userptr, "glStencilClearTagEXT"); +} +static void glad_gl_load_GL_EXT_stencil_two_side( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_stencil_two_side) return; + glad_glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC) load(userptr, "glActiveStencilFaceEXT"); +} +static void glad_gl_load_GL_EXT_subtexture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_subtexture) return; + glad_glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC) load(userptr, "glTexSubImage1DEXT"); + glad_glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC) load(userptr, "glTexSubImage2DEXT"); +} +static void glad_gl_load_GL_EXT_texture3D( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture3D) return; + glad_glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC) load(userptr, "glTexImage3DEXT"); + glad_glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC) load(userptr, "glTexSubImage3DEXT"); +} +static void glad_gl_load_GL_EXT_texture_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_array) return; + glad_glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) load(userptr, "glFramebufferTextureLayerEXT"); +} +static void glad_gl_load_GL_EXT_texture_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_buffer_object) return; + glad_glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC) load(userptr, "glTexBufferEXT"); +} +static void glad_gl_load_GL_EXT_texture_integer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_integer) return; + glad_glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC) load(userptr, "glClearColorIiEXT"); + glad_glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC) load(userptr, "glClearColorIuiEXT"); + glad_glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC) load(userptr, "glGetTexParameterIivEXT"); + glad_glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC) load(userptr, "glGetTexParameterIuivEXT"); + glad_glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC) load(userptr, "glTexParameterIivEXT"); + glad_glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC) load(userptr, "glTexParameterIuivEXT"); +} +static void glad_gl_load_GL_EXT_texture_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_object) return; + glad_glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC) load(userptr, "glAreTexturesResidentEXT"); + glad_glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC) load(userptr, "glBindTextureEXT"); + glad_glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC) load(userptr, "glDeleteTexturesEXT"); + glad_glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC) load(userptr, "glGenTexturesEXT"); + glad_glIsTextureEXT = (PFNGLISTEXTUREEXTPROC) load(userptr, "glIsTextureEXT"); + glad_glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC) load(userptr, "glPrioritizeTexturesEXT"); +} +static void glad_gl_load_GL_EXT_texture_perturb_normal( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_perturb_normal) return; + glad_glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC) load(userptr, "glTextureNormalEXT"); +} +static void glad_gl_load_GL_EXT_texture_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_storage) return; + glad_glTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC) load(userptr, "glTexStorage1DEXT"); + glad_glTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC) load(userptr, "glTexStorage2DEXT"); + glad_glTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC) load(userptr, "glTexStorage3DEXT"); + glad_glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) load(userptr, "glTextureStorage1DEXT"); + glad_glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) load(userptr, "glTextureStorage2DEXT"); + glad_glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) load(userptr, "glTextureStorage3DEXT"); +} +static void glad_gl_load_GL_EXT_timer_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_timer_query) return; + glad_glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC) load(userptr, "glGetQueryObjecti64vEXT"); + glad_glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) load(userptr, "glGetQueryObjectui64vEXT"); +} +static void glad_gl_load_GL_EXT_transform_feedback( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_transform_feedback) return; + glad_glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) load(userptr, "glBeginTransformFeedbackEXT"); + glad_glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC) load(userptr, "glBindBufferBaseEXT"); + glad_glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC) load(userptr, "glBindBufferOffsetEXT"); + glad_glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC) load(userptr, "glBindBufferRangeEXT"); + glad_glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC) load(userptr, "glEndTransformFeedbackEXT"); + glad_glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) load(userptr, "glGetTransformFeedbackVaryingEXT"); + glad_glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) load(userptr, "glTransformFeedbackVaryingsEXT"); +} +static void glad_gl_load_GL_EXT_vertex_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_vertex_array) return; + glad_glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC) load(userptr, "glArrayElementEXT"); + glad_glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC) load(userptr, "glColorPointerEXT"); + glad_glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC) load(userptr, "glDrawArraysEXT"); + glad_glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC) load(userptr, "glEdgeFlagPointerEXT"); + glad_glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC) load(userptr, "glGetPointervEXT"); + glad_glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC) load(userptr, "glIndexPointerEXT"); + glad_glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC) load(userptr, "glNormalPointerEXT"); + glad_glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC) load(userptr, "glTexCoordPointerEXT"); + glad_glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC) load(userptr, "glVertexPointerEXT"); +} +static void glad_gl_load_GL_EXT_vertex_attrib_64bit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_vertex_attrib_64bit) return; + glad_glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC) load(userptr, "glGetVertexAttribLdvEXT"); + glad_glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC) load(userptr, "glVertexAttribL1dEXT"); + glad_glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC) load(userptr, "glVertexAttribL1dvEXT"); + glad_glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC) load(userptr, "glVertexAttribL2dEXT"); + glad_glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC) load(userptr, "glVertexAttribL2dvEXT"); + glad_glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC) load(userptr, "glVertexAttribL3dEXT"); + glad_glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC) load(userptr, "glVertexAttribL3dvEXT"); + glad_glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC) load(userptr, "glVertexAttribL4dEXT"); + glad_glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC) load(userptr, "glVertexAttribL4dvEXT"); + glad_glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC) load(userptr, "glVertexAttribLPointerEXT"); +} +static void glad_gl_load_GL_EXT_vertex_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_vertex_shader) return; + glad_glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC) load(userptr, "glBeginVertexShaderEXT"); + glad_glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC) load(userptr, "glBindLightParameterEXT"); + glad_glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC) load(userptr, "glBindMaterialParameterEXT"); + glad_glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC) load(userptr, "glBindParameterEXT"); + glad_glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC) load(userptr, "glBindTexGenParameterEXT"); + glad_glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) load(userptr, "glBindTextureUnitParameterEXT"); + glad_glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC) load(userptr, "glBindVertexShaderEXT"); + glad_glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC) load(userptr, "glDeleteVertexShaderEXT"); + glad_glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) load(userptr, "glDisableVariantClientStateEXT"); + glad_glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) load(userptr, "glEnableVariantClientStateEXT"); + glad_glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC) load(userptr, "glEndVertexShaderEXT"); + glad_glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC) load(userptr, "glExtractComponentEXT"); + glad_glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC) load(userptr, "glGenSymbolsEXT"); + glad_glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC) load(userptr, "glGenVertexShadersEXT"); + glad_glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC) load(userptr, "glGetInvariantBooleanvEXT"); + glad_glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC) load(userptr, "glGetInvariantFloatvEXT"); + glad_glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC) load(userptr, "glGetInvariantIntegervEXT"); + glad_glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) load(userptr, "glGetLocalConstantBooleanvEXT"); + glad_glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC) load(userptr, "glGetLocalConstantFloatvEXT"); + glad_glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) load(userptr, "glGetLocalConstantIntegervEXT"); + glad_glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC) load(userptr, "glGetVariantBooleanvEXT"); + glad_glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC) load(userptr, "glGetVariantFloatvEXT"); + glad_glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC) load(userptr, "glGetVariantIntegervEXT"); + glad_glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC) load(userptr, "glGetVariantPointervEXT"); + glad_glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC) load(userptr, "glInsertComponentEXT"); + glad_glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC) load(userptr, "glIsVariantEnabledEXT"); + glad_glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC) load(userptr, "glSetInvariantEXT"); + glad_glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC) load(userptr, "glSetLocalConstantEXT"); + glad_glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC) load(userptr, "glShaderOp1EXT"); + glad_glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC) load(userptr, "glShaderOp2EXT"); + glad_glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC) load(userptr, "glShaderOp3EXT"); + glad_glSwizzleEXT = (PFNGLSWIZZLEEXTPROC) load(userptr, "glSwizzleEXT"); + glad_glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC) load(userptr, "glVariantPointerEXT"); + glad_glVariantbvEXT = (PFNGLVARIANTBVEXTPROC) load(userptr, "glVariantbvEXT"); + glad_glVariantdvEXT = (PFNGLVARIANTDVEXTPROC) load(userptr, "glVariantdvEXT"); + glad_glVariantfvEXT = (PFNGLVARIANTFVEXTPROC) load(userptr, "glVariantfvEXT"); + glad_glVariantivEXT = (PFNGLVARIANTIVEXTPROC) load(userptr, "glVariantivEXT"); + glad_glVariantsvEXT = (PFNGLVARIANTSVEXTPROC) load(userptr, "glVariantsvEXT"); + glad_glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC) load(userptr, "glVariantubvEXT"); + glad_glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC) load(userptr, "glVariantuivEXT"); + glad_glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC) load(userptr, "glVariantusvEXT"); + glad_glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC) load(userptr, "glWriteMaskEXT"); +} +static void glad_gl_load_GL_EXT_vertex_weighting( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_vertex_weighting) return; + glad_glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC) load(userptr, "glVertexWeightPointerEXT"); + glad_glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC) load(userptr, "glVertexWeightfEXT"); + glad_glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC) load(userptr, "glVertexWeightfvEXT"); +} +static void glad_gl_load_GL_EXT_win32_keyed_mutex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_win32_keyed_mutex) return; + glad_glAcquireKeyedMutexWin32EXT = (PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) load(userptr, "glAcquireKeyedMutexWin32EXT"); + glad_glReleaseKeyedMutexWin32EXT = (PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) load(userptr, "glReleaseKeyedMutexWin32EXT"); +} +static void glad_gl_load_GL_EXT_window_rectangles( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_window_rectangles) return; + glad_glWindowRectanglesEXT = (PFNGLWINDOWRECTANGLESEXTPROC) load(userptr, "glWindowRectanglesEXT"); +} +static void glad_gl_load_GL_EXT_x11_sync_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_x11_sync_object) return; + glad_glImportSyncEXT = (PFNGLIMPORTSYNCEXTPROC) load(userptr, "glImportSyncEXT"); +} +static void glad_gl_load_GL_GREMEDY_frame_terminator( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_GREMEDY_frame_terminator) return; + glad_glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC) load(userptr, "glFrameTerminatorGREMEDY"); +} +static void glad_gl_load_GL_GREMEDY_string_marker( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_GREMEDY_string_marker) return; + glad_glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC) load(userptr, "glStringMarkerGREMEDY"); +} +static void glad_gl_load_GL_HP_image_transform( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_HP_image_transform) return; + glad_glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) load(userptr, "glGetImageTransformParameterfvHP"); + glad_glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) load(userptr, "glGetImageTransformParameterivHP"); + glad_glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC) load(userptr, "glImageTransformParameterfHP"); + glad_glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) load(userptr, "glImageTransformParameterfvHP"); + glad_glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC) load(userptr, "glImageTransformParameteriHP"); + glad_glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) load(userptr, "glImageTransformParameterivHP"); +} +static void glad_gl_load_GL_IBM_multimode_draw_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IBM_multimode_draw_arrays) return; + glad_glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC) load(userptr, "glMultiModeDrawArraysIBM"); + glad_glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC) load(userptr, "glMultiModeDrawElementsIBM"); +} +static void glad_gl_load_GL_IBM_static_data( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IBM_static_data) return; + glad_glFlushStaticDataIBM = (PFNGLFLUSHSTATICDATAIBMPROC) load(userptr, "glFlushStaticDataIBM"); +} +static void glad_gl_load_GL_IBM_vertex_array_lists( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IBM_vertex_array_lists) return; + glad_glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC) load(userptr, "glColorPointerListIBM"); + glad_glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC) load(userptr, "glEdgeFlagPointerListIBM"); + glad_glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC) load(userptr, "glFogCoordPointerListIBM"); + glad_glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC) load(userptr, "glIndexPointerListIBM"); + glad_glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC) load(userptr, "glNormalPointerListIBM"); + glad_glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) load(userptr, "glSecondaryColorPointerListIBM"); + glad_glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC) load(userptr, "glTexCoordPointerListIBM"); + glad_glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC) load(userptr, "glVertexPointerListIBM"); +} +static void glad_gl_load_GL_INGR_blend_func_separate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_INGR_blend_func_separate) return; + glad_glBlendFuncSeparateINGR = (PFNGLBLENDFUNCSEPARATEINGRPROC) load(userptr, "glBlendFuncSeparateINGR"); +} +static void glad_gl_load_GL_INTEL_framebuffer_CMAA( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_INTEL_framebuffer_CMAA) return; + glad_glApplyFramebufferAttachmentCMAAINTEL = (PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) load(userptr, "glApplyFramebufferAttachmentCMAAINTEL"); +} +static void glad_gl_load_GL_INTEL_map_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_INTEL_map_texture) return; + glad_glMapTexture2DINTEL = (PFNGLMAPTEXTURE2DINTELPROC) load(userptr, "glMapTexture2DINTEL"); + glad_glSyncTextureINTEL = (PFNGLSYNCTEXTUREINTELPROC) load(userptr, "glSyncTextureINTEL"); + glad_glUnmapTexture2DINTEL = (PFNGLUNMAPTEXTURE2DINTELPROC) load(userptr, "glUnmapTexture2DINTEL"); +} +static void glad_gl_load_GL_INTEL_parallel_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_INTEL_parallel_arrays) return; + glad_glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC) load(userptr, "glColorPointervINTEL"); + glad_glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC) load(userptr, "glNormalPointervINTEL"); + glad_glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC) load(userptr, "glTexCoordPointervINTEL"); + glad_glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC) load(userptr, "glVertexPointervINTEL"); +} +static void glad_gl_load_GL_INTEL_performance_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_INTEL_performance_query) return; + glad_glBeginPerfQueryINTEL = (PFNGLBEGINPERFQUERYINTELPROC) load(userptr, "glBeginPerfQueryINTEL"); + glad_glCreatePerfQueryINTEL = (PFNGLCREATEPERFQUERYINTELPROC) load(userptr, "glCreatePerfQueryINTEL"); + glad_glDeletePerfQueryINTEL = (PFNGLDELETEPERFQUERYINTELPROC) load(userptr, "glDeletePerfQueryINTEL"); + glad_glEndPerfQueryINTEL = (PFNGLENDPERFQUERYINTELPROC) load(userptr, "glEndPerfQueryINTEL"); + glad_glGetFirstPerfQueryIdINTEL = (PFNGLGETFIRSTPERFQUERYIDINTELPROC) load(userptr, "glGetFirstPerfQueryIdINTEL"); + glad_glGetNextPerfQueryIdINTEL = (PFNGLGETNEXTPERFQUERYIDINTELPROC) load(userptr, "glGetNextPerfQueryIdINTEL"); + glad_glGetPerfCounterInfoINTEL = (PFNGLGETPERFCOUNTERINFOINTELPROC) load(userptr, "glGetPerfCounterInfoINTEL"); + glad_glGetPerfQueryDataINTEL = (PFNGLGETPERFQUERYDATAINTELPROC) load(userptr, "glGetPerfQueryDataINTEL"); + glad_glGetPerfQueryIdByNameINTEL = (PFNGLGETPERFQUERYIDBYNAMEINTELPROC) load(userptr, "glGetPerfQueryIdByNameINTEL"); + glad_glGetPerfQueryInfoINTEL = (PFNGLGETPERFQUERYINFOINTELPROC) load(userptr, "glGetPerfQueryInfoINTEL"); +} +static void glad_gl_load_GL_KHR_blend_equation_advanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_blend_equation_advanced) return; + glad_glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC) load(userptr, "glBlendBarrierKHR"); +} +static void glad_gl_load_GL_KHR_debug( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_debug) return; + glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); + glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC) load(userptr, "glDebugMessageCallbackKHR"); + glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); + glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC) load(userptr, "glDebugMessageControlKHR"); + glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); + glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC) load(userptr, "glDebugMessageInsertKHR"); + glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); + glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC) load(userptr, "glGetDebugMessageLogKHR"); + glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); + glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC) load(userptr, "glGetObjectLabelKHR"); + glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); + glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC) load(userptr, "glGetObjectPtrLabelKHR"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC) load(userptr, "glGetPointervKHR"); + glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); + glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC) load(userptr, "glObjectLabelKHR"); + glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); + glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC) load(userptr, "glObjectPtrLabelKHR"); + glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); + glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC) load(userptr, "glPopDebugGroupKHR"); + glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); + glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC) load(userptr, "glPushDebugGroupKHR"); +} +static void glad_gl_load_GL_KHR_parallel_shader_compile( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_parallel_shader_compile) return; + glad_glMaxShaderCompilerThreadsKHR = (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) load(userptr, "glMaxShaderCompilerThreadsKHR"); +} +static void glad_gl_load_GL_KHR_robustness( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_robustness) return; + glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus"); + glad_glGetGraphicsResetStatusKHR = (PFNGLGETGRAPHICSRESETSTATUSKHRPROC) load(userptr, "glGetGraphicsResetStatusKHR"); + glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv"); + glad_glGetnUniformfvKHR = (PFNGLGETNUNIFORMFVKHRPROC) load(userptr, "glGetnUniformfvKHR"); + glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv"); + glad_glGetnUniformivKHR = (PFNGLGETNUNIFORMIVKHRPROC) load(userptr, "glGetnUniformivKHR"); + glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv"); + glad_glGetnUniformuivKHR = (PFNGLGETNUNIFORMUIVKHRPROC) load(userptr, "glGetnUniformuivKHR"); + glad_glReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels"); + glad_glReadnPixelsKHR = (PFNGLREADNPIXELSKHRPROC) load(userptr, "glReadnPixelsKHR"); +} +static void glad_gl_load_GL_MESA_framebuffer_flip_y( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_MESA_framebuffer_flip_y) return; + glad_glFramebufferParameteriMESA = (PFNGLFRAMEBUFFERPARAMETERIMESAPROC) load(userptr, "glFramebufferParameteriMESA"); + glad_glGetFramebufferParameterivMESA = (PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) load(userptr, "glGetFramebufferParameterivMESA"); +} +static void glad_gl_load_GL_MESA_resize_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_MESA_resize_buffers) return; + glad_glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC) load(userptr, "glResizeBuffersMESA"); +} +static void glad_gl_load_GL_MESA_window_pos( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_MESA_window_pos) return; + glad_glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC) load(userptr, "glWindowPos2dMESA"); + glad_glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC) load(userptr, "glWindowPos2dvMESA"); + glad_glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC) load(userptr, "glWindowPos2fMESA"); + glad_glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC) load(userptr, "glWindowPos2fvMESA"); + glad_glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC) load(userptr, "glWindowPos2iMESA"); + glad_glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC) load(userptr, "glWindowPos2ivMESA"); + glad_glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC) load(userptr, "glWindowPos2sMESA"); + glad_glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC) load(userptr, "glWindowPos2svMESA"); + glad_glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC) load(userptr, "glWindowPos3dMESA"); + glad_glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC) load(userptr, "glWindowPos3dvMESA"); + glad_glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC) load(userptr, "glWindowPos3fMESA"); + glad_glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC) load(userptr, "glWindowPos3fvMESA"); + glad_glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC) load(userptr, "glWindowPos3iMESA"); + glad_glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC) load(userptr, "glWindowPos3ivMESA"); + glad_glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC) load(userptr, "glWindowPos3sMESA"); + glad_glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC) load(userptr, "glWindowPos3svMESA"); + glad_glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC) load(userptr, "glWindowPos4dMESA"); + glad_glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC) load(userptr, "glWindowPos4dvMESA"); + glad_glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC) load(userptr, "glWindowPos4fMESA"); + glad_glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC) load(userptr, "glWindowPos4fvMESA"); + glad_glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC) load(userptr, "glWindowPos4iMESA"); + glad_glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC) load(userptr, "glWindowPos4ivMESA"); + glad_glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC) load(userptr, "glWindowPos4sMESA"); + glad_glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC) load(userptr, "glWindowPos4svMESA"); +} +static void glad_gl_load_GL_NVX_conditional_render( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NVX_conditional_render) return; + glad_glBeginConditionalRenderNVX = (PFNGLBEGINCONDITIONALRENDERNVXPROC) load(userptr, "glBeginConditionalRenderNVX"); + glad_glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC) load(userptr, "glEndConditionalRenderNVX"); +} +static void glad_gl_load_GL_NVX_gpu_multicast2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NVX_gpu_multicast2) return; + glad_glAsyncCopyBufferSubDataNVX = (PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) load(userptr, "glAsyncCopyBufferSubDataNVX"); + glad_glAsyncCopyImageSubDataNVX = (PFNGLASYNCCOPYIMAGESUBDATANVXPROC) load(userptr, "glAsyncCopyImageSubDataNVX"); + glad_glMulticastScissorArrayvNVX = (PFNGLMULTICASTSCISSORARRAYVNVXPROC) load(userptr, "glMulticastScissorArrayvNVX"); + glad_glMulticastViewportArrayvNVX = (PFNGLMULTICASTVIEWPORTARRAYVNVXPROC) load(userptr, "glMulticastViewportArrayvNVX"); + glad_glMulticastViewportPositionWScaleNVX = (PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC) load(userptr, "glMulticastViewportPositionWScaleNVX"); + glad_glUploadGpuMaskNVX = (PFNGLUPLOADGPUMASKNVXPROC) load(userptr, "glUploadGpuMaskNVX"); +} +static void glad_gl_load_GL_NVX_linked_gpu_multicast( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NVX_linked_gpu_multicast) return; + glad_glLGPUCopyImageSubDataNVX = (PFNGLLGPUCOPYIMAGESUBDATANVXPROC) load(userptr, "glLGPUCopyImageSubDataNVX"); + glad_glLGPUInterlockNVX = (PFNGLLGPUINTERLOCKNVXPROC) load(userptr, "glLGPUInterlockNVX"); + glad_glLGPUNamedBufferSubDataNVX = (PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) load(userptr, "glLGPUNamedBufferSubDataNVX"); +} +static void glad_gl_load_GL_NVX_progress_fence( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NVX_progress_fence) return; + glad_glClientWaitSemaphoreui64NVX = (PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC) load(userptr, "glClientWaitSemaphoreui64NVX"); + glad_glCreateProgressFenceNVX = (PFNGLCREATEPROGRESSFENCENVXPROC) load(userptr, "glCreateProgressFenceNVX"); + glad_glSignalSemaphoreui64NVX = (PFNGLSIGNALSEMAPHOREUI64NVXPROC) load(userptr, "glSignalSemaphoreui64NVX"); + glad_glWaitSemaphoreui64NVX = (PFNGLWAITSEMAPHOREUI64NVXPROC) load(userptr, "glWaitSemaphoreui64NVX"); +} +static void glad_gl_load_GL_NV_alpha_to_coverage_dither_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_alpha_to_coverage_dither_control) return; + glad_glAlphaToCoverageDitherControlNV = (PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC) load(userptr, "glAlphaToCoverageDitherControlNV"); +} +static void glad_gl_load_GL_NV_bindless_multi_draw_indirect( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_bindless_multi_draw_indirect) return; + glad_glMultiDrawArraysIndirectBindlessNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) load(userptr, "glMultiDrawArraysIndirectBindlessNV"); + glad_glMultiDrawElementsIndirectBindlessNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) load(userptr, "glMultiDrawElementsIndirectBindlessNV"); +} +static void glad_gl_load_GL_NV_bindless_multi_draw_indirect_count( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_bindless_multi_draw_indirect_count) return; + glad_glMultiDrawArraysIndirectBindlessCountNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) load(userptr, "glMultiDrawArraysIndirectBindlessCountNV"); + glad_glMultiDrawElementsIndirectBindlessCountNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) load(userptr, "glMultiDrawElementsIndirectBindlessCountNV"); +} +static void glad_gl_load_GL_NV_bindless_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_bindless_texture) return; + glad_glGetImageHandleNV = (PFNGLGETIMAGEHANDLENVPROC) load(userptr, "glGetImageHandleNV"); + glad_glGetTextureHandleNV = (PFNGLGETTEXTUREHANDLENVPROC) load(userptr, "glGetTextureHandleNV"); + glad_glGetTextureSamplerHandleNV = (PFNGLGETTEXTURESAMPLERHANDLENVPROC) load(userptr, "glGetTextureSamplerHandleNV"); + glad_glIsImageHandleResidentNV = (PFNGLISIMAGEHANDLERESIDENTNVPROC) load(userptr, "glIsImageHandleResidentNV"); + glad_glIsTextureHandleResidentNV = (PFNGLISTEXTUREHANDLERESIDENTNVPROC) load(userptr, "glIsTextureHandleResidentNV"); + glad_glMakeImageHandleNonResidentNV = (PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) load(userptr, "glMakeImageHandleNonResidentNV"); + glad_glMakeImageHandleResidentNV = (PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) load(userptr, "glMakeImageHandleResidentNV"); + glad_glMakeTextureHandleNonResidentNV = (PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) load(userptr, "glMakeTextureHandleNonResidentNV"); + glad_glMakeTextureHandleResidentNV = (PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) load(userptr, "glMakeTextureHandleResidentNV"); + glad_glProgramUniformHandleui64NV = (PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) load(userptr, "glProgramUniformHandleui64NV"); + glad_glProgramUniformHandleui64vNV = (PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) load(userptr, "glProgramUniformHandleui64vNV"); + glad_glUniformHandleui64NV = (PFNGLUNIFORMHANDLEUI64NVPROC) load(userptr, "glUniformHandleui64NV"); + glad_glUniformHandleui64vNV = (PFNGLUNIFORMHANDLEUI64VNVPROC) load(userptr, "glUniformHandleui64vNV"); +} +static void glad_gl_load_GL_NV_blend_equation_advanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_blend_equation_advanced) return; + glad_glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC) load(userptr, "glBlendBarrierNV"); + glad_glBlendParameteriNV = (PFNGLBLENDPARAMETERINVPROC) load(userptr, "glBlendParameteriNV"); +} +static void glad_gl_load_GL_NV_clip_space_w_scaling( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_clip_space_w_scaling) return; + glad_glViewportPositionWScaleNV = (PFNGLVIEWPORTPOSITIONWSCALENVPROC) load(userptr, "glViewportPositionWScaleNV"); +} +static void glad_gl_load_GL_NV_command_list( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_command_list) return; + glad_glCallCommandListNV = (PFNGLCALLCOMMANDLISTNVPROC) load(userptr, "glCallCommandListNV"); + glad_glCommandListSegmentsNV = (PFNGLCOMMANDLISTSEGMENTSNVPROC) load(userptr, "glCommandListSegmentsNV"); + glad_glCompileCommandListNV = (PFNGLCOMPILECOMMANDLISTNVPROC) load(userptr, "glCompileCommandListNV"); + glad_glCreateCommandListsNV = (PFNGLCREATECOMMANDLISTSNVPROC) load(userptr, "glCreateCommandListsNV"); + glad_glCreateStatesNV = (PFNGLCREATESTATESNVPROC) load(userptr, "glCreateStatesNV"); + glad_glDeleteCommandListsNV = (PFNGLDELETECOMMANDLISTSNVPROC) load(userptr, "glDeleteCommandListsNV"); + glad_glDeleteStatesNV = (PFNGLDELETESTATESNVPROC) load(userptr, "glDeleteStatesNV"); + glad_glDrawCommandsAddressNV = (PFNGLDRAWCOMMANDSADDRESSNVPROC) load(userptr, "glDrawCommandsAddressNV"); + glad_glDrawCommandsNV = (PFNGLDRAWCOMMANDSNVPROC) load(userptr, "glDrawCommandsNV"); + glad_glDrawCommandsStatesAddressNV = (PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) load(userptr, "glDrawCommandsStatesAddressNV"); + glad_glDrawCommandsStatesNV = (PFNGLDRAWCOMMANDSSTATESNVPROC) load(userptr, "glDrawCommandsStatesNV"); + glad_glGetCommandHeaderNV = (PFNGLGETCOMMANDHEADERNVPROC) load(userptr, "glGetCommandHeaderNV"); + glad_glGetStageIndexNV = (PFNGLGETSTAGEINDEXNVPROC) load(userptr, "glGetStageIndexNV"); + glad_glIsCommandListNV = (PFNGLISCOMMANDLISTNVPROC) load(userptr, "glIsCommandListNV"); + glad_glIsStateNV = (PFNGLISSTATENVPROC) load(userptr, "glIsStateNV"); + glad_glListDrawCommandsStatesClientNV = (PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) load(userptr, "glListDrawCommandsStatesClientNV"); + glad_glStateCaptureNV = (PFNGLSTATECAPTURENVPROC) load(userptr, "glStateCaptureNV"); +} +static void glad_gl_load_GL_NV_conditional_render( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_conditional_render) return; + glad_glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC) load(userptr, "glBeginConditionalRenderNV"); + glad_glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC) load(userptr, "glEndConditionalRenderNV"); +} +static void glad_gl_load_GL_NV_conservative_raster( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_conservative_raster) return; + glad_glSubpixelPrecisionBiasNV = (PFNGLSUBPIXELPRECISIONBIASNVPROC) load(userptr, "glSubpixelPrecisionBiasNV"); +} +static void glad_gl_load_GL_NV_conservative_raster_dilate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_conservative_raster_dilate) return; + glad_glConservativeRasterParameterfNV = (PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) load(userptr, "glConservativeRasterParameterfNV"); +} +static void glad_gl_load_GL_NV_conservative_raster_pre_snap_triangles( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_conservative_raster_pre_snap_triangles) return; + glad_glConservativeRasterParameteriNV = (PFNGLCONSERVATIVERASTERPARAMETERINVPROC) load(userptr, "glConservativeRasterParameteriNV"); +} +static void glad_gl_load_GL_NV_copy_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_copy_image) return; + glad_glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC) load(userptr, "glCopyImageSubDataNV"); +} +static void glad_gl_load_GL_NV_depth_buffer_float( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_depth_buffer_float) return; + glad_glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC) load(userptr, "glClearDepthdNV"); + glad_glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC) load(userptr, "glDepthBoundsdNV"); + glad_glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC) load(userptr, "glDepthRangedNV"); +} +static void glad_gl_load_GL_NV_draw_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_draw_texture) return; + glad_glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC) load(userptr, "glDrawTextureNV"); +} +static void glad_gl_load_GL_NV_draw_vulkan_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_draw_vulkan_image) return; + glad_glDrawVkImageNV = (PFNGLDRAWVKIMAGENVPROC) load(userptr, "glDrawVkImageNV"); + glad_glGetVkProcAddrNV = (PFNGLGETVKPROCADDRNVPROC) load(userptr, "glGetVkProcAddrNV"); + glad_glSignalVkFenceNV = (PFNGLSIGNALVKFENCENVPROC) load(userptr, "glSignalVkFenceNV"); + glad_glSignalVkSemaphoreNV = (PFNGLSIGNALVKSEMAPHORENVPROC) load(userptr, "glSignalVkSemaphoreNV"); + glad_glWaitVkSemaphoreNV = (PFNGLWAITVKSEMAPHORENVPROC) load(userptr, "glWaitVkSemaphoreNV"); +} +static void glad_gl_load_GL_NV_evaluators( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_evaluators) return; + glad_glEvalMapsNV = (PFNGLEVALMAPSNVPROC) load(userptr, "glEvalMapsNV"); + glad_glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC) load(userptr, "glGetMapAttribParameterfvNV"); + glad_glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC) load(userptr, "glGetMapAttribParameterivNV"); + glad_glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC) load(userptr, "glGetMapControlPointsNV"); + glad_glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC) load(userptr, "glGetMapParameterfvNV"); + glad_glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC) load(userptr, "glGetMapParameterivNV"); + glad_glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC) load(userptr, "glMapControlPointsNV"); + glad_glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC) load(userptr, "glMapParameterfvNV"); + glad_glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC) load(userptr, "glMapParameterivNV"); +} +static void glad_gl_load_GL_NV_explicit_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_explicit_multisample) return; + glad_glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC) load(userptr, "glGetMultisamplefvNV"); + glad_glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC) load(userptr, "glSampleMaskIndexedNV"); + glad_glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC) load(userptr, "glTexRenderbufferNV"); +} +static void glad_gl_load_GL_NV_fence( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_fence) return; + glad_glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) load(userptr, "glDeleteFencesNV"); + glad_glFinishFenceNV = (PFNGLFINISHFENCENVPROC) load(userptr, "glFinishFenceNV"); + glad_glGenFencesNV = (PFNGLGENFENCESNVPROC) load(userptr, "glGenFencesNV"); + glad_glGetFenceivNV = (PFNGLGETFENCEIVNVPROC) load(userptr, "glGetFenceivNV"); + glad_glIsFenceNV = (PFNGLISFENCENVPROC) load(userptr, "glIsFenceNV"); + glad_glSetFenceNV = (PFNGLSETFENCENVPROC) load(userptr, "glSetFenceNV"); + glad_glTestFenceNV = (PFNGLTESTFENCENVPROC) load(userptr, "glTestFenceNV"); +} +static void glad_gl_load_GL_NV_fragment_coverage_to_color( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_fragment_coverage_to_color) return; + glad_glFragmentCoverageColorNV = (PFNGLFRAGMENTCOVERAGECOLORNVPROC) load(userptr, "glFragmentCoverageColorNV"); +} +static void glad_gl_load_GL_NV_fragment_program( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_fragment_program) return; + glad_glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) load(userptr, "glGetProgramNamedParameterdvNV"); + glad_glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) load(userptr, "glGetProgramNamedParameterfvNV"); + glad_glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) load(userptr, "glProgramNamedParameter4dNV"); + glad_glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) load(userptr, "glProgramNamedParameter4dvNV"); + glad_glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) load(userptr, "glProgramNamedParameter4fNV"); + glad_glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) load(userptr, "glProgramNamedParameter4fvNV"); +} +static void glad_gl_load_GL_NV_framebuffer_mixed_samples( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_framebuffer_mixed_samples) return; + glad_glCoverageModulationNV = (PFNGLCOVERAGEMODULATIONNVPROC) load(userptr, "glCoverageModulationNV"); + glad_glCoverageModulationTableNV = (PFNGLCOVERAGEMODULATIONTABLENVPROC) load(userptr, "glCoverageModulationTableNV"); + glad_glGetCoverageModulationTableNV = (PFNGLGETCOVERAGEMODULATIONTABLENVPROC) load(userptr, "glGetCoverageModulationTableNV"); + glad_glRasterSamplesEXT = (PFNGLRASTERSAMPLESEXTPROC) load(userptr, "glRasterSamplesEXT"); +} +static void glad_gl_load_GL_NV_framebuffer_multisample_coverage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_framebuffer_multisample_coverage) return; + glad_glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) load(userptr, "glRenderbufferStorageMultisampleCoverageNV"); +} +static void glad_gl_load_GL_NV_geometry_program4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_geometry_program4) return; + glad_glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC) load(userptr, "glFramebufferTextureEXT"); + glad_glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) load(userptr, "glFramebufferTextureFaceEXT"); + glad_glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) load(userptr, "glFramebufferTextureLayerEXT"); + glad_glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC) load(userptr, "glProgramVertexLimitNV"); +} +static void glad_gl_load_GL_NV_gpu_multicast( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_gpu_multicast) return; + glad_glMulticastBarrierNV = (PFNGLMULTICASTBARRIERNVPROC) load(userptr, "glMulticastBarrierNV"); + glad_glMulticastBlitFramebufferNV = (PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) load(userptr, "glMulticastBlitFramebufferNV"); + glad_glMulticastBufferSubDataNV = (PFNGLMULTICASTBUFFERSUBDATANVPROC) load(userptr, "glMulticastBufferSubDataNV"); + glad_glMulticastCopyBufferSubDataNV = (PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) load(userptr, "glMulticastCopyBufferSubDataNV"); + glad_glMulticastCopyImageSubDataNV = (PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) load(userptr, "glMulticastCopyImageSubDataNV"); + glad_glMulticastFramebufferSampleLocationsfvNV = (PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) load(userptr, "glMulticastFramebufferSampleLocationsfvNV"); + glad_glMulticastGetQueryObjecti64vNV = (PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) load(userptr, "glMulticastGetQueryObjecti64vNV"); + glad_glMulticastGetQueryObjectivNV = (PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) load(userptr, "glMulticastGetQueryObjectivNV"); + glad_glMulticastGetQueryObjectui64vNV = (PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) load(userptr, "glMulticastGetQueryObjectui64vNV"); + glad_glMulticastGetQueryObjectuivNV = (PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) load(userptr, "glMulticastGetQueryObjectuivNV"); + glad_glMulticastWaitSyncNV = (PFNGLMULTICASTWAITSYNCNVPROC) load(userptr, "glMulticastWaitSyncNV"); + glad_glRenderGpuMaskNV = (PFNGLRENDERGPUMASKNVPROC) load(userptr, "glRenderGpuMaskNV"); +} +static void glad_gl_load_GL_NV_gpu_program4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_gpu_program4) return; + glad_glGetProgramEnvParameterIivNV = (PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) load(userptr, "glGetProgramEnvParameterIivNV"); + glad_glGetProgramEnvParameterIuivNV = (PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) load(userptr, "glGetProgramEnvParameterIuivNV"); + glad_glGetProgramLocalParameterIivNV = (PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) load(userptr, "glGetProgramLocalParameterIivNV"); + glad_glGetProgramLocalParameterIuivNV = (PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) load(userptr, "glGetProgramLocalParameterIuivNV"); + glad_glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC) load(userptr, "glProgramEnvParameterI4iNV"); + glad_glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC) load(userptr, "glProgramEnvParameterI4ivNV"); + glad_glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC) load(userptr, "glProgramEnvParameterI4uiNV"); + glad_glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) load(userptr, "glProgramEnvParameterI4uivNV"); + glad_glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) load(userptr, "glProgramEnvParametersI4ivNV"); + glad_glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) load(userptr, "glProgramEnvParametersI4uivNV"); + glad_glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC) load(userptr, "glProgramLocalParameterI4iNV"); + glad_glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) load(userptr, "glProgramLocalParameterI4ivNV"); + glad_glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) load(userptr, "glProgramLocalParameterI4uiNV"); + glad_glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) load(userptr, "glProgramLocalParameterI4uivNV"); + glad_glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) load(userptr, "glProgramLocalParametersI4ivNV"); + glad_glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) load(userptr, "glProgramLocalParametersI4uivNV"); +} +static void glad_gl_load_GL_NV_gpu_program5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_gpu_program5) return; + glad_glGetProgramSubroutineParameteruivNV = (PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) load(userptr, "glGetProgramSubroutineParameteruivNV"); + glad_glProgramSubroutineParametersuivNV = (PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) load(userptr, "glProgramSubroutineParametersuivNV"); +} +static void glad_gl_load_GL_NV_gpu_shader5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_gpu_shader5) return; + glad_glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC) load(userptr, "glGetUniformi64vNV"); + glad_glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC) load(userptr, "glProgramUniform1i64NV"); + glad_glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC) load(userptr, "glProgramUniform1i64vNV"); + glad_glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC) load(userptr, "glProgramUniform1ui64NV"); + glad_glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC) load(userptr, "glProgramUniform1ui64vNV"); + glad_glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC) load(userptr, "glProgramUniform2i64NV"); + glad_glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC) load(userptr, "glProgramUniform2i64vNV"); + glad_glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC) load(userptr, "glProgramUniform2ui64NV"); + glad_glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC) load(userptr, "glProgramUniform2ui64vNV"); + glad_glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC) load(userptr, "glProgramUniform3i64NV"); + glad_glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC) load(userptr, "glProgramUniform3i64vNV"); + glad_glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC) load(userptr, "glProgramUniform3ui64NV"); + glad_glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC) load(userptr, "glProgramUniform3ui64vNV"); + glad_glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC) load(userptr, "glProgramUniform4i64NV"); + glad_glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC) load(userptr, "glProgramUniform4i64vNV"); + glad_glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC) load(userptr, "glProgramUniform4ui64NV"); + glad_glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC) load(userptr, "glProgramUniform4ui64vNV"); + glad_glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC) load(userptr, "glUniform1i64NV"); + glad_glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC) load(userptr, "glUniform1i64vNV"); + glad_glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC) load(userptr, "glUniform1ui64NV"); + glad_glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC) load(userptr, "glUniform1ui64vNV"); + glad_glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC) load(userptr, "glUniform2i64NV"); + glad_glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC) load(userptr, "glUniform2i64vNV"); + glad_glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC) load(userptr, "glUniform2ui64NV"); + glad_glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC) load(userptr, "glUniform2ui64vNV"); + glad_glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC) load(userptr, "glUniform3i64NV"); + glad_glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC) load(userptr, "glUniform3i64vNV"); + glad_glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC) load(userptr, "glUniform3ui64NV"); + glad_glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC) load(userptr, "glUniform3ui64vNV"); + glad_glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC) load(userptr, "glUniform4i64NV"); + glad_glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC) load(userptr, "glUniform4i64vNV"); + glad_glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC) load(userptr, "glUniform4ui64NV"); + glad_glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC) load(userptr, "glUniform4ui64vNV"); +} +static void glad_gl_load_GL_NV_half_float( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_half_float) return; + glad_glColor3hNV = (PFNGLCOLOR3HNVPROC) load(userptr, "glColor3hNV"); + glad_glColor3hvNV = (PFNGLCOLOR3HVNVPROC) load(userptr, "glColor3hvNV"); + glad_glColor4hNV = (PFNGLCOLOR4HNVPROC) load(userptr, "glColor4hNV"); + glad_glColor4hvNV = (PFNGLCOLOR4HVNVPROC) load(userptr, "glColor4hvNV"); + glad_glFogCoordhNV = (PFNGLFOGCOORDHNVPROC) load(userptr, "glFogCoordhNV"); + glad_glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC) load(userptr, "glFogCoordhvNV"); + glad_glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC) load(userptr, "glMultiTexCoord1hNV"); + glad_glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC) load(userptr, "glMultiTexCoord1hvNV"); + glad_glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC) load(userptr, "glMultiTexCoord2hNV"); + glad_glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC) load(userptr, "glMultiTexCoord2hvNV"); + glad_glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC) load(userptr, "glMultiTexCoord3hNV"); + glad_glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC) load(userptr, "glMultiTexCoord3hvNV"); + glad_glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC) load(userptr, "glMultiTexCoord4hNV"); + glad_glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC) load(userptr, "glMultiTexCoord4hvNV"); + glad_glNormal3hNV = (PFNGLNORMAL3HNVPROC) load(userptr, "glNormal3hNV"); + glad_glNormal3hvNV = (PFNGLNORMAL3HVNVPROC) load(userptr, "glNormal3hvNV"); + glad_glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC) load(userptr, "glSecondaryColor3hNV"); + glad_glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC) load(userptr, "glSecondaryColor3hvNV"); + glad_glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC) load(userptr, "glTexCoord1hNV"); + glad_glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC) load(userptr, "glTexCoord1hvNV"); + glad_glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC) load(userptr, "glTexCoord2hNV"); + glad_glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC) load(userptr, "glTexCoord2hvNV"); + glad_glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC) load(userptr, "glTexCoord3hNV"); + glad_glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC) load(userptr, "glTexCoord3hvNV"); + glad_glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC) load(userptr, "glTexCoord4hNV"); + glad_glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC) load(userptr, "glTexCoord4hvNV"); + glad_glVertex2hNV = (PFNGLVERTEX2HNVPROC) load(userptr, "glVertex2hNV"); + glad_glVertex2hvNV = (PFNGLVERTEX2HVNVPROC) load(userptr, "glVertex2hvNV"); + glad_glVertex3hNV = (PFNGLVERTEX3HNVPROC) load(userptr, "glVertex3hNV"); + glad_glVertex3hvNV = (PFNGLVERTEX3HVNVPROC) load(userptr, "glVertex3hvNV"); + glad_glVertex4hNV = (PFNGLVERTEX4HNVPROC) load(userptr, "glVertex4hNV"); + glad_glVertex4hvNV = (PFNGLVERTEX4HVNVPROC) load(userptr, "glVertex4hvNV"); + glad_glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC) load(userptr, "glVertexAttrib1hNV"); + glad_glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC) load(userptr, "glVertexAttrib1hvNV"); + glad_glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC) load(userptr, "glVertexAttrib2hNV"); + glad_glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC) load(userptr, "glVertexAttrib2hvNV"); + glad_glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC) load(userptr, "glVertexAttrib3hNV"); + glad_glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC) load(userptr, "glVertexAttrib3hvNV"); + glad_glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC) load(userptr, "glVertexAttrib4hNV"); + glad_glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC) load(userptr, "glVertexAttrib4hvNV"); + glad_glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC) load(userptr, "glVertexAttribs1hvNV"); + glad_glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC) load(userptr, "glVertexAttribs2hvNV"); + glad_glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC) load(userptr, "glVertexAttribs3hvNV"); + glad_glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC) load(userptr, "glVertexAttribs4hvNV"); + glad_glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC) load(userptr, "glVertexWeighthNV"); + glad_glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC) load(userptr, "glVertexWeighthvNV"); +} +static void glad_gl_load_GL_NV_internalformat_sample_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_internalformat_sample_query) return; + glad_glGetInternalformatSampleivNV = (PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) load(userptr, "glGetInternalformatSampleivNV"); +} +static void glad_gl_load_GL_NV_memory_attachment( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_memory_attachment) return; + glad_glBufferAttachMemoryNV = (PFNGLBUFFERATTACHMEMORYNVPROC) load(userptr, "glBufferAttachMemoryNV"); + glad_glGetMemoryObjectDetachedResourcesuivNV = (PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) load(userptr, "glGetMemoryObjectDetachedResourcesuivNV"); + glad_glNamedBufferAttachMemoryNV = (PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) load(userptr, "glNamedBufferAttachMemoryNV"); + glad_glResetMemoryObjectParameterNV = (PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) load(userptr, "glResetMemoryObjectParameterNV"); + glad_glTexAttachMemoryNV = (PFNGLTEXATTACHMEMORYNVPROC) load(userptr, "glTexAttachMemoryNV"); + glad_glTextureAttachMemoryNV = (PFNGLTEXTUREATTACHMEMORYNVPROC) load(userptr, "glTextureAttachMemoryNV"); +} +static void glad_gl_load_GL_NV_memory_object_sparse( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_memory_object_sparse) return; + glad_glBufferPageCommitmentMemNV = (PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) load(userptr, "glBufferPageCommitmentMemNV"); + glad_glNamedBufferPageCommitmentMemNV = (PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) load(userptr, "glNamedBufferPageCommitmentMemNV"); + glad_glTexPageCommitmentMemNV = (PFNGLTEXPAGECOMMITMENTMEMNVPROC) load(userptr, "glTexPageCommitmentMemNV"); + glad_glTexturePageCommitmentMemNV = (PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) load(userptr, "glTexturePageCommitmentMemNV"); +} +static void glad_gl_load_GL_NV_mesh_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_mesh_shader) return; + glad_glDrawMeshTasksIndirectNV = (PFNGLDRAWMESHTASKSINDIRECTNVPROC) load(userptr, "glDrawMeshTasksIndirectNV"); + glad_glDrawMeshTasksNV = (PFNGLDRAWMESHTASKSNVPROC) load(userptr, "glDrawMeshTasksNV"); + glad_glMultiDrawMeshTasksIndirectCountNV = (PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) load(userptr, "glMultiDrawMeshTasksIndirectCountNV"); + glad_glMultiDrawMeshTasksIndirectNV = (PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) load(userptr, "glMultiDrawMeshTasksIndirectNV"); +} +static void glad_gl_load_GL_NV_occlusion_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_occlusion_query) return; + glad_glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC) load(userptr, "glBeginOcclusionQueryNV"); + glad_glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC) load(userptr, "glDeleteOcclusionQueriesNV"); + glad_glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC) load(userptr, "glEndOcclusionQueryNV"); + glad_glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC) load(userptr, "glGenOcclusionQueriesNV"); + glad_glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC) load(userptr, "glGetOcclusionQueryivNV"); + glad_glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC) load(userptr, "glGetOcclusionQueryuivNV"); + glad_glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC) load(userptr, "glIsOcclusionQueryNV"); +} +static void glad_gl_load_GL_NV_parameter_buffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_parameter_buffer_object) return; + glad_glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) load(userptr, "glProgramBufferParametersIivNV"); + glad_glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) load(userptr, "glProgramBufferParametersIuivNV"); + glad_glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) load(userptr, "glProgramBufferParametersfvNV"); +} +static void glad_gl_load_GL_NV_path_rendering( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_path_rendering) return; + glad_glCopyPathNV = (PFNGLCOPYPATHNVPROC) load(userptr, "glCopyPathNV"); + glad_glCoverFillPathInstancedNV = (PFNGLCOVERFILLPATHINSTANCEDNVPROC) load(userptr, "glCoverFillPathInstancedNV"); + glad_glCoverFillPathNV = (PFNGLCOVERFILLPATHNVPROC) load(userptr, "glCoverFillPathNV"); + glad_glCoverStrokePathInstancedNV = (PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) load(userptr, "glCoverStrokePathInstancedNV"); + glad_glCoverStrokePathNV = (PFNGLCOVERSTROKEPATHNVPROC) load(userptr, "glCoverStrokePathNV"); + glad_glDeletePathsNV = (PFNGLDELETEPATHSNVPROC) load(userptr, "glDeletePathsNV"); + glad_glGenPathsNV = (PFNGLGENPATHSNVPROC) load(userptr, "glGenPathsNV"); + glad_glGetPathColorGenfvNV = (PFNGLGETPATHCOLORGENFVNVPROC) load(userptr, "glGetPathColorGenfvNV"); + glad_glGetPathColorGenivNV = (PFNGLGETPATHCOLORGENIVNVPROC) load(userptr, "glGetPathColorGenivNV"); + glad_glGetPathCommandsNV = (PFNGLGETPATHCOMMANDSNVPROC) load(userptr, "glGetPathCommandsNV"); + glad_glGetPathCoordsNV = (PFNGLGETPATHCOORDSNVPROC) load(userptr, "glGetPathCoordsNV"); + glad_glGetPathDashArrayNV = (PFNGLGETPATHDASHARRAYNVPROC) load(userptr, "glGetPathDashArrayNV"); + glad_glGetPathLengthNV = (PFNGLGETPATHLENGTHNVPROC) load(userptr, "glGetPathLengthNV"); + glad_glGetPathMetricRangeNV = (PFNGLGETPATHMETRICRANGENVPROC) load(userptr, "glGetPathMetricRangeNV"); + glad_glGetPathMetricsNV = (PFNGLGETPATHMETRICSNVPROC) load(userptr, "glGetPathMetricsNV"); + glad_glGetPathParameterfvNV = (PFNGLGETPATHPARAMETERFVNVPROC) load(userptr, "glGetPathParameterfvNV"); + glad_glGetPathParameterivNV = (PFNGLGETPATHPARAMETERIVNVPROC) load(userptr, "glGetPathParameterivNV"); + glad_glGetPathSpacingNV = (PFNGLGETPATHSPACINGNVPROC) load(userptr, "glGetPathSpacingNV"); + glad_glGetPathTexGenfvNV = (PFNGLGETPATHTEXGENFVNVPROC) load(userptr, "glGetPathTexGenfvNV"); + glad_glGetPathTexGenivNV = (PFNGLGETPATHTEXGENIVNVPROC) load(userptr, "glGetPathTexGenivNV"); + glad_glGetProgramResourcefvNV = (PFNGLGETPROGRAMRESOURCEFVNVPROC) load(userptr, "glGetProgramResourcefvNV"); + glad_glInterpolatePathsNV = (PFNGLINTERPOLATEPATHSNVPROC) load(userptr, "glInterpolatePathsNV"); + glad_glIsPathNV = (PFNGLISPATHNVPROC) load(userptr, "glIsPathNV"); + glad_glIsPointInFillPathNV = (PFNGLISPOINTINFILLPATHNVPROC) load(userptr, "glIsPointInFillPathNV"); + glad_glIsPointInStrokePathNV = (PFNGLISPOINTINSTROKEPATHNVPROC) load(userptr, "glIsPointInStrokePathNV"); + glad_glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC) load(userptr, "glMatrixFrustumEXT"); + glad_glMatrixLoad3x2fNV = (PFNGLMATRIXLOAD3X2FNVPROC) load(userptr, "glMatrixLoad3x2fNV"); + glad_glMatrixLoad3x3fNV = (PFNGLMATRIXLOAD3X3FNVPROC) load(userptr, "glMatrixLoad3x3fNV"); + glad_glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC) load(userptr, "glMatrixLoadIdentityEXT"); + glad_glMatrixLoadTranspose3x3fNV = (PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) load(userptr, "glMatrixLoadTranspose3x3fNV"); + glad_glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC) load(userptr, "glMatrixLoadTransposedEXT"); + glad_glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC) load(userptr, "glMatrixLoadTransposefEXT"); + glad_glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC) load(userptr, "glMatrixLoaddEXT"); + glad_glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC) load(userptr, "glMatrixLoadfEXT"); + glad_glMatrixMult3x2fNV = (PFNGLMATRIXMULT3X2FNVPROC) load(userptr, "glMatrixMult3x2fNV"); + glad_glMatrixMult3x3fNV = (PFNGLMATRIXMULT3X3FNVPROC) load(userptr, "glMatrixMult3x3fNV"); + glad_glMatrixMultTranspose3x3fNV = (PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) load(userptr, "glMatrixMultTranspose3x3fNV"); + glad_glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC) load(userptr, "glMatrixMultTransposedEXT"); + glad_glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC) load(userptr, "glMatrixMultTransposefEXT"); + glad_glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC) load(userptr, "glMatrixMultdEXT"); + glad_glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC) load(userptr, "glMatrixMultfEXT"); + glad_glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC) load(userptr, "glMatrixOrthoEXT"); + glad_glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC) load(userptr, "glMatrixPopEXT"); + glad_glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC) load(userptr, "glMatrixPushEXT"); + glad_glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC) load(userptr, "glMatrixRotatedEXT"); + glad_glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC) load(userptr, "glMatrixRotatefEXT"); + glad_glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC) load(userptr, "glMatrixScaledEXT"); + glad_glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC) load(userptr, "glMatrixScalefEXT"); + glad_glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC) load(userptr, "glMatrixTranslatedEXT"); + glad_glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC) load(userptr, "glMatrixTranslatefEXT"); + glad_glPathColorGenNV = (PFNGLPATHCOLORGENNVPROC) load(userptr, "glPathColorGenNV"); + glad_glPathCommandsNV = (PFNGLPATHCOMMANDSNVPROC) load(userptr, "glPathCommandsNV"); + glad_glPathCoordsNV = (PFNGLPATHCOORDSNVPROC) load(userptr, "glPathCoordsNV"); + glad_glPathCoverDepthFuncNV = (PFNGLPATHCOVERDEPTHFUNCNVPROC) load(userptr, "glPathCoverDepthFuncNV"); + glad_glPathDashArrayNV = (PFNGLPATHDASHARRAYNVPROC) load(userptr, "glPathDashArrayNV"); + glad_glPathFogGenNV = (PFNGLPATHFOGGENNVPROC) load(userptr, "glPathFogGenNV"); + glad_glPathGlyphIndexArrayNV = (PFNGLPATHGLYPHINDEXARRAYNVPROC) load(userptr, "glPathGlyphIndexArrayNV"); + glad_glPathGlyphIndexRangeNV = (PFNGLPATHGLYPHINDEXRANGENVPROC) load(userptr, "glPathGlyphIndexRangeNV"); + glad_glPathGlyphRangeNV = (PFNGLPATHGLYPHRANGENVPROC) load(userptr, "glPathGlyphRangeNV"); + glad_glPathGlyphsNV = (PFNGLPATHGLYPHSNVPROC) load(userptr, "glPathGlyphsNV"); + glad_glPathMemoryGlyphIndexArrayNV = (PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) load(userptr, "glPathMemoryGlyphIndexArrayNV"); + glad_glPathParameterfNV = (PFNGLPATHPARAMETERFNVPROC) load(userptr, "glPathParameterfNV"); + glad_glPathParameterfvNV = (PFNGLPATHPARAMETERFVNVPROC) load(userptr, "glPathParameterfvNV"); + glad_glPathParameteriNV = (PFNGLPATHPARAMETERINVPROC) load(userptr, "glPathParameteriNV"); + glad_glPathParameterivNV = (PFNGLPATHPARAMETERIVNVPROC) load(userptr, "glPathParameterivNV"); + glad_glPathStencilDepthOffsetNV = (PFNGLPATHSTENCILDEPTHOFFSETNVPROC) load(userptr, "glPathStencilDepthOffsetNV"); + glad_glPathStencilFuncNV = (PFNGLPATHSTENCILFUNCNVPROC) load(userptr, "glPathStencilFuncNV"); + glad_glPathStringNV = (PFNGLPATHSTRINGNVPROC) load(userptr, "glPathStringNV"); + glad_glPathSubCommandsNV = (PFNGLPATHSUBCOMMANDSNVPROC) load(userptr, "glPathSubCommandsNV"); + glad_glPathSubCoordsNV = (PFNGLPATHSUBCOORDSNVPROC) load(userptr, "glPathSubCoordsNV"); + glad_glPathTexGenNV = (PFNGLPATHTEXGENNVPROC) load(userptr, "glPathTexGenNV"); + glad_glPointAlongPathNV = (PFNGLPOINTALONGPATHNVPROC) load(userptr, "glPointAlongPathNV"); + glad_glProgramPathFragmentInputGenNV = (PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) load(userptr, "glProgramPathFragmentInputGenNV"); + glad_glStencilFillPathInstancedNV = (PFNGLSTENCILFILLPATHINSTANCEDNVPROC) load(userptr, "glStencilFillPathInstancedNV"); + glad_glStencilFillPathNV = (PFNGLSTENCILFILLPATHNVPROC) load(userptr, "glStencilFillPathNV"); + glad_glStencilStrokePathInstancedNV = (PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) load(userptr, "glStencilStrokePathInstancedNV"); + glad_glStencilStrokePathNV = (PFNGLSTENCILSTROKEPATHNVPROC) load(userptr, "glStencilStrokePathNV"); + glad_glStencilThenCoverFillPathInstancedNV = (PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) load(userptr, "glStencilThenCoverFillPathInstancedNV"); + glad_glStencilThenCoverFillPathNV = (PFNGLSTENCILTHENCOVERFILLPATHNVPROC) load(userptr, "glStencilThenCoverFillPathNV"); + glad_glStencilThenCoverStrokePathInstancedNV = (PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) load(userptr, "glStencilThenCoverStrokePathInstancedNV"); + glad_glStencilThenCoverStrokePathNV = (PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) load(userptr, "glStencilThenCoverStrokePathNV"); + glad_glTransformPathNV = (PFNGLTRANSFORMPATHNVPROC) load(userptr, "glTransformPathNV"); + glad_glWeightPathsNV = (PFNGLWEIGHTPATHSNVPROC) load(userptr, "glWeightPathsNV"); +} +static void glad_gl_load_GL_NV_pixel_data_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_pixel_data_range) return; + glad_glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC) load(userptr, "glFlushPixelDataRangeNV"); + glad_glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) load(userptr, "glPixelDataRangeNV"); +} +static void glad_gl_load_GL_NV_point_sprite( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_point_sprite) return; + glad_glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC) load(userptr, "glPointParameteriNV"); + glad_glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC) load(userptr, "glPointParameterivNV"); +} +static void glad_gl_load_GL_NV_present_video( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_present_video) return; + glad_glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC) load(userptr, "glGetVideoi64vNV"); + glad_glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC) load(userptr, "glGetVideoivNV"); + glad_glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC) load(userptr, "glGetVideoui64vNV"); + glad_glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC) load(userptr, "glGetVideouivNV"); + glad_glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC) load(userptr, "glPresentFrameDualFillNV"); + glad_glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC) load(userptr, "glPresentFrameKeyedNV"); +} +static void glad_gl_load_GL_NV_primitive_restart( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_primitive_restart) return; + glad_glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC) load(userptr, "glPrimitiveRestartIndexNV"); + glad_glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC) load(userptr, "glPrimitiveRestartNV"); +} +static void glad_gl_load_GL_NV_query_resource( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_query_resource) return; + glad_glQueryResourceNV = (PFNGLQUERYRESOURCENVPROC) load(userptr, "glQueryResourceNV"); +} +static void glad_gl_load_GL_NV_query_resource_tag( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_query_resource_tag) return; + glad_glDeleteQueryResourceTagNV = (PFNGLDELETEQUERYRESOURCETAGNVPROC) load(userptr, "glDeleteQueryResourceTagNV"); + glad_glGenQueryResourceTagNV = (PFNGLGENQUERYRESOURCETAGNVPROC) load(userptr, "glGenQueryResourceTagNV"); + glad_glQueryResourceTagNV = (PFNGLQUERYRESOURCETAGNVPROC) load(userptr, "glQueryResourceTagNV"); +} +static void glad_gl_load_GL_NV_register_combiners( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_register_combiners) return; + glad_glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC) load(userptr, "glCombinerInputNV"); + glad_glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC) load(userptr, "glCombinerOutputNV"); + glad_glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC) load(userptr, "glCombinerParameterfNV"); + glad_glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC) load(userptr, "glCombinerParameterfvNV"); + glad_glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC) load(userptr, "glCombinerParameteriNV"); + glad_glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC) load(userptr, "glCombinerParameterivNV"); + glad_glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC) load(userptr, "glFinalCombinerInputNV"); + glad_glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) load(userptr, "glGetCombinerInputParameterfvNV"); + glad_glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) load(userptr, "glGetCombinerInputParameterivNV"); + glad_glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) load(userptr, "glGetCombinerOutputParameterfvNV"); + glad_glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) load(userptr, "glGetCombinerOutputParameterivNV"); + glad_glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) load(userptr, "glGetFinalCombinerInputParameterfvNV"); + glad_glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) load(userptr, "glGetFinalCombinerInputParameterivNV"); +} +static void glad_gl_load_GL_NV_register_combiners2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_register_combiners2) return; + glad_glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) load(userptr, "glCombinerStageParameterfvNV"); + glad_glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) load(userptr, "glGetCombinerStageParameterfvNV"); +} +static void glad_gl_load_GL_NV_sample_locations( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_sample_locations) return; + glad_glFramebufferSampleLocationsfvNV = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) load(userptr, "glFramebufferSampleLocationsfvNV"); + glad_glNamedFramebufferSampleLocationsfvNV = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) load(userptr, "glNamedFramebufferSampleLocationsfvNV"); + glad_glResolveDepthValuesNV = (PFNGLRESOLVEDEPTHVALUESNVPROC) load(userptr, "glResolveDepthValuesNV"); +} +static void glad_gl_load_GL_NV_scissor_exclusive( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_scissor_exclusive) return; + glad_glScissorExclusiveArrayvNV = (PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) load(userptr, "glScissorExclusiveArrayvNV"); + glad_glScissorExclusiveNV = (PFNGLSCISSOREXCLUSIVENVPROC) load(userptr, "glScissorExclusiveNV"); +} +static void glad_gl_load_GL_NV_shader_buffer_load( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_shader_buffer_load) return; + glad_glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC) load(userptr, "glGetBufferParameterui64vNV"); + glad_glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC) load(userptr, "glGetIntegerui64vNV"); + glad_glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) load(userptr, "glGetNamedBufferParameterui64vNV"); + glad_glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC) load(userptr, "glGetUniformui64vNV"); + glad_glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC) load(userptr, "glIsBufferResidentNV"); + glad_glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC) load(userptr, "glIsNamedBufferResidentNV"); + glad_glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC) load(userptr, "glMakeBufferNonResidentNV"); + glad_glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC) load(userptr, "glMakeBufferResidentNV"); + glad_glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) load(userptr, "glMakeNamedBufferNonResidentNV"); + glad_glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) load(userptr, "glMakeNamedBufferResidentNV"); + glad_glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC) load(userptr, "glProgramUniformui64NV"); + glad_glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC) load(userptr, "glProgramUniformui64vNV"); + glad_glUniformui64NV = (PFNGLUNIFORMUI64NVPROC) load(userptr, "glUniformui64NV"); + glad_glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC) load(userptr, "glUniformui64vNV"); +} +static void glad_gl_load_GL_NV_shading_rate_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_shading_rate_image) return; + glad_glBindShadingRateImageNV = (PFNGLBINDSHADINGRATEIMAGENVPROC) load(userptr, "glBindShadingRateImageNV"); + glad_glGetShadingRateImagePaletteNV = (PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) load(userptr, "glGetShadingRateImagePaletteNV"); + glad_glGetShadingRateSampleLocationivNV = (PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) load(userptr, "glGetShadingRateSampleLocationivNV"); + glad_glShadingRateImageBarrierNV = (PFNGLSHADINGRATEIMAGEBARRIERNVPROC) load(userptr, "glShadingRateImageBarrierNV"); + glad_glShadingRateImagePaletteNV = (PFNGLSHADINGRATEIMAGEPALETTENVPROC) load(userptr, "glShadingRateImagePaletteNV"); + glad_glShadingRateSampleOrderCustomNV = (PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) load(userptr, "glShadingRateSampleOrderCustomNV"); + glad_glShadingRateSampleOrderNV = (PFNGLSHADINGRATESAMPLEORDERNVPROC) load(userptr, "glShadingRateSampleOrderNV"); +} +static void glad_gl_load_GL_NV_texture_barrier( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_texture_barrier) return; + glad_glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC) load(userptr, "glTextureBarrierNV"); +} +static void glad_gl_load_GL_NV_texture_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_texture_multisample) return; + glad_glTexImage2DMultisampleCoverageNV = (PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) load(userptr, "glTexImage2DMultisampleCoverageNV"); + glad_glTexImage3DMultisampleCoverageNV = (PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) load(userptr, "glTexImage3DMultisampleCoverageNV"); + glad_glTextureImage2DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) load(userptr, "glTextureImage2DMultisampleCoverageNV"); + glad_glTextureImage2DMultisampleNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) load(userptr, "glTextureImage2DMultisampleNV"); + glad_glTextureImage3DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) load(userptr, "glTextureImage3DMultisampleCoverageNV"); + glad_glTextureImage3DMultisampleNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) load(userptr, "glTextureImage3DMultisampleNV"); +} +static void glad_gl_load_GL_NV_timeline_semaphore( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_timeline_semaphore) return; + glad_glCreateSemaphoresNV = (PFNGLCREATESEMAPHORESNVPROC) load(userptr, "glCreateSemaphoresNV"); + glad_glGetSemaphoreParameterivNV = (PFNGLGETSEMAPHOREPARAMETERIVNVPROC) load(userptr, "glGetSemaphoreParameterivNV"); + glad_glSemaphoreParameterivNV = (PFNGLSEMAPHOREPARAMETERIVNVPROC) load(userptr, "glSemaphoreParameterivNV"); +} +static void glad_gl_load_GL_NV_transform_feedback( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_transform_feedback) return; + glad_glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC) load(userptr, "glActiveVaryingNV"); + glad_glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC) load(userptr, "glBeginTransformFeedbackNV"); + glad_glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC) load(userptr, "glBindBufferBaseNV"); + glad_glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC) load(userptr, "glBindBufferOffsetNV"); + glad_glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC) load(userptr, "glBindBufferRangeNV"); + glad_glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC) load(userptr, "glEndTransformFeedbackNV"); + glad_glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC) load(userptr, "glGetActiveVaryingNV"); + glad_glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) load(userptr, "glGetTransformFeedbackVaryingNV"); + glad_glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC) load(userptr, "glGetVaryingLocationNV"); + glad_glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) load(userptr, "glTransformFeedbackAttribsNV"); + glad_glTransformFeedbackStreamAttribsNV = (PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) load(userptr, "glTransformFeedbackStreamAttribsNV"); + glad_glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) load(userptr, "glTransformFeedbackVaryingsNV"); +} +static void glad_gl_load_GL_NV_transform_feedback2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_transform_feedback2) return; + glad_glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC) load(userptr, "glBindTransformFeedbackNV"); + glad_glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC) load(userptr, "glDeleteTransformFeedbacksNV"); + glad_glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC) load(userptr, "glDrawTransformFeedbackNV"); + glad_glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC) load(userptr, "glGenTransformFeedbacksNV"); + glad_glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC) load(userptr, "glIsTransformFeedbackNV"); + glad_glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC) load(userptr, "glPauseTransformFeedbackNV"); + glad_glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC) load(userptr, "glResumeTransformFeedbackNV"); +} +static void glad_gl_load_GL_NV_vdpau_interop( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vdpau_interop) return; + glad_glVDPAUFiniNV = (PFNGLVDPAUFININVPROC) load(userptr, "glVDPAUFiniNV"); + glad_glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC) load(userptr, "glVDPAUGetSurfaceivNV"); + glad_glVDPAUInitNV = (PFNGLVDPAUINITNVPROC) load(userptr, "glVDPAUInitNV"); + glad_glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC) load(userptr, "glVDPAUIsSurfaceNV"); + glad_glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC) load(userptr, "glVDPAUMapSurfacesNV"); + glad_glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) load(userptr, "glVDPAURegisterOutputSurfaceNV"); + glad_glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) load(userptr, "glVDPAURegisterVideoSurfaceNV"); + glad_glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC) load(userptr, "glVDPAUSurfaceAccessNV"); + glad_glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC) load(userptr, "glVDPAUUnmapSurfacesNV"); + glad_glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC) load(userptr, "glVDPAUUnregisterSurfaceNV"); +} +static void glad_gl_load_GL_NV_vdpau_interop2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vdpau_interop2) return; + glad_glVDPAURegisterVideoSurfaceWithPictureStructureNV = (PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC) load(userptr, "glVDPAURegisterVideoSurfaceWithPictureStructureNV"); +} +static void glad_gl_load_GL_NV_vertex_array_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vertex_array_range) return; + glad_glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC) load(userptr, "glFlushVertexArrayRangeNV"); + glad_glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC) load(userptr, "glVertexArrayRangeNV"); +} +static void glad_gl_load_GL_NV_vertex_attrib_integer_64bit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vertex_attrib_integer_64bit) return; + glad_glGetVertexAttribLi64vNV = (PFNGLGETVERTEXATTRIBLI64VNVPROC) load(userptr, "glGetVertexAttribLi64vNV"); + glad_glGetVertexAttribLui64vNV = (PFNGLGETVERTEXATTRIBLUI64VNVPROC) load(userptr, "glGetVertexAttribLui64vNV"); + glad_glVertexAttribL1i64NV = (PFNGLVERTEXATTRIBL1I64NVPROC) load(userptr, "glVertexAttribL1i64NV"); + glad_glVertexAttribL1i64vNV = (PFNGLVERTEXATTRIBL1I64VNVPROC) load(userptr, "glVertexAttribL1i64vNV"); + glad_glVertexAttribL1ui64NV = (PFNGLVERTEXATTRIBL1UI64NVPROC) load(userptr, "glVertexAttribL1ui64NV"); + glad_glVertexAttribL1ui64vNV = (PFNGLVERTEXATTRIBL1UI64VNVPROC) load(userptr, "glVertexAttribL1ui64vNV"); + glad_glVertexAttribL2i64NV = (PFNGLVERTEXATTRIBL2I64NVPROC) load(userptr, "glVertexAttribL2i64NV"); + glad_glVertexAttribL2i64vNV = (PFNGLVERTEXATTRIBL2I64VNVPROC) load(userptr, "glVertexAttribL2i64vNV"); + glad_glVertexAttribL2ui64NV = (PFNGLVERTEXATTRIBL2UI64NVPROC) load(userptr, "glVertexAttribL2ui64NV"); + glad_glVertexAttribL2ui64vNV = (PFNGLVERTEXATTRIBL2UI64VNVPROC) load(userptr, "glVertexAttribL2ui64vNV"); + glad_glVertexAttribL3i64NV = (PFNGLVERTEXATTRIBL3I64NVPROC) load(userptr, "glVertexAttribL3i64NV"); + glad_glVertexAttribL3i64vNV = (PFNGLVERTEXATTRIBL3I64VNVPROC) load(userptr, "glVertexAttribL3i64vNV"); + glad_glVertexAttribL3ui64NV = (PFNGLVERTEXATTRIBL3UI64NVPROC) load(userptr, "glVertexAttribL3ui64NV"); + glad_glVertexAttribL3ui64vNV = (PFNGLVERTEXATTRIBL3UI64VNVPROC) load(userptr, "glVertexAttribL3ui64vNV"); + glad_glVertexAttribL4i64NV = (PFNGLVERTEXATTRIBL4I64NVPROC) load(userptr, "glVertexAttribL4i64NV"); + glad_glVertexAttribL4i64vNV = (PFNGLVERTEXATTRIBL4I64VNVPROC) load(userptr, "glVertexAttribL4i64vNV"); + glad_glVertexAttribL4ui64NV = (PFNGLVERTEXATTRIBL4UI64NVPROC) load(userptr, "glVertexAttribL4ui64NV"); + glad_glVertexAttribL4ui64vNV = (PFNGLVERTEXATTRIBL4UI64VNVPROC) load(userptr, "glVertexAttribL4ui64vNV"); + glad_glVertexAttribLFormatNV = (PFNGLVERTEXATTRIBLFORMATNVPROC) load(userptr, "glVertexAttribLFormatNV"); +} +static void glad_gl_load_GL_NV_vertex_buffer_unified_memory( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vertex_buffer_unified_memory) return; + glad_glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC) load(userptr, "glBufferAddressRangeNV"); + glad_glColorFormatNV = (PFNGLCOLORFORMATNVPROC) load(userptr, "glColorFormatNV"); + glad_glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC) load(userptr, "glEdgeFlagFormatNV"); + glad_glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC) load(userptr, "glFogCoordFormatNV"); + glad_glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC) load(userptr, "glGetIntegerui64i_vNV"); + glad_glIndexFormatNV = (PFNGLINDEXFORMATNVPROC) load(userptr, "glIndexFormatNV"); + glad_glNormalFormatNV = (PFNGLNORMALFORMATNVPROC) load(userptr, "glNormalFormatNV"); + glad_glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC) load(userptr, "glSecondaryColorFormatNV"); + glad_glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC) load(userptr, "glTexCoordFormatNV"); + glad_glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC) load(userptr, "glVertexAttribFormatNV"); + glad_glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC) load(userptr, "glVertexAttribIFormatNV"); + glad_glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC) load(userptr, "glVertexFormatNV"); +} +static void glad_gl_load_GL_NV_vertex_program( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vertex_program) return; + glad_glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC) load(userptr, "glAreProgramsResidentNV"); + glad_glBindProgramNV = (PFNGLBINDPROGRAMNVPROC) load(userptr, "glBindProgramNV"); + glad_glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC) load(userptr, "glDeleteProgramsNV"); + glad_glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC) load(userptr, "glExecuteProgramNV"); + glad_glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC) load(userptr, "glGenProgramsNV"); + glad_glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC) load(userptr, "glGetProgramParameterdvNV"); + glad_glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC) load(userptr, "glGetProgramParameterfvNV"); + glad_glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC) load(userptr, "glGetProgramStringNV"); + glad_glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC) load(userptr, "glGetProgramivNV"); + glad_glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC) load(userptr, "glGetTrackMatrixivNV"); + glad_glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC) load(userptr, "glGetVertexAttribPointervNV"); + glad_glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) load(userptr, "glGetVertexAttribdvNV"); + glad_glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) load(userptr, "glGetVertexAttribfvNV"); + glad_glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) load(userptr, "glGetVertexAttribivNV"); + glad_glIsProgramNV = (PFNGLISPROGRAMNVPROC) load(userptr, "glIsProgramNV"); + glad_glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC) load(userptr, "glLoadProgramNV"); + glad_glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC) load(userptr, "glProgramParameter4dNV"); + glad_glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC) load(userptr, "glProgramParameter4dvNV"); + glad_glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC) load(userptr, "glProgramParameter4fNV"); + glad_glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC) load(userptr, "glProgramParameter4fvNV"); + glad_glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC) load(userptr, "glProgramParameters4dvNV"); + glad_glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC) load(userptr, "glProgramParameters4fvNV"); + glad_glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC) load(userptr, "glRequestResidentProgramsNV"); + glad_glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC) load(userptr, "glTrackMatrixNV"); + glad_glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC) load(userptr, "glVertexAttrib1dNV"); + glad_glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC) load(userptr, "glVertexAttrib1dvNV"); + glad_glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC) load(userptr, "glVertexAttrib1fNV"); + glad_glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC) load(userptr, "glVertexAttrib1fvNV"); + glad_glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC) load(userptr, "glVertexAttrib1sNV"); + glad_glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC) load(userptr, "glVertexAttrib1svNV"); + glad_glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC) load(userptr, "glVertexAttrib2dNV"); + glad_glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC) load(userptr, "glVertexAttrib2dvNV"); + glad_glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC) load(userptr, "glVertexAttrib2fNV"); + glad_glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC) load(userptr, "glVertexAttrib2fvNV"); + glad_glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC) load(userptr, "glVertexAttrib2sNV"); + glad_glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC) load(userptr, "glVertexAttrib2svNV"); + glad_glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC) load(userptr, "glVertexAttrib3dNV"); + glad_glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC) load(userptr, "glVertexAttrib3dvNV"); + glad_glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC) load(userptr, "glVertexAttrib3fNV"); + glad_glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC) load(userptr, "glVertexAttrib3fvNV"); + glad_glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC) load(userptr, "glVertexAttrib3sNV"); + glad_glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC) load(userptr, "glVertexAttrib3svNV"); + glad_glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC) load(userptr, "glVertexAttrib4dNV"); + glad_glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC) load(userptr, "glVertexAttrib4dvNV"); + glad_glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC) load(userptr, "glVertexAttrib4fNV"); + glad_glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC) load(userptr, "glVertexAttrib4fvNV"); + glad_glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC) load(userptr, "glVertexAttrib4sNV"); + glad_glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC) load(userptr, "glVertexAttrib4svNV"); + glad_glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) load(userptr, "glVertexAttrib4ubNV"); + glad_glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC) load(userptr, "glVertexAttrib4ubvNV"); + glad_glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC) load(userptr, "glVertexAttribPointerNV"); + glad_glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC) load(userptr, "glVertexAttribs1dvNV"); + glad_glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC) load(userptr, "glVertexAttribs1fvNV"); + glad_glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC) load(userptr, "glVertexAttribs1svNV"); + glad_glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC) load(userptr, "glVertexAttribs2dvNV"); + glad_glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC) load(userptr, "glVertexAttribs2fvNV"); + glad_glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC) load(userptr, "glVertexAttribs2svNV"); + glad_glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC) load(userptr, "glVertexAttribs3dvNV"); + glad_glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC) load(userptr, "glVertexAttribs3fvNV"); + glad_glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC) load(userptr, "glVertexAttribs3svNV"); + glad_glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC) load(userptr, "glVertexAttribs4dvNV"); + glad_glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC) load(userptr, "glVertexAttribs4fvNV"); + glad_glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC) load(userptr, "glVertexAttribs4svNV"); + glad_glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC) load(userptr, "glVertexAttribs4ubvNV"); +} +static void glad_gl_load_GL_NV_vertex_program4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_vertex_program4) return; + glad_glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC) load(userptr, "glGetVertexAttribIivEXT"); + glad_glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC) load(userptr, "glGetVertexAttribIuivEXT"); + glad_glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC) load(userptr, "glVertexAttribI1iEXT"); + glad_glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC) load(userptr, "glVertexAttribI1ivEXT"); + glad_glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC) load(userptr, "glVertexAttribI1uiEXT"); + glad_glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC) load(userptr, "glVertexAttribI1uivEXT"); + glad_glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC) load(userptr, "glVertexAttribI2iEXT"); + glad_glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC) load(userptr, "glVertexAttribI2ivEXT"); + glad_glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC) load(userptr, "glVertexAttribI2uiEXT"); + glad_glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC) load(userptr, "glVertexAttribI2uivEXT"); + glad_glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC) load(userptr, "glVertexAttribI3iEXT"); + glad_glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC) load(userptr, "glVertexAttribI3ivEXT"); + glad_glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC) load(userptr, "glVertexAttribI3uiEXT"); + glad_glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC) load(userptr, "glVertexAttribI3uivEXT"); + glad_glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC) load(userptr, "glVertexAttribI4bvEXT"); + glad_glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC) load(userptr, "glVertexAttribI4iEXT"); + glad_glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC) load(userptr, "glVertexAttribI4ivEXT"); + glad_glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC) load(userptr, "glVertexAttribI4svEXT"); + glad_glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC) load(userptr, "glVertexAttribI4ubvEXT"); + glad_glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC) load(userptr, "glVertexAttribI4uiEXT"); + glad_glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC) load(userptr, "glVertexAttribI4uivEXT"); + glad_glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC) load(userptr, "glVertexAttribI4usvEXT"); + glad_glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC) load(userptr, "glVertexAttribIPointerEXT"); +} +static void glad_gl_load_GL_NV_video_capture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_video_capture) return; + glad_glBeginVideoCaptureNV = (PFNGLBEGINVIDEOCAPTURENVPROC) load(userptr, "glBeginVideoCaptureNV"); + glad_glBindVideoCaptureStreamBufferNV = (PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) load(userptr, "glBindVideoCaptureStreamBufferNV"); + glad_glBindVideoCaptureStreamTextureNV = (PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) load(userptr, "glBindVideoCaptureStreamTextureNV"); + glad_glEndVideoCaptureNV = (PFNGLENDVIDEOCAPTURENVPROC) load(userptr, "glEndVideoCaptureNV"); + glad_glGetVideoCaptureStreamdvNV = (PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) load(userptr, "glGetVideoCaptureStreamdvNV"); + glad_glGetVideoCaptureStreamfvNV = (PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) load(userptr, "glGetVideoCaptureStreamfvNV"); + glad_glGetVideoCaptureStreamivNV = (PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) load(userptr, "glGetVideoCaptureStreamivNV"); + glad_glGetVideoCaptureivNV = (PFNGLGETVIDEOCAPTUREIVNVPROC) load(userptr, "glGetVideoCaptureivNV"); + glad_glVideoCaptureNV = (PFNGLVIDEOCAPTURENVPROC) load(userptr, "glVideoCaptureNV"); + glad_glVideoCaptureStreamParameterdvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) load(userptr, "glVideoCaptureStreamParameterdvNV"); + glad_glVideoCaptureStreamParameterfvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) load(userptr, "glVideoCaptureStreamParameterfvNV"); + glad_glVideoCaptureStreamParameterivNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) load(userptr, "glVideoCaptureStreamParameterivNV"); +} +static void glad_gl_load_GL_NV_viewport_swizzle( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_viewport_swizzle) return; + glad_glViewportSwizzleNV = (PFNGLVIEWPORTSWIZZLENVPROC) load(userptr, "glViewportSwizzleNV"); +} +static void glad_gl_load_GL_OES_byte_coordinates( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_byte_coordinates) return; + glad_glMultiTexCoord1bOES = (PFNGLMULTITEXCOORD1BOESPROC) load(userptr, "glMultiTexCoord1bOES"); + glad_glMultiTexCoord1bvOES = (PFNGLMULTITEXCOORD1BVOESPROC) load(userptr, "glMultiTexCoord1bvOES"); + glad_glMultiTexCoord2bOES = (PFNGLMULTITEXCOORD2BOESPROC) load(userptr, "glMultiTexCoord2bOES"); + glad_glMultiTexCoord2bvOES = (PFNGLMULTITEXCOORD2BVOESPROC) load(userptr, "glMultiTexCoord2bvOES"); + glad_glMultiTexCoord3bOES = (PFNGLMULTITEXCOORD3BOESPROC) load(userptr, "glMultiTexCoord3bOES"); + glad_glMultiTexCoord3bvOES = (PFNGLMULTITEXCOORD3BVOESPROC) load(userptr, "glMultiTexCoord3bvOES"); + glad_glMultiTexCoord4bOES = (PFNGLMULTITEXCOORD4BOESPROC) load(userptr, "glMultiTexCoord4bOES"); + glad_glMultiTexCoord4bvOES = (PFNGLMULTITEXCOORD4BVOESPROC) load(userptr, "glMultiTexCoord4bvOES"); + glad_glTexCoord1bOES = (PFNGLTEXCOORD1BOESPROC) load(userptr, "glTexCoord1bOES"); + glad_glTexCoord1bvOES = (PFNGLTEXCOORD1BVOESPROC) load(userptr, "glTexCoord1bvOES"); + glad_glTexCoord2bOES = (PFNGLTEXCOORD2BOESPROC) load(userptr, "glTexCoord2bOES"); + glad_glTexCoord2bvOES = (PFNGLTEXCOORD2BVOESPROC) load(userptr, "glTexCoord2bvOES"); + glad_glTexCoord3bOES = (PFNGLTEXCOORD3BOESPROC) load(userptr, "glTexCoord3bOES"); + glad_glTexCoord3bvOES = (PFNGLTEXCOORD3BVOESPROC) load(userptr, "glTexCoord3bvOES"); + glad_glTexCoord4bOES = (PFNGLTEXCOORD4BOESPROC) load(userptr, "glTexCoord4bOES"); + glad_glTexCoord4bvOES = (PFNGLTEXCOORD4BVOESPROC) load(userptr, "glTexCoord4bvOES"); + glad_glVertex2bOES = (PFNGLVERTEX2BOESPROC) load(userptr, "glVertex2bOES"); + glad_glVertex2bvOES = (PFNGLVERTEX2BVOESPROC) load(userptr, "glVertex2bvOES"); + glad_glVertex3bOES = (PFNGLVERTEX3BOESPROC) load(userptr, "glVertex3bOES"); + glad_glVertex3bvOES = (PFNGLVERTEX3BVOESPROC) load(userptr, "glVertex3bvOES"); + glad_glVertex4bOES = (PFNGLVERTEX4BOESPROC) load(userptr, "glVertex4bOES"); + glad_glVertex4bvOES = (PFNGLVERTEX4BVOESPROC) load(userptr, "glVertex4bvOES"); +} +static void glad_gl_load_GL_OES_fixed_point( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_fixed_point) return; + glad_glAccumxOES = (PFNGLACCUMXOESPROC) load(userptr, "glAccumxOES"); + glad_glAlphaFuncxOES = (PFNGLALPHAFUNCXOESPROC) load(userptr, "glAlphaFuncxOES"); + glad_glBitmapxOES = (PFNGLBITMAPXOESPROC) load(userptr, "glBitmapxOES"); + glad_glBlendColorxOES = (PFNGLBLENDCOLORXOESPROC) load(userptr, "glBlendColorxOES"); + glad_glClearAccumxOES = (PFNGLCLEARACCUMXOESPROC) load(userptr, "glClearAccumxOES"); + glad_glClearColorxOES = (PFNGLCLEARCOLORXOESPROC) load(userptr, "glClearColorxOES"); + glad_glClearDepthxOES = (PFNGLCLEARDEPTHXOESPROC) load(userptr, "glClearDepthxOES"); + glad_glClipPlanexOES = (PFNGLCLIPPLANEXOESPROC) load(userptr, "glClipPlanexOES"); + glad_glColor3xOES = (PFNGLCOLOR3XOESPROC) load(userptr, "glColor3xOES"); + glad_glColor3xvOES = (PFNGLCOLOR3XVOESPROC) load(userptr, "glColor3xvOES"); + glad_glColor4xOES = (PFNGLCOLOR4XOESPROC) load(userptr, "glColor4xOES"); + glad_glColor4xvOES = (PFNGLCOLOR4XVOESPROC) load(userptr, "glColor4xvOES"); + glad_glConvolutionParameterxOES = (PFNGLCONVOLUTIONPARAMETERXOESPROC) load(userptr, "glConvolutionParameterxOES"); + glad_glConvolutionParameterxvOES = (PFNGLCONVOLUTIONPARAMETERXVOESPROC) load(userptr, "glConvolutionParameterxvOES"); + glad_glDepthRangexOES = (PFNGLDEPTHRANGEXOESPROC) load(userptr, "glDepthRangexOES"); + glad_glEvalCoord1xOES = (PFNGLEVALCOORD1XOESPROC) load(userptr, "glEvalCoord1xOES"); + glad_glEvalCoord1xvOES = (PFNGLEVALCOORD1XVOESPROC) load(userptr, "glEvalCoord1xvOES"); + glad_glEvalCoord2xOES = (PFNGLEVALCOORD2XOESPROC) load(userptr, "glEvalCoord2xOES"); + glad_glEvalCoord2xvOES = (PFNGLEVALCOORD2XVOESPROC) load(userptr, "glEvalCoord2xvOES"); + glad_glFeedbackBufferxOES = (PFNGLFEEDBACKBUFFERXOESPROC) load(userptr, "glFeedbackBufferxOES"); + glad_glFogxOES = (PFNGLFOGXOESPROC) load(userptr, "glFogxOES"); + glad_glFogxvOES = (PFNGLFOGXVOESPROC) load(userptr, "glFogxvOES"); + glad_glFrustumxOES = (PFNGLFRUSTUMXOESPROC) load(userptr, "glFrustumxOES"); + glad_glGetClipPlanexOES = (PFNGLGETCLIPPLANEXOESPROC) load(userptr, "glGetClipPlanexOES"); + glad_glGetConvolutionParameterxvOES = (PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) load(userptr, "glGetConvolutionParameterxvOES"); + glad_glGetFixedvOES = (PFNGLGETFIXEDVOESPROC) load(userptr, "glGetFixedvOES"); + glad_glGetHistogramParameterxvOES = (PFNGLGETHISTOGRAMPARAMETERXVOESPROC) load(userptr, "glGetHistogramParameterxvOES"); + glad_glGetLightxOES = (PFNGLGETLIGHTXOESPROC) load(userptr, "glGetLightxOES"); + glad_glGetLightxvOES = (PFNGLGETLIGHTXVOESPROC) load(userptr, "glGetLightxvOES"); + glad_glGetMapxvOES = (PFNGLGETMAPXVOESPROC) load(userptr, "glGetMapxvOES"); + glad_glGetMaterialxOES = (PFNGLGETMATERIALXOESPROC) load(userptr, "glGetMaterialxOES"); + glad_glGetMaterialxvOES = (PFNGLGETMATERIALXVOESPROC) load(userptr, "glGetMaterialxvOES"); + glad_glGetPixelMapxv = (PFNGLGETPIXELMAPXVPROC) load(userptr, "glGetPixelMapxv"); + glad_glGetTexEnvxvOES = (PFNGLGETTEXENVXVOESPROC) load(userptr, "glGetTexEnvxvOES"); + glad_glGetTexGenxvOES = (PFNGLGETTEXGENXVOESPROC) load(userptr, "glGetTexGenxvOES"); + glad_glGetTexLevelParameterxvOES = (PFNGLGETTEXLEVELPARAMETERXVOESPROC) load(userptr, "glGetTexLevelParameterxvOES"); + glad_glGetTexParameterxvOES = (PFNGLGETTEXPARAMETERXVOESPROC) load(userptr, "glGetTexParameterxvOES"); + glad_glIndexxOES = (PFNGLINDEXXOESPROC) load(userptr, "glIndexxOES"); + glad_glIndexxvOES = (PFNGLINDEXXVOESPROC) load(userptr, "glIndexxvOES"); + glad_glLightModelxOES = (PFNGLLIGHTMODELXOESPROC) load(userptr, "glLightModelxOES"); + glad_glLightModelxvOES = (PFNGLLIGHTMODELXVOESPROC) load(userptr, "glLightModelxvOES"); + glad_glLightxOES = (PFNGLLIGHTXOESPROC) load(userptr, "glLightxOES"); + glad_glLightxvOES = (PFNGLLIGHTXVOESPROC) load(userptr, "glLightxvOES"); + glad_glLineWidthxOES = (PFNGLLINEWIDTHXOESPROC) load(userptr, "glLineWidthxOES"); + glad_glLoadMatrixxOES = (PFNGLLOADMATRIXXOESPROC) load(userptr, "glLoadMatrixxOES"); + glad_glLoadTransposeMatrixxOES = (PFNGLLOADTRANSPOSEMATRIXXOESPROC) load(userptr, "glLoadTransposeMatrixxOES"); + glad_glMap1xOES = (PFNGLMAP1XOESPROC) load(userptr, "glMap1xOES"); + glad_glMap2xOES = (PFNGLMAP2XOESPROC) load(userptr, "glMap2xOES"); + glad_glMapGrid1xOES = (PFNGLMAPGRID1XOESPROC) load(userptr, "glMapGrid1xOES"); + glad_glMapGrid2xOES = (PFNGLMAPGRID2XOESPROC) load(userptr, "glMapGrid2xOES"); + glad_glMaterialxOES = (PFNGLMATERIALXOESPROC) load(userptr, "glMaterialxOES"); + glad_glMaterialxvOES = (PFNGLMATERIALXVOESPROC) load(userptr, "glMaterialxvOES"); + glad_glMultMatrixxOES = (PFNGLMULTMATRIXXOESPROC) load(userptr, "glMultMatrixxOES"); + glad_glMultTransposeMatrixxOES = (PFNGLMULTTRANSPOSEMATRIXXOESPROC) load(userptr, "glMultTransposeMatrixxOES"); + glad_glMultiTexCoord1xOES = (PFNGLMULTITEXCOORD1XOESPROC) load(userptr, "glMultiTexCoord1xOES"); + glad_glMultiTexCoord1xvOES = (PFNGLMULTITEXCOORD1XVOESPROC) load(userptr, "glMultiTexCoord1xvOES"); + glad_glMultiTexCoord2xOES = (PFNGLMULTITEXCOORD2XOESPROC) load(userptr, "glMultiTexCoord2xOES"); + glad_glMultiTexCoord2xvOES = (PFNGLMULTITEXCOORD2XVOESPROC) load(userptr, "glMultiTexCoord2xvOES"); + glad_glMultiTexCoord3xOES = (PFNGLMULTITEXCOORD3XOESPROC) load(userptr, "glMultiTexCoord3xOES"); + glad_glMultiTexCoord3xvOES = (PFNGLMULTITEXCOORD3XVOESPROC) load(userptr, "glMultiTexCoord3xvOES"); + glad_glMultiTexCoord4xOES = (PFNGLMULTITEXCOORD4XOESPROC) load(userptr, "glMultiTexCoord4xOES"); + glad_glMultiTexCoord4xvOES = (PFNGLMULTITEXCOORD4XVOESPROC) load(userptr, "glMultiTexCoord4xvOES"); + glad_glNormal3xOES = (PFNGLNORMAL3XOESPROC) load(userptr, "glNormal3xOES"); + glad_glNormal3xvOES = (PFNGLNORMAL3XVOESPROC) load(userptr, "glNormal3xvOES"); + glad_glOrthoxOES = (PFNGLORTHOXOESPROC) load(userptr, "glOrthoxOES"); + glad_glPassThroughxOES = (PFNGLPASSTHROUGHXOESPROC) load(userptr, "glPassThroughxOES"); + glad_glPixelMapx = (PFNGLPIXELMAPXPROC) load(userptr, "glPixelMapx"); + glad_glPixelStorex = (PFNGLPIXELSTOREXPROC) load(userptr, "glPixelStorex"); + glad_glPixelTransferxOES = (PFNGLPIXELTRANSFERXOESPROC) load(userptr, "glPixelTransferxOES"); + glad_glPixelZoomxOES = (PFNGLPIXELZOOMXOESPROC) load(userptr, "glPixelZoomxOES"); + glad_glPointParameterxOES = (PFNGLPOINTPARAMETERXOESPROC) load(userptr, "glPointParameterxOES"); + glad_glPointParameterxvOES = (PFNGLPOINTPARAMETERXVOESPROC) load(userptr, "glPointParameterxvOES"); + glad_glPointSizexOES = (PFNGLPOINTSIZEXOESPROC) load(userptr, "glPointSizexOES"); + glad_glPolygonOffsetxOES = (PFNGLPOLYGONOFFSETXOESPROC) load(userptr, "glPolygonOffsetxOES"); + glad_glPrioritizeTexturesxOES = (PFNGLPRIORITIZETEXTURESXOESPROC) load(userptr, "glPrioritizeTexturesxOES"); + glad_glRasterPos2xOES = (PFNGLRASTERPOS2XOESPROC) load(userptr, "glRasterPos2xOES"); + glad_glRasterPos2xvOES = (PFNGLRASTERPOS2XVOESPROC) load(userptr, "glRasterPos2xvOES"); + glad_glRasterPos3xOES = (PFNGLRASTERPOS3XOESPROC) load(userptr, "glRasterPos3xOES"); + glad_glRasterPos3xvOES = (PFNGLRASTERPOS3XVOESPROC) load(userptr, "glRasterPos3xvOES"); + glad_glRasterPos4xOES = (PFNGLRASTERPOS4XOESPROC) load(userptr, "glRasterPos4xOES"); + glad_glRasterPos4xvOES = (PFNGLRASTERPOS4XVOESPROC) load(userptr, "glRasterPos4xvOES"); + glad_glRectxOES = (PFNGLRECTXOESPROC) load(userptr, "glRectxOES"); + glad_glRectxvOES = (PFNGLRECTXVOESPROC) load(userptr, "glRectxvOES"); + glad_glRotatexOES = (PFNGLROTATEXOESPROC) load(userptr, "glRotatexOES"); + glad_glSampleCoveragexOES = (PFNGLSAMPLECOVERAGEXOESPROC) load(userptr, "glSampleCoveragexOES"); + glad_glScalexOES = (PFNGLSCALEXOESPROC) load(userptr, "glScalexOES"); + glad_glTexCoord1xOES = (PFNGLTEXCOORD1XOESPROC) load(userptr, "glTexCoord1xOES"); + glad_glTexCoord1xvOES = (PFNGLTEXCOORD1XVOESPROC) load(userptr, "glTexCoord1xvOES"); + glad_glTexCoord2xOES = (PFNGLTEXCOORD2XOESPROC) load(userptr, "glTexCoord2xOES"); + glad_glTexCoord2xvOES = (PFNGLTEXCOORD2XVOESPROC) load(userptr, "glTexCoord2xvOES"); + glad_glTexCoord3xOES = (PFNGLTEXCOORD3XOESPROC) load(userptr, "glTexCoord3xOES"); + glad_glTexCoord3xvOES = (PFNGLTEXCOORD3XVOESPROC) load(userptr, "glTexCoord3xvOES"); + glad_glTexCoord4xOES = (PFNGLTEXCOORD4XOESPROC) load(userptr, "glTexCoord4xOES"); + glad_glTexCoord4xvOES = (PFNGLTEXCOORD4XVOESPROC) load(userptr, "glTexCoord4xvOES"); + glad_glTexEnvxOES = (PFNGLTEXENVXOESPROC) load(userptr, "glTexEnvxOES"); + glad_glTexEnvxvOES = (PFNGLTEXENVXVOESPROC) load(userptr, "glTexEnvxvOES"); + glad_glTexGenxOES = (PFNGLTEXGENXOESPROC) load(userptr, "glTexGenxOES"); + glad_glTexGenxvOES = (PFNGLTEXGENXVOESPROC) load(userptr, "glTexGenxvOES"); + glad_glTexParameterxOES = (PFNGLTEXPARAMETERXOESPROC) load(userptr, "glTexParameterxOES"); + glad_glTexParameterxvOES = (PFNGLTEXPARAMETERXVOESPROC) load(userptr, "glTexParameterxvOES"); + glad_glTranslatexOES = (PFNGLTRANSLATEXOESPROC) load(userptr, "glTranslatexOES"); + glad_glVertex2xOES = (PFNGLVERTEX2XOESPROC) load(userptr, "glVertex2xOES"); + glad_glVertex2xvOES = (PFNGLVERTEX2XVOESPROC) load(userptr, "glVertex2xvOES"); + glad_glVertex3xOES = (PFNGLVERTEX3XOESPROC) load(userptr, "glVertex3xOES"); + glad_glVertex3xvOES = (PFNGLVERTEX3XVOESPROC) load(userptr, "glVertex3xvOES"); + glad_glVertex4xOES = (PFNGLVERTEX4XOESPROC) load(userptr, "glVertex4xOES"); + glad_glVertex4xvOES = (PFNGLVERTEX4XVOESPROC) load(userptr, "glVertex4xvOES"); +} +static void glad_gl_load_GL_OES_query_matrix( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_query_matrix) return; + glad_glQueryMatrixxOES = (PFNGLQUERYMATRIXXOESPROC) load(userptr, "glQueryMatrixxOES"); +} +static void glad_gl_load_GL_OES_single_precision( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_single_precision) return; + glad_glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC) load(userptr, "glClearDepthfOES"); + glad_glClipPlanefOES = (PFNGLCLIPPLANEFOESPROC) load(userptr, "glClipPlanefOES"); + glad_glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC) load(userptr, "glDepthRangefOES"); + glad_glFrustumfOES = (PFNGLFRUSTUMFOESPROC) load(userptr, "glFrustumfOES"); + glad_glGetClipPlanefOES = (PFNGLGETCLIPPLANEFOESPROC) load(userptr, "glGetClipPlanefOES"); + glad_glOrthofOES = (PFNGLORTHOFOESPROC) load(userptr, "glOrthofOES"); +} +static void glad_gl_load_GL_OVR_multiview( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OVR_multiview) return; + glad_glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) load(userptr, "glFramebufferTextureMultiviewOVR"); + glad_glNamedFramebufferTextureMultiviewOVR = (PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) load(userptr, "glNamedFramebufferTextureMultiviewOVR"); +} +static void glad_gl_load_GL_PGI_misc_hints( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_PGI_misc_hints) return; + glad_glHintPGI = (PFNGLHINTPGIPROC) load(userptr, "glHintPGI"); +} +static void glad_gl_load_GL_SGIS_detail_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_detail_texture) return; + glad_glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC) load(userptr, "glDetailTexFuncSGIS"); + glad_glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC) load(userptr, "glGetDetailTexFuncSGIS"); +} +static void glad_gl_load_GL_SGIS_fog_function( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_fog_function) return; + glad_glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC) load(userptr, "glFogFuncSGIS"); + glad_glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC) load(userptr, "glGetFogFuncSGIS"); +} +static void glad_gl_load_GL_SGIS_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_multisample) return; + glad_glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC) load(userptr, "glSampleMaskSGIS"); + glad_glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC) load(userptr, "glSamplePatternSGIS"); +} +static void glad_gl_load_GL_SGIS_pixel_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_pixel_texture) return; + glad_glGetPixelTexGenParameterfvSGIS = (PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) load(userptr, "glGetPixelTexGenParameterfvSGIS"); + glad_glGetPixelTexGenParameterivSGIS = (PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) load(userptr, "glGetPixelTexGenParameterivSGIS"); + glad_glPixelTexGenParameterfSGIS = (PFNGLPIXELTEXGENPARAMETERFSGISPROC) load(userptr, "glPixelTexGenParameterfSGIS"); + glad_glPixelTexGenParameterfvSGIS = (PFNGLPIXELTEXGENPARAMETERFVSGISPROC) load(userptr, "glPixelTexGenParameterfvSGIS"); + glad_glPixelTexGenParameteriSGIS = (PFNGLPIXELTEXGENPARAMETERISGISPROC) load(userptr, "glPixelTexGenParameteriSGIS"); + glad_glPixelTexGenParameterivSGIS = (PFNGLPIXELTEXGENPARAMETERIVSGISPROC) load(userptr, "glPixelTexGenParameterivSGIS"); +} +static void glad_gl_load_GL_SGIS_point_parameters( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_point_parameters) return; + glad_glPointParameterfSGIS = (PFNGLPOINTPARAMETERFSGISPROC) load(userptr, "glPointParameterfSGIS"); + glad_glPointParameterfvSGIS = (PFNGLPOINTPARAMETERFVSGISPROC) load(userptr, "glPointParameterfvSGIS"); +} +static void glad_gl_load_GL_SGIS_sharpen_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_sharpen_texture) return; + glad_glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC) load(userptr, "glGetSharpenTexFuncSGIS"); + glad_glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC) load(userptr, "glSharpenTexFuncSGIS"); +} +static void glad_gl_load_GL_SGIS_texture4D( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_texture4D) return; + glad_glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC) load(userptr, "glTexImage4DSGIS"); + glad_glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC) load(userptr, "glTexSubImage4DSGIS"); +} +static void glad_gl_load_GL_SGIS_texture_color_mask( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_texture_color_mask) return; + glad_glTextureColorMaskSGIS = (PFNGLTEXTURECOLORMASKSGISPROC) load(userptr, "glTextureColorMaskSGIS"); +} +static void glad_gl_load_GL_SGIS_texture_filter4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIS_texture_filter4) return; + glad_glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC) load(userptr, "glGetTexFilterFuncSGIS"); + glad_glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC) load(userptr, "glTexFilterFuncSGIS"); +} +static void glad_gl_load_GL_SGIX_async( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_async) return; + glad_glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC) load(userptr, "glAsyncMarkerSGIX"); + glad_glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC) load(userptr, "glDeleteAsyncMarkersSGIX"); + glad_glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC) load(userptr, "glFinishAsyncSGIX"); + glad_glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC) load(userptr, "glGenAsyncMarkersSGIX"); + glad_glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC) load(userptr, "glIsAsyncMarkerSGIX"); + glad_glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC) load(userptr, "glPollAsyncSGIX"); +} +static void glad_gl_load_GL_SGIX_flush_raster( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_flush_raster) return; + glad_glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC) load(userptr, "glFlushRasterSGIX"); +} +static void glad_gl_load_GL_SGIX_fragment_lighting( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_fragment_lighting) return; + glad_glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC) load(userptr, "glFragmentColorMaterialSGIX"); + glad_glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC) load(userptr, "glFragmentLightModelfSGIX"); + glad_glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) load(userptr, "glFragmentLightModelfvSGIX"); + glad_glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC) load(userptr, "glFragmentLightModeliSGIX"); + glad_glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) load(userptr, "glFragmentLightModelivSGIX"); + glad_glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC) load(userptr, "glFragmentLightfSGIX"); + glad_glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC) load(userptr, "glFragmentLightfvSGIX"); + glad_glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC) load(userptr, "glFragmentLightiSGIX"); + glad_glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC) load(userptr, "glFragmentLightivSGIX"); + glad_glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC) load(userptr, "glFragmentMaterialfSGIX"); + glad_glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC) load(userptr, "glFragmentMaterialfvSGIX"); + glad_glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC) load(userptr, "glFragmentMaterialiSGIX"); + glad_glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC) load(userptr, "glFragmentMaterialivSGIX"); + glad_glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC) load(userptr, "glGetFragmentLightfvSGIX"); + glad_glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC) load(userptr, "glGetFragmentLightivSGIX"); + glad_glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC) load(userptr, "glGetFragmentMaterialfvSGIX"); + glad_glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC) load(userptr, "glGetFragmentMaterialivSGIX"); + glad_glLightEnviSGIX = (PFNGLLIGHTENVISGIXPROC) load(userptr, "glLightEnviSGIX"); +} +static void glad_gl_load_GL_SGIX_framezoom( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_framezoom) return; + glad_glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC) load(userptr, "glFrameZoomSGIX"); +} +static void glad_gl_load_GL_SGIX_igloo_interface( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_igloo_interface) return; + glad_glIglooInterfaceSGIX = (PFNGLIGLOOINTERFACESGIXPROC) load(userptr, "glIglooInterfaceSGIX"); +} +static void glad_gl_load_GL_SGIX_instruments( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_instruments) return; + glad_glGetInstrumentsSGIX = (PFNGLGETINSTRUMENTSSGIXPROC) load(userptr, "glGetInstrumentsSGIX"); + glad_glInstrumentsBufferSGIX = (PFNGLINSTRUMENTSBUFFERSGIXPROC) load(userptr, "glInstrumentsBufferSGIX"); + glad_glPollInstrumentsSGIX = (PFNGLPOLLINSTRUMENTSSGIXPROC) load(userptr, "glPollInstrumentsSGIX"); + glad_glReadInstrumentsSGIX = (PFNGLREADINSTRUMENTSSGIXPROC) load(userptr, "glReadInstrumentsSGIX"); + glad_glStartInstrumentsSGIX = (PFNGLSTARTINSTRUMENTSSGIXPROC) load(userptr, "glStartInstrumentsSGIX"); + glad_glStopInstrumentsSGIX = (PFNGLSTOPINSTRUMENTSSGIXPROC) load(userptr, "glStopInstrumentsSGIX"); +} +static void glad_gl_load_GL_SGIX_list_priority( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_list_priority) return; + glad_glGetListParameterfvSGIX = (PFNGLGETLISTPARAMETERFVSGIXPROC) load(userptr, "glGetListParameterfvSGIX"); + glad_glGetListParameterivSGIX = (PFNGLGETLISTPARAMETERIVSGIXPROC) load(userptr, "glGetListParameterivSGIX"); + glad_glListParameterfSGIX = (PFNGLLISTPARAMETERFSGIXPROC) load(userptr, "glListParameterfSGIX"); + glad_glListParameterfvSGIX = (PFNGLLISTPARAMETERFVSGIXPROC) load(userptr, "glListParameterfvSGIX"); + glad_glListParameteriSGIX = (PFNGLLISTPARAMETERISGIXPROC) load(userptr, "glListParameteriSGIX"); + glad_glListParameterivSGIX = (PFNGLLISTPARAMETERIVSGIXPROC) load(userptr, "glListParameterivSGIX"); +} +static void glad_gl_load_GL_SGIX_pixel_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_pixel_texture) return; + glad_glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC) load(userptr, "glPixelTexGenSGIX"); +} +static void glad_gl_load_GL_SGIX_polynomial_ffd( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_polynomial_ffd) return; + glad_glDeformSGIX = (PFNGLDEFORMSGIXPROC) load(userptr, "glDeformSGIX"); + glad_glDeformationMap3dSGIX = (PFNGLDEFORMATIONMAP3DSGIXPROC) load(userptr, "glDeformationMap3dSGIX"); + glad_glDeformationMap3fSGIX = (PFNGLDEFORMATIONMAP3FSGIXPROC) load(userptr, "glDeformationMap3fSGIX"); + glad_glLoadIdentityDeformationMapSGIX = (PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) load(userptr, "glLoadIdentityDeformationMapSGIX"); +} +static void glad_gl_load_GL_SGIX_reference_plane( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_reference_plane) return; + glad_glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC) load(userptr, "glReferencePlaneSGIX"); +} +static void glad_gl_load_GL_SGIX_sprite( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_sprite) return; + glad_glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC) load(userptr, "glSpriteParameterfSGIX"); + glad_glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC) load(userptr, "glSpriteParameterfvSGIX"); + glad_glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC) load(userptr, "glSpriteParameteriSGIX"); + glad_glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC) load(userptr, "glSpriteParameterivSGIX"); +} +static void glad_gl_load_GL_SGIX_tag_sample_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGIX_tag_sample_buffer) return; + glad_glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC) load(userptr, "glTagSampleBufferSGIX"); +} +static void glad_gl_load_GL_SGI_color_table( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SGI_color_table) return; + glad_glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC) load(userptr, "glColorTableParameterfvSGI"); + glad_glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC) load(userptr, "glColorTableParameterivSGI"); + glad_glColorTableSGI = (PFNGLCOLORTABLESGIPROC) load(userptr, "glColorTableSGI"); + glad_glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC) load(userptr, "glCopyColorTableSGI"); + glad_glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) load(userptr, "glGetColorTableParameterfvSGI"); + glad_glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) load(userptr, "glGetColorTableParameterivSGI"); + glad_glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC) load(userptr, "glGetColorTableSGI"); +} +static void glad_gl_load_GL_SUNX_constant_data( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SUNX_constant_data) return; + glad_glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC) load(userptr, "glFinishTextureSUNX"); +} +static void glad_gl_load_GL_SUN_global_alpha( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SUN_global_alpha) return; + glad_glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC) load(userptr, "glGlobalAlphaFactorbSUN"); + glad_glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC) load(userptr, "glGlobalAlphaFactordSUN"); + glad_glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC) load(userptr, "glGlobalAlphaFactorfSUN"); + glad_glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC) load(userptr, "glGlobalAlphaFactoriSUN"); + glad_glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC) load(userptr, "glGlobalAlphaFactorsSUN"); + glad_glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC) load(userptr, "glGlobalAlphaFactorubSUN"); + glad_glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC) load(userptr, "glGlobalAlphaFactoruiSUN"); + glad_glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC) load(userptr, "glGlobalAlphaFactorusSUN"); +} +static void glad_gl_load_GL_SUN_mesh_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SUN_mesh_array) return; + glad_glDrawMeshArraysSUN = (PFNGLDRAWMESHARRAYSSUNPROC) load(userptr, "glDrawMeshArraysSUN"); +} +static void glad_gl_load_GL_SUN_triangle_list( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SUN_triangle_list) return; + glad_glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC) load(userptr, "glReplacementCodePointerSUN"); + glad_glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC) load(userptr, "glReplacementCodeubSUN"); + glad_glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC) load(userptr, "glReplacementCodeubvSUN"); + glad_glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC) load(userptr, "glReplacementCodeuiSUN"); + glad_glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC) load(userptr, "glReplacementCodeuivSUN"); + glad_glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC) load(userptr, "glReplacementCodeusSUN"); + glad_glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC) load(userptr, "glReplacementCodeusvSUN"); +} +static void glad_gl_load_GL_SUN_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_SUN_vertex) return; + glad_glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC) load(userptr, "glColor3fVertex3fSUN"); + glad_glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC) load(userptr, "glColor3fVertex3fvSUN"); + glad_glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glColor4fNormal3fVertex3fSUN"); + glad_glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glColor4fNormal3fVertex3fvSUN"); + glad_glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC) load(userptr, "glColor4ubVertex2fSUN"); + glad_glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC) load(userptr, "glColor4ubVertex2fvSUN"); + glad_glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC) load(userptr, "glColor4ubVertex3fSUN"); + glad_glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC) load(userptr, "glColor4ubVertex3fvSUN"); + glad_glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC) load(userptr, "glNormal3fVertex3fSUN"); + glad_glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glNormal3fVertex3fvSUN"); + glad_glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiColor3fVertex3fSUN"); + glad_glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiColor3fVertex3fvSUN"); + glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiColor4fNormal3fVertex3fSUN"); + glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiColor4fNormal3fVertex3fvSUN"); + glad_glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiColor4ubVertex3fSUN"); + glad_glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiColor4ubVertex3fvSUN"); + glad_glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiNormal3fVertex3fSUN"); + glad_glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiNormal3fVertex3fvSUN"); + glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN"); + glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN"); + glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN"); + glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN"); + glad_glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fVertex3fSUN"); + glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiTexCoord2fVertex3fvSUN"); + glad_glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) load(userptr, "glReplacementCodeuiVertex3fSUN"); + glad_glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) load(userptr, "glReplacementCodeuiVertex3fvSUN"); + glad_glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) load(userptr, "glTexCoord2fColor3fVertex3fSUN"); + glad_glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) load(userptr, "glTexCoord2fColor3fVertex3fvSUN"); + glad_glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glTexCoord2fColor4fNormal3fVertex3fSUN"); + glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glTexCoord2fColor4fNormal3fVertex3fvSUN"); + glad_glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) load(userptr, "glTexCoord2fColor4ubVertex3fSUN"); + glad_glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) load(userptr, "glTexCoord2fColor4ubVertex3fvSUN"); + glad_glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) load(userptr, "glTexCoord2fNormal3fVertex3fSUN"); + glad_glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) load(userptr, "glTexCoord2fNormal3fVertex3fvSUN"); + glad_glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC) load(userptr, "glTexCoord2fVertex3fSUN"); + glad_glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC) load(userptr, "glTexCoord2fVertex3fvSUN"); + glad_glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) load(userptr, "glTexCoord4fColor4fNormal3fVertex4fSUN"); + glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) load(userptr, "glTexCoord4fColor4fNormal3fVertex4fvSUN"); + glad_glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC) load(userptr, "glTexCoord4fVertex4fSUN"); + glad_glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC) load(userptr, "glTexCoord4fVertex4fvSUN"); +} +static void glad_gl_load_GL_APPLE_copy_texture_levels( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_copy_texture_levels) return; + glad_glCopyTextureLevelsAPPLE = (PFNGLCOPYTEXTURELEVELSAPPLEPROC) load(userptr, "glCopyTextureLevelsAPPLE"); +} +static void glad_gl_load_GL_APPLE_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_framebuffer_multisample) return; + glad_glRenderbufferStorageMultisampleAPPLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) load(userptr, "glRenderbufferStorageMultisampleAPPLE"); + glad_glResolveMultisampleFramebufferAPPLE = (PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) load(userptr, "glResolveMultisampleFramebufferAPPLE"); +} +static void glad_gl_load_GL_APPLE_sync( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_APPLE_sync) return; + glad_glClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC) load(userptr, "glClientWaitSyncAPPLE"); + glad_glDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC) load(userptr, "glDeleteSyncAPPLE"); + glad_glFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC) load(userptr, "glFenceSyncAPPLE"); + glad_glGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC) load(userptr, "glGetInteger64vAPPLE"); + glad_glGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC) load(userptr, "glGetSyncivAPPLE"); + glad_glIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC) load(userptr, "glIsSyncAPPLE"); + glad_glWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC) load(userptr, "glWaitSyncAPPLE"); +} +static void glad_gl_load_GL_EXT_discard_framebuffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_discard_framebuffer) return; + glad_glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC) load(userptr, "glDiscardFramebufferEXT"); +} +static void glad_gl_load_GL_EXT_map_buffer_range( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_map_buffer_range) return; + glad_glFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) load(userptr, "glFlushMappedBufferRangeEXT"); + glad_glMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC) load(userptr, "glMapBufferRangeEXT"); +} +static void glad_gl_load_GL_EXT_multisampled_render_to_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multisampled_render_to_texture) return; + glad_glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) load(userptr, "glFramebufferTexture2DMultisampleEXT"); + glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT"); +} +static void glad_gl_load_GL_EXT_robustness( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_robustness) return; + glad_glGetGraphicsResetStatusEXT = (PFNGLGETGRAPHICSRESETSTATUSEXTPROC) load(userptr, "glGetGraphicsResetStatusEXT"); + glad_glGetnUniformfvEXT = (PFNGLGETNUNIFORMFVEXTPROC) load(userptr, "glGetnUniformfvEXT"); + glad_glGetnUniformivEXT = (PFNGLGETNUNIFORMIVEXTPROC) load(userptr, "glGetnUniformivEXT"); + glad_glReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC) load(userptr, "glReadnPixelsEXT"); +} +static void glad_gl_load_GL_IMG_multisampled_render_to_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IMG_multisampled_render_to_texture) return; + glad_glFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) load(userptr, "glFramebufferTexture2DMultisampleIMG"); + glad_glRenderbufferStorageMultisampleIMG = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) load(userptr, "glRenderbufferStorageMultisampleIMG"); +} +static void glad_gl_load_GL_IMG_user_clip_plane( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IMG_user_clip_plane) return; + glad_glClipPlanefIMG = (PFNGLCLIPPLANEFIMGPROC) load(userptr, "glClipPlanefIMG"); + glad_glClipPlanexIMG = (PFNGLCLIPPLANEXIMGPROC) load(userptr, "glClipPlanexIMG"); +} +static void glad_gl_load_GL_OES_EGL_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_EGL_image) return; + glad_glEGLImageTargetRenderbufferStorageOES = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) load(userptr, "glEGLImageTargetRenderbufferStorageOES"); + glad_glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) load(userptr, "glEGLImageTargetTexture2DOES"); +} +static void glad_gl_load_GL_OES_blend_equation_separate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_blend_equation_separate) return; + glad_glBlendEquationSeparateOES = (PFNGLBLENDEQUATIONSEPARATEOESPROC) load(userptr, "glBlendEquationSeparateOES"); +} +static void glad_gl_load_GL_OES_blend_func_separate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_blend_func_separate) return; + glad_glBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOESPROC) load(userptr, "glBlendFuncSeparateOES"); +} +static void glad_gl_load_GL_OES_blend_subtract( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_blend_subtract) return; + glad_glBlendEquationOES = (PFNGLBLENDEQUATIONOESPROC) load(userptr, "glBlendEquationOES"); +} +static void glad_gl_load_GL_OES_draw_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_draw_texture) return; + glad_glDrawTexfOES = (PFNGLDRAWTEXFOESPROC) load(userptr, "glDrawTexfOES"); + glad_glDrawTexfvOES = (PFNGLDRAWTEXFVOESPROC) load(userptr, "glDrawTexfvOES"); + glad_glDrawTexiOES = (PFNGLDRAWTEXIOESPROC) load(userptr, "glDrawTexiOES"); + glad_glDrawTexivOES = (PFNGLDRAWTEXIVOESPROC) load(userptr, "glDrawTexivOES"); + glad_glDrawTexsOES = (PFNGLDRAWTEXSOESPROC) load(userptr, "glDrawTexsOES"); + glad_glDrawTexsvOES = (PFNGLDRAWTEXSVOESPROC) load(userptr, "glDrawTexsvOES"); + glad_glDrawTexxOES = (PFNGLDRAWTEXXOESPROC) load(userptr, "glDrawTexxOES"); + glad_glDrawTexxvOES = (PFNGLDRAWTEXXVOESPROC) load(userptr, "glDrawTexxvOES"); +} +static void glad_gl_load_GL_OES_framebuffer_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_framebuffer_object) return; + glad_glBindFramebufferOES = (PFNGLBINDFRAMEBUFFEROESPROC) load(userptr, "glBindFramebufferOES"); + glad_glBindRenderbufferOES = (PFNGLBINDRENDERBUFFEROESPROC) load(userptr, "glBindRenderbufferOES"); + glad_glCheckFramebufferStatusOES = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) load(userptr, "glCheckFramebufferStatusOES"); + glad_glDeleteFramebuffersOES = (PFNGLDELETEFRAMEBUFFERSOESPROC) load(userptr, "glDeleteFramebuffersOES"); + glad_glDeleteRenderbuffersOES = (PFNGLDELETERENDERBUFFERSOESPROC) load(userptr, "glDeleteRenderbuffersOES"); + glad_glFramebufferRenderbufferOES = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC) load(userptr, "glFramebufferRenderbufferOES"); + glad_glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC) load(userptr, "glFramebufferTexture2DOES"); + glad_glGenFramebuffersOES = (PFNGLGENFRAMEBUFFERSOESPROC) load(userptr, "glGenFramebuffersOES"); + glad_glGenRenderbuffersOES = (PFNGLGENRENDERBUFFERSOESPROC) load(userptr, "glGenRenderbuffersOES"); + glad_glGenerateMipmapOES = (PFNGLGENERATEMIPMAPOESPROC) load(userptr, "glGenerateMipmapOES"); + glad_glGetFramebufferAttachmentParameterivOES = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC) load(userptr, "glGetFramebufferAttachmentParameterivOES"); + glad_glGetRenderbufferParameterivOES = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC) load(userptr, "glGetRenderbufferParameterivOES"); + glad_glIsFramebufferOES = (PFNGLISFRAMEBUFFEROESPROC) load(userptr, "glIsFramebufferOES"); + glad_glIsRenderbufferOES = (PFNGLISRENDERBUFFEROESPROC) load(userptr, "glIsRenderbufferOES"); + glad_glRenderbufferStorageOES = (PFNGLRENDERBUFFERSTORAGEOESPROC) load(userptr, "glRenderbufferStorageOES"); +} +static void glad_gl_load_GL_OES_mapbuffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_mapbuffer) return; + glad_glGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC) load(userptr, "glGetBufferPointervOES"); + glad_glMapBufferOES = (PFNGLMAPBUFFEROESPROC) load(userptr, "glMapBufferOES"); + glad_glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC) load(userptr, "glUnmapBufferOES"); +} +static void glad_gl_load_GL_OES_matrix_palette( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_matrix_palette) return; + glad_glCurrentPaletteMatrixOES = (PFNGLCURRENTPALETTEMATRIXOESPROC) load(userptr, "glCurrentPaletteMatrixOES"); + glad_glLoadPaletteFromModelViewMatrixOES = (PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC) load(userptr, "glLoadPaletteFromModelViewMatrixOES"); + glad_glMatrixIndexPointerOES = (PFNGLMATRIXINDEXPOINTEROESPROC) load(userptr, "glMatrixIndexPointerOES"); + glad_glWeightPointerOES = (PFNGLWEIGHTPOINTEROESPROC) load(userptr, "glWeightPointerOES"); +} +static void glad_gl_load_GL_OES_point_size_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_point_size_array) return; + glad_glPointSizePointerOES = (PFNGLPOINTSIZEPOINTEROESPROC) load(userptr, "glPointSizePointerOES"); +} +static void glad_gl_load_GL_OES_texture_cube_map( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_cube_map) return; + glad_glGetTexGenfvOES = (PFNGLGETTEXGENFVOESPROC) load(userptr, "glGetTexGenfvOES"); + glad_glGetTexGenivOES = (PFNGLGETTEXGENIVOESPROC) load(userptr, "glGetTexGenivOES"); + glad_glGetTexGenxvOES = (PFNGLGETTEXGENXVOESPROC) load(userptr, "glGetTexGenxvOES"); + glad_glTexGenfOES = (PFNGLTEXGENFOESPROC) load(userptr, "glTexGenfOES"); + glad_glTexGenfvOES = (PFNGLTEXGENFVOESPROC) load(userptr, "glTexGenfvOES"); + glad_glTexGeniOES = (PFNGLTEXGENIOESPROC) load(userptr, "glTexGeniOES"); + glad_glTexGenivOES = (PFNGLTEXGENIVOESPROC) load(userptr, "glTexGenivOES"); + glad_glTexGenxOES = (PFNGLTEXGENXOESPROC) load(userptr, "glTexGenxOES"); + glad_glTexGenxvOES = (PFNGLTEXGENXVOESPROC) load(userptr, "glTexGenxvOES"); +} +static void glad_gl_load_GL_OES_vertex_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_vertex_array_object) return; + glad_glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC) load(userptr, "glBindVertexArrayOES"); + glad_glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC) load(userptr, "glDeleteVertexArraysOES"); + glad_glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC) load(userptr, "glGenVertexArraysOES"); + glad_glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC) load(userptr, "glIsVertexArrayOES"); +} +static void glad_gl_load_GL_QCOM_driver_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_driver_control) return; + glad_glDisableDriverControlQCOM = (PFNGLDISABLEDRIVERCONTROLQCOMPROC) load(userptr, "glDisableDriverControlQCOM"); + glad_glEnableDriverControlQCOM = (PFNGLENABLEDRIVERCONTROLQCOMPROC) load(userptr, "glEnableDriverControlQCOM"); + glad_glGetDriverControlStringQCOM = (PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) load(userptr, "glGetDriverControlStringQCOM"); + glad_glGetDriverControlsQCOM = (PFNGLGETDRIVERCONTROLSQCOMPROC) load(userptr, "glGetDriverControlsQCOM"); +} +static void glad_gl_load_GL_QCOM_extended_get( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_extended_get) return; + glad_glExtGetBufferPointervQCOM = (PFNGLEXTGETBUFFERPOINTERVQCOMPROC) load(userptr, "glExtGetBufferPointervQCOM"); + glad_glExtGetBuffersQCOM = (PFNGLEXTGETBUFFERSQCOMPROC) load(userptr, "glExtGetBuffersQCOM"); + glad_glExtGetFramebuffersQCOM = (PFNGLEXTGETFRAMEBUFFERSQCOMPROC) load(userptr, "glExtGetFramebuffersQCOM"); + glad_glExtGetRenderbuffersQCOM = (PFNGLEXTGETRENDERBUFFERSQCOMPROC) load(userptr, "glExtGetRenderbuffersQCOM"); + glad_glExtGetTexLevelParameterivQCOM = (PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) load(userptr, "glExtGetTexLevelParameterivQCOM"); + glad_glExtGetTexSubImageQCOM = (PFNGLEXTGETTEXSUBIMAGEQCOMPROC) load(userptr, "glExtGetTexSubImageQCOM"); + glad_glExtGetTexturesQCOM = (PFNGLEXTGETTEXTURESQCOMPROC) load(userptr, "glExtGetTexturesQCOM"); + glad_glExtTexObjectStateOverrideiQCOM = (PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) load(userptr, "glExtTexObjectStateOverrideiQCOM"); +} +static void glad_gl_load_GL_QCOM_extended_get2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_extended_get2) return; + glad_glExtGetProgramBinarySourceQCOM = (PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) load(userptr, "glExtGetProgramBinarySourceQCOM"); + glad_glExtGetProgramsQCOM = (PFNGLEXTGETPROGRAMSQCOMPROC) load(userptr, "glExtGetProgramsQCOM"); + glad_glExtGetShadersQCOM = (PFNGLEXTGETSHADERSQCOMPROC) load(userptr, "glExtGetShadersQCOM"); + glad_glExtIsProgramBinaryQCOM = (PFNGLEXTISPROGRAMBINARYQCOMPROC) load(userptr, "glExtIsProgramBinaryQCOM"); +} +static void glad_gl_load_GL_QCOM_tiled_rendering( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_tiled_rendering) return; + glad_glEndTilingQCOM = (PFNGLENDTILINGQCOMPROC) load(userptr, "glEndTilingQCOM"); + glad_glStartTilingQCOM = (PFNGLSTARTTILINGQCOMPROC) load(userptr, "glStartTilingQCOM"); +} +static void glad_gl_load_GL_ANGLE_framebuffer_blit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ANGLE_framebuffer_blit) return; + glad_glBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC) load(userptr, "glBlitFramebufferANGLE"); +} +static void glad_gl_load_GL_ANGLE_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ANGLE_framebuffer_multisample) return; + glad_glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) load(userptr, "glRenderbufferStorageMultisampleANGLE"); +} +static void glad_gl_load_GL_ANGLE_instanced_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ANGLE_instanced_arrays) return; + glad_glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC) load(userptr, "glDrawArraysInstancedANGLE"); + glad_glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) load(userptr, "glDrawElementsInstancedANGLE"); + glad_glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC) load(userptr, "glVertexAttribDivisorANGLE"); +} +static void glad_gl_load_GL_ANGLE_translated_shader_source( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ANGLE_translated_shader_source) return; + glad_glGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) load(userptr, "glGetTranslatedShaderSourceANGLE"); +} +static void glad_gl_load_GL_ARM_shader_core_properties( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARM_shader_core_properties) return; + glad_glMaxActiveShaderCoresARM = (PFNGLMAXACTIVESHADERCORESARMPROC) load(userptr, "glMaxActiveShaderCoresARM"); +} +static void glad_gl_load_GL_EXT_base_instance( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_base_instance) return; + glad_glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) load(userptr, "glDrawArraysInstancedBaseInstanceEXT"); + glad_glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) load(userptr, "glDrawElementsInstancedBaseInstanceEXT"); + glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstanceEXT"); +} +static void glad_gl_load_GL_EXT_blend_func_extended( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_blend_func_extended) return; + glad_glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC) load(userptr, "glBindFragDataLocationEXT"); + glad_glBindFragDataLocationIndexedEXT = (PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) load(userptr, "glBindFragDataLocationIndexedEXT"); + glad_glGetFragDataIndexEXT = (PFNGLGETFRAGDATAINDEXEXTPROC) load(userptr, "glGetFragDataIndexEXT"); + glad_glGetProgramResourceLocationIndexEXT = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) load(userptr, "glGetProgramResourceLocationIndexEXT"); +} +static void glad_gl_load_GL_EXT_buffer_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_buffer_storage) return; + glad_glBufferStorageEXT = (PFNGLBUFFERSTORAGEEXTPROC) load(userptr, "glBufferStorageEXT"); +} +static void glad_gl_load_GL_EXT_clear_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_clear_texture) return; + glad_glClearTexImageEXT = (PFNGLCLEARTEXIMAGEEXTPROC) load(userptr, "glClearTexImageEXT"); + glad_glClearTexSubImageEXT = (PFNGLCLEARTEXSUBIMAGEEXTPROC) load(userptr, "glClearTexSubImageEXT"); +} +static void glad_gl_load_GL_EXT_clip_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_clip_control) return; + glad_glClipControlEXT = (PFNGLCLIPCONTROLEXTPROC) load(userptr, "glClipControlEXT"); +} +static void glad_gl_load_GL_EXT_copy_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_copy_image) return; + glad_glCopyImageSubDataEXT = (PFNGLCOPYIMAGESUBDATAEXTPROC) load(userptr, "glCopyImageSubDataEXT"); +} +static void glad_gl_load_GL_EXT_disjoint_timer_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_disjoint_timer_query) return; + glad_glBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) load(userptr, "glBeginQueryEXT"); + glad_glDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) load(userptr, "glDeleteQueriesEXT"); + glad_glEndQueryEXT = (PFNGLENDQUERYEXTPROC) load(userptr, "glEndQueryEXT"); + glad_glGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) load(userptr, "glGenQueriesEXT"); + glad_glGetInteger64vEXT = (PFNGLGETINTEGER64VEXTPROC) load(userptr, "glGetInteger64vEXT"); + glad_glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC) load(userptr, "glGetQueryObjecti64vEXT"); + glad_glGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC) load(userptr, "glGetQueryObjectivEXT"); + glad_glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) load(userptr, "glGetQueryObjectui64vEXT"); + glad_glGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC) load(userptr, "glGetQueryObjectuivEXT"); + glad_glGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) load(userptr, "glGetQueryivEXT"); + glad_glIsQueryEXT = (PFNGLISQUERYEXTPROC) load(userptr, "glIsQueryEXT"); + glad_glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC) load(userptr, "glQueryCounterEXT"); +} +static void glad_gl_load_GL_EXT_draw_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_buffers) return; + glad_glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC) load(userptr, "glDrawBuffersEXT"); +} +static void glad_gl_load_GL_EXT_draw_buffers_indexed( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_buffers_indexed) return; + glad_glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC) load(userptr, "glBlendEquationSeparateiEXT"); + glad_glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC) load(userptr, "glBlendEquationiEXT"); + glad_glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC) load(userptr, "glBlendFuncSeparateiEXT"); + glad_glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC) load(userptr, "glBlendFunciEXT"); + glad_glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC) load(userptr, "glColorMaskiEXT"); + glad_glDisableiEXT = (PFNGLDISABLEIEXTPROC) load(userptr, "glDisableiEXT"); + glad_glEnableiEXT = (PFNGLENABLEIEXTPROC) load(userptr, "glEnableiEXT"); + glad_glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC) load(userptr, "glIsEnablediEXT"); +} +static void glad_gl_load_GL_EXT_draw_elements_base_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_elements_base_vertex) return; + glad_glDrawElementsBaseVertexEXT = (PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) load(userptr, "glDrawElementsBaseVertexEXT"); + glad_glDrawElementsInstancedBaseVertexEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) load(userptr, "glDrawElementsInstancedBaseVertexEXT"); + glad_glDrawRangeElementsBaseVertexEXT = (PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) load(userptr, "glDrawRangeElementsBaseVertexEXT"); + glad_glMultiDrawElementsBaseVertexEXT = (PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) load(userptr, "glMultiDrawElementsBaseVertexEXT"); +} +static void glad_gl_load_GL_EXT_draw_transform_feedback( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_draw_transform_feedback) return; + glad_glDrawTransformFeedbackEXT = (PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) load(userptr, "glDrawTransformFeedbackEXT"); + glad_glDrawTransformFeedbackInstancedEXT = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) load(userptr, "glDrawTransformFeedbackInstancedEXT"); +} +static void glad_gl_load_GL_EXT_fragment_shading_rate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_fragment_shading_rate) return; + glad_glFramebufferShadingRateEXT = (PFNGLFRAMEBUFFERSHADINGRATEEXTPROC) load(userptr, "glFramebufferShadingRateEXT"); + glad_glGetFragmentShadingRatesEXT = (PFNGLGETFRAGMENTSHADINGRATESEXTPROC) load(userptr, "glGetFragmentShadingRatesEXT"); + glad_glShadingRateCombinerOpsEXT = (PFNGLSHADINGRATECOMBINEROPSEXTPROC) load(userptr, "glShadingRateCombinerOpsEXT"); + glad_glShadingRateEXT = (PFNGLSHADINGRATEEXTPROC) load(userptr, "glShadingRateEXT"); +} +static void glad_gl_load_GL_EXT_geometry_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_geometry_shader) return; + glad_glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC) load(userptr, "glFramebufferTextureEXT"); +} +static void glad_gl_load_GL_EXT_instanced_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_instanced_arrays) return; + glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) load(userptr, "glDrawArraysInstancedEXT"); + glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) load(userptr, "glDrawElementsInstancedEXT"); + glad_glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC) load(userptr, "glVertexAttribDivisorEXT"); +} +static void glad_gl_load_GL_EXT_multi_draw_indirect( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multi_draw_indirect) return; + glad_glMultiDrawArraysIndirectEXT = (PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) load(userptr, "glMultiDrawArraysIndirectEXT"); + glad_glMultiDrawElementsIndirectEXT = (PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) load(userptr, "glMultiDrawElementsIndirectEXT"); +} +static void glad_gl_load_GL_EXT_multiview_draw_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multiview_draw_buffers) return; + glad_glDrawBuffersIndexedEXT = (PFNGLDRAWBUFFERSINDEXEDEXTPROC) load(userptr, "glDrawBuffersIndexedEXT"); + glad_glGetIntegeri_vEXT = (PFNGLGETINTEGERI_VEXTPROC) load(userptr, "glGetIntegeri_vEXT"); + glad_glReadBufferIndexedEXT = (PFNGLREADBUFFERINDEXEDEXTPROC) load(userptr, "glReadBufferIndexedEXT"); +} +static void glad_gl_load_GL_EXT_occlusion_query_boolean( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_occlusion_query_boolean) return; + glad_glBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) load(userptr, "glBeginQueryEXT"); + glad_glDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) load(userptr, "glDeleteQueriesEXT"); + glad_glEndQueryEXT = (PFNGLENDQUERYEXTPROC) load(userptr, "glEndQueryEXT"); + glad_glGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) load(userptr, "glGenQueriesEXT"); + glad_glGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC) load(userptr, "glGetQueryObjectuivEXT"); + glad_glGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) load(userptr, "glGetQueryivEXT"); + glad_glIsQueryEXT = (PFNGLISQUERYEXTPROC) load(userptr, "glIsQueryEXT"); +} +static void glad_gl_load_GL_EXT_primitive_bounding_box( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_primitive_bounding_box) return; + glad_glPrimitiveBoundingBoxEXT = (PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) load(userptr, "glPrimitiveBoundingBoxEXT"); +} +static void glad_gl_load_GL_EXT_separate_shader_objects( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_separate_shader_objects) return; + glad_glActiveShaderProgramEXT = (PFNGLACTIVESHADERPROGRAMEXTPROC) load(userptr, "glActiveShaderProgramEXT"); + glad_glBindProgramPipelineEXT = (PFNGLBINDPROGRAMPIPELINEEXTPROC) load(userptr, "glBindProgramPipelineEXT"); + glad_glCreateShaderProgramvEXT = (PFNGLCREATESHADERPROGRAMVEXTPROC) load(userptr, "glCreateShaderProgramvEXT"); + glad_glDeleteProgramPipelinesEXT = (PFNGLDELETEPROGRAMPIPELINESEXTPROC) load(userptr, "glDeleteProgramPipelinesEXT"); + glad_glGenProgramPipelinesEXT = (PFNGLGENPROGRAMPIPELINESEXTPROC) load(userptr, "glGenProgramPipelinesEXT"); + glad_glGetProgramPipelineInfoLogEXT = (PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) load(userptr, "glGetProgramPipelineInfoLogEXT"); + glad_glGetProgramPipelineivEXT = (PFNGLGETPROGRAMPIPELINEIVEXTPROC) load(userptr, "glGetProgramPipelineivEXT"); + glad_glIsProgramPipelineEXT = (PFNGLISPROGRAMPIPELINEEXTPROC) load(userptr, "glIsProgramPipelineEXT"); + glad_glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) load(userptr, "glProgramParameteriEXT"); + glad_glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) load(userptr, "glProgramUniform1fEXT"); + glad_glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) load(userptr, "glProgramUniform1fvEXT"); + glad_glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) load(userptr, "glProgramUniform1iEXT"); + glad_glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) load(userptr, "glProgramUniform1ivEXT"); + glad_glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC) load(userptr, "glProgramUniform1uiEXT"); + glad_glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC) load(userptr, "glProgramUniform1uivEXT"); + glad_glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) load(userptr, "glProgramUniform2fEXT"); + glad_glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) load(userptr, "glProgramUniform2fvEXT"); + glad_glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) load(userptr, "glProgramUniform2iEXT"); + glad_glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) load(userptr, "glProgramUniform2ivEXT"); + glad_glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC) load(userptr, "glProgramUniform2uiEXT"); + glad_glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC) load(userptr, "glProgramUniform2uivEXT"); + glad_glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) load(userptr, "glProgramUniform3fEXT"); + glad_glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) load(userptr, "glProgramUniform3fvEXT"); + glad_glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) load(userptr, "glProgramUniform3iEXT"); + glad_glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) load(userptr, "glProgramUniform3ivEXT"); + glad_glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC) load(userptr, "glProgramUniform3uiEXT"); + glad_glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC) load(userptr, "glProgramUniform3uivEXT"); + glad_glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) load(userptr, "glProgramUniform4fEXT"); + glad_glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) load(userptr, "glProgramUniform4fvEXT"); + glad_glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) load(userptr, "glProgramUniform4iEXT"); + glad_glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) load(userptr, "glProgramUniform4ivEXT"); + glad_glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC) load(userptr, "glProgramUniform4uiEXT"); + glad_glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC) load(userptr, "glProgramUniform4uivEXT"); + glad_glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) load(userptr, "glProgramUniformMatrix2fvEXT"); + glad_glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) load(userptr, "glProgramUniformMatrix2x3fvEXT"); + glad_glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) load(userptr, "glProgramUniformMatrix2x4fvEXT"); + glad_glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) load(userptr, "glProgramUniformMatrix3fvEXT"); + glad_glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) load(userptr, "glProgramUniformMatrix3x2fvEXT"); + glad_glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) load(userptr, "glProgramUniformMatrix3x4fvEXT"); + glad_glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) load(userptr, "glProgramUniformMatrix4fvEXT"); + glad_glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) load(userptr, "glProgramUniformMatrix4x2fvEXT"); + glad_glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) load(userptr, "glProgramUniformMatrix4x3fvEXT"); + glad_glUseProgramStagesEXT = (PFNGLUSEPROGRAMSTAGESEXTPROC) load(userptr, "glUseProgramStagesEXT"); + glad_glValidateProgramPipelineEXT = (PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) load(userptr, "glValidateProgramPipelineEXT"); +} +static void glad_gl_load_GL_EXT_shader_pixel_local_storage2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_shader_pixel_local_storage2) return; + glad_glClearPixelLocalStorageuiEXT = (PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) load(userptr, "glClearPixelLocalStorageuiEXT"); + glad_glFramebufferPixelLocalStorageSizeEXT = (PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) load(userptr, "glFramebufferPixelLocalStorageSizeEXT"); + glad_glGetFramebufferPixelLocalStorageSizeEXT = (PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) load(userptr, "glGetFramebufferPixelLocalStorageSizeEXT"); +} +static void glad_gl_load_GL_EXT_sparse_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_sparse_texture) return; + glad_glTexPageCommitmentEXT = (PFNGLTEXPAGECOMMITMENTEXTPROC) load(userptr, "glTexPageCommitmentEXT"); +} +static void glad_gl_load_GL_EXT_tessellation_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_tessellation_shader) return; + glad_glPatchParameteriEXT = (PFNGLPATCHPARAMETERIEXTPROC) load(userptr, "glPatchParameteriEXT"); +} +static void glad_gl_load_GL_EXT_texture_border_clamp( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_border_clamp) return; + glad_glGetSamplerParameterIivEXT = (PFNGLGETSAMPLERPARAMETERIIVEXTPROC) load(userptr, "glGetSamplerParameterIivEXT"); + glad_glGetSamplerParameterIuivEXT = (PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) load(userptr, "glGetSamplerParameterIuivEXT"); + glad_glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC) load(userptr, "glGetTexParameterIivEXT"); + glad_glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC) load(userptr, "glGetTexParameterIuivEXT"); + glad_glSamplerParameterIivEXT = (PFNGLSAMPLERPARAMETERIIVEXTPROC) load(userptr, "glSamplerParameterIivEXT"); + glad_glSamplerParameterIuivEXT = (PFNGLSAMPLERPARAMETERIUIVEXTPROC) load(userptr, "glSamplerParameterIuivEXT"); + glad_glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC) load(userptr, "glTexParameterIivEXT"); + glad_glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC) load(userptr, "glTexParameterIuivEXT"); +} +static void glad_gl_load_GL_EXT_texture_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_buffer) return; + glad_glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC) load(userptr, "glTexBufferEXT"); + glad_glTexBufferRangeEXT = (PFNGLTEXBUFFERRANGEEXTPROC) load(userptr, "glTexBufferRangeEXT"); +} +static void glad_gl_load_GL_EXT_texture_storage_compression( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_storage_compression) return; + glad_glTexStorageAttribs2DEXT = (PFNGLTEXSTORAGEATTRIBS2DEXTPROC) load(userptr, "glTexStorageAttribs2DEXT"); + glad_glTexStorageAttribs3DEXT = (PFNGLTEXSTORAGEATTRIBS3DEXTPROC) load(userptr, "glTexStorageAttribs3DEXT"); +} +static void glad_gl_load_GL_EXT_texture_view( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_view) return; + glad_glTextureViewEXT = (PFNGLTEXTUREVIEWEXTPROC) load(userptr, "glTextureViewEXT"); +} +static void glad_gl_load_GL_IMG_bindless_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IMG_bindless_texture) return; + glad_glGetTextureHandleIMG = (PFNGLGETTEXTUREHANDLEIMGPROC) load(userptr, "glGetTextureHandleIMG"); + glad_glGetTextureSamplerHandleIMG = (PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) load(userptr, "glGetTextureSamplerHandleIMG"); + glad_glProgramUniformHandleui64IMG = (PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) load(userptr, "glProgramUniformHandleui64IMG"); + glad_glProgramUniformHandleui64vIMG = (PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) load(userptr, "glProgramUniformHandleui64vIMG"); + glad_glUniformHandleui64IMG = (PFNGLUNIFORMHANDLEUI64IMGPROC) load(userptr, "glUniformHandleui64IMG"); + glad_glUniformHandleui64vIMG = (PFNGLUNIFORMHANDLEUI64VIMGPROC) load(userptr, "glUniformHandleui64vIMG"); +} +static void glad_gl_load_GL_IMG_framebuffer_downsample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_IMG_framebuffer_downsample) return; + glad_glFramebufferTexture2DDownsampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) load(userptr, "glFramebufferTexture2DDownsampleIMG"); + glad_glFramebufferTextureLayerDownsampleIMG = (PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) load(userptr, "glFramebufferTextureLayerDownsampleIMG"); +} +static void glad_gl_load_GL_MESA_sampler_objects( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_MESA_sampler_objects) return; + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); +} +static void glad_gl_load_GL_NV_copy_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_copy_buffer) return; + glad_glCopyBufferSubDataNV = (PFNGLCOPYBUFFERSUBDATANVPROC) load(userptr, "glCopyBufferSubDataNV"); +} +static void glad_gl_load_GL_NV_coverage_sample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_coverage_sample) return; + glad_glCoverageMaskNV = (PFNGLCOVERAGEMASKNVPROC) load(userptr, "glCoverageMaskNV"); + glad_glCoverageOperationNV = (PFNGLCOVERAGEOPERATIONNVPROC) load(userptr, "glCoverageOperationNV"); +} +static void glad_gl_load_GL_NV_draw_buffers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_draw_buffers) return; + glad_glDrawBuffersNV = (PFNGLDRAWBUFFERSNVPROC) load(userptr, "glDrawBuffersNV"); +} +static void glad_gl_load_GL_NV_draw_instanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_draw_instanced) return; + glad_glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC) load(userptr, "glDrawArraysInstancedNV"); + glad_glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC) load(userptr, "glDrawElementsInstancedNV"); +} +static void glad_gl_load_GL_NV_framebuffer_blit( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_framebuffer_blit) return; + glad_glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC) load(userptr, "glBlitFramebufferNV"); +} +static void glad_gl_load_GL_NV_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_framebuffer_multisample) return; + glad_glRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) load(userptr, "glRenderbufferStorageMultisampleNV"); +} +static void glad_gl_load_GL_NV_instanced_arrays( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_instanced_arrays) return; + glad_glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC) load(userptr, "glVertexAttribDivisorNV"); +} +static void glad_gl_load_GL_NV_non_square_matrices( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_non_square_matrices) return; + glad_glUniformMatrix2x3fvNV = (PFNGLUNIFORMMATRIX2X3FVNVPROC) load(userptr, "glUniformMatrix2x3fvNV"); + glad_glUniformMatrix2x4fvNV = (PFNGLUNIFORMMATRIX2X4FVNVPROC) load(userptr, "glUniformMatrix2x4fvNV"); + glad_glUniformMatrix3x2fvNV = (PFNGLUNIFORMMATRIX3X2FVNVPROC) load(userptr, "glUniformMatrix3x2fvNV"); + glad_glUniformMatrix3x4fvNV = (PFNGLUNIFORMMATRIX3X4FVNVPROC) load(userptr, "glUniformMatrix3x4fvNV"); + glad_glUniformMatrix4x2fvNV = (PFNGLUNIFORMMATRIX4X2FVNVPROC) load(userptr, "glUniformMatrix4x2fvNV"); + glad_glUniformMatrix4x3fvNV = (PFNGLUNIFORMMATRIX4X3FVNVPROC) load(userptr, "glUniformMatrix4x3fvNV"); +} +static void glad_gl_load_GL_NV_polygon_mode( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_polygon_mode) return; + glad_glPolygonModeNV = (PFNGLPOLYGONMODENVPROC) load(userptr, "glPolygonModeNV"); +} +static void glad_gl_load_GL_NV_read_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_read_buffer) return; + glad_glReadBufferNV = (PFNGLREADBUFFERNVPROC) load(userptr, "glReadBufferNV"); +} +static void glad_gl_load_GL_NV_viewport_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_NV_viewport_array) return; + glad_glDepthRangeArrayfvNV = (PFNGLDEPTHRANGEARRAYFVNVPROC) load(userptr, "glDepthRangeArrayfvNV"); + glad_glDepthRangeIndexedfNV = (PFNGLDEPTHRANGEINDEXEDFNVPROC) load(userptr, "glDepthRangeIndexedfNV"); + glad_glDisableiNV = (PFNGLDISABLEINVPROC) load(userptr, "glDisableiNV"); + glad_glEnableiNV = (PFNGLENABLEINVPROC) load(userptr, "glEnableiNV"); + glad_glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC) load(userptr, "glGetFloati_vNV"); + glad_glIsEnablediNV = (PFNGLISENABLEDINVPROC) load(userptr, "glIsEnablediNV"); + glad_glScissorArrayvNV = (PFNGLSCISSORARRAYVNVPROC) load(userptr, "glScissorArrayvNV"); + glad_glScissorIndexedNV = (PFNGLSCISSORINDEXEDNVPROC) load(userptr, "glScissorIndexedNV"); + glad_glScissorIndexedvNV = (PFNGLSCISSORINDEXEDVNVPROC) load(userptr, "glScissorIndexedvNV"); + glad_glViewportArrayvNV = (PFNGLVIEWPORTARRAYVNVPROC) load(userptr, "glViewportArrayvNV"); + glad_glViewportIndexedfNV = (PFNGLVIEWPORTINDEXEDFNVPROC) load(userptr, "glViewportIndexedfNV"); + glad_glViewportIndexedfvNV = (PFNGLVIEWPORTINDEXEDFVNVPROC) load(userptr, "glViewportIndexedfvNV"); +} +static void glad_gl_load_GL_OES_copy_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_copy_image) return; + glad_glCopyImageSubDataOES = (PFNGLCOPYIMAGESUBDATAOESPROC) load(userptr, "glCopyImageSubDataOES"); +} +static void glad_gl_load_GL_OES_draw_buffers_indexed( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_draw_buffers_indexed) return; + glad_glBlendEquationSeparateiOES = (PFNGLBLENDEQUATIONSEPARATEIOESPROC) load(userptr, "glBlendEquationSeparateiOES"); + glad_glBlendEquationiOES = (PFNGLBLENDEQUATIONIOESPROC) load(userptr, "glBlendEquationiOES"); + glad_glBlendFuncSeparateiOES = (PFNGLBLENDFUNCSEPARATEIOESPROC) load(userptr, "glBlendFuncSeparateiOES"); + glad_glBlendFunciOES = (PFNGLBLENDFUNCIOESPROC) load(userptr, "glBlendFunciOES"); + glad_glColorMaskiOES = (PFNGLCOLORMASKIOESPROC) load(userptr, "glColorMaskiOES"); + glad_glDisableiOES = (PFNGLDISABLEIOESPROC) load(userptr, "glDisableiOES"); + glad_glEnableiOES = (PFNGLENABLEIOESPROC) load(userptr, "glEnableiOES"); + glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC) load(userptr, "glIsEnablediOES"); +} +static void glad_gl_load_GL_OES_draw_elements_base_vertex( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_draw_elements_base_vertex) return; + glad_glDrawElementsBaseVertexOES = (PFNGLDRAWELEMENTSBASEVERTEXOESPROC) load(userptr, "glDrawElementsBaseVertexOES"); + glad_glDrawElementsInstancedBaseVertexOES = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) load(userptr, "glDrawElementsInstancedBaseVertexOES"); + glad_glDrawRangeElementsBaseVertexOES = (PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) load(userptr, "glDrawRangeElementsBaseVertexOES"); + glad_glMultiDrawElementsBaseVertexEXT = (PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) load(userptr, "glMultiDrawElementsBaseVertexEXT"); +} +static void glad_gl_load_GL_OES_geometry_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_geometry_shader) return; + glad_glFramebufferTextureOES = (PFNGLFRAMEBUFFERTEXTUREOESPROC) load(userptr, "glFramebufferTextureOES"); +} +static void glad_gl_load_GL_OES_get_program_binary( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_get_program_binary) return; + glad_glGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) load(userptr, "glGetProgramBinaryOES"); + glad_glProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) load(userptr, "glProgramBinaryOES"); +} +static void glad_gl_load_GL_OES_primitive_bounding_box( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_primitive_bounding_box) return; + glad_glPrimitiveBoundingBoxOES = (PFNGLPRIMITIVEBOUNDINGBOXOESPROC) load(userptr, "glPrimitiveBoundingBoxOES"); +} +static void glad_gl_load_GL_OES_sample_shading( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_sample_shading) return; + glad_glMinSampleShadingOES = (PFNGLMINSAMPLESHADINGOESPROC) load(userptr, "glMinSampleShadingOES"); +} +static void glad_gl_load_GL_OES_tessellation_shader( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_tessellation_shader) return; + glad_glPatchParameteriOES = (PFNGLPATCHPARAMETERIOESPROC) load(userptr, "glPatchParameteriOES"); +} +static void glad_gl_load_GL_OES_texture_3D( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_3D) return; + glad_glCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) load(userptr, "glCompressedTexImage3DOES"); + glad_glCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) load(userptr, "glCompressedTexSubImage3DOES"); + glad_glCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOESPROC) load(userptr, "glCopyTexSubImage3DOES"); + glad_glFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOESPROC) load(userptr, "glFramebufferTexture3DOES"); + glad_glTexImage3DOES = (PFNGLTEXIMAGE3DOESPROC) load(userptr, "glTexImage3DOES"); + glad_glTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOESPROC) load(userptr, "glTexSubImage3DOES"); +} +static void glad_gl_load_GL_OES_texture_border_clamp( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_border_clamp) return; + glad_glGetSamplerParameterIivOES = (PFNGLGETSAMPLERPARAMETERIIVOESPROC) load(userptr, "glGetSamplerParameterIivOES"); + glad_glGetSamplerParameterIuivOES = (PFNGLGETSAMPLERPARAMETERIUIVOESPROC) load(userptr, "glGetSamplerParameterIuivOES"); + glad_glGetTexParameterIivOES = (PFNGLGETTEXPARAMETERIIVOESPROC) load(userptr, "glGetTexParameterIivOES"); + glad_glGetTexParameterIuivOES = (PFNGLGETTEXPARAMETERIUIVOESPROC) load(userptr, "glGetTexParameterIuivOES"); + glad_glSamplerParameterIivOES = (PFNGLSAMPLERPARAMETERIIVOESPROC) load(userptr, "glSamplerParameterIivOES"); + glad_glSamplerParameterIuivOES = (PFNGLSAMPLERPARAMETERIUIVOESPROC) load(userptr, "glSamplerParameterIuivOES"); + glad_glTexParameterIivOES = (PFNGLTEXPARAMETERIIVOESPROC) load(userptr, "glTexParameterIivOES"); + glad_glTexParameterIuivOES = (PFNGLTEXPARAMETERIUIVOESPROC) load(userptr, "glTexParameterIuivOES"); +} +static void glad_gl_load_GL_OES_texture_buffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_buffer) return; + glad_glTexBufferOES = (PFNGLTEXBUFFEROESPROC) load(userptr, "glTexBufferOES"); + glad_glTexBufferRangeOES = (PFNGLTEXBUFFERRANGEOESPROC) load(userptr, "glTexBufferRangeOES"); +} +static void glad_gl_load_GL_OES_texture_storage_multisample_2d_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_storage_multisample_2d_array) return; + glad_glTexStorage3DMultisampleOES = (PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) load(userptr, "glTexStorage3DMultisampleOES"); +} +static void glad_gl_load_GL_OES_texture_view( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_view) return; + glad_glTextureViewOES = (PFNGLTEXTUREVIEWOESPROC) load(userptr, "glTextureViewOES"); +} +static void glad_gl_load_GL_OES_viewport_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_viewport_array) return; + glad_glDepthRangeArrayfvOES = (PFNGLDEPTHRANGEARRAYFVOESPROC) load(userptr, "glDepthRangeArrayfvOES"); + glad_glDepthRangeIndexedfOES = (PFNGLDEPTHRANGEINDEXEDFOESPROC) load(userptr, "glDepthRangeIndexedfOES"); + glad_glDisableiOES = (PFNGLDISABLEIOESPROC) load(userptr, "glDisableiOES"); + glad_glEnableiOES = (PFNGLENABLEIOESPROC) load(userptr, "glEnableiOES"); + glad_glGetFloati_vOES = (PFNGLGETFLOATI_VOESPROC) load(userptr, "glGetFloati_vOES"); + glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC) load(userptr, "glIsEnablediOES"); + glad_glScissorArrayvOES = (PFNGLSCISSORARRAYVOESPROC) load(userptr, "glScissorArrayvOES"); + glad_glScissorIndexedOES = (PFNGLSCISSORINDEXEDOESPROC) load(userptr, "glScissorIndexedOES"); + glad_glScissorIndexedvOES = (PFNGLSCISSORINDEXEDVOESPROC) load(userptr, "glScissorIndexedvOES"); + glad_glViewportArrayvOES = (PFNGLVIEWPORTARRAYVOESPROC) load(userptr, "glViewportArrayvOES"); + glad_glViewportIndexedfOES = (PFNGLVIEWPORTINDEXEDFOESPROC) load(userptr, "glViewportIndexedfOES"); + glad_glViewportIndexedfvOES = (PFNGLVIEWPORTINDEXEDFVOESPROC) load(userptr, "glViewportIndexedfvOES"); +} +static void glad_gl_load_GL_OVR_multiview_multisampled_render_to_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OVR_multiview_multisampled_render_to_texture) return; + glad_glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) load(userptr, "glFramebufferTextureMultisampleMultiviewOVR"); +} +static void glad_gl_load_GL_QCOM_alpha_test( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_alpha_test) return; + glad_glAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC) load(userptr, "glAlphaFuncQCOM"); +} +static void glad_gl_load_GL_QCOM_frame_extrapolation( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_frame_extrapolation) return; + glad_glExtrapolateTex2DQCOM = (PFNGLEXTRAPOLATETEX2DQCOMPROC) load(userptr, "glExtrapolateTex2DQCOM"); +} +static void glad_gl_load_GL_QCOM_framebuffer_foveated( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_framebuffer_foveated) return; + glad_glFramebufferFoveationConfigQCOM = (PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) load(userptr, "glFramebufferFoveationConfigQCOM"); + glad_glFramebufferFoveationParametersQCOM = (PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) load(userptr, "glFramebufferFoveationParametersQCOM"); +} +static void glad_gl_load_GL_QCOM_motion_estimation( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_motion_estimation) return; + glad_glTexEstimateMotionQCOM = (PFNGLTEXESTIMATEMOTIONQCOMPROC) load(userptr, "glTexEstimateMotionQCOM"); + glad_glTexEstimateMotionRegionsQCOM = (PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC) load(userptr, "glTexEstimateMotionRegionsQCOM"); +} +static void glad_gl_load_GL_QCOM_shader_framebuffer_fetch_noncoherent( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_shader_framebuffer_fetch_noncoherent) return; + glad_glFramebufferFetchBarrierQCOM = (PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) load(userptr, "glFramebufferFetchBarrierQCOM"); +} +static void glad_gl_load_GL_QCOM_shading_rate( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_shading_rate) return; + glad_glShadingRateQCOM = (PFNGLSHADINGRATEQCOMPROC) load(userptr, "glShadingRateQCOM"); +} +static void glad_gl_load_GL_QCOM_texture_foveated( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_QCOM_texture_foveated) return; + glad_glTextureFoveationParametersQCOM = (PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) load(userptr, "glTextureFoveationParametersQCOM"); +} + + +static void glad_gl_resolve_aliases(void) { + if (glad_glActiveTexture == NULL && glad_glActiveTextureARB != NULL) glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)glad_glActiveTextureARB; + if (glad_glActiveTextureARB == NULL && glad_glActiveTexture != NULL) glad_glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glad_glActiveTexture; + if (glad_glArrayElement == NULL && glad_glArrayElementEXT != NULL) glad_glArrayElement = (PFNGLARRAYELEMENTPROC)glad_glArrayElementEXT; + if (glad_glArrayElementEXT == NULL && glad_glArrayElement != NULL) glad_glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glad_glArrayElement; + if (glad_glAttachObjectARB == NULL && glad_glAttachShader != NULL) glad_glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glad_glAttachShader; + if (glad_glAttachShader == NULL && glad_glAttachObjectARB != NULL) glad_glAttachShader = (PFNGLATTACHSHADERPROC)glad_glAttachObjectARB; + if (glad_glBeginConditionalRender == NULL && glad_glBeginConditionalRenderNV != NULL) glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glad_glBeginConditionalRenderNV; + if (glad_glBeginConditionalRenderNV == NULL && glad_glBeginConditionalRender != NULL) glad_glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glad_glBeginConditionalRender; + if (glad_glBeginQuery == NULL && glad_glBeginQueryARB != NULL) glad_glBeginQuery = (PFNGLBEGINQUERYPROC)glad_glBeginQueryARB; + if (glad_glBeginQueryARB == NULL && glad_glBeginQuery != NULL) glad_glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glad_glBeginQuery; + if (glad_glBeginTransformFeedback == NULL && glad_glBeginTransformFeedbackEXT != NULL) glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glad_glBeginTransformFeedbackEXT; + if (glad_glBeginTransformFeedback == NULL && glad_glBeginTransformFeedbackNV != NULL) glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glad_glBeginTransformFeedbackNV; + if (glad_glBeginTransformFeedbackEXT == NULL && glad_glBeginTransformFeedback != NULL) glad_glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glad_glBeginTransformFeedback; + if (glad_glBeginTransformFeedbackEXT == NULL && glad_glBeginTransformFeedbackNV != NULL) glad_glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glad_glBeginTransformFeedbackNV; + if (glad_glBeginTransformFeedbackNV == NULL && glad_glBeginTransformFeedback != NULL) glad_glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glad_glBeginTransformFeedback; + if (glad_glBeginTransformFeedbackNV == NULL && glad_glBeginTransformFeedbackEXT != NULL) glad_glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glad_glBeginTransformFeedbackEXT; + if (glad_glBindAttribLocation == NULL && glad_glBindAttribLocationARB != NULL) glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glad_glBindAttribLocationARB; + if (glad_glBindAttribLocationARB == NULL && glad_glBindAttribLocation != NULL) glad_glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glad_glBindAttribLocation; + if (glad_glBindBuffer == NULL && glad_glBindBufferARB != NULL) glad_glBindBuffer = (PFNGLBINDBUFFERPROC)glad_glBindBufferARB; + if (glad_glBindBufferARB == NULL && glad_glBindBuffer != NULL) glad_glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glad_glBindBuffer; + if (glad_glBindBufferBase == NULL && glad_glBindBufferBaseEXT != NULL) glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glad_glBindBufferBaseEXT; + if (glad_glBindBufferBase == NULL && glad_glBindBufferBaseNV != NULL) glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glad_glBindBufferBaseNV; + if (glad_glBindBufferBaseEXT == NULL && glad_glBindBufferBase != NULL) glad_glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glad_glBindBufferBase; + if (glad_glBindBufferBaseEXT == NULL && glad_glBindBufferBaseNV != NULL) glad_glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glad_glBindBufferBaseNV; + if (glad_glBindBufferBaseNV == NULL && glad_glBindBufferBase != NULL) glad_glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glad_glBindBufferBase; + if (glad_glBindBufferBaseNV == NULL && glad_glBindBufferBaseEXT != NULL) glad_glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glad_glBindBufferBaseEXT; + if (glad_glBindBufferOffsetEXT == NULL && glad_glBindBufferOffsetNV != NULL) glad_glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glad_glBindBufferOffsetNV; + if (glad_glBindBufferOffsetNV == NULL && glad_glBindBufferOffsetEXT != NULL) glad_glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glad_glBindBufferOffsetEXT; + if (glad_glBindBufferRange == NULL && glad_glBindBufferRangeEXT != NULL) glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glad_glBindBufferRangeEXT; + if (glad_glBindBufferRange == NULL && glad_glBindBufferRangeNV != NULL) glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glad_glBindBufferRangeNV; + if (glad_glBindBufferRangeEXT == NULL && glad_glBindBufferRange != NULL) glad_glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glad_glBindBufferRange; + if (glad_glBindBufferRangeEXT == NULL && glad_glBindBufferRangeNV != NULL) glad_glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glad_glBindBufferRangeNV; + if (glad_glBindBufferRangeNV == NULL && glad_glBindBufferRange != NULL) glad_glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glad_glBindBufferRange; + if (glad_glBindBufferRangeNV == NULL && glad_glBindBufferRangeEXT != NULL) glad_glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glad_glBindBufferRangeEXT; + if (glad_glBindFragDataLocation == NULL && glad_glBindFragDataLocationEXT != NULL) glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glad_glBindFragDataLocationEXT; + if (glad_glBindFragDataLocationEXT == NULL && glad_glBindFragDataLocation != NULL) glad_glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glad_glBindFragDataLocation; + if (glad_glBindFragDataLocationIndexed == NULL && glad_glBindFragDataLocationIndexedEXT != NULL) glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)glad_glBindFragDataLocationIndexedEXT; + if (glad_glBindFragDataLocationIndexedEXT == NULL && glad_glBindFragDataLocationIndexed != NULL) glad_glBindFragDataLocationIndexedEXT = (PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC)glad_glBindFragDataLocationIndexed; + if (glad_glBindProgramARB == NULL && glad_glBindProgramNV != NULL) glad_glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glad_glBindProgramNV; + if (glad_glBindProgramNV == NULL && glad_glBindProgramARB != NULL) glad_glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glad_glBindProgramARB; + if (glad_glBindTexture == NULL && glad_glBindTextureEXT != NULL) glad_glBindTexture = (PFNGLBINDTEXTUREPROC)glad_glBindTextureEXT; + if (glad_glBindTextureEXT == NULL && glad_glBindTexture != NULL) glad_glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glad_glBindTexture; + if (glad_glBindVertexArray == NULL && glad_glBindVertexArrayOES != NULL) glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glad_glBindVertexArrayOES; + if (glad_glBindVertexArrayOES == NULL && glad_glBindVertexArray != NULL) glad_glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)glad_glBindVertexArray; + if (glad_glBlendBarrier == NULL && glad_glBlendBarrierKHR != NULL) glad_glBlendBarrier = (PFNGLBLENDBARRIERPROC)glad_glBlendBarrierKHR; + if (glad_glBlendBarrier == NULL && glad_glBlendBarrierNV != NULL) glad_glBlendBarrier = (PFNGLBLENDBARRIERPROC)glad_glBlendBarrierNV; + if (glad_glBlendBarrierKHR == NULL && glad_glBlendBarrier != NULL) glad_glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC)glad_glBlendBarrier; + if (glad_glBlendBarrierKHR == NULL && glad_glBlendBarrierNV != NULL) glad_glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC)glad_glBlendBarrierNV; + if (glad_glBlendBarrierNV == NULL && glad_glBlendBarrier != NULL) glad_glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glad_glBlendBarrier; + if (glad_glBlendBarrierNV == NULL && glad_glBlendBarrierKHR != NULL) glad_glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glad_glBlendBarrierKHR; + if (glad_glBlendColor == NULL && glad_glBlendColorEXT != NULL) glad_glBlendColor = (PFNGLBLENDCOLORPROC)glad_glBlendColorEXT; + if (glad_glBlendColorEXT == NULL && glad_glBlendColor != NULL) glad_glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glad_glBlendColor; + if (glad_glBlendEquation == NULL && glad_glBlendEquationEXT != NULL) glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)glad_glBlendEquationEXT; + if (glad_glBlendEquationEXT == NULL && glad_glBlendEquation != NULL) glad_glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glad_glBlendEquation; + if (glad_glBlendEquationi == NULL && glad_glBlendEquationIndexedAMD != NULL) glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glad_glBlendEquationIndexedAMD; + if (glad_glBlendEquationi == NULL && glad_glBlendEquationiARB != NULL) glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glad_glBlendEquationiARB; + if (glad_glBlendEquationi == NULL && glad_glBlendEquationiEXT != NULL) glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glad_glBlendEquationiEXT; + if (glad_glBlendEquationi == NULL && glad_glBlendEquationiOES != NULL) glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glad_glBlendEquationiOES; + if (glad_glBlendEquationiARB == NULL && glad_glBlendEquationIndexedAMD != NULL) glad_glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glad_glBlendEquationIndexedAMD; + if (glad_glBlendEquationiARB == NULL && glad_glBlendEquationi != NULL) glad_glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glad_glBlendEquationi; + if (glad_glBlendEquationiARB == NULL && glad_glBlendEquationiEXT != NULL) glad_glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glad_glBlendEquationiEXT; + if (glad_glBlendEquationiARB == NULL && glad_glBlendEquationiOES != NULL) glad_glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glad_glBlendEquationiOES; + if (glad_glBlendEquationiEXT == NULL && glad_glBlendEquationIndexedAMD != NULL) glad_glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glad_glBlendEquationIndexedAMD; + if (glad_glBlendEquationiEXT == NULL && glad_glBlendEquationi != NULL) glad_glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glad_glBlendEquationi; + if (glad_glBlendEquationiEXT == NULL && glad_glBlendEquationiARB != NULL) glad_glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glad_glBlendEquationiARB; + if (glad_glBlendEquationiEXT == NULL && glad_glBlendEquationiOES != NULL) glad_glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glad_glBlendEquationiOES; + if (glad_glBlendEquationIndexedAMD == NULL && glad_glBlendEquationi != NULL) glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glad_glBlendEquationi; + if (glad_glBlendEquationIndexedAMD == NULL && glad_glBlendEquationiARB != NULL) glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glad_glBlendEquationiARB; + if (glad_glBlendEquationIndexedAMD == NULL && glad_glBlendEquationiEXT != NULL) glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glad_glBlendEquationiEXT; + if (glad_glBlendEquationIndexedAMD == NULL && glad_glBlendEquationiOES != NULL) glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glad_glBlendEquationiOES; + if (glad_glBlendEquationiOES == NULL && glad_glBlendEquationIndexedAMD != NULL) glad_glBlendEquationiOES = (PFNGLBLENDEQUATIONIOESPROC)glad_glBlendEquationIndexedAMD; + if (glad_glBlendEquationiOES == NULL && glad_glBlendEquationi != NULL) glad_glBlendEquationiOES = (PFNGLBLENDEQUATIONIOESPROC)glad_glBlendEquationi; + if (glad_glBlendEquationiOES == NULL && glad_glBlendEquationiARB != NULL) glad_glBlendEquationiOES = (PFNGLBLENDEQUATIONIOESPROC)glad_glBlendEquationiARB; + if (glad_glBlendEquationiOES == NULL && glad_glBlendEquationiEXT != NULL) glad_glBlendEquationiOES = (PFNGLBLENDEQUATIONIOESPROC)glad_glBlendEquationiEXT; + if (glad_glBlendEquationSeparate == NULL && glad_glBlendEquationSeparateEXT != NULL) glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glad_glBlendEquationSeparateEXT; + if (glad_glBlendEquationSeparateEXT == NULL && glad_glBlendEquationSeparate != NULL) glad_glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glad_glBlendEquationSeparate; + if (glad_glBlendEquationSeparatei == NULL && glad_glBlendEquationSeparateIndexedAMD != NULL) glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glad_glBlendEquationSeparateIndexedAMD; + if (glad_glBlendEquationSeparatei == NULL && glad_glBlendEquationSeparateiARB != NULL) glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glad_glBlendEquationSeparateiARB; + if (glad_glBlendEquationSeparatei == NULL && glad_glBlendEquationSeparateiEXT != NULL) glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glad_glBlendEquationSeparateiEXT; + if (glad_glBlendEquationSeparatei == NULL && glad_glBlendEquationSeparateiOES != NULL) glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glad_glBlendEquationSeparateiOES; + if (glad_glBlendEquationSeparateiARB == NULL && glad_glBlendEquationSeparateIndexedAMD != NULL) glad_glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glad_glBlendEquationSeparateIndexedAMD; + if (glad_glBlendEquationSeparateiARB == NULL && glad_glBlendEquationSeparatei != NULL) glad_glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glad_glBlendEquationSeparatei; + if (glad_glBlendEquationSeparateiARB == NULL && glad_glBlendEquationSeparateiEXT != NULL) glad_glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glad_glBlendEquationSeparateiEXT; + if (glad_glBlendEquationSeparateiARB == NULL && glad_glBlendEquationSeparateiOES != NULL) glad_glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glad_glBlendEquationSeparateiOES; + if (glad_glBlendEquationSeparateiEXT == NULL && glad_glBlendEquationSeparateIndexedAMD != NULL) glad_glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glad_glBlendEquationSeparateIndexedAMD; + if (glad_glBlendEquationSeparateiEXT == NULL && glad_glBlendEquationSeparatei != NULL) glad_glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glad_glBlendEquationSeparatei; + if (glad_glBlendEquationSeparateiEXT == NULL && glad_glBlendEquationSeparateiARB != NULL) glad_glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glad_glBlendEquationSeparateiARB; + if (glad_glBlendEquationSeparateiEXT == NULL && glad_glBlendEquationSeparateiOES != NULL) glad_glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glad_glBlendEquationSeparateiOES; + if (glad_glBlendEquationSeparateIndexedAMD == NULL && glad_glBlendEquationSeparatei != NULL) glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glad_glBlendEquationSeparatei; + if (glad_glBlendEquationSeparateIndexedAMD == NULL && glad_glBlendEquationSeparateiARB != NULL) glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glad_glBlendEquationSeparateiARB; + if (glad_glBlendEquationSeparateIndexedAMD == NULL && glad_glBlendEquationSeparateiEXT != NULL) glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glad_glBlendEquationSeparateiEXT; + if (glad_glBlendEquationSeparateIndexedAMD == NULL && glad_glBlendEquationSeparateiOES != NULL) glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glad_glBlendEquationSeparateiOES; + if (glad_glBlendEquationSeparateiOES == NULL && glad_glBlendEquationSeparateIndexedAMD != NULL) glad_glBlendEquationSeparateiOES = (PFNGLBLENDEQUATIONSEPARATEIOESPROC)glad_glBlendEquationSeparateIndexedAMD; + if (glad_glBlendEquationSeparateiOES == NULL && glad_glBlendEquationSeparatei != NULL) glad_glBlendEquationSeparateiOES = (PFNGLBLENDEQUATIONSEPARATEIOESPROC)glad_glBlendEquationSeparatei; + if (glad_glBlendEquationSeparateiOES == NULL && glad_glBlendEquationSeparateiARB != NULL) glad_glBlendEquationSeparateiOES = (PFNGLBLENDEQUATIONSEPARATEIOESPROC)glad_glBlendEquationSeparateiARB; + if (glad_glBlendEquationSeparateiOES == NULL && glad_glBlendEquationSeparateiEXT != NULL) glad_glBlendEquationSeparateiOES = (PFNGLBLENDEQUATIONSEPARATEIOESPROC)glad_glBlendEquationSeparateiEXT; + if (glad_glBlendFunci == NULL && glad_glBlendFuncIndexedAMD != NULL) glad_glBlendFunci = (PFNGLBLENDFUNCIPROC)glad_glBlendFuncIndexedAMD; + if (glad_glBlendFunci == NULL && glad_glBlendFunciARB != NULL) glad_glBlendFunci = (PFNGLBLENDFUNCIPROC)glad_glBlendFunciARB; + if (glad_glBlendFunci == NULL && glad_glBlendFunciEXT != NULL) glad_glBlendFunci = (PFNGLBLENDFUNCIPROC)glad_glBlendFunciEXT; + if (glad_glBlendFunci == NULL && glad_glBlendFunciOES != NULL) glad_glBlendFunci = (PFNGLBLENDFUNCIPROC)glad_glBlendFunciOES; + if (glad_glBlendFunciARB == NULL && glad_glBlendFuncIndexedAMD != NULL) glad_glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glad_glBlendFuncIndexedAMD; + if (glad_glBlendFunciARB == NULL && glad_glBlendFunci != NULL) glad_glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glad_glBlendFunci; + if (glad_glBlendFunciARB == NULL && glad_glBlendFunciEXT != NULL) glad_glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glad_glBlendFunciEXT; + if (glad_glBlendFunciARB == NULL && glad_glBlendFunciOES != NULL) glad_glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glad_glBlendFunciOES; + if (glad_glBlendFunciEXT == NULL && glad_glBlendFuncIndexedAMD != NULL) glad_glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glad_glBlendFuncIndexedAMD; + if (glad_glBlendFunciEXT == NULL && glad_glBlendFunci != NULL) glad_glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glad_glBlendFunci; + if (glad_glBlendFunciEXT == NULL && glad_glBlendFunciARB != NULL) glad_glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glad_glBlendFunciARB; + if (glad_glBlendFunciEXT == NULL && glad_glBlendFunciOES != NULL) glad_glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glad_glBlendFunciOES; + if (glad_glBlendFuncIndexedAMD == NULL && glad_glBlendFunci != NULL) glad_glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glad_glBlendFunci; + if (glad_glBlendFuncIndexedAMD == NULL && glad_glBlendFunciARB != NULL) glad_glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glad_glBlendFunciARB; + if (glad_glBlendFuncIndexedAMD == NULL && glad_glBlendFunciEXT != NULL) glad_glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glad_glBlendFunciEXT; + if (glad_glBlendFuncIndexedAMD == NULL && glad_glBlendFunciOES != NULL) glad_glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glad_glBlendFunciOES; + if (glad_glBlendFunciOES == NULL && glad_glBlendFuncIndexedAMD != NULL) glad_glBlendFunciOES = (PFNGLBLENDFUNCIOESPROC)glad_glBlendFuncIndexedAMD; + if (glad_glBlendFunciOES == NULL && glad_glBlendFunci != NULL) glad_glBlendFunciOES = (PFNGLBLENDFUNCIOESPROC)glad_glBlendFunci; + if (glad_glBlendFunciOES == NULL && glad_glBlendFunciARB != NULL) glad_glBlendFunciOES = (PFNGLBLENDFUNCIOESPROC)glad_glBlendFunciARB; + if (glad_glBlendFunciOES == NULL && glad_glBlendFunciEXT != NULL) glad_glBlendFunciOES = (PFNGLBLENDFUNCIOESPROC)glad_glBlendFunciEXT; + if (glad_glBlendFuncSeparate == NULL && glad_glBlendFuncSeparateEXT != NULL) glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glad_glBlendFuncSeparateEXT; + if (glad_glBlendFuncSeparate == NULL && glad_glBlendFuncSeparateINGR != NULL) glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glad_glBlendFuncSeparateINGR; + if (glad_glBlendFuncSeparateEXT == NULL && glad_glBlendFuncSeparate != NULL) glad_glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glad_glBlendFuncSeparate; + if (glad_glBlendFuncSeparateEXT == NULL && glad_glBlendFuncSeparateINGR != NULL) glad_glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glad_glBlendFuncSeparateINGR; + if (glad_glBlendFuncSeparatei == NULL && glad_glBlendFuncSeparateIndexedAMD != NULL) glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glad_glBlendFuncSeparateIndexedAMD; + if (glad_glBlendFuncSeparatei == NULL && glad_glBlendFuncSeparateiARB != NULL) glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glad_glBlendFuncSeparateiARB; + if (glad_glBlendFuncSeparatei == NULL && glad_glBlendFuncSeparateiEXT != NULL) glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glad_glBlendFuncSeparateiEXT; + if (glad_glBlendFuncSeparatei == NULL && glad_glBlendFuncSeparateiOES != NULL) glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glad_glBlendFuncSeparateiOES; + if (glad_glBlendFuncSeparateiARB == NULL && glad_glBlendFuncSeparateIndexedAMD != NULL) glad_glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glad_glBlendFuncSeparateIndexedAMD; + if (glad_glBlendFuncSeparateiARB == NULL && glad_glBlendFuncSeparatei != NULL) glad_glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glad_glBlendFuncSeparatei; + if (glad_glBlendFuncSeparateiARB == NULL && glad_glBlendFuncSeparateiEXT != NULL) glad_glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glad_glBlendFuncSeparateiEXT; + if (glad_glBlendFuncSeparateiARB == NULL && glad_glBlendFuncSeparateiOES != NULL) glad_glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glad_glBlendFuncSeparateiOES; + if (glad_glBlendFuncSeparateiEXT == NULL && glad_glBlendFuncSeparateIndexedAMD != NULL) glad_glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glad_glBlendFuncSeparateIndexedAMD; + if (glad_glBlendFuncSeparateiEXT == NULL && glad_glBlendFuncSeparatei != NULL) glad_glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glad_glBlendFuncSeparatei; + if (glad_glBlendFuncSeparateiEXT == NULL && glad_glBlendFuncSeparateiARB != NULL) glad_glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glad_glBlendFuncSeparateiARB; + if (glad_glBlendFuncSeparateiEXT == NULL && glad_glBlendFuncSeparateiOES != NULL) glad_glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glad_glBlendFuncSeparateiOES; + if (glad_glBlendFuncSeparateIndexedAMD == NULL && glad_glBlendFuncSeparatei != NULL) glad_glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glad_glBlendFuncSeparatei; + if (glad_glBlendFuncSeparateIndexedAMD == NULL && glad_glBlendFuncSeparateiARB != NULL) glad_glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glad_glBlendFuncSeparateiARB; + if (glad_glBlendFuncSeparateIndexedAMD == NULL && glad_glBlendFuncSeparateiEXT != NULL) glad_glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glad_glBlendFuncSeparateiEXT; + if (glad_glBlendFuncSeparateIndexedAMD == NULL && glad_glBlendFuncSeparateiOES != NULL) glad_glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glad_glBlendFuncSeparateiOES; + if (glad_glBlendFuncSeparateINGR == NULL && glad_glBlendFuncSeparate != NULL) glad_glBlendFuncSeparateINGR = (PFNGLBLENDFUNCSEPARATEINGRPROC)glad_glBlendFuncSeparate; + if (glad_glBlendFuncSeparateINGR == NULL && glad_glBlendFuncSeparateEXT != NULL) glad_glBlendFuncSeparateINGR = (PFNGLBLENDFUNCSEPARATEINGRPROC)glad_glBlendFuncSeparateEXT; + if (glad_glBlendFuncSeparateiOES == NULL && glad_glBlendFuncSeparateIndexedAMD != NULL) glad_glBlendFuncSeparateiOES = (PFNGLBLENDFUNCSEPARATEIOESPROC)glad_glBlendFuncSeparateIndexedAMD; + if (glad_glBlendFuncSeparateiOES == NULL && glad_glBlendFuncSeparatei != NULL) glad_glBlendFuncSeparateiOES = (PFNGLBLENDFUNCSEPARATEIOESPROC)glad_glBlendFuncSeparatei; + if (glad_glBlendFuncSeparateiOES == NULL && glad_glBlendFuncSeparateiARB != NULL) glad_glBlendFuncSeparateiOES = (PFNGLBLENDFUNCSEPARATEIOESPROC)glad_glBlendFuncSeparateiARB; + if (glad_glBlendFuncSeparateiOES == NULL && glad_glBlendFuncSeparateiEXT != NULL) glad_glBlendFuncSeparateiOES = (PFNGLBLENDFUNCSEPARATEIOESPROC)glad_glBlendFuncSeparateiEXT; + if (glad_glBlitFramebuffer == NULL && glad_glBlitFramebufferEXT != NULL) glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glad_glBlitFramebufferEXT; + if (glad_glBlitFramebuffer == NULL && glad_glBlitFramebufferNV != NULL) glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glad_glBlitFramebufferNV; + if (glad_glBlitFramebufferEXT == NULL && glad_glBlitFramebuffer != NULL) glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glad_glBlitFramebuffer; + if (glad_glBlitFramebufferEXT == NULL && glad_glBlitFramebufferNV != NULL) glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glad_glBlitFramebufferNV; + if (glad_glBlitFramebufferNV == NULL && glad_glBlitFramebuffer != NULL) glad_glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)glad_glBlitFramebuffer; + if (glad_glBlitFramebufferNV == NULL && glad_glBlitFramebufferEXT != NULL) glad_glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)glad_glBlitFramebufferEXT; + if (glad_glBufferData == NULL && glad_glBufferDataARB != NULL) glad_glBufferData = (PFNGLBUFFERDATAPROC)glad_glBufferDataARB; + if (glad_glBufferDataARB == NULL && glad_glBufferData != NULL) glad_glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glad_glBufferData; + if (glad_glBufferStorage == NULL && glad_glBufferStorageEXT != NULL) glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC)glad_glBufferStorageEXT; + if (glad_glBufferStorageEXT == NULL && glad_glBufferStorage != NULL) glad_glBufferStorageEXT = (PFNGLBUFFERSTORAGEEXTPROC)glad_glBufferStorage; + if (glad_glBufferSubData == NULL && glad_glBufferSubDataARB != NULL) glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glad_glBufferSubDataARB; + if (glad_glBufferSubDataARB == NULL && glad_glBufferSubData != NULL) glad_glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glad_glBufferSubData; + if (glad_glCheckFramebufferStatus == NULL && glad_glCheckFramebufferStatusEXT != NULL) glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glad_glCheckFramebufferStatusEXT; + if (glad_glCheckFramebufferStatusEXT == NULL && glad_glCheckFramebufferStatus != NULL) glad_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glad_glCheckFramebufferStatus; + if (glad_glClampColor == NULL && glad_glClampColorARB != NULL) glad_glClampColor = (PFNGLCLAMPCOLORPROC)glad_glClampColorARB; + if (glad_glClampColorARB == NULL && glad_glClampColor != NULL) glad_glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glad_glClampColor; + if (glad_glClearDepthf == NULL && glad_glClearDepthfOES != NULL) glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC)glad_glClearDepthfOES; + if (glad_glClearDepthfOES == NULL && glad_glClearDepthf != NULL) glad_glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC)glad_glClearDepthf; + if (glad_glClearTexImage == NULL && glad_glClearTexImageEXT != NULL) glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)glad_glClearTexImageEXT; + if (glad_glClearTexImageEXT == NULL && glad_glClearTexImage != NULL) glad_glClearTexImageEXT = (PFNGLCLEARTEXIMAGEEXTPROC)glad_glClearTexImage; + if (glad_glClearTexSubImage == NULL && glad_glClearTexSubImageEXT != NULL) glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)glad_glClearTexSubImageEXT; + if (glad_glClearTexSubImageEXT == NULL && glad_glClearTexSubImage != NULL) glad_glClearTexSubImageEXT = (PFNGLCLEARTEXSUBIMAGEEXTPROC)glad_glClearTexSubImage; + if (glad_glClientActiveTexture == NULL && glad_glClientActiveTextureARB != NULL) glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glad_glClientActiveTextureARB; + if (glad_glClientActiveTextureARB == NULL && glad_glClientActiveTexture != NULL) glad_glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glad_glClientActiveTexture; + if (glad_glClientWaitSync == NULL && glad_glClientWaitSyncAPPLE != NULL) glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glad_glClientWaitSyncAPPLE; + if (glad_glClientWaitSyncAPPLE == NULL && glad_glClientWaitSync != NULL) glad_glClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC)glad_glClientWaitSync; + if (glad_glClipControl == NULL && glad_glClipControlEXT != NULL) glad_glClipControl = (PFNGLCLIPCONTROLPROC)glad_glClipControlEXT; + if (glad_glClipControlEXT == NULL && glad_glClipControl != NULL) glad_glClipControlEXT = (PFNGLCLIPCONTROLEXTPROC)glad_glClipControl; + if (glad_glColorMaski == NULL && glad_glColorMaskIndexedEXT != NULL) glad_glColorMaski = (PFNGLCOLORMASKIPROC)glad_glColorMaskIndexedEXT; + if (glad_glColorMaski == NULL && glad_glColorMaskiEXT != NULL) glad_glColorMaski = (PFNGLCOLORMASKIPROC)glad_glColorMaskiEXT; + if (glad_glColorMaski == NULL && glad_glColorMaskiOES != NULL) glad_glColorMaski = (PFNGLCOLORMASKIPROC)glad_glColorMaskiOES; + if (glad_glColorMaskiEXT == NULL && glad_glColorMaskIndexedEXT != NULL) glad_glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC)glad_glColorMaskIndexedEXT; + if (glad_glColorMaskiEXT == NULL && glad_glColorMaski != NULL) glad_glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC)glad_glColorMaski; + if (glad_glColorMaskiEXT == NULL && glad_glColorMaskiOES != NULL) glad_glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC)glad_glColorMaskiOES; + if (glad_glColorMaskIndexedEXT == NULL && glad_glColorMaski != NULL) glad_glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glad_glColorMaski; + if (glad_glColorMaskIndexedEXT == NULL && glad_glColorMaskiEXT != NULL) glad_glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glad_glColorMaskiEXT; + if (glad_glColorMaskIndexedEXT == NULL && glad_glColorMaskiOES != NULL) glad_glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glad_glColorMaskiOES; + if (glad_glColorMaskiOES == NULL && glad_glColorMaskIndexedEXT != NULL) glad_glColorMaskiOES = (PFNGLCOLORMASKIOESPROC)glad_glColorMaskIndexedEXT; + if (glad_glColorMaskiOES == NULL && glad_glColorMaski != NULL) glad_glColorMaskiOES = (PFNGLCOLORMASKIOESPROC)glad_glColorMaski; + if (glad_glColorMaskiOES == NULL && glad_glColorMaskiEXT != NULL) glad_glColorMaskiOES = (PFNGLCOLORMASKIOESPROC)glad_glColorMaskiEXT; + if (glad_glColorSubTable == NULL && glad_glColorSubTableEXT != NULL) glad_glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glad_glColorSubTableEXT; + if (glad_glColorSubTableEXT == NULL && glad_glColorSubTable != NULL) glad_glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glad_glColorSubTable; + if (glad_glColorTable == NULL && glad_glColorTableEXT != NULL) glad_glColorTable = (PFNGLCOLORTABLEPROC)glad_glColorTableEXT; + if (glad_glColorTable == NULL && glad_glColorTableSGI != NULL) glad_glColorTable = (PFNGLCOLORTABLEPROC)glad_glColorTableSGI; + if (glad_glColorTableEXT == NULL && glad_glColorTable != NULL) glad_glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glad_glColorTable; + if (glad_glColorTableEXT == NULL && glad_glColorTableSGI != NULL) glad_glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glad_glColorTableSGI; + if (glad_glColorTableParameterfv == NULL && glad_glColorTableParameterfvSGI != NULL) glad_glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glad_glColorTableParameterfvSGI; + if (glad_glColorTableParameterfvSGI == NULL && glad_glColorTableParameterfv != NULL) glad_glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glad_glColorTableParameterfv; + if (glad_glColorTableParameteriv == NULL && glad_glColorTableParameterivSGI != NULL) glad_glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glad_glColorTableParameterivSGI; + if (glad_glColorTableParameterivSGI == NULL && glad_glColorTableParameteriv != NULL) glad_glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glad_glColorTableParameteriv; + if (glad_glColorTableSGI == NULL && glad_glColorTable != NULL) glad_glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glad_glColorTable; + if (glad_glColorTableSGI == NULL && glad_glColorTableEXT != NULL) glad_glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glad_glColorTableEXT; + if (glad_glCompileShader == NULL && glad_glCompileShaderARB != NULL) glad_glCompileShader = (PFNGLCOMPILESHADERPROC)glad_glCompileShaderARB; + if (glad_glCompileShaderARB == NULL && glad_glCompileShader != NULL) glad_glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glad_glCompileShader; + if (glad_glCompressedTexImage1D == NULL && glad_glCompressedTexImage1DARB != NULL) glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glad_glCompressedTexImage1DARB; + if (glad_glCompressedTexImage1DARB == NULL && glad_glCompressedTexImage1D != NULL) glad_glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glad_glCompressedTexImage1D; + if (glad_glCompressedTexImage2D == NULL && glad_glCompressedTexImage2DARB != NULL) glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glad_glCompressedTexImage2DARB; + if (glad_glCompressedTexImage2DARB == NULL && glad_glCompressedTexImage2D != NULL) glad_glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glad_glCompressedTexImage2D; + if (glad_glCompressedTexImage3D == NULL && glad_glCompressedTexImage3DARB != NULL) glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glad_glCompressedTexImage3DARB; + if (glad_glCompressedTexImage3DARB == NULL && glad_glCompressedTexImage3D != NULL) glad_glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glad_glCompressedTexImage3D; + if (glad_glCompressedTexSubImage1D == NULL && glad_glCompressedTexSubImage1DARB != NULL) glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glad_glCompressedTexSubImage1DARB; + if (glad_glCompressedTexSubImage1DARB == NULL && glad_glCompressedTexSubImage1D != NULL) glad_glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glad_glCompressedTexSubImage1D; + if (glad_glCompressedTexSubImage2D == NULL && glad_glCompressedTexSubImage2DARB != NULL) glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glad_glCompressedTexSubImage2DARB; + if (glad_glCompressedTexSubImage2DARB == NULL && glad_glCompressedTexSubImage2D != NULL) glad_glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glad_glCompressedTexSubImage2D; + if (glad_glCompressedTexSubImage3D == NULL && glad_glCompressedTexSubImage3DARB != NULL) glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glad_glCompressedTexSubImage3DARB; + if (glad_glCompressedTexSubImage3DARB == NULL && glad_glCompressedTexSubImage3D != NULL) glad_glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glad_glCompressedTexSubImage3D; + if (glad_glConvolutionFilter1D == NULL && glad_glConvolutionFilter1DEXT != NULL) glad_glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glad_glConvolutionFilter1DEXT; + if (glad_glConvolutionFilter1DEXT == NULL && glad_glConvolutionFilter1D != NULL) glad_glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glad_glConvolutionFilter1D; + if (glad_glConvolutionFilter2D == NULL && glad_glConvolutionFilter2DEXT != NULL) glad_glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glad_glConvolutionFilter2DEXT; + if (glad_glConvolutionFilter2DEXT == NULL && glad_glConvolutionFilter2D != NULL) glad_glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glad_glConvolutionFilter2D; + if (glad_glConvolutionParameterf == NULL && glad_glConvolutionParameterfEXT != NULL) glad_glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glad_glConvolutionParameterfEXT; + if (glad_glConvolutionParameterfEXT == NULL && glad_glConvolutionParameterf != NULL) glad_glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glad_glConvolutionParameterf; + if (glad_glConvolutionParameterfv == NULL && glad_glConvolutionParameterfvEXT != NULL) glad_glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glad_glConvolutionParameterfvEXT; + if (glad_glConvolutionParameterfvEXT == NULL && glad_glConvolutionParameterfv != NULL) glad_glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glad_glConvolutionParameterfv; + if (glad_glConvolutionParameteri == NULL && glad_glConvolutionParameteriEXT != NULL) glad_glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glad_glConvolutionParameteriEXT; + if (glad_glConvolutionParameteriEXT == NULL && glad_glConvolutionParameteri != NULL) glad_glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glad_glConvolutionParameteri; + if (glad_glConvolutionParameteriv == NULL && glad_glConvolutionParameterivEXT != NULL) glad_glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glad_glConvolutionParameterivEXT; + if (glad_glConvolutionParameterivEXT == NULL && glad_glConvolutionParameteriv != NULL) glad_glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glad_glConvolutionParameteriv; + if (glad_glCopyBufferSubData == NULL && glad_glCopyBufferSubDataNV != NULL) glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glad_glCopyBufferSubDataNV; + if (glad_glCopyBufferSubDataNV == NULL && glad_glCopyBufferSubData != NULL) glad_glCopyBufferSubDataNV = (PFNGLCOPYBUFFERSUBDATANVPROC)glad_glCopyBufferSubData; + if (glad_glCopyColorSubTable == NULL && glad_glCopyColorSubTableEXT != NULL) glad_glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glad_glCopyColorSubTableEXT; + if (glad_glCopyColorSubTableEXT == NULL && glad_glCopyColorSubTable != NULL) glad_glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glad_glCopyColorSubTable; + if (glad_glCopyColorTable == NULL && glad_glCopyColorTableSGI != NULL) glad_glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glad_glCopyColorTableSGI; + if (glad_glCopyColorTableSGI == NULL && glad_glCopyColorTable != NULL) glad_glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glad_glCopyColorTable; + if (glad_glCopyConvolutionFilter1D == NULL && glad_glCopyConvolutionFilter1DEXT != NULL) glad_glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glad_glCopyConvolutionFilter1DEXT; + if (glad_glCopyConvolutionFilter1DEXT == NULL && glad_glCopyConvolutionFilter1D != NULL) glad_glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glad_glCopyConvolutionFilter1D; + if (glad_glCopyConvolutionFilter2D == NULL && glad_glCopyConvolutionFilter2DEXT != NULL) glad_glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glad_glCopyConvolutionFilter2DEXT; + if (glad_glCopyConvolutionFilter2DEXT == NULL && glad_glCopyConvolutionFilter2D != NULL) glad_glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glad_glCopyConvolutionFilter2D; + if (glad_glCopyImageSubData == NULL && glad_glCopyImageSubDataEXT != NULL) glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glad_glCopyImageSubDataEXT; + if (glad_glCopyImageSubData == NULL && glad_glCopyImageSubDataOES != NULL) glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glad_glCopyImageSubDataOES; + if (glad_glCopyImageSubDataEXT == NULL && glad_glCopyImageSubData != NULL) glad_glCopyImageSubDataEXT = (PFNGLCOPYIMAGESUBDATAEXTPROC)glad_glCopyImageSubData; + if (glad_glCopyImageSubDataEXT == NULL && glad_glCopyImageSubDataOES != NULL) glad_glCopyImageSubDataEXT = (PFNGLCOPYIMAGESUBDATAEXTPROC)glad_glCopyImageSubDataOES; + if (glad_glCopyImageSubDataOES == NULL && glad_glCopyImageSubData != NULL) glad_glCopyImageSubDataOES = (PFNGLCOPYIMAGESUBDATAOESPROC)glad_glCopyImageSubData; + if (glad_glCopyImageSubDataOES == NULL && glad_glCopyImageSubDataEXT != NULL) glad_glCopyImageSubDataOES = (PFNGLCOPYIMAGESUBDATAOESPROC)glad_glCopyImageSubDataEXT; + if (glad_glCopyTexImage1D == NULL && glad_glCopyTexImage1DEXT != NULL) glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)glad_glCopyTexImage1DEXT; + if (glad_glCopyTexImage1DEXT == NULL && glad_glCopyTexImage1D != NULL) glad_glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glad_glCopyTexImage1D; + if (glad_glCopyTexImage2D == NULL && glad_glCopyTexImage2DEXT != NULL) glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)glad_glCopyTexImage2DEXT; + if (glad_glCopyTexImage2DEXT == NULL && glad_glCopyTexImage2D != NULL) glad_glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glad_glCopyTexImage2D; + if (glad_glCopyTexSubImage1D == NULL && glad_glCopyTexSubImage1DEXT != NULL) glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)glad_glCopyTexSubImage1DEXT; + if (glad_glCopyTexSubImage1DEXT == NULL && glad_glCopyTexSubImage1D != NULL) glad_glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glad_glCopyTexSubImage1D; + if (glad_glCopyTexSubImage2D == NULL && glad_glCopyTexSubImage2DEXT != NULL) glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)glad_glCopyTexSubImage2DEXT; + if (glad_glCopyTexSubImage2DEXT == NULL && glad_glCopyTexSubImage2D != NULL) glad_glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glad_glCopyTexSubImage2D; + if (glad_glCopyTexSubImage3D == NULL && glad_glCopyTexSubImage3DEXT != NULL) glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glad_glCopyTexSubImage3DEXT; + if (glad_glCopyTexSubImage3DEXT == NULL && glad_glCopyTexSubImage3D != NULL) glad_glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glad_glCopyTexSubImage3D; + if (glad_glCreateProgram == NULL && glad_glCreateProgramObjectARB != NULL) glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)glad_glCreateProgramObjectARB; + if (glad_glCreateProgramObjectARB == NULL && glad_glCreateProgram != NULL) glad_glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glad_glCreateProgram; + if (glad_glCreateShader == NULL && glad_glCreateShaderObjectARB != NULL) glad_glCreateShader = (PFNGLCREATESHADERPROC)glad_glCreateShaderObjectARB; + if (glad_glCreateShaderObjectARB == NULL && glad_glCreateShader != NULL) glad_glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glad_glCreateShader; + if (glad_glDebugMessageCallback == NULL && glad_glDebugMessageCallbackARB != NULL) glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glad_glDebugMessageCallbackARB; + if (glad_glDebugMessageCallback == NULL && glad_glDebugMessageCallbackKHR != NULL) glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glad_glDebugMessageCallbackKHR; + if (glad_glDebugMessageCallbackARB == NULL && glad_glDebugMessageCallback != NULL) glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glad_glDebugMessageCallback; + if (glad_glDebugMessageCallbackARB == NULL && glad_glDebugMessageCallbackKHR != NULL) glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glad_glDebugMessageCallbackKHR; + if (glad_glDebugMessageCallbackKHR == NULL && glad_glDebugMessageCallback != NULL) glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC)glad_glDebugMessageCallback; + if (glad_glDebugMessageCallbackKHR == NULL && glad_glDebugMessageCallbackARB != NULL) glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC)glad_glDebugMessageCallbackARB; + if (glad_glDebugMessageControl == NULL && glad_glDebugMessageControlARB != NULL) glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glad_glDebugMessageControlARB; + if (glad_glDebugMessageControl == NULL && glad_glDebugMessageControlKHR != NULL) glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glad_glDebugMessageControlKHR; + if (glad_glDebugMessageControlARB == NULL && glad_glDebugMessageControl != NULL) glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glad_glDebugMessageControl; + if (glad_glDebugMessageControlARB == NULL && glad_glDebugMessageControlKHR != NULL) glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glad_glDebugMessageControlKHR; + if (glad_glDebugMessageControlKHR == NULL && glad_glDebugMessageControl != NULL) glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC)glad_glDebugMessageControl; + if (glad_glDebugMessageControlKHR == NULL && glad_glDebugMessageControlARB != NULL) glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC)glad_glDebugMessageControlARB; + if (glad_glDebugMessageInsert == NULL && glad_glDebugMessageInsertARB != NULL) glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glad_glDebugMessageInsertARB; + if (glad_glDebugMessageInsert == NULL && glad_glDebugMessageInsertKHR != NULL) glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glad_glDebugMessageInsertKHR; + if (glad_glDebugMessageInsertARB == NULL && glad_glDebugMessageInsert != NULL) glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glad_glDebugMessageInsert; + if (glad_glDebugMessageInsertARB == NULL && glad_glDebugMessageInsertKHR != NULL) glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glad_glDebugMessageInsertKHR; + if (glad_glDebugMessageInsertKHR == NULL && glad_glDebugMessageInsert != NULL) glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC)glad_glDebugMessageInsert; + if (glad_glDebugMessageInsertKHR == NULL && glad_glDebugMessageInsertARB != NULL) glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC)glad_glDebugMessageInsertARB; + if (glad_glDeleteBuffers == NULL && glad_glDeleteBuffersARB != NULL) glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glad_glDeleteBuffersARB; + if (glad_glDeleteBuffersARB == NULL && glad_glDeleteBuffers != NULL) glad_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glad_glDeleteBuffers; + if (glad_glDeleteFramebuffers == NULL && glad_glDeleteFramebuffersEXT != NULL) glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glad_glDeleteFramebuffersEXT; + if (glad_glDeleteFramebuffersEXT == NULL && glad_glDeleteFramebuffers != NULL) glad_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glad_glDeleteFramebuffers; + if (glad_glDeleteProgramsARB == NULL && glad_glDeleteProgramsNV != NULL) glad_glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glad_glDeleteProgramsNV; + if (glad_glDeleteProgramsNV == NULL && glad_glDeleteProgramsARB != NULL) glad_glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glad_glDeleteProgramsARB; + if (glad_glDeleteQueries == NULL && glad_glDeleteQueriesARB != NULL) glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)glad_glDeleteQueriesARB; + if (glad_glDeleteQueriesARB == NULL && glad_glDeleteQueries != NULL) glad_glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glad_glDeleteQueries; + if (glad_glDeleteRenderbuffers == NULL && glad_glDeleteRenderbuffersEXT != NULL) glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glad_glDeleteRenderbuffersEXT; + if (glad_glDeleteRenderbuffersEXT == NULL && glad_glDeleteRenderbuffers != NULL) glad_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glad_glDeleteRenderbuffers; + if (glad_glDeleteSync == NULL && glad_glDeleteSyncAPPLE != NULL) glad_glDeleteSync = (PFNGLDELETESYNCPROC)glad_glDeleteSyncAPPLE; + if (glad_glDeleteSyncAPPLE == NULL && glad_glDeleteSync != NULL) glad_glDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC)glad_glDeleteSync; + if (glad_glDeleteTransformFeedbacks == NULL && glad_glDeleteTransformFeedbacksNV != NULL) glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)glad_glDeleteTransformFeedbacksNV; + if (glad_glDeleteTransformFeedbacksNV == NULL && glad_glDeleteTransformFeedbacks != NULL) glad_glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glad_glDeleteTransformFeedbacks; + if (glad_glDeleteVertexArrays == NULL && glad_glDeleteVertexArraysAPPLE != NULL) glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glad_glDeleteVertexArraysAPPLE; + if (glad_glDeleteVertexArrays == NULL && glad_glDeleteVertexArraysOES != NULL) glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glad_glDeleteVertexArraysOES; + if (glad_glDeleteVertexArraysAPPLE == NULL && glad_glDeleteVertexArrays != NULL) glad_glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glad_glDeleteVertexArrays; + if (glad_glDeleteVertexArraysAPPLE == NULL && glad_glDeleteVertexArraysOES != NULL) glad_glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glad_glDeleteVertexArraysOES; + if (glad_glDeleteVertexArraysOES == NULL && glad_glDeleteVertexArrays != NULL) glad_glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)glad_glDeleteVertexArrays; + if (glad_glDeleteVertexArraysOES == NULL && glad_glDeleteVertexArraysAPPLE != NULL) glad_glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)glad_glDeleteVertexArraysAPPLE; + if (glad_glDepthRangef == NULL && glad_glDepthRangefOES != NULL) glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC)glad_glDepthRangefOES; + if (glad_glDepthRangefOES == NULL && glad_glDepthRangef != NULL) glad_glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC)glad_glDepthRangef; + if (glad_glDetachObjectARB == NULL && glad_glDetachShader != NULL) glad_glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glad_glDetachShader; + if (glad_glDetachShader == NULL && glad_glDetachObjectARB != NULL) glad_glDetachShader = (PFNGLDETACHSHADERPROC)glad_glDetachObjectARB; + if (glad_glDisablei == NULL && glad_glDisableIndexedEXT != NULL) glad_glDisablei = (PFNGLDISABLEIPROC)glad_glDisableIndexedEXT; + if (glad_glDisablei == NULL && glad_glDisableiEXT != NULL) glad_glDisablei = (PFNGLDISABLEIPROC)glad_glDisableiEXT; + if (glad_glDisablei == NULL && glad_glDisableiNV != NULL) glad_glDisablei = (PFNGLDISABLEIPROC)glad_glDisableiNV; + if (glad_glDisablei == NULL && glad_glDisableiOES != NULL) glad_glDisablei = (PFNGLDISABLEIPROC)glad_glDisableiOES; + if (glad_glDisableiEXT == NULL && glad_glDisableIndexedEXT != NULL) glad_glDisableiEXT = (PFNGLDISABLEIEXTPROC)glad_glDisableIndexedEXT; + if (glad_glDisableiEXT == NULL && glad_glDisablei != NULL) glad_glDisableiEXT = (PFNGLDISABLEIEXTPROC)glad_glDisablei; + if (glad_glDisableiEXT == NULL && glad_glDisableiNV != NULL) glad_glDisableiEXT = (PFNGLDISABLEIEXTPROC)glad_glDisableiNV; + if (glad_glDisableiEXT == NULL && glad_glDisableiOES != NULL) glad_glDisableiEXT = (PFNGLDISABLEIEXTPROC)glad_glDisableiOES; + if (glad_glDisableIndexedEXT == NULL && glad_glDisablei != NULL) glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glad_glDisablei; + if (glad_glDisableIndexedEXT == NULL && glad_glDisableiEXT != NULL) glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glad_glDisableiEXT; + if (glad_glDisableIndexedEXT == NULL && glad_glDisableiNV != NULL) glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glad_glDisableiNV; + if (glad_glDisableIndexedEXT == NULL && glad_glDisableiOES != NULL) glad_glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glad_glDisableiOES; + if (glad_glDisableiNV == NULL && glad_glDisableIndexedEXT != NULL) glad_glDisableiNV = (PFNGLDISABLEINVPROC)glad_glDisableIndexedEXT; + if (glad_glDisableiNV == NULL && glad_glDisablei != NULL) glad_glDisableiNV = (PFNGLDISABLEINVPROC)glad_glDisablei; + if (glad_glDisableiNV == NULL && glad_glDisableiEXT != NULL) glad_glDisableiNV = (PFNGLDISABLEINVPROC)glad_glDisableiEXT; + if (glad_glDisableiNV == NULL && glad_glDisableiOES != NULL) glad_glDisableiNV = (PFNGLDISABLEINVPROC)glad_glDisableiOES; + if (glad_glDisableiOES == NULL && glad_glDisableIndexedEXT != NULL) glad_glDisableiOES = (PFNGLDISABLEIOESPROC)glad_glDisableIndexedEXT; + if (glad_glDisableiOES == NULL && glad_glDisablei != NULL) glad_glDisableiOES = (PFNGLDISABLEIOESPROC)glad_glDisablei; + if (glad_glDisableiOES == NULL && glad_glDisableiEXT != NULL) glad_glDisableiOES = (PFNGLDISABLEIOESPROC)glad_glDisableiEXT; + if (glad_glDisableiOES == NULL && glad_glDisableiNV != NULL) glad_glDisableiOES = (PFNGLDISABLEIOESPROC)glad_glDisableiNV; + if (glad_glDisableVertexAttribArray == NULL && glad_glDisableVertexAttribArrayARB != NULL) glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glad_glDisableVertexAttribArrayARB; + if (glad_glDisableVertexAttribArrayARB == NULL && glad_glDisableVertexAttribArray != NULL) glad_glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glad_glDisableVertexAttribArray; + if (glad_glDrawArrays == NULL && glad_glDrawArraysEXT != NULL) glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)glad_glDrawArraysEXT; + if (glad_glDrawArraysEXT == NULL && glad_glDrawArrays != NULL) glad_glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glad_glDrawArrays; + if (glad_glDrawArraysInstanced == NULL && glad_glDrawArraysInstancedANGLE != NULL) glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glad_glDrawArraysInstancedANGLE; + if (glad_glDrawArraysInstanced == NULL && glad_glDrawArraysInstancedARB != NULL) glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glad_glDrawArraysInstancedARB; + if (glad_glDrawArraysInstanced == NULL && glad_glDrawArraysInstancedEXT != NULL) glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glad_glDrawArraysInstancedEXT; + if (glad_glDrawArraysInstanced == NULL && glad_glDrawArraysInstancedNV != NULL) glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glad_glDrawArraysInstancedNV; + if (glad_glDrawArraysInstancedANGLE == NULL && glad_glDrawArraysInstanced != NULL) glad_glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glad_glDrawArraysInstanced; + if (glad_glDrawArraysInstancedANGLE == NULL && glad_glDrawArraysInstancedARB != NULL) glad_glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glad_glDrawArraysInstancedARB; + if (glad_glDrawArraysInstancedANGLE == NULL && glad_glDrawArraysInstancedEXT != NULL) glad_glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glad_glDrawArraysInstancedEXT; + if (glad_glDrawArraysInstancedANGLE == NULL && glad_glDrawArraysInstancedNV != NULL) glad_glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glad_glDrawArraysInstancedNV; + if (glad_glDrawArraysInstancedARB == NULL && glad_glDrawArraysInstanced != NULL) glad_glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glad_glDrawArraysInstanced; + if (glad_glDrawArraysInstancedARB == NULL && glad_glDrawArraysInstancedANGLE != NULL) glad_glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glad_glDrawArraysInstancedANGLE; + if (glad_glDrawArraysInstancedARB == NULL && glad_glDrawArraysInstancedEXT != NULL) glad_glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glad_glDrawArraysInstancedEXT; + if (glad_glDrawArraysInstancedARB == NULL && glad_glDrawArraysInstancedNV != NULL) glad_glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glad_glDrawArraysInstancedNV; + if (glad_glDrawArraysInstancedBaseInstance == NULL && glad_glDrawArraysInstancedBaseInstanceEXT != NULL) glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)glad_glDrawArraysInstancedBaseInstanceEXT; + if (glad_glDrawArraysInstancedBaseInstanceEXT == NULL && glad_glDrawArraysInstancedBaseInstance != NULL) glad_glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)glad_glDrawArraysInstancedBaseInstance; + if (glad_glDrawArraysInstancedEXT == NULL && glad_glDrawArraysInstanced != NULL) glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glad_glDrawArraysInstanced; + if (glad_glDrawArraysInstancedEXT == NULL && glad_glDrawArraysInstancedANGLE != NULL) glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glad_glDrawArraysInstancedANGLE; + if (glad_glDrawArraysInstancedEXT == NULL && glad_glDrawArraysInstancedARB != NULL) glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glad_glDrawArraysInstancedARB; + if (glad_glDrawArraysInstancedEXT == NULL && glad_glDrawArraysInstancedNV != NULL) glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glad_glDrawArraysInstancedNV; + if (glad_glDrawArraysInstancedNV == NULL && glad_glDrawArraysInstanced != NULL) glad_glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glad_glDrawArraysInstanced; + if (glad_glDrawArraysInstancedNV == NULL && glad_glDrawArraysInstancedANGLE != NULL) glad_glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glad_glDrawArraysInstancedANGLE; + if (glad_glDrawArraysInstancedNV == NULL && glad_glDrawArraysInstancedARB != NULL) glad_glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glad_glDrawArraysInstancedARB; + if (glad_glDrawArraysInstancedNV == NULL && glad_glDrawArraysInstancedEXT != NULL) glad_glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glad_glDrawArraysInstancedEXT; + if (glad_glDrawBuffers == NULL && glad_glDrawBuffersARB != NULL) glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glad_glDrawBuffersARB; + if (glad_glDrawBuffers == NULL && glad_glDrawBuffersATI != NULL) glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glad_glDrawBuffersATI; + if (glad_glDrawBuffers == NULL && glad_glDrawBuffersEXT != NULL) glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glad_glDrawBuffersEXT; + if (glad_glDrawBuffersARB == NULL && glad_glDrawBuffers != NULL) glad_glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glad_glDrawBuffers; + if (glad_glDrawBuffersARB == NULL && glad_glDrawBuffersATI != NULL) glad_glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glad_glDrawBuffersATI; + if (glad_glDrawBuffersARB == NULL && glad_glDrawBuffersEXT != NULL) glad_glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glad_glDrawBuffersEXT; + if (glad_glDrawBuffersATI == NULL && glad_glDrawBuffers != NULL) glad_glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glad_glDrawBuffers; + if (glad_glDrawBuffersATI == NULL && glad_glDrawBuffersARB != NULL) glad_glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glad_glDrawBuffersARB; + if (glad_glDrawBuffersATI == NULL && glad_glDrawBuffersEXT != NULL) glad_glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glad_glDrawBuffersEXT; + if (glad_glDrawBuffersEXT == NULL && glad_glDrawBuffers != NULL) glad_glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)glad_glDrawBuffers; + if (glad_glDrawBuffersEXT == NULL && glad_glDrawBuffersARB != NULL) glad_glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)glad_glDrawBuffersARB; + if (glad_glDrawBuffersEXT == NULL && glad_glDrawBuffersATI != NULL) glad_glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)glad_glDrawBuffersATI; + if (glad_glDrawElementsBaseVertex == NULL && glad_glDrawElementsBaseVertexEXT != NULL) glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glad_glDrawElementsBaseVertexEXT; + if (glad_glDrawElementsBaseVertex == NULL && glad_glDrawElementsBaseVertexOES != NULL) glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glad_glDrawElementsBaseVertexOES; + if (glad_glDrawElementsBaseVertexEXT == NULL && glad_glDrawElementsBaseVertex != NULL) glad_glDrawElementsBaseVertexEXT = (PFNGLDRAWELEMENTSBASEVERTEXEXTPROC)glad_glDrawElementsBaseVertex; + if (glad_glDrawElementsBaseVertexEXT == NULL && glad_glDrawElementsBaseVertexOES != NULL) glad_glDrawElementsBaseVertexEXT = (PFNGLDRAWELEMENTSBASEVERTEXEXTPROC)glad_glDrawElementsBaseVertexOES; + if (glad_glDrawElementsBaseVertexOES == NULL && glad_glDrawElementsBaseVertex != NULL) glad_glDrawElementsBaseVertexOES = (PFNGLDRAWELEMENTSBASEVERTEXOESPROC)glad_glDrawElementsBaseVertex; + if (glad_glDrawElementsBaseVertexOES == NULL && glad_glDrawElementsBaseVertexEXT != NULL) glad_glDrawElementsBaseVertexOES = (PFNGLDRAWELEMENTSBASEVERTEXOESPROC)glad_glDrawElementsBaseVertexEXT; + if (glad_glDrawElementsInstanced == NULL && glad_glDrawElementsInstancedANGLE != NULL) glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glad_glDrawElementsInstancedANGLE; + if (glad_glDrawElementsInstanced == NULL && glad_glDrawElementsInstancedARB != NULL) glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glad_glDrawElementsInstancedARB; + if (glad_glDrawElementsInstanced == NULL && glad_glDrawElementsInstancedEXT != NULL) glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glad_glDrawElementsInstancedEXT; + if (glad_glDrawElementsInstanced == NULL && glad_glDrawElementsInstancedNV != NULL) glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glad_glDrawElementsInstancedNV; + if (glad_glDrawElementsInstancedANGLE == NULL && glad_glDrawElementsInstanced != NULL) glad_glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glad_glDrawElementsInstanced; + if (glad_glDrawElementsInstancedANGLE == NULL && glad_glDrawElementsInstancedARB != NULL) glad_glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glad_glDrawElementsInstancedARB; + if (glad_glDrawElementsInstancedANGLE == NULL && glad_glDrawElementsInstancedEXT != NULL) glad_glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glad_glDrawElementsInstancedEXT; + if (glad_glDrawElementsInstancedANGLE == NULL && glad_glDrawElementsInstancedNV != NULL) glad_glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glad_glDrawElementsInstancedNV; + if (glad_glDrawElementsInstancedARB == NULL && glad_glDrawElementsInstanced != NULL) glad_glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glad_glDrawElementsInstanced; + if (glad_glDrawElementsInstancedARB == NULL && glad_glDrawElementsInstancedANGLE != NULL) glad_glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glad_glDrawElementsInstancedANGLE; + if (glad_glDrawElementsInstancedARB == NULL && glad_glDrawElementsInstancedEXT != NULL) glad_glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glad_glDrawElementsInstancedEXT; + if (glad_glDrawElementsInstancedARB == NULL && glad_glDrawElementsInstancedNV != NULL) glad_glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glad_glDrawElementsInstancedNV; + if (glad_glDrawElementsInstancedBaseInstance == NULL && glad_glDrawElementsInstancedBaseInstanceEXT != NULL) glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)glad_glDrawElementsInstancedBaseInstanceEXT; + if (glad_glDrawElementsInstancedBaseInstanceEXT == NULL && glad_glDrawElementsInstancedBaseInstance != NULL) glad_glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)glad_glDrawElementsInstancedBaseInstance; + if (glad_glDrawElementsInstancedBaseVertex == NULL && glad_glDrawElementsInstancedBaseVertexEXT != NULL) glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glad_glDrawElementsInstancedBaseVertexEXT; + if (glad_glDrawElementsInstancedBaseVertex == NULL && glad_glDrawElementsInstancedBaseVertexOES != NULL) glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glad_glDrawElementsInstancedBaseVertexOES; + if (glad_glDrawElementsInstancedBaseVertexBaseInstance == NULL && glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT != NULL) glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT; + if (glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT == NULL && glad_glDrawElementsInstancedBaseVertexBaseInstance != NULL) glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)glad_glDrawElementsInstancedBaseVertexBaseInstance; + if (glad_glDrawElementsInstancedBaseVertexEXT == NULL && glad_glDrawElementsInstancedBaseVertex != NULL) glad_glDrawElementsInstancedBaseVertexEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC)glad_glDrawElementsInstancedBaseVertex; + if (glad_glDrawElementsInstancedBaseVertexEXT == NULL && glad_glDrawElementsInstancedBaseVertexOES != NULL) glad_glDrawElementsInstancedBaseVertexEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC)glad_glDrawElementsInstancedBaseVertexOES; + if (glad_glDrawElementsInstancedBaseVertexOES == NULL && glad_glDrawElementsInstancedBaseVertex != NULL) glad_glDrawElementsInstancedBaseVertexOES = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC)glad_glDrawElementsInstancedBaseVertex; + if (glad_glDrawElementsInstancedBaseVertexOES == NULL && glad_glDrawElementsInstancedBaseVertexEXT != NULL) glad_glDrawElementsInstancedBaseVertexOES = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC)glad_glDrawElementsInstancedBaseVertexEXT; + if (glad_glDrawElementsInstancedEXT == NULL && glad_glDrawElementsInstanced != NULL) glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glad_glDrawElementsInstanced; + if (glad_glDrawElementsInstancedEXT == NULL && glad_glDrawElementsInstancedANGLE != NULL) glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glad_glDrawElementsInstancedANGLE; + if (glad_glDrawElementsInstancedEXT == NULL && glad_glDrawElementsInstancedARB != NULL) glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glad_glDrawElementsInstancedARB; + if (glad_glDrawElementsInstancedEXT == NULL && glad_glDrawElementsInstancedNV != NULL) glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glad_glDrawElementsInstancedNV; + if (glad_glDrawElementsInstancedNV == NULL && glad_glDrawElementsInstanced != NULL) glad_glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glad_glDrawElementsInstanced; + if (glad_glDrawElementsInstancedNV == NULL && glad_glDrawElementsInstancedANGLE != NULL) glad_glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glad_glDrawElementsInstancedANGLE; + if (glad_glDrawElementsInstancedNV == NULL && glad_glDrawElementsInstancedARB != NULL) glad_glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glad_glDrawElementsInstancedARB; + if (glad_glDrawElementsInstancedNV == NULL && glad_glDrawElementsInstancedEXT != NULL) glad_glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glad_glDrawElementsInstancedEXT; + if (glad_glDrawRangeElements == NULL && glad_glDrawRangeElementsEXT != NULL) glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glad_glDrawRangeElementsEXT; + if (glad_glDrawRangeElementsBaseVertex == NULL && glad_glDrawRangeElementsBaseVertexEXT != NULL) glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glad_glDrawRangeElementsBaseVertexEXT; + if (glad_glDrawRangeElementsBaseVertex == NULL && glad_glDrawRangeElementsBaseVertexOES != NULL) glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glad_glDrawRangeElementsBaseVertexOES; + if (glad_glDrawRangeElementsBaseVertexEXT == NULL && glad_glDrawRangeElementsBaseVertex != NULL) glad_glDrawRangeElementsBaseVertexEXT = (PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC)glad_glDrawRangeElementsBaseVertex; + if (glad_glDrawRangeElementsBaseVertexEXT == NULL && glad_glDrawRangeElementsBaseVertexOES != NULL) glad_glDrawRangeElementsBaseVertexEXT = (PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC)glad_glDrawRangeElementsBaseVertexOES; + if (glad_glDrawRangeElementsBaseVertexOES == NULL && glad_glDrawRangeElementsBaseVertex != NULL) glad_glDrawRangeElementsBaseVertexOES = (PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC)glad_glDrawRangeElementsBaseVertex; + if (glad_glDrawRangeElementsBaseVertexOES == NULL && glad_glDrawRangeElementsBaseVertexEXT != NULL) glad_glDrawRangeElementsBaseVertexOES = (PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC)glad_glDrawRangeElementsBaseVertexEXT; + if (glad_glDrawRangeElementsEXT == NULL && glad_glDrawRangeElements != NULL) glad_glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glad_glDrawRangeElements; + if (glad_glDrawTransformFeedback == NULL && glad_glDrawTransformFeedbackEXT != NULL) glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glad_glDrawTransformFeedbackEXT; + if (glad_glDrawTransformFeedback == NULL && glad_glDrawTransformFeedbackNV != NULL) glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glad_glDrawTransformFeedbackNV; + if (glad_glDrawTransformFeedbackEXT == NULL && glad_glDrawTransformFeedback != NULL) glad_glDrawTransformFeedbackEXT = (PFNGLDRAWTRANSFORMFEEDBACKEXTPROC)glad_glDrawTransformFeedback; + if (glad_glDrawTransformFeedbackEXT == NULL && glad_glDrawTransformFeedbackNV != NULL) glad_glDrawTransformFeedbackEXT = (PFNGLDRAWTRANSFORMFEEDBACKEXTPROC)glad_glDrawTransformFeedbackNV; + if (glad_glDrawTransformFeedbackInstanced == NULL && glad_glDrawTransformFeedbackInstancedEXT != NULL) glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)glad_glDrawTransformFeedbackInstancedEXT; + if (glad_glDrawTransformFeedbackInstancedEXT == NULL && glad_glDrawTransformFeedbackInstanced != NULL) glad_glDrawTransformFeedbackInstancedEXT = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC)glad_glDrawTransformFeedbackInstanced; + if (glad_glDrawTransformFeedbackNV == NULL && glad_glDrawTransformFeedback != NULL) glad_glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glad_glDrawTransformFeedback; + if (glad_glDrawTransformFeedbackNV == NULL && glad_glDrawTransformFeedbackEXT != NULL) glad_glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glad_glDrawTransformFeedbackEXT; + if (glad_glEnablei == NULL && glad_glEnableIndexedEXT != NULL) glad_glEnablei = (PFNGLENABLEIPROC)glad_glEnableIndexedEXT; + if (glad_glEnablei == NULL && glad_glEnableiEXT != NULL) glad_glEnablei = (PFNGLENABLEIPROC)glad_glEnableiEXT; + if (glad_glEnablei == NULL && glad_glEnableiNV != NULL) glad_glEnablei = (PFNGLENABLEIPROC)glad_glEnableiNV; + if (glad_glEnablei == NULL && glad_glEnableiOES != NULL) glad_glEnablei = (PFNGLENABLEIPROC)glad_glEnableiOES; + if (glad_glEnableiEXT == NULL && glad_glEnableIndexedEXT != NULL) glad_glEnableiEXT = (PFNGLENABLEIEXTPROC)glad_glEnableIndexedEXT; + if (glad_glEnableiEXT == NULL && glad_glEnablei != NULL) glad_glEnableiEXT = (PFNGLENABLEIEXTPROC)glad_glEnablei; + if (glad_glEnableiEXT == NULL && glad_glEnableiNV != NULL) glad_glEnableiEXT = (PFNGLENABLEIEXTPROC)glad_glEnableiNV; + if (glad_glEnableiEXT == NULL && glad_glEnableiOES != NULL) glad_glEnableiEXT = (PFNGLENABLEIEXTPROC)glad_glEnableiOES; + if (glad_glEnableIndexedEXT == NULL && glad_glEnablei != NULL) glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glad_glEnablei; + if (glad_glEnableIndexedEXT == NULL && glad_glEnableiEXT != NULL) glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glad_glEnableiEXT; + if (glad_glEnableIndexedEXT == NULL && glad_glEnableiNV != NULL) glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glad_glEnableiNV; + if (glad_glEnableIndexedEXT == NULL && glad_glEnableiOES != NULL) glad_glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glad_glEnableiOES; + if (glad_glEnableiNV == NULL && glad_glEnableIndexedEXT != NULL) glad_glEnableiNV = (PFNGLENABLEINVPROC)glad_glEnableIndexedEXT; + if (glad_glEnableiNV == NULL && glad_glEnablei != NULL) glad_glEnableiNV = (PFNGLENABLEINVPROC)glad_glEnablei; + if (glad_glEnableiNV == NULL && glad_glEnableiEXT != NULL) glad_glEnableiNV = (PFNGLENABLEINVPROC)glad_glEnableiEXT; + if (glad_glEnableiNV == NULL && glad_glEnableiOES != NULL) glad_glEnableiNV = (PFNGLENABLEINVPROC)glad_glEnableiOES; + if (glad_glEnableiOES == NULL && glad_glEnableIndexedEXT != NULL) glad_glEnableiOES = (PFNGLENABLEIOESPROC)glad_glEnableIndexedEXT; + if (glad_glEnableiOES == NULL && glad_glEnablei != NULL) glad_glEnableiOES = (PFNGLENABLEIOESPROC)glad_glEnablei; + if (glad_glEnableiOES == NULL && glad_glEnableiEXT != NULL) glad_glEnableiOES = (PFNGLENABLEIOESPROC)glad_glEnableiEXT; + if (glad_glEnableiOES == NULL && glad_glEnableiNV != NULL) glad_glEnableiOES = (PFNGLENABLEIOESPROC)glad_glEnableiNV; + if (glad_glEnableVertexAttribArray == NULL && glad_glEnableVertexAttribArrayARB != NULL) glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glad_glEnableVertexAttribArrayARB; + if (glad_glEnableVertexAttribArrayARB == NULL && glad_glEnableVertexAttribArray != NULL) glad_glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glad_glEnableVertexAttribArray; + if (glad_glEndConditionalRender == NULL && glad_glEndConditionalRenderNV != NULL) glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glad_glEndConditionalRenderNV; + if (glad_glEndConditionalRender == NULL && glad_glEndConditionalRenderNVX != NULL) glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glad_glEndConditionalRenderNVX; + if (glad_glEndConditionalRenderNV == NULL && glad_glEndConditionalRender != NULL) glad_glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glad_glEndConditionalRender; + if (glad_glEndConditionalRenderNV == NULL && glad_glEndConditionalRenderNVX != NULL) glad_glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glad_glEndConditionalRenderNVX; + if (glad_glEndConditionalRenderNVX == NULL && glad_glEndConditionalRender != NULL) glad_glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glad_glEndConditionalRender; + if (glad_glEndConditionalRenderNVX == NULL && glad_glEndConditionalRenderNV != NULL) glad_glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glad_glEndConditionalRenderNV; + if (glad_glEndQuery == NULL && glad_glEndQueryARB != NULL) glad_glEndQuery = (PFNGLENDQUERYPROC)glad_glEndQueryARB; + if (glad_glEndQueryARB == NULL && glad_glEndQuery != NULL) glad_glEndQueryARB = (PFNGLENDQUERYARBPROC)glad_glEndQuery; + if (glad_glEndTransformFeedback == NULL && glad_glEndTransformFeedbackEXT != NULL) glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glad_glEndTransformFeedbackEXT; + if (glad_glEndTransformFeedback == NULL && glad_glEndTransformFeedbackNV != NULL) glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glad_glEndTransformFeedbackNV; + if (glad_glEndTransformFeedbackEXT == NULL && glad_glEndTransformFeedback != NULL) glad_glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glad_glEndTransformFeedback; + if (glad_glEndTransformFeedbackEXT == NULL && glad_glEndTransformFeedbackNV != NULL) glad_glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glad_glEndTransformFeedbackNV; + if (glad_glEndTransformFeedbackNV == NULL && glad_glEndTransformFeedback != NULL) glad_glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glad_glEndTransformFeedback; + if (glad_glEndTransformFeedbackNV == NULL && glad_glEndTransformFeedbackEXT != NULL) glad_glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glad_glEndTransformFeedbackEXT; + if (glad_glFenceSync == NULL && glad_glFenceSyncAPPLE != NULL) glad_glFenceSync = (PFNGLFENCESYNCPROC)glad_glFenceSyncAPPLE; + if (glad_glFenceSyncAPPLE == NULL && glad_glFenceSync != NULL) glad_glFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC)glad_glFenceSync; + if (glad_glFlushMappedBufferRange == NULL && glad_glFlushMappedBufferRangeAPPLE != NULL) glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glad_glFlushMappedBufferRangeAPPLE; + if (glad_glFlushMappedBufferRange == NULL && glad_glFlushMappedBufferRangeEXT != NULL) glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glad_glFlushMappedBufferRangeEXT; + if (glad_glFlushMappedBufferRangeAPPLE == NULL && glad_glFlushMappedBufferRange != NULL) glad_glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glad_glFlushMappedBufferRange; + if (glad_glFlushMappedBufferRangeAPPLE == NULL && glad_glFlushMappedBufferRangeEXT != NULL) glad_glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glad_glFlushMappedBufferRangeEXT; + if (glad_glFlushMappedBufferRangeEXT == NULL && glad_glFlushMappedBufferRange != NULL) glad_glFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC)glad_glFlushMappedBufferRange; + if (glad_glFlushMappedBufferRangeEXT == NULL && glad_glFlushMappedBufferRangeAPPLE != NULL) glad_glFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC)glad_glFlushMappedBufferRangeAPPLE; + if (glad_glFogCoordd == NULL && glad_glFogCoorddEXT != NULL) glad_glFogCoordd = (PFNGLFOGCOORDDPROC)glad_glFogCoorddEXT; + if (glad_glFogCoorddEXT == NULL && glad_glFogCoordd != NULL) glad_glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glad_glFogCoordd; + if (glad_glFogCoorddv == NULL && glad_glFogCoorddvEXT != NULL) glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC)glad_glFogCoorddvEXT; + if (glad_glFogCoorddvEXT == NULL && glad_glFogCoorddv != NULL) glad_glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glad_glFogCoorddv; + if (glad_glFogCoordf == NULL && glad_glFogCoordfEXT != NULL) glad_glFogCoordf = (PFNGLFOGCOORDFPROC)glad_glFogCoordfEXT; + if (glad_glFogCoordfEXT == NULL && glad_glFogCoordf != NULL) glad_glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glad_glFogCoordf; + if (glad_glFogCoordfv == NULL && glad_glFogCoordfvEXT != NULL) glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC)glad_glFogCoordfvEXT; + if (glad_glFogCoordfvEXT == NULL && glad_glFogCoordfv != NULL) glad_glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glad_glFogCoordfv; + if (glad_glFogCoordPointer == NULL && glad_glFogCoordPointerEXT != NULL) glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glad_glFogCoordPointerEXT; + if (glad_glFogCoordPointerEXT == NULL && glad_glFogCoordPointer != NULL) glad_glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glad_glFogCoordPointer; + if (glad_glFramebufferRenderbuffer == NULL && glad_glFramebufferRenderbufferEXT != NULL) glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glad_glFramebufferRenderbufferEXT; + if (glad_glFramebufferRenderbufferEXT == NULL && glad_glFramebufferRenderbuffer != NULL) glad_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glad_glFramebufferRenderbuffer; + if (glad_glFramebufferTexture == NULL && glad_glFramebufferTextureARB != NULL) glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glad_glFramebufferTextureARB; + if (glad_glFramebufferTexture == NULL && glad_glFramebufferTextureEXT != NULL) glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glad_glFramebufferTextureEXT; + if (glad_glFramebufferTexture == NULL && glad_glFramebufferTextureOES != NULL) glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glad_glFramebufferTextureOES; + if (glad_glFramebufferTexture1D == NULL && glad_glFramebufferTexture1DEXT != NULL) glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glad_glFramebufferTexture1DEXT; + if (glad_glFramebufferTexture1DEXT == NULL && glad_glFramebufferTexture1D != NULL) glad_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glad_glFramebufferTexture1D; + if (glad_glFramebufferTexture2D == NULL && glad_glFramebufferTexture2DEXT != NULL) glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glad_glFramebufferTexture2DEXT; + if (glad_glFramebufferTexture2DEXT == NULL && glad_glFramebufferTexture2D != NULL) glad_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glad_glFramebufferTexture2D; + if (glad_glFramebufferTexture3D == NULL && glad_glFramebufferTexture3DEXT != NULL) glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glad_glFramebufferTexture3DEXT; + if (glad_glFramebufferTexture3DEXT == NULL && glad_glFramebufferTexture3D != NULL) glad_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glad_glFramebufferTexture3D; + if (glad_glFramebufferTextureARB == NULL && glad_glFramebufferTexture != NULL) glad_glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glad_glFramebufferTexture; + if (glad_glFramebufferTextureARB == NULL && glad_glFramebufferTextureEXT != NULL) glad_glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glad_glFramebufferTextureEXT; + if (glad_glFramebufferTextureARB == NULL && glad_glFramebufferTextureOES != NULL) glad_glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glad_glFramebufferTextureOES; + if (glad_glFramebufferTextureEXT == NULL && glad_glFramebufferTexture != NULL) glad_glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glad_glFramebufferTexture; + if (glad_glFramebufferTextureEXT == NULL && glad_glFramebufferTextureARB != NULL) glad_glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glad_glFramebufferTextureARB; + if (glad_glFramebufferTextureEXT == NULL && glad_glFramebufferTextureOES != NULL) glad_glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glad_glFramebufferTextureOES; + if (glad_glFramebufferTextureFaceARB == NULL && glad_glFramebufferTextureFaceEXT != NULL) glad_glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glad_glFramebufferTextureFaceEXT; + if (glad_glFramebufferTextureFaceEXT == NULL && glad_glFramebufferTextureFaceARB != NULL) glad_glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glad_glFramebufferTextureFaceARB; + if (glad_glFramebufferTextureLayer == NULL && glad_glFramebufferTextureLayerARB != NULL) glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glad_glFramebufferTextureLayerARB; + if (glad_glFramebufferTextureLayer == NULL && glad_glFramebufferTextureLayerEXT != NULL) glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glad_glFramebufferTextureLayerEXT; + if (glad_glFramebufferTextureLayerARB == NULL && glad_glFramebufferTextureLayer != NULL) glad_glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glad_glFramebufferTextureLayer; + if (glad_glFramebufferTextureLayerARB == NULL && glad_glFramebufferTextureLayerEXT != NULL) glad_glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glad_glFramebufferTextureLayerEXT; + if (glad_glFramebufferTextureLayerEXT == NULL && glad_glFramebufferTextureLayer != NULL) glad_glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glad_glFramebufferTextureLayer; + if (glad_glFramebufferTextureLayerEXT == NULL && glad_glFramebufferTextureLayerARB != NULL) glad_glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glad_glFramebufferTextureLayerARB; + if (glad_glFramebufferTextureOES == NULL && glad_glFramebufferTexture != NULL) glad_glFramebufferTextureOES = (PFNGLFRAMEBUFFERTEXTUREOESPROC)glad_glFramebufferTexture; + if (glad_glFramebufferTextureOES == NULL && glad_glFramebufferTextureARB != NULL) glad_glFramebufferTextureOES = (PFNGLFRAMEBUFFERTEXTUREOESPROC)glad_glFramebufferTextureARB; + if (glad_glFramebufferTextureOES == NULL && glad_glFramebufferTextureEXT != NULL) glad_glFramebufferTextureOES = (PFNGLFRAMEBUFFERTEXTUREOESPROC)glad_glFramebufferTextureEXT; + if (glad_glGenBuffers == NULL && glad_glGenBuffersARB != NULL) glad_glGenBuffers = (PFNGLGENBUFFERSPROC)glad_glGenBuffersARB; + if (glad_glGenBuffersARB == NULL && glad_glGenBuffers != NULL) glad_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glad_glGenBuffers; + if (glad_glGenerateMipmap == NULL && glad_glGenerateMipmapEXT != NULL) glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glad_glGenerateMipmapEXT; + if (glad_glGenerateMipmapEXT == NULL && glad_glGenerateMipmap != NULL) glad_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glad_glGenerateMipmap; + if (glad_glGenFramebuffers == NULL && glad_glGenFramebuffersEXT != NULL) glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glad_glGenFramebuffersEXT; + if (glad_glGenFramebuffersEXT == NULL && glad_glGenFramebuffers != NULL) glad_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glad_glGenFramebuffers; + if (glad_glGenProgramsARB == NULL && glad_glGenProgramsNV != NULL) glad_glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glad_glGenProgramsNV; + if (glad_glGenProgramsNV == NULL && glad_glGenProgramsARB != NULL) glad_glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glad_glGenProgramsARB; + if (glad_glGenQueries == NULL && glad_glGenQueriesARB != NULL) glad_glGenQueries = (PFNGLGENQUERIESPROC)glad_glGenQueriesARB; + if (glad_glGenQueriesARB == NULL && glad_glGenQueries != NULL) glad_glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glad_glGenQueries; + if (glad_glGenRenderbuffers == NULL && glad_glGenRenderbuffersEXT != NULL) glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glad_glGenRenderbuffersEXT; + if (glad_glGenRenderbuffersEXT == NULL && glad_glGenRenderbuffers != NULL) glad_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glad_glGenRenderbuffers; + if (glad_glGenTransformFeedbacks == NULL && glad_glGenTransformFeedbacksNV != NULL) glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)glad_glGenTransformFeedbacksNV; + if (glad_glGenTransformFeedbacksNV == NULL && glad_glGenTransformFeedbacks != NULL) glad_glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glad_glGenTransformFeedbacks; + if (glad_glGenVertexArrays == NULL && glad_glGenVertexArraysAPPLE != NULL) glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glad_glGenVertexArraysAPPLE; + if (glad_glGenVertexArrays == NULL && glad_glGenVertexArraysOES != NULL) glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glad_glGenVertexArraysOES; + if (glad_glGenVertexArraysAPPLE == NULL && glad_glGenVertexArrays != NULL) glad_glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glad_glGenVertexArrays; + if (glad_glGenVertexArraysAPPLE == NULL && glad_glGenVertexArraysOES != NULL) glad_glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glad_glGenVertexArraysOES; + if (glad_glGenVertexArraysOES == NULL && glad_glGenVertexArrays != NULL) glad_glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)glad_glGenVertexArrays; + if (glad_glGenVertexArraysOES == NULL && glad_glGenVertexArraysAPPLE != NULL) glad_glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)glad_glGenVertexArraysAPPLE; + if (glad_glGetActiveAttrib == NULL && glad_glGetActiveAttribARB != NULL) glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glad_glGetActiveAttribARB; + if (glad_glGetActiveAttribARB == NULL && glad_glGetActiveAttrib != NULL) glad_glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glad_glGetActiveAttrib; + if (glad_glGetActiveUniform == NULL && glad_glGetActiveUniformARB != NULL) glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glad_glGetActiveUniformARB; + if (glad_glGetActiveUniformARB == NULL && glad_glGetActiveUniform != NULL) glad_glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glad_glGetActiveUniform; + if (glad_glGetAttribLocation == NULL && glad_glGetAttribLocationARB != NULL) glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glad_glGetAttribLocationARB; + if (glad_glGetAttribLocationARB == NULL && glad_glGetAttribLocation != NULL) glad_glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glad_glGetAttribLocation; + if (glad_glGetBooleani_v == NULL && glad_glGetBooleanIndexedvEXT != NULL) glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glad_glGetBooleanIndexedvEXT; + if (glad_glGetBooleanIndexedvEXT == NULL && glad_glGetBooleani_v != NULL) glad_glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glad_glGetBooleani_v; + if (glad_glGetBufferParameteriv == NULL && glad_glGetBufferParameterivARB != NULL) glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glad_glGetBufferParameterivARB; + if (glad_glGetBufferParameterivARB == NULL && glad_glGetBufferParameteriv != NULL) glad_glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glad_glGetBufferParameteriv; + if (glad_glGetBufferPointerv == NULL && glad_glGetBufferPointervARB != NULL) glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glad_glGetBufferPointervARB; + if (glad_glGetBufferPointerv == NULL && glad_glGetBufferPointervOES != NULL) glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glad_glGetBufferPointervOES; + if (glad_glGetBufferPointervARB == NULL && glad_glGetBufferPointerv != NULL) glad_glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glad_glGetBufferPointerv; + if (glad_glGetBufferPointervARB == NULL && glad_glGetBufferPointervOES != NULL) glad_glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glad_glGetBufferPointervOES; + if (glad_glGetBufferPointervOES == NULL && glad_glGetBufferPointerv != NULL) glad_glGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC)glad_glGetBufferPointerv; + if (glad_glGetBufferPointervOES == NULL && glad_glGetBufferPointervARB != NULL) glad_glGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC)glad_glGetBufferPointervARB; + if (glad_glGetBufferSubData == NULL && glad_glGetBufferSubDataARB != NULL) glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glad_glGetBufferSubDataARB; + if (glad_glGetBufferSubDataARB == NULL && glad_glGetBufferSubData != NULL) glad_glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glad_glGetBufferSubData; + if (glad_glGetColorTable == NULL && glad_glGetColorTableEXT != NULL) glad_glGetColorTable = (PFNGLGETCOLORTABLEPROC)glad_glGetColorTableEXT; + if (glad_glGetColorTableEXT == NULL && glad_glGetColorTable != NULL) glad_glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glad_glGetColorTable; + if (glad_glGetColorTableParameterfv == NULL && glad_glGetColorTableParameterfvEXT != NULL) glad_glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glad_glGetColorTableParameterfvEXT; + if (glad_glGetColorTableParameterfvEXT == NULL && glad_glGetColorTableParameterfv != NULL) glad_glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glad_glGetColorTableParameterfv; + if (glad_glGetColorTableParameteriv == NULL && glad_glGetColorTableParameterivEXT != NULL) glad_glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glad_glGetColorTableParameterivEXT; + if (glad_glGetColorTableParameterivEXT == NULL && glad_glGetColorTableParameteriv != NULL) glad_glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glad_glGetColorTableParameteriv; + if (glad_glGetCompressedTexImage == NULL && glad_glGetCompressedTexImageARB != NULL) glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glad_glGetCompressedTexImageARB; + if (glad_glGetCompressedTexImageARB == NULL && glad_glGetCompressedTexImage != NULL) glad_glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glad_glGetCompressedTexImage; + if (glad_glGetDebugMessageLog == NULL && glad_glGetDebugMessageLogARB != NULL) glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glad_glGetDebugMessageLogARB; + if (glad_glGetDebugMessageLog == NULL && glad_glGetDebugMessageLogKHR != NULL) glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glad_glGetDebugMessageLogKHR; + if (glad_glGetDebugMessageLogARB == NULL && glad_glGetDebugMessageLog != NULL) glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glad_glGetDebugMessageLog; + if (glad_glGetDebugMessageLogARB == NULL && glad_glGetDebugMessageLogKHR != NULL) glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glad_glGetDebugMessageLogKHR; + if (glad_glGetDebugMessageLogKHR == NULL && glad_glGetDebugMessageLog != NULL) glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC)glad_glGetDebugMessageLog; + if (glad_glGetDebugMessageLogKHR == NULL && glad_glGetDebugMessageLogARB != NULL) glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC)glad_glGetDebugMessageLogARB; + if (glad_glGetDoublei_v == NULL && glad_glGetDoubleIndexedvEXT != NULL) glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glad_glGetDoubleIndexedvEXT; + if (glad_glGetDoublei_v == NULL && glad_glGetDoublei_vEXT != NULL) glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glad_glGetDoublei_vEXT; + if (glad_glGetDoublei_vEXT == NULL && glad_glGetDoubleIndexedvEXT != NULL) glad_glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glad_glGetDoubleIndexedvEXT; + if (glad_glGetDoublei_vEXT == NULL && glad_glGetDoublei_v != NULL) glad_glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glad_glGetDoublei_v; + if (glad_glGetDoubleIndexedvEXT == NULL && glad_glGetDoublei_v != NULL) glad_glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glad_glGetDoublei_v; + if (glad_glGetDoubleIndexedvEXT == NULL && glad_glGetDoublei_vEXT != NULL) glad_glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glad_glGetDoublei_vEXT; + if (glad_glGetFloati_v == NULL && glad_glGetFloatIndexedvEXT != NULL) glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC)glad_glGetFloatIndexedvEXT; + if (glad_glGetFloati_v == NULL && glad_glGetFloati_vEXT != NULL) glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC)glad_glGetFloati_vEXT; + if (glad_glGetFloati_v == NULL && glad_glGetFloati_vNV != NULL) glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC)glad_glGetFloati_vNV; + if (glad_glGetFloati_v == NULL && glad_glGetFloati_vOES != NULL) glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC)glad_glGetFloati_vOES; + if (glad_glGetFloati_vEXT == NULL && glad_glGetFloatIndexedvEXT != NULL) glad_glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glad_glGetFloatIndexedvEXT; + if (glad_glGetFloati_vEXT == NULL && glad_glGetFloati_v != NULL) glad_glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glad_glGetFloati_v; + if (glad_glGetFloati_vEXT == NULL && glad_glGetFloati_vNV != NULL) glad_glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glad_glGetFloati_vNV; + if (glad_glGetFloati_vEXT == NULL && glad_glGetFloati_vOES != NULL) glad_glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glad_glGetFloati_vOES; + if (glad_glGetFloati_vNV == NULL && glad_glGetFloatIndexedvEXT != NULL) glad_glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glad_glGetFloatIndexedvEXT; + if (glad_glGetFloati_vNV == NULL && glad_glGetFloati_v != NULL) glad_glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glad_glGetFloati_v; + if (glad_glGetFloati_vNV == NULL && glad_glGetFloati_vEXT != NULL) glad_glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glad_glGetFloati_vEXT; + if (glad_glGetFloati_vNV == NULL && glad_glGetFloati_vOES != NULL) glad_glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glad_glGetFloati_vOES; + if (glad_glGetFloati_vOES == NULL && glad_glGetFloatIndexedvEXT != NULL) glad_glGetFloati_vOES = (PFNGLGETFLOATI_VOESPROC)glad_glGetFloatIndexedvEXT; + if (glad_glGetFloati_vOES == NULL && glad_glGetFloati_v != NULL) glad_glGetFloati_vOES = (PFNGLGETFLOATI_VOESPROC)glad_glGetFloati_v; + if (glad_glGetFloati_vOES == NULL && glad_glGetFloati_vEXT != NULL) glad_glGetFloati_vOES = (PFNGLGETFLOATI_VOESPROC)glad_glGetFloati_vEXT; + if (glad_glGetFloati_vOES == NULL && glad_glGetFloati_vNV != NULL) glad_glGetFloati_vOES = (PFNGLGETFLOATI_VOESPROC)glad_glGetFloati_vNV; + if (glad_glGetFloatIndexedvEXT == NULL && glad_glGetFloati_v != NULL) glad_glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glad_glGetFloati_v; + if (glad_glGetFloatIndexedvEXT == NULL && glad_glGetFloati_vEXT != NULL) glad_glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glad_glGetFloati_vEXT; + if (glad_glGetFloatIndexedvEXT == NULL && glad_glGetFloati_vNV != NULL) glad_glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glad_glGetFloati_vNV; + if (glad_glGetFloatIndexedvEXT == NULL && glad_glGetFloati_vOES != NULL) glad_glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glad_glGetFloati_vOES; + if (glad_glGetFragDataIndex == NULL && glad_glGetFragDataIndexEXT != NULL) glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)glad_glGetFragDataIndexEXT; + if (glad_glGetFragDataIndexEXT == NULL && glad_glGetFragDataIndex != NULL) glad_glGetFragDataIndexEXT = (PFNGLGETFRAGDATAINDEXEXTPROC)glad_glGetFragDataIndex; + if (glad_glGetFragDataLocation == NULL && glad_glGetFragDataLocationEXT != NULL) glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glad_glGetFragDataLocationEXT; + if (glad_glGetFragDataLocationEXT == NULL && glad_glGetFragDataLocation != NULL) glad_glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glad_glGetFragDataLocation; + if (glad_glGetFramebufferAttachmentParameteriv == NULL && glad_glGetFramebufferAttachmentParameterivEXT != NULL) glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glad_glGetFramebufferAttachmentParameterivEXT; + if (glad_glGetFramebufferAttachmentParameterivEXT == NULL && glad_glGetFramebufferAttachmentParameteriv != NULL) glad_glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glad_glGetFramebufferAttachmentParameteriv; + if (glad_glGetGraphicsResetStatus == NULL && glad_glGetGraphicsResetStatusEXT != NULL) glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)glad_glGetGraphicsResetStatusEXT; + if (glad_glGetGraphicsResetStatus == NULL && glad_glGetGraphicsResetStatusKHR != NULL) glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)glad_glGetGraphicsResetStatusKHR; + if (glad_glGetGraphicsResetStatusEXT == NULL && glad_glGetGraphicsResetStatus != NULL) glad_glGetGraphicsResetStatusEXT = (PFNGLGETGRAPHICSRESETSTATUSEXTPROC)glad_glGetGraphicsResetStatus; + if (glad_glGetGraphicsResetStatusEXT == NULL && glad_glGetGraphicsResetStatusKHR != NULL) glad_glGetGraphicsResetStatusEXT = (PFNGLGETGRAPHICSRESETSTATUSEXTPROC)glad_glGetGraphicsResetStatusKHR; + if (glad_glGetGraphicsResetStatusKHR == NULL && glad_glGetGraphicsResetStatus != NULL) glad_glGetGraphicsResetStatusKHR = (PFNGLGETGRAPHICSRESETSTATUSKHRPROC)glad_glGetGraphicsResetStatus; + if (glad_glGetGraphicsResetStatusKHR == NULL && glad_glGetGraphicsResetStatusEXT != NULL) glad_glGetGraphicsResetStatusKHR = (PFNGLGETGRAPHICSRESETSTATUSKHRPROC)glad_glGetGraphicsResetStatusEXT; + if (glad_glGetInteger64v == NULL && glad_glGetInteger64vAPPLE != NULL) glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)glad_glGetInteger64vAPPLE; + if (glad_glGetInteger64v == NULL && glad_glGetInteger64vEXT != NULL) glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)glad_glGetInteger64vEXT; + if (glad_glGetInteger64vAPPLE == NULL && glad_glGetInteger64v != NULL) glad_glGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC)glad_glGetInteger64v; + if (glad_glGetInteger64vAPPLE == NULL && glad_glGetInteger64vEXT != NULL) glad_glGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC)glad_glGetInteger64vEXT; + if (glad_glGetInteger64vEXT == NULL && glad_glGetInteger64v != NULL) glad_glGetInteger64vEXT = (PFNGLGETINTEGER64VEXTPROC)glad_glGetInteger64v; + if (glad_glGetInteger64vEXT == NULL && glad_glGetInteger64vAPPLE != NULL) glad_glGetInteger64vEXT = (PFNGLGETINTEGER64VEXTPROC)glad_glGetInteger64vAPPLE; + if (glad_glGetIntegeri_v == NULL && glad_glGetIntegerIndexedvEXT != NULL) glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glad_glGetIntegerIndexedvEXT; + if (glad_glGetIntegerIndexedvEXT == NULL && glad_glGetIntegeri_v != NULL) glad_glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glad_glGetIntegeri_v; + if (glad_glGetMultisamplefv == NULL && glad_glGetMultisamplefvNV != NULL) glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glad_glGetMultisamplefvNV; + if (glad_glGetMultisamplefvNV == NULL && glad_glGetMultisamplefv != NULL) glad_glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glad_glGetMultisamplefv; + if (glad_glGetnUniformfv == NULL && glad_glGetnUniformfvEXT != NULL) glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)glad_glGetnUniformfvEXT; + if (glad_glGetnUniformfv == NULL && glad_glGetnUniformfvKHR != NULL) glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)glad_glGetnUniformfvKHR; + if (glad_glGetnUniformfvEXT == NULL && glad_glGetnUniformfv != NULL) glad_glGetnUniformfvEXT = (PFNGLGETNUNIFORMFVEXTPROC)glad_glGetnUniformfv; + if (glad_glGetnUniformfvEXT == NULL && glad_glGetnUniformfvKHR != NULL) glad_glGetnUniformfvEXT = (PFNGLGETNUNIFORMFVEXTPROC)glad_glGetnUniformfvKHR; + if (glad_glGetnUniformfvKHR == NULL && glad_glGetnUniformfv != NULL) glad_glGetnUniformfvKHR = (PFNGLGETNUNIFORMFVKHRPROC)glad_glGetnUniformfv; + if (glad_glGetnUniformfvKHR == NULL && glad_glGetnUniformfvEXT != NULL) glad_glGetnUniformfvKHR = (PFNGLGETNUNIFORMFVKHRPROC)glad_glGetnUniformfvEXT; + if (glad_glGetnUniformiv == NULL && glad_glGetnUniformivEXT != NULL) glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)glad_glGetnUniformivEXT; + if (glad_glGetnUniformiv == NULL && glad_glGetnUniformivKHR != NULL) glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)glad_glGetnUniformivKHR; + if (glad_glGetnUniformivEXT == NULL && glad_glGetnUniformiv != NULL) glad_glGetnUniformivEXT = (PFNGLGETNUNIFORMIVEXTPROC)glad_glGetnUniformiv; + if (glad_glGetnUniformivEXT == NULL && glad_glGetnUniformivKHR != NULL) glad_glGetnUniformivEXT = (PFNGLGETNUNIFORMIVEXTPROC)glad_glGetnUniformivKHR; + if (glad_glGetnUniformivKHR == NULL && glad_glGetnUniformiv != NULL) glad_glGetnUniformivKHR = (PFNGLGETNUNIFORMIVKHRPROC)glad_glGetnUniformiv; + if (glad_glGetnUniformivKHR == NULL && glad_glGetnUniformivEXT != NULL) glad_glGetnUniformivKHR = (PFNGLGETNUNIFORMIVKHRPROC)glad_glGetnUniformivEXT; + if (glad_glGetnUniformuiv == NULL && glad_glGetnUniformuivKHR != NULL) glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)glad_glGetnUniformuivKHR; + if (glad_glGetnUniformuivKHR == NULL && glad_glGetnUniformuiv != NULL) glad_glGetnUniformuivKHR = (PFNGLGETNUNIFORMUIVKHRPROC)glad_glGetnUniformuiv; + if (glad_glGetObjectLabel == NULL && glad_glGetObjectLabelKHR != NULL) glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)glad_glGetObjectLabelKHR; + if (glad_glGetObjectLabelKHR == NULL && glad_glGetObjectLabel != NULL) glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC)glad_glGetObjectLabel; + if (glad_glGetObjectPtrLabel == NULL && glad_glGetObjectPtrLabelKHR != NULL) glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)glad_glGetObjectPtrLabelKHR; + if (glad_glGetObjectPtrLabelKHR == NULL && glad_glGetObjectPtrLabel != NULL) glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC)glad_glGetObjectPtrLabel; + if (glad_glGetPointerv == NULL && glad_glGetPointervEXT != NULL) glad_glGetPointerv = (PFNGLGETPOINTERVPROC)glad_glGetPointervEXT; + if (glad_glGetPointerv == NULL && glad_glGetPointervKHR != NULL) glad_glGetPointerv = (PFNGLGETPOINTERVPROC)glad_glGetPointervKHR; + if (glad_glGetPointervEXT == NULL && glad_glGetPointerv != NULL) glad_glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glad_glGetPointerv; + if (glad_glGetPointervEXT == NULL && glad_glGetPointervKHR != NULL) glad_glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glad_glGetPointervKHR; + if (glad_glGetPointervKHR == NULL && glad_glGetPointerv != NULL) glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC)glad_glGetPointerv; + if (glad_glGetPointervKHR == NULL && glad_glGetPointervEXT != NULL) glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC)glad_glGetPointervEXT; + if (glad_glGetProgramBinary == NULL && glad_glGetProgramBinaryOES != NULL) glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)glad_glGetProgramBinaryOES; + if (glad_glGetProgramBinaryOES == NULL && glad_glGetProgramBinary != NULL) glad_glGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC)glad_glGetProgramBinary; + if (glad_glGetQueryiv == NULL && glad_glGetQueryivARB != NULL) glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)glad_glGetQueryivARB; + if (glad_glGetQueryivARB == NULL && glad_glGetQueryiv != NULL) glad_glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glad_glGetQueryiv; + if (glad_glGetQueryObjecti64v == NULL && glad_glGetQueryObjecti64vEXT != NULL) glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)glad_glGetQueryObjecti64vEXT; + if (glad_glGetQueryObjecti64vEXT == NULL && glad_glGetQueryObjecti64v != NULL) glad_glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glad_glGetQueryObjecti64v; + if (glad_glGetQueryObjectiv == NULL && glad_glGetQueryObjectivARB != NULL) glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glad_glGetQueryObjectivARB; + if (glad_glGetQueryObjectiv == NULL && glad_glGetQueryObjectivEXT != NULL) glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glad_glGetQueryObjectivEXT; + if (glad_glGetQueryObjectivARB == NULL && glad_glGetQueryObjectiv != NULL) glad_glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glad_glGetQueryObjectiv; + if (glad_glGetQueryObjectivARB == NULL && glad_glGetQueryObjectivEXT != NULL) glad_glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glad_glGetQueryObjectivEXT; + if (glad_glGetQueryObjectivEXT == NULL && glad_glGetQueryObjectiv != NULL) glad_glGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC)glad_glGetQueryObjectiv; + if (glad_glGetQueryObjectivEXT == NULL && glad_glGetQueryObjectivARB != NULL) glad_glGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC)glad_glGetQueryObjectivARB; + if (glad_glGetQueryObjectui64v == NULL && glad_glGetQueryObjectui64vEXT != NULL) glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glad_glGetQueryObjectui64vEXT; + if (glad_glGetQueryObjectui64vEXT == NULL && glad_glGetQueryObjectui64v != NULL) glad_glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glad_glGetQueryObjectui64v; + if (glad_glGetQueryObjectuiv == NULL && glad_glGetQueryObjectuivARB != NULL) glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glad_glGetQueryObjectuivARB; + if (glad_glGetQueryObjectuivARB == NULL && glad_glGetQueryObjectuiv != NULL) glad_glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glad_glGetQueryObjectuiv; + if (glad_glGetRenderbufferParameteriv == NULL && glad_glGetRenderbufferParameterivEXT != NULL) glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glad_glGetRenderbufferParameterivEXT; + if (glad_glGetRenderbufferParameterivEXT == NULL && glad_glGetRenderbufferParameteriv != NULL) glad_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glad_glGetRenderbufferParameteriv; + if (glad_glGetSamplerParameterIiv == NULL && glad_glGetSamplerParameterIivEXT != NULL) glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glad_glGetSamplerParameterIivEXT; + if (glad_glGetSamplerParameterIiv == NULL && glad_glGetSamplerParameterIivOES != NULL) glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glad_glGetSamplerParameterIivOES; + if (glad_glGetSamplerParameterIivEXT == NULL && glad_glGetSamplerParameterIiv != NULL) glad_glGetSamplerParameterIivEXT = (PFNGLGETSAMPLERPARAMETERIIVEXTPROC)glad_glGetSamplerParameterIiv; + if (glad_glGetSamplerParameterIivEXT == NULL && glad_glGetSamplerParameterIivOES != NULL) glad_glGetSamplerParameterIivEXT = (PFNGLGETSAMPLERPARAMETERIIVEXTPROC)glad_glGetSamplerParameterIivOES; + if (glad_glGetSamplerParameterIivOES == NULL && glad_glGetSamplerParameterIiv != NULL) glad_glGetSamplerParameterIivOES = (PFNGLGETSAMPLERPARAMETERIIVOESPROC)glad_glGetSamplerParameterIiv; + if (glad_glGetSamplerParameterIivOES == NULL && glad_glGetSamplerParameterIivEXT != NULL) glad_glGetSamplerParameterIivOES = (PFNGLGETSAMPLERPARAMETERIIVOESPROC)glad_glGetSamplerParameterIivEXT; + if (glad_glGetSamplerParameterIuiv == NULL && glad_glGetSamplerParameterIuivEXT != NULL) glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glad_glGetSamplerParameterIuivEXT; + if (glad_glGetSamplerParameterIuiv == NULL && glad_glGetSamplerParameterIuivOES != NULL) glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glad_glGetSamplerParameterIuivOES; + if (glad_glGetSamplerParameterIuivEXT == NULL && glad_glGetSamplerParameterIuiv != NULL) glad_glGetSamplerParameterIuivEXT = (PFNGLGETSAMPLERPARAMETERIUIVEXTPROC)glad_glGetSamplerParameterIuiv; + if (glad_glGetSamplerParameterIuivEXT == NULL && glad_glGetSamplerParameterIuivOES != NULL) glad_glGetSamplerParameterIuivEXT = (PFNGLGETSAMPLERPARAMETERIUIVEXTPROC)glad_glGetSamplerParameterIuivOES; + if (glad_glGetSamplerParameterIuivOES == NULL && glad_glGetSamplerParameterIuiv != NULL) glad_glGetSamplerParameterIuivOES = (PFNGLGETSAMPLERPARAMETERIUIVOESPROC)glad_glGetSamplerParameterIuiv; + if (glad_glGetSamplerParameterIuivOES == NULL && glad_glGetSamplerParameterIuivEXT != NULL) glad_glGetSamplerParameterIuivOES = (PFNGLGETSAMPLERPARAMETERIUIVOESPROC)glad_glGetSamplerParameterIuivEXT; + if (glad_glGetShaderSource == NULL && glad_glGetShaderSourceARB != NULL) glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glad_glGetShaderSourceARB; + if (glad_glGetShaderSourceARB == NULL && glad_glGetShaderSource != NULL) glad_glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glad_glGetShaderSource; + if (glad_glGetSynciv == NULL && glad_glGetSyncivAPPLE != NULL) glad_glGetSynciv = (PFNGLGETSYNCIVPROC)glad_glGetSyncivAPPLE; + if (glad_glGetSyncivAPPLE == NULL && glad_glGetSynciv != NULL) glad_glGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC)glad_glGetSynciv; + if (glad_glGetTexParameterIiv == NULL && glad_glGetTexParameterIivEXT != NULL) glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glad_glGetTexParameterIivEXT; + if (glad_glGetTexParameterIiv == NULL && glad_glGetTexParameterIivOES != NULL) glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glad_glGetTexParameterIivOES; + if (glad_glGetTexParameterIivEXT == NULL && glad_glGetTexParameterIiv != NULL) glad_glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glad_glGetTexParameterIiv; + if (glad_glGetTexParameterIivEXT == NULL && glad_glGetTexParameterIivOES != NULL) glad_glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glad_glGetTexParameterIivOES; + if (glad_glGetTexParameterIivOES == NULL && glad_glGetTexParameterIiv != NULL) glad_glGetTexParameterIivOES = (PFNGLGETTEXPARAMETERIIVOESPROC)glad_glGetTexParameterIiv; + if (glad_glGetTexParameterIivOES == NULL && glad_glGetTexParameterIivEXT != NULL) glad_glGetTexParameterIivOES = (PFNGLGETTEXPARAMETERIIVOESPROC)glad_glGetTexParameterIivEXT; + if (glad_glGetTexParameterIuiv == NULL && glad_glGetTexParameterIuivEXT != NULL) glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glad_glGetTexParameterIuivEXT; + if (glad_glGetTexParameterIuiv == NULL && glad_glGetTexParameterIuivOES != NULL) glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glad_glGetTexParameterIuivOES; + if (glad_glGetTexParameterIuivEXT == NULL && glad_glGetTexParameterIuiv != NULL) glad_glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glad_glGetTexParameterIuiv; + if (glad_glGetTexParameterIuivEXT == NULL && glad_glGetTexParameterIuivOES != NULL) glad_glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glad_glGetTexParameterIuivOES; + if (glad_glGetTexParameterIuivOES == NULL && glad_glGetTexParameterIuiv != NULL) glad_glGetTexParameterIuivOES = (PFNGLGETTEXPARAMETERIUIVOESPROC)glad_glGetTexParameterIuiv; + if (glad_glGetTexParameterIuivOES == NULL && glad_glGetTexParameterIuivEXT != NULL) glad_glGetTexParameterIuivOES = (PFNGLGETTEXPARAMETERIUIVOESPROC)glad_glGetTexParameterIuivEXT; + if (glad_glGetTextureHandleARB == NULL && glad_glGetTextureHandleIMG != NULL) glad_glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC)glad_glGetTextureHandleIMG; + if (glad_glGetTextureHandleIMG == NULL && glad_glGetTextureHandleARB != NULL) glad_glGetTextureHandleIMG = (PFNGLGETTEXTUREHANDLEIMGPROC)glad_glGetTextureHandleARB; + if (glad_glGetTextureSamplerHandleARB == NULL && glad_glGetTextureSamplerHandleIMG != NULL) glad_glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC)glad_glGetTextureSamplerHandleIMG; + if (glad_glGetTextureSamplerHandleIMG == NULL && glad_glGetTextureSamplerHandleARB != NULL) glad_glGetTextureSamplerHandleIMG = (PFNGLGETTEXTURESAMPLERHANDLEIMGPROC)glad_glGetTextureSamplerHandleARB; + if (glad_glGetTransformFeedbackVarying == NULL && glad_glGetTransformFeedbackVaryingEXT != NULL) glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glad_glGetTransformFeedbackVaryingEXT; + if (glad_glGetTransformFeedbackVaryingEXT == NULL && glad_glGetTransformFeedbackVarying != NULL) glad_glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glad_glGetTransformFeedbackVarying; + if (glad_glGetUniformfv == NULL && glad_glGetUniformfvARB != NULL) glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glad_glGetUniformfvARB; + if (glad_glGetUniformfvARB == NULL && glad_glGetUniformfv != NULL) glad_glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glad_glGetUniformfv; + if (glad_glGetUniformiv == NULL && glad_glGetUniformivARB != NULL) glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glad_glGetUniformivARB; + if (glad_glGetUniformivARB == NULL && glad_glGetUniformiv != NULL) glad_glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glad_glGetUniformiv; + if (glad_glGetUniformLocation == NULL && glad_glGetUniformLocationARB != NULL) glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glad_glGetUniformLocationARB; + if (glad_glGetUniformLocationARB == NULL && glad_glGetUniformLocation != NULL) glad_glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glad_glGetUniformLocation; + if (glad_glGetUniformuiv == NULL && glad_glGetUniformuivEXT != NULL) glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glad_glGetUniformuivEXT; + if (glad_glGetUniformuivEXT == NULL && glad_glGetUniformuiv != NULL) glad_glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glad_glGetUniformuiv; + if (glad_glGetVertexAttribdv == NULL && glad_glGetVertexAttribdvARB != NULL) glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glad_glGetVertexAttribdvARB; + if (glad_glGetVertexAttribdv == NULL && glad_glGetVertexAttribdvNV != NULL) glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glad_glGetVertexAttribdvNV; + if (glad_glGetVertexAttribdvARB == NULL && glad_glGetVertexAttribdv != NULL) glad_glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glad_glGetVertexAttribdv; + if (glad_glGetVertexAttribdvARB == NULL && glad_glGetVertexAttribdvNV != NULL) glad_glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glad_glGetVertexAttribdvNV; + if (glad_glGetVertexAttribdvNV == NULL && glad_glGetVertexAttribdv != NULL) glad_glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glad_glGetVertexAttribdv; + if (glad_glGetVertexAttribdvNV == NULL && glad_glGetVertexAttribdvARB != NULL) glad_glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glad_glGetVertexAttribdvARB; + if (glad_glGetVertexAttribfv == NULL && glad_glGetVertexAttribfvARB != NULL) glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glad_glGetVertexAttribfvARB; + if (glad_glGetVertexAttribfv == NULL && glad_glGetVertexAttribfvNV != NULL) glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glad_glGetVertexAttribfvNV; + if (glad_glGetVertexAttribfvARB == NULL && glad_glGetVertexAttribfv != NULL) glad_glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glad_glGetVertexAttribfv; + if (glad_glGetVertexAttribfvARB == NULL && glad_glGetVertexAttribfvNV != NULL) glad_glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glad_glGetVertexAttribfvNV; + if (glad_glGetVertexAttribfvNV == NULL && glad_glGetVertexAttribfv != NULL) glad_glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glad_glGetVertexAttribfv; + if (glad_glGetVertexAttribfvNV == NULL && glad_glGetVertexAttribfvARB != NULL) glad_glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glad_glGetVertexAttribfvARB; + if (glad_glGetVertexAttribIiv == NULL && glad_glGetVertexAttribIivEXT != NULL) glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glad_glGetVertexAttribIivEXT; + if (glad_glGetVertexAttribIivEXT == NULL && glad_glGetVertexAttribIiv != NULL) glad_glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glad_glGetVertexAttribIiv; + if (glad_glGetVertexAttribIuiv == NULL && glad_glGetVertexAttribIuivEXT != NULL) glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glad_glGetVertexAttribIuivEXT; + if (glad_glGetVertexAttribIuivEXT == NULL && glad_glGetVertexAttribIuiv != NULL) glad_glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glad_glGetVertexAttribIuiv; + if (glad_glGetVertexAttribiv == NULL && glad_glGetVertexAttribivARB != NULL) glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glad_glGetVertexAttribivARB; + if (glad_glGetVertexAttribiv == NULL && glad_glGetVertexAttribivNV != NULL) glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glad_glGetVertexAttribivNV; + if (glad_glGetVertexAttribivARB == NULL && glad_glGetVertexAttribiv != NULL) glad_glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glad_glGetVertexAttribiv; + if (glad_glGetVertexAttribivARB == NULL && glad_glGetVertexAttribivNV != NULL) glad_glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glad_glGetVertexAttribivNV; + if (glad_glGetVertexAttribivNV == NULL && glad_glGetVertexAttribiv != NULL) glad_glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glad_glGetVertexAttribiv; + if (glad_glGetVertexAttribivNV == NULL && glad_glGetVertexAttribivARB != NULL) glad_glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glad_glGetVertexAttribivARB; + if (glad_glGetVertexAttribLdv == NULL && glad_glGetVertexAttribLdvEXT != NULL) glad_glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)glad_glGetVertexAttribLdvEXT; + if (glad_glGetVertexAttribLdvEXT == NULL && glad_glGetVertexAttribLdv != NULL) glad_glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC)glad_glGetVertexAttribLdv; + if (glad_glGetVertexAttribPointerv == NULL && glad_glGetVertexAttribPointervARB != NULL) glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glad_glGetVertexAttribPointervARB; + if (glad_glGetVertexAttribPointerv == NULL && glad_glGetVertexAttribPointervNV != NULL) glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glad_glGetVertexAttribPointervNV; + if (glad_glGetVertexAttribPointervARB == NULL && glad_glGetVertexAttribPointerv != NULL) glad_glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glad_glGetVertexAttribPointerv; + if (glad_glGetVertexAttribPointervARB == NULL && glad_glGetVertexAttribPointervNV != NULL) glad_glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glad_glGetVertexAttribPointervNV; + if (glad_glGetVertexAttribPointervNV == NULL && glad_glGetVertexAttribPointerv != NULL) glad_glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glad_glGetVertexAttribPointerv; + if (glad_glGetVertexAttribPointervNV == NULL && glad_glGetVertexAttribPointervARB != NULL) glad_glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glad_glGetVertexAttribPointervARB; + if (glad_glHistogram == NULL && glad_glHistogramEXT != NULL) glad_glHistogram = (PFNGLHISTOGRAMPROC)glad_glHistogramEXT; + if (glad_glHistogramEXT == NULL && glad_glHistogram != NULL) glad_glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glad_glHistogram; + if (glad_glIsBuffer == NULL && glad_glIsBufferARB != NULL) glad_glIsBuffer = (PFNGLISBUFFERPROC)glad_glIsBufferARB; + if (glad_glIsBufferARB == NULL && glad_glIsBuffer != NULL) glad_glIsBufferARB = (PFNGLISBUFFERARBPROC)glad_glIsBuffer; + if (glad_glIsEnabledi == NULL && glad_glIsEnabledIndexedEXT != NULL) glad_glIsEnabledi = (PFNGLISENABLEDIPROC)glad_glIsEnabledIndexedEXT; + if (glad_glIsEnabledi == NULL && glad_glIsEnablediEXT != NULL) glad_glIsEnabledi = (PFNGLISENABLEDIPROC)glad_glIsEnablediEXT; + if (glad_glIsEnabledi == NULL && glad_glIsEnablediNV != NULL) glad_glIsEnabledi = (PFNGLISENABLEDIPROC)glad_glIsEnablediNV; + if (glad_glIsEnabledi == NULL && glad_glIsEnablediOES != NULL) glad_glIsEnabledi = (PFNGLISENABLEDIPROC)glad_glIsEnablediOES; + if (glad_glIsEnablediEXT == NULL && glad_glIsEnabledIndexedEXT != NULL) glad_glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glad_glIsEnabledIndexedEXT; + if (glad_glIsEnablediEXT == NULL && glad_glIsEnabledi != NULL) glad_glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glad_glIsEnabledi; + if (glad_glIsEnablediEXT == NULL && glad_glIsEnablediNV != NULL) glad_glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glad_glIsEnablediNV; + if (glad_glIsEnablediEXT == NULL && glad_glIsEnablediOES != NULL) glad_glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glad_glIsEnablediOES; + if (glad_glIsEnabledIndexedEXT == NULL && glad_glIsEnabledi != NULL) glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glad_glIsEnabledi; + if (glad_glIsEnabledIndexedEXT == NULL && glad_glIsEnablediEXT != NULL) glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glad_glIsEnablediEXT; + if (glad_glIsEnabledIndexedEXT == NULL && glad_glIsEnablediNV != NULL) glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glad_glIsEnablediNV; + if (glad_glIsEnabledIndexedEXT == NULL && glad_glIsEnablediOES != NULL) glad_glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glad_glIsEnablediOES; + if (glad_glIsEnablediNV == NULL && glad_glIsEnabledIndexedEXT != NULL) glad_glIsEnablediNV = (PFNGLISENABLEDINVPROC)glad_glIsEnabledIndexedEXT; + if (glad_glIsEnablediNV == NULL && glad_glIsEnabledi != NULL) glad_glIsEnablediNV = (PFNGLISENABLEDINVPROC)glad_glIsEnabledi; + if (glad_glIsEnablediNV == NULL && glad_glIsEnablediEXT != NULL) glad_glIsEnablediNV = (PFNGLISENABLEDINVPROC)glad_glIsEnablediEXT; + if (glad_glIsEnablediNV == NULL && glad_glIsEnablediOES != NULL) glad_glIsEnablediNV = (PFNGLISENABLEDINVPROC)glad_glIsEnablediOES; + if (glad_glIsEnablediOES == NULL && glad_glIsEnabledIndexedEXT != NULL) glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC)glad_glIsEnabledIndexedEXT; + if (glad_glIsEnablediOES == NULL && glad_glIsEnabledi != NULL) glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC)glad_glIsEnabledi; + if (glad_glIsEnablediOES == NULL && glad_glIsEnablediEXT != NULL) glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC)glad_glIsEnablediEXT; + if (glad_glIsEnablediOES == NULL && glad_glIsEnablediNV != NULL) glad_glIsEnablediOES = (PFNGLISENABLEDIOESPROC)glad_glIsEnablediNV; + if (glad_glIsFramebuffer == NULL && glad_glIsFramebufferEXT != NULL) glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glad_glIsFramebufferEXT; + if (glad_glIsFramebufferEXT == NULL && glad_glIsFramebuffer != NULL) glad_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glad_glIsFramebuffer; + if (glad_glIsProgramARB == NULL && glad_glIsProgramNV != NULL) glad_glIsProgramARB = (PFNGLISPROGRAMARBPROC)glad_glIsProgramNV; + if (glad_glIsProgramNV == NULL && glad_glIsProgramARB != NULL) glad_glIsProgramNV = (PFNGLISPROGRAMNVPROC)glad_glIsProgramARB; + if (glad_glIsQuery == NULL && glad_glIsQueryARB != NULL) glad_glIsQuery = (PFNGLISQUERYPROC)glad_glIsQueryARB; + if (glad_glIsQueryARB == NULL && glad_glIsQuery != NULL) glad_glIsQueryARB = (PFNGLISQUERYARBPROC)glad_glIsQuery; + if (glad_glIsRenderbuffer == NULL && glad_glIsRenderbufferEXT != NULL) glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glad_glIsRenderbufferEXT; + if (glad_glIsRenderbufferEXT == NULL && glad_glIsRenderbuffer != NULL) glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glad_glIsRenderbuffer; + if (glad_glIsSync == NULL && glad_glIsSyncAPPLE != NULL) glad_glIsSync = (PFNGLISSYNCPROC)glad_glIsSyncAPPLE; + if (glad_glIsSyncAPPLE == NULL && glad_glIsSync != NULL) glad_glIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC)glad_glIsSync; + if (glad_glIsTransformFeedback == NULL && glad_glIsTransformFeedbackNV != NULL) glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)glad_glIsTransformFeedbackNV; + if (glad_glIsTransformFeedbackNV == NULL && glad_glIsTransformFeedback != NULL) glad_glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glad_glIsTransformFeedback; + if (glad_glIsVertexArray == NULL && glad_glIsVertexArrayAPPLE != NULL) glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glad_glIsVertexArrayAPPLE; + if (glad_glIsVertexArray == NULL && glad_glIsVertexArrayOES != NULL) glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glad_glIsVertexArrayOES; + if (glad_glIsVertexArrayAPPLE == NULL && glad_glIsVertexArray != NULL) glad_glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glad_glIsVertexArray; + if (glad_glIsVertexArrayAPPLE == NULL && glad_glIsVertexArrayOES != NULL) glad_glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glad_glIsVertexArrayOES; + if (glad_glIsVertexArrayOES == NULL && glad_glIsVertexArray != NULL) glad_glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)glad_glIsVertexArray; + if (glad_glIsVertexArrayOES == NULL && glad_glIsVertexArrayAPPLE != NULL) glad_glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)glad_glIsVertexArrayAPPLE; + if (glad_glLinkProgram == NULL && glad_glLinkProgramARB != NULL) glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)glad_glLinkProgramARB; + if (glad_glLinkProgramARB == NULL && glad_glLinkProgram != NULL) glad_glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glad_glLinkProgram; + if (glad_glLoadTransposeMatrixd == NULL && glad_glLoadTransposeMatrixdARB != NULL) glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glad_glLoadTransposeMatrixdARB; + if (glad_glLoadTransposeMatrixdARB == NULL && glad_glLoadTransposeMatrixd != NULL) glad_glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glad_glLoadTransposeMatrixd; + if (glad_glLoadTransposeMatrixf == NULL && glad_glLoadTransposeMatrixfARB != NULL) glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glad_glLoadTransposeMatrixfARB; + if (glad_glLoadTransposeMatrixfARB == NULL && glad_glLoadTransposeMatrixf != NULL) glad_glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glad_glLoadTransposeMatrixf; + if (glad_glMapBuffer == NULL && glad_glMapBufferARB != NULL) glad_glMapBuffer = (PFNGLMAPBUFFERPROC)glad_glMapBufferARB; + if (glad_glMapBuffer == NULL && glad_glMapBufferOES != NULL) glad_glMapBuffer = (PFNGLMAPBUFFERPROC)glad_glMapBufferOES; + if (glad_glMapBufferARB == NULL && glad_glMapBuffer != NULL) glad_glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glad_glMapBuffer; + if (glad_glMapBufferARB == NULL && glad_glMapBufferOES != NULL) glad_glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glad_glMapBufferOES; + if (glad_glMapBufferOES == NULL && glad_glMapBuffer != NULL) glad_glMapBufferOES = (PFNGLMAPBUFFEROESPROC)glad_glMapBuffer; + if (glad_glMapBufferOES == NULL && glad_glMapBufferARB != NULL) glad_glMapBufferOES = (PFNGLMAPBUFFEROESPROC)glad_glMapBufferARB; + if (glad_glMapBufferRange == NULL && glad_glMapBufferRangeEXT != NULL) glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glad_glMapBufferRangeEXT; + if (glad_glMapBufferRangeEXT == NULL && glad_glMapBufferRange != NULL) glad_glMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC)glad_glMapBufferRange; + if (glad_glMaxShaderCompilerThreadsARB == NULL && glad_glMaxShaderCompilerThreadsKHR != NULL) glad_glMaxShaderCompilerThreadsARB = (PFNGLMAXSHADERCOMPILERTHREADSARBPROC)glad_glMaxShaderCompilerThreadsKHR; + if (glad_glMaxShaderCompilerThreadsKHR == NULL && glad_glMaxShaderCompilerThreadsARB != NULL) glad_glMaxShaderCompilerThreadsKHR = (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)glad_glMaxShaderCompilerThreadsARB; + if (glad_glMemoryBarrier == NULL && glad_glMemoryBarrierEXT != NULL) glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)glad_glMemoryBarrierEXT; + if (glad_glMemoryBarrierEXT == NULL && glad_glMemoryBarrier != NULL) glad_glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC)glad_glMemoryBarrier; + if (glad_glMinmax == NULL && glad_glMinmaxEXT != NULL) glad_glMinmax = (PFNGLMINMAXPROC)glad_glMinmaxEXT; + if (glad_glMinmaxEXT == NULL && glad_glMinmax != NULL) glad_glMinmaxEXT = (PFNGLMINMAXEXTPROC)glad_glMinmax; + if (glad_glMinSampleShading == NULL && glad_glMinSampleShadingARB != NULL) glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glad_glMinSampleShadingARB; + if (glad_glMinSampleShading == NULL && glad_glMinSampleShadingOES != NULL) glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glad_glMinSampleShadingOES; + if (glad_glMinSampleShadingARB == NULL && glad_glMinSampleShading != NULL) glad_glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glad_glMinSampleShading; + if (glad_glMinSampleShadingARB == NULL && glad_glMinSampleShadingOES != NULL) glad_glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glad_glMinSampleShadingOES; + if (glad_glMinSampleShadingOES == NULL && glad_glMinSampleShading != NULL) glad_glMinSampleShadingOES = (PFNGLMINSAMPLESHADINGOESPROC)glad_glMinSampleShading; + if (glad_glMinSampleShadingOES == NULL && glad_glMinSampleShadingARB != NULL) glad_glMinSampleShadingOES = (PFNGLMINSAMPLESHADINGOESPROC)glad_glMinSampleShadingARB; + if (glad_glMultiDrawArrays == NULL && glad_glMultiDrawArraysEXT != NULL) glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glad_glMultiDrawArraysEXT; + if (glad_glMultiDrawArraysEXT == NULL && glad_glMultiDrawArrays != NULL) glad_glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glad_glMultiDrawArrays; + if (glad_glMultiDrawArraysIndirect == NULL && glad_glMultiDrawArraysIndirectAMD != NULL) glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glad_glMultiDrawArraysIndirectAMD; + if (glad_glMultiDrawArraysIndirect == NULL && glad_glMultiDrawArraysIndirectEXT != NULL) glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glad_glMultiDrawArraysIndirectEXT; + if (glad_glMultiDrawArraysIndirectAMD == NULL && glad_glMultiDrawArraysIndirect != NULL) glad_glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glad_glMultiDrawArraysIndirect; + if (glad_glMultiDrawArraysIndirectAMD == NULL && glad_glMultiDrawArraysIndirectEXT != NULL) glad_glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glad_glMultiDrawArraysIndirectEXT; + if (glad_glMultiDrawArraysIndirectCount == NULL && glad_glMultiDrawArraysIndirectCountARB != NULL) glad_glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)glad_glMultiDrawArraysIndirectCountARB; + if (glad_glMultiDrawArraysIndirectCountARB == NULL && glad_glMultiDrawArraysIndirectCount != NULL) glad_glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)glad_glMultiDrawArraysIndirectCount; + if (glad_glMultiDrawArraysIndirectEXT == NULL && glad_glMultiDrawArraysIndirect != NULL) glad_glMultiDrawArraysIndirectEXT = (PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC)glad_glMultiDrawArraysIndirect; + if (glad_glMultiDrawArraysIndirectEXT == NULL && glad_glMultiDrawArraysIndirectAMD != NULL) glad_glMultiDrawArraysIndirectEXT = (PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC)glad_glMultiDrawArraysIndirectAMD; + if (glad_glMultiDrawElements == NULL && glad_glMultiDrawElementsEXT != NULL) glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glad_glMultiDrawElementsEXT; + if (glad_glMultiDrawElementsBaseVertex == NULL && glad_glMultiDrawElementsBaseVertexEXT != NULL) glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glad_glMultiDrawElementsBaseVertexEXT; + if (glad_glMultiDrawElementsBaseVertexEXT == NULL && glad_glMultiDrawElementsBaseVertex != NULL) glad_glMultiDrawElementsBaseVertexEXT = (PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC)glad_glMultiDrawElementsBaseVertex; + if (glad_glMultiDrawElementsEXT == NULL && glad_glMultiDrawElements != NULL) glad_glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glad_glMultiDrawElements; + if (glad_glMultiDrawElementsIndirect == NULL && glad_glMultiDrawElementsIndirectAMD != NULL) glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glad_glMultiDrawElementsIndirectAMD; + if (glad_glMultiDrawElementsIndirect == NULL && glad_glMultiDrawElementsIndirectEXT != NULL) glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glad_glMultiDrawElementsIndirectEXT; + if (glad_glMultiDrawElementsIndirectAMD == NULL && glad_glMultiDrawElementsIndirect != NULL) glad_glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glad_glMultiDrawElementsIndirect; + if (glad_glMultiDrawElementsIndirectAMD == NULL && glad_glMultiDrawElementsIndirectEXT != NULL) glad_glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glad_glMultiDrawElementsIndirectEXT; + if (glad_glMultiDrawElementsIndirectCount == NULL && glad_glMultiDrawElementsIndirectCountARB != NULL) glad_glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)glad_glMultiDrawElementsIndirectCountARB; + if (glad_glMultiDrawElementsIndirectCountARB == NULL && glad_glMultiDrawElementsIndirectCount != NULL) glad_glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)glad_glMultiDrawElementsIndirectCount; + if (glad_glMultiDrawElementsIndirectEXT == NULL && glad_glMultiDrawElementsIndirect != NULL) glad_glMultiDrawElementsIndirectEXT = (PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC)glad_glMultiDrawElementsIndirect; + if (glad_glMultiDrawElementsIndirectEXT == NULL && glad_glMultiDrawElementsIndirectAMD != NULL) glad_glMultiDrawElementsIndirectEXT = (PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC)glad_glMultiDrawElementsIndirectAMD; + if (glad_glMultiTexCoord1d == NULL && glad_glMultiTexCoord1dARB != NULL) glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glad_glMultiTexCoord1dARB; + if (glad_glMultiTexCoord1dARB == NULL && glad_glMultiTexCoord1d != NULL) glad_glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glad_glMultiTexCoord1d; + if (glad_glMultiTexCoord1dv == NULL && glad_glMultiTexCoord1dvARB != NULL) glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glad_glMultiTexCoord1dvARB; + if (glad_glMultiTexCoord1dvARB == NULL && glad_glMultiTexCoord1dv != NULL) glad_glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glad_glMultiTexCoord1dv; + if (glad_glMultiTexCoord1f == NULL && glad_glMultiTexCoord1fARB != NULL) glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glad_glMultiTexCoord1fARB; + if (glad_glMultiTexCoord1fARB == NULL && glad_glMultiTexCoord1f != NULL) glad_glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glad_glMultiTexCoord1f; + if (glad_glMultiTexCoord1fv == NULL && glad_glMultiTexCoord1fvARB != NULL) glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glad_glMultiTexCoord1fvARB; + if (glad_glMultiTexCoord1fvARB == NULL && glad_glMultiTexCoord1fv != NULL) glad_glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glad_glMultiTexCoord1fv; + if (glad_glMultiTexCoord1i == NULL && glad_glMultiTexCoord1iARB != NULL) glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glad_glMultiTexCoord1iARB; + if (glad_glMultiTexCoord1iARB == NULL && glad_glMultiTexCoord1i != NULL) glad_glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glad_glMultiTexCoord1i; + if (glad_glMultiTexCoord1iv == NULL && glad_glMultiTexCoord1ivARB != NULL) glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glad_glMultiTexCoord1ivARB; + if (glad_glMultiTexCoord1ivARB == NULL && glad_glMultiTexCoord1iv != NULL) glad_glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glad_glMultiTexCoord1iv; + if (glad_glMultiTexCoord1s == NULL && glad_glMultiTexCoord1sARB != NULL) glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glad_glMultiTexCoord1sARB; + if (glad_glMultiTexCoord1sARB == NULL && glad_glMultiTexCoord1s != NULL) glad_glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glad_glMultiTexCoord1s; + if (glad_glMultiTexCoord1sv == NULL && glad_glMultiTexCoord1svARB != NULL) glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glad_glMultiTexCoord1svARB; + if (glad_glMultiTexCoord1svARB == NULL && glad_glMultiTexCoord1sv != NULL) glad_glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glad_glMultiTexCoord1sv; + if (glad_glMultiTexCoord2d == NULL && glad_glMultiTexCoord2dARB != NULL) glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glad_glMultiTexCoord2dARB; + if (glad_glMultiTexCoord2dARB == NULL && glad_glMultiTexCoord2d != NULL) glad_glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glad_glMultiTexCoord2d; + if (glad_glMultiTexCoord2dv == NULL && glad_glMultiTexCoord2dvARB != NULL) glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glad_glMultiTexCoord2dvARB; + if (glad_glMultiTexCoord2dvARB == NULL && glad_glMultiTexCoord2dv != NULL) glad_glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glad_glMultiTexCoord2dv; + if (glad_glMultiTexCoord2f == NULL && glad_glMultiTexCoord2fARB != NULL) glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glad_glMultiTexCoord2fARB; + if (glad_glMultiTexCoord2fARB == NULL && glad_glMultiTexCoord2f != NULL) glad_glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glad_glMultiTexCoord2f; + if (glad_glMultiTexCoord2fv == NULL && glad_glMultiTexCoord2fvARB != NULL) glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glad_glMultiTexCoord2fvARB; + if (glad_glMultiTexCoord2fvARB == NULL && glad_glMultiTexCoord2fv != NULL) glad_glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glad_glMultiTexCoord2fv; + if (glad_glMultiTexCoord2i == NULL && glad_glMultiTexCoord2iARB != NULL) glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glad_glMultiTexCoord2iARB; + if (glad_glMultiTexCoord2iARB == NULL && glad_glMultiTexCoord2i != NULL) glad_glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glad_glMultiTexCoord2i; + if (glad_glMultiTexCoord2iv == NULL && glad_glMultiTexCoord2ivARB != NULL) glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glad_glMultiTexCoord2ivARB; + if (glad_glMultiTexCoord2ivARB == NULL && glad_glMultiTexCoord2iv != NULL) glad_glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glad_glMultiTexCoord2iv; + if (glad_glMultiTexCoord2s == NULL && glad_glMultiTexCoord2sARB != NULL) glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glad_glMultiTexCoord2sARB; + if (glad_glMultiTexCoord2sARB == NULL && glad_glMultiTexCoord2s != NULL) glad_glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glad_glMultiTexCoord2s; + if (glad_glMultiTexCoord2sv == NULL && glad_glMultiTexCoord2svARB != NULL) glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glad_glMultiTexCoord2svARB; + if (glad_glMultiTexCoord2svARB == NULL && glad_glMultiTexCoord2sv != NULL) glad_glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glad_glMultiTexCoord2sv; + if (glad_glMultiTexCoord3d == NULL && glad_glMultiTexCoord3dARB != NULL) glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glad_glMultiTexCoord3dARB; + if (glad_glMultiTexCoord3dARB == NULL && glad_glMultiTexCoord3d != NULL) glad_glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glad_glMultiTexCoord3d; + if (glad_glMultiTexCoord3dv == NULL && glad_glMultiTexCoord3dvARB != NULL) glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glad_glMultiTexCoord3dvARB; + if (glad_glMultiTexCoord3dvARB == NULL && glad_glMultiTexCoord3dv != NULL) glad_glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glad_glMultiTexCoord3dv; + if (glad_glMultiTexCoord3f == NULL && glad_glMultiTexCoord3fARB != NULL) glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glad_glMultiTexCoord3fARB; + if (glad_glMultiTexCoord3fARB == NULL && glad_glMultiTexCoord3f != NULL) glad_glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glad_glMultiTexCoord3f; + if (glad_glMultiTexCoord3fv == NULL && glad_glMultiTexCoord3fvARB != NULL) glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glad_glMultiTexCoord3fvARB; + if (glad_glMultiTexCoord3fvARB == NULL && glad_glMultiTexCoord3fv != NULL) glad_glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glad_glMultiTexCoord3fv; + if (glad_glMultiTexCoord3i == NULL && glad_glMultiTexCoord3iARB != NULL) glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glad_glMultiTexCoord3iARB; + if (glad_glMultiTexCoord3iARB == NULL && glad_glMultiTexCoord3i != NULL) glad_glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glad_glMultiTexCoord3i; + if (glad_glMultiTexCoord3iv == NULL && glad_glMultiTexCoord3ivARB != NULL) glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glad_glMultiTexCoord3ivARB; + if (glad_glMultiTexCoord3ivARB == NULL && glad_glMultiTexCoord3iv != NULL) glad_glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glad_glMultiTexCoord3iv; + if (glad_glMultiTexCoord3s == NULL && glad_glMultiTexCoord3sARB != NULL) glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glad_glMultiTexCoord3sARB; + if (glad_glMultiTexCoord3sARB == NULL && glad_glMultiTexCoord3s != NULL) glad_glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glad_glMultiTexCoord3s; + if (glad_glMultiTexCoord3sv == NULL && glad_glMultiTexCoord3svARB != NULL) glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glad_glMultiTexCoord3svARB; + if (glad_glMultiTexCoord3svARB == NULL && glad_glMultiTexCoord3sv != NULL) glad_glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glad_glMultiTexCoord3sv; + if (glad_glMultiTexCoord4d == NULL && glad_glMultiTexCoord4dARB != NULL) glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glad_glMultiTexCoord4dARB; + if (glad_glMultiTexCoord4dARB == NULL && glad_glMultiTexCoord4d != NULL) glad_glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glad_glMultiTexCoord4d; + if (glad_glMultiTexCoord4dv == NULL && glad_glMultiTexCoord4dvARB != NULL) glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glad_glMultiTexCoord4dvARB; + if (glad_glMultiTexCoord4dvARB == NULL && glad_glMultiTexCoord4dv != NULL) glad_glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glad_glMultiTexCoord4dv; + if (glad_glMultiTexCoord4f == NULL && glad_glMultiTexCoord4fARB != NULL) glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glad_glMultiTexCoord4fARB; + if (glad_glMultiTexCoord4fARB == NULL && glad_glMultiTexCoord4f != NULL) glad_glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glad_glMultiTexCoord4f; + if (glad_glMultiTexCoord4fv == NULL && glad_glMultiTexCoord4fvARB != NULL) glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glad_glMultiTexCoord4fvARB; + if (glad_glMultiTexCoord4fvARB == NULL && glad_glMultiTexCoord4fv != NULL) glad_glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glad_glMultiTexCoord4fv; + if (glad_glMultiTexCoord4i == NULL && glad_glMultiTexCoord4iARB != NULL) glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glad_glMultiTexCoord4iARB; + if (glad_glMultiTexCoord4iARB == NULL && glad_glMultiTexCoord4i != NULL) glad_glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glad_glMultiTexCoord4i; + if (glad_glMultiTexCoord4iv == NULL && glad_glMultiTexCoord4ivARB != NULL) glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glad_glMultiTexCoord4ivARB; + if (glad_glMultiTexCoord4ivARB == NULL && glad_glMultiTexCoord4iv != NULL) glad_glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glad_glMultiTexCoord4iv; + if (glad_glMultiTexCoord4s == NULL && glad_glMultiTexCoord4sARB != NULL) glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glad_glMultiTexCoord4sARB; + if (glad_glMultiTexCoord4sARB == NULL && glad_glMultiTexCoord4s != NULL) glad_glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glad_glMultiTexCoord4s; + if (glad_glMultiTexCoord4sv == NULL && glad_glMultiTexCoord4svARB != NULL) glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glad_glMultiTexCoord4svARB; + if (glad_glMultiTexCoord4svARB == NULL && glad_glMultiTexCoord4sv != NULL) glad_glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glad_glMultiTexCoord4sv; + if (glad_glMultTransposeMatrixd == NULL && glad_glMultTransposeMatrixdARB != NULL) glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glad_glMultTransposeMatrixdARB; + if (glad_glMultTransposeMatrixdARB == NULL && glad_glMultTransposeMatrixd != NULL) glad_glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glad_glMultTransposeMatrixd; + if (glad_glMultTransposeMatrixf == NULL && glad_glMultTransposeMatrixfARB != NULL) glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glad_glMultTransposeMatrixfARB; + if (glad_glMultTransposeMatrixfARB == NULL && glad_glMultTransposeMatrixf != NULL) glad_glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glad_glMultTransposeMatrixf; + if (glad_glNamedBufferStorage == NULL && glad_glNamedBufferStorageEXT != NULL) glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)glad_glNamedBufferStorageEXT; + if (glad_glNamedBufferStorageEXT == NULL && glad_glNamedBufferStorage != NULL) glad_glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC)glad_glNamedBufferStorage; + if (glad_glNamedBufferSubData == NULL && glad_glNamedBufferSubDataEXT != NULL) glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)glad_glNamedBufferSubDataEXT; + if (glad_glNamedBufferSubDataEXT == NULL && glad_glNamedBufferSubData != NULL) glad_glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glad_glNamedBufferSubData; + if (glad_glObjectLabel == NULL && glad_glObjectLabelKHR != NULL) glad_glObjectLabel = (PFNGLOBJECTLABELPROC)glad_glObjectLabelKHR; + if (glad_glObjectLabelKHR == NULL && glad_glObjectLabel != NULL) glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC)glad_glObjectLabel; + if (glad_glObjectPtrLabel == NULL && glad_glObjectPtrLabelKHR != NULL) glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)glad_glObjectPtrLabelKHR; + if (glad_glObjectPtrLabelKHR == NULL && glad_glObjectPtrLabel != NULL) glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC)glad_glObjectPtrLabel; + if (glad_glPatchParameteri == NULL && glad_glPatchParameteriEXT != NULL) glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glad_glPatchParameteriEXT; + if (glad_glPatchParameteri == NULL && glad_glPatchParameteriOES != NULL) glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glad_glPatchParameteriOES; + if (glad_glPatchParameteriEXT == NULL && glad_glPatchParameteri != NULL) glad_glPatchParameteriEXT = (PFNGLPATCHPARAMETERIEXTPROC)glad_glPatchParameteri; + if (glad_glPatchParameteriEXT == NULL && glad_glPatchParameteriOES != NULL) glad_glPatchParameteriEXT = (PFNGLPATCHPARAMETERIEXTPROC)glad_glPatchParameteriOES; + if (glad_glPatchParameteriOES == NULL && glad_glPatchParameteri != NULL) glad_glPatchParameteriOES = (PFNGLPATCHPARAMETERIOESPROC)glad_glPatchParameteri; + if (glad_glPatchParameteriOES == NULL && glad_glPatchParameteriEXT != NULL) glad_glPatchParameteriOES = (PFNGLPATCHPARAMETERIOESPROC)glad_glPatchParameteriEXT; + if (glad_glPauseTransformFeedback == NULL && glad_glPauseTransformFeedbackNV != NULL) glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)glad_glPauseTransformFeedbackNV; + if (glad_glPauseTransformFeedbackNV == NULL && glad_glPauseTransformFeedback != NULL) glad_glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glad_glPauseTransformFeedback; + if (glad_glPointParameterf == NULL && glad_glPointParameterfARB != NULL) glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glad_glPointParameterfARB; + if (glad_glPointParameterf == NULL && glad_glPointParameterfEXT != NULL) glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glad_glPointParameterfEXT; + if (glad_glPointParameterf == NULL && glad_glPointParameterfSGIS != NULL) glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glad_glPointParameterfSGIS; + if (glad_glPointParameterfARB == NULL && glad_glPointParameterf != NULL) glad_glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glad_glPointParameterf; + if (glad_glPointParameterfARB == NULL && glad_glPointParameterfEXT != NULL) glad_glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glad_glPointParameterfEXT; + if (glad_glPointParameterfARB == NULL && glad_glPointParameterfSGIS != NULL) glad_glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glad_glPointParameterfSGIS; + if (glad_glPointParameterfEXT == NULL && glad_glPointParameterf != NULL) glad_glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glad_glPointParameterf; + if (glad_glPointParameterfEXT == NULL && glad_glPointParameterfARB != NULL) glad_glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glad_glPointParameterfARB; + if (glad_glPointParameterfEXT == NULL && glad_glPointParameterfSGIS != NULL) glad_glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glad_glPointParameterfSGIS; + if (glad_glPointParameterfSGIS == NULL && glad_glPointParameterf != NULL) glad_glPointParameterfSGIS = (PFNGLPOINTPARAMETERFSGISPROC)glad_glPointParameterf; + if (glad_glPointParameterfSGIS == NULL && glad_glPointParameterfARB != NULL) glad_glPointParameterfSGIS = (PFNGLPOINTPARAMETERFSGISPROC)glad_glPointParameterfARB; + if (glad_glPointParameterfSGIS == NULL && glad_glPointParameterfEXT != NULL) glad_glPointParameterfSGIS = (PFNGLPOINTPARAMETERFSGISPROC)glad_glPointParameterfEXT; + if (glad_glPointParameterfv == NULL && glad_glPointParameterfvARB != NULL) glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glad_glPointParameterfvARB; + if (glad_glPointParameterfv == NULL && glad_glPointParameterfvEXT != NULL) glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glad_glPointParameterfvEXT; + if (glad_glPointParameterfv == NULL && glad_glPointParameterfvSGIS != NULL) glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glad_glPointParameterfvSGIS; + if (glad_glPointParameterfvARB == NULL && glad_glPointParameterfv != NULL) glad_glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glad_glPointParameterfv; + if (glad_glPointParameterfvARB == NULL && glad_glPointParameterfvEXT != NULL) glad_glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glad_glPointParameterfvEXT; + if (glad_glPointParameterfvARB == NULL && glad_glPointParameterfvSGIS != NULL) glad_glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glad_glPointParameterfvSGIS; + if (glad_glPointParameterfvEXT == NULL && glad_glPointParameterfv != NULL) glad_glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glad_glPointParameterfv; + if (glad_glPointParameterfvEXT == NULL && glad_glPointParameterfvARB != NULL) glad_glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glad_glPointParameterfvARB; + if (glad_glPointParameterfvEXT == NULL && glad_glPointParameterfvSGIS != NULL) glad_glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glad_glPointParameterfvSGIS; + if (glad_glPointParameterfvSGIS == NULL && glad_glPointParameterfv != NULL) glad_glPointParameterfvSGIS = (PFNGLPOINTPARAMETERFVSGISPROC)glad_glPointParameterfv; + if (glad_glPointParameterfvSGIS == NULL && glad_glPointParameterfvARB != NULL) glad_glPointParameterfvSGIS = (PFNGLPOINTPARAMETERFVSGISPROC)glad_glPointParameterfvARB; + if (glad_glPointParameterfvSGIS == NULL && glad_glPointParameterfvEXT != NULL) glad_glPointParameterfvSGIS = (PFNGLPOINTPARAMETERFVSGISPROC)glad_glPointParameterfvEXT; + if (glad_glPointParameteri == NULL && glad_glPointParameteriNV != NULL) glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glad_glPointParameteriNV; + if (glad_glPointParameteriNV == NULL && glad_glPointParameteri != NULL) glad_glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glad_glPointParameteri; + if (glad_glPointParameteriv == NULL && glad_glPointParameterivNV != NULL) glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glad_glPointParameterivNV; + if (glad_glPointParameterivNV == NULL && glad_glPointParameteriv != NULL) glad_glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glad_glPointParameteriv; + if (glad_glPolygonMode == NULL && glad_glPolygonModeNV != NULL) glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)glad_glPolygonModeNV; + if (glad_glPolygonModeNV == NULL && glad_glPolygonMode != NULL) glad_glPolygonModeNV = (PFNGLPOLYGONMODENVPROC)glad_glPolygonMode; + if (glad_glPolygonOffsetClamp == NULL && glad_glPolygonOffsetClampEXT != NULL) glad_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)glad_glPolygonOffsetClampEXT; + if (glad_glPolygonOffsetClampEXT == NULL && glad_glPolygonOffsetClamp != NULL) glad_glPolygonOffsetClampEXT = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)glad_glPolygonOffsetClamp; + if (glad_glPopDebugGroup == NULL && glad_glPopDebugGroupKHR != NULL) glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)glad_glPopDebugGroupKHR; + if (glad_glPopDebugGroupKHR == NULL && glad_glPopDebugGroup != NULL) glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC)glad_glPopDebugGroup; + if (glad_glPrimitiveBoundingBox == NULL && glad_glPrimitiveBoundingBoxARB != NULL) glad_glPrimitiveBoundingBox = (PFNGLPRIMITIVEBOUNDINGBOXPROC)glad_glPrimitiveBoundingBoxARB; + if (glad_glPrimitiveBoundingBox == NULL && glad_glPrimitiveBoundingBoxEXT != NULL) glad_glPrimitiveBoundingBox = (PFNGLPRIMITIVEBOUNDINGBOXPROC)glad_glPrimitiveBoundingBoxEXT; + if (glad_glPrimitiveBoundingBox == NULL && glad_glPrimitiveBoundingBoxOES != NULL) glad_glPrimitiveBoundingBox = (PFNGLPRIMITIVEBOUNDINGBOXPROC)glad_glPrimitiveBoundingBoxOES; + if (glad_glPrimitiveBoundingBoxARB == NULL && glad_glPrimitiveBoundingBox != NULL) glad_glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC)glad_glPrimitiveBoundingBox; + if (glad_glPrimitiveBoundingBoxARB == NULL && glad_glPrimitiveBoundingBoxEXT != NULL) glad_glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC)glad_glPrimitiveBoundingBoxEXT; + if (glad_glPrimitiveBoundingBoxARB == NULL && glad_glPrimitiveBoundingBoxOES != NULL) glad_glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC)glad_glPrimitiveBoundingBoxOES; + if (glad_glPrimitiveBoundingBoxEXT == NULL && glad_glPrimitiveBoundingBox != NULL) glad_glPrimitiveBoundingBoxEXT = (PFNGLPRIMITIVEBOUNDINGBOXEXTPROC)glad_glPrimitiveBoundingBox; + if (glad_glPrimitiveBoundingBoxEXT == NULL && glad_glPrimitiveBoundingBoxARB != NULL) glad_glPrimitiveBoundingBoxEXT = (PFNGLPRIMITIVEBOUNDINGBOXEXTPROC)glad_glPrimitiveBoundingBoxARB; + if (glad_glPrimitiveBoundingBoxEXT == NULL && glad_glPrimitiveBoundingBoxOES != NULL) glad_glPrimitiveBoundingBoxEXT = (PFNGLPRIMITIVEBOUNDINGBOXEXTPROC)glad_glPrimitiveBoundingBoxOES; + if (glad_glPrimitiveBoundingBoxOES == NULL && glad_glPrimitiveBoundingBox != NULL) glad_glPrimitiveBoundingBoxOES = (PFNGLPRIMITIVEBOUNDINGBOXOESPROC)glad_glPrimitiveBoundingBox; + if (glad_glPrimitiveBoundingBoxOES == NULL && glad_glPrimitiveBoundingBoxARB != NULL) glad_glPrimitiveBoundingBoxOES = (PFNGLPRIMITIVEBOUNDINGBOXOESPROC)glad_glPrimitiveBoundingBoxARB; + if (glad_glPrimitiveBoundingBoxOES == NULL && glad_glPrimitiveBoundingBoxEXT != NULL) glad_glPrimitiveBoundingBoxOES = (PFNGLPRIMITIVEBOUNDINGBOXOESPROC)glad_glPrimitiveBoundingBoxEXT; + if (glad_glPrioritizeTextures == NULL && glad_glPrioritizeTexturesEXT != NULL) glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)glad_glPrioritizeTexturesEXT; + if (glad_glPrioritizeTexturesEXT == NULL && glad_glPrioritizeTextures != NULL) glad_glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glad_glPrioritizeTextures; + if (glad_glProgramBinary == NULL && glad_glProgramBinaryOES != NULL) glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC)glad_glProgramBinaryOES; + if (glad_glProgramBinaryOES == NULL && glad_glProgramBinary != NULL) glad_glProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC)glad_glProgramBinary; + if (glad_glProgramParameteri == NULL && glad_glProgramParameteriARB != NULL) glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glad_glProgramParameteriARB; + if (glad_glProgramParameteri == NULL && glad_glProgramParameteriEXT != NULL) glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glad_glProgramParameteriEXT; + if (glad_glProgramParameteriARB == NULL && glad_glProgramParameteri != NULL) glad_glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glad_glProgramParameteri; + if (glad_glProgramParameteriARB == NULL && glad_glProgramParameteriEXT != NULL) glad_glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glad_glProgramParameteriEXT; + if (glad_glProgramParameteriEXT == NULL && glad_glProgramParameteri != NULL) glad_glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glad_glProgramParameteri; + if (glad_glProgramParameteriEXT == NULL && glad_glProgramParameteriARB != NULL) glad_glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glad_glProgramParameteriARB; + if (glad_glProgramUniform1f == NULL && glad_glProgramUniform1fEXT != NULL) glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)glad_glProgramUniform1fEXT; + if (glad_glProgramUniform1fEXT == NULL && glad_glProgramUniform1f != NULL) glad_glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glad_glProgramUniform1f; + if (glad_glProgramUniform1fv == NULL && glad_glProgramUniform1fvEXT != NULL) glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)glad_glProgramUniform1fvEXT; + if (glad_glProgramUniform1fvEXT == NULL && glad_glProgramUniform1fv != NULL) glad_glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glad_glProgramUniform1fv; + if (glad_glProgramUniform1i == NULL && glad_glProgramUniform1iEXT != NULL) glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)glad_glProgramUniform1iEXT; + if (glad_glProgramUniform1iEXT == NULL && glad_glProgramUniform1i != NULL) glad_glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glad_glProgramUniform1i; + if (glad_glProgramUniform1iv == NULL && glad_glProgramUniform1ivEXT != NULL) glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)glad_glProgramUniform1ivEXT; + if (glad_glProgramUniform1ivEXT == NULL && glad_glProgramUniform1iv != NULL) glad_glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glad_glProgramUniform1iv; + if (glad_glProgramUniform1ui == NULL && glad_glProgramUniform1uiEXT != NULL) glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)glad_glProgramUniform1uiEXT; + if (glad_glProgramUniform1uiEXT == NULL && glad_glProgramUniform1ui != NULL) glad_glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glad_glProgramUniform1ui; + if (glad_glProgramUniform1uiv == NULL && glad_glProgramUniform1uivEXT != NULL) glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)glad_glProgramUniform1uivEXT; + if (glad_glProgramUniform1uivEXT == NULL && glad_glProgramUniform1uiv != NULL) glad_glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glad_glProgramUniform1uiv; + if (glad_glProgramUniform2f == NULL && glad_glProgramUniform2fEXT != NULL) glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)glad_glProgramUniform2fEXT; + if (glad_glProgramUniform2fEXT == NULL && glad_glProgramUniform2f != NULL) glad_glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glad_glProgramUniform2f; + if (glad_glProgramUniform2fv == NULL && glad_glProgramUniform2fvEXT != NULL) glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)glad_glProgramUniform2fvEXT; + if (glad_glProgramUniform2fvEXT == NULL && glad_glProgramUniform2fv != NULL) glad_glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glad_glProgramUniform2fv; + if (glad_glProgramUniform2i == NULL && glad_glProgramUniform2iEXT != NULL) glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)glad_glProgramUniform2iEXT; + if (glad_glProgramUniform2iEXT == NULL && glad_glProgramUniform2i != NULL) glad_glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glad_glProgramUniform2i; + if (glad_glProgramUniform2iv == NULL && glad_glProgramUniform2ivEXT != NULL) glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)glad_glProgramUniform2ivEXT; + if (glad_glProgramUniform2ivEXT == NULL && glad_glProgramUniform2iv != NULL) glad_glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glad_glProgramUniform2iv; + if (glad_glProgramUniform2ui == NULL && glad_glProgramUniform2uiEXT != NULL) glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)glad_glProgramUniform2uiEXT; + if (glad_glProgramUniform2uiEXT == NULL && glad_glProgramUniform2ui != NULL) glad_glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glad_glProgramUniform2ui; + if (glad_glProgramUniform2uiv == NULL && glad_glProgramUniform2uivEXT != NULL) glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)glad_glProgramUniform2uivEXT; + if (glad_glProgramUniform2uivEXT == NULL && glad_glProgramUniform2uiv != NULL) glad_glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glad_glProgramUniform2uiv; + if (glad_glProgramUniform3f == NULL && glad_glProgramUniform3fEXT != NULL) glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)glad_glProgramUniform3fEXT; + if (glad_glProgramUniform3fEXT == NULL && glad_glProgramUniform3f != NULL) glad_glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glad_glProgramUniform3f; + if (glad_glProgramUniform3fv == NULL && glad_glProgramUniform3fvEXT != NULL) glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)glad_glProgramUniform3fvEXT; + if (glad_glProgramUniform3fvEXT == NULL && glad_glProgramUniform3fv != NULL) glad_glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glad_glProgramUniform3fv; + if (glad_glProgramUniform3i == NULL && glad_glProgramUniform3iEXT != NULL) glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)glad_glProgramUniform3iEXT; + if (glad_glProgramUniform3iEXT == NULL && glad_glProgramUniform3i != NULL) glad_glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glad_glProgramUniform3i; + if (glad_glProgramUniform3iv == NULL && glad_glProgramUniform3ivEXT != NULL) glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)glad_glProgramUniform3ivEXT; + if (glad_glProgramUniform3ivEXT == NULL && glad_glProgramUniform3iv != NULL) glad_glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glad_glProgramUniform3iv; + if (glad_glProgramUniform3ui == NULL && glad_glProgramUniform3uiEXT != NULL) glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)glad_glProgramUniform3uiEXT; + if (glad_glProgramUniform3uiEXT == NULL && glad_glProgramUniform3ui != NULL) glad_glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glad_glProgramUniform3ui; + if (glad_glProgramUniform3uiv == NULL && glad_glProgramUniform3uivEXT != NULL) glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)glad_glProgramUniform3uivEXT; + if (glad_glProgramUniform3uivEXT == NULL && glad_glProgramUniform3uiv != NULL) glad_glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glad_glProgramUniform3uiv; + if (glad_glProgramUniform4f == NULL && glad_glProgramUniform4fEXT != NULL) glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)glad_glProgramUniform4fEXT; + if (glad_glProgramUniform4fEXT == NULL && glad_glProgramUniform4f != NULL) glad_glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glad_glProgramUniform4f; + if (glad_glProgramUniform4fv == NULL && glad_glProgramUniform4fvEXT != NULL) glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)glad_glProgramUniform4fvEXT; + if (glad_glProgramUniform4fvEXT == NULL && glad_glProgramUniform4fv != NULL) glad_glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glad_glProgramUniform4fv; + if (glad_glProgramUniform4i == NULL && glad_glProgramUniform4iEXT != NULL) glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)glad_glProgramUniform4iEXT; + if (glad_glProgramUniform4iEXT == NULL && glad_glProgramUniform4i != NULL) glad_glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glad_glProgramUniform4i; + if (glad_glProgramUniform4iv == NULL && glad_glProgramUniform4ivEXT != NULL) glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)glad_glProgramUniform4ivEXT; + if (glad_glProgramUniform4ivEXT == NULL && glad_glProgramUniform4iv != NULL) glad_glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glad_glProgramUniform4iv; + if (glad_glProgramUniform4ui == NULL && glad_glProgramUniform4uiEXT != NULL) glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)glad_glProgramUniform4uiEXT; + if (glad_glProgramUniform4uiEXT == NULL && glad_glProgramUniform4ui != NULL) glad_glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glad_glProgramUniform4ui; + if (glad_glProgramUniform4uiv == NULL && glad_glProgramUniform4uivEXT != NULL) glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)glad_glProgramUniform4uivEXT; + if (glad_glProgramUniform4uivEXT == NULL && glad_glProgramUniform4uiv != NULL) glad_glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glad_glProgramUniform4uiv; + if (glad_glProgramUniformHandleui64ARB == NULL && glad_glProgramUniformHandleui64IMG != NULL) glad_glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)glad_glProgramUniformHandleui64IMG; + if (glad_glProgramUniformHandleui64IMG == NULL && glad_glProgramUniformHandleui64ARB != NULL) glad_glProgramUniformHandleui64IMG = (PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC)glad_glProgramUniformHandleui64ARB; + if (glad_glProgramUniformHandleui64vARB == NULL && glad_glProgramUniformHandleui64vIMG != NULL) glad_glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)glad_glProgramUniformHandleui64vIMG; + if (glad_glProgramUniformHandleui64vIMG == NULL && glad_glProgramUniformHandleui64vARB != NULL) glad_glProgramUniformHandleui64vIMG = (PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC)glad_glProgramUniformHandleui64vARB; + if (glad_glProgramUniformMatrix2fv == NULL && glad_glProgramUniformMatrix2fvEXT != NULL) glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)glad_glProgramUniformMatrix2fvEXT; + if (glad_glProgramUniformMatrix2fvEXT == NULL && glad_glProgramUniformMatrix2fv != NULL) glad_glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glad_glProgramUniformMatrix2fv; + if (glad_glProgramUniformMatrix2x3fv == NULL && glad_glProgramUniformMatrix2x3fvEXT != NULL) glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)glad_glProgramUniformMatrix2x3fvEXT; + if (glad_glProgramUniformMatrix2x3fvEXT == NULL && glad_glProgramUniformMatrix2x3fv != NULL) glad_glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glad_glProgramUniformMatrix2x3fv; + if (glad_glProgramUniformMatrix2x4fv == NULL && glad_glProgramUniformMatrix2x4fvEXT != NULL) glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)glad_glProgramUniformMatrix2x4fvEXT; + if (glad_glProgramUniformMatrix2x4fvEXT == NULL && glad_glProgramUniformMatrix2x4fv != NULL) glad_glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glad_glProgramUniformMatrix2x4fv; + if (glad_glProgramUniformMatrix3fv == NULL && glad_glProgramUniformMatrix3fvEXT != NULL) glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)glad_glProgramUniformMatrix3fvEXT; + if (glad_glProgramUniformMatrix3fvEXT == NULL && glad_glProgramUniformMatrix3fv != NULL) glad_glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glad_glProgramUniformMatrix3fv; + if (glad_glProgramUniformMatrix3x2fv == NULL && glad_glProgramUniformMatrix3x2fvEXT != NULL) glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)glad_glProgramUniformMatrix3x2fvEXT; + if (glad_glProgramUniformMatrix3x2fvEXT == NULL && glad_glProgramUniformMatrix3x2fv != NULL) glad_glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glad_glProgramUniformMatrix3x2fv; + if (glad_glProgramUniformMatrix3x4fv == NULL && glad_glProgramUniformMatrix3x4fvEXT != NULL) glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)glad_glProgramUniformMatrix3x4fvEXT; + if (glad_glProgramUniformMatrix3x4fvEXT == NULL && glad_glProgramUniformMatrix3x4fv != NULL) glad_glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glad_glProgramUniformMatrix3x4fv; + if (glad_glProgramUniformMatrix4fv == NULL && glad_glProgramUniformMatrix4fvEXT != NULL) glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)glad_glProgramUniformMatrix4fvEXT; + if (glad_glProgramUniformMatrix4fvEXT == NULL && glad_glProgramUniformMatrix4fv != NULL) glad_glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glad_glProgramUniformMatrix4fv; + if (glad_glProgramUniformMatrix4x2fv == NULL && glad_glProgramUniformMatrix4x2fvEXT != NULL) glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)glad_glProgramUniformMatrix4x2fvEXT; + if (glad_glProgramUniformMatrix4x2fvEXT == NULL && glad_glProgramUniformMatrix4x2fv != NULL) glad_glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glad_glProgramUniformMatrix4x2fv; + if (glad_glProgramUniformMatrix4x3fv == NULL && glad_glProgramUniformMatrix4x3fvEXT != NULL) glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)glad_glProgramUniformMatrix4x3fvEXT; + if (glad_glProgramUniformMatrix4x3fvEXT == NULL && glad_glProgramUniformMatrix4x3fv != NULL) glad_glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glad_glProgramUniformMatrix4x3fv; + if (glad_glProvokingVertex == NULL && glad_glProvokingVertexEXT != NULL) glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glad_glProvokingVertexEXT; + if (glad_glProvokingVertexEXT == NULL && glad_glProvokingVertex != NULL) glad_glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glad_glProvokingVertex; + if (glad_glPushDebugGroup == NULL && glad_glPushDebugGroupKHR != NULL) glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)glad_glPushDebugGroupKHR; + if (glad_glPushDebugGroupKHR == NULL && glad_glPushDebugGroup != NULL) glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC)glad_glPushDebugGroup; + if (glad_glQueryCounter == NULL && glad_glQueryCounterEXT != NULL) glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC)glad_glQueryCounterEXT; + if (glad_glQueryCounterEXT == NULL && glad_glQueryCounter != NULL) glad_glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC)glad_glQueryCounter; + if (glad_glReadnPixels == NULL && glad_glReadnPixelsARB != NULL) glad_glReadnPixels = (PFNGLREADNPIXELSPROC)glad_glReadnPixelsARB; + if (glad_glReadnPixels == NULL && glad_glReadnPixelsEXT != NULL) glad_glReadnPixels = (PFNGLREADNPIXELSPROC)glad_glReadnPixelsEXT; + if (glad_glReadnPixels == NULL && glad_glReadnPixelsKHR != NULL) glad_glReadnPixels = (PFNGLREADNPIXELSPROC)glad_glReadnPixelsKHR; + if (glad_glReadnPixelsARB == NULL && glad_glReadnPixels != NULL) glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glad_glReadnPixels; + if (glad_glReadnPixelsARB == NULL && glad_glReadnPixelsEXT != NULL) glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glad_glReadnPixelsEXT; + if (glad_glReadnPixelsARB == NULL && glad_glReadnPixelsKHR != NULL) glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glad_glReadnPixelsKHR; + if (glad_glReadnPixelsEXT == NULL && glad_glReadnPixels != NULL) glad_glReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC)glad_glReadnPixels; + if (glad_glReadnPixelsEXT == NULL && glad_glReadnPixelsARB != NULL) glad_glReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC)glad_glReadnPixelsARB; + if (glad_glReadnPixelsEXT == NULL && glad_glReadnPixelsKHR != NULL) glad_glReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC)glad_glReadnPixelsKHR; + if (glad_glReadnPixelsKHR == NULL && glad_glReadnPixels != NULL) glad_glReadnPixelsKHR = (PFNGLREADNPIXELSKHRPROC)glad_glReadnPixels; + if (glad_glReadnPixelsKHR == NULL && glad_glReadnPixelsARB != NULL) glad_glReadnPixelsKHR = (PFNGLREADNPIXELSKHRPROC)glad_glReadnPixelsARB; + if (glad_glReadnPixelsKHR == NULL && glad_glReadnPixelsEXT != NULL) glad_glReadnPixelsKHR = (PFNGLREADNPIXELSKHRPROC)glad_glReadnPixelsEXT; + if (glad_glRenderbufferStorage == NULL && glad_glRenderbufferStorageEXT != NULL) glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glad_glRenderbufferStorageEXT; + if (glad_glRenderbufferStorageEXT == NULL && glad_glRenderbufferStorage != NULL) glad_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glad_glRenderbufferStorage; + if (glad_glRenderbufferStorageMultisample == NULL && glad_glRenderbufferStorageMultisampleEXT != NULL) glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glad_glRenderbufferStorageMultisampleEXT; + if (glad_glRenderbufferStorageMultisample == NULL && glad_glRenderbufferStorageMultisampleNV != NULL) glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glad_glRenderbufferStorageMultisampleNV; + if (glad_glRenderbufferStorageMultisampleEXT == NULL && glad_glRenderbufferStorageMultisample != NULL) glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glad_glRenderbufferStorageMultisample; + if (glad_glRenderbufferStorageMultisampleEXT == NULL && glad_glRenderbufferStorageMultisampleNV != NULL) glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glad_glRenderbufferStorageMultisampleNV; + if (glad_glRenderbufferStorageMultisampleNV == NULL && glad_glRenderbufferStorageMultisample != NULL) glad_glRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC)glad_glRenderbufferStorageMultisample; + if (glad_glRenderbufferStorageMultisampleNV == NULL && glad_glRenderbufferStorageMultisampleEXT != NULL) glad_glRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC)glad_glRenderbufferStorageMultisampleEXT; + if (glad_glResetHistogram == NULL && glad_glResetHistogramEXT != NULL) glad_glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glad_glResetHistogramEXT; + if (glad_glResetHistogramEXT == NULL && glad_glResetHistogram != NULL) glad_glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glad_glResetHistogram; + if (glad_glResetMinmax == NULL && glad_glResetMinmaxEXT != NULL) glad_glResetMinmax = (PFNGLRESETMINMAXPROC)glad_glResetMinmaxEXT; + if (glad_glResetMinmaxEXT == NULL && glad_glResetMinmax != NULL) glad_glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glad_glResetMinmax; + if (glad_glResumeTransformFeedback == NULL && glad_glResumeTransformFeedbackNV != NULL) glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)glad_glResumeTransformFeedbackNV; + if (glad_glResumeTransformFeedbackNV == NULL && glad_glResumeTransformFeedback != NULL) glad_glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glad_glResumeTransformFeedback; + if (glad_glSampleCoverage == NULL && glad_glSampleCoverageARB != NULL) glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glad_glSampleCoverageARB; + if (glad_glSampleCoverageARB == NULL && glad_glSampleCoverage != NULL) glad_glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glad_glSampleCoverage; + if (glad_glSampleMaskEXT == NULL && glad_glSampleMaskSGIS != NULL) glad_glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glad_glSampleMaskSGIS; + if (glad_glSampleMaskSGIS == NULL && glad_glSampleMaskEXT != NULL) glad_glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glad_glSampleMaskEXT; + if (glad_glSamplePatternEXT == NULL && glad_glSamplePatternSGIS != NULL) glad_glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glad_glSamplePatternSGIS; + if (glad_glSamplePatternSGIS == NULL && glad_glSamplePatternEXT != NULL) glad_glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glad_glSamplePatternEXT; + if (glad_glSamplerParameterIiv == NULL && glad_glSamplerParameterIivEXT != NULL) glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glad_glSamplerParameterIivEXT; + if (glad_glSamplerParameterIiv == NULL && glad_glSamplerParameterIivOES != NULL) glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glad_glSamplerParameterIivOES; + if (glad_glSamplerParameterIivEXT == NULL && glad_glSamplerParameterIiv != NULL) glad_glSamplerParameterIivEXT = (PFNGLSAMPLERPARAMETERIIVEXTPROC)glad_glSamplerParameterIiv; + if (glad_glSamplerParameterIivEXT == NULL && glad_glSamplerParameterIivOES != NULL) glad_glSamplerParameterIivEXT = (PFNGLSAMPLERPARAMETERIIVEXTPROC)glad_glSamplerParameterIivOES; + if (glad_glSamplerParameterIivOES == NULL && glad_glSamplerParameterIiv != NULL) glad_glSamplerParameterIivOES = (PFNGLSAMPLERPARAMETERIIVOESPROC)glad_glSamplerParameterIiv; + if (glad_glSamplerParameterIivOES == NULL && glad_glSamplerParameterIivEXT != NULL) glad_glSamplerParameterIivOES = (PFNGLSAMPLERPARAMETERIIVOESPROC)glad_glSamplerParameterIivEXT; + if (glad_glSamplerParameterIuiv == NULL && glad_glSamplerParameterIuivEXT != NULL) glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glad_glSamplerParameterIuivEXT; + if (glad_glSamplerParameterIuiv == NULL && glad_glSamplerParameterIuivOES != NULL) glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glad_glSamplerParameterIuivOES; + if (glad_glSamplerParameterIuivEXT == NULL && glad_glSamplerParameterIuiv != NULL) glad_glSamplerParameterIuivEXT = (PFNGLSAMPLERPARAMETERIUIVEXTPROC)glad_glSamplerParameterIuiv; + if (glad_glSamplerParameterIuivEXT == NULL && glad_glSamplerParameterIuivOES != NULL) glad_glSamplerParameterIuivEXT = (PFNGLSAMPLERPARAMETERIUIVEXTPROC)glad_glSamplerParameterIuivOES; + if (glad_glSamplerParameterIuivOES == NULL && glad_glSamplerParameterIuiv != NULL) glad_glSamplerParameterIuivOES = (PFNGLSAMPLERPARAMETERIUIVOESPROC)glad_glSamplerParameterIuiv; + if (glad_glSamplerParameterIuivOES == NULL && glad_glSamplerParameterIuivEXT != NULL) glad_glSamplerParameterIuivOES = (PFNGLSAMPLERPARAMETERIUIVOESPROC)glad_glSamplerParameterIuivEXT; + if (glad_glScissorArrayv == NULL && glad_glScissorArrayvNV != NULL) glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glad_glScissorArrayvNV; + if (glad_glScissorArrayv == NULL && glad_glScissorArrayvOES != NULL) glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glad_glScissorArrayvOES; + if (glad_glScissorArrayvNV == NULL && glad_glScissorArrayv != NULL) glad_glScissorArrayvNV = (PFNGLSCISSORARRAYVNVPROC)glad_glScissorArrayv; + if (glad_glScissorArrayvNV == NULL && glad_glScissorArrayvOES != NULL) glad_glScissorArrayvNV = (PFNGLSCISSORARRAYVNVPROC)glad_glScissorArrayvOES; + if (glad_glScissorArrayvOES == NULL && glad_glScissorArrayv != NULL) glad_glScissorArrayvOES = (PFNGLSCISSORARRAYVOESPROC)glad_glScissorArrayv; + if (glad_glScissorArrayvOES == NULL && glad_glScissorArrayvNV != NULL) glad_glScissorArrayvOES = (PFNGLSCISSORARRAYVOESPROC)glad_glScissorArrayvNV; + if (glad_glScissorIndexed == NULL && glad_glScissorIndexedNV != NULL) glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glad_glScissorIndexedNV; + if (glad_glScissorIndexed == NULL && glad_glScissorIndexedOES != NULL) glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glad_glScissorIndexedOES; + if (glad_glScissorIndexedNV == NULL && glad_glScissorIndexed != NULL) glad_glScissorIndexedNV = (PFNGLSCISSORINDEXEDNVPROC)glad_glScissorIndexed; + if (glad_glScissorIndexedNV == NULL && glad_glScissorIndexedOES != NULL) glad_glScissorIndexedNV = (PFNGLSCISSORINDEXEDNVPROC)glad_glScissorIndexedOES; + if (glad_glScissorIndexedOES == NULL && glad_glScissorIndexed != NULL) glad_glScissorIndexedOES = (PFNGLSCISSORINDEXEDOESPROC)glad_glScissorIndexed; + if (glad_glScissorIndexedOES == NULL && glad_glScissorIndexedNV != NULL) glad_glScissorIndexedOES = (PFNGLSCISSORINDEXEDOESPROC)glad_glScissorIndexedNV; + if (glad_glScissorIndexedv == NULL && glad_glScissorIndexedvNV != NULL) glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glad_glScissorIndexedvNV; + if (glad_glScissorIndexedv == NULL && glad_glScissorIndexedvOES != NULL) glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glad_glScissorIndexedvOES; + if (glad_glScissorIndexedvNV == NULL && glad_glScissorIndexedv != NULL) glad_glScissorIndexedvNV = (PFNGLSCISSORINDEXEDVNVPROC)glad_glScissorIndexedv; + if (glad_glScissorIndexedvNV == NULL && glad_glScissorIndexedvOES != NULL) glad_glScissorIndexedvNV = (PFNGLSCISSORINDEXEDVNVPROC)glad_glScissorIndexedvOES; + if (glad_glScissorIndexedvOES == NULL && glad_glScissorIndexedv != NULL) glad_glScissorIndexedvOES = (PFNGLSCISSORINDEXEDVOESPROC)glad_glScissorIndexedv; + if (glad_glScissorIndexedvOES == NULL && glad_glScissorIndexedvNV != NULL) glad_glScissorIndexedvOES = (PFNGLSCISSORINDEXEDVOESPROC)glad_glScissorIndexedvNV; + if (glad_glSecondaryColor3b == NULL && glad_glSecondaryColor3bEXT != NULL) glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glad_glSecondaryColor3bEXT; + if (glad_glSecondaryColor3bEXT == NULL && glad_glSecondaryColor3b != NULL) glad_glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glad_glSecondaryColor3b; + if (glad_glSecondaryColor3bv == NULL && glad_glSecondaryColor3bvEXT != NULL) glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glad_glSecondaryColor3bvEXT; + if (glad_glSecondaryColor3bvEXT == NULL && glad_glSecondaryColor3bv != NULL) glad_glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glad_glSecondaryColor3bv; + if (glad_glSecondaryColor3d == NULL && glad_glSecondaryColor3dEXT != NULL) glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glad_glSecondaryColor3dEXT; + if (glad_glSecondaryColor3dEXT == NULL && glad_glSecondaryColor3d != NULL) glad_glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glad_glSecondaryColor3d; + if (glad_glSecondaryColor3dv == NULL && glad_glSecondaryColor3dvEXT != NULL) glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glad_glSecondaryColor3dvEXT; + if (glad_glSecondaryColor3dvEXT == NULL && glad_glSecondaryColor3dv != NULL) glad_glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glad_glSecondaryColor3dv; + if (glad_glSecondaryColor3f == NULL && glad_glSecondaryColor3fEXT != NULL) glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glad_glSecondaryColor3fEXT; + if (glad_glSecondaryColor3fEXT == NULL && glad_glSecondaryColor3f != NULL) glad_glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glad_glSecondaryColor3f; + if (glad_glSecondaryColor3fv == NULL && glad_glSecondaryColor3fvEXT != NULL) glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glad_glSecondaryColor3fvEXT; + if (glad_glSecondaryColor3fvEXT == NULL && glad_glSecondaryColor3fv != NULL) glad_glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glad_glSecondaryColor3fv; + if (glad_glSecondaryColor3i == NULL && glad_glSecondaryColor3iEXT != NULL) glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glad_glSecondaryColor3iEXT; + if (glad_glSecondaryColor3iEXT == NULL && glad_glSecondaryColor3i != NULL) glad_glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glad_glSecondaryColor3i; + if (glad_glSecondaryColor3iv == NULL && glad_glSecondaryColor3ivEXT != NULL) glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glad_glSecondaryColor3ivEXT; + if (glad_glSecondaryColor3ivEXT == NULL && glad_glSecondaryColor3iv != NULL) glad_glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glad_glSecondaryColor3iv; + if (glad_glSecondaryColor3s == NULL && glad_glSecondaryColor3sEXT != NULL) glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glad_glSecondaryColor3sEXT; + if (glad_glSecondaryColor3sEXT == NULL && glad_glSecondaryColor3s != NULL) glad_glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glad_glSecondaryColor3s; + if (glad_glSecondaryColor3sv == NULL && glad_glSecondaryColor3svEXT != NULL) glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glad_glSecondaryColor3svEXT; + if (glad_glSecondaryColor3svEXT == NULL && glad_glSecondaryColor3sv != NULL) glad_glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glad_glSecondaryColor3sv; + if (glad_glSecondaryColor3ub == NULL && glad_glSecondaryColor3ubEXT != NULL) glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glad_glSecondaryColor3ubEXT; + if (glad_glSecondaryColor3ubEXT == NULL && glad_glSecondaryColor3ub != NULL) glad_glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glad_glSecondaryColor3ub; + if (glad_glSecondaryColor3ubv == NULL && glad_glSecondaryColor3ubvEXT != NULL) glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glad_glSecondaryColor3ubvEXT; + if (glad_glSecondaryColor3ubvEXT == NULL && glad_glSecondaryColor3ubv != NULL) glad_glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glad_glSecondaryColor3ubv; + if (glad_glSecondaryColor3ui == NULL && glad_glSecondaryColor3uiEXT != NULL) glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glad_glSecondaryColor3uiEXT; + if (glad_glSecondaryColor3uiEXT == NULL && glad_glSecondaryColor3ui != NULL) glad_glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glad_glSecondaryColor3ui; + if (glad_glSecondaryColor3uiv == NULL && glad_glSecondaryColor3uivEXT != NULL) glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glad_glSecondaryColor3uivEXT; + if (glad_glSecondaryColor3uivEXT == NULL && glad_glSecondaryColor3uiv != NULL) glad_glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glad_glSecondaryColor3uiv; + if (glad_glSecondaryColor3us == NULL && glad_glSecondaryColor3usEXT != NULL) glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glad_glSecondaryColor3usEXT; + if (glad_glSecondaryColor3usEXT == NULL && glad_glSecondaryColor3us != NULL) glad_glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glad_glSecondaryColor3us; + if (glad_glSecondaryColor3usv == NULL && glad_glSecondaryColor3usvEXT != NULL) glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glad_glSecondaryColor3usvEXT; + if (glad_glSecondaryColor3usvEXT == NULL && glad_glSecondaryColor3usv != NULL) glad_glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glad_glSecondaryColor3usv; + if (glad_glSecondaryColorPointer == NULL && glad_glSecondaryColorPointerEXT != NULL) glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glad_glSecondaryColorPointerEXT; + if (glad_glSecondaryColorPointerEXT == NULL && glad_glSecondaryColorPointer != NULL) glad_glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glad_glSecondaryColorPointer; + if (glad_glSeparableFilter2D == NULL && glad_glSeparableFilter2DEXT != NULL) glad_glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glad_glSeparableFilter2DEXT; + if (glad_glSeparableFilter2DEXT == NULL && glad_glSeparableFilter2D != NULL) glad_glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glad_glSeparableFilter2D; + if (glad_glShaderSource == NULL && glad_glShaderSourceARB != NULL) glad_glShaderSource = (PFNGLSHADERSOURCEPROC)glad_glShaderSourceARB; + if (glad_glShaderSourceARB == NULL && glad_glShaderSource != NULL) glad_glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glad_glShaderSource; + if (glad_glSpecializeShader == NULL && glad_glSpecializeShaderARB != NULL) glad_glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)glad_glSpecializeShaderARB; + if (glad_glSpecializeShaderARB == NULL && glad_glSpecializeShader != NULL) glad_glSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)glad_glSpecializeShader; + if (glad_glStencilOpSeparate == NULL && glad_glStencilOpSeparateATI != NULL) glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glad_glStencilOpSeparateATI; + if (glad_glStencilOpSeparateATI == NULL && glad_glStencilOpSeparate != NULL) glad_glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glad_glStencilOpSeparate; + if (glad_glTexBuffer == NULL && glad_glTexBufferARB != NULL) glad_glTexBuffer = (PFNGLTEXBUFFERPROC)glad_glTexBufferARB; + if (glad_glTexBuffer == NULL && glad_glTexBufferEXT != NULL) glad_glTexBuffer = (PFNGLTEXBUFFERPROC)glad_glTexBufferEXT; + if (glad_glTexBuffer == NULL && glad_glTexBufferOES != NULL) glad_glTexBuffer = (PFNGLTEXBUFFERPROC)glad_glTexBufferOES; + if (glad_glTexBufferARB == NULL && glad_glTexBuffer != NULL) glad_glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glad_glTexBuffer; + if (glad_glTexBufferARB == NULL && glad_glTexBufferEXT != NULL) glad_glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glad_glTexBufferEXT; + if (glad_glTexBufferARB == NULL && glad_glTexBufferOES != NULL) glad_glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glad_glTexBufferOES; + if (glad_glTexBufferEXT == NULL && glad_glTexBuffer != NULL) glad_glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glad_glTexBuffer; + if (glad_glTexBufferEXT == NULL && glad_glTexBufferARB != NULL) glad_glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glad_glTexBufferARB; + if (glad_glTexBufferEXT == NULL && glad_glTexBufferOES != NULL) glad_glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glad_glTexBufferOES; + if (glad_glTexBufferOES == NULL && glad_glTexBuffer != NULL) glad_glTexBufferOES = (PFNGLTEXBUFFEROESPROC)glad_glTexBuffer; + if (glad_glTexBufferOES == NULL && glad_glTexBufferARB != NULL) glad_glTexBufferOES = (PFNGLTEXBUFFEROESPROC)glad_glTexBufferARB; + if (glad_glTexBufferOES == NULL && glad_glTexBufferEXT != NULL) glad_glTexBufferOES = (PFNGLTEXBUFFEROESPROC)glad_glTexBufferEXT; + if (glad_glTexBufferRange == NULL && glad_glTexBufferRangeEXT != NULL) glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glad_glTexBufferRangeEXT; + if (glad_glTexBufferRange == NULL && glad_glTexBufferRangeOES != NULL) glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glad_glTexBufferRangeOES; + if (glad_glTexBufferRangeEXT == NULL && glad_glTexBufferRange != NULL) glad_glTexBufferRangeEXT = (PFNGLTEXBUFFERRANGEEXTPROC)glad_glTexBufferRange; + if (glad_glTexBufferRangeEXT == NULL && glad_glTexBufferRangeOES != NULL) glad_glTexBufferRangeEXT = (PFNGLTEXBUFFERRANGEEXTPROC)glad_glTexBufferRangeOES; + if (glad_glTexBufferRangeOES == NULL && glad_glTexBufferRange != NULL) glad_glTexBufferRangeOES = (PFNGLTEXBUFFERRANGEOESPROC)glad_glTexBufferRange; + if (glad_glTexBufferRangeOES == NULL && glad_glTexBufferRangeEXT != NULL) glad_glTexBufferRangeOES = (PFNGLTEXBUFFERRANGEOESPROC)glad_glTexBufferRangeEXT; + if (glad_glTexImage3D == NULL && glad_glTexImage3DEXT != NULL) glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)glad_glTexImage3DEXT; + if (glad_glTexImage3DEXT == NULL && glad_glTexImage3D != NULL) glad_glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glad_glTexImage3D; + if (glad_glTexPageCommitmentARB == NULL && glad_glTexPageCommitmentEXT != NULL) glad_glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC)glad_glTexPageCommitmentEXT; + if (glad_glTexPageCommitmentEXT == NULL && glad_glTexPageCommitmentARB != NULL) glad_glTexPageCommitmentEXT = (PFNGLTEXPAGECOMMITMENTEXTPROC)glad_glTexPageCommitmentARB; + if (glad_glTexParameterIiv == NULL && glad_glTexParameterIivEXT != NULL) glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glad_glTexParameterIivEXT; + if (glad_glTexParameterIiv == NULL && glad_glTexParameterIivOES != NULL) glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glad_glTexParameterIivOES; + if (glad_glTexParameterIivEXT == NULL && glad_glTexParameterIiv != NULL) glad_glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glad_glTexParameterIiv; + if (glad_glTexParameterIivEXT == NULL && glad_glTexParameterIivOES != NULL) glad_glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glad_glTexParameterIivOES; + if (glad_glTexParameterIivOES == NULL && glad_glTexParameterIiv != NULL) glad_glTexParameterIivOES = (PFNGLTEXPARAMETERIIVOESPROC)glad_glTexParameterIiv; + if (glad_glTexParameterIivOES == NULL && glad_glTexParameterIivEXT != NULL) glad_glTexParameterIivOES = (PFNGLTEXPARAMETERIIVOESPROC)glad_glTexParameterIivEXT; + if (glad_glTexParameterIuiv == NULL && glad_glTexParameterIuivEXT != NULL) glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glad_glTexParameterIuivEXT; + if (glad_glTexParameterIuiv == NULL && glad_glTexParameterIuivOES != NULL) glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glad_glTexParameterIuivOES; + if (glad_glTexParameterIuivEXT == NULL && glad_glTexParameterIuiv != NULL) glad_glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glad_glTexParameterIuiv; + if (glad_glTexParameterIuivEXT == NULL && glad_glTexParameterIuivOES != NULL) glad_glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glad_glTexParameterIuivOES; + if (glad_glTexParameterIuivOES == NULL && glad_glTexParameterIuiv != NULL) glad_glTexParameterIuivOES = (PFNGLTEXPARAMETERIUIVOESPROC)glad_glTexParameterIuiv; + if (glad_glTexParameterIuivOES == NULL && glad_glTexParameterIuivEXT != NULL) glad_glTexParameterIuivOES = (PFNGLTEXPARAMETERIUIVOESPROC)glad_glTexParameterIuivEXT; + if (glad_glTexStorage1D == NULL && glad_glTexStorage1DEXT != NULL) glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)glad_glTexStorage1DEXT; + if (glad_glTexStorage1DEXT == NULL && glad_glTexStorage1D != NULL) glad_glTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC)glad_glTexStorage1D; + if (glad_glTexStorage2D == NULL && glad_glTexStorage2DEXT != NULL) glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)glad_glTexStorage2DEXT; + if (glad_glTexStorage2DEXT == NULL && glad_glTexStorage2D != NULL) glad_glTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC)glad_glTexStorage2D; + if (glad_glTexStorage3D == NULL && glad_glTexStorage3DEXT != NULL) glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)glad_glTexStorage3DEXT; + if (glad_glTexStorage3DEXT == NULL && glad_glTexStorage3D != NULL) glad_glTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC)glad_glTexStorage3D; + if (glad_glTexStorage3DMultisample == NULL && glad_glTexStorage3DMultisampleOES != NULL) glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)glad_glTexStorage3DMultisampleOES; + if (glad_glTexStorage3DMultisampleOES == NULL && glad_glTexStorage3DMultisample != NULL) glad_glTexStorage3DMultisampleOES = (PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC)glad_glTexStorage3DMultisample; + if (glad_glTexSubImage1D == NULL && glad_glTexSubImage1DEXT != NULL) glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)glad_glTexSubImage1DEXT; + if (glad_glTexSubImage1DEXT == NULL && glad_glTexSubImage1D != NULL) glad_glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glad_glTexSubImage1D; + if (glad_glTexSubImage2D == NULL && glad_glTexSubImage2DEXT != NULL) glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)glad_glTexSubImage2DEXT; + if (glad_glTexSubImage2DEXT == NULL && glad_glTexSubImage2D != NULL) glad_glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glad_glTexSubImage2D; + if (glad_glTexSubImage3D == NULL && glad_glTexSubImage3DEXT != NULL) glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glad_glTexSubImage3DEXT; + if (glad_glTexSubImage3DEXT == NULL && glad_glTexSubImage3D != NULL) glad_glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glad_glTexSubImage3D; + if (glad_glTextureView == NULL && glad_glTextureViewEXT != NULL) glad_glTextureView = (PFNGLTEXTUREVIEWPROC)glad_glTextureViewEXT; + if (glad_glTextureView == NULL && glad_glTextureViewOES != NULL) glad_glTextureView = (PFNGLTEXTUREVIEWPROC)glad_glTextureViewOES; + if (glad_glTextureViewEXT == NULL && glad_glTextureView != NULL) glad_glTextureViewEXT = (PFNGLTEXTUREVIEWEXTPROC)glad_glTextureView; + if (glad_glTextureViewEXT == NULL && glad_glTextureViewOES != NULL) glad_glTextureViewEXT = (PFNGLTEXTUREVIEWEXTPROC)glad_glTextureViewOES; + if (glad_glTextureViewOES == NULL && glad_glTextureView != NULL) glad_glTextureViewOES = (PFNGLTEXTUREVIEWOESPROC)glad_glTextureView; + if (glad_glTextureViewOES == NULL && glad_glTextureViewEXT != NULL) glad_glTextureViewOES = (PFNGLTEXTUREVIEWOESPROC)glad_glTextureViewEXT; + if (glad_glTransformFeedbackVaryings == NULL && glad_glTransformFeedbackVaryingsEXT != NULL) glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glad_glTransformFeedbackVaryingsEXT; + if (glad_glTransformFeedbackVaryingsEXT == NULL && glad_glTransformFeedbackVaryings != NULL) glad_glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glad_glTransformFeedbackVaryings; + if (glad_glUniform1f == NULL && glad_glUniform1fARB != NULL) glad_glUniform1f = (PFNGLUNIFORM1FPROC)glad_glUniform1fARB; + if (glad_glUniform1fARB == NULL && glad_glUniform1f != NULL) glad_glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glad_glUniform1f; + if (glad_glUniform1fv == NULL && glad_glUniform1fvARB != NULL) glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)glad_glUniform1fvARB; + if (glad_glUniform1fvARB == NULL && glad_glUniform1fv != NULL) glad_glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glad_glUniform1fv; + if (glad_glUniform1i == NULL && glad_glUniform1iARB != NULL) glad_glUniform1i = (PFNGLUNIFORM1IPROC)glad_glUniform1iARB; + if (glad_glUniform1iARB == NULL && glad_glUniform1i != NULL) glad_glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glad_glUniform1i; + if (glad_glUniform1iv == NULL && glad_glUniform1ivARB != NULL) glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)glad_glUniform1ivARB; + if (glad_glUniform1ivARB == NULL && glad_glUniform1iv != NULL) glad_glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glad_glUniform1iv; + if (glad_glUniform1ui == NULL && glad_glUniform1uiEXT != NULL) glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)glad_glUniform1uiEXT; + if (glad_glUniform1uiEXT == NULL && glad_glUniform1ui != NULL) glad_glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glad_glUniform1ui; + if (glad_glUniform1uiv == NULL && glad_glUniform1uivEXT != NULL) glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glad_glUniform1uivEXT; + if (glad_glUniform1uivEXT == NULL && glad_glUniform1uiv != NULL) glad_glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glad_glUniform1uiv; + if (glad_glUniform2f == NULL && glad_glUniform2fARB != NULL) glad_glUniform2f = (PFNGLUNIFORM2FPROC)glad_glUniform2fARB; + if (glad_glUniform2fARB == NULL && glad_glUniform2f != NULL) glad_glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glad_glUniform2f; + if (glad_glUniform2fv == NULL && glad_glUniform2fvARB != NULL) glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)glad_glUniform2fvARB; + if (glad_glUniform2fvARB == NULL && glad_glUniform2fv != NULL) glad_glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glad_glUniform2fv; + if (glad_glUniform2i == NULL && glad_glUniform2iARB != NULL) glad_glUniform2i = (PFNGLUNIFORM2IPROC)glad_glUniform2iARB; + if (glad_glUniform2iARB == NULL && glad_glUniform2i != NULL) glad_glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glad_glUniform2i; + if (glad_glUniform2iv == NULL && glad_glUniform2ivARB != NULL) glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)glad_glUniform2ivARB; + if (glad_glUniform2ivARB == NULL && glad_glUniform2iv != NULL) glad_glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glad_glUniform2iv; + if (glad_glUniform2ui == NULL && glad_glUniform2uiEXT != NULL) glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)glad_glUniform2uiEXT; + if (glad_glUniform2uiEXT == NULL && glad_glUniform2ui != NULL) glad_glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glad_glUniform2ui; + if (glad_glUniform2uiv == NULL && glad_glUniform2uivEXT != NULL) glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glad_glUniform2uivEXT; + if (glad_glUniform2uivEXT == NULL && glad_glUniform2uiv != NULL) glad_glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glad_glUniform2uiv; + if (glad_glUniform3f == NULL && glad_glUniform3fARB != NULL) glad_glUniform3f = (PFNGLUNIFORM3FPROC)glad_glUniform3fARB; + if (glad_glUniform3fARB == NULL && glad_glUniform3f != NULL) glad_glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glad_glUniform3f; + if (glad_glUniform3fv == NULL && glad_glUniform3fvARB != NULL) glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)glad_glUniform3fvARB; + if (glad_glUniform3fvARB == NULL && glad_glUniform3fv != NULL) glad_glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glad_glUniform3fv; + if (glad_glUniform3i == NULL && glad_glUniform3iARB != NULL) glad_glUniform3i = (PFNGLUNIFORM3IPROC)glad_glUniform3iARB; + if (glad_glUniform3iARB == NULL && glad_glUniform3i != NULL) glad_glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glad_glUniform3i; + if (glad_glUniform3iv == NULL && glad_glUniform3ivARB != NULL) glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)glad_glUniform3ivARB; + if (glad_glUniform3ivARB == NULL && glad_glUniform3iv != NULL) glad_glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glad_glUniform3iv; + if (glad_glUniform3ui == NULL && glad_glUniform3uiEXT != NULL) glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)glad_glUniform3uiEXT; + if (glad_glUniform3uiEXT == NULL && glad_glUniform3ui != NULL) glad_glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glad_glUniform3ui; + if (glad_glUniform3uiv == NULL && glad_glUniform3uivEXT != NULL) glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glad_glUniform3uivEXT; + if (glad_glUniform3uivEXT == NULL && glad_glUniform3uiv != NULL) glad_glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glad_glUniform3uiv; + if (glad_glUniform4f == NULL && glad_glUniform4fARB != NULL) glad_glUniform4f = (PFNGLUNIFORM4FPROC)glad_glUniform4fARB; + if (glad_glUniform4fARB == NULL && glad_glUniform4f != NULL) glad_glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glad_glUniform4f; + if (glad_glUniform4fv == NULL && glad_glUniform4fvARB != NULL) glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)glad_glUniform4fvARB; + if (glad_glUniform4fvARB == NULL && glad_glUniform4fv != NULL) glad_glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glad_glUniform4fv; + if (glad_glUniform4i == NULL && glad_glUniform4iARB != NULL) glad_glUniform4i = (PFNGLUNIFORM4IPROC)glad_glUniform4iARB; + if (glad_glUniform4iARB == NULL && glad_glUniform4i != NULL) glad_glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glad_glUniform4i; + if (glad_glUniform4iv == NULL && glad_glUniform4ivARB != NULL) glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)glad_glUniform4ivARB; + if (glad_glUniform4ivARB == NULL && glad_glUniform4iv != NULL) glad_glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glad_glUniform4iv; + if (glad_glUniform4ui == NULL && glad_glUniform4uiEXT != NULL) glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)glad_glUniform4uiEXT; + if (glad_glUniform4uiEXT == NULL && glad_glUniform4ui != NULL) glad_glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glad_glUniform4ui; + if (glad_glUniform4uiv == NULL && glad_glUniform4uivEXT != NULL) glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glad_glUniform4uivEXT; + if (glad_glUniform4uivEXT == NULL && glad_glUniform4uiv != NULL) glad_glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glad_glUniform4uiv; + if (glad_glUniformHandleui64ARB == NULL && glad_glUniformHandleui64IMG != NULL) glad_glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC)glad_glUniformHandleui64IMG; + if (glad_glUniformHandleui64IMG == NULL && glad_glUniformHandleui64ARB != NULL) glad_glUniformHandleui64IMG = (PFNGLUNIFORMHANDLEUI64IMGPROC)glad_glUniformHandleui64ARB; + if (glad_glUniformHandleui64vARB == NULL && glad_glUniformHandleui64vIMG != NULL) glad_glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC)glad_glUniformHandleui64vIMG; + if (glad_glUniformHandleui64vIMG == NULL && glad_glUniformHandleui64vARB != NULL) glad_glUniformHandleui64vIMG = (PFNGLUNIFORMHANDLEUI64VIMGPROC)glad_glUniformHandleui64vARB; + if (glad_glUniformMatrix2fv == NULL && glad_glUniformMatrix2fvARB != NULL) glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glad_glUniformMatrix2fvARB; + if (glad_glUniformMatrix2fvARB == NULL && glad_glUniformMatrix2fv != NULL) glad_glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glad_glUniformMatrix2fv; + if (glad_glUniformMatrix2x3fv == NULL && glad_glUniformMatrix2x3fvNV != NULL) glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glad_glUniformMatrix2x3fvNV; + if (glad_glUniformMatrix2x3fvNV == NULL && glad_glUniformMatrix2x3fv != NULL) glad_glUniformMatrix2x3fvNV = (PFNGLUNIFORMMATRIX2X3FVNVPROC)glad_glUniformMatrix2x3fv; + if (glad_glUniformMatrix2x4fv == NULL && glad_glUniformMatrix2x4fvNV != NULL) glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glad_glUniformMatrix2x4fvNV; + if (glad_glUniformMatrix2x4fvNV == NULL && glad_glUniformMatrix2x4fv != NULL) glad_glUniformMatrix2x4fvNV = (PFNGLUNIFORMMATRIX2X4FVNVPROC)glad_glUniformMatrix2x4fv; + if (glad_glUniformMatrix3fv == NULL && glad_glUniformMatrix3fvARB != NULL) glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glad_glUniformMatrix3fvARB; + if (glad_glUniformMatrix3fvARB == NULL && glad_glUniformMatrix3fv != NULL) glad_glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glad_glUniformMatrix3fv; + if (glad_glUniformMatrix3x2fv == NULL && glad_glUniformMatrix3x2fvNV != NULL) glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glad_glUniformMatrix3x2fvNV; + if (glad_glUniformMatrix3x2fvNV == NULL && glad_glUniformMatrix3x2fv != NULL) glad_glUniformMatrix3x2fvNV = (PFNGLUNIFORMMATRIX3X2FVNVPROC)glad_glUniformMatrix3x2fv; + if (glad_glUniformMatrix3x4fv == NULL && glad_glUniformMatrix3x4fvNV != NULL) glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glad_glUniformMatrix3x4fvNV; + if (glad_glUniformMatrix3x4fvNV == NULL && glad_glUniformMatrix3x4fv != NULL) glad_glUniformMatrix3x4fvNV = (PFNGLUNIFORMMATRIX3X4FVNVPROC)glad_glUniformMatrix3x4fv; + if (glad_glUniformMatrix4fv == NULL && glad_glUniformMatrix4fvARB != NULL) glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glad_glUniformMatrix4fvARB; + if (glad_glUniformMatrix4fvARB == NULL && glad_glUniformMatrix4fv != NULL) glad_glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glad_glUniformMatrix4fv; + if (glad_glUniformMatrix4x2fv == NULL && glad_glUniformMatrix4x2fvNV != NULL) glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glad_glUniformMatrix4x2fvNV; + if (glad_glUniformMatrix4x2fvNV == NULL && glad_glUniformMatrix4x2fv != NULL) glad_glUniformMatrix4x2fvNV = (PFNGLUNIFORMMATRIX4X2FVNVPROC)glad_glUniformMatrix4x2fv; + if (glad_glUniformMatrix4x3fv == NULL && glad_glUniformMatrix4x3fvNV != NULL) glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glad_glUniformMatrix4x3fvNV; + if (glad_glUniformMatrix4x3fvNV == NULL && glad_glUniformMatrix4x3fv != NULL) glad_glUniformMatrix4x3fvNV = (PFNGLUNIFORMMATRIX4X3FVNVPROC)glad_glUniformMatrix4x3fv; + if (glad_glUnmapBuffer == NULL && glad_glUnmapBufferARB != NULL) glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glad_glUnmapBufferARB; + if (glad_glUnmapBuffer == NULL && glad_glUnmapBufferOES != NULL) glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glad_glUnmapBufferOES; + if (glad_glUnmapBufferARB == NULL && glad_glUnmapBuffer != NULL) glad_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glad_glUnmapBuffer; + if (glad_glUnmapBufferARB == NULL && glad_glUnmapBufferOES != NULL) glad_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glad_glUnmapBufferOES; + if (glad_glUnmapBufferOES == NULL && glad_glUnmapBuffer != NULL) glad_glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC)glad_glUnmapBuffer; + if (glad_glUnmapBufferOES == NULL && glad_glUnmapBufferARB != NULL) glad_glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC)glad_glUnmapBufferARB; + if (glad_glUseProgram == NULL && glad_glUseProgramObjectARB != NULL) glad_glUseProgram = (PFNGLUSEPROGRAMPROC)glad_glUseProgramObjectARB; + if (glad_glUseProgramObjectARB == NULL && glad_glUseProgram != NULL) glad_glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glad_glUseProgram; + if (glad_glValidateProgram == NULL && glad_glValidateProgramARB != NULL) glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glad_glValidateProgramARB; + if (glad_glValidateProgramARB == NULL && glad_glValidateProgram != NULL) glad_glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glad_glValidateProgram; + if (glad_glVertexAttrib1d == NULL && glad_glVertexAttrib1dARB != NULL) glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glad_glVertexAttrib1dARB; + if (glad_glVertexAttrib1d == NULL && glad_glVertexAttrib1dNV != NULL) glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glad_glVertexAttrib1dNV; + if (glad_glVertexAttrib1dARB == NULL && glad_glVertexAttrib1d != NULL) glad_glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glad_glVertexAttrib1d; + if (glad_glVertexAttrib1dARB == NULL && glad_glVertexAttrib1dNV != NULL) glad_glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glad_glVertexAttrib1dNV; + if (glad_glVertexAttrib1dNV == NULL && glad_glVertexAttrib1d != NULL) glad_glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glad_glVertexAttrib1d; + if (glad_glVertexAttrib1dNV == NULL && glad_glVertexAttrib1dARB != NULL) glad_glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glad_glVertexAttrib1dARB; + if (glad_glVertexAttrib1dv == NULL && glad_glVertexAttrib1dvARB != NULL) glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glad_glVertexAttrib1dvARB; + if (glad_glVertexAttrib1dv == NULL && glad_glVertexAttrib1dvNV != NULL) glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glad_glVertexAttrib1dvNV; + if (glad_glVertexAttrib1dvARB == NULL && glad_glVertexAttrib1dv != NULL) glad_glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glad_glVertexAttrib1dv; + if (glad_glVertexAttrib1dvARB == NULL && glad_glVertexAttrib1dvNV != NULL) glad_glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glad_glVertexAttrib1dvNV; + if (glad_glVertexAttrib1dvNV == NULL && glad_glVertexAttrib1dv != NULL) glad_glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glad_glVertexAttrib1dv; + if (glad_glVertexAttrib1dvNV == NULL && glad_glVertexAttrib1dvARB != NULL) glad_glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glad_glVertexAttrib1dvARB; + if (glad_glVertexAttrib1f == NULL && glad_glVertexAttrib1fARB != NULL) glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glad_glVertexAttrib1fARB; + if (glad_glVertexAttrib1f == NULL && glad_glVertexAttrib1fNV != NULL) glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glad_glVertexAttrib1fNV; + if (glad_glVertexAttrib1fARB == NULL && glad_glVertexAttrib1f != NULL) glad_glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glad_glVertexAttrib1f; + if (glad_glVertexAttrib1fARB == NULL && glad_glVertexAttrib1fNV != NULL) glad_glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glad_glVertexAttrib1fNV; + if (glad_glVertexAttrib1fNV == NULL && glad_glVertexAttrib1f != NULL) glad_glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glad_glVertexAttrib1f; + if (glad_glVertexAttrib1fNV == NULL && glad_glVertexAttrib1fARB != NULL) glad_glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glad_glVertexAttrib1fARB; + if (glad_glVertexAttrib1fv == NULL && glad_glVertexAttrib1fvARB != NULL) glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glad_glVertexAttrib1fvARB; + if (glad_glVertexAttrib1fv == NULL && glad_glVertexAttrib1fvNV != NULL) glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glad_glVertexAttrib1fvNV; + if (glad_glVertexAttrib1fvARB == NULL && glad_glVertexAttrib1fv != NULL) glad_glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glad_glVertexAttrib1fv; + if (glad_glVertexAttrib1fvARB == NULL && glad_glVertexAttrib1fvNV != NULL) glad_glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glad_glVertexAttrib1fvNV; + if (glad_glVertexAttrib1fvNV == NULL && glad_glVertexAttrib1fv != NULL) glad_glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glad_glVertexAttrib1fv; + if (glad_glVertexAttrib1fvNV == NULL && glad_glVertexAttrib1fvARB != NULL) glad_glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glad_glVertexAttrib1fvARB; + if (glad_glVertexAttrib1s == NULL && glad_glVertexAttrib1sARB != NULL) glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glad_glVertexAttrib1sARB; + if (glad_glVertexAttrib1s == NULL && glad_glVertexAttrib1sNV != NULL) glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glad_glVertexAttrib1sNV; + if (glad_glVertexAttrib1sARB == NULL && glad_glVertexAttrib1s != NULL) glad_glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glad_glVertexAttrib1s; + if (glad_glVertexAttrib1sARB == NULL && glad_glVertexAttrib1sNV != NULL) glad_glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glad_glVertexAttrib1sNV; + if (glad_glVertexAttrib1sNV == NULL && glad_glVertexAttrib1s != NULL) glad_glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glad_glVertexAttrib1s; + if (glad_glVertexAttrib1sNV == NULL && glad_glVertexAttrib1sARB != NULL) glad_glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glad_glVertexAttrib1sARB; + if (glad_glVertexAttrib1sv == NULL && glad_glVertexAttrib1svARB != NULL) glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glad_glVertexAttrib1svARB; + if (glad_glVertexAttrib1sv == NULL && glad_glVertexAttrib1svNV != NULL) glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glad_glVertexAttrib1svNV; + if (glad_glVertexAttrib1svARB == NULL && glad_glVertexAttrib1sv != NULL) glad_glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glad_glVertexAttrib1sv; + if (glad_glVertexAttrib1svARB == NULL && glad_glVertexAttrib1svNV != NULL) glad_glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glad_glVertexAttrib1svNV; + if (glad_glVertexAttrib1svNV == NULL && glad_glVertexAttrib1sv != NULL) glad_glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glad_glVertexAttrib1sv; + if (glad_glVertexAttrib1svNV == NULL && glad_glVertexAttrib1svARB != NULL) glad_glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glad_glVertexAttrib1svARB; + if (glad_glVertexAttrib2d == NULL && glad_glVertexAttrib2dARB != NULL) glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glad_glVertexAttrib2dARB; + if (glad_glVertexAttrib2d == NULL && glad_glVertexAttrib2dNV != NULL) glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glad_glVertexAttrib2dNV; + if (glad_glVertexAttrib2dARB == NULL && glad_glVertexAttrib2d != NULL) glad_glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glad_glVertexAttrib2d; + if (glad_glVertexAttrib2dARB == NULL && glad_glVertexAttrib2dNV != NULL) glad_glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glad_glVertexAttrib2dNV; + if (glad_glVertexAttrib2dNV == NULL && glad_glVertexAttrib2d != NULL) glad_glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glad_glVertexAttrib2d; + if (glad_glVertexAttrib2dNV == NULL && glad_glVertexAttrib2dARB != NULL) glad_glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glad_glVertexAttrib2dARB; + if (glad_glVertexAttrib2dv == NULL && glad_glVertexAttrib2dvARB != NULL) glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glad_glVertexAttrib2dvARB; + if (glad_glVertexAttrib2dv == NULL && glad_glVertexAttrib2dvNV != NULL) glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glad_glVertexAttrib2dvNV; + if (glad_glVertexAttrib2dvARB == NULL && glad_glVertexAttrib2dv != NULL) glad_glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glad_glVertexAttrib2dv; + if (glad_glVertexAttrib2dvARB == NULL && glad_glVertexAttrib2dvNV != NULL) glad_glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glad_glVertexAttrib2dvNV; + if (glad_glVertexAttrib2dvNV == NULL && glad_glVertexAttrib2dv != NULL) glad_glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glad_glVertexAttrib2dv; + if (glad_glVertexAttrib2dvNV == NULL && glad_glVertexAttrib2dvARB != NULL) glad_glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glad_glVertexAttrib2dvARB; + if (glad_glVertexAttrib2f == NULL && glad_glVertexAttrib2fARB != NULL) glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glad_glVertexAttrib2fARB; + if (glad_glVertexAttrib2f == NULL && glad_glVertexAttrib2fNV != NULL) glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glad_glVertexAttrib2fNV; + if (glad_glVertexAttrib2fARB == NULL && glad_glVertexAttrib2f != NULL) glad_glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glad_glVertexAttrib2f; + if (glad_glVertexAttrib2fARB == NULL && glad_glVertexAttrib2fNV != NULL) glad_glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glad_glVertexAttrib2fNV; + if (glad_glVertexAttrib2fNV == NULL && glad_glVertexAttrib2f != NULL) glad_glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glad_glVertexAttrib2f; + if (glad_glVertexAttrib2fNV == NULL && glad_glVertexAttrib2fARB != NULL) glad_glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glad_glVertexAttrib2fARB; + if (glad_glVertexAttrib2fv == NULL && glad_glVertexAttrib2fvARB != NULL) glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glad_glVertexAttrib2fvARB; + if (glad_glVertexAttrib2fv == NULL && glad_glVertexAttrib2fvNV != NULL) glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glad_glVertexAttrib2fvNV; + if (glad_glVertexAttrib2fvARB == NULL && glad_glVertexAttrib2fv != NULL) glad_glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glad_glVertexAttrib2fv; + if (glad_glVertexAttrib2fvARB == NULL && glad_glVertexAttrib2fvNV != NULL) glad_glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glad_glVertexAttrib2fvNV; + if (glad_glVertexAttrib2fvNV == NULL && glad_glVertexAttrib2fv != NULL) glad_glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glad_glVertexAttrib2fv; + if (glad_glVertexAttrib2fvNV == NULL && glad_glVertexAttrib2fvARB != NULL) glad_glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glad_glVertexAttrib2fvARB; + if (glad_glVertexAttrib2s == NULL && glad_glVertexAttrib2sARB != NULL) glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glad_glVertexAttrib2sARB; + if (glad_glVertexAttrib2s == NULL && glad_glVertexAttrib2sNV != NULL) glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glad_glVertexAttrib2sNV; + if (glad_glVertexAttrib2sARB == NULL && glad_glVertexAttrib2s != NULL) glad_glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glad_glVertexAttrib2s; + if (glad_glVertexAttrib2sARB == NULL && glad_glVertexAttrib2sNV != NULL) glad_glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glad_glVertexAttrib2sNV; + if (glad_glVertexAttrib2sNV == NULL && glad_glVertexAttrib2s != NULL) glad_glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glad_glVertexAttrib2s; + if (glad_glVertexAttrib2sNV == NULL && glad_glVertexAttrib2sARB != NULL) glad_glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glad_glVertexAttrib2sARB; + if (glad_glVertexAttrib2sv == NULL && glad_glVertexAttrib2svARB != NULL) glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glad_glVertexAttrib2svARB; + if (glad_glVertexAttrib2sv == NULL && glad_glVertexAttrib2svNV != NULL) glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glad_glVertexAttrib2svNV; + if (glad_glVertexAttrib2svARB == NULL && glad_glVertexAttrib2sv != NULL) glad_glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glad_glVertexAttrib2sv; + if (glad_glVertexAttrib2svARB == NULL && glad_glVertexAttrib2svNV != NULL) glad_glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glad_glVertexAttrib2svNV; + if (glad_glVertexAttrib2svNV == NULL && glad_glVertexAttrib2sv != NULL) glad_glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glad_glVertexAttrib2sv; + if (glad_glVertexAttrib2svNV == NULL && glad_glVertexAttrib2svARB != NULL) glad_glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glad_glVertexAttrib2svARB; + if (glad_glVertexAttrib3d == NULL && glad_glVertexAttrib3dARB != NULL) glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glad_glVertexAttrib3dARB; + if (glad_glVertexAttrib3d == NULL && glad_glVertexAttrib3dNV != NULL) glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glad_glVertexAttrib3dNV; + if (glad_glVertexAttrib3dARB == NULL && glad_glVertexAttrib3d != NULL) glad_glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glad_glVertexAttrib3d; + if (glad_glVertexAttrib3dARB == NULL && glad_glVertexAttrib3dNV != NULL) glad_glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glad_glVertexAttrib3dNV; + if (glad_glVertexAttrib3dNV == NULL && glad_glVertexAttrib3d != NULL) glad_glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glad_glVertexAttrib3d; + if (glad_glVertexAttrib3dNV == NULL && glad_glVertexAttrib3dARB != NULL) glad_glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glad_glVertexAttrib3dARB; + if (glad_glVertexAttrib3dv == NULL && glad_glVertexAttrib3dvARB != NULL) glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glad_glVertexAttrib3dvARB; + if (glad_glVertexAttrib3dv == NULL && glad_glVertexAttrib3dvNV != NULL) glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glad_glVertexAttrib3dvNV; + if (glad_glVertexAttrib3dvARB == NULL && glad_glVertexAttrib3dv != NULL) glad_glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glad_glVertexAttrib3dv; + if (glad_glVertexAttrib3dvARB == NULL && glad_glVertexAttrib3dvNV != NULL) glad_glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glad_glVertexAttrib3dvNV; + if (glad_glVertexAttrib3dvNV == NULL && glad_glVertexAttrib3dv != NULL) glad_glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glad_glVertexAttrib3dv; + if (glad_glVertexAttrib3dvNV == NULL && glad_glVertexAttrib3dvARB != NULL) glad_glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glad_glVertexAttrib3dvARB; + if (glad_glVertexAttrib3f == NULL && glad_glVertexAttrib3fARB != NULL) glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glad_glVertexAttrib3fARB; + if (glad_glVertexAttrib3f == NULL && glad_glVertexAttrib3fNV != NULL) glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glad_glVertexAttrib3fNV; + if (glad_glVertexAttrib3fARB == NULL && glad_glVertexAttrib3f != NULL) glad_glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glad_glVertexAttrib3f; + if (glad_glVertexAttrib3fARB == NULL && glad_glVertexAttrib3fNV != NULL) glad_glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glad_glVertexAttrib3fNV; + if (glad_glVertexAttrib3fNV == NULL && glad_glVertexAttrib3f != NULL) glad_glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glad_glVertexAttrib3f; + if (glad_glVertexAttrib3fNV == NULL && glad_glVertexAttrib3fARB != NULL) glad_glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glad_glVertexAttrib3fARB; + if (glad_glVertexAttrib3fv == NULL && glad_glVertexAttrib3fvARB != NULL) glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glad_glVertexAttrib3fvARB; + if (glad_glVertexAttrib3fv == NULL && glad_glVertexAttrib3fvNV != NULL) glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glad_glVertexAttrib3fvNV; + if (glad_glVertexAttrib3fvARB == NULL && glad_glVertexAttrib3fv != NULL) glad_glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glad_glVertexAttrib3fv; + if (glad_glVertexAttrib3fvARB == NULL && glad_glVertexAttrib3fvNV != NULL) glad_glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glad_glVertexAttrib3fvNV; + if (glad_glVertexAttrib3fvNV == NULL && glad_glVertexAttrib3fv != NULL) glad_glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glad_glVertexAttrib3fv; + if (glad_glVertexAttrib3fvNV == NULL && glad_glVertexAttrib3fvARB != NULL) glad_glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glad_glVertexAttrib3fvARB; + if (glad_glVertexAttrib3s == NULL && glad_glVertexAttrib3sARB != NULL) glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glad_glVertexAttrib3sARB; + if (glad_glVertexAttrib3s == NULL && glad_glVertexAttrib3sNV != NULL) glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glad_glVertexAttrib3sNV; + if (glad_glVertexAttrib3sARB == NULL && glad_glVertexAttrib3s != NULL) glad_glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glad_glVertexAttrib3s; + if (glad_glVertexAttrib3sARB == NULL && glad_glVertexAttrib3sNV != NULL) glad_glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glad_glVertexAttrib3sNV; + if (glad_glVertexAttrib3sNV == NULL && glad_glVertexAttrib3s != NULL) glad_glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glad_glVertexAttrib3s; + if (glad_glVertexAttrib3sNV == NULL && glad_glVertexAttrib3sARB != NULL) glad_glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glad_glVertexAttrib3sARB; + if (glad_glVertexAttrib3sv == NULL && glad_glVertexAttrib3svARB != NULL) glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glad_glVertexAttrib3svARB; + if (glad_glVertexAttrib3sv == NULL && glad_glVertexAttrib3svNV != NULL) glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glad_glVertexAttrib3svNV; + if (glad_glVertexAttrib3svARB == NULL && glad_glVertexAttrib3sv != NULL) glad_glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glad_glVertexAttrib3sv; + if (glad_glVertexAttrib3svARB == NULL && glad_glVertexAttrib3svNV != NULL) glad_glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glad_glVertexAttrib3svNV; + if (glad_glVertexAttrib3svNV == NULL && glad_glVertexAttrib3sv != NULL) glad_glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glad_glVertexAttrib3sv; + if (glad_glVertexAttrib3svNV == NULL && glad_glVertexAttrib3svARB != NULL) glad_glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glad_glVertexAttrib3svARB; + if (glad_glVertexAttrib4bv == NULL && glad_glVertexAttrib4bvARB != NULL) glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glad_glVertexAttrib4bvARB; + if (glad_glVertexAttrib4bvARB == NULL && glad_glVertexAttrib4bv != NULL) glad_glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glad_glVertexAttrib4bv; + if (glad_glVertexAttrib4d == NULL && glad_glVertexAttrib4dARB != NULL) glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glad_glVertexAttrib4dARB; + if (glad_glVertexAttrib4d == NULL && glad_glVertexAttrib4dNV != NULL) glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glad_glVertexAttrib4dNV; + if (glad_glVertexAttrib4dARB == NULL && glad_glVertexAttrib4d != NULL) glad_glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glad_glVertexAttrib4d; + if (glad_glVertexAttrib4dARB == NULL && glad_glVertexAttrib4dNV != NULL) glad_glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glad_glVertexAttrib4dNV; + if (glad_glVertexAttrib4dNV == NULL && glad_glVertexAttrib4d != NULL) glad_glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glad_glVertexAttrib4d; + if (glad_glVertexAttrib4dNV == NULL && glad_glVertexAttrib4dARB != NULL) glad_glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glad_glVertexAttrib4dARB; + if (glad_glVertexAttrib4dv == NULL && glad_glVertexAttrib4dvARB != NULL) glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glad_glVertexAttrib4dvARB; + if (glad_glVertexAttrib4dv == NULL && glad_glVertexAttrib4dvNV != NULL) glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glad_glVertexAttrib4dvNV; + if (glad_glVertexAttrib4dvARB == NULL && glad_glVertexAttrib4dv != NULL) glad_glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glad_glVertexAttrib4dv; + if (glad_glVertexAttrib4dvARB == NULL && glad_glVertexAttrib4dvNV != NULL) glad_glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glad_glVertexAttrib4dvNV; + if (glad_glVertexAttrib4dvNV == NULL && glad_glVertexAttrib4dv != NULL) glad_glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glad_glVertexAttrib4dv; + if (glad_glVertexAttrib4dvNV == NULL && glad_glVertexAttrib4dvARB != NULL) glad_glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glad_glVertexAttrib4dvARB; + if (glad_glVertexAttrib4f == NULL && glad_glVertexAttrib4fARB != NULL) glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glad_glVertexAttrib4fARB; + if (glad_glVertexAttrib4f == NULL && glad_glVertexAttrib4fNV != NULL) glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glad_glVertexAttrib4fNV; + if (glad_glVertexAttrib4fARB == NULL && glad_glVertexAttrib4f != NULL) glad_glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glad_glVertexAttrib4f; + if (glad_glVertexAttrib4fARB == NULL && glad_glVertexAttrib4fNV != NULL) glad_glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glad_glVertexAttrib4fNV; + if (glad_glVertexAttrib4fNV == NULL && glad_glVertexAttrib4f != NULL) glad_glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glad_glVertexAttrib4f; + if (glad_glVertexAttrib4fNV == NULL && glad_glVertexAttrib4fARB != NULL) glad_glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glad_glVertexAttrib4fARB; + if (glad_glVertexAttrib4fv == NULL && glad_glVertexAttrib4fvARB != NULL) glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glad_glVertexAttrib4fvARB; + if (glad_glVertexAttrib4fv == NULL && glad_glVertexAttrib4fvNV != NULL) glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glad_glVertexAttrib4fvNV; + if (glad_glVertexAttrib4fvARB == NULL && glad_glVertexAttrib4fv != NULL) glad_glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glad_glVertexAttrib4fv; + if (glad_glVertexAttrib4fvARB == NULL && glad_glVertexAttrib4fvNV != NULL) glad_glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glad_glVertexAttrib4fvNV; + if (glad_glVertexAttrib4fvNV == NULL && glad_glVertexAttrib4fv != NULL) glad_glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glad_glVertexAttrib4fv; + if (glad_glVertexAttrib4fvNV == NULL && glad_glVertexAttrib4fvARB != NULL) glad_glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glad_glVertexAttrib4fvARB; + if (glad_glVertexAttrib4iv == NULL && glad_glVertexAttrib4ivARB != NULL) glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glad_glVertexAttrib4ivARB; + if (glad_glVertexAttrib4ivARB == NULL && glad_glVertexAttrib4iv != NULL) glad_glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glad_glVertexAttrib4iv; + if (glad_glVertexAttrib4Nbv == NULL && glad_glVertexAttrib4NbvARB != NULL) glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glad_glVertexAttrib4NbvARB; + if (glad_glVertexAttrib4NbvARB == NULL && glad_glVertexAttrib4Nbv != NULL) glad_glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glad_glVertexAttrib4Nbv; + if (glad_glVertexAttrib4Niv == NULL && glad_glVertexAttrib4NivARB != NULL) glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glad_glVertexAttrib4NivARB; + if (glad_glVertexAttrib4NivARB == NULL && glad_glVertexAttrib4Niv != NULL) glad_glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glad_glVertexAttrib4Niv; + if (glad_glVertexAttrib4Nsv == NULL && glad_glVertexAttrib4NsvARB != NULL) glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glad_glVertexAttrib4NsvARB; + if (glad_glVertexAttrib4NsvARB == NULL && glad_glVertexAttrib4Nsv != NULL) glad_glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glad_glVertexAttrib4Nsv; + if (glad_glVertexAttrib4Nub == NULL && glad_glVertexAttrib4NubARB != NULL) glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glad_glVertexAttrib4NubARB; + if (glad_glVertexAttrib4Nub == NULL && glad_glVertexAttrib4ubNV != NULL) glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glad_glVertexAttrib4ubNV; + if (glad_glVertexAttrib4NubARB == NULL && glad_glVertexAttrib4Nub != NULL) glad_glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glad_glVertexAttrib4Nub; + if (glad_glVertexAttrib4NubARB == NULL && glad_glVertexAttrib4ubNV != NULL) glad_glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glad_glVertexAttrib4ubNV; + if (glad_glVertexAttrib4Nubv == NULL && glad_glVertexAttrib4NubvARB != NULL) glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glad_glVertexAttrib4NubvARB; + if (glad_glVertexAttrib4Nubv == NULL && glad_glVertexAttrib4ubvNV != NULL) glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glad_glVertexAttrib4ubvNV; + if (glad_glVertexAttrib4NubvARB == NULL && glad_glVertexAttrib4Nubv != NULL) glad_glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glad_glVertexAttrib4Nubv; + if (glad_glVertexAttrib4NubvARB == NULL && glad_glVertexAttrib4ubvNV != NULL) glad_glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glad_glVertexAttrib4ubvNV; + if (glad_glVertexAttrib4Nuiv == NULL && glad_glVertexAttrib4NuivARB != NULL) glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glad_glVertexAttrib4NuivARB; + if (glad_glVertexAttrib4NuivARB == NULL && glad_glVertexAttrib4Nuiv != NULL) glad_glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glad_glVertexAttrib4Nuiv; + if (glad_glVertexAttrib4Nusv == NULL && glad_glVertexAttrib4NusvARB != NULL) glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glad_glVertexAttrib4NusvARB; + if (glad_glVertexAttrib4NusvARB == NULL && glad_glVertexAttrib4Nusv != NULL) glad_glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glad_glVertexAttrib4Nusv; + if (glad_glVertexAttrib4s == NULL && glad_glVertexAttrib4sARB != NULL) glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glad_glVertexAttrib4sARB; + if (glad_glVertexAttrib4s == NULL && glad_glVertexAttrib4sNV != NULL) glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glad_glVertexAttrib4sNV; + if (glad_glVertexAttrib4sARB == NULL && glad_glVertexAttrib4s != NULL) glad_glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glad_glVertexAttrib4s; + if (glad_glVertexAttrib4sARB == NULL && glad_glVertexAttrib4sNV != NULL) glad_glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glad_glVertexAttrib4sNV; + if (glad_glVertexAttrib4sNV == NULL && glad_glVertexAttrib4s != NULL) glad_glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glad_glVertexAttrib4s; + if (glad_glVertexAttrib4sNV == NULL && glad_glVertexAttrib4sARB != NULL) glad_glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glad_glVertexAttrib4sARB; + if (glad_glVertexAttrib4sv == NULL && glad_glVertexAttrib4svARB != NULL) glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glad_glVertexAttrib4svARB; + if (glad_glVertexAttrib4sv == NULL && glad_glVertexAttrib4svNV != NULL) glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glad_glVertexAttrib4svNV; + if (glad_glVertexAttrib4svARB == NULL && glad_glVertexAttrib4sv != NULL) glad_glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glad_glVertexAttrib4sv; + if (glad_glVertexAttrib4svARB == NULL && glad_glVertexAttrib4svNV != NULL) glad_glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glad_glVertexAttrib4svNV; + if (glad_glVertexAttrib4svNV == NULL && glad_glVertexAttrib4sv != NULL) glad_glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glad_glVertexAttrib4sv; + if (glad_glVertexAttrib4svNV == NULL && glad_glVertexAttrib4svARB != NULL) glad_glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glad_glVertexAttrib4svARB; + if (glad_glVertexAttrib4ubNV == NULL && glad_glVertexAttrib4Nub != NULL) glad_glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glad_glVertexAttrib4Nub; + if (glad_glVertexAttrib4ubNV == NULL && glad_glVertexAttrib4NubARB != NULL) glad_glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glad_glVertexAttrib4NubARB; + if (glad_glVertexAttrib4ubv == NULL && glad_glVertexAttrib4ubvARB != NULL) glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glad_glVertexAttrib4ubvARB; + if (glad_glVertexAttrib4ubvARB == NULL && glad_glVertexAttrib4ubv != NULL) glad_glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glad_glVertexAttrib4ubv; + if (glad_glVertexAttrib4ubvNV == NULL && glad_glVertexAttrib4Nubv != NULL) glad_glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glad_glVertexAttrib4Nubv; + if (glad_glVertexAttrib4ubvNV == NULL && glad_glVertexAttrib4NubvARB != NULL) glad_glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glad_glVertexAttrib4NubvARB; + if (glad_glVertexAttrib4uiv == NULL && glad_glVertexAttrib4uivARB != NULL) glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glad_glVertexAttrib4uivARB; + if (glad_glVertexAttrib4uivARB == NULL && glad_glVertexAttrib4uiv != NULL) glad_glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glad_glVertexAttrib4uiv; + if (glad_glVertexAttrib4usv == NULL && glad_glVertexAttrib4usvARB != NULL) glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glad_glVertexAttrib4usvARB; + if (glad_glVertexAttrib4usvARB == NULL && glad_glVertexAttrib4usv != NULL) glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glad_glVertexAttrib4usv; + if (glad_glVertexAttribDivisor == NULL && glad_glVertexAttribDivisorANGLE != NULL) glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glad_glVertexAttribDivisorANGLE; + if (glad_glVertexAttribDivisor == NULL && glad_glVertexAttribDivisorARB != NULL) glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glad_glVertexAttribDivisorARB; + if (glad_glVertexAttribDivisor == NULL && glad_glVertexAttribDivisorEXT != NULL) glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glad_glVertexAttribDivisorEXT; + if (glad_glVertexAttribDivisor == NULL && glad_glVertexAttribDivisorNV != NULL) glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glad_glVertexAttribDivisorNV; + if (glad_glVertexAttribDivisorANGLE == NULL && glad_glVertexAttribDivisor != NULL) glad_glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glad_glVertexAttribDivisor; + if (glad_glVertexAttribDivisorANGLE == NULL && glad_glVertexAttribDivisorARB != NULL) glad_glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glad_glVertexAttribDivisorARB; + if (glad_glVertexAttribDivisorANGLE == NULL && glad_glVertexAttribDivisorEXT != NULL) glad_glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glad_glVertexAttribDivisorEXT; + if (glad_glVertexAttribDivisorANGLE == NULL && glad_glVertexAttribDivisorNV != NULL) glad_glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glad_glVertexAttribDivisorNV; + if (glad_glVertexAttribDivisorARB == NULL && glad_glVertexAttribDivisor != NULL) glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glad_glVertexAttribDivisor; + if (glad_glVertexAttribDivisorARB == NULL && glad_glVertexAttribDivisorANGLE != NULL) glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glad_glVertexAttribDivisorANGLE; + if (glad_glVertexAttribDivisorARB == NULL && glad_glVertexAttribDivisorEXT != NULL) glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glad_glVertexAttribDivisorEXT; + if (glad_glVertexAttribDivisorARB == NULL && glad_glVertexAttribDivisorNV != NULL) glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glad_glVertexAttribDivisorNV; + if (glad_glVertexAttribDivisorEXT == NULL && glad_glVertexAttribDivisor != NULL) glad_glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glad_glVertexAttribDivisor; + if (glad_glVertexAttribDivisorEXT == NULL && glad_glVertexAttribDivisorANGLE != NULL) glad_glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glad_glVertexAttribDivisorANGLE; + if (glad_glVertexAttribDivisorEXT == NULL && glad_glVertexAttribDivisorARB != NULL) glad_glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glad_glVertexAttribDivisorARB; + if (glad_glVertexAttribDivisorEXT == NULL && glad_glVertexAttribDivisorNV != NULL) glad_glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glad_glVertexAttribDivisorNV; + if (glad_glVertexAttribDivisorNV == NULL && glad_glVertexAttribDivisor != NULL) glad_glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glad_glVertexAttribDivisor; + if (glad_glVertexAttribDivisorNV == NULL && glad_glVertexAttribDivisorANGLE != NULL) glad_glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glad_glVertexAttribDivisorANGLE; + if (glad_glVertexAttribDivisorNV == NULL && glad_glVertexAttribDivisorARB != NULL) glad_glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glad_glVertexAttribDivisorARB; + if (glad_glVertexAttribDivisorNV == NULL && glad_glVertexAttribDivisorEXT != NULL) glad_glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glad_glVertexAttribDivisorEXT; + if (glad_glVertexAttribI1i == NULL && glad_glVertexAttribI1iEXT != NULL) glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glad_glVertexAttribI1iEXT; + if (glad_glVertexAttribI1iEXT == NULL && glad_glVertexAttribI1i != NULL) glad_glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glad_glVertexAttribI1i; + if (glad_glVertexAttribI1iv == NULL && glad_glVertexAttribI1ivEXT != NULL) glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glad_glVertexAttribI1ivEXT; + if (glad_glVertexAttribI1ivEXT == NULL && glad_glVertexAttribI1iv != NULL) glad_glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glad_glVertexAttribI1iv; + if (glad_glVertexAttribI1ui == NULL && glad_glVertexAttribI1uiEXT != NULL) glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glad_glVertexAttribI1uiEXT; + if (glad_glVertexAttribI1uiEXT == NULL && glad_glVertexAttribI1ui != NULL) glad_glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glad_glVertexAttribI1ui; + if (glad_glVertexAttribI1uiv == NULL && glad_glVertexAttribI1uivEXT != NULL) glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glad_glVertexAttribI1uivEXT; + if (glad_glVertexAttribI1uivEXT == NULL && glad_glVertexAttribI1uiv != NULL) glad_glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glad_glVertexAttribI1uiv; + if (glad_glVertexAttribI2i == NULL && glad_glVertexAttribI2iEXT != NULL) glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glad_glVertexAttribI2iEXT; + if (glad_glVertexAttribI2iEXT == NULL && glad_glVertexAttribI2i != NULL) glad_glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glad_glVertexAttribI2i; + if (glad_glVertexAttribI2iv == NULL && glad_glVertexAttribI2ivEXT != NULL) glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glad_glVertexAttribI2ivEXT; + if (glad_glVertexAttribI2ivEXT == NULL && glad_glVertexAttribI2iv != NULL) glad_glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glad_glVertexAttribI2iv; + if (glad_glVertexAttribI2ui == NULL && glad_glVertexAttribI2uiEXT != NULL) glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glad_glVertexAttribI2uiEXT; + if (glad_glVertexAttribI2uiEXT == NULL && glad_glVertexAttribI2ui != NULL) glad_glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glad_glVertexAttribI2ui; + if (glad_glVertexAttribI2uiv == NULL && glad_glVertexAttribI2uivEXT != NULL) glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glad_glVertexAttribI2uivEXT; + if (glad_glVertexAttribI2uivEXT == NULL && glad_glVertexAttribI2uiv != NULL) glad_glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glad_glVertexAttribI2uiv; + if (glad_glVertexAttribI3i == NULL && glad_glVertexAttribI3iEXT != NULL) glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glad_glVertexAttribI3iEXT; + if (glad_glVertexAttribI3iEXT == NULL && glad_glVertexAttribI3i != NULL) glad_glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glad_glVertexAttribI3i; + if (glad_glVertexAttribI3iv == NULL && glad_glVertexAttribI3ivEXT != NULL) glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glad_glVertexAttribI3ivEXT; + if (glad_glVertexAttribI3ivEXT == NULL && glad_glVertexAttribI3iv != NULL) glad_glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glad_glVertexAttribI3iv; + if (glad_glVertexAttribI3ui == NULL && glad_glVertexAttribI3uiEXT != NULL) glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glad_glVertexAttribI3uiEXT; + if (glad_glVertexAttribI3uiEXT == NULL && glad_glVertexAttribI3ui != NULL) glad_glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glad_glVertexAttribI3ui; + if (glad_glVertexAttribI3uiv == NULL && glad_glVertexAttribI3uivEXT != NULL) glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glad_glVertexAttribI3uivEXT; + if (glad_glVertexAttribI3uivEXT == NULL && glad_glVertexAttribI3uiv != NULL) glad_glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glad_glVertexAttribI3uiv; + if (glad_glVertexAttribI4bv == NULL && glad_glVertexAttribI4bvEXT != NULL) glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glad_glVertexAttribI4bvEXT; + if (glad_glVertexAttribI4bvEXT == NULL && glad_glVertexAttribI4bv != NULL) glad_glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glad_glVertexAttribI4bv; + if (glad_glVertexAttribI4i == NULL && glad_glVertexAttribI4iEXT != NULL) glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glad_glVertexAttribI4iEXT; + if (glad_glVertexAttribI4iEXT == NULL && glad_glVertexAttribI4i != NULL) glad_glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glad_glVertexAttribI4i; + if (glad_glVertexAttribI4iv == NULL && glad_glVertexAttribI4ivEXT != NULL) glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glad_glVertexAttribI4ivEXT; + if (glad_glVertexAttribI4ivEXT == NULL && glad_glVertexAttribI4iv != NULL) glad_glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glad_glVertexAttribI4iv; + if (glad_glVertexAttribI4sv == NULL && glad_glVertexAttribI4svEXT != NULL) glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glad_glVertexAttribI4svEXT; + if (glad_glVertexAttribI4svEXT == NULL && glad_glVertexAttribI4sv != NULL) glad_glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glad_glVertexAttribI4sv; + if (glad_glVertexAttribI4ubv == NULL && glad_glVertexAttribI4ubvEXT != NULL) glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glad_glVertexAttribI4ubvEXT; + if (glad_glVertexAttribI4ubvEXT == NULL && glad_glVertexAttribI4ubv != NULL) glad_glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glad_glVertexAttribI4ubv; + if (glad_glVertexAttribI4ui == NULL && glad_glVertexAttribI4uiEXT != NULL) glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glad_glVertexAttribI4uiEXT; + if (glad_glVertexAttribI4uiEXT == NULL && glad_glVertexAttribI4ui != NULL) glad_glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glad_glVertexAttribI4ui; + if (glad_glVertexAttribI4uiv == NULL && glad_glVertexAttribI4uivEXT != NULL) glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glad_glVertexAttribI4uivEXT; + if (glad_glVertexAttribI4uivEXT == NULL && glad_glVertexAttribI4uiv != NULL) glad_glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glad_glVertexAttribI4uiv; + if (glad_glVertexAttribI4usv == NULL && glad_glVertexAttribI4usvEXT != NULL) glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glad_glVertexAttribI4usvEXT; + if (glad_glVertexAttribI4usvEXT == NULL && glad_glVertexAttribI4usv != NULL) glad_glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glad_glVertexAttribI4usv; + if (glad_glVertexAttribIPointer == NULL && glad_glVertexAttribIPointerEXT != NULL) glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glad_glVertexAttribIPointerEXT; + if (glad_glVertexAttribIPointerEXT == NULL && glad_glVertexAttribIPointer != NULL) glad_glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glad_glVertexAttribIPointer; + if (glad_glVertexAttribL1d == NULL && glad_glVertexAttribL1dEXT != NULL) glad_glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)glad_glVertexAttribL1dEXT; + if (glad_glVertexAttribL1dEXT == NULL && glad_glVertexAttribL1d != NULL) glad_glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC)glad_glVertexAttribL1d; + if (glad_glVertexAttribL1dv == NULL && glad_glVertexAttribL1dvEXT != NULL) glad_glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)glad_glVertexAttribL1dvEXT; + if (glad_glVertexAttribL1dvEXT == NULL && glad_glVertexAttribL1dv != NULL) glad_glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC)glad_glVertexAttribL1dv; + if (glad_glVertexAttribL2d == NULL && glad_glVertexAttribL2dEXT != NULL) glad_glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)glad_glVertexAttribL2dEXT; + if (glad_glVertexAttribL2dEXT == NULL && glad_glVertexAttribL2d != NULL) glad_glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC)glad_glVertexAttribL2d; + if (glad_glVertexAttribL2dv == NULL && glad_glVertexAttribL2dvEXT != NULL) glad_glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)glad_glVertexAttribL2dvEXT; + if (glad_glVertexAttribL2dvEXT == NULL && glad_glVertexAttribL2dv != NULL) glad_glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC)glad_glVertexAttribL2dv; + if (glad_glVertexAttribL3d == NULL && glad_glVertexAttribL3dEXT != NULL) glad_glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)glad_glVertexAttribL3dEXT; + if (glad_glVertexAttribL3dEXT == NULL && glad_glVertexAttribL3d != NULL) glad_glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC)glad_glVertexAttribL3d; + if (glad_glVertexAttribL3dv == NULL && glad_glVertexAttribL3dvEXT != NULL) glad_glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)glad_glVertexAttribL3dvEXT; + if (glad_glVertexAttribL3dvEXT == NULL && glad_glVertexAttribL3dv != NULL) glad_glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC)glad_glVertexAttribL3dv; + if (glad_glVertexAttribL4d == NULL && glad_glVertexAttribL4dEXT != NULL) glad_glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)glad_glVertexAttribL4dEXT; + if (glad_glVertexAttribL4dEXT == NULL && glad_glVertexAttribL4d != NULL) glad_glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC)glad_glVertexAttribL4d; + if (glad_glVertexAttribL4dv == NULL && glad_glVertexAttribL4dvEXT != NULL) glad_glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)glad_glVertexAttribL4dvEXT; + if (glad_glVertexAttribL4dvEXT == NULL && glad_glVertexAttribL4dv != NULL) glad_glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC)glad_glVertexAttribL4dv; + if (glad_glVertexAttribLPointer == NULL && glad_glVertexAttribLPointerEXT != NULL) glad_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)glad_glVertexAttribLPointerEXT; + if (glad_glVertexAttribLPointerEXT == NULL && glad_glVertexAttribLPointer != NULL) glad_glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC)glad_glVertexAttribLPointer; + if (glad_glVertexAttribPointer == NULL && glad_glVertexAttribPointerARB != NULL) glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glad_glVertexAttribPointerARB; + if (glad_glVertexAttribPointerARB == NULL && glad_glVertexAttribPointer != NULL) glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glad_glVertexAttribPointer; + if (glad_glViewportArrayv == NULL && glad_glViewportArrayvNV != NULL) glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glad_glViewportArrayvNV; + if (glad_glViewportArrayv == NULL && glad_glViewportArrayvOES != NULL) glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glad_glViewportArrayvOES; + if (glad_glViewportArrayvNV == NULL && glad_glViewportArrayv != NULL) glad_glViewportArrayvNV = (PFNGLVIEWPORTARRAYVNVPROC)glad_glViewportArrayv; + if (glad_glViewportArrayvNV == NULL && glad_glViewportArrayvOES != NULL) glad_glViewportArrayvNV = (PFNGLVIEWPORTARRAYVNVPROC)glad_glViewportArrayvOES; + if (glad_glViewportArrayvOES == NULL && glad_glViewportArrayv != NULL) glad_glViewportArrayvOES = (PFNGLVIEWPORTARRAYVOESPROC)glad_glViewportArrayv; + if (glad_glViewportArrayvOES == NULL && glad_glViewportArrayvNV != NULL) glad_glViewportArrayvOES = (PFNGLVIEWPORTARRAYVOESPROC)glad_glViewportArrayvNV; + if (glad_glViewportIndexedf == NULL && glad_glViewportIndexedfNV != NULL) glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glad_glViewportIndexedfNV; + if (glad_glViewportIndexedf == NULL && glad_glViewportIndexedfOES != NULL) glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glad_glViewportIndexedfOES; + if (glad_glViewportIndexedfNV == NULL && glad_glViewportIndexedf != NULL) glad_glViewportIndexedfNV = (PFNGLVIEWPORTINDEXEDFNVPROC)glad_glViewportIndexedf; + if (glad_glViewportIndexedfNV == NULL && glad_glViewportIndexedfOES != NULL) glad_glViewportIndexedfNV = (PFNGLVIEWPORTINDEXEDFNVPROC)glad_glViewportIndexedfOES; + if (glad_glViewportIndexedfOES == NULL && glad_glViewportIndexedf != NULL) glad_glViewportIndexedfOES = (PFNGLVIEWPORTINDEXEDFOESPROC)glad_glViewportIndexedf; + if (glad_glViewportIndexedfOES == NULL && glad_glViewportIndexedfNV != NULL) glad_glViewportIndexedfOES = (PFNGLVIEWPORTINDEXEDFOESPROC)glad_glViewportIndexedfNV; + if (glad_glViewportIndexedfv == NULL && glad_glViewportIndexedfvNV != NULL) glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glad_glViewportIndexedfvNV; + if (glad_glViewportIndexedfv == NULL && glad_glViewportIndexedfvOES != NULL) glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glad_glViewportIndexedfvOES; + if (glad_glViewportIndexedfvNV == NULL && glad_glViewportIndexedfv != NULL) glad_glViewportIndexedfvNV = (PFNGLVIEWPORTINDEXEDFVNVPROC)glad_glViewportIndexedfv; + if (glad_glViewportIndexedfvNV == NULL && glad_glViewportIndexedfvOES != NULL) glad_glViewportIndexedfvNV = (PFNGLVIEWPORTINDEXEDFVNVPROC)glad_glViewportIndexedfvOES; + if (glad_glViewportIndexedfvOES == NULL && glad_glViewportIndexedfv != NULL) glad_glViewportIndexedfvOES = (PFNGLVIEWPORTINDEXEDFVOESPROC)glad_glViewportIndexedfv; + if (glad_glViewportIndexedfvOES == NULL && glad_glViewportIndexedfvNV != NULL) glad_glViewportIndexedfvOES = (PFNGLVIEWPORTINDEXEDFVOESPROC)glad_glViewportIndexedfvNV; + if (glad_glWaitSync == NULL && glad_glWaitSyncAPPLE != NULL) glad_glWaitSync = (PFNGLWAITSYNCPROC)glad_glWaitSyncAPPLE; + if (glad_glWaitSyncAPPLE == NULL && glad_glWaitSync != NULL) glad_glWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC)glad_glWaitSync; + if (glad_glWindowPos2d == NULL && glad_glWindowPos2dARB != NULL) glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glad_glWindowPos2dARB; + if (glad_glWindowPos2d == NULL && glad_glWindowPos2dMESA != NULL) glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glad_glWindowPos2dMESA; + if (glad_glWindowPos2dARB == NULL && glad_glWindowPos2d != NULL) glad_glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glad_glWindowPos2d; + if (glad_glWindowPos2dARB == NULL && glad_glWindowPos2dMESA != NULL) glad_glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glad_glWindowPos2dMESA; + if (glad_glWindowPos2dMESA == NULL && glad_glWindowPos2d != NULL) glad_glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glad_glWindowPos2d; + if (glad_glWindowPos2dMESA == NULL && glad_glWindowPos2dARB != NULL) glad_glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glad_glWindowPos2dARB; + if (glad_glWindowPos2dv == NULL && glad_glWindowPos2dvARB != NULL) glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glad_glWindowPos2dvARB; + if (glad_glWindowPos2dv == NULL && glad_glWindowPos2dvMESA != NULL) glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glad_glWindowPos2dvMESA; + if (glad_glWindowPos2dvARB == NULL && glad_glWindowPos2dv != NULL) glad_glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glad_glWindowPos2dv; + if (glad_glWindowPos2dvARB == NULL && glad_glWindowPos2dvMESA != NULL) glad_glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glad_glWindowPos2dvMESA; + if (glad_glWindowPos2dvMESA == NULL && glad_glWindowPos2dv != NULL) glad_glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glad_glWindowPos2dv; + if (glad_glWindowPos2dvMESA == NULL && glad_glWindowPos2dvARB != NULL) glad_glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glad_glWindowPos2dvARB; + if (glad_glWindowPos2f == NULL && glad_glWindowPos2fARB != NULL) glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glad_glWindowPos2fARB; + if (glad_glWindowPos2f == NULL && glad_glWindowPos2fMESA != NULL) glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glad_glWindowPos2fMESA; + if (glad_glWindowPos2fARB == NULL && glad_glWindowPos2f != NULL) glad_glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glad_glWindowPos2f; + if (glad_glWindowPos2fARB == NULL && glad_glWindowPos2fMESA != NULL) glad_glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glad_glWindowPos2fMESA; + if (glad_glWindowPos2fMESA == NULL && glad_glWindowPos2f != NULL) glad_glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glad_glWindowPos2f; + if (glad_glWindowPos2fMESA == NULL && glad_glWindowPos2fARB != NULL) glad_glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glad_glWindowPos2fARB; + if (glad_glWindowPos2fv == NULL && glad_glWindowPos2fvARB != NULL) glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glad_glWindowPos2fvARB; + if (glad_glWindowPos2fv == NULL && glad_glWindowPos2fvMESA != NULL) glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glad_glWindowPos2fvMESA; + if (glad_glWindowPos2fvARB == NULL && glad_glWindowPos2fv != NULL) glad_glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glad_glWindowPos2fv; + if (glad_glWindowPos2fvARB == NULL && glad_glWindowPos2fvMESA != NULL) glad_glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glad_glWindowPos2fvMESA; + if (glad_glWindowPos2fvMESA == NULL && glad_glWindowPos2fv != NULL) glad_glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glad_glWindowPos2fv; + if (glad_glWindowPos2fvMESA == NULL && glad_glWindowPos2fvARB != NULL) glad_glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glad_glWindowPos2fvARB; + if (glad_glWindowPos2i == NULL && glad_glWindowPos2iARB != NULL) glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glad_glWindowPos2iARB; + if (glad_glWindowPos2i == NULL && glad_glWindowPos2iMESA != NULL) glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glad_glWindowPos2iMESA; + if (glad_glWindowPos2iARB == NULL && glad_glWindowPos2i != NULL) glad_glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glad_glWindowPos2i; + if (glad_glWindowPos2iARB == NULL && glad_glWindowPos2iMESA != NULL) glad_glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glad_glWindowPos2iMESA; + if (glad_glWindowPos2iMESA == NULL && glad_glWindowPos2i != NULL) glad_glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glad_glWindowPos2i; + if (glad_glWindowPos2iMESA == NULL && glad_glWindowPos2iARB != NULL) glad_glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glad_glWindowPos2iARB; + if (glad_glWindowPos2iv == NULL && glad_glWindowPos2ivARB != NULL) glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glad_glWindowPos2ivARB; + if (glad_glWindowPos2iv == NULL && glad_glWindowPos2ivMESA != NULL) glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glad_glWindowPos2ivMESA; + if (glad_glWindowPos2ivARB == NULL && glad_glWindowPos2iv != NULL) glad_glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glad_glWindowPos2iv; + if (glad_glWindowPos2ivARB == NULL && glad_glWindowPos2ivMESA != NULL) glad_glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glad_glWindowPos2ivMESA; + if (glad_glWindowPos2ivMESA == NULL && glad_glWindowPos2iv != NULL) glad_glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glad_glWindowPos2iv; + if (glad_glWindowPos2ivMESA == NULL && glad_glWindowPos2ivARB != NULL) glad_glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glad_glWindowPos2ivARB; + if (glad_glWindowPos2s == NULL && glad_glWindowPos2sARB != NULL) glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glad_glWindowPos2sARB; + if (glad_glWindowPos2s == NULL && glad_glWindowPos2sMESA != NULL) glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glad_glWindowPos2sMESA; + if (glad_glWindowPos2sARB == NULL && glad_glWindowPos2s != NULL) glad_glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glad_glWindowPos2s; + if (glad_glWindowPos2sARB == NULL && glad_glWindowPos2sMESA != NULL) glad_glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glad_glWindowPos2sMESA; + if (glad_glWindowPos2sMESA == NULL && glad_glWindowPos2s != NULL) glad_glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glad_glWindowPos2s; + if (glad_glWindowPos2sMESA == NULL && glad_glWindowPos2sARB != NULL) glad_glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glad_glWindowPos2sARB; + if (glad_glWindowPos2sv == NULL && glad_glWindowPos2svARB != NULL) glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glad_glWindowPos2svARB; + if (glad_glWindowPos2sv == NULL && glad_glWindowPos2svMESA != NULL) glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glad_glWindowPos2svMESA; + if (glad_glWindowPos2svARB == NULL && glad_glWindowPos2sv != NULL) glad_glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glad_glWindowPos2sv; + if (glad_glWindowPos2svARB == NULL && glad_glWindowPos2svMESA != NULL) glad_glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glad_glWindowPos2svMESA; + if (glad_glWindowPos2svMESA == NULL && glad_glWindowPos2sv != NULL) glad_glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glad_glWindowPos2sv; + if (glad_glWindowPos2svMESA == NULL && glad_glWindowPos2svARB != NULL) glad_glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glad_glWindowPos2svARB; + if (glad_glWindowPos3d == NULL && glad_glWindowPos3dARB != NULL) glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glad_glWindowPos3dARB; + if (glad_glWindowPos3d == NULL && glad_glWindowPos3dMESA != NULL) glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glad_glWindowPos3dMESA; + if (glad_glWindowPos3dARB == NULL && glad_glWindowPos3d != NULL) glad_glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glad_glWindowPos3d; + if (glad_glWindowPos3dARB == NULL && glad_glWindowPos3dMESA != NULL) glad_glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glad_glWindowPos3dMESA; + if (glad_glWindowPos3dMESA == NULL && glad_glWindowPos3d != NULL) glad_glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glad_glWindowPos3d; + if (glad_glWindowPos3dMESA == NULL && glad_glWindowPos3dARB != NULL) glad_glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glad_glWindowPos3dARB; + if (glad_glWindowPos3dv == NULL && glad_glWindowPos3dvARB != NULL) glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glad_glWindowPos3dvARB; + if (glad_glWindowPos3dv == NULL && glad_glWindowPos3dvMESA != NULL) glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glad_glWindowPos3dvMESA; + if (glad_glWindowPos3dvARB == NULL && glad_glWindowPos3dv != NULL) glad_glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glad_glWindowPos3dv; + if (glad_glWindowPos3dvARB == NULL && glad_glWindowPos3dvMESA != NULL) glad_glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glad_glWindowPos3dvMESA; + if (glad_glWindowPos3dvMESA == NULL && glad_glWindowPos3dv != NULL) glad_glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glad_glWindowPos3dv; + if (glad_glWindowPos3dvMESA == NULL && glad_glWindowPos3dvARB != NULL) glad_glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glad_glWindowPos3dvARB; + if (glad_glWindowPos3f == NULL && glad_glWindowPos3fARB != NULL) glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glad_glWindowPos3fARB; + if (glad_glWindowPos3f == NULL && glad_glWindowPos3fMESA != NULL) glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glad_glWindowPos3fMESA; + if (glad_glWindowPos3fARB == NULL && glad_glWindowPos3f != NULL) glad_glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glad_glWindowPos3f; + if (glad_glWindowPos3fARB == NULL && glad_glWindowPos3fMESA != NULL) glad_glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glad_glWindowPos3fMESA; + if (glad_glWindowPos3fMESA == NULL && glad_glWindowPos3f != NULL) glad_glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glad_glWindowPos3f; + if (glad_glWindowPos3fMESA == NULL && glad_glWindowPos3fARB != NULL) glad_glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glad_glWindowPos3fARB; + if (glad_glWindowPos3fv == NULL && glad_glWindowPos3fvARB != NULL) glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glad_glWindowPos3fvARB; + if (glad_glWindowPos3fv == NULL && glad_glWindowPos3fvMESA != NULL) glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glad_glWindowPos3fvMESA; + if (glad_glWindowPos3fvARB == NULL && glad_glWindowPos3fv != NULL) glad_glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glad_glWindowPos3fv; + if (glad_glWindowPos3fvARB == NULL && glad_glWindowPos3fvMESA != NULL) glad_glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glad_glWindowPos3fvMESA; + if (glad_glWindowPos3fvMESA == NULL && glad_glWindowPos3fv != NULL) glad_glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glad_glWindowPos3fv; + if (glad_glWindowPos3fvMESA == NULL && glad_glWindowPos3fvARB != NULL) glad_glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glad_glWindowPos3fvARB; + if (glad_glWindowPos3i == NULL && glad_glWindowPos3iARB != NULL) glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glad_glWindowPos3iARB; + if (glad_glWindowPos3i == NULL && glad_glWindowPos3iMESA != NULL) glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glad_glWindowPos3iMESA; + if (glad_glWindowPos3iARB == NULL && glad_glWindowPos3i != NULL) glad_glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glad_glWindowPos3i; + if (glad_glWindowPos3iARB == NULL && glad_glWindowPos3iMESA != NULL) glad_glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glad_glWindowPos3iMESA; + if (glad_glWindowPos3iMESA == NULL && glad_glWindowPos3i != NULL) glad_glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glad_glWindowPos3i; + if (glad_glWindowPos3iMESA == NULL && glad_glWindowPos3iARB != NULL) glad_glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glad_glWindowPos3iARB; + if (glad_glWindowPos3iv == NULL && glad_glWindowPos3ivARB != NULL) glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glad_glWindowPos3ivARB; + if (glad_glWindowPos3iv == NULL && glad_glWindowPos3ivMESA != NULL) glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glad_glWindowPos3ivMESA; + if (glad_glWindowPos3ivARB == NULL && glad_glWindowPos3iv != NULL) glad_glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glad_glWindowPos3iv; + if (glad_glWindowPos3ivARB == NULL && glad_glWindowPos3ivMESA != NULL) glad_glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glad_glWindowPos3ivMESA; + if (glad_glWindowPos3ivMESA == NULL && glad_glWindowPos3iv != NULL) glad_glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glad_glWindowPos3iv; + if (glad_glWindowPos3ivMESA == NULL && glad_glWindowPos3ivARB != NULL) glad_glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glad_glWindowPos3ivARB; + if (glad_glWindowPos3s == NULL && glad_glWindowPos3sARB != NULL) glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glad_glWindowPos3sARB; + if (glad_glWindowPos3s == NULL && glad_glWindowPos3sMESA != NULL) glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glad_glWindowPos3sMESA; + if (glad_glWindowPos3sARB == NULL && glad_glWindowPos3s != NULL) glad_glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glad_glWindowPos3s; + if (glad_glWindowPos3sARB == NULL && glad_glWindowPos3sMESA != NULL) glad_glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glad_glWindowPos3sMESA; + if (glad_glWindowPos3sMESA == NULL && glad_glWindowPos3s != NULL) glad_glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glad_glWindowPos3s; + if (glad_glWindowPos3sMESA == NULL && glad_glWindowPos3sARB != NULL) glad_glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glad_glWindowPos3sARB; + if (glad_glWindowPos3sv == NULL && glad_glWindowPos3svARB != NULL) glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glad_glWindowPos3svARB; + if (glad_glWindowPos3sv == NULL && glad_glWindowPos3svMESA != NULL) glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glad_glWindowPos3svMESA; + if (glad_glWindowPos3svARB == NULL && glad_glWindowPos3sv != NULL) glad_glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glad_glWindowPos3sv; + if (glad_glWindowPos3svARB == NULL && glad_glWindowPos3svMESA != NULL) glad_glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glad_glWindowPos3svMESA; + if (glad_glWindowPos3svMESA == NULL && glad_glWindowPos3sv != NULL) glad_glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glad_glWindowPos3sv; + if (glad_glWindowPos3svMESA == NULL && glad_glWindowPos3svARB != NULL) glad_glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glad_glWindowPos3svARB; +} + +static void glad_gl_free_extensions(char **exts_i) { + if (exts_i != NULL) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + free((void *) (exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } +} +static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) { +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) + if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i)); + if (exts_i == NULL) { + return 0; + } + for(index = 0; index < num_exts_i; index++) { + const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; + + char *local_str = (char*) malloc(len * sizeof(char)); + if(local_str == NULL) { + exts_i[index] = NULL; + glad_gl_free_extensions(exts_i); + return 0; + } + + memcpy(local_str, gl_str_tmp, len * sizeof(char)); + exts_i[index] = local_str; + } + exts_i[index] = NULL; + + *out_exts_i = exts_i; + + return 1; + } +#else + GLAD_UNUSED(out_exts_i); +#endif + if (glad_glGetString == NULL) { + return 0; + } + *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); + return 1; +} +static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) { + if(exts_i) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + const char *e = exts_i[index]; + if(strcmp(e, ext) == 0) { + return 1; + } + } + } else { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } + } + return 0; +} + +static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_gl_find_extensions_gl(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_GL_3DFX_multisample = glad_gl_has_extension(exts, exts_i, "GL_3DFX_multisample"); + GLAD_GL_3DFX_tbuffer = glad_gl_has_extension(exts, exts_i, "GL_3DFX_tbuffer"); + GLAD_GL_3DFX_texture_compression_FXT1 = glad_gl_has_extension(exts, exts_i, "GL_3DFX_texture_compression_FXT1"); + GLAD_GL_AMD_blend_minmax_factor = glad_gl_has_extension(exts, exts_i, "GL_AMD_blend_minmax_factor"); + GLAD_GL_AMD_conservative_depth = glad_gl_has_extension(exts, exts_i, "GL_AMD_conservative_depth"); + GLAD_GL_AMD_debug_output = glad_gl_has_extension(exts, exts_i, "GL_AMD_debug_output"); + GLAD_GL_AMD_depth_clamp_separate = glad_gl_has_extension(exts, exts_i, "GL_AMD_depth_clamp_separate"); + GLAD_GL_AMD_draw_buffers_blend = glad_gl_has_extension(exts, exts_i, "GL_AMD_draw_buffers_blend"); + GLAD_GL_AMD_framebuffer_multisample_advanced = glad_gl_has_extension(exts, exts_i, "GL_AMD_framebuffer_multisample_advanced"); + GLAD_GL_AMD_framebuffer_sample_positions = glad_gl_has_extension(exts, exts_i, "GL_AMD_framebuffer_sample_positions"); + GLAD_GL_AMD_gcn_shader = glad_gl_has_extension(exts, exts_i, "GL_AMD_gcn_shader"); + GLAD_GL_AMD_gpu_shader_half_float = glad_gl_has_extension(exts, exts_i, "GL_AMD_gpu_shader_half_float"); + GLAD_GL_AMD_gpu_shader_int16 = glad_gl_has_extension(exts, exts_i, "GL_AMD_gpu_shader_int16"); + GLAD_GL_AMD_gpu_shader_int64 = glad_gl_has_extension(exts, exts_i, "GL_AMD_gpu_shader_int64"); + GLAD_GL_AMD_interleaved_elements = glad_gl_has_extension(exts, exts_i, "GL_AMD_interleaved_elements"); + GLAD_GL_AMD_multi_draw_indirect = glad_gl_has_extension(exts, exts_i, "GL_AMD_multi_draw_indirect"); + GLAD_GL_AMD_name_gen_delete = glad_gl_has_extension(exts, exts_i, "GL_AMD_name_gen_delete"); + GLAD_GL_AMD_occlusion_query_event = glad_gl_has_extension(exts, exts_i, "GL_AMD_occlusion_query_event"); + GLAD_GL_AMD_performance_monitor = glad_gl_has_extension(exts, exts_i, "GL_AMD_performance_monitor"); + GLAD_GL_AMD_pinned_memory = glad_gl_has_extension(exts, exts_i, "GL_AMD_pinned_memory"); + GLAD_GL_AMD_query_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_AMD_query_buffer_object"); + GLAD_GL_AMD_sample_positions = glad_gl_has_extension(exts, exts_i, "GL_AMD_sample_positions"); + GLAD_GL_AMD_seamless_cubemap_per_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_seamless_cubemap_per_texture"); + GLAD_GL_AMD_shader_atomic_counter_ops = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_atomic_counter_ops"); + GLAD_GL_AMD_shader_ballot = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_ballot"); + GLAD_GL_AMD_shader_explicit_vertex_parameter = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_explicit_vertex_parameter"); + GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_gpu_shader_half_float_fetch"); + GLAD_GL_AMD_shader_image_load_store_lod = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_image_load_store_lod"); + GLAD_GL_AMD_shader_stencil_export = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_stencil_export"); + GLAD_GL_AMD_shader_trinary_minmax = glad_gl_has_extension(exts, exts_i, "GL_AMD_shader_trinary_minmax"); + GLAD_GL_AMD_sparse_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_sparse_texture"); + GLAD_GL_AMD_stencil_operation_extended = glad_gl_has_extension(exts, exts_i, "GL_AMD_stencil_operation_extended"); + GLAD_GL_AMD_texture_gather_bias_lod = glad_gl_has_extension(exts, exts_i, "GL_AMD_texture_gather_bias_lod"); + GLAD_GL_AMD_texture_texture4 = glad_gl_has_extension(exts, exts_i, "GL_AMD_texture_texture4"); + GLAD_GL_AMD_transform_feedback3_lines_triangles = glad_gl_has_extension(exts, exts_i, "GL_AMD_transform_feedback3_lines_triangles"); + GLAD_GL_AMD_transform_feedback4 = glad_gl_has_extension(exts, exts_i, "GL_AMD_transform_feedback4"); + GLAD_GL_AMD_vertex_shader_layer = glad_gl_has_extension(exts, exts_i, "GL_AMD_vertex_shader_layer"); + GLAD_GL_AMD_vertex_shader_tessellator = glad_gl_has_extension(exts, exts_i, "GL_AMD_vertex_shader_tessellator"); + GLAD_GL_AMD_vertex_shader_viewport_index = glad_gl_has_extension(exts, exts_i, "GL_AMD_vertex_shader_viewport_index"); + GLAD_GL_APPLE_aux_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_APPLE_aux_depth_stencil"); + GLAD_GL_APPLE_client_storage = glad_gl_has_extension(exts, exts_i, "GL_APPLE_client_storage"); + GLAD_GL_APPLE_element_array = glad_gl_has_extension(exts, exts_i, "GL_APPLE_element_array"); + GLAD_GL_APPLE_fence = glad_gl_has_extension(exts, exts_i, "GL_APPLE_fence"); + GLAD_GL_APPLE_float_pixels = glad_gl_has_extension(exts, exts_i, "GL_APPLE_float_pixels"); + GLAD_GL_APPLE_flush_buffer_range = glad_gl_has_extension(exts, exts_i, "GL_APPLE_flush_buffer_range"); + GLAD_GL_APPLE_object_purgeable = glad_gl_has_extension(exts, exts_i, "GL_APPLE_object_purgeable"); + GLAD_GL_APPLE_rgb_422 = glad_gl_has_extension(exts, exts_i, "GL_APPLE_rgb_422"); + GLAD_GL_APPLE_row_bytes = glad_gl_has_extension(exts, exts_i, "GL_APPLE_row_bytes"); + GLAD_GL_APPLE_specular_vector = glad_gl_has_extension(exts, exts_i, "GL_APPLE_specular_vector"); + GLAD_GL_APPLE_texture_range = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_range"); + GLAD_GL_APPLE_transform_hint = glad_gl_has_extension(exts, exts_i, "GL_APPLE_transform_hint"); + GLAD_GL_APPLE_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_APPLE_vertex_array_object"); + GLAD_GL_APPLE_vertex_array_range = glad_gl_has_extension(exts, exts_i, "GL_APPLE_vertex_array_range"); + GLAD_GL_APPLE_vertex_program_evaluators = glad_gl_has_extension(exts, exts_i, "GL_APPLE_vertex_program_evaluators"); + GLAD_GL_APPLE_ycbcr_422 = glad_gl_has_extension(exts, exts_i, "GL_APPLE_ycbcr_422"); + GLAD_GL_ARB_ES2_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_ES2_compatibility"); + GLAD_GL_ARB_ES3_1_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_ES3_1_compatibility"); + GLAD_GL_ARB_ES3_2_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_ES3_2_compatibility"); + GLAD_GL_ARB_ES3_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_ES3_compatibility"); + GLAD_GL_ARB_arrays_of_arrays = glad_gl_has_extension(exts, exts_i, "GL_ARB_arrays_of_arrays"); + GLAD_GL_ARB_base_instance = glad_gl_has_extension(exts, exts_i, "GL_ARB_base_instance"); + GLAD_GL_ARB_bindless_texture = glad_gl_has_extension(exts, exts_i, "GL_ARB_bindless_texture"); + GLAD_GL_ARB_blend_func_extended = glad_gl_has_extension(exts, exts_i, "GL_ARB_blend_func_extended"); + GLAD_GL_ARB_buffer_storage = glad_gl_has_extension(exts, exts_i, "GL_ARB_buffer_storage"); + GLAD_GL_ARB_cl_event = glad_gl_has_extension(exts, exts_i, "GL_ARB_cl_event"); + GLAD_GL_ARB_clear_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_clear_buffer_object"); + GLAD_GL_ARB_clear_texture = glad_gl_has_extension(exts, exts_i, "GL_ARB_clear_texture"); + GLAD_GL_ARB_clip_control = glad_gl_has_extension(exts, exts_i, "GL_ARB_clip_control"); + GLAD_GL_ARB_color_buffer_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_color_buffer_float"); + GLAD_GL_ARB_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_compatibility"); + GLAD_GL_ARB_compressed_texture_pixel_storage = glad_gl_has_extension(exts, exts_i, "GL_ARB_compressed_texture_pixel_storage"); + GLAD_GL_ARB_compute_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_compute_shader"); + GLAD_GL_ARB_compute_variable_group_size = glad_gl_has_extension(exts, exts_i, "GL_ARB_compute_variable_group_size"); + GLAD_GL_ARB_conditional_render_inverted = glad_gl_has_extension(exts, exts_i, "GL_ARB_conditional_render_inverted"); + GLAD_GL_ARB_conservative_depth = glad_gl_has_extension(exts, exts_i, "GL_ARB_conservative_depth"); + GLAD_GL_ARB_copy_buffer = glad_gl_has_extension(exts, exts_i, "GL_ARB_copy_buffer"); + GLAD_GL_ARB_copy_image = glad_gl_has_extension(exts, exts_i, "GL_ARB_copy_image"); + GLAD_GL_ARB_cull_distance = glad_gl_has_extension(exts, exts_i, "GL_ARB_cull_distance"); + GLAD_GL_ARB_debug_output = glad_gl_has_extension(exts, exts_i, "GL_ARB_debug_output"); + GLAD_GL_ARB_depth_buffer_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_depth_buffer_float"); + GLAD_GL_ARB_depth_clamp = glad_gl_has_extension(exts, exts_i, "GL_ARB_depth_clamp"); + GLAD_GL_ARB_depth_texture = glad_gl_has_extension(exts, exts_i, "GL_ARB_depth_texture"); + GLAD_GL_ARB_derivative_control = glad_gl_has_extension(exts, exts_i, "GL_ARB_derivative_control"); + GLAD_GL_ARB_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_ARB_direct_state_access"); + GLAD_GL_ARB_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_ARB_draw_buffers"); + GLAD_GL_ARB_draw_buffers_blend = glad_gl_has_extension(exts, exts_i, "GL_ARB_draw_buffers_blend"); + GLAD_GL_ARB_draw_elements_base_vertex = glad_gl_has_extension(exts, exts_i, "GL_ARB_draw_elements_base_vertex"); + GLAD_GL_ARB_draw_indirect = glad_gl_has_extension(exts, exts_i, "GL_ARB_draw_indirect"); + GLAD_GL_ARB_draw_instanced = glad_gl_has_extension(exts, exts_i, "GL_ARB_draw_instanced"); + GLAD_GL_ARB_enhanced_layouts = glad_gl_has_extension(exts, exts_i, "GL_ARB_enhanced_layouts"); + GLAD_GL_ARB_explicit_attrib_location = glad_gl_has_extension(exts, exts_i, "GL_ARB_explicit_attrib_location"); + GLAD_GL_ARB_explicit_uniform_location = glad_gl_has_extension(exts, exts_i, "GL_ARB_explicit_uniform_location"); + GLAD_GL_ARB_fragment_coord_conventions = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_coord_conventions"); + GLAD_GL_ARB_fragment_layer_viewport = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_layer_viewport"); + GLAD_GL_ARB_fragment_program = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_program"); + GLAD_GL_ARB_fragment_program_shadow = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_program_shadow"); + GLAD_GL_ARB_fragment_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_shader"); + GLAD_GL_ARB_fragment_shader_interlock = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_shader_interlock"); + GLAD_GL_ARB_framebuffer_no_attachments = glad_gl_has_extension(exts, exts_i, "GL_ARB_framebuffer_no_attachments"); + GLAD_GL_ARB_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_framebuffer_object"); + GLAD_GL_ARB_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_ARB_framebuffer_sRGB"); + GLAD_GL_ARB_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_ARB_geometry_shader4"); + GLAD_GL_ARB_get_program_binary = glad_gl_has_extension(exts, exts_i, "GL_ARB_get_program_binary"); + GLAD_GL_ARB_get_texture_sub_image = glad_gl_has_extension(exts, exts_i, "GL_ARB_get_texture_sub_image"); + GLAD_GL_ARB_gl_spirv = glad_gl_has_extension(exts, exts_i, "GL_ARB_gl_spirv"); + GLAD_GL_ARB_gpu_shader5 = glad_gl_has_extension(exts, exts_i, "GL_ARB_gpu_shader5"); + GLAD_GL_ARB_gpu_shader_fp64 = glad_gl_has_extension(exts, exts_i, "GL_ARB_gpu_shader_fp64"); + GLAD_GL_ARB_gpu_shader_int64 = glad_gl_has_extension(exts, exts_i, "GL_ARB_gpu_shader_int64"); + GLAD_GL_ARB_half_float_pixel = glad_gl_has_extension(exts, exts_i, "GL_ARB_half_float_pixel"); + GLAD_GL_ARB_half_float_vertex = glad_gl_has_extension(exts, exts_i, "GL_ARB_half_float_vertex"); + GLAD_GL_ARB_imaging = glad_gl_has_extension(exts, exts_i, "GL_ARB_imaging"); + GLAD_GL_ARB_indirect_parameters = glad_gl_has_extension(exts, exts_i, "GL_ARB_indirect_parameters"); + GLAD_GL_ARB_instanced_arrays = glad_gl_has_extension(exts, exts_i, "GL_ARB_instanced_arrays"); + GLAD_GL_ARB_internalformat_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_internalformat_query"); + GLAD_GL_ARB_internalformat_query2 = glad_gl_has_extension(exts, exts_i, "GL_ARB_internalformat_query2"); + GLAD_GL_ARB_invalidate_subdata = glad_gl_has_extension(exts, exts_i, "GL_ARB_invalidate_subdata"); + GLAD_GL_ARB_map_buffer_alignment = glad_gl_has_extension(exts, exts_i, "GL_ARB_map_buffer_alignment"); + GLAD_GL_ARB_map_buffer_range = glad_gl_has_extension(exts, exts_i, "GL_ARB_map_buffer_range"); + GLAD_GL_ARB_matrix_palette = glad_gl_has_extension(exts, exts_i, "GL_ARB_matrix_palette"); + GLAD_GL_ARB_multi_bind = glad_gl_has_extension(exts, exts_i, "GL_ARB_multi_bind"); + GLAD_GL_ARB_multi_draw_indirect = glad_gl_has_extension(exts, exts_i, "GL_ARB_multi_draw_indirect"); + GLAD_GL_ARB_multisample = glad_gl_has_extension(exts, exts_i, "GL_ARB_multisample"); + GLAD_GL_ARB_multitexture = glad_gl_has_extension(exts, exts_i, "GL_ARB_multitexture"); + GLAD_GL_ARB_occlusion_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_occlusion_query"); + GLAD_GL_ARB_occlusion_query2 = glad_gl_has_extension(exts, exts_i, "GL_ARB_occlusion_query2"); + GLAD_GL_ARB_parallel_shader_compile = glad_gl_has_extension(exts, exts_i, "GL_ARB_parallel_shader_compile"); + GLAD_GL_ARB_pipeline_statistics_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_pipeline_statistics_query"); + GLAD_GL_ARB_pixel_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_pixel_buffer_object"); + GLAD_GL_ARB_point_parameters = glad_gl_has_extension(exts, exts_i, "GL_ARB_point_parameters"); + GLAD_GL_ARB_point_sprite = glad_gl_has_extension(exts, exts_i, "GL_ARB_point_sprite"); + GLAD_GL_ARB_polygon_offset_clamp = glad_gl_has_extension(exts, exts_i, "GL_ARB_polygon_offset_clamp"); + GLAD_GL_ARB_post_depth_coverage = glad_gl_has_extension(exts, exts_i, "GL_ARB_post_depth_coverage"); + GLAD_GL_ARB_program_interface_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_program_interface_query"); + GLAD_GL_ARB_provoking_vertex = glad_gl_has_extension(exts, exts_i, "GL_ARB_provoking_vertex"); + GLAD_GL_ARB_query_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_query_buffer_object"); + GLAD_GL_ARB_robust_buffer_access_behavior = glad_gl_has_extension(exts, exts_i, "GL_ARB_robust_buffer_access_behavior"); + GLAD_GL_ARB_robustness = glad_gl_has_extension(exts, exts_i, "GL_ARB_robustness"); + GLAD_GL_ARB_robustness_isolation = glad_gl_has_extension(exts, exts_i, "GL_ARB_robustness_isolation"); + GLAD_GL_ARB_sample_locations = glad_gl_has_extension(exts, exts_i, "GL_ARB_sample_locations"); + GLAD_GL_ARB_sample_shading = glad_gl_has_extension(exts, exts_i, "GL_ARB_sample_shading"); + GLAD_GL_ARB_sampler_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_sampler_objects"); + GLAD_GL_ARB_seamless_cube_map = glad_gl_has_extension(exts, exts_i, "GL_ARB_seamless_cube_map"); + GLAD_GL_ARB_seamless_cubemap_per_texture = glad_gl_has_extension(exts, exts_i, "GL_ARB_seamless_cubemap_per_texture"); + GLAD_GL_ARB_separate_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_separate_shader_objects"); + GLAD_GL_ARB_shader_atomic_counter_ops = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_atomic_counter_ops"); + GLAD_GL_ARB_shader_atomic_counters = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_atomic_counters"); + GLAD_GL_ARB_shader_ballot = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_ballot"); + GLAD_GL_ARB_shader_bit_encoding = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_bit_encoding"); + GLAD_GL_ARB_shader_clock = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_clock"); + GLAD_GL_ARB_shader_draw_parameters = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_draw_parameters"); + GLAD_GL_ARB_shader_group_vote = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_group_vote"); + GLAD_GL_ARB_shader_image_load_store = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_image_load_store"); + GLAD_GL_ARB_shader_image_size = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_image_size"); + GLAD_GL_ARB_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_objects"); + GLAD_GL_ARB_shader_precision = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_precision"); + GLAD_GL_ARB_shader_stencil_export = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_stencil_export"); + GLAD_GL_ARB_shader_storage_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_storage_buffer_object"); + GLAD_GL_ARB_shader_subroutine = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_subroutine"); + GLAD_GL_ARB_shader_texture_image_samples = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_texture_image_samples"); + GLAD_GL_ARB_shader_texture_lod = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_texture_lod"); + GLAD_GL_ARB_shader_viewport_layer_array = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_viewport_layer_array"); + GLAD_GL_ARB_shading_language_100 = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_100"); + GLAD_GL_ARB_shading_language_420pack = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_420pack"); + GLAD_GL_ARB_shading_language_include = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_include"); + GLAD_GL_ARB_shading_language_packing = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_packing"); + GLAD_GL_ARB_shadow = glad_gl_has_extension(exts, exts_i, "GL_ARB_shadow"); + GLAD_GL_ARB_shadow_ambient = glad_gl_has_extension(exts, exts_i, "GL_ARB_shadow_ambient"); + GLAD_GL_ARB_sparse_buffer = glad_gl_has_extension(exts, exts_i, "GL_ARB_sparse_buffer"); + GLAD_GL_ARB_sparse_texture = glad_gl_has_extension(exts, exts_i, "GL_ARB_sparse_texture"); + GLAD_GL_ARB_sparse_texture2 = glad_gl_has_extension(exts, exts_i, "GL_ARB_sparse_texture2"); + GLAD_GL_ARB_sparse_texture_clamp = glad_gl_has_extension(exts, exts_i, "GL_ARB_sparse_texture_clamp"); + GLAD_GL_ARB_spirv_extensions = glad_gl_has_extension(exts, exts_i, "GL_ARB_spirv_extensions"); + GLAD_GL_ARB_stencil_texturing = glad_gl_has_extension(exts, exts_i, "GL_ARB_stencil_texturing"); + GLAD_GL_ARB_sync = glad_gl_has_extension(exts, exts_i, "GL_ARB_sync"); + GLAD_GL_ARB_tessellation_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_tessellation_shader"); + GLAD_GL_ARB_texture_barrier = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_barrier"); + GLAD_GL_ARB_texture_border_clamp = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_border_clamp"); + GLAD_GL_ARB_texture_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_buffer_object"); + GLAD_GL_ARB_texture_buffer_object_rgb32 = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_buffer_object_rgb32"); + GLAD_GL_ARB_texture_buffer_range = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_buffer_range"); + GLAD_GL_ARB_texture_compression = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_compression"); + GLAD_GL_ARB_texture_compression_bptc = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_compression_bptc"); + GLAD_GL_ARB_texture_compression_rgtc = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_compression_rgtc"); + GLAD_GL_ARB_texture_cube_map = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_cube_map"); + GLAD_GL_ARB_texture_cube_map_array = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_cube_map_array"); + GLAD_GL_ARB_texture_env_add = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_env_add"); + GLAD_GL_ARB_texture_env_combine = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_env_combine"); + GLAD_GL_ARB_texture_env_crossbar = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_env_crossbar"); + GLAD_GL_ARB_texture_env_dot3 = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_env_dot3"); + GLAD_GL_ARB_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_filter_anisotropic"); + GLAD_GL_ARB_texture_filter_minmax = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_filter_minmax"); + GLAD_GL_ARB_texture_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_float"); + GLAD_GL_ARB_texture_gather = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_gather"); + GLAD_GL_ARB_texture_mirror_clamp_to_edge = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_mirror_clamp_to_edge"); + GLAD_GL_ARB_texture_mirrored_repeat = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_mirrored_repeat"); + GLAD_GL_ARB_texture_multisample = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_multisample"); + GLAD_GL_ARB_texture_non_power_of_two = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_non_power_of_two"); + GLAD_GL_ARB_texture_query_levels = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_query_levels"); + GLAD_GL_ARB_texture_query_lod = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_query_lod"); + GLAD_GL_ARB_texture_rectangle = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rectangle"); + GLAD_GL_ARB_texture_rg = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rg"); + GLAD_GL_ARB_texture_rgb10_a2ui = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rgb10_a2ui"); + GLAD_GL_ARB_texture_stencil8 = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_stencil8"); + GLAD_GL_ARB_texture_storage = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_storage"); + GLAD_GL_ARB_texture_storage_multisample = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_storage_multisample"); + GLAD_GL_ARB_texture_swizzle = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_swizzle"); + GLAD_GL_ARB_texture_view = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_view"); + GLAD_GL_ARB_timer_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_timer_query"); + GLAD_GL_ARB_transform_feedback2 = glad_gl_has_extension(exts, exts_i, "GL_ARB_transform_feedback2"); + GLAD_GL_ARB_transform_feedback3 = glad_gl_has_extension(exts, exts_i, "GL_ARB_transform_feedback3"); + GLAD_GL_ARB_transform_feedback_instanced = glad_gl_has_extension(exts, exts_i, "GL_ARB_transform_feedback_instanced"); + GLAD_GL_ARB_transform_feedback_overflow_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_transform_feedback_overflow_query"); + GLAD_GL_ARB_transpose_matrix = glad_gl_has_extension(exts, exts_i, "GL_ARB_transpose_matrix"); + GLAD_GL_ARB_uniform_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_uniform_buffer_object"); + GLAD_GL_ARB_vertex_array_bgra = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_array_bgra"); + GLAD_GL_ARB_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_array_object"); + GLAD_GL_ARB_vertex_attrib_64bit = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_attrib_64bit"); + GLAD_GL_ARB_vertex_attrib_binding = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_attrib_binding"); + GLAD_GL_ARB_vertex_blend = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_blend"); + GLAD_GL_ARB_vertex_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_buffer_object"); + GLAD_GL_ARB_vertex_program = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_program"); + GLAD_GL_ARB_vertex_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_shader"); + GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_type_10f_11f_11f_rev"); + GLAD_GL_ARB_vertex_type_2_10_10_10_rev = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_type_2_10_10_10_rev"); + GLAD_GL_ARB_viewport_array = glad_gl_has_extension(exts, exts_i, "GL_ARB_viewport_array"); + GLAD_GL_ARB_window_pos = glad_gl_has_extension(exts, exts_i, "GL_ARB_window_pos"); + GLAD_GL_ATI_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_ATI_draw_buffers"); + GLAD_GL_ATI_element_array = glad_gl_has_extension(exts, exts_i, "GL_ATI_element_array"); + GLAD_GL_ATI_envmap_bumpmap = glad_gl_has_extension(exts, exts_i, "GL_ATI_envmap_bumpmap"); + GLAD_GL_ATI_fragment_shader = glad_gl_has_extension(exts, exts_i, "GL_ATI_fragment_shader"); + GLAD_GL_ATI_map_object_buffer = glad_gl_has_extension(exts, exts_i, "GL_ATI_map_object_buffer"); + GLAD_GL_ATI_meminfo = glad_gl_has_extension(exts, exts_i, "GL_ATI_meminfo"); + GLAD_GL_ATI_pixel_format_float = glad_gl_has_extension(exts, exts_i, "GL_ATI_pixel_format_float"); + GLAD_GL_ATI_pn_triangles = glad_gl_has_extension(exts, exts_i, "GL_ATI_pn_triangles"); + GLAD_GL_ATI_separate_stencil = glad_gl_has_extension(exts, exts_i, "GL_ATI_separate_stencil"); + GLAD_GL_ATI_text_fragment_shader = glad_gl_has_extension(exts, exts_i, "GL_ATI_text_fragment_shader"); + GLAD_GL_ATI_texture_env_combine3 = glad_gl_has_extension(exts, exts_i, "GL_ATI_texture_env_combine3"); + GLAD_GL_ATI_texture_float = glad_gl_has_extension(exts, exts_i, "GL_ATI_texture_float"); + GLAD_GL_ATI_texture_mirror_once = glad_gl_has_extension(exts, exts_i, "GL_ATI_texture_mirror_once"); + GLAD_GL_ATI_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_ATI_vertex_array_object"); + GLAD_GL_ATI_vertex_attrib_array_object = glad_gl_has_extension(exts, exts_i, "GL_ATI_vertex_attrib_array_object"); + GLAD_GL_ATI_vertex_streams = glad_gl_has_extension(exts, exts_i, "GL_ATI_vertex_streams"); + GLAD_GL_EXT_422_pixels = glad_gl_has_extension(exts, exts_i, "GL_EXT_422_pixels"); + GLAD_GL_EXT_EGL_image_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_storage"); + GLAD_GL_EXT_EGL_sync = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_sync"); + GLAD_GL_EXT_abgr = glad_gl_has_extension(exts, exts_i, "GL_EXT_abgr"); + GLAD_GL_EXT_bgra = glad_gl_has_extension(exts, exts_i, "GL_EXT_bgra"); + GLAD_GL_EXT_bindable_uniform = glad_gl_has_extension(exts, exts_i, "GL_EXT_bindable_uniform"); + GLAD_GL_EXT_blend_color = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_color"); + GLAD_GL_EXT_blend_equation_separate = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_equation_separate"); + GLAD_GL_EXT_blend_func_separate = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_func_separate"); + GLAD_GL_EXT_blend_logic_op = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_logic_op"); + GLAD_GL_EXT_blend_minmax = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_minmax"); + GLAD_GL_EXT_blend_subtract = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_subtract"); + GLAD_GL_EXT_clip_volume_hint = glad_gl_has_extension(exts, exts_i, "GL_EXT_clip_volume_hint"); + GLAD_GL_EXT_cmyka = glad_gl_has_extension(exts, exts_i, "GL_EXT_cmyka"); + GLAD_GL_EXT_color_subtable = glad_gl_has_extension(exts, exts_i, "GL_EXT_color_subtable"); + GLAD_GL_EXT_compiled_vertex_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_compiled_vertex_array"); + GLAD_GL_EXT_convolution = glad_gl_has_extension(exts, exts_i, "GL_EXT_convolution"); + GLAD_GL_EXT_coordinate_frame = glad_gl_has_extension(exts, exts_i, "GL_EXT_coordinate_frame"); + GLAD_GL_EXT_copy_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_copy_texture"); + GLAD_GL_EXT_cull_vertex = glad_gl_has_extension(exts, exts_i, "GL_EXT_cull_vertex"); + GLAD_GL_EXT_debug_label = glad_gl_has_extension(exts, exts_i, "GL_EXT_debug_label"); + GLAD_GL_EXT_debug_marker = glad_gl_has_extension(exts, exts_i, "GL_EXT_debug_marker"); + GLAD_GL_EXT_depth_bounds_test = glad_gl_has_extension(exts, exts_i, "GL_EXT_depth_bounds_test"); + GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access"); + GLAD_GL_EXT_draw_buffers2 = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_buffers2"); + GLAD_GL_EXT_draw_instanced = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_instanced"); + GLAD_GL_EXT_draw_range_elements = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_range_elements"); + GLAD_GL_EXT_external_buffer = glad_gl_has_extension(exts, exts_i, "GL_EXT_external_buffer"); + GLAD_GL_EXT_fog_coord = glad_gl_has_extension(exts, exts_i, "GL_EXT_fog_coord"); + GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit"); + GLAD_GL_EXT_framebuffer_blit_layers = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit_layers"); + GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample"); + GLAD_GL_EXT_framebuffer_multisample_blit_scaled = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample_blit_scaled"); + GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_object"); + GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_sRGB"); + GLAD_GL_EXT_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_shader4"); + GLAD_GL_EXT_gpu_program_parameters = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_program_parameters"); + GLAD_GL_EXT_gpu_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_shader4"); + GLAD_GL_EXT_histogram = glad_gl_has_extension(exts, exts_i, "GL_EXT_histogram"); + GLAD_GL_EXT_index_array_formats = glad_gl_has_extension(exts, exts_i, "GL_EXT_index_array_formats"); + GLAD_GL_EXT_index_func = glad_gl_has_extension(exts, exts_i, "GL_EXT_index_func"); + GLAD_GL_EXT_index_material = glad_gl_has_extension(exts, exts_i, "GL_EXT_index_material"); + GLAD_GL_EXT_index_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_index_texture"); + GLAD_GL_EXT_light_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_light_texture"); + GLAD_GL_EXT_memory_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object"); + GLAD_GL_EXT_memory_object_fd = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object_fd"); + GLAD_GL_EXT_memory_object_win32 = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object_win32"); + GLAD_GL_EXT_misc_attribute = glad_gl_has_extension(exts, exts_i, "GL_EXT_misc_attribute"); + GLAD_GL_EXT_multi_draw_arrays = glad_gl_has_extension(exts, exts_i, "GL_EXT_multi_draw_arrays"); + GLAD_GL_EXT_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisample"); + GLAD_GL_EXT_multiview_tessellation_geometry_shader = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_tessellation_geometry_shader"); + GLAD_GL_EXT_multiview_texture_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_texture_multisample"); + GLAD_GL_EXT_multiview_timer_query = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_timer_query"); + GLAD_GL_EXT_packed_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_EXT_packed_depth_stencil"); + GLAD_GL_EXT_packed_float = glad_gl_has_extension(exts, exts_i, "GL_EXT_packed_float"); + GLAD_GL_EXT_packed_pixels = glad_gl_has_extension(exts, exts_i, "GL_EXT_packed_pixels"); + GLAD_GL_EXT_paletted_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_paletted_texture"); + GLAD_GL_EXT_pixel_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_pixel_buffer_object"); + GLAD_GL_EXT_pixel_transform = glad_gl_has_extension(exts, exts_i, "GL_EXT_pixel_transform"); + GLAD_GL_EXT_pixel_transform_color_table = glad_gl_has_extension(exts, exts_i, "GL_EXT_pixel_transform_color_table"); + GLAD_GL_EXT_point_parameters = glad_gl_has_extension(exts, exts_i, "GL_EXT_point_parameters"); + GLAD_GL_EXT_polygon_offset = glad_gl_has_extension(exts, exts_i, "GL_EXT_polygon_offset"); + GLAD_GL_EXT_polygon_offset_clamp = glad_gl_has_extension(exts, exts_i, "GL_EXT_polygon_offset_clamp"); + GLAD_GL_EXT_post_depth_coverage = glad_gl_has_extension(exts, exts_i, "GL_EXT_post_depth_coverage"); + GLAD_GL_EXT_provoking_vertex = glad_gl_has_extension(exts, exts_i, "GL_EXT_provoking_vertex"); + GLAD_GL_EXT_raster_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_raster_multisample"); + GLAD_GL_EXT_rescale_normal = glad_gl_has_extension(exts, exts_i, "GL_EXT_rescale_normal"); + GLAD_GL_EXT_secondary_color = glad_gl_has_extension(exts, exts_i, "GL_EXT_secondary_color"); + GLAD_GL_EXT_semaphore = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore"); + GLAD_GL_EXT_semaphore_fd = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore_fd"); + GLAD_GL_EXT_semaphore_win32 = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore_win32"); + GLAD_GL_EXT_separate_specular_color = glad_gl_has_extension(exts, exts_i, "GL_EXT_separate_specular_color"); + GLAD_GL_EXT_shader_framebuffer_fetch = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_framebuffer_fetch"); + GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_framebuffer_fetch_non_coherent"); + GLAD_GL_EXT_shader_image_load_formatted = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_image_load_formatted"); + GLAD_GL_EXT_shader_image_load_store = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_image_load_store"); + GLAD_GL_EXT_shader_integer_mix = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_integer_mix"); + GLAD_GL_EXT_shader_samples_identical = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_samples_identical"); + GLAD_GL_EXT_shadow_funcs = glad_gl_has_extension(exts, exts_i, "GL_EXT_shadow_funcs"); + GLAD_GL_EXT_shared_texture_palette = glad_gl_has_extension(exts, exts_i, "GL_EXT_shared_texture_palette"); + GLAD_GL_EXT_sparse_texture2 = glad_gl_has_extension(exts, exts_i, "GL_EXT_sparse_texture2"); + GLAD_GL_EXT_stencil_clear_tag = glad_gl_has_extension(exts, exts_i, "GL_EXT_stencil_clear_tag"); + GLAD_GL_EXT_stencil_two_side = glad_gl_has_extension(exts, exts_i, "GL_EXT_stencil_two_side"); + GLAD_GL_EXT_stencil_wrap = glad_gl_has_extension(exts, exts_i, "GL_EXT_stencil_wrap"); + GLAD_GL_EXT_subtexture = glad_gl_has_extension(exts, exts_i, "GL_EXT_subtexture"); + GLAD_GL_EXT_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture"); + GLAD_GL_EXT_texture3D = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture3D"); + GLAD_GL_EXT_texture_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_array"); + GLAD_GL_EXT_texture_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_buffer_object"); + GLAD_GL_EXT_texture_compression_latc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_latc"); + GLAD_GL_EXT_texture_compression_rgtc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_rgtc"); + GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc"); + GLAD_GL_EXT_texture_cube_map = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_cube_map"); + GLAD_GL_EXT_texture_env_add = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_env_add"); + GLAD_GL_EXT_texture_env_combine = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_env_combine"); + GLAD_GL_EXT_texture_env_dot3 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_env_dot3"); + GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_anisotropic"); + GLAD_GL_EXT_texture_filter_minmax = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_minmax"); + GLAD_GL_EXT_texture_integer = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_integer"); + GLAD_GL_EXT_texture_lod_bias = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_lod_bias"); + GLAD_GL_EXT_texture_mirror_clamp = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_mirror_clamp"); + GLAD_GL_EXT_texture_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_object"); + GLAD_GL_EXT_texture_perturb_normal = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_perturb_normal"); + GLAD_GL_EXT_texture_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB"); + GLAD_GL_EXT_texture_sRGB_R8 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_R8"); + GLAD_GL_EXT_texture_sRGB_RG8 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_RG8"); + GLAD_GL_EXT_texture_sRGB_decode = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_decode"); + GLAD_GL_EXT_texture_shadow_lod = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_shadow_lod"); + GLAD_GL_EXT_texture_shared_exponent = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_shared_exponent"); + GLAD_GL_EXT_texture_snorm = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_snorm"); + GLAD_GL_EXT_texture_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_storage"); + GLAD_GL_EXT_texture_swizzle = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_swizzle"); + GLAD_GL_EXT_timer_query = glad_gl_has_extension(exts, exts_i, "GL_EXT_timer_query"); + GLAD_GL_EXT_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_EXT_transform_feedback"); + GLAD_GL_EXT_vertex_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_vertex_array"); + GLAD_GL_EXT_vertex_array_bgra = glad_gl_has_extension(exts, exts_i, "GL_EXT_vertex_array_bgra"); + GLAD_GL_EXT_vertex_attrib_64bit = glad_gl_has_extension(exts, exts_i, "GL_EXT_vertex_attrib_64bit"); + GLAD_GL_EXT_vertex_shader = glad_gl_has_extension(exts, exts_i, "GL_EXT_vertex_shader"); + GLAD_GL_EXT_vertex_weighting = glad_gl_has_extension(exts, exts_i, "GL_EXT_vertex_weighting"); + GLAD_GL_EXT_win32_keyed_mutex = glad_gl_has_extension(exts, exts_i, "GL_EXT_win32_keyed_mutex"); + GLAD_GL_EXT_window_rectangles = glad_gl_has_extension(exts, exts_i, "GL_EXT_window_rectangles"); + GLAD_GL_EXT_x11_sync_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_x11_sync_object"); + GLAD_GL_GREMEDY_frame_terminator = glad_gl_has_extension(exts, exts_i, "GL_GREMEDY_frame_terminator"); + GLAD_GL_GREMEDY_string_marker = glad_gl_has_extension(exts, exts_i, "GL_GREMEDY_string_marker"); + GLAD_GL_HP_convolution_border_modes = glad_gl_has_extension(exts, exts_i, "GL_HP_convolution_border_modes"); + GLAD_GL_HP_image_transform = glad_gl_has_extension(exts, exts_i, "GL_HP_image_transform"); + GLAD_GL_HP_occlusion_test = glad_gl_has_extension(exts, exts_i, "GL_HP_occlusion_test"); + GLAD_GL_HP_texture_lighting = glad_gl_has_extension(exts, exts_i, "GL_HP_texture_lighting"); + GLAD_GL_IBM_cull_vertex = glad_gl_has_extension(exts, exts_i, "GL_IBM_cull_vertex"); + GLAD_GL_IBM_multimode_draw_arrays = glad_gl_has_extension(exts, exts_i, "GL_IBM_multimode_draw_arrays"); + GLAD_GL_IBM_rasterpos_clip = glad_gl_has_extension(exts, exts_i, "GL_IBM_rasterpos_clip"); + GLAD_GL_IBM_static_data = glad_gl_has_extension(exts, exts_i, "GL_IBM_static_data"); + GLAD_GL_IBM_texture_mirrored_repeat = glad_gl_has_extension(exts, exts_i, "GL_IBM_texture_mirrored_repeat"); + GLAD_GL_IBM_vertex_array_lists = glad_gl_has_extension(exts, exts_i, "GL_IBM_vertex_array_lists"); + GLAD_GL_INGR_blend_func_separate = glad_gl_has_extension(exts, exts_i, "GL_INGR_blend_func_separate"); + GLAD_GL_INGR_color_clamp = glad_gl_has_extension(exts, exts_i, "GL_INGR_color_clamp"); + GLAD_GL_INGR_interlace_read = glad_gl_has_extension(exts, exts_i, "GL_INGR_interlace_read"); + GLAD_GL_INTEL_blackhole_render = glad_gl_has_extension(exts, exts_i, "GL_INTEL_blackhole_render"); + GLAD_GL_INTEL_conservative_rasterization = glad_gl_has_extension(exts, exts_i, "GL_INTEL_conservative_rasterization"); + GLAD_GL_INTEL_fragment_shader_ordering = glad_gl_has_extension(exts, exts_i, "GL_INTEL_fragment_shader_ordering"); + GLAD_GL_INTEL_framebuffer_CMAA = glad_gl_has_extension(exts, exts_i, "GL_INTEL_framebuffer_CMAA"); + GLAD_GL_INTEL_map_texture = glad_gl_has_extension(exts, exts_i, "GL_INTEL_map_texture"); + GLAD_GL_INTEL_parallel_arrays = glad_gl_has_extension(exts, exts_i, "GL_INTEL_parallel_arrays"); + GLAD_GL_INTEL_performance_query = glad_gl_has_extension(exts, exts_i, "GL_INTEL_performance_query"); + GLAD_GL_KHR_blend_equation_advanced = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced"); + GLAD_GL_KHR_blend_equation_advanced_coherent = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced_coherent"); + GLAD_GL_KHR_context_flush_control = glad_gl_has_extension(exts, exts_i, "GL_KHR_context_flush_control"); + GLAD_GL_KHR_debug = glad_gl_has_extension(exts, exts_i, "GL_KHR_debug"); + GLAD_GL_KHR_no_error = glad_gl_has_extension(exts, exts_i, "GL_KHR_no_error"); + GLAD_GL_KHR_parallel_shader_compile = glad_gl_has_extension(exts, exts_i, "GL_KHR_parallel_shader_compile"); + GLAD_GL_KHR_robust_buffer_access_behavior = glad_gl_has_extension(exts, exts_i, "GL_KHR_robust_buffer_access_behavior"); + GLAD_GL_KHR_robustness = glad_gl_has_extension(exts, exts_i, "GL_KHR_robustness"); + GLAD_GL_KHR_shader_subgroup = glad_gl_has_extension(exts, exts_i, "GL_KHR_shader_subgroup"); + GLAD_GL_KHR_texture_compression_astc_hdr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_hdr"); + GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_ldr"); + GLAD_GL_KHR_texture_compression_astc_sliced_3d = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_sliced_3d"); + GLAD_GL_MESAX_texture_stack = glad_gl_has_extension(exts, exts_i, "GL_MESAX_texture_stack"); + GLAD_GL_MESA_framebuffer_flip_x = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_flip_x"); + GLAD_GL_MESA_framebuffer_flip_y = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_flip_y"); + GLAD_GL_MESA_framebuffer_swap_xy = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_swap_xy"); + GLAD_GL_MESA_pack_invert = glad_gl_has_extension(exts, exts_i, "GL_MESA_pack_invert"); + GLAD_GL_MESA_program_binary_formats = glad_gl_has_extension(exts, exts_i, "GL_MESA_program_binary_formats"); + GLAD_GL_MESA_resize_buffers = glad_gl_has_extension(exts, exts_i, "GL_MESA_resize_buffers"); + GLAD_GL_MESA_shader_integer_functions = glad_gl_has_extension(exts, exts_i, "GL_MESA_shader_integer_functions"); + GLAD_GL_MESA_tile_raster_order = glad_gl_has_extension(exts, exts_i, "GL_MESA_tile_raster_order"); + GLAD_GL_MESA_window_pos = glad_gl_has_extension(exts, exts_i, "GL_MESA_window_pos"); + GLAD_GL_MESA_ycbcr_texture = glad_gl_has_extension(exts, exts_i, "GL_MESA_ycbcr_texture"); + GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_NVX_blend_equation_advanced_multi_draw_buffers"); + GLAD_GL_NVX_conditional_render = glad_gl_has_extension(exts, exts_i, "GL_NVX_conditional_render"); + GLAD_GL_NVX_gpu_memory_info = glad_gl_has_extension(exts, exts_i, "GL_NVX_gpu_memory_info"); + GLAD_GL_NVX_gpu_multicast2 = glad_gl_has_extension(exts, exts_i, "GL_NVX_gpu_multicast2"); + GLAD_GL_NVX_linked_gpu_multicast = glad_gl_has_extension(exts, exts_i, "GL_NVX_linked_gpu_multicast"); + GLAD_GL_NVX_progress_fence = glad_gl_has_extension(exts, exts_i, "GL_NVX_progress_fence"); + GLAD_GL_NV_alpha_to_coverage_dither_control = glad_gl_has_extension(exts, exts_i, "GL_NV_alpha_to_coverage_dither_control"); + GLAD_GL_NV_bindless_multi_draw_indirect = glad_gl_has_extension(exts, exts_i, "GL_NV_bindless_multi_draw_indirect"); + GLAD_GL_NV_bindless_multi_draw_indirect_count = glad_gl_has_extension(exts, exts_i, "GL_NV_bindless_multi_draw_indirect_count"); + GLAD_GL_NV_bindless_texture = glad_gl_has_extension(exts, exts_i, "GL_NV_bindless_texture"); + GLAD_GL_NV_blend_equation_advanced = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_equation_advanced"); + GLAD_GL_NV_blend_equation_advanced_coherent = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_equation_advanced_coherent"); + GLAD_GL_NV_blend_minmax_factor = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_minmax_factor"); + GLAD_GL_NV_blend_square = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_square"); + GLAD_GL_NV_clip_space_w_scaling = glad_gl_has_extension(exts, exts_i, "GL_NV_clip_space_w_scaling"); + GLAD_GL_NV_command_list = glad_gl_has_extension(exts, exts_i, "GL_NV_command_list"); + GLAD_GL_NV_compute_program5 = glad_gl_has_extension(exts, exts_i, "GL_NV_compute_program5"); + GLAD_GL_NV_compute_shader_derivatives = glad_gl_has_extension(exts, exts_i, "GL_NV_compute_shader_derivatives"); + GLAD_GL_NV_conditional_render = glad_gl_has_extension(exts, exts_i, "GL_NV_conditional_render"); + GLAD_GL_NV_conservative_raster = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster"); + GLAD_GL_NV_conservative_raster_dilate = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_dilate"); + GLAD_GL_NV_conservative_raster_pre_snap = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_pre_snap"); + GLAD_GL_NV_conservative_raster_pre_snap_triangles = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_pre_snap_triangles"); + GLAD_GL_NV_conservative_raster_underestimation = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_underestimation"); + GLAD_GL_NV_copy_depth_to_color = glad_gl_has_extension(exts, exts_i, "GL_NV_copy_depth_to_color"); + GLAD_GL_NV_copy_image = glad_gl_has_extension(exts, exts_i, "GL_NV_copy_image"); + GLAD_GL_NV_deep_texture3D = glad_gl_has_extension(exts, exts_i, "GL_NV_deep_texture3D"); + GLAD_GL_NV_depth_buffer_float = glad_gl_has_extension(exts, exts_i, "GL_NV_depth_buffer_float"); + GLAD_GL_NV_depth_clamp = glad_gl_has_extension(exts, exts_i, "GL_NV_depth_clamp"); + GLAD_GL_NV_draw_texture = glad_gl_has_extension(exts, exts_i, "GL_NV_draw_texture"); + GLAD_GL_NV_draw_vulkan_image = glad_gl_has_extension(exts, exts_i, "GL_NV_draw_vulkan_image"); + GLAD_GL_NV_evaluators = glad_gl_has_extension(exts, exts_i, "GL_NV_evaluators"); + GLAD_GL_NV_explicit_multisample = glad_gl_has_extension(exts, exts_i, "GL_NV_explicit_multisample"); + GLAD_GL_NV_fence = glad_gl_has_extension(exts, exts_i, "GL_NV_fence"); + GLAD_GL_NV_fill_rectangle = glad_gl_has_extension(exts, exts_i, "GL_NV_fill_rectangle"); + GLAD_GL_NV_float_buffer = glad_gl_has_extension(exts, exts_i, "GL_NV_float_buffer"); + GLAD_GL_NV_fog_distance = glad_gl_has_extension(exts, exts_i, "GL_NV_fog_distance"); + GLAD_GL_NV_fragment_coverage_to_color = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_coverage_to_color"); + GLAD_GL_NV_fragment_program = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_program"); + GLAD_GL_NV_fragment_program2 = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_program2"); + GLAD_GL_NV_fragment_program4 = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_program4"); + GLAD_GL_NV_fragment_program_option = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_program_option"); + GLAD_GL_NV_fragment_shader_barycentric = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_shader_barycentric"); + GLAD_GL_NV_fragment_shader_interlock = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_shader_interlock"); + GLAD_GL_NV_framebuffer_mixed_samples = glad_gl_has_extension(exts, exts_i, "GL_NV_framebuffer_mixed_samples"); + GLAD_GL_NV_framebuffer_multisample_coverage = glad_gl_has_extension(exts, exts_i, "GL_NV_framebuffer_multisample_coverage"); + GLAD_GL_NV_geometry_program4 = glad_gl_has_extension(exts, exts_i, "GL_NV_geometry_program4"); + GLAD_GL_NV_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_NV_geometry_shader4"); + GLAD_GL_NV_geometry_shader_passthrough = glad_gl_has_extension(exts, exts_i, "GL_NV_geometry_shader_passthrough"); + GLAD_GL_NV_gpu_multicast = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_multicast"); + GLAD_GL_NV_gpu_program4 = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_program4"); + GLAD_GL_NV_gpu_program5 = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_program5"); + GLAD_GL_NV_gpu_program5_mem_extended = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_program5_mem_extended"); + GLAD_GL_NV_gpu_shader5 = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_shader5"); + GLAD_GL_NV_half_float = glad_gl_has_extension(exts, exts_i, "GL_NV_half_float"); + GLAD_GL_NV_internalformat_sample_query = glad_gl_has_extension(exts, exts_i, "GL_NV_internalformat_sample_query"); + GLAD_GL_NV_light_max_exponent = glad_gl_has_extension(exts, exts_i, "GL_NV_light_max_exponent"); + GLAD_GL_NV_memory_attachment = glad_gl_has_extension(exts, exts_i, "GL_NV_memory_attachment"); + GLAD_GL_NV_memory_object_sparse = glad_gl_has_extension(exts, exts_i, "GL_NV_memory_object_sparse"); + GLAD_GL_NV_mesh_shader = glad_gl_has_extension(exts, exts_i, "GL_NV_mesh_shader"); + GLAD_GL_NV_multisample_coverage = glad_gl_has_extension(exts, exts_i, "GL_NV_multisample_coverage"); + GLAD_GL_NV_multisample_filter_hint = glad_gl_has_extension(exts, exts_i, "GL_NV_multisample_filter_hint"); + GLAD_GL_NV_occlusion_query = glad_gl_has_extension(exts, exts_i, "GL_NV_occlusion_query"); + GLAD_GL_NV_packed_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_NV_packed_depth_stencil"); + GLAD_GL_NV_parameter_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_NV_parameter_buffer_object"); + GLAD_GL_NV_parameter_buffer_object2 = glad_gl_has_extension(exts, exts_i, "GL_NV_parameter_buffer_object2"); + GLAD_GL_NV_path_rendering = glad_gl_has_extension(exts, exts_i, "GL_NV_path_rendering"); + GLAD_GL_NV_path_rendering_shared_edge = glad_gl_has_extension(exts, exts_i, "GL_NV_path_rendering_shared_edge"); + GLAD_GL_NV_pixel_data_range = glad_gl_has_extension(exts, exts_i, "GL_NV_pixel_data_range"); + GLAD_GL_NV_point_sprite = glad_gl_has_extension(exts, exts_i, "GL_NV_point_sprite"); + GLAD_GL_NV_present_video = glad_gl_has_extension(exts, exts_i, "GL_NV_present_video"); + GLAD_GL_NV_primitive_restart = glad_gl_has_extension(exts, exts_i, "GL_NV_primitive_restart"); + GLAD_GL_NV_primitive_shading_rate = glad_gl_has_extension(exts, exts_i, "GL_NV_primitive_shading_rate"); + GLAD_GL_NV_query_resource = glad_gl_has_extension(exts, exts_i, "GL_NV_query_resource"); + GLAD_GL_NV_query_resource_tag = glad_gl_has_extension(exts, exts_i, "GL_NV_query_resource_tag"); + GLAD_GL_NV_register_combiners = glad_gl_has_extension(exts, exts_i, "GL_NV_register_combiners"); + GLAD_GL_NV_register_combiners2 = glad_gl_has_extension(exts, exts_i, "GL_NV_register_combiners2"); + GLAD_GL_NV_representative_fragment_test = glad_gl_has_extension(exts, exts_i, "GL_NV_representative_fragment_test"); + GLAD_GL_NV_robustness_video_memory_purge = glad_gl_has_extension(exts, exts_i, "GL_NV_robustness_video_memory_purge"); + GLAD_GL_NV_sample_locations = glad_gl_has_extension(exts, exts_i, "GL_NV_sample_locations"); + GLAD_GL_NV_sample_mask_override_coverage = glad_gl_has_extension(exts, exts_i, "GL_NV_sample_mask_override_coverage"); + GLAD_GL_NV_scissor_exclusive = glad_gl_has_extension(exts, exts_i, "GL_NV_scissor_exclusive"); + GLAD_GL_NV_shader_atomic_counters = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_counters"); + GLAD_GL_NV_shader_atomic_float = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_float"); + GLAD_GL_NV_shader_atomic_float64 = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_float64"); + GLAD_GL_NV_shader_atomic_fp16_vector = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_fp16_vector"); + GLAD_GL_NV_shader_atomic_int64 = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_int64"); + GLAD_GL_NV_shader_buffer_load = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_buffer_load"); + GLAD_GL_NV_shader_buffer_store = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_buffer_store"); + GLAD_GL_NV_shader_storage_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_storage_buffer_object"); + GLAD_GL_NV_shader_subgroup_partitioned = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_subgroup_partitioned"); + GLAD_GL_NV_shader_texture_footprint = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_texture_footprint"); + GLAD_GL_NV_shader_thread_group = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_thread_group"); + GLAD_GL_NV_shader_thread_shuffle = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_thread_shuffle"); + GLAD_GL_NV_shading_rate_image = glad_gl_has_extension(exts, exts_i, "GL_NV_shading_rate_image"); + GLAD_GL_NV_stereo_view_rendering = glad_gl_has_extension(exts, exts_i, "GL_NV_stereo_view_rendering"); + GLAD_GL_NV_tessellation_program5 = glad_gl_has_extension(exts, exts_i, "GL_NV_tessellation_program5"); + GLAD_GL_NV_texgen_emboss = glad_gl_has_extension(exts, exts_i, "GL_NV_texgen_emboss"); + GLAD_GL_NV_texgen_reflection = glad_gl_has_extension(exts, exts_i, "GL_NV_texgen_reflection"); + GLAD_GL_NV_texture_barrier = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_barrier"); + GLAD_GL_NV_texture_compression_vtc = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_compression_vtc"); + GLAD_GL_NV_texture_env_combine4 = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_env_combine4"); + GLAD_GL_NV_texture_expand_normal = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_expand_normal"); + GLAD_GL_NV_texture_multisample = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_multisample"); + GLAD_GL_NV_texture_rectangle = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_rectangle"); + GLAD_GL_NV_texture_rectangle_compressed = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_rectangle_compressed"); + GLAD_GL_NV_texture_shader = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_shader"); + GLAD_GL_NV_texture_shader2 = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_shader2"); + GLAD_GL_NV_texture_shader3 = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_shader3"); + GLAD_GL_NV_timeline_semaphore = glad_gl_has_extension(exts, exts_i, "GL_NV_timeline_semaphore"); + GLAD_GL_NV_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_NV_transform_feedback"); + GLAD_GL_NV_transform_feedback2 = glad_gl_has_extension(exts, exts_i, "GL_NV_transform_feedback2"); + GLAD_GL_NV_uniform_buffer_std430_layout = glad_gl_has_extension(exts, exts_i, "GL_NV_uniform_buffer_std430_layout"); + GLAD_GL_NV_uniform_buffer_unified_memory = glad_gl_has_extension(exts, exts_i, "GL_NV_uniform_buffer_unified_memory"); + GLAD_GL_NV_vdpau_interop = glad_gl_has_extension(exts, exts_i, "GL_NV_vdpau_interop"); + GLAD_GL_NV_vdpau_interop2 = glad_gl_has_extension(exts, exts_i, "GL_NV_vdpau_interop2"); + GLAD_GL_NV_vertex_array_range = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_array_range"); + GLAD_GL_NV_vertex_array_range2 = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_array_range2"); + GLAD_GL_NV_vertex_attrib_integer_64bit = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_attrib_integer_64bit"); + GLAD_GL_NV_vertex_buffer_unified_memory = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_buffer_unified_memory"); + GLAD_GL_NV_vertex_program = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program"); + GLAD_GL_NV_vertex_program1_1 = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program1_1"); + GLAD_GL_NV_vertex_program2 = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program2"); + GLAD_GL_NV_vertex_program2_option = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program2_option"); + GLAD_GL_NV_vertex_program3 = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program3"); + GLAD_GL_NV_vertex_program4 = glad_gl_has_extension(exts, exts_i, "GL_NV_vertex_program4"); + GLAD_GL_NV_video_capture = glad_gl_has_extension(exts, exts_i, "GL_NV_video_capture"); + GLAD_GL_NV_viewport_array2 = glad_gl_has_extension(exts, exts_i, "GL_NV_viewport_array2"); + GLAD_GL_NV_viewport_swizzle = glad_gl_has_extension(exts, exts_i, "GL_NV_viewport_swizzle"); + GLAD_GL_OES_byte_coordinates = glad_gl_has_extension(exts, exts_i, "GL_OES_byte_coordinates"); + GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_paletted_texture"); + GLAD_GL_OES_fixed_point = glad_gl_has_extension(exts, exts_i, "GL_OES_fixed_point"); + GLAD_GL_OES_query_matrix = glad_gl_has_extension(exts, exts_i, "GL_OES_query_matrix"); + GLAD_GL_OES_read_format = glad_gl_has_extension(exts, exts_i, "GL_OES_read_format"); + GLAD_GL_OES_single_precision = glad_gl_has_extension(exts, exts_i, "GL_OES_single_precision"); + GLAD_GL_OML_interlace = glad_gl_has_extension(exts, exts_i, "GL_OML_interlace"); + GLAD_GL_OML_resample = glad_gl_has_extension(exts, exts_i, "GL_OML_resample"); + GLAD_GL_OML_subsample = glad_gl_has_extension(exts, exts_i, "GL_OML_subsample"); + GLAD_GL_OVR_multiview = glad_gl_has_extension(exts, exts_i, "GL_OVR_multiview"); + GLAD_GL_OVR_multiview2 = glad_gl_has_extension(exts, exts_i, "GL_OVR_multiview2"); + GLAD_GL_PGI_misc_hints = glad_gl_has_extension(exts, exts_i, "GL_PGI_misc_hints"); + GLAD_GL_PGI_vertex_hints = glad_gl_has_extension(exts, exts_i, "GL_PGI_vertex_hints"); + GLAD_GL_REND_screen_coordinates = glad_gl_has_extension(exts, exts_i, "GL_REND_screen_coordinates"); + GLAD_GL_S3_s3tc = glad_gl_has_extension(exts, exts_i, "GL_S3_s3tc"); + GLAD_GL_SGIS_detail_texture = glad_gl_has_extension(exts, exts_i, "GL_SGIS_detail_texture"); + GLAD_GL_SGIS_fog_function = glad_gl_has_extension(exts, exts_i, "GL_SGIS_fog_function"); + GLAD_GL_SGIS_generate_mipmap = glad_gl_has_extension(exts, exts_i, "GL_SGIS_generate_mipmap"); + GLAD_GL_SGIS_multisample = glad_gl_has_extension(exts, exts_i, "GL_SGIS_multisample"); + GLAD_GL_SGIS_pixel_texture = glad_gl_has_extension(exts, exts_i, "GL_SGIS_pixel_texture"); + GLAD_GL_SGIS_point_line_texgen = glad_gl_has_extension(exts, exts_i, "GL_SGIS_point_line_texgen"); + GLAD_GL_SGIS_point_parameters = glad_gl_has_extension(exts, exts_i, "GL_SGIS_point_parameters"); + GLAD_GL_SGIS_sharpen_texture = glad_gl_has_extension(exts, exts_i, "GL_SGIS_sharpen_texture"); + GLAD_GL_SGIS_texture4D = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture4D"); + GLAD_GL_SGIS_texture_border_clamp = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_border_clamp"); + GLAD_GL_SGIS_texture_color_mask = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_color_mask"); + GLAD_GL_SGIS_texture_edge_clamp = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_edge_clamp"); + GLAD_GL_SGIS_texture_filter4 = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_filter4"); + GLAD_GL_SGIS_texture_lod = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_lod"); + GLAD_GL_SGIS_texture_select = glad_gl_has_extension(exts, exts_i, "GL_SGIS_texture_select"); + GLAD_GL_SGIX_async = glad_gl_has_extension(exts, exts_i, "GL_SGIX_async"); + GLAD_GL_SGIX_async_histogram = glad_gl_has_extension(exts, exts_i, "GL_SGIX_async_histogram"); + GLAD_GL_SGIX_async_pixel = glad_gl_has_extension(exts, exts_i, "GL_SGIX_async_pixel"); + GLAD_GL_SGIX_blend_alpha_minmax = glad_gl_has_extension(exts, exts_i, "GL_SGIX_blend_alpha_minmax"); + GLAD_GL_SGIX_calligraphic_fragment = glad_gl_has_extension(exts, exts_i, "GL_SGIX_calligraphic_fragment"); + GLAD_GL_SGIX_clipmap = glad_gl_has_extension(exts, exts_i, "GL_SGIX_clipmap"); + GLAD_GL_SGIX_convolution_accuracy = glad_gl_has_extension(exts, exts_i, "GL_SGIX_convolution_accuracy"); + GLAD_GL_SGIX_depth_pass_instrument = glad_gl_has_extension(exts, exts_i, "GL_SGIX_depth_pass_instrument"); + GLAD_GL_SGIX_depth_texture = glad_gl_has_extension(exts, exts_i, "GL_SGIX_depth_texture"); + GLAD_GL_SGIX_flush_raster = glad_gl_has_extension(exts, exts_i, "GL_SGIX_flush_raster"); + GLAD_GL_SGIX_fog_offset = glad_gl_has_extension(exts, exts_i, "GL_SGIX_fog_offset"); + GLAD_GL_SGIX_fragment_lighting = glad_gl_has_extension(exts, exts_i, "GL_SGIX_fragment_lighting"); + GLAD_GL_SGIX_framezoom = glad_gl_has_extension(exts, exts_i, "GL_SGIX_framezoom"); + GLAD_GL_SGIX_igloo_interface = glad_gl_has_extension(exts, exts_i, "GL_SGIX_igloo_interface"); + GLAD_GL_SGIX_instruments = glad_gl_has_extension(exts, exts_i, "GL_SGIX_instruments"); + GLAD_GL_SGIX_interlace = glad_gl_has_extension(exts, exts_i, "GL_SGIX_interlace"); + GLAD_GL_SGIX_ir_instrument1 = glad_gl_has_extension(exts, exts_i, "GL_SGIX_ir_instrument1"); + GLAD_GL_SGIX_list_priority = glad_gl_has_extension(exts, exts_i, "GL_SGIX_list_priority"); + GLAD_GL_SGIX_pixel_texture = glad_gl_has_extension(exts, exts_i, "GL_SGIX_pixel_texture"); + GLAD_GL_SGIX_pixel_tiles = glad_gl_has_extension(exts, exts_i, "GL_SGIX_pixel_tiles"); + GLAD_GL_SGIX_polynomial_ffd = glad_gl_has_extension(exts, exts_i, "GL_SGIX_polynomial_ffd"); + GLAD_GL_SGIX_reference_plane = glad_gl_has_extension(exts, exts_i, "GL_SGIX_reference_plane"); + GLAD_GL_SGIX_resample = glad_gl_has_extension(exts, exts_i, "GL_SGIX_resample"); + GLAD_GL_SGIX_scalebias_hint = glad_gl_has_extension(exts, exts_i, "GL_SGIX_scalebias_hint"); + GLAD_GL_SGIX_shadow = glad_gl_has_extension(exts, exts_i, "GL_SGIX_shadow"); + GLAD_GL_SGIX_shadow_ambient = glad_gl_has_extension(exts, exts_i, "GL_SGIX_shadow_ambient"); + GLAD_GL_SGIX_sprite = glad_gl_has_extension(exts, exts_i, "GL_SGIX_sprite"); + GLAD_GL_SGIX_subsample = glad_gl_has_extension(exts, exts_i, "GL_SGIX_subsample"); + GLAD_GL_SGIX_tag_sample_buffer = glad_gl_has_extension(exts, exts_i, "GL_SGIX_tag_sample_buffer"); + GLAD_GL_SGIX_texture_add_env = glad_gl_has_extension(exts, exts_i, "GL_SGIX_texture_add_env"); + GLAD_GL_SGIX_texture_coordinate_clamp = glad_gl_has_extension(exts, exts_i, "GL_SGIX_texture_coordinate_clamp"); + GLAD_GL_SGIX_texture_lod_bias = glad_gl_has_extension(exts, exts_i, "GL_SGIX_texture_lod_bias"); + GLAD_GL_SGIX_texture_multi_buffer = glad_gl_has_extension(exts, exts_i, "GL_SGIX_texture_multi_buffer"); + GLAD_GL_SGIX_texture_scale_bias = glad_gl_has_extension(exts, exts_i, "GL_SGIX_texture_scale_bias"); + GLAD_GL_SGIX_vertex_preclip = glad_gl_has_extension(exts, exts_i, "GL_SGIX_vertex_preclip"); + GLAD_GL_SGIX_ycrcb = glad_gl_has_extension(exts, exts_i, "GL_SGIX_ycrcb"); + GLAD_GL_SGIX_ycrcb_subsample = glad_gl_has_extension(exts, exts_i, "GL_SGIX_ycrcb_subsample"); + GLAD_GL_SGIX_ycrcba = glad_gl_has_extension(exts, exts_i, "GL_SGIX_ycrcba"); + GLAD_GL_SGI_color_matrix = glad_gl_has_extension(exts, exts_i, "GL_SGI_color_matrix"); + GLAD_GL_SGI_color_table = glad_gl_has_extension(exts, exts_i, "GL_SGI_color_table"); + GLAD_GL_SGI_texture_color_table = glad_gl_has_extension(exts, exts_i, "GL_SGI_texture_color_table"); + GLAD_GL_SUNX_constant_data = glad_gl_has_extension(exts, exts_i, "GL_SUNX_constant_data"); + GLAD_GL_SUN_convolution_border_modes = glad_gl_has_extension(exts, exts_i, "GL_SUN_convolution_border_modes"); + GLAD_GL_SUN_global_alpha = glad_gl_has_extension(exts, exts_i, "GL_SUN_global_alpha"); + GLAD_GL_SUN_mesh_array = glad_gl_has_extension(exts, exts_i, "GL_SUN_mesh_array"); + GLAD_GL_SUN_slice_accum = glad_gl_has_extension(exts, exts_i, "GL_SUN_slice_accum"); + GLAD_GL_SUN_triangle_list = glad_gl_has_extension(exts, exts_i, "GL_SUN_triangle_list"); + GLAD_GL_SUN_vertex = glad_gl_has_extension(exts, exts_i, "GL_SUN_vertex"); + GLAD_GL_WIN_phong_shading = glad_gl_has_extension(exts, exts_i, "GL_WIN_phong_shading"); + GLAD_GL_WIN_specular_fog = glad_gl_has_extension(exts, exts_i, "GL_WIN_specular_fog"); + GLAD_GL_EXT_separate_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_EXT_separate_shader_objects"); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gl(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; + GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; + GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; + GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; + GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; + GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; + GLAD_GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gl(); + + glad_gl_load_GL_VERSION_1_0(load, userptr); + glad_gl_load_GL_VERSION_1_1(load, userptr); + glad_gl_load_GL_VERSION_1_2(load, userptr); + glad_gl_load_GL_VERSION_1_3(load, userptr); + glad_gl_load_GL_VERSION_1_4(load, userptr); + glad_gl_load_GL_VERSION_1_5(load, userptr); + glad_gl_load_GL_VERSION_2_0(load, userptr); + glad_gl_load_GL_VERSION_2_1(load, userptr); + glad_gl_load_GL_VERSION_3_0(load, userptr); + glad_gl_load_GL_VERSION_3_1(load, userptr); + glad_gl_load_GL_VERSION_3_2(load, userptr); + glad_gl_load_GL_VERSION_3_3(load, userptr); + glad_gl_load_GL_VERSION_4_0(load, userptr); + glad_gl_load_GL_VERSION_4_1(load, userptr); + glad_gl_load_GL_VERSION_4_2(load, userptr); + glad_gl_load_GL_VERSION_4_3(load, userptr); + glad_gl_load_GL_VERSION_4_4(load, userptr); + glad_gl_load_GL_VERSION_4_5(load, userptr); + glad_gl_load_GL_VERSION_4_6(load, userptr); + + if (!glad_gl_find_extensions_gl()) return 0; + glad_gl_load_GL_3DFX_tbuffer(load, userptr); + glad_gl_load_GL_AMD_debug_output(load, userptr); + glad_gl_load_GL_AMD_draw_buffers_blend(load, userptr); + glad_gl_load_GL_AMD_framebuffer_multisample_advanced(load, userptr); + glad_gl_load_GL_AMD_framebuffer_sample_positions(load, userptr); + glad_gl_load_GL_AMD_gpu_shader_int64(load, userptr); + glad_gl_load_GL_AMD_interleaved_elements(load, userptr); + glad_gl_load_GL_AMD_multi_draw_indirect(load, userptr); + glad_gl_load_GL_AMD_name_gen_delete(load, userptr); + glad_gl_load_GL_AMD_occlusion_query_event(load, userptr); + glad_gl_load_GL_AMD_performance_monitor(load, userptr); + glad_gl_load_GL_AMD_sample_positions(load, userptr); + glad_gl_load_GL_AMD_sparse_texture(load, userptr); + glad_gl_load_GL_AMD_stencil_operation_extended(load, userptr); + glad_gl_load_GL_AMD_vertex_shader_tessellator(load, userptr); + glad_gl_load_GL_APPLE_element_array(load, userptr); + glad_gl_load_GL_APPLE_fence(load, userptr); + glad_gl_load_GL_APPLE_flush_buffer_range(load, userptr); + glad_gl_load_GL_APPLE_object_purgeable(load, userptr); + glad_gl_load_GL_APPLE_texture_range(load, userptr); + glad_gl_load_GL_APPLE_vertex_array_object(load, userptr); + glad_gl_load_GL_APPLE_vertex_array_range(load, userptr); + glad_gl_load_GL_APPLE_vertex_program_evaluators(load, userptr); + glad_gl_load_GL_ARB_ES2_compatibility(load, userptr); + glad_gl_load_GL_ARB_ES3_1_compatibility(load, userptr); + glad_gl_load_GL_ARB_ES3_2_compatibility(load, userptr); + glad_gl_load_GL_ARB_base_instance(load, userptr); + glad_gl_load_GL_ARB_bindless_texture(load, userptr); + glad_gl_load_GL_ARB_blend_func_extended(load, userptr); + glad_gl_load_GL_ARB_buffer_storage(load, userptr); + glad_gl_load_GL_ARB_cl_event(load, userptr); + glad_gl_load_GL_ARB_clear_buffer_object(load, userptr); + glad_gl_load_GL_ARB_clear_texture(load, userptr); + glad_gl_load_GL_ARB_clip_control(load, userptr); + glad_gl_load_GL_ARB_color_buffer_float(load, userptr); + glad_gl_load_GL_ARB_compute_shader(load, userptr); + glad_gl_load_GL_ARB_compute_variable_group_size(load, userptr); + glad_gl_load_GL_ARB_copy_buffer(load, userptr); + glad_gl_load_GL_ARB_copy_image(load, userptr); + glad_gl_load_GL_ARB_debug_output(load, userptr); + glad_gl_load_GL_ARB_direct_state_access(load, userptr); + glad_gl_load_GL_ARB_draw_buffers(load, userptr); + glad_gl_load_GL_ARB_draw_buffers_blend(load, userptr); + glad_gl_load_GL_ARB_draw_elements_base_vertex(load, userptr); + glad_gl_load_GL_ARB_draw_indirect(load, userptr); + glad_gl_load_GL_ARB_draw_instanced(load, userptr); + glad_gl_load_GL_ARB_fragment_program(load, userptr); + glad_gl_load_GL_ARB_framebuffer_no_attachments(load, userptr); + glad_gl_load_GL_ARB_framebuffer_object(load, userptr); + glad_gl_load_GL_ARB_geometry_shader4(load, userptr); + glad_gl_load_GL_ARB_get_program_binary(load, userptr); + glad_gl_load_GL_ARB_get_texture_sub_image(load, userptr); + glad_gl_load_GL_ARB_gl_spirv(load, userptr); + glad_gl_load_GL_ARB_gpu_shader_fp64(load, userptr); + glad_gl_load_GL_ARB_gpu_shader_int64(load, userptr); + glad_gl_load_GL_ARB_imaging(load, userptr); + glad_gl_load_GL_ARB_indirect_parameters(load, userptr); + glad_gl_load_GL_ARB_instanced_arrays(load, userptr); + glad_gl_load_GL_ARB_internalformat_query(load, userptr); + glad_gl_load_GL_ARB_internalformat_query2(load, userptr); + glad_gl_load_GL_ARB_invalidate_subdata(load, userptr); + glad_gl_load_GL_ARB_map_buffer_range(load, userptr); + glad_gl_load_GL_ARB_matrix_palette(load, userptr); + glad_gl_load_GL_ARB_multi_bind(load, userptr); + glad_gl_load_GL_ARB_multi_draw_indirect(load, userptr); + glad_gl_load_GL_ARB_multisample(load, userptr); + glad_gl_load_GL_ARB_multitexture(load, userptr); + glad_gl_load_GL_ARB_occlusion_query(load, userptr); + glad_gl_load_GL_ARB_parallel_shader_compile(load, userptr); + glad_gl_load_GL_ARB_point_parameters(load, userptr); + glad_gl_load_GL_ARB_polygon_offset_clamp(load, userptr); + glad_gl_load_GL_ARB_program_interface_query(load, userptr); + glad_gl_load_GL_ARB_provoking_vertex(load, userptr); + glad_gl_load_GL_ARB_robustness(load, userptr); + glad_gl_load_GL_ARB_sample_locations(load, userptr); + glad_gl_load_GL_ARB_sample_shading(load, userptr); + glad_gl_load_GL_ARB_sampler_objects(load, userptr); + glad_gl_load_GL_ARB_separate_shader_objects(load, userptr); + glad_gl_load_GL_ARB_shader_atomic_counters(load, userptr); + glad_gl_load_GL_ARB_shader_image_load_store(load, userptr); + glad_gl_load_GL_ARB_shader_objects(load, userptr); + glad_gl_load_GL_ARB_shader_storage_buffer_object(load, userptr); + glad_gl_load_GL_ARB_shader_subroutine(load, userptr); + glad_gl_load_GL_ARB_shading_language_include(load, userptr); + glad_gl_load_GL_ARB_sparse_buffer(load, userptr); + glad_gl_load_GL_ARB_sparse_texture(load, userptr); + glad_gl_load_GL_ARB_sync(load, userptr); + glad_gl_load_GL_ARB_tessellation_shader(load, userptr); + glad_gl_load_GL_ARB_texture_barrier(load, userptr); + glad_gl_load_GL_ARB_texture_buffer_object(load, userptr); + glad_gl_load_GL_ARB_texture_buffer_range(load, userptr); + glad_gl_load_GL_ARB_texture_compression(load, userptr); + glad_gl_load_GL_ARB_texture_multisample(load, userptr); + glad_gl_load_GL_ARB_texture_storage(load, userptr); + glad_gl_load_GL_ARB_texture_storage_multisample(load, userptr); + glad_gl_load_GL_ARB_texture_view(load, userptr); + glad_gl_load_GL_ARB_timer_query(load, userptr); + glad_gl_load_GL_ARB_transform_feedback2(load, userptr); + glad_gl_load_GL_ARB_transform_feedback3(load, userptr); + glad_gl_load_GL_ARB_transform_feedback_instanced(load, userptr); + glad_gl_load_GL_ARB_transpose_matrix(load, userptr); + glad_gl_load_GL_ARB_uniform_buffer_object(load, userptr); + glad_gl_load_GL_ARB_vertex_array_object(load, userptr); + glad_gl_load_GL_ARB_vertex_attrib_64bit(load, userptr); + glad_gl_load_GL_ARB_vertex_attrib_binding(load, userptr); + glad_gl_load_GL_ARB_vertex_blend(load, userptr); + glad_gl_load_GL_ARB_vertex_buffer_object(load, userptr); + glad_gl_load_GL_ARB_vertex_program(load, userptr); + glad_gl_load_GL_ARB_vertex_shader(load, userptr); + glad_gl_load_GL_ARB_vertex_type_2_10_10_10_rev(load, userptr); + glad_gl_load_GL_ARB_viewport_array(load, userptr); + glad_gl_load_GL_ARB_window_pos(load, userptr); + glad_gl_load_GL_ATI_draw_buffers(load, userptr); + glad_gl_load_GL_ATI_element_array(load, userptr); + glad_gl_load_GL_ATI_envmap_bumpmap(load, userptr); + glad_gl_load_GL_ATI_fragment_shader(load, userptr); + glad_gl_load_GL_ATI_map_object_buffer(load, userptr); + glad_gl_load_GL_ATI_pn_triangles(load, userptr); + glad_gl_load_GL_ATI_separate_stencil(load, userptr); + glad_gl_load_GL_ATI_vertex_array_object(load, userptr); + glad_gl_load_GL_ATI_vertex_attrib_array_object(load, userptr); + glad_gl_load_GL_ATI_vertex_streams(load, userptr); + glad_gl_load_GL_EXT_EGL_image_storage(load, userptr); + glad_gl_load_GL_EXT_bindable_uniform(load, userptr); + glad_gl_load_GL_EXT_blend_color(load, userptr); + glad_gl_load_GL_EXT_blend_equation_separate(load, userptr); + glad_gl_load_GL_EXT_blend_func_separate(load, userptr); + glad_gl_load_GL_EXT_blend_minmax(load, userptr); + glad_gl_load_GL_EXT_color_subtable(load, userptr); + glad_gl_load_GL_EXT_compiled_vertex_array(load, userptr); + glad_gl_load_GL_EXT_convolution(load, userptr); + glad_gl_load_GL_EXT_coordinate_frame(load, userptr); + glad_gl_load_GL_EXT_copy_texture(load, userptr); + glad_gl_load_GL_EXT_cull_vertex(load, userptr); + glad_gl_load_GL_EXT_debug_label(load, userptr); + glad_gl_load_GL_EXT_debug_marker(load, userptr); + glad_gl_load_GL_EXT_depth_bounds_test(load, userptr); + glad_gl_load_GL_EXT_direct_state_access(load, userptr); + glad_gl_load_GL_EXT_draw_buffers2(load, userptr); + glad_gl_load_GL_EXT_draw_instanced(load, userptr); + glad_gl_load_GL_EXT_draw_range_elements(load, userptr); + glad_gl_load_GL_EXT_external_buffer(load, userptr); + glad_gl_load_GL_EXT_fog_coord(load, userptr); + glad_gl_load_GL_EXT_framebuffer_blit(load, userptr); + glad_gl_load_GL_EXT_framebuffer_blit_layers(load, userptr); + glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr); + glad_gl_load_GL_EXT_framebuffer_object(load, userptr); + glad_gl_load_GL_EXT_geometry_shader4(load, userptr); + glad_gl_load_GL_EXT_gpu_program_parameters(load, userptr); + glad_gl_load_GL_EXT_gpu_shader4(load, userptr); + glad_gl_load_GL_EXT_histogram(load, userptr); + glad_gl_load_GL_EXT_index_func(load, userptr); + glad_gl_load_GL_EXT_index_material(load, userptr); + glad_gl_load_GL_EXT_light_texture(load, userptr); + glad_gl_load_GL_EXT_memory_object(load, userptr); + glad_gl_load_GL_EXT_memory_object_fd(load, userptr); + glad_gl_load_GL_EXT_memory_object_win32(load, userptr); + glad_gl_load_GL_EXT_multi_draw_arrays(load, userptr); + glad_gl_load_GL_EXT_multisample(load, userptr); + glad_gl_load_GL_EXT_paletted_texture(load, userptr); + glad_gl_load_GL_EXT_pixel_transform(load, userptr); + glad_gl_load_GL_EXT_point_parameters(load, userptr); + glad_gl_load_GL_EXT_polygon_offset(load, userptr); + glad_gl_load_GL_EXT_polygon_offset_clamp(load, userptr); + glad_gl_load_GL_EXT_provoking_vertex(load, userptr); + glad_gl_load_GL_EXT_raster_multisample(load, userptr); + glad_gl_load_GL_EXT_secondary_color(load, userptr); + glad_gl_load_GL_EXT_semaphore(load, userptr); + glad_gl_load_GL_EXT_semaphore_fd(load, userptr); + glad_gl_load_GL_EXT_semaphore_win32(load, userptr); + glad_gl_load_GL_EXT_shader_framebuffer_fetch_non_coherent(load, userptr); + glad_gl_load_GL_EXT_shader_image_load_store(load, userptr); + glad_gl_load_GL_EXT_stencil_clear_tag(load, userptr); + glad_gl_load_GL_EXT_stencil_two_side(load, userptr); + glad_gl_load_GL_EXT_subtexture(load, userptr); + glad_gl_load_GL_EXT_texture3D(load, userptr); + glad_gl_load_GL_EXT_texture_array(load, userptr); + glad_gl_load_GL_EXT_texture_buffer_object(load, userptr); + glad_gl_load_GL_EXT_texture_integer(load, userptr); + glad_gl_load_GL_EXT_texture_object(load, userptr); + glad_gl_load_GL_EXT_texture_perturb_normal(load, userptr); + glad_gl_load_GL_EXT_texture_storage(load, userptr); + glad_gl_load_GL_EXT_timer_query(load, userptr); + glad_gl_load_GL_EXT_transform_feedback(load, userptr); + glad_gl_load_GL_EXT_vertex_array(load, userptr); + glad_gl_load_GL_EXT_vertex_attrib_64bit(load, userptr); + glad_gl_load_GL_EXT_vertex_shader(load, userptr); + glad_gl_load_GL_EXT_vertex_weighting(load, userptr); + glad_gl_load_GL_EXT_win32_keyed_mutex(load, userptr); + glad_gl_load_GL_EXT_window_rectangles(load, userptr); + glad_gl_load_GL_EXT_x11_sync_object(load, userptr); + glad_gl_load_GL_GREMEDY_frame_terminator(load, userptr); + glad_gl_load_GL_GREMEDY_string_marker(load, userptr); + glad_gl_load_GL_HP_image_transform(load, userptr); + glad_gl_load_GL_IBM_multimode_draw_arrays(load, userptr); + glad_gl_load_GL_IBM_static_data(load, userptr); + glad_gl_load_GL_IBM_vertex_array_lists(load, userptr); + glad_gl_load_GL_INGR_blend_func_separate(load, userptr); + glad_gl_load_GL_INTEL_framebuffer_CMAA(load, userptr); + glad_gl_load_GL_INTEL_map_texture(load, userptr); + glad_gl_load_GL_INTEL_parallel_arrays(load, userptr); + glad_gl_load_GL_INTEL_performance_query(load, userptr); + glad_gl_load_GL_KHR_blend_equation_advanced(load, userptr); + glad_gl_load_GL_KHR_debug(load, userptr); + glad_gl_load_GL_KHR_parallel_shader_compile(load, userptr); + glad_gl_load_GL_KHR_robustness(load, userptr); + glad_gl_load_GL_MESA_framebuffer_flip_y(load, userptr); + glad_gl_load_GL_MESA_resize_buffers(load, userptr); + glad_gl_load_GL_MESA_window_pos(load, userptr); + glad_gl_load_GL_NVX_conditional_render(load, userptr); + glad_gl_load_GL_NVX_gpu_multicast2(load, userptr); + glad_gl_load_GL_NVX_linked_gpu_multicast(load, userptr); + glad_gl_load_GL_NVX_progress_fence(load, userptr); + glad_gl_load_GL_NV_alpha_to_coverage_dither_control(load, userptr); + glad_gl_load_GL_NV_bindless_multi_draw_indirect(load, userptr); + glad_gl_load_GL_NV_bindless_multi_draw_indirect_count(load, userptr); + glad_gl_load_GL_NV_bindless_texture(load, userptr); + glad_gl_load_GL_NV_blend_equation_advanced(load, userptr); + glad_gl_load_GL_NV_clip_space_w_scaling(load, userptr); + glad_gl_load_GL_NV_command_list(load, userptr); + glad_gl_load_GL_NV_conditional_render(load, userptr); + glad_gl_load_GL_NV_conservative_raster(load, userptr); + glad_gl_load_GL_NV_conservative_raster_dilate(load, userptr); + glad_gl_load_GL_NV_conservative_raster_pre_snap_triangles(load, userptr); + glad_gl_load_GL_NV_copy_image(load, userptr); + glad_gl_load_GL_NV_depth_buffer_float(load, userptr); + glad_gl_load_GL_NV_draw_texture(load, userptr); + glad_gl_load_GL_NV_draw_vulkan_image(load, userptr); + glad_gl_load_GL_NV_evaluators(load, userptr); + glad_gl_load_GL_NV_explicit_multisample(load, userptr); + glad_gl_load_GL_NV_fence(load, userptr); + glad_gl_load_GL_NV_fragment_coverage_to_color(load, userptr); + glad_gl_load_GL_NV_fragment_program(load, userptr); + glad_gl_load_GL_NV_framebuffer_mixed_samples(load, userptr); + glad_gl_load_GL_NV_framebuffer_multisample_coverage(load, userptr); + glad_gl_load_GL_NV_geometry_program4(load, userptr); + glad_gl_load_GL_NV_gpu_multicast(load, userptr); + glad_gl_load_GL_NV_gpu_program4(load, userptr); + glad_gl_load_GL_NV_gpu_program5(load, userptr); + glad_gl_load_GL_NV_gpu_shader5(load, userptr); + glad_gl_load_GL_NV_half_float(load, userptr); + glad_gl_load_GL_NV_internalformat_sample_query(load, userptr); + glad_gl_load_GL_NV_memory_attachment(load, userptr); + glad_gl_load_GL_NV_memory_object_sparse(load, userptr); + glad_gl_load_GL_NV_mesh_shader(load, userptr); + glad_gl_load_GL_NV_occlusion_query(load, userptr); + glad_gl_load_GL_NV_parameter_buffer_object(load, userptr); + glad_gl_load_GL_NV_path_rendering(load, userptr); + glad_gl_load_GL_NV_pixel_data_range(load, userptr); + glad_gl_load_GL_NV_point_sprite(load, userptr); + glad_gl_load_GL_NV_present_video(load, userptr); + glad_gl_load_GL_NV_primitive_restart(load, userptr); + glad_gl_load_GL_NV_query_resource(load, userptr); + glad_gl_load_GL_NV_query_resource_tag(load, userptr); + glad_gl_load_GL_NV_register_combiners(load, userptr); + glad_gl_load_GL_NV_register_combiners2(load, userptr); + glad_gl_load_GL_NV_sample_locations(load, userptr); + glad_gl_load_GL_NV_scissor_exclusive(load, userptr); + glad_gl_load_GL_NV_shader_buffer_load(load, userptr); + glad_gl_load_GL_NV_shading_rate_image(load, userptr); + glad_gl_load_GL_NV_texture_barrier(load, userptr); + glad_gl_load_GL_NV_texture_multisample(load, userptr); + glad_gl_load_GL_NV_timeline_semaphore(load, userptr); + glad_gl_load_GL_NV_transform_feedback(load, userptr); + glad_gl_load_GL_NV_transform_feedback2(load, userptr); + glad_gl_load_GL_NV_vdpau_interop(load, userptr); + glad_gl_load_GL_NV_vdpau_interop2(load, userptr); + glad_gl_load_GL_NV_vertex_array_range(load, userptr); + glad_gl_load_GL_NV_vertex_attrib_integer_64bit(load, userptr); + glad_gl_load_GL_NV_vertex_buffer_unified_memory(load, userptr); + glad_gl_load_GL_NV_vertex_program(load, userptr); + glad_gl_load_GL_NV_vertex_program4(load, userptr); + glad_gl_load_GL_NV_video_capture(load, userptr); + glad_gl_load_GL_NV_viewport_swizzle(load, userptr); + glad_gl_load_GL_OES_byte_coordinates(load, userptr); + glad_gl_load_GL_OES_fixed_point(load, userptr); + glad_gl_load_GL_OES_query_matrix(load, userptr); + glad_gl_load_GL_OES_single_precision(load, userptr); + glad_gl_load_GL_OVR_multiview(load, userptr); + glad_gl_load_GL_PGI_misc_hints(load, userptr); + glad_gl_load_GL_SGIS_detail_texture(load, userptr); + glad_gl_load_GL_SGIS_fog_function(load, userptr); + glad_gl_load_GL_SGIS_multisample(load, userptr); + glad_gl_load_GL_SGIS_pixel_texture(load, userptr); + glad_gl_load_GL_SGIS_point_parameters(load, userptr); + glad_gl_load_GL_SGIS_sharpen_texture(load, userptr); + glad_gl_load_GL_SGIS_texture4D(load, userptr); + glad_gl_load_GL_SGIS_texture_color_mask(load, userptr); + glad_gl_load_GL_SGIS_texture_filter4(load, userptr); + glad_gl_load_GL_SGIX_async(load, userptr); + glad_gl_load_GL_SGIX_flush_raster(load, userptr); + glad_gl_load_GL_SGIX_fragment_lighting(load, userptr); + glad_gl_load_GL_SGIX_framezoom(load, userptr); + glad_gl_load_GL_SGIX_igloo_interface(load, userptr); + glad_gl_load_GL_SGIX_instruments(load, userptr); + glad_gl_load_GL_SGIX_list_priority(load, userptr); + glad_gl_load_GL_SGIX_pixel_texture(load, userptr); + glad_gl_load_GL_SGIX_polynomial_ffd(load, userptr); + glad_gl_load_GL_SGIX_reference_plane(load, userptr); + glad_gl_load_GL_SGIX_sprite(load, userptr); + glad_gl_load_GL_SGIX_tag_sample_buffer(load, userptr); + glad_gl_load_GL_SGI_color_table(load, userptr); + glad_gl_load_GL_SUNX_constant_data(load, userptr); + glad_gl_load_GL_SUN_global_alpha(load, userptr); + glad_gl_load_GL_SUN_mesh_array(load, userptr); + glad_gl_load_GL_SUN_triangle_list(load, userptr); + glad_gl_load_GL_SUN_vertex(load, userptr); + glad_gl_load_GL_EXT_separate_shader_objects(load, userptr); + + + glad_gl_resolve_aliases(); + + return version; +} + + +int gladLoadGL( GLADloadfunc load) { + return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + +static int glad_gl_find_extensions_gles1(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_GL_EXT_blend_minmax = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_minmax"); + GLAD_GL_EXT_debug_marker = glad_gl_has_extension(exts, exts_i, "GL_EXT_debug_marker"); + GLAD_GL_EXT_multi_draw_arrays = glad_gl_has_extension(exts, exts_i, "GL_EXT_multi_draw_arrays"); + GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_anisotropic"); + GLAD_GL_EXT_texture_lod_bias = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_lod_bias"); + GLAD_GL_EXT_texture_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_storage"); + GLAD_GL_KHR_debug = glad_gl_has_extension(exts, exts_i, "GL_KHR_debug"); + GLAD_GL_NV_fence = glad_gl_has_extension(exts, exts_i, "GL_NV_fence"); + GLAD_GL_OES_byte_coordinates = glad_gl_has_extension(exts, exts_i, "GL_OES_byte_coordinates"); + GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_paletted_texture"); + GLAD_GL_OES_fixed_point = glad_gl_has_extension(exts, exts_i, "GL_OES_fixed_point"); + GLAD_GL_OES_query_matrix = glad_gl_has_extension(exts, exts_i, "GL_OES_query_matrix"); + GLAD_GL_OES_read_format = glad_gl_has_extension(exts, exts_i, "GL_OES_read_format"); + GLAD_GL_OES_single_precision = glad_gl_has_extension(exts, exts_i, "GL_OES_single_precision"); + GLAD_GL_AMD_compressed_3DC_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_compressed_3DC_texture"); + GLAD_GL_AMD_compressed_ATC_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_compressed_ATC_texture"); + GLAD_GL_APPLE_copy_texture_levels = glad_gl_has_extension(exts, exts_i, "GL_APPLE_copy_texture_levels"); + GLAD_GL_APPLE_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_APPLE_framebuffer_multisample"); + GLAD_GL_APPLE_sync = glad_gl_has_extension(exts, exts_i, "GL_APPLE_sync"); + GLAD_GL_APPLE_texture_2D_limited_npot = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_2D_limited_npot"); + GLAD_GL_APPLE_texture_format_BGRA8888 = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_format_BGRA8888"); + GLAD_GL_APPLE_texture_max_level = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_max_level"); + GLAD_GL_ARM_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_ARM_rgba8"); + GLAD_GL_EXT_discard_framebuffer = glad_gl_has_extension(exts, exts_i, "GL_EXT_discard_framebuffer"); + GLAD_GL_EXT_map_buffer_range = glad_gl_has_extension(exts, exts_i, "GL_EXT_map_buffer_range"); + GLAD_GL_EXT_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisampled_render_to_texture"); + GLAD_GL_EXT_read_format_bgra = glad_gl_has_extension(exts, exts_i, "GL_EXT_read_format_bgra"); + GLAD_GL_EXT_robustness = glad_gl_has_extension(exts, exts_i, "GL_EXT_robustness"); + GLAD_GL_EXT_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_sRGB"); + GLAD_GL_EXT_texture_compression_dxt1 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_dxt1"); + GLAD_GL_EXT_texture_format_BGRA8888 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_format_BGRA8888"); + GLAD_GL_IMG_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_IMG_multisampled_render_to_texture"); + GLAD_GL_IMG_read_format = glad_gl_has_extension(exts, exts_i, "GL_IMG_read_format"); + GLAD_GL_IMG_texture_compression_pvrtc = glad_gl_has_extension(exts, exts_i, "GL_IMG_texture_compression_pvrtc"); + GLAD_GL_IMG_texture_env_enhanced_fixed_function = glad_gl_has_extension(exts, exts_i, "GL_IMG_texture_env_enhanced_fixed_function"); + GLAD_GL_IMG_user_clip_plane = glad_gl_has_extension(exts, exts_i, "GL_IMG_user_clip_plane"); + GLAD_GL_OES_EGL_image = glad_gl_has_extension(exts, exts_i, "GL_OES_EGL_image"); + GLAD_GL_OES_EGL_image_external = glad_gl_has_extension(exts, exts_i, "GL_OES_EGL_image_external"); + GLAD_GL_OES_blend_equation_separate = glad_gl_has_extension(exts, exts_i, "GL_OES_blend_equation_separate"); + GLAD_GL_OES_blend_func_separate = glad_gl_has_extension(exts, exts_i, "GL_OES_blend_func_separate"); + GLAD_GL_OES_blend_subtract = glad_gl_has_extension(exts, exts_i, "GL_OES_blend_subtract"); + GLAD_GL_OES_compressed_ETC1_RGB8_sub_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_ETC1_RGB8_sub_texture"); + GLAD_GL_OES_compressed_ETC1_RGB8_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_ETC1_RGB8_texture"); + GLAD_GL_OES_depth24 = glad_gl_has_extension(exts, exts_i, "GL_OES_depth24"); + GLAD_GL_OES_depth32 = glad_gl_has_extension(exts, exts_i, "GL_OES_depth32"); + GLAD_GL_OES_draw_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_draw_texture"); + GLAD_GL_OES_element_index_uint = glad_gl_has_extension(exts, exts_i, "GL_OES_element_index_uint"); + GLAD_GL_OES_extended_matrix_palette = glad_gl_has_extension(exts, exts_i, "GL_OES_extended_matrix_palette"); + GLAD_GL_OES_fbo_render_mipmap = glad_gl_has_extension(exts, exts_i, "GL_OES_fbo_render_mipmap"); + GLAD_GL_OES_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_OES_framebuffer_object"); + GLAD_GL_OES_mapbuffer = glad_gl_has_extension(exts, exts_i, "GL_OES_mapbuffer"); + GLAD_GL_OES_matrix_get = glad_gl_has_extension(exts, exts_i, "GL_OES_matrix_get"); + GLAD_GL_OES_matrix_palette = glad_gl_has_extension(exts, exts_i, "GL_OES_matrix_palette"); + GLAD_GL_OES_packed_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_OES_packed_depth_stencil"); + GLAD_GL_OES_point_size_array = glad_gl_has_extension(exts, exts_i, "GL_OES_point_size_array"); + GLAD_GL_OES_point_sprite = glad_gl_has_extension(exts, exts_i, "GL_OES_point_sprite"); + GLAD_GL_OES_required_internalformat = glad_gl_has_extension(exts, exts_i, "GL_OES_required_internalformat"); + GLAD_GL_OES_rgb8_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_OES_rgb8_rgba8"); + GLAD_GL_OES_stencil1 = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil1"); + GLAD_GL_OES_stencil4 = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil4"); + GLAD_GL_OES_stencil8 = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil8"); + GLAD_GL_OES_stencil_wrap = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil_wrap"); + GLAD_GL_OES_surfaceless_context = glad_gl_has_extension(exts, exts_i, "GL_OES_surfaceless_context"); + GLAD_GL_OES_texture_cube_map = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_cube_map"); + GLAD_GL_OES_texture_env_crossbar = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_env_crossbar"); + GLAD_GL_OES_texture_mirrored_repeat = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_mirrored_repeat"); + GLAD_GL_OES_texture_npot = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_npot"); + GLAD_GL_OES_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_OES_vertex_array_object"); + GLAD_GL_QCOM_driver_control = glad_gl_has_extension(exts, exts_i, "GL_QCOM_driver_control"); + GLAD_GL_QCOM_extended_get = glad_gl_has_extension(exts, exts_i, "GL_QCOM_extended_get"); + GLAD_GL_QCOM_extended_get2 = glad_gl_has_extension(exts, exts_i, "GL_QCOM_extended_get2"); + GLAD_GL_QCOM_perfmon_global_mode = glad_gl_has_extension(exts, exts_i, "GL_QCOM_perfmon_global_mode"); + GLAD_GL_QCOM_tiled_rendering = glad_gl_has_extension(exts, exts_i, "GL_QCOM_tiled_rendering"); + GLAD_GL_QCOM_writeonly_rendering = glad_gl_has_extension(exts, exts_i, "GL_QCOM_writeonly_rendering"); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gles1(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_VERSION_ES_CM_1_0 = (major == 1 && minor >= 0) || major > 1; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLES1UserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gles1(); + + glad_gl_load_GL_VERSION_ES_CM_1_0(load, userptr); + + if (!glad_gl_find_extensions_gles1()) return 0; + glad_gl_load_GL_EXT_blend_minmax(load, userptr); + glad_gl_load_GL_EXT_debug_marker(load, userptr); + glad_gl_load_GL_EXT_multi_draw_arrays(load, userptr); + glad_gl_load_GL_EXT_texture_storage(load, userptr); + glad_gl_load_GL_KHR_debug(load, userptr); + glad_gl_load_GL_NV_fence(load, userptr); + glad_gl_load_GL_OES_byte_coordinates(load, userptr); + glad_gl_load_GL_OES_fixed_point(load, userptr); + glad_gl_load_GL_OES_query_matrix(load, userptr); + glad_gl_load_GL_OES_single_precision(load, userptr); + glad_gl_load_GL_APPLE_copy_texture_levels(load, userptr); + glad_gl_load_GL_APPLE_framebuffer_multisample(load, userptr); + glad_gl_load_GL_APPLE_sync(load, userptr); + glad_gl_load_GL_EXT_discard_framebuffer(load, userptr); + glad_gl_load_GL_EXT_map_buffer_range(load, userptr); + glad_gl_load_GL_EXT_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_EXT_robustness(load, userptr); + glad_gl_load_GL_IMG_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_IMG_user_clip_plane(load, userptr); + glad_gl_load_GL_OES_EGL_image(load, userptr); + glad_gl_load_GL_OES_blend_equation_separate(load, userptr); + glad_gl_load_GL_OES_blend_func_separate(load, userptr); + glad_gl_load_GL_OES_blend_subtract(load, userptr); + glad_gl_load_GL_OES_draw_texture(load, userptr); + glad_gl_load_GL_OES_framebuffer_object(load, userptr); + glad_gl_load_GL_OES_mapbuffer(load, userptr); + glad_gl_load_GL_OES_matrix_palette(load, userptr); + glad_gl_load_GL_OES_point_size_array(load, userptr); + glad_gl_load_GL_OES_texture_cube_map(load, userptr); + glad_gl_load_GL_OES_vertex_array_object(load, userptr); + glad_gl_load_GL_QCOM_driver_control(load, userptr); + glad_gl_load_GL_QCOM_extended_get(load, userptr); + glad_gl_load_GL_QCOM_extended_get2(load, userptr); + glad_gl_load_GL_QCOM_tiled_rendering(load, userptr); + + + glad_gl_resolve_aliases(); + + return version; +} + + +int gladLoadGLES1( GLADloadfunc load) { + return gladLoadGLES1UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + +static int glad_gl_find_extensions_gles2(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_GL_AMD_framebuffer_multisample_advanced = glad_gl_has_extension(exts, exts_i, "GL_AMD_framebuffer_multisample_advanced"); + GLAD_GL_AMD_performance_monitor = glad_gl_has_extension(exts, exts_i, "GL_AMD_performance_monitor"); + GLAD_GL_APPLE_rgb_422 = glad_gl_has_extension(exts, exts_i, "GL_APPLE_rgb_422"); + GLAD_GL_EXT_EGL_image_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_storage"); + GLAD_GL_EXT_blend_minmax = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_minmax"); + GLAD_GL_EXT_debug_label = glad_gl_has_extension(exts, exts_i, "GL_EXT_debug_label"); + GLAD_GL_EXT_debug_marker = glad_gl_has_extension(exts, exts_i, "GL_EXT_debug_marker"); + GLAD_GL_EXT_draw_instanced = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_instanced"); + GLAD_GL_EXT_external_buffer = glad_gl_has_extension(exts, exts_i, "GL_EXT_external_buffer"); + GLAD_GL_EXT_framebuffer_blit_layers = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit_layers"); + GLAD_GL_EXT_memory_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object"); + GLAD_GL_EXT_memory_object_fd = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object_fd"); + GLAD_GL_EXT_memory_object_win32 = glad_gl_has_extension(exts, exts_i, "GL_EXT_memory_object_win32"); + GLAD_GL_EXT_multi_draw_arrays = glad_gl_has_extension(exts, exts_i, "GL_EXT_multi_draw_arrays"); + GLAD_GL_EXT_multiview_tessellation_geometry_shader = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_tessellation_geometry_shader"); + GLAD_GL_EXT_multiview_texture_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_texture_multisample"); + GLAD_GL_EXT_multiview_timer_query = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_timer_query"); + GLAD_GL_EXT_polygon_offset_clamp = glad_gl_has_extension(exts, exts_i, "GL_EXT_polygon_offset_clamp"); + GLAD_GL_EXT_post_depth_coverage = glad_gl_has_extension(exts, exts_i, "GL_EXT_post_depth_coverage"); + GLAD_GL_EXT_raster_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_raster_multisample"); + GLAD_GL_EXT_semaphore = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore"); + GLAD_GL_EXT_semaphore_fd = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore_fd"); + GLAD_GL_EXT_semaphore_win32 = glad_gl_has_extension(exts, exts_i, "GL_EXT_semaphore_win32"); + GLAD_GL_EXT_shader_framebuffer_fetch = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_framebuffer_fetch"); + GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_framebuffer_fetch_non_coherent"); + GLAD_GL_EXT_shader_integer_mix = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_integer_mix"); + GLAD_GL_EXT_shader_samples_identical = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_samples_identical"); + GLAD_GL_EXT_sparse_texture2 = glad_gl_has_extension(exts, exts_i, "GL_EXT_sparse_texture2"); + GLAD_GL_EXT_texture_compression_rgtc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_rgtc"); + GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc"); + GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_anisotropic"); + GLAD_GL_EXT_texture_filter_minmax = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_minmax"); + GLAD_GL_EXT_texture_sRGB_R8 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_R8"); + GLAD_GL_EXT_texture_sRGB_RG8 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_RG8"); + GLAD_GL_EXT_texture_sRGB_decode = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB_decode"); + GLAD_GL_EXT_texture_shadow_lod = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_shadow_lod"); + GLAD_GL_EXT_texture_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_storage"); + GLAD_GL_EXT_win32_keyed_mutex = glad_gl_has_extension(exts, exts_i, "GL_EXT_win32_keyed_mutex"); + GLAD_GL_EXT_window_rectangles = glad_gl_has_extension(exts, exts_i, "GL_EXT_window_rectangles"); + GLAD_GL_INTEL_blackhole_render = glad_gl_has_extension(exts, exts_i, "GL_INTEL_blackhole_render"); + GLAD_GL_INTEL_conservative_rasterization = glad_gl_has_extension(exts, exts_i, "GL_INTEL_conservative_rasterization"); + GLAD_GL_INTEL_framebuffer_CMAA = glad_gl_has_extension(exts, exts_i, "GL_INTEL_framebuffer_CMAA"); + GLAD_GL_INTEL_performance_query = glad_gl_has_extension(exts, exts_i, "GL_INTEL_performance_query"); + GLAD_GL_KHR_blend_equation_advanced = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced"); + GLAD_GL_KHR_blend_equation_advanced_coherent = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced_coherent"); + GLAD_GL_KHR_context_flush_control = glad_gl_has_extension(exts, exts_i, "GL_KHR_context_flush_control"); + GLAD_GL_KHR_debug = glad_gl_has_extension(exts, exts_i, "GL_KHR_debug"); + GLAD_GL_KHR_no_error = glad_gl_has_extension(exts, exts_i, "GL_KHR_no_error"); + GLAD_GL_KHR_parallel_shader_compile = glad_gl_has_extension(exts, exts_i, "GL_KHR_parallel_shader_compile"); + GLAD_GL_KHR_robust_buffer_access_behavior = glad_gl_has_extension(exts, exts_i, "GL_KHR_robust_buffer_access_behavior"); + GLAD_GL_KHR_robustness = glad_gl_has_extension(exts, exts_i, "GL_KHR_robustness"); + GLAD_GL_KHR_shader_subgroup = glad_gl_has_extension(exts, exts_i, "GL_KHR_shader_subgroup"); + GLAD_GL_KHR_texture_compression_astc_hdr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_hdr"); + GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_ldr"); + GLAD_GL_KHR_texture_compression_astc_sliced_3d = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_sliced_3d"); + GLAD_GL_MESA_framebuffer_flip_x = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_flip_x"); + GLAD_GL_MESA_framebuffer_flip_y = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_flip_y"); + GLAD_GL_MESA_framebuffer_swap_xy = glad_gl_has_extension(exts, exts_i, "GL_MESA_framebuffer_swap_xy"); + GLAD_GL_MESA_program_binary_formats = glad_gl_has_extension(exts, exts_i, "GL_MESA_program_binary_formats"); + GLAD_GL_MESA_shader_integer_functions = glad_gl_has_extension(exts, exts_i, "GL_MESA_shader_integer_functions"); + GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_NVX_blend_equation_advanced_multi_draw_buffers"); + GLAD_GL_NV_bindless_texture = glad_gl_has_extension(exts, exts_i, "GL_NV_bindless_texture"); + GLAD_GL_NV_blend_equation_advanced = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_equation_advanced"); + GLAD_GL_NV_blend_equation_advanced_coherent = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_equation_advanced_coherent"); + GLAD_GL_NV_blend_minmax_factor = glad_gl_has_extension(exts, exts_i, "GL_NV_blend_minmax_factor"); + GLAD_GL_NV_clip_space_w_scaling = glad_gl_has_extension(exts, exts_i, "GL_NV_clip_space_w_scaling"); + GLAD_GL_NV_compute_shader_derivatives = glad_gl_has_extension(exts, exts_i, "GL_NV_compute_shader_derivatives"); + GLAD_GL_NV_conditional_render = glad_gl_has_extension(exts, exts_i, "GL_NV_conditional_render"); + GLAD_GL_NV_conservative_raster = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster"); + GLAD_GL_NV_conservative_raster_pre_snap = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_pre_snap"); + GLAD_GL_NV_conservative_raster_pre_snap_triangles = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster_pre_snap_triangles"); + GLAD_GL_NV_draw_vulkan_image = glad_gl_has_extension(exts, exts_i, "GL_NV_draw_vulkan_image"); + GLAD_GL_NV_fence = glad_gl_has_extension(exts, exts_i, "GL_NV_fence"); + GLAD_GL_NV_fill_rectangle = glad_gl_has_extension(exts, exts_i, "GL_NV_fill_rectangle"); + GLAD_GL_NV_fragment_coverage_to_color = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_coverage_to_color"); + GLAD_GL_NV_fragment_shader_barycentric = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_shader_barycentric"); + GLAD_GL_NV_fragment_shader_interlock = glad_gl_has_extension(exts, exts_i, "GL_NV_fragment_shader_interlock"); + GLAD_GL_NV_framebuffer_mixed_samples = glad_gl_has_extension(exts, exts_i, "GL_NV_framebuffer_mixed_samples"); + GLAD_GL_NV_geometry_shader_passthrough = glad_gl_has_extension(exts, exts_i, "GL_NV_geometry_shader_passthrough"); + GLAD_GL_NV_gpu_shader5 = glad_gl_has_extension(exts, exts_i, "GL_NV_gpu_shader5"); + GLAD_GL_NV_internalformat_sample_query = glad_gl_has_extension(exts, exts_i, "GL_NV_internalformat_sample_query"); + GLAD_GL_NV_memory_attachment = glad_gl_has_extension(exts, exts_i, "GL_NV_memory_attachment"); + GLAD_GL_NV_memory_object_sparse = glad_gl_has_extension(exts, exts_i, "GL_NV_memory_object_sparse"); + GLAD_GL_NV_mesh_shader = glad_gl_has_extension(exts, exts_i, "GL_NV_mesh_shader"); + GLAD_GL_NV_path_rendering = glad_gl_has_extension(exts, exts_i, "GL_NV_path_rendering"); + GLAD_GL_NV_path_rendering_shared_edge = glad_gl_has_extension(exts, exts_i, "GL_NV_path_rendering_shared_edge"); + GLAD_GL_NV_primitive_shading_rate = glad_gl_has_extension(exts, exts_i, "GL_NV_primitive_shading_rate"); + GLAD_GL_NV_representative_fragment_test = glad_gl_has_extension(exts, exts_i, "GL_NV_representative_fragment_test"); + GLAD_GL_NV_sample_locations = glad_gl_has_extension(exts, exts_i, "GL_NV_sample_locations"); + GLAD_GL_NV_sample_mask_override_coverage = glad_gl_has_extension(exts, exts_i, "GL_NV_sample_mask_override_coverage"); + GLAD_GL_NV_scissor_exclusive = glad_gl_has_extension(exts, exts_i, "GL_NV_scissor_exclusive"); + GLAD_GL_NV_shader_atomic_fp16_vector = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_atomic_fp16_vector"); + GLAD_GL_NV_shader_subgroup_partitioned = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_subgroup_partitioned"); + GLAD_GL_NV_shader_texture_footprint = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_texture_footprint"); + GLAD_GL_NV_shading_rate_image = glad_gl_has_extension(exts, exts_i, "GL_NV_shading_rate_image"); + GLAD_GL_NV_stereo_view_rendering = glad_gl_has_extension(exts, exts_i, "GL_NV_stereo_view_rendering"); + GLAD_GL_NV_timeline_semaphore = glad_gl_has_extension(exts, exts_i, "GL_NV_timeline_semaphore"); + GLAD_GL_NV_viewport_array2 = glad_gl_has_extension(exts, exts_i, "GL_NV_viewport_array2"); + GLAD_GL_NV_viewport_swizzle = glad_gl_has_extension(exts, exts_i, "GL_NV_viewport_swizzle"); + GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_paletted_texture"); + GLAD_GL_OVR_multiview = glad_gl_has_extension(exts, exts_i, "GL_OVR_multiview"); + GLAD_GL_OVR_multiview2 = glad_gl_has_extension(exts, exts_i, "GL_OVR_multiview2"); + GLAD_GL_AMD_compressed_3DC_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_compressed_3DC_texture"); + GLAD_GL_AMD_compressed_ATC_texture = glad_gl_has_extension(exts, exts_i, "GL_AMD_compressed_ATC_texture"); + GLAD_GL_APPLE_copy_texture_levels = glad_gl_has_extension(exts, exts_i, "GL_APPLE_copy_texture_levels"); + GLAD_GL_APPLE_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_APPLE_framebuffer_multisample"); + GLAD_GL_APPLE_sync = glad_gl_has_extension(exts, exts_i, "GL_APPLE_sync"); + GLAD_GL_APPLE_texture_format_BGRA8888 = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_format_BGRA8888"); + GLAD_GL_APPLE_texture_max_level = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_max_level"); + GLAD_GL_ARM_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_ARM_rgba8"); + GLAD_GL_EXT_discard_framebuffer = glad_gl_has_extension(exts, exts_i, "GL_EXT_discard_framebuffer"); + GLAD_GL_EXT_map_buffer_range = glad_gl_has_extension(exts, exts_i, "GL_EXT_map_buffer_range"); + GLAD_GL_EXT_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisampled_render_to_texture"); + GLAD_GL_EXT_read_format_bgra = glad_gl_has_extension(exts, exts_i, "GL_EXT_read_format_bgra"); + GLAD_GL_EXT_robustness = glad_gl_has_extension(exts, exts_i, "GL_EXT_robustness"); + GLAD_GL_EXT_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_sRGB"); + GLAD_GL_EXT_texture_compression_dxt1 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_dxt1"); + GLAD_GL_EXT_texture_format_BGRA8888 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_format_BGRA8888"); + GLAD_GL_IMG_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_IMG_multisampled_render_to_texture"); + GLAD_GL_IMG_read_format = glad_gl_has_extension(exts, exts_i, "GL_IMG_read_format"); + GLAD_GL_IMG_texture_compression_pvrtc = glad_gl_has_extension(exts, exts_i, "GL_IMG_texture_compression_pvrtc"); + GLAD_GL_OES_EGL_image = glad_gl_has_extension(exts, exts_i, "GL_OES_EGL_image"); + GLAD_GL_OES_EGL_image_external = glad_gl_has_extension(exts, exts_i, "GL_OES_EGL_image_external"); + GLAD_GL_OES_compressed_ETC1_RGB8_sub_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_ETC1_RGB8_sub_texture"); + GLAD_GL_OES_compressed_ETC1_RGB8_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_compressed_ETC1_RGB8_texture"); + GLAD_GL_OES_depth24 = glad_gl_has_extension(exts, exts_i, "GL_OES_depth24"); + GLAD_GL_OES_depth32 = glad_gl_has_extension(exts, exts_i, "GL_OES_depth32"); + GLAD_GL_OES_element_index_uint = glad_gl_has_extension(exts, exts_i, "GL_OES_element_index_uint"); + GLAD_GL_OES_fbo_render_mipmap = glad_gl_has_extension(exts, exts_i, "GL_OES_fbo_render_mipmap"); + GLAD_GL_OES_mapbuffer = glad_gl_has_extension(exts, exts_i, "GL_OES_mapbuffer"); + GLAD_GL_OES_packed_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_OES_packed_depth_stencil"); + GLAD_GL_OES_required_internalformat = glad_gl_has_extension(exts, exts_i, "GL_OES_required_internalformat"); + GLAD_GL_OES_rgb8_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_OES_rgb8_rgba8"); + GLAD_GL_OES_stencil1 = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil1"); + GLAD_GL_OES_stencil4 = glad_gl_has_extension(exts, exts_i, "GL_OES_stencil4"); + GLAD_GL_OES_surfaceless_context = glad_gl_has_extension(exts, exts_i, "GL_OES_surfaceless_context"); + GLAD_GL_OES_texture_npot = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_npot"); + GLAD_GL_OES_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_OES_vertex_array_object"); + GLAD_GL_QCOM_driver_control = glad_gl_has_extension(exts, exts_i, "GL_QCOM_driver_control"); + GLAD_GL_QCOM_extended_get = glad_gl_has_extension(exts, exts_i, "GL_QCOM_extended_get"); + GLAD_GL_QCOM_extended_get2 = glad_gl_has_extension(exts, exts_i, "GL_QCOM_extended_get2"); + GLAD_GL_QCOM_perfmon_global_mode = glad_gl_has_extension(exts, exts_i, "GL_QCOM_perfmon_global_mode"); + GLAD_GL_QCOM_tiled_rendering = glad_gl_has_extension(exts, exts_i, "GL_QCOM_tiled_rendering"); + GLAD_GL_QCOM_writeonly_rendering = glad_gl_has_extension(exts, exts_i, "GL_QCOM_writeonly_rendering"); + GLAD_GL_AMD_program_binary_Z400 = glad_gl_has_extension(exts, exts_i, "GL_AMD_program_binary_Z400"); + GLAD_GL_ANDROID_extension_pack_es31a = glad_gl_has_extension(exts, exts_i, "GL_ANDROID_extension_pack_es31a"); + GLAD_GL_ANGLE_depth_texture = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_depth_texture"); + GLAD_GL_ANGLE_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_framebuffer_blit"); + GLAD_GL_ANGLE_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_framebuffer_multisample"); + GLAD_GL_ANGLE_instanced_arrays = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_instanced_arrays"); + GLAD_GL_ANGLE_pack_reverse_row_order = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_pack_reverse_row_order"); + GLAD_GL_ANGLE_program_binary = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_program_binary"); + GLAD_GL_ANGLE_texture_compression_dxt3 = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_texture_compression_dxt3"); + GLAD_GL_ANGLE_texture_compression_dxt5 = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_texture_compression_dxt5"); + GLAD_GL_ANGLE_texture_usage = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_texture_usage"); + GLAD_GL_ANGLE_translated_shader_source = glad_gl_has_extension(exts, exts_i, "GL_ANGLE_translated_shader_source"); + GLAD_GL_APPLE_clip_distance = glad_gl_has_extension(exts, exts_i, "GL_APPLE_clip_distance"); + GLAD_GL_APPLE_color_buffer_packed_float = glad_gl_has_extension(exts, exts_i, "GL_APPLE_color_buffer_packed_float"); + GLAD_GL_APPLE_texture_packed_float = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_packed_float"); + GLAD_GL_ARM_mali_program_binary = glad_gl_has_extension(exts, exts_i, "GL_ARM_mali_program_binary"); + GLAD_GL_ARM_mali_shader_binary = glad_gl_has_extension(exts, exts_i, "GL_ARM_mali_shader_binary"); + GLAD_GL_ARM_shader_core_properties = glad_gl_has_extension(exts, exts_i, "GL_ARM_shader_core_properties"); + GLAD_GL_ARM_shader_framebuffer_fetch = glad_gl_has_extension(exts, exts_i, "GL_ARM_shader_framebuffer_fetch"); + GLAD_GL_ARM_shader_framebuffer_fetch_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_ARM_shader_framebuffer_fetch_depth_stencil"); + GLAD_GL_ARM_texture_unnormalized_coordinates = glad_gl_has_extension(exts, exts_i, "GL_ARM_texture_unnormalized_coordinates"); + GLAD_GL_DMP_program_binary = glad_gl_has_extension(exts, exts_i, "GL_DMP_program_binary"); + GLAD_GL_DMP_shader_binary = glad_gl_has_extension(exts, exts_i, "GL_DMP_shader_binary"); + GLAD_GL_EXT_EGL_image_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_array"); + GLAD_GL_EXT_EGL_image_storage_compression = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_storage_compression"); + GLAD_GL_EXT_YUV_target = glad_gl_has_extension(exts, exts_i, "GL_EXT_YUV_target"); + GLAD_GL_EXT_base_instance = glad_gl_has_extension(exts, exts_i, "GL_EXT_base_instance"); + GLAD_GL_EXT_blend_func_extended = glad_gl_has_extension(exts, exts_i, "GL_EXT_blend_func_extended"); + GLAD_GL_EXT_buffer_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_buffer_storage"); + GLAD_GL_EXT_clear_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_clear_texture"); + GLAD_GL_EXT_clip_control = glad_gl_has_extension(exts, exts_i, "GL_EXT_clip_control"); + GLAD_GL_EXT_clip_cull_distance = glad_gl_has_extension(exts, exts_i, "GL_EXT_clip_cull_distance"); + GLAD_GL_EXT_color_buffer_float = glad_gl_has_extension(exts, exts_i, "GL_EXT_color_buffer_float"); + GLAD_GL_EXT_color_buffer_half_float = glad_gl_has_extension(exts, exts_i, "GL_EXT_color_buffer_half_float"); + GLAD_GL_EXT_conservative_depth = glad_gl_has_extension(exts, exts_i, "GL_EXT_conservative_depth"); + GLAD_GL_EXT_copy_image = glad_gl_has_extension(exts, exts_i, "GL_EXT_copy_image"); + GLAD_GL_EXT_depth_clamp = glad_gl_has_extension(exts, exts_i, "GL_EXT_depth_clamp"); + GLAD_GL_EXT_disjoint_timer_query = glad_gl_has_extension(exts, exts_i, "GL_EXT_disjoint_timer_query"); + GLAD_GL_EXT_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_buffers"); + GLAD_GL_EXT_draw_buffers_indexed = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_buffers_indexed"); + GLAD_GL_EXT_draw_elements_base_vertex = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_elements_base_vertex"); + GLAD_GL_EXT_draw_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_EXT_draw_transform_feedback"); + GLAD_GL_EXT_float_blend = glad_gl_has_extension(exts, exts_i, "GL_EXT_float_blend"); + GLAD_GL_EXT_fragment_shading_rate = glad_gl_has_extension(exts, exts_i, "GL_EXT_fragment_shading_rate"); + GLAD_GL_EXT_geometry_point_size = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_point_size"); + GLAD_GL_EXT_geometry_shader = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_shader"); + GLAD_GL_EXT_gpu_shader5 = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_shader5"); + GLAD_GL_EXT_instanced_arrays = glad_gl_has_extension(exts, exts_i, "GL_EXT_instanced_arrays"); + GLAD_GL_EXT_multi_draw_indirect = glad_gl_has_extension(exts, exts_i, "GL_EXT_multi_draw_indirect"); + GLAD_GL_EXT_multisampled_compatibility = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisampled_compatibility"); + GLAD_GL_EXT_multisampled_render_to_texture2 = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisampled_render_to_texture2"); + GLAD_GL_EXT_multiview_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_EXT_multiview_draw_buffers"); + GLAD_GL_EXT_occlusion_query_boolean = glad_gl_has_extension(exts, exts_i, "GL_EXT_occlusion_query_boolean"); + GLAD_GL_EXT_primitive_bounding_box = glad_gl_has_extension(exts, exts_i, "GL_EXT_primitive_bounding_box"); + GLAD_GL_EXT_protected_textures = glad_gl_has_extension(exts, exts_i, "GL_EXT_protected_textures"); + GLAD_GL_EXT_pvrtc_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_pvrtc_sRGB"); + GLAD_GL_EXT_render_snorm = glad_gl_has_extension(exts, exts_i, "GL_EXT_render_snorm"); + GLAD_GL_EXT_sRGB_write_control = glad_gl_has_extension(exts, exts_i, "GL_EXT_sRGB_write_control"); + GLAD_GL_EXT_separate_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_EXT_separate_depth_stencil"); + GLAD_GL_EXT_separate_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_EXT_separate_shader_objects"); + GLAD_GL_EXT_shader_group_vote = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_group_vote"); + GLAD_GL_EXT_shader_implicit_conversions = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_implicit_conversions"); + GLAD_GL_EXT_shader_io_blocks = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_io_blocks"); + GLAD_GL_EXT_shader_non_constant_global_initializers = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_non_constant_global_initializers"); + GLAD_GL_EXT_shader_pixel_local_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_pixel_local_storage"); + GLAD_GL_EXT_shader_pixel_local_storage2 = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_pixel_local_storage2"); + GLAD_GL_EXT_shader_texture_lod = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_texture_lod"); + GLAD_GL_EXT_shadow_samplers = glad_gl_has_extension(exts, exts_i, "GL_EXT_shadow_samplers"); + GLAD_GL_EXT_sparse_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_sparse_texture"); + GLAD_GL_EXT_tessellation_point_size = glad_gl_has_extension(exts, exts_i, "GL_EXT_tessellation_point_size"); + GLAD_GL_EXT_tessellation_shader = glad_gl_has_extension(exts, exts_i, "GL_EXT_tessellation_shader"); + GLAD_GL_EXT_texture_border_clamp = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_border_clamp"); + GLAD_GL_EXT_texture_buffer = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_buffer"); + GLAD_GL_EXT_texture_compression_astc_decode_mode = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_astc_decode_mode"); + GLAD_GL_EXT_texture_compression_bptc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_bptc"); + GLAD_GL_EXT_texture_compression_s3tc_srgb = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc_srgb"); + GLAD_GL_EXT_texture_cube_map_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_cube_map_array"); + GLAD_GL_EXT_texture_format_sRGB_override = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_format_sRGB_override"); + GLAD_GL_EXT_texture_mirror_clamp_to_edge = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_mirror_clamp_to_edge"); + GLAD_GL_EXT_texture_norm16 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_norm16"); + GLAD_GL_EXT_texture_query_lod = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_query_lod"); + GLAD_GL_EXT_texture_rg = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_rg"); + GLAD_GL_EXT_texture_storage_compression = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_storage_compression"); + GLAD_GL_EXT_texture_type_2_10_10_10_REV = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_type_2_10_10_10_REV"); + GLAD_GL_EXT_texture_view = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_view"); + GLAD_GL_EXT_unpack_subimage = glad_gl_has_extension(exts, exts_i, "GL_EXT_unpack_subimage"); + GLAD_GL_FJ_shader_binary_GCCSO = glad_gl_has_extension(exts, exts_i, "GL_FJ_shader_binary_GCCSO"); + GLAD_GL_IMG_bindless_texture = glad_gl_has_extension(exts, exts_i, "GL_IMG_bindless_texture"); + GLAD_GL_IMG_framebuffer_downsample = glad_gl_has_extension(exts, exts_i, "GL_IMG_framebuffer_downsample"); + GLAD_GL_IMG_program_binary = glad_gl_has_extension(exts, exts_i, "GL_IMG_program_binary"); + GLAD_GL_IMG_shader_binary = glad_gl_has_extension(exts, exts_i, "GL_IMG_shader_binary"); + GLAD_GL_IMG_texture_compression_pvrtc2 = glad_gl_has_extension(exts, exts_i, "GL_IMG_texture_compression_pvrtc2"); + GLAD_GL_IMG_texture_filter_cubic = glad_gl_has_extension(exts, exts_i, "GL_IMG_texture_filter_cubic"); + GLAD_GL_MESA_bgra = glad_gl_has_extension(exts, exts_i, "GL_MESA_bgra"); + GLAD_GL_MESA_sampler_objects = glad_gl_has_extension(exts, exts_i, "GL_MESA_sampler_objects"); + GLAD_GL_NV_copy_buffer = glad_gl_has_extension(exts, exts_i, "GL_NV_copy_buffer"); + GLAD_GL_NV_coverage_sample = glad_gl_has_extension(exts, exts_i, "GL_NV_coverage_sample"); + GLAD_GL_NV_depth_nonlinear = glad_gl_has_extension(exts, exts_i, "GL_NV_depth_nonlinear"); + GLAD_GL_NV_draw_buffers = glad_gl_has_extension(exts, exts_i, "GL_NV_draw_buffers"); + GLAD_GL_NV_draw_instanced = glad_gl_has_extension(exts, exts_i, "GL_NV_draw_instanced"); + GLAD_GL_NV_explicit_attrib_location = glad_gl_has_extension(exts, exts_i, "GL_NV_explicit_attrib_location"); + GLAD_GL_NV_fbo_color_attachments = glad_gl_has_extension(exts, exts_i, "GL_NV_fbo_color_attachments"); + GLAD_GL_NV_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_NV_framebuffer_blit"); + GLAD_GL_NV_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_NV_framebuffer_multisample"); + GLAD_GL_NV_generate_mipmap_sRGB = glad_gl_has_extension(exts, exts_i, "GL_NV_generate_mipmap_sRGB"); + GLAD_GL_NV_image_formats = glad_gl_has_extension(exts, exts_i, "GL_NV_image_formats"); + GLAD_GL_NV_instanced_arrays = glad_gl_has_extension(exts, exts_i, "GL_NV_instanced_arrays"); + GLAD_GL_NV_non_square_matrices = glad_gl_has_extension(exts, exts_i, "GL_NV_non_square_matrices"); + GLAD_GL_NV_pack_subimage = glad_gl_has_extension(exts, exts_i, "GL_NV_pack_subimage"); + GLAD_GL_NV_pixel_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_NV_pixel_buffer_object"); + GLAD_GL_NV_polygon_mode = glad_gl_has_extension(exts, exts_i, "GL_NV_polygon_mode"); + GLAD_GL_NV_read_buffer = glad_gl_has_extension(exts, exts_i, "GL_NV_read_buffer"); + GLAD_GL_NV_read_buffer_front = glad_gl_has_extension(exts, exts_i, "GL_NV_read_buffer_front"); + GLAD_GL_NV_read_depth = glad_gl_has_extension(exts, exts_i, "GL_NV_read_depth"); + GLAD_GL_NV_read_depth_stencil = glad_gl_has_extension(exts, exts_i, "GL_NV_read_depth_stencil"); + GLAD_GL_NV_read_stencil = glad_gl_has_extension(exts, exts_i, "GL_NV_read_stencil"); + GLAD_GL_NV_sRGB_formats = glad_gl_has_extension(exts, exts_i, "GL_NV_sRGB_formats"); + GLAD_GL_NV_shader_noperspective_interpolation = glad_gl_has_extension(exts, exts_i, "GL_NV_shader_noperspective_interpolation"); + GLAD_GL_NV_shadow_samplers_array = glad_gl_has_extension(exts, exts_i, "GL_NV_shadow_samplers_array"); + GLAD_GL_NV_shadow_samplers_cube = glad_gl_has_extension(exts, exts_i, "GL_NV_shadow_samplers_cube"); + GLAD_GL_NV_texture_border_clamp = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_border_clamp"); + GLAD_GL_NV_texture_compression_s3tc_update = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_compression_s3tc_update"); + GLAD_GL_NV_texture_npot_2D_mipmap = glad_gl_has_extension(exts, exts_i, "GL_NV_texture_npot_2D_mipmap"); + GLAD_GL_NV_viewport_array = glad_gl_has_extension(exts, exts_i, "GL_NV_viewport_array"); + GLAD_GL_OES_EGL_image_external_essl3 = glad_gl_has_extension(exts, exts_i, "GL_OES_EGL_image_external_essl3"); + GLAD_GL_OES_copy_image = glad_gl_has_extension(exts, exts_i, "GL_OES_copy_image"); + GLAD_GL_OES_depth_texture = glad_gl_has_extension(exts, exts_i, "GL_OES_depth_texture"); + GLAD_GL_OES_draw_buffers_indexed = glad_gl_has_extension(exts, exts_i, "GL_OES_draw_buffers_indexed"); + GLAD_GL_OES_draw_elements_base_vertex = glad_gl_has_extension(exts, exts_i, "GL_OES_draw_elements_base_vertex"); + GLAD_GL_OES_fragment_precision_high = glad_gl_has_extension(exts, exts_i, "GL_OES_fragment_precision_high"); + GLAD_GL_OES_geometry_point_size = glad_gl_has_extension(exts, exts_i, "GL_OES_geometry_point_size"); + GLAD_GL_OES_geometry_shader = glad_gl_has_extension(exts, exts_i, "GL_OES_geometry_shader"); + GLAD_GL_OES_get_program_binary = glad_gl_has_extension(exts, exts_i, "GL_OES_get_program_binary"); + GLAD_GL_OES_gpu_shader5 = glad_gl_has_extension(exts, exts_i, "GL_OES_gpu_shader5"); + GLAD_GL_OES_primitive_bounding_box = glad_gl_has_extension(exts, exts_i, "GL_OES_primitive_bounding_box"); + GLAD_GL_OES_sample_shading = glad_gl_has_extension(exts, exts_i, "GL_OES_sample_shading"); + GLAD_GL_OES_sample_variables = glad_gl_has_extension(exts, exts_i, "GL_OES_sample_variables"); + GLAD_GL_OES_shader_image_atomic = glad_gl_has_extension(exts, exts_i, "GL_OES_shader_image_atomic"); + GLAD_GL_OES_shader_io_blocks = glad_gl_has_extension(exts, exts_i, "GL_OES_shader_io_blocks"); + GLAD_GL_OES_shader_multisample_interpolation = glad_gl_has_extension(exts, exts_i, "GL_OES_shader_multisample_interpolation"); + GLAD_GL_OES_standard_derivatives = glad_gl_has_extension(exts, exts_i, "GL_OES_standard_derivatives"); + GLAD_GL_OES_tessellation_point_size = glad_gl_has_extension(exts, exts_i, "GL_OES_tessellation_point_size"); + GLAD_GL_OES_tessellation_shader = glad_gl_has_extension(exts, exts_i, "GL_OES_tessellation_shader"); + GLAD_GL_OES_texture_3D = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_3D"); + GLAD_GL_OES_texture_border_clamp = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_border_clamp"); + GLAD_GL_OES_texture_buffer = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_buffer"); + GLAD_GL_OES_texture_compression_astc = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_compression_astc"); + GLAD_GL_OES_texture_cube_map_array = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_cube_map_array"); + GLAD_GL_OES_texture_float = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_float"); + GLAD_GL_OES_texture_float_linear = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_float_linear"); + GLAD_GL_OES_texture_half_float = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_half_float"); + GLAD_GL_OES_texture_half_float_linear = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_half_float_linear"); + GLAD_GL_OES_texture_stencil8 = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_stencil8"); + GLAD_GL_OES_texture_storage_multisample_2d_array = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_storage_multisample_2d_array"); + GLAD_GL_OES_texture_view = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_view"); + GLAD_GL_OES_vertex_half_float = glad_gl_has_extension(exts, exts_i, "GL_OES_vertex_half_float"); + GLAD_GL_OES_vertex_type_10_10_10_2 = glad_gl_has_extension(exts, exts_i, "GL_OES_vertex_type_10_10_10_2"); + GLAD_GL_OES_viewport_array = glad_gl_has_extension(exts, exts_i, "GL_OES_viewport_array"); + GLAD_GL_OVR_multiview_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_OVR_multiview_multisampled_render_to_texture"); + GLAD_GL_QCOM_YUV_texture_gather = glad_gl_has_extension(exts, exts_i, "GL_QCOM_YUV_texture_gather"); + GLAD_GL_QCOM_alpha_test = glad_gl_has_extension(exts, exts_i, "GL_QCOM_alpha_test"); + GLAD_GL_QCOM_binning_control = glad_gl_has_extension(exts, exts_i, "GL_QCOM_binning_control"); + GLAD_GL_QCOM_frame_extrapolation = glad_gl_has_extension(exts, exts_i, "GL_QCOM_frame_extrapolation"); + GLAD_GL_QCOM_framebuffer_foveated = glad_gl_has_extension(exts, exts_i, "GL_QCOM_framebuffer_foveated"); + GLAD_GL_QCOM_motion_estimation = glad_gl_has_extension(exts, exts_i, "GL_QCOM_motion_estimation"); + GLAD_GL_QCOM_render_sRGB_R8_RG8 = glad_gl_has_extension(exts, exts_i, "GL_QCOM_render_sRGB_R8_RG8"); + GLAD_GL_QCOM_render_shared_exponent = glad_gl_has_extension(exts, exts_i, "GL_QCOM_render_shared_exponent"); + GLAD_GL_QCOM_shader_framebuffer_fetch_noncoherent = glad_gl_has_extension(exts, exts_i, "GL_QCOM_shader_framebuffer_fetch_noncoherent"); + GLAD_GL_QCOM_shader_framebuffer_fetch_rate = glad_gl_has_extension(exts, exts_i, "GL_QCOM_shader_framebuffer_fetch_rate"); + GLAD_GL_QCOM_shading_rate = glad_gl_has_extension(exts, exts_i, "GL_QCOM_shading_rate"); + GLAD_GL_QCOM_texture_foveated = glad_gl_has_extension(exts, exts_i, "GL_QCOM_texture_foveated"); + GLAD_GL_QCOM_texture_foveated2 = glad_gl_has_extension(exts, exts_i, "GL_QCOM_texture_foveated2"); + GLAD_GL_QCOM_texture_foveated_subsampled_layout = glad_gl_has_extension(exts, exts_i, "GL_QCOM_texture_foveated_subsampled_layout"); + GLAD_GL_QCOM_texture_lod_bias = glad_gl_has_extension(exts, exts_i, "GL_QCOM_texture_lod_bias"); + GLAD_GL_QCOM_ycbcr_degamma = glad_gl_has_extension(exts, exts_i, "GL_QCOM_ycbcr_degamma"); + GLAD_GL_VIV_shader_binary = glad_gl_has_extension(exts, exts_i, "GL_VIV_shader_binary"); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gles2(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_ES_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_ES_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gles2(); + + glad_gl_load_GL_ES_VERSION_2_0(load, userptr); + glad_gl_load_GL_ES_VERSION_3_0(load, userptr); + glad_gl_load_GL_ES_VERSION_3_1(load, userptr); + glad_gl_load_GL_ES_VERSION_3_2(load, userptr); + + if (!glad_gl_find_extensions_gles2()) return 0; + glad_gl_load_GL_AMD_framebuffer_multisample_advanced(load, userptr); + glad_gl_load_GL_AMD_performance_monitor(load, userptr); + glad_gl_load_GL_EXT_EGL_image_storage(load, userptr); + glad_gl_load_GL_EXT_blend_minmax(load, userptr); + glad_gl_load_GL_EXT_debug_label(load, userptr); + glad_gl_load_GL_EXT_debug_marker(load, userptr); + glad_gl_load_GL_EXT_draw_instanced(load, userptr); + glad_gl_load_GL_EXT_external_buffer(load, userptr); + glad_gl_load_GL_EXT_framebuffer_blit_layers(load, userptr); + glad_gl_load_GL_EXT_memory_object(load, userptr); + glad_gl_load_GL_EXT_memory_object_fd(load, userptr); + glad_gl_load_GL_EXT_memory_object_win32(load, userptr); + glad_gl_load_GL_EXT_multi_draw_arrays(load, userptr); + glad_gl_load_GL_EXT_polygon_offset_clamp(load, userptr); + glad_gl_load_GL_EXT_raster_multisample(load, userptr); + glad_gl_load_GL_EXT_semaphore(load, userptr); + glad_gl_load_GL_EXT_semaphore_fd(load, userptr); + glad_gl_load_GL_EXT_semaphore_win32(load, userptr); + glad_gl_load_GL_EXT_shader_framebuffer_fetch_non_coherent(load, userptr); + glad_gl_load_GL_EXT_texture_storage(load, userptr); + glad_gl_load_GL_EXT_win32_keyed_mutex(load, userptr); + glad_gl_load_GL_EXT_window_rectangles(load, userptr); + glad_gl_load_GL_INTEL_framebuffer_CMAA(load, userptr); + glad_gl_load_GL_INTEL_performance_query(load, userptr); + glad_gl_load_GL_KHR_blend_equation_advanced(load, userptr); + glad_gl_load_GL_KHR_debug(load, userptr); + glad_gl_load_GL_KHR_parallel_shader_compile(load, userptr); + glad_gl_load_GL_KHR_robustness(load, userptr); + glad_gl_load_GL_MESA_framebuffer_flip_y(load, userptr); + glad_gl_load_GL_NV_bindless_texture(load, userptr); + glad_gl_load_GL_NV_blend_equation_advanced(load, userptr); + glad_gl_load_GL_NV_clip_space_w_scaling(load, userptr); + glad_gl_load_GL_NV_conditional_render(load, userptr); + glad_gl_load_GL_NV_conservative_raster(load, userptr); + glad_gl_load_GL_NV_conservative_raster_pre_snap_triangles(load, userptr); + glad_gl_load_GL_NV_draw_vulkan_image(load, userptr); + glad_gl_load_GL_NV_fence(load, userptr); + glad_gl_load_GL_NV_fragment_coverage_to_color(load, userptr); + glad_gl_load_GL_NV_framebuffer_mixed_samples(load, userptr); + glad_gl_load_GL_NV_gpu_shader5(load, userptr); + glad_gl_load_GL_NV_internalformat_sample_query(load, userptr); + glad_gl_load_GL_NV_memory_attachment(load, userptr); + glad_gl_load_GL_NV_memory_object_sparse(load, userptr); + glad_gl_load_GL_NV_mesh_shader(load, userptr); + glad_gl_load_GL_NV_path_rendering(load, userptr); + glad_gl_load_GL_NV_sample_locations(load, userptr); + glad_gl_load_GL_NV_scissor_exclusive(load, userptr); + glad_gl_load_GL_NV_shading_rate_image(load, userptr); + glad_gl_load_GL_NV_timeline_semaphore(load, userptr); + glad_gl_load_GL_NV_viewport_swizzle(load, userptr); + glad_gl_load_GL_OVR_multiview(load, userptr); + glad_gl_load_GL_APPLE_copy_texture_levels(load, userptr); + glad_gl_load_GL_APPLE_framebuffer_multisample(load, userptr); + glad_gl_load_GL_APPLE_sync(load, userptr); + glad_gl_load_GL_EXT_discard_framebuffer(load, userptr); + glad_gl_load_GL_EXT_map_buffer_range(load, userptr); + glad_gl_load_GL_EXT_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_EXT_robustness(load, userptr); + glad_gl_load_GL_IMG_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_OES_EGL_image(load, userptr); + glad_gl_load_GL_OES_mapbuffer(load, userptr); + glad_gl_load_GL_OES_vertex_array_object(load, userptr); + glad_gl_load_GL_QCOM_driver_control(load, userptr); + glad_gl_load_GL_QCOM_extended_get(load, userptr); + glad_gl_load_GL_QCOM_extended_get2(load, userptr); + glad_gl_load_GL_QCOM_tiled_rendering(load, userptr); + glad_gl_load_GL_ANGLE_framebuffer_blit(load, userptr); + glad_gl_load_GL_ANGLE_framebuffer_multisample(load, userptr); + glad_gl_load_GL_ANGLE_instanced_arrays(load, userptr); + glad_gl_load_GL_ANGLE_translated_shader_source(load, userptr); + glad_gl_load_GL_ARM_shader_core_properties(load, userptr); + glad_gl_load_GL_EXT_base_instance(load, userptr); + glad_gl_load_GL_EXT_blend_func_extended(load, userptr); + glad_gl_load_GL_EXT_buffer_storage(load, userptr); + glad_gl_load_GL_EXT_clear_texture(load, userptr); + glad_gl_load_GL_EXT_clip_control(load, userptr); + glad_gl_load_GL_EXT_copy_image(load, userptr); + glad_gl_load_GL_EXT_disjoint_timer_query(load, userptr); + glad_gl_load_GL_EXT_draw_buffers(load, userptr); + glad_gl_load_GL_EXT_draw_buffers_indexed(load, userptr); + glad_gl_load_GL_EXT_draw_elements_base_vertex(load, userptr); + glad_gl_load_GL_EXT_draw_transform_feedback(load, userptr); + glad_gl_load_GL_EXT_fragment_shading_rate(load, userptr); + glad_gl_load_GL_EXT_geometry_shader(load, userptr); + glad_gl_load_GL_EXT_instanced_arrays(load, userptr); + glad_gl_load_GL_EXT_multi_draw_indirect(load, userptr); + glad_gl_load_GL_EXT_multiview_draw_buffers(load, userptr); + glad_gl_load_GL_EXT_occlusion_query_boolean(load, userptr); + glad_gl_load_GL_EXT_primitive_bounding_box(load, userptr); + glad_gl_load_GL_EXT_separate_shader_objects(load, userptr); + glad_gl_load_GL_EXT_shader_pixel_local_storage2(load, userptr); + glad_gl_load_GL_EXT_sparse_texture(load, userptr); + glad_gl_load_GL_EXT_tessellation_shader(load, userptr); + glad_gl_load_GL_EXT_texture_border_clamp(load, userptr); + glad_gl_load_GL_EXT_texture_buffer(load, userptr); + glad_gl_load_GL_EXT_texture_storage_compression(load, userptr); + glad_gl_load_GL_EXT_texture_view(load, userptr); + glad_gl_load_GL_IMG_bindless_texture(load, userptr); + glad_gl_load_GL_IMG_framebuffer_downsample(load, userptr); + glad_gl_load_GL_MESA_sampler_objects(load, userptr); + glad_gl_load_GL_NV_copy_buffer(load, userptr); + glad_gl_load_GL_NV_coverage_sample(load, userptr); + glad_gl_load_GL_NV_draw_buffers(load, userptr); + glad_gl_load_GL_NV_draw_instanced(load, userptr); + glad_gl_load_GL_NV_framebuffer_blit(load, userptr); + glad_gl_load_GL_NV_framebuffer_multisample(load, userptr); + glad_gl_load_GL_NV_instanced_arrays(load, userptr); + glad_gl_load_GL_NV_non_square_matrices(load, userptr); + glad_gl_load_GL_NV_polygon_mode(load, userptr); + glad_gl_load_GL_NV_read_buffer(load, userptr); + glad_gl_load_GL_NV_viewport_array(load, userptr); + glad_gl_load_GL_OES_copy_image(load, userptr); + glad_gl_load_GL_OES_draw_buffers_indexed(load, userptr); + glad_gl_load_GL_OES_draw_elements_base_vertex(load, userptr); + glad_gl_load_GL_OES_geometry_shader(load, userptr); + glad_gl_load_GL_OES_get_program_binary(load, userptr); + glad_gl_load_GL_OES_primitive_bounding_box(load, userptr); + glad_gl_load_GL_OES_sample_shading(load, userptr); + glad_gl_load_GL_OES_tessellation_shader(load, userptr); + glad_gl_load_GL_OES_texture_3D(load, userptr); + glad_gl_load_GL_OES_texture_border_clamp(load, userptr); + glad_gl_load_GL_OES_texture_buffer(load, userptr); + glad_gl_load_GL_OES_texture_storage_multisample_2d_array(load, userptr); + glad_gl_load_GL_OES_texture_view(load, userptr); + glad_gl_load_GL_OES_viewport_array(load, userptr); + glad_gl_load_GL_OVR_multiview_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_QCOM_alpha_test(load, userptr); + glad_gl_load_GL_QCOM_frame_extrapolation(load, userptr); + glad_gl_load_GL_QCOM_framebuffer_foveated(load, userptr); + glad_gl_load_GL_QCOM_motion_estimation(load, userptr); + glad_gl_load_GL_QCOM_shader_framebuffer_fetch_noncoherent(load, userptr); + glad_gl_load_GL_QCOM_shading_rate(load, userptr); + glad_gl_load_GL_QCOM_texture_foveated(load, userptr); + + + glad_gl_resolve_aliases(); + + return version; +} + + +int gladLoadGLES2( GLADloadfunc load) { + return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + + +#ifdef __cplusplus +} +#endif diff --git a/sdk/include/glad/gl.h b/sdk/include/glad/gl.h new file mode 100644 index 00000000000..c3d8ba724ac --- /dev/null +++ b/sdk/include/glad/gl.h @@ -0,0 +1,17821 @@ +/** + * Loader generated by glad 2.0.6 on Tue May 28 17:43:00 2024 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 854 + * + * APIs: + * - gl:compatibility=4.6 + * - gles1:common=1.0 + * - gles2=3.2 + * + * Options: + * - ALIAS = True + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = False + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --merge --api='gl:compatibility=4.6,gles1:common=1.0,gles2=3.2' --extensions='GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_EGL_sync,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_blit_layers,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_multiview_tessellation_geometry_shader,GL_EXT_multiview_texture_multisample,GL_EXT_multiview_timer_query,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shader_samples_identical,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_R8,GL_EXT_texture_sRGB_RG8,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shadow_lod,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_storage,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_shader_subgroup,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_framebuffer_flip_x,GL_MESA_framebuffer_flip_y,GL_MESA_framebuffer_swap_xy,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_gpu_multicast2,GL_NVX_linked_gpu_multicast,GL_NVX_progress_fence,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_compute_shader_derivatives,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_barycentric,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_memory_attachment,GL_NV_memory_object_sparse,GL_NV_mesh_shader,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_primitive_shading_rate,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_representative_fragment_test,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_scissor_exclusive,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_subgroup_partitioned,GL_NV_shader_texture_footprint,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_shading_rate_image,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_timeline_semaphore,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_std430_layout,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vdpau_interop2,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog,GL_AMD_compressed_3DC_texture,GL_AMD_compressed_ATC_texture,GL_APPLE_copy_texture_levels,GL_APPLE_framebuffer_multisample,GL_APPLE_sync,GL_APPLE_texture_2D_limited_npot,GL_APPLE_texture_format_BGRA8888,GL_APPLE_texture_max_level,GL_ARM_rgba8,GL_EXT_discard_framebuffer,GL_EXT_map_buffer_range,GL_EXT_multisampled_render_to_texture,GL_EXT_read_format_bgra,GL_EXT_robustness,GL_EXT_sRGB,GL_EXT_texture_compression_dxt1,GL_EXT_texture_format_BGRA8888,GL_IMG_multisampled_render_to_texture,GL_IMG_read_format,GL_IMG_texture_compression_pvrtc,GL_IMG_texture_env_enhanced_fixed_function,GL_IMG_user_clip_plane,GL_OES_EGL_image,GL_OES_EGL_image_external,GL_OES_blend_equation_separate,GL_OES_blend_func_separate,GL_OES_blend_subtract,GL_OES_compressed_ETC1_RGB8_sub_texture,GL_OES_compressed_ETC1_RGB8_texture,GL_OES_depth24,GL_OES_depth32,GL_OES_draw_texture,GL_OES_element_index_uint,GL_OES_extended_matrix_palette,GL_OES_fbo_render_mipmap,GL_OES_framebuffer_object,GL_OES_mapbuffer,GL_OES_matrix_get,GL_OES_matrix_palette,GL_OES_packed_depth_stencil,GL_OES_point_size_array,GL_OES_point_sprite,GL_OES_required_internalformat,GL_OES_rgb8_rgba8,GL_OES_stencil1,GL_OES_stencil4,GL_OES_stencil8,GL_OES_stencil_wrap,GL_OES_surfaceless_context,GL_OES_texture_cube_map,GL_OES_texture_env_crossbar,GL_OES_texture_mirrored_repeat,GL_OES_texture_npot,GL_OES_vertex_array_object,GL_QCOM_driver_control,GL_QCOM_extended_get,GL_QCOM_extended_get2,GL_QCOM_perfmon_global_mode,GL_QCOM_tiled_rendering,GL_QCOM_writeonly_rendering,GL_AMD_program_binary_Z400,GL_ANDROID_extension_pack_es31a,GL_ANGLE_depth_texture,GL_ANGLE_framebuffer_blit,GL_ANGLE_framebuffer_multisample,GL_ANGLE_instanced_arrays,GL_ANGLE_pack_reverse_row_order,GL_ANGLE_program_binary,GL_ANGLE_texture_compression_dxt3,GL_ANGLE_texture_compression_dxt5,GL_ANGLE_texture_usage,GL_ANGLE_translated_shader_source,GL_APPLE_clip_distance,GL_APPLE_color_buffer_packed_float,GL_APPLE_texture_packed_float,GL_ARM_mali_program_binary,GL_ARM_mali_shader_binary,GL_ARM_shader_core_properties,GL_ARM_shader_framebuffer_fetch,GL_ARM_shader_framebuffer_fetch_depth_stencil,GL_ARM_texture_unnormalized_coordinates,GL_DMP_program_binary,GL_DMP_shader_binary,GL_EXT_EGL_image_array,GL_EXT_EGL_image_storage_compression,GL_EXT_YUV_target,GL_EXT_base_instance,GL_EXT_blend_func_extended,GL_EXT_buffer_storage,GL_EXT_clear_texture,GL_EXT_clip_control,GL_EXT_clip_cull_distance,GL_EXT_color_buffer_float,GL_EXT_color_buffer_half_float,GL_EXT_conservative_depth,GL_EXT_copy_image,GL_EXT_depth_clamp,GL_EXT_disjoint_timer_query,GL_EXT_draw_buffers,GL_EXT_draw_buffers_indexed,GL_EXT_draw_elements_base_vertex,GL_EXT_draw_transform_feedback,GL_EXT_float_blend,GL_EXT_fragment_shading_rate,GL_EXT_geometry_point_size,GL_EXT_geometry_shader,GL_EXT_gpu_shader5,GL_EXT_instanced_arrays,GL_EXT_multi_draw_indirect,GL_EXT_multisampled_compatibility,GL_EXT_multisampled_render_to_texture2,GL_EXT_multiview_draw_buffers,GL_EXT_occlusion_query_boolean,GL_EXT_primitive_bounding_box,GL_EXT_protected_textures,GL_EXT_pvrtc_sRGB,GL_EXT_render_snorm,GL_EXT_sRGB_write_control,GL_EXT_separate_depth_stencil,GL_EXT_separate_shader_objects,GL_EXT_shader_group_vote,GL_EXT_shader_implicit_conversions,GL_EXT_shader_io_blocks,GL_EXT_shader_non_constant_global_initializers,GL_EXT_shader_pixel_local_storage,GL_EXT_shader_pixel_local_storage2,GL_EXT_shader_texture_lod,GL_EXT_shadow_samplers,GL_EXT_sparse_texture,GL_EXT_tessellation_point_size,GL_EXT_tessellation_shader,GL_EXT_texture_border_clamp,GL_EXT_texture_buffer,GL_EXT_texture_compression_astc_decode_mode,GL_EXT_texture_compression_bptc,GL_EXT_texture_compression_s3tc_srgb,GL_EXT_texture_cube_map_array,GL_EXT_texture_format_sRGB_override,GL_EXT_texture_mirror_clamp_to_edge,GL_EXT_texture_norm16,GL_EXT_texture_query_lod,GL_EXT_texture_rg,GL_EXT_texture_storage_compression,GL_EXT_texture_type_2_10_10_10_REV,GL_EXT_texture_view,GL_EXT_unpack_subimage,GL_FJ_shader_binary_GCCSO,GL_IMG_bindless_texture,GL_IMG_framebuffer_downsample,GL_IMG_program_binary,GL_IMG_shader_binary,GL_IMG_texture_compression_pvrtc2,GL_IMG_texture_filter_cubic,GL_MESA_bgra,GL_MESA_sampler_objects,GL_NV_copy_buffer,GL_NV_coverage_sample,GL_NV_depth_nonlinear,GL_NV_draw_buffers,GL_NV_draw_instanced,GL_NV_explicit_attrib_location,GL_NV_fbo_color_attachments,GL_NV_framebuffer_blit,GL_NV_framebuffer_multisample,GL_NV_generate_mipmap_sRGB,GL_NV_image_formats,GL_NV_instanced_arrays,GL_NV_non_square_matrices,GL_NV_pack_subimage,GL_NV_pixel_buffer_object,GL_NV_polygon_mode,GL_NV_read_buffer,GL_NV_read_buffer_front,GL_NV_read_depth,GL_NV_read_depth_stencil,GL_NV_read_stencil,GL_NV_sRGB_formats,GL_NV_shader_noperspective_interpolation,GL_NV_shadow_samplers_array,GL_NV_shadow_samplers_cube,GL_NV_texture_border_clamp,GL_NV_texture_compression_s3tc_update,GL_NV_texture_npot_2D_mipmap,GL_NV_viewport_array,GL_OES_EGL_image_external_essl3,GL_OES_copy_image,GL_OES_depth_texture,GL_OES_draw_buffers_indexed,GL_OES_draw_elements_base_vertex,GL_OES_fragment_precision_high,GL_OES_geometry_point_size,GL_OES_geometry_shader,GL_OES_get_program_binary,GL_OES_gpu_shader5,GL_OES_primitive_bounding_box,GL_OES_sample_shading,GL_OES_sample_variables,GL_OES_shader_image_atomic,GL_OES_shader_io_blocks,GL_OES_shader_multisample_interpolation,GL_OES_standard_derivatives,GL_OES_tessellation_point_size,GL_OES_tessellation_shader,GL_OES_texture_3D,GL_OES_texture_border_clamp,GL_OES_texture_buffer,GL_OES_texture_compression_astc,GL_OES_texture_cube_map_array,GL_OES_texture_float,GL_OES_texture_float_linear,GL_OES_texture_half_float,GL_OES_texture_half_float_linear,GL_OES_texture_stencil8,GL_OES_texture_storage_multisample_2d_array,GL_OES_texture_view,GL_OES_vertex_half_float,GL_OES_vertex_type_10_10_10_2,GL_OES_viewport_array,GL_OVR_multiview_multisampled_render_to_texture,GL_QCOM_YUV_texture_gather,GL_QCOM_alpha_test,GL_QCOM_binning_control,GL_QCOM_frame_extrapolation,GL_QCOM_framebuffer_foveated,GL_QCOM_motion_estimation,GL_QCOM_render_sRGB_R8_RG8,GL_QCOM_render_shared_exponent,GL_QCOM_shader_framebuffer_fetch_noncoherent,GL_QCOM_shader_framebuffer_fetch_rate,GL_QCOM_shading_rate,GL_QCOM_texture_foveated,GL_QCOM_texture_foveated2,GL_QCOM_texture_foveated_subsampled_layout,GL_QCOM_texture_lod_bias,GL_QCOM_ycbcr_degamma,GL_VIV_shader_binary' c --alias + * + * Online: + * http://glad.sh/#api=gl%3Acompatibility%3D4.6%2Cgles1%3Acommon%3D1.0%2Cgles2%3D3.2&generator=c&options=MERGE%2CALIAS + * + */ + +#ifndef GLAD_GL_H_ +#define GLAD_GL_H_ + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif +#ifdef __gl_h_ + #error OpenGL (gl.h) header already included (API: gl), remove previous include! +#endif +#define __gl_h_ 1 +#ifdef __gl3_h_ + #error OpenGL (gl3.h) header already included (API: gl), remove previous include! +#endif +#define __gl3_h_ 1 +#ifdef __glext_h_ + #error OpenGL (glext.h) header already included (API: gl), remove previous include! +#endif +#define __glext_h_ 1 +#ifdef __gl3ext_h_ + #error OpenGL (gl3ext.h) header already included (API: gl), remove previous include! +#endif +#define __gl3ext_h_ 1 +#ifdef __gles1_gl_h_ + #error OpenGL ES 1 header already included (API: gles1), remove previous include! +#endif +#define __gles1_gl_h_ 1 +#ifdef __gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gl2_h_ 1 +#ifdef __gles2_gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl2_h_ 1 +#ifdef __gles2_gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl3_h_ 1 +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#define GLAD_GL +#define GLAD_OPTION_GL_ALIAS + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.6" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GL_1PASS_EXT 0x80A1 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2D 0x0600 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_2_BYTES 0x1407 +#define GL_2_BYTES_NV 0x1407 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_3_BYTES 0x1408 +#define GL_3_BYTES_NV 0x1408 +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_EXT 0x80CC +#define GL_422_REV_AVERAGE_EXT 0x80CF +#define GL_422_REV_EXT 0x80CD +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_4_BYTES 0x1409 +#define GL_4_BYTES_NV 0x1409 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_ABGR_EXT 0x8000 +#define GL_ACCUM 0x0100 +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_ADD 0x0104 +#define GL_ADD_ATI 0x8963 +#define GL_ADD_SIGNED 0x8574 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_ALL_PIXELS_AMD 0xFFFFFFFF +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_ALPHA 0x1906 +#define GL_ALPHA12 0x803D +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16 0x803E +#define GL_ALPHA16F_ARB 0x881C +#define GL_ALPHA16F_EXT 0x881C +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_ALPHA16_EXT 0x803E +#define GL_ALPHA16_SNORM 0x9018 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_ALPHA4 0x803B +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA8_SNORM 0x9014 +#define GL_ALPHA_BIAS 0x0D1D +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#define GL_ALPHA_MAX_SGIX 0x8321 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_REF_COMMAND_NV 0x000F +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_SNORM 0x9010 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D +#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F +#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E +#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALWAYS 0x0207 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_AMBIENT 0x1200 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARC_TO_NV 0xFE +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_ASYNC_MARKER_SGIX 0x8329 +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4 +#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ATTENUATION_EXT 0x834D +#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_AUX_BUFFERS 0x0C00 +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#define GL_AVERAGE_EXT 0x8335 +#define GL_AVERAGE_HP 0x8160 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_RIGHT 0x0403 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_BEVEL_NV 0x90A6 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_BGRA8_EXT 0x93A1 +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_BGR_EXT 0x80E0 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BITMAP 0x1A00 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_BLACKHOLE_RENDER_INTEL 0x83FC +#define GL_BLEND 0x0BE2 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_COLOR_COMMAND_NV 0x000B +#define GL_BLEND_COLOR_EXT 0x8005 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#define GL_BLEND_EQUATION_EXT 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLOCK_INDEX 0x92FD +#define GL_BLUE 0x1905 +#define GL_BLUE_BIAS 0x0D1B +#define GL_BLUE_BITS 0x0D54 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_BLUE_NV 0x1905 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BOLD_BIT_NV 0x01 +#define GL_BOOL 0x8B56 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_BUFFER 0x82E0 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_TARGET_ATI 0x877C +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_BYTE 0x1400 +#define GL_C3F_V3F 0x2A24 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_CCW 0x0901 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_CLAMP 0x2900 +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLEAR 0x1500 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_CMYKA_EXT 0x800D +#define GL_CMYK_EXT 0x800C +#define GL_CND0_ATI 0x896B +#define GL_CND_ATI 0x896A +#define GL_COEFF 0x0A00 +#define GL_COLOR 0x1800 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_COLORBURN_KHR 0x929A +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORDODGE_NV 0x9299 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_COLOR_ARRAY 0x8076 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_COLOR_ENCODING 0x8296 +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#define GL_COLOR_INDEX 0x1900 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEXES 0x1603 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_COLOR_SUM 0x8458 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_COLOR_TABLE 0x80D0 +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMBINE 0x8570 +#define GL_COMBINE4_NV 0x8503 +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_COMBINE_ALPHA 0x8572 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPLETION_STATUS_ARB 0x91B1 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONFORMANT_NV 0x9374 +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_CONJOINT_NV 0x9284 +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B +#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 +#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_CONSTANT 0x8576 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_CONSTANT_ARB 0x8576 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_CONSTANT_EXT 0x8576 +#define GL_CONSTANT_NV 0x8576 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_CONTEXT_LOST 0x0507 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 +#define GL_CONTINUOUS_AMD 0x9007 +#define GL_CONTRAST_NV 0x92A1 +#define GL_CONVEX_HULL_NV 0x908B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_2_ATI 0x8943 +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_COORD_REPLACE 0x8862 +#define GL_COORD_REPLACE_ARB 0x8862 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_CUBIC_EXT 0x8334 +#define GL_CUBIC_HP 0x815F +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_CULL_MODES_NV 0x86E0 +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_IBM 103050 +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_CURRENT_BIT 0x00000001 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_CW 0x0900 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +#define GL_DARKEN_KHR 0x9297 +#define GL_DARKEN_NV 0x9297 +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DECAL 0x2101 +#define GL_DECODE_EXT 0x8A49 +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DECR_WRAP_EXT 0x8508 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_DEPTH_BIAS 0x0D1F +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#define GL_DEPTH_CLAMP 0x864F +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_NV 0x864F +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DETACHED_BUFFERS_NV 0x95AB +#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9 +#define GL_DETACHED_TEXTURES_NV 0x95AA +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DIFFERENCE_KHR 0x929E +#define GL_DIFFERENCE_NV 0x929E +#define GL_DIFFUSE 0x1201 +#define GL_DISCARD_ATI 0x8763 +#define GL_DISCARD_NV 0x8530 +#define GL_DISCRETE_AMD 0x9006 +#define GL_DISJOINT_NV 0x9283 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DISPLAY_LIST 0x82E7 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#define GL_DITHER 0x0BD0 +#define GL_DOMAIN 0x0A02 +#define GL_DONT_CARE 0x1100 +#define GL_DOT2_ADD_ATI 0x896C +#define GL_DOT3_ATI 0x8966 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_DOT3_RGBA_ARB 0x86AF +#define GL_DOT3_RGBA_EXT 0x8741 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT4_ATI 0x8967 +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_VEC4_EXT 0x8FFE +#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 +#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 +#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 +#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 +#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_DSDT_NV 0x86F5 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_COLOR 0x0306 +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_BIAS_NV 0x8717 +#define GL_DT_SCALE_NV 0x8711 +#define GL_DU8DV8_ATI 0x877A +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_DUDV_ATI 0x8779 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_COPY_ARB 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_EDGE_FLAG 0x0B43 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_MAP_NV 0x855F +#define GL_EMISSION 0x1600 +#define GL_ENABLE_BIT 0x00002000 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_BIT 0x00010000 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXTENSIONS 0x1F03 +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_EYE_PLANE 0x2502 +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_EYE_RADIAL_NV 0x855B +#define GL_E_TIMES_F_NV 0x8531 +#define GL_FACTOR_MAX_AMD 0x901D +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FAILURE_NV 0x9030 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FEEDBACK 0x1C01 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_FENCE_APPLE 0x8A0B +#define GL_FENCE_CONDITION_NV 0x84F4 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FIELDS_NV 0x8E27 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FILE_NAME_NV 0x9074 +#define GL_FILL 0x1B02 +#define GL_FILL_RECTANGLE_NV 0x933C +#define GL_FILTER 0x829A +#define GL_FILTER4_SGIS 0x8146 +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_FIXED 0x140C +#define GL_FIXED_OES 0x140C +#define GL_FIXED_ONLY 0x891D +#define GL_FIXED_ONLY_ARB 0x891D +#define GL_FLAT 0x1D00 +#define GL_FLOAT 0x1406 +#define GL_FLOAT16_MAT2_AMD 0x91C5 +#define GL_FLOAT16_MAT2x3_AMD 0x91C8 +#define GL_FLOAT16_MAT2x4_AMD 0x91C9 +#define GL_FLOAT16_MAT3_AMD 0x91C6 +#define GL_FLOAT16_MAT3x2_AMD 0x91CA +#define GL_FLOAT16_MAT3x4_AMD 0x91CB +#define GL_FLOAT16_MAT4_AMD 0x91C7 +#define GL_FLOAT16_MAT4x2_AMD 0x91CC +#define GL_FLOAT16_MAT4x3_AMD 0x91CD +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_FOG 0x0B60 +#define GL_FOG_BIT 0x00000080 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_COORD 0x8451 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_FOG_END 0x0B64 +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_HINT 0x0C54 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#define GL_FOG_START 0x0B63 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_FRAGMENT_INPUT_NV 0x936D +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC +#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAME_NV 0x8E26 +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_FACE_COMMAND_NV 0x0012 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEQUAL 0x0206 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_GREEN_BIAS 0x0D19 +#define GL_GREEN_BITS 0x0D53 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_GREEN_NV 0x1904 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_HALF_APPLE 0x140B +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_HALF_FLOAT 0x140B +#define GL_HALF_FLOAT_ARB 0x140B +#define GL_HALF_FLOAT_NV 0x140B +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_HARDLIGHT_KHR 0x929B +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_HILO16_NV 0x86F8 +#define GL_HILO8_NV 0x885E +#define GL_HILO_NV 0x86F4 +#define GL_HINT_BIT 0x00008000 +#define GL_HISTOGRAM 0x8024 +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_SINK 0x802D +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HI_BIAS_NV 0x8714 +#define GL_HI_SCALE_NV 0x870E +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_IDENTITY_NV 0x862A +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_INDEX 0x8222 +#define GL_INDEX_ARRAY 0x8077 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_BITS 0x0D51 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#define GL_INT 0x1404 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_ARB 0x140E +#define GL_INT64_NV 0x140E +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16 0x804D +#define GL_INTENSITY16F_ARB 0x881D +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_INTENSITY16_EXT 0x804D +#define GL_INTENSITY16_SNORM 0x901B +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_INGR 0x8568 +#define GL_INTERLACE_READ_OML 0x8981 +#define GL_INTERLACE_SGIX 0x8094 +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERPOLATE 0x8575 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_INVARIANT_EXT 0x87C2 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVERSE_NV 0x862B +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_INVERT 0x150A +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#define GL_ISOLINES 0x8E7A +#define GL_IS_PER_PATCH 0x92E7 +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_KEEP 0x1E00 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_LAYER_NV 0x8DAA +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 +#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LERP_ATI 0x8969 +#define GL_LESS 0x0201 +#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_LINES 0x0001 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_BIT 0x00000004 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_TO_NV 0x04 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_COMMAND_NV 0x000D +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINK_STATUS 0x8B82 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_BIT 0x00020000 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 +#define GL_LIST_PRIORITY_SGIX 0x8182 +#define GL_LOAD 0x0101 +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_EXT 0x87C4 +#define GL_LOCATION 0x930E +#define GL_LOCATION_COMPONENT 0x934A +#define GL_LOCATION_INDEX 0x930F +#define GL_LOGIC_OP 0x0BF1 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_LO_BIAS_NV 0x8715 +#define GL_LO_SCALE_NV 0x870F +#define GL_LUID_SIZE_EXT 8 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_MAD_ATI 0x8968 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_MAJOR_VERSION 0x821B +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_STENCIL 0x0D11 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX7_NV 0x8637 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX_EXT 0x87C0 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 +#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD +#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_EXT 0x8008 +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_LGPU_GPUS_NVX 0x92BA +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64 +#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539 +#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61 +#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536 +#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63 +#define GL_MAX_MESH_VIEWS_NV 0x9557 +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2 +#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 +#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C +#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A +#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69 +#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537 +#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68 +#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3 +#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#define GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6 +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VIEWPORTS 0x825B +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6 +#define GL_MEMORY_ATTACHABLE_NV 0x95A8 +#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7 +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF +#define GL_MESH_OUTPUT_TYPE_NV 0x957B +#define GL_MESH_PRIMITIVES_OUT_NV 0x957A +#define GL_MESH_SHADER_BIT_NV 0x00000040 +#define GL_MESH_SHADER_NV 0x9559 +#define GL_MESH_SUBROUTINE_NV 0x957C +#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E +#define GL_MESH_VERTICES_OUT_NV 0x9579 +#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E +#define GL_MIN 0x8007 +#define GL_MINMAX 0x802E +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_MINOR_VERSION 0x821C +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MIN_EXT 0x8007 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIPMAP 0x8293 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_MODELVIEW 0x1700 +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW1_EXT 0x850A +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_MODULATE 0x2100 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_MOVE_TO_NV 0x02 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOV_ATI 0x8961 +#define GL_MULT 0x0103 +#define GL_MULTICAST_GPUS_NV 0x92BA +#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_MULTIPLY_NV 0x9294 +#define GL_MULTISAMPLE 0x809D +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_MUL_ATI 0x8964 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_N3F_V3F 0x2A25 +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +#define GL_NAME_LENGTH 0x92F9 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_NAND 0x150E +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NEAREST 0x2600 +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEVER 0x0200 +#define GL_NEXT_BUFFER_NV -2 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOOP 0x1505 +#define GL_NOP_COMMAND_NV 0x0001 +#define GL_NOR 0x1508 +#define GL_NORMALIZE 0x0BA1 +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 +#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_PLANE 0x2501 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_OBJECT_TYPE 0x9112 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#define GL_OFFSET 0x92FC +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_ONE 1 +#define GL_ONE_EXT 0x87DE +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND3_ALPHA_NV 0x859B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_MOV_EXT 0x8799 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_SUB_EXT 0x8796 +#define GL_OR 0x1507 +#define GL_ORDER 0x0A01 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_OVERLAY_KHR 0x9296 +#define GL_OVERLAY_NV 0x9296 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_PACK_INVERT_MESA 0x8758 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_PATCHES 0x000E +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_PERTURB_EXT 0x85AE +#define GL_PER_GPU_STORAGE_BIT_NV 0x0800 +#define GL_PER_GPU_STORAGE_NV 0x9548 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#define GL_PHONG_HINT_WIN 0x80EB +#define GL_PHONG_WIN 0x80EA +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE +#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_BIT 0x00000002 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_POINT_SPRITE 0x8861 +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#define GL_POINT_TOKEN 0x0701 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_POSITION 0x1203 +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_PRESENT_DURATION_NV 0x8E2B +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESERVE_ATI 0x8762 +#define GL_PREVIOUS 0x8578 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF +#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PROGRAM 0x82E2 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROJECTION 0x1701 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_PURGEABLE_APPLE 0x8A1D +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB +#define GL_Q 0x2003 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_QUADS 0x0007 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_QUAD_STRIP 0x0008 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_QUERY 0x82E3 +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_QUERY_RESOURCE_BUFFEROBJECT_NV 0x9547 +#define GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV 0x9542 +#define GL_QUERY_RESOURCE_RENDERBUFFER_NV 0x9546 +#define GL_QUERY_RESOURCE_SYS_RESERVED_NV 0x9544 +#define GL_QUERY_RESOURCE_TEXTURE_NV 0x9545 +#define GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV 0x9540 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_TARGET 0x82EA +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_R 0x2002 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16F_EXT 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R16_SNORM 0x8F98 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R32F 0x822E +#define GL_R32F_EXT 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R3_G3_B2 0x2A10 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_EXT 0x8229 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_READ_ONLY 0x88B8 +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#define GL_READ_WRITE 0x88BA +#define GL_READ_WRITE_ARB 0x88BA +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_RECT_NV 0xF6 +#define GL_RED 0x1903 +#define GL_REDUCE 0x8016 +#define GL_REDUCE_EXT 0x8016 +#define GL_RED_BIAS 0x0D15 +#define GL_RED_BITS 0x0D52 +#define GL_RED_BIT_ATI 0x00000001 +#define GL_RED_INTEGER 0x8D94 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_RED_NV 0x1903 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_SNORM 0x8F90 +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFLECTION_MAP 0x8512 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_REFLECTION_MAP_NV 0x8512 +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_2_ATI 0x8923 +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_RENDER 0x1C00 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_RENDER_GPU_MASK_NV 0x9558 +#define GL_RENDER_MODE 0x0C40 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACE_EXT 0x8062 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_REPLICATE_BORDER 0x8153 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 +#define GL_RESCALE_NORMAL 0x803A +#define GL_RESCALE_NORMAL_EXT 0x803A +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_RESTART_SUN 0x0001 +#define GL_RETAINED_APPLE 0x8A1B +#define GL_RETURN 0x0102 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16F_EXT 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG16_SNORM 0x8F99 +#define GL_RG32F 0x8230 +#define GL_RG32F_EXT 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_EXT 0x822B +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB16F 0x881B +#define GL_RGB16F_ARB 0x881B +#define GL_RGB16F_EXT 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16I_EXT 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_RGB16_EXT 0x8054 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB2_EXT 0x804E +#define GL_RGB32F 0x8815 +#define GL_RGB32F_ARB 0x8815 +#define GL_RGB32F_EXT 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32I_EXT 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_RGB4 0x804F +#define GL_RGB4_EXT 0x804F +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGB5 0x8050 +#define GL_RGB565 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8I_EXT 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8UI_EXT 0x8D7D +#define GL_RGB8_EXT 0x8051 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA16F 0x881A +#define GL_RGBA16F_ARB 0x881A +#define GL_RGBA16F_EXT 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGBA16_EXT 0x805B +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA2 0x8055 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA4_DXT5_S3TC 0x83A5 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGBA8_EXT 0x8058 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#define GL_RGBA_MODE 0x0C31 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#define GL_RGBA_SNORM 0x8F93 +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGB_RAW_422_APPLE 0x8A51 +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB_SCALE 0x8573 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_RGB_SNORM 0x8F92 +#define GL_RG_INTEGER 0x8228 +#define GL_RG_SNORM 0x8F91 +#define GL_RIGHT 0x0407 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_ROUND_NV 0x90A4 +#define GL_S 0x2000 +#define GL_SAMPLER 0x82E6 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_SAMPLER_OBJECT_AMD 0x9155 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_LOCATION_ARB 0x8E50 +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_SCALAR_EXT 0x87BE +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCISSOR_BIT 0x00080000 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556 +#define GL_SCISSOR_COMMAND_NV 0x0011 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555 +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_SCREEN_KHR 0x9295 +#define GL_SCREEN_NV 0x9295 +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_SELECT 0x1C02 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_SEMAPHORE_TYPE_BINARY_NV 0x95B4 +#define GL_SEMAPHORE_TYPE_NV 0x95B3 +#define GL_SEMAPHORE_TYPE_TIMELINE_NV 0x95B5 +#define GL_SEPARABLE_2D 0x8012 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#define GL_SET 0x150F +#define GL_SET_AMD 0x874A +#define GL_SHADER 0x82E1 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADE_MODEL 0x0B54 +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F +#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569 +#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A +#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B +#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565 +#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C +#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D +#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E +#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B +#define GL_SHADING_RATE_IMAGE_NV 0x9563 +#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2 +#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E +#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1 +#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D +#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C +#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564 +#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE +#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF +#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0 +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_SHARED_EDGE_NV 0xC0 +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#define GL_SHININESS 0x1601 +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SKIP_COMPONENTS1_NV -6 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS4_NV -3 +#define GL_SKIP_DECODE_EXT 0x8A4A +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_SLICE_ACCUM_SUN 0x85CC +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_SMOOTH 0x1D01 +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_SM_COUNT_NV 0x933B +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SPARE0_NV 0x852E +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_SPARE1_NV 0x852F +#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 +#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +#define GL_SPECULAR 0x1202 +#define GL_SPHERE_MAP 0x2402 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_SPIR_V_BINARY_ARB 0x9552 +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SQUARE_NV 0x90A3 +#define GL_SR8_EXT 0x8FBD +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_ALPHA 0x8589 +#define GL_SRC1_COLOR 0x88F9 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_ALPHA 0x858A +#define GL_SRC2_RGB 0x8582 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_COLOR 0x0300 +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_SRG8_EXT 0x8FBE +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB_DECODE_ARB 0x8299 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_STATIC_ATI 0x8760 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_REF_COMMAND_NV 0x000C +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_SHARED_APPLE 0x85BF +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004 +#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008 +#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001 +#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040 +#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100 +#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080 +#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010 +#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020 +#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002 +#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535 +#define GL_SUBGROUP_SIZE_KHR 0x9532 +#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534 +#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#define GL_SUBTRACT 0x84E7 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_SUB_ATI 0x8965 +#define GL_SUCCESS_NV 0x902F +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_T 0x2001 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_T4F_V4F 0x2A28 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TASK_SHADER_BIT_NV 0x00000080 +#define GL_TASK_SHADER_NV 0x955A +#define GL_TASK_SUBROUTINE_NV 0x957D +#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F +#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F +#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE31_ARB 0x84DF +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_TARGET 0x1006 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8 +#define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9 +#define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_TIMELINE_SEMAPHORE_VALUE_NV 0x9595 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TIMESTAMP 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_NV 0x862C +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_TRUE 1 +#define GL_TYPE 0x92FA +#define GL_UNCORRELATED_NV 0x9282 +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_UNSIGNED_INT64_ARB 0x140F +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_UPLOAD_GPU_MASK_NVX 0x954A +#define GL_UPPER_LEFT 0x8CA2 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_UTF16_NV 0x909B +#define GL_UTF8_NV 0x909A +#define GL_UUID_SIZE_EXT 16 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_EXT 0x87C1 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_VECTOR_EXT 0x87BF +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_VERTEX_TEXTURE 0x829B +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_VERTICES_SUBMITTED_ARB 0x82EE +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIEWPORT 0x0BA2 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_COMMAND_NV 0x0010 +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_ASTC_10x10_RGBA 0x9393 +#define GL_VIEW_CLASS_ASTC_10x5_RGBA 0x9390 +#define GL_VIEW_CLASS_ASTC_10x6_RGBA 0x9391 +#define GL_VIEW_CLASS_ASTC_10x8_RGBA 0x9392 +#define GL_VIEW_CLASS_ASTC_12x10_RGBA 0x9394 +#define GL_VIEW_CLASS_ASTC_12x12_RGBA 0x9395 +#define GL_VIEW_CLASS_ASTC_4x4_RGBA 0x9388 +#define GL_VIEW_CLASS_ASTC_5x4_RGBA 0x9389 +#define GL_VIEW_CLASS_ASTC_5x5_RGBA 0x938A +#define GL_VIEW_CLASS_ASTC_6x5_RGBA 0x938B +#define GL_VIEW_CLASS_ASTC_6x6_RGBA 0x938C +#define GL_VIEW_CLASS_ASTC_8x5_RGBA 0x938D +#define GL_VIEW_CLASS_ASTC_8x6_RGBA 0x938E +#define GL_VIEW_CLASS_ASTC_8x8_RGBA 0x938F +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_EAC_R11 0x9383 +#define GL_VIEW_CLASS_EAC_RG11 0x9384 +#define GL_VIEW_CLASS_ETC2_EAC_RGBA 0x9387 +#define GL_VIEW_CLASS_ETC2_RGB 0x9385 +#define GL_VIEW_CLASS_ETC2_RGBA 0x9386 +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_WAIT_FAILED 0x911D +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WEIGHTED_AVERAGE_ARB 0x9367 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_WRAP_BORDER_SUN 0x81D4 +#define GL_WRITE_DISCARD_NV 0x88BE +#define GL_WRITE_ONLY 0x88B9 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_W_EXT 0x87D8 +#define GL_XOR 0x1506 +#define GL_XOR_NV 0x1506 +#define GL_X_EXT 0x87D5 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_YCBCR_MESA 0x8757 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCRCBA_SGIX 0x8319 +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#define GL_YCRCB_SGIX 0x8318 +#define GL_Y_EXT 0x87D6 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_ZERO 0 +#define GL_ZERO_EXT 0x87DD +#define GL_ZERO_TO_ONE 0x935F +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_Z_EXT 0x87D7 +#define GL_3DC_XY_AMD 0x87FA +#define GL_3DC_X_AMD 0x87F9 +#define GL_ADD_BLEND_IMG 0x8C09 +#define GL_ALPHA8_OES 0x803C +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_BGRA_IMG 0x80E1 +#define GL_BLEND_DST_ALPHA_OES 0x80CA +#define GL_BLEND_DST_RGB_OES 0x80C8 +#define GL_BLEND_EQUATION_ALPHA_OES 0x883D +#define GL_BLEND_EQUATION_OES 0x8009 +#define GL_BLEND_EQUATION_RGB_OES 0x8009 +#define GL_BLEND_SRC_ALPHA_OES 0x80CB +#define GL_BLEND_SRC_RGB_OES 0x80C9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#define GL_CLIP_PLANE0_IMG 0x3000 +#define GL_CLIP_PLANE1_IMG 0x3001 +#define GL_CLIP_PLANE2_IMG 0x3002 +#define GL_CLIP_PLANE3_IMG 0x3003 +#define GL_CLIP_PLANE4_IMG 0x3004 +#define GL_CLIP_PLANE5_IMG 0x3005 +#define GL_COLOR_ATTACHMENT0_OES 0x8CE0 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_COLOR_EXT 0x1800 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_COORD_REPLACE_OES 0x8862 +#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843 +#define GL_DECR_WRAP_OES 0x8508 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#define GL_DEPTH_ATTACHMENT_OES 0x8D00 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH_EXT 0x1801 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_DOT3_RGBA_IMG 0x86AF +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_ETC1_RGB8_OES 0x8D64 +#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07 +#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_FRAMEBUFFER_OES 0x8D40 +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD +#define GL_FUNC_ADD_OES 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B +#define GL_FUNC_SUBTRACT_OES 0x800A +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INCR_WRAP_OES 0x8507 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E +#define GL_MATRIX_INDEX_ARRAY_OES 0x8844 +#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849 +#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848 +#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847 +#define GL_MATRIX_PALETTE_OES 0x8840 +#define GL_MAX_CLIP_PLANES_IMG 0x0D32 +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C +#define GL_MAX_PALETTE_MATRICES_OES 0x8842 +#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_MAX_VERTEX_UNITS_OES 0x86A4 +#define GL_MIRRORED_REPEAT_OES 0x8370 +#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D +#define GL_MODULATE_COLOR_IMG 0x8C04 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#define GL_NONE_OES 0 +#define GL_NORMAL_MAP_OES 0x8511 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F +#define GL_POINT_SIZE_ARRAY_OES 0x8B9C +#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C +#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B +#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A +#define GL_POINT_SPRITE_OES 0x8861 +#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05 +#define GL_REFLECTION_MAP_OES 0x8512 +#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53 +#define GL_RENDERBUFFER_BINDING_OES 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51 +#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44 +#define GL_RENDERBUFFER_OES 0x8D41 +#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 +#define GL_RENDERBUFFER_WIDTH_OES 0x8D42 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_RGB565_OES 0x8D62 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA4_OES 0x8056 +#define GL_RGBA8_OES 0x8058 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_STATE_RESTORE 0x8BDC +#define GL_STENCIL_ATTACHMENT_OES 0x8D20 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_STENCIL_EXT 0x1802 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#define GL_STENCIL_INDEX8_OES 0x8D48 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06 +#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_TEXTURE_CROP_RECT_OES 0x8B9D +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A +#define GL_TEXTURE_CUBE_MAP_OES 0x8513 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_GEN_MODE_OES 0x2500 +#define GL_TEXTURE_GEN_STR_OES 0x8D60 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFF +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#define GL_VERSION_ES_CL_1_0 1 +#define GL_VERSION_ES_CL_1_1 1 +#define GL_VERSION_ES_CM_1_1 1 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E +#define GL_WEIGHT_ARRAY_OES 0x86AD +#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC +#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB +#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA +#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9 +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_KHR 0x82E0 +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 +#define GL_CLAMP_TO_BORDER_EXT 0x812D +#define GL_CLAMP_TO_BORDER_NV 0x812D +#define GL_CLAMP_TO_BORDER_OES 0x812D +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIP_DEPTH_MODE_EXT 0x935D +#define GL_CLIP_DISTANCE0_APPLE 0x3000 +#define GL_CLIP_DISTANCE0_EXT 0x3000 +#define GL_CLIP_DISTANCE1_APPLE 0x3001 +#define GL_CLIP_DISTANCE1_EXT 0x3001 +#define GL_CLIP_DISTANCE2_APPLE 0x3002 +#define GL_CLIP_DISTANCE2_EXT 0x3002 +#define GL_CLIP_DISTANCE3_APPLE 0x3003 +#define GL_CLIP_DISTANCE3_EXT 0x3003 +#define GL_CLIP_DISTANCE4_APPLE 0x3004 +#define GL_CLIP_DISTANCE4_EXT 0x3004 +#define GL_CLIP_DISTANCE5_APPLE 0x3005 +#define GL_CLIP_DISTANCE5_EXT 0x3005 +#define GL_CLIP_DISTANCE6_APPLE 0x3006 +#define GL_CLIP_DISTANCE6_EXT 0x3006 +#define GL_CLIP_DISTANCE7_APPLE 0x3007 +#define GL_CLIP_DISTANCE7_EXT 0x3007 +#define GL_CLIP_ORIGIN_EXT 0x935C +#define GL_COLORBURN 0x929A +#define GL_COLORDODGE 0x9299 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD +#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 +#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 +#define GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 +#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 +#define GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 +#define GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 +#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 +#define GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 +#define GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 +#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 +#define GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7 +#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7 +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1 +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010 +#define GL_CONTEXT_LOST_KHR 0x0507 +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC +#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB +#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_CUBIC_IMG 0x9139 +#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B +#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_DARKEN 0x9297 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEPTH_CLAMP_EXT 0x864F +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#define GL_DIFFERENCE 0x929E +#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 +#define GL_DOWNSAMPLE_SCALES_IMG 0x913E +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_ETC1_SRGB8_NV 0x88EE +#define GL_EXCLUSION 0x92A0 +#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 +#define GL_FILL_NV 0x1B02 +#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3_NV 0x8B6A +#define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001 +#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x00000002 +#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004 +#define GL_FRACTIONAL_EVEN_EXT 0x8E7C +#define GL_FRACTIONAL_EVEN_OES 0x8E7C +#define GL_FRACTIONAL_ODD_EXT 0x8E7B +#define GL_FRACTIONAL_ODD_OES 0x8E7B +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 +#define GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT 0x96DF +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT 0x96D2 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT 0x96D5 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT 0x96D4 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT 0x96D6 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT 0x96D3 +#define GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT 0x8F6F +#define GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT 0x96DE +#define GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT 0x96DD +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 +#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF +#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F +#define GL_GEOMETRY_SHADER_OES 0x8DD9 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253 +#define GL_HALF_FLOAT_OES 0x8D61 +#define GL_HARDLIGHT 0x929B +#define GL_HSL_COLOR 0x92AF +#define GL_HSL_HUE 0x92AD +#define GL_HSL_LUMINOSITY 0x92B0 +#define GL_HSL_SATURATION 0x92AE +#define GL_IMAGE_BUFFER_OES 0x9051 +#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 +#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#define GL_INT_IMAGE_BUFFER_OES 0x905C +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C +#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E +#define GL_ISOLINES_EXT 0x8E7A +#define GL_ISOLINES_OES 0x8E7A +#define GL_IS_PER_PATCH_EXT 0x92E7 +#define GL_IS_PER_PATCH_OES 0x92E7 +#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E +#define GL_LIGHTEN 0x9298 +#define GL_LINES_ADJACENCY_OES 0x000A +#define GL_LINE_NV 0x1B01 +#define GL_LINE_STRIP_ADJACENCY_OES 0x000B +#define GL_LOCATION_INDEX_EXT 0x930F +#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252 +#define GL_LOWER_LEFT_EXT 0x8CA1 +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 +#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F +#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT 0x96DC +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT 0x96DB +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96DA +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D8 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 +#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D +#define GL_MAX_PATCH_VERTICES_OES 0x8E7D +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#define GL_MAX_SAMPLES_NV 0x8D57 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 +#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A +#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E +#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 +#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 +#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B +#define GL_MAX_VIEWPORTS_NV 0x825B +#define GL_MAX_VIEWPORTS_OES 0x825B +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96D9 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D7 +#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM 0x8C90 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM 0x8C91 +#define GL_MULTIPLY 0x9294 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382 +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E +#define GL_NO_RESET_NOTIFICATION_KHR 0x8261 +#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA +#define GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT 0x8F6E +#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_OVERLAY 0x9296 +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#define GL_PACK_ROW_LENGTH_NV 0x0D02 +#define GL_PACK_SKIP_PIXELS_NV 0x0D04 +#define GL_PACK_SKIP_ROWS_NV 0x0D03 +#define GL_PATCHES_EXT 0x000E +#define GL_PATCHES_OES 0x000E +#define GL_PATCH_VERTICES_EXT 0x8E72 +#define GL_PATCH_VERTICES_OES 0x8E72 +#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED +#define GL_PIXEL_PACK_BUFFER_NV 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC +#define GL_POINT_NV 0x1B00 +#define GL_POLYGON_MODE_NV 0x0B40 +#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 +#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 +#define GL_PRIMITIVES_GENERATED_OES 0x8C87 +#define GL_PRIMITIVE_BOUNDING_BOX 0x92BE +#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE +#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#define GL_PROGRAM_PIPELINE_KHR 0x82E4 +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_QUADS_EXT 0x0007 +#define GL_QUADS_OES 0x0007 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_QUERY_KHR 0x82E3 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_R11F_G11F_B10F_APPLE 0x8C3A +#define GL_R16_EXT 0x822A +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_READ_BUFFER_NV 0x0C02 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_RED_EXT 0x1903 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256 +#define GL_RG16_EXT 0x822C +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RGB16_SNORM_EXT 0x8F9A +#define GL_RGB9_E5_APPLE 0x8C3D +#define GL_RGBA16_SNORM_EXT 0x8F9B +#define GL_RG_EXT 0x8227 +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_SAMPLER_BUFFER_OES 0x8DC2 +#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_SAMPLER_KHR 0x82E6 +#define GL_SAMPLE_SHADING_OES 0x8C36 +#define GL_SCREEN 0x9295 +#define GL_SGX_BINARY_IMG 0x8C0A +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#define GL_SHADER_BINARY_DMP 0x9250 +#define GL_SHADER_BINARY_VIV 0x8FC4 +#define GL_SHADER_CORE_ACTIVE_COUNT_ARM 0x96F1 +#define GL_SHADER_CORE_COUNT_ARM 0x96F0 +#define GL_SHADER_CORE_FMA_RATE_ARM 0x96F6 +#define GL_SHADER_CORE_MAX_WARP_COUNT_ARM 0x96F3 +#define GL_SHADER_CORE_PIXEL_RATE_ARM 0x96F4 +#define GL_SHADER_CORE_PRESENT_MASK_ARM 0x96F2 +#define GL_SHADER_CORE_TEXEL_RATE_ARM 0x96F5 +#define GL_SHADER_KHR 0x82E1 +#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 +#define GL_SHADING_RATE_1X1_PIXELS_EXT 0x96A6 +#define GL_SHADING_RATE_1X1_PIXELS_QCOM 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_EXT 0x96A7 +#define GL_SHADING_RATE_1X2_PIXELS_QCOM 0x96A7 +#define GL_SHADING_RATE_1X4_PIXELS_EXT 0x96AA +#define GL_SHADING_RATE_1X4_PIXELS_QCOM 0x96AA +#define GL_SHADING_RATE_2X1_PIXELS_EXT 0x96A8 +#define GL_SHADING_RATE_2X1_PIXELS_QCOM 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_EXT 0x96A9 +#define GL_SHADING_RATE_2X2_PIXELS_QCOM 0x96A9 +#define GL_SHADING_RATE_2X4_PIXELS_EXT 0x96AD +#define GL_SHADING_RATE_2X4_PIXELS_QCOM 0x96AD +#define GL_SHADING_RATE_4X1_PIXELS_EXT 0x96AB +#define GL_SHADING_RATE_4X1_PIXELS_QCOM 0x96AB +#define GL_SHADING_RATE_4X2_PIXELS_EXT 0x96AC +#define GL_SHADING_RATE_4X2_PIXELS_QCOM 0x96AC +#define GL_SHADING_RATE_4X4_PIXELS_EXT 0x96AE +#define GL_SHADING_RATE_4X4_PIXELS_QCOM 0x96AE +#define GL_SHADING_RATE_ATTACHMENT_EXT 0x96D1 +#define GL_SHADING_RATE_EXT 0x96D0 +#define GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM 0x96A5 +#define GL_SHADING_RATE_QCOM 0x96A4 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 +#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 +#define GL_SOFTLIGHT 0x929C +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 +#define GL_SRC1_ALPHA_EXT 0x8589 +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_SRGB8_NV 0x8C41 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#define GL_STENCIL_INDEX_OES 0x1901 +#define GL_SURFACE_COMPRESSION_EXT 0x96C0 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x96CD +#define GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x96CE +#define GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x96CF +#define GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x96C4 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x96C5 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x96C6 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x96C7 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x96C8 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x96C9 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x96CA +#define GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x96CB +#define GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x96CC +#define GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x96C2 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x96C1 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 +#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 +#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 +#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 +#define GL_TESS_CONTROL_SHADER_OES 0x8E88 +#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 +#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 +#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 +#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 +#define GL_TESS_GEN_MODE_EXT 0x8E76 +#define GL_TESS_GEN_MODE_OES 0x8E76 +#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 +#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 +#define GL_TESS_GEN_SPACING_EXT 0x8E77 +#define GL_TESS_GEN_SPACING_OES 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 +#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A +#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 +#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D +#define GL_TEXTURE_BUFFER_OES 0x8C2A +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F +#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D +#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E +#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E +#define GL_TEXTURE_CBCR_DEGAMMA_QCOM 0x9711 +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 +#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 +#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF +#define GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM 0x96A0 +#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB +#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD +#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC +#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE +#define GL_TEXTURE_LOD_BIAS_QCOM 0x8C96 +#define GL_TEXTURE_PROTECTED_EXT 0x8BFA +#define GL_TEXTURE_SPARSE_EXT 0x91A6 +#define GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM 0x8F6A +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD +#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB +#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE +#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC +#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_Y_DEGAMMA_QCOM 0x9710 +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#define GL_TRIANGLES_ADJACENCY_OES 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_UNDEFINED_VERTEX_OES 0x8260 +#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E +#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#define GL_UPPER_LEFT_EXT 0x8CA2 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D +#define GL_VIEWPORT_BOUNDS_RANGE_OES 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F +#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C +#define GL_VIEWPORT_SUBPIXEL_BITS_OES 0x825C +#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 +#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 +#define GL_Z400_BINARY_AMD 0x8740 +#define GL_ZERO_TO_ONE_EXT 0x935F + + +#include +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptr; +#else +typedef khronos_intptr_t GLintptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptrARB; +#else +typedef khronos_intptr_t GLintptrARB; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptr; +#else +typedef khronos_ssize_t GLsizeiptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptrARB; +#else +typedef khronos_ssize_t GLsizeiptrARB; +#endif +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); + + +#define GL_VERSION_1_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_0; +#define GL_VERSION_1_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_1; +#define GL_VERSION_1_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_2; +#define GL_VERSION_1_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_3; +#define GL_VERSION_1_4 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_4; +#define GL_VERSION_1_5 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_5; +#define GL_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_0; +#define GL_VERSION_2_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_1; +#define GL_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_0; +#define GL_VERSION_3_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_1; +#define GL_VERSION_3_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_2; +#define GL_VERSION_3_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_3; +#define GL_VERSION_4_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_0; +#define GL_VERSION_4_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_1; +#define GL_VERSION_4_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_2; +#define GL_VERSION_4_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_3; +#define GL_VERSION_4_4 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_4; +#define GL_VERSION_4_5 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_5; +#define GL_VERSION_4_6 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_6; +#define GL_VERSION_ES_CM_1_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_ES_CM_1_0; +#define GL_ES_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_2_0; +#define GL_ES_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_0; +#define GL_ES_VERSION_3_1 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_1; +#define GL_ES_VERSION_3_2 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_2; +#define GL_3DFX_multisample 1 +GLAD_API_CALL int GLAD_GL_3DFX_multisample; +#define GL_3DFX_tbuffer 1 +GLAD_API_CALL int GLAD_GL_3DFX_tbuffer; +#define GL_3DFX_texture_compression_FXT1 1 +GLAD_API_CALL int GLAD_GL_3DFX_texture_compression_FXT1; +#define GL_AMD_blend_minmax_factor 1 +GLAD_API_CALL int GLAD_GL_AMD_blend_minmax_factor; +#define GL_AMD_conservative_depth 1 +GLAD_API_CALL int GLAD_GL_AMD_conservative_depth; +#define GL_AMD_debug_output 1 +GLAD_API_CALL int GLAD_GL_AMD_debug_output; +#define GL_AMD_depth_clamp_separate 1 +GLAD_API_CALL int GLAD_GL_AMD_depth_clamp_separate; +#define GL_AMD_draw_buffers_blend 1 +GLAD_API_CALL int GLAD_GL_AMD_draw_buffers_blend; +#define GL_AMD_framebuffer_multisample_advanced 1 +GLAD_API_CALL int GLAD_GL_AMD_framebuffer_multisample_advanced; +#define GL_AMD_framebuffer_sample_positions 1 +GLAD_API_CALL int GLAD_GL_AMD_framebuffer_sample_positions; +#define GL_AMD_gcn_shader 1 +GLAD_API_CALL int GLAD_GL_AMD_gcn_shader; +#define GL_AMD_gpu_shader_half_float 1 +GLAD_API_CALL int GLAD_GL_AMD_gpu_shader_half_float; +#define GL_AMD_gpu_shader_int16 1 +GLAD_API_CALL int GLAD_GL_AMD_gpu_shader_int16; +#define GL_AMD_gpu_shader_int64 1 +GLAD_API_CALL int GLAD_GL_AMD_gpu_shader_int64; +#define GL_AMD_interleaved_elements 1 +GLAD_API_CALL int GLAD_GL_AMD_interleaved_elements; +#define GL_AMD_multi_draw_indirect 1 +GLAD_API_CALL int GLAD_GL_AMD_multi_draw_indirect; +#define GL_AMD_name_gen_delete 1 +GLAD_API_CALL int GLAD_GL_AMD_name_gen_delete; +#define GL_AMD_occlusion_query_event 1 +GLAD_API_CALL int GLAD_GL_AMD_occlusion_query_event; +#define GL_AMD_performance_monitor 1 +GLAD_API_CALL int GLAD_GL_AMD_performance_monitor; +#define GL_AMD_pinned_memory 1 +GLAD_API_CALL int GLAD_GL_AMD_pinned_memory; +#define GL_AMD_query_buffer_object 1 +GLAD_API_CALL int GLAD_GL_AMD_query_buffer_object; +#define GL_AMD_sample_positions 1 +GLAD_API_CALL int GLAD_GL_AMD_sample_positions; +#define GL_AMD_seamless_cubemap_per_texture 1 +GLAD_API_CALL int GLAD_GL_AMD_seamless_cubemap_per_texture; +#define GL_AMD_shader_atomic_counter_ops 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_atomic_counter_ops; +#define GL_AMD_shader_ballot 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_ballot; +#define GL_AMD_shader_explicit_vertex_parameter 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_explicit_vertex_parameter; +#define GL_AMD_shader_gpu_shader_half_float_fetch 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch; +#define GL_AMD_shader_image_load_store_lod 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_image_load_store_lod; +#define GL_AMD_shader_stencil_export 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_stencil_export; +#define GL_AMD_shader_trinary_minmax 1 +GLAD_API_CALL int GLAD_GL_AMD_shader_trinary_minmax; +#define GL_AMD_sparse_texture 1 +GLAD_API_CALL int GLAD_GL_AMD_sparse_texture; +#define GL_AMD_stencil_operation_extended 1 +GLAD_API_CALL int GLAD_GL_AMD_stencil_operation_extended; +#define GL_AMD_texture_gather_bias_lod 1 +GLAD_API_CALL int GLAD_GL_AMD_texture_gather_bias_lod; +#define GL_AMD_texture_texture4 1 +GLAD_API_CALL int GLAD_GL_AMD_texture_texture4; +#define GL_AMD_transform_feedback3_lines_triangles 1 +GLAD_API_CALL int GLAD_GL_AMD_transform_feedback3_lines_triangles; +#define GL_AMD_transform_feedback4 1 +GLAD_API_CALL int GLAD_GL_AMD_transform_feedback4; +#define GL_AMD_vertex_shader_layer 1 +GLAD_API_CALL int GLAD_GL_AMD_vertex_shader_layer; +#define GL_AMD_vertex_shader_tessellator 1 +GLAD_API_CALL int GLAD_GL_AMD_vertex_shader_tessellator; +#define GL_AMD_vertex_shader_viewport_index 1 +GLAD_API_CALL int GLAD_GL_AMD_vertex_shader_viewport_index; +#define GL_APPLE_aux_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_APPLE_aux_depth_stencil; +#define GL_APPLE_client_storage 1 +GLAD_API_CALL int GLAD_GL_APPLE_client_storage; +#define GL_APPLE_element_array 1 +GLAD_API_CALL int GLAD_GL_APPLE_element_array; +#define GL_APPLE_fence 1 +GLAD_API_CALL int GLAD_GL_APPLE_fence; +#define GL_APPLE_float_pixels 1 +GLAD_API_CALL int GLAD_GL_APPLE_float_pixels; +#define GL_APPLE_flush_buffer_range 1 +GLAD_API_CALL int GLAD_GL_APPLE_flush_buffer_range; +#define GL_APPLE_object_purgeable 1 +GLAD_API_CALL int GLAD_GL_APPLE_object_purgeable; +#define GL_APPLE_rgb_422 1 +GLAD_API_CALL int GLAD_GL_APPLE_rgb_422; +#define GL_APPLE_row_bytes 1 +GLAD_API_CALL int GLAD_GL_APPLE_row_bytes; +#define GL_APPLE_specular_vector 1 +GLAD_API_CALL int GLAD_GL_APPLE_specular_vector; +#define GL_APPLE_texture_range 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_range; +#define GL_APPLE_transform_hint 1 +GLAD_API_CALL int GLAD_GL_APPLE_transform_hint; +#define GL_APPLE_vertex_array_object 1 +GLAD_API_CALL int GLAD_GL_APPLE_vertex_array_object; +#define GL_APPLE_vertex_array_range 1 +GLAD_API_CALL int GLAD_GL_APPLE_vertex_array_range; +#define GL_APPLE_vertex_program_evaluators 1 +GLAD_API_CALL int GLAD_GL_APPLE_vertex_program_evaluators; +#define GL_APPLE_ycbcr_422 1 +GLAD_API_CALL int GLAD_GL_APPLE_ycbcr_422; +#define GL_ARB_ES2_compatibility 1 +GLAD_API_CALL int GLAD_GL_ARB_ES2_compatibility; +#define GL_ARB_ES3_1_compatibility 1 +GLAD_API_CALL int GLAD_GL_ARB_ES3_1_compatibility; +#define GL_ARB_ES3_2_compatibility 1 +GLAD_API_CALL int GLAD_GL_ARB_ES3_2_compatibility; +#define GL_ARB_ES3_compatibility 1 +GLAD_API_CALL int GLAD_GL_ARB_ES3_compatibility; +#define GL_ARB_arrays_of_arrays 1 +GLAD_API_CALL int GLAD_GL_ARB_arrays_of_arrays; +#define GL_ARB_base_instance 1 +GLAD_API_CALL int GLAD_GL_ARB_base_instance; +#define GL_ARB_bindless_texture 1 +GLAD_API_CALL int GLAD_GL_ARB_bindless_texture; +#define GL_ARB_blend_func_extended 1 +GLAD_API_CALL int GLAD_GL_ARB_blend_func_extended; +#define GL_ARB_buffer_storage 1 +GLAD_API_CALL int GLAD_GL_ARB_buffer_storage; +#define GL_ARB_cl_event 1 +GLAD_API_CALL int GLAD_GL_ARB_cl_event; +#define GL_ARB_clear_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_clear_buffer_object; +#define GL_ARB_clear_texture 1 +GLAD_API_CALL int GLAD_GL_ARB_clear_texture; +#define GL_ARB_clip_control 1 +GLAD_API_CALL int GLAD_GL_ARB_clip_control; +#define GL_ARB_color_buffer_float 1 +GLAD_API_CALL int GLAD_GL_ARB_color_buffer_float; +#define GL_ARB_compatibility 1 +GLAD_API_CALL int GLAD_GL_ARB_compatibility; +#define GL_ARB_compressed_texture_pixel_storage 1 +GLAD_API_CALL int GLAD_GL_ARB_compressed_texture_pixel_storage; +#define GL_ARB_compute_shader 1 +GLAD_API_CALL int GLAD_GL_ARB_compute_shader; +#define GL_ARB_compute_variable_group_size 1 +GLAD_API_CALL int GLAD_GL_ARB_compute_variable_group_size; +#define GL_ARB_conditional_render_inverted 1 +GLAD_API_CALL int GLAD_GL_ARB_conditional_render_inverted; +#define GL_ARB_conservative_depth 1 +GLAD_API_CALL int GLAD_GL_ARB_conservative_depth; +#define GL_ARB_copy_buffer 1 +GLAD_API_CALL int GLAD_GL_ARB_copy_buffer; +#define GL_ARB_copy_image 1 +GLAD_API_CALL int GLAD_GL_ARB_copy_image; +#define GL_ARB_cull_distance 1 +GLAD_API_CALL int GLAD_GL_ARB_cull_distance; +#define GL_ARB_debug_output 1 +GLAD_API_CALL int GLAD_GL_ARB_debug_output; +#define GL_ARB_depth_buffer_float 1 +GLAD_API_CALL int GLAD_GL_ARB_depth_buffer_float; +#define GL_ARB_depth_clamp 1 +GLAD_API_CALL int GLAD_GL_ARB_depth_clamp; +#define GL_ARB_depth_texture 1 +GLAD_API_CALL int GLAD_GL_ARB_depth_texture; +#define GL_ARB_derivative_control 1 +GLAD_API_CALL int GLAD_GL_ARB_derivative_control; +#define GL_ARB_direct_state_access 1 +GLAD_API_CALL int GLAD_GL_ARB_direct_state_access; +#define GL_ARB_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_ARB_draw_buffers; +#define GL_ARB_draw_buffers_blend 1 +GLAD_API_CALL int GLAD_GL_ARB_draw_buffers_blend; +#define GL_ARB_draw_elements_base_vertex 1 +GLAD_API_CALL int GLAD_GL_ARB_draw_elements_base_vertex; +#define GL_ARB_draw_indirect 1 +GLAD_API_CALL int GLAD_GL_ARB_draw_indirect; +#define GL_ARB_draw_instanced 1 +GLAD_API_CALL int GLAD_GL_ARB_draw_instanced; +#define GL_ARB_enhanced_layouts 1 +GLAD_API_CALL int GLAD_GL_ARB_enhanced_layouts; +#define GL_ARB_explicit_attrib_location 1 +GLAD_API_CALL int GLAD_GL_ARB_explicit_attrib_location; +#define GL_ARB_explicit_uniform_location 1 +GLAD_API_CALL int GLAD_GL_ARB_explicit_uniform_location; +#define GL_ARB_fragment_coord_conventions 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_coord_conventions; +#define GL_ARB_fragment_layer_viewport 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_layer_viewport; +#define GL_ARB_fragment_program 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_program; +#define GL_ARB_fragment_program_shadow 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_program_shadow; +#define GL_ARB_fragment_shader 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_shader; +#define GL_ARB_fragment_shader_interlock 1 +GLAD_API_CALL int GLAD_GL_ARB_fragment_shader_interlock; +#define GL_ARB_framebuffer_no_attachments 1 +GLAD_API_CALL int GLAD_GL_ARB_framebuffer_no_attachments; +#define GL_ARB_framebuffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_framebuffer_object; +#define GL_ARB_framebuffer_sRGB 1 +GLAD_API_CALL int GLAD_GL_ARB_framebuffer_sRGB; +#define GL_ARB_geometry_shader4 1 +GLAD_API_CALL int GLAD_GL_ARB_geometry_shader4; +#define GL_ARB_get_program_binary 1 +GLAD_API_CALL int GLAD_GL_ARB_get_program_binary; +#define GL_ARB_get_texture_sub_image 1 +GLAD_API_CALL int GLAD_GL_ARB_get_texture_sub_image; +#define GL_ARB_gl_spirv 1 +GLAD_API_CALL int GLAD_GL_ARB_gl_spirv; +#define GL_ARB_gpu_shader5 1 +GLAD_API_CALL int GLAD_GL_ARB_gpu_shader5; +#define GL_ARB_gpu_shader_fp64 1 +GLAD_API_CALL int GLAD_GL_ARB_gpu_shader_fp64; +#define GL_ARB_gpu_shader_int64 1 +GLAD_API_CALL int GLAD_GL_ARB_gpu_shader_int64; +#define GL_ARB_half_float_pixel 1 +GLAD_API_CALL int GLAD_GL_ARB_half_float_pixel; +#define GL_ARB_half_float_vertex 1 +GLAD_API_CALL int GLAD_GL_ARB_half_float_vertex; +#define GL_ARB_imaging 1 +GLAD_API_CALL int GLAD_GL_ARB_imaging; +#define GL_ARB_indirect_parameters 1 +GLAD_API_CALL int GLAD_GL_ARB_indirect_parameters; +#define GL_ARB_instanced_arrays 1 +GLAD_API_CALL int GLAD_GL_ARB_instanced_arrays; +#define GL_ARB_internalformat_query 1 +GLAD_API_CALL int GLAD_GL_ARB_internalformat_query; +#define GL_ARB_internalformat_query2 1 +GLAD_API_CALL int GLAD_GL_ARB_internalformat_query2; +#define GL_ARB_invalidate_subdata 1 +GLAD_API_CALL int GLAD_GL_ARB_invalidate_subdata; +#define GL_ARB_map_buffer_alignment 1 +GLAD_API_CALL int GLAD_GL_ARB_map_buffer_alignment; +#define GL_ARB_map_buffer_range 1 +GLAD_API_CALL int GLAD_GL_ARB_map_buffer_range; +#define GL_ARB_matrix_palette 1 +GLAD_API_CALL int GLAD_GL_ARB_matrix_palette; +#define GL_ARB_multi_bind 1 +GLAD_API_CALL int GLAD_GL_ARB_multi_bind; +#define GL_ARB_multi_draw_indirect 1 +GLAD_API_CALL int GLAD_GL_ARB_multi_draw_indirect; +#define GL_ARB_multisample 1 +GLAD_API_CALL int GLAD_GL_ARB_multisample; +#define GL_ARB_multitexture 1 +GLAD_API_CALL int GLAD_GL_ARB_multitexture; +#define GL_ARB_occlusion_query 1 +GLAD_API_CALL int GLAD_GL_ARB_occlusion_query; +#define GL_ARB_occlusion_query2 1 +GLAD_API_CALL int GLAD_GL_ARB_occlusion_query2; +#define GL_ARB_parallel_shader_compile 1 +GLAD_API_CALL int GLAD_GL_ARB_parallel_shader_compile; +#define GL_ARB_pipeline_statistics_query 1 +GLAD_API_CALL int GLAD_GL_ARB_pipeline_statistics_query; +#define GL_ARB_pixel_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_pixel_buffer_object; +#define GL_ARB_point_parameters 1 +GLAD_API_CALL int GLAD_GL_ARB_point_parameters; +#define GL_ARB_point_sprite 1 +GLAD_API_CALL int GLAD_GL_ARB_point_sprite; +#define GL_ARB_polygon_offset_clamp 1 +GLAD_API_CALL int GLAD_GL_ARB_polygon_offset_clamp; +#define GL_ARB_post_depth_coverage 1 +GLAD_API_CALL int GLAD_GL_ARB_post_depth_coverage; +#define GL_ARB_program_interface_query 1 +GLAD_API_CALL int GLAD_GL_ARB_program_interface_query; +#define GL_ARB_provoking_vertex 1 +GLAD_API_CALL int GLAD_GL_ARB_provoking_vertex; +#define GL_ARB_query_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_query_buffer_object; +#define GL_ARB_robust_buffer_access_behavior 1 +GLAD_API_CALL int GLAD_GL_ARB_robust_buffer_access_behavior; +#define GL_ARB_robustness 1 +GLAD_API_CALL int GLAD_GL_ARB_robustness; +#define GL_ARB_robustness_isolation 1 +GLAD_API_CALL int GLAD_GL_ARB_robustness_isolation; +#define GL_ARB_sample_locations 1 +GLAD_API_CALL int GLAD_GL_ARB_sample_locations; +#define GL_ARB_sample_shading 1 +GLAD_API_CALL int GLAD_GL_ARB_sample_shading; +#define GL_ARB_sampler_objects 1 +GLAD_API_CALL int GLAD_GL_ARB_sampler_objects; +#define GL_ARB_seamless_cube_map 1 +GLAD_API_CALL int GLAD_GL_ARB_seamless_cube_map; +#define GL_ARB_seamless_cubemap_per_texture 1 +GLAD_API_CALL int GLAD_GL_ARB_seamless_cubemap_per_texture; +#define GL_ARB_separate_shader_objects 1 +GLAD_API_CALL int GLAD_GL_ARB_separate_shader_objects; +#define GL_ARB_shader_atomic_counter_ops 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_atomic_counter_ops; +#define GL_ARB_shader_atomic_counters 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_atomic_counters; +#define GL_ARB_shader_ballot 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_ballot; +#define GL_ARB_shader_bit_encoding 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_bit_encoding; +#define GL_ARB_shader_clock 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_clock; +#define GL_ARB_shader_draw_parameters 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_draw_parameters; +#define GL_ARB_shader_group_vote 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_group_vote; +#define GL_ARB_shader_image_load_store 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_image_load_store; +#define GL_ARB_shader_image_size 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_image_size; +#define GL_ARB_shader_objects 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_objects; +#define GL_ARB_shader_precision 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_precision; +#define GL_ARB_shader_stencil_export 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_stencil_export; +#define GL_ARB_shader_storage_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_storage_buffer_object; +#define GL_ARB_shader_subroutine 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_subroutine; +#define GL_ARB_shader_texture_image_samples 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_texture_image_samples; +#define GL_ARB_shader_texture_lod 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_texture_lod; +#define GL_ARB_shader_viewport_layer_array 1 +GLAD_API_CALL int GLAD_GL_ARB_shader_viewport_layer_array; +#define GL_ARB_shading_language_100 1 +GLAD_API_CALL int GLAD_GL_ARB_shading_language_100; +#define GL_ARB_shading_language_420pack 1 +GLAD_API_CALL int GLAD_GL_ARB_shading_language_420pack; +#define GL_ARB_shading_language_include 1 +GLAD_API_CALL int GLAD_GL_ARB_shading_language_include; +#define GL_ARB_shading_language_packing 1 +GLAD_API_CALL int GLAD_GL_ARB_shading_language_packing; +#define GL_ARB_shadow 1 +GLAD_API_CALL int GLAD_GL_ARB_shadow; +#define GL_ARB_shadow_ambient 1 +GLAD_API_CALL int GLAD_GL_ARB_shadow_ambient; +#define GL_ARB_sparse_buffer 1 +GLAD_API_CALL int GLAD_GL_ARB_sparse_buffer; +#define GL_ARB_sparse_texture 1 +GLAD_API_CALL int GLAD_GL_ARB_sparse_texture; +#define GL_ARB_sparse_texture2 1 +GLAD_API_CALL int GLAD_GL_ARB_sparse_texture2; +#define GL_ARB_sparse_texture_clamp 1 +GLAD_API_CALL int GLAD_GL_ARB_sparse_texture_clamp; +#define GL_ARB_spirv_extensions 1 +GLAD_API_CALL int GLAD_GL_ARB_spirv_extensions; +#define GL_ARB_stencil_texturing 1 +GLAD_API_CALL int GLAD_GL_ARB_stencil_texturing; +#define GL_ARB_sync 1 +GLAD_API_CALL int GLAD_GL_ARB_sync; +#define GL_ARB_tessellation_shader 1 +GLAD_API_CALL int GLAD_GL_ARB_tessellation_shader; +#define GL_ARB_texture_barrier 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_barrier; +#define GL_ARB_texture_border_clamp 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_border_clamp; +#define GL_ARB_texture_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_object; +#define GL_ARB_texture_buffer_object_rgb32 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_object_rgb32; +#define GL_ARB_texture_buffer_range 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_range; +#define GL_ARB_texture_compression 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_compression; +#define GL_ARB_texture_compression_bptc 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_compression_bptc; +#define GL_ARB_texture_compression_rgtc 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_compression_rgtc; +#define GL_ARB_texture_cube_map 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_cube_map; +#define GL_ARB_texture_cube_map_array 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_cube_map_array; +#define GL_ARB_texture_env_add 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_env_add; +#define GL_ARB_texture_env_combine 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_env_combine; +#define GL_ARB_texture_env_crossbar 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_env_crossbar; +#define GL_ARB_texture_env_dot3 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_env_dot3; +#define GL_ARB_texture_filter_anisotropic 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_filter_anisotropic; +#define GL_ARB_texture_filter_minmax 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_filter_minmax; +#define GL_ARB_texture_float 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_float; +#define GL_ARB_texture_gather 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_gather; +#define GL_ARB_texture_mirror_clamp_to_edge 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_mirror_clamp_to_edge; +#define GL_ARB_texture_mirrored_repeat 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_mirrored_repeat; +#define GL_ARB_texture_multisample 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_multisample; +#define GL_ARB_texture_non_power_of_two 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_non_power_of_two; +#define GL_ARB_texture_query_levels 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_query_levels; +#define GL_ARB_texture_query_lod 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_query_lod; +#define GL_ARB_texture_rectangle 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_rectangle; +#define GL_ARB_texture_rg 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_rg; +#define GL_ARB_texture_rgb10_a2ui 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_rgb10_a2ui; +#define GL_ARB_texture_stencil8 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_stencil8; +#define GL_ARB_texture_storage 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_storage; +#define GL_ARB_texture_storage_multisample 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_storage_multisample; +#define GL_ARB_texture_swizzle 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_swizzle; +#define GL_ARB_texture_view 1 +GLAD_API_CALL int GLAD_GL_ARB_texture_view; +#define GL_ARB_timer_query 1 +GLAD_API_CALL int GLAD_GL_ARB_timer_query; +#define GL_ARB_transform_feedback2 1 +GLAD_API_CALL int GLAD_GL_ARB_transform_feedback2; +#define GL_ARB_transform_feedback3 1 +GLAD_API_CALL int GLAD_GL_ARB_transform_feedback3; +#define GL_ARB_transform_feedback_instanced 1 +GLAD_API_CALL int GLAD_GL_ARB_transform_feedback_instanced; +#define GL_ARB_transform_feedback_overflow_query 1 +GLAD_API_CALL int GLAD_GL_ARB_transform_feedback_overflow_query; +#define GL_ARB_transpose_matrix 1 +GLAD_API_CALL int GLAD_GL_ARB_transpose_matrix; +#define GL_ARB_uniform_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_uniform_buffer_object; +#define GL_ARB_vertex_array_bgra 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_array_bgra; +#define GL_ARB_vertex_array_object 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_array_object; +#define GL_ARB_vertex_attrib_64bit 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_attrib_64bit; +#define GL_ARB_vertex_attrib_binding 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_attrib_binding; +#define GL_ARB_vertex_blend 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_blend; +#define GL_ARB_vertex_buffer_object 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_buffer_object; +#define GL_ARB_vertex_program 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_program; +#define GL_ARB_vertex_shader 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_shader; +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev; +#define GL_ARB_vertex_type_2_10_10_10_rev 1 +GLAD_API_CALL int GLAD_GL_ARB_vertex_type_2_10_10_10_rev; +#define GL_ARB_viewport_array 1 +GLAD_API_CALL int GLAD_GL_ARB_viewport_array; +#define GL_ARB_window_pos 1 +GLAD_API_CALL int GLAD_GL_ARB_window_pos; +#define GL_ATI_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_ATI_draw_buffers; +#define GL_ATI_element_array 1 +GLAD_API_CALL int GLAD_GL_ATI_element_array; +#define GL_ATI_envmap_bumpmap 1 +GLAD_API_CALL int GLAD_GL_ATI_envmap_bumpmap; +#define GL_ATI_fragment_shader 1 +GLAD_API_CALL int GLAD_GL_ATI_fragment_shader; +#define GL_ATI_map_object_buffer 1 +GLAD_API_CALL int GLAD_GL_ATI_map_object_buffer; +#define GL_ATI_meminfo 1 +GLAD_API_CALL int GLAD_GL_ATI_meminfo; +#define GL_ATI_pixel_format_float 1 +GLAD_API_CALL int GLAD_GL_ATI_pixel_format_float; +#define GL_ATI_pn_triangles 1 +GLAD_API_CALL int GLAD_GL_ATI_pn_triangles; +#define GL_ATI_separate_stencil 1 +GLAD_API_CALL int GLAD_GL_ATI_separate_stencil; +#define GL_ATI_text_fragment_shader 1 +GLAD_API_CALL int GLAD_GL_ATI_text_fragment_shader; +#define GL_ATI_texture_env_combine3 1 +GLAD_API_CALL int GLAD_GL_ATI_texture_env_combine3; +#define GL_ATI_texture_float 1 +GLAD_API_CALL int GLAD_GL_ATI_texture_float; +#define GL_ATI_texture_mirror_once 1 +GLAD_API_CALL int GLAD_GL_ATI_texture_mirror_once; +#define GL_ATI_vertex_array_object 1 +GLAD_API_CALL int GLAD_GL_ATI_vertex_array_object; +#define GL_ATI_vertex_attrib_array_object 1 +GLAD_API_CALL int GLAD_GL_ATI_vertex_attrib_array_object; +#define GL_ATI_vertex_streams 1 +GLAD_API_CALL int GLAD_GL_ATI_vertex_streams; +#define GL_EXT_422_pixels 1 +GLAD_API_CALL int GLAD_GL_EXT_422_pixels; +#define GL_EXT_EGL_image_storage 1 +GLAD_API_CALL int GLAD_GL_EXT_EGL_image_storage; +#define GL_EXT_EGL_sync 1 +GLAD_API_CALL int GLAD_GL_EXT_EGL_sync; +#define GL_EXT_abgr 1 +GLAD_API_CALL int GLAD_GL_EXT_abgr; +#define GL_EXT_bgra 1 +GLAD_API_CALL int GLAD_GL_EXT_bgra; +#define GL_EXT_bindable_uniform 1 +GLAD_API_CALL int GLAD_GL_EXT_bindable_uniform; +#define GL_EXT_blend_color 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_color; +#define GL_EXT_blend_equation_separate 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_equation_separate; +#define GL_EXT_blend_func_separate 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_func_separate; +#define GL_EXT_blend_logic_op 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_logic_op; +#define GL_EXT_blend_minmax 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_minmax; +#define GL_EXT_blend_subtract 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_subtract; +#define GL_EXT_clip_volume_hint 1 +GLAD_API_CALL int GLAD_GL_EXT_clip_volume_hint; +#define GL_EXT_cmyka 1 +GLAD_API_CALL int GLAD_GL_EXT_cmyka; +#define GL_EXT_color_subtable 1 +GLAD_API_CALL int GLAD_GL_EXT_color_subtable; +#define GL_EXT_compiled_vertex_array 1 +GLAD_API_CALL int GLAD_GL_EXT_compiled_vertex_array; +#define GL_EXT_convolution 1 +GLAD_API_CALL int GLAD_GL_EXT_convolution; +#define GL_EXT_coordinate_frame 1 +GLAD_API_CALL int GLAD_GL_EXT_coordinate_frame; +#define GL_EXT_copy_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_copy_texture; +#define GL_EXT_cull_vertex 1 +GLAD_API_CALL int GLAD_GL_EXT_cull_vertex; +#define GL_EXT_debug_label 1 +GLAD_API_CALL int GLAD_GL_EXT_debug_label; +#define GL_EXT_debug_marker 1 +GLAD_API_CALL int GLAD_GL_EXT_debug_marker; +#define GL_EXT_depth_bounds_test 1 +GLAD_API_CALL int GLAD_GL_EXT_depth_bounds_test; +#define GL_EXT_direct_state_access 1 +GLAD_API_CALL int GLAD_GL_EXT_direct_state_access; +#define GL_EXT_draw_buffers2 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_buffers2; +#define GL_EXT_draw_instanced 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_instanced; +#define GL_EXT_draw_range_elements 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_range_elements; +#define GL_EXT_external_buffer 1 +GLAD_API_CALL int GLAD_GL_EXT_external_buffer; +#define GL_EXT_fog_coord 1 +GLAD_API_CALL int GLAD_GL_EXT_fog_coord; +#define GL_EXT_framebuffer_blit 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit; +#define GL_EXT_framebuffer_blit_layers 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit_layers; +#define GL_EXT_framebuffer_multisample 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample; +#define GL_EXT_framebuffer_multisample_blit_scaled 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample_blit_scaled; +#define GL_EXT_framebuffer_object 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object; +#define GL_EXT_framebuffer_sRGB 1 +GLAD_API_CALL int GLAD_GL_EXT_framebuffer_sRGB; +#define GL_EXT_geometry_shader4 1 +GLAD_API_CALL int GLAD_GL_EXT_geometry_shader4; +#define GL_EXT_gpu_program_parameters 1 +GLAD_API_CALL int GLAD_GL_EXT_gpu_program_parameters; +#define GL_EXT_gpu_shader4 1 +GLAD_API_CALL int GLAD_GL_EXT_gpu_shader4; +#define GL_EXT_histogram 1 +GLAD_API_CALL int GLAD_GL_EXT_histogram; +#define GL_EXT_index_array_formats 1 +GLAD_API_CALL int GLAD_GL_EXT_index_array_formats; +#define GL_EXT_index_func 1 +GLAD_API_CALL int GLAD_GL_EXT_index_func; +#define GL_EXT_index_material 1 +GLAD_API_CALL int GLAD_GL_EXT_index_material; +#define GL_EXT_index_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_index_texture; +#define GL_EXT_light_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_light_texture; +#define GL_EXT_memory_object 1 +GLAD_API_CALL int GLAD_GL_EXT_memory_object; +#define GL_EXT_memory_object_fd 1 +GLAD_API_CALL int GLAD_GL_EXT_memory_object_fd; +#define GL_EXT_memory_object_win32 1 +GLAD_API_CALL int GLAD_GL_EXT_memory_object_win32; +#define GL_EXT_misc_attribute 1 +GLAD_API_CALL int GLAD_GL_EXT_misc_attribute; +#define GL_EXT_multi_draw_arrays 1 +GLAD_API_CALL int GLAD_GL_EXT_multi_draw_arrays; +#define GL_EXT_multisample 1 +GLAD_API_CALL int GLAD_GL_EXT_multisample; +#define GL_EXT_multiview_tessellation_geometry_shader 1 +GLAD_API_CALL int GLAD_GL_EXT_multiview_tessellation_geometry_shader; +#define GL_EXT_multiview_texture_multisample 1 +GLAD_API_CALL int GLAD_GL_EXT_multiview_texture_multisample; +#define GL_EXT_multiview_timer_query 1 +GLAD_API_CALL int GLAD_GL_EXT_multiview_timer_query; +#define GL_EXT_packed_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_EXT_packed_depth_stencil; +#define GL_EXT_packed_float 1 +GLAD_API_CALL int GLAD_GL_EXT_packed_float; +#define GL_EXT_packed_pixels 1 +GLAD_API_CALL int GLAD_GL_EXT_packed_pixels; +#define GL_EXT_paletted_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_paletted_texture; +#define GL_EXT_pixel_buffer_object 1 +GLAD_API_CALL int GLAD_GL_EXT_pixel_buffer_object; +#define GL_EXT_pixel_transform 1 +GLAD_API_CALL int GLAD_GL_EXT_pixel_transform; +#define GL_EXT_pixel_transform_color_table 1 +GLAD_API_CALL int GLAD_GL_EXT_pixel_transform_color_table; +#define GL_EXT_point_parameters 1 +GLAD_API_CALL int GLAD_GL_EXT_point_parameters; +#define GL_EXT_polygon_offset 1 +GLAD_API_CALL int GLAD_GL_EXT_polygon_offset; +#define GL_EXT_polygon_offset_clamp 1 +GLAD_API_CALL int GLAD_GL_EXT_polygon_offset_clamp; +#define GL_EXT_post_depth_coverage 1 +GLAD_API_CALL int GLAD_GL_EXT_post_depth_coverage; +#define GL_EXT_provoking_vertex 1 +GLAD_API_CALL int GLAD_GL_EXT_provoking_vertex; +#define GL_EXT_raster_multisample 1 +GLAD_API_CALL int GLAD_GL_EXT_raster_multisample; +#define GL_EXT_rescale_normal 1 +GLAD_API_CALL int GLAD_GL_EXT_rescale_normal; +#define GL_EXT_secondary_color 1 +GLAD_API_CALL int GLAD_GL_EXT_secondary_color; +#define GL_EXT_semaphore 1 +GLAD_API_CALL int GLAD_GL_EXT_semaphore; +#define GL_EXT_semaphore_fd 1 +GLAD_API_CALL int GLAD_GL_EXT_semaphore_fd; +#define GL_EXT_semaphore_win32 1 +GLAD_API_CALL int GLAD_GL_EXT_semaphore_win32; +#define GL_EXT_separate_specular_color 1 +GLAD_API_CALL int GLAD_GL_EXT_separate_specular_color; +#define GL_EXT_shader_framebuffer_fetch 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_framebuffer_fetch; +#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent; +#define GL_EXT_shader_image_load_formatted 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_image_load_formatted; +#define GL_EXT_shader_image_load_store 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_image_load_store; +#define GL_EXT_shader_integer_mix 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_integer_mix; +#define GL_EXT_shader_samples_identical 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_samples_identical; +#define GL_EXT_shadow_funcs 1 +GLAD_API_CALL int GLAD_GL_EXT_shadow_funcs; +#define GL_EXT_shared_texture_palette 1 +GLAD_API_CALL int GLAD_GL_EXT_shared_texture_palette; +#define GL_EXT_sparse_texture2 1 +GLAD_API_CALL int GLAD_GL_EXT_sparse_texture2; +#define GL_EXT_stencil_clear_tag 1 +GLAD_API_CALL int GLAD_GL_EXT_stencil_clear_tag; +#define GL_EXT_stencil_two_side 1 +GLAD_API_CALL int GLAD_GL_EXT_stencil_two_side; +#define GL_EXT_stencil_wrap 1 +GLAD_API_CALL int GLAD_GL_EXT_stencil_wrap; +#define GL_EXT_subtexture 1 +GLAD_API_CALL int GLAD_GL_EXT_subtexture; +#define GL_EXT_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_texture; +#define GL_EXT_texture3D 1 +GLAD_API_CALL int GLAD_GL_EXT_texture3D; +#define GL_EXT_texture_array 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_array; +#define GL_EXT_texture_buffer_object 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_buffer_object; +#define GL_EXT_texture_compression_latc 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_latc; +#define GL_EXT_texture_compression_rgtc 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_rgtc; +#define GL_EXT_texture_compression_s3tc 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc; +#define GL_EXT_texture_cube_map 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_cube_map; +#define GL_EXT_texture_env_add 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_env_add; +#define GL_EXT_texture_env_combine 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_env_combine; +#define GL_EXT_texture_env_dot3 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_env_dot3; +#define GL_EXT_texture_filter_anisotropic 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic; +#define GL_EXT_texture_filter_minmax 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_filter_minmax; +#define GL_EXT_texture_integer 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_integer; +#define GL_EXT_texture_lod_bias 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_lod_bias; +#define GL_EXT_texture_mirror_clamp 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_mirror_clamp; +#define GL_EXT_texture_object 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_object; +#define GL_EXT_texture_perturb_normal 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_perturb_normal; +#define GL_EXT_texture_sRGB 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB; +#define GL_EXT_texture_sRGB_R8 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB_R8; +#define GL_EXT_texture_sRGB_RG8 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB_RG8; +#define GL_EXT_texture_sRGB_decode 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB_decode; +#define GL_EXT_texture_shadow_lod 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_shadow_lod; +#define GL_EXT_texture_shared_exponent 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_shared_exponent; +#define GL_EXT_texture_snorm 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_snorm; +#define GL_EXT_texture_storage 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_storage; +#define GL_EXT_texture_swizzle 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_swizzle; +#define GL_EXT_timer_query 1 +GLAD_API_CALL int GLAD_GL_EXT_timer_query; +#define GL_EXT_transform_feedback 1 +GLAD_API_CALL int GLAD_GL_EXT_transform_feedback; +#define GL_EXT_vertex_array 1 +GLAD_API_CALL int GLAD_GL_EXT_vertex_array; +#define GL_EXT_vertex_array_bgra 1 +GLAD_API_CALL int GLAD_GL_EXT_vertex_array_bgra; +#define GL_EXT_vertex_attrib_64bit 1 +GLAD_API_CALL int GLAD_GL_EXT_vertex_attrib_64bit; +#define GL_EXT_vertex_shader 1 +GLAD_API_CALL int GLAD_GL_EXT_vertex_shader; +#define GL_EXT_vertex_weighting 1 +GLAD_API_CALL int GLAD_GL_EXT_vertex_weighting; +#define GL_EXT_win32_keyed_mutex 1 +GLAD_API_CALL int GLAD_GL_EXT_win32_keyed_mutex; +#define GL_EXT_window_rectangles 1 +GLAD_API_CALL int GLAD_GL_EXT_window_rectangles; +#define GL_EXT_x11_sync_object 1 +GLAD_API_CALL int GLAD_GL_EXT_x11_sync_object; +#define GL_GREMEDY_frame_terminator 1 +GLAD_API_CALL int GLAD_GL_GREMEDY_frame_terminator; +#define GL_GREMEDY_string_marker 1 +GLAD_API_CALL int GLAD_GL_GREMEDY_string_marker; +#define GL_HP_convolution_border_modes 1 +GLAD_API_CALL int GLAD_GL_HP_convolution_border_modes; +#define GL_HP_image_transform 1 +GLAD_API_CALL int GLAD_GL_HP_image_transform; +#define GL_HP_occlusion_test 1 +GLAD_API_CALL int GLAD_GL_HP_occlusion_test; +#define GL_HP_texture_lighting 1 +GLAD_API_CALL int GLAD_GL_HP_texture_lighting; +#define GL_IBM_cull_vertex 1 +GLAD_API_CALL int GLAD_GL_IBM_cull_vertex; +#define GL_IBM_multimode_draw_arrays 1 +GLAD_API_CALL int GLAD_GL_IBM_multimode_draw_arrays; +#define GL_IBM_rasterpos_clip 1 +GLAD_API_CALL int GLAD_GL_IBM_rasterpos_clip; +#define GL_IBM_static_data 1 +GLAD_API_CALL int GLAD_GL_IBM_static_data; +#define GL_IBM_texture_mirrored_repeat 1 +GLAD_API_CALL int GLAD_GL_IBM_texture_mirrored_repeat; +#define GL_IBM_vertex_array_lists 1 +GLAD_API_CALL int GLAD_GL_IBM_vertex_array_lists; +#define GL_INGR_blend_func_separate 1 +GLAD_API_CALL int GLAD_GL_INGR_blend_func_separate; +#define GL_INGR_color_clamp 1 +GLAD_API_CALL int GLAD_GL_INGR_color_clamp; +#define GL_INGR_interlace_read 1 +GLAD_API_CALL int GLAD_GL_INGR_interlace_read; +#define GL_INTEL_blackhole_render 1 +GLAD_API_CALL int GLAD_GL_INTEL_blackhole_render; +#define GL_INTEL_conservative_rasterization 1 +GLAD_API_CALL int GLAD_GL_INTEL_conservative_rasterization; +#define GL_INTEL_fragment_shader_ordering 1 +GLAD_API_CALL int GLAD_GL_INTEL_fragment_shader_ordering; +#define GL_INTEL_framebuffer_CMAA 1 +GLAD_API_CALL int GLAD_GL_INTEL_framebuffer_CMAA; +#define GL_INTEL_map_texture 1 +GLAD_API_CALL int GLAD_GL_INTEL_map_texture; +#define GL_INTEL_parallel_arrays 1 +GLAD_API_CALL int GLAD_GL_INTEL_parallel_arrays; +#define GL_INTEL_performance_query 1 +GLAD_API_CALL int GLAD_GL_INTEL_performance_query; +#define GL_KHR_blend_equation_advanced 1 +GLAD_API_CALL int GLAD_GL_KHR_blend_equation_advanced; +#define GL_KHR_blend_equation_advanced_coherent 1 +GLAD_API_CALL int GLAD_GL_KHR_blend_equation_advanced_coherent; +#define GL_KHR_context_flush_control 1 +GLAD_API_CALL int GLAD_GL_KHR_context_flush_control; +#define GL_KHR_debug 1 +GLAD_API_CALL int GLAD_GL_KHR_debug; +#define GL_KHR_no_error 1 +GLAD_API_CALL int GLAD_GL_KHR_no_error; +#define GL_KHR_parallel_shader_compile 1 +GLAD_API_CALL int GLAD_GL_KHR_parallel_shader_compile; +#define GL_KHR_robust_buffer_access_behavior 1 +GLAD_API_CALL int GLAD_GL_KHR_robust_buffer_access_behavior; +#define GL_KHR_robustness 1 +GLAD_API_CALL int GLAD_GL_KHR_robustness; +#define GL_KHR_shader_subgroup 1 +GLAD_API_CALL int GLAD_GL_KHR_shader_subgroup; +#define GL_KHR_texture_compression_astc_hdr 1 +GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_hdr; +#define GL_KHR_texture_compression_astc_ldr 1 +GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_ldr; +#define GL_KHR_texture_compression_astc_sliced_3d 1 +GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_sliced_3d; +#define GL_MESAX_texture_stack 1 +GLAD_API_CALL int GLAD_GL_MESAX_texture_stack; +#define GL_MESA_framebuffer_flip_x 1 +GLAD_API_CALL int GLAD_GL_MESA_framebuffer_flip_x; +#define GL_MESA_framebuffer_flip_y 1 +GLAD_API_CALL int GLAD_GL_MESA_framebuffer_flip_y; +#define GL_MESA_framebuffer_swap_xy 1 +GLAD_API_CALL int GLAD_GL_MESA_framebuffer_swap_xy; +#define GL_MESA_pack_invert 1 +GLAD_API_CALL int GLAD_GL_MESA_pack_invert; +#define GL_MESA_program_binary_formats 1 +GLAD_API_CALL int GLAD_GL_MESA_program_binary_formats; +#define GL_MESA_resize_buffers 1 +GLAD_API_CALL int GLAD_GL_MESA_resize_buffers; +#define GL_MESA_shader_integer_functions 1 +GLAD_API_CALL int GLAD_GL_MESA_shader_integer_functions; +#define GL_MESA_tile_raster_order 1 +GLAD_API_CALL int GLAD_GL_MESA_tile_raster_order; +#define GL_MESA_window_pos 1 +GLAD_API_CALL int GLAD_GL_MESA_window_pos; +#define GL_MESA_ycbcr_texture 1 +GLAD_API_CALL int GLAD_GL_MESA_ycbcr_texture; +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers; +#define GL_NVX_conditional_render 1 +GLAD_API_CALL int GLAD_GL_NVX_conditional_render; +#define GL_NVX_gpu_memory_info 1 +GLAD_API_CALL int GLAD_GL_NVX_gpu_memory_info; +#define GL_NVX_gpu_multicast2 1 +GLAD_API_CALL int GLAD_GL_NVX_gpu_multicast2; +#define GL_NVX_linked_gpu_multicast 1 +GLAD_API_CALL int GLAD_GL_NVX_linked_gpu_multicast; +#define GL_NVX_progress_fence 1 +GLAD_API_CALL int GLAD_GL_NVX_progress_fence; +#define GL_NV_alpha_to_coverage_dither_control 1 +GLAD_API_CALL int GLAD_GL_NV_alpha_to_coverage_dither_control; +#define GL_NV_bindless_multi_draw_indirect 1 +GLAD_API_CALL int GLAD_GL_NV_bindless_multi_draw_indirect; +#define GL_NV_bindless_multi_draw_indirect_count 1 +GLAD_API_CALL int GLAD_GL_NV_bindless_multi_draw_indirect_count; +#define GL_NV_bindless_texture 1 +GLAD_API_CALL int GLAD_GL_NV_bindless_texture; +#define GL_NV_blend_equation_advanced 1 +GLAD_API_CALL int GLAD_GL_NV_blend_equation_advanced; +#define GL_NV_blend_equation_advanced_coherent 1 +GLAD_API_CALL int GLAD_GL_NV_blend_equation_advanced_coherent; +#define GL_NV_blend_minmax_factor 1 +GLAD_API_CALL int GLAD_GL_NV_blend_minmax_factor; +#define GL_NV_blend_square 1 +GLAD_API_CALL int GLAD_GL_NV_blend_square; +#define GL_NV_clip_space_w_scaling 1 +GLAD_API_CALL int GLAD_GL_NV_clip_space_w_scaling; +#define GL_NV_command_list 1 +GLAD_API_CALL int GLAD_GL_NV_command_list; +#define GL_NV_compute_program5 1 +GLAD_API_CALL int GLAD_GL_NV_compute_program5; +#define GL_NV_compute_shader_derivatives 1 +GLAD_API_CALL int GLAD_GL_NV_compute_shader_derivatives; +#define GL_NV_conditional_render 1 +GLAD_API_CALL int GLAD_GL_NV_conditional_render; +#define GL_NV_conservative_raster 1 +GLAD_API_CALL int GLAD_GL_NV_conservative_raster; +#define GL_NV_conservative_raster_dilate 1 +GLAD_API_CALL int GLAD_GL_NV_conservative_raster_dilate; +#define GL_NV_conservative_raster_pre_snap 1 +GLAD_API_CALL int GLAD_GL_NV_conservative_raster_pre_snap; +#define GL_NV_conservative_raster_pre_snap_triangles 1 +GLAD_API_CALL int GLAD_GL_NV_conservative_raster_pre_snap_triangles; +#define GL_NV_conservative_raster_underestimation 1 +GLAD_API_CALL int GLAD_GL_NV_conservative_raster_underestimation; +#define GL_NV_copy_depth_to_color 1 +GLAD_API_CALL int GLAD_GL_NV_copy_depth_to_color; +#define GL_NV_copy_image 1 +GLAD_API_CALL int GLAD_GL_NV_copy_image; +#define GL_NV_deep_texture3D 1 +GLAD_API_CALL int GLAD_GL_NV_deep_texture3D; +#define GL_NV_depth_buffer_float 1 +GLAD_API_CALL int GLAD_GL_NV_depth_buffer_float; +#define GL_NV_depth_clamp 1 +GLAD_API_CALL int GLAD_GL_NV_depth_clamp; +#define GL_NV_draw_texture 1 +GLAD_API_CALL int GLAD_GL_NV_draw_texture; +#define GL_NV_draw_vulkan_image 1 +GLAD_API_CALL int GLAD_GL_NV_draw_vulkan_image; +#define GL_NV_evaluators 1 +GLAD_API_CALL int GLAD_GL_NV_evaluators; +#define GL_NV_explicit_multisample 1 +GLAD_API_CALL int GLAD_GL_NV_explicit_multisample; +#define GL_NV_fence 1 +GLAD_API_CALL int GLAD_GL_NV_fence; +#define GL_NV_fill_rectangle 1 +GLAD_API_CALL int GLAD_GL_NV_fill_rectangle; +#define GL_NV_float_buffer 1 +GLAD_API_CALL int GLAD_GL_NV_float_buffer; +#define GL_NV_fog_distance 1 +GLAD_API_CALL int GLAD_GL_NV_fog_distance; +#define GL_NV_fragment_coverage_to_color 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_coverage_to_color; +#define GL_NV_fragment_program 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_program; +#define GL_NV_fragment_program2 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_program2; +#define GL_NV_fragment_program4 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_program4; +#define GL_NV_fragment_program_option 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_program_option; +#define GL_NV_fragment_shader_barycentric 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_shader_barycentric; +#define GL_NV_fragment_shader_interlock 1 +GLAD_API_CALL int GLAD_GL_NV_fragment_shader_interlock; +#define GL_NV_framebuffer_mixed_samples 1 +GLAD_API_CALL int GLAD_GL_NV_framebuffer_mixed_samples; +#define GL_NV_framebuffer_multisample_coverage 1 +GLAD_API_CALL int GLAD_GL_NV_framebuffer_multisample_coverage; +#define GL_NV_geometry_program4 1 +GLAD_API_CALL int GLAD_GL_NV_geometry_program4; +#define GL_NV_geometry_shader4 1 +GLAD_API_CALL int GLAD_GL_NV_geometry_shader4; +#define GL_NV_geometry_shader_passthrough 1 +GLAD_API_CALL int GLAD_GL_NV_geometry_shader_passthrough; +#define GL_NV_gpu_multicast 1 +GLAD_API_CALL int GLAD_GL_NV_gpu_multicast; +#define GL_NV_gpu_program4 1 +GLAD_API_CALL int GLAD_GL_NV_gpu_program4; +#define GL_NV_gpu_program5 1 +GLAD_API_CALL int GLAD_GL_NV_gpu_program5; +#define GL_NV_gpu_program5_mem_extended 1 +GLAD_API_CALL int GLAD_GL_NV_gpu_program5_mem_extended; +#define GL_NV_gpu_shader5 1 +GLAD_API_CALL int GLAD_GL_NV_gpu_shader5; +#define GL_NV_half_float 1 +GLAD_API_CALL int GLAD_GL_NV_half_float; +#define GL_NV_internalformat_sample_query 1 +GLAD_API_CALL int GLAD_GL_NV_internalformat_sample_query; +#define GL_NV_light_max_exponent 1 +GLAD_API_CALL int GLAD_GL_NV_light_max_exponent; +#define GL_NV_memory_attachment 1 +GLAD_API_CALL int GLAD_GL_NV_memory_attachment; +#define GL_NV_memory_object_sparse 1 +GLAD_API_CALL int GLAD_GL_NV_memory_object_sparse; +#define GL_NV_mesh_shader 1 +GLAD_API_CALL int GLAD_GL_NV_mesh_shader; +#define GL_NV_multisample_coverage 1 +GLAD_API_CALL int GLAD_GL_NV_multisample_coverage; +#define GL_NV_multisample_filter_hint 1 +GLAD_API_CALL int GLAD_GL_NV_multisample_filter_hint; +#define GL_NV_occlusion_query 1 +GLAD_API_CALL int GLAD_GL_NV_occlusion_query; +#define GL_NV_packed_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_NV_packed_depth_stencil; +#define GL_NV_parameter_buffer_object 1 +GLAD_API_CALL int GLAD_GL_NV_parameter_buffer_object; +#define GL_NV_parameter_buffer_object2 1 +GLAD_API_CALL int GLAD_GL_NV_parameter_buffer_object2; +#define GL_NV_path_rendering 1 +GLAD_API_CALL int GLAD_GL_NV_path_rendering; +#define GL_NV_path_rendering_shared_edge 1 +GLAD_API_CALL int GLAD_GL_NV_path_rendering_shared_edge; +#define GL_NV_pixel_data_range 1 +GLAD_API_CALL int GLAD_GL_NV_pixel_data_range; +#define GL_NV_point_sprite 1 +GLAD_API_CALL int GLAD_GL_NV_point_sprite; +#define GL_NV_present_video 1 +GLAD_API_CALL int GLAD_GL_NV_present_video; +#define GL_NV_primitive_restart 1 +GLAD_API_CALL int GLAD_GL_NV_primitive_restart; +#define GL_NV_primitive_shading_rate 1 +GLAD_API_CALL int GLAD_GL_NV_primitive_shading_rate; +#define GL_NV_query_resource 1 +GLAD_API_CALL int GLAD_GL_NV_query_resource; +#define GL_NV_query_resource_tag 1 +GLAD_API_CALL int GLAD_GL_NV_query_resource_tag; +#define GL_NV_register_combiners 1 +GLAD_API_CALL int GLAD_GL_NV_register_combiners; +#define GL_NV_register_combiners2 1 +GLAD_API_CALL int GLAD_GL_NV_register_combiners2; +#define GL_NV_representative_fragment_test 1 +GLAD_API_CALL int GLAD_GL_NV_representative_fragment_test; +#define GL_NV_robustness_video_memory_purge 1 +GLAD_API_CALL int GLAD_GL_NV_robustness_video_memory_purge; +#define GL_NV_sample_locations 1 +GLAD_API_CALL int GLAD_GL_NV_sample_locations; +#define GL_NV_sample_mask_override_coverage 1 +GLAD_API_CALL int GLAD_GL_NV_sample_mask_override_coverage; +#define GL_NV_scissor_exclusive 1 +GLAD_API_CALL int GLAD_GL_NV_scissor_exclusive; +#define GL_NV_shader_atomic_counters 1 +GLAD_API_CALL int GLAD_GL_NV_shader_atomic_counters; +#define GL_NV_shader_atomic_float 1 +GLAD_API_CALL int GLAD_GL_NV_shader_atomic_float; +#define GL_NV_shader_atomic_float64 1 +GLAD_API_CALL int GLAD_GL_NV_shader_atomic_float64; +#define GL_NV_shader_atomic_fp16_vector 1 +GLAD_API_CALL int GLAD_GL_NV_shader_atomic_fp16_vector; +#define GL_NV_shader_atomic_int64 1 +GLAD_API_CALL int GLAD_GL_NV_shader_atomic_int64; +#define GL_NV_shader_buffer_load 1 +GLAD_API_CALL int GLAD_GL_NV_shader_buffer_load; +#define GL_NV_shader_buffer_store 1 +GLAD_API_CALL int GLAD_GL_NV_shader_buffer_store; +#define GL_NV_shader_storage_buffer_object 1 +GLAD_API_CALL int GLAD_GL_NV_shader_storage_buffer_object; +#define GL_NV_shader_subgroup_partitioned 1 +GLAD_API_CALL int GLAD_GL_NV_shader_subgroup_partitioned; +#define GL_NV_shader_texture_footprint 1 +GLAD_API_CALL int GLAD_GL_NV_shader_texture_footprint; +#define GL_NV_shader_thread_group 1 +GLAD_API_CALL int GLAD_GL_NV_shader_thread_group; +#define GL_NV_shader_thread_shuffle 1 +GLAD_API_CALL int GLAD_GL_NV_shader_thread_shuffle; +#define GL_NV_shading_rate_image 1 +GLAD_API_CALL int GLAD_GL_NV_shading_rate_image; +#define GL_NV_stereo_view_rendering 1 +GLAD_API_CALL int GLAD_GL_NV_stereo_view_rendering; +#define GL_NV_tessellation_program5 1 +GLAD_API_CALL int GLAD_GL_NV_tessellation_program5; +#define GL_NV_texgen_emboss 1 +GLAD_API_CALL int GLAD_GL_NV_texgen_emboss; +#define GL_NV_texgen_reflection 1 +GLAD_API_CALL int GLAD_GL_NV_texgen_reflection; +#define GL_NV_texture_barrier 1 +GLAD_API_CALL int GLAD_GL_NV_texture_barrier; +#define GL_NV_texture_compression_vtc 1 +GLAD_API_CALL int GLAD_GL_NV_texture_compression_vtc; +#define GL_NV_texture_env_combine4 1 +GLAD_API_CALL int GLAD_GL_NV_texture_env_combine4; +#define GL_NV_texture_expand_normal 1 +GLAD_API_CALL int GLAD_GL_NV_texture_expand_normal; +#define GL_NV_texture_multisample 1 +GLAD_API_CALL int GLAD_GL_NV_texture_multisample; +#define GL_NV_texture_rectangle 1 +GLAD_API_CALL int GLAD_GL_NV_texture_rectangle; +#define GL_NV_texture_rectangle_compressed 1 +GLAD_API_CALL int GLAD_GL_NV_texture_rectangle_compressed; +#define GL_NV_texture_shader 1 +GLAD_API_CALL int GLAD_GL_NV_texture_shader; +#define GL_NV_texture_shader2 1 +GLAD_API_CALL int GLAD_GL_NV_texture_shader2; +#define GL_NV_texture_shader3 1 +GLAD_API_CALL int GLAD_GL_NV_texture_shader3; +#define GL_NV_timeline_semaphore 1 +GLAD_API_CALL int GLAD_GL_NV_timeline_semaphore; +#define GL_NV_transform_feedback 1 +GLAD_API_CALL int GLAD_GL_NV_transform_feedback; +#define GL_NV_transform_feedback2 1 +GLAD_API_CALL int GLAD_GL_NV_transform_feedback2; +#define GL_NV_uniform_buffer_std430_layout 1 +GLAD_API_CALL int GLAD_GL_NV_uniform_buffer_std430_layout; +#define GL_NV_uniform_buffer_unified_memory 1 +GLAD_API_CALL int GLAD_GL_NV_uniform_buffer_unified_memory; +#define GL_NV_vdpau_interop 1 +GLAD_API_CALL int GLAD_GL_NV_vdpau_interop; +#define GL_NV_vdpau_interop2 1 +GLAD_API_CALL int GLAD_GL_NV_vdpau_interop2; +#define GL_NV_vertex_array_range 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_array_range; +#define GL_NV_vertex_array_range2 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_array_range2; +#define GL_NV_vertex_attrib_integer_64bit 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_attrib_integer_64bit; +#define GL_NV_vertex_buffer_unified_memory 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_buffer_unified_memory; +#define GL_NV_vertex_program 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program; +#define GL_NV_vertex_program1_1 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program1_1; +#define GL_NV_vertex_program2 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program2; +#define GL_NV_vertex_program2_option 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program2_option; +#define GL_NV_vertex_program3 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program3; +#define GL_NV_vertex_program4 1 +GLAD_API_CALL int GLAD_GL_NV_vertex_program4; +#define GL_NV_video_capture 1 +GLAD_API_CALL int GLAD_GL_NV_video_capture; +#define GL_NV_viewport_array2 1 +GLAD_API_CALL int GLAD_GL_NV_viewport_array2; +#define GL_NV_viewport_swizzle 1 +GLAD_API_CALL int GLAD_GL_NV_viewport_swizzle; +#define GL_OES_byte_coordinates 1 +GLAD_API_CALL int GLAD_GL_OES_byte_coordinates; +#define GL_OES_compressed_paletted_texture 1 +GLAD_API_CALL int GLAD_GL_OES_compressed_paletted_texture; +#define GL_OES_fixed_point 1 +GLAD_API_CALL int GLAD_GL_OES_fixed_point; +#define GL_OES_query_matrix 1 +GLAD_API_CALL int GLAD_GL_OES_query_matrix; +#define GL_OES_read_format 1 +GLAD_API_CALL int GLAD_GL_OES_read_format; +#define GL_OES_single_precision 1 +GLAD_API_CALL int GLAD_GL_OES_single_precision; +#define GL_OML_interlace 1 +GLAD_API_CALL int GLAD_GL_OML_interlace; +#define GL_OML_resample 1 +GLAD_API_CALL int GLAD_GL_OML_resample; +#define GL_OML_subsample 1 +GLAD_API_CALL int GLAD_GL_OML_subsample; +#define GL_OVR_multiview 1 +GLAD_API_CALL int GLAD_GL_OVR_multiview; +#define GL_OVR_multiview2 1 +GLAD_API_CALL int GLAD_GL_OVR_multiview2; +#define GL_PGI_misc_hints 1 +GLAD_API_CALL int GLAD_GL_PGI_misc_hints; +#define GL_PGI_vertex_hints 1 +GLAD_API_CALL int GLAD_GL_PGI_vertex_hints; +#define GL_REND_screen_coordinates 1 +GLAD_API_CALL int GLAD_GL_REND_screen_coordinates; +#define GL_S3_s3tc 1 +GLAD_API_CALL int GLAD_GL_S3_s3tc; +#define GL_SGIS_detail_texture 1 +GLAD_API_CALL int GLAD_GL_SGIS_detail_texture; +#define GL_SGIS_fog_function 1 +GLAD_API_CALL int GLAD_GL_SGIS_fog_function; +#define GL_SGIS_generate_mipmap 1 +GLAD_API_CALL int GLAD_GL_SGIS_generate_mipmap; +#define GL_SGIS_multisample 1 +GLAD_API_CALL int GLAD_GL_SGIS_multisample; +#define GL_SGIS_pixel_texture 1 +GLAD_API_CALL int GLAD_GL_SGIS_pixel_texture; +#define GL_SGIS_point_line_texgen 1 +GLAD_API_CALL int GLAD_GL_SGIS_point_line_texgen; +#define GL_SGIS_point_parameters 1 +GLAD_API_CALL int GLAD_GL_SGIS_point_parameters; +#define GL_SGIS_sharpen_texture 1 +GLAD_API_CALL int GLAD_GL_SGIS_sharpen_texture; +#define GL_SGIS_texture4D 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture4D; +#define GL_SGIS_texture_border_clamp 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_border_clamp; +#define GL_SGIS_texture_color_mask 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_color_mask; +#define GL_SGIS_texture_edge_clamp 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_edge_clamp; +#define GL_SGIS_texture_filter4 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_filter4; +#define GL_SGIS_texture_lod 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_lod; +#define GL_SGIS_texture_select 1 +GLAD_API_CALL int GLAD_GL_SGIS_texture_select; +#define GL_SGIX_async 1 +GLAD_API_CALL int GLAD_GL_SGIX_async; +#define GL_SGIX_async_histogram 1 +GLAD_API_CALL int GLAD_GL_SGIX_async_histogram; +#define GL_SGIX_async_pixel 1 +GLAD_API_CALL int GLAD_GL_SGIX_async_pixel; +#define GL_SGIX_blend_alpha_minmax 1 +GLAD_API_CALL int GLAD_GL_SGIX_blend_alpha_minmax; +#define GL_SGIX_calligraphic_fragment 1 +GLAD_API_CALL int GLAD_GL_SGIX_calligraphic_fragment; +#define GL_SGIX_clipmap 1 +GLAD_API_CALL int GLAD_GL_SGIX_clipmap; +#define GL_SGIX_convolution_accuracy 1 +GLAD_API_CALL int GLAD_GL_SGIX_convolution_accuracy; +#define GL_SGIX_depth_pass_instrument 1 +GLAD_API_CALL int GLAD_GL_SGIX_depth_pass_instrument; +#define GL_SGIX_depth_texture 1 +GLAD_API_CALL int GLAD_GL_SGIX_depth_texture; +#define GL_SGIX_flush_raster 1 +GLAD_API_CALL int GLAD_GL_SGIX_flush_raster; +#define GL_SGIX_fog_offset 1 +GLAD_API_CALL int GLAD_GL_SGIX_fog_offset; +#define GL_SGIX_fragment_lighting 1 +GLAD_API_CALL int GLAD_GL_SGIX_fragment_lighting; +#define GL_SGIX_framezoom 1 +GLAD_API_CALL int GLAD_GL_SGIX_framezoom; +#define GL_SGIX_igloo_interface 1 +GLAD_API_CALL int GLAD_GL_SGIX_igloo_interface; +#define GL_SGIX_instruments 1 +GLAD_API_CALL int GLAD_GL_SGIX_instruments; +#define GL_SGIX_interlace 1 +GLAD_API_CALL int GLAD_GL_SGIX_interlace; +#define GL_SGIX_ir_instrument1 1 +GLAD_API_CALL int GLAD_GL_SGIX_ir_instrument1; +#define GL_SGIX_list_priority 1 +GLAD_API_CALL int GLAD_GL_SGIX_list_priority; +#define GL_SGIX_pixel_texture 1 +GLAD_API_CALL int GLAD_GL_SGIX_pixel_texture; +#define GL_SGIX_pixel_tiles 1 +GLAD_API_CALL int GLAD_GL_SGIX_pixel_tiles; +#define GL_SGIX_polynomial_ffd 1 +GLAD_API_CALL int GLAD_GL_SGIX_polynomial_ffd; +#define GL_SGIX_reference_plane 1 +GLAD_API_CALL int GLAD_GL_SGIX_reference_plane; +#define GL_SGIX_resample 1 +GLAD_API_CALL int GLAD_GL_SGIX_resample; +#define GL_SGIX_scalebias_hint 1 +GLAD_API_CALL int GLAD_GL_SGIX_scalebias_hint; +#define GL_SGIX_shadow 1 +GLAD_API_CALL int GLAD_GL_SGIX_shadow; +#define GL_SGIX_shadow_ambient 1 +GLAD_API_CALL int GLAD_GL_SGIX_shadow_ambient; +#define GL_SGIX_sprite 1 +GLAD_API_CALL int GLAD_GL_SGIX_sprite; +#define GL_SGIX_subsample 1 +GLAD_API_CALL int GLAD_GL_SGIX_subsample; +#define GL_SGIX_tag_sample_buffer 1 +GLAD_API_CALL int GLAD_GL_SGIX_tag_sample_buffer; +#define GL_SGIX_texture_add_env 1 +GLAD_API_CALL int GLAD_GL_SGIX_texture_add_env; +#define GL_SGIX_texture_coordinate_clamp 1 +GLAD_API_CALL int GLAD_GL_SGIX_texture_coordinate_clamp; +#define GL_SGIX_texture_lod_bias 1 +GLAD_API_CALL int GLAD_GL_SGIX_texture_lod_bias; +#define GL_SGIX_texture_multi_buffer 1 +GLAD_API_CALL int GLAD_GL_SGIX_texture_multi_buffer; +#define GL_SGIX_texture_scale_bias 1 +GLAD_API_CALL int GLAD_GL_SGIX_texture_scale_bias; +#define GL_SGIX_vertex_preclip 1 +GLAD_API_CALL int GLAD_GL_SGIX_vertex_preclip; +#define GL_SGIX_ycrcb 1 +GLAD_API_CALL int GLAD_GL_SGIX_ycrcb; +#define GL_SGIX_ycrcb_subsample 1 +GLAD_API_CALL int GLAD_GL_SGIX_ycrcb_subsample; +#define GL_SGIX_ycrcba 1 +GLAD_API_CALL int GLAD_GL_SGIX_ycrcba; +#define GL_SGI_color_matrix 1 +GLAD_API_CALL int GLAD_GL_SGI_color_matrix; +#define GL_SGI_color_table 1 +GLAD_API_CALL int GLAD_GL_SGI_color_table; +#define GL_SGI_texture_color_table 1 +GLAD_API_CALL int GLAD_GL_SGI_texture_color_table; +#define GL_SUNX_constant_data 1 +GLAD_API_CALL int GLAD_GL_SUNX_constant_data; +#define GL_SUN_convolution_border_modes 1 +GLAD_API_CALL int GLAD_GL_SUN_convolution_border_modes; +#define GL_SUN_global_alpha 1 +GLAD_API_CALL int GLAD_GL_SUN_global_alpha; +#define GL_SUN_mesh_array 1 +GLAD_API_CALL int GLAD_GL_SUN_mesh_array; +#define GL_SUN_slice_accum 1 +GLAD_API_CALL int GLAD_GL_SUN_slice_accum; +#define GL_SUN_triangle_list 1 +GLAD_API_CALL int GLAD_GL_SUN_triangle_list; +#define GL_SUN_vertex 1 +GLAD_API_CALL int GLAD_GL_SUN_vertex; +#define GL_WIN_phong_shading 1 +GLAD_API_CALL int GLAD_GL_WIN_phong_shading; +#define GL_WIN_specular_fog 1 +GLAD_API_CALL int GLAD_GL_WIN_specular_fog; +#define GL_AMD_compressed_3DC_texture 1 +GLAD_API_CALL int GLAD_GL_AMD_compressed_3DC_texture; +#define GL_AMD_compressed_ATC_texture 1 +GLAD_API_CALL int GLAD_GL_AMD_compressed_ATC_texture; +#define GL_APPLE_copy_texture_levels 1 +GLAD_API_CALL int GLAD_GL_APPLE_copy_texture_levels; +#define GL_APPLE_framebuffer_multisample 1 +GLAD_API_CALL int GLAD_GL_APPLE_framebuffer_multisample; +#define GL_APPLE_sync 1 +GLAD_API_CALL int GLAD_GL_APPLE_sync; +#define GL_APPLE_texture_2D_limited_npot 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_2D_limited_npot; +#define GL_APPLE_texture_format_BGRA8888 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_format_BGRA8888; +#define GL_APPLE_texture_max_level 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_max_level; +#define GL_ARM_rgba8 1 +GLAD_API_CALL int GLAD_GL_ARM_rgba8; +#define GL_EXT_discard_framebuffer 1 +GLAD_API_CALL int GLAD_GL_EXT_discard_framebuffer; +#define GL_EXT_map_buffer_range 1 +GLAD_API_CALL int GLAD_GL_EXT_map_buffer_range; +#define GL_EXT_multisampled_render_to_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_multisampled_render_to_texture; +#define GL_EXT_read_format_bgra 1 +GLAD_API_CALL int GLAD_GL_EXT_read_format_bgra; +#define GL_EXT_robustness 1 +GLAD_API_CALL int GLAD_GL_EXT_robustness; +#define GL_EXT_sRGB 1 +GLAD_API_CALL int GLAD_GL_EXT_sRGB; +#define GL_EXT_texture_compression_dxt1 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_dxt1; +#define GL_EXT_texture_format_BGRA8888 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_format_BGRA8888; +#define GL_IMG_multisampled_render_to_texture 1 +GLAD_API_CALL int GLAD_GL_IMG_multisampled_render_to_texture; +#define GL_IMG_read_format 1 +GLAD_API_CALL int GLAD_GL_IMG_read_format; +#define GL_IMG_texture_compression_pvrtc 1 +GLAD_API_CALL int GLAD_GL_IMG_texture_compression_pvrtc; +#define GL_IMG_texture_env_enhanced_fixed_function 1 +GLAD_API_CALL int GLAD_GL_IMG_texture_env_enhanced_fixed_function; +#define GL_IMG_user_clip_plane 1 +GLAD_API_CALL int GLAD_GL_IMG_user_clip_plane; +#define GL_OES_EGL_image 1 +GLAD_API_CALL int GLAD_GL_OES_EGL_image; +#define GL_OES_EGL_image_external 1 +GLAD_API_CALL int GLAD_GL_OES_EGL_image_external; +#define GL_OES_blend_equation_separate 1 +GLAD_API_CALL int GLAD_GL_OES_blend_equation_separate; +#define GL_OES_blend_func_separate 1 +GLAD_API_CALL int GLAD_GL_OES_blend_func_separate; +#define GL_OES_blend_subtract 1 +GLAD_API_CALL int GLAD_GL_OES_blend_subtract; +#define GL_OES_compressed_ETC1_RGB8_sub_texture 1 +GLAD_API_CALL int GLAD_GL_OES_compressed_ETC1_RGB8_sub_texture; +#define GL_OES_compressed_ETC1_RGB8_texture 1 +GLAD_API_CALL int GLAD_GL_OES_compressed_ETC1_RGB8_texture; +#define GL_OES_depth24 1 +GLAD_API_CALL int GLAD_GL_OES_depth24; +#define GL_OES_depth32 1 +GLAD_API_CALL int GLAD_GL_OES_depth32; +#define GL_OES_draw_texture 1 +GLAD_API_CALL int GLAD_GL_OES_draw_texture; +#define GL_OES_element_index_uint 1 +GLAD_API_CALL int GLAD_GL_OES_element_index_uint; +#define GL_OES_extended_matrix_palette 1 +GLAD_API_CALL int GLAD_GL_OES_extended_matrix_palette; +#define GL_OES_fbo_render_mipmap 1 +GLAD_API_CALL int GLAD_GL_OES_fbo_render_mipmap; +#define GL_OES_framebuffer_object 1 +GLAD_API_CALL int GLAD_GL_OES_framebuffer_object; +#define GL_OES_mapbuffer 1 +GLAD_API_CALL int GLAD_GL_OES_mapbuffer; +#define GL_OES_matrix_get 1 +GLAD_API_CALL int GLAD_GL_OES_matrix_get; +#define GL_OES_matrix_palette 1 +GLAD_API_CALL int GLAD_GL_OES_matrix_palette; +#define GL_OES_packed_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_OES_packed_depth_stencil; +#define GL_OES_point_size_array 1 +GLAD_API_CALL int GLAD_GL_OES_point_size_array; +#define GL_OES_point_sprite 1 +GLAD_API_CALL int GLAD_GL_OES_point_sprite; +#define GL_OES_required_internalformat 1 +GLAD_API_CALL int GLAD_GL_OES_required_internalformat; +#define GL_OES_rgb8_rgba8 1 +GLAD_API_CALL int GLAD_GL_OES_rgb8_rgba8; +#define GL_OES_stencil1 1 +GLAD_API_CALL int GLAD_GL_OES_stencil1; +#define GL_OES_stencil4 1 +GLAD_API_CALL int GLAD_GL_OES_stencil4; +#define GL_OES_stencil8 1 +GLAD_API_CALL int GLAD_GL_OES_stencil8; +#define GL_OES_stencil_wrap 1 +GLAD_API_CALL int GLAD_GL_OES_stencil_wrap; +#define GL_OES_surfaceless_context 1 +GLAD_API_CALL int GLAD_GL_OES_surfaceless_context; +#define GL_OES_texture_cube_map 1 +GLAD_API_CALL int GLAD_GL_OES_texture_cube_map; +#define GL_OES_texture_env_crossbar 1 +GLAD_API_CALL int GLAD_GL_OES_texture_env_crossbar; +#define GL_OES_texture_mirrored_repeat 1 +GLAD_API_CALL int GLAD_GL_OES_texture_mirrored_repeat; +#define GL_OES_texture_npot 1 +GLAD_API_CALL int GLAD_GL_OES_texture_npot; +#define GL_OES_vertex_array_object 1 +GLAD_API_CALL int GLAD_GL_OES_vertex_array_object; +#define GL_QCOM_driver_control 1 +GLAD_API_CALL int GLAD_GL_QCOM_driver_control; +#define GL_QCOM_extended_get 1 +GLAD_API_CALL int GLAD_GL_QCOM_extended_get; +#define GL_QCOM_extended_get2 1 +GLAD_API_CALL int GLAD_GL_QCOM_extended_get2; +#define GL_QCOM_perfmon_global_mode 1 +GLAD_API_CALL int GLAD_GL_QCOM_perfmon_global_mode; +#define GL_QCOM_tiled_rendering 1 +GLAD_API_CALL int GLAD_GL_QCOM_tiled_rendering; +#define GL_QCOM_writeonly_rendering 1 +GLAD_API_CALL int GLAD_GL_QCOM_writeonly_rendering; +#define GL_AMD_program_binary_Z400 1 +GLAD_API_CALL int GLAD_GL_AMD_program_binary_Z400; +#define GL_ANDROID_extension_pack_es31a 1 +GLAD_API_CALL int GLAD_GL_ANDROID_extension_pack_es31a; +#define GL_ANGLE_depth_texture 1 +GLAD_API_CALL int GLAD_GL_ANGLE_depth_texture; +#define GL_ANGLE_framebuffer_blit 1 +GLAD_API_CALL int GLAD_GL_ANGLE_framebuffer_blit; +#define GL_ANGLE_framebuffer_multisample 1 +GLAD_API_CALL int GLAD_GL_ANGLE_framebuffer_multisample; +#define GL_ANGLE_instanced_arrays 1 +GLAD_API_CALL int GLAD_GL_ANGLE_instanced_arrays; +#define GL_ANGLE_pack_reverse_row_order 1 +GLAD_API_CALL int GLAD_GL_ANGLE_pack_reverse_row_order; +#define GL_ANGLE_program_binary 1 +GLAD_API_CALL int GLAD_GL_ANGLE_program_binary; +#define GL_ANGLE_texture_compression_dxt3 1 +GLAD_API_CALL int GLAD_GL_ANGLE_texture_compression_dxt3; +#define GL_ANGLE_texture_compression_dxt5 1 +GLAD_API_CALL int GLAD_GL_ANGLE_texture_compression_dxt5; +#define GL_ANGLE_texture_usage 1 +GLAD_API_CALL int GLAD_GL_ANGLE_texture_usage; +#define GL_ANGLE_translated_shader_source 1 +GLAD_API_CALL int GLAD_GL_ANGLE_translated_shader_source; +#define GL_APPLE_clip_distance 1 +GLAD_API_CALL int GLAD_GL_APPLE_clip_distance; +#define GL_APPLE_color_buffer_packed_float 1 +GLAD_API_CALL int GLAD_GL_APPLE_color_buffer_packed_float; +#define GL_APPLE_texture_packed_float 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_packed_float; +#define GL_ARM_mali_program_binary 1 +GLAD_API_CALL int GLAD_GL_ARM_mali_program_binary; +#define GL_ARM_mali_shader_binary 1 +GLAD_API_CALL int GLAD_GL_ARM_mali_shader_binary; +#define GL_ARM_shader_core_properties 1 +GLAD_API_CALL int GLAD_GL_ARM_shader_core_properties; +#define GL_ARM_shader_framebuffer_fetch 1 +GLAD_API_CALL int GLAD_GL_ARM_shader_framebuffer_fetch; +#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_ARM_shader_framebuffer_fetch_depth_stencil; +#define GL_ARM_texture_unnormalized_coordinates 1 +GLAD_API_CALL int GLAD_GL_ARM_texture_unnormalized_coordinates; +#define GL_DMP_program_binary 1 +GLAD_API_CALL int GLAD_GL_DMP_program_binary; +#define GL_DMP_shader_binary 1 +GLAD_API_CALL int GLAD_GL_DMP_shader_binary; +#define GL_EXT_EGL_image_array 1 +GLAD_API_CALL int GLAD_GL_EXT_EGL_image_array; +#define GL_EXT_EGL_image_storage_compression 1 +GLAD_API_CALL int GLAD_GL_EXT_EGL_image_storage_compression; +#define GL_EXT_YUV_target 1 +GLAD_API_CALL int GLAD_GL_EXT_YUV_target; +#define GL_EXT_base_instance 1 +GLAD_API_CALL int GLAD_GL_EXT_base_instance; +#define GL_EXT_blend_func_extended 1 +GLAD_API_CALL int GLAD_GL_EXT_blend_func_extended; +#define GL_EXT_buffer_storage 1 +GLAD_API_CALL int GLAD_GL_EXT_buffer_storage; +#define GL_EXT_clear_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_clear_texture; +#define GL_EXT_clip_control 1 +GLAD_API_CALL int GLAD_GL_EXT_clip_control; +#define GL_EXT_clip_cull_distance 1 +GLAD_API_CALL int GLAD_GL_EXT_clip_cull_distance; +#define GL_EXT_color_buffer_float 1 +GLAD_API_CALL int GLAD_GL_EXT_color_buffer_float; +#define GL_EXT_color_buffer_half_float 1 +GLAD_API_CALL int GLAD_GL_EXT_color_buffer_half_float; +#define GL_EXT_conservative_depth 1 +GLAD_API_CALL int GLAD_GL_EXT_conservative_depth; +#define GL_EXT_copy_image 1 +GLAD_API_CALL int GLAD_GL_EXT_copy_image; +#define GL_EXT_depth_clamp 1 +GLAD_API_CALL int GLAD_GL_EXT_depth_clamp; +#define GL_EXT_disjoint_timer_query 1 +GLAD_API_CALL int GLAD_GL_EXT_disjoint_timer_query; +#define GL_EXT_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_buffers; +#define GL_EXT_draw_buffers_indexed 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_buffers_indexed; +#define GL_EXT_draw_elements_base_vertex 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_elements_base_vertex; +#define GL_EXT_draw_transform_feedback 1 +GLAD_API_CALL int GLAD_GL_EXT_draw_transform_feedback; +#define GL_EXT_float_blend 1 +GLAD_API_CALL int GLAD_GL_EXT_float_blend; +#define GL_EXT_fragment_shading_rate 1 +GLAD_API_CALL int GLAD_GL_EXT_fragment_shading_rate; +#define GL_EXT_geometry_point_size 1 +GLAD_API_CALL int GLAD_GL_EXT_geometry_point_size; +#define GL_EXT_geometry_shader 1 +GLAD_API_CALL int GLAD_GL_EXT_geometry_shader; +#define GL_EXT_gpu_shader5 1 +GLAD_API_CALL int GLAD_GL_EXT_gpu_shader5; +#define GL_EXT_instanced_arrays 1 +GLAD_API_CALL int GLAD_GL_EXT_instanced_arrays; +#define GL_EXT_multi_draw_indirect 1 +GLAD_API_CALL int GLAD_GL_EXT_multi_draw_indirect; +#define GL_EXT_multisampled_compatibility 1 +GLAD_API_CALL int GLAD_GL_EXT_multisampled_compatibility; +#define GL_EXT_multisampled_render_to_texture2 1 +GLAD_API_CALL int GLAD_GL_EXT_multisampled_render_to_texture2; +#define GL_EXT_multiview_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_EXT_multiview_draw_buffers; +#define GL_EXT_occlusion_query_boolean 1 +GLAD_API_CALL int GLAD_GL_EXT_occlusion_query_boolean; +#define GL_EXT_primitive_bounding_box 1 +GLAD_API_CALL int GLAD_GL_EXT_primitive_bounding_box; +#define GL_EXT_protected_textures 1 +GLAD_API_CALL int GLAD_GL_EXT_protected_textures; +#define GL_EXT_pvrtc_sRGB 1 +GLAD_API_CALL int GLAD_GL_EXT_pvrtc_sRGB; +#define GL_EXT_render_snorm 1 +GLAD_API_CALL int GLAD_GL_EXT_render_snorm; +#define GL_EXT_sRGB_write_control 1 +GLAD_API_CALL int GLAD_GL_EXT_sRGB_write_control; +#define GL_EXT_separate_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_EXT_separate_depth_stencil; +#define GL_EXT_separate_shader_objects 1 +GLAD_API_CALL int GLAD_GL_EXT_separate_shader_objects; +#define GL_EXT_shader_group_vote 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_group_vote; +#define GL_EXT_shader_implicit_conversions 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_implicit_conversions; +#define GL_EXT_shader_io_blocks 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_io_blocks; +#define GL_EXT_shader_non_constant_global_initializers 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_non_constant_global_initializers; +#define GL_EXT_shader_pixel_local_storage 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_pixel_local_storage; +#define GL_EXT_shader_pixel_local_storage2 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_pixel_local_storage2; +#define GL_EXT_shader_texture_lod 1 +GLAD_API_CALL int GLAD_GL_EXT_shader_texture_lod; +#define GL_EXT_shadow_samplers 1 +GLAD_API_CALL int GLAD_GL_EXT_shadow_samplers; +#define GL_EXT_sparse_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_sparse_texture; +#define GL_EXT_tessellation_point_size 1 +GLAD_API_CALL int GLAD_GL_EXT_tessellation_point_size; +#define GL_EXT_tessellation_shader 1 +GLAD_API_CALL int GLAD_GL_EXT_tessellation_shader; +#define GL_EXT_texture_border_clamp 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_border_clamp; +#define GL_EXT_texture_buffer 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_buffer; +#define GL_EXT_texture_compression_astc_decode_mode 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_astc_decode_mode; +#define GL_EXT_texture_compression_bptc 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_bptc; +#define GL_EXT_texture_compression_s3tc_srgb 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc_srgb; +#define GL_EXT_texture_cube_map_array 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_cube_map_array; +#define GL_EXT_texture_format_sRGB_override 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_format_sRGB_override; +#define GL_EXT_texture_mirror_clamp_to_edge 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_mirror_clamp_to_edge; +#define GL_EXT_texture_norm16 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_norm16; +#define GL_EXT_texture_query_lod 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_query_lod; +#define GL_EXT_texture_rg 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_rg; +#define GL_EXT_texture_storage_compression 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_storage_compression; +#define GL_EXT_texture_type_2_10_10_10_REV 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_type_2_10_10_10_REV; +#define GL_EXT_texture_view 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_view; +#define GL_EXT_unpack_subimage 1 +GLAD_API_CALL int GLAD_GL_EXT_unpack_subimage; +#define GL_FJ_shader_binary_GCCSO 1 +GLAD_API_CALL int GLAD_GL_FJ_shader_binary_GCCSO; +#define GL_IMG_bindless_texture 1 +GLAD_API_CALL int GLAD_GL_IMG_bindless_texture; +#define GL_IMG_framebuffer_downsample 1 +GLAD_API_CALL int GLAD_GL_IMG_framebuffer_downsample; +#define GL_IMG_program_binary 1 +GLAD_API_CALL int GLAD_GL_IMG_program_binary; +#define GL_IMG_shader_binary 1 +GLAD_API_CALL int GLAD_GL_IMG_shader_binary; +#define GL_IMG_texture_compression_pvrtc2 1 +GLAD_API_CALL int GLAD_GL_IMG_texture_compression_pvrtc2; +#define GL_IMG_texture_filter_cubic 1 +GLAD_API_CALL int GLAD_GL_IMG_texture_filter_cubic; +#define GL_MESA_bgra 1 +GLAD_API_CALL int GLAD_GL_MESA_bgra; +#define GL_MESA_sampler_objects 1 +GLAD_API_CALL int GLAD_GL_MESA_sampler_objects; +#define GL_NV_copy_buffer 1 +GLAD_API_CALL int GLAD_GL_NV_copy_buffer; +#define GL_NV_coverage_sample 1 +GLAD_API_CALL int GLAD_GL_NV_coverage_sample; +#define GL_NV_depth_nonlinear 1 +GLAD_API_CALL int GLAD_GL_NV_depth_nonlinear; +#define GL_NV_draw_buffers 1 +GLAD_API_CALL int GLAD_GL_NV_draw_buffers; +#define GL_NV_draw_instanced 1 +GLAD_API_CALL int GLAD_GL_NV_draw_instanced; +#define GL_NV_explicit_attrib_location 1 +GLAD_API_CALL int GLAD_GL_NV_explicit_attrib_location; +#define GL_NV_fbo_color_attachments 1 +GLAD_API_CALL int GLAD_GL_NV_fbo_color_attachments; +#define GL_NV_framebuffer_blit 1 +GLAD_API_CALL int GLAD_GL_NV_framebuffer_blit; +#define GL_NV_framebuffer_multisample 1 +GLAD_API_CALL int GLAD_GL_NV_framebuffer_multisample; +#define GL_NV_generate_mipmap_sRGB 1 +GLAD_API_CALL int GLAD_GL_NV_generate_mipmap_sRGB; +#define GL_NV_image_formats 1 +GLAD_API_CALL int GLAD_GL_NV_image_formats; +#define GL_NV_instanced_arrays 1 +GLAD_API_CALL int GLAD_GL_NV_instanced_arrays; +#define GL_NV_non_square_matrices 1 +GLAD_API_CALL int GLAD_GL_NV_non_square_matrices; +#define GL_NV_pack_subimage 1 +GLAD_API_CALL int GLAD_GL_NV_pack_subimage; +#define GL_NV_pixel_buffer_object 1 +GLAD_API_CALL int GLAD_GL_NV_pixel_buffer_object; +#define GL_NV_polygon_mode 1 +GLAD_API_CALL int GLAD_GL_NV_polygon_mode; +#define GL_NV_read_buffer 1 +GLAD_API_CALL int GLAD_GL_NV_read_buffer; +#define GL_NV_read_buffer_front 1 +GLAD_API_CALL int GLAD_GL_NV_read_buffer_front; +#define GL_NV_read_depth 1 +GLAD_API_CALL int GLAD_GL_NV_read_depth; +#define GL_NV_read_depth_stencil 1 +GLAD_API_CALL int GLAD_GL_NV_read_depth_stencil; +#define GL_NV_read_stencil 1 +GLAD_API_CALL int GLAD_GL_NV_read_stencil; +#define GL_NV_sRGB_formats 1 +GLAD_API_CALL int GLAD_GL_NV_sRGB_formats; +#define GL_NV_shader_noperspective_interpolation 1 +GLAD_API_CALL int GLAD_GL_NV_shader_noperspective_interpolation; +#define GL_NV_shadow_samplers_array 1 +GLAD_API_CALL int GLAD_GL_NV_shadow_samplers_array; +#define GL_NV_shadow_samplers_cube 1 +GLAD_API_CALL int GLAD_GL_NV_shadow_samplers_cube; +#define GL_NV_texture_border_clamp 1 +GLAD_API_CALL int GLAD_GL_NV_texture_border_clamp; +#define GL_NV_texture_compression_s3tc_update 1 +GLAD_API_CALL int GLAD_GL_NV_texture_compression_s3tc_update; +#define GL_NV_texture_npot_2D_mipmap 1 +GLAD_API_CALL int GLAD_GL_NV_texture_npot_2D_mipmap; +#define GL_NV_viewport_array 1 +GLAD_API_CALL int GLAD_GL_NV_viewport_array; +#define GL_OES_EGL_image_external_essl3 1 +GLAD_API_CALL int GLAD_GL_OES_EGL_image_external_essl3; +#define GL_OES_copy_image 1 +GLAD_API_CALL int GLAD_GL_OES_copy_image; +#define GL_OES_depth_texture 1 +GLAD_API_CALL int GLAD_GL_OES_depth_texture; +#define GL_OES_draw_buffers_indexed 1 +GLAD_API_CALL int GLAD_GL_OES_draw_buffers_indexed; +#define GL_OES_draw_elements_base_vertex 1 +GLAD_API_CALL int GLAD_GL_OES_draw_elements_base_vertex; +#define GL_OES_fragment_precision_high 1 +GLAD_API_CALL int GLAD_GL_OES_fragment_precision_high; +#define GL_OES_geometry_point_size 1 +GLAD_API_CALL int GLAD_GL_OES_geometry_point_size; +#define GL_OES_geometry_shader 1 +GLAD_API_CALL int GLAD_GL_OES_geometry_shader; +#define GL_OES_get_program_binary 1 +GLAD_API_CALL int GLAD_GL_OES_get_program_binary; +#define GL_OES_gpu_shader5 1 +GLAD_API_CALL int GLAD_GL_OES_gpu_shader5; +#define GL_OES_primitive_bounding_box 1 +GLAD_API_CALL int GLAD_GL_OES_primitive_bounding_box; +#define GL_OES_sample_shading 1 +GLAD_API_CALL int GLAD_GL_OES_sample_shading; +#define GL_OES_sample_variables 1 +GLAD_API_CALL int GLAD_GL_OES_sample_variables; +#define GL_OES_shader_image_atomic 1 +GLAD_API_CALL int GLAD_GL_OES_shader_image_atomic; +#define GL_OES_shader_io_blocks 1 +GLAD_API_CALL int GLAD_GL_OES_shader_io_blocks; +#define GL_OES_shader_multisample_interpolation 1 +GLAD_API_CALL int GLAD_GL_OES_shader_multisample_interpolation; +#define GL_OES_standard_derivatives 1 +GLAD_API_CALL int GLAD_GL_OES_standard_derivatives; +#define GL_OES_tessellation_point_size 1 +GLAD_API_CALL int GLAD_GL_OES_tessellation_point_size; +#define GL_OES_tessellation_shader 1 +GLAD_API_CALL int GLAD_GL_OES_tessellation_shader; +#define GL_OES_texture_3D 1 +GLAD_API_CALL int GLAD_GL_OES_texture_3D; +#define GL_OES_texture_border_clamp 1 +GLAD_API_CALL int GLAD_GL_OES_texture_border_clamp; +#define GL_OES_texture_buffer 1 +GLAD_API_CALL int GLAD_GL_OES_texture_buffer; +#define GL_OES_texture_compression_astc 1 +GLAD_API_CALL int GLAD_GL_OES_texture_compression_astc; +#define GL_OES_texture_cube_map_array 1 +GLAD_API_CALL int GLAD_GL_OES_texture_cube_map_array; +#define GL_OES_texture_float 1 +GLAD_API_CALL int GLAD_GL_OES_texture_float; +#define GL_OES_texture_float_linear 1 +GLAD_API_CALL int GLAD_GL_OES_texture_float_linear; +#define GL_OES_texture_half_float 1 +GLAD_API_CALL int GLAD_GL_OES_texture_half_float; +#define GL_OES_texture_half_float_linear 1 +GLAD_API_CALL int GLAD_GL_OES_texture_half_float_linear; +#define GL_OES_texture_stencil8 1 +GLAD_API_CALL int GLAD_GL_OES_texture_stencil8; +#define GL_OES_texture_storage_multisample_2d_array 1 +GLAD_API_CALL int GLAD_GL_OES_texture_storage_multisample_2d_array; +#define GL_OES_texture_view 1 +GLAD_API_CALL int GLAD_GL_OES_texture_view; +#define GL_OES_vertex_half_float 1 +GLAD_API_CALL int GLAD_GL_OES_vertex_half_float; +#define GL_OES_vertex_type_10_10_10_2 1 +GLAD_API_CALL int GLAD_GL_OES_vertex_type_10_10_10_2; +#define GL_OES_viewport_array 1 +GLAD_API_CALL int GLAD_GL_OES_viewport_array; +#define GL_OVR_multiview_multisampled_render_to_texture 1 +GLAD_API_CALL int GLAD_GL_OVR_multiview_multisampled_render_to_texture; +#define GL_QCOM_YUV_texture_gather 1 +GLAD_API_CALL int GLAD_GL_QCOM_YUV_texture_gather; +#define GL_QCOM_alpha_test 1 +GLAD_API_CALL int GLAD_GL_QCOM_alpha_test; +#define GL_QCOM_binning_control 1 +GLAD_API_CALL int GLAD_GL_QCOM_binning_control; +#define GL_QCOM_frame_extrapolation 1 +GLAD_API_CALL int GLAD_GL_QCOM_frame_extrapolation; +#define GL_QCOM_framebuffer_foveated 1 +GLAD_API_CALL int GLAD_GL_QCOM_framebuffer_foveated; +#define GL_QCOM_motion_estimation 1 +GLAD_API_CALL int GLAD_GL_QCOM_motion_estimation; +#define GL_QCOM_render_sRGB_R8_RG8 1 +GLAD_API_CALL int GLAD_GL_QCOM_render_sRGB_R8_RG8; +#define GL_QCOM_render_shared_exponent 1 +GLAD_API_CALL int GLAD_GL_QCOM_render_shared_exponent; +#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 +GLAD_API_CALL int GLAD_GL_QCOM_shader_framebuffer_fetch_noncoherent; +#define GL_QCOM_shader_framebuffer_fetch_rate 1 +GLAD_API_CALL int GLAD_GL_QCOM_shader_framebuffer_fetch_rate; +#define GL_QCOM_shading_rate 1 +GLAD_API_CALL int GLAD_GL_QCOM_shading_rate; +#define GL_QCOM_texture_foveated 1 +GLAD_API_CALL int GLAD_GL_QCOM_texture_foveated; +#define GL_QCOM_texture_foveated2 1 +GLAD_API_CALL int GLAD_GL_QCOM_texture_foveated2; +#define GL_QCOM_texture_foveated_subsampled_layout 1 +GLAD_API_CALL int GLAD_GL_QCOM_texture_foveated_subsampled_layout; +#define GL_QCOM_texture_lod_bias 1 +GLAD_API_CALL int GLAD_GL_QCOM_texture_lod_bias; +#define GL_QCOM_ycbcr_degamma 1 +GLAD_API_CALL int GLAD_GL_QCOM_ycbcr_degamma; +#define GL_VIV_shader_binary 1 +GLAD_API_CALL int GLAD_GL_VIV_shader_binary; + + +typedef void (GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); +typedef void (GLAD_API_PTR *PFNGLACCUMXOESPROC)(GLenum op, GLfixed value); +typedef GLboolean (GLAD_API_PTR *PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC)(GLuint memory, GLuint64 key, GLuint timeout); +typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); +typedef void (GLAD_API_PTR *PFNGLACTIVESTENCILFACEEXTPROC)(GLenum face); +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREARBPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLACTIVEVARYINGNVPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLALPHAFRAGMENTOP1ATIPROC)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAD_API_PTR *PFNGLALPHAFRAGMENTOP2ATIPROC)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAD_API_PTR *PFNGLALPHAFRAGMENTOP3ATIPROC)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAD_API_PTR *PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); +typedef void (GLAD_API_PTR *PFNGLALPHAFUNCXOESPROC)(GLenum func, GLfixed ref); +typedef void (GLAD_API_PTR *PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC)(void); +typedef void (GLAD_API_PTR *PFNGLAPPLYTEXTUREEXTPROC)(GLenum mode); +typedef GLboolean (GLAD_API_PTR *PFNGLAREPROGRAMSRESIDENTNVPROC)(GLsizei n, const GLuint * programs, GLboolean * residences); +typedef GLboolean (GLAD_API_PTR *PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint * textures, GLboolean * residences); +typedef GLboolean (GLAD_API_PTR *PFNGLARETEXTURESRESIDENTEXTPROC)(GLsizei n, const GLuint * textures, GLboolean * residences); +typedef void (GLAD_API_PTR *PFNGLARRAYELEMENTPROC)(GLint i); +typedef void (GLAD_API_PTR *PFNGLARRAYELEMENTEXTPROC)(GLint i); +typedef void (GLAD_API_PTR *PFNGLARRAYOBJECTATIPROC)(GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef GLuint (GLAD_API_PTR *PFNGLASYNCCOPYBUFFERSUBDATANVXPROC)(GLsizei waitSemaphoreCount, const GLuint * waitSemaphoreArray, const GLuint64 * fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint * signalSemaphoreArray, const GLuint64 * signalValueArray); +typedef GLuint (GLAD_API_PTR *PFNGLASYNCCOPYIMAGESUBDATANVXPROC)(GLsizei waitSemaphoreCount, const GLuint * waitSemaphoreArray, const GLuint64 * waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint * signalSemaphoreArray, const GLuint64 * signalValueArray); +typedef void (GLAD_API_PTR *PFNGLASYNCMARKERSGIXPROC)(GLuint marker); +typedef void (GLAD_API_PTR *PFNGLATTACHOBJECTARBPROC)(GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBEGINPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERNVPROC)(GLuint id, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERNVXPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINFRAGMENTSHADERATIPROC)(void); +typedef void (GLAD_API_PTR *PFNGLBEGINOCCLUSIONQUERYNVPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINPERFMONITORAMDPROC)(GLuint monitor); +typedef void (GLAD_API_PTR *PFNGLBEGINPERFQUERYINTELPROC)(GLuint queryHandle); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYARBPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKNVPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBEGINVERTEXSHADEREXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLBEGINVIDEOCAPTURENVPROC)(GLuint video_capture_slot); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONARBPROC)(GLhandleARB programObj, GLuint index, const GLcharARB * name); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERARBPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEEXTPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASENVPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFEROFFSETEXTPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFEROFFSETNVPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEEXTPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGENVPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONEXTPROC)(GLuint program, GLuint color, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGMENTSHADERATIPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREEXTPROC)(GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); +typedef GLuint (GLAD_API_PTR *PFNGLBINDLIGHTPARAMETEREXTPROC)(GLenum light, GLenum value); +typedef GLuint (GLAD_API_PTR *PFNGLBINDMATERIALPARAMETEREXTPROC)(GLenum face, GLenum value); +typedef void (GLAD_API_PTR *PFNGLBINDMULTITEXTUREEXTPROC)(GLenum texunit, GLenum target, GLuint texture); +typedef GLuint (GLAD_API_PTR *PFNGLBINDPARAMETEREXTPROC)(GLenum value); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMARBPROC)(GLenum target, GLuint program); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMNVPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLBINDSHADINGRATEIMAGENVPROC)(GLuint texture); +typedef GLuint (GLAD_API_PTR *PFNGLBINDTEXGENPARAMETEREXTPROC)(GLenum unit, GLenum coord, GLenum value); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREEXTPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture); +typedef GLuint (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)(GLenum unit, GLenum value); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKNVPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYAPPLEPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXSHADEREXTPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (GLAD_API_PTR *PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC)(GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3BEXTPROC)(GLbyte bx, GLbyte by, GLbyte bz); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3BVEXTPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3DEXTPROC)(GLdouble bx, GLdouble by, GLdouble bz); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3DVEXTPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3FEXTPROC)(GLfloat bx, GLfloat by, GLfloat bz); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3FVEXTPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3IEXTPROC)(GLint bx, GLint by, GLint bz); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3IVEXTPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3SEXTPROC)(GLshort bx, GLshort by, GLshort bz); +typedef void (GLAD_API_PTR *PFNGLBINORMAL3SVEXTPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLBINORMALPOINTEREXTPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); +typedef void (GLAD_API_PTR *PFNGLBITMAPXOESPROC)(GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte * bitmap); +typedef void (GLAD_API_PTR *PFNGLBLENDBARRIERKHRPROC)(void); +typedef void (GLAD_API_PTR *PFNGLBLENDBARRIERNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLOREXTPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORXOESPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONINDEXEDAMDPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEEXTPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIARBPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIARBPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCINDEXEDAMDPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEEXTPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEINGRPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIARBPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIARBPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLENDPARAMETERINVPROC)(GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFEREXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERLAYEREXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERLAYERSEXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBUFFERADDRESSRANGENVPROC)(GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLBUFFERATTACHMEMORYNVPROC)(GLenum target, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAARBPROC)(GLenum target, GLsizeiptrARB size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERPAGECOMMITMENTARBPROC)(GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLBUFFERPAGECOMMITMENTMEMNVPROC)(GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLBUFFERPARAMETERIAPPLEPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEEXTERNALEXTPROC)(GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEMEMEXTPROC)(GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAARBPROC)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void * data); +typedef void (GLAD_API_PTR *PFNGLCALLCOMMANDLISTNVPROC)(GLuint list); +typedef void (GLAD_API_PTR *PFNGLCALLLISTPROC)(GLuint list); +typedef void (GLAD_API_PTR *PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void * lists); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(GLenum target); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)(GLuint framebuffer, GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORARBPROC)(GLenum target, GLenum clamp); +typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARACCUMXOESPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORIIEXTPROC)(GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORIUIEXTPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORXOESPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHDNVPROC)(GLdouble depth); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFOESPROC)(GLclampf depth); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHXOESPROC)(GLfixed depth); +typedef void (GLAD_API_PTR *PFNGLCLEARINDEXPROC)(GLfloat c); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAEXTPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC)(GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREARBPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)(GLenum stream); +typedef void (GLAD_API_PTR *PFNGLCLIENTATTRIBDEFAULTEXTPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC)(GLsizei fenceObjectCount, const GLuint * semaphoreArray, const GLuint64 * fenceValueArray); +typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble * equation); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEFOESPROC)(GLenum plane, const GLfloat * equation); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEXOESPROC)(GLenum plane, const GLfixed * equation); +typedef void (GLAD_API_PTR *PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FVERTEX3FSUNPROC)(GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FVERTEX3FVSUNPROC)(const GLfloat * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3HNVPROC)(GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR3XOESPROC)(GLfixed red, GLfixed green, GLfixed blue); +typedef void (GLAD_API_PTR *PFNGLCOLOR3XVOESPROC)(const GLfixed * components); +typedef void (GLAD_API_PTR *PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)(GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)(const GLfloat * c, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4HNVPROC)(GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVERTEX2FSUNPROC)(GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVERTEX2FVSUNPROC)(const GLubyte * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVERTEX3FSUNPROC)(GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVERTEX3FVSUNPROC)(const GLubyte * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLCOLOR4XOESPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLCOLOR4XVOESPROC)(const GLfixed * components); +typedef void (GLAD_API_PTR *PFNGLCOLORFORMATNVPROC)(GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLCOLORFRAGMENTOP1ATIPROC)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAD_API_PTR *PFNGLCOLORFRAGMENTOP2ATIPROC)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAD_API_PTR *PFNGLCOLORFRAGMENTOP3ATIPROC)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKINDEXEDEXTPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLCOLORPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERLISTIBMPROC)(GLint size, GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERVINTELPROC)(GLint size, GLenum type, const void ** pointer); +typedef void (GLAD_API_PTR *PFNGLCOLORSUBTABLEPROC)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOLORSUBTABLEEXTPROC)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * table); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEEXTPROC)(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void * table); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEPARAMETERFVSGIPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLEPARAMETERIVSGIPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLCOLORTABLESGIPROC)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * table); +typedef void (GLAD_API_PTR *PFNGLCOMBINERINPUTNVPROC)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAD_API_PTR *PFNGLCOMBINEROUTPUTNVPROC)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAD_API_PTR *PFNGLCOMBINERPARAMETERFNVPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLCOMBINERPARAMETERFVNVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCOMBINERPARAMETERINVPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLCOMBINERPARAMETERIVNVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)(GLenum stage, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCOMMANDLISTSEGMENTSNVPROC)(GLuint list, GLuint segments); +typedef void (GLAD_API_PTR *PFNGLCOMPILECOMMANDLISTNVPROC)(GLuint list); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERARBPROC)(GLhandleARB shaderObj); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERINCLUDEARBPROC)(GLuint shader, GLsizei count, const GLchar *const* path, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAD_API_PTR *PFNGLCONSERVATIVERASTERPARAMETERFNVPROC)(GLenum pname, GLfloat value); +typedef void (GLAD_API_PTR *PFNGLCONSERVATIVERASTERPARAMETERINVPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONFILTER1DPROC)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * image); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONFILTER1DEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * image); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONFILTER2DPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * image); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONFILTER2DEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * image); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERFEXTPROC)(GLenum target, GLenum pname, GLfloat params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERFVEXTPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERIPROC)(GLenum target, GLenum pname, GLint params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERIEXTPROC)(GLenum target, GLenum pname, GLint params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERIVEXTPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERXOESPROC)(GLenum target, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLCONVOLUTIONPARAMETERXVOESPROC)(GLenum target, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYCOLORSUBTABLEPROC)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCOLORSUBTABLEEXTPROC)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCOLORTABLEPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCOLORTABLESGIPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCONVOLUTIONFILTER1DPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYCONVOLUTIONFILTER2DPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATANVPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLCOPYMULTITEXIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYMULTITEXIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYPATHNVPROC)(GLuint resultPath, GLuint srcPath); +typedef void (GLAD_API_PTR *PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DEXTPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DEXTPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTUREIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTUREIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOVERFILLPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLCOVERFILLPATHNVPROC)(GLuint path, GLenum coverMode); +typedef void (GLAD_API_PTR *PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLCOVERSTROKEPATHNVPROC)(GLuint path, GLenum coverMode); +typedef void (GLAD_API_PTR *PFNGLCOVERAGEMODULATIONNVPROC)(GLenum components); +typedef void (GLAD_API_PTR *PFNGLCOVERAGEMODULATIONTABLENVPROC)(GLsizei n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLCREATECOMMANDLISTSNVPROC)(GLsizei n, GLuint * lists); +typedef void (GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLCREATEMEMORYOBJECTSEXTPROC)(GLsizei n, GLuint * memoryObjects); +typedef void (GLAD_API_PTR *PFNGLCREATEPERFQUERYINTELPROC)(GLuint queryId, GLuint * queryHandle); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef GLhandleARB (GLAD_API_PTR *PFNGLCREATEPROGRAMOBJECTARBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRESSFENCENVXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLCREATESEMAPHORESNVPROC)(GLsizei n, GLuint * semaphores); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef GLhandleARB (GLAD_API_PTR *PFNGLCREATESHADEROBJECTARBPROC)(GLenum shaderType); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings); +typedef void (GLAD_API_PTR *PFNGLCREATESTATESNVPROC)(GLsizei n, GLuint * states); +typedef GLsync (GLAD_API_PTR *PFNGLCREATESYNCFROMCLEVENTARBPROC)(struct _cl_context * context, struct _cl_event * event, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLCULLPARAMETERDVEXTPROC)(GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLCULLPARAMETERFVEXTPROC)(GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLCURRENTPALETTEMATRIXARBPROC)(GLint index); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKAMDPROC)(GLDEBUGPROCAMD callback, void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKARBPROC)(GLDEBUGPROCARB callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLARBPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEENABLEAMDPROC)(GLenum category, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTAMDPROC)(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTARBPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDEFORMSGIXPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLDEFORMATIONMAP3DSGIXPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLDEFORMATIONMAP3FSGIXPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLDELETEASYNCMARKERSSGIXPROC)(GLuint marker, GLsizei range); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSARBPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETECOMMANDLISTSNVPROC)(GLsizei n, const GLuint * lists); +typedef void (GLAD_API_PTR *PFNGLDELETEFENCESAPPLEPROC)(GLsizei n, const GLuint * fences); +typedef void (GLAD_API_PTR *PFNGLDELETEFENCESNVPROC)(GLsizei n, const GLuint * fences); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAGMENTSHADERATIPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); +typedef void (GLAD_API_PTR *PFNGLDELETEMEMORYOBJECTSEXTPROC)(GLsizei n, const GLuint * memoryObjects); +typedef void (GLAD_API_PTR *PFNGLDELETENAMEDSTRINGARBPROC)(GLint namelen, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLDELETENAMESAMDPROC)(GLenum identifier, GLuint num, const GLuint * names); +typedef void (GLAD_API_PTR *PFNGLDELETEOBJECTARBPROC)(GLhandleARB obj); +typedef void (GLAD_API_PTR *PFNGLDELETEOCCLUSIONQUERIESNVPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEPATHSNVPROC)(GLuint path, GLsizei range); +typedef void (GLAD_API_PTR *PFNGLDELETEPERFMONITORSAMDPROC)(GLsizei n, GLuint * monitors); +typedef void (GLAD_API_PTR *PFNGLDELETEPERFQUERYINTELPROC)(GLuint queryHandle); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMSARBPROC)(GLsizei n, const GLuint * programs); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMSNVPROC)(GLsizei n, const GLuint * programs); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESARBPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERYRESOURCETAGNVPROC)(GLsizei n, const GLint * tagIds); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLDELETESEMAPHORESEXTPROC)(GLsizei n, const GLuint * semaphores); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETESTATESNVPROC)(GLsizei n, const GLuint * states); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESEXTPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSNVPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSAPPLEPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXSHADEREXTPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLDEPTHBOUNDSEXTPROC)(GLclampd zmin, GLclampd zmax); +typedef void (GLAD_API_PTR *PFNGLDEPTHBOUNDSDNVPROC)(GLdouble zmin, GLdouble zmax); +typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYDVNVPROC)(GLuint first, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDDNVPROC)(GLuint index, GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEDNVPROC)(GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFOESPROC)(GLclampf n, GLclampf f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEXOESPROC)(GLfixed n, GLfixed f); +typedef void (GLAD_API_PTR *PFNGLDETACHOBJECTARBPROC)(GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDETAILTEXFUNCSGISPROC)(GLenum target, GLsizei n, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEPROC)(GLenum array); +typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)(GLenum array, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEIEXTPROC)(GLenum array, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYEXTPROC)(GLuint vaobj, GLenum array); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBAPPLEPROC)(GLuint index, GLenum pname); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSEXTPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDARBPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDEXTPROC)(GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSARBPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSATIPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWCOMMANDSADDRESSNVPROC)(GLenum primitiveMode, const GLuint64 * indirects, const GLsizei * sizes, GLuint count); +typedef void (GLAD_API_PTR *PFNGLDRAWCOMMANDSNVPROC)(GLenum primitiveMode, GLuint buffer, const GLintptr * indirects, const GLsizei * sizes, GLuint count); +typedef void (GLAD_API_PTR *PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC)(const GLuint64 * indirects, const GLsizei * sizes, const GLuint * states, const GLuint * fbos, GLuint count); +typedef void (GLAD_API_PTR *PFNGLDRAWCOMMANDSSTATESNVPROC)(GLuint buffer, const GLintptr * indirects, const GLsizei * sizes, const GLuint * states, const GLuint * fbos, GLuint count); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTARRAYAPPLEPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTARRAYATIPROC)(GLenum mode, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDARBPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWMESHARRAYSSUNPROC)(GLenum mode, GLint first, GLsizei count, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLDRAWMESHTASKSINDIRECTNVPROC)(GLintptr indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWMESHTASKSNVPROC)(GLuint first, GLuint count); +typedef void (GLAD_API_PTR *PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTARRAYATIPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSEXTPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXTURENVPROC)(GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKNVPROC)(GLenum mode, GLuint id); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWVKIMAGENVPROC)(GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef void (GLAD_API_PTR *PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC)(GLenum target, GLeglImageOES image, const GLint * attrib_list); +typedef void (GLAD_API_PTR *PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC)(GLuint texture, GLeglImageOES image, const GLint * attrib_list); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGFORMATNVPROC)(GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTEREXTPROC)(GLsizei stride, GLsizei count, const GLboolean * pointer); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTERLISTIBMPROC)(GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLEDGEFLAGVPROC)(const GLboolean * flag); +typedef void (GLAD_API_PTR *PFNGLELEMENTPOINTERAPPLEPROC)(GLenum type, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLELEMENTPOINTERATIPROC)(GLenum type, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEPROC)(GLenum array); +typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)(GLenum array, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEIEXTPROC)(GLenum array, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYEXTPROC)(GLuint vaobj, GLenum array); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBAPPLEPROC)(GLuint index, GLenum pname); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYARBPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERNVXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDFRAGMENTSHADERATIPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDLISTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDOCCLUSIONQUERYNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDPERFMONITORAMDPROC)(GLuint monitor); +typedef void (GLAD_API_PTR *PFNGLENDPERFQUERYINTELPROC)(GLuint queryHandle); +typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDQUERYARBPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKEXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDVERTEXSHADEREXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDVIDEOCAPTURENVPROC)(GLuint video_capture_slot); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DPROC)(GLdouble u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DVPROC)(const GLdouble * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FPROC)(GLfloat u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FVPROC)(const GLfloat * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1XOESPROC)(GLfixed u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD1XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DVPROC)(const GLdouble * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FVPROC)(const GLfloat * u); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2XOESPROC)(GLfixed u, GLfixed v); +typedef void (GLAD_API_PTR *PFNGLEVALCOORD2XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLEVALMAPSNVPROC)(GLenum target, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); +typedef void (GLAD_API_PTR *PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +typedef void (GLAD_API_PTR *PFNGLEVALPOINT1PROC)(GLint i); +typedef void (GLAD_API_PTR *PFNGLEVALPOINT2PROC)(GLint i, GLint j); +typedef void (GLAD_API_PTR *PFNGLEVALUATEDEPTHVALUESARBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLEXECUTEPROGRAMNVPROC)(GLenum target, GLuint id, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLEXTRACTCOMPONENTEXTPROC)(GLuint res, GLuint src, GLuint num); +typedef void (GLAD_API_PTR *PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat * buffer); +typedef void (GLAD_API_PTR *PFNGLFEEDBACKBUFFERXOESPROC)(GLsizei n, GLenum type, const GLfixed * buffer); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFINALCOMBINERINPUTNVPROC)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef GLint (GLAD_API_PTR *PFNGLFINISHASYNCSGIXPROC)(GLuint * markerp); +typedef void (GLAD_API_PTR *PFNGLFINISHFENCEAPPLEPROC)(GLuint fence); +typedef void (GLAD_API_PTR *PFNGLFINISHFENCENVPROC)(GLuint fence); +typedef void (GLAD_API_PTR *PFNGLFINISHOBJECTAPPLEPROC)(GLenum object, GLint name); +typedef void (GLAD_API_PTR *PFNGLFINISHTEXTURESUNXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)(GLenum target, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFLUSHPIXELDATARANGENVPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLFLUSHRASTERSGIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHSTATICDATAIBMPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)(GLsizei length, void * pointer); +typedef void (GLAD_API_PTR *PFNGLFLUSHVERTEXARRAYRANGENVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFORMATNVPROC)(GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTEREXTPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTERLISTIBMPROC)(GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDPROC)(GLdouble coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDEXTPROC)(GLdouble coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDVPROC)(const GLdouble * coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDDVEXTPROC)(const GLdouble * coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFPROC)(GLfloat coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFEXTPROC)(GLfloat coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFVPROC)(const GLfloat * coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDFVEXTPROC)(const GLfloat * coord); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDHNVPROC)(GLhalfNV fog); +typedef void (GLAD_API_PTR *PFNGLFOGCOORDHVNVPROC)(const GLhalfNV * fog); +typedef void (GLAD_API_PTR *PFNGLFOGFUNCSGISPROC)(GLsizei n, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLFOGFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLFOGFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLFOGIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFOGIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLFOGXOESPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLFOGXVOESPROC)(GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTCOLORMATERIALSGIXPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTCOVERAGECOLORNVPROC)(GLuint color); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTMODELFSGIXPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTMODELISGIXPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTFSGIXPROC)(GLenum light, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTFVSGIXPROC)(GLenum light, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTISGIXPROC)(GLenum light, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTLIGHTIVSGIXPROC)(GLenum light, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTMATERIALFSGIXPROC)(GLenum face, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTMATERIALFVSGIXPROC)(GLenum face, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTMATERIALISGIXPROC)(GLenum face, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAGMENTMATERIALIVSGIXPROC)(GLenum face, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLFRAMETERMINATORGREMEDYPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFRAMEZOOMSGIXPROC)(GLint factor); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)(GLuint framebuffer, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIMESAPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERREADBUFFEREXTPROC)(GLuint framebuffer, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)(GLenum target, GLuint start, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)(GLenum target, GLuint start, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)(GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREARBPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREEXTPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (GLAD_API_PTR *PFNGLFREEOBJECTBUFFERATIPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMFOESPROC)(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMXOESPROC)(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef GLuint (GLAD_API_PTR *PFNGLGENASYNCMARKERSSGIXPROC)(GLsizei range); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSARBPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENFENCESAPPLEPROC)(GLsizei n, GLuint * fences); +typedef void (GLAD_API_PTR *PFNGLGENFENCESNVPROC)(GLsizei n, GLuint * fences); +typedef GLuint (GLAD_API_PTR *PFNGLGENFRAGMENTSHADERSATIPROC)(GLuint range); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint * framebuffers); +typedef GLuint (GLAD_API_PTR *PFNGLGENLISTSPROC)(GLsizei range); +typedef void (GLAD_API_PTR *PFNGLGENNAMESAMDPROC)(GLenum identifier, GLuint num, GLuint * names); +typedef void (GLAD_API_PTR *PFNGLGENOCCLUSIONQUERIESNVPROC)(GLsizei n, GLuint * ids); +typedef GLuint (GLAD_API_PTR *PFNGLGENPATHSNVPROC)(GLsizei range); +typedef void (GLAD_API_PTR *PFNGLGENPERFMONITORSAMDPROC)(GLsizei n, GLuint * monitors); +typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLGENPROGRAMSARBPROC)(GLsizei n, GLuint * programs); +typedef void (GLAD_API_PTR *PFNGLGENPROGRAMSNVPROC)(GLsizei n, GLuint * programs); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESARBPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENQUERYRESOURCETAGNVPROC)(GLsizei n, GLint * tagIds); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLGENSEMAPHORESEXTPROC)(GLsizei n, GLuint * semaphores); +typedef GLuint (GLAD_API_PTR *PFNGLGENSYMBOLSEXTPROC)(GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESEXTPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSNVPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSAPPLEPROC)(GLsizei n, GLuint * arrays); +typedef GLuint (GLAD_API_PTR *PFNGLGENVERTEXSHADERSEXTPROC)(GLuint range); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGENERATEMULTITEXMIPMAPEXTPROC)(GLenum texunit, GLenum target); +typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture); +typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPEXTPROC)(GLuint texture, GLenum target); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBARBPROC)(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMARBPROC)(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEVARYINGNVPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETARRAYOBJECTFVATIPROC)(GLenum array, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETARRAYOBJECTIVATIPROC)(GLenum array, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDOBJECTSARBPROC)(GLhandleARB containerObj, GLsizei maxCount, GLsizei * count, GLhandleARB * obj); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONARBPROC)(GLhandleARB programObj, const GLcharARB * name); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANINDEXEDVEXTPROC)(GLenum target, GLuint index, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVARBPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERUI64VNVPROC)(GLenum target, GLenum pname, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVARBPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAARBPROC)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble * equation); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEFOESPROC)(GLenum plane, GLfloat * equation); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEXOESPROC)(GLenum plane, GLfixed * equation); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPROC)(GLenum target, GLenum format, GLenum type, void * table); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEEXTPROC)(GLenum target, GLenum format, GLenum type, void * data); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCOLORTABLESGIPROC)(GLenum target, GLenum format, GLenum type, void * table); +typedef void (GLAD_API_PTR *PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)(GLenum stage, GLenum portion, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)(GLenum stage, GLenum pname, GLfloat * params); +typedef GLuint (GLAD_API_PTR *PFNGLGETCOMMANDHEADERNVPROC)(GLenum tokenID, GLuint size); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)(GLenum texunit, GLenum target, GLint lod, void * img); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)(GLenum target, GLint level, void * img); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)(GLuint texture, GLenum target, GLint lod, void * img); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONFILTERPROC)(GLenum target, GLenum format, GLenum type, void * image); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONFILTEREXTPROC)(GLenum target, GLenum format, GLenum type, void * image); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETCONVOLUTIONPARAMETERXVOESPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETCOVERAGEMODULATIONTABLENVPROC)(GLsizei bufSize, GLfloat * v); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGAMDPROC)(GLuint count, GLsizei bufSize, GLenum * categories, GLenum * severities, GLuint * ids, GLsizei * lengths, GLchar * message); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef void (GLAD_API_PTR *PFNGLGETDETAILTEXFUNCSGISPROC)(GLenum target, GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEINDEXEDVEXTPROC)(GLenum target, GLuint index, GLdouble * data); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble * data); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VEXTPROC)(GLenum pname, GLuint index, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFENCEIVNVPROC)(GLuint fence, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)(GLenum variable, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)(GLenum variable, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFIRSTPERFQUERYIDINTELPROC)(GLuint * queryId); +typedef void (GLAD_API_PTR *PFNGLGETFIXEDVOESPROC)(GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETFLOATINDEXEDVEXTPROC)(GLenum target, GLuint index, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VEXTPROC)(GLenum pname, GLuint index, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFOGFUNCSGISPROC)(GLfloat * points); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONEXTPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAGMENTLIGHTFVSGIXPROC)(GLenum light, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAGMENTLIGHTIVSGIXPROC)(GLenum light, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAGMENTMATERIALFVSGIXPROC)(GLenum face, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAGMENTMATERIALIVSGIXPROC)(GLenum face, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC)(GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)(GLuint framebuffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC)(GLenum target, GLenum pname, GLint * params); +typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void); +typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSARBPROC)(void); +typedef GLhandleARB (GLAD_API_PTR *PFNGLGETHANDLEARBPROC)(GLenum pname); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMEXTPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETHISTOGRAMPARAMETERXVOESPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETIMAGEHANDLEARBPROC)(GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETIMAGEHANDLENVPROC)(GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (GLAD_API_PTR *PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINFOLOGARBPROC)(GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog); +typedef GLint (GLAD_API_PTR *PFNGLGETINSTRUMENTSSGIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERINDEXEDVEXTPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERUI64I_VNVPROC)(GLenum value, GLuint index, GLuint64EXT * result); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERUI64VNVPROC)(GLenum value, GLuint64EXT * result); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATSAMPLEIVNVPROC)(GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINVARIANTBOOLEANVEXTPROC)(GLuint id, GLenum value, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETINVARIANTFLOATVEXTPROC)(GLuint id, GLenum value, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETINVARIANTINTEGERVEXTPROC)(GLuint id, GLenum value, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTXOESPROC)(GLenum light, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETLISTPARAMETERFVSGIXPROC)(GLuint list, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETLISTPARAMETERIVSGIXPROC)(GLuint list, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)(GLuint id, GLenum value, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETLOCALCONSTANTFLOATVEXTPROC)(GLuint id, GLenum value, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)(GLuint id, GLenum value, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETMAPATTRIBPARAMETERFVNVPROC)(GLenum target, GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMAPATTRIBPARAMETERIVNVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMAPCONTROLPOINTSNVPROC)(GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void * points); +typedef void (GLAD_API_PTR *PFNGLGETMAPPARAMETERFVNVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMAPPARAMETERIVNVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint * v); +typedef void (GLAD_API_PTR *PFNGLGETMAPXVOESPROC)(GLenum target, GLenum query, GLfixed * v); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALXOESPROC)(GLenum face, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC)(GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC)(GLuint memoryObject, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXEXTPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXPARAMETERFVEXTPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMINMAXPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXENVFVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXENVIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXGENDVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXGENFVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXGENIVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXIMAGEEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXPARAMETERIIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXPARAMETERFVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTITEXPARAMETERIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVNVPROC)(GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)(GLuint buffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)(GLuint buffer, GLenum pname, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)(GLuint buffer, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC)(GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC)(GLuint framebuffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)(GLuint program, GLenum target, GLuint index, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)(GLuint program, GLenum target, GLuint index, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)(GLuint program, GLenum target, GLuint index, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)(GLuint program, GLenum target, GLuint index, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)(GLuint program, GLenum target, GLenum pname, void * string); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDPROGRAMIVEXTPROC)(GLuint program, GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)(GLuint renderbuffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDSTRINGARBPROC)(GLint namelen, const GLchar * name, GLsizei bufSize, GLint * stringlen, GLchar * string); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDSTRINGIVARBPROC)(GLint namelen, const GLchar * name, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNEXTPERFQUERYIDINTELPROC)(GLuint queryId, GLuint * nextQueryId); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTBUFFERFVATIPROC)(GLuint buffer, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTBUFFERIVATIPROC)(GLuint buffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELEXTPROC)(GLenum type, GLuint object, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPARAMETERFVARBPROC)(GLhandleARB obj, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPARAMETERIVAPPLEPROC)(GLenum objectType, GLuint name, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPARAMETERIVARBPROC)(GLhandleARB obj, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOCCLUSIONQUERYIVNVPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETOCCLUSIONQUERYUIVNVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETPATHCOLORGENFVNVPROC)(GLenum color, GLenum pname, GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLGETPATHCOLORGENIVNVPROC)(GLenum color, GLenum pname, GLint * value); +typedef void (GLAD_API_PTR *PFNGLGETPATHCOMMANDSNVPROC)(GLuint path, GLubyte * commands); +typedef void (GLAD_API_PTR *PFNGLGETPATHCOORDSNVPROC)(GLuint path, GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLGETPATHDASHARRAYNVPROC)(GLuint path, GLfloat * dashArray); +typedef GLfloat (GLAD_API_PTR *PFNGLGETPATHLENGTHNVPROC)(GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef void (GLAD_API_PTR *PFNGLGETPATHMETRICRANGENVPROC)(GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat * metrics); +typedef void (GLAD_API_PTR *PFNGLGETPATHMETRICSNVPROC)(GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLsizei stride, GLfloat * metrics); +typedef void (GLAD_API_PTR *PFNGLGETPATHPARAMETERFVNVPROC)(GLuint path, GLenum pname, GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLGETPATHPARAMETERIVNVPROC)(GLuint path, GLenum pname, GLint * value); +typedef void (GLAD_API_PTR *PFNGLGETPATHSPACINGNVPROC)(GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat * returnedSpacing); +typedef void (GLAD_API_PTR *PFNGLGETPATHTEXGENFVNVPROC)(GLenum texCoordSet, GLenum pname, GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLGETPATHTEXGENIVNVPROC)(GLenum texCoordSet, GLenum pname, GLint * value); +typedef void (GLAD_API_PTR *PFNGLGETPERFCOUNTERINFOINTELPROC)(GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar * counterName, GLuint counterDescLength, GLchar * counterDesc, GLuint * counterOffset, GLuint * counterDataSize, GLuint * counterTypeEnum, GLuint * counterDataTypeEnum, GLuint64 * rawCounterMaxValue); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint * data, GLint * bytesWritten); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)(GLuint group, GLuint counter, GLenum pname, void * data); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei * length, GLchar * counterString); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORCOUNTERSAMDPROC)(GLuint group, GLint * numCounters, GLint * maxActiveCounters, GLsizei counterSize, GLuint * counters); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)(GLuint group, GLsizei bufSize, GLsizei * length, GLchar * groupString); +typedef void (GLAD_API_PTR *PFNGLGETPERFMONITORGROUPSAMDPROC)(GLint * numGroups, GLsizei groupsSize, GLuint * groups); +typedef void (GLAD_API_PTR *PFNGLGETPERFQUERYDATAINTELPROC)(GLuint queryHandle, GLuint flags, GLsizei dataSize, void * data, GLuint * bytesWritten); +typedef void (GLAD_API_PTR *PFNGLGETPERFQUERYIDBYNAMEINTELPROC)(GLchar * queryName, GLuint * queryId); +typedef void (GLAD_API_PTR *PFNGLGETPERFQUERYINFOINTELPROC)(GLuint queryId, GLuint queryNameLength, GLchar * queryName, GLuint * dataSize, GLuint * noCounters, GLuint * noInstances, GLuint * capsMask); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPXVPROC)(GLenum map, GLint size, GLfixed * values); +typedef void (GLAD_API_PTR *PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC)(GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC)(GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERINDEXEDVEXTPROC)(GLenum target, GLuint index, void ** data); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERI_VEXTPROC)(GLenum pname, GLuint index, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVEXTPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte * mask); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMENVPARAMETERIIVNVPROC)(GLenum target, GLuint index, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC)(GLenum target, GLuint index, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMENVPARAMETERDVARBPROC)(GLenum target, GLuint index, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMENVPARAMETERFVARBPROC)(GLenum target, GLuint index, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC)(GLenum target, GLuint index, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC)(GLenum target, GLuint index, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)(GLenum target, GLuint index, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)(GLenum target, GLuint index, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPARAMETERDVNVPROC)(GLenum target, GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPARAMETERFVNVPROC)(GLenum target, GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params); +typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEFVNVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTRINGARBPROC)(GLenum target, GLenum pname, void * string); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTRINGNVPROC)(GLuint id, GLenum pname, GLubyte * program); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC)(GLenum target, GLuint index, GLuint * param); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVARBPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVNVPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VEXTPROC)(GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVARBPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VEXTPROC)(GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVARBPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVARBPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSEMAPHOREPARAMETERIVNVPROC)(GLuint semaphore, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC)(GLuint semaphore, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETSEPARABLEFILTERPROC)(GLenum target, GLenum format, GLenum type, void * row, void * column, void * span); +typedef void (GLAD_API_PTR *PFNGLGETSEPARABLEFILTEREXTPROC)(GLenum target, GLenum format, GLenum type, void * row, void * column, void * span); +typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEARBPROC)(GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSHADINGRATEIMAGEPALETTENVPROC)(GLuint viewport, GLuint entry, GLenum * rate); +typedef void (GLAD_API_PTR *PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC)(GLenum rate, GLuint samples, GLuint index, GLint * location); +typedef void (GLAD_API_PTR *PFNGLGETSHARPENTEXFUNCSGISPROC)(GLenum target, GLfloat * points); +typedef GLushort (GLAD_API_PTR *PFNGLGETSTAGEINDEXNVPROC)(GLenum shadertype); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef GLuint (GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXBUMPPARAMETERFVATIPROC)(GLenum pname, GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLGETTEXBUMPPARAMETERIVATIPROC)(GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVXVOESPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXFILTERFUNCSGISPROC)(GLenum target, GLenum filter, GLfloat * weights); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENXVOESPROC)(GLenum coord, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERXVOESPROC)(GLenum target, GLint level, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVEXTPROC)(GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERXVOESPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTUREHANDLEARBPROC)(GLuint texture); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTUREHANDLENVPROC)(GLuint texture); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLint * params); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTURESAMPLERHANDLEARBPROC)(GLuint texture, GLuint sampler); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTURESAMPLERHANDLENVPROC)(GLuint texture, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTRACKMATRIXIVNVPROC)(GLenum target, GLuint address, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)(GLuint program, GLuint index, GLint * location); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint * param); +typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMBUFFERSIZEEXTPROC)(GLuint program, GLint location); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONARBPROC)(GLhandleARB programObj, const GLcharARB * name); +typedef GLintptr (GLAD_API_PTR *PFNGLGETUNIFORMOFFSETEXTPROC)(GLuint program, GLint location); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVARBPROC)(GLhandleARB programObj, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMI64VARBPROC)(GLuint program, GLint location, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMI64VNVPROC)(GLuint program, GLint location, GLint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVARBPROC)(GLhandleARB programObj, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUI64VARBPROC)(GLuint program, GLint location, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUI64VNVPROC)(GLuint program, GLint location, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVEXTPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNSIGNEDBYTEI_VEXTPROC)(GLenum target, GLuint index, GLubyte * data); +typedef void (GLAD_API_PTR *PFNGLGETUNSIGNEDBYTEVEXTPROC)(GLenum pname, GLubyte * data); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTARRAYOBJECTFVATIPROC)(GLuint id, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTARRAYOBJECTIVATIPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTBOOLEANVEXTPROC)(GLuint id, GLenum value, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTFLOATVEXTPROC)(GLuint id, GLenum value, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTINTEGERVEXTPROC)(GLuint id, GLenum value, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETVARIANTPOINTERVEXTPROC)(GLuint id, GLenum value, void ** data); +typedef GLint (GLAD_API_PTR *PFNGLGETVARYINGLOCATIONNVPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINTEGERVEXTPROC)(GLuint vaobj, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)(GLuint vaobj, GLuint index, GLenum pname, void ** param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYPOINTERVEXTPROC)(GLuint vaobj, GLenum pname, void ** param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVEXTPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVEXTPROC)(GLuint index, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVEXTPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLI64VNVPROC)(GLuint index, GLenum pname, GLint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLUI64VARBPROC)(GLuint index, GLenum pname, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLUI64VNVPROC)(GLuint index, GLenum pname, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVARBPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVNVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVARBPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVNVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVARBPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVNVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVARBPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVNVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOCAPTURESTREAMDVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOCAPTURESTREAMFVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOCAPTURESTREAMIVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOCAPTUREIVNVPROC)(GLuint video_capture_slot, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOI64VNVPROC)(GLuint video_slot, GLenum pname, GLint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOIVNVPROC)(GLuint video_slot, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOUI64VNVPROC)(GLuint video_slot, GLenum pname, GLuint64EXT * params); +typedef void (GLAD_API_PTR *PFNGLGETVIDEOUIVNVPROC)(GLuint video_slot, GLenum pname, GLuint * params); +typedef GLVULKANPROCNV (GLAD_API_PTR *PFNGLGETVKPROCADDRNVPROC)(const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETNCOLORTABLEPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * table); +typedef void (GLAD_API_PTR *PFNGLGETNCOLORTABLEARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * table); +typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)(GLenum target, GLint lod, GLsizei bufSize, void * img); +typedef void (GLAD_API_PTR *PFNGLGETNCONVOLUTIONFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * image); +typedef void (GLAD_API_PTR *PFNGLGETNCONVOLUTIONFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * image); +typedef void (GLAD_API_PTR *PFNGLGETNHISTOGRAMPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); +typedef void (GLAD_API_PTR *PFNGLGETNHISTOGRAMARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); +typedef void (GLAD_API_PTR *PFNGLGETNMAPDVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLGETNMAPDVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLGETNMAPFVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLGETNMAPFVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLGETNMAPIVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint * v); +typedef void (GLAD_API_PTR *PFNGLGETNMAPIVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint * v); +typedef void (GLAD_API_PTR *PFNGLGETNMINMAXPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); +typedef void (GLAD_API_PTR *PFNGLGETNMINMAXARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPFVPROC)(GLenum map, GLsizei bufSize, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPFVARBPROC)(GLenum map, GLsizei bufSize, GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUIVPROC)(GLenum map, GLsizei bufSize, GLuint * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUIVARBPROC)(GLenum map, GLsizei bufSize, GLuint * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUSVPROC)(GLenum map, GLsizei bufSize, GLushort * values); +typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUSVARBPROC)(GLenum map, GLsizei bufSize, GLushort * values); +typedef void (GLAD_API_PTR *PFNGLGETNPOLYGONSTIPPLEPROC)(GLsizei bufSize, GLubyte * pattern); +typedef void (GLAD_API_PTR *PFNGLGETNPOLYGONSTIPPLEARBPROC)(GLsizei bufSize, GLubyte * pattern); +typedef void (GLAD_API_PTR *PFNGLGETNSEPARABLEFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void * row, GLsizei columnBufSize, void * column, void * span); +typedef void (GLAD_API_PTR *PFNGLGETNSEPARABLEFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void * row, GLsizei columnBufSize, void * column, void * span); +typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEARBPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * img); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMI64VARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUI64VARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORBSUNPROC)(GLbyte factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORDSUNPROC)(GLdouble factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORFSUNPROC)(GLfloat factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORISUNPROC)(GLint factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORSSUNPROC)(GLshort factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORUBSUNPROC)(GLubyte factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORUISUNPROC)(GLuint factor); +typedef void (GLAD_API_PTR *PFNGLGLOBALALPHAFACTORUSSUNPROC)(GLushort factor); +typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLHINTPGIPROC)(GLenum target, GLint mode); +typedef void (GLAD_API_PTR *PFNGLHISTOGRAMPROC)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAD_API_PTR *PFNGLHISTOGRAMEXTPROC)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAD_API_PTR *PFNGLIGLOOINTERFACESGIXPROC)(GLenum pname, const void * params); +typedef void (GLAD_API_PTR *PFNGLIMAGETRANSFORMPARAMETERFHPPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLIMAGETRANSFORMPARAMETERIHPPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLIMPORTMEMORYFDEXTPROC)(GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +typedef void (GLAD_API_PTR *PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC)(GLuint memory, GLuint64 size, GLenum handleType, void * handle); +typedef void (GLAD_API_PTR *PFNGLIMPORTMEMORYWIN32NAMEEXTPROC)(GLuint memory, GLuint64 size, GLenum handleType, const void * name); +typedef void (GLAD_API_PTR *PFNGLIMPORTSEMAPHOREFDEXTPROC)(GLuint semaphore, GLenum handleType, GLint fd); +typedef void (GLAD_API_PTR *PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC)(GLuint semaphore, GLenum handleType, void * handle); +typedef void (GLAD_API_PTR *PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC)(GLuint semaphore, GLenum handleType, const void * name); +typedef GLsync (GLAD_API_PTR *PFNGLIMPORTSYNCEXTPROC)(GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLINDEXFORMATNVPROC)(GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLINDEXFUNCEXTPROC)(GLenum func, GLclampf ref); +typedef void (GLAD_API_PTR *PFNGLINDEXMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLINDEXMATERIALEXTPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLINDEXPOINTEREXTPROC)(GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLINDEXPOINTERLISTIBMPROC)(GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLINDEXDPROC)(GLdouble c); +typedef void (GLAD_API_PTR *PFNGLINDEXDVPROC)(const GLdouble * c); +typedef void (GLAD_API_PTR *PFNGLINDEXFPROC)(GLfloat c); +typedef void (GLAD_API_PTR *PFNGLINDEXFVPROC)(const GLfloat * c); +typedef void (GLAD_API_PTR *PFNGLINDEXIPROC)(GLint c); +typedef void (GLAD_API_PTR *PFNGLINDEXIVPROC)(const GLint * c); +typedef void (GLAD_API_PTR *PFNGLINDEXSPROC)(GLshort c); +typedef void (GLAD_API_PTR *PFNGLINDEXSVPROC)(const GLshort * c); +typedef void (GLAD_API_PTR *PFNGLINDEXUBPROC)(GLubyte c); +typedef void (GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte * c); +typedef void (GLAD_API_PTR *PFNGLINDEXXOESPROC)(GLfixed component); +typedef void (GLAD_API_PTR *PFNGLINDEXXVOESPROC)(const GLfixed * component); +typedef void (GLAD_API_PTR *PFNGLINITNAMESPROC)(void); +typedef void (GLAD_API_PTR *PFNGLINSERTCOMPONENTEXTPROC)(GLuint res, GLuint src, GLuint num); +typedef void (GLAD_API_PTR *PFNGLINSERTEVENTMARKEREXTPROC)(GLsizei length, const GLchar * marker); +typedef void (GLAD_API_PTR *PFNGLINSTRUMENTSBUFFERSGIXPROC)(GLsizei size, GLint * buffer); +typedef void (GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLINTERPOLATEPATHSNVPROC)(GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef GLboolean (GLAD_API_PTR *PFNGLISASYNCMARKERSGIXPROC)(GLuint marker); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERARBPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERRESIDENTNVPROC)(GLenum target); +typedef GLboolean (GLAD_API_PTR *PFNGLISCOMMANDLISTNVPROC)(GLuint list); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISFENCEAPPLEPROC)(GLuint fence); +typedef GLboolean (GLAD_API_PTR *PFNGLISFENCENVPROC)(GLuint fence); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFEREXTPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISIMAGEHANDLERESIDENTARBPROC)(GLuint64 handle); +typedef GLboolean (GLAD_API_PTR *PFNGLISIMAGEHANDLERESIDENTNVPROC)(GLuint64 handle); +typedef GLboolean (GLAD_API_PTR *PFNGLISLISTPROC)(GLuint list); +typedef GLboolean (GLAD_API_PTR *PFNGLISMEMORYOBJECTEXTPROC)(GLuint memoryObject); +typedef GLboolean (GLAD_API_PTR *PFNGLISNAMEAMDPROC)(GLenum identifier, GLuint name); +typedef GLboolean (GLAD_API_PTR *PFNGLISNAMEDBUFFERRESIDENTNVPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISNAMEDSTRINGARBPROC)(GLint namelen, const GLchar * name); +typedef GLboolean (GLAD_API_PTR *PFNGLISOBJECTBUFFERATIPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISOCCLUSIONQUERYNVPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISPATHNVPROC)(GLuint path); +typedef GLboolean (GLAD_API_PTR *PFNGLISPOINTINFILLPATHNVPROC)(GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (GLAD_API_PTR *PFNGLISPOINTINSTROKEPATHNVPROC)(GLuint path, GLfloat x, GLfloat y); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMARBPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMNVPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYARBPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFEREXTPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); +typedef GLboolean (GLAD_API_PTR *PFNGLISSEMAPHOREEXTPROC)(GLuint semaphore); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISSTATENVPROC)(GLuint state); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREEXTPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREHANDLERESIDENTARBPROC)(GLuint64 handle); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREHANDLERESIDENTNVPROC)(GLuint64 handle); +typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKNVPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISVARIANTENABLEDEXTPROC)(GLuint id, GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYAPPLEPROC)(GLuint array); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)(GLuint index, GLenum pname); +typedef void (GLAD_API_PTR *PFNGLLGPUCOPYIMAGESUBDATANVXPROC)(GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLLGPUINTERLOCKNVXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC)(GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLLABELOBJECTEXTPROC)(GLenum type, GLuint object, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLLIGHTENVISGIXPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELXOESPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELXVOESPROC)(GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLLIGHTXOESPROC)(GLenum light, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLLIGHTXVOESPROC)(GLenum light, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHXOESPROC)(GLfixed width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMARBPROC)(GLhandleARB programObj); +typedef void (GLAD_API_PTR *PFNGLLISTBASEPROC)(GLuint base); +typedef void (GLAD_API_PTR *PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC)(GLuint list, GLuint segment, const void ** indirects, const GLsizei * sizes, const GLuint * states, const GLuint * fbos, GLuint count); +typedef void (GLAD_API_PTR *PFNGLLISTPARAMETERFSGIXPROC)(GLuint list, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLLISTPARAMETERFVSGIXPROC)(GLuint list, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLLISTPARAMETERISGIXPROC)(GLuint list, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLLISTPARAMETERIVSGIXPROC)(GLuint list, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLLOADIDENTITYPROC)(void); +typedef void (GLAD_API_PTR *PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXXOESPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLLOADNAMEPROC)(GLuint name); +typedef void (GLAD_API_PTR *PFNGLLOADPROGRAMNVPROC)(GLenum target, GLuint id, GLsizei len, const GLubyte * program); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDARBPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFARBPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXXOESPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLLOCKARRAYSEXTPROC)(GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); +typedef void (GLAD_API_PTR *PFNGLMAKEBUFFERNONRESIDENTNVPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLMAKEBUFFERRESIDENTNVPROC)(GLenum target, GLenum access); +typedef void (GLAD_API_PTR *PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAKEIMAGEHANDLERESIDENTARBPROC)(GLuint64 handle, GLenum access); +typedef void (GLAD_API_PTR *PFNGLMAKEIMAGEHANDLERESIDENTNVPROC)(GLuint64 handle, GLenum access); +typedef void (GLAD_API_PTR *PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)(GLuint buffer, GLenum access); +typedef void (GLAD_API_PTR *PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAKETEXTUREHANDLERESIDENTARBPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAKETEXTUREHANDLERESIDENTNVPROC)(GLuint64 handle); +typedef void (GLAD_API_PTR *PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLMAP1XOESPROC)(GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +typedef void (GLAD_API_PTR *PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLMAP2XOESPROC)(GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERARBPROC)(GLenum target, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLMAPCONTROLPOINTSNVPROC)(GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void * points); +typedef void (GLAD_API_PTR *PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID1XOESPROC)(GLint n, GLfixed u1, GLfixed u2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLMAPGRID2XOESPROC)(GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFEREXTPROC)(GLuint buffer, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void * (GLAD_API_PTR *PFNGLMAPOBJECTBUFFERATIPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLMAPPARAMETERFVNVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMAPPARAMETERIVNVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void * (GLAD_API_PTR *PFNGLMAPTEXTURE2DINTELPROC)(GLuint texture, GLint level, GLbitfield access, GLint * stride, GLenum * layout); +typedef void (GLAD_API_PTR *PFNGLMAPVERTEXATTRIB1DAPPLEPROC)(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAPVERTEXATTRIB1FAPPLEPROC)(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLMAPVERTEXATTRIB2DAPPLEPROC)(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); +typedef void (GLAD_API_PTR *PFNGLMAPVERTEXATTRIB2FAPPLEPROC)(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMATERIALXOESPROC)(GLenum face, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLMATERIALXVOESPROC)(GLenum face, GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLMATRIXFRUSTUMEXTPROC)(GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLMATRIXINDEXPOINTERARBPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLMATRIXINDEXUBVARBPROC)(GLint size, const GLubyte * indices); +typedef void (GLAD_API_PTR *PFNGLMATRIXINDEXUIVARBPROC)(GLint size, const GLuint * indices); +typedef void (GLAD_API_PTR *PFNGLMATRIXINDEXUSVARBPROC)(GLint size, const GLushort * indices); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOAD3X2FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOAD3X3FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADTRANSPOSEDEXTPROC)(GLenum mode, const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADTRANSPOSEFEXTPROC)(GLenum mode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADDEXTPROC)(GLenum mode, const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXLOADFEXTPROC)(GLenum mode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMODEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULT3X2FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULT3X3FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC)(GLenum matrixMode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULTTRANSPOSEDEXTPROC)(GLenum mode, const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULTTRANSPOSEFEXTPROC)(GLenum mode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULTDEXTPROC)(GLenum mode, const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXMULTFEXTPROC)(GLenum mode, const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMATRIXORTHOEXTPROC)(GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLMATRIXPOPEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLMATRIXPUSHEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLMATRIXROTATEDEXTPROC)(GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLMATRIXROTATEFEXTPROC)(GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLMATRIXSCALEDEXTPROC)(GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLMATRIXSCALEFEXTPROC)(GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLMATRIXTRANSLATEDEXTPROC)(GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLMATRIXTRANSLATEFEXTPROC)(GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLMAXSHADERCOMPILERTHREADSARBPROC)(GLuint count); +typedef void (GLAD_API_PTR *PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)(GLuint count); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIEREXTPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMEMORYOBJECTPARAMETERIVEXTPROC)(GLuint memoryObject, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value); +typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGARBPROC)(GLfloat value); +typedef void (GLAD_API_PTR *PFNGLMINMAXPROC)(GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAD_API_PTR *PFNGLMINMAXEXTPROC)(GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXXOESPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDARBPROC)(const GLdouble * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFARBPROC)(const GLfloat * m); +typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXXOESPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSEXTPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)(GLenum mode, const void * indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC)(GLenum mode, const void * indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC)(GLenum mode, const void * indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)(GLenum mode, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)(GLenum mode, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSEXTPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)(GLenum mode, GLenum type, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)(GLenum mode, GLenum type, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC)(GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC)(GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)(GLenum mode, GLuint start, GLuint end, const GLint * first, const GLsizei * count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLMULTIMODEDRAWARRAYSIBMPROC)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); +typedef void (GLAD_API_PTR *PFNGLMULTIMODEDRAWELEMENTSIBMPROC)(const GLenum * mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei primcount, GLint modestride); +typedef void (GLAD_API_PTR *PFNGLMULTITEXBUFFEREXTPROC)(GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1BOESPROC)(GLenum texture, GLbyte s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1BVOESPROC)(GLenum texture, const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DARBPROC)(GLenum target, GLdouble s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DVARBPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FARBPROC)(GLenum target, GLfloat s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FVARBPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1HNVPROC)(GLenum target, GLhalfNV s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1HVNVPROC)(GLenum target, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IARBPROC)(GLenum target, GLint s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IVARBPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SARBPROC)(GLenum target, GLshort s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SVARBPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1XOESPROC)(GLenum texture, GLfixed s); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1XVOESPROC)(GLenum texture, const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2BOESPROC)(GLenum texture, GLbyte s, GLbyte t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2BVOESPROC)(GLenum texture, const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DARBPROC)(GLenum target, GLdouble s, GLdouble t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DVARBPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FARBPROC)(GLenum target, GLfloat s, GLfloat t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FVARBPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2HNVPROC)(GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2HVNVPROC)(GLenum target, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IARBPROC)(GLenum target, GLint s, GLint t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IVARBPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SARBPROC)(GLenum target, GLshort s, GLshort t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SVARBPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2XOESPROC)(GLenum texture, GLfixed s, GLfixed t); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2XVOESPROC)(GLenum texture, const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3BOESPROC)(GLenum texture, GLbyte s, GLbyte t, GLbyte r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3BVOESPROC)(GLenum texture, const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DARBPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DVARBPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FARBPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FVARBPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3HNVPROC)(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3HVNVPROC)(GLenum target, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IARBPROC)(GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IVARBPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SARBPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SVARBPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3XOESPROC)(GLenum texture, GLfixed s, GLfixed t, GLfixed r); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3XVOESPROC)(GLenum texture, const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4BOESPROC)(GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4BVOESPROC)(GLenum texture, const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DARBPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DVARBPROC)(GLenum target, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FARBPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FVARBPROC)(GLenum target, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4HNVPROC)(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4HVNVPROC)(GLenum target, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IARBPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IVARBPROC)(GLenum target, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SARBPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SVARBPROC)(GLenum target, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4XOESPROC)(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4XVOESPROC)(GLenum texture, const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDPOINTEREXTPROC)(GLenum texunit, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLMULTITEXENVFEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXENVFVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXENVIEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXENVIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENDEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENDVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENFEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENFVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENIEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXGENIVEXTPROC)(GLenum texunit, GLenum coord, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTITEXIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTITEXIMAGE3DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERIIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERIUIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERFEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERFVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERIEXTPROC)(GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLMULTITEXPARAMETERIVEXTPROC)(GLenum texunit, GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLMULTITEXRENDERBUFFEREXTPROC)(GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLMULTITEXSUBIMAGE1DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTITEXSUBIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTITEXSUBIMAGE3DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLMULTICASTBARRIERNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLMULTICASTBLITFRAMEBUFFERNVPROC)(GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLMULTICASTBUFFERSUBDATANVPROC)(GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC)(GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLMULTICASTCOPYIMAGESUBDATANVPROC)(GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAD_API_PTR *PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)(GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC)(GLuint gpu, GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLMULTICASTGETQUERYOBJECTIVNVPROC)(GLuint gpu, GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC)(GLuint gpu, GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC)(GLuint gpu, GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLMULTICASTSCISSORARRAYVNVXPROC)(GLuint gpu, GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLMULTICASTVIEWPORTARRAYVNVXPROC)(GLuint gpu, GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC)(GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); +typedef void (GLAD_API_PTR *PFNGLMULTICASTWAITSYNCNVPROC)(GLuint signalGpu, GLbitfield waitGpuMask); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERATTACHMEMORYNVPROC)(GLuint buffer, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAEXTPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEEXTPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC)(GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC)(GLuint framebuffer, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)(GLuint framebuffer, GLuint start, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)(GLuint framebuffer, GLuint start, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)(GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)(GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)(GLuint program, GLenum target, GLuint index, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)(GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)(GLuint program, GLenum target, GLuint index, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)(GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)(GLuint program, GLenum target, GLuint index, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)(GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)(GLuint program, GLenum target, GLuint index, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)(GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)(GLuint program, GLenum target, GLuint index, GLsizei count, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)(GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLNAMEDPROGRAMSTRINGEXTPROC)(GLuint program, GLenum target, GLenum format, GLsizei len, const void * string); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)(GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDSTRINGARBPROC)(GLenum type, GLint namelen, const GLchar * name, GLint stringlen, const GLchar * string); +typedef void (GLAD_API_PTR *PFNGLNEWLISTPROC)(GLuint list, GLenum mode); +typedef GLuint (GLAD_API_PTR *PFNGLNEWOBJECTBUFFERATIPROC)(GLsizei size, const void * pointer, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FVERTEX3FSUNPROC)(GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FVERTEX3FVSUNPROC)(const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3HNVPROC)(GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLNORMAL3XOESPROC)(GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (GLAD_API_PTR *PFNGLNORMAL3XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALFORMATNVPROC)(GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLNORMALPOINTEREXTPROC)(GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERLISTIBMPROC)(GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERVINTELPROC)(GLenum type, const void ** pointer); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3BATIPROC)(GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3BVATIPROC)(GLenum stream, const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3DATIPROC)(GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3DVATIPROC)(GLenum stream, const GLdouble * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3FATIPROC)(GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3FVATIPROC)(GLenum stream, const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3IATIPROC)(GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3IVATIPROC)(GLenum stream, const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3SATIPROC)(GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (GLAD_API_PTR *PFNGLNORMALSTREAM3SVATIPROC)(GLenum stream, const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label); +typedef GLenum (GLAD_API_PTR *PFNGLOBJECTPURGEABLEAPPLEPROC)(GLenum objectType, GLuint name, GLenum option); +typedef GLenum (GLAD_API_PTR *PFNGLOBJECTUNPURGEABLEAPPLEPROC)(GLenum objectType, GLuint name, GLenum option); +typedef void (GLAD_API_PTR *PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAD_API_PTR *PFNGLORTHOFOESPROC)(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLORTHOXOESPROC)(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (GLAD_API_PTR *PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPASSTEXCOORDATIPROC)(GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAD_API_PTR *PFNGLPASSTHROUGHPROC)(GLfloat token); +typedef void (GLAD_API_PTR *PFNGLPASSTHROUGHXOESPROC)(GLfixed token); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPATHCOLORGENNVPROC)(GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat * coeffs); +typedef void (GLAD_API_PTR *PFNGLPATHCOMMANDSNVPROC)(GLuint path, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const void * coords); +typedef void (GLAD_API_PTR *PFNGLPATHCOORDSNVPROC)(GLuint path, GLsizei numCoords, GLenum coordType, const void * coords); +typedef void (GLAD_API_PTR *PFNGLPATHCOVERDEPTHFUNCNVPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLPATHDASHARRAYNVPROC)(GLuint path, GLsizei dashCount, const GLfloat * dashArray); +typedef void (GLAD_API_PTR *PFNGLPATHFOGGENNVPROC)(GLenum genMode); +typedef GLenum (GLAD_API_PTR *PFNGLPATHGLYPHINDEXARRAYNVPROC)(GLuint firstPathName, GLenum fontTarget, const void * fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GLAD_API_PTR *PFNGLPATHGLYPHINDEXRANGENVPROC)(GLenum fontTarget, const void * fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint * baseAndCount); +typedef void (GLAD_API_PTR *PFNGLPATHGLYPHRANGENVPROC)(GLuint firstPathName, GLenum fontTarget, const void * fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAD_API_PTR *PFNGLPATHGLYPHSNVPROC)(GLuint firstPathName, GLenum fontTarget, const void * fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void * charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GLAD_API_PTR *PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC)(GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void * fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAD_API_PTR *PFNGLPATHPARAMETERFNVPROC)(GLuint path, GLenum pname, GLfloat value); +typedef void (GLAD_API_PTR *PFNGLPATHPARAMETERFVNVPROC)(GLuint path, GLenum pname, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPATHPARAMETERINVPROC)(GLuint path, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPATHPARAMETERIVNVPROC)(GLuint path, GLenum pname, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPATHSTENCILDEPTHOFFSETNVPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLPATHSTENCILFUNCNVPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLPATHSTRINGNVPROC)(GLuint path, GLenum format, GLsizei length, const void * pathString); +typedef void (GLAD_API_PTR *PFNGLPATHSUBCOMMANDSNVPROC)(GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const void * coords); +typedef void (GLAD_API_PTR *PFNGLPATHSUBCOORDSNVPROC)(GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void * coords); +typedef void (GLAD_API_PTR *PFNGLPATHTEXGENNVPROC)(GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat * coeffs); +typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPIXELDATARANGENVPROC)(GLenum target, GLsizei length, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint * values); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort * values); +typedef void (GLAD_API_PTR *PFNGLPIXELMAPXPROC)(GLenum map, GLint size, const GLfixed * values); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREXPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLPIXELTEXGENPARAMETERFSGISPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELTEXGENPARAMETERFVSGISPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPIXELTEXGENPARAMETERISGISPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELTEXGENPARAMETERIVSGISPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPIXELTEXGENSGIXPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERXOESPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); +typedef void (GLAD_API_PTR *PFNGLPIXELZOOMXOESPROC)(GLfixed xfactor, GLfixed yfactor); +typedef GLboolean (GLAD_API_PTR *PFNGLPOINTALONGPATHNVPROC)(GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat * x, GLfloat * y, GLfloat * tangentX, GLfloat * tangentY); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFARBPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFEXTPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFSGISPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVARBPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVEXTPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVSGISPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERINVPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVNVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERXVOESPROC)(GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEXOESPROC)(GLfixed size); +typedef GLint (GLAD_API_PTR *PFNGLPOLLASYNCSGIXPROC)(GLuint * markerp); +typedef GLint (GLAD_API_PTR *PFNGLPOLLINSTRUMENTSSGIXPROC)(GLint * marker_p); +typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPPROC)(GLfloat factor, GLfloat units, GLfloat clamp); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPEXTPROC)(GLfloat factor, GLfloat units, GLfloat clamp); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETEXTPROC)(GLfloat factor, GLfloat bias); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETXOESPROC)(GLfixed factor, GLfixed units); +typedef void (GLAD_API_PTR *PFNGLPOLYGONSTIPPLEPROC)(const GLubyte * mask); +typedef void (GLAD_API_PTR *PFNGLPOPATTRIBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPCLIENTATTRIBPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPGROUPMARKEREXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPMATRIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPOPNAMEPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPRESENTFRAMEDUALFILLNVPROC)(GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAD_API_PTR *PFNGLPRESENTFRAMEKEYEDNVPROC)(GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVEBOUNDINGBOXARBPROC)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXNVPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint * textures, const GLfloat * priorities); +typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESEXTPROC)(GLsizei n, const GLuint * textures, const GLclampf * priorities); +typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESXOESPROC)(GLsizei n, const GLuint * textures, const GLfixed * priorities); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETER4DARBPROC)(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETER4DVARBPROC)(GLenum target, GLuint index, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETER4FARBPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETER4FVARBPROC)(GLenum target, GLuint index, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERI4INVPROC)(GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERI4IVNVPROC)(GLenum target, GLuint index, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERI4UINVPROC)(GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)(GLenum target, GLuint index, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETER4DARBPROC)(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)(GLenum target, GLuint index, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETER4FARBPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)(GLenum target, GLuint index, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERI4INVPROC)(GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)(GLenum target, GLuint index, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)(GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)(GLenum target, GLuint index, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETER4DNVPROC)(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETER4DVNVPROC)(GLenum target, GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETER4FNVPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETER4FVNVPROC)(GLenum target, GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIARBPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIEXTPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERS4DVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERS4FVNVPROC)(GLenum target, GLuint index, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC)(GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat * coeffs); +typedef void (GLAD_API_PTR *PFNGLPROGRAMSTRINGARBPROC)(GLenum target, GLenum format, GLsizei len, const void * string); +typedef void (GLAD_API_PTR *PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC)(GLenum target, GLsizei count, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DEXTPROC)(GLuint program, GLint location, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FEXTPROC)(GLuint program, GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1I64ARBPROC)(GLuint program, GLint location, GLint64 x); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1I64NVPROC)(GLuint program, GLint location, GLint64EXT x); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1I64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1I64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IEXTPROC)(GLuint program, GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UI64ARBPROC)(GLuint program, GLint location, GLuint64 x); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UI64NVPROC)(GLuint program, GLint location, GLuint64EXT x); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UI64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIEXTPROC)(GLuint program, GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DEXTPROC)(GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FEXTPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2I64ARBPROC)(GLuint program, GLint location, GLint64 x, GLint64 y); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2I64NVPROC)(GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2I64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2I64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IEXTPROC)(GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UI64ARBPROC)(GLuint program, GLint location, GLuint64 x, GLuint64 y); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UI64NVPROC)(GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UI64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIEXTPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DEXTPROC)(GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FEXTPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3I64ARBPROC)(GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3I64NVPROC)(GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3I64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3I64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IEXTPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UI64ARBPROC)(GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UI64NVPROC)(GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UI64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIEXTPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DEXTPROC)(GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FEXTPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4I64ARBPROC)(GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4I64NVPROC)(GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4I64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4I64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IEXTPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UI64ARBPROC)(GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UI64NVPROC)(GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UI64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIEXTPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVEXTPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)(GLuint program, GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC)(GLuint program, GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * values); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * values); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMUI64NVPROC)(GLuint program, GLint location, GLuint64EXT value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMUI64VNVPROC)(GLuint program, GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMVERTEXLIMITNVPROC)(GLenum target, GLint limit); +typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPUSHATTRIBPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +typedef void (GLAD_API_PTR *PFNGLPUSHGROUPMARKEREXTPROC)(GLsizei length, const GLchar * marker); +typedef void (GLAD_API_PTR *PFNGLPUSHMATRIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPUSHNAMEPROC)(GLuint name); +typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); +typedef GLbitfield (GLAD_API_PTR *PFNGLQUERYMATRIXXOESPROC)(GLfixed * mantissa, GLint * exponent); +typedef void (GLAD_API_PTR *PFNGLQUERYOBJECTPARAMETERUIAMDPROC)(GLenum target, GLuint id, GLenum pname, GLuint param); +typedef GLint (GLAD_API_PTR *PFNGLQUERYRESOURCENVPROC)(GLenum queryType, GLint tagId, GLuint count, GLint * buffer); +typedef void (GLAD_API_PTR *PFNGLQUERYRESOURCETAGNVPROC)(GLint tagId, const GLchar * tagString); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2XOESPROC)(GLfixed x, GLfixed y); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS2XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3XOESPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS3XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4XOESPROC)(GLfixed x, GLfixed y, GLfixed z, GLfixed w); +typedef void (GLAD_API_PTR *PFNGLRASTERPOS4XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLRASTERSAMPLESEXTPROC)(GLuint samples, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); +typedef void (GLAD_API_PTR *PFNGLREADINSTRUMENTSSGIXPROC)(GLint marker); +typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +typedef void (GLAD_API_PTR *PFNGLREADNPIXELSARBPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +typedef void (GLAD_API_PTR *PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +typedef void (GLAD_API_PTR *PFNGLRECTDVPROC)(const GLdouble * v1, const GLdouble * v2); +typedef void (GLAD_API_PTR *PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +typedef void (GLAD_API_PTR *PFNGLRECTFVPROC)(const GLfloat * v1, const GLfloat * v2); +typedef void (GLAD_API_PTR *PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); +typedef void (GLAD_API_PTR *PFNGLRECTIVPROC)(const GLint * v1, const GLint * v2); +typedef void (GLAD_API_PTR *PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +typedef void (GLAD_API_PTR *PFNGLRECTSVPROC)(const GLshort * v1, const GLshort * v2); +typedef void (GLAD_API_PTR *PFNGLRECTXOESPROC)(GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +typedef void (GLAD_API_PTR *PFNGLRECTXVOESPROC)(const GLfixed * v1, const GLfixed * v2); +typedef void (GLAD_API_PTR *PFNGLREFERENCEPLANESGIXPROC)(const GLdouble * equation); +typedef GLboolean (GLAD_API_PTR *PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC)(GLuint memory, GLuint64 key); +typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRENDERGPUMASKNVPROC)(GLbitfield mask); +typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEPOINTERSUNPROC)(GLenum type, GLsizei stride, const void ** pointer); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUBSUNPROC)(GLubyte code); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUBVSUNPROC)(const GLubyte * code); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)(GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)(GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * c, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)(GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)(const GLuint * rc, const GLubyte * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)(GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUISUNPROC)(GLuint code); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)(GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)(GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * tc, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)(GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * tc, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)(GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)(const GLuint * rc, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUIVSUNPROC)(const GLuint * code); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUSSUNPROC)(GLushort code); +typedef void (GLAD_API_PTR *PFNGLREPLACEMENTCODEUSVSUNPROC)(const GLushort * code); +typedef void (GLAD_API_PTR *PFNGLREQUESTRESIDENTPROGRAMSNVPROC)(GLsizei n, const GLuint * programs); +typedef void (GLAD_API_PTR *PFNGLRESETHISTOGRAMPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLRESETHISTOGRAMEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLRESETMEMORYOBJECTPARAMETERNVPROC)(GLuint memory, GLenum pname); +typedef void (GLAD_API_PTR *PFNGLRESETMINMAXPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLRESETMINMAXEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLRESIZEBUFFERSMESAPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRESOLVEDEPTHVALUESNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLROTATEXOESPROC)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEARBPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMAPATIPROC)(GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKEXTPROC)(GLclampf value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKINDEXEDNVPROC)(GLuint index, GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKSGISPROC)(GLclampf value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLSAMPLEPATTERNEXTPROC)(GLenum pattern); +typedef void (GLAD_API_PTR *PFNGLSAMPLEPATTERNSGISPROC)(GLenum pattern); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLSCALEXOESPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSOREXCLUSIVEARRAYVNVPROC)(GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSOREXCLUSIVENVPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BEXTPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVEXTPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DEXTPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVEXTPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FEXTPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVEXTPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3HNVPROC)(GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IEXTPROC)(GLint red, GLint green, GLint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVEXTPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SEXTPROC)(GLshort red, GLshort green, GLshort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVEXTPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBEXTPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVEXTPROC)(const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIEXTPROC)(GLuint red, GLuint green, GLuint blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVEXTPROC)(const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USEXTPROC)(GLushort red, GLushort green, GLushort blue); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVEXTPROC)(const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORFORMATNVPROC)(GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint * color); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)(GLint size, GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint * buffer); +typedef void (GLAD_API_PTR *PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint * counterList); +typedef void (GLAD_API_PTR *PFNGLSEMAPHOREPARAMETERIVNVPROC)(GLuint semaphore, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLSEMAPHOREPARAMETERUI64VEXTPROC)(GLuint semaphore, GLenum pname, const GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLSEPARABLEFILTER2DPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * row, const void * column); +typedef void (GLAD_API_PTR *PFNGLSEPARABLEFILTER2DEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * row, const void * column); +typedef void (GLAD_API_PTR *PFNGLSETFENCEAPPLEPROC)(GLuint fence); +typedef void (GLAD_API_PTR *PFNGLSETFENCENVPROC)(GLuint fence, GLenum condition); +typedef void (GLAD_API_PTR *PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)(GLuint dst, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLSETINVARIANTEXTPROC)(GLuint id, GLenum type, const void * addr); +typedef void (GLAD_API_PTR *PFNGLSETLOCALCONSTANTEXTPROC)(GLuint id, GLenum type, const void * addr); +typedef void (GLAD_API_PTR *PFNGLSETMULTISAMPLEFVAMDPROC)(GLenum pname, GLuint index, const GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLSHADEMODELPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLSHADEROP1EXTPROC)(GLenum op, GLuint res, GLuint arg1); +typedef void (GLAD_API_PTR *PFNGLSHADEROP2EXTPROC)(GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAD_API_PTR *PFNGLSHADEROP3EXTPROC)(GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEARBPROC)(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATEIMAGEBARRIERNVPROC)(GLboolean synchronize); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATEIMAGEPALETTENVPROC)(GLuint viewport, GLuint first, GLsizei count, const GLenum * rates); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC)(GLenum rate, GLuint samples, const GLint * locations); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATESAMPLEORDERNVPROC)(GLenum order); +typedef void (GLAD_API_PTR *PFNGLSHARPENTEXFUNCSGISPROC)(GLenum target, GLsizei n, const GLfloat * points); +typedef void (GLAD_API_PTR *PFNGLSIGNALSEMAPHOREEXTPROC)(GLuint semaphore, GLuint numBufferBarriers, const GLuint * buffers, GLuint numTextureBarriers, const GLuint * textures, const GLenum * dstLayouts); +typedef void (GLAD_API_PTR *PFNGLSIGNALSEMAPHOREUI64NVXPROC)(GLuint signalGpu, GLsizei fenceObjectCount, const GLuint * semaphoreArray, const GLuint64 * fenceValueArray); +typedef void (GLAD_API_PTR *PFNGLSIGNALVKFENCENVPROC)(GLuint64 vkFence); +typedef void (GLAD_API_PTR *PFNGLSIGNALVKSEMAPHORENVPROC)(GLuint64 vkSemaphore); +typedef void (GLAD_API_PTR *PFNGLSPECIALIZESHADERPROC)(GLuint shader, const GLchar * pEntryPoint, GLuint numSpecializationConstants, const GLuint * pConstantIndex, const GLuint * pConstantValue); +typedef void (GLAD_API_PTR *PFNGLSPECIALIZESHADERARBPROC)(GLuint shader, const GLchar * pEntryPoint, GLuint numSpecializationConstants, const GLuint * pConstantIndex, const GLuint * pConstantValue); +typedef void (GLAD_API_PTR *PFNGLSPRITEPARAMETERFSGIXPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSPRITEPARAMETERFVSGIXPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLSPRITEPARAMETERISGIXPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSPRITEPARAMETERIVSGIXPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLSTARTINSTRUMENTSSGIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLSTATECAPTURENVPROC)(GLuint state, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLSTENCILCLEARTAGEXTPROC)(GLsizei stencilTagBits, GLuint stencilClearTag); +typedef void (GLAD_API_PTR *PFNGLSTENCILFILLPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLSTENCILFILLPATHNVPROC)(GLuint path, GLenum fillMode, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEATIPROC)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEATIPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPVALUEAMDPROC)(GLenum face, GLuint value); +typedef void (GLAD_API_PTR *PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLSTENCILSTROKEPATHNVPROC)(GLuint path, GLint reference, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLSTENCILTHENCOVERFILLPATHNVPROC)(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (GLAD_API_PTR *PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC)(GLsizei numPaths, GLenum pathNameType, const void * paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC)(GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (GLAD_API_PTR *PFNGLSTOPINSTRUMENTSSGIXPROC)(GLint marker); +typedef void (GLAD_API_PTR *PFNGLSTRINGMARKERGREMEDYPROC)(GLsizei len, const void * string); +typedef void (GLAD_API_PTR *PFNGLSUBPIXELPRECISIONBIASNVPROC)(GLuint xbits, GLuint ybits); +typedef void (GLAD_API_PTR *PFNGLSWIZZLEEXTPROC)(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAD_API_PTR *PFNGLSYNCTEXTUREINTELPROC)(GLuint texture); +typedef void (GLAD_API_PTR *PFNGLTAGSAMPLEBUFFERSGIXPROC)(void); +typedef void (GLAD_API_PTR *PFNGLTANGENT3BEXTPROC)(GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (GLAD_API_PTR *PFNGLTANGENT3BVEXTPROC)(const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLTANGENT3DEXTPROC)(GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (GLAD_API_PTR *PFNGLTANGENT3DVEXTPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTANGENT3FEXTPROC)(GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (GLAD_API_PTR *PFNGLTANGENT3FVEXTPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTANGENT3IEXTPROC)(GLint tx, GLint ty, GLint tz); +typedef void (GLAD_API_PTR *PFNGLTANGENT3IVEXTPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTANGENT3SEXTPROC)(GLshort tx, GLshort ty, GLshort tz); +typedef void (GLAD_API_PTR *PFNGLTANGENT3SVEXTPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTANGENTPOINTEREXTPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLTBUFFERMASK3DFXPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLTESSELLATIONFACTORAMDPROC)(GLfloat factor); +typedef void (GLAD_API_PTR *PFNGLTESSELLATIONMODEAMDPROC)(GLenum mode); +typedef GLboolean (GLAD_API_PTR *PFNGLTESTFENCEAPPLEPROC)(GLuint fence); +typedef GLboolean (GLAD_API_PTR *PFNGLTESTFENCENVPROC)(GLuint fence); +typedef GLboolean (GLAD_API_PTR *PFNGLTESTOBJECTAPPLEPROC)(GLenum object, GLuint name); +typedef void (GLAD_API_PTR *PFNGLTEXATTACHMEMORYNVPROC)(GLenum target, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERARBPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFEREXTPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXBUMPPARAMETERFVATIPROC)(GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLTEXBUMPPARAMETERIVATIPROC)(GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1BOESPROC)(GLbyte s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DPROC)(GLdouble s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FPROC)(GLfloat s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1HNVPROC)(GLhalfNV s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SPROC)(GLshort s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1XOESPROC)(GLfixed s); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD1XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2BOESPROC)(GLbyte s, GLbyte t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)(const GLfloat * tc, const GLfloat * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)(const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)(GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)(const GLfloat * tc, const GLubyte * c, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)(GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)(const GLfloat * tc, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVERTEX3FSUNPROC)(GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVERTEX3FVSUNPROC)(const GLfloat * tc, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2HNVPROC)(GLhalfNV s, GLhalfNV t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IPROC)(GLint s, GLint t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2XOESPROC)(GLfixed s, GLfixed t); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD2XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3BOESPROC)(GLbyte s, GLbyte t, GLbyte r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3HNVPROC)(GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3XOESPROC)(GLfixed s, GLfixed t, GLfixed r); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD3XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4BOESPROC)(GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)(GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)(const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVERTEX4FSUNPROC)(GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVERTEX4FVSUNPROC)(const GLfloat * tc, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4HNVPROC)(GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4XOESPROC)(GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (GLAD_API_PTR *PFNGLTEXCOORD4XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDFORMATNVPROC)(GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint * coords); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERLISTIBMPROC)(GLint size, GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERVINTELPROC)(GLint size, GLenum type, const void ** pointer); +typedef void (GLAD_API_PTR *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXENVXOESPROC)(GLenum target, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLTEXENVXVOESPROC)(GLenum target, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLTEXFILTERFUNCSGISPROC)(GLenum target, GLenum filter, GLsizei n, const GLfloat * weights); +typedef void (GLAD_API_PTR *PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAD_API_PTR *PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENXOESPROC)(GLenum coord, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLTEXGENXVOESPROC)(GLenum coord, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC)(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DEXTPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC)(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE4DSGISPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXPAGECOMMITMENTARBPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLTEXPAGECOMMITMENTMEMNVPROC)(GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVEXTPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVEXTPROC)(GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERXOESPROC)(GLenum target, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERXVOESPROC)(GLenum target, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLTEXRENDERBUFFERNVPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM1DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM2DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM3DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGESPARSEAMDPROC)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE4DSGISPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREATTACHMEMORYNVPROC)(GLuint texture, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERNVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFEREXTPROC)(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEEXTPROC)(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXTURECOLORMASKSGISPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC)(GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE3DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC)(GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURELIGHTEXTPROC)(GLenum pname); +typedef void (GLAD_API_PTR *PFNGLTEXTUREMATERIALEXTPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLTEXTURENORMALEXTPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPAGECOMMITMENTEXTPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC)(GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVEXTPROC)(GLuint texture, GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIEXTPROC)(GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVEXTPROC)(GLuint texture, GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTURERANGEAPPLEPROC)(GLenum target, GLsizei length, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLTEXTURERENDERBUFFEREXTPROC)(GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM1DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM2DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC)(GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM3DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC)(GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGESPARSEAMDPROC)(GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DEXTPROC)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (GLAD_API_PTR *PFNGLTRACKMATRIXNVPROC)(GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)(GLsizei count, const GLint * attribs, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC)(GLsizei count, const GLint * attribs, GLsizei nbuffers, const GLint * bufstreams, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)(GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMPATHNVPROC)(GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat * transformValues); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEXOESPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FARBPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVARBPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1I64ARBPROC)(GLint location, GLint64 x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1I64NVPROC)(GLint location, GLint64EXT x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1I64VARBPROC)(GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1I64VNVPROC)(GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IARBPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVARBPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UI64ARBPROC)(GLint location, GLuint64 x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UI64NVPROC)(GLint location, GLuint64EXT x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UI64VARBPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UI64VNVPROC)(GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIEXTPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVEXTPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FARBPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVARBPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2I64ARBPROC)(GLint location, GLint64 x, GLint64 y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2I64NVPROC)(GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2I64VARBPROC)(GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2I64VNVPROC)(GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IARBPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVARBPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UI64ARBPROC)(GLint location, GLuint64 x, GLuint64 y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UI64NVPROC)(GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UI64VARBPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UI64VNVPROC)(GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIEXTPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVEXTPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FARBPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVARBPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3I64ARBPROC)(GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3I64NVPROC)(GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3I64VARBPROC)(GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3I64VNVPROC)(GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IARBPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVARBPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UI64ARBPROC)(GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UI64NVPROC)(GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UI64VARBPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UI64VNVPROC)(GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIEXTPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVEXTPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FARBPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVARBPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4I64ARBPROC)(GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4I64NVPROC)(GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4I64VARBPROC)(GLint location, GLsizei count, const GLint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4I64VNVPROC)(GLint location, GLsizei count, const GLint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IARBPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVARBPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UI64ARBPROC)(GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UI64NVPROC)(GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UI64VARBPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UI64VNVPROC)(GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIEXTPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVEXTPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBUFFEREXTPROC)(GLuint program, GLint location, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64ARBPROC)(GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64NVPROC)(GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64VARBPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64VNVPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVARBPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVARBPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVARBPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint * indices); +typedef void (GLAD_API_PTR *PFNGLUNIFORMUI64NVPROC)(GLint location, GLuint64EXT value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMUI64VNVPROC)(GLint location, GLsizei count, const GLuint64EXT * value); +typedef void (GLAD_API_PTR *PFNGLUNLOCKARRAYSEXTPROC)(void); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERARBPROC)(GLenum target); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFEREXTPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLUNMAPOBJECTBUFFERATIPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLUNMAPTEXTURE2DINTELPROC)(GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLUPDATEOBJECTBUFFERATIPROC)(GLuint buffer, GLuint offset, GLsizei size, const void * pointer, GLenum preserve); +typedef void (GLAD_API_PTR *PFNGLUPLOADGPUMASKNVXPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMOBJECTARBPROC)(GLhandleARB programObj); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAD_API_PTR *PFNGLVDPAUFININVPROC)(void); +typedef void (GLAD_API_PTR *PFNGLVDPAUGETSURFACEIVNVPROC)(GLvdpauSurfaceNV surface, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLVDPAUINITNVPROC)(const void * vdpDevice, const void * getProcAddress); +typedef GLboolean (GLAD_API_PTR *PFNGLVDPAUISSURFACENVPROC)(GLvdpauSurfaceNV surface); +typedef void (GLAD_API_PTR *PFNGLVDPAUMAPSURFACESNVPROC)(GLsizei numSurfaces, const GLvdpauSurfaceNV * surfaces); +typedef GLvdpauSurfaceNV (GLAD_API_PTR *PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)(const void * vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint * textureNames); +typedef GLvdpauSurfaceNV (GLAD_API_PTR *PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)(const void * vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint * textureNames); +typedef GLvdpauSurfaceNV (GLAD_API_PTR *PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC)(const void * vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint * textureNames, GLboolean isFrameStructure); +typedef void (GLAD_API_PTR *PFNGLVDPAUSURFACEACCESSNVPROC)(GLvdpauSurfaceNV surface, GLenum access); +typedef void (GLAD_API_PTR *PFNGLVDPAUUNMAPSURFACESNVPROC)(GLsizei numSurface, const GLvdpauSurfaceNV * surfaces); +typedef void (GLAD_API_PTR *PFNGLVDPAUUNREGISTERSURFACENVPROC)(GLvdpauSurfaceNV surface); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMARBPROC)(GLhandleARB programObj); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLVARIANTARRAYOBJECTATIPROC)(GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAD_API_PTR *PFNGLVARIANTPOINTEREXTPROC)(GLuint id, GLenum type, GLuint stride, const void * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTBVEXTPROC)(GLuint id, const GLbyte * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTDVEXTPROC)(GLuint id, const GLdouble * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTFVEXTPROC)(GLuint id, const GLfloat * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTIVEXTPROC)(GLuint id, const GLint * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTSVEXTPROC)(GLuint id, const GLshort * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTUBVEXTPROC)(GLuint id, const GLubyte * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTUIVEXTPROC)(GLuint id, const GLuint * addr); +typedef void (GLAD_API_PTR *PFNGLVARIANTUSVEXTPROC)(GLuint id, const GLushort * addr); +typedef void (GLAD_API_PTR *PFNGLVERTEX2BOESPROC)(GLbyte x, GLbyte y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2HNVPROC)(GLhalfNV x, GLhalfNV y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEX2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX2XOESPROC)(GLfixed x); +typedef void (GLAD_API_PTR *PFNGLVERTEX2XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEX3BOESPROC)(GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3HNVPROC)(GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEX3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX3XOESPROC)(GLfixed x, GLfixed y); +typedef void (GLAD_API_PTR *PFNGLVERTEX3XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEX4BOESPROC)(GLbyte x, GLbyte y, GLbyte z, GLbyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4BVOESPROC)(const GLbyte * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4HNVPROC)(GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4HVNVPROC)(const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEX4SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEX4XOESPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLVERTEX4XVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYRANGEAPPLEPROC)(GLsizei length, void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYRANGENVPROC)(GLsizei length, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC)(GLuint vaobj, GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DARBPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DNVPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVARBPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVNVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FARBPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FNVPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVARBPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVNVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1HNVPROC)(GLuint index, GLhalfNV x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1HVNVPROC)(GLuint index, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SARBPROC)(GLuint index, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SNVPROC)(GLuint index, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVARBPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVNVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DARBPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DNVPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVARBPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVNVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FARBPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FNVPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVARBPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVNVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2HNVPROC)(GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2HVNVPROC)(GLuint index, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SARBPROC)(GLuint index, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SNVPROC)(GLuint index, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVARBPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVNVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DARBPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DNVPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVARBPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVNVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FARBPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FNVPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVARBPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVNVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3HNVPROC)(GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3HVNVPROC)(GLuint index, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SARBPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SNVPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVARBPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVNVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVARBPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVARBPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVARBPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBARBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVARBPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVARBPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVARBPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVARBPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DARBPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DNVPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVARBPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVNVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FARBPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FNVPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVARBPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVNVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4HNVPROC)(GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4HVNVPROC)(GLuint index, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVARBPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SARBPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SNVPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVARBPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVNVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBNVPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVARBPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVNVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVARBPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVARBPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORARBPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATNVPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IEXTPROC)(GLuint index, GLint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVEXTPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIEXTPROC)(GLuint index, GLuint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVEXTPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IEXTPROC)(GLuint index, GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVEXTPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIEXTPROC)(GLuint index, GLuint x, GLuint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVEXTPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IEXTPROC)(GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVEXTPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIEXTPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVEXTPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVEXTPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IEXTPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVEXTPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVEXTPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVEXTPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIEXTPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVEXTPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVEXTPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATNVPROC)(GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTEREXTPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DEXTPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVEXTPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1I64NVPROC)(GLuint index, GLint64EXT x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1I64VNVPROC)(GLuint index, const GLint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1UI64ARBPROC)(GLuint index, GLuint64EXT x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1UI64NVPROC)(GLuint index, GLuint64EXT x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1UI64VARBPROC)(GLuint index, const GLuint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1UI64VNVPROC)(GLuint index, const GLuint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DEXTPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVEXTPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2I64NVPROC)(GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2I64VNVPROC)(GLuint index, const GLint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2UI64NVPROC)(GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2UI64VNVPROC)(GLuint index, const GLuint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DEXTPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVEXTPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3I64NVPROC)(GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3I64VNVPROC)(GLuint index, const GLint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3UI64NVPROC)(GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3UI64VNVPROC)(GLuint index, const GLuint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DEXTPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVEXTPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4I64NVPROC)(GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4I64VNVPROC)(GLuint index, const GLint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4UI64NVPROC)(GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4UI64VNVPROC)(GLuint index, const GLuint64EXT * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATNVPROC)(GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTEREXTPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPARAMETERIAMDPROC)(GLuint index, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERARBPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERNVPROC)(GLuint index, GLint fsize, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS1DVNVPROC)(GLuint index, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS1FVNVPROC)(GLuint index, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS1HVNVPROC)(GLuint index, GLsizei n, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS1SVNVPROC)(GLuint index, GLsizei count, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS2DVNVPROC)(GLuint index, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS2FVNVPROC)(GLuint index, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS2HVNVPROC)(GLuint index, GLsizei n, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS2SVNVPROC)(GLuint index, GLsizei count, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS3DVNVPROC)(GLuint index, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS3FVNVPROC)(GLuint index, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS3HVNVPROC)(GLuint index, GLsizei n, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS3SVNVPROC)(GLuint index, GLsizei count, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS4DVNVPROC)(GLuint index, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS4FVNVPROC)(GLuint index, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS4HVNVPROC)(GLuint index, GLsizei n, const GLhalfNV * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS4SVNVPROC)(GLuint index, GLsizei count, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBS4UBVNVPROC)(GLuint index, GLsizei count, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXBLENDARBPROC)(GLint count); +typedef void (GLAD_API_PTR *PFNGLVERTEXBLENDENVFATIPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLVERTEXBLENDENVIATIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLVERTEXFORMATNVPROC)(GLint size, GLenum type, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERLISTIBMPROC)(GLint size, GLenum type, GLint stride, const void ** pointer, GLint ptrstride); +typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERVINTELPROC)(GLint size, GLenum type, const void ** pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1DATIPROC)(GLenum stream, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1DVATIPROC)(GLenum stream, const GLdouble * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1FATIPROC)(GLenum stream, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1FVATIPROC)(GLenum stream, const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1IATIPROC)(GLenum stream, GLint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1IVATIPROC)(GLenum stream, const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1SATIPROC)(GLenum stream, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM1SVATIPROC)(GLenum stream, const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2DATIPROC)(GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2DVATIPROC)(GLenum stream, const GLdouble * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2FATIPROC)(GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2FVATIPROC)(GLenum stream, const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2IATIPROC)(GLenum stream, GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2IVATIPROC)(GLenum stream, const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2SATIPROC)(GLenum stream, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM2SVATIPROC)(GLenum stream, const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3DATIPROC)(GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3DVATIPROC)(GLenum stream, const GLdouble * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3FATIPROC)(GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3FVATIPROC)(GLenum stream, const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3IATIPROC)(GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3IVATIPROC)(GLenum stream, const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3SATIPROC)(GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM3SVATIPROC)(GLenum stream, const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4DATIPROC)(GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4DVATIPROC)(GLenum stream, const GLdouble * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4FATIPROC)(GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4FVATIPROC)(GLenum stream, const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4IATIPROC)(GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4IVATIPROC)(GLenum stream, const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4SATIPROC)(GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXSTREAM4SVATIPROC)(GLenum stream, const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLVERTEXWEIGHTPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXWEIGHTFEXTPROC)(GLfloat weight); +typedef void (GLAD_API_PTR *PFNGLVERTEXWEIGHTFVEXTPROC)(const GLfloat * weight); +typedef void (GLAD_API_PTR *PFNGLVERTEXWEIGHTHNVPROC)(GLhalfNV weight); +typedef void (GLAD_API_PTR *PFNGLVERTEXWEIGHTHVNVPROC)(const GLhalfNV * weight); +typedef GLenum (GLAD_API_PTR *PFNGLVIDEOCAPTURENVPROC)(GLuint video_capture_slot, GLuint * sequence_num, GLuint64EXT * capture_time); +typedef void (GLAD_API_PTR *PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC)(GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPOSITIONWSCALENVPROC)(GLuint index, GLfloat xcoeff, GLfloat ycoeff); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTSWIZZLENVPROC)(GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +typedef void (GLAD_API_PTR *PFNGLWAITSEMAPHOREEXTPROC)(GLuint semaphore, GLuint numBufferBarriers, const GLuint * buffers, GLuint numTextureBarriers, const GLuint * textures, const GLenum * srcLayouts); +typedef void (GLAD_API_PTR *PFNGLWAITSEMAPHOREUI64NVXPROC)(GLuint waitGpu, GLsizei fenceObjectCount, const GLuint * semaphoreArray, const GLuint64 * fenceValueArray); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLWAITVKSEMAPHORENVPROC)(GLuint64 vkSemaphore); +typedef void (GLAD_API_PTR *PFNGLWEIGHTPATHSNVPROC)(GLuint resultPath, GLsizei numPaths, const GLuint * paths, const GLfloat * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTPOINTERARBPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLWEIGHTBVARBPROC)(GLint size, const GLbyte * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTDVARBPROC)(GLint size, const GLdouble * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTFVARBPROC)(GLint size, const GLfloat * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTIVARBPROC)(GLint size, const GLint * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTSVARBPROC)(GLint size, const GLshort * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTUBVARBPROC)(GLint size, const GLubyte * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTUIVARBPROC)(GLint size, const GLuint * weights); +typedef void (GLAD_API_PTR *PFNGLWEIGHTUSVARBPROC)(GLint size, const GLushort * weights); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DARBPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DMESAPROC)(GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVARBPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVMESAPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FARBPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FMESAPROC)(GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVARBPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVMESAPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IARBPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IMESAPROC)(GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVARBPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVMESAPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SARBPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SMESAPROC)(GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVARBPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVMESAPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DARBPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DMESAPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVARBPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVMESAPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FARBPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FMESAPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVARBPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVMESAPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IARBPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IMESAPROC)(GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVARBPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVMESAPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SARBPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SMESAPROC)(GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVARBPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVMESAPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4DMESAPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4DVMESAPROC)(const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4FMESAPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4FVMESAPROC)(const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4IMESAPROC)(GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4IVMESAPROC)(const GLint * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4SMESAPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLWINDOWPOS4SVMESAPROC)(const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLWINDOWRECTANGLESEXTPROC)(GLenum mode, GLsizei count, const GLint * box); +typedef void (GLAD_API_PTR *PFNGLWRITEMASKEXTPROC)(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAD_API_PTR *PFNGLALPHAFUNCXPROC)(GLenum func, GLfixed ref); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFEROESPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFEROESPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYOESPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONOESPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEOESPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEOESPROC)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORXPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHXPROC)(GLfixed depth); +typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCAPPLEPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEFPROC)(GLenum p, const GLfloat * eqn); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEFIMGPROC)(GLenum p, const GLfloat * eqn); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEXPROC)(GLenum plane, const GLfixed * equation); +typedef void (GLAD_API_PTR *PFNGLCLIPPLANEXIMGPROC)(GLenum p, const GLfixed * eqn); +typedef void (GLAD_API_PTR *PFNGLCOLOR4XPROC)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURELEVELSAPPLEPROC)(GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +typedef void (GLAD_API_PTR *PFNGLCURRENTPALETTEMATRIXOESPROC)(GLuint matrixpaletteindex); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSOESPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSOESPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCAPPLEPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSOESPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEXPROC)(GLfixed n, GLfixed f); +typedef void (GLAD_API_PTR *PFNGLDISABLEDRIVERCONTROLQCOMPROC)(GLuint driverControl); +typedef void (GLAD_API_PTR *PFNGLDISCARDFRAMEBUFFEREXTPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXFOESPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXFVOESPROC)(const GLfloat * coords); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXIOESPROC)(GLint x, GLint y, GLint z, GLint width, GLint height); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXIVOESPROC)(const GLint * coords); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXSOESPROC)(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXSVOESPROC)(const GLshort * coords); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXXOESPROC)(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height); +typedef void (GLAD_API_PTR *PFNGLDRAWTEXXVOESPROC)(const GLfixed * coords); +typedef void (GLAD_API_PTR *PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)(GLenum target, GLeglImageOES image); +typedef void (GLAD_API_PTR *PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum target, GLeglImageOES image); +typedef void (GLAD_API_PTR *PFNGLENABLEDRIVERCONTROLQCOMPROC)(GLuint driverControl); +typedef void (GLAD_API_PTR *PFNGLENDTILINGQCOMPROC)(GLbitfield preserveMask); +typedef void (GLAD_API_PTR *PFNGLEXTGETBUFFERPOINTERVQCOMPROC)(GLenum target, void ** params); +typedef void (GLAD_API_PTR *PFNGLEXTGETBUFFERSQCOMPROC)(GLuint * buffers, GLint maxBuffers, GLint * numBuffers); +typedef void (GLAD_API_PTR *PFNGLEXTGETFRAMEBUFFERSQCOMPROC)(GLuint * framebuffers, GLint maxFramebuffers, GLint * numFramebuffers); +typedef void (GLAD_API_PTR *PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC)(GLuint program, GLenum shadertype, GLchar * source, GLint * length); +typedef void (GLAD_API_PTR *PFNGLEXTGETPROGRAMSQCOMPROC)(GLuint * programs, GLint maxPrograms, GLint * numPrograms); +typedef void (GLAD_API_PTR *PFNGLEXTGETRENDERBUFFERSQCOMPROC)(GLuint * renderbuffers, GLint maxRenderbuffers, GLint * numRenderbuffers); +typedef void (GLAD_API_PTR *PFNGLEXTGETSHADERSQCOMPROC)(GLuint * shaders, GLint maxShaders, GLint * numShaders); +typedef void (GLAD_API_PTR *PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC)(GLuint texture, GLenum face, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLEXTGETTEXSUBIMAGEQCOMPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void * texels); +typedef void (GLAD_API_PTR *PFNGLEXTGETTEXTURESQCOMPROC)(GLuint * textures, GLint maxTextures, GLint * numTextures); +typedef GLboolean (GLAD_API_PTR *PFNGLEXTISPROGRAMBINARYQCOMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC)(GLenum target, GLenum pname, GLint param); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCAPPLEPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFOGXPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLFOGXVPROC)(GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DOESPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMFPROC)(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLFRUSTUMXPROC)(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSOESPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSOESPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSOESPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPOESPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVOESPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEFPROC)(GLenum plane, GLfloat * equation); +typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEXPROC)(GLenum plane, GLfixed * equation); +typedef void (GLAD_API_PTR *PFNGLGETDRIVERCONTROLSTRINGQCOMPROC)(GLuint driverControl, GLsizei bufSize, GLsizei * length, GLchar * driverControlString); +typedef void (GLAD_API_PTR *PFNGLGETDRIVERCONTROLSQCOMPROC)(GLint * num, GLsizei size, GLuint * driverControls); +typedef void (GLAD_API_PTR *PFNGLGETFIXEDVPROC)(GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSEXTPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VAPPLEPROC)(GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTXVPROC)(GLenum light, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETLIGHTXVOESPROC)(GLenum light, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALXVPROC)(GLenum face, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETMATERIALXVOESPROC)(GLenum face, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVAPPLEPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXENVXVPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENFVOESPROC)(GLenum coord, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXGENIVOESPROC)(GLenum coord, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERXVPROC)(GLenum target, GLenum pname, GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVEXTPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVEXTPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFEROESPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFEROESPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCAPPLEPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYOESPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELXPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLLIGHTMODELXVPROC)(GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLLIGHTXPROC)(GLenum light, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLLIGHTXVPROC)(GLenum light, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHXPROC)(GLfixed width); +typedef void (GLAD_API_PTR *PFNGLLOADMATRIXXPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC)(void); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFEROESPROC)(GLenum target, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEEXTPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLMATERIALXPROC)(GLenum face, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLMATERIALXVPROC)(GLenum face, GLenum pname, const GLfixed * param); +typedef void (GLAD_API_PTR *PFNGLMATRIXINDEXPOINTEROESPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLMULTMATRIXXPROC)(const GLfixed * m); +typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4XPROC)(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (GLAD_API_PTR *PFNGLNORMAL3XPROC)(GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (GLAD_API_PTR *PFNGLORTHOFPROC)(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLORTHOXPROC)(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERXPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERXOESPROC)(GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERXVPROC)(GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPOINTEROESPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEXPROC)(GLfixed size); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETXPROC)(GLfixed factor, GLfixed units); +typedef void (GLAD_API_PTR *PFNGLREADNPIXELSEXTPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEOESPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC)(void); +typedef void (GLAD_API_PTR *PFNGLROTATEXPROC)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEXPROC)(GLclampx value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEXOESPROC)(GLclampx value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSCALEXPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAD_API_PTR *PFNGLSTARTTILINGQCOMPROC)(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GLAD_API_PTR *PFNGLTEXENVXPROC)(GLenum target, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLTEXENVXVPROC)(GLenum target, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENFOESPROC)(GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXGENFVOESPROC)(GLenum coord, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXGENIOESPROC)(GLenum coord, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXGENIVOESPROC)(GLenum coord, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERXPROC)(GLenum target, GLenum pname, GLfixed param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERXVPROC)(GLenum target, GLenum pname, const GLfixed * params); +typedef void (GLAD_API_PTR *PFNGLTRANSLATEXPROC)(GLfixed x, GLfixed y, GLfixed z); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFEROESPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCAPPLEPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLWEIGHTPOINTEROESPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMEXTPROC)(GLuint pipeline, GLuint program); +typedef void (GLAD_API_PTR *PFNGLALPHAFUNCQCOMPROC)(GLenum func, GLclampf ref); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYEXTPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEEXTPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLBLENDBARRIERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIEXTPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIOESPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIEXTPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIOESPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIEXTPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIOESPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIEXTPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIOESPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERANGLEPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERNVPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEEXTPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC)(GLsizei offset, GLsizei n, const GLuint * values); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEEXTPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEEXTPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLEXTPROC)(GLenum origin, GLenum depth); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKIEXTPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKIOESPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DOESPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATANVPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAEXTPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAOESPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DOESPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOVERAGEMASKNVPROC)(GLboolean mask); +typedef void (GLAD_API_PTR *PFNGLCOVERAGEOPERATIONNVPROC)(GLenum operation); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVEXTPROC)(GLenum type, GLsizei count, const GLchar *const* strings); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKKHRPROC)(GLDEBUGPROCKHR callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLKHRPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTKHRPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESEXTPROC)(GLsizei n, const GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESEXTPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYFVNVPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYFVOESPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDFNVPROC)(GLuint index, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDFOESPROC)(GLuint index, GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDISABLEIEXTPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEINVPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEIOESPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDANGLEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDNVPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSEXTPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSINDEXEDEXTPROC)(GLint n, const GLenum * location, const GLint * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSNVPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXOESPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDNVPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKEXTPROC)(GLenum mode, GLuint id); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC)(GLenum mode, GLuint id, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLENABLEIEXTPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEINVPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEIOESPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDQUERYEXTPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLEXTRAPOLATETEX2DQCOMPROC)(GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC)(GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint * providedFeatures); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC)(GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)(GLuint target, GLsizei size); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERSHADINGRATEEXTPROC)(GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DOESPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREOESPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESEXTPROC)(GLsizei n, GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESEXTPROC)(GLsizei n, GLuint * ids); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VNVPROC)(GLenum target, GLuint index, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VOESPROC)(GLenum target, GLuint index, GLfloat * data); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXEXTPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAGMENTSHADINGRATESEXTPROC)(GLsizei samples, GLsizei maxCount, GLsizei * count, GLenum * shadingRates); +typedef GLsizei (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)(GLuint target); +typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VEXTPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VEXTPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELKHRPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVKHRPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYOESPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVEXTPROC)(GLuint pipeline, GLenum pname, GLint * params); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVEXTPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVEXTPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVEXTPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVEXTPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVOESPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVEXTPROC)(GLuint sampler, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVOESPROC)(GLuint sampler, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVOESPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVOESPROC)(GLenum target, GLenum pname, GLuint * params); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTUREHANDLEIMGPROC)(GLuint texture); +typedef GLuint64 (GLAD_API_PTR *PFNGLGETTEXTURESAMPLERHANDLEIMGPROC)(GLuint texture, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVKHRPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVKHRPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVKHRPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIEXTPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDINVPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIOESPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEEXTPROC)(GLuint pipeline); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYEXTPROC)(GLuint id); +typedef void (GLAD_API_PTR *PFNGLMAXACTIVESHADERCORESARMPROC)(GLuint count); +typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGOESPROC)(GLfloat value); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELKHRPROC)(const void * ptr, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIEXTPROC)(GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIOESPROC)(GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPOLYGONMODENVPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPKHRPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVEBOUNDINGBOXPROC)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVEBOUNDINGBOXEXTPROC)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVEBOUNDINGBOXOESPROC)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYOESPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLint length); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC)(GLuint program, GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC)(GLuint program, GLint location, GLsizei count, const GLuint64 * values); +typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPKHRPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTEREXTPROC)(GLuint id, GLenum target); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERINDEXEDEXTPROC)(GLenum src, GLint index); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERNVPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLREADNPIXELSKHRPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVEXTPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVOESPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVEXTPROC)(GLuint sampler, GLenum pname, const GLuint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVOESPROC)(GLuint sampler, GLenum pname, const GLuint * param); +typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVNVPROC)(GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVOESPROC)(GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDNVPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDOESPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVNVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVOESPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATECOMBINEROPSEXTPROC)(GLenum combinerOp0, GLenum combinerOp1); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATEEXTPROC)(GLenum rate); +typedef void (GLAD_API_PTR *PFNGLSHADINGRATEQCOMPROC)(GLenum rate); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFEROESPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEEXTPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEOESPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXESTIMATEMOTIONQCOMPROC)(GLuint ref, GLuint target, GLuint output); +typedef void (GLAD_API_PTR *PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC)(GLuint ref, GLuint target, GLuint output, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DOESPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXPAGECOMMITMENTEXTPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVOESPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVOESPROC)(GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEATTRIBS2DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, const GLint * attrib_list); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEATTRIBS3DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const GLint * attrib_list); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DOESPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC)(GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWEXTPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWOESPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64IMGPROC)(GLint location, GLuint64 value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMHANDLEUI64VIMGPROC)(GLint location, GLsizei count, const GLuint64 * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVNVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESEXTPROC)(GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEEXTPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORANGLEPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISOREXTPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORNVPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVNVPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVOESPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFNVPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFOESPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVNVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVOESPROC)(GLuint index, const GLfloat * v); + +GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; +#define glAccum glad_glAccum +GLAD_API_CALL PFNGLACCUMXOESPROC glad_glAccumxOES; +#define glAccumxOES glad_glAccumxOES +GLAD_API_CALL PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT; +#define glAcquireKeyedMutexWin32EXT glad_glAcquireKeyedMutexWin32EXT +GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; +#define glActiveShaderProgram glad_glActiveShaderProgram +GLAD_API_CALL PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT; +#define glActiveStencilFaceEXT glad_glActiveStencilFaceEXT +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB; +#define glActiveTextureARB glad_glActiveTextureARB +GLAD_API_CALL PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV; +#define glActiveVaryingNV glad_glActiveVaryingNV +GLAD_API_CALL PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI; +#define glAlphaFragmentOp1ATI glad_glAlphaFragmentOp1ATI +GLAD_API_CALL PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI; +#define glAlphaFragmentOp2ATI glad_glAlphaFragmentOp2ATI +GLAD_API_CALL PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI; +#define glAlphaFragmentOp3ATI glad_glAlphaFragmentOp3ATI +GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; +#define glAlphaFunc glad_glAlphaFunc +GLAD_API_CALL PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES; +#define glAlphaFuncxOES glad_glAlphaFuncxOES +GLAD_API_CALL PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV; +#define glAlphaToCoverageDitherControlNV glad_glAlphaToCoverageDitherControlNV +GLAD_API_CALL PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL; +#define glApplyFramebufferAttachmentCMAAINTEL glad_glApplyFramebufferAttachmentCMAAINTEL +GLAD_API_CALL PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT; +#define glApplyTextureEXT glad_glApplyTextureEXT +GLAD_API_CALL PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV; +#define glAreProgramsResidentNV glad_glAreProgramsResidentNV +GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; +#define glAreTexturesResident glad_glAreTexturesResident +GLAD_API_CALL PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT; +#define glAreTexturesResidentEXT glad_glAreTexturesResidentEXT +GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; +#define glArrayElement glad_glArrayElement +GLAD_API_CALL PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT; +#define glArrayElementEXT glad_glArrayElementEXT +GLAD_API_CALL PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI; +#define glArrayObjectATI glad_glArrayObjectATI +GLAD_API_CALL PFNGLASYNCCOPYBUFFERSUBDATANVXPROC glad_glAsyncCopyBufferSubDataNVX; +#define glAsyncCopyBufferSubDataNVX glad_glAsyncCopyBufferSubDataNVX +GLAD_API_CALL PFNGLASYNCCOPYIMAGESUBDATANVXPROC glad_glAsyncCopyImageSubDataNVX; +#define glAsyncCopyImageSubDataNVX glad_glAsyncCopyImageSubDataNVX +GLAD_API_CALL PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX; +#define glAsyncMarkerSGIX glad_glAsyncMarkerSGIX +GLAD_API_CALL PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB; +#define glAttachObjectARB glad_glAttachObjectARB +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBEGINPROC glad_glBegin; +#define glBegin glad_glBegin +GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV; +#define glBeginConditionalRenderNV glad_glBeginConditionalRenderNV +GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX; +#define glBeginConditionalRenderNVX glad_glBeginConditionalRenderNVX +GLAD_API_CALL PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI; +#define glBeginFragmentShaderATI glad_glBeginFragmentShaderATI +GLAD_API_CALL PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV; +#define glBeginOcclusionQueryNV glad_glBeginOcclusionQueryNV +GLAD_API_CALL PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD; +#define glBeginPerfMonitorAMD glad_glBeginPerfMonitorAMD +GLAD_API_CALL PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL; +#define glBeginPerfQueryINTEL glad_glBeginPerfQueryINTEL +GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +GLAD_API_CALL PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB; +#define glBeginQueryARB glad_glBeginQueryARB +GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; +#define glBeginQueryIndexed glad_glBeginQueryIndexed +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT; +#define glBeginTransformFeedbackEXT glad_glBeginTransformFeedbackEXT +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV; +#define glBeginTransformFeedbackNV glad_glBeginTransformFeedbackNV +GLAD_API_CALL PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT; +#define glBeginVertexShaderEXT glad_glBeginVertexShaderEXT +GLAD_API_CALL PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV; +#define glBeginVideoCaptureNV glad_glBeginVideoCaptureNV +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB; +#define glBindAttribLocationARB glad_glBindAttribLocationARB +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDBUFFERARBPROC glad_glBindBufferARB; +#define glBindBufferARB glad_glBindBufferARB +GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +GLAD_API_CALL PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT; +#define glBindBufferBaseEXT glad_glBindBufferBaseEXT +GLAD_API_CALL PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV; +#define glBindBufferBaseNV glad_glBindBufferBaseNV +GLAD_API_CALL PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT; +#define glBindBufferOffsetEXT glad_glBindBufferOffsetEXT +GLAD_API_CALL PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV; +#define glBindBufferOffsetNV glad_glBindBufferOffsetNV +GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +GLAD_API_CALL PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT; +#define glBindBufferRangeEXT glad_glBindBufferRangeEXT +GLAD_API_CALL PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV; +#define glBindBufferRangeNV glad_glBindBufferRangeNV +GLAD_API_CALL PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; +#define glBindBuffersBase glad_glBindBuffersBase +GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; +#define glBindBuffersRange glad_glBindBuffersRange +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT; +#define glBindFragDataLocationEXT glad_glBindFragDataLocationEXT +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; +#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed +GLAD_API_CALL PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI; +#define glBindFragmentShaderATI glad_glBindFragmentShaderATI +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; +#define glBindFramebufferEXT glad_glBindFramebufferEXT +GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; +#define glBindImageTexture glad_glBindImageTexture +GLAD_API_CALL PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT; +#define glBindImageTextureEXT glad_glBindImageTextureEXT +GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; +#define glBindImageTextures glad_glBindImageTextures +GLAD_API_CALL PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT; +#define glBindLightParameterEXT glad_glBindLightParameterEXT +GLAD_API_CALL PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT; +#define glBindMaterialParameterEXT glad_glBindMaterialParameterEXT +GLAD_API_CALL PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT; +#define glBindMultiTextureEXT glad_glBindMultiTextureEXT +GLAD_API_CALL PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT; +#define glBindParameterEXT glad_glBindParameterEXT +GLAD_API_CALL PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB; +#define glBindProgramARB glad_glBindProgramARB +GLAD_API_CALL PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV; +#define glBindProgramNV glad_glBindProgramNV +GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; +#define glBindProgramPipeline glad_glBindProgramPipeline +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; +#define glBindRenderbufferEXT glad_glBindRenderbufferEXT +GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers; +#define glBindSamplers glad_glBindSamplers +GLAD_API_CALL PFNGLBINDSHADINGRATEIMAGENVPROC glad_glBindShadingRateImageNV; +#define glBindShadingRateImageNV glad_glBindShadingRateImageNV +GLAD_API_CALL PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT; +#define glBindTexGenParameterEXT glad_glBindTexGenParameterEXT +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT; +#define glBindTextureEXT glad_glBindTextureEXT +GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; +#define glBindTextureUnit glad_glBindTextureUnit +GLAD_API_CALL PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT; +#define glBindTextureUnitParameterEXT glad_glBindTextureUnitParameterEXT +GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures; +#define glBindTextures glad_glBindTextures +GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; +#define glBindTransformFeedback glad_glBindTransformFeedback +GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV; +#define glBindTransformFeedbackNV glad_glBindTransformFeedbackNV +GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +GLAD_API_CALL PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE; +#define glBindVertexArrayAPPLE glad_glBindVertexArrayAPPLE +GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; +#define glBindVertexBuffer glad_glBindVertexBuffer +GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; +#define glBindVertexBuffers glad_glBindVertexBuffers +GLAD_API_CALL PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT; +#define glBindVertexShaderEXT glad_glBindVertexShaderEXT +GLAD_API_CALL PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV; +#define glBindVideoCaptureStreamBufferNV glad_glBindVideoCaptureStreamBufferNV +GLAD_API_CALL PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV; +#define glBindVideoCaptureStreamTextureNV glad_glBindVideoCaptureStreamTextureNV +GLAD_API_CALL PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT; +#define glBinormal3bEXT glad_glBinormal3bEXT +GLAD_API_CALL PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT; +#define glBinormal3bvEXT glad_glBinormal3bvEXT +GLAD_API_CALL PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT; +#define glBinormal3dEXT glad_glBinormal3dEXT +GLAD_API_CALL PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT; +#define glBinormal3dvEXT glad_glBinormal3dvEXT +GLAD_API_CALL PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT; +#define glBinormal3fEXT glad_glBinormal3fEXT +GLAD_API_CALL PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT; +#define glBinormal3fvEXT glad_glBinormal3fvEXT +GLAD_API_CALL PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT; +#define glBinormal3iEXT glad_glBinormal3iEXT +GLAD_API_CALL PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT; +#define glBinormal3ivEXT glad_glBinormal3ivEXT +GLAD_API_CALL PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT; +#define glBinormal3sEXT glad_glBinormal3sEXT +GLAD_API_CALL PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT; +#define glBinormal3svEXT glad_glBinormal3svEXT +GLAD_API_CALL PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT; +#define glBinormalPointerEXT glad_glBinormalPointerEXT +GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; +#define glBitmap glad_glBitmap +GLAD_API_CALL PFNGLBITMAPXOESPROC glad_glBitmapxOES; +#define glBitmapxOES glad_glBitmapxOES +GLAD_API_CALL PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; +#define glBlendBarrierKHR glad_glBlendBarrierKHR +GLAD_API_CALL PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV; +#define glBlendBarrierNV glad_glBlendBarrierNV +GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +GLAD_API_CALL PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT; +#define glBlendColorEXT glad_glBlendColorEXT +GLAD_API_CALL PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES; +#define glBlendColorxOES glad_glBlendColorxOES +GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +GLAD_API_CALL PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT; +#define glBlendEquationEXT glad_glBlendEquationEXT +GLAD_API_CALL PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD; +#define glBlendEquationIndexedAMD glad_glBlendEquationIndexedAMD +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT; +#define glBlendEquationSeparateEXT glad_glBlendEquationSeparateEXT +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; +#define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei; +#define glBlendEquationSeparatei glad_glBlendEquationSeparatei +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB; +#define glBlendEquationSeparateiARB glad_glBlendEquationSeparateiARB +GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi; +#define glBlendEquationi glad_glBlendEquationi +GLAD_API_CALL PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB; +#define glBlendEquationiARB glad_glBlendEquationiARB +GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +GLAD_API_CALL PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD; +#define glBlendFuncIndexedAMD glad_glBlendFuncIndexedAMD +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT; +#define glBlendFuncSeparateEXT glad_glBlendFuncSeparateEXT +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR; +#define glBlendFuncSeparateINGR glad_glBlendFuncSeparateINGR +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD; +#define glBlendFuncSeparateIndexedAMD glad_glBlendFuncSeparateIndexedAMD +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei; +#define glBlendFuncSeparatei glad_glBlendFuncSeparatei +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB; +#define glBlendFuncSeparateiARB glad_glBlendFuncSeparateiARB +GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci; +#define glBlendFunci glad_glBlendFunci +GLAD_API_CALL PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB; +#define glBlendFunciARB glad_glBlendFunciARB +GLAD_API_CALL PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV; +#define glBlendParameteriNV glad_glBlendParameteriNV +GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +GLAD_API_CALL PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; +#define glBlitFramebufferEXT glad_glBlitFramebufferEXT +GLAD_API_CALL PFNGLBLITFRAMEBUFFERLAYEREXTPROC glad_glBlitFramebufferLayerEXT; +#define glBlitFramebufferLayerEXT glad_glBlitFramebufferLayerEXT +GLAD_API_CALL PFNGLBLITFRAMEBUFFERLAYERSEXTPROC glad_glBlitFramebufferLayersEXT; +#define glBlitFramebufferLayersEXT glad_glBlitFramebufferLayersEXT +GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; +#define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer +GLAD_API_CALL PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV; +#define glBufferAddressRangeNV glad_glBufferAddressRangeNV +GLAD_API_CALL PFNGLBUFFERATTACHMEMORYNVPROC glad_glBufferAttachMemoryNV; +#define glBufferAttachMemoryNV glad_glBufferAttachMemoryNV +GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +GLAD_API_CALL PFNGLBUFFERDATAARBPROC glad_glBufferDataARB; +#define glBufferDataARB glad_glBufferDataARB +GLAD_API_CALL PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB; +#define glBufferPageCommitmentARB glad_glBufferPageCommitmentARB +GLAD_API_CALL PFNGLBUFFERPAGECOMMITMENTMEMNVPROC glad_glBufferPageCommitmentMemNV; +#define glBufferPageCommitmentMemNV glad_glBufferPageCommitmentMemNV +GLAD_API_CALL PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE; +#define glBufferParameteriAPPLE glad_glBufferParameteriAPPLE +GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; +#define glBufferStorage glad_glBufferStorage +GLAD_API_CALL PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT; +#define glBufferStorageExternalEXT glad_glBufferStorageExternalEXT +GLAD_API_CALL PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT; +#define glBufferStorageMemEXT glad_glBufferStorageMemEXT +GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +GLAD_API_CALL PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB; +#define glBufferSubDataARB glad_glBufferSubDataARB +GLAD_API_CALL PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV; +#define glCallCommandListNV glad_glCallCommandListNV +GLAD_API_CALL PFNGLCALLLISTPROC glad_glCallList; +#define glCallList glad_glCallList +GLAD_API_CALL PFNGLCALLLISTSPROC glad_glCallLists; +#define glCallLists glad_glCallLists +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; +#define glCheckFramebufferStatusEXT glad_glCheckFramebufferStatusEXT +GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; +#define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus +GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT; +#define glCheckNamedFramebufferStatusEXT glad_glCheckNamedFramebufferStatusEXT +GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +GLAD_API_CALL PFNGLCLAMPCOLORARBPROC glad_glClampColorARB; +#define glClampColorARB glad_glClampColorARB +GLAD_API_CALL PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; +#define glClearAccum glad_glClearAccum +GLAD_API_CALL PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES; +#define glClearAccumxOES glad_glClearAccumxOES +GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; +#define glClearBufferData glad_glClearBufferData +GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; +#define glClearBufferSubData glad_glClearBufferSubData +GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +GLAD_API_CALL PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT; +#define glClearColorIiEXT glad_glClearColorIiEXT +GLAD_API_CALL PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT; +#define glClearColorIuiEXT glad_glClearColorIuiEXT +GLAD_API_CALL PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES; +#define glClearColorxOES glad_glClearColorxOES +GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +GLAD_API_CALL PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV; +#define glClearDepthdNV glad_glClearDepthdNV +GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; +#define glClearDepthf glad_glClearDepthf +GLAD_API_CALL PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES; +#define glClearDepthfOES glad_glClearDepthfOES +GLAD_API_CALL PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES; +#define glClearDepthxOES glad_glClearDepthxOES +GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; +#define glClearIndex glad_glClearIndex +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; +#define glClearNamedBufferData glad_glClearNamedBufferData +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT; +#define glClearNamedBufferDataEXT glad_glClearNamedBufferDataEXT +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; +#define glClearNamedBufferSubData glad_glClearNamedBufferSubData +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT; +#define glClearNamedBufferSubDataEXT glad_glClearNamedBufferSubDataEXT +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; +#define glClearNamedFramebufferfi glad_glClearNamedFramebufferfi +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; +#define glClearNamedFramebufferfv glad_glClearNamedFramebufferfv +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; +#define glClearNamedFramebufferiv glad_glClearNamedFramebufferiv +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; +#define glClearNamedFramebufferuiv glad_glClearNamedFramebufferuiv +GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; +#define glClearTexImage glad_glClearTexImage +GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; +#define glClearTexSubImage glad_glClearTexSubImage +GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; +#define glClientActiveTexture glad_glClientActiveTexture +GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB; +#define glClientActiveTextureARB glad_glClientActiveTextureARB +GLAD_API_CALL PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI; +#define glClientActiveVertexStreamATI glad_glClientActiveVertexStreamATI +GLAD_API_CALL PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT; +#define glClientAttribDefaultEXT glad_glClientAttribDefaultEXT +GLAD_API_CALL PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC glad_glClientWaitSemaphoreui64NVX; +#define glClientWaitSemaphoreui64NVX glad_glClientWaitSemaphoreui64NVX +GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl; +#define glClipControl glad_glClipControl +GLAD_API_CALL PFNGLCLIPPLANEPROC glad_glClipPlane; +#define glClipPlane glad_glClipPlane +GLAD_API_CALL PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES; +#define glClipPlanefOES glad_glClipPlanefOES +GLAD_API_CALL PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES; +#define glClipPlanexOES glad_glClipPlanexOES +GLAD_API_CALL PFNGLCOLOR3BPROC glad_glColor3b; +#define glColor3b glad_glColor3b +GLAD_API_CALL PFNGLCOLOR3BVPROC glad_glColor3bv; +#define glColor3bv glad_glColor3bv +GLAD_API_CALL PFNGLCOLOR3DPROC glad_glColor3d; +#define glColor3d glad_glColor3d +GLAD_API_CALL PFNGLCOLOR3DVPROC glad_glColor3dv; +#define glColor3dv glad_glColor3dv +GLAD_API_CALL PFNGLCOLOR3FPROC glad_glColor3f; +#define glColor3f glad_glColor3f +GLAD_API_CALL PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN; +#define glColor3fVertex3fSUN glad_glColor3fVertex3fSUN +GLAD_API_CALL PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN; +#define glColor3fVertex3fvSUN glad_glColor3fVertex3fvSUN +GLAD_API_CALL PFNGLCOLOR3FVPROC glad_glColor3fv; +#define glColor3fv glad_glColor3fv +GLAD_API_CALL PFNGLCOLOR3HNVPROC glad_glColor3hNV; +#define glColor3hNV glad_glColor3hNV +GLAD_API_CALL PFNGLCOLOR3HVNVPROC glad_glColor3hvNV; +#define glColor3hvNV glad_glColor3hvNV +GLAD_API_CALL PFNGLCOLOR3IPROC glad_glColor3i; +#define glColor3i glad_glColor3i +GLAD_API_CALL PFNGLCOLOR3IVPROC glad_glColor3iv; +#define glColor3iv glad_glColor3iv +GLAD_API_CALL PFNGLCOLOR3SPROC glad_glColor3s; +#define glColor3s glad_glColor3s +GLAD_API_CALL PFNGLCOLOR3SVPROC glad_glColor3sv; +#define glColor3sv glad_glColor3sv +GLAD_API_CALL PFNGLCOLOR3UBPROC glad_glColor3ub; +#define glColor3ub glad_glColor3ub +GLAD_API_CALL PFNGLCOLOR3UBVPROC glad_glColor3ubv; +#define glColor3ubv glad_glColor3ubv +GLAD_API_CALL PFNGLCOLOR3UIPROC glad_glColor3ui; +#define glColor3ui glad_glColor3ui +GLAD_API_CALL PFNGLCOLOR3UIVPROC glad_glColor3uiv; +#define glColor3uiv glad_glColor3uiv +GLAD_API_CALL PFNGLCOLOR3USPROC glad_glColor3us; +#define glColor3us glad_glColor3us +GLAD_API_CALL PFNGLCOLOR3USVPROC glad_glColor3usv; +#define glColor3usv glad_glColor3usv +GLAD_API_CALL PFNGLCOLOR3XOESPROC glad_glColor3xOES; +#define glColor3xOES glad_glColor3xOES +GLAD_API_CALL PFNGLCOLOR3XVOESPROC glad_glColor3xvOES; +#define glColor3xvOES glad_glColor3xvOES +GLAD_API_CALL PFNGLCOLOR4BPROC glad_glColor4b; +#define glColor4b glad_glColor4b +GLAD_API_CALL PFNGLCOLOR4BVPROC glad_glColor4bv; +#define glColor4bv glad_glColor4bv +GLAD_API_CALL PFNGLCOLOR4DPROC glad_glColor4d; +#define glColor4d glad_glColor4d +GLAD_API_CALL PFNGLCOLOR4DVPROC glad_glColor4dv; +#define glColor4dv glad_glColor4dv +GLAD_API_CALL PFNGLCOLOR4FPROC glad_glColor4f; +#define glColor4f glad_glColor4f +GLAD_API_CALL PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN; +#define glColor4fNormal3fVertex3fSUN glad_glColor4fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN; +#define glColor4fNormal3fVertex3fvSUN glad_glColor4fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLCOLOR4FVPROC glad_glColor4fv; +#define glColor4fv glad_glColor4fv +GLAD_API_CALL PFNGLCOLOR4HNVPROC glad_glColor4hNV; +#define glColor4hNV glad_glColor4hNV +GLAD_API_CALL PFNGLCOLOR4HVNVPROC glad_glColor4hvNV; +#define glColor4hvNV glad_glColor4hvNV +GLAD_API_CALL PFNGLCOLOR4IPROC glad_glColor4i; +#define glColor4i glad_glColor4i +GLAD_API_CALL PFNGLCOLOR4IVPROC glad_glColor4iv; +#define glColor4iv glad_glColor4iv +GLAD_API_CALL PFNGLCOLOR4SPROC glad_glColor4s; +#define glColor4s glad_glColor4s +GLAD_API_CALL PFNGLCOLOR4SVPROC glad_glColor4sv; +#define glColor4sv glad_glColor4sv +GLAD_API_CALL PFNGLCOLOR4UBPROC glad_glColor4ub; +#define glColor4ub glad_glColor4ub +GLAD_API_CALL PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN; +#define glColor4ubVertex2fSUN glad_glColor4ubVertex2fSUN +GLAD_API_CALL PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN; +#define glColor4ubVertex2fvSUN glad_glColor4ubVertex2fvSUN +GLAD_API_CALL PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN; +#define glColor4ubVertex3fSUN glad_glColor4ubVertex3fSUN +GLAD_API_CALL PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN; +#define glColor4ubVertex3fvSUN glad_glColor4ubVertex3fvSUN +GLAD_API_CALL PFNGLCOLOR4UBVPROC glad_glColor4ubv; +#define glColor4ubv glad_glColor4ubv +GLAD_API_CALL PFNGLCOLOR4UIPROC glad_glColor4ui; +#define glColor4ui glad_glColor4ui +GLAD_API_CALL PFNGLCOLOR4UIVPROC glad_glColor4uiv; +#define glColor4uiv glad_glColor4uiv +GLAD_API_CALL PFNGLCOLOR4USPROC glad_glColor4us; +#define glColor4us glad_glColor4us +GLAD_API_CALL PFNGLCOLOR4USVPROC glad_glColor4usv; +#define glColor4usv glad_glColor4usv +GLAD_API_CALL PFNGLCOLOR4XOESPROC glad_glColor4xOES; +#define glColor4xOES glad_glColor4xOES +GLAD_API_CALL PFNGLCOLOR4XVOESPROC glad_glColor4xvOES; +#define glColor4xvOES glad_glColor4xvOES +GLAD_API_CALL PFNGLCOLORFORMATNVPROC glad_glColorFormatNV; +#define glColorFormatNV glad_glColorFormatNV +GLAD_API_CALL PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI; +#define glColorFragmentOp1ATI glad_glColorFragmentOp1ATI +GLAD_API_CALL PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI; +#define glColorFragmentOp2ATI glad_glColorFragmentOp2ATI +GLAD_API_CALL PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI; +#define glColorFragmentOp3ATI glad_glColorFragmentOp3ATI +GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +GLAD_API_CALL PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT; +#define glColorMaskIndexedEXT glad_glColorMaskIndexedEXT +GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +GLAD_API_CALL PFNGLCOLORMATERIALPROC glad_glColorMaterial; +#define glColorMaterial glad_glColorMaterial +GLAD_API_CALL PFNGLCOLORP3UIPROC glad_glColorP3ui; +#define glColorP3ui glad_glColorP3ui +GLAD_API_CALL PFNGLCOLORP3UIVPROC glad_glColorP3uiv; +#define glColorP3uiv glad_glColorP3uiv +GLAD_API_CALL PFNGLCOLORP4UIPROC glad_glColorP4ui; +#define glColorP4ui glad_glColorP4ui +GLAD_API_CALL PFNGLCOLORP4UIVPROC glad_glColorP4uiv; +#define glColorP4uiv glad_glColorP4uiv +GLAD_API_CALL PFNGLCOLORPOINTERPROC glad_glColorPointer; +#define glColorPointer glad_glColorPointer +GLAD_API_CALL PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT; +#define glColorPointerEXT glad_glColorPointerEXT +GLAD_API_CALL PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM; +#define glColorPointerListIBM glad_glColorPointerListIBM +GLAD_API_CALL PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL; +#define glColorPointervINTEL glad_glColorPointervINTEL +GLAD_API_CALL PFNGLCOLORSUBTABLEPROC glad_glColorSubTable; +#define glColorSubTable glad_glColorSubTable +GLAD_API_CALL PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT; +#define glColorSubTableEXT glad_glColorSubTableEXT +GLAD_API_CALL PFNGLCOLORTABLEPROC glad_glColorTable; +#define glColorTable glad_glColorTable +GLAD_API_CALL PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT; +#define glColorTableEXT glad_glColorTableEXT +GLAD_API_CALL PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv; +#define glColorTableParameterfv glad_glColorTableParameterfv +GLAD_API_CALL PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI; +#define glColorTableParameterfvSGI glad_glColorTableParameterfvSGI +GLAD_API_CALL PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv; +#define glColorTableParameteriv glad_glColorTableParameteriv +GLAD_API_CALL PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI; +#define glColorTableParameterivSGI glad_glColorTableParameterivSGI +GLAD_API_CALL PFNGLCOLORTABLESGIPROC glad_glColorTableSGI; +#define glColorTableSGI glad_glColorTableSGI +GLAD_API_CALL PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV; +#define glCombinerInputNV glad_glCombinerInputNV +GLAD_API_CALL PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV; +#define glCombinerOutputNV glad_glCombinerOutputNV +GLAD_API_CALL PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV; +#define glCombinerParameterfNV glad_glCombinerParameterfNV +GLAD_API_CALL PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV; +#define glCombinerParameterfvNV glad_glCombinerParameterfvNV +GLAD_API_CALL PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV; +#define glCombinerParameteriNV glad_glCombinerParameteriNV +GLAD_API_CALL PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV; +#define glCombinerParameterivNV glad_glCombinerParameterivNV +GLAD_API_CALL PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV; +#define glCombinerStageParameterfvNV glad_glCombinerStageParameterfvNV +GLAD_API_CALL PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV; +#define glCommandListSegmentsNV glad_glCommandListSegmentsNV +GLAD_API_CALL PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV; +#define glCompileCommandListNV glad_glCompileCommandListNV +GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +GLAD_API_CALL PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB; +#define glCompileShaderARB glad_glCompileShaderARB +GLAD_API_CALL PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB; +#define glCompileShaderIncludeARB glad_glCompileShaderIncludeARB +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT; +#define glCompressedMultiTexImage1DEXT glad_glCompressedMultiTexImage1DEXT +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT; +#define glCompressedMultiTexImage2DEXT glad_glCompressedMultiTexImage2DEXT +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT; +#define glCompressedMultiTexImage3DEXT glad_glCompressedMultiTexImage3DEXT +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT; +#define glCompressedMultiTexSubImage1DEXT glad_glCompressedMultiTexSubImage1DEXT +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT; +#define glCompressedMultiTexSubImage2DEXT glad_glCompressedMultiTexSubImage2DEXT +GLAD_API_CALL PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT; +#define glCompressedMultiTexSubImage3DEXT glad_glCompressedMultiTexSubImage3DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB; +#define glCompressedTexImage1DARB glad_glCompressedTexImage1DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB; +#define glCompressedTexImage2DARB glad_glCompressedTexImage2DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB; +#define glCompressedTexImage3DARB glad_glCompressedTexImage3DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB; +#define glCompressedTexSubImage1DARB glad_glCompressedTexSubImage1DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB; +#define glCompressedTexSubImage2DARB glad_glCompressedTexSubImage2DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB; +#define glCompressedTexSubImage3DARB glad_glCompressedTexSubImage3DARB +GLAD_API_CALL PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT; +#define glCompressedTextureImage1DEXT glad_glCompressedTextureImage1DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT; +#define glCompressedTextureImage2DEXT glad_glCompressedTextureImage2DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT; +#define glCompressedTextureImage3DEXT glad_glCompressedTextureImage3DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; +#define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT; +#define glCompressedTextureSubImage1DEXT glad_glCompressedTextureSubImage1DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; +#define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT; +#define glCompressedTextureSubImage2DEXT glad_glCompressedTextureSubImage2DEXT +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; +#define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT; +#define glCompressedTextureSubImage3DEXT glad_glCompressedTextureSubImage3DEXT +GLAD_API_CALL PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV; +#define glConservativeRasterParameterfNV glad_glConservativeRasterParameterfNV +GLAD_API_CALL PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV; +#define glConservativeRasterParameteriNV glad_glConservativeRasterParameteriNV +GLAD_API_CALL PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D; +#define glConvolutionFilter1D glad_glConvolutionFilter1D +GLAD_API_CALL PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT; +#define glConvolutionFilter1DEXT glad_glConvolutionFilter1DEXT +GLAD_API_CALL PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D; +#define glConvolutionFilter2D glad_glConvolutionFilter2D +GLAD_API_CALL PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT; +#define glConvolutionFilter2DEXT glad_glConvolutionFilter2DEXT +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf; +#define glConvolutionParameterf glad_glConvolutionParameterf +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT; +#define glConvolutionParameterfEXT glad_glConvolutionParameterfEXT +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv; +#define glConvolutionParameterfv glad_glConvolutionParameterfv +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT; +#define glConvolutionParameterfvEXT glad_glConvolutionParameterfvEXT +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri; +#define glConvolutionParameteri glad_glConvolutionParameteri +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT; +#define glConvolutionParameteriEXT glad_glConvolutionParameteriEXT +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv; +#define glConvolutionParameteriv glad_glConvolutionParameteriv +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT; +#define glConvolutionParameterivEXT glad_glConvolutionParameterivEXT +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES; +#define glConvolutionParameterxOES glad_glConvolutionParameterxOES +GLAD_API_CALL PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES; +#define glConvolutionParameterxvOES glad_glConvolutionParameterxvOES +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +GLAD_API_CALL PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable; +#define glCopyColorSubTable glad_glCopyColorSubTable +GLAD_API_CALL PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT; +#define glCopyColorSubTableEXT glad_glCopyColorSubTableEXT +GLAD_API_CALL PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable; +#define glCopyColorTable glad_glCopyColorTable +GLAD_API_CALL PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI; +#define glCopyColorTableSGI glad_glCopyColorTableSGI +GLAD_API_CALL PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D; +#define glCopyConvolutionFilter1D glad_glCopyConvolutionFilter1D +GLAD_API_CALL PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT; +#define glCopyConvolutionFilter1DEXT glad_glCopyConvolutionFilter1DEXT +GLAD_API_CALL PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D; +#define glCopyConvolutionFilter2D glad_glCopyConvolutionFilter2D +GLAD_API_CALL PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT; +#define glCopyConvolutionFilter2DEXT glad_glCopyConvolutionFilter2DEXT +GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; +#define glCopyImageSubData glad_glCopyImageSubData +GLAD_API_CALL PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV; +#define glCopyImageSubDataNV glad_glCopyImageSubDataNV +GLAD_API_CALL PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT; +#define glCopyMultiTexImage1DEXT glad_glCopyMultiTexImage1DEXT +GLAD_API_CALL PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT; +#define glCopyMultiTexImage2DEXT glad_glCopyMultiTexImage2DEXT +GLAD_API_CALL PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT; +#define glCopyMultiTexSubImage1DEXT glad_glCopyMultiTexSubImage1DEXT +GLAD_API_CALL PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT; +#define glCopyMultiTexSubImage2DEXT glad_glCopyMultiTexSubImage2DEXT +GLAD_API_CALL PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT; +#define glCopyMultiTexSubImage3DEXT glad_glCopyMultiTexSubImage3DEXT +GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; +#define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData +GLAD_API_CALL PFNGLCOPYPATHNVPROC glad_glCopyPathNV; +#define glCopyPathNV glad_glCopyPathNV +GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; +#define glCopyPixels glad_glCopyPixels +GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +GLAD_API_CALL PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT; +#define glCopyTexImage1DEXT glad_glCopyTexImage1DEXT +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT; +#define glCopyTexImage2DEXT glad_glCopyTexImage2DEXT +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT; +#define glCopyTexSubImage1DEXT glad_glCopyTexSubImage1DEXT +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT; +#define glCopyTexSubImage2DEXT glad_glCopyTexSubImage2DEXT +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT; +#define glCopyTexSubImage3DEXT glad_glCopyTexSubImage3DEXT +GLAD_API_CALL PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT; +#define glCopyTextureImage1DEXT glad_glCopyTextureImage1DEXT +GLAD_API_CALL PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT; +#define glCopyTextureImage2DEXT glad_glCopyTextureImage2DEXT +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; +#define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT; +#define glCopyTextureSubImage1DEXT glad_glCopyTextureSubImage1DEXT +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; +#define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT; +#define glCopyTextureSubImage2DEXT glad_glCopyTextureSubImage2DEXT +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; +#define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT; +#define glCopyTextureSubImage3DEXT glad_glCopyTextureSubImage3DEXT +GLAD_API_CALL PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV; +#define glCoverFillPathInstancedNV glad_glCoverFillPathInstancedNV +GLAD_API_CALL PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV; +#define glCoverFillPathNV glad_glCoverFillPathNV +GLAD_API_CALL PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV; +#define glCoverStrokePathInstancedNV glad_glCoverStrokePathInstancedNV +GLAD_API_CALL PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV; +#define glCoverStrokePathNV glad_glCoverStrokePathNV +GLAD_API_CALL PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV; +#define glCoverageModulationNV glad_glCoverageModulationNV +GLAD_API_CALL PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV; +#define glCoverageModulationTableNV glad_glCoverageModulationTableNV +GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; +#define glCreateBuffers glad_glCreateBuffers +GLAD_API_CALL PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV; +#define glCreateCommandListsNV glad_glCreateCommandListsNV +GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; +#define glCreateFramebuffers glad_glCreateFramebuffers +GLAD_API_CALL PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT; +#define glCreateMemoryObjectsEXT glad_glCreateMemoryObjectsEXT +GLAD_API_CALL PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL; +#define glCreatePerfQueryINTEL glad_glCreatePerfQueryINTEL +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB; +#define glCreateProgramObjectARB glad_glCreateProgramObjectARB +GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; +#define glCreateProgramPipelines glad_glCreateProgramPipelines +GLAD_API_CALL PFNGLCREATEPROGRESSFENCENVXPROC glad_glCreateProgressFenceNVX; +#define glCreateProgressFenceNVX glad_glCreateProgressFenceNVX +GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries; +#define glCreateQueries glad_glCreateQueries +GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; +#define glCreateRenderbuffers glad_glCreateRenderbuffers +GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; +#define glCreateSamplers glad_glCreateSamplers +GLAD_API_CALL PFNGLCREATESEMAPHORESNVPROC glad_glCreateSemaphoresNV; +#define glCreateSemaphoresNV glad_glCreateSemaphoresNV +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB; +#define glCreateShaderObjectARB glad_glCreateShaderObjectARB +GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; +#define glCreateShaderProgramv glad_glCreateShaderProgramv +GLAD_API_CALL PFNGLCREATESTATESNVPROC glad_glCreateStatesNV; +#define glCreateStatesNV glad_glCreateStatesNV +GLAD_API_CALL PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB; +#define glCreateSyncFromCLeventARB glad_glCreateSyncFromCLeventARB +GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures; +#define glCreateTextures glad_glCreateTextures +GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; +#define glCreateTransformFeedbacks glad_glCreateTransformFeedbacks +GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; +#define glCreateVertexArrays glad_glCreateVertexArrays +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT; +#define glCullParameterdvEXT glad_glCullParameterdvEXT +GLAD_API_CALL PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT; +#define glCullParameterfvEXT glad_glCullParameterfvEXT +GLAD_API_CALL PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB; +#define glCurrentPaletteMatrixARB glad_glCurrentPaletteMatrixARB +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; +#define glDebugMessageCallback glad_glDebugMessageCallback +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD; +#define glDebugMessageCallbackAMD glad_glDebugMessageCallbackAMD +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; +#define glDebugMessageCallbackARB glad_glDebugMessageCallbackARB +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; +#define glDebugMessageControl glad_glDebugMessageControl +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; +#define glDebugMessageControlARB glad_glDebugMessageControlARB +GLAD_API_CALL PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD; +#define glDebugMessageEnableAMD glad_glDebugMessageEnableAMD +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; +#define glDebugMessageInsert glad_glDebugMessageInsert +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD; +#define glDebugMessageInsertAMD glad_glDebugMessageInsertAMD +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; +#define glDebugMessageInsertARB glad_glDebugMessageInsertARB +GLAD_API_CALL PFNGLDEFORMSGIXPROC glad_glDeformSGIX; +#define glDeformSGIX glad_glDeformSGIX +GLAD_API_CALL PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX; +#define glDeformationMap3dSGIX glad_glDeformationMap3dSGIX +GLAD_API_CALL PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX; +#define glDeformationMap3fSGIX glad_glDeformationMap3fSGIX +GLAD_API_CALL PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX; +#define glDeleteAsyncMarkersSGIX glad_glDeleteAsyncMarkersSGIX +GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +GLAD_API_CALL PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB; +#define glDeleteBuffersARB glad_glDeleteBuffersARB +GLAD_API_CALL PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV; +#define glDeleteCommandListsNV glad_glDeleteCommandListsNV +GLAD_API_CALL PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE; +#define glDeleteFencesAPPLE glad_glDeleteFencesAPPLE +GLAD_API_CALL PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV; +#define glDeleteFencesNV glad_glDeleteFencesNV +GLAD_API_CALL PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI; +#define glDeleteFragmentShaderATI glad_glDeleteFragmentShaderATI +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; +#define glDeleteFramebuffersEXT glad_glDeleteFramebuffersEXT +GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; +#define glDeleteLists glad_glDeleteLists +GLAD_API_CALL PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT; +#define glDeleteMemoryObjectsEXT glad_glDeleteMemoryObjectsEXT +GLAD_API_CALL PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB; +#define glDeleteNamedStringARB glad_glDeleteNamedStringARB +GLAD_API_CALL PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD; +#define glDeleteNamesAMD glad_glDeleteNamesAMD +GLAD_API_CALL PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB; +#define glDeleteObjectARB glad_glDeleteObjectARB +GLAD_API_CALL PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV; +#define glDeleteOcclusionQueriesNV glad_glDeleteOcclusionQueriesNV +GLAD_API_CALL PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV; +#define glDeletePathsNV glad_glDeletePathsNV +GLAD_API_CALL PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD; +#define glDeletePerfMonitorsAMD glad_glDeletePerfMonitorsAMD +GLAD_API_CALL PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL; +#define glDeletePerfQueryINTEL glad_glDeletePerfQueryINTEL +GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; +#define glDeleteProgramPipelines glad_glDeleteProgramPipelines +GLAD_API_CALL PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB; +#define glDeleteProgramsARB glad_glDeleteProgramsARB +GLAD_API_CALL PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV; +#define glDeleteProgramsNV glad_glDeleteProgramsNV +GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +GLAD_API_CALL PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB; +#define glDeleteQueriesARB glad_glDeleteQueriesARB +GLAD_API_CALL PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV; +#define glDeleteQueryResourceTagNV glad_glDeleteQueryResourceTagNV +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; +#define glDeleteRenderbuffersEXT glad_glDeleteRenderbuffersEXT +GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +GLAD_API_CALL PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT; +#define glDeleteSemaphoresEXT glad_glDeleteSemaphoresEXT +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV; +#define glDeleteStatesNV glad_glDeleteStatesNV +GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT; +#define glDeleteTexturesEXT glad_glDeleteTexturesEXT +GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; +#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks +GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV; +#define glDeleteTransformFeedbacksNV glad_glDeleteTransformFeedbacksNV +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE; +#define glDeleteVertexArraysAPPLE glad_glDeleteVertexArraysAPPLE +GLAD_API_CALL PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT; +#define glDeleteVertexShaderEXT glad_glDeleteVertexShaderEXT +GLAD_API_CALL PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT; +#define glDepthBoundsEXT glad_glDepthBoundsEXT +GLAD_API_CALL PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV; +#define glDepthBoundsdNV glad_glDepthBoundsdNV +GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +GLAD_API_CALL PFNGLDEPTHRANGEARRAYDVNVPROC glad_glDepthRangeArraydvNV; +#define glDepthRangeArraydvNV glad_glDepthRangeArraydvNV +GLAD_API_CALL PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; +#define glDepthRangeArrayv glad_glDepthRangeArrayv +GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; +#define glDepthRangeIndexed glad_glDepthRangeIndexed +GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV; +#define glDepthRangeIndexeddNV glad_glDepthRangeIndexeddNV +GLAD_API_CALL PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV; +#define glDepthRangedNV glad_glDepthRangedNV +GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; +#define glDepthRangef glad_glDepthRangef +GLAD_API_CALL PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES; +#define glDepthRangefOES glad_glDepthRangefOES +GLAD_API_CALL PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES; +#define glDepthRangexOES glad_glDepthRangexOES +GLAD_API_CALL PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB; +#define glDetachObjectARB glad_glDetachObjectARB +GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +GLAD_API_CALL PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS; +#define glDetailTexFuncSGIS glad_glDetailTexFuncSGIS +GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; +#define glDisableClientState glad_glDisableClientState +GLAD_API_CALL PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT; +#define glDisableClientStateIndexedEXT glad_glDisableClientStateIndexedEXT +GLAD_API_CALL PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT; +#define glDisableClientStateiEXT glad_glDisableClientStateiEXT +GLAD_API_CALL PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT; +#define glDisableIndexedEXT glad_glDisableIndexedEXT +GLAD_API_CALL PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT; +#define glDisableVariantClientStateEXT glad_glDisableVariantClientStateEXT +GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; +#define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib +GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT; +#define glDisableVertexArrayAttribEXT glad_glDisableVertexArrayAttribEXT +GLAD_API_CALL PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT; +#define glDisableVertexArrayEXT glad_glDisableVertexArrayEXT +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE; +#define glDisableVertexAttribAPPLE glad_glDisableVertexAttribAPPLE +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB; +#define glDisableVertexAttribArrayARB glad_glDisableVertexAttribArrayARB +GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; +#define glDispatchCompute glad_glDispatchCompute +GLAD_API_CALL PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB; +#define glDispatchComputeGroupSizeARB glad_glDispatchComputeGroupSizeARB +GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; +#define glDispatchComputeIndirect glad_glDispatchComputeIndirect +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT; +#define glDrawArraysEXT glad_glDrawArraysEXT +GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; +#define glDrawArraysIndirect glad_glDrawArraysIndirect +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB; +#define glDrawArraysInstancedARB glad_glDrawArraysInstancedARB +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; +#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT; +#define glDrawArraysInstancedEXT glad_glDrawArraysInstancedEXT +GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +GLAD_API_CALL PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB; +#define glDrawBuffersARB glad_glDrawBuffersARB +GLAD_API_CALL PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI; +#define glDrawBuffersATI glad_glDrawBuffersATI +GLAD_API_CALL PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV; +#define glDrawCommandsAddressNV glad_glDrawCommandsAddressNV +GLAD_API_CALL PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV; +#define glDrawCommandsNV glad_glDrawCommandsNV +GLAD_API_CALL PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV; +#define glDrawCommandsStatesAddressNV glad_glDrawCommandsStatesAddressNV +GLAD_API_CALL PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV; +#define glDrawCommandsStatesNV glad_glDrawCommandsStatesNV +GLAD_API_CALL PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE; +#define glDrawElementArrayAPPLE glad_glDrawElementArrayAPPLE +GLAD_API_CALL PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI; +#define glDrawElementArrayATI glad_glDrawElementArrayATI +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; +#define glDrawElementsIndirect glad_glDrawElementsIndirect +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB; +#define glDrawElementsInstancedARB glad_glDrawElementsInstancedARB +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; +#define glDrawElementsInstancedBaseInstance glad_glDrawElementsInstancedBaseInstance +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; +#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT; +#define glDrawElementsInstancedEXT glad_glDrawElementsInstancedEXT +GLAD_API_CALL PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN; +#define glDrawMeshArraysSUN glad_glDrawMeshArraysSUN +GLAD_API_CALL PFNGLDRAWMESHTASKSINDIRECTNVPROC glad_glDrawMeshTasksIndirectNV; +#define glDrawMeshTasksIndirectNV glad_glDrawMeshTasksIndirectNV +GLAD_API_CALL PFNGLDRAWMESHTASKSNVPROC glad_glDrawMeshTasksNV; +#define glDrawMeshTasksNV glad_glDrawMeshTasksNV +GLAD_API_CALL PFNGLDRAWPIXELSPROC glad_glDrawPixels; +#define glDrawPixels glad_glDrawPixels +GLAD_API_CALL PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE; +#define glDrawRangeElementArrayAPPLE glad_glDrawRangeElementArrayAPPLE +GLAD_API_CALL PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI; +#define glDrawRangeElementArrayATI glad_glDrawRangeElementArrayATI +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT; +#define glDrawRangeElementsEXT glad_glDrawRangeElementsEXT +GLAD_API_CALL PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV; +#define glDrawTextureNV glad_glDrawTextureNV +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; +#define glDrawTransformFeedback glad_glDrawTransformFeedback +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; +#define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV; +#define glDrawTransformFeedbackNV glad_glDrawTransformFeedbackNV +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; +#define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; +#define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced +GLAD_API_CALL PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV; +#define glDrawVkImageNV glad_glDrawVkImageNV +GLAD_API_CALL PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT; +#define glEGLImageTargetTexStorageEXT glad_glEGLImageTargetTexStorageEXT +GLAD_API_CALL PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT; +#define glEGLImageTargetTextureStorageEXT glad_glEGLImageTargetTextureStorageEXT +GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; +#define glEdgeFlag glad_glEdgeFlag +GLAD_API_CALL PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV; +#define glEdgeFlagFormatNV glad_glEdgeFlagFormatNV +GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; +#define glEdgeFlagPointer glad_glEdgeFlagPointer +GLAD_API_CALL PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT; +#define glEdgeFlagPointerEXT glad_glEdgeFlagPointerEXT +GLAD_API_CALL PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM; +#define glEdgeFlagPointerListIBM glad_glEdgeFlagPointerListIBM +GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; +#define glEdgeFlagv glad_glEdgeFlagv +GLAD_API_CALL PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE; +#define glElementPointerAPPLE glad_glElementPointerAPPLE +GLAD_API_CALL PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI; +#define glElementPointerATI glad_glElementPointerATI +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; +#define glEnableClientState glad_glEnableClientState +GLAD_API_CALL PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT; +#define glEnableClientStateIndexedEXT glad_glEnableClientStateIndexedEXT +GLAD_API_CALL PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT; +#define glEnableClientStateiEXT glad_glEnableClientStateiEXT +GLAD_API_CALL PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT; +#define glEnableIndexedEXT glad_glEnableIndexedEXT +GLAD_API_CALL PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT; +#define glEnableVariantClientStateEXT glad_glEnableVariantClientStateEXT +GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; +#define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib +GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT; +#define glEnableVertexArrayAttribEXT glad_glEnableVertexArrayAttribEXT +GLAD_API_CALL PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT; +#define glEnableVertexArrayEXT glad_glEnableVertexArrayEXT +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE; +#define glEnableVertexAttribAPPLE glad_glEnableVertexAttribAPPLE +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB; +#define glEnableVertexAttribArrayARB glad_glEnableVertexAttribArrayARB +GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +GLAD_API_CALL PFNGLENDPROC glad_glEnd; +#define glEnd glad_glEnd +GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +GLAD_API_CALL PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV; +#define glEndConditionalRenderNV glad_glEndConditionalRenderNV +GLAD_API_CALL PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX; +#define glEndConditionalRenderNVX glad_glEndConditionalRenderNVX +GLAD_API_CALL PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI; +#define glEndFragmentShaderATI glad_glEndFragmentShaderATI +GLAD_API_CALL PFNGLENDLISTPROC glad_glEndList; +#define glEndList glad_glEndList +GLAD_API_CALL PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV; +#define glEndOcclusionQueryNV glad_glEndOcclusionQueryNV +GLAD_API_CALL PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD; +#define glEndPerfMonitorAMD glad_glEndPerfMonitorAMD +GLAD_API_CALL PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL; +#define glEndPerfQueryINTEL glad_glEndPerfQueryINTEL +GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +GLAD_API_CALL PFNGLENDQUERYARBPROC glad_glEndQueryARB; +#define glEndQueryARB glad_glEndQueryARB +GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; +#define glEndQueryIndexed glad_glEndQueryIndexed +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT; +#define glEndTransformFeedbackEXT glad_glEndTransformFeedbackEXT +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV; +#define glEndTransformFeedbackNV glad_glEndTransformFeedbackNV +GLAD_API_CALL PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT; +#define glEndVertexShaderEXT glad_glEndVertexShaderEXT +GLAD_API_CALL PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV; +#define glEndVideoCaptureNV glad_glEndVideoCaptureNV +GLAD_API_CALL PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; +#define glEvalCoord1d glad_glEvalCoord1d +GLAD_API_CALL PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; +#define glEvalCoord1dv glad_glEvalCoord1dv +GLAD_API_CALL PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; +#define glEvalCoord1f glad_glEvalCoord1f +GLAD_API_CALL PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; +#define glEvalCoord1fv glad_glEvalCoord1fv +GLAD_API_CALL PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES; +#define glEvalCoord1xOES glad_glEvalCoord1xOES +GLAD_API_CALL PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES; +#define glEvalCoord1xvOES glad_glEvalCoord1xvOES +GLAD_API_CALL PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; +#define glEvalCoord2d glad_glEvalCoord2d +GLAD_API_CALL PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; +#define glEvalCoord2dv glad_glEvalCoord2dv +GLAD_API_CALL PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; +#define glEvalCoord2f glad_glEvalCoord2f +GLAD_API_CALL PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; +#define glEvalCoord2fv glad_glEvalCoord2fv +GLAD_API_CALL PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES; +#define glEvalCoord2xOES glad_glEvalCoord2xOES +GLAD_API_CALL PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES; +#define glEvalCoord2xvOES glad_glEvalCoord2xvOES +GLAD_API_CALL PFNGLEVALMAPSNVPROC glad_glEvalMapsNV; +#define glEvalMapsNV glad_glEvalMapsNV +GLAD_API_CALL PFNGLEVALMESH1PROC glad_glEvalMesh1; +#define glEvalMesh1 glad_glEvalMesh1 +GLAD_API_CALL PFNGLEVALMESH2PROC glad_glEvalMesh2; +#define glEvalMesh2 glad_glEvalMesh2 +GLAD_API_CALL PFNGLEVALPOINT1PROC glad_glEvalPoint1; +#define glEvalPoint1 glad_glEvalPoint1 +GLAD_API_CALL PFNGLEVALPOINT2PROC glad_glEvalPoint2; +#define glEvalPoint2 glad_glEvalPoint2 +GLAD_API_CALL PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB; +#define glEvaluateDepthValuesARB glad_glEvaluateDepthValuesARB +GLAD_API_CALL PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV; +#define glExecuteProgramNV glad_glExecuteProgramNV +GLAD_API_CALL PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT; +#define glExtractComponentEXT glad_glExtractComponentEXT +GLAD_API_CALL PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; +#define glFeedbackBuffer glad_glFeedbackBuffer +GLAD_API_CALL PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES; +#define glFeedbackBufferxOES glad_glFeedbackBufferxOES +GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +GLAD_API_CALL PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV; +#define glFinalCombinerInputNV glad_glFinalCombinerInputNV +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX; +#define glFinishAsyncSGIX glad_glFinishAsyncSGIX +GLAD_API_CALL PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE; +#define glFinishFenceAPPLE glad_glFinishFenceAPPLE +GLAD_API_CALL PFNGLFINISHFENCENVPROC glad_glFinishFenceNV; +#define glFinishFenceNV glad_glFinishFenceNV +GLAD_API_CALL PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE; +#define glFinishObjectAPPLE glad_glFinishObjectAPPLE +GLAD_API_CALL PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX; +#define glFinishTextureSUNX glad_glFinishTextureSUNX +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE; +#define glFlushMappedBufferRangeAPPLE glad_glFlushMappedBufferRangeAPPLE +GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; +#define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange +GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT; +#define glFlushMappedNamedBufferRangeEXT glad_glFlushMappedNamedBufferRangeEXT +GLAD_API_CALL PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV; +#define glFlushPixelDataRangeNV glad_glFlushPixelDataRangeNV +GLAD_API_CALL PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX; +#define glFlushRasterSGIX glad_glFlushRasterSGIX +GLAD_API_CALL PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM; +#define glFlushStaticDataIBM glad_glFlushStaticDataIBM +GLAD_API_CALL PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE; +#define glFlushVertexArrayRangeAPPLE glad_glFlushVertexArrayRangeAPPLE +GLAD_API_CALL PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV; +#define glFlushVertexArrayRangeNV glad_glFlushVertexArrayRangeNV +GLAD_API_CALL PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV; +#define glFogCoordFormatNV glad_glFogCoordFormatNV +GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; +#define glFogCoordPointer glad_glFogCoordPointer +GLAD_API_CALL PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT; +#define glFogCoordPointerEXT glad_glFogCoordPointerEXT +GLAD_API_CALL PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM; +#define glFogCoordPointerListIBM glad_glFogCoordPointerListIBM +GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; +#define glFogCoordd glad_glFogCoordd +GLAD_API_CALL PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT; +#define glFogCoorddEXT glad_glFogCoorddEXT +GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; +#define glFogCoorddv glad_glFogCoorddv +GLAD_API_CALL PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT; +#define glFogCoorddvEXT glad_glFogCoorddvEXT +GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; +#define glFogCoordf glad_glFogCoordf +GLAD_API_CALL PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT; +#define glFogCoordfEXT glad_glFogCoordfEXT +GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; +#define glFogCoordfv glad_glFogCoordfv +GLAD_API_CALL PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT; +#define glFogCoordfvEXT glad_glFogCoordfvEXT +GLAD_API_CALL PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV; +#define glFogCoordhNV glad_glFogCoordhNV +GLAD_API_CALL PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV; +#define glFogCoordhvNV glad_glFogCoordhvNV +GLAD_API_CALL PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS; +#define glFogFuncSGIS glad_glFogFuncSGIS +GLAD_API_CALL PFNGLFOGFPROC glad_glFogf; +#define glFogf glad_glFogf +GLAD_API_CALL PFNGLFOGFVPROC glad_glFogfv; +#define glFogfv glad_glFogfv +GLAD_API_CALL PFNGLFOGIPROC glad_glFogi; +#define glFogi glad_glFogi +GLAD_API_CALL PFNGLFOGIVPROC glad_glFogiv; +#define glFogiv glad_glFogiv +GLAD_API_CALL PFNGLFOGXOESPROC glad_glFogxOES; +#define glFogxOES glad_glFogxOES +GLAD_API_CALL PFNGLFOGXVOESPROC glad_glFogxvOES; +#define glFogxvOES glad_glFogxvOES +GLAD_API_CALL PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX; +#define glFragmentColorMaterialSGIX glad_glFragmentColorMaterialSGIX +GLAD_API_CALL PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV; +#define glFragmentCoverageColorNV glad_glFragmentCoverageColorNV +GLAD_API_CALL PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX; +#define glFragmentLightModelfSGIX glad_glFragmentLightModelfSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX; +#define glFragmentLightModelfvSGIX glad_glFragmentLightModelfvSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX; +#define glFragmentLightModeliSGIX glad_glFragmentLightModeliSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX; +#define glFragmentLightModelivSGIX glad_glFragmentLightModelivSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX; +#define glFragmentLightfSGIX glad_glFragmentLightfSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX; +#define glFragmentLightfvSGIX glad_glFragmentLightfvSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX; +#define glFragmentLightiSGIX glad_glFragmentLightiSGIX +GLAD_API_CALL PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX; +#define glFragmentLightivSGIX glad_glFragmentLightivSGIX +GLAD_API_CALL PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX; +#define glFragmentMaterialfSGIX glad_glFragmentMaterialfSGIX +GLAD_API_CALL PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX; +#define glFragmentMaterialfvSGIX glad_glFragmentMaterialfvSGIX +GLAD_API_CALL PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX; +#define glFragmentMaterialiSGIX glad_glFragmentMaterialiSGIX +GLAD_API_CALL PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX; +#define glFragmentMaterialivSGIX glad_glFragmentMaterialivSGIX +GLAD_API_CALL PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY; +#define glFrameTerminatorGREMEDY glad_glFrameTerminatorGREMEDY +GLAD_API_CALL PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX; +#define glFrameZoomSGIX glad_glFrameZoomSGIX +GLAD_API_CALL PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT; +#define glFramebufferDrawBufferEXT glad_glFramebufferDrawBufferEXT +GLAD_API_CALL PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT; +#define glFramebufferDrawBuffersEXT glad_glFramebufferDrawBuffersEXT +GLAD_API_CALL PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT; +#define glFramebufferFetchBarrierEXT glad_glFramebufferFetchBarrierEXT +GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; +#define glFramebufferParameteri glad_glFramebufferParameteri +GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIMESAPROC glad_glFramebufferParameteriMESA; +#define glFramebufferParameteriMESA glad_glFramebufferParameteriMESA +GLAD_API_CALL PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT; +#define glFramebufferReadBufferEXT glad_glFramebufferReadBufferEXT +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; +#define glFramebufferRenderbufferEXT glad_glFramebufferRenderbufferEXT +GLAD_API_CALL PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB; +#define glFramebufferSampleLocationsfvARB glad_glFramebufferSampleLocationsfvARB +GLAD_API_CALL PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV; +#define glFramebufferSampleLocationsfvNV glad_glFramebufferSampleLocationsfvNV +GLAD_API_CALL PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD; +#define glFramebufferSamplePositionsfvAMD glad_glFramebufferSamplePositionsfvAMD +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; +#define glFramebufferTexture1DEXT glad_glFramebufferTexture1DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; +#define glFramebufferTexture2DEXT glad_glFramebufferTexture2DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; +#define glFramebufferTexture3DEXT glad_glFramebufferTexture3DEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB; +#define glFramebufferTextureARB glad_glFramebufferTextureARB +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT; +#define glFramebufferTextureEXT glad_glFramebufferTextureEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB; +#define glFramebufferTextureFaceARB glad_glFramebufferTextureFaceARB +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT; +#define glFramebufferTextureFaceEXT glad_glFramebufferTextureFaceEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB; +#define glFramebufferTextureLayerARB glad_glFramebufferTextureLayerARB +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT; +#define glFramebufferTextureLayerEXT glad_glFramebufferTextureLayerEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; +#define glFramebufferTextureMultiviewOVR glad_glFramebufferTextureMultiviewOVR +GLAD_API_CALL PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI; +#define glFreeObjectBufferATI glad_glFreeObjectBufferATI +GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; +#define glFrustum glad_glFrustum +GLAD_API_CALL PFNGLFRUSTUMFOESPROC glad_glFrustumfOES; +#define glFrustumfOES glad_glFrustumfOES +GLAD_API_CALL PFNGLFRUSTUMXOESPROC glad_glFrustumxOES; +#define glFrustumxOES glad_glFrustumxOES +GLAD_API_CALL PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX; +#define glGenAsyncMarkersSGIX glad_glGenAsyncMarkersSGIX +GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +GLAD_API_CALL PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB; +#define glGenBuffersARB glad_glGenBuffersARB +GLAD_API_CALL PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE; +#define glGenFencesAPPLE glad_glGenFencesAPPLE +GLAD_API_CALL PFNGLGENFENCESNVPROC glad_glGenFencesNV; +#define glGenFencesNV glad_glGenFencesNV +GLAD_API_CALL PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI; +#define glGenFragmentShadersATI glad_glGenFragmentShadersATI +GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; +#define glGenFramebuffersEXT glad_glGenFramebuffersEXT +GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; +#define glGenLists glad_glGenLists +GLAD_API_CALL PFNGLGENNAMESAMDPROC glad_glGenNamesAMD; +#define glGenNamesAMD glad_glGenNamesAMD +GLAD_API_CALL PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV; +#define glGenOcclusionQueriesNV glad_glGenOcclusionQueriesNV +GLAD_API_CALL PFNGLGENPATHSNVPROC glad_glGenPathsNV; +#define glGenPathsNV glad_glGenPathsNV +GLAD_API_CALL PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD; +#define glGenPerfMonitorsAMD glad_glGenPerfMonitorsAMD +GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; +#define glGenProgramPipelines glad_glGenProgramPipelines +GLAD_API_CALL PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB; +#define glGenProgramsARB glad_glGenProgramsARB +GLAD_API_CALL PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV; +#define glGenProgramsNV glad_glGenProgramsNV +GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +GLAD_API_CALL PFNGLGENQUERIESARBPROC glad_glGenQueriesARB; +#define glGenQueriesARB glad_glGenQueriesARB +GLAD_API_CALL PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV; +#define glGenQueryResourceTagNV glad_glGenQueryResourceTagNV +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; +#define glGenRenderbuffersEXT glad_glGenRenderbuffersEXT +GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +GLAD_API_CALL PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT; +#define glGenSemaphoresEXT glad_glGenSemaphoresEXT +GLAD_API_CALL PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT; +#define glGenSymbolsEXT glad_glGenSymbolsEXT +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT; +#define glGenTexturesEXT glad_glGenTexturesEXT +GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; +#define glGenTransformFeedbacks glad_glGenTransformFeedbacks +GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV; +#define glGenTransformFeedbacksNV glad_glGenTransformFeedbacksNV +GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +GLAD_API_CALL PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE; +#define glGenVertexArraysAPPLE glad_glGenVertexArraysAPPLE +GLAD_API_CALL PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT; +#define glGenVertexShadersEXT glad_glGenVertexShadersEXT +GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +GLAD_API_CALL PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; +#define glGenerateMipmapEXT glad_glGenerateMipmapEXT +GLAD_API_CALL PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT; +#define glGenerateMultiTexMipmapEXT glad_glGenerateMultiTexMipmapEXT +GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; +#define glGenerateTextureMipmap glad_glGenerateTextureMipmap +GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT; +#define glGenerateTextureMipmapEXT glad_glGenerateTextureMipmapEXT +GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; +#define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv +GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +GLAD_API_CALL PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB; +#define glGetActiveAttribARB glad_glGetActiveAttribARB +GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; +#define glGetActiveSubroutineName glad_glGetActiveSubroutineName +GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; +#define glGetActiveSubroutineUniformName glad_glGetActiveSubroutineUniformName +GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; +#define glGetActiveSubroutineUniformiv glad_glGetActiveSubroutineUniformiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +GLAD_API_CALL PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB; +#define glGetActiveUniformARB glad_glGetActiveUniformARB +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +GLAD_API_CALL PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV; +#define glGetActiveVaryingNV glad_glGetActiveVaryingNV +GLAD_API_CALL PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI; +#define glGetArrayObjectfvATI glad_glGetArrayObjectfvATI +GLAD_API_CALL PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI; +#define glGetArrayObjectivATI glad_glGetArrayObjectivATI +GLAD_API_CALL PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB; +#define glGetAttachedObjectsARB glad_glGetAttachedObjectsARB +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB; +#define glGetAttribLocationARB glad_glGetAttribLocationARB +GLAD_API_CALL PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT; +#define glGetBooleanIndexedvEXT glad_glGetBooleanIndexedvEXT +GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB; +#define glGetBufferParameterivARB glad_glGetBufferParameterivARB +GLAD_API_CALL PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV; +#define glGetBufferParameterui64vNV glad_glGetBufferParameterui64vNV +GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB; +#define glGetBufferPointervARB glad_glGetBufferPointervARB +GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +GLAD_API_CALL PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB; +#define glGetBufferSubDataARB glad_glGetBufferSubDataARB +GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; +#define glGetClipPlane glad_glGetClipPlane +GLAD_API_CALL PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES; +#define glGetClipPlanefOES glad_glGetClipPlanefOES +GLAD_API_CALL PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES; +#define glGetClipPlanexOES glad_glGetClipPlanexOES +GLAD_API_CALL PFNGLGETCOLORTABLEPROC glad_glGetColorTable; +#define glGetColorTable glad_glGetColorTable +GLAD_API_CALL PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT; +#define glGetColorTableEXT glad_glGetColorTableEXT +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv; +#define glGetColorTableParameterfv glad_glGetColorTableParameterfv +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT; +#define glGetColorTableParameterfvEXT glad_glGetColorTableParameterfvEXT +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI; +#define glGetColorTableParameterfvSGI glad_glGetColorTableParameterfvSGI +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv; +#define glGetColorTableParameteriv glad_glGetColorTableParameteriv +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT; +#define glGetColorTableParameterivEXT glad_glGetColorTableParameterivEXT +GLAD_API_CALL PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI; +#define glGetColorTableParameterivSGI glad_glGetColorTableParameterivSGI +GLAD_API_CALL PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI; +#define glGetColorTableSGI glad_glGetColorTableSGI +GLAD_API_CALL PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV; +#define glGetCombinerInputParameterfvNV glad_glGetCombinerInputParameterfvNV +GLAD_API_CALL PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV; +#define glGetCombinerInputParameterivNV glad_glGetCombinerInputParameterivNV +GLAD_API_CALL PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV; +#define glGetCombinerOutputParameterfvNV glad_glGetCombinerOutputParameterfvNV +GLAD_API_CALL PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV; +#define glGetCombinerOutputParameterivNV glad_glGetCombinerOutputParameterivNV +GLAD_API_CALL PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV; +#define glGetCombinerStageParameterfvNV glad_glGetCombinerStageParameterfvNV +GLAD_API_CALL PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV; +#define glGetCommandHeaderNV glad_glGetCommandHeaderNV +GLAD_API_CALL PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT; +#define glGetCompressedMultiTexImageEXT glad_glGetCompressedMultiTexImageEXT +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB; +#define glGetCompressedTexImageARB glad_glGetCompressedTexImageARB +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; +#define glGetCompressedTextureImage glad_glGetCompressedTextureImage +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT; +#define glGetCompressedTextureImageEXT glad_glGetCompressedTextureImageEXT +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; +#define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage +GLAD_API_CALL PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter; +#define glGetConvolutionFilter glad_glGetConvolutionFilter +GLAD_API_CALL PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT; +#define glGetConvolutionFilterEXT glad_glGetConvolutionFilterEXT +GLAD_API_CALL PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv; +#define glGetConvolutionParameterfv glad_glGetConvolutionParameterfv +GLAD_API_CALL PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT; +#define glGetConvolutionParameterfvEXT glad_glGetConvolutionParameterfvEXT +GLAD_API_CALL PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv; +#define glGetConvolutionParameteriv glad_glGetConvolutionParameteriv +GLAD_API_CALL PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT; +#define glGetConvolutionParameterivEXT glad_glGetConvolutionParameterivEXT +GLAD_API_CALL PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES; +#define glGetConvolutionParameterxvOES glad_glGetConvolutionParameterxvOES +GLAD_API_CALL PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV; +#define glGetCoverageModulationTableNV glad_glGetCoverageModulationTableNV +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; +#define glGetDebugMessageLog glad_glGetDebugMessageLog +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD; +#define glGetDebugMessageLogAMD glad_glGetDebugMessageLogAMD +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; +#define glGetDebugMessageLogARB glad_glGetDebugMessageLogARB +GLAD_API_CALL PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS; +#define glGetDetailTexFuncSGIS glad_glGetDetailTexFuncSGIS +GLAD_API_CALL PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT; +#define glGetDoubleIndexedvEXT glad_glGetDoubleIndexedvEXT +GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; +#define glGetDoublei_v glad_glGetDoublei_v +GLAD_API_CALL PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT; +#define glGetDoublei_vEXT glad_glGetDoublei_vEXT +GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV; +#define glGetFenceivNV glad_glGetFenceivNV +GLAD_API_CALL PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV; +#define glGetFinalCombinerInputParameterfvNV glad_glGetFinalCombinerInputParameterfvNV +GLAD_API_CALL PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV; +#define glGetFinalCombinerInputParameterivNV glad_glGetFinalCombinerInputParameterivNV +GLAD_API_CALL PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL; +#define glGetFirstPerfQueryIdINTEL glad_glGetFirstPerfQueryIdINTEL +GLAD_API_CALL PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES; +#define glGetFixedvOES glad_glGetFixedvOES +GLAD_API_CALL PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT; +#define glGetFloatIndexedvEXT glad_glGetFloatIndexedvEXT +GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v; +#define glGetFloati_v glad_glGetFloati_v +GLAD_API_CALL PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT; +#define glGetFloati_vEXT glad_glGetFloati_vEXT +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS; +#define glGetFogFuncSGIS glad_glGetFogFuncSGIS +GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; +#define glGetFragDataIndex glad_glGetFragDataIndex +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT; +#define glGetFragDataLocationEXT glad_glGetFragDataLocationEXT +GLAD_API_CALL PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX; +#define glGetFragmentLightfvSGIX glad_glGetFragmentLightfvSGIX +GLAD_API_CALL PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX; +#define glGetFragmentLightivSGIX glad_glGetFragmentLightivSGIX +GLAD_API_CALL PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX; +#define glGetFragmentMaterialfvSGIX glad_glGetFragmentMaterialfvSGIX +GLAD_API_CALL PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX; +#define glGetFragmentMaterialivSGIX glad_glGetFragmentMaterialivSGIX +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; +#define glGetFramebufferAttachmentParameterivEXT glad_glGetFramebufferAttachmentParameterivEXT +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD; +#define glGetFramebufferParameterfvAMD glad_glGetFramebufferParameterfvAMD +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; +#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT; +#define glGetFramebufferParameterivEXT glad_glGetFramebufferParameterivEXT +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC glad_glGetFramebufferParameterivMESA; +#define glGetFramebufferParameterivMESA glad_glGetFramebufferParameterivMESA +GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; +#define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus +GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; +#define glGetGraphicsResetStatusARB glad_glGetGraphicsResetStatusARB +GLAD_API_CALL PFNGLGETHANDLEARBPROC glad_glGetHandleARB; +#define glGetHandleARB glad_glGetHandleARB +GLAD_API_CALL PFNGLGETHISTOGRAMPROC glad_glGetHistogram; +#define glGetHistogram glad_glGetHistogram +GLAD_API_CALL PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT; +#define glGetHistogramEXT glad_glGetHistogramEXT +GLAD_API_CALL PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv; +#define glGetHistogramParameterfv glad_glGetHistogramParameterfv +GLAD_API_CALL PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT; +#define glGetHistogramParameterfvEXT glad_glGetHistogramParameterfvEXT +GLAD_API_CALL PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv; +#define glGetHistogramParameteriv glad_glGetHistogramParameteriv +GLAD_API_CALL PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT; +#define glGetHistogramParameterivEXT glad_glGetHistogramParameterivEXT +GLAD_API_CALL PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES; +#define glGetHistogramParameterxvOES glad_glGetHistogramParameterxvOES +GLAD_API_CALL PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB; +#define glGetImageHandleARB glad_glGetImageHandleARB +GLAD_API_CALL PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV; +#define glGetImageHandleNV glad_glGetImageHandleNV +GLAD_API_CALL PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP; +#define glGetImageTransformParameterfvHP glad_glGetImageTransformParameterfvHP +GLAD_API_CALL PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP; +#define glGetImageTransformParameterivHP glad_glGetImageTransformParameterivHP +GLAD_API_CALL PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB; +#define glGetInfoLogARB glad_glGetInfoLogARB +GLAD_API_CALL PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX; +#define glGetInstrumentsSGIX glad_glGetInstrumentsSGIX +GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +GLAD_API_CALL PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT; +#define glGetIntegerIndexedvEXT glad_glGetIntegerIndexedvEXT +GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +GLAD_API_CALL PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV; +#define glGetIntegerui64i_vNV glad_glGetIntegerui64i_vNV +GLAD_API_CALL PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV; +#define glGetIntegerui64vNV glad_glGetIntegerui64vNV +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV; +#define glGetInternalformatSampleivNV glad_glGetInternalformatSampleivNV +GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; +#define glGetInternalformati64v glad_glGetInternalformati64v +GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; +#define glGetInternalformativ glad_glGetInternalformativ +GLAD_API_CALL PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT; +#define glGetInvariantBooleanvEXT glad_glGetInvariantBooleanvEXT +GLAD_API_CALL PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT; +#define glGetInvariantFloatvEXT glad_glGetInvariantFloatvEXT +GLAD_API_CALL PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT; +#define glGetInvariantIntegervEXT glad_glGetInvariantIntegervEXT +GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; +#define glGetLightfv glad_glGetLightfv +GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; +#define glGetLightiv glad_glGetLightiv +GLAD_API_CALL PFNGLGETLIGHTXOESPROC glad_glGetLightxOES; +#define glGetLightxOES glad_glGetLightxOES +GLAD_API_CALL PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX; +#define glGetListParameterfvSGIX glad_glGetListParameterfvSGIX +GLAD_API_CALL PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX; +#define glGetListParameterivSGIX glad_glGetListParameterivSGIX +GLAD_API_CALL PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT; +#define glGetLocalConstantBooleanvEXT glad_glGetLocalConstantBooleanvEXT +GLAD_API_CALL PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT; +#define glGetLocalConstantFloatvEXT glad_glGetLocalConstantFloatvEXT +GLAD_API_CALL PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT; +#define glGetLocalConstantIntegervEXT glad_glGetLocalConstantIntegervEXT +GLAD_API_CALL PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV; +#define glGetMapAttribParameterfvNV glad_glGetMapAttribParameterfvNV +GLAD_API_CALL PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV; +#define glGetMapAttribParameterivNV glad_glGetMapAttribParameterivNV +GLAD_API_CALL PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV; +#define glGetMapControlPointsNV glad_glGetMapControlPointsNV +GLAD_API_CALL PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV; +#define glGetMapParameterfvNV glad_glGetMapParameterfvNV +GLAD_API_CALL PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV; +#define glGetMapParameterivNV glad_glGetMapParameterivNV +GLAD_API_CALL PFNGLGETMAPDVPROC glad_glGetMapdv; +#define glGetMapdv glad_glGetMapdv +GLAD_API_CALL PFNGLGETMAPFVPROC glad_glGetMapfv; +#define glGetMapfv glad_glGetMapfv +GLAD_API_CALL PFNGLGETMAPIVPROC glad_glGetMapiv; +#define glGetMapiv glad_glGetMapiv +GLAD_API_CALL PFNGLGETMAPXVOESPROC glad_glGetMapxvOES; +#define glGetMapxvOES glad_glGetMapxvOES +GLAD_API_CALL PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; +#define glGetMaterialfv glad_glGetMaterialfv +GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; +#define glGetMaterialiv glad_glGetMaterialiv +GLAD_API_CALL PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES; +#define glGetMaterialxOES glad_glGetMaterialxOES +GLAD_API_CALL PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC glad_glGetMemoryObjectDetachedResourcesuivNV; +#define glGetMemoryObjectDetachedResourcesuivNV glad_glGetMemoryObjectDetachedResourcesuivNV +GLAD_API_CALL PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT; +#define glGetMemoryObjectParameterivEXT glad_glGetMemoryObjectParameterivEXT +GLAD_API_CALL PFNGLGETMINMAXPROC glad_glGetMinmax; +#define glGetMinmax glad_glGetMinmax +GLAD_API_CALL PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT; +#define glGetMinmaxEXT glad_glGetMinmaxEXT +GLAD_API_CALL PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv; +#define glGetMinmaxParameterfv glad_glGetMinmaxParameterfv +GLAD_API_CALL PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT; +#define glGetMinmaxParameterfvEXT glad_glGetMinmaxParameterfvEXT +GLAD_API_CALL PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv; +#define glGetMinmaxParameteriv glad_glGetMinmaxParameteriv +GLAD_API_CALL PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT; +#define glGetMinmaxParameterivEXT glad_glGetMinmaxParameterivEXT +GLAD_API_CALL PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT; +#define glGetMultiTexEnvfvEXT glad_glGetMultiTexEnvfvEXT +GLAD_API_CALL PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT; +#define glGetMultiTexEnvivEXT glad_glGetMultiTexEnvivEXT +GLAD_API_CALL PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT; +#define glGetMultiTexGendvEXT glad_glGetMultiTexGendvEXT +GLAD_API_CALL PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT; +#define glGetMultiTexGenfvEXT glad_glGetMultiTexGenfvEXT +GLAD_API_CALL PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT; +#define glGetMultiTexGenivEXT glad_glGetMultiTexGenivEXT +GLAD_API_CALL PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT; +#define glGetMultiTexImageEXT glad_glGetMultiTexImageEXT +GLAD_API_CALL PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT; +#define glGetMultiTexLevelParameterfvEXT glad_glGetMultiTexLevelParameterfvEXT +GLAD_API_CALL PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT; +#define glGetMultiTexLevelParameterivEXT glad_glGetMultiTexLevelParameterivEXT +GLAD_API_CALL PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT; +#define glGetMultiTexParameterIivEXT glad_glGetMultiTexParameterIivEXT +GLAD_API_CALL PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT; +#define glGetMultiTexParameterIuivEXT glad_glGetMultiTexParameterIuivEXT +GLAD_API_CALL PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT; +#define glGetMultiTexParameterfvEXT glad_glGetMultiTexParameterfvEXT +GLAD_API_CALL PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT; +#define glGetMultiTexParameterivEXT glad_glGetMultiTexParameterivEXT +GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +GLAD_API_CALL PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV; +#define glGetMultisamplefvNV glad_glGetMultisamplefvNV +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; +#define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; +#define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT; +#define glGetNamedBufferParameterivEXT glad_glGetNamedBufferParameterivEXT +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV; +#define glGetNamedBufferParameterui64vNV glad_glGetNamedBufferParameterui64vNV +GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; +#define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv +GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT; +#define glGetNamedBufferPointervEXT glad_glGetNamedBufferPointervEXT +GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; +#define glGetNamedBufferSubData glad_glGetNamedBufferSubData +GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT; +#define glGetNamedBufferSubDataEXT glad_glGetNamedBufferSubDataEXT +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; +#define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT; +#define glGetNamedFramebufferAttachmentParameterivEXT glad_glGetNamedFramebufferAttachmentParameterivEXT +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD; +#define glGetNamedFramebufferParameterfvAMD glad_glGetNamedFramebufferParameterfvAMD +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; +#define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT; +#define glGetNamedFramebufferParameterivEXT glad_glGetNamedFramebufferParameterivEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT; +#define glGetNamedProgramLocalParameterIivEXT glad_glGetNamedProgramLocalParameterIivEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT; +#define glGetNamedProgramLocalParameterIuivEXT glad_glGetNamedProgramLocalParameterIuivEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT; +#define glGetNamedProgramLocalParameterdvEXT glad_glGetNamedProgramLocalParameterdvEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT; +#define glGetNamedProgramLocalParameterfvEXT glad_glGetNamedProgramLocalParameterfvEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT; +#define glGetNamedProgramStringEXT glad_glGetNamedProgramStringEXT +GLAD_API_CALL PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT; +#define glGetNamedProgramivEXT glad_glGetNamedProgramivEXT +GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; +#define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv +GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT; +#define glGetNamedRenderbufferParameterivEXT glad_glGetNamedRenderbufferParameterivEXT +GLAD_API_CALL PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB; +#define glGetNamedStringARB glad_glGetNamedStringARB +GLAD_API_CALL PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB; +#define glGetNamedStringivARB glad_glGetNamedStringivARB +GLAD_API_CALL PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL; +#define glGetNextPerfQueryIdINTEL glad_glGetNextPerfQueryIdINTEL +GLAD_API_CALL PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI; +#define glGetObjectBufferfvATI glad_glGetObjectBufferfvATI +GLAD_API_CALL PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI; +#define glGetObjectBufferivATI glad_glGetObjectBufferivATI +GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; +#define glGetObjectLabel glad_glGetObjectLabel +GLAD_API_CALL PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT; +#define glGetObjectLabelEXT glad_glGetObjectLabelEXT +GLAD_API_CALL PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB; +#define glGetObjectParameterfvARB glad_glGetObjectParameterfvARB +GLAD_API_CALL PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE; +#define glGetObjectParameterivAPPLE glad_glGetObjectParameterivAPPLE +GLAD_API_CALL PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB; +#define glGetObjectParameterivARB glad_glGetObjectParameterivARB +GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; +#define glGetObjectPtrLabel glad_glGetObjectPtrLabel +GLAD_API_CALL PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV; +#define glGetOcclusionQueryivNV glad_glGetOcclusionQueryivNV +GLAD_API_CALL PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV; +#define glGetOcclusionQueryuivNV glad_glGetOcclusionQueryuivNV +GLAD_API_CALL PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV; +#define glGetPathColorGenfvNV glad_glGetPathColorGenfvNV +GLAD_API_CALL PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV; +#define glGetPathColorGenivNV glad_glGetPathColorGenivNV +GLAD_API_CALL PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV; +#define glGetPathCommandsNV glad_glGetPathCommandsNV +GLAD_API_CALL PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV; +#define glGetPathCoordsNV glad_glGetPathCoordsNV +GLAD_API_CALL PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV; +#define glGetPathDashArrayNV glad_glGetPathDashArrayNV +GLAD_API_CALL PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV; +#define glGetPathLengthNV glad_glGetPathLengthNV +GLAD_API_CALL PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV; +#define glGetPathMetricRangeNV glad_glGetPathMetricRangeNV +GLAD_API_CALL PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV; +#define glGetPathMetricsNV glad_glGetPathMetricsNV +GLAD_API_CALL PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV; +#define glGetPathParameterfvNV glad_glGetPathParameterfvNV +GLAD_API_CALL PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV; +#define glGetPathParameterivNV glad_glGetPathParameterivNV +GLAD_API_CALL PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV; +#define glGetPathSpacingNV glad_glGetPathSpacingNV +GLAD_API_CALL PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV; +#define glGetPathTexGenfvNV glad_glGetPathTexGenfvNV +GLAD_API_CALL PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV; +#define glGetPathTexGenivNV glad_glGetPathTexGenivNV +GLAD_API_CALL PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL; +#define glGetPerfCounterInfoINTEL glad_glGetPerfCounterInfoINTEL +GLAD_API_CALL PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD; +#define glGetPerfMonitorCounterDataAMD glad_glGetPerfMonitorCounterDataAMD +GLAD_API_CALL PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD; +#define glGetPerfMonitorCounterInfoAMD glad_glGetPerfMonitorCounterInfoAMD +GLAD_API_CALL PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD; +#define glGetPerfMonitorCounterStringAMD glad_glGetPerfMonitorCounterStringAMD +GLAD_API_CALL PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD; +#define glGetPerfMonitorCountersAMD glad_glGetPerfMonitorCountersAMD +GLAD_API_CALL PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD; +#define glGetPerfMonitorGroupStringAMD glad_glGetPerfMonitorGroupStringAMD +GLAD_API_CALL PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD; +#define glGetPerfMonitorGroupsAMD glad_glGetPerfMonitorGroupsAMD +GLAD_API_CALL PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL; +#define glGetPerfQueryDataINTEL glad_glGetPerfQueryDataINTEL +GLAD_API_CALL PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL; +#define glGetPerfQueryIdByNameINTEL glad_glGetPerfQueryIdByNameINTEL +GLAD_API_CALL PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL; +#define glGetPerfQueryInfoINTEL glad_glGetPerfQueryInfoINTEL +GLAD_API_CALL PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; +#define glGetPixelMapfv glad_glGetPixelMapfv +GLAD_API_CALL PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; +#define glGetPixelMapuiv glad_glGetPixelMapuiv +GLAD_API_CALL PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; +#define glGetPixelMapusv glad_glGetPixelMapusv +GLAD_API_CALL PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv; +#define glGetPixelMapxv glad_glGetPixelMapxv +GLAD_API_CALL PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS; +#define glGetPixelTexGenParameterfvSGIS glad_glGetPixelTexGenParameterfvSGIS +GLAD_API_CALL PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS; +#define glGetPixelTexGenParameterivSGIS glad_glGetPixelTexGenParameterivSGIS +GLAD_API_CALL PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT; +#define glGetPixelTransformParameterfvEXT glad_glGetPixelTransformParameterfvEXT +GLAD_API_CALL PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT; +#define glGetPixelTransformParameterivEXT glad_glGetPixelTransformParameterivEXT +GLAD_API_CALL PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT; +#define glGetPointerIndexedvEXT glad_glGetPointerIndexedvEXT +GLAD_API_CALL PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT; +#define glGetPointeri_vEXT glad_glGetPointeri_vEXT +GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv +GLAD_API_CALL PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT; +#define glGetPointervEXT glad_glGetPointervEXT +GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; +#define glGetPolygonStipple glad_glGetPolygonStipple +GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; +#define glGetProgramBinary glad_glGetProgramBinary +GLAD_API_CALL PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV; +#define glGetProgramEnvParameterIivNV glad_glGetProgramEnvParameterIivNV +GLAD_API_CALL PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV; +#define glGetProgramEnvParameterIuivNV glad_glGetProgramEnvParameterIuivNV +GLAD_API_CALL PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB; +#define glGetProgramEnvParameterdvARB glad_glGetProgramEnvParameterdvARB +GLAD_API_CALL PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB; +#define glGetProgramEnvParameterfvARB glad_glGetProgramEnvParameterfvARB +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; +#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv +GLAD_API_CALL PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV; +#define glGetProgramLocalParameterIivNV glad_glGetProgramLocalParameterIivNV +GLAD_API_CALL PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV; +#define glGetProgramLocalParameterIuivNV glad_glGetProgramLocalParameterIuivNV +GLAD_API_CALL PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB; +#define glGetProgramLocalParameterdvARB glad_glGetProgramLocalParameterdvARB +GLAD_API_CALL PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB; +#define glGetProgramLocalParameterfvARB glad_glGetProgramLocalParameterfvARB +GLAD_API_CALL PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV; +#define glGetProgramNamedParameterdvNV glad_glGetProgramNamedParameterdvNV +GLAD_API_CALL PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV; +#define glGetProgramNamedParameterfvNV glad_glGetProgramNamedParameterfvNV +GLAD_API_CALL PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV; +#define glGetProgramParameterdvNV glad_glGetProgramParameterdvNV +GLAD_API_CALL PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV; +#define glGetProgramParameterfvNV glad_glGetProgramParameterfvNV +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; +#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; +#define glGetProgramPipelineiv glad_glGetProgramPipelineiv +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; +#define glGetProgramResourceIndex glad_glGetProgramResourceIndex +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; +#define glGetProgramResourceLocation glad_glGetProgramResourceLocation +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; +#define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex +GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; +#define glGetProgramResourceName glad_glGetProgramResourceName +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV; +#define glGetProgramResourcefvNV glad_glGetProgramResourcefvNV +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; +#define glGetProgramResourceiv glad_glGetProgramResourceiv +GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; +#define glGetProgramStageiv glad_glGetProgramStageiv +GLAD_API_CALL PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB; +#define glGetProgramStringARB glad_glGetProgramStringARB +GLAD_API_CALL PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV; +#define glGetProgramStringNV glad_glGetProgramStringNV +GLAD_API_CALL PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV; +#define glGetProgramSubroutineParameteruivNV glad_glGetProgramSubroutineParameteruivNV +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB; +#define glGetProgramivARB glad_glGetProgramivARB +GLAD_API_CALL PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV; +#define glGetProgramivNV glad_glGetProgramivNV +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; +#define glGetQueryBufferObjecti64v glad_glGetQueryBufferObjecti64v +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; +#define glGetQueryBufferObjectiv glad_glGetQueryBufferObjectiv +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; +#define glGetQueryBufferObjectui64v glad_glGetQueryBufferObjectui64v +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; +#define glGetQueryBufferObjectuiv glad_glGetQueryBufferObjectuiv +GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; +#define glGetQueryIndexediv glad_glGetQueryIndexediv +GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; +#define glGetQueryObjecti64v glad_glGetQueryObjecti64v +GLAD_API_CALL PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT; +#define glGetQueryObjecti64vEXT glad_glGetQueryObjecti64vEXT +GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +GLAD_API_CALL PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB; +#define glGetQueryObjectivARB glad_glGetQueryObjectivARB +GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; +#define glGetQueryObjectui64v glad_glGetQueryObjectui64v +GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT; +#define glGetQueryObjectui64vEXT glad_glGetQueryObjectui64vEXT +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB; +#define glGetQueryObjectuivARB glad_glGetQueryObjectuivARB +GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +GLAD_API_CALL PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB; +#define glGetQueryivARB glad_glGetQueryivARB +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; +#define glGetRenderbufferParameterivEXT glad_glGetRenderbufferParameterivEXT +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; +#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; +#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +GLAD_API_CALL PFNGLGETSEMAPHOREPARAMETERIVNVPROC glad_glGetSemaphoreParameterivNV; +#define glGetSemaphoreParameterivNV glad_glGetSemaphoreParameterivNV +GLAD_API_CALL PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT; +#define glGetSemaphoreParameterui64vEXT glad_glGetSemaphoreParameterui64vEXT +GLAD_API_CALL PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter; +#define glGetSeparableFilter glad_glGetSeparableFilter +GLAD_API_CALL PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT; +#define glGetSeparableFilterEXT glad_glGetSeparableFilterEXT +GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; +#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat +GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +GLAD_API_CALL PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB; +#define glGetShaderSourceARB glad_glGetShaderSourceARB +GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +GLAD_API_CALL PFNGLGETSHADINGRATEIMAGEPALETTENVPROC glad_glGetShadingRateImagePaletteNV; +#define glGetShadingRateImagePaletteNV glad_glGetShadingRateImagePaletteNV +GLAD_API_CALL PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC glad_glGetShadingRateSampleLocationivNV; +#define glGetShadingRateSampleLocationivNV glad_glGetShadingRateSampleLocationivNV +GLAD_API_CALL PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS; +#define glGetSharpenTexFuncSGIS glad_glGetSharpenTexFuncSGIS +GLAD_API_CALL PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV; +#define glGetStageIndexNV glad_glGetStageIndexNV +GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +GLAD_API_CALL PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; +#define glGetSubroutineIndex glad_glGetSubroutineIndex +GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; +#define glGetSubroutineUniformLocation glad_glGetSubroutineUniformLocation +GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +GLAD_API_CALL PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI; +#define glGetTexBumpParameterfvATI glad_glGetTexBumpParameterfvATI +GLAD_API_CALL PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI; +#define glGetTexBumpParameterivATI glad_glGetTexBumpParameterivATI +GLAD_API_CALL PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; +#define glGetTexEnvfv glad_glGetTexEnvfv +GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; +#define glGetTexEnviv glad_glGetTexEnviv +GLAD_API_CALL PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES; +#define glGetTexEnvxvOES glad_glGetTexEnvxvOES +GLAD_API_CALL PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS; +#define glGetTexFilterFuncSGIS glad_glGetTexFilterFuncSGIS +GLAD_API_CALL PFNGLGETTEXGENDVPROC glad_glGetTexGendv; +#define glGetTexGendv glad_glGetTexGendv +GLAD_API_CALL PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; +#define glGetTexGenfv glad_glGetTexGenfv +GLAD_API_CALL PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; +#define glGetTexGeniv glad_glGetTexGeniv +GLAD_API_CALL PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES; +#define glGetTexGenxvOES glad_glGetTexGenxvOES +GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES; +#define glGetTexLevelParameterxvOES glad_glGetTexLevelParameterxvOES +GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +GLAD_API_CALL PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT; +#define glGetTexParameterIivEXT glad_glGetTexParameterIivEXT +GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT; +#define glGetTexParameterIuivEXT glad_glGetTexParameterIuivEXT +GLAD_API_CALL PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE; +#define glGetTexParameterPointervAPPLE glad_glGetTexParameterPointervAPPLE +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES; +#define glGetTexParameterxvOES glad_glGetTexParameterxvOES +GLAD_API_CALL PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB; +#define glGetTextureHandleARB glad_glGetTextureHandleARB +GLAD_API_CALL PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV; +#define glGetTextureHandleNV glad_glGetTextureHandleNV +GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; +#define glGetTextureImage glad_glGetTextureImage +GLAD_API_CALL PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT; +#define glGetTextureImageEXT glad_glGetTextureImageEXT +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; +#define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT; +#define glGetTextureLevelParameterfvEXT glad_glGetTextureLevelParameterfvEXT +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; +#define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT; +#define glGetTextureLevelParameterivEXT glad_glGetTextureLevelParameterivEXT +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; +#define glGetTextureParameterIiv glad_glGetTextureParameterIiv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT; +#define glGetTextureParameterIivEXT glad_glGetTextureParameterIivEXT +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; +#define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT; +#define glGetTextureParameterIuivEXT glad_glGetTextureParameterIuivEXT +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; +#define glGetTextureParameterfv glad_glGetTextureParameterfv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT; +#define glGetTextureParameterfvEXT glad_glGetTextureParameterfvEXT +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; +#define glGetTextureParameteriv glad_glGetTextureParameteriv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT; +#define glGetTextureParameterivEXT glad_glGetTextureParameterivEXT +GLAD_API_CALL PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB; +#define glGetTextureSamplerHandleARB glad_glGetTextureSamplerHandleARB +GLAD_API_CALL PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV; +#define glGetTextureSamplerHandleNV glad_glGetTextureSamplerHandleNV +GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; +#define glGetTextureSubImage glad_glGetTextureSubImage +GLAD_API_CALL PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV; +#define glGetTrackMatrixivNV glad_glGetTrackMatrixivNV +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT; +#define glGetTransformFeedbackVaryingEXT glad_glGetTransformFeedbackVaryingEXT +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV; +#define glGetTransformFeedbackVaryingNV glad_glGetTransformFeedbackVaryingNV +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; +#define glGetTransformFeedbacki64_v glad_glGetTransformFeedbacki64_v +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; +#define glGetTransformFeedbacki_v glad_glGetTransformFeedbacki_v +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; +#define glGetTransformFeedbackiv glad_glGetTransformFeedbackiv +GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +GLAD_API_CALL PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT; +#define glGetUniformBufferSizeEXT glad_glGetUniformBufferSizeEXT +GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB; +#define glGetUniformLocationARB glad_glGetUniformLocationARB +GLAD_API_CALL PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT; +#define glGetUniformOffsetEXT glad_glGetUniformOffsetEXT +GLAD_API_CALL PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; +#define glGetUniformSubroutineuiv glad_glGetUniformSubroutineuiv +GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; +#define glGetUniformdv glad_glGetUniformdv +GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +GLAD_API_CALL PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB; +#define glGetUniformfvARB glad_glGetUniformfvARB +GLAD_API_CALL PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB; +#define glGetUniformi64vARB glad_glGetUniformi64vARB +GLAD_API_CALL PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV; +#define glGetUniformi64vNV glad_glGetUniformi64vNV +GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +GLAD_API_CALL PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB; +#define glGetUniformivARB glad_glGetUniformivARB +GLAD_API_CALL PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB; +#define glGetUniformui64vARB glad_glGetUniformui64vARB +GLAD_API_CALL PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV; +#define glGetUniformui64vNV glad_glGetUniformui64vNV +GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +GLAD_API_CALL PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT; +#define glGetUniformuivEXT glad_glGetUniformuivEXT +GLAD_API_CALL PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT; +#define glGetUnsignedBytei_vEXT glad_glGetUnsignedBytei_vEXT +GLAD_API_CALL PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT; +#define glGetUnsignedBytevEXT glad_glGetUnsignedBytevEXT +GLAD_API_CALL PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI; +#define glGetVariantArrayObjectfvATI glad_glGetVariantArrayObjectfvATI +GLAD_API_CALL PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI; +#define glGetVariantArrayObjectivATI glad_glGetVariantArrayObjectivATI +GLAD_API_CALL PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT; +#define glGetVariantBooleanvEXT glad_glGetVariantBooleanvEXT +GLAD_API_CALL PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT; +#define glGetVariantFloatvEXT glad_glGetVariantFloatvEXT +GLAD_API_CALL PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT; +#define glGetVariantIntegervEXT glad_glGetVariantIntegervEXT +GLAD_API_CALL PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT; +#define glGetVariantPointervEXT glad_glGetVariantPointervEXT +GLAD_API_CALL PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV; +#define glGetVaryingLocationNV glad_glGetVaryingLocationNV +GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; +#define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv +GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; +#define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv +GLAD_API_CALL PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT; +#define glGetVertexArrayIntegeri_vEXT glad_glGetVertexArrayIntegeri_vEXT +GLAD_API_CALL PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT; +#define glGetVertexArrayIntegervEXT glad_glGetVertexArrayIntegervEXT +GLAD_API_CALL PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT; +#define glGetVertexArrayPointeri_vEXT glad_glGetVertexArrayPointeri_vEXT +GLAD_API_CALL PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT; +#define glGetVertexArrayPointervEXT glad_glGetVertexArrayPointervEXT +GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; +#define glGetVertexArrayiv glad_glGetVertexArrayiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI; +#define glGetVertexAttribArrayObjectfvATI glad_glGetVertexAttribArrayObjectfvATI +GLAD_API_CALL PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI; +#define glGetVertexAttribArrayObjectivATI glad_glGetVertexAttribArrayObjectivATI +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT; +#define glGetVertexAttribIivEXT glad_glGetVertexAttribIivEXT +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT; +#define glGetVertexAttribIuivEXT glad_glGetVertexAttribIuivEXT +GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; +#define glGetVertexAttribLdv glad_glGetVertexAttribLdv +GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT; +#define glGetVertexAttribLdvEXT glad_glGetVertexAttribLdvEXT +GLAD_API_CALL PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV; +#define glGetVertexAttribLi64vNV glad_glGetVertexAttribLi64vNV +GLAD_API_CALL PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB; +#define glGetVertexAttribLui64vARB glad_glGetVertexAttribLui64vARB +GLAD_API_CALL PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV; +#define glGetVertexAttribLui64vNV glad_glGetVertexAttribLui64vNV +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB; +#define glGetVertexAttribPointervARB glad_glGetVertexAttribPointervARB +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV; +#define glGetVertexAttribPointervNV glad_glGetVertexAttribPointervNV +GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +GLAD_API_CALL PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB; +#define glGetVertexAttribdvARB glad_glGetVertexAttribdvARB +GLAD_API_CALL PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV; +#define glGetVertexAttribdvNV glad_glGetVertexAttribdvNV +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB; +#define glGetVertexAttribfvARB glad_glGetVertexAttribfvARB +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV; +#define glGetVertexAttribfvNV glad_glGetVertexAttribfvNV +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB; +#define glGetVertexAttribivARB glad_glGetVertexAttribivARB +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV; +#define glGetVertexAttribivNV glad_glGetVertexAttribivNV +GLAD_API_CALL PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV; +#define glGetVideoCaptureStreamdvNV glad_glGetVideoCaptureStreamdvNV +GLAD_API_CALL PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV; +#define glGetVideoCaptureStreamfvNV glad_glGetVideoCaptureStreamfvNV +GLAD_API_CALL PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV; +#define glGetVideoCaptureStreamivNV glad_glGetVideoCaptureStreamivNV +GLAD_API_CALL PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV; +#define glGetVideoCaptureivNV glad_glGetVideoCaptureivNV +GLAD_API_CALL PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV; +#define glGetVideoi64vNV glad_glGetVideoi64vNV +GLAD_API_CALL PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV; +#define glGetVideoivNV glad_glGetVideoivNV +GLAD_API_CALL PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV; +#define glGetVideoui64vNV glad_glGetVideoui64vNV +GLAD_API_CALL PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV; +#define glGetVideouivNV glad_glGetVideouivNV +GLAD_API_CALL PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV; +#define glGetVkProcAddrNV glad_glGetVkProcAddrNV +GLAD_API_CALL PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable; +#define glGetnColorTable glad_glGetnColorTable +GLAD_API_CALL PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; +#define glGetnColorTableARB glad_glGetnColorTableARB +GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage; +#define glGetnCompressedTexImage glad_glGetnCompressedTexImage +GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; +#define glGetnCompressedTexImageARB glad_glGetnCompressedTexImageARB +GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter; +#define glGetnConvolutionFilter glad_glGetnConvolutionFilter +GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; +#define glGetnConvolutionFilterARB glad_glGetnConvolutionFilterARB +GLAD_API_CALL PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram; +#define glGetnHistogram glad_glGetnHistogram +GLAD_API_CALL PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; +#define glGetnHistogramARB glad_glGetnHistogramARB +GLAD_API_CALL PFNGLGETNMAPDVPROC glad_glGetnMapdv; +#define glGetnMapdv glad_glGetnMapdv +GLAD_API_CALL PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; +#define glGetnMapdvARB glad_glGetnMapdvARB +GLAD_API_CALL PFNGLGETNMAPFVPROC glad_glGetnMapfv; +#define glGetnMapfv glad_glGetnMapfv +GLAD_API_CALL PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; +#define glGetnMapfvARB glad_glGetnMapfvARB +GLAD_API_CALL PFNGLGETNMAPIVPROC glad_glGetnMapiv; +#define glGetnMapiv glad_glGetnMapiv +GLAD_API_CALL PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; +#define glGetnMapivARB glad_glGetnMapivARB +GLAD_API_CALL PFNGLGETNMINMAXPROC glad_glGetnMinmax; +#define glGetnMinmax glad_glGetnMinmax +GLAD_API_CALL PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; +#define glGetnMinmaxARB glad_glGetnMinmaxARB +GLAD_API_CALL PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv; +#define glGetnPixelMapfv glad_glGetnPixelMapfv +GLAD_API_CALL PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; +#define glGetnPixelMapfvARB glad_glGetnPixelMapfvARB +GLAD_API_CALL PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv; +#define glGetnPixelMapuiv glad_glGetnPixelMapuiv +GLAD_API_CALL PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; +#define glGetnPixelMapuivARB glad_glGetnPixelMapuivARB +GLAD_API_CALL PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv; +#define glGetnPixelMapusv glad_glGetnPixelMapusv +GLAD_API_CALL PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; +#define glGetnPixelMapusvARB glad_glGetnPixelMapusvARB +GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple; +#define glGetnPolygonStipple glad_glGetnPolygonStipple +GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; +#define glGetnPolygonStippleARB glad_glGetnPolygonStippleARB +GLAD_API_CALL PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter; +#define glGetnSeparableFilter glad_glGetnSeparableFilter +GLAD_API_CALL PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; +#define glGetnSeparableFilterARB glad_glGetnSeparableFilterARB +GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage; +#define glGetnTexImage glad_glGetnTexImage +GLAD_API_CALL PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; +#define glGetnTexImageARB glad_glGetnTexImageARB +GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv; +#define glGetnUniformdv glad_glGetnUniformdv +GLAD_API_CALL PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; +#define glGetnUniformdvARB glad_glGetnUniformdvARB +GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; +#define glGetnUniformfv glad_glGetnUniformfv +GLAD_API_CALL PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; +#define glGetnUniformfvARB glad_glGetnUniformfvARB +GLAD_API_CALL PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB; +#define glGetnUniformi64vARB glad_glGetnUniformi64vARB +GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; +#define glGetnUniformiv glad_glGetnUniformiv +GLAD_API_CALL PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; +#define glGetnUniformivARB glad_glGetnUniformivARB +GLAD_API_CALL PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB; +#define glGetnUniformui64vARB glad_glGetnUniformui64vARB +GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; +#define glGetnUniformuiv glad_glGetnUniformuiv +GLAD_API_CALL PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; +#define glGetnUniformuivARB glad_glGetnUniformuivARB +GLAD_API_CALL PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN; +#define glGlobalAlphaFactorbSUN glad_glGlobalAlphaFactorbSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN; +#define glGlobalAlphaFactordSUN glad_glGlobalAlphaFactordSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN; +#define glGlobalAlphaFactorfSUN glad_glGlobalAlphaFactorfSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN; +#define glGlobalAlphaFactoriSUN glad_glGlobalAlphaFactoriSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN; +#define glGlobalAlphaFactorsSUN glad_glGlobalAlphaFactorsSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN; +#define glGlobalAlphaFactorubSUN glad_glGlobalAlphaFactorubSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN; +#define glGlobalAlphaFactoruiSUN glad_glGlobalAlphaFactoruiSUN +GLAD_API_CALL PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN; +#define glGlobalAlphaFactorusSUN glad_glGlobalAlphaFactorusSUN +GLAD_API_CALL PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +GLAD_API_CALL PFNGLHINTPGIPROC glad_glHintPGI; +#define glHintPGI glad_glHintPGI +GLAD_API_CALL PFNGLHISTOGRAMPROC glad_glHistogram; +#define glHistogram glad_glHistogram +GLAD_API_CALL PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT; +#define glHistogramEXT glad_glHistogramEXT +GLAD_API_CALL PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX; +#define glIglooInterfaceSGIX glad_glIglooInterfaceSGIX +GLAD_API_CALL PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP; +#define glImageTransformParameterfHP glad_glImageTransformParameterfHP +GLAD_API_CALL PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP; +#define glImageTransformParameterfvHP glad_glImageTransformParameterfvHP +GLAD_API_CALL PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP; +#define glImageTransformParameteriHP glad_glImageTransformParameteriHP +GLAD_API_CALL PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP; +#define glImageTransformParameterivHP glad_glImageTransformParameterivHP +GLAD_API_CALL PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT; +#define glImportMemoryFdEXT glad_glImportMemoryFdEXT +GLAD_API_CALL PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT; +#define glImportMemoryWin32HandleEXT glad_glImportMemoryWin32HandleEXT +GLAD_API_CALL PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT; +#define glImportMemoryWin32NameEXT glad_glImportMemoryWin32NameEXT +GLAD_API_CALL PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT; +#define glImportSemaphoreFdEXT glad_glImportSemaphoreFdEXT +GLAD_API_CALL PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT; +#define glImportSemaphoreWin32HandleEXT glad_glImportSemaphoreWin32HandleEXT +GLAD_API_CALL PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT; +#define glImportSemaphoreWin32NameEXT glad_glImportSemaphoreWin32NameEXT +GLAD_API_CALL PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT; +#define glImportSyncEXT glad_glImportSyncEXT +GLAD_API_CALL PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV; +#define glIndexFormatNV glad_glIndexFormatNV +GLAD_API_CALL PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT; +#define glIndexFuncEXT glad_glIndexFuncEXT +GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; +#define glIndexMask glad_glIndexMask +GLAD_API_CALL PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT; +#define glIndexMaterialEXT glad_glIndexMaterialEXT +GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; +#define glIndexPointer glad_glIndexPointer +GLAD_API_CALL PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT; +#define glIndexPointerEXT glad_glIndexPointerEXT +GLAD_API_CALL PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM; +#define glIndexPointerListIBM glad_glIndexPointerListIBM +GLAD_API_CALL PFNGLINDEXDPROC glad_glIndexd; +#define glIndexd glad_glIndexd +GLAD_API_CALL PFNGLINDEXDVPROC glad_glIndexdv; +#define glIndexdv glad_glIndexdv +GLAD_API_CALL PFNGLINDEXFPROC glad_glIndexf; +#define glIndexf glad_glIndexf +GLAD_API_CALL PFNGLINDEXFVPROC glad_glIndexfv; +#define glIndexfv glad_glIndexfv +GLAD_API_CALL PFNGLINDEXIPROC glad_glIndexi; +#define glIndexi glad_glIndexi +GLAD_API_CALL PFNGLINDEXIVPROC glad_glIndexiv; +#define glIndexiv glad_glIndexiv +GLAD_API_CALL PFNGLINDEXSPROC glad_glIndexs; +#define glIndexs glad_glIndexs +GLAD_API_CALL PFNGLINDEXSVPROC glad_glIndexsv; +#define glIndexsv glad_glIndexsv +GLAD_API_CALL PFNGLINDEXUBPROC glad_glIndexub; +#define glIndexub glad_glIndexub +GLAD_API_CALL PFNGLINDEXUBVPROC glad_glIndexubv; +#define glIndexubv glad_glIndexubv +GLAD_API_CALL PFNGLINDEXXOESPROC glad_glIndexxOES; +#define glIndexxOES glad_glIndexxOES +GLAD_API_CALL PFNGLINDEXXVOESPROC glad_glIndexxvOES; +#define glIndexxvOES glad_glIndexxvOES +GLAD_API_CALL PFNGLINITNAMESPROC glad_glInitNames; +#define glInitNames glad_glInitNames +GLAD_API_CALL PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT; +#define glInsertComponentEXT glad_glInsertComponentEXT +GLAD_API_CALL PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT; +#define glInsertEventMarkerEXT glad_glInsertEventMarkerEXT +GLAD_API_CALL PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX; +#define glInstrumentsBufferSGIX glad_glInstrumentsBufferSGIX +GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; +#define glInterleavedArrays glad_glInterleavedArrays +GLAD_API_CALL PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV; +#define glInterpolatePathsNV glad_glInterpolatePathsNV +GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; +#define glInvalidateBufferData glad_glInvalidateBufferData +GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; +#define glInvalidateBufferSubData glad_glInvalidateBufferSubData +GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; +#define glInvalidateFramebuffer glad_glInvalidateFramebuffer +GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; +#define glInvalidateNamedFramebufferData glad_glInvalidateNamedFramebufferData +GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; +#define glInvalidateNamedFramebufferSubData glad_glInvalidateNamedFramebufferSubData +GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; +#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer +GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; +#define glInvalidateTexImage glad_glInvalidateTexImage +GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; +#define glInvalidateTexSubImage glad_glInvalidateTexSubImage +GLAD_API_CALL PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX; +#define glIsAsyncMarkerSGIX glad_glIsAsyncMarkerSGIX +GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +GLAD_API_CALL PFNGLISBUFFERARBPROC glad_glIsBufferARB; +#define glIsBufferARB glad_glIsBufferARB +GLAD_API_CALL PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV; +#define glIsBufferResidentNV glad_glIsBufferResidentNV +GLAD_API_CALL PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV; +#define glIsCommandListNV glad_glIsCommandListNV +GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +GLAD_API_CALL PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT; +#define glIsEnabledIndexedEXT glad_glIsEnabledIndexedEXT +GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +GLAD_API_CALL PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE; +#define glIsFenceAPPLE glad_glIsFenceAPPLE +GLAD_API_CALL PFNGLISFENCENVPROC glad_glIsFenceNV; +#define glIsFenceNV glad_glIsFenceNV +GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +GLAD_API_CALL PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; +#define glIsFramebufferEXT glad_glIsFramebufferEXT +GLAD_API_CALL PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB; +#define glIsImageHandleResidentARB glad_glIsImageHandleResidentARB +GLAD_API_CALL PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV; +#define glIsImageHandleResidentNV glad_glIsImageHandleResidentNV +GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; +#define glIsList glad_glIsList +GLAD_API_CALL PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT; +#define glIsMemoryObjectEXT glad_glIsMemoryObjectEXT +GLAD_API_CALL PFNGLISNAMEAMDPROC glad_glIsNameAMD; +#define glIsNameAMD glad_glIsNameAMD +GLAD_API_CALL PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV; +#define glIsNamedBufferResidentNV glad_glIsNamedBufferResidentNV +GLAD_API_CALL PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB; +#define glIsNamedStringARB glad_glIsNamedStringARB +GLAD_API_CALL PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI; +#define glIsObjectBufferATI glad_glIsObjectBufferATI +GLAD_API_CALL PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV; +#define glIsOcclusionQueryNV glad_glIsOcclusionQueryNV +GLAD_API_CALL PFNGLISPATHNVPROC glad_glIsPathNV; +#define glIsPathNV glad_glIsPathNV +GLAD_API_CALL PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV; +#define glIsPointInFillPathNV glad_glIsPointInFillPathNV +GLAD_API_CALL PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV; +#define glIsPointInStrokePathNV glad_glIsPointInStrokePathNV +GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +GLAD_API_CALL PFNGLISPROGRAMARBPROC glad_glIsProgramARB; +#define glIsProgramARB glad_glIsProgramARB +GLAD_API_CALL PFNGLISPROGRAMNVPROC glad_glIsProgramNV; +#define glIsProgramNV glad_glIsProgramNV +GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; +#define glIsProgramPipeline glad_glIsProgramPipeline +GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +GLAD_API_CALL PFNGLISQUERYARBPROC glad_glIsQueryARB; +#define glIsQueryARB glad_glIsQueryARB +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; +#define glIsRenderbufferEXT glad_glIsRenderbufferEXT +GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +GLAD_API_CALL PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT; +#define glIsSemaphoreEXT glad_glIsSemaphoreEXT +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISSTATENVPROC glad_glIsStateNV; +#define glIsStateNV glad_glIsStateNV +GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT; +#define glIsTextureEXT glad_glIsTextureEXT +GLAD_API_CALL PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB; +#define glIsTextureHandleResidentARB glad_glIsTextureHandleResidentARB +GLAD_API_CALL PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV; +#define glIsTextureHandleResidentNV glad_glIsTextureHandleResidentNV +GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; +#define glIsTransformFeedback glad_glIsTransformFeedback +GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV; +#define glIsTransformFeedbackNV glad_glIsTransformFeedbackNV +GLAD_API_CALL PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT; +#define glIsVariantEnabledEXT glad_glIsVariantEnabledEXT +GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +GLAD_API_CALL PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE; +#define glIsVertexArrayAPPLE glad_glIsVertexArrayAPPLE +GLAD_API_CALL PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE; +#define glIsVertexAttribEnabledAPPLE glad_glIsVertexAttribEnabledAPPLE +GLAD_API_CALL PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX; +#define glLGPUCopyImageSubDataNVX glad_glLGPUCopyImageSubDataNVX +GLAD_API_CALL PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX; +#define glLGPUInterlockNVX glad_glLGPUInterlockNVX +GLAD_API_CALL PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX; +#define glLGPUNamedBufferSubDataNVX glad_glLGPUNamedBufferSubDataNVX +GLAD_API_CALL PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT; +#define glLabelObjectEXT glad_glLabelObjectEXT +GLAD_API_CALL PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX; +#define glLightEnviSGIX glad_glLightEnviSGIX +GLAD_API_CALL PFNGLLIGHTMODELFPROC glad_glLightModelf; +#define glLightModelf glad_glLightModelf +GLAD_API_CALL PFNGLLIGHTMODELFVPROC glad_glLightModelfv; +#define glLightModelfv glad_glLightModelfv +GLAD_API_CALL PFNGLLIGHTMODELIPROC glad_glLightModeli; +#define glLightModeli glad_glLightModeli +GLAD_API_CALL PFNGLLIGHTMODELIVPROC glad_glLightModeliv; +#define glLightModeliv glad_glLightModeliv +GLAD_API_CALL PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES; +#define glLightModelxOES glad_glLightModelxOES +GLAD_API_CALL PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES; +#define glLightModelxvOES glad_glLightModelxvOES +GLAD_API_CALL PFNGLLIGHTFPROC glad_glLightf; +#define glLightf glad_glLightf +GLAD_API_CALL PFNGLLIGHTFVPROC glad_glLightfv; +#define glLightfv glad_glLightfv +GLAD_API_CALL PFNGLLIGHTIPROC glad_glLighti; +#define glLighti glad_glLighti +GLAD_API_CALL PFNGLLIGHTIVPROC glad_glLightiv; +#define glLightiv glad_glLightiv +GLAD_API_CALL PFNGLLIGHTXOESPROC glad_glLightxOES; +#define glLightxOES glad_glLightxOES +GLAD_API_CALL PFNGLLIGHTXVOESPROC glad_glLightxvOES; +#define glLightxvOES glad_glLightxvOES +GLAD_API_CALL PFNGLLINESTIPPLEPROC glad_glLineStipple; +#define glLineStipple glad_glLineStipple +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES; +#define glLineWidthxOES glad_glLineWidthxOES +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB; +#define glLinkProgramARB glad_glLinkProgramARB +GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; +#define glListBase glad_glListBase +GLAD_API_CALL PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV; +#define glListDrawCommandsStatesClientNV glad_glListDrawCommandsStatesClientNV +GLAD_API_CALL PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX; +#define glListParameterfSGIX glad_glListParameterfSGIX +GLAD_API_CALL PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX; +#define glListParameterfvSGIX glad_glListParameterfvSGIX +GLAD_API_CALL PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX; +#define glListParameteriSGIX glad_glListParameteriSGIX +GLAD_API_CALL PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX; +#define glListParameterivSGIX glad_glListParameterivSGIX +GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; +#define glLoadIdentity glad_glLoadIdentity +GLAD_API_CALL PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX; +#define glLoadIdentityDeformationMapSGIX glad_glLoadIdentityDeformationMapSGIX +GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; +#define glLoadMatrixd glad_glLoadMatrixd +GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; +#define glLoadMatrixf glad_glLoadMatrixf +GLAD_API_CALL PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES; +#define glLoadMatrixxOES glad_glLoadMatrixxOES +GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; +#define glLoadName glad_glLoadName +GLAD_API_CALL PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV; +#define glLoadProgramNV glad_glLoadProgramNV +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; +#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB; +#define glLoadTransposeMatrixdARB glad_glLoadTransposeMatrixdARB +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; +#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB; +#define glLoadTransposeMatrixfARB glad_glLoadTransposeMatrixfARB +GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES; +#define glLoadTransposeMatrixxOES glad_glLoadTransposeMatrixxOES +GLAD_API_CALL PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT; +#define glLockArraysEXT glad_glLockArraysEXT +GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +GLAD_API_CALL PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV; +#define glMakeBufferNonResidentNV glad_glMakeBufferNonResidentNV +GLAD_API_CALL PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV; +#define glMakeBufferResidentNV glad_glMakeBufferResidentNV +GLAD_API_CALL PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB; +#define glMakeImageHandleNonResidentARB glad_glMakeImageHandleNonResidentARB +GLAD_API_CALL PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV; +#define glMakeImageHandleNonResidentNV glad_glMakeImageHandleNonResidentNV +GLAD_API_CALL PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB; +#define glMakeImageHandleResidentARB glad_glMakeImageHandleResidentARB +GLAD_API_CALL PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV; +#define glMakeImageHandleResidentNV glad_glMakeImageHandleResidentNV +GLAD_API_CALL PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV; +#define glMakeNamedBufferNonResidentNV glad_glMakeNamedBufferNonResidentNV +GLAD_API_CALL PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV; +#define glMakeNamedBufferResidentNV glad_glMakeNamedBufferResidentNV +GLAD_API_CALL PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB; +#define glMakeTextureHandleNonResidentARB glad_glMakeTextureHandleNonResidentARB +GLAD_API_CALL PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV; +#define glMakeTextureHandleNonResidentNV glad_glMakeTextureHandleNonResidentNV +GLAD_API_CALL PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB; +#define glMakeTextureHandleResidentARB glad_glMakeTextureHandleResidentARB +GLAD_API_CALL PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV; +#define glMakeTextureHandleResidentNV glad_glMakeTextureHandleResidentNV +GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; +#define glMap1d glad_glMap1d +GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; +#define glMap1f glad_glMap1f +GLAD_API_CALL PFNGLMAP1XOESPROC glad_glMap1xOES; +#define glMap1xOES glad_glMap1xOES +GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; +#define glMap2d glad_glMap2d +GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; +#define glMap2f glad_glMap2f +GLAD_API_CALL PFNGLMAP2XOESPROC glad_glMap2xOES; +#define glMap2xOES glad_glMap2xOES +GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +GLAD_API_CALL PFNGLMAPBUFFERARBPROC glad_glMapBufferARB; +#define glMapBufferARB glad_glMapBufferARB +GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +GLAD_API_CALL PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV; +#define glMapControlPointsNV glad_glMapControlPointsNV +GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; +#define glMapGrid1d glad_glMapGrid1d +GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; +#define glMapGrid1f glad_glMapGrid1f +GLAD_API_CALL PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES; +#define glMapGrid1xOES glad_glMapGrid1xOES +GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; +#define glMapGrid2d glad_glMapGrid2d +GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; +#define glMapGrid2f glad_glMapGrid2f +GLAD_API_CALL PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES; +#define glMapGrid2xOES glad_glMapGrid2xOES +GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; +#define glMapNamedBuffer glad_glMapNamedBuffer +GLAD_API_CALL PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT; +#define glMapNamedBufferEXT glad_glMapNamedBufferEXT +GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; +#define glMapNamedBufferRange glad_glMapNamedBufferRange +GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT; +#define glMapNamedBufferRangeEXT glad_glMapNamedBufferRangeEXT +GLAD_API_CALL PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI; +#define glMapObjectBufferATI glad_glMapObjectBufferATI +GLAD_API_CALL PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV; +#define glMapParameterfvNV glad_glMapParameterfvNV +GLAD_API_CALL PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV; +#define glMapParameterivNV glad_glMapParameterivNV +GLAD_API_CALL PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL; +#define glMapTexture2DINTEL glad_glMapTexture2DINTEL +GLAD_API_CALL PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE; +#define glMapVertexAttrib1dAPPLE glad_glMapVertexAttrib1dAPPLE +GLAD_API_CALL PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE; +#define glMapVertexAttrib1fAPPLE glad_glMapVertexAttrib1fAPPLE +GLAD_API_CALL PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE; +#define glMapVertexAttrib2dAPPLE glad_glMapVertexAttrib2dAPPLE +GLAD_API_CALL PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE; +#define glMapVertexAttrib2fAPPLE glad_glMapVertexAttrib2fAPPLE +GLAD_API_CALL PFNGLMATERIALFPROC glad_glMaterialf; +#define glMaterialf glad_glMaterialf +GLAD_API_CALL PFNGLMATERIALFVPROC glad_glMaterialfv; +#define glMaterialfv glad_glMaterialfv +GLAD_API_CALL PFNGLMATERIALIPROC glad_glMateriali; +#define glMateriali glad_glMateriali +GLAD_API_CALL PFNGLMATERIALIVPROC glad_glMaterialiv; +#define glMaterialiv glad_glMaterialiv +GLAD_API_CALL PFNGLMATERIALXOESPROC glad_glMaterialxOES; +#define glMaterialxOES glad_glMaterialxOES +GLAD_API_CALL PFNGLMATERIALXVOESPROC glad_glMaterialxvOES; +#define glMaterialxvOES glad_glMaterialxvOES +GLAD_API_CALL PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT; +#define glMatrixFrustumEXT glad_glMatrixFrustumEXT +GLAD_API_CALL PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB; +#define glMatrixIndexPointerARB glad_glMatrixIndexPointerARB +GLAD_API_CALL PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB; +#define glMatrixIndexubvARB glad_glMatrixIndexubvARB +GLAD_API_CALL PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB; +#define glMatrixIndexuivARB glad_glMatrixIndexuivARB +GLAD_API_CALL PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB; +#define glMatrixIndexusvARB glad_glMatrixIndexusvARB +GLAD_API_CALL PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV; +#define glMatrixLoad3x2fNV glad_glMatrixLoad3x2fNV +GLAD_API_CALL PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV; +#define glMatrixLoad3x3fNV glad_glMatrixLoad3x3fNV +GLAD_API_CALL PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT; +#define glMatrixLoadIdentityEXT glad_glMatrixLoadIdentityEXT +GLAD_API_CALL PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV; +#define glMatrixLoadTranspose3x3fNV glad_glMatrixLoadTranspose3x3fNV +GLAD_API_CALL PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT; +#define glMatrixLoadTransposedEXT glad_glMatrixLoadTransposedEXT +GLAD_API_CALL PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT; +#define glMatrixLoadTransposefEXT glad_glMatrixLoadTransposefEXT +GLAD_API_CALL PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT; +#define glMatrixLoaddEXT glad_glMatrixLoaddEXT +GLAD_API_CALL PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT; +#define glMatrixLoadfEXT glad_glMatrixLoadfEXT +GLAD_API_CALL PFNGLMATRIXMODEPROC glad_glMatrixMode; +#define glMatrixMode glad_glMatrixMode +GLAD_API_CALL PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV; +#define glMatrixMult3x2fNV glad_glMatrixMult3x2fNV +GLAD_API_CALL PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV; +#define glMatrixMult3x3fNV glad_glMatrixMult3x3fNV +GLAD_API_CALL PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV; +#define glMatrixMultTranspose3x3fNV glad_glMatrixMultTranspose3x3fNV +GLAD_API_CALL PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT; +#define glMatrixMultTransposedEXT glad_glMatrixMultTransposedEXT +GLAD_API_CALL PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT; +#define glMatrixMultTransposefEXT glad_glMatrixMultTransposefEXT +GLAD_API_CALL PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT; +#define glMatrixMultdEXT glad_glMatrixMultdEXT +GLAD_API_CALL PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT; +#define glMatrixMultfEXT glad_glMatrixMultfEXT +GLAD_API_CALL PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT; +#define glMatrixOrthoEXT glad_glMatrixOrthoEXT +GLAD_API_CALL PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT; +#define glMatrixPopEXT glad_glMatrixPopEXT +GLAD_API_CALL PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT; +#define glMatrixPushEXT glad_glMatrixPushEXT +GLAD_API_CALL PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT; +#define glMatrixRotatedEXT glad_glMatrixRotatedEXT +GLAD_API_CALL PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT; +#define glMatrixRotatefEXT glad_glMatrixRotatefEXT +GLAD_API_CALL PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT; +#define glMatrixScaledEXT glad_glMatrixScaledEXT +GLAD_API_CALL PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT; +#define glMatrixScalefEXT glad_glMatrixScalefEXT +GLAD_API_CALL PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT; +#define glMatrixTranslatedEXT glad_glMatrixTranslatedEXT +GLAD_API_CALL PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT; +#define glMatrixTranslatefEXT glad_glMatrixTranslatefEXT +GLAD_API_CALL PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB; +#define glMaxShaderCompilerThreadsARB glad_glMaxShaderCompilerThreadsARB +GLAD_API_CALL PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR; +#define glMaxShaderCompilerThreadsKHR glad_glMaxShaderCompilerThreadsKHR +GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; +#define glMemoryBarrier glad_glMemoryBarrier +GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; +#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion +GLAD_API_CALL PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT; +#define glMemoryBarrierEXT glad_glMemoryBarrierEXT +GLAD_API_CALL PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT; +#define glMemoryObjectParameterivEXT glad_glMemoryObjectParameterivEXT +GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading; +#define glMinSampleShading glad_glMinSampleShading +GLAD_API_CALL PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB; +#define glMinSampleShadingARB glad_glMinSampleShadingARB +GLAD_API_CALL PFNGLMINMAXPROC glad_glMinmax; +#define glMinmax glad_glMinmax +GLAD_API_CALL PFNGLMINMAXEXTPROC glad_glMinmaxEXT; +#define glMinmaxEXT glad_glMinmaxEXT +GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; +#define glMultMatrixd glad_glMultMatrixd +GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; +#define glMultMatrixf glad_glMultMatrixf +GLAD_API_CALL PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES; +#define glMultMatrixxOES glad_glMultMatrixxOES +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; +#define glMultTransposeMatrixd glad_glMultTransposeMatrixd +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB; +#define glMultTransposeMatrixdARB glad_glMultTransposeMatrixdARB +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; +#define glMultTransposeMatrixf glad_glMultTransposeMatrixf +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB; +#define glMultTransposeMatrixfARB glad_glMultTransposeMatrixfARB +GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES; +#define glMultTransposeMatrixxOES glad_glMultTransposeMatrixxOES +GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +GLAD_API_CALL PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT; +#define glMultiDrawArraysEXT glad_glMultiDrawArraysEXT +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; +#define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD; +#define glMultiDrawArraysIndirectAMD glad_glMultiDrawArraysIndirectAMD +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV; +#define glMultiDrawArraysIndirectBindlessCountNV glad_glMultiDrawArraysIndirectBindlessCountNV +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV; +#define glMultiDrawArraysIndirectBindlessNV glad_glMultiDrawArraysIndirectBindlessNV +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount; +#define glMultiDrawArraysIndirectCount glad_glMultiDrawArraysIndirectCount +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB; +#define glMultiDrawArraysIndirectCountARB glad_glMultiDrawArraysIndirectCountARB +GLAD_API_CALL PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE; +#define glMultiDrawElementArrayAPPLE glad_glMultiDrawElementArrayAPPLE +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT; +#define glMultiDrawElementsEXT glad_glMultiDrawElementsEXT +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; +#define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD; +#define glMultiDrawElementsIndirectAMD glad_glMultiDrawElementsIndirectAMD +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV; +#define glMultiDrawElementsIndirectBindlessCountNV glad_glMultiDrawElementsIndirectBindlessCountNV +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV; +#define glMultiDrawElementsIndirectBindlessNV glad_glMultiDrawElementsIndirectBindlessNV +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount; +#define glMultiDrawElementsIndirectCount glad_glMultiDrawElementsIndirectCount +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB; +#define glMultiDrawElementsIndirectCountARB glad_glMultiDrawElementsIndirectCountARB +GLAD_API_CALL PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC glad_glMultiDrawMeshTasksIndirectCountNV; +#define glMultiDrawMeshTasksIndirectCountNV glad_glMultiDrawMeshTasksIndirectCountNV +GLAD_API_CALL PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC glad_glMultiDrawMeshTasksIndirectNV; +#define glMultiDrawMeshTasksIndirectNV glad_glMultiDrawMeshTasksIndirectNV +GLAD_API_CALL PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE; +#define glMultiDrawRangeElementArrayAPPLE glad_glMultiDrawRangeElementArrayAPPLE +GLAD_API_CALL PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM; +#define glMultiModeDrawArraysIBM glad_glMultiModeDrawArraysIBM +GLAD_API_CALL PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM; +#define glMultiModeDrawElementsIBM glad_glMultiModeDrawElementsIBM +GLAD_API_CALL PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT; +#define glMultiTexBufferEXT glad_glMultiTexBufferEXT +GLAD_API_CALL PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES; +#define glMultiTexCoord1bOES glad_glMultiTexCoord1bOES +GLAD_API_CALL PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES; +#define glMultiTexCoord1bvOES glad_glMultiTexCoord1bvOES +GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; +#define glMultiTexCoord1d glad_glMultiTexCoord1d +GLAD_API_CALL PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB; +#define glMultiTexCoord1dARB glad_glMultiTexCoord1dARB +GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; +#define glMultiTexCoord1dv glad_glMultiTexCoord1dv +GLAD_API_CALL PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB; +#define glMultiTexCoord1dvARB glad_glMultiTexCoord1dvARB +GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; +#define glMultiTexCoord1f glad_glMultiTexCoord1f +GLAD_API_CALL PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB; +#define glMultiTexCoord1fARB glad_glMultiTexCoord1fARB +GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; +#define glMultiTexCoord1fv glad_glMultiTexCoord1fv +GLAD_API_CALL PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB; +#define glMultiTexCoord1fvARB glad_glMultiTexCoord1fvARB +GLAD_API_CALL PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV; +#define glMultiTexCoord1hNV glad_glMultiTexCoord1hNV +GLAD_API_CALL PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV; +#define glMultiTexCoord1hvNV glad_glMultiTexCoord1hvNV +GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; +#define glMultiTexCoord1i glad_glMultiTexCoord1i +GLAD_API_CALL PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB; +#define glMultiTexCoord1iARB glad_glMultiTexCoord1iARB +GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; +#define glMultiTexCoord1iv glad_glMultiTexCoord1iv +GLAD_API_CALL PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB; +#define glMultiTexCoord1ivARB glad_glMultiTexCoord1ivARB +GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; +#define glMultiTexCoord1s glad_glMultiTexCoord1s +GLAD_API_CALL PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB; +#define glMultiTexCoord1sARB glad_glMultiTexCoord1sARB +GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; +#define glMultiTexCoord1sv glad_glMultiTexCoord1sv +GLAD_API_CALL PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB; +#define glMultiTexCoord1svARB glad_glMultiTexCoord1svARB +GLAD_API_CALL PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES; +#define glMultiTexCoord1xOES glad_glMultiTexCoord1xOES +GLAD_API_CALL PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES; +#define glMultiTexCoord1xvOES glad_glMultiTexCoord1xvOES +GLAD_API_CALL PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES; +#define glMultiTexCoord2bOES glad_glMultiTexCoord2bOES +GLAD_API_CALL PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES; +#define glMultiTexCoord2bvOES glad_glMultiTexCoord2bvOES +GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; +#define glMultiTexCoord2d glad_glMultiTexCoord2d +GLAD_API_CALL PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB; +#define glMultiTexCoord2dARB glad_glMultiTexCoord2dARB +GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; +#define glMultiTexCoord2dv glad_glMultiTexCoord2dv +GLAD_API_CALL PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB; +#define glMultiTexCoord2dvARB glad_glMultiTexCoord2dvARB +GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; +#define glMultiTexCoord2f glad_glMultiTexCoord2f +GLAD_API_CALL PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB; +#define glMultiTexCoord2fARB glad_glMultiTexCoord2fARB +GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; +#define glMultiTexCoord2fv glad_glMultiTexCoord2fv +GLAD_API_CALL PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB; +#define glMultiTexCoord2fvARB glad_glMultiTexCoord2fvARB +GLAD_API_CALL PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV; +#define glMultiTexCoord2hNV glad_glMultiTexCoord2hNV +GLAD_API_CALL PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV; +#define glMultiTexCoord2hvNV glad_glMultiTexCoord2hvNV +GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; +#define glMultiTexCoord2i glad_glMultiTexCoord2i +GLAD_API_CALL PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB; +#define glMultiTexCoord2iARB glad_glMultiTexCoord2iARB +GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; +#define glMultiTexCoord2iv glad_glMultiTexCoord2iv +GLAD_API_CALL PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB; +#define glMultiTexCoord2ivARB glad_glMultiTexCoord2ivARB +GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; +#define glMultiTexCoord2s glad_glMultiTexCoord2s +GLAD_API_CALL PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB; +#define glMultiTexCoord2sARB glad_glMultiTexCoord2sARB +GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; +#define glMultiTexCoord2sv glad_glMultiTexCoord2sv +GLAD_API_CALL PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB; +#define glMultiTexCoord2svARB glad_glMultiTexCoord2svARB +GLAD_API_CALL PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES; +#define glMultiTexCoord2xOES glad_glMultiTexCoord2xOES +GLAD_API_CALL PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES; +#define glMultiTexCoord2xvOES glad_glMultiTexCoord2xvOES +GLAD_API_CALL PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES; +#define glMultiTexCoord3bOES glad_glMultiTexCoord3bOES +GLAD_API_CALL PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES; +#define glMultiTexCoord3bvOES glad_glMultiTexCoord3bvOES +GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; +#define glMultiTexCoord3d glad_glMultiTexCoord3d +GLAD_API_CALL PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB; +#define glMultiTexCoord3dARB glad_glMultiTexCoord3dARB +GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; +#define glMultiTexCoord3dv glad_glMultiTexCoord3dv +GLAD_API_CALL PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB; +#define glMultiTexCoord3dvARB glad_glMultiTexCoord3dvARB +GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; +#define glMultiTexCoord3f glad_glMultiTexCoord3f +GLAD_API_CALL PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB; +#define glMultiTexCoord3fARB glad_glMultiTexCoord3fARB +GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; +#define glMultiTexCoord3fv glad_glMultiTexCoord3fv +GLAD_API_CALL PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB; +#define glMultiTexCoord3fvARB glad_glMultiTexCoord3fvARB +GLAD_API_CALL PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV; +#define glMultiTexCoord3hNV glad_glMultiTexCoord3hNV +GLAD_API_CALL PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV; +#define glMultiTexCoord3hvNV glad_glMultiTexCoord3hvNV +GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; +#define glMultiTexCoord3i glad_glMultiTexCoord3i +GLAD_API_CALL PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB; +#define glMultiTexCoord3iARB glad_glMultiTexCoord3iARB +GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; +#define glMultiTexCoord3iv glad_glMultiTexCoord3iv +GLAD_API_CALL PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB; +#define glMultiTexCoord3ivARB glad_glMultiTexCoord3ivARB +GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; +#define glMultiTexCoord3s glad_glMultiTexCoord3s +GLAD_API_CALL PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB; +#define glMultiTexCoord3sARB glad_glMultiTexCoord3sARB +GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; +#define glMultiTexCoord3sv glad_glMultiTexCoord3sv +GLAD_API_CALL PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB; +#define glMultiTexCoord3svARB glad_glMultiTexCoord3svARB +GLAD_API_CALL PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES; +#define glMultiTexCoord3xOES glad_glMultiTexCoord3xOES +GLAD_API_CALL PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES; +#define glMultiTexCoord3xvOES glad_glMultiTexCoord3xvOES +GLAD_API_CALL PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES; +#define glMultiTexCoord4bOES glad_glMultiTexCoord4bOES +GLAD_API_CALL PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES; +#define glMultiTexCoord4bvOES glad_glMultiTexCoord4bvOES +GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; +#define glMultiTexCoord4d glad_glMultiTexCoord4d +GLAD_API_CALL PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB; +#define glMultiTexCoord4dARB glad_glMultiTexCoord4dARB +GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; +#define glMultiTexCoord4dv glad_glMultiTexCoord4dv +GLAD_API_CALL PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB; +#define glMultiTexCoord4dvARB glad_glMultiTexCoord4dvARB +GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; +#define glMultiTexCoord4f glad_glMultiTexCoord4f +GLAD_API_CALL PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB; +#define glMultiTexCoord4fARB glad_glMultiTexCoord4fARB +GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; +#define glMultiTexCoord4fv glad_glMultiTexCoord4fv +GLAD_API_CALL PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB; +#define glMultiTexCoord4fvARB glad_glMultiTexCoord4fvARB +GLAD_API_CALL PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV; +#define glMultiTexCoord4hNV glad_glMultiTexCoord4hNV +GLAD_API_CALL PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV; +#define glMultiTexCoord4hvNV glad_glMultiTexCoord4hvNV +GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; +#define glMultiTexCoord4i glad_glMultiTexCoord4i +GLAD_API_CALL PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB; +#define glMultiTexCoord4iARB glad_glMultiTexCoord4iARB +GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; +#define glMultiTexCoord4iv glad_glMultiTexCoord4iv +GLAD_API_CALL PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB; +#define glMultiTexCoord4ivARB glad_glMultiTexCoord4ivARB +GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; +#define glMultiTexCoord4s glad_glMultiTexCoord4s +GLAD_API_CALL PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB; +#define glMultiTexCoord4sARB glad_glMultiTexCoord4sARB +GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; +#define glMultiTexCoord4sv glad_glMultiTexCoord4sv +GLAD_API_CALL PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB; +#define glMultiTexCoord4svARB glad_glMultiTexCoord4svARB +GLAD_API_CALL PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES; +#define glMultiTexCoord4xOES glad_glMultiTexCoord4xOES +GLAD_API_CALL PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES; +#define glMultiTexCoord4xvOES glad_glMultiTexCoord4xvOES +GLAD_API_CALL PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; +#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui +GLAD_API_CALL PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; +#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; +#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui +GLAD_API_CALL PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; +#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; +#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui +GLAD_API_CALL PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; +#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv +GLAD_API_CALL PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; +#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui +GLAD_API_CALL PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; +#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv +GLAD_API_CALL PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT; +#define glMultiTexCoordPointerEXT glad_glMultiTexCoordPointerEXT +GLAD_API_CALL PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT; +#define glMultiTexEnvfEXT glad_glMultiTexEnvfEXT +GLAD_API_CALL PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT; +#define glMultiTexEnvfvEXT glad_glMultiTexEnvfvEXT +GLAD_API_CALL PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT; +#define glMultiTexEnviEXT glad_glMultiTexEnviEXT +GLAD_API_CALL PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT; +#define glMultiTexEnvivEXT glad_glMultiTexEnvivEXT +GLAD_API_CALL PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT; +#define glMultiTexGendEXT glad_glMultiTexGendEXT +GLAD_API_CALL PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT; +#define glMultiTexGendvEXT glad_glMultiTexGendvEXT +GLAD_API_CALL PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT; +#define glMultiTexGenfEXT glad_glMultiTexGenfEXT +GLAD_API_CALL PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT; +#define glMultiTexGenfvEXT glad_glMultiTexGenfvEXT +GLAD_API_CALL PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT; +#define glMultiTexGeniEXT glad_glMultiTexGeniEXT +GLAD_API_CALL PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT; +#define glMultiTexGenivEXT glad_glMultiTexGenivEXT +GLAD_API_CALL PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT; +#define glMultiTexImage1DEXT glad_glMultiTexImage1DEXT +GLAD_API_CALL PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT; +#define glMultiTexImage2DEXT glad_glMultiTexImage2DEXT +GLAD_API_CALL PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT; +#define glMultiTexImage3DEXT glad_glMultiTexImage3DEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT; +#define glMultiTexParameterIivEXT glad_glMultiTexParameterIivEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT; +#define glMultiTexParameterIuivEXT glad_glMultiTexParameterIuivEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT; +#define glMultiTexParameterfEXT glad_glMultiTexParameterfEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT; +#define glMultiTexParameterfvEXT glad_glMultiTexParameterfvEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT; +#define glMultiTexParameteriEXT glad_glMultiTexParameteriEXT +GLAD_API_CALL PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT; +#define glMultiTexParameterivEXT glad_glMultiTexParameterivEXT +GLAD_API_CALL PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT; +#define glMultiTexRenderbufferEXT glad_glMultiTexRenderbufferEXT +GLAD_API_CALL PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT; +#define glMultiTexSubImage1DEXT glad_glMultiTexSubImage1DEXT +GLAD_API_CALL PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT; +#define glMultiTexSubImage2DEXT glad_glMultiTexSubImage2DEXT +GLAD_API_CALL PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT; +#define glMultiTexSubImage3DEXT glad_glMultiTexSubImage3DEXT +GLAD_API_CALL PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV; +#define glMulticastBarrierNV glad_glMulticastBarrierNV +GLAD_API_CALL PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV; +#define glMulticastBlitFramebufferNV glad_glMulticastBlitFramebufferNV +GLAD_API_CALL PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV; +#define glMulticastBufferSubDataNV glad_glMulticastBufferSubDataNV +GLAD_API_CALL PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV; +#define glMulticastCopyBufferSubDataNV glad_glMulticastCopyBufferSubDataNV +GLAD_API_CALL PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV; +#define glMulticastCopyImageSubDataNV glad_glMulticastCopyImageSubDataNV +GLAD_API_CALL PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV; +#define glMulticastFramebufferSampleLocationsfvNV glad_glMulticastFramebufferSampleLocationsfvNV +GLAD_API_CALL PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV; +#define glMulticastGetQueryObjecti64vNV glad_glMulticastGetQueryObjecti64vNV +GLAD_API_CALL PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV; +#define glMulticastGetQueryObjectivNV glad_glMulticastGetQueryObjectivNV +GLAD_API_CALL PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV; +#define glMulticastGetQueryObjectui64vNV glad_glMulticastGetQueryObjectui64vNV +GLAD_API_CALL PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV; +#define glMulticastGetQueryObjectuivNV glad_glMulticastGetQueryObjectuivNV +GLAD_API_CALL PFNGLMULTICASTSCISSORARRAYVNVXPROC glad_glMulticastScissorArrayvNVX; +#define glMulticastScissorArrayvNVX glad_glMulticastScissorArrayvNVX +GLAD_API_CALL PFNGLMULTICASTVIEWPORTARRAYVNVXPROC glad_glMulticastViewportArrayvNVX; +#define glMulticastViewportArrayvNVX glad_glMulticastViewportArrayvNVX +GLAD_API_CALL PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC glad_glMulticastViewportPositionWScaleNVX; +#define glMulticastViewportPositionWScaleNVX glad_glMulticastViewportPositionWScaleNVX +GLAD_API_CALL PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV; +#define glMulticastWaitSyncNV glad_glMulticastWaitSyncNV +GLAD_API_CALL PFNGLNAMEDBUFFERATTACHMEMORYNVPROC glad_glNamedBufferAttachMemoryNV; +#define glNamedBufferAttachMemoryNV glad_glNamedBufferAttachMemoryNV +GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; +#define glNamedBufferData glad_glNamedBufferData +GLAD_API_CALL PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT; +#define glNamedBufferDataEXT glad_glNamedBufferDataEXT +GLAD_API_CALL PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB; +#define glNamedBufferPageCommitmentARB glad_glNamedBufferPageCommitmentARB +GLAD_API_CALL PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT; +#define glNamedBufferPageCommitmentEXT glad_glNamedBufferPageCommitmentEXT +GLAD_API_CALL PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC glad_glNamedBufferPageCommitmentMemNV; +#define glNamedBufferPageCommitmentMemNV glad_glNamedBufferPageCommitmentMemNV +GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; +#define glNamedBufferStorage glad_glNamedBufferStorage +GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT; +#define glNamedBufferStorageEXT glad_glNamedBufferStorageEXT +GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT; +#define glNamedBufferStorageExternalEXT glad_glNamedBufferStorageExternalEXT +GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT; +#define glNamedBufferStorageMemEXT glad_glNamedBufferStorageMemEXT +GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; +#define glNamedBufferSubData glad_glNamedBufferSubData +GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT; +#define glNamedBufferSubDataEXT glad_glNamedBufferSubDataEXT +GLAD_API_CALL PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT; +#define glNamedCopyBufferSubDataEXT glad_glNamedCopyBufferSubDataEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; +#define glNamedFramebufferDrawBuffer glad_glNamedFramebufferDrawBuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; +#define glNamedFramebufferDrawBuffers glad_glNamedFramebufferDrawBuffers +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; +#define glNamedFramebufferParameteri glad_glNamedFramebufferParameteri +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT; +#define glNamedFramebufferParameteriEXT glad_glNamedFramebufferParameteriEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; +#define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; +#define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT; +#define glNamedFramebufferRenderbufferEXT glad_glNamedFramebufferRenderbufferEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB; +#define glNamedFramebufferSampleLocationsfvARB glad_glNamedFramebufferSampleLocationsfvARB +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV; +#define glNamedFramebufferSampleLocationsfvNV glad_glNamedFramebufferSampleLocationsfvNV +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD; +#define glNamedFramebufferSamplePositionsfvAMD glad_glNamedFramebufferSamplePositionsfvAMD +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; +#define glNamedFramebufferTexture glad_glNamedFramebufferTexture +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT; +#define glNamedFramebufferTexture1DEXT glad_glNamedFramebufferTexture1DEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT; +#define glNamedFramebufferTexture2DEXT glad_glNamedFramebufferTexture2DEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT; +#define glNamedFramebufferTexture3DEXT glad_glNamedFramebufferTexture3DEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT; +#define glNamedFramebufferTextureEXT glad_glNamedFramebufferTextureEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT; +#define glNamedFramebufferTextureFaceEXT glad_glNamedFramebufferTextureFaceEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; +#define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT; +#define glNamedFramebufferTextureLayerEXT glad_glNamedFramebufferTextureLayerEXT +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glNamedFramebufferTextureMultiviewOVR; +#define glNamedFramebufferTextureMultiviewOVR glad_glNamedFramebufferTextureMultiviewOVR +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT; +#define glNamedProgramLocalParameter4dEXT glad_glNamedProgramLocalParameter4dEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT; +#define glNamedProgramLocalParameter4dvEXT glad_glNamedProgramLocalParameter4dvEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT; +#define glNamedProgramLocalParameter4fEXT glad_glNamedProgramLocalParameter4fEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT; +#define glNamedProgramLocalParameter4fvEXT glad_glNamedProgramLocalParameter4fvEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT; +#define glNamedProgramLocalParameterI4iEXT glad_glNamedProgramLocalParameterI4iEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT; +#define glNamedProgramLocalParameterI4ivEXT glad_glNamedProgramLocalParameterI4ivEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT; +#define glNamedProgramLocalParameterI4uiEXT glad_glNamedProgramLocalParameterI4uiEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT; +#define glNamedProgramLocalParameterI4uivEXT glad_glNamedProgramLocalParameterI4uivEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT; +#define glNamedProgramLocalParameters4fvEXT glad_glNamedProgramLocalParameters4fvEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT; +#define glNamedProgramLocalParametersI4ivEXT glad_glNamedProgramLocalParametersI4ivEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT; +#define glNamedProgramLocalParametersI4uivEXT glad_glNamedProgramLocalParametersI4uivEXT +GLAD_API_CALL PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT; +#define glNamedProgramStringEXT glad_glNamedProgramStringEXT +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; +#define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT; +#define glNamedRenderbufferStorageEXT glad_glNamedRenderbufferStorageEXT +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; +#define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD; +#define glNamedRenderbufferStorageMultisampleAdvancedAMD glad_glNamedRenderbufferStorageMultisampleAdvancedAMD +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT; +#define glNamedRenderbufferStorageMultisampleCoverageEXT glad_glNamedRenderbufferStorageMultisampleCoverageEXT +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT; +#define glNamedRenderbufferStorageMultisampleEXT glad_glNamedRenderbufferStorageMultisampleEXT +GLAD_API_CALL PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB; +#define glNamedStringARB glad_glNamedStringARB +GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; +#define glNewList glad_glNewList +GLAD_API_CALL PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI; +#define glNewObjectBufferATI glad_glNewObjectBufferATI +GLAD_API_CALL PFNGLNORMAL3BPROC glad_glNormal3b; +#define glNormal3b glad_glNormal3b +GLAD_API_CALL PFNGLNORMAL3BVPROC glad_glNormal3bv; +#define glNormal3bv glad_glNormal3bv +GLAD_API_CALL PFNGLNORMAL3DPROC glad_glNormal3d; +#define glNormal3d glad_glNormal3d +GLAD_API_CALL PFNGLNORMAL3DVPROC glad_glNormal3dv; +#define glNormal3dv glad_glNormal3dv +GLAD_API_CALL PFNGLNORMAL3FPROC glad_glNormal3f; +#define glNormal3f glad_glNormal3f +GLAD_API_CALL PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN; +#define glNormal3fVertex3fSUN glad_glNormal3fVertex3fSUN +GLAD_API_CALL PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN; +#define glNormal3fVertex3fvSUN glad_glNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLNORMAL3FVPROC glad_glNormal3fv; +#define glNormal3fv glad_glNormal3fv +GLAD_API_CALL PFNGLNORMAL3HNVPROC glad_glNormal3hNV; +#define glNormal3hNV glad_glNormal3hNV +GLAD_API_CALL PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV; +#define glNormal3hvNV glad_glNormal3hvNV +GLAD_API_CALL PFNGLNORMAL3IPROC glad_glNormal3i; +#define glNormal3i glad_glNormal3i +GLAD_API_CALL PFNGLNORMAL3IVPROC glad_glNormal3iv; +#define glNormal3iv glad_glNormal3iv +GLAD_API_CALL PFNGLNORMAL3SPROC glad_glNormal3s; +#define glNormal3s glad_glNormal3s +GLAD_API_CALL PFNGLNORMAL3SVPROC glad_glNormal3sv; +#define glNormal3sv glad_glNormal3sv +GLAD_API_CALL PFNGLNORMAL3XOESPROC glad_glNormal3xOES; +#define glNormal3xOES glad_glNormal3xOES +GLAD_API_CALL PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES; +#define glNormal3xvOES glad_glNormal3xvOES +GLAD_API_CALL PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV; +#define glNormalFormatNV glad_glNormalFormatNV +GLAD_API_CALL PFNGLNORMALP3UIPROC glad_glNormalP3ui; +#define glNormalP3ui glad_glNormalP3ui +GLAD_API_CALL PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; +#define glNormalP3uiv glad_glNormalP3uiv +GLAD_API_CALL PFNGLNORMALPOINTERPROC glad_glNormalPointer; +#define glNormalPointer glad_glNormalPointer +GLAD_API_CALL PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT; +#define glNormalPointerEXT glad_glNormalPointerEXT +GLAD_API_CALL PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM; +#define glNormalPointerListIBM glad_glNormalPointerListIBM +GLAD_API_CALL PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL; +#define glNormalPointervINTEL glad_glNormalPointervINTEL +GLAD_API_CALL PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI; +#define glNormalStream3bATI glad_glNormalStream3bATI +GLAD_API_CALL PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI; +#define glNormalStream3bvATI glad_glNormalStream3bvATI +GLAD_API_CALL PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI; +#define glNormalStream3dATI glad_glNormalStream3dATI +GLAD_API_CALL PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI; +#define glNormalStream3dvATI glad_glNormalStream3dvATI +GLAD_API_CALL PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI; +#define glNormalStream3fATI glad_glNormalStream3fATI +GLAD_API_CALL PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI; +#define glNormalStream3fvATI glad_glNormalStream3fvATI +GLAD_API_CALL PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI; +#define glNormalStream3iATI glad_glNormalStream3iATI +GLAD_API_CALL PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI; +#define glNormalStream3ivATI glad_glNormalStream3ivATI +GLAD_API_CALL PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI; +#define glNormalStream3sATI glad_glNormalStream3sATI +GLAD_API_CALL PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI; +#define glNormalStream3svATI glad_glNormalStream3svATI +GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel; +#define glObjectLabel glad_glObjectLabel +GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; +#define glObjectPtrLabel glad_glObjectPtrLabel +GLAD_API_CALL PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE; +#define glObjectPurgeableAPPLE glad_glObjectPurgeableAPPLE +GLAD_API_CALL PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE; +#define glObjectUnpurgeableAPPLE glad_glObjectUnpurgeableAPPLE +GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; +#define glOrtho glad_glOrtho +GLAD_API_CALL PFNGLORTHOFOESPROC glad_glOrthofOES; +#define glOrthofOES glad_glOrthofOES +GLAD_API_CALL PFNGLORTHOXOESPROC glad_glOrthoxOES; +#define glOrthoxOES glad_glOrthoxOES +GLAD_API_CALL PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI; +#define glPNTrianglesfATI glad_glPNTrianglesfATI +GLAD_API_CALL PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI; +#define glPNTrianglesiATI glad_glPNTrianglesiATI +GLAD_API_CALL PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI; +#define glPassTexCoordATI glad_glPassTexCoordATI +GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; +#define glPassThrough glad_glPassThrough +GLAD_API_CALL PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES; +#define glPassThroughxOES glad_glPassThroughxOES +GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; +#define glPatchParameterfv glad_glPatchParameterfv +GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; +#define glPatchParameteri glad_glPatchParameteri +GLAD_API_CALL PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV; +#define glPathColorGenNV glad_glPathColorGenNV +GLAD_API_CALL PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV; +#define glPathCommandsNV glad_glPathCommandsNV +GLAD_API_CALL PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV; +#define glPathCoordsNV glad_glPathCoordsNV +GLAD_API_CALL PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV; +#define glPathCoverDepthFuncNV glad_glPathCoverDepthFuncNV +GLAD_API_CALL PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV; +#define glPathDashArrayNV glad_glPathDashArrayNV +GLAD_API_CALL PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV; +#define glPathFogGenNV glad_glPathFogGenNV +GLAD_API_CALL PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV; +#define glPathGlyphIndexArrayNV glad_glPathGlyphIndexArrayNV +GLAD_API_CALL PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV; +#define glPathGlyphIndexRangeNV glad_glPathGlyphIndexRangeNV +GLAD_API_CALL PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV; +#define glPathGlyphRangeNV glad_glPathGlyphRangeNV +GLAD_API_CALL PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV; +#define glPathGlyphsNV glad_glPathGlyphsNV +GLAD_API_CALL PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV; +#define glPathMemoryGlyphIndexArrayNV glad_glPathMemoryGlyphIndexArrayNV +GLAD_API_CALL PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV; +#define glPathParameterfNV glad_glPathParameterfNV +GLAD_API_CALL PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV; +#define glPathParameterfvNV glad_glPathParameterfvNV +GLAD_API_CALL PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV; +#define glPathParameteriNV glad_glPathParameteriNV +GLAD_API_CALL PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV; +#define glPathParameterivNV glad_glPathParameterivNV +GLAD_API_CALL PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV; +#define glPathStencilDepthOffsetNV glad_glPathStencilDepthOffsetNV +GLAD_API_CALL PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV; +#define glPathStencilFuncNV glad_glPathStencilFuncNV +GLAD_API_CALL PFNGLPATHSTRINGNVPROC glad_glPathStringNV; +#define glPathStringNV glad_glPathStringNV +GLAD_API_CALL PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV; +#define glPathSubCommandsNV glad_glPathSubCommandsNV +GLAD_API_CALL PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV; +#define glPathSubCoordsNV glad_glPathSubCoordsNV +GLAD_API_CALL PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV; +#define glPathTexGenNV glad_glPathTexGenNV +GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; +#define glPauseTransformFeedback glad_glPauseTransformFeedback +GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV; +#define glPauseTransformFeedbackNV glad_glPauseTransformFeedbackNV +GLAD_API_CALL PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV; +#define glPixelDataRangeNV glad_glPixelDataRangeNV +GLAD_API_CALL PFNGLPIXELMAPFVPROC glad_glPixelMapfv; +#define glPixelMapfv glad_glPixelMapfv +GLAD_API_CALL PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; +#define glPixelMapuiv glad_glPixelMapuiv +GLAD_API_CALL PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; +#define glPixelMapusv glad_glPixelMapusv +GLAD_API_CALL PFNGLPIXELMAPXPROC glad_glPixelMapx; +#define glPixelMapx glad_glPixelMapx +GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPIXELSTOREXPROC glad_glPixelStorex; +#define glPixelStorex glad_glPixelStorex +GLAD_API_CALL PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS; +#define glPixelTexGenParameterfSGIS glad_glPixelTexGenParameterfSGIS +GLAD_API_CALL PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS; +#define glPixelTexGenParameterfvSGIS glad_glPixelTexGenParameterfvSGIS +GLAD_API_CALL PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS; +#define glPixelTexGenParameteriSGIS glad_glPixelTexGenParameteriSGIS +GLAD_API_CALL PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS; +#define glPixelTexGenParameterivSGIS glad_glPixelTexGenParameterivSGIS +GLAD_API_CALL PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX; +#define glPixelTexGenSGIX glad_glPixelTexGenSGIX +GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; +#define glPixelTransferf glad_glPixelTransferf +GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; +#define glPixelTransferi glad_glPixelTransferi +GLAD_API_CALL PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES; +#define glPixelTransferxOES glad_glPixelTransferxOES +GLAD_API_CALL PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT; +#define glPixelTransformParameterfEXT glad_glPixelTransformParameterfEXT +GLAD_API_CALL PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT; +#define glPixelTransformParameterfvEXT glad_glPixelTransformParameterfvEXT +GLAD_API_CALL PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT; +#define glPixelTransformParameteriEXT glad_glPixelTransformParameteriEXT +GLAD_API_CALL PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT; +#define glPixelTransformParameterivEXT glad_glPixelTransformParameterivEXT +GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; +#define glPixelZoom glad_glPixelZoom +GLAD_API_CALL PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES; +#define glPixelZoomxOES glad_glPixelZoomxOES +GLAD_API_CALL PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV; +#define glPointAlongPathNV glad_glPointAlongPathNV +GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +GLAD_API_CALL PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB; +#define glPointParameterfARB glad_glPointParameterfARB +GLAD_API_CALL PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT; +#define glPointParameterfEXT glad_glPointParameterfEXT +GLAD_API_CALL PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS; +#define glPointParameterfSGIS glad_glPointParameterfSGIS +GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +GLAD_API_CALL PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB; +#define glPointParameterfvARB glad_glPointParameterfvARB +GLAD_API_CALL PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT; +#define glPointParameterfvEXT glad_glPointParameterfvEXT +GLAD_API_CALL PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS; +#define glPointParameterfvSGIS glad_glPointParameterfvSGIS +GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +GLAD_API_CALL PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV; +#define glPointParameteriNV glad_glPointParameteriNV +GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +GLAD_API_CALL PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV; +#define glPointParameterivNV glad_glPointParameterivNV +GLAD_API_CALL PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES; +#define glPointParameterxvOES glad_glPointParameterxvOES +GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +GLAD_API_CALL PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES; +#define glPointSizexOES glad_glPointSizexOES +GLAD_API_CALL PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX; +#define glPollAsyncSGIX glad_glPollAsyncSGIX +GLAD_API_CALL PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX; +#define glPollInstrumentsSGIX glad_glPollInstrumentsSGIX +GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; +#define glPolygonOffsetClamp glad_glPolygonOffsetClamp +GLAD_API_CALL PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT; +#define glPolygonOffsetClampEXT glad_glPolygonOffsetClampEXT +GLAD_API_CALL PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT; +#define glPolygonOffsetEXT glad_glPolygonOffsetEXT +GLAD_API_CALL PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES; +#define glPolygonOffsetxOES glad_glPolygonOffsetxOES +GLAD_API_CALL PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; +#define glPolygonStipple glad_glPolygonStipple +GLAD_API_CALL PFNGLPOPATTRIBPROC glad_glPopAttrib; +#define glPopAttrib glad_glPopAttrib +GLAD_API_CALL PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; +#define glPopClientAttrib glad_glPopClientAttrib +GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; +#define glPopDebugGroup glad_glPopDebugGroup +GLAD_API_CALL PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT; +#define glPopGroupMarkerEXT glad_glPopGroupMarkerEXT +GLAD_API_CALL PFNGLPOPMATRIXPROC glad_glPopMatrix; +#define glPopMatrix glad_glPopMatrix +GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; +#define glPopName glad_glPopName +GLAD_API_CALL PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV; +#define glPresentFrameDualFillNV glad_glPresentFrameDualFillNV +GLAD_API_CALL PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV; +#define glPresentFrameKeyedNV glad_glPresentFrameKeyedNV +GLAD_API_CALL PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB; +#define glPrimitiveBoundingBoxARB glad_glPrimitiveBoundingBoxARB +GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV; +#define glPrimitiveRestartIndexNV glad_glPrimitiveRestartIndexNV +GLAD_API_CALL PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV; +#define glPrimitiveRestartNV glad_glPrimitiveRestartNV +GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; +#define glPrioritizeTextures glad_glPrioritizeTextures +GLAD_API_CALL PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT; +#define glPrioritizeTexturesEXT glad_glPrioritizeTexturesEXT +GLAD_API_CALL PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES; +#define glPrioritizeTexturesxOES glad_glPrioritizeTexturesxOES +GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; +#define glProgramBinary glad_glProgramBinary +GLAD_API_CALL PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV; +#define glProgramBufferParametersIivNV glad_glProgramBufferParametersIivNV +GLAD_API_CALL PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV; +#define glProgramBufferParametersIuivNV glad_glProgramBufferParametersIuivNV +GLAD_API_CALL PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV; +#define glProgramBufferParametersfvNV glad_glProgramBufferParametersfvNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB; +#define glProgramEnvParameter4dARB glad_glProgramEnvParameter4dARB +GLAD_API_CALL PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB; +#define glProgramEnvParameter4dvARB glad_glProgramEnvParameter4dvARB +GLAD_API_CALL PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB; +#define glProgramEnvParameter4fARB glad_glProgramEnvParameter4fARB +GLAD_API_CALL PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB; +#define glProgramEnvParameter4fvARB glad_glProgramEnvParameter4fvARB +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV; +#define glProgramEnvParameterI4iNV glad_glProgramEnvParameterI4iNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV; +#define glProgramEnvParameterI4ivNV glad_glProgramEnvParameterI4ivNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV; +#define glProgramEnvParameterI4uiNV glad_glProgramEnvParameterI4uiNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV; +#define glProgramEnvParameterI4uivNV glad_glProgramEnvParameterI4uivNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT; +#define glProgramEnvParameters4fvEXT glad_glProgramEnvParameters4fvEXT +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV; +#define glProgramEnvParametersI4ivNV glad_glProgramEnvParametersI4ivNV +GLAD_API_CALL PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV; +#define glProgramEnvParametersI4uivNV glad_glProgramEnvParametersI4uivNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB; +#define glProgramLocalParameter4dARB glad_glProgramLocalParameter4dARB +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB; +#define glProgramLocalParameter4dvARB glad_glProgramLocalParameter4dvARB +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB; +#define glProgramLocalParameter4fARB glad_glProgramLocalParameter4fARB +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB; +#define glProgramLocalParameter4fvARB glad_glProgramLocalParameter4fvARB +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV; +#define glProgramLocalParameterI4iNV glad_glProgramLocalParameterI4iNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV; +#define glProgramLocalParameterI4ivNV glad_glProgramLocalParameterI4ivNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV; +#define glProgramLocalParameterI4uiNV glad_glProgramLocalParameterI4uiNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV; +#define glProgramLocalParameterI4uivNV glad_glProgramLocalParameterI4uivNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT; +#define glProgramLocalParameters4fvEXT glad_glProgramLocalParameters4fvEXT +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV; +#define glProgramLocalParametersI4ivNV glad_glProgramLocalParametersI4ivNV +GLAD_API_CALL PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV; +#define glProgramLocalParametersI4uivNV glad_glProgramLocalParametersI4uivNV +GLAD_API_CALL PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV; +#define glProgramNamedParameter4dNV glad_glProgramNamedParameter4dNV +GLAD_API_CALL PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV; +#define glProgramNamedParameter4dvNV glad_glProgramNamedParameter4dvNV +GLAD_API_CALL PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV; +#define glProgramNamedParameter4fNV glad_glProgramNamedParameter4fNV +GLAD_API_CALL PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV; +#define glProgramNamedParameter4fvNV glad_glProgramNamedParameter4fvNV +GLAD_API_CALL PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV; +#define glProgramParameter4dNV glad_glProgramParameter4dNV +GLAD_API_CALL PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV; +#define glProgramParameter4dvNV glad_glProgramParameter4dvNV +GLAD_API_CALL PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV; +#define glProgramParameter4fNV glad_glProgramParameter4fNV +GLAD_API_CALL PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV; +#define glProgramParameter4fvNV glad_glProgramParameter4fvNV +GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; +#define glProgramParameteri glad_glProgramParameteri +GLAD_API_CALL PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB; +#define glProgramParameteriARB glad_glProgramParameteriARB +GLAD_API_CALL PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT; +#define glProgramParameteriEXT glad_glProgramParameteriEXT +GLAD_API_CALL PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV; +#define glProgramParameters4dvNV glad_glProgramParameters4dvNV +GLAD_API_CALL PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV; +#define glProgramParameters4fvNV glad_glProgramParameters4fvNV +GLAD_API_CALL PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV; +#define glProgramPathFragmentInputGenNV glad_glProgramPathFragmentInputGenNV +GLAD_API_CALL PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB; +#define glProgramStringARB glad_glProgramStringARB +GLAD_API_CALL PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV; +#define glProgramSubroutineParametersuivNV glad_glProgramSubroutineParametersuivNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; +#define glProgramUniform1d glad_glProgramUniform1d +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT; +#define glProgramUniform1dEXT glad_glProgramUniform1dEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; +#define glProgramUniform1dv glad_glProgramUniform1dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT; +#define glProgramUniform1dvEXT glad_glProgramUniform1dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; +#define glProgramUniform1f glad_glProgramUniform1f +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT; +#define glProgramUniform1fEXT glad_glProgramUniform1fEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; +#define glProgramUniform1fv glad_glProgramUniform1fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT; +#define glProgramUniform1fvEXT glad_glProgramUniform1fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; +#define glProgramUniform1i glad_glProgramUniform1i +GLAD_API_CALL PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB; +#define glProgramUniform1i64ARB glad_glProgramUniform1i64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV; +#define glProgramUniform1i64NV glad_glProgramUniform1i64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB; +#define glProgramUniform1i64vARB glad_glProgramUniform1i64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV; +#define glProgramUniform1i64vNV glad_glProgramUniform1i64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT; +#define glProgramUniform1iEXT glad_glProgramUniform1iEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; +#define glProgramUniform1iv glad_glProgramUniform1iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT; +#define glProgramUniform1ivEXT glad_glProgramUniform1ivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; +#define glProgramUniform1ui glad_glProgramUniform1ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB; +#define glProgramUniform1ui64ARB glad_glProgramUniform1ui64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV; +#define glProgramUniform1ui64NV glad_glProgramUniform1ui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB; +#define glProgramUniform1ui64vARB glad_glProgramUniform1ui64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV; +#define glProgramUniform1ui64vNV glad_glProgramUniform1ui64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT; +#define glProgramUniform1uiEXT glad_glProgramUniform1uiEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; +#define glProgramUniform1uiv glad_glProgramUniform1uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT; +#define glProgramUniform1uivEXT glad_glProgramUniform1uivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; +#define glProgramUniform2d glad_glProgramUniform2d +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT; +#define glProgramUniform2dEXT glad_glProgramUniform2dEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; +#define glProgramUniform2dv glad_glProgramUniform2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT; +#define glProgramUniform2dvEXT glad_glProgramUniform2dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; +#define glProgramUniform2f glad_glProgramUniform2f +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT; +#define glProgramUniform2fEXT glad_glProgramUniform2fEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; +#define glProgramUniform2fv glad_glProgramUniform2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT; +#define glProgramUniform2fvEXT glad_glProgramUniform2fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; +#define glProgramUniform2i glad_glProgramUniform2i +GLAD_API_CALL PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB; +#define glProgramUniform2i64ARB glad_glProgramUniform2i64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV; +#define glProgramUniform2i64NV glad_glProgramUniform2i64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB; +#define glProgramUniform2i64vARB glad_glProgramUniform2i64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV; +#define glProgramUniform2i64vNV glad_glProgramUniform2i64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT; +#define glProgramUniform2iEXT glad_glProgramUniform2iEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; +#define glProgramUniform2iv glad_glProgramUniform2iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT; +#define glProgramUniform2ivEXT glad_glProgramUniform2ivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; +#define glProgramUniform2ui glad_glProgramUniform2ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB; +#define glProgramUniform2ui64ARB glad_glProgramUniform2ui64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV; +#define glProgramUniform2ui64NV glad_glProgramUniform2ui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB; +#define glProgramUniform2ui64vARB glad_glProgramUniform2ui64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV; +#define glProgramUniform2ui64vNV glad_glProgramUniform2ui64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT; +#define glProgramUniform2uiEXT glad_glProgramUniform2uiEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; +#define glProgramUniform2uiv glad_glProgramUniform2uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT; +#define glProgramUniform2uivEXT glad_glProgramUniform2uivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; +#define glProgramUniform3d glad_glProgramUniform3d +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT; +#define glProgramUniform3dEXT glad_glProgramUniform3dEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; +#define glProgramUniform3dv glad_glProgramUniform3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT; +#define glProgramUniform3dvEXT glad_glProgramUniform3dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; +#define glProgramUniform3f glad_glProgramUniform3f +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT; +#define glProgramUniform3fEXT glad_glProgramUniform3fEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; +#define glProgramUniform3fv glad_glProgramUniform3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT; +#define glProgramUniform3fvEXT glad_glProgramUniform3fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; +#define glProgramUniform3i glad_glProgramUniform3i +GLAD_API_CALL PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB; +#define glProgramUniform3i64ARB glad_glProgramUniform3i64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV; +#define glProgramUniform3i64NV glad_glProgramUniform3i64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB; +#define glProgramUniform3i64vARB glad_glProgramUniform3i64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV; +#define glProgramUniform3i64vNV glad_glProgramUniform3i64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT; +#define glProgramUniform3iEXT glad_glProgramUniform3iEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; +#define glProgramUniform3iv glad_glProgramUniform3iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT; +#define glProgramUniform3ivEXT glad_glProgramUniform3ivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; +#define glProgramUniform3ui glad_glProgramUniform3ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB; +#define glProgramUniform3ui64ARB glad_glProgramUniform3ui64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV; +#define glProgramUniform3ui64NV glad_glProgramUniform3ui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB; +#define glProgramUniform3ui64vARB glad_glProgramUniform3ui64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV; +#define glProgramUniform3ui64vNV glad_glProgramUniform3ui64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT; +#define glProgramUniform3uiEXT glad_glProgramUniform3uiEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; +#define glProgramUniform3uiv glad_glProgramUniform3uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT; +#define glProgramUniform3uivEXT glad_glProgramUniform3uivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; +#define glProgramUniform4d glad_glProgramUniform4d +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT; +#define glProgramUniform4dEXT glad_glProgramUniform4dEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; +#define glProgramUniform4dv glad_glProgramUniform4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT; +#define glProgramUniform4dvEXT glad_glProgramUniform4dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; +#define glProgramUniform4f glad_glProgramUniform4f +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT; +#define glProgramUniform4fEXT glad_glProgramUniform4fEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; +#define glProgramUniform4fv glad_glProgramUniform4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT; +#define glProgramUniform4fvEXT glad_glProgramUniform4fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; +#define glProgramUniform4i glad_glProgramUniform4i +GLAD_API_CALL PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB; +#define glProgramUniform4i64ARB glad_glProgramUniform4i64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV; +#define glProgramUniform4i64NV glad_glProgramUniform4i64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB; +#define glProgramUniform4i64vARB glad_glProgramUniform4i64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV; +#define glProgramUniform4i64vNV glad_glProgramUniform4i64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT; +#define glProgramUniform4iEXT glad_glProgramUniform4iEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; +#define glProgramUniform4iv glad_glProgramUniform4iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT; +#define glProgramUniform4ivEXT glad_glProgramUniform4ivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; +#define glProgramUniform4ui glad_glProgramUniform4ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB; +#define glProgramUniform4ui64ARB glad_glProgramUniform4ui64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV; +#define glProgramUniform4ui64NV glad_glProgramUniform4ui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB; +#define glProgramUniform4ui64vARB glad_glProgramUniform4ui64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV; +#define glProgramUniform4ui64vNV glad_glProgramUniform4ui64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT; +#define glProgramUniform4uiEXT glad_glProgramUniform4uiEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; +#define glProgramUniform4uiv glad_glProgramUniform4uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT; +#define glProgramUniform4uivEXT glad_glProgramUniform4uivEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB; +#define glProgramUniformHandleui64ARB glad_glProgramUniformHandleui64ARB +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV; +#define glProgramUniformHandleui64NV glad_glProgramUniformHandleui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB; +#define glProgramUniformHandleui64vARB glad_glProgramUniformHandleui64vARB +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV; +#define glProgramUniformHandleui64vNV glad_glProgramUniformHandleui64vNV +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; +#define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT; +#define glProgramUniformMatrix2dvEXT glad_glProgramUniformMatrix2dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; +#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT; +#define glProgramUniformMatrix2fvEXT glad_glProgramUniformMatrix2fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; +#define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT; +#define glProgramUniformMatrix2x3dvEXT glad_glProgramUniformMatrix2x3dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; +#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT; +#define glProgramUniformMatrix2x3fvEXT glad_glProgramUniformMatrix2x3fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; +#define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT; +#define glProgramUniformMatrix2x4dvEXT glad_glProgramUniformMatrix2x4dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; +#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT; +#define glProgramUniformMatrix2x4fvEXT glad_glProgramUniformMatrix2x4fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; +#define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT; +#define glProgramUniformMatrix3dvEXT glad_glProgramUniformMatrix3dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; +#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT; +#define glProgramUniformMatrix3fvEXT glad_glProgramUniformMatrix3fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; +#define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT; +#define glProgramUniformMatrix3x2dvEXT glad_glProgramUniformMatrix3x2dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; +#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT; +#define glProgramUniformMatrix3x2fvEXT glad_glProgramUniformMatrix3x2fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; +#define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT; +#define glProgramUniformMatrix3x4dvEXT glad_glProgramUniformMatrix3x4dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; +#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT; +#define glProgramUniformMatrix3x4fvEXT glad_glProgramUniformMatrix3x4fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; +#define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT; +#define glProgramUniformMatrix4dvEXT glad_glProgramUniformMatrix4dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; +#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT; +#define glProgramUniformMatrix4fvEXT glad_glProgramUniformMatrix4fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; +#define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT; +#define glProgramUniformMatrix4x2dvEXT glad_glProgramUniformMatrix4x2dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; +#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT; +#define glProgramUniformMatrix4x2fvEXT glad_glProgramUniformMatrix4x2fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; +#define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT; +#define glProgramUniformMatrix4x3dvEXT glad_glProgramUniformMatrix4x3dvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; +#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT; +#define glProgramUniformMatrix4x3fvEXT glad_glProgramUniformMatrix4x3fvEXT +GLAD_API_CALL PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV; +#define glProgramUniformui64NV glad_glProgramUniformui64NV +GLAD_API_CALL PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV; +#define glProgramUniformui64vNV glad_glProgramUniformui64vNV +GLAD_API_CALL PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV; +#define glProgramVertexLimitNV glad_glProgramVertexLimitNV +GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +GLAD_API_CALL PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT; +#define glProvokingVertexEXT glad_glProvokingVertexEXT +GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; +#define glPushAttrib glad_glPushAttrib +GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; +#define glPushClientAttrib glad_glPushClientAttrib +GLAD_API_CALL PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT; +#define glPushClientAttribDefaultEXT glad_glPushClientAttribDefaultEXT +GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; +#define glPushDebugGroup glad_glPushDebugGroup +GLAD_API_CALL PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT; +#define glPushGroupMarkerEXT glad_glPushGroupMarkerEXT +GLAD_API_CALL PFNGLPUSHMATRIXPROC glad_glPushMatrix; +#define glPushMatrix glad_glPushMatrix +GLAD_API_CALL PFNGLPUSHNAMEPROC glad_glPushName; +#define glPushName glad_glPushName +GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; +#define glQueryCounter glad_glQueryCounter +GLAD_API_CALL PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES; +#define glQueryMatrixxOES glad_glQueryMatrixxOES +GLAD_API_CALL PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD; +#define glQueryObjectParameteruiAMD glad_glQueryObjectParameteruiAMD +GLAD_API_CALL PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV; +#define glQueryResourceNV glad_glQueryResourceNV +GLAD_API_CALL PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV; +#define glQueryResourceTagNV glad_glQueryResourceTagNV +GLAD_API_CALL PFNGLRASTERPOS2DPROC glad_glRasterPos2d; +#define glRasterPos2d glad_glRasterPos2d +GLAD_API_CALL PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; +#define glRasterPos2dv glad_glRasterPos2dv +GLAD_API_CALL PFNGLRASTERPOS2FPROC glad_glRasterPos2f; +#define glRasterPos2f glad_glRasterPos2f +GLAD_API_CALL PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; +#define glRasterPos2fv glad_glRasterPos2fv +GLAD_API_CALL PFNGLRASTERPOS2IPROC glad_glRasterPos2i; +#define glRasterPos2i glad_glRasterPos2i +GLAD_API_CALL PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; +#define glRasterPos2iv glad_glRasterPos2iv +GLAD_API_CALL PFNGLRASTERPOS2SPROC glad_glRasterPos2s; +#define glRasterPos2s glad_glRasterPos2s +GLAD_API_CALL PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; +#define glRasterPos2sv glad_glRasterPos2sv +GLAD_API_CALL PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES; +#define glRasterPos2xOES glad_glRasterPos2xOES +GLAD_API_CALL PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES; +#define glRasterPos2xvOES glad_glRasterPos2xvOES +GLAD_API_CALL PFNGLRASTERPOS3DPROC glad_glRasterPos3d; +#define glRasterPos3d glad_glRasterPos3d +GLAD_API_CALL PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; +#define glRasterPos3dv glad_glRasterPos3dv +GLAD_API_CALL PFNGLRASTERPOS3FPROC glad_glRasterPos3f; +#define glRasterPos3f glad_glRasterPos3f +GLAD_API_CALL PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; +#define glRasterPos3fv glad_glRasterPos3fv +GLAD_API_CALL PFNGLRASTERPOS3IPROC glad_glRasterPos3i; +#define glRasterPos3i glad_glRasterPos3i +GLAD_API_CALL PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; +#define glRasterPos3iv glad_glRasterPos3iv +GLAD_API_CALL PFNGLRASTERPOS3SPROC glad_glRasterPos3s; +#define glRasterPos3s glad_glRasterPos3s +GLAD_API_CALL PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; +#define glRasterPos3sv glad_glRasterPos3sv +GLAD_API_CALL PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES; +#define glRasterPos3xOES glad_glRasterPos3xOES +GLAD_API_CALL PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES; +#define glRasterPos3xvOES glad_glRasterPos3xvOES +GLAD_API_CALL PFNGLRASTERPOS4DPROC glad_glRasterPos4d; +#define glRasterPos4d glad_glRasterPos4d +GLAD_API_CALL PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; +#define glRasterPos4dv glad_glRasterPos4dv +GLAD_API_CALL PFNGLRASTERPOS4FPROC glad_glRasterPos4f; +#define glRasterPos4f glad_glRasterPos4f +GLAD_API_CALL PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; +#define glRasterPos4fv glad_glRasterPos4fv +GLAD_API_CALL PFNGLRASTERPOS4IPROC glad_glRasterPos4i; +#define glRasterPos4i glad_glRasterPos4i +GLAD_API_CALL PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; +#define glRasterPos4iv glad_glRasterPos4iv +GLAD_API_CALL PFNGLRASTERPOS4SPROC glad_glRasterPos4s; +#define glRasterPos4s glad_glRasterPos4s +GLAD_API_CALL PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; +#define glRasterPos4sv glad_glRasterPos4sv +GLAD_API_CALL PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES; +#define glRasterPos4xOES glad_glRasterPos4xOES +GLAD_API_CALL PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES; +#define glRasterPos4xvOES glad_glRasterPos4xvOES +GLAD_API_CALL PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT; +#define glRasterSamplesEXT glad_glRasterSamplesEXT +GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +GLAD_API_CALL PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX; +#define glReadInstrumentsSGIX glad_glReadInstrumentsSGIX +GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels; +#define glReadnPixels glad_glReadnPixels +GLAD_API_CALL PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; +#define glReadnPixelsARB glad_glReadnPixelsARB +GLAD_API_CALL PFNGLRECTDPROC glad_glRectd; +#define glRectd glad_glRectd +GLAD_API_CALL PFNGLRECTDVPROC glad_glRectdv; +#define glRectdv glad_glRectdv +GLAD_API_CALL PFNGLRECTFPROC glad_glRectf; +#define glRectf glad_glRectf +GLAD_API_CALL PFNGLRECTFVPROC glad_glRectfv; +#define glRectfv glad_glRectfv +GLAD_API_CALL PFNGLRECTIPROC glad_glRecti; +#define glRecti glad_glRecti +GLAD_API_CALL PFNGLRECTIVPROC glad_glRectiv; +#define glRectiv glad_glRectiv +GLAD_API_CALL PFNGLRECTSPROC glad_glRects; +#define glRects glad_glRects +GLAD_API_CALL PFNGLRECTSVPROC glad_glRectsv; +#define glRectsv glad_glRectsv +GLAD_API_CALL PFNGLRECTXOESPROC glad_glRectxOES; +#define glRectxOES glad_glRectxOES +GLAD_API_CALL PFNGLRECTXVOESPROC glad_glRectxvOES; +#define glRectxvOES glad_glRectxvOES +GLAD_API_CALL PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX; +#define glReferencePlaneSGIX glad_glReferencePlaneSGIX +GLAD_API_CALL PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT; +#define glReleaseKeyedMutexWin32EXT glad_glReleaseKeyedMutexWin32EXT +GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; +#define glReleaseShaderCompiler glad_glReleaseShaderCompiler +GLAD_API_CALL PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV; +#define glRenderGpuMaskNV glad_glRenderGpuMaskNV +GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; +#define glRenderMode glad_glRenderMode +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; +#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD; +#define glRenderbufferStorageMultisampleAdvancedAMD glad_glRenderbufferStorageMultisampleAdvancedAMD +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV; +#define glRenderbufferStorageMultisampleCoverageNV glad_glRenderbufferStorageMultisampleCoverageNV +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; +#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT +GLAD_API_CALL PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN; +#define glReplacementCodePointerSUN glad_glReplacementCodePointerSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN; +#define glReplacementCodeubSUN glad_glReplacementCodeubSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN; +#define glReplacementCodeubvSUN glad_glReplacementCodeubvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN; +#define glReplacementCodeuiColor3fVertex3fSUN glad_glReplacementCodeuiColor3fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN; +#define glReplacementCodeuiColor3fVertex3fvSUN glad_glReplacementCodeuiColor3fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN; +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN; +#define glReplacementCodeuiColor4ubVertex3fSUN glad_glReplacementCodeuiColor4ubVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN; +#define glReplacementCodeuiColor4ubVertex3fvSUN glad_glReplacementCodeuiColor4ubVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN; +#define glReplacementCodeuiNormal3fVertex3fSUN glad_glReplacementCodeuiNormal3fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN; +#define glReplacementCodeuiNormal3fVertex3fvSUN glad_glReplacementCodeuiNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN; +#define glReplacementCodeuiSUN glad_glReplacementCodeuiSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN; +#define glReplacementCodeuiTexCoord2fVertex3fSUN glad_glReplacementCodeuiTexCoord2fVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN; +#define glReplacementCodeuiTexCoord2fVertex3fvSUN glad_glReplacementCodeuiTexCoord2fVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN; +#define glReplacementCodeuiVertex3fSUN glad_glReplacementCodeuiVertex3fSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN; +#define glReplacementCodeuiVertex3fvSUN glad_glReplacementCodeuiVertex3fvSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN; +#define glReplacementCodeuivSUN glad_glReplacementCodeuivSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN; +#define glReplacementCodeusSUN glad_glReplacementCodeusSUN +GLAD_API_CALL PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN; +#define glReplacementCodeusvSUN glad_glReplacementCodeusvSUN +GLAD_API_CALL PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV; +#define glRequestResidentProgramsNV glad_glRequestResidentProgramsNV +GLAD_API_CALL PFNGLRESETHISTOGRAMPROC glad_glResetHistogram; +#define glResetHistogram glad_glResetHistogram +GLAD_API_CALL PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT; +#define glResetHistogramEXT glad_glResetHistogramEXT +GLAD_API_CALL PFNGLRESETMEMORYOBJECTPARAMETERNVPROC glad_glResetMemoryObjectParameterNV; +#define glResetMemoryObjectParameterNV glad_glResetMemoryObjectParameterNV +GLAD_API_CALL PFNGLRESETMINMAXPROC glad_glResetMinmax; +#define glResetMinmax glad_glResetMinmax +GLAD_API_CALL PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT; +#define glResetMinmaxEXT glad_glResetMinmaxEXT +GLAD_API_CALL PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA; +#define glResizeBuffersMESA glad_glResizeBuffersMESA +GLAD_API_CALL PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV; +#define glResolveDepthValuesNV glad_glResolveDepthValuesNV +GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; +#define glResumeTransformFeedback glad_glResumeTransformFeedback +GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV; +#define glResumeTransformFeedbackNV glad_glResumeTransformFeedbackNV +GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; +#define glRotated glad_glRotated +GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; +#define glRotatef glad_glRotatef +GLAD_API_CALL PFNGLROTATEXOESPROC glad_glRotatexOES; +#define glRotatexOES glad_glRotatexOES +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; +#define glSampleCoverageARB glad_glSampleCoverageARB +GLAD_API_CALL PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI; +#define glSampleMapATI glad_glSampleMapATI +GLAD_API_CALL PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT; +#define glSampleMaskEXT glad_glSampleMaskEXT +GLAD_API_CALL PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV; +#define glSampleMaskIndexedNV glad_glSampleMaskIndexedNV +GLAD_API_CALL PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS; +#define glSampleMaskSGIS glad_glSampleMaskSGIS +GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +GLAD_API_CALL PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT; +#define glSamplePatternEXT glad_glSamplePatternEXT +GLAD_API_CALL PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS; +#define glSamplePatternSGIS glad_glSamplePatternSGIS +GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; +#define glSamplerParameterIiv glad_glSamplerParameterIiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; +#define glSamplerParameterIuiv glad_glSamplerParameterIuiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +GLAD_API_CALL PFNGLSCALEDPROC glad_glScaled; +#define glScaled glad_glScaled +GLAD_API_CALL PFNGLSCALEFPROC glad_glScalef; +#define glScalef glad_glScalef +GLAD_API_CALL PFNGLSCALEXOESPROC glad_glScalexOES; +#define glScalexOES glad_glScalexOES +GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; +#define glScissorArrayv glad_glScissorArrayv +GLAD_API_CALL PFNGLSCISSOREXCLUSIVEARRAYVNVPROC glad_glScissorExclusiveArrayvNV; +#define glScissorExclusiveArrayvNV glad_glScissorExclusiveArrayvNV +GLAD_API_CALL PFNGLSCISSOREXCLUSIVENVPROC glad_glScissorExclusiveNV; +#define glScissorExclusiveNV glad_glScissorExclusiveNV +GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; +#define glScissorIndexed glad_glScissorIndexed +GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; +#define glScissorIndexedv glad_glScissorIndexedv +GLAD_API_CALL PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; +#define glSecondaryColor3b glad_glSecondaryColor3b +GLAD_API_CALL PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT; +#define glSecondaryColor3bEXT glad_glSecondaryColor3bEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; +#define glSecondaryColor3bv glad_glSecondaryColor3bv +GLAD_API_CALL PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT; +#define glSecondaryColor3bvEXT glad_glSecondaryColor3bvEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; +#define glSecondaryColor3d glad_glSecondaryColor3d +GLAD_API_CALL PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT; +#define glSecondaryColor3dEXT glad_glSecondaryColor3dEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; +#define glSecondaryColor3dv glad_glSecondaryColor3dv +GLAD_API_CALL PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT; +#define glSecondaryColor3dvEXT glad_glSecondaryColor3dvEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; +#define glSecondaryColor3f glad_glSecondaryColor3f +GLAD_API_CALL PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT; +#define glSecondaryColor3fEXT glad_glSecondaryColor3fEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; +#define glSecondaryColor3fv glad_glSecondaryColor3fv +GLAD_API_CALL PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT; +#define glSecondaryColor3fvEXT glad_glSecondaryColor3fvEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV; +#define glSecondaryColor3hNV glad_glSecondaryColor3hNV +GLAD_API_CALL PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV; +#define glSecondaryColor3hvNV glad_glSecondaryColor3hvNV +GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; +#define glSecondaryColor3i glad_glSecondaryColor3i +GLAD_API_CALL PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT; +#define glSecondaryColor3iEXT glad_glSecondaryColor3iEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; +#define glSecondaryColor3iv glad_glSecondaryColor3iv +GLAD_API_CALL PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT; +#define glSecondaryColor3ivEXT glad_glSecondaryColor3ivEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; +#define glSecondaryColor3s glad_glSecondaryColor3s +GLAD_API_CALL PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT; +#define glSecondaryColor3sEXT glad_glSecondaryColor3sEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; +#define glSecondaryColor3sv glad_glSecondaryColor3sv +GLAD_API_CALL PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT; +#define glSecondaryColor3svEXT glad_glSecondaryColor3svEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; +#define glSecondaryColor3ub glad_glSecondaryColor3ub +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT; +#define glSecondaryColor3ubEXT glad_glSecondaryColor3ubEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; +#define glSecondaryColor3ubv glad_glSecondaryColor3ubv +GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT; +#define glSecondaryColor3ubvEXT glad_glSecondaryColor3ubvEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; +#define glSecondaryColor3ui glad_glSecondaryColor3ui +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT; +#define glSecondaryColor3uiEXT glad_glSecondaryColor3uiEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; +#define glSecondaryColor3uiv glad_glSecondaryColor3uiv +GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT; +#define glSecondaryColor3uivEXT glad_glSecondaryColor3uivEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; +#define glSecondaryColor3us glad_glSecondaryColor3us +GLAD_API_CALL PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT; +#define glSecondaryColor3usEXT glad_glSecondaryColor3usEXT +GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; +#define glSecondaryColor3usv glad_glSecondaryColor3usv +GLAD_API_CALL PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT; +#define glSecondaryColor3usvEXT glad_glSecondaryColor3usvEXT +GLAD_API_CALL PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV; +#define glSecondaryColorFormatNV glad_glSecondaryColorFormatNV +GLAD_API_CALL PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; +#define glSecondaryColorP3ui glad_glSecondaryColorP3ui +GLAD_API_CALL PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; +#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv +GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; +#define glSecondaryColorPointer glad_glSecondaryColorPointer +GLAD_API_CALL PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT; +#define glSecondaryColorPointerEXT glad_glSecondaryColorPointerEXT +GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM; +#define glSecondaryColorPointerListIBM glad_glSecondaryColorPointerListIBM +GLAD_API_CALL PFNGLSELECTBUFFERPROC glad_glSelectBuffer; +#define glSelectBuffer glad_glSelectBuffer +GLAD_API_CALL PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD; +#define glSelectPerfMonitorCountersAMD glad_glSelectPerfMonitorCountersAMD +GLAD_API_CALL PFNGLSEMAPHOREPARAMETERIVNVPROC glad_glSemaphoreParameterivNV; +#define glSemaphoreParameterivNV glad_glSemaphoreParameterivNV +GLAD_API_CALL PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT; +#define glSemaphoreParameterui64vEXT glad_glSemaphoreParameterui64vEXT +GLAD_API_CALL PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D; +#define glSeparableFilter2D glad_glSeparableFilter2D +GLAD_API_CALL PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT; +#define glSeparableFilter2DEXT glad_glSeparableFilter2DEXT +GLAD_API_CALL PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE; +#define glSetFenceAPPLE glad_glSetFenceAPPLE +GLAD_API_CALL PFNGLSETFENCENVPROC glad_glSetFenceNV; +#define glSetFenceNV glad_glSetFenceNV +GLAD_API_CALL PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI; +#define glSetFragmentShaderConstantATI glad_glSetFragmentShaderConstantATI +GLAD_API_CALL PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT; +#define glSetInvariantEXT glad_glSetInvariantEXT +GLAD_API_CALL PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT; +#define glSetLocalConstantEXT glad_glSetLocalConstantEXT +GLAD_API_CALL PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD; +#define glSetMultisamplefvAMD glad_glSetMultisamplefvAMD +GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; +#define glShadeModel glad_glShadeModel +GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; +#define glShaderBinary glad_glShaderBinary +GLAD_API_CALL PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT; +#define glShaderOp1EXT glad_glShaderOp1EXT +GLAD_API_CALL PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT; +#define glShaderOp2EXT glad_glShaderOp2EXT +GLAD_API_CALL PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT; +#define glShaderOp3EXT glad_glShaderOp3EXT +GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +GLAD_API_CALL PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB; +#define glShaderSourceARB glad_glShaderSourceARB +GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; +#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding +GLAD_API_CALL PFNGLSHADINGRATEIMAGEBARRIERNVPROC glad_glShadingRateImageBarrierNV; +#define glShadingRateImageBarrierNV glad_glShadingRateImageBarrierNV +GLAD_API_CALL PFNGLSHADINGRATEIMAGEPALETTENVPROC glad_glShadingRateImagePaletteNV; +#define glShadingRateImagePaletteNV glad_glShadingRateImagePaletteNV +GLAD_API_CALL PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC glad_glShadingRateSampleOrderCustomNV; +#define glShadingRateSampleOrderCustomNV glad_glShadingRateSampleOrderCustomNV +GLAD_API_CALL PFNGLSHADINGRATESAMPLEORDERNVPROC glad_glShadingRateSampleOrderNV; +#define glShadingRateSampleOrderNV glad_glShadingRateSampleOrderNV +GLAD_API_CALL PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS; +#define glSharpenTexFuncSGIS glad_glSharpenTexFuncSGIS +GLAD_API_CALL PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT; +#define glSignalSemaphoreEXT glad_glSignalSemaphoreEXT +GLAD_API_CALL PFNGLSIGNALSEMAPHOREUI64NVXPROC glad_glSignalSemaphoreui64NVX; +#define glSignalSemaphoreui64NVX glad_glSignalSemaphoreui64NVX +GLAD_API_CALL PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV; +#define glSignalVkFenceNV glad_glSignalVkFenceNV +GLAD_API_CALL PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV; +#define glSignalVkSemaphoreNV glad_glSignalVkSemaphoreNV +GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader; +#define glSpecializeShader glad_glSpecializeShader +GLAD_API_CALL PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB; +#define glSpecializeShaderARB glad_glSpecializeShaderARB +GLAD_API_CALL PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX; +#define glSpriteParameterfSGIX glad_glSpriteParameterfSGIX +GLAD_API_CALL PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX; +#define glSpriteParameterfvSGIX glad_glSpriteParameterfvSGIX +GLAD_API_CALL PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX; +#define glSpriteParameteriSGIX glad_glSpriteParameteriSGIX +GLAD_API_CALL PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX; +#define glSpriteParameterivSGIX glad_glSpriteParameterivSGIX +GLAD_API_CALL PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX; +#define glStartInstrumentsSGIX glad_glStartInstrumentsSGIX +GLAD_API_CALL PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV; +#define glStateCaptureNV glad_glStateCaptureNV +GLAD_API_CALL PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT; +#define glStencilClearTagEXT glad_glStencilClearTagEXT +GLAD_API_CALL PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV; +#define glStencilFillPathInstancedNV glad_glStencilFillPathInstancedNV +GLAD_API_CALL PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV; +#define glStencilFillPathNV glad_glStencilFillPathNV +GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI; +#define glStencilFuncSeparateATI glad_glStencilFuncSeparateATI +GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +GLAD_API_CALL PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI; +#define glStencilOpSeparateATI glad_glStencilOpSeparateATI +GLAD_API_CALL PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD; +#define glStencilOpValueAMD glad_glStencilOpValueAMD +GLAD_API_CALL PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV; +#define glStencilStrokePathInstancedNV glad_glStencilStrokePathInstancedNV +GLAD_API_CALL PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV; +#define glStencilStrokePathNV glad_glStencilStrokePathNV +GLAD_API_CALL PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV; +#define glStencilThenCoverFillPathInstancedNV glad_glStencilThenCoverFillPathInstancedNV +GLAD_API_CALL PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV; +#define glStencilThenCoverFillPathNV glad_glStencilThenCoverFillPathNV +GLAD_API_CALL PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV; +#define glStencilThenCoverStrokePathInstancedNV glad_glStencilThenCoverStrokePathInstancedNV +GLAD_API_CALL PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV; +#define glStencilThenCoverStrokePathNV glad_glStencilThenCoverStrokePathNV +GLAD_API_CALL PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX; +#define glStopInstrumentsSGIX glad_glStopInstrumentsSGIX +GLAD_API_CALL PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY; +#define glStringMarkerGREMEDY glad_glStringMarkerGREMEDY +GLAD_API_CALL PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV; +#define glSubpixelPrecisionBiasNV glad_glSubpixelPrecisionBiasNV +GLAD_API_CALL PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT; +#define glSwizzleEXT glad_glSwizzleEXT +GLAD_API_CALL PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL; +#define glSyncTextureINTEL glad_glSyncTextureINTEL +GLAD_API_CALL PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX; +#define glTagSampleBufferSGIX glad_glTagSampleBufferSGIX +GLAD_API_CALL PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT; +#define glTangent3bEXT glad_glTangent3bEXT +GLAD_API_CALL PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT; +#define glTangent3bvEXT glad_glTangent3bvEXT +GLAD_API_CALL PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT; +#define glTangent3dEXT glad_glTangent3dEXT +GLAD_API_CALL PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT; +#define glTangent3dvEXT glad_glTangent3dvEXT +GLAD_API_CALL PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT; +#define glTangent3fEXT glad_glTangent3fEXT +GLAD_API_CALL PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT; +#define glTangent3fvEXT glad_glTangent3fvEXT +GLAD_API_CALL PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT; +#define glTangent3iEXT glad_glTangent3iEXT +GLAD_API_CALL PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT; +#define glTangent3ivEXT glad_glTangent3ivEXT +GLAD_API_CALL PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT; +#define glTangent3sEXT glad_glTangent3sEXT +GLAD_API_CALL PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT; +#define glTangent3svEXT glad_glTangent3svEXT +GLAD_API_CALL PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT; +#define glTangentPointerEXT glad_glTangentPointerEXT +GLAD_API_CALL PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX; +#define glTbufferMask3DFX glad_glTbufferMask3DFX +GLAD_API_CALL PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD; +#define glTessellationFactorAMD glad_glTessellationFactorAMD +GLAD_API_CALL PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD; +#define glTessellationModeAMD glad_glTessellationModeAMD +GLAD_API_CALL PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE; +#define glTestFenceAPPLE glad_glTestFenceAPPLE +GLAD_API_CALL PFNGLTESTFENCENVPROC glad_glTestFenceNV; +#define glTestFenceNV glad_glTestFenceNV +GLAD_API_CALL PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE; +#define glTestObjectAPPLE glad_glTestObjectAPPLE +GLAD_API_CALL PFNGLTEXATTACHMEMORYNVPROC glad_glTexAttachMemoryNV; +#define glTexAttachMemoryNV glad_glTexAttachMemoryNV +GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +GLAD_API_CALL PFNGLTEXBUFFERARBPROC glad_glTexBufferARB; +#define glTexBufferARB glad_glTexBufferARB +GLAD_API_CALL PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT; +#define glTexBufferEXT glad_glTexBufferEXT +GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; +#define glTexBufferRange glad_glTexBufferRange +GLAD_API_CALL PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI; +#define glTexBumpParameterfvATI glad_glTexBumpParameterfvATI +GLAD_API_CALL PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI; +#define glTexBumpParameterivATI glad_glTexBumpParameterivATI +GLAD_API_CALL PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES; +#define glTexCoord1bOES glad_glTexCoord1bOES +GLAD_API_CALL PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES; +#define glTexCoord1bvOES glad_glTexCoord1bvOES +GLAD_API_CALL PFNGLTEXCOORD1DPROC glad_glTexCoord1d; +#define glTexCoord1d glad_glTexCoord1d +GLAD_API_CALL PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; +#define glTexCoord1dv glad_glTexCoord1dv +GLAD_API_CALL PFNGLTEXCOORD1FPROC glad_glTexCoord1f; +#define glTexCoord1f glad_glTexCoord1f +GLAD_API_CALL PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; +#define glTexCoord1fv glad_glTexCoord1fv +GLAD_API_CALL PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV; +#define glTexCoord1hNV glad_glTexCoord1hNV +GLAD_API_CALL PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV; +#define glTexCoord1hvNV glad_glTexCoord1hvNV +GLAD_API_CALL PFNGLTEXCOORD1IPROC glad_glTexCoord1i; +#define glTexCoord1i glad_glTexCoord1i +GLAD_API_CALL PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; +#define glTexCoord1iv glad_glTexCoord1iv +GLAD_API_CALL PFNGLTEXCOORD1SPROC glad_glTexCoord1s; +#define glTexCoord1s glad_glTexCoord1s +GLAD_API_CALL PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; +#define glTexCoord1sv glad_glTexCoord1sv +GLAD_API_CALL PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES; +#define glTexCoord1xOES glad_glTexCoord1xOES +GLAD_API_CALL PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES; +#define glTexCoord1xvOES glad_glTexCoord1xvOES +GLAD_API_CALL PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES; +#define glTexCoord2bOES glad_glTexCoord2bOES +GLAD_API_CALL PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES; +#define glTexCoord2bvOES glad_glTexCoord2bvOES +GLAD_API_CALL PFNGLTEXCOORD2DPROC glad_glTexCoord2d; +#define glTexCoord2d glad_glTexCoord2d +GLAD_API_CALL PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; +#define glTexCoord2dv glad_glTexCoord2dv +GLAD_API_CALL PFNGLTEXCOORD2FPROC glad_glTexCoord2f; +#define glTexCoord2f glad_glTexCoord2f +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN; +#define glTexCoord2fColor3fVertex3fSUN glad_glTexCoord2fColor3fVertex3fSUN +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN; +#define glTexCoord2fColor3fVertex3fvSUN glad_glTexCoord2fColor3fVertex3fvSUN +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN; +#define glTexCoord2fColor4fNormal3fVertex3fSUN glad_glTexCoord2fColor4fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN; +#define glTexCoord2fColor4fNormal3fVertex3fvSUN glad_glTexCoord2fColor4fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN; +#define glTexCoord2fColor4ubVertex3fSUN glad_glTexCoord2fColor4ubVertex3fSUN +GLAD_API_CALL PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN; +#define glTexCoord2fColor4ubVertex3fvSUN glad_glTexCoord2fColor4ubVertex3fvSUN +GLAD_API_CALL PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN; +#define glTexCoord2fNormal3fVertex3fSUN glad_glTexCoord2fNormal3fVertex3fSUN +GLAD_API_CALL PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN; +#define glTexCoord2fNormal3fVertex3fvSUN glad_glTexCoord2fNormal3fVertex3fvSUN +GLAD_API_CALL PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN; +#define glTexCoord2fVertex3fSUN glad_glTexCoord2fVertex3fSUN +GLAD_API_CALL PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN; +#define glTexCoord2fVertex3fvSUN glad_glTexCoord2fVertex3fvSUN +GLAD_API_CALL PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; +#define glTexCoord2fv glad_glTexCoord2fv +GLAD_API_CALL PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV; +#define glTexCoord2hNV glad_glTexCoord2hNV +GLAD_API_CALL PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV; +#define glTexCoord2hvNV glad_glTexCoord2hvNV +GLAD_API_CALL PFNGLTEXCOORD2IPROC glad_glTexCoord2i; +#define glTexCoord2i glad_glTexCoord2i +GLAD_API_CALL PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; +#define glTexCoord2iv glad_glTexCoord2iv +GLAD_API_CALL PFNGLTEXCOORD2SPROC glad_glTexCoord2s; +#define glTexCoord2s glad_glTexCoord2s +GLAD_API_CALL PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; +#define glTexCoord2sv glad_glTexCoord2sv +GLAD_API_CALL PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES; +#define glTexCoord2xOES glad_glTexCoord2xOES +GLAD_API_CALL PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES; +#define glTexCoord2xvOES glad_glTexCoord2xvOES +GLAD_API_CALL PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES; +#define glTexCoord3bOES glad_glTexCoord3bOES +GLAD_API_CALL PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES; +#define glTexCoord3bvOES glad_glTexCoord3bvOES +GLAD_API_CALL PFNGLTEXCOORD3DPROC glad_glTexCoord3d; +#define glTexCoord3d glad_glTexCoord3d +GLAD_API_CALL PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; +#define glTexCoord3dv glad_glTexCoord3dv +GLAD_API_CALL PFNGLTEXCOORD3FPROC glad_glTexCoord3f; +#define glTexCoord3f glad_glTexCoord3f +GLAD_API_CALL PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; +#define glTexCoord3fv glad_glTexCoord3fv +GLAD_API_CALL PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV; +#define glTexCoord3hNV glad_glTexCoord3hNV +GLAD_API_CALL PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV; +#define glTexCoord3hvNV glad_glTexCoord3hvNV +GLAD_API_CALL PFNGLTEXCOORD3IPROC glad_glTexCoord3i; +#define glTexCoord3i glad_glTexCoord3i +GLAD_API_CALL PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; +#define glTexCoord3iv glad_glTexCoord3iv +GLAD_API_CALL PFNGLTEXCOORD3SPROC glad_glTexCoord3s; +#define glTexCoord3s glad_glTexCoord3s +GLAD_API_CALL PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; +#define glTexCoord3sv glad_glTexCoord3sv +GLAD_API_CALL PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES; +#define glTexCoord3xOES glad_glTexCoord3xOES +GLAD_API_CALL PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES; +#define glTexCoord3xvOES glad_glTexCoord3xvOES +GLAD_API_CALL PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES; +#define glTexCoord4bOES glad_glTexCoord4bOES +GLAD_API_CALL PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES; +#define glTexCoord4bvOES glad_glTexCoord4bvOES +GLAD_API_CALL PFNGLTEXCOORD4DPROC glad_glTexCoord4d; +#define glTexCoord4d glad_glTexCoord4d +GLAD_API_CALL PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; +#define glTexCoord4dv glad_glTexCoord4dv +GLAD_API_CALL PFNGLTEXCOORD4FPROC glad_glTexCoord4f; +#define glTexCoord4f glad_glTexCoord4f +GLAD_API_CALL PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN; +#define glTexCoord4fColor4fNormal3fVertex4fSUN glad_glTexCoord4fColor4fNormal3fVertex4fSUN +GLAD_API_CALL PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN; +#define glTexCoord4fColor4fNormal3fVertex4fvSUN glad_glTexCoord4fColor4fNormal3fVertex4fvSUN +GLAD_API_CALL PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN; +#define glTexCoord4fVertex4fSUN glad_glTexCoord4fVertex4fSUN +GLAD_API_CALL PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN; +#define glTexCoord4fVertex4fvSUN glad_glTexCoord4fVertex4fvSUN +GLAD_API_CALL PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; +#define glTexCoord4fv glad_glTexCoord4fv +GLAD_API_CALL PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV; +#define glTexCoord4hNV glad_glTexCoord4hNV +GLAD_API_CALL PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV; +#define glTexCoord4hvNV glad_glTexCoord4hvNV +GLAD_API_CALL PFNGLTEXCOORD4IPROC glad_glTexCoord4i; +#define glTexCoord4i glad_glTexCoord4i +GLAD_API_CALL PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; +#define glTexCoord4iv glad_glTexCoord4iv +GLAD_API_CALL PFNGLTEXCOORD4SPROC glad_glTexCoord4s; +#define glTexCoord4s glad_glTexCoord4s +GLAD_API_CALL PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; +#define glTexCoord4sv glad_glTexCoord4sv +GLAD_API_CALL PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES; +#define glTexCoord4xOES glad_glTexCoord4xOES +GLAD_API_CALL PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES; +#define glTexCoord4xvOES glad_glTexCoord4xvOES +GLAD_API_CALL PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV; +#define glTexCoordFormatNV glad_glTexCoordFormatNV +GLAD_API_CALL PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; +#define glTexCoordP1ui glad_glTexCoordP1ui +GLAD_API_CALL PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; +#define glTexCoordP1uiv glad_glTexCoordP1uiv +GLAD_API_CALL PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; +#define glTexCoordP2ui glad_glTexCoordP2ui +GLAD_API_CALL PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; +#define glTexCoordP2uiv glad_glTexCoordP2uiv +GLAD_API_CALL PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; +#define glTexCoordP3ui glad_glTexCoordP3ui +GLAD_API_CALL PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; +#define glTexCoordP3uiv glad_glTexCoordP3uiv +GLAD_API_CALL PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; +#define glTexCoordP4ui glad_glTexCoordP4ui +GLAD_API_CALL PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; +#define glTexCoordP4uiv glad_glTexCoordP4uiv +GLAD_API_CALL PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; +#define glTexCoordPointer glad_glTexCoordPointer +GLAD_API_CALL PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT; +#define glTexCoordPointerEXT glad_glTexCoordPointerEXT +GLAD_API_CALL PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM; +#define glTexCoordPointerListIBM glad_glTexCoordPointerListIBM +GLAD_API_CALL PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL; +#define glTexCoordPointervINTEL glad_glTexCoordPointervINTEL +GLAD_API_CALL PFNGLTEXENVFPROC glad_glTexEnvf; +#define glTexEnvf glad_glTexEnvf +GLAD_API_CALL PFNGLTEXENVFVPROC glad_glTexEnvfv; +#define glTexEnvfv glad_glTexEnvfv +GLAD_API_CALL PFNGLTEXENVIPROC glad_glTexEnvi; +#define glTexEnvi glad_glTexEnvi +GLAD_API_CALL PFNGLTEXENVIVPROC glad_glTexEnviv; +#define glTexEnviv glad_glTexEnviv +GLAD_API_CALL PFNGLTEXENVXOESPROC glad_glTexEnvxOES; +#define glTexEnvxOES glad_glTexEnvxOES +GLAD_API_CALL PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES; +#define glTexEnvxvOES glad_glTexEnvxvOES +GLAD_API_CALL PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS; +#define glTexFilterFuncSGIS glad_glTexFilterFuncSGIS +GLAD_API_CALL PFNGLTEXGENDPROC glad_glTexGend; +#define glTexGend glad_glTexGend +GLAD_API_CALL PFNGLTEXGENDVPROC glad_glTexGendv; +#define glTexGendv glad_glTexGendv +GLAD_API_CALL PFNGLTEXGENFPROC glad_glTexGenf; +#define glTexGenf glad_glTexGenf +GLAD_API_CALL PFNGLTEXGENFVPROC glad_glTexGenfv; +#define glTexGenfv glad_glTexGenfv +GLAD_API_CALL PFNGLTEXGENIPROC glad_glTexGeni; +#define glTexGeni glad_glTexGeni +GLAD_API_CALL PFNGLTEXGENIVPROC glad_glTexGeniv; +#define glTexGeniv glad_glTexGeniv +GLAD_API_CALL PFNGLTEXGENXOESPROC glad_glTexGenxOES; +#define glTexGenxOES glad_glTexGenxOES +GLAD_API_CALL PFNGLTEXGENXVOESPROC glad_glTexGenxvOES; +#define glTexGenxvOES glad_glTexGenxvOES +GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV; +#define glTexImage2DMultisampleCoverageNV glad_glTexImage2DMultisampleCoverageNV +GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +GLAD_API_CALL PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT; +#define glTexImage3DEXT glad_glTexImage3DEXT +GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV; +#define glTexImage3DMultisampleCoverageNV glad_glTexImage3DMultisampleCoverageNV +GLAD_API_CALL PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS; +#define glTexImage4DSGIS glad_glTexImage4DSGIS +GLAD_API_CALL PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB; +#define glTexPageCommitmentARB glad_glTexPageCommitmentARB +GLAD_API_CALL PFNGLTEXPAGECOMMITMENTMEMNVPROC glad_glTexPageCommitmentMemNV; +#define glTexPageCommitmentMemNV glad_glTexPageCommitmentMemNV +GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +GLAD_API_CALL PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT; +#define glTexParameterIivEXT glad_glTexParameterIivEXT +GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +GLAD_API_CALL PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT; +#define glTexParameterIuivEXT glad_glTexParameterIuivEXT +GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +GLAD_API_CALL PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES; +#define glTexParameterxOES glad_glTexParameterxOES +GLAD_API_CALL PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES; +#define glTexParameterxvOES glad_glTexParameterxvOES +GLAD_API_CALL PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV; +#define glTexRenderbufferNV glad_glTexRenderbufferNV +GLAD_API_CALL PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; +#define glTexStorage1D glad_glTexStorage1D +GLAD_API_CALL PFNGLTEXSTORAGE1DEXTPROC glad_glTexStorage1DEXT; +#define glTexStorage1DEXT glad_glTexStorage1DEXT +GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; +#define glTexStorage2D glad_glTexStorage2D +GLAD_API_CALL PFNGLTEXSTORAGE2DEXTPROC glad_glTexStorage2DEXT; +#define glTexStorage2DEXT glad_glTexStorage2DEXT +GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; +#define glTexStorage2DMultisample glad_glTexStorage2DMultisample +GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; +#define glTexStorage3D glad_glTexStorage3D +GLAD_API_CALL PFNGLTEXSTORAGE3DEXTPROC glad_glTexStorage3DEXT; +#define glTexStorage3DEXT glad_glTexStorage3DEXT +GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; +#define glTexStorage3DMultisample glad_glTexStorage3DMultisample +GLAD_API_CALL PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT; +#define glTexStorageMem1DEXT glad_glTexStorageMem1DEXT +GLAD_API_CALL PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT; +#define glTexStorageMem2DEXT glad_glTexStorageMem2DEXT +GLAD_API_CALL PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT; +#define glTexStorageMem2DMultisampleEXT glad_glTexStorageMem2DMultisampleEXT +GLAD_API_CALL PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT; +#define glTexStorageMem3DEXT glad_glTexStorageMem3DEXT +GLAD_API_CALL PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT; +#define glTexStorageMem3DMultisampleEXT glad_glTexStorageMem3DMultisampleEXT +GLAD_API_CALL PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD; +#define glTexStorageSparseAMD glad_glTexStorageSparseAMD +GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +GLAD_API_CALL PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT; +#define glTexSubImage1DEXT glad_glTexSubImage1DEXT +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT; +#define glTexSubImage2DEXT glad_glTexSubImage2DEXT +GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +GLAD_API_CALL PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT; +#define glTexSubImage3DEXT glad_glTexSubImage3DEXT +GLAD_API_CALL PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS; +#define glTexSubImage4DSGIS glad_glTexSubImage4DSGIS +GLAD_API_CALL PFNGLTEXTUREATTACHMEMORYNVPROC glad_glTextureAttachMemoryNV; +#define glTextureAttachMemoryNV glad_glTextureAttachMemoryNV +GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; +#define glTextureBarrier glad_glTextureBarrier +GLAD_API_CALL PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV; +#define glTextureBarrierNV glad_glTextureBarrierNV +GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; +#define glTextureBuffer glad_glTextureBuffer +GLAD_API_CALL PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT; +#define glTextureBufferEXT glad_glTextureBufferEXT +GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; +#define glTextureBufferRange glad_glTextureBufferRange +GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT; +#define glTextureBufferRangeEXT glad_glTextureBufferRangeEXT +GLAD_API_CALL PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS; +#define glTextureColorMaskSGIS glad_glTextureColorMaskSGIS +GLAD_API_CALL PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT; +#define glTextureImage1DEXT glad_glTextureImage1DEXT +GLAD_API_CALL PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT; +#define glTextureImage2DEXT glad_glTextureImage2DEXT +GLAD_API_CALL PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV; +#define glTextureImage2DMultisampleCoverageNV glad_glTextureImage2DMultisampleCoverageNV +GLAD_API_CALL PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV; +#define glTextureImage2DMultisampleNV glad_glTextureImage2DMultisampleNV +GLAD_API_CALL PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT; +#define glTextureImage3DEXT glad_glTextureImage3DEXT +GLAD_API_CALL PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV; +#define glTextureImage3DMultisampleCoverageNV glad_glTextureImage3DMultisampleCoverageNV +GLAD_API_CALL PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV; +#define glTextureImage3DMultisampleNV glad_glTextureImage3DMultisampleNV +GLAD_API_CALL PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT; +#define glTextureLightEXT glad_glTextureLightEXT +GLAD_API_CALL PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT; +#define glTextureMaterialEXT glad_glTextureMaterialEXT +GLAD_API_CALL PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT; +#define glTextureNormalEXT glad_glTextureNormalEXT +GLAD_API_CALL PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT; +#define glTexturePageCommitmentEXT glad_glTexturePageCommitmentEXT +GLAD_API_CALL PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC glad_glTexturePageCommitmentMemNV; +#define glTexturePageCommitmentMemNV glad_glTexturePageCommitmentMemNV +GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; +#define glTextureParameterIiv glad_glTextureParameterIiv +GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT; +#define glTextureParameterIivEXT glad_glTextureParameterIivEXT +GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; +#define glTextureParameterIuiv glad_glTextureParameterIuiv +GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT; +#define glTextureParameterIuivEXT glad_glTextureParameterIuivEXT +GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; +#define glTextureParameterf glad_glTextureParameterf +GLAD_API_CALL PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT; +#define glTextureParameterfEXT glad_glTextureParameterfEXT +GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; +#define glTextureParameterfv glad_glTextureParameterfv +GLAD_API_CALL PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT; +#define glTextureParameterfvEXT glad_glTextureParameterfvEXT +GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; +#define glTextureParameteri glad_glTextureParameteri +GLAD_API_CALL PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT; +#define glTextureParameteriEXT glad_glTextureParameteriEXT +GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; +#define glTextureParameteriv glad_glTextureParameteriv +GLAD_API_CALL PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT; +#define glTextureParameterivEXT glad_glTextureParameterivEXT +GLAD_API_CALL PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE; +#define glTextureRangeAPPLE glad_glTextureRangeAPPLE +GLAD_API_CALL PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT; +#define glTextureRenderbufferEXT glad_glTextureRenderbufferEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; +#define glTextureStorage1D glad_glTextureStorage1D +GLAD_API_CALL PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT; +#define glTextureStorage1DEXT glad_glTextureStorage1DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; +#define glTextureStorage2D glad_glTextureStorage2D +GLAD_API_CALL PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT; +#define glTextureStorage2DEXT glad_glTextureStorage2DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; +#define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample +GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT; +#define glTextureStorage2DMultisampleEXT glad_glTextureStorage2DMultisampleEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; +#define glTextureStorage3D glad_glTextureStorage3D +GLAD_API_CALL PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT; +#define glTextureStorage3DEXT glad_glTextureStorage3DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; +#define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample +GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT; +#define glTextureStorage3DMultisampleEXT glad_glTextureStorage3DMultisampleEXT +GLAD_API_CALL PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT; +#define glTextureStorageMem1DEXT glad_glTextureStorageMem1DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT; +#define glTextureStorageMem2DEXT glad_glTextureStorageMem2DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT; +#define glTextureStorageMem2DMultisampleEXT glad_glTextureStorageMem2DMultisampleEXT +GLAD_API_CALL PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT; +#define glTextureStorageMem3DEXT glad_glTextureStorageMem3DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT; +#define glTextureStorageMem3DMultisampleEXT glad_glTextureStorageMem3DMultisampleEXT +GLAD_API_CALL PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD; +#define glTextureStorageSparseAMD glad_glTextureStorageSparseAMD +GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; +#define glTextureSubImage1D glad_glTextureSubImage1D +GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT; +#define glTextureSubImage1DEXT glad_glTextureSubImage1DEXT +GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; +#define glTextureSubImage2D glad_glTextureSubImage2D +GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT; +#define glTextureSubImage2DEXT glad_glTextureSubImage2DEXT +GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; +#define glTextureSubImage3D glad_glTextureSubImage3D +GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT; +#define glTextureSubImage3DEXT glad_glTextureSubImage3DEXT +GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView; +#define glTextureView glad_glTextureView +GLAD_API_CALL PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV; +#define glTrackMatrixNV glad_glTrackMatrixNV +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV; +#define glTransformFeedbackAttribsNV glad_glTransformFeedbackAttribsNV +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; +#define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; +#define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV; +#define glTransformFeedbackStreamAttribsNV glad_glTransformFeedbackStreamAttribsNV +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT; +#define glTransformFeedbackVaryingsEXT glad_glTransformFeedbackVaryingsEXT +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV; +#define glTransformFeedbackVaryingsNV glad_glTransformFeedbackVaryingsNV +GLAD_API_CALL PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV; +#define glTransformPathNV glad_glTransformPathNV +GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; +#define glTranslated glad_glTranslated +GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; +#define glTranslatef glad_glTranslatef +GLAD_API_CALL PFNGLTRANSLATEXOESPROC glad_glTranslatexOES; +#define glTranslatexOES glad_glTranslatexOES +GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d; +#define glUniform1d glad_glUniform1d +GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv; +#define glUniform1dv glad_glUniform1dv +GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +GLAD_API_CALL PFNGLUNIFORM1FARBPROC glad_glUniform1fARB; +#define glUniform1fARB glad_glUniform1fARB +GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +GLAD_API_CALL PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB; +#define glUniform1fvARB glad_glUniform1fvARB +GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +GLAD_API_CALL PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB; +#define glUniform1i64ARB glad_glUniform1i64ARB +GLAD_API_CALL PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV; +#define glUniform1i64NV glad_glUniform1i64NV +GLAD_API_CALL PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB; +#define glUniform1i64vARB glad_glUniform1i64vARB +GLAD_API_CALL PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV; +#define glUniform1i64vNV glad_glUniform1i64vNV +GLAD_API_CALL PFNGLUNIFORM1IARBPROC glad_glUniform1iARB; +#define glUniform1iARB glad_glUniform1iARB +GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +GLAD_API_CALL PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB; +#define glUniform1ivARB glad_glUniform1ivARB +GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +GLAD_API_CALL PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB; +#define glUniform1ui64ARB glad_glUniform1ui64ARB +GLAD_API_CALL PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV; +#define glUniform1ui64NV glad_glUniform1ui64NV +GLAD_API_CALL PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB; +#define glUniform1ui64vARB glad_glUniform1ui64vARB +GLAD_API_CALL PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV; +#define glUniform1ui64vNV glad_glUniform1ui64vNV +GLAD_API_CALL PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT; +#define glUniform1uiEXT glad_glUniform1uiEXT +GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +GLAD_API_CALL PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT; +#define glUniform1uivEXT glad_glUniform1uivEXT +GLAD_API_CALL PFNGLUNIFORM2DPROC glad_glUniform2d; +#define glUniform2d glad_glUniform2d +GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv; +#define glUniform2dv glad_glUniform2dv +GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +GLAD_API_CALL PFNGLUNIFORM2FARBPROC glad_glUniform2fARB; +#define glUniform2fARB glad_glUniform2fARB +GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +GLAD_API_CALL PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB; +#define glUniform2fvARB glad_glUniform2fvARB +GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +GLAD_API_CALL PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB; +#define glUniform2i64ARB glad_glUniform2i64ARB +GLAD_API_CALL PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV; +#define glUniform2i64NV glad_glUniform2i64NV +GLAD_API_CALL PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB; +#define glUniform2i64vARB glad_glUniform2i64vARB +GLAD_API_CALL PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV; +#define glUniform2i64vNV glad_glUniform2i64vNV +GLAD_API_CALL PFNGLUNIFORM2IARBPROC glad_glUniform2iARB; +#define glUniform2iARB glad_glUniform2iARB +GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +GLAD_API_CALL PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB; +#define glUniform2ivARB glad_glUniform2ivARB +GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +GLAD_API_CALL PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB; +#define glUniform2ui64ARB glad_glUniform2ui64ARB +GLAD_API_CALL PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV; +#define glUniform2ui64NV glad_glUniform2ui64NV +GLAD_API_CALL PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB; +#define glUniform2ui64vARB glad_glUniform2ui64vARB +GLAD_API_CALL PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV; +#define glUniform2ui64vNV glad_glUniform2ui64vNV +GLAD_API_CALL PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT; +#define glUniform2uiEXT glad_glUniform2uiEXT +GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +GLAD_API_CALL PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT; +#define glUniform2uivEXT glad_glUniform2uivEXT +GLAD_API_CALL PFNGLUNIFORM3DPROC glad_glUniform3d; +#define glUniform3d glad_glUniform3d +GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv; +#define glUniform3dv glad_glUniform3dv +GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +GLAD_API_CALL PFNGLUNIFORM3FARBPROC glad_glUniform3fARB; +#define glUniform3fARB glad_glUniform3fARB +GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +GLAD_API_CALL PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB; +#define glUniform3fvARB glad_glUniform3fvARB +GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +GLAD_API_CALL PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB; +#define glUniform3i64ARB glad_glUniform3i64ARB +GLAD_API_CALL PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV; +#define glUniform3i64NV glad_glUniform3i64NV +GLAD_API_CALL PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB; +#define glUniform3i64vARB glad_glUniform3i64vARB +GLAD_API_CALL PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV; +#define glUniform3i64vNV glad_glUniform3i64vNV +GLAD_API_CALL PFNGLUNIFORM3IARBPROC glad_glUniform3iARB; +#define glUniform3iARB glad_glUniform3iARB +GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +GLAD_API_CALL PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB; +#define glUniform3ivARB glad_glUniform3ivARB +GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +GLAD_API_CALL PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB; +#define glUniform3ui64ARB glad_glUniform3ui64ARB +GLAD_API_CALL PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV; +#define glUniform3ui64NV glad_glUniform3ui64NV +GLAD_API_CALL PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB; +#define glUniform3ui64vARB glad_glUniform3ui64vARB +GLAD_API_CALL PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV; +#define glUniform3ui64vNV glad_glUniform3ui64vNV +GLAD_API_CALL PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT; +#define glUniform3uiEXT glad_glUniform3uiEXT +GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +GLAD_API_CALL PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT; +#define glUniform3uivEXT glad_glUniform3uivEXT +GLAD_API_CALL PFNGLUNIFORM4DPROC glad_glUniform4d; +#define glUniform4d glad_glUniform4d +GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv; +#define glUniform4dv glad_glUniform4dv +GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +GLAD_API_CALL PFNGLUNIFORM4FARBPROC glad_glUniform4fARB; +#define glUniform4fARB glad_glUniform4fARB +GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +GLAD_API_CALL PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB; +#define glUniform4fvARB glad_glUniform4fvARB +GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +GLAD_API_CALL PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB; +#define glUniform4i64ARB glad_glUniform4i64ARB +GLAD_API_CALL PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV; +#define glUniform4i64NV glad_glUniform4i64NV +GLAD_API_CALL PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB; +#define glUniform4i64vARB glad_glUniform4i64vARB +GLAD_API_CALL PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV; +#define glUniform4i64vNV glad_glUniform4i64vNV +GLAD_API_CALL PFNGLUNIFORM4IARBPROC glad_glUniform4iARB; +#define glUniform4iARB glad_glUniform4iARB +GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +GLAD_API_CALL PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB; +#define glUniform4ivARB glad_glUniform4ivARB +GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +GLAD_API_CALL PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB; +#define glUniform4ui64ARB glad_glUniform4ui64ARB +GLAD_API_CALL PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV; +#define glUniform4ui64NV glad_glUniform4ui64NV +GLAD_API_CALL PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB; +#define glUniform4ui64vARB glad_glUniform4ui64vARB +GLAD_API_CALL PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV; +#define glUniform4ui64vNV glad_glUniform4ui64vNV +GLAD_API_CALL PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT; +#define glUniform4uiEXT glad_glUniform4uiEXT +GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +GLAD_API_CALL PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT; +#define glUniform4uivEXT glad_glUniform4uivEXT +GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +GLAD_API_CALL PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT; +#define glUniformBufferEXT glad_glUniformBufferEXT +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB; +#define glUniformHandleui64ARB glad_glUniformHandleui64ARB +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV; +#define glUniformHandleui64NV glad_glUniformHandleui64NV +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB; +#define glUniformHandleui64vARB glad_glUniformHandleui64vARB +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV; +#define glUniformHandleui64vNV glad_glUniformHandleui64vNV +GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; +#define glUniformMatrix2dv glad_glUniformMatrix2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB; +#define glUniformMatrix2fvARB glad_glUniformMatrix2fvARB +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; +#define glUniformMatrix2x3dv glad_glUniformMatrix2x3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; +#define glUniformMatrix2x4dv glad_glUniformMatrix2x4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; +#define glUniformMatrix3dv glad_glUniformMatrix3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB; +#define glUniformMatrix3fvARB glad_glUniformMatrix3fvARB +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; +#define glUniformMatrix3x2dv glad_glUniformMatrix3x2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; +#define glUniformMatrix3x4dv glad_glUniformMatrix3x4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; +#define glUniformMatrix4dv glad_glUniformMatrix4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB; +#define glUniformMatrix4fvARB glad_glUniformMatrix4fvARB +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; +#define glUniformMatrix4x2dv glad_glUniformMatrix4x2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; +#define glUniformMatrix4x3dv glad_glUniformMatrix4x3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; +#define glUniformSubroutinesuiv glad_glUniformSubroutinesuiv +GLAD_API_CALL PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV; +#define glUniformui64NV glad_glUniformui64NV +GLAD_API_CALL PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV; +#define glUniformui64vNV glad_glUniformui64vNV +GLAD_API_CALL PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT; +#define glUnlockArraysEXT glad_glUnlockArraysEXT +GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +GLAD_API_CALL PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB; +#define glUnmapBufferARB glad_glUnmapBufferARB +GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; +#define glUnmapNamedBuffer glad_glUnmapNamedBuffer +GLAD_API_CALL PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT; +#define glUnmapNamedBufferEXT glad_glUnmapNamedBufferEXT +GLAD_API_CALL PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI; +#define glUnmapObjectBufferATI glad_glUnmapObjectBufferATI +GLAD_API_CALL PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL; +#define glUnmapTexture2DINTEL glad_glUnmapTexture2DINTEL +GLAD_API_CALL PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI; +#define glUpdateObjectBufferATI glad_glUpdateObjectBufferATI +GLAD_API_CALL PFNGLUPLOADGPUMASKNVXPROC glad_glUploadGpuMaskNVX; +#define glUploadGpuMaskNVX glad_glUploadGpuMaskNVX +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB; +#define glUseProgramObjectARB glad_glUseProgramObjectARB +GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; +#define glUseProgramStages glad_glUseProgramStages +GLAD_API_CALL PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV; +#define glVDPAUFiniNV glad_glVDPAUFiniNV +GLAD_API_CALL PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV; +#define glVDPAUGetSurfaceivNV glad_glVDPAUGetSurfaceivNV +GLAD_API_CALL PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV; +#define glVDPAUInitNV glad_glVDPAUInitNV +GLAD_API_CALL PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV; +#define glVDPAUIsSurfaceNV glad_glVDPAUIsSurfaceNV +GLAD_API_CALL PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV; +#define glVDPAUMapSurfacesNV glad_glVDPAUMapSurfacesNV +GLAD_API_CALL PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV; +#define glVDPAURegisterOutputSurfaceNV glad_glVDPAURegisterOutputSurfaceNV +GLAD_API_CALL PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV; +#define glVDPAURegisterVideoSurfaceNV glad_glVDPAURegisterVideoSurfaceNV +GLAD_API_CALL PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC glad_glVDPAURegisterVideoSurfaceWithPictureStructureNV; +#define glVDPAURegisterVideoSurfaceWithPictureStructureNV glad_glVDPAURegisterVideoSurfaceWithPictureStructureNV +GLAD_API_CALL PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV; +#define glVDPAUSurfaceAccessNV glad_glVDPAUSurfaceAccessNV +GLAD_API_CALL PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV; +#define glVDPAUUnmapSurfacesNV glad_glVDPAUUnmapSurfacesNV +GLAD_API_CALL PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV; +#define glVDPAUUnregisterSurfaceNV glad_glVDPAUUnregisterSurfaceNV +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB; +#define glValidateProgramARB glad_glValidateProgramARB +GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; +#define glValidateProgramPipeline glad_glValidateProgramPipeline +GLAD_API_CALL PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI; +#define glVariantArrayObjectATI glad_glVariantArrayObjectATI +GLAD_API_CALL PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT; +#define glVariantPointerEXT glad_glVariantPointerEXT +GLAD_API_CALL PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT; +#define glVariantbvEXT glad_glVariantbvEXT +GLAD_API_CALL PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT; +#define glVariantdvEXT glad_glVariantdvEXT +GLAD_API_CALL PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT; +#define glVariantfvEXT glad_glVariantfvEXT +GLAD_API_CALL PFNGLVARIANTIVEXTPROC glad_glVariantivEXT; +#define glVariantivEXT glad_glVariantivEXT +GLAD_API_CALL PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT; +#define glVariantsvEXT glad_glVariantsvEXT +GLAD_API_CALL PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT; +#define glVariantubvEXT glad_glVariantubvEXT +GLAD_API_CALL PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT; +#define glVariantuivEXT glad_glVariantuivEXT +GLAD_API_CALL PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT; +#define glVariantusvEXT glad_glVariantusvEXT +GLAD_API_CALL PFNGLVERTEX2BOESPROC glad_glVertex2bOES; +#define glVertex2bOES glad_glVertex2bOES +GLAD_API_CALL PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES; +#define glVertex2bvOES glad_glVertex2bvOES +GLAD_API_CALL PFNGLVERTEX2DPROC glad_glVertex2d; +#define glVertex2d glad_glVertex2d +GLAD_API_CALL PFNGLVERTEX2DVPROC glad_glVertex2dv; +#define glVertex2dv glad_glVertex2dv +GLAD_API_CALL PFNGLVERTEX2FPROC glad_glVertex2f; +#define glVertex2f glad_glVertex2f +GLAD_API_CALL PFNGLVERTEX2FVPROC glad_glVertex2fv; +#define glVertex2fv glad_glVertex2fv +GLAD_API_CALL PFNGLVERTEX2HNVPROC glad_glVertex2hNV; +#define glVertex2hNV glad_glVertex2hNV +GLAD_API_CALL PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV; +#define glVertex2hvNV glad_glVertex2hvNV +GLAD_API_CALL PFNGLVERTEX2IPROC glad_glVertex2i; +#define glVertex2i glad_glVertex2i +GLAD_API_CALL PFNGLVERTEX2IVPROC glad_glVertex2iv; +#define glVertex2iv glad_glVertex2iv +GLAD_API_CALL PFNGLVERTEX2SPROC glad_glVertex2s; +#define glVertex2s glad_glVertex2s +GLAD_API_CALL PFNGLVERTEX2SVPROC glad_glVertex2sv; +#define glVertex2sv glad_glVertex2sv +GLAD_API_CALL PFNGLVERTEX2XOESPROC glad_glVertex2xOES; +#define glVertex2xOES glad_glVertex2xOES +GLAD_API_CALL PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES; +#define glVertex2xvOES glad_glVertex2xvOES +GLAD_API_CALL PFNGLVERTEX3BOESPROC glad_glVertex3bOES; +#define glVertex3bOES glad_glVertex3bOES +GLAD_API_CALL PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES; +#define glVertex3bvOES glad_glVertex3bvOES +GLAD_API_CALL PFNGLVERTEX3DPROC glad_glVertex3d; +#define glVertex3d glad_glVertex3d +GLAD_API_CALL PFNGLVERTEX3DVPROC glad_glVertex3dv; +#define glVertex3dv glad_glVertex3dv +GLAD_API_CALL PFNGLVERTEX3FPROC glad_glVertex3f; +#define glVertex3f glad_glVertex3f +GLAD_API_CALL PFNGLVERTEX3FVPROC glad_glVertex3fv; +#define glVertex3fv glad_glVertex3fv +GLAD_API_CALL PFNGLVERTEX3HNVPROC glad_glVertex3hNV; +#define glVertex3hNV glad_glVertex3hNV +GLAD_API_CALL PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV; +#define glVertex3hvNV glad_glVertex3hvNV +GLAD_API_CALL PFNGLVERTEX3IPROC glad_glVertex3i; +#define glVertex3i glad_glVertex3i +GLAD_API_CALL PFNGLVERTEX3IVPROC glad_glVertex3iv; +#define glVertex3iv glad_glVertex3iv +GLAD_API_CALL PFNGLVERTEX3SPROC glad_glVertex3s; +#define glVertex3s glad_glVertex3s +GLAD_API_CALL PFNGLVERTEX3SVPROC glad_glVertex3sv; +#define glVertex3sv glad_glVertex3sv +GLAD_API_CALL PFNGLVERTEX3XOESPROC glad_glVertex3xOES; +#define glVertex3xOES glad_glVertex3xOES +GLAD_API_CALL PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES; +#define glVertex3xvOES glad_glVertex3xvOES +GLAD_API_CALL PFNGLVERTEX4BOESPROC glad_glVertex4bOES; +#define glVertex4bOES glad_glVertex4bOES +GLAD_API_CALL PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES; +#define glVertex4bvOES glad_glVertex4bvOES +GLAD_API_CALL PFNGLVERTEX4DPROC glad_glVertex4d; +#define glVertex4d glad_glVertex4d +GLAD_API_CALL PFNGLVERTEX4DVPROC glad_glVertex4dv; +#define glVertex4dv glad_glVertex4dv +GLAD_API_CALL PFNGLVERTEX4FPROC glad_glVertex4f; +#define glVertex4f glad_glVertex4f +GLAD_API_CALL PFNGLVERTEX4FVPROC glad_glVertex4fv; +#define glVertex4fv glad_glVertex4fv +GLAD_API_CALL PFNGLVERTEX4HNVPROC glad_glVertex4hNV; +#define glVertex4hNV glad_glVertex4hNV +GLAD_API_CALL PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV; +#define glVertex4hvNV glad_glVertex4hvNV +GLAD_API_CALL PFNGLVERTEX4IPROC glad_glVertex4i; +#define glVertex4i glad_glVertex4i +GLAD_API_CALL PFNGLVERTEX4IVPROC glad_glVertex4iv; +#define glVertex4iv glad_glVertex4iv +GLAD_API_CALL PFNGLVERTEX4SPROC glad_glVertex4s; +#define glVertex4s glad_glVertex4s +GLAD_API_CALL PFNGLVERTEX4SVPROC glad_glVertex4sv; +#define glVertex4sv glad_glVertex4sv +GLAD_API_CALL PFNGLVERTEX4XOESPROC glad_glVertex4xOES; +#define glVertex4xOES glad_glVertex4xOES +GLAD_API_CALL PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES; +#define glVertex4xvOES glad_glVertex4xvOES +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; +#define glVertexArrayAttribBinding glad_glVertexArrayAttribBinding +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; +#define glVertexArrayAttribFormat glad_glVertexArrayAttribFormat +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; +#define glVertexArrayAttribIFormat glad_glVertexArrayAttribIFormat +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; +#define glVertexArrayAttribLFormat glad_glVertexArrayAttribLFormat +GLAD_API_CALL PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT; +#define glVertexArrayBindVertexBufferEXT glad_glVertexArrayBindVertexBufferEXT +GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; +#define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor +GLAD_API_CALL PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT; +#define glVertexArrayColorOffsetEXT glad_glVertexArrayColorOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT; +#define glVertexArrayEdgeFlagOffsetEXT glad_glVertexArrayEdgeFlagOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; +#define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer +GLAD_API_CALL PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT; +#define glVertexArrayFogCoordOffsetEXT glad_glVertexArrayFogCoordOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT; +#define glVertexArrayIndexOffsetEXT glad_glVertexArrayIndexOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT; +#define glVertexArrayMultiTexCoordOffsetEXT glad_glVertexArrayMultiTexCoordOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT; +#define glVertexArrayNormalOffsetEXT glad_glVertexArrayNormalOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE; +#define glVertexArrayParameteriAPPLE glad_glVertexArrayParameteriAPPLE +GLAD_API_CALL PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE; +#define glVertexArrayRangeAPPLE glad_glVertexArrayRangeAPPLE +GLAD_API_CALL PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV; +#define glVertexArrayRangeNV glad_glVertexArrayRangeNV +GLAD_API_CALL PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT; +#define glVertexArraySecondaryColorOffsetEXT glad_glVertexArraySecondaryColorOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT; +#define glVertexArrayTexCoordOffsetEXT glad_glVertexArrayTexCoordOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT; +#define glVertexArrayVertexAttribBindingEXT glad_glVertexArrayVertexAttribBindingEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT; +#define glVertexArrayVertexAttribDivisorEXT glad_glVertexArrayVertexAttribDivisorEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT; +#define glVertexArrayVertexAttribFormatEXT glad_glVertexArrayVertexAttribFormatEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT; +#define glVertexArrayVertexAttribIFormatEXT glad_glVertexArrayVertexAttribIFormatEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT; +#define glVertexArrayVertexAttribIOffsetEXT glad_glVertexArrayVertexAttribIOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT; +#define glVertexArrayVertexAttribLFormatEXT glad_glVertexArrayVertexAttribLFormatEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT; +#define glVertexArrayVertexAttribLOffsetEXT glad_glVertexArrayVertexAttribLOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT; +#define glVertexArrayVertexAttribOffsetEXT glad_glVertexArrayVertexAttribOffsetEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT; +#define glVertexArrayVertexBindingDivisorEXT glad_glVertexArrayVertexBindingDivisorEXT +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; +#define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; +#define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT; +#define glVertexArrayVertexOffsetEXT glad_glVertexArrayVertexOffsetEXT +GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +GLAD_API_CALL PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB; +#define glVertexAttrib1dARB glad_glVertexAttrib1dARB +GLAD_API_CALL PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV; +#define glVertexAttrib1dNV glad_glVertexAttrib1dNV +GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +GLAD_API_CALL PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB; +#define glVertexAttrib1dvARB glad_glVertexAttrib1dvARB +GLAD_API_CALL PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV; +#define glVertexAttrib1dvNV glad_glVertexAttrib1dvNV +GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +GLAD_API_CALL PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB; +#define glVertexAttrib1fARB glad_glVertexAttrib1fARB +GLAD_API_CALL PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV; +#define glVertexAttrib1fNV glad_glVertexAttrib1fNV +GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +GLAD_API_CALL PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB; +#define glVertexAttrib1fvARB glad_glVertexAttrib1fvARB +GLAD_API_CALL PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV; +#define glVertexAttrib1fvNV glad_glVertexAttrib1fvNV +GLAD_API_CALL PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV; +#define glVertexAttrib1hNV glad_glVertexAttrib1hNV +GLAD_API_CALL PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV; +#define glVertexAttrib1hvNV glad_glVertexAttrib1hvNV +GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +GLAD_API_CALL PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB; +#define glVertexAttrib1sARB glad_glVertexAttrib1sARB +GLAD_API_CALL PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV; +#define glVertexAttrib1sNV glad_glVertexAttrib1sNV +GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +GLAD_API_CALL PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB; +#define glVertexAttrib1svARB glad_glVertexAttrib1svARB +GLAD_API_CALL PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV; +#define glVertexAttrib1svNV glad_glVertexAttrib1svNV +GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +GLAD_API_CALL PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB; +#define glVertexAttrib2dARB glad_glVertexAttrib2dARB +GLAD_API_CALL PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV; +#define glVertexAttrib2dNV glad_glVertexAttrib2dNV +GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +GLAD_API_CALL PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB; +#define glVertexAttrib2dvARB glad_glVertexAttrib2dvARB +GLAD_API_CALL PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV; +#define glVertexAttrib2dvNV glad_glVertexAttrib2dvNV +GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +GLAD_API_CALL PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB; +#define glVertexAttrib2fARB glad_glVertexAttrib2fARB +GLAD_API_CALL PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV; +#define glVertexAttrib2fNV glad_glVertexAttrib2fNV +GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +GLAD_API_CALL PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB; +#define glVertexAttrib2fvARB glad_glVertexAttrib2fvARB +GLAD_API_CALL PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV; +#define glVertexAttrib2fvNV glad_glVertexAttrib2fvNV +GLAD_API_CALL PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV; +#define glVertexAttrib2hNV glad_glVertexAttrib2hNV +GLAD_API_CALL PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV; +#define glVertexAttrib2hvNV glad_glVertexAttrib2hvNV +GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +GLAD_API_CALL PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB; +#define glVertexAttrib2sARB glad_glVertexAttrib2sARB +GLAD_API_CALL PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV; +#define glVertexAttrib2sNV glad_glVertexAttrib2sNV +GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +GLAD_API_CALL PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB; +#define glVertexAttrib2svARB glad_glVertexAttrib2svARB +GLAD_API_CALL PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV; +#define glVertexAttrib2svNV glad_glVertexAttrib2svNV +GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +GLAD_API_CALL PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB; +#define glVertexAttrib3dARB glad_glVertexAttrib3dARB +GLAD_API_CALL PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV; +#define glVertexAttrib3dNV glad_glVertexAttrib3dNV +GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +GLAD_API_CALL PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB; +#define glVertexAttrib3dvARB glad_glVertexAttrib3dvARB +GLAD_API_CALL PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV; +#define glVertexAttrib3dvNV glad_glVertexAttrib3dvNV +GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +GLAD_API_CALL PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB; +#define glVertexAttrib3fARB glad_glVertexAttrib3fARB +GLAD_API_CALL PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV; +#define glVertexAttrib3fNV glad_glVertexAttrib3fNV +GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +GLAD_API_CALL PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB; +#define glVertexAttrib3fvARB glad_glVertexAttrib3fvARB +GLAD_API_CALL PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV; +#define glVertexAttrib3fvNV glad_glVertexAttrib3fvNV +GLAD_API_CALL PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV; +#define glVertexAttrib3hNV glad_glVertexAttrib3hNV +GLAD_API_CALL PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV; +#define glVertexAttrib3hvNV glad_glVertexAttrib3hvNV +GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +GLAD_API_CALL PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB; +#define glVertexAttrib3sARB glad_glVertexAttrib3sARB +GLAD_API_CALL PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV; +#define glVertexAttrib3sNV glad_glVertexAttrib3sNV +GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +GLAD_API_CALL PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB; +#define glVertexAttrib3svARB glad_glVertexAttrib3svARB +GLAD_API_CALL PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV; +#define glVertexAttrib3svNV glad_glVertexAttrib3svNV +GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +GLAD_API_CALL PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB; +#define glVertexAttrib4NbvARB glad_glVertexAttrib4NbvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +GLAD_API_CALL PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB; +#define glVertexAttrib4NivARB glad_glVertexAttrib4NivARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +GLAD_API_CALL PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB; +#define glVertexAttrib4NsvARB glad_glVertexAttrib4NsvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB; +#define glVertexAttrib4NubARB glad_glVertexAttrib4NubARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB; +#define glVertexAttrib4NubvARB glad_glVertexAttrib4NubvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB; +#define glVertexAttrib4NuivARB glad_glVertexAttrib4NuivARB +GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB; +#define glVertexAttrib4NusvARB glad_glVertexAttrib4NusvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +GLAD_API_CALL PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB; +#define glVertexAttrib4bvARB glad_glVertexAttrib4bvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +GLAD_API_CALL PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB; +#define glVertexAttrib4dARB glad_glVertexAttrib4dARB +GLAD_API_CALL PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV; +#define glVertexAttrib4dNV glad_glVertexAttrib4dNV +GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +GLAD_API_CALL PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB; +#define glVertexAttrib4dvARB glad_glVertexAttrib4dvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV; +#define glVertexAttrib4dvNV glad_glVertexAttrib4dvNV +GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +GLAD_API_CALL PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB; +#define glVertexAttrib4fARB glad_glVertexAttrib4fARB +GLAD_API_CALL PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV; +#define glVertexAttrib4fNV glad_glVertexAttrib4fNV +GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +GLAD_API_CALL PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB; +#define glVertexAttrib4fvARB glad_glVertexAttrib4fvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV; +#define glVertexAttrib4fvNV glad_glVertexAttrib4fvNV +GLAD_API_CALL PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV; +#define glVertexAttrib4hNV glad_glVertexAttrib4hNV +GLAD_API_CALL PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV; +#define glVertexAttrib4hvNV glad_glVertexAttrib4hvNV +GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +GLAD_API_CALL PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB; +#define glVertexAttrib4ivARB glad_glVertexAttrib4ivARB +GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +GLAD_API_CALL PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB; +#define glVertexAttrib4sARB glad_glVertexAttrib4sARB +GLAD_API_CALL PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV; +#define glVertexAttrib4sNV glad_glVertexAttrib4sNV +GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +GLAD_API_CALL PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB; +#define glVertexAttrib4svARB glad_glVertexAttrib4svARB +GLAD_API_CALL PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV; +#define glVertexAttrib4svNV glad_glVertexAttrib4svNV +GLAD_API_CALL PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV; +#define glVertexAttrib4ubNV glad_glVertexAttrib4ubNV +GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +GLAD_API_CALL PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB; +#define glVertexAttrib4ubvARB glad_glVertexAttrib4ubvARB +GLAD_API_CALL PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV; +#define glVertexAttrib4ubvNV glad_glVertexAttrib4ubvNV +GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +GLAD_API_CALL PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB; +#define glVertexAttrib4uivARB glad_glVertexAttrib4uivARB +GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +GLAD_API_CALL PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB; +#define glVertexAttrib4usvARB glad_glVertexAttrib4usvARB +GLAD_API_CALL PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI; +#define glVertexAttribArrayObjectATI glad_glVertexAttribArrayObjectATI +GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; +#define glVertexAttribBinding glad_glVertexAttribBinding +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB; +#define glVertexAttribDivisorARB glad_glVertexAttribDivisorARB +GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; +#define glVertexAttribFormat glad_glVertexAttribFormat +GLAD_API_CALL PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV; +#define glVertexAttribFormatNV glad_glVertexAttribFormatNV +GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +GLAD_API_CALL PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT; +#define glVertexAttribI1iEXT glad_glVertexAttribI1iEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +GLAD_API_CALL PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT; +#define glVertexAttribI1ivEXT glad_glVertexAttribI1ivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT; +#define glVertexAttribI1uiEXT glad_glVertexAttribI1uiEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT; +#define glVertexAttribI1uivEXT glad_glVertexAttribI1uivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +GLAD_API_CALL PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT; +#define glVertexAttribI2iEXT glad_glVertexAttribI2iEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +GLAD_API_CALL PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT; +#define glVertexAttribI2ivEXT glad_glVertexAttribI2ivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT; +#define glVertexAttribI2uiEXT glad_glVertexAttribI2uiEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT; +#define glVertexAttribI2uivEXT glad_glVertexAttribI2uivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +GLAD_API_CALL PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT; +#define glVertexAttribI3iEXT glad_glVertexAttribI3iEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +GLAD_API_CALL PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT; +#define glVertexAttribI3ivEXT glad_glVertexAttribI3ivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT; +#define glVertexAttribI3uiEXT glad_glVertexAttribI3uiEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT; +#define glVertexAttribI3uivEXT glad_glVertexAttribI3uivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +GLAD_API_CALL PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT; +#define glVertexAttribI4bvEXT glad_glVertexAttribI4bvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +GLAD_API_CALL PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT; +#define glVertexAttribI4iEXT glad_glVertexAttribI4iEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT; +#define glVertexAttribI4ivEXT glad_glVertexAttribI4ivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +GLAD_API_CALL PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT; +#define glVertexAttribI4svEXT glad_glVertexAttribI4svEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT; +#define glVertexAttribI4ubvEXT glad_glVertexAttribI4ubvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT; +#define glVertexAttribI4uiEXT glad_glVertexAttribI4uiEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT; +#define glVertexAttribI4uivEXT glad_glVertexAttribI4uivEXT +GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +GLAD_API_CALL PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT; +#define glVertexAttribI4usvEXT glad_glVertexAttribI4usvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; +#define glVertexAttribIFormat glad_glVertexAttribIFormat +GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV; +#define glVertexAttribIFormatNV glad_glVertexAttribIFormatNV +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT; +#define glVertexAttribIPointerEXT glad_glVertexAttribIPointerEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; +#define glVertexAttribL1d glad_glVertexAttribL1d +GLAD_API_CALL PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT; +#define glVertexAttribL1dEXT glad_glVertexAttribL1dEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; +#define glVertexAttribL1dv glad_glVertexAttribL1dv +GLAD_API_CALL PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT; +#define glVertexAttribL1dvEXT glad_glVertexAttribL1dvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV; +#define glVertexAttribL1i64NV glad_glVertexAttribL1i64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV; +#define glVertexAttribL1i64vNV glad_glVertexAttribL1i64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB; +#define glVertexAttribL1ui64ARB glad_glVertexAttribL1ui64ARB +GLAD_API_CALL PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV; +#define glVertexAttribL1ui64NV glad_glVertexAttribL1ui64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB; +#define glVertexAttribL1ui64vARB glad_glVertexAttribL1ui64vARB +GLAD_API_CALL PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV; +#define glVertexAttribL1ui64vNV glad_glVertexAttribL1ui64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; +#define glVertexAttribL2d glad_glVertexAttribL2d +GLAD_API_CALL PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT; +#define glVertexAttribL2dEXT glad_glVertexAttribL2dEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; +#define glVertexAttribL2dv glad_glVertexAttribL2dv +GLAD_API_CALL PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT; +#define glVertexAttribL2dvEXT glad_glVertexAttribL2dvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV; +#define glVertexAttribL2i64NV glad_glVertexAttribL2i64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV; +#define glVertexAttribL2i64vNV glad_glVertexAttribL2i64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV; +#define glVertexAttribL2ui64NV glad_glVertexAttribL2ui64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV; +#define glVertexAttribL2ui64vNV glad_glVertexAttribL2ui64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; +#define glVertexAttribL3d glad_glVertexAttribL3d +GLAD_API_CALL PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT; +#define glVertexAttribL3dEXT glad_glVertexAttribL3dEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; +#define glVertexAttribL3dv glad_glVertexAttribL3dv +GLAD_API_CALL PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT; +#define glVertexAttribL3dvEXT glad_glVertexAttribL3dvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV; +#define glVertexAttribL3i64NV glad_glVertexAttribL3i64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV; +#define glVertexAttribL3i64vNV glad_glVertexAttribL3i64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV; +#define glVertexAttribL3ui64NV glad_glVertexAttribL3ui64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV; +#define glVertexAttribL3ui64vNV glad_glVertexAttribL3ui64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; +#define glVertexAttribL4d glad_glVertexAttribL4d +GLAD_API_CALL PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT; +#define glVertexAttribL4dEXT glad_glVertexAttribL4dEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; +#define glVertexAttribL4dv glad_glVertexAttribL4dv +GLAD_API_CALL PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT; +#define glVertexAttribL4dvEXT glad_glVertexAttribL4dvEXT +GLAD_API_CALL PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV; +#define glVertexAttribL4i64NV glad_glVertexAttribL4i64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV; +#define glVertexAttribL4i64vNV glad_glVertexAttribL4i64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV; +#define glVertexAttribL4ui64NV glad_glVertexAttribL4ui64NV +GLAD_API_CALL PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV; +#define glVertexAttribL4ui64vNV glad_glVertexAttribL4ui64vNV +GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; +#define glVertexAttribLFormat glad_glVertexAttribLFormat +GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV; +#define glVertexAttribLFormatNV glad_glVertexAttribLFormatNV +GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; +#define glVertexAttribLPointer glad_glVertexAttribLPointer +GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT; +#define glVertexAttribLPointerEXT glad_glVertexAttribLPointerEXT +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; +#define glVertexAttribP1ui glad_glVertexAttribP1ui +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; +#define glVertexAttribP1uiv glad_glVertexAttribP1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; +#define glVertexAttribP2ui glad_glVertexAttribP2ui +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; +#define glVertexAttribP2uiv glad_glVertexAttribP2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; +#define glVertexAttribP3ui glad_glVertexAttribP3ui +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; +#define glVertexAttribP3uiv glad_glVertexAttribP3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; +#define glVertexAttribP4ui glad_glVertexAttribP4ui +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; +#define glVertexAttribP4uiv glad_glVertexAttribP4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD; +#define glVertexAttribParameteriAMD glad_glVertexAttribParameteriAMD +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB; +#define glVertexAttribPointerARB glad_glVertexAttribPointerARB +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV; +#define glVertexAttribPointerNV glad_glVertexAttribPointerNV +GLAD_API_CALL PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV; +#define glVertexAttribs1dvNV glad_glVertexAttribs1dvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV; +#define glVertexAttribs1fvNV glad_glVertexAttribs1fvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV; +#define glVertexAttribs1hvNV glad_glVertexAttribs1hvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV; +#define glVertexAttribs1svNV glad_glVertexAttribs1svNV +GLAD_API_CALL PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV; +#define glVertexAttribs2dvNV glad_glVertexAttribs2dvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV; +#define glVertexAttribs2fvNV glad_glVertexAttribs2fvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV; +#define glVertexAttribs2hvNV glad_glVertexAttribs2hvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV; +#define glVertexAttribs2svNV glad_glVertexAttribs2svNV +GLAD_API_CALL PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV; +#define glVertexAttribs3dvNV glad_glVertexAttribs3dvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV; +#define glVertexAttribs3fvNV glad_glVertexAttribs3fvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV; +#define glVertexAttribs3hvNV glad_glVertexAttribs3hvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV; +#define glVertexAttribs3svNV glad_glVertexAttribs3svNV +GLAD_API_CALL PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV; +#define glVertexAttribs4dvNV glad_glVertexAttribs4dvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV; +#define glVertexAttribs4fvNV glad_glVertexAttribs4fvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV; +#define glVertexAttribs4hvNV glad_glVertexAttribs4hvNV +GLAD_API_CALL PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV; +#define glVertexAttribs4svNV glad_glVertexAttribs4svNV +GLAD_API_CALL PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV; +#define glVertexAttribs4ubvNV glad_glVertexAttribs4ubvNV +GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; +#define glVertexBindingDivisor glad_glVertexBindingDivisor +GLAD_API_CALL PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB; +#define glVertexBlendARB glad_glVertexBlendARB +GLAD_API_CALL PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI; +#define glVertexBlendEnvfATI glad_glVertexBlendEnvfATI +GLAD_API_CALL PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI; +#define glVertexBlendEnviATI glad_glVertexBlendEnviATI +GLAD_API_CALL PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV; +#define glVertexFormatNV glad_glVertexFormatNV +GLAD_API_CALL PFNGLVERTEXP2UIPROC glad_glVertexP2ui; +#define glVertexP2ui glad_glVertexP2ui +GLAD_API_CALL PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; +#define glVertexP2uiv glad_glVertexP2uiv +GLAD_API_CALL PFNGLVERTEXP3UIPROC glad_glVertexP3ui; +#define glVertexP3ui glad_glVertexP3ui +GLAD_API_CALL PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; +#define glVertexP3uiv glad_glVertexP3uiv +GLAD_API_CALL PFNGLVERTEXP4UIPROC glad_glVertexP4ui; +#define glVertexP4ui glad_glVertexP4ui +GLAD_API_CALL PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; +#define glVertexP4uiv glad_glVertexP4uiv +GLAD_API_CALL PFNGLVERTEXPOINTERPROC glad_glVertexPointer; +#define glVertexPointer glad_glVertexPointer +GLAD_API_CALL PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT; +#define glVertexPointerEXT glad_glVertexPointerEXT +GLAD_API_CALL PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM; +#define glVertexPointerListIBM glad_glVertexPointerListIBM +GLAD_API_CALL PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL; +#define glVertexPointervINTEL glad_glVertexPointervINTEL +GLAD_API_CALL PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI; +#define glVertexStream1dATI glad_glVertexStream1dATI +GLAD_API_CALL PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI; +#define glVertexStream1dvATI glad_glVertexStream1dvATI +GLAD_API_CALL PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI; +#define glVertexStream1fATI glad_glVertexStream1fATI +GLAD_API_CALL PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI; +#define glVertexStream1fvATI glad_glVertexStream1fvATI +GLAD_API_CALL PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI; +#define glVertexStream1iATI glad_glVertexStream1iATI +GLAD_API_CALL PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI; +#define glVertexStream1ivATI glad_glVertexStream1ivATI +GLAD_API_CALL PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI; +#define glVertexStream1sATI glad_glVertexStream1sATI +GLAD_API_CALL PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI; +#define glVertexStream1svATI glad_glVertexStream1svATI +GLAD_API_CALL PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI; +#define glVertexStream2dATI glad_glVertexStream2dATI +GLAD_API_CALL PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI; +#define glVertexStream2dvATI glad_glVertexStream2dvATI +GLAD_API_CALL PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI; +#define glVertexStream2fATI glad_glVertexStream2fATI +GLAD_API_CALL PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI; +#define glVertexStream2fvATI glad_glVertexStream2fvATI +GLAD_API_CALL PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI; +#define glVertexStream2iATI glad_glVertexStream2iATI +GLAD_API_CALL PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI; +#define glVertexStream2ivATI glad_glVertexStream2ivATI +GLAD_API_CALL PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI; +#define glVertexStream2sATI glad_glVertexStream2sATI +GLAD_API_CALL PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI; +#define glVertexStream2svATI glad_glVertexStream2svATI +GLAD_API_CALL PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI; +#define glVertexStream3dATI glad_glVertexStream3dATI +GLAD_API_CALL PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI; +#define glVertexStream3dvATI glad_glVertexStream3dvATI +GLAD_API_CALL PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI; +#define glVertexStream3fATI glad_glVertexStream3fATI +GLAD_API_CALL PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI; +#define glVertexStream3fvATI glad_glVertexStream3fvATI +GLAD_API_CALL PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI; +#define glVertexStream3iATI glad_glVertexStream3iATI +GLAD_API_CALL PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI; +#define glVertexStream3ivATI glad_glVertexStream3ivATI +GLAD_API_CALL PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI; +#define glVertexStream3sATI glad_glVertexStream3sATI +GLAD_API_CALL PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI; +#define glVertexStream3svATI glad_glVertexStream3svATI +GLAD_API_CALL PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI; +#define glVertexStream4dATI glad_glVertexStream4dATI +GLAD_API_CALL PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI; +#define glVertexStream4dvATI glad_glVertexStream4dvATI +GLAD_API_CALL PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI; +#define glVertexStream4fATI glad_glVertexStream4fATI +GLAD_API_CALL PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI; +#define glVertexStream4fvATI glad_glVertexStream4fvATI +GLAD_API_CALL PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI; +#define glVertexStream4iATI glad_glVertexStream4iATI +GLAD_API_CALL PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI; +#define glVertexStream4ivATI glad_glVertexStream4ivATI +GLAD_API_CALL PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI; +#define glVertexStream4sATI glad_glVertexStream4sATI +GLAD_API_CALL PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI; +#define glVertexStream4svATI glad_glVertexStream4svATI +GLAD_API_CALL PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT; +#define glVertexWeightPointerEXT glad_glVertexWeightPointerEXT +GLAD_API_CALL PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT; +#define glVertexWeightfEXT glad_glVertexWeightfEXT +GLAD_API_CALL PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT; +#define glVertexWeightfvEXT glad_glVertexWeightfvEXT +GLAD_API_CALL PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV; +#define glVertexWeighthNV glad_glVertexWeighthNV +GLAD_API_CALL PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV; +#define glVertexWeighthvNV glad_glVertexWeighthvNV +GLAD_API_CALL PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV; +#define glVideoCaptureNV glad_glVideoCaptureNV +GLAD_API_CALL PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV; +#define glVideoCaptureStreamParameterdvNV glad_glVideoCaptureStreamParameterdvNV +GLAD_API_CALL PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV; +#define glVideoCaptureStreamParameterfvNV glad_glVideoCaptureStreamParameterfvNV +GLAD_API_CALL PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV; +#define glVideoCaptureStreamParameterivNV glad_glVideoCaptureStreamParameterivNV +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; +#define glViewportArrayv glad_glViewportArrayv +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; +#define glViewportIndexedf glad_glViewportIndexedf +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; +#define glViewportIndexedfv glad_glViewportIndexedfv +GLAD_API_CALL PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV; +#define glViewportPositionWScaleNV glad_glViewportPositionWScaleNV +GLAD_API_CALL PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV; +#define glViewportSwizzleNV glad_glViewportSwizzleNV +GLAD_API_CALL PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT; +#define glWaitSemaphoreEXT glad_glWaitSemaphoreEXT +GLAD_API_CALL PFNGLWAITSEMAPHOREUI64NVXPROC glad_glWaitSemaphoreui64NVX; +#define glWaitSemaphoreui64NVX glad_glWaitSemaphoreui64NVX +GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +GLAD_API_CALL PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV; +#define glWaitVkSemaphoreNV glad_glWaitVkSemaphoreNV +GLAD_API_CALL PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV; +#define glWeightPathsNV glad_glWeightPathsNV +GLAD_API_CALL PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB; +#define glWeightPointerARB glad_glWeightPointerARB +GLAD_API_CALL PFNGLWEIGHTBVARBPROC glad_glWeightbvARB; +#define glWeightbvARB glad_glWeightbvARB +GLAD_API_CALL PFNGLWEIGHTDVARBPROC glad_glWeightdvARB; +#define glWeightdvARB glad_glWeightdvARB +GLAD_API_CALL PFNGLWEIGHTFVARBPROC glad_glWeightfvARB; +#define glWeightfvARB glad_glWeightfvARB +GLAD_API_CALL PFNGLWEIGHTIVARBPROC glad_glWeightivARB; +#define glWeightivARB glad_glWeightivARB +GLAD_API_CALL PFNGLWEIGHTSVARBPROC glad_glWeightsvARB; +#define glWeightsvARB glad_glWeightsvARB +GLAD_API_CALL PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB; +#define glWeightubvARB glad_glWeightubvARB +GLAD_API_CALL PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB; +#define glWeightuivARB glad_glWeightuivARB +GLAD_API_CALL PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB; +#define glWeightusvARB glad_glWeightusvARB +GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; +#define glWindowPos2d glad_glWindowPos2d +GLAD_API_CALL PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB; +#define glWindowPos2dARB glad_glWindowPos2dARB +GLAD_API_CALL PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA; +#define glWindowPos2dMESA glad_glWindowPos2dMESA +GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; +#define glWindowPos2dv glad_glWindowPos2dv +GLAD_API_CALL PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB; +#define glWindowPos2dvARB glad_glWindowPos2dvARB +GLAD_API_CALL PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA; +#define glWindowPos2dvMESA glad_glWindowPos2dvMESA +GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; +#define glWindowPos2f glad_glWindowPos2f +GLAD_API_CALL PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB; +#define glWindowPos2fARB glad_glWindowPos2fARB +GLAD_API_CALL PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA; +#define glWindowPos2fMESA glad_glWindowPos2fMESA +GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; +#define glWindowPos2fv glad_glWindowPos2fv +GLAD_API_CALL PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB; +#define glWindowPos2fvARB glad_glWindowPos2fvARB +GLAD_API_CALL PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA; +#define glWindowPos2fvMESA glad_glWindowPos2fvMESA +GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; +#define glWindowPos2i glad_glWindowPos2i +GLAD_API_CALL PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB; +#define glWindowPos2iARB glad_glWindowPos2iARB +GLAD_API_CALL PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA; +#define glWindowPos2iMESA glad_glWindowPos2iMESA +GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; +#define glWindowPos2iv glad_glWindowPos2iv +GLAD_API_CALL PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB; +#define glWindowPos2ivARB glad_glWindowPos2ivARB +GLAD_API_CALL PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA; +#define glWindowPos2ivMESA glad_glWindowPos2ivMESA +GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; +#define glWindowPos2s glad_glWindowPos2s +GLAD_API_CALL PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB; +#define glWindowPos2sARB glad_glWindowPos2sARB +GLAD_API_CALL PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA; +#define glWindowPos2sMESA glad_glWindowPos2sMESA +GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; +#define glWindowPos2sv glad_glWindowPos2sv +GLAD_API_CALL PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB; +#define glWindowPos2svARB glad_glWindowPos2svARB +GLAD_API_CALL PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA; +#define glWindowPos2svMESA glad_glWindowPos2svMESA +GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; +#define glWindowPos3d glad_glWindowPos3d +GLAD_API_CALL PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB; +#define glWindowPos3dARB glad_glWindowPos3dARB +GLAD_API_CALL PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA; +#define glWindowPos3dMESA glad_glWindowPos3dMESA +GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; +#define glWindowPos3dv glad_glWindowPos3dv +GLAD_API_CALL PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB; +#define glWindowPos3dvARB glad_glWindowPos3dvARB +GLAD_API_CALL PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA; +#define glWindowPos3dvMESA glad_glWindowPos3dvMESA +GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; +#define glWindowPos3f glad_glWindowPos3f +GLAD_API_CALL PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB; +#define glWindowPos3fARB glad_glWindowPos3fARB +GLAD_API_CALL PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA; +#define glWindowPos3fMESA glad_glWindowPos3fMESA +GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; +#define glWindowPos3fv glad_glWindowPos3fv +GLAD_API_CALL PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB; +#define glWindowPos3fvARB glad_glWindowPos3fvARB +GLAD_API_CALL PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA; +#define glWindowPos3fvMESA glad_glWindowPos3fvMESA +GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; +#define glWindowPos3i glad_glWindowPos3i +GLAD_API_CALL PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB; +#define glWindowPos3iARB glad_glWindowPos3iARB +GLAD_API_CALL PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA; +#define glWindowPos3iMESA glad_glWindowPos3iMESA +GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; +#define glWindowPos3iv glad_glWindowPos3iv +GLAD_API_CALL PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB; +#define glWindowPos3ivARB glad_glWindowPos3ivARB +GLAD_API_CALL PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA; +#define glWindowPos3ivMESA glad_glWindowPos3ivMESA +GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; +#define glWindowPos3s glad_glWindowPos3s +GLAD_API_CALL PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB; +#define glWindowPos3sARB glad_glWindowPos3sARB +GLAD_API_CALL PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA; +#define glWindowPos3sMESA glad_glWindowPos3sMESA +GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; +#define glWindowPos3sv glad_glWindowPos3sv +GLAD_API_CALL PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB; +#define glWindowPos3svARB glad_glWindowPos3svARB +GLAD_API_CALL PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA; +#define glWindowPos3svMESA glad_glWindowPos3svMESA +GLAD_API_CALL PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA; +#define glWindowPos4dMESA glad_glWindowPos4dMESA +GLAD_API_CALL PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA; +#define glWindowPos4dvMESA glad_glWindowPos4dvMESA +GLAD_API_CALL PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA; +#define glWindowPos4fMESA glad_glWindowPos4fMESA +GLAD_API_CALL PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA; +#define glWindowPos4fvMESA glad_glWindowPos4fvMESA +GLAD_API_CALL PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA; +#define glWindowPos4iMESA glad_glWindowPos4iMESA +GLAD_API_CALL PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA; +#define glWindowPos4ivMESA glad_glWindowPos4ivMESA +GLAD_API_CALL PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA; +#define glWindowPos4sMESA glad_glWindowPos4sMESA +GLAD_API_CALL PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA; +#define glWindowPos4svMESA glad_glWindowPos4svMESA +GLAD_API_CALL PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT; +#define glWindowRectanglesEXT glad_glWindowRectanglesEXT +GLAD_API_CALL PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT; +#define glWriteMaskEXT glad_glWriteMaskEXT +GLAD_API_CALL PFNGLALPHAFUNCXPROC glad_glAlphaFuncx; +#define glAlphaFuncx glad_glAlphaFuncx +GLAD_API_CALL PFNGLBINDFRAMEBUFFEROESPROC glad_glBindFramebufferOES; +#define glBindFramebufferOES glad_glBindFramebufferOES +GLAD_API_CALL PFNGLBINDRENDERBUFFEROESPROC glad_glBindRenderbufferOES; +#define glBindRenderbufferOES glad_glBindRenderbufferOES +GLAD_API_CALL PFNGLBINDVERTEXARRAYOESPROC glad_glBindVertexArrayOES; +#define glBindVertexArrayOES glad_glBindVertexArrayOES +GLAD_API_CALL PFNGLBLENDEQUATIONOESPROC glad_glBlendEquationOES; +#define glBlendEquationOES glad_glBlendEquationOES +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEOESPROC glad_glBlendEquationSeparateOES; +#define glBlendEquationSeparateOES glad_glBlendEquationSeparateOES +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEOESPROC glad_glBlendFuncSeparateOES; +#define glBlendFuncSeparateOES glad_glBlendFuncSeparateOES +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSOESPROC glad_glCheckFramebufferStatusOES; +#define glCheckFramebufferStatusOES glad_glCheckFramebufferStatusOES +GLAD_API_CALL PFNGLCLEARCOLORXPROC glad_glClearColorx; +#define glClearColorx glad_glClearColorx +GLAD_API_CALL PFNGLCLEARDEPTHXPROC glad_glClearDepthx; +#define glClearDepthx glad_glClearDepthx +GLAD_API_CALL PFNGLCLIENTWAITSYNCAPPLEPROC glad_glClientWaitSyncAPPLE; +#define glClientWaitSyncAPPLE glad_glClientWaitSyncAPPLE +GLAD_API_CALL PFNGLCLIPPLANEFPROC glad_glClipPlanef; +#define glClipPlanef glad_glClipPlanef +GLAD_API_CALL PFNGLCLIPPLANEFIMGPROC glad_glClipPlanefIMG; +#define glClipPlanefIMG glad_glClipPlanefIMG +GLAD_API_CALL PFNGLCLIPPLANEXPROC glad_glClipPlanex; +#define glClipPlanex glad_glClipPlanex +GLAD_API_CALL PFNGLCLIPPLANEXIMGPROC glad_glClipPlanexIMG; +#define glClipPlanexIMG glad_glClipPlanexIMG +GLAD_API_CALL PFNGLCOLOR4XPROC glad_glColor4x; +#define glColor4x glad_glColor4x +GLAD_API_CALL PFNGLCOPYTEXTURELEVELSAPPLEPROC glad_glCopyTextureLevelsAPPLE; +#define glCopyTextureLevelsAPPLE glad_glCopyTextureLevelsAPPLE +GLAD_API_CALL PFNGLCURRENTPALETTEMATRIXOESPROC glad_glCurrentPaletteMatrixOES; +#define glCurrentPaletteMatrixOES glad_glCurrentPaletteMatrixOES +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSOESPROC glad_glDeleteFramebuffersOES; +#define glDeleteFramebuffersOES glad_glDeleteFramebuffersOES +GLAD_API_CALL PFNGLDELETERENDERBUFFERSOESPROC glad_glDeleteRenderbuffersOES; +#define glDeleteRenderbuffersOES glad_glDeleteRenderbuffersOES +GLAD_API_CALL PFNGLDELETESYNCAPPLEPROC glad_glDeleteSyncAPPLE; +#define glDeleteSyncAPPLE glad_glDeleteSyncAPPLE +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSOESPROC glad_glDeleteVertexArraysOES; +#define glDeleteVertexArraysOES glad_glDeleteVertexArraysOES +GLAD_API_CALL PFNGLDEPTHRANGEXPROC glad_glDepthRangex; +#define glDepthRangex glad_glDepthRangex +GLAD_API_CALL PFNGLDISABLEDRIVERCONTROLQCOMPROC glad_glDisableDriverControlQCOM; +#define glDisableDriverControlQCOM glad_glDisableDriverControlQCOM +GLAD_API_CALL PFNGLDISCARDFRAMEBUFFEREXTPROC glad_glDiscardFramebufferEXT; +#define glDiscardFramebufferEXT glad_glDiscardFramebufferEXT +GLAD_API_CALL PFNGLDRAWTEXFOESPROC glad_glDrawTexfOES; +#define glDrawTexfOES glad_glDrawTexfOES +GLAD_API_CALL PFNGLDRAWTEXFVOESPROC glad_glDrawTexfvOES; +#define glDrawTexfvOES glad_glDrawTexfvOES +GLAD_API_CALL PFNGLDRAWTEXIOESPROC glad_glDrawTexiOES; +#define glDrawTexiOES glad_glDrawTexiOES +GLAD_API_CALL PFNGLDRAWTEXIVOESPROC glad_glDrawTexivOES; +#define glDrawTexivOES glad_glDrawTexivOES +GLAD_API_CALL PFNGLDRAWTEXSOESPROC glad_glDrawTexsOES; +#define glDrawTexsOES glad_glDrawTexsOES +GLAD_API_CALL PFNGLDRAWTEXSVOESPROC glad_glDrawTexsvOES; +#define glDrawTexsvOES glad_glDrawTexsvOES +GLAD_API_CALL PFNGLDRAWTEXXOESPROC glad_glDrawTexxOES; +#define glDrawTexxOES glad_glDrawTexxOES +GLAD_API_CALL PFNGLDRAWTEXXVOESPROC glad_glDrawTexxvOES; +#define glDrawTexxvOES glad_glDrawTexxvOES +GLAD_API_CALL PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glad_glEGLImageTargetRenderbufferStorageOES; +#define glEGLImageTargetRenderbufferStorageOES glad_glEGLImageTargetRenderbufferStorageOES +GLAD_API_CALL PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glad_glEGLImageTargetTexture2DOES; +#define glEGLImageTargetTexture2DOES glad_glEGLImageTargetTexture2DOES +GLAD_API_CALL PFNGLENABLEDRIVERCONTROLQCOMPROC glad_glEnableDriverControlQCOM; +#define glEnableDriverControlQCOM glad_glEnableDriverControlQCOM +GLAD_API_CALL PFNGLENDTILINGQCOMPROC glad_glEndTilingQCOM; +#define glEndTilingQCOM glad_glEndTilingQCOM +GLAD_API_CALL PFNGLEXTGETBUFFERPOINTERVQCOMPROC glad_glExtGetBufferPointervQCOM; +#define glExtGetBufferPointervQCOM glad_glExtGetBufferPointervQCOM +GLAD_API_CALL PFNGLEXTGETBUFFERSQCOMPROC glad_glExtGetBuffersQCOM; +#define glExtGetBuffersQCOM glad_glExtGetBuffersQCOM +GLAD_API_CALL PFNGLEXTGETFRAMEBUFFERSQCOMPROC glad_glExtGetFramebuffersQCOM; +#define glExtGetFramebuffersQCOM glad_glExtGetFramebuffersQCOM +GLAD_API_CALL PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC glad_glExtGetProgramBinarySourceQCOM; +#define glExtGetProgramBinarySourceQCOM glad_glExtGetProgramBinarySourceQCOM +GLAD_API_CALL PFNGLEXTGETPROGRAMSQCOMPROC glad_glExtGetProgramsQCOM; +#define glExtGetProgramsQCOM glad_glExtGetProgramsQCOM +GLAD_API_CALL PFNGLEXTGETRENDERBUFFERSQCOMPROC glad_glExtGetRenderbuffersQCOM; +#define glExtGetRenderbuffersQCOM glad_glExtGetRenderbuffersQCOM +GLAD_API_CALL PFNGLEXTGETSHADERSQCOMPROC glad_glExtGetShadersQCOM; +#define glExtGetShadersQCOM glad_glExtGetShadersQCOM +GLAD_API_CALL PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC glad_glExtGetTexLevelParameterivQCOM; +#define glExtGetTexLevelParameterivQCOM glad_glExtGetTexLevelParameterivQCOM +GLAD_API_CALL PFNGLEXTGETTEXSUBIMAGEQCOMPROC glad_glExtGetTexSubImageQCOM; +#define glExtGetTexSubImageQCOM glad_glExtGetTexSubImageQCOM +GLAD_API_CALL PFNGLEXTGETTEXTURESQCOMPROC glad_glExtGetTexturesQCOM; +#define glExtGetTexturesQCOM glad_glExtGetTexturesQCOM +GLAD_API_CALL PFNGLEXTISPROGRAMBINARYQCOMPROC glad_glExtIsProgramBinaryQCOM; +#define glExtIsProgramBinaryQCOM glad_glExtIsProgramBinaryQCOM +GLAD_API_CALL PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC glad_glExtTexObjectStateOverrideiQCOM; +#define glExtTexObjectStateOverrideiQCOM glad_glExtTexObjectStateOverrideiQCOM +GLAD_API_CALL PFNGLFENCESYNCAPPLEPROC glad_glFenceSyncAPPLE; +#define glFenceSyncAPPLE glad_glFenceSyncAPPLE +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC glad_glFlushMappedBufferRangeEXT; +#define glFlushMappedBufferRangeEXT glad_glFlushMappedBufferRangeEXT +GLAD_API_CALL PFNGLFOGXPROC glad_glFogx; +#define glFogx glad_glFogx +GLAD_API_CALL PFNGLFOGXVPROC glad_glFogxv; +#define glFogxv glad_glFogxv +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFEROESPROC glad_glFramebufferRenderbufferOES; +#define glFramebufferRenderbufferOES glad_glFramebufferRenderbufferOES +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT; +#define glFramebufferTexture2DMultisampleEXT glad_glFramebufferTexture2DMultisampleEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC glad_glFramebufferTexture2DMultisampleIMG; +#define glFramebufferTexture2DMultisampleIMG glad_glFramebufferTexture2DMultisampleIMG +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DOESPROC glad_glFramebufferTexture2DOES; +#define glFramebufferTexture2DOES glad_glFramebufferTexture2DOES +GLAD_API_CALL PFNGLFRUSTUMFPROC glad_glFrustumf; +#define glFrustumf glad_glFrustumf +GLAD_API_CALL PFNGLFRUSTUMXPROC glad_glFrustumx; +#define glFrustumx glad_glFrustumx +GLAD_API_CALL PFNGLGENFRAMEBUFFERSOESPROC glad_glGenFramebuffersOES; +#define glGenFramebuffersOES glad_glGenFramebuffersOES +GLAD_API_CALL PFNGLGENRENDERBUFFERSOESPROC glad_glGenRenderbuffersOES; +#define glGenRenderbuffersOES glad_glGenRenderbuffersOES +GLAD_API_CALL PFNGLGENVERTEXARRAYSOESPROC glad_glGenVertexArraysOES; +#define glGenVertexArraysOES glad_glGenVertexArraysOES +GLAD_API_CALL PFNGLGENERATEMIPMAPOESPROC glad_glGenerateMipmapOES; +#define glGenerateMipmapOES glad_glGenerateMipmapOES +GLAD_API_CALL PFNGLGETBUFFERPOINTERVOESPROC glad_glGetBufferPointervOES; +#define glGetBufferPointervOES glad_glGetBufferPointervOES +GLAD_API_CALL PFNGLGETCLIPPLANEFPROC glad_glGetClipPlanef; +#define glGetClipPlanef glad_glGetClipPlanef +GLAD_API_CALL PFNGLGETCLIPPLANEXPROC glad_glGetClipPlanex; +#define glGetClipPlanex glad_glGetClipPlanex +GLAD_API_CALL PFNGLGETDRIVERCONTROLSTRINGQCOMPROC glad_glGetDriverControlStringQCOM; +#define glGetDriverControlStringQCOM glad_glGetDriverControlStringQCOM +GLAD_API_CALL PFNGLGETDRIVERCONTROLSQCOMPROC glad_glGetDriverControlsQCOM; +#define glGetDriverControlsQCOM glad_glGetDriverControlsQCOM +GLAD_API_CALL PFNGLGETFIXEDVPROC glad_glGetFixedv; +#define glGetFixedv glad_glGetFixedv +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC glad_glGetFramebufferAttachmentParameterivOES; +#define glGetFramebufferAttachmentParameterivOES glad_glGetFramebufferAttachmentParameterivOES +GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSEXTPROC glad_glGetGraphicsResetStatusEXT; +#define glGetGraphicsResetStatusEXT glad_glGetGraphicsResetStatusEXT +GLAD_API_CALL PFNGLGETINTEGER64VAPPLEPROC glad_glGetInteger64vAPPLE; +#define glGetInteger64vAPPLE glad_glGetInteger64vAPPLE +GLAD_API_CALL PFNGLGETLIGHTXVPROC glad_glGetLightxv; +#define glGetLightxv glad_glGetLightxv +GLAD_API_CALL PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES; +#define glGetLightxvOES glad_glGetLightxvOES +GLAD_API_CALL PFNGLGETMATERIALXVPROC glad_glGetMaterialxv; +#define glGetMaterialxv glad_glGetMaterialxv +GLAD_API_CALL PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES; +#define glGetMaterialxvOES glad_glGetMaterialxvOES +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVOESPROC glad_glGetRenderbufferParameterivOES; +#define glGetRenderbufferParameterivOES glad_glGetRenderbufferParameterivOES +GLAD_API_CALL PFNGLGETSYNCIVAPPLEPROC glad_glGetSyncivAPPLE; +#define glGetSyncivAPPLE glad_glGetSyncivAPPLE +GLAD_API_CALL PFNGLGETTEXENVXVPROC glad_glGetTexEnvxv; +#define glGetTexEnvxv glad_glGetTexEnvxv +GLAD_API_CALL PFNGLGETTEXGENFVOESPROC glad_glGetTexGenfvOES; +#define glGetTexGenfvOES glad_glGetTexGenfvOES +GLAD_API_CALL PFNGLGETTEXGENIVOESPROC glad_glGetTexGenivOES; +#define glGetTexGenivOES glad_glGetTexGenivOES +GLAD_API_CALL PFNGLGETTEXPARAMETERXVPROC glad_glGetTexParameterxv; +#define glGetTexParameterxv glad_glGetTexParameterxv +GLAD_API_CALL PFNGLGETNUNIFORMFVEXTPROC glad_glGetnUniformfvEXT; +#define glGetnUniformfvEXT glad_glGetnUniformfvEXT +GLAD_API_CALL PFNGLGETNUNIFORMIVEXTPROC glad_glGetnUniformivEXT; +#define glGetnUniformivEXT glad_glGetnUniformivEXT +GLAD_API_CALL PFNGLISFRAMEBUFFEROESPROC glad_glIsFramebufferOES; +#define glIsFramebufferOES glad_glIsFramebufferOES +GLAD_API_CALL PFNGLISRENDERBUFFEROESPROC glad_glIsRenderbufferOES; +#define glIsRenderbufferOES glad_glIsRenderbufferOES +GLAD_API_CALL PFNGLISSYNCAPPLEPROC glad_glIsSyncAPPLE; +#define glIsSyncAPPLE glad_glIsSyncAPPLE +GLAD_API_CALL PFNGLISVERTEXARRAYOESPROC glad_glIsVertexArrayOES; +#define glIsVertexArrayOES glad_glIsVertexArrayOES +GLAD_API_CALL PFNGLLIGHTMODELXPROC glad_glLightModelx; +#define glLightModelx glad_glLightModelx +GLAD_API_CALL PFNGLLIGHTMODELXVPROC glad_glLightModelxv; +#define glLightModelxv glad_glLightModelxv +GLAD_API_CALL PFNGLLIGHTXPROC glad_glLightx; +#define glLightx glad_glLightx +GLAD_API_CALL PFNGLLIGHTXVPROC glad_glLightxv; +#define glLightxv glad_glLightxv +GLAD_API_CALL PFNGLLINEWIDTHXPROC glad_glLineWidthx; +#define glLineWidthx glad_glLineWidthx +GLAD_API_CALL PFNGLLOADMATRIXXPROC glad_glLoadMatrixx; +#define glLoadMatrixx glad_glLoadMatrixx +GLAD_API_CALL PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC glad_glLoadPaletteFromModelViewMatrixOES; +#define glLoadPaletteFromModelViewMatrixOES glad_glLoadPaletteFromModelViewMatrixOES +GLAD_API_CALL PFNGLMAPBUFFEROESPROC glad_glMapBufferOES; +#define glMapBufferOES glad_glMapBufferOES +GLAD_API_CALL PFNGLMAPBUFFERRANGEEXTPROC glad_glMapBufferRangeEXT; +#define glMapBufferRangeEXT glad_glMapBufferRangeEXT +GLAD_API_CALL PFNGLMATERIALXPROC glad_glMaterialx; +#define glMaterialx glad_glMaterialx +GLAD_API_CALL PFNGLMATERIALXVPROC glad_glMaterialxv; +#define glMaterialxv glad_glMaterialxv +GLAD_API_CALL PFNGLMATRIXINDEXPOINTEROESPROC glad_glMatrixIndexPointerOES; +#define glMatrixIndexPointerOES glad_glMatrixIndexPointerOES +GLAD_API_CALL PFNGLMULTMATRIXXPROC glad_glMultMatrixx; +#define glMultMatrixx glad_glMultMatrixx +GLAD_API_CALL PFNGLMULTITEXCOORD4XPROC glad_glMultiTexCoord4x; +#define glMultiTexCoord4x glad_glMultiTexCoord4x +GLAD_API_CALL PFNGLNORMAL3XPROC glad_glNormal3x; +#define glNormal3x glad_glNormal3x +GLAD_API_CALL PFNGLORTHOFPROC glad_glOrthof; +#define glOrthof glad_glOrthof +GLAD_API_CALL PFNGLORTHOXPROC glad_glOrthox; +#define glOrthox glad_glOrthox +GLAD_API_CALL PFNGLPOINTPARAMETERXPROC glad_glPointParameterx; +#define glPointParameterx glad_glPointParameterx +GLAD_API_CALL PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES; +#define glPointParameterxOES glad_glPointParameterxOES +GLAD_API_CALL PFNGLPOINTPARAMETERXVPROC glad_glPointParameterxv; +#define glPointParameterxv glad_glPointParameterxv +GLAD_API_CALL PFNGLPOINTSIZEPOINTEROESPROC glad_glPointSizePointerOES; +#define glPointSizePointerOES glad_glPointSizePointerOES +GLAD_API_CALL PFNGLPOINTSIZEXPROC glad_glPointSizex; +#define glPointSizex glad_glPointSizex +GLAD_API_CALL PFNGLPOLYGONOFFSETXPROC glad_glPolygonOffsetx; +#define glPolygonOffsetx glad_glPolygonOffsetx +GLAD_API_CALL PFNGLREADNPIXELSEXTPROC glad_glReadnPixelsEXT; +#define glReadnPixelsEXT glad_glReadnPixelsEXT +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC glad_glRenderbufferStorageMultisampleAPPLE; +#define glRenderbufferStorageMultisampleAPPLE glad_glRenderbufferStorageMultisampleAPPLE +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC glad_glRenderbufferStorageMultisampleIMG; +#define glRenderbufferStorageMultisampleIMG glad_glRenderbufferStorageMultisampleIMG +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEOESPROC glad_glRenderbufferStorageOES; +#define glRenderbufferStorageOES glad_glRenderbufferStorageOES +GLAD_API_CALL PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC glad_glResolveMultisampleFramebufferAPPLE; +#define glResolveMultisampleFramebufferAPPLE glad_glResolveMultisampleFramebufferAPPLE +GLAD_API_CALL PFNGLROTATEXPROC glad_glRotatex; +#define glRotatex glad_glRotatex +GLAD_API_CALL PFNGLSAMPLECOVERAGEXPROC glad_glSampleCoveragex; +#define glSampleCoveragex glad_glSampleCoveragex +GLAD_API_CALL PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES; +#define glSampleCoveragexOES glad_glSampleCoveragexOES +GLAD_API_CALL PFNGLSCALEXPROC glad_glScalex; +#define glScalex glad_glScalex +GLAD_API_CALL PFNGLSTARTTILINGQCOMPROC glad_glStartTilingQCOM; +#define glStartTilingQCOM glad_glStartTilingQCOM +GLAD_API_CALL PFNGLTEXENVXPROC glad_glTexEnvx; +#define glTexEnvx glad_glTexEnvx +GLAD_API_CALL PFNGLTEXENVXVPROC glad_glTexEnvxv; +#define glTexEnvxv glad_glTexEnvxv +GLAD_API_CALL PFNGLTEXGENFOESPROC glad_glTexGenfOES; +#define glTexGenfOES glad_glTexGenfOES +GLAD_API_CALL PFNGLTEXGENFVOESPROC glad_glTexGenfvOES; +#define glTexGenfvOES glad_glTexGenfvOES +GLAD_API_CALL PFNGLTEXGENIOESPROC glad_glTexGeniOES; +#define glTexGeniOES glad_glTexGeniOES +GLAD_API_CALL PFNGLTEXGENIVOESPROC glad_glTexGenivOES; +#define glTexGenivOES glad_glTexGenivOES +GLAD_API_CALL PFNGLTEXPARAMETERXPROC glad_glTexParameterx; +#define glTexParameterx glad_glTexParameterx +GLAD_API_CALL PFNGLTEXPARAMETERXVPROC glad_glTexParameterxv; +#define glTexParameterxv glad_glTexParameterxv +GLAD_API_CALL PFNGLTRANSLATEXPROC glad_glTranslatex; +#define glTranslatex glad_glTranslatex +GLAD_API_CALL PFNGLUNMAPBUFFEROESPROC glad_glUnmapBufferOES; +#define glUnmapBufferOES glad_glUnmapBufferOES +GLAD_API_CALL PFNGLWAITSYNCAPPLEPROC glad_glWaitSyncAPPLE; +#define glWaitSyncAPPLE glad_glWaitSyncAPPLE +GLAD_API_CALL PFNGLWEIGHTPOINTEROESPROC glad_glWeightPointerOES; +#define glWeightPointerOES glad_glWeightPointerOES +GLAD_API_CALL PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT; +#define glActiveShaderProgramEXT glad_glActiveShaderProgramEXT +GLAD_API_CALL PFNGLALPHAFUNCQCOMPROC glad_glAlphaFuncQCOM; +#define glAlphaFuncQCOM glad_glAlphaFuncQCOM +GLAD_API_CALL PFNGLBEGINQUERYEXTPROC glad_glBeginQueryEXT; +#define glBeginQueryEXT glad_glBeginQueryEXT +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC glad_glBindFragDataLocationIndexedEXT; +#define glBindFragDataLocationIndexedEXT glad_glBindFragDataLocationIndexedEXT +GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT; +#define glBindProgramPipelineEXT glad_glBindProgramPipelineEXT +GLAD_API_CALL PFNGLBLENDBARRIERPROC glad_glBlendBarrier; +#define glBlendBarrier glad_glBlendBarrier +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIEXTPROC glad_glBlendEquationSeparateiEXT; +#define glBlendEquationSeparateiEXT glad_glBlendEquationSeparateiEXT +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIOESPROC glad_glBlendEquationSeparateiOES; +#define glBlendEquationSeparateiOES glad_glBlendEquationSeparateiOES +GLAD_API_CALL PFNGLBLENDEQUATIONIEXTPROC glad_glBlendEquationiEXT; +#define glBlendEquationiEXT glad_glBlendEquationiEXT +GLAD_API_CALL PFNGLBLENDEQUATIONIOESPROC glad_glBlendEquationiOES; +#define glBlendEquationiOES glad_glBlendEquationiOES +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIEXTPROC glad_glBlendFuncSeparateiEXT; +#define glBlendFuncSeparateiEXT glad_glBlendFuncSeparateiEXT +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIOESPROC glad_glBlendFuncSeparateiOES; +#define glBlendFuncSeparateiOES glad_glBlendFuncSeparateiOES +GLAD_API_CALL PFNGLBLENDFUNCIEXTPROC glad_glBlendFunciEXT; +#define glBlendFunciEXT glad_glBlendFunciEXT +GLAD_API_CALL PFNGLBLENDFUNCIOESPROC glad_glBlendFunciOES; +#define glBlendFunciOES glad_glBlendFunciOES +GLAD_API_CALL PFNGLBLITFRAMEBUFFERANGLEPROC glad_glBlitFramebufferANGLE; +#define glBlitFramebufferANGLE glad_glBlitFramebufferANGLE +GLAD_API_CALL PFNGLBLITFRAMEBUFFERNVPROC glad_glBlitFramebufferNV; +#define glBlitFramebufferNV glad_glBlitFramebufferNV +GLAD_API_CALL PFNGLBUFFERSTORAGEEXTPROC glad_glBufferStorageEXT; +#define glBufferStorageEXT glad_glBufferStorageEXT +GLAD_API_CALL PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC glad_glClearPixelLocalStorageuiEXT; +#define glClearPixelLocalStorageuiEXT glad_glClearPixelLocalStorageuiEXT +GLAD_API_CALL PFNGLCLEARTEXIMAGEEXTPROC glad_glClearTexImageEXT; +#define glClearTexImageEXT glad_glClearTexImageEXT +GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEEXTPROC glad_glClearTexSubImageEXT; +#define glClearTexSubImageEXT glad_glClearTexSubImageEXT +GLAD_API_CALL PFNGLCLIPCONTROLEXTPROC glad_glClipControlEXT; +#define glClipControlEXT glad_glClipControlEXT +GLAD_API_CALL PFNGLCOLORMASKIEXTPROC glad_glColorMaskiEXT; +#define glColorMaskiEXT glad_glColorMaskiEXT +GLAD_API_CALL PFNGLCOLORMASKIOESPROC glad_glColorMaskiOES; +#define glColorMaskiOES glad_glColorMaskiOES +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DOESPROC glad_glCompressedTexImage3DOES; +#define glCompressedTexImage3DOES glad_glCompressedTexImage3DOES +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC glad_glCompressedTexSubImage3DOES; +#define glCompressedTexSubImage3DOES glad_glCompressedTexSubImage3DOES +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATANVPROC glad_glCopyBufferSubDataNV; +#define glCopyBufferSubDataNV glad_glCopyBufferSubDataNV +GLAD_API_CALL PFNGLCOPYIMAGESUBDATAEXTPROC glad_glCopyImageSubDataEXT; +#define glCopyImageSubDataEXT glad_glCopyImageSubDataEXT +GLAD_API_CALL PFNGLCOPYIMAGESUBDATAOESPROC glad_glCopyImageSubDataOES; +#define glCopyImageSubDataOES glad_glCopyImageSubDataOES +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DOESPROC glad_glCopyTexSubImage3DOES; +#define glCopyTexSubImage3DOES glad_glCopyTexSubImage3DOES +GLAD_API_CALL PFNGLCOVERAGEMASKNVPROC glad_glCoverageMaskNV; +#define glCoverageMaskNV glad_glCoverageMaskNV +GLAD_API_CALL PFNGLCOVERAGEOPERATIONNVPROC glad_glCoverageOperationNV; +#define glCoverageOperationNV glad_glCoverageOperationNV +GLAD_API_CALL PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT; +#define glCreateShaderProgramvEXT glad_glCreateShaderProgramvEXT +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; +#define glDebugMessageCallbackKHR glad_glDebugMessageCallbackKHR +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; +#define glDebugMessageControlKHR glad_glDebugMessageControlKHR +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; +#define glDebugMessageInsertKHR glad_glDebugMessageInsertKHR +GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT; +#define glDeleteProgramPipelinesEXT glad_glDeleteProgramPipelinesEXT +GLAD_API_CALL PFNGLDELETEQUERIESEXTPROC glad_glDeleteQueriesEXT; +#define glDeleteQueriesEXT glad_glDeleteQueriesEXT +GLAD_API_CALL PFNGLDEPTHRANGEARRAYFVNVPROC glad_glDepthRangeArrayfvNV; +#define glDepthRangeArrayfvNV glad_glDepthRangeArrayfvNV +GLAD_API_CALL PFNGLDEPTHRANGEARRAYFVOESPROC glad_glDepthRangeArrayfvOES; +#define glDepthRangeArrayfvOES glad_glDepthRangeArrayfvOES +GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDFNVPROC glad_glDepthRangeIndexedfNV; +#define glDepthRangeIndexedfNV glad_glDepthRangeIndexedfNV +GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDFOESPROC glad_glDepthRangeIndexedfOES; +#define glDepthRangeIndexedfOES glad_glDepthRangeIndexedfOES +GLAD_API_CALL PFNGLDISABLEIEXTPROC glad_glDisableiEXT; +#define glDisableiEXT glad_glDisableiEXT +GLAD_API_CALL PFNGLDISABLEINVPROC glad_glDisableiNV; +#define glDisableiNV glad_glDisableiNV +GLAD_API_CALL PFNGLDISABLEIOESPROC glad_glDisableiOES; +#define glDisableiOES glad_glDisableiOES +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDANGLEPROC glad_glDrawArraysInstancedANGLE; +#define glDrawArraysInstancedANGLE glad_glDrawArraysInstancedANGLE +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT; +#define glDrawArraysInstancedBaseInstanceEXT glad_glDrawArraysInstancedBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDNVPROC glad_glDrawArraysInstancedNV; +#define glDrawArraysInstancedNV glad_glDrawArraysInstancedNV +GLAD_API_CALL PFNGLDRAWBUFFERSEXTPROC glad_glDrawBuffersEXT; +#define glDrawBuffersEXT glad_glDrawBuffersEXT +GLAD_API_CALL PFNGLDRAWBUFFERSINDEXEDEXTPROC glad_glDrawBuffersIndexedEXT; +#define glDrawBuffersIndexedEXT glad_glDrawBuffersIndexedEXT +GLAD_API_CALL PFNGLDRAWBUFFERSNVPROC glad_glDrawBuffersNV; +#define glDrawBuffersNV glad_glDrawBuffersNV +GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXEXTPROC glad_glDrawElementsBaseVertexEXT; +#define glDrawElementsBaseVertexEXT glad_glDrawElementsBaseVertexEXT +GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXOESPROC glad_glDrawElementsBaseVertexOES; +#define glDrawElementsBaseVertexOES glad_glDrawElementsBaseVertexOES +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDANGLEPROC glad_glDrawElementsInstancedANGLE; +#define glDrawElementsInstancedANGLE glad_glDrawElementsInstancedANGLE +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT; +#define glDrawElementsInstancedBaseInstanceEXT glad_glDrawElementsInstancedBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +#define glDrawElementsInstancedBaseVertexBaseInstanceEXT glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC glad_glDrawElementsInstancedBaseVertexEXT; +#define glDrawElementsInstancedBaseVertexEXT glad_glDrawElementsInstancedBaseVertexEXT +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC glad_glDrawElementsInstancedBaseVertexOES; +#define glDrawElementsInstancedBaseVertexOES glad_glDrawElementsInstancedBaseVertexOES +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDNVPROC glad_glDrawElementsInstancedNV; +#define glDrawElementsInstancedNV glad_glDrawElementsInstancedNV +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC glad_glDrawRangeElementsBaseVertexEXT; +#define glDrawRangeElementsBaseVertexEXT glad_glDrawRangeElementsBaseVertexEXT +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC glad_glDrawRangeElementsBaseVertexOES; +#define glDrawRangeElementsBaseVertexOES glad_glDrawRangeElementsBaseVertexOES +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKEXTPROC glad_glDrawTransformFeedbackEXT; +#define glDrawTransformFeedbackEXT glad_glDrawTransformFeedbackEXT +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC glad_glDrawTransformFeedbackInstancedEXT; +#define glDrawTransformFeedbackInstancedEXT glad_glDrawTransformFeedbackInstancedEXT +GLAD_API_CALL PFNGLENABLEIEXTPROC glad_glEnableiEXT; +#define glEnableiEXT glad_glEnableiEXT +GLAD_API_CALL PFNGLENABLEINVPROC glad_glEnableiNV; +#define glEnableiNV glad_glEnableiNV +GLAD_API_CALL PFNGLENABLEIOESPROC glad_glEnableiOES; +#define glEnableiOES glad_glEnableiOES +GLAD_API_CALL PFNGLENDQUERYEXTPROC glad_glEndQueryEXT; +#define glEndQueryEXT glad_glEndQueryEXT +GLAD_API_CALL PFNGLEXTRAPOLATETEX2DQCOMPROC glad_glExtrapolateTex2DQCOM; +#define glExtrapolateTex2DQCOM glad_glExtrapolateTex2DQCOM +GLAD_API_CALL PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC glad_glFramebufferFetchBarrierQCOM; +#define glFramebufferFetchBarrierQCOM glad_glFramebufferFetchBarrierQCOM +GLAD_API_CALL PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC glad_glFramebufferFoveationConfigQCOM; +#define glFramebufferFoveationConfigQCOM glad_glFramebufferFoveationConfigQCOM +GLAD_API_CALL PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC glad_glFramebufferFoveationParametersQCOM; +#define glFramebufferFoveationParametersQCOM glad_glFramebufferFoveationParametersQCOM +GLAD_API_CALL PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC glad_glFramebufferPixelLocalStorageSizeEXT; +#define glFramebufferPixelLocalStorageSizeEXT glad_glFramebufferPixelLocalStorageSizeEXT +GLAD_API_CALL PFNGLFRAMEBUFFERSHADINGRATEEXTPROC glad_glFramebufferShadingRateEXT; +#define glFramebufferShadingRateEXT glad_glFramebufferShadingRateEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC glad_glFramebufferTexture2DDownsampleIMG; +#define glFramebufferTexture2DDownsampleIMG glad_glFramebufferTexture2DDownsampleIMG +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DOESPROC glad_glFramebufferTexture3DOES; +#define glFramebufferTexture3DOES glad_glFramebufferTexture3DOES +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC glad_glFramebufferTextureLayerDownsampleIMG; +#define glFramebufferTextureLayerDownsampleIMG glad_glFramebufferTextureLayerDownsampleIMG +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glad_glFramebufferTextureMultisampleMultiviewOVR; +#define glFramebufferTextureMultisampleMultiviewOVR glad_glFramebufferTextureMultisampleMultiviewOVR +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREOESPROC glad_glFramebufferTextureOES; +#define glFramebufferTextureOES glad_glFramebufferTextureOES +GLAD_API_CALL PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT; +#define glGenProgramPipelinesEXT glad_glGenProgramPipelinesEXT +GLAD_API_CALL PFNGLGENQUERIESEXTPROC glad_glGenQueriesEXT; +#define glGenQueriesEXT glad_glGenQueriesEXT +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; +#define glGetDebugMessageLogKHR glad_glGetDebugMessageLogKHR +GLAD_API_CALL PFNGLGETFLOATI_VNVPROC glad_glGetFloati_vNV; +#define glGetFloati_vNV glad_glGetFloati_vNV +GLAD_API_CALL PFNGLGETFLOATI_VOESPROC glad_glGetFloati_vOES; +#define glGetFloati_vOES glad_glGetFloati_vOES +GLAD_API_CALL PFNGLGETFRAGDATAINDEXEXTPROC glad_glGetFragDataIndexEXT; +#define glGetFragDataIndexEXT glad_glGetFragDataIndexEXT +GLAD_API_CALL PFNGLGETFRAGMENTSHADINGRATESEXTPROC glad_glGetFragmentShadingRatesEXT; +#define glGetFragmentShadingRatesEXT glad_glGetFragmentShadingRatesEXT +GLAD_API_CALL PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC glad_glGetFramebufferPixelLocalStorageSizeEXT; +#define glGetFramebufferPixelLocalStorageSizeEXT glad_glGetFramebufferPixelLocalStorageSizeEXT +GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR; +#define glGetGraphicsResetStatusKHR glad_glGetGraphicsResetStatusKHR +GLAD_API_CALL PFNGLGETINTEGER64VEXTPROC glad_glGetInteger64vEXT; +#define glGetInteger64vEXT glad_glGetInteger64vEXT +GLAD_API_CALL PFNGLGETINTEGERI_VEXTPROC glad_glGetIntegeri_vEXT; +#define glGetIntegeri_vEXT glad_glGetIntegeri_vEXT +GLAD_API_CALL PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; +#define glGetObjectLabelKHR glad_glGetObjectLabelKHR +GLAD_API_CALL PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; +#define glGetObjectPtrLabelKHR glad_glGetObjectPtrLabelKHR +GLAD_API_CALL PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; +#define glGetPointervKHR glad_glGetPointervKHR +GLAD_API_CALL PFNGLGETPROGRAMBINARYOESPROC glad_glGetProgramBinaryOES; +#define glGetProgramBinaryOES glad_glGetProgramBinaryOES +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT; +#define glGetProgramPipelineInfoLogEXT glad_glGetProgramPipelineInfoLogEXT +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT; +#define glGetProgramPipelineivEXT glad_glGetProgramPipelineivEXT +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC glad_glGetProgramResourceLocationIndexEXT; +#define glGetProgramResourceLocationIndexEXT glad_glGetProgramResourceLocationIndexEXT +GLAD_API_CALL PFNGLGETQUERYOBJECTIVEXTPROC glad_glGetQueryObjectivEXT; +#define glGetQueryObjectivEXT glad_glGetQueryObjectivEXT +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVEXTPROC glad_glGetQueryObjectuivEXT; +#define glGetQueryObjectuivEXT glad_glGetQueryObjectuivEXT +GLAD_API_CALL PFNGLGETQUERYIVEXTPROC glad_glGetQueryivEXT; +#define glGetQueryivEXT glad_glGetQueryivEXT +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVEXTPROC glad_glGetSamplerParameterIivEXT; +#define glGetSamplerParameterIivEXT glad_glGetSamplerParameterIivEXT +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVOESPROC glad_glGetSamplerParameterIivOES; +#define glGetSamplerParameterIivOES glad_glGetSamplerParameterIivOES +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVEXTPROC glad_glGetSamplerParameterIuivEXT; +#define glGetSamplerParameterIuivEXT glad_glGetSamplerParameterIuivEXT +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVOESPROC glad_glGetSamplerParameterIuivOES; +#define glGetSamplerParameterIuivOES glad_glGetSamplerParameterIuivOES +GLAD_API_CALL PFNGLGETTEXPARAMETERIIVOESPROC glad_glGetTexParameterIivOES; +#define glGetTexParameterIivOES glad_glGetTexParameterIivOES +GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVOESPROC glad_glGetTexParameterIuivOES; +#define glGetTexParameterIuivOES glad_glGetTexParameterIuivOES +GLAD_API_CALL PFNGLGETTEXTUREHANDLEIMGPROC glad_glGetTextureHandleIMG; +#define glGetTextureHandleIMG glad_glGetTextureHandleIMG +GLAD_API_CALL PFNGLGETTEXTURESAMPLERHANDLEIMGPROC glad_glGetTextureSamplerHandleIMG; +#define glGetTextureSamplerHandleIMG glad_glGetTextureSamplerHandleIMG +GLAD_API_CALL PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC glad_glGetTranslatedShaderSourceANGLE; +#define glGetTranslatedShaderSourceANGLE glad_glGetTranslatedShaderSourceANGLE +GLAD_API_CALL PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR; +#define glGetnUniformfvKHR glad_glGetnUniformfvKHR +GLAD_API_CALL PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR; +#define glGetnUniformivKHR glad_glGetnUniformivKHR +GLAD_API_CALL PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR; +#define glGetnUniformuivKHR glad_glGetnUniformuivKHR +GLAD_API_CALL PFNGLISENABLEDIEXTPROC glad_glIsEnablediEXT; +#define glIsEnablediEXT glad_glIsEnablediEXT +GLAD_API_CALL PFNGLISENABLEDINVPROC glad_glIsEnablediNV; +#define glIsEnablediNV glad_glIsEnablediNV +GLAD_API_CALL PFNGLISENABLEDIOESPROC glad_glIsEnablediOES; +#define glIsEnablediOES glad_glIsEnablediOES +GLAD_API_CALL PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT; +#define glIsProgramPipelineEXT glad_glIsProgramPipelineEXT +GLAD_API_CALL PFNGLISQUERYEXTPROC glad_glIsQueryEXT; +#define glIsQueryEXT glad_glIsQueryEXT +GLAD_API_CALL PFNGLMAXACTIVESHADERCORESARMPROC glad_glMaxActiveShaderCoresARM; +#define glMaxActiveShaderCoresARM glad_glMaxActiveShaderCoresARM +GLAD_API_CALL PFNGLMINSAMPLESHADINGOESPROC glad_glMinSampleShadingOES; +#define glMinSampleShadingOES glad_glMinSampleShadingOES +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC glad_glMultiDrawArraysIndirectEXT; +#define glMultiDrawArraysIndirectEXT glad_glMultiDrawArraysIndirectEXT +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC glad_glMultiDrawElementsBaseVertexEXT; +#define glMultiDrawElementsBaseVertexEXT glad_glMultiDrawElementsBaseVertexEXT +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC glad_glMultiDrawElementsIndirectEXT; +#define glMultiDrawElementsIndirectEXT glad_glMultiDrawElementsIndirectEXT +GLAD_API_CALL PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; +#define glObjectLabelKHR glad_glObjectLabelKHR +GLAD_API_CALL PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; +#define glObjectPtrLabelKHR glad_glObjectPtrLabelKHR +GLAD_API_CALL PFNGLPATCHPARAMETERIEXTPROC glad_glPatchParameteriEXT; +#define glPatchParameteriEXT glad_glPatchParameteriEXT +GLAD_API_CALL PFNGLPATCHPARAMETERIOESPROC glad_glPatchParameteriOES; +#define glPatchParameteriOES glad_glPatchParameteriOES +GLAD_API_CALL PFNGLPOLYGONMODENVPROC glad_glPolygonModeNV; +#define glPolygonModeNV glad_glPolygonModeNV +GLAD_API_CALL PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; +#define glPopDebugGroupKHR glad_glPopDebugGroupKHR +GLAD_API_CALL PFNGLPRIMITIVEBOUNDINGBOXPROC glad_glPrimitiveBoundingBox; +#define glPrimitiveBoundingBox glad_glPrimitiveBoundingBox +GLAD_API_CALL PFNGLPRIMITIVEBOUNDINGBOXEXTPROC glad_glPrimitiveBoundingBoxEXT; +#define glPrimitiveBoundingBoxEXT glad_glPrimitiveBoundingBoxEXT +GLAD_API_CALL PFNGLPRIMITIVEBOUNDINGBOXOESPROC glad_glPrimitiveBoundingBoxOES; +#define glPrimitiveBoundingBoxOES glad_glPrimitiveBoundingBoxOES +GLAD_API_CALL PFNGLPROGRAMBINARYOESPROC glad_glProgramBinaryOES; +#define glProgramBinaryOES glad_glProgramBinaryOES +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC glad_glProgramUniformHandleui64IMG; +#define glProgramUniformHandleui64IMG glad_glProgramUniformHandleui64IMG +GLAD_API_CALL PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC glad_glProgramUniformHandleui64vIMG; +#define glProgramUniformHandleui64vIMG glad_glProgramUniformHandleui64vIMG +GLAD_API_CALL PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; +#define glPushDebugGroupKHR glad_glPushDebugGroupKHR +GLAD_API_CALL PFNGLQUERYCOUNTEREXTPROC glad_glQueryCounterEXT; +#define glQueryCounterEXT glad_glQueryCounterEXT +GLAD_API_CALL PFNGLREADBUFFERINDEXEDEXTPROC glad_glReadBufferIndexedEXT; +#define glReadBufferIndexedEXT glad_glReadBufferIndexedEXT +GLAD_API_CALL PFNGLREADBUFFERNVPROC glad_glReadBufferNV; +#define glReadBufferNV glad_glReadBufferNV +GLAD_API_CALL PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR; +#define glReadnPixelsKHR glad_glReadnPixelsKHR +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC glad_glRenderbufferStorageMultisampleANGLE; +#define glRenderbufferStorageMultisampleANGLE glad_glRenderbufferStorageMultisampleANGLE +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC glad_glRenderbufferStorageMultisampleNV; +#define glRenderbufferStorageMultisampleNV glad_glRenderbufferStorageMultisampleNV +GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVEXTPROC glad_glSamplerParameterIivEXT; +#define glSamplerParameterIivEXT glad_glSamplerParameterIivEXT +GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVOESPROC glad_glSamplerParameterIivOES; +#define glSamplerParameterIivOES glad_glSamplerParameterIivOES +GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVEXTPROC glad_glSamplerParameterIuivEXT; +#define glSamplerParameterIuivEXT glad_glSamplerParameterIuivEXT +GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVOESPROC glad_glSamplerParameterIuivOES; +#define glSamplerParameterIuivOES glad_glSamplerParameterIuivOES +GLAD_API_CALL PFNGLSCISSORARRAYVNVPROC glad_glScissorArrayvNV; +#define glScissorArrayvNV glad_glScissorArrayvNV +GLAD_API_CALL PFNGLSCISSORARRAYVOESPROC glad_glScissorArrayvOES; +#define glScissorArrayvOES glad_glScissorArrayvOES +GLAD_API_CALL PFNGLSCISSORINDEXEDNVPROC glad_glScissorIndexedNV; +#define glScissorIndexedNV glad_glScissorIndexedNV +GLAD_API_CALL PFNGLSCISSORINDEXEDOESPROC glad_glScissorIndexedOES; +#define glScissorIndexedOES glad_glScissorIndexedOES +GLAD_API_CALL PFNGLSCISSORINDEXEDVNVPROC glad_glScissorIndexedvNV; +#define glScissorIndexedvNV glad_glScissorIndexedvNV +GLAD_API_CALL PFNGLSCISSORINDEXEDVOESPROC glad_glScissorIndexedvOES; +#define glScissorIndexedvOES glad_glScissorIndexedvOES +GLAD_API_CALL PFNGLSHADINGRATECOMBINEROPSEXTPROC glad_glShadingRateCombinerOpsEXT; +#define glShadingRateCombinerOpsEXT glad_glShadingRateCombinerOpsEXT +GLAD_API_CALL PFNGLSHADINGRATEEXTPROC glad_glShadingRateEXT; +#define glShadingRateEXT glad_glShadingRateEXT +GLAD_API_CALL PFNGLSHADINGRATEQCOMPROC glad_glShadingRateQCOM; +#define glShadingRateQCOM glad_glShadingRateQCOM +GLAD_API_CALL PFNGLTEXBUFFEROESPROC glad_glTexBufferOES; +#define glTexBufferOES glad_glTexBufferOES +GLAD_API_CALL PFNGLTEXBUFFERRANGEEXTPROC glad_glTexBufferRangeEXT; +#define glTexBufferRangeEXT glad_glTexBufferRangeEXT +GLAD_API_CALL PFNGLTEXBUFFERRANGEOESPROC glad_glTexBufferRangeOES; +#define glTexBufferRangeOES glad_glTexBufferRangeOES +GLAD_API_CALL PFNGLTEXESTIMATEMOTIONQCOMPROC glad_glTexEstimateMotionQCOM; +#define glTexEstimateMotionQCOM glad_glTexEstimateMotionQCOM +GLAD_API_CALL PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC glad_glTexEstimateMotionRegionsQCOM; +#define glTexEstimateMotionRegionsQCOM glad_glTexEstimateMotionRegionsQCOM +GLAD_API_CALL PFNGLTEXIMAGE3DOESPROC glad_glTexImage3DOES; +#define glTexImage3DOES glad_glTexImage3DOES +GLAD_API_CALL PFNGLTEXPAGECOMMITMENTEXTPROC glad_glTexPageCommitmentEXT; +#define glTexPageCommitmentEXT glad_glTexPageCommitmentEXT +GLAD_API_CALL PFNGLTEXPARAMETERIIVOESPROC glad_glTexParameterIivOES; +#define glTexParameterIivOES glad_glTexParameterIivOES +GLAD_API_CALL PFNGLTEXPARAMETERIUIVOESPROC glad_glTexParameterIuivOES; +#define glTexParameterIuivOES glad_glTexParameterIuivOES +GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC glad_glTexStorage3DMultisampleOES; +#define glTexStorage3DMultisampleOES glad_glTexStorage3DMultisampleOES +GLAD_API_CALL PFNGLTEXSTORAGEATTRIBS2DEXTPROC glad_glTexStorageAttribs2DEXT; +#define glTexStorageAttribs2DEXT glad_glTexStorageAttribs2DEXT +GLAD_API_CALL PFNGLTEXSTORAGEATTRIBS3DEXTPROC glad_glTexStorageAttribs3DEXT; +#define glTexStorageAttribs3DEXT glad_glTexStorageAttribs3DEXT +GLAD_API_CALL PFNGLTEXSUBIMAGE3DOESPROC glad_glTexSubImage3DOES; +#define glTexSubImage3DOES glad_glTexSubImage3DOES +GLAD_API_CALL PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC glad_glTextureFoveationParametersQCOM; +#define glTextureFoveationParametersQCOM glad_glTextureFoveationParametersQCOM +GLAD_API_CALL PFNGLTEXTUREVIEWEXTPROC glad_glTextureViewEXT; +#define glTextureViewEXT glad_glTextureViewEXT +GLAD_API_CALL PFNGLTEXTUREVIEWOESPROC glad_glTextureViewOES; +#define glTextureViewOES glad_glTextureViewOES +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64IMGPROC glad_glUniformHandleui64IMG; +#define glUniformHandleui64IMG glad_glUniformHandleui64IMG +GLAD_API_CALL PFNGLUNIFORMHANDLEUI64VIMGPROC glad_glUniformHandleui64vIMG; +#define glUniformHandleui64vIMG glad_glUniformHandleui64vIMG +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVNVPROC glad_glUniformMatrix2x3fvNV; +#define glUniformMatrix2x3fvNV glad_glUniformMatrix2x3fvNV +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVNVPROC glad_glUniformMatrix2x4fvNV; +#define glUniformMatrix2x4fvNV glad_glUniformMatrix2x4fvNV +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVNVPROC glad_glUniformMatrix3x2fvNV; +#define glUniformMatrix3x2fvNV glad_glUniformMatrix3x2fvNV +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVNVPROC glad_glUniformMatrix3x4fvNV; +#define glUniformMatrix3x4fvNV glad_glUniformMatrix3x4fvNV +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVNVPROC glad_glUniformMatrix4x2fvNV; +#define glUniformMatrix4x2fvNV glad_glUniformMatrix4x2fvNV +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVNVPROC glad_glUniformMatrix4x3fvNV; +#define glUniformMatrix4x3fvNV glad_glUniformMatrix4x3fvNV +GLAD_API_CALL PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT; +#define glUseProgramStagesEXT glad_glUseProgramStagesEXT +GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT; +#define glValidateProgramPipelineEXT glad_glValidateProgramPipelineEXT +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORANGLEPROC glad_glVertexAttribDivisorANGLE; +#define glVertexAttribDivisorANGLE glad_glVertexAttribDivisorANGLE +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISOREXTPROC glad_glVertexAttribDivisorEXT; +#define glVertexAttribDivisorEXT glad_glVertexAttribDivisorEXT +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORNVPROC glad_glVertexAttribDivisorNV; +#define glVertexAttribDivisorNV glad_glVertexAttribDivisorNV +GLAD_API_CALL PFNGLVIEWPORTARRAYVNVPROC glad_glViewportArrayvNV; +#define glViewportArrayvNV glad_glViewportArrayvNV +GLAD_API_CALL PFNGLVIEWPORTARRAYVOESPROC glad_glViewportArrayvOES; +#define glViewportArrayvOES glad_glViewportArrayvOES +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFNVPROC glad_glViewportIndexedfNV; +#define glViewportIndexedfNV glad_glViewportIndexedfNV +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFOESPROC glad_glViewportIndexedfOES; +#define glViewportIndexedfOES glad_glViewportIndexedfOES +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVNVPROC glad_glViewportIndexedfvNV; +#define glViewportIndexedfvNV glad_glViewportIndexedfvNV +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVOESPROC glad_glViewportIndexedfvOES; +#define glViewportIndexedfvOES glad_glViewportIndexedfvOES + + + + + +GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGL( GLADloadfunc load); + +GLAD_API_CALL int gladLoadGLES1UserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLES1( GLADloadfunc load); + +GLAD_API_CALL int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLES2( GLADloadfunc load); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/sdk/libraries/x64/glew32s.lib b/sdk/libraries/x64/glew32s.lib deleted file mode 100644 index 1130f846950e35f3b0112489137f91db5988b168..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2845622 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ི(*o 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�|?vQcCaqas5N_ti>K+jc< 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ƜEB(Ey4GB5$iJWH*fX~lWh8h4{_=}HXE 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�)GLo#cT0K{1v{7Ei_-@ssct{A4`&H17X+2Hp?P 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

          %p=r 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ξA<`i;adbvdE!!52w;&8)Snx!C(!ooYjf=*lP@ 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

          OQ&4q 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

          {Cqx{SW_Fgda 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

          2X~wIXYa9Wc6p^F-<@ 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¬mOO;Yzb>epO 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 JtlUf>g_KZ_R<4-9!Ug_+a%mR&{ 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

          1x|ec{zV$Kvmex^@#kcAy$Ie@y(G%$B)R%rm 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

          IPHeh`}y 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˜n`J8?r((M_dzQqY5GfqhE)8xU1BhLVKi& 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

        2. EzMNxyQ2rFFy0(YOeYARZ2cMhpRRg{%JrQE1} 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, _ps, _gs, _hs, _ds); - if (HW.SeparateShaderObjectsSupported || !dest.pp->pp) + if (GLAD_GL_ARB_separate_shader_objects || !dest.pp->pp) #endif { dest.ps = RImplementation.Resources->_CreatePS(_ps); diff --git a/src/Layers/xrRender/Blender_Recorder_R2.cpp b/src/Layers/xrRender/Blender_Recorder_R2.cpp index ede1699f9df..076d8810327 100644 --- a/src/Layers/xrRender/Blender_Recorder_R2.cpp +++ b/src/Layers/xrRender/Blender_Recorder_R2.cpp @@ -25,7 +25,7 @@ void CBlender_Compile::r_Pass(LPCSTR _vs, LPCSTR _ps, bool bFog, BOOL bZtest, BO // Create shaders #if defined(USE_OGL) dest.pp = RImplementation.Resources->_CreatePP(_vs, _ps, "null", "null", "null"); - if (HW.SeparateShaderObjectsSupported || !dest.pp->pp) + if (GLAD_GL_ARB_separate_shader_objects || !dest.pp->pp) #endif { dest.ps = RImplementation.Resources->_CreatePS(_ps); diff --git a/src/Layers/xrRender/R_Backend.h b/src/Layers/xrRender/R_Backend.h index 8ea0a9589b9..b75f7a808ec 100644 --- a/src/Layers/xrRender/R_Backend.h +++ b/src/Layers/xrRender/R_Backend.h @@ -456,7 +456,7 @@ class ECORE_API CBackend if (!C) return; #ifdef USE_OGL - if (!HW.SeparateShaderObjectsSupported) + if (!GLAD_GL_ARB_separate_shader_objects) VERIFY(C->pp.program == pp); #endif constants.set(C, std::forward(args)...); @@ -468,7 +468,7 @@ class ECORE_API CBackend if (!C) return; #ifdef USE_OGL - if (!HW.SeparateShaderObjectsSupported) + if (!GLAD_GL_ARB_separate_shader_objects) VERIFY(C->pp.program == pp); #endif constants.seta(C, std::forward(args)...); diff --git a/src/Layers/xrRender/SH_Atomic.cpp b/src/Layers/xrRender/SH_Atomic.cpp index d70792211b1..bbb0c1cda42 100644 --- a/src/Layers/xrRender/SH_Atomic.cpp +++ b/src/Layers/xrRender/SH_Atomic.cpp @@ -47,7 +47,7 @@ SVS::~SVS() #if defined(USE_DX11) _RELEASE(sh); #elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -63,7 +63,7 @@ SPS::~SPS() #if defined(USE_DX11) _RELEASE(sh); #elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -81,7 +81,7 @@ SGS::~SGS() # if defined(USE_DX11) _RELEASE(sh); # elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -97,7 +97,7 @@ SHS::~SHS() # if defined(USE_DX11) _RELEASE(sh); # elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -113,7 +113,7 @@ SDS::~SDS() # if defined(USE_DX11) _RELEASE(sh); # elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -127,7 +127,7 @@ SCS::~SCS() # if defined(USE_DX11) _RELEASE(sh); # elif defined(USE_OGL) - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgram(sh)); else CHK_GL(glDeleteShader(sh)); @@ -141,7 +141,7 @@ SCS::~SCS() #if defined(USE_OGL) SPP::~SPP() { - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glDeleteProgramPipelines(1, &pp)); else CHK_GL(glDeleteProgram(pp)); diff --git a/src/Layers/xrRender/ShaderResourceTraits.h b/src/Layers/xrRender/ShaderResourceTraits.h index c258a6bd67d..f9056c8c14e 100644 --- a/src/Layers/xrRender/ShaderResourceTraits.h +++ b/src/Layers/xrRender/ShaderResourceTraits.h @@ -56,15 +56,15 @@ inline std::pair GLCompileShader(pcstr* buffer, size_t size, pcstr return { 's', 0 }; // 's' means "shader", 0 means error } - if (!HW.SeparateShaderObjectsSupported) + if (!GLAD_GL_ARB_separate_shader_objects) return { 's', shader }; const GLuint program = glCreateProgram(); R_ASSERT(program); - if (GLEW_VERSION_4_3) + if (glObjectLabel) CHK_GL(glObjectLabel(GL_PROGRAM, program, -1, name)); CHK_GL(glProgramParameteri(program, GL_PROGRAM_SEPARABLE, (GLint)GL_TRUE)); - if (HW.ShaderBinarySupported) + if (GLAD_GL_ARB_get_program_binary) CHK_GL(glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, (GLint)GL_TRUE)); CHK_GL(glAttachShader(program, shader)); @@ -93,7 +93,7 @@ inline std::pair GLUseBinary(pcstr* buffer, size_t size, const GLe const GLuint program = glCreateProgram(); R_ASSERT(program); - if (GLEW_VERSION_4_3) + if (glObjectLabel) CHK_GL(glObjectLabel(GL_PROGRAM, program, -1, name)); CHK_GL(glProgramParameteri(program, GL_PROGRAM_SEPARABLE, (GLint)GL_TRUE)); @@ -118,7 +118,7 @@ static GLuint GLLinkMonolithicProgram(pcstr name, GLuint ps, GLuint vs, GLuint g { const GLuint program = glCreateProgram(); R_ASSERT(program); - if (GLEW_VERSION_4_3) + if (glObjectLabel) CHK_GL(glObjectLabel(GL_PROGRAM, program, -1, name)); // XXX: support caching for monolithic programs //if (HW.ShaderBinarySupported) diff --git a/src/Layers/xrRenderGL/Blender_Recorder_GL.cpp b/src/Layers/xrRenderGL/Blender_Recorder_GL.cpp index 22b596610e5..b649694a300 100644 --- a/src/Layers/xrRenderGL/Blender_Recorder_GL.cpp +++ b/src/Layers/xrRenderGL/Blender_Recorder_GL.cpp @@ -66,7 +66,7 @@ void CBlender_Compile::r_Pass(LPCSTR _vs, LPCSTR _gs, LPCSTR _ps, bool bFog, BOO // Create shaders #if defined(USE_OGL) dest.pp = RImplementation.Resources->_CreatePP(_vs, _ps, _gs, "null", "null"); - if (HW.SeparateShaderObjectsSupported || !dest.pp->pp) + if (GLAD_GL_ARB_separate_shader_objects || !dest.pp->pp) #endif { dest.ps = RImplementation.Resources->_CreatePS(_ps); diff --git a/src/Layers/xrRenderGL/glBufferUtils.cpp b/src/Layers/xrRenderGL/glBufferUtils.cpp index 3c4d4a0a333..778cc719036 100644 --- a/src/Layers/xrRenderGL/glBufferUtils.cpp +++ b/src/Layers/xrRenderGL/glBufferUtils.cpp @@ -169,7 +169,7 @@ void ConvertVertexDeclaration(const VertexElement* dxdecl, SDeclaration* decl) [](GLuint location, GLint size, GLenum type, GLboolean normalized, GLuint offset, GLuint stream) { CHK_GL(glEnableVertexAttribArray(location)); - if (GLEW_ARB_vertex_attrib_binding) + if (GLAD_GL_ARB_vertex_attrib_binding) { CHK_GL(glVertexAttribFormat(location, size, type, normalized, offset)); CHK_GL(glVertexAttribBinding(location, stream)); diff --git a/src/Layers/xrRenderGL/glHW.cpp b/src/Layers/xrRenderGL/glHW.cpp index b085bbe49fe..e108765b0df 100644 --- a/src/Layers/xrRenderGL/glHW.cpp +++ b/src/Layers/xrRenderGL/glHW.cpp @@ -121,22 +121,10 @@ void CHW::CreateDevice(SDL_Window* hWnd) return; } - // Initialize OpenGL Extension Wrangler -#ifdef XR_PLATFORM_APPLE - // This is essential for complete OpenGL 4.1 load on mac - glewExperimental = GL_TRUE; -#endif - GLenum err = glewInit(); - if (GLEW_OK != err) - { - Log("! Could not initialize glew:", (pcstr)glewGetErrorString(err)); - return; - } - UpdateVSync(); #ifdef DEBUG - if (GLEW_KHR_debug) // NOTE: this extension is only available starting with OpenGL 4.3 + if (glDebugMessageCallback) { CHK_GL(glEnable(GL_DEBUG_OUTPUT)); CHK_GL(glDebugMessageCallback((GLDEBUGPROC)OnDebugCallback, nullptr)); @@ -147,9 +135,6 @@ void CHW::CreateDevice(SDL_Window* hWnd) glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &iMaxVTFUnits); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &iMaxCTIUnits); - glGetIntegerv(GL_MAJOR_VERSION, &(std::get<0>(OpenGLVersion))); - glGetIntegerv(GL_MINOR_VERSION, &(std::get<1>(OpenGLVersion))); - AdapterName = reinterpret_cast(glGetString(GL_RENDERER)); OpenGLVersionString = reinterpret_cast(glGetString(GL_VERSION)); ShadingVersion = reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION)); @@ -159,8 +144,6 @@ void CHW::CreateDevice(SDL_Window* hWnd) Msg("* GPU OpenGL shading language version: %s", ShadingVersion); Msg("* GPU OpenGL VTF units: [%d] CTI units: [%d]", iMaxVTFUnits, iMaxCTIUnits); - SeparateShaderObjectsSupported = GLEW_ARB_separate_shader_objects; - ShaderBinarySupported = GLEW_ARB_get_program_binary; ComputeShadersSupported = false; // XXX: Implement compute shaders support Caps.fTarget = D3DFMT_A8R8G8B8; @@ -295,12 +278,12 @@ bool CHW::ThisInstanceIsGlobal() const void CHW::BeginPixEvent(pcstr name) const { - if (GLEW_KHR_debug) + if (glPushDebugGroup) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, name); } void CHW::EndPixEvent() const { - if (GLEW_KHR_debug) + if (glPushDebugGroup) glPopDebugGroup(); } diff --git a/src/Layers/xrRenderGL/glHW.h b/src/Layers/xrRenderGL/glHW.h index c62e8cf98d3..0f4df1d8b42 100644 --- a/src/Layers/xrRenderGL/glHW.h +++ b/src/Layers/xrRenderGL/glHW.h @@ -60,9 +60,6 @@ class CHW pcstr AdapterName; pcstr OpenGLVersionString; pcstr ShadingVersion; - std::pair OpenGLVersion; - bool SeparateShaderObjectsSupported; - bool ShaderBinarySupported; bool ComputeShadersSupported; }; diff --git a/src/Layers/xrRenderGL/glHWCaps.cpp b/src/Layers/xrRenderGL/glHWCaps.cpp index 78f06c693bd..2d07609de4f 100644 --- a/src/Layers/xrRenderGL/glHWCaps.cpp +++ b/src/Layers/xrRenderGL/glHWCaps.cpp @@ -26,9 +26,7 @@ void CHWCaps::Update() geometry.dwRegisters = cnt; geometry.dwInstructions = 256; geometry.dwClipPlanes = _min(6, 15); - geometry.bVTF = - (HW.OpenGLVersion >= std::make_pair(3, 0) || GLEW_ARB_texture_float) - && !strstr(Core.Params, "-novtf"); + geometry.bVTF = (GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_texture_float) && !strstr(Core.Params, "-novtf"); // ***************** PIXEL processing raster_major = 4; diff --git a/src/Layers/xrRenderGL/glR_Backend_Runtime.h b/src/Layers/xrRenderGL/glR_Backend_Runtime.h index b7f1ccaf2eb..ffd07300e2a 100644 --- a/src/Layers/xrRenderGL/glR_Backend_Runtime.h +++ b/src/Layers/xrRenderGL/glR_Backend_Runtime.h @@ -219,7 +219,7 @@ ICF void CBackend::set_PP(GLuint _pp, pcstr _n) { #ifdef RBackend_PGO string_path name; - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) glGetObjectLabel(GL_PROGRAM_PIPELINE, _pp, sizeof(name), nullptr, name) else glGetObjectLabel(GL_PROGRAM, _pp, sizeof(name), nullptr, name) @@ -227,7 +227,7 @@ ICF void CBackend::set_PP(GLuint _pp, pcstr _n) PGO(Msg("PGO:PPshader:%d,%s", _pp, _n ? _n : name)); stat.pp++; pp = _pp; - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glBindProgramPipeline(pp)); else CHK_GL(glUseProgram(pp)); @@ -248,7 +248,7 @@ ICF void CBackend::set_Vertices(GLuint _vb, u32 _vb_stride) vb = _vb; vb_stride = _vb_stride; - if (GLEW_ARB_vertex_attrib_binding) + if (GLAD_GL_ARB_vertex_attrib_binding) { CHK_GL(glBindVertexBuffer(0, vb, 0, vb_stride)); } diff --git a/src/Layers/xrRenderGL/glResourceManager_Resources.cpp b/src/Layers/xrRenderGL/glResourceManager_Resources.cpp index 80b680dd336..3dd9049f902 100644 --- a/src/Layers/xrRenderGL/glResourceManager_Resources.cpp +++ b/src/Layers/xrRenderGL/glResourceManager_Resources.cpp @@ -105,7 +105,7 @@ bool CResourceManager::_LinkPP(SPass& pass) if (pp.pp) return true; - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) pp.pp = GLGeneratePipeline(pp.cName.c_str(), pass.ps->sh, pass.vs->sh, pass.gs->sh); else { diff --git a/src/Layers/xrRenderGL/glState.cpp b/src/Layers/xrRenderGL/glState.cpp index e8237003262..f4233676b93 100644 --- a/src/Layers/xrRenderGL/glState.cpp +++ b/src/Layers/xrRenderGL/glState.cpp @@ -256,8 +256,8 @@ void glState::UpdateSamplerState(u32 stage, u32 name, u32 value) CHK_GL(glSamplerParameteri(m_samplerArray[stage], GL_TEXTURE_MAX_LEVEL, value)); break; case D3DSAMP_MAXANISOTROPY: /* DWORD maximum anisotropy */ - if (GLEW_EXT_texture_filter_anisotropic) - CHK_GL(glSamplerParameteri(m_samplerArray[stage], GL_TEXTURE_MAX_ANISOTROPY_EXT, value)); + if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) + CHK_GL(glSamplerParameteri(m_samplerArray[stage], GL_TEXTURE_MAX_ANISOTROPY, value)); break; case XRDX11SAMP_COMPARISONFILTER: CHK_GL(glSamplerParameteri(m_samplerArray[stage], GL_TEXTURE_COMPARE_MODE, value ? (GLint) diff --git a/src/Layers/xrRenderGL/glr_constants.cpp b/src/Layers/xrRenderGL/glr_constants.cpp index 5f4676be4dd..1503a7dc667 100644 --- a/src/Layers/xrRenderGL/glr_constants.cpp +++ b/src/Layers/xrRenderGL/glr_constants.cpp @@ -7,7 +7,7 @@ static class cl_sampler : public R_constant_setup { void setup(CBackend& cmd_list, R_constant* C) override { - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform1i(C->samp.program, C->samp.location, C->samp.index)); else { diff --git a/src/Layers/xrRenderGL/glr_constants_cache.h b/src/Layers/xrRenderGL/glr_constants_cache.h index 80f4b078b2b..d8f2bd3f571 100644 --- a/src/Layers/xrRenderGL/glr_constants_cache.h +++ b/src/Layers/xrRenderGL/glr_constants_cache.h @@ -15,7 +15,7 @@ class ECORE_API R_constants case RC_2x4: it[0].set(A._11, A._21, A._31, A._41); it[1].set(A._12, A._22, A._32, A._42); - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniformMatrix4x2fv(L.program, L.location, 1, GL_TRUE, (float*)&it)); else CHK_GL(glUniformMatrix4x2fv(L.location, 1, GL_TRUE, (float*)&it)); @@ -25,7 +25,7 @@ class ECORE_API R_constants it[0].set(A._11, A._21, A._31, A._41); it[1].set(A._12, A._22, A._32, A._42); it[2].set(A._13, A._23, A._33, A._43); - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniformMatrix4x3fv(L.program, L.location, 1, GL_TRUE, (float*)&it)); else CHK_GL(glUniformMatrix4x3fv(L.location, 1, GL_TRUE, (float*)&it)); @@ -36,7 +36,7 @@ class ECORE_API R_constants it[1].set(A._12, A._22, A._32, A._42); it[2].set(A._13, A._23, A._33, A._43); it[3].set(A._14, A._24, A._34, A._44); - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniformMatrix4fv(L.program, L.location, 1, GL_TRUE, (float*)&it)); else CHK_GL(glUniformMatrix4fv(L.location, 1, GL_TRUE, (float*)&it)); @@ -57,21 +57,21 @@ class ECORE_API R_constants switch (L.cls) { case RC_1x2: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform2fv(L.program, L.location, 1, (float*)&A)); else CHK_GL(glUniform2fv(L.location, 1, (float*)&A)); break; case RC_1x3: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform3fv(L.program, L.location, 1, (float*)&A)); else CHK_GL(glUniform3fv(L.location, 1, (float*)&A)); break; case RC_1x4: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform4fv(L.program, L.location, 1, (float*)&A)); else CHK_GL(glUniform4fv(L.location, 1, (float*)&A)); @@ -92,21 +92,21 @@ class ECORE_API R_constants switch (L.cls) { case RC_1x2: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform2f(L.program, L.location, x, y)); else CHK_GL(glUniform2f(L.location, x, y)); break; case RC_1x3: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform3f(L.program, L.location, x, y, z)); else CHK_GL(glUniform3f(L.location, x, y, z)); break; case RC_1x4: - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform4f(L.program, L.location, x, y, z, w)); else CHK_GL(glUniform4f(L.location, x, y, z, w)); @@ -126,7 +126,7 @@ class ECORE_API R_constants { VERIFY(RC_float == C->type); VERIFY(RC_1x1 == L.cls); - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform1f(L.program, L.location, A)); else CHK_GL(glUniform1f(L.location, A)); @@ -136,7 +136,7 @@ class ECORE_API R_constants { VERIFY(RC_int == C->type); VERIFY(RC_1x1 == L.cls); - if (HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_separate_shader_objects) CHK_GL(glProgramUniform1i(L.program, L.location, A)); else CHK_GL(glUniform1i(L.location, A)); diff --git a/src/Layers/xrRenderPC_GL/CMakeLists.txt b/src/Layers/xrRenderPC_GL/CMakeLists.txt index a61c0f09d5b..8793cb3be37 100644 --- a/src/Layers/xrRenderPC_GL/CMakeLists.txt +++ b/src/Layers/xrRenderPC_GL/CMakeLists.txt @@ -383,6 +383,9 @@ target_sources(xrRender_GL PRIVATE ../../Include/xrRender/UIShader.h ../../Include/xrRender/WallMarkArray.h ../../utils/xrLC_Light/R_light.h + ../../../sdk/include/glad/gl.c + ../../../sdk/include/glad/gl.h + ../../../sdk/include/KHR/khrplatform.h ) target_include_directories(xrRender_GL @@ -392,6 +395,7 @@ target_include_directories(xrRender_GL "${CMAKE_SOURCE_DIR}/src/Layers/xrRender" "${CMAKE_SOURCE_DIR}/src/Include/xrRender" "${CMAKE_SOURCE_DIR}/src/Layers/xrRender_R2" + "${CMAKE_SOURCE_DIR}/sdk/include" "${CMAKE_SOURCE_DIR}/sdk/include/DirectXMesh" "${CMAKE_SOURCE_DIR}/Externals" "${CMAKE_SOURCE_DIR}/Externals/gli" @@ -408,8 +412,6 @@ target_link_libraries(xrRender_GL xrParticles xrScriptEngine xrImGui - OpenGL::GL - GLEW::GLEW ) target_compile_definitions(xrRender_GL @@ -425,7 +427,7 @@ set_target_properties(xrRender_GL PROPERTIES target_precompile_headers(xrRender_GL PRIVATE - stdafx.h + $<$:stdafx.h> ) install(TARGETS xrRender_GL LIBRARY diff --git a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp index 4109596b9f1..3ba5b683490 100644 --- a/src/Layers/xrRenderPC_GL/r2_test_hw.cpp +++ b/src/Layers/xrRenderPC_GL/r2_test_hw.cpp @@ -48,14 +48,16 @@ BOOL xrRender_test_hw() if (!windowTest.successful()) return FALSE; - GLenum err; + int version; { - ZoneScopedN("glewInit()"); - err = glewInit(); + ZoneScopedN("gladLoadGL"); + version = gladLoadGL((GLADloadfunc) SDL_GL_GetProcAddress); } - if (GLEW_OK != err) + if (version == 0) { - Log("~ Could not initialize glew:", (pcstr)glewGetErrorString(err)); + Log("~ Could not initialize GLAD."); + if (auto err = SDL_GetError()) + Log("SDL Error:", err); return FALSE; } diff --git a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp index 80160d6a8d5..31b85d91c4d 100644 --- a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp +++ b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp @@ -503,7 +503,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, u32 fileCrc = 0; string_path filename, full_path{}; strconcat(sizeof(filename), filename, "gl" DELIMITER, name, ".", extension, DELIMITER, sh_name.c_str()); - if (HW.ShaderBinarySupported && HW.SeparateShaderObjectsSupported) + if (GLAD_GL_ARB_get_program_binary && GLAD_GL_ARB_separate_shader_objects) { string_path file; strconcat(sizeof(file), file, "shaders_cache_oxr" DELIMITER, filename); @@ -517,7 +517,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, } GLuint program = 0; - if (HW.ShaderBinarySupported && HW.SeparateShaderObjectsSupported && FS.exist(full_path)) + if (GLAD_GL_ARB_get_program_binary && GLAD_GL_ARB_separate_shader_objects && FS.exist(full_path)) { IReader* file = FS.r_open(full_path); if (file->length() > 8) @@ -564,7 +564,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, // Compile the shader from sources program = create_shader(pTarget, sources.get(), sources.length(), filename, result, nullptr); - if (HW.ShaderBinarySupported && HW.SeparateShaderObjectsSupported && program) + if (GLAD_GL_ARB_get_program_binary && GLAD_GL_ARB_separate_shader_objects && program) { GLint binaryLength{}; GLenum binaryFormat{}; diff --git a/src/Layers/xrRenderPC_GL/stdafx.h b/src/Layers/xrRenderPC_GL/stdafx.h index 9f00421c26e..5b7d5e8c52b 100644 --- a/src/Layers/xrRenderPC_GL/stdafx.h +++ b/src/Layers/xrRenderPC_GL/stdafx.h @@ -14,8 +14,7 @@ #include "xrParticles/psystem.h" -#define GLEW_STATIC -#include +#include "glad/gl.h" #include #include diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj index 2aafb423ec4..40c440ba4bc 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj @@ -25,18 +25,21 @@ - $(SolutionDir)Layers\xrRender_R2;$(xrSdkDir)include\DirectXMesh;$(xrExternals)imgui;$(xrExternals)OpenAutomate\inc;$(xrExternals)gl\include;$(xrExternals)glew\include;$(xrExternals)gli;$(xrExternals)gli\external;$(xrExternals)AGS_SDK;$(xrExternals)glslang\glslang\Public;$(xrExternals)sse2neon\include;%(AdditionalIncludeDirectories) + $(SolutionDir)Layers\xrRender_R2;$(xrSdkDir)include\DirectXMesh;$(xrExternals)imgui;$(xrExternals)OpenAutomate\inc;$(xrExternals)gli;$(xrExternals)gli\external;$(xrExternals)AGS_SDK;$(xrExternals)glslang\glslang\Public;$(xrExternals)sse2neon\include;%(AdditionalIncludeDirectories) _USRDLL;XRRENDER_GL_EXPORTS;USE_OGL;%(PreprocessorDefinitions) /bigobj %(AdditionalOptions) - opengl32.lib;glew32s.lib;glu32.lib;nvapi$(PlatformArchitecture).lib;amd_ags_$(PlatformShortName).lib;%(AdditionalDependencies) + nvapi$(PlatformArchitecture).lib;amd_ags_$(PlatformShortName).lib;%(AdditionalDependencies) $(xrExternals)OpenAutomate\libraries;$(xrExternals)AGS_SDK\ags_lib\lib;%(AdditionalLibraryDirectories) $(xrExternals)nvapi\x86;%(AdditionalLibraryDirectories) $(xrExternals)nvapi\amd64;%(AdditionalLibraryDirectories) + + NotUsing + @@ -217,6 +220,8 @@ + + diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters index 141f1e0f08e..e1822ba1208 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.vcxproj.filters @@ -169,6 +169,12 @@ {24b98c00-6a2d-4e26-bdc2-316324ee4025} + + {00d25eb4-7ecd-4265-b321-908e1d027222} + + + {4e37e39a-262e-4e88-8fcd-d4b403e1ee7e} + @@ -699,6 +705,9 @@ Refactored\Execution & 3D\Gamma + + Refactored\HW\glad + @@ -1163,6 +1172,12 @@ Lights + + Refactored\HW\glad + + + Refactored\HW\KHR + From c420f333de78604bd85b00776e81e2e1cd4e84b0 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 1 Jun 2024 02:03:44 +0500 Subject: [PATCH 456/497] Optimize constructors and explicitly assign shared_str to nullptr --- src/xrCore/Animation/Motion.hpp | 4 +- src/xrEngine/Environment.cpp | 22 +---------- src/xrEngine/Environment.h | 38 +++++++++---------- src/xrEngine/XR_IOConsole.cpp | 12 +----- src/xrEngine/XR_IOConsole.h | 12 +++--- src/xrGame/AI_PhraseDialogManager.cpp | 5 +-- src/xrGame/AI_PhraseDialogManager.h | 1 - src/xrGame/Actor.cpp | 18 ++++----- src/xrGame/Artefact.cpp | 5 --- src/xrGame/Artefact.h | 6 +-- src/xrGame/CustomOutfit.cpp | 4 +- src/xrGame/CustomOutfit.h | 2 +- src/xrGame/GameObject.cpp | 4 +- src/xrGame/GraviZone.cpp | 8 ++-- src/xrGame/GraviZone.h | 3 +- src/xrGame/InfoDocument.cpp | 4 +- src/xrGame/InfoDocument.h | 3 +- src/xrGame/PDA.cpp | 1 - src/xrGame/PHSkeleton.cpp | 2 +- src/xrGame/ShootingObject.cpp | 23 +---------- src/xrGame/ShootingObject.h | 22 +++++------ src/xrGame/WeaponAmmo.cpp | 1 - src/xrGame/game_cl_base.cpp | 2 - .../game_cl_base_weapon_usage_statistic.cpp | 18 +-------- .../game_cl_base_weapon_usage_statistic.h | 16 ++++---- src/xrGame/game_cl_mp.cpp | 4 +- src/xrGame/game_sv_mp.h | 12 +----- src/xrGame/inventory_item.cpp | 3 -- src/xrGame/ui/FactionState.cpp | 6 +-- src/xrGame/ui/FractionState.cpp | 10 +---- src/xrGame/ui/UIInvUpgrade.cpp | 1 - src/xrServerEntities/character_info.cpp | 1 - src/xrServerEntities/character_info_defs.h | 2 +- src/xrServerEntities/specific_character.cpp | 14 +------ src/xrServerEntities/specific_character.h | 16 ++++---- .../xrServer_Objects_ALife_Items.cpp | 17 +++------ .../xrServer_Objects_ALife_Items.h | 4 +- 37 files changed, 99 insertions(+), 227 deletions(-) diff --git a/src/xrCore/Animation/Motion.hpp b/src/xrCore/Animation/Motion.hpp index a77eca18b8b..5747ee7fd8d 100644 --- a/src/xrCore/Animation/Motion.hpp +++ b/src/xrCore/Animation/Motion.hpp @@ -32,13 +32,11 @@ struct st_BoneMotion flWorldOrient = 1 << 0, }; shared_str name; - CEnvelope* envs[ctMaxChannel]; + CEnvelope* envs[ctMaxChannel]{}; Flags8 m_Flags; st_BoneMotion() { - name = 0; m_Flags.zero(); - ZeroMemory(envs, sizeof(CEnvelope*) * ctMaxChannel); } void SetName(pcstr nm) { name = nm; } }; diff --git a/src/xrEngine/Environment.cpp b/src/xrEngine/Environment.cpp index faf86780855..70951527604 100644 --- a/src/xrEngine/Environment.cpp +++ b/src/xrEngine/Environment.cpp @@ -37,32 +37,15 @@ static const float MAX_NOISE_FREQ = 0.03f; ////////////////////////////////////////////////////////////////////////// // environment -CEnvironment::CEnvironment() : m_ambients_config(0) +CEnvironment::CEnvironment() + : PerlinNoise1D(xr_new(Random.randI(0, 0xFFFF))) { - bWFX = false; - Current[0] = 0; - Current[1] = 0; - CurrentWeather = 0; - CurrentWeatherName = 0; - eff_Rain = 0; - eff_LensFlare = 0; - eff_Thunderbolt = 0; OnDeviceCreate(); - fGameTime = 0.f; fTimeFactor = 12.f; - wind_strength_factor = 0.f; - wind_gust_factor = 0.f; - - wetness_factor = 0.f; - - wind_blast_strength = 0.f; wind_blast_direction.set(1.f, 0.f, 0.f); - wind_blast_strength_start_value = 0.f; - wind_blast_strength_stop_value = 0.f; - // fill clouds hemi verts & faces const Fvector* verts; CloudsVerts.resize(xrHemisphereVertices(2, verts)); @@ -72,7 +55,6 @@ CEnvironment::CEnvironment() : m_ambients_config(0) CopyMemory(&CloudsIndices.front(), indices, CloudsIndices.size() * sizeof(u16)); // perlin noise - PerlinNoise1D = xr_new(Random.randI(0, 0xFFFF)); PerlinNoise1D->SetOctaves(2); PerlinNoise1D->SetAmplitude(0.66666f); diff --git a/src/xrEngine/Environment.h b/src/xrEngine/Environment.h index 2beda21cb6a..3d939749ce9 100644 --- a/src/xrEngine/Environment.h +++ b/src/xrEngine/Environment.h @@ -1,6 +1,4 @@ #pragma once -#ifndef EnvironmentH -#define EnvironmentH #include "Include/xrRender/FactoryPtr.h" #include "Include/xrRender/EnvironmentRender.h" @@ -254,34 +252,34 @@ class ENGINE_API CEnvironment protected: CPerlinNoise1D* PerlinNoise1D; - float fGameTime; + float fGameTime{}; public: FactoryPtr m_pRender; - float wind_strength_factor; - float wind_gust_factor; + float wind_strength_factor{}; + float wind_gust_factor{}; - float wetness_factor; + float wetness_factor{}; // wind blast params - float wind_blast_strength; - Fvector wind_blast_direction; + float wind_blast_strength{}; + Fvector wind_blast_direction{}; Fquaternion wind_blast_start_time; Fquaternion wind_blast_stop_time; - float wind_blast_strength_start_value; - float wind_blast_strength_stop_value; + float wind_blast_strength_start_value{}; + float wind_blast_strength_stop_value{}; Fquaternion wind_blast_current; // Environments CEnvDescriptorMixer CurrentEnv; - CEnvDescriptor* Current[2]; + CEnvDescriptor* Current[2]{}; - bool bWFX; + bool bWFX{}; float wfx_time; CEnvDescriptor* WFX_end_desc[2]; - EnvVec* CurrentWeather; + EnvVec* CurrentWeather{}; shared_str CurrentWeatherName; shared_str CurrentCycleName; @@ -290,9 +288,9 @@ class ENGINE_API CEnvironment xr_vector Modifiers; EnvAmbVec Ambients; - CEffect_Rain* eff_Rain; - CLensFlare* eff_LensFlare; - CEffect_Thunderbolt* eff_Thunderbolt; + CEffect_Rain* eff_Rain{}; + CLensFlare* eff_LensFlare{}; + CEffect_Thunderbolt* eff_Thunderbolt{}; float fTimeFactor; @@ -347,9 +345,9 @@ class ENGINE_API CEnvironment // editor-related void ED_Reload(); - CInifile* m_ambients_config; - CInifile* m_sound_channels_config; - CInifile* m_effects_config; + CInifile* m_ambients_config{}; + CInifile* m_sound_channels_config{}; + CInifile* m_effects_config{}; protected: virtual CEnvDescriptor* create_descriptor(shared_str const& identifier, CInifile const* config, pcstr section = nullptr); @@ -365,5 +363,3 @@ class ENGINE_API CEnvironment ENGINE_API extern Flags32 psEnvFlags; ENGINE_API extern float psVisDistance; ENGINE_API extern float SunshaftsIntensity; - -#endif // EnvironmentH diff --git a/src/xrEngine/XR_IOConsole.cpp b/src/xrEngine/XR_IOConsole.cpp index ce3d5328913..d3e03741f02 100644 --- a/src/xrEngine/XR_IOConsole.cpp +++ b/src/xrEngine/XR_IOConsole.cpp @@ -102,13 +102,6 @@ void CConsole::Initialize() { ZoneScoped; - scroll_delta = 0; - bVisible = false; - pFont = NULL; - pFont2 = NULL; - - m_last_cmd = NULL; - m_cmd_history.reserve(m_cmd_history_max + 2); m_cmd_history.clear(); reset_cmd_history_idx(); @@ -118,9 +111,6 @@ void CConsole::Initialize() m_temp_tips.reserve(MAX_TIPS_COUNT + 1); m_temp_tips.clear(); - m_tips_mode = 0; - m_prev_length_str = 0; - m_cur_cmd = NULL; reset_selected_tip(); eConsole = Engine.Event.Handler_Attach("KERNEL:console", this); @@ -836,7 +826,7 @@ void CConsole::update_tips() m_temp_tips.clear(); m_tips.clear(); - m_cur_cmd = NULL; + m_cur_cmd = nullptr; if (!bVisible) { return; diff --git a/src/xrEngine/XR_IOConsole.h b/src/xrEngine/XR_IOConsole.h index 16ff543d420..855f1171ac0 100644 --- a/src/xrEngine/XR_IOConsole.h +++ b/src/xrEngine/XR_IOConsole.h @@ -82,10 +82,10 @@ class ENGINE_API CConsole : }; protected: - int scroll_delta; + int scroll_delta{}; - CGameFont* pFont; - CGameFont* pFont2; + CGameFont* pFont{}; + CGameFont* pFont2{}; FactoryPtr* m_hShader_back{}; @@ -103,11 +103,11 @@ class ENGINE_API CConsole : vecTips m_temp_tips; vecTipsEx m_tips; - u32 m_tips_mode; + u32 m_tips_mode{}; shared_str m_cur_cmd; int m_select_tip; int m_start_tip; - u32 m_prev_length_str; + u32 m_prev_length_str{}; public: CConsole(); @@ -126,7 +126,7 @@ class ENGINE_API CConsole : pcstr GetUserConfigFileName() override { return ConfigFile; } string64 ConfigFile; - bool bVisible; + bool bVisible{}; vecCMD Commands; void AddCommand(IConsole_Command* cc); diff --git a/src/xrGame/AI_PhraseDialogManager.cpp b/src/xrGame/AI_PhraseDialogManager.cpp index d2ceba89441..b8d5e1e9600 100644 --- a/src/xrGame/AI_PhraseDialogManager.cpp +++ b/src/xrGame/AI_PhraseDialogManager.cpp @@ -13,9 +13,8 @@ #include "GameObject.h" #include "relation_registry.h" -CAI_PhraseDialogManager::CAI_PhraseDialogManager(void) { m_sStartDialog = m_sDefaultStartDialog = NULL; } -CAI_PhraseDialogManager::~CAI_PhraseDialogManager(void) {} -// PhraseDialogManager +CAI_PhraseDialogManager::CAI_PhraseDialogManager() = default; + void CAI_PhraseDialogManager::ReceivePhrase(DIALOG_SHARED_PTR& phrase_dialog) { AnswerPhrase(phrase_dialog); diff --git a/src/xrGame/AI_PhraseDialogManager.h b/src/xrGame/AI_PhraseDialogManager.h index dc8bfd95a18..595997de3d4 100644 --- a/src/xrGame/AI_PhraseDialogManager.h +++ b/src/xrGame/AI_PhraseDialogManager.h @@ -15,7 +15,6 @@ class CAI_PhraseDialogManager : public CPhraseDialogManager public: CAI_PhraseDialogManager(); - virtual ~CAI_PhraseDialogManager(); virtual void ReceivePhrase(DIALOG_SHARED_PTR& phrase_dialog); virtual void UpdateAvailableDialogs(CPhraseDialogManager* partner); diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 1a954197823..1573ff6df54 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -185,8 +185,6 @@ CActor::CActor() : CEntityAlive(), current_ik_cam_shift(0) SetZoomAimingMode(false); - m_sDefaultObjAction = NULL; - m_fSprintFactor = 4.f; // hFriendlyIndicator.create(FVF::F_LIT,RCache.Vertex.Buffer(),RCache.QuadIB); @@ -1318,7 +1316,7 @@ void CActor::shedule_Update(u32 DT) if (m_holder || !getEnabled() || !Ready()) { - m_sDefaultObjAction = NULL; + m_sDefaultObjAction = nullptr; inherited::shedule_Update(DT); return; } @@ -1552,19 +1550,19 @@ void CActor::shedule_Update(u32 DT) } else { - m_sDefaultObjAction = NULL; + m_sDefaultObjAction = nullptr; } } } } else { - m_pPersonWeLookingAt = NULL; - m_sDefaultObjAction = NULL; - m_pUsableObject = NULL; - m_pObjectWeLookingAt = NULL; - m_pVehicleWeLookingAt = NULL; - m_pInvBoxWeLookingAt = NULL; + m_pPersonWeLookingAt = nullptr; + m_sDefaultObjAction = nullptr; + m_pUsableObject = nullptr; + m_pObjectWeLookingAt = nullptr; + m_pVehicleWeLookingAt = nullptr; + m_pInvBoxWeLookingAt = nullptr; } // UpdateSleep (); diff --git a/src/xrGame/Artefact.cpp b/src/xrGame/Artefact.cpp index 9ee3e4b1509..738432662b5 100644 --- a/src/xrGame/Artefact.cpp +++ b/src/xrGame/Artefact.cpp @@ -46,11 +46,6 @@ CArtefact::CArtefact() { shedule.t_min = 20; shedule.t_max = 50; - m_sParticlesName = NULL; - m_pTrailLight = NULL; - m_activationObj = NULL; - m_detectorObj = NULL; - m_additional_weight = 0.0f; } CArtefact::~CArtefact() {} diff --git a/src/xrGame/Artefact.h b/src/xrGame/Artefact.h index 48a5cd898f3..5edd3815d33 100644 --- a/src/xrGame/Artefact.h +++ b/src/xrGame/Artefact.h @@ -53,8 +53,8 @@ class CArtefact : public CHudItemObject, public CPHUpdateObject virtual void UpdateCLChild(){}; virtual void CreateArtefactActivation(); - SArtefactActivation* m_activationObj; - SArtefactDetectorsSupport* m_detectorObj; + SArtefactActivation* m_activationObj{}; + SArtefactDetectorsSupport* m_detectorObj{}; u16 m_CarringBoneID; shared_str m_sParticlesName; @@ -64,7 +64,7 @@ class CArtefact : public CHudItemObject, public CPHUpdateObject float m_fTrailLightRange; u8 m_af_rank; bool m_bLightsEnabled; - float m_additional_weight; + float m_additional_weight{}; virtual void UpdateLights(); diff --git a/src/xrGame/CustomOutfit.cpp b/src/xrGame/CustomOutfit.cpp index 1d67b5682cd..2e356c947ab 100644 --- a/src/xrGame/CustomOutfit.cpp +++ b/src/xrGame/CustomOutfit.cpp @@ -21,8 +21,6 @@ CCustomOutfit::CCustomOutfit() m_HitTypeProtection[i] = 1.0f; m_boneProtection = xr_new(); - m_artefact_count = 0; - m_BonesProtectionSect = NULL; } CCustomOutfit::~CCustomOutfit() { xr_delete(m_boneProtection); } @@ -82,7 +80,7 @@ void CCustomOutfit::Load(LPCSTR section) if (pSettings->line_exist(section, "actor_visual")) m_ActorVisual = pSettings->r_string(section, "actor_visual"); else - m_ActorVisual = NULL; + m_ActorVisual = nullptr; m_ef_equipment_type = pSettings->r_u32(section, "ef_equipment_type"); m_fPowerLoss = READ_IF_EXISTS(pSettings, r_float, section, "power_loss", 1.0f); diff --git a/src/xrGame/CustomOutfit.h b/src/xrGame/CustomOutfit.h index f436f1d0397..8fbcf042b6e 100644 --- a/src/xrGame/CustomOutfit.h +++ b/src/xrGame/CustomOutfit.h @@ -40,7 +40,7 @@ class CCustomOutfit : public CInventoryItemObject protected: u32 m_ef_equipment_type; - u32 m_artefact_count; + u32 m_artefact_count{}; public: float m_fPowerLoss; diff --git a/src/xrGame/GameObject.cpp b/src/xrGame/GameObject.cpp index d369d07b3fd..60aece96f3a 100644 --- a/src/xrGame/GameObject.cpp +++ b/src/xrGame/GameObject.cpp @@ -154,7 +154,7 @@ void CGameObject::cNameVisual_set(shared_str N) else { GEnv.Render->model_Delete(renderable.visual); - NameVisual = 0; + NameVisual = nullptr; } OnChangeVisual(); } @@ -1531,6 +1531,6 @@ bool CGameObject::use(IGameObject* obj) LPCSTR CGameObject::tip_text() { return *m_sTipText; } void CGameObject::set_tip_text(LPCSTR new_text) { m_sTipText = new_text; } -void CGameObject::set_tip_text_default() { m_sTipText = NULL; } +void CGameObject::set_tip_text_default() { m_sTipText = nullptr; } bool CGameObject::nonscript_usable() { return m_bNonscriptUsable; } void CGameObject::set_nonscript_usable(bool usable) { m_bNonscriptUsable = usable; } diff --git a/src/xrGame/GraviZone.cpp b/src/xrGame/GraviZone.cpp index 511df5f3781..292ad359fa8 100644 --- a/src/xrGame/GraviZone.cpp +++ b/src/xrGame/GraviZone.cpp @@ -10,8 +10,8 @@ #include "Level.h" #include "CharacterPhysicsSupport.h" -CBaseGraviZone::CBaseGraviZone(void) { m_dwTeleTime = 0; } -CBaseGraviZone::~CBaseGraviZone(void) {} +CBaseGraviZone::CBaseGraviZone() {} + void CBaseGraviZone::Load(LPCSTR section) { inherited::Load(section); @@ -28,12 +28,12 @@ void CBaseGraviZone::Load(LPCSTR section) if (pSettings->line_exist(section, "tele_particles_big")) m_sTeleParticlesBig = pSettings->r_string(section, "tele_particles_big"); else - m_sTeleParticlesBig = NULL; + m_sTeleParticlesBig = nullptr; if (pSettings->line_exist(section, "tele_particles_small")) m_sTeleParticlesSmall = pSettings->r_string(section, "tele_particles_small"); else - m_sTeleParticlesSmall = NULL; + m_sTeleParticlesSmall = nullptr; } bool CBaseGraviZone::net_Spawn(CSE_Abstract* DC) { return inherited::net_Spawn(DC); } diff --git a/src/xrGame/GraviZone.h b/src/xrGame/GraviZone.h index f04c9945f55..fb5c6e5000d 100644 --- a/src/xrGame/GraviZone.h +++ b/src/xrGame/GraviZone.h @@ -18,7 +18,6 @@ class CBaseGraviZone : public CCustomZone public: CBaseGraviZone(void); - virtual ~CBaseGraviZone(void); virtual void Load(LPCSTR section); @@ -56,7 +55,7 @@ class CBaseGraviZone : public CCustomZone float m_fTeleHeight; u32 m_dwTimeToTele; u32 m_dwTelePause; - u32 m_dwTeleTime; + u32 m_dwTeleTime{}; //имя партиклов телекинеза void PlayTeleParticles(CGameObject* pObject); diff --git a/src/xrGame/InfoDocument.cpp b/src/xrGame/InfoDocument.cpp index 409cbdbbc40..274e6c4be74 100644 --- a/src/xrGame/InfoDocument.cpp +++ b/src/xrGame/InfoDocument.cpp @@ -10,8 +10,8 @@ #include "xrServer_Objects_ALife_Items.h" #include "xrServerEntities/xrMessages.h" -CInfoDocument::CInfoDocument(void) { m_Info = NULL; } -CInfoDocument::~CInfoDocument(void) {} +CInfoDocument::CInfoDocument() = default; + bool CInfoDocument::net_Spawn(CSE_Abstract* DC) { BOOL res = inherited::net_Spawn(DC); diff --git a/src/xrGame/InfoDocument.h b/src/xrGame/InfoDocument.h index 31159fbd484..c5003d80c74 100644 --- a/src/xrGame/InfoDocument.h +++ b/src/xrGame/InfoDocument.h @@ -14,8 +14,7 @@ class CInfoDocument : public CInventoryItemObject typedef CInventoryItemObject inherited; public: - CInfoDocument(void); - virtual ~CInfoDocument(void); + CInfoDocument(); virtual bool net_Spawn(CSE_Abstract* DC); virtual void Load(LPCSTR section); diff --git a/src/xrGame/PDA.cpp b/src/xrGame/PDA.cpp index d4186297870..6a962e84042 100644 --- a/src/xrGame/PDA.cpp +++ b/src/xrGame/PDA.cpp @@ -15,7 +15,6 @@ CPda::CPda(void) { m_idOriginalOwner = u16(-1); - m_SpecificChracterOwner = NULL; TurnOff(); } diff --git a/src/xrGame/PHSkeleton.cpp b/src/xrGame/PHSkeleton.cpp index b14ac1ff327..760a9711a94 100644 --- a/src/xrGame/PHSkeleton.cpp +++ b/src/xrGame/PHSkeleton.cpp @@ -54,7 +54,7 @@ void CPHSkeleton::Init() { m_remove_time = u32(-1); b_removing = false; - m_startup_anim = NULL; + m_startup_anim = nullptr; } bool CPHSkeleton::Spawn(CSE_Abstract* D) diff --git a/src/xrGame/ShootingObject.cpp b/src/xrGame/ShootingObject.cpp index 08b4d8b12ca..59fd266e501 100644 --- a/src/xrGame/ShootingObject.cpp +++ b/src/xrGame/ShootingObject.cpp @@ -20,32 +20,11 @@ #define HIT_POWER_EPSILON 0.05f #define WALLMARK_SIZE 0.04f -CShootingObject::CShootingObject(void) +CShootingObject::CShootingObject() { - fShotTimeCounter = 0; - fOneShotTime = 0; // fHitPower = 0.0f; - fvHitPower.set(0.0f, 0.0f, 0.0f, 0.0f); - fvHitPowerCritical.set(0.0f, 0.0f, 0.0f, 0.0f); m_fStartBulletSpeed = 1000.f; - m_vCurrentShootDir.set(0, 0, 0); - m_vCurrentShootPos.set(0, 0, 0); - m_iCurrentParentID = 0xFFFF; - - m_fPredBulletTime = 0.0f; - m_bUseAimBullet = false; - m_fTimeToAim = 0.0f; - - // particles - m_sFlameParticlesCurrent = m_sFlameParticles = NULL; - m_sSmokeParticlesCurrent = m_sSmokeParticles = NULL; - m_sShellParticles = NULL; - - bWorking = false; - - light_render = 0; - reinit(); } CShootingObject::~CShootingObject(void) {} diff --git a/src/xrGame/ShootingObject.h b/src/xrGame/ShootingObject.h index 23140dcc1c8..ec9762b133c 100644 --- a/src/xrGame/ShootingObject.h +++ b/src/xrGame/ShootingObject.h @@ -29,15 +29,15 @@ class CShootingObject : public IAnticheatDumpable void reload(LPCSTR section){}; void Load(LPCSTR section); - Fvector m_vCurrentShootDir; - Fvector m_vCurrentShootPos; + Fvector m_vCurrentShootDir{}; + Fvector m_vCurrentShootPos{}; private: float m_air_resistance_factor; protected: // ID персонажа который иницировал действие - u16 m_iCurrentParentID; + u16 m_iCurrentParentID{ 0xFFFF }; ////////////////////////////////////////////////////////////////////////// // Fire Params @@ -58,13 +58,13 @@ class CShootingObject : public IAnticheatDumpable virtual BOOL ParentIsActor() { return FALSE; } protected: // Weapon fires now - bool bWorking; + bool bWorking{}; - float fOneShotTime; + float fOneShotTime{}; float modeShotTime; bool cycleDown; - Fvector4 fvHitPower; - Fvector4 fvHitPowerCritical; + Fvector4 fvHitPower{}; + Fvector4 fvHitPowerCritical{}; float fHitImpulse; //скорость вылета пули из ствола @@ -76,7 +76,7 @@ class CShootingObject : public IAnticheatDumpable float fireDispersionBase; //счетчик времени, затрачиваемого на выстрел - float fShotTimeCounter; + float fShotTimeCounter{}; struct SilencerKoeffs // value *= koef; { @@ -170,9 +170,9 @@ class CShootingObject : public IAnticheatDumpable public: Fvector vLoadedShellPoint; - float m_fPredBulletTime; - float m_fTimeToAim; - bool m_bUseAimBullet; + float m_fPredBulletTime{}; + float m_fTimeToAim{}; + bool m_bUseAimBullet{}; protected: //имя пратиклов для огня diff --git a/src/xrGame/WeaponAmmo.cpp b/src/xrGame/WeaponAmmo.cpp index 0a8b32bae46..dd07aaef61e 100644 --- a/src/xrGame/WeaponAmmo.cpp +++ b/src/xrGame/WeaponAmmo.cpp @@ -15,7 +15,6 @@ CCartridge::CCartridge() { m_flags.assign(cfTracer | cfRicochet); - m_ammoSect = NULL; param_s.Init(); bullet_material_idx = u16(-1); } diff --git a/src/xrGame/game_cl_base.cpp b/src/xrGame/game_cl_base.cpp index 7e0dd519997..ac3f160a7e2 100644 --- a/src/xrGame/game_cl_base.cpp +++ b/src/xrGame/game_cl_base.cpp @@ -21,8 +21,6 @@ game_cl_GameState::game_cl_GameState() local_player = createPlayerState(NULL); // initializing account info m_WeaponUsageStatistic = NULL; - m_game_type_name = 0; - shedule.t_min = 5; shedule.t_max = 20; m_game_ui_custom = NULL; diff --git a/src/xrGame/game_cl_base_weapon_usage_statistic.cpp b/src/xrGame/game_cl_base_weapon_usage_statistic.cpp index aba2ad8f728..fdcedbfde11 100644 --- a/src/xrGame/game_cl_base_weapon_usage_statistic.cpp +++ b/src/xrGame/game_cl_base_weapon_usage_statistic.cpp @@ -47,21 +47,7 @@ void HitData::net_load(NET_Packet* P, victims_table const& vt, bone_table const& Completed = true; }; -Weapon_Statistic::Weapon_Statistic(LPCSTR Name) -{ - WName = Name; - InvName = NULL; - NumBought = 0; - - m_dwRoundsFired = m_dwRoundsFired_d = 0; - m_dwBulletsFired = m_dwBulletsFired_d = 0; - m_dwHitsScored = m_dwHitsScored_d = 0; - m_dwKillsScored = m_dwKillsScored_d = 0; - m_explosion_kills = 0; - m_bleed_kills = 0; - - ZeroMemory(m_Basket, sizeof(m_Basket)); -}; +Weapon_Statistic::Weapon_Statistic(pcstr name) : WName(name) {} Weapon_Statistic::~Weapon_Statistic(){}; @@ -845,7 +831,6 @@ void WeaponUsageStatistic::OnExplosionKill(game_PlayerState* ps, const SHit& hit NewHit.Pos0 = killer->Position(); NewHit.Pos1 = weapon_object->Position(); NewHit.TargetName = ps->getName(); - NewHit.BoneName = 0; NewHit.count = 1; //--------------------------- WeaponIt->add_hit(NewHit); @@ -877,7 +862,6 @@ void WeaponUsageStatistic::OnBleedKill(game_PlayerState* killer_ps, game_PlayerS NewHit.Pos0 = Fvector3(); NewHit.Pos1 = Fvector3(); NewHit.TargetName = victim_ps->getName(); - NewHit.BoneName = 0; NewHit.count = 1; //--------------------------- WeaponIt->add_hit(NewHit); diff --git a/src/xrGame/game_cl_base_weapon_usage_statistic.h b/src/xrGame/game_cl_base_weapon_usage_statistic.h index 73f125b869f..3854f9bb3f4 100644 --- a/src/xrGame/game_cl_base_weapon_usage_statistic.h +++ b/src/xrGame/game_cl_base_weapon_usage_statistic.h @@ -101,16 +101,16 @@ struct Weapon_Statistic static u32 const net_packet_size; shared_str WName; shared_str InvName; - u32 NumBought; + u32 NumBought{}; //--------------------------- - u32 m_dwRoundsFired, m_dwRoundsFired_d; - u32 m_dwBulletsFired, m_dwBulletsFired_d; - u32 m_dwHitsScored, m_dwHitsScored_d; - u32 m_dwKillsScored, m_dwKillsScored_d; - u16 m_explosion_kills; - u16 m_bleed_kills; + u32 m_dwRoundsFired{}, m_dwRoundsFired_d{}; + u32 m_dwBulletsFired{}, m_dwBulletsFired_d{}; + u32 m_dwHitsScored{}, m_dwHitsScored_d{}; + u32 m_dwKillsScored{}, m_dwKillsScored_d{}; + u16 m_explosion_kills{}; + u16 m_bleed_kills{}; //--------------------------- - u32 m_Basket[STAT_TEAM_COUNT][MAX_BASKET]; + u32 m_Basket[STAT_TEAM_COUNT][MAX_BASKET]{}; // u32 m_dwNumCompleted; HITS_VEC m_Hits; diff --git a/src/xrGame/game_cl_mp.cpp b/src/xrGame/game_cl_mp.cpp index 5bdbf64fb82..314c13b3683 100644 --- a/src/xrGame/game_cl_mp.cpp +++ b/src/xrGame/game_cl_mp.cpp @@ -853,7 +853,7 @@ void game_cl_mp::OnPlayerKilled(NET_Packet& P) KMS.m_victim.m_name = pPlayer->getName(); KMS.m_victim.m_color = Color_Teams_u32[ModifyTeam(pPlayer->team) + 1]; - KMS.m_killer.m_name = NULL; + KMS.m_killer.m_name = nullptr; KMS.m_killer.m_color = color_rgba(255, 255, 255, 255); switch (KillType) @@ -997,7 +997,7 @@ void game_cl_mp::OnPlayerKilled(NET_Packet& P) // suicide if (KilledID == KillerID) { - KMS.m_victim.m_name = NULL; + KMS.m_victim.m_name = nullptr; KMS.m_ext_info.m_shader = GetKillEventIconsShader(); KMS.m_ext_info.m_rect.x1 = 32; diff --git a/src/xrGame/game_sv_mp.h b/src/xrGame/game_sv_mp.h index e0e85cccfab..26d21835d32 100644 --- a/src/xrGame/game_sv_mp.h +++ b/src/xrGame/game_sv_mp.h @@ -15,17 +15,9 @@ class xrClientData; struct Rank_Struct { shared_str m_sTitle; - int m_iTerms[MAX_TERMS]; - int m_iBonusMoney; + int m_iTerms[MAX_TERMS]{}; + int m_iBonusMoney{}; xr_vector m_aRankDiff_ExpBonus; - - Rank_Struct() - { - m_sTitle = NULL; - ZeroMemory(m_iTerms, sizeof(m_iTerms)); - m_iBonusMoney = 0; - m_aRankDiff_ExpBonus.clear(); - }; }; class game_sv_mp : public game_sv_GameState diff --git a/src/xrGame/inventory_item.cpp b/src/xrGame/inventory_item.cpp index 2230f8b620e..b8548a4ac83 100644 --- a/src/xrGame/inventory_item.cpp +++ b/src/xrGame/inventory_item.cpp @@ -56,15 +56,12 @@ CInventoryItem::CInventoryItem() m_flags.set(FUsingCondition, FALSE); m_fCondition = 1.0f; - m_name = m_nameShort = NULL; - m_ItemCurrPlace.value = 0; m_ItemCurrPlace.type = eItemPlaceUndefined; m_ItemCurrPlace.base_slot_id = NO_ACTIVE_SLOT; m_ItemCurrPlace.slot_id = NO_ACTIVE_SLOT; m_Description = ""; - m_section_id = 0; m_flags.set(FIsHelperItem, FALSE); } diff --git a/src/xrGame/ui/FactionState.cpp b/src/xrGame/ui/FactionState.cpp index 461e8eb7e76..a7c78294b51 100644 --- a/src/xrGame/ui/FactionState.cpp +++ b/src/xrGame/ui/FactionState.cpp @@ -45,12 +45,12 @@ void FactionState::ResetStates() { for ( int i = 0; i < war_state_count ; ++i ) { - m_war_state_str[i]._set( NULL ); - m_war_state_hint_str[i]._set( NULL ); + m_war_state_str[i] = nullptr; + m_war_state_hint_str[i] = nullptr; } /*for ( int i = 0; i < bonuses_count ; ++i ) { - bonuses_vs[i]._set( NULL ); + bonuses_vs[i] = nullptr; }*/ } diff --git a/src/xrGame/ui/FractionState.cpp b/src/xrGame/ui/FractionState.cpp index 5165f339d3b..a8e72c469a8 100644 --- a/src/xrGame/ui/FractionState.cpp +++ b/src/xrGame/ui/FractionState.cpp @@ -23,15 +23,7 @@ FractionState::FractionState(): power(0.0f), state_vs(0), m_actor_goodwill(0) -{ - m_id._set ( NULL ); - m_name._set ( NULL ); - m_icon._set ( NULL ); - m_icon_big._set ( NULL ); - m_target._set ( NULL ); - m_target_desc._set( NULL ); - m_location._set ( NULL ); -} +{} FractionState::FractionState( shared_str const& id ) : FractionState() diff --git a/src/xrGame/ui/UIInvUpgrade.cpp b/src/xrGame/ui/UIInvUpgrade.cpp index 8c4e536f8a1..bcf59bf6dac 100644 --- a/src/xrGame/ui/UIInvUpgrade.cpp +++ b/src/xrGame/ui/UIInvUpgrade.cpp @@ -49,7 +49,6 @@ UIUpgrade::UIUpgrade(CUIInventoryUpgradeWnd* parent_wnd, bool cellBorder) m_ink = nullptr; } - m_upgrade_id = NULL; Reset(); } diff --git a/src/xrServerEntities/character_info.cpp b/src/xrServerEntities/character_info.cpp index 2659ddf12c6..5ee5744b5a2 100644 --- a/src/xrServerEntities/character_info.cpp +++ b/src/xrServerEntities/character_info.cpp @@ -33,7 +33,6 @@ CCharacterInfo::CCharacterInfo() #ifdef XRGAME_EXPORTS m_CurrentRank.set(NO_RANK); m_CurrentReputation.set(NO_REPUTATION); - m_StartDialog = NULL; m_Sympathy = 0.0f; #endif } diff --git a/src/xrServerEntities/character_info_defs.h b/src/xrServerEntities/character_info_defs.h index cafcc7c1f0f..0d5bdd1af3b 100644 --- a/src/xrServerEntities/character_info_defs.h +++ b/src/xrServerEntities/character_info_defs.h @@ -10,7 +10,7 @@ typedef int CHARACTER_GOODWILL; #define NEUTRAL_GOODWILL CHARACTER_GOODWILL(0) typedef shared_str CHARACTER_CLASS; -#define NO_CHARACTER_CLASS NULL +#define NO_CHARACTER_CLASS nullptr //репутация персонажа - величина от -100 (очень плохой, беспредельщик) //до 100 (очень хороший, благородный) diff --git a/src/xrServerEntities/specific_character.cpp b/src/xrServerEntities/specific_character.cpp index 61abd643192..825568a2475 100644 --- a/src/xrServerEntities/specific_character.cpp +++ b/src/xrServerEntities/specific_character.cpp @@ -7,23 +7,11 @@ SSpecificCharacterData::SSpecificCharacterData() { m_sGameName.clear(); - m_sBioText = NULL; m_sVisual.clear(); m_sSupplySpawn.clear(); m_sNpcConfigSect.clear(); - m_StartDialog = NULL; m_ActorDialogs.clear(); - - m_Rank = NO_RANK; - m_Reputation = NO_REPUTATION; - - m_bNoRandom = false; - m_bDefaultForCommunity = false; - m_fPanic_threshold = 0.0f; - m_fHitProbabilityFactor = 1.f; - m_crouch_type = 0; - m_upgrade_mechanic = false; } SSpecificCharacterData::~SSpecificCharacterData() {} @@ -86,7 +74,7 @@ void CSpecificCharacter::load_shared(LPCSTR) data()->m_StartDialog = start_dialog; } else - data()->m_StartDialog = NULL; + data()->m_StartDialog = nullptr; int dialogs_num = pXML->GetNodesNum(pXML->GetLocalRoot(), "actor_dialog"); data()->m_ActorDialogs.clear(); diff --git a/src/xrServerEntities/specific_character.h b/src/xrServerEntities/specific_character.h index 4d45faf900f..c635951609d 100644 --- a/src/xrServerEntities/specific_character.h +++ b/src/xrServerEntities/specific_character.h @@ -37,10 +37,10 @@ struct SSpecificCharacterData : CSharedResource //имя секции конфигурации звука для NPC персонажа xr_string m_sound_voice_prefix; - float m_fPanic_threshold; - float m_fHitProbabilityFactor; - int m_crouch_type; - bool m_upgrade_mechanic; + float m_fPanic_threshold{}; + float m_fHitProbabilityFactor{ 1.f }; + int m_crouch_type{}; + bool m_upgrade_mechanic{}; xr_string m_critical_wound_weights; #endif @@ -63,9 +63,9 @@ struct SSpecificCharacterData : CSharedResource #endif //ранг - CHARACTER_RANK_VALUE m_Rank; + CHARACTER_RANK_VALUE m_Rank{ NO_RANK }; //репутация - CHARACTER_REPUTATION_VALUE m_Reputation; + CHARACTER_REPUTATION_VALUE m_Reputation{ NO_REPUTATION }; //классы персонажа (военные-ветераны, ученые и т.д.) //к которым он принадлежит @@ -73,9 +73,9 @@ struct SSpecificCharacterData : CSharedResource //указание на то что персонаж не предназначен для случайного выбора //и задается только через явное указание ID - bool m_bNoRandom; + bool m_bNoRandom{}; //если персонаж является заданым по умолчанию для своей команды - bool m_bDefaultForCommunity; + bool m_bDefaultForCommunity{}; #ifdef XRGAME_EXPORTS struct SMoneyDef { diff --git a/src/xrServerEntities/xrServer_Objects_ALife_Items.cpp b/src/xrServerEntities/xrServer_Objects_ALife_Items.cpp index 6a2003df9a2..53e19117ae3 100644 --- a/src/xrServerEntities/xrServer_Objects_ALife_Items.cpp +++ b/src/xrServerEntities/xrServer_Objects_ALife_Items.cpp @@ -840,12 +840,8 @@ BOOL CSE_ALifeItemArtefact::Net_Relevant() //////////////////////////////////////////////////////////////////////////// CSE_ALifeItemPDA::CSE_ALifeItemPDA(LPCSTR caSection) : CSE_ALifeItem(caSection) { - m_original_owner = 0xffff; - m_specific_character = NULL; - m_info_portion = NULL; } -CSE_ALifeItemPDA::~CSE_ALifeItemPDA() {} void CSE_ALifeItemPDA::STATE_Read(NET_Packet& tNetPacket, u16 size) { inherited::STATE_Read(tNetPacket, size); @@ -859,8 +855,8 @@ void CSE_ALifeItemPDA::STATE_Read(NET_Packet& tNetPacket, u16 size) int tmp, tmp2; tNetPacket.r(&tmp, sizeof(int)); tNetPacket.r(&tmp2, sizeof(int)); - m_info_portion = NULL; - m_specific_character = NULL; + m_info_portion = nullptr; + m_specific_character = nullptr; } else { @@ -877,8 +873,8 @@ void CSE_ALifeItemPDA::STATE_Write(NET_Packet& tNetPacket) tNetPacket.w_stringZ(m_specific_character); tNetPacket.w_stringZ(m_info_portion); #else - shared_str tmp_1 = NULL; - shared_str tmp_2 = NULL; + shared_str tmp_1; + shared_str tmp_2; tNetPacket.w_stringZ(tmp_1); tNetPacket.w_stringZ(tmp_2); @@ -894,8 +890,7 @@ void CSE_ALifeItemPDA::FillProps(LPCSTR pref, PropItemVec& items) { inherited::F //////////////////////////////////////////////////////////////////////////// // CSE_ALifeItemDocument //////////////////////////////////////////////////////////////////////////// -CSE_ALifeItemDocument::CSE_ALifeItemDocument(LPCSTR caSection) : CSE_ALifeItem(caSection) { m_wDoc = NULL; } -CSE_ALifeItemDocument::~CSE_ALifeItemDocument() {} +CSE_ALifeItemDocument::CSE_ALifeItemDocument(pcstr caSection) : CSE_ALifeItem(caSection) {} void CSE_ALifeItemDocument::STATE_Read(NET_Packet& tNetPacket, u16 size) { inherited::STATE_Read(tNetPacket, size); @@ -904,7 +899,7 @@ void CSE_ALifeItemDocument::STATE_Read(NET_Packet& tNetPacket, u16 size) { u16 tmp; tNetPacket.r_u16(tmp); - m_wDoc = NULL; + m_wDoc = nullptr; } else tNetPacket.r_stringZ(m_wDoc); diff --git a/src/xrServerEntities/xrServer_Objects_ALife_Items.h b/src/xrServerEntities/xrServer_Objects_ALife_Items.h index 12439ac7ebd..63f3bdbe683 100644 --- a/src/xrServerEntities/xrServer_Objects_ALife_Items.h +++ b/src/xrServerEntities/xrServer_Objects_ALife_Items.h @@ -344,12 +344,11 @@ class CSE_ALifeItemPDA : public CSE_ALifeItem using inherited = CSE_ALifeItem; public: - u16 m_original_owner; + u16 m_original_owner{ 0xffff }; shared_str m_specific_character; shared_str m_info_portion; CSE_ALifeItemPDA(LPCSTR caSection); - virtual ~CSE_ALifeItemPDA(); virtual CSE_ALifeItemPDA* cast_item_pda() { return this; }; virtual void UPDATE_Read(NET_Packet& P); virtual void UPDATE_Write(NET_Packet& P); @@ -365,7 +364,6 @@ class CSE_ALifeItemDocument : public CSE_ALifeItem public: shared_str m_wDoc; CSE_ALifeItemDocument(LPCSTR caSection); - virtual ~CSE_ALifeItemDocument(); virtual void UPDATE_Read(NET_Packet& P); virtual void UPDATE_Write(NET_Packet& P); virtual void STATE_Read(NET_Packet& P, u16 size); From dce1e92caf6e14464d01d87edbf8e4031444cc82 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 1 Jun 2024 01:18:19 +0500 Subject: [PATCH 457/497] xrCore/xrstring.h: make shared_str movable, use noexcept, modernize --- src/xrCore/xrstring.h | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/xrCore/xrstring.h b/src/xrCore/xrstring.h index 7810b1c7893..2c0b837450d 100644 --- a/src/xrCore/xrstring.h +++ b/src/xrCore/xrstring.h @@ -58,73 +58,92 @@ XRCORE_API extern str_container* g_pStringContainer; ////////////////////////////////////////////////////////////////////////// class shared_str { - str_value* p_; + str_value* p_{}; protected: // ref-counting - void _dec() + void _dec() noexcept { - if (0 == p_) + if (nullptr == p_) return; p_->dwReference--; if (0 == p_->dwReference) - p_ = 0; + p_ = nullptr; } public: void _set(pcstr rhs) { str_value* v = g_pStringContainer->dock(rhs); - if (0 != v) + if (nullptr != v) v->dwReference++; _dec(); p_ = v; } - void _set(shared_str const& rhs) + void _set(shared_str const& rhs) noexcept { str_value* v = rhs.p_; - if (0 != v) + if (nullptr != v) v->dwReference++; _dec(); p_ = v; } - // void _set (shared_str const &rhs) { str_value* v = g_pStringContainer->dock(rhs.c_str()); if (0!=v) - // v->dwReference++; _dec(); p_ = v; } + void _set(nullptr_t) noexcept + { + _dec(); + p_ = nullptr; + } [[nodiscard]] const str_value* _get() const { return p_; } public: // construction - shared_str() { p_ = 0; } + shared_str() = default; shared_str(pcstr rhs) { - p_ = 0; + p_ = nullptr; _set(rhs); } - shared_str(shared_str const& rhs) + shared_str(shared_str const& rhs) noexcept { - p_ = 0; + p_ = nullptr; _set(rhs); } + shared_str(shared_str&& rhs) noexcept + : p_(rhs.p_) + { + rhs.p_ = nullptr; + } ~shared_str() { _dec(); } // assignment & accessors shared_str& operator=(pcstr rhs) { _set(rhs); - return (shared_str&)*this; + return *this; } - shared_str& operator=(shared_str const& rhs) + shared_str& operator=(shared_str const& rhs) noexcept { _set(rhs); - return (shared_str&)*this; + return *this; + } + shared_str& operator=(shared_str&& rhs) noexcept + { + p_ = rhs.p_; + rhs.p_ = nullptr; + return *this; + } + shared_str& operator=(nullptr_t) noexcept + { + _set(nullptr); + return *this; } // XXX tamlin: Remove operator*(). It may be convenient, but it's dangerous. Use [[nodiscard]] - pcstr operator*() const { return p_ ? p_->value : 0; } + pcstr operator*() const { return p_ ? p_->value : nullptr; } [[nodiscard]] - bool operator!() const { return p_ == 0; } + bool operator!() const { return p_ == nullptr; } [[nodiscard]] char operator[](size_t id) { return p_->value[id]; } @@ -132,7 +151,7 @@ class shared_str char operator[](size_t id) const { return p_->value[id]; } [[nodiscard]] - pcstr c_str() const { return p_ ? p_->value : 0; } + pcstr c_str() const { return p_ ? p_->value : nullptr; } // misc func [[nodiscard]] From e72b01b4e11c0bbb9852cb9335c59537efca24b8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 1 Jun 2024 02:29:23 +0500 Subject: [PATCH 458/497] xrSound: made CSoundRender_Source noexcept movable --- src/xrSound/SoundRender_Core_SourceManager.cpp | 16 ++++++---------- src/xrSound/SoundRender_Source.h | 8 +++++++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/xrSound/SoundRender_Core_SourceManager.cpp b/src/xrSound/SoundRender_Core_SourceManager.cpp index e82d7bb8834..c1d8211a6f6 100644 --- a/src/xrSound/SoundRender_Core_SourceManager.cpp +++ b/src/xrSound/SoundRender_Core_SourceManager.cpp @@ -22,20 +22,16 @@ CSoundRender_Source* CSoundRender_Core::i_create_source(pcstr name) } // Load a _new one - CSoundRender_Source* S = xr_new(); - - if (!S->load(id)) - { - // XXX: Make CSoundRender_Source movable and make allocation only if S->load succeeded. - xr_delete(S); - } - else + CSoundRender_Source source; + if (source.load(id)) { ScopeLock scope(&s_sources_lock); - s_sources.insert({ id, S }); + CSoundRender_Source* S = xr_new(std::move(source)); + s_sources.emplace(id, S); + return S; } - return S; + return nullptr; } void CSoundRender_Core::i_destroy_source(CSoundRender_Source* S) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index 484c3ce014f..d8edc8c5d28 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -47,9 +47,15 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source bool LoadWave(pcstr name); public: - CSoundRender_Source() = default; + CSoundRender_Source() noexcept = default; ~CSoundRender_Source() override; + CSoundRender_Source(const CSoundRender_Source&) = delete; + CSoundRender_Source(CSoundRender_Source&&) noexcept = default; + + CSoundRender_Source& operator=(const CSoundRender_Source&) = delete; + CSoundRender_Source& operator=(CSoundRender_Source&&) noexcept = default; + bool load(pcstr name); void unload(); From eecab73843bc51521da8c6cb435c8f7c346025ca Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 1 Jun 2024 02:32:01 +0500 Subject: [PATCH 459/497] Include/xrRender/FactoryPtr.h: use operator bool instead of unspecified bool type --- src/Include/xrRender/FactoryPtr.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Include/xrRender/FactoryPtr.h b/src/Include/xrRender/FactoryPtr.h index 85e38815e1e..af45b377547 100644 --- a/src/Include/xrRender/FactoryPtr.h +++ b/src/Include/xrRender/FactoryPtr.h @@ -46,9 +46,7 @@ class FactoryPtr T& operator*() const { return *m_pObject; } T* operator->() const { return m_pObject; } - // unspecified bool type - typedef T const* (FactoryPtr::*unspecified_bool_type)() const; - operator unspecified_bool_type() const { return (!m_pObject ? 0 : &FactoryPtr::get); } + operator bool() const { return m_pObject; } bool operator!() const { return m_pObject == nullptr; } private: void CreateObject(); From 87ae41b10c10432bd51d84bcbc9454f111a79f60 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 2 Jun 2024 01:15:20 +0500 Subject: [PATCH 460/497] xrRender_GL: improve shaders conformance with GLSL standard --- res/gamedata/shaders/gl/accum_volumetric.ps | Bin 2200 -> 2207 bytes .../shaders/gl/accum_volumetric_sun_msaa0.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa1.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa2.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa3.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa4.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa5.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa6.ps | Bin 53 -> 59 bytes .../shaders/gl/accum_volumetric_sun_msaa7.ps | Bin 53 -> 59 bytes res/gamedata/shaders/gl/combine_2_naa.ps | Bin 3914 -> 3940 bytes res/gamedata/shaders/gl/combine_volumetric.ps | Bin 898 -> 899 bytes res/gamedata/shaders/gl/common_policies.h | 4 ++-- res/gamedata/shaders/gl/copy.ps | Bin 619 -> 625 bytes res/gamedata/shaders/gl/copy_p.ps | Bin 722 -> 729 bytes res/gamedata/shaders/gl/depth_downs.ps | Bin 1961 -> 1968 bytes res/gamedata/shaders/gl/rain_apply_gloss.ps | Bin 1077 -> 1084 bytes res/gamedata/shaders/gl/rain_apply_normal.ps | Bin 837 -> 843 bytes res/gamedata/shaders/gl/rain_patch_normal.ps | Bin 4079 -> 4085 bytes .../shaders/gl/rain_patch_normal_new.ps | Bin 3996 -> 4003 bytes res/gamedata/shaders/gl/ssao_calc.ps | Bin 727 -> 733 bytes src/Layers/xrRenderPC_GL/rgl_shaders.cpp | 15 ++++----------- 21 files changed, 6 insertions(+), 13 deletions(-) diff --git a/res/gamedata/shaders/gl/accum_volumetric.ps b/res/gamedata/shaders/gl/accum_volumetric.ps index 909932fe2f1b5d991cfb0ccea826fae28d10997c..b2e9b0cf8acf9f08054e0e01dcfd18d5c401340e 100644 GIT binary patch delta 20 bcmbOsIA3r=E_-QaUWtZ*=EgiN4n{5jNQnje delta 12 TcmbO)I74tkE~CN55-kn@8?gi5 diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps index 4b733fd88e66384131179ecf7de9416237fe2a7a..22216c9b51730aadcaa3450b87337ccd5de04557 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE735}oG7RQ0Di9sXaE2J delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO(+t^xo}S_W4D diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa1.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa1.ps index 140e48af20026a49d7733c0c386122ae62eb31f2..843a0ec0bd02d43bc58b3b28ab0d9e950528c847 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE7362oG7RQ0DiOxX#fBK delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO_=t^xo}UIthI diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa2.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa2.ps index 2c49b8dc148ba648248221c8bff0ecc28547488f..9173af98a9363fb47215a8c187bdd8fce7786a5e 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE7360oG7RQ0Did$Y5)KL delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO<;t^xo}Vg^|N diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa3.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa3.ps index 5516f2721468ee2b3027f15b13c56f38e0b478b2..789bb538ecf8e02add3c2f558ff6a0d3be3d34cb 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE7364oG7RQ0Dis*YXATM delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWP0?t^xo}W(HaS diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa4.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa4.ps index 9a39afcb9672ea68a6613551d7ce324f4fed8c14..b8083e1e99670ff84160d5627465ef0e141a9443 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE735~oG7RQ0Di*=YybcN delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO+-t^xo}Y6e>X diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa5.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa5.ps index e639cb97deeca61b095f4a8707abe7d1ea4277aa..5e69bf4113839562df4cae227959484cc7ce8b01 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE7363oG7RQ0Di~_Z2$lO delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO|>t^xo}ZU$Tc diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa6.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa6.ps index 58bcacb686908e91ff3e1abef742108d6f9a66bb..cf872e97bd73b49bca7e03e57bd4dc49311ea8c2 100644 GIT binary patch delta 29 kcmXrD7FSM5P0P$nRqzaU^bPQFRVdBOE7361oG7RQ0DjE~ZU6uP delta 23 ecmcCE6;w`1P0P$nRqzaU^bPQFRWO?l_e5?(9y4R<=bQ<+sQLBa}|!HKyAIjIV^ y3Sdk0*yV-~(n~@u6Hq;Q!&5K!=a{>UW8Ycw+ delta 89 zcmaDNcS>$U9`odUW@#SZU`NOJU`O8oAJ^c?bC^}NGxJImGJ_Ly3vyBwY!wWwxs+4$ cQZm!HwDh?+(d0J&V&1{X22s0tFY9tn00RIV@Bjb+ diff --git a/res/gamedata/shaders/gl/combine_volumetric.ps b/res/gamedata/shaders/gl/combine_volumetric.ps index c16fef51d9b4b033775ecb92c9cee7ed2b886a1e..14d810ca14e602390683f48322d0aa6fe0b3500d 100644 GIT binary patch delta 9 QcmZo-Z)V@n#LUPA01h7lQ~&?~ delta 7 OcmZo>Z(`rj#0&rlg91qa diff --git a/res/gamedata/shaders/gl/common_policies.h b/res/gamedata/shaders/gl/common_policies.h index bd77da3d37c..64180fb6a06 100644 --- a/res/gamedata/shaders/gl/common_policies.h +++ b/res/gamedata/shaders/gl/common_policies.h @@ -3,7 +3,7 @@ // Define default sample index for MSAA #ifndef ISAMPLE -#define ISAMPLE 0 +#define ISAMPLE uint(0) #endif // ISAMPLE // redefine sample index @@ -36,4 +36,4 @@ # endif #endif -#endif // common_policies_h_included \ No newline at end of file +#endif // common_policies_h_included diff --git a/res/gamedata/shaders/gl/copy.ps b/res/gamedata/shaders/gl/copy.ps index 7a876e8293eb5a2d34b74db0a88246f570b2c623..39bc549e171b34b3e0bd6a1eac1b59ec0e115ae9 100644 GIT binary patch delta 18 ZcmaFO@{whNDSK&VUWtZ*=0-D9CICW%1`q%M delta 12 Tcmey!@|tCWDWkzg8&f6#AEN{R diff --git a/res/gamedata/shaders/gl/copy_p.ps b/res/gamedata/shaders/gl/copy_p.ps index 93cae92af0d9e2881a549c08d33f5b3f4c47c38b..a48a59108739c212fa3ffde307ce44b0f25e241e 100644 GIT binary patch delta 32 ncmcb_dXsg6DSv5ZUWtZ*CYN$*UP@*f*W~+*QX39VLwEzkw delta 12 Tcmcb~dWm&{DWkzgn>kDX9%}?Q diff --git a/res/gamedata/shaders/gl/depth_downs.ps b/res/gamedata/shaders/gl/depth_downs.ps index 2e873d702578936c0a15c1ae8799c9d638bae8b9..3cb386cb92b905501a60c8bf0bbc77cd0b814b5c 100644 GIT binary patch delta 20 bcmZ33CwpmTUWtZ*=Eg30c1A7$OvnaB delta 12 TcmdnMzmk7KC!@i}3G(a!9smR> diff --git a/res/gamedata/shaders/gl/rain_apply_gloss.ps b/res/gamedata/shaders/gl/rain_apply_gloss.ps index c4494abd5543b3f8ff22610a5351852a339eaf03..c4129747305df0ff92b8e6ccd1e74210a6785ca2 100644 GIT binary patch delta 20 bcmdnWv4>+q6MJc9UWtZ*=Emkt%#2(BPe=yP delta 12 TcmdnPv6W*&6QjY#&P~h!A6Nvm diff --git a/res/gamedata/shaders/gl/rain_apply_normal.ps b/res/gamedata/shaders/gl/rain_apply_normal.ps index 92eda4013cd705a66f7a8f3adf8e6f45d660e660..3d7dcc9201f20694ddcec3e4bac7bc7be20d5327 100644 GIT binary patch delta 18 ZcmX@gcA9NME_-QaUWtZ*=El71OaMZA2HF4s delta 12 TcmX@jc9d;GE~CN5lIu(WANvH! diff --git a/res/gamedata/shaders/gl/rain_patch_normal.ps b/res/gamedata/shaders/gl/rain_patch_normal.ps index 4e0b8fecdabc39da236f9ffc94ea92d6ee3db91d..e151a66efe424f1d41f68497951e7a3a20bf119e 100644 GIT binary patch delta 20 bcmaDa|5biN2n%~@W?qSgf#&8=mRZ~YRM-b3 delta 14 Vcmew=|6YDW2n(aZ=4h5#+yE@$1rq=O diff --git a/res/gamedata/shaders/gl/rain_patch_normal_new.ps b/res/gamedata/shaders/gl/rain_patch_normal_new.ps index 503d36bc637097db5cd1e0a27ac3b19ec450aac1..714d29f2aede43ccc541f96b1e9f01429546d4b1 100644 GIT binary patch delta 22 dcmbOuzgT`l4hwr}W?qSgf#&917JY6;E&x^@22TJ0 delta 14 VcmZ21KSzE;4hy5f=3*9oZU7|X1Tz2t diff --git a/res/gamedata/shaders/gl/ssao_calc.ps b/res/gamedata/shaders/gl/ssao_calc.ps index 6944095447845eece2cf43756f7cb222568e469a..244f37d970d3bbee65faf5f9ef0cacbaa0fa1fec 100644 GIT binary patch delta 18 Zcmcc4dY5&ADSK&VUWtZ*=0>xHOaMUB237z7 delta 12 Tcmcc1dYyHGDWkzgn}tjO9@hj# diff --git a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp index 31b85d91c4d..de45da1b898 100644 --- a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp +++ b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp @@ -222,6 +222,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, string32 c_sun_shafts; string32 c_ssao; string32 c_sun_quality; + string32 c_isample; string32 c_water_reflection; // TODO: OGL: Implement these parameters. @@ -436,17 +437,9 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, appendShaderOption(o.msaa_samples, "MSAA_SAMPLES", samples); } - { - static char def[2]; - if (m_MSAASample < 0) - def[0] = '0'; - else - def[0] = '0' + char(m_MSAASample); - - def[1] = 0; - options.add("ISAMPLE", def); - sh_name.append(static_cast(0)); - } + xr_sprintf(c_isample, "uint(%d)", m_MSAASample); + options.add("ISAMPLE", c_isample); + sh_name.append(static_cast(0)); appendShaderOption(o.msaa_opt, "MSAA_OPTIMIZATION", "1"); From 72e5e58e52c8258fa1b43bc7ce0fcd6b0263183e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 2 Jun 2024 02:07:44 +0500 Subject: [PATCH 461/497] xrRender_GL: improve shader generation code --- src/Layers/xrRenderPC_GL/rgl_shaders.cpp | 29 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp index de45da1b898..c7d0d76a1f6 100644 --- a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp +++ b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp @@ -88,6 +88,11 @@ class shader_options_holder string512 m_options[128]; public: + void add(cpcstr string) + { + strconcat(m_options[pos++], string, "\n"); + } + void add(cpcstr name, cpcstr value) { // It's important to have postfix increment! @@ -191,15 +196,10 @@ class shader_sources_manager void apply_options(shader_options_holder& options) { // Compile sources list - const size_t head_lines = 2; // "#version" line + name_comment line + constexpr size_t head_lines = 1; // name_comment line m_sources_lines = m_source.size() + options.size() + head_lines; m_sources = xr_alloc(m_sources_lines); -#ifdef DEBUG - m_sources[0] = "#version 410\n#pragma optimize (off)\n"; -#else - m_sources[0] = "#version 410\n"; -#endif - m_sources[1] = m_name_comment; + m_sources[0] = m_name_comment; // Make define lines for (size_t i = 0; i < options.size(); ++i) @@ -238,6 +238,18 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, sh_name.append(option); }; + options.add("#version 410"); + +#ifdef DEBUG + options.add("#pragma optimize (off)"); + sh_name.append(0u); +#else + options.add("#pragma optimize (on)"); + sh_name.append(1u); +#endif + + options.add("#extension GL_ARB_separate_shader_objects : enable"); + // Shadow map size { xr_itoa(m_SMAPSize, c_smapsize, 10); @@ -483,9 +495,6 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, sh_name.append(static_cast(0)); // DX10_1_NATIVE off } - // Don't mix optimized and unoptimized shaders - sh_name.append(static_cast(shader_sources_manager::optimized())); - // finish options.finish(); sh_name.finish(); From 6a16bdc20a7df5d116b66894a776d4288d6c5e30 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Sun, 2 Jun 2024 17:10:57 +0500 Subject: [PATCH 462/497] Fix build on Alpine Linux Yes. This needs to be cleaned up. --- src/Common/PlatformLinux.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index a65ea5b68fe..fcdf140c8a2 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -12,6 +12,7 @@ #include // for PAGESIZE... #include #include +#include #include // for min max From 7d236bffdf7bf943279d65f9dc38d52dcaabf830 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 2 Jun 2024 17:46:49 +0500 Subject: [PATCH 463/497] Properly fix builds for platforms with nullptr missing from global space --- src/Common/PlatformLinux.inl | 1 - src/xrCore/xrstring.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Common/PlatformLinux.inl b/src/Common/PlatformLinux.inl index fcdf140c8a2..a65ea5b68fe 100644 --- a/src/Common/PlatformLinux.inl +++ b/src/Common/PlatformLinux.inl @@ -12,7 +12,6 @@ #include // for PAGESIZE... #include #include -#include #include // for min max diff --git a/src/xrCore/xrstring.h b/src/xrCore/xrstring.h index 2c0b837450d..e0d42e6fee0 100644 --- a/src/xrCore/xrstring.h +++ b/src/xrCore/xrstring.h @@ -88,7 +88,7 @@ class shared_str _dec(); p_ = v; } - void _set(nullptr_t) noexcept + void _set(std::nullptr_t) noexcept { _dec(); p_ = nullptr; @@ -133,7 +133,7 @@ class shared_str rhs.p_ = nullptr; return *this; } - shared_str& operator=(nullptr_t) noexcept + shared_str& operator=(std::nullptr_t) noexcept { _set(nullptr); return *this; From b4afaa4a90c826afd3c9b1a1be9370fdd2775924 Mon Sep 17 00:00:00 2001 From: yohjimane Date: Sun, 2 Jun 2024 06:40:17 -0700 Subject: [PATCH 464/497] ImGui Hud Tuner (#1685) Co-authored-by: Sultan Uramaev --- src/Layers/xrRender/ParticleEffect.cpp | 4 +- src/Layers/xrRender/r__dsgraph_render.cpp | 2 +- src/xrEngine/device.h | 1 + src/xrEngine/editor_base.h | 4 + src/xrGame/ActorInput.cpp | 19 +- src/xrGame/CMakeLists.txt | 1 + src/xrGame/GamePersistent.h | 6 + src/xrGame/HudItem.cpp | 50 +- src/xrGame/HudItem.h | 4 +- src/xrGame/Missile.cpp | 5 +- src/xrGame/UIGameSP.cpp | 13 - src/xrGame/Weapon.cpp | 30 +- src/xrGame/Weapon.h | 1 - src/xrGame/attachable_item.cpp | 95 ---- src/xrGame/player_hud.cpp | 5 +- src/xrGame/player_hud.h | 1 - src/xrGame/player_hud_tune.cpp | 542 +++++++++------------- src/xrGame/player_hud_tune.h | 73 +++ src/xrGame/xrGame.vcxproj | 1 + src/xrGame/xrGame.vcxproj.filters | 3 + 20 files changed, 386 insertions(+), 474 deletions(-) create mode 100644 src/xrGame/player_hud_tune.h diff --git a/src/Layers/xrRender/ParticleEffect.cpp b/src/Layers/xrRender/ParticleEffect.cpp index 6a5995042ae..5add4574b31 100644 --- a/src/Layers/xrRender/ParticleEffect.cpp +++ b/src/Layers/xrRender/ParticleEffect.cpp @@ -673,7 +673,7 @@ void CParticleEffect::Render(CBackend& cmd_list, float, bool use_fast_geo) Fmatrix FTold = Device.mFullTransform; if (GetHudMode()) { - Device.mProject.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, VIEWPORT_NEAR, + Device.mProject.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, HUD_VIEWPORT_NEAR, g_pGamePersistent->Environment().CurrentEnv.far_plane); Device.mFullTransform.mul(Device.mProject, Device.mView); @@ -841,7 +841,7 @@ void CParticleEffect::Render(float, bool) Fmatrix FTold = Device.mFullTransform; if (GetHudMode()) { - Device.mProject.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, VIEWPORT_NEAR, + Device.mProject.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, HUD_VIEWPORT_NEAR, g_pGamePersistent->Environment().CurrentEnv.far_plane); Device.mFullTransform.mul(Device.mProject, Device.mView); diff --git a/src/Layers/xrRender/r__dsgraph_render.cpp b/src/Layers/xrRender/r__dsgraph_render.cpp index 5a5b21718a9..86b1eba36ce 100644 --- a/src/Layers/xrRender/r__dsgraph_render.cpp +++ b/src/Layers/xrRender/r__dsgraph_render.cpp @@ -167,7 +167,7 @@ class hud_transform_helper Fmatrix prj_new; prj_new.build_projection(deg2rad(psHUD_FOV * Device.fFOV /* *Device.fASPECT*/), Device.fASPECT, - VIEWPORT_NEAR, g_pGamePersistent->Environment().CurrentEnv.far_plane); + HUD_VIEWPORT_NEAR, g_pGamePersistent->Environment().CurrentEnv.far_plane); cmd_list.set_xform_project(prj_new); RImplementation.rmNear(cmd_list); diff --git a/src/xrEngine/device.h b/src/xrEngine/device.h index 424386ab24c..26afdd47581 100644 --- a/src/xrEngine/device.h +++ b/src/xrEngine/device.h @@ -16,6 +16,7 @@ #include "xrCore/ModuleLookup.hpp" #define VIEWPORT_NEAR 0.2f +#define HUD_VIEWPORT_NEAR 0.05f #define DEVICE_RESET_PRECACHE_FRAME_COUNT 10 diff --git a/src/xrEngine/editor_base.h b/src/xrEngine/editor_base.h index fbc728bea9c..b8e440b29a3 100644 --- a/src/xrEngine/editor_base.h +++ b/src/xrEngine/editor_base.h @@ -20,6 +20,9 @@ class XR_NOVTABLE ENGINE_API ide_tool : public pureFrame virtual pcstr tool_name() = 0; bool& get_open_state() { return is_opened; } + bool is_open() const { return is_opened; } + virtual bool is_active() const { return is_opened; } + ImGuiWindowFlags get_default_window_flags() const; }; @@ -57,6 +60,7 @@ class ENGINE_API ide final : auto GetState() const { return m_state; } void SetState(visible_state state); void SwitchToNextState(); + bool IsActiveState() const { return m_state == visible_state::full; } public: // Interface implementations diff --git a/src/xrGame/ActorInput.cpp b/src/xrGame/ActorInput.cpp index 3c71e5521a2..a303d52ad87 100644 --- a/src/xrGame/ActorInput.cpp +++ b/src/xrGame/ActorInput.cpp @@ -30,14 +30,13 @@ #include "clsid_game.h" #include "HUDManager.h" #include "Weapon.h" - -extern u32 hud_adj_mode; +#include "GamePersistent.h" bool g_bAutoClearCrouch = true; void CActor::IR_OnKeyboardPress(int cmd) { - if (hud_adj_mode && pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)) + if (GamePersistent().GetHudTuner().is_active()) return; if (Remote()) @@ -213,11 +212,8 @@ void CActor::IR_OnKeyboardPress(int cmd) void CActor::IR_OnMouseWheel(float x, float y) { - if (hud_adj_mode) - { - g_player_hud->tune({ 0, 0, static_cast(std::round(y)) }); + if (GamePersistent().GetHudTuner().is_active()) return; - } if (inventory().Action((y > 0) ? (u16)kWPN_ZOOM_INC : (u16)kWPN_ZOOM_DEC, CMD_START)) return; @@ -230,7 +226,7 @@ void CActor::IR_OnMouseWheel(float x, float y) void CActor::IR_OnKeyboardRelease(int cmd) { - if (hud_adj_mode && pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)) + if (GamePersistent().GetHudTuner().is_active()) return; if (Remote()) @@ -272,7 +268,7 @@ void CActor::IR_OnKeyboardRelease(int cmd) void CActor::IR_OnKeyboardHold(int cmd) { - if (hud_adj_mode && pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)) + if (GamePersistent().GetHudTuner().is_active()) return; if (Remote() || !g_Alive()) @@ -352,11 +348,8 @@ void CActor::OnAxisMove(float x, float y, float scale, bool invert) void CActor::IR_OnMouseMove(int dx, int dy) { - if (hud_adj_mode) - { - g_player_hud->tune(Ivector().set(dx, dy, 0)); + if (GamePersistent().GetHudTuner().is_active()) return; - } PIItem iitem = inventory().ActiveItem(); if (iitem && iitem->cast_hud_item()) diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index 02b4ec50002..a0850bdbc35 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -1005,6 +1005,7 @@ target_sources(xrGame PRIVATE player_hud.cpp player_hud.h player_hud_tune.cpp + player_hud_tune.h player_name_modifyer.cpp player_name_modifyer.h player_spot_params.cpp diff --git a/src/xrGame/GamePersistent.h b/src/xrGame/GamePersistent.h index 8ed8431e976..1b5c7df47f6 100644 --- a/src/xrGame/GamePersistent.h +++ b/src/xrGame/GamePersistent.h @@ -3,6 +3,7 @@ #pragma once #include "xrEngine/IGame_Persistent.h" +#include "player_hud_tune.h" class Task; class CMainMenu; @@ -40,6 +41,9 @@ class CGamePersistent : public IGame_Persistent fastdelegate::FastDelegate0<> m_intro_event; + // hud tuner + CHudTuner m_hudTuner; + void start_logo_intro(); void update_logo_intro(); @@ -101,6 +105,8 @@ class CGamePersistent : public IGame_Persistent virtual void SetBaseDof(const Fvector3& dof); virtual void OnSectorChanged(IRender_Sector::sector_id_t sector); virtual void OnAssetsChanged(); + + CHudTuner GetHudTuner() { return m_hudTuner; } }; IC CGamePersistent& GamePersistent() { return *((CGamePersistent*)g_pGamePersistent); } diff --git a/src/xrGame/HudItem.cpp b/src/xrGame/HudItem.cpp index 6e8bae3a1d0..0cecb3cf54e 100644 --- a/src/xrGame/HudItem.cpp +++ b/src/xrGame/HudItem.cpp @@ -75,7 +75,6 @@ void CHudItem::renderable_Render(u32 context_id, IRenderable* root) if (!object().H_Parent() || (!_hud_render && !IsHidden())) { on_renderable_Render(context_id, root); - debug_draw_firedeps(); } else if (object().H_Parent()) { @@ -431,6 +430,55 @@ void CHudItem::OnMovementChanged(ACTOR_DEFS::EMoveCommand cmd) } } +extern ENGINE_API float psHUD_FOV; +void CHudItem::TransformPosFromWorldToHud(Fvector& worldPos) +{ + CActor* actor = smart_cast(object().H_Parent()); + + Fmatrix mView; + mView.set(Device.mView); + if (GetHUDmode() && actor) + { + Fmatrix trans; + actor->Cameras().hud_camera_Matrix(trans); + mView.build_camera_dir(trans.c, trans.k, trans.j); + } + + Fmatrix hud_project; + hud_project.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, HUD_VIEWPORT_NEAR, + g_pGamePersistent->Environment().CurrentEnv.far_plane); + + mView.transform_tiny(worldPos); + hud_project.transform_tiny(worldPos); + + Fmatrix().set(Device.mProject).invert().transform_tiny(worldPos); + Fmatrix().set(mView).invert().transform_tiny(worldPos); +} + +void CHudItem::TransformDirFromWorldToHud(Fvector& worldDir) +{ + CActor* actor = smart_cast(object().H_Parent()); + + Fmatrix mView; + mView.set(Device.mView); + if (GetHUDmode() && actor) + { + Fmatrix trans; + actor->Cameras().hud_camera_Matrix(trans); + mView.build_camera_dir(trans.c, trans.k, trans.j); + } + + Fmatrix hud_project; + hud_project.build_projection(deg2rad(psHUD_FOV * Device.fFOV), Device.fASPECT, HUD_VIEWPORT_NEAR, + g_pGamePersistent->Environment().CurrentEnv.far_plane); + + mView.transform_dir(worldDir); + hud_project.transform_dir(worldDir); + + Fmatrix().set(Device.mProject).invert().transform_dir(worldDir); + Fmatrix().set(mView).invert().transform_dir(worldDir); +} + attachable_hud_item* CHudItem::HudItemData() const { attachable_hud_item* hi = NULL; diff --git a/src/xrGame/HudItem.h b/src/xrGame/HudItem.h index f11c3820bd0..0ce80570238 100644 --- a/src/xrGame/HudItem.h +++ b/src/xrGame/HudItem.h @@ -93,6 +93,9 @@ class CHudItem : public CHUDState virtual bool Action(u16 cmd, u32 flags) { return false; } void OnMovementChanged(ACTOR_DEFS::EMoveCommand cmd); + virtual void TransformPosFromWorldToHud(Fvector& worldPos); + virtual void TransformDirFromWorldToHud(Fvector& worldDir); + virtual u8 GetCurrentHudOffsetIdx() { return 0; } BOOL GetHUDmode(); IC BOOL IsPending() const { return !!m_huditem_flags.test(fl_pending); } @@ -178,7 +181,6 @@ class CHudItem : public CHUDState } IC u32 animation_slot() { return m_animation_slot; } virtual void on_renderable_Render(u32 context_id, IRenderable* root) = 0; - virtual void debug_draw_firedeps(){}; virtual CHudItem* cast_hud_item() { return this; } void PlayAnimIdleMovingCrouch(); //AVO: new crouch idle animation diff --git a/src/xrGame/Missile.cpp b/src/xrGame/Missile.cpp index 06d3bc33feb..a86f382bd1c 100644 --- a/src/xrGame/Missile.cpp +++ b/src/xrGame/Missile.cpp @@ -24,6 +24,7 @@ #include "xrUICore/ProgressBar/UIProgressShape.h" #include "ui/UIXmlInit.h" #include "PhysicsShellHolder.h" +#include "GamePersistent.h" CUIProgressShape* g_MissileForceShape = NULL; @@ -188,8 +189,6 @@ void CMissile::OnH_B_Independent(bool just_before_destroy) } } -extern u32 hud_adj_mode; - void CMissile::UpdateCL() { m_dwStateTime += Device.dwTimeDelta; @@ -199,7 +198,7 @@ void CMissile::UpdateCL() CActor* pActor = smart_cast(H_Parent()); if (pActor && !pActor->AnyMove() && this == pActor->inventory().ActiveItem()) { - if (hud_adj_mode == 0 && GetState() == eIdle && (Device.dwTimeGlobal - m_dw_curr_substate_time > 20000)) + if (!GamePersistent().GetHudTuner().is_active() && GetState() == eIdle && (Device.dwTimeGlobal - m_dw_curr_substate_time > 20000)) { SwitchState(eBore); ResetSubStateTime(); diff --git a/src/xrGame/UIGameSP.cpp b/src/xrGame/UIGameSP.cpp index 6da0f630772..7399921e8b2 100644 --- a/src/xrGame/UIGameSP.cpp +++ b/src/xrGame/UIGameSP.cpp @@ -60,12 +60,6 @@ void CUIGameSP::SetClGame(game_cl_GameState* g) m_game = smart_cast(g); R_ASSERT(m_game); } -#ifdef DEBUG -void attach_adjust_mode_keyb(int dik); -void attach_draw_adjust_mode(); -void hud_adjust_mode_keyb(int dik); -void hud_draw_adjust_mode(); -#endif void CUIGameSP::OnFrame() { @@ -109,11 +103,6 @@ bool CUIGameSP::IR_UIOnKeyboardPress(int dik) if (Device.Paused()) return false; -#ifdef DEBUG - hud_adjust_mode_keyb(dik); - attach_adjust_mode_keyb(dik); -#endif - CInventoryOwner* pInvOwner = smart_cast(Level().CurrentEntity()); if (!pInvOwner) return false; @@ -182,8 +171,6 @@ bool CUIGameSP::IR_UIOnKeyboardPress(int dik) void CUIGameSP::Render() { inherited::Render(); - hud_draw_adjust_mode(); - attach_draw_adjust_mode(); } #endif diff --git a/src/xrGame/Weapon.cpp b/src/xrGame/Weapon.cpp index c8c48fdbe0c..c556cb13eba 100644 --- a/src/xrGame/Weapon.cpp +++ b/src/xrGame/Weapon.cpp @@ -27,6 +27,7 @@ #include "Torch.h" #include "xrNetServer/NET_Messages.h" #include "xrCore/xr_token.h" +#include "GamePersistent.h" #define WEAPON_REMOVE_TIME 60000 #define ROTATION_TIME 0.25f @@ -857,7 +858,6 @@ void CWeapon::OnH_B_Chield() m_set_next_ammoType_on_reload = undefined_ammo_type; } -extern u32 hud_adj_mode; bool CWeapon::AllowBore() { return true; } void CWeapon::UpdateCL() { @@ -878,7 +878,7 @@ void CWeapon::UpdateCL() CActor* pActor = smart_cast(H_Parent()); if (pActor && !pActor->AnyMove() && this == pActor->inventory().ActiveItem()) { - if (hud_adj_mode == 0 && GetState() == eIdle && (Device.dwTimeGlobal - m_dw_curr_substate_time > 20000) && + if (!GamePersistent().GetHudTuner().is_active() && GetState() == eIdle && (Device.dwTimeGlobal - m_dw_curr_substate_time > 20000) && !IsZoomed() && g_player_hud->attached_item(1) == nullptr) { if (AllowBore()) @@ -1297,6 +1297,8 @@ bool CWeapon::SilencerAttachable() { return (ALife::eAddonAttachable == m_eSilen void CWeapon::UpdateHUDAddonsVisibility() { + if (GamePersistent().GetHudTuner().is_active()) + return; static shared_str wpn_scope = WPN_SCOPE; static shared_str wpn_silencer = WPN_SILENCER; static shared_str wpn_grenade_launcher = WPN_GRENADE_LAUNCHER; @@ -1344,6 +1346,9 @@ void CWeapon::UpdateHUDAddonsVisibility() void CWeapon::UpdateAddonsVisibility() { + if (GamePersistent().GetHudTuner().is_active()) + return; + static shared_str wpn_scope = WPN_SCOPE; static shared_str wpn_silencer = WPN_SILENCER; static shared_str wpn_grenade_launcher = WPN_GRENADE_LAUNCHER; @@ -1894,27 +1899,6 @@ BOOL CWeapon::ParentIsActor() return EA->cast_actor() != nullptr; } -extern u32 hud_adj_mode; - -void CWeapon::debug_draw_firedeps() -{ -#ifdef DEBUG - if (hud_adj_mode == 5 || hud_adj_mode == 6 || hud_adj_mode == 7) - { - CDebugRenderer& render = Level().debug_renderer(); - - if (hud_adj_mode == 5) - render.draw_aabb(get_LastFP(), 0.005f, 0.005f, 0.005f, color_xrgb(255, 0, 0)); - - if (hud_adj_mode == 6) - render.draw_aabb(get_LastFP2(), 0.005f, 0.005f, 0.005f, color_xrgb(0, 0, 255)); - - if (hud_adj_mode == 7) - render.draw_aabb(get_LastSP(), 0.005f, 0.005f, 0.005f, color_xrgb(0, 255, 0)); - } -#endif // DEBUG -} - const float& CWeapon::hit_probability() const { VERIFY((g_SingleGameDifficulty >= egdNovice) && (g_SingleGameDifficulty <= egdMaster)); diff --git a/src/xrGame/Weapon.h b/src/xrGame/Weapon.h index 922d7d219ed..c7d28d2b3eb 100644 --- a/src/xrGame/Weapon.h +++ b/src/xrGame/Weapon.h @@ -311,7 +311,6 @@ class CWeapon : public CHudItemObject, public CShootingObject return m_current_firedeps.m_FireParticlesXForm; } virtual void ForceUpdateFireParticles(); - virtual void debug_draw_firedeps(); protected: virtual void SetDefaults(); diff --git a/src/xrGame/attachable_item.cpp b/src/xrGame/attachable_item.cpp index fdf8d7d56ca..9d7f6da8ee0 100644 --- a/src/xrGame/attachable_item.cpp +++ b/src/xrGame/attachable_item.cpp @@ -132,98 +132,3 @@ bool CAttachableItem::use_parent_ai_locations() const { return !enabled(); } - -#ifdef DEBUG -float ATT_ITEM_MOVE_CURR = 0.01f; -float ATT_ITEM_ROT_CURR = 0.1f; - -float ATT_ITEM_MOVE_STEP = 0.001f; -float ATT_ITEM_ROT_STEP = 0.01f; - -void attach_adjust_mode_keyb(int dik) -{ - if (!CAttachableItem::m_dbgItem) - return; - - bool b_move = !!(pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)); - bool b_rot = !!(pInput->iGetAsyncKeyState(SDL_SCANCODE_LALT)); - - int axis = -1; - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_Z)) - axis = 0; - else if (pInput->iGetAsyncKeyState(SDL_SCANCODE_X)) - axis = 1; - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_C)) - axis = 2; - - if (!b_move && !b_rot) - return; - - switch (dik) - { - case SDL_SCANCODE_LEFT: - { - if (b_move) - CAttachableItem::mov(axis, ATT_ITEM_MOVE_CURR); - else - CAttachableItem::rot(axis, ATT_ITEM_ROT_CURR); - } - break; - case SDL_SCANCODE_RIGHT: - { - if (b_move) - CAttachableItem::mov(axis, -ATT_ITEM_MOVE_CURR); - else - CAttachableItem::rot(axis, -ATT_ITEM_ROT_CURR); - } - break; - case SDL_SCANCODE_PAGEUP: - { - if (b_move) - ATT_ITEM_MOVE_CURR += ATT_ITEM_MOVE_STEP; - else - ATT_ITEM_ROT_CURR += ATT_ITEM_ROT_STEP; - } - break; - case SDL_SCANCODE_PAGEDOWN: - { - if (b_move) - ATT_ITEM_MOVE_CURR -= ATT_ITEM_MOVE_STEP; - else - ATT_ITEM_ROT_CURR -= ATT_ITEM_ROT_STEP; - } - break; - }; -} - -void attach_draw_adjust_mode() -{ - if (!CAttachableItem::m_dbgItem) - return; - - string1024 _text; - - CGameFont* F = UI().Font().pFontDI; - F->SetAligment(CGameFont::alCenter); - F->OutSetI(0.f, -0.8f); - F->SetColor(0xffffffff); - xr_sprintf(_text, "Adjusting attachable item [%s]", CAttachableItem::m_dbgItem->object().cNameSect().c_str()); - F->OutNext(_text); - xr_sprintf(_text, "move step [%3.3f] rotate step [%3.3f]", ATT_ITEM_MOVE_CURR, ATT_ITEM_ROT_CURR); - F->OutNext(_text); - - F->OutNext("HOLD LShift to move. ALT to rotate"); - F->OutNext("HOLD [Z]-x axis [X]-y axis [C]-z axis"); - - F->OutNext("RIGHT-LEFT - move. PgUP-PgDOWN - step"); - F->OutSkip(); - - Fvector _pos = CAttachableItem::get_pos_offset(); - xr_sprintf(_text, "attach_position_offset IS [%3.3f][%3.3f][%3.3f]", _pos.x, _pos.y, _pos.z); - F->OutNext(_text); - - Fvector _ang = CAttachableItem::get_angle_offset(); - xr_sprintf(_text, "attach_angle_offset IS [%3.3f][%3.3f][%3.3f]", _ang.x, _ang.y, _ang.z); - F->OutNext(_text); -} -#endif // #ifdef DEBUG diff --git a/src/xrGame/player_hud.cpp b/src/xrGame/player_hud.cpp index ae82710b3a8..9489b2cdec1 100644 --- a/src/xrGame/player_hud.cpp +++ b/src/xrGame/player_hud.cpp @@ -7,8 +7,8 @@ #include "static_cast_checked.hpp" #include "ActorEffector.h" #include "WeaponMagazinedWGrenade.h" // XXX: move somewhere +#include "GamePersistent.h" -extern u32 hud_adj_mode; player_hud* g_player_hud = nullptr; extern ENGINE_API shared_str current_player_hud_sect; // clang-format off @@ -131,7 +131,7 @@ void attachable_hud_item::update(bool bForce) reload_measures(); } - if (hud_adj_mode > 0) + if (GamePersistent().GetHudTuner().is_active()) m_measures.update(m_attach_offset); m_parent->calc_transform(m_attach_place_idx, m_attach_offset, m_item_transform); @@ -199,7 +199,6 @@ bool attachable_hud_item::need_renderable() const { return m_parent_hud_item->ne void attachable_hud_item::render(u32 context_id, IRenderable* root) { GEnv.Render->add_Visual(context_id, root, m_model->dcast_RenderVisual(), m_item_transform); - debug_draw_firedeps(); m_parent_hud_item->render_hud_mode(); } diff --git a/src/xrGame/player_hud.h b/src/xrGame/player_hud.h index cbba3c8e909..28acd5eaf5b 100644 --- a/src/xrGame/player_hud.h +++ b/src/xrGame/player_hud.h @@ -108,7 +108,6 @@ struct attachable_hud_item bool render_item_ui_query() const; bool need_renderable() const; void set_bone_visible(const shared_str& bone_name, BOOL bVisibility, BOOL bSilent = FALSE); - void debug_draw_firedeps(); // hands bind position Fvector& hands_attach_pos(); diff --git a/src/xrGame/player_hud_tune.cpp b/src/xrGame/player_hud_tune.cpp index 087b4108cb7..528b568df9c 100644 --- a/src/xrGame/player_hud_tune.cpp +++ b/src/xrGame/player_hud_tune.cpp @@ -11,372 +11,280 @@ #include "xrUICore/ui_base.h" #include "debug_renderer.h" #include "xrEngine/GameFont.h" +#include "player_hud_tune.h" -u32 hud_adj_mode = 0; -u32 hud_adj_item_idx = 0; -// "press SHIFT+NUM 0-return 1-hud_pos 2-hud_rot 3-itm_pos 4-itm_rot 5-fire_point 6-fire_2_point 7-shell_point"; +extern ENGINE_API float psHUD_FOV; -float _delta_pos = 0.0005f; -float _delta_rot = 0.05f; +CHudTuner::CHudTuner() +{ + ImGui::SetCurrentContext(Device.GetImGuiContext()); + paused = fsimilar(Device.time_factor(), EPS); +} -bool is_attachable_item_tuning_mode() +bool CHudTuner::is_active() const { - return pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT) || pInput->iGetAsyncKeyState(SDL_SCANCODE_Z) || - pInput->iGetAsyncKeyState(SDL_SCANCODE_X) || pInput->iGetAsyncKeyState(SDL_SCANCODE_C); + return is_open() && Device.editor().IsActiveState(); } -void tune_remap(const Ivector& in_values, Ivector& out_values) +void CHudTuner::ResetToDefaultValues() { - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)) + if (current_hud_item) { - out_values = in_values; - } - else if (pInput->iGetAsyncKeyState(SDL_SCANCODE_Z)) - { // strict by X - out_values.x = in_values.y; - out_values.y = 0; - out_values.z = 0; - } - else if (pInput->iGetAsyncKeyState(SDL_SCANCODE_X)) - { // strict by Y - out_values.x = 0; - out_values.y = in_values.y; - out_values.z = 0; - } - else if (pInput->iGetAsyncKeyState(SDL_SCANCODE_C)) - { // strict by Z - out_values.x = 0; - out_values.y = 0; - out_values.z = in_values.y; + current_hud_item->reload_measures(); + curr_measures = current_hud_item->m_measures; } else { - out_values.set(0, 0, 0); + Fvector zero = { 0, 0, 0 }; + curr_measures.m_hands_attach[0] = zero; + curr_measures.m_hands_attach[1] = zero; + curr_measures.m_hands_offset[0][0] = zero; + curr_measures.m_hands_offset[1][0] = zero; + curr_measures.m_hands_offset[0][1] = zero; + curr_measures.m_hands_offset[1][1] = zero; + curr_measures.m_hands_offset[0][2] = zero; + curr_measures.m_hands_offset[1][2] = zero; + curr_measures.m_item_attach[0] = zero; + curr_measures.m_item_attach[1] = zero; + curr_measures.m_fire_point_offset = zero; + curr_measures.m_fire_point2_offset = zero; + curr_measures.m_shell_point_offset = zero; } -} -void calc_cam_diff_pos(Fmatrix item_transform, Fvector diff, Fvector& res) -{ - Fmatrix cam_m; - cam_m.i.set(Device.vCameraRight); - cam_m.j.set(Device.vCameraTop); - cam_m.k.set(Device.vCameraDirection); - cam_m.c.set(Device.vCameraPosition); - - Fvector res1; - cam_m.transform_dir(res1, diff); - - Fmatrix item_transform_i; - item_transform_i.invert(item_transform); - item_transform_i.transform_dir(res, res1); + new_measures = curr_measures; } -void calc_cam_diff_rot(Fmatrix item_transform, Fvector diff, Fvector& res) +void CHudTuner::UpdateValues() { - Fmatrix cam_m; - cam_m.i.set(Device.vCameraRight); - cam_m.j.set(Device.vCameraTop); - cam_m.k.set(Device.vCameraDirection); - cam_m.c.set(Device.vCameraPosition); - - Fmatrix R; - R.identity(); - if (!fis_zero(diff.x)) - { - R.rotation(cam_m.i, diff.x); - } - else if (!fis_zero(diff.y)) - { - R.rotation(cam_m.j, diff.y); - } - else if (!fis_zero(diff.z)) + if (current_hud_item) { - R.rotation(cam_m.k, diff.z); - }; + new_measures.m_hands_attach[0].set(curr_measures.m_hands_attach[0]); + new_measures.m_hands_attach[1].set(curr_measures.m_hands_attach[1]); + new_measures.m_hands_attach[0].add(new_measures.m_hands_offset[0][0]); + new_measures.m_hands_attach[1].add(new_measures.m_hands_offset[1][0]); - Fmatrix item_transform_i; - item_transform_i.invert(item_transform); - R.mulB_43(item_transform); - R.mulA_43(item_transform_i); - - R.getHPB(res); - - res.mul(180.0f / PI); + current_hud_item->m_measures = new_measures; + } } -void attachable_hud_item::tune(Ivector values) +void CHudTuner::OnFrame() { #ifndef MASTER_GOLD - if (!is_attachable_item_tuning_mode()) + if (!get_open_state()) return; - Fvector diff; - diff.set(0, 0, 0); + if (!g_player_hud) + return; - if (hud_adj_mode == 3 || hud_adj_mode == 4) + auto hud_item = g_player_hud->attached_item(current_hud_idx); + if (current_hud_item != hud_item) { - if (hud_adj_mode == 3) - { - if (values.x) - diff.x = (values.x > 0) ? _delta_pos : -_delta_pos; - if (values.y) - diff.y = (values.y > 0) ? _delta_pos : -_delta_pos; - if (values.z) - diff.z = (values.z > 0) ? _delta_pos : -_delta_pos; - - Fvector d; - Fmatrix ancor_m; - m_parent->calc_transform(m_attach_place_idx, Fidentity, ancor_m); - calc_cam_diff_pos(ancor_m, diff, d); - m_measures.m_item_attach[0].add(d); - } - else if (hud_adj_mode == 4) - { - if (values.x) - diff.x = (values.x > 0) ? _delta_rot : -_delta_rot; - if (values.y) - diff.y = (values.y > 0) ? _delta_rot : -_delta_rot; - if (values.z) - diff.z = (values.z > 0) ? _delta_rot : -_delta_rot; - - Fvector d; - Fmatrix ancor_m; - m_parent->calc_transform(m_attach_place_idx, Fidentity, ancor_m); - - calc_cam_diff_pos(m_item_transform, diff, d); - m_measures.m_item_attach[1].add(d); - } - - if ((values.x) || (values.y) || (values.z)) - { - Msg("[%s]", m_sect_name.c_str()); - Msg("item_position = %f,%f,%f", m_measures.m_item_attach[0].x, m_measures.m_item_attach[0].y, - m_measures.m_item_attach[0].z); - Msg("item_orientation = %f,%f,%f", m_measures.m_item_attach[1].x, m_measures.m_item_attach[1].y, - m_measures.m_item_attach[1].z); - Log("-----------"); - } + current_hud_item = hud_item; + ResetToDefaultValues(); } - if (hud_adj_mode == 5 || hud_adj_mode == 6 || hud_adj_mode == 7) + if (ImGui::Begin(tool_name(), &get_open_state(), get_default_window_flags())) { - if (values.x) - diff.x = (values.x > 0) ? _delta_pos : -_delta_pos; - if (values.y) - diff.y = (values.y > 0) ? _delta_pos : -_delta_pos; - if (values.z) - diff.z = (values.z > 0) ? _delta_pos : -_delta_pos; - - if (hud_adj_mode == 5) + if (ImGui::BeginMenuBar()) { - m_measures.m_fire_point_offset.add(diff); - } - if (hud_adj_mode == 6) - { - m_measures.m_fire_point2_offset.add(diff); - } - if (hud_adj_mode == 7) - { - m_measures.m_shell_point_offset.add(diff); - } - if ((values.x) || (values.y) || (values.z)) - { - Msg("[%s]", m_sect_name.c_str()); - Msg("fire_point = %f,%f,%f", m_measures.m_fire_point_offset.x, m_measures.m_fire_point_offset.y, - m_measures.m_fire_point_offset.z); - Msg("fire_point2 = %f,%f,%f", m_measures.m_fire_point2_offset.x, - m_measures.m_fire_point2_offset.y, m_measures.m_fire_point2_offset.z); - Msg("shell_point = %f,%f,%f", m_measures.m_shell_point_offset.x, - m_measures.m_shell_point_offset.y, m_measures.m_shell_point_offset.z); - Log("-----------"); - } - } -#endif // #ifndef MASTER_GOLD -} - -void attachable_hud_item::debug_draw_firedeps() -{ -#ifdef DEBUG - bool bForce = (hud_adj_mode == 3 || hud_adj_mode == 4); - - if (hud_adj_mode == 5 || hud_adj_mode == 6 || hud_adj_mode == 7 || bForce) - { - CDebugRenderer& render = Level().debug_renderer(); - - firedeps fd; - setup_firedeps(fd); - - if (hud_adj_mode == 5 || bForce) - render.draw_aabb(fd.vLastFP, 0.005f, 0.005f, 0.005f, color_xrgb(255, 0, 0)); - - if (hud_adj_mode == 6) - render.draw_aabb(fd.vLastFP2, 0.005f, 0.005f, 0.005f, color_xrgb(0, 0, 255)); + if (ImGui::RadioButton("Pause", paused)) + { + paused = !paused; + float time_factor = 1.f; + if (paused) + { + time_factor = EPS; + } + Device.time_factor(time_factor); + } - if (hud_adj_mode == 7) - render.draw_aabb(fd.vLastSP, 0.005f, 0.005f, 0.005f, color_xrgb(0, 255, 0)); - } -#endif // DEBUG -} + ImGui::EndMenuBar(); + } -void player_hud::tune(Ivector _values) -{ -#ifndef MASTER_GOLD - Ivector values; - tune_remap(_values, values); + if (ImGui::CollapsingHeader("Main Settings", ImGuiTreeNodeFlags_DefaultOpen)) + { + if (ImGui::BeginCombo("Hud Item Mode", hud_item_mode[current_hud_idx])) + { + for (const auto& [idx, value] : hud_item_mode) + { + if (ImGui::Selectable(value, current_hud_idx == idx)) + { + current_hud_idx = idx; + } + } + ImGui::EndCombo(); + } - bool is_16x9 = UI().is_widescreen(); + ImGui::LabelText("Current item", "%s", hud_item ? hud_item->m_sect_name.c_str() : "none"); - if (hud_adj_mode == 1 || hud_adj_mode == 2) - { - Fvector diff; - diff.set(0, 0, 0); + ImGui::SliderFloat("HUD FOV", &psHUD_FOV, 0.1f, 1.0f); - float _curr_dr = _delta_rot; + ImGui::NewLine(); - attachable_hud_item* hi = m_attached_items[hud_adj_item_idx]; - if (!hi) - return; + ImGui::SliderFloat("Position step", &_delta_pos, 0.0000001f, 0.001f, "%.7f"); + ImGui::SliderFloat("Rotation step", &_delta_rot, 0.000001f, 0.1f, "%.6f"); - u8 idx = hi->m_parent_hud_item->GetCurrentHudOffsetIdx(); - if (idx) - _curr_dr /= 20.0f; + ImGui::DragFloat3(hud_adj_modes[HUD_POS], (float*)&new_measures.m_hands_offset[0][0], _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_ROT], (float*)&new_measures.m_hands_offset[1][0], _delta_rot, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_POS_AIM], (float*)&new_measures.m_hands_offset[0][1], _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_ROT_AIM], (float*)&new_measures.m_hands_offset[1][1], _delta_rot, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_POS_GL], (float*)&new_measures.m_hands_offset[0][2], _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_ROT_GL], (float*)&new_measures.m_hands_offset[1][2], _delta_rot, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[ITEM_POS], (float*)&new_measures.m_item_attach[0], _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[ITEM_ROT], (float*)&new_measures.m_item_attach[1], _delta_rot, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[FIRE_POINT], (float*)&new_measures.m_fire_point_offset, _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[FIRE_POINT_2], (float*)&new_measures.m_fire_point2_offset, _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[SHELL_POINT], (float*)&new_measures.m_shell_point_offset, _delta_pos, 0.f, 0.f, "%.7f"); - Fvector& pos_ = (idx != 0) ? hi->hands_offset_pos() : hi->hands_attach_pos(); - Fvector& rot_ = (idx != 0) ? hi->hands_offset_rot() : hi->hands_attach_rot(); + UpdateValues(); - if (hud_adj_mode == 1) - { - if (values.x) - diff.x = (values.x < 0) ? _delta_pos : -_delta_pos; - if (values.y) - diff.y = (values.y > 0) ? _delta_pos : -_delta_pos; - if (values.z) - diff.z = (values.z > 0) ? _delta_pos : -_delta_pos; - - pos_.add(diff); - } + string128 selectable; - if (hud_adj_mode == 2) - { - if (values.x) - diff.x = (values.x > 0) ? _curr_dr : -_curr_dr; - if (values.y) - diff.y = (values.y > 0) ? _curr_dr : -_curr_dr; - if (values.z) - diff.z = (values.z > 0) ? _curr_dr : -_curr_dr; - - rot_.add(diff); - } - if ((values.x) || (values.y) || (values.z)) - { - if (idx == 0) + if (current_hud_item) { - Msg("[%s]", hi->m_sect_name.c_str()); - Msg("hands_position%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); - Msg("hands_orientation%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); - Log("-----------"); - } - else if (idx == 1) - { - Msg("[%s]", hi->m_sect_name.c_str()); - Msg("aim_hud_offset_pos%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); - Msg("aim_hud_offset_rot%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); - Log("-----------"); + bool is_16x9 = UI().is_widescreen(); + shared_str m_sect_name = current_hud_item->m_sect_name; + + ImGuiIO& io = ImGui::GetIO(); + + if (ImGui::Button("Copy formatted values to clipboard")) + { + ImGui::LogToClipboard(); + xr_sprintf(selectable, "[%s]\n", m_sect_name.c_str()); + ImGui::LogText(selectable); + xr_sprintf(selectable, "hands_position%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[0][0].x, new_measures.m_hands_offset[0][0].y, new_measures.m_hands_offset[0][0].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "hands_orientation%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[1][0].x, new_measures.m_hands_offset[1][0].y, new_measures.m_hands_offset[1][0].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "aim_hud_offset_pos%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[0][1].x, new_measures.m_hands_offset[0][1].y, new_measures.m_hands_offset[0][1].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "aim_hud_offset_rot%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[1][1].x, new_measures.m_hands_offset[1][1].y, new_measures.m_hands_offset[1][1].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "gl_hud_offset_pos%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[0][2].x, new_measures.m_hands_offset[0][2].y, new_measures.m_hands_offset[0][2].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "gl_hud_offset_rot%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[1][2].x, new_measures.m_hands_offset[1][2].y, new_measures.m_hands_offset[1][2].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "item_position = %f,%f,%f\n", new_measures.m_item_attach[0].x, new_measures.m_item_attach[0].y, new_measures.m_item_attach[0].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "item_orientation = %f,%f,%f\n", new_measures.m_item_attach[1].x, new_measures.m_item_attach[1].y, new_measures.m_item_attach[1].z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "fire_point = %f,%f,%f\n", new_measures.m_fire_point_offset.x, new_measures.m_fire_point_offset.y, new_measures.m_fire_point_offset.z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "fire_point = %f,%f,%f\n", new_measures.m_fire_point2_offset.x, new_measures.m_fire_point2_offset.y, new_measures.m_fire_point2_offset.z); + ImGui::LogText(selectable); + xr_sprintf(selectable, "shell_point = %f,%f,%f\n", new_measures.m_shell_point_offset.x, new_measures.m_shell_point_offset.y, new_measures.m_shell_point_offset.z); + ImGui::LogText(selectable); + ImGui::LogFinish(); + } + + ImGui::NewLine(); + +#ifdef DEBUG + firedeps fd; + current_hud_item->setup_firedeps(fd); + collide::rq_result& RQ = HUD().GetCurrentRayQuery(); + + CDebugRenderer& render = Level().debug_renderer(); + + ImGui::SliderFloat("Debug Point Size", &debug_point_size, 0.00005f, 1.f, "%.5f"); + if (ImGui::RadioButton("Draw Fire Point", draw_fp)) { draw_fp = !draw_fp; }; ImGui::SameLine(); + if (ImGui::RadioButton("Draw Fire Point (GL)", draw_fp2)) { draw_fp2 = !draw_fp2; } ImGui::SameLine(); + if (ImGui::RadioButton("Draw Fire Direction", draw_fd)) { draw_fd = !draw_fd; } ImGui::SameLine(); + if (ImGui::RadioButton("Draw Fire Direction (GL)", draw_fd2)) { draw_fd2 = !draw_fd2; } ImGui::SameLine(); + if (ImGui::RadioButton("Draw Shell Point", draw_sp)) { draw_sp = !draw_sp; } + + if (draw_fp) + { + Fvector point; + point.set(fd.vLastFP); + current_hud_item->m_parent_hud_item->TransformPosFromWorldToHud(point); + render.draw_aabb(point, debug_point_size, debug_point_size, debug_point_size, color_xrgb(255, 0, 0)); + } + + if (draw_fp2) + { + Fvector point; + point.set(fd.vLastFP2); + current_hud_item->m_parent_hud_item->TransformPosFromWorldToHud(point); + render.draw_aabb(point, debug_point_size, debug_point_size, debug_point_size, color_xrgb(255, 0, 0)); + } + + if (draw_fd) + { + Fvector point; + Fvector dir; + point.set(fd.vLastFP); + dir.set(fd.vLastFD); + current_hud_item->m_parent_hud_item->TransformPosFromWorldToHud(point); + current_hud_item->m_parent_hud_item->TransformDirFromWorldToHud(dir); + + Fvector parallelPoint; + parallelPoint.set(point); + parallelPoint.mad(dir, RQ.range); + render.draw_aabb(parallelPoint, debug_point_size, debug_point_size, debug_point_size, color_xrgb(255, 0, 0)); + render.draw_line(Fidentity, point, parallelPoint, color_xrgb(255, 0, 0)); + } + + if (draw_fd2) + { + Fvector point; + Fvector dir; + point.set(fd.vLastFP2); + dir.set(fd.vLastFD); + current_hud_item->m_parent_hud_item->TransformPosFromWorldToHud(point); + current_hud_item->m_parent_hud_item->TransformDirFromWorldToHud(dir); + + Fvector parallelPoint; + parallelPoint.set(point); + parallelPoint.mad(dir, RQ.range); + render.draw_aabb(parallelPoint, debug_point_size, debug_point_size, debug_point_size, color_xrgb(255, 0, 0)); + render.draw_line(Fidentity, point, parallelPoint, color_xrgb(255, 0, 0)); + } + + if (draw_sp) + { + Fvector point; + point.set(fd.vLastSP); + current_hud_item->m_parent_hud_item->TransformPosFromWorldToHud(point); + render.draw_aabb(point, debug_point_size, debug_point_size, debug_point_size, color_xrgb(255, 0, 0)); + } +#endif // DEBUG } - else if (idx == 2) + + if (ImGui::Button("Reset to default values")) { - Msg("[%s]", hi->m_sect_name.c_str()); - Msg("gl_hud_offset_pos%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", pos_.x, pos_.y, pos_.z); - Msg("gl_hud_offset_rot%s = %f,%f,%f", (is_16x9) ? "_16x9" : "", rot_.x, rot_.y, rot_.z); - Log("-----------"); + ResetToDefaultValues(); } } - } - else if (hud_adj_mode == 8 || hud_adj_mode == 9) - { - if (hud_adj_mode == 8 && (values.z)) - _delta_pos += (values.z > 0) ? _delta_pos * 0.1f : _delta_pos * -0.1f; - if (hud_adj_mode == 9 && (values.z)) - _delta_rot += (values.z > 0) ? _delta_rot * .1f : _delta_rot * -0.1f; - } - else - { - attachable_hud_item* hi = m_attached_items[hud_adj_item_idx]; - if (!hi) - return; - hi->tune(values); - } -#endif // #ifndef MASTER_GOLD -} + if (current_hud_item && ImGui::CollapsingHeader("Bone and Animation Debugging", ImGuiTreeNodeFlags_DefaultOpen)) + { + IKinematics* ik = current_hud_item->m_model; + ImGui::Text("Bone Count = %i", ik->LL_BoneCount()); + ImGui::Text("Root Bone = %s", ik->LL_BoneName_dbg(ik->LL_GetBoneRoot())); -void hud_draw_adjust_mode() -{ - if (!hud_adj_mode) - return; + for (const auto& [bone_name, bone_id] : *ik->LL_Bones()) + { + if (bone_id == ik->LL_GetBoneRoot()) + continue; - LPCSTR _text = NULL; - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT) && hud_adj_mode) - _text = - "press SHIFT+NUM 0-return 1-hud_pos 2-hud_rot 3-itm_pos 4-itm_rot 5-fire_point 6-fire_2_point " - "7-shell_point " - "8-pos_step 9-rot_step"; + bool visible = ik->LL_GetBoneVisible(bone_id); + if (ImGui::RadioButton(bone_name.c_str(), visible)) { visible = !visible; }; ImGui::SameLine(); + ik->LL_SetBoneVisible(bone_id, visible, FALSE); + } - switch (hud_adj_mode) - { - case 1: _text = "adjusting HUD POSITION"; break; - case 2: _text = "adjusting HUD ROTATION"; break; - case 3: _text = "adjusting ITEM POSITION"; break; - case 4: _text = "adjusting ITEM ROTATION"; break; - case 5: _text = "adjusting FIRE POINT"; break; - case 6: _text = "adjusting FIRE 2 POINT"; break; - case 7: _text = "adjusting SHELL POINT"; break; - case 8: _text = "adjusting pos STEP"; break; - case 9: _text = "adjusting rot STEP"; break; - }; - if (_text) - { - CGameFont* F = UI().Font().pFontDI; - F->SetAligment(CGameFont::alCenter); - F->OutSetI(0.f, -0.8f); - F->SetColor(0xffffffff); - F->OutNext(_text); - F->OutNext("for item [%d]", hud_adj_item_idx); - F->OutNext("delta values dP=%f dR=%f", _delta_pos, _delta_rot); - F->OutNext("[Z]-x axis [X]-y axis [C]-z axis"); - } -} + ImGui::NewLine(); -void hud_adjust_mode_keyb(int dik) -{ - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LSHIFT)) - { - if (dik == SDL_SCANCODE_KP_0 || dik == SDL_SCANCODE_0) - hud_adj_mode = 0; - if (dik == SDL_SCANCODE_KP_1 || dik == SDL_SCANCODE_1) - hud_adj_mode = 1; - if (dik == SDL_SCANCODE_KP_2 || dik == SDL_SCANCODE_2) - hud_adj_mode = 2; - if (dik == SDL_SCANCODE_KP_3 || dik == SDL_SCANCODE_3) - hud_adj_mode = 3; - if (dik == SDL_SCANCODE_KP_4 || dik == SDL_SCANCODE_4) - hud_adj_mode = 4; - if (dik == SDL_SCANCODE_KP_5 || dik == SDL_SCANCODE_5) - hud_adj_mode = 5; - if (dik == SDL_SCANCODE_KP_6 || dik == SDL_SCANCODE_6) - hud_adj_mode = 6; - if (dik == SDL_SCANCODE_KP_7 || dik == SDL_SCANCODE_7) - hud_adj_mode = 7; - if (dik == SDL_SCANCODE_KP_8 || dik == SDL_SCANCODE_8) - hud_adj_mode = 8; - if (dik == SDL_SCANCODE_KP_9 || dik == SDL_SCANCODE_9) - hud_adj_mode = 9; - } - if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LCTRL)) - { - if (dik == SDL_SCANCODE_KP_0 || dik == SDL_SCANCODE_0) - hud_adj_item_idx = 0; - if (dik == SDL_SCANCODE_KP_1 || dik == SDL_SCANCODE_1) - hud_adj_item_idx = 1; + for (const auto& [anim_name, motion] : current_hud_item->m_hand_motions.m_anims) + { + if (ImGui::Button(anim_name.c_str())) + { + current_hud_item->m_parent_hud_item->PlayHUDMotion_noCB(anim_name, false); + }; + ImGui::SameLine(); + } + } } + ImGui::End(); +#endif } diff --git a/src/xrGame/player_hud_tune.h b/src/xrGame/player_hud_tune.h new file mode 100644 index 00000000000..a2c470ffae5 --- /dev/null +++ b/src/xrGame/player_hud_tune.h @@ -0,0 +1,73 @@ +#pragma once + +#include "player_hud.h" + +class CHudTuner final : public xray::editor::ide_tool +{ +public: + CHudTuner(); + void OnFrame() override; + bool is_active() const override; + +private: + pcstr tool_name() override { return "Hud Tuner"; } + + void ResetToDefaultValues(); + void UpdateValues(); + + enum hud_adj_mode_keys + { + HUD_POS = 0, + HUD_ROT, + HUD_POS_AIM, + HUD_ROT_AIM, + HUD_POS_GL, + HUD_ROT_GL, + ITEM_POS, + ITEM_ROT, + FIRE_POINT, + FIRE_POINT_2, + SHELL_POINT, + }; + enum hud_item_idx + { + MAIN_ITEM = 0, + OFFHAND_ITEM, + }; + xr_map hud_item_mode + { + { MAIN_ITEM, "Main hand item" }, + { OFFHAND_ITEM, "Off hand item" }, + }; + xr_map hud_adj_modes = + { + { HUD_POS, "Hud Position (Default)" }, + { HUD_ROT, "Hud Rotation (Default)" }, + { HUD_POS_AIM, "Hud Position (Aiming)" }, + { HUD_ROT_AIM, "Hud Rotation (Aiming)" }, + { HUD_POS_GL, "Hud Position (GL)" }, + { HUD_ROT_GL, "Hud Rotation (GL)" }, + { ITEM_POS, "Item Position" }, + { ITEM_ROT, "Item Rotation" }, + { FIRE_POINT, "Fire Point" }, + { FIRE_POINT_2, "Fire Point 2" }, + { SHELL_POINT, "Shell Point" }, + }; + + bool paused{}; + bool draw_fp{}; + bool draw_fp2{}; + bool draw_fd{}; + bool draw_fd2{}; + bool draw_sp{}; + + float debug_point_size{ 0.005f }; + float _delta_pos{ 0.0005f }; + float _delta_rot{ 0.05f }; + + attachable_hud_item* current_hud_item{}; + hud_item_idx current_hud_idx{ MAIN_ITEM }; + + hud_item_measures curr_measures{}; + hud_item_measures new_measures{}; +}; diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index 54ee5a81250..762c7b46e36 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -967,6 +967,7 @@ + diff --git a/src/xrGame/xrGame.vcxproj.filters b/src/xrGame/xrGame.vcxproj.filters index 541aba9c67d..ba820c81759 100644 --- a/src/xrGame/xrGame.vcxproj.filters +++ b/src/xrGame/xrGame.vcxproj.filters @@ -6492,6 +6492,9 @@ Core\Server + + Core\Client\Objects\items & weapons\HudItem + From 23357476fa87ebc404d6f4f05742481052c5633d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 2 Jun 2024 19:15:47 +0500 Subject: [PATCH 465/497] xrRender_GL: possible fix for shaders compilation --- src/Layers/xrRenderPC_GL/rgl_shaders.cpp | 29 +++++++----------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp index c7d0d76a1f6..917cb9e51cc 100644 --- a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp +++ b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp @@ -113,14 +113,8 @@ class shader_sources_manager pcstr* m_sources{}; size_t m_sources_lines{}; xr_vector m_source, m_includes; - string512 m_name_comment; public: - explicit shader_sources_manager(cpcstr name) - { - strconcat(m_name_comment, "// ", name, "\n"); - } - ~shader_sources_manager() { // Free string resources @@ -134,15 +128,6 @@ class shader_sources_manager [[nodiscard]] auto get() const { return m_sources; } [[nodiscard]] auto length() const { return m_sources_lines; } - [[nodiscard]] static constexpr bool optimized() - { -#ifdef DEBUG - return false; -#else - return true; -#endif - } - void compile(IReader* file, shader_options_holder& options) { load_includes(file); @@ -196,17 +181,15 @@ class shader_sources_manager void apply_options(shader_options_holder& options) { // Compile sources list - constexpr size_t head_lines = 1; // name_comment line - m_sources_lines = m_source.size() + options.size() + head_lines; + m_sources_lines = m_source.size() + options.size(); m_sources = xr_alloc(m_sources_lines); - m_sources[0] = m_name_comment; // Make define lines for (size_t i = 0; i < options.size(); ++i) { - m_sources[head_lines + i] = options[i]; + m_sources[i] = options[i]; } - CopyMemory(m_sources + head_lines + options.size(), m_source.data(), m_source.size() * sizeof(pstr)); + CopyMemory(m_sources + options.size(), m_source.data(), m_source.size() * sizeof(pstr)); } }; @@ -217,6 +200,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, shader_name_holder sh_name; // Don't move these variables to lower scope! + string64 c_name; string32 c_smapsize; string32 c_gloss; string32 c_sun_shafts; @@ -250,6 +234,9 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, options.add("#extension GL_ARB_separate_shader_objects : enable"); + xr_sprintf(c_name, "// %s.%s", name, pTarget); + options.add(c_name); + // Shadow map size { xr_itoa(m_SMAPSize, c_smapsize, 10); @@ -560,7 +547,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, Log("- Compile shader:", filename); #endif // Compile sources list - shader_sources_manager sources(name); + shader_sources_manager sources; sources.compile(fs, options); // Compile the shader from sources From 2981decc7c29ae4ef64ccbd07b54fac82f39e089 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 12:22:03 +0000 Subject: [PATCH 466/497] build(deps): bump Externals/luabind from `c90385d` to `dd33679` Bumps [Externals/luabind](https://github.com/OpenXRay/luabind-deboostified) from `c90385d` to `dd33679`. - [Commits](https://github.com/OpenXRay/luabind-deboostified/compare/c90385df57349171506463cde3632c2f64991bd5...dd33679d7f3e427fa8a0046250ce8d738eb77413) --- updated-dependencies: - dependency-name: Externals/luabind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/luabind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/luabind b/Externals/luabind index c90385df573..dd33679d7f3 160000 --- a/Externals/luabind +++ b/Externals/luabind @@ -1 +1 @@ -Subproject commit c90385df57349171506463cde3632c2f64991bd5 +Subproject commit dd33679d7f3e427fa8a0046250ce8d738eb77413 From 29c04a698a1feef53433dc824781fa356a4d18b1 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 7 Jun 2024 11:39:05 +0500 Subject: [PATCH 467/497] GitHub Actions: set timeout for Windows builds to 35 minutes [skip ci] --- .github/workflows/cibuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 1c0ff89ee62..65af2a85fde 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -11,7 +11,7 @@ jobs: windows: name: Windows ${{ matrix.Configuration }} ${{ matrix.Platform }} (msvc) runs-on: windows-latest - timeout-minutes: 30 + timeout-minutes: 35 strategy: fail-fast: false matrix: From 3ab767c8a418fc90cc7fea93d1b73ebbf18fdede Mon Sep 17 00:00:00 2001 From: yohjimane Date: Thu, 6 Jun 2024 23:39:19 -0700 Subject: [PATCH 468/497] Improvements for ImGui Hud Tuner (#1688) --- src/xrGame/player_hud_tune.cpp | 84 +++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/src/xrGame/player_hud_tune.cpp b/src/xrGame/player_hud_tune.cpp index 528b568df9c..87ec5cdf0f2 100644 --- a/src/xrGame/player_hud_tune.cpp +++ b/src/xrGame/player_hud_tune.cpp @@ -58,11 +58,6 @@ void CHudTuner::UpdateValues() { if (current_hud_item) { - new_measures.m_hands_attach[0].set(curr_measures.m_hands_attach[0]); - new_measures.m_hands_attach[1].set(curr_measures.m_hands_attach[1]); - new_measures.m_hands_attach[0].add(new_measures.m_hands_offset[0][0]); - new_measures.m_hands_attach[1].add(new_measures.m_hands_offset[1][0]); - current_hud_item->m_measures = new_measures; } } @@ -76,6 +71,13 @@ void CHudTuner::OnFrame() if (!g_player_hud) return; + auto calcColumnCount = [](float columnWidth) -> int + { + float windowWidth = ImGui::GetWindowWidth(); + int columnCount = _max(1, static_cast(windowWidth / columnWidth)); + return columnCount; + }; + auto hud_item = g_player_hud->attached_item(current_hud_idx); if (current_hud_item != hud_item) { @@ -124,8 +126,8 @@ void CHudTuner::OnFrame() ImGui::SliderFloat("Position step", &_delta_pos, 0.0000001f, 0.001f, "%.7f"); ImGui::SliderFloat("Rotation step", &_delta_rot, 0.000001f, 0.1f, "%.6f"); - ImGui::DragFloat3(hud_adj_modes[HUD_POS], (float*)&new_measures.m_hands_offset[0][0], _delta_pos, 0.f, 0.f, "%.7f"); - ImGui::DragFloat3(hud_adj_modes[HUD_ROT], (float*)&new_measures.m_hands_offset[1][0], _delta_rot, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_POS], (float*)&new_measures.m_hands_attach[0], _delta_pos, 0.f, 0.f, "%.7f"); + ImGui::DragFloat3(hud_adj_modes[HUD_ROT], (float*)&new_measures.m_hands_attach[1], _delta_rot, 0.f, 0.f, "%.7f"); ImGui::DragFloat3(hud_adj_modes[HUD_POS_AIM], (float*)&new_measures.m_hands_offset[0][1], _delta_pos, 0.f, 0.f, "%.7f"); ImGui::DragFloat3(hud_adj_modes[HUD_ROT_AIM], (float*)&new_measures.m_hands_offset[1][1], _delta_rot, 0.f, 0.f, "%.7f"); ImGui::DragFloat3(hud_adj_modes[HUD_POS_GL], (float*)&new_measures.m_hands_offset[0][2], _delta_pos, 0.f, 0.f, "%.7f"); @@ -152,9 +154,9 @@ void CHudTuner::OnFrame() ImGui::LogToClipboard(); xr_sprintf(selectable, "[%s]\n", m_sect_name.c_str()); ImGui::LogText(selectable); - xr_sprintf(selectable, "hands_position%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[0][0].x, new_measures.m_hands_offset[0][0].y, new_measures.m_hands_offset[0][0].z); + xr_sprintf(selectable, "hands_position%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_attach[0].x, new_measures.m_hands_attach[0].y, new_measures.m_hands_attach[0].z); ImGui::LogText(selectable); - xr_sprintf(selectable, "hands_orientation%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[1][0].x, new_measures.m_hands_offset[1][0].y, new_measures.m_hands_offset[1][0].z); + xr_sprintf(selectable, "hands_orientation%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_attach[1].x, new_measures.m_hands_attach[1].y, new_measures.m_hands_attach[1].z); ImGui::LogText(selectable); xr_sprintf(selectable, "aim_hud_offset_pos%s = %f,%f,%f\n", (is_16x9) ? "_16x9" : "", new_measures.m_hands_offset[0][1].x, new_measures.m_hands_offset[0][1].y, new_measures.m_hands_offset[0][1].z); ImGui::LogText(selectable); @@ -187,11 +189,21 @@ void CHudTuner::OnFrame() CDebugRenderer& render = Level().debug_renderer(); ImGui::SliderFloat("Debug Point Size", &debug_point_size, 0.00005f, 1.f, "%.5f"); - if (ImGui::RadioButton("Draw Fire Point", draw_fp)) { draw_fp = !draw_fp; }; ImGui::SameLine(); - if (ImGui::RadioButton("Draw Fire Point (GL)", draw_fp2)) { draw_fp2 = !draw_fp2; } ImGui::SameLine(); - if (ImGui::RadioButton("Draw Fire Direction", draw_fd)) { draw_fd = !draw_fd; } ImGui::SameLine(); - if (ImGui::RadioButton("Draw Fire Direction (GL)", draw_fd2)) { draw_fd2 = !draw_fd2; } ImGui::SameLine(); - if (ImGui::RadioButton("Draw Shell Point", draw_sp)) { draw_sp = !draw_sp; } + + if (ImGui::BeginTable("Show Debug Widgets", calcColumnCount(210.f))) + { + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Draw Fire Point", draw_fp)) { draw_fp = !draw_fp; }; + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Draw Fire Point (GL)", draw_fp2)) { draw_fp2 = !draw_fp2; } + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Draw Fire Direction", draw_fd)) { draw_fd = !draw_fd; } + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Draw Fire Direction (GL)", draw_fd2)) { draw_fd2 = !draw_fd2; } + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Draw Shell Point", draw_sp)) { draw_sp = !draw_sp; } + ImGui::EndTable(); + } if (draw_fp) { @@ -257,31 +269,49 @@ void CHudTuner::OnFrame() } } + ImGui::NewLine(); + if (current_hud_item && ImGui::CollapsingHeader("Bone and Animation Debugging", ImGuiTreeNodeFlags_DefaultOpen)) { IKinematics* ik = current_hud_item->m_model; ImGui::Text("Bone Count = %i", ik->LL_BoneCount()); - ImGui::Text("Root Bone = %s", ik->LL_BoneName_dbg(ik->LL_GetBoneRoot())); + ImGui::Text("Root Bone = %s, ID: %i", ik->LL_BoneName_dbg(ik->LL_GetBoneRoot()), ik->LL_GetBoneRoot()); - for (const auto& [bone_name, bone_id] : *ik->LL_Bones()) + if (ImGui::BeginTable("Bone Visibility", calcColumnCount(125.f))) { - if (bone_id == ik->LL_GetBoneRoot()) - continue; + for (const auto& [bone_name, bone_id] : *ik->LL_Bones()) + { + if (bone_id == ik->LL_GetBoneRoot()) + continue; - bool visible = ik->LL_GetBoneVisible(bone_id); - if (ImGui::RadioButton(bone_name.c_str(), visible)) { visible = !visible; }; ImGui::SameLine(); - ik->LL_SetBoneVisible(bone_id, visible, FALSE); + ImGui::TableNextColumn(); + bool visible = ik->LL_GetBoneVisible(bone_id); + if (ImGui::RadioButton(bone_name.c_str(), visible)) { visible = !visible; }; + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + { + ImGui::SetTooltip("Bone Name = %s, ID: %i", bone_name.c_str(), bone_id); + } + ik->LL_SetBoneVisible(bone_id, visible, FALSE); + } + ImGui::EndTable(); } ImGui::NewLine(); - - for (const auto& [anim_name, motion] : current_hud_item->m_hand_motions.m_anims) + if (ImGui::BeginTable("Animations", calcColumnCount(125.f))) { - if (ImGui::Button(anim_name.c_str())) + for (const auto& [anim_name, motion] : current_hud_item->m_hand_motions.m_anims) { - current_hud_item->m_parent_hud_item->PlayHUDMotion_noCB(anim_name, false); - }; - ImGui::SameLine(); + ImGui::TableNextColumn(); + if (ImGui::Button(anim_name.c_str())) + { + current_hud_item->m_parent_hud_item->PlayHUDMotion_noCB(anim_name, false); + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + { + ImGui::SetTooltip("%s = %s, %s", anim_name.c_str(), motion.m_base_name.c_str(), motion.m_additional_name.c_str()); + } + } + ImGui::EndTable(); } } } From d12ccfedb66eb7e1cb6a586dfe008f552bb97ead Mon Sep 17 00:00:00 2001 From: Hrusteckiy <47980896+Hrusteckiy@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:39:38 +0300 Subject: [PATCH 469/497] Restored mirroring of texture feature for `CUIStatic` (#1690) Co-authored-by: Sultan Uramaev --- src/xrUICore/Static/UIStaticItem.cpp | 12 ++++++++++++ src/xrUICore/Static/UIStaticItem.h | 12 ++++++++++++ src/xrUICore/XML/UIXmlInitBase.cpp | 8 ++++++++ 3 files changed, 32 insertions(+) diff --git a/src/xrUICore/Static/UIStaticItem.cpp b/src/xrUICore/Static/UIStaticItem.cpp index 1cbe4a64c32..4554547f489 100644 --- a/src/xrUICore/Static/UIStaticItem.cpp +++ b/src/xrUICore/Static/UIStaticItem.cpp @@ -56,6 +56,12 @@ void CUIStaticItem::RenderInternal(const Fvector2& in_pos) LTt.set(TextureRect.x1 / ts.x, TextureRect.y1 / ts.y); RBt.set(TextureRect.x2 / ts.x, TextureRect.y2 / ts.y); + // Check mirror mode + if (EUIMirroring::Horisontal == eMirrorMode || EUIMirroring::Both == eMirrorMode) + std::swap(LTt.x, RBt.x); + if (EUIMirroring::Vertical == eMirrorMode || EUIMirroring::Both == eMirrorMode) + std::swap(LTt.y, RBt.y); + float offset = -0.5f; if (UI().m_currentPointType == IUIRender::pttLIT) offset = 0.0f; @@ -131,6 +137,12 @@ void CUIStaticItem::RenderInternal(float angle) LTt.set(TextureRect.x1 / ts.x + hp.x, TextureRect.y1 / ts.y + hp.y); RBt.set(TextureRect.x2 / ts.x + hp.x, TextureRect.y2 / ts.y + hp.y); + // Check mirror mode + if (EUIMirroring::Horisontal == eMirrorMode || EUIMirroring::Both == eMirrorMode) + std::swap(LTt.x, RBt.x); + if (EUIMirroring::Vertical == eMirrorMode || EUIMirroring::Both == eMirrorMode) + std::swap(LTt.y, RBt.y); + float kx = UI().get_current_kx(); // clip poly diff --git a/src/xrUICore/Static/UIStaticItem.h b/src/xrUICore/Static/UIStaticItem.h index f50801a52ed..c9bb8a1cd48 100644 --- a/src/xrUICore/Static/UIStaticItem.h +++ b/src/xrUICore/Static/UIStaticItem.h @@ -6,6 +6,14 @@ #include "xrCore/xrstring.h" #endif +enum class EUIMirroring +{ + None, + Horisontal, + Vertical, + Both +}; + class XRUICORE_API CUIStaticItem { protected: @@ -22,6 +30,7 @@ class XRUICORE_API CUIStaticItem Fvector2 vHeadingPivot; Fvector2 vHeadingOffset; Flags8 uFlags; + EUIMirroring eMirrorMode{}; ui_shader hShader; Fvector2 vPos; @@ -65,6 +74,9 @@ class XRUICORE_API CUIStaticItem void ResetHeadingPivot(); IC bool GetFixedLTWhileHeading() const { return !!uFlags.test(flFixedLTWhileHeading); } Fvector2 GetHeadingPivot() { return vHeadingPivot; } + IC void SetMirrorMode(EUIMirroring m) { eMirrorMode = m; } + IC EUIMirroring GetMirrorMode() { return eMirrorMode; } + private: void RenderInternal(const Fvector2& pos); void RenderInternal(float angle); diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 371d56845fe..553bd14b0b7 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -143,6 +143,14 @@ bool CUIXmlInitBase::InitStatic(CUIXml& xml_doc, pcstr path, int index, CUIStati InitTexture(xml_doc, path, index, pWnd); InitTextureOffset(xml_doc, path, index, pWnd); + cpcstr mirroring = xml_doc.ReadAttrib(path, index, "mirror", ""); + if (0 == xr_strcmp(mirroring, "h")) + pWnd->GetStaticItem()->SetMirrorMode(EUIMirroring::Horisontal); + else if (0 == xr_strcmp(mirroring, "v")) + pWnd->GetStaticItem()->SetMirrorMode(EUIMirroring::Vertical); + else if (0 == xr_strcmp(mirroring, "b")) + pWnd->GetStaticItem()->SetMirrorMode(EUIMirroring::Both); + const int flag = xml_doc.ReadAttribInt(path, index, "heading", 0); pWnd->EnableHeading((flag) ? true : false); From 7f18a2b6662be55147eecca57fa62dfd774b55b8 Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Fri, 7 Jun 2024 11:41:38 +0500 Subject: [PATCH 470/497] xrRender_GL: fix possible problems with shader compilation on some OpenGL drivers --- src/Layers/xrRenderPC_GL/rgl_shaders.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp index 917cb9e51cc..d97026825a4 100644 --- a/src/Layers/xrRenderPC_GL/rgl_shaders.cpp +++ b/src/Layers/xrRenderPC_GL/rgl_shaders.cpp @@ -223,6 +223,7 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, }; options.add("#version 410"); + options.add("#extension GL_ARB_separate_shader_objects : enable"); #ifdef DEBUG options.add("#pragma optimize (off)"); @@ -232,8 +233,6 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, sh_name.append(1u); #endif - options.add("#extension GL_ARB_separate_shader_objects : enable"); - xr_sprintf(c_name, "// %s.%s", name, pTarget); options.add(c_name); From c67235d9239b9797859a1b82c0769789405be6cc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 17 Jun 2024 00:56:58 +0500 Subject: [PATCH 471/497] Removed version switcher (reverts #491, cancels part of #710) We want simplicity. I also want to reduce platform-specific code in the next commits. So, let the user handle version switching for themselves. The version switcher in the current form is unfinished and has some issues, e.g. some problems with FS or some missing features (were tracked in #710) This reverts cc2e180ae85d1da8392e014f88c6236074883494 and 9cf69d03a89e71483fc9f20568943b215d5e5d50. --- res/fsgame.ltx | 1 - res/gamedata/configs/text/eng/openxray.xml | 3 - res/gamedata/configs/text/pol/openxray.xml | 3 - res/gamedata/configs/text/rus/openxray.xml | 3 - res/gamedata/configs/ui/message_box.xml | 17 -- res/gamedata/configs/ui/message_box_16.xml | 17 -- .../configs/ui/ui_mm_versions_dlg.xml | 52 ------ .../configs/ui/ui_mm_versions_dlg_16.xml | 58 ------ res/gamedata/scripts/ui_main_menu.script | 18 +- .../scripts/ui_versions_dialog.script | 70 -------- src/xrGame/CMakeLists.txt | 4 - src/xrGame/ScriptXMLInit.cpp | 10 -- src/xrGame/ScriptXMLInit.h | 2 - src/xrGame/VersionSwitcher.cpp | 169 ------------------ src/xrGame/VersionSwitcher.h | 52 ------ src/xrGame/ui/ServerList.cpp | 60 ++----- src/xrGame/ui/ServerList.h | 1 - src/xrGame/ui/UIVersionList.cpp | 101 ----------- src/xrGame/ui/UIVersionList.h | 30 ---- src/xrGame/ui/UIWindow_script.cpp | 16 -- src/xrGame/xrGame.vcxproj | 4 - src/xrGame/xrGame.vcxproj.filters | 11 -- 22 files changed, 11 insertions(+), 691 deletions(-) delete mode 100644 res/gamedata/configs/ui/ui_mm_versions_dlg.xml delete mode 100644 res/gamedata/configs/ui/ui_mm_versions_dlg_16.xml delete mode 100644 res/gamedata/scripts/ui_versions_dialog.script delete mode 100644 src/xrGame/VersionSwitcher.cpp delete mode 100644 src/xrGame/VersionSwitcher.h delete mode 100644 src/xrGame/ui/UIVersionList.cpp delete mode 100644 src/xrGame/ui/UIVersionList.h diff --git a/res/fsgame.ltx b/res/fsgame.ltx index 98caf0b4a44..4082c5030bd 100644 --- a/res/fsgame.ltx +++ b/res/fsgame.ltx @@ -1,6 +1,5 @@ ;abbreviation = recurs|notif| root| add| ext| description $app_data_root$ = true| false| $fs_root$| _appdata_\ -$game_versions$ = true| false| $fs_root$| versions\ $arch_dir$ = false| false| $fs_root$ $game_arch_mp$ = false| false| $fs_root$| mp\ $arch_dir_levels$ = false| false| $fs_root$| levels\ diff --git a/res/gamedata/configs/text/eng/openxray.xml b/res/gamedata/configs/text/eng/openxray.xml index 7d11350be53..ddb06f0af6c 100644 --- a/res/gamedata/configs/text/eng/openxray.xml +++ b/res/gamedata/configs/text/eng/openxray.xml @@ -81,9 +81,6 @@ Field of view - - Do you really want to launch another version of the game? - Language diff --git a/res/gamedata/configs/text/pol/openxray.xml b/res/gamedata/configs/text/pol/openxray.xml index c516a182339..71a475336a3 100644 --- a/res/gamedata/configs/text/pol/openxray.xml +++ b/res/gamedata/configs/text/pol/openxray.xml @@ -78,9 +78,6 @@ Pole widzenia - - Czy na pewno chcesz uruchomic kolejna wersje gry? - Jzyk diff --git a/res/gamedata/configs/text/rus/openxray.xml b/res/gamedata/configs/text/rus/openxray.xml index 98fff6386d2..4a500525a93 100644 --- a/res/gamedata/configs/text/rus/openxray.xml +++ b/res/gamedata/configs/text/rus/openxray.xml @@ -87,9 +87,6 @@ - - ? - diff --git a/res/gamedata/configs/ui/message_box.xml b/res/gamedata/configs/ui/message_box.xml index 28f3d5444d1..317a5937edb 100644 --- a/res/gamedata/configs/ui/message_box.xml +++ b/res/gamedata/configs/ui/message_box.xml @@ -583,21 +583,4 @@ ui_inGame2_Mp_bigbuttone - - - ui_inGame2_message_box - - st_switch_version_invitation - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - diff --git a/res/gamedata/configs/ui/message_box_16.xml b/res/gamedata/configs/ui/message_box_16.xml index 1014593a153..5573c5d75c0 100644 --- a/res/gamedata/configs/ui/message_box_16.xml +++ b/res/gamedata/configs/ui/message_box_16.xml @@ -584,21 +584,4 @@ ui_inGame2_Mp_bigbuttone - - - ui_inGame2_message_box - - st_switch_version_invitation - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - diff --git a/res/gamedata/configs/ui/ui_mm_versions_dlg.xml b/res/gamedata/configs/ui/ui_mm_versions_dlg.xml deleted file mode 100644 index 22fe91f1b1b..00000000000 --- a/res/gamedata/configs/ui/ui_mm_versions_dlg.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - ui\video_voroni_crop - - - ui\video_water_crop - - - ui_inGame2_background - - - ui_save_load_back - - - -
          - ui_inGame2_main_window_small - - - - - - - - - - ui_inGame2_Mp_bigbuttone - ui_mm_cancel - - - - ui_inGame2_Mp_bigbuttone - ui_mm_apply - - - - - - - - ui_inGame2_servers_list_frame - -
          - ui_inGame2_servers_list_button - - version - -
          -
          - -
          diff --git a/res/gamedata/configs/ui/ui_mm_versions_dlg_16.xml b/res/gamedata/configs/ui/ui_mm_versions_dlg_16.xml deleted file mode 100644 index a9a40c7c9d4..00000000000 --- a/res/gamedata/configs/ui/ui_mm_versions_dlg_16.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - ui\video_voroni_crop - - - ui\video_water_crop - - - ui_inGame2_background - - - ui_inGame2_left_widepanel - - - ui_inGame2_right_widepanel - - - ui_save_load_back - - - -
          - ui_inGame2_main_window_small - - - - - - - - - - ui_inGame2_Mp_bigbuttone - ui_mm_cancel - - - - ui_inGame2_Mp_bigbuttone - ui_mm_apply - - - - - - - - ui_inGame2_servers_list_frame - -
          - ui_inGame2_servers_list_button - - version - -
          -
          - -
          diff --git a/res/gamedata/scripts/ui_main_menu.script b/res/gamedata/scripts/ui_main_menu.script index 85b8b66b3fb..db6b0443923 100644 --- a/res/gamedata/scripts/ui_main_menu.script +++ b/res/gamedata/scripts/ui_main_menu.script @@ -30,10 +30,9 @@ function main_menu:InitControls() self.message_box = CUIMessageBoxEx() self:Register (self.message_box, "msg_box") - local _ver = xml:Init3tButton ("static_version",self) + local _ver = xml:InitStatic ("static_version",self) local mm = _G.main_menu.get_main_menu() _ver:TextControl():SetText ("ver. " .. mm:GetGSVer()) - self:Register(_ver, 'btn_version'); self.l_mgr = mm:GetLoginMngr() self.acc_mgr = mm:GetAccountMngr() @@ -86,8 +85,6 @@ function main_menu:InitCallBacks() self:AddCallback("msg_box", ui_events.MESSAGE_BOX_NO_CLICKED, self.OnMsgNo, self) self:AddCallback("msg_box", ui_events.MESSAGE_BOX_QUIT_GAME_CLICKED,self.OnMessageQuitGame, self) self:AddCallback("msg_box", ui_events.MESSAGE_BOX_QUIT_WIN_CLICKED, self.OnMessageQuitWin, self) - - self:AddCallback("btn_version", ui_events.BUTTON_CLICKED, self.OnButton_version_clicked, self) self:Register(self, "self") self:AddCallback("self", ui_events.MAIN_MENU_RELOADED, self.OnMenuReloaded, self) @@ -323,19 +320,6 @@ function main_menu:OnButton_localnet_clicked() console:execute ("check_for_updates 0") end -function main_menu:OnButton_version_clicked() - if self.ver_dlg ==nil then - self.ver_dlg = ui_versions_dialog.versions_dialog() - self.ver_dlg.owner = self - end - - if self.ver_dlg:NeedToBeShown() then - self.ver_dlg:ShowDialog(true) - self:HideDialog() - self:Show(false) - end -end - function main_menu:Dispatch(cmd, param) --virtual function if cmd == 2 then self:OnButton_multiplayer_clicked() diff --git a/res/gamedata/scripts/ui_versions_dialog.script b/res/gamedata/scripts/ui_versions_dialog.script deleted file mode 100644 index 31f29ed24ed..00000000000 --- a/res/gamedata/scripts/ui_versions_dialog.script +++ /dev/null @@ -1,70 +0,0 @@ -class "versions_dialog" (CUIScriptWnd) - -function versions_dialog:__init() super() - self:InitControls() - self:InitCallBacks() -end - -function versions_dialog:__finalize() -end - -function versions_dialog:InitControls() - self:SetWndRect (Frect():set(0,0,1024,768)) - - local xml = CScriptXmlInit() - xml:ParseFile ("ui_mm_versions_dlg.xml") - xml:InitStatic ("background",self) - - self.form = xml:InitStatic("form",self) - self.caption = xml:InitStatic ("form:caption",self.form) - self.description = xml:InitTextWnd ("form:description",self.form) - - self.btn_cancel = xml:Init3tButton ("form:btn_cancel", self.form) - self:Register (self.btn_cancel, "button_back") - - self.btn_start = xml:Init3tButton ("form:btn_start", self.form) - self:Register (self.btn_start, "button_start") - - self.ver_list = xml:InitVerList ("form:ver_list", self.form) - self:Register (self.ver_list, "ver_list") - -end - -function versions_dialog:InitCallBacks() - self:AddCallback("button_back", ui_events.BUTTON_CLICKED, self.OnButton_back_clicked, self) - self:AddCallback("button_start", ui_events.BUTTON_CLICKED, self.OnButton_start_clicked, self) - self:AddCallback("ver_list", ui_events.LIST_ITEM_CLICKED, self.OnListClicked, self) - self:AddCallback("ver_list", ui_events.WINDOW_LBUTTON_DB_CLICK, self.OnListDblClicked, self) -end - -function versions_dialog:OnListClicked() - local descr = self.ver_list:GetCurrentVersionDescr(); - self.description:SetText(descr) -end - -function versions_dialog:OnListDblClicked() - self:OnButton_start_clicked(); -end - -function versions_dialog:OnButton_start_clicked() - self.ver_list:SwitchToSelectedVersion() -end - -function versions_dialog:OnButton_back_clicked() - self.owner:ShowDialog(true) - self:HideDialog() - self.owner:Show(true) -end - -function versions_dialog:NeedToBeShown() - return self.ver_list:GetItemsCount() > 0 -end - -function versions_dialog:OnKeyboard(dik, keyboard_action) - CUIScriptWnd.OnKeyboard(self,dik,keyboard_action) - local bind = dik_to_bind(dik) - if bind == key_bindings.kQUIT then - self:OnButton_back_clicked() - end - return true -end diff --git a/src/xrGame/CMakeLists.txt b/src/xrGame/CMakeLists.txt index a0850bdbc35..4f7d4dcdee0 100644 --- a/src/xrGame/CMakeLists.txt +++ b/src/xrGame/CMakeLists.txt @@ -1591,8 +1591,6 @@ target_sources(xrGame PRIVATE UITimeDilator.h UIZoneMap.cpp UIZoneMap.h - VersionSwitcher.cpp - VersionSwitcher.h vision_client.cpp vision_client.h vision_client_inline.h @@ -2471,8 +2469,6 @@ target_sources(xrGame PRIVATE ui/UITradeBar.h ui/UITradeWnd.cpp ui/UITradeWnd.h - ui/UIVersionList.cpp - ui/UIVersionList.h ui/UIVote.cpp ui/UIVote.h ui/UIVoteStatusWnd.cpp diff --git a/src/xrGame/ScriptXMLInit.cpp b/src/xrGame/ScriptXMLInit.cpp index b4ef8c71623..46911dba27a 100644 --- a/src/xrGame/ScriptXMLInit.cpp +++ b/src/xrGame/ScriptXMLInit.cpp @@ -11,7 +11,6 @@ #include "ui/UILabel.h" #include "ui/ServerList.h" #include "ui/UIMapList.h" -#include "ui/UIVersionList.h" #include "ui/UIKeyBinding.h" #include "xrUICore/EditBox/UIEditBox.h" #include "xrUICore/Static/UIAnimatedStatic.h" @@ -202,14 +201,6 @@ CUIMapList* CScriptXmlInit::InitMapList(LPCSTR path, CUIWindow* parent) return pWnd; } -CUIVersionList* CScriptXmlInit::InitVerList(LPCSTR path, CUIWindow* parent) -{ - CUIVersionList* pWnd = xr_new(); - pWnd->InitFromXml(m_xml, path); - _attach_child(pWnd, parent); - return pWnd; -} - CUIMMShniaga* CScriptXmlInit::InitMMShniaga(LPCSTR path, CUIWindow* parent) { CUIMMShniaga* pWnd = xr_new(); @@ -297,7 +288,6 @@ SCRIPT_EXPORT(CScriptXmlInit, (), .def("InitTab", &CScriptXmlInit::InitTab) .def("InitServerList", &CScriptXmlInit::InitServerList) .def("InitMapList", &CScriptXmlInit::InitMapList) - .def("InitVerList", &CScriptXmlInit::InitVerList) .def("InitMapInfo", &CScriptXmlInit::InitMapInfo) .def("InitTrackBar", &CScriptXmlInit::InitTrackBar) .def("InitCDkey", &CScriptXmlInit::InitCDkey) diff --git a/src/xrGame/ScriptXMLInit.h b/src/xrGame/ScriptXMLInit.h index 1d338c8e19f..737816abe4d 100644 --- a/src/xrGame/ScriptXMLInit.h +++ b/src/xrGame/ScriptXMLInit.h @@ -21,7 +21,6 @@ class CUIAnimatedStatic; class CUISleepStatic; class CServerList; class CUIMapList; -class CUIVersionList; class CUITrackBar; class CUIMapInfo; class CUIMMShniaga; @@ -53,7 +52,6 @@ class CScriptXmlInit CUITabControl* InitTab(LPCSTR path, CUIWindow* parent); CServerList* InitServerList(LPCSTR path, CUIWindow* parent); CUIMapList* InitMapList(LPCSTR path, CUIWindow* parent); - CUIVersionList* InitVerList(LPCSTR path, CUIWindow* parent); CUIMapInfo* InitMapInfo(LPCSTR path, CUIWindow* parent); CUITrackBar* InitTrackBar(LPCSTR path, CUIWindow* parent); CUIEditBox* InitCDkey(LPCSTR path, CUIWindow* parent); diff --git a/src/xrGame/VersionSwitcher.cpp b/src/xrGame/VersionSwitcher.cpp deleted file mode 100644 index 95af330ede3..00000000000 --- a/src/xrGame/VersionSwitcher.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "StdAfx.h" -#include "VersionSwitcher.h" -#include "xrEngine/XR_IOConsole.h" - -static CVersionSwitcher s_switcher; - -extern ENGINE_API string512 g_sLaunchOnExit_app; -extern ENGINE_API string512 g_sLaunchOnExit_params; -extern ENGINE_API string_path g_sLaunchWorkingFolder; - -size_t CVersionSwitcher::GetVerCount() -{ - if (!s_switcher.inited) - s_switcher.Init(); - return s_switcher.GetVerCountInternal(); -} - -size_t CVersionSwitcher::GetVerCountInternal() const { return versions.size(); } - -const SVersionDescription& CVersionSwitcher::GetVerDesc(size_t idx) -{ - if (!s_switcher.inited) - s_switcher.Init(); - return s_switcher.GetVerDescInternal(idx); -} - -const SVersionDescription& CVersionSwitcher::GetVerDescInternal(size_t idx) const -{ - R_ASSERT(idx < versions.size()); - return versions[idx]; -} - -void CVersionSwitcher::SwitchToGameVer(size_t idx, CVersionSwitcher::EVersionSwitchMode mode) -{ - R_ASSERT(s_switcher.inited); - const SVersionDescription& desc = s_switcher.GetVerDescInternal(idx); - pcstr args = (mode == SWITCH_TO_SERVER) ? desc.arguments_mp.c_str() : desc.arguments_mm.c_str(); - s_switcher.SwitchToGameVerInternal(desc.exe_path.c_str(), desc.working_dir.c_str(), args); -} - -void CVersionSwitcher::SwitchToGameVer(pcstr name, EVersionSwitchMode mode) -{ - size_t idx = FindVersionIdByName(name); - R_ASSERT(idx != CVersionSwitcher::VERSION_NOT_FOUND); - SwitchToGameVer(idx, mode); -} - -void CVersionSwitcher::SwitchToGameVerInternal(xr_string appexe, xr_string working_dir, xr_string args) const -{ - // Command line specifiers: - // %SERVER% - address and port of the selected server (for multiplayer mode) - // %PLAYERNAME% - nickname of the player in multiplayer - // %SERVERPASSWORD% - password for connection to the server - // %USERPASSWORD% - password for connection to the server with user's list - - args = xr_substrreplace(args, "%SERVER%", server); - args = xr_substrreplace(args, "%PLAYERNAME%", name); - args = xr_substrreplace(args, "%SERVERPASSWORD%", server_password); - args = xr_substrreplace(args, "%USERPASSWORD%", user_password); - - xr_strcpy(g_sLaunchWorkingFolder, working_dir.c_str()); - xr_strcpy(g_sLaunchOnExit_app, appexe.c_str()); - xr_strcpy(g_sLaunchOnExit_params, appexe.c_str()); - xr_strcpy(g_sLaunchOnExit_params, " "); - xr_strcat(g_sLaunchOnExit_params, args.c_str()); - - Console->Execute("quit"); -} - -size_t CVersionSwitcher::FindVersionIdByName(pcstr version) -{ - if (!s_switcher.inited) - s_switcher.Init(); - - return s_switcher.FindVersionIdByNameInternal(version); -} - -size_t CVersionSwitcher::FindVersionIdByNameInternal(pcstr version) -{ - size_t result = VERSION_NOT_FOUND; - for (size_t i = 0; i < versions.size(); ++i) - { - if (xr_strcmp(versions[i].name.c_str(), version) == 0) - { - result = i; - break; - } - } - return result; -} - -void CVersionSwitcher::SetupMPParams(pcstr name, pcstr srvpsw, pcstr userpsw, pcstr server) -{ - R_ASSERT(s_switcher.inited); - s_switcher.SetupMPParamsInternal(name, srvpsw, userpsw, server); -} - -void CVersionSwitcher::SetupMPParamsInternal(pcstr nick, pcstr srvpsw, pcstr userpsw, pcstr srv) -{ - server = srv; - name = nick; - server_password = srvpsw; - user_password = userpsw; -} - -void CVersionSwitcher::ParseVersionConfig(const string_path& cfg) -{ - const char* SECTION = "ver_desc"; - CInifile ini(cfg); - SVersionDescription desc; - - desc.name = READ_IF_EXISTS(&ini, r_string, SECTION, "name", ""); - desc.description = READ_IF_EXISTS(&ini, r_string_wb, SECTION, "description", ""); - desc.exe_path = READ_IF_EXISTS(&ini, r_string_wb, SECTION, "exe_path", ""); - desc.arguments_mm = READ_IF_EXISTS(&ini, r_string_wb, SECTION, "arguments_mm", ""); - desc.arguments_mp = READ_IF_EXISTS(&ini, r_string_wb, SECTION, "arguments_mp", ""); - - if (desc.name.size() > 0) - { - xr_string dir = cfg; - size_t pos = dir.rfind(_DELIMITER); - dir = dir.substr(0, pos); - - if (desc.exe_path.size() < 1) - { - // Use current engine - xr_string exe_path = Core.ApplicationPath; - - // TODO: Create a cross-platform way to restart the current engine, also should be useful for dedicated - // server (maybe use xrCore class) - exe_path += "xrEngine.exe"; - - desc.exe_path = exe_path.c_str(); - desc.working_dir = dir.c_str(); - } - else - { - xr_string exe_path = dir + _DELIMITER + desc.exe_path.c_str(); - desc.exe_path = exe_path.c_str(); - desc.working_dir = dir.c_str(); - } - - versions.push_back(desc); - } -} - -void CVersionSwitcher::ReloadInternal() -{ - const char* VERSIONS_ROOT = "$game_versions$"; - - if (FS.path_exist(VERSIONS_ROOT)) - { - FS_FileSet vers; - FS.file_list(vers, VERSIONS_ROOT, FS_ListFiles, "*verdesc.ltx"); - - for (const FS_File& cfg : vers) - { - string_path file_name; - FS.update_path(file_name, VERSIONS_ROOT, cfg.name.c_str()); - ParseVersionConfig(file_name); - } - } -} - -void CVersionSwitcher::Init() -{ - ReloadInternal(); - inited = true; -} diff --git a/src/xrGame/VersionSwitcher.h b/src/xrGame/VersionSwitcher.h deleted file mode 100644 index ba6ff11bb47..00000000000 --- a/src/xrGame/VersionSwitcher.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include "xrCore/xrstring.h" -#include "xrCommon/xr_vector.h" - -struct SVersionDescription -{ - shared_str name; - shared_str description; - shared_str exe_path; - shared_str working_dir; - shared_str arguments_mm; - shared_str arguments_mp; -}; - -class CVersionSwitcher -{ -public: - static size_t GetVerCount(); - static const SVersionDescription& GetVerDesc(size_t idx); - - enum EVersionSwitchMode - { - SWITCH_TO_MAINMENU, - SWITCH_TO_SERVER, - SWITCH_COUNT, - }; - static void SwitchToGameVer(size_t idx, EVersionSwitchMode mode); - static void SwitchToGameVer(pcstr name, EVersionSwitchMode mode); - static void SetupMPParams(pcstr name, pcstr srvpsw, pcstr userpsw, pcstr server); - - static size_t FindVersionIdByName(pcstr version); - static const size_t VERSION_NOT_FOUND = size_t(-1); - -private: - size_t GetVerCountInternal() const; - const SVersionDescription& GetVerDescInternal(size_t idx) const; - void SwitchToGameVerInternal(xr_string appexe, xr_string working_dir, xr_string args) const; - void SetupMPParamsInternal(pcstr nick, pcstr srvpsw, pcstr userpsw, pcstr srv); - size_t FindVersionIdByNameInternal(pcstr version); - - void ReloadInternal(); - void Init(); - void ParseVersionConfig(const string_path& cfg); - - bool inited; - xr_vector versions; - - xr_string server; - xr_string name; - xr_string server_password; - xr_string user_password; -}; diff --git a/src/xrGame/ui/ServerList.cpp b/src/xrGame/ui/ServerList.cpp index 908bf5c457a..68585dfb4ce 100644 --- a/src/xrGame/ui/ServerList.cpp +++ b/src/xrGame/ui/ServerList.cpp @@ -11,7 +11,6 @@ #include "xrGameSpy/GameSpy_Keys.h" #include "xrGameSpy/GameSpy_Full.h" #include "Spectator.h" -#include "VersionSwitcher.h" LPCSTR GameTypeToStringEx(u32 gt, bool bShort); @@ -52,18 +51,6 @@ CServerList::CServerList() m_message_box->InitMessageBox("message_box_password"); m_message_box->SetMessageTarget(this); - if (CVersionSwitcher::GetVerCount() > 0) - { - m_version_switch_msgbox = xr_new(); - m_version_switch_msgbox->SetMessageTarget(this); - if (!m_version_switch_msgbox->InitMessageBox("message_box_version_switch")) - xr_delete(m_version_switch_msgbox); - } - else - { - m_version_switch_msgbox = nullptr; - } - m_b_local = false; m_last_retreived_index = u32(-1); @@ -73,7 +60,6 @@ CServerList::CServerList() CServerList::~CServerList() { - xr_delete(m_version_switch_msgbox); xr_delete(m_message_box); auto bro = browser_LL(); @@ -187,27 +173,13 @@ void CServerList::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) if (!item) return; - if (m_version_switch_msgbox != nullptr && pWnd == m_version_switch_msgbox) + if (pWnd == m_message_box) { - pcstr srvpsw = (item->GetInfo()->info.icons.pass) ? m_message_box->GetPassword() : ""; - pcstr upsw = (item->GetInfo()->info.icons.user_pass) ? m_message_box->m_pMessageBox->GetUserPassword() : ""; - CVersionSwitcher::SetupMPParams(m_playerName.c_str(), srvpsw, upsw, m_itemInfo.info.address.c_str()); - CVersionSwitcher::SwitchToGameVer(m_itemInfo.info.version.c_str(), CVersionSwitcher::SWITCH_TO_SERVER); - } - else if (pWnd == m_message_box) - { - if (m_version_switch_msgbox != nullptr && - xr_strcmp(item->GetInfo()->info.version, MainMenu()->GetGSVer()) != 0) - { - m_version_switch_msgbox->ShowDialog(true); - } - else - { - xr_string command; - item->CreateConsoleCommand(command, m_playerName.c_str(), - m_message_box->m_pMessageBox->GetUserPassword(), m_message_box->GetPassword()); - Console->Execute(command.c_str()); - } + xr_string command; + item->CreateConsoleCommand(command, m_playerName.c_str(), + m_message_box->m_pMessageBox->GetUserPassword(), + m_message_box->GetPassword()); + Console->Execute(command.c_str()); } } else if (WINDOW_LBUTTON_DB_CLICK == msg && &m_list[LST_SERVER] == pWnd) @@ -631,12 +603,7 @@ void CServerList::ConnectToSelected() return; } - pcstr ver = item->GetInfo()->info.version.c_str(); - bool dif_ver = xr_strcmp(ver, MainMenu()->GetGSVer()) != 0; - - if (dif_ver && - (m_version_switch_msgbox == nullptr || - CVersionSwitcher::FindVersionIdByName(ver) == CVersionSwitcher::VERSION_NOT_FOUND)) + if (xr_strcmp(item->GetInfo()->info.version, MainMenu()->GetGSVer())) { MainMenu()->SetErrorDialog(CMainMenu::ErrDifferentVersion); return; @@ -650,16 +617,9 @@ void CServerList::ConnectToSelected() } else { - if (dif_ver) - { - m_version_switch_msgbox->ShowDialog(true); - } - else - { - xr_string command; - item->CreateConsoleCommand(command, m_playerName.c_str(), "", ""); - Console->Execute(command.c_str()); - } + xr_string command; + item->CreateConsoleCommand(command, m_playerName.c_str(), "", ""); + Console->Execute(command.c_str()); } #endif } diff --git a/src/xrGame/ui/ServerList.h b/src/xrGame/ui/ServerList.h index 543598805c6..49d714a70be 100644 --- a/src/xrGame/ui/ServerList.h +++ b/src/xrGame/ui/ServerList.h @@ -135,7 +135,6 @@ class CServerList final : public CUIWindow bool m_b_local; CUIMessageBoxEx* m_message_box; - CUIMessageBoxEx* m_version_switch_msgbox; ESortingMode m_sort_mode; bool m_sort_ascending; diff --git a/src/xrGame/ui/UIVersionList.cpp b/src/xrGame/ui/UIVersionList.cpp deleted file mode 100644 index 54e2f1d526f..00000000000 --- a/src/xrGame/ui/UIVersionList.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "StdAfx.h" -#include "UIVersionList.h" -#include "VersionSwitcher.h" -#include "xrUICore/ListBox/UIListBoxItem.h" - -CUIVersionList::CUIVersionList() - : CUIWindow("CUIVersionList") -{ - itemsCount = 0; - - versionsList = xr_new(); - frame = xr_new("Frame"); - header = xr_new("Header"); - - versionsList->SetAutoDelete(true); - frame->SetAutoDelete(true); - header->SetAutoDelete(true); - - AttachChild(versionsList); - AttachChild(frame); - AttachChild(header); -} - -void CUIVersionList::InitFromXml(CUIXml& xml_doc, const char* path) -{ - CUIXmlInit::InitWindow(xml_doc, path, 0, this); - string256 buf; - CUIXmlInit::InitListBox(xml_doc, strconcat(sizeof(buf), buf, path, ":list_versions"), 0, versionsList); - CUIXmlInit::InitFrameLine(xml_doc, strconcat(sizeof(buf), buf, path, ":header"), 0, header); - CUIXmlInit::InitFrameWindow(xml_doc, strconcat(sizeof(buf), buf, path, ":frame"), 0, frame); - - UpdateVersionList(); -} - -void CUIVersionList::UpdateVersionList() -{ - versionsList->Clear(); - - itemsCount = CVersionSwitcher::GetVerCount(); - - for (size_t i = 0; i < itemsCount; ++i) - { - const SVersionDescription desc = CVersionSwitcher::GetVerDesc(i); - - CUIListBoxItem* itm = versionsList->AddTextItem(desc.name.c_str()); - itm->SetData(reinterpret_cast(i)); - itm->Enable(true); - } -} - -const SVersionDescription* CUIVersionList::GetCurrentItem() const -{ - CUIListBoxItem* itm = versionsList->GetSelectedItem(); - if (!itm) - return nullptr; - return &CVersionSwitcher::GetVerDesc(reinterpret_cast(itm->GetData())); -} - -pcstr CUIVersionList::GetCurrentVersionName() const -{ - const SVersionDescription* desc = GetCurrentItem(); - return desc ? desc->name.c_str() : ""; -} - -pcstr CUIVersionList::GetCurrentVersionDescr() const -{ - const SVersionDescription* desc = GetCurrentItem(); - return desc ? desc->description.c_str() : ""; -} - -size_t CUIVersionList::GetItemsCount() const { return itemsCount; } - -void CUIVersionList::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) -{ - if (pWnd == versionsList) - { - switch (msg) - { - case LIST_ITEM_CLICKED: - { - GetMessageTarget()->SendMessage(this, LIST_ITEM_CLICKED, pData); - break; - } - case WINDOW_LBUTTON_DB_CLICK: - { - GetMessageTarget()->SendMessage(this, WINDOW_LBUTTON_DB_CLICK, pData); - break; - } - } - } -} - -void CUIVersionList::SwitchToSelectedVersion() const -{ - CUIListBoxItem* itm = versionsList->GetSelectedItem(); - if (itm) - { - size_t idx = reinterpret_cast(itm->GetData()); - CVersionSwitcher::SwitchToGameVer(idx, CVersionSwitcher::SWITCH_TO_MAINMENU); - } -} diff --git a/src/xrGame/ui/UIVersionList.h b/src/xrGame/ui/UIVersionList.h deleted file mode 100644 index a7a79c4c9eb..00000000000 --- a/src/xrGame/ui/UIVersionList.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "xrUICore/Windows/UIWindow.h" -#include "xrUICore/ListBox/UIListBox.h" - -struct SVersionDescription; - -class CUIVersionList final : public CUIWindow -{ - CUIListBox* versionsList; - CUIFrameLineWnd* header; - CUIFrameWindow* frame; - - size_t itemsCount; - -public: - CUIVersionList(); - void InitFromXml(CUIXml& xml_doc, const char* path); - pcstr GetCurrentVersionName() const; - pcstr GetCurrentVersionDescr() const; - void SwitchToSelectedVersion() const; - const SVersionDescription* GetCurrentItem() const; - size_t GetItemsCount() const; - - virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); - - pcstr GetDebugType() override { return "CUIVersionList"; } - -private: - void UpdateVersionList(); -}; diff --git a/src/xrGame/ui/UIWindow_script.cpp b/src/xrGame/ui/UIWindow_script.cpp index 8705c5df9a3..132679010ab 100644 --- a/src/xrGame/ui/UIWindow_script.cpp +++ b/src/xrGame/ui/UIWindow_script.cpp @@ -10,7 +10,6 @@ #include "UIMapInfo.h" #include "xrUICore/ComboBox/UIComboBox.h" #include "UIMapList.h" -#include "UIVersionList.h" #include "ScriptXMLInit.h" #include "xrScriptEngine/ScriptExporter.hpp" @@ -173,21 +172,6 @@ SCRIPT_EXPORT(CUIMapList, (CUIWindow), ]; }); -SCRIPT_EXPORT(CUIVersionList, (CUIWindow), -{ - using namespace luabind; - - module(luaState) - [ - class_("CUIVersionList") - .def(constructor<>()) - .def("GetCurrentVersionName", &CUIVersionList::GetCurrentVersionName) - .def("GetCurrentVersionDescr", &CUIVersionList::GetCurrentVersionDescr) - .def("GetItemsCount", &CUIVersionList::GetItemsCount) - .def("SwitchToSelectedVersion", &CUIVersionList::SwitchToSelectedVersion) - ]; -}); - SCRIPT_EXPORT(EnumGameIDs, (), { using namespace luabind; diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj index 762c7b46e36..1fc2352e6c6 100644 --- a/src/xrGame/xrGame.vcxproj +++ b/src/xrGame/xrGame.vcxproj @@ -1390,7 +1390,6 @@ - @@ -1399,7 +1398,6 @@ - @@ -3365,7 +3363,6 @@ - @@ -3385,7 +3382,6 @@ pch_script.h $(IntDir)$(ProjectName)_script.pch - pch_script.h diff --git a/src/xrGame/xrGame.vcxproj.filters b/src/xrGame/xrGame.vcxproj.filters index ba820c81759..6ec15dde90f 100644 --- a/src/xrGame/xrGame.vcxproj.filters +++ b/src/xrGame/xrGame.vcxproj.filters @@ -2233,9 +2233,6 @@ {f7b72e14-4fc5-4054-98a9-cff48b3fc45b} - - {04c90fd3-e247-4f21-b715-8dc556986837} - {e4a3fb7b-b6ee-40f3-a25a-be388178d29e} @@ -6452,10 +6449,6 @@ Core\Server\Games\server\base - - - UI\Multiplayer\MM_MP\VersionList - UI\Common\Inventory @@ -9820,10 +9813,6 @@ Core\Server\Games\client\base - - - UI\Multiplayer\MM_MP\VersionList - UI\Common\Inventory From 14c469276a6d9730b20bb5f1dd5eef8a25cd8fd3 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 17 Jun 2024 01:01:42 +0500 Subject: [PATCH 472/497] Removed unmodified vanilla message_box.xml This partially reverts d78d6b819254a69ee036324f3c079d9f9355ad33. --- res/gamedata/configs/ui/message_box.xml | 586 -------------------- res/gamedata/configs/ui/message_box_16.xml | 587 --------------------- 2 files changed, 1173 deletions(-) delete mode 100644 res/gamedata/configs/ui/message_box.xml delete mode 100644 res/gamedata/configs/ui/message_box_16.xml diff --git a/res/gamedata/configs/ui/message_box.xml b/res/gamedata/configs/ui/message_box.xml deleted file mode 100644 index 317a5937edb..00000000000 --- a/res/gamedata/configs/ui/message_box.xml +++ /dev/null @@ -1,586 +0,0 @@ - - - ui_inGame2_message_box - - level_changer_invitation - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - level_changer_invitation - - - button_ok - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_error - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_file_name_is_empty - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_delete_existing_file_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_file_exist_owerwrite_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - You can buy a spawn for 1000 $. Press Yes to pay - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_quit_windows_message - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_want_to_leave_game_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_load_game_confirm - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_invalid_saved_game - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_invalid_host - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_invalid_pass - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_sess_full - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_rejected_server - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_invalid - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_in_use - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_disabled - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_version_differs - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_err_gs_not_available - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_err_sb_master_server_conn_fail - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_new_patch - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_no_new_patch - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_voting_disabled - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_select_one_map - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_need_restart - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_cant_run_r2 - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_patch_download_error - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_patch_download_success - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_connecting_to_masterserver - - - button_ok - ui_mm_cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_kicked_by_server - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_error_loading - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - a - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - a - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - mm_mp_host_port - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - mm_mp_userpassword - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - download_map - - - - ui_inGame2_edit_box_1 - - - button_copy - ui_st_btn_copy_url - ui_inGame2_Mp_bigbuttone - - - button_yes - ui_st_btn_download_map - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - - - - button_cancel_login - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - - - - - ui_inGame2_message_box - - - - - - - ui_inGame2_message_box - - - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - mm_mp_login - - - - ui_inGame2_edit_box_1 - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - diff --git a/res/gamedata/configs/ui/message_box_16.xml b/res/gamedata/configs/ui/message_box_16.xml deleted file mode 100644 index 5573c5d75c0..00000000000 --- a/res/gamedata/configs/ui/message_box_16.xml +++ /dev/null @@ -1,587 +0,0 @@ - - - ui_inGame2_message_box - - level_changer_invitation - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - level_changer_invitation - - - button_ok - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_error - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_file_name_is_empty - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_delete_existing_file_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_file_exist_owerwrite_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - You can buy a spawn for 1000 $. Press Yes to pay - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_quit_windows_message - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_want_to_leave_game_q - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_load_game_confirm - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_invalid_saved_game - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_invalid_host - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_invalid_pass - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_sess_full - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_rejected_server - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_invalid - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_in_use - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_cdkey_disabled - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_version_differs - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_err_gs_not_available - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_err_sb_master_server_conn_fail - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_new_patch - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_conn_no_new_patch - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_voting_disabled - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_select_one_map - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_mm_need_restart - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_cant_run_r2 - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_patch_download_error - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_patch_download_success - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_connecting_to_masterserver - - - button_ok - ui_mm_cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_kicked_by_server - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - ui_st_error_loading - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - a - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - a - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - mm_mp_host_port - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - mm_mp_userpassword - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - ui_inGame2_message_box - - download_map - - - - ui_inGame2_edit_box_1 - - - button_copy - ui_st_btn_copy_url - ui_inGame2_Mp_bigbuttone - - - button_yes - ui_st_btn_download_map - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - - - - button_cancel_login - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - - - - - ui_inGame2_message_box - - - - - - - ui_inGame2_message_box - - - - - button_ok - Btn_OK - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - - - - button_yes - Btn_Yes - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_No - ui_inGame2_Mp_bigbuttone - - - - - ui_inGame2_message_box - - mm_mp_login - - - - ui_inGame2_edit_box_1 - - - mm_mp_password - - - - ui_inGame2_edit_box_1 - - - button_yes - Btn_OK - ui_inGame2_Mp_bigbuttone - - - button_no - Btn_Cancel - ui_inGame2_Mp_bigbuttone - - - From b5496f142f166c38a96f7a63c6fc320c6dec0c47 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 29 Jun 2024 14:36:50 +0500 Subject: [PATCH 473/497] Fix compilation with Visual Studio 17.10 --- src/xrGame/CustomRocket.cpp | 7 +++++++ src/xrPhysics/tri-colliderknoopc/dcTriangle.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/xrGame/CustomRocket.cpp b/src/xrGame/CustomRocket.cpp index c04259cbecc..1c17a1cb8a5 100644 --- a/src/xrGame/CustomRocket.cpp +++ b/src/xrGame/CustomRocket.cpp @@ -180,6 +180,12 @@ void CCustomRocket::create_physic_shell() // Rocket specific functions ////////////////////////////////////////////////////////////////////////// +#pragma warning(push) + +// XXX: maybe update ODE to a newer version +// The warning happens on line 241: l_pMYU->last_pos[0] != -dInfinity +#pragma warning(disable : 4756) + void CCustomRocket::ObjectContactCallback( bool& do_colide, bool bo1, dContact& c, SGameMtl* material_1, SGameMtl* material_2) { @@ -291,6 +297,7 @@ void CCustomRocket::ObjectContactCallback( { } } +#pragma warning(pop) void CCustomRocket::Load(LPCSTR section) { diff --git a/src/xrPhysics/tri-colliderknoopc/dcTriangle.h b/src/xrPhysics/tri-colliderknoopc/dcTriangle.h index 14362498d56..b403b3e6a0f 100644 --- a/src/xrPhysics/tri-colliderknoopc/dcTriangle.h +++ b/src/xrPhysics/tri-colliderknoopc/dcTriangle.h @@ -1,4 +1,9 @@ #pragma once + +// XXX: maybe update ODE to a newer version +// The warning happens on lines 23-24 when assigning to -dInfinity +#pragma warning(disable : 4756) + struct Triangle { // dReal* v0; @@ -20,3 +25,5 @@ struct Triangle #endif } }; + +#pragma warning(pop) From 80d99e4a90e5b198abb53ce745f25df2665e7eb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:19:31 +0000 Subject: [PATCH 474/497] build(deps): bump Externals/sse2neon from `42c7047` to `4874418` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `42c7047` to `4874418`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/42c704755d3ec218ed9126a122f0a667beeb630a...48744186a26e04d767f77255623f81e79011c423) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 42c704755d3..48744186a26 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 42c704755d3ec218ed9126a122f0a667beeb630a +Subproject commit 48744186a26e04d767f77255623f81e79011c423 From eaa647ce3de0fd9e61df5dd254d62665839c82fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:19:33 +0000 Subject: [PATCH 475/497] build(deps): bump Externals/zlib from `0f51fb4` to `534864b` Bumps [Externals/zlib](https://github.com/madler/zlib) from `0f51fb4` to `534864b`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/0f51fb4933fc9ce18199cb2554dacea8033e7fd3...534864bccd78812648ad1beaccdeec7c9d47aeef) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 0f51fb4933f..534864bccd7 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 0f51fb4933fc9ce18199cb2554dacea8033e7fd3 +Subproject commit 534864bccd78812648ad1beaccdeec7c9d47aeef From 083f9e51c29b9d7405e88d1ed3bfdf609efa5fcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 12:57:48 +0000 Subject: [PATCH 476/497] build(deps): bump Externals/zlib from `534864b` to `3adaa09` Bumps [Externals/zlib](https://github.com/madler/zlib) from `534864b` to `3adaa09`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/534864bccd78812648ad1beaccdeec7c9d47aeef...3adaa095a7a6c3f2cc00f73311f9bc8688c21aa7) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 534864bccd7..3adaa095a7a 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 534864bccd78812648ad1beaccdeec7c9d47aeef +Subproject commit 3adaa095a7a6c3f2cc00f73311f9bc8688c21aa7 From e083209f3319b04a49fe5fc33c68643d867c208d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 12:19:01 +0000 Subject: [PATCH 477/497] build(deps): bump Externals/zlib from `3adaa09` to `ceadaf2` Bumps [Externals/zlib](https://github.com/madler/zlib) from `3adaa09` to `ceadaf2`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/3adaa095a7a6c3f2cc00f73311f9bc8688c21aa7...ceadaf28dfa48dbf238a0ddb884d4c543b4170e8) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index 3adaa095a7a..ceadaf28dfa 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit 3adaa095a7a6c3f2cc00f73311f9bc8688c21aa7 +Subproject commit ceadaf28dfa48dbf238a0ddb884d4c543b4170e8 From 091ad634bc1965cb66ba2bbc6309d484681628dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 12:25:35 +0000 Subject: [PATCH 478/497] build(deps): bump cross-platform-actions/action from 0.24.0 to 0.25.0 Bumps [cross-platform-actions/action](https://github.com/cross-platform-actions/action) from 0.24.0 to 0.25.0. - [Release notes](https://github.com/cross-platform-actions/action/releases) - [Changelog](https://github.com/cross-platform-actions/action/blob/master/changelog.md) - [Commits](https://github.com/cross-platform-actions/action/compare/v0.24.0...v0.25.0) --- updated-dependencies: - dependency-name: cross-platform-actions/action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/cibuild.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 65af2a85fde..5accb77cf16 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -196,7 +196,7 @@ jobs: submodules: recursive - name: Setup ${{ matrix.platform.name }} and packages - uses: cross-platform-actions/action@v0.24.0 + uses: cross-platform-actions/action@v0.25.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -209,7 +209,7 @@ jobs: run: ${{ matrix.platform.install-cmd }} - name: Run CMake - uses: cross-platform-actions/action@v0.24.0 + uses: cross-platform-actions/action@v0.25.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} @@ -222,7 +222,7 @@ jobs: run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.Configuration }} -DCMAKE_UNITY_BUILD=ON - name: Run CMake Build - uses: cross-platform-actions/action@v0.24.0 + uses: cross-platform-actions/action@v0.25.0 with: operating_system: ${{ matrix.platform.os }} architecture: ${{ matrix.platform.arch }} From 1527691960a7224b3763ccb8ac99f0fb5d3a9b81 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 29 Jun 2024 14:57:44 +0500 Subject: [PATCH 479/497] xrGame/ui/UIMap.cpp: reduce code width No functional changes --- src/xrGame/ui/UIMap.cpp | 58 ++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/xrGame/ui/UIMap.cpp b/src/xrGame/ui/UIMap.cpp index 1c419e5ca25..196ff37f51e 100644 --- a/src/xrGame/ui/UIMap.cpp +++ b/src/xrGame/ui/UIMap.cpp @@ -391,46 +391,46 @@ void CUILevelMap::Draw() for (auto it = m_ChildWndList.begin(); m_ChildWndList.end() != it; ++it) { CMapSpot* sp = smart_cast((*it)); - if (sp) + if (!sp) + continue; + + if (sp->m_bScale) { - if (sp->m_bScale) + Fvector2 sz = sp->m_originSize; + // XXX: try to remove if-else branches and use common code path + if (ShadowOfChernobylMode) + { + sz.mul(gmz); + sp->SetWndSize(sz); + } + else if (ClearSkyMode) { - Fvector2 sz = sp->m_originSize; - // XXX: try to remove if-else branches and use common code path - if (ShadowOfChernobylMode) + if (gmz > sp->m_scale_bounds.x && gmz < sp->m_scale_bounds.y) { - sz.mul(gmz); + float k = (gmz - sp->m_scale_bounds.x) / (sp->m_scale_bounds.y - sp->m_scale_bounds.x); + sz.mul(k); sp->SetWndSize(sz); } - else if (ClearSkyMode) + else if (gmz > sp->m_scale_bounds.y) { - if (gmz > sp->m_scale_bounds.x && gmz < sp->m_scale_bounds.y) - { - float k = (gmz - sp->m_scale_bounds.x) / (sp->m_scale_bounds.y - sp->m_scale_bounds.x); - sz.mul(k); - sp->SetWndSize(sz); - } - else if (gmz > sp->m_scale_bounds.y) - { - sp->SetWndSize(sz); - } + sp->SetWndSize(sz); } - else // COP - { - float k = gmz; + } + else // COP + { + float k = gmz; - if (gmz > sp->m_scale_bounds.y) - k = sp->m_scale_bounds.y; - else if (gmz < sp->m_scale_bounds.x) - k = sp->m_scale_bounds.x; + if (gmz > sp->m_scale_bounds.y) + k = sp->m_scale_bounds.y; + else if (gmz < sp->m_scale_bounds.x) + k = sp->m_scale_bounds.x; - sz.mul(k); - sp->SetWndSize(sz); - } + sz.mul(k); + sp->SetWndSize(sz); } - else if (sp->m_scale_bounds.x > 0.0f) - sp->SetVisible(sp->m_scale_bounds.x < gmz); } + else if (sp->m_scale_bounds.x > 0.0f) + sp->SetVisible(sp->m_scale_bounds.x < gmz); } } inherited::Draw(); From 195be7bef0c2149544caa0962cd623c93d050f2e Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Jul 2024 22:02:51 +0500 Subject: [PATCH 480/497] Removed xrD3D9-Null This was needed for DX9 renderer, but it was removed several months ago. --- src/engine.sln | 37 - src/xrD3D9-Null/IDirect3D9.cpp | 135 ---- src/xrD3D9-Null/IDirect3D9.h | 63 -- src/xrD3D9-Null/IDirect3DCubeTexture9.cpp | 173 ---- src/xrD3D9-Null/IDirect3DCubeTexture9.h | 61 -- src/xrD3D9-Null/IDirect3DDevice9.cpp | 737 ------------------ src/xrD3D9-Null/IDirect3DDevice9.h | 198 ----- src/xrD3D9-Null/IDirect3DDevice9_Caps.cpp | 178 ----- src/xrD3D9-Null/IDirect3DIndexBuffer9.cpp | 115 --- src/xrD3D9-Null/IDirect3DIndexBuffer9.h | 49 -- src/xrD3D9-Null/IDirect3DPixelShader9.cpp | 58 -- src/xrD3D9-Null/IDirect3DPixelShader9.h | 27 - src/xrD3D9-Null/IDirect3DQuery9.cpp | 94 --- src/xrD3D9-Null/IDirect3DQuery9.h | 36 - src/xrD3D9-Null/IDirect3DStateBlock9.cpp | 63 -- src/xrD3D9-Null/IDirect3DStateBlock9.h | 28 - src/xrD3D9-Null/IDirect3DSurface9.cpp | 169 ---- src/xrD3D9-Null/IDirect3DSurface9.h | 56 -- src/xrD3D9-Null/IDirect3DTexture9.cpp | 171 ---- src/xrD3D9-Null/IDirect3DTexture9.h | 60 -- src/xrD3D9-Null/IDirect3DVertexBuffer9.cpp | 117 --- src/xrD3D9-Null/IDirect3DVertexBuffer9.h | 49 -- .../IDirect3DVertexDeclaration9.cpp | 58 -- src/xrD3D9-Null/IDirect3DVertexDeclaration9.h | 27 - src/xrD3D9-Null/IDirect3DVertexShader9.cpp | 58 -- src/xrD3D9-Null/IDirect3DVertexShader9.h | 27 - src/xrD3D9-Null/ReadMe.txt | 32 - src/xrD3D9-Null/stdafx.cpp | 1 - src/xrD3D9-Null/stdafx.h | 10 - src/xrD3D9-Null/xrD3D9-Null.cpp | 53 -- src/xrD3D9-Null/xrD3D9-Null.def | 3 - src/xrD3D9-Null/xrD3D9-Null.h | 15 - src/xrD3D9-Null/xrD3D9-Null.vcxproj | 107 --- src/xrD3D9-Null/xrD3D9-Null.vcxproj.filters | 161 ---- src/xrD3D9-Null/xrD3D9-Null_OutProc.cpp | 37 - src/xrD3D9-Null/xrD3D9-Null_OutProc.h | 14 - src/xrNetServer/NET_AuthCheck.cpp | 1 - 37 files changed, 3278 deletions(-) delete mode 100644 src/xrD3D9-Null/IDirect3D9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3D9.h delete mode 100644 src/xrD3D9-Null/IDirect3DCubeTexture9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DCubeTexture9.h delete mode 100644 src/xrD3D9-Null/IDirect3DDevice9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DDevice9.h delete mode 100644 src/xrD3D9-Null/IDirect3DDevice9_Caps.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DIndexBuffer9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DIndexBuffer9.h delete mode 100644 src/xrD3D9-Null/IDirect3DPixelShader9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DPixelShader9.h delete mode 100644 src/xrD3D9-Null/IDirect3DQuery9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DQuery9.h delete mode 100644 src/xrD3D9-Null/IDirect3DStateBlock9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DStateBlock9.h delete mode 100644 src/xrD3D9-Null/IDirect3DSurface9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DSurface9.h delete mode 100644 src/xrD3D9-Null/IDirect3DTexture9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DTexture9.h delete mode 100644 src/xrD3D9-Null/IDirect3DVertexBuffer9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DVertexBuffer9.h delete mode 100644 src/xrD3D9-Null/IDirect3DVertexDeclaration9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DVertexDeclaration9.h delete mode 100644 src/xrD3D9-Null/IDirect3DVertexShader9.cpp delete mode 100644 src/xrD3D9-Null/IDirect3DVertexShader9.h delete mode 100644 src/xrD3D9-Null/ReadMe.txt delete mode 100644 src/xrD3D9-Null/stdafx.cpp delete mode 100644 src/xrD3D9-Null/stdafx.h delete mode 100644 src/xrD3D9-Null/xrD3D9-Null.cpp delete mode 100644 src/xrD3D9-Null/xrD3D9-Null.def delete mode 100644 src/xrD3D9-Null/xrD3D9-Null.h delete mode 100644 src/xrD3D9-Null/xrD3D9-Null.vcxproj delete mode 100644 src/xrD3D9-Null/xrD3D9-Null.vcxproj.filters delete mode 100644 src/xrD3D9-Null/xrD3D9-Null_OutProc.cpp delete mode 100644 src/xrD3D9-Null/xrD3D9-Null_OutProc.h diff --git a/src/engine.sln b/src/engine.sln index f669f1db4f1..9c2788283ab 100644 --- a/src/engine.sln +++ b/src/engine.sln @@ -11,14 +11,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XR_3DA", "xr_3da\xr_3da.vcx EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dedicated", "dedicated", "{3FC858CB-4888-42FF-ABC5-82DAECB59C2C}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Externals", "Externals", "{2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODE", "..\Externals\ODE.vcxproj", "{1BF75FEB-87DD-486C-880B-227987D191C2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrD3D9-Null", "xrD3D9-Null\xrD3D9-Null.vcxproj", "{0899B131-F1D4-4876-9BA1-67AC821DB9E1}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrCompress", "utils\xrCompress\xrCompress.vcxproj", "{EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrSE_Factory", "utils\xrSE_Factory\xrSE_Factory.vcxproj", "{3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61}" @@ -197,38 +193,6 @@ Global {1BF75FEB-87DD-486C-880B-227987D191C2}.Release|x64.Build.0 = Release|x64 {1BF75FEB-87DD-486C-880B-227987D191C2}.Release|x86.ActiveCfg = Release|Win32 {1BF75FEB-87DD-486C-880B-227987D191C2}.Release|x86.Build.0 = Release|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|ARM.ActiveCfg = Debug|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|ARM.Build.0 = Debug|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|ARM64.ActiveCfg = Debug|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|ARM64.Build.0 = Debug|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|x64.ActiveCfg = Debug|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|x64.Build.0 = Debug|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|x86.ActiveCfg = Debug|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Debug|x86.Build.0 = Debug|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|ARM.ActiveCfg = Mixed|ARM - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|ARM.Build.0 = Mixed|ARM - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|ARM64.ActiveCfg = Mixed|ARM64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|ARM64.Build.0 = Mixed|ARM64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|x64.ActiveCfg = Mixed|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|x64.Build.0 = Mixed|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|x86.ActiveCfg = Mixed|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Mixed|x86.Build.0 = Mixed|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|ARM.ActiveCfg = Release Master Gold|ARM - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|ARM.Build.0 = Release Master Gold|ARM - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|ARM64.ActiveCfg = Release Master Gold|ARM64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|ARM64.Build.0 = Release Master Gold|ARM64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|x64.ActiveCfg = Release Master Gold|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|x64.Build.0 = Release Master Gold|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|x86.ActiveCfg = Release Master Gold|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release Master Gold|x86.Build.0 = Release Master Gold|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|ARM.ActiveCfg = Release|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|ARM.Build.0 = Release|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|ARM64.ActiveCfg = Release|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|ARM64.Build.0 = Release|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x64.ActiveCfg = Release|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x64.Build.0 = Release|x64 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x86.ActiveCfg = Release|Win32 - {0899B131-F1D4-4876-9BA1-67AC821DB9E1}.Release|x86.Build.0 = Release|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.ActiveCfg = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM.Build.0 = Debug|Win32 {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -1480,7 +1444,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {1BF75FEB-87DD-486C-880B-227987D191C2} = {2BFC806B-CE92-4EA4-8FE8-5F2EA54BA348} - {0899B131-F1D4-4876-9BA1-67AC821DB9E1} = {3FC858CB-4888-42FF-ABC5-82DAECB59C2C} {EF76867B-6EB8-4DC0-A1D6-E964FAD6FC7B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {3AD26FD3-4F52-4E22-A4CF-AD4C49E74C61} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} {1924EF23-A05E-40E5-93F2-6CCD64BE1F8B} = {89F6A7EE-3BBE-45D3-A8A8-5D9366CD987B} diff --git a/src/xrD3D9-Null/IDirect3D9.cpp b/src/xrD3D9-Null/IDirect3D9.cpp deleted file mode 100644 index 581116f0b30..00000000000 --- a/src/xrD3D9-Null/IDirect3D9.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "stdafx.h" -#include "IDirect3D9.h" -#include "IDirect3DDevice9.h" -#include "xrD3D9-Null_OutProc.h" -#include - -const GUID DECLSPEC_SELECTANY IID_IDirect3D9; - -xrIDirect3D9::xrIDirect3D9() : m_refCount(0) -{ - APIDEBUG("xrIDirect3D9::xrIDirect3D9"); - //#ifdef D3D_DEBUG_INFO - Version = NULL; - //#endif -}; - -ULONG xrIDirect3D9::AddRef(void) -{ - APIDEBUG("xrIDirect3D9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3D9::Release(void) -{ - APIDEBUG("xrIDirect3D9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -HRESULT xrIDirect3D9::QueryInterface(const IID& iid, void FAR* FAR* ppvObj) -{ - APIDEBUG("xrIDirect3D9::QueryInterface"); - if (iid == IID_IUnknown || iid == IID_IDirect3D9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -HRESULT xrIDirect3D9::RegisterSoftwareDevice(void* pInitializeFunction) -{ - APIDEBUG("xrIDirect3D9::RegisterSoftwareDevice"); - return S_OK; -}; -UINT xrIDirect3D9::GetAdapterCount() -{ - APIDEBUG("xrIDirect3D9::GetAdapterCount"); - return 1; -}; - -HRESULT xrIDirect3D9::GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) -{ - APIDEBUG("xrIDirect3D9::GetAdapterIdentifier"); - sprintf_s(pIdentifier->Driver, "Default Driver"); - sprintf_s(pIdentifier->Description, "Default X-Ray Dedicated Adapter"); - sprintf_s(pIdentifier->DeviceName, "Dedicated"); - return S_OK; -}; -UINT xrIDirect3D9::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) -{ - APIDEBUG("xrIDirect3D9::GetAdapterModeCount"); - return 1; -}; - -HRESULT xrIDirect3D9::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) -{ - APIDEBUG("xrIDirect3D9::EnumAdapterModes"); - return S_OK; -}; -HRESULT xrIDirect3D9::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) -{ - APIDEBUG("xrIDirect3D9::GetAdapterDisplayMode"); - pMode->Format = D3DFMT_A8R8G8B8; - return S_OK; -}; -HRESULT xrIDirect3D9::CheckDeviceType( - UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) -{ - APIDEBUG("xrIDirect3D9::CheckDeviceType"); - return S_OK; -}; -HRESULT xrIDirect3D9::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, - D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) -{ - APIDEBUG("xrIDirect3D9::CheckDeviceFormat"); - return S_OK; -}; -HRESULT xrIDirect3D9::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, - BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) -{ - APIDEBUG("xrIDirect3D9::CheckDeviceMultiSampleType"); - return S_OK; -}; -HRESULT xrIDirect3D9::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, - D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) -{ - APIDEBUG("xrIDirect3D9::CheckDepthStencilMatch"); - return S_OK; -}; -HRESULT xrIDirect3D9::CheckDeviceFormatConversion( - UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) -{ - APIDEBUG("xrIDirect3D9::CheckDeviceFormatConversion"); - return S_OK; -}; -HRESULT xrIDirect3D9::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) -{ - APIDEBUG("xrIDirect3D9::GetDeviceCaps"); - if (pCaps) - ZeroMemory(pCaps, sizeof(D3DCAPS9)); - return S_OK; -}; -HMONITOR xrIDirect3D9::GetAdapterMonitor(UINT Adapter) -{ - APIDEBUG("xrIDirect3D9::GetAdapterMonitor"); - return NULL; -}; - -HRESULT xrIDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, - D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) -{ - APIDEBUG("xrIDirect3D9::CreateDevice"); - *ppReturnedDeviceInterface = NULL; - xrIDirect3DDevice9* I = new xrIDirect3DDevice9(this, pPresentationParameters); - *ppReturnedDeviceInterface = I; - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3D9.h b/src/xrD3D9-Null/IDirect3D9.h deleted file mode 100644 index d2265a9577e..00000000000 --- a/src/xrD3D9-Null/IDirect3D9.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -/* -//--------------------------------- -#include "d3d9types.h" -#include "d3d9caps.h" - -#include "IDirect3DDevice9.h" -*/ -/* IID_IDirect3D9 */ -/* {81BDCBCA-64D4-426d-AE8D-AD0147F4275C} */ -// DEFINE_GUID(IID_IDirect3D9, 0x81bdcbca, 0x64d4, 0x426d, 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c); - -// interface DECLSPEC_UUID("81BDCBCA-64D4-426d-AE8D-AD0147F4275C") IDirect3D9; - -// typedef interface IDirect3D9 IDirect3D9; - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3D9 : public IDirect3D9 -{ -protected: - LONG m_refCount; - -public: - xrIDirect3D9(); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3D9 methods ***/ - HRESULT __stdcall RegisterSoftwareDevice(void* pInitializeFunction); - UINT __stdcall GetAdapterCount(); - HRESULT __stdcall GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier); - UINT __stdcall GetAdapterModeCount(UINT Adapter, D3DFORMAT Format); - HRESULT __stdcall EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode); - HRESULT __stdcall GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode); - HRESULT __stdcall CheckDeviceType( - UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed); - HRESULT __stdcall CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, - D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); - HRESULT __stdcall CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, - BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels); - HRESULT __stdcall CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, - D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat); - HRESULT __stdcall CheckDeviceFormatConversion( - UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); - HRESULT __stdcall GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps); - HMONITOR __stdcall GetAdapterMonitor(UINT Adapter); - HRESULT __stdcall CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, - D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); - - ///#ifdef D3D_DEBUG_INFO - LPCWSTR Version; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DCubeTexture9.cpp b/src/xrD3D9-Null/IDirect3DCubeTexture9.cpp deleted file mode 100644 index f15e5f78b79..00000000000 --- a/src/xrD3D9-Null/IDirect3DCubeTexture9.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DCubeTexture9.h" -#include "IDirect3DSurface9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DCubeTexture9; - -xrIDirect3DCubeTexture9::xrIDirect3DCubeTexture9(IDirect3DDevice9* pIDirect3DDevice9, UINT iWidth, UINT iHeight, - UINT iLevels, DWORD iUsage, D3DFORMAT iFormat, D3DPOOL iPool) - : m_refCount(0), Name(nullptr), Width(iWidth), Height(iHeight), Levels(iLevels), Usage(iUsage), Format(iFormat) - //#ifdef D3D_DEBUG_INFO - , - Pool(iPool), Priority(0) -//#endif -{ - APIDEBUG("xrIDirect3DCubeTexture9::xrIDirect3DCubeTexture9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; - //------------------------------------------------------------- - LOD = 0; - FilterType = D3DTEXTUREFILTERTYPE(0); - LockCount = 0; - CreationCallStack = nullptr; -} - -/*** IUnknown methods ***/ -HRESULT xrIDirect3DCubeTexture9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DCubeTexture9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DCubeTexture9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DCubeTexture9::AddRef() -{ - APIDEBUG("xrIDirect3DCubeTexture9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DCubeTexture9::Release() -{ - APIDEBUG("xrIDirect3DCubeTexture9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DBaseTexture9 methods ***/ -HRESULT xrIDirect3DCubeTexture9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -} -HRESULT xrIDirect3DCubeTexture9::SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DCubeTexture9::SetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DCubeTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DCubeTexture9::FreePrivateData(REFGUID refguid) -{ - APIDEBUG("xrIDirect3DCubeTexture9::FreePrivateData"); - return S_OK; -}; -DWORD xrIDirect3DCubeTexture9::SetPriority(DWORD PriorityNew) -{ - APIDEBUG("xrIDirect3DCubeTexture9::SetPriority"); - DWORD old = Priority; - Priority = PriorityNew; - return old; -}; -DWORD xrIDirect3DCubeTexture9::GetPriority() -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetPriority"); - return Priority; -}; -void xrIDirect3DCubeTexture9::PreLoad() { APIDEBUG("xrIDirect3DCubeTexture9::PreLoad"); }; -D3DRESOURCETYPE xrIDirect3DCubeTexture9::GetType() -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetType"); - return D3DRTYPE_TEXTURE; -}; -DWORD xrIDirect3DCubeTexture9::SetLOD(DWORD LODNew) -{ - APIDEBUG("xrIDirect3DCubeTexture9::SetLOD"); - DWORD old = LOD; - LOD = LODNew; - return old; -}; -DWORD xrIDirect3DCubeTexture9::GetLOD() -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetLOD"); - return LOD; -}; -DWORD xrIDirect3DCubeTexture9::GetLevelCount() -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetLevelCount"); - return Levels; -}; -HRESULT xrIDirect3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE iFilterType) -{ - APIDEBUG("xrIDirect3DCubeTexture9::SetAutoGenFilterType"); - FilterType = iFilterType; - return S_OK; -}; -D3DTEXTUREFILTERTYPE xrIDirect3DCubeTexture9::GetAutoGenFilterType() -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetAutoGenFilterType"); - return FilterType; -}; -void xrIDirect3DCubeTexture9::GenerateMipSubLevels() { APIDEBUG("xrIDirect3DCubeTexture9::GenerateMipSubLevels"); }; -HRESULT xrIDirect3DCubeTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetLevelDesc"); - - pDesc->Format = Format; - pDesc->Type = D3DRTYPE_TEXTURE; - pDesc->Usage = Usage; - pDesc->Pool = Pool; - - pDesc->MultiSampleType = D3DMULTISAMPLE_TYPE(0); - pDesc->MultiSampleQuality = 0; - pDesc->Width = Width; - pDesc->Height = Height; - - return S_OK; -}; - -HRESULT xrIDirect3DCubeTexture9::GetCubeMapSurface( - D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) -{ - APIDEBUG("xrIDirect3DCubeTexture9::GetCubeMapSurface"); - - *ppCubeMapSurface = NULL; - xrIDirect3DSurface9* I = - new xrIDirect3DSurface9(m_pIDirect3DDevice9, Width, Height, Format, D3DMULTISAMPLE_TYPE(0), 0); - *ppCubeMapSurface = I; - - return S_OK; -}; -HRESULT xrIDirect3DCubeTexture9::LockRect( - D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) -{ - APIDEBUG("xrIDirect3DCubeTexture9::LockRect"); - return S_OK; -}; -HRESULT xrIDirect3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level) -{ - APIDEBUG("xrIDirect3DCubeTexture9::UnlockRect"); - return S_OK; -}; -HRESULT xrIDirect3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) -{ - APIDEBUG("xrIDirect3DCubeTexture9::AddDirtyRect"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DCubeTexture9.h b/src/xrD3D9-Null/IDirect3DCubeTexture9.h deleted file mode 100644 index 417c5f93eaf..00000000000 --- a/src/xrD3D9-Null/IDirect3DCubeTexture9.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DCubeTexture9 : public IDirect3DCubeTexture9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DCubeTexture9(IDirect3DDevice9* pIDirect3DDevice9, UINT iWidth, UINT iHeight, UINT iLevels, DWORD iUsage, - D3DFORMAT iFormat, D3DPOOL iPool); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DBaseTexture9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); - HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData); - HRESULT __stdcall FreePrivateData(REFGUID refguid); - DWORD __stdcall SetPriority(DWORD PriorityNew); - DWORD __stdcall GetPriority(); - void __stdcall PreLoad(); - D3DRESOURCETYPE __stdcall GetType(); - DWORD __stdcall SetLOD(DWORD LODNew); - DWORD __stdcall GetLOD(); - DWORD __stdcall GetLevelCount(); - HRESULT __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType); - D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType(); - void __stdcall GenerateMipSubLevels(); - HRESULT __stdcall GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc); - HRESULT __stdcall GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface); - HRESULT __stdcall LockRect( - D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags); - HRESULT __stdcall UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level); - HRESULT __stdcall AddDirtyRect(D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect); - - //#ifdef D3D_DEBUG_INFO - LPCWSTR Name; - UINT Width; - UINT Height; - UINT Levels; - DWORD Usage; - D3DFORMAT Format; - D3DPOOL Pool; - DWORD Priority; - DWORD LOD; - D3DTEXTUREFILTERTYPE FilterType; - UINT LockCount; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DDevice9.cpp b/src/xrD3D9-Null/IDirect3DDevice9.cpp deleted file mode 100644 index f7632193df2..00000000000 --- a/src/xrD3D9-Null/IDirect3DDevice9.cpp +++ /dev/null @@ -1,737 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DDevice9.h" -#include "IDirect3DQuery9.h" -#include "IDirect3DSurface9.h" -#include "IDirect3DIndexBuffer9.h" -#include "IDirect3DVertexBuffer9.h" -#include "IDirect3DTexture9.h" -#include "IDirect3DVertexDeclaration9.h" -#include "IDirect3DVertexShader9.h" -#include "IDirect3DPixelShader9.h" -#include "IDirect3DStateBlock9.h" -#include "IDirect3DCubeTexture9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DDevice9; - -xrIDirect3DDevice9::xrIDirect3DDevice9(IDirect3D9* pDirect3D9, D3DPRESENT_PARAMETERS* pPresentationParameters) - : m_refCount(0) -{ - APIDEBUG("xrIDirect3DDevice9::xrIDirect3DDevice9"); - - m_pIDirect3D9 = pDirect3D9; - //#ifdef D3D_DEBUG_INFO - //------------------------------------------------------- - memset(&CreationParameters, 0, sizeof(CreationParameters)); - memcpy(&PresentParameters, pPresentationParameters, sizeof(PresentParameters)); - memset(&DisplayMode, 0, sizeof(DisplayMode)); - memset(&Caps, 0, sizeof(Caps)); - - AvailableTextureMem = 1 << 31; - SwapChains = 0; - Textures = 0; - VertexBuffers = 0; - IndexBuffers = 0; - VertexShaders = 0; - PixelShaders = 0; - - memset(&Viewport, 0, sizeof(Viewport)); - memset(&ProjectionMatrix, 0, sizeof(ProjectionMatrix)); - memset(&ViewMatrix, 0, sizeof(ViewMatrix)); - memset(&WorldMatrix, 0, sizeof(WorldMatrix)); - memset(&TextureMatrices, 0, sizeof(TextureMatrices)); - - FVF = 0; - VertexSize = 0; - VertexShaderVersion = 0; - PixelShaderVersion = 0; - SoftwareVertexProcessing = 0; - - memset(&Material, 0, sizeof(Material)); - memset(&Lights, 0, sizeof(Lights)); - memset(&LightsEnabled, 0, sizeof(LightsEnabled)); - - memset(&GammaRamp, 0, sizeof(GammaRamp)); - memset(&ScissorRect, 0, sizeof(ScissorRect)); - DialogBoxMode = FALSE; - //#endif -}; - -ULONG xrIDirect3DDevice9::AddRef(void) -{ - APIDEBUG("xrIDirect3DDevice9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DDevice9::Release(void) -{ - APIDEBUG("xrIDirect3DDevice9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return 0; - } - return m_refCount; -} - -HRESULT xrIDirect3DDevice9::QueryInterface(const IID& iid, void FAR* FAR* ppvObj) -{ - APIDEBUG("xrIDirect3DDevice9::QueryInterface"); - if (iid == IID_IUnknown || iid == IID_IDirect3DDevice9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -HRESULT xrIDirect3DDevice9::TestCooperativeLevel() -{ - APIDEBUG("xrIDirect3DDevice9::TestCooperativeLevel"); - return S_OK; -}; -UINT xrIDirect3DDevice9::GetAvailableTextureMem() -{ - APIDEBUG("xrIDirect3DDevice9::GetAvailableTextureMem"); - return AvailableTextureMem; -}; -HRESULT xrIDirect3DDevice9::EvictManagedResources() -{ - APIDEBUG("xrIDirect3DDevice9::EvictManagedResources"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetDirect3D(IDirect3D9** ppD3D9) -{ - APIDEBUG("xrIDirect3DDevice9::GetDirect3D"); - - m_pIDirect3D9->AddRef(); - *ppD3D9 = m_pIDirect3D9; - return S_OK; -}; - -HRESULT xrIDirect3DDevice9::GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE* pMode) -{ - APIDEBUG("xrIDirect3DDevice9::GetDisplayMode"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS* pParameters) -{ - APIDEBUG("xrIDirect3DDevice9::GetCreationParameters"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) -{ - APIDEBUG("xrIDirect3DDevice9::SetCursorProperties"); - return S_OK; -}; -void xrIDirect3DDevice9::SetCursorPosition(int X, int Y, DWORD Flags) -{ - APIDEBUG("xrIDirect3DDevice9::SetCursorPosition"); -}; -BOOL xrIDirect3DDevice9::ShowCursor(BOOL bShow) -{ - APIDEBUG("xrIDirect3DDevice9::ShowCursor"); - return bShow; -}; -HRESULT xrIDirect3DDevice9::CreateAdditionalSwapChain( - D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) -{ - APIDEBUG("xrIDirect3DDevice9::CreateAdditionalSwapChain"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) -{ - APIDEBUG("xrIDirect3DDevice9::GetSwapChain"); - return S_OK; -}; -UINT xrIDirect3DDevice9::GetNumberOfSwapChains() -{ - APIDEBUG("xrIDirect3DDevice9::GetNumberOfSwapChains"); - return 1; -}; -HRESULT xrIDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) -{ - APIDEBUG("xrIDirect3DDevice9::Reset"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::Present( - CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) -{ - APIDEBUG("xrIDirect3DDevice9::Present"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetBackBuffer( - UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) -{ - APIDEBUG("xrIDirect3DDevice9::GetBackBuffer"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) -{ - APIDEBUG("xrIDirect3DDevice9::GetRasterStatus"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs) -{ - APIDEBUG("xrIDirect3DDevice9::SetDialogBoxMode"); - return S_OK; -}; -void xrIDirect3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) -{ - APIDEBUG("xrIDirect3DDevice9::SetGammaRamp"); -}; -void xrIDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp) -{ - APIDEBUG("xrIDirect3DDevice9::GetGammaRamp"); -}; - -HRESULT xrIDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, - D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateTexture"); - - *ppTexture = NULL; - xrIDirect3DTexture9* I = new xrIDirect3DTexture9(this, Width, Height, Levels, Usage, Format, Pool); - *ppTexture = I; - - return S_OK; -}; - -HRESULT xrIDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, - D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateVolumeTexture"); - return S_OK; -}; - -HRESULT xrIDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, - IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateCubeTexture"); - - *ppCubeTexture = NULL; - xrIDirect3DCubeTexture9* I = new xrIDirect3DCubeTexture9(this, EdgeLength, EdgeLength, Levels, Usage, Format, Pool); - *ppCubeTexture = I; - - return S_OK; -}; - -HRESULT xrIDirect3DDevice9::CreateVertexBuffer( - UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateVertexBuffer"); - - *ppVertexBuffer = NULL; - xrIDirect3DVertexBuffer9* I = new xrIDirect3DVertexBuffer9(this, Length, Usage, FVF, Pool); - *ppVertexBuffer = I; - - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, - IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateIndexBuffer"); - - *ppIndexBuffer = NULL; - xrIDirect3DIndexBuffer9* I = new xrIDirect3DIndexBuffer9(this, Length, Usage, Format, Pool); - *ppIndexBuffer = I; - - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, - D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, - HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateRenderTarget"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, - D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, - HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateDepthStencilSurface"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, - IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) -{ - APIDEBUG("xrIDirect3DDevice9::UpdateSurface"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::UpdateTexture( - IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) -{ - APIDEBUG("xrIDirect3DDevice9::UpdateTexture"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) -{ - APIDEBUG("xrIDirect3DDevice9::GetRenderTargetData"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9* pDestSurface) -{ - APIDEBUG("xrIDirect3DDevice9::GetFrontBufferData"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::StretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, - IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) -{ - APIDEBUG("xrIDirect3DDevice9::StretchRect"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::ColorFill(IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) -{ - APIDEBUG("xrIDirect3DDevice9::ColorFill"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateOffscreenPlainSurface( - UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) -{ - APIDEBUG("xrIDirect3DDevice9::CreateOffscreenPlainSurface"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) -{ - APIDEBUG("xrIDirect3DDevice9::SetRenderTarget"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) -{ - APIDEBUG("xrIDirect3DDevice9::GetRenderTarget"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) -{ - APIDEBUG("xrIDirect3DDevice9::SetDepthStencilSurface"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) -{ - APIDEBUG("xrIDirect3DDevice9::GetDepthStencilSurface"); - - *ppZStencilSurface = NULL; - xrIDirect3DSurface9* I = new xrIDirect3DSurface9(this, 0, 0, D3DFORMAT(0), D3DMULTISAMPLE_TYPE(0), 0); - *ppZStencilSurface = I; - - return S_OK; -}; -HRESULT xrIDirect3DDevice9::BeginScene() -{ - APIDEBUG("xrIDirect3DDevice9::BeginScene"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::EndScene() -{ - APIDEBUG("xrIDirect3DDevice9::EndScene"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::Clear( - DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) -{ - APIDEBUG("xrIDirect3DDevice9::Clear"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) -{ - APIDEBUG("xrIDirect3DDevice9::SetTransform"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) -{ - APIDEBUG("xrIDirect3DDevice9::GetTransform"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) -{ - APIDEBUG("xrIDirect3DDevice9::MultiplyTransform"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetViewport(CONST D3DVIEWPORT9* pViewport) -{ - APIDEBUG("xrIDirect3DDevice9::SetViewport"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetViewport(D3DVIEWPORT9* pViewport) -{ - APIDEBUG("xrIDirect3DDevice9::GetViewport"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial) -{ - APIDEBUG("xrIDirect3DDevice9::SetMaterial"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetMaterial(D3DMATERIAL9* pMaterial) -{ - APIDEBUG("xrIDirect3DDevice9::GetMaterial"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetLight(DWORD Index, CONST D3DLIGHT9*) -{ - APIDEBUG("xrIDirect3DDevice9::SetLight"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetLight(DWORD Index, D3DLIGHT9*) -{ - APIDEBUG("xrIDirect3DDevice9::GetLight"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::LightEnable(DWORD Index, BOOL Enable) -{ - APIDEBUG("xrIDirect3DDevice9::LightEnable"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetLightEnable(DWORD Index, BOOL* pEnable) -{ - APIDEBUG("xrIDirect3DDevice9::GetLightEnable"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetClipPlane(DWORD Index, CONST float* pPlane) -{ - APIDEBUG("xrIDirect3DDevice9::SetClipPlane"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetClipPlane(DWORD Index, float* pPlane) -{ - APIDEBUG("xrIDirect3DDevice9::GetClipPlane"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) -{ - APIDEBUG("xrIDirect3DDevice9::SetRenderState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue) -{ - APIDEBUG("xrIDirect3DDevice9::GetRenderState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) -{ - APIDEBUG("xrIDirect3DDevice9::CreateStateBlock"); - *ppSB = NULL; - xrIDirect3DStateBlock9* I = new xrIDirect3DStateBlock9(this); - *ppSB = I; - return S_OK; -}; -HRESULT xrIDirect3DDevice9::BeginStateBlock() -{ - APIDEBUG("xrIDirect3DDevice9::BeginStateBlock"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::EndStateBlock(IDirect3DStateBlock9** ppSB) -{ - APIDEBUG("xrIDirect3DDevice9::EndStateBlock"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetClipStatus(CONST D3DCLIPSTATUS9* pClipStatus) -{ - APIDEBUG("xrIDirect3DDevice9::SetClipStatus"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetClipStatus(D3DCLIPSTATUS9* pClipStatus) -{ - APIDEBUG("xrIDirect3DDevice9::GetClipStatus"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetTexture(DWORD Stage, IDirect3DBaseTexture9** ppTexture) -{ - APIDEBUG("xrIDirect3DDevice9::GetTexture"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture) -{ - APIDEBUG("xrIDirect3DDevice9::SetTexture"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) -{ - APIDEBUG("xrIDirect3DDevice9::GetTextureStageState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) -{ - APIDEBUG("xrIDirect3DDevice9::SetTextureStageState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) -{ - APIDEBUG("xrIDirect3DDevice9::GetSamplerState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) -{ - APIDEBUG("xrIDirect3DDevice9::SetSamplerState"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::ValidateDevice(DWORD* pNumPasses) -{ - APIDEBUG("xrIDirect3DDevice9::ValidateDevice"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetPaletteEntries(UINT PaletteNumber, CONST PALETTEENTRY* pEntries) -{ - APIDEBUG("xrIDirect3DDevice9::SetPaletteEntries"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY* pEntries) -{ - APIDEBUG("xrIDirect3DDevice9::GetPaletteEntries"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetCurrentTexturePalette(UINT PaletteNumber) -{ - APIDEBUG("xrIDirect3DDevice9::SetCurrentTexturePalette"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetCurrentTexturePalette(UINT* PaletteNumber) -{ - APIDEBUG("xrIDirect3DDevice9::GetCurrentTexturePalette"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetScissorRect(CONST RECT* pRect) -{ - APIDEBUG("xrIDirect3DDevice9::SetScissorRect"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetScissorRect(RECT* pRect) -{ - APIDEBUG("xrIDirect3DDevice9::GetScissorRect"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetSoftwareVertexProcessing(BOOL bSoftware) -{ - APIDEBUG("xrIDirect3DDevice9::SetSoftwareVertexProcessing"); - return S_OK; -}; -BOOL xrIDirect3DDevice9::GetSoftwareVertexProcessing() -{ - APIDEBUG("xrIDirect3DDevice9::GetSoftwareVertexProcessing"); - return TRUE; -}; -HRESULT xrIDirect3DDevice9::SetNPatchMode(float nSegments) -{ - APIDEBUG("xrIDirect3DDevice9::SetNPatchMode"); - return S_OK; -}; -float xrIDirect3DDevice9::GetNPatchMode() -{ - APIDEBUG("xrIDirect3DDevice9::GetNPatchMode"); - return 0.0f; -}; -HRESULT xrIDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) -{ - APIDEBUG("xrIDirect3DDevice9::DrawPrimitive"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DrawIndexedPrimitive( - D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) -{ - APIDEBUG("xrIDirect3DDevice9::DrawIndexedPrimitive"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DrawPrimitiveUP( - D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) -{ - APIDEBUG("xrIDirect3DDevice9::DrawPrimitiveUP"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, - UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, - CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) -{ - APIDEBUG("xrIDirect3DDevice9::DrawIndexedPrimitiveUP"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, - IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) -{ - APIDEBUG("xrIDirect3DDevice9::ProcessVertices"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateVertexDeclaration( - CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) -{ - APIDEBUG("xrIDirect3DDevice9::CreateVertexDeclaration"); - *ppDecl = NULL; - xrIDirect3DVertexDeclaration9* I = new xrIDirect3DVertexDeclaration9(this); - *ppDecl = I; - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) -{ - APIDEBUG("xrIDirect3DDevice9::SetVertexDeclaration"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl) -{ - APIDEBUG("xrIDirect3DDevice9::GetVertexDeclaration"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetFVF(DWORD FVF) -{ - APIDEBUG("xrIDirect3DDevice9::SetFVF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetFVF(DWORD* pFVF) -{ - APIDEBUG("xrIDirect3DDevice9::GetFVF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateVertexShader(CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader) -{ - APIDEBUG("xrIDirect3DDevice9::CreateVertexShader"); - *ppShader = NULL; - xrIDirect3DVertexShader9* I = new xrIDirect3DVertexShader9(this); - *ppShader = I; - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader) -{ - APIDEBUG("xrIDirect3DDevice9::SetVertexShader"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetVertexShader(IDirect3DVertexShader9** ppShader) -{ - APIDEBUG("xrIDirect3DDevice9::GetVertexShader"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetVertexShaderConstantF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetVertexShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetVertexShaderConstantF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetVertexShaderConstantI"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetVertexShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetVertexShaderConstantI"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetVertexShaderConstantB"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetVertexShaderConstantB"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetStreamSource( - UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) -{ - APIDEBUG("xrIDirect3DDevice9::SetStreamSource"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetStreamSource( - UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) -{ - APIDEBUG("xrIDirect3DDevice9::GetStreamSource"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) -{ - APIDEBUG("xrIDirect3DDevice9::SetStreamSourceFreq"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetStreamSourceFreq(UINT StreamNumber, UINT* pSetting) -{ - APIDEBUG("xrIDirect3DDevice9::GetStreamSourceFreq"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData) -{ - APIDEBUG("xrIDirect3DDevice9::SetIndices"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetIndices(IDirect3DIndexBuffer9** ppIndexData) -{ - APIDEBUG("xrIDirect3DDevice9::GetIndices"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreatePixelShader(CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader) -{ - APIDEBUG("xrIDirect3DDevice9::CreatePixelShader"); - *ppShader = NULL; - xrIDirect3DPixelShader9* I = new xrIDirect3DPixelShader9(this); - *ppShader = I; - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader) -{ - APIDEBUG("xrIDirect3DDevice9::SetPixelShader"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetPixelShader(IDirect3DPixelShader9** ppShader) -{ - APIDEBUG("xrIDirect3DDevice9::GetPixelShader"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetPixelShaderConstantF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetPixelShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetPixelShaderConstantF"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetPixelShaderConstantI(UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetPixelShaderConstantI"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetPixelShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetPixelShaderConstantI"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) -{ - APIDEBUG("xrIDirect3DDevice9::SetPixelShaderConstantB"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::GetPixelShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) -{ - APIDEBUG("xrIDirect3DDevice9::GetPixelShaderConstantB"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DrawRectPatch(UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) -{ - APIDEBUG("xrIDirect3DDevice9::DrawRectPatch"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DrawTriPatch(UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) -{ - APIDEBUG("xrIDirect3DDevice9::DrawTriPatch"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::DeletePatch(UINT Handle) -{ - APIDEBUG("xrIDirect3DDevice9::DeletePatch"); - return S_OK; -}; -HRESULT xrIDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) -{ - APIDEBUG("xrIDirect3DDevice9::CreateQuery"); - *ppQuery = NULL; - xrIDirect3DQuery9* I = new xrIDirect3DQuery9(this, Type); - *ppQuery = I; - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DDevice9.h b/src/xrD3D9-Null/IDirect3DDevice9.h deleted file mode 100644 index fcb37eebe30..00000000000 --- a/src/xrD3D9-Null/IDirect3DDevice9.h +++ /dev/null @@ -1,198 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DDevice9 : public IDirect3DDevice9 -{ -protected: - LONG m_refCount; - IDirect3D9* m_pIDirect3D9; - -public: - xrIDirect3DDevice9(IDirect3D9* pDirect3D9, D3DPRESENT_PARAMETERS* pPresentationParameters); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - HRESULT __stdcall TestCooperativeLevel(); - - UINT __stdcall GetAvailableTextureMem(); - HRESULT __stdcall EvictManagedResources(); - HRESULT __stdcall GetDirect3D(IDirect3D9** ppD3D9); - HRESULT __stdcall GetDeviceCaps(D3DCAPS9* pCaps); - HRESULT __stdcall GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE* pMode); - HRESULT __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS* pParameters); - HRESULT __stdcall SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap); - void __stdcall SetCursorPosition(int X, int Y, DWORD Flags); - BOOL __stdcall ShowCursor(BOOL bShow); - HRESULT __stdcall CreateAdditionalSwapChain( - D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain); - HRESULT __stdcall GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain); - UINT __stdcall GetNumberOfSwapChains(); - HRESULT __stdcall Reset(D3DPRESENT_PARAMETERS* pPresentationParameters); - HRESULT __stdcall Present( - CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); - HRESULT __stdcall GetBackBuffer( - UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer); - HRESULT __stdcall GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus); - HRESULT __stdcall SetDialogBoxMode(BOOL bEnableDialogs); - void __stdcall SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp); - void __stdcall GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp); - HRESULT __stdcall CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, - IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle); - HRESULT __stdcall CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, - D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle); - HRESULT __stdcall CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, - IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle); - HRESULT __stdcall CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, - IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle); - HRESULT __stdcall CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, - IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle); - HRESULT __stdcall CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, - DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle); - HRESULT __stdcall CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, - D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, - HANDLE* pSharedHandle); - HRESULT __stdcall UpdateSurface(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, - IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint); - HRESULT __stdcall UpdateTexture(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture); - HRESULT __stdcall GetRenderTargetData(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface); - HRESULT __stdcall GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9* pDestSurface); - HRESULT __stdcall StretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, - IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter); - HRESULT __stdcall ColorFill(IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color); - HRESULT __stdcall CreateOffscreenPlainSurface( - UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle); - HRESULT __stdcall SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget); - HRESULT __stdcall GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget); - HRESULT __stdcall SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil); - HRESULT __stdcall GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface); - HRESULT __stdcall BeginScene(); - HRESULT __stdcall EndScene(); - HRESULT __stdcall Clear(DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil); - HRESULT __stdcall SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix); - HRESULT __stdcall GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix); - HRESULT __stdcall MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); - HRESULT __stdcall SetViewport(CONST D3DVIEWPORT9* pViewport); - HRESULT __stdcall GetViewport(D3DVIEWPORT9* pViewport); - HRESULT __stdcall SetMaterial(CONST D3DMATERIAL9* pMaterial); - HRESULT __stdcall GetMaterial(D3DMATERIAL9* pMaterial); - HRESULT __stdcall SetLight(DWORD Index, CONST D3DLIGHT9*); - HRESULT __stdcall GetLight(DWORD Index, D3DLIGHT9*); - HRESULT __stdcall LightEnable(DWORD Index, BOOL Enable); - HRESULT __stdcall GetLightEnable(DWORD Index, BOOL* pEnable); - HRESULT __stdcall SetClipPlane(DWORD Index, CONST float* pPlane); - HRESULT __stdcall GetClipPlane(DWORD Index, float* pPlane); - HRESULT __stdcall SetRenderState(D3DRENDERSTATETYPE State, DWORD Value); - HRESULT __stdcall GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue); - HRESULT __stdcall CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB); - HRESULT __stdcall BeginStateBlock(); - HRESULT __stdcall EndStateBlock(IDirect3DStateBlock9** ppSB); - HRESULT __stdcall SetClipStatus(CONST D3DCLIPSTATUS9* pClipStatus); - HRESULT __stdcall GetClipStatus(D3DCLIPSTATUS9* pClipStatus); - HRESULT __stdcall GetTexture(DWORD Stage, IDirect3DBaseTexture9** ppTexture); - HRESULT __stdcall SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture); - HRESULT __stdcall GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue); - HRESULT __stdcall SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value); - HRESULT __stdcall GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue); - HRESULT __stdcall SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); - HRESULT __stdcall ValidateDevice(DWORD* pNumPasses); - HRESULT __stdcall SetPaletteEntries(UINT PaletteNumber, CONST PALETTEENTRY* pEntries); - HRESULT __stdcall GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY* pEntries); - HRESULT __stdcall SetCurrentTexturePalette(UINT PaletteNumber); - HRESULT __stdcall GetCurrentTexturePalette(UINT* PaletteNumber); - HRESULT __stdcall SetScissorRect(CONST RECT* pRect); - HRESULT __stdcall GetScissorRect(RECT* pRect); - HRESULT __stdcall SetSoftwareVertexProcessing(BOOL bSoftware); - BOOL __stdcall GetSoftwareVertexProcessing(); - HRESULT __stdcall SetNPatchMode(float nSegments); - float __stdcall GetNPatchMode(); - HRESULT __stdcall DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); - HRESULT __stdcall DrawIndexedPrimitive( - D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); - HRESULT __stdcall DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, - CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride); - HRESULT __stdcall DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, - UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, - UINT VertexStreamZeroStride); - HRESULT __stdcall ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, - IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags); - HRESULT __stdcall CreateVertexDeclaration( - CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl); - HRESULT __stdcall SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl); - HRESULT __stdcall GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl); - HRESULT __stdcall SetFVF(DWORD FVF); - HRESULT __stdcall GetFVF(DWORD* pFVF); - HRESULT __stdcall CreateVertexShader(CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader); - HRESULT __stdcall SetVertexShader(IDirect3DVertexShader9* pShader); - HRESULT __stdcall GetVertexShader(IDirect3DVertexShader9** ppShader); - HRESULT __stdcall SetVertexShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount); - HRESULT __stdcall GetVertexShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount); - HRESULT __stdcall SetVertexShaderConstantI(UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount); - HRESULT __stdcall GetVertexShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount); - HRESULT __stdcall SetVertexShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount); - HRESULT __stdcall GetVertexShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount); - HRESULT __stdcall SetStreamSource( - UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride); - HRESULT __stdcall GetStreamSource( - UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride); - HRESULT __stdcall SetStreamSourceFreq(UINT StreamNumber, UINT Setting); - HRESULT __stdcall GetStreamSourceFreq(UINT StreamNumber, UINT* pSetting); - HRESULT __stdcall SetIndices(IDirect3DIndexBuffer9* pIndexData); - HRESULT __stdcall GetIndices(IDirect3DIndexBuffer9** ppIndexData); - HRESULT __stdcall CreatePixelShader(CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader); - HRESULT __stdcall SetPixelShader(IDirect3DPixelShader9* pShader); - HRESULT __stdcall GetPixelShader(IDirect3DPixelShader9** ppShader); - HRESULT __stdcall SetPixelShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount); - HRESULT __stdcall GetPixelShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount); - HRESULT __stdcall SetPixelShaderConstantI(UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount); - HRESULT __stdcall GetPixelShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount); - HRESULT __stdcall SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount); - HRESULT __stdcall GetPixelShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount); - HRESULT __stdcall DrawRectPatch(UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo); - HRESULT __stdcall DrawTriPatch(UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo); - HRESULT __stdcall DeletePatch(UINT Handle); - HRESULT __stdcall CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery); - - //#ifdef D3D_DEBUG_INFO - D3DDEVICE_CREATION_PARAMETERS CreationParameters; - D3DPRESENT_PARAMETERS PresentParameters; - D3DDISPLAYMODE DisplayMode; - D3DCAPS9 Caps; - - UINT AvailableTextureMem; - UINT SwapChains; - UINT Textures; - UINT VertexBuffers; - UINT IndexBuffers; - UINT VertexShaders; - UINT PixelShaders; - - D3DVIEWPORT9 Viewport; - D3DMATRIX ProjectionMatrix; - D3DMATRIX ViewMatrix; - D3DMATRIX WorldMatrix; - D3DMATRIX TextureMatrices[8]; - - DWORD FVF; - UINT VertexSize; - DWORD VertexShaderVersion; - DWORD PixelShaderVersion; - BOOL SoftwareVertexProcessing; - - D3DMATERIAL9 Material; - D3DLIGHT9 Lights[16]; - BOOL LightsEnabled[16]; - - D3DGAMMARAMP GammaRamp; - RECT ScissorRect; - BOOL DialogBoxMode; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DDevice9_Caps.cpp b/src/xrD3D9-Null/IDirect3DDevice9_Caps.cpp deleted file mode 100644 index 8f7c5b3cf44..00000000000 --- a/src/xrD3D9-Null/IDirect3DDevice9_Caps.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "stdafx.h" -#include "IDirect3DDevice9.h" - -#include "xrD3D9-Null_OutProc.h" - -HRESULT xrIDirect3DDevice9::GetDeviceCaps(D3DCAPS9* pCaps) -{ - APIDEBUG("xrIDirect3DDevice9::GetDeviceCaps"); - - if (!pCaps) - return D3DERR_INVALIDCALL; - - memset(pCaps, 0, sizeof(D3DCAPS9)); - - /* Device Info */ - pCaps->DeviceType = D3DDEVTYPE_HAL; - pCaps->AdapterOrdinal = 0; - - /* Caps from DX7 Draw */ - pCaps->Caps = 0; // D3DCAPS_READ_SCANLINE; - pCaps->Caps2 = D3DCAPS2_CANAUTOGENMIPMAP | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_CANMANAGERESOURCE | - D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA; // D3DCAPS2_CANRENDERWINDOWED ; - pCaps->Caps3 = D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_COPY_TO_VIDMEM | D3DCAPS3_COPY_TO_SYSTEMMEM | - D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION; - - pCaps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE; // see wglSwapIntervalEXT - - /* Cursor Caps */ - pCaps->CursorCaps = D3DCURSORCAPS_COLOR; - - pCaps->DevCaps = D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | - D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_TEXTUREVIDEOMEMORY | - D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | - D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | D3DDEVCAPS_DRAWPRIMITIVES2EX | - D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_CANBLTSYSTONONLOCAL | D3DDEVCAPS_HWRASTERIZATION | - D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES | D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | - D3DDEVCAPS_NPATCHES; - - pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW | - D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS | D3DPMISCCAPS_CLIPTLVERTS | - D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP | D3DPMISCCAPS_NULLREFERENCE | - D3DPMISCCAPS_INDEPENDENTWRITEMASKS | D3DPMISCCAPS_PERSTAGECONSTANT | D3DPMISCCAPS_FOGANDSPECULARALPHA | - D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS | - D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED; - - pCaps->RasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX | - D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | - D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_WFOG | - D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | D3DPRASTERCAPS_SCISSORTEST | - D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE; - - pCaps->ZCmpCaps = D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | - D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS; - - pCaps->SrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | - D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | - D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | - D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR; - - pCaps->DestBlendCaps = pCaps->SrcBlendCaps; - - pCaps->AlphaCmpCaps = pCaps->ZCmpCaps; - - pCaps->ShadeCaps = D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | - D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD; - - pCaps->TextureCaps = D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | - D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE | - D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | - D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | - D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2 | D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; - - pCaps->TextureFilterCaps = D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | - D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | - D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | - D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD | - D3DPTFILTERCAPS_MAGFGAUSSIANQUAD; - - pCaps->CubeTextureFilterCaps = pCaps->TextureFilterCaps; - - pCaps->VolumeTextureFilterCaps = pCaps->TextureFilterCaps; - - pCaps->TextureAddressCaps = D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | - D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV | D3DPTADDRESSCAPS_MIRRORONCE; - - pCaps->VolumeTextureAddressCaps = pCaps->TextureAddressCaps; - - pCaps->LineCaps = D3DLINECAPS_TEXTURE | D3DLINECAPS_ZTEST | D3DLINECAPS_BLEND | D3DLINECAPS_ALPHACMP | - D3DLINECAPS_FOG | D3DLINECAPS_ANTIALIAS; - - pCaps->MaxTextureWidth = 1 << 12; - pCaps->MaxTextureHeight = 1 << 12; - pCaps->MaxVolumeExtent = 1 << 12; - pCaps->MaxTextureRepeat = 1 << 16; - pCaps->MaxTextureAspectRatio = 1 << 12; - pCaps->MaxAnisotropy = 16; - pCaps->MaxVertexW = 1E+010; - - pCaps->GuardBandLeft = -1E+008; - pCaps->GuardBandTop = -1E+008; - pCaps->GuardBandRight = 1E+008; - pCaps->GuardBandBottom = 1E+008; - - pCaps->ExtentsAdjust = 0; - - pCaps->StencilCaps = D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCRSAT | - D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR | - D3DSTENCILCAPS_TWOSIDED; - - pCaps->FVFCaps = D3DFVFCAPS_TEXCOORDCOUNTMASK | D3DFVFCAPS_DONOTSTRIPELEMENTS | D3DFVFCAPS_PSIZE; - - pCaps->TextureOpCaps = D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | - D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE4X | D3DTEXOPCAPS_ADD | - D3DTEXOPCAPS_ADDSIGNED | D3DTEXOPCAPS_ADDSIGNED2X | D3DTEXOPCAPS_SUBTRACT | D3DTEXOPCAPS_ADDSMOOTH | - D3DTEXOPCAPS_BLENDDIFFUSEALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHA | D3DTEXOPCAPS_BLENDFACTORALPHA | - D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | D3DTEXOPCAPS_BLENDCURRENTALPHA | D3DTEXOPCAPS_PREMODULATE | - D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | - D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | D3DTEXOPCAPS_BUMPENVMAP | - D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | D3DTEXOPCAPS_DOTPRODUCT3 | D3DTEXOPCAPS_MULTIPLYADD | D3DTEXOPCAPS_LERP; - - pCaps->MaxTextureBlendStages = 16; - pCaps->MaxSimultaneousTextures = 16; - - pCaps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | - D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_TEXGEN_SPHEREMAP | - D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER; - - pCaps->MaxActiveLights = 32; - pCaps->MaxUserClipPlanes = 32; - pCaps->MaxVertexBlendMatrices = 256; - pCaps->MaxVertexBlendMatrixIndex = pCaps->MaxVertexBlendMatrices + 1; - pCaps->MaxPointSize = 3.0f; - pCaps->MaxPrimitiveCount = 0xffff - 1; - pCaps->MaxVertexIndex = 0xffffffff; - pCaps->MaxStreams = 16; - pCaps->MaxStreamStride = 16; - - pCaps->VertexShaderVersion = 0x03; - pCaps->MaxVertexShaderConst = 32; - pCaps->PixelShaderVersion = 0x03; - pCaps->PixelShader1xMaxValue = 8.0f; - - pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET | D3DDEVCAPS2_DMAPNPATCH | D3DDEVCAPS2_ADAPTIVETESSRTPATCH | - D3DDEVCAPS2_ADAPTIVETESSNPATCH | D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES | D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH | - D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; - - pCaps->MaxNpatchTessellationLevel = 32; - pCaps->MasterAdapterOrdinal = 0; - pCaps->AdapterOrdinalInGroup = 0; - pCaps->NumberOfAdaptersInGroup = 1; - - pCaps->DeclTypes = D3DDTCAPS_UBYTE4 | D3DDTCAPS_UBYTE4N | D3DDTCAPS_SHORT2N | D3DDTCAPS_SHORT4N | - D3DDTCAPS_USHORT2N | D3DDTCAPS_USHORT4N | D3DDTCAPS_UDEC3 | D3DDTCAPS_DEC3N | D3DDTCAPS_FLOAT16_2 | - D3DDTCAPS_FLOAT16_4; - - pCaps->NumSimultaneousRTs = 1; - pCaps->StretchRectFilterCaps = pCaps->VertexTextureFilterCaps; - - pCaps->VS20Caps.Caps = D3DVS20CAPS_PREDICATION; - - pCaps->VS20Caps.DynamicFlowControlDepth = 24; - pCaps->VS20Caps.NumTemps = 32; - pCaps->VS20Caps.StaticFlowControlDepth = 4; - - pCaps->PS20Caps.Caps = D3DPS20CAPS_ARBITRARYSWIZZLE | D3DPS20CAPS_GRADIENTINSTRUCTIONS | D3DPS20CAPS_PREDICATION | - D3DPS20CAPS_NODEPENDENTREADLIMIT | D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT; - pCaps->PS20Caps.DynamicFlowControlDepth = 24; - pCaps->PS20Caps.NumInstructionSlots = 512; - pCaps->PS20Caps.NumTemps = 32; - pCaps->PS20Caps.StaticFlowControlDepth = 4; - - pCaps->MaxVShaderInstructionsExecuted = 32768; - pCaps->MaxPShaderInstructionsExecuted = 32768; - pCaps->MaxVertexShader30InstructionSlots = 32768; - pCaps->MaxPixelShader30InstructionSlots = 32768; - - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DIndexBuffer9.cpp b/src/xrD3D9-Null/IDirect3DIndexBuffer9.cpp deleted file mode 100644 index 01168b5fab3..00000000000 --- a/src/xrD3D9-Null/IDirect3DIndexBuffer9.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DIndexBuffer9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DIndexBuffer9; - -xrIDirect3DIndexBuffer9::xrIDirect3DIndexBuffer9( - IDirect3DDevice9* pIDirect3DDevice9, UINT iLength, DWORD iUsage, D3DFORMAT iFormat, D3DPOOL iPool) - : m_refCount(0), m_pIDirect3DDevice9(pIDirect3DDevice9) -//#ifdef D3D_DEBUG_INFO - , Name(nullptr), Length(iLength), Usage(iUsage), Format(iFormat), Pool(iPool), - Priority(0), LockCount(0), CreationCallStack(nullptr) -//#endif -{ - APIDEBUG("xrIDirect3DIndexBuffer9::xrIDirect3DIndexBuffer9"); - - switch (Format) - { - case D3DFMT_INDEX16: m_pBuffer = new BYTE[Length * 2]; break; - case D3DFMT_INDEX32: m_pBuffer = new BYTE[Length * 4]; break; - } -}; -/*** IUnknown methods ***/ -HRESULT xrIDirect3DIndexBuffer9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DIndexBuffer9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DIndexBuffer9::AddRef() -{ - APIDEBUG("xrIDirect3DIndexBuffer9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DIndexBuffer9::Release() -{ - APIDEBUG("xrIDirect3DIndexBuffer9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete[] m_pBuffer; - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DIndexBuffer9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::SetPrivateData( - REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::SetPrivateData"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::GetPrivateData"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::FreePrivateData(REFGUID refguid) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::FreePrivateData"); - return S_OK; -}; -DWORD __stdcall xrIDirect3DIndexBuffer9::SetPriority(DWORD PriorityNew) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::SetPriority"); - DWORD old = Priority; - Priority = PriorityNew; - return old; -}; -DWORD __stdcall xrIDirect3DIndexBuffer9::GetPriority() -{ - APIDEBUG("xrIDirect3DIndexBuffer9::GetPriority"); - return Priority; -}; -void __stdcall xrIDirect3DIndexBuffer9::PreLoad() { APIDEBUG("xrIDirect3DIndexBuffer9::PreLoad"); }; -D3DRESOURCETYPE __stdcall xrIDirect3DIndexBuffer9::GetType() -{ - APIDEBUG("xrIDirect3DIndexBuffer9::GetType"); - return D3DRESOURCETYPE(0); -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::Lock"); - *ppbData = m_pBuffer + OffsetToLock; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::Unlock() -{ - APIDEBUG("xrIDirect3DIndexBuffer9::Unlock"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DIndexBuffer9::GetDesc(D3DINDEXBUFFER_DESC* pDesc) -{ - APIDEBUG("xrIDirect3DIndexBuffer9::GetDesc"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DIndexBuffer9.h b/src/xrD3D9-Null/IDirect3DIndexBuffer9.h deleted file mode 100644 index acf38f8dca6..00000000000 --- a/src/xrD3D9-Null/IDirect3DIndexBuffer9.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DIndexBuffer9 : public IDirect3DIndexBuffer9 -{ -protected: - LONG m_refCount; - BYTE* m_pBuffer; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DIndexBuffer9( - IDirect3DDevice9* pIDirect3DDevice9, UINT iLength, DWORD iUsage, D3DFORMAT iFormat, D3DPOOL iPool); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DResource9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); - HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData); - HRESULT __stdcall FreePrivateData(REFGUID refguid); - DWORD __stdcall SetPriority(DWORD PriorityNew); - DWORD __stdcall GetPriority(); - void __stdcall PreLoad(); - D3DRESOURCETYPE __stdcall GetType(); - HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags); - HRESULT __stdcall Unlock(); - HRESULT __stdcall GetDesc(D3DINDEXBUFFER_DESC* pDesc); - - //#ifdef D3D_DEBUG_INFO - LPCWSTR Name; - UINT Length; - DWORD Usage; - D3DFORMAT Format; - D3DPOOL Pool; - DWORD Priority; - UINT LockCount; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DPixelShader9.cpp b/src/xrD3D9-Null/IDirect3DPixelShader9.cpp deleted file mode 100644 index 30aef8862d5..00000000000 --- a/src/xrD3D9-Null/IDirect3DPixelShader9.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DPixelShader9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DPixelShader9; - -xrIDirect3DPixelShader9::xrIDirect3DPixelShader9(IDirect3DDevice9* pIDirect3DDevice9) : m_refCount(0) -{ - APIDEBUG("xrIDirect3DPixelShader9::xrIDirect3DPixelShader9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; -}; -HRESULT xrIDirect3DPixelShader9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DPixelShader9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DPixelShader9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DPixelShader9::AddRef() -{ - APIDEBUG("xrIDirect3DPixelShader9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DPixelShader9::Release() -{ - APIDEBUG("xrIDirect3DPixelShader9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DPixelShader9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DPixelShader9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DPixelShader9::GetFunction(void* pData, UINT* pSizeOfData) -{ - APIDEBUG("xrIDirect3DPixelShader9::GetFunction"); - *pSizeOfData = 0; - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DPixelShader9.h b/src/xrD3D9-Null/IDirect3DPixelShader9.h deleted file mode 100644 index e412f022f7e..00000000000 --- a/src/xrD3D9-Null/IDirect3DPixelShader9.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DPixelShader9 : public IDirect3DPixelShader9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DPixelShader9(IDirect3DDevice9* pIDirect3DDevice9); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DVertexDeclaration9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall GetFunction(void*, UINT* pSizeOfData); -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DQuery9.cpp b/src/xrD3D9-Null/IDirect3DQuery9.cpp deleted file mode 100644 index b893c7c61d3..00000000000 --- a/src/xrD3D9-Null/IDirect3DQuery9.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "stdafx.h" -#include "IDirect3DQuery9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DQuery9; - -xrIDirect3DQuery9::xrIDirect3DQuery9(IDirect3DDevice9* pIDirect3DDevice9, D3DQUERYTYPE rType) : m_refCount(0) -{ - APIDEBUG("xrIDirect3DQuery9::xrIDirect3DQuery9"); - DataSize = 0; - memcpy(&Type, &rType, sizeof(rType)); - CreationCallStack = NULL; - m_pIDirect3DDevice9 = pIDirect3DDevice9; -}; - -/*** IUnknown methods ***/ -HRESULT xrIDirect3DQuery9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DQuery9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DQuery9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DQuery9::AddRef() -{ - APIDEBUG("xrIDirect3DQuery9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DQuery9::Release() -{ - APIDEBUG("xrIDirect3DQuery9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - - return m_refCount; -} - -/*** IDirect3DQuery9 methods ***/ -HRESULT xrIDirect3DQuery9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DQuery9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -D3DQUERYTYPE xrIDirect3DQuery9::GetType() -{ - APIDEBUG("xrIDirect3DQuery9::GetType"); - return Type; -}; -DWORD xrIDirect3DQuery9::GetDataSize() -{ - APIDEBUG("xrIDirect3DQuery9::GetDataSize"); - return DataSize; -}; -HRESULT xrIDirect3DQuery9::Issue(DWORD dwIssueFlags) -{ - APIDEBUG("xrIDirect3DQuery9::Issue"); - return S_OK; -}; -HRESULT xrIDirect3DQuery9::GetData(void* pData, DWORD dwSize, DWORD dwGetDataFlags) -{ - APIDEBUG("xrIDirect3DQuery9::GetData"); - return S_OK; -}; -//----------------------------------------------------------------------- -/* -HRESULT xrIDirect3DQuery9::HRESULT_Proc(HRESULT ret) -{ - return ret; -} - -ULONG xrIDirect3DQuery9::ULONG_Proc(ULONG ret) -{ - return ret; -} - -DWORD xrIDirect3DQuery9::DWORD_Proc(DWORD ret) -{ - return ret; -} -*/ diff --git a/src/xrD3D9-Null/IDirect3DQuery9.h b/src/xrD3D9-Null/IDirect3DQuery9.h deleted file mode 100644 index 54a76efb919..00000000000 --- a/src/xrD3D9-Null/IDirect3DQuery9.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DQuery9 : public IDirect3DQuery9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DQuery9(IDirect3DDevice9* pIDirect3DDevice9, D3DQUERYTYPE rType); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DQuery9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - D3DQUERYTYPE __stdcall GetType(); - DWORD __stdcall GetDataSize(); - HRESULT __stdcall Issue(DWORD dwIssueFlags); - HRESULT __stdcall GetData(void* pData, DWORD dwSize, DWORD dwGetDataFlags); - - //#ifdef D3D_DEBUG_INFO - D3DQUERYTYPE Type; - DWORD DataSize; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DStateBlock9.cpp b/src/xrD3D9-Null/IDirect3DStateBlock9.cpp deleted file mode 100644 index a71cb3bedbf..00000000000 --- a/src/xrD3D9-Null/IDirect3DStateBlock9.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DStateBlock9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DStateBlock9; - -xrIDirect3DStateBlock9::xrIDirect3DStateBlock9(IDirect3DDevice9* pIDirect3DDevice9) : m_refCount(0) -{ - APIDEBUG("xrIDirect3DStateBlock9::xrIDirect3DStateBlock9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; -}; -HRESULT xrIDirect3DStateBlock9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DStateBlock9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DStateBlock9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DStateBlock9::AddRef() -{ - APIDEBUG("xrIDirect3DStateBlock9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DStateBlock9::Release() -{ - APIDEBUG("xrIDirect3DStateBlock9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DStateBlock9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DStateBlock9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; - -HRESULT __stdcall xrIDirect3DStateBlock9::Capture() -{ - APIDEBUG("xrIDirect3DStateBlock9::Capture"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DStateBlock9::Apply() -{ - APIDEBUG("xrIDirect3DStateBlock9::Apply"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DStateBlock9.h b/src/xrD3D9-Null/IDirect3DStateBlock9.h deleted file mode 100644 index 938494bc448..00000000000 --- a/src/xrD3D9-Null/IDirect3DStateBlock9.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DStateBlock9 : public IDirect3DStateBlock9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DStateBlock9(IDirect3DDevice9* pIDirect3DDevice9); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DVertexDeclaration9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall Capture(); - HRESULT __stdcall Apply(); -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DSurface9.cpp b/src/xrD3D9-Null/IDirect3DSurface9.cpp deleted file mode 100644 index 7b54891108a..00000000000 --- a/src/xrD3D9-Null/IDirect3DSurface9.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DSurface9.h" - -#include "xrD3D9-Null_OutProc.h" - -#ifdef _DEBUG -#include "crtdbg.h" -#endif - -const GUID DECLSPEC_SELECTANY IID_IDirect3DSurface9; - -xrIDirect3DSurface9::xrIDirect3DSurface9(IDirect3DDevice9* pIDirect3DDevice9, UINT iWidth, UINT iHeight, - D3DFORMAT iFormat, D3DMULTISAMPLE_TYPE iMultiSample, DWORD iMultisampleQuality) - : Width(iWidth), Height(iHeight), Format(iFormat), MultiSampleType(iMultiSample), - MultiSampleQuality(iMultisampleQuality), m_refCount(0) -{ - APIDEBUG("xrIDirect3DSurface9::xrIDirect3DSurface9"); - - m_pIDirect3DDevice9 = pIDirect3DDevice9; - //----------------------------------------------- - Name = NULL; - Usage = 0; - Pool = D3DPOOL(0); - MultiSampleQuality = 0; - Priority = 0; - LockCount = 0; - DCCount = 0; - CreationCallStack = NULL; - //----------------------------------------------- - m_pLockedData = NULL; -}; - -/*** IUnknown methods ***/ -HRESULT xrIDirect3DSurface9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DSurface9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DSurface9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DSurface9::AddRef() -{ - APIDEBUG("xrIDirect3DSurface9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DSurface9::Release() -{ - APIDEBUG("xrIDirect3DSurface9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT xrIDirect3DSurface9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DSurface9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; - -HRESULT xrIDirect3DSurface9::SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DSurface9::SetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DSurface9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) -{ - APIDEBUG("xrIDirect3DSurface9::GetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DSurface9::FreePrivateData(REFGUID refguid) -{ - APIDEBUG("xrIDirect3DSurface9::FreePrivateData"); - return S_OK; -}; -DWORD xrIDirect3DSurface9::SetPriority(DWORD PriorityNew) -{ - APIDEBUG("xrIDirect3DSurface9::SetPriority"); - DWORD old = Priority; - Priority = PriorityNew; - return old; -}; -DWORD xrIDirect3DSurface9::GetPriority() -{ - APIDEBUG("xrIDirect3DSurface9::GetPriority"); - return Priority; -}; -void xrIDirect3DSurface9::PreLoad() { APIDEBUG("xrIDirect3DSurface9::PreLoad"); }; -D3DRESOURCETYPE xrIDirect3DSurface9::GetType() -{ - APIDEBUG("xrIDirect3DSurface9::GetType"); - return D3DRESOURCETYPE(0); -}; -HRESULT xrIDirect3DSurface9::GetContainer(REFIID riid, void** ppContainer) -{ - APIDEBUG("xrIDirect3DSurface9::GetContainer"); - return S_OK; -}; -HRESULT xrIDirect3DSurface9::GetDesc(D3DSURFACE_DESC* pDesc) -{ - APIDEBUG("xrIDirect3DSurface9::GetDesc"); - - pDesc->Format = Format; - pDesc->Type = D3DRTYPE_SURFACE; - pDesc->Usage = Usage; - pDesc->Pool = Pool; - - pDesc->MultiSampleType = MultiSampleType; - pDesc->MultiSampleQuality = MultiSampleQuality; - pDesc->Width = Width; - pDesc->Height = Height; - return S_OK; -}; -HRESULT xrIDirect3DSurface9::LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) -{ - APIDEBUG("xrIDirect3DSurface9::LockRect"); -#ifdef _DEBUG - if (m_pLockedData != NULL) - { - _ASSERT(0); - } -#endif - UINT RWidth = (NULL == pRect) ? Width : (pRect->right - pRect->left); - UINT RHeight = (NULL == pRect) ? Height : (pRect->bottom - pRect->top); - m_pLockedData = new BYTE[RWidth * RHeight * 4]; - pLockedRect->Pitch = 4; - pLockedRect->pBits = m_pLockedData; - - return S_OK; -}; -HRESULT xrIDirect3DSurface9::UnlockRect() -{ - APIDEBUG("xrIDirect3DSurface9::UnlockRect"); - -#ifdef _DEBUG - if (m_pLockedData == NULL) - { - _ASSERT(0); - } -#endif - delete[] m_pLockedData; - m_pLockedData = NULL; - - return S_OK; -}; -HRESULT xrIDirect3DSurface9::GetDC(HDC* phdc) -{ - APIDEBUG("xrIDirect3DSurface9::GetDC"); - return S_OK; -}; -HRESULT xrIDirect3DSurface9::ReleaseDC(HDC hdc) -{ - APIDEBUG("xrIDirect3DSurface9::ReleaseDC"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DSurface9.h b/src/xrD3D9-Null/IDirect3DSurface9.h deleted file mode 100644 index 170685cced4..00000000000 --- a/src/xrD3D9-Null/IDirect3DSurface9.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DSurface9 : public IDirect3DSurface9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - BYTE* m_pLockedData; - -public: - xrIDirect3DSurface9(IDirect3DDevice9* pIDirect3DDevice9, UINT Width, UINT Height, D3DFORMAT Format, - D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DResource9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); - HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData); - HRESULT __stdcall FreePrivateData(REFGUID refguid); - DWORD __stdcall SetPriority(DWORD PriorityNew); - DWORD __stdcall GetPriority(); - void __stdcall PreLoad(); - D3DRESOURCETYPE __stdcall GetType(); - HRESULT __stdcall GetContainer(REFIID riid, void** ppContainer); - HRESULT __stdcall GetDesc(D3DSURFACE_DESC* pDesc); - HRESULT __stdcall LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags); - HRESULT __stdcall UnlockRect(); - HRESULT __stdcall GetDC(HDC* phdc); - HRESULT __stdcall ReleaseDC(HDC hdc); - - //#ifdef D3D_DEBUG_INFO - LPCWSTR Name; - UINT Width; - UINT Height; - DWORD Usage; - D3DFORMAT Format; - D3DPOOL Pool; - D3DMULTISAMPLE_TYPE MultiSampleType; - DWORD MultiSampleQuality; - DWORD Priority; - UINT LockCount; - UINT DCCount; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DTexture9.cpp b/src/xrD3D9-Null/IDirect3DTexture9.cpp deleted file mode 100644 index 3b07bd04e90..00000000000 --- a/src/xrD3D9-Null/IDirect3DTexture9.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DTexture9.h" -#include "IDirect3DSurface9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DTexture9; - -xrIDirect3DTexture9::xrIDirect3DTexture9(IDirect3DDevice9* pIDirect3DDevice9, UINT iWidth, UINT iHeight, UINT iLevels, - DWORD iUsage, D3DFORMAT iFormat, D3DPOOL iPool) - : m_refCount(0), Name(nullptr), Width(iWidth), Height(iHeight), Levels(iLevels), Usage(iUsage), Format(iFormat) - //#ifdef D3D_DEBUG_INFO - , - Pool(iPool), Priority(0) -//#endif -{ - APIDEBUG("xrIDirect3DTexture9::xrIDirect3DTexture9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; - //------------------------------------------------------------- - LOD = 0; - FilterType = D3DTEXTUREFILTERTYPE(0); - LockCount = 0; - CreationCallStack = nullptr; -} - -/*** IUnknown methods ***/ -HRESULT xrIDirect3DTexture9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DTexture9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DTexture9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DTexture9::AddRef() -{ - APIDEBUG("xrIDirect3DTexture9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DTexture9::Release() -{ - APIDEBUG("xrIDirect3DTexture9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DBaseTexture9 methods ***/ -HRESULT xrIDirect3DTexture9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DTexture9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -} -HRESULT xrIDirect3DTexture9::SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DTexture9::SetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) -{ - APIDEBUG("xrIDirect3DTexture9::GetPrivateData"); - return S_OK; -}; -HRESULT xrIDirect3DTexture9::FreePrivateData(REFGUID refguid) -{ - APIDEBUG("xrIDirect3DTexture9::FreePrivateData"); - return S_OK; -}; -DWORD xrIDirect3DTexture9::SetPriority(DWORD PriorityNew) -{ - APIDEBUG("xrIDirect3DTexture9::SetPriority"); - DWORD old = Priority; - Priority = PriorityNew; - return old; -}; -DWORD xrIDirect3DTexture9::GetPriority() -{ - APIDEBUG("xrIDirect3DTexture9::GetPriority"); - return Priority; -}; -void xrIDirect3DTexture9::PreLoad() { APIDEBUG("xrIDirect3DTexture9::PreLoad"); }; -D3DRESOURCETYPE xrIDirect3DTexture9::GetType() -{ - APIDEBUG("xrIDirect3DTexture9::GetType"); - return D3DRTYPE_TEXTURE; -}; -DWORD xrIDirect3DTexture9::SetLOD(DWORD LODNew) -{ - APIDEBUG("xrIDirect3DTexture9::SetLOD"); - DWORD old = LOD; - LOD = LODNew; - return old; -}; -DWORD xrIDirect3DTexture9::GetLOD() -{ - APIDEBUG("xrIDirect3DTexture9::GetLOD"); - return LOD; -}; -DWORD xrIDirect3DTexture9::GetLevelCount() -{ - APIDEBUG("xrIDirect3DTexture9::GetLevelCount"); - return Levels; -}; -HRESULT xrIDirect3DTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE iFilterType) -{ - APIDEBUG("xrIDirect3DTexture9::SetAutoGenFilterType"); - FilterType = iFilterType; - return S_OK; -}; -D3DTEXTUREFILTERTYPE xrIDirect3DTexture9::GetAutoGenFilterType() -{ - APIDEBUG("xrIDirect3DTexture9::GetAutoGenFilterType"); - return D3DTEXTUREFILTERTYPE(FilterType); -}; -void xrIDirect3DTexture9::GenerateMipSubLevels() { APIDEBUG("xrIDirect3DTexture9::GenerateMipSubLevels"); }; -HRESULT xrIDirect3DTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) -{ - APIDEBUG("xrIDirect3DTexture9::GetLevelDesc"); - - pDesc->Format = Format; - pDesc->Type = D3DRTYPE_TEXTURE; - pDesc->Usage = Usage; - pDesc->Pool = Pool; - - pDesc->MultiSampleType = D3DMULTISAMPLE_TYPE(0); - pDesc->MultiSampleQuality = 0; - pDesc->Width = Width; - pDesc->Height = Height; - - return S_OK; -}; - -HRESULT xrIDirect3DTexture9::GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) -{ - APIDEBUG("xrIDirect3DTexture9::GetSurfaceLevel"); - - *ppSurfaceLevel = NULL; - xrIDirect3DSurface9* I = - new xrIDirect3DSurface9(m_pIDirect3DDevice9, Width, Height, Format, D3DMULTISAMPLE_TYPE(0), 0); - *ppSurfaceLevel = I; - - return S_OK; -}; -HRESULT xrIDirect3DTexture9::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) -{ - APIDEBUG("xrIDirect3DTexture9::LockRect"); - return S_OK; -}; -HRESULT xrIDirect3DTexture9::UnlockRect(UINT Level) -{ - APIDEBUG("xrIDirect3DTexture9::UnlockRect"); - return S_OK; -}; -HRESULT xrIDirect3DTexture9::AddDirtyRect(CONST RECT* pDirtyRect) -{ - APIDEBUG("xrIDirect3DTexture9::AddDirtyRect"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DTexture9.h b/src/xrD3D9-Null/IDirect3DTexture9.h deleted file mode 100644 index ef14995491b..00000000000 --- a/src/xrD3D9-Null/IDirect3DTexture9.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DTexture9 : public IDirect3DTexture9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DTexture9(IDirect3DDevice9* pIDirect3DDevice9, UINT iWidth, UINT iHeight, UINT iLevels, DWORD iUsage, - D3DFORMAT iFormat, D3DPOOL iPool); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DBaseTexture9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); - HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData); - HRESULT __stdcall FreePrivateData(REFGUID refguid); - DWORD __stdcall SetPriority(DWORD PriorityNew); - DWORD __stdcall GetPriority(); - void __stdcall PreLoad(); - D3DRESOURCETYPE __stdcall GetType(); - DWORD __stdcall SetLOD(DWORD LODNew); - DWORD __stdcall GetLOD(); - DWORD __stdcall GetLevelCount(); - HRESULT __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType); - D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType(); - void __stdcall GenerateMipSubLevels(); - HRESULT __stdcall GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc); - HRESULT __stdcall GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel); - HRESULT __stdcall LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags); - HRESULT __stdcall UnlockRect(UINT Level); - HRESULT __stdcall AddDirtyRect(CONST RECT* pDirtyRect); - - //#ifdef D3D_DEBUG_INFO - LPCWSTR Name; - UINT Width; - UINT Height; - UINT Levels; - DWORD Usage; - D3DFORMAT Format; - D3DPOOL Pool; - DWORD Priority; - DWORD LOD; - D3DTEXTUREFILTERTYPE FilterType; - UINT LockCount; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DVertexBuffer9.cpp b/src/xrD3D9-Null/IDirect3DVertexBuffer9.cpp deleted file mode 100644 index 1f48c06b961..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexBuffer9.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DVertexBuffer9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DVertexBuffer9; - -xrIDirect3DVertexBuffer9::xrIDirect3DVertexBuffer9( - IDirect3DDevice9* pIDirect3DDevice9, UINT iLength, DWORD iUsage, DWORD iFVF, D3DPOOL iPool) - : m_refCount(0) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::xrIDirect3DVertexBuffer9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; - //----------------------------------------------- - Name = NULL; - Length = iLength; - Usage = iUsage; - m_FVF = iFVF; - Pool = iPool; - Priority = 0; - LockCount = 0; - CreationCallStack = NULL; - //----------------------------------------------- - m_pBuffer = new BYTE[Length]; -}; -/*** IUnknown methods ***/ -HRESULT xrIDirect3DVertexBuffer9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DVertexBuffer9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DVertexBuffer9::AddRef() -{ - APIDEBUG("xrIDirect3DVertexBuffer9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DVertexBuffer9::Release() -{ - APIDEBUG("xrIDirect3DVertexBuffer9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete[] m_pBuffer; - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DVertexBuffer9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::SetPrivateData( - REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::SetPrivateData"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::GetPrivateData"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::FreePrivateData(REFGUID refguid) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::FreePrivateData"); - return S_OK; -}; -DWORD __stdcall xrIDirect3DVertexBuffer9::SetPriority(DWORD PriorityNew) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::SetPriority"); - DWORD old = Priority; - Priority = PriorityNew; - return old; -}; -DWORD __stdcall xrIDirect3DVertexBuffer9::GetPriority() -{ - APIDEBUG("xrIDirect3DVertexBuffer9::GetPriority"); - return Priority; -}; -void __stdcall xrIDirect3DVertexBuffer9::PreLoad() { APIDEBUG("xrIDirect3DVertexBuffer9::PreLoad"); }; -D3DRESOURCETYPE __stdcall xrIDirect3DVertexBuffer9::GetType() -{ - APIDEBUG("xrIDirect3DVertexBuffer9::GetType"); - return D3DRESOURCETYPE(0); -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::Lock"); - *ppbData = m_pBuffer + OffsetToLock; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::Unlock() -{ - APIDEBUG("xrIDirect3DVertexBuffer9::Unlock"); - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexBuffer9::GetDesc(D3DVERTEXBUFFER_DESC* pDesc) -{ - APIDEBUG("xrIDirect3DVertexBuffer9::GetDesc"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DVertexBuffer9.h b/src/xrD3D9-Null/IDirect3DVertexBuffer9.h deleted file mode 100644 index e6475a508bb..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexBuffer9.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DVertexBuffer9 : public IDirect3DVertexBuffer9 -{ -protected: - LONG m_refCount; - BYTE* m_pBuffer; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DVertexBuffer9( - IDirect3DDevice9* pIDirect3DDevice9, UINT iLength, DWORD iUsage, DWORD iFVF, D3DPOOL iPool); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DResource9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); - HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData); - HRESULT __stdcall FreePrivateData(REFGUID refguid); - DWORD __stdcall SetPriority(DWORD PriorityNew); - DWORD __stdcall GetPriority(); - void __stdcall PreLoad(); - D3DRESOURCETYPE __stdcall GetType(); - HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags); - HRESULT __stdcall Unlock(); - HRESULT __stdcall GetDesc(D3DVERTEXBUFFER_DESC* pDesc); - - //#ifdef D3D_DEBUG_INFO - LPCWSTR Name; - UINT Length; - DWORD Usage; - DWORD m_FVF; - D3DPOOL Pool; - DWORD Priority; - UINT LockCount; - LPCWSTR CreationCallStack; - //#endif -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DVertexDeclaration9.cpp b/src/xrD3D9-Null/IDirect3DVertexDeclaration9.cpp deleted file mode 100644 index 1015e76b432..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexDeclaration9.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DVertexDeclaration9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DVertexDeclaration9; - -xrIDirect3DVertexDeclaration9::xrIDirect3DVertexDeclaration9(IDirect3DDevice9* pIDirect3DDevice9) : m_refCount(0) -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::xrIDirect3DVertexDeclaration9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; -}; -HRESULT xrIDirect3DVertexDeclaration9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DVertexDeclaration9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DVertexDeclaration9::AddRef() -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DVertexDeclaration9::Release() -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DVertexDeclaration9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexDeclaration9::GetDeclaration( - D3DVERTEXELEMENT9* pD3DVertexElement9, UINT* pNumElements) -{ - APIDEBUG("xrIDirect3DVertexDeclaration9::GetDeclaration"); - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DVertexDeclaration9.h b/src/xrD3D9-Null/IDirect3DVertexDeclaration9.h deleted file mode 100644 index 7ddab65147d..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexDeclaration9.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DVertexDeclaration9 : public IDirect3DVertexDeclaration9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DVertexDeclaration9(IDirect3DDevice9* pIDirect3DDevice9); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DVertexDeclaration9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall GetDeclaration(D3DVERTEXELEMENT9* pD3DVertexElement9, UINT* pNumElements); -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/IDirect3DVertexShader9.cpp b/src/xrD3D9-Null/IDirect3DVertexShader9.cpp deleted file mode 100644 index 81cbda57c5d..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexShader9.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "stdafx.h" - -#include "IDirect3DVertexShader9.h" - -#include "xrD3D9-Null_OutProc.h" - -const GUID DECLSPEC_SELECTANY IID_IDirect3DVertexShader9; - -xrIDirect3DVertexShader9::xrIDirect3DVertexShader9(IDirect3DDevice9* pIDirect3DDevice9) : m_refCount(0) -{ - APIDEBUG("xrIDirect3DVertexShader9::xrIDirect3DVertexShader9"); - m_pIDirect3DDevice9 = pIDirect3DDevice9; -}; -HRESULT xrIDirect3DVertexShader9::QueryInterface(REFIID riid, void** ppvObj) -{ - APIDEBUG("xrIDirect3DVertexShader9::QueryInterface"); - if (riid == IID_IUnknown || riid == IID_IDirect3DVertexShader9) - { - *ppvObj = this; - AddRef(); - return NOERROR; - } - return E_NOINTERFACE; -} - -ULONG xrIDirect3DVertexShader9::AddRef() -{ - APIDEBUG("xrIDirect3DVertexShader9::AddRef"); - m_refCount++; - return m_refCount; -} - -ULONG xrIDirect3DVertexShader9::Release() -{ - APIDEBUG("xrIDirect3DVertexShader9::Release"); - m_refCount--; - if (m_refCount < 0) - { - delete this; - return -1; - } - return m_refCount; -} - -/*** IDirect3DResource9 methods ***/ -HRESULT __stdcall xrIDirect3DVertexShader9::GetDevice(IDirect3DDevice9** ppDevice) -{ - APIDEBUG("xrIDirect3DVertexShader9::GetDevice"); - m_pIDirect3DDevice9->AddRef(); - *ppDevice = m_pIDirect3DDevice9; - return S_OK; -}; -HRESULT __stdcall xrIDirect3DVertexShader9::GetFunction(void* pData, UINT* pSizeOfData) -{ - APIDEBUG("xrIDirect3DVertexShader9::GetFunction"); - *pSizeOfData = 0; - return S_OK; -}; diff --git a/src/xrD3D9-Null/IDirect3DVertexShader9.h b/src/xrD3D9-Null/IDirect3DVertexShader9.h deleted file mode 100644 index a3c8d803804..00000000000 --- a/src/xrD3D9-Null/IDirect3DVertexShader9.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class xrIDirect3DVertexShader9 : public IDirect3DVertexShader9 -{ -protected: - LONG m_refCount; - IDirect3DDevice9* m_pIDirect3DDevice9; - -public: - xrIDirect3DVertexShader9(IDirect3DDevice9* pIDirect3DDevice9); - /*** IUnknown methods ***/ - HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - /*** IDirect3DVertexDeclaration9 methods ***/ - HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice); - HRESULT __stdcall GetFunction(void*, UINT* pSizeOfData); -}; - -#ifdef __cplusplus -}; -#endif diff --git a/src/xrD3D9-Null/ReadMe.txt b/src/xrD3D9-Null/ReadMe.txt deleted file mode 100644 index 835209fd600..00000000000 --- a/src/xrD3D9-Null/ReadMe.txt +++ /dev/null @@ -1,32 +0,0 @@ -======================================================================== - DYNAMIC LINK LIBRARY : xrD3D9-Null Project Overview -======================================================================== - -AppWizard has created this xrD3D9-Null DLL for you. -This file contains a summary of what you will find in each of the files that -make up your xrD3D9-Null application. - - -xrD3D9-Null.vcproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -xrD3D9-Null.cpp - This is the main DLL source file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named xrD3D9-Null.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/src/xrD3D9-Null/stdafx.cpp b/src/xrD3D9-Null/stdafx.cpp deleted file mode 100644 index fd4f341c7b2..00000000000 --- a/src/xrD3D9-Null/stdafx.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "stdafx.h" diff --git a/src/xrD3D9-Null/stdafx.h b/src/xrD3D9-Null/stdafx.h deleted file mode 100644 index e4df7977db0..00000000000 --- a/src/xrD3D9-Null/stdafx.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif - -#include "Common/Common.hpp" -#include -#include -#include diff --git a/src/xrD3D9-Null/xrD3D9-Null.cpp b/src/xrD3D9-Null/xrD3D9-Null.cpp deleted file mode 100644 index 3a992e27f82..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// xrD3D9-Null.cpp : Defines the entry point for the DLL application. -// - -#include "stdafx.h" -#include "xrD3D9-Null.h" -#include "xrD3D9-Null_OutProc.h" - -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: break; - } - return TRUE; -} -/* -// This is an example of an exported variable -XRD3D9NULL_API int nxrD3D9Null=0; - -// This is an example of an exported function. -XRD3D9NULL_API int fnxrD3D9Null(void) -{ - return 42; -} - -// This is the constructor of a class that has been exported. -// see xrD3D9-Null.h for the class definition -CxrD3D9Null::CxrD3D9Null() -{ - return; -} -*/ - -IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) -{ - UINT cSDKVersion = D3D_SDK_VERSION; -// LogOut_File("In %x out %x", cSDKVersion, SDKVersion); -// LogOut("In %d out %d", cSDKVersion, SDKVersion); -#ifdef NDEBUG - if (SDKVersion != cSDKVersion) - { - // LogOut_File("NULL"); - LogOut_File("cSDKVersion = %d, SDKVersion = %d", cSDKVersion, SDKVersion); - return NULL; - } -#endif - xrIDirect3D9* I = new xrIDirect3D9(); - // LogOut_File("%x", I); - return I; -} diff --git a/src/xrD3D9-Null/xrD3D9-Null.def b/src/xrD3D9-Null/xrD3D9-Null.def deleted file mode 100644 index 83f030c086c..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null.def +++ /dev/null @@ -1,3 +0,0 @@ -LIBRARY xrD3D9-Null -EXPORTS - Direct3DCreate9 @1 diff --git a/src/xrD3D9-Null/xrD3D9-Null.h b/src/xrD3D9-Null/xrD3D9-Null.h deleted file mode 100644 index d90f02c271e..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include -#include "IDirect3D9.h" - -#ifdef XRD3D9NULL_EXPORTS -#define XRD3D9NULL_API XR_EXPORT -#else -#define XRD3D9NULL_API XR_IMPORT -#endif - -extern "C" { -IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion); -}; diff --git a/src/xrD3D9-Null/xrD3D9-Null.vcxproj b/src/xrD3D9-Null/xrD3D9-Null.vcxproj deleted file mode 100644 index 833a9948c35..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null.vcxproj +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - {0899B131-F1D4-4876-9BA1-67AC821DB9E1} - Win32Proj - - - - - - - DynamicLibrary - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - - - - - - - - - - _USRDLL;XRD3D9NULL_EXPORTS;%(PreprocessorDefinitions) - Level3 - - - xrD3D9-Null.def - - - - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/xrD3D9-Null/xrD3D9-Null.vcxproj.filters b/src/xrD3D9-Null/xrD3D9-Null.vcxproj.filters deleted file mode 100644 index 5724a843780..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null.vcxproj.filters +++ /dev/null @@ -1,161 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - {8b01ab6a-2c04-43f7-89d8-c4ceacb73c90} - - - {c3e085f6-f2e9-48d8-ba44-0945409352a3} - - - {e53681f4-fe45-4b01-b3da-6adbc822581b} - - - {24e5c548-8ece-4bfa-bc25-7b80fb03dd55} - - - {e81919b6-7587-4211-bf13-4d804fc6a744} - - - {6997882f-ff96-4ed3-85ba-addb46851671} - - - {022b183d-aea7-4759-a3cd-62cce0eb5d12} - - - {5abf5987-7c5a-4dd7-a14d-1ca230085b70} - - - {dd5f7b1c-f560-4511-b99c-1f12a617d5e2} - - - {2b1f941f-80ba-4a09-bd20-7555a198a706} - - - {d8e8c670-ea4f-4b67-b9ed-2c3283615dde} - - - {649a92fc-7217-4072-9aab-74056b114a35} - - - - - Source Files - - - Source Files - - - Source Files - - - IDirect3D9 - - - IDirect3DDevice9 - - - IDirect3DDevice9 - - - IDirect3DQuery9 - - - IDirect3DSurface9 - - - IDirect3DIndexBuffer9 - - - IDirect3DVertexBuffer9 - - - IDirect3DTexture9 - - - IDirect3DVertexDeclaration9 - - - IDirect3DVertexShader9 - - - IDirect3DPixelShader9 - - - IDirect3DStateBlock9 - - - IDirect3DCubeTexture9 - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - IDirect3D9 - - - IDirect3DDevice9 - - - IDirect3DQuery9 - - - IDirect3DSurface9 - - - IDirect3DIndexBuffer9 - - - IDirect3DVertexBuffer9 - - - IDirect3DTexture9 - - - IDirect3DVertexDeclaration9 - - - IDirect3DVertexShader9 - - - IDirect3DPixelShader9 - - - IDirect3DStateBlock9 - - - IDirect3DCubeTexture9 - - - - - - - - - \ No newline at end of file diff --git a/src/xrD3D9-Null/xrD3D9-Null_OutProc.cpp b/src/xrD3D9-Null/xrD3D9-Null_OutProc.cpp deleted file mode 100644 index efee85ee3af..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null_OutProc.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "stdafx.h" - -#include -#include - -void LogOut(const char* format, ...) -{ - constexpr size_t BUF_SIZE = 4096; - char text[BUF_SIZE]; - - va_list argptr; - va_start(argptr, format); - vsprintf_s(text, BUF_SIZE, format, argptr); - va_end(argptr); - - // rr printf(text); - // OutputDebugString( text ); -} - -void LogOut_File(const char* pszFormat, ...) -{ - constexpr size_t BUF_SIZE = 128; - char s[BUF_SIZE]; - va_list va; - va_start(va, pszFormat); - vsprintf_s(s, BUF_SIZE, pszFormat, va); - va_end(va); - fputs(s, stderr); - - FILE* fp; - std::ignore = fopen_s(&fp, "d3d9-null.log", "a+t"); - if (fp) - { - fprintf(fp, "%s", s); - fclose(fp); - } -} diff --git a/src/xrD3D9-Null/xrD3D9-Null_OutProc.h b/src/xrD3D9-Null/xrD3D9-Null_OutProc.h deleted file mode 100644 index 45752b826c1..00000000000 --- a/src/xrD3D9-Null/xrD3D9-Null_OutProc.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -extern void LogOut(const char* format, ...); -extern void LogOut_File(const char* format, ...); - -#ifdef _DEBUG -#define APIDEBUG(str)\ - LogOut("---------------------" #str "-------------------------\n") -//; LogOut_File("---------------------"#str"-------------------------\n") - -#else -#define APIDEBUG(str) // LogOut_File("---------------------"#str"-------------------------\n") - -#endif diff --git a/src/xrNetServer/NET_AuthCheck.cpp b/src/xrNetServer/NET_AuthCheck.cpp index 4d4e698f0e0..debe0feb8d1 100644 --- a/src/xrNetServer/NET_AuthCheck.cpp +++ b/src/xrNetServer/NET_AuthCheck.cpp @@ -30,7 +30,6 @@ void XRNETSERVER_API fill_auth_check_params(xr_auth_strings_t& ignore, xr_auth_s check.push_back(shared_str(FS.update_path(config, "$game_textures$", "wpn\\wpn_crosshair_l85.dds"))); check.push_back(shared_str(FS.update_path(config, "$game_textures$", "wpn\\wpn_crosshair_rpg.dds"))); - check.push_back(shared_str("xrD3D9-Null")); check.push_back(shared_str("ODE")); check.push_back(shared_str("xrCDB")); check.push_back(shared_str("xrCore")); From 8cd060d2a10d47c1a9eb11dc7a373cfc764d695a Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Jul 2024 22:07:02 +0500 Subject: [PATCH 481/497] xrNetServer/NET_AuthCheck.cpp: update libraries that should be checked --- src/xrNetServer/NET_AuthCheck.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/xrNetServer/NET_AuthCheck.cpp b/src/xrNetServer/NET_AuthCheck.cpp index debe0feb8d1..970f0cd4f90 100644 --- a/src/xrNetServer/NET_AuthCheck.cpp +++ b/src/xrNetServer/NET_AuthCheck.cpp @@ -30,17 +30,20 @@ void XRNETSERVER_API fill_auth_check_params(xr_auth_strings_t& ignore, xr_auth_s check.push_back(shared_str(FS.update_path(config, "$game_textures$", "wpn\\wpn_crosshair_l85.dds"))); check.push_back(shared_str(FS.update_path(config, "$game_textures$", "wpn\\wpn_crosshair_rpg.dds"))); +#ifndef MASTER_GOLD + // ODE is a static library in Master Gold builds check.push_back(shared_str("ODE")); +#endif check.push_back(shared_str("xrCDB")); check.push_back(shared_str("xrCore")); //check.push_back(shared_str("xrGame")); - check.push_back(shared_str("xrGamespy")); - check.push_back(shared_str("xrNetserver")); + check.push_back(shared_str("xrGameSpy")); + check.push_back(shared_str("xrMaterialSystem")); + check.push_back(shared_str("xrNetServer")); check.push_back(shared_str("xrParticles")); - check.push_back(shared_str("xrRender_R1")); - check.push_back(shared_str("xrRender_R2")); + check.push_back(shared_str("xrRender_R4")); + check.push_back(shared_str("xrRender_RGL")); check.push_back(shared_str("xrSound")); - check.push_back(shared_str("xrXMLParser")); //check.push_back(shared_str("xrEngine.exe")); } From 040933172e85f93db149b06867ace1101a055232 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sun, 21 Jul 2024 23:06:42 +0500 Subject: [PATCH 482/497] Add trees_amplitude, trees_speed, trees_rotation and trees_wave weather parameters Merged from Lost Alpha --- src/Layers/xrRender/FTreeVisual.cpp | 16 ++++------------ src/Layers/xrRender/xrRender_console.cpp | 15 +-------------- src/Layers/xrRender/xrRender_console.h | 4 ---- src/Layers/xrRender_R2/r2.cpp | 11 ----------- src/xrEngine/Environment.h | 6 +++++- src/xrEngine/Environment_misc.cpp | 20 ++++++++++++++++---- 6 files changed, 26 insertions(+), 46 deletions(-) diff --git a/src/Layers/xrRender/FTreeVisual.cpp b/src/Layers/xrRender/FTreeVisual.cpp index ea4f4481ff2..3108f52ccc9 100644 --- a/src/Layers/xrRender/FTreeVisual.cpp +++ b/src/Layers/xrRender/FTreeVisual.cpp @@ -119,27 +119,19 @@ struct FTreeVisual_setup void calculate() { dwFrame = Device.dwFrame; - - const float tm_rot = PI_MUL_2 * Device.fTimeGlobal / ps_r__Tree_w_rot; + CEnvDescriptor& desc = g_pGamePersistent->Environment().CurrentEnv; // Calc wind-vector3, scale + float tm_rot = PI_MUL_2 * Device.fTimeGlobal / desc.m_fTreeRotation; wind.set(_sin(tm_rot), 0, _cos(tm_rot), 0); wind.normalize(); - -#if RENDER!=R_R1 - const auto& env = g_pGamePersistent->Environment().CurrentEnv; - const float fValue = env.m_fTreeAmplitudeIntensity; - wind.mul(fValue); // dir1*amplitude -#else - wind.mul(ps_r__Tree_w_amp); // dir1*amplitude -#endif + wind.mul(desc.m_fTreeAmplitude); // dir1*amplitude scale = 1.f / float(FTreeVisual_quant); // setup constants - wave.set( - ps_r__Tree_Wave.x, ps_r__Tree_Wave.y, ps_r__Tree_Wave.z, Device.fTimeGlobal * ps_r__Tree_w_speed); // wave + wave.set(desc.m_fTreeWave.x, desc.m_fTreeWave.y, desc.m_fTreeWave.z, Device.fTimeGlobal * desc.m_fTreeSpeed); // wave wave.div(PI_MUL_2); } }; diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index b342d7bb7b0..e2c7a6ec871 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -130,10 +130,6 @@ float ps_r__Detail_density = 0.3f; float ps_r__Detail_height = 1.f; float ps_r__Detail_rainbow_hemi = 0.75f; -float ps_r__Tree_w_rot = 10.0f; -float ps_r__Tree_w_speed = 1.00f; -float ps_r__Tree_w_amp = 0.005f; -Fvector ps_r__Tree_Wave = {.1f, .01f, .11f}; float ps_r__Tree_SBC = 1.5f; // scale bias correct float ps_r__WallmarkTTL = 50.f; @@ -881,8 +877,6 @@ void xrRender_initconsole() CMD4(CCC_Float, "r__gamma", &ps_r2_img_gamma, 0.5f, 2.2f); CMD4(CCC_Float, "r__saturation", &ps_r2_img_saturation, 0.0f, 2.0f); - Fvector tw_min, tw_max; - CMD4(CCC_Float, "r__geometry_lod", &ps_r__LOD, 0.1f, 2.f); //CMD4(CCC_Float, "r__geometry_lod_pow", &ps_r__LOD_Power, 0, 2); @@ -893,14 +887,6 @@ void xrRender_initconsole() #ifdef DEBUG CMD4(CCC_Float, "r__detail_l_ambient", &ps_r__Detail_l_ambient, .5f, .95f); CMD4(CCC_Float, "r__detail_l_aniso", &ps_r__Detail_l_aniso, .1f, .5f); - - CMD4(CCC_Float, "r__d_tree_w_amp", &ps_r__Tree_w_amp, .001f, 1.f); - CMD4(CCC_Float, "r__d_tree_w_rot", &ps_r__Tree_w_rot, .01f, 100.f); - CMD4(CCC_Float, "r__d_tree_w_speed", &ps_r__Tree_w_speed, 1.0f, 10.f); - - tw_min.set(EPS, EPS, EPS); - tw_max.set(2, 2, 2); - CMD4(CCC_Vector3, "r__d_tree_wave", &ps_r__Tree_Wave, tw_min, tw_max); #endif // DEBUG CMD3(CCC_Mask, "r__actor_shadow", &ps_r__common_flags, RFLAG_ACTOR_SHADOW); @@ -1028,6 +1014,7 @@ void xrRender_initconsole() CMD4(CCC_Float, "r2_slight_fade", &ps_r2_slight_fade, .2f, 1.f); CMD3(CCC_Token, "r2_smap_size", &ps_r2_smapsize, qsmapsize_token); + Fvector tw_min, tw_max; tw_min.set(0, 0, 0); tw_max.set(1, 1, 1); CMD4(CCC_Vector3, "r2_aa_break", &ps_r2_aa_barier, tw_min, tw_max); diff --git a/src/Layers/xrRender/xrRender_console.h b/src/Layers/xrRender/xrRender_console.h index d8008a948f3..93ae7627669 100644 --- a/src/Layers/xrRender/xrRender_console.h +++ b/src/Layers/xrRender/xrRender_console.h @@ -37,11 +37,7 @@ extern ECORE_API float ps_r__Detail_l_aniso; extern ECORE_API float ps_r__Detail_density; extern ECORE_API float ps_r__Detail_height; -extern ECORE_API float ps_r__Tree_w_rot; -extern ECORE_API float ps_r__Tree_w_speed; -extern ECORE_API float ps_r__Tree_w_amp; extern ECORE_API float ps_r__Tree_SBC; // scale bias correct -extern ECORE_API Fvector ps_r__Tree_Wave; extern ECORE_API float ps_r__WallmarkTTL; extern ECORE_API float ps_r__WallmarkSHIFT; diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index 196cb2f0015..24322539a7a 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -109,17 +109,6 @@ static class cl_water_intensity : public R_constant_setup } } binder_water_intensity; -static class cl_tree_amplitude_intensity : public R_constant_setup -{ - void setup(CBackend& cmd_list, R_constant* C) override - { - const auto& env = g_pGamePersistent->Environment().CurrentEnv; - const float fValue = env.m_fTreeAmplitudeIntensity; - cmd_list.set_c(C, fValue, fValue, fValue, 0.f); - } -} binder_tree_amplitude_intensity; -// XXX: do we need to register this binder? - static class cl_sun_shafts_intensity : public R_constant_setup { void setup(CBackend& cmd_list, R_constant* C) override diff --git a/src/xrEngine/Environment.h b/src/xrEngine/Environment.h index 3d939749ce9..c2edbb71065 100644 --- a/src/xrEngine/Environment.h +++ b/src/xrEngine/Environment.h @@ -169,7 +169,11 @@ class ENGINE_API CEnvDescriptor float m_fSunShaftsIntensity; float m_fWaterIntensity; - float m_fTreeAmplitudeIntensity; + // SkyLoader: trees wave + float m_fTreeAmplitude { 0.005f }; + float m_fTreeSpeed { 1.00f }; + float m_fTreeRotation { 10.0f }; + Fvector3 m_fTreeWave { 0.1f, 0.01f, 0.11f }; CLensFlareDescriptor* lens_flare; SThunderboltCollection* thunderbolt; diff --git a/src/xrEngine/Environment_misc.cpp b/src/xrEngine/Environment_misc.cpp index 3bf8b658cc2..6d478e32de4 100644 --- a/src/xrEngine/Environment_misc.cpp +++ b/src/xrEngine/Environment_misc.cpp @@ -288,8 +288,6 @@ CEnvDescriptor::CEnvDescriptor(shared_str const& identifier) : m_identifier(iden m_fSunShaftsIntensity = 0; m_fWaterIntensity = 1; - m_fTreeAmplitudeIntensity = 0.01f; - lens_flare = nullptr; thunderbolt = nullptr; @@ -407,7 +405,17 @@ void CEnvDescriptor::load(CEnvironment& environment, const CInifile& config, pcs m_fSunShaftsIntensity = config.read_if_exists(identifier, "sun_shafts_intensity", 0.0); m_fWaterIntensity = config.read_if_exists(identifier, "water_intensity", 1.0); - m_fTreeAmplitudeIntensity = config.read_if_exists(identifier, "tree_amplitude_intensity", 0.01); + + m_fTreeAmplitude = 0.005f; + if (config.line_exist(identifier, "trees_amplitude")) // Lost Alpha config + m_fTreeAmplitude = config.r_float(identifier, "trees_amplitude"); + else if (config.line_exist(identifier, "tree_amplitude_intensity")) // Call of Chernobyl config + m_fTreeAmplitude = config.r_float(identifier, "tree_amplitude_intensity"); + + m_fTreeSpeed = config.read_if_exists(identifier, "trees_speed", 1.0f); + m_fTreeRotation = config.read_if_exists(identifier, "trees_rotation", 10.0f); + + m_fTreeWave = config.read_if_exists(identifier, "trees_wave", { .1f, .01f, .11f }); C_CHECK(clouds_color); C_CHECK(sky_color); @@ -565,7 +573,11 @@ void CEnvDescriptorMixer::lerp(CEnvironment& parent, CEnvDescriptor& A, CEnvDesc m_fWaterIntensity = fi * A.m_fWaterIntensity + f * B.m_fWaterIntensity; - m_fTreeAmplitudeIntensity = fi * A.m_fTreeAmplitudeIntensity + f * B.m_fTreeAmplitudeIntensity; + // trees + m_fTreeAmplitude = fi * A.m_fTreeAmplitude + f * B.m_fTreeAmplitude; + m_fTreeSpeed = fi * A.m_fTreeSpeed + f * B.m_fTreeSpeed; + m_fTreeRotation = fi * A.m_fTreeRotation + f * B.m_fTreeRotation; + m_fTreeWave.lerp(A.m_fTreeWave, B.m_fTreeWave, f); // colors //. sky_color.lerp (A.sky_color,B.sky_color,f).add(Mdf.sky_color).mul(modif_power); From 19cb9e13dfa04536c72a9767ae38317f91eb085d Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 00:06:28 +0500 Subject: [PATCH 483/497] xrCore/XML/tinyxml.h: just clear std::string instead of assigning empty string Optimization --- src/xrCore/XML/tinyxml.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xrCore/XML/tinyxml.h b/src/xrCore/XML/tinyxml.h index 77471637faf..b1f4e0d04e1 100644 --- a/src/xrCore/XML/tinyxml.h +++ b/src/xrCore/XML/tinyxml.h @@ -1304,7 +1304,7 @@ class TiXmlDocument : public TiXmlNode { error = false; errorId = 0; - errorDesc = ""; + errorDesc.clear(); errorLocation.row = errorLocation.col = 0; // errorLocation.last = 0; } From 24be1da43fa8796a4ffd06405aad27a743864919 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 00:07:24 +0500 Subject: [PATCH 484/497] xrCore/Animation/SkeletonMotions.hpp|cpp: pass a reference instead of a copy --- src/xrCore/Animation/SkeletonMotions.cpp | 2 +- src/xrCore/Animation/SkeletonMotions.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrCore/Animation/SkeletonMotions.cpp b/src/xrCore/Animation/SkeletonMotions.cpp index efff81bfa31..8f23b3a82d0 100644 --- a/src/xrCore/Animation/SkeletonMotions.cpp +++ b/src/xrCore/Animation/SkeletonMotions.cpp @@ -245,7 +245,7 @@ BOOL motions_value::load(pcstr N, IReader* data, vecBones* bones) return bRes; } -MotionVec* motions_value::bone_motions(shared_str bone_name) +MotionVec* motions_value::bone_motions(const shared_str& bone_name) { const auto I = m_motions.find(bone_name); // VERIFY (I != m_motions.end()); diff --git a/src/xrCore/Animation/SkeletonMotions.hpp b/src/xrCore/Animation/SkeletonMotions.hpp index afc9222fc76..d47b4098bde 100644 --- a/src/xrCore/Animation/SkeletonMotions.hpp +++ b/src/xrCore/Animation/SkeletonMotions.hpp @@ -215,7 +215,7 @@ struct XRCORE_API motions_value shared_str m_id; BOOL load(pcstr N, IReader* data, vecBones* bones); - MotionVec* bone_motions(shared_str bone_name); + MotionVec* bone_motions(const shared_str& bone_name); u32 mem_usage() { From eadbe55edcec8ae524a868c172132959a7f702fb Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 00:11:39 +0500 Subject: [PATCH 485/497] xrRender: added r__clear_models_on_unload that allows to unload models during level unload Merged from Call of Chernobyl --- src/Layers/xrRender/xrRender_console.cpp | 4 ++++ src/Layers/xrRender/xrRender_console.h | 2 ++ src/Layers/xrRender_R2/r2_loader.cpp | 13 +++++++------ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index e2c7a6ec871..8162dd264ce 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -147,6 +147,8 @@ float ps_r__ssaHZBvsTEX = 96.f; // RO int ps_r__tf_Anisotropic = 8; float ps_r__tf_Mipbias = 0.0f; +int ps_r__clear_models_on_unload = 0; // Alundaio + // R1 float ps_r1_ssaLOD_A = 64.f; float ps_r1_ssaLOD_B = 48.f; @@ -895,6 +897,8 @@ void xrRender_initconsole() CMD2(CCC_tf_MipBias, "r1_tf_mipbias", &ps_r__tf_Mipbias); // {-3 +3} CMD2(CCC_tf_MipBias, "r2_tf_mipbias", &ps_r__tf_Mipbias); // {-3 +3} + CMD4(CCC_Integer, "r__clear_models_on_unload", &ps_r__clear_models_on_unload, 0, 1); // Alundaio + // R1 CMD4(CCC_Float, "r1_ssa_lod_a", &ps_r1_ssaLOD_A, 16, 96); CMD4(CCC_Float, "r1_ssa_lod_b", &ps_r1_ssaLOD_B, 16, 64); diff --git a/src/Layers/xrRender/xrRender_console.h b/src/Layers/xrRender/xrRender_console.h index 93ae7627669..efd7e079cd7 100644 --- a/src/Layers/xrRender/xrRender_console.h +++ b/src/Layers/xrRender/xrRender_console.h @@ -53,6 +53,8 @@ extern ECORE_API float ps_r__ssaHZBvsTEX; extern ECORE_API int ps_r__tf_Anisotropic; extern ECORE_API float ps_r__tf_Mipbias; +extern ECORE_API int ps_r__clear_models_on_unload; + enum { RFLAG_ACTOR_SHADOW = 1 << 0, diff --git a/src/Layers/xrRender_R2/r2_loader.cpp b/src/Layers/xrRender_R2/r2_loader.cpp index 29359f5ac16..c703c7e96ce 100644 --- a/src/Layers/xrRender_R2/r2_loader.cpp +++ b/src/Layers/xrRender_R2/r2_loader.cpp @@ -182,13 +182,14 @@ void CRender::level_Unload() //*** Shaders Shaders.clear(); b_loaded = FALSE; - /* - Models->ClearPool( true ); + if (ps_r__clear_models_on_unload) + { + Models->ClearPool(true); Visuals.clear(); - dxRenderDeviceRender::Instance().Resources->Dump(false); - static int unload_counter = 0; - Msg("The Level Unloaded.======================== %d", ++unload_counter); - */ + Resources->Dump(false); + //static int unload_counter = 0; + //Msg("The Level Unloaded.======================== %d", ++unload_counter); + } } void CRender::LoadBuffers(CStreamReader* base_fs, bool alternative) From 43ad080655b194fff0f0ee07328d9914e2e4ddb5 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 13:29:43 +0500 Subject: [PATCH 486/497] Cleanup CInifile script export Cosmetic changes --- src/xrCore/xr_ini.cpp | 5 ----- src/xrCore/xr_ini.h | 4 ++-- src/xrServerEntities/script_ini_file.cpp | 17 +++++------------ src/xrServerEntities/script_ini_file.h | 2 -- src/xrServerEntities/script_ini_file_script.cpp | 6 +++--- 5 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/xrCore/xr_ini.cpp b/src/xrCore/xr_ini.cpp index 1286e131ea2..914e0cf950b 100644 --- a/src/xrCore/xr_ini.cpp +++ b/src/xrCore/xr_ini.cpp @@ -1122,11 +1122,6 @@ void CInifile::remove_line(pcstr S, pcstr L) } } -void CInifile::set_readonly(bool b) -{ - m_flags.set(eReadOnly, b); -} - template<> XRCORE_API pcstr CInifile::read(pcstr section, pcstr line) const { diff --git a/src/xrCore/xr_ini.h b/src/xrCore/xr_ini.h index 76add450d55..b97c8c8642e 100644 --- a/src/xrCore/xr_ini.h +++ b/src/xrCore/xr_ini.h @@ -81,8 +81,9 @@ class XRCORE_API CInifile virtual ~CInifile(); bool save_as(pcstr new_fname = nullptr); void save_as(IWriter& writer, bool bcheck = false) const; - void set_override_names(bool b) noexcept { m_flags.set(eOverrideNames, b); } void save_at_end(bool b) noexcept { m_flags.set(eSaveAtEnd, b); } + void set_readonly(bool b) noexcept { m_flags.set(eReadOnly, b); } + void set_override_names(bool b) noexcept { m_flags.set(eOverrideNames, b); } pcstr fname() const /*noexcept*/ { return m_file_name; }; Sect& r_section(pcstr S) const; Sect& r_section(const shared_str& S) const; @@ -257,7 +258,6 @@ class XRCORE_API CInifile void w_bool(pcstr S, pcstr L, bool V, pcstr comment = nullptr); void remove_line(pcstr S, pcstr L); - void set_readonly(bool b); }; #define READ_IF_EXISTS(ltx, method, section, name, default_value) \ diff --git a/src/xrServerEntities/script_ini_file.cpp b/src/xrServerEntities/script_ini_file.cpp index 4b876d50bb9..9cf2b8bcde6 100644 --- a/src/xrServerEntities/script_ini_file.cpp +++ b/src/xrServerEntities/script_ini_file.cpp @@ -26,7 +26,11 @@ LPCSTR CScriptIniFile::update(LPCSTR initial, LPCSTR file_name) return *shared_str(S1); } -int CScriptIniFile::r_clsid(LPCSTR S, LPCSTR L) { return object_factory().script_clsid(inherited::r_clsid(S, L)); } +int CScriptIniFile::r_clsid(LPCSTR S, LPCSTR L) +{ + return object_factory().script_clsid(inherited::r_clsid(S, L)); +} + int CScriptIniFile::r_token(LPCSTR S, LPCSTR L, const CScriptTokenList& token_list) { return inherited::r_token(S, L, &token_list.tokens().front()); @@ -192,20 +196,9 @@ bool CScriptIniFile::save_as(pcstr new_fname) return(inherited::save_as(new_fname)); } -void CScriptIniFile::save_at_end(bool b) -{ - inherited::save_at_end(b); -} - void CScriptIniFile::remove_line(pcstr S, pcstr L) { THROW3(inherited::section_exist(S), "Cannot find section", S); THROW3(inherited::line_exist(S, L), "Cannot find line", L); inherited::remove_line(S, L); } - -void CScriptIniFile::set_override_names(bool b) -{ - inherited::set_override_names(b); -} - diff --git a/src/xrServerEntities/script_ini_file.h b/src/xrServerEntities/script_ini_file.h index 94d0c183cb9..e28df805941 100644 --- a/src/xrServerEntities/script_ini_file.h +++ b/src/xrServerEntities/script_ini_file.h @@ -48,7 +48,5 @@ class CScriptIniFile : public CInifile void w_u64(pcstr S, pcstr L, u64 V, pcstr comment /* = nullptr */); void w_u8(pcstr S, pcstr L, u8 V, pcstr comment /* = nullptr */); bool save_as(pcstr new_fname /* = nullptr */); - void save_at_end(bool b); void remove_line(pcstr S, pcstr L); - void set_override_names(bool b); }; diff --git a/src/xrServerEntities/script_ini_file_script.cpp b/src/xrServerEntities/script_ini_file_script.cpp index 31b00ef139f..1aa2a17e777 100644 --- a/src/xrServerEntities/script_ini_file_script.cpp +++ b/src/xrServerEntities/script_ini_file_script.cpp @@ -99,9 +99,9 @@ static void CScriptIniFile_Export(lua_State* luaState) .def("w_u64", &CScriptIniFile::w_u64) .def("w_u8", &CScriptIniFile::w_u8) .def("save_as", &CScriptIniFile::save_as) - .def("save_at_end", &CScriptIniFile::save_at_end) + .def("save_at_end", &CInifile::save_at_end) .def("remove_line", &CScriptIniFile::remove_line) - .def("set_override_names", &CScriptIniFile::set_override_names) + .def("set_override_names", &CInifile::set_override_names) .def("section_count", &CScriptIniFile::section_count) .def("section_for_each", +[](CScriptIniFile* self, const luabind::functor& functor) { @@ -113,7 +113,7 @@ static void CScriptIniFile_Export(lua_State* luaState) functor(section->Name.c_str()); } }) - .def("set_readonly", &CScriptIniFile::set_readonly) + .def("set_readonly", &CInifile::set_readonly) //Alundaio: END .def("fname", &CScriptIniFile::fname) .def("section_exist", (bool (CScriptIniFile::*)(pcstr) const)&CScriptIniFile::section_exist) From 2b9342f097b03a9a82193b6d70af2d2c61c7d269 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 13:35:17 +0500 Subject: [PATCH 487/497] Layers/xrRender*/*Texture.cpp: replace R_ASSERT with R_ASSERT2_CURE --- src/Layers/xrRenderDX11/dx11Texture.cpp | 3 ++- src/Layers/xrRenderGL/glTexture.cpp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11Texture.cpp b/src/Layers/xrRenderDX11/dx11Texture.cpp index cafed2f3e8d..4c728dc061d 100644 --- a/src/Layers/xrRenderDX11/dx11Texture.cpp +++ b/src/Layers/xrRenderDX11/dx11Texture.cpp @@ -316,11 +316,12 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) { // Load and get header S = FS.r_open(fn); + R_ASSERT2_CURE(S, fn, true, { return nullptr; }); + img_size = S->length(); #ifdef DEBUG Msg("* Loaded: %s[%zu]", fn, img_size); #endif // DEBUG - R_ASSERT(S); R_CHK2(LoadFromDDSMemory(S->pointer(), S->length(), DirectX::DDS_FLAGS_PERMISSIVE, &IMG, texture), fn); diff --git a/src/Layers/xrRenderGL/glTexture.cpp b/src/Layers/xrRenderGL/glTexture.cpp index 6e9ec4cffa7..07a0ccf6b31 100644 --- a/src/Layers/xrRenderGL/glTexture.cpp +++ b/src/Layers/xrRenderGL/glTexture.cpp @@ -101,11 +101,11 @@ GLuint CRender::texture_load(LPCSTR fRName, u32& ret_msize, GLenum& ret_desc) { // Load and get header S = FS.r_open(fn); + R_ASSERT2_CURE(S, fn, true, { return 0; }); + img_size = S->length(); #ifdef DEBUG - Msg("* Loaded: %s[%d]b", fn, S->length()); + Msg("* Loaded: %s[%d]b", fn, img_size); #endif // DEBUG - img_size = S->length(); - R_ASSERT(S); gli::texture texture = gli::load((char*)S->pointer(), img_size); R_ASSERT2(!texture.empty(), fn); From 43270965803ada94613319458877d817189e33dc Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 22 Jul 2024 13:48:01 +0500 Subject: [PATCH 488/497] xrCore/xrDebug_macros.h: make R_ASSERT_CURE always show error message on Debug and Mixed --- src/xrCore/xrDebug_macros.h | 135 +++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 41 deletions(-) diff --git a/src/xrCore/xrDebug_macros.h b/src/xrCore/xrDebug_macros.h index 8816883ef88..63032abcf51 100644 --- a/src/xrCore/xrDebug_macros.h +++ b/src/xrCore/xrDebug_macros.h @@ -39,15 +39,40 @@ xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1, arg2);\ } while (false) +#define R_CHK(expr)\ + do\ + {\ + static bool ignoreAlways = false;\ + HRESULT hr = expr;\ + if (!ignoreAlways && FAILED(hr))\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, hr);\ + } while (false) +#define R_CHK2(expr, arg1)\ + do\ + {\ + static bool ignoreAlways = false;\ + HRESULT hr = expr;\ + if (!ignoreAlways && FAILED(hr))\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, hr, arg1);\ + } while (false) +#define FATAL(desc) xrDebug::Fatal(DEBUG_INFO, "%s", desc) +#define FATAL_F(format, ...) xrDebug::Fatal(DEBUG_INFO, format, __VA_ARGS__) + +#ifdef VERIFY +#undef VERIFY +#endif + +#ifdef DEBUG +#define NODEFAULT FATAL("nodefault reached") + #define R_ASSERT1_CURE(expr, can_be_cured, cure)\ do\ {\ static bool ignoreAlways = false;\ if (!ignoreAlways && !(expr))\ {\ - if (!can_be_cured)\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr);\ - else\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr);\ + if (can_be_cured)\ {\ cure;\ }\ @@ -60,9 +85,8 @@ static bool ignoreAlways = false;\ if (!ignoreAlways && !(expr))\ {\ - if (!can_be_cured)\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc);\ - else\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc);\ + if (can_be_cured)\ {\ cure;\ }\ @@ -75,9 +99,8 @@ static bool ignoreAlways = false;\ if (!ignoreAlways && !(expr))\ {\ - if (!can_be_cured)\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1);\ - else\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1);\ + if (can_be_cured)\ {\ cure;\ }\ @@ -90,40 +113,14 @@ static bool ignoreAlways = false;\ if (!ignoreAlways && !(expr))\ {\ - if (!can_be_cured)\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1, arg2);\ - else\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1, arg2);\ + if (can_be_cured)\ {\ cure;\ }\ }\ } while (false) -#define R_CHK(expr)\ - do\ - {\ - static bool ignoreAlways = false;\ - HRESULT hr = expr;\ - if (!ignoreAlways && FAILED(hr))\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, hr);\ - } while (false) -#define R_CHK2(expr, arg1)\ - do\ - {\ - static bool ignoreAlways = false;\ - HRESULT hr = expr;\ - if (!ignoreAlways && FAILED(hr))\ - xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, hr, arg1);\ - } while (false) -#define FATAL(desc) xrDebug::Fatal(DEBUG_INFO, "%s", desc) -#define FATAL_F(format, ...) xrDebug::Fatal(DEBUG_INFO, format, __VA_ARGS__) - -#ifdef VERIFY -#undef VERIFY -#endif - -#ifdef DEBUG -#define NODEFAULT FATAL("nodefault reached") #define VERIFY(expr)\ do\ {\ @@ -170,11 +167,67 @@ xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, (long)err);\ } while (false) #else // DEBUG -#ifdef __BORLANDC__ -#define NODEFAULT -#else +#define R_ASSERT1_CURE(expr, can_be_cured, cure)\ + do\ + {\ + static bool ignoreAlways = false;\ + if (!ignoreAlways && !(expr))\ + {\ + if (!can_be_cured)\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr);\ + else\ + {\ + cure;\ + }\ + }\ + } while (false) + +#define R_ASSERT2_CURE(expr, desc, can_be_cured, cure)\ + do\ + {\ + static bool ignoreAlways = false;\ + if (!ignoreAlways && !(expr))\ + {\ + if (!can_be_cured)\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc);\ + else\ + {\ + cure;\ + }\ + }\ + } while (false) + +#define R_ASSERT3_CURE(expr, desc, arg1, can_be_cured, cure)\ + do\ + {\ + static bool ignoreAlways = false;\ + if (!ignoreAlways && !(expr))\ + {\ + if (!can_be_cured)\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1);\ + else\ + {\ + cure;\ + }\ + }\ + } while (false) + +#define R_ASSERT4_CURE(expr, cure, desc, arg1, arg2, can_be_cured)\ + do\ + {\ + static bool ignoreAlways = false;\ + if (!ignoreAlways && !(expr))\ + {\ + if (!can_be_cured)\ + xrDebug::Fail(ignoreAlways, DEBUG_INFO, #expr, desc, arg1, arg2);\ + else\ + {\ + cure;\ + }\ + }\ + } while (false) + #define NODEFAULT XR_ASSUME(0) -#endif #define VERIFY(expr) XR_ASSUME(expr) #define VERIFY2(expr, desc) XR_ASSUME(expr) #define VERIFY3(expr, desc, arg1) XR_ASSUME(expr) From 419fe72bcb3b1ee3517d87f772d0160f6955a31c Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Tue, 23 Jul 2024 00:08:18 +0500 Subject: [PATCH 489/497] Fix build Addition to 43ad080655b194fff0f0ee07328d9914e2e4ddb5 --- src/xrCore/xr_ini.h | 2 +- src/xrServerEntities/script_ini_file_script.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xrCore/xr_ini.h b/src/xrCore/xr_ini.h index b97c8c8642e..cbfcbdaa2e2 100644 --- a/src/xrCore/xr_ini.h +++ b/src/xrCore/xr_ini.h @@ -84,7 +84,7 @@ class XRCORE_API CInifile void save_at_end(bool b) noexcept { m_flags.set(eSaveAtEnd, b); } void set_readonly(bool b) noexcept { m_flags.set(eReadOnly, b); } void set_override_names(bool b) noexcept { m_flags.set(eOverrideNames, b); } - pcstr fname() const /*noexcept*/ { return m_file_name; }; + pcstr fname() const noexcept { return m_file_name; } Sect& r_section(pcstr S) const; Sect& r_section(const shared_str& S) const; bool line_exist(pcstr S, pcstr L)const; diff --git a/src/xrServerEntities/script_ini_file_script.cpp b/src/xrServerEntities/script_ini_file_script.cpp index 1aa2a17e777..0f2e9bbabf1 100644 --- a/src/xrServerEntities/script_ini_file_script.cpp +++ b/src/xrServerEntities/script_ini_file_script.cpp @@ -99,9 +99,9 @@ static void CScriptIniFile_Export(lua_State* luaState) .def("w_u64", &CScriptIniFile::w_u64) .def("w_u8", &CScriptIniFile::w_u8) .def("save_as", &CScriptIniFile::save_as) - .def("save_at_end", &CInifile::save_at_end) + .def("save_at_end", +[](CScriptIniFile* self, bool value) { self->save_at_end(value); }) .def("remove_line", &CScriptIniFile::remove_line) - .def("set_override_names", &CInifile::set_override_names) + .def("set_override_names", +[](CScriptIniFile* self, bool value) { self->set_override_names(value); }) .def("section_count", &CScriptIniFile::section_count) .def("section_for_each", +[](CScriptIniFile* self, const luabind::functor& functor) { @@ -113,9 +113,9 @@ static void CScriptIniFile_Export(lua_State* luaState) functor(section->Name.c_str()); } }) - .def("set_readonly", &CInifile::set_readonly) + .def("set_readonly", +[](CScriptIniFile* self, bool value) { self->set_readonly(value); }) //Alundaio: END - .def("fname", &CScriptIniFile::fname) + .def("fname", +[](const CScriptIniFile* self) { return self->fname(); }) .def("section_exist", (bool (CScriptIniFile::*)(pcstr) const)&CScriptIniFile::section_exist) .def("line_exist", (bool (CScriptIniFile::*)(pcstr, pcstr) const)&CScriptIniFile::line_exist) .def("r_clsid", &CScriptIniFile::r_clsid) From a5f9add2f1d12513b17a8616d1bb7632de1350fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:10:52 +0000 Subject: [PATCH 490/497] build(deps): bump Externals/sse2neon from `4874418` to `200cd4e` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `4874418` to `200cd4e`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/48744186a26e04d767f77255623f81e79011c423...200cd4e825bf72ff80f84eed477f68d039039768) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 48744186a26..200cd4e825b 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 48744186a26e04d767f77255623f81e79011c423 +Subproject commit 200cd4e825bf72ff80f84eed477f68d039039768 From 83c8b95e25d0b9a7f6c0a2421c7dc88daf059c26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:10:52 +0000 Subject: [PATCH 491/497] build(deps): bump Externals/AGS_SDK from `f686755` to `f4e655e` Bumps [Externals/AGS_SDK](https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK) from `f686755` to `f4e655e`. - [Release notes](https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/releases) - [Commits](https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/compare/f686755b60a18521eb2fe7b40d7b3e35125cf151...f4e655ed363a91a7e0af35f5aecffa175c79a748) --- updated-dependencies: - dependency-name: Externals/AGS_SDK dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/AGS_SDK | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/AGS_SDK b/Externals/AGS_SDK index f686755b60a..f4e655ed363 160000 --- a/Externals/AGS_SDK +++ b/Externals/AGS_SDK @@ -1 +1 @@ -Subproject commit f686755b60a18521eb2fe7b40d7b3e35125cf151 +Subproject commit f4e655ed363a91a7e0af35f5aecffa175c79a748 From 667e1d62cf6a31adac77316448fa5d2c93081ade Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:13:21 +0000 Subject: [PATCH 492/497] build(deps): bump Externals/sse2neon from `200cd4e` to `1a854ed` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `200cd4e` to `1a854ed`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/200cd4e825bf72ff80f84eed477f68d039039768...1a854ed6a0c0ef717755eba17238e8e4e5423534) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 200cd4e825b..1a854ed6a0c 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 200cd4e825bf72ff80f84eed477f68d039039768 +Subproject commit 1a854ed6a0c0ef717755eba17238e8e4e5423534 From 298933579bd8158c3da64fb6c074970c245c202a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:21:03 +0000 Subject: [PATCH 493/497] build(deps): bump Externals/sse2neon from `1a854ed` to `29716df` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `1a854ed` to `29716df`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/1a854ed6a0c0ef717755eba17238e8e4e5423534...29716df957401e9c357348e9b73c95a38cdcd34f) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 1a854ed6a0c..29716df9574 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 1a854ed6a0c0ef717755eba17238e8e4e5423534 +Subproject commit 29716df957401e9c357348e9b73c95a38cdcd34f From 00255b9f3c0f6693950625aa7941f88c97ca5386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:21:07 +0000 Subject: [PATCH 494/497] build(deps): bump Externals/zlib from `ceadaf2` to `545f194` Bumps [Externals/zlib](https://github.com/madler/zlib) from `ceadaf2` to `545f194`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/ceadaf28dfa48dbf238a0ddb884d4c543b4170e8...545f1949635949159fa6282e81712aec32b5d4f1) --- updated-dependencies: - dependency-name: Externals/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/zlib b/Externals/zlib index ceadaf28dfa..545f1949635 160000 --- a/Externals/zlib +++ b/Externals/zlib @@ -1 +1 @@ -Subproject commit ceadaf28dfa48dbf238a0ddb884d4c543b4170e8 +Subproject commit 545f1949635949159fa6282e81712aec32b5d4f1 From a43165afc572bddbd06c49e65e92d959f2a9be84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:24:37 +0000 Subject: [PATCH 495/497] build(deps): bump Externals/sse2neon from `29716df` to `706d3b5` Bumps [Externals/sse2neon](https://github.com/DLTcollab/sse2neon) from `29716df` to `706d3b5`. - [Release notes](https://github.com/DLTcollab/sse2neon/releases) - [Commits](https://github.com/DLTcollab/sse2neon/compare/29716df957401e9c357348e9b73c95a38cdcd34f...706d3b58025364c2371cafcf9b16e32ff7e630ed) --- updated-dependencies: - dependency-name: Externals/sse2neon dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Externals/sse2neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/sse2neon b/Externals/sse2neon index 29716df9574..706d3b58025 160000 --- a/Externals/sse2neon +++ b/Externals/sse2neon @@ -1 +1 @@ -Subproject commit 29716df957401e9c357348e9b73c95a38cdcd34f +Subproject commit 706d3b58025364c2371cafcf9b16e32ff7e630ed From 75e1928774bfc35938dd0d9afd26521ea50733ba Mon Sep 17 00:00:00 2001 From: Sultan Uramaev Date: Mon, 19 Aug 2024 17:45:36 +0500 Subject: [PATCH 496/497] Create CODEOWNERS --- .github/CODEOWNERS | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..f706ea6ac88 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,10 @@ +# Lines starting with '#' are comments. +# More details are here: https://help.github.com/articles/about-codeowners/ + +# CMake +CMakeLists.txt @Masterkatze +*.cmake @Masterkatze + +# xrRender +/src/Layers/* @vTurbine @Xottab-DUTY +/src/Layers/xrAPI From 34f7e49e519913026648c611e5929b278de20943 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Sun, 25 Aug 2024 16:56:51 +0800 Subject: [PATCH 497/497] Support running SSE intrinsics on RISC-V platform (#1710) sse2rvv is a header file only translator which allows to run SSE on RISC-V machines --- .gitmodules | 3 +++ src/Common/Platform.hpp | 3 +++ src/Layers/xrRender/DetailManager.cpp | 2 ++ src/Layers/xrRender/ParticleEffect.cpp | 2 ++ src/xrCDB/ISpatial_q_ray.cpp | 2 ++ src/xrCDB/xrCDB_ray.cpp | 2 ++ src/xrCore/Threading/TaskManager.cpp | 2 ++ src/xrParticles/noise.cpp | 2 ++ src/xrParticles/particle_actions_collection.cpp | 2 ++ 9 files changed, 20 insertions(+) diff --git a/.gitmodules b/.gitmodules index e0b9e0abb38..4e570902340 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,6 @@ [submodule "Externals/xrLuaFix"] path = Externals/xrLuaFix url = https://github.com/OpenXRay/xrLuaFix.git +[submodule "Externals/sse2rvv"] + path = Externals/sse2rvv + url = https://github.com/pattonkan/sse2rvv.git diff --git a/src/Common/Platform.hpp b/src/Common/Platform.hpp index 6bb391d3ac5..74731c954b9 100644 --- a/src/Common/Platform.hpp +++ b/src/Common/Platform.hpp @@ -42,6 +42,9 @@ #elif defined (_M_ARM64) || defined(__aarch64__) # define XR_ARCHITECTURE_ARM64 # define _XRAY_ARCHITECTURE_MARKER "ARM 64-bit" +#elif defined(__riscv) || defined(__riscv__) +# define XR_ARCHITECTURE_RISCV +# define _XRAY_ARCHITECTURE_MARKER "RISC-V" #elif defined(__powerpc64__) || defined(__ppc64__) # define XR_ARCHITECTURE_PPC64 # define _XRAY_ARCHITECTURE_MARKER "PowerPC 64-bit" diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index 3e0c969a306..36408e29887 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -24,6 +24,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif diff --git a/src/Layers/xrRender/ParticleEffect.cpp b/src/Layers/xrRender/ParticleEffect.cpp index 5add4574b31..c738584e1f0 100644 --- a/src/Layers/xrRender/ParticleEffect.cpp +++ b/src/Layers/xrRender/ParticleEffect.cpp @@ -9,6 +9,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif diff --git a/src/xrCDB/ISpatial_q_ray.cpp b/src/xrCDB/ISpatial_q_ray.cpp index 73fbc72994c..9046c53399a 100644 --- a/src/xrCDB/ISpatial_q_ray.cpp +++ b/src/xrCDB/ISpatial_q_ray.cpp @@ -8,6 +8,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif diff --git a/src/xrCDB/xrCDB_ray.cpp b/src/xrCDB/xrCDB_ray.cpp index efa6c8e86ab..30a798fac69 100644 --- a/src/xrCDB/xrCDB_ray.cpp +++ b/src/xrCDB/xrCDB_ray.cpp @@ -10,6 +10,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif diff --git a/src/xrCore/Threading/TaskManager.cpp b/src/xrCore/Threading/TaskManager.cpp index 3dad17d9ed4..4746f70e886 100644 --- a/src/xrCore/Threading/TaskManager.cpp +++ b/src/xrCore/Threading/TaskManager.cpp @@ -31,6 +31,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #elif defined(XR_ARCHITECTURE_PPC64) #include #else diff --git a/src/xrParticles/noise.cpp b/src/xrParticles/noise.cpp index 582d79c4cd1..d2574e87a68 100644 --- a/src/xrParticles/noise.cpp +++ b/src/xrParticles/noise.cpp @@ -6,6 +6,8 @@ #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif diff --git a/src/xrParticles/particle_actions_collection.cpp b/src/xrParticles/particle_actions_collection.cpp index 413df325b23..31090068d78 100644 --- a/src/xrParticles/particle_actions_collection.cpp +++ b/src/xrParticles/particle_actions_collection.cpp @@ -1620,6 +1620,8 @@ extern void noise3Init(); #include #elif defined(XR_ARCHITECTURE_ARM) || defined(XR_ARCHITECTURE_ARM64) #include "sse2neon/sse2neon.h" +#elif defined(XR_ARCHITECTURE_RISCV) +#include "sse2rvv/sse2rvv.h" #else #error Add your platform here #endif
        3. n40n}CwP^;np&pc|6JEN?+dW|hL7_fBS$ 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

          lAT+IS$O3Ba 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�C!5QA_bjD7|~YraOmfW_~a zWOPQO%->v%@4}GHRP=|i=q2gRQ^L@ipJ2^yL@V9=QY^juZJU|j{2J}c>}k5%&Ll0J zvm0j-V!x72T0YM)ketT3gkYNAIFC?!PY!AMyue5nGQv}C<03}wO?i#Egvhkmfi7!Y z!l;&)5`%6v&C7|O$L19dDZgBV7*^ zb7A8KFzDtjjfISAd84bb35;!xTCi^I+)B1!nOpoYE!sT|cDDE_tBw3K)FX08p8)x)_6v*TB%4 z8;#e&qIV284l=6co36$!VaR5v@wTw|CHEVLz|fmJo~*mVdf2FU_n2wlG_7fv5Sbo0 z(nmlsk2F38gKr)ID)SQ;W3=%p7+UkZ@fleBj!~d8zi>5P3PUzyjjx2oFBxwf14D0K zd$8U$z7dwGdkZFBMe~fNab~CUd(q$*AA}*BiN=q@!gnTwp*5d8Sd)#Pg{6028@~t> z@0t{b)_enNb`x6Z=DT8P-BjZb#pIWz-;$-e8)y62FMe+Z|GI(+)=I>&1*<+UY=j zO}iMCxuj_~Gw5C)BbZ7ZX*p2L{-#PW=;m;fpHVFbT#QIl5DdKuG0VQ9yD3bFO!ba5 z3KVm!sR<0eIR;ebRu?1L6bD0VI-3$;(K`+`B^lLn%GKB_4B2!w?GqMW(gntmCau}; z$vU7|dUueR^di%InE2gnKI)KqnvO9_U+-ZA({Tsd+jN3anNKyHWCq>a%Lt~^j`R#r z%zaH~!JwP_oB9~l@;MjdV$*pr^yUJy_!Um+68o+n(q)%C&~yb1zH0!e%vW8E!KQ0q zXw8kL>tNA4hMNW%)$&bOF$?mn%dvgw*Lj7Idki@SQeY7 zvqY_#jPR7*Jd08KT{a__<~Y!t=DCc@JimD!Gw9wNMldaKqzi#!&TU=<2Hl+3oXe<| z7rPkCnwNl~H%pntuW(As*>`!6R=DK+=9OUZUHL#|UgcsGG_M9jYt}Ze0gK*I)Lg)* zme;u&>xChk!sZRa;+Je`E(AkwHhQu)32R%k-fdulWa?6+C`+kuxduRrl zuLuh_4+ukRu6nQro39B=?`||-7bd@JxOor^y}9Yhx}{iJH`IJvG4Znd%|pU6b$2|Q zcNOztv#GrYHs0u#AHes+B0uubj5I%H*6bL6C!I%xp*2rDSfkBPg{61To1Y1j{*9#X z8Wo1tyzpebR4lC$^>(WHhidb`(La|?sivv@ z`A_yQgKh4AXTHe%+YkJl9?Se0GCyZpjXh<@W?5~<%eERi%~9H%*j%gS^ZeL6i)7x- zu^KupP}_y1rE_j<5h0nE^J2MHi}PXwSr%JDh)hc@YH!h|<(8L6rWJ-cKemz(`@MY9 z@_Chk6vS2&f@y7R4WXGmMX>^_#d)2PtY?I$!q^5z?M+)^g@nko(UERqbX!d3&6Z*B z)TXVLS45`mhPgPlgAn_@V$$+?r-Arly9mKl65CCvy~jsdK9?FvIU_vzW0j2Bo5C?a zAudMrH1dC75CFJrqk4 zB2&td?gfguE4B{|zPXFhBQcrxyBY_Cp*06B%f3LH4qIL~nT{Ifp4c%$?Du*|%je?; z(i=NL2&Pl9lZ4uPdP&RY(?)WJ5uW;DXBo9O^~d@Mk?EWRy%;;ssFp7fgKjm=mx$lb z=F1LgAa;dO`uYGPn65g|!PqrMWxf%+&J26+aBPqenQl7LTR<@n#cqQ^H{Xv9F{%oh9&=^N;i!#g6W9^9gRI@ROaWgXUw2`M;XEN z!jZlNig_&d3Jkh=JT}ItmS4LV?_zJj(3`i+vagudGERt0?;Ys}pqM9OAHm?8CxFWQ z$;FtAeFj5ozQ(?Q#qXG8bViHJ-&~FF!jR2W?1!-ECF#vm!qA$ZV9jnpE8YB3EWP_} zo0;GITI|d0X}a3ZBrTn@TV@erzmiQ_KF=|boR+zSV4B}Dk5GG04r%$kz(^J{!c%U` zB1Y{^c`dnw$h6pjE^ArBsFs%!gKjm=%ZZ=I<`oVpzhxz(^!0p3Fs*W+1ud%?m3eK; z8fMsgi&_c@k!hVHT@MsqpPtAjBPDivzb`*2GhKi_(g2q?vRRG zb}&j`FJ=VOP6z61*~O^LB`v#|LHGI?!Bpx<%YkC{w^V{bH-}sNjA}XHVnkYkVCYSV zS@sp(Enz}rs&}MOpqOJVOS;N~DBaY<2&Ur>w72C1qcWdr zImryVx0ex2ryc1TpqTqw&VoTV_qX&hs^xPo#>JNNVCc;SX7MYW(k1p?Kcvepd7$MA z7<|_NP?@i~7=ta>z|fi-E!V-KcMP`-GOFd9uEs54$Y!YJwy^jm_gjX*(3?A+th>T` z*rIp$m}%cMt#z0XnI1UOM?f);v^)lbZyo_E^Ai_iwB;!nTJyZ+8Cd*|QJ^xva5Y{E zLpEbAuY|=f8E+W_LvLPtu->)25tgZY3npGg^NiMUW~cLe(cl*!gdv-WmXE^1cP50P zHJ?0KlP#ZxrFUOjz6cZVniPiCd;@ECD_ZI1yJBhGRLc*=!2n^G*j`{~*IrJAPp zw{2&B|8KSLw5RE6JCn3@&TgGWi2X`7Y56?IKyq5=5`t-d>pVj3JvpT1^8zDT$Ouol zt&147H|4eF5+c)L2fD0v38PwGN({QyG%qK99-CJn_2 zt!tQJ?=5OAAVj8hj&wax%!RERz@VGAv=%a|<&Cb!CNQ?OYRzV1(Hl(jR^k`2dAma@ zZr#BseZ80wOgkN@uXPurGMBXOW(M8sV+2#FBP|Dt+22|T2HhNP^)ssFfQu1n4T7OJ zA!gZEbhm~Hk*VI1MuB3EwKjplH^+d=-0ET^TjOA8O=oKYEPBVG)+D1^PPrO;g&~`+ z)_ualOS-@~(yBH4Jy{17OYaU6lU`(+4->ze%|{(lPwO#8>FYg=U^?zVds|O1D)Xt< zlgyxddl|uW+L4|Cin*`#EEsfie`_D3T0ZAuTx>lLhTdFY7QezNU1Hz$L%Qse2U@Ry z!FLS+mHDcRG1z(y46V7*dL1l!$8hT)qguY{YTOcrY=&BI3yWWJzjX)(fUzXc*%q?wC0ls zYqIsTu=MV0>lb0-U6WwUXw#Z+o~-YRrFB!SKNOQ+mcC<3vGnezFlV<(Gu{1CO;h`u z+L?a=h-bA~x57N#NMj9{AMKy%vWGAi@@wt38;dvh4Uw7`)r1d2Jg zZ4nrBb6#66qgr0WwE{3md7Z_So(zY8ceuodJ%%!eIxiDnoZ>tm*za-q|2SaZH9;`@P zP*|oe1SY+zyDiM9mg`-Os4!#`Yikk~UJ?_A*0g%Cl5KHe>0M`ALYVxnLv2Yg^d{xW z+N)Sv*VVR9G38}l!aCBXcl$k?2UOG49%MGZ&`#6h-NZ|$!;raq6e#ANwqs!M?|XpC zeB8z8Z94&m)|_fP2^PPj7pTmqU5zuskWF9PSz+-@`rG=z(3^7}tcz{ug=Ok4fQeVR zzxBo2mG?TP+&W_I_#P+jE%jY=;k`tdx2&Vb* zd4$?~a!AYP1xB)v5uS46ix{;x<;8Oek!i65T^3)$sFs%!gKjm=%ZZ=I<`oVpKfaPt z`g%Sim{vK^g7|7iWnLR!!wh?GQM`ZVh6;G1JWWo~sblJPhgTGJU%fJN^( z6i+g$<&>+jR~WMCitiH^UeX1|k+|0E_hcPVEWJBOOnQ-NK1}>>HXn6JJ@I3V(${+! z!F1e#_Qp>zD)XuMNoLT!y^LTw?MTl6#oQM^3kKcXAMayS%jaB-i}CYd=*WwB|VgO3T@Id5~7PEvNj28Tf5$E zW+uPMDQ#un6+znWl8f7SfWdba1C@EFi{WeE1%}p?wC@Is-{Au)bE&IQE)3cD+be~| zFA2B%!O)w42P@JZ6qczAfl06GZVxl6<$6~mDh%1g+M9%hm&AmjHLV`3WP4m#de_;W z5GKFtP6e#AN z_G4i1%{@S6KJH@lwx0k)YfiPF1dHF%3smOQuErT*$fmFTtg!ec{q22V=*>9~*2VVo z!ZLLiz{IQE@+J7bU*yXknt}E!!otl1!qA$l9<0IkYr@jI8|~MH$?qC&9|S{hZhEqA zDVEj^wcl1uyzGAakg!bM9na=n#eCRqYVUzfZ=9AGW>m`$T#ZMzKlia9s22n@P8FOkcrmKVDi%Mwe#(3_>q z;#WAObIyZxF>zj4rtSimc$Hhe1mE|IeAz=Ykhmf&+&mx*t-0#K8cbXhmfqb+ zTo)$4YdA3ohTh!tWZhCMts6?*R!qF?equ;irtXes^R8k(OqkkxVAC73I))k5@&i}n zkuYR4l6WjEyktZeTJyw%HJW%TEWLZ4cqUA|Yg8Co^TLz$Qn9pdEb&S)@v`y6n6OOU zYmer;#2dvlw{L~bubkE~4u;;m_hfxgEUlYJd{j(%*@R;0-6xOcWa6`8n%b|4FN!Vi zoD|lK4!!&4+5E1WdOMZ)q1t$9`l>0_G_^k!dv=Frr`ul!+uZ-=U;O?eh=vXZ*y<6L{ zMwtArqK*PE^k$tWYrSG=U17%t#l*|DbQB89)NS-^Zc@x`9j10O*m$E`-U{CriM-uI zQ{1sbSh%@Z7+SN_gXQbkB`m!w>DVnyyvrvHtts_nl`EFk`8z5V6E6#Q_=RQa0v^ps zM^G`%ZAjSs%I=OZ7n2A?-)@m zy?f%(9PN0jn5Oo5$1|}1FNuHdbTg`0diTP!`BF9YcC6!-YV*I*^rhn+V~S~RU;l&s zuH%hrJN0jsFSM(@cJGz<#?|h_KeQ7aA5~ksYC<(l?WcdRCp$i?wz>b>@kRYYyL(bK zP3^aTvcDT_Q$N-5!|;WE`INyn_doyni(kesoXGFYSDF9YFZekjpPg?JoP2dGHP$? zPxcWa(>VuvF?pU*Engr8-D;XI5x<|!mmShT@(QE$^#MjOU3H*?$!m-UfqizMmXoRLgfKwLOoF5p;BSv@{Nj_$j zZW>_((-Q|entaNr%+Hh0m_hfBGJ@%aBYg=J^H}l~7 z4`II&%q;X|V%c*13dHEiWYo-D;Yb6F-m5 zD;!dO=SoKD>-mgeTIE0sI#)9)^V-fe%&_+sbrujJ(>h1G9w_F*&JAGD&09JP8P)Pe zS7Q?x+d8#oGqLCmrg?^uE!-U9G??|ISF~>Taz~Gx>KxJ-qF_N8e zFtnz#GXWO8<4|XkQ7xxjjlIHxbxn*E-v1B#`02Z?E2l(JYyTW?dsdx97Y2P$0HB5+14;<+upqNKGAA`X+j{ueV ziHkAX`4kMTdEWU9EPlr*P?=x28ZU(*o3YMU!s3^VcaDLfH?KWd?>gTI%hbIE6R)Cq zMrxed>HJClA(S=VxK*-Pg`9!o<5Kg`qXyz?z*xE8Too zEUlaB{Gpiqvh;gXiluiyJ)6H&)71X9?ac50Df>=)ny$7pNlWMK)GR{mSF%aV=Q#$F zlbTBirunIPgxY&@NXzF1MzW9*o^n%*7_~R$rE&?8X|V%cmRiE7mX{KPZZ*xziJ!;j z6%HvswUSZ#dOjnVRyoju)M`d$UYlCO40~@;s(=ug);ZGkKrt7lHh@7lZ%Gw0s^yKY z#wIYfrL<-PzinROXV@Zf4NEK1MK=I?{5W znEk0rFzDuR%Fn2l11?4+6$C?XLd>$S=uU+Rk*VI1MuB3ErJBItn`1y_Zgnw|sW=!~ z)0s+uMejJ2N;0bDl&i5<7_#X~?GqMW(gntml-BI`WF1f}y*o%udXZ^9O#E&(A9YAQ zsbh@N*LxVjblidVrcN*_^QqKHX3)L8j9@zLNY4Pp+?P5F2Ho7B>SI*P=Uj}7sq`!hE1c3L_FX@u%Px5!bp;H*YXGRsS6z(3)HN`)=0@r|SoDtJ)F7i;zUgY*5{7Js zQn!W0FS(x@0z+@^c(U#a>tRao?lIH8DQnL#Au>I1q>q4N9!Wh0gKr)ID)SQ;V>I;? z46S*ddIlE1V-%>&FIXoqgCF7|vF!biN2kTwxjj&AJTQKQW)Ao!rs^#~t z#s^`@W+L@bSa`{VFtp~A2Wv9*Sy+1aHT6Z9c-JHtGxliBH&51g#nQT|)DOkvm!q?zu1sivv@P3_FT0PM}$W8Dh#bR(I`2v6C2W-&@%&t?SE90!`SXD*{M z&)+kT8FX(BBbXLA(uF`V=k8eq2Hl*uCznwzFLp7O?O6hb-YjJnzrrakXW!*PTH%uO z_pAhi@5%=%^C}mkV9#nWv}Wy|HDJ*@iuM#Rs^xXA#(H7Mrf|;&Vew10>?s68Z#H_e zHVJFn9=+SlOn#G7+RDBwg0$Tw7w_2t2H#Z-ROX#7hHuX6 z$vtsl>0RfZgfRJChxR1F(3_MeYp-HyUDuv{iYYJa64sGDdbi)Rc|bKy?LlVq3+*&* zZ#VJM=`dvO9tDcIXU{P(`1d_P|3ABK9}?Bx_U+pXB@tZ~5fagD5g`#_5g`$6dm$tu zEFvT#EFvT#taKd5XwRGDIF94YIF4gPSVTxfSVTxf*b5;MVG$t_VG$t_VG$t_?cX&y z>$}dk?^>(pZvVKhoBhYLJwKo0SnE8U++DTrhv$fm5kCz08oBOAf5Q z6PKAKcUMnbVJ5z7;6xuW$+e`UH^$2f=MsCbE2PFy6&c9^Oj)VJE3cD6Pw;> zm+zwIr_>IxeBVJcc;W%G;O6Xm2bm!?4;@%TCmu0N?w*`@%uIUM5HqCasUz!|U`gHZ ziRXezFB>^A%q(5^!lC*4#7n`{x38GZuXNJ9Vec6cnzs(S(G%~8IlY#?FWZa?mfXE} zXpWuuAeg%L(}|CQjX$sKonwL}cb^@bUqn-G$4`6}ZRyf+(bToye#!o>vGx5A^9l36 z{s`0LTJw7`r>UTYbAIhKKukX$w0NGOAqBNF0ikJj?JPjeJq4h}^BgUiiwI7Iwet`) zHx<aaL3%aOw0ise~2n@JYH!lW$5t^4+q~hA8h{CrQBSOL*dz4u44qt5zqEbF?Yt%A> zH||;&v*;ymVgzcX#^cC3DOhrM3YhRB-RuXx7tKM76s`>+3f~?^gr0M*Qm{KP-pB-6W1WW41YrhI6zASskxM0cMH)c++<7T$|E}FXb z2ei$<_t(K&;XGMOrXqqnu_5JPSjA`4$(l@_Dtibz^wlZ)$?5(DolCY0x8HbzO^a$-o$ z%DNTAf_IeFl^`nRRkp@zX7Hx8ZVj{WB^&BWi6J*@9a-y`wW&_-)*}<&WR*6e=gLUh zY?I6Dwh#mFDkqfZtu{tQ-8N!K&5pY5#KLz}5X$pTTVoe9cvD%on_2jhs=7*I$ju%H z*8aM^%+huHhzYOq)>R=Y!QSvnnYcUSon@Op*$yTjTAF@lc`HH3t!Sxmm!ASoOWQHt2@IiU3Zq4^eVf2 zo;=^f@&yM?Z{0;^(apWgkeW*ltiHO-%#ypSbyt{)?;5Dt&+maco@(0pC@QZV)HD`xX6aWlm=LY~Ps zZ-kCN_g1i^ZnW;5VDk5k3YOfxcW92)eGp7t`>F1uVDmf21WWEdGjqC&o7wJ*Xv*z) z-B;13muBBPE}FXb+b`MQHMYM00iQ7b`;R-%r7kD)WG$JB2u}H~X^6tN=OaSX3=3M| znu#dSvt6^00rwUlLem^eI+swI3tjVw0XG-93K5m^d>dntYXLFjW+Afh6;^36daj71 zB{sR(wUiimS23YHFS9X9T+4|eH7i{!hz0K`bCn<}v8-Qew!> zT1VD8W^HoG-Fjr=o2=4C^jsN9n{9HrYYQ>(u5v{_ zS|vYv&P!6zCWl=iV&Gk2LV1qZ7;#sW7*dmP#fXLPh!e_l($+{ZgEtvhnpyag9#@7K za&y{&bP%#fN(4y-=cWoF6URo4|};=2Z1 zeZ-KPYmThzf+cnRt{Z|$FT3OFXO^zJ>Das_nD<<|_BOHMjd}G0h)Vgct#O|jycu*o zU>3b(kQq|*(1A7Ndc-Wbd*XV`OnTQ4Go#bl(-KguGVDigG1xxPUJ2b~!9|Tj^esX;jY<}k$v!>L` z-Dk(<7txg4ao1PTrk7@~8W&An`%SQ?*GqP`{jRa~{SW*E{4YTD=Jk`@c_d9H8M{*n zr8&QT8Zq$m`GoR3!^SA6pGgd)?!DEm%@lTE9jx>17-0OPQtX);c!V3FfAHUAvyx^hUe9kvw0<@@5B3dHoh<(aq(| zkeaOytcv<=%#ynu_1l?A@2X&i)a-O*?Gh}htE}HGnDnx$`buW$x;+lf{q=hVQ{V1m zHonqZUquYLIpD}TC|FWgU4KY0`DN9DC3lA%nl<%D1XI@@t3N8(^iE%W4YPFJamQw@ zXv(d--X+@7rEb9t)azQ$FWDzGw!S|_o}d@oWj}g;irdR_&_NTf4>1dF&b~Ly45^7Y zu;TSmX31TmKE_OXSDYDAlXPUI1WW2N^=ZMRm-WE z_MRT0x!|ztt-mOk{ElA1lDkU|&A$4}f~jk-)?X29dgnlWAG37bHOJ<4(UjZ%`WvFn zFTGRWFPQrF<}cZ|MEhR7zQ4_$;5R#I?y~m`2+e(m-C+F#VorC{_hp+w!IHa&4$YzZ zM}nzqpVU7VZ2Wm;?;H{=xqIr^d?uQ5J6!))(mCbk(S6>e~0eV2{;*5N&<`ss1B-;$Lq5d1SjW(bTn{f64x$ zv331;{a4Ks^b?=Bd|YGe`)|Me#CPozR^*5Il=F0wM z&oeZnz&#TXnr6Fa0c!3k04<*9Xvthea4K}qL)6?<V;i z5tZ^fTxy~L24eaJGe@Vcu2;pu=SJxD0c)$T*Yz?-WH z<@vCUQR6;B45>NhK1wWjhtFMusFaV}8nw*ejoa;F7QMtxjDTBeJdUiBf+csSfC(?s z&3@o}(Hyi$VRr~o`1UX&G({|E+#N-f=Y%_k47fLr2u(>#nj)0uj5|#XxVgujK~&18 zZH#m7GsKXav&h0%Sf%smxgL@(*yLXKMPlGxy@c|7$;Rk&UnYjsTy3u?J9&|q-2HreK zD9;aVj3M_UVo1#s_hVw=JBA45`Khh(j2XNcc0XqpzGTEbOboes;lO(Be#tCd_llVC zs!0tah)Vg5t?`x_ycu=BV-~$+lo?X<-hnmd{=h7``{e$}OnTQCF{U&~&1Xl}7r~Oc zaralj#Fu677#A$L`^L=a4cyFj-$hf`{(!dm_x=WWE1V~5$y7ve%5Rv4D12i+A~emg zpal&x5#@Py!z^ULy#5tZ_M8)H$!0%FL`LS*49tkPoi zToFl2Y;tkKQexm;#f0*_%*H5bSWXP7S=q3HSn!Urh7v@jyvo*C%?#d@HmqS5zGOo~ zDKX?`ts`q4vo06a25%}Gb~6iKQq@pN47u6kz}nximsz@QA2H!o-i9hfrF_8FILHj%R5u)A z7QLjJ8B%lDfmPFRgjsTTtl=m#@m;=#8e+)JaYt6IU`d_3!6lgdGB>jV4RYskY@QTN zU3&`I;6jfV5|;dyG)O4T;f4?~@a8a~JV$JdcteyJQj=(i5ewfDCzR);t&w5|Z!!&O zX5mYE8ZyL?o6`=ga}8&hrR&ZTlU`+)&y(kSSiaz(>20{kEV{Xu8B%k}fz{V=nOSmo zwc!dg@m&KAeZ-KPYmThzf+cnR4L1anUUsLUpIN%@repJ#VBTxcwYP~4Z=B>AKvc?i zZH@cP;LTve17^`n2ALr>4;@%T4Ud>5cTXA~Gn3vm#0;r<>d1N~SW-9K@LVwIWg`v4 z%+hr)9Gb5iUJ9nZeZ_2kC2pp8M#wYS=8e$t=iUmI)QvX06HNZTQNfbC_YTdmh7W?N zYdXJ$_Ka5LL|5ly)rZ}=+O^wR8m$3;`ue)}c+yT;b{Kj0JQfB*5o z%i%m(OQs@%Q@&>!qVSFRh|n~{f);pYBFgh@&n#rXy#X1ma$-o$O3w;n!8^)4 zC5TFSm94Rw8N4a=tYH?uWP_)a7;>}Lk+qIln>=#29+~(itF#e4S4Prin_TYMLJYjC zoKT*(+87m{ZN!k89iHvP!go{<%JWWJV;3`cQ|Z~wEPP3or;-?Qv&Vt8-?Nulx^5pa z;ZB5$UgH3wQod_z+-C-F20ag$MK2j-hSWTCU=4X5F-z{Acpfv8-ZjJwsd?(i zdL~#>H|%*XnDnv{&oHxe-3y22YtKu;)VHsgjjx>4I6@4$dE>}>D_BxD>Uk%a{IXHO zlDqc~%`wjh!PK>%JRb#{-#NytDUEXX*|GUWH05^O^HsFzrP-^-MN`*)6YS}YlAUe8 zYixc013v-(3s57z9;eBcbSj}V=QmCx27Y@!p*+v9F$x-I5<_ZcH_jp!zN3Ipp6A#a zbD6=L!p3>b!j}{^77{~l<~y(!H7;P5u3JbX35>k#ud!Oca=4k5JPTOIkHv@meiFtt`SUn*@nhaX6d@Mj?Hy~xv5dtt|vCV z(JpT!&zG^h*+Em@xP@7Cb2&4lW~&3MqH!Cu7jP2&;4 z)V0SNj|w)u)7MzTEM0fpu~{pca_eq%iMDj9TQCESy4Lec_DPMc?@y5@=*4!~PoDR( z9CXlx8$-;Zo5ReInur4{-WX+;+$9=g%%pe4nISbvM^;L(q%PB#7EF3sPh*Bzy6&_? z^IYQ@!PK{Bna!_s(wt}S=@FU>4!hpQi-O7T=oKuvyX4U9YrHI&y7p@06~U%=4m9>L zOV?d=XJB|H^rkJ_%nay;a>;-`O4SxUHm=Hwn-OcyT7Ku9dQ1GeCL?``Ad}A{JXV& zyZ!S{jK9du*(>Ph`JZyf@A`iDCoO%~`VRkm{J}m!yU&Y%=JW|}NDcjU`jcHEJ;itN z_ejr4mfX?L=RfzZ-~D~^e|IK+iufmzHFfP@)8VfXoc|!d!kE#|*_u*2dntYbC+<^D zpXX0-Lu%+x72RW(`8(+o+>jc2$Dic$;h&h?@b@^|mi-ywm-C++>eywzoj$=0so~fC zuJ<_G=JfOV^FQ?0&G}CY|D?0uyZrkH|25E=^7DU9!N33f!9G2@foA@zXK(Olq+i|N z^&V&2qzmNF{Xg}t-~D|$|3u`^X`-b+Uw^WnFzIgo8B70GIJ2ZD<$p_l_xqf0mhZ{7 z{PUAOFL{&n{m8!$I5*|z{y8#Q`up2IKVSd+e3}1t(VvFDw0{%e{~k`b^yllJe?N7fl>Axq&+jkt z=YolUlclGnPTua^l%M~<^5?HV*k?;W8JhX8hP}a`$^N@SpQBlNiaY#0(sPm}cl_6z z?{v~gZ|BcRmfZ2Xe)sn&{hCbto+jNb-6Q|WpFi!Skv;|foMg$JbnowepYzSX_BX2k zmOKBh@Bi06E%~Q#;wSm9>G_fB7V{e=_F3$C|(U{`EibcMCZG zLH;a?*`L2esm*^^w|=|*^G=Mv$j#X+=+D}J${oM!`{AFo^j+&a`scKNKA(U7`^?|@ z-)H{$`TFPQ>+k&e`cM6R^>_b1?fiH236uUlZ?w{%=;*(rf3g1+{nhQ#8+8}Su5>5; z-*)4BlHVY=@_Ti+>1=&Z|7=FDu*>|NDcq2e%E`PZPWb>@lX0c^{(IjeLDX{ zvL^qWCR+ZJ_s{3YKY?HQ{Qg^ho&T<%pI`fF)BO}0J^lUfPvP%q{MU;&{P(Zl|Lf#z zt8|I(=SzB{?%!nD<^O*F{_p!&z9ZfB(w%?bdw=Z;-T(Da_uo#WUkRt3e3|sLZ0g$o zOP}w5>(7Pm-*T&;FZoyA>c83j`V;*3So3#Z{NMlnV88p)Z8Y=WZR`#HO!gl79L>^G z+~Mz$o|7!O$J zC3n)jzx#d8H~-r29RDqM{$1byuYFqbPoeocApJCHmj1osj`Y1cv!o~G@9=lO&-rHg z9^EJV-*V^Q_5J_ar=|N8Cwl3ByZ`xorQf}+KS${^)BXAWzxC(h@BX>7{)DBURQ=De zLFk`9|73px{pa^zt3P$|KVM0om;4hg|2rYIQm6ZOP?i6?u! znOuXX(?WaBdq%Z%KAR(XKkw^No{`V9=7MU>sn>f^wRyQW^{NI=mxQ*@ds(%3zUsZA zNZ!x)4tV==4W6!v?RC(?x!-#Oki6WR?|A!FOXr(fatn}qUYc&_Xx_hfX zYAzXH^L^70&(9_E>kQHq_-5uBIL-FWLhmV1&cyZt-yGJ=RgF0n`sS&2;>jXkVXnc` ze4$%%-C^GThGG9rq z!P6?ST@6||m-^NKV!U~SuT-^kUaKYR0NLcDX?>0wJLuPq>S=>)R*gB8`?jdo@XA#K zr>#O;;oGKKJn!&rSHyU4g=*lmQ*3vE7S5Hv-GCTxuJTo?md<-LWWR4OAUy3;bYhFw zSCwnuzzC(bRZ>|O{o)2qCjqeB`G#&FD1=QH%^VO)9&d0T+77?7>J{O{J zlN*qLk0y^LJxM6fr*g*6jehS$0$=^C3981N!oHAdjW>l=1E+}4#(h!M;yK}qDPp`g zt{ONc#Wn?6IA?rmK#Vu{_%f=c^Jxt^=Q{%kPiGZ1w@A}@<@JE+f@bdZT?E8@UoU9! zd`Uz4e3t>C>8kGvpvIm7U!Q8}d`(NPBZ5=E?*^jgraQiVKzO=oNpB%~&&Ts^WlZdx zT68aU1N&qD7hP|m~^1^zj#nX4LeD)i4&?ZlHs{=!^? zr};v=$iG0fbY7Sv##`yv#p+3eEK!X)75kT}*6@l|1E*y|TjF1?T0F1xuTW&-y=DHA zT!W`oV!Il&a4z+)0mOLo27jq)>AY4;)&a7~Pt*DwHFnUi8`aYW*{m9KD)(Klc z22NXrw!*(nwRqm)->!)9-U`*gX{Xrk0xg^?{ks7%-dyFcR4twNXvlv5UO;%-r|85M zufHnS;OT(a9t16%tNn)nG2dJbT09@tkQ)CHKxjJVKMJU^$LFt6EuD{RNi8Bcx&1Cg z;U+gA0Y6P1OL~$}o=@crVq!cwyDRDI&CSe^j-2PWWSr81Id% z22M$_O@S898GjlOg0Wsg#3tBv1 z(vUv?Wk6`U>c0Z0v1h>Fr&>B+(~|3m;MDKGfvCCZj=vueo^D#wTZrEC^L$$w6Fc() z1GxrIcg6NTXyH8Qe*lR2=0VWn`Jsjk`5ys7(-Z$=K+QcvpvCi3EqR6rPQ(7^h?<*5 z{KJ6o^umI^_P<0_%CCT7Y@HMsQ7xU{Xvteda2oZ$LlkZrMTDmJ7Ie)20a2bm`9C59 z?i~YUN`R)%mh=muG>`kg62sh_-8D`q&)<+SJ%EjD{>}`k`C(YuzX1gE0zdBnUnjF> zs%p$BKQK+T#vAfg1E(26TM(G3T0GAV%u>X7Z-HvyG)HXbf)>t&fq8%!Z!QWHs+P|4 zHDpm>0U$grRMgxeO^cOR1g0gLxj3*C5c7S-pvCht4JipM2ZW}Tffaxnd&&YOs-^QP zEm@5SPNji0h?<)=1WEznX{{w)hv=pN&+C<8?v$pD$}0oYX3bn4*aC?8zH-pwd8>w0 z1hxS}(~iJ)K+QcBpvCh}E!l+#PL+Y(h?<+K0+oR9w8w((59~!$%KLy}Z1o1JR7>Xr zT5=E(oT>wd5QUqn5uxd@1+57jL6qlXfuqPU_xb`gfbewOlGYMRvpe7-2HxyOG!Wp~ zV{4pbhSZ!=*2D#qg5F$%C%@PRK?~<_AOwi{<}hgS9MO;5cXue>PdIJ{`g>Uaggr-Xtv@dWO zQJ${`t{}tQI}qptgr{qk^g5w5_Xlne18%+(=toq_H*Jku#JCrbn%lsFHyHDj;D9o+ z^IepnbsrI&1_KWeh0hHlLeoPFIuv+>D9=vpdT@lKw>Eh+@QxVfuI$@J3FY~{jWHJZKn$t*6!=Ii ze8(7}Jb$(|zA%F~4X;==a9Sp`CBfyY#q-MG3PmQ~TNW(IHF#Pj zwyQx4=hEOBK#VtU2$rgr&TF+~9Uz;6G_B83V+Z}ZQ9W&t&8jh{^57QL8eX|-;Ivg} zD}vipi{~A|?TQ%htxye|c8cvT(89SgxEm1T%~iol)zW#7hU^dS1%#)4icW0t2CH%n zo(_oZLD0gvI(P^W^Uc+u#q(hesR z2-4)Sq$dgG`Bcs@Hqx(t^#+3kRbx)!U`Vxw7gi0NB0?JvMpcXFL@=g^@!q&<;FJ{G z6lmd`38n!t-rN(+sFu#BHRN3I3?Mw6Rn*)fP3M)@1Evd_xi@$b5c7S#pvChg4e1MB z285=o!7G3odj^7is-^QaExC>ePW{0fh?<-31p5Ku>82&Uh3LH?&$pE^u`{n}AlKmO zuGroOEu05~4*)UWJP2AmKh%(+;3Gh2dJ=pLsJUkdw0M51CC?DSX*l>CQFGHsa2ODt zURcoA!Iy|i`4upXt&^HYR7>YKTJjbVoJNE15QUpY5uxe51sw~1K$PcC!H>v*d&dBo z(nQl|OZtUSn#Y4*iD7Qe?iweQ=WocE-h_>8{>}`k`C(XjdD;K_Pm^(n@pUq5rmDuA z@|&iq)_5{sHE^0Cv;|EwRg34@O|uj+-dms=IL#5;xuAt}VbeT7j5ilG6{?ob^EG5q z(*i(vTBxYGMVb~XuLw*_G;?v&Qb5f26@wPf%QU2BT;8+=5c7TIpvCi64XJ3_ z1_(_%nzjRK?x_GRo_A`=E<|vuY}$>exv8qD5)hvDSkV1Vdl8lLK42JIy-iiBrSkzT zIfw{O)lG*Gg`27oq3N&%t!X-fD9^{5jv~X{>uah3gs0<{w3bks-AyiH;LUDC15G@8 zY>ku5keXA<%3Toh8V#EKVjBc4oWo5aK+HFXL5t^zhQynqfY6j^iUDfwiGvo;Ni9hs zf>Wj`ji|Y)rzrynPp2*Dxu!FSO8G1>;8xvy9{4?IzF?7hn=T>>-``Vp1#OlIiWu)LPz{{si0xd^!nrUs4-n(cMWI5~(s{my zED9|Egr|jynp>o4vGR(*v_vx(hn50jzONXxcwVL3l#- z4kCh6b?6YHa8orRG#$2}HK8Mj@_a0G6dC4TU#JEUo{n46T0&`dhg`(Ko85>8LOgqH zjg!ofnp4U$FOVj`^1NUQYUXe#1c>>*Flg}{(U5p33J6V!Pz+FWPaL#(PHIUC5u7ri zG@|CFo=^r5o=#iPbD=YcO8G1>;8xvy9{4?IzF?7hLl+T+Z|_Bfrb`yIFLW7Ep09?k zAj8}{5b6Vjr)!q^=J~U& z@r4<@84rDB7Q7_8d7K$i^Nm>3o2iv;z6+Mz{V+}AZ-C7cmrV-ifoU?BO+FR0aL#X@ z28ikBgBH&-G^C(;CLlD;Zk`3Gxu*cMc%Gvra}mL*uz4P$=BA?NLO^($Z$TF|FF;hv z3xNT*>gL73FGBMYi&Wga6jAv0Vnk?KWPZ#49%M@QhD!rNR02u}wr=|Mti zu5La=47|CTP@WIl7&XmDh#@t{nvW6--r;MmK~&1eZH-!H@W$QjVivu`O^iUZ)OZ|O zCk0FHP5~2Mq?`T9pAz<>IcSl>%^^gMw`boGMuet_1&udH5#>42976`&8%Knuq$N!e zN^_<;O$@lXr#XYDluz3j=bFzDLvGF@3twTC&ZFmgNV;H?dz&v31Mli3l;=w}Mql$~ zVo1%^<}1X4cMLT5Au8o-w#Id4@TR}{2D9)bcbfZ&AvZT2S+|&VuUYPHBNN|bmF}YF z21vSZlLwn00AqR>KA%m4g!25*#u#dTL=35U()^fM=J%YvV~9|mpV}JFn8BOj=I6}9 zmy9$I6GLuZIIvzfzhsuKdqqrom0f;Ao*!ZPt%GK?`5m+9=22!y&3gydSn~&F$=#>s zkI4L27=M4+JjM*E`RvI0B3M#4-uzWC;U_k6*|=cI-8aYPchS_fKPK#nzx#uKP7Y68 zJMqt{xnz9J4^KlpKbOp}Ge}bqo|$XlG&?*Cy{AAq6MGB7b67K1HRe!|PpiasHE7{n8eRj4@#YQTQq|IVt(L3vvL~wG4 zU5LU>Za@NInmm^DB%wT?${EH+`qi)AV343{%qbiWsn+nqs)18PXyf6iYVn*1#}qN% z8&?gSl46?zEu1sqG$6*Cd%_vj()qN8oC}`;gr~ELnp>plyz+X$bU`!shA#qQzONUw zc)p||ec{W1&~!C?1yEzpK)6q}biSq~*Ac;~KYRmGbJLx0KOj8aw4}EXy%*;BwlXGm z=Cusu8a&+<+xwt}^I-S^Am*C~L5t^y8Zs1q1PDz}!jAzp_Y8p+&rh}F86r3hho2*A zZW;*>1H#h_3;H_z5>Y9?0*0}5Qp<>H>HJ1Z-Xen2X!sqXaMLIvG`+W=W8n{o^86|M z5gBmr7$8$xX!>kPzYt3Ec=#(Z%+1+dBG#@ETL znW`Fd%5RybTI0!l)xc?n&=$1JR4txox6D$+cyEDf;50{U=Ykf_g)Q>{G2UF%Qm9%w z&)1MeEeinQX`!O#7HL|nydp3y(agmyO93(8R}5M_FVm2cmgRuZw6bLdpvIoEmJ-#{ zd6kx|Mg*tQmNkf)n>MtR0>aZ;OS%rxO)WgHSBAM$nl>u03{0Cfb9u`aK+N}*gBH(Q zHKd|t8z408XxR>^xu*iOc;2ZcyAZ*tvSl}-=BBEaN_t?{`+#9=^|n;0 zmd*#Xt5w5H_Gg{r0V zd<|I?SpW!63l%lDNYi5F6@h7qW-g8_1;l(`F=+9;OhZZ{%K@QjWn=}Q#-6fBiE8P* zN=sHFf>UW^4Wj0z4Utkncv@>o*CDzo!t;7%m^-Cuqw>nYv{^HkN45ZBzONj#c;2cZ z6_IU#(6l469Z+*m1!(cSQ%iOsf>UK=H=^dIsz@auJngZd`y+c1mGVAd7+bxOD%H~Y zfR-FY1gGlAAw=P(YD8!{Y(Z-xM-b)tSmY=&%)P!y4In%nx1_a%((I17h=Dh|5e-Cm z_ShOHnISc&lx1EZO@8Hh!4%ZY;YbJ&^L=5^;yI!r@kkU9ni7#1pyr-9Xz`rXk`y91 zWg=-r%}qU#3?Mw6wxH)CXAqV0Szy4ey7@ftd(eErBK1ZtA`0K$iwI4ZENEZkGNL?R zja)&7xpyGa2MABsEa`PZY3`5QAO_rgC(@6olyBM^w}^2sA~m;xW!#Y0I-puQ-_?@) zh~P9Bd4MR~G>8aI4=w0W2HZP@2u)8d=`%uU9*#UG2HZRn8AepfFKmq0 zk(b1fn^(v(ub9+20tioUEa_W9X&#NdBL?0)N+{3oZH%$V2VzLgr^rWQ;XB3jFfj zybu_0t8QKl{30|ju}HWfrugbvdFuuWVg`40CT;YY8Act+J%638lHT zbqz7#<_)c-h)Q{_t+9?6n_8u2J+R;nx_Kk;%h0^pB9*spK@`5d91)tfTF{EtZHV%` zqjftn;NA*EXxeE>cM(c+W$SKYz|B>ym554tkBzavbuTgGW*@T5E4-~$fbev{k{%?K z=IYi%#K4=Y3FY~)jZxEjgcwqDto10d;2pl!8bqah+}5aN25;Q0E@sh7+{6g9N{z>n zbyBe8?i4WLMaDcS>QzQ|_M-%?AR;)0TSJJ#=fa546tST3)+nMpCt733fP3SJ(3G^K zDMD$^w5EvxH}|w=5S8+28{=H-8DhxIS!CfWtkQY(Tn|YXY;tewMPlGxy@c|7$;Rkw zy-Wg~e9hLl&J5o4x87hDzT{48KQZLyrX%YXv+lLZ-ECyzo2=4Z z@Z6N>07>_4@?h%&Vwk(KZyO|(=Z7}NQ0pUNNX?Vh$Hc;S3=zunQ(NO1Gk7!H`kYz# zl9AS7V#v)42iEJ>m(0?2uZT&nvdeGC^CK+3bNXX22L}CwjerFwRoN#ou!EJ-U8LYX^z;=1udKlqw@eU-dq$dR4tw7 zYsjML0zi0LsHnL`nieas2uw>fb8&PjAm;muL5t^Q8d4Hn4hT&vqbmS4_LN0SR7>Yo zTCy4uoJyl>5H&Y#h?WAv(^^Zq4$)0fp4ThG+$l{Pl~)F)&6>G9x&;vPedVCV^HvS1 zh;9RfrXA7kfSP+MK#S*{TCxifoGPQc5j8heMJoZ}X^#cnAKi45>M#Eb{_s@+;2^rl4jHM?-*^?+b$#&k+rYN27qyl!(RvHTT3pi|3@4q!7U= z6HOy(Zt96<0O9Gh1w9u%gQ%3x0t0T<&F6vNgXRkssW*BNQTX;=L}hls29} z+Ztb(!JF~uS7yOWvYW@5AvNEKHNA~m+2*@o$=wgr%>KX1fLnF*V&E5{d5J|TZd-~de0wn>G%d5BC2h+Q<#}b>3S^jj%i2l+;c1m6T}>#> zrEP170XJ`GD@9bwYi*5n#Msm(HS2)|Z_v#ffnSE^%@(P=Z409C?d6EjwAF%Ev~5F_ z=N)a^kpcHsAVSklOS+3tnk(CO69aCpYO6$4%6n{#{cU@RAvgPwWnSTJs{(|l1D5n4 zp)^;w9U=zaTums?hi#0Swj;!lnqzH8i3RWQwbdXh<>R(SEi-uIZgVk=gh*FjI<3C zLvCI;uwJ*lWR|XbMNE1X%u`|`$j;_Btf5c5Wd?6X+ukvYzGsvfQuE${HP-flS#tNO z?ISbkU1Q9Un$N_V9-~&a`65_SH{SMDF!5#C_l*md+*MC9Wge=q-H&^;0?NYBk;@6yxAg^$F?8}-(HRg zOoX|9azCI;MG6{|#4%6n{#{jt5okehwTGOzH) zssQ2XfF(UhD9zQeL&U(Fs|n@#u#Hg@J3`6R)eUNkJ}ox%;1eX=3*AT z#7&GqOlmxitdoKzcc*{}FVf9^;Cs;=v`FDt2vPX}6EQSoYH;xER zNlTg{l;%t`yY2K9A zJ^%<$cP;6CLTMh1Js<|&JV+?d4{eO0*dt;{&6C(;V&OZ62<7>yt?`T*ycv!?XBNI> zBsNS8xq0EhdL4VoEM51CnDDAe?IVav`HijdmKnSmjlE+Qy=0UbQuE${H5U88EV=s> z`^Zds*BCLTv`furN7fg?lDhHOSHZ-WW$zdlEV=u}%<1ji%y!>JQ`i20_Rs$U@bmBe z?eJDOPgZ0~JP*xNEmD5_G(?RzX5W#I2u(9AXhHi-M0uXwJ_{LeZvi4S&9S6&38lHP zeI7C3=A!mOM5R36##q$8fEaSK5Lx&NtF#zBS47ehn_S$!lo)tdF`+y!voT8AmlH#3 zR<^Go7QCaZy#!Gyud+2(GlMs!?Q58YFWJyuN({MK>&RNitWE85w;q}JCabg&Jy%B3 zW}95zzJ(ZgS2>|PZ?!Qh+P4uyYId}5Cl54!+8Vouo)SW@S1cL^rH%+0JoyWDvknudsx2Upy_SD$Sk_Kml;xX$${0^ewkTvceVWrGx1#m?R~_Mn`@4&>w+b9 z{p~jdlU{bGy`NdS?xth&mSEm%*R{8aO>eZzcggbuEZ=v~47NXD7Tr9^45@kOz#3|Q z#4Ndc(*78k|BB=9FPn#$AvI4OSW15&3nu);vX_mt4>L>Gy>Mv0ZhtA5`t}vG z`ISzZH|#wlLi5&PH`@MAF!>#$f+ctF9hzh99|Tj^ero?H*!<2h!IHbrj?FKkDYxV8 zUqxHGbX+ub?YCdDziVuL|6}5biT}SJ;GdJ@6Sq(Nb80RbU-RSB5YNvg^Xm-K6vSud z8aU04&qD7hP|n2Og7_TP%vFs!6~^bOcH+sRcww%=(|n;_6kniPIxox-j2plr)hnT8awFMjp}KGY*vjqmB+WJ*6_+z1E;M*TM^%;T0HNFZ&$>4Z-r{$ zv{P(%ffmk{@!fzJZ?1}0s+P`sG-Q8#FCaYaQ*>gBH(r%%@N__I4}uoX)$v1sm~XBI zEuIf+NKO0*AT%9|9|hFd1E-|era%klOgs&U@#da*MzwT4 zts&>)X8_^ptfJ-?X*#dG9xz?d%)Rl8fSB*=1udR0X-HrEG9WZvjb8!O*fS9CQ!SmZ zX~}g&aO#iWK-AoHC*BVTPd6>;Eky6ddA_ZTiJf_gfn0;9yJCAEv~V7bKLEsh^B`#P z{7^%N;*S8K=}G)Cpyr+-(Bk>2mOMiQr{VZ>M9obj@nJxCdSO9d$6q2U+)JB+WBSu<5N=9Hh9rds34eAU2dhR_xyW~vs? zvlFuvG2UCC8aT}n+qs~Hb75j0AjX@E5{0Uz^L!0ilvn@=PYV?_w@A}sIAyi7M67`GA%jLs8GR(ccL=7N39k-;lgwpIzxQKx_yAcf}c=p&DCz&BNr<9euAn7$4H2K9g2wFIY z6Cps%H-|xs=ZJ>H6H!2DN+e={ntS4)#dA_iQi$M`Nu&`qH}xbkfbewMf}Ts9K~&0T zfdRMb=JUYsLGuNR)SI}7D13V_A~apHpnZwUi1K_jaRnLX-ho6PAUs{Oq}K_hxj%7( z7;y8QL_eZZzG-XRBF4Rh)Z7M^al@qKfNJS{S4-|Ag41B)0itlzAR;t9w4g(YM~L$L zB=Hy-aPJTzG(EMX&j_V?IPshqaPvrF7*Q#|urXdIUJ^rYULgx#VWug`5#VLh8y0z-fli79?k?7SFSjvlKDj zTc8>^%@NzVpoMc`avmVYn~Rc#s-^RM4Ox_200>VD6*ad=(_-ZnfoX|mE>125#C%^d zXz{#ELrRj%0ikJSas{Bqp0Z?#YU#X6OI9O-Q)zMyqUNRz$x=XgT5CzyA-XBa^Lk~N zJEdu(^2)%pSu>X>w*X?kuN<^^-l`!L$!&npv?IA4P;*ZOXz{#LOLifGQ)O~DqUNTm zWF;Ux?XjTylY0@B@;+b~TfNCD)zbNZmK;O`r|RS(MB%1tL})r}L2Hsn5asz;@+dOQ zy}o1(AUqwnq_u?7>`uCffj7Gm4J3K?*cvC9AvLFzWnLgne&u<=6x7V&WC#%RePPhz zIiex)WE2pZ63G~#=AJlc@to9>6e2ifl4(TEO+CpBAUvJ6py!fj5S8*-V8E@q`8@D@ z(0sun^(HSO3g6y~2u+tPXkYR&qC8(sUO|SrcOcmZ2v656>2*SB?oZwz2Hbon*^j7{ zZ`vBSh;c6|HMfCf+>qBXpjtZL)sp*&;53+gfGFHFhzLy&E$C445u!XlNj^pf+&hE_ zO;0W9GeT(|PCh3F+&q#TMpVi#Y>d~*m&A~pSI9E2nA9->2v2V;>03f+9!}5EyW)Ze9%hA~Y|tNW~pX5ruCrMueti7PO>e zIiftT>{x*eb8lHk2_QVJvZSjCrMa|Y4Kd*64IQP3N_nlVv5pv>e7-U>u$+G$C55lVAq$8KW4%~c(hh)Q{n zjj_LDFEQk1AF|9Vyd715@N~eE9we0J>W)Liz?-WH<@vCUQPXjR7*cbr<0!G<9lnkl zM5TP()~IC$Z`>U&X3Zeor=!GDB+KJFvz&J}^t}K6QL#Cj3OQca1SaYCb!%z6h4ojdy$%On%w8 zV9DJ#$L4p@)U`hh+xXi*`8qjeTy1=vsv2|3Pfb&;;pM9aPBVnIAT?99c%Ge_rHJv~ z0@c82j@ZrxEu0He^8hj4T$CzQEuH6U$fDE&KzLfHsJTU&7Avm^OiMI#acU_b=KG34 zi|1t;Qj%H@2u&+fD*!e2l%+~kOXpQuvKkSbN>ghPH8*WYl>)-kT1&bP(M>6y*DJ%^ zDNP%dR|cldnz=l+1rYOn<)Fp$Rt>30Z3Bd+9jWbrntLihi|3tMvI`NMDpR`=H8)kI zDgohXj|JVI+KZ@^_W{G$>P=Otmd*#X3xgKV z5ePck);pwymJ(oIzsFcqF18&vL=YijY z<_i|7H+2zF`1W2zXu4!U`%;$?<@svr3Np;S1F1ehc)DguuMM=6l-XTP2 zdTL3Z5lZuL>Nzps=8@DeqEdcgW4uniB!=9)LY8^Oq|OmQczR<=-x5mmXzCp?@a9oM zd46wWjHNyhLux*yJ`xMxF^1@rPM$y88ef>foAK0FX2DCco5z_UHQ$Iey^~tm=DT3Y z-4D|={^r+dUS>{{#da!a;hf(&4G{A!`Jlz~3=JvhoCyd`vpZ)2YVIijEuQCS$y`Km zD(swxsJW@Avk(xT=3CH3oeL0^@m zys~ozGR(bYoh5+qw91mMCY0vV&NakTcpA}Zyzw#GVQZ0eMn^}vER=;n>UFGKTY zi&WmZ1yT6+aztp_YC$VHw;{^&j?V4KfO{(tp=qZj-9;$Pm7TkZ0XJ85Rw63pJvPSv z&b`Etn|;VKukdzO0m9P(OL~w{nyWhx5d&|oCY0yHHbzb75n@QqvCgB!f_L~jYY>(4 zaa*I78N6|Kx|l^TaT6oZDK#EP)=9yVyHmha7p1*sOJ={81QEe0+!;a?ZVDqpQ^bPC zJEMs5oal@p1MZC@LQ~R`rU<1u)0rj)+}zWdK~&18ZH#lBXNVy;XOV@kuuA9Ab3G(o zu*toh7m0y)^%BbSB^#r!^D;4{=4$5^V!=BGI{Ofn@-w!F{lt)) zn~tno%(~Ypcejyg-ZUva00>WaE$MwiX&&r+Kn%QjkWii<+89HfkBA{PPdXnH3*RwB zD9=xAjc3f@&2Z;)X5mXlI){lNH!mDmuRC8dOV_<3CcO&gDd`bpXY(7@&?nw9gEym{ z@0dm3Gs+C9dGEj)>-@khx%<@lk(u9vqVcHXa|Ig&5b9bU?ve-@qEu8by(*QBwmk(Mz&(M&9^h`i#nw_2nsJW*A zw0NGQC36wMsW3ecQFBvKx)2ba=3CH3=>>>Nc_A?1R^7Z9_(f=5Vv&l|OA&={FGhr> zWfrs~y&O@VSEg4W!`xezE&+t6RhD!$p){AK*AN44-jFUuRLW~@jdjG>l$M(Hz=AjE z=8eEFL-S^fRG!{~D13W4A~bEapcUzDi1NH6y&V~FZv`SW?X;x32&K6)y_*}bk=fgHeP5KBiq~=)qD6!xj zzH|+uQa)~L)G~uN?zD?p^b$8Q0%@u7II>O(mfW2JCcH>D`+@I8bI>A%(;-CR+rx;^ z6tST3bQDpZ6X_T-;NCbQG$k!*icp#}=`=Cm=ALv0Q7NCcG0vsW5JPUxA`4$(mCmE* zdPurplY7$_iGg?Z63X)>8>26MnHW-YHGPFx@Q#6WAEHveW@}t$25{hV3&l9BW0M*Qn9?ORpB-6W1WW41(_aM>UzWXNT(IQs8#AYO zaWmU}7foIJ1KQ?)0q8Pros`K#^JJ8uH5Cz@^1G%X3ZKhIgr*r5w4iGyqCC&;nuQFw zw*V2E=2+6XgwkBtHIEo@b5U0zqEeo3V=U@gKn%HAh%9`CRa%UmDY%2bsZ}>aIh~qL)-NLuw8?uxh%F zFiY-^bsc3UzRTBDLkzh&?#QYYEU9yMxdfA6=4Mu)OYS_5&6A?3Yfm8?Uuc#5;JGOo zFG)e09PSDc!`zj9TbNLuBQ{37D@qKhNp!`Ch3|+H%5&1zNHK#qnXWXm@FhK68DhxI zX$RK1t~1Qib!Ul5ud>VM$@4udUvSX$c3or^-Q3Fzsk!99>g&49EV;Ydb%mMuu7R#T zV#v)kN7i-0lDht`8-htMyVKRrEM0fgv3W}{?{(?g+r*|f+U2|C`2m*iJ7@;G9w2La z2EQkp2bm!?4;@%TU5}V0cTc(=GZTIy*}I0AAvI4OSV~_X3nsm6q-&U2y6%NT z^L5ut!PK{}n9Z+r(!62s84;Sd4!hB=cY?|97!@qJd+*R3>-r#=y7p7oM`HggL%;8A zGbUJa_t~-eMKtAhyz8rI<4<(r(s9w$wcmcp{;sk0{SV^_w zKzLfHsJTU&7Avm^OiMI#ab_tX=KG34i|1t;Qj%E?2u&+9D*!e2lx0d(OXpQuvKkSb zN;7K^H8*X@lmf!jT1&bP(M=hi*DJ%^DNP%dR|cldnz=l)1rYOn<)Fp$Rt>4hYy*U* z9hvQbntLihi|3tMvI`NMDl@wgH8)jdDgohXj|JVI*^8)@_W{G$>djQCmd*#X3xgKV5ed9mP;pwymJ(oFysFcqF18&vL=YijY<_i|7H**nD`1W2zXu4!U`!bgi<@svn3Np;S z1DQTRc)DguuM_p)zbN{mfS}Kr@_nv zMB%1EL}+?wL5DJr5aszv<}oth-XTP2dTL3Z5lZuL<~cFo=8?=WqEdcgW4zA1B!=9) zLY8^Or0x+wczR<=-x5mmXyzR;@a9oMd46wWjAcF$Lux){J`xMxF^1@rZk|8e8ef>f zoAJz7X2DCco5z_UHQ$Iey_;Iu=DT3Y-4D|={^r+hUS>{{#da!a;hf(+4G{A!`Jlz~ z3=Jvho(Tv|v%6;jYVIijEuQCS$y`KmD(s$zsJW@AyATkb=3CH3-3t(v@Tcq zA}Zyzw#GVQZ0eSp^}vER=;n>UFGKTYi&Wmd1yT6+aztp_YC$Wyw;{^&j_&QqfO{(t zp=qZj-9;$PmEF6E0XJ85S0XCqJvPSv?!Cm2n|;VKukdzP0m9P(OL~w{nyb4H5d&|o zCY0yHHbzbN5n@QqvF@Y9f_M13YY>(4aa*I78N6|KyO>2UaT6oZEj1oT)=9yVyHmha z7oGN+Et&mV5<~>2aCZn%xG9VXO%V$k?~WqMbD}$j47fLr2u(>#nj)0uOm~_XaC1+0 z22m-WwlU6ipCN|aoJAJC!YZ9d&-IXW!6x^1UnB&)OyfA!*OJ~Rl;*+i z2gJae2MOi*p^Y)r{fHP+^Q8MRvG5&3g!25<)_BGY-VAp?XBNI>qhz#@(o+j-!sFPGK8DBEljok=J?r&rA) zjq{asLiu@)p~2k!hW4yB=E1 zxm6p$pf7K!%4MyVH+mYIz}Qx$kJ- zGViI{%?$c(0c$Yrb#3=Si@C6BKN$4oqN+mHYWaYNak%Or7&3(T&~i{ zIVOt)Oy z+t6aJthxgRec4}C$yzN}c^H8z9~e5RWfouImV)e_A5w!y4plXQ!QTo&D|4%d5vdA; zp^>ht4zTEsp{fXLwH);{dW0cKyecLvzT|#Y91NWdSXl{SJ*?8%J!U$a(yE6@Bhv%d z_7Sw0hpQfg!CxMRR^}%j#z@suFf{VK>KRyk#|X4Czwk6(3PY07s#n6|OU9~3!O+QT z3+r9g8)2E)TQKRWY1Lz_)$)5!%EL<`!42^uUuqLWL3rlBTtG);mcTIpX zqgo^1tgP>frLoDXABxGBC3j3Jmd<_(b9S{flkAsjn&@w8PyGhKmsXwH3g_v@W+rQR zO0S;9TKe^L)?k|B(q>f8Wv$HftLHI;zMH`sObcAwh0tQotX>2LeL1T-leJo2>|rdc zUIKf|pi|)v)&S9;V*LfQ2 zg&|39^#)<_C0nXKZ-W!~#)>=TA0h1L6o#g`OS7lNUa0~Xfd>Vv{Eu|r_eRb|yhtkv=n zPvfXCBq^>wCM;Z1EDVhtx3Eg8PY6qAr>aj1lkd7%T>^$qPFq=L6iZ{J)n^q`E-Mw* zFjf4u(cFk@e`CT=2I$8ZgwY8;_s%fG>|H=Mku+99pbHn-Vk8+ys zbN(*QX(plcobH=N8pls3l%MAqnhf7u(qNkJn@3vboeV7C9Ku*Qex0oP3Psr&tm5lE-Bl$lC|{f*{s2|%B9Wmt!AyvYkg~&;k=vY z%OQs;IQ&|=Q@Z2*J5yv3KxS}kw%G&X^;&8Lyg#QJZ8Kdmy&m-mM%=dH$OJ8O8# z_w8UUeJP(cn0C6f1-@OZm3fbEH#6wF1+2le*R|aTE#^YselY0EMZQATYWaYNaoBed z44oWemb0SFS40|_j<~i*p~YP6I|c@SxfoiRk9!y;z7t?*FfeA=_1ql67kE}`HD*__g!Tz{dzfTFkN$LD}2{k zEAvg?4Q9}HD_Dc+mTP+(TFjNcJ7Cb4{k}@pYPrh82>5(p=%kiee1%&IvU`3=4IVk< zYXXD66@pggRu3cM3xlDNE?);&bjOe{!dfjyJ&hh=ND}wOgvFQK_r<}`$$*uW5Y|JV z&h9bO*_2i@L>ieMxVDd=#XRhL3iZ&0+%*Blj2ex6v$DP`mc}N1KNOQMOYWFdES>!n=Ik12CfP65G|}JGPX65g z-_IOrHGj5F^QZavdAhNg$r_&0Yi6;Qem$KvnC7^&88vfREA#xCdCZ{iX0Qg+0@rpS zw3st%7J)%u&Z@~|t(F&i7|UvwfT5G6%;GED(sFh$3(^XYoL#dL4E|O&v@);qFmh^E zgQ1bNHEY14JMwCBSgYlAp2m7%NRnH#L0EjrmYQ5Jbh6RP+9a%PH9FhOOuor2ZDsfJ zAZ_=^`87Mh;BVzaEAvhdqo8IN7#i7Avl}eFqX1f&_j(%pgds^`&3<9=B}FxbVCdw4 zg>|^*ps-Br5SVmTSxpgZwS2_WI4TTDiffJu3zrlNLnFs6tdg1&!qVBPnv=rhyDrw0 zfT5GqR@NEC(pYKDS;dsgN`-Z~MrY@&&GV{hq8FG=7S@*0Mx;xw?G43Q(@`sdCfCn z;;s>4Xyk>J^-{4kHd^yaF>%>g&8V3Mppnc+`k=b0`ky>=FBr@ol{MmlRS&2ecn zYUi?6=J~brm_gsoU=5}PuI)l-F=y5;0)xJsRh!9LEid*kmeno+Lnlj_#aFncu~KsVVT$=FzKqY+9K9!`G}`+R2Y&J*B%oVE-4m< zMvhxpCABAnrL$ADCxyv(U92quLno)LtTT$GvC`VJiYb?s3hQ#M&dynz=T*~0FEE=g zbW4}my)sBwJaT#MRWSHl<!%1YMSUz#hzWK*-84#V4L}Ge&g?Nfd2d4P90y*({$H%CbXE->t+#S zwm%J0x@Vr_VPw?J1w$kA>*j&w{4JBKGN6@tfv2%h7?NbxEfN-Al2w-phE5h+Sj*~` z2+PElf{ClV@^ZMJCGrXjl3lk_Som_bFf_8t!pf;zEi9d_ty?2ZzALXT2MnF8v$EDJ zmd0}HHYg@8+ftV+EEC&kZEjM`ZFMHP8Eo9>mAAtEJdw9sko>wG!orvHg`tt17FI#s zE@A0xPu*@|;;sT=Xk@RIwNJ4$R#>-RF>zT@U7@f{?0}_txbC20n&}~7^Oa?FMPTUU zh?R9zu{2g(cT6$mvSP*3*>Ov=r0#@bn&_#zlZuTyFV>X^%fwDwn`cy0r=@jgRa;wH zs+gDSO!VA8+2;+mnO}e#xY#RSg8OA6U$G$NbytOjFP95LBiAgfin{B<(%H?r8_fKl zpa1=mxk4Bkxn*VDRxFKG*4Vw!2Ku;oe{5)|L@E2P1a zh3c9VQ|<^Umd;u&%}8BXF-^3qu0yeL=TKclSSA*=HhWZ4r}4U&YRjef>*9)OrUUK%s#gsdS6-#GNEX|R+r;2H!&+DEkw%j?QSUP)Q zZN5}ZosQPMQf;|(tZq~>&Ghv@*zfAzsJ0t_3pf6sAOG(vNyZdQXYZ}e52~rt@w$(y z&HsJ>EFD)(6aDlL_C(!h)i(35bzjsQ+U^O}G|_MWWPdl(Br4kNoF!|DV6fpZ}csH%K4WivGEo<j%|CzPIZ{ToP=_V>$M{JANL z=Z(f@6KS^jF>U_aru}^b|J<6oJ=JVa5$BZe-;ttIUVe(u(@upJ_;;l!KkxDHPBm$N z7Z#)lJ?&NLK0@ia(7&HFX@9?52E#ezZz4@v z>dPTQ`MK55MEqgWVCwRBkT&h_J460RisCtHY2w7}3`!cPxW`iM|^9`-*bO61%4;s4B9nZNqKFe8n;J3*Qm0ZiXq+wag~p7j3!BQ5oE@~uf|W&X*G*#T}O z^Dkj&>48}(I_0OQ2tCbFXhvXeit_XPz`Rs5_1%mVp{E5Z zT}UWBX9gCLX6nmXfy@-e^I}7@EU<($GA&KD&MVq!dCJQorxk{Cc3>rGobP25%Fn9| zO-^7nX)vt~tRd~xJ9&Ye6vgv8W3!$$Jmm&9u-18LOCXmtGHrBiH?ekGK<3RU!+BFX zZB2Q3JQW9yv6jA6%o4$Dg$>|>%8O-RFX!fDwj48@Ud3Q zwZx#Wn$AJu``Nj{C4~Y_tfgNMu?ADCOB)Gmv$uZl(jNH z4?JTAeRqU4m|nQHFQLUe8h8Z;eR(V}%33YI_AuTB-hiQ#x6I-zoHQdiM!aNt51G3k zpv62M_y`8SKMt+TpFE6-z-KTt@-^@UEWTp`TA9BwV|I`m$^2ayl1v7E2#YRBerHk` z8u@8u{ZcHQ{hl)a{M;9uS~d0ObU|jOh;vF0&Pvg#o9QV+PjeKS5uBT%{5(H6FV#$a zHzP&pX@N=?5=zgR!9}E*`f^qxgK1B2H))-B3JB%ry~buAYj`RQ z?q{v@Qc+Mae5DnVb;pr73^S!^X^bELK>N(u5Ayr znB&1181&`)!8mKRJm6_0z<3zc$US0BZAhyhN>MyNFgA}^!_#o^F>C2d!>qyd#HAex zK4q=U&x6mHLEjx=4W<{a?MrAej|N|XL0=vVjT#Lr^q6)q{e zekE(^*RxrJX_ZTxQ@@(EGOw*)!wl!$y!sr{$h6M2T@Nkh-1-e*(3iK==dxDI8$FFp zU~H?`$Yx^E4W{!};^(pRc9)c2zk{{(>-ns~w9}<6sNcm}nfKK1W(Iw?fHj!*y0-hE z#avjw9}N0(QGFq6wS2(CI9z`a44oWemb0R)zKAq39dT`sLW{Y${umhi+tS@1$mQQ;cXM`b1Y5iGY;gV7?F4t@1oRxK6v2=EUm~_$9d0InR z%1E9su|%yatl_D={wizfy>ixIy5`bW)L&<<%s1*e0|tHB zUth^uEmwIMfqEYpI;mwAU*VR5?4BP|gGUb4H-W+53PCG#tA`P(4}+nRuKEtJ=#HWK z2y3+*^)z~fAxXSGCM>?>etjGaoeWr631K~~*V#R0@=b2(0l7D$VF=PAk33xe7!2pF zF;f2&42?Xme+CxcF#@g3FFcKx!jNRN{*|!!lCk7R>Ay&F*Mu-M^3BTn zu2>qItpA~ya@nL}>FlSq`AaoT^!JoK_0vE6IlWw3kjv?%!Wmznfh{8LuQKNd9k5c*06*$GA&KD&MVq! zdCJQorxk{CcEd{2IN!@Al%H1_nw*B!q`|bdVGU`g-pOmoNl`qnGdAm4!&7d<2G%++ zZE46QjZ7O|+fA(9)*$odl;OOoowlaDJaXD@IOjL)AdU0Ad_wtor=clm*hLyldm46= z)_JFZP=4NPZ1%B+r^1H)taV;0YA7U)Ob1-r!wm;ntK~z)n0mFWp(sW1e8kusWerco z4aZnZUn*t|rsFPcNy7=&%6zKfBr}|MFE*5rMyAuQ?HOn>mo}UQgTGwL+RF_xpYt@% z3qvCpQkJtoJ6%e7W#n|la4v7SN*d>T<%II{HA7R;aGf-mZZ_N?t@BO=q5OQy*xY6f zPn8XKSnIsxZ>S`VOjRyzpuxvlE!Pr*zG^xLiSK9U2A33SXksn>dWbccT3y;mLzuNP zcQte{!+Ce8Awn9NqONTZw3y=!F)--M_Z#A@)$)L+kpSaigGTNVYidJU<4}s?`GK){ z#2TK48y>TkzBJ4lOix_ek%p(NmHBzYGiK0tM_7aDg=_l~TFj#jufU)$k2Q?4R?DwF zjCT!hz|hHCW;rXSHI9)+ruVMx2WT;mH+%$xzdR1D%%41riH6T$Xyj|d7qIw_3D(YN zl=+*d@m&~_Og8)w7G08jc~Te}`3ctSMzoUTmtyJcw_{HIH_jui^G*h#{Jg-}EMyH&nT?BB>%5fJm`NI$7Q3{|8kewE z%S(wtUp1YV6F-ZcSGc6?#+9t4U(aR@rd2L&PUC9U%DlF54Kti~^BQwVBhxz9c0IJ1 za~n5+L0{g|n9Eu%Z}c=afw8SoBb$juH<->_iJ!;L+g(zA;||u+ujjJ{(@vMRpm7&# zW!}@cn;G=o0@h&K>)P&v7IR_aelY0EMU925)$#!k<8b3aFm!T=Su`c$KyErE=C_y5`bWG+t+|%r_fvFoV8Z!5U1r zT-)2wVy?>eq$UAoeWr631K~K)Y&~|I-9074UtBs z2d?cSXfY2rJ_duoJPfVOPdto~#;0IttJkncoY7H$DhMlJUlm!ou&23qvEHEUbyf&%)B#*Tyfx z#9b4@(8xEiW;dagB;OTFW0Q?P6q7GYes5B-boSHQ{H2;E`rEPp{QMtEYx=vBou;dF zCZY74-ZYCe&iB#@<>xtuCZlOCX)w)innzmaoeV!-WIn{I$EV|=jQweLeeA?4EBMeDOo6ZUg zmz08Wxk)4EtgQ2jrLzmfq>D`FOT;f@=PNF$yy+@y>DS9ygXx+}ThVl#wKCsqy1@+k zZUt*F-EwVjLyNhx=?)n5Wq(s8YqebEVFa3dVCbZlS$u_C3bK2CNDUr2)YJq9e=7v7 z%&i_qq$v!BM!K3hz@j^bnj);#a@5o45r!o3rkJq!lKV|@Fmy6tWhI35ut{h4nCWav zYaSwvOb=Y!N6=y(Zh8y`e|Z>MnV)zVBTY}i(8%+qXJGLiBhbqH!qa#u3`s_tUI~jY z8EYB^Lnp5-tanXsgk@rH!KACEHIK1Y%kMpn55kaSyy>H`aLKqZH1f&9nrQkgES-IA z`XWr+H37zqW{rHavc4;p#wMG7C?;Q)+%c(GI{PWi+0D{SvR|rcqQ9x_{05+TYU{L6 z8aq#CiCQyR!&7?mEY{L{>8!yt$ED3^p37R9=Qqz|27Nb!HJBE-whN)foY}kx4El0b zb0%xGyx7B7*1QA^oh)S*U*VRPvwK;PR(Ry>=9OUZx3Zy?d6kEe)4UoCjjU~60~Xzp z*PO#zEwA%5)(bSu`yO#%PyGPD%-T?-G zD<4{!cX}8F&AY(R$e!liVDTLV(8|2m)7U2rNeY|y3yUu)YAysrCkHI7!_5bUWnzcG zq^ruBi&(4WBc8@lVMtQkd`wulq*xdlIc{NJi!bpvSAwCFDhn&n>=TxW)q;tuymAok`$cZB zAfe_aVd2XmVQ8e)!iqG9g{8Bu<_=-*rjQSoY`poSV#*!k zilwtpmgYqBXT>zpugzb;{$B|H-bpf{SUUS=ZGKlxolZ9YP;LG%`e*5+YMSWJf3klW zY%~8obz|yxKk(=D(A3{y>d%=e;+)b$vr=@*OHUDcnxoK+(A*T|=lP*|sb=cC87V?f z3skz0P!iVSGjxNr&N~%^^7AcYbDK3hRfg`c)_KVvsw9m}RW5BH0?C?h$KhLt4vFisJc!v3bNAo`yq@Sxa9UW(}q%F6~I@DQjhZ z9(u+M`tAs8FuibXUqXv{H1rA#`tn$4l(kxZ?P0tNy#YffZ<*z+nAS2z8kyd^wjZFy zJRbT827h@RTA4q27!#q-U})rP=nGhU#{_F%5ae zC_gVSHVaw9Q)bH|);cd`wPcb;ro}GpvX&*R)$&qe&{s|8<;2fo=M^p~yJaP7>DRMa zgK3pZo71wIwKA`5S;GwH-Mp3@(#W*VwOtP_=G>MIV9=MhwB)i@%Nsq7O<-(m(a2_E z(G8~aR^sQe^LCe%-?D?X^y~So!L-w*Eoj-rTABB>>}Cdiw}3U6_PVzFpv7F+vL6ik za#2emYqfm9!#Lb>5Dc9hVwSU_tfh!FG97Vkk3x&NxaAla{N-Y3Wj^j)ZmdrElptXw?fd$-0EROTEbvxq^qR^EV^T;CBj-QM?H-mVMr2h zi3y7@x!)28Lni}PRzg@0TXc4hna-wZtwW@d>49te2wKd;Esw$AFAqa2^Aitaq~$3X z8hPIG3@pB51X`J2cp5K-A<1aVD`D{^V=bd#=;XD9^{(ZOuuSYNn7E4O8LeZ?PUiQ5 z;EfN$kYv2&qp$dHh-z6iT-x%sh|H_ot@5Ux=LpfO3&%7vqi4ryds=i07^7ISXv1~BN$TUv8jtL2TJ#wIYf zwQ6KDvFHZVc`Nbr*m=84%5UAlTKe^T)?nJ{(iXJtVy(=3T6Z&pzFWW=OnY71eb8bq zY~2qAeYvQ$khNMq;9(qYJqU(Q4l&DFQPx^S8kvr`wnw4GT-S07$!(eEntF;3xx?`v{!dfjyJ&hh= zND^<235zee-x>!)Cj(YiLRb%5b#{-L&Ze}sA=1e7z_on@E#~3Y$6)Z6hoP1EiH9-L z`V%%i5NJp_8S|;w#+Ja&|8Z(h859 z-L?`8{#G`$GOzM5a@tmdp^>$1YrvvA^4fA(tL1f`#(H5$lH0aHSbWKrwp=iDveC-g zB&=<1I@`=lzR4|ZW%u$RZTHCeZ9Bl=Z{THTM=uue8kf@Dhx@A+l~nfmlO*_BgZYQ zlC~4V(%GrDlfvY?F1D3`p_9{A))~dpSZUi?#gxlRg>|`2XXmWV^Qvj07nsc#I%!(C zjCjd(2{L!DK#RG&?J5}jemS%t1DCsh_!pv@;N6RQOiS9#?i-1m#zU_nA{O~S&LL&DHVtA!P53kyqUU2Pr07;6!=+A$$e;I5u|Lxpxe*2@GriY!si*uSuC_Sf#XOYJ7(+TD0 zIff=9JeM?>=7;Bz)_Es`P<~!uY!Pb(_)u)S$GL+wY-!V^i|V& zIq|dDd4)^L4zFY_{dzWQFs*WFbHb}xEA!g$8fG}}=7n=eBhxz9c0IJ1bHf|Jpf7I; z=dxDI8$FFpU~CI(WHYho2Ge;f@$=YuyGzOs?_e$cdOm9~?R04i!n;^2^Pcc-X3%#F zSc7S=Yr79x%!T3oV9=L~!iB8W@&OOyaQGk?IyuBFXGK}Kh%_=Cacz%6i@7*_3=IBq zF|;xt_b^JrC&19isqjg#=#Gow64q+@w5M@K7?PBR&k75dl!9?NtdVn8)_KL!*#%VzRFtq^>Wr=y5`bWgs-z!=9}Rg%%Ja9um;mD*Y-BFm@C6~z@RVt z!2>Za$NiDPZ3bzzw_xz9=JaQ=91O|UA1g*@i9!4Y_216rV;SR9qj-hab zwOWpP8a=|0Bp!|li!Zq!j)S3-0V^vZtcPKp-D9S+DXo2oG%`JKZ6864c{uzS4F2*k zv@$>OFh;^p!O+O_@H4RZjuB{Oe&K1n6ow?D;a9@qOUA;ZVCdwvh4n7{Mp!2H7EHQo zTKgDlwfx@G_#g~P#={?lg-gbTp^;A()5^-E1zODI?N`CzFPB3r^ED5nqWwA;8oAki11!Fy0$Q1Gc^bEcAxUNX z9bxe${`N{RbW&wu1=@YWGO=1Pag|pN!hOHU4HhKS-Xtu1IV22?v|3n^_OP&Y*45r2 zOulQVJpzVKqE=RqVreYi9#c$QcE3F?EE5~BHWP~Zu-!!OflW6~>lk9KmLGT;kAxw~ zaQkCn;gVrtXyl27HPZf6SUP*&{!Ey-YeX0td0}O}R4k2+w!czLTsGD|Dl8LwZE3!1 zf1{XY`c~L-B_}gF#^6qpyjPgK_d&5VHs1bGG3EEh6-#HIEX|4b&x&cHU)#SZw%j?P zSUUSA%-J2%OtSB)snf~!AF7Q@li!_GO%wh3Pxdc^ZRWq}4d?ei9aGDvMbg-LI!n}= z$r_&0J7%$#-b-f8LYvyz_ncnE#}OQMPSgEvpO)@pg3 zr?FlblH_)55Efsur6U&%oouwSHVJE6ht4)LlW%fMTiLxlNZUPfe#Z_l_*?nV%DmIV zDCpP)hDP>u>;{YPD1cVxy`IKCVMtQgv0qqxNl`~37&0(Aha_^So-B=mlo;g>LB*yH^J3ibpQ*xC#b;s~lRHuXz|19oNCo$jy!$VDTLl z(8_$v)3_}RNh&+;2#YWAcT|F*lPU`<(BTu7iPeIMtGsd$?)ybrAz^5w z)xwH&goUNEu8t02@?Aq65ioQTwX%8?OJnhlm}26x`yFv%nb?4}nNZA!9VU7YY`QV6 zbBMKCe&A_55{4wh9gl^DONND^ktY_`NXJuQ>FjyOGhyPc5n*WLg_ZSEu{1W?@k%jq z*;vP@uuSZ=rTMPojbfVVTVeB+(>lk%(8+r%>w{uxY`o*6V#;OXilwtpmgYpqXT>zp zuN_|$Tkf0?){IV_eX};dtENsTJASA(E={hQR8158so1kSH9JXv8EiBE&2Rku4bXqT z_37m6d74hz8Id$dGd*&8=PWRsuP48j4z0{{JdBLaxnO8ye&;-}_>K%{WnSQEEEI+$ znVpM-#g}AtW`d!U#TM4G&LzS!v87<*DzCg8?q`X-!h&RXt`ru&oGlEEtg^6jI#&xz zXKOpx2$S#1>&yW|C+n=N^@^pj+|CV(iOaTh<_gQiHd>pT6mwgriEaiPH+to*a6eDv z?G_}zbBD0-<$PgiWT%By(78)kI@{B^TbQ`3Ko}a?Yh~?IER7X*?pI7)R@7N2EE79m zX&&x8sF-GYNZ5R3S!WR#Iyqux9aSui6?Yy}Ou4LBv2=Fa(k$sbp_nFms`I2`gjZP|O}dt)m5@DFsn^P_5OtHxE+L_ht5J<<7Dwaxr%=NI*cwtGS~P4wG8+20Me ziBER^Fx=3WPa149|M|~1ei?7LHNU5BP5pPj;LquislUx|8M*6@@Y*}z)o zr7e+M(#W*YwcW(pZ4sF_rwr#!?X)%J<&o2N!#O{)gEY?f@(JbVorb0$vWqmB_C$7* z)_JFZP=4NPZ1%B+r^3j7);cd0MG8qH(*c+EaO5CswS0&eQ?Hgqic%EMM~ux;*6>su zImTN0QZZ{V9d~IgckE?pYqk8^!*~~Y z1BOoCGRs*pt!s=lGQD?gKR}ClJn|6?{_;4qGJoi)OBzh`yXKMBc_)KVeqLZ~7P5w?%&tYObzaKq$|Q|Ui(T4fT}xQ2<)y@+ zubR%wiJ!&JD_l}`*GksXuV=Fc(<+xXr)xE9WnSC0h8fPgd0jcAk!hW4yB=E1xm_E; zpf7Lf%4MyVH+mYIz}VKMkEuZ!@&Im)2(yp_@!X>3(T<+4yIVS08>!eD5m ztE&Snx?`v-!dfjyJ&hh=ND}Xg35zee-xUW#Cj(YiLRb&Gbas!K&ZcS6A=1e7z_on@ zE#~2_$6)Z6hoP1EiH9-L^%M+^Jnwo27T+-ft;{bxjhDiZWVGv*u=tX(u2C>_^4h|B z*Y!qNCiWIgTt)MY=oqt;`Mn@`71skbS9znoF1J; z8s{tNg!1zoLz5AmOBzh`qw`4XypusFKQAyg3t7WcW^@s2otLtrnWT|vu}ixwx`ee_ zUP=u5s_DF(_*v|{!X;%#SF)CVJ)1R{R=Kn}(bcS#d2MtJGn{wxqB*3IX`O4k9$L(~ z(G6hGm$yW7S*zuZp2j9Hwna6vnOJm#>AaQrdF;I1CFMtVu$F#3pEa0vy0it+U96RP zPjojk=(`21!L--4-3Kk^!svc5=*vaXLe^^efQNB7dJqhq9AcKUqAXfO8kvr`wnw4G zTpT?H27kF2TA7b~7$wmYU})r2^dwkx$Hiy~YqfmZ(>NmxNlK$!MGgN$T=(P zykhC>0x{_#)AsfODd0EWi9=BIcqRob7?E0*I6s`&FBqg(040XgXxxQdmCEJ zmC-w3(3kzuO4e$*%EJgmePHOMmRWp-TMDv!en<@-ITURIgTEDmR_0a@BN7dRp^>g= z2Uv8+P&C3?Ek`|#9$`olkH&<>m)wuW!O+Qom6Z_I!>G>gG1J+U);&ZTnI5>dkD$do z9DNK1e|Z>MnV)zVBhjZ|XykeH8CZPB2(&W4@HAcuLz2pX^u;q(LI;7GSBax#|-*z25T@aaBUYti#fA<5g7F4tnN(KYI(7Tv8;Ou7&=+X zEWW}mEob+#Ag%Do+1)F_;BRF^EAuK3Bd2>c7#dmIy#_40BdCOd1CmXG-O~TsNt+UO{tc5a7&Lz2qwJHp~i{N0sc=%mWR3UvE~Wn#5p;wrBkg!_Jx8!SkuyGdC1a!42&X|=E- z-C<$rtgE|2n0(hzcLWTbM6IkI#nM>3JEoYp?0$D#SSB`LZ6*}+VYi9i0~MifN)> zyT2$l|MyDnoKP&CeX};dtENsTyML&*wscZ8P4wqK*}n|7ng4cfIKTZ-PSbmwzl(F4 zNhm$1_sk-VCnLxwJVwt63}a+MYGcaNf=9$svtQ z>s;IQ&|=Q**#HK8c}q_&Yqh-5)7S*YwjPaaCKlabI&UR@9y@P$N%=iHSWCa2&l*fS zUD|@4U96RPPtR^<(02=1gK4j8yAN8-g+2Shpf4Bo6tY&!2Rw|!JqN+i$suMrE6RF` zNF&n`*Y+s1n2URkfx%xchF0d|9!5#e2{1Hrs^=tFbjQV>64q+@w5M@K7?PCsoD~)> zDFx$lk4DZ}S?3i?XBUV`7n#nNh+oFeS6otg&sEmaua~n1(>0g2qUSnmWxm;SgBkSQ z3f5q{<=Wnc7IS6K9Wdz2{+>$KYPrh82=w^C&`B+`_zJfaWcU1#8a#5SrwI)HRtQ>| zTRn_OPZ$i1boF$AMRyGKL|CiksHf2*3`ycWF=6o~_j}@C=w!gkN(k#=kIwEf)7g~P zJ470p9=NuTpv64g^B4^N@-VbAKk+a|dY*!zk>@?nz~Vbbpq2TBr}0u4l8pAe5*A-F z)-wu*PF`DB?|R+{%f#M-Nmotl9b>JQ-+LM#gdxdz&qrb5l5t^Z|F!~eL1T)leJo2 z>|reHT>^$qmNJX4a7)YCy(~y8JaTsLN-+3a+0e?o%EQR%T@8jt*7mLei|)wl&0(#U z*LfQ2g&|39?*?JKZ-W!~#)>=TA0g}wWQ#g`QI7J{LZ0~Xfd-h;w2u|r_eRb{0<99o&Lc^DPF*TK-p&E6Ye z@f{V=%6!YyxGfAxDtqq;i!br_R)V3EDhn&n>l2oV)q;tuymAok`$cZBAfetSVd2Xm zVQ8e)!iw~Ug{8Bu-VR~%T|>PQFmw{NvU(ItWAWaYV&byVfg*nqW}P|SzDCVCHS zx^Y@;h_zaN;AuP(h9twikA;OxhJ~S#Cl=O7?^9vv?0N4qVdAb4VQA!qmGx4wG&b7% zN-=TSSnsH?OzgF#`L6ekVw&k&Vat`A%!rM_og{g$FnRBTVrgu=_oHIU?~N;#&OTY1 z6TP1m(?q}aeo<_>b3(Cn_Dz_xW715r@2aWO$=)BTjZ2f?om5Q|{rOM!FN1C7zv+#s z-~YtZVyWeDo^EVrvWBPh*eur4ucxyH(;SyJBQ}?{GS83AV+MUUgEg2IxV8(S#he*i z1O|OME0)PxEid*kmc^EUp_8S|;w#+Ja&|8Z(h8599a{+oe=8eWnOAujIkDAXXk=|{ z4OnzXUMz>TT3+XAtQUqPxv>qx;!C!~a>3BaMk{NRu(ri?wwalHlUv%#?&U$+?ve9j zJHX&?-+V+Vz0 zVu!$_tIA?Utkv=nPvfXCBq@#^6BaHh7KTQSTUaHr6T;Hjsn|(j@?95WC1B{}w3T&6 zu{2g1JFA#-S*frt$8>hi+B~nCCVGL{e4$&q#O{?ry5f<`V^_i8ZVX`)|aUld#JoDkNGKAnBDHovQ;PA6kOR2!EjS52y>iT+gV*?pRwq`wTdng8ZD z=x>1fob}V z%)Uj!;!CpnGQrTvVhd|o-x6V&*itZYl~-O4_p?M^VL`I{RtgJW&K8D7R#{j%eXE6~ zv$cI|gvod1_2qz}lXX_sdd1RMZr=vQ#ARFha)o7L8?DVvin*=NL^p$t8@=*YxSuET zb_0S0YU;GK@2qNTOG_2=a-WHw`zQOn!8Y>?a03^6TaC z?~AFnTzbDRu9#*z@K1I^wIBAG`8{z%Znhy0#CL`i^2m}6_dN!4b{xN#B*TiOvnQ73 zNZ(V%G|}gM&lH>gdnI>{D3;D%Seq|ZQ>UYSuT)zu9qSuaOf!A`5B9shH>&N%-zqn> z)wb-t^1U&YefS4D-uF?pwN>M)X`-M0!Jg>*tlDP&weO3#@xQqI_ein{)ilv>|73qR z*d{*N_rq`l|Hc0-pETHJ{_~%2{4(BfYkoVooZtN^r|EI$Z|0n45=zhM@mZvC{B%P3 zd5)pUh|eVrrup%Cq;=lOAe5gM7@LKx;VCn|h_%j3S@BHL$h6p{T^3)$S}iXn27T3Z zUQYZhc3$CEV@)P&v7IR^IKN$4oqIe-|wS2(CI2=C+hE5JK%UMwtFCvXhM_k*Z&|)r*9|MEG zTnw$u$32Xa_z5sHaw>ijEV|=jyo9w{KJ96o5r!nC@w39hC8c0oj%(zcm33aRbasK5 zbdl+NiTGvge8nY|$FH)Me!ZMEn6A0B74hq=mHB4;1~cfp6|BK@%eB1?E#}Jj9Wdz2 z{&*#8wOr+41mZq0bW+PKzQQd9**!m`29F$yH-W+53PCG#tA`PZhr!TDSG)r(x??CF zVXc;!^sC>T0Nn9dqZb6nbt z{<*A`d4B&qX3%#tSc7SSYr7Cy%$fa*z@RT@^=GnH%ZojXW&KOQ(8*F}@fB`qIlGqy zX@y75?q3N8e=8eWnOAujIsL1_(8${UHDJ*ldHp%8)$%$|W4$mW$?e}DEWTt*e=Zn0 z*=S{L64thUoo!|&-{h9IvU_=uwtM9K{vBZOxALKtd8da_(7y`|jqK^)4Hn-~0Ike> zJ&k?BkfgAGzp(g{qW(fKbaKGLI^2IySSEG|OuDM9zlgP3KH_N{6^10m{l|obONxb| zk>eItN&g99>FiYhNn!F`7yC=V(8*~l>x^P)thE2EV#;Nu!n)kAvvbzwdDS%03(O`9 z2g+z8(k0jS3bdHZ`>%q*UoMAM=4&2CMgMg$G;*{523UMY1++5X@-%J>Lz2q=JHp~i z{QZ?+=%mWR3iSJgWn#5p;wrBkg!_Jx8!Skuze!m5a!42&X|=E-{b6D0tgF96n0(hz ze*_GjM6IkI#nM>3Kc<+t?0$b-SSB`LZ6*}+VZVvq1DkG~HZa6mEkE!y9tlH|;r_?M z!X?AP(8v=DYo!0Fuyppk|Cumx*N8AQ^1{k`saP5t?SG}1xNNL{R9GhV+R}X2|3)#* z^sTVvN={}BjKQ5Gd9N^e?}K7#Y`p)YV#@E0E0)eaS(+35pB2+YzxIDoY`Jqnv2^xL zn6n3@nPlHpQ>T;tKU5o+CcitWnkM@5pX^@-+suE{8_w^42Iz8no^EVrvWBPhfmy7j zUrc8Wra3Nc#=u8LYvyz_ncnE#}ODMPSgEvj#F*tL4QW#YoUhDP=b z>;{YPD1cVxy`IKCVMtOquwPhwNzp(d7&LB*yH^J3ibpOVxC#b;s~lRHuXz|11J}XO$jyNpVDTLl(8_$v)3_}R zNh$~K2#YWA4^)DolPU`rAz^5w)xwGlgoUNE zu7M6=@?Ap%5ioQTwX%8?OJnhYm}26x`vY-dnb?4}nNZA!115S8Y`QURaEP^9e&A_5 z5{4wh1CND;ONND^ktY_`$iP!!>FoKyGhyPc5n*WLg_ZSEu{1V1@Jcap+1S9SuuSZ= zrTK2)jbfVVTVeB+(+0=D(8+r%>w{uxY<%FOV#;OXilwtpmgdC3XT>zpuLEBcTkf0? z){H@&eX};dtENsT2Y#qFE={hQR8158so1jzH9JXv8EiBE&2Kor0ZOC|lJz1@cWq}v zi#dI878v}kbZBLs<6&eB&ILmw^9SdF#dl;tEAs+RW1%o4$sAlHEWRXbFcS=&EVi(g z4K5Lui7f>aS9#^-a6e1r6&56WaHX*D{HZxX~+bh5LCTZ?_=%gFA$UFXszGBRegu zg27$F(%GKD-NM9O1;WtCUMp*#Vri^!aKB>WvZBF4VVT$gOY`vHLB%xFL&D}O%La?U z(8&=i>!@OBta$L4V#;O3ilwvTmS)M|3B@$gQ-dcJ8+TqDED@H8owhd5sHRR!2hXau zwzO0+FAtjNxqq_H8*DSb05@+IvpK+rP^}o*x;yQn(6C*u-^^7QEfN=R=J_Awq@^??~SSK!#~jR!H>e8 zosi#6vT@Zk(NF(iPYixmZ8QHm_(i>e|C-6&6RK&V-~P$|Zm>;!a`1=YhQ55#V4L~R zf4=d{c*Cvv{eQQnrKS1PB5D8kzXVL35~lNX*$n-6H!<^1qo(x4EY|+_^}l91YcS1m zX)_XYSu6AW#5`uucQaUnX@P6I5L(QciA7-0m$MR?tkv>j4`W$k2^czA$}GOZEiGsF zvLLPS$k~aNVDPuHp_O@+hmn(54TeV6Cf0yOcjP5Pf z^IhVNVw&k&Ve^&K?v8<>llNBE2gTCZc;cgC%4OqT-OAF7Q@ldC3G(?owN_UyZwout1EwweFtHux3(I$3OCExWr!SSGd=1bhl7gCU(Hm zJbd?{Vw&k8Ve^$`cZql*@`0OJ~O|&62w(6w^dc-94$;xbx!O z5@DIxX>0S0YU;G~?pf8=mX<2!<+~<&?w{=Q2HVUpzzw$eUKwwde96{6?d--OJ_Il-Vi44st|@oZdqBk6-#54ckd`BF7x00|D3#SNR(aMhHW2| zMD$ohNJOtighYfzghYgW5E2m<5fTv=5fTv=5fTyhK}bYcL`XzfL`XzfL`Zb$%s7tY zIF2*pIF92uju9adVG$t_@xF6k*UY(&HBu7C8rL)@U7XLY!kfr-b+@&XGn|35xp%4L3F zVHPkn!~X<S=NY_QXFaXxs5LxPex4 zHm4&aZf4m>NYU+2(8P4|pU==n-<^b}j((YeJ@wC5XzTg+f4;#RX!jH}b@T_Y=XW4G zOMhx?9iRT^m*$3Cp8fu`#@6%SGrsXhd&92zOK<)6`@jGF7OsQ-EHurwZRfI<=faM8 ziZS0+z*3=OUf^I9bu45CB8xi~G0XZXv#W|&EAtXZW2rDCDehP%EV`tmqnH_(EH|)L zb*vDUj;&-SU*(inv->3?uQ4E{9czWfUoI5}BI^vSvX1q_!fa#524T`&6&+>Fz+{t= zwHa85m3M3bCSSIrqg+@zw$<3&2FzU@I=Y?Ne4|s|$?jK(yxV|OcI*)rf4Nc^i0n16 zsyg-w3$p_q`-RDORS5%;gGSaNU?EoBaTu6w$T_Lq{*o$iA$x_52FE!52H_YwUi5$Tti~W5-Ql@s}HgfygZbtEuC*urRyZaYvYZ zSCcRhxo2eE2Nq(@9S?xXm$h^>3roiy8k$c!9syHN9}8QqG$BvLcUk~>X2@DQo&!_v zXayE#FAUALj+emH(bpZXfX#QhI@*M#V{eSjx6s72z2hCUv#zV*U;vFy%5ourLc4n&FNhFm*K25dyZ{83q<+QDZX(O-vIV zacIk>nT`Z7^)xvHd!i!+Z9AR@H~8vVof%>2*hgdY6ErcM?D!0Av~&`hI{IY>_Eg7L zXzTg+j&JY=+C2r#Ih{KCV@CE*jjiL;9lta;iMM^-?*&3Vb@#{x8zS?LavGL zGyrnLkTrJR1g6~42rSHQ8JbOAw7K&EwB^#4&Sqfh z>BAY=PdXn#+m1hGH~t?N|L;|nv;YgUr^eOq9?#^~-+wu1^zVShGqpQ=d=>WIT&tS?t z;Cn8}yfdKwP9L<wLp`T{RCp$lDZs3iR8e7l5%<#rk=U2@QyXJf6 zH_a{lb4+P$J^wM|8$Y!-^v!hVFYPVePcp5&Vb}cr|8?t+%`N-x@4q+y_gmk8f0BRy zbGA!ObN@@ZKMP&+NMHD0vi@AaNReyde?&bkb}b^`Dat$lzFy>7BFNG_u};OVWqJDV z%@SAfe}tZv1G>t!B2W2w<$q1?tNhQ^`J1_BO`ce%QrFr%&3UDHqMp_PTIO1xr}Vth zwISd9``rpx*?)wdHbJ^sq3XHZwMA)iU*6#=&r^Qhs%^F@%`O*D+y85GZ}2~N=5Obk z-Faf2DqVZ>H0M?3iF(=#Xq9VUp3?IH*ZzEy`)*a9sHcOF9#W`!u67+(n%tLbT-ABX z&qp-Pao16$k?B~z{r8mySIvKfo=!k|QlaX()^$p0tS{Fpl%7v(nmX4RrQzwE>#Wk| z-nr_k%TsJ5TBPuIo;|$$hsePt?;rNbf6DJvX}^C{6CmEw1J~<>!Z*=85Z( z(#Z5U-&(Jr)6=}yqMV*-&aJNJN@IPmRiX6!LesRlUMdYwuU)T{HusLp)t0CH{6^cn zB@IpOu6LxhUUIwIl}4ubw(SSfcDZEk$Q%E@S>Sg4N9f4|saK)u+3)fxjrC=}Lg_i6 zX~M3c((n{5EM}<@!omnZLWf5kq}Ct~}*ukGAoW zh9SXIdDD{5G=w01LCfIkRBa|M$QATj0s9%KbT8khytcoeDkk z@-%m|Fi+Ie0zivA3-gqo7kd`vo7{Jc@oiT7XT8$!w9&IcX>;#Xc*^pWpEqfn z&7`5J+_QzW)=N7)Tl-m6efyEW%Z&mN_*zE`PGdfuyP zsyzFYhNlCb{Yq=SQ>9RPKB#RDk%p#f&tcM9FV%Rel}4r`HtliGQPQG(Ofhn=Hh60C zl%G#%o0FuWsn&CfwCYQ>q~YnbOOdSlzZWi8L`o_EYpUv_)iNsID(N8Oy3@VyPQ+=begQLC(8vQf1d3 z(yCvtBn?k{ZQ81?eWaE7K-Yd^sP9&hhNpwJ?IG6kT-|k;8S2Y5UDc#T`G|vYyz3}4 zFgZpnYehp>jnc?;!nQrhTApjWPBDYNT+3RSPdgZOU1ykq$hoew%u;t;?W!X!%I6)8 z3&N13zU!i}_>y{NT<=2Ul96>8SeRW=Om$K2Jj>gVH?rqzB&pU7($Lh{b(6H}y++dT zbjzk~>bgx@neTSpA%^;H6KQz5XWQOqEziwe51668+|t!dT9h9;7*Dz$F$0sw#G)(g z(o=G;g{5Z>xwY##Gw55btd;qNgVEOYk{O7+?s~;6b%(2~jkGAgaWvivLz4Eccfz7e z++FR=z~sG=^+8x&U6^$clWww09_8K~uZtzGL-u$1m|?w@{hFV(G6x)ta95BSh(x+V z%%VHOtd%+HXvBmeNunz*EV?Aqm0$)YNds%5D^gs{fx+;49H~HXJXCw z((h#Rq%aWqVqi^meH9jF-@CpEQ~evs?wS$?B0r3*pTI(Fy6YD(<+5pDVfNeD`~yuL z{hPCM|N3Wt&i3Y3=l-0VC)TOZJ1Jumhy$~U?17UhY0S_0`( zg{tRb?=q#yeYwP2oTvP}T+^)bu2348R_0sl6?9si_ezx08qK-XyH;te@0BW)p4Vxb zGVgk&;c26HgVN^SsqmKNDL-%0Hk(O9Q@M8wX|0!bc*~VWrmeQ^Hq!3$%Dg>qSZ|`! z&b(KloOWx@mEJu{V|}kuq4d00(^Pr)DGg5ty!(~bdZ$XE^n6g;93l-()!xITwO*?6 zRx6E6M{L^T-lL>N`IutlUTyH!X`8mrdxo?!pYxt2 zhV|}MZ=KS}bl$eTz*?T`y%(85U#=(Zb+62q9F5DuK;%l^vKFAzwY=A$oNj2&jozC| zV|}ktq4a!9(=>T+D-BO~y?2z>dZ$UD^n6d-+$Rl9&E5y3wO(rRHY<%x4{h2f-bbWG z`LSZCuj5HZwu!=&LUYTL$G%X7jTXNLN6#+x85%1H-f!kc0SCTU_>D`s_Plt!kHw(Td@ z@;vGN%nbVSBx_~<;$Td9zcK@n@7{0BqC2KYJEvRbACAUPVMsFV{Ut1QN%rMwVIcCG zS@XNOl_h_Gh1p-r%>B!++gfIwWt0VGI%wM-VlB_r z-G`Z>zFgB?OpsgYb;s52I?|$i-qE-q3`y#{FA9q zn;WE|sj>SeY1Nk+NyF1Eo3^R@Hfd$P+kJ-^>bp&(;pv`jd!MyDH+Mf^hWc_#cQa{G ze&}F4>3+lvOdb=9uCPl_$-Neqo;l>!?&r*)Z?&>k<`)h|TlY(5Ao9BV6|>YGuI@I{ zqWs3ucqIl^u%^1d3JbIE-QR@CcTEWcksr*O@8edM`~((a z)7`&-Ntb26Hw`SzejA&ApsAyOE&Jbp|N9Gk|Lr8F*^tgvsCq8+%~KlddxZ+6=LMRk z$hS~wcv|dRq_oyMMGB?oCE8{wX=p0;EhDYikl_`x(n{3<7tmV1fw}lz%%R7AK zq(ynFqp^({yL^ajS1fgd?z~g+E691bO{(eUPwW7gSqck#|ux(GWmgidEDQ3`@ zYgsGvX$PaucZL~=ob#P!mb&Arua2}RpLaAa2t$&3-$h~ZCH2g>?nC5~k#!kZm|am! zb&>9TP4OGZ`G!qu^xY(_`t?TA@N~??*TK^ zms@`m!6V)Ei65A$gRHT%%E?zvR3974n~{rB{L9t?R&*6 zb%)E>Mp~5LI2vz-AxXRMov`QeFi9F%6TXzNbS%wG zb=9n%3~5pR=xBTrh9r}|&%)wMCWV2>7Xxd`_f=S!efND6Cf_y1j5$4s{4lb90t>Ne z-!EX&W!W9mz{2deFz5G3Gt2%!Q%C=*w)Go;p4`@1{sMBIO_FNOB@Io5J@ZJb-YX;x zPYZ0?qMn7Mm3eW`B4ViT7LkUhCARHS*7983vy2()%OyRzRSb#-0t#Qg>AJl#v$YO^(K9VMtQmvqe~R z$&Q|KW?-__$l4~XT|Jm>Cnnuwmv)kS6)f#`$dx^Nm_gsFWUb759gM1;eat}QK+k?= z(H&K+mHD8faYz`FRQDVf7F|-)Q_T!aju=?SdyWcA$Br>mUDeQ2Lt2ziI2tE~AxUk| zDPi#?wZcH;w1HLEb4FO0o$EO(OuFl8PaQKbId5cL02X5PJr{u~m(>gFdJkrojLpl? z)X^)%rVH)THRawMe*;T59CBmNO=ehcWxv+QTA6P-7)?F5nSsdNo;%EG2nHiWoG_aoZJQ9|UJ!U3f<&>YY`z<0rGa#)!&xOTbZWRV1FAS`< zo|nSH>~+s8VbWc$o;GG+^2W$|3oOLid)@()FLU>_3rok|8=D`1+0~b^WXL9aJ_A$km;@GPUkuHup0B{v(eFLqnEii# z{&Q!^6tFP+VQl_{CZ^Lpzo1S3M*m$p4NV>WJtO;%#@6${xf{9P{jfi0`*S}-?$5b- zVx0>8^YS$373PV0S^#K~e_@`|^J4#^e3ScbQJ$!$C6F#vsCq8;FH@S_mrMM`dCJer zHO(sj3Z;>0WxlmuL8sMuuS7Ym(VR>DYn8_OUa3Oqd7Y*y^RHJLo;Lb7C~fYY3V&Ii z^7AHbvzatBmHW4l)_Q4&zg%f#+G^WwBkeA~%-i#Z^(H#)%zG8eX}9KF>EEL?*7qtE zO3!;WO_hJ2((rV^zh7yscd8Uh&j+>5A=1!P?LSOf>!lihwbICR#HKy&KT2AZk10m( z)dqh}p7QevZF7<|G}Zb~kyd@FmNYz_wrT79XGkmaIsaK=Snpo-*C~xm=WW{ytmV1h ze~}sV<$BUy_se|A(YP!OM6Tp5YXLf4%X4xUq=)b8n*7q6}O3$}6O_Tq&((rWG ze@AJpcbXJR&-b*=ebUg>?0-O7>!lWdv(m`)(58Lje?(f8A1j9Xs_y($@mt9GnN4c- zKPRpF^;XjG^unfX^S>mm%&+~gh+)0!^0z6COmA%4x2)y4-T#gm>dS6_J84mV?`V8r zMwcIv4#moCDCl+NDL;F(jh8eu`Tai9sxSFT!&AVf4f}(nl{w-M5kq}9Od6h|wrz~H zJSY5dW~eV`{0Y*coOCcI{3&K&k|vh5VpeZPX=M6n+kRp#&y)Vo%%Cq%vR39V4#t%K zD>D%J?*GOtx?_s8b9!a|;b{C6h9uMeU&2zCWM7^Z1|q+iHNTfzS@H*1nEkcP+`s&K zt!36}Hl%YEs-6pb=P8Z#l|qHm^8!s%)Vok=cv{@MNNKHiiWExEOSH{W($G}gyNtBf zOC`OulPx-u0xFd1LPe zVp#81^p+`&Oq*=m&8+3Qymt#T)R%YkmXj9ct&YYvX6))kWV>Ri8+7NLieEv_yKPcs z?;g^sU#}z$PkU|Js@{F1mH9yLeqyNaR*{CMgSPD<*7984dzcyO%Qd~#q(%9NgK@m~ zC^IlQMl5SZLvM}J$aKQCJ;_?0YkN;IgT7qLTA5Ef7vea;N}Rx4{|e&JxW^}b{VBCmU2F-zUy>TM$}%5NNvx5AL5z4x84=n{8t zJ2NnOZ)ANCR#z`(9mKRY%?h}bMkbGK>t!v^{$3w5=*xcA${cVo!o5LeAQI^fF^ld9 zvsUJ)qY)E^B#GX*u;`LZZ-N<^Bn_;I-juL(EX_>5O3iZu8DeMiM?v_FPr{I7viGyF z_;)6SfyfsFYpVCFurT}H`%Rd9*OV|2`N6FD0d8f{~rcJi(X4djt9@xSR_2nIba?+x_)zR3-j9mdlwkwvpL3iG% z_!Z>5+a^^8_K;TndL?Oi+H2ER1@@6v<^zHK#8BU@A`MRmZQDbv<+(a=m>KHJHGyi< zqI|@`I37643`~v@%UaP8s8Jf3PT005S<7>6;1o0H%eAbP`Lu&k7dXQVM9u}yGE3cY zHBd)dl+QaF7la{6ec+<7_>y{NTn`{}$;i44EX=Mbrn*RXzNYvMH3n{yR{eS- zX?VJ2(>4WelUC-tfjh)d-)$ldPxoxw`>f@;Iq-lP>dP&GX40bk(7|{Tc*G1$9uteM zuuD(Ly%v_9Ipo&Bb7s)DT3IXe3kRbu@RAvbybio#mb$|gXd^AkZyb%c!jPmr@J?8C zi968F3{2h|Ss#Se6~L^6nAWC(K9|zS}Rda0S6--2r>haNFc;4 zx+Bb5nWK(IOc;_R0&!u{C7D2i8JHvutcgHMSUQ$wrn+iYUxu_Oe{?iH2}6>}z-M9c zC6mHH9XvOX<%XYTbT3vq?u)Z zpsAyORXg_^fM7viek(iA);4oVLsMbjJkqLPFC-053vAk=zJ;Wfd2!z&VyN#Hk%p%w zw(U~Z@?6}vj2Y_7C4I%DMR~b{v8rzcGcZ|6EV{xjttR(MSX$$dOZ(O`gT7VDTA9~5 z7-fCynSsd0z75P$cU1J1krw4mj>cwTNK)RnMObvnj=pkcV6xT7+9s@BeVA=0Cf#J0 zc9MG)EbVs4m3@1dLEoxmt;~BJjHpLq< zy6b9R9WyXFZ)9Bn7Gm{%7lA34)eGx-A7+<~&CAf#(JREJ3#~LO*r0gXbd6=|-e4`y zjeR$nLGL%RR_0p{MpNHyW*~C6?+&x*jwaU1e9zIiFAPbV`yL33E@|m&W(Fn?4Xh`9 zkA$UTkD19=IpwG9ev8P@3`lF=b7Aq9TZMth3j?dI@1?LXd)@a+m~@w`uZPBzIVXn%iMkK!qTz##^wiLcJ=9K2ebJ`r|cp3=LB6Mdku)c&nGPPWM<8#8tV z5!tR->IU6;r{Y(T^KP3|8Qeo!_3M?S;c2f;TNT_#TA2?7_Y*^Xw~9189kgu^v6koR z;9+K{FV_UCNsICk2jh6~C^IlQMl5SZL$F3^WIAEno@6c0wZT)&pfA_5R_4 zGY~l!Jj*O~$JJmRX;D7!Xj~A6B=y0I!s1KnnQ=Xc$R#7|GO#eaqL}I;-T9j0H<0rU zo75P*Nm}*mjilk}mQC9fyiHn}?*{J>Lw&c2G(6q2ZSS*|=jPx8W~eW>1e-~V@sK_TW2V(IxI+J2NnOZ)ANCR#y{f6&Ja`m&$3G6x)t za4^UWL?Xcuv*?a6Yh{i)8Zlu=k_g6yMVDlP31(oDG_WRuDPieYnwjdVS^XK(qWsa( z_#_NTCWD`a#g|M91CcKV)>QDTurT``{3cAkYl<0j`VskIWc>sdV$;E2z@*EvJEnn! z*>7Ra@0Vtl{eh;A{#EUN|J@%h2p07Jw^f{HYn!>Gp{cNc9%#til4lKx`SqP*O}Sk=FR8JMgj7F}VNR+D=rEUj_K zrTuG}LEkE6t<38jjI#dq%s^yg{|08MJ1Y9iNQ?3&M`N=vBq{ITA}qROM}IjpFxhHk zZ4=h6e$2KLlWww0JITEYmUcVj%Kkmfpl?;OR_479MpgelW*~B)e?PP6jw;s5e9+N2 zBn(Na`wt6?E~)9SW(Fol46Nh*M}?(h$C#V>$Cb}(DrI4k5LEy^B8!z&C){QW** z@g;s?AQCXJ!u>&EVHW8R36t*%3j>j;kre|LVu}7ZF!{1fe?nL~mNYac`cuHv)3mVV zN=oL0GVD&4d<0D1`vfe+Ci_1FQ+{s}SeSh=G^hH%0#ir7_kRPn+&Kj-%zg-Sen^^G z_7j?zPWS(UHeZ_k?ld%Y^!JSHKN?%l|Ef2v-~WVi%V&iP$aywNsx_B1G!=&CkygD| zNE)6N*tA8Vg`|~vacB`S)OU+W!_yMmb}4IlE)FeYhWc_zsF<`UFLy9jg;p>Fla<7x zE9}y0a<7D?H4eEnw3Zq4ty0#?yw1TW3$14cA{#>+n5FKh2$hi*bu0NKzX* zB`m(ARv3t!Hn8eKXM}~>xzJf*(p^_WbW1a<74<8xFZKbdwqMtwz?$e9OUT3f*P~B6mY~m_>Iqu~z1Lj>dgqNYWg7 zAS}A1CDhCeOdc9oPePA`rDKno$yYh$r|f=<$j=N&Yv{SK_{*)rK;(si)fRdwEX-bq zUI~-#a)sKMfyo;q>n*SlYY)8xCST?bwF^tf-W!`AfY}w&(GF&-8w&|P(oNbmNYacLMdSC zX-x^Q%8RTd;S2jv-FR~*7Lvg#(%#7`rmJT2IzX4W-INSZ~;qm9dhBo zJZ4y5&wj0twK6YoFp35iG6Rvt1B;kNcNDQ!<|U5CQej9^Jg`hybVtFgHan7amabUU;8MyI@!-LDXNw*jdf*dr|da-}d3*=t}` z4eS#ZW(NlL3zP4v5(Xj%jjTh!Lach=FfjSDnt^Iz>DUoN^Z39~VCv~HVbhfj12xRR z2PZy1oqft$pdAEw{Q=0;&4a?8MK8n`Vi%Z#WAiOEF>N1s2W`33Jo11h(~`3HQ!lso*u!Yp8Dh6jSc)X~U5h}r)a=0A6qgn@-w z)Yyzc6Vt>%9NP46G`lo2kN~EhCTCzz45XlK$J5{jT5ZZcg70M@`!oYOIq(_UXw@V% zb@a;&?5TmT(AM+s1K;2cw0jDgI{ITq_D_wiTX+ zxj4K`X>wmK2^Z%nKQGrbtHLXkMy8ed)_Mh_Dnx-tg zUTJvR7~Y_?xpykUWqHcao3zbl($G{M-a=aIr5)jNrIBf?ZM%)MyTUSW&l}d8=(IEM zRVb(3nsa4%kJ4D*t5hgG@6|L_;eATO(}D1QrM2FvQYbwi)Ha7mLsND5FlnuqYQoh@ zBhwL^_IUUxX;D6=7`ay)!Zmry&nL9aNz%|%8$Lx^^`%<2lDDh{=yWabH7KVWnsa0LrqWp7 zYg8yb-_kTq;oC~X)7|hLrM2E^QYby&(>C`>LsN730cow5TEfjrBhy2h_DT2=X;FTx z80xFK^HardA?If{sWtqZwCdMeNyF0%o3<_dlC(0v4!@qrm#VMICuHg_GlX~X=w6?eWX=i@{@+AfK3|?2T3b) zBpf1!`fivsJVkBW7;AY>gyYOmU(SRRq(wRDU`&Kl%)lf~ENjKANJeR7`e@sJVlB^; z;m^#VFHf>o<}VJ$RQM}15cwYd#w@yHinMbgGXHQiehNd9>F_UMsY|jiPYVN)-^`jH z;Z~OX0TyO|Ei?BozlgQWI?aZ3u0qvwVPu}tSYIhrC_OLGG)0kxO2gCQ$Ree+-YHTj zJulHVOG!ghaby{3t(Qt7#Y!X7a+`KlWCdwaUa1)BtGe@Q#V;Y}H8!a!*Goym z(>j~BEV7=oGH;A*AcpmBMWjq=WZGogZe}gd<&iDSP+#5=DJLz;TOEyU%-9t{WV>Ri z8+7NLieEv_yKPcsWDjZ8uUC?Wr@c09Rb(G&Wj+wuPYm_lD$?+D(6&9qTAr&Thnb4a^2lC?b7Mouwiv%*|zst%X4$&0W;K>TO!S*MfstF@g(wy z8JIjK7F}VNo|1blEIo6`t&!)zZq@5XF+j?2cvp?cv27TGjTA2e5MmQ2= z1|pG2h*@+;n6)xT9gUbUBuPZ#!lFwukpwd^Ng7xak(97>EX_>5O3ibk8DeMiM?v_F zPr{I7GV)ni{5zAvK;(;oH5K_PEX=+~z6q1>ni2*gKbSQ?%B?K<2`t2>Bfo%2mu0^< z4J^!l8=HTisiS`_JNNJZsI}8N&4zTYLe+C&be_^!Unx{5JulESMbU*y!_(sEBBiz7 zDN-msFVQwjNkda{bQx)_mrA0=N+Z*9n|4)n1!+-UsTk_3y7OwqFCphOHmNkambB{E zOG(4iI-9mEx}LN$Z;WmrhV^bmv`lGa+GN{qW-ZU<(JjnSU)~WdCoRfb9gS_w*cC-& zyJD#ubmyIlUqQ~hZBk`)4{6n}SCWROy*6!CbRTJDJ`mkc4E5bA((rW9wmrmJo~xsW znW4U16RjpK%10cG8l{oxgl&70wLI5GPcehOT+3RSPdgZO(KF0I zeX9j(%m9;Xza4_1UFPVYJ>*yBSPbSaHY9^2N-TAuw;A2aC7e%8tya4^Er zATtn&L_^G?JHo7$IqGP{gds^H8W$E_l8Gjmfl1Q9nuw-^rDJJks;g!VW=M<6Ih5%M}Gm6F3awi1{P+& zg*ksvnpyS-nmYPdwR67#h!qUxx3cqWZ8MiNG!+icBdz-NLelWGz@{x4Tu54(7Y{BX zhWc(1X?R*<+b(4-&&7kwn4!L0GFVJnl$Sdgs|Hsv1Cy1+qATpuYI3iHr8N$@bZ{** z=v$?%m3f_mQ8u`q8Hj8g+`ue#N5xfHZNl0$ zh}m{x(oJ@0C%IR_(r$-bIk<-z^sP$P%DmUXs2beI3`7nL?q?R=QN>!B4>}r$gds`w z;9+6WB{hT9%)sP`fpvWFsIYYG7&FyX4TCkLMfrrIaZ(tP)DE5!7GF{;3`9;FSapME zgoW9;!L!1oyRHt_F$0tHM%D#jAyz+l5twpWy|AtiVs^>cybMhpy+Uld&`Psn4T_gd z*I1_R4c7A9ICzs8^nN32WxnNLG!5Qn1|oL{?=Xw*Xkx9*_Z*G;!jPnS@PV-Cl9s_{ zW?=HrzdV{*PxDeFq?05${uomPRu2;*MRs3eZo>- z&VJV~3`7D3R(LQdEX*QxT8)A8?u-vwjxqG*_YOxiB_QX)M1`q4c~!(-g%P zDh*GIV~dp5dZ$RC^t?pdEF}$1#j$0iwO%TT6)TNQ%Wc|Ku@$66d8J~guj z*Vv@e*jm!6UoRyMPwQ;jveR=T#eO{7UlDf#sy(WQXji0EWV_k8P{WoTr#pQ0}Hb&im5Kr zov$f=13BNYNsY0aq*cG(NE)7Q*|bfu+oYBGZtM;*)OVXm!_z(6_C9NQZjL=*hWc_# zteLbZKXfpj#2zsNlgGrOE9}x!a<7G@XAZeF_M92?tyb2`{KCO#i@jt9BClhwn5FJ; z#o9=V@*79vtuQ2MkG&HXUE+?lGXsbpgx;c1C&yOgy&7Y{9ChWc{JP%&vyUhZJ58d|{&OjZ($uCPn1$-NSm z);Q$Sp|#AQZmDMR}8>u~`_Bln-qY7G1JqsGJ#? zY&EjB32WC7X4{ELH`%3~m*cw<=jH^Iiv|YG@xb5IHckpILNA6>DWa z=x7`gh9uQPhlNF#)C^TK1Ct{L*72dE!qTy0%v4u34AqbpqXSpCpNV9I6n!n!_$*(GE1GBkDc3bB=i z@dmXK>6&eOgS9+24&7u1eYugfGT(AAnucyO1ChH!cbG+YG_h9Zdyd9^VMx+E^gvj2 zNy|_(Gcb8*U_BXnBrF|!%uK$@DL-ZRTSR_lKw5{M3yZ(pDhxzk7+7sXFNKBK>!DY| zq`O>0ZOp*rjgj>hSctU`y#pp+<{oMnmX5tQHa`HfYe+{sn5}M{6?c&qWsjrb6^11K zA)m1L62CAI2^d)6p`frZiwuQ?$#;c?fk@QIiUA9;#84cVd|75FAuJtB8k!SBDPZbp zTG(6r|0D|H`Q_|9TieVf4NZmdd8Adp zUPv0A7TB~!@r9(7d2xIZG1Pa9NW;?-+jc2yc`lAGV}|;2NxYb}C@*&~R>fB^1Cy1+ zqATpuYI3iHr8N$@G`^M@^sQ3X%Dm3OD2uOW1|l2d8aKjNKzd?EG)XDCSJ`9OpX{>$KywZrDMmKsjg~>*N_(F6OP77VMtON zKP4=_q*fS+oHnrP;%9_~*}3>xVbWb!<8{oyScoO!abWUgnRr52I+ipvC*mn! z>Si?7Gjg}&%l(+CV_?77ejL@{uP)y`aS*)*mCETu;vV7_QTlx z2~A9=abV{;oYcMa?4c4qU9PI)K0Um@~t15!D>M_ByjN?{VDe=(!_~slu_K1&@!_Mu)YD_arYjqUYnXw_2_x$y zun?;qJ_SsxVBw8!fE|=JjD6 zy)+~Hvc}f)E9?ee?3AyO`*RWvBHu6|jl(yErM{f~Zlf>|xn*EA4c`_PW_O402$Sz> z5(XmojI8^>LacfC0WkTpmf>b$>DWU<^U3fdVCv~(Vat^! zz{2c>q1iV45|}#rdiWKv`A*kxo3M23jj{O_nwYi^zk{}1>K<+frk=i^k^KSMUBi0b zA#TXcCd4DY;{wEM$o#`TX3kIW?`4S}SeOM2&G2v#m^vC64gs6~ePwrsfrVMr*o;9F z)5LHb+Hz@TH~~yOP0qlc7*0Xkj;Fy5wAz$?1mDX*_Gt!ma`-c}(W*&k>gbml*i*w_ zp{?iNhrfv%|Cf+|A6Yg9O&$F)Bm1Yu*751#Uz!{IZ~Wio(;8dPf6w^FAMFjh=C5_j z`rRKm%}!W9nRS}0Q1x7xn5Q(BU#L)eUZ81;5(|}vr^SgyN^8ASq)>WZqHUIvhNj}g zGSXTvl_ZLlMyBO9?W)8I(xSXlG1OOe=hcc|Le6V!QfXo>Y1OZnl7^>sHf>pAJ!xg$ znAkuJ>)nb(nbOF#$+q3hTAs@jTbQA~ydzOgT9mgs8rzt$D}l&%#Zouu&N~&qf}D5T zq{_q|(yCvtBn?k{ZQ82DKGMp3AhDkq>bq5>;pw1ldx*6>S0@fLLw&g>QB7Kuk2n~| z6GxeW$uVMCD;g3tN+Z(=+x8@Dd9F>IVg`M=mbEgUb};G^XPAM=xx`s!sXMMF>PU<7 zc}L@dFeIr@Toe{xQqPR*2}CX#S(kx@*%if97wOK|6u*I-Z`h>9#7)wwUvDH0Pq%E^ zro?U1%6vC*hZyR+O{C%Jo^5-dwLCW`9xy|Fxh2s|T9h9;7*7(9n1RV-V$l_L=_$F_ z!qPK`+?sgK4Ek0pYh`}nV6-J(G6RvacpNHUrDEG)icQW%JQ zF|ei*UxkI)_ry10@?BHRm@|UN4W+$$GSZ^F$3`xpIwg`(Z*)dYi3{18fS=)rQYXr0H#H5?-(oS-(f~DOK zxpHI=Gw55Dtd)7MgHbiIj~R#@7}?J(x}%DXF03qDyKEQ6tnf%sSeQjdLc-*` z!ool#YGlQLg;-)F4oto*Gm;RNjwKDviIEgA^)xMPxssAO$qc)bB_9Ek_dWp&vB{Co zz?9#c1Qupr49%&LufWvN?<3!UEq6`<3$q`>oS&3tmi>e#rqd(8pv{+NzdH?09sNBc z`;W%f^S|m1>-RrNb-8+;t!?I#hNi;gJkqLPEF=w23vAk=+;mO?GJ~ zxmUr`Ziif%+`|m|RwZj?-s@mgCHFA{kps#7%%VH0SS#~EN8^w%B&kjw78YGnldNV2 zCPxgco)Q*cQY#EZP8(Qt$uq*j>|FA!FzK$V z$vS3Wa^A?g04&7nlNW(0m(>gFdJ?ls#^z;c>gW|>(}i~F8oAfN(hY~)n7qjh`c@-r zWxnNLG$n5{1ChJQJItaxnpi9IJxAldFeGVCJ`fgN(voau1||;;tS8Aw!qTzF%;c+_ z@>6!dMdW7&q&4|mSp4NyVIcCtz-mjr6c%Q$ldptHce#>n%)sQ0k@Xf>h_xr*0h2Ft zC)SzbE)r|$CF4CgxaWuTbki?(#35zfB3j>jWffY^$g@sup84@Pn z6&3~}Q6nn`EW{GYI57FLOfn%X9ZMRT6Uh`X^)xMPx^mWNh8dWAG_pPc3$e-MXJE=@ zlfc64i=jD{{0dAR{hs^=Y`JqvSaU`(`(bSUgeIob$zRasOS7w{p{b+4fjxf|*;)EW zW9#`}dc*n+P^w^5SufIT+jcH%c`h8C#|-*bA!}t`;9wMuE@TEGi$@nRi|#05t;|at zjithnqgaZ6^Nmh< zC%a!E@@@lCIl4z!{N+kvAhOrMsv6xVEX)p!?iVKCRV55W4jNg9fQ4A~=wV>;Wi_MK z!qTxLhUW3nqrlYDW5T8@8%ArGfyoIY>m;xcs~tTBOu4KUSeTtQH0wss08>ZLjh+QI z-+6VkPFOm2-q^eVO-$=YFG3qFtq11yQ60TBBm1((*7Gau24Ae^S*ZqMXY(~d_>CLF zkfd?+rm*;T8ij$#Ed#4*^tP}tyE}SEn0!~0Fc7(CWZefAV$GuufXSD&j5Z5P#~vD* zPevaBQ%@fYTdp)APsMjy0C{G}T1TG)Q|@R57G^ID&9>2(z|_&#qpyI?ce+N~gr#F| zjLo;u#I$|%9kk_A_h>sX_4NIW><`fH8rAa-aYJr4As+UfIVl$)UPI;|^#POa$iCnQ z7G?oMGdvmurjABNL%^0h!@$BUYHY@!iD_aq4sE$KGnxRVo+f8tPmHFZZO7B#23l>( zK7#LMAp0}}Iyw4T*z;5JyID2~O&$F*1AA)pE420e`{*}#ga2)2cTYi6M}N%7{;9Eb ze0ubk<_2Cqt+Dm|_l$4+(cZ9Y{;Ids-~MUNvs3C%sGjGNhNi;QJkqN73Q5D$0-Lrd zwUD$jFHS8YhWc(1X?R*<+b(4-&&8=_%uru0Nfnb8<>d~>s?-W*V6u`}bcJ17P41Pj zw8kNqrq(ipzE#Rvnb$cOWvTVdKxAWT1GCf}6{#}PqP)q`*enc5%2Qi}MVIVIl`{jA ztwz>1VeLv`ww;*&ZORlR3Q`rh2Bw|1?QYicT$$R#4Ek~(W(Fol46Ng+qr%d$W6V@nHKb}ti}DFaZ~y7uB)j!W?*vO$hrV5#OhNQfhm{O3+s9cvrES2WoYW? z6=KtccIg_q*TB*ZhuoOD$qf2dBWq>8`Liq2eZ|U1!FGKqU>=ryuy&g zpYjQdFYyZlk$`~}P6dU9StJz_Cf^kn1|m@-D+VmY5~(;a`LawZAuJtB8k!TS6fpHP zEo{1S)>wuan0z#{J^>4{$<$|H%4L(l!t9HoIhFbfOdb86`UY&db4plq#xVO~Z2p8M zrqiik(B@0CtEQo;qrZVYe+=1K`bT5y`CoeD-{1QD?_YccW4ZOSG6gA~X4|%NS<7?b z*gR&?w+dM+^8yE>Xlx-f5LrC7h*@+;5o={$;%F=th9t#f%Y;Rjl#CTK1C!+j)~c}; z!qTyo%;c+_@@jU!MC3IFq;zbpu=vZR!a!u5fmJrPURaoI9NQpFx~pQWj2W10GO{)U z3$gOCEx_cYU~IoI`K~HqAac;iIs`1ls>coklP{|os}`1y9WgYIj~xZ3o*ol6UD+^J!wgJL z7+EKQg;?#_DPYQFwZOvcw4qryb_SR_dT#72u=&obV|BvPvGc~}1!!VgKXwt?XlXq# zuaD{Ir5V|mHMX8#VK>O)bOUWczUFA$5QZd;V>gAxmoy3kky{2<)7WicVRm=yjxhPI zCSf3Q&&awDEX10}9srXsYZ+@6mX19%G@pz;0;Zlm7PeezLY|86v;gwVkhP9I2d3Q7 z3M|ZC7@BQkFM+9}ug6{io9}duwFyhd-WZ#2p^0hx*gI&;rS7qIVCw1n8QCA8-8H7? z9pVPvJS**D1|}XO%L^>T{9`^~%4L3FVHPkn!(%~U>S$yv1Z=r83@pr|#%2tfm?p;J z(3VRxV+mmDX>tbk#8?X2c03Jkpw*nsNoT~(Ec*y4y8Q{7m`;v;hBo@{Bs6vO%M9$P zv9Hk9^Y3Hd;0?5U3Yt3l1K9J^$j;KA8e7Mw$9`#U$mQAZPit&F|2^Xyf3!F3n!ohc zf4~3x-*5cV^k<=Iw$jeY6tFbcAs43SF~jE7cq+1T4g=(}#h{m(`@J zg{5Oh49(-|qrlYDW5T8@8`3q*z~qFHbrM*J)uvAYQ!c9o7G|dn&ARj%VCv|(^jTo@ zombO!!qTzx#^wcRVp^ZR2yL{q9+=nDI(lhF_GOK&=U3PbzSt>WWA__GzF|Nb(>I01 zUv3lzBDV~zru1!LVRkotN0@w9lQ0muXJp+67Gllm2f*aZTGGwJ(y@nz=9BazVCv~( zVat^!V;1g4I@PQL;+-|0%X2}{S`7@KdQiD`TK z9kk_Ace)*zdis7w_6KNprS-f++@PBa#$C+7#A9T6frXeq?E|J<<_8vL0YfvK4gyn0 zBk2&Z<<2m$FpCTXS>qXD>DWhO^Aj{N zolJj*Hd;CfO&$F*1A8j{7210KJ^c;dK)a`aIcHo)f6U1Ksj+o@I{iy?LoUy5oYvTS z{u|zyKaOu?`5)~KyXG&ymH!Rk|9-1C&VL@BXFD2mg&|4d_&j3G&lHGUXhaqmSViLt zg@xJT@kPQ^{|2%wF!l7v4D93MN1<)UkAWL}b;Ed#uypK%v3U}jnAVP; zf;L)O3r!t8Jp;RL{0y}9{M`6icth^KI$j4%Jv~1o`+~;S@%r(Lnj3g|J+!Zn>-nV_ z-?*&3Vb@#{x8zS?LavGLGyrnLkTs6q1g6~42rSHQ8JbPww}GjncgOEA`~Nch=gyKQ zU}1L8*t`!-Oq<6aK%4%JW|y{%Hv>~oAI`vjGX4nKcKk88fmWNcr{H@nkUg6LZ5@9O zZM3QtnmYPo26o%{OK9u)>+x6chTQEMZv&>DzL}BzR%7dU`}jM}4Yb@n-VSX${(iEBOqmCK&jp!x2Gl?9gEm^_ho+7OW?+ZMgV5IV$ao0eK)b`x)Y0gS z?3l*Z@x*vsa|12Uj3=ON$CER>F)^Of+^}!b;@1C@k^g`dHkP#`<2RLg{(0rm4#8QyQKQWcDkq^-h&S>G`0x zIYb(osxya4YrRyHsa6`9j@Y!vGe=2_@-fB8z1one$y0tlp>0l*hNjxgDblJh)slv% z(>85g<_u|NK9@O54C~#inL4GB>AY=wfwer>XD%{>zFbe*>lv9ZIU1LRfykA-Wi3Fb zYk99hIo;5l8#6bR#`<2PLh1RIrfJIDRvMn}X6`7h^-hyQ>G__vxlbCJnllebYrWKx zX;vDU9@?}|GLJ}$@?*tNU)7zTDt-$&KeI`#ndhWczurn3o?h6rZJC#(mHBn%6)~)L zU70qek?D(xF(n4FwafJmqJPw(*jNCV$39 zTJp|L?*=yOwz=% zR?M2nD2+@XZQD<*<#{smnHluuN!H5z#le`$d}RhA-!tEsMR!b*cFu&%KOBvp!jNP- z^GjIjlI+XV!a(FVv*u55D@*!qaOX`M}5HnE7DQPBg!~l8y&|>9Al$#yo~W0bX*Q`91kkTrVX*twhiq#25sAL zY{sB5hBn57A8lwMHX7qFw#%Sn3^BGrV+=7~8$aSDjyPx=!!pG1Q9uDjQG6GLBX_@t z;_&Y0`S17Lb#ly2XX#qx+0XC!?RWpHDCz_4ll6|%4P;9DwAzitu%Db>o2E=rzsbee zTDzGTm~2t3krX+#>9z^)wmD9>lPT>pYIhJrJvoC+dB4-e$g0gG1|qv_cM;2;<4|pu zGDZC!S7R?TILWTv$1Iv8n;1uG5!r8K9RL<)2W{r3iRyAjC|MuYPL3)QwacwNrcCW8 zJp&0ga3zP}%PB~6blPT>BYtInFesWQ5p)y7NSr_9%?Kxs# za$d326i(emWnU5LF1hr@wU>#Zo>feyyuadNl+<1&1|rvMuMx|hqpY?>nWFxNt8tSV zoRrqyVwRfZUTrBcFu84H-C@>)TFmY$=18Vdb!D~*@9sNJACf8U%WEGILp`~iOnLv< z#i*=(LJUNn)jlPbnxm3TdH>wic)<)#s%l>{OHEQ!TSW{^UKv=mwbjhhvDd_;sqFoj zx*El{`Z`AF4i7Up@zypni(bde3`ANCtU#@gS(tUy`k6^{1(<Ou^tv=eCNU7%UAK!^_8f=mvXm+6_qZB+nZZeR-9Bc~B-z9` zQisTXBkKULFgs{7?TK{j!!|!hSs!)ia_f#MQ~T9(l?m;RJ4_4e@|7v?Pu87K4EwnS z%7k{O9H*zrl=g*nXNX}xxu~vCnWFxzi*cdu95FCCuUKjdr|zP%uZVP)T>9d=%fwL6 zDkf9jUvV)?>aG$4k?VEWh-J@FR#&1-QGdhLxXBDoO6zVhOHFdGu9O&<+%~fAFzZ1b zW_J~HB$KEwvrTw+-*NhoOlen6q`^PRuW!)2EAo8s4DY4WXm1N5M=dQ*J zW^htf_mWv^lA5|IVqo&hz^bjQW|oeQTysb`ut9}MCFqx@XY6_=rwz4mlbaPz#xca%oP|u1ZQ{K;WG2-jz z69bWj^$Un)&yiRkuS`+D$kkZP3{Dd2moQ6BvZ6kL7?>_orNq)6C$cu>K6Q)Fegqg~Y(*tbui* z{v5M(>^w1PD!2Y3*&UoVj8UP zg*HkWgr<&$BC_9TY(0NFvSZ}8KVUW5Gjdx-R%30{zK-&YvrR_)C>vGR6Eu@(&qUjV zc9T7mY}1i*qHR=NPti`MDigJf@k~>uBPYdrVr&!MO?Q~i^2|`CsGn&w?5FD1vu%E? zvYzA6#d+o`Q~TB9lnL$TIZWd{^OY&@7kU;b#>lyeo_O1YcZ(dSi^-Js37#dyu%Eob zlb}pdztq)OMvPS+M3&nudj{QlrOi)N)=3UsvS+n2wO>71nb2;H!!*^CqD*xEgzz!AZ7fAG2tZY+@YoAhO@c zIsh!p4%$q6BHjA1&CgNRM;*Fc&oO0czk04Rq1|zZX@MtSnezUm=Y(R|&n-|Uv^(WE zJx!*xFZ7%thW+FsPoXkJ{aF{|g6AADFgdSSY6_?BqOz}ubeCNEV$Wq_sAmIm$dG$`tiCT#cK|;H1=Zi&<)td!ABaU~=2Yy2Gpo9?b44=13;d zP-dI(?!M#nA(_&?-1CSS>dEC~%KOJIMy2NoF%Ws?c}grbM(ScD zSY@JiQ4Qmisr`yk%7k_k9H!9?6O}3NCpSz|4Ewp!%7k`P9H&#sl=d+V(}-a|Ikq82 znWBEWi!rNV1~D+1saR?Xr*5{gFP3z3T>7|%xx`S6%=X3G^*&E(XrRQ4s3F3F`&ZdgqW z^{iwv<^38LBefxg7>KNESW7H5M=F`}e!Z))ff<~nHEd*-nk2m;jTo40GO)HbY-W~@ zZ6T&TRZc^?GDZD1S7SRfILT<(!7Q32gBghIG_bN7GMR=V`o1c1 zMXbMMK#ChKGmD;F%nU@X7+56@SDA&`^@eNARCARzln?`x8%EYmU?Eo8a0{3;*}aBR zX6e{%WAhF$A2jIbU1Hlaj%qAZrl`N~YCL2HC*=)~m_?J6GXs&w23BRm6J}xdtl=p$ zX|76UAoASEdI2oNsv2GblP0TasA86my)raw8>)e+r>~jKQ>tW4V-4A3kvhQmJ`b=E z^ENaBlV8sZEX-OA%|L?>m^#|g;0HF(82}b$oy;8H$W4oNLle_rLoc*xQtP@wXzFMv zBKwWT*7LXa9mBu>@ruSzlauvm?PRPnQM;(damv(w^(bXRy9o}{=*Ef4l=qVxCn<*g z+-PM&yD5&-sbos~n8sQ*ZI5=ocj(kC~rCWd-eGMVyzjf;`mm_iIh)-|prmYO4#OnJZF)!4uc zPSP4TGD}U8-k3%VOg0%Q)?Q#Cmfg4ym^@iFvyL=kw%^!108Je|sMu;kr|z(_ zFNbtTUHaU{W5iI;$|Y0YA9pbd8uN*P$jQbN#8Ptq6r>X6e{@V$xJ@{YA3Bi1n8YNO9w3X3>+2nSsa^1FNL*Dzh-V-gu3fYOb=z z5@KL-!^pY`EW}D1Zvm4gyVqFCEFHUTY~BIpgGL>_OKf{a(Nv~PQGegnc*qP+${Qas zizX>&1|p9QtjfkG%);zh<5OnRT$Ri~2B>Ky{V1;>-DuLQ?pQLVeN@vpVyOG0 z$dvaJT#V?ZiNru;a?>PYsX3y_l=o9yjj7DwB&KN^v(zN9O)bsAWR6*ip#CQVkJw4BCp3;O|WY;MIrln1{pv{xsYbph%p5Bhgz60$CO?rNp z?ckYB$bEL5GC&?0vht=!#2oLX*Rx1DurPaUXjV2o0j7>VYkCT7_5QMQRssvN=f>s> zXkuE`^b*=UX-!iVF!l6R1a@sxHME`hYp?^QHf43-dNq)FBB0);Mrfl{UTErQO9XbH z$p>vc?`ZO~9bfSB`@>=ZXzFNZM0U5v*70CduVx3m$A^*!HMX9IBHr;vyTfVnc4XJc z@BYAQw0Go|jjYDnsC^yf9cP=2_)#{ht|w?F(cX!+3GF6(C)uVW=S176x}Kt)OjRao z7vr6#Oh- zd*>@t-Y@hnP>hjt6TR`a3GWs;P8X9Y?GwC9h+#i@g*QQ&qJF8Xv5Xk2yofBfS@sON z^-7zcsH~G5x@7NaWoo~AvNECF8i#4BH$|E9ew}x%V%X13RVK7s?>OB+rnFD0)GgGl_x7 zZtpH)*>fE7W+_wD?{PKuGJ}(B?>=VHB-z9`;zeY?k#zuAm>sm4_C&h%VVj?$tdBZ$ zx!z;S)PD6`WkS2-4$}f}zB1+gN$&~8u%BC?OlWt?aeA6eXjY6OOz?< zZ@3yanZZe^_ZG9%B=@|f#K7dXk#&bz54@P&Rm_o0qPfgA;oW`5=|eK5eYy7$G1QaG z$&~kxU5rZa6Jj9p%=?sBYK}@W<^6M4;{`J~sq(&LmYSr-TSW{^UKv=m-fCv)*lS|i zQ;lk_QKqP`b2U87;Kb`~WEM^0WdEmrZ`Tgk}2(Dnx_%NesXMcj50<2bQfb*^9*8OGE=eC6i(f2 zWnV1m=D756&2x#No)t%?yr1V{#5d0;1|kca7ZA&yBe6MNnWBD?tFf3FoFp_aVV0U? zMRNi%Fj;D3Eo0WIX3Ul=rkcsATdC|zBwdnApWM8f80uNcWXk(BE=Fo|3Na8_*SwZk zYK~Mg<^6hBV*@idNo(H7EHz1ba~d%)*<@gCZQjf*9os@od#aq~bY+VAZLY?4W^j_x zyn|UZNd_|z*=b;9HD@vlv)#?Rn5pJE)SN{OO!gRAdx3>mcJn@9@?_b}I?{~Ueq-|h zGJx~K0z!sM**4g{**n5pI}Yc3%MCO3?%o4`V>wD}e=X|j9GrOeW?+s5V{U_NNp(YwU9XB^d1 zrc6}?3{J|MA2Ew2DQ5;Ej}5HK<|oX;>{;_uX3|`h%s}M1k@W&th*dSe1SU;Z z(_F>xL$#!RB6Q)1=mQgV5B`P(=0{jjiWz?K?((|I=bmZeNeq zPR1$|wTo&Qr%dfvj8Z1Fo8T~wZkeb|c|W;jl497;jaDYKo8mZ~N~W}rX_-b0`^m8_ zG0GJ6(_M^NEi;IL$xOvkQ#f_Am3^_Ko8!{Qwag`kdR82n@_wF+5#KVO7>F!vSwJj% zj>MLDWs3SmuEt_!aFWongjs5m6)g$Gz+|bBwTxM-S}k#tEeeR9ic zVyI^&lPT}lxEQG|Da1fzUCUZxsX0=~l=tghjSbA;B&}s5v(zN%EosESWRrolwPiE2 zbZiST?WuBF(v>Odx49bInZZd$%MNDIBpJ*=WT%0Z)so39%yzfzVy2qwP)imuFxg{d z?FANM*)98k$&+O>>qrY``;E;5(A3d`imfJe>JBUWa!7a7rO$0SMhx|=Tr%bTaTlYY zC7&3GoNPHkEHy^~nezUWt8tncoD{a4VV0VtsHKn?n4C4RF0`CumX4h#CQaqmUnKjB zSbxcY6t`Sv7CpI`8Hijluu594G7GcoE!UW-<|=C`AqFNljI5i$Laemq7BFeDdo88R z(y`md<{e-@XwlKT#I|P?t!2s-_4i$khs@xlyyX$IXp(YfAoAG2s%&|}EX6MVb)@323mZ;)X|O>Kd^bu0JFxlV%BMFc0&`>U`sEwX;Ldy5Sls~0`~Y;WLxx& z#@6$<>W-1$0Qp3#Ej{Z-J5I-vDea?L#}Pw4D~e2cKf%R_Zk3{0jQShHGZFiXc~5|gHK>t~bwv8Ce4+~3`Eu&SsQ?bSX%2wVA5pi zt!d2Cu}y~N*4E9y)YC1@R#WD*rV|5`ZAR91U?G;#x&xRzSq88$+i7TKwPpfSM|ZdG z0yfQgs5OgOI=08y+zU-ivs?E;8zs#K=8;w%-5-&CKx6CqL9&A;w)dlaIf`xdhZ&(e zjxvLj+}2~vqSwh~1|r7|tb*2jW?^=+^#n6%t^#Hta>~d$4J^b8Th9QKCM#+!WR{Md zH8d}@o&%l6WU$&eMdUIr%5Q4B21t{9pntyh7mqt{!n0h{J5Yb{}x zj@>XeZ$cB(($-th=1K3hmI6~xZ%1U`f%bz|J-^F#@XRLUKDo{qUl|||4Ow~XBVejI ztP{$Ch1p|6v$FLGFm?1<>r-I!oRz@B?76Y|0-BgswZ4QlPg>Jj1x!7C6@gvbS`BR{ z{u=B+sZCiOxLyrpo(QP7wUOE5ef+u>^FmWcTOzOntv+b$c}J@s?x6Rkl{)}U9qo+B z?$+2k9&GK^?7+!`8e7jp5$|}T-QhHOYu{!6?Vn~n+GoFo_Vrk0qIOZfamv)bFG`uv zZi2%!+BZ>|@_w>!l497;jaDYKo8mZ~N~W}r@l7L!{p46*j50<2bQfcmZw4_inW|0F?^{iwv<^38LBh{Be3`ExX z))Gt2kxHh#U+-#cUw@nbvvlk{F=;Bd{vz35#QIAHq}X?vS@h&$W*~CKz$)=w zWfo@Feb<<&<|^}*5CfANM%GPWAy(?U1x%Xkp0AWyI(FOGyaUV!J{`SFYDVhnv({G)Og(+gY&GSmwi;q!QfFj&fQ6XX*9c6W%nK~cS`5vA&j(B$?eO`5&2t8r zHKq--PGhqhnwSQCz0jsftyDp1>Szeq@<}(Ykg>4I%spd*-izfyq zi;S$rz(OpcZ3!@GvK4I!%+j%?#^y3$u4>cK<;12L-TIYee~d$4J^b8+s*)!CM#+yWR{MdH8d}@odc$xo@X{sX+kct>l6WU$&eMd zT?Qu4Q4B21t{9pnZC8P*qu1N60h{J5Yb#-vj@>XeZ$cB((zaXB=1K3hl>$>wZ%1U` zf%bzoJ-^F#sF_Fk%ZP!=eIx53un;S6djw3LtQ=UFJvKBe+nxYZN1wGl1vbxF2`tQ> z8=EhniD^~aOK9_?HEmVE)YDfH*tKod(01al!48y~vN8S|w$oyDkfPllXkzMZYlJqs zt{0j*+7f{sX!Ai^&pX=ua0kjAfToUi0(-n4*%s~A*g76;>(%Vw$*t=LHMX9IBHr;v zyTfVnR^4U){hxp2wu}l0(v2p)>W(E-+DG}v5kuV{MW(!;;9^AkClUjZ$^J>iQgcL; zDetGa8dI6UNsNCQv(zN9{up9lGTp$M<)6VU9h*r^n#!%8P4>sKevSc&^Uq}#JvojU zh|Dvv;{EfPh1o*?0%oeY68-VSz+{n;wHR24CHR*BlO|i?PhgggEj2cm0dtjKN0$?u zW_0UUlKqLSPck6M{?*K)Cnqxlku?TZsy~HUn62}#WhTv)$_zx-8(ABGg;<(@BQR;Q zbblJNbZnEMxz)cJn0mT}*=ouhe>yQR*=A&I2Nq%({vE*N$ufY2*-k?<%by8M9o_BU z1#Fu0kUxuAI=08y+zU-iv;F&^jgn>q^N3$Z_eW$O(Aau@knEs|-TK31e-7)98jxK7 zF=o+|bD4q2aRaNspU*7JPWn$UljbU51|p}7tkb|ktk8c3m^4|DzmQovcGl3m;6DdU zJw4BCp3;O|WY;MI!yfhMM2ep)8sAP_33W_Klz08LEO+BZU*Crxip1E!vCioo95z8Tt1d<)n?Q|Gj&GfT&|8JpXo ziD^dr4rrsK8PL?xoe|hs?U~Tl^WE*c;0~VqPj}}_Fj#xL~{;WRnOcJW(aLJqU*`x$8Sq($w8z|_;T5!e^n&q3RXp9ecoYEyO*T(1bSOA*lG z_RG*lsfwYgqgNuZOWLnOThFhzUxPb%?y~k0VCw0Oi0qphTgOY=Z)tX*XX2*ker^#Kg3*81&b{|}?46=t2(DL?2&_=1sp{b*fBd{ympFmsBpS3?_JH8O$ z_lLzQp{b+KBeGv;Y#py^f2r9)?{O=6O?wrzo%pK=cht65Yj!wKUc+7ZRzyPU;B{*> z)Dt21wl`{a;EZ04t>-Nf?g+H|G&`Io9qoS2E_^!z8e7jhBi_-i-JzcZ+k3UUbhjj^ z-QhF|eWqP+9CkU+-j3}2^f$jFw`gQFIxw;xS&g+(`#LHx&NdnGqij@NPtZ)F0~2i% z+D#5jvQ0V=P->A%vYwoUl>@R7$fH<2I6fK-Ys&RE+$jjCj^!d!+!FL zK!P$w{ZdzB88KD`5Ls@s>=|_Hl{P<7StmJk$${0%)PD73WkS0(4%5^?iZbQ>y1-h+ zu%DZ%OlY^>ak_y_X`dF@NDTYQ>47w5iuz41#@4`QVqmgGu|`tl1k!C2-feT7ZYNXP zX9RW-Lp?czOnJZ4#mEX|5(AOlfnCJ1=QtF|Ql_Zi<7(_>1}E8peaxasvWamdfXIF$ z>j1DYJ7_cQiFE73Ha|yMA9d(*1ILu9{pz{Ogm%XrrUij~Wy<@LffI^hKes@c(C(Du z^fZ~$zA$ix81|Ek0)@&H^=Dm-3xRXQz~sDQsVSVgi^{$t(p_@tivyR5p`KMtro6x6 zVw41~5(AOzfosIF=O_!5C{xtma5Zi+gOk$0EoP}n?gdJTfyr$n>khLX1Ted+m?N1) zN11KHyZesQhh$3o^1vfvs3(_`DeoV<7?pu1#6aX(;3=`x9F=6s`{%C43ubUq6?n-k zHAzjNiWr!@GO%g`)y&ed*Tl4^8r4ywOi^FwYIvBzi8s*5ESkj23`ANCtU$oWEX+Cr zerD2K0b-2lK%~>i>IN2K!9XuC)nrzVAh0kCF>`zeH!b!CnmYQ{Zjby1pu?Wkz8VzGFTy5LwuCE6!nW-jm6C1B%xyov(zLjIueM1$x5^RfN}?e5scOf}b`jx1tevd75U z3oOL4JN5ySC(CBmkq*rE8=D89siOxK+m^61$39`*VaMrFGNpZP$1!54C+CtW?~l6} z1s(asK;&e{31X=^3dofAr(BKG%;2Q3;|#OZBt;#C#K7dNfpwwd9J6%nJTYl1xBep8 zU&Q)L2Bf&-GPCH(#mqqDih)(qag|w^UGKQYOf^?oM+q@7xnX481QueY9k+l-X*p@mAIWrJ>Y+zM(JYg1Q&pMtm zljf>q1|rXmtQWvStg7QBFln-yjw)v9*egS`wxb%Ddit8#Jf%v;bk>kP7O4Y_@ACi) zF>gmBF!}Yoz{0G>&b1pH| zv*O5<_w!tg_|EynKxAR(0%F;7BzDFtQ`9eVH5N02lZ4JC%u_+R5LksE0ukTq)T$?lRH-vLp>{*OnJY?#YpW;AqFDrI@c0Q&5=r`ykGBXY+wc_ zX`LIHr6x)5Od|#+n+&Y2otv4ZV_S%6PnFY|u1rzC&DGe>3{EmScQA`4$zTQ|I}NO? z&P--uw!3o|Gu2#&I;XvZ)_fbrj8y|Y&D@%cUak% zL%O3beQxJ5VyI{3k}2nvrKj@>pk?*Q{br;gqwwmqZhDpRJYzwc^1WCkbYosXDB zlaw<9k;evBW#{`G~HCJL+JTWj?WMnM{7GeoqOMpp} zt>{W%mX0koHkSc&RhNz~CpOLK)~_V{6Iq{RK$5#wGmD;_%nU@<7+9%YDa^ubUDsM> z(p;&`KxDm9}=HDyj$Ix#TWW@K##7GfD) zJAlcPWdIAaorY#sS0*rZba&S-VAGt3y0Vz1V|$Fvz0kxoyK5h`QPON+9_iB2{Sny* zG`5}}Bs*wgdq1i>N3pH`Fe7xwQD$(G+jWdt^g6lBK;*cARnV2sEX+=JonR)-Rlp2H zP8nIJfrVIM*BM~aWJO(t%+j&5hUSH?bHLQo^UUTcO~^%dogzRk8M5N8%fRG0ih+gM z6+^S6>nbpH^m^AdVAGssT_w!Yu^YzbO=x0T+I0)sJn6lzQef)o?TG9<(0x6P(VfNV2tn7LMOdWmJ^%U4VXC<&Odv0vLfF`C@ zT`!@{lh$-q0aH(3MPS!hd7-JJEfLs( zE+4e@yratxchGy&${m2Fj&??5cWZ1N4|erxcHrbejjiXQhYhOiOlB&Un!>4@t?Y{>-5i%bu6r&q)U)Eql=t&ojQH;P#6V65!x6GJ^KnM`@V#>GhOP9X*&>$=wxOU;o=ro3P8YHVNzCu!XqnWZL4?@l8ICYubb zt=*fMrDI!&X-}2Yovut#zs=Ry&J0d6x_2;(Cdpt1B0CMNtnN%^VYa(_7cOr9*8Sx34t+iz?hfToTfRBSb&Q+HU|mqWUvE`4tIF=D7^<&r7y zkGmKJ-TA~o1ChrDR%Q1SW?}ZM z`zbSNu1aPg^4!RJ0W8F-x?cj5CadYLVwR4*GBj(utAVMfubHi;9Mw}p3{2{bEDx{{ z^L94^lPB{63$qqOGtlh=rjB-W`+?1K2ADOb2eVFNvm2V22D^KqO_N%wg3#2_5U|Jh zAlssEG`60(isASG&=U)3Ibq`>39A#89suMW(!;;9^AgOe6*(lY1r+OU)5Y zro5lxYD{GYCow(Kn58C(?TH}dtdK~FxjFgw|Ef|)c|0W%OeWn`TO7Gi}xXMjnQ74;M{OUKR{ zniqP`0aH)UGn=P0As5+oiU7G}$clR|1C!?{1{P*l49$|BtH9LJ>pj>s@lrT%j zZWx<4p^0f}&n;;4r1yGCfvKmrBeL&6`$3PM-(@@0%%ghCh=Iv{BkLis5G(I_1WcZ+ z99Wn=HZ&`Ho&ZxvpY=QiHqTiJEXv*uISF?jBx2_-5*m@p{c*h&<4yVamb=S!6|AL~|c3W6C+HpFTOlcq0JB}FY zSy5!l`w1>abnirBATqgk60y`A(PYZ|DXzv;W^fYIJB?XtlGxrDVqh}ez?#)NgIPK@ zlbAG>TR)rZk7fNF0}|Iems#}WIA$O+&%lcBozE=H7WOV+rkX3UH=Y=nEHbhd0}HW) z-X*}K$yW3xFiXdl8k@_2xvE!3mlK<2bn91={fVqkG9byltC>YlPG$xoYYeQ^-V|nG zwyt+AGik0=W+1ZO$l3rb#L{{<0+S|7?@eQtj%_kDxAtxZrk-wLwwf}hH=P)mY%{X9 z0}HW?-W|Z?$ufY2*-k?CZ80~%Y;50V`;v0Hzb?9XBSQ3I0OdyHB1DXCA^Fr@AVCw04X7iLLc%F!l6yMD`tMKj_u-yKIM= zS@e|=1C#qk)V>wOArp0g5Im_0W(UqBPns@|8- z=1FUMtAMGeuOhH(d#j=C#9xCQH1(*y8fNKOow4bGCZ^urMrfm?UTErQO9XbH*9UDq z@96cz9VmAIm}B~Mv@;^RTVv~Zu(wyUgD1B#1~s;xhv1I!eRzk(-)MI@P2SR7>Tdx1 z?6+rBP_TY9BXq}DW^fYKH;!5KI#J9(WP*Ve-8Ye0m`(1R#7vqini+^pF|wut3$d8K zX~3k(V*6s4rDM|#%~^djfT^c5naxw0klE}yv4G4mWO03Sfyr~k0SmKvhGu-M6 z!oCH-ra2S);+dsmi;T_1(8M&MZwa({(iMFPz|_;F5!uV2y{b>om$Mx_vk6(ru9FBz zk|9g(TMbN}BNglEk z?5%y9q3y)CfE_e-PG35+bZnckxgDCAX7ufVHcFZSOCft}Tt32i;!-M0(w;JFX= zWdT!9_e5mx)z~_o-M3G(11Hah_K`k4-yiXg1KJ%vO^9la8PUD9_I+IoJy?;6~}bC>m%08>wI zL}cI8*g9U?cT2MaCBN5K3T-ETJK`O8G&>&jIZf_@UFbHLvisnAWsp6LfR^_?V)pnT zzpll~p{b*fBd{y`o<*tOLjy{jbexb2-ysGb|W(P`M(^my;C;lqJ z9kqScnjOxQ*KilU6_L<7c-v>CrI|6+^%?_tYN1q?;`a%%h zPZkYmY(4Lcct^K(hkg?5>(%b!-;tqP64dT+nuI>nt~U<5oM&(CJMF*w)vQMc?YGyy z9;-~$E-E-qncDY7DHGaFaF|91Cn{6kPYzB}4Ewp!%7k`P9H&#sl=d;fX~eLf92<;L zrl_CpV$2H8AOHZT1eY*NO|l}GKnzTl8d=MjwJM0&a>Z0LIdvFxg~aZ4GW_mX2*9 zrae_oFkP9Vew(YYof({D1a~ltCdpt1B0CMNtY9XyFxws6#Y{EVp2rg}h@qa9OQyU(?qU=K^NE4T z$>0fMsW}SBl=r7xjnmBFq%e4fS!$A^U?DLuIcs2D2%ck>j-4kaP36{KB>Rh4f60Ip z2QM>=o?OffM6MWECBduA!t8qR8Z*^gWx*0+U~)1Ci%O z)(c=ERuy~+Oq#4FSj8+Idu3?W2CIRor>~ievD6&VWXk&~uEtbma1zr$ zjah1v*!~z|U^3mnn$4pm&n(Oq z_Ag+jnk%tCo*0-cGO`u}3$cX$CBUS~R`e$@OUITPo6CT?s$WN!6Pspq>sONfiL6gD zAj$o!nMF@dW(Fc_46M}t6lP(zu752vX|7aeAhO=b+5jxX()u?7lO{{=Ph*yjZ89{s z_HPEJo^D~bnlh(9ofw#GGqSb=3$cv;9l+$tGJu8IPD3-RKNFZby1RcDuxZXi{aMV? zu|3A-UT9*P-MwnU{b5(*C^I<8?LWpWnk1JQ zh#WVt3i|Vzh1tpe6U?N!3YdY&DI@DNun;TkKLbpftf;?`Svq#s(7e!p4w!m+p4mL5 z3AxCwQv}E*Lsr~>8JIjrF|aVZVrZ81Uj?R)UhlsKY?`yIzl2#jcEi}b2~A8(`)@&; zC%xBS3QRq{9g%$p+7J5m{4U#}W*!wPBL*h-jjV^jLae<15iohOa$sTh*wC!(e*#P$ zeb)aJ*gR(?urPaWY`%adrd9nfq0N)l^j85>PhUk~*Y;OK+ljvhJ5XxM#)N9vPK(t+ zigtUTiK(~05!&dwUTErQO9XbH-v@0y@96i#9VmAInmXDE?C~LFTeMqa>v*ugSF?jB zx2_-5*m@p{c*h&<4yVamb(j73e1G1RL^kty#dxERr)iNru; za%d8<)Ev=d%KIs<##Cl-5)+!nEHz1ND25oAOgFG*g=R2I$7T|frgH0Nll`%*pJPDc zLUWl#PmW^-BJ&Ka_|SZ2VYV=|fSGEp#85mjFj-_|Ed~~1385vxq{&u<5}2i9OO4HC zz+4s5(dERZ8QuDoWPc*-lMG05Xf?Cw$;r$>WQ~E98cJanX6r(0nMre{G6RwIM%D&k zA(j@}2uzwRJ(R{Q9ouARZVhb)rk-wLwwf|0luisxwi#L5frVH`Xa_KPvJ7Bhw$sqe z3S|OQM|X#I0h{JL6v|?jj_olv_d*lX?9e`FqomouJQC8;{Sny*G`5}}Bs*wgxBf8M zpTqj21|&Chj9K*LTxKA0+`uXbol+sD-4|hCQVipDrA<9 zoi#Ksgw6p|PtP-(r!*lK*>#Elxn#(SLzjWca})y$vnz&XN$4stb@Y1Z8n9{3vQP=L zbnJ$)c@vtLmWFOYn&Dg~yV-j2w=1MLSPJ-^F#sF}q;88I-qZ)80L7GmY0N5JIC z%7KO1V?(nt^aPkX`YiMm*gR(?urPaWY`%adrd6Sr(B?^NLRG-j(^nDLwV`TgJMq_G z2TeU{poUpGR%dK_poytB)Cg^q)C)}=ZHd4RgnZD}^Nx@o?m)Q%z#KE6qn#1i-5OiR zgP~r{4xZe~7}VH$9)df@58xdZf1};uGvjPNm0x| zWP*VeJus13m`xs-#7vqini+^pF|wut3$d7iX~3k(Vh3WFrDM|#%~=C8fT^c5naxw0 zklE}yv4G4mWN`y?fyr~k0SmKvhGzW0d|>M6!hr?Ara2P_;+dsmi;T_1(8M%hUglEk?5zWvq3y)CfE_e-&Okb|bZnckxgDCA zW(@3rHcFZSOCft@vw32i;!J+KSz;JFVCWC2r8_e5mx)z~_oJ+M!+11Hah_K^WS z-yiXg1KJ%Z?!Yl%@*KIq!tA)ASul_fOdUNra01voX92J< zJ7sL1h9;(k181PklNJpW0#i@VMqpnUI0tPfeje;VsZH5MaJ?ePE=53#2QEV!r7DJ| zj$VntE*ZEAZ9Ts}a1HL@xyuGhfT^c9BC>C4Y#lEhxTV>FlHVIBg|-vF9r2DknjH@Y zoF;d{E_54A*?n-mGRPiAK+6XnK^vtiho+7`j=-)Qcmi!be>U(G?m)RKp{b+KBeGv; zY#px}c&XWelGhAWLEDMHif~8mK(%Iv^W-($g>OY9v<_akMngRja_>N+W(Usb)!2I8 z65)=(fKRi-Y0@#^*X+W#BcQSMyffk*-P#@cNpPT7yGwUVg4!KUlh9|{^~PbB^X%;> zJI9Fe;tS%7!n!TP>kk~ek0Y8=`(rWqIq!ErfuCuS!BI}PnO{}4(KX!-dfQPBelps{ z&!V>nCFHjnC$PN1G3ps=$5YZdPwj5-Jt*<#bse+QPy%%S@OuPZpJ#v9-?xw1Pn<>2 zshH8nfqpkOb#!pNdS9p=zc=Ze-@EPx--GUn&+9s7r=bKEEr8T^1Aae{JG%wG5V=6v(QfTef@E{|9*UOn&0#I`(aW3_=)V%rh60)^T98uk0Q0> zk5)S8-wk(z@3GR*eY8irxWli5_8|+i_s@SL@5ev>GR*m?_ZzECoboodi47A{_%;PU7R0> z=svTaJ^ADF^L{-;uf0ys=(?ncBc{7=u!|mF@Al{aUEUwM+pfEndX63!@BV&4ujfOL z75qpYdd%yxT6+e+sD9tojz1gIIsa*JH~1d(J^#F}V|E%!Fm%t-9JEK*=MH);HnY%9 z{7Cz}uV;QT&NKArqp4{B{{F*{vmuI}f%rX$zf;J=&w%D8-miOJdRNztEQKx|etqYe zO$ho9@O{X_4Bf)d`+DXlNAmNHexC73==Px7jdx>HN72vGySr{=DI$A(zQ2DXdo*)K( zxBfAS?;Gbwv3?JFeE+ze-QatyPh)f+?a?mo@av#`$ij@jqVqFN2)a7ohb+u^uFv~+qVLJj zr)HEJaL-)^_;&C;Wp9N-uJ0G!`|P1l^Saxn%R2NM0KSV8{ECP? zd=HqLc)#v;zpLv;mO__K|6TcU&Hb+Lm&or){e3(%!M_=MfB);B6Yzb5KZy)|cF|u8 zy}yh6RqV4pD*kb9N93;%&i5pKynePvxzkU;@QnWc_x<~C-E*Ao@x(bN?_WQMKk=da zCeoj8bPZF6zq@ERHgyy~54@}EMwTMd`xif2b!Xz+i0=>GHFUO~>t1srOB4C^Kg$kX z*7xtf^^eSV`+dY$kA&(T2lyH~ThDcmnRk8t$P;~*_cQobL_&2r@ila|p8xZ{|KI)d zaOC&wXL%gypFf+46JNdH)|Cc0;ze=fJ zfBtzsFI%5CoStXi#r>#%j&lA9F`Eurzwl>&U8}z7I8lcmI7Dlz-$u<`)yf5m)_6*0=Y3^vfB0W8=Q@?_#%oJ2rK}ngy|` znOlGDm%q7Zer)DP-}vUPU;XBGYm)TQu5bO?fBp5Xd%ih8Hf8Vj1+gnqQexMC`Af+g zz8bs!!>@k0e&dHp3&NMpvCjFmLhHF{=+D~5#J{-ylRr!fx5AnaudN#U6TkD5_I{#l zqHMsr@Fy4V{Cafyf7|5x^>O&mSm|${?{?V_=dtF)>)~o0X^x^6+C4YI%&!_yt+OMRpTmRJ!U)%VL zXZ3Jtr8FBd{T?0fA4?1 z`X8}FWA=X!y&Xb{;rgeB{)(`FOZxxoqUYjt(Qwgw@jvUYfAGR5JJ$V#5bIuTc@-;u z>DA6xi@5)zs@FCBLM%KuoQx@-6VU!xgkMXvKNhi{Q-J@UFY{ym0};OW=<{V@_Lyk# z(_^C7Bqy!6l%n7KAUY5n6jx;pwf>E`BkN%M--;))`v3lksFt;&tVH-^%{!7U-pKm# z;0qCTaHvj|b)Wx{h?R9m#T7AM)(`XciUe5$@~Jv8T$5$3@%u%ptoJG^M4GHe^72Hw ztUW!|B16_e&qI+FuGzBs|N75Fj;s}bc3$Mln)jRE5(TnaxeH|-Y^@N*pY(&GBwR~B zseV!RNv#m&pVT~2DeLi{sT0+*{{Fmq!XxWoVxsWL>i>`bQFO~%@$dh=cq41xPye(S z`|$_SuSq==KX;>vG|#j@u8>eob~tiN==NTkSG*fS{7WIfT~ z7u#js|CbdaOV+O*%M%A={aC(o<%a8NS@-$n{V(f|3L&n_`eB|BrLsQ%Xr_25>)^+8 zM5V0$eX~ThtQ9+cN_b_>`|w|h?oZ~a;*C}JY!qX2q_;CwOq8|aKYu8u%9^+QXT=Oz zxBqUNm@n&Kuv#R9Ym%&fZ-q#ewW9pG*eq*aZnnsfRlW%qS>c*(Rr!6(v8w#O#n^2Br;_k%oiftsviq+ zR962!Aqr%z*dfF@S@S*=qFC1dzUYa#DeDiH4~jBbZ!GnTC$gShR3WNl&6u4hJhIBW zUHD{eKC@p0W&Pfr?}@0x@^LzNPsGT2(|=RM$@=|@?~4RkKg#<^B+HuopYlYStUvpe zuZRp;|C_wuvSs~kd4J`~`fYiC70S9^-e1MCT3)HF;^{L{F6(LWBk@Ak!KuF^YQohg ztAEOOMNrm?=zU`B5t(m7s)&|V{BTgr2-o>mz2O(jta`RWq*yg0Pi&U;qmMok+ru?e z)|mw|SGXRPb;dEjD3CQ~Z-qD~YxG)~Pu3f=XN#M%4#vleGFkoe=Zhz@R?M9%s$|WZ zK3#aMc_<(PvX;cBi#M`XS67RuqaQ>E<@3l?SqJ|{h#BEJM^^t|2{B*RiXRBESk}B> z6JnXHuYNyPB+EK@@860Ivifh%7U{B9eE+9JrmT4%O%>U)-o1NQ2c6LUX^j=gb3%#iiB zo`%GHSxf2$#WGnh{m3s;Wc}@16=Jij>A#UDGG#rQH7E|q`s=y>UF3)BIax~{z7|(y zeOx;z?#O!QxqP0H_2Qpah-z7P$^AZA2M23JFkGX)D|7jui5OWcD&+Hvta*9+MS`r0 zDi(<(Swn$Fks_=7SD0c$xTeeMmk<0*Su5lNKU-Go`SYl(*7J70tb>dHM4Xn@AO8p9 zoU9f9u0ULpHE+f?aaC69b-GMeA@@I#_4e0(B&ubt*)b@5vOfDIzj!0-&Gi*x;&J(X z{15W^S=Qgl`dcwy);~Hd?`%o+ zS@VALH$;rAgPuPXbFBLM2O>UP6J_=PuL~ko)`~xo?<-`@`}P)*C94oQB0F4<%KE>1 z8b!XW-#YQrqEObd!R6wTtbgKPDoSKMEARh1vVN2|Ta?Q>C_g(?hHI6q{m?~?;<5bqKP0tfkWtA@zA|_m8 zWtA@zB2HHMG9lt+wO;QNWWDpf?};Q?2k+ezsj~WS-V~cVI;NdTcY+3!^UMX^9t;qN}kt=K7 zm*$EBS%2$kt0?@W4vI^%9xRiOA6YXmSBN{ZuF1+1<+ASFR3To-dgNCIMUAZcf7vg5 zvVQdS3K5j`OUv@a*n$tDvvLYVw5*Th^XLp&|6D$g#>x77@_BTzteNt8Fi}>^OObUj z6cQW4b+fGg=4P>7){4LSE0HN{-gmz%_R1>c8@-%xEwHM5!&hWg`G&8=s`3qAnXIc1 z-xN<|{YL4asFHQ_Rlo4a`jyiaA|UIM?Rnyjtj}-CH;^ag`M>`a5hbht?3YEftk&Z< zM%KJdKOe=h?8|tKCds9)i0md6J@QC&+93&=E>WWX3f9xC6OMk8M68}uM}Cb zR($2>M7FGXOXi9kSrcn2MZT;;eoiQ~s{EXA$*S^mLWx!7=Y%`5`VafXLs=_h3q+-? zgUio|YKt$;7hYK_7G;ZWS@UMgk8r2t^XKb75mB-ZHr*D{vihs8i5OWcZl4jcvgRG! zA>ypLd|rr`wWp^?Ec>JvA}L%`WR*`BVuP&m=|XIlRX$ya?Xp_WhhNrwUd)nn>vd=N zb76w~{A7LZqo3<^pWEo?vf4DBm4U@-TSTK_fy3(ul2b=_rA$`UnFn7_I=L``98yXU-J)r z-$LJ)48QLfe!o#7bIQB@)At?2?<(_o&ew)QFulR)(R!#ZJS5mFICTYbde=+gp zaFzWh^Ir%*pJgR~{Z}n-?}ur7t(uy$LB5L<;uk(#n`G55hwHYV|I#PD{2ln0Enabaad1 zXXB((ENf|a{ZQ5y^2^#=BWrhQPnBO5kCk=b%VbRtuQO!L53dVljr96ua*vh& ziL5Vd>l)kIXIlqtYwIj)@9=Fw>#|!RYFp2-try$YNw&3heR=s$uaDLnq(7WL z-L}rOt+Q?Gqqen4{sQS+=UVxTZ0i!+y3Dq&w5?6@*GPXjzt6S~+SX%#Fychp)+YI9 zNPjs0eA{}NZJlCUZ?>&X@@Gol`nM3-vYxiBi)`zwwsom(ZC&5mJN)=T>oVzEKU3EA zD{bo<+d5!di)$mkb$x5^@b%GpqV%OAVq}fAt>@d;3AS~TZEbS@q=x-;Su<_x1GaU( zZGFzRHo5-QuwN=`nQi^Vwyv_RJ+`&U^?hOgjjR*@c<8>e)-!DD`L^{k+uG#%$zgwk zteN5UURkZZZqJP-PJZ~B=VZMTUYE=24X?XpHMx$?i7pv>ZjY69zWlNtO9|m>y_Q*D z_CHo{{k$U{qv5fDTmN>%I_#6{1m)|M{4XeeQTEogKjjA`mw)eTaqIQR;#Rf)vHE!V z^)KvDt}UJ@zv#bFk;jNw`DMMf+5cEPU4H#bJCtjS=g2SXXWRbA${jN^(TeoRS;^Cf z)-tZh`8Pvr>*qE2lSAvDkn1~dhVEbM?85&&w6?B4BfQtT?WKP`#I4)o3$LwAduI$? z$I6lTa>)5V*;d+p5XQN3LVSYx(OykrZCflk3Id_0Pz4T6mo!*GI$m z$sxH;3G>5pEyCA7BA3Zw=crs~g`Mxnbw=z^=3{c568?VumRv`N*ST^X4DbD}T*rp5 zDL?v)?cwX>%k|Ol`nTme`~PF_ec-d6{{R2i{%^IiYSl_*X=-Ki`v3pWRjpK3O|2wj zTia@5ZEL%#m0^?=y;&q-SR^3~y%RzRAq*izi&VUaMF_+1abDMX)pcF{^Lc-NzuWD1 z``$itJDvN^bzZO6d7VGc^ZauzqkJ=X10AD!@S($jcV7-(L+jiEPNMgO*O6I4%U6&( zbS~WnE}~<)616fNiwA5$uiKec%*Y z=K*jc<+Wgy@`K=X%Im=Slpg|TQGOWgwf_-t4J}^}UQgH2qu?@H-UM!-`~-Lr<)^@# zC~pL>r~EW{2jxxRZIqt@w^4o`oJQY~!9r@FV;TY8Me8Jh6F&*`NoVk3TAl=EX?b68 zD&>CQEXrqseU$O26aIMegvgeBDqDy=8BLkUlja?PHjp*w^^Xr+PwSAm-5xY2*H9*N zaua1DbiMf&0ruooBzOzGe-!vIvRQs@~s=#yJs@EjMnK6_T*>q7?H!kIkXO5@yHK(7f<${sQtmuCC{p)vg?G; zf-ue48|eQCa5Cjc@My|76~dTaoz$aa5e=@T>of-J&G}gHk-Y$1b2xDScv7F6FKSb7}pt;1!h52lt_M#)G}SodEXUYa%$4*2w{jl<}lve?_1gL9DAB25ODA+JZ820ny-B`FuY2xS|P z^1y45w;&aPw<1sckCRjkZUdX(nczOiry`YtvyhWi4z58?QZ={|IZ1x-3gmT2bHSUC zlT-s$ z?+EtvOrk#@qPiB*pFNq3Et>Ju`b2+TMVU0*lhs6j_GGoIKhruyXWl@$JE>2Z=+E9B zMD*u%^toj3uKy{}Cq#d4q4kOWyp=N1pAS6aCrS$BEAD=?nu&9Z$xBJ=x2G zTj_m9gHs`okTGMBM*kAvvEU5K=Yx}IopIny%9FwAR0o~{_Vj@Z!6L0Q73_@*@R%R3 zt=MXhtKaxg9<0aIQk`ZA%Dwjw*JIlI2J~98$2ZaX#2{NkIRfmBK_uAQZ-~s^N$U`q z?dkMHW^bkCvEWw9M1HqWCi1%v#xfcy0j$z-?Fde%Ok{ZuSH_tphX*;RzXn=A3)6j~<%JeqO`ut~Wi*xT1+&ft2=r-8k7m;|n+tqAzE&N z_fodNeW(sizHt;!IVlz64rY;3!9>r_A-{tgkk=vkz{Gd39w{4q2>C7~ra$Hzu{TIM z6aDP*06fd%H1v8`CvV7l^5!X7Po8Wf>&e?w$a?bT1zAs?PEOW`XA_b2;q^V4?~U|XWWIZI zGZpN~w*FvmJ(2mlnbs%srHL|`FU^$6eAz~s%$HWm3^u%7lq0~NE}ewU&)Z)ZIFF*K z42}RFqV*%eskEHI2ASm50cTQ<1hbT*!1!1||cXzZEhLO#B>~$d@1ye?u+GE5XFaumO1kQV(zo@~ucc z!HGX2W(@8P_JR8#oeuUR&mzBrS0S%M>I>e2d_7V>@LuHGk)(sYo1{=%jT>Jh<^m#LmG6xB+=Hk_p~|ydB8~w;}f(f=vfbM_z_B1)PiA z?RZS?M#@AFTLRvOMD(!r$lH**fOjEJ`5FBKjz*q~)D1iu`7$J8|JESifb_3xaZlvr z{x^Z!DBlcjp}Y#51bwz0zuyTax@{k%yTL@~HIbfMi1~(`+^70_w8xKq2fv>QWpfeo zN~ARKdgLpR&H^_hC-nz`w}4xa(!o1PInkl&A^*T4I0~GKd@52jI1_mTQp9rHA9)K> zBzPP0BSs6&wjBy4O^sC@|5zh+ilgT!efTQVe(z@=Zvw;C0AbkmA6u4fGpq zMKJLt_W>u6^0zRKNFBgQC{vM=!5PS>BGrPkko%DqgG-RFK&l5XLB0uTId~277NlFi z+mR;{AATd+4_3huU}A3-Aw`07kS{}u0@otnfD{dGMBaiF1Kx(5!B5BgFbDpCO^V+W z!5QErq|V?X4S!q%Gd_Nn1SKh_vO1Edy3*ebSb6%E4_3f4-;N zk-gN@;mBU<>2_of^x}eK4=kehBzxdg%483$rA+ofKV`B9dhPM-I24`mhrFX_vygZE zUw;aQAN}CjI7D~wY@9w|&j(F(2hT4-{3%}lp9%K-DQRHOhmryI<}VBO{3#sR^QZ7& z&z~ZIJ%5S_uBE;b3GCU+8aO>Quzqx~r_&o?&z3jA-kPw$p6(7j?hl#&o^QmPKN-i- zbG?g6{YAS1YmUsNCdy*4@qvM&G0y4XeQlldS0dEmKTJ5hvA z!_4Q<-k6d$dt*)7?9G9A@GiQ(h>pCSGFh{pObA}HWDRO zGm*LH5xg~?ir>Ap-yiI~d&s+>QagQC1lW@UUBCxuc~`Latp4CWG;VPwIGxrJ!HKkd zE?A|^u$XU@Bfwt#BNBW>?t#5`j0I=W`f=b&%JJY5$_Zf4_u2*Qy;oPT_rBf0UOyy* zN7Ht82YYLz2l$Ar1J}|zr-RqfXY~Plwq;-N7FwPPUQc-lxP|iB;AYA!IG);^9Jq~^ zM`1yFGBCo2cc*otz&VtepdT{-Jvl(;lJ_oTE_v@l=91T+Wbg9Ei|iL(|B!Xz^)s1o zr#jC;Y^>v*)u=Mr3_Rc6=2lV`7i^1N02sQM$=MVmcav0+!y`lNrCP)-7GqTChi$!KD?da^rs{gXX=9j#CHY)@VjndQY9$ez86 z)(MsuuH8z@$=>7n8Oh$``5%L23b9+gu_XJDHy){AZ@mS}morgb^l3mI4FHq%+>YnD zdlhoRXQ4dxi$I-$;3Ud}z&^_9;0(%eg&pyWoCD6M}NT& zz5@2*Eo5)2qvd1|^Txskm(g+uOk&7u@VgIOPs@jan<<|M-b{Hk_z>kWU~j&T1ABYt z1n>b`CmZbf)pEf}yU{=R>=LkdJ|!P)qC5?0CO8{8GNuG+G`I|@6r4lLF9)vz*OAY_ zn`rqg@EXeH;JuV9z}qNSf}>jk_n!^+V*6F#L$ppcIGxt^n~<&suc74(7Htbj5+fn!eME2qxE49NX9sW*WfCu0N4XQYo^ogKPRb+>zLhd@mc@S= zxDW9gw9<0oH!x{A@f)O4CVqn=%H6?J!HbYc47~>VdL$AnZ$M7kb_ST7;o61Y&jc6Y zUABVL!0}(f?gI}5lXDh*@cSTeGIAeMI#@(rhBO%L>Ec7c@rk~q9F(68Za}^WX((aZ z&m^8s{1v1PEI9v@0CV8Ys7uNv@H)zWVN>#AIg!|uT4*_m3GJX9BD={QXl#(^QmtN{ zRE*0BbV4H2^Wo3TM8cz)Wyt+VWIt>|j*KDuVI#O1iOBRV$PXbAnZ6e}GKR?XWP09@ z$n<#1M5e2hiT;=Y&OstF-RnCd(-)zv42j6}^~jOA|Np-g;O$7HU^6WzGW`&^1&PS? z9_3wGO-a2oP5q+7wc$k!l|{ka}FGKTEW#GWU-5@{PP zza6}Z@+$BF%6EWwP`(o!P0wOAf)CO1)!{1mvE@&>TCXKVy-rsd7xWURvj_`QYH0V87~d}uQ`6Dbm` z(())US+@*+V!*kSLtlzV|&D5rv(DW`$SI%n_` z@eHP<9N#JM+>YQjTAm2@ z(eh5S=Tc4rH&N~aUO~AlcrWE{;O&%?!6}^s&+QIoDE9zQrQ8#2QceLc zqudKz3Eqm-8@!H|pAJ4uxes_J<-XvI(*n=x2TrDZ2DpTBDtI*I{@^u~&ji;|9sq8k zoCe-P`7CfsQsDjr!3^a=;2g^7V3qPG8Vqri#X1MP_hAExCoV3n4~g3~C+flDaIgR?0o zfLBoN0IsFn5xkXhB6vOJPT*F`ox!^(p9W6sLB|E$PRqN1GiZ5Na39Luz*&@&!6xPI z;4;cRz`2xrf|pTF0oPLQ1zu0NH@JcF>ENA|Bi@9pqZ|oN>=|fh6!-uwj|PvXFXc#Z4&^BDD$3E| zMU-Q}+bG9^*HexIN7L_##Dn+J@&s@uE$;wMqudd^gmNOdh;k?JX3Cwx>nNWF-b*=A*IG}@iLSMm@?dZ?L@X-L}y> z#J=_H#-ZR8TAu|cQs%%SWghJLQ3P-rEf>K#l!*Q@U z*w3EdaXdKVGsM@BE&zLHyeEQ53<()C2`Lkw6TS#ZrA+MVe98sj9PlEf>0m!CF9ffn zTnr{>q>(W*khW8v3Eo1P*xoIaiS50UGO@SG8DL}#v9S+Ot^_Ah|1q(R+i7`-T~vp0 zr}j?-*z=7=gH?KM3^<)~EI6BT95|D5Jh+l_0yvj)5_kpWu3)c!nB)9(UWok%XJyGp zb&Jq;%GZLYQvUcl?8%gOf@>&0em!IxALa}d$sR4_^8EK@7$Gbkr#1DBvoq-Q8_ zTla^w;dnnpwjA&0WaT9n2L2z{L!Dt4idm)8Cl<`hE3PRluJo5ylvn$FTVsLJzK6_om`eVM*$f054@_&4m@!iu8e!nyuD+@aX3 z5PWa?c-(eIaaCSXfxn>IUsYT%i?rf6^+*%KY8|)U^wOEfRz1%B=9QKgRm`gny=8Dc zylLPKe3_Y(^TtiD_80hz{Xs7q_P$P9`J7pKGf^cI{Z<-y8N6LyslT|Yz+X{y^4{~h z=s53w?6_oA%q%S&SySj6Q(TkB=keivHq7s@DxE&ZU+fz*YX+?l`ffS%D~pScR-2Mt zRXn$}c;1*<1v7c5U`UF7Pp$A^4AVUE9Yj(-$}Ecgzg<8@wfd2v-~;c=@5wRLi! z!X$TYjKeF{1l=;I-W2*-*{qxrOrs*NTSD5ERa#y=+?{Ya1=W}PoMCK@sPIKxp@yzJ z(o>=BbZd?|=C&C9(0WcBU2RmIiS5U@wDJ4%6$KE*vUi;FAWl{tyXpraQbrBk(Id`Q((wRvRu+*t*cM=v=_ zr+N+;I z@^_kubyQJaP7B>O+R)$yeC$=^SxbXM_+C+EqpJ%NA? znp6Mi`jgDbe{}tSJ@#(*`$H>)Twh&P7~X)8&r8ew zRiT#$kJprurQuHx9jB4yHOJHlxjzpRSL;e+@rL7Zb4aSBSJneCwAybKA&}p&(TJI zSSN+t-(TaOeoQZhy~B)C&b8{wu&EaEjOxnLa7!=b^Qwv&VbdUV9A=f_&$XST501Tk z==DVvVY4vo{i+JeXP&H&F^{Xm7F$UBON&k}Yl>h=mW91Qn7kcXUQt#URwd*a_28GeuQf?37> zii)y|@~~bH8@Gz%ZxkWVD=n)oo*nwqA)ljP=Z8(ckk891Dk?)S5APFy@vO@5C3Z}m z>Wc8u4SScOVz`EiimIx@TN_pnomXADAbc1@pXZK&{}}H|$a~?>Ws#Aps0_>dYyJ%jcL~{n&ai#EZjwBBWh~73Jjx)6reUVY_G8y-2;|+$`i?7w-U&!6Le_EGYiUypDk>M z3hSrRa?HY+#Q$;fcPuO@FDx!QrePt^3(U}y-p6ycz^8B$KSaQWES&+dO#IEKaB2s) z!LvWH>-~?fo#ZbXGb&&YgfuSr{-`tIpVXOjiu(jypxF?_zGFO>!Oy#}qU!SEsz7bm z8>$xZ#oBan#<7=$tV?>uN$)+W7(S$uiYoYHj&Ys_w_y@|qXEB(JG4jL9bxNWe8req zm0`jn_&%BQ3XVJc!F94Ks;lQ`7Wy-biEqDZI0;Ss7uWqa*NmtxJmF;_ee1PxWch#B zMta=|A9lR{px6B4HcqH4m_4WXX!sy_u?63M64o_wtewJcob1}bC#xJb7sx%s{P@KM zYSDB_kx#g`La!M!W|TYOk9%3jco1)S(eYj&v`v9`I7#K;ej(Mu+RqhnGkCdJJz@LD z!J;b7E~xVV)3%)Ag5dU$g;P zAMX`{o)PHFQ(X{t|IqPu2e(L33yW1n3u#o)bEZrzb68A1t~tq63!cA6`|>0g1mF8Ob5kpp!~#Wun<~h;AAAjI zk2fbssOv=a%1GQYuehoT@9(v`TtD>-U zR;7=G(-3>~9ueFhQ;2q*S6V)!0zuQ@Yhm8x6;xFf%+D(?o|hMBiFb$KdU<)}73FzV zet&6R#q`S%z@U|a>yUeq=ad$CcL*J0@_DfrcMrcld)QQT%h9%F56cYseRR-g&af#n z3JMW(4t?X`ws<-VG?xE)6f(FSc-Dx#F;w#i?K|%o#M1o-D%H_iY8!D}+KH-^& z5qVyVL;JUCPC3!=L;4_OP8`!-m>wrmY){nKu(3W_JKY7Ehmdvg%!;b{$DiXkKS7p& zcSaQ!>+7lQP%)Jw>Ag>!juA}Ff3UE-Us-Vyxdax*L zZPB_js)~zC$%&ir%EA5X?n~r=$Z_8jXO1f8lw%X3N3n=h2%QIBUy#wp25|Bo3F~F= zFiPOA;rAuyoe(Q?$A-=&OyU27^G+9vqb80VnKx$Ku=7UdjhZlV+_0Qu&pwTqSnRsd z%4b3m4co&qwQ5 z>#1xw@?ltCyR7oxl{@m;L|IPpZ(E|&&y)lc;+u?Zm zWcTOQ7rneGsSAFtalE{@9nrfnV#teLUf7oQz*l`=x4rz4Eti}>a^JKUyqw)}S&7+o zpXKEZW8!zE?!D}JFTZW~t)+k09WcF|_DY?XlfR{bpR3(}kq64z5ka}{kNych{O;w< zIhl*d@o6uwTQw@49IbZqI~Sf_dBOH2hL@9ijPGw>NY1p7BiHz8aZ=97%=x4LZ%6V# z`TuSIw$Xm|a{M7`_s7fsZ+qY4zE3`zS457*Gs|!NY%H?W_QBE^uF(AIlcCX3wn+|YlM zuPWrP?belieWCfzEz8N*8<_gtACs>?;`JgMgIGtNNX@>kvbzQ~(W4*qyLa^GFoP9b0E@X51YB>#JZmRn~| z=!v|pyxUsxRoX3AEgPDQyz%P!cjB8m4ExaKG)hp$7cr} zpBy?quhQ{3la9}7IzId9_$;L3vx|;TE*+oMbbQ9q@!6P)_F{a_rQ@@dj!z`{dJV>B z1|6Sw>G9iO3ee2VG#?D;3- zgC-vPBfVVG|GrO8d*g4?^Y|IkJ#&2d!r$)ui~f!xSH2=o8r89jJ1&LOrr|d-c8Rz54~O|AyQR*GJIn$I|N;k+0qS@6SK(fd~d)*OwDxV90kiFxihO zPrwX;`-aKiGL6ZM3B8K^mKj5q&J=uSC=dURWF~^fFcX;Z_~kcqVCaDc;O`2htl= z?(gJ1gYTY=Q8zLbimhVi&SY*jw29*>&ub>?`ax_I>s%_5k}M8^y(Q zUAX~VI>&P(xY681u8=F?s*eieTo{}jK8f0_S)-^qW;|HL2WBZY24ig2bN2&yn#xInmA zC=^PBDq*3pM7Tw`UsxwRDZCQH+w}rLIzc>1;`mRB5<0Nt!B6m#U>2>00SlX_a)J z^q90s+A1|myQBlskJ4g!t^B0?tlTR9E_YQ1DVj1v`B2%fe6PHr*6MZoB7KRzOt05h z=&SSwy-{DIuhZA-P5K7C-T2iZ6PGA~k#d6kj(c6D>Q`&jTD4AHqpnlet4(Tm=K%+c z*xiG5X_xkb{+`bG@V#VQw~KtqI2->D3}nl>9^z~AM)MwLqr>FmJDe!HiC@d_lj7v= z@&I|A{E_^t9HVqoRw>^oKP!TkY^Iof%v3YYEH&@87TK}RcCxWn;=9Di#<0J$&vHE9 zM@SXYgmfW8UzuCX*XhgkJM`81L;CM}q|w3XY7`r@ zjrqnk#!}-$V~_ETanSh97;8>6rqm*uI>Z08DRu~YBdg}y~^!FqAKky*fx|w0JrfAlhADOM@?^dkM+C3d+OW@s-*)eQ6+mBPYEN-swi|`KG z;kU1}m)h$brWtbwYq=+T7OS%r>|*v#_A&Nl_9OON_AfS`>x32Clk0~ydk$8u!r550 zGq_4_4!3~2np@1(bGLDKa`$p;xo5ep+#B3G+y~sJ++OY*?tAVh?su*;ebpj!K&ONbQXJxA>AnVRt6|%D}rJu^OOgaCzNNDmy|b@81+2#^tb9y>K|&9)=@iOo1-Fda1rZzeRspKd46=KN*9}FU_vjaO+y@Wh>I=?dkR{_RIE<_IYHiTgZNZ zKi$C=u`AgY_H3@4`xkcwe}S+1{d$3Pp;RgP(XX}A1LouA zM)P@dtGVC&-u&5YH>0c$R*Kc%;;dm-fwj^451F%=B>Bj;bDwaBxWBjrz8l{Ul3Cy_ zS2AD1&%_AV^0)E#LaIER#={)1S zfgFq=OO-i`jm0S3jh*B$*B?8_M|_R&gYcWsT|7fH#F3Ej zw}~%_JH-EpU8FS0kP6Tf4bs1*zof46S@NZFm3*E2g8aVxwcJnPm66JP%(ng-rw!8z zv_G^g{ZjpA<4N;1^HcO!g4NTivOcoDwf?dO*ou9=J;V0fuiBs3-`Ob`C!dq!)S!iX z$T;~Tm>Og{_R9O&pV-r}`WJC6+!p?O@pI)r%5TaV^+k1?`mXws`iZtrJ69j8U#35* zf2wyjh8mX`R~q%k3S*VgU^E(QjCIC(qsiD{Y%(^ZSH6Z!7+~7wMdo62s5KrE?gcy5 zS?K&oo|_$bZZGZ%?puz`lArnRf{oqr3gKE|sZcK%Sasv%N%Ab^Mdf;RuC`x4qz^U5 zaS1< zwa&HVx%m-fyI^A2L^hlKmHm@#=04&E@Pm0%x{NR#`uRL(t<&s$>|nRV-V~Ta zS!_Q03;PjwH?N6BVySqwxL8~!E*I|=J4n1#BvnXjrNv6N_N-QBEJiQxH)2g4@AbO5 z&Bho4MDxeUP1B2rI>0`JnuloT8kmoTDhpaO_tF%53Et zWwr8}GFTm|3aYAF>TpP<3)Mokqux#5qkpd_7~PD1MmqL^@z}pAjJfFBMaF{|yH|`4 zFq3{VU%~pogX<$)+xQ~(3Cz*=#699c@ipm7=|0Shoob@iL+h`dt;w1Xa&EGguU!Ud zceQqdwnDpCdq~@$y`WuTSmZv95kw7O?&iPauM{5;-w}Tm&y(jX^~!^gK}FgRT3`JU zeZMi^deHjb`orpJ_qRFQuygJE?S1wS4$~9?4HJGw_I!2$`w;en8Qfi5Gj}EAv>o;S8)r+VM`1bzFx@w3rxM425-W=jN< zi+ipXo)8M8%jMZJr_?D=D(9<3>OA!(^;Y!`^(jcn5Add6sGT4gFV%{)Yqh7L4a|aG z)XjJoJHBjQY5rkGSd*=PIk#Z+KX7(BUtk}LV5Z{UkFrm(SE>*{;zE_I)J5IbC~mZY7oorM|jhL)wwiFpS~G zg~p|rWo1USvA|evtTvu7-ZK)>V|kDZvn;=L1@^w%t$VPN)>}_m&sr~8+pG_*&#a#@ z6S}xF;R1UtR#YTWkC=1u?pLy{tONaFCO4a_#lF8BvtcdQ#68EoiZxxzZ{gqOi?GWq z6IKfU7GA_&`L?h__)Pdx_*M8zh!GRTZenk&!3ZT@IZf%I^i?jys;N=_t!>sK^f-Nj zK24tvY3CT4`J$O^a+D)eKAJ=E{uLt(D(z>COV|bCIrGtzzf1b=X0caLb^FZRFnK zyTB^RmP({L*dk5RHffaHBJY(CpeNeoL-JvHlqzV4HAA1IU#>4i`=8QZ!u;8zM;OD+ zF=n=TA*6gUcDA0*1m_NC3szPe>33fwa{yU9o64$?H%eE_cgs)6o8)cs=W=JIr;@4+#{OzR z>mR2~QSy{3B}bj1UIX1IT1(W@A>RtLQtdj;*3U83|jjIR@xtWypd=m8OcTp zR$8i&2FaRXu$cWSB&-h_^JpW>m}6WG`Tj5LnRglY8BZH87_VYC`v4mB9^(M4h6uBZ z$(i?AE9}koVDg^Xk*@ww0?A*=`tg?kVpp(tu`jUO*$>!H**)w*HiGMd*^0EZzO=rxeuciAXp_An z0~Us8tF~$T>`Z&Kon>d+Irdb$3$)X(ogbWEoIf3=GSam(quD|1P*#Ez8NrTar?R#3 z61h=XuY9U}u6+Z^dsu7N7(H5#*Aw+5J=WkH)nV!)UEj?gTz5W|PlKkJ!Lz&qEByko zK%9;KG^9P4*`u^fW085A`Mzn|W9(wP!d_r6f+li@y~cjbe#U;q-WjAh4{|uigie;} zjCQh|Z0KfF$+*`?GK-KgY&1L?iEI*^%%-q?U=f|m%FqL5vUAv4cr|Wdmt!XEghs&e zSMdv=4NQ~nK_8wYug1K7Nq$e>BU|c3^&(Z$Ol{I}?fXsoX8kjLnvnWMMl7>U1)0v(=v0d~|U@PK>|?KO(;#Ha9mf_k8wujUuP>+vbSn}0w&SI$-Qv3r)N zW$GODYIU*tFLj0bwEBYjs=6Kf=%?x)^?>>e_UC48m$qN~N&8FdpkJUDU_C9@*BZB& zoCS-yDUw-1UY}jXPUe?FKhz<~A9AI3FHsb2tmJHQCj26`@QW-H>%|pV(G9TP*T9}w zFE)uA#7*L6*x6fQX>W(+wgcAoF0n=YK{{71R@NvFt9#YQ^&j-!W{&xxm2BT;-wW;S zQG0{^vHgYpwcTp}WdCl*J6)Xq7@=WgOtu8(`at$J_CEGCb{IDvmL{68|2opa@~Hz=Z-y+;pxC`tUW_aaMAx zxks?;Y~kMGK788WdULY=l zth*yo>L~RbZN4_}IQz)a{Uh7RF{Yw#Dh)q+rWPKU zMbL1U9kIebv%j<%{9n*~Xb-V@+u^~979_zDMhWAv1I&Yzz787Et-_s<(;Ef9yg=S4 z&(W{YH|j4# z8Q0E@a`oubS%uAoty9Fl#J)#&r%`-1KN)Kwk1ygY(C@YIx-?>5oGxsH-(sG06ZFgh z@(_8llB;~D_SF08S3zDjLxXO0ekc9wi*kJlgV?TOinvTlm3i5bv*e598FDY>0%fVP z9~NIXXo`Qq21~>`UJnn&`|wcghn$Ucx;tk$JY?)NrwBISGUs+@HEi>Zu=GEI4g4SM z3wTC$6w{83VLP(jp;HWDhhtxu%oelPu*={zehNG8JMcgK%qDTE+}W;fHifHz$LTuA zfJSJYZ*V)f-P{lGFLmI%^Jiga@bOdOW4Z$Ce;HrTuYh;Bfj^OFvL3#iRYHT%2p@2( z(1v~Uu+Rg(-R01lGE`AD)v4-g^&#~M^=){Sh&G>K^|A(9g5|TuVLxoM((TjWhmjly z8d;8$=af2r=PGBZbE|WY^BC6XX6Q~^oo(=#Hak0@MeRcGwmFB$yXQx_{?q%|^?1)` z*f-f7>}Twk>^E#1G||7{ITCXZQ`s|1Ti@MQBm8;SpP{ZPH)R_v>dH zcUuozTdjAXTYd%G@30kRcY=2Ly#1{`6eG4D`*sww2~CY;d$Jkq6m}L@&3z7EZ&%?A z;Vj`?=zE#M1mPn1b;}`RXF;=h7gp-I(v#BLuvCAQ66OB#Ala73$P+MYX3Mw9_rg#5 zC_JUl!B_e*e5GGQBmD_JabgX0giW>tGVw1pRhzEWY2RzH(6vYCm*{OqXLF=E*_>@& zV=jm8++t3#Mqt;T4gbPo_+}r+ym}t}yx;lRX(xSK7vFz$4~UuoJ$9J|1s% zv-(=;77u@67PU!=tP*RpwI6zU99BT8eYP#wqwH}uQy)cK@yv5v5B?ii-E*ap=z%Hn zC32B`y?hh;p+UZ1ei$0?YjUF6pfQb6uHSy3xKZwb-HB<6a${BHShM3X%C~YL9*6btyBTAhX7#aBtu(YX!(uJbQsE)Opg}aNU#j1! zf2%{Zi{M{aqpgF6x*gW?P-}_9v_!f7f$q@jMzI&dCb)@v3YK6iw~Hq_gDK{VS0Ik^ zAv^`w;mz-nACtEu#;`~J53Djq>8Nyv{y#(+rF@HBH5u~t8HZ_$a`iBQy;8ak@szs| zN!cNNi#STG+)F-JR^;>Hohz5;%8TTip>s9Es`*2X!o7OKlHlM$I!~FTT#VgrrE-t* zFgy!yDSMSR<*?FI?XODk%J{V_AyYfUhO2-#_)R?pcJj-{o5ou6BIiNp2{MNeTO)qR z)sWc4itUOgSDJpa2EO$=SdZ(>^=6Z~!Q2Gj*Dh+my$QJ-=Ztc$M-Q)e{%{!l-!O>} z`5wf)I>38AgR7Is{AaXiEgqIll9sIf4*!~B3^Rt|z75vL7Lyw7#vvNH*I-Gf!Y`SQ z_0Gco{T=MqxAk+$__NXO{J5TNgAevF*Um9~H2;vgM7vo#jkMht?dr^zb30*;wD5Zo zRcPh!5LQE%dqS8XUMS{4i>nYF$dL)~0Ov_Fp}WdhsiR<#?UTR9$ZUk?u|->9t+E=d zMr)0=&Z@Sruov1l+PB(*V>lz6^PNe~#SW7l?arep=*!8_m2YJm*fo%875pDUq?oGc zN{%v1*{W<)wkyrb4rQlOr2PcDEz0N!pVM{L2lh6|MYK6T(B^JzIV5`=tjXSp-#v&p z-Lt~W!g+|uU4mHA9|AS9H;!zK1Fb%>ZLbGr_w2o)RHgTYI4kCd!1+^wxj+YbVBsp15k^9K0 zu2z#Fv$E*wHaMq_8qmUG|-%|%S9NG_4fBnpE#XJY@%pz$M{|fd-n`lDNIq+cc4L9-xbvl-l?Zj3R;ZWjH$%(r z1fTjcv))``u7Y>@GuJ;CSo=$qf5Q(y!MGe!={n;E<96d=;~Bi&$B3K#Y($&g%roIP z@R<{^XUxL-z0thWd8s0NZ15(_;Swg8!{(Q*kqpHtL4b&#HD z^fb@JqB$(Y1v40iu-yUS{H^sPnN&#ZN{Zv_fLF=cN!TM`5MQbd)s zW=o8_-zCDA_%eGY{GYX)3EMFqI`OMwA1QbzS}K30W@|axR4o^gha#;+E7Rs`Ef)UZ zx$ArHA;m%3cUA|ex_TK-DqMBsl)?sele!sFWwLfNX6X>41pc^v#yMuL`Jnl^ImEge z-sd*xQ-`f~i$U8HowG1QnU+BR-GtZ!Ctc&(rc7ImyPnsIm*Ux)dB54ia^NRkYBgI! z?R@(>`0_r4<=Tz(7ZdCD^<4I1oGbYSnn|Wm3%&n2;UghUoFRTJ?iOYFLHTjHFZ?FI zLpH3{o;5eytH`zZ%S0spaV~o`ym)URme3hH@&Q=wQ=m&nzbS$|MJjB$%Hx7Zvk}b$DqUfhWJEx zt2ZJPNb{XD)DHqLeY4X|@wfbRmjEwq3$a6VuX>t*6unt3DeiaPE~Jl%9ir@H+H?-m(Ud=45%ATma2`ll%!Z&!1h3W2iD+xmvki zxl3t;&D5+gYG3s%Ra0$sq*|`tiTKk?>W8l9tTST1<1yZsX%(1j_e1yn29h^M@1S=< zB%naQ3Lc_+;8l58-wi*)(LTQxF~v6!arxT#7GCClki*x&LwTpU8Zpz4pf&DAv@gQy zgkC?MrtU>Ph?P-hRaz^odvQ)-n`^HPL5yxRERAXQOhlQlv2U{Pve)5!z)pA~T5X&y zaXL83PCt01#yS@`Qy}4soXa71=R0*Y>i)9x25eGH?Ce;k4CBSX3T=iDsTIEMcC7z% zIDyj<2Pxrh;@*X)tpz&K&(Jh;VTYEx_VsNzcl9{GnSTdCmM#QEOW3?L*nP^y5{b5s0u!^7&KX1JWyYE*^voC`8?+V1cZ-bBd zbF7MJC&B6A48XaJ;ZCJ92fmM+od)c7&yl{)k7f3vuVdJ8IEQlu^yF7@CT=(T8|?j# zTncv<&efE`yRn$NmD|8=f<)Nz4>VHGCoaNzYvtQ;e&{guK*bA*LXr@!t%|2SomB(r zSSKt(WWn=_vm_8uP|D^1rqyd`7LO^ zAH$MNRJtm?5Q!fN@6@G;!GETFt^5R=ucO)%^X6P=CFiM=pk-Z-81q8)X7w)hK}4Bf zRNqoR#z~wX5L1mqRNd4jVlI_xmGBB)4Y~fj_P4eHC(h!HDeh^rr8tl9pz$2Ez+3G* z?Phxi*4!?;#omjPIj!~@_)G$_eG0cv7>_8Hjq6^)35ns>7m4hcSynZ%}B&apN7}^1H`Hm;0qm!2=!Y1F~siP z)_*r5vFGPqR{to`}pzL!@rR( z*A`yru-1y=40gB6KaZ zNxvw4u&#Hg8sfa$a3aLpC;e89RcqB*i-LR?>#ZhOj+?CQ&<=MXhPlgXvG!UAtX7O{ zoa^J9>PGf{K_6`wJ`l#jzv}rCj#}^Oa=6tVYONn@rJL|%mTDxd>_+aBpki8lKX zG}CtM($P*l{Ku(I8g}ZySw7OEfp{bt=OU-XDGM3rRoG1$$^1@=bK``Wd>Nu$se%qI z=TA9WA(6gC+7j3`_3+iL(i#x!T7%Ks47m|J*Swfl`;mz2v9Yge_~TATR5i!C9;ZYC z@m*-+h*iY7v4Op=Uy1BEwlG$>5Psl#Xw@Uc^Rf5OMV#wwSYVT}-~S;esNK{N>ZNL9 zkR{LpJ)7uLJG5W4M(C?A;rz;(h^&xPhj<1X=h|26`1OcoZ9t?GW!Z7A-aHN3#RuZ2 zVz9?24UwXwqq9$E^5fjI5%t{dT=0%qi-`9x(!b>?N}+NSbicRp{Li$7(B3xdufry4 z)!T69?XcdiGe$I`v(?5G#zNyIoMAd(^n_O<&wR#w2`A8Ynkm*`SRAvgwK$!DwpGTt zHdY=^##A6Oc0Ko}kSG?(gVm1O0qtz#8Jw$R>f&7g#7b_Q@SW(Fe^4IKh8T^eKy0-7 zIHncZH8^*>4so3A(3O92?OF-CavtaBmU8!SKk|EoA<%ux#5-{^wu7We!(idQiMg66 z_mv0ZRI(*sEMEqD{95^T_=q;ZJ48-d{0IKgIGnf9an`0@c@}zW-s)|C6JeQx^pE5rvP$ci51x;c9~rXJ+;QJwGWf|(-`O4uSxJ1ZeXJ! zMfc(~;xxo3YOv@2ti7y%Y20ldgjZ;QT|w$M#kqdeS%|yefhYvaj}-n8DkK?ibsAbf zUGHdCTbJ6UcD4P79p%X6nk{jz|D`kA3*St5h<$?H%#GkP5Rd&*`Vi+EZ&Qb9iS&F8 z@t3n9p7MtvFZMt_jI^2NICsB^W3Pjy_6X+TyNKuxlJ?1!>WA9ZIM=n*UPzwT66gBP zCSt5+az0q|KjOse-D0xbNgbf4n@n4r>r-huqSy?uY@hVLS09{89+`DY{9v&!+IxUj8TB|EvwycqQ<*x8`P)c-OY|&bQo$cpJ~Xj`+?XAy!I)Mb!`AZx{oc>UW$BV(e%;9&wH& zJK0XL`yk#C*pWlee=w=>?%0mOSUv%{Lt^YZv@fs*e#GgHB|%ZsMrbVPH#Xk=j>6Bv z*{~hsT|0d}+k|d(Zuv&nUNwKZ(DK5z=~`bS!}GzZ`MzcX0-@6V3?zZ6xDl6&d*xMM{>!|8~25kNp6= zPfyv;+Akr#`7Znkm|b=8?pSwXd$2bj*+~L^i{3aBgFo`?`ix9r1mxlc&_42n8RXl) zO@Z>Q(6lavcJ({|H~*gfjg3F->&k`qao(f9$ijR5gZ!ROW^^^?U%cy=xs|&Laq~y` zb}2&c1g~2HPRj06zEk?D=R==;0Q+E!HWXSbIXPa7=viP7U=7i+p%=uvvh-pjA2IAX z@B`pG%x!^rVzVRJEH*~$fYS*nIH5EU)|)71;ky?(u1`2$$%AxCaNp-n_z*rdcEgVs z2`g!=$s{GXW0#Dxs7z|0&O(gE3TO@YE3(#?$Tc>>Jxlc)-$N*e|F=K1^D1bdML4PA z$2V9Osmt8x7az5wmN3A@)b@Nm2h4KfLu?ihV4P6n1iF5M1a=Oc)R zeGX0Xpw2;q%)}|L97O168s&Ju-Npf&3{AAow1!xt5c8Vso@E?Q&a>ilNhECJuFi!x zOSqdvp?wMNy6gyVMJC&fxO=vEIZn7-g)_IGihqh7r4;E5iTLz;%KhZCAzxFJ{+N49 zaW1nFCtB9w{8E#$LD__u>z0r>$6nuMhM)7@GkP8#>t2jDEpEPQ{UpL-7U0eB)lGFssIIe=5#!7@8OTZWGyamzHH>~%pj&?Wu4EtQ1IZATlSu@GG zN?%7;*Uv{Z^AY$(UWAqYH1{GG$#>v;;M96&p$DSg1;Q+7uM5PR#24TJ{#1M&wrL_F zJkUcBUzvunovU1c$n4!%osX)w!CUu*_O152_A%nPsgOXX(aV&~nTRznG;^&AMA$YU z8o$AQ4&Om}1D2(CBIsLprqcYxp!BMBiwf(3^)vS!xIteN00!5xA-1cw$% za48bpAyBkPDTUw=DApDU6t@N`Qlx?6dOpuHfkNB8-}jue|M+q3tB}mB^~imH?Ou)& za~JH?C3Jz0(3F@gE>v7q=}hO?lTeAjvd;ktdE)F0+A#&JW0-5a%MhDW-ks<0CKSat zQPVWsRKcv#<8QXCRew;!sVP#d18m*3e)P?+v?-kPOF$jJ1}|9v5}PIzLsYg5%r>m% zqpqda-wE=n;R&k-2a*kSUj?+M9jP)#Iwm@1gPvuEhY=lNYi@|;tkyl~tB$i~AEM6m z)pflRs??_F|0jc=ZAUkI61@0#{VjZVM{2ME^dozy=DoO|@}pr8h-Dp+nK<`C^nV-O z+uX_cFkZRyMHfd`=8CQiBGwUIMhe^`j7L156I`Yc>ck#W?>UA3X));f2Cy(M+*!fK z^69GJ(Z-qJwX4ydY=bq-fZ8M$rCFlsd()5H*QwIK^~Tf`)#oHsnH$W>C_k^5f0xg` z4m#M@toL51=DxSwMJw^vk{Jznpc<|gQR|@Qn4-?dJGcY&gy2{FIC09r%T}<~u(p#` z-EsP|tCFD&hUe}|H8;#Q#x~hD%eDw_%5hs3&07o63WB@0(|U6+OryTrpe1ShwVy%B z{?Hz4_3h2+NxIql;)>cJxsO-&j3Al*oEZhtyT{{1oC!X**>S;fi@P!#Z>0!&ayuM# zGpdZPk|#gKJ#ZbCA-~?3F1?%H7aVz{F80Pw zh#hwUeBO$Rsfv3bc=B}jB8ezp0Tp@Reu}p#iZ|3Lx)=L!Wb{PbLA!ZNe~Rvw8ab!I z!h6c9f7R<5}zN;^cBaIWO*XB!AngMNK0P4xYrs`HAb-hJ38wRGuWGAq!rIt0krR|n2ARbTEw`z8)9~yuH zRM|$943n+%P#zoyvwUjJ2=WvH_f-ZJL!FO)G@+ZwjJGQvw_|Y-5j(!2S@uP^Grs2} zxCegh&l4{JD&htgX-)t06RPG5j!3;ME);=$e0Zkw={TP0@2J`Q!HUbHiSOqc<@%bQ zYzeN7y)Y&l+*{py-G`}9&cTy4!0$69dNvv)xQ4`>vQNx}#wr{os|%%AZ^_XoQSBW< zUv*1S(HB(*kMD}6e~7V^sRF1^IdgZAf(4u%r_e=Z1np~r`}HqNAGGyb)Z?tr%<$MI zIO_@4$JRVH!Gly{{dgGnrjBpK-LNsI#9(5ShVX|ir9w?;#yx84WmM%Gm9dt|s7M!p zN320Vx|Or^AWF>)|KPv7!NuLCPRc1Yb^@XIg()2%8QVmC`6p_OU3&6=YUrDa&y$i< z-c|l;h*Ui+1Y@`cFBrux>y86yBmBTqx@ZS(9>EM8fW^wL`Qa34j3;FQZj@B5EH1sV z)F!v>_wB-k+RE9^IYQsTs*iFtbIkzX%fY#`41L}K>aLu!7GI4X;zLC{gp+v^`0jjE zli9h=^P^fTWy+))(sIiB;JG!xmem=89I( z))J^%)rM*x5cLGyqPeYwwZZ6G1v*&8F~u>$Sr!KPl0MWOkG5~TdlD6G1F?^MbIJE| z8!ba-oY9H!Dmp)_fU2q^)HUiQ^&Y2BQEPkaZQg8oDz*;XWn*j;9LMx#t_I-Ui`+Rl zMLUB`tPwvi()06tdAD7SRZV_qX6~BvqYu7r386#n!82}34{G2hyrqSL)IGHq1&{BC znzNDc2I+k`CEmG4x|L`fSdl@=Wthv4b+SH>DV5-e8k<_tmCQ5GvUF8j(aHX!w$i+` z{|Uv@Q1O*RSyoM}rNw9sQS|-YPYsq1>PcDxU6lu!7)piJ^M|Z-7jnzK^BAf$qno` zx${3q7C!hETFAODm+X6AaQiaVNuUmSGq;PkM&!sw;Pi9HaXOL`BZmHNh} zrkm!G>OE@@O>~x?r!g80p67|o)fRq+*KC8iO~$!;1VwoY{ld&d6_^ZCTB^FRXH=}{9 zhu6O^I=3mHmfv!xAEIKush7p!I^VS&m+KRk53J)1&bjZoy-&e^JOt0o5gm-C#Dc40 z3L0%x#F4qBz9S#*iH6)dSHQD$(;wy=YBTFaM=Yp+7rbe4QdRxNS;kevmCPN+XHjy? zezOPu^8Uub#xgi5_v)=(hH|;(T2C_ubC+i^e?d2~7BuEB?x%uQCk*cd>j`Ta&a3%! zi2R%w&)+{zjl9Qn!xDsVT$k)ncle*x+GeeVeSzb$vyW>5+zeWe*xVB9=>u0a!BQF= zyoJ=Q4n?&&4dvAa>vptOC#;6V+;Z>VHTszTR9~V>3`D6l294Hil&sz;8pCW8ZFA5b zuC~?T#OXpMb|0^gm)#r1z+4=fEA0iPzp#?Su+j65vg0vXuY`aTWU`p>19rl@H6K1G zg`d9@liDJyRI=jLpx@((51d3djknn^R1^OpRQ+t|qBuU^45 zy2BphXyV9--zgZbsHAR1$J`oSRTSQx6YhKNG%Bz_5a|Nw`)Z)>`;rr0s72Ru{_T&x z9(~v2Gmr6>YsD8`a51GS_(3e%^DgObslg!W@ycHG{YO!?2p`mY-c?sL!UJIx7nqm9 z?Irkn*YoUls{7TS)N|woytLIuuObk}F7(Lp zyoJf2;|uJ|?7N*#cLf|nz0nRE;=JX4DW$m4p*L3ADLuK-{5ZqgX?@`ef7I&W)+_C@ z$aBtOXehuWtIuBB5MXNnrJq4>TSa>{=O3tL zqFfEA%J<;pstJpo5CT!!C%$>Kt#KMhY~ z3o5mI+7?vQ*SYbg^7Ar+QC9`6tPg6(_et@5j@G78_<yPF#&YIh{ z5`BRe>Y4H=InLtu)tuq5|Km~db%W(Mqu%hPkM7F~G{|dtYm}gTQcD4?v zaW`thjmCYbQ8SocvVIzonX-xAXDK14Zc1SBk@)qpgp?+R{g{@5tVH- z%RcoO_*OJt_Gb7AhQp#~p>pcuobTL5n!qrZ6+h@UPnJNWk30kBf{0&+HLHNbr7S9( zAXda6^(%DS%jgqqoSHkpaK5u2hezKDVyD6#{N+^i1~`y2yM1t)H*&Ye)ihV0`#$pg z-L9C?`|bk^ss}qc2VCWZ?Hf+$et7zB;vF%R^O5!IapjEix4K~NM41+c}(u3yLs@R9dbZ#wG3@VM(8jp+(_B?+E?GYdWZVeY8LmUvJWhfqzk z&wM1-XC%dF1RnP&&|AYs&-Xt}!q6b+U4Hf(S5hBD@sahz3=o85_GKtqd8f4kZ}4j>xy@7&7vbGAIa{JopG{Z&ySSrM zedHaH1@vyCl7tq;+gQ+826x?g<84wite`(l$ZB~&f`^SXpI8!nDv+hn8{O59xchEe zoM01OtZO*~PNO|`Xmv?D=&c#jeB}Pmp>)NAF&(YTVHoo?@RaJN#wIV$^0t;Cc(itN zlH8`RoTS#aov^KiFE|Yg&Ue8P5y1a0(tfbdM$ZYGz9!vi9{tQJke4l-z30@c=tb_Ue{niyK!xpt-YA^DwIrRZ9j3dgwGP^_ zmUKGZtixUV#2SqBm3Qpd${^!Qlo0JrX1Jmx>fWsO?)KyO`s<={e&fmmtF>FMSzmb` zpH;pE^|@{-ulE1{soH*mKl_dK0Cm+R@$<|1%JZWdci=R2FsIde>F&A1&GDMdoBU|j zjA&aL(bsh0mYPJTx&+VCk03rGVaAIjoV?^4R7Ann9F3H?^8_z*!CoHx?JRz;M?$qn zt>k&$XQ;rvNv6smv@Ef{@=UqOdNjZXZBzHE&3V_tchQiW^beT7ETj+B7CcUzuiOKH zrjlaK$hs*TnJ9*MU%96XTk7CJ-U+IH+42|IL0)i_LuhaEfxt;lFv0Wtzf!)Y`ZXIH z2w`xduiWQ(a22dJmaxoH7oyqOEH$JbI*|$XagJ5sg<+i6r$6yx+@~X-L8ie?PK_Dl z!&HhUp=YD7JhRS#7^N!h!0euxa+$xf2+XY&-^&1oQ_@yht4%Ky&+pkKvxJI)))saa z1F`i+kvbJdXgyl5!|sUaqM}z#_PqakR6sNFzN|Ecf(`egpYF@IePGek9f!5li7kiit6r2Z9JOsJRyIZ-33r80` zrLR2ex++)MMWaDnrcz@Dsf2PnY>vvfc3#6p2at48 z8Ajtz-o383`VTBW`mxs43o*V*gxS!apwOC+~xEXg>dDRL<(LV$a6-$^PI3>nt1C z{8&>09;TIKQhciI^0t;ni~1#8{7bY1%jsYrQCU{ztY1Q3nlU;Yb$&Vapr5SA0;sM> zq0IhWd9C;viyFI`2AF1>g@flX9mzRsAzQ4i3z*dmRFg@zuCQij>|>o%NCirU@pY7&nYv5C27 zx>jg3mGvt%$U4Y67B#_4YFWXB#iN7%&R)l{i1eRB?&I!KuolT+>^zTnKdINROlCw2 zrIXS}nZen7z~W1n(}(1#aoknHrS&tO=r^2LCEx+K+xPL#1unYLvCVNEr?M{@538L= z^!%>U|M0XmbPc5T8sX}WCd!cDSwjQhjj?X6%pf3=rzOm^;Y_Jsc#je<7{H)&)17$Vc=TYQcC zqOXvQ#b?;)CpoF&N?x>l`%z6lHD)tKaoScysn^mpgudekvH(hPCtfvY$2Z)XTe?5q zyWO0)?=3BPcQZM`U!sV9Y>kAoOoA`Chh{GfPn;b@HHQ16mv+E@0;WC#^{`H-*vT;h z{l{g84;eOXeRg(E1y1@lj;w0Ds1?q`dYunIr^H!s605AI>3Ys zwVkD(x@UVPPw?hiM=jDZ2c%;+w?ZEhZZ@IXt%>i^Pu?lD;8@J^-Pv&pcCqzC2N*yf zR-OEW+1h0s60032oDaZD-qY3ik$z|bk)KbdUS~2TvP65M@+~IMQ$KnCuYwQCNkoQ&*PG>R+8~IUZZMPjp%Y4K3$oAfr>tBjPfl*Gx}Fr#v2zalr}OuXl;O$)Wd(gqTeA6XQS(2yR002~H6IYsTAVdQ z9rJN!)F$_92B+C0(7zB@5!WkMF!-z?)?eO3Z;S`blhxa57wdIv9j!A}NK-1d!SJLz z9f$a&b6qc8OHrDa65l`0^Zg@0VHPO0$zj-Sx@CG`Zbkhu5MSP7aue2)LvqJHA9q;; z6db=hi{WrSrx(Rtk_Ka1fbL(o2xh|_6^l0WeQU7xCh^v`ME@uqVSkDYmw3e%PY%N;UF~X26nsi!W2h0b0xAqfK*66ZdPP zzr52oo2r=epjt6I_UML<{_;Lvs#HP|Y$XliM@MDQt$}oKhGc)K88G4nx8nQGVm)eG zXm9CE(xcq7#qUk={P!%zDD|>d-EnB6F^Q>mYX?tC8z`VF|)S6U9c zKXp`3GD#Njb_{xPl9$@(y>Ufe5#Q60N8UR>;L11;QlCe+TBd(f`#N{^_iRbtpeYAWihFWVqwSm;QQ?&W^ zLMUfqorPc>zt?x^-e4HNxfIyh${-kg1m8S{&HV8tjOrw+jy^cV6Y+gyCso8jH@KJ_ zT`%;WqsW7q1B%aJHnd!WO;Z94Cm3kdS$_@%U3iagBe%ek1+fH};%3lMXs6kuB7i9UrHE#jd}mN4mO62g`YSBLhkaGs#WWVdBT* zU%5_>VlAnI=|J`I1CG#>VhxnbV>rSeA_J)p-F!T|a~ienOT_{=m)(@lRMcc4|FZ^9 zbuO;p`zGPp>Hvd07yRl7^+;ioOp-zEe7F&(%Uiq}p5}|_m1A)a9L1@TMs?PX`ePL} zU~YR8`waBvkL_OY<4s^Lg764ThZB0|w2;g&LEnsqCslt8CN&5I^Rer#E1O#=@1jY5 z8b|GUmZzKrjaOT4pSe__r$J4)17q^YyE;NCj&`6NsX4)2>j~gWm-s1(@LDXnGpx8X}E{fn^ zP9@{)mR00D53`N571HX_lmATT^q%_mIw*oKD5aakoe%uS(0`@MBz}_Z8Hy_}3N-$( zr%#H@Bk$5v#$x1P)uyj*kESFGE}1H*NIKAG?Bv!fOh!UC@VAZJeK~B`s1icRQSRaB zPioz0(BuVZJa#!ExL1qn9o&D3_Z*)`Vjnq_(zv}wn2TG^vKPGg#+R&>*{fyIGF^lr z?Sw95vGY%KVR>Yqm zYAF6ravs?m^`|R(s7x}BKp%Ok)hp%HKT=x=?z*E{4`hAf+ zY$bEJ0r#@?d*f>_j6jTH2IKO{JHL#j&=;OE+-=mJOP{|8z+&UEAC-5W$qQPo| zi$2L2qDSfFsa0FRQB0D#1xL{X{EdCJ;>H|;V`CN_WfJJiS*qD)obF+`5@T_bByjuC zSCsR7_dqhe%iuda!=0Fq%&3WEa~&g9E{8cU*;S))bsizPtSS{paXR(6>bG=Zr>Jgk z<2lG?jevQKCZ%CC72jg(kKFBl!H8sm0~KiiDk{h?(Qf`kXLcLB@;TjRHoAlcob!vw zGZh)86Jffd&_8v=VPGH`S3|4WmdZGZ)BY^zj_|Za<5lj5@^2w1*+X$!X4F&ITn`6Ir(-*96-b(g^RI#BM1{n5w38f7mX<5_3Wd(rV-Le=udoP&z91laXAXq8U# z99DyTU$qv}D)8RCNTU>tqnpLsb6naUmab8R9(WLMFWZ2DAYUsorM8x8$TM>qaL$05i5c-~R}EDC+7`E<4WTe(*vQUCX6Pem6M{H{9dNzgk57V2BTp_lZS` zCPAVxU8QFH*}NL%V@~EHbOkRN2}?QBp4Hji6(*ijg6F+FP@X8+{xLg%g+|5md1i^| z`V+vO)}g=N2b!@2A4@G*ysjjB3?yA`ELxrpoDGA>Y#Tw3x6HXhzfGl(giC}}eENt0 ziCIUP3Zb?B(xPiCb=Vc|o`Cc|WR!Bt98CgvBfkGG`!8^e4`CxtI-2N*#krRpAbGT3 zjWMR*P?^+$_gcm`qVnc$2mv$h%I{9*sk_lq9MP-7xVA;<`;}`7HQ`eC0P(w0JiqHa zr)CsxSs%`nCu$j3+^*J)_6#IvBsqgbca-XRmUVDw3^bO-9kP|WyDrc2mMzS&(b)|> z&;#@n_uSv&wBzTd1xW3!6;>yYDFhb2n7Jxm1i`;MP+hl&zc~gjRzWRBeswi+R~OsX zpkP1FIrI>|JTEHJ|4lpfe^LxBmnl&jaX5O^F&Y@#c~IL>&atYf-K*Apf)X>o?8{*{t4_hP`-yMBn8|iQC>>7PgV+N_(X-S+P5Fi1IC?mf91e9_@3)mUVD3ru(=psq!?av3H@-stdrY9LP4+6+&4o!4?`ykb&jX$xMZWA@ z)QH)^CJeEGGJ`B9NXG>_j=ZoUjlh#9k{(irzGFQq_#ocj6gWq3R?Z@IFv&jKxF_zQ zZ;QYqT9YK)xwhu`m4}i_F@rAt0C@zrwC7qjGy)~)rmN90)n&DR@5s&hf7jK={jIwL zzW%%7JH`ddwJDT0ed#Qg!UK<`=V?MN?+aGx8tW*{h9Y$n=$1D+-Vxj;bHSlwI9EHn zx{|F%Qhj`&kZ{u(s+2HKlV(w&qMFKIKh|zPpB2WhRcTLA-bsR(|BW|Mn_*80=H7x78gg{wO zXmoGAQTQfu9=ub!lRS3@e6tGu#3OT*+5w)b8$OI@+BA@7f6l=;D%viv0kx_3DvS4& z=viAo;&TX+-MyV6jarT4azikYZwUGfQei>6%wX5n+bu#6no8yBE_@8?qlD_IH z{tGv`QZvD09+BVG0dGMHHldJm-=+ToK5hXU=e;SOpOJ~% z-%j>JGZHRekg-u1yx5H@<%p>jZ*3HMiPhF$=^9^H<85^{jjDJuC*_xDCE8K11<5mR zyVBb@n=UJv6Q{lNYv*3n6lLgcuF+N1ah)R_R!28~nO>LQiB`T1ywN4)nkfhbVFdcP zY5ayZRN<38VQ&667t>|i|D>M%{08`^HuN&Jf=3^kraej5i2j{=7is;;1#2*qYr9?zNIbq$3WP)k>nFhq2HK~XMOd@41it#NJW)3S7MOFG_q42 z*QF}&0W*8Z{FXGmR@SlB{^%a6fSX>XV-1IO&Q4Bq2gh0}tLz|K6G+tgf&F$z?@qsS z&J{p1M=BYngTJO*{ISEhM~xv#brcoMR-EmbNc^mdmw)hoo@k@#m}? z=1ukPuy0?H_A-q+bU8ZGJtXgnxk8W0Cd-VUECR)<9rUgiU6hz#(wFXk3{!xXkif7B zMDHlxn~U^7B8}G@EVvlj!V2&OEm3OqCQD@kHN!Xbe!Hc&@&@R@Gv1#sIfx~2oK>Rw zY>g*yFkQlQ>d+O!W$Bw&*7=)^8tLVaO^r}zpX0f|FpmTO+d=9M4<9D!(%gn1d%>Qt+6Rz(xtvdZoPIPPD11fcMfu}- z`$MoUN?uu;27$x&Kvnj)k3Wvtd4oTuGfkq8SYiH&bD<SIMqODdXkHAk-VOKdR5TN4kS$u1z`@jAneUU}`8%oPYt*yUpz9dSI$cT1=nB}z z4&dkfoy5GdK5T`v;IZi$wP`QyXGdlx9Mb-S8R8(xZH&DvKJzRtZ&xWCjr{E7yz;EhZJcE4ZfQrAA3!qq5R@$`;9rkyKBWGahY9FN zM>my|X&H#h4bJ2mXt&ndFEUf0h29%}W1hYd@6jdw5i36ozu#oAyqD<03~8S4SHt`i z@7ES^r!t_omFzC3g*Q-F-zju>AR0p3G>n{QkrOJr1Q73Kbg-L*>Wx|^Sk@mSmDhGdLa@{v%qQ3E9s7z(naX>D?RV5dKRJ#&6gZ4X zK7lwjhN0Omi?atc3hz2t;_}m#%*Gs?ti_C{7bm24v>=`Kwlk3TAT?T zMHk%jA`#{keONZoG~t%m#;tJ{FO^Ig-xzEd&#$PVw5Gon(-OCWB2P2!Mw?R|4NgaM zKc+vN06+dq`bxt=TzZo4nZW)$j3Va`a&s55Cf?#;Qt9oN(Zi0$3wHy4KY)I`C@FMJ z=teq&?Vi!ggLejSPN*cQsN69J$N@bsx)|16u;C_u{OvIGWM&-wm{OIh++^zNeQuX0 zbRBOLgVBrmtGRGB2jFWC!!;|O%;@y#L7!{C>Y|7fbNob~Qya|sflcU3oBhA`J^fcT zKk1WsrysIRQo$%Q>RFjQn429tn^eOsBySi}f@KdjSb1h#VHT;6sc44lsS99fg<`Wl zJy>s)4okuRj@s`ze&Jp#u9sof(inKAO|FUVZS=3f@+^;s@%x>p(bl+(WFa5Y@tT_J z(FIHtdnYYeW>vV174VOBzz;hD{3iisFiFn0I$`ujY1P&=700U3ls`c${>D-)J)c`c z3sFu^m#BpzrXlBVOB@m%Ud!BPTNtC6F0aUZzK+x|V>KXv^>E4@N&) zZ9v!Y&X!55%*k?)bn`IOm~~NXZPPcPh&|*g;O@qaxB-8}U+(te=lbT8`n>l{z$!_O z?pEV^*6jteNNAXfLUfnK%5&^s1{EKxk`hef;*+9Cxkmm3ub@pMrCY9)m>QY|}fD`#arkeWcdG&A-nX7~M z^@1;0O;>!Jb2Ni1t8}C5)DHj5)a>svyB+Sbc-Gd7j!(%a@vdbut@JnwA0xNK5LA%s z=@e3pk$81GlG`$$Jz>Y6G!T#f9&X<^W?$-Z8}mw6f~ksik&U!VU-B-4(aC(8ocm#o zv_kWEgrwiIWM8*%8_MOA9N%*KjSin>h+MV>q<6LP=`(`Ix&FpJ)}a$M#N?Cbaa~0? z<%SyL(|2-`{SJ8uqCb2gvvduyp1*fkIsaMC`FwPkM?RU=V~Ecu^U&5ZIpPQ|&nwJF z84B_pf)cYm9@eLhoXpf3NtVVzvKcbtRF5Y6x`DAa=gBL%J8XVaNJ^hBbb{yX)~gHOE{Yd9gF z#Kvssq>p@-=@?Cyd||Zm^Uk*N&XUO%@gyv&bP`_a6Q@4l4dp+}024?;15SwT z=pHNRNv@sD#xtO(uEOql%T32`PxL%913jjgf;|z>)LdLsVlwUz=mOoQ$|Nb5U^235 z?#vYGK_Fy7Jo9th1KCJ_2qj&{#EH=i?0>%c3;GD*PUvFoNnf`W4MA_*giTN-F3?g? z^?IYtw8-g19=_*u^y4%r`(;?~QY8N_cdn7yv!dH+2k-C$eT;bOd+7cC5O?gxd{VEp z6PI}kb0D=?V@o7z*@o$fLjTpD{@>zJzW+*UtoAQw zcRXsy&t1&h{^ec%Z+uG3nM*`-cpZQL6ZC-*DD~!{&%dMpsf%fePdr|QlzfIsd|h8T zAFMEMyp*CS7G~nbyr{vc^=jlFwZ=U_V%Q4)!45qU^9$=KKcPk(M|YUfJQWX&$Y%XNC$fsn1(7nEo#_PMS$&yD zQ7YZLt&`wcNlqgcS*TeZ-i~t25NVm7huMSQ-XDJXd-6Pl4#1nJjU-rzY8 zPDc@o$xq#xIa(PVN9byA{ww9EI8(7tP`mNG3?WieC(azWsy*78@5jxNy7`2(?71SgjCzERl8m+Bg&3zNPsVOnn9t0mG@E>>w!JY-7=7tRubTBn)6Sbb=M} zjZN3)$O)UQ}%N8#-_p=acqttL@(FY3o-+@B$`erlk!f>pmsrJ0)w zvo);UU@(gRn*`trIM>R6Xq_bA>;lMhWpty3sWyMW6?Q&7A2kbeyeq+a{pk1-T>pD| z&@B2O)B)nY4+phb3LbDg9a}3!R>cfi>0||kG?WW5ECdsuN4jE4dWP%&Tpf3XZ=CdT zhE$^T)UQj=qTI!t(*xl4N6GvVnV}IR8&#EVw7Dc;j{nzeylvD_$(93jZC+~Oj}u)2 zn2B_rPG zBV4h0ndrNoJ8%zKruVq_bATs|V1+Bxd^$DXIFOhW`uNMPNOw_kdgI)K*#E-Me-w1s z2<}i9$4~p{o@g7N9O{KP?RF8riYw7D<;paHJ3)gaEz*}C%F3={C*F}>&b%qu^9f0dU9gfO4Q%G zP`~EH<JM~$C zkQJ0II`>D!*$^Kh`{V*t|6-nRU7qJ^daJ8AMI!KycLS^Wid8zD^KT{C_bjlB66o38 z+z<7c0nv#Y!ke5}j~?l`t5$k~?Ou_Ali+!;S;!x1Mz8!eCv7TeO-~dBjJc9=073m>)rl7!|i4s=KJw69=(bGMEs&p#q;=S&iAh^8OM9vHT z5dBtJoZ4RarEJVT6f+C{g3&L=tiLVH?s#qr2agh2Nw?9{oWXZc4Gz{$!e1)s9Z~Q; zHvE>6@WpefpAsF*@s_N^*R&aD(=M6ed4$Q5DNJth)NY=%m_Sm1QqV6LnYrGIb&)^{ zeP(Xpwyp-^vu*TzHldS?OrMK7)-;(@YCE$NPM9t*gZ2pt5#i}h*;sJH1l;qF%}JI$ zRGuOq;Uv>%{7|SZL{EGVpGRMk_ZKob?zF8H`TAo(C3cZpw*|bfCUt)Y<{h4Qp4J0g zaqNJ>|8cwTA|vwv`U699h@2xjl1g|fn#jXUPjAk|NZ~G9Wju`1tbwTs%JI1$9oy@u zLpEDHr=*zWkPWR}Bv_#@-jHtG2L=+hF59MPzV-;_ogc6lAq}!VPw_j6K(~cw`4iWE zA}LwnoJCWq(aWL8-^6WO3RL&9cwQ+XQpcW=yvv&S3ufV#SgjN_o-=iX7aNRH`CF3m zE|PFqkPMy*@IN0?3Af{O7D}0GmV4<5g?Y%FII7+tA!!i_yDe-^R8hiP+l#pzGs!zW zVXx?@fdVKCDzLij^QX>N)CAes;U5sj5ZHz?xY%Z+^(^KV+*t?o0^`%OyuXXyjE)^` zcxs5`-CUrv^>EI0lxm1k^!{^ru4~~WzhUlb2>Fy%Q2ZvVzoAimffr*YsS$Tc_Ipom zW*`o(u`p8)Kx}I}bLc+cSSmeRO*C~+z!wc^o^>>y*_2C|u5kj@ubGU%s?67I!NjfJ zDBVWEgv|k4Udzfk$x|r64W{FsuJqa5s^y$?C79eZmEG6>Uui-oP`+lt*H?pd{qfY; zTd1*L*@Nk029VHbVg}kclKP68>&1T;nVlGQTrX8OKGrdO2XD&Pe!MFm7MVF=)>H+ewK<1Yid_(0q_ZzB-45lof zO!X=(=L&yAYR+SJ^Hg^8OWZsY_`dHfrI;kt4J>yX%=|t14Igv5?4%RBN{UNShfvjJ z(+!cKl1Iy^WaS2ng5|Hzr|vB=j-Qniq*&Dg4WD6LBxk*hAcJn1C7Yac{GsbC{Ex}A zA6V{f%%wZQ@34bxv?G~fAiefPrd2Jb;@PC{LLrfY(xA1gD}IBy@E?zv@KlQWy9K?q zU>2XcTfjtZ=jOO9G(AeF;WAIQI!x$8IeFp{{AUInVPC*#Z{$3CMjf65Tr9u27#*RG z-X;c@o|y4C*gS<@`zK6aG5p|}QFX*~&Lz+*ZlP!WJD=STM7|^1zV-C459A$EnEPXt z?UZc|X@n`Ln9}|SO+b6jYt_++JMwGx&sE1Z=Wa03=jnN~4_UA8^h9RRY{VPi;S+Z4 zfoG;>xloBYf0{Nohh4snoQOMA*`=6U&g5UvSd7(NOYGVnXG) z749fPhpkg(j)mD3>69y(vas6`iVM<2vO_$a)=awV@2G|j;Z&&ry4FU{*&3mL#~b-w ze~K#22Y#~+Z$)JFO(AJz1%8YB;4#7tBAE7Ac&RwD9afWm^W6QO?6ca^vCxO~zOSi` zF5=gI0gfJO=ugd>jeOcD@+k$@yg?@Sogq)DII}@3q6TV5-_jS)?nY7@?!eT($BS5> z*{?nDB7RM7@B*f^oM+Fxp)zTVzo9D~#t_nYW}+gu;>;I2eG;A4Qp@*Ls=wfHxHxuCB4Bxp3hi<{L$LRM$BIw zXPio+{Wmg;)*r7>8EVcNxYj$NEu3tMWM?Y;W|3d{H44uimK|g@J_gIli2KS2s#G4Q zMt?A`xu^|A<)kq$Wh_1?p`lH-1>(INoz6{dCsFte{L~{nE4ksP4%yd8-Mts}|0{g{ zd0~kwQ<)4T(_}iQ&~IQQuk~}N`MgnM+hAVXqQ|~2Ir3~^z-`F%9EKWXb@W!a)w{w| zm=G#C{ha7B#CeoJGR_|M>K{DkLR5zpIWy}SyBo_hzv2u0Z;|H0oJpn3*`*(MFiYoFlIiyWLa=kWY>Xb*N^EY}t9Atlj zTH=#r%y+0CvXRX2BaUJ(Ejwz)0FFTT_<|CGlz@?)+W2s*Gf5 zS0sH=%nckx#{Xi@wkj)NQCmK=T<^E7UQ?mk5u+EDK(C$Oww)^kP9vTs}`z@5sX zN!*LJCRAe2&(-cY06MU{|5kdHgqe)9KXinOXObK$d%KQwaSzZqY$Nsdxq2FA*^9a^ zjH#5Rz#v4RSMq{;UDW|}Gs;OJl+}=#ZGQ-ffgaaH+CAG$~pOu?xQE|hyRNKP^%;65*iihN} znv-nze4MBIQT}#B6*>mr*e>?rWxju2usIvwdMVoKBc$Zqw&x&0wm4|Dfs|e`2c-=@ zn7Md-f5J`Ug=@V8Yq=3`Q0OXF=%~l2kS6my4x*NLgrZU~ijBwyiAPbngl_#ju8HT& zv<`|!aR{~;D*5bpo8Mxg!%@3eu{>_}IJ_hr? zp*_QkQ;poUG34^TB2_FJwrMDJn3zq}gHP4My$|%_6g=!@yqveF*we_9Cs7Gg>x)l&D4p9_u#W_C;O4s)b91kTHQL0~ zo?X1%LsEZrAE#$V<|~9ro?#E1p%3S%4pQ(1S!svN+bk71iK>ybAN$R-H97Nmg!U*?EA?kyY@fmPcJwwvwk1C+;qIxkDSW3(jf^$|Av7Eu+?0M+K0CUpX0! zKz=g7gj&KxeW{aASB1Jc1|3IpV{3TvE~G>Bm2BfkR^234-E3A}BCGCOR-H(T z*@Fr~uyA6sV=lPw2y{>uW+zPcVA31I#h|XXM{VnCxwVatwCio3!-mM`uOxFJeIE8op$Nc5* zNt92en-G(6vod4M#mRVtx+OPL4vM)!e9}Cht2j^4WNb>}{}8b2qUb_GStncU@u=vS zy1@U1%X6!e@g&MeKk~vKTk>;)@3+1tcQd?aC9SurZ9z@&sw{ zf1x1Dh&pcsGo9yHE27Ew;Z{3F>Pi`0eG^fLPIMb0!zEtPNy!e5bDE^40Di+Evhbd% zb-+Xt*i(nd4>FJ_`P_B{&gu#OKBuEOcvk{m3z1FW<@Basagh4j&N+>WcQv@>WqQJU z%)xldz4uE6-cwL;6=0L-=(sBLF(+dk2QP*9DC9z%CB z6$E!4816Tqxa+BV1lRDK-ZETjjT(^oHrf~fLudeV4>tt!#D*FJEd9v&?nf3tCEQ|$ zm~eTXdnpZ#v&`)+gDl^}HSUq@_i@htdpN?KS}Ud#`El!4vm0W=<(k=`j>iB#j1>cu%#3$H|X=TumR{mwk-GfLwhXv>_x$<(gl z5}V0L>eoZ+x!kz+*P5E)9A8HYh!gy1q;&?4$d^>uqinPARSE51K5Y+-`Wx1|Mt}LY zcdxtS94X@Sbzi0swLm-JcH89s_k5SlI1xil{*+6O;s)PWEJ&Ddx=}{E3mSyOmf=d>!zWAT4c!Y)u>~Xwm|~r!P}6@I%tVrM~8z zQK3%g3I1-we{Qo+VgB(idIuD2yZEX3@O-3#Kv$H*z#!h{l z_};$xB`=uUY-N7V4RZj`GovkwoMawE(tacrV+qpsEvTK{D3io_UmpisOVR{7fmZkB z%?(9?JQh4SfdrEIRR6-`umL6BHh6&jI2(_m$vX?v^*uGwpE&ajk@=+tBM~0(iZT$C z=D2Z{<(;i4*?MBOPAU6i=Q9*92Hjr|LM<4nU!$gpAjymr8YRD6Q{CyYOOyU~l=W0k zrj)+2gp-8%+SWzet=-jH!em{umvwZ<*SntX_Nj9u+O7eh1GAZoK=)8CzdXM#7;mVJ z+2h0U2aXhmVnRS(oT5dYilFyUeJQSWQ6Ry|UAe|S*JBZ0|Nac_E+y{c+ z?8JQ#$9?bx_rW4X%s_~uUv!~i=?Q|i9IU6dc_ZlN3A+71n3R+o%vGRWb<{REQ8shF z97kdO7)Nh$yu4LNtvy7}#CZ^H6M2Io$s|eJV&6m8kQLQ$2`0@{WCnE`9G73hY|OxK zxdCm{Mf%0JAY?XB$5q_sH(9-znIct;iNejvYlx$>ig!;VRcR{|md>C|_^UX zko*##xd@W+7=OWA`EN?+0c{ALWx><;=`T zZCrx9ni}-8T{sgBartE}ve2}fPvvVa0;{Gm9^>j!mRk35{5D z)TCQLRL(F9{24nXuQihU(axNY7NjWjNA)z@x`dPH85tzLcmb>0>VnLpIJK2PIXXt0 zMUH+FX(VUy0;jRNvy&oI5@I9p)sgo{Xy_oN&F-Q zUC1Mxa>aCkDvm_AbCi`>82x(#)TZ;$yw|{A70D_8bM#Hmxf-8e_UhTu3KvuyVCcJAyooK)1Y_e9mM! zlg6K{*T(clu}ntk24~eDecxAfNsGzQ`H?>9KHmEX)kUVvYM7noFcW#G%HtiqnXDbp zy7JeTkwvyn->4_)JLm-tFvaFLyIQFGucO?!&;1@qH&_PO_+_fcEMz+^;(flMj?6E0 z%Khl-x*8uEC!hz+jwWXk{f&-l{skUMlcSsSmA=khnwxN|m=~3p-*A9E=0Gn!lzROo znM+%ZOsUIa1ai^lGZ}X| zxi#-Or;3p)_dWH;9y#stICX*G&95`*1$VlmysNV~UpMBLcW+kZ5&7Zo@DY1k{BgC1 zQQ1eK8?lnsQV!;=2FPG%*f&FRetEXPRUR?R$K2UEdal3(J= z{!Gzoql_TUW)5f0Qc|(kl2pBg+jcMA^G_h*zbY3vVQ;_*Jz&K=C(kg0F|#qJ(Z?7F z(iK5YPjNYY+D4yKo)qJn^g4~0MBRqGEjW2Fup!Jh8U+$I8Mbl`eC1Ny`fH8f8Mhd> zQ?vaDKX(kz$~lsLuE8tbW48EHFqik_dSo~GnDUTw5RQYZsHwEcXtLq_DGz(v7EE}M zDUmdX{$v@f;@tHHH+gFBCp06e`K7jO3i$_XNmofl!5&R^^gwp$cT6p)#of~tmDXbJ zmq?P!`f|>!MT@H18=zNQ25NQ)=fxA!K62vcu8cEcsdFp&HC`aZ#au2lB5lAaW`YoN zgS-1i&xzgu*Lwjk0J&pn`DH#(VL0*fJk4bA-AqiODuj11nq4*kCLx>I2!cBt{B{kF z%kwZae}NmB$thfb*OIv#B+{3*Rf2?pVt6PtWpI0tI>Z04A87zvU@U}e&K1#=#+z$Q5JQ(IfpnB(V z=R5(w@I|K-h1+ou^Gtu%tGi0THt;iIB4o`GLSK0iZN(tYvfr6Zn3)8p!%*+y zQp3hj5tnwj995mQ;5yp6SJAC{vMnMcp5O*2Z^Mb$N3sw;VxQ2BKock;52-|FC?q!2_NYZ*T$@_a0EKYXb z9D0V9dV8?lHQX21bu(_F4z8^(1+ROA>>CPja_z()xKIsXe{8Zx!oK(6eHs!XWUbs; z*=#&v+)3U}ZK~ij$JgNahQtVo_q;?uT}Ch~yrb{Y{v})Y;ryYZyX$^B*PSOz+CTF8EbLX3ZluSn%BAg)k z@He?Y?mFVY6tm4PphtPYjTS|xHkn&{JzT~~Fn0Fl#t4G}{zwBSXb9#sh_g8X93VHR zt(D~0DxgSTfE?}R#Jt2E_yUZ`k27&N9`Dugf!kyf*&9+9=5w?8b3c>;m#&G{xvgak zGy8U+cep|&|Bg3n$3=ee5leV!8fcXU*sUw zt#N((T)7UA1xe;D6TwWolF<@av}V>f@P|y_5BQm0Qecza_&%rCK;1T$5I+Oaul;1lUy z#C+f<^anxU3OZcichpqBP=VaRzxGZqh^w#ZHq;5TScQjFkvF;uY&H`K%Js?FiNgMgdu=+vV_X) zsX5XT4Yxm@vv9D@sM)ltWMbDN+p`7ls3SO9Z}KpPXv4KpOb`~?6mwuxmQq`L@!CYdQWUqBwwpnx67xEQZ+ZdP_X@bE??7X=+xL>6`xCgyuS^KNLT7cG8|)Ex z_G@aL%#Q31A0}az<$SJ;!e9kzwmXh;;Nxql@!>$rc-o4(@Aap+-vVW0ifn zqan`6f%vTTzn!WDYmdado~eKkM(T_8YFBmC{R-L|#cU729-rIgxCz zlD>K)Yhnjl?E|a~K7SaBxfYJ?PiY!;lYfT_fE_ z>X*tz%KN4+j+d8AsVYkr^4Uva#t|F!>qKo#^xq}TT%RlKat?~)>ciM=_pRuw+EfjO?s$z zOw67GdY_4eQ$uW|yl37j6~GEtkY;N55em7Cq zP6By3O155ZlC^46Z%&~bJO+Z{uZ1$5t{r=DA-nA|=}eKNC&rTf7=X5>yhEYGD~F?S z8JdJq)FXB2Vx{kUW2CH?6sq#K${e`KXppc!O<}CmpUg8Y-@>s>CbMp(Ohic{{Vy48 z?q_hU(;xs>B`zvE5atmS){2p%Y?A3g6-bV%h32v`s>@h9w{D;q zLL2lIr>;=w-^D%O4z52l=XXXr?vXG6lVAX5!vLg^+Zrj)wpQ}q8cnudZ({|tPPOn? zEwNT1?eaPrt6=;;+t34C!8>;cjHWL>lsWJPm$)ZuyDtl;Yf7Z78ycfZo<{Fck(|my zU^S0T3Cz#vWEpJfZvBGOt}kkZsqD*VaBXcld+LxFx1FDKnmoQ2=rIeUCY}sF5eEu7 z1>F7&c)cMtQfdYAqY%`|#vBJ8xC%6V8~w*kIuFg%-89T}mZ?U!O(G|!4XbJep4Mb~ zz&n;3bP^fiHXF;&}Bp8fDoR(+lg^q(UWHAS` zW-l|BB?|4sU2vh2s4fOsi=spu0qV1qTWKHc_%-gJ3{06W!1RLh+%#?NeVFAq3$)~- zJ-`vcEw7M7*8!)Mm?oS^^?Vxbvshuxm@7RSl=4?J0)AkBR#1~RRFPAt_jjPbdWI@8 z!c`Ldq%rm6XcUMGNJtbb=aDOmJJ7AW8<4m#5e$Aa>e64h>7S9`T$sMVNydLC5(1{d z2_=!ReOEAu4j7Zq6cHxagv(n7N4y{A?su}WyOL438kX&p@j5qgMw36OOjc7Rlh}E|aI#G;Yni?@#=6D& zJ2^C!>9bbwrZVF-?g)N(5Dk10DyU-)eA~28m0+N54O^+I7 zR9R~)!B_q;Mv+b2leM*ldG1Bf1+E0g`-8mg%G{M_L9`<2?*_7hl1T)&(p!%uC--+I zur;=I1cyIMoe;up&=CdsS?c@{c78`#*s~-mhj5AwK>ziO&*E^7MaPgrPPj@6MUsAy z=Tn6_?h~m*es_hCl`sI8`7Kzi66~G`Bzc z&sl4QS!qtxD^u;unZUi%Zoq|5m?^+cD*Op(!;?rA6Z1_9gB3Yt6%|0@XGzYRo+#XA zqe(iUUqQQ@g_^ZIePIVV{bDUQ)oIr)*F6x2(oFLc`p*gSyb=C^m+q{bHdaoXuCRDB zrM~upN8gfIK<49QQG%5yR!~Dwu-WL^MgDYVa|jC1>P&nZ4X?Ecb?`Ons9cspQZv{e zbaO3l{E4L~b3FQ!{C11mtOWN*Kc2}=QocK(=UGLC;6(>9n=|1GU4WHyV3>U0h0y$s zMH7FRH|~Z0w-dGbDw+A2mn^=9?EECK+~>^IwSbO^B-7`vD(FYXk?wpO-{n9!b&>B= zKypP{V85h16#CAr*v;tlH(O5I4x#-TgbyT? zr(cavF^uykiCsCEdVU9Pu{-))*IIhDXZSw$fk9-F_tztOO4b=$#7i;LRb~bM9Ym5~ zQ8eP?R5z=;i}nm$dWAax++PUhZ(s3q~n+~XZ(wr-}L6FUFa)E5!lfivw5>5;~B18>Eb zzS6mw+Pedldpy3#n>e8v&SfCj*yxnv7@vCvPS)axm&m7eR7Cr@W`?fEz@!J z5L0PhT95GlvvJ-$(~8o|&nD#{3T^FdP>((INTazqv$+b8A}XG70n!bG8nXbq85Jh~ zS5TgxerOe{aNk`ucEZ)r3s$8H_(Kw|yxAaivzg?1M;pv-eby0!F82()#z3@t{Bz%e zl6(JxvvQwtApb7Otg%)H@cGWD&8<7FVdzo%(8Z?lzHF?yo4STh!w^|e`a6U139JU6 z+rvz>Fm7BUh)HAA4_o;pZ%As_QP_?o6~>$WP#L8BS4%V~ydSmXD(f6=7D<7d=<3SQ zDfYrKEzZ_w+-wE;P3P!2%~YqINtqKF2PfQjSzX~wKdy%YZ4Au1NFWnaI}A!eLp-&B zP?bBCMkvZBz_;vXl|Ld8x(GL1GZ68~oNW6z*Pfz>Db7TgR=oddU~dP>w0cS6WN8?w zw#;sv1#0#aOw?O*UW<_x*Adis9@XeE@)R=QLsqE(x{|N4h$kd6jc+oq@&11(DFR6I z4}-NTjK``JSdYc3!I%hqwHj+TMk1^&(PMU?uI&L*-v1M2<|K);&c$_-D3R86oT8g0 z)|$*|dPJhFr}6V#2FbgLcj-R)-%sFT{!YR@#7%bBwgKJFL)_4!{_TZMdjnYKLx(qW zv&HkC0{3_v4Wl6EBgK@fxuf*>>qqJpp~L9Adfh!v!a zZmb|kD>O?=5ClO~5Tq5|EWs>6kmdJ0=QEim-P%9jz4t!8_xIiVxR2}Jy}NDldB5N1 zyw2Fa7%C=KKcaZNt70-?2;p=fm#ArFyy^2mPyfJg36n9}1$n9%ss{ z|I&B3hpvHVn0~d18etL}<)u#8k4+0FGg0Ys7{+^e>Ce!qzllzQN%$*fWhK&wc0|_6 z`1UTxxpxn0^E2%H-IVnuYUr+bClm2K9f4!;Jm$UKguCfccE!FyZS8%}cX z3U*J#v2+A`RmJ(X1-4)?;7P34@kQJ zwDT6cP%<3YEzH;aI(-iO>y;qRkD1+h0BHU`aM<>!gr~yyKF2(=IdF4V@;X0eC+-2n z@z9c|=~V=m70uEfVhg;`D)7-u>_IpQgz;P03@_2Qoa*u|oc2o ze?AJ@_Vn~lhP&vb)6hka&C;~PaQ&9DRpc6w>}t5OXVC%s)4oXiYg$bDp2Xi)rUY{~ zRc3rG!6|or>MB(8o4qAjEBKvdvvV_*iui>-QS>ka{2;qw^5~~3$F=qP*`?bJa9mhJf|ZD+Pz%M{aMW_qn;AI4mKrk4;|R|{K?uWgp<_&bn`TS1T8!^zC& zR98~F{l!zC`~-35AbJc0J<2@sWvRz-|7U0w`Uwas2G;Nx>ht%QEnCYJvYzxLdIYL* zZyR_sWCO>Mu>5C&ARgt-TXg1fD07#rU*fAdny!mqEU_+`LuO8*8ePU+)md20vlMH; zujpYJcd!cIWDj-KZi#NTYrV*>nF8)#A9>EBoWaf1%Nvr*h-{nbJ-m@^CX>Am`oON@ zn?I7ani}~fg_9r$JYjy1UEQ(tc(~EeN_5A@ z@2GS?XD7%h=$v<}m-9llgaE2u21=(_nWx=D~4^DZ!EBU#{4`ik1v;Tv{8=Q)Kq zek?rdKB(_crd`a9>`$MOu@HPC5p*^?R!+(~pZ!|1bynQ_FgHom>6M8sxWgxL`}aUi zxtv)$-@(H?2nYKOa~jV}e^yl?(}_RIq{{@Dyf#p&AG~x8TlS=T#cl!u;rYUf41sgx4SEol2hzy z-_l9F99PEGV4ZvM%srj)3Kj03aa?Zio6a2n#W*gd@9=bD?G?=VyBn=^o$p1^&=&96 zzU<%1@mWy}3p1q$lAxV)0e@;13H?M=m9IT$lU~2S4vrGH}%MEAmnw- z+xdVwd*3k6Vk+@^K1}X`x+9?+ZFIYg9nqdrm^tw)6o}<8Ysb+4w1Q}N3qF_@YUMY< zv0uWvPXp^1WwUjr(c^Gt8}M9wO{HK5Hzv`0eFTx^ToBCe^mC@LN%API z5a8#@7oxriYF|VDPY+f4S1541(y^5Q>Ux`=_-~lDxEt|9HdhMAbsnnyjbJIGYPP=P z)WjV6Ax>AHLQt#ij>I=`O8o_dbQ|b>Ee?gZh@it{?&t`6@b^q!L&SzhpGbRxM_4@OnM_`>F0?S&3Am8z_An4~C3?}@ z>O$EyV-IE`FQzB{VD!Y(sk<-9sKMoW7gbpc9gSb0+&o6@{T3dTPkjbF!yZg(Jp%pm zYVhHmRD%zrLQi2n!CZVG%Wxo`NF7tBc%c_1TJ~-n#Qf6|c5+?DE{MBuyVLE3H`P3Y z9q<|?fdmhN*_8Rzmk?WTBdR_?M12}`{gyH}`+%@NVs7B}^y%(J4$feM`Eu&5`x76> zQ}7B5#fORWnX_=Pb~LWQRdxe=I^MuvJ&414M~@5F#HD1N5cSP7o)(dV4^`1^dzZ4DkPA0Lw zLZ$K@tj8|s$bRaTJ7GRLU_LhyEyMJf#Q652cPEuuln2w@cp~-71#P8 z^tafE_Bpe?va)h`cjxPb(*SP82iP+vKFUqhlrrHo27mWVF#50QM&Jy(XKOFkbj~1| zY_V)UaHGqfy?htd=jSd z&BPDb3;rWploOZ&e-WK|H|ajlhvAm@VzWpR%G#0ig_P1wzXr|YWjMkwsC{B#IWFW4 z+)JE!0j!toMF1Pn`|BSIIWqn^g%| zORex#!so=34KQ?x-u+PZPsW3_2Bes*?7k76t(wOQexH?e4zA*!tjCkN5%>Ofo@t($ z;FF~|kuG3L%@v*mc;I6cKVOj@BaG7F3XYI-G+mfZY@kp2mLpqi3{7j9W(G&Wgd-Ng#WzTr99L$xTg}ds4MB!xrgZsPs0IpFt2to zHT!x{nuYyD=kT-rkh-HcJHl3m;mT%aEM*$yxy<5UPi^edI%p=2gPz1I={OCdkM5Yf z3tEB;_rV?HkyiE)?1Kl(Lv{85b$%xb@8Z-He)lzSq#aCk5QXq4PV9MJ&|BV3?9s`g zeklaqf0h=)JNG7P!MDutI0dKIYO1x*=!Ea(w~-scJi$Ddp6x+wgjke(Gm7O}nAaH8 z$hlq*yRP0~4*hm%)6+gi$;m^PFNcY_L0P`FRKYXJkisjkM0LCg&88{y2@u6*(VL50 zs!^SWBkGBScM^}LPw!H`c58AcF*od;i)-N!>Z?1`d^mH?WY4)v=at@uui6Nh=hl;X zSJqmbd{j!*JTC1Qm`mi#XYSKpXoK6~w3*9`n!)s-09fmxcLvD zi9gRqb_3LP8r@5)yvL`#$;Rnr8NX(FjFpo(mdVs-GSyf;0?jVfIdhm#u^f-F)B`Kf zHQ%9%nuR0k0elAwU}7Ke?#=#?Te%-QFmvD-w8I)a+*UZ)6{s*%eS3lH?`mMx-w{)Myp2X!t5{sFVv>LbXJ7C5|NwOvD^5h%fkp93=@HVen zYLegLB$p1{uTVCZdVhtg__+5Zc$#Y5I;(LRwr9NTdj~eq0@m7{eN`80tTNBw8)nG< z5~or@!m&wZ#QA0EM=}+$HU0REm2?@d1|yz`OM;)V-=$u(o9K9Y7>?{cc+pibtUsZF z&E(auW%A$iurUkSnRhCjek0n~voP2{(7p41@}K!Rm&3ozM*F;>QCuDapG`) zmhUr^K9?$Pn0>8#i6c7fQg6j1cPf+DHmKG+1FX>OdE65ZipiiSp-201hrRoz?~cRf zK;2grt5d*Y ztJr$Kp3MatL14?6rF<(WyO@nm|H_DH)5 zZFPP6&Kc*^pT8MwEozQKHl;8}$^899i`X43D0TmG{0Gm&R4-*~SSC|n8aekDVR}D9 zBe8;lbEF@uY>uAAPTUgN&@~^X?G&bAulBU?lP|E`;|#3HRoM%rR}lMPpQ%KSu$6gIenDcN4w^h3pEmlbBOW%fty6W&)REF6i-b~b+1>*+rdK1WJs_ zw8P`iN2|zUhW?SLQl*(^WL-)va36T&bzCQ#snWJ%yG*Q3K*)l5ITB1FeOs5pc-O?6^bxi$w2DW<$mTT99J@JMoFc%;%;dmIDvv7i64(oOk9k0K~ z|J{bV_d0VYH^awnPe<0Po_BHBe@XwquBadT;-+5)-aDS!uaep?h+?%i`6ag5eL*+6 zB_$?h50vhGQ7y~qzqm)URXaHFE#_c-LIj;g=g}RCa5F0M!pE}XMq9c$78)ZGuT>!cm8+FN+>KS5RgDQ#C};>1_DnY(NQ38ph= zvZq=22CkD`AB+&im7LA!7=bGIIf3pxjni- z5)R*NVnu~+Kzx|Y|1MnqWSrJf~oH&`pRSm z*_g5megElv&C~dnH>0R@;`5t~%Xuj|;0pBkAez;4Y%uvM{U;E$RE+sxg>%UCzoVl^ zQ1yqn(WWqyF$I=)1=`+o)W=`>ej?Y*gYC`d`<=ry%iCZZI`G$iNX0)T%RxoEKU_n8 z*2PQ(TMg5&IqL^zZ%dtj4h-mRYzXM!u6`)ly?c%k;QQ|2-VHCp{_HQw=jGN=(L6>y z)4@E85m?1J+}i>agImxgpT$Gmqfx~L6SM@~UMl1udz>CdseG5&MwX=Mym%M=Zw0vB zt|WK83{UC;Q7?gEJsqqXWCP*DM7Xzc-&&HVGX=`UX37G1z$?hUK{V=4(8Sm1@ELI9 zvWHSm;ce7-3zhah#Mc8;k3yln0>wH=)R1i*U+E-?1>i{0=mjZ!Og%H5YQ}{-^C+e+ zT%j|r9>+5?pqnaXL$4Rd`6+l~%ZVwC=x}dw7FOKm2f%)w&t0zOCa+=B#79(?!*~Mc zP}dwuRZ~o_YaNWmvnbjcg$`mvrS-+uy1voD#A zhsL9|=2iHfAA|S%0DW|h&UxHk>&zuEdZ%;igXm@t)2Z|}{s~LMbUICB*G2){&=t&7 z2_`&ACKc{%I$1m`@l^I)-^`rn5W5TBq67CAbTQeJQqdubne6@>6!Aa6UH8DUeSsz} zy$qsBo=+aW3vEIwfS)*(c_?c6Ajfk!mD`fmt*rxXf3nU_DJL_^r1r;u<~)7}@)>^~DO8**Qm$ot z;{ehACtk@sqJ2KQWzON1+=hRq1CQ*7ypky(2@ms85A)`GFUH5Xnp*QsYJYuv(KcO-pMt5|BvX{VEQcoHP>(xul9sH%XS|L2UAQ=sH2*Gj#xDbw@*II;5odE z+hCPDU@Sib-|mpO8)vXTY*;=_SPd`ZF*bX2pvaG?7ifRft~2TETZ_x_FU*zt*CW+* za&K=&K0iFHdpbp zOZig=9)MHv5)CFa;u`usF$?yuBgskinUgGaxMZ2hcnIby7QC6c2)zjl6Vu77FTs5N z1W&OSbL*;cgAIF1aCmMY%Ly-D!D&AY`W&Di`LDjcsP-?(+>~XwIV(==Q0D)g0f$`Y zwj^G}ExnUyUYxpD+S&Z)(m-6tlfw>x2QvI~6$>}=mVTnkV;&6XVeHSmhS>~%B*MLm zQoS=fwa=li=T){R2($Gt2zxm75NfhehD>UijuXQJpSLFKPU`EqT2t=N1VWiGQKEZd z4CX|5mIY!;WHx^La^Cc(iBZ537NTTf$7^ ztLURk<}8e&xvE`A4fBGhoXu3%5u+Z)AJ{{U`9RJ?8P2j$%wC0ga4jR`UUDw^GaRTFjwo&4P*l= z$b2EV{3;?(3OAx2jQMf0cxq2$v+gZ?>kp_6cESPuTRbs45i72P=eIJo;d*}W4a9{* zsEY5z2lXkNsxHOl3SV?$n&rk`{92HQv2`3jlK~b^4-J)FiI&Cxz^z<`Izc!cRclZ z_)2cU9riLT)$ZW#Tfy2dC9lTi@dXU`k8}Z5pd)rF)0sxb$ydit9h2HN5Y@iHt#**s z|K_`U&^;M6vANLqo$M2G7z&CDSif083Nh7^l%ZVmyd6yMw*TVg6 z@jHtT_;rxvba>f6;V?f&I?~W9&G)$jvx!e9QyoEf$W?ULKLtV_^sFE|JVS5LW;C!f z=r+rM!JDV|EZr+kC;s!cd0Nv?P0FQG@snw)$uno8_Fqf?rR>3ePI+Nrg?DD|zyh$- zMR?#0=RDoVS%({`2c2Rnv)~e_?=N7}!JBZh)A9T!v7hxU+y^qX@dl z75FZEDC?-|zwlfS``xIsMczSo{{;O06CS3$Q|969S(0)bJk%ek-ghJmUJbkUAQ|v` z`0vGVcE4saLO;Dd3o;L49()D8;;{Vgd4_+IVZ1<}@1KZ2=hCZtBR}IL`fZb$Js|Ay z;bii{#FNof&PG+ah{$*)dvOE!4(s73e$P#QjI(-*`}`7N>dJ z7w8XpgZ{w}c(H#5!F>(iVt6K_#7^V={t|~{9DW_?3|WG+>tLoiNQe5#e7Up0co%WI zr7J`_yzgLU;_p2VdLGsO?hbT@*XW3QPrJK^IMHvJ`TYwvDote@$ezqsn1k|=z{EOV z@_s~zL#dyRrGh$@38Q7&)xDBh>N*s-I_>HH0}9a^Uh#UEv@R;uUU;fcQNeehPCXp9 z>LO-D+(fPVD18IcU$+Ub)ChjxxlB|`gb7+kmAV}fD~~>^d#IgSnL|99c5nJ)M4CC^ zzp9L9@hT@WJN^Omp10XcIE>!23;jCcWlzChdLWMWHQyhbA)l0U+yzOMa=pQ1*{?4%ebD9985GWzhf$#}XU5e{x{dHT{O<3A3lHF}U4+Nr zcd(8Ja`G48bG(^3zW0FuzhD>VEIQex8U^;l~9J*c7dmP8g(o>7 zV-|eJ+nM*^N%c`19tYyO1hwl$ROlbcoxE*umYrOgg`#pgmBvlDx$lMdt^|C$?lIayV@ zlVsAs?|IW}nBV!V=OyO!zQe@gKa&A})cZF*`IjJ+OtSCMbf?~+?EEUC@R8li3KdC*LSBS2AP&7|xYD^*rNk{oIJY%Qfo85p`I|<}5m)VfN0$07mH@t>;_haG|HmhVY zsrGR2##!8hD{wmg9wqR*q-16pAI`q>v#6M_LFstfvpo3{Sm_Uw|3suSQg%+6fj*H+ zq&pIArXGCxG8+)yPA&DGk7K!6=awEvr$`Cih_~UidpB)}$t`tJpnj2^}Bn=-nA%3VsYTlUm`po`*l?cEDTCQ$L8^ zoq!+iI+(6+-MgU9|0dybvemIv_O~XdqoetoF7!nS=YM$c1E9p10C1x-g?K-N|KfxVL_pE0+^iMEdR=6%3+S&tA=jHp{ zZ7Urxx#7hyTD1N@jio@u~~D_N3ZA46~5q9>4R#Yr}LVx$Bq3YH|rZ>%}xoj z{V1TZ(JUE5gJ(Za)0~toQi5C{5HSH)|cmF)q@20cMeHm5nC9rhtl1BrSDF)SW38uex zCwi=9=1~(fQ_M{gNq@5g#|Y2U9^)(M<+&H1!2_Vv$C$#k4qonAHjTWD3Q|S)uED=c z`e46h$NQN~A$^~ha}AtDSIRl`Zm;(qNcYM;1ssu zbkPctOMmKTGCd0&Gfr_&JnD0W`zRRPM)qw4={diQ_?AOP98OL|7u^Sy{mk^ij8kw- zA1nH&J5KA77F3AuQRpwA7ik?oZGtz=yFdNI2f(NPhW_v;&=|ggSKSxa+hn#?Ox3wf zd%|JQqQcGsS5IMY+qoD1bGmNr0tsUp5p9$}N9$MSQ z>6fKnPUpjKLHu_z<9ZYP?HzQmXHefp0u@kUjg5#aCZqi1y#Tw>9#Rh!4|kr^#c zPf6N^uy9X&zeV+E2sR>w(|AgdUMcP#<1pg4AZX1Iv;<$jnE=%U{Nvx7&GhkD_bDX-zN{r`$0K zKDs9B!205}aDbAsQPT>T-g6mG~*+!GdA+ta#=TgsCvPJZd#Mhbh ziXBFDt)&0zB|5?jxc95m_Qj=gDg7@NG@TM=L+<8V#P4x5uEI4qkv~Bvs%O?5dT&FV z#>_p@Q6Fb+&s(rYU%JzIvyb6@+ki9Q!?dss$s3a|qSiQ=7$qvk*G!FEMeY7$fFY~T#%x$_G$Ji8D?qqW2rsM`T`2CR{>GQp- z@owA!GPmJi`v`q4E%T7fB4WzrcwLP4IMt&+XJTh@!p7tmQ_kkhFXOzQXP4wx%zT)Q za(lY(VrF zzms@ZmFUTvy@`myhTWh3D0u0c^pAX>p;p*%nje&T z3pw!vbkBX6lX*5e#ai?Cy2MPP>LO1XNa$?P&r_i9*O{!e3A85;j9IuZ{Oa_(oGnW4llk_B2R}Kr8CGly+7$sqH~$(f7Ut@DmB6V!1@iT(y5`=e3c63Cm5B5DQDof zdL`vj6o^}imao$9cWpKTX`7Mr>G1e%~!K z0iAIr{Ym@qv(4l6-D!Hc{qq$Atw9l-N*7c^lFUP&Mn|yB%p6ErlDZb9ZVG=(JNe@3 zj3=ppa+nA68Qo^PW>#cA0Q0vAG_`{0_pbb|dGie?IQ}sAlhQ{7;{F|u0T){0iD)gd zN##i@v^P2ZDNH_D0E?MLo<9?gt(=T}4W5F#P+uCk2Y+Oq&>OtQKC=H`nC~W=fo!<_ z<}h0*J#`7(e?FDS31EWr;Un&3TH*7|EBOFz(MtbEA^xCxSpN=`v5#Q>KjU{;4D){m zE|m3YAL7hBkgX`kq!*@Nh{Ag(TFisIK5_khMPB(uhLzZ}i0$9`^fR9T!*CU|8e~iT z2%5}%7|5fUK3ard|3;MX7eTV4_+yUXef$Bg|6?Y?9fr^E3_3tU)O9bx_Wv2Szh1si z(R}supAIX010K(HIKy6{YTt?6wUb9?EzCi&x(Oy;W({uQWyYf%UPBGCim%rW>##Qy zuZO9;j-s#SMo#`o=GM)i@76^OsU|C2&;7hF{Zt(1oAD;vbaLxjU!O05vwstJ*ms%7 zGPz@2*1>GhevnR3_S%=t*O~fPqxu}f%!sq7n_6*ye1y-&jyEll8*w=m!OKizdyhEp z&}dPCF5JRT^kuRYb>>&}0!>DYoR(0Nv*1VLe_Xg0?UP-^^C;EU6!UVXKZqJ=et$C4Z z^h>4@EN5C-1Dw-Cc&=s=tu6os2XVEXfotK)jPEjLfWY4K^|4puuT)&(Lp~M0VJ7ow zACkYn!Tc5#iF?wE^8kotC60jaJhAxk&c=~f2`_mc*|H6GWkd45R75LNZe|*gL5IoS zY|Fljy8i)sIo9CFei~%nM}9PzrC0)nyN(T*N8xo}pHc3+h#uu?y12jciBI+pw6S;C zKPTGQuK1@u&RQZrOY?lq-)VI8AHsCbh4ec4m~D3sG5uBi3bsTCUaCwyu7|U)G!8c7 z5Zp=qo?ZAkA3~@4IQe+`YOmL=4bpQw2>Ojl-8?eleR%P9#LGJoQA95K5wjdUM=yC>8B0Mnj>3;1yQiudNWh1i(9CmjoC z69adYjRxKG)zkA7J?!5nxIrCvQ~z`^pX_PgQ7j&%GWOc-gS%n{@3|WeL^p zwK7owjsE#sJDi$$9H)FcvA7}SL-d$$=tcU3s8pD-J#N;v%oD(4MtHvJ0ln^{5(g5$ zAx_xwQ2KDD--AbKCV1uy97WIKB>P3GLDxvRZv}Hxmu3aQ6Aoq? zdWk(ZGD&R}eE$o~wn-*>9>vt3R-C$@pw;b;7bB6%WJmC{%;cJn7J3+X`j22YljF!E zB3({Tz{5+{!H@Fe*%oMD!tE%YYuIKdGv2?WLqYVm&l7~5Y$sp74U_&2J%e`8zA%vI z!8C5717_FcN646mr>-EjTt`%qIZM;%fSkrpvC)^CS%7w4&dJ|~lks)>dS+4c-UgO* zg6Vy5ZAa6^768?+LZ4coGbXNge}xNVCwTq)VQF84Oa313%)q@_&SIs;5_JMP8xAbpvYmc*Q`!@)1-g8El+IJ8uH0J`kC5GDD}F?9Y^wi2z)!!!5_rawH}uYlLGw<)OWr+@vnfss;##=zDyByHsX3(${Sb(cHfSPG$(OJ>zTlrMm_%sdpGxB4(Cd4 z`$lGj9Kz18$Izws012E-Z>pV~dp2j#0s{D@Fce_01zNvs&m5xTVN~vMf6A_+^Lf*o zc+XDws}j6L-y~-8CEuZ9%)phu5bOGu}!cC3qaAogQfp6 zWmoi!;jn9e05yC`<~R;^ z<2ml$q~rylr671ei4(mE<>ix<(_zm3g6I4QoTbllmP_zSy~atd0i}G(H%rVof|Gm` z-}*VQF@FSE@0R(i%(Gx3-e#KWVtT7DKy6<~O}rf)p$BsF?&RjlJd*`FYuE{5xEMX8 zovFD~bZ6%8sjzlncJ1lx5PA|8Ad$HiL3FKQHfC19{@YNQPJjt`k{+`eDF-p-^ggz9 z{fZiWXZj-^@P2?#VkL85pT>^jAM-Q2a$l4I#oa5IDZ5SY}fP(ANqe_bD)X?2T@Bl(;+Y^ZRa!}HFh3I@+`jfYS`Up zcuk|Y7j5t>i$MRUF^%zZuw)zTP&e=Ev-DV$B{#3^5UtMwRA>)Up>3usXp(PdCQB|u zt2>!VF!gx!o9SS9g(___yvi&b5rt^tW%Tf02cCMK&fZOI1B?X|yXoIQgbMkptN;$7 z2kGhF%wE7rY=HIgO7p<%XW_qHP510GAa^of^8)2NC$n>87CX=iQD4e*a_F_N<#)S{ z_66$UYKd;N>S6*_4?dT^gnsz)LC!8r=hg^QGK@q^qBSw*Z+0!Z@e;AQg)Z1^RO{Tt zJX}QusKQ0K8A_N$S4J0o1s$?g`0#4rh3n9U%^l2bx_kNGnIB=JigVC^hD_dzXFHC&Qo$SUL~U`veU?zWwbC_avl7($Ry0a0FR%cAPa_j-Mv|P=)Me6ZX)KygIU9 zK8Sa#p3W5M9+#=lE!saWbDukjgxxy%xsP}#JD-N=Dj(LZPX=3gth)Ef&V--X1ShW5 zI5zXR(UiRrzf%r-^78QP6(khGz!l@rDW%i6TsQPo(IZl$J9>gBg7utX2&JWoO_41+ zQJ@{ymTcRvi&{Ylw)IC9w%kk6eeWO7k4T3RVij&gczE4gLW zOz^4IiJx`sRcO$epG|0NEigN6)J;Zsq2ApQuZP`pO-w3ur5CYrxi{So!mY(`WTAt; z5|wrsZncy;eSmG{h2-8I5KAueDLTkl@ycZxoNWbX6n4k+JwwE`SmILLv8V@2gT#Q3vokYIq4uL7DME$CK`?= zdih4p_%7qvz|{Z)?!a{%z%gRQgI|SGHj?5YiZ!uI&&3?hdiX;-d8rmJy@mO>mGsmM zr@PtP(TKmviT|_?Kemn8*fqGY4OHd|kY+e59#tqL^G}@S&l3xh4{~#3@BvoCOOG<` zvYeA0g1;!{eEPtd`M6}dJXZL=Dst^evIkzg3HHLpu9kZ6h@I)6wY+;vnjhzED=*#6 zJoQHW{7z<-*Wrk@`Er@&)Pb+S2RGY-=Oi9~NeIn5c1Z!wHL8BMd1f)Z#A;B|sN2i! zZzc=Hkxd$?!5rMF0G=N!YE=~ui4l*7{NIGz!NruKdZrE8$?mm84GX*MDnXaSUN;j| z8gaQh$5^YSFuE9HKkcGvo8TQ2!QA5PjSfXi=nT|0;(rV(U){cJj8+l>jnt9K0 zyvqjiqk}vbfIqQv+pD;>BTN%1W2Wq&$HnBudN^b|^OI_|pVLpyX@wVcvs0kaJK%NF z6f~!&WM%gW0PF^2E!!&=MI6RyU zZ2oc(F9N)KEBUty7H$MRxeU!~5a(_Yn5mbp^*r`!cA}d2K}4-|7rDuWjreb!#O*pF zwT*d+HMq?Ux-ly7(}vUI(e6T2k+F0w2Vulw(A%n+GBV2k%yJmQp{zI@G7ZFAqsaVu z9P~;Ah<{daZ54Q81pjCmIBzh~MFgnF>0$@R)zZUnfv2pb|8h9l%}l9Aczh>0x{f$+ zql2^tR@?w@Rp7l2vqiWBKD8e-Re-Ozn||sX7`k?_k{5oYnQA2tuWSQI$boAoAamr( z%sXVoS5W0{BldcTp-o^J7nr0T1;|chszr0Lup6Tix7V=8jkeSXXX;ETWcol4%1SQy zpo99!hey8!3>c4ZB*f&MSTJ@FgcpP7s+wNMQR+=?llsK`MjoKbY} z1Ke7H{vS?_C)0+=t+BAE!L)8_;T)LtcJ_UG>6B^C7{ZlN3|8m^Ddd9_xAN+QH99Nv9RPpc0tFWUsR*RjIt4{oQ(xT>2Y+8G=O;>xIzQ$rLp4Ctpd@GWO}GF zn((=}@Qc+`SsD%TiZkrY5vV1LTBso^$!f#!l%+Tc1`?g*kvjY@Hcu|9O$YspzT^rR z{%~?UlgUC%7>fnz8U97;vHshP(!qJlBkxN%_BC~@zVRbIdS|PWw^CkiO~iMQVusLz|Yg0JjyM~=4YzK zlhZ@Ijs=YtbDPA!(M=3+aHopU6B_A~4imk-#DXgBRwtUDjV_M@qId%_VURoKh6k?5 zsOO#y;7y7L1(p-h>v7%m)AJNZTrVR^v~ueVrkdn1buU1C?Flmp<^&XjVw#Bc!$b}r_plli(FGc`gW?N`AR+GK5URO{++9iR?;w)I-~`U69<7Hb z93Th86H&^!pKbWeEVyoSVQw19mtmr>m$zKS&FBQP+29`vh{6rL=|OIYn@tQA*KLF!x2F^i>R+J&|n&$)THr#>=!Hm^Jv#F0<* zDFh1@6BkRtXyu%1CHJ_RJW@-aWRUz;&*p^?nYW30xdlYf#<_QJ&%20PJ-W@PpL;O) zGaEY{R0vLLggEYrn|I-zuxBrycTxx@EG9pcQZ<#6w<_5sRn6(wvNtivy{hLOg+L%p zM57jvQ5#XR1I*UN?fBctY$HTaBg2BW8pDPaJ09^^W~;ckm+`zq5A~Q2td~vP&jo|# zlaC6i(2B{ErQF+c-f1N+T<$|S$*AUD{5HuD@5fl z1~HaW50`^wD?vp*_yHrFrZsgF5wnH-&<1krpgX1uMA?(s0OoEa|2C5=TEPYFx|yO& zVycm@|2ZSwl5V9+w^64%(g*N14S|wnuWvP#gv|9XpxP<|c@>joO6jXg*V$C%5vC^_ z{vb~`ofU$Gi`jK%-f@r53+DFYN6DcU$cz5eRbaXryvG5sW*zyh0Sw&8Cb(QCh~E@1V@hNtY-Z+YR)alnT0s77GE3nT^BWH zAC>SB)%hqmMJ5Ww(xDa4{AVATJeM;q)VTuX_zmH^;@Kh<4VI}oyEj4sKb$ye&g}S2yOxZ(yHUP35rjoV5{n+7s zTyQ=fkXJTbPd+?PF&s}hsI!_o8>A`-QL6|a+W{);q0Stj`W>bsx4^yH6Jyy85YPDv z-pt)ogdw>`CkKJn1~A4ks3IgI(!w4WYAW!XD7XW zy;KH+&69w@AcdaMleRR!`2fVvt$T+N^@*+nID0Q*5$VbGPqgjgHiAt#8+ z4Vvn#*eLi%45#H8Lw^zO%&c#!=v}JO{ggqzdp%!1 z#J6wa>$mXz+c<#^&Y+7^=;0jtIEewyVu;fi<~&9@5esJ$!>QPHTcwjaCJt=xPWEs< zK29i`Gs@+Z@;RrmNM6cmm2+N|oLDtyR;!yU>tH+@=*Ve=i)p3~YNa-4r(W!YyXppa z|6J@HV}1EW`?FMAG{28$0^ZyjZB~Lax1h`r2(txr*#WZb!S68uq8#3eXZC;|vte8E zL5;;A#&XbNb$U1KdLJyu*16Tuc-=C2D@V$kfd zFIr-B{DL2l^LG&a-NgPJxUM4Neg#oKK+JC>;45_opaL1D`moR|X~+NNqRY;M+L{fskq_%r3=>rjKUPhI2@+jGM3xq! zN(T|8hiEcDBpD`(Sco8Y<^Z~g93G-ZHW4GAXi*F!QcjepCPD;>4k02#3sIqih|mKP z8vun3Q~6lvVX}k3Ty&{=V3)H0ufbsdUR*DtGA^SkuF|N+x z@S7uWu2yiigIYI^I@b$}p93#aKy6z>U0Xp-TSGltM=je(9otF`+e!V}3uiJ2Pdh@* zYNcLvP^-pKr+RhnQy$f65tV5fRcRGmcL4sq0ZpJ8cBP$aLgJqEy@aVH3}T&)nL18X zMmPA}4>r%EwkV>mD5IvR0+|Ou1Pbi`?DdSaF z3IAHQ#OUN7W}Y*%+qQFCfV(K_aEf1sTmtv{xwz9;*K*w=)<{zt(<# zUzzLJibs{W=+`*!{s%g$;rAOp>X&NRp)t-!Dom5(adYbnqKr-%cV74#leuYwtr_69 z%Q?txcPbxaGBNp7F~Yk9sA1}~ifPkR8lTfgGwf6^apP*wJnpts%TjUHajV;@T6(zC zecWoPcEe;H2Q^DPH`>DqNKKu?DU@*zW(6FiT50Ac_fn~ZsZ*pTb&!4J7W=7D3aL)Y zs7-3Px%GN?rONK3CJ9rKSh=sUdSm_6BZXw2GO|w%+I>BmN+bEFn;K+5b!?sUlIJ(F z$w4vHA5Jom2gTZtW>=yU9jdhU2$6$YBMNjcS;#I_pk zZllH+fbAYphldq^nN*M2>g32L165L21XS^Dz$eg2?lIZPAv6m+)kGXwN2-ZDRe8%* z->oLwG*LselWRJuAqJJ@ilKUtJmVq5dgsI#u)B-V7 z?(x*@eyV_ctph656H>4JmQB3-9?<_FmHH?;kco?&iiPs&-Y8MFH9&P9Qiin!R<#eT zA66#S0Ot#D>Qj_or2J^LGNVDTY8yGATaoH8s;!mSAFI*dPu$O+z-U(S3WUF$$Xxcp zZCiK;;~7d1RlV?$Wl<)wTH}5r5#M|fTjJIbHNBmPKQTV#5b?{X=qEBUAzvGjs5|m5 zgasPbnC~Fk$LqVu=4F^XO=0A9)Dfu~Kxd8mMp}vX{Z#YA6WAL&)x3|Fl1D8+#wAI- zH{Z)dZmNq~ewava1-03z<+r?@JSusUfhwbxuh43~o;tpn7u3N7u`Yc_y(rxy=#+k= zpEo2pUS5$a>i+P7=8Abs6%$+@b*R1VRPjBay1uBJV;GG*7Vn08f@>oWXF&xud@V|B zFzU{bIXc4D3{G%SO?+c{V7&rGdzIk4K*Sl<6meCwqXvi$U@8FCq!=oA!FnEbSQJd~ zR#Z^EOI_F!@lcqNx(AduO6@Lh&%x_+g7f02-^~|TO66Wo?Ow?{6r2|V;k9m6GY(QG z+CX>{Yr||1o>YPpYrqDXstdlG$g_>2guAHPy%RPI74SZ*VAv++s1_KuzQ`*biEawA zQL}q_tGSW4T1eGi498XtyH+=$H(ILpe(LpMxHT*6+E_i~qK3((UN6$OYi7v`YW6yP zy=@bekv`tAg=*cA7CTM>@lvf9p?8!|P&&rH=U!^hepNKWs9W-?<0mK=xx8)BDJCiu zjUc-2NQN5%(G6>!v!Fi2ljr;s6o(@4Tn&6(J!mcznSs>8`|i;Sc0_sMvD(!E_VB~j zO~f1JAUV5cKBw|^*~-3_;INU*R{>imXs$t7<&G$y zEIDuhrY;5?=Y*$=<88aC!UW3|fZ|H2!m2bE)`H}Ot7}olxtDy{ADMR`NX|w^bivVi zVd*3<<|tEF%B!xTG7CnsV~G6N%-imTqZ``d@&e=ejY6%{EWB`+=E$50elFR?5`d!% zP4I1X@VbX0`O+HoXF2g?<&ZTCC-|@`dEFuO($)!n$zIe`19zmI&YxH^sL8^5sN)J@ z=gO$!Dx&_!0PI{VRb1But#4vB^+ed79CB(IHC*)sw^WE4u8XWXQAIL%-EmZKK6p9F zueoq@QpJ@kM>LTgYK0LJE@*fH3uKSv+KFsW85y^Z>TM#c(?#_*45vTF-Z+#&kAsuT zgFi2Zk*iSlydH;8v+7u#yz6e|&du!W80Xsb@UG=Wm#I6mD)OS+bWd>?T)8k5=392a zNBChP^5NYC>z2ch*Tc9qtG?N;nx^@7<>k6jEwhznE73Pw3-WB3ph&h;hY1!Pr3#Zw z9HW((n;I;eOe}b`7@kP}jlu=vN@gAG>J+^^C2O=*~sw$_VPcy&f^9JSh1>nl1mTJ}4 z*Qc3v2=r+OeVXsiOHLJKrkvVI*ztN*dIWt+-89HM8^zyb=20haOZiba9h+}Y=_+zZd>wVvHFM0$&2;m#b(%#R=gPFGhz&^hrE^?jKbcX(aR2D96#{X@fHrwzQA8VSyWUz-tIADqXJm zaG)ic^D1CGh3jmIu$-N6)M4I(MHO7T?$Pt|5{h^Um60hP_2V?%vA58RiZlu@ZK6@z zI4`s0I=?!XWr|qMgcs3Aej5Oln)z*vr;}GvNOr4G)uieT`&kl0g*lQ3r zwMbt?P+vnUh_nkt+7BOLL^QwHsPgUwl@?7<*y~hTZ;hhT?nrGG0}l~L*2<2k#m{_xE zoW41zNYnnanMiU_NEOf)-b5F#q6a>qkIKwgV$r(HrCfr%j3V%5B??hMUqv%>YuX~% zvJX@l7H%QnH`=Ic4fPj~N0wgPOht+;&AijZ3y~U4INweXWf)z^tkK+xCjGpT5`81p zks7UmT+=?m(K|w&wk6MawN8@`{Ze(;3xW)y0X30f+F=SiHOutD6I#HHF0I!5V8=o- zi_~gT>(@u$N;hf`<^`sd2v#)TiR6)z2tt%B(h}7a1|nL5Mb!f<^^ONuND+KjE$)v_ zBCGK5P7shV?}B=Q+?#HAt06E>986Up*u2>T>xrBzXi zsVN%D2YVv?QZ-y~J2i%25Q%}J5te~BYL)YCr*g0;KO|937$H;VYX?D$LOlD80nSbk zgM*qNpALy)JbD!o4X+cQltpzrr_RXC!9ljqRvk|8d+_h_w1V8@ zh*kM~`zpSDqv~uX7aOKVj@>2$E4aK4RNg_x9`(c!le|QuVz76Byxa!f9wheIseb)1 zr=?`xIx5}{@@+4wmxa!V{HPXP7tytP$f*YSSn63n*|ZqeC_pA{!ynW|)Ue?DiRV21 zWY0>@vyQyks;s5tN-HtK)KZGzDC;#dwvrbII9Zd0^l`SusxJqWd2E7{k@GboIcIG{SOuz)_^YXL7d$QjE^ z9Wwp9&3>bkGq&RV&sN^PB%;!`@(zbpnYE!%n5?~=ZAcZ^cKnc|s=7MBbdrtAz;R8= z!OOd{P>tDDO*Of8QBWHq{CY20$B1z1UJ#kdqX#_AWSBnHLnWtpR0A~`a?w3aRy+)@ zGMRAEH>=fw(4cB&50%jQJLfpPSs?O zV?i|%zsr;_u2(NW>o|_sLN(!5^`?^gp;2}IFy|@Ceh#NuOpVaMS&Diub-w8Jd7Pvu z^o^Wk2WZ4-_Z!0+XKmE)qQR7aK7x3l8^@{aR(dMjVE1g!vy>LxYR)23F^4})duBjeAqE~0}B!dJQUEQ?g}Xap6A z#$mun#ZJ&OM5Pu)+!A$?41fSeKmg{6=Bjr@)M(M6ThuSoO)Wc0uJ@u0=ab*?jd9CfLF!V)VYQAa-!lueA9aQXU0lB(~!G)1`TB#n8Ce;T9 zqRtP&s~+BJ5wW-yq}obOHe;~pa^_pjj`}&u{>I1A8{zluk(ZmR&JE#tLezl5(*W#8)|@eh4{nUqmr0Ql+es+A5r62O$>1iG==v+U3W+P#V#< z8Y6y%0dSxVhk_3dvP3-z^+e-d^$b~*b@bpo$fx2dk2-{!IO}fp1<6^*s3*t+qAMUW zm#Pa$-f;`@xzig1mh`x`fyovPLYcFzO5%jt@nqzxun zJS1|ian!H5yyG%rbC7)73PzWAY``|jE0)+?3d0oOT*cAQ3nn*D(oH>DNgXQLR-$qj zm1v)4++jUQR|HQLlXa^jjxJ$_Bu4j9fm+~u<2lLvZK!&!s_FG|n!*A}<>^rNr<5}l zM^>-8u$-tG@^Wj5)8elh0WHVE*GSgg+D+A@PO2>~DkJPSMmXn~Z91q*x8a`Zn&6#^ z(THBm9SERYbik+%D-M<$5EpU0`J!&9(g^2L^)q-ZOsw~UfvaFkJK;xd`r1q2LIdDi z@huH1&T?`O1ZP#ifHZLr+M{kHtEvqi^&l1T$|bS~{*L$PZ=FX4u$SWeS1F_p5}>Z-i~=fx$Q6_u|!CQ310c)1$;uF-pdcgSQhOMHMf+iHzNgdPPlS zEH#GoecMp2d=YdlZ#)FE-c1EGN)KEd>_9#qxGG|J6Rx*jUblslb#tPH>VODP{kM{- z2Z-D@^0W^WT>^>@g1Fj=*h8Ra2h6s37YfviR*PGqm3KWr9dE#1YodE4JZ}al?IGPY}&}kJ}T!e8M!u+llwqfF7Q<;m|5_0OSC599+ga_e(+?;I%ueP0v$;w;J zgAc6(clG}rM`9`1t9ct9L{Ty9_?6#35BSMidb`!1yHX$JO=KT6+{Llw*| zdPjED!BQUW%&3ieSlXhU7(Ed@YK-f=h*f0jpU`Ph9CfmoI=|>2O;ImPAGPIx`s0U* zXf}1TxT5-|FY0G0jXKV&c}ETEXlVh}nmS0AW)~sXRme{B+;)%Ljid7jY(-#?t_*jb3$?SLG?T;ffyf1~nJkHDqE(T; zb(z5|=&han-AR=1Rvc%db?dmf5-z;!g6f0;E>HzU@SW6ZfpN1V1nYGw+UpTwpvt5O}bwd4(xeQArh6uR)l4Mu# z>$WNCcJA|tvNEXNIBUf3?25W-eNo4AY1Bnq9rZl7MEGQ>9{Y8E`^dP?AbZsJY(^eY zS_&0;R7E3Co%SlUM!e5GR2_X}wE?P3GxkhWU2+ts7NMj{gU~7ZXH9(qv=-AQSO8cTSE-#rpv+M6Gkd8>UtB_Q8Miq^VkP6 z7Eh3Eg3ql$9YNK^fI7{--Q!$s7MRGKaXz*xb)hzD&D*aYR6DQP4|W!g5`QUo6y`X6+R7NDdwC`TElS2z~rTtt2? zQ(u2TF_)+$g1YRg6}q_1@#^E399pyu_kPzlyGexuk(#)CLU)W=8;_x|0eF#Nx*3J< zvZH%QW#z$(lMR;6SMEz{tV;Ee2kBD$SN-E9%4N5Z!-UI@!G|MUb}3p%Jz1%PJTwf8 z9m|c%rQRy%9)(ad%wGGToYCM;fA5E;stRPMLV;k0`G}*V#Q48!!nt)Qsqb6wXQO&s!Hw8 z5WLi6I zga?;=98@m6gDgD4&5(QHrK_j_ZK(?0CGa=BL<3Z5G295xIG1_p1dqAYZ0-1sT#C|5 z;a|it-plDbi5J;m?ON^a=~ai&7@~GWJ9-Mh(IwGdo(2%KRBb=k$CD2WQ;mZlq}*CN zcVfuvi1g-|9C_6^cCDLyBNccYdRDG-YE{I6z<-G|dn^n2U|Op|rCnqjJE*e|l`{mY z9D-Hzz>`_T59c9-n$i)77vT!hb^tt zUNccSTB)`BVN=AvBK5Wx%vGTi5BkTkq_%(9H5Q^)>*Cc9Cs`FUWmA=vtDme*8Pq$3^tLPs3|%x-i8z3tYhT;7vQ@ODr4TReCc4sYac^xlFv)8r}h|R8i@l1+fOf~ zC?9py5uNI#8s_wz)C~ENK1Xp+Rq6|Gh`J)XGNo4~2S!}Zv>Uu{g-wgo$ul*m9-Zp{ z4V$>VY^nBsni{jbVsT&yRxeStvXaPNqpDV``V~jq2JT-$$!slXc|2)qph z-b;)hA;x>b*cIUFR(R8qM2EU53RD}e<4k*%SMe&RQpeluC2ouUSfHF(DePWjs?Qj8$4X8XZ)}C0isa!&nCuR`2>sNS z;jMZjd}xjZygP}>RgpgbpsG}3Y-qo_#D`FqtvC@RGUq7XD^O>wFr!uKo(rf~yg^kg zaVE5B9oeT9WLP^Q?5b1d_>AVIsyR8fa*Rq&%_ghn5=rwXR83{-h>`QCj`(7Nyufds;Dif}K^OOxN)>^3wXHEeBX#?He&8T(l@ci96t8PG98pA7Gp{TJguiNWUhDN&Q z#DQ7{eyt++1Yi&w$Un`ni0z<~ZeB<~dO#TbYNT0|opFL+-KxcBqYj9}qL?>R&YO`= zil8zx&8P+Kyqs=a<^A|Bq&6~ewAs*fop8o(=4beMKY3J2MR?lEct!Gt0>rom6oqEE z$ac_8H>|R}qA+hr7#SNHk&~C?hE?{1ar20MMJR@4XuwsV9eGI&VBTi@ZtWo7Zk(w7 zyrVD(*ue8<0|PnXF5Sv8XM=_E$#BKW!c>vz0(6cyfR3BtG~3aWx^cjbXD#|8JrLos zS$^G1jUJ2SILp5{%ddo7`0u?a{KvFcnaLXWBj9W_#Y z$^8z4ob6;#FRZoP(<*ev5bQ&z^44M02Rn#JVr-$h(Hc~B6b)hs6+*ack9yB4;3?~I z3ACdw4}gfpdnpxE9`#eX#@~AIu&~$zcm%9qqImU7mr>UTH5#{}F!tm7uxM|m)a<3| z`v|IgvKJ*voMKMyTO1XWn>*+I&&-#t9N2~1nE6sYE~`v*W}CUCc%7Jz4pbP`ADI7fIjo{lX{XhXE~qXka1 z4OX;6y{g^gn9)HHZFsAW5Sw~fw=kt{5U*EzM5G?h-KtZh6eZGhxK@pGme*;omFewk zjxee1>U`be^6QT}&bKhD)(M>@g2LiK*q#YYYaWQZK%KJ1I`gC~(s5EXj(M%q{w>o% z+l&Uf#VxpniS6Gyru8p1YW|O6S~2MF-;HWR>O%Yv;uuAZvM?bdMmuc&ClNtVtWg8MG2ph2Q;VDt2Z&d(S9Zh?oljLO6@v#pstm*>opH?|t{$EKI6_BU zCmM^1YEA!B(SN$-BRb-E{?JqryK!^$t0PY}MB_LkM)Q@)Gdbx98P770aT3Bvh|{A% zS;kiNymv>`!!R|jaE`X9b|}nL4%MtMkR|wh#z)*@}*f7rhC+@I+joGS;DuwObpYH$6LsBo>f9E`;EsT)3;I{2<9HF|kYOj{_ z|JkV-71~o-tFtlcwVy>0Z<{KNUE0wik#tCBWQ?K^$dnB6RXY{k3bys57v$=!j6&_A z7DQW#lR$g~LDdjK+Dk1cwgW!0Tj!!lBp5Qg!Z7f|0&OggF&B1UHz2>TVUzHT4Yx5SBj?aVAu zW>aECwf0`u!E%O_qt4`MRS!a!MwdRF4Jw#$RQ;-=p*gf`J6^pAGM^_W(%V_2_)pMZm3D6j6!(R6 z{+dkcY1dBf9$4Fc<=?}wx1-wEX48p1PW2^t;B);twI@%fd=;y1E3T+2owg8Ee?mw* zKwEWwPp3}w>Qj%xkoJKZOfQW|5soYu?pOG+N;rGr#+qP(g%|6?0V_QxF}UYk@L@jn zvlnTXg79GV_>_bL>!OEq0RC&#Yel8$KlAx`sd*!gIwE z2ZZAi=3e-%O4Vo^l)>+S*XqM(B%GG0wZdol;D&|E5)P{#CRq3@=}{SgyBbwjq!Yia zm%g+-W*wHG;#R2xUbrgh)9h!u;Rp(zI3?ql5#mS3E1)tKzhsT}tu#^nc4%MHpgJdG z=+JcGjrJ+$UxXJ=Jd^<{)<*ThccB0b@LI)9Y1i8Gzu9%qy11D-#zPkM@m}nJ%iEC6>Ll+uIAADRGjnay@!3ifP zuF^bp|Cdvh)M`IgGu&J!YIVPMd>7p+B{5C;Bo@j^J1N6w}HvltG!5-m*l<0jn29dO5e>R2`Cf_5lp?89p;d~qob zzH0TJH!4rurM+HZG;q7lof4(RjR!)yzH)RTvhc%|5w%79dcqMmY0r>2(mRzW7SG(MzFw650mbCQ(kJ6S&WMZn`ov@J(D^3uipzbfREbVy z>V@L$t3aQsRdimjx>U3FT(qkq)uR}FKplR<3yBV8)5)c#p6F2(Sv-D%)(ayuh04|G zSM&chcZSYsgi#PbaRPAyQGqydG9rR@m`nuX1OgFJfnb;uhzbM(fryAeAR-V51mZ+Q z1R?@~Kp-Lz6$k_Z5rK$6AP@)yqQAGLLui|jnap&`U%`;<>HS920_?qt9@)g}7sJ~J@9OT?I@_GV<~(WQ>yJT2 z^Y%~V315SQ2{16g5o~G7uX2aiLA(}dcdt$H3%c4>hU<*IbRo`@qP*faxa~Sj7sl)} zcw)Ec2A$f&(`zbGR>__+iuJYBp%@3k0A*+*cmEpSZbFLCIhtq=pMS&_gE~r3OG&-H z@;x*85L~n$pE-O6{rWxq`V#w0A+@yaY4oegvvNSdF&H>Kfr8B!IQV^!gyxxbwFl0p z-wY4UG5Z!Gu8uG4LEF9 zIZ#WJ%{afVOi2$*&I7)vLx)_#Q*-i1MamPJZrhS#d#|+iXx|eH`e92iB-#FRh6WqT zb0)F)qRQ;dZY4=!7Md}f3hd8~>;vieCZdke|_C5~0)zWE6Ab3efQ zey{vv?w3NfJg~p=AN=oE-T#dNHt~7Ha`rufB6F!64m-;|xw(98B`|Fx3wj(X{u}4E zXKw8Xsoys5`33j5n1Pkv2KU<>w^t$sQFGa+;WuSS<36v%7WD zyv0VOPxGW&<`+JE+-_*;!mCr@ewR$ymQ;Qoj@(7@U4r44rJl^3=M&c^WE zCy>;VK#@{FBesoL0w|jX{XC?nft)zSU(jaLS?6iDhz%xbk{E#!I%N!~PH@#!?!ip}o hq<_r3C<)7~fI&T;rGRh75=b*8_A{_VeyIQ8^8*rT1d{*& diff --git a/sdk/binaries/x86/FreeImagePlus.dll b/sdk/binaries/x86/FreeImagePlus.dll deleted file mode 100644 index 448b25d2e78d04a86d73f0f5781dde983bf6b1e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111104 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 YEg))&H=r%Hi2f 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 I|DS*V34(w6-2eap diff --git a/sdk/include/FreeImage.h b/sdk/include/FreeImage.h deleted file mode 100644 index 12182cd8fed..00000000000 --- a/sdk/include/FreeImage.h +++ /dev/null @@ -1,1163 +0,0 @@ -// ========================================================== -// FreeImage 3 -// -// Design and implementation by -// - Floris van den Berg (flvdberg@wxs.nl) -// - Herv Drolon (drolon@infonie.fr) -// -// Contributors: -// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#ifndef FREEIMAGE_H -#define FREEIMAGE_H - -// Version information ------------------------------------------------------ - -#define FREEIMAGE_MAJOR_VERSION 3 -#define FREEIMAGE_MINOR_VERSION 18 -#define FREEIMAGE_RELEASE_SERIAL 0 - -// Compiler options --------------------------------------------------------- - -#include // needed for UNICODE functions - -#if defined(FREEIMAGE_LIB) - #define DLL_API - #define DLL_CALLCONV -#else - #if defined(_WIN32) || defined(__WIN32__) - #define DLL_CALLCONV __stdcall - // The following ifdef block is the standard way of creating macros which make exporting - // from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS - // symbol defined on the command line. this symbol should not be defined on any project - // that uses this DLL. This way any other project whose source files include this file see - // DLL_API functions as being imported from a DLL, wheras this DLL sees symbols - // defined with this macro as being exported. - #ifdef FREEIMAGE_EXPORTS - #define DLL_API __declspec(dllexport) - #else - #define DLL_API __declspec(dllimport) - #endif // FREEIMAGE_EXPORTS - #else - // try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility) - #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) - #ifndef GCC_HASCLASSVISIBILITY - #define GCC_HASCLASSVISIBILITY - #endif - #endif // __GNUC__ - #define DLL_CALLCONV - #if defined(GCC_HASCLASSVISIBILITY) - #define DLL_API __attribute__ ((visibility("default"))) - #else - #define DLL_API - #endif - #endif // WIN32 / !WIN32 -#endif // FREEIMAGE_LIB - -// Endianness: -// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined. -// If your big endian system isn't being detected, add an OS specific check -// or define any of FREEIMAGE_BIGENDIAN and FREEIMAGE_LITTLEENDIAN directly -// to specify the desired endianness. -#if (!defined(FREEIMAGE_BIGENDIAN) && !defined(FREEIMAGE_LITTLEENDIAN)) -#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__) - #define FREEIMAGE_BIGENDIAN - #endif // BYTE_ORDER -#endif // !FREEIMAGE_[BIG|LITTLE]ENDIAN - -// Color-Order: -// The specified order of color components red, green and blue affects 24- -// and 32-bit images of type FIT_BITMAP as well as the colors that are part -// of a color palette. All other images always use RGB order. By default, -// color order is coupled to endianness: -// little-endian -> BGR -// big-endian -> RGB -// However, you can always define FREEIMAGE_COLORORDER to any of the known -// orders FREEIMAGE_COLORORDER_BGR (0) and FREEIMAGE_COLORORDER_RGB (1) to -// specify your preferred color order. -#define FREEIMAGE_COLORORDER_BGR 0 -#define FREEIMAGE_COLORORDER_RGB 1 -#if (!defined(FREEIMAGE_COLORORDER)) || ((FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_BGR) && (FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_RGB)) - #if defined(FREEIMAGE_BIGENDIAN) - #define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB - #else - #define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR - #endif // FREEIMAGE_BIGENDIAN -#endif // FREEIMAGE_COLORORDER - -// Ensure 4-byte enums if we're using Borland C++ compilers -#if defined(__BORLANDC__) -#pragma option push -b -#endif - -// For C compatibility -------------------------------------------------------- - -#ifdef __cplusplus -#define FI_DEFAULT(x) = x -#define FI_ENUM(x) enum x -#define FI_STRUCT(x) struct x -#else -#define FI_DEFAULT(x) -#define FI_ENUM(x) typedef int x; enum x -#define FI_STRUCT(x) typedef struct x x; struct x -#endif - -// Bitmap types ------------------------------------------------------------- - -FI_STRUCT (FIBITMAP) { void *data; }; -FI_STRUCT (FIMULTIBITMAP) { void *data; }; - -// Types used in the library (directly copied from Windows) ----------------- - -#if defined(__MINGW32__) && defined(_WINDOWS_H) -#define _WINDOWS_ // prevent a bug in MinGW32 -#endif // __MINGW32__ - -#ifndef _WINDOWS_ -#define _WINDOWS_ - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef NULL -#define NULL 0 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#ifndef _MSC_VER -// define portable types for 32-bit / 64-bit OS -#include -typedef int32_t BOOL; -typedef uint8_t BYTE; -typedef uint16_t WORD; -typedef uint32_t DWORD; -typedef int32_t LONG; -typedef int64_t INT64; -typedef uint64_t UINT64; -#else -// MS is not C99 ISO compliant -typedef long BOOL; -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef long LONG; -typedef signed __int64 INT64; -typedef unsigned __int64 UINT64; -#endif // _MSC_VER - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -typedef struct tagRGBQUAD { -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; -#else - BYTE rgbRed; - BYTE rgbGreen; - BYTE rgbBlue; -#endif // FREEIMAGE_COLORORDER - BYTE rgbReserved; -} RGBQUAD; - -typedef struct tagRGBTRIPLE { -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbtBlue; - BYTE rgbtGreen; - BYTE rgbtRed; -#else - BYTE rgbtRed; - BYTE rgbtGreen; - BYTE rgbtBlue; -#endif // FREEIMAGE_COLORORDER -} RGBTRIPLE; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -typedef struct tagBITMAPINFOHEADER{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -} BITMAPINFOHEADER, *PBITMAPINFOHEADER; - -typedef struct tagBITMAPINFO { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[1]; -} BITMAPINFO, *PBITMAPINFO; - -#endif // _WINDOWS_ - -// Types used in the library (specific to FreeImage) ------------------------ - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -/** 48-bit RGB -*/ -typedef struct tagFIRGB16 { - WORD red; - WORD green; - WORD blue; -} FIRGB16; - -/** 64-bit RGBA -*/ -typedef struct tagFIRGBA16 { - WORD red; - WORD green; - WORD blue; - WORD alpha; -} FIRGBA16; - -/** 96-bit RGB Float -*/ -typedef struct tagFIRGBF { - float red; - float green; - float blue; -} FIRGBF; - -/** 128-bit RGBA Float -*/ -typedef struct tagFIRGBAF { - float red; - float green; - float blue; - float alpha; -} FIRGBAF; - -/** Data structure for COMPLEX type (complex number) -*/ -typedef struct tagFICOMPLEX { - /// real part - double r; - /// imaginary part - double i; -} FICOMPLEX; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -// Indexes for byte arrays, masks and shifts for treating pixels as words --- -// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- - -#ifndef FREEIMAGE_BIGENDIAN -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Little Endian (x86 / MS Windows, Linux) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x00FF0000 -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x000000FF -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 16 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 0 -#define FI_RGBA_ALPHA_SHIFT 24 -#else -// Little Endian (x86 / MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x000000FF -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x00FF0000 -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 0 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 16 -#define FI_RGBA_ALPHA_SHIFT 24 -#endif // FREEIMAGE_COLORORDER -#else -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Big Endian (PPC / none) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x0000FF00 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0xFF000000 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 8 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 24 -#define FI_RGBA_ALPHA_SHIFT 0 -#else -// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0xFF000000 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0x0000FF00 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 24 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 8 -#define FI_RGBA_ALPHA_SHIFT 0 -#endif // FREEIMAGE_COLORORDER -#endif // FREEIMAGE_BIGENDIAN - -#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK) - -// The 16bit macros only include masks and shifts, since each color element is not byte aligned - -#define FI16_555_RED_MASK 0x7C00 -#define FI16_555_GREEN_MASK 0x03E0 -#define FI16_555_BLUE_MASK 0x001F -#define FI16_555_RED_SHIFT 10 -#define FI16_555_GREEN_SHIFT 5 -#define FI16_555_BLUE_SHIFT 0 -#define FI16_565_RED_MASK 0xF800 -#define FI16_565_GREEN_MASK 0x07E0 -#define FI16_565_BLUE_MASK 0x001F -#define FI16_565_RED_SHIFT 11 -#define FI16_565_GREEN_SHIFT 5 -#define FI16_565_BLUE_SHIFT 0 - -// ICC profile support ------------------------------------------------------ - -#define FIICC_DEFAULT 0x00 -#define FIICC_COLOR_IS_CMYK 0x01 - -FI_STRUCT (FIICCPROFILE) { - WORD flags; //! info flag - DWORD size; //! profile's size measured in bytes - void *data; //! points to a block of contiguous memory containing the profile -}; - -// Important enums ---------------------------------------------------------- - -/** I/O image format identifiers. -*/ -FI_ENUM(FREE_IMAGE_FORMAT) { - FIF_UNKNOWN = -1, - FIF_BMP = 0, - FIF_ICO = 1, - FIF_JPEG = 2, - FIF_JNG = 3, - FIF_KOALA = 4, - FIF_LBM = 5, - FIF_IFF = FIF_LBM, - FIF_MNG = 6, - FIF_PBM = 7, - FIF_PBMRAW = 8, - FIF_PCD = 9, - FIF_PCX = 10, - FIF_PGM = 11, - FIF_PGMRAW = 12, - FIF_PNG = 13, - FIF_PPM = 14, - FIF_PPMRAW = 15, - FIF_RAS = 16, - FIF_TARGA = 17, - FIF_TIFF = 18, - FIF_WBMP = 19, - FIF_PSD = 20, - FIF_CUT = 21, - FIF_XBM = 22, - FIF_XPM = 23, - FIF_DDS = 24, - FIF_GIF = 25, - FIF_HDR = 26, - FIF_FAXG3 = 27, - FIF_SGI = 28, - FIF_EXR = 29, - FIF_J2K = 30, - FIF_JP2 = 31, - FIF_PFM = 32, - FIF_PICT = 33, - FIF_RAW = 34, - FIF_WEBP = 35, - FIF_JXR = 36 -}; - -/** Image type used in FreeImage. -*/ -FI_ENUM(FREE_IMAGE_TYPE) { - FIT_UNKNOWN = 0, //! unknown type - FIT_BITMAP = 1, //! standard image : 1-, 4-, 8-, 16-, 24-, 32-bit - FIT_UINT16 = 2, //! array of unsigned short : unsigned 16-bit - FIT_INT16 = 3, //! array of short : signed 16-bit - FIT_UINT32 = 4, //! array of unsigned long : unsigned 32-bit - FIT_INT32 = 5, //! array of long : signed 32-bit - FIT_FLOAT = 6, //! array of float : 32-bit IEEE floating point - FIT_DOUBLE = 7, //! array of double : 64-bit IEEE floating point - FIT_COMPLEX = 8, //! array of FICOMPLEX : 2 x 64-bit IEEE floating point - FIT_RGB16 = 9, //! 48-bit RGB image : 3 x 16-bit - FIT_RGBA16 = 10, //! 64-bit RGBA image : 4 x 16-bit - FIT_RGBF = 11, //! 96-bit RGB float image : 3 x 32-bit IEEE floating point - FIT_RGBAF = 12 //! 128-bit RGBA float image : 4 x 32-bit IEEE floating point -}; - -/** Image color type used in FreeImage. -*/ -FI_ENUM(FREE_IMAGE_COLOR_TYPE) { - FIC_MINISWHITE = 0, //! min value is white - FIC_MINISBLACK = 1, //! min value is black - FIC_RGB = 2, //! RGB color model - FIC_PALETTE = 3, //! color map indexed - FIC_RGBALPHA = 4, //! RGB color model with alpha channel - FIC_CMYK = 5 //! CMYK color model -}; - -/** Color quantization algorithms. -Constants used in FreeImage_ColorQuantize. -*/ -FI_ENUM(FREE_IMAGE_QUANTIZE) { - FIQ_WUQUANT = 0, //! Xiaolin Wu color quantization algorithm - FIQ_NNQUANT = 1, //! NeuQuant neural-net quantization algorithm by Anthony Dekker - FIQ_LFPQUANT = 2 //! Lossless Fast Pseudo-Quantization Algorithm by Carsten Klein -}; - -/** Dithering algorithms. -Constants used in FreeImage_Dither. -*/ -FI_ENUM(FREE_IMAGE_DITHER) { - FID_FS = 0, //! Floyd & Steinberg error diffusion - FID_BAYER4x4 = 1, //! Bayer ordered dispersed dot dithering (order 2 dithering matrix) - FID_BAYER8x8 = 2, //! Bayer ordered dispersed dot dithering (order 3 dithering matrix) - FID_CLUSTER6x6 = 3, //! Ordered clustered dot dithering (order 3 - 6x6 matrix) - FID_CLUSTER8x8 = 4, //! Ordered clustered dot dithering (order 4 - 8x8 matrix) - FID_CLUSTER16x16= 5, //! Ordered clustered dot dithering (order 8 - 16x16 matrix) - FID_BAYER16x16 = 6 //! Bayer ordered dispersed dot dithering (order 4 dithering matrix) -}; - -/** Lossless JPEG transformations -Constants used in FreeImage_JPEGTransform -*/ -FI_ENUM(FREE_IMAGE_JPEG_OPERATION) { - FIJPEG_OP_NONE = 0, //! no transformation - FIJPEG_OP_FLIP_H = 1, //! horizontal flip - FIJPEG_OP_FLIP_V = 2, //! vertical flip - FIJPEG_OP_TRANSPOSE = 3, //! transpose across UL-to-LR axis - FIJPEG_OP_TRANSVERSE = 4, //! transpose across UR-to-LL axis - FIJPEG_OP_ROTATE_90 = 5, //! 90-degree clockwise rotation - FIJPEG_OP_ROTATE_180 = 6, //! 180-degree rotation - FIJPEG_OP_ROTATE_270 = 7 //! 270-degree clockwise (or 90 ccw) -}; - -/** Tone mapping operators. -Constants used in FreeImage_ToneMapping. -*/ -FI_ENUM(FREE_IMAGE_TMO) { - FITMO_DRAGO03 = 0, //! Adaptive logarithmic mapping (F. Drago, 2003) - FITMO_REINHARD05 = 1, //! Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005) - FITMO_FATTAL02 = 2 //! Gradient domain high dynamic range compression (R. Fattal, 2002) -}; - -/** Upsampling / downsampling filters. -Constants used in FreeImage_Rescale. -*/ -FI_ENUM(FREE_IMAGE_FILTER) { - FILTER_BOX = 0, //! Box, pulse, Fourier window, 1st order (constant) b-spline - FILTER_BICUBIC = 1, //! Mitchell & Netravali's two-param cubic filter - FILTER_BILINEAR = 2, //! Bilinear filter - FILTER_BSPLINE = 3, //! 4th order (cubic) b-spline - FILTER_CATMULLROM = 4, //! Catmull-Rom spline, Overhauser spline - FILTER_LANCZOS3 = 5 //! Lanczos3 filter -}; - -/** Color channels. -Constants used in color manipulation routines. -*/ -FI_ENUM(FREE_IMAGE_COLOR_CHANNEL) { - FICC_RGB = 0, //! Use red, green and blue channels - FICC_RED = 1, //! Use red channel - FICC_GREEN = 2, //! Use green channel - FICC_BLUE = 3, //! Use blue channel - FICC_ALPHA = 4, //! Use alpha channel - FICC_BLACK = 5, //! Use black channel - FICC_REAL = 6, //! Complex images: use real part - FICC_IMAG = 7, //! Complex images: use imaginary part - FICC_MAG = 8, //! Complex images: use magnitude - FICC_PHASE = 9 //! Complex images: use phase -}; - -// Metadata support --------------------------------------------------------- - -/** - Tag data type information (based on TIFF specifications) - - Note: RATIONALs are the ratio of two 32-bit integer values. -*/ -FI_ENUM(FREE_IMAGE_MDTYPE) { - FIDT_NOTYPE = 0, //! placeholder - FIDT_BYTE = 1, //! 8-bit unsigned integer - FIDT_ASCII = 2, //! 8-bit bytes w/ last byte null - FIDT_SHORT = 3, //! 16-bit unsigned integer - FIDT_LONG = 4, //! 32-bit unsigned integer - FIDT_RATIONAL = 5, //! 64-bit unsigned fraction - FIDT_SBYTE = 6, //! 8-bit signed integer - FIDT_UNDEFINED = 7, //! 8-bit untyped data - FIDT_SSHORT = 8, //! 16-bit signed integer - FIDT_SLONG = 9, //! 32-bit signed integer - FIDT_SRATIONAL = 10, //! 64-bit signed fraction - FIDT_FLOAT = 11, //! 32-bit IEEE floating point - FIDT_DOUBLE = 12, //! 64-bit IEEE floating point - FIDT_IFD = 13, //! 32-bit unsigned integer (offset) - FIDT_PALETTE = 14, //! 32-bit RGBQUAD - FIDT_LONG8 = 16, //! 64-bit unsigned integer - FIDT_SLONG8 = 17, //! 64-bit signed integer - FIDT_IFD8 = 18 //! 64-bit unsigned integer (offset) -}; - -/** - Metadata models supported by FreeImage -*/ -FI_ENUM(FREE_IMAGE_MDMODEL) { - FIMD_NODATA = -1, - FIMD_COMMENTS = 0, //! single comment or keywords - FIMD_EXIF_MAIN = 1, //! Exif-TIFF metadata - FIMD_EXIF_EXIF = 2, //! Exif-specific metadata - FIMD_EXIF_GPS = 3, //! Exif GPS metadata - FIMD_EXIF_MAKERNOTE = 4, //! Exif maker note metadata - FIMD_EXIF_INTEROP = 5, //! Exif interoperability metadata - FIMD_IPTC = 6, //! IPTC/NAA metadata - FIMD_XMP = 7, //! Abobe XMP metadata - FIMD_GEOTIFF = 8, //! GeoTIFF metadata - FIMD_ANIMATION = 9, //! Animation metadata - FIMD_CUSTOM = 10, //! Used to attach other metadata types to a dib - FIMD_EXIF_RAW = 11 //! Exif metadata as a raw buffer -}; - -/** - Handle to a metadata model -*/ -FI_STRUCT (FIMETADATA) { void *data; }; - -/** - Handle to a FreeImage tag -*/ -FI_STRUCT (FITAG) { void *data; }; - -// File IO routines --------------------------------------------------------- - -#ifndef FREEIMAGE_IO -#define FREEIMAGE_IO - -typedef void* fi_handle; -typedef unsigned (DLL_CALLCONV *FI_ReadProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); -typedef unsigned (DLL_CALLCONV *FI_WriteProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); -typedef int (DLL_CALLCONV *FI_SeekProc) (fi_handle handle, long offset, int origin); -typedef long (DLL_CALLCONV *FI_TellProc) (fi_handle handle); - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -FI_STRUCT(FreeImageIO) { - FI_ReadProc read_proc; //! pointer to the function used to read data - FI_WriteProc write_proc; //! pointer to the function used to write data - FI_SeekProc seek_proc; //! pointer to the function used to seek - FI_TellProc tell_proc; //! pointer to the function used to aquire the current position -}; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -/** -Handle to a memory I/O stream -*/ -FI_STRUCT (FIMEMORY) { void *data; }; - -#endif // FREEIMAGE_IO - -// Plugin routines ---------------------------------------------------------- - -#ifndef PLUGINS -#define PLUGINS - -typedef const char *(DLL_CALLCONV *FI_FormatProc)(void); -typedef const char *(DLL_CALLCONV *FI_DescriptionProc)(void); -typedef const char *(DLL_CALLCONV *FI_ExtensionListProc)(void); -typedef const char *(DLL_CALLCONV *FI_RegExprProc)(void); -typedef void *(DLL_CALLCONV *FI_OpenProc)(FreeImageIO *io, fi_handle handle, BOOL read); -typedef void (DLL_CALLCONV *FI_CloseProc)(FreeImageIO *io, fi_handle handle, void *data); -typedef int (DLL_CALLCONV *FI_PageCountProc)(FreeImageIO *io, fi_handle handle, void *data); -typedef int (DLL_CALLCONV *FI_PageCapabilityProc)(FreeImageIO *io, fi_handle handle, void *data); -typedef FIBITMAP *(DLL_CALLCONV *FI_LoadProc)(FreeImageIO *io, fi_handle handle, int page, int flags, void *data); -typedef BOOL (DLL_CALLCONV *FI_SaveProc)(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data); -typedef BOOL (DLL_CALLCONV *FI_ValidateProc)(FreeImageIO *io, fi_handle handle); -typedef const char *(DLL_CALLCONV *FI_MimeProc)(void); -typedef BOOL (DLL_CALLCONV *FI_SupportsExportBPPProc)(int bpp); -typedef BOOL (DLL_CALLCONV *FI_SupportsExportTypeProc)(FREE_IMAGE_TYPE type); -typedef BOOL (DLL_CALLCONV *FI_SupportsICCProfilesProc)(void); -typedef BOOL (DLL_CALLCONV *FI_SupportsNoPixelsProc)(void); - -FI_STRUCT (Plugin) { - FI_FormatProc format_proc; - FI_DescriptionProc description_proc; - FI_ExtensionListProc extension_proc; - FI_RegExprProc regexpr_proc; - FI_OpenProc open_proc; - FI_CloseProc close_proc; - FI_PageCountProc pagecount_proc; - FI_PageCapabilityProc pagecapability_proc; - FI_LoadProc load_proc; - FI_SaveProc save_proc; - FI_ValidateProc validate_proc; - FI_MimeProc mime_proc; - FI_SupportsExportBPPProc supports_export_bpp_proc; - FI_SupportsExportTypeProc supports_export_type_proc; - FI_SupportsICCProfilesProc supports_icc_profiles_proc; - FI_SupportsNoPixelsProc supports_no_pixels_proc; -}; - -typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id); - -#endif // PLUGINS - - -// Load / Save flag constants ----------------------------------------------- - -#define FIF_LOAD_NOPIXELS 0x8000 //! loading: load the image header only (not supported by all plugins, default to full loading) - -#define BMP_DEFAULT 0 -#define BMP_SAVE_RLE 1 -#define CUT_DEFAULT 0 -#define DDS_DEFAULT 0 -#define EXR_DEFAULT 0 //! save data as half with piz-based wavelet compression -#define EXR_FLOAT 0x0001 //! save data as float instead of as half (not recommended) -#define EXR_NONE 0x0002 //! save with no compression -#define EXR_ZIP 0x0004 //! save with zlib compression, in blocks of 16 scan lines -#define EXR_PIZ 0x0008 //! save with piz-based wavelet compression -#define EXR_PXR24 0x0010 //! save with lossy 24-bit float compression -#define EXR_B44 0x0020 //! save with lossy 44% float compression - goes to 22% when combined with EXR_LC -#define EXR_LC 0x0040 //! save images with one luminance and two chroma channels, rather than as RGB (lossy compression) -#define FAXG3_DEFAULT 0 -#define GIF_DEFAULT 0 -#define GIF_LOAD256 1 //! load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color -#define GIF_PLAYBACK 2 //! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading -#define HDR_DEFAULT 0 -#define ICO_DEFAULT 0 -#define ICO_MAKEALPHA 1 //! convert to 32bpp and create an alpha channel from the AND-mask when loading -#define IFF_DEFAULT 0 -#define J2K_DEFAULT 0 //! save with a 16:1 rate -#define JP2_DEFAULT 0 //! save with a 16:1 rate -#define JPEG_DEFAULT 0 //! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) -#define JPEG_FAST 0x0001 //! load the file as fast as possible, sacrificing some quality -#define JPEG_ACCURATE 0x0002 //! load the file with the best quality, sacrificing some speed -#define JPEG_CMYK 0x0004 //! load separated CMYK "as is" (use | to combine with other load flags) -#define JPEG_EXIFROTATE 0x0008 //! load and rotate according to Exif 'Orientation' tag if available -#define JPEG_GREYSCALE 0x0010 //! load and convert to a 8-bit greyscale image -#define JPEG_QUALITYSUPERB 0x80 //! save with superb quality (100:1) -#define JPEG_QUALITYGOOD 0x0100 //! save with good quality (75:1) -#define JPEG_QUALITYNORMAL 0x0200 //! save with normal quality (50:1) -#define JPEG_QUALITYAVERAGE 0x0400 //! save with average quality (25:1) -#define JPEG_QUALITYBAD 0x0800 //! save with bad quality (10:1) -#define JPEG_PROGRESSIVE 0x2000 //! save as a progressive-JPEG (use | to combine with other save flags) -#define JPEG_SUBSAMPLING_411 0x1000 //! save with high 4x1 chroma subsampling (4:1:1) -#define JPEG_SUBSAMPLING_420 0x4000 //! save with medium 2x2 medium chroma subsampling (4:2:0) - default value -#define JPEG_SUBSAMPLING_422 0x8000 //! save with low 2x1 chroma subsampling (4:2:2) -#define JPEG_SUBSAMPLING_444 0x10000 //! save with no chroma subsampling (4:4:4) -#define JPEG_OPTIMIZE 0x20000 //! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size) -#define JPEG_BASELINE 0x40000 //! save basic JPEG, without metadata or any markers -#define KOALA_DEFAULT 0 -#define LBM_DEFAULT 0 -#define MNG_DEFAULT 0 -#define PCD_DEFAULT 0 -#define PCD_BASE 1 //! load the bitmap sized 768 x 512 -#define PCD_BASEDIV4 2 //! load the bitmap sized 384 x 256 -#define PCD_BASEDIV16 3 //! load the bitmap sized 192 x 128 -#define PCX_DEFAULT 0 -#define PFM_DEFAULT 0 -#define PICT_DEFAULT 0 -#define PNG_DEFAULT 0 -#define PNG_IGNOREGAMMA 1 //! loading: avoid gamma correction -#define PNG_Z_BEST_SPEED 0x0001 //! save using ZLib level 1 compression flag (default value is 6) -#define PNG_Z_DEFAULT_COMPRESSION 0x0006 //! save using ZLib level 6 compression flag (default recommended value) -#define PNG_Z_BEST_COMPRESSION 0x0009 //! save using ZLib level 9 compression flag (default value is 6) -#define PNG_Z_NO_COMPRESSION 0x0100 //! save without ZLib compression -#define PNG_INTERLACED 0x0200 //! save using Adam7 interlacing (use | to combine with other save flags) -#define PNM_DEFAULT 0 -#define PNM_SAVE_RAW 0 //! if set the writer saves in RAW format (i.e. P4, P5 or P6) -#define PNM_SAVE_ASCII 1 //! if set the writer saves in ASCII format (i.e. P1, P2 or P3) -#define PSD_DEFAULT 0 -#define PSD_CMYK 1 //! reads tags for separated CMYK (default is conversion to RGB) -#define PSD_LAB 2 //! reads tags for CIELab (default is conversion to RGB) -#define PSD_NONE 0x0100 //! save without any compression -#define PSD_RLE 0x0200 //! save using RLE compression -#define PSD_PSB 0x2000 //! save using Adobe Large Document Format (use | to combine with other save flags) -#define RAS_DEFAULT 0 -#define RAW_DEFAULT 0 //! load the file as linear RGB 48-bit -#define RAW_PREVIEW 1 //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit -#define RAW_DISPLAY 2 //! load the file as RGB 24-bit -#define RAW_HALFSIZE 4 //! output a half-size color image -#define RAW_UNPROCESSED 8 //! output a FIT_UINT16 raw Bayer image -#define SGI_DEFAULT 0 -#define TARGA_DEFAULT 0 -#define TARGA_LOAD_RGB888 1 //! if set the loader converts RGB555 and ARGB8888 -> RGB888. -#define TARGA_SAVE_RLE 2 //! if set, the writer saves with RLE compression -#define TIFF_DEFAULT 0 -#define TIFF_CMYK 0x0001 //! reads/stores tags for separated CMYK (use | to combine with compression flags) -#define TIFF_PACKBITS 0x0100 //! save using PACKBITS compression -#define TIFF_DEFLATE 0x0200 //! save using DEFLATE compression (a.k.a. ZLIB compression) -#define TIFF_ADOBE_DEFLATE 0x0400 //! save using ADOBE DEFLATE compression -#define TIFF_NONE 0x0800 //! save without any compression -#define TIFF_CCITTFAX3 0x1000 //! save using CCITT Group 3 fax encoding -#define TIFF_CCITTFAX4 0x2000 //! save using CCITT Group 4 fax encoding -#define TIFF_LZW 0x4000 //! save using LZW compression -#define TIFF_JPEG 0x8000 //! save using JPEG compression -#define TIFF_LOGLUV 0x10000 //! save using LogLuv compression -#define WBMP_DEFAULT 0 -#define XBM_DEFAULT 0 -#define XPM_DEFAULT 0 -#define WEBP_DEFAULT 0 //! save with good quality (75:1) -#define WEBP_LOSSLESS 0x100 //! save in lossless mode -#define JXR_DEFAULT 0 //! save with quality 80 and no chroma subsampling (4:4:4) -#define JXR_LOSSLESS 0x0064 //! save lossless -#define JXR_PROGRESSIVE 0x2000 //! save as a progressive-JXR (use | to combine with other save flags) - -// Background filling options --------------------------------------------------------- -// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas - -#define FI_COLOR_IS_RGB_COLOR 0x00 //! RGBQUAD color is a RGB color (contains no valid alpha channel) -#define FI_COLOR_IS_RGBA_COLOR 0x01 //! RGBQUAD color is a RGBA color (contains a valid alpha channel) -#define FI_COLOR_FIND_EQUAL_COLOR 0x02 //! For palettized images: lookup equal RGB color from palette -#define FI_COLOR_ALPHA_IS_INDEX 0x04 //! The color's rgbReserved member (alpha) contains the palette index to be used -#define FI_COLOR_PALETTE_SEARCH_MASK (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX) // No color lookup is performed - -// RescaleEx options --------------------------------------------------------- -// Constants used in FreeImage_RescaleEx - -#define FI_RESCALE_DEFAULT 0x00 //! default options; none of the following other options apply -#define FI_RESCALE_TRUE_COLOR 0x01 //! for non-transparent greyscale images, convert to 24-bit if src bitdepth <= 8 (default is a 8-bit greyscale image). -#define FI_RESCALE_OMIT_METADATA 0x02 //! do not copy metadata to the rescaled image - - -#ifdef __cplusplus -extern "C" { -#endif - -// Init / Error routines ---------------------------------------------------- - -DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE)); -DLL_API void DLL_CALLCONV FreeImage_DeInitialise(void); - -// Version routines --------------------------------------------------------- - -DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void); -DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void); - -// Message output functions ------------------------------------------------- - -typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg); -typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg); - -DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf); -DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf); -DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc(int fif, const char *fmt, ...); - -// Allocate / Clone / Unload routines --------------------------------------- - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); -DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib); -DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib); - -// Header loading routines -DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib); - -// Load / Save routines ----------------------------------------------------- - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); - -// Memory I/O stream routines ----------------------------------------------- - -DLL_API FIMEMORY *DLL_CALLCONV FreeImage_OpenMemory(BYTE *data FI_DEFAULT(0), DWORD size_in_bytes FI_DEFAULT(0)); -DLL_API void DLL_CALLCONV FreeImage_CloseMemory(FIMEMORY *stream); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags FI_DEFAULT(0)); -DLL_API long DLL_CALLCONV FreeImage_TellMemory(FIMEMORY *stream); -DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin); -DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes); -DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream); -DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream); - -DLL_API FIMULTIBITMAP *DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags); - -// Plugin Interface --------------------------------------------------------- - -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin(const char *path, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); -DLL_API int DLL_CALLCONV FreeImage_GetFIFCount(void); -DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable); -DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat(const char *format); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime(const char *mime); -DLL_API const char *DLL_CALLCONV FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif); -DLL_API const char *DLL_CALLCONV FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif); -DLL_API const char *DLL_CALLCONV FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif); -DLL_API const char *DLL_CALLCONV FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif); -DLL_API const char *DLL_CALLCONV FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename(const char *filename); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU(const wchar_t *filename); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif); -DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif); - -// Multipaging interface ---------------------------------------------------- - -DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0)); -DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); -DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0)); -DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap); -DLL_API void DLL_CALLCONV FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data); -DLL_API void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data); -DLL_API void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page); -DLL_API FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page); -DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *data, BOOL changed); -DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source); -DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count); - -// File type request routines ------------------------------------------------ - -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0)); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0)); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0)); -DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0)); - -DLL_API BOOL DLL_CALLCONV FreeImage_Validate(FREE_IMAGE_FORMAT fif, const char *filename); -DLL_API BOOL DLL_CALLCONV FreeImage_ValidateU(FREE_IMAGE_FORMAT fif, const wchar_t *filename); -DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle); -DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream); - - -// Image type request routine ----------------------------------------------- - -DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib); - -// FreeImage helper routines ------------------------------------------------ - -DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void); -DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); -DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); - -// Pixel access routines ---------------------------------------------------- - -DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib); -DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline); - -DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); -DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); -DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); -DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); - -// DIB info routines -------------------------------------------------------- - -DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetMemorySize(FIBITMAP *dib); -DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib); - -DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib); -DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res); -DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res); - -DLL_API BITMAPINFOHEADER *DLL_CALLCONV FreeImage_GetInfoHeader(FIBITMAP *dib); -DLL_API BITMAPINFO *DLL_CALLCONV FreeImage_GetInfo(FIBITMAP *dib); -DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib); - -DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib); -DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib); - -DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib); -DLL_API BYTE * DLL_CALLCONV FreeImage_GetTransparencyTable(FIBITMAP *dib); -DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled); -DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count); -DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib); -DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index); -DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib); - -DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib); -DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); -DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetThumbnail(FIBITMAP *dib); -DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail); - -// ICC profile routines ----------------------------------------------------- - -DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib); -DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size); -DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib); - -// Line conversion routines ------------------------------------------------- - -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels); -DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels); - -// Smart conversion routines ------------------------------------------------ - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT(FIQ_WUQUANT), int PaletteSize FI_DEFAULT(256), int ReserveSize FI_DEFAULT(0), RGBQUAD *ReservePalette FI_DEFAULT(NULL)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); -DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBF(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBAF(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBA16(FIBITMAP *dib); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE)); - -// Tone mapping operators --------------------------------------------------- - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0), double adaptation FI_DEFAULT(1), double color_correction FI_DEFAULT(0)); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(FIBITMAP *src, double color_saturation FI_DEFAULT(0.5), double attenuation FI_DEFAULT(0.85)); - -// ZLib interface ----------------------------------------------------------- - -DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); -DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); -DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); -DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); -DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size); - -// -------------------------------------------------------------------------- -// Metadata routines -// -------------------------------------------------------------------------- - -// tag creation / destruction -DLL_API FITAG *DLL_CALLCONV FreeImage_CreateTag(void); -DLL_API void DLL_CALLCONV FreeImage_DeleteTag(FITAG *tag); -DLL_API FITAG *DLL_CALLCONV FreeImage_CloneTag(FITAG *tag); - -// tag getters and setters -DLL_API const char *DLL_CALLCONV FreeImage_GetTagKey(FITAG *tag); -DLL_API const char *DLL_CALLCONV FreeImage_GetTagDescription(FITAG *tag); -DLL_API WORD DLL_CALLCONV FreeImage_GetTagID(FITAG *tag); -DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag); -DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag); -DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag); -DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag); - -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length); -DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value); - -// iterator -DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag); -DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag); -DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle); - -// metadata setter and getter -DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag); -DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag); -DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value); - -// helpers -DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib); -DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src); - -// tag to C string conversion -DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL)); - -// -------------------------------------------------------------------------- -// JPEG lossless transformation routines -// -------------------------------------------------------------------------- - -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); -DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); - - -// -------------------------------------------------------------------------- -// Image manipulation toolkit -// -------------------------------------------------------------------------- - -// rotation and flipping -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask); -DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib); -DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib); - -// upsampling / downsampling -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RescaleRect(FIBITMAP *dib, int dst_width, int dst_height, int left, int top, int right, int bottom, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM), unsigned flags FI_DEFAULT(0)); - -// color manipulation routines (point operations) -DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve(FIBITMAP *dib, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel); -DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma(FIBITMAP *dib, double gamma); -DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness(FIBITMAP *dib, double percentage); -DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast(FIBITMAP *dib, double percentage); -DLL_API BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *dib); -DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram(FIBITMAP *dib, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT(FICC_BLACK)); -DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert); -DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT(FALSE)); -DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap); -DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha); -DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices, BYTE *dstindices, unsigned count, BOOL swap); -DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b); - -// channel processing routines -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetChannel(FIBITMAP *dib, FREE_IMAGE_COLOR_CHANNEL channel); -DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); -DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); - -// copy / paste / composite routines -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom); -DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_CreateView(FIBITMAP *dib, unsigned left, unsigned top, unsigned right, unsigned bottom); - -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL)); -DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib); - -// background filling routines -DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateEx(int width, int height, int bpp, const RGBQUAD *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); - -// miscellaneous algorithms -DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle FI_DEFAULT(3)); - -// restore the borland-specific enum size option -#if defined(__BORLANDC__) -#pragma option pop -#endif - -#ifdef __cplusplus -} -#endif - -#endif // FREEIMAGE_H diff --git a/sdk/include/FreeImagePlus.h b/sdk/include/FreeImagePlus.h deleted file mode 100644 index be95a0f2d7d..00000000000 --- a/sdk/include/FreeImagePlus.h +++ /dev/null @@ -1,1786 +0,0 @@ -// ========================================================== -// FreeImagePlus 3 -// -// Design and implementation by -// - Herv Drolon (drolon@infonie.fr) -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#ifndef FREEIMAGEPLUS_H -#define FREEIMAGEPLUS_H - -#ifdef _WIN32 -#include -#endif // _WIN32 -#include "FreeImage.h" - - -// Compiler options --------------------------------------------------------- - -#if defined(FREEIMAGE_LIB) - #define FIP_API - #define FIP_CALLCONV -#else - #if defined(_WIN32) || defined(__WIN32__) - #define WIN32_LEAN_AND_MEAN - #define FIP_CALLCONV __stdcall - // The following ifdef block is the standard way of creating macros which make exporting - // from a DLL simpler. All files within this DLL are compiled with the FIP_EXPORTS - // symbol defined on the command line. this symbol should not be defined on any project - // that uses this DLL. This way any other project whose source files include this file see - // FIP_API functions as being imported from a DLL, wheras this DLL sees symbols - // defined with this macro as being exported. - #ifdef FIP_EXPORTS - #define FIP_API __declspec(dllexport) - #else - #define FIP_API __declspec(dllimport) - #endif // FIP_EXPORTS - #else - // try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility) - #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) - #ifndef GCC_HASCLASSVISIBILITY - #define GCC_HASCLASSVISIBILITY - #endif - #endif - #define FIP_CALLCONV - #if defined(GCC_HASCLASSVISIBILITY) - #define FIP_API __attribute__ ((visibility("default"))) - #else - #define FIP_API - #endif - #endif // WIN32 / !WIN32 -#endif // FREEIMAGE_LIB - -/////////////////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------- - -/** Abstract base class for all objects used by the library. - @version FreeImage 3 - @author Herv Drolon -*/ - -class FIP_API fipObject -{ -public: - /// Destructor - virtual ~fipObject(){}; - - /**@name Information functions */ - //@{ - /// Returns TRUE if the object is allocated, FALSE otherwise - virtual BOOL isValid() const = 0; - //@} -}; - -// ---------------------------------------------------------- - -class fipMemoryIO; -class fipMultiPage; -class fipTag; - -/** A class used to manage all photo related images and all image types used by the library. - - fipImage encapsulates the FIBITMAP format. It relies on the FreeImage library, especially for - loading / saving images and for bit depth conversion. - @version FreeImage 3 - @author Herv Drolon -*/ - -class FIP_API fipImage : public fipObject -{ -protected: - /// DIB data - FIBITMAP *_dib; - /// Original (or last saved) fif format if available, FIF_UNKNOWN otherwise - FREE_IMAGE_FORMAT _fif; - /// TRUE whenever the display need to be refreshed - mutable BOOL _bHasChanged; - -public: - friend class fipMultiPage; - -public: - - /**@name Creation & Destruction */ - //@{ - /** - Constructor - @see FreeImage_AllocateT - */ - fipImage(FREE_IMAGE_TYPE image_type = FIT_BITMAP, unsigned width = 0, unsigned height = 0, unsigned bpp = 0); - /// Destructor - virtual ~fipImage(); - /** - Image allocator - @see FreeImage_AllocateT - */ - BOOL setSize(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp, unsigned red_mask = 0, unsigned green_mask = 0, unsigned blue_mask = 0); - /// Destroy image data - virtual void clear(); - //@} - - /**@name Copying */ - //@{ - /** - Copy constructor - @see FreeImage_Clone - */ - fipImage(const fipImage& src); - /** - Copy constructor - @see FreeImage_Clone - */ - fipImage& operator=(const fipImage& src); - /** - Assignement operator
          - Copy the input pointer and manage its destruction - @see operator FIBITMAP*() - */ - fipImage& operator=(FIBITMAP *dib); - - - /** - @brief Copy a sub part of the current image and returns it as a fipImage object. - - This method works with any bitmap type. - @param dst Output subimage - @param left Specifies the left position of the cropped rectangle. - @param top Specifies the top position of the cropped rectangle. - @param right Specifies the right position of the cropped rectangle. - @param bottom Specifies the bottom position of the cropped rectangle. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Copy - */ - BOOL copySubImage(fipImage& dst, int left, int top, int right, int bottom) const; - - /** - @brief Alpha blend or combine a sub part image with the current image. - - The bit depth of dst bitmap must be greater than or equal to the bit depth of src. - Upper promotion of src is done internally. Supported bit depth equals to 4, 8, 16, 24 or 32. - @param src Source subimage - @param left Specifies the left position of the sub image. - @param top Specifies the top position of the sub image. - @param alpha Alpha blend factor. The source and destination images are alpha blended if - alpha = 0..255. If alpha > 255, then the source image is combined to the destination image. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Paste - */ - BOOL pasteSubImage(fipImage& src, int left, int top, int alpha = 256); - - /** - @brief Crop a sub part of the current image and update it accordingly. - - This method works with any bitmap type. - @param left Specifies the left position of the cropped rectangle. - @param top Specifies the top position of the cropped rectangle. - @param right Specifies the right position of the cropped rectangle. - @param bottom Specifies the bottom position of the cropped rectangle. - @return Returns TRUE if successful, FALSE otherwise. - */ - BOOL crop(int left, int top, int right, int bottom); - - /** - @brief Returns a reference (a.k.a. "dynamic view") to a sub part of the current image. - - A dynamic view is a FreeImage bitmap with its own width and height, that, however, shares its - bits with another FreeImage bitmap. Typically, views are used to define one or more - rectangular sub-images of an existing bitmap. All FreeImage operations, like saving, - displaying and all the toolkit functions, when applied to the view, only affect the view's - rectangular area. - This method works with any bitmap type. - - @param dynamicView Returns a reference to the specified dynamic view - @param left Specifies the left position of the view's area - @param top Specifies the top position of the view's area - @param right Specifies the right position of the view's area - @param bottom Specifies the bottom position of the view's area - @return Returns TRUE if successful, returns FALSE otherwise - @see FreeImage_CreateView - */ - BOOL createView(fipImage& dynamicView, unsigned left, unsigned top, unsigned right, unsigned bottom); - - //@} - - /** @name File type identification - */ - //@{ - /** - @brief Identifies an image from disk, given its file name - @param lpszPathName Path and file name of the image to identify. - @return Returns the found FreeImage format if successful, returns FIF_UNKNOWN otherwise. - @see FreeImage_GetFileType, FreeImage_GetFIFFromFilename, FreeImage documentation - */ - static FREE_IMAGE_FORMAT identifyFIF(const char* lpszPathName); - - /** - UNICODE version of identifyFIF (this function only works under WIN32 and does nothing on other OS) - @see FreeImage_GetFileTypeU, FreeImage_GetFIFFromFilenameU, FreeImage documentation - */ - static FREE_IMAGE_FORMAT identifyFIFU(const wchar_t* lpszPathName); - - /** - @brief Identifies an image using the specified FreeImageIO struct and fi_handle. - @param io FreeImageIO structure - @param handle FreeImage fi_handle - @return Returns the found FreeImage format if successful, returns FIF_UNKNOWN otherwise. - @see FreeImage_GetFileTypeFromHandle, FreeImage documentation - */ - static FREE_IMAGE_FORMAT identifyFIFFromHandle(FreeImageIO *io, fi_handle handle); - - /** - @brief Identifies an image using the specified memory stream. - @param hmem FreeImage memory stream - @return Returns the found FreeImage format if successful, returns FIF_UNKNOWN otherwise. - @see FreeImage_GetFileTypeFromMemory, FreeImage documentation - */ - static FREE_IMAGE_FORMAT identifyFIFFromMemory(FIMEMORY *hmem); - - //@} - - - /** @name Loading & Saving - * Loading and saving is handled by the FreeImage library. - */ - //@{ - /** - Loads an image from disk, given its file name and an optional flag. - The function will use FreeImage_GetFileType to get the right FREE_IMAGE_FORMAT. - @param lpszPathName Path and file name of the image to load. - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Load, FreeImage_GetFileType, FreeImage documentation - */ - BOOL load(const char* lpszPathName, int flag = 0); - - /** - @brief Loads an image from disk, given its format, file name and an optional flag. - @param fif Format identifier (FreeImage format) - @param lpszPathName Path and file name of the image to load. - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Load, FreeImage documentation - */ - BOOL load(FREE_IMAGE_FORMAT fif, const char* lpszPathName, int flag = 0); - - /** - UNICODE version of load (this function only works under WIN32 and does nothing on other OS) - @see load - */ - BOOL loadU(const wchar_t* lpszPathName, int flag = 0); - - /** - UNICODE version of load (this function only works under WIN32 and does nothing on other OS) - @see load - */ - BOOL loadU(FREE_IMAGE_FORMAT fif, const wchar_t* lpszPathName, int flag = 0); - - /** - @brief Loads an image using the specified FreeImageIO struct and fi_handle, and an optional flag. - @param io FreeImageIO structure - @param handle FreeImage fi_handle - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_LoadFromHandle, FreeImage documentation - */ - BOOL loadFromHandle(FreeImageIO *io, fi_handle handle, int flag = 0); - - /** - @brief Loads an image using the specified memory stream and an optional flag. - @param memIO FreeImage memory stream - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_LoadFromMemory, FreeImage documentation - */ - BOOL loadFromMemory(fipMemoryIO& memIO, int flag = 0); - - /** - @brief Loads an image using the specified fif and memory stream and an optional flag. - @param fif Expected format identifier (FreeImage format) - @param memIO FreeImage memory stream - @param flag The signification of this flag depends on the image to be read. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_LoadFromMemory, FreeImage documentation - */ - BOOL loadFromMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag = 0); - - /** - Saves an image to disk, given its file name and an optional flag. - The function will use FreeImage_GetFIFFromFilename to get the right FREE_IMAGE_FORMAT. - @param lpszPathName Path and file name of the image to save. - @param flag The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Save, FreeImage_GetFIFFromFilename, FreeImage documentation - */ - BOOL save(const char* lpszPathName, int flag = 0); - - /** - Saves an image to disk, given its format, file name and an optional flag. - @param fif Format identifier (FreeImage format) - @param lpszPathName Path and file name of the image to save. - @param flag The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_Save, FreeImage documentation - */ - BOOL save(FREE_IMAGE_FORMAT fif, const char* lpszPathName, int flag = 0); - - /** - UNICODE version of save (this function only works under WIN32 and does nothing on other OS) - @see save - */ - BOOL saveU(const wchar_t* lpszPathName, int flag = 0); - - /** - UNICODE version of save (this function only works under WIN32 and does nothing on other OS) - @see save - */ - BOOL saveU(FREE_IMAGE_FORMAT fif, const wchar_t* lpszPathName, int flag = 0); - - /** - @brief Saves an image using the specified FreeImageIO struct and fi_handle, and an optional flag. - @param fif Format identifier (FreeImage format) - @param io FreeImageIO structure - @param handle FreeImage fi_handle - @param flag The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SaveToHandle, FreeImage documentation - */ - BOOL saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flag = 0); - - /** - @brief Saves an image using the specified memory stream and an optional flag. - @param fif Format identifier (FreeImage format) - @param memIO FreeImage memory stream - @param flag The signification of this flag depends on the image to be saved. - @return Returns TRUE if successful, FALSE otherwise. - @see FreeImage_SaveToMemory, FreeImage documentation - */ - BOOL saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag = 0); - - //@} - - /** @name Information functions - * Accessors to the DIB BITMAPINFO structure. - */ - //@{ - - /** - Returns the data type of the image - @see FreeImage_GetImageType - */ - FREE_IMAGE_TYPE getImageType() const; - - /** - Return the original (or last saved) fif format if available, returns FIF_UNKNOWN otherwise - */ - FREE_IMAGE_FORMAT getFIF() const; - - /** - Returns the image width in pixels - @see FreeImage_GetWidth - */ - unsigned getWidth() const; - - /** - Returns the image height in pixels - @see FreeImage_GetHeight - */ - unsigned getHeight() const; - - /** - Returns the width of the bitmap in bytes rounded to the nearest DWORD. - @see FreeImage_GetPitch - */ - unsigned getScanWidth() const; - - /** - Returns a pointer to the FIBITMAP data. Used for direct access from FREEIMAGE functions - or from your own low level C functions.
          - Sample use :
          -

        4. r~m=o7Vh~j6Z&jijfbTV9W&Ya$5BgwFLBpLQfD;I$bvE9RQ#8jH2 zphcanL{-KSw(`H08#ETnDxkusM+amdmqQC9=Pk8QFLT{xTXH!J_uU1LS)?fV=_P#F zXKVi{K9sS=a>yc|F*o6?{iAvXwlqzq8vaI`*eE!>E0Z`p5fr)mYZM&bq|L;H{w1hT1Uj(O11y0vqY~Vz`&S|Jd8K)e5oPt*hoSuCyiW8*ZFAJxi z-2Vk}nvQKW#;FDmUBoyg%s=Zm894p<3W3v~ejCM!t_Xffw6|~B7sRP4iR07;`+)){ zV05-|%GJl|5*?@H7@RC$9!{s0enFgmfyQ8*ewh-*>8#^q;NQCo;sZwl1)IwAW?21FrFLu;woSWi zoO8hlq4wP+v?=P=`Ih!Coph~ge)#M(ZonC*!%2w3!R(K~Sv>;IHSushc|nI0!6z}E z>o%tUK=AP&PZIb%hVv2~A8QPpD@MTC5s1U*dj^~cEu0Nbo(|`RD4cOIaDMYpe81fh z4=2Nbb5?vDIz9*fN#L`4TLd3y)+7BkYXqEQ{y2PgVl|5&pON?&aK5R-xjPC6hX@fk z@3+O{vpOEmodz6}@S^$IHED`YZwWe_lg~u(!5LNr&dL#Ru84>8AyzVu54h^+>x2R4 zvCBojJradO5{g0BmyUq*o5gYc#tb-#e+|wJ9L`4V>L?uCkBz|j6=b2<`7?{d*{EGZ zOLA0fnu{$vB&Km!Lhz-#$ul-!`#O#O6w#mC=+7-S z3OG$WZf?0x#R8|AEx_rs^3c1>xt zPOLoioe^*@jfXRU)rP}~;FC0hKeV(8{_uznM~T9Tm4_ydfb*++g#o8Vhf^Mf6DtqB*%Xh@cjDnpH{e9@8A%6j9iO8q0v~b^tJ7PoJhW&8oQd&p z{)m+<9-p(pQFJ&fqHxZOkyFNxfb+!sxPE)UfD^&TGJ@VVFBkOoH66|+Q8?$v!1)RE z9WNT!%9) z3Wsz-h8+0{bRMzzEQ*IyXuyf!Gm_p6IQ5Sh2F?$lSBdSnTjJqNFyKV! zZ6usB9iLw&i++3jiAcYt#K4(60?sS<#NqQ(tX#a`&Weu#XPOQtKMLo<7&v>NQ;EfA zemoqP0q3myBcG1XJ9dH38;?iuxhMwCH%7oojED0oRxO^6s#_EXDpC zsC^$~3vsRS$wf(c4()kTK4V{ezGOGOKzt1M-FgQWuru<0X$5kIACyW?sWTJwSF%^D z`B%Dv&r*U^9Q0}5Odtsd7pJAxW(bvP>6P+3eMg0AHlz+r2nRN(xL{abi!rRA8v>@!0qc4JiwRh`jgc#((ssTkP=XdA3U{&2(F&d29A=eg~Q^q0TJLm{}Bi4_a#dFOZ4;4ig#aZ8TjD z0aeijtmv7$)LKFG1c#HGscV%$2Yax{+`OGtY&8cSRhrk~w3sz-X18a$it=ztVx83X zGi+>I9(0(bRE;okZDqfWS69aa#dA7rXh{b=A!>9c@s}pWX3|u9LKlNX|IzQo-f`q`O za`=otZFPR)Ed_~z^JF}`kyhuMZz(YQ$8!H&biml#XB{BW!O0K?E4< zC>`W^wn!@zKv)BK4YrjnEMlHD=D_w!w#<^Z%<6aI4#Ev%F^`HB95S}RXD4)R$?N6_suL7uY6|~g~5Y7+nuo#n&){^TKNs!_MoZr{S)uv zB~HvypHN!Ov2&)3BR=h5;N7tHUBx)Ii#%x-=XZBU`SFUuPW1lhELrikvt~Q&T`0{R zN?R>>T!>#aK>?_q*Xisw{t<%qKEw>gvkosrxvve%3%XYLjVp1PUTLH2obZ-MH+Zs- zt6r;5d75rMX+MI+J=L=Tmwv3;ukeklgD$K8{$g%iyv*+HqBt7{0`Nfh0WoQCr5u zwChqTfj57fTzJyj7LWP5N?1{;$fG5X-+k1}=`mx2F%9BSWD?$efk!sibd zZ*QpBPC#LRj)NS7WoryEVhxPA*glZ+`55}Gs2L3XpGCd&SS2x3luJ?q=JqD|x@#fp z@=8%&njR#MhG4oLBwP0gI(Tq(3z@HPFUoU*Nh5|2i^nh-e~CVb3Q648L=^?VaI^V<%$gAGX z(WmxeXf~U)lVc8t7j)ILo6WeGZ7i6CGRV^mz?>f~CuVvRR?5Y8$v#G3QL)-}4lHIN zTK*rDyCu3h2k`){-2nD?773x`B)5Y?62d;{89pN+TqV+V2>}L5y`8?wa&7S~nA@HW z5D{>VRcY?g`8wKYkqW(?c;kMByeF)dgk3xEvZP?he6(fib^h_LqyF(T@CEtcDCC2E zVfhT?g9#WI*BOIQAvbYCl?vbly%)El`NBjZ0dCUaUVLv7i1c}SF~cgJllLd+tM%q{ zNCqFF(?Ljwha&`vYlp>DJNj(1L71NHQGtwx1Gk`8(pBkP3JjU(;!+iGuj#&xkxK|;ONt*w&5yL7_)ty=KLMVod>agyF&hK zd6~nmmfG0?&_HtdKCG$FVd>sH3(eY$XI4I~3nCLe7~BPG7vkm=`3`N%MUC_yDlf%P zs4a&Fbud9XczBu;Tqpe3$;$zw(!R*dD(&GV>7N1dFEJqed8nR<%)3r)dk_`)h@Ig& zFRs$EGCVwip;M&!;6${DQnl~b5h(fw(!3SK7Mw6fgeWkeb}V2@V1sL6snq%u1EBmTw)C=&(A~6N*g)W zL%dWN!W}8f#JZ)z*R#VJdz6YbB-HGOP;(PIYTS2$aC3`K``#)LyGmube6yzAl2_t7 z6L^#mHR5+kneeh25^@Uyi8rQ(e^gDW>8e7j>W|!J8Rs z4+%UwA_C8>c$R$x(kq_rz5KBdc%bStiKdHoW5Rib4Cw8ow%3uEb|Jst^nX-Ti?+X| z`KK5~Xw-m72dmfwFJBNO1(2@=x4O`LGoaKc^AYxS(r3HOz0QNpcKJuN=1?+!p~Zb6Hf zN*rA&Tjiw31fF)7;Lypn?M}J?TXB$h_2=LO^tc~<$@38(2fiK{9AB&loy7GMwe=ur z#+Q*|v6{H}YO>hMnmhXc8~&?E%!WUCsg-V$BxqcsSCIS#6^3gWeIAN2GRW z->}W;SkPI|CYpEPDcyo%XFWdJs2f=+R?>Dnesh(ksWY6y&)|X(rQ`LSJ1x)C68JX= z_<03sfqO*Hvsvlv!F1QDKovTaxzk<40k5kEp4Tc`^VZV?FF#BHE{C}BS|ZE0Dg{<~ zhfS$yRrqs`fh!<)sJILr))sluE-r}~PaNq^JVZ6}RTgj?&h64*DnoemyH?O6JIcDb z7)AbWi-oXdCs(i&kkc(BtRdX44q)r^M_Q7-t>P~K^8{9Z_i!xu!6frBzr?sy$+~@& z+M>DWujBs7u+)up-{1!#gE|XOyq6bU{1L-l+1HAaKVn4}pH_;J`Hl8NSo@qzCDert zgxIGQcmV+`1$ZF*Ye-tyYhc`nGh&dF$Q383>{3#6=7a<5v<{I40-t{MLi-UmdBTiU zz^dJ+*YH`n`w%SWLKy<%Qre{D5WcJCziapvlLym;Y`qJ{hEr!(z}_9q9>9t$D_)4F zd~-7;T*oi=Ly-Ziwjdik>?>Xdv%P8h%RaFaEpw!2{~4FUGhR~eb=c$gqgR0dtDxX$ zf}Pk&xcKPE#lM`ee^QzzU4cIFJ4%(JNtyU9LS(vj>T47^$$`i$tr-E_i=ULm$|hx! zm6oDOsjR3q7l}Fem#dUbnup&h_*eD<0AVSBCnA5ULn}l{c~`nCw0sIfo78~Y{2|HX zWf@tpz#u(UmXTS)iigcXrT8?=`78YYstkxcGZ z1zlkKP7>aH59E=J&WojODPGgt+4cs!;J)nZkN|O_ofHN;3HF~Szms4N2DS6dJ79H0 zyX`xl(t?KC8x+gZV)=}_X(O&_*2LIL?SBBH6WOf^|1V@5QQDTsEN!N@ueU1+(zb#~ z0KQWtkx&jow?sm@2+fIvrXVyX5^^JCkA#X4N{xg{5xOE0Dnn>; zB;-SAN+dJ~p;?hoHA0n;+6eF~v1+z~NW>u#Q5=cr z6A`76h$A9mUL-;j5#NYJ42pH(^iCKwxlNfj1DWDoTF(MzWDeo~uI%oAA^sly60?xLIuzKMwKZ z6hE2bCrkX~h@V{XGe!Kk#ZM9a$oHq3+TpD#7#JJMPu&drsWotUuD20v@?>Z%!DLIP zVEJA&o89GhedvdCtrjW_MZPuzMjb-J_b0fY@C7P&SzR9n-a#Q&QiT0p-|(Hc@~6)e z*^JY2=am^p<*w86nMq3*v!f6W*1d0rHA~(&EaIUOH`T41(_|%CP(bFhnYkI=@;j$> z5qu(x)0!;J;2M)MUJu8d*CUWG;mE^$_21mWkfim>&qDI z#J1z|e{q_Scq*NE1&~qcz(ar&u!LTdq`xqNZKhK}VYhD$S(2fR&SCKvZ;q51cpUIU zQjy`U2^Y|ecROTw0pdAVrH%Ryi03{m{-UPaP!mI$8ENtL30PEXu+NN63tAN}6NdEKZE$y zx(c$x45tv#W;n<~-p_RXp>C;)ziiGzJ+QahJ|Z(K&dDgwLdHF?5*6&9WZnY-E&&>X zwuu9pP_S>T+?npv7HM4XqVO#-6nH%^qyw?z zJ0z)SPXXNe1wK-|M{uyin%B5aF24xkbnxA=u8XlV_B8c_`4v{Q_B0Av)}qX!V=T}v_Ahvi)7FFxc$B~PHK=~bYSA(r zHcnGi(yfZ~oM5Ppj5E;uMf-n4zfuvG-612cpMoUCyAFcl+FxNyiBVI$k17=%P%gG2 zC(3Z8s|)?}vjoY*tAcFEf0gEqdChC2hdxEa@eE4nBiVZDa@Ix-7tLoWr=;Y9h4?oQ z|9tr8#=k85OUFMf%-f}HFuk9sSbj&CwNd#7X;%=Moy0KgAzOx7MGGvX`AI1*w}7>Ar-h(Y?#p9pxADaLy0TGEr8VY zI<>WVBiSejOxFulLRuJRwo}qJlfjJ>p0y)4v%uGZ9pl5jjRmEy&d7d5N;au(xDZJQ zeB8f@vKCK4SDV5)!=h4rgfAqMt6W!S#ba-III(#`IOk;eLb5SBaF0Bkq=(7+=s=Y` zJWdajUDAOPdH8%iOcqNAZkC5r^f1{n9k@y!zDy63mD7QXneAk`JbY!dHGCnNRvj1< zzK{&K8pH*TTY}NX;JYyRD{Wj!x<(G01OL|2{4;7lgJuifB~5|z%JG1b{Rk6kmu;X1 z6(r*ye5%0>K~2)5AXLe@7crM2cwsAocow${VzEiM6-)B-sG7^S^I!7DLH_7!$)Ut} z{JR93;Z|C>>CkqgL9a#|EZu=ieVA-V%$`Sm;R}0!0rPGIJLy+Z1W-Y;yIB*`n;#X@ zxMu_TCqXy=4`gvXqWbl>xhxJKj}j|wknYC6g&64Mv1H2~|3K~~Ao~(G{$U!F%)`Hh z;0}0UywSB^TA5E%#=B1b)}t-?Xds`;*yv+=y1cE@nnhU18J~DeOk4g}pE;YR}I) zjwed$EDI<^iI-`uoy@aQYCDBUR`Dp?qpYt-IjU$e>Gvwu>FcxnJnfr# z&6Y$qrCnOPg^GAKumkeDV}tKn%yz~tAPId%hx`jtTO_Ct+NEvd)$g`YX1Lz9t$xjo{j7@Ql<3|72mN5>h}0 zxaKQ701VeS5!tU$e<7uL0|STjb`a_Ty$^w@rCnFR1m(W5!9I(5tlksCG?cXV7Rt+& z3R2Z8iaHN1!Cpg9N>;d7?X8*Amg}5q(O-LfTM4Wa^X`@omC* zhz?P>-rS%@^Xt&Z3zEb{u#5${nx8L48^koj%gZZaXG;E72gnm6FkYRN2$I3xglO|j z;5``hq|9iV=qsZIO+O+ksaS_cl%N%;%j93ss+E9QhzTgQ-G3UTn%6MCcpEd_&G@1% zR&-Yz$x70isl!wtE8Du^mPNp+EpH7Fsu5_eRc1ygz2$?VgP=ZwG(o?Vg{udw+s{Qc6w>n+9&N zp1X?Enl>_Thk%_A-7JkU+PS70=nDgOgTjE_nX_ra-$Wy!3EznqQY3+Uj!>(k$3PSk zyfGhEPDM|m|6E?IU7et$Fh9l6HuB;YRVC>|TeY4FW#W^qCqX7-5B32OWxPG!hThUU z0lr9pALR_)e$>n_HZ}HOPXh(9wkJ`ycR;#ut>mBaNcOazBs~;)KZ~SHBx#f88#@QF zL7H7b+Oh1n$WMx${ID0|*%gExruz@)^3Z|6*zIm0KHy+`R=h*W=sjH`+G7q5SXpm_ zGRI?b^P=Grt2~B|JBHm&op;TxV>|DJ;~#xLwqno<{%)uoTOAgJF!HSq8$O_XWUY>L zd_etZBBA1RJ+?=W-OghjdTgg2+s$L0dTiDh!nD=V%VYVj7|{Ckyc&v@NH zEZ;UFc8DX@>ab!mhl+FcdhL2%Ivm$sdm!&dyd#;26unBk_>JkzSU+$7TiJ-Nsuy=3uyO_$fj<##zBNE zoTWDX*$kI?6yA|)5PF>cfhdYC&C&G_xg+!s`~Kw|`iC4=GUc!9A5z{V{R1C%;#xvs zperO;iBsqwvi`dMVecDM4<|rgk5I*wa4J)0rjh;u$8Opi|7vg%vX?^r1;6I#7uZXA zJ*tY32Wt&IL>u*5yuB3YBDSEHv3H7CB8V|?vg@#C7a2H7n@W}lc9D^iU51*0O4%?d zis!i)r3D%OGfKU8D-;Ve(t$z-bPFSj!?F3c-XXQ# zguczDb-npe2P<}p_4@?M&`zc|Z-z};+mDd2A5@vfEVr;vU^&Iso;TMjt$iFxECDTn zEf49Lia)}U5)7_L&v@URa3J0(6r3tm9KrPS9MN|;ePV~x_dnR-;I!eu-NtDHjC~X~ zz`6*0B*1WBteb?f*de>n$~AY;;)%Ay#y%`=)Exv8N?Ln9P62@;41l3WTtIXUiIV6* z-f`$EtkGf5AlW4vqz*$5i4zxCCVGYBKJO-RYE)dLh|Z1~I^jOY6Yg*d z)zCrbyG75QHt$p{&vGCrP{PL~G9YkW@CKQ?>dS*gy|v83nb(aQxd(astxaHEFn7x; zdiZ$YrVb4*saz_MlPynYb8)tYOEseQ{Uc2K571~8=fEPrQa4EFSui*LmTKc-Da_V% z;EH3&v)77TY6_2J%dKpO>-DBFs^zwf9i=m&nwd5X0?hMhO=DG?DZ{HxgT1X%v|w5g zR~iFb7%Z~Q!1l=kQzzYQ822B>AaMUc3OrZ904zwOljJt2FkmkdRv`-@tTV~bP*^6& zJ1z3J_QJH37FY=(TU+r7O@3+3-83|FF(lToM_?y=24NKI2q7JhXP&21T8YEBFbieu zlr@JuY?I{w5~#o6reB|(l|mqG!fh6W-zb39Gszd*gmO{@?y2Ki;bMRS#t9;Z90wVD=<;+$|!ua@v#(qve&!)eK9qm}W=BG`s1G9O^-lFn=zeW~i`eYAMhuwv=P89b)@b z&ogMf#Sso1@@eE-75j?@W@=E(@=mCw#GsL`um2}#nQ`Anv=8=lEnH&%KhwspI-`xP zQ^jhpH?x<+_fpkM+On;L|rA!hqQgOVUyegK7GDy!QbbAJ-`HB)_Dy9!gS0XGa!L(*-&L|wlU z@oLI<8su9{f${Eq=mbdwhA-}ffF-*V?kp^Mh=43jvhx7!wVg*F=x_7MaB&JcT@Jgk z*IO>Q7mRS#Z3kyT^G@^^a_&_(D7Y7_`E19v5)5fPTY;|w?{jY4zk}v^%~p5?0(StT zK}?@(hqR`HVk#cRJ_z^bH^%RSMs7lCu?czM0N(>KTu86jbnZRNwaDIKWRJP`dnZ$g zj__c;8dr?e{~{p)kJcZnGvo&$H$?XXoa!LXLU6@J3s5HnP!hvP%tRcVgK%e%l?X4? zC3Xkf>Y$6AB$#5RQaXH~CT-M{NnqWgf6u|UN&l|LcZ>e*$G2M-YFjai2zK%$;Zqwy zpB~&KQcZg1ts>Z?r|uHLK0QdR9cAr$<|885q6a@hu!EJYv#4&Xw9Pi7K`H$RLF4;4 zzHva#w-DwE{RN4j?%kT>S%x)~JDDHKJ zvANl1f$_sUyE%xf*t(#q|1{vh4*7a;Zf09QEcCQ#>uFoA=6Hucm}bWjM?W&8=oMi> z*lkoh&3s_lO(4oLM+)S%3p?PJ0P}Auv9jmI#=dqZ&S0cD(BRIyXIojvEUB4Jitj}gOY3bY>aIo->=$!3rw+F#5EOcS%G4miFN{}2CP*!Hl{(b z^58&;Iz0hXy!leKB2i7bgY;u!a^|~fa$@oi(KeN)=k9@vRa+{ep!(<2)5^M6>=yHL zJhrpu-f&5Z{E55i5$tGV_OtS!6SyXA0pV#27bJ0u)U=L>pOZ+bDS> zB~KnLIgOGxQ}P9)CBvk(J*ktDKbk)ZYzrm#Q1b6bOHQTaUP^uj$ryr6ew;%_wN-L< z9l^rli0FqfnAO;s+Z#_y&OahcJ*b7RoES36`7u&TaTUt$gNxbfKBQwG&)rGemqD*n zQ$)M^>OP^ew>ZQ%Eywf?$HCZk|4CGeznO@uMP6KOK|$0?0n+vJS|~szc}h(!Ra`s7 zD@hkca47}JR57jA)k8*E#8&qsWezo%TqKu~Gv#WOr4yA}ItS%GrE8kVvoy&J$@h{s zWP9Tj$hfs1gU?w-( zaEOShB(>cExmL}0tG8Q;-T|i?VC;?PuCt8SJS2B)#Pk8!J~TfvWZPSKr0DN2d(<3X z!l-e?JAq#OsJYRFjr8Y>jv7_P2S$tFsJS81Hh`~#C;{(G+f9LSQiy1aI(mO=Q zCO^87cW`p!JgjRtvyZ>T5^=XR3e%47n~|{7Wox_k-p+DU-6d_t3v1Bm%nWJ#wZLV%3mHCEjh|x z7LAr1Cuv-{N?*d=JHF@SN!Fx{gJVy{ffW*WAT@v zno(FlRDL-yT5^=X{A#r1D1Z6hXvtCj;vX$J%3mr*OOEoFn~==;i{&f+@)dviiocvi zYxZ~EA9YlmlfT?IT5^=X%o;5@%3rcaOOEoFl+lu-{N>|0qcknbUtU8p=Px)u`)Ysm z)&A(K{Sh>^pVi9$o%u^v`6!b(D!(L;mK^0T$9$udj`EjRM@x?Km#w2ENBPV8(UPP5 zWeJiwf5GjBulUPX{N*eD@{h=0ddf!O5K;c}%h8gf{N=l&B}e(o;?a_${AJE)$x;4t z<7mlI{&EqLaVa2^j;5g_uf}1paX4*n#2Kl*6eq6YIEU8Hr=7eDYC}MB9-R_5 z;xzpYeh?i!mqyyz4yDD}GMzu;NE+wQ>HPE(f0L`JFWorDH%>c!0Ll-cad9PjS}hK$ zlN;$c+KmxPo`>r?ZW=CB^3?$}k*9ub0G;xG%K@}_Uv3S=*vGZv9=Cq48+N^PcWTPN z4$f;D1zv(`4}2O{N-S(DE3}Z? zwJJ-?cVONpcU0?p7qg4l?G{)K;->mwUeQg?IYiL^v2we0V61W*4D!0IaPRDmyM_kq zH&&Pp8`KuuP3HFIo3zV6G~@1*z%MHnKigUG!&O%894N8ko^ zhFyF6*N4J*%*wh9^JRqZXIo-}$N53rkJZkfr#GhK7&Qj}m5T>C>@Y4iv5Pa_WF?l2 z9e7kuru%M_TEB*CPHd(%V^8p8Vx_terU?(cznzjYcHqfOs;hg6g>?;BRm*tTsw?PH zZEe&7*z2+L3YH|naNU4afBSS5Yy-n4A1(_P!>sPi$NBqn+z)Pj24&QRSIY18!8nd# z8TfjU&W2!B^*ESun*7JputsdjMiZIj(gIRO&v0j{f{h zHu`fF$W-r7F<*SK^Cj&p^M$>k)b%nKw;9VStmG#1^%L)B><^x@FmbmYx7c}VtQ}cg zO}-WPZO7oMG|~EWE2unUzn+b5;*O#6xP%BJ3q<`HJ3#bf*%>9!H!wk+GTwDYDmbGw z_o=oQ@NRhp**+a}F0!xwUy)&=XBJVizX+EJ?eH)v(#a|F&_EK5cVgyxj)Vg?efq1G z78t3(;{}+1EOo*}0}STA{?s8nEwHf)jr=j5ssDhaW#JM7>D6z9KXOmo4o;hVA&b3 zVdyY$`ywwKU@A=H;7?rM5B_^@AI7K-%jx;8arfFoKbxW zMuh?UR4VvXwLKVo2baz%@3}_niA|BwqUQk7(bCPAuNLW%No5BzX~M>uYRf{q$vjOu z@k7{aGl5GdFgI-1Sh4zGAbJcQwgeBlh=+YWHkGz=c(nmw9QMc+-LH#E^+6R7EH;6yf?Tf%%(Ej%p`Pg+{f-YlQ3y@)omx;_k|YPpjZ9IP{# ztcUdV1|H`}pLm#$2Ql$32J|por+W|5#Je9ME^+)E#(lI0{u73;AG^+=2tf}We+xZC zr=`ar2Ska7XDdDtv+|M8Py@w-8b(aaa}Yx!5yM}bpW}ZVA%-hQBZl`kehy+tG>8GF zgf;Eb+c2+2BZj+EkT8-M$|zDNhM77sRL??O95FE99~<1)kVm)te}x`S{pj5E@TN#VH*<)mhwn^13q8Cu zaTI#kOOYe!VY}~dp@+xOEYq`h#smy56#!a(!<|Re!cC7k)a!P zKQKw8N0!>N?FX&_W^wz0OArw+zmDZuzKHzl;J`nJ{CfS>kY7t62`pW6&bWi?L*oebY3z*x#j8Dv-J)R}c;oYAolSdaqh#GWj4I398W7B6bn8J8;^?o>~?F*{Wg>TJ~9bB9wveJ zS86{ahEQzja@!IptDC-fp;8M=W(8I}ODYgL2eX2xe2W6}qhnpAmcRtXXMx_Ke;xW7 z@#M<^QC5mtfhfgJN{R0fz`&(ceOLZS5DP5>b*?OHDFQf17>Q*c%|IJZ6Kp3T94C%=dp7Ida!2;YmKRQ-UU;MFuj|qT~G#FAw&M# z?AmWu=(-4+GD1G-iCvHEXOUMG@1T4?48Opw57+YqoZ&zU943VWcHjJjN-de-kD`~c z!(5upl?$WdWUhNAnd_cuXLWY=s{8==5pw}-cbA73+h=KK{`*kGV7Juz2u_;>2q<=D zR}qX~khSemVZaRaJYFeVXf^8PHtlB+z!`R`A9n4_wI9U6xK@V&0F}UHzNu21c2*c1 zfu(lV1*_>}2-r(HqzU0Ab{`;=Yg6KC?*WapJb0doh5SiusdeBsb~CqbeUV|^`Z^G3 zF(*C$$Iz(Ev~W)&MD!D20BITz`i~Mpupz1FD1l?I0{R7`qV~csqTT18gNmv5fEhQJ zeT9MFH_4pPsC|eI;JsXO)*R|mJ8#2FXu||x@aTRG$Rve{S?s zPQt*|ah*zjkoIGECElq^LDP-Mj2=b50vP($!ft}|gC$l1>R(HpTycbbNS-I!(GRXm z1J|RIRFAD{_WT5&c8aXki@xb{TVOU|q~6wUYIy(^C9%cUf!mpxbHCKcya?PJ`NR~t z2HSL=;ZpXJuy@e|es~_TM7-<#nVKaP4gHlK_}&ww!xSNP$8+ucFaKUdR`~^LRhL~U|L;E7A$d%Is~`RB5w7T4SUs|3E`#TM;Hm%?6B zAzhUvQ8`3++Dxd%^)~D^Pom?5m*jVb^*#MX@%kNU)iz}2I-YkrsOPPOu_CFKej#$E z!6872RS=6E8a&qrOBypi@K=q*pB^&8QW9^3mWc+TD%2qQ`_oIJ{cY!IHj!rZH_X~t z*22+%Kg!2l-FPm(iuL^JV+ z3Q~<^cun9C-HK0~wGSsstL_(cO@Rnq?q!iXexO9gi5hV$*A0y{;A z3WV3PL=!83HS<(fkVdA>3({fPoE12fe8=hnXM4Vr6=W*;nXDj7$3VzG*TgD1%mHb*(Fi+l5ujJ2@gY{@z+kM~_ysbclkkMKoHZU)21Nmo$ z15j(etbLnwA6_dTQr2uDXC+aWe;A$!(N}S$<|(y=l$z2i(v`DQV5@^FC;A0D>y>~B z+DwmejOK}@`L~zM;Um!`Mk3>F|1~rYRoeLn$vhbE6B>sS(Jfmqy}PAwHvSwY7b)S7_?2lXorQigf?OA!L`$0 z&(5f&DH+3pALvw}PIHEeBr=qTG0fj3oXh1Oq+?j@cn?y1D8HAx(8=G0o!TJT<2U(xH|Q!gG)7)xhI-!LZw%^a@)Zv~ivYf}|FtRe>v|fy`_mQM+qD z{NWwQcnul=gFnPE;!rVN<-m?e8AF>!Y%Pl>lNG}d7%??Su&|&FyLFyX?y|Y|2cDzq zK>$|#TD7-wu=b%f=r@3SPDwSl&f^h>rLK3Mz#SPFjM_LB zIl5j6!wz)^|9sg5yHuT&?dlYVWPeSnJ}7k^u7DY;K8oym@d?~#YN4#v2c)h)qu{lj z6teG^s%;Lbx<{&hNveJsP05m+02D3i48nv2Y*A55x}sp{8qbSp!ewM50_Hfa9iAXq`r8;}J{-DtY+AEy@=e$HM@i1wlny*SV4 z#ZhVDOX|gWdM_@7m5vsgTcAaK6z!Wkc*MJr@dObNRUVE|C5T|uQH`OM=y1l+)#oS4 z&0BaIJ{MKC2n2M>?BJ~zwnzTo?^%0$CvW&s$$3(8z9V%VHA!73E2QL>jTF!4P6x-W z>zyYg`{o{sHRjFljfoQ9)w?ls&l6Mr_sD#qnDUsx_I*j-pL1ocCbKlI$y5c(F$|(vMRk#={fK9N;Z`kk_Z@10rNG zc>B8~rytnY+{%NsALG&_^?q%yRAP-?s%U5h7fTYdNem>}5RyRU zU#pMC)V2s&0!kopS;@_KE&A2gwzjq3+V^}_pS)*PY^%*Cm;|I4P!Sa|BH|56HK0O3 z$bLU(=HC66gnw$^@An?GX79c8@60)8&YU@O=1j7}F`Wz{(n|SciCipEI!(#|!R8|e zAWA0vPxfgD{xXRSr0*{X2Y-S7aeh9EolMWqM|@U4KOYUFBAs$Rk{gBCixm30OefiI zOyLmth9VRp(h2Wk&dPXAY8y(xCx<7v2$k+kAZc0TaEq)%S*Xnu_R=ZzG6Qs<;{a-Mo`r3JY?Tqy`7^$L6#AF{1X&r{04Q4sgFJNv9TiKysL|EA))@NV5iec8rwnvO@ zoHsmgZ`193^Z)1D+ny5!R@hAcf3X837r?N1&V~(a6Ae2zLa~C${v77UG=2O`!a;Dc zUyEbyy1g0`r@RvO>bbC2;~4p{_G)2LF?I?5H`%M_!d|`di?CM%*8F+j;>t1YrEcezd%kUo-s-!gU{Ux-3jQQxy?h1?O8YKf5Pzbo;kHxI)ql!v z3I`!_GlhSM*-Kds)X-*%!JNo*&U-0TSMs?qCmNlfij5dzO}?>$y_9I)oUHGqoZml* z9ZJTi2zwd)4_+_Ectwas-ueBL2xpF1{|)(+`zJB@3~zUY_ePAF8Xhyy82*W#5`*^b zg9>g`3|Cv>alRI@{c2Zp^_QLuMt>_o3O_ zEA9-7yciN*n}~vdd${IBIWxeYfqXgPV}GnY(t)}?pSwT8*}J*{2Wx_BYj3fWm2pS_22XKGm*BCwJ)N3ytLcD3b#|+NBYqVobrPA!BMnG9S2+9NBi-i)mi2_Cm*8@|$3I~q)(S59h+fS4dD*#=1BW^|0`VPJw)D|Lo z2k>b8(+@A$D})=o?iSxZLpYw|G=9T<%7KO)uW!0`Bf_R%5n-JF7sT%vbG$2s~VM);5{5|q|GPfQLr zp>r?K;aQ!0GJ;pGP$PN89)=yKGbwX~<3Hz@gA0d-KNH^mW#pKT^Ck5t80AK-Z9}jG zI$vR&XZbbWk?~<<)Hd?8;m))0Lloiydd*DTAKw$jZsgx>pdfWP6#NqHh|o0B`d{E# zoxBzYj~a#=EhEuCW3;Ro)camsUpk0-IATO2CKKM?GO&;q)pgy29FF01&S5|0foHg# zJjAs?f__K@{ln-YS@xZa(8Xy8GZGq6UvU4vfgTLsKl>NjztX||`|()xZ+>?~|HS#o zloh9oPsfAPu{xXTPD0SSzIHchFeZ<>Xnde2zD$ch9t`q0ZeTredYSY5+S&qEjO#Pm zSRRDUwR`zU)%r_UpvD4TRMyyiAB~eF%rN{7y|?0YfN^iSyRV`$9ApojczOfoALZ%0X?g3m>8Bs`12M|ejg;uWAAj2t zOgIlv_)Dm4_xIw7PFSd=<~ILs`V4zYlR0}`v-g;D zt7x~>qpFmorC03u44~S<-X(cva1*`pThzT z$GP}-up3VJS|&IHzGiXOg#;Et1;yRSWd_Sb5K7Bbw_Uo^hXnQj^@_!zQ%YQ;`YXIh zFKl6fK)H@dm4w4osDM##BwCAA6OJe&VZkpPVYI>O-hh+xyYUVAUt9 zvSrmz?;foYG|}!rI1Gb91b;M!`GW@Z5b+lof<sR{?jgzm8+Q7g;K0_6~iF!(qCX%q`B= z%pN4*-W(^z>bQ7Hq5l)@yEqe)bo z2J+lAPmrfQ3V}Bg-ZD(us`m{Hi2iR1_a6%Bpx~3#`M#hRH(93zy{SQO3eM|l-~SON zEd-rR{1ed5@-uX_OwFHIa{*$swH^UO zeh%fM(M8yr7-AL9G8G8sU}J|g>)L@}d%{Mr8qN+y-12Lr-@kh3bbd%Qc(vAA$?4Nt z!LF`ktE{f0HM7Kd>S71+#^o#_I}|m^!w;Lahyhr8IS<(A6Xl}?6bYrao53p2En3*B z-Txkl9Ik)1s6PQbmc@!~&QrvM{046#4NZv261ssNaWp(%qLrtpl`E;0@W0Q|-o}bE zY43%7G3^~zYpD8#Av!6$M5sE_fcR$=STgFmvMx%KR~QEmo3ctWt!( zqo9Gq#XGCuBlobH$7A13V22Uxa7!6z$XDkyti%ateSuEh-1|-x5xXB78Ku;8e>Exk zokhPJ_{m~tG9IocSfB=yY7#TV0ZLgkC?S42t%$f0Hai#Hu^pSq}BQ)}cORaF2}P=)r}A&T(!2j%n*kyEt6;USc1J6FWkKYfT&JU^jS z`~J#-5I&|=XrqV7j3%llYb!j|f2(3rvaARVy`&v+n9PPOlB^%gj2iFy1{uiwdKmXHm^*#jo5Nr_od#>$`8MeI)p>I%om!77* zuPxbtSwj2HZb+Rxs}MU@UH-J$P|v%dj4cY}D0oYNpEJ>4CUO)lE*@66(Lr#ozYx^7 zz8Qg~&(U6A(V4Y(0>MA{NAN$JbLVrn?8PlV}K(F7!Q_2l-vG(ul{UOKG^E7~Aq zwWT7Fv{CIrqYYtiWp7ln0Uo31d%;>8g6X~w-5ss6>8ES=T8_#KPt|V!EHMC%Qlzb# z-;yyE5R4TN=<$vbKI0&JgF??EQiRQ0XvBNFgmvnX=re`?3PZ?s*1-d2ebO_Y<%noQ z4wuK~l~^Z2@Hr4)jVJf&uWl2@aGeNlbs-1AiikK#>~@>$HOXHO^zaB^UMnKk)xv-} zwaV&^S5{hklBQmXNN(RjB)2s-e9rKu>!o+~AnqM|oreM&6$uctKz@yxT5Xg3YxR0- z64`c&LAMNnuGq^wG*VJb%=}6ccy5yt=PF0&ICi*a90zEb00_bR5yL2l2WUb*9XuXu z&TR!yMyxsJrl@#LZhKRqy)nn$SY$`2DL9Gj1R%`fT4|NmwQ`sc0PjP|{}g>5P2K=xfoa+VTs7r-4Xx&C&$**k(q`nQ{Fmgo=OF>N_Kq@Jl1EOU)0 z(v)X!%(kNvGjcIh2WhXhp|zeFyqVFF&G2AIqj)P9vQisw#>LEt9BB4tA|oJYC)oOOew;X^b37nt^^=AbqQhW)s%VYK0m8Di?tg_5X zLk$To89@mrg}x|DZK3CFqP}Yo3r>l{pCRkJfam#$A~C&Ek=&B&DYg`uHUgzuGHnxz** z&B<9vqjs`*N8zrAlk$KX?{c9BWq46}t_Q_DgImMrYIUAqDt>Hrx$!3&X%1b`T-{gDwPb_Y99~ksjL{`ud zD_-O#THtX!-6tw}kbjWxLRh`{+#o(1un>QUPr#ns^srtRaSlA*?h|DmmIPOJ0!W4fpAQHKo`b?+=NJT|@8F2D_BJn|L`ZId$%0yivf4xtcWJ1CQdH5w9ZSW(xT6cWEy7 zs-@KV?@=zK%%>W6QT&T}7i5vNnqPy@^DgAiK*JT30hIs*?nH~*tB-v{Mh5;v9-Tzq zcoP*(Mtd2rOY_MAcPaP#olor|#>a&`eclE9>-@u^@E!AClrngqK9Z6*))OLYU@HR zpzM5Ly)8H0(?}%AlG;|Md*C+q#)mXTv~{Ca9iZS4*SRw*75D1z9Vg z;6N=!)weB0@f#LXS(G{WHWzT1VA?jLxEM%!h#1a9ZQD@I@0tnZ+7JWM~-73vl5PO=c3;47o?s zD(^}%CO|5LZcwiX?qp0N$+t{Gcb8)KT=M@O!FU%%o3|;xoDGH>n!+QEvC&%^5?^F) z{EpDcu_S+EtD#?r@>!yM_#%m+$}bI<|HZkKpA;@XFH~OW*J)w>dPw#94Mf^><31wU zmEd)|c6qa*^y+%Hc6%RGPzzLi{Fy`#HrsSvlq`7vgoU{$LT0NJuck z+Ca;7f)S4tZ(n*Qp)pQ+23~?@>6twI;3XSB7QDqZ=2-EDpLo1k8gmlxhMz>dSsQa~ zc*D;Kyu~->jKmv$lJJ%QqXORWa{=BG8*@hCEzuXSHRedZ7Fopt7CwrE7d5}1BeWAY zI{0_4`3{{Op<#;t%7ihX$Zl3KOUl+!z!XrE-3OFFw#&Jr@KhyU`@FjdLxFu(UyBX# zIn~F24%Cz8>;uM9)M;_V-_kQyjvs5O^h|!RF}Kv5rLihzRsXD!; z_Nmaq!}OApb2z!6hW2@1=X8#wR^26>Ql}wM8T(3w5&wHeIT>B(a;J+v; zOuP~N`@s?(&)eU;Djre15r}s$`!-){cPv@}1lSki-T=c4x~U73rD06R8n3h|+p0Q< zr)-VZ^lI~LW)6C+boGN+0Al?~zND0{CxYT24vZIM^xn2fi>_}|U-Ww^_tru<>E$-( za%*59&VOW0359P?(d~0HtkrZOtaTGEAQjhrIao)a+txTM{bJV9h&Y~sZiFgN!TTj} zrAoz@@vwd&x+>tzcMYt5egQ0mA%IJ%!)3py@a?mxw^=JIU`-<*tkk%`XK`iPLa;<; z(Erw&8#oB?cR^KDEBkge1#As^(7QS5@3;D#H zuFqCCi^hQn{a+dG7DE#4>MgRe9+v3TD8g|^;A9-!R9uIoyFLO8!YNf+@4(;_fvKm5 z0{9Mj9i)SMentoJjlK>t>sk_sRzIS)lig08JHhu}mog(1+&fLAv)%BveT%g@U!;KE zs`WAQEc&1h@=~HZUJ%Q>Ov|XpYoc#+3bs*BcirQ6xioh3$`N?@DP_FAQNev=DK0Zu z2@$|AaegX-f0t>i&>B3KRO=#vp8--9GncC(TrtJy(c|ESvUqlGG^(4iLe`i|XP`)#Bafc=!5 zl+10cMVr7aU0E%u@ZGXqN3MUe_T5iU1grLw&k$stN2^$4F;z8=&=aqZPMk`KQ;fv4 z=)_b?>@%vhL?;G;)T%!ji3dK3YI7eYt~L_4L?^yTiMdANU-jS&*oKN#O=`BwDo}L^p6# zL<2B#pQirni7ji<0tsDeVS65p7v2S(hE^>;x&?En1(waj4u@zq82;;tV2luY&i zI9$KZKvwM!hoeyRyE_aNvFym%V`%);Qtfor5Y;Y+Yu9<#s^v%5J|k2+;zwsYPKBR2 z>A7kSABhg7)S)-=ggb;Fee77Z{fDAD&~>}s0bKBT+WLEa{Wqfvr73#-MdAAOfos*) zMb}?%)W2yrMsGw5r4=*{!C!I)?joRVSxj!nXmT6DCpTN*m>lS*$!#Qrg$MG0kE9nSbn40ioA|eY&HOuHtB^q>0^AY&}4G~ zq&~6B(Gxp+DXDX|_88q1lSu98WDsRfUvTHS7Cd$~1v$vg0@O6R*5_P6<@W)dOTixx z(P9l4@Fjts1GXf(5>#M zga$CzPB9euxHPoWA%-KBw4ZZHTzLyP&!tUAWJv)ei5wChr-3#lvgBFyGxeNHrk!)i z^vIH&gfd_T@dP0u7^&Bw?`T6BkXSWD1!q7~5$Svzc*I_9WeKHhyS@mJh^I#xvI1+_ zZS<@!0w{YDxetK6GB^i-z&|H}M8-Ln$M*2&DsMk!`Dj@uV5eS$;g?TY{`CEKe9rPI zpR;`GDa#Mlf6;e=h2;FSb1YA^Pv)bJ`L1wJ%~$i<}Ec9=xV zVX^SVxgz!o1WXE~>EkW7M%e5F8VRSbaZ^Hz^mstVTY5l~Squ33Qt9zlnrx9P1s~?8 zPoV6%>6g)E)1()Co#a@Gm?E9vdumMPjmcOXIan*|mDyI*ORc0*Xh=6umLtjA)V?q6WYC#?t(GR*ij5noao<8v}n3H-;G`>q~5G5E={q zS&d=U0C8|5);^A@Fr@I4MMBxZ-_U%MZ-W=gz`T<|HDAWlC;TY|PY3x^8lJlNQwE-P z@ux|6+Qy%z;HiZ_W#MTPp0Gev^9%6u7=ID&p(Ky`qUBL38T8KULxu+TKUg0cN_*pr zMTqk#eTcNwj7UvtsFElHwuxD8Qpt(uTyoMmmz;dgC8tD|gv2F%5%@R*&3Ia5$xta# zg>Ii7218kqCBs@OH)%&NXpL1z#DX>?FV5?y=k?Riw?0TerG9&Q{XXM!mY;aa^26)r z7(V%vAbd`}zBxVolTX?H>B~>~oaLvTvizz0pA}kP^heL<=hqh$f(6T%^XrTB^XrTM z73&LH$9wd}Oa$u>v5u!TeAMET7KeNpk461_G9?Iu!Jsw#ob<~hmT7bUSt}>%+2XTm zEUI^82qD|Vc+s!OWi_p|hge!yomFF>b7{TwOKfb=(t4%d7-tZ&x(NA5OhVltr5E_& zrk?ajHi1>?tPMSP)nlLhOYB_KQa-%8e&&intLxbH^=}G|_4WPyiPqOm{E61r_56v} z*DLrFt*>w8Pqe=NK7XS1^;|rK*4H!nXAeGS^QXCZx|TmJ#?v?XQx%>j@TaAC`U-zq zi6@Dk))Thy5{DPmYE109g+TZR7KHr+hdzJvhO(ef>-@KYAoJSTfbJUDZn2JpUqOkv zDKVc1aXFS>sl9Ze#e{f8bXFD@(RZ}Zu%mfg$L$b5GW|3qs4L8kaBDK7*kQ0mIJy7~ z8Dzl-UGgj7Yd9nLCJ}sfHUXA#Oeo)`ddvvtvTh5a%(SRW%@taP01>gDSiW7EVQ01W ziZ=HNvnC+{PJGG?hq7FT8x1S7;d@*YLE0Fn&KBUVwO4BIJ1nN)atG_vcHxOmz}+D$ z%N@a`_TW-Sg?1O>5coEe$#eLg2?D@85?tYEPasTcO;qa&n|3FD0SDW@u>013)ena2 z^orfj7x>u{#t#lG4(Z}aAyBGQG-V9H-A&Y4(5s`!|CY4w|AH#)CGEpMAnFIFDh@Rf zN(SMs7v(|TSlq>FuOMMC?kq##?%$D9;O>_MjJq!ycZG9?!(A(G1CPaL#MU>*5DePZ z;BEHcZ4QQ=v*2uN$g@l!Q0&(_aG+HCS_qEO1P6Tf2!2jS zctG)x;;u7$$07R8=%yU=b=hX`C|^sQFA#@;vOlxAC;qF=z7Dg$**k~b0XAGX8uj!s z_eOA?Hj7@0HY%%R1-+j^J~F}O_`d_l&_3be030#+!Drls#LHn%={kJFC%l+6uf%0X~l0t%Gf+wrt$C% zj~iyH=AamI}uC+amNjm+||~B9k~h~euMOsWMgAvH1_o{uZ1=@E<&$y zC=XGgxIS|s3t)D01iE2sm+^EFCVvOYkB#t?SZI@;Txex0?C=Hrp|342SLaH@K<$(l`dTW9hf)ds>la`;NOguq4So$UdK@KLMiHns8@?@ ze2b7JaG!=cING{L20pMQ^+V**3KoyYXxIG%WbMP(u*Kko@{f`EFqWBcYIOHSFE`bq zu4)s!A1bxflQ_7!V88U_g07G_S~CNYqI~V#f0m6^^9QQU9&B^Yw$TgtQ-4Wd+p951 zJ^ZuT`0Q)vJx3rU#JcM8AWo+C=m4g{qAqO%eq#mz*go1tU{ej)IFdi2?bm`m`iVU* z0DJV4fpQdQ4}0LazV|hT*rS3rTWI5q7>Bb-Bs*1GL(KG5ySvuxaek6;MIu|Nswn*`|ZBu=8|I67ej!L+&{$tHmOZ(Ov1L@)Wh+AAtis@hZz2cx@x`gV|4 zcPUlp*buIZjj^;75nlqKsfzb+gs)}{b+EtC7!6-3PUd%uVxeLyAIU7s@-jC0u_K#fU^XOPg<{ zgS?_mID##+i`dH^%rCyS6dGy&MvkS?LoH&w&5ayy8N*E$<+jYXl=9B03+&Q8b~ufy ztE@QBpccJKV{j`Uf!^0KsCIEDmv*-XQH=SMSO8-&>5$?6((dl1s0wZF-9~)B+L4M^ zYs>xCZd1?Iz5%KBD;27HH$IUw?sxgjU>B)l5C^x-z0IT+?GAdkRcKG39(Yh+#L7GI z$ye7aS4cC8cC$DE5L|fabF0;|w{&X0jR#IU?tpiAzBQ%C=E1@2iHJ4B%1PCLtmhH> z5c_TS@Uh>%h1hRDNaEt$wZL9yL&M$uQdnnf@Bv3K zwBXuu9KiUY?0gZ2QSSUY5DHIs1X1}$CF`ei0KS(c1*a}t$5vR`F>EEb?a-VZu0tyl z|3+nd5-n}6ekrFP`mG*=DcS*g`bdJ3J3zk-EU8N;_zrX_c_9br@gkk|!2$XR)Dl^l zAxkgdYy{d)$9tM`heMrqrKKGQBT{4nsC?Nx=BljF3T9$jt4W`zTCc>Gu@RzAmt3r2 z{EZGx9@eIO?#kTUWgVGsM-o}$Aza|;5-BSA_@d1V((%kXQ^N=NG93>}oyj-glGcA5s^P=f8u}t?H~^PKN7CWUqYVd4rnRQbql(w$ z`wZoOW|RkR7a#43tz&mY9q-u!`|L??X6|ix4^@~l_bLlaz98!O7V40msY$QVyFyr9 z={sPyG^08=?ro(HOR3b_>Ao(6%uP({Lr>}Jt(L8q1=pBNT+q>ns>^}{Yr?NLUv~23 zNt5MBQXj`k;6OqoV!+_5aV&@ZJ?XgbgXu{}lRmCCqhnfgJmTB^DZL)JVt=oW(>98C zI>>}~i}tX1ZxruVZG(8fTfE0>_2PYlcu&xliue1)d!n{jygw-3ZJGz~7_YM^637DD zpRf4}iHxk40#nta7*@n;+G8(<9futr?ca*w9ltV3PrN5Ov568V8Hu+=C;o^MHKW=& z(TN@;^6>&Og0lu@FUd)a+spn2_=7ai;k#pO2!A^J+O_{`iNfE1 zVA2Er*oae6H`f0@OkY>+^fRLGJ}boCwY~!eW#8o{AAZH0)c(fkohkf zDnAMY_FXh&{!50;A4Cr>88ZL)i1DTO_cDOLHn4B}p#0JN!_P+L^0Q2dwdtx|B`t6h zDW|V=O~|pnqG8O@p^Y24!HZL2lMruK?Y`zPf8f;2JvizFj7Haw#TjZS&>Of0@@JOb z$SYlc=FRLwde(%NqdO;5Sd&`l6d{@;BNoYFo2g1~&ZbR>Xb$F!@uE38|7~T-Brz|= z0phJ#$~C-est*P)Gu79d0`JO6frfpMp=*;`KzN8iZ$iVq>F6Y*cj9MANGe_Mx#aCQ zUETuXSTReBtcZWH_7Z|05<0|{91OE7&U*oJx^f_{H=2=nO|zb3a5_)onW&jfvOQ*f zEY@~d+U+1UU7R@KPA?E*sYu{OnR@`TE zit}Sa02znJ200ALV5+F)>kA~e&cH@U%U5ya@APNQ#2B}SY=oO8o)W)b$oM`hZ$~-` zLly%1ujA|`!#_C42&9FC7Hfe-o#B92YOnEAdK zGAYt{Sg>H9`vOM}#X?yQqi5vcVaE)HZ51AfCA&^3vT~o^vQR9m^i$BP9CFu zPMx`5PWv^rKEalMjvOewWylTAlk-V#B!9tTBM}DHjpiF^x8s`T8zamW+sf5j)7SZW zS62tCeiq(@Yv{chbPDamt%Md9;k5DeIv^4I+3eS33MN$vTg_qv{9}CP+uC9e9M7-P z9{6#w2Y%)o;85MhGz3>%b+y?$ss4DJHxCxrcM&Sk|2*+z%wE?@TpBgiVlk=zvYPf( zt0rTLSBs`;&3@x{DEBmv_M<7d8cIzu95}MDuGZF!fdj|1*6DI}T$KldzyY>k2 z$!2oi@E~JVJrX_I+KJqG1GgW&|IE9%ZR#hX_t*IQBJr;Jsd7Nz(Jt=UqhC-(ARI(k z9&Ka@1iFe$`)u^vxX9~aJfdkJ-Bk4;Z)=QE7v)lmuo1cAV5ly<{RVYG{*w+I=>a1A z7mkHV>FXVKKNU`EuPO_=;Htpt?8<^|ihF<6MnItBpxvSY60P>bIKqVD?jnaLOn&yD z7pkN-8@I91d{~`<@9=rDYDLJ&`Y5lL@*=cUO*-rz&+)62KKVFPZqG|a^@wVpCVtZC zhqnKe;X6{tV_q1naP(gNwRjn;h z>N*wgZk9h805aSISdhx{tj>f$zeOq9PZEbmO5e*Y)i!lnCo`+%+HB(0XWSqC0tzu) z1Kb}J*@7*!)TKJun?@8)Vq#RbXUqP_?8CIu- zAT8hH>Xh!BOQxO$uQGI}uCpzFjyZD+t;Z6ah{R^`@2qjc|H-$~YO0O*O);$)neA(~ zxwbC*N6(mwAP}BE#{`6Fu6e|`_Cc<7d`EbU$=DGVt3g`tA3_`L2}J7pKNGS|h~9rE zjd16k_4r$f>rdg3&|H%#?w3N4^m_Wvteb*Mt=jArsIkJD52{C&LLpcGvYm^3f2Q3Z zVwhqZg1wJm@Iwj8D1h$R5Q}gty|yRp2XhFGhTULeH>7sIUw=~E_W~=NuQ@d=vGC5a zGQ#hI-wRiT{B;_7=SGUI*!%yyjfm0?y4Ts1y1NxWp)W0am9PTN1Iv$CDpwF?hRTo9$C@jE}OLON%WKG6M&D_L#1%R(SG;0 z6UeuYZTD!qUO*K^54jKz@^OrbdnwMCYeO3TO8(1iK&FyHUmDZ-mofOl1IZUKj|kv6 zPQOIq0_c09~x2E|`P*?}os%M(RHkK zs{0WShO9+<^?B;y-N2DYse4enkhg@_bsp`CP^;@6v7)aiNe%(ioWYf8ROhQHrV`1_Tbuk(<>uK70pc&$G7 zgK?aevkY2J&}o@0##0nMAL+R)=zg$gyFpaP2A4t4MTvM_6x8mUzM&5!1UsN=(k5U=c1Rl$HUs# zGnFFTTqHd^x!kljQ(l4@@~hY?T5DpR@pSiR;NS(meP#=`UoWt<^t5~yq6GHb4vL%;%d!Y2o?4*3980i@8iHFapqCJdFGTzvuKk4Vlh|$XLivR{_bd4yEW3XaPLz?LQO% z;eMRw$TtSjSM&)KI_b6T<9qOHI7*c%t_@OY>B-cQR(j6j%AfxCk@56T)t4 zcAqzm_M@`*dvO=(!#Tb{nydW&Wi6~CRWxqKIDCL0WJQgPg9CA)G(1E??%s!~ANZaP zCGO$+P4v;^UD9L0H!xr(E84)?oZEfxcIi%24z_~dYu6@jq?FbtA)GpHw)<#5^t+-) zcoJiJz_|7E=|M1?Tc0G*NLxK`K{Tf>o#^u3EvBFb$Pn{OZ*4%i2n(VQs`sL!ur@y*UcVcxRL2)t$8_m4Clg^4NdEB_@IL1QCN6? zL0H>^y(`<=lr<;(C3e62HY;~?V8tt)#Wj()%hil+x{LS{2D2>Mf`AJpi)EcCKSdh`O$FK8hS~KFjmR_Kj9^6p{)E%AHvS! z-lz_xZnxe?#k~hJL>tr)EwBsdBLxxBqK*T9W6xbb1+4Q?b9mSLSy;lV{? zs$27DBMWH3k>=5^UNQhft<~b~>e+%?I7==-HLS!6g>olrSckIChI;(P@&GG}Y2YEo z-t2Ni?+FVOk)l1C|F)RH zb0brU9vDF5KaMl0e<13SaX_5jNJU4r1`EcIdp9bHX9cwC(0)SdeBHLH`R`%4sQ!t_ zRh9B7J=fZ`J5%-1v&wi_iU(FKV9 z;>GX5_2JbfZO`R!NaNgBv{Ks);ir$Xl^!jCqzW=&{GC2KZbz_MvLF1BN;p2jd6Obs z{ueF*bHGoLL?e*=89W}%jfjxkV?m6^1CdNiuG0q7x_bw4tQefkEwcr7#rr5$5(ewm zJ>2Gg#H5W_O04mS8L|>l+=6-GI?KiK!LWHqcIfL$TK+2*_A)At)1LUrAi5Uyf~bXugjBTa1f^TlwT)&X z=%a*XouI#2Mg)DxASgLXhY9+hn2SI=kM^kX@LQUl1`)J7T_-3tLIkafCxX%&nzCsB z{-I9Lq_2m_vr+r_p%6hgdbGaF1bN`^-wPpgz2C5hLbs6po~AWDBrReVo0d z)1W<(+hp!~=S0wVeGQqIpIeN-tW%nC0X^s*_%d6HJ&>jNAo=4!6|yNpyUGQs<6LH_ z_}GlVmPB|zf=*Rk?&JFr;#k!fmxAI`T<78oW2BrotswL<7 zvQ)L808_OLt_d!)2CvZ=qU9om&6JhK`zcpDYG})z14ZJKn-w@{noRSsTP`Ng2_G4g zXVvBlXj=S}cH^%?bis5s7iYT+QwaYR^!Y&~ec)v<_{wxH+i_()8pkE+5!Qmo{tivJ zgzN{J{3d^7CMA2a{%OG*_ymXW-8f#zl9a+J^fJ??6i!11n1ht;EdGGQX}Ne%v*&x% z>{O5T2Rq4Do8rb12wEnG&PNd{8tVxU^<2E-j7FSmx8(Z`K2_&xe|{4P5GFaSp+J@+ zH9yfoxsO2MfR>^M!AV*mf!eSSbsL(J2iM!u(F4%Wa0t)}J07H2unl&+_Pohx2|rWF zovbY{9RpG=o`$yKv`M!P1i5p6z7_9)upU{I$q&xx&Lh!irbBtDsFa|9(XfHfS|s%8 zL3$F0M)}<mxvW>;=du-kI`{eZBaE8LQA!& zwB4GH8F9Mm-tP%Lm!wu_Rb!GrfnMNhy*?QD$k0JAZjFAlrR^|K)lMY7Kv;fnZxrRV zOOxLYDhciRnBGw&f0p?1h@bi5XR-LXS^QLqpIgPxQt?wGepZT~)%2tOv>tzj=fCdv z-=1xwl=k&Bq&aV`e~>=3ttW*8-yfkL{A*wTsCdBBf zXtxnXaLz44EJPih=Hne>n;px1OW=pCUx(t1gXg4?ME2wL^l9=hFmjgQ^4>5Z!R6XQ zQg4c<&?T!ASzfwvx$9UKb$^XmK=Hu*kH5|}|LWZ6af3@c(@ok>MWTRWMg$lb(08t) zA;ZxC(OSxWN}YFhgcogt+Wa|C!P}gIYQqS`Xc!WQ{208bx>2wCguWgeRP{8Y>bG}M z)%D0v|9I7eLHgIeo~ogLYDtY2e?5T7uR{H9RPnG9aQ595kek5P9 z{Q07;n@?HS|1s*C%;!QneS`AZ%a8ywv>{Xvx|e-!lfj81I%l zLi#|3t_?)&w;f`|c3)sxdqO?tFm2oqz;oNRGF+V%!P~~QOrpL^!u4VQ=M?i-FI!~S zMTE}V?JDnZ0ZLxK2F>7%K zvfy^RIvp|+HxOWtqmX6I7x#%+CO2AEH)1-Bb8TI77)dBGM$eZupE(*;>$R57o}|p3 zcwn8FE_Sk+G|DDTEwj}*>Gl)sPW7@9%!nxnN8n)vB8q^GCBtqIobBLAww}?*)jora zW03iFGCp8o1;u=_37Zf34z@^!EPR!cvEa#<*&;`QZ%a@qdKJqtY=U8kt(yQd2g|Es zuQ)3(3)`_Mv6vP2ZZdZ437wCu)h{nEUdh(fIA1>6jpYX}${|m|@s<`>hveIiM%2j) zn{_lr@$UD(wQ>Y&#WaD=jb#D(Sk;avCgu$Tot1z{SWZLuF+BN8e%4 zIAAR-voUP>EvuPDf zE8ov@cgfO|0ZZ;K8=JGsj$O4UG3{-Yo_yKThhvnM4lFUL@r5>aM@_J%-5Q+S&e~{d z%tAm2n6&mIECbA`x$SA#&}>hIsn?qBnOzE?u%b#C307aw<=dR016E6lIBLwZ)2h*X z4J+ElugSqUVg0z9Cy=gw*DUz2DK3YH-gpIPsr&Z61>=t$i%at+%Pr}0E7ehKuU~~a z##WC-v8r6G{IrhPd=_lVfd}24-8(7Le&mco(Ky1^2xI=98XkYA8qasrcrLt&k7wV! zA;)tW+XK|#ibH5fC%@sN~cK2)q?@RBIq}i`b@MPZM_38`2OmfC((z`3Snp z9^eSbMO2z6xd~de<}hA~lKa44bMzf0{sCsA=L`<>^;@KMX;>!u`V*ve7x4#NtxjsE zuOEA8|8=3s)O{D#4{`bQG&F5UnJlJGrdNI08WuG|5ds_KyQQ| zHg+RJL>o0xNm^H{v4_?Nx2xbWYB&PH|MR}!uTH066wdyjFWDO^u6XK($YT2 zg>e`K{+)~)&ZTvv(veP_3<$)gFyrln$GaqFh)^Vd#{xIlS#hzEZ-BvBWCZf zx=FVsI28Ow!Li{S+sFNNiM;V!4iErz!yktL4*~={M8WX$?lDoAq5Tblh)iFR5CI-w zg6>$AzXoLJxZ!<&1^9_T0ih>3QJ_j7>CEv#YZPjIRZQzk2p?zOK4BrI>C<9D0POua z4KQLk-}8JkOuFj<*nNbQa0Wys=MKR0tktI85Vu50l%CBUIj}^@kCUFwreCX?pTM3c zrd*;-QCDKx;njU;_P*3TgX$tCXXPDY+X+k#RyX(@94-V1=W`(j!0jPkcW*Yv2OkTp z9rs5XY%lr0&ACaiz7Pe3%OcL>1do73=o6AWiE&9v^yCk4?gfvJqI2-E^-xHiC)U`H@B!pbUNXqZ$ zLrE9nO8#-YUPB}5g!F6<{SF8Q_O^=o)5moH%yo^UFsisK4zwtJg4whmC^KPj@HwWQ z4tZloguQM|G_TS?A~6hYSf6M}d5D~1c7=vr)D%NH0ZlO&560wj61CIhLiI`OYUvHC z!alH&KE}qIB>5^|JH{7O2i}f+sXnV@ye1|*R5xfYNr(|*QgVeppXBND$&V-b+Oo(& z=eOPDkxb40Fx>3fw+YUOZ4{qGt9TI2;vv-Tuev{r>iq3`=ikS#=&B)a^#1cHg-FQ>22yB}jhH`9)qlO^ABI{E;rvY6Jgc4y=m_t>3e6L7cJ!F%Ol}?4gR>T9j1`=t zpCDk&UZwkQ05JsGe{t5PzHazJ;L&Lw2@pPU9;10ffP{xAnEc&N9c^6MHqbUU1e@5O z64H*emdojic}%PVSz+C27cdhuQE=S}yiZ*m0#gFJ&?tw;*H0r!c_$wV(fB%Bc+Le! zq5}e2uRkH#kU^gm z@&>$r8g|TFa)`zZ78f*FE|c)b5dXuhGcbfQcV5~tBX_&IP` zTKeJ^(76+r`1Mifx;UKkdaRYvhB2=p=n=mi*HQVH^Y9G>uXh|AODhE<(7I zu@7_&ua~~KzJmA8y0a*AX1%41QQe&y?(UmI()R^?jqE)7EXh+P&{4id(C-~SuhD=5 zA$95sRq#Vl|MZjPq_`Vrhr9%AQ)bjx~t3+b0r4E^#NL%%#nDKl2+IA_m`G<}|ltf@%zwM~Kw zCGk^6-FK3NLC(O@xB7L_rjD7=?%` zVZoqlB(b{4Hr<5J&FWG5`+XX85!g&4H(jvh1|P7zm$-8ed+)~9s{6TjPrde!ufiQk z=7EyyJ=*O!?iA(SvuzvVq0)}Oa1upe4JYD7Vh?XT|A2iw#5a}MVYq-eUkZFU-f|de zC1S@9iO!eU!N5PpTMi1xQW1C1bx69a7rky6Sh8eEg0w!DSaruHdf9Q%i5pM`{)u&Ao2M9&piVqbzt*|WCWRz)$9qr zt}dnEL{BoRNvhC(jvPqG=1Q}YNKRS^>f|Q~7R#rIV4H&GE6U5XH9@q-1994M&2ue|Pg<|^XtwCWs8Gg#sbyLTvcsuH zwLYU-TO+F1p38xk@x2$DOgugmg|KD2c_0vn^Bq=XV&(AWwmNq>4+TDp4;+sV48&7h zTGyM>T>}8A0j~VPL}`5)q4Mx1dfD-zv(42>lo;!3m2z6yZfr3-1N-82PwlbnwiCXV z3C`_mwjjf3D!U!-i^rc9WN=ew;W{Je;1+avt7ehW7+FdJ@5MKKrW0WXCqgSH!erDD zBElwQj3mNaHA!XKXx@q-f*WTz;0158w8GsB?#kF6HMx$}EadAWNlxU4Ir6cHOw-SE zxQ=<@v&)GC+LXHXu9y}$5N|nJQK@lvVBCL5u1jvK>rhRKBq#6+@^H>4RKcOh3OtqC zzoPdjg8o<#gjiW%)UBmugD|#K5Jvw8+T4l}^O_TpBxqnEj86(X92l^$@pM5zKE{l* zHE@hhInqEmh|V`)_cjPlr&Tlt3cUb=~Sa+fzj4WM4e%V$j_dN zpw6#jsKbXy4RQ=IL=ZP4ga$h zoPDgYU!9$%*qUY~SQ`thOIYFFB}zd8E5yjRvBLdIft?j4_4ATPVfi6~p~h{l^rw54a7uM?$pD~OsUHnqy^ z+{%Ys;8;A{AqWc}{}+2~Bn4lTa$dx(*YEQ2%1f?@hp_6g>EbXtgz$;~e-p zcY^P|E@eh2gzz4b&UQn1y#=(U2D;)^dkTjRNG4e>$tEe;EXi5eT*;Qn+wvuZ6gcd? z)YVdREBw!qj=e>sbx|I49FKjj7Vif=#jduRi#H6N-sb%PRk;q=T!B`pRK$8NLCvCZ zh5C#k)`#{!V2N-tng|S$laX=KW^}ZpSnXBZ$!I6m$DLj{$$;7PI zaFWkp>(&w}XNp1slU23XW55#5ucvBGMc4F=A-awty2gfvwuSFd{{- zLq21bd@?_-=F==vJDEqD-t;8(7VOXGOC{6t;v&`Bh6D3x%#OJhht@41tAo$2py^*- zpy~Z+muQLzJvLwO#BvILJjMAsCOdWzGIrXIlm355_mGvZtU_HDWG}MqVE!G)EbR)S ze}M{FhW$9J%crFk5y9Ep@E*Z901FW^7_4Er=@VVub*mu5_5AAOud-d37ul@qvRt#S zOZ)0usMgmSXKA{MHY+S6^xmc08SaEQ%lETGGD#QwFb-lg% zcYLw{aOhSpq?W_=hPU8Ii`hGa*Nmnt?Ifd6|9&C14v6|8svx!?svx!?svx!?svx%d zdHpA-{x*o?RGik^G2qhbN_Zy-R@Y0*b9lYy1aw<5Rk!*-n{cl;!OUv{zBzEX^IJ*b z@L`4}0B5CV5QMYRClZLW(kBs&v(hIMkh9XK5R^m)^dH3g>Gv=X(lr3S%@e~OL`Z}S zRl1c<#$5v)&PQ8Wk~~6^OJ(KirW~u35opYYK+gf@vlHNM2e%fuB;zs@mLn?=aXE0I zcd(ok@|Vj=RkBl;NXvIymq=@xQIwu-cpll9W5s#YB?_vM*5ugu2BpZBhRT2n}Wa#HYTHu>*Ek(-(z`6h!4C3%!2SIA02Q#J=N4Ru zXWNxLxaG-8p3Jfxa42WlDexv|*{Mq2kRXmgH#vx?Mp}~{31YSmV(Abd-asH`6Nsg$ zEN-e<@;wlNLG%BYFh~&(`231dk;=t&8vE3F6xVVD1`^nA=Q~`BgNntgT@R^16Ks^h*pP<@ZkPR7?2;A=}ovr-^9%^{b^uSrL70z>y;T>EziS<=_oF6-1 z#HR--3(CwP#bH*3YIS+Eb(HPa^qX-cu1A9Qfm^sLwV&W4&bO)+X%MFa%fG_fHn4?V ztiyH5vI}aH)TLb*bVyis(DmB#F>D0wdrTd!aT{Novde+r0yvWR~?sptl& zLN7{px}oF%V`;oM??`v;0_ebMntI0p_LJkTE2TRh!gP)+tWKD#$?J7tKA* zY25=SFoIgUfKGo7&v)eR0(VHTdr)exKy z!yG)5t06PF8ZwjAkfCUu)HsvSMru5e4>Zh(#M}%Wb7ezdZYE)F24Su&wR<#05Fqtj znY3_$;<1vB-b(ifQ1DGVU1eb}CtVFP#Lhm1Oi$Ty5?8IbUab3pI(fRTb&Z48H7@O| zLDIU~<1DR~0rooSMz5Ts*42)if__I+21I?T>!i1Yw5>waNSaJ5n>CJvT;(MHxdJAXFM#ZlmQUvm zotyII`f&A=Ofo7c5h^DH8PU3g(;8mAP`FAstxGtqOE|4dXpsbR-#9OLD${O3Yd*5dU1C@r zY^It7)!G++)&AuNCxY6Ts|J}@w+)ZqxWKWvDEv;B)`#&sJ!C0}!ml5wG8y=tek%NS z{_fQH-6+x{@f!#HK1TSh)uQmb>EK}e8poAlSL_16ukp%(-=|KA-#Cun5om2F{BDfE zuOIeB?Wu1L#xEV`fh3vCTDetb3Xe!q>FZBhvkbF$0fu6(KPcUE9VVOdG8L;0()T`v zU?LIFP7^$P2?yJt)$Is6|8D7rEdu9vuxZxi3Vb zD1B@CT-J)Ln`Kyi(Bj&k;n0tCcM3M1Tpvs8Wc;dY(p;ZO>*DdK$B&d`iM=ez6h>*y z-=$<&GilM80gcI53>ek?{i{qsZaycxf+SpxzI7=wk*V*|au@%~sXKjRg2Fru&N<;uMc)h}{T**&hd9so}lI1y+ z{820qr=v%+yi_HBEGU->?wm^DW^m;g)iq7qcnpxtN}q$X@=)KPwsShf)!icuLK&?r zze}y`a%s!66k6z<@;E%)d)&R_~PQjjm_`Tpos>hCV-Iq$TnVX}tVVB4vOHOv0FF>}L zEU4ZYuC3m^u%m{H8~Zny%~IG;Z0rHr(qJkn-_EUMaSZIx5N}7y?*KXE%q_S(ECT_a z0+>VCEICz8m2om-1Z#^vkJTm)YKX7mJQhw`Ay6Co+>WZbuAd%yO4XlcrUC?U+zR#e z;F>Fbx+|hK9MHPM!OEwwnJLnfuz(u}wT{8Gm4eKPh!>-u=-NRCxbXexURFLWoUdb; ze01(=hV0x9T&7A-w!!R!lXKFOGi5@#njN=8J32WXiE*DVXHPFW3W8# zc0$%g@F&GnjBL*c1vGSfzy8&!+Ivcm=@C&q^+zjc4F->ZTIQNjJoG|^R*rfAadg*t zF>xNWK73g06z9?OqvGP2=~EN=v9#Vxabc_*O(j*QRcQbCrQS}&b}XGd4I^B%_wZS@ z$B)6y5bdpwYOn6J?S0<(mG@2f{P8O}EkqDYpvhjLwf$l^a%`hLGIlL?Ugxk%-NL?$ z?&LHMkjB`PE4V%Ru$ss1$rIRNgyE_}?P6D$m^5l*7&|sv-DQzn`g!GT)t+BZm$eV- z<8&q$@2|(aw};*Z{r86H4*@gW`QrsL4*R+t`e8)&R6Pk=whn)>RdFot=pi=kXG$F| zP@ks7e*@fD?wDGcS~HcgyOBkDa;s%#mV#rtK6))sDpM^1fffbVBO;uXYPC>8BcOXTV_Tq9bZs<<7@o$4~HA>D}rX=8201iaU*yFad1zDHY++O>?f2nN94Sd=cFUt=rgGw zZdqAqQ`W#Pie{mnV4oM-2^q2@eI57#QydZ;;w$sY{J<*CK6~Z*H8{n3AuH1ONm!3s zoUV0VyoX|RAh?4butS5xKf+HS_R!*Ybb{hsd3Q%f_zv}mc+g{4hYqDT^md?R=zM8x zJm^LwGXDnp`)eWw;x{rsdHGU!!d4!8>IM4FiVK({z@8@(BX$Z-`QZpTVqM}|aMqF( zz@5s{x_O`#%gYF8_D9X$5mOh=t;r~z-IK~nc)%DLCpnAy5W*(jRcfsn74-H7y?c0C z(Bm+Q)m)D+YI$F^bv8dgF1=7E?poG^QX?WY-3O~*%$(HkdVyetKNU4iAze_o*C-rY z)v2y+rkkAiE9IJki%iQuqR7Iym4ZI@#@$8&>n=i^^waOstLP;Ui<8Rg z_OoO*y%Lw5j||SXv$`%Nu?L6YyMou^3Sb_~>n_5oHxX;OytzH`&fUtwxiQRBM8UCB zA4Lc(1jlaG)aOs?7noCUD{alDJqS;Y$RK4Z_gdA5VwDwK>d`jrz)iK7RXVgIH&VFk zdhsp-WAX6T-`POrSLxxYlHQIpY0l^tQmF-supNAckQ{0TorR+gnyIWx! z#)RHi@psFh#=rMdR4oG2AvV@Md*V!0Q&1I!&1$w3>YlWu=&RKiHqrlgjZVUmx38|24;V2Ds%=&pdzOt9u(+>P1nkkOH zFsb?a&s^a>8H@hSYEbJlyqQ(+StkFeH4f1fKZb)ttg}??#f=UD{ z+BDJ@aF>?^5;iNj3|Fz0U$NCnTWnEj#UhIS)Fy!0hzP+_ML|iG>cm7F!~!C^|L>W( zcOQ9y+W!0h)XGc#w-obx@MLL0Av5fI8=iWow`2&3bfcH+ z$Brn`Yub0BVm&P(M=>W?Py(HELy0p0=f`*4PYW>S6@fwr@ei2gghh4jMLHH$zBN?+ z0zRXEXj)}@NU_s3;TAPk*W=2}m&ImcK_-}PXfQl@3ZP=rL{d$dsL=x>Zr#tTl!ln zN|Qh7^aJ|_>H#W8-A47M?hp-7r>6p5NXr@PWi|8yxKrV|sr=C=fH$&-e*zOKyrwB% ztEtB8NU91-wH$thk(_jlC7NL;S(!?isX1wCae6mP4|GNZh(Op=ln%C3R{=i{KSOnZ z?*c+-k`77Lw6}80A;7{N zkvRPV91cAT;wDzi63Bl*`+H!wnESk(85b*X(G?tS_ZyVXt_3M$0*9OMEYQJ4G03nF zU%g%jhx-I5JeX-De-EjOSz5mVf4_fk_xyd!cO`!VH4cbQU>L#5)W?EL9VYKo;vt^+ z>u%U|(1l=AI@lsae+T#m>2x!DV=?%&y!RcV==WUZ?q zi@I;h#?@60%zEv0GBAZjW~lKCBqkf zNf52%k0LpbU$9GOyJX{{KQ6kmUCI7VY`6dE7`C(WA-~qyZXqy;Vi!2tFHHj8KTVU> z&k^Ma@4sdfeqA*i@wYp?e|pX&-hYw?rkEu0{$su()H%ZYuYRr`X-&QqIU6x=Dxi$} z8$kc~F!0l?qECWww0Vk%8x)T99 z5G=vJ23W@g@Gqv2_sgli>ojE}K!L?~xJGmYcO;M6G;DyxCosj{FOrK$3Buz~*=WH0 zpEbh&yQqnytX?Ag_k!vVJpV%i&tGZLk?ulDJ2him)f(T0ozVTEaa1_ejRgYYziM?G z`iAiRi|Y8TSbAC2Y6E+Gf1i;u>A!Z{vqiHKq&RXsgSV!mG-aM zAep3wI{3eiBygn1& z{KlT+Z^Vr+F;Fl#zT=Dxu=k;VVET~4o2PFwIHC3fuxiAfl+{p-0bEDD9;0ThJ{I$UU4m4(~{`GGEI^SZ5tn7tDG_QoW zQV+)<#Pj#A!?z{t1w#Bf!UzTkX9AmRtzI_3;_7s6ILGbXfO30@Y8$KZ)?_ zQI}|Y#Qltzd)Rv7w1gRUsG=a`HVQ%>AIvR7$5JlYS5G zRoY1azzB>8W_z0<3{%RI9HDHqe{`ao&_ zd1U&UfjUSA5JRPC18Sact(c3(>1-6`g3KXeJ0k|o1Jrsx=|#QiigA%GFJcDGFYk_> zszOcCwow~p`^vsS`({x4W_Q~@d$fH^H^#N^$G_{PeO}1%#-va$+V>MIR?v`o`R&HV z40#dLzUP<3w(rAGeEVqJdu90UK^V8VwZ;u{+5T0r?eBejQ>?WdV3OOJ-xe9@#Nu+G z<4_$wN55Z9+@98*X2(F(7vuew-*(UM`6T3b8t?4}zu)-3I#ImFMFB3l^85WScj9;F z@8kHr82VkI5!%uir5On16!c1l;!OO{`xsZ%)Ab5I6e%%?x-V7E9Ose&zs@U`qQ)HjyeiA#&TvMaH2bVjYInkb%5PX9qlt% z&TLlhbf<21Xz$SDgN{0K(kx~EO;e_ph38ER&+~@oO$^T~grx({^AVnq@xt%^17XR6aA@eO1GmOHSI)V=;Q6nW2QQeXGYfsY2NFil81tL zKS?t$Qq&9fFbUHt(1L_&k~QfA1iKVfsc%$vn)t{8LfXN#ncYj9U*RR?x|gKF6Rkvm z=vl3!Hh{xG>h>}SgVfKH@f%o%<=aLUFz}T$xtD>F5P1~QS-?Fon1cX$8hNoGIr^$a z2XI#AZd!(reN2l!VHz?~1NPwt?6N4bu~uY7xoJ_?B=dCtQ$3Y(A#&Uj*kp-TqRD15;f zg{epz4LXwjj6MppjEhTg(RCF1gm4LAh>D_7cx*k5Lb^kNiG0*5eH8vr1C2t8VI%_H z@Vmzv12OnC>g?ryB;ad*V=Qx`>i0Z!C@cfiATw*lB7E-Uzu79P#+pibqUZ17iVf`) zG>YLVpue%o731vVe8XLl zRS|dl>JwzVn|H>b_K|ou&*L$F8x5Bdh^YFjzly1PLPeU$|AVLXs+aKz(Hb@zPp9&$ z=&4hreO^8_>H-R-MC*b(1%=AFi~hUa-5lcNxs?`Jvs(N}ue)G0Wh4>VNp zmCr(XKgkNbc6qK8&Scl80>6Dqa@gO@ifDqSfIv7eL?BxPmkRs2H@umq4n7g)mGm0I zigBg}xNnY42<$Y1WUGx(x=cAlcYmilOs6T1pzzO84!FlUg5>&5Ga4|$p)^347#gt& zd@7sYT7G9$)16-8q`>0uh{bcX^hyzm}8PAOv)k6@{DU{f2jA|TU%2PsaG$Cahhn#>6p_o6LZa+=&Y{1dO>1g`^*5A!|9fW!xJ&lSQ7!nJf#@sch_dI+0VCmjpPxtvVtk z1={CC=Arn*4v=&MWt%hhF;fbTfkrg&z8lTHRBA?_1*gL>7=TNfwc-H9mBKUgU7~5m z3C>_K((#3(wg6&H>u=FgO18^SpE_!PCRC6XB{vwu?mEG#Rdn zjEuoQ#O% z@8wfhpyvzd@XE`FRpS~Z?92!$n?W{{9{33Pi3muJCv!5?ng=97nYh5Ck!lUC@KkDN z@yJn2dV7-ZDhv5Db0aLjUKe<=gOU9MMk^etLA0x;+-VmC^OH?{0on=8=SGUUmB}+6 z!M<0T#m3vj!j_)9v4Ms)8_erM`Ly#7hw^C_#19ER_(`K5if@A$Q78jH*$(_P=4Xgd zQ63t&ybr9!v2(%vahxfeQA_$rvj^z|P)RM?#Hu&qS{-GkaThx{FmMpzVFVtBHxoVh zkEp#wO~lOI#8mo>*$3%?pGr25S4%c`A{Yf<|10)4;d!&e^JazT%?Qt%9-fy;D&I}N zL)TD`Yjfd%TA?lRk-gdtbA(swTsSVcFv#C@qKHJY><37LRoM62x}%p?^Zm_P4q2bn|c zJ!qhvv*zDB(j39x6SX0D7o?P_!XO1VG;$u8g^@$g;hhe1cw9Ku8WL<6a1c6mCtmCG z;H!KjIo0J_1H9S`OH!>MmF@QOF?LZ1i597Vs_C2sO_vh@S#xt_#-#ZY?imRCIjDvf zj6A3{E9MfVVG_>^FEdC@8&sYLK%`FVWp;Ev?RK%mV#xNAu7V{AJ49=xO-8{r^RYkH zS13apgB5cagdy0wJhh(M-&Dp=VERSe2nufjTO_h&BKB8BAX+44>INj_7s5h<;>v$c zuG(=N6k~u5Ee3gYJImbjrdN%{PHhyN08-q=GpbzJs$EQi-BNg7WN)rIAA7rDq^p2o zz1zN~sz3Q7%-n3g1uMzSE9>cpE(MNrNAkxr@kbD(+K}O zyl_@1i3r5&?o2>vsoA_5zij0u9 zvh~Pi89hcW>p)h*h49l#;$vH7Vf-|X$YmLbv?pK68X>YPnqL!JlRB16xXZ)QII1AoGK)SC>-at zRpkmJX%QgD8HOmY?8KO6yRlVLnrPL8atwZ7h>``jFVv;mG0Hd#pLZzA(oYzcu9;RaazeFaDXm?j-gPc1*ho}*4;Y90PkB(11sjqGB7 zNAHxKTI#RZw8NOb52rbvd;<-sUV3;4OcDpu%2>3_#e|^x{|DdjH+P5$iujL7m5u*_Z}?Lr zrxVRC_=ayCg<^|BUXnlK|ND4dzS)9=gu~V?Ue`4F{{J#w*Hej@AP7$>7O(3edid?| zx@@8~XOGuq??7kzP_9_7gnt;xFoyU6@({ohfV7!{rH1!Dc*hd^b-w|o*=hK1}&f4;3h+f?=zAy(Q;Lm0FW z-EyVqmW#1S%Z=5gAUHk1&bq#YjN%t44+|IQn2tK&>P2yYtA)2lCM4e!tuxr_rFd&h zMizpAvseTGoPq;JYZ-I9I!Xb*Ip%SlLf0Y*9D3P~o3UX*5OIJm{QBcKqIC8*?cKli zG8Esle`{`h)`I4(IGl{`hJaVqU~lCykH{Z&I`9Pyf7G2ITq%Ef7B!$}f7Fhs{L_m( zW%#2Cv1-JpLads>zcl<&ou$0oD5sO81#0OWWB7*(d*|ncI1YQ~6(l*k1ZLA2?45_9 z1VpbdAZ8O2;nha-F zN9|U+nrU?(Lug`hf6fDh5sC5!EJ>FT!tM0IcErv8%LQZs8!AGY503W1V%Z|Q`RANaKc;mYUEF=1Z@=PTp7DRIphn(kPn3HXi0E1 ziEdR;%*dih8tuNIb67mY3w4)n;`xD&U-Ic;BY}k6NCrP4MuQpU_?= zT?0~ONgDIRGcm=hAz1z0$v~U~M^-tZEVQe4rKnQ@O_e5RPyQRITXAlqYcndH{IVJ7 z3h78o#zS~b?y;AWSJfVV+Yxf$r=iXo)nzvI7JJN?)`eUs2jhx>tUy2Dx)wlO+O%}1;VJ5PXbXQ9qj%EX>gYpQtQHg7}rzu zXA8#6tU!J8gXa9SnS)Bx0dN6DUZK#dP1{j1R;uwb_`ZKajVGK@A)$MD)o*bkmSVho zI{xJ>yc7%)bADSI9W*uVEvQH2+$8?|maU~uWZDDtR~*-}hwJEiE9p3-ck`5Dah6N_ zZ7&Wq$qHja1sR@fU5`gNCRIyz!=Rr37$>SYo5gN=d;dli@jU%-fljA$id@NM{(j@i z()_987N#S1ZPW*P7h-<`yVmO7MWwwDcP7=-Xhtuj0#3f zWO9J!23w1}mbkk^ad+R?Rr-Kh(ji=>+u$nwkz{d&cjgLr$q`5JYSauq)$b$WdwRl_ zt_kq7CW4mNGlDAWG5l&0#a0iH4mz^h> ztjNT@9~%s)m|7pEAs%(-EqXur+havaY8)_dMoM8{g>s2X#}0T@XcgtSb-Xb{kyebIv(lsyD;UzQM>-T zU;jO#8-8qrVJ%5(O?=>Y$j^ISG*=)Nv;|B1L?6uEy_+*inZX)cYUX)piY6x1Z* z7k=#5*dPs#ud9{nD*VC)??tK$s!6}_Qr$1Sf26Q^qOdQ1W>of8ao;BIV+y~%7+FXB z!WW?MifRyr&dmSRb~>hBH{+EqCPseb`q>aW6_7~V(;`a#$CcA{GKUfu!5WU|myj?J z<9s}bY%-g$LROmjrtiyB@=8EG2!CEa%t-Ep-q-@!Np~~8@+B;~#-RXduL(YQ55F5* zlWtZ)7}P*Px_H9&shIW|tbfQ!an=2T;9g#1 zTr9#xS1X3?FwCKCUBnYMXDL}Rkd6$sxAGOY>sAa$9*QBmq_=rRL|!?wzjtSPzcIB( zdYgE5rtT5jBpgS`W+4F>RUqV*G}(0(Cwd~}<*0QpgdDX{5HiNY(@Mm*QPu?4JnxN_?5g)=(0$BE!LTrn|#; zGvGs`d?6fWJUFEkE>5X%T9m#sm+Ag&5&xOC^Kl#{5;@&-Z7?+Kfb9$2`#Nwr+3KE` z=YKSsZz$==u`FOTMV%W^E%J9L^tuWs3K2d=s@79MsY=LuL!^_K>``ZdrEA*PV_JYc>bfZF2HHm%B14cw0ZbY( z&M9xHcS04FIEnRN&4pMt%&cfWi#c0Mvkn*1i{+Q9||K&A>%bi;nng zFsBGkz;-46EN#EHIAl$SCF6BkQB$R-(i2klqf~4^4$u$3pB$zp7~URwc}R*wB%G_^ zw*w%Klr`Zmv%9Q#RLt_d$Xy&x`YI`h zPmt#8RqFJ$JyhygrL5G=vQo8o%H<1xMO|xA61&@qsPILH{Bh(pfHZAzq3kgEFTo|t0pv`7 zK+dF6LXqZqO6|zo&aR*6MUDwx)PTB)vj4|qk$qp0{Qz3(jW=z@81ek}o6x5?`QB*- zf!8WL?C(G}uxrD&tvJ?1Q$#Dm$|3A>S?9KlQw}*+WDygfeu#*RsY)x_->H8au#~V4 zvTxQiL)Xyq8B#j%7s5vu0{sB5B@2Q^P24jH6{*_K4gjizEw@%LA7F9>>Ff~5ayZWr z_P~L=lb!6Z^Ap(Mz;a;2O?J+=0B#ixnG#-@R?Po6`(U_%4~ORv#F}&1av0MdY8zC+ zG5NGUM`mAp*>&hK%G&od%5v}ZWd#-^qa4a8$4S{E^Yg>=(jX`EseDFEhS(P>huZp3 z6+^7Nh3MHZ(cS3xvcAlJ1e9D}1YY#FfHVL})D&0-Tmb7=gB)R{1GH8BM;J)dnHb}g zj=M^6fYf@F>^}S*Ja7eS+r&pAOAOjM6{7}|P3#}*AWNjur6vqEY54#it4eb-_P|A% zcwpgwxD-MQi94;YW9MHQ9*qMjbOvbwkY+zm8jZ1=0UQ**sR*lx-d&`Tkb?<5Mjh9s zl4Qw!&p+_yB|HA$IPH!#A*BhI=;Ph;r)sL6yyeyn>6b{FHl|ht#Bxz;r$Aw zP@43zAYj}{@?lYvmp@tXckJt%<#_Tpk$R=!R65qwnR@jR$PQmz#CB$4C}1paRYlA_&+P$x&uTCDNCuv zp`d1OM?b#mVq!Mb!E)dm zlWhsXe}L`c=Rb-aax+fvUKis(Q)gpfBSAD6mt*tURA(T^YHjPMm9zlD@%*9CI)&_l zAJnRre2lg(EawKt-35+YRp6oZBC}2jv4T;qhDPO|(EcZ2%AljJji}X{N>g~$Q~Y~> zge*Qe6I5ddnEfdjGy#U$jGoFm9z3`VDxplWLbld1PbzSdz2Swa{CAte;e34HKDM+4 z@3pc_%vmt-v2JekWSH^QccA>WZl>dLPikP1)wHlrV617ujX8mOoBP$JAFnF^CmV0g zXZ?g71*$}q{s}5wd(bzix+-My^~V&PigCUe_3Wf8(@6Y)@4^UZ+_Xp6&pL$;!SNEDr$w}PA31=yOAwXrk582o~Yt!{Z*#Tkb)Gvx(u&)S|>OW-G2Aus1Q`s zz6jlH$U#aMe=AiZwE-Zhe4$2`&ppPg!Ag?KZj}Dr7cQ_%=h> zEM?Z`36mogU-DZfh-G*%ylHTI0xe4+_1ceN_Q5ofVg@lWKR%5DS{Y49-vrN@Nmkb`EtrICAR%Ujy~Ucg5yh)79>QP#w={f(u;Usfa3vPwJFTe23uZ)P zO?;?)jqV*P@(k8vKqP?Ts`eRW5|__O6f`JdNMTe56@5WC(-B z1T}aPFIY~RD<>64Qs$tj$m;8G=+t5%_8a`_q7)o-|Z(=Bk`VhSv2w9ovFE%vCwOw`{O$VYH?k2~I znWzpE48b&VwTCPvxQuDraEB&0rDt@7=4br2+kuDgt3T$rxVFWVKLX^>>lhcd6eo@%Krtg z7Md;o7q6HYK5+?H-%|ePT5#}-#NKQxbvpd|@TodhoonSEU-#is$&AGKpnl)O5@pw&KsvAti4c0%(Uce8b^W(%p5)dC zk&PxMD#2_oej&d+MPJHZqhX9od`!L8BzjNMm5=aXXlpc&x)xcnA9#_N{J|61<5)9! zAzelTZ6LFbBN#hR8ZDX@j0=qn31WLm&EBW__FUj(k1E&9o8^b=jg_0ufT zPruUp>EG;};LkU@h~`CfQRN1`iUj*TVYo%_kZGFUJCvYn@7M_7TTE0sHyhJbB4)+F8z#%=vH(?Z{NPU!pR7z3 zd`||?(sM~n&K@~Iww?qy{*8AXX5u{N`L-l36$qMr~F!sEfR*$Fr?Q>~}5?SQ#K|F={FBl|pi0i1GLZ7}O zC+IsO>n#gXCLz%P)WO6?0R-J9H|MTBs#w0__97u9%6eU0O9BVQvl0tHRy`XvluaCD zrK3{|q?9tpaFUy;W*qr5(Jk1v+V5uwOJ;9W?WfqpMyp4icnYG(TB-vRO9!*}Vo)>t^=B5ScyiYX>VF0L%GSgyI4d5GiI(oBFo z0|al502aHVR>R3`irA=bH#Vw;=y(K1`@XCZDw@T#%~VRrwKw*&<>IrD@!25ytc;(! zMl__8fGvFUU-m*qf$hD`R51seB27yJ-S{cM$4cE{knX+wvmla5X><=%a@Zy9uh=NG z3zMOJ$3768JOe2)42Wa+Tk{REJ4lZK4TlUWrV+|+a0BWc5`QTvj%w)D5h}cB9j}g* ztgOTNXY{M};w$xi!2kb? z|MA+KU`|L#uo&^|S{w7y`(vLuN-NJ~gI(K8vyM|I`_i2>yeSSQ21qq!OZ%%o^F}hQ z?N5^4Nqu`&#(#@^vAqgodqpR}$uZk2e=5&=MBiSW!1l_52?b~n#@;HtEES(5Z$|jT zHPM|_uGm@a#m;JC`e3N*@~L97R>{QE^FiyGwXgWjsa~3%g54F6!&BL7{QP5x(kSDt zT1`)x8^>pu>X1R(i&7yh&o8bDM9wb)?HQ5HPrScfl@r=9M0Cc!M`=cIY}LOzJcheQ zLkE)tw9Wz?2fYdWY& zprW=d3mk9&8JMGxcTziYz{F1$z|6S7Py~-Fu=y?r3f=+OY*P?M#K}v^baC}RhThz=~lY$Pe zxE*{2u8vVO>dQ@!9N(GeV2_~!mClOwy|!g!q%9bprf<=f+phYWZ6SwgwB@65qAh&z z)tEtwn!WrK=!fQ5#647yAK{+3{7aw{|C>hqxe2NV9k1e zv0VTuGPXzO|B2cb8$&>Txx>)*;>gn(uCu;kdTWWqw5ckjOdh^6buDxpc z?ugh2^;&01=$ev}k|B=TgBZ>T7^uxP;|sq$Q$nO`dWo+)1-edxO`88mTYm~+PJ!Rh zOVa#MWY$|)vT;`t0j)H6eu5IUMI!5a#E~_v|E8AyDoD{lE^dAGNAkvwCz! zXlOwoiUZoHv0Ajaca3g;Ux0_)+-smMlNHd(4-cQ^S*s#W!B6(Ay-po=i;crL!H zN-=f&D7|8bW)ul2A7`YJeQFDP6?o(bcnx0T*W(csV(>l6!u)j$N>LRX zPLYR*^I`ZOA}cb@^xOPLSr%w0IN?#hF&@oxlNYeE>Z|GFBnX98@m_9B!?ljzzd(TiX&U(0?9f-R|K3#;*clF#;pfiSq|LVV({2XEBQ#vD^f_3_iw(Q;RFj)JdRN_uP}iyAql?f3#lUYu5J3(Dh8`-5L`dVMK6dq(h}vHS>E*~& z#LNVT&>nzi)4;(wy-h_9pUqYW;NEnjwAY3Qx%`ITgQI9MHS+~Ayh&4tw~DH4{b-n+Sh$n zMoXJVOa?v(hesH)JW>0)qn3_c+~fRNs4+OctkSG0cJ?aH6A6GoHn7oS1$W8@U9>xs1A=&-OwEl?U22W4sSQnq7u%)yHI?<;d$`MNpDB z-R7zRs8TTrj;%ie#VZk3C7I8@40FC>!=_5jM727f|3UE6Y0r5-?D7Qd=lDT;ibrgN z6V!9aYIzAz=k9d6Ud9MoaRG*1DZ48fVdN2%7>4f7z+Q(~^FGI#_jy|iYuv|OP41%$ zlKw*9wk25_;W;t>q&C^CJ7HW*?oPYH?gmHxb}zqfWMsW-1Z}&lcf;lT$a?2ga|sDB z9bN@m_T`okLN}&3sU9WsZ)EPWQeKS13QTpGn)Pz}@p2Cy;0t(TraG@Ae-e zbNKt6O+4XqQ5po6UgHT5`R5m5z9SZRLzgdV+6e>EFzKsJ7r2PE>4fH3T0x2_FG8g{ z*-VdN(^#7>&hzjXZYA^?@b6r6W&ZN?fk_m5NCCI3a){1gHQHm$9%H;?CbaGvYzXA&)^>F_k-BN zP`}jao$Gf&=lWd{`-wik4y%pPPo;LZ{xeLj?Id;qFaR5j1AN5u*vaQYCw0gSbdx}R z9(Eo2w9B9yAXt)pt8N-lSAMMaAS-Y8kC5}(xFyc2K5UAu&B{Jy=ZGb!9eam9?q$xZ z1lHm1@ZVZ#<0CRaROt!CX{&;L#xQaNnqcKOABD;j8|Y&dAc?*!vcWo$wp_{)ialY{ zCgowb!k?m)fqExyh4~lu(tiS&dfSZZs$c$TLC=9g@#q~wpo#b% z5(|?!Y=e;8o$p!jpzqEaEHB~f7FIUApHTCK2~+j_i?rMkfmg!r9gh44FaP{|pi~p> zAYbv_5bI8Q5E@E;5O47gd&hcJ`nH!^c1$IieGD!5k6?lnBQFc`_$@3nlY)Kox1h}7 zWn1Jt_HFBTW3Tmd_g=p+Cfly{yOHYm?4M=*q%+S@)*@3OKT zUBwUh1&@W$#qW6vl__fH6B;2SU@GHP=zK%ITJ--U{VquFjeg+~--dq4+c9DxAe{~U zY*1A3{LPYncf&qN(C->Br$N6hQTi2krwtTnNBf?J2V-~9+g2%XJ*~#fQdcli=YV(& zqfmh~WKrze!aTJgo9$VpATgO60^2AaN{l~_6Kyq-g+c`r!6R^I^~#@V^b^M)Qpu?= zr23B$FL^^DxmyWI<4V!+4TGYX?sc$eAg=5usV`q{cUI60~zLk#M zM^~my<oH^b*xwDXSsnCg-P@5i{n4A2H~YML`AB%g(+Gv< z!(?*dHzL3lj3UIMOkslwh5UjwOyFtV!tzsbtFTGwy?VKm1Sxpw>EUR2K2(wmV!~aMyc)t^BG$>5faiIHq#3S`$0&*0O^SbkNH2v zJ2rXR*HppYEmW|>sZw$lp-RO~B--RW-a%X6f=o0thfN+!4ed#Z=n{?G`yI+JliDQm z8%0;f+$PYqUV0MfT8AEw>E_la@F-^dkd&?^dze|XuAvhFfiD5I)A2ltciz8pI^tiW z7$TC0^DgiZ{yY9osFK|*ot{uJTN&Sbfvi|)W;6mlPIg9%$5z#(0)N;e4o1voV@g9v z(4oD(FRe@g!p5;wEKWlqO{h*b6pBJN5c8&Rv?5=1$d^lj;djF4ykiZRcxtELVvcz=Kh-_SPhn=hk#RoCV3$MR>oCW{e9F$*0%oR zE{A6IT4+|6;c#JGhCf~Z`VA;I9PG_V0I5hoH)a972al^nc(&zwzCJpthfa7t;i>Hv zmF?dtrc@bqkYZ93+$B)uvQOL26BU{-E2Lga%Chl7ql9#N^@Q$Mv7%Cj?w0{*W4v{h zVqbNGy>7g{uE<_pWe3Rh>!=8Htc$FUTH5zlFNZ?<6Gw0hJs#-(++PVzs?b*t7P{(J z0nmq2H$P0d#S1Lace6p&OY8`)4Miz5%Vysl`h|aR<9MOsM$F(>`KR)eRr&V196K^G zBNan-(1P>t;ayvQHsQm4+=|xScoz$c#Ku=h`CIyJdb?62@zSq2lYD-vG+5 z)E1K=xET*^(TB)Bk|3_aVm=d)DvzT_r%Ftf$pTZw(+N|hv(&O&Ou{!n``^P7E?0~# zh%v1rs>I`|SUostyhiLn&ta2J2kJ+-js_Y}2fiAs ziCu4%ly6dkG5QC4w-P0+WBiD^$?5bHl4ZGF7kIGZ4WR?fE$CeAgU|+~z{1zo-PYS~ zl6WX%Oh!%Q{l%T`hjqG7>U4i1tizq|mfwFExySlsBWG1CQ&IGp&OPA}JyAbQkc+n5 zt-mwsBkAFZ(xY2qyoK!{)XybO*#0Q)H~cx_1%~+!f8GNAw}8d)CzCF0`ZgA0t0zUg z-2@eH?Ma$1;J&LZf`6xf0-I|SuD}vMMD6smhmX|~d-ZiD)_@><#Ws=CP^tOxUySuALC@`Y+qpfSUeI*21F9QRE2R@8 zX$Cak1|(@`;(7&fZyPFzTbU7+rO0{)vz-%rIlQF9Zg}4)u&@@e`Zy>zL){&fll3zS zOpX(NYxEBEH6`p4_KsKtQ=oMc1j=P0ZIV;A|16`GF7Cq?kk08{Hd?HcFS_6HU9IIh z*Q|0}ZS$W;W@f734!{A+E?HmRNvO;{Caq#!DV>>I4l`jY8>%_f#i*v zQBF5;^M&N66;Xb|0^B`IRaS&7g>Z1@zfT5rWC-#OeUK5l(?O80yP+K_!1kErI4Gy+ z2dY$PMHZ6(R|3{Tf4iJ*bYyVeHj$ur*^b77G$a-RE&zPxrz7Q$kPvnFUR^v46=c() zLa4wae@OjN9V#f4KizC}Lj}`iW;5i^Ecr8=epI-8b?)aK#vtjcLNP=!LDy0?&l)ll zogi_a18J%ab+4=_<)01~3>WX+j{PNxOLpiM_wwQwV46dgUMcWr!v&zyaGXmnYW>x* zilLV3Pxe1WyEO%7X8-&p zrZT#QFRJBNbdA$6M{OV2xEc1-TCuYS3psr}#@opapt7o<&pm*EMuD&sYFtNdqt4}l z&-?hVtQmXL_*-xDUs}D$dZ#~K)(ei+*r<^K0QJ_A5cvt2sK;6l(M8ya{E$uHbF=@F z>ajP)e1_M?XSrkQc~7)zlV(KySuvFYL}*+wxj!c8?vKiT?-YI-tRQ^(55Sjy+PM7b!k7P^ z^A5t7e_D$0<@fSu=KyWre*lC6Wia5vsO$Vo3Rq)JSS|`UOC^NugmlUG2h3?^J+oXLm z={LasLv9`%V!dn9Z;g1cqoI@XbUw=#5dCjJA4DoOXk5>I$XGGZi-G!-=oCVDQtJZk z6+ni#@SYfKQ*i1-JnsVWj5LJwfb%UBqgMGL&C2w^#8*Ju!2Gka4&o8HH?ny=(&&X*nE2alX~6X?m{szhLCwdCyt$ZCNC+(Qx)0B9r20_PaHuaD z2M~0bRQ}k z+txxY^=7oS;eEKKvVN574&?eAUxI*1(Oj>$)3Z0^vq;keJ2KIFG`*2>F3w{&X1o8o z6w5=QJIAxs>iVnjZ!Y&CwwtSbE?@<69Zw!0mYAxR&)^4AjIOnMr)ouMJcI{Xub^N1 zWF1tCrm5xLaYZv0%w|d^s1UN&iT+g5^eYhhD#USOCs@_AHAth`w~_1dHnW)}1hTi8 z79=tyEo|L}#sxkx``@7|7EL31Dw&qlx*U|?-Zg(CNR5KXzN&DVt5CY?V^%8qp)o5J zTefROb}#=C;uN6IvW}yIiP*iX3PPmBd}5@xZ1(}Cdt%@#vp=zVc^ZLe7U7h5fo89P zcXa@^ebn=C_A=C4lfCdsiGJ2RRXV%4itGd%p!%o9Sbr8eYJX0%E6M<{`7EJJ zKuLZSBg`sOEsEVcl@2{q_#i5=Xa+*g)vNxA*oscX_z-+LHY@B_ymz^77lV0H)gCl>2d?(*sLn?=QDy1Dd^EC`r6^N2{@i_EhI64CbC>&;{esHolu=1Gyn_^0ly?U2APVvc@1Vh` z9hSC`l1+mrqlivtU#coyfS58 zW6zKmDV~tmT}EC~cvhrtRRM=kUWA?iR}5QxUe0(=sD)#Yk4xr5E5?Or5-lZ*FQngQ zZbtp$Brz^pA1MwgXWi1WS^-rva*)jJ(Ucz2k&6z0G zgn{n4StJ z7HCjMI&vEVU-j`P>(ZfJNQa5o!;p8`8)lOnAzzwSx1 zsjV+`t9|(f7fN`I9pDovqgUZvGG5QoJcZqwDeH<|MVQC<3ld{)MQ- z74(VCJvqC|LiH%bW!^Ge=0QGiPxjDL44I<_s^#PqRz*2_`H zg|P@#ISIaV>y4MW@h`8#OMd0gkb)a2E{soc0aA$b;lPplK)Vk%b=bR2$YWEp-Mg@~ z=N7tiX=&euiRu-mq~^Gk6c{KX6h{O4$HOK}b4~D;s!FQvpTPD+S2j3R;7A{iVr)+- zywLbCoc4ifJ&v+^HjoadvB}q+{T)x1q@eSsiBJ^?lWF#{+-%EsD9&eKfvdE-ny~3Y z>lg7quK@9iU<`FV?NfnBSe42K!ol%8+Fd3hYdvEqk&r`Px;K(#r4?revm)6gAiJeJ z_fN+p58|%+Zmg_R*g&jE$aV+SIX2ru(Bv%gZTq91FYPw@WmF1sOhJzGy5yL0 zRyjUsKC50SE#K+o1$2YL zP$$H}B!v+b?aww8%w$d~wd$8(IygIgK57uflKd4z1Cbk=6}$q&L05aF=xQXXFPI#= zRp~Y!Bw09gs~wWZ(!D5&%-tx78m|^gqR@X)NffuzVOys!SpXsfDqnbBN_bv!c%Cgh z&l#R)=ZV-{1$L$)&415->uc?Az>wvYOc zJS&oX9siO2qVTiuAE9W<{9*(0@sLZ{5S`BrUHKdh&2W+&FS^`l`*Q zW%qM`T$AZzL% z_q&eq?`rm&30vU%90fLhKqa$HG2rO83~G}qK0X{ zblv|Ylq1#nImtpyM&=DEfsf4o4@F8?(PME>;fY_ggiGLZ09}cRKX|GICgxQF{AM8qB ztbb&}lME{~j0-3Gsg=FMl3WK6^v~7Y@I?Y98uzD;d$x($g{EM~%EL5q?h;<9`&#vx z2kPR!SDMd#~uIwW}0HJH}4{`zbU1>i>w9}l;D6a#=`%+rYH zi+Ni3fUkruBsx#iBb}O!pr-EWE#15^Ii{b{)qB#32t5huvI{*gm+vJ#wY(pj*c+OC zC8o~|WKWy8RM+2pX(4jOiy^V3RU{%$iNMqONK;M+P7Zgh{0+)u9~GDIjmL>jpzs3n{1$HCSo;6Rtyo{arGLy@$FOzo(Ld&Y@fOlkPyR8>1uhNF9OC?AURjE@aExBp zZ|fg3uGjjV-+TQI3#^&W^&7Y8t1$n?a!Jc?TfYZC?TvnS<83eWyRO^%{fPW`PAvQP z)bI17z18m^-u6YD;CI_FvO5Pj+O7=S{t>z;RCDgd3H%$kjeKyiL_YP26YZJ*?<&A ztGn|)1LO@ko|PZL5tcy>MeBV8>0kxEc|HoC$C;c6E9s#YkJLp>bK7SownZSb8O+at$$Uo`Tx9|{9B)} zM0Be}u+}>$<^J4G&V`RkKW9}kEpBXs)SJ>p)u}(i-VtC$*(InInZ+rwY z6wJV!MFS;NFpI821+(dg6?lm}P{|0|1*Q>D>9byAviEJRI ziVeiuTCUtc&`CXe8>S&Y6vcTdcTwCly3!3orN0uY9_O#rrRp@-imIP4@)C#YA}@Ka zF8wjJ$?1F~$f-?E;hzmh=!3DSL3m*bVtHcvEg<`1G!4E{$+2YWY_EK$C}#^k(GN*P zIZ_KJjcEl=lZRlZdU3Hz7un3AY?7$GA{Q|=hh!vE2nsuRHDP?j{=;}IW6P{?^~7-+ z=J|7Q=9Pjep|YZk4@YLmM))z22NU3-<&&Axw~F$?_n|~Gyx{N6MdaN)>4lYE%HQL1 zRuo=X(GtZJ%5%lb?p&UX`C%k0g@PmSUQh9gFJ%p|gsjpF0iGN-gLZYGX00J}Kj>V= zmF*USlw-bVqvQOcCd2+K*59+I`FNzDtrLZvX+Flzl&8iNx0}XGtiRNEWBsKBG0OO} zA4*b5m#KG2qKo)liQ(3}zei8Cmi`_$A@g2pea!#O{XN1Th?iy^1_L)F+Vk@2 zTeoKw3jGhY=ZZ75CwG3=_Rz6D;ov!Hn=$B0pl~U3|I2rmV5`~i$^gU&uOnouNfLK} zUE6c);GyxcgB>fYk)=SUS^JM(8~rc;eLVr~_2RU1k#O3%8d=j^fq4v*WL&uOndLNP z6ak(k+KWd2`R3@pM^4zlF9iGrNf_jA8s|K8bHgbM+b&?Capus_V(s32XoRTA<|Ali zPjlA}{_HgwQ_rp5fCw00%@oIeeA4cw_JbEB1 zj|SSub|>#ML{2U`R;(4hKnhX|&fmP;`}|=trpI%aMMe;5GTgfPs1AyA1_a;JWpl;^d-#66m2K zvJAVFgoW}W)IKLGd4YLg#*qZLVe1N3Ltfdi=W`34exIZ46+A%@smmJ(tQh9WOZqf$XB(mqG<-D7@$9G))4N&DJFulc z|04LY0M@Hd7{^}?9}Nh+XSQI346rn|p|%&yfgM&6BnK;dN|b%SEF18pDi!N^@|fk* zJIMYTi9*6a-ap=Ot2(z^o3IjlTNd3?sv4*67+3bp?0E z#|2wB5fGJ)En?1rxPkOL<8juVEDmRVVJeOe{zs;dGszI4z4>MV!V#UGbUdReDyHSfaz3bVAz=;Y4F8JsXI&A zX(*yi=@6m*0bwYV^cmt^c8mBy#;LHBu1pUp(0dTx^J$B^O`rh)rm~uP+RVQbTM5{8 z7=d5M0h&WUbit6?6R4-kSiEoru=Ao%;JE>VcZybM-)NRTz}Ud+lJKe+*ICp62oYc6&Q>;83=&U!270~ z5uC=$wN|{4R7>^pN8mVtWLix%3h`<=K0TN4yjhe>$2BBI0|2E9<3Y^BFaf;`90&x( zoql-(ud}KPMi;2qngf%9NY$9*}_@IOfngqBaj5E2u zJs2HdFg5H6@g{CyC5eG`!y$cOwWGT5W2AwVjDhv&MR5bGz{=B*QilLT3_J|1;}}?b z`05`ME{zyi5-ua^--$k?!Fe3EHJ~rPF{uKg4fk?Lk<|^Wrv9N&$vSIJCQM_Uli<^$ zIEgv;^4bf)8k2iujla1iYsABQk@t@?Mpy#9Xg@Ov+be2)^>Z|^O}-SJo4u(p%kB?f zi(MFUPRT$Es-L5AV)84jW;1?WHJk9a3`=qrLZA39C+4lDM{v*}2d7^Ery5@t(25cB z0n)>p=V<(d{X^LOf-k$2r*mc~kz(`0c@ZlGs}sZc`qb9tKRq3*8=`4e*l&}e zoBof|$Hw24{PB8}KWf?w(dej)VVs8{tOg$-xC3QFq-(G?1<5v76~Qg|3wL6&n`~_i zlBup4V_Bc5`IZB;Qf^=!nzBjtuk-TXLfwD|n(~mBKO?R;(L%ow?GH4-Wneu*6zt(6 z{{(|^rJBU@TmMKotarm-Z4-Fwe(D_enl$`%1n(eyph^payDnWknT97~4b3%7uzOf; zHvxIMP_E2F?pQhlUn~8wWdSfVm*PWb=7LM<}-Rwv`$kt5*S_rziE>o6v*V| z%QT%v)xbj(*MdejLHIZDZ}DYt5$fXQIpV{OM8we`f$qPhYy#{Z2&$()OMhpFdJNU7 z%;eV}Kn*%*ZS~h;NKa(SMzUI7BZQqg>H>X)CSr9B<=gNTaB!qHBtKc+k<@5XC#9;T zX?GAtju}R^`59v9mplYYx!(kI^cV;%pa=W3Z7BMlT;A&VPcK9E{xu9_@;`)<&#FH+ zcHf^HWBPL=(Oail|0jstL^Tl_O}v>+^lVhNnE1z!>u-Hmg6kwD&ys}8fVH^A3=$^3 zDd*6j580Br=LV3Yx@rr0eUr~7=N4GiD;p&x*>fa9N^$a2hqESw?gX=|%6e8q+^s6L ztcDn04bCAptQjk==Zb4F8E8}%j0BYRWF!!zH)>7_6UixDx>Bp=q^(l6sPh2R@Q}I~ za^q^X*jAU5-k5U{89nDv{~$PXEnsN+sqloN&Y`ZUm0h#n727pL&ZQ{B%U^iRAXpJK z(O)1?SaQxF@@@oFOpX+J2S+5{jWH7MMo?e$zH-LVJi-{w!wi3l9>z1q)U~TnAQ|gGuMGs(S1wWUgrtvhWkGe&Yr5yBQHLLL| z>vdO69e%~8432tL57ac$y)j-BL)JC8m7j|*w5RC3E0NZK=K1eZPRa&tUM6NqAZ;$e zBzWRV5W8qYcq`GEjYh04uqmx3_g(@XzzT!;*uM_sqU%Hh;bFAl#f#)o2%JQM9E$Op z?TmJlq{7UfJZ6;*4yVV4k!r(l3Vu@%M#huDln3r`ypd0?WI%nZAzpUXtjAy3;7l}_ ziTldT@Tkq4?FWS?TPbpCr^Ik%djoCNL}IO^&b=L&p|XWdFjZX72VIO-D-WQU#u~D6 zMWfe~lmKB3evuDh=esYeZ|o8u_Yl5-Lr#B`Pi1SgMqw=?wF$rYb}Uk{hyqMF1iuV@ zl5_~JXc*SOQJzL* z3@WSx>HGCuYd%O3IA1`@ils>8<^7$ypqF4=eD2VnbQl*O$_p(>C7>Fx&)S1hL;!oL z$9$^C?K4Thlk4}X==$BAaCelX5V>91%g>vQ#zWDy*I1d)#RDxL;Hfc4*bxJI49iv3 z)gYQKLX>Em(kW73O*^ey@QTi?i`lvzz%xU12+~RiRf;zPP$14sp)gU)DNGICVu!L{ zUq8rY^AO@F@w;zB^`>I(+;3(pHXw~_#d?wQG`u#fjuo(AKmb7c8kSN)6Ykt0Hh+#| zVv}R?NdSlgBYZVb?@aC`a~<~q;KtfrtE(S(skAf9QiJ$eSJ;S$x;Q8tB&3HjLmAVai643bE1dU<#*;Lb%@{3;yJd zUsBZ21h>E4_g(NX5N>%X?5w=}IHsL= znGh1>I3^@YW?fT_IL^ML;Bmi2n+uTek(ffDpNanf6UbgDH-k3RySi$>*aBjWfmdMG z4?6Mu%}k>nLR8_`5D!v&l=_pr10`>#qK*8D&kkZvBqdfKOfC^QlMlNcYKN-bVkZOc z9*MLSDgOd@YYXlC(g8XzUu4+qF@^@T?%j!P9BP-#rS zTot}}tSlM$PpZ-ZtT7TWv0W~zS4(W}f|P~V&$qgF-Ia@h8E8z!l)v+}FT&7_*}|Fp z^HZRs^!&UgcF(q5aR>PjOd-f{AfFek`|;|b|9oYF)v^x z2ot{uD?A*w5O-r%R(<&VE7T=LSGbTiyWjGW)*!Q?$o1vB9-)PQF&OhQZypKai$A zcne)jk&+zR^e-RE;HIZ;$?sO>S$*7r%m=@)b zz@}pv(B)%nF<%Yr4Z8~GFy$d;tz)|^%6?VZsVNw(d)AXQV;2yepVpw^bd3o(aRps> zkf?o<)U-u5P1)wTV0%RVPPzI#-~}B7UeI*&)i)7dP<=vR zdqVBOIJ_W-`Y9S1fV1Xev^?t|qGy*Mp_nP-XRFE!jwb<>;B-9cZ?OPZp@WUDfJzjT zr@MK%;@a+kE_CVn05ouIFWkpHTJm_ywHAN7jBvJ>mig_u2*WH6wR!g9_ag(X9tE0lYx!I2$R#Gw^CDzL01 z+3H7#!bGy*J}h?P@g~ULO$hcwuP8=Ehda}k3AbSQ)~#7}cJw3RyU7f|E%s~LsRUnN z)R%34@WdC0JU^7}2p(M22gGT!o&b%+(-Ut)R}4O3J6zix!Dm7H@H5nSLjaegKv#tQ zyFnU4Mf6yOZy@kX!cURJ9u^AV@KYpqw{-=EU1=r!238y%H0MYn4xd( zKm)06z;nTbrStv3LKA?{t^ zo2s(?@w5pLA$o#Dtxna9hB2Bdl~x5)w6C;P+Y%@(pcEO!OfQ$2snGJ!f`w4punF`! zIHPmb>vixBGcp%Ok)oqcA4m&wu{_kGs2!}%sjXT;d29aPwf8y6IZ1%d{C~gS<)h6x z`|PvVUXQ)@+H3E#mM*Dh^r!4Te9As+7dO@75C76e@k#uX=WgdJw38&-(b+RfW*Rva zyDA#(4*Lo5UDo;g=faX%A5rSd`kNsFswLy8(3vqfPvKdF029np6Yw~&+!xv?R5=%6 z8|1$jz*)qp>>_1dZgAzzed_p|q^*Lsx9}HfjH&{qPUM4UQxdTqGom$6lpH9vODpn7 zk*wsaw~m0v2Cu#ROEL^7kEEQyDyziu&{*w+)`Sol6o0KX)QPBaL)>Mis>`S|)pkmB z$=znW26>UOQc*n22+_fvy}?o^WfdmB8c+LN?UJ^7ZV)-bJx=^m&Spvwj(2&f`_Hcf zrc{?e-TcRz5bqzA>hRqL)QQE5Zi)_)*Y<7~Y+R2?Uw8`&na4!l+;Rs3g?joC|ILVB ztUo9ZI{tX9qwovWiq)*czZd&gB&c8rCaqD3ImyZm$Uj^EBzisX0(a?vR39Xwd6H-e zzML+LoD{ga$cnIg)%^&-3gr{1v><_1wcT1aZ)Kv5!AMUepIRDRbV@wI({;kA9C$7?lHEE&#Am$D$J?m z$2v$qtnl~OKtFt<)emGXhxNlEoqnKY4jiR22m)7GV9Dz~X_TkCcH0TOf~Chg8bD%r zb|{<(c$x#AEjv8h3~~+D2Y32!lp-tSwz(JbYlIJA4uqXgC=6G5xr$%k|ncpy%S9?#9n$o^d{rqN3j#q zCWLf?i`}@0T}xd$TvgJK8FR{B%OLcJX;4;Zo?#NO0aY+F$ zu5c}$oiA-V&B~MgZOIf5qW!7yrRIgV%^Nb_W1XKGe3%wwY0X%WO~rC-&X*)BScoC@ zZZg(lA%qWvkXTD-Ay#ecGX~0&Svgh}vUM@6rMGE5@>pe~a$`oHe~tIB zB`3YPn-O{m)A&zDoWMK?lhec&U_hGj0R5v0{Uj!I+>JOPe|r>S_daBvzKnhc zpD=rN<=~_=I*|$GQL(h1Ti$krxUwPL+M1t{T6l;5`O*~?lr()d`%0yYgp8f5dMM(BBFnm{a3gP26X$c;$XwBH`V=D_!4L;;9IZ@ z>1@L_X0ZhepRc-IN?Y(0$JG!J8~U{O$PLQK_Gz&x&dz>530j#6ZiC?6Rql=|+Mb4c z8N&YM1>if53&2&eoTl`sy>;O&)#?E94;FyC%lc_FV%Gdq1odV85c}|`=gu45z~>Vu zd#0J-Ab;(lKzX+!B=Wl$ef|mC2c}!CuWrU))+yy&NEb>RGb^jKx^HPlfmC-RHsSnV zndV)>*WZaqND3p-gg`7Pod31|hci{_s}gTdsJ_ns!}nF!ugXriJu9L53jYs3R3)#< zPP{!UvHC*)51}e)Rkrc=EMwI$9>N#9ApC$EF|}e0x9aGH8(!@;KCP zI!$|@botp|_$6%8tXWFYSSp%|g#pic7`S^j-Q0uJq!q8x&?Z#`*J##Ueqjk@RU*s~ z))9G?SVFLw6`8J?vvaU0kT$g)KP)x296vasW0G9-hAJPStuzzMx1oR)^@t`t{ed-| zD8)t&pQi)Q@;Mu=&a8CJoSVb6O(pWCpq_d{Tf3>L{@2lzr-%0bo;`$uz)C7suyF_k zfh*z>K~Sb(z|qV-P$pmgEmX@?7|W&rcdugG5Ruy19=>S~EK6mUHMbzJj9W73%Njl- zx45!R#%v22V#QUHys{r(Sf_p1NF-QElZ9*LM*O8ck}k>5a5={-Z~O~-C^jd_lS*d} zX3SAen=0SAgtsIucm+F?cKVUap#1`Q4s@|S&k1P_?Z`vMki1NK*q)aw;b%u)DqNw# z;sQQ_-cs~^NI9!O<4bJm2hyL+>AeqcE95MZ-$aK9Z}0KJxdoQ@(r3kk-J>BMf&vY89)lGq+*4yg|Bic4c?tRDfALG z0NyV891MkAW71n@5>;7Nr7LUhvX%zCp9yYVf^Thco=^U0n~?hf%D&dVjNH)l5A&x# zcshjmi%6hOd-+e`4rdg}fmTP)xxVtthANuWsz%_CRCfvw`Ya%bzn0ob>>D1w#*P<` zK_d6TX4P?Wmd*YCzBQ`X1mV?kVGpbO`~8~z;Qro+h>Q9ujXRq$t8IcCHTVL_C=V6; zqr>XNMs9D}^3jJdxF8b=^4>Rq(?GB;1LYM@Vgt!5Uv*5G(vaC_d2M&7!pn(fBzu3 z6FJw0iXd?)5OuU|FPIp6w2hzdVs|AYar9(UXdhaRGXdsNuzJk|m=c}<`xEg*bF@t- zBx3rDOpaOsQl>`b`-PJ%F9|v^u$)iFs{2Fn;LwS?iKep1p{6{3;_e-J6ZR7E7M3_- zUcMTK6)j?7oxs#8GUsF}Olluifdf+53j>GXsV9|YkO$V|tj@wz8Vm>{k53J8 z1c&sgi9dbmf55WAd~kR$?F{m+Rq=Q87m1%5{!>rtMqI59Up0oWXn{xn+PTw5Ts_T8 zsO-7$)%x(&2IVT)M3alIzske`pHO@K>v+f|Zf!HJcGPdjU$odkKlrz!emDKJ*V9}} z|Jv(mo~3{7^)xHfzxMiW`oX{U`a|LZS917@lMr`1>Q7Kvdp#*-adk#q7>pDm*s_hv z+v`b?=%2e|M?LwJ4Q0~A7E-NWV5Y-S<pYqH6vYRe9@Jo^b`56w2NCmGZ*fNQ&-GUqKH)1h#_!Bt9>5z+;+w19N z`iEY&bJEjIdp$Kn{{&{D=?%C)XVa6_rh8wark|q*@Q*i5RHJ|G_0$agWA!w+MAI~+ z&e`;FdZ86o!5ZE)y-ELg(@%LWKgLJ3Xqv|IIh&@Jc++XT=>}>5|9I1@#Wk8% zRRYVeLc92&uZ9{uTMFcRc!P)k3^E9gHyXS~k4q-FsW z?H!D?=kHI&m{eRT5hn_*rLd+vz-Fq6cl>UHRM$aVFE$5DaE7}Q-br#z9-==z^k+Nr zCs7t8schw!Gtn-)Cc~SM0ZjD(tQjW1}dS$39ZVFlEKJ3y@QUdzH; zk-w_6f4tW`KZS3~xz!1BX?WjA3E!1|g zg(^yqACxxj!M7nT)nm!y`!cn|Ouw#OG}?gAMp!r9w!3oXhSHaz7}y~Rhga@Tq-}eA z(1Ooa4rKK{Ow%k|Gbq z&d^khz`#lD2+~WitMS1x7D%qQ5!mY_1&D;-Zsixibs5^EIAgaFFZXVvo4sGSTHPHB zhpSPs*Z^`@yCMm&E@e^QY9Ax+(YM-v*~m3tyl+Uc`Yu;ty^Z>jG|T#67sp=2q$@)F zNGqN}MQw>gNf zOE8@llm^O+i)^)Tpcans*o`}|B6i88v_9f5LQK?vWq5J2sJ&Kg^JOJ=8GViX{cTu` zm0qBHRgYL`*W;Rk%)DAieP3ktwP#xJf!PZ@V~^0!2BxvM*9n}IxhU07I5{R+< z2ucuoi|LIyz5#B*mjyJ`q|(l#>W7hvjQ#J$Z~f#Coatwchx=FY{Jim7cOBt^ zfm7g0bkSE)Km#KZ5BK-H%0Cjnbvp+>i1@AVAliz2-LP;BhX1vAV~rcaC@*^+^NNAe?Ep_#|0_AqTaBli;7SFZxH6og2-yCdA zF6`IQcN+vOT7J*A7!dJT-{p;izDEOBV=BN5V&g%w_&mdd8D8c3uH|zhB4C!t7XVs3 z`VOd*2x3eOnR6QPFK>>eFVfFbya{BHGrtKQVAusGC#*_n$PNXw5(2|04r0Ib<`l;W zX=|=yc*|k)h)(pzj0@V&+e`a-N*S^X2CUN~UwR3Jj+p22wZKMw5PH}okBYiCYVOr| z9+~Hf=Wz{>=kcfYSTu1j53QMmqepR^Af8ZLYAnA0So=liZ2!Ud?aQ>t5lgjOEB zeG8}g1AKYh*J}Rhi};pXnfw`|h@w^`Oo}oaitho-)b9abBl)JhM#7C(K$*qWRYjQz z2hrqAF-(Nh2f(;Nu;=H2>7xt6aU{$H%!cO4RcVhO(Jd>v;T$nymm|C_v6aK235K)Dis{M(bT2aE_uZjUWkYMYZJ z74230*_(^)@nFv96`t$N;R zSkN@!Es=Z3U!HHub0KatTzp2j_z%?%lK!hZk2P=<`Gzv4B(e0o`W>;P?7stQcy_#P0-7`qF*i*FY_r1FGtN< z?)_3-9bTkhAEAZG@|_8^n(3#@bbi@Gm)GMG`+bmX;*3iSKQyut=Bx+KkOaPk+T+zPG{$BH!%+eifA{<2S*&6{uU$fP4C;?XimI z=&A#Myz+k^gI_d|u0=@G7--Ndb zacB4}!64hiy>$SvJQBTCkCoC{QDv>F94oyx3?c9!^rD{7s5kY)7h{)(Ee&6`mSk3p z>lQ@ILB@@_?yjogoDRJ+(Nu6!$hbe4UpXF|!*J~4bZG}mfMyDM4tYZhlI6zl5xk_{ z!e<>bc8YOou3K783T>g8QfMs4mE6~=veZOEbLb5c@osNfMQRcRx{2Nn*4Z@TlS$>( zaz!D2@x9!8Drd8QN@BD-d_R`ozaGAyw;#KYbp!;5!ZPGhPkb2aeGaE{==&8K!#HaG z$(bK;)I5CKiCgT&_?L7;fqeo!#FsJ9Df>y8dHT!5){c5eUZ6@yE?kPQwFc%dQum0e z?~_e>G{1Wt;?*xO38RNrA+|VWiSNn6-Tv2Egw}WOij92Ue?B@&)}jC1)RBZ>Y3Jk; zr87{~_*R^64&r<*tM5mfY5Qm%s2{*3juEr^Z~4WxKV4y6Vemp1#k27 zw*26Io_k>hZ5LN}Eq$E)tEC5&+SMIK8ywWE-i)3}n_3Bg3$51hYb8G4WRS4gh zN!-d8_d?n@w_bQ0+!~91%BTOTHa&$@dOwZ_su*|5zgSTP>Ztzji_F&y? z(&$~H0}9Mfab%aKs}A`t4s(C_KF~=Tye)j+yNB*y7WX*YsA}+$=#zR_xA$2yi$FW0GkAuxP4 zsr$D`U-~YoNJ4uwNS`e|t#%Qr_TN9&samde={(_?({!HD1ft@6{&Vh!yh1ueQ_h5Eqen5pa@LDV7iUH1M3V1 z3ib)00z=sCfdZK-uRB4y12?;IQ;!=~y&L!b9cE+ocEorFz?!SrFd$z+*ORC{bEp$$ z$K}huqLRK3ki-^w1*u9I9^)$<{~K03z?qwVoRO=(7@y(WFsgb2Q@Tt!z0*mkaiH@e z+Gsbr+HwL@T2An%EoXY^$kDdW7ihl$`v~YfWDG@6g*Y61hzf8npR7E+xgMmBz%Sv8<#(b`r}<4rC`IksVIyZn^XO5W=@138H_y6BoG-v*i2$ z7ljVoPU`}sT($#O2aifK+wlK>{Qov$whhJqWhVS7HqS(U%8}d?mK%0^V14HA8SwWP z&}s#c%BI3Yw`MKr(IrWU`iAYJA&p})d3dxU8$3}d*hd0p;q!M1I2VQ&$Bj1BKxUA@ z3jb$Jpqu%Z`OvFzQd5f$Wfp0SrOxp280&)MNk~$01wS%_G4`Xz4?}?CV+J3ZvA|h# zJ8w!faj_57yIpG95q|qJdOKNt`=hnW+o^cbs(F#a&QM@m!*5?sZ(pUp{U3PS$IR3{ ztJDPO)C17e#ybkAxHgIFn>s1(-6OZ5Md>C{#tVKz4Irhh=1gw|)96|>ih?||C>d#S$ltF)gHjV{lm7$ih>j7e zocYtQJapm)D|kD_F%C}!eUC~rcA;nn>fGBRP04lS`lNfCr7>L#B#6W=bm1p>Y;p9B zPr+*wLqf1TlRL=>QD= z<_oc%X9d&j?pA5dH5iX*C6#aarTgDP6raShse!pjhysaG*0 zRAj*Wlzq)6HI+gN@O?qk8?|U%YN{pI1D+B@qJ-@gl3!Fw1(z=Az&9SK(=6&ZQ3nA( ztjTJfOw_rulh=8M)~|RL=J1fsD8~yV3l8-KFX$)QFa-$?-XF3J^(LVb`VW$2plEa# ziojx$m=yKZX?SpBH-9h^Rq@F3gwn)?&Ab@;f{N4m8xXG+U@;4C-O?i-XNabp9Vo99 z5;T1RwJ0_H={eqe^o?3DDJ@JNB04e+I%dXhwD>>xe-HkDN9mmD4HXF@0v>P~e?~1N z>ZvvVq!x<4>PG{o0ce$?*5>1ph(kma?b1lu&tNzZpJ}jU{Xi^}nliry`-nBTu5?IE z1tzJbkR;Ei$Pm)7HYTB@#KN9>U+N&I`%mq-+Q533NtDJ&Dg(qQtRL(%5 z!ViVy06!arQRHr_tbzn>0YIgjkRX-pJcc2PNwER* ztEaO}NSdhwe6@>POppAQbPS$m(k-}W9 zv{yl8G*rS;g>uqe8S2oQpy($%Bm+66=#i?DCXh-(0Zt2mU&rZ@s%j=E!$l2uGpC{P3|%r>f| zu+5tBe^}6~LEK&D7`rkzD*(&`{H$ec2Q*cPVkXE0Jyz zm7Ae-Gc<=1t-5EB@>+luolsty(3E`5f$bEWNh@@i#*+=Z2D@04(U0WCj;;P65}iFC(^RA#qwjqZN3U;|#e5}K_zt6Y-Q>m$K1X>b;-0Ta$9J|1B#l*7JkA(;M?!*RNglEt?5O=EBKzPJXK{f#;Xypqn}9eSC%G>Uh} z)f&~8B;eq$aX5#Q4GqB5Vb(@X&o9xV@A`(d0d0Z)IdH#30D{tt0tEs#6Xs;ZqE{(d zn2-R-25Z)hu_LWs3SWcZqeYp7{QWc$IHK&?WU^;JhmDHXQn)>vs0^YQ@Va<|FPxz@5)DY?y`lzvCXTXLPMyRSsh7fTC zB36?+VGR-86*bifYY34+t*OpPLx_f=O)^!T%Y-GvS4G@Z1+TcNN}R!U#8gF3wKnQD zVWU2|9!S7cCCd>tbQbC*)K#cgL2x|Po2r5m5mS|{(rCg~R-sU#s-keErp+rjOw}w+ zK~J3#(#FaQbf#`Oqnf9JJ}^(gW5ql@yAVXoQ>v{uPX*ti*B}44c{lelKJ_PIU?yXT z+o8t$EYNY&Xwd;1bOwGCv&kqun@!3`FKp5jY4x39o7Aq_r2hV-(zGvOx|+w&MeA$s zFu_lUc>|6auD|gGEHknaE1M5FvGl@}li8zob{|x#?F$&9U%?Rl8cMzox|OeLNmrn= zsq9};g%z4Lj#L!cfT%*sCpC`QnMz_ovcfV86caLRPSCT_M17X&Ri1^d3VL=WNg&Id zraTK97l1QMDGS>cD660{A}5VXK4NGP;3i^@((pl{J&t*yh*LasR2iNy3^Z1QGLU(p zI=Uw)qQnc;(XHqVVdAQzdxB6kaji~8J8^qiYYa@kM08}vX&RLmQim}X$SPIULX>rR z!IH3bDXau;U8XXOcwt=%rv1a#C5Zv}F04xsew=DelGed}Ccg)@!qy}T!F^#4M%d5U zE(#-j=lm9hQ4AM_Q5;8MG|R!=D3<>}XE*2on^p*Z*g_@YP%YFbIS`@_#ZJbj!e+tY z2zRkM(Ho6nIT?h}_`@R+QGgP_2qvSk7hk@U(I}JA*qf-_kkQyX)I+OYH`cDw>b=}( zyszB9JxSFrwBEIlI!UVgP+D_48H+H@;dUd@0R2ZdJ2I`b^mUX?4OS)wm*5OIMFog_ zpCUEokt0$tUb^WZcY?Z5nut;{e3cv_k6a=(p-=fR^zdW4iS6k91D`_R^qh7GwG%*M z#b+trpAO%(;^IV=1E3)s*&~yQC3}@AHOq_}cue8(1o>$Gn0c28+`&{t)`a{&i@6&U zwh8$dfzn8mgA*iuS9)jx=DUQJmdHaa*$?+`HG$)!X(@Za7(tE{e3WE zPil=ge}6jBGq*I9CeIpz^Aq#U2f-*HQbm7>`;zkq*@H(Qbs@Gq@EE;?r`4JEB`Qq8 zgzs!6r~478dOYBLKolRU{wnQCl({-!zGuLUH$j;@q^VzOzJEsx7`&469Y8@lxUC`E z3xyf(FQlNKSUf72J|5ySb~plokr~=lIMxC{VjY9nNXVRxh3Ht2)@lpVB3c^rp48OA zMWd-1r5Ri)O8Fg9(_RE<0Tio=ull7i?Yy)FC5lLl`DnoeylH3qr7=e$tw_#qMNMgp z(CbouCzcY_l42#%uEh*QUq?%u-WMqSQ2s4Fswj=_n@I z5wyf}>Y(5WXzG;4?3bGM051%J3u`b`IZ0bNf>P7Iqf$An*t6j&TsYDgtWhB&DGQ3w z#q=<)*k(zU#=w;o#<%I1$C8P^Oeu@hmtPSt8s5cF7TkZJ268mx6rKbEdxK<>*iS}%!1G(^q5;8DN$Hv?=5F;%2 z)3M7mty3EFuC$Wuc@hVr%oV62Xd*Qk@f!T>s($5Np1vKgfi(JdP%v{BP(;TeS^_$u z@Jf|RJZf7w$w@Qw9;(Pw#nrlsR|(w-DpAk1^=6}9m?r3jnB}1<6A@F6WLnWp#0_siP#zuq&jv63=dtkib@1M6;C)&j4R7}?I(SKgh1U}Y-UDHH z7ZZN?LKY}i#(YE_aOd?d*@O3kavPtlvPk}Plrp-lW` z`SBe3z#bA7F>X;M4m}8zJX_GiR2mjpuY7oiN)J`Oj@Cu<`%s#W7*50jiV*)C@DAVu z7Ra*>-n)$#K(;=JqOJ)Nq9 zN70K01#e3ncw@uxH1d@h1M+%3$Z8$PIP%Q#bNnn8zt&b2KMlN2gtgbB`05xPibHhp zggl?r%ClXOXM|tYh4EZsM#=(w?jbiIBsP*Ts7XKCJqIcw;&RKv4{#dy0JJ8}&fW^k zkKh%1N51=~B-01vY(x{%2s6&h@FXpE3d64$1E4(DpY*0Y_PNuPUFrP#lh;=0W1Sop zVPqt0QRx%rKR)Bo6X)rhbi|QgIY0k7ymb$8e(2zhje(aF1207nZ_!}kyMLDYrf|NO|M61gR%T*<-tU48hyHdNi@9IT{?K?!NNNb2j1i`JdM1~iUE0- z9^?}*X;F+LZydke2V(I%4C58nI`GrL8>op!@!${VW|}Dc5K8vb=o!Anie3dy1fk&OX}*OIOfCm9I}9jV8wK z>vhCPLSUmvXK)pV{v6)+S)Belcn`$Dn;!#jh92Gqd=xb(cvYAcqV2OIFkWN$ZHNKc z>(rrmiw@-3@awrh7T)rB@ERY9Ch1~5ytg)KQ55pEQY&BQ)n^4K?X%znfOwWvdho1i%wakbwZya9FeX;yl9s}=J3!>rG z=;3uBl2L^D=YY2kb40X!UmS*~kvDq`$P4r!OLZXQ$Q#Gc6bHZOx2p8iz}s9Mjp9?+ z>PSjoRYgz~@;2}f$y)^iM#otn{O7;wgJehyO9~u8o0b(ZicISa=T164CPZ zJS=a4pO*jgqfvb7$2t^0+n_};j=XXF)=i6rH#Q!;%oupr>)}=F;0bxVa*bwv5Z_)i z9yzDIHUlD}+G`z?b@tl9Z_a10(aZ9_F@v<%cF~|1z2wuV1MnhWUl_^P9ulG9{M&lVjjL7z3|R5AVtK zgM>F5vp}>wABLqJ!|#D#M5A~xS%>0i9mqKH#qm2(5({r$Jb1M+@cu;)@0H(aQ55p^ z;Q8e%hayv+eZ5(wkuP(xPQEVZF)d?u(!{jH*PHaRe6eeg^2KZS#G%InFs}9THUH<) z#Gmma9q~6HD$x1nM-FcabaFJmkHFH^!!yRf>%T$=Z`@$vnd0ELJPc2xzZ&O8qqtZP z@~!{Wq8LZMIDS==V)45;9z1&tybJX3N_Fsre62jce0_?HQRk4aT8(^dxJM^nuhN_6 z)L-ej~w2&6JzQBI1fXr^_Tr_ zPBgsLdU##`F-UmpF$YA;^EF|38u?0%0eQI|;i_fdSIJ|X5vHTtz11~2AUWy*xqQSz;#T*bVU#+m5WBA?qvuG4w zy+nuN5FN-k^2PDnQWy(way)pmV&L7Shxf$OT9OL++I@ccx|WjEoPB;=r;#r?PbXg| zKRcg%(aZ9YYX>P`y!Q4u^vH&>u9vS8Uo`PEY&zmM{JWMI@%0ynmkymA&F_7%WcBbq zeJC2 zn%{>;>WJZdN=y9s^2OmDD2S#1ycl@?7- zdUPP;$QQ@&+x%E~kHb=rk+0_-h$d-35AWUIXi*gMb@AHs`X?Slx~FsKuMHaca%St~ zYdpPqPWhsj<*`=}QoeX?QyhLThw-eJuV4K%niw^bj`$tF))FJWd~tYH(8GMRFEa+-^?G>K zI(S09ZaKev89!0w%Z~GFB3ZU_cCC9@#P_xPPF1$3n*7nn=a4P1bNArR7ZC)n-29(s zKVLNE*4Xn!9aF-GGnDg12AK2UP}KRN3-3SY`62=?rwjUPn)J#q!E)BibKA^lW^c6U zn0?|`T4u+WXAWR%FG(OAN!)&i^qWPnvZodUPP;$TP?9Tj)K=vkt$F1PZ0xqu;^w%_r^Pi$M z&3UD3(UN|D*D_4U>}hMX#E&n}9G>Y8&Tk#O=V1)%$Ir{tqTxL~R0mHE4ies$IPk`X z;c4VKGX~`KdXUvRka6Uhj=j&#phKTyga0)M))_hiwlI zMcKDEPC2LkB;fKCLI31PlU{k>I+fqy^M57L%-)@#V|G$NOZ@oylf&CSPUsgcya!_7 z&5waMLl195!yw^RjgN(Q1eR)yJR4#__8N33-l78;N1i!;J{WSjmC&fXSLNG?mh|>P{|~3M-_wm-sbvQ6kHdcsujdxde;vH#G4Oun zjfPjFhu2XzNOT7suOsPa zE3_yI`My~z-vyfU`jIspd|kn!jff-bmAer9)LStCHY5Fq@-=Ag7?S3V?VgPW68h3T zIw@AZ1+k%T8e4$mneS&)Q}SWUApKpuwoTBZu`H~Tk%k?Xyk5S3R~$`@)n|0X=<;ic z5nsMIycKDj-#U2L#K237ftRd@S20+4>6r1L&vfu!g0URK@8+Ut6#sBqhvIk3wJ64s zFOJ`OXrpL&+410cW8jU~!>iN56Y@3lACj*{BS^js$y)j9NzuvIcL+$Y(UOXMZ7GZ| zU(}Sm9KqrSbsmS;-V%o%V_{kA~U@Je;?ggpPZR-SEf?9FcZ(;Xz4SU+{oAbF-dFMRzZ zQ%rwaOIg&lR5w1=gaTA&>fhpvj$l!@@}m4AZ|5wh%?2yq)V^1444hrQ9aqK5_dw)h zPQ~8rgzX(G-yh|jQ@#nfY!dv?H0hO>i`F#q{VTMjm+zWyb@JBnsFwNh<(tE+a&i9a z;9VR8@7fr67CpRagN5h7{0Di{!FwLYag6@l?1@J4siQg+KYK)rVjTJA_^pE;jD|Nh z9=yyLc-QOURqNmh`QEFQ@A&%Kh}2T&*k844B)Y?)>TC-2ARlZyhtB5qCcP~0!zyf0 z_5iQFUeH5-{u`FNUZ17qMiW2zh>rLbi?zg$FJByB(U ziA95iw>=KL>@Yly{`AIx9Ippirvn*BzBqpA&RG2R!8neQ=kDxi6n75jP`pG3FW!92 zRyZtRb{UT~L-Ay+>>KR9tT?;2T5x$pTV0;ktjxEFjxrg&5up)~G85xN!yiS3T?iyl zKM4SV3tqWe`$}AUA%6d|&(Xj4kTOYKz3ck-QkK4dn)QRyzn{ZA*Y)o)?JK({A>k?l zfth4KQZ6Cbkp<~u$v>AEKrWkXQy|aGvdw`!3(H1wNh`}nqDdRewgvK%Sawn%FPUX0 z2lDJJ+aAbsuxv*l&&jf#fxHx!of61PW!b5LymXeG9>^QVvd0DTGFWy-ATJY%T&Ig1 zq(VQO(CP=<+46NB43r}cm3iBXfBfSO?Fc}OJ(wKCu%jO{{UA@P>(b+2w46$0tu6A^ z##XQVa}*<|kDIwEH_xrgoEY$!DcjJJ9^`l1f$#?IfvQW(;M#uY)(@bAkPIXV&-^=* z`aTalYC=e+h(U;eOIXmN>y)K^)^**`nR5*C^6K!YBQAlYBI&L^<8EDZ_0X}+Gx73- zKmPHL!xug>HJFjv@^|C1kim+SS+@rBul4T?x!a|@7O(tp3fR`+M*{1eRb|1fYyI8b zfr2xEp~RM<#&+;!a{^CjUl*!Mo+@XfdSEE3$2?DKj`NcI!u8!Dxoumx+t5tnpWuh{ z-!%R&t$$#u#zF8+pn5Z?#g0X>W}=IE5Q(2fTPa%MPx*_XJ+r~WoJSv?(_?i zP}r#OKOPL*$`00jSxq5flh{4h^7{hjwB}YT1>xTf4bc~o z0KNKhmSYVhq&44%vP@{GB@+n!Tr^aQ#wR0$q*q=K01W9ft#w~kJxu6K4ccxB7ALrO z&6ieXg;Ht_30cUr`Yj=P4`@wT6UHjSS1S2#Rt*K-4X8_KCuZ|2;DccC=maugC$P70 zQ&4^%`teL1+JSjNQrV9A5DiZK~ zOMAYM>=l^^U^dZ4+C)yufS21%h6T=`U9fdSebQZV5DAt z2J?PW_SxUp_5WTc@qzdM+dHZMa(PLFAIW9%mAryBkGCdYXG4T3{(f~46!1hP=Y`hk zVb4%-@RC4vHx#&ha59)wM`FzfU@mLVb5J1^l%yyqcZXDutpx-7MA~$awe6L$(!%45HIJ+4v1ee}>Ch)Xgce*; zk$NR1&@;%-To%?&hThqzl(zFVgrhVZKP)x296vasW0HKsb)@oaLBGMC0I~TIZdtJj z;*2>~zL9!%;^l-O_Q~Gy${)iOgK%bac@&qd12B;&dPOaoRPt%(C8zE4Z?ghag0%H* zDR*z}q6-bHKBz8aUUTguNW6U&8(zB@zavF_?*z7&bx@tEZv&+ReWQ`Jm_NQ;wCBz; zS6_tG-GF}=e^B)$vKcFV_+_LI)hihw?|hBuszI*kC%{Ie<;`=*pWw@6^f`g71gu(N zC1BN>m%8G^s!Qi2$XQUukRJbu#Oh(nyb(1C+{bvP-Z#dHJdqeh$~2H6r(YT-G%^)_ z^K(^gaQU>gb4ie28%_EmNq&j{I^;j%*T3CD<7|spj5B1#(~qyH@dnL`Y}Uq**M!kU z5!sX3{1kt`mF*5b5<-#Fc!K3P=^~I2m}Ck(Yz{28u(#zN&;`bWe(+&n^H!khsEGq~ zgH(NpyvnbTuMc4=DPbS7uOMTe{2yqfHCa_1TrK>w{W*XD!T-Pevlfj+^+)K}X6;b6 z$Ft{PbyoNLmsm(1J$6={L|RLyCb^-NY+y@M$1h1{#VJxTemvIkMM7WYZ{3}`vRqw zaK6Q22df%sHSVhWaM1;`^q-rVORJEZrl=e2WmS^Zcrw!G zj<|j9IDSytvOzoKq`3;G9v z>!$v#17UMO&ov9sxe9|F(s1vOk*k`nSl1lPQRUro!_P>~SRt&h8bD`OI>1i5kmA&m z*1Y%B(HGN>Df89X=0K^rZr{>t*eQTRf`!UFw#$EbSWB-_+G@I7da<*?bh-O@&EZu> z#}8?t2IHF{oEe8iS7SMYv^*3!y*4AsP=%1&I}lmf-LiBTLt0)lLtyN7cgqsQwkF=P zQ^BkR)-i!PS+l3YU`RB`>oNJT0e(HlP=LM4y^4;0~}yZLatCo&s(or6$uv zA2a3Qm5Hz@YrbaaUn{#OsYNz7crIutMJGLof1UsmG zlU(yBWJbmm$IvPtL?o37)X^Ny~nV$X2q%Fi%9E2-zG!t28z}}6GH_DJgXtj zLJMyQdNu}%8ioE{FW(OL5LdoWd*x!fF4{=S7qsNc_c^Y78%gj{$)M+HzvnrjaUX(@iX+NA&q;OgCMn9G=t>N$6M-eqag8v? zpe~T*st56)dNb65k6k2feOKDrLfVm3Bg;!f8hHN>ldt7(W+a05jp)F*m6~>LqXCOW zw+{xXzZwn@pL_4ZWY+5H2-?Q^TN0|QuJ=|AZ7_|^^Y@bcS8o<$yCa!25=J>2;A6W{ zJ_gkW&}q#yumhfrX&=^oSamr>>uro||KEnamH=+;KfJ;=4iu}xXiUz_M75k{r}+Ti z$I90S3qpaSrzg<;5_`~Qc$EOSb_FxW?(KzM>plA7sGYu}FR~@iv7)D0>1Im5<$0PV z`de}6YoqjL(I#LQDB3J-E&A^ZiZ-`Av>CYW#udX2$9qHv9=nSyONUnsz>e>2fZ@!F zo`l@6yKJtOy(herLe-lm%O`K=oCxyx(*N+liJ!!P?{}yGMxWC?b!H*$bgTrFY(RtjkbF0rx}tjtR{SKkQ* zByGwu*EKIqXZM(t^|{n^K|w>&#+F`lL(!jn5LsVfxW6?K6_C9)a1Y!Cj~xPF^bvH< z^EYFpZ*ZeWt7(EG%suNcAFrqRcoNOWzgO_sKpkH4WTVo5TAz`=-N^DCMlgN@E3iUb z)Cu_{qY1eM7-@|Nl+uI@aiJM`3@aicOPjLH!DK^8=wTDMEx&#*#*JqKS?#5pjr-Bh zglQ)9tIvpgpp!?s85(C{a?J`&Umv30gR5W#cv#+mgx6&Oqia$U8jyc?d4gf8{0#nr z>*Pn!`}=rU)4RwYhlP8xp<*+Hkvva(|66rckmqUXPx+D~bhA7K4NX@U5xCFQ-s{#Q zH{c1aN3P+&4*3fF^7V*3IybUzPA`)`gUv}Di}*2ApMYllobCx8rqb z(`kRdnYF_M>yv(gYy_V-ACab+-pWK)?<2_1V7Tx`{Eqa?+Y#qFRSy+;nkj@?`Kox&oAR{!(h&Aulxb7 zfdXGZ+vK_Uc$t|4#mTGyf9?Y~LWhZEmTE_lq+d|7x9OG>`9G(Ku!^X)7r8O6>( z0{^R7TaqqO*K+*D+(E7<*W$&f_1ixKzW|oPKLuaHi&60X{WZc|p?vm>{I5GmQVpeS zqvL7(!l7wJ!Xan%70?U;4-ATOIJOqSm-q+nS*k&6Y@K5rs*ayz$36?mvs5_API*r7 zfYj>vNsbZ}IoQ*@9>9#l(@bQgv0`Pv*vgIvYLL?C18MEMG~sM?&{CssgrYwIE}7kx zM4L)pd7_M29|gF}^`casNd@q_xl^ST3-LDQn>T5>sOmi!DA0TDbs?SJLn-OKcS!9? zb+k_jE@t5W+|X9OB>jyCBeXN^L$;Dk9%u-3*5PWCR@_RrG8{mkp^tP?w;CmI7ubN7 z)7TnJwgxSuKs6Y;(i)m;Ty1!g!Un?YJCDKt7NvZpoFe=$a#7fUl%2J(lcNoW+Q*hr z7R}mae+wZ^C+7Rw$EvTvD&R60`)Kb+&C7OD+3_w+DI;3?uG@wiL!X^}Gh%?XjIPD2 z#vL%?Cs6UcA&jm;p_G=d%_B~*cU(wY19Ce63@I~PWNX7PtS)48euF8kVMGodIbq97 zb)_`dY(`^*8#@t9PYhZvRq-OOs`wx^o+0=cvNJcs4-Iqhtwh(`tc$nVkRNI&4$;!! zgT4x2Xk#tGaEq^TI}*-8sc!?fVHfs<@4M zIrq=GE6vps&(&jPnfyUjKYB;$Cm?dfs)8i>@1KRmu8tvhJ!NuDLMGP&X-y$+(T8M^ z*G6ez*?enXB0K2%0XjOOo~IA#Fy2mD896dOqW__nCqsZgn&HSeBBh{YYMH-zHUMV= zaHcmj-zGnP#TRhbCBf}{4J-|8F*bk=@bG(xN6!1oF(_@^zeaknCRC_xbv0FS-m*xm4FpV|z8%592W{tZu-3n01mn#tp_~eH|btE zk8TvbFq-s2*xuuED0IY5I9OoGX>~-zz6588CWfs>Hp|GBC zwM#27JV`ZFE#&$k9d7|g0usfmEw-)5p=w!e1=U=uXNvh4 z?(&g_@sHJEY&*vYPNxwJ%Opu2eOL$xrNYDHQTG`QTO^sx=kkTTM$($+sVL9tl9A2G zJ}(n*X0T%0{pD~J%%m*ORjh3$?W+9;{7+&SR4hv5gDyk<$$HgP#asCB1fMa<%RzU! z2!FK0Z@12#S#^=HXO`oa+cR=-e8etwmdQoRgNR+KKmSotN&6s_H)s9tB0WIf94~sn z;YQWprq-|0*SD+nHTG_S*4|Z<9L3nX*vdN~>|OQ@X(;vz*#zFe5;)+x0_8o}M3R3q z?o4P^9gTMu`CNI}8M1xvH#hK2KFE|Iu+Y|?pM(oTdp_SdYR|XRom`JErUUto_IxMZ zVkxcc936EJNcHuk88#gaRLjed$S?GmRNsh_w4H26^iGidLRhX7vGrpL&l|DAk_P`8@`||8oGDn&e+b`hfi(_{_@>F;BO@*(hyl3tBQ;{+8I%o9JKCV^}a! z?3GpbjQ4a)^*BdwU@b852Nn$HHhnKVq=umBBCnimp(f{ zjWbpD`rGXCj|h!UwC_%o>h7RrD~MXuCI1dzF{3;&ke|ZtHU}oAvb!yTiRt6-w_~?V zY(g{rKC`l0wiYg^;6pX#*m?@@mJL0P(I^g0KpnJAhJQ$$r!dHUr^1i08@U0GV)a8( z`%oGj@|@wMAClz<_^(sG7r%V{I;Z&ScfN6&*B8lZ=5XWa=#l1z_WRWeWw}h8Yl!`5c1v4wEaWg2|UcsF@}+pt-tdVhU^i~RZ6EL&)*+xOVVeLn)Tu~$JmRVB1f z^@n^u>Wm-LHWl#`C}e_9Hh+tq_)Fb$=i8;#(+E%C=mA=55dR|7OKWPvkrvFtzSH8j zbm2dZTQcvX*iPe}G!3qkHNOgXa31yc{^YbTSsRyf;s4W{4_SIw1Vq_I8jucgAb*}-5@g8LoT zCl!9d-i38)O$*VY6-$gYxoEsGIML|tsJX}0p0+QzDCBE&pJJ_2VSCVm#G9s@kwSS2 z60({ur;BkU{kTb>n@n6>PZtH*{!^x!4h(uL80+l2g$)JnsW30`lg^CzJC5bhO$H_h zEY9fECKiWSxZk_|4D1j<`w&-bTc4wxi~tD2T0_stZK2=07dMmIF8*7%?o#eeDqx$^&v6=IV|!Wa^ibjW7$djenPzh zo%lFNK{v=VXv6=7>|v*IAaF-uDX9XdqJgKTaSfbHr+Fbe>b_bgisNWtJJ-M&6RYo0 zHE^`=D9$Lz=zQU;smMBZv^YNpjl*`%lVAH~?80RJfMci?}Ek@SO&M94b~#(o)+ zW&3d~+lZ+OdccJ>G?-}(2uQs*Qp5a>@i?Bj<{I1rGOd&ijjY6sDQ*{pvVi6%BOT(v zAPbtj#7OazB7VHIVs0@BKY%)(;B+Kx{HKi4>g_`fhE;iq8E2{sq^;QW%S#{~?;Fvw zWY}o<)(m}#$8j(s*D>Q&0xk404Z#^%7)ncq`9P-`eP3;(lh46|Q@tml2>qunl2*?} zyJ&Em9S@|fOA}TtNL*EhBLl}o^Cx{RpPQtudti(E_IFE7U8`D~Ws`5j07yqxfz{{# z{7z}>KI}iD!skBMQ6JEqv1*#hXFR^D%|~+IEDx>y^iFmbw=>`~9$8f~WYv8`2_iN%n*rbFqL+>B00;?AC47tN&rCpS zIc(xR0~M;Up55L$YQsd7O1(kp74!yF z&=mjx!gc!g|6SL)AAGL&e8w6eqIQx~p<DcNcc?KzoT8mU-K0pnwT0~%0z2E!= zHj#Okb^YbUykga~3yGd{R_$;8VyLvWU2@)-dDR_O@L6(BNX3;j6%s@g?W8_)es^=0 zxBFaZVuylluH%ukW@>33)?1RbFn5OJd|z@N^hqD?#s44qr0S1-(kF)`XB%$!;}VIs z-}Xs;ok$?Blx#<72a0wfk96(~f3w+t!ixP?jO}d~L8`$En*9ot(G)D`G43@E)IOSI z2#E1T!?~&?ZD*r|nP`TXi83IM{3f?>rnUq(xrMW|CAi5gd_Y_BfI5G%`Q~80(Y<5I zus6-mSWP)tR>GU#`R8he+c_hCT^8l3;${`%Q zE(@;UTNzYRBY%k!|Mt|r9QjjRv3o4Ed_wCutaCXvRUuy7p?jE#rx(-HN_v_uZ{Uqs zpkg!e?Scuvxn|P0^v7#fG$oOcw3z!*v$WcWRM?81RUQ)o6@Az@ETV#KXd>N&Ou>*` z8}OA@_npG4$Q}&dIALI-v&rOc#;Vwn;hu&$_kL9HFR~`EX*BOTAj#vTy01Vx_bzEI z;-?r$o2!~#TGNUr*g>D-uyOmHEplSF9(J_i4b|Gw5pO6;j~@hR2aa#SlAgjX>51m* z)ViHZ^I1O5BpL2%z*r++e6Hg{(wrDcMp)H&2+rZaU)|2f4l1T}3qSO=&{QJNCUoqoPad%@#-R)w18n2(02gAHCLmccawrGZI0`)rMW=G zwiefhe+pl%b&VB3iTqz~%@W}J{jLe<`aB(d#!egc&G6WDcr=X_BnO7OI0I{7Gu=NE zR!%;=Q~vE_<;YV}QEtUFxm)-PRe!*}IAKZtfXV#VDc_A>66ig0>F9{xa9o*u34ai8 zKRe1F81^5|UaRvTS}~h*f5NhU8J$s0xD^gswXqeB0sKf)_rdJK$qs|$9AYPZ=Dd&; z9EoyTvw9xFnvo?rzm}ZGp^0St{|(d?eyfi_Bi%wKhU9$9Cw)CcT#_OiK&>vxx*~Tw zZ~A{ECv@6}Tz8Tdlbr2PWdDOp{tkZkDu7W78j#f9=Sq)ocM=s2Oz#W|&!<{~9+#MZs-;H~^>7+lqBxj3Hn%{*j z9{!l$n6x*E{Kh9O#o40fzU#vK5mM9YDr(w?O^v2@wpYsO%#)g0*$Mv-)|$gOZii2l zKtLh>Sg&UNg=`gAPcU-#e;Qnjowxswxp#q&s=D^aXEKLmBm-xV6r-jZB_cXhgGnnm zC`rg9Q4^dHlK3ECt>xxYYh#!Jv5qZLcEpxC0#i%bNBL=Xd_ zL`B^pQ9u;JL+1Zo`xaxa`|Ri1Yp=cbdhMmzQ~~?iag^-@t=zNg zl3Lxu1kH%3IOHDF$_^NBnbd-p=D3oXmU z9@&lrEeqAX@C&wdIh}o+Ct+eaHQ+o76RCn7S?s9qlw9>G;7q5!1f0g}8*y6mot-Q% z`#hX>)S(qsNK^$i<{1TmO-GYSf(Hbvxm?tUl!(fkK8~r6G3w7U6O5Z4OtDGL1JclD zJSE1Uu9W($80dQkVusS^k7I{Ia#o*ZslS8vj&bxw!k5JQtRZCM8PoJJmHjjpA1Bmj z#iGvCq21Kby>VCw>6Axgpwg4-Vf8PnZq+KzK$h(KELe@!-!T*!@=!1$e|~*dJZsjn zy3y9Gp~yE3z##HB^S=5lTiSNPN%5Mv5Lk$S4x+aq{mVB>6un)IjZu@|W~acQyJL29 zFEoqZ36Mx{ZSEcF`}j)V$t%5yCt89yop`TuzU{T?&k`j6t)MY5FOdAEk8ZU0UTQXj zVCYg|VRb+ksH0v$M1s{&U6c3LaKbg9e~$~ZgZbB&@C}$}$@!W_P#r=$cSdWu z8@r!M+PL;t;8K0?QK5u~Hm>ECkd&VU%Zb#Qy%c_vU@uegZ(I?75YvDJd>~=`B*?Oe z^(^7}NLEXrRZq5bsT5skp65p6$K}*bxGW`io&`Q-wp$B`{21j~b!$ zV!g1ume<2VLCvD7C*f?9g5Ok2J6O{c5XK3XJ~cCF*-}IllE)VqWh)k1>h1m`wDg#04MIlIusa!JnLI)9QIF_zJ0$xbLbnLCX;z99NNF=!QZbS3lIn zCo<`yqUG1t3(HTek@6EOdLddq(`vNrePR~u0ex-OC`zn<1>ZeHWB&mXKxUUip61uU5=T`x9p?8eAs9> z4a0NBm3#&=S2!>yt~6UvYvPC^DFXu$djslBgla!&;Rbw3LVaVYMVBVeOmKd+@Hco* z0V<3Wo@?2xP_wf6KJ9#_W@MA#%p?06k|3XBUz6%<7qEkFgZoz)%2W>2QD-1q|NtliO^_IAd^yKLSOSm6s(8oCBD@$mRSX5W1H{UJ$S zYnELwiOA|2pbtkaTQmD+u#eb#;Fmm(z3LRRdWYHBEa&e_Ynn1K*XAANJ8fP#uIqFL zejgt|$31GEx$nBPw<-N%!EMy-lU*%cr!y(XF$3ZqcY32ia!6B-sdTz z&u;4TmbAAWt)kB(se@xeUG9AhnJ?UHpf~&00f;(|p+{;7e39k+c76DxsH*X^L*oYq zRAlyz(`viqErOvqPZBhCbPZ$?ERI>WYS}^^Px!lpjBq`Bn?}JRmCa9oDfoqCEeE_` zkRvfF$0J$}GROoW!qf(DE(vZ(sX>iFlB-P!rt+5|qtm`lz(K9JNPL)%4+zyrJgMMW z+a}BcK7nO97{tuCO>Zr)&?N4!}yqwWsMQv z&vumZpB=*L$I-A5e-i0WGW|&^3|8QL7Oaqh6;^a>7(B<^{959_+Mwe|3-Z$lV1qgm z8Dt9s7I`sot-%!k{q8YhZNhT^QcrQvJ!O>_VGlL<)T+6x|L0uHbp7Bh-v!*`7xXX9if$vwLBS7za)=kC;=D(&gM+g=5y) zT|#Cgc+In&vK{gx!D^mG(S`3rSAa&G`>HQXX1ZP>T_-X6$g`y6{`hxLaT?-TM^z@R9sTaE+vT8Cl4H^-=`B|{$ z3%e}?y)v?uFV&DKg=b7X8!Wefok7ab6gS^~liAd;YU&s}{abL?7<(4xG+N&bEY2e` z=BC{N`Kq%MP(DiG1Xr z!z&@t&1H0+_=%egMv`9eUo`&|FgMZQZ7Jm)_~q-L`Yu?Wuh|}g?b$Xy#P(=~@mKSo zs)#f#%Fq_n7TC(WRo6EU{t-BC(rYf*pw(O)s+oKND#H~=_eW&LvXgj9r~vKIJi{o# ze~l>%^+xco6i>vh#0GMRR+;!I9BII2P@s>n*;S}SbbBaCAdQMf0^8kT;F1w}^#3V!ftvI-T zp)zTCI$&%lfn2~Gom zAb;^V`rdJ(%XxHuvZdWO@ca2cVcL-&cB>@5s)xv_wv8HZ)!Ybxfc)(H;gP^*^Y1r; zyrya!Vh{v19Menrw(tdAKYLdg9h;KmHv#SuJ1(&A%)AA+k+L{yMV;h%Vc zxFGjILzAW!AufmmaY24~fv_Mmz)akS!}r5m05A28uR-AyVk z(oA=gvFu?73!a+q`HBo-6N%=*ewPSMK9f=ar3X$5@<*Qay2Wk+zcfB-{+^l8CY(&d41Y^z{@oh4lHM zSR*?TYotifbG6#sby!Wh!E(xZZ0@KfG3qpPeQXY%hc1zG>xbh>1Q>C%Ewjpm1>|!B zf_Ts%bPGs3Px*EDJd2s`{EE9Lp5cC&AKyJX6AZma5pEnL7wVi6MvRA<0-L_C)8U&W*1 z0+=MQvQA%f0vvLE@Es`IEtfXIGgT?THZjuGh*(GD?cgF_t$2e{+yhT4rMO?)@0jf) z-^Y`cf;QRz0%{dB+*x)+R-eKf;cLR4TXDQJRgYkh0!;P}odUKz139V?C1X3<@(sjP z{oFSYTXn7K>PGht;$Nd1VUs4$iRB9u(57qq8&*^Xd{hg+?z6rDZKg>rOjE17EiI*L z^}&_+(^xvqUC8gE>;>J($y^)A-wP3(Fb-D_y4!az`PRZcI}j_c>59dmnm>t+FK)vp z_-ez=ODWjk3tFpEVW-IU`3_s5>u*KOr{8}|b@l+G;Pi|P)d$HR7=@6{yC2oSw-+97 zyJ^r*eg)RwA6$5u=rFvNi+db9`P<)64IFOAG2QK-1u ze7j7%`xvBg`{qAVIb@=%ZSEXa+)eR33VQU}S?gvkQ1;2|I%1o9V+-BW`1=>5-Qw*c zSJMS^y@FiG68awWZbs{Ktb7GN_}cRNobY?OnIURJH}m$$>yE`Xe-(?K!VVV^SPKyh z9skxAmK3@9Y--R&6YV=}e)MC21CRt7yEXy703365z#p{($C#zt=)fP*D%o&)+NEH6 zJDjLK!tY0X0o7J^kYoa`e&OiqTC2@q@jAygei6U{1I&6eL{AzQwVE4f;3O@{14f@2U$0m)(M16@(&o!qX}urgpKq zE+u_kFt}-Z5z5cRkz`J={DVkxrJql?DE_#ekb2t6<@5f)IdY$53 z4VO*-aqozU8+(u>`*R`I>wOnplwT`_WkD{K`Lp8W*Y1+xvmD>q{3(2QbIsZ_S*^v1 zN2JBZcPqtEALkB1p7?G&NXEl(`1gVoy_P!+MiAskkZThUO2PJ8?A2zIym&hfNt(;C zytoO^YA&3<`uPf+K@imKKWnSE*Pu%a?{`r6i~gdbptsX<0%3Pb+3r5-&(1d!MhuUO^^cgI?G zIlJU#S0E=A+gMiJq}o1&!Z`>76l`;1yVEy2>~pliakdryy9M1?*0*ber!B~J5FPF- zX0H9d0cT~dS`lEb-Ik*ninj@N^~>G@5bzD9eN6$+wW@6kwGlvPpdRRrQ6EFti$Ipx zQ_)626E#!ab~~Vf;eb?kI}3KpPp$&_VAX3t^D#U9ya2s}3qKa1HhIlG7EG&UqHFu( z`K5$kCHyh8fUy!X3H(AT;Z$h}w__W_yq5CCHVAll{)cqP%)wvmy1mcfOwDf?2E@6C z{cki|5q!U@mC3~xpRs%U#^U0W~XI-+$I85-w?40S+?Mmsn~wY zI-P;4ZD@nUr%B>89q#Im0}qe#DHyTIOw07u2sN;rms?j{f;skuCZBevpL zVXMw1?k<7ET<~XQWhT`f>^jBLpG9md=bcjJ74u`+aA*9yQA+w^)-n;N?5cgN0ICYb zws=-q>rA#ye-h&zfxnWHP}{n_MB|~3@?#(9{L~ycbHwtLt4YRf$B`)dyaE5~Hsp-- z$KEjLea)cv<&p1$&o9&wlJ40x89B4S7GnYpHCgAETqZW0EtKRnJ3$9cplB=OJK|3% z!%;8+R(V1ATUxACtZH`|^qgeBX%|zltA~b~w~`I8eJmESEV&8Pd~{&+E>Qf?puqQ2 z^9j^slJi52V3d@G^tXV260>!)>D?04ZR?3L_od%2A0$5=;fjCWc&6o&Niy*p zFc|Tq9}4>U3`BboDf*tp<3m}r;2k}DBC-%KQ;d*5tjtOwJT$7uEb&t$uPsv<%A{@a z+1n(~H)$W#orrqQL~s z%p8zfFtISyX%QrpnN_Jpk)EFdQd4H{0v9Yl`CEL4FsEyP!dhj&b>=RRZ1z4FFen_V zxpScU&e;tX5p)NBflq=4y`|G2c3}R<%Art&9uZ;6VDd>$W`y;??gKc}L#@BoXbt^7AB$RGtgkwkZ$(Tay-+Un% zKaD~|cLE4lrUiCKnYH<}1&S$Edct=yrV4?@tnd;tQz?Lh`ezi*q{0Pul%{|?E*th1 z0+?hsOZ%`Tv243EB6}aqrek1Y4q_|1AZnOnLIds+{sNg+wI%qZ1Bi~)@0)%AacFHT zoZCE?hu8mJ`WpV^{R*73Vq2jmyo1>?`J`L$@fMUzsCRaGMm8Y8l(Z8`JM|>wFN47B zd4ke1#4-$)@`)%X09uM3aVKIMl=6x_w71Q{Ut*^oz%MqwL7Wthz7$WM1Jq%84|$ft zDxx1h;D4}%mA>IY{a}DVxKubNfJ!B*P*)v$kqpyu+}Y~OZc9QB+mcP0I+`9r(YJ0f zijiet0+D3l50L#0%+9_^w!mrNo1~G@e0`IQlZ<(4S1*noClPJzL#!HUD-lFcpdYh` z(C=^A46LWq@|qK|E1N%$jX#AAHWB{o$m82$#*s-$hXwFfNkL`>S&e?Y4iVEg7>O=B zzJ`;CiN+fu*N~5-qndm=03!G*jTgPWKMm4k40sasa>=Tci_Rn>*K}V~T!`;S)D$u} zL!_V2uup^9XF#MfsX>0t3~{-<=3DE^%;wLn@rPi>i*HcfO#*Ev({Ug;Y=ZxULIe*% z6(^}vzQ&O9(R6+!S-&PY8C55=uZ;&o}|JQ01yE*9rB5yx0wHTD|KmUXtZS zx8a4F{fuw}_DH#iG1vTwJ-#IzMTmsVRDKdU#NOXans6sH$g(dEWoIjwAh?|P@F#qL z??v6W7(VSpO=vX%D3wH7ifXEVIy8mSBK+jBNiCphzAq*tPpb1k_00q?^l0qd>;4;1 zb{?qO)hFTay=)s;{hb(aK5Q}bA?AURI&_gZu6Co(x z=4=(}49(dRyuf?pn(v*jbbY>zabO5__t7K}mH{2708Ts&Pf7^19~Ol4c(3E-dD_0+@`EC$X)_mH`o7F z|L(`hJqV=owdD~O-O~z{-VLZXiG3)qJ0076I2P^9Za~g-<6mh}G2bqVB>KKGKYCCr z7lCYe9E1-w#{91NSrq=b;W8x(4$42lm@iLs{^SegH|o!h&VS?wdi@|ZHktxh^k8tf z2*Pq2CJ>0&>3bdvrMSTvn0po5wdC>>?`r3_TN1s)R9lSik?@$QSwCIr1it{nfDkG~9LN}e^-(Om{h zaH2TyF%I)L+Ii>B$n(yFVSQZ+)6!Fp~BJd)fIs%zC zDBd+n+4A#V@DQh;ii9P?QA{8#5hgq`#!fD#pv{jbVI`(v`z=@}E{Q-?JI9U_y^uR- z_d&>YZ=wuC$iAlQiq{}k;Oqv~mdadf3WMn|3b?{3y&5qHnKYi|kB5YPm7_yc7EzDq zjdR1p)7Nf8@t|uplVGtrQF3&kj=?odbgiyzL%cke#_qC< zk3rWu#}1!st>kkx+9KLQZzn>C=xUS~xd}1O@$o+bVdYC7qGd#hiyY3TM1J1 zip$Bo2Ehv_mRc9KYxn{G2ZGOPa!~y*0!A8w7Q&m@(yU4uaP~o84UnYr7k-Eg-W3`w z3s!-nnP;=?V1<%n#EC;8sCp))9cLF22+|Nl4<%eHauM^9;E-X1bFQmVt6)$u=RoD# zh=2(oAY2S9SdDOtkjkw_2f_3%6^o#3IrFZ`!sdlB04toOa9wc%2))O#-pWl^Vedd3 zzLWKaWdP~kkB@-l_)625UyZTTztoB`_RD}Fg4o~>LJJ_|fap*O05KzlSXMjTYEXpe znc#|S5hIi9Ab~Lzm!^FgK40bEAc@ir+YRjOiQWJRGV+*0(2(nhPo~%tHIxpblK}A8 zZe-b)N)G8#95k^33s+x2he>0Z4L*fOX#*I`4>)j@JQiaP1Pg2dzTU`eI2a^K4vM(z zJW}}{%fHcR{zhLbnPVoM=*IjC49Xn6-`nK5g z{3rBf0eM}byy$A=pH+rcbP+DFt%F`ECE0TYb&G9l$3oMDekuG;Xewqx@?meWn`X9~ z%=)7NUyU9th@=NIE<_JRK+po{$yTrm((dGG9d#I&jGpL)A_C)rr29(CR;6H#Cxd-N zF(vQRV8GJ!)vaaljH2^mj-<}BIdZ-Mz+mwM`S+KAlkb=7%-#;fwFIewhRxAV;0(xq zVn);6h5D>`o&RmQ?l8?9gz^aextdnV8U$j_kC7a<7%}A$t5U9eM$fwzi#_dK3M^@p zVP~2tIn3G|=d$WmL`M)cTryKEON8I1^Xx~8)J00WDN1&il*JxLQ1M3eiAix5&_gSt zd}*`YId=$Z=-YwMLDw2k1{=c2vivx7CvI?eCb}@PweliZ!9q#43bcf%2<10miir=Q zs6kIgQSO3OJP{IT1jkIry&eAJo^d1tY6mU)cmN^ZFx!=OHV-0^(T;Z95#$@Va{iRU z5?%zHAS{j6ONmgKS3qJ##0c?5#_3D6#2>jtiy%ehIn%@rt>Mdyk@%8#A$-C8KTWIv zL1Q=I(3D{fcEWDc)i@d&kafP3LGQ2Tj4QW(O1Hv51>S?{fvV;phGuGqZk+$@-M!Eg z;>#KO;^tFY5KpBTN=$~lZ3GDVWzLwGC>_Ov}7t^6+y$eAWNGa+1ikX}H5~tOd9mWj@ z)La=fuG_OfjHpkNlVQ8ePBk#JvXvvT%Zqk`xYL>_UUxq1YQhnaunW>t3(QLmx?}wM`fV`C`A?fRDYx4l??60) z{j{X(6v!}9NH_(8LY5Nqy#jl3{??vLj9srZ<&7%1y#OuZ~w<8+VRJ&uUja5S%+DIG}f^ma|a@FZ%0UBJI z0Hv&63>9par+_U)NdIhr?k;`2H%HS>=rh--uBY8a zD)|5exr3OV92>f%xK`+_lD^2WJGxc_ZN=soa4n}t(IdI;QmiCawgOg#-nA_M3Im6( zV5h0jDx;8|`!&4Nj!OM^t-yQ?U;#vJs1Flu2f4f5rb>^i(iUjZOcpN*>hg%ay!-)J3Ed_jVA~mRb6xEFYUUq`($u zSLK_Gx_q0_<=X^WuOhTx5rOuroSA0pX2R zC@Lm1=&fTr90JlOdLu42D`6XHa3%bqQACUEP_*8t0ws1aZ{2m?rL20XG2YBG>g|b& zbhA1S!gsFZoFOaNUTq#(tYD;{1hBwJule;Dd)jfxBkHP=;5#ioa=~>9{2mZk=a`*$hhrZHK|QcQFAT zXpDW$b_e8XV!W5AkBjlOTNUnU=dLYtbNfv0?gP-D`oGnuU(Z-_NPMzfP(r1xeQ&3Ohk zSmed0JjxhzPPX5MvKc1hR{l=4u@PsJ>E_!A@EF-!VQ*@46E|w7fBaUA9d>l#JkjU% z|DExCDP&Rqay;#!Y~k^IR~0p$laPaj`$|uP`wP&UJWhgtGQs~Iz#l+_eKjB-1@^wH z&o>!;1n+#BqA_cPJsu00!Hvqg*~oqm{lr-v#O+Tgxaau*)Bf`ZqKAj^H~03@GgtBsPB(T zviet~i>6-0L)5k#!QY^jC;g&=$63A~ng+kgvGbg+v@d)x+(KU-l&#aDsC9!3YhA-$ z9?8UdeiGWsZgjj8*;@O;%SAskVPQ^qpaS zl^bthD0)R7!0tiOj|1bl5@M3eY>sVgL&}5564Aa~XN68eXdY~(4Nx|nrUEPmalR$A@?y+WtnT(bG6pP6EK7-Mf@!j{p}qLgxbWkQ@5<9W28h?1WqELulIs zRwf%2zC&qWP*l>Y|QZAuJ-6GQ~# z@I}m~X$VnPcyS&JZ+_Tuylo=QpB+S^jq-~@ir3DsRe;WV$ zT_pc&Kc9UyOclwV7U$$0z<maQh{j?W!C(>I{Y0#Z8h{eF+BD~`Xdz*X0BxoC8DV^vo#&P0HAwDV5&Jqcp z2ekDYl1-!qbq;%9bKjMgeQ*yJ{A&s1Z!Ff)*?h|4e-})^0?9Ogh;M>v-ndLUQ*5pL zG8Y`9^E6~V5Z<`JU7|%hdHq!W(Kta^=`0~m717S0V!ulUHjEW>SVSW4aYQwVbJT<+ zY%i!$YS(E}ra`7oh6TlpgMy@XeWyzIm4Lw6RVe`1EAHcocj7|=JH~b)EKf=zbZu_C z^TX1b8K`hLKv(%pK zfZh3C)obYM1m}C+F=SzOl`7p1XN~~Zi$L>Wlo-%Ts8fSoC!HTvXJQE?YVu5!Q4<10 zY9?k$^HVCNiPz7)Lbk_Hn@4Y_@?9sw;wU7o2UwL?+PG3rq;lf7eOXcDtIslfC2ENe9))Q-yC}?7}(3 zfKaf3vDk5n)NvVfNAYJ8t|>qy4ejeQ2@5K-E?xHWq+i|?Kt7s zf}|~4l3O^g=UFJ%tCTc@yzMf8mdSlGsM%Qbn6JbKkZyHqBCh5D?mExT&147&UIU6} zVl$@s!(P*}9`VdYIggUXxHN?+x8UpsexO$`Cxh686x zPZ#j6;@XdEP(RU~jmkhs3jUdh>EnRAgng!^*Go83G0*V5Y)@@*7WNiWysWuH0 zF)Z{PS*W)Wjf&CbAc$mQXn;+Ly#boS0H>y4!!VtCe3p6~E8ArhE=9F*_{|~EOunK_ua9no?T zCERl!;&!a+b?S=qnD-h8PC(l-!nAD~dVpSQ)KI5wn4)Coq3WL?{6W_MP8YOBg{kcP z(Vzw}m7ROJYMTbPN&t0)w9|lQ_D;K#S8c^@hvd%thz;)Ro}~6aP{7cqH^^6m~thl8nHBBAeL(-2*I_{`R%+b9N#v7ZYjZy zjeIXWf*`L`r7MtC&*6zxr6b{2{@&bELGE)7K5c6HrD8+DREkqu3d0rh?>k1aJFSlR z6Ndyj4#^l#goW~;2zID#p7&cRbaVb(DN zDYsIF@0)=ua9Go4U?c7P3r73C=z)~On1Qn|i|=dzGXU25mnODHwJip$#-e(it<0cS;((XgdKtz#R35bAj>?(sY;8LDTFU6mVh!v;0v}Y4P~YZ z&_J~=K=Z8!+eL;c%Do|wtMwbw)2|3T$V;HXZvy}0lCweO*8;z^8a)Xt9&MJY>9uTI z2_K1ZD03se^XBDegIt~%jdP^W{QoJw{q?2q$G0c7@Bdr)wn+K^0^gFTl}LO$jnmA( zhi_H^hySM|u^f$n_7k)Ar-?Z}~*`Z{!Z5qd!Z=5kSff1QIKKUnF zP6(m~ZhN}_OZmymKynI;aAHp^#eF#6Vx!)|wmCqzfc*$q)%Bf)i#2d7Bl%QkJ67J^?qc|yqB?ge{|{_F#IN)b^tISe$J{j5bl6j6apDDOvjEZ9L(AK6rWx4A7!KpC~$T+B+vZgWb7RskyX(d<-VDIYF6 zX+0k(aKhuGL%j%hK(l27Utx0|^Hh{-_MG>lFXBFy|I6O|Nc5%#OIEiBZLK1*EznGN>sDG_O?Ioc8HB1*)Kvu17(>NaJj)?kB zO;CT?2*n|QUcUdi$#!0<8c0w`_LDFp#M#-(mpy~nI3Pi|yaGQ7N)Cw;l9U{Z_+-QF zn5;dJlSEh?$Vt|IQs}2WXRK-FJuucn3!41vXUjwWLbd&E$Z`P@7+u-iUk+PW!=*J4 zyA+BkK4p!-cE!cX8wluWgE)+J@V`!=sNz@xIntbz_8QU$m;)|Sj>0Gc-m3AD<;XB; zxNu+LV}>CzyvB)R>Fn?|O`z;<+-7d$xBTrp+(RX?j0w%$w$|(!R)qMj*W3*M;5Sh1 zoU#11KVnS`VDZ5T2*uzw1{3B-MKEX^K>x;-h7D}X{wC#t1(lufwkhb(zm z4LvA`LpxPcGbgxNExr4ilY$jV{HC`6{2lz)H_{4}=9u9mQ@aj5&~w!`lfIcUUbGM7 z)Tj)RZOM3q}4jQ0+}I9&W({wDU;xEljXi#;~6hLK;)oOZjZ7UlDZ4$~WO5~ivz zBW5VgZ4@%DNCz^$heANc>(G*pj5Z9+q9fxoH~sG-Q-U5ue+^TFK-@vlzgdRx7DFKYv!EgD_N3lf zX{RG&KhX&B-Pe>9E{RLJ?4QTg-z&6O5v-o2d$#*qlT7CHSDZc>3G(m z_{%{~6#on&F{^H*J3*v&|NVF~gVY)dm8Vw$!{OPfy4EV*)o$*a1|HP4f`Un|z#~j$ zD3+w~r)h@Y)GVUO`zy)h-`$n@o?E)wfKgem^uZBzFMY88hrC_bz(ZhvCNByN3 z9yX<6#YpL7cYtckbw5X=%v%GujOuzoNvYpYSb%K;LW$ZQru1*94)mU6+q98F7oSCQ{Rxwn|vK$2xR3`^k_~hzjT#Od6xtC^I)G!o{0)E1`6V!!U)HTe5OE#P5S}c zO>YVGGdqxxXforH*o@>r##rscIQkJBhHDKNz@bVUE+7E-`bGi;+@)$k9l!n-jEGE< z>Y1xi%xUJonA66-D~&lF8Jf?=i1}=cfKcDV1XF^LzX#_G09|~fc(nlfdK2GjWboV+ z0^WZUY74=RtTzK{pZ-pRn%{$JNrXvu4>i^63GF>rR!i{fgGY5E6Fe4sBMAxY6~bsJ zzG}zPo4|O*wI;1;LM>QKll%-UjhE9~s{ZDGh>)^&0$vrrFy$2$GnHC}gv_;uBxK@? zl9{l?wZ1+xk%>Y|=2%>IuRH?d<`v4LQ2*8|h1T}WOVRoWa5tIbFhwv`T`r~w{$yf` zMyaml+7vAYo2X5Z0X{N7bMs}t)M4wHN`v+0iTJ8nMts!^EXhXP{+y|YS8bs9s>5NY z3q$A(?fT*`h0)?#feE?)0u$EuU1MOvrJBAkgbz{cTP!Lpq~TLB5J8FjuR{UMTy+4r zSb@vky!jymQ|iuO`n38mxv?wt$)!R6Z?B4m!K!kL1FltUp5$vsIF;3qI}4jXQ0#GV ztpGHG!UU21qy+63tVVcH-r5iO5w;E#^RC8RiZeBHOEr(-V(W=UgyX3Dp>R`~9m+F= zL(kMAA`b)of{DC%@qDY?VeN}kV4tC6U{hEn+cT{4h#V_^p&Q8|ZF2^&x`w0_V`00S zC$ZWMm^VjlBmQD*##E)U>KZ2A=cESH8~K~h0;+dO!ha$xbln7MrVhCxx;RstvuSI^oVD_{H;rkLFw=bFCcta0{T910C_zyZzX@_QOhp1d zm-pj~n>TgoQ}Md-@K^0Y^;0DR@Jow<0U{8s4H+_iWy&mlu@32kq zzq{aiNF1#GrUh4Hm-IcFYK9+qr}qcWr)X5w!<@BLqIyW98S<2yn(!yofCjJ1NO%n( zZx~+DCg^+NdqezDBP&cLGsPC<^_@aMjVkegD{EHOuQ{T@qwNC#J^=cY}6i9KUE?o z{^_E~iO)b&VotRAcrkK5ngD?d$b-lvDw7;okOi`ibch3j6$^qD9=_oPVN?-;(OTR% z_)TckB^}-6Uu^_+arF~(3X&c=i10mQ;2cxU#jy@JolQea1g9xP481$_(e)S)@8jXz z)7({iDIY`()D)c)R=+`~IeHV6?BoB^PjgdX$!Z{^HvS#|#`qg+1T3ofE6@LTK+w10 z{2vJ@H4eRLFDYIJ%*sfuLqz{0*JYk;*GDJ{_6D zxUe-v9On}V2bL26INz?1{($kYM|+5%Yv~N@MBFezbnT}&mTNPt&F}TU4ecl2PoE>k zCrB8^*Kncn{pr6#;~Nz{zPRrj-=Wdr@imF@S&d-@x9I~tu02GIZ~BtR@zuU>jF0HB zu%EZ_5!BJ_6e*J2>hj*Q$niHJ--XvV**9iNB+m63F=2xSife1#*EAMJuv1nMwkMxY zjA@Hp@~2-pKfZr@^||=oZ{Yj!tvVpSG#(D(;aq&b;k`ll{_@5seE;fs9pBwhdI^L8 zfb0TZbbG1z#}Q9UgB#gsYxwd+B)sSkc15Iv*&mbvin0JE5#1 z!!h$^pzUC1RtpiKC&SAh{xAF7V3tfzo&^Ad(OlZ^n)k-nnX|F2@~`w zIzoHQ-4Ju(sCo`n&bW%EXpKRYDg0V_#>F~SE_z#^qC1R-Ogx-BMNII1pvu$~QRSf< zXo~1fP~|(H)2Ha=-3a@XjOx{bM*hs5*sZkX-00@N!6%(yWB%YTqRk@yCb-@FI=~=g zK`XQ+$V0y(ALW3!$FKk{R@dPp;>h)XgG9tGJrFt79BIZ>`-u*oGux18?I!N?O)+)P z2|)%teTCeZb?CECk%(PQ?XETx-<$;Qv;^n+HZxna0W~@nHR3M~-8Ue~i)z6!(0mtz zTcFu3z_0HyFjQ7(hy9cB=KMQRT3Jn_=ih1gb1j~kO1m)gQ#?FGmqbKfXUD?fFe_BU zDNH5gWgD#`Prq}=LWGHhN(V;GN7NiM;s;X*&a4XDR^g4O^rKT1?|#I_q!`dhl%Hu< zZFJ{gP$}r7sH7iWjNugbGgl8rV9_HBJNIbj?abTV;5_oU2VpaDdUC!Yc8Hr0g!cyL zN_&)&0DDd5xzNz{Wga8?-A-OYQMKx_LQlq&q=B6exK(D8syAB3j2a6DK&0VOv zxSJRJh|WJrZoWnq9f8&deaY#ow-k3$5aZ(h-iOg!bX6eNTh!gM-D$_+!*?gnbDcB+ zLfERE=Wc0Wn&?$(s9BI<^28wqtwpWKZqLXtWu03BcAq=3Z2eE6YcbzZjw#sA zKf4SKg?B*WeN@69EV;*5;Q;s|VOv>CqQ2}11Nq16XxVk3lDH^l=a#7bly~wN%wlt*ZqK+&tSC+7I#e z2qv~fEttfsbJ6>R$8gb! zb}`74wm4;V2nY$0pYK41oZVb2nAcD+aR{b@J?0XuD*P_?Y?L=J{8u}Fh- zvi_g+E;cJ?6812P3q`bSEqybWql%XcXZ;zBC#_%@g9-5Av)2+zeAmy zqZ4N#5$Aqf$cwC6SsJG;_N$N&&<$xg7|A z4Io!uEYEuGyXs!^fI^YKVV`Lswed%Oa1PBaSO9`M95OQX=T$^)Bdbi%m1%j<=BETJlG%vhv;GYE({kzfCRh@b)RN6O0qaed1Vjt7wwB#)kY^e62nRij%v znY^q?r*ORHjsp;S4-LIni1$QLFQI01pWDjZr3BC_w#M& zv;U>2KF|9T`iukDq}ItK)r$!>ZpNtfZrO+3VlORE#$PwD4mI}a?bNwnhTeCH_p);u z|3`I*_@QyW6}w3dz(T}0Injv0Mg4jQp9DSpxB0hmaP+F}-wjL$)qE|IYPvCBA^wdP zb`;?xZXGe9`eE2jTBzsxX{~HLg1?9Y6(T`p`*9Tm1xR16Pc6b7D1MUFx4UXgypLFl zT+pT(oi+iU<}hK>l$&g;qCSWcP`Du44ADX<9yAdg|Cym^vsBVqypLpm9}=9u(^$L% z^!%#E;_af0{{7U&=X$7%(1Vt3aJDYADrIXC*u5{7Jtw}td64p`Tnyu&^CVcjfKqS} zdg=}}(~R&JxWqu?@P@IIxH=KOYfAAZ@OZ@t69OI&gd&2?Q%Mi&JSErVW0_&gfb-t6 zAK{U_-*77ewvXE-r;x5y-$W7Iv`wRW40tz#vrB3OXZJyfvzyca&Mp|q*_}Xr(@GHD zTpVB2%(0;p3}inKp?x=ZJ&A1sA!l)p$-`lkm#|t6jFs1m@1;eW_L$Z7BT?I4@QGAd zivMo><=-};d|5vf3E<*_shZ&pRNi9I6JuxW5K}a&pce0*1IG$&3xVru@%!>?u05KE zsB3qGgDA?1ROeH)f@J@0f{ic}Qj0sIs_^boi?^eecPVP=5zuM!O~vC;a^@6CQzR-7 zB8b?$&~o)owYUStb_j=0P-`j%-_MW_C?uEXDOR>kEp9`xt(vo~3spq=+QQG))lbDB zbsN-RaR9~I^`W*!3{@K^ZqD%AF-T|iLD@f+9?JI1{tOy+8F%iI{U!8B7b2{RrumCL z{to9*L`<%WPM>3>584c;Asr_ru{p11-c`=O)7ho+VtKJlt-ea98hNorG+d7*wfIY@ z&nt)3R@Y&|ABQO{UVYU~$g^Ajuvz=C1+U<77Qac!HsNZ5?CbHy7SSoLB={m% zZ4i}FYkhtijB7>9@a|edJQ?kW1=I&K?u#i6ZX}%3DdhjGK6aMPnb(>JNX~|G^o;j<2Y7li$(163h$Mu+` zzv`2;?wm>5B`=*xox)E4wc{89MMHVzYIKOT;AR1bu(fapUpa`{gRk_6zx(l*f4BZL zCMh9TfeNZyM4mvn6%@4`%jk8XV*m!+N2{BFbgYI>k@EU>xO~a-;wRCb)3sS%?5Bpo zTUH;O0#ef30nXO)CQ%UtdIOCCx#`6QN~<}zk!WIYBk8UNBVs~Lbq$@TE~4|)QvM7X z1P(e+5k1HDe&aGaPZ9MGpQqN47~`oIu*p?7pptkH=&(TXQ9I64&rL_8#*u0RvX@s~ zMv{!VHm+H|_)N4j6NGHFP(zSEc^IEz#1XV4^gu3}jud##swS>{=XnA5H9SPSU2frHt)c6ZO zy}Nk~We~f(+Cv#`4ricuH~+W=8HjsT)g(+59~I6(?@(1y2I6B?^=``WtsH8C-rf8K z%0L_~@nr9ZzPj+K4xjj%|B8a+Gms*M;3$>PxcW9QGmX%l5IN}xdVBcD%mcwWrL4GzvOUwx;?&rOF;&>ymi0?sCc?KYY@~Bih&tfMGzCtuA_zKY`oNj}!f_F?6 z+0u=+aZd+FvIcTDu|WK@&iTnBGdg9N*iJZsMc=|<0nO3cV5_C_fn}0sn=%Qasuv0HnqkDN(WG~~&yG1W2 zMfUQA$r^aS7!uLTC3@n!;l%yit0%r0PUQT4B$iLOl%W0@v?jEfh_xpK08>I;bU^@6 z(S-grtd4?W?e8O?Xf2mU6HctsD$;Nwc$?P0+;FQ0`5`^=rf}kZ{+^!r!*C+!O-L;7 z7X5P>)k3?!nV)C`9;_7~#^D2a2AViUqn|rS4&qvm91SAJ(5RsaAq<%K%FqO8QkZ4` z!~oa75H-Nnzl#{)kn*Ks0{-zg0jcukVs>BF-dM*R6H(pA`3&k>mH76Q@eL^IqU8D? z5U3wBl7rqR8qD?dsX~03WqiUNG*;zK+mAt#v}AIzL|96Vm?5uNVGY)X19SJYx;=P6(P~k1^R}>ReJcN*$LLR} zGq`@SgAdU=!@RKEw~~vh;0mc%N<|W#Z-il)FjH+#;;+p<6@;A&UEz^A0cMQzFu{1o zMs^`1cDIe9EmakkWfKQJP|5`i>A1IjMY2_5MbOjV4l&R2@_EaDVX3AFO4iC$-;!(L{ z0WpR2P(_(DU{+eA&7vx-HQcJOW55rI5%ELvMX-#NDe8#EAN65sb0t+Jmde+b5^SUr z!A2?&Y^2j`P?%K&D^hvEpOBY2qE^_HCCl**y-=2rJQDp<7p=yFvIG)x-2&0s?immC zoIMg&VX;gVCpt4E7bI`WAy?h=`7WvA(8|YCp}VAjFq%Y-IG1(eZ-l&GuKNNBbIQ5z z5qyQ*O;Q8{kAptQ2A$7En4a^sF^8Dbm_UvV`QTn-*M1VUpCs*PEdB7Ie?ASvwQ;CC zkdq1s1p_(h+Rp^-XA=Fi=VYLo=~}_NW&F11WMjhBsWZ@!h3}3z69kSNCrBa0EA zLzt*iP_^L{i!58jBKr$f0T&H%LV?99!AsbCmKpY*V|9Z;TayWW(LvlNHfjaq5buV!|G8-Xio8rbC=RYixnvK$6Ax z{s#Nx8nVz6wPK>N{!RRWhlHt}bT$|)@4#0#?}6$9v*G6N8xK3Q2h~p%X+aF351kX* zcPVD0n-{%~>gI+T6$g(8(Wpi&bSW2qwG!KTB6x@(-F zlj;$sMVtQ9Xpn3#K7+Wpe7_#P@SPu_(vVrkR(ujvJp4za=l_hP=Y)S3qURzY6aNp8 zHykn+kbprVUEu~o08q7@#1cgaW3-|1v$HTSl%7EQ7CqRNS`ysQvI@&VSVq()wUhsr zLS5xbL)Iay8zElRoFuj#hmv?fVKjjguYFNuimHeFywHrXp`Ejx2}Jm1jX(r4jQQ{x z0~Jh|D!!uuvtop!<~3MVkcipwrF;zl>gFH)S;v4MLjfoFVJapjA+0=e67JuqLt2CH z@i2VP%glgTVLR!N%Hkl!z)cMgJf!mth7AaeUoXMhh5yMbZ3MrLQhrq;pwU5=-dI3$ z$U_i)2`cp+^c~upnkGD$X~8R$#4|5D8zd)3mG#ZWW1Ha zm*|4V@enlrNLNYWsz2wX#_B5|UA#=Um4GX^)7DT8hxr9@vl`7a!92{msfm7cltca6 z^!0wdmM%Wm;Pb1M5&Tuc`9MVc72kOVvt^lMDhx;|&;U^RQ%#SoqnK&Csr+L58_WOf-yAwsBu|G zKe3fDkYB4)t+2M2Qow|P4HN&H`OEy2aHG=_)Md+2Bkd=F#Y?Gj{1;f($G&o;yjrPUelp(PA8~VY2 zfyK0M(0}MjoaNoXVv@Sif1BvHeK8qPm5%O1Adavf!9VCgI2%=<8#IyUSjg*}&hPGjSm zdbjT+1?A4k#*JIT1$gc3`*kS*Jd7xI-pbD%o2c8M752gv|jB7{UwZe>ax{H<1;}k)VnfxY&)XhW&rfT`58P9 z6%g&aD~V6ViefuqZPA;3@^p|tfI)}17V(7BomKohSN3WCy^wuInak<)U`d!Bl;~Sg zlo|I_o3D9BAa)hjIG=--LDl|v7(d~o%S_to(F2XXyd16%0b+r}=TsWjP1)dRu2Yd< z#iU@x1hTWONL91O24AfKP=b|J!O8`}N)LL3?e=o7F!u_$2!B9?X<0%Z+m!aUqimD7 z6>|#F6V@7WIp($hArOKcfw9jV6Ca6JRHmBA2~wc#FL?Sk(vvJWcjbQU+s%Z^g5 zEso~24+7E?q6yrH4wdpjXTfH9*_-qgajTx}$Ai4SU=#Z-7f+qg3?qmV?06h4?%-<& zkr;ffNBrH7zr1>-m;>;+b_lx(zj2>PJs}6HA*|3A%aOU+>Ll!FNR?!A4te6Yr-Sl( zy0BX^LmiFNHe5PtL@^2QlK9V&LEI4x-@|^oZlpV>4{~kpfHI6O_daM&cp{UzHb7C< zdkfYfDYgnWWjV__VId(;E$i&HP-?D?BopM^a(1a$FJE-p`*# zb9dPg^@BX4aNHN<s~5K)J1C$;(} zp;X^2laz!ONU#B>$Hp?zsK|^s_XsB8g^dvHX5eFgnt0|DG$fd71tjy1{I)t$aa z$3a2bjVQ5NI;APqooT^|e;1RS9hmrcns>TfvQ^Fw)I54AOc45EkmeZ;kh9|bj@DrM zBGt7!_y|H+424xT!u;cWkRxohkcg26$HQ?gGdWl>PJS&j5xbn&+uXrNpwvb=Tkw$t z+=d$Tc0-mM^dkBu?t0$<>2~l{fm5&cpaa2I38#XOfJ6Q{#O$Jx={da@(M-B{2J9bt zzXb0Q^zP@$4{9qQykIqRb;Rz3&%KR|!Mx*O*hMoYF$6jvVDI~yv(n!G0+ zyQY=$$1CzCsMItc8K6Q!~eCjyrVfzr;lIQkoI=%w}>PnfGHgom68`(jiw7|L!kn3*lxg?QFi};KeXRK7=G+TcRr65H2`P z%e_;4LY;pLf8w`(1-kQ@r0*1k`UHGPj@_3y_7TKe0BnjcH(9Q`ieQY0Z(A`1C29qn z0bd?^>(hN9 zu!abR5f3PXl~^5}VTZwsSzhGbG4rox&C}fchv?S@LhK;&OxnL)|C=+vul`-2R-umT z59mLi@J%pyJUhi|_6!#y^b+nxJz(h&6A6dns3J7p5{kDV0?(W`-a;vsYZ^JyM#o#& z#Ef_gX{en%`u=wiOR22@ncu!rn?Ja|AV06O3?)6&PjnOHq>G&4ZcnXL$2T%Vr5;PFvrf{ zyALf1X|30WR4fgMYCYFe=%5`u{^04L1|mfBg>lqO+@cclMAA2Pu$R&5mHUW0M`Uq6 z40X|2ncuiZg9!Ng-W6Yl!(v3(=l7nMT2okZO>9?wc#{k@=U>-{+RoU(GaE zt*7UWb@*FK%#wc}0Lb8>3}Efb1XX+4rBDeY@wf zknO_dhamygj5AHWyNI38rUeqmx+cWn#2d~Y=HN|1H!!zbG57r#Hnj}5N_#GH^9A?N zT7cq>7i6LLYK{}b)TH3eZaNvjoVkNIZL6hVGh~?~T}_sqBU|APq)birb()l% zXr(gxm!=T$+JNVcs(?{>|~Uq6p(=B(aM{dc$idr-Gq z$#_NxB_S#P)0HGCP7S^PR=g*N-k%Wf_R#x0@ov)I4J-diZvIvgdJ?j1WmqNrrJAU| zuKG13rZB}N%U1Lf@P+n?uv6=J`Ts-Ry8uR2U5no{nMpE`!81tEpg~d@YBZo|&;kP( zkN{TDSRfDOVJoJ&NR`42!InVcB*Ji*N_(}fecY?H-rCod-d4aTGl?YOoq)<4f_n9Y zK@AU0z{q^Rwa-jmptaxa{r|rY&75=Aeyz3k+OM_OUc0Mt>(fuf@k>(Wt?l^!^eVx( z-2CoR{*iBWC{@8Gh4MR$TW|ZYqh1MW`S)0dD)Uq)V;0xI8uwi3>zuVDA^0YC2kJqkat9b+>1_WXWoZTIlscl~Bn z$8=q|GF(3?zwxD=yvP2A^6dCCj_+Z0t(@F(hHXyu(C+gAbG-Ut*RHsYO7G~3d+h&m zG_QQ5#k`5TB#Kz%nR^@f!}+6?mW7Y5zalEK-67jf5A~;owRpbay(xI7%LK1>jqV$B zc#~%xeYZHg2_@k3ria6uM{?r11WYdnRevQlWwg_u8jmg& z%L*qs$6K$3X-S^(iyz0f4kVV^I%vDAL&{Mo4Pgn_QQa~9)qnm2{EqFPTNK~lhvnV* zzU}uH;rplkVtgOf!S}eop?@CxpGmop{fDWN{|WnlQ{2J+OP6(HzpeD*?7xyN9?@P_ zb+G@DJG-*~KYrPj{W1O@>&k!8gLcY$Hw$+iE$tmtCf2{}_Kfzq<&3iu?Z4`LlFh2Y-x5y76bf7wW!{KapUJKkvj}_M0!k zPNyE<(UVW~m*ZUUDcPIfAxCTf z=Yn+C{T+HB*qP*Tfk0Qv79|`2wSetOV(jJGwH;!#usS zr|Y^N`oaI4U+-cnd%^f}3BCP4n_q*z)4{LDOS|!_e9@Qj>nD1QUxD~bx%twCUq^25 z%C8g-R`ujp#R;)0F}tHT0+nuybPtuR?NQmqI{t|=A<8p$bJKt@q|$98(1I6f49&-?&qdpo(pgF_UWq!jJ_h)7Zq7Y-xG5&SDjGVwJ*B2YRe-DdTsXZ;40~nJhgMQ z+(vzkDnEO>UTrwOji!|C0Zx8*RVjRRe6PMZzIXgD;ahm$Ka8(_GCtOJayrkL|C@{Q z`CnOMD?WcC&S$kB@XulPFVQnygxLtom+|}J`2XRVi{ihB(ffZ5|AT0VE{;F;LZSt= z2OOptUGObp+$$cc&bM{@{sQ_%(SZi!Rks>WPj=KF^RquZ9j8B;NYYMFbL1K7Jeaf- zk6C|?>HkpuEwu-dBME_T&_twd>UDGHa6#I;=#OG_$CfDnIKJop{i65|?j5VIep83j`Lk-TA+&WJeDcr zmG8U^9Otq5XqeOK6s9d0Z6?onZLN$Z!SUU1Ofu(l>pI6@ zxnTR^`{nFT8-IQd8zg+y>=Pv(OUnRvkr#xDl}1s&CHO(<7n{pR2g{2}}SR4;PE41oE&5b~Gz3C6~eBJrfXS!;a<(I1zC17Wsh` z=(|F)uN~jBh=umZY|rpGCIi0&le-<FvkP}Sj``MnLlX=x)FfkFrq6VGF7wUSeXigHeDpD@rgctX3S(0k zyyVIhrmL4+@qa)WR3b%uOUn2otMZGN;d$FvtS{keNteDYC|8@we*RZfPiTQL@shYA z4{9v=#`rHR2{nK42dF8uL6+5N9Sg(4*uv0MfApl}ZNx=8AP^rhjIXQZO^TDBSM^s~x}_)O$Ve3dHRxTN8y5bJi+z_>*Z zizPg?>!(*=)lma;Vl_~E!O|QYVL%}T!hq><+OJkZ1^M}M0Q2I4>vQCZ*x^I{i((w% zta#Z8^2GxW4TD8_bUM4H*lgb_ouxzEUvX%&XOHPpf<5ho@d%Qq_E@&9?$R)03kkD* zwsdWusbA3FV}*^5o7-2BigjEo(N5`Xk2L9vv06H@D)+teljly=(NDO`yQt zrQ5_H`In&Pxx#l7Tq~G9AD^~HFc;77JH@WpWLRyE9q@%rEB_(6CF_fs^hFAFo9ZjC zpqrm$cHk);uij6Haf^%;+f<~lace5}Q*HV_eXGai(}=i-zEa;Mq23QT$*cHd2VO7j zYCH`bdcUH6t&gIF9jazI(_q@-`BIHnbC7^s2MVpga471j8B(WrND2MMB3Pot;0?CH zI+l@4f=6M>p-{U`#!lKAI>4_~4OO8>65&7B5TDm?QMFKWuS{&snYvkoiK$$k(ic?0 zvuhwxI>S#Q%@>AadW=ExBJQ>hOyDOrbTJrneH=rr)stuEBH)E~yr?X)OUVSl{glA) z4oG03qvL(Mncq!vm?a@zrwn!7^6Mk{<(l|w5`3CcmY^)1$Fof?g zjJ%kJVMQ01)~-)W_n*Zz>p?179O@LX5%gKV2I#u@O8`~ zF9r_<$780+IC)``2G7oAPeGt(S6K?#1)QtKdv-1RBA11pyJuPY&9xaOoxZcPGUDV(k}h>ZdM@!aUtDntdjF?eUI!Q zq*;usw{&TlrdTnbw==&|mOz-xROH=lTuYr|=|}>iFb#9~Po&P2E15E~>M+Gnw>!HV zKbK3`2G-=Wed&uOwf6$KI?IN z@NT(dGF7d;Q(=nzDSg38L1MUY==a(U;nJ^bH`JGYo%1>hqT&cx6R?I+UFxV=FF48) zX>h3%bmz~+*eu}Opr7*WS@sKp(>;6OBA1@aRnRH=)W_Q;)XVj_`O(I6o{!4zHRmho zKLZJ_o03wVl2Trx6abl}*GWk?%BecmlO4eo5)7WDDH43ChaL?(hja@5rewS9Kb6%R zR8t%*dR!bK&bfE)Y`ic?E0w&|om*lT=*-7YQ$GwPM9!Q)mC|1q8Z#tocZ~EO$B`=S zCEz}uy=A=up1@3t-jCGF-02ejQ~g%SqBHfZSn8J~^v9B^N}cOD$8FbME|t10;DPX& zs^rc{s^koY70GR*q+Q#Qwijs=1N{PJ7P)*a*5$B#gUK=hq8|L=_N?mZT=YCs&Uj=N z1jjszyjIISl?YD0+y^};hv4AQ&9p5`Fuh7W)J4$!xCr_vyvh&SJ>t@$hP{nlG9RDl zp2FR$dRu;8)@NCpfxcuyXE3xZbLZJ4;(q{QIT}g1yWm^#`=3eZ4i?xkxO92y7W;4< z|FMjpm|eCDala7aRtrb-g~Gd8h5$)l#ZT(bwHx-7-m2YjfD4niExUzq$*gpk#2#cu zbpBk@uacyf3E1x0zpRfcvaDVI*t2=jPhp5$-<9cUSiG20uP6SDUt4tP2_^EI2h@aEip@%qsp1|6N{%W~Nae%bnfQ z9yyKR7gh`XNqUNY12{N^Qv36gMWIkJD~8AOfK#DsPw9AJKoVD9hZPG-M@!r*W8}wE zhf4>WSZK?xP$nn|Eb463{!lqXTVtnvWG-4Q%~cRlh`~yap*@C8o+ZerV%0CF`$z?` zS#IeHoNEO!I8k4EpCI;d3^8GND$=;8^mY@mYR|r9<0Qs3i5q86JaxE~daK7~J=sI< z%dYi*Z1 zz%;n-&^LpGv$0Jzm~>AA?9R|nk?qj3?*yH% zLeG9!btk>(*b_l4eUk3n5TFx&o6aD^b8^}9@XjT*4nGydcPUS|^u@i*zW8U13J1!* z2{bdfDB5^lzn1POeS;J$Wji~|j*kJVcmBPgq{`Mjhs#m|bl-1}^15Bi)(e}&e)ebP z)sQi@)BiPlRm;sXigGCD3+|_G8ll23YOngcA2RFiv{yCC`22_LRTEX=U(sH56r~|X z!JhY1cePi2Af3Bg-wjL^9OZnDxU)QB$AEr?q7eSM;*omT7C zZ2{ikqg&!~6>K{(P=HJ~?5x}AV3=jZQV#&z zf_lK>*+HL}PG^*%-L->)ay;9#HG?rLC-Rj1f?^Pyr{-f>5&fk0!UFew95s1iqWeCq z@J9rP{)@gDmTcFm=FdmK-km z@qE5`p|&CYM%~ahjMg?>rfu4s^|7{Tm#vgf7H({7u7r7smU3K( zZ6Jq)V5)<&AoY**3O;HA8?+5c!z|^XstEw)dB z>9^60Gt}@7EuO>LW7}kuqT)olsEpzMWp11=-vb|CHko*CafY_Rc?UP8EpWRadD9m1 zeo(T3dA9n-vyrdIP=h}E9YLoHY8tvw0~)U4KD-4dAL{~D=(^|Tum`L-2>6gONmrOjH7k^!~ z@dnCE1>;Gof)uvP378ni_PRK>W<2|(i(;G##*>Nzm)K5wT9^DnVFp%;lc;j0GM7Dw z5V_%GCNqX9+K)b_QJXDsOni{10M=t8UXu2u7G+bpzWA;>=4dHOo^4z35`M1ntlr#s z7EYuh#%Z!@Uvu1S7#vP4rfO!Pr91!yg;|@m7wRZ+XwW`EZ={bIp#zbo^uk_3^t0Lv zOtQ&oB&emq$tj*0#Ni#TxwMt1KxFV#_f%LnMcTF5dZuO};2P~W4_Ib!0W+Be?%|Q7 z;Fr|M$i{QphL8O3TZ7Ka!PI5j3B_)jUDl4Q zNO6Euc{}{atlFlx8qe9b5+OBPCUtj1z}8)eEXZTq+i-^*t#N>*dg+3#f)TV;)qI`d-X>w7_=Sl7+-NqQ7D8RxhSb{xsjYgozscHo))p?d z*|ZHUS=HKxkRX*(tXCH|8pT=l(nE1UHyvP$wjoSWFwcHRaUk1vSh2-(bjfoH0SY%| zxEahv>e7*QFcUcs4rbTGTyLveoJ{@m9i95HiWBKcaf6o4sC&Bl6AA<~&p~8v8t38z zR;~bg(!qD#c)Nvv#dYHyQA^!;b(SGe)y^a)P}QV<-&4PB>et}+B@glIs!B*K|AMcH zrCVLqg4p-zKfdH8LLj$YHez0sXu;QTc@br6^Yn8n4F9xMIkf)Zi}EX9C&)MW+7!M{ zKd0Z6z2&JuFpVVWdUI0)Pr7)0N^c81=@eL%e4@vC(atjvOqJi)&X9qpO2W03eHeN1 ze7OsMn=%H!)H+23sS9gU?olJvc13TA?e8e{eta<9+c z?LT&F;7P$M5OhmXXK&T2YAMM?$;`6@rJK8;o0mB|R%BBv)PF}0Ov;gUZb^*2PD|68aC`_Fnbzg!xU zQms`g!noH#YR%ttYdkBdHeD5^{WhEwZc0jN$PT5115fT#bz=(MA>Ky?MfAL`KwnN6 z`@@bvP{JaEf>jcen-zj0rp7a3Ayg&u8K{y3dR3;Bpct&J&v868N^!ij?;^XWesPK! zylRRgl4QOTr&lb_A`Jya{gPhsIK85kL6LD&@^mF}{;<^)JvpIZ@80AEKc$g+ zf+CUHW2BuYEHT-wW@*PS}HQ%X1;FirJgOIH;6!?h-2{@qcl!mVF*vs~C(vXnV(^S33sLLhsKR>1$ei;FwPBh6(} zhLXBo-cv~ii}`HupB=fZiI=TfCW`FE`vgcF^^PL@Jj&hW^|pq9a9eqIy&n z>Q&NOUq*Rr3EX8zfj?YZKe<;<7q(G6PIeqBLhX z$5XrfQ?vam1ot%2U8>Ut*M&}La|DZ^$opX>^@r2lM$>Am<#1xdkZ~?nEBmR~(7}_^ zm0Boq(RKTd?cZ|rN*#5To2Baq z4@)pF%Gbo$m#22gh)(&WdPH!tx7aG*lEEQR`IaQ>x8|*>^0nqIN%l>6`Zi`P*;|yu zh%O@Wxf}eSl*Si)5qCe)z+|Tye}b>cv&49hFCL#9OwnY*Wp+I=C5AbZ8xa@eM=`2oZGbhgX= z;c~)Lwe?9)v0F3My;NI2$;$fS+-o@!@3%+QX#K7uWgh{I-rc@!J-+Qdz7wAk0Hb{@ zeNvC_Wc4kf=Ti2`W&mY4p2E8bdLx-5>Zi2d?sSBY(Q7cmq|~Q~Zqn5W>wOVeN;ep@ z)C@Ddvm4xm^|=V_l8eAJ1!LMbl{vSpB*9`-rCV)i{;01^GFV28di{;*7E9^Z7CA=! zTS(q64}T0_*Nh9@MuaC`55e)~8kp+;Jg01Au+m-5I|iO8Z8GF1Q+~$eZOj2INB9L| z6f;|3PMxM|gDHM$aMIG3FhsVDT54Z3sMJ0xZOH&_eSR zaI+Vedps@{KwNT*IGC9;5V12liJ@puJ@Cq%2Ay!R_GbN4Sn^GUk{KwqS2jz}%tDLC z)_|K3`I_X^Q`brrn7L&&lM$JnWDT>S=KEf9@z7{uK$VqOqC8K_!=$ka_rc zn%qFO<_?MsI%PZ1?O9_o`|&G)aYaq#ClrHh4-GoU2aC?j{l&$)EqHrEabWy;|8cAD zr0|N&+#-MonEykE2$jfKq^~3trb--E-s5wmKK-9N%f@^~q#I;n(6v?sZBI-f)|_VE z;(yg$4vH4vO%&#xJNsTSx_wBg$4amoE6H&y+sNU@Cx45#d$ta7o%>ymO)X_$!f(30{>OULx_Tt{uPjA3CZj!$~ z>fag-*vH)wm@$s4q8%0Io2cmJJE)qm9*Te&uQj-#_+M0TVfYt=0dQrRqbO8Bb-9 zHNCKCkBUzCWm#?pCzo{aV~S(&6eoQ373jR#1+yaRMGP~g^MBX3;ea%#)82htuhlCiTP`>b@kUW=!^WdY*v+vEATz z8#b>A&wKi7xxoyN`D;Px;D5JGw~D_O>}@AzwTLWke!w&iL7#8GZr9LjBr zOGWAKwxuoRw(a6>TZSndl(B}mZNbToGETVAZOh2tF|8;+dbaamuQ`3#u51rp%7H+c zE2L&^D_|!i-)_7&REemI{w}?jwHIc&$(|Z5I1GMg?NbBwEVp~6-;<-Q`6Y>IUz|Co zAz9Hn=m+rWWYvEAnd2#ODsUjBjc+Cq-M*Pbbo*u!(d|32$9GbX@8quEfjQ=`=s3{L zs7n@d{J9o~-x7+5;4ymo$ZB$&gmZlkSd%6C<0`HduW%Xq?m@D6Rgs})}WWd49S7Flz(5v&H?|pPS31sbo|O|m5-5IkG$qfUQ+CQtZ(t(Al}`L zKAiUTzu}rK@Vi&%Iwj%Zk!;D zI_r=v{Npd~)R$hwcu;?Y-a%i8-C(r;-@?~nXBvH5Z>x%WFV!_{VQ=gP@3u0+D@%SP zjUH#`vkTy&!7WfxaicTyG9@@S3y>>1kIYddMoWIw1&`Q~=&pVm^G%YB<&fuJo@OcX z_KGe^Gj4yH-2BC9;uC^_qL*O_H`e33`k*cFD-4_Yr!r}(LbLMtRJ1m&w5HUW#O0r&EF29wb z6@zfv#5BdCFBuLVefipG=Pp`W`NQ;6MMdyBzW`6vXN^Z8QlFej9+&FF=hIW(Nd&!? ziu}~~k^j4yOqYhn0Xv0LC!j1U#mr#Uu`q$)=_yxcSC82fzYIG69#Mh74~K;_sK zd#BS#{$|B%s$+gaiJV{#*o=8|5gEOuD6rUWZ2YTLJWgF+p#RYRQn}#XQg@p}`pnbM z&5b1c?{`=@=w;k0d2p@fZBDT2ooD=xWJP?g0c8~V>EAkS`X#OkD>0nv$nIO6N3i9bQ-FW0_*oJIt zkrk}wKeZQHy-NtWO2^X1L9;Q={ud?9Y|++lWwU(B5KB3Wt^P#S_k_=}&e^JMvQG&c z8vAeHt<6tZHM4!y?9Xd+&sz#3y|Y8BX1CYoes0OZ_qXp%a9Z1Z+ud}s?Rkn*1x7FQ z5dJqZK!7`4BbUmWeSL157iI6Xv*9L3O8DNnaXIQvKXfbl!R{jTe>+b94`TEiUqt_) zfA2wmLQnet^1nns3Ki&Q1@;x`XANBD$o_Qx(EI}9T_!NJ8slA%3nUvu;R3UD<1@i^ z3N4n4=AH=QBopQ1bsXSfsFyL}GA!t7!{==NretmX)X`4ukKt83Cb1+$B9^@^#~;id zgF`epSVNp_K`c&l(dsjejo2rl;>$AzNLNXXom_oY`Deqty~;n!^4kBJ6|qj@um%$c zZUmZ(tm&6CZD92AoZ?8HrZ>J$gIwX+>SGb)>rWcIiq)1n$-y^lEYZuCxQ%ghtd=^< z)si?j6@-)O1Tjtw5DS8AwULC@eKEIeszsy{kIjf_ZA4B8I7Ga`9QR$eII;_V9Y;24 zRc>_5FmLZMS>B}D+^FD-Aw9PEtHhC{KWfz~Q`C!Fdpv=cs_62|IdkBH@X94c_S#62fCaq2yGu(R? z3_1R}KQQf#_IfBXATayPOCxR^=ejPey>K*;+XfI1!`kaf4E;Y7-sWwTU@kqqSJg87 z+CIwH;=2SVKhU{IMs!EyLGAUGvxuhe%&O0tc4Fz6sx2!9=(%nBHuB4=_v~Mkg3G;d zYpW;sjCYXnE(7^RSnJ;wU6&QHtrph!5?T-H)11gmLf}SPBQ~N^UP2%(JJiYayT!*} zhj6s@6pr>^#`*n)!m(27w_b!J*~2jqkuP5&Ca<~e*`IC_N$}*h`;zo=P)wHNl@+&1Sl_D-U1vGvsPTuPEx~J&512fM=CL<8nO?z*89_|5Q^$A=& zOR~yz743lbdT#V7TYW*l17s}{m}gwpB}ZebWH#>HCSQLgB3dPWV&w2v zz}oycZwTX`I)w4i(tL#RM#)_-YtwfLGA?+Pwoj{ zqGzVzrTyP?aUtD>km^U-i!5tfEp^~aZavDS&RxZ|PTv#h(?wvjcXzE~XZ9AVwM}pE ze_*e8ryPXGKcC}GNC`jhpx)~fhIkMWM5^BF)SWN>{HAfPNzmKkAM@f9yj#52RPFX& z`+RTj5Lp-9{3evj(&z;iH^P~aw@;pN{6nfj8p`Y%i8SKHc&q@i!~vy~Nx)HNL8INp5KGYS{oSvA*V@>o$E90Kl(Ctxp5qc8HS0jsxG%FrSech+N@=KiA;M#u; zUwTVPCLj6H{uz8_Cx%!nmy8g|v-L~^yMf0j@b;eIDGJ=s6FftK-|PuqsKEPrf-4pH zP*3m^3f$Ba{Ja9c*Ax7z0vkQSZz}MKo?t_PTY7>WBZT-fJ;50Y+}0C3Qi0ohf~Nw0 z*76hd4c$0+pNee<-VMA=fgL@;zfxdlPw++scJ%~rSK!p1;3fr5>j`dA;Pjqg*UdtF zMo;ii1$OrYPgUT|p5PJ%9@-OJuE4{4f`6sJBYJ{2D)7jj;Oz=LrYHD41f5qI66C4%y|35Iy;t>~oKIvC>?(-mG?O0IXU7fik(J-@pSODV&hHcLUm`t2D6)f& z2W+J2#<1y6O2I~!(H*F0@$UsHS&li)MHlt)m+62aLv(v^6=aXk3-rl@)M)=F1m_ld z^4@Wc1`Ajf=0DqeQNu;FLC;7+QMmo)A**zUQ=T<*S}QrJlmWAl*dosvQ$;Zy5@!pk ztoN3uqIPu|t$$(~@2M@qll-y-y@hkM(NVeX0(Ih4domQXZ)VcLt$V(VX#bx}?p#N4 zMm9RX3p{AQG&sfK311l+9QKYIYoSjrz0A1da>k}Zfd|^~`0uW>;fKT$xeTQuLpnS8 zxot(joprXuhv~s<@Q>2QY=Gs~QQo*jyV6R=- z_A?$szo#Dp(*-dK`f&&CkAwn2zn}yCNP>P8z@&VTV*b$hw-6s6<)tTyT)JU z;K=#a=t-L`{LoX-;CuhN#E!jaC5;VEozXH z#i-&}oXv1}oE&|Q)wv&V7fA{gU4ROUCWfLlt;F>(MW+&#o9BJ)R9(RLp2z3%j?3a8 zG97tGF}o;cQsfw(v^mDF^FNyBLmYLl7ud{@bEDegIxpIjO=yJ^+z4-gX1Y?t@S&Vr^nD2a)&HP>+)aUxCKNMp;wV*G&& zu!Z6xd6Ot4AuZnXWWs}SJF55f zHw~JfQN*ex*RiMGoPVkY^QD0Z*N{%(x|kahH6tz=`mZw6l7XmXA)*kU@}hL>-)#;o zJte|yDN!>Tb8c3mCMNp6*q55U=xyegy0&Es3yg`hyd3|KDU@T;x0Os(<*63Dr@$Bh zJMy2M3e3pjwW#RXJl-#q?d(tugrgVFZ2$}6aV}^N?iJQZ> zs4DYc7b2Nv%1j?7=Cibp_LqtNoY~DRFr{I1kJIN*jFQA0A5d@k0mr;&h7wWlvr5o& zu6jly1S+V%&YZp#%c)?K6vuQy6-V=6V@2~{5{+Ctf1dF$k%}TG{NtkDlV6-Ci3L4b zy~POf4WWCK`3(*%ZWbQ-j}6+hQ*pC%=$}&q)$2$Yy;;~m3*=oXYsbpBB_BhHSSIuh z**6Q{$w#s8g3KcBINJmj*@JV$v)u?F#!j=3{ZdI3j_Xs#$f>aLslmI`Z1l3@lOAlz zw4L(2?Hxd;?D?j1QEwbA*(NwW^^2VT>P-AY9cOljTDv-OHs5%XogMm?jCs$nH)?s^ z3*I;pi*N|sOV_S%WzKd90@1?th&9}lSYymH6C@iaXj73iBaiPqqgtjchz-K1d5>y#tjDO+Qg+Kuo~&mW2|1FkhI^#z-i>Ah(4&>yC+L-!pWaC~g(7#TIu82I z6wn=Q66{r<#E>8FlhF7xM`NP++;h)ulJq8kBqnTbZK7afrGjK0GC$GyDc$Av`Hqr> z((PW)hYWNZr`?0;-YDp_xO}sp8N;JuqkQD$GE_`+Y(Y}bVhn=Y? zlGKRMMN&*=Pewgn)Vi=;9Q5QGs){^Izkh?Z;Apk+Q=or+1wB8&5)nI@{`C; zSY){IFAyC`G;ZUetq;kZNU2z)ofKj4ROYfE*M#7d8pajP#`_-w-CE)Jt4=iv{an~4 zj-DDxV?54A->Teq|7vCQlj`t~T_{9rRkCqYmna`HI2&&ekD+Utae#U=ejz`9=BMOO z)r=%-`7wSV(j(Gzt+Bw2oKdnyLN_vfGb}39%rJorZ#qbU@o`x+@c5Uz%_t>HChFrX z?A95(O+>vkD(CzJSf$_6+4n^gmw}q_L|Z-k1NQHXVGQv_%#@5Ppi>6bYj|#FKC@1U z-;~11C`p2a%(tgJD{lrj-$DC(on$BY?lf)(ccT{hFw#NBKSZ%3jwlm326CyjLxP+P z=Ba{1U*l$y;bO}8oxlZ)Cn!*`5ZCQ8*JuzdM)6^4ueDKQ1&0;M*`el3;IJS;PM$Vz zZ+|oaKXkKQkzD=ezcEIOgS1c4QRluF;SLnxLu@;n#UJyr_hhK91~C<8yaECp;6HYN zcU{kYZxWlW2Hyzs8$Mk+E@K05SwlIDM@jgMl*f#UCgD<0y*|DSZenat^ha&Jd(3jC zcb4OwY$8gown>q1T!3Q)d#V$<_3r5KlFbvYL0FoYMsT8v`v}ty%%G%UTfsz zf>n)V($OXwN8wv%vj3!}MWu&qONTk697f_n)6I(iwq64_GHTB6Z9H_Hv}~<%fnsh8 z%=Pz?AnyFlF9-~jG{Le%)3x8|r|(7mUuqBBFbzh-aPq%hkUYE5Xv!=24^4QfN^d+d#x#TDfEYTI0Dn1zT3!UNXxBJZEPsX zYVi&pdtXw5#hX5Mp*;GJ%}cUz3phX?$pCE@Zt5Oe2~Pf9)_{6J-)sWP&LndOC1ozV zX?}8H_Ld9EHH&2W*;-?vX>q&wu7p?~Hhp%>+&RCe$Fz8hP5SM1i9)-yLEsjL_fC1Z zypuU0WNi>F{md5WKBu+#o02#O=ezzHVVl3+VI~wyv1bMHX-x)e%K8iwEd93vXNS}c zMPlzLu2Zw>Rex8nzcIwp!eN~HQ;TpGSoDOrvv8lP877zVRaqh*5WoCv&f?3;&t@!6 z(*E4A=Nxl^@VPxQlhWyZHAmOQG-5 zmjzGb5I@sSh4omfAc(mEjup89_IZsU=N?eLcYCNE8bD8eTPF%2lp3iM|Y8MTe0@> zhs44D{oqbup8(?k(efsLn`QZ6G9l5&djT|1!U1f6m+wxg_Qsf#0hT~o2s$D`r)t#E zEW-gjPLuychS1Hfz1x4z;dN9#ItUtknfr(3@C>B7u~?MpH01W>+_(C5Va1+i{E=DP zVQvb_sOee35+AO_D_BHMKBf90RqA8Epi>{O=@x4GJJh-yo~;ynnOLk?t&z6BBUWKc zZt$PAdoNSI9Smihti<3JQb$rvk+_a`GdzPgNgS{3#n;4ZTdN#SF=h>)lQ)%%_{nO% z+$?_|<@hd@)F#?D99RU-v#7U+--UoP@P6@|{48%u!4ShtzfL6;VSIu&NgET!YVA>O z*N!%;K3|U5p3<%hhnv+AwjCkZf&ya@=l%e14IdY<^DO~$vaL_OdKQLjg1>c3J?NxY z5xZv75zVf$BZF{fD@0F~Ek3MLQ$l5_lR0SNYTeg*z`xHzHKt;8?jkHb9+uV_mQGk& zN(k4Y;$4fl*}J)cZ69wgo_iwWd6y8()&oKBFZ#|~aaZpsMO%QXm9<%Maw<9Mr6X~z|oBh>u)q9$1^ae}?=&s&j z_|M*5!+qa^WQeB;hG-sNKD#CLVUB|Ad`pTUhLG zT2bt8TjAXk6OZ8SYOFnx;eW4Xe`r57cocUAM;B1ba%3OgGiMlcq!|m7vGd!P6NRE|}j{cVQ~#?mktMH!mvsT5*8y%$nyGFW`Yp-B1gK?9I%( z+L`Glo7}s4bhuKA2ddUE4-N!Z$?ubu^84#@ z`F(Mj{Jyr7-{Lh-{#HGLvh*rm^J}kqR4r7G=N72PpG$cB>hY>y@z8VafvP8X3ChdU zyws_3t=J>!IqmcF0#&m14dy;Cn9KwdQZON|%YB{&N={uaBd8d3{w>-+q;xsK!f5M3 zq6;TfPFEacK6$<-+P|LgU~U_Fq&IkD@#bV5=74Bgnx#n1lOLIJ1HX zan*S9M#YJ>u$3N^5pqVcb}e&4?O@{5>+WIxk~t(~KACZ4wiRoIi5Y(pcu}Iogb!;l zpEozDXJO(x^LroDhuHh9M3+iaJl3L~d37lvt?I9oNuFa{RQ#eQ@-+Bs;g51=F^8P> z7JqN^$Bb|B>061MSRN~Eq50fOWahJ(@9=z&KPI3>Z}4|U5WP>uDZDw)ET99P6N3-$ z0ndoRU7he#17M#{<4E^+Sfh?B13q>=RucLu)<2hEp=bj@?m5P@cGubKqwVY5Y)^s-w*(f&<{ z5|V4-p;RkQ4kbAAQyy2M|pP*LPOAA6f`FMKd$sVn~z-?9)fzs<%Mn3~wecen|~x3nbr zE-9h!H{`H;Y%>u5OS8x<=h26QRjQjYZ?6V2 zI))op3-q1XZ1dyR-4*YUX*o+IymdqpRaKY>El*ZUzKBDs3?ug0yHjQfU)J)Di>h>s z?{Xe?i}(8diH;g^#xXQzGH!w;G=n1=7le*+qhcLt=90!% zAL745DBJzl@DM$@DvZT|95nP#DYAS@m90Ts`EkjmjpY zc{^~Gd3Ll*_Ks#bofE;>XM3@>Ob!?S1+iOqD85gs7E( z-5vBY_~Y&nPYp~1l)r|N`nl}TD|AP<%E&Ks0RF^Xqnq>WS8*cQ>^%nI`lIqw)J60e zq7#bn%0bqOt z_W_q@gDQU^&>G%; z*X4a-m-q6{cgbC$#Z!x+reMNUArTl_u(zLZ%N$v+bXUq_u6>BqS;f2ZYpbCG*OqH5 z?_p>l8{qmoE^W;f}KdpE#g; zoIg=u54%t0Up!1|pjgY>%stIaG%8;+xj8Jxy9jg+i}5bf!EOP@7^Wh`7^dE1OxjF2 zhrxqH2Zt>*DLajj942iIaK!dt|5(%iOvIS@XMjuPh@jQ-l**B&_J-so>3F`yQ!1d2 zxF*{HnzayaJ_ilJFN!?Tz^~&EJ`|oH?#(eez^(A+7#+M9$=@kpAMqR*qe%oILYiv9 zy&RgrTX@Yzz`pt{i?1i_cgFxdR%G1 zGI4fU7Bdkk8fc-EjUxa`N8S7r`rZ3DRY#f0REFJcEIT9HdeV)%zpbN-Wh=sa8{^@? z3=*m;_4dLtpkJ7SwNrhdfKD)XVIGqw&7dX9%W`hx}v6#YS^`w8Ay!Ls_#Y@p5(n_d># zmyM+Ji7mX#){?k>SxD&(*U`Pv1#Pakqjf;#&FdZ;sG0*+v342yeV8n=u$H=)?kaPP z8k>k&L;YNv?v4+7HujM&GVGCJ=nfgpctJ~WEu(dOu%l)gDvrBg6)FZbzzvg+igQO- zSjx4>LkzBC&DR%s<$|2nONzDB&rt;&E!Jv3Ng&6uGD3hJ+fuVWAU_lrqR5!V{#Ids z8Tfb-miaDEn&T{af<-3Xs$?=to^||5eDo8UC_0K@cjk}`)um+)8?K&3lK02NK?hMd zBuBvthvk`ZP7@XnA97zTY+<)_nP(+kxe25Eg?mJy!DgH)bcjhrA$2y3%w%tE;cjs} zD|3e!g;Mgtcg;cXm<)QvJ!A{V2EM(tIx}IBc#%!-60ai;XH$uj8KDWKn)4qjJcZq{ zS@?^AtNa-={sa3 zg$6paOm;(ysFWghKnoL}HuD=2Qcnq2Ve;(LV8W_-r#5AfEJP}h33xAI_ zlErr!s~q;mH5c_}w9-j2*Qd)>5iG>;^(Bn;x{8rzyhRK$hhZP%+>M44D%LJl1NMxt z{#(^g)Wql8sPGn@y8N^@Yj=$Ba-kJGD%Na<)s>|fv>b2wL!;=pdM^WZY~lnU&oa-unl zA7a#8e~;@RezXs5*}o;WE!@Y#`h*f3q;wo)ZoGe}`*3185f3M>Qon1}@6Y)~Ti}}P z|KPl64i2)Zc4+(l?MFV`zjfcXBPaH4JrX&x&N=3@OfJ}Iw-5vKhJFs#grOEc(C?^L(TiQ zkaI@x39Cf*pXvR!gJv~B;^BQ=m!t%_H<0-qB5o}%8vj9kN&Ebt4B zIf%%_utBSb>ehXU*-VpR@X$PNN0=gihUiY%DA3#RF3Dz`aC8PY4&cLHE?xLmfgzp& zh#=YXC&gxfSDHy}hWW@eAH#W&dyeD)MWUR|Ir0(pvUz`4Y6kut+7=^f-;N`1?B8~z zc7K=}3lpPe-`4$G)cYIzw;U1%4&NW*TVlO&WGl%=l0Ec?;p(vaVA>I>21U2F0kNzK z9lp|QM|8%8Ke$RR%a{>Uykv*!5J|R7ZWG_GD>?(#!W}!CjI!tJ{JXX$GPmgw|4a6I zRr~sq_9Pmme_ng~-an;1iKWrsYff+ff4w>7{9kQOe?Ws`HYa%5y&-KfgZ_Wkkm4Ha zuhgKvMBaCI$ooXbk4Z9qaKFTtjUN+f$`iYfA0y-A$C87?)=53%o&WESA0Z+hPOMkI z4U%Zs)BOIu@q<37&pzTEIj*|fkflbl&i5`;jo6YM0ST_!t{UMyhu;j?mkU_=2%xB!k09<26=O7mOVv z=t73a#*Xb~1j&*=7yUmE89p|G3?l_SJdI?;zHRjUTleocG|xT!$QuNQOqA=*hY+xD z`;i*PKN%*rFlfl&QLX6Pp`a2PrpmS}iual68h9Mq8V{F|Q$`M{e32Ppl_1s_J+l93 z)4%;7VM#x8Sn=0=F7PAA;xS}&nbr=OLWMq><>z-IFV*r&rdV_4;U8q zx7l&Z#j4VYRVjNm?9iX6UUZEMw+C#K&wEA^2XeV)*D#F~I6-hX)~?29<76^}0jde+ zB0|#}lmEoX=@n%T@v-l_bmNoXzlLK7PPx<}r+GbD`5&m~+W76W7GL9vp;4dB{lg7h z{t(E0Q(>`>V~^^&>$3a@!~kI|GvtvGq4D zXCa~I0O0ym_W0$D4|W!L#EA}%&TKC#5~Bcr*$IpH@_G6|AyUU4wLV~*7f@f3UV1!x zYzCCA0nFoEocI}%W4m`bxq)gfY-+Fibm=V*hEwr^WUIjohxc~Qk@=0(+ea;xLth(Jv*|;=5D5fU)(Iu(TC3yG} z`{yNCPCJbIr^qBN!#s;au5!#HaEYs z&dxcQk>8FPgd59?JU5s9MUwG9krL!O-vlhVdPPo(@6QAnbo?)I2H`8kDGq+7IgJMn zh?$B*5mt;RtXyYZj$0%IA&e}D%*WGNF22Un)UTYMi!L-tP_K%LUt_-k6#(S;h8zXt z0&u4xjveH#W%EDftVsmju&V(z9kU*(jQi8|2Q#8glopp8EZV4!cB)SfkL9Tv;N$>B zDO2+s%+j!c5pHA4Z8jxgUB0mchDMj9N0(&6X1wg(JV{VXRW2(zuadbC)BWYt1{A{^ zuX)JOx4^&DW%CtREKSWw{MP~AOL_U4y!7JbYF>PI=u^`1XERa1+b)KfV&eZTc%tqe zkJ%s=<7{M!9 zG**wIVspfk%q0ZiGE9Vyt*uXBQOA*6*+8Dj=`5@MeY>riM%72Z-Jz#mraODvcG|)* zfudS16(hfO+igwWt13oLyNl;#F_OP#TunLt`_e4UdtRVYQsrxDnq|4e=*4Sv3eI}) z0$DLfQ2or8jCDxD7a=SkUq}C-CLj%B~@IulQQjuU!vEirJq14pI8OZpTETS0kdh~S8e1x4y)gX>LXlO>C#*Y#oFlm>-+mo z1?}IAT*+NK;>1{B3F8;rf+N1k5r%44 z_O=Z^=R?n=LUXuAo;>!7W6KlTt9xzLk=G!eBNAJpr~Z@MO)5W*ee7fk!C4Q7+##QD{9qb(S#$2i*%OkP9I)1ow_8lNfzmL`ms5lzdW$h# zqWQmWsm19nLi$Y8PdVQiKibHNtL&CNJ1MD)R|Mm~aPKSKy7ZSHO(gm3=ApSXoG$;w zHbT~T96;_6gPn9W+DZ`yZGB(;fQZ2!t+JW#uEHQ})KB_%aRh4s+~QdOz}B$Tnh(X! z!+qgDva|O<)j?n4CIO?eJMc=Bx54`=K5OAwdJXd9=q^7IG)sH;Q!!+>TYL4O-*DLw zi!?sx`$N{zdwj3z4Z%CDDx<1hzEOkGKda2R^Y&r(CRM>?B87X=_eBs)g@gl{=Qi=k zW^%Rdv26ouGIfoHGZ$|I&rV$}>Ov&Hq`*T{HrEe|P zh14)MH!WtWBe4RnH9zBIULj=qYh6$y@_%QG^ZP$}WJj~O71!2ZAs!*d^E&z}t!gPx z@jPB_jr@6aU%jnzxA)=I-?vtN>Yb^#ioSJqGQp#(y_a)ZOGl5K)& zea*q;(beBhsC>_xDWHVWZ}?tcJ>EvDwAIC2mIJ_hH1bEqwAIz>%w=$LR5+;D$!`~F zoyK79sL5(HE4FJdqbgN;8i({O^ks*% zSHm_Gk;@NcZyD{G>NYVzmmataWAM{6}2J35rryTii=@5-)aet?;c)mq{E+7Nko*%!B3tv*M^ z`($12djs#8uq`+tdT$L^|BkNl-U5$~kAByC4ZM3NY`6gR2ecPZ5};j?AJ3Vqq6a6O zCoxGsHy`ctP<$&8H{RlcJ(cB~6SNv_wVv}!EF`U@oG!WWY?OC)=N4QG{K@+T#M$H&8Al66I-kL zwY=8~2em4(tJPlqAYpMIJ;~o}4=%9>l7lPkfNYEVqISN--|WD5Kl@8saD}6_7B!s3 z`+)ZH`!>!0H{NNZcb*9@IioXVJv_(dZywHbQU*T{4G%6E?msKv*dL76_B)HU6@&O{ zlCNs{nvB#xjOKc@c0xWM&Iqm;UbZ2)#M%5pEbF%5k~Z{KMEml*L9k2S^3^48`RvHs z5y>aFJKKXx+P?zMX#Tt8D_>pmmCufR@$K(g)(`21W3J#5C|d!?ToFTi`PhZrJ$5nf z;v8qhat;$VnHA;jw>oK6^6k><>#Qco_o3dXWaK{)mT+^z>F50K*rM(yRWf&QBB|HP z&s6>j`CGtWOh(p9W?kR$w76=rH3osl5^lm)PfA!dIUyc5IO3Av7)_Nbeq%ZXOt$M{ zn5OD`K_qMI>PgX6lcRUuCAWQ?R!OcRiQWjRg!@0TbLs8pr=M#Fb6*cNfuC6cBC2T%xV`F40yzOtclH zL|d_9VMVj#*%~gVulB8l{6&NPA7%JICPhavv5fr98LiYBo z*<{+G3G_vnifGJR@ZBP$$aQ>j{6pHj($DI({w9qhp;hlvFrsm6MfiBKw>W5;8!7o_ zLl*k@$(Keshvv8XUTp1EMG{#cY#44Kc&E+FSuUl3vQC% zZ~C4Ex4Bg9@kAzhUo-Uu7ZMs=LZi<3rtiO*(|CvL9OX*zYWih?%l&oSDPlJ%;(&+E zl=exJZ}+vv&^PtfLTd*->hM@rL)O;2^=h0blB(D0%T`^kQiY8KZy(8-K8zl0itlt$ zb2BTit^=0n$<3i^FCDO*>1^c~1oU4*^!yxo%+P*x6xvKl(bnj^cj;~a0O#%cxtfj^ z;QucoFxrLK0}EMfyR^Q^Ol18Zv}ElvvsgYgPD;%F3pNV#r4Ly#IYWMi%TJE{2%{(8 zCqD~K7RSYjt3#J9O2W~I`G22t?+k+?n$_?B`~N@d#~JS2^Y)zQJm)#* zJm+}{h=UsE#G;{q;-t-MbThWRAaL)T_=PymBW&25SOn#u%dR=G3x!d6`Ouk*_1&Hz z9g8fDc#%vx;PkmDQM28MQytcpmp7T3 z>wnktmrk{wo9;TR^_&-r_t{bUUiyl~Cjp-{d}w-rC;o3+&z}Wo_txU837>uVwBr+k z^}p*mE%N_e&sEy}{?>EUmjfx2F7#w?d=O+rktL^?`{UoNYsydTMflV9g&NPc!q-W@tN3a#?x-Kc-U zbVV3l*Ji_`1&;=$DRc-_&w%{98{Z^8gzN@^M?QL(3{=yxLiL)GYDqhI(v04uu&_Q` z{zHyfsG2@ueICW@FdNkup6zR++BdV%H*?JinWc7;Y$xwMFSiqdGu&IG+miRgnW8th z8&^B>N{C?Lz^E#F&ljU&M3DXhR6BipbwwXi4b0Dc0 zR^!&s%+`xBQmp|JhRVI-VF=$M#?(qp2y!3}!{tWRUQr~?%Y)uB+#q#QO*YhY(YLE< ztS{4yCELtKV~bNz;B?u=Xo##5<+soQ#fWz1JIgxO%#+a0^(9?r1mIjcCLtFNXMn(bc?rK`sD&#&?3pd{3@JTzq%hN2x4M%e3kVB+w?kwt$w$4p zetDR*&0KTN%&}s6<$fS;seWb=yxTxZ3|S2fSr5bNJJDIUW(2l1C}kDBE`8_bb>?Eo}{zR?Jla}W`;JT=d>!Ai=` zAXbY30b-1Hy&P%W)_ZG`Ws$Bm>7;8BQe}auQAaFGbLd5;dwtS65sM5y(d@+w=x%8| zoFU-K1JfEZc(xS3>glpbHpsZ&{4xM{c$wlG&;eyc@vXtv7WMUmJaQSb-3R^YolM3F z3og=V0!OB1IIItAXAlSE{NU>ng9h}vF_7soxN5l$54bPl&zA*XT7nPHoW32wJOg(Vnb_brIIF$xbB8=k-ci@)z~rI7xI*rrzveo{j5rw1ZNlvcdvD#m zEwM?6;qgiyuJu`5fINUxZq;jpQK_pFUev6cU++K5gFH(I{95r`dlJbrVKdwvKU{|Z z(NvK#n&_Vi!}`{bpi0fu#xh=kAH%4^?I#fT;UXQt14>*OY8~j*I?&ELfDWAwdOfe1 z4FvtcLDWI=@iZ{>ou`8SAzlHXM+_#y`bp56&ldW*yygL+kNd9BA2L(-{qh0`l_8pz zj}Z&pgPUc-{ik%0hU{E%cndKib&3sPE9kEo_v5%71Wh#ePZQOs*18#2Haq%HFXqj% z)6z`GsjxmtgF78@u=>Ti?QF6BFG#APXEG4YJjJto2b#H=R{*TrPl0vVGM@$3hoRbm zu>K{)9_ZTHWBqTu0?;~~@n~3Y?=w>!CtzJ=HR?=7F!EFLnS2#AFc~1ef0~)Wvw+D! zdxs_~_)N^nT;`PX^ebYIp!9TjOzM|nVo!kmjJeEjdCdb-%sQUsJ5bD}Q~@@hW!)ul zOAtlKI@LfZ^V3q9&@sb`#ZQv~t{;{P%C&p1nG9F{xe{KIOuu_$!N z$I;c#9KZrr2>>Xdl~*BO*sjj(FI0Xyza8uHKEipBhki;3S2=0vK%De4)H%?c z9;Xd81koh zma~Vvgvx6a?kC9o-wWi!PY-zq4hE;$?F>jQ(6dP0i#p)Y4W8MCoj4id&Egx*iS z7s4R-ivyzATJ<*1a<*u;R{e^~YphS{i)Cd1EDy-~=AzD1W7=9ZLG9LAWBWrK1cTWA zoUr}*_kwNmf_55gljrKQCu(ce9l%zs9-$yI}ieDzDM@*L|`5_1R+kCe%3)w&!!0&z_S+gt_kia`w#T0xGW!$j5yL8AOBs*{}n2)Vf(Yb*#7Knv0aQh2O|Fk z9Oknpe{(O)8DA2%zx-aX{kNl>2nNFTPkENJr|m^lUc+`*Uu<`sEw+z$4UFw~k^Wt1 z`!`fxqwV8_?c?7Iw&$u~4TSADp5^SZ-TGA!a_b8Vd#o?y_pFfXR@5=G^@WZV@;3F! zzXHnVmCqw9#H7~E5O8AeLFe&Cc~{%xoPWMgy?+0D>2(%?G%)|XfM+@TUVjQR`QUhc zM38^i9Fn`q-=C95c=Grd?hWQbs ze;1gqrScl*JVrC|*!MCM2dQ8U#5q5Pjm&r16+A)ZIpo&O+23G;`AuSr2-}A29z6Ge zMOI4SQho1%+E!7aTxe2Gvu-vdc8Ct^=2d#@<~e#i*`gnrWSjmt)S;i6WV`-1lWh49PqMB1!z9~tf0|@_@_|XVhkiH7 zw*9e5ww@;^**^RABwO1}n zcw&;R;g^$ab!da3jRgF*;P(jpz7W4}L!061r)0fDRzP&s2X%XY4-{4xnT)%WEh+5d zM}gB!v%JW{eJQhlhmc0B1S3oDv#nrtQ&^Zq`pq&sM>AVz~+|TZ% zD?6Cn{+vW6E;FuD82Ipa>U({T`+iseePlJ+-@n*Bix1%nD7sg<@e1u_)PQV z*b1Mi0FXY`8F$tfDsiMWiGRu{ zs&8yDIl0e!31|C&{5pFBg`wf%XC%XrwquYwwaaLLrdi^pNV6=sa@7eJ71Lk#lUoch zS%k$Of)`#)Z{%GR6*U-{>@6Ab#Hl7TSz5KQtI-6;K6RZ%7^XH3^P47CpuVQYy-O_Y zb`myZwNt^jU@6E9NZ!eI!bF9o!lyFJz;77M@aSo+z$TufSTSCz(bG(L1>FVMHX>Nr z6X-1>W|2k?54JUoeTif?6Se$UY+w z3b&caa`Dj?j0Y5Mg&9PFC==smo9w8dgQpab-}UG48}Y8X1Zzc)T1Osxit0f13|Evq z`cUFg#4(a)QFQ^)2oo6uM;dW8;0jz!?_@tqqH6aQNM8qpQP93AC<&-ZY_VED1s~q8 z%*iWBDABW;cL)aF>aaX5-vz;Z!;<&sXzxbycM3FwlDqPlokN9&DQxj_xgOeDVG!l@ zg{Xu54ntCqM}ZwFzi+<&C=ffLaXB2TPx&k6t{Lf%5%dLwp~=P6c{h8EN>TW)F(Kpu zX`}E~8p69@fGB(z*znY2h~^kfMN;4CtIl6j4zzQ(MqetC3A#?XgQxDooYvO2n!Sg+nMwDK@Wy z=10QAm|k0@l@d9c;FFkyZZ_LYIP4xej_n~g?DjDiA~@AJ@NP#W^Ob}}9%Al>eD zHL?2uhIgHfc}YB$W%Dk8OMV_o%=Ep4}{ zE(oCUQfAgvP#RseXj#V)gH0#bv&`R-^)nQ(;1epAv^NG#v^T0I+84=%ho!RZI&m@-f+hmz>>0v07=uG9 zs}07|%V%BC$tfrR3JMR`mzcJsBh)Ip{6R#D8-^yOb?}9JE}@;3A@C&YAvsi*nJn17 z3u4(lEy(wW)vDFDR2HYhk`xR5uQH1OrVyuwQw!j11w_cMDWrWQH-dq=*{?8MvKSw@ z1RfzMQZ9Rt?$9$$#YE--F(KVM-yB#2`*x%v0x4AaD9{8PJp=xzd^ekj@>n@SN=Pv4 z=4iQuTdpU;PW=>?>mzuVtZW8)lH8o(T@WYNg{;V>_Ia3+q`_9^NJbdHebt45ij5`@ zMv5pUohXIeLioWRtak@+W96K0viiE{>IxQvmk|ios{8O$Dz_P}RiC3^MY#&fNIY;O z`XP8ABYJC93zAcdVy#t;cwoQB(KB_4&06U}dG-rBh_1A;yYaWdwNDRiG3Y~5K)h-s zt4)a)P%~nDu!&*8CI)FuKqU~>SLRWLb9wc#!U~p3Rj0>-XxW8$gi%ADcS$V!HLe~h z?w>eME^AF4XZ`6o6qD-_8d$!{RGfAje9c^GHnA2U4lx$1-p4>8Y}{PfyP_uNxDD^L zeMYY^QL{P~=xui5dOnDf3Z$qgS&OG2y#1hL36fKnTda2lfD&KUo7ujs_H3wf#^tk@ zUIEy-ShDTT+&8V#LCUZIWCabKR$oDfx3CGbC^ZA2&i{%eXGW*>p2zVZr$Q4@UJt7d zZyCe5T7P;Ez0HgzWf(Jgg>W%%7DBr3^yVJ+W*w+%E>9$n3DaTn!CIiCfE^PE7Yd;V zFn3$TSk@Wp9zR*RgwQ+XjEA_c}G@z|U3`0Zj7{Dz1f zpkw%L=!DJqzi4i4pMvhlS*_^89I4Lk&4pfMEA{QpsTh^y{hqQ|9Rgazn0)b8nxmew zfKI$djv|+a<7N>ptzIN;#00f;&5tt)b7%sJY4j}K6j&RZ#~Of49?7v#nTT-#UQ5qS zDU1~t0yLo1P4K`SizSa$044BP!Nx++mbxTXoTTl_sPTWlN{#!nUSUr|I$8V&Fn6Ep z6*v3YPE7tk-UiZQ5OT2(>FXfAyr9~*NbHr>33esB;(6Cq?qI9%K6Ry8 zm{u{HyKfH>7mJP-r-*OTQpfKD-~!VpPg8HZ8`NRk}vK&b=) zYy6;2C%CI|8|g3Pnggq21Jm5>OFjTZ-J?mBCaZISR0rxtZj{1la^std;dwnNAcD@f z*`PZO8$|KRM7#2Tvolqz!8S6?K<<`baZ% zWhVKU66srSG2X5QUKj0oi?iiIa}HZZV}!L6D*NY=7XFM9J=cX@<6t&$fr0`ze3|6) z=sAibn9>E}3Z@ieifGF%`{Ys%Fug>ahC0By8Jo+N|2UE<$Rs7{4HNm)R@#u8$*ovN4bT9UDb#J+L@g zd*g~iMTgu!n7g)_g;;r^gPM2-RnY+c5r4fgzWHW%wsL7#lpfyr*HZ)m;!Tvk34a4? z?SWN}JodY0B3_HM5jx&^6hStd%E5VriTBtWsidR!)a4Fw0?ue|?AxzIQC>HDAM^~Q z*$d!l1R=@FZcFte;TtY+OCKDP4hn?g40V&~_2*n_?!bd*XPtX>7tQi`fM5Nu*+6Lp!Ei z@+c(Fp+j}4Z-JSdV%*kc@X*FB0u(J?2Vc<1UCw$T$v4+rGkT^2_8Vk|P@tc=gzPu! z3^<&U83GIpg7zESlS*P&6hi!V8O*{tAdxN|qC0mP^umxX9e-^QjLBV@D1-xJ2%1O9 zzt*g;7EQ7V<8F|LIDk9iX`bzPaAufSM>sP~r4c1V5Qm8G_rmhWhUG`7suMGFCt;6~ zPnEtWFsw9EyBi_%mNdGarEzU^{T+?z8eQ-fOMhNb|J2eSpX*sUQC{P?!O8t$3Bz*o zz{QJy_bP-zY*mp#R|F#05vJnYOu&W#;VnnXbK_=_sVh8Q&5g&4VL5>oG98Jk$^k6u90_tH8yleH4SLI~C+=^4X64U!kCf*c2c&^ENizPSP zy`%u=Wt@ovEkGvqObtzGM?OdHVt00SaqDX*b`hTa%r|%^Qu9DW5_R#)_$kSwc}IH$ zC+e6X9q$oL&M!+ZL`QwsJa3bush@YCn>*ER&NZ`}!BTj<5F9hv9r&R;+EU?lRSZQaMp$4o6Cyf{U9>ZUunZ3g|mnKwdmL~^R z#bOZ&tV-Zk4OEQeKyZyLe~MV1`;+%3cO?e`d*EWWu>M~8QyJF-kjA_Kj>VIkks%QH z75VfK^0$0zym@gpTDP-DIJ4v4yAbm3Fy>xz7s&Jxt4^2C zeu*Om-%kr80ukLvlNuaSqeJR(tlp34_EC(mG93mg^>Bhj>EL{Ew=_8NeOq?o7vwoN zfXV|yc+t-t@P{BO%b(R3k?f7rrPMmEB(5M4J0C=3)UtOcKNhXd#*wsY(e+N|_w{&?AtM6zgz&$1y%I!p}FG5R@TG8i}_gf4+EeNmOyl z_RDNJY~*ac)}iz8ZUKL12)!GUmlvu5<`G?}WiSjO;NNDGUKxoexnUD5--M{Vz=(L% zjr0*PyLXmZtW|j!<&dck*>RzZ=vBTit;#~MN690ock&MM64mm?4(WJ+#EHs07-yN} zZAu!XLbU&7Js1!YUkT@8H9#lgvjncvHjsP-g)un1ekmHB?`&PA@7vnHCTWEli_d1(2PhMl1rT4#vly{Cd z$(L?&?h(5g+UI2O1~Rb10?IuW!cSp4o|-FCFtuu}zo?VzXdi`Wfv#XsdIpc_0dR#j zOaKH+R_P4%Vv$h_|0h;o@}90!F3x7_ zNdVDO0D?~N%{LkAkG^5tW^9;HpV%NbCGPfScPqo#k9Y})fpx46D;=LP8YI{Qk<1NA zKu0(G5J9a9Xffp-sc28YBB!op{{$P5AeYP+22p=L0y+vx+`cMwpGQRf7xsk3YLL_< zNTEnX{t{lP8NkB5Rr`?BS4D|l9=*_8)k@F41N43WKKg#>P5S;v3w^)36W<7)>gRua z?flO}P5e*QcK+w_TK?xRui(#v_f&P@k4!OB86JG}(20je-lP^h)mwF#XR@GifI~Ms zRTM&y7i-5uFlH*rzj<_24mLP~79e$aRY0^79#k|OB&jZVRPw);GxsLc6GRfp;Ze zOpSoMq3j#lyaR*W$}Yr!?&Pj8-EOv?vj#f`6+RjB=pS35zEXeC?q_GosK5yFU<=41 zN+Ph2%q!7v9fdfOd0;O80oFjiV8LOrFpGlZE}%o4VDjZ-ILkH6x9C9IgJnHDpumr) zGE$ml{tbf2io+iDA3*$RFtSGa+&B3L#Kk(vx%{tJ!i5nYj1Y;9Un4~ED(8RswPw3sp!3;UZL zHDuAR1ruDsNr-qbn4G?>4o0@kir&xl&e#}vPa%+3RFR8T>m~fie(`v3$Hq{H|Z-V6vR8BbK za@PmTLD*o{R+v+Ft+%}kg5~HUk&!$7fl#6iu@FNn&&&we0%C|+=10>p)`a?rgkEhz zoRIyUezHrgrv5V@?l-fc|IDBFo7vodX1Z}b5o)PbAI#hy>&rR}(UgtF5Em&lBkT{l zwB`!tw%HC#;|Z%Yi-h2Nk|fijYn zzJ^Mg8+8}(%Bl;yGpb$RpiaLp*I(^Aj%p!mTZtggiy=4e=EV9e9nq-|tOAh^rR^k* zbfm!Itnwy|dN1T{ONa>kdT}HHkHfZKNbK!^G7er${djwfyH7o-f7`eR06s}EU-2l20R5rI2dHnUv-1~+O=3c0-XWxOW&N3S(Xb^NY^ zw}RU@lVExl!$C4*3?>rzd zhBH-|@w*sgOD;=|1J`X9GS7z6QHj}&!Dm-~tzlR^h@rt%qu=xORB|6_z@rl3`8rXI zfz+;MY$kGhMGGo|3@-prxdEHFuBLuUQre)kX6x2^skTL#fZx}pjn;nuNg0mc8KK|J z@WR^!l?V6&4T!T!1}|4qY9ceMAzu|OY3qbBX-ja&jeGDC^KuCKferREGFC>LHvZbS zJOl;mN#1)DP9Dg8hVP0N&oK_f8`8EuK;U;DAn==j*nvPT0U_1-_L_@TnXS}>OG$`( z{m$1{Tg3=xZhI*(Kw?~kc70~IaR+3%p|+KK;60k4>%=ua9Cdfqn{gs>v1CL|wkF{% zPimWmS6ghjuc8c+gMM8L!3)oRK7L8HgDLwEWS>e2Z5GPX5zJydAqyq6(N=cL3LuHs z(u!ZI&>^qoHz#CSfrK^>uO*m;F6Y7<`k1m5@>(#n zc`a9;kYxoD+Gg@B;5|Icv=g%+p=}gp`8b$`LQD2(h_ZA7?ORqr+QVy6@GCqECA96K zEN?1;!{Og3V zl7ERX8tL$1XNM$1=cY+N38V!g2TN)ejow^)i1t;M1fg;h$R5rAm(K6}FP;DIpmS2h zng$0>Yo^GeUwYl_{9<*qXmV~VjgVe9DTA!fh;}0uVSk90+fuQ70nK?~f?+)gLB>up;~Kh*^;9WCeOGX}2CcS0_BrV%cY{InCo z@-~G%hnog%c}sy_Z*nb^nLBV;M>f72GQ$qxEogpWKZNZ#_CvL71J6fsR*(^4JX-qf zh_;7zM4eDqVV6R0nr}PB{ioU#4FwaZ88;ufs|(>LDYW#3EqHYQcy=2k3z*B5C4-lE zU3Mk2CTe~)bW6)|e*Ky@tJ zT>|X^Xj!pq<`{IiwOj^u4S0LY3Sg56jf|SQ;D&CGx|ga8Zs_ov_EL4h4IO@~dns(f zXghVSGuOUm8NY(>kecC0$L|ymub#Lz!s%kG$Kp#IiWj2AS=hSTinqB3u*Yh~HM?IK zmFI@KM?id&ZNjnD2w~fo7^vY#YOM3CarItiX}b}7Bxrq5U(112?Ao3*<66kog8d0b zzXRK@GQ=u$v#VhZfsq5*B(uAp3(_U!hdXk(NM zNoXL6y|fwUS1uUEF#H`Wq70@H5`fYTlia{wMiFRK;_4Xl5rrP0LP2q1CHz?QO1h*n z2WqxK-_7o=dIaYX(ZTjT8$wOdf6#bSplt;9IZ(f&d)8LEaE|r)HXt*53h8vRd-Y!Y z!bQv8KjR<#z`sgWNv#HN)!lfA-sa^Qybt{Xzr6SV8sFmJ>iZwWUz{qU8mj0C7>x5( zQAH{wzA6u%L6r_4hYXm_cKdvPz)O}Mg-z9sojUDj8n#_>2Tnv+087cu5C=rp39-=C zg^XGJiCjeuI_t#?5Km>Y^GNALWtpr3RwrbkTO+Ev)|;xWxYyKj3R%^bD4&nQNwT46 z%JXV99(52|@osCpP5=7qh!J5R)B|SyeSB}F~86W(L_S55k z2?W&|X&zJt#{UKF|99|T8_@^IwPooKw6zR&#SUSK0Bd(wcgkese`?P7{~t1YZ{Mg^;R3N zR*U-%=|vN!oKB3~f>8CkdbvV}pL^)C0xT?>wAUe$t-#STu(8z2mhmb;&$vERa&nUQ z8@o~;rV5~!*+V4}UEu}#yB1OtWm+El?PR?U(kPNOox`=j?xEaFz!z={p4WSMZZ~@x zF`5dX@WhwoUP-Kd0cj_Vqpy(?8zc-x_lF498ka5YM}j$RjVhcWaS9~U@)!B?R$l!i zfQzYXGBzj%BPpKq-axVIi+tarbeVS<=?3{2>!wq4p?QJP?=7DpFG{Ft-e|(4OHAG? z*B=!v3q9MCyo(a#eV*f~S&6{EOW;nbVvEGb0Z$`W~ zBVmO%BgvbQQk{|Jtw_hL_EyZJxy?fjs!hTLFI`d47Dwm3YXP767H=fooWTVx1d6c3 za@oC^xWA0`X4<(`1(to9M4&Ua@@&eYU|=(61v%p&kA8w4VOXOf0g0EenMi;l8ZLkf zWCOrykj5i6RFL&lv=fW!-H8yzLn$={XO2w0u9|NNpz2xR^U)RpyO_&9LKh>|6(9ZN zdjdHV`x|xB;FdEjfh3rm1y-8q9qmBeY(J)G*hb+fIIy~|L+|!dRO@+__6B@qr)IR3 zJwNad+L5r~^GWK)^&6Jc1>ewH07CEeA<;w*Zm~So=)0_|aVQZ8q7#)-qlfnSS3KU9 zkf01oyHSWva|PdjA@5n}Nlg-tr;HZ$3u_D+bE+wO7i<9dh}4jvyftmzSxvFj6@Ng=usjd1XbwrgU-5TvV)%tYXin3^UC zozdwdp_#xLo>XqZGRKxY0V2<|$mO{B>n<6bEsv8XLD3y1DBZdRZYJY+0mNf-?bT}~ z&euw0TBMZmP+fI(J2P#oqd@UkBMsAQrP)}1vE~@O<5b16AQ7sJR;#5ILbd_g9e#4V zf7MESw|0vMZuhr19h}hLOU|lY%rM_ii90YUj`$e1s!f5Sdh9V$i)_{^5{0t^e+X@i zu796zjM`qrdv8&Sw3pl)(xGDNOF66 z+~i@=IuSRIe8O?_Aoc!~xcLajE{>Z6B+Cuq<}P%RC*#--qxt_RzPXp&xGa0gy6oW1`@XxMIgFDUq6Vla7IZ}NiPWKS^pvEJm#p=7>1Wkbyvy9_m_Frg-M znmW^PD~?M%Hu_v@Ux)}~I)IKvjsVmk)iqWvN9+gi88DGE9S{))i@VuFv1Er#TMjj+ za>|@*LOJQkMQaUi<1)=Pi>84K!F39jDBX(GSa+GLI;&fSjzB9%u|A;5i)=M|upM89 z9&1ZV(KOM{o_aWhwxk1uHU$I9J?ZmBW`M>nr4D6lY^P-mwh;YPe?@Qgd-nHM|E=m4 zPEq&gzYBpb_O08qe%b}XU|&Xpn_YvO$$BZn4lN=GRd?+YK2fxXRRv0yl>2ig$zd5HXUp)ZIO7stS>Pyov@9kry|{(9n0c- zyYke#oOq@6Q*^j3-C8U8ORV=apaN^<3;34&3x%sB|CPdJlK*PVR)4Xz>ImM;88%N! zv1m(g%$R~ob=Zq@We@xWkJh#A#uuK4&~v@|OczpZRHvM6t1+Y{i?N>D_0v_;EZ-ah za?_O-RrE9bO}j)Kjr1ATs!IG))4{eWT@ll65bS9;3%0bM2$nPv2k&))DQ$^Zh&pfs zs#C7U0~SJ^a)so-Rk%R%3j)^KwL*;Kzg@f(iQsTL2f~>W%e!@}IE1SM*IUJylnu4KmTBec2eK@FT%ecgg=5IJ{5(}`E3Z{O>h4f;b)9+bq!M4 z@Z99RB})pdTQjFg{u?&lVy&ck>8#s$nQ*D(&#+eh96u%hTw)FL%FmVj^Q}Mi@K-sa z72Aj-aFswiPOxN1=i0V|P2`l=lzfRTMZ7~6CFIeHFCJcuyb~}FmA!a)oAw^fl7HpK zEMd0fzo{H;-%OMDHk!OY5jP{xSHqC!aXj2R6b}zdi{fmHOQ0Lgd|)@q-FSEjvssbw zFbOcUk@mX8)~LE)e3#LJU52%aRKXUvk(q|4JV_@+)zr7)46c*&;*x9gNoP%ldRY%* zXERe}J#5wR06z;tWP_`Fsxq?j4gQpx4m`V;O=;UG!i_Wx{fKZo|A;-ATx-B|f`OF_tV@Qax|hH@MiBi{cZDQW6h! zZL^3YX#vdfafw9j=i*HD#4-U&3G$*iU%7)^C>fvB3u6#+ zq^nLZ4$lwP02d;2)f%wj08(KOgoEFPbLGr91XDzj-mGZMp=Nznubv1siOlyxCzoM3 z&y-GNED@YehS53aG<4EVM}aR;B-=o88rZ%oUdm6A?U=5;XG41IfBgwr;{u?)SQM+KBQw1(MbY5gwe?%Y&bZb zoFAl ziCO6&_f2wO6VmR+=RSPs`F`y~&-8gf`x{J?DWcjJ`BEkh2M{Z-qllxIz~UB?wu=I# zQ|PP)19uZd!S_H$h>`FX%>cc>5G6$KVcyJ?hRig*G71k$Ok?JZYyLge)|i<>8(Adi zmKQy%N2u~MZeq$0-$e7_v+f0*J8{6N}*9k+?GK4{mnF-Wy2 zX={A9>uUzjscaUHCBBV$=FLmdBn3YZc9(t-!tSMb{Px(@qtxlK`xtT&cHe-&Rm1Ko z96<-b?yVem17UY5iQ)fuW49YJRE>7u!Q;2b?qeu*dhEIgtH3To9tW{IJaItm#&FyX zgxzlNn(qs{#1#56%j*FtEnDU3*iENu+%-q-sr7~QZgrkgpB{yH)$Pkn!F;?1mMti> z3~B%q8#0sh$~c)T0zehbAn(>HsY&my)`Q1#W}>kP!GPFc*n@tl7csw>NOl8H0$WV2u-UAA#_{A|Dy;sLQH%b zgsuhQ5<-W6XM}dc-R(dWs^IQgQ#M=m&;Lge`Wz&_r$OkGKqMjbBEtQ*rO>{cT$X%3 z*#<-O|IDTk?k?U=xKrj44SR7>TtEs{iS%_Ym(Rcllu6u$n5hqVqrCYhWdt6*QA*4T z{9S>Eh?-1Cbrdmfnj3Vb(Pv}LUYn@3>FjN@uD-X;5kEkiR|MN^yerhttgtpovGu$5 zGdqq8l)x?qRqXJ9^?0-6;10&jeh%xpdij*e|HM_{0Le#j<62*$FR?XdB#@LI0&fz< zvsqMYKkrMax_;i1y3vVekaGBl>BdP$f)Z=QYXPY3^u3_>v>4Vv~e3?||k2KDxqFh~>Q}u$K{ZR^aU@C8(Ujb_R zJP2Dl7>>Z;`w7}GqTRFJq7zI3vY0XlWJ685MHval*M~}>(#B|$8=A5nocN^GgIJ1 zFJCU70k3~vP|BkU zWq*pj!dz!jiujT;j&5$1(V={$DcUtEX!|DG@?>=rV@v+mGPctN77SHG%^ARV1N6p` zX9B40%m8fz(S-pz;rj&i6{ygk9-}t_f-}HqdS5_qpVtSYVf13x=mnZ;Q2w*%K~y$f zVH-8Wrw5PHEWZP}O}1>zgHIOtp%kM%>!4!mvI!R}iHR%C&ZDah@=>yBh7#UjQgk;$ z_e!568}%#AvN4$1q)$;~gW%-xGi6lInrI02V8GW0>)Lo_a6sSgWvv7E) zg?l0g0D#a89#R33HIGnPBkabHPM<9~tlaTut7r!}xp(g)R$k+g9fVy`tHJ@`3=UYzANA*9EuNnkBWBb_@L4V&$fKU2<7YQp&9eR z2_l?jw$<;`*T@E=j=fP11L5&S-Xym4WdPZrjD(@CFFQ~ZSu?oWaCvo1rt{0yU-ofR z16|J(8n%>7T{3@#*XX;#aP(ccj0Rtb$tA=7X7yrP5V< zH;mdCHH&syr7>(~sCjfyn-)^Lo#Wsf78^=szu&@f5Z%&7N+hZe@5Sdpp%==OQ2+6# z7MRP7-U2gx=;YuGyK5|V20Or_!F~ug?atRX##rxe1O(0_);nJ#fT3WWZg~=0fBs~C zAhAPk7_&p(!%e;+ZT)06_6E1?P9pAM;yVO*u&tSAo{T1;?j-9Iu?tve;b-!$I-`&a zmoj?tFrC{Wj+fP)N7p>tRD*y)_Y=!yKQdr(-)`X=Bw7y71{==mDNx5HvbqG4TDA|D zLda$G4}Vt~uY$?1JjG#b@EyV70=}YKlq<>WDdH>F$+`aMZK6qjL%9^H)7XIz&B<3u zdMf$~+EmUX@Wc_=j~jrXXPh8f6nqy2Wxw&*@HgZ}F!>M#OYQM0lK-EVVKqB^2YgyXm!6|$Lk!Fm<-+!y?7X(G z(Rhg=A8PoFwa4-$*oke}B4@5mT*xtq8vGQsq|Tkq$m2Oy6I$NzGSf1A2fysLRz8Mm zYH~YfzJXit;|93LFf2ncWBu^m+(SRPVC7Sku}x?Mx=C>QyCdM-CPvBI+PF8>vhIyj zUL*sc4JPLoYtIXg5naEl)PxHMwexHt}T27w>U5@ z*(VnV0%2Q6BEm7)4$`!d_etx)YJx+OLqkF|P5u-gC^0N{vl>(`zwWK_e~!ub{%r64 z?Rb!n+;S|bt|t=LXqJD_um=QdJU;MKy<`k#o%)idUR5V$-zMKrf8ity-_EP8aq!ZP z0dUT<#v>#wji}C7)qym3u?`UXs=DbJ6*>YVy19ESYvr>%n>sEz>Xz>@?N9g=i^UZsrOT_U{knXNOSI9lTxEk z8zK((%?~)6);ORN=t&t27jaDr^zCb{TRkZ_V;GyH2EDXbm*M;eFWcmNL)@;y3*U}) z4;Xoehu=>fRY)B>nu2AJud-$A4>N&^;PL>wD0rhw(+ktn48n!P!MZRn;M8(|VqI#M zWlZ4c+Y|i4P*3V$F;Z)CuJe%iITmhW6x?OG$PDi3oN8Kn`|#7hcCT^wvwAPNZJNB^tTgbU4Kl4E zI7{2u--IA$)rA<_PVj-F1yZf0<2*C%_RDP8hr&fGq4om~2jm6Tsyi|7fP2wO@BjD> ztj+fo3_qUSML!Sy26NJ7E|3?Pq-)JO?9w^<_+o}fA-benYXDXP>G15Bk(MEj3T83` zFyfqz=?-GG{Iv}LxLGtfn97#nq{I{rCEf6?tLkA?+hn}}h=APCj++in4=i>QbQIKu zCxOsBL}<}qcfH2h=dRbt2fI#o0dbdpjI+n0NVsu!_qq__@C#zq2I}xo*g#>&5J@IY znq3o~VA;gTz8wn=;+(TJ!-%cL$_=WY1$B_%l)hbaT{#v*fV15wSa(CRo2# z7U%KRxAOACa@YsI1}Z4F0dZ(@*WZZ!c?_Ky@R$gn|5)8n9}I6-N0#)!GXt+Whi$<5 zzQE0P#uGN+Hzpw5NInquIP2DevFLNniN~FFtFuv~k^q{>v2KOuO96JX1w1~|1p$}& zDs&M&!vYbRymt;g1*}!)@g>#P_7-Tj#I~ekkUsG!tX3Ofwc56gZ{a&jYy};I%*rPm z^>7PC-p7P*O;-9LcIzg|Hs;SMDhTT-}$2lO|4#@Ew6;W~X|3gl`46H>+Je z9@^+2nbpA$iWIzCY0?_8uu=qzl04hcqC>yPQB6U5FdeK zo{11&3PZ7O6J7uPCJarM1IRA)<*G7-+H;Ebn}69eYv5%OFj zzfA}DgH>H^AJWKWSk(OUA@@QjK@zj9)!z_F>;p;Edkg)}ZPrcAc;OCATTJmu{!BXw z0sxcEpSTYrH95nqN3cB3LUE2?eLZ&bfsM|6r4d91YAsS(CoK1fK5$s~CvHPABs#aP zU4`8Wkhzxb>Zb1<=m*q%oQO?h1pW*h4lf*T6 z58A`Nz2l0@A&>(CdDo#dqjz;w?WajlW#{B!Z~G;&HefSG!{!P&?nEQ(-k;F8k4HOg zw{i-C3tOU=#3L#Z+1jq5*FowDF(Eo82EEbR`AP2);x!M?K($0z)5$_zfFBtLyc;#GM}1m_Meb77~;hd6h$<2tzaoJLY} zxluugLXgnmJhq66s>>V+bN~SPYW^{16&K|`bX)M49FJD9`5*xku^>D49ILJ59i(YF zhY+PM0np@w_7W9ln2Qf$*YFAy3$m{n&KA)xE`<2^Q@lE3$;c&SK8s^%E#X8?#%mt_ z&Cbq4X6^Xw z2dDP}D}>-+$N$8Ey-@=;dH;&kal*kBsbc|ARw$ctfPHQ^Wc&fCz{6Myilt6|gpFBU{+^AaOU^?v@d>U+e+)w5^9pE#i#?X$)d_BBz{0-owfMIJmEDJ*lDd@TQ-J=7t*D@#KjOeZ~nF z7SFt)(fu@}!8?L=-x3^ub|>lqt5dSEz~;j(O&!C&Mo7(L%YKHib%^`75m?M);}A{7 z%@#o23ETeU@+D|?>ut9WIz zKLSv-u~>Pzyy*ysJ~((4?J$fFv%JRSrOi6#-w1Y~B!r*q|ES_;ne;e$bk_NN^d~Rd z%_Ja(J2$=1S4AG6-GP5l5}QTL0x(ou3_+x4ITbS)=``5#A!DLyw(g{WF_ zJhO+o#eRbV=$qEFMN?E%(=O>9oPz$Xq7AXhMwo#zG&lPsd;wKvVHn}-9QJZ?5MRnu z?63R>$Ie6SQTzaQelZ|+t_3FhVrLP56ONrU{$^n8OxmVl$67f7s0n(}-v5Unav+WB z6=HzGN$@{}-^}7bkSEQ zeSJw^pV3#ln~l7P*aB`2KsD^h1z}X2O)DRcWZiDKY%A>c&4+65FlhDh0G#IOwW{C@ zYj!tin-4ig-_35vF_Ldk#55#9p$0Q53O60|&E&*kzJ=`5=fkaoO`Z>j4t9AyoI5z= z`LQsYmFLG5fR=E7to&Xjm47`J#0KraN9fe?wXvfsf@26&s6hicK^3+g_!?axzF*Nk zqt7HH!M-}9v4+z|<8}}%=GQJ=XWF9d6kC+$DgqD=mZP?U2m|zi+ygy9mD4)8F4+1;&KDdbOy=q zzW|P-ci^j zqRQ%g1J#P(!3Ie3PfN>doq8S1!x0Q&TriQxa<5>$u_zG!f`_EslqX zXabI|%P*b{;|KN-`1yO-%Y$`WU&xBt(y>veo6xkv*(Bbao&8>HJd4&CemTq~4dvH? zhl&&SyKK1Dd#|wbJy+*@*TkDq0cD-?CK0f$Z4HYj-e(#-ONTA2^`58jYnBc&nDVI+ItZ{3D2JdmstaSk z(6#-J${68ev25ZypB-%OH!rWekquk+|D zHZ;lv^}ad|HwJbT4mR@;^)Own7ok~;ddE0Lt?yM{9~SV5@bK|oL@o4WLS0w8HVO{( z(sohTVwJIIDPJwP7U;+U+WhQ&=<>ctQU$vfXb{sQouW&I>u!@BsADu_m^M{U&UOkSO6LmU&V2BP;cBJ!QTO0I- z50915I}t4p)U}SoJYHmq9$5iB@tGHm380!l zzzU~2Dv)PbRBqCml-}1%%@Fbh%R_8MRRCt+!i{zBkE(bd{oNSd1YLlMfL%vV4le@g zg|+uU@?PXeUmb%+qMz{16zpilwg6ad#Rq{XoessVp1Kbp4UUe9ZjrZnW0GC=EU3LCCFA)pK4=X6aQdYi8PO@B?}&>q(G9k7cVpy{Y@)AXjoP_Kvd+jIll7jJijxDlQ z{**u5X05Ek0|mhjc#b8Bb4lNRmt2mU=MMHTs(^Q1_*xhapT3Zxb)w!4xu`emm@-=4 z)qt?a>~`J`#awoEpfw(N*5)mQkK!KR?PjXe(ctRQqolhRq9oySz@EH6r7&RqMg0}h zhmlhKAa7wuuWR2rxZFpqhLCGt{LT+|?Tg=+V$<3Lzoly@`f8~A)Qt0(V62XsAAoRv z7dtc`Xw9{8EGU1#97Q11UT<47&DJX7g~+%$ETeCZ+36SK3Gi`pVW$fF73}B8qM1?*ig6l>acN4`C5q9R%kB?bN&u_i97a+^`tCQ5clAQjCT#WhD|{o-g#3I9?1v zC8*&UWUpxg6=58$zi@p6QX+bq%IWE6JP|1vSVGPSZB%a$zQ;@9^RvK*UxzsA*rDLInxyJHOD z7rLLj*we@ejHwvCZ!ypUr;&MP=W*d0&qjphj=0KsT>J_@vot^_R($=e5(sRV3T!6V z0-1bhjOo^AT%Ez*l$%QiDPv2blylU~WhU(XViJ#g$9l_Qgi@zmP-0l3Ohf=&A2rPo zL7Vo-iY@%jt>7CtIH>+f)%{Euhxq`Y4#Z)GpkJrpFkjB=!(k2~@b8&%m={s-J93y( zRB;lAS(c4@!#GSfZ|6)n%%on3{%1JM=D9%YnQ$0iSjJOum=a|9VL6OB42ZrQCUf+e zaF}gZp|`zD7jc+>%=uOv<}PGEC5O40C!WkYgK4nwZbA*QoI83X%ol7q_)-m(s?eo$bniJn>Q z*>{;uFwd;6#9#3y7+v0+PDq9RYI=1v8U8^S@-`Vs&&@(#=iA7xnoH+gh;WOn)y5j* z%)6@9TJE}+YMF}M6OfcyZIpT<#6x7t8G+IzMqF-jg*u9OcNtt+fTy<8^K?8XH$!>i z7j-_9&xnpF|JGzVr|rPCS_f_jcHsTl{db`L%9A><8Clg16l)z=8SKDskrdv6DwOWq zfyrSVIQP^YfUW{pUf~);5SEq!^L`+bD9BewN?#jQwC%d$ zB$%6#r8+V#L742z>STT_tk_$Uq+V+MhISP90(+El5Gf^5Z65qY#Xm=>{JiQ&)}yBb z6NuSV5}{ZjiCQ0gF{~ugx_P9$d)Z=^PtDdV3p|%i7Sd}XksG!cO}>m4(rF&;%Xk=p z&Ps=>0nbVYNynC3tA2tLAlgY(p_?o=qb&TJ;Vs-TXu}>9&kcZ)bs9!C1TixF1dM!h z`AHb*m=%r@+bJ>91z}(>MqWZGjuG4t_QlAfKp96-7)I`*X3q*Ei&f|bz(`JB@_v%0 z%SURWX5Q7LV&JZwgn?nCYV$U33^J>uq#l!a@OfC7z{|NNq3B!kS*_&XLnYrj!;)LH zlC`0dKMIzN7`V+xw31JTN?w1;l5|bsA7tG`3Zrn7Gbg50G?OGpIe1c$ie?btM&+OVB{`1lmgo5JvM9?-+_0sL4udk7mV4WFohWurZA1F{wxKI%yk$Cb_WjZh|Q=4D&zrp>Tv{6hVgf{ z<&?XY=O!?6btkLes5=zduv-}o*<+^`cgH$};_h@%+?~$hN2mjVOV#b0zwKJgQs^|% z%L6zApe@ASK_KrIya|XqSqc_o(wje`q|0TUq-L}GZa!L|m}C}()k;-FqJnyH5X1@; ztx1VT6rRB-w-po2qeN^aULfbTD=}TJ?obdO`E5^GlWrM>M}0*L!2=R2i^stBO5~vD z9*p+Xmux3vRQe~|Rah}JvORiNzhrymrc;vbxrCaN$Tq6aTa|1-M0;ow&LP`$aVz|IVX|r6IcrSlC48!GMsEl zp7uXZww8B3gAhK?Ew#r%{0DtkpDQ5me5VkqrlnJSh%P`bk=PrIh{_%)y_T8U=rO@l zhKpQyb%civPx<*U@r8x16*ZA>^yN_)Vz{C2^;U!{*a6y^!P`kfJKkVB#q4MOv~ywK zb`tw($42dRoYs6R(ZcymI325P6bKQDfw;jNg>8n8dS zo#uYpi6vWRYzI?{&KGA&nKzi^MK{O=ll!uu5T39SZPmkBun_G- zoQ=#I;7|pE)!h`n<^oDHMK{9Ss?^M$_%XJ%q!(ihWLn4uayNKaqmHY$JWndN@V`ZR zu9;IH8SoY|*y%u{7K)#dumJ%#hcyO5G;~BG5f-euox)%z?7FZDvvp}gigz^gs<+lRmw+2!EG*%-G< z_H_Zb+U<+p$2fYS#v5oWBJ}1GdKWW2j#}a9jX~O}(c8h%izd$)y(d#NEe;xb-`L2} z>pU5~;S@b3h~AMzac`D{Q8XF38rj$2!x~NhO~rILO_M2JI8Aqk({#5t*B?gHrPRV| zYJq5)oj}u{Uc`}}&IxQR*VH~AqF?B=gM*MNYkm$}g_9o!W)c|`!s<>X?fW?HuO{4I zjxQ>M5iQ0_p=MJl`^y0-`^_L_$8gFvV}2wzukf0`9c{N{gpi+C&XG@7goNNQb`nn8 z6N1PeLLmSBLb}Z$oNwY4aq52QWa|DlIKPD|UWST;)Xmtx@e4=K(q(gI|@@UiT9j;Aa`P2Fn}(2h}Fr^#hbq+i}B20PQ^4TjoNwj1_RpdanTr zBHlUJ37piLR`RyqlAU*O2v1p(Am4*fE%{!9@AfG;r=nsU$V<%LIXLncc$Zp^{CT-| zDJ;oWc$eC%myYxDlCWV5bB#FpJmeyTay$rJo_sJJ&4FG39&bT39?ti|qM+ zRIKyPy%wj^<=(kB$n_NBO^Z$iZ4!XSiRb_D_Ac;IRoCMGOlFb{Byb`G2m%r%C>pUy zuz~}afC*>~4Mg%#0=Bhj8m&b#L$n2wcrwaxoYvmzz4cmJd#kUH;k5 zz}M2AD_HQ{bEeWCmpYbGM}<|#eZ6(SD=1?(Z9M{k|KN1M8+#n4ZpL60C(1m><`9Wm zRd@6;&OyD(3lt6nM1@1Fu*}zgz(bxhkpGze?bXDK@aNWZS0It5ME|28W~H@MqEF@4 z7nsLb8{{_IGdWzXthMw&q`JO(Am(fM53qC?`oVhR#bB+Dz}he8HjWDy^lHMza{kA~ za-N%H^}k=8FJCO@>5Jw3@x^lPh~%{RhG~nFJz@-*B*Zh%0b+Ztg|m_%C1BftI}F;k4C}LLu5k2xXIKA*oqGz$)b8 zG{?~ZN0R3<<7fphPqhy@Z61eVZ>qFa{E}W*JpSg)l!|Wo=MI`O2Z34JB$GFi>A6^@ zrF^g0CYj9YsFE+DP*vj)^VdKiJB0cD{g#}}Tu+L&KHr6u(2~aaqY6D-vdRKWwnVJ% z6V=1n7pgDOUTyK09rDBn=Hh9{cq5dey}FqMUhyaShTf3QTFctCCfivbTrC&&jak9l z^!LW-jcJ)X(a+4>3IohdKAf=J7>}=IH1uE%Or5)R6?A+wgu%=MC=rU4bo`mgjoti@ zuSFk74?gT})dE@c7@m4ABbVRlXzbcA3?Y62f|_6O1pmpooqBh+rhg)nJ{JQ<LTL{!#y!JoGiZExYB?5thp2WQTO$F*$E{oFq8OEfC|5u!n~88@dD?5Kr>dvUA?}sb!yg;{J>^S*OItHa`Ij#4yKkJo1#I+h`ej zJZZC-oQ+mmWbWhI!*@|>HR>ALBlBe(%2G1Rj%Jpf{8~pYuaQC27+D4}u46s)2LB8l zBl+grrTLTj?K;3T=snrX1{i0I6CJNJNXP+i3(F|H!|4Dq6+Uj%AhoMOIxK@^%I6@T zWst(LL4sHxGVFx`NGH`GZ4oGAgEaKG3{Uly zm=YdemR*gZ^75NVK^|4st^KaczVnmWQ*)esG0wej)u{O$KSEo5Rf>4pc++SxKR8XD z$EmdpzH_v>cP#48-Q$jf(MD@6?zQkJ_6<<5K$$MXN8su#bctEjC+RP53cHfp_u58w zvZE}CsRhm=mV?|R%7UoOF4Y@HxKCH#3{QYRv*q!|15UAm(x=&ZzSYI^mV!081m_fr zhs-!D=-9k~Lmt|2cgaF%PV2y~h&!r=PviA>$8vlu3{;!?(}I&$e^gY_em2yU?|}eJ(4mGP@+R!JrN7QCU=hx$TB?BRKN&Zb2cFi&J<6 zFilj}H#m)zN5{38wR{sV8ZE4=uC`0$T^Rz0`?PxW`y0v>~V=cyvNIbpqzLlLG zqDrhT6S&99Xf-$)u)wVfbR=_~0{zEw0Lw*Y3jZkZVyBn5_1*m`pB2QS9em>IiP7`Fx&dAAx&FX9e)RS+ge44)^!r}m z&3EvjI9$riaT;&9_lc_lJ?IJ)yE6AXS{yt5Yn#c!==!!v!4{YQ$yOe)XI^W{hf{vv zVfo$SUwbV}*#F`o-u$ly`Pbb;h>rv)=jj2O4?8qsaBKCC$XsoC-M01L-PqFAzc`6P zT^~9c{MI9m9P*5O0m(ewpS24+WE?2jUwE>&-l4%+MklT=Omf_=pOI!? zSljzK+U)iEbJC{GYEFMnfW)^)|8_U9Pg{*j>uTt-PGxP;)+gS3YM`StXU=&8=G#Fn z*3gP&i9}5@8i@Ncu(a!#-`7Ta##Vpecl?SK@GoRv>b`Qhqw>lUZGEzD`(I~rQ8dN3 zgJ0vc-?xu^4Ijo82b_bg0kU8fv(=hwsA_XVdt8B`vS}|lecLD&aQa$NWTzK0h>n&5 z^RIBah8o_iEjg@bcZ2rmUztVYRmp)IYPK5x$H27I z3;{tNL!nT|dUhT6X|HolL+E3sqZ_9ir;L`aXBBQ-1T(;imo9=6s_GoS`U(9Ui#pYV z!pMC1*UDsB*kIv}IU1NOfPjo(Gv8rDckkC8{hf49P55hqJXWV~^3{ugD00}8F#?-K$~N*4c< zvM}qnaQD&Xe{v7c_#oNsUn@`K!nH|OFpFuF$z&Icc*u#{_KlZksQ0D#VTa@1P(mnr@nqyU;=YGTc8?>pXP`g(DG0o7zC9xLrB0#aCpHSt82J^U2 zRF#BURhgG5W2mkhYKZ1QrhI8Kq-un%c~%JAkAQs2Iewizwv??U3KMm`p;l$4T13_g z)qEA~e1^43ndZMpi_-)5z!|ezD)r|Mom6C_ou4lt8+Ei6TP_yjbja~euv&`sVzt!O z53BPi3NkOCM|#-qDP%=`{qI;&7(Pa*tft>7qYp~HF9Qw|^hPpIeLz_YinVGh(R|C7{nEfw^oo)-+k z|8LY&ZDdjEspzl&RoOZ(q@Hc0MyaPzFpGN1Q;d4T5Jjoy2dr3q`b$DRJ2l^Sd5e<5 zD52`uAgg*8G}j_Y+l6}mSaP1O@+`oH5$YMRsOKy@+k>jxA~}ZhapOq=vn%6IjuuFy zyIJwZXO%3HF+{c0K-&Vh7F8Dvk8 zPU)?o#s?>wns3zKB%LozP!k=co>9`N)&Hl|r>K3VPqB^anLu!ge5z%-#giK&otkeo z1r)P!0j~6;)w8VzEea7~rVeVpqf&ZHM?8D_-%-iAs}$6TengBCp-M4w9lA$|>u({h zzZZT^*cC<6WCvFdvSqP@zhUj*4^Tynz*dcn?A{iD5q?r#g>ioM_4W-;L(zhMoht_} z!zau<2l19&fOo7 z33UhLB%tZPPEp?F>YwJT>~go_idZ##QZAD&*uSa|yAu2lHX?@IrD8C6Ai`Y+#=>>~vq z`|nDBmem;L=`ZcYMCp436FaJ`%_eb8Lx+z?2KciWZy_V2xOI78t|R9-X8G%ePb&H1 zS;m`pFJB|Y{cC0TqkN4NHt)|+d`&#fT7!<<)Gpw_u?t-=6psC`#j#6?ejK}0ihcjp zRATKpVa2gufLMhc{|Yi&4P?Xf*8d`c+migZx~gQSaO3^=6V;!{ej?9(xp7%Y(f#BL zxbc5_Kasu4_&fI#f#dJmPoz@WPvp1Xej-Ln|LA_QU#894_s-u>dM8k^;tCT2J{dk@ z%v~X@IMZlNlSsOQQj<@XQgkPgXU+F#3K-VXV&xr@Tv0|`t6$42R9vfX=0WJ!EBwZ& zxwNIIxjgiz=0B2pVklh-HJ3aVG*Jpt)n|*5&RmReJ$-p}i@~i??-nE3AvPgRRUvQI zrf{(;N~|iZwheUx<8*X?mPPyUSlyrY?Xqa!uBcq&iM1C({&&&7_H>3IO8cyh#0aQO zX_{?iT&7)^ZvDCDZhEq~3(^S62!Ug>A;}*&te#(yXSMSSuO4N`lPa&g%fD6_8@Q`| zmJkEs#@dK*W346J5XKxws?L6_d4c)75H>{uVaeBCT%h4hC67h?cFhuj2JYN&+(>^q zX_T|PCD5>FgTNRW_y`h84+_k85W5Nr1|);9EvWaOV$}S}z{}#k}8La0PfWZ_fAn)44)1_D+ zVlL41C+3pX{MBU)w`!U()?4Lz6_kzuqc zERfz>oYWlmnJ6RPiw_YQhKyWna27^f4ZSt#LO%Z_^{Iszm18LO!S_9APn5LC z@)eQLT;Rq3wMaAk(Q~#>r-I8B=X$xqguPW=;Mc3d4M*Y~om`qY zvvx^7Yvo*!Z+^Jpy?6%>Dl#{_kB{0l4iTT4$47oIbJk-VuT0lJ9NX|oJaz^C7X^JX zcUUJ~2*B@n- zJyl+p`}A^AAw|oQSMAYGrUE?knKI8k%a#qOTy|$HPAf zz@7HUp~Y<+2%S6+pCg+(_#!)QWI_J>$O~44p{C4G7cUrf%i@?P{h189NR#e*wfA}xZY9O(~WakLH)>B?(9l4w?|P#jYQTi>!@NbeycB{$Q*LS1W^Q!1W{yA`XkC%K@{Q3 z`Xb7)euyIX;DRVez8q10-Vae^hW|lC5#YwXDxg~2p&*K^hyP>Pb6hUn{X)A;| z@!#$jrQ4v$EQBnA385_ilj=9~??IEQ5sK^uqNG(y7MP#2sP$JBUKt1Qef30x(Y-n# z`w%S5P*H;zj2Z+}u+$zJ3VqSESDUOixxd|=w- z-5r~uxaQST=*1uzjaJ8wp}SdE@%rX-?A}V4-1TN()DEk?KZ@Q2EHMYXEqg~=Xrh%3 zuJOsB+&f!KA)0f3K#8&o%q!lN?5SvHT5jA@&>4<-Tu~lrxTjS{b`X>YT*h8*zfpR_ z=LH^ezs4=7{{9$8gWfcPD`Lk;cPCz=F=2TLu?JPUw^m=iOni-x($*(v&z^QZ)$pN{ z5EfhW^bj}A7}9im+eDLYA+e)E$y^nrtVzfNx$y@gW;Wg4qe>yLPVBwp9=LEpu{q%_ z)xpTkywZmebC->rWo%6w#EVhZu9z1(WvWtlbTr(im;o0VS$LToxLD@ViffUZTx?90 z?M=Ko2Iis8a#C;MR3tvhi~=XB5_*r_`xT?g8St6t7!(%-zUK75dYDH=pyvDCW*7FB zvR!Y^+7*F{Z74fdWPU;5hmg=%kz#+6*-R1c(s49xQZj3cd#iuMs4Yvn_Gj%{>`zjl zWrbUEWmB-V)4HN-sKQ7r@7z~NAAYE$l320JVL7>X1-1FH~--^sJfQe3sbZ#Mc zj_y|fOi}O4?HskGYyXm*D5xku%rbUz-Ia-(=xs)Wd+UmcC>-Skro0BQc*QeD8Z+Hz z{AJBF>m4*#|HKI>?#7iLhKL2!TxFkynq?9Q7@L-rSg$1;Q#PP&fXC-{QBCr;c?P@; z$8O7P4aL8l&cg=z2W^SW2F$)VK1?#uaT<0-srl^voW z*VkpQ_;Z6;Q{#In9tGOv*Qoq@lU;8M7ZjRnacs_dJFdThb)XnsQ%;I7ra|AS>Vjn$ z?uDywEht1h+m)1mR7w-C<&b#~1>J8hyBZU>+(XL=ICEBS3R9G79V^?YKwsERZ-azE zf@r@^OcLrWI|LXmkrJ$9ER6hZ!dfyf3uWNTP?^9Y4u|M?8y73Z++f$YPa0^6yuz-@Q)j0GNGwaZsP=oEJu>QTHb}I0q3WS!@HpuDb>e)#j zHJvlu7SC72SrIOU2+83LJc}3$AX)>5yBYYOd z7_*EJtm4z5mKS&q}Yx5 zErqfx!M2}`4I(13TEcctI5}-? z_{gEZo4BjJ{+7wp@zB{bU`4#%GicQtdQUpLkrg{JYJKug)OpL7)tNKF7kqFer<_%p zdUwJq47L(IgT%cpPXq8JA8ZOgkZyiH5LHu`JPk)DsI&>y#GDLZ%eGWDBOA(CwV{Ne z)VQk=UDv>3m+^*Kk}Mn;3l87Xp5g#%XFJRzR6|;dq%C3VzsV`@o+Li~br0wAp!XwV zRRwq3EO;I%cqBifAHZ!d@e?!9>g>>{#$f*f5GQBO1Y&H5%Lcnf|%fDHcym z8I1;cyjDyZ)e;^Wvt%5wpa3j+o;epA#^~a-+W6%cwb5(#*Z7A>8x`i;O&7Egv0}8^ z_*36Dii(ZX;cAzejF!2w%u5Z=!2+Z>qrlzh85H=s%Per&Y?BFN(gadZWiCP|tSg3i`s*&4MF#B!y0JYbBFk=cUfrS@8r7)QRwBjgV~VHE*066I7?y?x1r zRZoH73$-&v5#4?k4!zAl{+T|1|c`uos+8K>q@kf z%`%rUeE-{-WEa2;flX8IzDIjhxJRvC&f0o+Vf9q4ehQ>S@6OTc+f>?YPp;m5i}pxJ zz0J`cd09Q&s`>Ww(2_TSrDY41>t=~o|3C7{ba-ym%>=Ffao%L|G~XY1B8YfW-e|o4 zc?Y)S5#j_Qym&PIAI3I=Wktsul4rY_z^m9#Y^P@M9}|QQlNNY`wus3Dwh0~o!K2>2 zwE8v=)cD)W3ia;q5GQNN6m@(cQFl+#{03?dGk(NRo7p zK18Bq3!#%CFLJFJi1(f81FBuxYYlp^Ep$0fc&3kxy#6*c1YbO{*DcDiB6MF#P6`Vv z2jZta>tMkG9JQMzB{bKHEn3o6&oDWq&U1MN;bff~ilWi}d9KhEUjlWcUw8$VXa+g1 zB5i$&-czYP+6>rQ{U7;P@43}ep!eMFnW^{O;kj1tsnC3#qz4M@wKr9GH9Z*Dk|Wz3 z?u1>7n|Kx^=-A3X*}SlETOZ^_CQ;==La}CeZBLeWSnY#xlf75#K?mvNka<|#RNM1a z^<|1w?;sf>YZa{RxyLiIw&%N^)Y_i!d$igfuV-Lw&x5!{>?!ds@;~4TZIp)Mqxtoo z`-q&-;~^YC&kwwA`6hF$fRGnK01G1N&VAAD2&SlHvIwsE=hHQdX)-t5$^}JzVt)N3Aq;|e*P2BWqLZKlh;uz+dKHKA* zUg&jh&dGq?5Xbg{E^z!s*K(%3ifUjyZ2r6ns|mf3myQ>GW_oqr@N#_X<76K(`Cs^6 zTuDH(9%PmR8FnGHrx$yj*)&T+?bI^Nig>P_cVoJ-%2j)Fna5KY>4WE6;$3pOyTvng zO^LnsOqplWng_!-omrl+re)2UHT%vrg+^-Y_Y(W#x=RyX{=dY94Mn z<9$CgLR-J{{Lk{yGJ}%FpTIFA-MNbAu-F~M!s~V-N9uO<9V*BjRvW~9aCinN=0tqyz;ngnuqtApDLj7n!0M5(Y~4ES zlYCGPf-2)+&|INT%U5(e-#*~)BmU(1lgOVu%ir1=Y^^e{a10PVG4ftkld_1RJW@e0QEuVAH1!YW-KzLhXiF0*MeJAY|x!(wT> z?H-Mw?gUSioSgr1T=H23$Q)`u!HS94kzP7WaikKnewvL)#1Hj;3g@U#`a`&({xFuI zq&LIc=VdVLoS}!BU+vBDij||l98|}yCp1UpNbSw>?^X_Atu}?}R;yrs;Tj2h%wkww zc6N2{=jP;MS%teXlb)7buu}O$_}6QDxt(P4RNh=tE~XxNcNZ8otS2S7g*dD>pX1sA zFOkTB%C*9g{?K#qJc8?l(>7#Cg; zC(O&9R;j{ipPfl{7mE}2%n5|(&Dh|?;)D&xY)fp!B~F+`C#f7BjT3gIys0>0zqhJ$ zMB;=gWH0OZ_BLW)@E`2i?HS3&9T_RcB0_<16yb)YAaiS1BLhUlK5e~o;7xJfxsbh^ zX6YgO@+qep9o`PYNQ_5(Y@2bGf2t1{&VlYY?{0+D%TojE2ugAeBde~qahrcz%YUAo z__4pMDdeC%d=9p%GNT{J5i=WbN<&!^u!A*Jge8{C{K_UFFs$8pVyc9aB>2ln z$!1{Wbk_W|S{^s|I*?%@;S+4n4l#iobr3a|0z8_`#+J)fP#7NeGvXadfCIt$!B#k* z0#lg4&)w&Z9wkcQqKbZmA&L%$9iPXGvx^7D|`VgE*bf#keOTOs0jt6DOT#}gGm zNiBSdB@=b|Y>~NVk3iZTN{%*r2h9>2Yoh9b2q$95gJ>TqUGkgRFZ!Z zu>{OVeki(_-h>S&kCmo0>A}<{vnra@X(gptlT&2g$pmu)UtPUcnF7B&u41(rwzc$vuw+T)Kj_|M-h;J0$ zThaN{ohcz08oM{C;w;am^E)&hfy_vlmgc>rqP6jwl!^`fV-EZ-A4@CRBw?E*oUV`r zEb7TPXmh+kXot7LC4%{{0XtGEiHAvt1_86)>})c=ZJOWxS#&P5f^{oh->UjvJJQq$ zjuQDs!Zvz`m`_p!u7wzZE>rl*QX=+>Tt-YP^UvXg7CMforZNr@atR9)v9s*2fn1Zn zlLh7vIen`LkWQH#sYQ+nR!|>vCks#9Po>}Ut4X99*%bs7mq5Mb3lD3DA`tA##*dWy zy0or7Od(|(r}ANs3C(EbYRZB5Y(qXwdHFQE_k@u%-O*4twICO}<|8kQ4S)HxxoO^m z`h%Xq%m1oxFsTXmlffuo(d#}z|8_Uzt-GLNDa%P(NVTGBjVr2HO^OhaVd>JS*n18F z7$X+EXtBPs+a}{gmJG?F!ae--^*)!6AmFbB3qVWcf)LfmWpJ94EjUPtlYXiZYX*0J zC8!nqCPD~viB*7a9=;V-Iu?U(i5tX%JCxwwyfV?){A>AA=`1iaHnYLle*GY?=C_u~ z#3$=BbA+TF)X8I6i(*h&I<=>_JsV8XAY zDr0X$PlBIItrj9d-`hF~6(Nb0ZrtKZ6Q@+L;OA5njYND40D4&8JatapIoFBO6z?CF zu;*C4yEoT0HD1~f>?<;-UBN;Wkx$ks)kt_sg884XMp`U2oC$g`9lW@QLFQUSKbP#? z7rsGtbHxL6bG+(fX{2uGEch|Zd8e5nQM}b<46SpV1#F6vF!2>Q# zwGv%^Zp0$%ftj-!T|}ejr`@g6qEW(P@xlHDBr7U3_V-5cB3f9AH;EWtnonqL=&Cgm z_Z%m%Rt&F9*4bD3$MO1x{=P)`C>oIHC^(Fx6m%ZG3jYDnrcLQ-pAV|7GAp$=vrchXct(erj~1tuary8_!(v zC9uH$;Jp{t4Nmc=WNeWiHKCTFCS4meew+NCAh!DuT}@rFxg7E;FoUR zZ1WN{J`%|)G25{@bb?L>rISyi<`{wdp*az_W07iPQBR-?av$9{x|4`ZjLqhAl#O)4 zCuJj@P#6EA?_sug2`(?@BIP?%6jOSuK2E%sizz=n%z;eh@ax!|2>nPkF=R))Tnd8c zU)aSQe-hcJ(9_E+uZX&LCgpYW2eDS{Rx9rqL?NHqj1o-T?nYKu3M$YRm=vW}tB zo*drFIzHx6)`)&IMf;yc8BTD)Ilh(&o>4m%YV6afZU6L)a>JQXuD92e>)kb)uLq$| zxi*v}ZRqV8u5xY2jCIgqeuo9s?;YL8wUqX9t*Y(Xa&1$P%tbvsY;%kkwA6$4@!}i% zxK=vd_xu@E@LKiY2$pLTruc&4nJF7T1&GX@dPhpq*1FS_s@3%E5LA(C+BVj3{wmk* z-&(GnX^>`IC$uA!9WuyuaApc^zeD2QD`~QYYprqJ@b?$~4w2r*?+2uB=6NT1x~N}`@1_O^NxS*mOwt%> z9$4O##69FcLf#ghsdLfsaxFDHUgGY}kbgA&(s&7-CC?K(Z?@SSjT@iIW@OtYE}d?( zCAHOwz9(b*2bVy;h^iLtp^foY8+YsnWJzl**NS&-yql8cTJtU%P6wlX1*(93c_l9;W?+ylkC(Ul9 z+0woABD|3x&QdF>%{}y_MD^FE#`OLz-i`40QiPx~S^;qt({-S(QPv6tPD}xHcfWiB zBxG?gbyYi4%e5Zr`t)GA_6ffysCzlcytmQV${sUr5t&^AY_M1Dh-)swR9E>>-l)Hz0$BfpAR zblkul5iigfZNi6i7(!9CH=T!WqZP~EaLo+W|A&7JK-!}xWuejaM?*Yx{E#$75SZ8C zhR)dvJA)3Y>qn3n{bnkBkDB*L&F$3SS->bq$kZM2kuLQiSLc(9FQHU5Go7}M`_&bp z?7-m~s`vg1*+6pLd$PEswMh-{4jR|6QM!`U#^kV`sycyX$RLYi4oS^8t}WiWaTEnQ zq^l~w%(m}8Ns|6W@Fg;O#an>?5VOe)?A=17JaW~Yw&sqrJS8Bv41O)+bsC)cchY+2 z*ZV!1R;1<2=T`9Mym?jl;bCFKNYi-L2yAvTiSdFA5m4hN^gc)FSTr-%4a{JleqESB zuAibASTKiK8qFI&0TDayS6>)2CX>;u+Lg}3E^F|U8Wl#Ug>o;un~ZUqLeL@c1^j{x zTQ-hnG&t2krtBiKaUe1q4SmM> zTg*eFAY?{{>UrHUs(d|ZCpe+iKTW;B=^06;W=Di*-)yrjyFA+M^FCAoWDF7F(<7tH z*z96#8r9f@7D_*QyPy!#XiWm)hQtft8!wHt%GSK9ed8G3dY4)C2sE`$+p448i(NDae>}m zQ`caFEYy8eD?q$gTl~80Nuew8c6Bza{b(;U63rLMQP)_@USIq=`7hWCjN^5m$QA+J z{pYs?Mo;$IzMH^S;G^2E0}VZidSe_aQ|;*v@T@qzLG}*zjc)c0_6b3z|Lgk%)ZsMq z*ToXMe-|jlLO-z;2-W5xTLaIKv*J^HJIuHD*a6v+QluBHeBTCqU5+KBN=hStP5L=o zP0nHgmcJdO2-m^ZRRTM)DQIEdMv;G6JVX6p*3HI|ysK4Y<4tgY3RFR<FsH`17mqG#o*ykB0xH{EZtMS?VcC6&HB+3h|2RrUl z2}|F-g}Fb{yGky~+dP~BqYNh6YL^YI+hQTi{lYeOPK-b%Bw*7Xhs7qXNJ@j)dsZKYrI|+!PH-ZrZQTC133U7 z6dbWR&St(IiXIU1CddH+;asuNlX-lNb0#tQI8VmQ5$)I#4#`QY2bzyd_A5d=&>Y{b z7Femr8{uXf%+Bydj#feDXOPsqj$ zaB_i#7`9X)*#uU?gl^`z4K8IB*mg(!v;Fp-`ZSA>2IGA=6JJWr7W-+lamRi zm!#&^`4)A-n_USeFma6yc57%aw}utsdPn>^>W3)x z?fd>uRKMH#Vuu!tkq7C2oBHk7|BIr8=Hp^R&ZiidX2_vIPN%Z{E3yXv7&`}{v)!Q9 zvKQWdKD?BRmRZO8^bDJ~03N#*spMQK76;Aq&J68G#@()Yg)ju;*dY1L4!DVs;kM#9?W8YDrgkNv1sL?>QWe4c&2i@KcA- z6{{q+4-Mmit@fe#xq9o_Z10dF3N|dJ0ttvKo`tz2xi1lZS{it&>vY$FOLw9C5UD^S zy<0M&;bz>2QR3wvC&a7casjDQ#R553igJSpIlPyc2aZJZeS>_VEaU4=BN0h7HUek~ z*9=%OVn%jxIJ_*SGVx9{`7f6REE<5sh$TWp^n;Z*7tgckcw+q@$G*PN!4U0Z^WjkTjcovar+ZCpHrE-5lYR3sk~*p@ci?Mv8w zA~$J8<}dGNXhn*Cxsf-O9p{Ve=9$B?_dqqdaEXX@ zi_DkUAXNoJk)aitLE7rtS2`-#)mAz#hK*$%&y#MhX_h-RkE?RHxr4{jQ}HQ?pyNDO zRE`J_dj;_=ALA<%OaCIbX2Vcgs&tqO#wyu7Pm3|$v;%Z%V=s#&gpQup#l(fFPT_%yxuq;(e! zNX>n8Bp~(C_hVb}GFk@1&JRdUBfasF7d{~!As}^%tiO2X!XJr6eF{8?U77u@R+sm- zdX}NNu+?k(wfgB7wp!b_Rk(ddRAM7f#`YXptBS|`0`x;rx7e6TT*EaQb~vGUBVmmz zyUBGGq{>XbBQ~wz)!`v%D?dF>NpZm3nTjSKvkMT{sa|! zd6rP9(FG7b-!v1UxV**+~=D9nY}TWP2jz5QaDVj#6K4B zj2?>Mzm)ocSpW7(TVS?p^2gkg8T+K7OU`ZT3&AAMF=8I!cy*z;A;#xwg5EgbpNOUF zZmb^hqTO9~lnBd?*+#+~hDZSs`V)*Bff0>n<<8KQ2!!zW`frZj8pf%*2y zTUO_u!PLt?{7a%FXW>LetN$FdLy>Zpow-(B*PhrE3zCfPo7JnyyR2Dg?CrmF^w>W! z<`Nq@{oe4vKiM7Kbzv15Ik~si(C=Tz>gAt}i`=)OSL#0|Ch|M@KN!OZf^n}*WQcGj zov=CgjBO3kna*I*<4>?Y{!%_JG~EY0CAB}4pvYgt7sY41-Wq}N%GV?&visbM@fVAV z9O=m_CsC0{y3eU-$XJ)9WFGKO^_QrC$mtRgc~o&A_Y96Eg!Ks}MP5WRlXZwTL5!N9 z>LLEQw@3)YO2=Jm64$idRA)P+!jjfG`Sq4CW+~Y@{)E*d@XYk~0y=o`TKbS6*Dh!$ zCal)7wpis{k#Z?gZc=YK{dBzdEh+dP6y)xuN$oC@@Dr(tNCSy?g_7jGPQ9Py76dJ* zXcSV#XK;fpcO`ha>J!7WE-ljHXlZelk*FX|Ts>SrO$^Tk=q^S|Ja?sW_09>__&r}^FQU?NGvQaiWD{3k+|MspNvNDMD4^%=o72*^-LOU z3YAFo&H@#^^Sa*Xox>v0I|oIgcOqF?;vEXuQQ)rjZj*u|1PLZIHQh zDc|bJ#%@BIK0L`9j)$kna9pD5oh7~2dr&w#KYHbPWz!>NCtOgLD6)OZib`~z(-^GW zCdxJVF-O;?6WH7NJ6d3F zVL)po$QL%G*sGq5kzY${gK-Uqs=3KVLxVYp>FJzrrU+?)%}Rt*XKLP-(^&7hEyFQA z&O6{#1ElC&Ygto6M^f#(_B9Q?S&E7S4T1<9w1ama%4>9hB=G+l4Ol@Q0b--WOxT zL#Z&Lt>LmJz0zfWXutxq6e0_8GU9{+$HB2i`d8NRGR;<|RAdVt)vZ35yC+P3peDBstj%1(YKb14l?wMfL z?~QeEAn;V4BdYiO3Q=t{Z%kI4cSi}mDKbBhVeNV-WCQE3i6mz`v9l9cBreob*p2XFc8ShX@l$OXfo6%$* zdYX|~osdTb(+7GEa_q|vZ7{61{^uZ7SgWwCen>&^J!1a+-xVe$8!HbNnJW+U88D^NqNK|fR&C$Y+ke_q z%aZA4rVqn8NTefa>1EJ}LpWH2Dv}K0XHWH|>50;U8Yh%Qq5X&|{N5N$5pwPVroQC- z$bJhfw4AZoPc+g9uAskvjve7ul+SqK>79S2t~t)q(wE1=z!<1wc+mI#4v=5B|r@}`f~!V&{4x!dt3nKM*nSAd7LD^JSZ z4S{Jz@MT5>U;A^rBYJbz9gz~Tod?kAw%7pF3{n80$qzt>%|q%nDr^HFzG4zc9_Wwd*f^`p~e5Amj()2Lrh zx0$!}0=-rC%hqtm9~lM6L*-PwCFVBcn)Z{;vRNeuyv@{v)xe48tgUObd141Hv(n5k zKM`{7vnmPQS6D$cag~n3O4d4$#o=LTqDRj3iUEawF6;aA959&ZXShk z_oi1)wVJN#+cfS}tk$jKiACXI*~mqWroP4x68hELj^32ilUx~RUJG!g7><9JKJl$G z#hk%O1T@P!I2-5YE6-w+m>|f)M@(j2W{n(Fnp49bg+6KZ&y&Z<4T_lFpHMj^klR{Z zVBWTgtwFG!?ebe!iZ0bmN#6*^Hzbk66@@rB{Lmy`aH`?IvDMHb?;~E_VR?LIH&X#_&394>Mg=2AjmD^lg zAmbk%Ho;PIXH7Ogg)J#I!xV}6&uT+UJ;wa%MnGLvNwI#Ctsj^CnCVZ*ppK5LVJ<;_vyJ_Cs`*QPASJ9F zmaO1+!=EH0E6J?q6GHa{|5S{aF?1*RKO3USfOVCe1(J87+iBYZ%W|#q8+Vqw+o~t)-9M3=4isOif2{ApQ8y> zZ8_kHon+C0m?K@vQN3Uvx^wxUNS8F}(m<<24x)9DtsL%3T}u|2Z!&&*vy%}_lq@!n zsgBUHF`;5%Y%RhXBJe<5IqX?O9R2owmbrcBY2=XF!(u3-y%bkqir&Af!=e$|OS4E^ z8BO#oB?0S<`=SZnC4t)#EGRs86qsUqrb>I0Xd(igSw3wVivKjp?^hz3#}$}YePQN= z@@WrYD{Xn>jG<*YD|V45Nq)W}t~bh>V&{LZe;{JLYg^E_Vx1c3cxF_cuw|f^76yFc zCJNUB5=YP$@SWt%zgE(a3;zNgOAe#WDO@#u)!14bcqlelO$^qKou`)wElXNpa^tB^ zRVi#Wqah1y8SbWPLXw4Fl)B6pISiDpL8L2df3bPnV|}R5e4#u=YSm&zvl31kuBS6J zT{!m0c4PhvYe7LRHh$(eQM4%)D@8)Ev8SIk=TeAYmiZh$$%5}=saV!=wQ%P$?ep1N z#CH$u4kkykn*B%^l4a*ljZwvmW-1%_cVwD+UMBr$s*F5b*ih7DpfgIh-*5tr7@VGe z^*z*l2WKKyrgAIOL;~(kTjH!qSTTIs*kwbII8U47TrsA`Rd;jv8t%M@n!k${F*Zk} zzUI0AWhP| z_5L-~Rb;*fK$2cRN~+F1`P9{NMmSn9a$#qYd3mhVbV}j5gFLp5WBh}$h%@$aEFZ-v z%Sd=iTvmE6Ei%7jRg3qs+_R3{laZpz*V|K>-B@5vA9bLx*nF@E*K`TK;6q7zaJt^o z49~tBl3zKUZ;KuU5yb;$o|6cek~ma~)-)N>hbWR3Q|s zq)?jPVzNzJh0>_<_#?E`>f5yrYzDKhnF(a!lShG_P;-4f%L^J-pW~{OhRqsn zu5OO8-Gl9*(GHxH8GAcK&~D_U7Cu!(EY5xYvR1#h+3(#(xVFcFe5y&(&*W+kzsMs= zkN%$DWyy7C=5eIg9{r^%n?hB%b7N0RTJ_DRT5|U!Gap?m_xKm?dCGwn$sQ^ldfcCr z5~(@(&`=KRj(12I+SRYYyBW|(g9~|-2J`vtZSZE^a98HfeFZZ#r%$v|p7Q77L35A! z2X#uK4;$aJp2O%G3Z6msvAItFWs!35RY#=2QYL56$RlO&Rzo5t*2$TZg zc1{lcL7b#OobKHKh%XqkojAjMiX&QXv*Q>ZFVBbaN(EUuFy18aHrtj>W;`AfIBF&^ zh7aG*Q|K}vxm2KSwp9%QmciPOi%93YK9AoBOv`DxKTM+|!}jxsW!R=`zH}+I%Zh?$ zIDpI88X3EMYwYs3t++BWa5TE&tAH0=Hc2My18}6~N&)F0PodF(l%{lpm`VYN1Cs&> z>ox8tl2NvlOHcD>TsH-B+p3fW3SPI!jkYGOU$hdsOp0#&|rKhG2IR?lK+C6+JxyEiwy>qHP{v{68A z9e>gWrJ!It&s3%?j*f~hG`Er5at=dP{QEbw!y1-r2eCx@{tcb#c@NK3UDr`S^v5Y! zgb~y*Db!HcxC-J|*RukGT%Al+qAT7gs*(E9Ay4neEVf)6T$I;swK>XBcin$&hS9dO zI}?b$e?yz9{hj0SqT`CDIvTH*{n3fK#z>Ob+nnTb7DK_el&zpA!^OR(>(G|BxgZ^y zA*pX~d22K}mP4Ew`|pz*&mml)wqmy;iko$(<=?7nL?!%M0n4%jTsE@qbmq86g4Jou zl8n@hx}Hy`^_;6pk_;O~E**;Bh($E|mgs9<#9|?)yu0q-1n?oZNVDlpGsHBf>Uyz% ziabtc0Za-$)B8N= zXFM|%xKTj4lO|ClRfbNFXKT9fT;z9R5L6PsG*$>@RdXk&TE;7)ZjLL}XEOi-7qDNT z60G@3FNWW@MDbfLvKWI2re)1m^;c$V(_bWIP@95q!k9^KE7Tv~ZoS{oseaWBH@zxp zr$Do9d?zSGsb|`!D&xBiozs=EV<)(ai9sp%?2E90QxiLcj$j8bkIZGMt^Gm5mmBZw67={(4SXE5`Nr!D= zhGebqCx&}1GLwSK#TW`Uw$kTK4RXg{eY?2K{$}0jbF!9}Ml!`lahNrVYSdU{jcrn} zQQ7_^(|}+{1#mTOH0gZk>%6NHScI|Gh77u!ZyT92TZs7?GN^!8KyKKG&?4M10}_gd z4n~uvu>j-Ws_7Phi??i~zQ{_r{Q}#a*h=^fWSxp5D}g65tePN{h~_Qhs-4u&bSVQw z&#x>v{}a6ikn$N0qJ5E4`Kz(G&-s1WIB|f!5|vJG8kWzg=BpcHtlaFbbJq2rvhn{w zUx^Q^cM1bb!rC7W6gl>V@{JukJGkiZl;IQjL%Y`zcmQrEP5Z-fN2dtbBmO!TrYTXy zcm!S#DHq&tXCCk&#_jede?2sS-+*(tAE%5>%m09DYf*Z&_K-(bT6+j!eMq&)2YYKY zI=kL39d)Yf&2ir3($H41l(zm;{ezblo|k*{D>)uw+~FCM*=_ktU*ig7+t=KY7+!rl ze+6Ojg&tbGMD0aVgDQ`|czBpTW0Wsf8tSO&e^Jyj{A=YNO~%dts!bS!Q{M5MIW9MA zxUi1MpW{yn?|0Vns=skXtS<+NYO}Y+cajRg0g*l~+jpz>haHaX{s3pvu!OzK+}za_ zc+jqgUD~4u$YiKi+}pKBWGx0#Z}dNTl=9FQe2E|T`&^WBAFICJAfmnTMr7P~gTcPw zs(}U(F(m_pthJwTb9RMG_mx6}s9Y-6#deBx&XAO_9-gr!;@&rJaLF|x6 z<3$-i;|;?nNjpE){&3FGU5q?bxq69oAq9E4Dq@Zy6Viw9i)y6auu}VH9#&+1jg%0r z>OLh9{`arh%3N$(_E5=&Pu0B7>YnkWKxYk&g+K0d%WrfX_rKT)AnvZJ@kT&l0#X@O z?UU+$Rh6YrYk*epRLW?PaC@Cl6C0AwQ)HCz$;c#Hv^;Y2Xw3 zy9?}VZXd2@J~HniL)Bmb6|Gr@Ng^tRC}*7OkmBy{sv9g6$!v^3*Rp(EF}|dugWj*J z(nZf--QCOF5xi2UkQu>Nw?c^JBl{MQjFBq1Hv-g?YQDA_uL}NTZqICSH>}995FL2Z zjDX;te?_34s5XLd#0yi{XstDCT^-Z(TS1cuTK*8BoclOM74rH)TmKUZZL=+Oj;tbu zkdcMisp&2`+P8L0rEr84sh^FuoSRcR9{HW+olN{WT+D<@^F44eeqhnx!4Irc`{smU zLF;!+`a2e1&}O~g(5`;Jh%b01*WwEv2TJtgI{WYi$Nwf@fJFK4=L?ova4Ei^Rz3IU z3mzve$`^Dhm`fF3U{iU&kS`eaj8zvK;)L^f1jT&^!I}R9J|Q}~)~J3NpHKoEO&dF6 ze1epS@(BezZxls7i%-Z_pQ3!ic<}R!`2@MTvN+~1;S*LNBKXJn1O;b=PuK@?_T>|z z%DC&NrySTVI9w;n=}R#B_*JnnDVC3LJ6RhfW<>9NL++t zjzxe|GFP(8>Y_-=JN)6LqeP5{Ierd1CBOW=3p~wDHDlpNBg3gRD+daLvaMb+iW3?* z5Yka$_QstziFk%8e!UiDm#k9}S5(F3vkxPf33}4P@ohgt3uZGS)U>*D1qr}-o#8C6lIi5`+XBv-VHI>(b<#4a(N(WUb3Z|N63Pm#X* zMY^g`@pG8?p)Xx5`nBl8qgNz-Ho9R;iTfie=!ItI)yR2syR!}|e|eq8+_|DyQ&^0J z8xdVj79!|BYaT!VgKZFFI8^T*uGOED1=4+mH?QL)PYB5|Nh>gqX7aqR6gKZVQ32%I z9!YIrwlgbSP;CBNtcokBLh8A~Gq}(^HlA@uI{h5=aLZg=-0`1MV*-x;lue2wXx!0~ z!7b61Mnk985a+#26p0l7& z3LsgGTc{}Lxq@n3w|YnQspr1)>M_2a4A}l8W3Vy6vBke=M@Ho7mK~!bS0R=pd=5;2 z#W{1;#P#-Ix$kwE+osT|(vYX9xPrN;;VMb)(a#p6Byf#SMiPgK;+J^1XQ2#3fjD$K zYd-xTy|J!4zf#GiliWWckM8CY*ea1MCC16PYoXCfk>^{gA)~v<{4MA1QVEbD!Y4J5 z=6`(@1&-Sy^Zq&!ouT7;6s4(39NeN#)!!4JT)%UFvrP7LDzOesX4_Rj)yI|MRWixS zm13_OMRmc?r8kB0U2^p~KX#iZSD#yVo-PcO+5^r}1?H^)1p=aV>AZ`>2cyLe#tj@1 zVO8aR)o2NQ81)d<(Gl&yeDl`xz<362I}40#S08AvI4|2n(QNV02wL@a>og9*`gW@z zn$gHs9tb1Lr=<5R6t#BndpG#Y4jVrb9S{^aRbV0H`_KE!ekXw?ZwB`Qc`kq1KAbF$ z=JFF!!Tdn(^Cd~=g!|Lvq#+fOAeH=y5qG+#dp8vQbxwpAy%l%6`$`<8)H-`DMh z)Vxs+f$<dmZGt^PHV3B&cWWR_B@!2E*wn9>zg*Z?D1 zW=?OJHLA>Em0hYOBmWjx+8O5;%GUREU~5cg{!uf1LpO z$68VlL9Z^U2|O;(t4nKEU&_76>dThj8(641{Vk(x&zf1%?>n^h1L?QBwPsepIXLre z#P@+mrDbDfa{wROWv>|f4DTykHEgg^S-Ia4xGQdT^32s*j<$Z5eU7_z)e)dE2;EhN zJCnHDn{3|a00R}Um!zkaHzSI!99vpBw*0xkI#qEuYGApCO3R;nwl{$n!@I%w(PO~N z$^2HmH4MSC6P4|e$4Qzfy(}<)kPcjrJi+tpwfvLWQeb{ZCCUAZyp{46UN4oH^LXT@ z-pJk8BCXo|k4UnS`-1q7UguZU%7v7w4&l205vhc*UgBE%N|c+-WNHX|51UT)+isp6 zEANNQll*2Kr0&_G9d(4aQf!x|8>#_Fq@y$J^8Z3w!y51x0)9(E#rrc;T2xc!2l6Cs zReZ=(o~Rk1ViOTOLsfc9ze%K8g|&*04}~7>FmJ^zRb=Hu@6>-p|f^(R+@=2=?Ff_lF?^^w5Jg&JtL#utaR`V@j%=RBM-@#6= z_O#uLJ&``cTq}MreBY&DV9-(%4qlj}j%Rs~eZ0N@M{_0>+$r$6%zZrWH{a>_LA+;h zPU!mmTlRnO^gHcO|HA8fYu{V@_M3M$z1?tUQ`VNy@T@IJnGxY3=JPhIvOlM+^w?-) zNA9c<|4EunNwd8PNmTCrBe$+W{iw&-HXq(b#%NK7>*=>1aG686vS<8D-};8@ExX?A zkp=!6s@ot~(J`CZk&2@Y;-*7{3vcZsF;&UB1q#m$vs^~!z6>q+abnjk86#?W^$b5a zv39}DDfNHxFg_btinb0Mc%$xG{}-)(mUOqh!_ANMu4A&iH<*`^Ykxb2r@pnSowxQK zoY+n!7C0|R@!ky*iVf1GJP7ghWC{(G#4m|GXHd}g^nF;EkSR+Hu1 z<*4{}8Eh5%qZGR$)Pj4LH`D_9RqaplBU=phU-1LxbT?MT z8Et{-la1||Hw>(uX7j}7xOaF@Wo{=lxo;QaVRSpTXZGkHwmVL5I`-)n_YTkSO`mz} zn?BzgWa}qFTsrwbrY_uKCPXS|l?pa>S9kn`3fOH{EQ>U+VJP(XHqX7UY8oNA{$Z!% zG%b(R#KDILiF&m06dM2NB8`VGRVrQbrBOmG^#N?_5*$`UIi=nq(jF550j$ue20MNW z&~G>vaOMypbZ}N!G_&YwoV(R~GIM*!H^EM0=LLhg^P|XcPMME>Eb2!%(Dt7743g3= zDV=}TdqPyoWN6c=BeOA(JWp?LmvIfG=7h9OpLzQY>{d0f0cT#w)gOeNr)6{xS);2x z#(ho{@~e6w*Xj#cKni-TK36E6>Op76G+9@`f8K2T1MqwAiNM~;>1+5joK|F0w%O!4_@YS3K@P`C!%D6`}L<`tj{cORg;l@_fyNUx3%bqDC!leMHGeB=h2Jt>K-heYmG#(P;r$i24gD9hi z6h-IUh2(Z0GtzPAF$HsexG;fr9^!wReG!s=5~cCz(ky zK*9`?KzIn@p+=)NHlV}-48jDoL=$5sL=4zgV>)WKyZ?p$#MF$_qMmS>eaSd z+goi_(E3P-O@dMd^;!@@qf*`JNi|j)g2c@KyY@LV30Cjp^ZQGi*=N6>Yp=bYH=F6v zHCR06@P`MDb?#jp(zfE1%~yt2>?r2SL412h@weo6?vCPb%kQKe#dN7H{I#x9_YSHt z>j->P0<{Eq89U6Y3EVD$FA!*wz@hBG<^nDCYWRIZwm^wS|&AI_P6~3h}G%chDltljHZhB=BeRauMij z7(zhhS6p4Z-{k?H#$1?Z;`-Kj+1OotaR}y-YgzH4@Q~3J&5{~qOZ+*SBXwZsdkPzq zIs$60gg&7SfNl@dX6cVausYn}weU!`6vK8$7issXnb>l`{m|06;jE@TkIcnkbt&KG z!nhMQSXyg3R>&~D+~Ob69&xtgBwEg7=9uKtR{sci_%!Sm;9}|V#d-Kg8W;XG#WOlr z#vNwL6`f+PV=3rRJCo9yZs%~8njeZ#|F4L&?ofBM7?Iy-8AxKb_`tjrdG6HGlE$Ui zhE7NiFF@RSmTo5G!6bBJ@mwCRAD9!wV!|uj`FHu_`;|Fi6-~Q3Gp=1pC)>gwXl;C- z_CV;S=?fN*3!MjHV;;GjjL!3Hdb#?=KkRXpju}|oS=zT5KxH_va%yzTF#;)HphuYJ=Io-4tW zay6r#J;ugTwb`;|MAFrUkhOioQ1|ca#p3`2nOmH8lu+1-M^QDINn;(xsXN)?B$_%` zM`Vd)c7Q*(bwI=T#?!nb?%^Z|jKU4b%W-plKr76#h}L)J{r!|Eir+5 zG0TAEkVN(u8ZTL*ZFmobE|N)@BDpOhOd;eewsglMg4hdjVj1TLS^h%3Ux(F&bWK2p za|j!Z;fKsgl?qxKQ>bQ2r)!E15u7B!q|J#0Wy5nYLD{gRctf*|^lD?o1jzTE25{Yu zT`HLwgjo0SO$GK!{8RQvKau^u(d^a65?Lo;yy!%)?+{<+W`z*0pe|ihi9*L3QQbMf zabL~jSj_!v28Aty35=No?(@{27P+p@vtecHj&=GbDajayKT>sW3RaXRr%GY zmgk~39KJN!SfPw^WpE-yH&%=3TS>}JLgPM}WG#}Wz*($!nI^lKq*+GU|0%uiFlVIx z+wbRlpOh`EKBCI{U&^Pfg2FCGJibu6qSeIX3#Dmwmb6>b(YKefAQB~lNPG|P4WlIB zTl&b6AORoZkbRnp>CY%KmIT}=g|r<4sc_jT70w)6;bj8zPzL*?&g#{lsPJ>TLhC6Y zC{3hSyDaHuhVfdGCQT*wx72J_bYMmC%tbYahI8IXj7 z=pRAEZOj)=J)H4aidw%|#tR}I670Ts2q+HJgS zjR*~YqqCqZ(&oetf$#W?SB~@4iB=7VP+>X-G8mnNt81Ts7=()3utfBB-(Wo}qZz8I zjE!77WZ=Oqni5+H7+Nkd69RlMbEymU2fdb0JOzz4iGx9o(PJZ1sj8XEMa+Tj|KI3; zrE$8(D_;#57x8v5w!4ZxG+rn=$uzz!IN%@1gB+r#39#$Xu4STOI*i3B7OMjiaO8a# zlUZ+g(2D=C=*4IT!Ym-rwL`DIIEH79Q7XF~X~e-lH=`tb*-%jjo@vU4n5!~T(e;%b z3s3O*2QWJnx*w%=FdFeA-fw&W3&H#@eFOn1`XEfWiGTY9Ca%LOrpe*es3^U)3}d8<6gri6k`oqb<8r- zpnk+LJLQtpw-N9vUlelP;n{lT6CIPiVDE%<@Ir*{wE+Qr3ZT)9QqyVlv#9A?>=wJy zGO?IYf;l<-)LDI(D;>Lx+K-P2kJON2{ZBoPoM`e(_bCv}qgzFTH3i+TzEq^26#+Hr zl@WA%^FI{h3dh5u4{`T1^7n}!$(5BYTqv#}_md-uM@2>bF^D^&HC@BRY4>$ZXdu2Y zo6e~lGC`CV<`OI#1T&SWt8|oLc~PC9mgxw$j*w_oNCX=>x=`YzMf$C0NUkbj$fOIu zC7gr7So<23vrCe)(`ucnOmU`>+_@hoj!~qC(SaL9|p znKKR@e|6pgF;T<*;mVs}blXB4RYTlXD}5(1%aR~69Zw*&rb{F9&D?60Ly(OwVqXE3Sqq_TIg)XSJO76PJ%`5I+O_-tay0pL z)E*6FO{vft&;n%ZBfW1&x}DJ3$%6y-Wu;K5VA;9FPGbbf*V+ zDWpvXcn$+RvuAl;Vt_R9i4oqCmKX~ET`}O4ydwj~hmm(? z4|cdiQwIIsl#my8&~(byMBX{xcemX19T1{feB3mt6f5CmUlR#~9lXu|opDpnZ8=O1 zy48`j6!Cj&o)i<9^V&mKFL6LI2wk*9n--q#YY%^kN5H}N4o~}YZ%( z5+Tl8wQ;ijeOHeIp-DCjHk&co>@j{qqC8tGD%d<~GoZ<+;!4llvD<+&)(PT(zOawFZ|x~PB9x4)qf<97uw zaA6Pn2RJ`mqbV!*t3m%U{Pqll+*y=vB((pp(W+yJ{)P`kAour>1g)1I_vD&sMbL>? zHpkav7}Tq_T%%X$Lg1%ESVp*gKq*gvv1hplA=oo8^{;jq2yIk965J3)?6(OV;BA`pUtq7sT5P=gib|XBI^!8r7Jr*r< zM|!;%EYpTR(w&$})iLfw%zkCZxDqjF5Zh6y5``gGce_f{QS&;8QFqIt?i<{l0@9_KrllQ==*7Y4+#G6FPX0kR@+eY5}ToIPx&?&*6~bb9LI=(0Q%m??$>^ z<^=o0jC8xBDda$RyZz0yBKM9rd$GiSfvm^4HF=SSJX8Usg6s0$M8EtXyWD+njaR2$ z$6up%X5_l-NOB)^9$ZsyUM%%4<1PnArAC+KQKm=A^d!rWUOUrRc3mQi)Y9YZSyQf_ zt(J4*E*GzGP>}}Y^#+l7ncE8q;LH&MZV8+u;F7>`0;v*spFoNP{%oW?6$f32^g1KT z5n70(YG|(f$>L8qf5$`t9cG@9eny<*mL-4#Lx^7aJ}%$D6Z5?}Q;ZbuN)*MVj%iYS zoD`ovXNoz+NT0VmOQse9XB}j^QHx}n)`c<-E-ODc!%XX0R^BsX{o2u&nE3X~!Tt-s zn{(BIn1~Y33O!CK?N&kn@9}dy;QdCZ5)_d@86g0UQn$Pzawo+Es=7T=hv zo;DKwRhQD;U5soyrpl0O3B6t0_bomJd}&K37RX9iI^jNpv#M=-c-2OVLZIRH%rI&* zp_NWmUmmTvuWKa!tW<24!flQ0dXR<1I3O}0=M$^7v(GCyiLct(&_L1b`^sKSP?sGu z20TwV`Mictkj>@L=Uwnq{!}m^%-ONL+4WkEKEa-~hZqR2vd4I!H95w0bVZNRTxyL` z_p3PU-IT2!9nE$T+0dz;zOJ_KN57S4=P2L?tznaR6SNtoL2QJ1n(iT9&qlT|oWCR$ zG`Mx`8Xc5bVRFj6cu+e{m5w&Gw-a9kc&AOyi>HE#nMbR#y#~ypu`_e!i>J&?37;}E zkz2qd&jXJ|Ba zkv97g&JCzSD#AT*&eg!Ua`jLPdn208L}PvOIw5I%^$I4{FMe9F5Mt9u#H=F!N>&ZT zPj%LM2bqOBqKzqvIX*}u?)rPBo->p6qFbU@Al8%wO@YR0TY&r++@w#?ZO z@A7{AF1O^(B(s{vlqTV)9MurkOxy~3fd;aB5lQ1wmmmvD)BRopIS1)-XnciwSY+1d zas1ZB>K-c`zqL@^l?X0S(L`{O+Lj3BtBr}^xvD-9EK#+I;0kq>9em_EMygiu#hYey zNNJx&WVn}HGFW@uWI>g8$eI+PLkyLxBT{YR0P2VGw$+YMetgqvb>tByzjSqtPZJD6 z*-M0G!2P@h@j_^rAO0s>hW!&QU5!syp=w?)F?f0{B%e4_or8IewcJjYR=ylANl`x~ zDxiMMiU=uPxKMJojDcjiTwK9QG4XhrfedN*R&$$9493gVb)?YTE%nzk54=;}zfy9F z9BDYG+-_kpd8$<&2zZUTqS}r;OBW1#5}Bq-Ci7suP(!NKzsOWMR6odu+_v#hCbZ#t z>6cLa?XbEY4%c4Ym4FP8j((%c9$yBeB|5q(+0mV((9s(b9W9lPYI^=?N54;=fZ9x> zHRfW7A9{Ya>4Kvj{it`W<(}zKFWjRoAqcRyr?co#azf82SFc`e zPiVGG=+?yGPRj7sT1zIgn`(8sH__?uULkNnRwA5JY4`64RaL6pJcw${or&4qLnOf4 zlgRWW-=niTnNC-#Z&SpY+(x^7v$5XqJlm_Hl@7=K_O{Wkk<|s9L+Zl>s@!cgrU~UG zIi9R?^=nE*vZRQRr$)&f6r&axOefl&~@ScCY`K{HFO zW=@js8WNX6|NK#^1%@8Hypv;Pz3TKfZoB0vS~zhtub-n@P-~6(b)y68ZtX*ywZj#V zMX=*0EC^|JGNN%U{(+*lU}{V42QB`;*O>6PTWSZ2FdF~CGJp~LqwP`H~mQb&^%8$dfAOkd)vsGy~mFx!W#JmXq7nnuGVXxVqd) z@02E5{{vR+bnDN`(SA;#7HowbBVN8j+0gwaV07iguVis}4`4?5%~P6rn~IX%YnQqN zN?EqPF~_-DORvY6Gouuj>liEHj|jAHA4k*`Zm6Bn6cPDi^GOylg&Df!DF;R$tLuzK z+;erli^H?(05Lgr#ujWceLXeofsq&4?IJRKh*fpXXq(W!o^lzx1TnsYcdWF;^%`kg zU9OhUcirUThouRZ;AD=3tofA*S@Tl*s)3uzBL96d7d18Oj25BCMYGo6yxMR_v+|f7 zNa^=4;5fRQ0gNVO9dxSZ?3(8Wdu z_bc`?G35y{9xI{p@L35-y5Cp{@rVn^x~FWH>%DAp1ihaE_>M7SI4ZGTyelw%{3+;1oNowJ{Y-&xf5 zq|9r{9X8~EQ-nczxf-SOcHiPw-^Bac=n;}P63kfr^cZ(g54&iPHcDf6G}58E;=<6B z^7=>m@x_iLz0T(5iNdDXp+ybqiZ2RHsjh!)Y=(Dv%aTDJQkJcTZ~Q*NldVWFnGe;! zz;OTv{~9V5yxy2@&(3tQ1116>!ifo-IC$%MxqNg*hv7A~k$fWXQX*tWE?u>hSNdoOG|%uX6R} zM6bg0g6FQmmYb*PbAWv^dz#J^JS+^IJ2mbf?yKg@UO^Lz8kVbXo6O zSlHqME|lx*3}sg{F9y=dk?S%MHs1X+MwxuE?&v?pEQ~^VkQu0<*2}y(8~h}CcP@Wf z^X%v|GYN6AOtz@y>jb*imsrqMU3i>3xhl4*J{mihY_U~0M`L*s&?su!z3kO!ET0JW zW-g8!n!SXpqp?hWqOtk>Rn?CtSLkbWsxGp0d3b?{xot}gpKClWy{UhImEs}_sBgb+ z9k@16^F7qfbk7;IbR7hZFnbJK_3TTG+`$0&a^%T$Ly5CsrqEXrfek}j)J*>@ND?Y-59bt{L}gMeCF zCfI}Jt_5aZvn-QVq5z**uv%jl;|(3lDa^$BDELHFe~UtbGqygZGBCEI;osRS9R6-4 z@=&?)$EDM1T_W1kyoo*`>QEJbT=s`rF`9BMDMg3sif4rio|LisPHdbjiU)y;_~WuF zDmRfgl%o$t-<{;LR;*}`s1oR%%toQhGQlu7oyOgIFX+7`2u?sOQE8fOHjStkLX9GS47RUZvyRMf$(8&qA@NExU!VI9L3fS z9@bDp;Ean{egd1~&OnT1u(bZ?AgIysklKR4lz~Gtgw{Mwli5hsv2VDLY>pPef{T?F z#tXSx>hF~^yzsEe1>vl(aFR>C%T(`@81&j8{nh`3EOt^HB*I=0sgd?$tH3B=WgFxE z4@Vd%e*6H3xg8tw_)wc8$R>k57B95=b3w8%Yh~F{qI*7fNhaO!+$k2E#3Wt#a^s48 zu>`gUpPgNr5HSw3u%;$B~gAbY}c#6G6#RH)9yAWn1K(PtJh zK>9idWW^f*P54jXCo|j^k>55rnTD&YZxbIyZC%Za$xL02X!8P@mjlteS4eT>8p_B4 zj9%?&7S)})$hOqwo@Rj_1YPSr&0io`e-|@|KrC!VDJqZ;c*o{Ai^PJ?{X)iGY`hMo)iMVe{1-)u14$TQMt+V=GUOlKY=sKHpd`W>Y- zO66$|(#@Fb!X@eadLq^Q6)JTB_A*67?Q7nq~Gv9(4F6U}6hHeq#$Z zQnq+v2$v?HE)zY?9mF=b^}S73KyHMzSI+I)yozWG^xG{2)WRW|541rM#FpH9V%2#_ zdi)@I_uP*w7OR3$^1wm)P#<>O~&q$;r{0E`& zn;H5xEZW2FIXBUPYV}oVK^N0w45ckcpCn5PSgUJhEI0Hrmx@DZE8|F-=UeMISAaPY z;dM#nnD-SbK$4%I$wn1eqrQ8Iz_W7sPkrgp(M^7o9XPtl!CS;M8uM1!f=ZSII^>kwmi zw`59Q-W*0gV=g~vGbmlk0ARj3pD2yJE@fVg%%vh289SFqHJtHwI-M*C2N<$}KiU88x z(oN$sS9F$fw`7RMbheiw?e6G0m!a3&s^6+98k346AEj-5%$x^?H`{Q%j*8rh*O44@ z8G8PruGg)eM2RJ5_^S{fHoIA4N|pz=*O$u`l@fnk#;JC1lrszs!dkFU@sk3R>gL?( zm+Wx8wr}`bz3B7B7cSr-Y1g9WY-aCbCQ2}hyV|2yxJ;*XfRW>2$rW9h%Nqe{@CkNL zR(j2ek&|iRaf$Ejn>t|BKXQPsj8T9v^ulrsmm1Bo7o(Yr;*aUcR_7_^DJGi%+=ssv zQEL@cwj?ym((~wF>F%3K2s%2C^3df7KkSJ+2aOfS^SQy?;o^Acc)ofIPp$;!tAi4- z>;EHRt5F7JuXE<2#5Mq+>9e6b;5^io!W=ma*P`g^Kj-)TLhw|*-L13yufI;5Whls? zKf<7CC(iI6^E?6PRn-4ho#ALiDBu%}r6dY6R)k38hjOc%2e)N|TV|_@7Z|CpvnFJ9TDEeNk3(#aOwEY2@#EB5D$Y^`KRyea1TgY>o>^5GAK>WOsW5VjVZFhL5S zKP|S(?Q5UW2D{o~dT*Yre!!h*90sMF)#co~7fgL}xe9SVS$g;5x|}^dY?=-?qWf@p zFuCMu8m5J-1o_QIlh|rVK=)r{ni_^|D2IJ_Z6{f6zm#aLNy0k-8)uyNW|Sir!7`On zpo$LPfalx4;J0W`MMVYZ{LEzGOB02gqonuU&L8fp(P4ZJN0gJ*{vyUO3@K(^S4LtC z;&f2!g@-Qd%Ftuzax(ytd0!+G#*~RTcA}RDm+7a#>C*dRe_r_FavavumHD<%vxu3W zU#%KWNA#^|uu_F2fGp_^{ele%nNHQNRo9?oM3W*Z_)lF59<=8v#Fw8H3rJPhy& z=Yyz9^*Xb>BN7rEDxxvL6yX~{c)toA4UG+i+8{y>dv?AwZ;WOWn_9M{5QTDa zbig*5guX*K+j^R(=|_pkYRkBpPR*a({Y$<56TH|QNR*(PxKB;5i>4ICSM~|%N(e^8 zl&dxllqRoUieu8qc2~-_vwiDbThEf6?Pf=_25x*62ZG~(Yw8)uL6T391q4LbyEYUy zZcA~5&Ov0=EJ~EYJ_MyWf-9?~+^ufatjS1HXremf7N+-QD8=W{kAIrvuJwKA$>k$5 z-B6kJ9;Pz&Hx`X~N|KdD1;w)Wb|`!rn+j!LH^9sp$phPgjBJ0o;{kCbh6(;j>Q^^I zU(j~7iyne8%ht<{mG!Id@qtWH(O~f-57MJ>EvuWY71UYBO&2of9_okMS*aF%S(vh! z>Pu47IqRZ@jo|dct?o|{j62t%YQ$ntDxFeaY{5O7^y_s?MaFzdbb!Lc6@ltXwm?~S zMLHi;RP+x_+ij#A~H3W2-&|tD|pNV zbj5E=HBPdbV`Y0ee=W0AE**}ooKWodZq8N{^*B&_Qa|_w@GWim!2PAHUUAJbk09GyOc&jq;4kT?=sf8@F_?;XkzZreRjQ%ik{+M};EW z5iFe0UK5_vGLc>x<54wcin@b^HQ}^qZNHgGRIy=)Z!0XpQY+VX>Mp|dO!^HUb zKBG}ipCN8s)2Tog=Z(C1T;yVh=bQUT6L)|{yAkdMFnDMZXXXm;dX;z}y2>@rKQwQ@ zQFhEyr1m_wM^!a4IQG@U1N7Zn9V}c^Ua3xq-oo=3wH6qbY8+|x#~)ol zPuqIaT;-e;8KG*TRXn&1TIMDT%KB#vZpqXZlG8hvrxchIjvwUryvXa0<40nZsnM!l z<0GnXNo^k7dgd<0+;4aJx;M8MA6&WX)J zXn3$U0S|;Pn8Y+J7xy#Kn?Z#j)#uOM0CW&@kcgfiE9XR3Yd>YG`Z2b_9;Pa{xJ3-E2j%lRGxQbr_&D#YG}B(~d0&X=9-3JqTy$PIz0-MKY$FF{ zTTW|f3hwgQu47M%=ZW2sffQ$#a{#I}ok7~BqoC92&#eE|2TQ%>0rmdZ1-fOf<$~E1 zyCQXwKRd($^cz((jZ58)iwZ-ZV{1kJnsQtE@i#h4Q_c%szuxz!t!`uYkB-M3rK!R3 zV?Uh^91J$(riQZ{iwnb^pi{_m70R%7uYF_r2a@bVZ9E|HxJ+YeED8#%UDPH>PHwCL zR3rQ0haYAEjE0$GR{9np^(9w&A~Hl{R$4%%-WNm8E}2CZxkBc#vs~S#DSVI!LmIM7 z0gbU1m*yarSj(Dw%CdqR^lKrend;vE7-6U8IY})Xv}&G+S%C^)od^~B^ZI8aHqp$36HIc3=MBB@O3quRqP*b7>_b5-my-!!1t7s zHo)*@F)Gzoee>qpCs5+86KJL00sf^=;8-xRYLp~_tyy+OWos=GfgQZZefu`%1T#BR z9BVYzyH=fj7H1KRqv=q{-I;RUvdc-^bu-7J%YS$)KUnY=6E(N$;Pcq#-?fEcpxX09 zL+-O79s643IKtBhoDh1s8@Man_%_g{+IwR&o9Q4ve2=z}HRkehzuhH;!UJ9YWA_rm z8tT)rQp)eLXP_Xw%lG#gZ6(eQXIGrWt149aW_>)@BjMs{T0wn@(;}X6t<%Cd#VD9i zUyPS+?SpA!;da$j2@_``J4dAVHXV&L zWIIAf#OCiN?Dfoyj4Z=g*@zz(2qUGTah?8QRI65oT?7ydo*(H&E6X8N&hUlR>SYKz zcpU{TI~&{>w+ma-B9}Ne+WvLW-If&wHVCB*?5Yog-)t-@@lpvWk<(1YdwOK#i`(h64qb@hxzMyv$u))7iTSxt6g9LQ z%S?0nrxd_qGku#s_9D{QCE|Vm{>3E0Kkui^t%&y-C4yvUi9Q;@U{6YMmT>%mJEP(u zC?v6l<2g|}GC2g95=qQgo)dK>%X?+) zicBNrp*F6A@Kw8R2TBZ#OEEG4;RW^L%}m|W!3p}I#(W2+`XAbM!OpKAhR1#Gw+~VyS6i> z19M;jixV^`D(T4`7U^FV^Y6lD;9g$yb&-a@Iy_CX#%#QPd5R0qEnpNuo_BTvJ$5kEJK?~?3mciOs1abE$^_7@s?HhWuT3v4ab<%@(<^eq#+>!VQj+yJ%adPq;Y9qg0+V@`H9@+w}X?ciW-x66} zPefS##>*@eg6c*WYsP{_K}#(s%!4bu`6;2T)#@P`2Ck^0xS}|Ml{rhpmn zgDc$mDV$1IvN`omt?q%`9rjzUT2<1VT&8IG9x&dZqQpF)SmH2VHP5I2M(trEe4twO zOPd|)9;+JlOMb0^sKS5eyuTDTUdLVYMGV?H-4zua5;uZ9x3YP8q}Sl;Y?9iTEGEuy z%rZe(%ZBg@>E)7UldRG*U|~-}yf=&dHRh|LL|ZjHZ?~^2)Ft7UBJb$!JXmOC>iyVw z{RR0Sk3mwBgOmqWu`S=pOJqu=9+ALh)j*~DzX!iK4!5sb@6mhlhDf+XNAUr zk6zmMD?TtlfKKejJb4I>hc+_OJ^y1@Rtt_6<@+wKynTI*6WWA&M~tZ8{*@`S-ua$<2uvF zLjx=|&qP}!&MTiOdW$I{j;WArp>e#os)necl zTL_svd8d~aeE13Z`u_PcmsO*4`H?l3RrL1jgF8ZuA7lud6FA z`sA#BL1wkzcu{6`5!Z2-UrnbdxPH!C^x*7jalD)SimD0KtoB8I^e?JdbhEQoyM z4C72;*sy%ilSu5j1%EfQkH2B;4yOD_{HeOtpvG_jIJpHM0t^DY#p}hckxgjF=micl zZS{iK8sHDej5&{beMdm;NA?)m8q7AnncBKy>Ur}&9^Z}m(w5az&$9`3n&1e^FOT0$ z<9IB4rP1a4Xk%riXD7Gy^w8%bC$hrRVrx=;Z)`k`_hMbKkBs4r;P{%LOR&7U=tS14 z#@X)Mz2QZ4&p1ZiqxZKB@K#UCPhDGZ++I)AAH4OAa_xK#O0}q0kI1$20oS5jJH!0i z*Uo=2tvvf%5N~q$7FySiTtUW>_LJ#Gr`$Q+06gxTyXBA$u1Lv8qx24P>}c=;1h#Ji z*|V$tnXYyUY39~|n!HSIrI&HqdsJUYRt5Stq7H7OP03!UHC7F#eH8^1w+mNM<|&Tb zHFW4Q&t^EVExwjdH48GZWVjA}K&{cXi~X%tK$mnulZj+VgNb zj;MH8JP~~IjyU``IsL6C z3SP{_b-*r+`$!-^H;GBwwiBkZ|k*_ z&uOV0X*@Yz$3hF%v-1eQt+gXYLw`$d2`QIx4awEVYhPc!`owjv@SZc?)6^uhz#VI0 zJ4{~zrk@s%4}FdM<0b$F^#oJb+x2`(9R=f|7GCV{4=+8XmUFFI&Zd?#>{^`vO)ck+ zuT+17x+Y}df02rylv+J%-0IGEG}MZq5|&NlIjc2J6I#uXQp1-AVVLyFqklhEbi+eB zN4bUd%uYa^saFfsc^T6Ue-pMLKE(Q7*MpW@GPZc7d3LA2pB1rdO4egz2G@|QxU6^c zRnCT9=@~T0M9;kR>>=q$XzKnx(5_5K2Sb(W@A_evZ48-r?tfoI*NHw{85*w&HLT1u z|Dw)f?agCW4})pz!RDr_pH(J~le&XobWz_*!Ka39@ibpVpeWvVvHXa~;~PmANVH+J z$k4a-p|!Xi8feN}S=gfVOFboy!7&A;Syth3)#|N165)-E^lmys73gX*nG|?d7>icp zx3iJjLhl6B@<+%=@DNVYlged<)*2j0vhWs^{RXWRb(#{0oeuHd|sK;3WsoaWG>WV*NImcQ6nM(gV7 z=ZVJkwAK~V&u@J5WQ&M4A43V@mVdO61czVU_W*2wCp>`HYX z)J?>&JHq*qQder^LIl zR=MOE!VSSQ#JV0Dw-$21W~(PSwnoY71mpCy(PZ!?DLh@<; zHyh$bS=LB=%x*=muN_}|kvA{7X-^?{oYy|w`nhGScJqYEj-2Umc0}r2j!2ywQJVoc z=+WjO{+c($o*CxXcVOeJR_F4?yk8i7XGYe_mW-JH##xKPF zYAc3)lh_oq4V{+4x^``tZWT0iW4;3${%v$B$E;xIX=7H<8s1lt1peO)Pk@6xJZFbB zrlMD@QAMXlt6kA*w;7H-ZjY|Ov(t%qU1W$iPh_PVT>qN7=oHW@5aF2rBLcnwd#L;E zp$;U63Q}do1wLi8D_y?Me;Vx_$|IKItJ^G@<;{s1- zV+Ctj<~2@4n`Hq7{Io}BAzy^c9loJm`MN!kr{st~E)mF31IB$L8|Qd-df3n~n!@As zxV;EcB6G}N9^1b54cKj~uj1tti^-m-KscL%1?~HX%8mB&N*fv07T^GK&5At0)79KJ zv3|k@9l!^@ON0;exb!W#CC+l*Em;g*h+Xiazzr`z!}pAIaigc`P~R2g|CGc1Fw`8O zK7+{KD~RmRWve6*+59r=`Y7VpM&MvdX+&1QRsxX~H1#tPSx6$GuLRW17jlL_9Zj`} zCNHl}w4oj)$gTB%LsNH4105=Cl~s+S)ul%*G<6a~OK9<&J9h7T1=m9m8sF9o9W4)0 zCV8DJ1(=hk=Gir#uWJ$Ml3-H1Wb zv_{0c&JYCh!IbdnYX29kX+6xZ?V{~V)Yw-;b%QG|&d=jPo~k8mR2$NZAbr9M>3ulx z@Wbk;=o?}U=MvZjXNNVdM zys-*w&Z6UN6%57idA5U`LQFhI@ZlW6hi|rPrR=j{CFbtY@1O8$HGez${T$7j|6#25 z!Y_M`ii+AE4myNqCKy?NWfFoR8f{%N{?}sR*BIE(e)coFJN~0g`8BBavGeB#)7Bx$ zkgXoSJh?OejbOCUEGkz)LNz8&dp!W5(UpY8HTtG&DV`Z>hb}Wy7VFCd*-i4CbQbtk z(vs|>0Qe-=3Ct@~-G_7>qNhBEjLR|y+tb6dRk5yT9QCkAg5DZT>kf?5X5U`5;*65a zc9qG4AxmZHymN^M-vPTRk!WbVnUU++d^BOS0*l&S#6Hc0Qoor)4RIRT8R5%*#rg_Qs8%oVwv-!loDAz1=kc+Q5Ey=? zwu4^74w5(fDI+qSFsQ@@h`#5A@0qE-ji8^Nk$rkbKv%va!^U!HT-4kzC>SUaTP&Hz zs@%&ki38UV@)Ih1S7c`c`pB|cFnH#6SknOH4%b zf@H*g)zm>!Xkv0t^oew9V)dkqwN$JCihJj>0#cJ+bmXx%<;FL;FsgunPEEPm`98ZE zY>0-mSQmLw0~uAFslWdRU4@SPeRdjV1Xx!wC0wX(M8cMuE;7c z?95>*i7Vk82>qK{Fxc&;im6hCwT0;-N@g4^w`IA>ve_iXb(F~9S(X-}t7a0W<9E32 zEdyin^bkA`h)LSEU8E~B((!R@<~?GscA0Sze4t8HUfC!B^z#GiJ3#W9SRnKFjyyV) zYIIL{alrHFcx-Uj4wGq6;Qow&YLIMLXvJjR@1?~&;e%@!L{|#UzXum_sLz1^rMYG| zKFwlg2vx8xv|o1{J=6MoJ+jU6umCWXrY?F?T8xznR6=Y(>NkIDBkCM?eN zgwUmOmn?{=+|XGOHC}ENm#100)3@FdZ+ay>J2Js*F5EGpk?fDAXbIIy^?P`VX6W%0 zTKN1PGbCtxrCO23hA`Jz#Z+WM-fvUrMC%LY)e&`ds3f8$hKi&u>?chKO^T>=PqXM{ zRH_mRnrFuRA5%$>)cm9s{*8oxU8(Mn-}Fj#9lxzrBQ>qvv{BTC-RK{*IS0gL#8ft$ z>6DiL7P62Kjli_Z5n-%r0gm%CH?en|iYqQ_vV2UL8S+}k4X-F&;m=S4c5Ynb^( z>7kR2OP7Ri)gfN=C==@fM|Rl-uoKO$b~((8gKkpWbZXnFsi}wq1v5zP)~WxIOr0iW zQ=kc7WTuofE@G9jVXoCi)z|R2VIv#=*ggW+&gdAGSkPP}dDKC}sR`yKc8k36N)ZrD zb)Kjz&Iq0G?99MQ=+GDOp)$0Ac^=vv%288BEB*-;_x(+_OS-*}rgT|eV9aq{>9UXD z`&I_WJ5RJ!#bxc@X#MEXlxwIKF*Z-rerAdtwE4!+8oh&lE#Iu=lF=Phuv_d~v4Mm_ z1_~sYT9ag(=rzyTF|m>0qbcU*fD#u==2v#6m`7s%5#&EI*w;1Ynx;eHKSn0z{Vt{T zMYG~Fx6L#v=QPPtVB6ryR{dP6d(H}re4_cgfGU^Y^nf~>-1*xsvqM95kxQ0@H|yH?3Z~T`(52S>2NNNiE<7H?VeBE;E$pKDqdK+Z)YMc*&?~#B z{+Ldkn@pW8Wm6o%iEEr)G|3wVJ?bIRO>*~v0>{-E>}`7|J=`!7Un_6+BqD{eT#Y(d zAe;-?7(k4trUo3(lKasJT2*}`Qw#@$lZ{P$uCj79l>>wb2E9MRqsx*o049SO%0=SO z29}G_y=)Dw`3prP8|YpJ93PG@1BcK4^iGI^?f<$HhhP)_|I`WYJ|pG9k`ROkjCOT{ zC?$=alJt~_IT$I;yRGyIyH8Ca7ZhmrbVD)OM0yDWQskvE4UdtA}f=;a8@BnrupPU%?5DIKfr z8@PqO7qe~69Vc5_J0kw zwkE1yFHO7yG!y=l7P3E28)C2mYp~j`)T7c$;=SjUmz{8Da#SVNMDiSJU9vj!i_L>u z{MKuB;}Ut#2}=4=y2hMrE~7kS=ZXoTFiNswJqhuDWT+s&*_Mna$rUj}{bPw$yCYe< z`sUX)f;oCdghl19R)0KOrU8W3g;$>|?h{4_R_4Ov2DOMW`alsV*E0u8*5J${n5uqC zc8pF8s2@lqK?S$kwAG@v+VzrVA*%Bn3T^09=ks3 zEV`<>YzTuSk!6{ugp3WyO=!Ld+lZmt8DOmHwck->*K;FDaT{c9z+981;s1;X0-p+`D$;|ik!ot*{!p<0;ZK>`MY(Nu7)&nSjjjEA6biK zm`^Dgc7p;r!bgRN?m$-c0Mw&sVZrg^M`jEb{c+xLfoSTx@sIWUP)*55$hhHC602%c z)x58$z(M#;Rmt88T79F0dT%*aYR&pcB2#9@myu-l-ai}O>T^$q&faTGpsOo4{ zBj~4qKCiWa<*L=EN%$+BZRP3=?spVaS+zp(K&eY6icuyhwh^FAjS0lWQ-pCGO_69y zK+X9rg}Z9T8Z=J~<683Dfcz~{QETfHN{&5@Y_()GxkD$L!D{u=IDy-4MiGbHxw2Ya zgDoifZV7iKdcPMA1Pq8p*bC$)v-&>mXM1dbupax$oYQv*ecdgT+ zADWDXkwCH#xPm~}=nm7;B665^blo*Xo$*r7oef+pJK|-aa-KW>g)oBek)a8mJ8rNq zoaOjFMV?aa;G4@*kk`v4*pNNdb4Q5|<@!9@Q*fkVCZThQGZx%^^@2;hP7%3&=_Ko@nz&{l8KaXQpEQxeSYxk;q&gAe3^5>;+%->zEo=n7udSJ}I7gJP; zn0{ia)e@=p$;OHl$ML@4Vx!x5!{~fUfBx0kZFEh30(6RzZ^ zjjCNHG>d&k)oZ3#r4=W(74Ne2zJ$<_^#F?O2)b<@pTs{>Q2jAnW>8S-)Lw?9E z@{6Cj`1T^PJvxlx&?KgS*vQ1E2H;}V8SQoRc8j5qA`ApuhL2^7U~PvdMXvmrD1XG~ z6x7mGBnDg<{??umu>ZYt4;m+pR3n@ExIa_0O2SxKbvr_y;|FK#iM;up*bdUUpsD`g zdv92#mcO29CHBUaQLBV^yy>Q=u^nJwiOXCU=y~(cz10|J{`$C{gK+pTh@f@XCVF;u zJ|z7QZ*{S&?6**MWH%WQt-Hr)EA5OTh9 zrNoC6>TnaIXzjcoXDstRsEdXtvc{Q~gUks7@=bSw4r_ugpckAWa~=^r2eh$hakJ;y zIYKOUrFXn5+CMwq7loR2+{)2KiN!*HsSM3JztnbyrxE+ykSL>)ul-Hegzma%*~r*s z+JVhe+z+y*VUaJ*VX~~Kcz7J&X~^i-cIdSnlC_-oLY?mgq>Y@WvKE)GNqSW>U<5HB z7a|{j)b4Qwrd0Ga3?F*S^BgiPP{OU(bH$GjHVn&@`rXI(*Uc*%#=2OY?%2@5TZT@_ zD@2Zd=!Gev@rTaK$Ncu8+TkCIMQ1Nw1Fe{z+G9WFLo7v;X90O6MwpW04!(C#9r>W= z0AJWvK4?n9Xg7XL*G_3n=1i-@+8vb}R<844Z_z7jjt}CEaKi%6Z>)<*jK9@?QFCZ9 z)^gwXI6;gZ<8SVS_0KWJ->zIJr9iA2g?iPXsw0=@f5BE@~26o>qg5G1YJ6DfHTnJa%6GtCWQ+WfP%uXcFw!YHvQbigC_Ttl z@37E11N2D=3=DIr{!CRwHaGt@?got=XiI8MAAj49^ z>8O{t46-lroFNcf?V}1LS2)v=q3ZBLUagCsUy4-v-UkJf5CYj8;#TRnUCFqtKpGmXQ+CLipU*MjR_f@cVO2klz|z>`GP=u|>xO&;gW_k4m-=FmJwgTuYHXJS!9dBN_>Nps)R%JXLsyZXdvqvRP zST-RPU2}&Mlg88ZPUNxQJ6pVpyj-+I>c7J$!WL^kWw+KpFZ10de80RDwzG`aA^o0#b3S|f{tk-;fEl*0wLoJIfhv%D6oqX}(!Z1}jpMKqyXq+j{B>hAt$vSLlc5mm~#*O>4 z$F}+#E;-#_FokSs)ypi8ZDyWr{S`lcC)bEZrkFgk-fh|}ZpBF|uv+@@ht|A!|9M{O zm7LjL`IBG7bUT&O!?mW{qo+GLUFq?hEu;PS+qHhmY}XG+g}UkmQmadSk6Nh{Ys(gB zAF~M5+B910`+xt;HLM?!T6NWnrPeehrZPUe)~%zp{^-A{)ggOLSG`JVO;_(Q^>(c? zKo8)@-A~x{^G+BG#-|Q+srK1+WyjG^+YMFu4)KS?x_L0k> z_tMNMn~x9c`{vP3FSJ{LT=7p+@#RFPKQRN7#mfLgP;b#w=HNQHC9Mv>Gw_)kL7ktd z?z0XDaKb(>DhK!sIJIm2j$P}g90e`9rf2s5>7eIYBe{2UVrJTH+6R5C2OsrA#3eps zH8qzlh2D$hAi14id*7N7w?l2_Wyn)ZTo+wMP~9khw#uLH%AcRhpWn-$ee&lo@+X^? z)ISLI%_pSy=~IFb1hmH|@!y3K9#;U4pY~X;pM3jfyb^iqNM!fiWzj-hbAoUVidu?Z zUeR6(pA~pkF1^T7QPo)*54qzPTDK0*Xsyd46^47)C5deb%bD? zUAqR@jUBrlILTk#9QqU@prmhHEI}=5jCb`FpEyD_DOD#MMI43AGx)ArzXk0we;b}67D}@}5sQJ5E^uMwi z5*?Rcre!^16MLTIhYs%%=Tj7;=7P_wJCgEV< z%_rsNWL3GR)0c^>=X`V|mQe)jj4xBXvbvzVqMXiZtHJ7U*lsF(n%a7fjPV>=6sf=r zb0uWN<@Q)6L9D@3XhP-j1M{3f;FLapKUqaM^uMiQ%hKALGY9hZ;XkJ`G)VaQnO>@wljE5kg z(Y(4*D%0jB-n)Uya)RYX$2ze?vU=qRFB#-;an|g*0}ZG&a}#u0AofeWKH9f#U1$D`dlIjh)Mm)Y{kCYVq{~0tD`46b<$X z7s}cl8AcU^1E`#{&Pqa%2fmzeB2xdXY+zp}el$kTOr|%HZkAzp#<=GJDq>Slj)ji} z%F!&Yq(>ToFwcu`_Lg5&UQwR{X9V;NL8h0`%oC$3ZQ(5Sn`Cuz21ow;9U2*HwLG%K z1?23n42tO_1KU(3}B;0O=rLTRD z>+s=J-HG0@-TxnFG(16lYrf3pTnhL2kM-ae&GKOT!n+z1u#N(N**(~i3rF_FJfj1T zSdrco@f+sE_mlX2C14d?-tKXnxCC|>mb%=dU z(e2KmUDG?*F*7tliDx~lC&^cvmYU|Q%I#V0*?C1O7Gn0ds|@1=*PPal8xGGHY~LQ9 zh&fG6De&0p`!;zYY-ytW@viuG5ajVXRSZ>ycl|5L1sw%`%vZJ5p~2%H#%}tyqrqGx zuV3B{e|g7Snj(n`T6erI8b~#l;fJlRJ?`@C%=Q;TT=hKHh0<2Jgm${Fn76NJH@;Ns zqOL2rDKKk@WrXy)38K`;H_9}3wXGU^&jAhs&o)AC^Xy!fYV4bb4XxMLg|i>r9-dGa zDaLcUO(}&k_fVqqMALa87GYc&lq{me&5cHZfw3~R^Zs3s5SYSf;jtYAG$d$pBIKoZ z0ACK`SOmK^shh@E9K=7}*C~R(jo|or&eNRh`ww%(vBz&!i@f@?+R#`1B{Mj3v-`z6 zlv}K*dv=yh+$E&bdEJ_tiS}UlA{8^^@l_Cghf+6B#9-9>e3HMW#{4or_}n|Q#9IlR zJkYLv56+w)%nZ8COVnxXh@Pq;@ z_=KQWWsU9l-c$aIT|M8Wt}Oz%ok<(P%=+u(rYyxc+bAb^&aL)knIODDMJZb71zf-S z(m&Jq$|*aR##bPvt#t<4tP-en9>O75hX5+gL;%QAiq|`CmsAS9KGXWiwtn3DNAHxI zvb?w|gWj9z?Dn;XJkZjM%c0LAf`Hj7ob@Iz$xK{+!dLhdBl%MWi%4u&x^%zPf4?+& zzchcp)vB8K@2qy4yCaxiUm|nzC8+sDhhXE(sonc%N=w<>&~y?0@g3iu8(J7EjmyC1 z>fxOwf5Uz=J2EmMG(9rn!6?N@_O=C)kty3h7f>JQ6XQam zTiCY};_U%avn>J`+*?-7`|1m1GE)t&u^VMHJjZ$N+TBw1R?{n<=2k!zm-uALxT$fY z)X49%a}k_BE<>0A?l$5I&oh?0Q2B{`+2z0qxlg^qc#r_}?^WG|x*T^>4+(Q`O3RkD zayoCy%GH5xl!92aGel691v5X3cx;p%h^8b^rUGhfYduj*NB-#OOH*b{e z8nzv1uTJJBZ*V54H^&@MDytbs8Kg&7i0o=NBFh z?ZEl|h3+F>Jnb6Ez-FTSdf0veZS% zYD_rr|IcC~@=`JKV#|6rft5ts^!025yB+;rY8oZfRo9Q_yC@!OhE5YlEACx%ZNP-A@ACRIFwb~S zF1PR!L18z0>;%;)V8^_)G7wvn5==!TQv{W@7bqlAAks?_jplbxmx;-w`{uZSx=e~8 z(5%*em%uusE8%?nSkD-&4r?hG*9T>Y=Y*`yFexEdu$=0!mu_CJMFo5Z@LzvG+Aq&d zw9gV>J=*3}(Z>%cPz8C5LELZV@--}+(Ueg*~!Y-v(E14nfN&^au>=kE^`YlA8*j$ zM7J{`%y(@^MFsQ@BGpG4=8IiOzZY5wkFWL(tfS8T9kAACyC>W0R;ba2f}Y?Hb~<3v)__m<$Bbwz+62jJ^Y_m zC4E#vAYzBTB_M8E!TzF1J(Pk>jgL8Iq{T8>1DfUvoUKI*ZGD*-DVLQ zZXa6hKHw6Da6o*LVxt^{1Z_H`_{`NRvSVq8%U6n zb|>)%FhI;M21``-TkO>#5QGLWG3ZGyk{OBe2r^J)(cqoFg?SvBHFo@l8qf60VGE8Hc^0Eqzu1`&VrF zzb_&?btHoP-$_gU&(f)fYq&K9n%8pt>7n|DoC*j|cy8o9M<`niePJ6cB|Nzr+e_|h zj4wH>gM%=D07kY!2VSF5D&Q!YQ`FI%B=GMf7|9a_i7~i8C-qaieVy)haAy6zGTXy% zd@Qz>j$F@hBQM6IwMVf6&@hbh^p1EV^V6`xR{H>*V+Jo*KL=zdXEbzXBu%ER#Q1aj z+sMA}Wx8v45)Y-@+K`%T4Y;@wTc0ZXGX(^eIJCb8!XMo z<1n05nOyk@P2xkkj4cYXIS0)DDnOL4^G8@aJ$|D7-SpUk3`_F!B}=Q;zTi8>ijp0U zUW+p3k-iWocV!>gA}3sy`13MmYl-zWiNWtJH`?n5sS*ug)(;Kg0}0KS!4*zAv?8+A z2_bZes{JnKlJ%Qc)K)Msb^*&}0n23p%SRW`vb?aGqFf|X)S21I)pHZHRu8l$0lbk0 zIU#bU=473y2Klw{5OaC+o-JqjvSi*j&IXdac?t84KCwOJmdq;#>fKOM)x&oACz9pW z;&N_V5w_?`%jG@Mc&kvhyV7P7=C*ZorR5PC_<;7(<`e1$m+aUjsU5o{rDKbOtR z>;obMU;28LZbL)y16N|gYYLC{`=lTSrxOn!P5vYAnWK4smCP&Ee@fnuPLr|gdK;5@ zr4wWFR#fuzFFJ(u+_1WlCD!z@XBkg%?Xaims{{ldamTMTuE_Rf?PE~kOkdVvek~s& z#itiiqs6K4>`XhtM>)TT?cX=--vjbnSA6aahCC|)Y>NQ1&f)kdnkDR!vL7cN;xTffpVA`c?<>|mbttJZ5RCt4m+lKvs zUHxEcc{w(gH(_5MnUe-x;Tj|7HKxp1(kp+jnCbgd!*t&ZThD}6G}rgSwzf{Ysk*)afs@M1P|TWfJd~0Y{g}R1?U`xuEXiz6+9e;p?yVCGy5ngQWo3&lkv(qSZ7;RF z73)_grc?V}QWwyUevk8DKL)jVm{T;QZnIkVH2;uU6F~>%NyL1U7$Ya2UC5b2N@aoZ zg3;NUd-1gJbVR97Yh9D_|55kufl*c0;{PNwlME!`1PCt$i6mGwV$pyS0}_+~KA?kv zJd}s+)qLsHT1#dCl}F-akjd$^-g}F+S8cUw>+RFps)$812_!re611Ag!=PBtI20pL z5+E|)&)VnAB!Kqy`~LH@C3DU`d#}Cr-fOSD_S$Q&b!|lw8_#<2;)MnFAqKuT{@L|X zdQtbS#v1|Jr|-fIY+cfH@tT^qL%e(%59qQ{d0OBb&ymNh3aNz~jj}g5$1`ZD6uQ+o z3TGE}D#wFjPvo&L!R>qzaekJtYeasM4{!1Tn{98(ObNICx4Mg#RG%L2OPX0~l+P3j z*(Ua|oC?+rtv;3KO$}Y&GNs=N`^@O4)u*oYT~D?v$;Ob%QKA^f_C%di3f891tV@|P zVfEjtue;VaicIMO>x*+xo3pE(g8B86Q&3%EMnW8r;%;p7?Sk#S4&!+?H40s?E1FF- z$tD`?>oL}yV%?pf`;Hs;swZ=$k9$zvfSNPzZy23`v6wu1rx+CXz!7CUgNu$EKPOc& z#xZJ0yWPf=c#3Ia%pjM>Q_Kh?Y7la2se6<>Hal`B^Aj7g3aNyXCav}lbm_M;Byoy9 z_VJT-mGj zaE$y|$x<#Z~z^t`T$*t5Kxt0EowJ0RkhVIOD z`LxJZ?j&s5bnCRt$T1kH`7{tEL;~Jb{|Y>3WD?3qnCJeiTqAiDjn4pim`|fpSN{f& z0k=K|BHmlTF1@m5O77ZZta8VXE18zb@mJ?s?_xOxBm8^&U)#60f99WR(3>_b@CGGA z87-5iWp28F43X`;n>mL?-~L}^lRe76Di=eLp<@MrckBMPz2iG**G6c~79C>@r$qEZ zGwW6}>uZvyPV&%TTcWNz&aTV&ChCgY8jWknvn~RpD|l$%9v#tsu-&MOaDi593ZN>F zogrbn`gg4VcCVv7df;IHzj~9~I~qx>=YPfl$zU7^AK2c0=&}8q@1W3QCjwvRC&}l$ z>aXpm8p|U;qJ4tbC*ak%zYR!f``g;179<{z@Yn^={cVwNtGsn@Ms3D+fJ8R%9;XTn zuWPnUfU-*-Yu~(3YTCQ{w|iG_bkDoh_!?*MQ*3*`y>aiie|uX+IZhz{jIB_0Na70F zji+hf?b{nULfLRX<@jCjV08a^@Bk;U>=rBq=t5&`0#H)*vjXpP<&YJ4CbYhQETzM5 z7$J^zOp6EOr{mm%cO7cB+o5`fb;}YAlo+_gK>HAYRxJG>Q0+Fhj0Il>MiWu16KpLa%|_?%Cvg# zg_Tnw&l{qz_Dz?h3DM_F2jNYy^8k1nb!>!}IL3)eod6d0ioH zd#--)*=P4Jstc(Gg`SXhl(FMW5FJ67*P5NNwUt3U-l1Q{J>D~IX~E)C!9^$b ze)~k!j(VH2aq|3k`O5;q-{dbp6Ph@Szsw=!pXD!y&*Cq4Q!W`kEx`X{c+>jytX|iBzga+1kbyh zoSTRwPbWNoBa6W|dEYz!GT1WR^f#5c8;Xua-!wVsl_m$h>?|&ufOgT@(2TD@Jhz!! zV*la3zJaj!7F#Z~R(RI;b;<=LZbTuNq;aq&m(Ppf%;@BX8=51r)!jhEN4DvaT)ruT zy0?uZB;l)2Tv9#(|Iin-6}<2qt?^A1o4P-cw22cS0%vmx?QY)cQrA1K2&?c6~mbr}g=2AWOs@W31Q!GUYp1}ImMeTaAfh)BbZz5&Rjf~{4RoD|VOFu59 zaaf#k0|BCpK@!g8*i5 zMqz4MR^}FG4LQYGZcj`w>b64FaoqIIZ$FP!SZ1EZh83hlZw}qHPxK>VVr(pH>@!w1 zhaZM?dRr*#%N$`H!x==`R|PQ}WiRpKO8HwThvR_{D6zDfKcN7aierl@&K>W-9$)yQIIku*m0jKwc0%) zD`>}Kgm_T>l}|Pa&CwMSTVRS=o#AYu@$rV;hLXxC=&fPfxiuK?;EOc+EEDak5_eqn z+-CXfMsp*pNH%^sULX&ZXVj_h>+O+rGQfKiQ)*|}940gR_PE0Mju1Z;y~7nJ$V0|V zGU$s&!rW8fhI%=t_W1-X%2q94*AE%RLqsO-ZKDU!Y6Bn?%Cd!Sa$&(-*m`!1$nQ2- zuMzP2h%VvvWueud)PIcURVYp+MN-|tj?MbpKrOA-=_8|s8%s0@EpeI z6uewL*y}5`aT5devFkE7eadz(uhk#POxr=+QAB#pzn5BH;nB8fE%!ewwR?6{YNx|e zjq8~97s?LG7{^wFy5A@9-AkylnQZgN3U=pKJu=XeDtRj|R}WHk`NTj+nzW;IthD2( zR^CbJH-PsR@ZK5?yhh*+a+ozf{w?e+wXI=0NpJD5iKJ0dJ&Er~;@jl^ z3wfJ)2Ij(}m0DH|F_yiu{L%cwu-vWrK%U2UPD4N0u<6MndbVZ!y;E$qw3eDvX5YTR zrh(#sTKG0~j5X_+-ww)>)=;UH?b&n(B`dWpd#E@wY9W1`uhM|`_;-Zi81HUVqLZ8* z{PJ9WhF=K3f@yJYmsAIcd!zDjjDH_WDW(xWjBoiC{*iGo^JhQ*SYBl|snH%Zs#CRd z%{JN%mh*RlN^5qdwr0D`gwC~^|2+mRE$r{MX|=~8IqABPh)rGZ)ilV&p}?_;(D7TZ zh$@7c!Z=p7W>spZfc5F#O6>^0$AG;Y%6=EmdPEtdSj{PuW}XI=nlDphRHOyI$HYru zNB6uUm6}lJXPC%VwNjrzA2iCXy0RC#g7iufVHNG$Y7UCGA^)k&Ws8}_X##arU)~Y9 zq=$W~HfWV%D|gD@HL#AVce8ou*0+s?X|J8CI^n@(V5L2DK&Bq;f9TIVL>7~#SOgm6XnV|i!34$Nc0ZlM#oj{kpbLe_H$Z;8hkY|su4KIm@!$A;~?j~ z{4(y_H=z@=MTVMS6oml{CJPaC+k5~sN#X=vt@CWa8IAI?gvvXi#oStQ*@H|(Js z8dNt#D+J+QTosk!Ob{v>G*^zau<=l!1 zU-L<|wDyDQve#wtiC!|*mfRE5zW*7$AJ1pysA;HXQ7?O){O9p}{b)9JEwlBsT^88Vuqqd+6$pYGl<6HJnaj-?>%4>C$X$GvM0o*~ z`pA5haPPqxP{m(*=h7F7HxFLi6^lWmw(4csHQP;6x<@3(&hcM_rs4`)-?p1_Q_Uwr zyVMZ2=Qkv{Q(!#PDRMJ^9=3Gm{r~DK6ir+-!%9F6{>g#u?1f=*sLCz%IO=rVc${b` z@+G%_ZtB8S2xMa>`Owa0UG-PCLf+&Pe+JmW=u}g}jp|@a| zRmz9I@*&dR5&Z~-eFkOu5#-9xKLXI=n4Sg75qXz3p4$w&Aosg?fkx3a?;ZaWT6v)T z?30D*z72fr>8-79!`JEm_U&y46KR}JbP9-`wsukV`7UU$-2IT{@OF!(!vMRcy|QTbN61J>)+B}bfyxRy^(`XS05NjDxuL*$J^U4 z&%KS4CXQvN(u|ALfz%M@n|es!D2Gx;gcattMwL^hSXQo_>~cb*pmJB`yfp7r6W=8X zz?Z2buZ!b=hbzGTQ=`18hOVF+-|nqszw;KEa(&LQrtmIIU?VfjR@J;OV<8FA*Y`VT zoRe{4JR?19TmF-M8S^FMBi3CpPJm3uRvmvpeO2+?!@ipmNfYjZ$8k-9yItITXqWq4 zdHXW9jV;Qg2sgjDSdpQ!bc=7ViVDdfeyO7Uu&RnW_TvOGVcH8EB-+lk?FSjf&RD^m zEMK9Rlly$_Mq8^~9&_HW?Qe%-oi1*AL_}DXbg6baY8hHYqaQH@LSU{*y_*Y*w0)7P$L0Nf{u>WYbRRCAn)ld_RV= zadS$X#}~VnJC)hvh4o!+z3Dic6ld;P#t%OclSNT-Uq~$F$S+~zSU2Iwy(~CfKdtW! zu5RNFEpf35F7kd2yP8U@A1<5bj$KViEaRi^ij6#Q28mm{l9Jff#sdIg>mJoYbK2&S z%^1aU$aF?CO}@2wYbdzL_p-hkw~_mZ^0lZtPa$9zB2IJHB@%${>dQ*jQ~r3Xy{v z@hLe}U18}qjn}Ey*R8xBW5+Ju(jDvYp@6osnV?;TtM_?t*Wbx|H@M&sS7>nWcbKS` zQgib4%1~=TC+{emaq9<9GxEZA%+}@^$LmE2j9HJ*2SPf934WHI3}*H@5)4exE8ge( zHJWX)^qHU^D>0guh?2K>pETc)#v926tM^^Fy{k0`3#&uk3w58NpQQhuAma_8<&KKN z_wg{R@GmpgOKGgmP3OU;#m@S%as4d*;at7uWpVQsK7cPEUGybOqN* zmL%ERQHvU%zF_I9W8Oh1x6`qtx;W7!E_L+ey&rO1$FT#~%3X;M*GdHSoyKMcTtcXc zlL;K79$5@5Ur$9eP41&j(7XIMI2>ihyCheD?(IutBC9(mWo5>nbK@x29CibzSF6k= z2su0icUSO*C zA>R^ABtNB`(Bgghd#g`zOIV$n zUs?wqvmJS^@X6$0=y^(1Z#MXQg>P70NR|O^_>HSRd4|dSb)E-5f5xAm7n?*bgbiCnMx;Fq4e=NV{mkKp zl)s)hIj-m%dDn$w$u)qAtzGe93I3u+P7_wJ6hrq!iN#R@V};T;h8&Md{OXym{1ez@ z)-P0K!D*LyfV?PjJ31oFvWmnktMpg&TCv=1n}mZs)AQY&bR!$K8@ItyYp9oeave>% zF1}T=0*yw!B1g3I^c3cD(QJSHa6%(ZI*iGYF#yksdde$esWwl2bc)w<`P?a=KgF_3 zZhvjb_HXA%Pq%eyVV7?RNxH3Ovh8FAmVF>)SIDQ(<$Q4I*Uu)Lhgnx=%w{zR^v6HL zdMOwE9dfTWqtCtCr|x9|#aR4q^Jl5~bEo>TPX5HH1pO4fm{akw-C`~UM1S`g-=Jov zyn;68Q{RIIqL=%-KR-LUNRo&6yL&huEI!^_fV0ALT|gw3S2-OmEn6x*$5pke;T)w* z!#8N~0VpH*fW+AdzB&??uKG6gKsxU3UzZ-qJ6-3vhG4<|2o|OxUHWsA^lzP`V13eb zaW3+=UOWGq!`X~L?`&5W5kdi@TgV(^#@LWwb1aj;_jQ3FCq!}#r#G&zb&By|5wW|D z*9DG{I~0R8Fyn`fzn{fOuLp30Z2@6=wdog>ve zhx60wTLz5CtgFqyiEAvH`CPJhh@@mo3eeWq4v_AOrmlZnJxnj$y(}E9@ccCNh@|T~ z%P|%WbO6iVYUk+?PyYIB?j5e^uONq}XGaJ7H%t166$3(!0oAidWOFBRJ)TzA6Xi^b zny>`)ro{PP^jV85iJg%DFsEd4P-e){rx+{V2ex<`l_4)auHQJjaJoZz=qusKZ)rAd zHnuG$M>iK}HdHKBw_Bc15x?D4NZ*8-6qMt~j%1@&B-FAno|KwXE~QF>v%_bVKw4@VHAO({N&=G}a2dMyy12uxPBF+9Q0xH>KHmTpj?_>=eG`>XIj6aJCcJ(LZ`SY+rIf z;GWNoVURkDVUtrz$Hu9lnt`|1Ar2_#LGxx4HyHK&cwIh?3{o41KSIe1J`)l$^a7Yeqg%=1DSVxj#Ore>>Sq-0iM=j4pmm{or za_}{or@jT%tB+9bi1*^U*-0#@7icfFYA?B>DKb$U(+hVjKYz${9db zyIe)WwYr$p#;jA)OOD_=f!0iH2{J_O!8M#^ht>$Qi^$%wV5;z5@vy&*{E=Ug#Lz~> zs-_QusV0KoDn5j>&O@Pxv+0`ZYi;@t?^SivVMg9O?WGaIu7=f|7DiV!xb7hrd0aE{ zN8F&jG(D-XZTUwqE*y9HcFpoPxco84ve)!Q9VN8c!p(RD%k2chI@Qcg_oRd#&H@fQ z#N^Pegwab1-Iy$v|DO^?2YeZ}CGY?h@6ULu4-3HFA`3be8Q|M2Gc5Ik4ex>Y{^0Zl z%50@XS=7Y5S@=R*rj;@fKi#bcf>Ku_JQ8=&$oR8L!M3ZPk*@$m)5%^n*cdBs$_nP! zCOA9yrNjk(Y{OY z^KW^(T2F?uZbD(rci+Lqq3e_5H;uWYh}8Bd0J#_tV-l8@8ow55$EX44Sa}CpPm{wk zu{WjIiEiW53Sn%*)kex)14Q65BEUhO<%$-$+5CQf47aFQqJLfjFf0$=2evpvHOO&x zfEe_tatn)|rTzQk{7(ob9U|kR>eN#GjB)9ktg^*&ts7F8ctV9uTJ0Ww>xz=N;bS~S z-u%43Uu(aBhWHCYcaP~>o_kS)~1-3Cdo>kto+Bsx>N?@q%oK`!PcjEQt zHDOM20SK~Ch{HLydMm$HFv5FtY+{YE?^Zg99g$!(L98@f`iwe9&`~$NU}T-|n8$(6 zXR34rg^k~l8CgZ`ro7*X-p*!EKOLO7K3Ym~t+s_3*40MFkUP1sMSE~F?=_HgY?|i( zJm8~uq#xJx^<_sqw3*3nL8bj!P%*FB z7sCX_lEkQGOJRz%w5U^W$}4tFw{O#4D~>61sPOs<0^Y=iq$?`%4KS|WOa7gfbzG^@ zI!|b2fH9h6^J*U-%ZyEuyo8uS%5lHBo7)7xHm|nKlT8p)Nh~G|^xc59lqAD$AY z`(b2VauW!_-Wb=5@Lhf`LAXow19|W3TJKgcZwJle+7NVZoO(uy_KrfMkm_lae@dav zdwJ{{@gOv@(D?C@cvDB=*S8?m_Y(K!3{6mF!B*Qi1w!y zZMoD~KRq07g^g3Af2=&&;#{kb6HXaM+#~zM^?q5Y-c_Ps1oQ#=PRnD;TXKib-{dO9 z$K)aTBN;EpIm#verXK&A9-DWtDv{wqB#f7-@E^fz1<`DM`>(2pe#E?Pi81K$K3u&I z3eqbDK9~0*wtGD=HvzRf;ad$*g+7<>kSq?*Cy6J}9gmrClsuqs%Xf~XZ8)rXYa2|8 z#+r;7Upo)O2kJF<@BL zTl2SH+u`l^3X~XImfY2@hi_lJWP1Yh&R7uv7+2wN!QL55(%08Q9Eq3ezAxYFeJN#y zojq=G&3)ZAVl8qHav-+>DWB}WPdT@ohks4;J)9|b+uw;j|2U`>!BkVQyl4{?NNUHFpl!t!uBu_Az(3){IYt2p?r4xLB>*7?Wxs7eN(2jf~ z%n!(*#9K?p4b^8UC6eSxbsNvfNBP$1@Hc1Ty9t24=Sz+6NxF5_)+9jXd2?vZNmu7} znce}Yj1jVHo(F{@oK{iMTC2;=RoI(db4KMHuCJ3!h&jl!J}zPrR8k=nA0l;Y+nWGv zO79Br?6UzYVaZ$78JpcpO#S*26ED?Ll_E1EqjfM#^u|v5- zb|{zr4}9saLpI~^T*j|k&rrLRAE;eQs=neDCf*HbbfUynQ<{|6q;!HNg=XF2HYR`? z!_fCyTDo9+!Z*-(krhvNAr9lDl$2eFlbTE#7Jh>N0PhsD119N{3(w$UqbWMR6ovAm z@MRI9J}ooek>@_RNbXhkBF8xjh%CWEkG^vue21?HLjOvaq+nWp2;>cye)Xa-Q3>Af9|h zZ}R1CPiZ`P*jeDmyFF#`FQ2z0T6~4ub89^LFTKfMb$f`JK%+o&cW?4!>0}JM*&iDl zN$%~RDQ-Gh3Sc1qlimVF@qQ-xq2A;f@qQ-x-rnTd@vbDf;w#*Fo*l98(`at> z$wJ>T{iulIN$XSe&m_j!(dY;I>K;Yso~#OVN`6`SkbiwW)5Re!ifJo|rM`3HSSuP`9pK+1YD_65|qt#<%@|Is;Q53m> za>45gUX^OKTB(DAuc(3)>oh)|VHVSBe?Sh32CsuEb(P;UK(T??n+fjV;M+WprjiYk zt;voznM~r19T$3rZ|v&*GQkZHi_Bjpxpx9gbOXow@`U;#6gpOrFPBAV&hc1`OgT@+|5R;{V}!#P6rlr-Y7zDNhOUK;lmc$w1yu386sRPYHQI){!MtW(h;-CEtXr3-@-tmDA3>hpUY_ATvvyC!Y3+M?p(ALjB9}r2no?8_M|S{|JU< z5Da8=*!Yza#OAp0rgCMl<_^ZX+>?46RKz(geg%kY*+oEIe|<~-o~|zaRLJp)C`{0= zmddCNe*?^XJ!x&o2>zy%A;(64{Ybfdffg3O^KPSSCj%~D`Q(&}ttXr2NquGbSx$=l-##uvq85-7F93QbFZS0jRjuf0ENoXO-XB%81qXOpQ-Ql`)_hiQ@`UuD}E(wMQA1wcHPD$>T$9Mb;5<}aj86J z%A@L4p@L-IVlO=j^2R+y@+b{A{zE-VV~uhiL+gaN1ms(+RH1c3Nb>BP z0oZ?3pXCCly!~9g$%sfzBGblRlAbUe3cR%5I5|yHrNzb(^(d3X_>f2cmT_^Wtzt^} zUl%0U-@GPUkm#JHcajsy?C$@Dwv@6-!ukF$C8HN`^!9bCtH8OB4~gq7*jK6XeLkVU zEyB5~ty%3~06?G)Nshg&wqZrb;PL7aRxPr%Vho~t5j_%G1m$3mOWc{L@-M`lbTHKj z;Uv~H1Icm{;98DkDEDsuiOPbj&`LBU%U=2zOJqyldpNwtichJQ;eSr~au`ooJ4{G7 z2&6I5Kbo7|FNkJv3CfpzS#04qlplsGL{wX7siS}41c{YKp_F8tYL25+Lv&g&k~7M_ zAr0^X<+u*yLu=)pulI6^Yj8L^_UzQ&;07O?!41qf4-(!$Q#a`)#DNAXxQ23LG&cQA zd31w9$GA@r7!$ca#?Z(K*`mm}_@h`@-S1*s&yDHJ>T&TUAi7#;d zt;&K0J%ns;!Y$-baSQn=@xLV^bf)i}C3)e+t=+x!Uvv0*MzQzUMdm{&;HEmy0(Z?^ zmqX~O{88wsJ88|7P)NR%h328J>Z=9cffgL?o>|ZxTIUuieu3M#j@(KK>dO?}j%Zps zgQjN3yxKR%o=`TbqgeFXp5!I^0G#Mh302s4}#)2*s-% zqpEFDHTK(fX=boA-8lI}EG}od9C7H@wEvJ{-D+_s$i;mXbH z3j6g)qzzV?n!_SC^%*mnU&cMtWFnh)N#SbT?fe$5U!ZVQ%{haQn8R~B5L1(dR3cc>z9tfVf*`aa9s zX-=v#&w^Wxzj5fPCX!amH6_zuoZD^M5z;%W^ttXYhEOJWCQA%wx7PpLqqNxAA5bg-LmKl0VlpwD%@c^4!^gjX(rc%fl%5Ve&q^r$ z4wKSlm=dEjmvxN>rwFA-OG5$4jD?5W_~bc@F0a;iW3KfNY4Uzfc}yNQ1{!kQ4!y)% z5O2W9a~iPXOuPZYu1m|rfy9$)*eVN>v|9Z8+FrAL9XEHal{y}2ufxX)%j1wr{eDJd zO|nn(H#j(dAklX~Z^4z@9{-LcG`mY)bM-AXQc8_Xl*;H+D&hXkH%4~rJxHnPOHnjt zJB2l)c>6Eu9d8~2W%QbPMs+uClA~AjW_4sHvN}~(bv8>t9`vL>0>sJj`Ik8gP)i6K zr+#ivMXAyBpQ@%TPe1lX_|w{bwRC5?aFQZxN!ai2duTv$mc+8_<;-;D+!C5SJLI_L z$9WC9i0ZAUzqKBR$8CHJx}yE>bB3y7gr0dI zsqoC2Ki*DAtvyRvB6_2`OT>mU7AlzO@?C|$xutCjDU<~% ziju4zNhB3@n-oknPIOZu-KaAQF5!*P+68M|TJ12IjDDGt^dFWpmb|9birT#9jA`C* zl;_vQx&a6Far=g5EwGnl95VN@Z`e+XDF6}9N_+iIJ?H0RE*c`rO;xqRVwT()F zg)2h5kjkp?h2n}ncfJyo?l|u=l0>gSb7ydggLTW7CVW#ik`;Q3Cu!+7c8N%{(85Cd zQaLI)IJ$S6FVk!%bN?TqX5uB1l&W=1qShB$`qmn6`|#cxlqmI2i%>lP?iHad;eXI%*$z12EPuJ$t@q^XsX>S0E54_CciMNehwDWteT3 z8vl_fKfo+sutdc5FPy`du0CrHe+jdBFJIBqTl~c7=~79Gv-#rgQ_SWYeQ>@! zj&px$(j?j)&GA2Qhs~F-XkdJwtV!{#*sPV}U?|=>CT|k<^aZ?W-m0_Oh3yk=w6vG| zOYDh)GLLf!fhWYYtFU>6t0vqY!${5aw%@!Wr6w%b+_jgt`@=2azc}olndN+M$gbYn zyYvb~a-l_pO9Uc(v;TVn(V~AtAj+@iTf4UOtz{CJ;BO;o<%Z;-D=G{_8 zikq=q;5J&(wODAEn1WdaG)ucH?K&XuOHi;A4Gp>@KilndF; zQsX_8ZkFNKo2Fdn-CA=-ggWo$zCxV$cXHc^*o1db6WBh2$zlBL zA>^^W-o+$_{Ml56iu<_nJyMagl+32!n4*nVJD<))bW_5vTZwL{rsFiI)pEfhrbIDa zu%1_H+<8r06pLIa<08r`)0SIY97$*w@p5EM{d1y*tIv=2{hS-~Wq(m7F@21yOW;RH z`a_LU?x&b)!~LCfXj9}7##N@qa_&H7HYH>6u*RW>MM5m%(%XuDMy`|?6MaLOntER= z3Eh^YH_GjkrsN4^9$GgVU)uIr(d0i&SUrmb=W_EtGP%*60g4CL8`OkW!=RWIi)fYZbMa5ew455thr;4f|t{7{}iIQZiCcq%-g1;qCT zd&k-g$y8XIp#TQ2V!d@q&Df1yznw&=uJ7!eAPD#GWt=B6*ov5LRl|x z-{b!j9;USVUEQ@_4P(sC49{!h3yCT-B4kSsY*2+nUAdPvZD>qA}D zlGYfk4GG{I=bF{}PZEn;S3MowpsQBsszti$7A%7X;pl#|6v?kY_AB$-t8dV;Ry)(= zeq}&LDw-eMpnmi6>s1bSFd*Y&ehmd=XwYm6D6Zx`tI-$uUwl>#X8v}fJ4|QtO8$^4 z6%r~Szg6rG-Y9mDSuAou7P^~~^7lv_k1+i4B2an|rkiTL1hLSgzR(iL(1 z-SHJdI(K{pIW@l07X1mylJkUMF5@fs{Ilb$kW%BzMAFp^fbR^_w|&VFtG52TL)^eM z{60g>$@`0Hd@ZVw@%1<&Tq20ooWg?+UDQt|Y z+Vw-TT^j`V^V&6(cI~m+b;J?=WVF3LttDs{IjdQJ)D?JtEU79jG&4TQQ-UwbB$ps~ zg6yok%|auDQNoVkSiEh!f5u&_djH3xi}c;S?YaRNGLDKl1Oqbu^yzt1TxU0d4<=o$ z6`bkyuLy?JLQ$`+zYSTw>$6}$IHpW4;m~s1VyUbU-Ipx4doC&0UP=$_`tx;}+Dj7y zyZOb`P7!+e8x#vU0^8oWF4IEK-t0E+6PxVK z(gLDJ(k&~N>6@hw&@K-a&ip5kF`E^6Tz0@Q*6&}*!)CRhX|+G$1sCVEJAXU0)uuOh zJ@cY4Hg3Y#st5lb+f022_v{Wuo`(d2-wVj+m?{%ll7N+@J=81|qRQyay}cNGQ3wj0 zrC3na3)3v~ic zHw!g~1>$EV6DKFT37Zu{XS*^#Z7THA} zX2`CKH<&B?b5a)O^puo6S>?TxIHbe$fPC~n6H`i7JX0onkp6+kiJ%Lo%9NZuk=?YcfkI>dnq%y5`BehcDz<5>29#&Ni`Fj%31o6Rp zrboA_GO{((RX>;r%q;v&3pg2rzLQQ6w+ICi8S0{OTez)7&n?r{{K`|a#+++7vZnua zbH34!15nTEj?kU&T$dRPJPsuExr=0kA3qVV#T~u&oP0UM?VwYkw^3cm>5;L|SQAl;rHeTUAk~yZ*uF1w!(~ zX1JmRnc?zq{tWl7H7N+RMr}S*j;Tk^Hbei~l?KREc(BOVz9AH)xQj6J*AzwRZL)_@Qt~F-j{hm_ z`am^J2*PUGPT%_`Ym9k|dMQg9)rYeF(Ll(Api$=x!_oCJ3}zz;ub#IHquUp&X;F2< z1UCEj^;y?^&CijN;Xm0Afwo_T{jDr^ zPLLnx(s8ENNe>B4&NCiHW2Y2PzFpOuy(HNl^Kuy2g{Hc>B)aa z_rCZUFzV;??v;;xGOjs%ntWUtI{#kztp8NXyFT~IUwlNRATswe_Wo1=#P5~ADR1gt z`Fs;x{9d_IhH@q;aYZwXpOejsCpsC0Vy+cWbmaN*M75U)rRwkCu)z3kqL9&rE0lzL zt$D`(&~`{Jbt9c(i(ViW9;oERsQD$ns7~{KNF*Is!oA8ozZnF&ObY~rv{rL~E)s?= zFAL1D&`GL3qN>=8ho}$Wv9(;tkB5c!jJQ3o70bLY3Jg6WbOUjii+c#fd_%Sw8M+Ze zFE0OkGbB8;i^38i8XLE5R)FZ}UFdGNov#^Z3E*aF#+xJmGhvpnMuA~Lr5HHyH9G`q&Lo1wj03R3PVO4uM zE8jC>N$7e|<{T?@Js67*|5MmYszlWeNtM{q4IHsxYU(W(bDJWG1^s%oK$Q0ck#-wr z07z-`J%xyKyweVf`oEo-L_}$VNP9Uxv%*L>^FezV9ZmIW90K>(=NwK16tOHBh|63p z*Xs6s1N?o%+5HSQmOc@u*-zUQ%~tpaaI}DT!9)JlBW>P(UBy{z;R3!tBfA#k=kO3V zD@v6vepSpKE)5lTATXy0dLy}}u{se6PU13ypB_m9WXp8Wq2?G`1B{XMiJU;h`; zo~6)Mq&80`$^sYhhlLl6%ikM5C1Ir3kG29DPhRL6w@Ploze!KQQ*yhSY(=Ry-&p3I zgnKj|8LN)VwLp~hfJ4Nw>hldXyKF_gH>uaD^6V|1YUAw0dpU3XjO8ua=FQ`cpIqJ? zxa#K3Ve^e@N==FmPwR}n{z?){z1}1SioVpQRPn7d8VqcygylO?oL=O+8hyH$1=i;@ z=sWdefUy;M)8wbx`wdL|hH}(^zD&cH?ebavZpZQg{%)stYJUA8Pi=218@I%?-;kBB-V0eS3JKS=Iha?3;UpEdnL zb1@FMaC^>YQt+#AYVoBz$lq=Exob{-`s(ZW+>thxYcGe1D8nQjW~}|6#N77ssN0l{ z;nWzGPQDAVr%jeBzTOw1ccnvySg6kG`(?9SB#ggA(7U5l?5q8>R$1M!i{pc3eA{wF9Rszo6R(Ndf-pFg@l;x(xSdY6E z(_T?8&Q2@NMLk294>jvXs?#ve!G?2E7eB))c5PzpY&kecXZKbZUNO#lF~c)zs+_8M z2jQ2SpTenPl!UecjY4eN zhVY3-7q{=nY|~x}E4LHPpkqV3r#F{yN5~jO?^JL}2y*mfR^)}f*YR%>|1RfWuHPu4 znkODjRFh*>!!8jIa2WnXGd*@%iu+9_n^GG3E3<6Dnd!|lGpnhocJF=m>H(Rr+jt4Q z@4E=RWEu{Z<CMH5(@DiMZZ0bpDx$n_FN*eu8S~^zPIr~X^2OQD6KjZh zxj+Q{wCWv6dU*YUSR&y4`UP)WwXC1-8h2Lp^g^=rt!akqQk!=GP8Lo{->K-j<3hz} znu^Z|U(Av*I6Pc+Pb{C#xgWvazangfNKaa$%i%KanSE`vpzr7=qu5oE@8m+yRpubMjkW&`b$(Hu zN@~hCj?>WQL-pO$QgJ*buh=ezKxYe|G^W}ZKh>QJTiP9)?Py`j}8Db3$|!(m=CK$Vnj8)doCez#3h>|+`$(>_y)%pWV!*_#N9v=SX--jdRL%lE#&m;S~-kc|lLkDSaDfFq@=ik8Lrg6JX-)SGdEQj>m&&D$;{s z`--#<+{dVBciy2>rGZ|-J=4U!pMJC#@wcY8egfW&42^}i;L59A@J=?L9pJswULTG) z720WG?WLW9{y~R@d0KH#pKD4&0Xw*Kt2c;wN4+){=T!A+j1`EL=Cp((Lm3mIr_kfx zk^BmNT49UVK}5uXYE6yy_Y^IOI$xLZ)5Dvjp*amQ8uYe|20cKF8e}vWC>f0+b2MoG zJi`auh7c+$>D9Q+i>um1YM! z<#T-{@y4vqH{TfmE5R|QU6OW6F5~K;AaX~snVP}=!`Y=}o>cBohE{hR`&GNIqy4T9y|`oSw9#T5|A4G|Q>*_QABix{)sFn_ z(G2aki@5#WQ**E$ZaB|)9EOSsHazizX^b)KDEvWkTC2V*{DExE%%^0NLepBq9}Gxq z5c=+mBiX>P!k}1!QoF+Mom1Jj5lRU^r=3&7kX$>ve8|_a^y7fif{tu_ILs4Yk)EW_(yXe%k zZ6@g}nCjVtsU8I;0%xNMbQ{%xeS=^hUYyp@drOb*MUHS861$|rld8SkLO0Xds;BAZ zeBwVzPvhlVC*^*Tksva-4dVK6O`Zx`D-#yxIxmSsTDL#s6+>^qu+23~xcE&S?T=d%Y($ zt%XY?CgKDu2aO1U%uY?zXZEXlP20w? zx9U=R{gSk8<~S|BebrE_^)$)fQU65^&y@9LEF<$}((R@}pM zqUq5mzPWTM_nYRp@^+zYxl$=r8dsz!O-qaR@^ztEs9qXTz09(dEX|^1`F2l|s7m&D zot5yVCUJDPs9Pya_T;sA#{~A=heLL}ND$Bg#|fc|BycEf)4sognIIx+s_uC6ZtCs3 zZh`}YC0kWLSYp#9?C$}7h5c2D#UOWoeGcsAP*bh^MtY)<9G~M{=M{zA? zIwlfg_yl@l32g2aZr&E(D=2-=C?U%qAQfO(w=#3;A#kbcr#lo5eawf?i+7B0J{-Ch z$+-A!74@Qx^*1ZHdLP(~!PvOxkcf<(gvqVY7i9BF} z!|MH~W2=tq#knXL)0jBor`i?d6)heyfdfx~6G#0n_Gyt_DtnT6DJ_bG<>gG$8V9?$ zLj;P&3%}(;)%z@15D>Jypx9V;PicyU#Y^4TTPos(6vW9pUBA!MFXqd|1t$_5F7+35V3SuX zB6Y|ys5d(86f-*QP~*Y5Xx6p_?>dAeI;NR`_pBvZZewu@Cn&{-#Lh9j*``8%*3%n@ z^aUN5jx_Tm`gz$J+$z2$_Msi(E`nLBe0h>DWo0N*+C2TN$hlo~v*N zp5Pn2i9oqsb3jD`<=)mCdGs9)!j&-XElxxpW#cV@awk%4sj7j^mepX^I=f8oG|Jf-qR@Bc zG%XfO)wm;7XxiT~+Lw%aU!1;PMJ~@YwwssoKyLlYoKE8!dETwJ5yYS?r#gtXUQ>}p@sV>I0=$1+-NfB`XOow=s0gGR=V92`&_ zK|~X`@!@}fV}-hSD;sZ8T2+dQ_x&mWHrlF@XamJ(w7{=&@?-f|%_BqvW zwsC19=deUJU!BzIlv?Qso)e>ufh?WVL%1Bm;Yg|#WXFFvolr5x>L0VOgp<;<>5VED zJkev)z4NR9G)^P(Xe{=>e6RM6Za3!~cp(ua| zx%hbBFk`^FggWYn4RXX1c@CJOwP9lAlo|o5VD9@y8?A&|XtrU;X*1f@qim?7vyGrf zCMLN@g=Q9cu0@7AUe2Ero-5=B&prG-70obTkE_=cnBsD#8)@H`^ypBfAYrj>{u*5mvT~VDK!zIznVMyJv>Bc15#ibv9VV-p%ec_Q2=3ElZlIi<8jAOChe0zMtN>H2?S;ik!Vb!(*;yKIdl^pnR+9Qm_M6R$nb6JKFR5`~; zHSP4Z7Du;`^onQ`3?LzS^%+O_hrj!R<)e&iRB<&j)6}DkjIouV$7hu@8&=mdZL zS%b5%&*0G4tW+aaU*T1R;A(HG3mY6PUO%f($I6l|+i*FravRt|_St@Kl!G|*1eFEF z+}Qms2#`;LrT=3-b@X!`5yf=8^#sPu=Ce-JRcD|L>=sFk}8EqhUWCl!`1E_*SuTZ#_yEX z@o-9}TO}orgXbPAO!^!ne*DA~e`=g~LbN8j^}~jqNKnL^CREZfZH*&W9n|%Po0iDC z<1%dbnt^^hnAE%v$u!?bWvgF_b|@ijH~pYUMLT|&y9>S1j>oa9By1p26w7x}mN1M9 z`K=%z?zpiNRQU=b=8hX*q@E@Eu>_w*L}ee00!SxDsO2bR09sR`2Y%iV+H#U4|=S9RW9yG2r662HAZ_SaXAUBrMDnHg5Gx~J+G>I|EN>$ zcM)Q;jXG6O;A1rnR?-I~9Vc$@U`OtL;&y3+y}2&Jdb;*)KR|HA!MT!pKw^Fqc+rtd zd@;f!3?dNXHe$(2q~My9^0(?M60z~p=xyfZg=NEQPUhvTt6z50iXkdU*{M$pPMujc zC7QZv0E82DZjxE^Wl=^Y*riK^Q|$~DWRyNQyZxLqb*`63R}IQ@BgzPqzFSCVvLVpCNw3?px-`j1KS&LP0msIu3L#nMX7VT<~-f zvdKL6nWf*1wMiy%eohYcruk2f@}~Ijsy`FOFGl@-yc2bN=-+1Fzv%g3alI4`&2+i( zP-;5&2^CipPvNkD8jg(*7%i0*ZJzP;Ogi*BS49Qh{_nxlL2bQ6pU}nU0qcs3^Z(Uy zTb2!j^5rtHNG+K9hqs#x$-h1Ssu@MjnC)I+c z)~J6pFKw#&e`a3BJKXH(FPWF)0N1!Fl9-p0IX*A5`L;>KMsr?fs+udTc{%Lw&dYxP z%)D$X`IqOVLiFdMXL5m0G!)8MZo2fUO1CJdv zWSe>(FQJ~{wSz`=sP~16@3xrv5LvRe*ED1ET2`65WVVE#J1l~%QEJqaE$4BIX3YI64d&W(A*aY4~IuYh2UBsJ(1U?_fFf1hE z{GjsTVD%O+r-1r489Mou%ute&iN-%^0?CHsPpambbc4zysCl`I%*3kBq=s@(DQC$T zw3Nh!QT~BW`E1E9Q-~tv@AL0X{z-IfWVRtET?%RGc;(lgcH~xl#!WPI5Q{B$`_{I@WysbOUYXcUWQxv>&0ae3C><*kJHfg? z%627+=W?$>)PkyGY*|F{ae#E zDasE}5c{r9OTboIc;l5vUmk zWJg3`$%F}dfM5Sz-KZ40<)|Jn%%q#_e=y#E@zs+qK7a9vC&6^=Y<+sw|13*=ORk|L zJlw1HN0*8wWkEMP11wbm9vtZ3G1?tm&~1oDO;~-q@e`&!8zXiKYA0lO<4}(dEm}H( zVKhx#p3Xj9fiv|C`4Pj%G^3T`<~uj5PI6tgzVRvb6^n#);>qD&9d}Zw=&au8V-pyg zBpG8v9HPKuhwU40ZVdh1DZVkrO8_|s(Vir}2#49GUTndj`ljV_Z@EKJf3r%zc^%!l21k|p2iVUmyUIXgs>J0L29JX~;P zUdRDTkG8&zE?Dd07V|o}d4yXaImI(ZO{0{lNys#Q@0I=*^+81J#Fk1A{a^Op2d=6r zeIGq47AECUv8XJM1&M}*iiQ6Y6bls;6%ES@6ch{r`J>p+3e#o~WWu6`8mDlwqGB2> zt8F{oK#Jr(XAZ*ZaKBde@)5 z_S$RjbGX%ww-NA`koXg-7+0(N-tUjULIvMkR0s!bYVN{M-@5%n#lYs9D^nk5!DmFl z57yn^#4orP?B=iLx?@2$&wWC!fkvIeSimkx`>pN?h~9k3<$m`NM1q%G3f;YtSR2_B z12a$rC$e|5FrxX<(cVGOQY-E9|Jg!%ut)&2Hes0D^@ zD+VXdjz73}=drSa?^z`AE`xZNWBqx@*5F3~Y_G)3!acou&Bm>Ni}vErVq=Tb>@v(q zcy0NH`Ed?w$E%Io(!w$BXTJZXjOm46+8k+lf`08tvGkn}?@(hrhrpdh*du zpA8S7`FY!q$D;fB2AIF2dSd=iJR{>XJ-=!{Jg0ouzuKP%ziKBB-K$;s-FqLzpA78Y z`&04s4l_;*HW^OhSs0!UbbuhVw1Lm>r2k&&zgPP2mHrCT!V&eY9lC`SUeJTM1{EyEGm!h0KU1Gc9=P1E``Hy`-p!>P~d zUX6dT(#JHKh`5F`FF{(csf>x)AC|GDQNi`@LE=Xb;fxWBee3qr^&Be>^ACz(j|fk# z*F@q3R+k4+7UA5E@^&!e$LyxX--iAj)2(1oY4rFW^=l#%rr=Gne%pI<@iHbh2y+Ee z4*3AdqyF=7OC8v|t{}7&cSK0zS5;0Q$5%XYqm5&G>8{hM$ZsfphsPfKkKKaw0_5=C z37Gx*{=@sf-QU!EZ^6maKjJryQiB75hzWL{{<_Eh+>6Emx6(hi&p2RL^qO%k43{Sc z2aY<7ls{4dr$0O0wDvRnX*&G1KoK^xgxMk_hdN*AG(0#^86iylGK1mPHfqjTn}^Nm)z>vqq^ zK@D!5Hy7VD`VK`Po_hz}GKB?Nfd(Q_mOoI{FUYbDgbj5QT^~dOv+JE^*9RG0A0)b- zH40)&0PXau5xah%==vbD>jRChcgn60LTv_$t`~zK-mI6^`!fqvUGKQ_E>yNNqz&_{ z&s%EV?6!p&Pw(g5I}*SAhP^afhuX~cUkA>5Xk(2jpr4(j9Vwz$s^dl&a9z#6px&|^4$ zT8{}o2zTUtz|EJJ2C-PYRGieK;n>bTJL-Di@`{NLzg~3g5v;-c_bHTd^=kbgtLT34I5EH{YkeizoFD6HoZalZkYNL#lojY5~VEOioR+_E@4 zZ&|8f{GD5tCdtwDElZIk|DWBmluHtE%aViifB2RKw=K9|3EjQx{;6$ownZG@!2*_c@3y@q^fnQv2g;cl+-$?p-*+{BQMVfAHA) z(-paRLbX4>GcWp6?zB5ch}t)t=rf$#fCF4Y7h88%go`x$wBPV#q}ROV7OARxHve!An4BcAc*Pc@$Jo_AyD7mb%*(WpnIJsoBPIl_&`@&w#|S3oArGV zXPQypm%-{;-#d^a>l^P?-xHz=gN`(rH7)`64VS2K9c%nY=ss$E;z-l6_x>w&9_z{H zp1jJl&j0QGD`%{AF$fZA>tYZtba^pwNu2MCfdj_hxfn!Bj;=2TEw_ju{%041c1ePH zBWZLa(wG3S8TEhh{?%0OSgC8n#W>G>dP&C9rYATZ>B!W(j%UL z9&PCxsE@GpR_cQ-ef(db_qFs2>fJ28jr#HF>i(=OzEMxQ{2+cPRMQi1)M7TlzTalw zr$<)6UWRS0PJK8bg@n8$AzBBO%_d$8{wws2mcE+$8cRPweYvHFJqbO<($`U+W$Crl zqb=S4Dd;0CJ(>DoOV_CPwRC3{^lp}(PW|{aRe!CH`cYHIK7f87zF5PJ<$6E8EaFp{ z4A37?$w2*9l^m$YsbsL8qLN|yJS4TC&0zkc$t-6iEuXo|&0MXLdWxx+#W&~;m$E-< z^*S829kfT=>`i(#^V^v})XZ1&oi^}q$nR_Bm&KRs#TR`FKDS<5a~elKJzelO=*h-0 z$v7q$$5`VSC5}7v%7gR^)9YrECrXdJ3dgb*Y@F!J2Aj!+R`OOW8Hc16%b4z+$~M#i46NoUNf2Ft1P7ADs9pzSPZhkUn)B#|)A#{a<6jwu21!8w{HB8EDH*K5abp6iZL1 zKFiW8s7G6R9rY2G-bQ_}r3XC=y|1OmQ152xInj{c8#IH-QGB*39hVQ&hdn z;`izPfBLl3xQ^kE&3_u8n!HKB2~1kVi}2WKcxYRwZ8iN3zb0J&3_q=rh=&wDyaw7D z6VLfg+ky5eW`2g5Z`Rk%{8?tc7WH@N(Ux9GeT1dAQy*;Uu`faIYw1YFXye=GEjmYz&~jiqbUms`5?W#}oEo=$z1 zrPoo9w)CJ^ppP*1vNHV2cc(t!(LkwZ+RjL^V0C%F5Vcuk*2{66AOPx7e#J}u&PtzE%G^y@U2P+MoAf*YqaZgEZLJ`>^lOHQHln&+uulq&}zIfiQA!fv-BG3$D>s%Xnt=%KWga6J>X5~ zTP;16`esYtL4BjCbG&poFH}Y+S1%-f zpB}Xc$1*-Y*B_-zEnP15bkWW*vzwWzh5i%zalAz(BhV75AGP!%>iaFdhI+lF`~3_0 zR!d(%eY2%+qrTD719n1RW9g~Xms|P{>M5qqdKLc>of}w({HbQX)m|-nI_*)k5A|WM z(qn1Qq`lWUcCC{6$0w@#m&NbUgMjDJX&n9O@2CfEuZgqD-=_PAAMVt~)Bd~<`#!y) z`7;bo+Si|B*BY3=+|1WpZ$VG7^g`;hEWMF>w55mcfME_^d{FCWQ%b8#R}GK zdK6ic_rO|jSg{^%puW}8Pg37(>2VFvH<~)H_r;qSb&($aR~{?$CULCRi=IU3TZm6F z@mf3eS*FhQOzaE54cv?TF=oCRkJ@VH4>t3)1JwIky5n8w-7Gzc`tk9q|M{mbTDtdH zC)ZDHzm>&r(X~-n+?JIs;KZ`vdfqT3GP!&Y!lfj2m2ZidyrwTqP>>(6w|In?t?zd)Y;owZ{SjyKgP^g^{2g(_Hx=U^Aepn)5?sHZxNj&*Xm7ZmmCdc9WrN z=|ud)K%~b!b(_=uBF?G#yR-^g9yNX0M_L{8)|h$PN$SfjJ+2XYiluL%KFiY2P>;6s z#Qo4mSb7ch!Itj#5%j*6zJPi+Q|J25UEU-oAb)+?RwEgpFH}jVeoHUTW|*PE^|+bt z&ZS9s^&-Jt>#+Lnr+7D}_yeGRb`0Lx1L-3cX^>(H&@WU;r+&iUBt1RDB)#26T1C=A zlFkBYS^Nh5I-H3d5i8KuS|Tks3QL6^2#XfZoDk$NLX579OtN-;4#@%t@UsBlb)GS9 zC)@Rr1h_v2;LAu^g~o@l?%K_q{UWDL{}*z^4DZxOA$+Zh#%+di@E8!RX3pOXfFMC(=%@mY z*Q+Fi4S7G9KAuc2lw4#1+GDlqP?7a^)`E} z?*0M!&5ZAPGvA8OtvAqqlI^(Or@fl?@Xuh+@M$lmJ(KpSKJDqWSJOV!r#+VT1&q6w zPkSist@PK;_jK&>`_t~C|6U*VHr@R_+r2?|_2jWu4>FEUact2WVApa){eAd1>q*l& zo|^S?9JK`;e<>!8XL~XIt2j=ln)z0IZF)NG&9o2oVQN0EAzseMe9GF8pg8m87U zwUVi1rj{`^o~cDl1u-?Bsgo^8&19;PsVPj=Fg1>;Vx~qQ#hv??rlJK?nKKAEtOKUv zHTAI*{2ltjTfPIA4qFe{md1)XybW91+)rDYAk-s?xL1e^ z6a<@;p_qmzV9-*TDz_l36eNm*B9+P1PfW!!bqp!4FM~SKQgPoR=a9&$ z)Ni=~~hc}&3WF5cF{@0$jcPCGEF!JUsSFm3!XxRon6&QFyB zzfX4o&+9?;F`hR~`o&+!dAudTo%pl5FtzCV7#r;d&|X2>3Pv+V(V8LQ>ZEtPaZ24U zV9T_ZLA5j#?-D1tf9WuKJXom54As~d`g<>{tdcOSa#7q%y-{4?4=C>45xg+A>3{Yp zpjt7?0v`8dyxj-m0y4IL55_{l*s4zfBd36P9L*+dLg6C_-A8CVpk-xvk*iZ5BG8rk zQ`_NHwv8JgC;icuGN~h}I7(;)&9~V6DV=r(sTQQPY7(9aN1p1glQ6wa(>j`t!o;5W z7YjgGi}Ab5OYv9_w@YuFHrh|BFM6t*47IF`f2vcz(;f={04Peii=mX%;dTznY!;c! zBD1`sxsj&vG|dswIP`E)-53)06x9{UU(RREMe+wL*=i*ZS;-HOR8=mClJR`li%pZt z`Xi+UiTYnJ=aYYFY+x5ld_=H_WU-xPpk!H3mXdX{R;x*L@;iiHDTu1{0zo7mxlFTr z;|p+Xlj$M`c26{28|iunTub9?^kHx{?tZrK8*LAEqbbl}fFNd~;2s(=3)hFg5=+WIhk(b-STrkU0P=hx|6Oy`fUVOYG@Fbx->b@WndYSgu&oS7^qmF3*c za+HbjN6-{SQ-a;J52j0L8c5S@8-?=V7o~H`ZkR())9z9$M^ByU z@)}+0=<-n*OA#&`e7KaEE^Fzsi7rn`7mm^Sb{B^%MWbh&~q ziF6r57hE}>{nggOyU|v^V3SC;a63|3IKcq`mp*s^0a#BgpP`C}L{0i4Q0!8@S;B{` zpn1ild7d-@qrCV`Zt|imoVcKy%gbqDzoe#wAAg<;Y;F^Y^vVipThCEJ4F(I!S zkS{`QEbU-fK}aeg4;zr3b_h?Wga*=)M} znJ%?-dBt*BW_K~ps4UYZl`b3TQe?S|_2DwkbQwXHbh^aT1-og}9_SFqtFE!NH&}J4S|eMk!wzLjHDl{a2JsP6+BQ0U zKZHTF=x?G~RM69S(*1*wazfq{kXF3`t0C?SCflJL&g%%xB(#dqvK&t3w{;#=$(cx& zJ{XLa5Hk?|LMi@~6V^;dg&O%Cy zWvi52!&c!sP!ANNuSswF$u>re1T6e`@^1mj-9hy zFzp*?k5YE-e}#UF2PkUpB+r?%z(o)jq;M)GV>W#IjIGg(h50-1l0CMA{z;6pDcG|* z;{BM0du{6{o=+Qy&;JcgR(%d$#l@ygB`)9$a77Bo87(Lb6FW}5sv}lV(;9$}AikE@ zvjjWdeXYdjc;o$uk30puOX1CSVK=q@273$3cPP8D58sL{b}p+;IA@es36F4~8TMbT zn!&(t^M!wq_;sD2-)!OK%aH4Q;pY;6;4JXVEj(^Zv2&Z~3m-!KJ~nf-g~z@F@WH_5BL(;hZ#HNxsa2estr8`{`yTj#5>9RCHfc?C|?B7p*1-RJ{;NyeM z`bzu(Y(bwh9-bjSq9^e679MjF>bu1kzJT}*#Ba3lay;bw!cQT-mG~5Ie2g#r0OH4= z2mA;N?-KC@`oe#OohPk=_-+<{puo3c3;mq>a+gcX>;e3Km)Slt{%yYS4-(%j#=kdy zoiF@c;&+pOxrLYQpQ!Lyd(K~Fn{GIbUO~TDo(E%0KQ+HCHR^Bkztrx}em{a8A#D@S z>z@aydYS&Reh0ob+5_buDzueP|G(0I2M5{qbNyxf70O>tfAmYEUm)wd#`NR9A;wRt zFZ^iY2XcJQvhb2WLg5kL81MLg!w!_Tj((S#erEmrMR_N`^3mUK(=V9w(a|eayBPD` zZeRFEiC<0pR&RWTFMJyDVH_W8yz!~N@S}-8$$pw;;>`(~10j%rmR~^_t^mA_G+oA( zZHwM0j(ERP9Nl`0p;sD5*FfU1e}6fT2lVz8a=jP}-7JTja5dP~(lnkp4Ogg!F&flp zpDnFk?a9ks0p0u=|3=fzz~}qIPa!^u?UQ2R<#>$og&#nCHQRrLg_qZlKyN&^C%(eo zkygd?rkjPA7GFZ_eVmlMC)!prN&I$!v?#Jf1ZFSqas zVtgig<9Yss5MM}qw1t<~k6>T;pRm)VH4@*~#9P;oh} z_6DX#+Weh6~6Fk#QSr8Ut{6r^&{06el+pP#Lu$uay&%%!uKRzBYv`mx0qzJT~B&UYIvyo^8J7k&!y zwPO5x<70f`2M}LL{t*^l&X0i#kNNS^Jlp)ub;yw);TOpB;O9$Kz0LX2sDF!5f6o88 zHh;FmU+JID^LqQa{<3}*Hvh-H{qLZEF$dYIbN!9$pYm7N50)E3KR5lNO+Vv&4EBZp z=>+iYY@fasUh<#(w^hHNmwVOkpY%)MxIPqgPW#B~$2R3}kMBYHb+BDGn|{W8x6T)S zt|&*Wf4%XEzVIQ$J2*a~z45`m@IM^~zJdMJ*Tfr}rElYruA1UY&d58~cK|o;f9P1z z3yw{f@Q#%L{b3(2kC-m&>5@a2XM~H`EWOL_V(bPbn=bR{5=WO@%O%W*%W%`>YPy8d zWukQ9{rk^&{A z+sIw3fTo@ItNFCYTmXByX~*?8vix-C($(Vo44FsdI9!U$7M|7Jp;TNopw2K<c6wKn?d*151<=Qy3Yr2uV9`2 z=98zy%UTr)?wy9es$&Uv#!$^NILXFdOZOnUKLvM%6Wa>uG@T59X`Nth(^J4~LO3r? zA*7Lz6a#XTH{>cpY6!WBkg`bbfONFkDiR@M`uTgrq@G8$LD7oog;Fqf22ngJ)VXK&->a0_XY!LsP}rR zSxUvE1n^x-mA(m{YP6?1(onG@%#+|Go+0zv3z{I);$Z8128(Lu5@HeSVQeAE9@~$U zHjq(&*I!1BH@gmg=2bt=zRwZa(HqEJK(a;Z?#9H)hhPKsSKqVsCAVN!5q*H@M~PMq zMWQ=ts-@{3nAC;GIC>x>h>W=i$OMJteorh4V}oKyhZ&KkH;UV0I0lg;lN{p&N1Gn>7e1wK)oZ`CdU~3MkWb=8OD&dArvd%$30psL z)b1xFn2_)KdiB$5G&yMc2qtc5PdsXER!-vt_Xr?z9IYp~xi7%ac=Ke@q|sCY6FaUg z!JXG+3^9(M0R5|$Pdd|ER3FY$Mm22M{zFJpL7K@HO_)MTnkPMI`Y5BFrUg4iS`KN> zIL&Cj`qU$uTP+&&WP>u=X&xs{9BE#)Xr5F^8I99}W{oo1X=alqlr&kO;VTEzA7^Ja z>R-CCuZ=c;@89xa!YmF$b(u-T*ek@QlK8qL~(`TwA-CF$3J z-gIw(djp)L`@iVk;)MHWedIuYz0x*ncy|AVkR61)Za^x$A%%og5>f#Or;CkCZ0jsO zW}8b$J|W8mOPl`vH(pVVBqV{58HALH=PUj;R7r=N(Ru+W!|%k_j}}Ik%Z-AAybEq7 z#GjCki&(=(y#SPK?K?h~tv%N`#v8{eIGWA11+hO43R&JmBx~&hvKL8KCLRo>eQi~w z1V60DNp~?_N;Y7SLzz#nI(ikr%bEmvKVG=q>;5~8;MD#A$9jO_#-OW@$e^o?W2JE{ zH;%UKsc1bf%uMQ3ol-^h%>>H2u>pSPO{7THQ4c-b_SaGe#H9? z1O7URH{L@FJRpbqQrw>5g4WYhJ@v6+jS$vvlo~43CZ$FSb+4!ThM}hOH*Ex<`kb7{ zj2zV{;>DvS*s{{%80y*pOgz|kz_mJ4kt0s1cPJHsL7kyg1O|1YQV|%`a8Grxp&Ee! z(8tIz!>B>qwP2@7_T)jNv`_|gqPIB&IW7tlKQ;Sv8V7rg>GL=G1YZlEf5C?r(&=_E z=Z5QpE zG1&RB-pml+C5Lx{KE_6RgwL&Tsec<^nKtW4#$IGBB4Y>`?ej^a9(pmK7d7g&eR*uq zBX@DKYu2CLZoY5W+9>PAZNpW7ncU^z{yR38v=%n?-d=WYmSO_Avg0n77IZy;RSM`~ zPo+JE_9A6Bp2v+oYMU>)Yz5m5K+BODM!&Y};1{d>R1H~=AdC$j6YOJz9e)zLK3XOH zoXU>_BxnHJp-r!H+A2ysce%7P!+~$X>s6u%;@p7}pJT^!@x)y&%|-rN3*Vw^0^fp{ zT5bHCx46rt6_dY6;nR!6&}vU`r+jD(EnF%OCL1ejfBklq4AvX(G;+iBS5#lCTvuxkF~nxQ7DpM!dpKRpIIx<1=6%&DZTe+`8$b8puRkR^49Q?U zP{e^`xc;-sjnwZ`$wYm!Jq`}W8yUwIQGdk2w|6l}#+wDT>s#%;&Hdq?^eCdoV0f67 zVsC$o{UL1uP3IYv`tnb*QipLgp)7YNp^>8gJvjxo>#_EN$hL`)KteP^RO`{ShNkv# znEnbA&z^hi1+andBxD~U_ZS6yqdLi7&s51^{pjsx*S({1BlYPjnW#G#cy*m0nXAd{ z@{UXY9HwyQ@!g$VnSDiTRdP-_XXZi-7=9w7fwzpE)9z#hL$)ctxDmg!w ziI-r0`pnkO#!E1#uw8|hV0w!6whl#WrGHNke~#~xH=>klMJegJKmFx*RR1ap5MPPU zWimcipJuS1I3n4H+1N`GtrbDWZ6U(z9q(GNQwxkL7#6NXBo$-#xdGBjxmlSjN?$_IM_H|Y8?9- z$6m&K|q$>C_@z|kMd0H__RmR z-Zl>Q1fTXm+AC-eKgZqz{*%~p(rOr=)2ICa?S41G-u|0WPqs&rcYD+j*E$xs28B~? zQd(Bb>s-kD*2pPg4oY7EFWJ+X^xr`LVsC%mg}L`x&f>Ysc;b_ZPx8idzK%R(yY6!i z4j^75KJ*;CI^lV}YQ+YaHlFR}P&l){c#+vndlJV+%Nf-k%Ae(Iq1{RUI@6ALw7Ir; z$g`Tbn2Equ0>_XaC4`q4KmDF{xEM2um%f=)1<-La9bI(13yyr>6N}5(UFsUyrpF5& zEF=B&k%9+FeCf^3!vXy3C*V25j=cmtWo6<)!2XYI*GO)p0r(MsvX2_*(nOcmUu|Qa zH-xb-(_^51_g0(}JUznn z7Dmowtp4^IBX@!RSv2mdnVYVEsFL}5OzCC&O*6&5hTa z(B&9$yU|nPq4)fM8C8*w#HT40r!RI7#~G^e4EwhaY{4>olzJ97=i0z&DCja2!~*u@ z*bC_Rr%`}p)D6{Oe9;GE4H-M8g0bNgCxuj={(rllCu*_&!UE0+{GO?vZTDpkqRD}; zoLUx>99%?! z`v>eRY3T&^wt#Q@0KP+D41r(##9E3VHratj5Pt^dE?9y7cCVaGpNZjY z8o)MscOQqkNbaw}h2Y?~`LS7d>J6i`_^P$_p?dl*+XP*Vf_K14cJRw|chLQVALV8-o~FF6 z+|``QAzVyk^DRJb0g^S`Jl&ksAA9i>v)0y+*L$<6&xQKn|*ccR8p;aw(FkloF>L3wOiQoImd*O#*4|F=@;hRNRkb;!Tqz zG2O)(ad5i?VNEbpW3KAlYb(l_{TyUZj|cleu#;}@-6q{{nyi-Lzte|*-Fxtlp?~vn zj`Ifn(DOWp4(NmbjEOEjQy){0ySp;cXV)qJd%%Pr z(Guy?b#x2Te-KB9{tb>x!$gH|HzHImIBf@dF$^)4mT+7^8N>ix3~(F+EUV_c@QjG9 zML+V`FI+Z1$TJwf|D&pl=+~kQMOsoQXO08deUi(dcahT0#DVndcGkK{pCe*x(x)58 z$;NS2iP`<~4%WLy%UeO)^?ceE^ zJQHqvfAEZ!@wVXiz-{q1!(lZYYG=Tq(%Zo&K92Y(#>Kb9?9GAoe7jza&J|NexPFJd zX?RQ4m#*U(+i>A()|V6LN$g5#&5XmTcuhO!tOK;S(7FA4qg*b%{q6PP%BhApf8rVx zP6cW5F_?A4Z6mHq;g+V0{jqhg8tsbeOl>f#6QDoIq?*dOK%7Jd=WH&I1T;V|R}b;70xIUY?@O`a9x?UxpG#{4H;B4A-B$flsnr`eWi4puZ&Y z$LlK)2Y=D~z6to93rsb!3GR=!d5r{)+o$)S#0HkQ^E*y1?fU9HW@Yv>sVc+fFCcmg z(Hnu5Eyn2lg^#};Zg*&cLku0l=fELZId~8T)4qYN6Q%6D5T}=XhUoG8;G!0IzaSs6 zsX#RFw!Oo!>F2Nf%>Kg!S4xRo1vN&U`t+0j&d89#3|aqxzEf4{xjS@)c5AGFiGY64gRH6W*n1JWXHYH7nkS?#d^-Tfcjp zc^_JCXE*LcHmTh`~U=jNrN8hqFhOyuA#cqbnix9j&fuhyW z`}ntP)fisMUxb&Dtg;hun*u(YNiZ!3sXx=ZnBK3zo99AusyU9(uN${|oj~l!g>*`# z(|vH_uP$NIU80bDTOeFNw4K*iUe5I^MKG(`wf*hE7}u{r2BS6s&L?#gsjntA#wV6) z0gBq**+;OUqzxqUXI(~qD%xDC9ou{gm1)x-*=3yA;d*rdp67DOmak99r4_f?{2HP@ zbELQxUsGQ}Em~<+)L!W=oYvIWQ0plv*3|PoO?`>7HB-w_S}V1?mBw|q9={yrsn~gm z8_d`{5)u0Z#;#0U2A)UL0h+F|o9bXXhCLvymZtMzQs+L8CIe^R-Gp__2du?yz)U+! z*g|`266|&7*x9@5Xb+~nO4*G)ymkNZ8VtOw%q2XL#VuEGtS9r?+aYxvg~1#Hms!a^ zNUDHJa^xDu2@-Qe_aLLj00tS1#%R=-#!GJ4G^)1#Yu)pGVRxB|(<*0(Q;J zQvM1>D`ec;zwvBMTYIwE^M#kX|EJe##=Pp2#0OdpEufDWF zIAL8%NE{)f1;nj)x3lnSd@;nb#&wu2dO1|d5LdC=f}z~H^j4rMSmnY2kv<$Z%@^!q$i^=>VXz+V9dSflgn4C0jht4rUFWBP5KF zT?Qn<8?ufNe?qDZ$Z&5+3L&j`0CKMZxxgE86Crhk+-5+&Icf`>v0P5bCPHpBAiKRG z9oQ(+3JD1`Ae+4*pAeEr$njQL>HEAPFB1|@$Oi`Guy?o*5fVViivn^$uf{5hBPZMr z<+?bPQ1=2riv-lI-z%VQeXbqK!8?Y~-Gt6HSZ5oo!|XA#7cT--_M#u1s_5i0_>b7Z zUx&d1sMVnP}S8ELTW{I@MWvi!IM zkS&Dt0fh5C?>{=8v;AHK`(+cu9J4 z9ne5Lua|*(e7)^eD7JqJ9UAFyuW%?uJe78S#xtJ$YL#+5JyMh5F&!Qv{)e#O!#dhg zZX<7mpC6%7gt`Q@N`GHK%k@uiRCD^Yb$}kiW|6GIhe&Ay>2&NU@-Pzo?eXxUTSKsl z=PBaLiGNez8}+7-ZSAuU_|>SE1-O_;z7I1Cb;O>vnnk)Fh?x>nxSan^zUf#D2?L- z`_Y1=MGv==uwS;&uab11E8x|o~T+jowS8;DuolDcXp)PhG_-B zaVB^Y!4(AGDZq{Td;hTA|5XD#$OI1{IEUa71k0yVFLqjuRgy0kt!>yglEHj|lom&q zv;Ve5%ue1zQz%Ve!lc@tOTps#=DHTE)$Pw3_eb)E=mn+X_663z7^-nYbjRxl%`R7u zL+)fjN$Du)9>#zIhIkZ^WMjk)*i=u(-aZ%u$QVJ!P%s*|N8QoN`~uq>H#1Az9)0+l zEgI&a+Kt#Fl5O)2Qks)2Uwm$B8_pvy($uyDradqj3#m1BHe<{90h6teE)8_45H7p{ z(P!9QjBhT?G+n09WeZ(Wgp0Try4>z!+yD(Eu!z7&3wYvHTjdPkkJxm0*aNUyo_@}pVbt|^?+pOeKB-M1Iw)DTi{+4;W z`Uw=Rn%u{m$z7v=kOpq~C6lKGk?6HbJCV_Aj|(E>Msfp*){&^1L}mOAg#Liw+QM$X zRd9)9oRy5Wk~dh%YptZqN)E7+7a(a?t4a>y-XfZ2`SWjQvDc&}Gn&f~4KGN0=9(uk zZcID==5;T^i~U|Yji=LBho#fQ9!|S_IaSaph)%U|!dBOVIjDJp`!NMBqplbJhFeLI zO8qWAhL$YZ$Fb&|7N6lJKX&6DKuf5zHXawI~=7y&g$?U zSlso#8D(hvj({FNNieLb-$(5!rL|LAvk+A3^2Zr>E(k>ku2pI*4IbSOXSx#avNlRD?h*LrMd;^o}$ttgg;23zD@LIx;9#V|P zY4zw<^9(CNQU#(;t5SHH3xxYf6HJ;XOd1s)?r+7H$*0&!jPIY{OcHU)98U)AZZIT) z!Eov4!==CJ(u*z?bO{kI;#T+HwYE@e<*Cy0vMS{uQd$mOPBgI;;Zozn zpoje=c7L>V+MVavxt=*ddmZiVpBe>my;XUyZKx4fLtGni{4S(NK=`|lKcfvolC7~_ z(u5p%t$>&8&rJFUErWkC{LK(~^39^Dk)~yK6G!h2G@YbrHcVxh$A0>Q&6^{(KOu2h zfLt#iZTd%c2=5ZwYXNZ)!nefCvRS|79WO9?s7#?Y%zUy=MwH2_2>T zOQZctJJwHWD=NIuQ82W$y>q31>3i;k#>1VZ6PE_fbN7@Xm7XrT|3XLp(bE2<1?~85 z*7|9Fr9GAgt@khOu|C#+&tyNcb&hf${0pxbbKD=`C}UW=+gWrUxTlof>@Nzrva}sh zm0nb|3c1&pb}KzjwSl($ zKPl||+sESzB>FW&JB-Uz>3|j>jPmv&*+qH%WqD11HtN$%Zc!dNWO<~pmsdKV133nN zE0SICzjC!`uR_Itl3aqH9Fm_Dp8U1QG59wj*#-X`$seTnYse+|$szek;mO~C9D{!w zl3nosh@X_i^+|ioXrJBW68z+l{G{;YkNMu@4@a^K{zoK#lH!j7T=J7c@{_`oe*tog z_+ydmf`63c?|9URKZ#r-esV~DQh4$QBFEr&AlU`~$M{uAv`?ktcalr+lSA^8!jnG? zIR<|al3noUN&ZO1A4)F4PY%gX3Qztm$T9fKk?exMzvOSKFxsbzT!Nn*lAjcw{5z0i z@K+<*1^+AfwMw*4q2kxbCHTo9`AOl)pN|}aKN-m`_~%IeAjO|UF2PR@$xjMT{td`6 z_zRKjg8xVSnk2{nBS!lalS}ZEL-Lct&cD458Tt+V)qJ!)hx5}Pf|Xu6VEhmBRr#Sv zc2RzwEI(3}9|^cDpB%D$QrOEc9gv6|qkd6HcER6Y@;5zf)GvWtqJHF%{G{;Y4?vE= z-|>By{IB3gD%t;v-{0gXhvX-PCx5WT??keT_~%IeAjR)8`N<*qN#V)A1vy6iSm`I{ax+9$~5Cx_%Gg(v?3lxVb1UDxryf?uWN z_*eXmj8(J`IV3+RJo(#@WAHa2*+u+wB!7_Ncaux-lSA^8!jnH0H8S`UknDp0NBqhp z$N!&<_DN=22!3)%eo}byuSSl+pN?b~{EtZfB*kAyF2PR@$xjMT{s`n4{4ONB;2$OV zJIajs!^tK1$szek;mIF|9D_d+$u9Um#;;7GeJT}yEV%?fIV3+RJo$Gc$KbC;vJ3t^ z$seis>&PYe$szek;mO~O9D~0B$u9W&Oa7(}M*B38OYoCJ@{_`ozXCZ1e-V;h@V|mz zq2%~i{N>~l{N#}Qr10dgL5{&+iDVc2b0mL|;;$x`;3tRVCxs_}*m09T2+1z^f5Z<+ za{QMX?Gp;PgqPEE998{`Sdf@h)~ zxsV4SPe5LV?1p>jzRgjk;Z$S=1zJ@puS0E%9asy-%BoVS0 z!Vk`xqKhECApQ{M{WN2UIIsRbz~TG`au~7;@*yP3>2M}P_@4_>2Wf#6L8>58ePM?< zATCH9qyt$Po@p68wK-|GSljULjBf0fzcVej6pN007)J$m-^ z!{dQ&_ZlET9DaR!_8UAR`n>+LQqI3>dEm%38#nu3J!xzGfZ6-ogGVjQeW2F`7he)| z>183;3<(`NEMoKxH%5*bJ2_^`&9}r(oi-d^o*r>`2{Oh7OuKy z?Yam5@WnP;D?e*T4*U)lERYp-kD-*{`+?zi9B)3Ep5 zk3K%|$-z&X4t;j?i!WQh`uZEU{_XJ-Kc4*Q)aj0&e_^2AyLI>T>*04kWAD~|C9@EC zU%#G%N1WF$de-?V%llt7a*coBq>Y=m*7v%4)a>>F3v>5haB*j9&tMyl?}t3wU925y z&IOQsNCl)0;@mgP83sv$!gCs$UAsVC=68I6gAW4uy zNG+rpat7l1c$hO5k_^d*)IfGX90!IuV<0(@O_1G?7D&J+h#4{-k_btKY=G>BI1UbT zhC>n|t09$;I!G(z48-**%7P?7Hb5F6Zb%0ts0lGbk|6nza>xOQ^ALO>t0Co(YDgob z12XI^v^~?uw3!n>qQe$+2^1O!o~k`4<)}UYwQ- z`mFri>`d1(6a(ATtQ9Gl8L7x#mXn>8mX+_C8iUeZ8CkA5Gw}wYY0u5hapk5hFG$PF zhnpj2aw2@v7B9|NltHiT0?1-lZc5e?(h7UtqLj?ERM*1H>_vCG@-psWwF<$Vm7VX( zE6B;o&dpC_Jtv!GXJn$?OtGh<zpr z4vSM3QJ9yX zl5d<3qV>&6z>-_ADBm0@RzKup)ZCpXM;!a4;M_hbV4ujCS7hYo7o=pmQgU-sR=H9Z zEkbL-CeN0fl)OB2$vJV!{=*Q>%tYT7oKu()Jg^cb#PsvT{#(rX_**vvVG+|#Y&MQAvX>4U;&yXEi08Xtj#<*C5z$bW75qNv8JL^(Y(tF zGV?Pq!dwNoP{3t*K}uGB#yy-o)$}OF(j42FoSL1MC%RIwEz1zY*u{y(I)~+W^I+pu z#I*<=##w)ckD)zVUNSJy7pKX3tW3#sWupKNe#`_M>Fn8jGz#h)jebnWB$ctqn8-0m z!$%gn=*7y4c^$)PQp%#c#kB#GX`1I4bf`X&-SImFC`-&ItRiNTw3KB$lk!tCvRIJp zDPU%u+jhT8$oi+q^Ml$TP?TfimZ$rQK~zbC|cz zwaa-=&V%Oyes{WZMCV}Hv&cAYd6HxOmW#87O9ynWm>;n&N@JtiuM4uNT^DrP6Lugt({&2?37%tjS=`loJwpPaXOL^pXk)=g=wzngoF_h#t;~* z7IEStyErptNuD@EBjkx1Q5Ys?S1>M9*WbIdvR7u2CEOr!g>qt=cJtJmhlUx;MXWhc z-rOt`YnCX%A`%aD4A-j&&YJ!b#X45b7h}zN!@#L2&JJ=IHjgPw0&rq`tq%?CY%J$7 zN4chQ{fSk92>j;UG>iydq%pClVs1ulW-jE^cuuxs3a&~s7rVsJVH>-QPspfLR~O=7 zbJ-iw-V@hhro=irl^01YIOI)(Y<|bBDY;n~B4aT!3zjX+!bxddRK<1Lyo!l?2XXnb z^@u1ltuWuX_{!4+Ox6VA*?+8xn7h$@Tz+|%$@*d)uqZ7v6XQ6W_i*x_L3Wx4+1xC- z#6b&sfIQkPqQDjM`=YKzyzF7VLOc`j&oJ@7yd+>EFgoAD$QvHaQJJ_KLFsUlS>iM? zt}pV$j>clzvjVuK;G&1iVzGD-%Ld2nIf-)puq->9YwabT*I(IYS=m__T3M+nxwxZI zH$UPAPFw@#h+&73gGJdgHGhxg#FLNP5vQC0q_r3pwyblh03 za4i=A$&H1NF)GcnxZok!^U~>qFLe=biBkBl7}Mf*DaJ8u^M7ee1cb7q{?vX-jxl$Z_MN zJl0Lk`=VmzTv%XSXvBcZOY~1lexG|+#*{yKLb}47KH0>7wZ{u@5@aBV?o2sr?@#&*c9fco5S4=Oha25^mL#5O;JK2cJERAM&q(;ZfP4Nf$fXcI zAK>#7KS)mqpO=7EJQEm=hVU5*pO^4y@g>LIPx`yyvL1woTzcZ zaqyq0(|@-<-sgnVzwomE|3NHcD>A=`;{W z^sXQKj{R=08~cpo#063HVqdX+SU1MYIx%*(4cme7vu^x&$KxFf$DutAjy-az7&zWk zo3VV3F*TMLulm@_v6sOytN1xaIljqFE_EItDdMCbvHXyaX|@?-WL+mh?uT?z0O$mu z6M#+tIsxbepp$^8x09ZlGikabYU;?Rud43*cGBSgbtZ3N`rAo6r}PfLFX*W`XY!(# zB`$nw&MVQ;!~0z_Y5KzS#D(`IO`1M<+#8|00=@mGj@&urmFU6arjC4I$c>k`T=?`= zy~Cr2zY+TMRX1L~v)`Y3RrkFwsNW^K0;~JBT==J6|K_QTPy56lQew9zj5sy%-R$^{ zFMV@z;tPEuG9s|NIrE&PaqD>q{z}n>I$FL`F6GvTmd%(W&XL{@!^<$q8Cw3M^)#hx7 z+p&7>GX*-zc&-w@g1 zw>#ow@At<2dj6gpPZ!5(h3jIr<(E!>^MC#Eme*H?x`Ud6TLTYVd+hSVL%zA>)9Uof zq%Elxi7(#$m)oCP^5Fu-W~hPdGFkCs@L8z zKlgll^iL(z-ni!vH@~)G{nYKN9-Q)O!LV;H`|O&pFFrU_zw}VZR|7tIVd)dMJ-hg^ zdCzA&KL44tN9S@3^22e-Pv`wb9*(0!TKfm7ofjyggTyoxL-7Y=0T*_2Jk;m@+k%}T6R+ueB5X*%)vnO~+bNd48iV>(L|P@~G}N4BXl+@`{*lW3K$kF>cW7j`6M% z$4!IN9TTsb;c#6&&M~-GnB$p{qqjv}6Bipj{_i``w-}$uEA^RV&~edVoFpT8`2+KfwLrw0d4i`&$9TKwI8rq7slVf@V3 zP=3?}jk883CCwffKYz}jCf}BLWZdm@zmHfj@1^VRxb+EeTpZFgKWFY;w>=-1eEXr8 zlm%DawCIlD$VGQ<8+pgPORoEOa`n8ll$&QRUij55OBQ_?ot`>j{GvPVyfI_(h}lb* z^ohGWeay{E7Tp=GFC8*3^X_jFmMwX3de*W(&&|GjX2SQ`&f9X9T{X8o``G;D%dfcY zKxxUuAN^jPc<0)-i3JmeL^)iJm;pcRy6Hga1;`(byyq~76~*xU;klCr*$YX9@Kbqm zm{XlwJgRG_Fxvj9w&9p<_hDMe@8Oh>!f7@>=BaX(ojTKQ8;xC{4jYbrk__R;jw4^8tz7aILHM!b zm=3k!$X5j6$BrXkD9UC0Y8<$bPJj@{d^PUVec;#!-na%Ej9mh1sTP)&Jpam-h^NVJO|bcKsDY{W5N;bMVP{j2Ih8*%n}BmqY*#g~ku_^{$+gSwsM)T%GHedfWGWU7lfZQ2E6Vmdy!4)4y1$p+%S*q&OYiNa2YBfh zdg&K=>3zI(rTiy&gc1i4u0mp~`ea}y2OOH%`uKI6}kG|$IJ>l8i zvI;jPB~2t5m9!|8A|mZQH6$aEz2hyJW$TU12npFTGLumx}E1*Liw*(DdWarudod?IQ8MjfB0egk3|zt|?(} zCt~*i9ttrV{q<680Vv_MQ@UGYNYy3A?$3 zy|;vYpoHC4!tMacj_LALYUVNZooWNqPH=yUJ?;ks`M5vB${5BSx#b}FX@PN1emK<1 zK9X(XvXSJR_%r?;&A0Xq46vY2^L`2anFX#!Lt_$R`Wn@~Wtn3BQ~N~_07@*4vAiFCd1bhK{ z7YkrpmyDIQ?ZDKjGo~Lqe(I!jBYC+2HuiSY(q_#pI&tQ-l5!K(L4#d}%$>Jr;rZgr zmlPCL8ap^TJI$W6VE);27cZzaRd3~)(q-miT8 zsFPL~9shuk;Po4}Y<}?YNmW;UBg62BnCQQ^?ack>dG#w@J%etcVNsD=b9QWh`t0Qk zW0RgeV#g*X?Ao2T@AaGaHKyHrnZ?B?joY*L!2Y-IK7O$1W7&Vg#3?C<4j(Q2^7ZEr z^WOdXj!&LEDgWS+f={2nf1~&l4-{_-o8n7hQamXviXVkR@gmw3AEHU|AX=Wzt`069 zE|ij@GEHeM4(28MkBaucarZ|zQc}{=*po)OHW|uNEPVl)Jh(?9L;Sh8dvZXG(KD(a zR5z#&Q2n7gLRT6v1(*mV0r5Z#5CMb$0e}xM3h)Hn0ZJ8Aet|t;17ISJ`OZe);vh7b z?@{_Ny8v212Y|j0(RZTe0M$pTmpl)|6JKBHTMm8Op>I$0t*9f=8PEgh+ZcVj>j}{J zyMBN*U<)_`&VU;*3>XP`1Aagd5C%j6V}V2<8JG-A1^7z}H*P`_O zoj-CXdGXzNdCeMqcoqtY#nL-Pbo=JiaL)<-o z&%1>;(M93VMepdIXcG+r<*#HM@JMu#d!A1+d4EJh(oXdG{2;n?@%->Kczb=OxEt0t z`=6fEMSkew?R+|rNzZuyWEa2q=k$!fCt7@5c$4RyHz^L{;QjM7c$23kY3H94eWFRU z$fS0W$_s(oNlJf$`2D|q4{!fxbcr^_iH{d=^6`?i^UwMCQe1gA^o-(9@uawsNpgkn zE8tdCK8X&2zlaXmDcvZIh^8c6qWPz1d>+6lBj<=Go*vQX^M>b>=Z|QUOr$;w^=Bk` zC%=50=^e$1-0>IB7r7&dU-XXW3++msi+4{Zxf6#t4e@*44e`TY{4>e0={>!B4e;qe z&*-9O;{jKI)^HdDxAOC)4{88id|9Tr5ijC#sV_b}k7UwC zbSS_1Izu%6Egj;!GeF_cJ@H0#n{z)6a8ExaiC^8-h`-uEqRyp>RTSFz@pS)NdPH2A z`|&h+UbWC#)9+WV>OQH%AZJlQYuyb$o@OWHqWG^ag zq`de~JWRT8=#oK=Alf`#aT;{rR^s<>>B^!8Q+_o>w+(tWzxy@BuK{{JM3>Ji@id@& z$#NkXpN8ntb75*{CXM;Llce=)ZqC#W{55I=!ia!^o z_Nx^<_iykshdlY*1^y~eHU#CkK_FqZ=$|lHvYR?ozc= zDNL;B_{PPKcilVkm=h@^9iuZ7Q{AJgA+ci%I}J<4Xc{Cg?fuj@nZGo=my|^3l&)eyq&k=Dx`FQYt8}h^Rz?(c> zo^PHe`KNT_pOZ-!nK&?mNl&tqfBqu(bdg=$op_(LA^ylcg-sXF8=1UcdQaf_CH{Cn zWRhFD`1IsWdd6~9_dm}EPnX_Oym;XBnx7=C#NF{>^869Md^(dmx~GfY(>;M`P#C;B zGI_pvH#{BQADl30!TX{9w5_Y*#mAX<$J6HdB9qdO_fK}B zK^LDNWb%DwK3u+Bio2mO={+9?-Sh7GaCkepCBJ0n!=^C!xbkttqdNIaZpkkn2HANU z;?Kwpz2oDM%xh3$ld7AW$_fPNmwBp^9f4X=#%l)8)e?JNe_wFoi=GPgmSz z->`L!Xwf_VB0GWV7=O__s%v!7Jzcz=p7H+4pX5dE=oueAf6trzd!j=ZPnS&o9l7N% zqC?^E>BIBOzvtu4+r>?uPw{7TPtV<1^$Xa49}tR7f?-gZK*}yUQtNF?x;|*rJSq5~ z?S!nZ2Id{-k5T$T4~9iETc)u$mQ=7{<2=+Ruz9o!jNd18X6nY_|yiw0|RJ7 z;5ck|r)~Av_6UU;vEe@PK?#YmK6nckal+ulXmFPqLT5lg0&&*>9oo!C zWC9bTVtpva0ktvyg$A1+6c5S_XB!W0gCM0Vr?Vo#FM*bg`M0_F+Sl0r;ywy~LadvAr54g;C+bswbj?hy09WHf%SX=HfJ%9qdp7 z6gFNM9}1l#kwN5-u0MxQeo32eTH&5MNQHO=}KR}2L?zDLp{`ozrtd=9H`(PcLsbeA;9TM@v zTAfO)6Vz+eAu6*_MHL+$8x&#~O1fz}2Qo>;hRH|+D)izTg$Hx(EgDaAg0L6Q0dn^aCZy9{@ger zOz}iPUU`P{DwHT1Ha4z4ZbLlWJx20LhXjZx#UE}q1Brl}4PUU4I?Tr8Zenc5C;Izi zdw;x87Yb`AhEOvGiHp)2BXn^c0un!c}4X_?E(4BE(D0GKnksxSGBke+U(}2r6 zWCN-5VMKAgG=vCI7#|T9%lJoPCm0H8?8UZ8)GkpQY(ta+(Wi-vBF1>RS)0xjZAM%sQc5KXb)kojQE3MClc=Wt$wCsAA|g}_%zF0h z-V@rq;E__MuDrH!X;_xqxbWhpHXlW8fasl2m((ECawsZ-OlXqfktAak82n1JR=m+W zy7>5uXma7O85oBmRGWD9ae(Y#NY#zAtB7}cDbn+Y$5d#4<;!NMeSo}Mlh z1!z(U(vu)f?EWw4Q~$i)5G3>HclpP^v%uIOAOam3ZiEpEb)t|05CKp(GA;}XiXxMt znS-=?psPb^Mv|3xty`NRdhA%H-t?m?DRgz^!~C`Uy1R(KCWX7 z0qV|N-N82BO`<5E*9n!o5)t5es+BCY+>z&Q!jQ0WB)b!1DbaELAB4k}96g5HIsw)# zk3;Q;h}CD3$dWRXN*KAKMm8xFMG%RH@hFWaW1>+E`F8WyGDiJ%%mc9M9Vy9U(Ya^( z=`=Xt^=`5yJsvNiE|B^Q(7^<~lEKVS6Y0b1d_vh^%4@i3MBTEE;Mwx=YxtZhv5~96%<8x?rvxjtOtE* z0Z;=+Eh#D}GZA1Y97+z7FnXjhOKtWuK3Ez3YkoJ(uZ5E15IYx)iW=Ym;ra(bhchF- z*;>R-NN~(ki1mfnaJlD`#jK}^aSxOFQl*Fa|3#|&D?b0jK_z>VpG>y?Hp%qp``fpX-4BFKd~==-I(tclnGp-vJOC$o+V+fhMVbR7;_2= z#%DvmKSt4)^r(xmD85Pgj5o%>n~_WS>ce~sAg8PxU|7%{fznNGC{6ySbX{r*4~zYG z+$R5#+mW?Ikw5=Kx?;L zzcBtkreDiAlPai_bfnOD(dTQ7I_NWgZS%{PTgYqCS8yRSp*N~?ptoTXUy3<8$^VaZ z=ECI2` zkflP;1NlKTh3fSaplgV< z(-X3Bfgil4=n?lEKOxi;tBsE$J|YIi5)I5zM|BGV5hfiJg>f-q@u6YCG`YyfeKOrB z3K@et=n37^0C$zdn z!U0c*J#z}WsyX^dTGCHX8HlsLVh~TF$LIiOqM<1CKx2gxjzfNUmMEM2nc|FB-1H_| z9CAlRpN~G1exf->dc&Sr;v*IeIOW!>@Bz~kkps3JrqrvGUcoq@f{ur%C%F(ErjfzH z3XJ$>(;wf|z!jd+S1cxT;Erl29#I8T5{w#XJKS415KC0hyJ1@-ejyEp1auA*Q)Ia_ zEW)C}0`s7AypRh|6r6ybkvQunWTYBX7Vr#pgNi>}lsd<=m4Q7Ijja)#BF6h0MoCSJIY4~b?gLB0Jmu^tk2CjaCHmDh;UOR^8cWWDx!5eqW)20EWWuw!m^)csW{Or`|s!X=o}|1W0c64#llQ&6ze~pIW&b^ zS*67CLme<#+sCNlHa$AdVa3Xfho*G@4jOK9aBX4-vFxP6#u zXdi}tZE<0_rq9+4PxbnZiBI@fo)OoJ7w9@^DG+2^V-3P76bfC#7wa@p zi%m`lF6q=nEz~qNT&UedEiN!LY?mfXEDqe&wTW6lK&-#81K9&&W4pk;UsOQ0UK6$8 zpum7^Jhx%zvbh5b{9~|yifL8E*YcQ->26Aq8GvsfY=49M_(sl|Z`I_7T_aF$nsU_Z z_|**y4UA*`P@WEQH5EEK3>+#1O$(;FFi3{^b2_^}i-w(}FZ+Bh-M$Cwgvp{Sw+ zI$OI^k}&n(g+3~gu;HIlfZR!Z&2iYY+f;Y%Kt>_Z1O%$tp7`Nifbr2nsgf(DP z5y>6NMVjqn&z7S~7nO)PI84#86#;Rl6yZfL6@Dhtoa~{K*#^0aQ5eA0a-v<=jk_om z_LvbgkT|4{6}4!;D5X&ynZU$Zh(~LN?%p4Gu)`^@^>Xp6%wWVR;~u;cn@rfhgc}^z zP}KRkj38#2Wm26*fg~WfX%cYEP#4X8{MkJc2Fb^sm`Zhl#$EiuD@gTUB!-wXWQDr;w1Z;EmT|H3mt0(&*=N7_HR6xW zVQG+r2t-ju=Q0WtPc))qmKE5buP5pkBAWCPWilZtEPyFo16e0LoAVOScm6}Pm}9n_)K3?^3Un2idco1;>J(Gxcw(aWG%LpP z&hT0rKc=(DMTd1jiNog~*WE!05tRb;szqO**b*0;^i%nNiSX@=D)4!%RgGww-wlm+5;Rq6$-D<&PDU-%^{Lso;rkMZU6D0@niiE}2 z5n9qw+uDc~KSu6Hqj7*RW}0!P*MR!M@28+VtT!#`yT2c^po>{4!?tVat|Rp@9nA1e zJlF8xHk--g^V4r<9YIR4^WDe6Si$d2YP>ZM5%g`cEm z9YVHHlCfuG*Dhffcv=q~;yA?KLWoIVh|x&o8|pTa5d$zvw>s~m;{7Gxdobw}7(-%( zx(bYFp(c@8$}c*B7K^g^)zq})fo4t^u|v&@cwdK?R9XT>~ERks?wsOY`!=+0K98)Ew@dG@sWpo=HNY^`QI zcgt@-Y?xIrUBiQ{nDKx|qSfV(?hiMudTnX9|K0cN<3C$=F;UpA=_PN~&MUA_#pRY( zdPH!mj@3qxE8SqmhLde))qx1E9nR8O9n3xl6aQ;^JHCvLI`yNZ=EdOhIY`zJ&_^4VX z6=tumRbwVd+RBKFeke?%t#9HArNZYIX0Ho|7>~LWLN*nD`u7j341LcmptIg zH5(f9Ux@!=Aot=Rzv3V|;vkyhV77@tS_l(D5`4I^I@|csK!}D1Xb(tG)XEPD*Ywh$ zKibo1>O~0q^%ELn&j-FLNk|{`jcH4ogzsO%A}ai}Iu|bMuU@Gi7ldX0bX*)Yfh4N1 zA&6&JU?s4U5ekITse)7mHGxQ-KP8|g+o!M)|03s#P83b0BBpiP80IK&=5#vImseX? z2QkOL(5m~I$O))1!&E7|CkB0%7%V7CP@5o2TIy-2)MvmVQI=lq%fam;_3 z2V}?k)cpQm(DkK_stT@vnxKV3yr7wU2i(U3#+dv*CQy?{GAZ~1LfErmlKWJ^3ikVW zkKMBhBLHadQCuu&F5d_D(3GQK4tt59sXR3KD1-vKuIx6x9~$Kp5`Z3fe-{3sDM@)5GiH~TF66lox&sl znuZi_AwJMXrw|ErgFPQ+V_-hu1p6oWZ-o1yKr@8D0pV-mJ`OO&`;!PC+L{#nfljb* zgeeV70|vnU2>y|P3SIzCOH%v`;oIPT0$>6Ab%YO1cnaY_SJ?N#r1YE%41&D|{;@Mw zVK~rIV1=kOm+y}Iaex`#UqJZKqNflH=)k@mCZ+dGzz+5o@Q>Z-3S$6hQc_%v@B?t4 z0`!OdF2aX)C531J6L*RQFjawtz!2EK3E2FHHa&%=h<_TF|InVNV1oBWpilhz0Ucpq z4^s-53RuJb0Pl$(XyH?61N#y#|DknHp*QSTx%>}<9lJ;r_rN56=KzkdzlDFwPiXQ} zP#35vNK3K#56yiFJ@NiLm;XVqcZU6Mn3P^K09)Aqfq%+>XaH1b2m4Ac|Do|u0iSjh zZ*%z%jerUUupfd+jnrgwm878?;18iWg zf`7{YQ2^3eF@wwhiLm#9{U(?H5wN3NEAEF$Q*>1bZP&Do=|57ubJr`QK3e zKMwko|Gt0_?$^N-0I7f#?3H*=`9A_^4SPD5|Knjdhy4nd|Dmw!!oC|O<=1S$0rofW zPx;?a{XfU$e<0jw!+j1+az7my2>UbmCwij+P1sj(`9BHvzOa{Z`5y^;H`outYz)i? zoM8V9|CFB%)&Emm{`|J5c zgGuQ*7Z?Qld-$jPZ>auXIJrGTk`HS7=Zp7*4)gn8fcKz!CO$@K5>KQ2j6F@;?Y}I>Y@on3P^K09)9f!$0M}H_#6DRb2j0hP@x` zcewnIg53c2!!T8V1%NZ`U*VtfzoGhnhRgo|xY2_9EilP_8ejwa6Zoh69|dT@zMRYd ziLm#9y_C!U2-x*uKLAr1mX3%m%028ftxOHzY`{fHw&0J^A{d z#pOR=|0}rskAWK_xIYTB39txof&HgIO;$?KN>)m$xolH`hOCrYQ(0L-8(AqCby;gc zJ6S0!HQ7dj*0NI4Eo3_iG-aiP&14k?ZDpktTFOopSb=plS!wv63jb}$f9s~Q^5kDm zUDl8M`>M&xkpD(4WKGDwaWh#J^53|n>~YpVH2pOrkpe9piqOQNB#?z}C(_y02zsTY zq5DvZ(XUv$OoN*oXSRXRdd`UGm?U>R z{#XPXX~eNdYr{nE0B+>EvCyGjJbY)Y&T>0;1>C@dLFo3 zBY*sJE{38v0zrncd{Q?*)mMky6j!u48704{COo$1rhsP~mIbagoqb1jWB%Rb_RntI zpIvr!xxUkW#Uqn;r^p-RKS^(Qba9~Cfp%|&yTTpD9(-4BT{wO6_1kTqKe`v?mUq48 z%#3Sk!!skBAKMxcIN`JZ_ZR1a=DLiQYEc#`7ZA{|$(Q#k3JcB(qx+0e3v+s8?Rz6` zY{>d6j~ey0zb-TQ`wW$<5qV0RzHH6w8JW3fz|C`q?^t~<*#0o`mTBVX3fs#nH}8(@ zcV*jl<1!r!LAhJ1Tj|-BekDiqYW8*1I=OfFie-l`H`#O~e{H_BuEK0tpFL%bPisF@ z-aTtlj8Rjk&=K3(`5o_P5WIh}_1$rDWA8{62(M;#Rl89=XU6Wa9rE_eZF+PxtNZo* zr|ZwjkMHqW&}89O#f;XOs+EUT!lxMYi&9t~8JI3LI-sh?Eh56-FH-ZCanOt*0{^!! zm&rv=+$5!OyhdS~=gB7TPnYcqa(#B7*+2P(^Crzc_^qPdJ%2}o+v@KoU7H`|bp7iH zzdg>E-100E1O*!&7$3fFy{TeQ>9Sk>qE24f__gNdweV+QHs8vkd)Unm*-?`3dpq7h zX5iy?jk^0dDgAwJlFGflV`W|cwwCUqrlwptQ`q=i=e$tQy)$Bjir0e=WVy-t}WyY_7@J=3b+-jP#P_8ImWedNH7$V113Y56br?>)M*@q_)1R$kqm(A)mT zKRc7Iu2I*yBa_zhZhSN4fQQrj1pd`OJW6G&SNH_w%c_so{8U`pC0C%dd#(KBflHgb zzPdqSR_I%)_CJc`!n{5GKNg1srH(a=Z1Y4eB6^(0^&j{3ug&qAa9i!dpnD-P6$d|m zt}a|?Q+S}&jfJ~>pKiE$GiB+Obtj8%nGbzi;qoTr@RbnHg3b5j@+=3N?QyuRuX4*t zLuu!SL5<9OC&*ZzsP?TGRuQtbdSSFla$%U={Jnm~ZPS7avaiN;HhT~{bXij43ytiR z47{0F)EyC<4!>~Fkk;ngK7g*P4_ zsJ=U?W5pfi>sPPM9Pr@!n@@Z1g+`~{?r^bX;nYz&2R~FM?TSgVKhV0$OJR0wc$1&! z`^W{4R+eh|b8XO~uw4I7*M3I$*g}f!vgKn--x6p0 zFvmMd(ftR7U&+1eb+as3xx(soADkPQTaa^V?cwq%m-pB|`xkZQ08!z4K zzInqwZCSIDLrdjKFY0-gdmIfZ(=wb8yf=T4-$`kWQ18F=W4iV#RNl94VdE1T6|!Cn zs-@9L;~S@mMw@B=W~L|H4fJJBMF!f|Bu$>V#cTMP3~LvKxn*Y^4;NjT`?UH?aaqm7 z#x8l=ol|o278<0jy{wrz%dJ__AT_Nr_iM2=NC*m1cLCcUe@x(d4~$}2~iYc_jlW>>LC z-uv`ekJy*SK@l|{-*r8_zsO{LV!Gy>9@+AXzZPV*I<#QAYI1o_XY=YkeSapui!XF| z8a`R$ly%>(gRAbihH|EI~uDUC*w~WZo9I58k`LVQ6f5P_jvNitmqiRZorKcs6KtA3U8A7wT3y-F3#x}pq8X;vPbEq`iCfX7phPC@USAHUlp zy|E}qBP4ygu}*fDUViSWN1wCGzgt{*cXQ(RrB8h^Xc1mX=`?S zqb}dm)UIp$_#_kgeU-5e?@J=w%+l;8B<=AI7*hJBxJgyz)eCtSJ};PFdVf%}jGf9_ z3-+Il&0aId`tWo+Z>>i1k>+hrTB@7OP*v3(km(ZAD90n^*q7vCQ;YqbI-D|}I;KV| zbIlgjy>~Oz|JD$AJoYki`L@E}zx0-S@}*WTm5#$xzPK(kD4lp+^MZf#xeE-29?s~I z{`7E%lCo^M7w=NW>?jJdk4|@pG|F~Qd}`LrB1c|PE8Ig{K|jc{>7(Q=8Jipm76ogh zZ|u@_?veWi#c$UwD0%K*{{5I%byeAs%7PZ(O17w2rp?t!*^_R0P`f1dlX`JjAG@jn z6Oz7<%8LlPTjP~-s+Xest8wNIA9v>}=D*HrwyygH%eisiwU<);?-gDo6@7hrqmhMn z(s#Ei%0DkEmfJIFfy|7SF0%P<%~comxzgn3jO8ko)x#PGer~JizVw!YlEGS~e)gl4 zV>jq%+Mj#Wu6@$_4tni;+izDk(pcs9vTaetw$|_S!rGjD+q2ov%#Y1C>+Eit?i8=q z!mF>kmhq1k6Bg#Tbbd6U)qOi>^U`jMdM{jZuFt_w$`*ZJ4YX9AKC}N&i(`F*T&4Ss zXf?(xX7cJ@W+!gZ>&;(-5SlY1}Dbt?Y8pld&3>;dl?;D zurl`JlM!QcN4Ae&(fw|mX6L0z`Yvwc;@-4Muw8W{as1smDK7g5Pid*3GP$GwJ+>n?0$%_xYVK5I(5e(9oz>eC#Dbj7Eta| ztf)C;$pJ5?P4_aLGgqFp+xc3~{=*O}+vD2P1`ag6XdOSIiB;Ds#{uo;&$Dq2ed7@# z-F;a9f<#Znn+Jx^KlaJ}@ZT0gAGDa{dLyOK?P>1^UKQ@bQ8Ql#kK8?LCjOcl0NRXM%TA(u&^d^qc;=si)nWzpNE&Hs}|>|FUes$BRE*KKOc%FZ1km z=$7i7Z?}6t?0=`={n+w(S$iw4c6@*D@!(!}Z#9l6tq#t)x&K!6^{IOdZpdu(FX?_M z`$~9h)iv+7+E>+nj5*ciuhl10y52tRXw~}6h2fq>U;8dQv3}aM>>i(NEws{0D zfBR3TWv5c_|MlriLDuCRDQh#Do3CD%{AG=HOkQSl*`yVN4x6l+eC6FrGeXF?!y8 z^SEJ&8?7x5Y&xm;Df^v`#k#-0Puj3%dExq!_>*~0+Q{uI++wwV&c$g58sE9Nr_b&t zd;Oa@?j9C2Z&zri(!)Lu>WAb$xaXU!PCvMBZh1l4ea$1c$9Nrm*(0-%>VHs3LH@k6 zihsY_nb*v7x&I>5*X6zL`b2a-XkNOeT6f>6xh@Km1MeS+k(wn{nt$}>pnJE%-*!)` zxIbJiU__Q@8`m$!o1V7FQu{LY)Aj*pk4>!DvE@vNjY3?aPRyl?u~T*|Q*YhW;Ol{n zmTOB|&+78@a@zrm;@58%p5ArNeu6^(ou=8N&Ms`77t%+mL@;Yln7OM_W1knxAG{tp zW7hJ={jSWK8MN=d#XT>VMVBpgyC=<5d-Tu4q!B|^ZoRY$J?i#p-6#FmC$pA2bT#he z<>I;a!G{>fDN7aJpP9VH>PG8h-=c<;WcAcPptays>x``IDP6m?vHyN(lF(Xu$)Xyy zk53)8_8ZY+)d&`PsvWPVOf z-wJi78BdC?+)qsjQ#C4{7~zm~Vto^p;xnPUj?XEjhr<8{DP9J|&zotX<(ncS3`UEdtnKs+fDE;M# zrFtH|1NWK8e`;K@)w%tl%WpQns95r2PQIaCNUK#I(y?7$9Cmm;w%o|+oN?;sJHwvX z2CUAujQD&e?OLl)v*U41<|Y^S@_v--S~=S4r^k@anNL5&&z_gtvbtBxPgc`p)^zD# zpxxnFN9*y!R_rXjKkxjm(cSy(ANg|3mB+(&rMTMPX!GJ{WXC@KigvSZKY3<)cG|*) zvDeqW)ZP8rZL!brN7F1!Mp&dNF4|HR-Mxdt@tG=7n=SG-R$3i7KJ%Nbk)C6#K||i} zd^fI>X-3nvbH^9zXSOR_E*yNWX1rmp!?9yh->+^8whq@ElkqXRcUPC?8Cl+M-)KFS zZ4=?_n^O9I;T8WU&-a)63|**L)azN^gfcrpXhFw04@26MTQY^xpCP!kDJEa<81n1O${v>t&2qLm&TVR2W!XqLHSO@Y^!pE+e;7UL`^aaGnf-^o=_ofX za-d)T>wjOGclvTpuM~6ZDL1`!PDJmWGj7t&SLaX0+-x^eY4^IyN9|j@o0`0JaA{a^ z^F69b+eWV|I@tSkid5>4oYjw4sB0^mWt&C2X)fH-GI(au*xUWPmB(~*Jb3M|*HdK_ zmsREOp6IBup}pa54Tt_$Z45?6e?9Tx&a=(wA#NRVc3qfosd2(zeg}i!$jO#d{ZEoN z&UmHj*KLKO+adX=lWk(dYZg5V*wk}v;Ia*>cV?R=-_756|HiZS%deKrR^0ETpR#+> zktg{E@{5nQOK*2TEiinS@a?;UV;!a!T9>!IeSLD&y+_Y$uIIU>U7K;Hd1U7Bz=*BK zzWaZkFgNJjixyI&T>|7H%f2+}7qCD<<$a%M;aR6JwJ|q*tskuq85`HP(W5JaWv<&_ zRhjX9lTuzp&%CW)2JFd6&FuxBtxRu4KD4bEop|@A%H?fW`i;~nGv4l2F0eRT z>Xv%6#II$?eKmQ*_ny?cd}!H<{3Dy1=t}3W^^u*eaJq5Xp54mNw2fjW%^DHv)bzMt zyKVb}4f>6{YrR7^d^5F}hb zZ2VwQ#U|^1x0aP|ymB(?+Rd7;Het`gdqkIg+YvI`?zV4!$v_!{`0kC`J^owC$>*NR zq;syaWBYcIw*I?NSxxO+W8qBC(7evVm>GKy247da@x_5u0{SO)^?7q74pBwhQ*IZ57DRW0hJ^pUX zw1)x8&Hf7PGhHPry#Iu7udR<%FDoxq{JBO+klSUl{My~Gn=BnTOJT#+_EK*{!{my7 zeDwG9P7MkvZWC!XHabG?$&c$A+4BK^HzBtcY1ySpB)xfkGSKT?=pA zyt(1&x+_al%x@K)bg6hd^vdCoH=7GQLoD;;?m6r+8+=Pe|MpHL4JWfkgFaZxOz^Gn ztv<0eq+*y!^ulVpu)^eGzrFJdg45b|j=7pWH1vVlg~mzC4lCO?>LlIr;4oPoqf>|a z6z(~qtgFAzYsu)n;W9;~KeyzSTsG-ewszjA^4xZ-0*iLN2zaZL7`|b(bktI%)rxXC z&sEJVTo+PdTL?Iiysc^jEdQnRN4A~ebQ_Nud1I-!efKw`kZenr9663(AuA$ z{By(nB7R#kLWa&WI(eO~7jK zr5@#;dRk>6NB0I#Fg)ouDBn9&L%M5>{$Kl)3wxbtyl|bDY=wq_bTuaCaVD6CiM6Sj z|1^CA_Y;AUr(`B4)z}XA+A`C{I^)dQvbhRZiViz|seU^5VNF@__B@xydATXhYtsxC z&dSuhJgBIdn|qm-+W4B-Ykt+%OAK>MhxN*j%Iq|V)^VIt+EQfs!m^UsB=zva^F4G=JD^6e}+GGD6~GMF?mFJ*S@cl zU1Xp6rwlA|F_?A7L-X`s>T{(Qs2;Z3to1bQsCikDdG;xlj)!ZUlrpv~YQ7-j(&!5U zMcYynhv+Z<^O7pv&mTJM?Xe*{QhoLU%bV#Ls>{nuGhNSI$Z7hb^2^otUy7H;`InB4 zNUmyU<&jrD(q(#9OVws0ny72F(Ke60-A~JURnYf{Et4<-;90ELc}R(Qpj3M9hSqbl z9(3Pwp<~yA@4h>X>la@KSQ)Z5mV&0c?YPrR;eX6}(>}n!aqslBVCKRd8f9KWA<{xV<>En^H z$8RNBr!F@uwO?pZCAUeCcd9^R`t-5ZbK8b`9Uf(q^fc2evaC$qz@>d-vlO2$8V0NT z3pDQ?%oH@sPBU?zm+QZHNuK+ado`z8o~*9%tS;K}*N3u<8@ciY&kkrV*t*)JJYohW z0M17wzq}Ufu>F&_Mogt$SHs|Pv&t!_u z+~*ci@_vF{npuGNo}}V0r9-Y(RyFyI34r^h(--W_Xf|m70xjh=*|BG*AGV&;NXy%< zt$C!piMr)UT~*Z?AugE%Qao}R4NLxV%*nra>QwVn9Wu3Q#_UzyvgU8~jJuCL1RCF5 zOuS0{{a0K{cE9CV>C(#eOUm$xr3TCVFKAvjSTMJFkBq}ZI~;zRE|*s`6xqUSOTChd`R zX*ol+xm$jdD}5HJET3_+@v!Pj#kQXV6>cqcS6XYJq&(WbpQg@+*mjT3*>_l<)V{rM zJ3S2}`mJict)i$+Sl;_)J>Q;f{xS1s)7?6o)#9Df)%$w2Xz{~Xt7ZPe39TkP zayECiyWe|Jx6(f6mMpYT{&diC;H$pvoWnk^jbYRrswSwW<6Tx zNSSyZoo>AB#$MBF5&v{=Ds@jg;_>3nIg7S*sW$ncV=(HRmcO%8r|d2hg;gs$b<}>R z-gW#wUHwDl9rV8W+UfRJ8f!3Cv!>hLaVHGlpIvFxYyFPcl?#rI9r5I2eEX5Pad*3~ zNLt!ibDW!tenP7^afvrp*{007JATUG{VtPL6k1NY?B6jtHDTlU0qvJgkjXwj@$~uc zkp+gkqEZIViZTCE9{pwUvxvNzk>N=%MunOTl@5Dn-qU~Q6or5&bxS|}ZNa|Jj=KeI zF1;QYc;sPlr$&cD?uRXKC@mH`s;_G`*uBG$LFtLfF69B=hG;4lJ9!;g;+%PJlikUc znf7w8ciLJF`7m&r_HpZrrUR{-jEEoLSk={L-u!kRZ$e#%b(aqDOf2X>{J>2`_fN;> z54HIFu@bR|?5UA@ z|Kr#L4|ZRE^)P-@SykV?qo4dJi+G$LV)|%;ifpycAoEv`giT(oUpxGzZ;jtmqX&u*=Cp82sna_!Gyayehxs&)H%Yl6n-wI>IB8l9W?PVmg( zZBg2k*VFsyys`6aTBB(F*ZX4q4IdXQ`|`o%=f$$|-oCdE_42&^ZI0@l{ttVXk9}WI zu{Uepz4slj-t9H`acM;3TQ_rptFKqz+JD1f&(sqCjWSoVFLl3G6&rq4yRG-BF+bE! zuKugb>DygX&a}32Eb<(F;l#4OUyom#w*FYtr^||+cWynu=v3C(a}!UWQ*Qd^!a(_i zi!-BaE+4zr_LB5LgY=ylR*R#)B`wh(V7T;|ZkvqF{Z}s!^w_qn(?4(jx}SO~tKiJ1 zwJAF;uQqR}exZkEXWYRWCRi;Ol`fn`*Wj>iNnTiI$&v?{YmfS zIt!b38zz1Kdwt>ZHF+oFOZLgNd9vSXOW}cO7w7D`c&G8+CcFFWc5LFmYhKW>!=;@< z52-u&0cyit+jwR@-DLdb zi&|ET0oy-~t(bW1Y{;1{I}+m*Y%X4k(OI@*N~}TC*6NlU4}6`~x@2wJ%TK$kk6$!k z*Jj(WFFP{}ObJmr67WemE zUgYAH)Lqx|pGRslhmJ^kX!Y`z$|tv@p|ABnt#eqOb<(Soan}cHJzb_a#(X&QUSa7C zt1XkGz8!1bGpl6C0<8o3SsATQb?G`K`_Om$HqzF@NoqBVmTYx+`f*i@5&g8bT8=Pj zw|M`Ybsw*_7J<*M2U373`Wa{B|!5)q`D}_sd%8ZroLU zTC?%&4O8#zYTG-cbc+7f@##yWJJj^i`Pe9J<>KIUBg@%(OGmuiH_+Fk@h5qc_Rd=? zHov)i=*NbLp*+3eR!JLId|Ud_?Eq@Tgptc`c%-r%bJeQI%uyLHr{&P{nDM? zNAEiSa^(I#!yaE5WAB=>>*tF$H~jl_jJ!R|PVubivnR0&7f#cCx%T>Ex6iw$JsR#~ zF~Y=R%Ob_J4&9@xRAwGm$g|iSb;PQ2qwKet$6Gn-8SQ*OWRPj6aqs4?ZJLp(UpQX4 zysX{$nsbAXIpi8%{VsJZ+&XyE$BZ$WE?s*kduL@Vf2{T9t#d>h+4rR>zEAwGEc7Yg z|GY?X;m`?r&w7Ol?8-_o0WiD5U$mLJf}(r7 zxFIVyUDEq`VB*ZCP0my%EKw`F*mZm1R`WJZ?NT?5)4Fv!IMH{4lv>>7+#l!T&#m&@ z_@+~J>kRwvJ9_8XHXU>kmZw#IgN~w#*Wp z*@^mUnLvkSmTDVe?gEYh7l8Y~Yk=Mfp+*2FEkN6sp{b#X33e>TCdVxa6%U^elfvV} zX^E3NTjAFlKRWY}&Qzpx`RF{rcKBg^wt&=;{3*Q#1^GoAVApD_&>s7Xv1ga|%!nr< zF~VKKC^a=Yb4~#ej-`89q>lo3FDDSvk9jV`q}%HRH8lm?(R2PjRglWv3vnlqqUUsn zG?!uTrI928HM$o_NjH*_m6KOcP*hY>QdVw^O9huIt|qwDxT`65HRG=4+|@$jQkS?| zN?ffZuGW9J+Wg^a`-e;8_m?IUe;HX>Ib8C%6u1j|R+vjk;!>8lD7}7nQCj})qICXm zF3O|-=0Xi@+N@dg=9G<;b$oX5*(8}glG*Wx|8b7FZ>WHHhpv%_=be+l%-k-Y9IrRDHFrh!@?q2Pj^R z!O?uc3Ag}s1GWQ^zzaYVSPhH@?gD**0$>vG4Uh(=0Rw;{pcAkj@CP0M&44AqP~a+H z3hV*mfVY4WFc%mEoCmrBe*@vbKR{bxCEx|z1}uO>zy#n6AP39@?10mN4zL*r2C9IT zKn5@zxCxj6`+;%52S62A2n+!(0fs;>5DmNn+5>BWF+e%cA1DM;fFFPqFcq){jsqQm zb$}mG2{Z-L0XN_ZU;^w0#sY5uMPLr#2%H1-fE*wUcm}iqRsbV`GN3nb5J(0-1G2yj zz!o?KbOts7LBL}`9asho18x94fjl4)cn_!m3jk-}B47aQ0HT1GKs#U!;0@dZ`T<9P z$-sA@IbzUUN>Q*B=2DpMFx_EZgLw^RcbMH_?uEG*W<1PznD1b|gQ*Nt8Rk5g^I#5! zIT&U!%wm}OF!f<>gSic61k4DS&tX1?sR2_1<|>%0V2*-03g#V{cVPB`*$3ufn1^9b zggFuBSD0U6Qm;fF<}8@AVA{j9hj|9(8JJyQc7eGC<`$SCFhgKIf%ybxE10cdE{C}s zrYB5Kn58gFVfKRA3+4fs2Vf?_OoI6l=0})KU^aod2<9S~E-+nSUWR!YrV&gdm^)$a zgc$=f24*$PYM32hc7T}$GYh55`+)c*87_rMDMn#Y zI248uAlg=dFOUix1CTI+)c*$pp4^d!bl!vkw?taB);$z=AniQFUKosJ;n?>Mr7qZN zPaEnvy*3!12%#DWE@))Lj+TfW?38DQQH-u9TKPTHegF<8f)ac#z%ZQs1<%;+?H365 z!eF-a6R1Q!$+jdMCE zF4!U(=NBE1U6xVUf=TLFL}NczM{YE9{v{E2qzs2PW3t-@gvLzxSSRnpzOxVxb2YLa zZg1pjZR_D64DgHQ^cFx90hnRc8(<-Q94*i1^zULn0yNFUMDgVL9SH&fql<`CQSh4; zl9InoJd669K0aCRI z%W9rNCNe2XynrPikD=B>-0fV3I{UbL40Uw%v2%2CvK?w69AJxww))m~9=1c7vM36N z%~OUNm$Mc^Iy*2Xm>-`@glR!#hs{jN^xC}R4*%g9!}eM_ND}h_NViBvr#$WSNQk4e z>X^eHqTn5TvmPkN#a?oL5qIcbiHS3Sauuc|h-{>~h4Cp~CQ1991!?ydWtFI;G1@2? zx8iY4i1A_B#`!g4l5$+}5vxj%Z#vu8HqJzpHOUR#7m_M>f7!GZQm`*`L zl45?6H`qQ-y49^I3ur4jG);*d(S~hOhZRCDXul4prV00vEIp=PLX{LGi0E08UmP9l z#y%zeD71?jG%bYW2$%n0`+r&X+`=S&9X)4UMIyn+_z0jzg=s8m=_0Whon=gpvU{II zVbVL%QG2LAi72FEJdxam<`p7OSy1bgar4XkoS4JJIH(Xsjh4{MCdMyAFcJCyP+}U2 zQ*EH}|H2KgFY$u?q49&g@~rTy3Cq4`wxmvx*NG1vTtW zEv5+8Ls!VEK|?L66DFsCpMS}}ns4#;g=>21ODD*6jxQnWjq6wZ8@F6P z0=)j3m!QjRjT0sWji)pe?S~^fgaHZ~Q`cFmSX&rHo8iztaZLl-ZxZc-T5poA2I5T` z@2CqACOVA~$I&wS=L88uhq$xBLB$P2mA1$+R7uqh4sT=IJM6Q=dCpKoD9$Sh2{B&z zx<`+xablDY2^mSk$P=DtwwTt|Rm7F{C;G6lMyr^_siHuSjo8FlU#$8KOh5Bf`3DF_ z$cI~(j#!#cFZQ0<{LcAz*bNI|YP8+deBlcXZd&V_7=q(2Lk-9Z(rbN*~lEOkdiEF!H_4|h+ zS)8X!y-hk22HF?|5kbjGI3p7sOQ@!0n>^98PF5zJSlxdJHx8O#(W&fWJl@K*3;HG` zPdM4Z+;cJmBn59mAI{GE^r-*Ya}HHH8)YnQ{75Skc2fr606Qpkg3=RofEc+*7hg7N-w6cFORjFBiqnDR>?5wei`1@g z6`$wPFETb1n(rVS&>lizDLNU9x*F;k(t#Vyfd{pYn9l~{;qr8tfe#y^Sj}Qt=G{PF zC$;YlxT;MzrqhB$Q`x2wo#zmLAN1cs;{1{YjI1V^BreCqU7)!P;y+M962dRVg8Y)I zU<5Dr9%(85p41zQzvcQ+B5l81r<9F=er+n~i!%tCe0*zNaB*gvd4a1RjEszgU!wls|ALUQzqj0Da ztFY$GT6krvNWhAiu^k?0k-@glz-=ePCc{dn;ii& zypx~$YM&8PIV7qo&gxBMyU*w^vk6z9GsdrEb*{&+BUiuukcl`_mC6_SV#d5QBS5@S zzuGU*FP1s{m>USQEhl6awC9mBR>&U8IesXBa>EVFBpi@XCcXop=#{Ax+-Td8+>>rY zRxu&firQ0%xvYa+W0Wc;GCSEtDJCjsLy2*|!}I&81A$=!8DZGK3r9wmIZ8RTLCm>5 zNGZNo#3*bM@q-&(Jw8tv<`}v9Ya>fO>b#HjLt;WhKa+UO$e5}GQ#M$4%(*YDlqTi) zKJf{GVKKGst!Na;mZv}X;WyUTGaCGzf0B;%2KgI4c|Q#Y$rL*Opk&f>OGg`E#LpBz zUjA_1dUE!ga9CIMaaWtxl4)4$r(y1>J>dubY{3#2*?b*g1RRxIT~X<0N;ee-G5N`m z5~&y#O-L{`FA5b1gEF*ZM$BXZMoyrbj5ZOnZIrn;WID%(1yd4(abPj3A04L5xiK;O zts|nN&$fZTBgKSg@NeAt{n-_S^{5cP-?Bw**C^uc_pX>W?%%La^#05k@&)dGo2I-t z`CVf1Wt2KbZ053!BYRJiMZ8!P>JG3Thz63Aja=zq^tzH}Qg+}M13?Q>_iG^{cVgv; zEr`E5!`unm-(tdHWGc%K`4`257hVmNR~&_#Af&|MIviBS#hYw&i4-2+_VAQ~bhA|0^8^pq6OKp4-(p@4@ z#6cvb8R1wfDeAh!e2_>sLs>YEd|`y{C{gO+m=p2YKyi5~<{spkW`o)cZVs_ty0vVG zBzObv(8faOi)JlZq7AqW^rOIW(DtvheMpE@t7F1!-}`EdT}zC2#lBXU?Qm9iYv|L~ znImqQ=a2s+GkxGm?TvwtTKwg4y~n14y-}LY39StQ51TJ_zt(+k{5$1&gNyaIMLhri zSbGz|8m{;Mf9}m@7ooON*Pb9Gkwol?#4d!`tBr_|5E8MgmfDKaQoGhxyHeD?R8dON z*1qpc?Yr8!|JO73-sG63pZxO8f0)cYGv|Gt=RD^*&)J?i^ZvIVo~gd&lUHtE)ZbHf zao6hwrnNayWkdgGxxa4qSEZGS_lwPmx={O)p@~H|2}Jdy~8o_)Sz&mZsA`fS@*DKG`fqraz44d(-~aI2Gv&MgaJ%{^TVCbnJ=9`Rb1qa$TzS9t zkYCu)$>I|n(J^W0gt@D>AH4X$l&83FNb~4kpHG~(ddHzl56vDW{OYvmlsxR4?|<5P z`0^vCyd^7#M#l6WK571%UyodQ?3}NZe^|@TeMU@Puy)tct500sD;-d`RczmpQx>k< zeeBvluKCLZ)@$9R->9jJ*8g_=@274B%2ui0rfdH%rY+vE=fw4ASqgdvHE0_*VD$7Q z8~2{P@jPoGuc{5(#Sa`aW9g>fPu+Zxt#G+&jo7zk?964G_np4=GW+}Gt2h3z`zK$1 z`@@#~XKugBQKUkRCLIz6kNa-<)&pnnyv|wFyJq-DJw6>jYsJrhoV)ub*9R4AHT}5f zXJ5_!aoeBg@4d}ktWxb}QHevop0o0ozb@RjN}aK<-H6|vKH|5HbY&`1M)IkjozTY> zwt=W_7gBLjaoK1+IWZ|YUYz_?>n~#`z93|qUa&9!=u{0IddvS9d#mjPb}v~5IQrCK zYX4eqLmbbrk21|p^=@WcH3`?J8wtxQrzhSZ5v=6)XZ3y#EBt#{b;qXx_r0p7mZn70 zIMWZNeWu%{TxLIW8}p~;h2}raFU+N#BAtdgt#P{MRM0uxd4%&;=cmqoE{QHHT<*G5 za_#N9(emtF1oiC4XH z`O04@zrMm)@92uvD!u3P$mg){TE7{Uhx*3{v62{Z#A0}+;Q7UnK((_(jdY|aisNeSfRR^ve z)N#I+i%{v{r-|EVB0`>;h30htC zz3RPc?5dfoc8lQgAv^0l3@u!@X1(_HlN*d`IHl2?#tWM)4qw=GPP3^IW10_a5zCh= z16mbo{i5}WHf!2`*{)Ojzz^LzoanINqr{JcqO4K7I(`w|pi`EZ-(rS!t`YlB?D8(r zUEhn_6E`595%CI8C z=M67A;)fBHM*cK1VAT3iL0@eAqUz|4qpOTrH>UE~Rb#!sT>53HadXBM9zS_}&aXy& z_4ccNU*G+@^Mo@Knos;~V)buUep71Fv`N_}e>(a8?Pl+sU4G7_Ij`o#%-uiNZ{Cb~)_Jkt z@BiL+{?z%e=0`2~bwSyMUoO12u=%33iwZ0rxcJQC8cSv^dAlTP>Gq|TWkZ);SXTRo z*+0Dg;lt&dmKRvjcg2wvK0l8C@z#&^R(`+o?aKD6*00L5I$`ym)y01r{L}HDeAbLv zb7f79wNuvKTU&44>~+u9HC?}G{oD1eHZ0%Zw6WdBRU2J5b=dUNCb!KWZT@Mq+m;Sn zR&8$xOYHt5(`^D{kJBIH#x})^Yemj5L zS>V^Mzi#-|ZC9IJi*`NTRd@H~-B)(|{WkQszkVyar~95wd))T6+WY<9`+IBtKKAz$ zzn9#Xv~TOatovK-pSS<+{-6UR4jer2{vTcbSpCQAKkENE@z1k=mia5`ug!lsA8dMX z`oT*F%N^=-=;uSOhnpRqcKG69&m+B#Y&v2(+VJSaqoR2YdF<)2n#V^R-+$cW zM7tAnPFy=t;bij3jVIrp3_CUE)L*Caoo;`6&grYCz0UMJv*ygRGd0c*J-hpC)^p+K zCZ0QXuF&}o=jWcka=z?^ZWmTucyOWe#eNqzU3_)1)}^7Be!b*!x&Gxbm-k=Jd8OHv z30DqZ$$Pcc)u~rcTrGI5-L;w5&Ri?mS_s_{OXo=WZ0e z+2Q7QH_zNGe5>89>96zt8>E_wU^={~+$c!UvZh6nog=;q-^c9_D$}^wHQyzddq#T>J4Sk2gGi^tj@a zZci3Hx%8yyKW+b+^v_@aWP4io>CmTJo<4o*`z+zvqGy+$z5l%R^9j%QKX-Xi`^CT) zYhK)aQTAo@%Wq#EeVOZ3gIAxw+VbkjEAQ7`UeA4f>b1w4#&1Tv+4|<6Hx=J@c{}Ir ziMQ_72G-B5o2-BRKKt`to!hqvZx9w-vwBdVzn^cVir(eRd3lyCTc&iWQYA~2C|=xR zDOT)*4?ZYb6em(~G{qTJ{8PneRrg=DIkVb4k{y1^4##DOBeREx!?l^K!`s<*HTu=2 z;ivl_uD$=uBREG6g9~xmL4)6MxF#b zMsQ!#o*oyUB~3fxt%pw4&bBG}i|RLUj6GlTxz~@a9<99kvd(~KZCHHE zXLauIyvp$pf3H6Fqnk6new=fRliv;#3C#;D{^rM%i9R*%Y1)9wU0!z|eYwi;o5^oB zKJ*+W_`?C;Sv&^Z-(unUFXdYMyZ+H+M)5WkdVDnQ_(6Hz=|s!9e|k0l=pgC;`!H#* z9*=m|VqwLC4RZYZspRAJC%)r0s9)mAie7*Gl!~wM5n$u9@)N) zVVlB7+PWVWYfIw!V0)D6Pt=8V0oHO@T4F(0I<~f@L77X7(x1VDrMwS^O%C>T0sEUR zyrmLYv2uXL+k##UwD<;8;0y1*K^FZ;eRah%#>>L%D?z-z;^S9=KmPJ3P~K(NC?_}_{jCVwAT(W%EJna+$y-B8uC8TF(dak`KVetuF;W_QN0TMURQorv&OWkDL zv?A$QC-BX#3YPk;DJ5C_{VG@*_KcxSEdNiL%BId43<6?bBcKz{0+KSHV4sd`(q3GG zc$r9Z?4`;bGRwL;ZpNKaFF??~ZG z;rX34GfT=MkL^Q^y7P){p-P{%H$JyZi!VMgThWKLGc~Spo-<|f0re4wBFCq>80Rn{ z&6Iu&E0M9vzP0b(HjG<9#m00OH8#MBXB&-)@bw9CW|i!|1QwP`wX%5l#Bn;}>Hdk# zm7;W#oJ@V`jwbK$XnanZDfzK^ILeSs98zQg&f!X7^R=-pQl}+aO{RBPtk50%Y`%&t z+ABUz3GqF29~8TLrXdZ7heYaHo5NQ_zFna^%;;0Swz(chevMg?+HA|TtS0K8U3Yxv z&fy-BDl2lPdxL_B2#vJhp4FF6JF-$H<6!Yx3=0tRATFP_5v}c$7xE-2majmvR>TZF ztDlTVS%BvAT-Z5Ht1rXT{|S&3^{6SlG~}a^j&fC?DbHj13aRct8PbW`$2zJ-LBOL@ zAHrh$@$s}K@wg``aV#+j(Y<@C@tR^9JBP|VdYbY0_EKWko-9*!PUEqfjt~*?Ii~$J zm8z7TqaYk5Y<#XegX;2T)tXOm$Kz=t3m^XE%Q1uNSd-B8+mR5@Nn4y$u{|LkYVYJO~Ie9$`U`lS2G>T?XK3v;@knzFbo6Ta`x zX}=rSyH?wF?TOP+pA6L<97NH?W!XaeBul6%zD%|WQ+pi8vv+YRv#ELutABOf`CU4W`lx@HSFeaEB<=h-9H$Hn3BPt5WaG&Z&(2gze(d-E2O&o~sWVEBT&L2o z>AuXnss6cA-7nPEHucdzD%**V{d7gM^*$2i zk$SlE)4$9=-E)N6?p@pwO7BY6GHgBuEF+|RK@K}7!MgG#OZ}Un_|-7O$Jgojt|#q% z=O|m}2|sz-BHh6`5T@lxp7*ZTffn$QeM^)+#% zXREWRH7E63j;Xvm@-B_NUh`7E_m~>TuHVMTDfxeQjZLMJnuhvqNm?DEvM{NBL6fH$2dJEblQU$-t5rHN;xa-v)a#5@7wh_-fpfurJrDE(R6%kCuyjdy(| zQ|~*dq=DP-*gl4MEMLD4kEIXKa$r31G6x(Bb`zKi)1 zH~ZAM#@fnw>z(JRdLv%_skr~TucU`0Z5aGD?QJ5a@m*$!)2gSV7sXTY`?gsPQ4o2D zAf?W{6HmV7tvAxT36Z$E%ekX|Ngyp=RXx#tK|PI)rPu%BN8V&e;m1*r7~j!ZO!=m* z@FK4>q{P#ld2NolkStl8oy}}$Aa7pF4W_WBBk( z9n$y2k`Ytv3*!y@FREv9a^EET3rxnI0qwBjz#5;n@3^$hDZD$3kL@)n{TnV8Pus{= zw>|cT6n+^GAP4D8;ANg1{jU~K?^{b2^iS;)O|z$+GVa$qta9JhEs+k}yT+Mkx;1fp z!&`T}<-0NR#)aXYUds&k9C^`4>vXQALg+q&_CCJ!x9wuKIWG~m`F5oGD%(12w)>76 zfStDuHwOY1q4{DQVhY>(J$D8;yuq^iS((xSD$7{X&-tXDz$Gw#eT;5=e>oPCVN~ zuxXY7{fRW+kD$cGEy!kz95%z@-{Y`Vj{XZGu=Qo7he$^h;aOzGnKp&ZWuo-AmW+C0 z^YWH)v~5&qD`H2N)TUm{r|AVqj8H<8i(q+|IGoT*|BA@B)foH(PA5tWG+ zu5V8pBlb#LoeIXJpY9Espz|r~>S??q0BVd9Y02w9{E<7maPjKhgHkNNK;hs=)3XKW8}*xo44&3oVc;*T5;IEHe_)c$CW z5*(6-q_th%=H-tZvT7k|NLmkc>JK#eCx7H{q$P0#&r9A`xi4W&vl6m}C7z@q>B~Jw z*bzs<@}9Ar&h`^)jqSGWwUJS~o-&pfk6yz&vF|+l4`<$Y;@B#Wt~#)jQeL_Wr8r&L zytZw9Jp90EGh%xt_U#&H_n)#?&bt3$uUm?J6uV;U^y{%(z`7W!6x(T=lc#sBPqWLk z35uLzKDBXUgWa`qCie$kCilr-2D>NOe^>Y-*nPYG_bT~a!Q_6ke_8#UJ|@_GLPap# z)4WaY6F8GNA8;Pz4Ca{+XA);e&LyO~-PcB=$oOFQ2ln4r#|68u@-w+xIDI%T5;vj} z@wjgND%icFzYUWG%!B}wdxwc!_nTAraPaeAS9juCIDI&SIU_ieI6HC<<#dntaG$_= zvQe=6&MBUkW}Zc;DO;Jld3 zbFS`vIPK}?8;xvxActhx>DRzKYYqS1`Q&SAI)1Mz&uQe-M0gCVfKsoWZ0!fpoRO z{O0uG-a(#k=X9hyl>2iz-9P0%*N$8r`As6-p%eejZ&D`t)sVxg@$mBtd~D}Dg$&LR zMurD35xxLTyBxK%$VAR_oY1wLAb;r6P|9IBdYgTO$=yDYK%GcT;$;$<$6?Z`Ql(}%NQ zlVEorCGM&N;P&zCcjE0KkAIP$KPjKz!0+PzuaqI_Xoo!9YkU*zezBly3Y}FsUESw$ zcI32hUd-X@p877cclo+B3#nn-yU)>`Vwi66F5i}p$A3SIND_NyHkq8vPG*fiY<)$a z*-5(0PAqAfxanjzb2<^niHF!@BJt0x(VOO{lWe5MZSL?xZivm+5kw(PFg7G;eoFHN zNn1mRT+_uiwCLjyF%7Ph|CaF6n&#{Nt?gS*E>sWp=UFc)QE#Vs^{Z|4RSV>#{Cx zFJ5Gk^i59Iw}q{LoAYM5`=YP&K<7B;R?ah>Kh>{2qPxd3#Fw?dWc}?8le6Soida9K zom^baZYI7;nk~DP;v@GWVcX$kb~drqiCfkz@=$Zt3)TKib9HfZ&f=8StYtIFLoP{Z>{PSZ^ z*N$FYE-d-f7hR72Q*CkYrAtP2+7r9?_jyka-E9BO$VJyD-PrNlpw5>Xb^CkG!y^mF z{xoy*hy^j%c0WG6YuK{WS0C*gKL7h)Z|%H%g?@;z%s*63GBu9OJG*$~an0+NC0~iG z#kG>}`TAwc|DaUmkUE75lrGrZKeUBcKy=k!odP4v1Qo9GdD)2rTh;YUZZ~gr7{lyC zFWX#txT#_Nm~Jmx*IQDq(SRA%`t}(WyQAOwsmI5R{QaLPYxg`GJ8fg{4JS{1v3O8} zVIyumS+u+Tc z0+C4Dl*K)(*(qC|f|f!a*_~Z-)5ojC`}uOZy5)MWNXc@(K~??Amnxb+cYzN| zSEyXAy1#dsVr44^)TkL)sY}Dr$lP{vbblKy6AG#5w2QMYFFwPY zJ)7<_VR&A(eNfr_M8fp2$D#1~Zhdiac6D+yXJN;pY}sviXT8ce>Wqu4vzycklRVFv z3%s4aJwlcajjMUNx!Ne`&zXTxDx{lh7MHBf*_^WHz;MZPjtC~4qGhni(M(>VuvD(x zriCqxWz(9*cTenT3u<*MEf+t|cb`{z=XqtGH%l1UBdM>9zL}q>;_uT+7Pah0 zQc{noK5>0}bV8aDf!RuTwv_Ii%`YH8_8Q`uZ(zz(_O6H?7@MqwBZ#U3k`vj!CO$O+ zZv*v?jY{kp8zoy~vfWH6|7fvZ3k)Z5f z_iubujL?FG-mwXt5>T0U5@rb3B`U6SvU-=-^P-cZ{89dV_e)di0EM9dFx#l_70%VtnVQKC+jpA)ez|LL#rI7@oyM zGb)ct?$IUXzNRgo)zI2$xX)UpZG5F)T{K6W z$JRGi`TFo(>uaksyHZ`XzO=gPyGTi{Qg>2y?B<#sN#{h;x!Da$c4U>EQQw1(?1(D6 zp~_CEMcF0Gq7~OlXeHUBt2F!LmBnw{i+%RW!;Lrl-Br?jG+*?!GJC@XvR_#cd(2g1 z-?SR+^;V1h!-BOCcJ~X_!nC?tJ@!Xyz+Qcg*)K4hJ@cC3|J__`!LDyD*M0?K8geK~LR#PsMhbh15eN!=0Nt36kg2~qufNy#&Qyo)1Q)5#z zQ>3XaJ&TT}SW~>Ihbh_A&-96Dh-tWKG`{N-OjArVOtVbin--at(d$@a+GyHJFJ!mr zcheuH!=~e=)20iiE2itFJEjMwC-h3(%z4cpn7z#Y=Gx}Q=GNwDbAq|QdARv2^9=I> z^Gfq(^Ka%u=CkJO=11nY=B!TnoQgS>a|(0{acbh!#;KE2Pp5%SBb>f=n(4IAX|>Z< zr#()Goz6Mkbb8`sl^%eT6SJl+*f2NRcfE_p4Hq-pqGG$UWYPO}(r#BrA197(z9d#YxU{+?i*XwSH(xp2qqN*t3jFz%SS<7{?g8pD+~+ssz1 z5{E7ccU+v@oU*WEo7u%#XzA&Ka?!geaA-EaHPP8J-#62>GUvhh-)zom_AuWwKSKa+ z=Bwr+PJcN)bIR)M>$2LVnb~U2X)f$k*7<=;71uMaP0W9rACu}SXLpz1UDvvnmRg{> z1iQFrwdB%r1{bsDw$`Q!)&8E_+c~#zcHop_Fny^dbT5wbJ65mLvT*W_snNP8c8=~I z6;rvg&$|!o_XB+@zk6SAQyhIXA%b-Ey?L`DE~TwgpV-p!3-mK2l_$4*?%cU@<;*GW zrrEM(&6*_($d)sk$t4TL z`rF7K6Qv(|WpmUk;UrCq!FuddyUu3sr& zNP!{uhfJB$>&X1jTUVYuG`M)$9UUbFHO1)y|UvmqnnRDIEYxS$ox*stAmo*n6 zk4%ef*vl;-x>u#pN_j36nD%N)^&#Dll>TMKp543GeR;pq5x4H88%`wi?{y1 zV&a97*NzT2R-oQsuO{J6H%rIm8MWr;XNl1zzAxinZrca-^2N;xE4VZG$!AgTugE@m zeb=?wFWs8*U6-@hKT2>peeA-Z`%ljl8`fldT>W`J->VwYy3x4{3!ndXdf$Y7raH5} z%+Wivugm1~rPd7fzgFSwx3%|Gu6yuI)ITkLEq?lPiRA9J4t}`gi*c?WQ# zUVoW;M90cSzODQ4!Tib9Jo;A-4;$cFWA>ZaHu)!af7R~b-V%Xl4#!Lno#*_;sAr4H zY&qU8{FiPOmzBT&_ki_HFIGA`cw3u7exH>)xN)?0QA}3j6ytaoU3b%pvaN|qB=(hKhYvhNlM-dS zZ5=22_Vz6^j3)kKk>5%;n!nsJ^Oun+f2lV-v}&&Wr9w$W?wfe*{MN)4mGYNv27fUq zZ>fFUp^K(D)39pVP^+H4RRAXblAPYCj;4ius|EAds+Ew|R;$ck6W^WIq&Ws@)x!8| z(zs)KYYG;))`h>CsRVyb#Fz26J0PnmjK54%NCKpWDc0OcMR=gUX_CMEW;Xb^dBJ%vLhRZ?jdi2yvQQ0l1SZvx#mLHZqvMR;?p{HIqed6GsL~?EXy(Vf=+6 z>{y8@{n?Jf8mTcB(cIx4Il!e!8x1$)4nbM9U}+)XQ>J}IEIcNM)_(FHs-c{~b0BO4 zqVd-emXO?+dr;M%lS)cVd1`z9R>w$z$kVqJjie?ifyRqC3b)B4D-Dt4nw-d$b;M9BS zFBPBiTQIflSh+fWtM?thq4yEbHNtWXm9YFy3G27@G;F`#{hLCQG*W(pO`++yFZa~@ z`fpi5#{DTuwvb4WcCNRr>iPQm`uPXxfBb`R0IXZjJ5uP%)xx!9q<38j%T>bR5w@^g zB}}|S6D2Umw{UzhT3M5;kcKQhM^1)^f*qWYZ#KywR*@Y^Ct%9`OUC zjS=X@h9=5L%M$1x@UMsZ4fk}Z2g{^rIKdZmP|KBDK$o#oR&_Pk22}zrL0ONO-?=47-{n1l`bFU(&eLqN+nG` zywwGHwoIUQ@+K#h?m9}UyxqfxqiG*PLfDUWb9Mw)yyO_vX52hy?p z5h|55`Dm`jNRy8i>GBboE*~vbDrxf3N{x{wAFb2nqfNSe#Hdu#GUdZ)|jaFt4$e2h?Iq{+v~ zbom&SE+1d0RMO;Qv>GE#KE|ZW$JliF7^hN6laKLgj5PW9DqTLlPM43#DwQ<(n4-o= zlaHzC@-Z!4KIUp6-hTQ!PHFYUXX*MG+#ou&;_Q`%*W@vr)K=$#m;$P_lTaMOPb zYg3{$G_mujyrUGIkaF+cAB{{(zp#OCr3QZQKG(D+CR?j+yq_A5Foo2MPYtH=tA4ti zhNa7C-E=vvmoBHx(&e;ex|}vom(v#MavGT~r=jWc5u7d`b<*V{Bwaq5rYo^t>GF}B zZeDt)%W0oGHp|(5{#=AIW^D9QsTl6PIdOrc~813oP%1oeg1ee^KMR8p3Xd za27*2t0A1t5Y8^sp!P%f&0z@VH1MCxfX{7+?`{a^F~s*Ug!3B0`3(5?4B`C57tbv@ zgx>;&a6vsi@$R)fFJuT8*2Agg^S&Wmgs_@^Q3L*il(1PV=Q}9mO6XKULgiEKyw>>YTmxs`E(OP;eGnGwwZVP)F!d^IB#lT^V z9^Yy$2i_5G>tVH)Cv3~F4PU{4_cqACqW;`Pr#}?>l?dDN@1jZA#}MCFNl%{p>GTB8 z_qCj?*2>Cr$&Y^uzph%1JXUK!O4t@Z(7=BcLwZ3e{Mq7HeJ8xkRL#I&bwjv@Azafy zzm|bsZPGXC-XcP8t|{1n4>5%67{Z~3aF`)n*AT8}2-i1+8yLb34dF(HaAQNbi6I7c`A+%FWq&=<$5j1jl_Gz>g^0eiHiX+4(rcTdAGY}I4A0ve z=zW+%PvY;#YXa4@A7WoVGK4=i#E&vO?`Q}|8}y?Sc$>Zmy+2GbhWvCkgkw|qwZ-p} zLO-i!ahhZ5YM>Wqh#zlw-pzpTZg`$xpx+}UEcC2aOF!0BLcM)u(WD+LEnzJ+%@WaG zv#_s)rG1EI36G9R=6eX1$d-Bsns4@WN#M;SOFcG+jU5;(qP0Xu>T58T$PnALS){&( zV`)-Xv#|V9+9xm}0spkpJ^}WtzwWIT7TKhQcZjdwA;9*1j-_?W~vt|84rwdSouwR)`@>1#es zV)-_NC6sM1c-<|ezSg8}!_W{*xcwTb)%C8d)8<-P`s8)J{q5lZ`_)(O`P!ZZ=+}N# z0;+gd@wM|s-oZ6(YhfFac&)MU6|E_w8}id9R$e^Un)JmtjJQqu_U?^1wFZoPnu@O% zzZ-`&*7zWm#!{8ecQ^;PwZ_OJyh%GPJP4eg7x~3+Js)iy`LTGm9GGPB^Y`)MS$Nfy zxcnk)2~X^qsP8i4NJF{fNUNnoCQSs>xLH_8V@pJk3^E+QWzb^(UB#DPf9c+~4^ox( z8({m5-(R)Tz4>o@W)J9*^tdU{Z8&8d(bhLim6@eM;Je`v3Abn%+Drzd^%>ff4(g3A z`3+D{;kykVHS-SX*_HRXLuA|jSOi|bZ43BrO2Mc4F*a?{#v<{3Y^rDTb*~a6uRn1F z1XT^B+@gE*?u*xdpd7V0s|SWuuU0)k7XBos@?X!A{NP^QkjR$dAx$-J4oN#Sq-nFJ zTod~R1o~Hj|LERHop>8)U_`vuA|k3;Yuj!49p7VspRW{_Y$qL+T+?>#R8xzI=}}YC z3i2@r`vq0|CDDD>ww~eLwl!HgtG4Tq+FPo$%&~RG<09KiZJ1m;EVK@#!uJSqYmmJ_ zLfO?ueuReW+eFKE3S$%bN{j8PS9kkwKO0Ve?(3T*Y1n?lHFYYfPv71aU*)$gzU_V$ zeI3;HJ5c!@;4cQiaXq&By?Bd6W*n%0H%6{PfU7qfWu(%whxByhH|3J@o7$N2 zo5WIn`}&|EN|+jx`pnNkLsS?UiDhWksasTx{wvD%8lBb&Utu=MWoz4nDBJtp5;v(& z1mA`<-ft99w|*2(CH>-K`|I0dkZycTj3Y(+o2%$kTw-D$A*Cm7Bc#OR(j}<-q-EP&Ql5o=Vseh9eh+$e+gT8)+4cZbbJh7lVmfaWMp3({A{@n(7zr@_4E!GeU`kC z2aCih-NmB+m)~u@Ln_;^x@{+{>o8Y5)3BY<-K7d^kuCfz`V~Jnxw7*Htt07*Up4!& zvBjWmzKVN|#aEAOSlv3U>RVcbw2|NO;e2z@LZUwSq(4z$!j|JeNSX%rw8ng z+5wAR6kPQpkgHxMVRa((_qFS{4b2lIwp%N)Zn;+1Q43E~^yngzV0s6hr zhE3}V&vHy&T*2M;i~SEPQ05P<)`d7kPkU;$ZZ5<8UsiOR@UtwMwl<$5rtP{!!A^+O zwA(kW*6WX~)-GTg71Ok69L?UouW6H9_|7?a_1Fkje3p4?+7+<(;P*1HU;}pW zGut88xMO*jCYgJypy!DUCX&W0_)?EJJ2oMgrtOEP z;_&PbcG?B2wM8u(HsZO}8VTJ?MO7sGliIQ8gEZ|7JO_g7z`5eC)%pWG?}qMF!ty8!a4E8t5vI^KmU~7ZzO8M>~d>8Cr2D*C{>{jwygm_Ch&r+Wr z(#z`r-IdV2LtP9sl-6b0j>6k`F)9=wrY>w_~L)RI}imN?FbzZs&_u>r-SO2X+m0;Zy3ucRW{*EK5^u zT}I_xP{B5)zE-(owayfq@we6LRaMiTk7tgUGq3TWDU z(3SFi|1wx)H3n<}=t@~lLU+`otsOfF8bNuHD|JwGVLtgC7pQ3$k+TPMyJ5FJGSH2) zW1pc1Eon(NVkZkh$3*-{Pfc5hKGmZSy! z=Q^J}smEwLc2D(;*TLy_Y;Nk&KFVkVG+J?vhVC-x?tz{!VJT;4LtR*6$Npb*a-$t9 zx-pFWOhd-ip;P_5)tVK1H3!@7ik@viW~U9hvDc3M3S0LTWl)lMCBT+KuQpP?uPGxl zbz>BA?(=~vDNQ?R$L2(Lr(+jhqF4LDjz>36R-^w0whm=BkgJn{?hQM3pueVli+$dU zZVZC&53gZ!u$>WLhJZbQZW!yrb366~dQ}vj`@r8~=;o&15suCI8(r)OFV5t5nxTBN zEVI>Lv2`^mqrTw2;`GPXO-I)nf&GK8bn^C&Y6>LUz()kBl z{auCrU7?usN`GfncTX z{|NRrcH@u%>#xxL3^|s9?lrKFu^ac$jjCY(B0Xulzctj~CJJ^EI(L;%hCcsfJC?Wev{tk$XE_6i`}i#Fe=y%12J6MRC7%10Eh<$_TVTgF#n$~o z-JS_e>Bs&`-)sl{*bmXgNb1!_(%5FG`)d{Ka>}40xT>5%VBZJ32h3RX*$sO+z#!)X z3O1v3&no$y3QysbuQPO`(2Zi`cN#iTll+czryp);2k(Gw#W+%qEp-_W9;aVN*h)K? zpOOA6+P1Z{P5#KzwT&&FJmI?^gypK^_yJw;XjkjR?lIB|SQk}YT54{-<&m~DWLcz8oy=~am*XTk+`oagW z&$UV8J>-6zbT+;BZf-g&*ol=itrE14fL%-aqv2EDz?zNBS|I!WdEUhiP_SE>Wf@N1 zEMSX}uVG-nhW|&@Etx~eWx$S8uzu*I(=)5}cXZkl-nUn<^{;p_&3b_RwL(ACW3Ga2 zN&Wns@p)^hgOs(jDbDaLeYMY_zt)i7wJJ7)?a@&Mdl;Kih`iqA%mUA6kezG@HW|7z zp}WFRkDg=#n`1?)PVQqar-mneerWYYcRzuCF=Xq0gDd)w7rh#aJZi#E2V`eau(z0l zDax~RU_Pb}dSUB)vT53%+3hacEo8xQ=doi5|zJS6@)4 zH!%iMj{ypHJUZAJObf6*8SA{P#&`}}H)cERVuzU}d1&IuZKXb0#PYsaYza~KOh;J!C)&U4aE#3m$@|CS2f z8`Kx~a@c3;ku&wEB=qlMXP#ZB&%^y7Z0tgGN8U6|q8=qE*yp7EKDsd$ef}GL{+M?E zebNbIZuTE|4>suYPz5_1oAa2mX$-w17qC&(h1t}-#oTj7zs6BV)nl@Pt!_bgp-}_u zMCjH7>jri$_p)%^VCbtXQLuSQcQ!OcpHDE>7zZ|hI*=DTUyJK4`flp6Rl$CUz?(ut z`spLUmIs@Yd?r)A2dMkY4E^?l3idhm=mTW69c%z|szZV_tv$ScLiilzd&nTGs|vO? zvX7&TuOsK)@cE;pg`8KQ&n>|=rrgxyxq=-^Km9pnYyw+>^Rv>}4R~z=_9oc!25gR% zsru|oe!4@iAv$=U_Hd#f<1Mg@NGA^ZUm4nzQVO;!Wv~J{Cxfj@zR#COPUP1Qx<8>u zoeXVR4Fzif`wHv`uzS$G-_bLf%Uw$*zXjXdfNiN@f1>=}U=y=(E+gN6!}DGA=>Xvp zw7=a9b}~W1PC(9yFy!M>ud z9U{Nap!=Z#`<;SqL_OP#j7;c4FWQuf*!E=PEXQ@qsG|Y9R>59^=ieEBmVxKd$gGqn z`&b~WZ%At~W%QY$d=Dtt>*()WY{Xv5I6Hl+ugJpyFn7p(7Qbwbx3(djwLgvLOtE&cVzE!C@83vD) zziA0j)M2X1QUn}sRZ zyYM)b@_h=OT*R+mM$@)Zz7P040PJP#u6lF;JH&qDY9RBM@I08fN5odZ#{uM=3%yzh zHlIPClN7r5z^(?{9^7g{~=r4s$4$%ZyGOyPMK zw*3<2`X~8oL0vdW8I7lmWF5?#@~vsG8%-4K5A=bSp;x8A=Dk3>PhZ8Eat$UNL7Q^Z zK)0=eErtFbB%gEPc@_QV+T?dGW#mG=xXN{;p}!HQU@xH0B`DW@V9(I6yFlMN7jz55 z%V^5z7y3c!F+jl%LXSMC`?a8R0v(A!NB<Q-ZCEq%JA!`B9`aiq8EqoJF62AN(9c<}U^6P`tqL}yJnsc7pB9kAgk0ayhMo|f zX%F`x_ebbtJ>oqw{~9Leu);vN9g2kg%C%)^ARCJCkx z_UbKV^`W7R@_`kc9K|ZKZbRLB1h)7&tF=KL#;?d|BY9s3{d$JFP)fn(KvvnHdjo9D zS^7m_MW18QjS19+1qQ6Yg7qtbZKKV0A%AD7gXhpIseA3=`2(=^4D~lm!7hO3)yPWb zDZZgi=|Gzzeh|e-Ydkjcjls6J%mlWxiY<+8mOdGD?os!*!*fw&^bh%!dD#_)y5A=g z*bxf0CFOe)Ie&qiE0f>J&|QX{yHQ5xp})o;s|gDB&$9G`ur;Drxv9VV!EQs&-tZg+ z&&`eFeFgi|o}J*iGIWPS zcLsFD_oE}aqaFt{fxW0;H(@v0(+;j6zxk1E*>aRA_2?LF%4)974SmrE3iene{q|$X z6rQirK6Le>KTR1GH!O!?sUHR$tMUMZ@zf&VA_Ua(G>V zy=uz!DRI=JltMS7Hr78A*f0efPzig7&8bg4s!!W;3EOuVS;T8 zhQ7);1)EX2-ziw}ZJ9=0kh$yD&~HQ^sUtkgdeTh@`WHnB~W}}_!flXfuHajw#L;kyht%l}1E7%OzUj>^{SshTY8Krwx!DckScQS!}tza`+Mmg4{*58a`izwKP=C^`^Emev+ zc>0qksYkDvH``PN+l(%*AzT{0dSkGYH8O#1qG0b(7kbkEif^eqb)hu%*95)c)Zf+E zjedr@&=G8~ofj|a!cBO70*~XFtG~dUqxer=qb>{qyV=n9P5?VJhs}~?6gxoSc`t3V z%n4S8M>D){r49~&uJ{MPKxU5&?city+Z+4a7JjFIU5X8m?N~-+XMPgwX0QbfJb$NP zeP|=a2crrmBR6IAJ8i1W^IwCPuGqX>2J9-ZGIt|6-jA$mA*&0}9)OKqNn8FAGTKXe z{kXO;w4u8cy7j?^(f-LCOj&rI1l@h`+6FmKfd1!({^Z$AVDBi{*t*QWVB4#azZ>)& z%0agc`Fsu^XVDRN!+1ekpIVPHip{5BCoqQF$lPW(==ve6(8}!L4Beq7=Ag-MutCnA z3N}w}#;n9UOc{-)jK-5z4P^B*vi}?zw>Gq8!I{9eRIq{2{RW!FpuHWPtV91w-di}z z*uk0l;&13r#wpm0@;o>b*l`MW9Xu^SKSMdAnHyFGgSGgD^gZx<6OJu3?^R zC^}IIUGQKmHV5o^u{2vQjd2t_cZ}qBmOJvv6oW~a<(Yg z&_LGJA#x5`OBw%ChCZyBF#|f?0s_)^R}UYssDWqz?F@3s1mwDo$UWXP2PY z3wiG&4fP0Cu;U_Fhh{z{H<_IQrd?V5bfJHN@+m-gxd9uY@Z5)f+%A|HOn$ADY2)(P zYlKu5Th#|XmKd-d6|9WQI#E}vlHWMeSm;f^9VTaknGIIv>(wJE6WE~&b{TT*Lta}# zw*~UrLc8!Mgm$1)gP`kXpgRF45LUNt=(%OJsHp zSv{bP3Zqj6xXSwv>aiVcgq?0#Z23~`#!MpoOkPn->tfOvg08>BJ|8xe(Lu10c5GOE z{4~LaBd?ptYZK-BjIth*3!iV|Jc7P@Tm;naRKbUz_=zdE4ER08Es2j2u#a(#y;41!W?;IOb>Gs2>v_t<2!rwJ)Y+6RvQ)UCh|84x*dqS6xvrxYFd8sEBe?09j{JZQjddn>|J=4 z`sxF{E8y0lhfT=;A?$fSWW1E?G6VL89s7`aW`gHB)By`}UIu-cpKSx(ZSe6JY<+`1 zYnxK*LK3vclfNDCc!as@7sy%WjvFwJUPqs9v|;R=BNNyn3buj;yF$Bjp8W1cznarm z8H{`vQ|2@26MV_39u*Yq4*0r>4gLt(+($R=Qh(#9SBH?>XXxb>Lw;*0*zA=3WN<66 zi6^ih)dN^(r|z4PcVKTB`rbno z>?`D$Ks*1JU}=ZTRzd%2Isgy-DwJOkxpU1%S z>r7zXH>cXGcG%-q*d|%WIYb!^!d@-Lw*G+(hG6r~d#D`af23evp>vhsH-!9dB8?^3 z$qC5l20AJ84M)h6diW^VzSyIK#FIJWrr28XT@%0SWbRq8Jv$6?4$B0#t%6;NJ*tPC z3t_Vs(T1MEUY*4TiT}4BJhw8?O;E5csW$HsqaDWGvpqPj?6dEovdIdSa@HW{z6^o$os#?D6_qkO+9o&{DNPT zwtCD}uu;^7Kd`5=ZgZSLR)R13k3Pv7UmW>;mj}4rF|mb24qp&}!tB@*PBawa}@RhWu_=8>mm723z;QPWMx6 z^DN|?mAq9(&X38jyc2AujDjh*VCupw!#soY7F+!lY)Q(*LfI5VCyV3Ln+I$>SZPC_ zgWYB*-+~IZTzSSC@Z211O|X}0P~Kqkf-MH$qYZMdpkhl=N8wr47W=^Sb?8dki8W~p&KjF z$zVhI1}oUx)Ui6~eLJuo=a`?Y!+a`rp*MPZ8$0+2eOHer3N}CbS{A2Jr5>H_*saKUrG-8nI2UBI z51wlWGp-`P;-{Mnne{c;t0aYPEbYFmLwpJL61vg57VQc3CqHyokoIUpyD(V6K0~j3 z$eXP1e}mm90`?hn<$Z>wv=?^_*wG5sLiu*VZit-6BdfRMe?N5B!}Dp{@cQIQJtiyI z>&STw`8@*Gmv;Z-%8ZYo`yA{VuHx^n9&_#3P2?vQo`w={B>7DM+l6*t-rtwGgNIy= zeWc|I-6mkC6E6^~i9SOo`h;IYuQKehYx^ecHhvvCn@& zZwRuVNL?`ciyl<4PViI<>;SOcDc@hQv9rnNDCBn#-eo@$^*F0w2UA8fDWgVUpVC*U zPG99Nm;}Pts7Lb+*c%FVKV>iy8u7$Eb`CoeY+IZ71YS;}*Ty#ViGuA7-8|ABQNF*R z8Z-VET2Z!3L7w5!9pm@GNVM@~-76bVogMDA=i_ zdl9{t{TXsmzGdi(PJ(WJ!gr}hmkjz`Fca8PnZWuuu;}x6%6BAkd4Zh&MmI)N2WwHj zLy%uKY|cM)IEZ3(7Z^HuN4?>3f^WcTR&oH*nBJfWyF^#4g_? zZgJ)rTp6bf2P3|TU69pFLm#-Mg3V|>>ZoA*q8p7m!-VK#^%bU_Syo&9Sv3*=7uzfOt9qPz0`rHbActl@a=G@oQw>*rzbHU>- zWS&$8pEY=0Wk!DJeMjPtQ?RY+$L+5@*m2 zS(o!ezhcWXF9QEB3Ag6ji+rfZDg~R-ap+bBn^B(kD%e}BWym_vUikY6{&F(EQVBUf zWG?y?I`a*3mOUcmJ>gL>e^kMaq#m`z<`f`*9?Ubyo{BOL`xi10pQa54IbT$;>sU`b zNZpaOjN**3nd-16&<9-u-MQr$gTqTR?rnqabLietu-{V$AE3L^mX)Dz)&;s{p|_qo zSc`gOoZon^U^D8w<@`&ktt&}8_!PQ{(0xN6Nyht4sXHH2e;+`1v!U+0D_B=c#`;JW z1zVXu(J7b1d)^57HYUGM(aC5- z-EXVV9YfrY!OFW!XPHMjT!Z-`WHcPz{uBD&8tBF;*grg3U!rWpm(~MpBkZK?<2sRg zH66M?8SLZ$1)BqG0N72$4P<@6Tn)bp=(Qp(d0*q4f$nGp>qU9Wy!R-u>!I7QI=+}- z<(+&lurmyO!pRC&_Wh`gPRgELhc7TE1J7TJUJ*Wm-H4#gQIENH>}%w_jP_H;a$TWw z9J*J)CO}X24UqZK90q+}rO>TMKQ)jJm%7UFb|d`dJ|Fl7p4?s72VSS%$gI zvkKOPUbTUS>=$&5_O~BA=cRlfa_uPi+0M$X;_o;~f@6JX1M zm33m#=hpE28lDS*%>mCY(0^{=ImnJZ4A#qleUlEhfs)_7$XWJlK1TUYqc8mJg{#Je{(?2i6&VZV5Io zSXuwA0QMZ${)YSxuw!L^pzYXl*^}i6 zJ<_f4Tpzk2(3SbYQ0Nv%&JzqgPtF8(fgSq>y3@$7tV=qP-*f0jJLpz{=TpeO33SWz zTs_ui0=vtOmGq_|i;2*cw!0rP3#aW~h%RI0t=u+JOie6C&3h(2oIo9i3PO-BDZ<4f7lM?AZT{ ztV-Fj`zhay%F17%n^A0-g1w849ZUNwKHrBatES~_K9GUP>N4#^3qu*T%mlWxg3Tz; zeH3g)b#jD)%_!Z;nZPbku!~D!W0128a_)-V`jfhF6+Iq`oR1>sRR%e4RIqO7YcTrw zJ=j9%^K{yBS?B(ix>1t)P;y>~&9HMc(0k$h^VjD)@Yn zU)f{u2l_}a4Rt@quc__tQ|5B!i@gAw9c-&0)fsMpK?Qv5&dn(T#pieddO8fQ^7|PVyaM z=$i#8SlL%w{LEy3v%T0JE4FStwpDnRy*kAwMLinWu`i%IAGyljG3B7^4R$kq#3-;y zU{^u6nZZ7{wPPi{2=qwaHx?g2Kja-jes>|OVx;vLy2lK<5vO3y@azxI(gz+2b{u8a z7P_*YQX0C(y}<`4*yUx}n-4kf2P?isOUr|W-Vk&ni0eti_-J${u+tUn5)1Qp)V&Gt zxCGuq$nSpWNj*xU9t9Y5a*2Zdo;GC%b#Ep--=jTTPkC1bJDTFEgg%cl@VrsMPNIz5 zD5KxNZU-xS5|#z~5BXgVc8Y=SUIpu0hI)gnV&Hi*ZD?`$$bx(qp`$}cBbNbtQo&Av zuI#V%)*_7LS4PP{?r(Ix8sFzUYe^Uou#JLtx2=3UgIrGov9etTQ$p3IFr#s(ZgHlx69 zMpm*`-pOEdIx5(|;JG_;K1SRYL`5i=lW#7Oa=w@F-`};Z**ettKZO$#~ z(TC`jm|aZCMQV3G#hK_%?cF z?8i1yu{Bc zSAM`Xr$Hy%Ds+Rv_J!xWQYPeg8$64R9R?p+knC>dkAb5L!V)=f|a&=HuS7u8>{c@chP5k9L72x>fQ~ z2Yns|&j;Z7cX-YN&)K1C1?vva#ytm4W&(Rh!FEBf7C>)3bj3#?D?E!n|A>7Kg>C^4 zRm%MSEtThtV)KEO)Q03{-$m+RP4wwJbgSbB|{sk@oj^gJ?&V*A1Ff` z3(w*M*^DtxUfQD_$XRryJJ>yj@j?wd&r_i*`=@rKTxD!=mO7Dxy3v_(m35L1U>6&( z5q7MM%QjoEiSTR%>kR#GD5F-$>Tk+O)?#uSWYswn*a7zZPKNG9>P;y6Bz3m+Qm(7(-py ztI*AX4i=&AABV?H*o`Rie+*qbKw9#>$A9fZl?l3cGJ$<<=UMcs9c^eg^7c18yHiFM zY>CX#$HD*4=+_WKyWqYjwJ!7nJ0Gmr*q95fpVr1UqEFe8-|?Kh_hOhUD3uAUe{x{*Y^=mgI$l)rkk%>*_s6W9S@9X56xHnt*lUqg?E zb5s0nrc*}s?De;^pJQzAJN(IvC5<6S`t!I}sku^{j#J#!O%jDA=Bq zK?FLKll+Y!-yhT8xJmsPM>vsd2}2utF%#G)nZRb*n_3qRdNHq0-Ip=zDC$B4^+>*_ z8HcR?Ki1v^Fs`clAAc!rNZYhcOKHm@JW30pblOZNYgs1KnaM(vbec)qw4&`aGf9R{ zGGS&yQ{)E`QK}%8RZx(spvcz+6%`fQDyT)-RKS9$1(9zNget27_WwEO-uvEtZzgT? z&HuHN_wKppoO|wm?z!7{F~<1|@=$+H)M&?=zf~ITSi=pCgSJ!BQalDx_luE7*CJ0I z!y2K-(N69`J9$3Z+f68&pLVqyedC}V9tZ6<(5ia08#3PjnJL7%i9^@`3yrQs*(q%Y0XO9u4YanL@Y(cW=7 z`awjV&IzQkY!BMLk0HDu;!n2ZQ(g7w#c|NSsnOnq`a6ttCR_bcXg97$yKx@EyA1Ao z5dL0Q-(C9f;xcqa{EU@$0ca_INzVzR|M@TaY??3sI{L3^NcT2`JAi(l&Y&G}wO4iH zpl#M@N6QRJC_R32sp3p@r@&1`h-#C99v?)nTiS;bT>_Z5T#-Z1vo$P`f ze?oXP9=-(cFS*kBigD21Iu6=hXvhwH9O`}m?G>HT{T}p}RjB(fyY%P%~kDI1%OhpD53?kLoeVUgfeu zEs(TlgLbUp)=65bN1Gwj$B`~yMq0fHUFkiv84QKRiae1CvE8baClD`*=*dn#ySp#39g_q*zEPNStYoitw9 z4ch-8oxi#i`-nmNWwf_+HqLsN-o9-dw6{uH%45HGv}uR}UdLprZP{yufCxVzzT@T0x(?tLP=HJQgs`=mzuVbq255k@Q0 z^$ytjofsHI&-TX@ohkzI1c5C*2vMBDUaiQyNkB$H+J7W*8E*C4%#|NOL;`==ja^&R}tT> z&~r|#!TL1h&EJrI<U*pE%d)XI}Wu4A>pNDX_qb{sNT{wtvN09cPKzcX1 z%H)e0?Gn_5PRP0rwBJGgo`$**LB8IPJbDT7ea=Puu0}i7Hn#MU|9f39$3a^)4%+5% z(4IdI+Chz$?xLtddqw-5$rkl(OQS?xff-V*2dGl(sZWm7g3Mia_NM7HQKTEWv^uKH^{YM19R+haA_^U;_69`U5PwG$A22ilD*k*_`s323j!#jg04kAwE? zanMG_K^xa-$C}Q=8to?7Aby6lqJ62~#rqMY)gaP}?tA(zbd_Jb((3AQ(C*M^$C|(Q zYP4g`-#r@bSnWv9jf3{UIA|w6X4i$W$~ zkGlQ~tW{e8{ka^rwjV=hr~v#5SKB^34%%%Rt$sezGU)C9YJk24Sw=e_>E?0J-lfrw z^*p!xG}^JABezGRU0n`43exosv=gsGuWPBocn&s|BIrm#*0)!q9jnayHQKSt z{H{hjR+&p4x69R7!<{z{+VXMG)@ig4K&OXUFi!b8+Vo#wymb}qi_f}r z(dKc`c4@R@O{>0f&<<;~V?Ez&+c;=%)@b#*emp0MlwJBu*Cg|_W@v~{y!(>)1o-8azo(OR{OpvT?^8;1Uz zsL_tKt*g*z$6Aj<8tr+fV=WBkwSNGapF#WFTZy@H$ees<4&T^jAwddxq7 z<^X74!#H^PX=vNgcm4r==x;#lKA*o&qrDDkL;I8_0QY{(x4*m$<9{u2x|V7Vd=7(l z_XLcu4`S}41N*Ts-%M-U=}wSu0JjS=Cop!Igt5W}u5=#J!aem2*c36AyAJW20+~-j z|1=SKb0gY5I^+9!*L=zjjrLlahl9*35#JNBuJ2@|)n1GT>AXS%efVxyU$$GLrL}4e zpr!evzrj{uz*bNKS~?p!h%~zva_i5N8f_5alFm(QY5y1RqcJX94cY*B`4R5fE}P7L zjdl+7@|~cg`%*s#nduyW3qeckuV_EcUtN06n;PvU(~%y)+laJz4|()wr1Oi@5H4h< z{d|i|U1EIy)~*YEi0^L1_ZrYY3Y+Rd*mKT8xL-tFp!-r!boD8v}SZ|W~9MWkoh^6Ew@Uey$!T;AoFRUeGT>ZX2kb4$V_Wq2O;w>T{4F> z+BZ)}ULtSkEIC@Y*@OHIf_4?$s}SyoTz1h;jrNnMW2YfplKIC-s~eF=J)pS{wEsl7 zyIf_XZydCjjDvRjIB4%sw9vEZyuNc0-;)r(`;cZ07)#DV9+e>e36#lwt~z*+q&i{O*-rgw15B0;PEu(Q|RpM zkAZeS!u`0b9_<|m?W-E?So7ETon4Q{N?WGU_MqH!BAsZAo`e0l9_{rrNW)8^d(-~G z<6Pz0)Mzh3{k;lpE1ehHhq|yHW%322?`Pnqv)DJg%4EejXd5)zvBozt4%&^9mgcRF zMccgq?FOBd^((ZKE6{GxdJ(!`gw}69;c6#STDW7Sy<{A;S8KHAqwk{q`?TNa6e#dZ zk-ucOx)1F$oq2zisn-OwW8B0g7#pEXpnEy^9^UTu>P;=& zvF_KH_H(zr z7NqmHT=VP^&{Cg3&&yc1`E%q^32<)*-m}nM`k~L&!T(0s8Lop{f8yhy9Ucem)#ISu z0a^p~jGh^&=PA4&Mx7(r*@){dlt&zUaPT$g$^T_6`_H{vxMQW=16ouAgX+TjXcyEt3^aiD@N-=nl)sZB>;T^j9T^dY}SU-Dgq`zw@_z+~Jhh_wDH()YSj?0dmaf8vss zV9Oe?PZzohotya}-Ww4P)q(A3ufK=B=y8`mnbK(AgwFpN=#lRr+&}*X>uj*j{D;U_ zI&bCk&`G}nS$>H7#OcoaTQK&yM5Cp>E#ECD@kV9TvJ2kQ|a_g}$}&fR?5wZ>+f zM!Oa||68DK1??h?We*^o-$b~y&TlRHP+D)OKR1AOAN&aR&~Zp-=qitawgcmZz0l1* zi*}Co$kEv99F$r8xoaG>_h~YZ^^V9rTDZp`o&SUQ(p+j1c~p$_q;4}g}=fxI2*Oy@Ga0lD<2Nu;m9FyKtkG^kyFhLFM&SPO&#)yS z-0vdXYVeAJb{F(({plJ9ZC?S}4KmzkWw>GB`uxlq~g01xQ#Ntzt!UFb;Wm^ z7OtW_(zLpH9JF^yTFT!w$ou;t?=5JLZ$KOSUzEwG&~DJ#EHp>|8<))YN!lkHa6S+6 zcQNvp_M!SvoH?WqptG2N28_v%(tLD{X1xvpt zJK-n3 z$cqr)>p}Y$%!w>Qd}&=Bt&ja8+UIvo3c-HnX|(Im9z6ltENHWT!rp(_JbFP(XIRnx zw#U$K=uf#udn($aYa!o$gmVq@=*zObqO;NI{MaE^dsU~=_9BnYMi^m)`#$t%x@(5^ zN;iO(Y<+$3*PmvMb|Uira)f&ZXx~G)0|@sApxpx6TR^+i6>gVC`xe%@twXrfmM?*= z;ANDn6HqobftG9qH@Rrz8tvziR&;ODouGXO>#tWs{~+7(F7P`S;h*Qqqnt+j81nZ5 zl;C0U4y+flNYkzdFM(ai0r*(KWi0^ca_aCmp+EkRQ7m-$U=KTy;T0NxEjy0X1 z&}dhq+{6&ZM-boX(9w=XxuUZyXx}y64Sky{o%fA{_JBr9a$9j);=^yO6Kh|*PX|!~<`#VUhk3#01&{ckodh{cd=cOncx1ntO z!BsXEjDxmf9JFU^v^PSge?jI}$b0}YUk{mSZ|U8TxfS)O!PR#+kAt>TqaABnZPaMT zn!hQHcC6uEqS203ue(~K9c#I|S)=^{%GFuuQ?5fEeGzTWD;R5i8+k;wY_gqy&s7)h z(r7n~2q%WOIo1vhm&gbh#Q3wnUrV{3=p=9^w&e-OJu{@KG z#kghF3<-P-R6$h3>A&b0ZuZzd96kxy`m% zX0zF{24DxCgtxSe0(av(-8CUa?}j_wwY4DtZ24+Op<^@+udbp3gf?9rIW@P}mf)t8)2Qx%{hL{?#sj6bncE zYh3=dZZ}834!_n#5Bb5+_V;pxG&d)>=H>|6?zS2vk4E1HEz;qJ_U>>)V{^C>p3Cj@ zw|RTKp{y#5D9n}&I$Wm(ykMQM;m$gt!OeCje-*4lcHleeAkhb1bX_*3F0a|;#B=a9 zgD3>bKa$>($VAcHn83?7mUxQ8M#zt4F~_sm{Yi$Cs0#Z z&OlA!cm--ksp~b!ltSU6YbXe>EzCbupe=~{IBD`^N1AyngjWH-N)AAzXG_=WsOd%4 z123CQo8c}`BegH;yIHpX(j8T@N%wm6XB;=>mTA_~9yV3{_?tpN80mprY}jl!L&@G` zE|wx#sB5LUvOR2s2eZ(%Iy@oNj>e%2l0C^(zZpjV3LM*A&v|IM8>?-<#v1Lrww8F? zc(vMh9Sdpu)!BYj2pgliTl=o8KwWgW9brT($y@XHx!l!mH>r>sel@4HC07)2clx8R zci>Z(qtR>ek3x@d_#xe#ZWr%*SJ?F~-mUPju)}JJdZ-bzWNnF>j1->JUE>Wg!exe@RZqYv2 zZV#gB)xsxtrS1+;2pWEXLeSlgwCnN&C}DJeN*LWuN}J{myXeD}j`Z+^UHrmMeyHG1 zer+y(QJ1^ZC4Z-jf2S+Hoi6%jr+XDSwfL+ecDB2zvCFKc9L7G;md@1?6Mris+BeoL z#HtOh!dyTQ(2i0^LgDcU%e-oj^z?@R~XG6U%eZ*xiSQ(D;!_Q!)>B2j}K!G-CY&( zaHr#f<Zs5tD%Z(ZeNANT_x(Ig2BY0<%VZ)wuA{Cp-LWUH;VinbFn`od?6bRRhBsUkL-6A#4=XBWBVmGZ^bn zWG*(>htL~WNjboCd8~VLO%;#XglrOKg%hcT>aXzYD1#+lU7htEj%Bw-`(l}dxxSvD z3daHGIw{jr!)Mh~@(c%}>!Qtpj^-ZzrbK_ zC~H<%p*GuYPfLqgC*6%na#3gP^sm<3&?GGX#w1+aHrV)Pt;4@o^ABbc@wCZxf$@c# z>w)Ix!lk)6ky;bU?wHxeorU~1%R9FYnw3=*XRti%FJU#6HZ0mIfHf6f00ph+`{cJL zED$OxYR*vp8pNVeuv(k-BC$}PEK0wuX zC9u`Ex6b-rPqvk|WOoL2y0QW((Uu%Yr*bigN5{(0|7N9&B$>+ig zkf3fDDLr|xd^}o)YvZkJ51V^20T(Qk7)We#!6L|Sw;U0Kn-8^2;^E{MpAtS!6^!J+7(ku8H?fX29Hn7%f;ZRv!ncCVvh>kMQ(%}hIcr7<9ja;sk zKiu3`S?<~j9-L@yn-;y8f`_51>EXbw`3YUi#--9>%M|u-7HRlme5B!PepEVi+A0p% z#ubX4=61v{4As*~kLJO_4^4#At%c21U3a^1Bis+#VMnOT(C{P3A%~m$Hx0kln|1iN z5<}ge80v0fsJn@w?j}V^cat8ZyX#zT8VhLtJZ{t7&hUlqV*9swX$p#r>N*T8b$4|E z97j4t!tEXmw=J4z#OKIExHUiI=j!#k+v{>yyWBNyceRtg*5Qv)mo9%4qbP^Fb6x9d zj1*LSJDWV*Cuwd++`86_ilY3*ZVj*6RXF@TNkoX z!ZDh%(hT40jYw=D2Fqiz+YGe@JwdKCc`ypY#tV8H*Vj=&aKk9UH5m8-u>g#8Y&TwI z0T{K!Zaiv@^I#NjTRsk#DuNqEh2IUM%Ik)S@feM7)_7W1>*EJ@n^Y;BG_VgAfB_`O zBcx@66ND1u5a~93ZazWc?Z81oJKQGflOwLJWC2t-B(EGJRn*fM$%V_tFTpRU#!@_X zbK!MSTkD2#`ErL%<=73g8g|Gd<3e&$5pu}wDpSbERz}ijxP8;yNWuK@38v%Z z=X+}xHGDb_x!v)w%Rz|KmHI0uP9sbK++|B%qI~c;+3T&!Pk+XD;O55}I4G1tHo-4H zj*aWl-cgaulZTbw0&p@yx@9N*UJoZfof^AH78hNY7rK=bMl-c;{!LVr-FTemE?Ul0 z7mTvQP0Mx_7anDi8;_bC9TxO7)$4AQt0t}oE?$lKdC}CEpY~0db#d@#e)(misgc`e zN8M;@%x@2y*gou%rMZAC%>`s>cIH{2$2IGWq6q%xuTb2?b=mQ|J1cIj@6C>?HU?=*jI>vXpZpW8>>AA@(B zKEk$J&CSMK&CSMb&217ubF*zpbF(p5bMs(SbDIRv+>{);+m$|%N-m3*{1KA?Iz5*U z-QUSi)GN!sWtGoFslZH*&4XZd1aiS@3c#u*ER9)#0dsk<($fsBJ_7q;CY_9%!(u^E zMQQn~jxAsy$Ups?0SszajjaI?RB#5_4+O-)sv6J66Km z_LoLbQYI`K1w)0iV9@;4w?>Z{)CvjjXbG-tHk%k?(RFp0Z7Wx|caj*29Z9bx zZc5B(tUo(6&})WQc$(U&g5|-ut99XVHPB%z+U5Eaiyvy7{ar~zSj*iMOT~t_n$cP_ z9PdpOfal}3cWJQpE_1cc5AOctK+@vh-X#{FsPN%t?L~Jx>5-y{x$R%6eIrpEerTCo zZYM8idbMNS3?-_~yIT9U)2O{m%o8iTwac9{HOYB&<==!smd=;lx*Sv{oNf;T6nzw( zSv1+(A2Z{F6M>hgB9p)9KK5Jrc~A5Pt0_SuRoh)j3WDTE{@k8wZZ<~hZff6kH;rF)H%;E@ZWn*pyB+@3E_|*W8a*#S(%oA8 zNM5#SYyPayX>MMy#O{{XV8ByDStsOUcWo__Q*+nX>+Z0p-tr537*%&iow&78oj341 z+R&b>u-UDJMQ#_qhKt2)DxDx_*n`Dfx?9DeZDlCj>S+(Og#~Rp){j-UYu_E(cc=aB z({PlGOe^K3Z*&eUJAFgJv%c3fai6cb?KB3i6{l!xrw5DvTy9ba1TW!Fs-xzvcKKJk z{q6i?dRA{Vda>?|Wn+IjSqS^jZvDQ$GZ)|ajbom8;Fg~j@0xYz1OA(WSDjroQhWak zFW-3fTjwRQ158nC+vuzkC5^2bi`BRBn&oBYUK*6{nbfBBD_`1H=kAHK2kj=>Lh z-u=%P{1ew)vva!V@?EpPefqA_31@y z@u(Yie*E0up1b1gFYG$7?KA!l`_FEO{$~HKWu=c7PXzgY4r0G_>Cq+j_l(KvdsAs` z$t>VJeQ>t1snkDtmN5ICJahZP+D*Jwx=zdN!8KLu!>6RR*?q^K%^j-cxeV zqzZ#VR#5V4p1ixb6i^$Npo3HHIhvr09k`Lw*(D7IwkP2!2;IOlYDKj9n<$ssRFdb;nO$c+$kp+v%po4MGDYG zfI8#09ne-|Hbd<&OUm}+_?l82yM^~QW1 zgzu4=v!|7!G%m2Dn+3ijGf$fqF)CfS+a*-wobuc;>;7pQt$bAZxo_4LrRN&1Eo;WU zS+@epO_?Ic`^{sHowfF1(6OmXntG3UAI`Fzc} z12Zl*A`VPCYi#d~=DfVvK5y@gDMbrhG8~vUQZ|elbamBtVJHU$= zDt0H?&~1`~wGW5AKFzq8rE`R~U2t#$jbkQIEO?=e&DJ=UphyRcFGpjZ#8q(<1eFq3 zL20iJPS0RmvD?dLT*FYz89OA4FjVYBvvE5Z3N^%m+sRNG5$WKV#MNOq-GHF93y5_D z#d%QRx>D!k3Rl~;XBeLpxN6@L&x7Hl7KUQ>*%92866ydN+ZakCHXZ(HhC27;q4XU^ zc_DU?DQQtB1ym=8=K_Mt9ZojxLdF$);%w+?66z4aIGv#wG&{iMim$ati1>IJx6NkB zU)2KYYW{Kp>T0~M5Ku8RwfNj1psa&gK;veGTVcbnUYMb-gfyBMishM(^l4#ewaT|O zf=`5@Vn?IR`ErTttlifOzOGVIG?8)$dp*q#n}IQrp?%PB~Wz>AV{4SMoi0h7F5TsQBX%p)XLBtK%-7Tc_p3Aqh3JK0qb!)NAZOWc40eL z@^!YMeu4%(!sKBwj!M347_y+9l7kj8_^sALvvt`u7F5UXQcyBjSPvpuiuN zp*c{Ek4h+;Srn=fBd9XuSkO%ZD$F+)v|GubCyo)fpwc|Y_z4l3FuYhCdIXfM2o})j zlelb@vA`Dys4)9j(3A{K&o!I?YRLd|pY~vkGSQ%6Fb;>qxe04jk!$o+)bW-H4Hutt z=NN;N$|f?c-Zh6i})wd~PM4312EQW{rp;BjU^Zs~Aputjwxqb`=)E zjHG~XvVDcp--Yk3S>`I3Rj(G6&Dt@oWJ1}5eEdjW0RO&xt}!x&PG*L-3;E?-09;YG zBto9;<;MLJo4NcH&B6MWCINiNd=r8=Sh}AXwzc@SxS13GibLSLnZs((UvE?t?_l{Uzgjl5r8gy0m~m>^5Y25(C04om zuLEt4^jXF<>jiIr9aLp+ARW)_a?ut`&toUWm zt{M}6!`x_?Q*P$+OzCgOmk(sgmuP#Bg-;iMyYcn7as&=I@v(P}!Jr&SMAyh~`{k}* zWY-nG)%}Aun)Y=QE)gBE>SKG8DqW4~%$8Ut9?0Z0WElFsXw~;3)GwRAIF!cIkMeBR z*^`j`Am;9ZvkN!9*sB za*CR!Fr4o@slB>}+bfbsraxBduUu2-RJH}(_IHfIvMK0fP~U;C*I%k#d7+s31HS1&6{;Ix6g!cw?CNi?@zX;a|yAjToFG} zS5z_UE`gs{e(LK)`SI4+1t>JC{1@UpB*oTx&--lA#xj%Be??V-b=IF(QQ_>AaBl7|&NTWa zm2!Iy{F3FdA#CF${LZeXyy(_UjQk;DY@Ga3acSw|3FS8!6M}TU6rp2Tx(@uE@XQD@i? z{(-xOjOM9bC5vIJAB}%ho=HLYW#7Kqh?FjvyZ}iw8ooMDgYf&Nd=~hNCYK()cv^W& z;q+1GbrAl(M{YAprrk5Sc#?V4sQj^uOCE(`l%>C9(9B3_@#5l9@#Q%l#J}sxUl=z} ze{xD`an&L4d5IFC8)ct=&EWZs(s`w$^QReT@f?`=s<93Hi%U-$HGTB6JPu6$hp~P7 zvr|eZFP=Oaf8bjYZurWHMF(c=pE~al@5;Fha@y z_fw0S%if%Ne%ZvL(dEH;BXm#;o_#-RFB+WrNa=A?T1w036wco$*2XA#jNsOyjkE5V zR#H}1GHQ9Cr8SD+xu=UpW=CcKzsxC*ea?v#onL18Nyf(FpVGur5%krfU<~J&u+OSB zSe=5sD-Kh!vGF*sVU|qAl-iVheBUBEt3qdQjJ)tsE_S7>Ky1WYHl%n zQ$L9*toaMjA8GPn4t#xq2Jy+o#_Hnx(Eb#G|IyQI`GGIbYSBX&xqOAOsALi3H|GQ2 z$)8s}>e%?+biT1@@_oe<43qe4_(-3QDqZzt!i^ml8YNTc^m06o_(GltHnXvZ{iosO zjIn46-I#^WE{}h89)DwQ7Wh{K-*n+q`q=eKh0xGV_}2m-Gq7`X`31gJ5hcM$`$fS2 zIq^T2 zeCf}q-$Zw&z$L(`E7 z`$&39PooJtU^B^Xb{72eCZI)c8bw9LMaF04xetsO!kHWeDE5Q(1j0xAb|m<9D3`@m z6M148>BHwoNd96qvonmwEq-JErbQdZ}azx!)sjWp9}qT4EUjsjodY>Xvd8EaHQvoK#QlsXKPkcu#JB=MoK}1hsK+&iGlP*++hdm3YF)Prn8LZ;vWfn3-HBR z7DUa*Sx613$m_0@1$3Mx^)wlK<$F(7tK>d7r;xYrUUn zHp)sSQF~Za{JaCd-Z3Gj2=)8*-UB~60>N}k|1T!hfm&=_6 zPX3v7W5GwVpZ05GM~SHK(@F=_AVA>6nH2!OsJLijKP&ETqdw3-HA!9f4S1e&W1?i*K ze&-8LkPz;HdLQGv18m4xlCtbmiC)$Nm z1B1})wC79>;=~PZH;CXa`D0 zy4sD_G>(_VL2iW82tNI>0TX32He3ESkXM*ExoeEC-cHo9Tn`AUNH_h!U zSF})J3v_fKW~f0O!8U%&v&89JJ5HRx#WCXMMN2S}AwSCv!?Zde$b{Y*?g$u-Ev;d5 zO}Hc4va+3cH6{lVklCbfd0eJAB`jtdE3i?2g=ZMQYW&3cgm~i{#urGpB7z@|Lg3Br zpx1lTpwv`W(4Kh9>LkW0wmZPpMR%L)(`+ErVU%9B8)uWzK7NZQ-1TB)Zo}lBSPMs- zvKp-v19%$`Rtae}&|tiy$96aI{vq2P?Gh)#BE68_A#AD$@hL_4#?U#0^$}!RBbh@m z`ZVm>wa=2Lm_Mq3?1sU#jip|FV- za!9vaEEB@%O(C4xq|AJZZ-h^uvBQbf3dWYd)P^iK!dT;7f|6v@h!b|OKFdTM;ZuR| zmK&l)kLB~NMTM2;ck!87QE_ak(dEJX01gJG<2Kc?o9ZY=c@(L!g3c907lSuaXT9P> zNn-H1S9tRoS$MYvy1G`QhKMt>7GiTyR^c}hzBoKXy`zTO6BWkPyxMD|TGeou+^?mz z`t3OM2uJGM59?9PKa=tRBG-~5&HkKc9RCI9o6?mp_MlJEFG z{^2cebY6M2|Jp^LS-b9!_xX$7kKP@6<|RMzf|Xjng)9H>;r*Za&RKuj`oc^8y9OtI zWA<6U8--s!pPx>!EVWLEv<=*=Gx-%$^*J2*ADb_!P6LG|z-%MIw z!y)#_bgf%&1cG6qG7F6qRAmz~xq*IjIrgZoU*|BM4raS!D(^7N<33rr>HYNE^tZ_H z{2t}%4e|ZRoFW4UkV2`7Z*<2=pTF>8%VO~_fq_W0XSWy*Uwy>g7{4uRBh9PKgWtFeGu7+1_9emz2m40%; zV4`#+WG^1+* ztpvhRxUHS*B4Kl3c1pNC)Ew$yJv0KZg>gc_f5`I9Uz`p(MrzZuKCukWv+#Y^ls}w$ zHong}ZrR)Cd~Eg-+8QwOgLhw)TLccMtpa{e@WfYMs5##6^ZB$gACcdK{%gMZe&xJV zFDG}y^A}&?|JdwrH_`jiN3PcJxBI_v%Ps7Vo$}a85AOUPeQ#X7`YHce^}!2&^~IIr!OJ4@Z9f)&YOE@7jM{;{T_AYj*jkiwFMce>eKq zJHPnQzoeXR`p@3{qmT5x_Lje6V^QmI_q``&p3(5x&kxM{#O@glkQ2{|4g4A@7jGld zfb{VBuHPWsPh2YAT~|u~?ee`tzV8w5Z4XNK%kq7I-+LY}4*bvEi@47;@Qhrs1m6w# zZ3O&oym#Zb2S4#79(|O)m!pTmZ)EwBH@=DY9<;m{hXBKv>0Cte#%~gSR7DA&-sC1Y`MZBK_@0a(l|3^2kg;?c ze$(-zfk_#DGx3{+-!b^j#*YRd)RE4`ZytWIBJ!RWx^9WCYNIO?Pr~nH{7n2#!EZi( zr{cE&zlHdnhTrMzwbA zm~c19a%;q${zg)|<+~y6bdOvp-8uQ*>U@uUT(}!9lkh8?{>G=JTfQ4U=X6(GE8N?z zm+)Jh?}{%Acf;)x@2gIK;~UZ~-woe!x^MWdr2D>v|JeDy;b+3#uuI}SDE%Ln@W-9* z8-6SCelOwAINvusFWe1(k$8WV{x3`T>-^q#(D^pDy&>`bE%6SD_qL;CIhf4vkxOUr z+kE;M2|rH4PnPgg14c&{WoyL0=c89~84KJMxbi!RXZ?>>KJ}+hz3{aEvJ39dT|e(v z{--ye{P{oC{YJuH^562)o3_um_kVE22}z=JpU;n?|(Z#tEpV0=U^(b3P^{jTqr*LTW?BK8h> zb?yc6kw;$`@j-ise|*qB0U$nTpAev*AfWH`x4-Em0E}5!k5QxR_Cznw2ASod_9oUF z=eCBe2%&NoV?F81G=+uc=o2if^%+SA2_=y5d``!WG|Q zMXOi?V_FMfmZxxrd0VU(2kZr5(&&##D+Z;%=ErtDH-_dPNq28fV{Ev zKv_wuHtYOXcSHkjH;jn`Ni!c$!k5%+cFIURgdcL>tP=jbM#8kM5P@o8DanK5C{(jN z*c@76_8~>MeC6Zd?wZ5m)E*uO$HW|#4^H?!JPs@>hm!~E7!HpEL(t*)U|rJTabOfW zET1EYI}8Vh=W_&cuZ7IG`$QKhFHgn#qeJ7!H7pJ!lsz{u*peJ5ZvQaOG&iyF>~Jy( zJe0M=$ZlKk@?~kNb%>HDE8Fy(DET;5L%W9Z zMaqwxyo1Tbt`HtCz&ZlF{ERJ7MzH=XKVu8x2@C7t!$lj9^;?I>JA7S`Yt0<2++|p< z|2ia&TFvD^DiBA;!%S>v(upa;wD)e>Zj_^txztoDK}TX!A_ez~WHzgSRyagYyQ=f> zyE}YDq?@QqmK6$zc6#TB6V0cogm@YqOmq2ko!)#ppNpFF;ofB%3$teE}R|q~T!4aDMnT&|qyG z)cbs#C>;Xsz$t*#6$Nj-44I8OO+m(;J~s`fHym;2J86R={ptQSd(C2y)-jTs<~y(^ z(RQOe=x(`2%JP?M5-qn}<7d085nGC{!CiM49BTdYO1 z-Ck^uQ|ZEM)p%yf_V0kE;Pj`=)ckp}M|ZpYQAX(AMHQD0KJ-m@lOC_Tkr56zrHpNmvRTDq;>e0$wVo!fZHz4m`LUbvi^=hBcf@_VcYrwEEKxqgh8cj1o?*%QLlQ zd8$cXo=zo(aeqn;!pnoT0d`)CS>>y%8unH47AA7zEXD!M0#}hBOYu9CXaQfJ80a6$ zCd@9B6sNmG+)Iev9rnG1S?zmRt<^KtN5xX?2W^bYnFidb%{ChPY`PF|U{hLz)(V z<Q;9layqeF+=VFJQR*P9{Oel9{e|XceZ_W* zhQ;CT(dprjKH1^l>2xDF&0nkvwDHBBAKNX~PS|dois7KQ?`D+o36P?s<5MT2yQy;O zZjwNATX#1~e%4)$mfI0Ok9BvW^yf3FZGQG$j?$mc(zg9Q)?JL!ztd|rWnzPUn20i? z$rPr_obp?DJ6iZo`K`Mk*`ESU@d7 z&|tVn5_9FwaD$DoL^^PUxGorr;fB?Nl@8;j3>vS_%n-cc@v_B;42?YnBK2ItA;#$MQDYO=Z4$D7Gb$G$Zw9d3a60(^^r#G|*bXSLG?c z=JY^1Qxmgr*-ep*?EtlPJ~H8>SO z1*bx$zG)SQ`c`Z5EjRWK(&T~e4(V=QNuv4liW21(D^W=A6ZDbgSZ~JT5zWnZcFhe9 zP2po@iM$V!Cig8F7={CimUb6_4M><+AtPwSiZ=0$Gq5aP;-)ITdH{EYZx~lG``r>qVNH^V= zDJX=$a@V^2Sp{^%xG#0mc`G}tu=y@dFE!FOj>+w>=H}ZqH8^y7Otv0%46mEK}vr!ij;OUC;CbUYzzs^l9AE=LLoI&q(y*SdjVe;OwWU(}DYs8^x-CK1*-8aSe5*Tjygr(!kT7*`skg!ktIM-m z-J%0bfyZ~Y5G&nHYLo8P(h2z19XaC87$w7+Ku60;b$bqOL2Yd^n}`v;i2>egXhxtB zD(ngfO75s!_o&tYo9+d`pcDJDOtgM=YM97-$+wzfAGzH3VX9pp$}QJTHes-AxM4I@ z$%8@Nbi-(fq+o&6U|(!$XzM_1cxk~qO7s2sSVZ3EU}7a{){yrIVnwO_?Zc;nS83n1 zSc0kG82@M0Hw^&fH|{b-WfT1Ija*dUq{yr9HP$!XPidCV548lEOmt!M?YS+1OLtZt z+MgPQL(pR&a%g`t*dL0XW}Xh|Uwue_+GkS`LB@|(*B;8BRtg`|f3yUY{Ar)eq3CJf z%_01Q>2zuktH`apIHlWh7pH_d?&7pyq*n-86fegen+lHy@Gd;qysUdSEj%E)`SD6; zCvCK*P^4@eEDjtn+rv;k+S8kpF_TsUt8a0ymViV1f%ZmqPPki#`hiWeJaiea4nw1c zn7Uv>?Nj@N=zdPqaX+W8!bkdmx-XFL>vXzn9R74)=UV$d#9(d3`o;J|YpN|CwN<{oaN<}806FmFAu}4xIyeMl zmI&5c@I5K&8^^)(HciWo%0rp%yw|63y{~#H{?z5csV=y2`Mw&*9aoL($*SPSt3_L? z!T4&xilt(glm^GWLI@hhFWM06h9j#hmQsrY@o1p$^lz$N+9d25E_mJ2I)vn1%6p(R zKXFghQgJbr6W&}M%}W>DhlQNe@c3>iVoh~VgY(r?5E4doV(#z*O>0;EQkdPad`P3= z`;=-bmezQeM%U-3Gwyh*SX%2{ihG^%(iZnl$>_nG$L1PeamN#u^w4EW^%YC&y-VvW z7h@bn_e+s(?m@TWkoCkflcS^cB-8DBQw2n{nA5OQ~(m`_DG$^@Fw~I$5CaweeU|Oej z@%Ld-7G0^N^Y>x@em+cGz2wA0W)PyrUtZf}c49xhHJrEnc^?S7Y#Liqnoh9cSb>3P z>TYfWEnc|7i|dO@7hE~zz$Z62TKI6Isyp0n`f4XW8#y(4pNn6W+wJ04<>F`G;YDR3 zf+MLZJTmZMucs-udUnLJgPRhW%vS7kgKY#$?Xl-A4+ec5aZz_jX;bQXFtSd$@c=`w zluvKAtWmgprmLjW?wzWk8?x%E=>{wxZpf-$LQ%G8Iu?(9iI&A{u{r8RT27qSaC?+* z+^VdTH*UGYYJy-9DkL50R0=k;IF@VmU{=fC4{OqX*cdF|hB^}wcWQaOG+2wu`?1JP zZM5YUcUZM2hWP-AJUB*l;!3SbVUu&wMSc0aNC}I!;qu7JibiTG-8`dp(jS|j9RBT` z3pRc`loXww+yqcEz|D2WcB2P$_`?m$k@Cl+LmjO?Rc^IUOu2EFlvz%z>=JQ@T!2Ga zwmqV;%s{%Q2P-n_Ylf?3CwEUc%O-Q$x&= zpaSNrsI45Xtf;D!?kXtA!}LdYbM6ZKXlIMH(pB+bpG_z+CP@`-i?s@)xJRx##l2d2 zFx-=s2g4m^bhlNYR=wHCE@9LiDtHHZD7b3Zq#LPg;YDpc`z|Otei#P%8rpfqG}gh& zfY#Q+e0GKgr$dR!d|&T?hk0>`O&_Lhe5e45AKa_~*>0N4)&0dG%Iq(X)8%1!fBSIH!O&+fbix=M~X2~ozT=H@8k_Y)?;3Rp{q3uC= ze;R$`*m1_AZ#u+Wh0O=Hi=)}uU)}>ng4k|xY`X0hhn2J2wRN6h;$Ta8T%(VVYt-TD z7)k|0foEJR?tEORythpp9V%p@Z)gLGuF`cRqy_iZJB}J0atZd%gvL}w4 zTSn728+vHNAe*mw^PUacl*0OShS?~IY&H?!kV?nm8_+;E8 zarhWmvO9^fj!aFQ522EW zQwx;1>{+E~cqN%Gj22?PG(D7~Fk~VHF{hV+YQ|edu|P;fjJgNxS-|Fx?hM9zo6^Hf z&*_m%r_D{tUQVsSOu8F+kHjMX)iTeSH8PA&+pSpQtzS~%=}4p!u`Jx(F{JPYw6BiR zVu<~z-l|O~d3rID_zsYPRLG_f>;~R+>hu%*v&a%BAB!eF(5w3l@_12)7{)*nlb=qI zgmuHVNA@_Ur-n}fbKTHjTZb-k;%8VFcEW}R23d*Ip?RZ>4j|-koZS5Z%$~vI^$$@k#7u%4D~*&AR+Hr{l5BXf)#8P7eXk&tS^Ots7jKh_WZ}< zfF(Yy&nk%Dy{S9nAdqsp*%(>qKsqA3V;M*3lduaNcw%g$gN&?zRq8+q^EqJsvDAi( zYIKm1WmvrfhMCB2%)vWg!#-y&%kp1EO23X6PxPd)MjLrk z%C6lkE{|ycvex(fniNVs~lTljbuCxBM7xI zQF$t~TTEn>u1!mMu#o(i^BzMm16} zA+M-ch)E^4{csMF?P3Eug$!G+!G9%*u`GD&TRyTsnya>6;gXaDV-E6Ns~dy?;-b3Z6D zu^+d=-*;`Bzj9IB|KMBOcz^ExgPZ^T*>8Nye_qF**^NUDaI(P*{!1>Mcgoq%zU2SV zmh+B&<>2f7p4Z=I|I@uC-#l^s`~KTr{(#-X&wc%*UpGu?AbGHBy#ePuG|*Syp3;+F zx_3dtFQZj(H!#dF?&9~z!N>959Wo*(BQ-{_!pktOyeV1#$LGx5!2Jce-A|DO&|Ci| z@KF*r5pUW7Pwu1fE5>gUepBUlDc;lYE5nb@2AGN8Z6lvLx9?hy|8p;9&N=hF={q-H ze&0@j{lEXS;XkYBA3Hn$y6}N`_a-zgs2kjEi}v7=kNoDGKmFip|7Gtj8+>frbvUo$ z`YdW|F2z%UcTR`Q=1H)d71} zhcXH9Ak!)|=UiU`8Z9fatVhP-n>CYJvwd}It2vnFreO)fhmK16I&|W=$;|rjg<2mb zJ>R6Jm1>~wV?YPbnK1#QW^%E)iA3bRxk90*=#^ItFC0FjFs^I~r24O6kHUL-vX>=* zku96ZQKNh0G(!W>yg9+8M24|}n5~H>a*fGE3b{beK>Q-o)WZY~S*xZiBJ1d&~vrI8opmapK43N)aX!x)O!mYxw zr9s;f>&KyT*+?S8)^Rfz>lLgh1F43&o7bycnY*7}U6Ks08VLtEVSq#-RLIP>NKTHEsL@G+sU+JA9y%r8Bz9>hOY-pU4JzKfx zaawNa<2)5j2jOA?@c>ed%A2ZAs3KXYI7l#vgoI_LqFy#x^-{D!J#>~5(Z*HX6ln(C zmfNTT{!}#)ZZyVgWxM+lFvvn>axpM_IA28?jmnGD{4h8&JgYU3nVJ~xP9)+eIW^VQ zzG{?|{$y^k*_&kjZ)lK2V(y3>HO15xv+-nz+ZIh+*g2?y_RvyfshQegp-qXW(b!N{ zuzAJRcH6O*Vp3514jz1+`fPgt3TOTt>_kB#4{F;w60A~NK`8iII(N!~Mibo<-w6jN z(L$gkVL5XklZl}51dN#26*4Aa(xzF;d71 z^5}$0nMFIP8Jh~?p+!kz+fhNkAeFR4yaQ#OwBf?(hV*ga$s{@?&nV6uW2T2n&yX0P zkZi4v-bv*vdQaKsiSj-)i17o}Eg~^x*PmB!&=RO-ifhbb6y?nc6h&z_WNJiK@ElBM zbDqQi+D~G$Eg@<8wN#5_{PE8w4(rc`j`09BL? zN=_;jGA*n$M}b0%-6o9JsH8A`a62bjweBI91O{>_aCQ$(sfFQR)`Y=9RE;HizCqi? zF)yO?b+r7{O2$&unxe;~E+M;_+g{cm5{b>SRK&Wa?N#KdB`Ei&s-3o#X3JmH6QmXK zI}{$`li7-p881Bq9f2g{VoIsDFb+S8qlm&L*rXE~5_Ao#d7^k{OuSC>H)WGK17li> z6rS~D#=$@a%+@*pa~Y4muZ7A|4`4iXX8aEkF*Blw;_wjf6|ZgN$q3 zPRM!$xm27*{xSh8szL;+N5Tl>#3MU9Wn5O^5}85-&o-#CNTi%hK^)0R2`F142ZV_F3Yy437Q`oX^gKh znh-Ho#8Is-BQi3+A~V;L9-}I{%ah6#ZurA2PC^wcE|+WA6~)lAhSwVqo(+@zt1RLQ zi*Qu2Cm6+POHCDOk|NJiZ9#27TC4**qYiFDQNZ_8vIiAUPzz(g>=d;6^sF*@&eUfGhi3yPv;Da23jNmv7@rI z8GXuVGO3h%!S39OHwyIbRLZ=5y&; zDf(i$rh&8}jve$vd<1I?OdUKrsM5T6Nw^OQd63a3O4&@nkLY@Ta#vq|UBiNf0 zy@X=s2$%6a=TeDAX;IcxShI56$5{M%)`=Ac*)%28(gsyMZCPyGjs%+vyAyma;#%J0 z&z0H1m)WvsgsjPwVWe|9!ddJcMJ!sOl_;|kkhoO?fEo&|C`9a3g|q(R-2^v?dr`#zeolWR$R|%&DNb%T_3aLRq z@bh3ij$KL1eJsBqn^0}4FeX`1>x3e<9C}2Mtf5)eZqU*qYBrd@k*tI^sSRtVnw#pR z&WL1SJkFj@GCXLoA-11}V9q7;I7DW@4&*4@;?nwd}!K8-=c~d?ChjSe4U{ z0TxE6Jy1Jo4NxwTH50M!KGL5G@omA-i6_62__|S;WFf!)LG-;S-NKwq?V+$GTjOrb z@=y__aVfnKFeBJ}#h~4$~2`uC#KKD7)aUlg?)iFB1&**SYnzCD+Rd_V&aIBALX?dH3Lh)QLbWGX12AT z6tz*Qm1&(w4PCF{Y!yijn;Gu8hH9mXJ@h=)%CZIs-Bu`tKtb4u4hmU!-_XG3tp+u! z7|s~n;^D)YH@xUV8mg%JVa^WtE5-DowSE#2rr9{~>hYY5KO5r7%n}+H(ZEF}7GzN7 zB30SrOUzbb|BMd}rm$t7)0PH1Vkerfod65TQC(Hs=emd~xk9x$ydoXEjy(H?Vx;9hFBWmg#W6wBf|_07!hy z(e0g=E;!$NE9J$Z`Jtdnez0f5;Yc=^^gNjaEgPd@pg!JV#XCHVB{5PCo(>|d1bt_B zpEPV)v0Y+@_z)S0gKF$?^UC7Z5u26h^zAl9RROimn0gYjm8UZ_138e`B2zj!(1XcR zGUJfR!1UHoR#-hE^?yNoI)?jMt);TF0zH`;8F2lwOZj}!^w4B)3YXpTm{iOs^6*4V z6wB;3mZy8sR?Q!c1$Q!{T|?R)0l&4_l8Jfa|6lkOXtx|z4~jzp9BTe}rehTUEZbhF zV+MlK+e!bi)0sOCGPViZVpgo>CVey84YMjG2(QN0b#(4iWIy*> zz;~uA7S7X(GK~JjbghFME&E{pthPcS6ivO5A1e%a834&ZkJX`RdYtGfd43$);m~4z zQOM94&Sd$&(j(9N(V^ze-`P1O^-4L5$MYvhC2QzQ9YTyWI9kMlNQqoEFi_!)cccjB zbQdncn&U&yb5I(yk*5Fykvd2(w_Y@wyxgl(o+||83NyE+g*Z<~3y;QmSbEFjOicZV z6*%02vEn20m&XU%n1S*$5Dnt=CDG_Be9lSIPGabtu#gEWIjAS6@fstZCGoAigk=HC zv}hd!T5y-59;cN%X;`N)^rA5XnllK<>jn4|Wp7j&?74r~$Pl_E%HhhPDuNIPJK1}Y z^$Vd0Sn?JuyBZCd@pY=je~wb2qu^&`UKCAuGnorRlx>5ERm>d3?t8jpDk zPrIBYiW1Eqh;g!B&w30Nseg^1GvjfGV;LeNJ^Z0B9Z;Mpp1rLIPFnF1d*tm3hs2!Q(2Sc z2ok{=r_s|>2Fvp@m{_N|4diVfnkswck!*rZF>y`_nZeF2w0H85Hfr=}b&4uOGFsGR zicX0qk2LuaXeaW87hTAj&JAo~Y#NebbrrQJ2%330(upKymFNhIhjHlgVeu0AP4#2+ z>^w}lJ$y#F=GC~E+i9_w&2v-(D4*;!bD@buv5^a=7}gFRvRPfELSRZ+I^iCE6PP~=7$cAGmk?kn3Kd7|Q;!2>1Rn)j67)wh4%&0Txz z?i+r0;uWEX7TghkarOXPte{x&DU0@?a?3*wox|-ip??_LY%U z9nsF!Yu4gU%@3ddk&kZJ7~9kh1*x|$dBNsX|3G^1LRg@OF4{7@_2Q3R^8YTqY~e}8e_-dX-9P*JgAe`Um%rNc@UMUK$fJ)v{={#8 z_xmTGdioE0pLzC=&;9Aof7$o^3x9p_Z!i7t{+Iv$%B%l)?ezoy{MQ?AzV-Gy@BaHg z@4f%Qe-BcB)QJ*-=9Q+!dGgx@DQKu`Y;Q8f`pzsR^p;?RAPqv6~yap=BD9Y@JS`?sHvGSfYj6nENFLl2z% z1n@QSpF(E3r*br$1CkHjV>uemz6S*#DhQ+DY#q1SQvg`_-mPiCQb z%>d3NlFzZD;1J(?B_CYl%Y0P2&|V^XXwT3-i8FT;dFBD9^j|{edBFKEWOkRIS>V1$ z=EZTN;2Z;-y%OhmDbFMl0uSwJqUR{!G{~?{I0Q~k;+!aP-15u@ubU;#hk!F$UhI}Q zCyf%;M9A}^#5ws8I3;h0^f6^v?mVTq?U!*s zGf(1_yZEU5pM!W+NSV(7&IJ5Ze5T8g<^rcx;w*OYQPNPUS}eozxa1KQT)IED$Vf>( zUWrqv4sMq?mB5*ee}!;%d{3nFS%=_rtK@U`A#ip}oO6LgaaZM#$~ryNCLEABe&7`2 zUm=|GH-$V6GAxybD(=UFPlHUKfDB9FsB~TkoK}gm95__pRX(YDN@;Pv#0ee(r%&R9 zSe_!@8^{rof2eJV_lxoq9tDTeASd~p$2bQM&XV+}$+y=iD!KwV_n^;fmGY=~DcJ+S zy`)=&)h79v$J=Xketf#dB)r(zn$CNH~qb- zZ)SvFLu++MVz&sIJkZp{tK?VSDA}*!)%?OEzbH>16z+@=G)kE1Y-G9`BKbE7nvvCL zlz6#8_lBSu1sW<3$u3<=Io1e%?G`lowa_#M&3-{MhWm8_wQkib2jMv)XvX3r@kT;b z67VX{VO}lAU7=CrWrDPZ#1PT`bxgUwUfx3wg@AiST>{nwsh_ zH)#3_ny*1aVOGMbq-7J(M8Uy|mn!xgKi=c4@q1i2Ht^rLTZz$yl@!@Kbr^`VT zgFmn%zmz(YXbuXRTR>A=+zr3U{PWyGnKzXDYAxJ@JJJCWp4`Q?^UrZXGvi7*zm%|Q z{O&N--E9n&o;HSZ&=4QSi*JE^=l~79PF+&FJ52@6L_wp3nRtvqdC^JGoDG`lai_E* zn!bYOoFMLu5;T*7xO1+c$yzCgS&6ff|CATg1x@Vgs`0`nei2QnpfSBxd!8;6H0B^Q zw+I>wXsXAZJmb77Xsm*U(u6KL=bkRmNR@)dRx1sYb_*IiXe9hqFQX`4`vr|dxTDZ0 z^#y38=RcJB&b_($0giR%2g^a=puJkyR$j}BncWtJ_Bh~_sBe!9E2uW(4+_& zg~#07C)uxdf~EmzD9lQD{PNCNFF`XAG?YFHO(1U!7BmfmxO1+caR;HP5HyWIL-}4) z+^-Ncjf2qKAZVHdp;;qnng*fSBxq8D&}d95i|;q#rb)RO%yb3gSazO z(4>Q=HhK35ns%U}`a%hFAg}II%d*oxh+j7dcRB>2c~H=F3_|m~py>n}3iGMu50l;y zG@XSzO1Yt=6O}Ey1NtP7%A{U`<{HpYUMTUQ{x)3{uRKAsT)3mqxQPH4XrzgPWw>s*gP>U%#GMBPO_E4GCBKAMFeFwfXvQOfYpXA|3z};MO-*fy_XW*$f<{T7 zIDfp@enGQR(7@nVQ~=FkL34c&ci4S0Z`=Ty+S*zML33jezmf&b2G9`y)RY%#g645S zqoiSAUD;01JR$t5Del>VCLNI_zZ4p`Kkm|CLGv)$V^kh0G=Y3LQPA+c6tHFQw4(mB z0|gC9vsGwU)?BAyJVUfA?+8LOP|!3M?Jp&+N;q=h`W1qvX$|c!3IowRENGew8pR!d znxQQtXwn4Dsd6bv(?wj_wQ@cyH2yL`Vuyu0(V(eqe8v5{+?I(6Lep2!NY~Zw*A;>$ z3N*E)^BamgqV1{hl)o;L*m1=jL8FxYfi!7HvW zprDBtG)kTZ^2WP@MiqqSu%Jl@Li6sMa@-SxgvaoQOk)8J$&(VEKptx?Xf75s3jg@a zen}cEXch;dnJ#Fq6*NkD1##yW@%$1&b6pUcHG*bk5Ss0RhOMrh50?nJkU&FxsKh-m zFIpd!(Eii4Wq}L_wnp;?Bi_CLsvT8bOm7gyt4OqXtcFd9hv4Xo9%IPRen2gQgMw z6rKnyThas#>9=t`Q?Z1exQFJu{mp<}=w%1&D-l449XV))+9>Fm<6Ne~z(+P}I<$VK zlVX(6@4%+Ud{Y3p-v__tEf#1!XW(9Bd~X(6C4Dq4E`-hqHkuR~cl@_sotrV7COm&c zQF$r01}n#sDgpkg}N9jiQ0_vgr^p?LE}4%i@3F}7ZjVPKj2ilg{*cW#3jMT{~EF=Xr`I)|tnt}B_ z_||s{UXH9N8A^%EHwEDP#!Q|u6Q}70I^1{YfYHi6rTE<&8%NK@K6So#$R2EHE=PtE zh3l+hPdHk)T3Gcp>(f7nmOf$GBGzjlOn4q#FdvG6_|4bW4#t+#Ge;Da78O+VoiQum zUEd6=E++e3vtyyH)KS zcP|I~W0g$njnii2#g;kcBe6;XS2g!CZ1kX1UzHOwPQ5nRpL%U`|mE6!Itx<=ByoewT|h#csTcP$B$sIzwAXypyvH@t5~pszNN@okHweRR;HR ziwle9VGY87nOIIglZz)U-zbNSVNYT%%eL@`6>}NK+C3;!^^unf%Vi#*o7o z*Jb&fgZ|jYYdVy!6k*545L}}aTlLAyH~6w9|I$X@#|F{tQhy)2hP6^vs$|-eiTZq_ zM&$Q{!B8ZOq#vAULTZP?v)!qkX?+NODmUMc&e%9KmEZW`4!j(rU6=VzX059%i=o|D z$$ctodFaMq-;YszOAfjGtHoX_(y)ph&SiKf)<|GEA^vG`C|@B2U5E`T zWsPP^OP`(`X*Y}Yu+UyUHL@ZNl{K?{upu>7c0xa|jJ5zLwdWcv_7sa( z;;Jq!&d_GwvUg-=o5!^|nAz?9*n0(i8S{XRJg-tXC!ldyeZDRY?|Y-kKlmYeY>fJa zffwzmEMF39c%$6rjH;CeIs<}+be94zzdL>!??;Rc%Ii0v|BQLFOTkFx)!H$&eWM*F z=^F|hMfCYI7dd(Hgz{ZH$^ML@Eg+BwWEcBuGnCG>E{2X8p#{#$=4sg6i*FrBY)5PM z3tO~xV^e@~dEpIK0v6M{l(GU;F4(LA^}+0E(_t35l{G5lK3|)XGkEZ@G5z{Z8rdgj z=%k_fLwffc0TG!q1M387IS-Zsp=v>xu$+?elb^g$T2_LM*KyFsESw527eIf-T}o>o zA5w##0wE&obDM8$Q9cPxHr_VNFDB1PF}|ktn+3BgO0W!+FM=mg!=i<9e>+oN##G+Z zU7f7_d~EX0#T{pp_}mY0s|Ht2**KB{?-K;1av`caTErypeZjTt(@EJisP`;@okVcq zM)?e!2w$W7e1o3i5;rB6n--X2!4`4}>z4yUPiq{I5}fAL^Nu5hdfknaqfLbS4x;OM&rb0S^}+Mv1cmZYThV4 zTF4YN#L&JV`AEd(js?oDpVN72qcG;5P>TMU8)#4Q!!-Dr6iTzgw=R_I)8+es765n$ z86s9MiB^qoSt;N91kLU~# zE{i^T3a8-)HXFxDKzyf}z_JP3JkTf((w^^MH4RJU%4S?hOJHZFgGI3oADW`R+~liZ zQASnSbs|;X=9H=-Wy@O%EZhv(?0`3GA*^B*HI(hL$Eo8Je6W<{N@>S}tnTT_O2r|YKKqwbww1iO36Qxc@oND4h$o>?JC-921 zhQ5Nlj}YvVA4;Rf&H2SG*YZ7RcOg-vv`Az$wnu!%<48NNPH7_!YnwtlV_+qfyb}-c zRxTPEO4v_nLtuRzMAgktpo9OlhRv4(a9(a^vBBfV;QZ?;=Tlz8D#i=3r$`assFDpW z8as;KVN9`2dBuF>i5!AHeR4;Qa*r5{Ml19EP9GzF4?tt9l<$Tif0Lg(fi`#KF!!L| zxx_LwhCv%*;5?p^$!H(|kWZo@I=VS)x9vuR#j?=;A}*xhV3AhFHK?wji?tD#Zf66#+pZmL*k+~Zh0`T{Yy)6BFAvraM4sHFLK z4YXHca9T?o?s|NWWoCSj#e8f6?(xvsiN&)T-<EgH0{&ow$w8uo1^vLc=4DwZh7c zc-EYmaM!?%c+gvLw=*m5(aeT>44&dy8gt;@3ad)uLFdA~DNDlL0ev|Y!k2=3G;4sn z3);^rd~@S&!uYxh^o?=1uqL=$VNV5jQ*pPmX1J%pe-Q-x5qz`Yer74-dE;ob(O z3Snr2dn{{B6UCr9zK7zH!eI)CE`zY2C_k6@s1wT6Dp31u5K9+UGeH`nC`*_wJ z_X(^A?t@rQ+|OdYaPPn}aPP=6aqq;k;8POI#@)m`NF_U~L`=J)ucv~G*|>LQ9^4CA zCGIG|qf~4<%f@{g^F$@E?W_{_x1jo*z}{ooxbI{h+}~%FxbMO=V*>ktW#j%K^WeUl zRpO2=U2FpTm}TR>hk0i#2tFgi5l>k*Gns^PC_Sx?rMG~ zJ8NNBY&y?N-I2Q{*FxgBYq?e?-;zH)eX@|D>7BM$ABM+gA#F%MV`guPlGQp z2(b#kb@=W8KPDn{2HYLs$3%QFfp!{VqDHz}aG!~os1XJm?rES^0}k9B;71MH2Ah5LB$qlQfdKWdN;Sx6H-_)){& z06%KjR`8<+T+Ad5{K&?=6ZlaBKPn|HLe8SJ2zfT{gTRkk@OUNegOPz+HU#{rWo6(; zEh`5ius7yPJ2ELf}-vB<`K6!=k#SXbgc9{i|<@7cH)f*-Yr z^*_yz80+jPm$B`6edB-b;Ctr%HEgy(J9tuAM&&8piD%`RTA8EiJ zF7OH*i+St?dECdZc`j3S46v|C(Da8hG(Hp~zL8DTQN1X~i`q84tw0F^yD&N_btL^((uh9G@8z}!^HlCT zc;q-08~lP-JjH1ap4J=EI*KgdGC-kG#mB|P;))ShbhRt$PcA9M3qh&ZSBS|c{Ymyj zRm;w3C7&tJv!)A>=;XKI&&WSi*7d< z(@mV&gW-fgFe<`;fuABUXBo|E6k*q2)Ix=Di*Mh;$A!UDe2%G{!M)jT?i{&B;U_L7 zH#zV3pk9dlK7i|Mp;7v-;9LxXyXCGPIYmrgOFy=HIbS6|s&-+0ePh4F9fLW|lss*xrm}#SG$;@PySwm(Z{*Y{L*8?SmrpbfphS{>qg+rP#dwk^wyJfW zi4Xsz4@xBb+;-(W`l@422n8rGMiDq9PS1fspl4rre82l(Q~>eUOI`X)q0A`COqx9^+SJ91|!dI5QqIB>aF+pHn>pGN8~O z7o2Lt$Fjr_8b)GC=YR$}`G&v!hUIc!Dg6)vIsQ1d2y;QRONokt#YcIl;Pz)RCHP+< zlKBvGD|BchjVN$_lMiYsp4LNV9!yP$efNFdR`;xW{#X6(PQ!RP5-ebp1RPhTT%dU1 ztZB^N(U29k(UIG?28uW?^iBCi?b}=4klT|{wa`%e_Ax;d4;q?hRorPS-02JFw+k9o zEi@SSl6DK4gj#6&gJ!>=Az`mcmzM^@jtH9QT4)A>CT6P~FNJr9iGe_F2AqY;pQ}g; z#_ovLCoLl}@i!8+GBrlZSWP zq#yAj9ev5^XaId6P*ld19r-(c;7`CyB@9(*`GJNtxPkW&qoRUYeamLlX|eFL+-b-e+dtQ4g`goQs(&;ax51syu8PsA-wWC>8ri59Ur9^9sYE5j?{CAU)Z_SQYU4S}G zm2?Dy`^4(c(z{wb0^K|{o&Oy%3e2~veBj%4yjmKA=c>vH+U{JOee&uTvVgQh+mv=A zC7#XY;~<#dLP6#~U@0)Qs4U|1_41CO^8BsbNQHgTu9fQ>VsyMy&dQioPzHrwWyf)9 zg;T?bH)DPF`i{tj8U&}S`TOuu!M_g-{(a=I{x#a?AyJY9O?NJ%IP{huPf?DZyiZw2 zD8ivVE_V%4Pg5-Zrrm0t#J}N&JXcS7_1FF7^Y*pS(_#m)tKuoTL~=gMw*QWQf&3zK zE`?X&jgiAf)|dxF#Cc{sUKR4}xMHVz`-8h0;3j=nYIR<@2!cTSN-ZDw9r}%A6}r{R z_#Nt3>TK~q$PAqC&wM_LLvb0On^&ckk7r*CUwjv>dOxkwHkWCYC;r{{K;Qf=b^a}& zcfl|-ri^5eFSKS*x%_&kN*@JovGItYG6q;!R4`NSxytj}IK+(9HAyE8Z5i~RX;PcV zuxfvmt5c)J$=%}L(E!5p&}#GcRr;0Cu~0geK6MKORgNeWeCY6K*%@CuRj439l+bjk zSq-CVzZ4Oy+DetvLeXCc%pm1mU?wT=l#EiIxjm61$~)Ne<&pAEd7(T9W}NaaF!Qvv z=AB>Hm-g5Ty!`p=r&01(@k60ko_%EzDLtX5iK9%!`Bc2rDWu(4(|G}h78ja5L_e7Z zHi$lre@4y}@^Pm$+E*UGP>;Ye%4{6|SFJ`tIj#5%ov_k2nNYApZ?A2^9H`DrqJ6wG zaXu|h2m;ql;>;!j3_4QFBfSgJBq_kym|yis483ucL@4eP8}d;5&H=!HL4L8nYNObR zv26;!PmiVc^boP4u6O|{oyjslohv?0M@i&LQD;3Wn5E=MVC&4b>=I$Fi|XWQp4py#6s0L|oY{#bM$2ZVFw3GJU67L5mEAAQz0qGh?8xlF zEHSbcjEQ~VCT(U8>n+TM!rT(OcyxSbKNcG&n}g!+>M3RBvK7MI zEzCyoc}suG7{bmI=0;)0sO0y{c5BdSw)k{)cMG$)=~?q$?zM`=q{`-rOVaxojq;$>xJ;ImWAd-Oc*9kj-y}xum81+@jSx=3%|=W7~vT(prADv^i@- zlU@(9XM|bMR(?)M-@Vb?Yc1O#%n9w}=h*f~H@?~P5w>2K6FWQ~^FYt_ETN-pZW89S zPA0pj=LTl$ESs-)UO(Q6=XqUTy*9b$TGpa#z0yXk)I+2bZ= z>HhJuojq2twcWQazoz>V*1bo;<`dl)u+2S|uDrI#MXYzv+qT`)qny3abM4c&^_a!l z^;)v&0WFKkxayrdx{qT;8JqJP^c=xn%y>?h-*YfCWbS@;RL_2FVrGvG zSN6TLE!C#?T0 z==}&?PJcbXcPfVlXn<}s>EZI}0IF?jXy0L`m)F-y(~fIamePn!d5c=k6Q)!W9marz zqp405dZIM!BZk4K0g99J%H(=pv`#QIMs84e0?xUYBZ)CLEIz6d2PK}>YkeAR63rm_ z;I=BqWy|sXyJ4C=hwLe;&P7-UhpzMhmEa}*kte?6cJ=weMRBAV6s~(;yo)^pQsMS}I>E1NkEs2 z-j;QzbJGnU=6#xV^72+i1FXNxbnHl0`MRE2kKg0Y20gB}**EpMdgiwmrDu2jWd7Rc z-cQe#{pp|0KeOEI?=81KGHcHT^7HEXvia3R;`_dAL*;`XzxnA;eMI=56VI<`NI41@ z?U_$kECio^D$h}(AW)uTs(qKJaTY-TckRbQ84XiiKL7r%{gC}f{3(h`{QhbGW5OK& zxO$%dG4(wEHDV*Oc*rryL42&d2RJ?BCyNJvYQ*~lm2SE7LQ`H$x&`0k58o;wmf!b>`* z6do$nYxN&=)W)LkKy5BmYR(r`Gu6dl&kS%;5QtXI3r$n+pFtM2GLBC#d8<5#LDtUzPtut^Y}|DL)kcuU`Mt2Os}~HdOhqYxO@B zq`vq=9{=h3pBid`{-;8MeC1ya@}K=LmVc`Mvk_*B4{v{gw|J94;Xm-#zpeiF1g1a2 z{$H#AE33(W_4?m)hULGm)&HJq^6!THMe2XK{quMGf4uUi^!pdfe{%{SWP-QLuhaEED)(%};omI(X@T-j{o}y=uR;DJ z{r|rw|8=eY&yLjp{{BaZ{l7^4|L+_BkM#fL`Uu?|KAzX2TKOO8|I6tE(GPk2S55Ul z>eRYa|3~`&XDHj0$ zFvk(;|I6jc|Lgic8vl>X|NpD%|4Njdf&AZEl&8x2zli?7oIXe)#Ro1`#*XRFvWP`*Xn1%F1? z|1;(xIfXo)>G8kn^?zjkKY;&GR)o6$M_pV07n%P*bNLUE1P$3LzAR|%P>@)%8SUcW`=|B((z6Q%tZ z>Ho|8fh6JS63X}wul&g!@LP@LA3O>7{9k>m|0~7#z9RqC$NwvlSCn68BLC}R{a;ya z{QaLE|E~<3e?t9`3iNBW?! zKsIvy{7N$MoDGxS|JnH`b#44VJFxsiq}?K(6n`quBK!aU_54SY@$26#|Mji@kIer= zjv?bHy0|>IATyx+XVv8YpRWJ^Q~iJF|3%jS%luYj{|EI+r2miffiTuK|JNAu>1+QY zz5c(?|M66le>as62w$ZBM?RpOtQ7f?Ez%`e`wt}iiq!wLjDLWsBJ=;jWSB`Ws7@vq4IKhgtf;>-U?|DW^6nP~qh>;F}l)1>h)6>g+YK+pJR zDx@{}6Zjpk{NM4B#)SgESGP~)c;NRc_EEmk_(b6M>h^>B569s|Q2RmsNB^GAUp{UB z5jYxm3T8j3|42MKCq9_{|JV2<@k!tOwEaH=`A=|6=M|GF&yRR3q! z=lUP{-#wi9kMyVUozv#OGa&z@-*DRg*LC@i)c?r+@aBJ{{~tp7p8@&r6z2R#5qSFL z&l!k+yHNbE>-~S!f7vJl!&&}^RsIqG*5S;5_}?@X|3l<|-v7XWYdG^itnweJ|G|CX z&Hu2AlZ~Z^WKkYAf+VXcMHi<7|1(43zq(%kqyDLc41_cP!z%xXf7@{8 zKm2bNivJ;&e_a02_YY_ON9z9&(m%xf2kY@GocSMC`44yf59X)+OHVufL(G3#|3l}s zowomVz5Yl1Z6U@#r2b#H`~Ot`qYWC){12=A!}G}ee|YmhQvZjL{vnqCk@f%eyZ=w~ z-;wqIA;@1{@BdTbTc5}O5&y{g|Iqk9GX5Vt{ZK_$XY37ZbMpNBW0z{Xf_LtIzX) z5Z;LXe`x$4YWpv&<9}hU|5g8j`F~G+p8rGr-#(n>|G!}T-vb#4rT(ka@{jy)6VCjH z|EZz)A8Pv_{#QoU|A)l?b-Dcy*5g;bmH%+p|B$~FJ#ApKi} zlKypl{2%f6paKtP{)e^wADRDW*&*_OsO>+Rf;w&f3$gqo{qIQsKZNu@1LMD8mH%+p z{}7(Y`u`C4FI4#l^VRqD|FnSdw9DVRF8^r%bPT2b3AOzP|C@y3e~A1~^N-n){(ngP z5Ag|VA6Zo8du0A!P7icBnF`~d^}7Ct{3TW6kAHIiH`@QNXDI%kf$~4B?SI6-QHb%c z%kp2}*Z))fM+csT(*6l4|KWeDQ1~y@`XA$ep2+(D@a2D)=l{TZ{0fEtLmmIA*Y$t6 z`~N6^x`G43ng8Lg|Fc4je@NwjnB|}L|D^*w!nq<-zCKOhdTZfssF=Q{v+%8b=vjM87Tk5I{z2u`aj(3|4IHkfdj&s|6!GX z#J^pL@vqbMKjNQ_2!u2L!z%xXf9r7OKm2bRivJwlF0^?m(+WqqFiNBg@2O2AOczmVF0@V{{={)gKCN8wkAHhd`Y zkM#e8r(dN1Up0NIkAH-9{4d<~KjhyPZutj;)?4{U`ny9(e=0lw#Qwio{_Fete;R+w z_>=rY7FUsvD&<$G`49hFR&)QK9RH*J|FaRHdMp1B-pKmD@aBKLuK&Z_|L5{wpU?k5 z`I{L^`5S8aA8!4B#J>_{U^vVFu*yH;-!`225C5Bm;{O@w|7T+&Hk|n%*73hc{SWR7 zZ~li>{*nJ-9sdXON7ny`z<(i@e=4MZeP91y8JYhNss2L|64ZXs@gFMu{=|OJ@rMxk zKN0?ChvGj17a9K#A^*eN{*SEx4|Dw==KjA5@*i3MA6$NemcRHIQu!Zd`KR&!$ol^< z=0DQk5=#9WV*O9;UuP)(N9zANE&s@ReuZ=Vr#|=pY5h$la^SSnKScTGQIP)L%Z#dWgll)iK=lQ?L_&>Nmyybs=uK&Zm{-4W#eV+eA z{og)B{;$*hf5hK|2!yl!7gqU4{M&>x|KWdXDE^1q{)hjSk@f!}@qb;Gf3P0E>aF}E z^TIm+5BW<$4xD!ShbsSwd^YuA(FQ;_fT?i%Tl&ZUf&PDsP}0Ay_y56vp2+-vNcpN^rVf2i$0_}?TH|3l1wnt#lW^#4QR|B%{$Vb=cv>+!4J%73`)f5=}Fa^SSn zKScSb_0K&+@xQLO{}KO2A;!Nh%YS`e|4;QF4S1cl{GEaNzf~yw7oz<0`M=2e|M2C1 zr2ePlM^8WfL*#!|xa zYWWBMJBQ+bU6+3dZ)E&Gg!=akP`6cuQjufVo`1tM71FnH3Wiu`;DXu7(=`Nfx zb!t&rQSp=+#nar4eI7J+7nfAH%V(FCmXuW#6}sonsF?0fEo?J+2HqCTDxFzW4tM&` zEGeiUi=`zqiYxxyy1THTqQE`1q-<6}1%>19+OOt43k>g^f|;|65X7nhXDn^Xl+^Ny zvKfU%EgEIuFuCa^WjRx(bYpm()}f{NB7YL!+S8Gn{ClSwzjvf9$@%xmrR7y9rk28K zd@GqUrCn-S$=vc87Z$l2Ww_z3KM(pA`SK27>5KHIBYt@}s|Sd}o>nao!VV7v|6V;1 zaBFHQIm_6v*%j`RsqR@tvr5Y5y9;K{ESVzbSL)0{_vHB%Med5CS*7mDvxx_=(Hh+I zgn{dW-}zn=w5$H0*^#ofcwY+n31saTwtF8lAj_IOwq>CcA&Zf`?bYFssq=y&8FP zITYX*wPx)4RtQf^#@=kf*sp2GD_}A@r)!!q_CqS%1Xea>>_<#k4+EZVjJ@lDm5mT% z;Bq(o2NqyKWjt^l4pwdeJPHNZ9AGyNy1D?+0S{x+YbfwDHov|F$N>&uA^NSrK;RDt zXn+F10laHxY$?zWhypgF(Y65S4a5Rlv50OtkPoB)Ut>}Idf-B!KVSjAKtp>2umBhV zGy#6Y<`-LmJArZ_7ib9lZe;8o-~nI(FahWc7=Z&Q@wNi@16Kf(fgHdMP-9}B9y;~F zJ-|X>Dliae1?YjF(c%0Mcn(+%ECyx*BYMPpbyXvXaHz{qiFl?2R;B^1)c!z0agMFfKuRGAP>j} z+5wFKBM=4r0$KVB_yBkv*aWNvZU>eF9-s^;0>%J?fDE7=&;+mn)c!bu2IL{&D_}RU z9iTm_o&+8O?f|X>76TUnr9dGt9vBAn1-b+2KvTd4=z&<^7)0?9@GYU{DuIo_ zBfuJ96>uG}1h@>C1Iz*nfeFA!U=Yw7=nk|8(f~K$01N<)C6nkML7Vm;`rK zTY=5Mv%nL;I$#ZO2XG^>9Jmtj0P}$|;C!GEI2#xP)rAD|b|1xN>40F8lUzy|1n z1RxqX5eI$-4guc-Ujv^39|1dow}3Z*mx1Sjr-2Q?I^cd_HEgfuDh&fCIq)fNy{=fqlSU;A7xJ;C)~R@HX%! z@CNW2@Cr}~yZ}54YyzGF9tYL~j{s|d2Y@xeJ-}VS?Z7JFX5a>3C9ndx23QJQ2`mCG z2Ry(fz(v43U=C0YTmTdUGl3bvG@uBW44ey`4NL&W0i%IYzzAR%Fa$UY7zp$S`T{vX z7LWn-1iAxVfKEUMpdHW#Xa%$Ynggjo6QB{$07wR0fCI1r7Qh4;03DzK5&;zu2gCqT z00T}&Gj<#}3LF7`0}cZ}0|$X0fdjyIz<%Hx;49z@U?1=quou_^d<1+5>;iTI?*Z=u zZv)$bZNOIGb>LOt6<{+^3A_kA4?GJz18fAI0-gjO2Oa|+1s(y`0S^HW0`~)JfO~LSP;+ z7nluH0A;`hKnYL`%mmH{W&qQHsX!4>2uubFfJwkPz(imIFdi5Si~;h2QNT!GIFJVn z1%?2Ffk8knFc9bu^aJ_=y@4Dc8^{DQfL=fkpgYhF=n8ZOIsqMl_CPxz9cT-*23i3v zffhh>pc#+~GzA(1jQ}^$5NH4-14)1jZ~}I~23P?LUg85AZSY5wIKh5cmMt1-uXJ1l|L70Ph0t0B-|t z0o#E$fo;H6;0@q);5Fb?U<>dH@G`I&s03aDUIbnMo(G;2coya}z$RcL@HFrg@FegA z@HnsmcuZhD%twJofQNx~05$m^0v;520OtL`eZU&vUf>?!Zh_S>?*i@w?f`BFZWCAq z^H$&%;AY?^;6{NPU|tWb1g;af7Ul|IIdBcIOyFvmOM$C^B?4E%TnsD%t`JxV^KxJT z;1ReC=B2JQp2gnx4f|)6h0kfAtPnd)rKzD&| zFbQ3OE&`olb`t0alh6TZFVGGqAsuKd&;}-6y+a8_CJ>lY-y zE@kt_BP(R{koLn^MtWA4!Z~oq>&er(V%x#+g$_k8jeZ@8J9i9W$m!O`BnAF!j8~ZAVS)Go_$ zx${S!ZERRLv-i+B7dA?teNp?YDYHhL!zwP$8D?-#E^b$T$?!?pWtSF|W#-X&-NsUoF^s`-`}E0^U_vInIYV=)nqcU^LR7@2gN96_z4S%sg{#{n>qIc8{qA+8K z32vf&0W1OFGTg>@Km}+34{!yr1b|QcBKsbI>?!W}?N<%^f@&9w=YMf5&J#O2mf^25 zW>t(QW^_!a81(V*w=epQ=#A0qqE|$FqKl)aMURf|AKfXsRkSM_?P>fSjQT3-lc;y2 zUX7}ZdOT`f)as~JQ7fXZjPgXyjVg|s7BwkqbW~o{ps4JqUQwN*(xX~MHHk`zvPBu9 zP?zBEh;&%`QQ9wkDeaX$l6FdON!z3?Ql<2q^tAN2v`%_Zx>veOS|!~iT`#SWmP(6} z&K_yLG)F3vily_UY0?yFk~BdYjlVo;h%`v*FZGeKrCw4usgu-RYAdyp(xg<$Ej5&q zB!^^`Op*b)l_>&GreaH5*uh$YirvC)VmGjr>{_;*UCoxVE7>Bp z5IN*wm#~Z2d^VTOX65VxR>F$e`D_N8#-_4DHkqBv&S4YT1U8P1#@|Rbg5|LxY%m+d za@hdZkM&`_SvJeU`D;B{cW5DYVV$rRt3C9w+OpQH6>GuLa5hR))&v^*Zq@+%BqU+4 zQU~Vit#IKFkTg_k4=s36gxEb?AUUA zc{KKg*qyOo#2$}T$2E#;7nc*47dJI-cHD}%JL8^=dnN9txRY^~_$Kig@q^>VZJ*e8C+NgR{wL|r>YM<(R)gjeU6-$_>x>R+g>KfH8sykH=s2)*mR=uuzSM`DF zbJe%1gR0+D`UGo2gM_9D=?R?^G86hHj7>NvVOqkhgn0>~` zVOzq^gpU$_Ncbh;ctTX7Hqo4zoY*+AXJSs`pv1hy35f-X=OvaVUXi#o@%qGD6W1iJ zO?)EpnZyGLKPMbZkPFzDd1a{gnDe z^%nIz>Rswj)nBQPs86cnHCl~B(?HW)(?)ZjdY$@7^|R_%)o-fbSAVSjQGHl_LLIHq zX)Kx)O%qKoO>fOvn&Fy>n#r2;H5X_WX|C4XpjoB4PqR+*q~=-84$X&}eVT7Hhcv%y zm^M!9(z>-RwCUO&+H7sEc9?d$wpcq?dx>_5cDeRu?H$?;+Kt*u?Q7Z{+7Gq+wBKl% zI!>)uTh(rLGj+PUvpQEjOg&b8j(Uc=L_JS^srqL19qRkl534t-Ur@iM-mc!K{zmAM6LNh^ApqZ_?NOOf|spdw_ZJITjwVGEnTQ%=#c5A-W z{7>_<=7>h4HEENyjkK+`9ke~QIofA5FKOP;ysi02^Oa zrR%L5q8q83sGF>t0~?EA<0ja+4>q>ww&`~2KGJ=q`%d?Z?hl<-Z`LR48|&NXJL-Gs zd+W#PC+Vl_i}myMm+6=2m+SA*Kd9fJ->83C|Au~t{zLsi{cn1&J{E0lo1vj0)zICL zWf*7}Y8YpjWSDL!HhiN$p#N2WOdn^^7_5dQL%N}}A=A*;FwBr|ILAL_(2dm<=%(q)bn|ozbXV$b)7`CGt9wlMoNhBx=3U*lx*v4E z>5l8-^;*3RDbr5hMW3bbr_a-mM#>cFFV$b6zeaz({!aZG{UiD(^snpR(tn`;ME|Y+ z2c*n#eTDu){X+d!`Wy7C^!Mr?(!Zd8MZaDDo_??XOQg)tdbPo5a2ec&R)+S59)@hg zD8qQe6vGTdh2cV^%vFZfhWicc4Nn;=kuvWfW&UUQ$#BGQ(vV=(BV`&GyBaf${f&c- zV~l4Try6G(J;uex6~-HltBv;~Wu7wbH~eV$-EhL7GU|+WV~VjoY-Gd6aM(B(HZC(R zGA=jXV7$wCpYc)Slg2lUZyP@}?ltZ={%HK&c*1BgxlBz=ElizEJxqN}xu&yCQ%o~W zWu{9^3r)*RD^2T68%)odDot;ic9=dk?K2%V9W_Op6U-K~%iP4=!hE;s0n=lqr%jtp zubbXAePH^|bkOvN$!kh98_Z5~LvuHCrg?yQh2uEb{{MmF8>BH<|A?KVW{$ z{IvNk^G@?8<}b`Yn13-JH%D1)mSjt+rIn?NrI)3j9{G%tTr3XY38=(uI3E$K=V-Z81vcY3(RxP9`j=J zb>^GRtIhYDUoyXHe%t)M`7`s^<{!<6%_@t|Vz;DN(kyK)T`d`wr_9fpx0tt?cbWH? zzcPPkK534zXf0+-14~m&8%syaV9N;01WSQsrlrhsk!6A9M$2uMHI}uOr!3D|wpg}V zKDT^pIcWLKB3a|D2CL25(%R12-I`?`WX-dVvre+kvtDYw(t3^c7VDkX2ds}+H(Ot~ zzH9x!`nmO6>p|;p))v-uYd34AHP<@KI@WrQwG1{Ez{X10xEnSqt*=?%vF@_&vwma! z$@;4`!KSx4Yz=HJZ0WXcwoF^TZGx@PcAjmv?IPP1wxzZ^ZEI|g*q*SxXxn0Y%eK>Y z!1lB4m`$>4>?V7Xy^+1My{EmeeULrhKEYmSKhOS!ZNKf1?RQ(0U1c}g?eiq{BN|pV0q25-SVMjujL!d0SmLnS@l+{)opEtlCiUOsCAU}Z0i(j zv9-c_iFKj%X6qf+`>hXKH(Fmn$++G6rS*T-pRGr%(Y6Ge2_<7|TL)WDTaIn8Z3Ifj z0^5Z)kL@bk3fn5%YTHA$^|n`RTW#;zcH6$R{SPJM5nHKkj_oqrBHOjLn{0R4?z25( zd&%~O?QPpfw$D&9{%DK0Ywb3Bvc0*zjlGM#mp#uu+CIr%WG}VPLCLtte!Kl1`#Spu z`|~In-$cpywf%ehVf#^gtV4~G(dFpq=J0Ea9;(Xfqyz_PE zTh0%hpEwUXe{*`Bu`Ywl=4$9lb=~2-*ZHvXapw!pSDf3O?>WD59&rBZJm!pZXnGO{*GZQt z$&u73sd-X|q;5$$NduD3O`4iik~BNXle9Q#MbeE)4<)Tn+LZKS($=JRl6EJ3nsmf* z(h={}Ivvgi&gRZG&K&0eXP$Gkv%opcS?ZkQT;aUYd8c!YbG`E^=ZnrQ&fU&Wo!>ft za2|1Bu34^f*Tt^OUDvp-cirx~$Mu|Rvum5{UDqDh z=dSNu2VF5qiAm-pXHwIomPs9xx+iULZFE(-UUThmedyZf`o?wC#gY<|^hvHHcT$U_ z^rV4FLzBiNot-p2sW@qF(j`gPCEc8~I_dtT4M`i5DwAGI+MD!c(t)I(lTIW>Cu@>T z$<2~mCwETnncP2laB_a~gyf3k3zHWnUzL1A@~Y%}lOIZcA^DZ$?aA*Y?@j(P`9Si| z$*IY$k~<~$NbZ+>R`RIi@yW%oaS3cJhmAX6x}6H88dzuLp8URdz6_sd;g zdN}XWFOPq)!|TOQY4Q>8fiL*arxyKqa_@KERd_pe@wVSzdy>;i&-~&2g(y9qO*j4S zJ+P1e98$d7d*B=XQz|;e|k=Ktw?=kdJOu$?j*ygpp4?p(F9mn@debZOId*cIp@9}=-k#0QX-MfzmXVW#`o%r+<@9S`E_>`x9 ze(c3Rw&A_BVE>5^Uj2CseomSH-qEeEdAEVUKH=V<*FN|AdqnWYZ{F`@FK0b|$ouWD z+_Bb|Z$0r=CI2a1@zb$AJG}S7+Br);Klbs9{H?9<(O;jvoBJj`{fBq|_xSAbT)g6t z_sj42&n82jI<|SI_bog~cOZSg<<{n3^S$@;FZs_lQ=UKe%17RPL?9jW?vlgsrgVgV z#oMc-4c>k7+Y<>#j=l4)w-RsHYxn)K`I$dn168hZ-QK&OIPie?JC8K!_Y?1LE7aqsq^&XZr{! zNI|b{j$PkB`_dWNC_lZ2eQ&=zc~W`n|Lpbt z=6n0o3E$6?Uf)me5#P^a0dEzjVEU~c^Lr8K!pReg#iRHkob$OF;8JZrKk|S0{P-b+ zo?HIz=%J%0gztXWKJ$m+#}oeF{#g9sr}aCFSoj`(uZ6((+Lxq0EBuGwGrwC^D3A`~ zf>bD%&sF6`5cAn%K8xQSJFM6|cI+2qf&Appiv#|j$4>YY!XL`G+ro{Sxq-|L5_Oeg-}1%fuu8YyqDtj(Lyye*NnI ziG)-<_8#+jc0Ay%|GU@cgZB@G>B({ch0g_Fw)$MJ_9MVjz?X05wHsG{!Ms~aZ+Rm7 z(zSEi_Mf!A--^8a5d&|V)~!e4x{qHlYHulX8SicViZ$_(`Hs9-T$!!2^RFF{*lgXd zYa6@Pw(V+OvbxdR1F|ftva)wI3119PQ=j|vs1!rf#T&<6HM!`#`)(NcT;b(+l(^5z z>pk^>DT6Z8zVo!`obdReYh0@H2eopo%)P(8{f?YwGgf!()Uez$eV8WcBkvev{FuH2 zT95eM?hcr*lU)STl@sqO~+bZ6+H*R%*?)hEZu8z|1Rt@_)&$DH(Yx;Rv zW3zSY70(+6Uz}+gIw`+5LU6qz*tyr<6ar5=* zdc(%XpS5qZv8}Pu#<q*0y6c?vHmYID}Gi_$xKhOd*l8)FAd?cTXX`(}-_^SkG|r2H0%eU=U>9-m%T zZjDNu>b>6{SCnE%%=Z*+adkH(PMx}|v8B~)i@xc-p1zW6YQ})n#+@7fQrWN9fM&UK zlRr)E+s4yaN>~57F4Ji4zcRmTX8+VysjCX_&0j5LB}`nBobBG4f0jNWA=|rYu3>as za%{HOc|_`_GG1|&w`+x`hu$*c%I>cDX=^$(ylT}VXOoXRPHVkz;YAJO?i`(#edP`N z+HCaLT*ie5SLvi3Z4A~4*`LNsuXeLGzpd9&`_x?{HQFwf-oEL{`L6tYkH@`ook<;^ zb?v&CnBSTtC9ZsQoyO&PF|Wy#C-W}t(kB1X^f8ZhY+-R1o#nZD&dLf;ezz9-#}4GD zCS(q1V4OS0Ycwq_YSwFM*Z!?s%U3ovH(2K_NU|(#laaYc8vcB?yM<-;&C4y;drQrl zj8{DEVjRjmcTIEL9UO*)_*l}+p{s8;v=leT#Kp#|5);%hm{_k#mq3bQ(KMeOcy%2# zB)M60?g+nmN*N0TpW>xyUh#*S@hX3^Mi6NQ$?!&3{loBcl|PmZ?UDc_SGyWkyJ8ww z{lnB?mA_S8tNy*7(r|FDz7)e>rD(OlBJk<>|Q0Q5~89L)$~3l zR-+C09u=!n>sX9RBgH0Yqv8^E(eY}%|2rcE2t6ExU5(cZn>w!-->Ze-6z~6pyjp-y zab1MBYFK$ts|U^h%wsA)%Av0D6MtFFB_E-mqoFe*9%Pf$b?A~!51-ff-xqkQ{vmZJ zg?#XNK<|*&%JX0OEof!mVO_b%DZ0q4t_G&BcE!iVktUj=o2IC%DJH3~1-k-8|8#ys z|K+92?t1C7%U0aA{-t+5`{}YPSKNHp1M4@w^!hs=e)jE8zhAcS%BxpgfAej3-TT10 z^-pYk?xj~=fAgK4AMW|=%WuE`>6hP+UAAE1qARbu`kEEjU4P@vx88QgU3cGm-vbY= zdu08FC!X5)%yTciwE2}+U*G!XTkq`Hx$DD^_U!%a^Dn>t_J801@YA7Re*OKAV<#@7 zbRxAG(tM!74k+{R^9-|K(nm^3F9^IK@Pfb#0&hbA1YQtOQbXi`XdoWY0}X*J;4%ON zxFYSJNc$(!{t0jUhe_V3lhHA8Ct{BuI~xCo>d5b?o&W5LjB7^5H6!Dik#SAY*gD0C zjB7^5HNBB>O<6AL-?(ON^QD+Vr9~I=stbeBXfj(YR;$fsw>z9pS5k6HgNE)#jhi%0 zO>NdZtwqaLt=qJ1o8GQ{hmM^(cj?-#dyk&IGBUHWb9(pb+pqtCfw_au8a#N&&|!JQ zM~obmKYGmAaTCs-bnfKBqN&r*n^|01Rx#(oi!b$De#PP?OP8&t^Wr*iNPq9 zq=h!WT}q}d9lxqK?;b)wE)W*<=>pO1b*u{vz`nK;3j|*R!Tfi5xrG1T5NR0rhoP4$ zfBP*DsRH5n{vlN$s(#&XxoBwBzhz6S{#CW@_+G`1cmpApG@y?w_fm;pRS74(iE83d zjh3G1_en23>GU)^Lx28X^u#3Pef7bBKGm-JKAvE-I#aZ`CE$i(GwgQrCu@UZup>gO z0ZW>&x(RDwuo*&}Dozt;h_l2w;*#S$aaY7OgH&1|$8Jce5i)JTJrVBGs*Mm8y?n#nL8Ts=kKxOz*Jwd71hJ`-XjwwNHn6nHnX!cb;O|f#Sz0_68 zz&4Q_obUPme&>&K_Ud`RyY_4Ez1I4C)*e4=EjP}7>RWd{|D{j8ZT1si&;E8> zfARs23qSFlcJU>Am;Kk@WdG%R?7#UI`^5V{`Kj{cdoS{o#TI|+l1nZ9^k*#ltmU7* z!gE)8-pVgnm?0W!2Tzc=1|mue+Xa=>PWRU%&rC3qNJi#g|y}X-hBjjAuS;xo1D;xhp>J`7e0k zi&kBIjWyR=XWjKT__yyp`^oG7x68laLjUoL|HS)`9OaqE)nDlU;Nt(|`~Sx;{=a(v z|D%gP`-7*xWzTuz&e>0V!=Le8ZXrMSJn^Wu)%`{Hua-CemkZs({(WE4|IckUwORZZ z^9aYwhR09sJ^0GtE5mJuU-1)<=SYgZM!%ST-OO6EuAkX*`mX6?XT5n=i;Jfg9xpRq zXJ#;S-}LvVkD0!E{CUqn^YGxn>2+pSoIY;+wDCMMyG^e$_}Jhr#^(-xHa>QA^yt*_(W9jXcg6uz+m9|B?=gMt__pz))4!Nmeb$9j zcYD5`^G3%`Z$ACJndPQGJH5mB-l@~4&Yik`{O#$%c$w)-hI3}knNM0c?3o9K+YfFV{B)ED z&l{ETyyK6Kmm8clym#uZ!6Kut56&6Ac6yQV7sp$V=No)_YNf$^1JArQeev++)4PoJ zp5ABH{)3~YcAfh8_@y(ajy^ZN!|24BMW&DS=*#=!TQf_{I(+ot_>$pqGbhYiWiV%W zd8EI2kQGJa(|{a5Ok+c-Y{h!(~U`^S199-7q+QSf(BweRcHbspn6B ze6;4wpT={iW`-+_?wr1VzK2II7=CB8<#_+W%~NL$ZN$1bbQ0$ z_Te9gza4BgJZH4dcroX9zQ^aTI@(~c_-M{}*WnVQ-A6we{e1A=$ir`q?;3u7=0!7i zjLXb^)6bt?VzBDe4@XA~wj1v}Yu=gn%-lITV6^Jg^x*x&%|{1}_n-fZ;}u6Mj<4_* zR}DTjGd1OT$7ao$S$O)Hqn`{vJ>?mHMhChki`jGYj6X7b>S$q)8opupqv0{5Jq8<% zE}Uoi;ils)rrtAn#q_sF8_d7q_>SRv{R&DdY3UFB`2nydjnyEkAnG_|Cy4 z!<)yqkFOlwKYhDra9C}4)bO{%J%_KHe${x%(PnO^`wm_`c*^LZ!5@Y{8XYx$`uO| z<=^r8!vjXoA6)9SYmL{Mf4%V^8CIC|0O5x3soj!z$bZ?MVKgM;r6-!pypaFN0G z(|eEG_=s6CxP9vO!M>xDMq3Rw^$6Q7r@uH_fAGn{pQk=QbHZqg!OGJck9HZKHS?6= z;;!vW2M>FE_w4E8M^`$&f9&9aVI8bF+Q{RwzcGF2c=OR~=ZoPzqxA+C&s;gWH#VH_ zUE_y+Hk~^4@!~O@XFEI_Ry819^#@0@CbRfaztoi+UZunbNfeQ#E>CF|ho(cHn-!)=GtzD_>mnLU0w zT+vsT!K??T-!=V?1x}n=aC(_p7YyDob;d&)hw_dFsBwNmJjRZ}FLXN4rcfJy>UEgIV(qUg2@pn+;z- zexrZ)8J;|Rt4GzJ?RIwApbw529yxs5@agk;#B7r2+sSx8)~p8>F8+~qO$LT$N$9V0`(&K}s4xO4FJwEhk z^6|6AJ51j=e%kO2Q)MvQ?dbB+OUL_-HX2_wea(24!DEBNM(>_FVEVxEs^j<0oHAN& zc=^=l+=_?8a|dV7^QG~@;|m50dfz>Viwt)geRQ=z#E9nsn96f#AaD(9q(<_W)c+p@v-&OxGTz&N1@yg?E2I~x0 zb-UVh{PE%H)2mNkIXrb{jq!a`#~ilA^DaE+f|uo2to7WdE--eVkH5aWd((BFx75O( zg=aX=B1=Diy;r~I4KI1&vWv|-J(`(s@n@|v`;G5?%SLNFXPKugIR8S6K7EB3zif-` z-}$;ZFIxT?OM1M>vsazF*}Hby?rpD1tF64^ax1-H^$j<9`}=qKz}8#7X0ra;Yp%1w zOJDoeZ9cf`&O5yC9dFwFl`r4;^>5y4+Z{jTM~n34m#nnW9*Z6IvTJugZuVd2sk5K> znZvV;%|86D3pUwm;T!(CE`OZ;#9J+P)E$585B+tvNB%nNC_VXZY2NhkoHKTFEIqCM z#LGP|OJDn{mu0uqPn+|^+dO%8i`_o^$-er~>v!Dn%)4LlfhXVYt3N;KiMM(3<#9*- zp8V^_<5N@q_xD#vl-UdPGoLu$^x>~9mS%Q*PCD+0)stmfpuf`VHcy*x{Z_Akcbd9r zJ8h@5*Sx#yCGBH`TQ&`yYcbP>xA^j z___1@d79_@Cpynxq;I_Bm(KTB>1${F%6b1fUHj6LoPSFj9N%1qlhf8u|BcJ>n>1^; zQ(Tr)(}`!E>hkZ5C&{ zoM)$BJni=`>+jRSE1%=?o|9g@&bco0x#`N;=egYHr8Cp{F8ldu&iWU){1>D>SG&-4 zxG?>A`HNhSi_%jTzSwoSIGy*v#jejK>1kJ9;yPWLo_6A;uGeMhfdemd-7Zg8ZhN`w zcX_(`C0DqPSELOWywdf&GR<6ZrR#cCdh@rga(%D1->!C@uTG1tbdBqMO*-zTYh3p~ zq)os52iL!+hqmapK~KM5(^GV#{A|n_QpXcFy&-%MEFb zU2m{$Zb*ke{YKm8#&rJ4H`+#jOvk_TkG9hv)AqxgY^$5n@UWX~uba|7>)&jf-JFJ( z+-$r3Dee3IKiPJFO3M##vHfmIe>mtC+whij#)`Mvj<=>iop7sd`RBCh%l>S8{@LyA z&$j7pY5uq0X1m^&cDwmD+xGVKx*cz~eQ!_o{@ZQiJJPm$++jQ4k$&~q9k%tI=^N!v z+xyP6*wkIN`CVzHa+mFXSGwWRyKMWr)2nvB+xEXZZFAq<_Q5?V?QoC%a8J7YrhDv* zd((Pvzt{e_H@)xTd+n3^(hje@&wjZtZSw2;?3?@2{Hxw?|J0UTZ#N-#wHbst?(J*7H7WA3mIx z*y&;W@!|BFD;~Bl|B^nn;a}{}zohql|1b9GU();Mf5d)$BptNlBlhhh>81-Gv40;; z?^^Rw`}onc@WGGT&yS`%AAHolek@JD`7!(ZvGj%$9<$FMOV=;)xc&ZkI(p~F?fb{m zug`zn{{NSkCqF-}HeBN5bvB%L#Sd?|!J6OL(C5d73$1^{hM(!9IrFZy?* zyEJEmHD5pH()Yg4*Pb%xWerfZN6dZZA=7ief9?EpZ(U>2x#hs8&5c-g?tHthF!yB-tvok>a`m}0&scZv zT_>fvmu~yAxgUDgrgJ~jH=ldW54M=Q+U{G;-E8ys&YgFy9p|pF+^%zXUHqeSx7l~^ zxr2E>Id_-+_nUjvlAoJ<@OQs3ciA-$oV(_kUzvNxI}Vw9+9QWLzi-Vwb^Y%-&mYb` zVZS4t?=f>%yZ$)meZt(|z5JKXzs+6h#8X^`)90SC=2kC|#OXlA6nk!tM zYv!JC+qEv!jdOo^;GbNs+ve`{(z{%?`{rK!_=7IrBhD)(J8V9ftoicM5DHsS#*)7Oy0e~Vv}FayToMCd6t}PGi#~I&u1+&8O-~P z$(;F@o$RvEa+53)FZs}9sjYUM%8u-9a?(8ngHFSqyPsx?18nX~aHCJ()RpULApe{!<{y1s!#r4|csJERwncn+1lY_r|%H&cYuSFTQAU+9MZF=7093 zlYKY7Y_iTym)n0=Ox8K&%E^AWUNxD2v1=x$uK$P0(eLh)b3cFWZM}OZH*S5O{eA!BRVP0%+35BMCp#|v@Z@(d|I6gHyF4ZS~hW~h)cl7U{<{SO{r}@YKxzhsU|J-T8>Hpf( zLeu}Xr-f(!d!H7W`R{!C>v#VrkBSb4PyF%y2~QkA_~-dA&zShP{{OcA=K~IZ|2Tht z`~PVF>%9X0{R0;N*#jQ`nfL#P`y~9sT@v21#g=b<+uQRywtA=gC2YOTd*8S1cJJTb z1Dig$)6O5-W!Deyw)-A?e&nNj{qMHV|L*$#C(r+{cj$I2c>Hhv<^TNs6_5KJ@gE3( zy_ffs(;pZH^G+`~HP3i~;e0bs++Doz#7lYdU;jMuoA?v||Hs3hxc#<2-+IfRZocV{H{Njlb=USk zTyynRS6*@XWtU!Z@kJM2aQ=Dcp7Z;&&pPvWXPkc8Z%;ktHz&7~e*LRo{^G=+pK$!o zetO(bjy>kbM;~?MkB&I}hd=oK_rCj`Z-48s`prYX@%2N#_SJ*Ga?qC#{L%qm{KEd9 z|J-Lk^XdKe{nRJ-`NYTf{#e=TqaWFGkKK3s@UFXjXy=_i_<Z`5#qE%k_f|Z~Dyp>jb?h4O&_VUX;YuRT$@bNdDPKAKIYh;9QV_o z9e={lPyEF%fA#B=+R48;<<#GvcKR8=JM*lwe}B%o=beASg%@3X$)%TFe#MnnU46|T z`nA_xf5VM`yy@mY-E!-nZ@c}DJMX&to_p`R|A7Y|diXC-JQg#`|GfOq7Wkhn@L#h9 z{;NOv|BJu){nJwq|IhM&w!r^vf&ZVjz~6r?{HKTW{@-8z^A8;V^fl+79uE3{efjt6 z`QLs1(`NtY-wOXf{;lV~{O8=i9-RDd`|tm{_0RTv?f?4p_Xk@4eg6G{*ngkyMEVb> z^iMCI8s{Hgo;bki9>M;;`NTaf|2m&o|NX${Dfg|o<^I39arOrDUi$4FH@Ic?6MqH$ z*QbR&7yiFKxij5Aoc`5s!hid%_-{LP;DP@0KE9x1tdEbK=5bo!i6;g4+w1?n>;Lw* zSC?<_Uri=|L$bUg4N7G_yqMB+7McBHT`U*KRWKj6olK;sO~ z<1#uob0-ht&bKjQ7W1<(i?Jljuq@AJMONlTtijr>Ph!H$c@?i=bKb<3WZuO#Y{!o5 z%!k>N!rpv>PqHtc=CgdBFK_?{au5geHNMWFRKCS`_#QvtaDK#5{Fq}oj-PP?C-O^v zP2)G5%4wXznViizoW})R#3fwD6aVT!k@XFJGq;Cxt|Alm`8XFcYTg2 z1`HW7W||phF%R=HAM>*S3$hRkvj|UNQ5Iuymf)!@$#`o}vjHz*Hi-?H!(1l3l#O^9 zFXt7!l8t#4o3JUb<~6*Q*RdI!^LpOE8+j8?{1=Vi!WL}FTX`FAC-V-r;+?#Uck>>$ zW*gqi``DK4ct6{-13U5oKFCh&%!k;8UHLG(u{(RPCm-RX>_u5C3h^iL*@NY?JuCNt|O6 z=bFTMCUL$=TwoFxn#4sWaj{8UViK2{#APONxk+4M5?7kURVHz@NnB$Re=vz|64#o< zbtZAWN!(x(H=4vBP2wh#xY;EBWD>WS#H}XrXOpLL;WFDKuinnnELHSyO1lJk}H%F|Rd+M$BhTp%L?2Q)t8j))X4Cpf!a?EM!fg z5er*WXv8Ac6dLgqYYL56)S5yg7PF?%h{dfbG-3&B3XOQGHHAhjX-%OKPqU`bh^4G4 zG-7FM3XNFCnnELswQ3#0J(B8u1cq3XPa;O`+k;-38N{Mr>$Jp%HVeDKuiPHHAh@tSL0&rPdT0 zv5_@}M!d|LLL**oO`#F5u%^(6S6WkO#KzVX8u2P?3XRyrnnEKswWiRBS6fqP#A~c6 zG~%_^6dLh5YYL6n%$hSG<@NSWl3ZTl}0B%rjy7NDveI;t&_+UDveHjTqlt! zR2rT5giaz;s5CmUk4_>}s5Cn9Nu5NdP-%4HQ#y%Eq0;EYzB-9aq0;EYemaRvq0;EY zr*#sULZ#7(&*&sFg-W9npVdiZ3YA7DKBtq&6e^8Qd|oG!DO4Jr*k31+DO4Jr_<~L% zQ>ZjL@kO0Prch~g;sBjQrch~g;!8S-Org@~#DO}AOrg@~#FupvnL?$}iGy?!nL?$} ziLdA+GKET`69?-gGKET`6JOOyWD1o=C%&eW$P_A#P8_0>$P_A#PJCS_kttLfo%n`M zB2%a|I&r8@B2%a|I`K`NM5a(_bfW4cGKET`6Nl*}GKET`6W`KFWD1o=C%&zd$P_A# zPJBlvkttLfo%pU!B2%a|I`KW7M5a(_bmIFuiAUNn{F@MkkKcNn{F@MkkKaNn{F@MkkKeNn{F@Mkju(lgJb* zjZPe+lgJb*jZPe^lgJb*jZXYTCy^;s8l5;!Cy^;s8lCv5P9jsNG&=D!okXTkX>{Uv zokXTkX>{TQokXTkX>{V}I*Cl7(&)sAI*Cl7(&)r5bP}0DrO}CB>LfCSN~06M(n(|r zl}0Cit&_+UDveH@q?5=LDvgd`I$~K8nL?$}iIa5_nL?$}iQniXGKET`6Q}4TGKET` z6Q}AVGKET`6Tj6-WD1o=Cr;BzWD1o=Cr;N%WD1o=C(h7GWD1o=Cw`}s$P_A#PMoQe z$P_A#PMoEa$P_A#PMoci$P_A#PW)ackttLfoj6A)kttLfoj6w~kttLfoj6Y?kttLf zoj6}7kttLfowz_JkttLfow!gZkttLfow!IRkttLfow!&hkttLfow!6NkttLfow!sd zkttLfow!UVkttLfow!^lkttLfow!0LkttLfow!mbkttLfow!OTkttLfow!;jkttLf zow!CPkttLfo%n-JB2%a|I?;6!nL?$}iEDKdnL?$}iR*L{nL?$}iR*O|nL?$}i5qkh znL?$}i5qninL?$}i9hNjGKET`6F2E3GKET`6F2K5GKET`6Mxc4WD1o=CvMS6WD1o= zCvMeAWD1o=C;qIH$P_A#PTZ!G$P_A#PTa1O$P_A#PTZlB$P_A#PTZ-J$P_A#PTZxF z$P_A#PTZ}N$P_A#PTZrD$P_A#PTZ@L$P_A#PTZ%H$P_A#PTa4P$P_A#PCTHK$P_A# zPCTfS$P_A#PCTTO$P_A#PCTrW$P_A#PW(kDkttLfop?kikttLfop@9ykttLfop?+q zkttLfop@X)kttLf9e;3)Wl3ZTl}0C~bP}0DrO}CjP9jsNG&(WVNn{F@Mkhu(iA{Org@~#5_8QOrg@~#JoC*Org@~#C$r5 zOrg@~#QZvmOrg@~!~!~rOrg@~#DY4BOrg@~#6miWOrg@~#KJm>Org@~#3DM0Org@~ z#8Y$=kttLf zop`2BB2%a|IM5a(_bYeN3M5a(_bYgj(M5a(_bmG}MiA?*$okXTkX>?*W zokXTkX>?+BokXTkX>?)@okXTkX>{VnI-Y^SUCwkWjZUnolgJb*jZUnklgJb*jZUns zlgJb*jZUnilgJb*jZUnqlgJb*jZUnmlgJb*jZUnulgJb*jZSQ!lgJb*jZVBoCy^;s z8l9M}lgJb*jgBi8%aX_xDveHTsFTPPDveIe(MeLfCSN~04KokXTkX>{VH zI*Cl7(&)rSI*Cl7(&)s?bP}0DrO}C(>m)LTN~066&`D$pl}0CCsguYQDveHTtdqzT zDveION+*#iR2rSwL?@9cR2rSwR40)sR2rRlwN4^as5Cn98l6O@P-%4HwK|DRq0;EY z>vR&CLZ#7(&2$o(LZ#7(&2ZjL@fMv#rch~gVhf!_rch~gVoRMwrch~g;;lM~Org@~#M^WdnL?$} ziMQ({GKET`OCnRKG&=DPokXTkX>?*MokXTkX>{V9I*Cl7(&)sybP}0DrO}CZ z>m)LTN~06+(Me?*A zokXTkX>{U~I*Cl7(&)sebP}0DrO}CfbrP9ErO}D~bP}0DrO}B`>m)LTN~05>(MeSg-W9n2k9g-g-W9nU(rcq3YA7D4%SIz z3YA7DzN(YR6e^8Qd`%~jDO4JrI7BCrDO4Jr__|IaQ>ZjL@eQ3srch~g;!vGLrch~g z;+r~&Org@~_+`fNf1OOB(&)rtI*Cl7(&)subP}0DrO}CR>m)LTN~06s(MeZjLaiUHlQ>ZjL@e7?qrch~g;+Hy!Org@~#IJM`nL?$}iC^m^GKET` z6DR2;GKET`;}02*|LbH5l}0B{)=6Xvl}0Ciqm#%KDveH@qLauJDveH@s*}hRDveJ3 zRwt1uR2rQ)O(&5lR2rQ)T_=$#R2rQ)Lno0bR2rT5olYWCs5ClprcNSLs5ClpmQEs5 zs5ClpwoW2bs5Cn9d!0n4P-%4H9Gyg_P-%4HT%AOwP-%4HJe@?QP-%4He4Rw5P-%4H z0-Z#rP-%4HLY+jWP-%4HBArC0P-%4HVx2^$P-%4H5}ib*P-%4HQk_JmP-%4HGMz-G zP-%4Ha-Bq`P-%4H3Y|ozP-%4HN}WWeP-%4HDxE~8P-%4HYMn%;P-%4H8l6O@P-%4H z4?2lVq0;F1Bc|j3I+;SH(TQty5}87!(TVGH5}87!(TVGI5}87!(TN*$5}87!(TN*% z5}87!(TP9mBr=6cqZ2pjBr=6cqZ2plBr=6cqZ5D9Nn{F@Mkj93Nn{F@Mkj97Nn{F@ zMkoHPlgJb*jZWOAlgJb*jZWOIlgJb*jZWO5lgJb*jZWODlgJb*jZWO9lgJb*jZWOH zlgJb*jZWO7lgJb*jZWOFlgJb*jZWOBlgJb*jZWOJlgJb*jZQqElgJb*jZQqMlgJb* zjZQqIlgJb*jZQqQlgJb*jZXYUCy^;s8l8AVCy^;s8l8AlCy^;s8l8AdCy^;s8l8At zCy^;s8XX5P9RFX}@&9!l|6kYf|8*VzU)S;fbshg-*YSUyM5a(_bYh^B$P_A#P7HMt znL?$}iIGksQ>ZjLG1f_B3YA7DrgajTLZ#7(8J$F?P-%2xmQEs5s5Ck;k4_>}s5Ck; zuTCOUs5Ck;pH3oEs5Ck;zfK}ks5CmUfKDP)s5CmUpiUxFs5CmUkWL~~s5CmUuudXV zs5CmUh)yC?s5Cn96rDt-P-%2xQJqAlP-%2xF`Y!FP-%2xah*h_P-%2x37tfyP-%4H zsXB>Fq0;EYk~)b@q0;EY({vJtqU*Mkk)7lgJb*jZQ45lgJb*jZQ4DlgJb* zjZQpUCy^;s8l8BKP9jsNG&-?@P9jsNG&=EIokXTkX>?*mokXTkX>?*GokXTkX>{Uw zI*Cl7(&)tVbrP9ErO}C%brP9ErO}BO=p-_QN~04m)JbFtl}0C4(Me%Org@~#D+SFOrg@~#2lSOrch~gVy;diQ>ZjL zG0{n63YA7DUaFJG6e^8QY^0OO6e^8Qyi6yNDO4Jrc)3m@Q>ZjL@d}+prch~g;*~my zOrg@~#Kt;_Org@~#H(}?nL?$}iA{78nL?$}iA{A9nL?$}iC60+GKET`6R*)pWD1o= zCtjZjLv6W6DQ>ZjL@lKsYrch~g z;$1q4Org@~#JhD8nL?$}iTCIvGKET`6I<&fGKET`6Wiz{GKET`6YteYWD1o=C*G%% z$P_A#PHd}_$P_A#PHd->$P_A#PP|_ykttLfo!DL{kttLfo!CJqkttLfo!C()kttLf zo%n!GB2%a|I`KiBM5a(_bYdr+M5a(_bYf?nM5a(_bmBugiAZjLv5!t7Q>ZjL@kyOTrch~g;!`?_Org@~#J)O-Org@~#C|%7Org@~#HV!< znL?$}iO=XHGKET`6Q9*dWD1o=CqAc>$P_A#PJCV`kttLfo!DO|kttLfo%n)IB2%a| zI`KuFM5a(_bm9P=M5a(_bmB`oiA|Ou;`qN#rch~g;xL^=rch~g;#)e2Org@~#J6=4nL?$} ziSOtnGKET`6W`TIWD1o=C%&hX$P_A#PJCY{kttLfo%n%HB2%a|I`KoDM5a(_bmDNG zM5a(_bm9n|M5a(_bmB)kiAXNn{F@MkjuzlgJb*jZPe| zlgJb*jZU1PlgJb*jZXYrCy^;s8l5;%Cy^;s8lCusP9jsNG&=E1okXTkX>{UOI*Cl7 z(&)smbrP9ErO}C#bP}0DrP1++3djF-GKET`6DR8=GKET`6Ti_(WD1o=Cr;5xWD1o= zCr;H#WD1o=Cw{Aw$P_A#PMoHb$P_A#PMofj$P_A#PMo2W$P_A#PW(@B2%a|I&qFpB2%a|I&rQ}B2%a|I&q#(B2%a| zI&r>EB2%a|I&pzcB2%a|I&q;+B2%a|I&qOsB2%a|I&ra1B2%a|I&q0kB2%a|I&rB^ zB2%a|I&qm!B2%a|I&ry9B2%a|I&p#>05}YU63uT=Q>+ z<%mDgNs4Azj`&lZq-ciah(FUwie^}j_;a14Xols8ztBmFW>}8+OP!=>hUJLA(n*SD zSdRE>oup`n<%qx0Ns4Azj`&-hq-ciah`-ZGie^}j_}8+N1dc- zhUJKV(n*SDSdRE-oup`n<%oaLNs4Azj`&xdq-ciah=0>bie^}j_;;P8Xols8|IkT_ zW>}8+Po1P_hUJL=(n*SDSdRE_oup`n<%s{$Ns4Azj`&}lq-ciai2u_`ie^|21BLzn z0sH?0_WuX${}0&zAF%&FVE=!>{;!i1&9EHtFgi)m49gJ@tCJMXupIGlI!VzC%MlN+ zlN8Oc9PtP`Nzn|;5s#>o6wR<4@klyJ(G1HGkF1jv&9EHtC^|{e49gLZs*@DWupIGd zI!VzC%Mp*RlN8Oc9Pt=BNzn|;5s#^p6wR<4@mM-Z(G1HGkFApw&9EHtI66tu49gLZ ztCJMXupIGtI!VzC%Mp*SlN8Oc9PtD?Nzn|;5l^U-6wR<4@kBaF(G1HGPpp#^&9EHt zBsxja49gKus*@DWupIGZI!VzC%MnkmlN8Oc9Pt!7Nzn|;5l^X;6wR<4#!36XPSFg@ z5l^L)6wR<4@zgp=(G1HGPot9*&9EHtv^q)A49gKur;`-TupII9I!VzC%Ms6@lN8Oc z9Px}gNzn|;5znNP6wR<4@yt3&(G1HG&!UqQ&9EHttU5{249gMErjr!SupII1I!VzC z%Ms6^lN8Oc9PykwNzn|;5znQQ6wR<4@!UE|(G1HG&!dwR&9EHtygEtI49gMEr;`-T zupIIHI!VzC%MmZ2lN8Oc9PxrWNzn|;5ig{Z6wR<4@xnSu(G1HG59lOCGb~3usFM`U zupIFaoup`n<%oysBtC25q8XMWUR)lA;-wBVJY~DVkw9;^lOb zq8XMWUS20DnqfKO6?BrK8I~hnQ70*yVL9TJbdsVOmLpzSCn=g?IpS4xlA;-wBVJV} zDVkw9;?;DLq8XMWUR@_CnqfKOHFT1q8I~hnQzt2!VL9TpbdsVOmLpzUCn=g?IpTG6 zlA;-wBVJc0DVkw9;`MZrq8XMWUSB6EnqfKO4Rn&C8I~j7P$wyxVL9TBbdsVOmLuL+ zCn=g?IXsl?|2jo8EJwVFPEs_(a>SeJBtm)@pEJwVJPEs_(a>U!}Btm)@pEJwVHPEs_(a>TppBtm)@pEJwVLPEs_(a>V=UBt}8+V4b9B zhUJJ4(MgJCSdREmoup`n<%kc{Ns4Azj`(n$q-ciah>y@oie^}j_(+|kXols8kJ3qs zW>}8+Xq}{JhUJKl(MgJCSdREuoup`n<%o~dNs4Azj`(<;q-ciah)>W-ie^}j_(Ywg zXols8Ptr+>W>}8+WSyjFhUJJ)(MgJCSdREqoup`n<%mzyNs4Azj`(z)q-ciah|kbT zie^}j_)MLoXols8&(cYXW>}8+Y@MWNhUJLQ(MgJCSdREyoup`n<%rMINs4Azj`)0? zq-ciah%eAdie^}j_(GkeXoltRGGhPNDVkw9;)`^Wq8XMWzE~$InqfKOOLUT=8I~iy zR3|B#VL9T<%l2DNs4Azj`$&+q-ciah#%HTie^}j_z|6?Xols8AJs{UW>}8+F`cAn zhUJJK*GY}8+Ih~|vhUJK#*GY}8+HJzkrhUJJ~*GY}8+J)NXzhUJLg*GYT>wBtS$QBtV25BtSGABtLf)oEJr+@ zPEs_(a>Uc?BtLf)oEJr+>PEs_(a>TRiBtLf)oEJr+_PEs_(a>VoNBt(G{bVl z3+p6BGb~3uppz8MupIHAPEs_(a>PS)lA;-wBOa=g6wR<4@gh1&(G1JshwcA5MKdf% zyr@o6G{bVli|HgqGb~5ExK2_u!*aw+=p;omEJwVgPEs_(a>PsNBtOg?Bt~Gb~5Ex=vCw!*axH=p;omEJwViPEs_( za>Q%tBt**v#Gb~5EzD`m!!*awM=p;om zEJwVdPEs_(a>N_yBt}7R3!S8BhUJL2)JckFSdMrroup`n<%qY|Ns4Azj(8iLq-ciah_}^A zie^}jcsre>Xols8x7SIEW>}7R2c4v7hUJKN)JckFSdMrnoup`n<%oCINs4Azj(8WH zq-ciah}7R51piFhUJL&)JckFSdMrvoup`n<%svz zNs4Azj(8uPq-ciai1*b=ie^}jct4$_Xols8_t!~^W>}8+0G*_0hUJJ4)JckFSdRE0 zoup`n<#6Dz|LYXZupIHhI!VzC%Ml-j2(G1HG zAEA>J&9EHtkvd7y49gK8rIQrRupIHxI!VzC%Ml-=lN8Oc9PzO_Nzn|;5g(_M6wR<4 z@$ouI(G1HGpP-Wz&9EHti8@Kq49gLpq>~iQupIHpI!VzC%MqWVlN8Oc9Pz0-Nzn|; z5uc`$6wR<4@##8A(G1HGpP`c!&9EHtnL0_)49gLprIQrRupIH(I!VzC%MqWWlN8Oc z9Pzn2Nzn|;5uc}%6wR<4@%cJQ(G1HGU!ao|&9EHtg*r*m49nqV!~U;RG{bVl7wIHL zGb~4Zu})Gn!*axz=p;omEJu8)PEs_(a>SSEBtDfMKdf%e5FoO zG{bVlSLq~0Gb~4ZwN6qr!*aye=p;omEJu8;PEs_(a>Uo^BtTdkBtV!P zBt_Nh49gL}s*@DWupIGgI!VzC%Mrh>lN8Oc9Pt}ENzn|; z5x=RE6wR<4@mo4c(G1HGzpaxL&9EHtJ32|x49gL}tCJMXupIGwI!VzC%Mrh?lN8Oc z94;B{|2jo8EJyr-PEs_(a>O6%Btm)@pEJyr>PEs_(a>QTiBtm)@pEJyrPICBtm)@pEJyr@PEs_(a>Re?BtT>wBtS$QBtV25BtSGABtLf)oEJr+@PEs_(a>Uc?BtLf)oEJr+>PEs_(a>TRiBtLf)oEJr+_PEs_(a>VoNBt(G{bVl3+p6BGb~3uppz8MupIHAPEs_(a>PS)lA;-wBOa=g z6wR<4@gh1&(G1Jsi|zk9MKdf%yr@o6G{bVli|HgqGb~5ExK2_u!*aw+=p;omEJwVg zPEs_(a>PsNBtOg?Bt~Gb~5E zx=vCw!*axH=p;omEJwViPEs_(a>Q%tBt**v#Gb~5EzD`m!!*awM=p;omEJwVdPEs_(a>N_yBt}7R3!S8BhUJL2)JckFSdMrroup`n z<%qY|Ns4Azj(8iLq-ciah_}^Aie^}jcsre>Xols8x7SIEW>}7R2c4v7hUJKN)JckF zSdMrnoup`n<%oCINs4Azj(8WHq-ciah}7R51piF zhUJL&)JckFSdMrvoup`n<%svzNs4Azj(8uPq-ciai1*b=ie^}jct4$_Xols8_t!~^ zW>}8+0G*_0hUJJ4)JckFSdRE0oup`n<#3>||LYXZupIHhI!VzC%Ml-j2(G1HGAEA>J&9EHtkvd7y49gK8rIQrRupIHxI!VzC%Ml-= zlN8Oc9PzO_Nzn|;5g(_M6wR<4@$ouI(G1HGpP-Wz&9EHti8@Kq49gLpq>~iQupIHp zI!VzC%MqWVlN8Oc9Pz0-Nzn|;5uc`$6wR<4@##8A(G1HGpP`c!&9EHtnL0_)49gLp zrIQrRupIH(I!VzC%MqWWlN8Oc9Pzn2Nzn|;5uc}%6wR<4@%cJQ(G1HGU!ao|&9EHt zg*r*m49nqV!v3#QG{bVl7wIHLGb~4Zu})Gn!*axz=p;omEJu8)PEs_(a>SSEBtDfMKdf%e5FoOG{bVlSLq~0Gb~4ZwN6qr!*aye=p;omEJu8;PEs_( za>Uo^BtTdkBtV!PBtPSFg@5kIJt z6wR<4@k2UE(G1HGKdh4!&9EHtBRWaZ49gKes*@DWupIGYI!VzC%Mm}WlN8Oc9Ptx6 zNzn|;5kIMu6wR<4@l!fU(G1HGKdqA#&9EHtGdfAp49gKetCJMXupIGoI!VzC%Mm}X zlN8Oc9PtY}Nzn|;5x=OD6wR<4@k=^M(G1HGzpRrK&9EHtD>_Nh49gL}s*@DWupIGg zI!VzC%Mrh>lN8Oc9Pt}ENzn|;5x=RE6wR<4@mo4c(G1HGzpaxL&9EHtJ32|x49gL} ztCJMXupIGwI!VzC%Mrh?lN8Oc94-;<|2jo8EJyr-PEs_(a>O6%Btm)@pEJyr>PEs_(a>QTiBtm)@pEJyrPICBtm)@p zEJyr@PEs_(a>Re?BtzfMv#!*ayK=p;omEJr-7PEs_(a>T>w zBtS$QBtV25BtSGABtLf)oEJr+@PEs_(a>Uc?BtLf)oEJr+>PEs_( za>TRiBtLf)o zEJr+_PEs_(a>VoNBt(G{bVl3+p6BGb~3uppz8M zupIHAPEs_(a>PS)lA;-wBOa=g6wR<4@gh1&(G1JsgZ6)&q8XMWUQ{P3nqfKO#dMOQ z8I~hnTqh}-VL9R@bdsVOmLpzLCn=g?IpU>slA;-wBVJl3DVkw9;$?J_q8XMWUREb5 znqfKO<#dvw8I~hnUMDGmV=8I~hnUneP=VL9RrbdsVOmLuL!Cn=g?IpU3U zlA;-wBi>jiDVkw9JT&b8Iz=-qN4$wnQZ&PI#GC3QMKdf%yqQi?G{bVlo9iS+Gb~5E zg-%j5!*ax1>Lf)oEJwVRPEs_(a>QHfBtLf)oEJwVPPEs_(a>P69BtLf)oEJwVTPEs_(a>RSLf)oEJu8hPEs_(ayT&9|8}8+NS&l; zhUJKl(n*SDSdRE;oup`n<%o~bNs4Azj`&!eq-ciah>z1rie^}j_;{V9Xols8PtZw< zW>}8+M4hB)hUJJ)(n*SDSdRE)oup`n<%mzwNs4Azj`&oaq-ciah)>f=ie^}j_;j75 zXols8&(KMVW>}8+Or4}?hUJLQ(n*SDSdRE?oup`n<%rMGNs4Azj`&=iq-ciah|kkW zie^}j_}8+LY<^&hUM_GVE@-CnqfKOi*%Br8I~iySSKl(VL9SU zbdsVOmLtAYCn=g?IpWK7lA;-wBfeZGDVkw9;wyBLq8XMWzEUSCnqfKOt8|j08I~iy zS|=%*VL9S!bdsVOmLtAaCn=g?IpXVdlA;-wBfefIDVkw9;v005q8XMWzELMBnqfKO zn{<+*8I~iyStlu)VL9SkbdsVOmLtAZCn=g?IpW)NlA;-wBfecHDVkw9;yZMbq8XMW zzEdYDnqfKOyL6JG8I~iyTPG=+VL9S^bdsVOmLtAbCn=g?IpX_tlA;-wBfeiJDVkw9 z;s}8+5uK!HhUJJK)k%tG zSdREHoup`n<%l2GNs4Azj`#_kq-ciah@aF+ie^}j_$i&FXols8pVmo=W>}8+8J(nP zhUJK#)k%tGSdREPoup`n<%plxNs4Azj`#(gq-ciah+ou6ie^}j_$8gBXols8U)D*A zW>}8+6`iDLhUJJ~)k%tGSdRELoup`n<%nO`Ns4Azj`$6oq-ciah~Lynie^}j_${5J zXols8-_}WrW>}8+9i60ThUJLg)k%tGSdREToup`n<%r+cNs4Az4wr=Xf1RQkmLvW^ zCn=g?IpPm>lA;-wBmPJyDVkw9;*WKbq8XMW{zNA!nqfKOPj!-_8I~jdOeZOtVL9T@ zb&~pjj_fg7qpdmHZGEwA?$|cp+Ocg`Y}*yvcEz?`v29mu+o!kFR_p7}^?N>Z%yH8U z%MpK}lN8Oc9PyVrNzn|;5r3tV6wR<4@z**@(G1HGf1{HW&9EHtw>nAD49gLJr;`-T zupIICI!VzC%Mt&elN8Oc9Py7jNzn|;5&xu<6wR<4@y|L*(G1HG|Dux=&9EHtuR2N5 z49gM!rjr!SupII4I!VzC%Mt&flN8Oc9PytzNzn|;5&xx=6wR<4@!vX0(G1HG|D%%> z&9EHtzdA|L49gM!r;`-Tup9;g`~O4i{|~YMKg9n35c~f_?Eeq3|3Ae3uagwbupIGF zI!VzC%MlN)lN8Oc9PuzZNzn|;5f7`A6wR<4@o+jx(G1HG53iFH&9EHt2s%m849gLZ zsFM`UupIG7I!VzC%Mp*PlN8Oc9PubRNzn|;5s#{q6wR<4@n||p(G1HGkFJvx&9EHt z7&=MO49gLZsgo4VupIGNI!VzC%Mp*QlN8Oc9Pv0hNzn|;5s#~r6wR<4@pw8((G1HG zkFS#y&9EHt1UgC449gKusFM`UupIG3I!VzC%MnkklN8Oc9PuPNNzn|;5l^a<6wR<4 z@nkwl(G1HGPp*>`&9EHCLHoZ>(G1HGPoa|(&9EHtlsZY#49gKurIQrRupIH!I!VzC z%MnkblN8Oc9PzX|Nzn|;5l^R+6wR<4@$@=L(G1HG&!CeO&9EHtj5~iQ zupIHsI!VzC%Ms6_lN8Oc9Pz9=Nzn|;5znTR6wR<4@$5QD(G1HG&!LkP&9EHtoH|L- z49gMErIQrRupIH+I!VzC%Ms6`lN8Oc9Pzw5Nzn|;5znWS6wR<4@%%bT(G1HGFQAhY z&9EHtf;vgj49gKOq>~iQupIHiI!VzC%MmZ4lN8Oc9Py$$Nzn|;5f9Nxie^|2!TzsP zG{bVlgE~pk49gKOrjr!SupIH?I!VzC%MmZ3lN8Oc9PyGmNzn|;5ig~a6wR<4@zOd; z(G1HGFQbzb&9EHtvN}o849gKOr;`-TupII7I!VzC%Mq`jlN8Oc9Px@eNzn|;5wE0^ z6wR<4@ya?$(G1HGucDI_&9EHtsya#049gL(rjr!SupIH~I!VzC%Mq`klN8Oc9Pyeu zNzn|;5wE3_6wR<4@!C2`(G1HGucMO`&9EHtx;jbG49gL(r;`-TupIIFI!VzC%Mov& zlN8Oc9Px%aNzn|;5pSfE6wR<4@y0qy(G1JsN5THDQ#8YJ#GB|OMKdf%ys1u7G{bVl zo9QG)Gb~5ExlU3v!*ax1=p;omEJwVhPEs_(a>QHdBtP67BtRS-BtNJeBt<%kc~Ns4Azj`$Frq-ciah!53Cie^}j_%NNMXols857$YG zW>}8+2%V&8hUJKl)JckFSdRE8oup`n<%o~gNs4Azj`$dzq-ciah>z7tie^}j_&A-U zXols8kJm|xW>}8+1f8U4hUJJ))JckFSdRE4oup`n<%mz#Ns4Azj`$Rvq-ciah)>l? zie^}j_%xlQXols8PuEF`W>}8+44tHChUJLQ)JckFSdRECoup`n<%rMLNs4Azj`$p% zq-ciah|kqYie^}j_&lAYXols8&(}$cW>}8+0-dC2hUJJa)JckFSPmZp_J5tC8I~iy zNGB&fCq8XMWzCtG{nqfKO zD|M2h8I~iyN+&6rVL9Tfb&{ePmLtAKCn=g?IpS+|lA;-wBfd^2DVkw9;_G#iq8XMW zzCkA`nqfKO8+DSR8I~iyNhc|qVL9TPb&{ePmLtAJCn=g?IpSM&lA;-wBfd>1DVkw9 z;@fqSq8XMWzC$M|nqfKOJ9Uzx8I~iyOD8FsVL9Tvb&{ePmLtALCn=g?IpTYDlA;-w zBfd{3DVkw9;`?=yq8XMWen2NFnqfIy1la#|ie^}j_(7edXols8AJR#RW>}8+VV$IC zhUJJK(MgJCSdREnoup`n<%l2CNs4Azj`(q%q-ciah@a3&ie^}j_(`3lXols8pVCQ+ zW>}8+X`Q5KhUJK#(MgJCSdREvoup`n<%pltNs4Azj`(?}8+Wu2sGhUJJ~(MgJCSdREroup`n<%nO?Ns4Azj`($*q-ciah~Lmj zie^}j_)VRpXols8-_l8nW>}8+ZJnfOhUJLg(MgJCSdREzoup`n<%r+YNs4Azj`)3@ zq-ciaa0zJt*D0D|IpPm=lA;-wBmPh)DVkw9;*WHaq8XMW{#Yj|nqfKOPjr%^8I~jd zR3|B#VL9T@bdsVOmLvXLCn=g?IpQyLlA;-wBmPn+DVkw9;;(d)q8XMW{#qv~nqfKO zZ*-EP8I~jdRwpT%VL9UObdsVOmLvXNCn=g?IpQC5lA;-wBmPk*DVkw9;-7Sqq8XMW z{#hp}nqfKOUv!e98I~jdRVOK$VL9U8bdsVOmLvXMCn=g?IpRNblA;-wBmPq-DVkw9 z;=go~q8XMW{#z$0nqfKOe{_mTAq8XOM_-FsuDVkw9;wf~Jq8XMWo>C_%nqfKOsdSQ} z8I~iSS|=%*VL9SybdsVOmLr~4Cn=g?IpXPblA;-wBc5I-DVkw9;u&<3q8XMWo>3<$ znqfKOnRJq(8I~iSStlu)VL9SibdsVOmLr~3Cn=g?IpW!LlA;-wBc5F+DVkw9;yHAZ zq8XMWo>M0&nqfKOxpb1E8I~iSTPG=+VL9S?bdsVOmLr~5Cn=g?IpX;gl8I~hnSSKl(VL9SObdsVOmLpzNCn=g?IpQHY zNzn|;Vfc>+NQ!1yj(AWfDVkw9;>C25q8XMWUR)lA;-wBVJY~DVkw9;^lObq8XMWUS20DnqfKO6?BrK8I~hn zQ70*yVL9TJbdsVOmLpzSCn=g?IpS4xlA;-wBVJV}DVkw9;?;DLq8XMWUR@_CnqfKO zHFT1q8I~hnQzt2!VL9TpbdsVOmLpzUCn=g?IpTG6lA;-wBVJc0DVkw9;`MZrq8XMW zUSB6EnqfKO4Rn&C8I~j7P$wyxVL9TBbdsVOmLuL+Cn=g?IXv|707=md%Mov)lN8Oc z9Py?)Nzn|;5pSlG6wR<4@#Z>7(G1HGZ=sVE&9EHtmO4q%49gL3rIQrRupIH$I!VzC z%Mov*lN8Oc9Pzd~Nzn|;5pSoH6wR<4@%B1N(G1HG@1T~iQ zupIHuI!VzC%MtIQlN8Oc9PzF?Nzn|;5$~px6wR<4@$NcF(G1HG@1c_v&9EHto;pd< z49gMkrIQrRupIH;I!VzC%MtIRlN8Oc9Pz$7Nzn|;5$~sy6wR<4@%}nV(G1HGAE1*I z&9EHtfjUXi49gK8q>~iQupD0a@c>ED49gK8tdkVYupIFrI!VzC%Ml-{lN8Oc9Pwc~ zNzn|;5g)FT6wR<4@ew*n(G1HGAE}cR&9EHtQ94P{49gK8t&1&9EHt#X3pR49gK;qLUQOupIHFI!VzC%Mo9ulN8Oc9P#BkNzn|; z5nrK`6wR<4@s&DB(G1HGU!{{2&9EHt)jCPh49gK;qmvZPupIHVI!VzC%Mo9vlN8Oc z9P#x!Nzn|;5#OMb6wR<4@r^o3(G1HG-=vci&9EHt%{ocZ49gMUqLUQOupIHNI!VzC z%MstElN8Oc9P#ZsNzn|;5#OPc6wR<4@trzJ(G1HG-=&ij&9EHt-8xCp49gMUqmvZP zupIHdI!VzC%MstFlN8Oc9P#}+Nzn|;5kH`l6wR<4KJ?=OlA;-wBYsdPDVkw9;)isS zq8XMWepn|dnqfKOM|6^+8I~h{R3|B#VL9T*bdsVOmLq;#Cn=g?IpQaDlA;-wBYsjR zDVkw9;-_?yq8XMWep)9fnqfKOXLORH8I~h{RwpT%VL9UGbdsVOmLq;%Cn=g?IpP;| zlA;-wBYsgQDVkw9;+J%iq8XMWepx3enqfKOS9Fr18I~h{RVOK$VL9U0bdsVOmLq;$ zCn=g?IpQ~TlA;-wBYsmSDVkw9;O6%Btm)@pEJyr>PEs_(a>QTiBtm)@pEJyrPICBtm)@pEJyr@PEs_( za>Re?Bt}8+e>zFg49gJ@rIQrRupIHwI!VzC%MlOrp#5K`Xols8ht)}nW>}7RIGv}7R zG@YbqhUJJy*GY}7RJe{OyhUJLI*GY}7RGM%JohUJJS*GYP^VBt{mm8I~hnL?C56q8XMWUgAOfzfRE% z%MmZBlN8Oc9Pv^*Nzn|;5ihNi6wR<4@iIC|(G1HGFRPOj&9EHtaym)T49gKOuagwb zupIFUI!VzC%Mq`rlN8Oc9PvszNzn|;5wEP16wR<4@hUn=(G1HGud0(2&9EHtYC1{L z49gL(u9FnaupIFkI!VzC%Mq`slN8Oc9PwH@Nzn|;5wES26wR<4@j5z5(G1HGud9<3 z&9EHtdOAtb49gL(uagwbupIFQI!VzC%Mov=lN8Oc9PvgvNzn|;5pS%M6wR<49_o02 zq-ciah&Rzmie^}jcvGFEXols8H`7UqW>}7R^9Sw!Iz=-qN4$kjQZ&PI#9QhlMKdf% zyp>K;G{bVlTk9l6Gb~5EjZRWD!*ayi>Lf)oEJwVZPEs_(a>U!~BtLf)oEJwVXPEs_(a>TpqBtLf)oEJwVbPEs_( za>V=VBteDVkw9;=^^4q8XMWK0+rcnqfKOBXyFZ8I~hHN+&6rVL9TX zb&{ePmLon!Cn=g?IpSk=lA;-wBR) z(G1HGU#623&9EHt49gMUppz8MupIG?I!VzC%MstClN8Oc9P!OM zNzn|;5#OSd6wR<4@vS;Z(G1HG-=>ok&9EHt?K(-(49gMUp_3HNupIH7I!VzC%MstD zlN8Oc9P!;cNzn|;5#OVe6wR<4@x3}p(G1HG-=~ul&9EHt{W?j}49gKeppz8MupB<* z;{lSQ8I~h{P$wyxVL9T5bdsVOmLq;xCn=g?IpRkiwEycA&9EHtqdG~^49gKerjr!S zupIH@I!VzC%Mm}JlN8Oc9PyJnNzn|;5kIAq6wR<4@zXj<(G1HGKckZr&9EHtvpPx9 z49gKer;`-TupII8I!VzC%MrhzlN8Oc9Px`fNzn|;5x=C96wR<4@yj|%(G1HGzoL^A z&9EHtt2#;149gL}rjr!SupII0I!VzC%Mrh!lN8Oc9PyhvNzn|;5x=FA6wR<4@!L8{ z(G1HGzoU~B&9EHtyE;kH49gL}r;`-TupIIGI!VzC%i$6)9v~^2VL9RtbdsVOmLvX9 zCn=g?IpU9WlA;-wBmVe7`@c@n49gLJqLUQOupIHHI!VzC%MpL3lN8Oc9P#HmNzn|; z5r3hR6wR<4@s~PD(G1HGf2ETY&9EHt*E&hj49gLJqmvZPupIHXI!VzC%MpL4lN8Oc z9P#%$Nzn|;5&xi*6wR<4@sB!5(G1HG|D=-?&9EHt&pJub49gM!qLUQOupIHPI!VzC z%Mt&klN8Oc9P#fuNzn|;5&xl+6wR<4@t-PUFBtOI)BtQfl zBtNtqBt2;E#8I~iSK_@AiVL9R%b&{ePmLr}?Cn=g?IpUdhlA;-wBc4SkDVkw9 z;#qZ)q8XMWo=qnynqfKO*>#el8I~iSLnkSkVL9SCb&{ePmLr}^Cn=g?IpVo>lA;-w zBc4YmDVkw9;(2wFq8XMWo=+z!nqfKO`E`<_8I~hnKqo1hVL9Rjb&{ePmLpzBCn=g? zIpT$NlA;-wBVI%&DVkw9;zf0mq8XMW9-@;J&9EGX`*?t)Xols82X&I78I~hnOeZOt zVL9T(b&{ePmLpz5Cn=g?IpQUClA;-wBVI};DVkw9;-z(xq8XMWUPdP=nqfKOWp$FG z8I~hnPA4gvVL9UEb&{ePmLpz4Cn=g?IpP&{lA;-wBVI`-DVkw9;+1uhq8XMWUPUJ< znqfKORdtf08I~hnO(!XuVL9T}b&{ePmLpz6Cn=g?IpQ^SlA;-wBVJ1 zq8XMWUPmV>nqfKOb#;=W8I~hnPbVpwVL9UUb&{ePmLuLkCn=g?IpPgp0N&9EHtW;#jH49gL3u9FnaupIFg zI!VzC%Mov>lN8Oc9Pw5y6O&9EHtb~;JX49gL3 zuagwbupIFYI!VzC%MtIWlN8Oc9Pv&%Nzn|;5$~*%6wR<4@h&<^(G1HG@2Zm&&9EHt zZaPWP49gMku9FnaupIFoI!VzC%MtIXlN8Oc9PwT{Nzn|;5$~;&6wR<4@jg09(G1HG z@2is(&9EHtemY6f49gMkuagwbupIFLI!VzC%Ml-_lN8Oc9PvRqNzn|;;e{O!kQB|Z z9Pz$(G1HGU$2uC&9EHt4LV8D49gMUsFM`UupIGC zI!VzC%MstKlN8Oc9PuqWNzn|;5#Oql6wR<4@ohRu(G1HG->#Ds&9EHt9Xd(T49gMU zsgo4VupIGSI!VzC%MstLlN8Oc9PvFmNzn|;5#Otm6wR<4@qIc;(G1HG->;Jt&9EHt z13F3349np|Jsuz_nqfKO2X&I78I~h{NGBUH8q8XMWenKZHnqfKOCv}pd8I~h{N+&6rVL9Tbb&{ePmLq;fCn=g? zIpSw^lA;-wBYsXNDVkw9;^%deq8XMWenBTGnqfKO7j=@N8I~h{Nhc|qVL9TLb&{eP zmLq;eCn=g?IpSA!lA;-wBYsUMDVkw9;@5SOq8XMWenTfInqfKOH+7Pt8I~h{OD8Fs zVL9Trb&{ePmLq;gCn=g?IpTM9lA;-wBYsaODVkw9;`eouq8XOMC0#r~QZ&PI#2@G+ zMKdf%{Gm=#G{bVlAL%4TGb~5^u})Gn!*ax*=p;omEJysQPEs_(a>SqMBtU>1BtT#s zBtW1XBt(U-nqfKONpzB; z8I~iSR3|B#VL9T-bdsVOmLr~ACn=g?IpQgFlA;-wBc4(xDVkw9;;D3!q8XOMIA{OY zDVkw9;;D6#q8XMWo<=7rnqfKOX?2pK8I~iSPA4gvVL9UIb&{ePmLr})Cn=g?IpP_0 zlA;-wBc4eoDVkw9;+b`lq8XMWo<%1qnqfKOS#^@48I~iSO(!XuVL9U2b&{ePmLr}+ zCn=g?IpR5WlA;-wBc4kqDVkw9;<slA;-wBVJl3DVkw9 z;(}7Ruuf7m!*aw!bdsVOmLpz9Cn=g?IpSq?lA;-wBVJA?DVkw9 z;^lRcq8XMWUO^`*nqfKO6?KxL8I~hnNhc|qVL9TJb&{ePmLpz8Cn=g?IpS4ylA;-w zBVJ7>DVkw9;?;GMq8XMWUPC7-nqfKOHFc7r8I~hnOD8FsVL9Tpb&{ePmLpzACn=g? zIpTG7lA;-wBVJD@DVkw9;`Mcsq8XMW-ascQnqfKO4Rw;D8I~j7NGBf_M z&9EHtRys-149gL3t&( z6wR<4@g6!!(G1HG@2Qg%&9EHtUOGw949gMkt&q8XMWzDOr2nqfKojNAWpie^}j_+p);Xols8FVRVgW>}8+Qk|q| zhUJJa(@BbESdRE|oup`n<%qA)Ns4Azj`&KQq-ciah_BK~ie^}j_-dV`Xols8uhB`0 zW>}8+TAie5hUJK_(@BbESdRF5oup`n<%n<4Ns4Azj`&8Mq-ciah;PzKie^}j_-37? zXols8Z_!DLW>}8+R-L41hUJKF(@BbESdRF1oup`n<%sXlNs4Azj`&WUq-ciai0{%# zie^}j_->t~Xols8@6kz$W>}8+UY(?9hUJLw(@BbESdRF9oup`n<%l29Ns4Azj`%^H zq-ciaa1pov>lDqf9PvXsNzn|;5kIVx6wR<4@gq7((G1HGKdO@y&9EHtV>(IE49gKe zu9FnaupIFdI!VzC%Mm}RlN8Oc9Pv{+Nzn|;5kIYy6wR<4@iRI}(G1HGKdX}z&9EHt zb2>@U49gKeuagwbupIFVI!VzC%Mrh*lN8Oc9Pvv!Nzn|;5x=aH6wR<4@hdt>(G1HG zzp9fI&9EHtYdT5M49gL}u9FnaupIFlI!VzC%Mrh+lN8Oc9PwK^Nzn|;5x=dI6wR<4 z@jE(6(G1HGzpIlJ&9EHtdpb$c49gL}uagwbupIFRI!VzC%i$5u{;yLs!*awQ>Lf)o zEJys2PEs_(a>O6&BtLf)oEJr+4Cn=g?IpVK$lA;-wBmP<^DVkw9;%{`4q8XMW{#GX`nqfKO?{t!) z8I~jdUMDG^(G1HGkE4?m z&9EHtxH?JE49gLZr;`-TupIIDI!VzC%MnkYlN8Oc9PxxYNzn|;5l^I(6wR<4@x(ew z(G1HGPok3)&9EHtq&i8_49gKurjr!SupIH^I!VzC%MnkZlN8Oc9PyMoNzn|;5l^L) z6wR<4#y9)FPSFg@5l^j?6wR<4@iaO~(G1HGPpgv@&9EHtbUI1V49gKuuagwbupIFW zI!VzC%Ms70lN8Oc9Pvy#Nzn|;5znlX6wR<4@hmz?(G1HG&#IFY&9EHtY&uEN49gME zu9FnaupIFmI!VzC%Ms71lN8Oc9PwN_Nzn|;5znoY6wR<4@jN<7(G1HG&#RLZ&9EHt zd^$W}7RYn`NMhUJL2(MgJCSdMsGoup`n<%qY_Ns4Azj(B^W zq-ciah}7RXPu;IhUJKN(MgJCSdMsCoup`n<%oCF zNs4Azj(B&Sq-ciai1*M*ie^}jcu$?AXols8_tHs}7RZ=IxQhUJL&(MgJCSdMsK zoup`n<%svwNs4Azj(C5aq-ciah!4<7ie^}j_&}YcXols857J4BW>}8+V4b9BhUM_V zjR%kv&9EHtAv#IX49gK8s*@DWupIGWI!VzC%Ml;0lN8Oc9Ptr4Nzn|;5g)0O6wR<4 z@liTS(G1HGAFY!V&9EHtF*-@n49gK8tCJMXupIGmI!VzC%Ml;1lN8Oc9PtS{Nzn|; z5ud1&6wR<4@ku&K(G1HGpRAJ<&9EHtDLP5f49gLps*@DWupIGeI!VzC%MqWhlN8Oc z9Pt@CNzn|;5ud4(6wR<4@mV@a(G1HGpRJP=&9EHtIXX$v49gLptCJMXupIGuI!VzC z%MqWilN8Oc9PtG@Nzn|;5nrg26wR<4@kKgG(G1JsXWRa-Q#8YJ#24!%MKdf%e2Gp{ zG{bVlm+B-%Gb~4ZnNCtP!*axz>m)@pEJu8WPEs_(a>Q5aBtMi zMKdf%e2q?0G{bVl*XkriGb~4Zola6T!*aye>m)@pEJu8UPEs_(a>O_4Btm)@pEJu8YPEs_(a>RG) zBtm)@pEJyr+ zPEs_(a>NhnBt<%l2BNs4Azj`(4nq-ciah#%2Oie^}j_)(ptXols8 zAJa*SW>}8+ah;@ShUJK#&`FABSdREfoup`n<%plsNs4Azj`(Svq-ciah@a6(ie^}j z_*tE#Xols8pVLW-W>}8+d7Y$ahUJJ~&`FABSdREboup`n<%nO>Ns4Azj`(Grq-cia zh+ol3ie^}j_*I>xXols8U(-p7W>}8+b)BSWhUJLg&`FABSdREjoup`n<%r+XNs4Az zj`(ezq-ciah~Lpkie^}j_+6c(Xols8-_uEoW>}8+eVwFehUJJq&`FABSPqYD_J5tC z8I~jdP$wyxVL9TDbdsVOmLvXHCn=g?IpR-rlA;-wBmPt;DVkw9;?H!Fq8XMW{#++1 znqfKOFLaWk8I~jdQYR^zVL9TVI!VzC%MpL2lN8Oc9P!sWNzn|;5r3nT6wR<4@wYlj z(G1HGf2Wfa&9EHt_c}?@49gM!ppz8MupIG^I!VzC%Mt&ilN8Oc9P!UONzn|;5&xo- z6wR<4@vk~b(G1HG|E7}^&9EHt?>b4*49gM!p_3HNupIH9I!VzC%Mt&jlN8Oc9P!^e zNzn|;5&xr;6wR<4@xMAr(G1HG|EH4_&9EFE*zNxhw*Noa{{P@;hUJKd(MgJCSdMsD zoup`n<%oyVNs4Azj(B*Tq-ciah)2*#ie^}jcto9~Xols8N76}(W>}7RWSyjFhUJJy z(MgJCSdMs9oup`n<%mbqNs4Azj(BvPq-ciah{w=Lie^}jcubw7Xols8$I?lPW>}7R zY@MWNhUJLI(MgJCSdMsHoup`n<%q}ANs4Azj(B{Xq-ciah$qlVie^}jctV||Xols8 zC(=oZW>}7RVx6RDhUJJS(MgJCSdMs7oup`n<%lQKNs4Azj(BpNq-ciah^Np=ie^}j zcuJk5Xols8r_xD^W>^m6n*Cp=Xols8r`Ab|W>}7R8l9wQhUJK-)k%tGSdMr)oup`n z<%p-(Ns4Azj(7&0q-ciah-cJEie^}jcqW~sXols8XVyuIW>}7R7M-MMhUJK7)k%tG zSdMr$oup`n<%nn3Ns4Azj(858q-ciai09Nvie^}jcrKl!Xols8=hjJzW>}7R9-X9U zhUJLo)k%tGSdMr;oup`n<%s9kNs4Azj(7o`q-ciah!@mJie^}jcp;snXols87uHFN zW>}7R5uK!HhUJJC)k%tGSdMrxoup`n<%k#8Ns4Azj(7>3q-ciah?mq!ie^|2!@B)n zr)Y-dh?mkyie^}jcxj!aXols82kIn6Gb~3uNGB}7R1)Zd5hUJJ?)JckFSdMrloup`n<%n0- zNs4Azj(8QFq-ciah*#A~ie^}jcr~4*Xols8SJz33W>}7R4V|QDhUJLY)JckFSdMrt zoup`n<%rkTNs4Azj(8oNq-ciah}YFgie^}jcs-q@Xols8*VjpkW>}7R1D&L3hUJJi z)JckFSdMrjoup`n<%l=dNs4Azj(8KDq-ciaaH#D6Iz=-qN4%*{QZ&PI#GC0PMKdf% zytz(NG{bVlTj(T3Gb~5ErA|^b!*ax1=_ExnEJwVxPEs_(a>U!{BtTpnBt}QZ&PI#JlMvMKdf%yt__PG{bVld*~!ZGb~5Er%qBd!*axX=_ExnEJwVzPEs_( za>V=SBtPEs_(a`>Re14xQySdRD*oup`n<%kc}Ns4Azj`%R0q-ciah!59Eie^}j_z0b( zXols8kJL$uW>}8+D4nEehUJKl)=7$HSdRD@oup`n<%o~fNs4Azj`%p8q-ciah>zDv zie^}j_ynD#Xols8Pt-|@W>}8+B%P#ahUJJ))=7$HSdRDr^ie^}j_zaz-Xols8&(ukZW>}8+ES;oihUJLQ)=7$HSdRD{oup`n<%rMK zNs4Azj`%#Cq-ciah|kwaie^}j_yV1zXols8FVsnjW>}8+BAujYhUM@x9SDVkw9;wyEMq8XMW zzDg%4nqfKOt96p18I~iyMkgtnVL9S!b&{ePmLtASCn=g?IpXVelA;-wBfdc=DVkw9 z;v036q8XMWzDXx3nqfKOn{|?+8I~iyMJFkmVL9Skb&{ePmLtARCn=g?IpW)OlA;-w zBfdi?DVkw9;yZPcq8XMWzDp-5nqfKOyLFPH8I~iyM<*$oVL9S^b&{ePmLtATCn=g? zIpX_ulA;-wBYr?9DVkw9;sP&QBtOs_BtQ@wBt&MKdf%{I*U~G{bVl@8~2&Gb~5^u1-=k!*ay$=_ExnEJyslPEs_(a>O6# zBt}8+Tb-n6hUJLA(@BbESdRF6oup`n<%oaKNs4Azj`&BNq-ciah=0;aie^}j z_-CD@Xols8f6+;bW>}8+SDmD2hUJKV(@BbESdRF2oup`n<%s{#Ns4Azj`&ZVq-cia zi2u?_ie^}j_-~!0Xols8|ItZ`W>}8+U!A0AhUJL=(@BbESPl>9_Wy_2{~u!ie~A76 zAu%jRJd93KG{bVl!|EhOGb~3uoK8|S!*ayK>m)@pEJr+oPEs_(a>OI*Bt?IG{bVlqv|9@Gb~3unod$Q!*ax<>m)@pEJr+sPEs_(a>Qfm zBtm)@pEJr+n zPEs_(a>NtrBtm)@pEJr+rPEs_(a>P^WBtO&~BtR4#BtNViBtPsPBt}7Rh)z;8!*ayS=p;omEJwVoPEs_(a>UE&BtT3YBtVQDBt*hJ8I~j7M<*$oVL9S`b&{ePmLuLzCn=g?IpY0wlA;-wBR)VUDVkw9 z;sbS(q8XMWK1e4inqfKOgLRUk8J5Eb)BdkhG{bVlhv+0lGb~4Zs7_Ke!*axj=_Exn zEJu8}PEs_(a>PgIBtOU-BtQroBtN(tBtQ=o&9EHt zZ8}NO49gMUu9FnaupIFnI!VzC%MstHlN8Oc9PwQ`Nzn|;5#Ozo6wR<4@jW_8(G1HG z->Z`p&9EHteL6|e49gMUuagwbupIFNI!VzC%Mm}QlN8Oc94^Z70Ft5^mLq;hCn=g? zIpT+PlA;-wBYs3DDVkw9;zxCoq8XMWeoQARnqfKO$90mT8I~h{LMJJjVL9R_b&{eP zmLq;jCn=g?IpU{vlA;-wBYs9FDVkw9;%9Y|q8XMWeoiMTnqfKO=XH{z8I~h{K_@Ai zVL9R#b&{ePmLq;iCn=g?IpUXflA;-wBYs6EDVkw9;#YN&q8XMWeoZGSnqfKO*L9Mj z8I~h{LnkSkVL9SAb&{ePmLq;kCn=g?IpVi}8+L!G2(hUJJq(n*SDSdRE(oup`n<%mDg zNs4Azj`&lZq-ciah(FUwie^}j_;a14Xols8ztBmFW>}8+OP!=>hUJKd>Lf)oEJys6 zPEs_(a>V~LY>&bIpvm2b`-yGaww(?)w%M_5ZpXIWv8~;WI=1bOH{RIEb5-qC-|G3i z*{PcO&pE&QoWIdYie^}j_*}8+d!3|chUJKd=_ExnEJyrPICBtm)@p zEJyr@PEs_(a>Re?BtLf)oEJr+&PEs_(a>OI+BtLf)oEJr++PEs_(a>QfnBtLf)oEJr+%PEs_(a>NtsBtLf)oEJr+*PEs_(a>P^XBtUc=BtTRgBtVoLBtR@2BtOg>Bt}7R zJDsFxhUJL2*GY}7RH=U$thUJKN*GYie^}j zcpsglXols8_ti;?W>}7RKb@p#hUJL&*GYXols857kMEW>}8+FrB1mhUJJ4*GYm)@pEJu8ePEs_(a>Uo_BtG{bVlH|iusGb~4ZlTK1J!*awo>m)@pEJu8cPEs_(a>Tdl zBtm)@pEJu8g zPEs_(a>V!QBt}8+KAog!hUJLw*GYB49gL}sFM`UupIGAI!VzC%Mrh}8+2c4v7hUJKV)JckFSdRE7oup`n<%oaQ zNs4Azj`$ayq-ciah=0{die^}j_&1%TXols8f7eNhW>}8+51piFhUJL=)JckFSdREF zoup`n<%s{*Ns4Azj`$y)q-ciai2v0|ie^}j_&=SbXoltR0f7H~r~NK(0W`yM#CLlm z=4p5ylGmbmPnwVC)A@XcujAWz5X(>TOZ*ncLwOkgPJEA_0pL-13?7Fk;7NE2o`z@O zS$GbfhZo>QcnOl1=aqOhUW?b`jd(MPx8)sqSKgEN0 zl!~f5*f4NB)_A<=^>F{+s_LzSqxq@NhglkH91H zNIWu+!lUwNJUWlTWAa!$Hjl&O@_0NxPrwuML_9H1!jtl3JULInQ}R?iHBZCS@^m~s z&%iVCOguBs!n5*hJUh?9bMjm~H_yZK@_al$FTe}(LcB09!i(}^yf`nxOY%~@G|9{G zvb-EG&nxhXJb+i?m3b9jl~?1{c@18Z*W$H#9bT8$H^lsDtec?;f> z;;ndV-iEj3?Rb0Mfp_GccxT>)cjeu9ciw~dpJs_q zx5Q^y;xjGrS(f;0OMH$cKGzbTXNk|Z#1~lN3oY?QmiS^ze2FE#)DmB2@y(#mJnWZS z;wvoim6rG_OMJB@zQz(?Yl*M3#MfKm8!YjSmiQ)1e6uCK#S-6YiEp#Sw_D;nEb*O| z_%2I)w0t zE%95H_-#x4jwOEA62E7O-?zjcSmF;YJ_PVJul*xS{IMne#1emMi9fT%pIhQDEb&lF z{G}!S$`XHViNCSL-&*4DEb;f2c$g*r!4m&yiGQ-hKU?BoEb*_F_%}=ZyCwd^68~w5 z|FXn?TjGB#@xPY%KZ}2W{OsR@d=>B@KlAq>|1EISEb(w|nk63IO|!%!xM`MnL^sV6 zkL0FV;*s4nOFW93W{F32(=735ZkimzXG)p{=n`Vi} zb<-^Icy5{{9^Xx~#1pt_mUu!p%@R-Krdi^N-84%)iJNALCw0>-@nmkAC7#?(v&2)l zX_k0OH_Z}H<)&HUsogY-55N5EmzyP?)=jg-)46GuczQR@63^hKS>hSpG)p{_n`Vh; zcGE2JEN+@5p4CmW#Iw0+mUwnI%@WVyrdi@S-84%)mz!pZ=XTR9@jPytC7#z!v&8ec zX_k0?H_Z|+;HFvP1>H1DypWq_i5GU$Eb$_4nk8P;O|!&{xoMVoaW~BpFX5(H;w9ZQ zOT3huW{H<}(=0yt^s_&1mUtOA%@Qx`rdi_U+%!wPyqji;S8&rT@rrJmB_80WS>l!4 zG)ug)n`VhuanmgEs&1MkUd>Ij#H+h$mUs;}%@VKardi^(+%!wPwwq>&*KyM<@w#rB zC0@@>v&8GWX_j~cH_Z}n=%!iXjodU#ys?{Ri8pc6Eb*ppnkC-MO|!(CyJ?nq3pdRY zZ|SC4eCX|GKin+wR&JUl-r7yG#M`)OmUvq?%@S|trdi_c-84(QgPUfFcXZP%@lI}< zCEnRhv&6f&X_k0bH_a07=B8QV-Q6@xyoZ}+iT8BVEb(4$nkC-bO|!)NxM`MnUpLJX z@8_mj;{Dw;OMHNvW{D4U(=72pZki=N*iEynUpG)p|tO|$so z(fhx@M$rt*5g(zG6wR<4@sT=7(G1HGAElEN&9EHt(K<=d49gK8qmvZPupIHRI!VzC z%Ml-^lN8Oc9P#lwNzn|;5uc!w6wR<4@rgP~(G1HGpQMu%&9EHt$vR2V49gLpqLUQO zupIHJI!VzC%MqWZlN8Oc9P#NoNzn|;5uc%x6wR<4@tHbF(G1HGpQV!&&9EHt**Zzl z49gLpqmvZPupIHZI!VzC%MqWalN8Oc9P#-&Nzn|;5nrH_6wR<4@r61`(G1HGU!;>1 z&9EHt#X3pR49gK;qLUQOupIHFI!VzC%Mo9ulN8Oc93DHp|LYXZupIH_I!VzC%Mo9p zlN8Oc9PyPpNzn|;5nrW~6wR<4@zpv>(G1HGU!#*0&9EHtwK_@B49gK;r;`-TupIIA zI!VzC%Mst8lN8Oc9Py1hNzn|;5#OYf6wR<4@y$9((G1HG-=dQg&9EHttvX5349gMU zrjr!SupII2I!VzC%Mst9lN8Oc9PynxNzn|;5#Obg6wR<4@!dK}(G1HG-=mWh&9EHt zy*f$J49gJ@(n*SDSdMtGPEs_(a>PS)lA;-wBfd{3DVkw9;`?=yq8XMWen2NFnqfKO z2X&I78I~h{NGBIq8XMWeo7}PnqfKOr*)E|8I~h{MkgtnVL9Swb&{eP zmLq;nCn=g?IpXJalA;-wBYr_ADVkw9;um$2q8XMWen}@OnqfKOmvxe&8I~h{MJFkm zVL9Sgb&{ePmLq;mCn=g?IpWuKlA;-wBYs0CDVkw9;x~1Yq8XMWeoH4QnqfKOw{?=D z8I~h{M<*$oVL9S=b&{ePmLq;oCn=g?IpX(qlA;-wBmO`qDVkw9;tzF_q8XOMA9CLR zb&6(Kj`$;;q-ciah(Fdzie^}j_!FI^Xols8Kh;T!W>}8+Go7SphUJJq*GYSoGb~5^txi%j!*aym z=_ExnEJyskPEs_(a>T=QlA;-wBmO}rDVkw9;vaRAq8XMW{z)e(nqfKOpLLR=8I~jd zMJFkmVL9Sob&{ePmLvX6Cn=g?IpW`SlA;-wBmP4tDVkw9;y-ngq8XMW{!1q*nqfKO zzjczL8I~jdM<*$oVL9S|b&{ePmLvX8Cn=g?IedZR_x~U44dB6k|Np_>0Uqr4{~zov z;K6ak|I}7RIGv}7RG@YbqhUJJy*GY}7RJe{OyhUJLI*GY}7RGM%JohUJJS*GY3<$nqfKOnRJq(8I~iSStlu)VL9SibdsVOmLr~3Cn=g? zIpW!LlA;-wBc5F+DVkw9;yHAZq8XMWo>M0&nqfKOxpb1E8I~iSTPG=+VL9S?bdsVO zmLr~5Cn=g?IpX;gl8I~hnSSKl( zVL9SObdsVOmLpzNCn=g?IpW21lA;-wBVJr5DVkw9;w5yFq8XMWUQ#D1nqfKOrF4>_ z8I~hnS|=%*VL5!T;rIV_ie^}jcp06fXols8m(@v%W>}7RIh~|vhUJKt*GYQ%sBt*yp!Gb~5E zu1-=k!*ayy=_ExnEJwV)PEs_(a>N_xBtQHcBt}8+NS&l;hUJKl z(n*SDSdRE;oup`n<%o~bNs4Azj`&!eq-ciah>z1rie^}j_;{V9Xols8PtZw}8+ zM4hB)hUJJ)(n*SDSdRE)oup`n<%mzwNs4Azj`&oaq-ciah)>f=ie^}j_;j75Xols8 z&(KMVW>}8+Or4}?hUJLQ(n*SDSdRE?oup`n<%rMGNs4Azj`&=iq-ciah|kkWie^}j z_}8+LY<^&hUJJa(n*SDSdRE&oup`n<%loQNs4Azj`&iYq-cia zh%eJgie^|2kD1>8b&6(Kj`(t&q-ciah_BE|ie^}j_)49mXols8uhL11W>}8+YMrEL zhUJK_(MgJCSdREwoup`n<%qA-Ns4Azj`(_=q-ciah;PtIie^}j_(q+iXols8Z_-JM zW>}8+W}T#HhUJKF(MgJCSdREsoup`n<%n<7Ns4Azj`((+q-ciai0{xzie^}j_)eXq zXols8@6t(%W>}8+Zk?oPhUJLw(MgJCSdRE!oup`n<%kFABt~iQupIHrI!VzC%Mrh#lN8Oc9Pz6tC+49gL}rIQrRupIH*I!VzC%Mrh$lN8Oc9Pzt4Nzn|;5x=LC6wR<4 z@%uVS(G1HGf1r~T&9EHthdN2o49npUG4KC6MKdf%{E<#lG{bVlAL}GVGb~5^iB3{9 z!*ax*>Lf)oEJysAPEs_(a>SqOBtT(G1HG|Dcl; z&9EHtk2*=w49gM!q>~iQupIHvI!VzC%Mt&glN8Oc9PzI@Nzn|;5&x!>6wR<4@$WiG z(G1HG|Dlr<&9EHtpE^m=49gM!rIQrRupIH^(G1HGkE4?m&9EHtxH?JE z49gLZr;`-TupIIDI!VzC%MnkYlN8Oc9PxxYNzn|;5l^I(6wR<4@x(ew(G1HGPok3) z&9EHtq&i8_49gKurjr!SupIH^I!VzC%MnkZlN8Oc9PyMoNzn|;5l^L)6wR<4@zgp= z(G1Jsn-}l@Iz=-qM?9@gQZ&PI#M9{{MKdf%JiSg*G{bVlGw38mGb~3uqfSyZ!*awk z=_ExnEJr-EPEs_(a>TRfBtRGb~3u zr%qBd!*axP=_ExnEJr-IPEs_(a>VoKBtR@1Bt}7RC7q;b zhUJJ?)=7$HSdMrVoup`n<%n0+Ns4Azj(9blq-ciah*#H1ie^}jcnzJTXols8*VIXh zW>}7REuExjhUJLY)=7$HSdMrdoup`n<%rkSNs4Azj(9ztq-ciah}YLiie^}jcmtiJ zXols8H`GarW>}7RBb}sZhUJJi)=7$HSdMrToup`n<%l=cNs4Azj(9Vjq-ciah&R_s zie^}jcnh7RXols8x710BW>^j%T6+K2DVkw9;;nR&q8XMW-dZOqnqfKOZFG{N8I~j7 zRwpT%VL9UMbdsVOmLuL?Cn=g?IpQ63lA;-wBi>ObDVkw9;+=Goq8XMW-dQIpnqfKO zU38M78I~j7RVOK$VL9U6bdsVOmLuL>Cn=g?IpRHZlA;-wBi>UdDVkw9;=Oc|q8XMW z-diUrnqfKOeRPtd8I~j7S0^c&VL9UcbdsVOmLuL@Cn=g?IpPC!lA;-wBR)_kDVkw9 z;)8UOq8XMWK3FFynqfKOLv)g&8I~hHR3|B#VL9T%bdsVOmLon~Cn=g?IpTpjNzn|; z;laZDzfRE%%Ml-;lN8Oc9PyDlNzn|;5g(49gMUppz8MupIG?I!VzC%MstClN8Oc9P!OMNzn|;5#OSd6wR<4@vS;Z(G1HG z-=>ok&9EHt?K(-(49gMUp_3HNupIH7I!VzC%MstDlN8Oc9P!;cNzn|;5#OVe6wR<4 z@x3}p(G1HG57J4BW>}7Ruuf7m!*aw!bdsVOmLtATCn=g?IpX_ulA;-wBYr?9DVkw9 z;sm)@pEJyr=PEs_(a>P&SBtm)@pEJyr;PEs_(a>Os{Btm)@pEJyr?PEs_(a>Q@yBtm)@pEJyr-PEs_(a>O6%Bt}8+d!3|chUNb=WKU5LZOa)(Ys9uWV%x6Rwkx*nify}M+d221RBYQ7+ji!| zeENEH_tPG0um6a@*GY}8+H=U$thUJKV*GY}8+Kb@p#hUIWTvHw3{|9`;#|A77f0sH?0_WuX${}0&z zb&{ePmLncUCn=g?IpSe;lA;-wBOXpCDVkw9;^B3Yq8XMW9ziE5nqfKO5p|NH8I~g+ zNhc|qVL9TFb&{ePmLncTCn=g?IpR@ulA;-wBOXmBDVkw9;?Z@Iq8XMW9z!Q7nqfKO zF?Eun8I~g+OD8FsVL9Tlb&{ePmLncVCn=g?IpT43lA;-wBOXsDDVkw9;_-Eoq8XMW zomTAq8XMWo}7RYMrELhUJK-(MgJC zSdMsFoup`n<%p-#Ns4Azj(B>Vq-ciah-c7Aie^}jct)M1Xols8XVOWEW>}7RW}T#H zhUJK7(MgJCSdMsBoup`n<%nm~Ns4Azj(B#Rq-ciai09Brie^}jcut+9Xols8=h8`v zW>}7RZk?oPhUJLo(MgJCSdMsJoup`n<%s9gNs4Azj(C2Zq-ciah!@aFie^}jctM?{ zXols87t%?JW>}7RVV$IChUJJC(MgJCSdMs6oup`n<%k#4Ns4Azj(BmMq-ciah?mew zie^|27Zdh>ouV0*BVJM`DVkw9;-z$wq8XMWURoz9nqfKOWpt9F8I~hnRwpT%VL9UE zbdsVOmLpzXCn=g?IpP&`lA;-wBVJJ_DVkw9;+1rgq8XMWURft8nqfKORdkY~8I~hn zRVOK$VL9T}bdsVOmLpzWCn=g?IpQ^RlA;-wBVJP{DVkw9;=q8XMWURx(AnqfKO zb##)V8I~hnS0^c&VL9UUbdsVOmLpzYCn=g?IpPg;lA;-wBi>LaDVkw9;*E5Yq8XMW z-dHConqfKOO>~l?8I~j7R3|B#VL9T>bdsVOmLuL=Cn=g?Ib2HG|8}7RJDsFxhUJL2*GY}7RH=U$t zhUJKN*GYie^}jcpsglXols8_ti;? zW>}7RKb@p#hUJL&*GY zXols857kMEW>}8+FrB1mhUG9w*#C8kW>}8+aGj)RhUJKl&`FABSdREeoup`n<%o~c zNs4Azj`(Puq-ciah>y`pie^}j_*k8!Xols8kJCwtW>}8+c%7tZhUJJ)&`FABSdREa zoup`n<%mzxNs4Azj`(Dqq-ciah)>Z;ie^}j_*9*wXols8Pt!??W>}8+be*JVhUJLQ z&`FABSdREioup`n<%rMHNs4Azj`(byq-ciah|keUie^}j_*|W&Xols8&(leYW>}8+ ze4V6dhUJJa&`FABSdREYoup`n<%loRNs4Azj`(7oq-ciah%eDeie^}j_)?vuXolr5 zM%w>%ie^}j_%fZOXols8FV{(mW>}8+3Z0~AhUJK_)JckFSdREAoup`n<%qA=Ns4Az zj`$j#q-ciah_BU2ie^}j_&S}WXols8uh&V6W>}8+2A!m6hUJKF)JckFSdRE6oup`n z<%n}8+4xOZEhUJLw)JckF zSdREEoup`n<%sXrNs4Azj`$v(q-ciai0{=&ie^}j_&%MaXols8@7GC+W>}7RKqo1h zVL9Rh7f49gKeqmvZPupIHTI!VzC%Mm}PlN8Oc9P#ryNzn|;5x=05 z6wR<4@ryc1(G1HGzoe5C&9EHt%Q{KX49gL}qLUQOupIHLI!VzC%Mrh(lN8Oc9P#Tq zNzn|;5x=366wR<4@tZnH(G1HGzonBD&9EHt+d4_n49gL}qmvZPupIHbI!VzC%Mrh) zlN8Oc9P#@)Nzn|;;UQ%I*D0D|IpPm=lA;-wBmPh)DVkw9;*WHaq8XMW{#Yj|nqfKO zPjr%^8I~jdR3|B#VL9T@bdsVOmLvXLCn=g?IpQyLlA;-wBmPn+DVkw9;;(d)q8XMW z{#qv~nqfKOZ*-EP8I~jdRwpT%VL9UObdsVOmLvXNCn=g?IpQC5lA;-wBmPk*DVkw9 z;-7Sqq8XMW{#hp}nqfKOUv!e98I~jdRVOK$VL9U8bdsVOmLvXMCn=g?IpRNblA;-w zBmPq-DVkw9;=go~q8XMW{#z$0nqfKOe{_m)@pEJr+yPEs_(a>T>xBtm)@pEJr+wPEs_(a>S$RBtm)@pEJr+!PEs_(a>V26 zBtm)@pEJr+v zPEs_(a>SGBBtOg>BtQ%sBt*yp!Gb~5Eu1-=k!*ayy=_ExnEJwV)PEs_(a>N_x zBtlN8Oc9Pw5y6O&9EHtb~;JX49gL3uagwbupIFYI!VzC%MtIWlN8Oc9Pv&%Nzn|;5$~*%6wR<4 z@h&<^(G1HG@2Zm&&9EHtZaPWP49gMku9FnaupIFoI!VzC%MtIXlN8Oc9PwT{Nzn|; z5$~;&6wR<4@jg09(G1HG@2is(&9EHtemY6f49gMkuagwbupIFLI!VzC%Ml-_lN8Oc z9PvRqNzn|;5g)9R6wR<4@gX`%(G1HGAF7iS&9EHtVLD0C49j6~u>b26&9EHt;W|mt z49gK8p_3HNupIG`I!VzC%Ml-?lN8Oc9P!aQNzn|;5g((I6wR<4@v%Bd(G1HGAE%QP z&9EHt@j6M-49gLpppz8MupIG;I!VzC%MqWXlN8Oc9P!CINzn|;5uc)y6wR<4@u@mV z(G1HGpQe)(&9EHt={iZ#49gLpp_3HNupIH3I!VzC%MqWYlN8Oc9P!yYNzn|;5uc-z z6wR<4@wqxl(G1HGpQn=)&9EHt`8r9_49gK;ppz8MupIG)I!VzC%Mo9slN8Oc9P!0E zNzn|;5nrN{6wR<4@ufOR(G1IBY_$LD6wR<4@nt$m(G1HGU#^oB&9EHt6*@`L49gK; zsgo4VupIGKI!VzC%Mo9#lN8Oc9Pu?eNzn|;5nrp56wR<4@pU>$(G1HGU$2uC&9EHt z4LV8D49gMUsFM`UupIGCI!VzC%MstKlN8Oc9PuqWNzn|;5#Oql6wR<4@ohRu(G1HG z->#Ds&9EHt9Xd(T49gMUsgo4VupIGSI!VzC%MstLlN8Oc9PvFmNzn|;5#Otm6wR<4 z@qIc;(G1HG->;Jt&9EHtfKF00!*aw!bdsVOmLndjlN8Oc9Pyw|QZ&PI#1H5sMKdgi zAF}`J6wR<4@q;=^(G1HGKctfs&9EHt!#YXP49gKeqLUQOupIHDI!VzC%Mm}OlN8Oc z9P#5iNzn|;5kH}m6wR<4@sm19(G1HGKc$lt&9EHt(>h7f49gKeqmvZPupIHTI!VzC z%Mm}PlN8Oc9P#ryNzn|;5x=056wR<4@ryc1(G1HGzoe5C&9EHt%Q{KX49gL}qLUQO zupIHLI!VzC%Mrh(lN8Oc9P#TqNzn|;5x=366wR<4@tZnH(G1HGzonBD&9EHt+d4_n z49gL}qmvZPupIHbI!VzC%Mrh)lN8Oc9P#@)Nzn|;;UQ!H*D0D|IpPm=lA;-wBmPh) zDVkw9;*WHaq8XMW{#Yj|nqfKOPjr%^8I~jdR3|B#VL9T@bdsVOmLvXLCn=g?IpQyL zlA;-wBmPn+DVkw9;;(d)q8XMW{#qv~nqfKOZ*-EP8I~jdRwpT%VL9UObdsVOmLvXN zCn=g?IpQC5lA;-wBmPk*DVkw9;-7Sqq8XMW{#hp}nqfKOUv!e98I~jdRVOK$VL9U8 zbdsVOmLvXMCn=g?IpRNblA;-wBmPq-DVkw9;=go~q8XMW{#z$0nqfKOe{_|3mHn54Hb4)c*fa`~O4j{|~kQ>m)@pEJr+yPEs_( za>T>xBtm)@p zEJr+wPEs_(a>S$RBtm)@pEJr+!PEs_(a>V26Btm)@pEJr+vPEs_(a>SGBBtOg>BtQ%sBt*yp!Gb~5Eu1-=k z!*ayy=_ExnEJwV)PEs_(a>N_xBtlN8Oc9Pw5< zNzn|;5pS)N6wR<4@isb1(G1HGZ>y6O&9EHtb~;JX49gL3uagwbupIFYI!VzC%MtIW zlN8Oc9Pv&%Nzn|;5$~*%6wR<4@h&<^(G1HG@2Zm&&9EHtZaPWP49gMku9FnaupIFo zI!VzC%MtIXlN8Oc9PwT{Nzn|;5$~;&6wR<4@jg09(G1HG@2is(&9EHtemY6f49gMk zuagwbupIFLI!VzC%Ml-_lN8Oc9PvRqNzn|;5g)9R6wR<4@gX`%(G1HGAF7iS&9EHt zVLD0C49j6qu>b26&9EHt;W|mt49gK8p_3HNupIG`I!VzC%Ml-?lN8Oc9P!aQNzn|; z5g((I6wR<4@v%Bd(G1HGAE%QP&9EHt@j6M-49gLpppz8MupIG;I!VzC%MqWXlN8Oc z9P!CINzn|;5uc)y6wR<4@u@mV(G1HGpQe)(&9EHt={iZ#49gLpp_3HNupIH3I!VzC z%MqWYlN8Oc9P!yYNzn|;5uc-z6wR<4@wqxl(G1HGpQn=)&9EHt`8r9_49gK;ppz8M zupIG)I!VzC%Mo9slN8Oc9P!0ENzn|;5nrN{6wR<4@ufOR(G1IBOtk;&6wR<4@nt$m z(G1HGU#^oB&9EHt6*@`L49gK;sgo4VupIGKI!VzC%Mo9#lN8Oc9Pu?eNzn|;5nrp5 z6wR<4@pU>$(G1HGU$2uC&9EHt4LV8D49gMUsFM`UupIGCI!VzC%MstKlN8Oc9PuqW zNzn|;5#Oql6wR<4@ohRu(G1HG->#Ds&9EHt9Xd(T49gMUsgo4VupIGSI!VzC%MstL zlN8Oc9PvFmNzn|;5#Otm6wR<4@qIc;(G1HG->;Jt&9EHtfKF00!*aw!bdsVOmLndj zlN8Oc9Pyw|QZ&PI#1H5sMKdgiFS7sZ6wR<4@q;=^(G1HGKctfs&9EHt!#YXP49gKe zqLUQOupIHDI!VzC%Mm}OlN8Oc9P#5iNzn|;5kH}m6wR<4@sm19(G1HGKc$lt&9EHt z(>h7f49gKeqmvZPupIHTI!VzC%Mm}PlN8Oc9P#ryNzn|;5x=056wR<4@ryc1(G1HG zzoe5C&9EHt%Q{KX49gL}qLUQOupIHLI!VzC%Mrh(lN8Oc9P#TqNzn|;5x=366wR<4 z@tZnH(G1HGzonBD&9EHt+d4_n49gL}qmvZPupIHbI!VzC%Mrh)lN8Oc9P#@)Nzn|; z;UQxG*D0D|IpPm=lA;-wBmPh)DVkw9;*WHaq8XMW{#Yj|nqfKOPjr%^8I~jdR3|B# zVL9T@bdsVOmLvXLCn=g?IpQyLlA;-wBmPn+DVkw9;;(d)q8XMW{#qv~nqfKOZ*-EP z8I~jdRwpT%VL9UObdsVOmLvXNCn=g?IpQC5lA;-wBmPk*DVkw9;-7Sqq8XMW{#hp} znqfKOUv!e98I~jdRVOK$VL9U8bdsVOmLvXMCn=g?IpRNblA;-wBmPq-DVkw9;=go~ zq8XMW{#z$0nqfKOe{_}7R1f8U4hUJJy z)JckFSdMrkoup`n<%mbtNs4Azj(8NEq-ciah)2~)ie^}jcr=})Xols8N7qS;W>}7R z44tHChUJLI)JckFSdMrsoup`n<%q}DNs4Azj(8lMq-ciah{x4Qie^}jcs!k?Xols8 z$Ja@UW>}7R0-dC2hUJJS)JckFSdMrioup`n<%lQNNs4Azj(8HCq-ciah$q!aie^}j zcru-&Xols8C)Y`eW>}7R3Z0~AhUJK-)JckFSPm}__J5tC8I~iSN+&6rVL9Tdb&{eP zmLr}C56 zq8XMWUP31+nqfIy9N7PLie^}jcuAe4Xols8m(od!W>}7RX`Q5KhUJKt(MgJCSdMsE zoup`n<%pNlNs4Azj(B;Uq-ciah*!`_ie^}jctxG0Xols8SJFv}W>}7RWu2sGhUJJ? z(MgJCSdMsAoup`n<%n0)Ns4Azj(ByQq-ciah}Y0bie^}jcuk$8Xols8*V0LfW>}7R zZJnfOhUJLY(MgJCSdMsIoup`n<%rkQNs4Azj(B~Yq-ciah&Rwlie^}jctf3}Xols8 zH_}OpW>}7RW1XaEhUJJi(MgJCSdMs8oup`n<%l=aNs4Azj(BsOq-ciaaA|1&*D0D| zIpQsJlA;-wBi>RcDVkw9;;nR&q8XMW-dZOqnqfKOZFG{N8I~j7RwpT%VL9UMbdsVO zmLuL?Cn=g?IpQ63lA;-wBi>ObDVkw9;+=Goq8XMW-dQIpnqfKOU38M78I~j7RVOK$ zVL9U6bdsVOmLuL>Cn=g?IpRHZlA;-wBi>UdDVkw9;=Oc|q8XMW-diUrnqfKOeRPtd z8I~j7S0^c&VL9UcbdsVOmLuL@Cn=g?IpPC!lA;-wBR)_kDVkw9;)8UOq8XMWK3FFy znqfKOLv)g&8I~hHR3|B#VL9T%bdsVOmcw9R|JNy+VL9T%b&{ePmLonwCn=g?IpQOA zlA;-wBR)zeDVkw9;-htvq8XMWK1L@gnqfKOV|9|E8I~hHPA4gvVL9UCb&{ePmLonv zCn=g?IpPy_lA;-wBR)wdDVkw9;*)ifq8XMWK1C-fnqfKOQ+1M}8I~hHO(!XuVL9T{ zb&{ePmLonxCn=g?IpQ;QlA;-wBR)$fDVkw9;8J5FXX#dwKnqfKO%XE^W8I~iyTqh}-VL9R}bdsVOmLtAWCn=g?IpV8ylA;-w zBfeTEDVkw9;%ju0q8XMWzE&qGnqfKO>vWQ$8I~iyUMDGwHnqfKO`*f0`8I~iyUneP= zVL9Rfoup`n<%oyqBt^j%wEycA&9EHtgE~pk z49gKeq>~iQupIHjI!VzC%Mm}KlN8Oc9Py(%Nzn|;5kIDr6wR<4@#8v4(G1HGKcSNp z&9EHtlR8P!49gKerIQrRupIHzI!VzC%Mm}LlN8Oc9PzU{Nzn|;5kIGs6wR<4@$))K z(G1HGzo3&8&9EHti#kcs49gL}q>~iQupIHrI!VzC%Mrh#lN8Oc9Pz6tC+49gL}rIQrRupIH*I!VzC%Mrh$lN8Oc9Pzt4 zNzn|;5x=LC6wR<4@%uVS(G1JsAz}a5DVkw9;tzC^q8XMW{!k|=nqfKOk93lv8I~jd zSSKl(VL9SYbdsVOmLvXDCn=g?IpWWBlA;-wBmP_`DVkw9;xBZPq8XMW{!%9?nqfKO zuXK{48I~jdS|=%*VL9S&bdsVOmLvXFCn=g?IpXhhlA;-wBmQ0|DVkw9;vaO9q8XMW z{!u3>nqfKOpLCL<8TS7R2_a&foW(;~p1B{IgC{G{bVlzvv`IGb~5^t4>lh!*ayG=_ExnEJysiPEs_(a>Re= zBt}7R1f8U4hUJJy)JckFSdMrkoup`n<%mbtNs4Az zj(8NEq-ciah)2~)ie^}jcr=})Xols8N7qS;W>}7R44tHChUJLI)JckFSdMrsoup`n z<%q}DNs4Azj(8lMq-ciah{x4Qie^}jcs!k?Xols8$Ja@UW>}7R0-dC2hUJJS)JckF zSdMrioup`n<%lQNNs4Azj(8HCq-ciah$q!aie^}jcru-&Xols8C)Y`eW>^j{2ljuR zq8XMWo}7RX`Q5KhUJKt(MgJCSdMsEoup`n<%pNlNs4Azj(B;Uq-cia zh*!`_ie^}jctxG0Xols8SJFv}W>}7RWu2sGhUJJ?(MgJCSdMsAoup`n<%n0)Ns4Az zj(ByQq-ciah}Y0bie^}jcuk$8Xols8*V0LfW>}7RZJnfOhUJLY(MgJCSdMsIoup`n z<%rkQNs4Azj(B~Yq-ciah&Rwlie^}jctf3}Xols8H_}OpW>}7RW1XaEhUJJi(MgJC zSdMs8oup`nbdsVOmLuL=Cn=g?IpQsJlA;-wBi>RcDVkw9;;nR& zq8XMW-dZOqnqfKOZFG{N8I~j7RwpT%VL9UMbdsVOmLuL?Cn=g?IpQ63lA;-wBi>Ob zDVkw9;+=Goq8XMW-dQIpnqfKOU38M78I~j7RVOK$VL9U6bdsVOmLuL>Cn=g?IpRHZ zlA;-wBi>UdDVkw9;=Oc|q8XMW-diUrnqfKOeRPtd8I~j7S0^c&VL9UcbdsVOmLuL@ zCn=g?IpPC!lA;-wBR)_kDVkw9;)8UOq8XMWK3FFynqfKOLv)g&8J5E!VE@-CnqfKO zLv@m(8I~hHOeZOtVL9T%b&{ePmLonwCn=g?IpQOAlA;-wBR)zeDVkw9;-htvq8XMW zK1L@gnqfKOV|9|E8I~hHPA4gvVL9UCb&{ePmLonvCn=g?IpPy_lA;-wBR)wdDVkw9 z;*)ifq8XMWK1C-fnqfKOQ+1M}8I~hHO(!XuVL9T{b&{ePmLonxCn=g?IpQ;QlA;-w zBR)$fDVkw9;vWQ$8I~iyUMDGwHnqfKO`*f0`8I~iyUneP=VL9RlbdsVOmLq;pCn=g?IpQHY zNzn|;;e-8Or)Y-dhzE6&q8XMWen=-NnqfKOhjo&o8I~h{L?Iq8XMWeo7}PnqfKOr*)E|8I~h{MkgtnVL9Sw zb&{ePmLq;nCn=g?IpXJalA;-wBYr_ADVkw9;um$2q8XMWen}@OnqfKOmvxe&8I~h{ zMJFkmVL9Sgb&{ePmLq;mCn=g?IpWuKlA;-wBYs0CDVkw9;x~1Yq8XMWeoH4QnqfKO zw{?=D8I~h{M<*$oVL9S=b&{ePmLq;oCn=g?IpX(qlA;-w!<%mDfNs4Az zj`%~Jq-ciah(FRvie^}j_+y=}8+Q=Oz}hUJJq(@BbESdRE}oup`n z<%qw~Ns4Azj`&NRq-ciah`-WFie^}j_-mb{Xols8ztKsGW>}8+Tb-n6hUJLA(@BbE zSdRF6oup`n<%oaKNs4Azj`&BNq-ciah=0;aie^}j_-CD@Xols8f6+;bW>}8+SDmD2 zhUJKV(@BbESdRF2oup`n<%s{#Ns4Azj`&ZVq-ciai2u?_ie^}j_-~!0Xols8|ItZ` zW>}8+U!A0AhUJL=(@BbESPlmO`~TYi*Z#lu|F!?`|NnRX$N$qwie^}jcqpBuXols8 zht^4oW>}7R7@eeOhUJKd)k%tGSdMr&oup`n<%oyZNs4Azj(CK%|LYXZupIG-I!VzC z%Mp*HlN8Oc9P!9HNzn|;5s#vi6wR<4@u)gU(G1HGkEW9p&9EHt=sHQ!49gLZp_3HN zupIH2I!VzC%Mp*IlN8Oc9P!vXNzn|;5s#yj6wR<4@whrk(G1HGkEfFq&9EHt_&Q0^ z49gKuppz8MupIG(I!VzC%MnkclN8Oc9Pz|DNzn|;5l^C%6wR<4@uWIQ(G1HGPo|R; z&9EHtw49ns0Z~xaRnqfKODRh#e8I~iSQYR^zVL9TdbdsVOmLr~8Cn=g?IpS$_ zlA;-wBc4_#DVkw9;^}mfq8XMWo?a&@nqfKO8FZ4O8I~iSQ70*yVL9TNbdsVOmLr~7 zCn=g?IpSG#lA;-wBc4?!DVkw9;@NbPq8XMWo?Ry?nqfKOIdqbu8I~iSQzt2!VL9Tt zbdsVOmLr~9Cn=g?IpTSAlA;-wBc4|$DVkw9;`wxvq8XMWo?j;^nqfKO1$2_48I~hn zP$wyxVL9T3bdsVOmLpzRCn=g?IpRfhlA;-wBVJS|DVkw9;>C25q8XOMi+?;oQZ&PI z#Ea`BMKdf%yo63tG{bVlOX?&=Gb~5ElulAK!*aw+>m)@pEJwVIPEs_(a>UE(BtMKdf%yn;?rG{bVlE9xXgGb~5El1@@I!*awc>m)@pEJwVGPEs_( za>T3ZBtm)@p zEJwVKPEs_(a>VQEBtm)@pEJwVFPEs_(a>SeJBt}7RYn`NMhUJL2(MgJCSdMsGoup`n<%qY_Ns4Azj(B^W zq-ciah}7RXPu;IhUJKN(MgJCSdMsCoup`n<%oCF zNs4Azj(B&Sq-ciai1*M*ie^}jcu$?AXols8_tHs}7RZ=IxQhUJL&(MgJCSdMsK zoup`n<%svwNs4Azj(C5aq-ciah!4<7ie^}j_&}YcXols857J4BW>}8+V4b9BhUJJ4 z(MgJCSPmEd@c>ED49gK8s*@DWupIGWI!VzC%Ml;0lN8Oc9Ptr4Nzn|;5g)0O6wR<4 z@liTS(G1HGAFY!V&9EHtF*-@n49gK8tCJMXupIGmI!VzC%Ml;1lN8Oc9PtS{Nzn|; z5ud1&6wR<4@ku&K(G1HGpRAJ<&9EHtDLP5f49gLps*@DWupIGeI!VzC%MqWhlN8Oc z9Pt@CNzn|;5ud4(6wR<4@mV@a(G1HGpRJP=&9EHtIXX$v49gLptCJMXupIGuI!VzC z%MqWilN8Oc9PtG@Nzn|;5nrg26wR<4@kKgG(G1HGU#yc9&9EHCzIcG7Xols8FVRVg zW>}8+Qk|q|hUJJa(@BbESdRE|oup`n<%qA)Ns4Azj`&KQq-ciah_BK~ie^}j_-dV` zXols8uhB`0W>}8+TAie5hUJK_(@BbESdRF5oup`n<%n<4Ns4Azj`&8Mq-ciah;PzK zie^}j_-37?Xols8Z_!DLW>}8+R-L41hUJKF(@BbESdRF1oup`n<%sXlNs4Azj`&WU zq-ciai0{%#ie^}j_->t~Xols8@6kz$W>}8+UY(?9hUJLw(@BbESdRF9oup`n<%l29 zNs4Azj`%^Hq-ciah==GTMKdgip+6oVDVkw9;z6CHXols8AJR#RW>}8+VV$IChUJJK z(MgJCSdREnoup`n<%l2CNs4Azj`(q%q-ciah@a3&ie^}j_(`3lXols8pVCQ+W>}8+ zX`Q5KhUJK#(MgJCSdREvoup`n<%pltNs4Azj`(?}8+Wu2sGhUJJ~(MgJCSdREroup`n<%nO?Ns4Azj`($*q-ciah~Lmjie^}j z_)VRpXols8-_l8nW>}8+ZJnfOhUJLg(MgJCSdREzoup`n<%r+YNs4Azj`)3@q-cia z@Q}v?BtLf)o zEJysAPEs_(a>SqOBtLf)oEJysEPEs_(a>U>3BtnG{bVlKkFn# zGb~5^i%wEB!*ayG>Lf)oEJysCPEs_(a>T#uBtLf)oEJysGPEs_(a`=Id2S|!$SdRFAI!VzC%MlNy zlN8Oc9P!XPNzn|;5f7u26wR<4@vu5c(G1HG52uq9&9EHt@H$D+49gLZ@Sy!)r)Y-d zh)2{(ie^}jcqE;qXols8N7hM-W>}7R6rH4KhUJJy)k%tGSdMr!oup`n<%mbuNs4Az zj(7~6q-ciah{x1Pie^}jcr2ZyXols8$JR-TW>}7R9G#?ShUJLI)k%tGSdMr+oup`n z<%q}ENs4Azj(7r{q-ciah$qxZie^}jcp{yoXols8C)P=dW>}7R5}l-IhUJJS)k%tG zSdMryoup`n<%lQONs4Az4u|`AfTU=K<%p-yNs4Azj(AF)q-ciah^Nv?ie^}jcxs)b zXols8r_o7@W>}7RTAie5hUJK-(@BbESdMu52krklMKdf%JcCYBG{bVlGwLKoGb~3u zlTK1J!*awk>m)@pEJr+xPEs_(a>TRhBtm)@pEJr+#PEs_(a>VoMBtm)@pEJwVEPEs_(a>R@3Bt}7RX`Q5KhUJKt(MgJC zSdMsEoup`n<%pMi(EhJeG{bVl%j+aXGb~5Ef=*I2!*awc>Lf)oEJwVOPEs_(a>Og^ zBtLf)oEJwVS zPEs_(a>Q%vBt+2*%Gb~5Eflg91!*awM z>Lf)oEJwVNPEs_(a>N_!Bt}7ROP!=>hUJL2(n*SDSdMsWoup`n<%qY@Ns4Azj(FP#?f*JO zGb~5Eola6T!*ayi>m)@pEJwV9PEs_(a>P68Btm)@pEJwVDPEs_(a>RS;Btm)@pEJu8RPEs_(a>NJfBt}8+aGj)RhUJKl z&`FABSdREeoup`n<%o~cNs4Azj`(Puq-ciah>v;D{;yLs!*ayO>Lf)oEJu8tPEs_( za>U2$BtLf)o zEJu8rPEs_(a>S?WBtLf)oEJu8vPEs_(a>VEBBt~iQupIHtI!VzC%MstAlN8Oc9PzC>Nzn|;5#Oeh6wR<4 z@$EWE(G1HG-=UKf&9EHtojOU;49gMUrIQrRupIH-I!VzC%MstBlN8Oc9Pzz6Nzn|; z5#Ohi6wR<4@%=hU(G1HGKcJHo&9EHtgE~pk49gJ@(MgJCSPnyeJU~)3!*axfI!VzC z%Mm}MlN8Oc9Pz_CNzn|;5kI1n6wR<4@uNCP(G1HGKc}8+8J(nPhUJK#)k%tGSdREPoup`n<%plx zNs4Azj`#(gq-ciah+ou6ie^}j_$8gBXols8U)D*AW>}8+6`iDLhUJJ~)k%tGSdREL zoup`n<%nO`Ns4Azj`$6oq-ciah~Lynie^}j_${5JXols8-_}WrW>}8+9i60ThUJLg z)k%tGSdREToup`n<%r+cNs4Az4i9lWKvFcra>O6#Bt}7RSe>M3hUJKd z(@BbESdMsjoup`n<%mbnNs4Azj(9|!q-ciah)2>%ie^}jcx0WVXols8N6|@&W>}7R zRGp+~hUJJy(@BbESdMsfoup`n<%q}7Ns4Azj(AL+q-ciah{w`Nie^}jcx;`dXols8 z$I(fOW>}7RT%Dw7hUJLI(@BbESdMsnoup`n<%lQHNs4Azj(9?yq-ciah$qrXie^}j zcw(KTXols8C(%iYW>}7RQk|q|hUJJS(@BbESdMsdoup`n<#2e92S|!$SdMrKoup`n z<%p-$Ns4Azj(94aq-ciah^N*`ie^}jcp9CgXols8r`1V{W>}7RI-R6whUJK-*GY}7RHl3ts zhUJK7*GY}7RKAog!hUJLo*GY}7RF`cAnhUM_$9uJTd&9EHt;yOvu49gKOp_3HNupIG{I!VzC%MmZ7 zlN8Oc9P!dRNzn|;5ig^Y6wR<4@v=He(G1HGFQ=0f&9EHt@;XV;49gL(ppz8MupIG< zI!VzC%Mq`nlN8Oc9P!FJNzn|;5wD_?6wR<4@v1sW(G1HGucng}&9EHt>N-i$49gL( zp_3HNupIH4I!VzC%Mq`olN8Oc9P!#ZNzn|;5wD|@6wR<4@wz%m(G1HGucwm~&9EHt z`Z`I`49gL3ppz8MupIG*I!VzC%Mov+lN8Oc9P!3FNzn|;5pSZC6wR<4@uoUS(G1Js z(k>n#DVkw9;>~oDq8XMW-drasnqfKOEp(Ei8I~j7QYR^zVL9ThbdsVOmLuL;Cn=g? zIpS?}lA;-wBi>dgDVkw9;_Y;jq8XMW-d-munqfKO9dweS8I~j7Q70*yVL9TRbdsVO zmLuL-Cn=g?IpSS(lA;-wBi>afDVkw9;@xzTq8XMW-d!gtnqfKOJ#>ghDVkw9;{9}zq8XMW-d`svnqfKO19Xz2 z8I~hHP$wyxVL9T1bdsVOmLon`Cn=g?IpRZflA;-w!-ai3KvFcra>R$~Btm)@pEJu8dPEs_(a>U2# zBtm)@pEJu8b zPEs_(a>S?VBtm)@pEJu8fPEs_(a>VEABtm)@pEQhf!9v~^2VL9SUbdsVOmLtAYCn=g?IpWK7lA;-wBfeZGDVkw9 z;wyBLq8XMWzEUSCnqfKOt8|j08I~iyS|=%*VL9S!bdsVOmLtAaCn=g?IpXVdlA;-w zBfefIDVkw9;v005q8XMWzELMBnqfKOn{<+*8I~iyStlu)VL9SkbdsVOmLtAZCn=g? zIpW)NlA;-wBfecHDVkw9;yZMbq8XMWzEdYDnqfKOyL6JG8I~iyTPG=+VL9S^bdsVO zmLtAbCn=g?IpX_tlA;-wBfeiJDVkw9;s}7RP$wyxVL9T5bdsVOmLq;xCn=g?IpRljlA;-wBYspTDVkw9;>UE7q8XMWeq1Lh znqfKOCv=jc8I~h{QYR^zVL9TbbdsVOmLq;zCn=g?IpSw@lA;-wBYsvVDVkw9;^%ad zq8XMWeqJXjnqfKO7j%-M8I~h{Q70*yVL9TLbdsVOmLq;yCn=g?IpSAzlA;-wBYssU zDVkw9;@5PNq8XMWeqARinqfKOH*}Js8I~h{Qzt2!VL9TrbdsVOmLq;!Cn=g?IpTM8 zlA;-wBYsyWDVkw9;`eltq8XMWeqSdknqfISr11br(G1HGf1r~T&9EHthdN2o49gLJ zq>~iQupIHnI!VzC%MpK~lN8Oc9Py_*Nzn|;5r3wW6wR<4@#i{8(G1HGf1#5U&9EHt zmpVz&49gLJrIQrRupIH%I!VzC%MpL0lN8Oc9Pzh0Nzn|;5r3zX6wR<4@%K7O(G1HG z|Dcl;&9EHtk2*=w49gM!q>~iQupIHvI!VzC%klp)WKUrLMY$D5Q``2`ww>CxQ`>fG z+fHrUX$Q6K)OM%VdRR~Y^ZD*QXU9WzlA;-wBmPwDVkw9;{SA#q8XOM z2ipGsz(|T_SdMrYoup`n<%oyXNs4Azj(9koq-ciah=}7RB%P#ahUJJy)=7$HSdMrUoup`n<%mbsNs4Azj(9Ykq-ciah)35+ie^}jcnqDS zXols8$J9xRW>}7RES;oihUJLI)=7$HSdMrcoup`n<%q}CNs4Azj(9wsq-ciah{xAS zie^}jcmkcIXols8C)7!bW>}7RBAujYhUJJS)=7$HSdMrSoup`n<%lQMNs4Azj(9Si zq-ciah$q)cie^}jcnY1QXols8r_@P`W>}7RDxIWghUM^cZvWRQnqfKOsdbW~8I~iS zMkgtnVL9Syb&{ePmLr}{Cn=g?IpXPclA;-wBc4GgDVkw9;u&?4q8XMWo=GPunqfKO znRSw)8I~iSMJFkmVL9Sib&{ePmLr}`Cn=g?IpW!MlA;-wBc4MiDVkw9;yHDaq8XMW zo=YbwnqfKOxpk7F8I~iSM<*$oVL9S?b&{ePmLr}|Cn=g?IpX{mm8I~hnL?Og>BtQ%sBt*yp!Gb~5Eu1-=k!*ayy=_ExnEJwV)PEs_(a>N_xBtQHcBtlN8Oc9Pw5y6O&9EHtb~;JX49gL3 zuagwbupIFYI!VzC%MtIWlN8Oc9Pv&%Nzn|;5$~*%6wR<4@h&<^(G1HG@2Zm&&9EHt zZaPWP49gMku9FnaupIFoI!VzC%MtIXlN8Oc9PwT{Nzn|;5$~;&6wR<4@jg09(G1HG z@2is(&9EHtemY6f49gMkuagwbupIFLI!VzC%Ml-_lN8Oc9PvRqNzn|;5g)9R6wR<4 z@gX`%(G1HGAF7iS&9EHtVLD0C49gK8u9FnaupA!b?f*JOGb~4Zgica4!*aw&>Lf)o zEJu8lPEs_(a>PgLBtLf)oEJu8jPEs_(a>OU=BtcMKdf%e40*DG{bVlr|Tp| zGb~4ZhE7s6!*axD>Lf)oEJu8nPEs_(a>QrrBtQZ&PI#OLZHMKdf%e4b8H zG{bVl=j$XzGb~4Zflg91!*awI>Lf)oEJu8iPEs_(a>N(wBtUo@BtTdjBtV!OBtS45BtP&QBtOs_BtQ@wBt&MKdf%{I*U~G{bVl@8~2&Gb~5^u1-=k z!*ay$=_ExnEJyslPEs_(a>O6#BtlA;-wBmPJyDVkw9;*WKb zq8XMW{zNA!nqfKOPj!-_8I~jdOeZOtVL9T@b&{ePmLvW`Cn=g?IpQyMlA;-wBmPP! zDVkw9;;(g*q8XMW{zfM$nqfKOZ*`KQ8I~jdPA4gvVL9UOb&{ePmLvW_Cn=g?IpQC6 zlA;-wBmPMzDVkw9;-7Vrq8XMW{zWG#nqfKOp*l&?49gM!s*@DWupIGkI!VzC%Mt&s zlN8Oc9PuAINzn|;5&x-^6wR<4@n1Sg(G1HG|E-f0&9EHtKRQX#49gM!tCJMXupIG! zI!VzC%i#lT|9_DE|3OhS!*ayK=p;omEJr-7PEs_(a>T>wBtS$QBtV25 zBtSGABtq8XMWUPmV>nqfKOb#;=W8I~hnPbVpwVL9UUb&{ePmLuLkCn=g?IpPg< zlA;-wBi=|SDVkw9;*E8Zq8XMW-b5!UnqfKOO?8r@8I~j7OeZOtVL9T>b&{ePmLuLm zCn=g?IXt?>14xQySdMs0oup`n<%qY^Ns4Azj(BUGq-ciah_}&6ie^}jcw3#MXols8 zx6?_AW>}7Rd!3|chUJKN&`FABSdMr{oup`n<%oCENs4Azj(BICq-ciah}7Rcb%kYhUJL&&`FABSdMs4oup`n<%svvNs4Azj(BgKq-cia zi1*P+ie^}jcwe2QXols8_tQy=W>}7Rf1RXghUJJ4&`FABSdREWoup`n<%kc`Ns4Az zj`(1mq-ciah!4?8ie^}j_)wjsXols857SACW>}8+aGj)RhUM_!9uFWXnqfKOBXp9Y z8I~hHQYR^zVL9TXbdsVOmLon|Cn=g?IpSk&cBq8XOM*k=FNDVkw9;>&fCq8XMWzCtG{nqfKOD|M2h8I~iy zN+&6rVL9Tfb&{ePmLtAKCn=g?IpS+|lA;-wBfd^2DVkw9;_G#iq8XMWzCkA`nqfKO z8+DSR8I~iyNhc|qVL9TPb&{ePmLtAJCn=g?IpSM&lA;-wBfd>1DVkw9;@fqSq8XMW zzC$M|nqfKOJ9Uzx8I~iyOD8FsVL9Tvb&{ePmLtALCn=g?IpTYDlA;-wBfd{3DVkw9 z;`?=yq8XMWen2NFnqfKO2X&I78I~h{NGBbDVkw9;(}7Ruuf7m!*aw!bdsVO zmLq;bCn=g?IpQaElA;-wBYsLJDVkw9;-__zq8XMWenuxLnqfKOXLXXI8I~h{PA4gv zVL9UGb&{ePmLq;aCn=g?IpP;}lA;-wBYsIIDVkw9;+J)jq8XMWenlrKnqfKOS9Ox2 z8I~h{O(!XuVL9U0b&{ePmLq;cCn=g?IpQ~UlA;-wBYsOKDVkw9;__(G1HG57kMEW>}8+SDmD2hUJKV z(@BbESdRF2oup`n<%s{#Ns4Azj`&ZVq-ciai2u?_ie^}j_-~!0Xols8|ItZ`W>}8+ zU!A0AhUJL=(@BbESPmap`~QRO{|~nRKRB9UIpSe-lA;-wBOX>KDVkw9;^B0Xq8XMW z9$qIYnqfKO5pmQ9q8XMWo?Is>nqfKODRh#e8I~iSQYR^zVL9TdbdsVO zmc!4r{a>eOhUJK-)=7$HSdMraoup`n<%p-%Ns4Azj(9qqq-ciah^N;{ie^}jcm|!M zXols8XVgiGW>}7RCY_{chUJK7)=7$HSdMrWoup`n<%nn1Ns4Azj(9emq-ciah-cSH zie^}jcn+PUXols8=hR7xW>}7RE}f)khUJLo)=7$HSdMreoup`n<%s9iNs4Azj(9$u zq-ciai09Wyie^}jcmbWHXols87t~3LW>}7RA)TaXhUJJC)=7$HSdMrRoup`n<%k#6 zNs4Azj(9Phq-ciah!@vMie^}jcnO`PXols8m()p$W>^jvYx}=W(G1HGFQt6wR<4 z@tQhG(G1HGucea|&9EHt+B!+m49gL(qmvZPupIHaI!VzC%Mq`qlN8Oc9P#=(Nzn|; z5pSTA6wR<4@rF7{(G1HGZ={nH&9EHt#yUyS49gL3qLUQOupIHGI!VzC%Mov;lN8Oc z9P#ElNzn|;5pSWB6wR<49@XssIz=-qN4%v@QZ&PI#9QekMKdf%ytPhJG{bVl+vp@k zGb~5Etxi%j!*ayi=_ExnEJwV(PEs_(a>P66BtQZ&PI#5?IEMKdf%yt7VH zG{bVlyXYiEGb~5Et4>lh!*ayC=_ExnEJwV%PEs_(a>RS+BtNJdBt)Nzn|;5g)CS6wR<4@i96{(G1HGAFGoT&9EHt zaXLxS49gK8uagwbupIFTI!VzC%MqWblN8Oc9PvpyNzn|;5udD+6wR<4@hLh<(G1HG zpQ@7-&9EHtX*x;K49gLpu9FnaupIFjI!VzC%MqWclN8Oc9PwE?Nzn|;5udG-6wR<4 z@i{t4(G1HGpR1D;&9EHtc{)ka49gLpuagwbupIFPI!VzC%Mo9wlN8Oc9PvduNzn|; z5nrs66wR<4@g+J*(G1HGU#gQ7&9EHtWjaaG49j6miwBSt&9EHt z49gMUppz8MupIG?I!VzC%MstClN8Oc9P!OMNzn|;5#OSd6wR<4@vS;Z(G1HG-=>ok z&9EHt?K(-(49gMUp_3HNupIH7I!VzC%MstDlN8Oc9P!;cNzn|;5#OVe6wR<4@x3}p z(G1HG-=~ul&9EHt{W?j}49gKeppz8MupIG&I!VzC%Mm}MlN8Oc9Pz_CNzn|;5kI1n z6wR<4@uNCP(G1IBNVos%6wR<4@nbqk(G1HGKdzG$&9EHtK%Jy$hUJI{=_ExnEJr+8 zCn=g?IpQHYNzn|;5kH}m6wR<4@sm19(G1HGKc$lt&9EHt(>h7f49gKeqmvZPupIHT zI!VzC%Mm}PlN8Oc9P#ryNzn|;5x=056wR<4@ryc1(G1HGzoe5C&9EHt%Q{KX49gL} zqLUQOupIHLI!VzC%Mrh(lN8Oc9P#TqNzn|;5x=366wR<4@tZnH(G1HGzonBD&9EHt z+d4_n49gL}qmvZPupIHbI!VzC%Mrh)lN8Oc9P#@)Nzn|;5r3eQ6wR<44w3y|r)Y-d zh(FXxie^}j_#>U9Xols8Kh{Z#W>}8+6P=`JhUJJq)k%tGSdREJoup`n<%mDmNs4Az zj`$0mq-ciah`-cHie^}j_$!^HXols8zt%~LW>}8+8=a(RhUJLA)k%tGSdRERoup`n z<%qx6Ns4Azj`#}8+7oDVNhUJKd>Lf)o zEJysSPEs_(a>T#sBtW1XBtO&}Btlh z!*ay4=_ExnEJr-MPEs_(a>R4!BtNVhBtPsMBt}7RIh~|vhUJKt*GY}7RHJzkrhUJJ? z*GY}7R zJ)NXzhUJLY*GY}7RGo7SphUJJi*GY}8+NS&l;hUJKl(n*SDSdRE;oup`n<%o~b zNs4Azj`&!eq-ciah>z1rie^}j_;{V9Xols8PtZw}8+M4hB)hUJJ)(n*SDSdRE) zoup`n<%mzwNs4Azj`&oaq-ciah)>f=ie^}j_;j75Xols8&(KMVW>}8+Or4}?hUJLQ z(n*SDSdRE?oup`n<%rMGNs4Azj`&=iq-ciah|kkWie^}j_}8+ zLY<^&hUJJa(n*SDSdRE&oup`n<%loQNs4Azj`&iYq-ciah%eJgie^|2V_7_aq-cia zh%eVkie^}j_zIn*Xols8uhdD3W>}8+DxIWghUJK_)=7$HSdRD_oup`n<%qA}8+CY_{chUJKF)=7$HSdRD>oup`n z<%n<9Ns4Azj`%j6q-ciah;P?Pie^}j_zs<}8+E}f)khUJLw)=7$H zSdRD}oup`n<%sXqNs4Azj`%*Eq-ciai0{`)ie^}j_yL`yXols8AJj>TW>}8+A)TaX zhUJJK)=7$HSdRD+oup`n<%l2ENs4Az4nui7fTU=K<%l2CNs4Azj`(q%q-ciahzIH< zMKdf%JV+-gnqfKO!8%FN49gJ@(MgJCSdRD!oup`n<%pluNs4Azj`%5^q-ciah@aL; zie^}j_!*s~Xols8pVdi}8+Ih~|vhUJK#*GY}8+HJzkrhUJJ~*GY}8+J)NXzhUJLg*GYO6$BtQThBtG{bVl-{~YpGb~5^y-rdz!*aww=p;omEJysKPEs_(a>PIBBt99;0ghX6u|fLuflE_mQW03k#`E+GdO zJn$ia5F#L#k%J2!_z*w{5s)j$!37U|2q1(A$W`Rvf(JeX5JCjx8gg*K10MniAp&w8 zIk@0~4*`S_0UnST|KEY}{~Z|r-+}S}9T@-LK|+XtFv!6L4}1t9ga`D9FJD4}1t9gb0X=99;0ghX6u|fN03U1rK}(AcP2rjvQR@z=r@r zh=3T#!37U|2q1(Ah>09r@W6)vLWqD^$iW27!37U| z2q1(A$nD6%1rK}(AcP1=N#x*y2R;N4LImUvaKQr~0tg`jQW`n9;DHYTgb)Eb z#~A-d4j%XrKnM|#WaQw22R;N4LIflQIk@0~4*`S_0l61BxZr^g0fZ0%DT5qb@W6)v zLWqErMGh`_;6nf*L_qFC4la1$LjWN}K*}Kp7d-GGfDj@e<&lF69{3PI2oaD9$iW2< zd)I|<1c;G_-Aw)nPMh-4`;6nf*L_q2x2Nyi> zA%GAfAoY=h3m*6oKnM|#2FSq$4}1t9ga}AOA%GAfAdevj7d-GGfDj@eZIFWt9{3PI2oaFB$iW2< zd8PE_mQW03k#`dLjoGJn$ia5F#MGkb?^z_z*w{ z5s==A_o^d z@F9Q@A|UC=!37U|2q1(ANCt9n!2=%x2q6NJi5y(;z=r@rh=BA%4la1$LjWN}K>8yG z7d-GGfDj@e1CWCY9{3PI2oaDhz=r@rh=2@14la1$LjWN}K(dj83m*6oKnM|#9OU4F2R;N4LIfliIk@0~4*`S_ z0U3%MT=2k$078g>A%GAfAR~~23m*6oKnM|#k;uUX4}1t9gb2teJcS%w@W6)vLWqD&M-DD{ z;6nf*L_lUB2Nyi>A%GAfATyDJ3m*6oKnM|#S;)Z!4}1t9gb2uN z%tsC`c;G_-Aw)nHAO{yb@F9Q@A|MNqg9{$`5I_hKkVVMB1rK}(AcP3WV&ve02R;N4 zLImVlyo?-N@W6)vLWqF8 zf*f4%z=r@rh=43b4la1$LjWN}K$al~7d-GGfDj@e%aMZ%9{3PI2oaDK$iW2@OF10MniAp)`*Ik@0~4*`S_0a=3_T=2k$ z078g>yoMZH@W6)vLWqF8jvQR@z=r@rh=8m`4la1$LjWN}K-M7#7d-GGfDj@e>yd*C z9{3PI2oaDC$iW2A%GAfz(4>=0v9~+ zA%GAfAnzdu7d-GGfDj@e?;{5nJn$ia5F#KSAO{yb@F9Q@A|Tt5g9{$`5I_hKkPnfA z3m*6oKnM|#kC1~49{3PI2oaDS$iW2{EQr2@W6)vLWqF;f*f4% zz=r@rh=BZx99;0ghX6u|fE+~*E_mQW03k#`jv)sZJn$ia5F#MIAqN*c@F9Q@A|S_+ zg9{$`5I_hKkQ2zk1rK}(AcP3WN#x*y2R;N4LImU#a&W-|9|8y=0&*HTxZr^g0fZ0% zIfEQr@W6)vLWqF;jvQR@z=r@rh=BZo99;0ghX6u|fc%LZT=2k$078g>oJ9^Uc;G_- zAw)p_LJlr?;6nf*L_p3V2Nyi>A%GAfAm@>T3m*6oKnM|#3&_C*4}1t9gb2t*J^a21gTke{BGJvb{nGiyj%|4cMcLDt~RjKm)qnVGpa@>tu&{*L9bayZqcNwpd3 z^-ZBCrn&U;1cpwW>C$2o89HLJOH&6iG<^`!ck8>~H*@$ztg20VwxpsP8c} zwGXECV`v0>VF{M!u%3;rT}rPd#ka9{mP@0=_VmYG>L;cjK{@wo63xJ`i)k0|>*2Ra zT6T6$K~hF$L1x|%>|auPVP0Nlc0p1<>_Ad(PJUKFR!(+O`LZ1=RE_P=h&C<_upW9k zi56z(Wv1u!&(0c^nURz^B0aX(IobG^5ml2&V!b)Jnb}G4W-3}?N^Bj-$`vH_EzBC6 zk(8Fywy+?#u%LNtbN%vihG0s;$lS~-L$dORq!pwOz^Zf8@(N-bPpmU58+A$>jIAc+ z#FvfFkd#7FlCtuXVtbRGGbA^yAgeD{IXtUiKvKbg*t*k(WMZTJ`eo*o%TLP98j(3T zzNM;IE`0!+0e|Q8yRpjn?xVJ;f6o^SW7|l}%lw~iB)_n4e%g>+oHzZG`lY28Z3T6RXYoV=uwN&hlO(RSM8{G-N6`MH_tS^cum8fiBwpOIFOmXx1Un3tYem2}LD zWd%7&!}GEVGLwenpq8<7GAVY_=A#8ryt$6PBjarnU&HXM?2Me@v3fO6i=EUrS5nkQ z@tLsVe;!2~+qC<L~8nN*k`Ymknyjom!> zb?c_*(ez+kSr1fV5$m zNf}wO!yh}nZ`t+uF-gGzidE?UWsz7*CgtR1WX6tSyTYvWL5Z^{UXl2@`_CHu+d2#L zZ>>e_M9s_0&yQVVLoy2ny8buL*uh!(1x3rG4bDT8jl{{HU66(bOjItm zqyJcE>>SR>L5mb!De;+c(V-s0vNDGkwRP1SZCsd(<#8XlHB7X5)ui|}i)$p2{tuQ( z>W8!b#-)YhgMY;n-^IVrR2-(FijB;~9U>Dqk9=G;I4QHTZ!UM^-ZCsRujp*Qxj5;R zojC%RNNa7T{(dzNr80m@oxSzP!ZlB}QlBGp@0ry9Dcrpz)B~v;fneIK9LWA#9=-#=> zbVOU+gOTk;79gAbLkgXJD21jzolLhQOC6O=*KSUx{!{pkQfThs6q@ub){~0+JC<7; zTW&o5K9@qzoKKjwDTaGD1eMovCnNCNx7R$|!)ny!hW9!CpsaWm+ zvS1{pVIRC{SQnP5&SJU6$+S#+v=x@~W81@WsaP%v%SE%3X)dw=`yOJsr0MvTv7B0l z(k01s8?vM^s8eh^nD>l^>3SJD8+DO8V7cK~2i94ABIdz#&n!dtqCGnz+l%ZBvc1Sc zis{A6(A0UTH!?CJnG$R-cM|GSq6{T>l%Wx_6UeF~qp`X?33sC|Wy;XC&m_}29kEW- zb1$;BsOOmqSf(P{2KAhXjG)aTWbOLcbIEigG7lMvwF{1W^@owcUSy;*GVDWA zY&q;hYP~WvjG3QITO*r|tU9vP$xt8r0M!>H(}l=FWNvIZWPSs*b3@bx*%4%Ckfp|! zn}QtEb6p(Ug;-Y?>;v}Ci!Fz&dL!&N1jxo9OGTC&TMqlaw=wpwDVD>&XJqB)4o(}{ zCH?@y^%lET-S{K^>}eExVimNpGh}YfLlW1zLbXhdH-zOQir7t zF2ob#@8uHtE%%duEKXu|h}8`bnWWfnW&Gdx11x9o;2b=r`^Wnp`GvW;IeECj)s4-R z=<%Q$mdpCL9h3iRCTt^qZ1K>F z?c4C!F^jhm{$TvZ4=Eg6kQM8(7Co=>2jmo@ zn;Y+a#Luz64|&!9@pAFg?v~}^J*OLOAAerPdtT_oqsCeBPWa7-AI^ar$1m1BOUjS+ zoBwk!{^MB0X3qb+J^zcNaC6;*Gl!x7JR~RMUsir&`$hBQ;iSrloy`9}Gurd-`Ty>4 z{bz+cWe>{E8J->Q>fh)=#oOsWca1c;rI&SMo}zO$-Uli=xnn((*o#~IB#iaJiq7pD zPkdZwSw)w@t?vtotFK1Uxjf=uy7TcKPptKDe~7j5zjgUV<#Qh(noiq27-42hZlwc?4asH^jj?Zx_- z|DU$^uZ{4}?X@W!(l;|NR>7hRJt-G|Fgxw~K#Y z&Phdg{hNQs&(Qe9Tl%u`iLq0(=&ZasckJ-QPK`XgUgFlBG&rZI?^-u0t049|9Dfmv zzy003u43m;^IKkrlkx{=rQ@aczv~d+`uw`}bvm(p{7l)2=l$%x=!5J@rpJbtqcrgw zE4wHkL{2_0%3{-EV)bcMP!Q{W$KLjEq_L;54*^3mQT>rshNR`@qCX#dy}^SE)8lUt z*s1s)#`^C?GvYZBn=yWcULMY}*aERz^ewgcm-pL$t55tHlc-Cq1!Hxq(l;&t){Xpg8}TLLJNhr1 zxY4Hl@j94R^vU36OXlWe#X5nB&qmovHjrbnM_szgDD%B0|Qb~9R!mnRCg=XM4 z6@UM)-&=;`xq9<^3I2#3{9Br%=(|h&&i#)=eF5vMj`jZUt`E=dg4hi__9fuvb$;{w zY1$p*RH6%FE%}~p6b1^p7ur4r=y(P zp{RTm<8D^Q-D zs5765^(5NLLpdo?-iET5SZB$8Sbw6O3s9b&sQ+G+&m^W-?vHsA>zsnJpV-!s*!0Bw z?f|^wCiZa&%4ZVuUqCrZ>`TWiloNGWi*lHlM<0lGNGv-5WiPSa?I=fyW05on^C#*& z2Iakpb~u3Y+C+V74aPnu+IBX|Br*R9l-DMvw;Y0XCd#j%>?P_?va#=p`Fo-qChD*i zWiL_B;yIWnF+CUMAW?_iC?_TASw0ubCeD+ID4$7`qgXky{(3`kjwRY;A<9XK@>!IF z#JQB3hx#Y#wi@NNiFxFF%#%1zGEh!U>`RC;O`H#<3eY}@^^8C{HPJr%Q1%n`tX_zA zNKBuOvU}tFN0}z}t5vhEO`A3D)S_d{_HDc1o>aDDRnl}A&g=A|bFC}NWKc@{*;u__ z(XX5M_3-=8XGGECp)mXA3t*ye8}BpVc^bQS#$S=}nCX{~KMK-fU&doE0{Ff?9NS%= z5`SJtOH<;{>)d7dezY9lidLl1CCEeMdspH+)hbMbqnJiFV3{@e8v?*1V`w4nVYtut z9a)eW`y`3?SbPXZ4-Q4rEG-XjoSFENh6%CTTHT`Oc`R!ldoQ{1vAF0fEdD9GORufP zHt=6A+|n1iWhGU~1^Ie75axF*T80|`-weXvS-&kK`Hp;mu)9ppe z+|uueHx2Ic*?)IE3kJj05%DLF{{&VQ|L^+s>tk<~J^*7q zXufoexH9ebRt5Bra)08j~g%EN@1dlNJ~zSk<>5n1yEHaP` z!a(~Fl1*}OZVx4SBp-wBg=82RPDYTCWE2@q#*oL!6J#v@-x7=?<$-J|lZDeEd22f_#ZVE%zaig}?=YbJJ^6tg z!m#p>&Yf`6vLFbvCZ49^IR$ViOLD2&QzjLsO0$yf|!Y{p@VF~yk@%x%o=OiAVr=1%4= zrWA8Ga}QIRNn(}!aT~fW*%eOFm0JsrXACs z>A-YkIx(G@E=*UZ8`GWX!SrN$F};~SjK`!geVKG7gUMw2G5whVOcpbc8N>``hA`Po z4wK6aW%8JOrhqAAhB3pL5zI(t6f>F`!#vJB!Hi{mW*jq~nZQhBCNWPklbI>ZRAw6U z6f>Qf!OUc4F|(OD%v|PaW*+klGoM+&EMyijiyw0p;)-mgu4a`Pn6SJAw!fa*UVBTcjVzx1FGw(3(G9mLG z^FH$dvz_^n`H0!U>|{P>K4Eq-yO~d!&zL>TUgmS=3+78^AG4qNiusy3zH`Wwr`im955BXKS!E z+56dA>;r6V_CdA|`w&}~eVDDs)@K{A4Oy3M#5QJ|uua)!Y;(2++mda?KEgiAwq_q= z+pulfRJI-4p6$SPWIM5)*)D8Xwj0}>?ZNhBd$GOQKCH*4v3=QeHiOM%`?3Am0c;jK zkR8MhW{0rZYz~{t4rTM$e71lsWQVcC*%9nWb`(3B9m77(KEaMo}Iu>WGAst zvXj{<>{NCd`xHB!ox#pzXR)){IqY2aX?7m_3_G7)z%FDLv5VPf*(L0A?DOmkY{0(A zzQn%FzQQhLm$A#)73{0*N_G{ynq9-b#=g$3W!JIm*$wPQb`!gq-NJ5V-(cTl-(t71 zZ?o^P@3JBL9{WD~0lS_3ko}0=!R}-~W|XYB_6zn)b|1T+{fhmX zJ-~j$e#?Hx9%R2~e_#)>5&I*1nEi=8!v4(u!v4x0WskAHvB%jH>`C?%dzwAN{?7iv z{>h$Y|6&SKDI&)pPu3R^+JJ*Bj$@SuTbA33EOXK=->0Abv z$@Sy^8_W&ivbh{CmmA9Ears;USI7$}QuTb1S%4xs}{1ZZ)@tdyRXYTg$EE)^i)Ujoc<~Gq;7? z%Dut8$-TvGd|CcJz8qhk zufSL2EAf^2DtuMG8eg5S!Pn&P=WFo~@U{5|`8xbVd|m!wz8+tnZ@@R?UA__Dm~X;2 z<(u)%`4)Ujz7_un|0v&@e~fR#x8+m$c6@uj1K*MF#CPVq@Llk7!e{e2d@etf&*Ss?0=|$R#t-L5@FV$A{Ahj* z|2Y2yKbH6Tar}6G0zZ+T#6QVT=BMye`Dy%9{B(W>Ka-!u&*tawbNQ$FdHgf{e0~AH zkYB_v=AY%4@Xztj^DpoL|04eq|1$pyzm#9bFXvbAuktJTRs3px4gVVdI=_}*$FJu% z@EiF}{APX&zmDBYp?JlmD3igx|&Q=0D{> zc&&4m_1OQDtUi14V;T6j!oBeWG#g?2)Fp@Yy-=p=L&x(Ho`ZbEmV zhtN~#CG-~h2%eB8^cB*D3?WnKC-fHv2wB2FVURFb7$Rf~IYO>5RLB$Zg#w{a7$yuC zMhGK?QNn0pjPSVdgfLd{g>k}oVS+GGm?S(YOctgHQ-x{5Q^Is%hA>l@CCnD)2y=y} zg?Yj=!hB(YuuxbeEEb*>mI%)Y&kHXIf$*a6lJK(dim+5zCM*|L2(Jn&g;m08VU6&b z@Vc;8SSPF(HV7MqO~Phji?CIALwHkoOV}p7ExaSVD}=&(!u!Gp!gk?9;Ui&(uv7S0 z_(a$x>=r&1J`?r`dxg)1FN80JeZqd>E8%P5fbfm*t?-?2Q21W>K{zBt!jHmX;V0pU z@U!rX@T+iCI41li92ZUqCxuhOY2l3UyYPqbr*KyIOE@Q-7cK}Fg-gO^;fiooxF%c| zh{%Yn$celth@vQovZ#ovsEN90h^A;ni4Tai#RtVY;zMFx z@nNx^SYK=)HWXd4k=R&lA~qG9iOt0pVoR}=_=xzZ*jju{Y$LW6Q^j^-d$EJqQS2mk z7Q2XD#cpDEv4_}G>?QUV`-q;HCiWH6#SAf1>?igY2Z&kXKyi>bSR5i|i#cMhI8@9N z^Th(OP#h)>7e|OA#ZlsDag6x5_=GrC^u=-FcyWR_QJf?`DNYurh*QOB;#1;uafUck zoF&c{=ZJH~r^R{VGva)4fw)jyBrX=86_<$5iO-8Kh=KT`_>%at_=>nxTqZ6TSBS5Q zE5%jfYH^MDn)tf7R$M2p7dMC-#ZBU7af`TBd_#Owd`sLWzAe5ZzAJ{}d*b`z2jX_| zL-8YVhqzPxSo}oXCGHkK6+aXAhX6IAT^X+sgcxJY9ck2nn}&27E(*8mGp@8sMK0|Oll*wl~Sd4 zQhTX`)KTgrb(XqFU8QbPcd3WeQ|cx4mikDZlqU6+(xnV3Q|c%6mj*~#(m-jDG*}uU zWlK3yt~6B2lk%kksZbgw4VOkpBc)N&Xlab}xb%cHR`R8B(s*ftG*Ox)Jt<9=rbttz zY0^{DbZLe(Q<^2smgY!vrKhEN(lgS0X@Rs*S|lx&o|TqJ&q>cqFGzv(qV$sVvh<3y zR9Yr2msUuxN-L#R(rRgq^qTa#v{qUtt(P`P8>LOsW@(GGReD2uQ+i94@~R^o#VXbW}Pf{U#lkPDm%EQ_^YajP$$ohxDg(R{Bdi zC!LorNEf9`(q-w2bXB@0U6+W=$gIrCye!C~EXlI0$f~T#x@^d%Y{^u%Wk)V17ne)O zx5>B5CFMKhJLS9NQu5vMJ#uL|NluniFxt08g{HWYo zeoSs7x0O@nc5-{UgWOT>BzKm($X(@ba(B6h+*9r)_m=y}o}4E4mDA-6IaBT@_m>CA zS@J-6kUUr(B4^7va;`j7&Xe=y0=ZBgCJ&cK$Rp)Z@@RRC{J8vtJXZGQaq@V1f;>^4 zBtI!nmZ!*5GCjTZMmruwiqA04ODY{}PreY~n zu@y%trW997D7PuMD7;a4x+qIZCcFRLN8Fl>((u8Kw+ZMkphdQOam#jPkhhgfdp~ zm2t{=Wr8wMnWQ|aOjf2SQLvQzn3`9#^J>{dQiK2!E6dzH_X zFO)Bpeae32E9GnDfbxy# zCzVsmY2}RayYh$fr*c;LOF5^US1u?Ql}pNH<%)7uxu#rKh{~v}%Bj36sG=&VvZ|=6 zs;RnasHSSERJBz{Ev6P%OQ^T0x2q-9JJdVXyVO$Z-ReDRX*EerR#Vh_)iP>X^**(n zT3)T7R#YpgmDMV0RkfO0U9F+kRPR@7sSl{N)d$r&>O*Q>^CTHdI};k=j^o zqBd2Vsm;|EYD=}1`iT0d+FE@~ZKJkTQ`L5Ad$ohwQSGF5R=cQO)oyBcwTIeM?WOis z`>39pruJ3S)eJRL?Wguv2dG)s8iKx>Qm};b%r`qou$rJ=cselr`37tGwOVG zfx1v#q%KyURhOvGsn4q~sDb*T`jYyx`ii<#U8XKqSE#S5E7eu%YITkJn)?~`mOq%dQkmd{XspXM(U61Vf82Vi2Aeoi~6g2 zR6VBtrXE*Ms3+A^>S^_i`n&pv`lotU{YyQko>woZ7u8GZW%Y`BRlTNOSBb`Gtj1}) zCTOB2X|kqhs-|hWW@x5nX;iZ{M=Pck*Gg!&X}4=7wL7#swY#)Z+TGecT4^mwOV(1f zd$lrJS?xZpoK{||pjFf=X_d7qT2-x@R$Z&1)zt3SYH1H>wY3MeI@&{8UF~75o>pIL zpf%K7t&!GPYoayPnrY3o7FtWKmG+4CsMcD0OlzaH)l#)~T6?X7)=}%Eb=JCQUA1mn zcddukQ|qPm*7|6kmZtU9(zOgNQ|qVo*9K@=+CXiPHdq^?WotQFt~ON5)AF?ftxy}L z4cA6!BehZ5Xl;!4xb}oLR`a!S+IVe(Hc^|TJ*iFBrf5^OY1&iTbZv$Tcj=4p4FCU&uPzVFKB`GqV|&Zvi6F$R9mJk*H&n+YAdx>+G=f$ z_L}y(wpLrGt=Bea8?{Z^W^IeMReM8wQ+rF>roFAbqrIzz+I!mj+6UTp?L+M&ZHKl~ z`&j!#+okQ+KGiXcx6h+GXvEc2&Ek zUDt@t=&a7^ye{aXF6pwa=&G*ix^C#EZs}CFbw@9z7uQSZx9PX*CG|V>JN3KtQu^Kc zJ$h+9Nl(^O^n3L(dRhHGy_{ZNub@}dE9sT>DtcADnqFP6q1V*!*K6qy=(Y6+^*Z`P zdR_fty`ElQZ=g5SUA>XsSZ|^?)tl+f^%ie7dHOT@e0_nwP+z1k)}Pgv=+EiT>o4em{-XYp{<8jxzEoePFV|P- zuj(uHRr+dujsBYcy1rIlr?1yH=o|G-`euELzEyuie^Y-;-=@E&`hNW@{cHVz{*C^v{+)hM|6cz= zKcq+ckNRQ#C;f>2v;K?ztA12JrvIiN*H7pt^;7z3{fz#*{)hgjepdfWKc}D9FX$Kb zOZsK~ihfnUreD{I!5FN;8N4AFq9GZwp%|*68Munos3W)wF{7`GX>8zqf9 zj603Hj8ewk#yv)9BgsfMQjB|zGDcbBKBJsb-l$+yG%6XDjVeY}qnc6OsA1GJ?l)=~ z4;ZzL2aP($Lq=WWVWXZ=-)LYoG+d*R(b#BWG&PzT&5agDOQV(Xi1Db=+IY-pW3)9= zjdn(Rql3}W=wx&@x)@!JZbo;bhtbpMW%M@s7@m=4^fl6r3?tL%XY@A)7+JW7_S;Dja9~KV~z2e@w&0rSZAy^HW(X?O~z(pi?P*s!+6tp%h+bTZM^43%J~Q?hdyUVHFN`mZea3#{E8}b9fbos- zt?`|4(D>f?!8l|@#*fBf<0s>Y@w4%Z@vCvvIA;8295+rFCyi6aY2%FXyYYwdr*YQ! z%Q$D8H!c_#jZ4O53&$(g(CK*Rx~S_mCY(J46HZ)zck=fX6Vm39Kna#}>W=pe``H1}B>g`}U2j z2bfvrKy#2e*c@VJn>l8#In>NE^UVUY&>UtCH%FKw%~9rPbBy`8`Gh&v^v!YRcyod| z(VS#HX-+n$m{ZMZ=2PZ$bA~z7oMp~7=a_TNr_FihGv<7Afw|CJWG*(JHJ6yrna`Uq zn1T7C`I7mv`HH#JTxKpeSD3GwE6r8rYIBYGn)$l9)?8<gc{J}hAM&^&^Ve=>Ri21Ymi}|a0)I4VXW*#?Bm?zCs=4tbc z`Mddt`KNi-{L4INo;NR;7tKrNW%G)8)x2h2H;Khqti@TpC0L>*S+b>As-;=FWmu+V zS=6#E$0}wOw@O&IS+`pytvjqct-GvJ*4@@UR%t8AO14t0d#y57S?fNloK@bcU{$m# zS(U9SR#mH-Ro$v#)wJ%nYFQ6hwXFxOI@Uv0UF%`1o>kv!U^TQ{tC7{%YGO6Dnpw@Q z7FJ8EmGy}AsMXqf%xYt`wNkBiR(q?1)zRu?b+)=#U9E0bcdLih)9PjQw)$9}m1gy| z(ya_D)9PpSw+2{Q)qF}!YlpSd`q=u!+GXvwKD9ox_E>wZ z&#f=4FRgvne(NjiYwLjZjrFbdopsRq-ul5hWJT7G)?w=>>xlKU^^5hZb<{d${bn7v zPFN?cQ`TwgjP<+qhxMm**80mjXPvh$SQo8J)@AF8b=A6NUAG8jC`&oYQ-O+9qB2#e zN;RregPPQ$l-ksx#b|L_g5E}NrzPnf^iFygEk*C9_t4Tbi6+w&dN2OhKV|8Cv>Yu@ zE6|Fx60JWYCd(fV=7wt{^P>-h3zBHX? z&`jEo_NN1A79B_j(ZO^G&89gtmky5`B_Rrc>xtI*mR>r_&j9CY?oR(>Zi5eVWdr&(QgF0bNKJ(Z%#xx`aMQpQkU- zfWAmyqA$}|=u*0jE~hK#t8^t@MOV``^fmfAT}#)|^>hQ>NH@{VbPL@|-=J^Ox9B$d zHhqV_OGEk|eV=|nx6=>lM|20>Nk68a&|P#l{gi%2_t3rcbNU7SlJ2AX=~wh?dVqdI zzop;NgY;Y|)l%*;Z`T)@lZr8AD z+V|VF><8@H_JejE`ysoo{jgonu5UN68``ej$Zl*mv76e>?B;e0yQSUAe#Cy%Zf!qi zx3SyWsdhWNz1_j?Xm_$Z+g=`F4R_Xb-c8+av6e_9%O_J;r|Ae!?DW`}R0{ygk95Xiu`A zv?tqB?5XxN`zd?6J;R=9&$4IRbL_eH)Al_38GF9Hz+PxCvKQOW+Dq)`?C0$l?7)7} ze#w5>e#KsDFSD21E9_V8mG&xowY|oE&3@fpYp=7{+Z*hS_9lC?y~W;YzhS>=zh!T; z-?rbe-?c;gJ^Ow81ADvuq5YA)!`^9sY=2_!vUl5`+Mn5b?7jBq_80b-_C9;R{gwT- zeZc<4{?`7^K4^b$|6m`oBl}1Du>F&L#Qxd-#s1YkY9F(Ivya;+?34B>`?P(={@wn= z{?k5d|7D-E&)XO5i}oe^vVFzAYG1Rj+r(iU*5Mr95ggHx9NAGE)zKW?F&xve9O~GP z;}mm>J0+akoZFp}&K=I3&RtF^=Wgd7r?ivgBs(e2y-pdYtaG1J&MEIya4I^LoXSoW zr>axUsqWNpYC88jwVVf>+RlSc9p@pZuJf={&#CV;a2h(U)5vM;G;x|b&79^=3#X;i z%6Y_j)M@QJ=CpCzI;l=Or@hm`>F9KFIy+sQu1+_nyVJwz>GX1XJAE9_Npt!-=}v}| z>GX5@I|H07XP`648SD&kvYi|!*BR>MIr&b3Q|JtHhC3sik-f$% zXS_4PndnS%o^&QVQ=F;JH0LR2x--L>>CAFwJ9C`5&eP63=NV_dv%p#CEOHh*&pJz- z=bY!A7o5O((Rs;v*?GlT>MV1XJ1d-5ot4fiXSK7&dChsb&8+>AdA^bKZ8|ao%-8=RN0r=L2WE^P%&Rv%}fxeC&MU>~eNHpE{p8dz`(_=gt?- zm(D(Czw?#zwR6Dv#`)Iy&N=9O@BH8#aw6wP=dkmWbHw@C`NjFwIqDp9eshjHC!CYc zDd)6v#`)d(!}-%W>-^=MbIv;#oQuvS=dyFfx$0bVt~;a{Q;aRf72}Hu#l&J#F}avh zOf9Ar(~JE-4BUeP*h&Hbz}k*B8+*e|Qros|+jzBY+qP}nwr#t2^C6R#NJpe6G7uSw zOawuY1VzvULjZy$Ai)tlArK-V5i+3=DxncNVGt%^5s0t}hj0mx@QHxHL`XzLOk^gq z5Ltb%}aJeWC%;kZ43SCYlgUiDpD|q6N{CXhpOp z+7NAtc0_xk1JRM_M06&)5M7CGM0cVG@gLEX=tcA<`Vf7Ienfv_05OmlL<}Z|5JQP! z#BgE+F_IWXj3&kqV~KIZcwz!Ek(fkGCZ-TmiD|@iVg@mjm_^Jc<`8pwlL5J!n)#Bt&TagsPioF>i?XNhyfdEx?bk+?)$Caw@yiEG4l;s$Y( zxJBG1?htp0d&GU>0r8M{L_8**5KoC`#B<^W@sfB&ye8fdZ;5xrd*TD}k@!S>CcY3~ ziEqSr;s^1Q_(l9C{t$nOe?$T@A(@CwOeP_dlF7*AWC}7RnTkwJrXkak>B#hC1~Ma= zi6lspq)3`%NIQYIBrB{fnf4bmhn5|K9PkS^(wJ{gdh49SR$$;@OH zGAo&l%uePYbCS8p++-dyFPV?bPZl5xl7+~^WD&9`S&S@BmLN-#rO47`8L}){jx0}B zAS;rU$jW3DvMO1PtWMS-Ym&9d+GHKFE?JMPPc|SMl8wm5WD~L}*^F#Xwjf)Qt;p77 z8?r6gj%-hMAUl$s$j)RJvMbq*>`wL||08>ny~y5VAF?mmkL*tlAP16z$id_gaws{B z98QiPN0Ot+(c~C%EIE!GPfj2wl9R~E

        Z_boU@q?O;DnyO#YJ>^2(fQTaB@U$$F0z?ZzJKtMUx z%#%hMbv4S{4b*D32j-r2zk(%E@uOmvHL)7&26zF9sKVXL#4PinW%O*#ZRHa~f{v2f zngzD4F*XmK3OB-xgORCX;4&la0u6VLVi%`usEz=u!j%o{7mOqUQEXlEgCJ`{L8u3^ zh&JkKQ&7+UhEPv=@ldF33*;2k6TS@Up7V<9LFiI5pTmM#;W6`FxBC>8pW+u;uVZ|N zMZwwbc<{_a$JEa*bfHH4;(Fa%P`W=G6JqU#9B3!Wl=! zAY~Osy&1BpEv_5ImUHY^4z$!DbnK`w(9ev*!y)N8o;Mr*;jF!^?X1(vrO!pu-`6l| zn>$9du*EqlyujBt*uSQ3M2LYMmI>J$x27v3jquq>8Z7G|NU8!!M=K{RbTycmTdy#2 zRi{UFh0y?9u}Batv-B`ddbiWZHK^$IcawA<}|Df$2I2WUa(G7u#Q%+%8~}G zH>QvqtjOS1x(tWmbu}OtlVxWXr=~7Q8`X?YjWy;30s0Jpp09u&3D93X>wAH3_qj|B zn{QF(qOyLSq^7dasw*I>hmNar0}idaW{*Q9kF!@1;5q@~DDDK;m{$u4k(JAS9muxT zrdmCi3WdKO^|Qxhea#A0DpDr(|A6|xxwk*==dsM^!x(cFZ@<< zy4j(;>XxSQ!(;k^$5nd#Os139X004wRY2h)poxwzNIcB4zEYPsDBN{p@JHdU*}-W@y)d8d3dz-_^R>nt@=y?*jmx@{0L!?` zy7U`DB+XUeoTEyq5YEZ^2c-zxZ50#fD}j6h!lm061?UBde7jN%CAd2lUcB~Vn=@4` zcyre9D*J|=tgv{F;{E&fojSbZIf{2Z{cd}95l4pN$O5+Jhvii)%3MRLD@Rgh2}%IM z=`thP3W*a!+yijQr7wCxfweX~a}YFoW+@!q%raM)%W=aqt01*2>W+7U18v zH>7MkkD%PigNUnVwQ3|u>D;=Tr8gHh?5hqP(=b1KMCcUi&!Il)H&sc)zH>swd>V;W z9-k!6I-y|)w?viA8_b@&_)azGecJCk=M)C`N@f`bY8_|qk)l&D8zYsyqPTT9MJ5}Z z8@72zvQ)&H@k|;c-1K@+Yv3L(WUVpb<{4K?3W)`jxkaKX5; z0Lz5lF#3C1Br0uCxe7$GcDvrteMaa4Kl{$}Jk7Mbq3e6WF`i~$(mT3iZeK)v-sTQZ zbBlhk#X1p^vVrY9*Gw&rhqvZyiv!1x)Siep@z4*($q;(m8vGTBSiVxwX^rz3?gB_{ zO;t$Q4a&~)$VP)oDP6VkbYE;jnH)8_S7LPJ-`mMO69}HV<`wTb3fY1Xg39%Ng#J6F zuGAWlA=JLi9f*qC*A}B_hWCZqrukKn>=m_VyUZUxkYX2(QLFDiYlWscEDARF(*iJj zGMlC@#lRkrnL>V}Z(t^5my?|;^PTmA;sJK;H83u3%!=YFqEEKWwu!bw&m^1XluyrZ z08{7vDVTzRl2SI{0e6A4_9RFR2MnO=vn8Y2ATkPRI7rSn$OSF{1Vn7PR(WJ@BZ_@ zt+|$K%|3$M&cJ;VE0DJ(5UuADJZ}Yd&D_~r&(-p;gi6c}P#~wt=TUK(3x3ZR75xve zb%s5^q=T$jG1X&?)nZAbQNLdthdXY5);su&%m=$ znwKcMWD1h&*!AVB5MPVgq|eB6uW(GNya;+e1v&QRJ>1;+?F?*xL0KHw5{qRFU}gU< zG9h)(<_Mh0dlzosWLOK$(FS@S z2}DCb$FolTlLRpA4!vZahT>EBsx_3t!PuoRYk&l+yO+a=y4fGT77eVUv~eDs2C_${r+@Ee2gIrxHlSHI%Q z!|cA*y`DS4i1=U0t!}X{6|q%`IfPZ>IiW3xg&sf;+-S4L2vXP_?Z3GwAfndS&D>88 zCapC%S-{k0>Tc*N3ED|8r@#3&E5>stlizxAi4=1f@0Zv+NUmk?@t2Xu`zklc__%g& zTo$$95N&bR=-h#!?{Q7ATnPMK1Y#HZ?2n;${m(TxfBt38g~bPBxdTtZp4T_g> z9DGz5czV3PysTDxa0Oy6kFlOZjdjVAH(u?BJIF3-J}Ox@vk88RQYCZHXoLR*r`bG z0h2|0rM6l@hFp6;f4(bpl9CKAy^EHbZw_Qgtis#Id~^3>WDPHz?+UIk*I)?dn^}OF z@y!M1i|VD+{JT7ji{>wroB<cl zqXHe9)Vv{ahdM%tND?rR>m%;pfMlr58=ICjXSSy)kXz=@0no0p+jcf*TPNbn%GjXX zvh2vw7JCMjX-{<2=d?8u;?xoG_P;#^)62`OKHi))^*I~8+Tv`ElrRrQnLLMl%DYl- zS#T>SS2AyEg>H>p3JnP_pW0@g`_e(>oxmm!4sB1*A%#_Z3dGJBfB&Xr_+19#E??zt zMc3on6uf%ZC3kB#;(@+vz`Qw_uswG3Y3MMuC%4Yh=4{TgX2>JknkJ7N>$~#EwJwlH zp5>88A8V{U@~v~^QDB`VkG@ugJg~o(N1=7RJo;Nl%cIEZFOLCMo;YW6V&BCrsTQeXvU;@VIoIA2>f?!BmSvSJEvCyrwy$!H_(*Wab?qk%X-<3M92shN zujjLIPvd(E{Fjs4D7-sMYRF3blTY%REw9;$KRT~D@|u%i$x>f)AX_{#L0x zimZY17+?u*_Nn&0GE1{I(5lrUNMN0+R_AapG8k^)H^ceOZlQP7=;&aP(MVgHB`5gF zR%Q;89awT94$w@W&`cOjArtrSxbZaCr~JD3CHeK4eVVI?-ynX2`JK$~bbeL*zQgZa zeqMe7evk88!fz$N*ZIBA?^AvU`1QT%G*=0~llYy%ZxlZ-ze)VQ$L|_`Tlsy+??3!L z=l2D_9L8loegpZH@*B$URDNgh8_CbjZ#+LgKSeKx2`!TyHCM~Qo5S14Mw$*kk?s|i znwJLE??OV?Vy9}f{!-uD#o8o(M)2%Pz~S`{y_?+VXYOopt|mX4vhU|&^6EuWtQ=)2 zs-Bh&G>o0S99Caz#Px^m1O4v2i->_yFbe1qKU6XQ`Eyx4Ti7a%TUtvpy|M#lZ{uoT zb*IlLI$ct`SK|z=8m*iT-^LDyvL;LJUEhyJ7Co|ZoXhGje#kkzD|(zab2{!V?)Mov z;Tl)yX#BChukzj{@&WZqgTW$hcgwEi-P#Ha!s zqs{bT|KG7_)I=}GY~@P|Vcuqq(n~|fg_lNX`hdB`;ib|ou3$dv{ci~ftG>cpA>1jf zdi|>@R$Y9GXIS-1HZ2j!0gP>D)cY!2zNsUz4BuYnVrxUc%mDt0-$R4Vgf_Yyz6*Kx zC&y>8dBnZ^RX!v4lo@<8?w78L?sX~FZ~qrR{OTffTHds_2@70ua^mZsc+ID@47Sp;O0lh2pX2UdT-(Z-z4 zMH14=u0C7sUQYEdb#^*;;KBnZ4gT=1WPSAp|58_$`dd`rxFNX8A8skIue5NAm$~c| zKR@zbQ~AJP$a%d6r%c5vRqzK+)TMTci=EdAnG}dS6o@136lXiHr=*J*>ckvvC%{pu zq}Lk9Ff3Gia-gEG_*t}X_U?)2BSlTdn+B4^`jqyS-He~Bfg*V1hkStJ*>Jo}KFs-$ zCP}E^=Dw1I-JIlTkv(13&G}6ODaYC^HKgai=q9W}>{9<(x`SJfN^;YM_3dRi&T*L^ z!8QBFN^s7bONEA*f4Nmr=`|+$jts6%cC1OP@9=$HS|(|HYF>j`rL(n~B3t3_D%Z2g zl?`Lgb%pl&AmhPt;?|nUhtRPBsXwvqm2*oP#*7*p(!^OIo9cIuQErP6k;({myDVJZ zpaF!!4w@P1`IFYnNYfPCZ(SfdyG&Qxj(VfpFV_u-tix`?hFfS@^%mSzhK@GJ>`o?A z8~mrRNU?74M^8kcN@wt$f5}jP3FRy81$08%m;kFJL3Yzn)aOi`%i$2dMd)R<(VL@ymMiGo%4fxB)guKLI2}3njwgm-X15+yF$Zl!^&r zo`|m1!~mQSWJGq4^lxIYBB^T=0!QzOhNr5JHqm#pw1u`SF#^w*KT1q^?C=##f30ya z664H#R4$Lp_^-GTxo$*Qk$_QB`G=vd`eB_~gYqK`vLPK7_=g$e`i zlB*^9zHF7cWI;N5nnd4o9jWW9VJ2_f1n0SN zm9i+hhDlAJVp>t5`dHjq*%9yVL)G-s)Yr*H`-=0Ju%kZgUqMczP%sEwycs|>uYsJIc z|s{WN?O(rzqO42PnV^Mqr6U49iI{X{AaUYa|w`b%03Eu9dV z*Vqm3JL4$Y%Lw{B@h|k0P)?3W^Mr71emF(Ao+PB*=cnU{-eE`Aiv!4_A&)>|@UK=` zGMJFo^cuqz>bZh6zG3(_!>ZG7KoU#(^LgQ!P{~4-BT+wWjn?>QQWND$M~Un^Z<1sd z(hFw)B{fHe%8+rFJgQz!wlleTv8nCZD*6f1fK)0>{EGu}89B6FMz_$a;uGRfg{eXn zroGFIKjp7v;@d~OZzUb`XPQh*nbt4!Owq9RT`Jj-mjRLJqKDM8Ck?ad*Kbt()S|2G z?-ZFzGj+&KnLN-lp<%_Z@q-9WYvGr7lKmapF_lR$RcMF|{C%nKS?as0rxQ?#pZWzq zXiV`b52Xv$A z6P@wyuVqvX8U7pT{0$`g(T1-pM&+pEuzkc(ARjAG{3j= zf25MiV)zq6KFxzBcG0sv@~GCd?JcUDkt+Gma;|V$C z{YXW^g`Nl)vwYeOt%;8r#3G;Z86{^+!otanBd2X8`I5eH$V49YioEAnskW62R%Kze ze{#C4->R}w^Py-JiR}^h5+N-zirLSoJc^83*p1L-%&H+Rt#iN0qV^(TV- zllC$(PbXHIs(6hPcnMxcYz_gUe400}lwjx>!BdM(_!2MC^|n1iPuL{|^x;xa2l#jW z58(f;2=E^ub*g`4u(L={g=%sx`g_c&ft0WT`4czv`>EkZzWp zE}(gaERdo^U%%)92^Hr3g@>S9^KQ}_#|o~c8`&C_)XJB_q9_l$v1bvohiJ)Um8-K} z^KRA}r%3I7?FM9#vQ#8Gxe~nx{VgUfvn8HbLcF5Bhr+kwmv$AJcgPlk*6C^bXv6=f z)OXL2=Lq&_UmDn-5)ZI%IVs&GcM@`d{j+=<<^apVibyI#US%Hw;!l#VjYDqbfq7KX z@jQF=5)IpE4(dWj10FEfhcaxGeesJl6sn$KouTQ6l@1X1kj{Lv zkV<~4DoOSKk<$K9(uO7NkJ138(o4^|hrCFNdd;&r$fZ3+|FB=y)EgTD!%8k!Z(iOu z@>XxZZDvUQj^L4M+xK&7E0Nl|_bPf1am>s=K!0BneAbTyn@G^U9}cUG|A%e}j+d%r zLvRbLC}Ud6<>CT)F^bxGvFH4Agjk&3lZPx$TEx$4&m3K?(tlyUNO~>uB)bDL|AH4g z^SvtiYPHEIS;ULo2~#BczOz;8l55k^K8e0(8L8X1&FLJuJl=grOZ&F{L*@f%`@Ro$ zw|8$TnJ(e(v%c-2M{(f-&9Zj@&yyEI@d6LO;{3^dgPhO|Z%$@fZ~*PQr*B`r=yG`a_U?+r^50$#PfzHJ_T5w0^4!2rc=~@?B;7du&G!ApMN6fy z{nJ|7-<|r-^6iPoi+(|b3M@{73h9^4JDlM22fJ}?A`Kl)f0*3ix$Ab zFaPbuEYwuErv2UNZ}MSj-oqp$qN{!X)Ha@Gd-vqL9Y2!}5&814ynhpJx2A4vZ<~IA zmaJ}Xo4Ow`ZJwQ);Ms}l=68TMc=q-!)3>*8nf4C9t?g~ocF>Mp6ugeMyv6Trn!Sei zc>9{^pSG`=x?7E&T2hVu{bN!sJUZAPJC_&j?yZm+d7Ce9cRnp|`xTG==Y4|aA&-6m zbo)M7yL|hnFXYW3QG0g}2EBdvw4xhSWQEO~(~u4PUZ?)mK%4h{KEg~3`tq(K>@Irp z&o(ymX7MU)wfc4qFAjg5d56(fFZT$B_D^eF9$zqRc$@t1-wJ2_`9qWxzZj;Q7Qeha zJ_n{-+8rDx#*@Nuhb|!-+;)4nkkIyShubD_1a3P+Kfy;{DRtWXHktGK0kmC+wKTXEGnM9>8y}dNB3<$-}?P?5dz8?bh^?GI@4a>}XGHDfuUvWCC}#Z-C!!->~nD z-^tf~@Y@%_?xfcfi1Rf+P0@vMgtYsPQ;crOt#-7{Z~u)Ko8Nvy(ljYg?nd6FyrlST znC(X-m9bj!+rLsdY<_zlLle4me>zI>+uMFZW{2PQ@=1$)LOQTrrC!82Fqzhn$|h!U zLR#ckKnGHV-@X*KMy+?kKmK0Q6%P4`hs{6!gpk8OJ}ciG{!z-qc_f%j{8>z8QvBmg zNmDrFuPUkVd*3DG@O$%Aq|JXCgtbTr!Y5rTcu8DIIjQv~UEa}>r*O!0l~u~iCghZN znu>&fJdVN6X85&lu3vyA^NQT#9Y1z%XlN_d#Vb6LmkPz5%SRC;6-@pg}# zrHT+YOhlh=M=SpE2K6DsKb|Sy+(pMq^gY**J`v%c!#^hOr@blu@hx5y|JX)=#tQ$q ziD2j$!BdMfjfC5_`HP;gONve|VX^tg^T=iX7zLZeOQcTqkIg^cA+?NT(Y;*)ZgBfg z0?dUN4_TBO-vd5XV`7oim7Xuum**o<;#yTG^KD8?;tCa3__6u3K6Wv}Uk)Z{^Ot8! zs4(w*9)do_U#crBQvBuC`}k5=bh?w-U9z4Cr<*^MZz+~-f&j<*%9^D3%YQ2dS=A3Y z&3lTpiPb6&d4ce|bBU3W13zgHJdB^bH1*vx!;wS5f2e^Bjl{zWw6xlZEOn z#ZMlHNkXsili%gTk!t%3Nz8Wi>k`LO8}z%gXDUE{ND}-(66}G!MLunxM{;__`4NJ3 z4wg7k3Jq>L&U|`HMiPJOzJsXR*~g4H;15*B>zZ>5^d__e;%F1}@nOgo`bg9&HvG9(9&A$ov7Z&RNzQ-3R5UqpzV461AJHqNB>Wx;l&hd6Ua^jj!TBU5;x} zyzSvrT~S{}JW;%8TavR7PU2L`wQJRtj~qmNgxMA=ymmT9U*^Tk&|e_vqHOD}Aw2GbDnW)6xnjP%7v<%qHn@Oyl_3dL3Cf$5ADf2@27ZI`I=03Z%;VZ2E zOPLrhGeD~97OjHfsk)|(b4VrU}%w=I@C#s+qqE1U9DVWIH-5WL)ZJ3*xjMA z3+)ufU^SgKHSr<$h%-2E2>?}q)BRY{DF}~r)x&`25gyUM#4frEu^YRr8ve6{t@M;v zoWut`HYt~I8Rs4@a|~m`Ix|%lec#wA-Z`{o+sEM=IMNaN#V&0U?pY~9iPjl}vjq-N zuXIP^r?9*>+@8-U?f8N_0+tSKv?j@{L*+`}YsUBG8LQ)op*b6_d*z27Fp=|AR+}Dc zx}MDxDfTAf`|`z&=g^$aYg+GTl;XAr4GYHxQt29Uye1}>$eByc9dBgj@fEn1$8Ck& zAG0he&010}4XW-CCD~+fqtD2fAy?}gTRSD0ynTTAw@hYhg>UKlZBu^=6fF7ih4?u} zV+K=5u|@%bCc1$vd*nv4|M;$ap{b4Lxl?Q`5sP?~=xUURtU zu5wUw^y2=$y=RGei*$Iro5JNb9}4eS^3!tvPw--~H<7a;zAxKB+jXt^l^wn%dAIGp zcKfsqK0u0cXKj36zeAzg`6&vR7Z>=JM4RkC03$VOprp>rq`t0oO!Q)|{a`5N*k_?N zbhx^|OY|)>HX;Fo%h#|c>(-x>PWLTYI{TeXe2%J51v_Xq8GKO($}(}v6qSJ#p~+*uMB$8gpDiPrA%u%*mAXtmynN#2N`DHg z=0zXX0tqr4*Uuc~*hsmU$oavL@upDwQ_XI?6gcqQ06b#$BC9(pF*)3PWS^U#Au+EB zRAuHiYL`QPfeP&2v4EY7!Jvm3AWtDz`}mA|R4t+md)mEHBn~|Ujz!A_969$^4eJ5l zjEBAyzG)fw)`8lug-`Dd-=43A@9x-_!dDQ0w)MK?hD!|t#t6S*Dt&}*Q9(G~T>1*0 zOk=Z-@kGnaGXN0pEcuD^+2rZXC;DUO;S?;piAxi;#k=Jq$y5DCet3RC)*S=ujg|JL zhwIGO?}Yg&RhJ&Fb8Z{lGM!Dzv$?bF+Xf*~`OR|mEA!6!hi_54_&;jce+GoS$?J;M zz4q7v?q1ELkqTpV&+7kpM~}qOIwf_i?r9aim#}xl$NKX!z8m&eh4g@tkHwoG3rt^B zi;aJbWWgamyuU;>?)5skW*|-{UfqDVPZ}85iLHdzd>pDnq|Vp>l~r%-6rU=yxlq@S zCd&x?(0nSz9tAj0XQhB9Cb(N~Zs*o|`{J|kR<5FK=^Lx-v@ILk!e*526Q0Hr;`3l$6V5?aP!B#_QWaT$1Hp0?5Q}|N7fnPN za&&3vwjRjwyFU$`ARrzq@QJr4g;xP_r^@-i1M0X#fJ#I3lrJfL!(~hr5qy}{lm?5; zNT-d@FSvd{-}81L`klco;jR0_E%^xzDFf*Sk*?UB?xcHF(miur!1xaLoHY-qkKK_K zh>mOM_67$vbWaTSYv{g8{>{dwwz=Kn@~`%hS=C!!n24_s@feB7nBl1TV^gv)`SV3_ zy7gc@rpvJD+sx&HL%W$n^q^o`})lp8q56^CB;q{?|yrs8p2MQ)|1ao0SWr=}N2AI=S9hA#|Mq`-XWn z9c2~wjFD+7i`5L_5PErKOY2P8cUz}*rph4g7!`bc<)&oyEA>Vfnp3fxaU9rZbmUw2 zR8MdPiwN9LKx_P)DjdD6R;Rmj^ritm_v`2zCQ)t8!ANuvXe>5g#SezFNccYzEMYRH z2Gj&bj%2cne^83=OYy%Z5Sph{zIqjn-hm<`(Q})M}P-9dpK?%G=t>})|h{lx9 zZav1kfK>>~F{maBu*PPxK26paWkt45JS0(RCQ*z;auIa^3&fvi_y@6cE5+On`VKjh z+giCcEbp&Z;0oDzvpIkK=t$Ndq-Fgi^q4elx@uay8KpobNlw$T=#1v5mc?#j0_8wB zi))I5{mozDlp|VY4x-|KQO)qPmxP=qt)aUjcy0<6T0}%yH3f;!q(@SXETNGD&8Zae zq6`DdS-az4a*4Du@o!1U5^ZcubzKuwX1ytQIf9>4oAcAf6jMxpbD#}Lvy{L|k1O%G zDgh>bz4_{d0wF5}T1AI2 z>%I5=@teQhYnz%aoBqCRzgH#Xev8cJJ}?Z!R7$b;_igD+N*r+Fm!+fnY%4&uUn&9c z4`T$|dDD4r;%3X@(YaTW59>$n2t6_U7CZH#@fd&&`Ixy;|8 z2x_@RZ8mWglgAifjs)l)7h%r80G5&8vz==HqikTiqz|g$Na+KRRABC=Okws5&C`j6 zZO`m`ngZnoj%7t{_$rJbuuTqMRR%`txB9SG#s~tNWiPtRVy}G3dya8L7j_V(YO%v; zBI3!xuvJx9aJ6A~$ z=}w;rO7cytlap4!m^8>}b%u1S8q(Vt(nu>uh($Erj~`~~>WR|*KI!kNYUd;$Cd#s} zhDn)u7Nr4ZjqHs?28!JxwUn5bwOa*W-Oqx1=H$E;#|AAioERmjZ78d$8tTNaHZKzkZ) zg^?=PW3|~LY%L*=l3aB4ajY@?IsM~%^s$)Bn6ol~ZQ))#&dbF$hM2LGnTxj^Ox}OL z;DP=98go5(lktt*0jTZqEzE-0qo!0a(%QeyiUHI+F z*B)xa_Oi!RQS=U<0PF{$DU~-%AVp6!q zJdL&j!VG{6<@?>A1qWM4+gl)#RgCG!rN7A))|%R;bN$8_lHnXm$CIlxmXXD;O#-J^Snr!=2N{yR0jcyUzmzwQu={AnuuCSPR z!x<%u;kJ%2cy|A)=ivG6179}~pQ2hZsl*dE??$l$qUb87HZhOc814S;=u z{rT3jLL@DA7PzIT@g;L=wZ$NAjrln|lZ`*&I2cn2dNd^~QeAE?!zGl{-Dgo914<@l zn}|c+^%+OOSjc!E>#wEn}s1S=aEbl;uO3c!AGYXTExqEtg~ALT+cCavjBD)LNL#>vIoX$tr3+5-yhQt`o<#oTR3l= zZODgTj*Nef77FO(ed`hYbCj~aK{CBN&5P)3>u7UROS*^a-%0f_&N?#m#TXAQVsgYy z2xjPZ#L8yQFJ-*r3#8=RcZp?M$=~lC$FYDvTWDr!y%9%ST8uJ7<^blN&|$!p9NJ22~PImr4nuh87~q5yp|(?Q8v)#2cwvQ~$%PE=0EzZ%Y;sN!TB zXXYOU=R?G#;B+LtUj^rjJ>eYH8&0)7_)0h-Nr{Qf5_vuf+SND~KCKj=GxpksKb%D$ zH2|wPs1nmFA^StkzrUb%gDZJB-8tqhoBA&&t^QIC|Cv24++&L`mHwR3XvN+Zt+>8Z z8<jAN3-9%Vc>EKNPZanAS_SH%ALy{o+8G%GqYNzT4{$^JlUIzqUQ9HJk$sk887|Pyz zANIE^0esf$8XY{TJbk?rGAAz9iKC%+>T8>{g(=jG$%a|b-2fGysq3In13SD zzPM>tbV48a<(gTZ=#L5jHyWxjm(vUp#7zV5VMeChePwuY_PspWA&WPcuSX{oFMXb^ zeKenlGV|V6a2cIY!LN*8mFhB^54lA4HE`IpW z^nUSYqQ4{@g|_TdO?R)?8eiZA2p2%(lQ{jo>M45elBZ+^Ds^CeniPijDFCc1=A7yk zaJvLM;gM$bUu9XnWC;sHvgAw(7rzj)c`@pVd&87VgnUN*+Ui$kMeF*QN~B@bFBd({2?&G z>4qEzbGp&MLx#(h>e7UiU#Z!2Ps44g?&*@H2bhb*%|1^#7PKw{o$R&hJCh|Z-m7Z! z$jSsL#3xIBXUA2kk)u89eb1vkd&zeG)oh)r z`?JE`$IT;jYxd~c<~M>lwau?ZUcrxHu51D{Z^x`rrw5Ol6&^J`*oXgTh5F1Ibxn2< zQ}9JVl((c-XV}Hx&0i|GnzeW1tYMpH6>bt8fGcB@{!SU@3y%m+cgof~!1DQ@J4A`8 z!~EUHvMmdaA<9xw>&*M?DEz{em`>DfcGNLMz3)U_V@Cn#0VPhXXgSRRdGH3ycQD3a)S~DArc|cNDRgXHF0@lVFPzzBdA~#MMS}r zR%L`)*?wY_4twxW=eM7i$5xuzk!Ocf;Yr6c-!G9p?8)E~njmw%Tinh{;l+FFchf z#)kZHpr40MFpCAhh(Gwpq^}$Yg|Bh5id1O#Hdkmz4x<>!b2%nRTC}xCheG~`j$uc$ zLi2Bd%**RI?a2jf{i`~x;1e`RyQAJI-?ihkCnnMb725pP&qS3junY-3U0aSN$j~+Z zHUzAyTH?+oigM#MqVv)sI(RNgq|JYy9HP{VKJR!!(6_^)k^ROUqS_!zYRKJJXgQ*F zmc8g<2`oo*OX*r>Cy<_ZG`PwnVa6=t$vapDm!a3D%@lo0bX-Q-CKIPU9w)-he7WT7 zu?7}uV53!Bp7Gxb_Q3;`{|LHu zN(CNjRrL~;+p;8Tzu@CuwDI4x@tyW#+8yh)+Z$2Iq$~KPTbRl7P|1wR?_upWZpBo7 zwCa5f_H4m79S}EV#ZB7F=!lDiebvUwp^yQ@NVS*wIj-fk9oI%|mycp?WSdqqiKex^ zzc88YXx`%wDMau3jJ9NaPd@0H_Yo{Q22VKs76LTCSSq2JV}790=4|2}4cs#O1ip`H zvp(k=mDq9#!{|?rpnD^ow+{nS<)83@W^Gyac$K&ulb^)w42a$+Yh#>qt^6X6Rk^}{I!^Pnx%k(nwh|Io>8xs(2xrwPzNTnXn^#Ow z2oXQ1#m=f`L5YjCEs7JDmREn=sf}pu#7apsUS-;LX%m_krl8eYCFrf}OI07N$COf> zHw{t7V@m{CKWH^OcFEv4ua`s~*nf(inZ)py`64y9riAxW^^ACjhW;p#o&6~ddE(my zg%(KoD%z{s+SSTdZED-sw6O4h-NIg03$14L&;Vw^O4=Qr$B&<7-m3R;ILcOYczLt7 zwteV=fzi-MpC>f*IzLf;0cE(&>MefhC>g0gmH3iYE00qfPnSMer*JCB1g}3^jELy( z;r?7urC3eg0fZtakeX^ZEpZ`LpH<-7d%wc-X^I=C)hs>30CIwSC*qsz0j*3c7WcmZ zG`Sk8HX?CDsSj?a76YXgLwl-4SASXcSu{_cbt@LmHrmbs@$Mo(eDGcm4T<81xk|RH z8OfF7qQ(AR^1Rq{p14>-$jo`8&5|en|HVVT!S?xCyV@i9S5T3!gD=Av@@yfg4I~}+ zQQOlP?Y;o2l5Zw`vpt$zdbU}TZ|W(zRe#kzbrEmw1qJ<=av3pWoZu*mmSF z3QW!X%R-thgVP$KvVgLd?(14h7j;`p`w-lCs@r1fW-2sxu$YRT%xEfzoPUptsmTAg zh=R>YDn^d?KSM8W$0$*W`$9ratHt!tCSFDN>$s)F)`s|Y_SM9rcJ)&Bo3WRvlH+*! z=Eei%85i@;O4cet2UtqcH`|Q@5#szKZIOktl%}(k%2$VcJ+_nerm>?u<8H}t=HLNJ zen)h<(6D;T_7O>t8gHi9jQ4q8zrW+9j1p3+mt7JI=1)cP? zaX0H}<8Ic|#@+9O4iidqHAj7>9o88)uj2mJ_9ismq?rFq0Tk+s|B*A-o!#jpB#44_DzjD z(!yvy*pCs_xMNm`uy-4Gl!sAg+s?c6%|;UMb2aWR&kjkVaCuwf?y~H|@_xL$MI{Ig zXlo3WgIN|;plwH|>Rl;~^gOvYy_l@Os)>PkpSX7LdjLFDQeA(Iu2B$P)VQ z4caIin*Ya=|9SFXP*e}=XEe`!l4oAed93x5glK2>h#$3nenWg? z$B`aT+l4Q+UVKyj(`Db7Uxu-@z5+zn*B?DdYks!1M+~^su(#G%lFRx!Pm7nM`##anqu}p7Dra$$V zNsV99*Fh)M;Hs9iD|$++&asHU&xP|Fy&31ckN3}lmZ-yuXwFf@JbSI%jcZbh(aMc*$YsK6|q4Tmxlj^R-qb%g*NN>~>|5!@BXVsg5u zBwwrkF?2&BZlxZ=cd3!@IVI>tk?(5Z9&a)aA$2O5G%{_NkV%TT&|NCuPKn+WjYbwY zqR(*v7I|U9ky{ZKU4H~Y5&`&ZG%I{asaNhPcc)$iH~+>q{p1lnapwh^5qMYbyEG-} z9F48T(Sbw}5;%Fp6HL9-UEg8jD$G)LXx8W8cNUEW@p>6@!xTPO!(t;Yq1$rXP_tOt zCpdYu+aDSom;#SdQkRP6#F{_-QT>fThXSxM9SXoEqe?+JmgWh58)BL#!PHxwMr-}P zL;;&DUx&gSzlmX#C%e2ZAO?t)6#$fgb z4OpbUAhfB+&{rf>=A0!9(A`Gh^#~SRpl7ifHHvT4v-l|q1fH1XuGgP)uj#w-=Q4L&5~74B7+qEQe-zu@)$jdS(fdZppywlth%K%5N8r9k~@u9jno zQCtyKCmfk}({+m7aoukDdl0_7Ik%H9?^=1RQ%B=pzv;Z;x}*MVBy^>~nzM9(9(aW7 z{78xRgotZ8SKrKL-|aZ1J$@SW8}2lJN8d&6)r_nWCqr$gqk1;Mq+9FT6PS`{E+w8q z2}z*Tv@Ep;ovC_c8@DT6VCBw50aU`7bBGGspLmNc`jn=@3QWrcQ~QeoQhf(wv<^KavC&l@8s|ymaT?@`b88fz+B~@% zbx{SP8}vEoM=_4|?{2fSfSRzdaK-b=i!3Tq`18f8Wog}#o46iWG7kRc(wodze;vb@ z;;}}r9CBw0k8~#T)QUm6Fv=k11_I?eo8;uaEy>OGccNV8_m>`iPCtqCExg%*=*Yo4 z{hdrm9A9%mR9eS`T7uST-I8?DFA0SE@s1!AZfOHcAyuCH>+$YzKA_PG5SDRBAw;7) zurvXN8e)sa?KW3M-2mqNe*yMV0Q*i3CL!QZqACZx7J*l%)tdB_z-y5T)@gxVe3w+8 z(5in#7n{!>lvQA}5c|#k`h$=MIwD%lSJgDr zYQ$QvF(DHYkg_z(D8WI(@=OwMJ|}T)H1Qphxa25zu&rE(au1uR^`DZ)Oxb9 zRoMjoVcf5UH(fv@e)G?sD8~~L%HQAOL(j?VhR#^3wxaH8GziPt(rlH3@{|Sr)OmT) zeW-)}a&wgZyl^;c#%&mO_NH;)n@syF)m?jXcq~ub%?C2$!lTe&{RuJk=B2ro0_%?U zNb||o;SI0_g%`@Nn1)Vuw0ik0vkfGd>=(NK$=>0(SeS%M+7RQCE@p$I1%JpC@{f6M zfnuMJVu^(niaDqpIKmC-1tdw}B}2AdHf{P27|q)sx+UHM?f!Pn%GzV{y%tGhw05+;ew!m^}>s zg}W@nfV71c$DwR2c`#N~-Vkacz}nwRKcMk!`}YIjrut<`=&&78A5Y6iU)v!*BxhYn znORo{DADGXFvLS`!-zN6902?C71WWoX9-z!iQr}{Z{eBU&qwf+TF4Z-pG;z-I6U^k z{sMFMKa*21_zX|g#OV1&_;KC8qs{N^@5VC?>AlI5z)MCiUTlr+)8PRySOy3~i_ zJo1IE11+nBv(PyXuO+?q7@SFAnb>!ebp3%J_H9dSJadhhx>;lUj38JC>DIHXwfi`M z&yaDsWWioeMt1DQ6MGpRdl|tCFdBsU($LxQzk6ME{9$^Wjz9P}(wr$DfZ3e;%Tm{g zeH=ReV(EBcN?{c#+VQKF^^sOR2+W21&hKwYiZKEDdy(oH@&6tZQ9rsuVx|A?{T^M> zv5&5}O_Nf~?DB*{$nYJ{mEU{lk*|VTnY1vl!X?X(_G-XuwbD(kSB(^Eb z<$pi_hX~7-{@|InOFcW|wnx)RntxGeRikrj(^Vh2tE~O5z?qp|sh*a-&;h&)ZGzlJ z?S&4b6lE_on}xEoJ-*ASnf)j8#A1!@DUz5^wlgaAZtb-{YsLB`cD}@p=qev-_g$jV zo_5%#$;(zq-eO)9$*X|>-HAnYp2kp(WgHEsDtlrVGn-i?W(# zs+?uQyz3l+vHl=sM(uYb$4uKQc^)X+)p%x>m}SeZw2IG@`argJ15g;VZ9-AAZzE7% z^1dgr!oJ;8zMm&tT1nBi2D@rA4?woocPmy_K8F@p2ks>ITj_aZXhjk*E#+qb)l6yT~eo=n|c+)DurnDtQ@wZ z_eICorG&)D?*U3T-~TYS9(OCL%U(*Ey3JI3x_RvB<{1sc>oJ{i_esQ_SK$AG69lFz zLahyKU$-yS*@{^fGYnu`790@0R2DOwEZ=oFG!knW{36{T(tcMklFqS~aYH?`cbi|iZDN*xK-BNrRLtsgbP`kjzE9mf zxLfhxtt`r(m}T2stt|_7 zT*^+b&fpIA^Pvv=D|CbA{}WRWd&C*X_+qxVYIlb5EriOI_Sjq%wI_W8QO8+grb>ou z^Bw@LTJ=Rlx{T)Gw%vrfhTHe^aJKDpvaql*V(F<;sk0|a>PM?VF-{GH+@%n}(;m;0 zsd<`{CBQdwn_iw;#U_-+ThXaj#WTER^=~|BcA_ACmgDJs$lyg`3S_1Q|z&;ZAeF?nGVe6R7G`h%P+b7RGeQo;` z=m)KBVdJTs>|I1CI=!IvQh2eD>C+hlNYr@h&M+i+bK|LNH*3|;(tnNYX85A3Z!j6GbGES zeyhWU0u7Y1AAsXV`8+1Xc>x_xh0}Wzv3~y#UrO&MDUU&>PvvB62OOz4sS`o^ zKiD6x-~U~q#JBuuH}SUL5Wl|RmY0$qU0;7MJ>7UZ+Q*7Qb<$hFzc>e|r=hp z1bc@&Y+v5Xb7x=Mmjcq-u*OT$*|DV24d!`z*m__|rgKJAMF@Klp;F`X0!+}rSv@3T z)PqFWae(>gsu;_}Jc*z*YC_)^S?EvnB8VIg<$`4qxAs3D>4`X0+p&0x$2jY5JK~)u zY8A7KPc-2%dog^TEpDykq)wdnKWFts1RQrp(%-qS4>nXNWYAJLVtd`WABB749`Q!E zfuD}>qF0s1h!U_b?&g~dty*zQ5mhmVMRUT7^%RkhH{PY3NctlRtZsazczhkP?fF|e<^0kJDK+*f+YljmAZXwsONvzPQ=N@YpwaN{NJmKrOKU#%?$iCJ z6SPN15vB*8&(Z~I;Llmb>iLhXLiKzzOI&Gt0&ixCM`%y*p-3rB_aq9_NK`(%?Kd$< zVQg^cHo8xq(1S~mtBfRTj~mR5QpZ<|?wb-EHPUT-D7bT+T%5`I1IasBY;Hud)1RIz zLb$p%b+0>-_{gFIsN}ox>gL$%z1*FJ(%fwotG*$3 ztliI9x$|PJMKT;Qdvc3>)Ys?#kfBw2`Mh1U7iFL@E)OX~0F3YT_u@v|;1r;ZoBmKV-p z{h!Esh3GC*W*+J!Aw*THmr~=P)JMYTE6?yccm1cMN`@Z*$aHbcdc=cQ7UAQ#>kp4& z*y_VuONNJIoPoGXJ@Aam>@>b|GaQVQ&fG8c;if+PXeny(cC;x>H`zmj5mIqG+7@wh zvn~8-!5(Z~WeRacwdb%_{S^WoLcr`C(60XihE(YLOgQ;C+L{>`n#~79*jL<{re4yx z3C4u1x$Ajy8&*BK@ZmA6iaXb4Qhf_!tG|L)xg719e?MU^hpG8l8>ArnPbsLgS;d5; z`zS+yn`r*hic4!g_ub&>d(sn#VKB|YAPw+}vy%F762Ba=qnMTM6|{zv+`-gdr8OPC zBFLNGcY_W_tv-lCz|7Fno*`HrBM?US)&my2V=nQFBLH-Wsscnvv@Z2WMsYzf$~pXu zbNHs*4u7O@`6VDttJ%QnD)^iSk0XSOwK#v|V=b7?i*!KE5MHVxTaiC_1j--nh^#!) zeoR5yw@-vV;8_(B)}t0|m%^jWz5IzW!v-=K&TE;lJ?i+G1t+r;Ezzo?Tr#|^%j|+! zS%CLKahKlreOarb__w;!U9;QAb<0NcDVX_MPE+VXM#-@fYVBk? zg=X{Rk2F8RwE&o!p@>17Z#3iEccXMZ*9Rw*LB#6|V1$HU6EvsD+n+ll`pD-mB%&S0 z0)BDHmh95LZEtyxQAc+9u)WDgMG2<~7lz-opVkSBJ(Vidm$2=Yna#T?*bKp3%A2@3 z69(ixbR0aCyt=Ib!oJ?1T@mLRabH893BRS8RL8Vy-VIJZO7U+t$GIoP$q0I;dA@TJ z<_25%h*Alo;h3(CVAm5HOD5xJU2d~M=apaogPo~y&*e6>ozmxE0$lEI=g=GbN5LG6 z(EtkgvxQl@J*3ySkGfz$bW0lRgmUwOR5EPfy*vNJ4JPNb<1N-eBrWb zIl?7x(sB;)*h)w{Pb8(4ixK+_*b$)Q3)oi&wVZdfoKJ~G#Juc?mCu%?63m3ZrJO&B zKax-gdvfGTv+d=?UZQ;)nQJ&Sk8>9dou<^Phg*)=Du7SoAP z=9#!diMB76=iJ1xR+UFvwT|LuVyLu{ybbbBucX=Up;m&e`e-cNymFgM0%iD;RK(?N z6C^;1=Ucg=-y}XizFe4a(%L3RIfCnFA>Wi{GZ1TNs<14B0mx zwh~<&P4xF35(&t6V?#c@Wk+Tl@EgPc>+IOo<21(mgjRm0)bVrMD_Rb2*kX!(tc{ko z)@G3{>EsV@DpRNU5K98A(;oQ4N7P9gQw7@eJgJvVp+E6Npu)-%WfI3Yx7VuBJ?T58 z4V>qN-$kD5KjEoW?_yL4%eaUkW3i0iCLJte!OM9p<98*;qkDyBMp?$g6|As*Fi(zc z?IoOyb^F91Po-XR@@sg;qLyuJt^Z zS^OHOM+y^Waawkfl_JI{hIxEGv$)&-oeb$YD#J`$zIv(~uugvQHC8k7WPH*|5TtU& zFXsIMe(_N&e_pc6(-XfqE&T~j`cx>&H%`0$0luxy-;-hGpD7w4?S!FulEZvf{Ai&O z5Qp-Qh!gHN!yUGF7w=Zs59cSQo2!AKeY?<-p6$^TZw3?x>U5hPS2d zZn>1V%(gO*vFtlA&o%wb6^O++T36ujC`WFpx8v>3;65oWFNxpXOHUCIO!X;~3Mgk##X_wpw!71Q&lo}h|>_#CDa%GmGsU!!5D%vmRop~>%av3*M zb{irVPzMNEQ)Ok&hyX_FFCTdVUvJyT?)G|5E)H@#wBSbwW`gwN!4jx=v$o#h_#<& zwo`N$Nz&s~@|g{xz9fs@mjg?yIU_q85^f`5=rcaL__bmx0!vv~g*Mxe3J~Mmu*>-D z>KbY6@5vcXgg?{0j`%}NvlqaOrf}AxwEaB!Ps`J+Fi?;dt$Ue0(Fy|{WqF^hl|16` zPMqIy%DSubK1D#TR?!NafX#STeJjwmW!Af3m~JbxS6kl#He;T8S5E2V+tz-MDyH6F z7w>OR@DAV#m$5Vx9yFViD8B-YL17%vTW9_f%B|ki0E@*7|Cm`I?RO5Z!|th8ElORD zr|&Suy-J8-{5eC`{twF1o)Y;9J|>a+krG~RmX{%LQSH-tgMVq0rz$1dKTsB%PF`-X z{$jh97gR2+3V{-r>Nd15a?%H=sPbJ<7yCeY56=`u6MHr6VY!^M`>mIk?B9#Ml=DLJ zJxp1I4L)D9t_yTm|BHWxdTKfyn2+3xeUU5 zXG?t>k2bX=Lz>`z|DYAjVw0T~-5c^KLlp4rO(Cb_+A4_^~)Z>+qJN%hD@<}ZY> zq=E4mzRjOE(hcay#Vs5q?c2=NJ9mM*R2w(&!OKhbmt!x#u%h><_Jt=SPfg9uyRAHe zt54-UimNg!*Bbk`W7)^XUh)J^cU+-^&FK=e=k4Raj z`qm#}vQ`7xczL)~3Yf5FsBj+{*s z#&PmYZN?LMfk$~Cx5_XwJ}4O%hY6ve?YAU}Y>F1t97!Kcx`_QPqA^Ldw^M_@3+93@ zn4e5hFj+ft%;7%4pUwhGRvIhcl^ zV{Y^{1M1Ay-FOWvmE^~K5&Hz}t5_EUSng1g=FViXF@XW6d@dVZ{9;i$%?Xps93|Z1 zqoJo{RvTNzFiIw{S11G{AO6B~FcD5&qE(B4xc}5Jty<>=TMvb6d2&aADkvOrY%;>< z>TUY2V61b8P=Ya4%%{MR=4iRYyaOoo&ZP=cBeX?9dXpD;w_&pHkh;vIE__oRGY>fM z>wSa8>?Rsk2zK(nQ13iViJ6onPSqa6EH$<&sblOguMz|)f%IB26M~tIqq>rT4`7=D zIe0O+f!)BlS%|{l04=0W7pppnw;Af>TNP5?5Dk)Io!^{zmDET~L}=9uKno4Sp5l@u z0Zg$9oG=$vLm6rNn-$E<6ikuaRqc#Z?c5r|MiAKOts8e8)#oH5=!8j*>4WHt?cRJ$ zFdWtD#S#;ig-H{O_YBH6Gc%`G6s$Mj3D*A-{uL7zARKBZ8=})`;%vS65VX;G4zcd zLw~PAS*p{-lwizgq`4nCJ#dcvvRI2O&EcJaUUF0{M_N`}gEQLc;LJct4#u|3zlo%w zG7qWd-=1NTodv&hh#(Xowm#mwQc$35jj5TrE+&KC-DXLC!C_?#s>OGyWjU<4+ijLI z)}~`nL65AfD7vN`^BIwKP>jLmFq#rIFM`2XrYe^{&8Dljj1V!#(iHx?G6C~I)C3H} z=MNZ&ka;XLDOL5c8vqRvN|5J3~6jc&pvOz_Aj8o=5A~DnYiw2wK3ldyJ6}4))6NK%pRbQoExB|GG7h$kgr>hX;u2Xs8 zmdsdJ8?PsBO>7z?^MBbfr;(ba2cOBRr2dig*%RdgNUPq&Qqi>}u(*!mcG3ZGXG3=@}QuU31lKQ=GtG$g(^z9}gOvpUXrN9*#>pjruqgM1%2 zjU);SR*_FPekvVN8Z3 zfIz?o+W&Qc%rQ|QNu5BR5)4pyzH^Owg9w*$t3~0n@tnaUlfnO<)ydUcfbBBoW|g^v zkDsNU6@h`Zcdc;N&RS9Xi%PzowZD{y(B642$H7In3R1fx$XR$tymz$rS|9DT@$ru4 z6<53PCPEH;j!-^tuEeH_l0fRD+SHu!wW;}uTdjo4KhpgT35A#W-gXC{k`}I(Tv}SZ zmgY`#Vpxp-scBl8Gn0UPJ|<;KNIoIOgiMo=VhNc>$ZYwV?MXbv`+T$+Hk&sOFS_=GNz7?8DXt5Pa8Nq2*XfdI)traxS%#& zwbT~FhJ|rr1BvYZU(3b?2@(jZ*vArKkYZIXMXZ5#vY%u>7h1%AYxCxUI&8}0DWC!C zd6Bxx(b$$eCUxvQ576g!*+C`CMeC4?z##MK?|11^+OQcNGinrd5J&ZrnK<#K*vPD) zhL)2!Q!aJimF%}l_F+^b{5Itnw#%=@tftW-MzNlFl3-NIR%i0WsOC_2E^2r zsfQ>jtuMSOjbH7ouc>Q1wb+M^)%r~0d>;d{e>fF*TJ;~uABA}&#H}A2%=l$1{QI=k ztd()7tm!8)$k%dCjiyi|&)3w*H&c`e6I-Ya0)bTMC>09BMfd>{e%|;BZ6}?ms*)yE z`9xJES(=s^Yg!l^Xi5EhEC2;O=_|wbexBfPBdAkoWS7hawl3a_MYSYsnzxDiT=mm3 zW?L$X`e@aU$zX;U!g~Fjb3|Ep)y66ChDKZMWd6tZ}+gtg?M-w{-MxA$Y zRUxPBI&Vc)A$jV&GpY(X*3@}jRfQPatMe9A2@|8vJFKek9|=7BR~5d>(>E2ZTj0fo zC-Nc`C_IK2cBiPT@xlQ-E}Y9twY&`DrAl4~@glpTa2hXudFjo|qr4cmrL7U|H?$xl z>1kv8#04Hs3#S=+lC)d}o*9D$)WH48%BmyVHf7H69COL&){2Y|7_of9C|Sgqx$;a8 zGJdlW%fsZfN4(1IcKffwx3nOX;eszuPawhVZ%Quy*5OLWFrQXjeYp6wVa3`rjU1lB zH@YLeMa#YS%Ea2)DXmkQ3 zrD;+GuC5;0RQ#|x6lidC*YXwEEWnaX2lYrZcI6|Qj@tBow#y-m3i9Db}aq?3NYdFIohw)(-{Ln zXM}0B=o0gj`y!Fx-IoLgns-&RPM-lcZ0UiD3V)z5aayZBo7FOU9T^L_mO^*_Ed!*Q@h?8#2 zfR(h(#0?!JNAa!(n&s5yjZ}sK2cm)IpZX#FCD^_>m~=`G?*iV~+6mn}4UfU;KO676 z#3(7I!vh)DP^EzFa()Y1uxyTHUdk_oG@75)Gwo2EMdk+1nK>2M1WT+rfp_CP} zc2#pT$kQqkMwyr_J)bs5#gg+2PKZ%w1FI!XD^tQ(xmKcbjjh;7U2);41Ywrc;c64B zuJO*wjxlb{RkyN_$Ed4r@xANDPn_~wXMX96Rn+?c2YP4W4c>cn{}!M$ItxdQ6ex|( z%CTd-*Q=4KvzKmBS(JCiY$eP2t}tKz@Ho~45LouTh=ds( zVNEJ=tAGryU}=KNK^LUtvC(3p$dozsjWGK40OK^48I*llt3zV*Q0%0piF2A_=FYHu zHEFaOkxr%`6x&zWc!g|dTNFbtKdxXq0Xg)x$6#+fH!Bl%MauQey*Z|=lASod&)eB8 zcU}mC%*>+)I1$KPjHGWEr8WoG$#mRg{$i_4GjpQU8DgvZ$Hr+j3z=;ehmC`Qh34W} z*v#EzUQW7@hiJvO68{4Zd&RX3XPfzyVnhlXtXtf8EAI94<7|V75UgLR7unKz_sM)1 zWNv3J)3y||g&ag5f}i!-NRldMnef-()qhBUxr|EizFXd(kaxohPgaz~-V)6e8qIg; zVZg@vp$ESH{7<5M{Yw*=O~Tgy8zJXRD~p!)katvPUV2jHU36jIZ(5@nl_doqd*oy{ zP&_QiVjp@C`l}mb9K*)Oy;Tfg-6#;_=M%8*4}rQfO)ogV8O32l8eFLz8})*n?%l%vh{R=HiuG zz?oivcY$PCoysZUo7d_K=xU7b3RR~IqvW-#2T!S9b9fBfB1)#ulHCQT+y%SvTIQq? z2u?~3sRPzKFn;ls_V{{oINvT-`95<>cOP-)(lH109b4Q5CIYOuDBQb1IihnkdXKoJ z;<*YCS7NONeK^_KQYg%A^y*fMk>)Wj(v9)Sr3I~Iaf8+!&83caeKxmaz4xV3vDm9-+CL6;FE##OKpOcW?szJ;5vuVnv792)lHG z=|OgT_e`69*#YOw%!r&E6~htINm6tr2|2M#YX6 zPr=60KyoSjYyPRJ+%s^;A*|2NOOCI--;nCCnP~5Jzi|+OXDWjGD_A~Tq@x42pNtq6 zhlOlur$w(y2{5Ny^r~Fmkd5wY;t887|XuGSRnQKLLIf;X8* zmdX{!Ci4L9sO9-aKuE?W^M2XE@l2c>g=^UvFK7wfgME}B%N9WN;SJ~w43)v*89WQ0lT*(_Oj>fMJ7aP5Cw zrxpfHBKxa2XWWSR00GM!WEMVFu)voM@-vF zHEY!ph6QJvPq_bIvLA;z@yoNExI1ySnNHlwuXN%JF-6#KwF$M8|gqSFpvE zi|_Gz4kDlC_{ThQ61n^q@0&b83^?P+9j-pdlj`06L-F1eP-1gp;HJr$ z+ltQ!VdPLkaul!GR|;Nlu<)8))`{1jExG`&?kbM6ct+Z#ka~|oF#CTHEa*6&hajU7 zeza-fnW}5mzaW`gsJ6b#d>{AZ7QMZdap=j$&pDH+mq1 zUc4~S2^Uv55`6vGjwA@*O%3;d5rxl--1>DP_~9`+AZQ(AZe^PjZPEns`~i^^w5?;w zk^Qs%5NntOAUZNG*OD_~65Mzj7=-y^rD-BfBt3^{s&c9MFd$iLBk4C>tvr_eeFjbq z5&;tR0U=|(hkfSe57Zu&D-U)vRkc*~Xe5rEYVwByPIyC#oP6y*^$9D#Ce=<+zH3&I zdn2LUb4TY|59NET{AzP1QV6oANHJ$IK?TmE|1q2-3y#%}fV2ZldoS;{`dq|PnvfyO zPP4a{iRT%-%k?!g&nqG3Yh{`qDBZ=9jY5YKNyt>kA|;Q&iWCyE=r73+WD1sPN3m9zqmMJx595;G{ZbfEb(f%Mum%XcPNxJ->3 z$b|_b0eG9tm*JLJLnGGSV%lKRX8r|K`m^JQ#wqW#U?<|35 zklAq0H*e|sC^KDMAG6IHyFTWbBf36xGo$Ncnwi%1vBXU5{0LM^laGHHD=JV24$K35 zgM!Q`3P3d|c#lj3!u~HoE=W9%5~y?_)uu|;WSI}q^^rvvVj2)euMC=N%&F{|xk*$3 z4tvHG97HdrLtU3zqo=QbDZb8ZW=;di0>85I?cp*A%+}UR)~Vj z%tPOk6vC78W*GKX!tpbealZs^GQTf<$I~vYJZJ8zx<=B=vYFlXpOFjYG2mTp{!GDB ztPqxSJUT82$?!MqJ`(BT)~b#al;&I848oKeni-fYDQ=S#_y~l6q)~}yNynl6X?BZY z9g=E3t}^;AGVE7d)m)^?+7`wQ<~Fm9I+FZek_)xIM6L+-WeE>Yv6LaP!Z?!9O@x{U zm&su{hL2t87Cr`>?|-)wA8ggB{|~|s8}`-2tI8)@m7mwG@|)*K<$oe6EZ&|}eh*-% z%{%xk3_C<7Z6g6RjLJViN>Z#*1#ObbZ!!m1mH$1-#fcmD_EG+(IabxPYkWk~KOQbP zzY-`G&aXGGRG<{jhe@5ani@elO>HMF+_-ZN`OxzL(binAD&>8*TWikVE3Ijk6kT0m zCmpTnC9Qc;y5h@uvDW;Ol(Z&H0KH&!#YFmmvHVOaF~SV zuJ1s=Y_|hP(4B;%t8_D!L^2LUo)YF$TsRclF> zYe)NHv7Tr#Vl~$;pf6{pFaom$^S}I;;>8SNnM-6B?J?HjW;lJG3>=cY6SkYLOqJD9 zYN57kY5`N%)yloPM+rclYGX$;=+A- zLx_4~Q%SvCyd!I-)`gNfgeG9|m9!cA4=2ucBL?Z{fjfc^DUYLW3B$PdNezUC@ z!YTv(DoS7mR>^8oW9!Ro^(CA6bqtYidw|Y7j^P*P*~#!G&t?pVcF$v-WucX-13DM* ze7DhI^f8}&M|KavjMIYw7`%S?Mf3xNH4|caM1t7a4$_MXxZp<)h`#R^tI@jT@Oy@4 z{)YTQE{f&kqC+t7jM~Fqf&Sb@X_=}txK+Y_F~He>DbmY+;Ui9Zu(2}5n>R6~Mx3Nb zF&8k1bYvd&KstNuHsk0}yp3T~L?eziixeY$3P<;Z@0-rJv z`l?a)~Q%+YTPMCy`a4*I78F10)HsB}bv@2(TJvbmRqga#=7v~`~Bet*q8*=3z~%n=_#qYp!3@6&_+N~&5>l;a(Y zBHCM{hcatGCfrl3M5_~IOE0=0=og6~NtQvfpT&|n6$2}p@C8X|&7cREK}@4*)-*a_ z_B8jq*4@Qjzhk8DI!|yyLPZG| z?N_Z$qY--WNvR~Xl67U1AXuyEkjA+J|Gb=taD&r0!hW*VK_j66&%*LmQ*kwkJi$>D zkog*0bJ#bMZYq5mPq|5dzigk)K`kmPrJ zzfV0XtsEo|&KPG-v69~q`msu$;G0bHw1ut;xm+dBHNK)~-6@4Usx@Z1%H>-s3AE}& z7Ddu))u$P%?%=G1NMk6UFgdP)bEb{lVnmOHT{lLaz_Kox-@ktcybCw6d*Cm73JmlV z=#@a(uQCwfWoXrZra4Rtt@^j}g3M91hzY47!O74S)R${%7ogv^$Z*`_ zp60(NEzW$Hi-YLgz%IUWcy0+52mhS4T4sOMr5$~?rO9}BH6 zQ;1PphQNUb9+^cIvV|%rsYj7~>yyACx@x@u>*NT}!nnR!|8JoNKYj&h&NV_c*gWLx z!CD!8!ksPj1YfjHR@Pa|b`%g2!KkZq8ypkh51Wx@YhYgvQLpfio8Zf@C|aE08^Q8% zv{1(N4!LZ0@0N{?Rx=F{a$le54BUXQeQ3IDtwe&{I4+Yi(!{JvU5wwrsS8rKLi^E2XAllr+b*JHuHCgPq6OYsnV>K`ibb`Fo-JT z0OLwpHR+i3HI?!}Cf-#vx{S71IQ9gm#CxnbkY{e#pzv1xB56Z6Q#-3raJA)bE9MJg zoXW4I6qvsjk?>48TinAEL^YCWbUw9)V>$IQ1X=jfUZ+vBAnTi)f!^SwvyOLA7n?+YzC*zuwu=j(Wpbzh6auEUb$LYt~-t{#JRZ)hTzSz zkQlAzznfIW`h}j61kxu^I+S6SW$6Wbq}TgMV4;!h6eWx4GHM%Ta9p!fp??t_9h$)D zlrsXza~6%BDafNXg1S;;y|uJGsY=nRFC}G2?0hR~9=nHTi+dq zH8$BV?Nh%-=5IPcH4Z9GL`ln^H(C31~12)#gH_=`iJytNluih0taYDCfoT; zf30lj(%9kWkeI^-_ndfvkAAoFtmE6{$=*j8C`y0jl==M=LVt+#ugB55s-xOVckU57 z^(+vg;q;^&hOYT<7IpKF$7IgIW)bxyUxq9=vt_}VCkxJeS>!uO-8xTjev-_O~zqVOT0nY|lrHif%g0Swe_|dA}kadNz=7w-{>M zY6jM+Ia)K22?LnY;M7dF(O=JP#Z@p`45?|Z-1;b;YVn2L+&5$Cj9y0ezr(4Od`T%= z3n<0kI8beGVigkL9-}nQ{Fu>Aq8dup9p2C~8SZ>hXr3;LH< zG@#EfHs5?y#Z8ze-~~4Sz@C$%+*GQCeQwuk-*`7eQB5_GkBZ&pR(&e!2D)KuNQf?T z)mcZuYDvLiwLk2DBcCa3h(4x=gds7WBTgRb+u5wTl5;}S2yiO7aHnyYgj#hGAr(%4 zp+~E^*Lq!&FhQ#k6OaTiNxECBnan#oud#w&c3umVIEM@-ty(-ia5eAAJ??Hht5pw? zT>e6bWf0VIKJE#Qc_LrNf~Mqac9?xaih^B2NL0iJQhANjcf#X1>b=+*Sx;B4l^p&J z13ivY%Nr5=NTB?t>!kdx<}Vur1;Y38;q`f}L#z2cwj=(!oJ zx5l3Gmk~@Ftd9}%m6|_IDlRJpRQG|Te7v2@YH=x{!1b~}L)LW`_2MW}mY~CY;5}EX z`GR2}Iy^0kXm2wY$)??SLUn@dA2xP;#rN}BWztPm>!r6kCl@ZbIj*;1jx7ta@I+QI zg*mPDL6j+FQxVlY+hksH61Y_4w@%|jJ-9fBE-ls#1gNPo6NiPHxs#NJ6)46n3p_K% zcZe}JNVQ3s4KybUK*DV$#us5)#O1TUDbs((w*0RpVlitp+lkP%{K!&rBTq9k@>O(; z`9Rl5bljzg;ss-otyineyQ)v~p%0A7k#VuDS0>G7JbLErXOm?<7FIme`O&s=$eYbD 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

      T9lJ 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